Update prebuilts to go1.10 ab/4625579

Test: m -j blueprint_tools
Change-Id: I24caea588e0801ed52e256b2076e3359190c2525
diff --git a/AUTHORS b/AUTHORS
index c510d4b..e861bfc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -18,12 +18,17 @@
 Abhinav Gupta <abhinav.g90@gmail.com>
 Adam Eijdenberg <adam@continusec.com>
 Adam Kisala <adam.kisala@gmail.com>
+Adam Thomason <athomason@gmail.com>
 Aditya Mukerjee <dev@chimeracoder.net>
+Adrian Hesketh <adrianhesketh@hushmail.com>
 Adrian Nos <nos.adrian@gmail.com>
 Adrian O'Grady <elpollouk@gmail.com>
 Adrien Bustany <adrien-xx-google@bustany.org>
 Aécio Júnior <aeciodantasjunior@gmail.com>
+Aeneas Rekkas (arekkas) <aeneas@ory.am>
+Afanasev Stanislav <phpprogger@gmail.com>
 Agis Anastasopoulos <agis.anast@gmail.com>
+Agniva De Sarker <agnivade@yahoo.co.in>
 Ahmed Waheed Moanes <oneofone@gmail.com>
 Ahmy Yulrizka <yulrizka@gmail.com>
 Aiden Scandella <ai@uber.com>
@@ -60,6 +65,7 @@
 Alexander Morozov <lk4d4math@gmail.com>
 Alexander Neumann <alexander@bumpern.de>
 Alexander Orlov <alexander.orlov@loxal.net>
+Alexander Pantyukhin <apantykhin@gmail.com>
 Alexander Reece <awreece@gmail.com>
 Alexander Surma <surma@surmair.de>
 Alexander Zhavnerchik <alex.vizor@gmail.com>
@@ -67,6 +73,7 @@
 Alexandre Cesaro <alexandre.cesaro@gmail.com>
 Alexandre Fiori <fiorix@gmail.com>
 Alexandre Normand <alexandre.normand@gmail.com>
+Alexandre Parentea <aubonbeurre@gmail.com>
 Alexei Sholik <alcosholik@gmail.com>
 Alexey Borzenkov <snaury@gmail.com>
 Alexey Neganov <neganovalexey@gmail.com>
@@ -76,9 +83,11 @@
 Alif Rachmawadi <subosito@gmail.com>
 Allan Simon <allan.simon@supinfo.com>
 Alok Menghrajani <alok.menghrajani@gmail.com>
+Aman Gupta <aman@tmm1.net>
 Amazon.com, Inc
 Amir Mohammad Saied <amir@gluegadget.com>
 Amrut Joshi <amrut.joshi@gmail.com>
+Anand K. Mistry <anand@mistry.ninja>
 Anders Pearson <anders@columbia.edu>
 André Carvalho <asantostc@gmail.com>
 Andre Nathan <andrenth@gmail.com>
@@ -104,7 +113,10 @@
 Andrew Williams <williams.andrew@gmail.com>
 Andrey Mirtchovski <mirtchovski@gmail.com>
 Andrey Petrov <andrey.petrov@shazow.net>
+Andrii Soldatenko <andrii.soldatenko@gmail.com>
+Andrii Soluk <isoluchok@gmail.com>
 Andriy Lytvynov <lytvynov.a.v@gmail.com>
+Andrzej Żeżel <andrii.zhezhel@gmail.com>
 Andy Balholm <andy@balholm.com>
 Andy Davis <andy@bigandian.com>
 Andy Finkenstadt <afinkenstadt@zynga.com>
@@ -115,9 +127,11 @@
 Anh Hai Trinh <anh.hai.trinh@gmail.com>
 Anmol Sethi <anmol@aubble.com>
 Anschel Schaffer-Cohen <anschelsc@gmail.com>
+Anthony Alves <cvballa3g0@gmail.com>
 Anthony Canino <anthony.canino1@gmail.com>
 Anthony Eufemio <anthony.eufemio@gmail.com>
 Anthony Martin <ality@pbrane.org>
+Anthony Sottile <asottile@umich.edu>
 Anthony Starks <ajstarks@gmail.com>
 Anthony Voutas <voutasaurus@gmail.com>
 Anthony Woods <awoods@raintank.io>
@@ -128,6 +142,7 @@
 Apsalar
 Aram Hăvărneanu <aram@mgk.ro>
 Areski Belaid <areski@gmail.com>
+Ariel Mashraki <ariel@mashraki.co.il>
 Arlo Breault <arlolra@gmail.com>
 ARM Ltd.
 Arnaud Ysmal <arnaud.ysmal@gmail.com>
@@ -143,12 +158,14 @@
 Aulus Egnatius Varialus <varialus@gmail.com>
 awaw fumin <awawfumin@gmail.com>
 Awn Umar <awn@cryptolosophy.io>
+Axel Wagner <axel.wagner.hh@googlemail.com>
 Ayanamist Yang <ayanamist@gmail.com>
 Aymerick Jéhanne <aymerick@jehanne.org>
 Baiju Muthukadan <baiju.m.mail@gmail.com>
 Bartosz Grzybowski <melkorm@gmail.com>
 Bastian Ike <bastian.ike@gmail.com>
 Ben Burkert <ben@benburkert.com>
+Ben Haines <bhainesva@gmail.com>
 Ben Lubar <ben.lubar@gmail.com>
 Ben Olive <sionide21@gmail.com>
 Ben Shi <powerman1st@163.com>
@@ -159,26 +176,33 @@
 Billie Harold Cleek <bhcleek@gmail.com>
 Bjorn Tillenius <bjorn@tillenius.me>
 Bjorn Tipling <bjorn.tipling@gmail.com>
+Blain Smith <rebelgeek@blainsmith.com>
 Blake Gentry <blakesgentry@gmail.com>
+Blake Mesdag <blakemesdag@gmail.com>
 Blake Mizerany <blake.mizerany@gmail.com>
 Blixt <me@blixt.nyc>
 Bobby Powers <bobbypowers@gmail.com>
 Bolt
+Borja Clemente <borja.clemente@gmail.com>
+Brad Burch <brad.burch@gmail.com>
 Brady Catherman <brady@gmail.com>
 Brady Sullivan <brady@bsull.com>
 Brendan Daniel Tracey <tracey.brendan@gmail.com>
 Brett Cannon <bcannon@gmail.com>
+Brett Merrill <brett.j.merrill94@gmail.com>
 Brian Dellisanti <briandellisanti@gmail.com>
 Brian Downs <brian.downs@gmail.com>
 Brian G. Merrell <bgmerrell@gmail.com>
 Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com>
 Brian Kennedy <btkennedy@gmail.com>
+Brian Kessler <brian.m.kessler@gmail.com>
 Brian Ketelsen <bketelsen@gmail.com>
 Brian Smith <ohohvi@gmail.com>
 Brian Starke <brian.starke@gmail.com>
 Bryan Alexander <Kozical@msn.com>
 Bryan Ford <brynosaurus@gmail.com>
 Bulat Gaifullin <gaifullinbf@gmail.com>
+Burak Guven <bguven@gmail.com>
 Caine Tighe <arctanofyourface@gmail.com>
 Caleb Spare <cespare@gmail.com>
 Carl Chatfield <carlchatfield@gmail.com>
@@ -193,9 +217,12 @@
 Casey Marshall <casey.marshall@gmail.com>
 Cezar Sá Espinola <cezarsa@gmail.com>
 ChaiShushan <chaishushan@gmail.com>
+Charles Fenwick Elliott <Charles@FenwickElliott.io>
 Charles L. Dorian <cldorian@gmail.com>
 Charles Lee <zombie.fml@gmail.com>
 Chew Choon Keat <choonkeat@gmail.com>
+Cholerae Hu <choleraehyq@gmail.com>
+Chris Ball <chris@printf.net>
 Chris Biscardi <chris@christopherbiscardi.com>
 Chris Dollin <ehog.hedge@gmail.com>
 Chris Farmiloe <chrisfarms@gmail.com>
@@ -207,6 +234,7 @@
 Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com>
 Chris Roche <rodaine@gmail.com>
 Chris Stockton <chrisstocktonaz@gmail.com>
+Christian Alexander <christian@linux.com>
 Christian Couder <chriscool@tuxfamily.org>
 Christian Himpel <chressie@googlemail.com>
 Christine Hansmann <chhansmann@gmail.com>
@@ -214,10 +242,12 @@
 Christoph Hack <christoph@tux21b.org>
 Christopher Cahoon <chris.cahoon@gmail.com>
 Christopher Guiney <chris@guiney.net>
+Christopher Henderson <chris@chenderson.org>
 Christopher Nelson <nadiasvertex@gmail.com>
 Christopher Nielsen <m4dh4tt3r@gmail.com>
 Christopher Redden <christopher.redden@gmail.com>
 Christopher Wedgwood <cw@f00f.org>
+Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
 CL Sung <clsung@gmail.com> <cl_sung@htc.com>
 Clement Skau <clementskau@gmail.com>
 CloudFlare Inc.
@@ -251,6 +281,8 @@
 Daniel Speichert <daniel@speichert.pl>
 Daniel Theophanes <kardianos@gmail.com>
 Daniel Upton <daniel@floppy.co>
+Daniela Petruzalek <daniela.petruzalek@gmail.com>
+Danny Rosseau <daniel.rosseau@gmail.com>
 Darren Elwood <darren@textnode.com>
 Datong Sun <dndx@idndx.com>
 Dave Cheney <dave@cheney.net>
@@ -272,6 +304,7 @@
 David Titarenco <david.titarenco@gmail.com>
 David Volquartz Lebech <david@lebech.info>
 Davies Liu <davies.liu@gmail.com>
+Davor Kapsa <davor.kapsa@gmail.com>
 Dean Prichard <dean.prichard@gmail.com>
 Deepak Jois <deepak.jois@gmail.com>
 Denis Bernard <db047h@gmail.com>
@@ -308,14 +341,18 @@
 Dustin Shields-Cloues <dcloues@gmail.com>
 Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
 Dylan Waits <dylan@waits.io>
+Edan Bedrik <3d4nb3@gmail.com>
 Eden Li <eden.li@gmail.com>
 Edward Muller <edwardam@interlix.com>
 Egon Elbre <egonelbre@gmail.com>
 Ehren Kret <ehren.kret@gmail.com>
 Eitan Adler <lists@eitanadler.com>
 Eivind Uggedal <eivind@uggedal.com>
+Elbert Fliek <efliek@gmail.com>
+Elena Grahovac <elena@grahovac.me>
 Elias Naur <elias.naur@gmail.com>
 Elliot Morrison-Reed <elliotmr@gmail.com>
+Emerson Lin <linyintor@gmail.com>
 Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
 Emilien Kenler <hello@emilienkenler.com>
 Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
@@ -326,6 +363,7 @@
 Eric Engestrom <eric@engestrom.ch>
 Eric Lagergren <ericscottlagergren@gmail.com>
 Eric Milliken <emilliken@gmail.com>
+Eric Rescorla <ekr@rtfm.com>
 Eric Roshan-Eisner <eric.d.eisner@gmail.com>
 Erik Aigner <aigner.erik@gmail.com>
 Erik Dubbelboer <erik@dubbelboer.com>
@@ -335,6 +373,7 @@
 Esko Luontola <esko.luontola@gmail.com>
 Euan Kemp <euank@euank.com>
 Evan Hicks <evan.hicks2@gmail.com>
+Evan Jones <ej@evanjones.ca>
 Evan Phoenix <evan@phx.io>
 Evan Shaw <chickencha@gmail.com>
 Evgeniy Polyakov <zbr@ioremap.net>
@@ -363,6 +402,8 @@
 Francisco Claude <fclaude@recoded.cl>
 Francisco Rojas <francisco.rojas.gallegos@gmail.com>
 Francisco Souza <franciscossouza@gmail.com>
+Frank Somers <fsomers@arista.com>
+Frederic Guillot <frederic.guillot@gmail.com>
 Frederick Kelly Mayle III <frederickmayle@gmail.com>
 Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
 Fredrik Forsmo <fredrik.forsmo@gmail.com>
@@ -391,9 +432,12 @@
 Gordon Klaus <gordon.klaus@gmail.com>
 Graham King <graham4king@gmail.com>
 Graham Miller <graham.miller@gmail.com>
+Grant Griffiths <ggp493@gmail.com>
 Greg Poirier <greg.istehbest@gmail.com>
 Greg Ward <greg@gerg.ca>
 Gregory Man <man.gregory@gmail.com>
+Guilherme Garnier <guilherme.garnier@gmail.com>
+Guilherme Rezende <guilhermebr@gmail.com>
 Guillaume J. Charmes <guillaume@charmes.net>
 Guobiao Mei <meiguobiao@gmail.com>
 Gustav Paul <gustav.paul@gmail.com>
@@ -404,6 +448,7 @@
 H. İbrahim Güngör <igungor@gmail.com>
 Hajime Hoshi <hajimehoshi@gmail.com>
 Hang Qian <hangqian90@gmail.com>
+Hanjun Kim <hallazzang@gmail.com>
 Hari haran <hariharan.uno@gmail.com>
 Hariharan Srinath <srinathh@gmail.com>
 Harley Laue <losinggeneration@gmail.com>
@@ -416,8 +461,12 @@
 Henning Schmiedehausen <henning@schmiedehausen.org>
 Henrik Edwards <henrik.edwards@gmail.com>
 Henrik Hodne <henrik@hodne.io>
+Henry Adi Sumarto <henry.adisumarto@gmail.com>
+Henry Bubert <google@mindeco.de>
 Henry Chang <mr.changyuheng@gmail.com>
 Herbert Georg Fischer <herbert.fischer@gmail.com>
+Hilko Bengen <bengen@hilluzination.de>
+Hiroaki Nakamura <hnakamur@gmail.com>
 Hironao OTSUBO <motemen@gmail.com>
 Hiroshi Ioka <hirochachacha@gmail.com>
 Hitoshi Mitake <mitake.hitoshi@gmail.com>
@@ -428,6 +477,7 @@
 Hu Keping <hukeping@huawei.com>
 Hugues Bruant <hugues.bruant@gmail.com>
 Ian Gudger <ian@loosescre.ws>
+Ian Kent <iankent85@gmail.com>
 IBM
 Ibrahim AshShohail <ibra.sho@gmail.com>
 Icarus Sparry <golang@icarus.freeuk.com>
@@ -435,13 +485,16 @@
 Idora Shinatose <idora.shinatose@gmail.com>
 Igneous Systems, Inc.
 Igor Dolzhikov <bluesriverz@gmail.com>
+Igor Vashyst <ivashyst@gmail.com>
 INADA Naoki <songofacandy@gmail.com>
+Inanc Gumus <m@inanc.io>
 Ingo Krabbe <ikrabbe.ask@gmail.com>
 Ingo Oeser <nightlyone@googlemail.com>
 Intel Corporation
 Irieda Noboru <irieda@gmail.com>
 Isaac Wagner <ibw@isaacwagner.me>
 Ivan Babrou <ivan@cloudflare.com>
+Ivan Bertona <ivan.bertona@gmail.com>
 Ivan Moscoso <moscoso@gmail.com>
 Ivan Ukhov <ivan.ukhov@gmail.com>
 Jacob Hoffman-Andrews <github@hoffman-andrews.com>
@@ -455,6 +508,7 @@
 James Fysh <james.fysh@gmail.com>
 James Gray <james@james4k.com>
 James Hartig <fastest963@gmail.com>
+James Lawrence <jljatone@gmail.com>
 James Meneghello <rawrz0r@gmail.com>
 James Myers <jfmyers9@gmail.com>
 James Neve <jamesoneve@gmail.com>
@@ -463,6 +517,7 @@
 James Smith <jrs1995@icloud.com>
 James Sweet <james.sweet88@googlemail.com>
 James Toy <nil@opensesame.st>
+James Treanor <jtreanor3@gmail.com>
 James Whitehead <jnwhiteh@gmail.com>
 Jamie Beverly <jamie.r.beverly@gmail.com>
 Jamie Kerr <jkerr113@googlemail.com>
@@ -474,19 +529,25 @@
 Jan Newmarch <jan.newmarch@gmail.com>
 Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
 Jani Monoses <jani.monoses@ubuntu.com>
+Jared Culp <jculp14@gmail.com>
 Jaroslavas Počepko <jp@webmaster.ms>
 Jason Barnett <jason.w.barnett@gmail.com>
 Jason Chu <jasonchujc@gmail.com>
 Jason Del Ponte <delpontej@gmail.com>
 Jason Smale <jsmale@zendesk.com>
 Jason Travis <infomaniac7@gmail.com>
+Jason Wangsadinata <jwangsadinata@gmail.com>
+Javier Segura <javism@gmail.com>
 Jay Weisskopf <jay@jayschwa.net>
+Jean-Francois Cantin <jfcantin@gmail.com>
 Jean-Nicolas Moal <jn.moal@gmail.com>
+Jeet Parekh <jeetparekh96@gmail.com>
 Jeff Hodges <jeff@somethingsimilar.com>
 Jeff R. Allen <jra@nella.org>
 Jeff Sickel <jas@corpus-callosum.com>
 Jeff Wendling <jeff@spacemonkey.com>
 Jeffrey H <jeffreyh192@gmail.com>
+Jelte Fennema <github-tech@jeltef.nl>
 Jens Frederich <jfrederich@gmail.com>
 Jeremy Jackins <jeremyjackins@gmail.com>
 Jeroen Bobbeldijk <jerbob92@gmail.com>
@@ -494,12 +555,14 @@
 Jesse Szwedko <jesse.szwedko@gmail.com>
 Jihyun Yu <yjh0502@gmail.com>
 Jim McGrath <jimmc2@gmail.com>
+Jimmy Frasche <soapboxcicero@gmail.com>
 Jimmy Zelinskie <jimmyzelinskie@gmail.com>
 Jin-wook Jeong <jeweljar@hanmail.net>
 Jingcheng Zhang <diogin@gmail.com>
 Jingguo Yao <yaojingguo@gmail.com>
 Jiong Du <londevil@gmail.com>
 Jirka Daněk <dnk@mail.muni.cz>
+Jiulong Wang <jiulongw@gmail.com>
 Joakim Sernbrant <serbaut@gmail.com>
 Joe Farrell <joe2farrell@gmail.com>
 Joe Harrison <joehazzers@gmail.com>
@@ -545,14 +608,18 @@
 Josh Holland <jrh@joshh.co.uk>
 Josh Roppo <joshroppo@gmail.com>
 Joshua Chase <jcjoshuachase@gmail.com>
+Joshua Rubin <joshua@rubixconsulting.com>
 Josselin Costanzi <josselin@costanzi.fr>
 Jostein Stuhaug <js@solidsystem.no>
 Joyent, Inc.
 JT Olds <jtolds@xnet5.com>
+Juan Carlos <juanjcsr@gmail.com>
+Jude Pereira <judebpereira@gmail.com>
 Jukka-Pekka Kekkonen <karatepekka@gmail.com>
 Julian Kornberger <jk+github@digineo.de>
 Julian Phillips <julian@quantumfyre.co.uk>
 Julien Schmidt <google@julienschmidt.com>
+Junya Hayashi <ledmonster@gmail.com>
 Justin Nuß <nuss.justin@gmail.com>
 Justyn Temme <justyntemme@gmail.com>
 Kai Backman <kaib@golang.org>
@@ -562,7 +629,9 @@
 Kamil Chmielewski <kamil.chm@gmail.com>
 Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
 Kang Hu <hukangustc@gmail.com>
+Karel Pazdera <pazderak@gmail.com>
 Karoly Negyesi <chx1975@gmail.com>
+Karsten Köhler <karsten.koehler95@gmail.com>
 Kashav Madan <kshvmdn@gmail.com>
 Kate Manson <kate.manson@izettle.com>
 Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@@ -579,13 +648,17 @@
 Ken Rockot <ken@oz.gs>
 Ken Sedgwick <ken@bonsai.com>
 Kenji Kaneda <kenji.kaneda@gmail.com>
+Kenji Yano <kenji.yano@gmail.com>
 Kenneth Shaw <kenshaw@gmail.com>
 Kenny Grant <kennygrant@gmail.com>
 Kevin Ballard <kevin@sb.org>
 Kevin Burke <kev@inburke.com>
 Kevin Kirsche <kev.kirsche@gmail.com>
+Kevin Ruffin <kruffin@gmail.com>
 Kevin Vu <kevin.m.vu@gmail.com>
+Kieran Colford <kieran@kcolford.com>
 Kim Yongbin <kybinz@gmail.com>
+Kirk Han <kirk91.han@gmail.com>
 Klaus Post <klauspost@gmail.com>
 Kodie Goodwin <kodiegoodwin@gmail.com>
 Koichi Shiraishi <zchee.io@gmail.com>
@@ -596,20 +669,26 @@
 Kris Nova <kris@nivenly.com>
 Kristopher Watts <traetox@gmail.com>
 Kun Li <likunarmstrong@gmail.com>
+Kunpei Sakai <namusyaka@gmail.com>
 Kyle Consalus <consalus@gmail.com>
 Kyle Isom <kyle@gokyle.net>
 Kyle Jones <kyle@kyledj.com>
 Kyle Lemons <kyle@kylelemons.net>
+Kyle Shannon <kyle@pobox.com>
+Kyohei Kadota <lufia@lufia.org>
 Kyrylo Silin <silin@kyrylo.org>
 L Campbell <unpantsu@gmail.com>
 Lai Jiangshan <eag0628@gmail.com>
+Lakshay Garg <lakshay.garg.1996@gmail.com>
 Lars Jeppesen <jeppesen.lars@gmail.com>
 Lars Wiegman <lars@namsral.com>
 Larz Conwell <larzconwell@gmail.com>
+Laurent Voisin <lpvoisin@gmail.com>
 Laurie Clark-Michalek <laurie@qubit.com>
 LE Manh Cuong <cuong.manhle.vn@gmail.com>
 Lee Hinman <hinman@gmail.com>
 Lee Packham <lpackham@gmail.com>
+Leigh McCulloch <leighmcc@gmail.com>
 Leon Klingele <git@leonklingele.de>
 Lev Shamardin <shamardin@gmail.com>
 Lewin Bormann <lewin.bormann@gmail.com>
@@ -629,10 +708,15 @@
 Luit van Drongelen <luitvd@gmail.com>
 Luka Zakrajšek <tr00.g33k@gmail.com>
 Luke Curley <qpingu@gmail.com>
+Luke Granger-Brown <git@lukegb.com>
+Lyle Franklin <lylejfranklin@gmail.com>
 Ma Peiqi <mapeiqi2017@gmail.com>
+Maicon Costa <maiconscosta@gmail.com>
 Maksym Trykur <maksym.trykur@gmail.com>
 Mal Curtis <mal@mal.co.nz>
 Manfred Touron <m@42.am>
+Manish Goregaokar <manishsmail@gmail.com>
+Mansour Rahimi <rahimi.mnr@gmail.com>
 Manu S Ajith <neo@codingarena.in>
 Manuel Mendez <mmendez534@gmail.com>
 Marc Weistroff <marc@weistroff.net>
@@ -642,8 +726,11 @@
 Marin Bašić <marin.basic02@gmail.com>
 Mark Adams <mark@markadams.me>
 Mark Bucciarelli <mkbucc@gmail.com>
+Mark Percival <m@mdp.im>
+Mark Pulford <mark@kyne.com.au>
 Mark Severson <miquella@gmail.com>
 Mark Theunissen <mark.theunissen@gmail.com>
+Mark Wolfe <mark@wolfe.id.au>
 Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
 Marko Mudrinic <mudrinic.mare@gmail.com>
 Marko Tiikkaja <marko@joh.to>
@@ -661,13 +748,17 @@
 Martin Olsen <github.com@martinolsen.net>
 Martin Olsson <martin@minimum.se>
 Martin Probst <martin@probst.io>
+Martins Sipenko <martins.sipenko@gmail.com>
 Marvin Stenger <marvin.stenger94@gmail.com>
 Marwan Sulaiman <marwan.sulaiman@work.co>
 Maryan Hratson <gmarik@gmail.com>
 Masahiro Furudate <masahiro.furudate@gmail.com>
 Masahiro Wakame <vvakame@gmail.com>
 Masaki Yoshida <yoshida.masaki@gmail.com>
+Mat Byczkowski <mbyczkowski@gmail.com>
 Máté Gulyás <mgulyas86@gmail.com>
+Matej Baćo <matejbaco@gmail.com>
+Mateus Amin <mateus.amin@gmail.com>
 Mateusz Czapliński <czapkofan@gmail.com>
 Mathias Beke <git@denbeke.be>
 Mathias Hall-Andersen <mathias@hall-andersen.dk>
@@ -677,6 +768,7 @@
 Matt Aimonetti <mattaimonetti@gmail.com>
 Matt Blair <me@matthewblair.net>
 Matt Bostock <matt@mattbostock.com>
+Matt Dee <mdee@hioscar.com>
 Matt Drollette <matt@drollette.com>
 Matt Harden <matt.harden@gmail.com>
 Matt Jibson <matt.jibson@gmail.com>
@@ -688,23 +780,28 @@
 Matt T. Proud <matt.proud@gmail.com>
 Matt Williams <gh@mattyw.net>
 Matthew Brennan <matty.brennan@gmail.com>
+Matthew Broberg <matthewbbroberg@gmail.com>
 Matthew Cottingham <mattcottingham@gmail.com>
 Matthew Denton <mdenton@skyportsystems.com>
 Matthew Holt <Matthew.Holt+git@gmail.com>
 Matthew Horsnell <matthew.horsnell@gmail.com>
 Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
 Matthieu Olivier <olivier.matthieu@gmail.com>
+Matthijs Kooijman <matthijs@stdin.nl>
 Max Riveiro <kavu13@gmail.com>
+Max Schmitt <max@schmitt.mx>
 Maxim Khitrov <max@mxcrypt.com>
 Maxime de Roucy <maxime.deroucy@gmail.com>
 Máximo Cuadros Ortiz <mcuadros@gmail.com>
 Maxwell Krohn <themax@gmail.com>
+Mayank Kumar <krmayankk@gmail.com>
 MediaMath, Inc
 Meir Fischer <meirfischer@gmail.com>
 Meng Zhuo <mengzhuo1203@gmail.com>
 Meteor Development Group
 Mhd Sulhan <m.shulhan@gmail.com>
 Micah Stetson <micah.stetson@gmail.com>
+Michael Brandenburg <mbrandenburg@bolste.com>
 Michael Chaten <mchaten@gmail.com>
 Michael Edwards <medwards@walledcity.ca>
 Michael Elkins <michael.elkins@gmail.com>
@@ -716,17 +813,22 @@
 Michael Lewis <mikelikespie@gmail.com>
 Michael MacInnis <Michael.P.MacInnis@gmail.com>
 Michael McConville <momcconville@gmail.com>
+Michael McLoughlin <mmcloughlin@gmail.com>
 Michael Pearson <mipearson@gmail.com>
 Michael Schaller <michael@5challer.de>
+Michael Schurter <michael.schurter@gmail.com>
 Michael Stapelberg <michael@stapelberg.de>
+Michael Steinert <mike.steinert@gmail.com>
 Michael Teichgräber <mteichgraeber@gmx.de>
 Michael Vetter <g.bluehut@gmail.com>
 Michal Bohuslávek <mbohuslavek@gmail.com>
 Michał Derkacz <ziutek@lnet.pl>
+Michal Pristas <michal.pristas@gmail.com>
 Miek Gieben <miek@miek.nl>
 Miguel Mendez <stxmendez@gmail.com>
 Miguel Molina <hi@mvader.me>
 Mihai Borobocea <MihaiBorobocea@gmail.com>
+Mihail Minaev <minaev.mike@gmail.com>
 Mikael Tillenius <mikti42@gmail.com>
 Mike Andrews <mra@xoba.com>
 Mike Appleby <mike@app.leby.org>
@@ -748,9 +850,11 @@
 Morten Siebuhr <sbhr@sbhr.dk>
 Môshe van der Sterre <moshevds@gmail.com>
 Mostyn Bramley-Moore <mostyn@antipode.se>
+Muhammad Falak R Wani <falakreyaz@gmail.com>
 Muhammed Uluyol <uluyol0@gmail.com>
 Mura Li <mura_li@castech.com.tw>
 Nan Deng <monnand@gmail.com>
+Naoki Kanatani <k12naoki@gmail.com>
 Nathan Caza <mastercactapus@gmail.com>
 Nathan Humphreys <nkhumphreys@gmail.com>
 Nathan John Youngman <nj@nathany.com>
@@ -779,6 +883,7 @@
 Nick Patavalis <nick.patavalis@gmail.com>
 Nick Petroni <npetroni@cs.umd.edu>
 Nick Robinson <nrobinson13@gmail.com>
+Nicolas BRULEZ <n.brulez@gmail.com>
 Nicolas Kaiser <nikai@nikai.net>
 Nicolas Owens <mischief@offblast.org>
 Nicolas S. Dade <nic.dade@gmail.com>
@@ -788,8 +893,10 @@
 Niklas Schnelle <niklas.schnelle@gmail.com>
 Niko Dziemba <niko@dziemba.com>
 Nikolay Turpitko <nikolay@turpitko.com>
+Nils Larsgård <nilsmagnus@gmail.com>
 Niranjan Godbole <niranjan8192@gmail.com>
 Noah Campbell <noahcampbell@gmail.com>
+Noble Johnson <noblepoly@gmail.com>
 Norberto Lopes <nlopes.ml@gmail.com>
 Odin Ugedal <odin@ugedal.com>
 Oleg Bulatov <dmage@yandex-team.ru>
@@ -823,12 +930,15 @@
 Patrick Pelletier <pp.pelletier@gmail.com>
 Patrick Smith <pat42smith@gmail.com>
 Paul A Querna <paul.querna@gmail.com>
+Paul Boyd <boyd.paul2@gmail.com>
 Paul Hammond <paul@paulhammond.org>
 Paul Jolly <paul@myitcv.org.uk>
 Paul Lalonde <paul.a.lalonde@gmail.com>
 Paul Meyer <paul.meyer@microsoft.com>
+Paul PISCUC <paul.piscuc@gmail.com>
 Paul Querna <pquerna@apache.org>
 Paul Rosania <paul.rosania@gmail.com>
+Paul Ruest <pruest@gmail.com>
 Paul Sbarra <Sbarra.Paul@gmail.com>
 Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
 Paul van Brouwershaven <paul@vanbrouwershaven.com>
@@ -853,6 +963,7 @@
 Peter Waldschmidt <peter@waldschmidt.com>
 Peter Waller <peter.waller@gmail.com>
 Peter Williams <pwil3058@gmail.com>
+Petrica Voicu <pvoicu@paypal.com>
 Philip Børgesen <philip.borgesen@gmail.com>
 Philip Hofer <phofer@umich.edu>
 Philip K. Warren <pkwarren@gmail.com>
@@ -861,26 +972,34 @@
 Piers <google@hellopiers.pro>
 Pieter Droogendijk <pieter@binky.org.uk>
 Pietro Gagliardi <pietro10@mac.com>
+Pontus Leitzler <leitzler@gmail.com>
 Prashant Varanasi <prashant@prashantv.com>
 Pravendra Singh <hackpravj@gmail.com>
 Preetam Jinka <pj@preet.am>
 Qiuxuan Zhu <ilsh1022@gmail.com>
+Qualcomm Data Center, Inc.
 Quan Tran <qeed.quan@gmail.com>
 Quan Yong Zhai <qyzhai@gmail.com>
 Quentin Perez <qperez@ocs.online.net>
 Quentin Renard <contact@asticode.com>
 Quoc-Viet Nguyen <afelion@gmail.com>
 RackTop Systems Inc.
+Radek Sohlich <sohlich@gmail.com>
 Radu Berinde <radu@cockroachlabs.com>
 Rafal Jeczalik <rjeczalik@gmail.com>
 Raif S. Naffah <go@naffah-raif.name>
 RainTank
 Rajat Goel <rajat.goel2010@gmail.com>
+Rajath Agasthya <rajathagasthya@gmail.com>
+Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
 Ralph Corderoy <ralph@inputplus.co.uk>
+Ramazan AYYILDIZ <rayyildiz@gmail.com>
 Raphael Geronimi <raphael.geronimi@gmail.com>
+RaviTeja Pothana <ravi.tezu@gmail.com>
 Ray Tung <rtung@thoughtworks.com>
 Raymond Kazlauskas <raima220@gmail.com>
 Red Hat, Inc.
+Reilly Watson <reillywatson@gmail.com>
 Reinaldo de Souza Jr <juniorz@gmail.com>
 Remi Gillig <remigillig@gmail.com>
 Rémy Oudompheng <oudomphe@phare.normalesup.org>
@@ -909,10 +1028,13 @@
 Roger Pau Monné <royger@gmail.com>
 Roger Peppe <rogpeppe@gmail.com>
 Roland Shoemaker <rolandshoemaker@gmail.com>
+Roman Budnikov <romanyx90@yandex.ru>
 Ron Hashimoto <mail@h2so5.net>
 Ron Minnich <rminnich@gmail.com>
+Ross Chater <rdchater@gmail.com>
 Ross Light <rlight2@gmail.com>
 Rowan Worth <sqweek@gmail.com>
+Rudi Kramer <rudi.kramer@gmail.com>
 Russell Haering <russellhaering@gmail.com>
 Ryan Bagwell <ryanbagwell@outlook.com>
 Ryan Boehning <ryan.boehning@apcera.com>
@@ -920,6 +1042,8 @@
 Ryan Lower <rpjlower@gmail.com>
 Ryan Seys <ryan@ryanseys.com>
 Ryan Slade <ryanslade@gmail.com>
+Ryoichi KATO <ryo1kato@gmail.com>
+Ryuji Iwata <qt.luigi@gmail.com>
 Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
 S.Çağlar Onur <caglar@10ur.org>
 Sakeven Jiang <jc5930@sina.cn>
@@ -933,15 +1057,19 @@
 Sasha Sobol <sasha@scaledinference.com>
 Scott Barron <scott.barron@github.com>
 Scott Bell <scott@sctsm.com>
+Scott Crunkleton <crunk1@gmail.com>
 Scott Ferguson <scottwferg@gmail.com>
 Scott Lawrence <bytbox@gmail.com>
 Sean Rees <sean@erifax.org>
 Sebastien Binet <seb.binet@gmail.com>
 Sébastien Paolacci <sebastien.paolacci@gmail.com>
+Seiji Takahashi <timaki.st@gmail.com>
 Sergei Skorobogatov <skorobo@rambler.ru>
 Sergey 'SnakE'  Gromov <snake.scaly@gmail.com>
 Sergey Mishin <sergeymishine@gmail.com>
+Sergey Semin <gray12511@gmail.com>
 Sergio Luis O. B. Correia <sergio@correia.cc>
+Sergiusz Bazanski <bazanski@gmail.com>
 Seth Hoenig <seth.a.hoenig@gmail.com>
 Seth Vargo <sethvargo@gmail.com>
 Shahar Kohanim <skohanim@gmail.com>
@@ -968,11 +1096,13 @@
 Sridhar Venkatakrishnan <sridhar@laddoo.net>
 StalkR <stalkr@stalkr.net>
 Stan Schwertly <stan@schwertly.com>
+Stanislav Afanasev <php.progger@gmail.com>
 Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
 Stéphane Travostino <stephane.travostino@gmail.com>
 Stephen McQuay <stephen@mcquay.me>
 Stephen Searles <stephens2424@gmail.com>
 Stephen Weinberg <stephen@q5comm.com>
+Steve Gilbert <stevegilbert23@gmail.com>
 Steve McCoy <mccoyst@gmail.com>
 Steve Phillips <elimisteve@gmail.com>
 Steve Streeting <steve@stevestreeting.com>
@@ -981,46 +1111,57 @@
 Steven Hartland <steven.hartland@multiplay.co.uk>
 Steven Wilkin <stevenwilkin@gmail.com>
 Stripe, Inc.
+Sukrit Handa <sukrit.handa@utoronto.ca>
 Sunny <me@darkowlzz.space>
 Suyash <dextrous93@gmail.com>
 Sven Almgren <sven@tras.se>
+Sylvain Zimmer <sylvain@sylvainzimmer.com>
 Syohei YOSHIDA <syohex@gmail.com>
 Szabolcs Nagy <nsz@port70.net>
+Tad Fisher <tadfisher@gmail.com>
 Tad Glines <tad.glines@gmail.com>
 Taj Khattra <taj.khattra@gmail.com>
 Takeshi YAMANASHI <9.nashi@gmail.com>
 Takuya Ueda <uedatakuya@gmail.com>
 Tal Shprecher <tshprecher@gmail.com>
 Tamir Duberstein <tamird@gmail.com>
+Tao Wang <twang2218@gmail.com>
 Tarmigan Casebolt <tarmigan@gmail.com>
 Taro Aoki <aizu.s1230022@gmail.com>
 Taru Karttunen <taruti@taruti.net>
 Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
 Ted Kornish <golang@tedkornish.com>
 Teleport Inc.
+Terin Stock <terinjokes@gmail.com>
 Terrel Shumway <gopher@shumway.us>
 Tetsuo Kiso <tetsuokiso9@gmail.com>
 Thanatat Tamtan <acoshift@gmail.com>
+Thiago Avelino <t@avelino.xxx>
 Thiago Fransosi Farina <thiago.farina@gmail.com>
 Thomas Alan Copeland <talan.copeland@gmail.com>
 Thomas Bonfort <thomas.bonfort@gmail.com>
 Thomas de Zeeuw <thomasdezeeuw@gmail.com>
 Thomas Desrosiers <thomasdesr@gmail.com>
 Thomas Kappler <tkappler@gmail.com>
+Thomas Wanielista <tomwans@gmail.com>
 Thorben Krueger <thorben.krueger@gmail.com>
 Thordur Bjornsson <thorduri@secnorth.net>
 Tilman Dilo <tilman.dilo@gmail.com>
 Tim Cooijmans <timcooijmans@gmail.com>
+Tim Cooper <tim.cooper@layeh.com>
 Tim Ebringer <tim.ebringer@gmail.com>
 Tim Heckman <t@heckman.io>
 Tim Henderson <tim.tadh@gmail.com>
+Tim Wright <tenortim@gmail.com>
 Timo Savola <timo.savola@gmail.com>
 Timo Truyts <alkaloid.btx@gmail.com>
 Timothy Studd <tim@timstudd.com>
+Tobias Assarsson <tobias.assarsson@gmail.com>
 Tobias Columbus <tobias.columbus@gmail.com>
 Tobias Klauser <tklauser@distanz.ch>
 Todd Neal <todd@tneal.org>
 Tom Heng <zhm20070928@gmail.com>
+Tom Levy <tomlevy93@gmail.com>
 Tom Linford <tomlinford@gmail.com>
 Tommy Schaefer <tommy.schaefer@teecom.com>
 Tonis Tiigi <tonistiigi@gmail.com>
@@ -1035,8 +1176,10 @@
 Trey Tacon <ttacon@gmail.com>
 Tristan Colgate <tcolgate@gmail.com>
 Tristan Ooohry <ooohry@gmail.com>
+Troels Thomsen <troels@thomsen.io>
 Trung Nguyen <trung.n.k@gmail.com>
 Tudor Golubenco <tudor.g@gmail.com>
+Tugdual Saunier <tugdual.saunier@gmail.com>
 Tuo Shan <sturbo89@gmail.com>
 Tyler Bunnell <tylerbunnell@gmail.com>
 Tyler Treat <ttreat31@gmail.com>
@@ -1063,14 +1206,18 @@
 Wade Simmons <wade@wades.im>
 Wander Lairson Costa <wcosta@mozilla.com>
 Weaveworks
+Wèi Cōngruì <crvv.mail@gmail.com>
 Wei Guangjing <vcc.163@gmail.com>
 Weichao Tang <tevic.tt@gmail.com>
+Wembley G. Leach, Jr <wembley.gl@gmail.com>
+Will Faught <will.faught@gmail.com>
 Will Storey <will@summercat.com>
 Willem van der Schyff <willemvds@gmail.com>
 William Josephson <wjosephson@gmail.com>
 William Orr <will@worrbase.com> <ay1244@gmail.com>
 Wisdom Omuya <deafgoat@gmail.com>
 Wu Yunzhou <yunzhouwu@gmail.com>
+Xi Ruoyao <xry23333@gmail.com>
 Xia Bin <snyh@snyh.org>
 Xing Xing <mikespook@gmail.com>
 Xu Fei <badgangkiller@gmail.com>
@@ -1078,30 +1225,36 @@
 Xuyang Kang <xuyangkang@gmail.com>
 Yahoo Inc.
 Yann Kerhervé <yann.kerherve@gmail.com>
+Yann Salaün <yannsalaun1@gmail.com>
 Yao Zhang <lunaria21@gmail.com>
 Yasha Bubnov <girokompass@gmail.com>
 Yasuharu Goto <matope.ono@gmail.com>
 Yasuhiro Matsumoto <mattn.jp@gmail.com>
 Yestin Sun <ylh@pdx.edu>
-Yesudeep Mangalapilly <yesudeep@google.com>
 Yissakhar Z. Beck <yissakhar.beck@gmail.com>
 Yo-An Lin <yoanlin93@gmail.com>
 Yongjian Xu <i3dmaster@gmail.com>
 Yorman Arias <cixtords@gmail.com>
 Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
+Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
+Yukihiro Nishinaka <6elpinal@gmail.com>
 Yusuke Kagiwada <block.rxckin.beats@gmail.com>
 Yuusei Kuwana <kuwana@kumama.org>
 Yuval Pavel Zholkover <paulzhol@gmail.com>
 Zac Bergquist <zbergquist99@gmail.com>
 Zach Bintliff <zbintliff@gmail.com>
+Zach Gershman <zachgersh@gmail.com>
 Zak <zrjknill@gmail.com>
 Zakatell Kanda <hi@zkanda.io>
 Zellyn Hunter <zellyn@gmail.com>
 Zemanta d.o.o.
 Zev Goldstein <zev.goldstein@gmail.com>
+Zhongtao Chen <chenzhongtao@126.com>
 Ziad Hatahet <hatahet@gmail.com>
 Zorion Arrizabalaga <zorionk@gmail.com>
 Максим Федосеев <max.faceless.frei@gmail.com>
+Роман Хавроненко <hagen1778@gmail.com>
+Тарас Буник <tbunyk@gmail.com>
 Фахриддин Балтаев <faxriddinjon@gmail.com>
 张嵩 <zs349596@gmail.com>
 申习之 <bronze1man@gmail.com>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4f2c4d4..7c1dd54 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -30,11 +30,6 @@
 
 Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches.
 
-**We do not accept GitHub pull requests**
-(we use [an instance](https://go-review.googlesource.com/) of the
-[Gerrit](https://www.gerritcodereview.com/) code review system instead).
-Also, please do not post patches on the issue tracker.
-
 Unless otherwise noted, the Go source files are distributed under
 the BSD-style license found in the LICENSE file.
 
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index b1854ed..27078cf 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -44,12 +44,17 @@
 Adam Eijdenberg <adam@continusec.com>
 Adam Kisala <adam.kisala@gmail.com>
 Adam Langley <agl@golang.org>
+Adam Thomason <athomason@gmail.com>
 Aditya Mukerjee <dev@chimeracoder.net>
+Adrian Hesketh <adrianhesketh@hushmail.com>
 Adrian Nos <nos.adrian@gmail.com>
 Adrian O'Grady <elpollouk@gmail.com>
 Adrien Bustany <adrien-xx-google@bustany.org>
 Aécio Júnior <aeciodantasjunior@gmail.com>
+Aeneas Rekkas (arekkas) <aeneas@ory.am>
+Afanasev Stanislav <phpprogger@gmail.com>
 Agis Anastasopoulos <agis.anast@gmail.com>
+Agniva De Sarker <agnivade@yahoo.co.in>
 Ahmed Waheed Moanes <oneofone@gmail.com>
 Ahmet Alp Balkan <ahmetb@google.com>
 Ahmy Yulrizka <yulrizka@gmail.com>
@@ -90,6 +95,7 @@
 Alexander Morozov <lk4d4math@gmail.com>
 Alexander Neumann <alexander@bumpern.de>
 Alexander Orlov <alexander.orlov@loxal.net>
+Alexander Pantyukhin <apantykhin@gmail.com>
 Alexander Polcyn <apolcyn@google.com>
 Alexander Reece <awreece@gmail.com>
 Alexander Surma <surma@surmair.de>
@@ -98,6 +104,7 @@
 Alexandre Cesaro <alexandre.cesaro@gmail.com>
 Alexandre Fiori <fiorix@gmail.com>
 Alexandre Normand <alexandre.normand@gmail.com>
+Alexandre Parentea <aubonbeurre@gmail.com>
 Alexandru Moșoi <brtzsnr@gmail.com>
 Alexei Sholik <alcosholik@gmail.com>
 Alexey Borzenkov <snaury@gmail.com>
@@ -110,8 +117,10 @@
 Alif Rachmawadi <subosito@gmail.com>
 Allan Simon <allan.simon@supinfo.com>
 Alok Menghrajani <alok.menghrajani@gmail.com>
+Aman Gupta <aman@tmm1.net>
 Amir Mohammad Saied <amir@gluegadget.com>
 Amrut Joshi <amrut.joshi@gmail.com>
+Anand K. Mistry <anand@mistry.ninja>
 Anders Pearson <anders@columbia.edu>
 André Carvalho <asantostc@gmail.com>
 Andre Nathan <andrenth@gmail.com>
@@ -144,7 +153,10 @@
 Andrew Williams <williams.andrew@gmail.com>
 Andrey Mirtchovski <mirtchovski@gmail.com>
 Andrey Petrov <andrey.petrov@shazow.net>
+Andrii Soldatenko <andrii.soldatenko@gmail.com>
+Andrii Soluk <isoluchok@gmail.com>
 Andriy Lytvynov <lytvynov.a.v@gmail.com>
+Andrzej Żeżel <andrii.zhezhel@gmail.com>
 Andy Balholm <andy@balholm.com>
 Andy Davis <andy@bigandian.com>
 Andy Finkenstadt <afinkenstadt@zynga.com>
@@ -155,9 +167,11 @@
 Anh Hai Trinh <anh.hai.trinh@gmail.com>
 Anmol Sethi <anmol@aubble.com>
 Anschel Schaffer-Cohen <anschelsc@gmail.com>
+Anthony Alves <cvballa3g0@gmail.com>
 Anthony Canino <anthony.canino1@gmail.com>
 Anthony Eufemio <anthony.eufemio@gmail.com>
 Anthony Martin <ality@pbrane.org>
+Anthony Sottile <asottile@umich.edu>
 Anthony Starks <ajstarks@gmail.com>
 Anthony Voutas <voutasaurus@gmail.com>
 Anthony Woods <awoods@raintank.io>
@@ -168,6 +182,7 @@
 Apisak Darakananda <pongad@gmail.com>
 Aram Hăvărneanu <aram@mgk.ro>
 Areski Belaid <areski@gmail.com>
+Ariel Mashraki <ariel@mashraki.co.il>
 Arkadi Pyuro <arkadi@google.com>
 Arlo Breault <arlolra@gmail.com>
 Arnaud Ysmal <arnaud.ysmal@gmail.com>
@@ -185,6 +200,7 @@
 Austin Clements <austin@google.com> <aclements@csail.mit.edu>
 awaw fumin <awawfumin@gmail.com>
 Awn Umar <awn@cryptolosophy.io>
+Axel Wagner <axel.wagner.hh@googlemail.com>
 Ayanamist Yang <ayanamist@gmail.com>
 Aymerick Jéhanne <aymerick@jehanne.org>
 Baiju Muthukadan <baiju.m.mail@gmail.com>
@@ -194,9 +210,12 @@
 Ben Burkert <ben@benburkert.com>
 Ben Eitzen <eitzenb@golang.org>
 Ben Fried <ben.fried@gmail.com>
+Ben Haines <bhainesva@gmail.com>
+Ben Laurie <ben@links.org> <benl@google.com>
 Ben Lubar <ben.lubar@gmail.com>
 Ben Lynn <benlynn@gmail.com>
 Ben Olive <sionide21@gmail.com>
+Ben Schwartz <bemasc@google.com>
 Ben Shi <powerman1st@163.com>
 Benjamin Black <b@b3k.us>
 Benjamin Prosnitz <bprosnitz@google.com>
@@ -212,11 +231,15 @@
 Billy Lynch <wlynch@google.com>
 Bjorn Tillenius <bjorn@tillenius.me>
 Bjorn Tipling <bjorn.tipling@gmail.com>
+Blain Smith <rebelgeek@blainsmith.com>
 Blake Gentry <blakesgentry@gmail.com>
+Blake Mesdag <blakemesdag@gmail.com>
 Blake Mizerany <blake.mizerany@gmail.com>
 Blixt <me@blixt.nyc>
 Bobby Powers <bobbypowers@gmail.com>
 Boris Nagaev <nagaev@google.com>
+Borja Clemente <borja.clemente@gmail.com>
+Brad Burch <brad.burch@gmail.com>
 Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com>
 Brad Garcia <bgarcia@golang.org>
 Brad Jones <rbjones@google.com>
@@ -229,11 +252,13 @@
 Brendan Daniel Tracey <tracey.brendan@gmail.com>
 Brendan O'Dea <bod@golang.org>
 Brett Cannon <bcannon@gmail.com>
+Brett Merrill <brett.j.merrill94@gmail.com>
 Brian Dellisanti <briandellisanti@gmail.com>
 Brian Downs <brian.downs@gmail.com>
 Brian G. Merrell <bgmerrell@gmail.com>
 Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
 Brian Kennedy <btkennedy@gmail.com>
+Brian Kessler <brian.m.kessler@gmail.com>
 Brian Ketelsen <bketelsen@gmail.com>
 Brian Slesinsky <skybrian@google.com>
 Brian Smith <ohohvi@gmail.com>
@@ -243,6 +268,7 @@
 Bryan Chan <bryan.chan@ca.ibm.com>
 Bryan Ford <brynosaurus@gmail.com>
 Bulat Gaifullin <gaifullinbf@gmail.com>
+Burak Guven <bguven@gmail.com>
 Caine Tighe <arctanofyourface@gmail.com>
 Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
 Caleb Spare <cespare@gmail.com>
@@ -266,11 +292,14 @@
 Cedric Staub <cs@squareup.com>
 Cezar Sá Espinola <cezarsa@gmail.com>
 ChaiShushan <chaishushan@gmail.com>
+Charles Fenwick Elliott <Charles@FenwickElliott.io>
 Charles L. Dorian <cldorian@gmail.com>
 Charles Lee <zombie.fml@gmail.com>
 Charles Weill <weill@google.com>
 Cherry Zhang <cherryyz@google.com>
 Chew Choon Keat <choonkeat@gmail.com>
+Cholerae Hu <choleraehyq@gmail.com>
+Chris Ball <chris@printf.net>
 Chris Biscardi <chris@christopherbiscardi.com>
 Chris Broadfoot <cbro@golang.org>
 Chris Dollin <ehog.hedge@gmail.com>
@@ -287,6 +316,7 @@
 Chris Roche <rodaine@gmail.com>
 Chris Stockton <chrisstocktonaz@gmail.com>
 Chris Zou <chriszou@ca.ibm.com>
+Christian Alexander <christian@linux.com>
 Christian Couder <chriscool@tuxfamily.org>
 Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
 Christine Hansmann <chhansmann@gmail.com>
@@ -294,11 +324,14 @@
 Christoph Hack <christoph@tux21b.org>
 Christopher Cahoon <chris.cahoon@gmail.com>
 Christopher Guiney <chris@guiney.net>
+Christopher Henderson <chris@chenderson.org>
+Christopher Koch <chrisko@google.com>
 Christopher Nelson <nadiasvertex@gmail.com>
 Christopher Nielsen <m4dh4tt3r@gmail.com>
 Christopher Redden <christopher.redden@gmail.com>
 Christopher Swenson <cswenson@google.com>
 Christopher Wedgwood <cw@f00f.org>
+Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
 Christy Perez <christy@linux.vnet.ibm.com>
 CL Sung <clsung@gmail.com> <cl_sung@htc.com>
 Clement Skau <clementskau@gmail.com>
@@ -341,6 +374,8 @@
 Daniel Speichert <daniel@speichert.pl>
 Daniel Theophanes <kardianos@gmail.com>
 Daniel Upton <daniel@floppy.co>
+Daniela Petruzalek <daniela.petruzalek@gmail.com>
+Danny Rosseau <daniel.rosseau@gmail.com>
 Daria Kolistratova <daria.kolistratova@intel.com>
 Darren Elwood <darren@textnode.com>
 Datong Sun <dndx@idndx.com>
@@ -379,6 +414,7 @@
 David Titarenco <david.titarenco@gmail.com>
 David Volquartz Lebech <david@lebech.info>
 Davies Liu <davies.liu@gmail.com>
+Davor Kapsa <davor.kapsa@gmail.com>
 Dean Prichard <dean.prichard@gmail.com>
 Deepak Jois <deepak.jois@gmail.com>
 Denis Bernard <db047h@gmail.com>
@@ -425,14 +461,18 @@
 Dustin Shields-Cloues <dcloues@gmail.com>
 Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
 Dylan Waits <dylan@waits.io>
+Edan Bedrik <3d4nb3@gmail.com>
 Eden Li <eden.li@gmail.com>
 Edward Muller <edwardam@interlix.com>
 Egon Elbre <egonelbre@gmail.com>
 Ehren Kret <ehren.kret@gmail.com>
 Eitan Adler <lists@eitanadler.com>
 Eivind Uggedal <eivind@uggedal.com>
+Elbert Fliek <efliek@gmail.com>
+Elena Grahovac <elena@grahovac.me>
 Elias Naur <elias.naur@gmail.com>
 Elliot Morrison-Reed <elliotmr@gmail.com>
+Emerson Lin <linyintor@gmail.com>
 Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
 Emilien Kenler <hello@emilienkenler.com>
 Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
@@ -444,6 +484,7 @@
 Eric Koleda <ekoleda+devrel@google.com>
 Eric Lagergren <ericscottlagergren@gmail.com>
 Eric Milliken <emilliken@gmail.com>
+Eric Rescorla <ekr@rtfm.com>
 Eric Roshan-Eisner <eric.d.eisner@gmail.com>
 Erik Aigner <aigner.erik@gmail.com>
 Erik Dubbelboer <erik@dubbelboer.com>
@@ -458,6 +499,7 @@
 Evan Broder <evan@stripe.com>
 Evan Brown <evanbrown@google.com>
 Evan Hicks <evan.hicks2@gmail.com>
+Evan Jones <ej@evanjones.ca>
 Evan Kroske <evankroske@google.com>
 Evan Martin <evan.martin@gmail.com>
 Evan Phoenix <evan@phx.io>
@@ -492,6 +534,8 @@
 Francisco Claude <fclaude@recoded.cl>
 Francisco Rojas <francisco.rojas.gallegos@gmail.com>
 Francisco Souza <franciscossouza@gmail.com>
+Frank Somers <fsomers@arista.com>
+Frederic Guillot <frederic.guillot@gmail.com>
 Frederick Kelly Mayle III <frederickmayle@gmail.com>
 Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
 Fredrik Forsmo <fredrik.forsmo@gmail.com>
@@ -504,6 +548,7 @@
 Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
 Gabriel Russell <gabriel.russell@gmail.com>
 Gareth Paul Jones <gpj@foursquare.com>
+Garret Kelly <gdk@google.com>
 Garrick Evans <garrick@google.com>
 Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com>
 Gary Elliott <garyelliott@google.com>
@@ -511,6 +556,7 @@
 Gautham Thambidorai <gautham.dorai@gmail.com>
 Geert-Johan Riemer <gjr19912@gmail.com>
 Gengliang Wang <ltnwgl@gmail.com>
+Geoff Berry <gberry.qdt@qualcommdatacenter.com>
 Geoffroy Lorieux <lorieux.g@gmail.com>
 Georg Reinke <guelfey@gmail.com>
 George Gkirtsou <ggirtsou@gmail.com>
@@ -526,9 +572,12 @@
 Gordon Klaus <gordon.klaus@gmail.com>
 Graham King <graham4king@gmail.com>
 Graham Miller <graham.miller@gmail.com>
+Grant Griffiths <ggp493@gmail.com>
 Greg Poirier <greg.istehbest@gmail.com>
 Greg Ward <greg@gerg.ca>
 Gregory Man <man.gregory@gmail.com>
+Guilherme Garnier <guilherme.garnier@gmail.com>
+Guilherme Rezende <guilhermebr@gmail.com>
 Guillaume J. Charmes <guillaume@charmes.net>
 Guobiao Mei <meiguobiao@gmail.com>
 Gustav Paul <gustav.paul@gmail.com>
@@ -542,6 +591,7 @@
 Hallgrimur Gunnarsson <halg@google.com>
 Han-Wen Nienhuys <hanwen@google.com>
 Hang Qian <hangqian90@gmail.com>
+Hanjun Kim <hallazzang@gmail.com>
 Hari haran <hariharan.uno@gmail.com>
 Hariharan Srinath <srinathh@gmail.com>
 Harley Laue <losinggeneration@gmail.com>
@@ -554,9 +604,14 @@
 Henning Schmiedehausen <henning@schmiedehausen.org>
 Henrik Edwards <henrik.edwards@gmail.com>
 Henrik Hodne <henrik@hodne.io>
+Henry Adi Sumarto <henry.adisumarto@gmail.com>
+Henry Bubert <google@mindeco.de>
 Henry Chang <mr.changyuheng@gmail.com>
 Herbert Georg Fischer <herbert.fischer@gmail.com>
+Herbie Ong <herbie@google.com>
 Heschi Kreinick <heschi@google.com>
+Hilko Bengen <bengen@hilluzination.de>
+Hiroaki Nakamura <hnakamur@gmail.com>
 Hironao OTSUBO <motemen@gmail.com>
 Hiroshi Ioka <hirochachacha@gmail.com>
 Hitoshi Mitake <mitake.hitoshi@gmail.com>
@@ -570,6 +625,7 @@
 Hugues Bruant <hugues.bruant@gmail.com>
 Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
 Ian Gudger <ian@loosescre.ws>
+Ian Kent <iankent85@gmail.com>
 Ian Lance Taylor <iant@golang.org>
 Ibrahim AshShohail <ibra.sho@gmail.com>
 Icarus Sparry <golang@icarus.freeuk.com>
@@ -577,13 +633,17 @@
 Idora Shinatose <idora.shinatose@gmail.com>
 Igor Bernstein <igorbernstein@google.com>
 Igor Dolzhikov <bluesriverz@gmail.com>
+Igor Vashyst <ivashyst@gmail.com>
 Ilya Tocar <ilya.tocar@intel.com>
 INADA Naoki <songofacandy@gmail.com>
+Inanc Gumus <m@inanc.io>
 Ingo Krabbe <ikrabbe.ask@gmail.com>
 Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com>
 Irieda Noboru <irieda@gmail.com>
 Isaac Wagner <ibw@isaacwagner.me>
+Iskander Sharipov <iskander.sharipov@intel.com>
 Ivan Babrou <ivan@cloudflare.com>
+Ivan Bertona <ivan.bertona@gmail.com>
 Ivan Krasin <krasin@golang.org>
 Ivan Moscoso <moscoso@gmail.com>
 Ivan Ukhov <ivan.ukhov@gmail.com>
@@ -605,6 +665,7 @@
 James Fysh <james.fysh@gmail.com>
 James Gray <james@james4k.com>
 James Hartig <fastest963@gmail.com>
+James Lawrence <jljatone@gmail.com>
 James Meneghello <rawrz0r@gmail.com>
 James Myers <jfmyers9@gmail.com>
 James Neve <jamesoneve@gmail.com>
@@ -614,11 +675,13 @@
 James Smith <jrs1995@icloud.com>
 James Sweet <james.sweet88@googlemail.com>
 James Toy <nil@opensesame.st>
+James Treanor <jtreanor3@gmail.com>
 James Tucker <raggi@google.com>
 James Whitehead <jnwhiteh@gmail.com>
 Jamie Beverly <jamie.r.beverly@gmail.com>
 Jamie Gennis <jgennis@google.com> <jgennis@gmail.com>
 Jamie Kerr <jkerr113@googlemail.com>
+Jamie Liu <jamieliu@google.com>
 Jamie Stackhouse <contin673@gmail.com>
 Jamie Turner <jamwt@dropbox.com>
 Jamie Wilkinson <jaq@spacepants.org>
@@ -630,6 +693,7 @@
 Jan Newmarch <jan.newmarch@gmail.com>
 Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
 Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
+Jared Culp <jculp14@gmail.com>
 Jaroslavas Počepko <jp@webmaster.ms>
 Jason Barnett <jason.w.barnett@gmail.com>
 Jason Buberel <jbuberel@google.com>
@@ -638,11 +702,15 @@
 Jason Hall <jasonhall@google.com>
 Jason Smale <jsmale@zendesk.com>
 Jason Travis <infomaniac7@gmail.com>
+Jason Wangsadinata <jwangsadinata@gmail.com>
+Javier Segura <javism@gmail.com>
 Jay Conrod <jayconrod@google.com>
 Jay Weisskopf <jay@jayschwa.net>
+Jean-Francois Cantin <jfcantin@gmail.com>
 Jean-Marc Eurin <jmeurin@google.com>
 Jean-Nicolas Moal <jn.moal@gmail.com>
 Jed Denlea <jed@fastly.com>
+Jeet Parekh <jeetparekh96@gmail.com>
 Jeff (Zhefu) Jiang <jeffjiang@google.com>
 Jeff Craig <jeffcraig@google.com>
 Jeff Hodges <jeff@somethingsimilar.com>
@@ -651,6 +719,7 @@
 Jeff Sickel <jas@corpus-callosum.com>
 Jeff Wendling <jeff@spacemonkey.com>
 Jeffrey H <jeffreyh192@gmail.com>
+Jelte Fennema <github-tech@jeltef.nl>
 Jens Frederich <jfrederich@gmail.com>
 Jeremiah Harmsen <jeremiah@google.com>
 Jeremy Jackins <jeremyjackins@gmail.com>
@@ -664,12 +733,14 @@
 Jim Cote <jfcote87@gmail.com>
 Jim Kingdon <jim@bolt.me>
 Jim McGrath <jimmc2@gmail.com>
+Jimmy Frasche <soapboxcicero@gmail.com>
 Jimmy Zelinskie <jimmyzelinskie@gmail.com>
 Jin-wook Jeong <jeweljar@hanmail.net>
 Jingcheng Zhang <diogin@gmail.com>
 Jingguo Yao <yaojingguo@gmail.com>
 Jiong Du <londevil@gmail.com>
 Jirka Daněk <dnk@mail.muni.cz>
+Jiulong Wang <jiulongw@gmail.com>
 Joakim Sernbrant <serbaut@gmail.com>
 Joe Farrell <joe2farrell@gmail.com>
 Joe Harrison <joehazzers@gmail.com>
@@ -734,10 +805,13 @@
 Josh Roppo <joshroppo@gmail.com>
 Joshua Boelter <joshua.boelter@intel.com>
 Joshua Chase <jcjoshuachase@gmail.com>
+Joshua Rubin <joshua@rubixconsulting.com>
 Josselin Costanzi <josselin@costanzi.fr>
 Jostein Stuhaug <js@solidsystem.no>
 JP Sugarbroad <jpsugar@google.com>
 JT Olds <jtolds@xnet5.com>
+Juan Carlos <juanjcsr@gmail.com>
+Jude Pereira <judebpereira@gmail.com>
 Jukka-Pekka Kekkonen <karatepekka@gmail.com>
 Julia Hansbrough <flowerhack@google.com>
 Julian Kornberger <jk+github@digineo.de>
@@ -746,6 +820,7 @@
 Julien Schmidt <google@julienschmidt.com>
 Julio Montes <julio.montes@intel.com>
 Jungho Ahn <jhahn@google.com>
+Junya Hayashi <ledmonster@gmail.com>
 Jure Ham <jure.ham@zemanta.com>
 Justin Nuß <nuss.justin@gmail.com>
 Justyn Temme <justyntemme@gmail.com>
@@ -758,7 +833,9 @@
 Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
 Kang Hu <hukangustc@gmail.com>
 Karan Dhiman <karandhi@ca.ibm.com>
+Karel Pazdera <pazderak@gmail.com>
 Karoly Negyesi <chx1975@gmail.com>
+Karsten Köhler <karsten.koehler95@gmail.com>
 Kashav Madan <kshvmdn@gmail.com>
 Kate Manson <kate.manson@izettle.com>
 Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@@ -779,6 +856,7 @@
 Ken Sedgwick <ken@bonsai.com>
 Ken Thompson <ken@golang.org>
 Kenji Kaneda <kenji.kaneda@gmail.com>
+Kenji Yano <kenji.yano@gmail.com>
 Kenneth Shaw <kenshaw@gmail.com>
 Kenny Grant <kennygrant@gmail.com>
 Kevin Ballard <kevin@sb.org>
@@ -786,10 +864,13 @@
 Kevin Kirsche <kev.kirsche@gmail.com>
 Kevin Klues <klueska@gmail.com> <klueska@google.com>
 Kevin Malachowski <chowski@google.com>
+Kevin Ruffin <kruffin@gmail.com>
 Kevin Vu <kevin.m.vu@gmail.com>
+Kieran Colford <kieran@kcolford.com>
 Kim Shrier <kshrier@racktopsystems.com>
 Kim Yongbin <kybinz@gmail.com>
 Kirill Smelkov <kirr@nexedi.com>
+Kirk Han <kirk91.han@gmail.com>
 Kirklin McDonald <kirklin.mcdonald@gmail.com>
 Klaus Post <klauspost@gmail.com>
 Kodie Goodwin <kodiegoodwin@gmail.com>
@@ -801,31 +882,40 @@
 Kris Rousey <krousey@google.com>
 Kristopher Watts <traetox@gmail.com>
 Kun Li <likunarmstrong@gmail.com>
+Kunpei Sakai <namusyaka@gmail.com>
 Kyle Consalus <consalus@gmail.com>
 Kyle Isom <kyle@gokyle.net>
 Kyle Jones <kyle@kyledj.com>
 Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
+Kyle Shannon <kyle@pobox.com>
+Kyohei Kadota <lufia@lufia.org>
 Kyrylo Silin <silin@kyrylo.org>
 L Campbell <unpantsu@gmail.com>
 Lai Jiangshan <eag0628@gmail.com>
+Lakshay Garg <lakshay.garg.1996@gmail.com>
+Lann Martin <lannm@google.com>
 Larry Hosken <lahosken@golang.org>
 Lars Jeppesen <jeppesen.lars@gmail.com>
 Lars Wiegman <lars@namsral.com>
 Larz Conwell <larzconwell@gmail.com>
+Laurent Voisin <lpvoisin@gmail.com>
 Laurie Clark-Michalek <laurie@qubit.com>
 LE Manh Cuong <cuong.manhle.vn@gmail.com>
 Lee Hinman <hinman@gmail.com>
 Lee Packham <lpackham@gmail.com>
+Leigh McCulloch <leighmcc@gmail.com>
 Leo Rudberg <ljr@google.com>
 Leon Klingele <git@leonklingele.de>
 Lev Shamardin <shamardin@gmail.com>
 Lewin Bormann <lewin.bormann@gmail.com>
 Lion Yang <lion@aosc.xyz>
 Lloyd Dewolf <foolswisdom@gmail.com>
+Lorenz Bauer <lmb@cloudflare.com>
 Lorenzo Masini <rugginoso@develer.com>
 Lorenzo Stoakes <lstoakes@gmail.com>
 Louis Kruger <louisk@google.com>
 Luan Santos <cfcluan@gmail.com>
+Luca Bruno <luca.bruno@coreos.com>
 Luca Greco <luca.greco@alcacoop.it>
 Lucas Bremgartner <lucas.bremgartner@gmail.com>
 Lucas Clemente <lclemente@google.com>
@@ -837,15 +927,20 @@
 Luka Zakrajšek <tr00.g33k@gmail.com>
 Lukasz Milewski <lmmilewski@gmail.com>
 Luke Curley <qpingu@gmail.com>
+Luke Granger-Brown <git@lukegb.com>
 Luna Duclos <luna.duclos@palmstonegames.com>
 Luuk van Dijk <lvd@golang.org> <lvd@google.com>
+Lyle Franklin <lylejfranklin@gmail.com>
 Lynn Boger <laboger@linux.vnet.ibm.com>
 Ma Peiqi <mapeiqi2017@gmail.com>
 Magnus Hiie <magnus.hiie@gmail.com>
+Maicon Costa <maiconscosta@gmail.com>
 Maksym Trykur <maksym.trykur@gmail.com>
 Mal Curtis <mal@mal.co.nz>
 Manfred Touron <m@42.am>
+Manish Goregaokar <manishsmail@gmail.com>
 Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
+Mansour Rahimi <rahimi.mnr@gmail.com>
 Manu Garg <manugarg@google.com>
 Manu S Ajith <neo@codingarena.in>
 Manuel Mendez <mmendez534@gmail.com>
@@ -861,9 +956,12 @@
 Mark Adams <mark@markadams.me>
 Mark Bucciarelli <mkbucc@gmail.com>
 Mark Harrison <marhar@google.com>
+Mark Percival <m@mdp.im>
+Mark Pulford <mark@kyne.com.au>
 Mark Ryan <mark.d.ryan@intel.com>
 Mark Severson <miquella@gmail.com>
 Mark Theunissen <mark.theunissen@gmail.com>
+Mark Wolfe <mark@wolfe.id.au>
 Mark Zavislak <zavislak@google.com>
 Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
 Marko Mikulicic <mkm@google.com>
@@ -884,6 +982,7 @@
 Martin Olsen <github.com@martinolsen.net>
 Martin Olsson <martin@minimum.se>
 Martin Probst <martin@probst.io>
+Martins Sipenko <martins.sipenko@gmail.com>
 Martynas Budriūnas <mabu@google.com>
 Marvin Stenger <marvin.stenger94@gmail.com>
 Marwan Sulaiman <marwan.sulaiman@work.co>
@@ -891,7 +990,10 @@
 Masahiro Furudate <masahiro.furudate@gmail.com>
 Masahiro Wakame <vvakame@gmail.com>
 Masaki Yoshida <yoshida.masaki@gmail.com>
+Mat Byczkowski <mbyczkowski@gmail.com>
 Máté Gulyás <mgulyas86@gmail.com>
+Matej Baćo <matejbaco@gmail.com>
+Mateus Amin <mateus.amin@gmail.com>
 Mateusz Czapliński <czapkofan@gmail.com>
 Mathias Beke <git@denbeke.be>
 Mathias Hall-Andersen <mathias@hall-andersen.dk>
@@ -902,6 +1004,7 @@
 Matt Blair <me@matthewblair.net>
 Matt Bostock <matt@mattbostock.com>
 Matt Brown <mdbrown@google.com>
+Matt Dee <mdee@hioscar.com>
 Matt Drollette <matt@drollette.com>
 Matt Harden <matt.harden@gmail.com>
 Matt Jibson <matt.jibson@gmail.com>
@@ -914,6 +1017,7 @@
 Matt T. Proud <matt.proud@gmail.com>
 Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com>
 Matthew Brennan <matty.brennan@gmail.com>
+Matthew Broberg <matthewbbroberg@gmail.com>
 Matthew Cottingham <mattcottingham@gmail.com>
 Matthew Dempsky <mdempsky@google.com>
 Matthew Denton <mdenton@skyportsystems.com>
@@ -921,17 +1025,21 @@
 Matthew Horsnell <matthew.horsnell@gmail.com>
 Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
 Matthieu Olivier <olivier.matthieu@gmail.com>
+Matthijs Kooijman <matthijs@stdin.nl>
 Max Riveiro <kavu13@gmail.com>
+Max Schmitt <max@schmitt.mx>
 Maxim Khitrov <max@mxcrypt.com>
 Maxim Pimenov <mpimenov@google.com>
 Maxim Ushakov <ushakov@google.com>
 Maxime de Roucy <maxime.deroucy@gmail.com>
 Máximo Cuadros Ortiz <mcuadros@gmail.com>
 Maxwell Krohn <themax@gmail.com>
+Mayank Kumar <krmayankk@gmail.com>
 Meir Fischer <meirfischer@gmail.com>
 Meng Zhuo <mengzhuo1203@gmail.com>
 Mhd Sulhan <m.shulhan@gmail.com>
 Micah Stetson <micah.stetson@gmail.com>
+Michael Brandenburg <mbrandenburg@bolste.com>
 Michael Chaten <mchaten@gmail.com>
 Michael Darakananda <pongad@google.com>
 Michael Edwards <medwards@walledcity.ca>
@@ -949,25 +1057,30 @@
 Michael Matloob <matloob@google.com>
 Michael McConville <momcconville@gmail.com>
 Michael McGreevy <mcgreevy@golang.org>
+Michael McLoughlin <mmcloughlin@gmail.com>
 Michael Munday <munday@ca.ibm.com>
 Michael Pearson <mipearson@gmail.com>
 Michael Piatek <piatek@google.com>
 Michael Pratt <mpratt@google.com>
 Michael Schaller <michael@5challer.de>
+Michael Schurter <michael.schurter@gmail.com>
 Michael Shields <mshields@google.com>
 Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
+Michael Steinert <mike.steinert@gmail.com>
 Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
 Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
 Michael Vetter <g.bluehut@gmail.com>
 Michal Bohuslávek <mbohuslavek@gmail.com>
 Michal Cierniak <cierniak@google.com>
 Michał Derkacz <ziutek@lnet.pl>
+Michal Pristas <michal.pristas@gmail.com>
 Michalis Kargakis <michaliskargakis@gmail.com>
 Michel Lespinasse <walken@google.com>
 Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
 Miguel Mendez <stxmendez@gmail.com>
 Miguel Molina <hi@mvader.me>
 Mihai Borobocea <MihaiBorobocea@gmail.com>
+Mihail Minaev <minaev.mike@gmail.com>
 Mikael Tillenius <mikti42@gmail.com>
 Mike Andrews <mra@xoba.com>
 Mike Appleby <mike@app.leby.org>
@@ -995,9 +1108,11 @@
 Môshe van der Sterre <moshevds@gmail.com>
 Mostyn Bramley-Moore <mostyn@antipode.se>
 Mrunal Patel <mrunalp@gmail.com>
+Muhammad Falak R Wani <falakreyaz@gmail.com>
 Muhammed Uluyol <uluyol0@gmail.com>
 Mura Li <mura_li@castech.com.tw>
 Nan Deng <monnand@gmail.com>
+Naoki Kanatani <k12naoki@gmail.com>
 Nathan Caza <mastercactapus@gmail.com>
 Nathan Humphreys <nkhumphreys@gmail.com>
 Nathan John Youngman <nj@nathany.com>
@@ -1027,6 +1142,7 @@
 Nick Patavalis <nick.patavalis@gmail.com>
 Nick Petroni <npetroni@cs.umd.edu>
 Nick Robinson <nrobinson13@gmail.com>
+Nicolas BRULEZ <n.brulez@gmail.com>
 Nicolas Kaiser <nikai@nikai.net>
 Nicolas Owens <mischief@offblast.org>
 Nicolas S. Dade <nic.dade@gmail.com>
@@ -1037,8 +1153,10 @@
 Niklas Schnelle <niklas.schnelle@gmail.com>
 Niko Dziemba <niko@dziemba.com>
 Nikolay Turpitko <nikolay@turpitko.com>
+Nils Larsgård <nilsmagnus@gmail.com>
 Niranjan Godbole <niranjan8192@gmail.com>
 Noah Campbell <noahcampbell@gmail.com>
+Noble Johnson <noblepoly@gmail.com>
 Nodir Turakulov <nodir@google.com>
 Norberto Lopes <nlopes.ml@gmail.com>
 Odin Ugedal <odin@ugedal.com>
@@ -1073,6 +1191,7 @@
 Patrick Smith <pat42smith@gmail.com>
 Paul A Querna <paul.querna@gmail.com>
 Paul Borman <borman@google.com>
+Paul Boyd <boyd.paul2@gmail.com>
 Paul Chang <paulchang@google.com>
 Paul Hammond <paul@paulhammond.org>
 Paul Hankin <paulhankin@google.com>
@@ -1081,8 +1200,10 @@
 Paul Marks <pmarks@google.com>
 Paul Meyer <paul.meyer@microsoft.com>
 Paul Nasrat <pnasrat@google.com>
+Paul PISCUC <paul.piscuc@gmail.com>
 Paul Querna <pquerna@apache.org>
 Paul Rosania <paul.rosania@gmail.com>
+Paul Ruest <pruest@gmail.com>
 Paul Sbarra <Sbarra.Paul@gmail.com>
 Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
 Paul van Brouwershaven <paul@vanbrouwershaven.com>
@@ -1116,6 +1237,8 @@
 Peter Waller <peter.waller@gmail.com>
 Peter Weinberger <pjw@golang.org>
 Peter Williams <pwil3058@gmail.com>
+Peter Wu <pwu@cloudflare.com>
+Petrica Voicu <pvoicu@paypal.com>
 Phil Pennock <pdp@golang.org>
 Philip Børgesen <philip.borgesen@gmail.com>
 Philip Hofer <phofer@umich.edu>
@@ -1125,6 +1248,7 @@
 Piers <google@hellopiers.pro>
 Pieter Droogendijk <pieter@binky.org.uk>
 Pietro Gagliardi <pietro10@mac.com>
+Pontus Leitzler <leitzler@gmail.com>
 Prasanna Swaminathan <prasanna@mediamath.com>
 Prashant Varanasi <prashant@prashantv.com>
 Pravendra Singh <hackpravj@gmail.com>
@@ -1137,19 +1261,25 @@
 Quentin Smith <quentin@golang.org>
 Quinn Slack <sqs@sourcegraph.com>
 Quoc-Viet Nguyen <afelion@gmail.com>
+Radek Sohlich <sohlich@gmail.com>
 Radu Berinde <radu@cockroachlabs.com>
 Rafal Jeczalik <rjeczalik@gmail.com>
 Rahul Chaudhry <rahulchaudhry@chromium.org>
 Raif S. Naffah <go@naffah-raif.name>
 Rajat Goel <rajat.goel2010@gmail.com>
+Rajath Agasthya <rajathagasthya@gmail.com>
+Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
 Ralph Corderoy <ralph@inputplus.co.uk>
+Ramazan AYYILDIZ <rayyildiz@gmail.com>
 Ramesh Dharan <dharan@google.com>
 Raph Levien <raph@google.com>
 Raphael Geronimi <raphael.geronimi@gmail.com>
 Raul Silvera <rsilvera@google.com>
+RaviTeja Pothana <ravi.tezu@gmail.com>
 Ray Tung <rtung@thoughtworks.com>
 Raymond Kazlauskas <raima220@gmail.com>
 Rebecca Stambler <rstambler@golang.org>
+Reilly Watson <reillywatson@gmail.com>
 Reinaldo de Souza Jr <juniorz@gmail.com>
 Remi Gillig <remigillig@gmail.com>
 Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
@@ -1187,10 +1317,13 @@
 Roger Pau Monné <royger@gmail.com>
 Roger Peppe <rogpeppe@gmail.com>
 Roland Shoemaker <rolandshoemaker@gmail.com>
+Roman Budnikov <romanyx90@yandex.ru>
 Ron Hashimoto <mail@h2so5.net>
 Ron Minnich <rminnich@gmail.com>
+Ross Chater <rdchater@gmail.com>
 Ross Light <light@google.com> <rlight2@gmail.com>
 Rowan Worth <sqweek@gmail.com>
+Rudi Kramer <rudi.kramer@gmail.com>
 Rui Ueyama <ruiu@google.com>
 Russ Cox <rsc@golang.org>
 Russell Haering <russellhaering@gmail.com>
@@ -1202,6 +1335,8 @@
 Ryan Lower <rpjlower@gmail.com>
 Ryan Seys <ryan@ryanseys.com>
 Ryan Slade <ryanslade@gmail.com>
+Ryoichi KATO <ryo1kato@gmail.com>
+Ryuji Iwata <qt.luigi@gmail.com>
 Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
 S.Çağlar Onur <caglar@10ur.org>
 Sai Cheemalapati <saicheems@google.com>
@@ -1223,6 +1358,7 @@
 Sasha Sobol <sasha@scaledinference.com>
 Scott Barron <scott.barron@github.com>
 Scott Bell <scott@sctsm.com>
+Scott Crunkleton <crunk1@gmail.com>
 Scott Ferguson <scottwferg@gmail.com>
 Scott Lawrence <bytbox@gmail.com>
 Scott Mansfield <smansfield@netflix.com>
@@ -1236,11 +1372,15 @@
 Sean Rees <sean@erifax.org>
 Sebastien Binet <seb.binet@gmail.com>
 Sébastien Paolacci <sebastien.paolacci@gmail.com>
+Seiji Takahashi <timaki.st@gmail.com>
 Sergei Skorobogatov <skorobo@rambler.ru>
 Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
 Sergey Arseev <sergey.arseev@intel.com>
+Sergey Frolov <sfrolov@google.com>
 Sergey Mishin <sergeymishine@gmail.com>
+Sergey Semin <gray12511@gmail.com>
 Sergio Luis O. B. Correia <sergio@correia.cc>
+Sergiusz Bazanski <bazanski@gmail.com>
 Seth Hoenig <seth.a.hoenig@gmail.com>
 Seth Vargo <sethvargo@gmail.com>
 Shahar Kohanim <skohanim@gmail.com>
@@ -1270,6 +1410,7 @@
 Sridhar Venkatakrishnan <sridhar@laddoo.net>
 StalkR <stalkr@stalkr.net>
 Stan Schwertly <stan@schwertly.com>
+Stanislav Afanasev <php.progger@gmail.com>
 Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
 Stéphane Travostino <stephane.travostino@gmail.com>
 Stephen Ma <stephenm@golang.org>
@@ -1277,6 +1418,7 @@
 Stephen Searles <stephens2424@gmail.com>
 Stephen Weinberg <stephen@q5comm.com>
 Steve Francia <spf@golang.org>
+Steve Gilbert <stevegilbert23@gmail.com>
 Steve McCoy <mccoyst@gmail.com>
 Steve Newman <snewman@google.com>
 Steve Phillips <elimisteve@gmail.com>
@@ -1288,13 +1430,16 @@
 Steven Wilkin <stevenwilkin@gmail.com>
 Sugu Sougoumarane <ssougou@gmail.com>
 Suharsh Sivakumar <suharshs@google.com>
+Sukrit Handa <sukrit.handa@utoronto.ca>
 Sunny <me@darkowlzz.space>
 Suyash <dextrous93@gmail.com>
 Suzy Mueller <suzmue@golang.org>
 Sven Almgren <sven@tras.se>
 Sven Blumenstein <svbl@google.com>
+Sylvain Zimmer <sylvain@sylvainzimmer.com>
 Syohei YOSHIDA <syohex@gmail.com>
 Szabolcs Nagy <nsz@port70.net>
+Tad Fisher <tadfisher@gmail.com>
 Tad Glines <tad.glines@gmail.com>
 Taj Khattra <taj.khattra@gmail.com>
 Takashi Matsuo <tmatsuo@google.com>
@@ -1303,15 +1448,18 @@
 Takuya Ueda <uedatakuya@gmail.com>
 Tal Shprecher <tshprecher@gmail.com>
 Tamir Duberstein <tamird@gmail.com>
+Tao Wang <twang2218@gmail.com>
 Tarmigan Casebolt <tarmigan@gmail.com>
 Taro Aoki <aizu.s1230022@gmail.com>
 Taru Karttunen <taruti@taruti.net>
 Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
 Ted Kornish <golang@tedkornish.com>
+Terin Stock <terinjokes@gmail.com>
 Terrel Shumway <gopher@shumway.us>
 Tetsuo Kiso <tetsuokiso9@gmail.com>
 Than McIntosh <thanm@google.com>
 Thanatat Tamtan <acoshift@gmail.com>
+Thiago Avelino <t@avelino.xxx>
 Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org>
 Thomas Alan Copeland <talan.copeland@gmail.com>
 Thomas Bonfort <thomas.bonfort@gmail.com>
@@ -1320,19 +1468,23 @@
 Thomas Desrosiers <thomasdesr@gmail.com>
 Thomas Habets <habets@google.com>
 Thomas Kappler <tkappler@gmail.com>
+Thomas Wanielista <tomwans@gmail.com>
 Thorben Krueger <thorben.krueger@gmail.com>
 Thordur Bjornsson <thorduri@secnorth.net>
 Tilman Dilo <tilman.dilo@gmail.com>
 Tim Cooijmans <timcooijmans@gmail.com>
+Tim Cooper <tim.cooper@layeh.com>
 Tim Ebringer <tim.ebringer@gmail.com>
 Tim Heckman <t@heckman.io>
 Tim Henderson <tim.tadh@gmail.com>
 Tim Hockin <thockin@google.com>
 Tim Swast <swast@google.com>
+Tim Wright <tenortim@gmail.com>
 Timo Savola <timo.savola@gmail.com>
 Timo Truyts <alkaloid.btx@gmail.com>
 Timothy Studd <tim@timstudd.com>
 Tipp Moseley <tipp@google.com>
+Tobias Assarsson <tobias.assarsson@gmail.com>
 Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
 Tobias Klauser <tklauser@distanz.ch>
 Toby Burress <kurin@google.com>
@@ -1340,6 +1492,8 @@
 Todd Wang <toddwang@gmail.com>
 Tom Bergan <tombergan@google.com>
 Tom Heng <zhm20070928@gmail.com>
+Tom Lanyon <tomlanyon@google.com>
+Tom Levy <tomlevy93@gmail.com>
 Tom Linford <tomlinford@gmail.com>
 Tom Szymanski <tgs@google.com>
 Tom Wilkie <tom@weave.works>
@@ -1358,9 +1512,12 @@
 Tristan Amini <tamini01@ca.ibm.com>
 Tristan Colgate <tcolgate@gmail.com>
 Tristan Ooohry <ooohry@gmail.com>
+Troels Thomsen <troels@thomsen.io>
 Trung Nguyen <trung.n.k@gmail.com>
 Tudor Golubenco <tudor.g@gmail.com>
+Tugdual Saunier <tugdual.saunier@gmail.com>
 Tuo Shan <sturbo89@gmail.com> <shantuo@google.com>
+Tyler Bui-Palsulich <tpalsulich@google.com>
 Tyler Bunnell <tylerbunnell@gmail.com>
 Tyler Treat <ttreat31@gmail.com>
 Tzu-Jung Lee <roylee17@currant.com>
@@ -1393,10 +1550,13 @@
 Walter Poupore <wpoupore@google.com>
 Wander Lairson Costa <wcosta@mozilla.com>
 Wedson Almeida Filho <wedsonaf@google.com>
+Wèi Cōngruì <crvv.mail@gmail.com>
 Wei Guangjing <vcc.163@gmail.com>
 Wei Xiao <wei.xiao@arm.com>
 Weichao Tang <tevic.tt@gmail.com>
+Wembley G. Leach, Jr <wembley.gl@gmail.com>
 Will Chan <willchan@google.com>
+Will Faught <will.faught@gmail.com>
 Will Norris <willnorris@google.com>
 Will Storey <will@summercat.com>
 Willem van der Schyff <willemvds@gmail.com>
@@ -1405,6 +1565,7 @@
 William Orr <will@worrbase.com> <ay1244@gmail.com>
 Wisdom Omuya <deafgoat@gmail.com>
 Wu Yunzhou <yunzhouwu@gmail.com>
+Xi Ruoyao <xry23333@gmail.com>
 Xia Bin <snyh@snyh.org>
 Xing Xing <mikespook@gmail.com>
 Xu Fei <badgangkiller@gmail.com>
@@ -1412,6 +1573,7 @@
 Xuyang Kang <xuyangkang@gmail.com>
 Yan Zou <yzou@google.com>
 Yann Kerhervé <yann.kerherve@gmail.com>
+Yann Salaün <yannsalaun1@gmail.com>
 Yao Zhang <lunaria21@gmail.com>
 Yasha Bubnov <girokompass@gmail.com>
 Yasuharu Goto <matope.ono@gmail.com>
@@ -1423,23 +1585,30 @@
 Yongjian Xu <i3dmaster@gmail.com>
 Yorman Arias <cixtords@gmail.com>
 Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
+Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
 Yu Heng Zhang <annita.zhang@cn.ibm.com>
 Yu Xuan Zhang <zyxsh@cn.ibm.com>
 Yuki Yugui Sonoda <yugui@google.com>
+Yukihiro Nishinaka <6elpinal@gmail.com>
 Yusuke Kagiwada <block.rxckin.beats@gmail.com>
 Yuusei Kuwana <kuwana@kumama.org>
 Yuval Pavel Zholkover <paulzhol@gmail.com>
 Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
 Zac Bergquist <zbergquist99@gmail.com>
 Zach Bintliff <zbintliff@gmail.com>
+Zach Gershman <zachgersh@gmail.com>
 Zak <zrjknill@gmail.com>
 Zakatell Kanda <hi@zkanda.io>
 Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
 Zev Goldstein <zev.goldstein@gmail.com>
+Zhengyu He <hzy@google.com>
+Zhongtao Chen <chenzhongtao@126.com>
 Zhongwei Yao <zhongwei.yao@arm.com>
 Ziad Hatahet <hatahet@gmail.com>
 Zorion Arrizabalaga <zorionk@gmail.com>
 Максим Федосеев <max.faceless.frei@gmail.com>
+Роман Хавроненко <hagen1778@gmail.com>
+Тарас Буник <tbunyk@gmail.com>
 Фахриддин Балтаев <faxriddinjon@gmail.com>
 张嵩 <zs349596@gmail.com>
 申习之 <bronze1man@gmail.com>
diff --git a/README.md b/README.md
index 57492b3..bb3d895 100644
--- a/README.md
+++ b/README.md
@@ -36,10 +36,9 @@
 To contribute, please read the contribution guidelines:
 	https://golang.org/doc/contribute.html
 
-Note that the Go project does not use GitHub pull requests, and that
-we use the issue tracker for bug reports and proposals only. See
-https://golang.org/wiki/Questions for a list of places to ask
-questions about the Go language.
+Note that the Go project uses the issue tracker for bug reports and
+proposals only. See https://golang.org/wiki/Questions for a list of
+places to ask questions about the Go language.
 
 [rf]: https://reneefrench.blogspot.com/
 [cc3-by]: https://creativecommons.org/licenses/by/3.0/
diff --git a/VERSION b/VERSION
index f213576..95ec39e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.9
\ No newline at end of file
+go1.10
diff --git a/api/except.txt b/api/except.txt
index fbabd18..f8cd0fa 100644
--- a/api/except.txt
+++ b/api/except.txt
@@ -1,4 +1,5 @@
 pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
+pkg math/big, const MaxBase = 36
 pkg math/big, type Word uintptr
 pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
 pkg os (linux-arm), const O_SYNC = 4096
@@ -343,3 +344,4 @@
 pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
 pkg syscall (openbsd-amd64), const SYS_KILL = 37
 pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
+pkg unicode, const Version = "9.0.0"
diff --git a/api/go1.10.txt b/api/go1.10.txt
new file mode 100644
index 0000000..250c10f
--- /dev/null
+++ b/api/go1.10.txt
@@ -0,0 +1,627 @@
+pkg archive/tar, const FormatGNU = 8
+pkg archive/tar, const FormatGNU Format
+pkg archive/tar, const FormatPAX = 4
+pkg archive/tar, const FormatPAX Format
+pkg archive/tar, const FormatUSTAR = 2
+pkg archive/tar, const FormatUSTAR Format
+pkg archive/tar, const FormatUnknown = 0
+pkg archive/tar, const FormatUnknown Format
+pkg archive/tar, method (Format) String() string
+pkg archive/tar, type Format int
+pkg archive/tar, type Header struct, Format Format
+pkg archive/tar, type Header struct, PAXRecords map[string]string
+pkg archive/zip, method (*Writer) SetComment(string) error
+pkg archive/zip, type FileHeader struct, Modified time.Time
+pkg archive/zip, type FileHeader struct, NonUTF8 bool
+pkg bufio, method (*Reader) Size() int
+pkg bufio, method (*Writer) Size() int
+pkg crypto/tls, const ECDSAWithSHA1 = 515
+pkg crypto/tls, const ECDSAWithSHA1 SignatureScheme
+pkg crypto/x509, const CANotAuthorizedForExtKeyUsage = 9
+pkg crypto/x509, const CANotAuthorizedForExtKeyUsage InvalidReason
+pkg crypto/x509, const ExtKeyUsageMicrosoftCommercialCodeSigning = 12
+pkg crypto/x509, const ExtKeyUsageMicrosoftCommercialCodeSigning ExtKeyUsage
+pkg crypto/x509, const ExtKeyUsageMicrosoftKernelCodeSigning = 13
+pkg crypto/x509, const ExtKeyUsageMicrosoftKernelCodeSigning ExtKeyUsage
+pkg crypto/x509, const NameConstraintsWithoutSANs = 6
+pkg crypto/x509, const NameConstraintsWithoutSANs InvalidReason
+pkg crypto/x509, const TooManyConstraints = 8
+pkg crypto/x509, const TooManyConstraints InvalidReason
+pkg crypto/x509, const UnconstrainedName = 7
+pkg crypto/x509, const UnconstrainedName InvalidReason
+pkg crypto/x509, func MarshalPKCS1PublicKey(*rsa.PublicKey) []uint8
+pkg crypto/x509, func MarshalPKCS8PrivateKey(interface{}) ([]uint8, error)
+pkg crypto/x509, func ParsePKCS1PublicKey([]uint8) (*rsa.PublicKey, error)
+pkg crypto/x509, method (PublicKeyAlgorithm) String() string
+pkg crypto/x509, type Certificate struct, ExcludedEmailAddresses []string
+pkg crypto/x509, type Certificate struct, ExcludedIPRanges []*net.IPNet
+pkg crypto/x509, type Certificate struct, ExcludedURIDomains []string
+pkg crypto/x509, type Certificate struct, PermittedEmailAddresses []string
+pkg crypto/x509, type Certificate struct, PermittedIPRanges []*net.IPNet
+pkg crypto/x509, type Certificate struct, PermittedURIDomains []string
+pkg crypto/x509, type Certificate struct, URIs []*url.URL
+pkg crypto/x509, type CertificateInvalidError struct, Detail string
+pkg crypto/x509, type CertificateRequest struct, URIs []*url.URL
+pkg crypto/x509, type VerifyOptions struct, MaxConstraintComparisions int
+pkg crypto/x509/pkix, method (Name) String() string
+pkg crypto/x509/pkix, method (RDNSequence) String() string
+pkg database/sql, func OpenDB(driver.Connector) *DB
+pkg database/sql/driver, type Connector interface { Connect, Driver }
+pkg database/sql/driver, type Connector interface, Connect(context.Context) (Conn, error)
+pkg database/sql/driver, type Connector interface, Driver() Driver
+pkg database/sql/driver, type DriverContext interface { OpenConnector }
+pkg database/sql/driver, type DriverContext interface, OpenConnector(string) (Connector, error)
+pkg database/sql/driver, type SessionResetter interface { ResetSession }
+pkg database/sql/driver, type SessionResetter interface, ResetSession(context.Context) error
+pkg debug/elf, const R_386_16 = 20
+pkg debug/elf, const R_386_16 R_386
+pkg debug/elf, const R_386_32PLT = 11
+pkg debug/elf, const R_386_32PLT R_386
+pkg debug/elf, const R_386_8 = 22
+pkg debug/elf, const R_386_8 R_386
+pkg debug/elf, const R_386_GOT32X = 43
+pkg debug/elf, const R_386_GOT32X R_386
+pkg debug/elf, const R_386_IRELATIVE = 42
+pkg debug/elf, const R_386_IRELATIVE R_386
+pkg debug/elf, const R_386_PC16 = 21
+pkg debug/elf, const R_386_PC16 R_386
+pkg debug/elf, const R_386_PC8 = 23
+pkg debug/elf, const R_386_PC8 R_386
+pkg debug/elf, const R_386_SIZE32 = 38
+pkg debug/elf, const R_386_SIZE32 R_386
+pkg debug/elf, const R_386_TLS_DESC = 41
+pkg debug/elf, const R_386_TLS_DESC R_386
+pkg debug/elf, const R_386_TLS_DESC_CALL = 40
+pkg debug/elf, const R_386_TLS_DESC_CALL R_386
+pkg debug/elf, const R_386_TLS_GOTDESC = 39
+pkg debug/elf, const R_386_TLS_GOTDESC R_386
+pkg debug/elf, const R_AARCH64_LD64_GOTOFF_LO15 = 310
+pkg debug/elf, const R_AARCH64_LD64_GOTOFF_LO15 R_AARCH64
+pkg debug/elf, const R_AARCH64_LD64_GOTPAGE_LO15 = 313
+pkg debug/elf, const R_AARCH64_LD64_GOTPAGE_LO15 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSGD_ADR_PREL21 = 512
+pkg debug/elf, const R_AARCH64_TLSGD_ADR_PREL21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSGD_MOVW_G0_NC = 516
+pkg debug/elf, const R_AARCH64_TLSGD_MOVW_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSGD_MOVW_G1 = 515
+pkg debug/elf, const R_AARCH64_TLSGD_MOVW_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLD_ADR_PAGE21 = 518
+pkg debug/elf, const R_AARCH64_TLSLD_ADR_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLD_ADR_PREL21 = 517
+pkg debug/elf, const R_AARCH64_TLSLD_ADR_PREL21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLD_LDST128_DTPREL_LO12 = 572
+pkg debug/elf, const R_AARCH64_TLSLD_LDST128_DTPREL_LO12 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC = 573
+pkg debug/elf, const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_LDST128_TPREL_LO12 = 570
+pkg debug/elf, const R_AARCH64_TLSLE_LDST128_TPREL_LO12 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC = 571
+pkg debug/elf, const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_ARM_ABS32_NOI = 55
+pkg debug/elf, const R_ARM_ABS32_NOI R_ARM
+pkg debug/elf, const R_ARM_ALU_PCREL_15_8 = 33
+pkg debug/elf, const R_ARM_ALU_PCREL_15_8 R_ARM
+pkg debug/elf, const R_ARM_ALU_PCREL_23_15 = 34
+pkg debug/elf, const R_ARM_ALU_PCREL_23_15 R_ARM
+pkg debug/elf, const R_ARM_ALU_PCREL_7_0 = 32
+pkg debug/elf, const R_ARM_ALU_PCREL_7_0 R_ARM
+pkg debug/elf, const R_ARM_ALU_PC_G0 = 58
+pkg debug/elf, const R_ARM_ALU_PC_G0 R_ARM
+pkg debug/elf, const R_ARM_ALU_PC_G0_NC = 57
+pkg debug/elf, const R_ARM_ALU_PC_G0_NC R_ARM
+pkg debug/elf, const R_ARM_ALU_PC_G1 = 60
+pkg debug/elf, const R_ARM_ALU_PC_G1 R_ARM
+pkg debug/elf, const R_ARM_ALU_PC_G1_NC = 59
+pkg debug/elf, const R_ARM_ALU_PC_G1_NC R_ARM
+pkg debug/elf, const R_ARM_ALU_PC_G2 = 61
+pkg debug/elf, const R_ARM_ALU_PC_G2 R_ARM
+pkg debug/elf, const R_ARM_ALU_SBREL_19_12_NC = 36
+pkg debug/elf, const R_ARM_ALU_SBREL_19_12_NC R_ARM
+pkg debug/elf, const R_ARM_ALU_SBREL_27_20_CK = 37
+pkg debug/elf, const R_ARM_ALU_SBREL_27_20_CK R_ARM
+pkg debug/elf, const R_ARM_ALU_SB_G0 = 71
+pkg debug/elf, const R_ARM_ALU_SB_G0 R_ARM
+pkg debug/elf, const R_ARM_ALU_SB_G0_NC = 70
+pkg debug/elf, const R_ARM_ALU_SB_G0_NC R_ARM
+pkg debug/elf, const R_ARM_ALU_SB_G1 = 73
+pkg debug/elf, const R_ARM_ALU_SB_G1 R_ARM
+pkg debug/elf, const R_ARM_ALU_SB_G1_NC = 72
+pkg debug/elf, const R_ARM_ALU_SB_G1_NC R_ARM
+pkg debug/elf, const R_ARM_ALU_SB_G2 = 74
+pkg debug/elf, const R_ARM_ALU_SB_G2 R_ARM
+pkg debug/elf, const R_ARM_BASE_ABS = 31
+pkg debug/elf, const R_ARM_BASE_ABS R_ARM
+pkg debug/elf, const R_ARM_CALL = 28
+pkg debug/elf, const R_ARM_CALL R_ARM
+pkg debug/elf, const R_ARM_GOTOFF12 = 98
+pkg debug/elf, const R_ARM_GOTOFF12 R_ARM
+pkg debug/elf, const R_ARM_GOTRELAX = 99
+pkg debug/elf, const R_ARM_GOTRELAX R_ARM
+pkg debug/elf, const R_ARM_GOT_ABS = 95
+pkg debug/elf, const R_ARM_GOT_ABS R_ARM
+pkg debug/elf, const R_ARM_GOT_BREL12 = 97
+pkg debug/elf, const R_ARM_GOT_BREL12 R_ARM
+pkg debug/elf, const R_ARM_GOT_PREL = 96
+pkg debug/elf, const R_ARM_GOT_PREL R_ARM
+pkg debug/elf, const R_ARM_IRELATIVE = 160
+pkg debug/elf, const R_ARM_IRELATIVE R_ARM
+pkg debug/elf, const R_ARM_JUMP24 = 29
+pkg debug/elf, const R_ARM_JUMP24 R_ARM
+pkg debug/elf, const R_ARM_LDC_PC_G0 = 67
+pkg debug/elf, const R_ARM_LDC_PC_G0 R_ARM
+pkg debug/elf, const R_ARM_LDC_PC_G1 = 68
+pkg debug/elf, const R_ARM_LDC_PC_G1 R_ARM
+pkg debug/elf, const R_ARM_LDC_PC_G2 = 69
+pkg debug/elf, const R_ARM_LDC_PC_G2 R_ARM
+pkg debug/elf, const R_ARM_LDC_SB_G0 = 81
+pkg debug/elf, const R_ARM_LDC_SB_G0 R_ARM
+pkg debug/elf, const R_ARM_LDC_SB_G1 = 82
+pkg debug/elf, const R_ARM_LDC_SB_G1 R_ARM
+pkg debug/elf, const R_ARM_LDC_SB_G2 = 83
+pkg debug/elf, const R_ARM_LDC_SB_G2 R_ARM
+pkg debug/elf, const R_ARM_LDRS_PC_G0 = 64
+pkg debug/elf, const R_ARM_LDRS_PC_G0 R_ARM
+pkg debug/elf, const R_ARM_LDRS_PC_G1 = 65
+pkg debug/elf, const R_ARM_LDRS_PC_G1 R_ARM
+pkg debug/elf, const R_ARM_LDRS_PC_G2 = 66
+pkg debug/elf, const R_ARM_LDRS_PC_G2 R_ARM
+pkg debug/elf, const R_ARM_LDRS_SB_G0 = 78
+pkg debug/elf, const R_ARM_LDRS_SB_G0 R_ARM
+pkg debug/elf, const R_ARM_LDRS_SB_G1 = 79
+pkg debug/elf, const R_ARM_LDRS_SB_G1 R_ARM
+pkg debug/elf, const R_ARM_LDRS_SB_G2 = 80
+pkg debug/elf, const R_ARM_LDRS_SB_G2 R_ARM
+pkg debug/elf, const R_ARM_LDR_PC_G1 = 62
+pkg debug/elf, const R_ARM_LDR_PC_G1 R_ARM
+pkg debug/elf, const R_ARM_LDR_PC_G2 = 63
+pkg debug/elf, const R_ARM_LDR_PC_G2 R_ARM
+pkg debug/elf, const R_ARM_LDR_SBREL_11_10_NC = 35
+pkg debug/elf, const R_ARM_LDR_SBREL_11_10_NC R_ARM
+pkg debug/elf, const R_ARM_LDR_SB_G0 = 75
+pkg debug/elf, const R_ARM_LDR_SB_G0 R_ARM
+pkg debug/elf, const R_ARM_LDR_SB_G1 = 76
+pkg debug/elf, const R_ARM_LDR_SB_G1 R_ARM
+pkg debug/elf, const R_ARM_LDR_SB_G2 = 77
+pkg debug/elf, const R_ARM_LDR_SB_G2 R_ARM
+pkg debug/elf, const R_ARM_ME_TOO = 128
+pkg debug/elf, const R_ARM_ME_TOO R_ARM
+pkg debug/elf, const R_ARM_MOVT_ABS = 44
+pkg debug/elf, const R_ARM_MOVT_ABS R_ARM
+pkg debug/elf, const R_ARM_MOVT_BREL = 85
+pkg debug/elf, const R_ARM_MOVT_BREL R_ARM
+pkg debug/elf, const R_ARM_MOVT_PREL = 46
+pkg debug/elf, const R_ARM_MOVT_PREL R_ARM
+pkg debug/elf, const R_ARM_MOVW_ABS_NC = 43
+pkg debug/elf, const R_ARM_MOVW_ABS_NC R_ARM
+pkg debug/elf, const R_ARM_MOVW_BREL = 86
+pkg debug/elf, const R_ARM_MOVW_BREL R_ARM
+pkg debug/elf, const R_ARM_MOVW_BREL_NC = 84
+pkg debug/elf, const R_ARM_MOVW_BREL_NC R_ARM
+pkg debug/elf, const R_ARM_MOVW_PREL_NC = 45
+pkg debug/elf, const R_ARM_MOVW_PREL_NC R_ARM
+pkg debug/elf, const R_ARM_PLT32_ABS = 94
+pkg debug/elf, const R_ARM_PLT32_ABS R_ARM
+pkg debug/elf, const R_ARM_PREL31 = 42
+pkg debug/elf, const R_ARM_PREL31 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_0 = 112
+pkg debug/elf, const R_ARM_PRIVATE_0 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_1 = 113
+pkg debug/elf, const R_ARM_PRIVATE_1 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_10 = 122
+pkg debug/elf, const R_ARM_PRIVATE_10 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_11 = 123
+pkg debug/elf, const R_ARM_PRIVATE_11 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_12 = 124
+pkg debug/elf, const R_ARM_PRIVATE_12 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_13 = 125
+pkg debug/elf, const R_ARM_PRIVATE_13 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_14 = 126
+pkg debug/elf, const R_ARM_PRIVATE_14 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_15 = 127
+pkg debug/elf, const R_ARM_PRIVATE_15 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_2 = 114
+pkg debug/elf, const R_ARM_PRIVATE_2 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_3 = 115
+pkg debug/elf, const R_ARM_PRIVATE_3 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_4 = 116
+pkg debug/elf, const R_ARM_PRIVATE_4 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_5 = 117
+pkg debug/elf, const R_ARM_PRIVATE_5 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_6 = 118
+pkg debug/elf, const R_ARM_PRIVATE_6 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_7 = 119
+pkg debug/elf, const R_ARM_PRIVATE_7 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_8 = 120
+pkg debug/elf, const R_ARM_PRIVATE_8 R_ARM
+pkg debug/elf, const R_ARM_PRIVATE_9 = 121
+pkg debug/elf, const R_ARM_PRIVATE_9 R_ARM
+pkg debug/elf, const R_ARM_REL32_NOI = 56
+pkg debug/elf, const R_ARM_REL32_NOI R_ARM
+pkg debug/elf, const R_ARM_RXPC25 = 249
+pkg debug/elf, const R_ARM_RXPC25 R_ARM
+pkg debug/elf, const R_ARM_SBREL31 = 39
+pkg debug/elf, const R_ARM_SBREL31 R_ARM
+pkg debug/elf, const R_ARM_TARGET1 = 38
+pkg debug/elf, const R_ARM_TARGET1 R_ARM
+pkg debug/elf, const R_ARM_TARGET2 = 41
+pkg debug/elf, const R_ARM_TARGET2 R_ARM
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G0_NC = 132
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G0_NC R_ARM
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G1_NC = 133
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G1_NC R_ARM
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G2_NC = 134
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G2_NC R_ARM
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G3 = 135
+pkg debug/elf, const R_ARM_THM_ALU_ABS_G3 R_ARM
+pkg debug/elf, const R_ARM_THM_ALU_PREL_11_0 = 53
+pkg debug/elf, const R_ARM_THM_ALU_PREL_11_0 R_ARM
+pkg debug/elf, const R_ARM_THM_GOT_BREL12 = 131
+pkg debug/elf, const R_ARM_THM_GOT_BREL12 R_ARM
+pkg debug/elf, const R_ARM_THM_JUMP11 = 102
+pkg debug/elf, const R_ARM_THM_JUMP11 R_ARM
+pkg debug/elf, const R_ARM_THM_JUMP19 = 51
+pkg debug/elf, const R_ARM_THM_JUMP19 R_ARM
+pkg debug/elf, const R_ARM_THM_JUMP24 = 30
+pkg debug/elf, const R_ARM_THM_JUMP24 R_ARM
+pkg debug/elf, const R_ARM_THM_JUMP6 = 52
+pkg debug/elf, const R_ARM_THM_JUMP6 R_ARM
+pkg debug/elf, const R_ARM_THM_JUMP8 = 103
+pkg debug/elf, const R_ARM_THM_JUMP8 R_ARM
+pkg debug/elf, const R_ARM_THM_MOVT_ABS = 48
+pkg debug/elf, const R_ARM_THM_MOVT_ABS R_ARM
+pkg debug/elf, const R_ARM_THM_MOVT_BREL = 88
+pkg debug/elf, const R_ARM_THM_MOVT_BREL R_ARM
+pkg debug/elf, const R_ARM_THM_MOVT_PREL = 50
+pkg debug/elf, const R_ARM_THM_MOVT_PREL R_ARM
+pkg debug/elf, const R_ARM_THM_MOVW_ABS_NC = 47
+pkg debug/elf, const R_ARM_THM_MOVW_ABS_NC R_ARM
+pkg debug/elf, const R_ARM_THM_MOVW_BREL = 89
+pkg debug/elf, const R_ARM_THM_MOVW_BREL R_ARM
+pkg debug/elf, const R_ARM_THM_MOVW_BREL_NC = 87
+pkg debug/elf, const R_ARM_THM_MOVW_BREL_NC R_ARM
+pkg debug/elf, const R_ARM_THM_MOVW_PREL_NC = 49
+pkg debug/elf, const R_ARM_THM_MOVW_PREL_NC R_ARM
+pkg debug/elf, const R_ARM_THM_PC12 = 54
+pkg debug/elf, const R_ARM_THM_PC12 R_ARM
+pkg debug/elf, const R_ARM_THM_TLS_CALL = 93
+pkg debug/elf, const R_ARM_THM_TLS_CALL R_ARM
+pkg debug/elf, const R_ARM_THM_TLS_DESCSEQ16 = 129
+pkg debug/elf, const R_ARM_THM_TLS_DESCSEQ16 R_ARM
+pkg debug/elf, const R_ARM_THM_TLS_DESCSEQ32 = 130
+pkg debug/elf, const R_ARM_THM_TLS_DESCSEQ32 R_ARM
+pkg debug/elf, const R_ARM_TLS_CALL = 91
+pkg debug/elf, const R_ARM_TLS_CALL R_ARM
+pkg debug/elf, const R_ARM_TLS_DESCSEQ = 92
+pkg debug/elf, const R_ARM_TLS_DESCSEQ R_ARM
+pkg debug/elf, const R_ARM_TLS_DTPMOD32 = 17
+pkg debug/elf, const R_ARM_TLS_DTPMOD32 R_ARM
+pkg debug/elf, const R_ARM_TLS_DTPOFF32 = 18
+pkg debug/elf, const R_ARM_TLS_DTPOFF32 R_ARM
+pkg debug/elf, const R_ARM_TLS_GD32 = 104
+pkg debug/elf, const R_ARM_TLS_GD32 R_ARM
+pkg debug/elf, const R_ARM_TLS_GOTDESC = 90
+pkg debug/elf, const R_ARM_TLS_GOTDESC R_ARM
+pkg debug/elf, const R_ARM_TLS_IE12GP = 111
+pkg debug/elf, const R_ARM_TLS_IE12GP R_ARM
+pkg debug/elf, const R_ARM_TLS_IE32 = 107
+pkg debug/elf, const R_ARM_TLS_IE32 R_ARM
+pkg debug/elf, const R_ARM_TLS_LDM32 = 105
+pkg debug/elf, const R_ARM_TLS_LDM32 R_ARM
+pkg debug/elf, const R_ARM_TLS_LDO12 = 109
+pkg debug/elf, const R_ARM_TLS_LDO12 R_ARM
+pkg debug/elf, const R_ARM_TLS_LDO32 = 106
+pkg debug/elf, const R_ARM_TLS_LDO32 R_ARM
+pkg debug/elf, const R_ARM_TLS_LE12 = 110
+pkg debug/elf, const R_ARM_TLS_LE12 R_ARM
+pkg debug/elf, const R_ARM_TLS_LE32 = 108
+pkg debug/elf, const R_ARM_TLS_LE32 R_ARM
+pkg debug/elf, const R_ARM_TLS_TPOFF32 = 19
+pkg debug/elf, const R_ARM_TLS_TPOFF32 R_ARM
+pkg debug/elf, const R_ARM_V4BX = 40
+pkg debug/elf, const R_ARM_V4BX R_ARM
+pkg debug/elf, const R_PPC64_ADDR16_HIGH = 110
+pkg debug/elf, const R_PPC64_ADDR16_HIGH R_PPC64
+pkg debug/elf, const R_PPC64_ADDR16_HIGHA = 111
+pkg debug/elf, const R_PPC64_ADDR16_HIGHA R_PPC64
+pkg debug/elf, const R_PPC64_ADDR64_LOCAL = 117
+pkg debug/elf, const R_PPC64_ADDR64_LOCAL R_PPC64
+pkg debug/elf, const R_PPC64_DTPREL16_HIGH = 114
+pkg debug/elf, const R_PPC64_DTPREL16_HIGH R_PPC64
+pkg debug/elf, const R_PPC64_DTPREL16_HIGHA = 115
+pkg debug/elf, const R_PPC64_DTPREL16_HIGHA R_PPC64
+pkg debug/elf, const R_PPC64_ENTRY = 118
+pkg debug/elf, const R_PPC64_ENTRY R_PPC64
+pkg debug/elf, const R_PPC64_IRELATIVE = 248
+pkg debug/elf, const R_PPC64_IRELATIVE R_PPC64
+pkg debug/elf, const R_PPC64_JMP_IREL = 247
+pkg debug/elf, const R_PPC64_JMP_IREL R_PPC64
+pkg debug/elf, const R_PPC64_PLT16_LO_DS = 60
+pkg debug/elf, const R_PPC64_PLT16_LO_DS R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT16 = 52
+pkg debug/elf, const R_PPC64_PLTGOT16 R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT16_DS = 65
+pkg debug/elf, const R_PPC64_PLTGOT16_DS R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT16_HA = 55
+pkg debug/elf, const R_PPC64_PLTGOT16_HA R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT16_HI = 54
+pkg debug/elf, const R_PPC64_PLTGOT16_HI R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT16_LO = 53
+pkg debug/elf, const R_PPC64_PLTGOT16_LO R_PPC64
+pkg debug/elf, const R_PPC64_PLTGOT_LO_DS = 66
+pkg debug/elf, const R_PPC64_PLTGOT_LO_DS R_PPC64
+pkg debug/elf, const R_PPC64_REL16DX_HA = 246
+pkg debug/elf, const R_PPC64_REL16DX_HA R_PPC64
+pkg debug/elf, const R_PPC64_REL24_NOTOC = 116
+pkg debug/elf, const R_PPC64_REL24_NOTOC R_PPC64
+pkg debug/elf, const R_PPC64_SECTOFF_DS = 61
+pkg debug/elf, const R_PPC64_SECTOFF_DS R_PPC64
+pkg debug/elf, const R_PPC64_SECTOFF_LO_DS = 61
+pkg debug/elf, const R_PPC64_SECTOFF_LO_DS R_PPC64
+pkg debug/elf, const R_PPC64_TOCSAVE = 109
+pkg debug/elf, const R_PPC64_TOCSAVE R_PPC64
+pkg debug/elf, const R_PPC64_TPREL16_HIGH = 112
+pkg debug/elf, const R_PPC64_TPREL16_HIGH R_PPC64
+pkg debug/elf, const R_PPC64_TPREL16_HIGHA = 113
+pkg debug/elf, const R_PPC64_TPREL16_HIGHA R_PPC64
+pkg debug/elf, const R_X86_64_GOT64 = 27
+pkg debug/elf, const R_X86_64_GOT64 R_X86_64
+pkg debug/elf, const R_X86_64_GOTOFF64 = 25
+pkg debug/elf, const R_X86_64_GOTOFF64 R_X86_64
+pkg debug/elf, const R_X86_64_GOTPC32 = 26
+pkg debug/elf, const R_X86_64_GOTPC32 R_X86_64
+pkg debug/elf, const R_X86_64_GOTPC32_TLSDESC = 34
+pkg debug/elf, const R_X86_64_GOTPC32_TLSDESC R_X86_64
+pkg debug/elf, const R_X86_64_GOTPC64 = 29
+pkg debug/elf, const R_X86_64_GOTPC64 R_X86_64
+pkg debug/elf, const R_X86_64_GOTPCREL64 = 28
+pkg debug/elf, const R_X86_64_GOTPCREL64 R_X86_64
+pkg debug/elf, const R_X86_64_GOTPCRELX = 41
+pkg debug/elf, const R_X86_64_GOTPCRELX R_X86_64
+pkg debug/elf, const R_X86_64_GOTPLT64 = 30
+pkg debug/elf, const R_X86_64_GOTPLT64 R_X86_64
+pkg debug/elf, const R_X86_64_IRELATIVE = 37
+pkg debug/elf, const R_X86_64_IRELATIVE R_X86_64
+pkg debug/elf, const R_X86_64_PC32_BND = 39
+pkg debug/elf, const R_X86_64_PC32_BND R_X86_64
+pkg debug/elf, const R_X86_64_PC64 = 24
+pkg debug/elf, const R_X86_64_PC64 R_X86_64
+pkg debug/elf, const R_X86_64_PLT32_BND = 40
+pkg debug/elf, const R_X86_64_PLT32_BND R_X86_64
+pkg debug/elf, const R_X86_64_PLTOFF64 = 31
+pkg debug/elf, const R_X86_64_PLTOFF64 R_X86_64
+pkg debug/elf, const R_X86_64_RELATIVE64 = 38
+pkg debug/elf, const R_X86_64_RELATIVE64 R_X86_64
+pkg debug/elf, const R_X86_64_REX_GOTPCRELX = 42
+pkg debug/elf, const R_X86_64_REX_GOTPCRELX R_X86_64
+pkg debug/elf, const R_X86_64_SIZE32 = 32
+pkg debug/elf, const R_X86_64_SIZE32 R_X86_64
+pkg debug/elf, const R_X86_64_SIZE64 = 33
+pkg debug/elf, const R_X86_64_SIZE64 R_X86_64
+pkg debug/elf, const R_X86_64_TLSDESC = 36
+pkg debug/elf, const R_X86_64_TLSDESC R_X86_64
+pkg debug/elf, const R_X86_64_TLSDESC_CALL = 35
+pkg debug/elf, const R_X86_64_TLSDESC_CALL R_X86_64
+pkg debug/macho, const ARM64_RELOC_ADDEND = 10
+pkg debug/macho, const ARM64_RELOC_ADDEND RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_BRANCH26 = 2
+pkg debug/macho, const ARM64_RELOC_BRANCH26 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_GOT_LOAD_PAGE21 = 5
+pkg debug/macho, const ARM64_RELOC_GOT_LOAD_PAGE21 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6
+pkg debug/macho, const ARM64_RELOC_GOT_LOAD_PAGEOFF12 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_PAGE21 = 3
+pkg debug/macho, const ARM64_RELOC_PAGE21 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_PAGEOFF12 = 4
+pkg debug/macho, const ARM64_RELOC_PAGEOFF12 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_POINTER_TO_GOT = 7
+pkg debug/macho, const ARM64_RELOC_POINTER_TO_GOT RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_SUBTRACTOR = 1
+pkg debug/macho, const ARM64_RELOC_SUBTRACTOR RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_TLVP_LOAD_PAGE21 = 8
+pkg debug/macho, const ARM64_RELOC_TLVP_LOAD_PAGE21 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9
+pkg debug/macho, const ARM64_RELOC_TLVP_LOAD_PAGEOFF12 RelocTypeARM64
+pkg debug/macho, const ARM64_RELOC_UNSIGNED = 0
+pkg debug/macho, const ARM64_RELOC_UNSIGNED RelocTypeARM64
+pkg debug/macho, const ARM_RELOC_BR24 = 5
+pkg debug/macho, const ARM_RELOC_BR24 RelocTypeARM
+pkg debug/macho, const ARM_RELOC_HALF = 8
+pkg debug/macho, const ARM_RELOC_HALF RelocTypeARM
+pkg debug/macho, const ARM_RELOC_HALF_SECTDIFF = 9
+pkg debug/macho, const ARM_RELOC_HALF_SECTDIFF RelocTypeARM
+pkg debug/macho, const ARM_RELOC_LOCAL_SECTDIFF = 3
+pkg debug/macho, const ARM_RELOC_LOCAL_SECTDIFF RelocTypeARM
+pkg debug/macho, const ARM_RELOC_PAIR = 1
+pkg debug/macho, const ARM_RELOC_PAIR RelocTypeARM
+pkg debug/macho, const ARM_RELOC_PB_LA_PTR = 4
+pkg debug/macho, const ARM_RELOC_PB_LA_PTR RelocTypeARM
+pkg debug/macho, const ARM_RELOC_SECTDIFF = 2
+pkg debug/macho, const ARM_RELOC_SECTDIFF RelocTypeARM
+pkg debug/macho, const ARM_RELOC_VANILLA = 0
+pkg debug/macho, const ARM_RELOC_VANILLA RelocTypeARM
+pkg debug/macho, const ARM_THUMB_32BIT_BRANCH = 7
+pkg debug/macho, const ARM_THUMB_32BIT_BRANCH RelocTypeARM
+pkg debug/macho, const ARM_THUMB_RELOC_BR22 = 6
+pkg debug/macho, const ARM_THUMB_RELOC_BR22 RelocTypeARM
+pkg debug/macho, const FlagAllModsBound = 4096
+pkg debug/macho, const FlagAllModsBound uint32
+pkg debug/macho, const FlagAllowStackExecution = 131072
+pkg debug/macho, const FlagAllowStackExecution uint32
+pkg debug/macho, const FlagAppExtensionSafe = 33554432
+pkg debug/macho, const FlagAppExtensionSafe uint32
+pkg debug/macho, const FlagBindAtLoad = 8
+pkg debug/macho, const FlagBindAtLoad uint32
+pkg debug/macho, const FlagBindsToWeak = 65536
+pkg debug/macho, const FlagBindsToWeak uint32
+pkg debug/macho, const FlagCanonical = 16384
+pkg debug/macho, const FlagCanonical uint32
+pkg debug/macho, const FlagDeadStrippableDylib = 4194304
+pkg debug/macho, const FlagDeadStrippableDylib uint32
+pkg debug/macho, const FlagDyldLink = 4
+pkg debug/macho, const FlagDyldLink uint32
+pkg debug/macho, const FlagForceFlat = 256
+pkg debug/macho, const FlagForceFlat uint32
+pkg debug/macho, const FlagHasTLVDescriptors = 8388608
+pkg debug/macho, const FlagHasTLVDescriptors uint32
+pkg debug/macho, const FlagIncrLink = 2
+pkg debug/macho, const FlagIncrLink uint32
+pkg debug/macho, const FlagLazyInit = 64
+pkg debug/macho, const FlagLazyInit uint32
+pkg debug/macho, const FlagNoFixPrebinding = 1024
+pkg debug/macho, const FlagNoFixPrebinding uint32
+pkg debug/macho, const FlagNoHeapExecution = 16777216
+pkg debug/macho, const FlagNoHeapExecution uint32
+pkg debug/macho, const FlagNoMultiDefs = 512
+pkg debug/macho, const FlagNoMultiDefs uint32
+pkg debug/macho, const FlagNoReexportedDylibs = 1048576
+pkg debug/macho, const FlagNoReexportedDylibs uint32
+pkg debug/macho, const FlagNoUndefs = 1
+pkg debug/macho, const FlagNoUndefs uint32
+pkg debug/macho, const FlagPIE = 2097152
+pkg debug/macho, const FlagPIE uint32
+pkg debug/macho, const FlagPrebindable = 2048
+pkg debug/macho, const FlagPrebindable uint32
+pkg debug/macho, const FlagPrebound = 16
+pkg debug/macho, const FlagPrebound uint32
+pkg debug/macho, const FlagRootSafe = 262144
+pkg debug/macho, const FlagRootSafe uint32
+pkg debug/macho, const FlagSetuidSafe = 524288
+pkg debug/macho, const FlagSetuidSafe uint32
+pkg debug/macho, const FlagSplitSegs = 32
+pkg debug/macho, const FlagSplitSegs uint32
+pkg debug/macho, const FlagSubsectionsViaSymbols = 8192
+pkg debug/macho, const FlagSubsectionsViaSymbols uint32
+pkg debug/macho, const FlagTwoLevel = 128
+pkg debug/macho, const FlagTwoLevel uint32
+pkg debug/macho, const FlagWeakDefines = 32768
+pkg debug/macho, const FlagWeakDefines uint32
+pkg debug/macho, const GENERIC_RELOC_LOCAL_SECTDIFF = 4
+pkg debug/macho, const GENERIC_RELOC_LOCAL_SECTDIFF RelocTypeGeneric
+pkg debug/macho, const GENERIC_RELOC_PAIR = 1
+pkg debug/macho, const GENERIC_RELOC_PAIR RelocTypeGeneric
+pkg debug/macho, const GENERIC_RELOC_PB_LA_PTR = 3
+pkg debug/macho, const GENERIC_RELOC_PB_LA_PTR RelocTypeGeneric
+pkg debug/macho, const GENERIC_RELOC_SECTDIFF = 2
+pkg debug/macho, const GENERIC_RELOC_SECTDIFF RelocTypeGeneric
+pkg debug/macho, const GENERIC_RELOC_TLV = 5
+pkg debug/macho, const GENERIC_RELOC_TLV RelocTypeGeneric
+pkg debug/macho, const GENERIC_RELOC_VANILLA = 0
+pkg debug/macho, const GENERIC_RELOC_VANILLA RelocTypeGeneric
+pkg debug/macho, const LoadCmdRpath = 2147483676
+pkg debug/macho, const LoadCmdRpath LoadCmd
+pkg debug/macho, const X86_64_RELOC_BRANCH = 2
+pkg debug/macho, const X86_64_RELOC_BRANCH RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_GOT = 4
+pkg debug/macho, const X86_64_RELOC_GOT RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_GOT_LOAD = 3
+pkg debug/macho, const X86_64_RELOC_GOT_LOAD RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_SIGNED = 1
+pkg debug/macho, const X86_64_RELOC_SIGNED RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_SIGNED_1 = 6
+pkg debug/macho, const X86_64_RELOC_SIGNED_1 RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_SIGNED_2 = 7
+pkg debug/macho, const X86_64_RELOC_SIGNED_2 RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_SIGNED_4 = 8
+pkg debug/macho, const X86_64_RELOC_SIGNED_4 RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_SUBTRACTOR = 5
+pkg debug/macho, const X86_64_RELOC_SUBTRACTOR RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_TLV = 9
+pkg debug/macho, const X86_64_RELOC_TLV RelocTypeX86_64
+pkg debug/macho, const X86_64_RELOC_UNSIGNED = 0
+pkg debug/macho, const X86_64_RELOC_UNSIGNED RelocTypeX86_64
+pkg debug/macho, method (RelocTypeARM) GoString() string
+pkg debug/macho, method (RelocTypeARM) String() string
+pkg debug/macho, method (RelocTypeARM64) GoString() string
+pkg debug/macho, method (RelocTypeARM64) String() string
+pkg debug/macho, method (RelocTypeGeneric) GoString() string
+pkg debug/macho, method (RelocTypeGeneric) String() string
+pkg debug/macho, method (RelocTypeX86_64) GoString() string
+pkg debug/macho, method (RelocTypeX86_64) String() string
+pkg debug/macho, method (Rpath) Raw() []uint8
+pkg debug/macho, method (Type) GoString() string
+pkg debug/macho, method (Type) String() string
+pkg debug/macho, type Reloc struct
+pkg debug/macho, type Reloc struct, Addr uint32
+pkg debug/macho, type Reloc struct, Extern bool
+pkg debug/macho, type Reloc struct, Len uint8
+pkg debug/macho, type Reloc struct, Pcrel bool
+pkg debug/macho, type Reloc struct, Scattered bool
+pkg debug/macho, type Reloc struct, Type uint8
+pkg debug/macho, type Reloc struct, Value uint32
+pkg debug/macho, type RelocTypeARM int
+pkg debug/macho, type RelocTypeARM64 int
+pkg debug/macho, type RelocTypeGeneric int
+pkg debug/macho, type RelocTypeX86_64 int
+pkg debug/macho, type Rpath struct
+pkg debug/macho, type Rpath struct, Path string
+pkg debug/macho, type Rpath struct, embedded LoadBytes
+pkg debug/macho, type RpathCmd struct
+pkg debug/macho, type RpathCmd struct, Cmd LoadCmd
+pkg debug/macho, type RpathCmd struct, Len uint32
+pkg debug/macho, type RpathCmd struct, Path uint32
+pkg debug/macho, type Section struct, Relocs []Reloc
+pkg encoding/asn1, const TagNumericString = 18
+pkg encoding/asn1, const TagNumericString ideal-int
+pkg encoding/asn1, func MarshalWithParams(interface{}, string) ([]uint8, error)
+pkg encoding/csv, type ParseError struct, StartLine int
+pkg encoding/hex, func NewDecoder(io.Reader) io.Reader
+pkg encoding/hex, func NewEncoder(io.Writer) io.Writer
+pkg encoding/json, method (*Decoder) DisallowUnknownFields()
+pkg encoding/xml, func NewTokenDecoder(TokenReader) *Decoder
+pkg encoding/xml, type TokenReader interface { Token }
+pkg encoding/xml, type TokenReader interface, Token() (Token, error)
+pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling
+pkg flag, method (*FlagSet) Name() string
+pkg flag, method (*FlagSet) Output() io.Writer
+pkg html/template, type Srcset string
+pkg math, func Erfcinv(float64) float64
+pkg math, func Erfinv(float64) float64
+pkg math, func Round(float64) float64
+pkg math, func RoundToEven(float64) float64
+pkg math/big, const MaxBase = 62
+pkg math/big, method (*Float) Sqrt(*Float) *Float
+pkg math/big, method (*Int) CmpAbs(*Int) int
+pkg math/rand, func Shuffle(int, func(int, int))
+pkg math/rand, method (*Rand) Shuffle(int, func(int, int))
+pkg net, method (*TCPListener) SyscallConn() (syscall.RawConn, error)
+pkg net, method (*UnixListener) SyscallConn() (syscall.RawConn, error)
+pkg net/smtp, method (*Client) Noop() error
+pkg os, func IsTimeout(error) bool
+pkg os, method (*File) SetDeadline(time.Time) error
+pkg os, method (*File) SetReadDeadline(time.Time) error
+pkg os, method (*File) SetWriteDeadline(time.Time) error
+pkg os, method (*PathError) Timeout() bool
+pkg os, method (*SyscallError) Timeout() bool
+pkg os, var ErrNoDeadline error
+pkg strings, method (*Builder) Grow(int)
+pkg strings, method (*Builder) Len() int
+pkg strings, method (*Builder) Reset()
+pkg strings, method (*Builder) String() string
+pkg strings, method (*Builder) Write([]uint8) (int, error)
+pkg strings, method (*Builder) WriteByte(uint8) error
+pkg strings, method (*Builder) WriteRune(int32) (int, error)
+pkg strings, method (*Builder) WriteString(string) (int, error)
+pkg strings, type Builder struct
+pkg syscall (freebsd-386), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-386), const SYS_UTIMENSAT ideal-int
+pkg syscall (freebsd-386-cgo), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-386-cgo), const SYS_UTIMENSAT ideal-int
+pkg syscall (freebsd-amd64), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-amd64), const SYS_UTIMENSAT ideal-int
+pkg syscall (freebsd-amd64-cgo), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-amd64-cgo), const SYS_UTIMENSAT ideal-int
+pkg syscall (freebsd-arm), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-arm), const SYS_UTIMENSAT ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_UTIMENSAT = 547
+pkg syscall (freebsd-arm-cgo), const SYS_UTIMENSAT ideal-int
+pkg syscall (windows-386), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
+pkg syscall (windows-386), type SysProcAttr struct, Token Token
+pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
+pkg syscall (windows-amd64), type SysProcAttr struct, Token Token
+pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error)
+pkg unicode, const Version = "10.0.0"
+pkg unicode, var Masaram_Gondi *RangeTable
+pkg unicode, var Nushu *RangeTable
+pkg unicode, var Regional_Indicator *RangeTable
+pkg unicode, var Soyombo *RangeTable
+pkg unicode, var Zanabazar_Square *RangeTable
diff --git a/bin/go b/bin/go
index 2bf6f4f..810d7d5 100755
--- a/bin/go
+++ b/bin/go
Binary files differ
diff --git a/bin/gofmt b/bin/gofmt
index c0b7610..e605328 100755
--- a/bin/gofmt
+++ b/bin/gofmt
Binary files differ
diff --git a/doc/articles/go_command.html b/doc/articles/go_command.html
index 0fd83cb..9f4e8e0 100644
--- a/doc/articles/go_command.html
+++ b/doc/articles/go_command.html
@@ -134,7 +134,7 @@
 example, if we allowed extra configuration such as compiler flags or
 command line recipes, then that configuration would need to be updated
 each time the build tools changed; it would also be inherently tied
-to the use of a specific tool chain.</p>
+to the use of a specific toolchain.</p>
 
 <h2>Getting started with the go command</h2>
 
diff --git a/doc/articles/wiki/final-noclosure.go b/doc/articles/wiki/final-noclosure.go
index d72ca80..b4ce255 100644
--- a/doc/articles/wiki/final-noclosure.go
+++ b/doc/articles/wiki/final-noclosure.go
@@ -8,6 +8,7 @@
 	"errors"
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 	"regexp"
 )
@@ -98,5 +99,5 @@
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
 	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/final-noerror.go b/doc/articles/wiki/final-noerror.go
index 86d8da7..42a22da 100644
--- a/doc/articles/wiki/final-noerror.go
+++ b/doc/articles/wiki/final-noerror.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -49,5 +50,5 @@
 func main() {
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/final-parsetemplate.go b/doc/articles/wiki/final-parsetemplate.go
index 5ff8bf6..a9aa7f2 100644
--- a/doc/articles/wiki/final-parsetemplate.go
+++ b/doc/articles/wiki/final-parsetemplate.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 	"regexp"
 )
@@ -87,5 +88,5 @@
 	http.HandleFunc("/view/", makeHandler(viewHandler))
 	http.HandleFunc("/edit/", makeHandler(editHandler))
 	http.HandleFunc("/save/", makeHandler(saveHandler))
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/final-template.go b/doc/articles/wiki/final-template.go
index 719157d..7ea480e 100644
--- a/doc/articles/wiki/final-template.go
+++ b/doc/articles/wiki/final-template.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -61,5 +62,5 @@
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
 	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/final-test.patch b/doc/articles/wiki/final-test.patch
index 499ad78..fd7d625 100644
--- a/doc/articles/wiki/final-test.patch
+++ b/doc/articles/wiki/final-test.patch
@@ -1,36 +1,27 @@
-*** final.go	2015-06-14 23:59:22.000000000 +0200
---- final-test.go	2015-06-15 00:15:41.000000000 +0200
-***************
-*** 7,12 ****
---- 7,14 ----
-  import (
-  	"html/template"
-  	"io/ioutil"
-+ 	"log"
-+ 	"net"
-  	"net/http"
-  	"regexp"
-  )
-***************
-*** 85,89 ****
-  	http.HandleFunc("/edit/", makeHandler(editHandler))
-  	http.HandleFunc("/save/", makeHandler(saveHandler))
-  
-! 	http.ListenAndServe(":8080", nil)
-  }
---- 87,101 ----
-  	http.HandleFunc("/edit/", makeHandler(editHandler))
-  	http.HandleFunc("/save/", makeHandler(saveHandler))
-  
-! 	l, err := net.Listen("tcp", "127.0.0.1:0")
-! 	if err != nil {
-! 		log.Fatal(err)
-! 	}
-! 	err = ioutil.WriteFile("final-test-port.txt", []byte(l.Addr().String()), 0644)
-! 	if err != nil {
-! 		log.Fatal(err)
-! 	}
-! 	s := &http.Server{}
-! 	s.Serve(l)
-! 	return
-  }
+--- final.go	2017-08-31 13:19:00.422925489 -0700
++++ final-test.go	2017-08-31 13:23:43.381391659 -0700
+@@ -8,6 +8,7 @@
+ 	"html/template"
+ 	"io/ioutil"
+ 	"log"
++	"net"
+ 	"net/http"
+ 	"regexp"
+ )
+@@ -86,5 +87,15 @@
+ 	http.HandleFunc("/edit/", makeHandler(editHandler))
+ 	http.HandleFunc("/save/", makeHandler(saveHandler))
+ 
+-	log.Fatal(http.ListenAndServe(":8080", nil))
++	l, err := net.Listen("tcp", "127.0.0.1:0")
++	if err != nil {
++		log.Fatal(err)
++	}
++	err = ioutil.WriteFile("final-test-port.txt", []byte(l.Addr().String()), 0644)
++	if err != nil {
++		log.Fatal(err)
++	}
++	s := &http.Server{}
++	s.Serve(l)
++	return
+ }
diff --git a/doc/articles/wiki/final.go b/doc/articles/wiki/final.go
index 139a323..0f6646b 100644
--- a/doc/articles/wiki/final.go
+++ b/doc/articles/wiki/final.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 	"regexp"
 )
@@ -85,5 +86,5 @@
 	http.HandleFunc("/edit/", makeHandler(editHandler))
 	http.HandleFunc("/save/", makeHandler(saveHandler))
 
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/http-sample.go b/doc/articles/wiki/http-sample.go
index ac8cc4f..9bc2084 100644
--- a/doc/articles/wiki/http-sample.go
+++ b/doc/articles/wiki/http-sample.go
@@ -2,6 +2,7 @@
 
 import (
 	"fmt"
+	"log"
 	"net/http"
 )
 
@@ -11,5 +12,5 @@
 
 func main() {
 	http.HandleFunc("/", handler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/index.html b/doc/articles/wiki/index.html
index b6b080d..3e0d532 100644
--- a/doc/articles/wiki/index.html
+++ b/doc/articles/wiki/index.html
@@ -179,7 +179,7 @@
 <pre>
 $ go build wiki.go
 $ ./wiki
-This is a sample page.
+This is a sample Page.
 </pre>
 
 <p>
@@ -214,6 +214,12 @@
 </p>
 
 <p>
+<code>ListenAndServe</code> always returns an error, since it only returns when an
+unexpected error occurs.
+In order to log that error we wrap the function call with <code>log.Fatal</code>.
+</p>
+
+<p>
 The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
 It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
 its arguments.
diff --git a/doc/articles/wiki/notemplate.go b/doc/articles/wiki/notemplate.go
index be214d1..0fda7a9 100644
--- a/doc/articles/wiki/notemplate.go
+++ b/doc/articles/wiki/notemplate.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -52,5 +53,5 @@
 func main() {
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/part2.go b/doc/articles/wiki/part2.go
index c023169..30f9dcf 100644
--- a/doc/articles/wiki/part2.go
+++ b/doc/articles/wiki/part2.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -37,5 +38,5 @@
 
 func main() {
 	http.HandleFunc("/view/", viewHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/part3-errorhandling.go b/doc/articles/wiki/part3-errorhandling.go
index bb4ecda..34b13a6 100644
--- a/doc/articles/wiki/part3-errorhandling.go
+++ b/doc/articles/wiki/part3-errorhandling.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -69,5 +70,5 @@
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
 	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/articles/wiki/part3.go b/doc/articles/wiki/part3.go
index 174f3ab..5e5d505 100644
--- a/doc/articles/wiki/part3.go
+++ b/doc/articles/wiki/part3.go
@@ -7,6 +7,7 @@
 import (
 	"html/template"
 	"io/ioutil"
+	"log"
 	"net/http"
 )
 
@@ -53,5 +54,5 @@
 	http.HandleFunc("/view/", viewHandler)
 	http.HandleFunc("/edit/", editHandler)
 	//http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
+	log.Fatal(http.ListenAndServe(":8080", nil))
 }
diff --git a/doc/asm.html b/doc/asm.html
index 79dc7df..3a05d46 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -29,7 +29,7 @@
 and instruction selection occurs partly after code generation.
 The assembler works on the semi-abstract form, so
 when you see an instruction like <code>MOV</code>
-what the tool chain actually generates for that operation might
+what the toolchain actually generates for that operation might
 not be a move instruction at all, perhaps a clear or load.
 Or it might correspond exactly to the machine instruction with that name.
 In general, machine-specific operations tend to appear as themselves, while more general concepts like
@@ -139,7 +139,7 @@
 <p>
 There are four predeclared symbols that refer to pseudo-registers.
 These are not real registers, but rather virtual registers maintained by
-the tool chain, such as a frame pointer.
+the toolchain, such as a frame pointer.
 The set of pseudo-registers is the same for all architectures:
 </p>
 
@@ -876,6 +876,12 @@
 
 </ul>
 
+<p>
+The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
+<code>softfloat</code>) is made available to assembly code by predefining either
+<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
+</p>
+
 <h3 id="unsupported_opcodes">Unsupported opcodes</h3>
 
 <p>
diff --git a/doc/conduct.html b/doc/conduct.html
index c40b007..bf52ef9 100644
--- a/doc/conduct.html
+++ b/doc/conduct.html
@@ -183,7 +183,6 @@
 	<li>Aditya Mukerjee &lt;dev@chimeracoder.net&gt;
 	<li>Andrew Gerrand &lt;adg@golang.org&gt;
 	<li>Peggy Li &lt;peggyli.224@gmail.com&gt;
-	<li>Sarah Adams &lt;sadams.codes@gmail.com&gt;
 	<li>Steve Francia &lt;steve.francia@gmail.com&gt;
 	<li>Verónica López &lt;gveronicalg@gmail.com&gt;
 </ul>
diff --git a/doc/contrib.html b/doc/contrib.html
index 0290923..df53d48 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -34,6 +34,7 @@
 <p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
 
 <ul>
+	<li><a href="/doc/go1.10">Go 1.10</a> <small>(February 2018)</small></li>
 	<li><a href="/doc/go1.9">Go 1.9</a> <small>(August 2017)</small></li>
 	<li><a href="/doc/go1.8">Go 1.8</a> <small>(February 2017)</small></li>
 	<li><a href="/doc/go1.7">Go 1.7</a> <small>(August 2016)</small></li>
@@ -117,6 +118,6 @@
 <p>
 Check <a href="//golang.org/issue">the tracker</a> for 
 open issues that interest you. Those labeled
-<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a>
+<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22">help wanted</a>
 are particularly in need of outside help.
 </p>
diff --git a/doc/contribute.html b/doc/contribute.html
index f204b06..e5312be 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -30,7 +30,7 @@
 You only need to do this once per Google Account.
 </p>
 
-<h2 id="go-contrib-init">Automatically set up &amp; diagnose your development environment</h3>
+<h2 id="go-contrib-init">Automatically set up &amp; diagnose your development environment</h2>
 <p>
   The <code>go-contrib-init</code> tool configures and debugs your Go
   development environment, automatically performing many of the steps
@@ -88,7 +88,7 @@
 </p>
 
 <p>
-Your secret authentication token is now in a <code>.gitcookie</code> file
+Your secret authentication token is now in a <code>.gitcookies</code> file
 and Git is configured to use this file.
 </p>
 
@@ -158,7 +158,7 @@
 Changes to Go must be reviewed before they are accepted, no matter who makes the change.
 A custom git command called <code>git-codereview</code>, discussed below,
 helps manage the code review process through a Google-hosted
-<a href="https://go-review.googlesource.com/">instance</a> Gerrit.
+<a href="https://go-review.googlesource.com/">instance</a> of Gerrit.
 </p>
 
 <h3 id="git-codereview_install">Install the git-codereview command</h3>
@@ -187,7 +187,7 @@
 On Windows, when using git-bash you must make sure that
 <code>git-codereview.exe</code> is in your git exec-path.
 Run <code>git --exec-path</code> to discover the right location then create a
-symbolic link or simply copy the executible from $GOPATH/bin to this directory.
+symbolic link or simply copy the executable from $GOPATH/bin to this directory.
 </p>
 
 <p>
@@ -208,12 +208,6 @@
 <code>git-codereview</code> <code>hooks</code>.
 </p>
 
-<p>
-The workflow described below assumes a single change per branch.
-It is also possible to prepare a sequence of (usually related) changes in a single branch.
-See the <a href="https://golang.org/x/review/git-codereview">git-codereview documentation</a> for details.
-</p>
-
 <h3 id="git-config">Set up git aliases</h3>
 
 <p>
@@ -305,6 +299,15 @@
 sent during a feature freeze but will not be accepted until the freeze thaws.
 </p>
 
+<h3 id="scratch">Not sure what change to make?</h3>
+
+<p>
+If you want to become familiar with Gerrit and the contribution process,
+but aren't sure what you'd like to contribute just yet, you can use the <a
+href="https://go.googlesource.com/scratch">scratch repository</a> to practice
+making a change.
+</p>
+
 <h2 id="making_a_change">Making a change</h2>
 
 <h3 id="checkout_go">Getting Go Source</h3>
@@ -383,7 +386,7 @@
 <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.
-These files are automatically generated from the commit logs perodically.
+These files are automatically generated from the commit logs periodically.
 The <a href="/AUTHORS"><code>AUTHORS</code></a> file defines who &ldquo;The Go
 Authors&rdquo;&mdash;the copyright holders&mdash;are.
 </p>
@@ -391,7 +394,7 @@
 <p>New files that you contribute should use the standard copyright header:</p>
 
 <pre>
-// Copyright 2017 The Go Authors. All rights reserved.
+// Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 </pre>
@@ -420,6 +423,12 @@
 directly to that local branch.
 </p>
 
+<p>
+The workflow described here assumes a single change per branch.
+It is also possible to prepare a sequence of (usually related) changes in a single branch.
+See the <a href="https://golang.org/x/review/git-codereview">git-codereview documentation</a> for details.
+</p>
+
 <pre>
 $ git change <i>&lt;branch&gt;</i>
 </pre>
@@ -681,8 +690,8 @@
 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.)
+You may reply through the web interface or
+<a href="https://gerrit-review.googlesource.com/Documentation/intro-user.html#reply-by-email">via email</a>.
 </p>
 
 <h3 id="revise">Revise and resend</h3>
@@ -696,8 +705,8 @@
 </p>
 
 <p>
-You must respond to review comments through the web interface.
-(Unlike with the old Rietveld review system, responding by mail has no effect.)
+You may respond to review comments through the web interface or
+<a href="https://gerrit-review.googlesource.com/Documentation/intro-user.html#reply-by-email">via email</a>.
 </p>
 
 <p>
diff --git a/doc/debugging_with_gdb.html b/doc/debugging_with_gdb.html
index f0e65ea..19d36f7 100644
--- a/doc/debugging_with_gdb.html
+++ b/doc/debugging_with_gdb.html
@@ -3,51 +3,76 @@
 	"Path": "/doc/gdb"
 }-->
 
-<p><i>
-This applies to the standard toolchain (the <code>gc</code> Go
-compiler and tools). Gccgo has native gdb support.
-Besides this overview you might want to consult the
-<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
-</i></p>
+<!--
+NOTE: In this document and others in this directory, the convention is to
+set fixed-width phrases with non-fixed-width spaces, as in
+<code>hello</code> <code>world</code>.
+Do not send CLs removing the interior tags from such phrases.
+-->
+
+<i>
+<p>
+The following instructions apply to the standard toolchain
+(the <code>gc</code> Go compiler and tools).
+Gccgo has native gdb support.
+</p>
+<p>
+Note that 
+<a href="https://github.com/derekparker/delve">Delve</a> is a better 
+alternative to GDB when debugging Go programs built with the standard
+toolchain. It understands the Go runtime, data structures, and
+expressions better than GDB. Delve currently supports Linux, OSX,
+and Windows on <code>amd64</code>.
+For the most up-to-date list of supported platforms, please see
+<a href="https://github.com/derekparker/delve/tree/master/Documentation/installation">
+ the Delve documentation</a>.
+</p>
+</i>
 
 <p>
 GDB does not understand Go programs well.
 The stack management, threading, and runtime contain aspects that differ
 enough from the execution model GDB expects that they can confuse
-the debugger, even when the program is compiled with gccgo.
-As a consequence, although GDB can be useful in some situations, it is
-not a reliable debugger for Go programs, particularly heavily concurrent ones.
-Moreover, it is not a priority for the Go project to address these issues, which
-are difficult.
-In short, the instructions below should be taken only as a guide to how
-to use GDB when it works, not as a guarantee of success.
+the debugger and cause incorrect results even when the program is
+compiled with gccgo.
+As a consequence, although GDB can be useful in some situations (e.g.,
+debugging Cgo code, or debugging the runtime itself), it is not
+a reliable debugger for Go programs, particularly heavily concurrent
+ones.  Moreover, it is not a priority for the Go project to address
+these issues, which are difficult.
 </p>
 
 <p>
-In time, a more Go-centric debugging architecture may be required.
+In short, the instructions below should be taken only as a guide to how
+to use GDB when it works, not as a guarantee of success.
+
+Besides this overview you might want to consult the
+<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
+</p>
+
+<p>
 </p>
 
 <h2 id="Introduction">Introduction</h2>
 
 <p>
 When you compile and link your Go programs with the <code>gc</code> toolchain
-on Linux, Mac OS X, FreeBSD or NetBSD, the resulting binaries contain DWARFv3
-debugging information that recent versions (&gt;7.1) of the GDB debugger can
+on Linux, Mac OS X, FreeBSD or NetBSD, the resulting binaries contain DWARFv4
+debugging information that recent versions (&ge;7.5) of the GDB debugger can
 use to inspect a live process or a core dump.
 </p>
 
 <p>
 Pass the <code>'-w'</code> flag to the linker to omit the debug information
-(for example, <code>go build -ldflags "-w" prog.go</code>).
+(for example, <code>go</code> <code>build</code> <code>-ldflags=-w</code> <code>prog.go</code>).
 </p>
 
 <p>
 The code generated by the <code>gc</code> compiler includes inlining of
 function invocations and registerization of variables. These optimizations
-can sometimes make debugging with <code>gdb</code> harder. To disable them
-when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
-<a href="/cmd/go"><code>go</code></a> command used to build the code being
-debugged.
+can sometimes make debugging with <code>gdb</code> harder.
+If you find that you need to disable these optimizations,
+build your program using <code>go</code> <code>build</code> <code>-gcflags=all="-N -l"</code>.
 </p>
 
 <p>
@@ -94,7 +119,7 @@
 
 <p>
 A recent extension mechanism to GDB allows it to load extension scripts for a
-given binary. The tool chain uses this to extend GDB with a handful of
+given binary. The toolchain uses this to extend GDB with a handful of
 commands to inspect internals of the runtime code (such as goroutines) and to
 pretty print the built-in map, slice and channel types.
 </p>
@@ -139,7 +164,7 @@
 
 <p>
 If you're interested in what the debugging information looks like, run
-'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
+<code>objdump</code> <code>-W</code> <code>a.out</code> and browse through the <code>.debug_*</code>
 sections.
 </p>
 
@@ -162,7 +187,7 @@
 <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/regexp</code> and run <code>go test -c</code>.
+change to <code>$GOROOT/src/regexp</code> and run <code>go</code> <code>test</code> <code>-c</code>.
 This should produce an executable file named <code>regexp.test</code>.
 </p>
 
@@ -188,7 +213,7 @@
 </pre>
 
 <p>
-The message <code>"Loading Go Runtime support"</code> means that GDB loaded the
+The message "Loading Go Runtime support" means that GDB loaded the
 extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
 </p>
 
@@ -353,7 +378,7 @@
 </pre>
 
 <p>
-The command <code>info locals</code> lists all variables local to the function and their values, but is a bit
+The command <code>info</code> <code>locals</code> lists all variables local to the function and their values, but is a bit
 dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try
 to print arbitrary large arrays.
 </p>
@@ -386,7 +411,7 @@
 </pre>
 
 <p>
-That <code>struct hchan&lt;*testing.T&gt;</code> is the
+That <code>struct</code> <code>hchan&lt;*testing.T&gt;</code> is the
 runtime-internal representation of a channel. It is currently empty,
 or gdb would have pretty-printed its contents.
 </p>
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 8304522..d82fb0c 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -30,6 +30,39 @@
 Read the <a href="/doc/go1.9">Go 1.9 Release Notes</a> for more information.
 </p>
 
+<h3 id="go1.9.minor">Minor revisions</h3>
+
+<p>
+go1.9.1 (released 2017/10/04) includes two security fixes.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.1">Go
+1.9.1 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.9.2 (released 2017/10/25) includes fixes to the compiler, linker, runtime,
+documentation, <code>go</code> command,
+and the <code>crypto/x509</code>, <code>database/sql</code>, <code>log</code>,
+and <code>net/smtp</code> packages.
+It includes a fix to a bug introduced in Go 1.9.1 that broke <code>go</code> <code>get</code>
+of non-Git repositories under certain conditions.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.2">Go
+1.9.2 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.9.3 (released 2018/01/22) includes fixes to the compiler, runtime,
+and the <code>database/sql</code>, <code>math/big</code>, <code>net/http</code>,
+and <code>net/url</code> packages.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.3">Go
+1.9.3 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.9.4 (released 2018/02/07) includes a security fix to “go get”.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.4">Go
+1.9.4</a> milestone on our issue tracker for details.
+</p>
+
 <h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
 
 <p>
@@ -63,6 +96,37 @@
 1.8.3 milestone</a> on our issue tracker for details.
 </p>
 
+<p>
+go1.8.4 (released 2017/10/04) includes two security fixes.
+It contains the same fixes as Go 1.9.1 and was released at the same time.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.4">Go
+1.8.4 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.8.5 (released 2017/10/25) includes fixes to the compiler, linker, runtime,
+documentation, <code>go</code> command,
+and the <code>crypto/x509</code> and <code>net/smtp</code> packages.
+It includes a fix to a bug introduced in Go 1.8.4 that broke <code>go</code> <code>get</code>
+of non-Git repositories under certain conditions.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.5">Go
+1.8.5 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.8.6 (released 2018/01/22) includes the the same fix in <code>math/big</code>
+as Go 1.9.3 and was released at the same time.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.6">Go
+1.8.6 milestone</a> on our issue tracker for details.
+</p>
+
+<p>
+go1.8.7 (released 2018/02/07) includes a security fix to “go get”.
+It contains the same fix as Go 1.9.4 and was released at the same time.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.7">Go
+1.8.7</a> milestone on our issue tracker for details.
+</p>
+
 <h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
 
 <p>
@@ -236,7 +300,7 @@
 </p>
 
 <p>
-go1.3.3 (released 2014/09/30) includes further bug fixes to cgo, the runtime package, and the nacl port. 
+go1.3.3 (released 2014/09/30) includes further bug fixes to cgo, the runtime package, and the nacl port.
 See the <a href="https://github.com/golang/go/commits/go1.3.3">change history</a> for details.
 </p>
 
@@ -300,7 +364,7 @@
 </p>
 
 <p>
-The go1 release corresponds to 
+The go1 release corresponds to
 <code><a href="weekly.html#2012-03-27">weekly.2012-03-27</a></code>.
 </p>
 
@@ -316,7 +380,7 @@
 
 <p>
 go1.0.2 (released 2012/06/13) was issued to fix two bugs in the implementation
-of maps using struct or array keys: 
+of maps using struct or array keys:
 <a href="//golang.org/issue/3695">issue 3695</a> and
 <a href="//golang.org/issue/3573">issue 3573</a>.
 It also includes many minor code and documentation fixes.
diff --git a/doc/diagnostics.html b/doc/diagnostics.html
new file mode 100644
index 0000000..35aae15
--- /dev/null
+++ b/doc/diagnostics.html
@@ -0,0 +1,458 @@
+<!--{
+	"Title": "Diagnostics",
+	"Template": true
+}-->
+
+<!--
+NOTE: In this document and others in this directory, the convention is to
+set fixed-width phrases with non-fixed-width spaces, as in
+<code>hello</code> <code>world</code>.
+Do not send CLs removing the interior tags from such phrases.
+-->
+
+<h2 id="introduction">Introduction</h2>
+
+<p>
+The Go ecosystem provides a large suite of APIs and tools to
+diagnose logic and performance problems in Go programs. This page
+summarizes the available tools and helps Go users pick the right one
+for their specific problem.
+</p>
+
+<p>
+Diagnostics solutions can be categorized into the following groups:
+</p>
+
+<ul>
+<li><strong>Profiling</strong>: Profiling tools analyze the complexity and costs of a
+Go program such as its memory usage and frequently called
+functions to identify the expensive sections of a Go program.</li>
+<li><strong>Tracing</strong>: Tracing is a way to instrument code to analyze latency
+throughout the lifecycle of a call or user request. Traces provide an
+overview of how much latency each component contributes to the overall
+latency in a system. Traces can span multiple Go processes.</li>
+<li><strong>Debugging</strong>: Debugging allows us to pause a Go program and examine
+its execution. Program state and flow can be verified with debugging.</li>
+<li><strong>Runtime statistics and events</strong>: Collection and analysis of runtime stats and events
+provides a high-level overview of the health of Go programs. Spikes/dips of metrics
+helps us to identify changes in throughput, utilization, and performance.</li>
+</ul>
+
+<p>
+Note: Some diagnostics tools may interfere with each other. For example, precise
+memory profiling skews CPU profiles and goroutine blocking profiling affects scheduler
+trace. Use tools in isolation to get more precise info.
+</p>
+
+<h2 id="profiling">Profiling</h2>
+
+<p>
+Profiling is useful for identifying expensive or frequently called sections
+of code. The Go runtime provides <a href="https://golang.org/pkg/runtime/pprof/">
+profiling data</a> in the format expected by the
+<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
+The profiling data can be collected during testing
+via <code>go</code> <code>test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
+net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
+and visualize the top code paths.
+</p>
+
+<p>Predefined profiles provided by the <a href="/pkg/runtime/pprof">runtime/pprof</a> package:</p>
+
+<ul>
+<li>
+<strong>cpu</strong>: CPU profile determines where a program spends
+its time while actively consuming CPU cycles (as opposed to while sleeping or waiting for I/O).
+</li>
+<li>
+<strong>heap</strong>: Heap profile reports memory allocation samples;
+used to monitor current and historical memory usage, and to check for memory leaks.
+</li>
+<li>
+<strong>threadcreate</strong>: Thread creation profile reports the sections
+of the program that lead the creation of new OS threads.
+</li>
+<li>
+<strong>goroutine</strong>: Goroutine profile reports the stack traces of all current goroutines.
+</li>
+<li>
+<strong>block</strong>: Block profile shows where goroutines block waiting on synchronization
+primitives (including timer channels). Block profile is not enabled by default;
+use <code>runtime.SetBlockProfileRate</code> to enable it.
+</li>
+<li>
+<strong>mutex</strong>: Mutex profile reports the lock contentions. When you think your
+CPU is not fully utilized due to a mutex contention, use this profile. Mutex profile
+is not enabled by default, see <code>runtime.SetMutexProfileFraction</code> to enable it.
+</li>
+</ul>
+
+
+<p><strong>What other profilers can I use to profile Go programs?</strong></p>
+
+<p>
+On Linux, <a href="https://perf.wiki.kernel.org/index.php/Tutorial">perf tools</a>
+can be used for profiling Go programs. Perf can profile
+and unwind cgo/SWIG code and kernel, so it can be useful to get insights into
+native/kernel performance bottlenecks. On macOS,
+<a href="https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/">Instruments</a>
+suite can be used profile Go programs.
+</p>
+
+<p><strong>Can I profile my production services?</strong></p>
+
+<p>Yes. It is safe to profile programs in production, but enabling
+some profiles (e.g. the CPU profile) adds cost. You should expect to
+see performance downgrade. The performance penalty can be estimated
+by measuring the overhead of the profiler before turning it on in
+production.
+</p>
+
+<p>
+You may want to periodically profile your production services.
+Especially in a system with many replicas of a single process, selecting
+a random replica periodically is a safe option.
+Select a production process, profile it for
+X seconds for every Y seconds and save the results for visualization and
+analysis; then repeat periodically. Results may be manually and/or automatically
+reviewed to find problems.
+Collection of profiles can interfere with each other,
+so it is recommended to collect only a single profile at a time.
+</p>
+
+<p>
+<strong>What are the best ways to visualize the profiling data?</strong>
+</p>
+
+<p>
+The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
+visualization of the profile data using
+<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
+Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
+to see them in action.
+</p>
+
+<p>
+<img width="800" src="https://storage.googleapis.com/golangorg-assets/pprof-text.png">
+<br>
+<small>Listing of the most expensive calls as text.</small>
+</p>
+
+<p>
+<img width="800" src="https://storage.googleapis.com/golangorg-assets/pprof-dot.png">
+<br>
+<small>Visualization of the most expensive calls as a graph.</small>
+</p>
+
+<p>Weblist view displays the expensive parts of the source line by line in
+an HTML page. In the following example, 530ms is spent in the
+<code>runtime.concatstrings</code> and cost of each line is presented
+in the listing.</p>
+
+<p>
+<img width="800" src="https://storage.googleapis.com/golangorg-assets/pprof-weblist.png">
+<br>
+<small>Visualization of the most expensive calls as weblist.</small>
+</p>
+
+<p>
+Another way to visualize profile data is a <a href="http://www.brendangregg.com/flamegraphs.html">flame graph</a>.
+Flame graphs allow you to move in a specific ancestry path, so you can zoom
+in/out of specific sections of code.
+The <a href="https://github.com/google/pprof">upstream pprof</a>
+has support for flame graphs.
+</p>
+
+<p>
+<img width="800" src="https://storage.googleapis.com/golangorg-assets/flame.png">
+<br>
+<small>Flame graphs offers visualization to spot the most expensive code-paths.</small>
+</p>
+
+<p><strong>Am I restricted to the built-in profiles?</strong></p>
+
+<p>
+Additionally to what is provided by the runtime, Go users can create
+their custom profiles via <a href="/pkg/runtime/pprof/#Profile">pprof.Profile</a>
+and use the existing tools to examine them.
+</p>
+
+<p><strong>Can I serve the profiler handlers (/debug/pprof/...) on a different path and port?</strong></p>
+
+<p>
+Yes. The <code>net/http/pprof</code> package registers its handlers to the default
+mux by default, but you can also register them yourself by using the handlers
+exported from the package.
+</p>
+
+<p>
+For example, the following example will serve the pprof.Profile
+handler on :7777 at /custom_debug_path/profile:
+</p>
+
+<p>
+<pre>
+package main
+
+import (
+	"log"
+	"net/http"
+	"net/http/pprof"
+)
+
+func main() {
+	mux := http.NewServeMux()
+	mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
+	log.Fatal(http.ListenAndServe(":7777", mux))
+}
+</pre>
+</p>
+
+<h2 id="tracing">Tracing</h2>
+
+<p>
+Tracing is a way to instrument code to analyze latency throughout the
+lifecycle of a chain of calls. Go provides
+<a href="https://godoc.org/golang.org/x/net/trace">golang.org/x/net/trace</a>
+package as a minimal tracing backend per Go node and provides a minimal
+instrumentation library with a simple dashboard. Go also provides
+an execution tracer to trace the runtime events within an interval.
+</p>
+
+<p>Tracing enables us to:</p>
+
+<ul>
+<li>Instrument and analyze application latency in a Go process.</li>
+<li>Measure the cost of specific calls in a long chain of calls.</li>
+<li>Figure out the utilization and performance improvements.
+Bottlenecks are not always obvious without tracing data.</li>
+</ul>
+
+<p>
+In monolithic systems, it's relatively easy to collect diagnostic data
+from the building blocks of a program. All modules live within one
+process and share common resources to report logs, errors, and other
+diagnostic information. Once your system grows beyond a single process and
+starts to become distributed, it becomes harder to follow a call starting
+from the front-end web server to all of its back-ends until a response is
+returned back to the user. This is where distributed tracing plays a big
+role to instrument and analyze your production systems.
+</p>
+
+<p>
+Distributed tracing is a way to instrument code to analyze latency throughout
+the lifecycle of a user request. When a system is distributed and when
+conventional profiling and debugging tools don’t scale, you might want
+to use distributed tracing tools to analyze the performance of your user
+requests and RPCs.
+</p>
+
+<p>Distributed tracing enables us to:</p>
+
+<ul>
+<li>Instrument and profile application latency in a large system.</li>
+<li>Track all RPCs within the lifecycle of a user request and see integration issues
+that are only visible in production.</li>
+<li>Figure out performance improvements that can be applied to our systems.
+Many bottlenecks are not obvious before the collection of tracing data.</li>
+</ul>
+
+<p>The Go ecosystem provides various distributed tracing libraries per tracing system
+and backend-agnostic ones.</p>
+
+
+<p><strong>Is there a way to automatically intercept each function call and create traces?</strong></p>
+
+<p>
+Go doesn’t provide a way to automatically intercept every function call and create
+trace spans. You need to manually instrument your code to create, end, and annotate spans.
+</p>
+
+<p><strong>How should I propagate trace headers in Go libraries?</strong></p>
+
+<p>
+You can propagate trace identifiers and tags in the
+<a href="/pkg/context#Context"><code>context.Context</code></a>.
+There is no canonical trace key or common representation of trace headers
+in the industry yet. Each tracing provider is responsible for providing propagation
+utilities in their Go libraries.
+</p>
+
+<p>
+<strong>What other low-level events from the standard library or
+runtime can be included in a trace?</strong>
+</p>
+
+<p>
+The standard library and runtime are trying to expose several additional APIs
+to notify on low level internal events. For example,
+<a href="/pkg/net/http/httptrace#ClientTrace"><code>httptrace.ClientTrace</code></a>
+provides APIs to follow low-level events in the life cycle of an outgoing request.
+There is an ongoing effort to retrieve low-level runtime events from
+the runtime execution tracer and allow users to define and record their user events.
+</p>
+
+<h2 id="debugging">Debugging</h2>
+
+<p>
+Debugging is the process of identifying why a program misbehaves.
+Debuggers allow us to understand a program’s execution flow and current state.
+There are several styles of debugging; this section will only focus on attaching
+a debugger to a program and core dump debugging.
+</p>
+
+<p>Go users mostly use the following debuggers:</p>
+
+<ul>
+<li>
+<a href="https://github.com/derekparker/delve">Delve</a>:
+Delve is a debugger for the Go programming language. It has
+support for Go’s runtime concepts and built-in types. Delve is
+trying to be a fully featured reliable debugger for Go programs.
+</li>
+<li>
+<a href="https://golang.org/doc/gdb">GDB</a>:
+Go provides GDB support via the standard Go compiler and Gccgo.
+The stack management, threading, and runtime contain aspects that differ
+enough from the execution model GDB expects that they can confuse the
+debugger, even when the program is compiled with gccgo. Even though
+GDB can be used to debug Go programs, it is not ideal and may
+create confusion.
+</li>
+</ul>
+
+<p><strong>How well do debuggers work with Go programs?</strong></p>
+
+<p>
+The <code>gc</code> compiler performs optimizations such as
+function inlining and variable registerization. These optimizations
+sometimes make debugging with debuggers harder. There is an ongoing
+effort to improve the quality of the DWARF information generated for
+optimized binaries. Until those improvements are available, we recommend
+disabling optimizations when building the code being debugged. The following
+command builds a package with no compiler optimizations:
+
+<p>
+<pre>
+$ go build -gcflags=all="-N -l"
+</pre>
+</p>
+
+As part of the improvement effort, Go 1.10 introduced a new compiler
+flag <code>-dwarflocationlists</code>. The flag causes the compiler to
+add location lists that helps debuggers work with optimized binaries.
+The following command builds a package with optimizations but with
+the DWARF location lists:
+
+<p>
+<pre>
+$ go build -gcflags="-dwarflocationlists=true"
+</pre>
+</p>
+
+<p><strong>What’s the recommended debugger user interface?</strong></p>
+
+<p>
+Even though both delve and gdb provides CLIs, most editor integrations
+and IDEs provides debugging-specific user interfaces.
+</p>
+
+<p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p>
+
+<p>
+A core dump file is a file that contains the memory dump of a running
+process and its process status. It is primarily used for post-mortem
+debugging of a program and to understand its state
+while it is still running. These two cases make debugging of core
+dumps a good diagnostic aid to postmortem and analyze production
+services. It is possible to obtain core files from Go programs and
+use delve or gdb to debug, see the
+<a href="https://golang.org/wiki/CoreDumpDebugging">core dump debugging</a>
+page for a step-by-step guide.
+</p>
+
+<h2 id="runtime">Runtime statistics and events</h2>
+
+<p>
+The runtime provides stats and reporting of internal events for
+users to diagnose performance and utilization problems at the
+runtime level.
+</p>
+
+<p>
+Users can monitor these stats to better understand the overall
+health and performance of Go programs.
+Some frequently monitored stats and states:
+</p>
+
+<ul>
+<li><code><a href="/pkg/runtime/#ReadMemStats">runtime.ReadMemStats</a></code>
+reports the metrics related to heap
+allocation and garbage collection. Memory stats are useful for
+monitoring how much memory resources a process is consuming,
+whether the process can utilize memory well, and to catch
+memory leaks.</li>
+<li><code><a href="/pkg/runtime/debug/#ReadGCStats">debug.ReadGCStats</a></code>
+reads statistics about garbage collection.
+It is useful to see how much of the resources are spent on GC pauses.
+It also reports a timeline of garbage collector pauses and pause time percentiles.</li>
+<li><code><a href="/pkg/runtime/debug/#Stack">debug.Stack</a></code>
+returns the current stack trace. Stack trace
+is useful to see how many goroutines are currently running,
+what they are doing, and whether they are blocked or not.</li>
+<li><code><a href="/pkg/runtime/debug/#WriteHeapDump">debug.WriteHeapDump</a></code>
+suspends the execution of all goroutines
+and allows you to dump the heap to a file. A heap dump is a
+snapshot of a Go process' memory at a given time. It contains all
+allocated objects as well as goroutines, finalizers, and more.</li>
+<li><code><a href="/pkg/runtime#NumGoroutine">runtime.NumGoroutine</a></code>
+returns the number of current goroutines.
+The value can be monitored to see whether enough goroutines are
+utilized, or to detect goroutine leaks.</li>
+</ul>
+
+<h3 id="execution-tracer">Execution tracer</h3>
+
+<p>Go comes with a runtime execution tracer to capture a wide range
+of runtime events. Scheduling, syscall, garbage collections,
+heap size, and other events are collected by runtime and available
+for visualization by the go tool trace. Execution tracer is a tool
+to detect latency and utilization problems. You can examine how well
+the CPU is utilized, and when networking or syscalls are a cause of
+preemption for the goroutines.</p>
+
+<p>Tracer is useful to:</p>
+<ul>
+<li>Understand how your goroutines execute.</li>
+<li>Understand some of the core runtime events such as GC runs.</li>
+<li>Identify poorly parallelized execution.</li>
+</ul>
+
+<p>However, it is not great for identifying hot spots such as
+analyzing the cause of excessive memory or CPU usage.
+Use profiling tools instead first to address them.</p>
+
+<p>
+<img width="800" src="https://storage.googleapis.com/golangorg-assets/tracer-lock.png">
+</p>
+
+<p>Above, the go tool trace visualization shows the execution started
+fine, and then it became serialized. It suggests that there might
+be lock contention for a shared resource that creates a bottleneck.</p>
+
+<p>See <a href="https://golang.org/cmd/trace/"><code>go</code> <code>tool</code> <code>trace</code></a>
+to collect and analyze runtime traces.
+</p>
+
+<h3 id="godebug">GODEBUG</h3>
+
+<p>Runtime also emits events and information if
+<a href="https://golang.org/pkg/runtime/#hdr-Environment_Variables">GODEBUG</a>
+environmental variable is set accordingly.</p>
+
+<ul>
+<li>GODEBUG=gctrace=1 prints garbage collector events at
+each collection, summarizing the amount of memory collected
+and the length of the pause.</li>
+<li>GODEBUG=schedtrace=X prints scheduling events every X milliseconds.</li>
+</ul>
diff --git a/doc/docs.html b/doc/docs.html
index 92392e2..21a9a63 100644
--- a/doc/docs.html
+++ b/doc/docs.html
@@ -1,6 +1,7 @@
 <!--{
 	"Title": "Documentation",
-	"Path": "/doc/"
+	"Path": "/doc/",
+	"Template": true
 }-->
 
 <p>
@@ -33,28 +34,37 @@
 
 <img class="gopher" src="/doc/gopher/doc.png"/>
 
-<h3 id="go_tour"><a href="//tour.golang.org/">A Tour of Go</a></h3>
+<h3 id="go_tour">
+	{{if $.GoogleCN}}
+	  A Tour of Go
+	{{else}}
+	  <a href="//tour.golang.org/">A Tour of Go</a>
+	{{end}}
+</h3>
 <p>
 An interactive introduction to Go in three sections.
 The first section covers basic syntax and data structures; the second discusses
 methods and interfaces; and the third introduces Go's concurrency primitives.
 Each section concludes with a few exercises so you can practice what you've
-learned. You can <a href="//tour.golang.org/">take the tour online</a> or
-install it locally with:
+learned. You can {{if not $.GoogleCN}}<a href="//tour.golang.org/">take the tour
+online</a> or{{end}} install it locally with:
 </p>
-<p>
 <pre>
 $ go get golang.org/x/tour/gotour
 </pre>
+<p>
 This will place the <code>gotour</code> binary in your workspace's <code>bin</code> directory.
 </p>
 
 <h3 id="code"><a href="code.html">How to write Go code</a></h3>
 <p>
-Also available as a
-<a href="//www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>, this doc
-explains how to use the <a href="/cmd/go/">go command</a> to fetch, build, and
-install packages, commands, and run tests.
+{{if not $.GoogleCN}}
+Also available as a <a href="//www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>, this
+{{else}}
+This
+{{end}}
+doc explains how to use the <a href="/cmd/go/">go command</a>
+to fetch, build, and install packages, commands, and run tests.
 </p>
 
 <h3 id="editors"><a href="editors.html">Editor plugins and IDEs</a></h3>
@@ -70,6 +80,11 @@
 the language specification, both of which should be read first.
 </p>
 
+<h3 id="diagnostics"><a href="/doc/diagnostics.html">Diagnostics</a></h3>
+<p>
+Summarizes tools and methodologies to diagnose problems in Go programs.
+</p>
+
 <h3 id="faq"><a href="/doc/faq">Frequently Asked Questions (FAQ)</a></h3>
 <p>
 Answers to common questions about Go.
@@ -115,9 +130,11 @@
 
 <h2 id="articles">Articles</h2>
 
+{{if not $.GoogleCN}}
 <h3 id="blog"><a href="//blog.golang.org/">The Go Blog</a></h3>
 <p>The official blog of the Go project, featuring news and in-depth articles by
 the Go team and guests.</p>
+{{end}}
 
 <h4>Codewalks</h4>
 <p>
@@ -130,6 +147,7 @@
 <li><a href="/doc/articles/wiki/">Writing Web Applications</a> - building a simple web application.</li>
 </ul>
 
+{{if not $.GoogleCN}}
 <h4>Language</h4>
 <ul>
 <li><a href="/blog/json-rpc-tale-of-interfaces">JSON-RPC: a tale of interfaces</a></li>
@@ -150,17 +168,20 @@
 <li><a href="/blog/go-image-package">The Go image package</a> - the fundamentals of the <a href="/pkg/image/">image</a> package.</li>
 <li><a href="/blog/go-imagedraw-package">The Go image/draw package</a> - the fundamentals of the <a href="/pkg/image/draw/">image/draw</a> package.</li>
 </ul>
+{{end}}
 
 <h4>Tools</h4>
 <ul>
 <li><a href="/doc/articles/go_command.html">About the Go command</a> - why we wrote it, what it is, what it's not, and how to use it.</li>
-<li><a href="/blog/c-go-cgo">C? Go? Cgo!</a> - linking against C code with <a href="/cmd/cgo/">cgo</a>.</li>
 <li><a href="/doc/gdb">Debugging Go Code with GDB</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="/doc/asm">A Quick Guide to Go's Assembler</a> - an introduction to the assembler used by Go.</li>
+{{if not $.GoogleCN}}
+<li><a href="/blog/c-go-cgo">C? Go? Cgo!</a> - linking against C code with <a href="/cmd/cgo/">cgo</a>.</li>
 <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>
-<li><a href="/doc/asm">A Quick Guide to Go's Assembler</a> - an introduction to the assembler used by Go.</li>
+{{end}}
 </ul>
 
 <h4 id="articles_more">More</h4>
@@ -169,7 +190,7 @@
 <a href="/wiki">Wiki</a> for more Go articles.
 </p>
 
-
+{{if not $.GoogleCN}}
 <h2 id="talks">Talks</h2>
 
 <img class="gopher" src="/doc/gopher/talks.png"/>
@@ -200,7 +221,7 @@
 <p>
 See the <a href="/talks">Go Talks site</a> and <a href="/wiki/GoTalks">wiki page</a> for more Go talks.
 </p>
-
+{{end}}
 
 <h2 id="nonenglish">Non-English Documentation</h2>
 
diff --git a/doc/editors.html b/doc/editors.html
index 264f5af..617a100 100644
--- a/doc/editors.html
+++ b/doc/editors.html
@@ -22,8 +22,8 @@
 <li><a href="https://github.com/fatih/vim-go">vim</a>: vim-go plugin provides Go programming language support</li>
 <li><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Visual Studio Code</a>:
 Go extension provides support for the Go programming language</li>
-<li><a href="https://www.jetbrains.com/go">Gogland</a>: Gogland is distributed either as a standalone IDE
-or as a plugin for the commercial IntelliJ Platform IDEs</li>
+<li><a href="https://www.jetbrains.com/go">GoLand</a>: GoLand is distributed either as a standalone IDE
+or as a plugin for IntelliJ IDEA Ultimate</li>
 <li><a href="https://atom.io/packages/go-plus">Atom</a>: Go-Plus is an Atom package that provides enhanced Go support</li>
 </ul>
 
@@ -33,199 +33,3 @@
 <a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a>
 is available at the Wiki.
 </p>
-
-<p>
-Each development environment integrates a number of Go-specific tools.
-The following feature matrix lists and compares the most significant features.
-</p>
-
-<table class="features-matrix">
-  <tr>
-    <th></th>
-    <th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>vim</th>
-    <th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code</th>
-    <th><img title="Gogland" src="/doc/editors/gogland.png"><br>Gogland</th>
-    <th><img title="Go-Plus" src="/doc/editors/go-plus.png"><br>Atom</th>
-  </tr>
-  <tr>
-    <td class="feature-row" colspan="5">Editing features</td>
-  </tr>
-  <tr>
-    <td>Build and run from the editor/IDE</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Autocompletion of identifers (variable, method, and function names)</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Type-aware autocompletion</td>
-    <td class="no">No</td>
-    <td class="no">No</td>
-    <td class="yes">Yes</td>
-    <td class="no">No</td>
-  </tr>
-  <tr>
-    <td>Rename identifiers</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Auto format, build, vet, and lint on save</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes<sup>1</sup></td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Auto insert import paths and remove unused on save</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes<sup>2</sup></td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Auto generate JSON, XML tags for struct fields</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td class="feature-row" colspan="5">Navigation features</td>
-  </tr>
-  <tr>
-    <td>Display documentation inline, or open godoc in browser</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Switch between <code>*.go</code> and <code>*_test.go</code> file</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">No</td>
-  </tr>
-  <tr>
-    <td>Jump to definition and referees</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Look up for interface implementations</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td>Search for callers and callees</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr>
-    <td class="feature-row" colspan="5">Testing and debugging features</td>
-  </tr>
-  <tr>
-    <td>Debugger support</td>
-    <td class="no">No</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes<sup>3</sup></td>
-
-  </tr>
-  <tr>
-    <td>Run a single test case, all tests from file, or all tests from a package</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="no">No</td>
-  </tr>
-  <tr>
-    <td>Auto generate tests for packages, files and identifiers</td>
-    <td class="no">No</td>
-    <td class="yes">Yes</td>
-    <td class="no">No</td>
-    <td class="no">No</td>
-  </tr>
-  <tr>
-    <td>Debug tests</td>
-    <td class="no">No</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes<sup>3</sup></td>
-  </tr>
-  <tr>
-    <td>Display test coverage</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-    <td class="yes">Yes</td>
-  </tr>
-  <tr class="download">
-    <td></td>
-    <td><a href="https://github.com/fatih/vim-go">Install<a/></td>
-    <td><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Install<a/></td>
-    <td><a href="https://www.jetbrains.com/go">Install<a/></td>
-    <td><a href="https://atom.io/packages/go-plus">Install</a></td>
-  </tr>
-</table>
-
-<p>
-<sup>1</sup>Possible when enabled via Settings &gt; Go &gt; On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
-<br>
-<sup>2</sup>Additionally, user input can disambiguate when two or more options are available.
-<br>
-<sup>3</sup>Available if the <a href="https://atom.io/packages/go-debug">go-debug</a> package is installed.
-</p>
-
-</div>
-
-<style>
-.features-matrix {
-  min-width: 800px;
-  border-collapse: collapse;
-}
-.features-matrix th {
-  width: 60px;
-  text-align: center;
-  font-size: 14px;
-  color: #666;
-}
-.features-matrix th img {
-  width: 48px;
-}
-.features-matrix .yes {
-  text-align: center;
-}
-.features-matrix .no {
-  text-align: center;
-  background-color: #ffe9e9;
-}
-.features-matrix .download {
-  font-weight: bold;
-  text-align: center;
-}
-.features-matrix td {
-  padding: 11px 5px 11px 5px;
-  border-bottom: solid 1px #ebebeb;
-}
-.features-matrix .feature-row {
-  background-color: #ebebeb;
-  font-weight: bold;
-}
-</style>
diff --git a/doc/editors/go-plus.png b/doc/editors/go-plus.png
deleted file mode 100644
index c09c7fe..0000000
--- a/doc/editors/go-plus.png
+++ /dev/null
Binary files differ
diff --git a/doc/editors/gogland.png b/doc/editors/gogland.png
deleted file mode 100644
index 842f089..0000000
--- a/doc/editors/gogland.png
+++ /dev/null
Binary files differ
diff --git a/doc/editors/vimgo.png b/doc/editors/vimgo.png
deleted file mode 100644
index cf317ef..0000000
--- a/doc/editors/vimgo.png
+++ /dev/null
Binary files differ
diff --git a/doc/editors/vscodego.png b/doc/editors/vscodego.png
deleted file mode 100644
index 4e6c7b8..0000000
--- a/doc/editors/vscodego.png
+++ /dev/null
Binary files differ
diff --git a/doc/effective_go.html b/doc/effective_go.html
index bc70b0c..61de824 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -1431,9 +1431,7 @@
         slice = newSlice
     }
     slice = slice[0:l+len(data)]
-    for i, c := range data {
-        slice[l+i] = c
-    }
+    copy(slice[l:], data)
     return slice
 }
 </pre>
@@ -1521,7 +1519,7 @@
 <p>
 Maps are a convenient and powerful built-in data structure that associate
 values of one type (the <em>key</em>) with values of another type
-(the <em>element</em> or <em>value</em>)
+(the <em>element</em> or <em>value</em>).
 The key can be of any type for which the equality operator is defined,
 such as integers,
 floating point and complex numbers,
@@ -2792,7 +2790,7 @@
 <p>
 If we need to refer to an embedded field directly, the type name of the field,
 ignoring the package qualifier, serves as a field name, as it did
-in the <code>Read</code> method of our <code>ReaderWriter</code> struct.
+in the <code>Read</code> method of our <code>ReadWriter</code> struct.
 Here, if we needed to access the
 <code>*log.Logger</code> of a <code>Job</code> variable <code>job</code>,
 we would write <code>job.Logger</code>,
diff --git a/doc/gccgo_install.html b/doc/gccgo_install.html
index 4f6a911..d4eac12 100644
--- a/doc/gccgo_install.html
+++ b/doc/gccgo_install.html
@@ -59,10 +59,17 @@
 </p>
 
 <p>
-The GCC 7 releases are expected to include a complete implementation
-of the Go 1.8 user libraries.  As with earlier releases, the Go 1.8
-runtime is not fully merged, but that should not be visible to Go
-programs.
+The GCC 7 releases include a complete implementation of the Go 1.8.1
+user libraries.  As with earlier releases, the Go 1.8 runtime is not
+fully merged, but that should not be visible to Go programs.
+</p>
+
+<p>
+The GCC 8 releases are expected to include a complete implementation
+of the Go 1.10 release, depending on release timing.  The Go 1.10
+runtime has now been fully merged into the GCC development sources,
+and concurrent garbage collection is expected to be fully supported in
+GCC 8.
 </p>
 
 <h2 id="Source_code">Source code</h2>
diff --git a/doc/go1.1.html b/doc/go1.1.html
index f059fd7..f615c97 100644
--- a/doc/go1.1.html
+++ b/doc/go1.1.html
@@ -166,7 +166,7 @@
 <h3 id="gc_flag">Command-line flag parsing</h3>
 
 <p>
-In the gc tool chain, the compilers and linkers now use the
+In the gc toolchain, the compilers and linkers now use the
 same command-line flag parsing rules as the Go flag package, a departure
 from the traditional Unix flag parsing. This may affect scripts that invoke
 the tool directly.
@@ -305,7 +305,7 @@
 <p>
 Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and
 a new internal <a href="//golang.org/s/go11func">representation of functions</a>,
-the arrangement of function arguments on the stack has changed in the gc tool chain.
+the arrangement of function arguments on the stack has changed in the gc toolchain.
 Functions written in assembly will need to be revised at least
 to adjust frame pointer offsets.
 </p>
@@ -395,7 +395,7 @@
 The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as
 <code>go fix</code>, no longer applies fixes to update code from
 before Go 1 to use Go 1 APIs.
-To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain
+To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain
 to convert the code to Go 1.0 first.
 </p>
 
@@ -427,7 +427,7 @@
 <h3 id="platforms">Additional platforms</h3>
 
 <p>
-The Go 1.1 tool chain adds experimental support for <code>freebsd/arm</code>,
+The Go 1.1 toolchain adds experimental support for <code>freebsd/arm</code>,
 <code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>,
 <code>openbsd/386</code> and <code>openbsd/amd64</code> platforms.
 </p>
diff --git a/doc/go1.10.html b/doc/go1.10.html
new file mode 100644
index 0000000..4c0e847
--- /dev/null
+++ b/doc/go1.10.html
@@ -0,0 +1,1448 @@
+<!--{
+	"Title": "Go 1.10 Release Notes",
+	"Path":  "/doc/go1.10",
+	"Template": true
+}-->
+
+<!--
+NOTE: In this document and others in this directory, the convention is to
+set fixed-width phrases with non-fixed-width spaces, as in
+<code>hello</code> <code>world</code>.
+Do not send CLs removing the interior tags from such phrases.
+-->
+
+<style>
+ul li { margin: 0.5em 0; }
+</style>
+
+<h2 id="introduction">Introduction to Go 1.10</h2>
+
+<p>
+The latest Go release, version 1.10, arrives six months after <a href="go1.9">Go 1.9</a>.
+Most of its changes are in the implementation of the toolchain, runtime, and libraries.
+As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
+We expect almost all Go programs to continue to compile and run as before.
+</p>
+
+<p>
+This release improves <a href="#build">caching of built packages</a>,
+adds <a href="#test">caching of successful test results</a>,
+runs <a href="#test-vet">vet automatically during tests</a>,
+and
+permits <a href="#cgo">passing string values directly between Go and C using cgo</a>.
+A new <a href="#cgo">compiler option whitelist</a> may cause
+unexpected <a href="https://golang.org/s/invalidflag"><code>invalid
+flag</code></a> errors in code that built successfully with older
+releases.
+</p>
+
+<h2 id="language">Changes to the language</h2>
+
+<p>
+There are no significant changes to the language specification.
+</p>
+
+<p><!-- CL 60230 -->
+A corner case involving shifts by untyped constants has been clarified,
+and as a result the compilers have been updated to allow the index expression
+<code>x[1.0</code>&nbsp;<code>&lt;&lt;</code>&nbsp;<code>s]</code> where <code>s</code> is an untyped constant;
+the <a href="/pkg/go/types/">go/types</a> package already did.
+</p>
+
+<p><!-- CL 73233 -->
+The grammar for method expressions has been updated to relax the
+syntax to allow any type expression as a receiver;
+this matches what the compilers were already implementing.
+For example, <code>struct{io.Reader}.Read</code> is a valid, if unusual,
+method expression that the compilers already accepted and is
+now permitted by the language grammar.
+</p>
+
+<h2 id="ports">Ports</h2>
+
+<p>
+There are no new supported operating systems or processor architectures in this release.
+Most of the work has focused on strengthening the support for existing ports,
+in particular <a href="#asm">new instructions in the assembler</a>
+and improvements to the code generated by the compilers.
+</p>
+
+<p id="freebsd">
+As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>,
+Go 1.10 now requires FreeBSD 10.3 or later;
+support for FreeBSD 9.3 has been removed.
+</p>
+
+<p id="netbsd">
+Go now runs on NetBSD again but requires the unreleased NetBSD 8.
+Only <code>GOARCH</code> <code>amd64</code> and <code>386</code> have
+been fixed. The <code>arm</code> port is still broken.
+</p>
+
+<p id="mips">
+On 32-bit MIPS systems, the new environment variable settings
+<code>GOMIPS=hardfloat</code> (the default) and
+<code>GOMIPS=softfloat</code> select whether to use
+hardware instructions or software emulation for floating-point computations.
+</p>
+
+<p id="openbsd">
+Go 1.10 is the last release that will run on OpenBSD 6.0.
+Go 1.11 will require OpenBSD 6.2.
+</p>
+
+<p id="darwin">
+Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion or OS X 10.9 Mavericks.
+Go 1.11 will require OS X 10.10 Yosemite or later.
+</p>
+
+<p id="windows">
+Go 1.10 is the last release that will run on Windows XP or Windows Vista.
+Go 1.11 will require Windows 7 or later.
+</p>
+
+<h2 id="tools">Tools</h2>
+
+<h3 id="goroot">Default GOROOT &amp; GOTMPDIR</h3>
+
+<p>
+If the environment variable <code>$GOROOT</code> is unset,
+the go tool previously used the default <code>GOROOT</code>
+set during toolchain compilation.
+Now, before falling back to that default, the go tool attempts to
+deduce <code>GOROOT</code> from its own executable path.
+This allows binary distributions to be unpacked anywhere in the
+file system and then be used without setting <code>GOROOT</code>
+explicitly.
+</p>
+
+<p>
+By default, the go tool creates its temporary files and directories
+in the system temporary directory (for example, <code>$TMPDIR</code> on Unix).
+If the new environment variable <code>$GOTMPDIR</code> is set,
+the go tool will creates its temporary files and directories in that directory instead.
+</p>
+
+<h3 id="build">Build &amp; Install</h3>
+
+<p>
+The <code>go</code>&nbsp;<code>build</code> command now detects out-of-date packages
+purely based on the content of source files, specified build flags, and metadata stored in the compiled packages.
+Modification times are no longer consulted or relevant.
+The old advice to add <code>-a</code> to force a rebuild in cases where
+the modification times were misleading for one reason or another
+(for example, changes in build flags) is no longer necessary:
+builds now always detect when packages must be rebuilt.
+(If you observe otherwise, please file a bug.)
+</p>
+
+<p>
+The <code>go</code>&nbsp;<code>build</code> <code>-asmflags</code>, <code>-gcflags</code>, <code>-gccgoflags</code>, and <code>-ldflags</code> options
+now apply by default only to the packages listed directly on the command line.
+For example, <code>go</code> <code>build</code> <code>-gcflags=-m</code> <code>mypkg</code>
+passes the compiler the <code>-m</code> flag when building <code>mypkg</code>
+but not its dependencies.
+The new, more general form <code>-asmflags=pattern=flags</code> (and similarly for the others)
+applies the <code>flags</code> only to the packages matching the pattern.
+For example: <code>go</code> <code>install</code> <code>-ldflags=cmd/gofmt=-X=main.version=1.2.3</code> <code>cmd/...</code>
+installs all the commands matching <code>cmd/...</code> but only applies the <code>-X</code> option
+to the linker flags for <code>cmd/gofmt</code>.
+For more details, see <a href="/cmd/go/#hdr-Compile_packages_and_dependencies"><code>go</code> <code>help</code> <code>build</code></a>.
+</p>
+
+<p>
+The <code>go</code>&nbsp;<code>build</code> command now maintains a cache of
+recently built packages, separate from the installed packages in <code>$GOROOT/pkg</code> or <code>$GOPATH/pkg</code>.
+The effect of the cache should be to speed builds that do not explicitly install packages
+or when switching between different copies of source code (for example, when changing
+back and forth between different branches in a version control system).
+The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code>
+or <code>go</code> <code>test</code> <code>-i</code>,
+is no longer necessary: builds run just as fast without <code>-i</code>.
+For more details, see <a href="/cmd/go/#hdr-Build_and_test_caching"><code>go</code> <code>help</code> <code>cache</code></a>.
+</p>
+
+<p>
+The <code>go</code>&nbsp;<code>install</code> command now installs only the
+packages and commands listed directly on the command line.
+For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code>
+installs the gofmt program but not any of the packages on which it depends.
+The new build cache makes future commands still run as quickly as if the
+dependencies had been installed.
+To force the installation of dependencies, use the new
+<code>go</code> <code>install</code> <code>-i</code> flag.
+Installing dependency packages should not be necessary in general,
+and the very concept of installed packages may disappear in a future release.
+</p>
+
+<p>
+Many details of the <code>go</code>&nbsp;<code>build</code> implementation have changed to support these improvements.
+One new requirement implied by these changes is that
+binary-only packages must now declare accurate import blocks in their
+stub source code, so that those imports can be made available when
+linking a program using the binary-only package.
+For more details, see <a href="/cmd/go/#hdr-File_types"><code>go</code> <code>help</code> <code>filetype</code></a>.
+</p>
+
+<h3 id="test">Test</h3>
+
+<p>
+The <code>go</code>&nbsp;<code>test</code> command now caches test results:
+if the test executable and command line match a previous run
+and the files and environment variables consulted by that run
+have not changed either, <code>go</code> <code>test</code> will print
+the previous test output, replacing the elapsed time with the string “(cached).”
+Test caching applies only to successful test results;
+only to <code>go</code> <code>test</code>
+commands with an explicit list of packages; and
+only to command lines using a subset of the
+<code>-cpu</code>, <code>-list</code>, <code>-parallel</code>,
+<code>-run</code>, <code>-short</code>, and <code>-v</code> test flags.
+The idiomatic way to bypass test caching is to use <code>-count=1</code>.
+</p>
+
+<p id="test-vet">
+The <code>go</code>&nbsp;<code>test</code> command now automatically runs
+<code>go</code> <code>vet</code> on the package being tested,
+to identify significant problems before running the test.
+Any such problems are treated like build errors and prevent execution of the test.
+Only a high-confidence subset of the available <code>go</code> <code>vet</code>
+checks are enabled for this automatic check.
+To disable the running of <code>go</code> <code>vet</code>, use
+<code>go</code> <code>test</code> <code>-vet=off</code>.
+</p>
+
+<p>
+The <code>go</code> <code>test</code> <code>-coverpkg</code> flag now
+interprets its argument as a comma-separated list of patterns to match against
+the dependencies of each test, not as a list of packages to load anew.
+For example, <code>go</code> <code>test</code> <code>-coverpkg=all</code>
+is now a meaningful way to run a test with coverage enabled for the test package
+and all its dependencies.
+Also, the <code>go</code> <code>test</code> <code>-coverprofile</code> option is now
+supported when running multiple tests.
+</p>
+
+<p>
+In case of failure due to timeout, tests are now more likely to write their profiles before exiting.
+</p>
+
+<p>
+The <code>go</code>&nbsp;<code>test</code> command now always
+merges the standard output and standard error from a given test binary execution
+and writes both to <code>go</code> <code>test</code>'s standard output.
+In past releases, <code>go</code> <code>test</code> only applied this
+merging most of the time.
+</p>
+
+<p>
+The <code>go</code>&nbsp;<code>test</code> <code>-v</code> output
+now includes <code>PAUSE</code> and <code>CONT</code> status update
+lines to mark when <a href="/pkg/testing/#T.Parallel">parallel tests</a> pause and continue.
+</p>
+
+<p>
+The new <code>go</code> <code>test</code> <code>-failfast</code> flag
+disables running additional tests after any test fails.
+Note that tests running in parallel with the failing test are allowed to complete.
+</p>
+
+<p>
+Finally, the new <code>go</code> <code>test</code> <code>-json</code> flag
+filters test output through the new command
+<code>go</code> <code>tool</code> <code>test2json</code>
+to produce a machine-readable JSON-formatted description of test execution.
+This allows the creation of rich presentations of test execution
+in IDEs and other tools.
+</p>
+
+
+<p>
+For more details about all these changes,
+see <a href="/cmd/go/#hdr-Test_packages"><code>go</code> <code>help</code> <code>test</code></a>
+and the <a href="/cmd/test2json/">test2json documentation</a>.
+</p>
+
+<h3 id="cgo">Cgo</h3>
+
+<p>
+Options specified by cgo using <code>#cgo CFLAGS</code> and the like
+are now checked against a whitelist of permitted options.
+This closes a security hole in which a downloaded package uses
+compiler options like
+<span style="white-space: nowrap"><code>-fplugin</code></span>
+to run arbitrary code on the machine where it is being built.
+This can cause a build error such as <code>invalid flag in #cgo CFLAGS</code>.
+For more background, and how to handle this error, see
+<a href="https://golang.org/s/invalidflag">https://golang.org/s/invalidflag</a>.
+</p>
+
+<p>
+Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>” using a Go type alias,
+so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably.
+It also now supports the use of niladic function-like macros.
+Also, the documentation has been updated to clarify that
+Go structs and Go arrays are not supported in the type signatures of cgo-exported functions.
+</p>
+
+<p>
+Cgo now supports direct access to Go string values from C.
+Functions in the C preamble may use the type <code>_GoString_</code>
+to accept a Go string as an argument.
+C code may call <code>_GoStringLen</code> and <code>_GoStringPtr</code>
+for direct access to the contents of the string.
+A value of type <code>_GoString_</code>
+may be passed in a call to an exported Go function that takes an argument of Go type <code>string</code>.
+</p>
+
+<p>
+During toolchain bootstrap, the environment variables <code>CC</code> and <code>CC_FOR_TARGET</code> specify
+the default C compiler that the resulting toolchain will use for host and target builds, respectively.
+However, if the toolchain will be used with multiple targets, it may be necessary to specify a different C compiler for each
+(for example, a different compiler for <code>darwin/arm64</code> versus <code>linux/ppc64le</code>).
+The new set of environment variables <code>CC_FOR_<i>goos</i>_<i>goarch</i></code>
+allows specifying a different default C compiler for each target.
+Note that these variables only apply during toolchain bootstrap,
+to set the defaults used by the resulting toolchain.
+Later <code>go</code> <code>build</code> commands use the <code>CC</code> environment
+variable or else the built-in default.
+</p>
+
+<p>
+Cgo now translates some C types that would normally map to a pointer
+type in Go, to a <code>uintptr</code> instead. These types include
+the <code>CFTypeRef</code> hierarchy in Darwin's CoreFoundation
+framework and the <code>jobject</code> hierarchy in Java's JNI
+interface.
+</p>
+
+<p>
+These types must be <code>uintptr</code> on the Go side because they
+would otherwise confuse the Go garbage collector; they are sometimes
+not really pointers but data structures encoded in a pointer-sized integer.
+Pointers to Go memory must not be stored in these <code>uintptr</code> values.
+</p>
+
+<p>
+Because of this change, values of the affected types need to be
+zero-initialized with the constant <code>0</code> instead of the
+constant <code>nil</code>. Go 1.10 provides <code>gofix</code>
+modules to help with that rewrite:
+</p>
+
+<pre>
+go tool fix -r cftype &lt;pkg&gt;
+go tool fix -r jni &lt;pkg&gt;
+</pre>
+
+<p>
+For more details, see the <a href="/cmd/cgo/">cgo documentation</a>.
+</p>
+
+<h3 id="doc">Doc</h3>
+
+<p>
+The <code>go</code>&nbsp;<code>doc</code> tool now adds functions returning slices of <code>T</code> or <code>*T</code>
+to the display of type <code>T</code>, similar to the existing behavior for functions returning single <code>T</code> or <code>*T</code> results.
+For example:
+</p>
+
+<pre>
+$ go doc mail.Address
+package mail // import "net/mail"
+
+type Address struct {
+	Name    string
+	Address string
+}
+    Address represents a single mail address.
+
+func ParseAddress(address string) (*Address, error)
+func ParseAddressList(list string) ([]*Address, error)
+func (a *Address) String() string
+$
+</pre>
+
+<p>
+Previously, <code>ParseAddressList</code> was only shown in the package overview (<code>go</code> <code>doc</code> <code>mail</code>).
+</p>
+
+<h3 id="fix">Fix</h3>
+
+<p>
+The <code>go</code>&nbsp;<code>fix</code> tool now replaces imports of <code>"golang.org/x/net/context"</code>
+with <code>"context"</code>.
+(Forwarding aliases in the former make it completely equivalent to the latter when using Go 1.9 or later.)
+</p>
+
+<h3 id="get">Get</h3>
+
+<p>
+The <code>go</code>&nbsp;<code>get</code> command now supports Fossil source code repositories.
+</p>
+
+<h3 id="pprof">Pprof</h3>
+
+<p>
+The blocking and mutex profiles produced by the <code>runtime/pprof</code> package
+now include symbol information, so they can be viewed
+in <code>go</code> <code>tool</code> <code>pprof</code>
+without the binary that produced the profile.
+(All other profile types were changed to include symbol information in Go 1.9.)
+</p>
+
+<p>
+The <a href="/cmd/pprof/"><code>go</code>&nbsp;<code>tool</code>&nbsp;<code>pprof</code></a>
+profile visualizer has been updated to git version 9e20b5b (2017-11-08)
+from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
+which includes an updated web interface.
+</p>
+
+<h3 id="vet">Vet</h3>
+
+<p>
+The <a href="/cmd/vet/"><code>go</code>&nbsp;<code>vet</code></a> command now always has access to
+complete, up-to-date type information when checking packages, even for packages using cgo or vendored imports.
+The reports should be more accurate as a result.
+Note that only <code>go</code>&nbsp;<code>vet</code> has access to this information;
+the more low-level <code>go</code>&nbsp;<code>tool</code>&nbsp;<code>vet</code> does not
+and should be avoided except when working on <code>vet</code> itself.
+(As of Go 1.9, <code>go</code>&nbsp;<code>vet</code> provides access to all the same flags as
+<code>go</code>&nbsp;<code>tool</code>&nbsp;<code>vet</code>.)
+</p>
+
+<h3 id="diag">Diagnostics</h3>
+
+<p>
+This release includes a new <a href="/doc/diagnostics.html">overview of available Go program diagnostic tools</a>.
+</p>
+
+<h3 id="gofmt">Gofmt</h3>
+
+<p>
+Two minor details of the default formatting of Go source code have changed.
+First, certain complex three-index slice expressions previously formatted like
+<code>x[i+1</code>&nbsp;<code>:</code>&nbsp;<code>j:k]</code> and now
+format with more consistent spacing: <code>x[i+1</code>&nbsp;<code>:</code>&nbsp;<code>j</code>&nbsp;<code>:</code>&nbsp;<code>k]</code>.
+Second, single-method interface literals written on a single line,
+which are sometimes used in type assertions,
+are no longer split onto multiple lines.
+</p>
+
+<p>
+Note that these kinds of minor updates to gofmt are expected from time to time.
+In general, we recommend against building systems that check that source code
+matches the output of a specific version of gofmt.
+For example, a continuous integration test that fails if any code already checked into
+a repository is not “properly formatted” is inherently fragile and not recommended.
+</p>
+
+<p>
+If multiple programs must agree about which version of gofmt is used to format a source file,
+we recommend that they do this by arranging to invoke the same gofmt binary.
+For example, in the Go open source repository, our Git pre-commit hook is written in Go
+and could import <code>go/format</code> directly, but instead it invokes the <code>gofmt</code>
+binary found in the current path, so that the pre-commit hook need not be recompiled
+each time <code>gofmt</code> changes.
+</p>
+
+<h3 id="compiler">Compiler Toolchain</h3>
+
+<p>
+The compiler includes many improvements to the performance of generated code,
+spread fairly evenly across the supported architectures.
+</p>
+
+<p>
+The DWARF debug information recorded in binaries has been improved in a few ways:
+constant values are now recorded;
+line number information is more accurate, making source-level stepping through a program work better;
+and each package is now presented as its own DWARF compilation unit.
+</p>
+
+<p>
+The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a>
+have been ported to more systems.
+Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>;
+<code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems;
+and <code>plugin</code> now works on <code>linux/ppc64le</code> and <code>darwin/amd64</code>.
+</p>
+
+<p>
+The <code>linux/ppc64le</code> port now requires the use of external linking
+with any programs that use cgo, even uses by the standard library.
+</p>
+
+<h3 id="asm">Assembler</h3>
+
+<p>
+For the ARM 32-bit port, the assembler now supports the instructions
+<code><small>BFC</small></code>,
+<code><small>BFI</small></code>,
+<code><small>BFX</small></code>,
+<code><small>BFXU</small></code>,
+<code><small>FMULAD</small></code>,
+<code><small>FMULAF</small></code>,
+<code><small>FMULSD</small></code>,
+<code><small>FMULSF</small></code>,
+<code><small>FNMULAD</small></code>,
+<code><small>FNMULAF</small></code>,
+<code><small>FNMULSD</small></code>,
+<code><small>FNMULSF</small></code>,
+<code><small>MULAD</small></code>,
+<code><small>MULAF</small></code>,
+<code><small>MULSD</small></code>,
+<code><small>MULSF</small></code>,
+<code><small>NMULAD</small></code>,
+<code><small>NMULAF</small></code>,
+<code><small>NMULD</small></code>,
+<code><small>NMULF</small></code>,
+<code><small>NMULSD</small></code>,
+<code><small>NMULSF</small></code>,
+<code><small>XTAB</small></code>,
+<code><small>XTABU</small></code>,
+<code><small>XTAH</small></code>,
+and
+<code><small>XTAHU</small></code>.
+</p>
+
+<p>
+For the ARM 64-bit port, the assembler now supports the
+<code><small>VADD</small></code>,
+<code><small>VADDP</small></code>,
+<code><small>VADDV</small></code>,
+<code><small>VAND</small></code>,
+<code><small>VCMEQ</small></code>,
+<code><small>VDUP</small></code>,
+<code><small>VEOR</small></code>,
+<code><small>VLD1</small></code>,
+<code><small>VMOV</small></code>,
+<code><small>VMOVI</small></code>,
+<code><small>VMOVS</small></code>,
+<code><small>VORR</small></code>,
+<code><small>VREV32</small></code>,
+and
+<code><small>VST1</small></code>
+instructions.
+</p>
+
+<p>
+For the PowerPC 64-bit port, the assembler now supports the POWER9 instructions
+<code><small>ADDEX</small></code>,
+<code><small>CMPEQB</small></code>,
+<code><small>COPY</small></code>,
+<code><small>DARN</small></code>,
+<code><small>LDMX</small></code>,
+<code><small>MADDHD</small></code>,
+<code><small>MADDHDU</small></code>,
+<code><small>MADDLD</small></code>,
+<code><small>MFVSRLD</small></code>,
+<code><small>MTVSRDD</small></code>,
+<code><small>MTVSRWS</small></code>,
+<code><small>PASTECC</small></code>,
+<code><small>VCMPNEZB</small></code>,
+<code><small>VCMPNEZBCC</small></code>,
+and
+<code><small>VMSUMUDM</small></code>.
+</p>
+
+<p>
+For the S390X port, the assembler now supports the
+<code><small>TMHH</small></code>,
+<code><small>TMHL</small></code>,
+<code><small>TMLH</small></code>,
+and
+<code><small>TMLL</small></code>
+instructions.
+</p>
+
+<p>
+For the X86 64-bit port, the assembler now supports 359 new instructions,
+including the full AVX, AVX2, BMI, BMI2, F16C, FMA3, SSE2, SSE3, SSSE3, SSE4.1, and SSE4.2 extension sets.
+The assembler also no longer implements <code><small>MOVL</small></code>&nbsp;<code><small>$0,</small></code>&nbsp;<code><small>AX</small></code>
+as an <code><small>XORL</small></code> instruction,
+to avoid clearing the condition flags unexpectedly.
+</p>
+
+<h3 id="gccgo">Gccgo</h3>
+
+<p>
+Due to the alignment of Go's semiannual release schedule with GCC's
+annual release schedule,
+GCC release 7 contains the Go 1.8.3 version of gccgo.
+We expect that the next release, GCC 8, will contain the Go 1.10
+version of gccgo.
+</p>
+
+<h2 id="runtime">Runtime</h2>
+
+<p>
+The behavior of nested calls to
+<a href="/pkg/runtime/#LockOSThread"><code>LockOSThread</code></a> and
+<a href="/pkg/runtime/#UnlockOSThread"><code>UnlockOSThread</code></a>
+has changed.
+These functions control whether a goroutine is locked to a specific operating system thread,
+so that the goroutine only runs on that thread, and the thread only runs that goroutine.
+Previously, calling <code>LockOSThread</code> more than once in a row
+was equivalent to calling it once, and a single <code>UnlockOSThread</code>
+always unlocked the thread.
+Now, the calls nest: if <code>LockOSThread</code> is called multiple times,
+<code>UnlockOSThread</code> must be called the same number of times
+in order to unlock the thread.
+Existing code that was careful not to nest these calls will remain correct.
+Existing code that incorrectly assumed the calls nested will become correct.
+Most uses of these functions in public Go source code falls into the second category.
+</p>
+
+<p>
+Because one common use of <code>LockOSThread</code> and <code>UnlockOSThread</code>
+is to allow Go code to reliably modify thread-local state (for example, Linux or Plan 9 name spaces),
+the runtime now treats locked threads as unsuitable for reuse or for creating new threads.
+</p>
+
+<p>
+Stack traces no longer include implicit wrapper functions (previously marked <code>&lt;autogenerated&gt;</code>),
+unless a fault or panic happens in the wrapper itself.
+As a result, skip counts passed to functions like <a href="/pkg/runtime/#Caller"><code>Caller</code></a>
+should now always match the structure of the code as written, rather than depending on
+optimization decisions and implementation details.
+</p>
+
+<p>
+The garbage collector has been modified to reduce its impact on allocation latency.
+It now uses a smaller fraction of the overall CPU when running, but it may run more of the time.
+The total CPU consumed by the garbage collector has not changed significantly.
+</p>
+
+<p>
+The <a href="/pkg/runtime/#GOROOT"><code>GOROOT</code></a> function
+now defaults (when the <code>$GOROOT</code> environment variable is not set)
+to the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
+at the time the calling program was compiled.
+Previously it used the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
+at the time the toolchain that compiled the calling program was compiled.
+</p>
+
+<p>
+There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
+(In Go 1.9 the limit was 1024.)
+</p>
+
+<h2 id="performance">Performance</h2>
+
+<p>
+As always, the changes are so general and varied that precise
+statements about performance are difficult to make.  Most programs
+should run a bit faster, due to speedups in the garbage collector,
+better generated code, and optimizations in the core library.
+</p>
+
+<h2 id="gc">Garbage Collector</h2>
+
+<p>
+Many applications should experience significantly lower allocation latency and overall performance overhead when the garbage collector is active.
+</p>
+
+<h2 id="library">Core library</h2>
+
+<p>
+All of the changes to the standard library are minor.
+The changes in <a href="#bytes">bytes</a>
+and <a href="#net/url">net/url</a> are the most likely to require updating of existing programs.
+</p>
+
+<h3 id="minor_library_changes">Minor changes to the library</h3>
+
+<p>
+As always, there are various minor changes and updates to the library,
+made with the Go 1 <a href="/doc/go1compat">promise of compatibility</a>
+in mind.
+</p>
+
+<dl id="archive/tar"><dt><a href="/pkg/archive/tar/">archive/tar</a></dt>
+<dd>
+<p>
+In general, the handling of special header formats is significantly improved and expanded.
+</p>
+<p>
+<a href="/pkg/archive/tar/#FileInfoHeader"><code>FileInfoHeader</code></a> has always
+recorded the Unix UID and GID numbers from its <a href="/pkg/os/#FileInfo"><code>os.FileInfo</code></a> argument
+(specifically, from the system-dependent information returned by the <code>FileInfo</code>'s <code>Sys</code> method)
+in the returned <a href="/pkg/archive/tar/#Header"><code>Header</code></a>.
+Now it also records the user and group names corresponding to those IDs,
+as well as the major and minor device numbers for device files.
+</p>
+<p>
+The new <a href="/pkg/archive/tar/#Header"><code>Header.Format</code></a> field
+of type <a href="/pkg/archive/tar/#Format"><code>Format</code></a>
+controls which tar header format the <a href="/pkg/archive/tar/#Writer"><code>Writer</code></a> uses.
+The default, as before, is to select the most widely-supported header type
+that can encode the fields needed by the header (USTAR if possible, or else PAX if possible, or else GNU).
+The <a href="/pkg/archive/tar/#Reader"><code>Reader</code></a> sets <code>Header.Format</code> for each header it reads.
+</p>
+<p>
+<code>Reader</code> and the <code>Writer</code> now support arbitrary PAX records,
+using the new <a href="/pkg/archive/tar/#Header"><code>Header.PAXRecords</code></a> field,
+a generalization of the existing <code>Xattrs</code> field.
+</p>
+<p>
+The <code>Reader</code> no longer insists that the file name or link name in GNU headers
+be valid UTF-8.
+</p>
+<p>
+When writing PAX- or GNU-format headers, the <code>Writer</code> now includes
+the <code>Header.AccessTime</code> and <code>Header.ChangeTime</code> fields (if set).
+When writing PAX-format headers, the times include sub-second precision.
+</p>
+</dl>
+
+<dl id="archive/zip"><dt><a href="/pkg/archive/zip/">archive/zip</a></dt>
+<dd>
+<p>
+Go 1.10 adds more complete support for times and character set encodings in ZIP archives.
+</p>
+<p>
+The original ZIP format used the standard MS-DOS encoding of year, month, day, hour, minute, and second into fields in two 16-bit values.
+That encoding cannot represent time zones or odd seconds, so multiple extensions have been
+introduced to allow richer encodings.
+In Go 1.10, the <a href="/pkg/archive/zip/#Reader"><code>Reader</code></a> and <a href="/pkg/archive/zip/#Writer"><code>Writer</code></a>
+now support the widely-understood Info-Zip extension that encodes the time separately in the 32-bit Unix “seconds since epoch” form.
+The <a href="/pkg/archive/zip/#FileHeader"><code>FileHeader</code></a>'s new <code>Modified</code> field of type <a href="/pkg/time/#Time"><code>time.Time</code></a>
+obsoletes the <code>ModifiedTime</code> and <code>ModifiedDate</code> fields, which continue to hold the MS-DOS encoding.
+The <code>Reader</code> and <code>Writer</code> now adopt the common
+convention that a ZIP archive storing a time zone-independent Unix time
+also stores the local time in the MS-DOS field,
+so that the time zone offset can be inferred.
+For compatibility, the <a href="/pkg/archive/zip/#FileHeader.ModTime"><code>ModTime</code></a> and
+<a href="/pkg/archive/zip/#FileHeader.SetModTime"><code>SetModTime</code></a> methods
+behave the same as in earlier releases; new code should use <code>Modified</code> directly.
+</p>
+<p>
+The header for each file in a ZIP archive has a flag bit indicating whether
+the name and comment fields are encoded as UTF-8, as opposed to a system-specific default encoding.
+In Go 1.8 and earlier, the <code>Writer</code> never set the UTF-8 bit.
+In Go 1.9, the <code>Writer</code> changed to set the UTF-8 bit almost always.
+This broke the creation of ZIP archives containing Shift-JIS file names.
+In Go 1.10, the <code>Writer</code> now sets the UTF-8 bit only when
+both the name and the comment field are valid UTF-8 and at least one is non-ASCII.
+Because non-ASCII encodings very rarely look like valid UTF-8, the new
+heuristic should be correct nearly all the time.
+Setting a <code>FileHeader</code>'s new <code>NonUTF8</code> field to true
+disables the heuristic entirely for that file.
+</p>
+<p>
+The <code>Writer</code> also now supports setting the end-of-central-directory record's comment field,
+by calling the <code>Writer</code>'s new <a href="/pkg/archive/zip/#Writer.SetComment"><code>SetComment</code></a> method.
+</p>
+</dl>
+
+<dl id="bufio"><dt><a href="/pkg/bufio/">bufio</a></dt>
+<dd>
+<p>
+The new <a href="/pkg/bufio/#Reader.Size"><code>Reader.Size</code></a>
+and <a href="/pkg/bufio/#Writer.Size"><code>Writer.Size</code></a>
+methods report the <code>Reader</code> or <code>Writer</code>'s underlying buffer size.
+</p>
+</dl>
+
+<dl id="bytes"><dt><a href="/pkg/bytes/">bytes</a></dt>
+<dd>
+<p>
+The
+<a href="/pkg/bytes/#Fields"><code>Fields</code></a>,
+<a href="/pkg/bytes/#FieldsFunc"><code>FieldsFunc</code></a>,
+<a href="/pkg/bytes/#Split"><code>Split</code></a>,
+and
+<a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a>
+functions have always returned subslices of their inputs.
+Go 1.10 changes each returned subslice to have capacity equal to its length,
+so that appending to one cannot overwrite adjacent data in the original input.
+</p>
+</dl>
+
+<dl id="crypto/cipher"><dt><a href="/pkg/crypto/cipher/">crypto/cipher</a></dt>
+<dd>
+<p>
+<a href="/pkg/crypto/cipher/#NewOFB"><code>NewOFB</code></a> now panics if given
+an initialization vector of incorrect length, like the other constructors in the
+package always have.
+(Previously it returned a nil <code>Stream</code> implementation.)
+</p>
+</dl>
+
+<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
+<dd>
+<p>
+The TLS server now advertises support for SHA-512 signatures when using TLS 1.2.
+The server already supported the signatures, but some clients would not select
+them unless explicitly advertised.
+</p>
+</dl>
+
+<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
+<dd>
+<p>
+<a href="/pkg/crypto/x509/#Certificate.Verify"><code>Certificate.Verify</code></a>
+now enforces the name constraints for all
+names contained in the certificate, not just the one name that a client has asked about.
+Extended key usage restrictions are similarly now checked all at once.
+As a result, after a certificate has been validated, now it can be trusted in its entirety.
+It is no longer necessary to revalidate the certificate for each additional name
+or key usage.
+</p>
+
+<p>
+Parsed certificates also now report URI names and IP, email, and URI constraints, using the new
+<a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields
+<code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>,
+<code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>,
+<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>. Certificates with
+invalid values for those fields are now rejected.
+</p>
+
+<p>
+The new <a href="/pkg/crypto/x509/#MarshalPKCS1PublicKey"><code>MarshalPKCS1PublicKey</code></a>
+and <a href="/pkg/crypto/x509/#ParsePKCS1PublicKey"><code>ParsePKCS1PublicKey</code></a>
+functions convert an RSA public key to and from PKCS#1-encoded form.
+</p>
+
+<p>
+The new <a href="/pkg/crypto/x509/#MarshalPKCS8PrivateKey"><code>MarshalPKCS8PrivateKey</code></a>
+function converts a private key to PKCS#8-encoded form.
+(<a href="/pkg/crypto/x509/#ParsePKCS8PrivateKey"><code>ParsePKCS8PrivateKey</code></a>
+has existed since Go 1.)
+</p>
+</dl>
+
+<dl id="crypto/x509/pkix"><dt><a href="/pkg/crypto/x509/pkix/">crypto/x509/pkix</a></dt>
+<dd>
+<p>
+<a href="/pkg/crypto/x509/pkix/#Name"><code>Name</code></a> now implements a
+<a href="/pkg/crypto/x509/pkix/#Name.String"><code>String</code></a> method that
+formats the X.509 distinguished name in the standard RFC 2253 format.
+</p>
+</dl>
+
+<dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt>
+<dd>
+<p>
+Drivers that currently hold on to the destination buffer provided by
+<a href="/pkg/database/sql/driver/#Rows.Next"><code>driver.Rows.Next</code></a> should ensure they no longer
+write to a buffer assigned to the destination array outside of that call.
+Drivers must be careful that underlying buffers are not modified when closing
+<a href="/pkg/database/sql/driver/#Rows"><code>driver.Rows</code></a>.
+</p>
+<p>
+Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for
+their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface
+and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function,
+instead of needing to encode all configuration into a string
+passed to  <a href="/pkg/database/sql/#Open"><code>sql.Open</code></a>.
+</p>
+<p>
+Drivers that want to parse the configuration string only once per <code>sql.DB</code>
+instead of once per <a href="/pkg/database/sql/#Conn"><code>sql.Conn</code></a>,
+or that want access to each <code>sql.Conn</code>'s underlying context,
+can make their <a href="/pkg/database/sql/driver/#Driver"><code>Driver</code></a>
+implementations also implement <a href="/pkg/database/sql/driver/#DriverContext"><code>DriverContext</code></a>'s
+new <code>OpenConnector</code> method.
+</p>
+<p>
+Drivers that implement <a href="/pkg/database/sql/driver/#ExecerContext"><code>ExecerContext</code></a>
+no longer need to implement <a href="/pkg/database/sql/driver/#Execer"><code>Execer</code></a>;
+similarly, drivers that implement <a href="/pkg/database/sql/driver/#QueryerContext"><code>QueryerContext</code></a>
+no longer need to implement <a href="/pkg/database/sql/driver/#Queryer"><code>Queryer</code></a>.
+Previously, even if the context-based interfaces were implemented they were ignored
+unless the non-context-based interfaces were also implemented.
+</p>
+<p>
+To allow drivers to better isolate different clients using a cached driver connection in succession,
+if a <a href="/pkg/database/sql/driver/#Conn"><code>Conn</code></a> implements the new
+<a href="/pkg/database/sql/driver/#SessionResetter"><code>SessionResetter</code></a> interface,
+<code>database/sql</code> will now call <code>ResetSession</code> before
+reusing the <code>Conn</code> for a new client.
+</p>
+</dl>
+
+<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
+<dd>
+<p>
+This release adds 348 new relocation constants divided between the relocation types
+<a href="/pkg/debug/elf/#R_386"><code>R_386</code></a>,
+<a href="/pkg/debug/elf/#R_AARCH64"><code>R_AARCH64</code></a>,
+<a href="/pkg/debug/elf/#R_ARM"><code>R_ARM</code></a>,
+<a href="/pkg/debug/elf/#R_PPC64"><code>R_PPC64</code></a>,
+and
+<a href="/pkg/debug/elf/#R_X86_64"><code>R_X86_64</code></a>.
+</p>
+</dl>
+
+<dl id="debug/macho"><dt><a href="/pkg/debug/macho/">debug/macho</a></dt>
+<dd>
+<p>
+Go 1.10 adds support for reading relocations from Mach-O sections,
+using the <a href="/pkg/debug/macho#Section"><code>Section</code></a> struct's new <code>Relocs</code> field
+and the new <a href="/pkg/debug/macho/#Reloc"><code>Reloc</code></a>,
+<a href="/pkg/debug/macho/#RelocTypeARM"><code>RelocTypeARM</code></a>,
+<a href="/pkg/debug/macho/#RelocTypeARM64"><code>RelocTypeARM64</code></a>,
+<a href="/pkg/debug/macho/#RelocTypeGeneric"><code>RelocTypeGeneric</code></a>,
+and
+<a href="/pkg/debug/macho/#RelocTypeX86_64"><code>RelocTypeX86_64</code></a>
+types and associated constants.
+</p>
+<p>
+Go 1.10 also adds support for the <code>LC_RPATH</code> load command,
+represented by the types
+<a href="/pkg/debug/macho/#RpathCmd"><code>RpathCmd</code></a> and
+<a href="/pkg/debug/macho/#Rpath"><code>Rpath</code></a>,
+and new <a href="/pkg/debug/macho/#pkg-constants">named constants</a>
+for the various flag bits found in headers.
+</p>
+</dl>
+
+<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt>
+<dd>
+<p>
+<a href="/pkg/encoding/asn1/#Marshal"><code>Marshal</code></a> now correctly encodes
+strings containing asterisks as type UTF8String instead of PrintableString,
+unless the string is in a struct field with a tag forcing the use of PrintableString.
+<code>Marshal</code> also now respects struct tags containing <code>application</code> directives.
+</p>
+<p>
+The new <a href="/pkg/encoding/asn1/#MarshalWithParams"><code>MarshalWithParams</code></a>
+function marshals its argument as if the additional params were its associated
+struct field tag.
+</p>
+<p>
+<a href="/pkg/encoding/asn1/#Unmarshal"><code>Unmarshal</code></a> now respects
+struct field tags using the <code>explicit</code> and <code>tag</code>
+directives.
+</p>
+<p>
+Both <code>Marshal</code> and <code>Unmarshal</code> now support a new struct field tag
+<code>numeric</code>, indicating an ASN.1 NumericString.
+</p>
+</dl>
+
+<dl id="encoding/csv"><dt><a href="/pkg/encoding/csv/">encoding/csv</a></dt>
+<dd>
+<p>
+<a href="/pkg/encoding/csv/#Reader"><code>Reader</code></a> now disallows the use of
+nonsensical <code>Comma</code> and <code>Comment</code> settings,
+such as NUL, carriage return, newline, invalid runes, and the Unicode replacement character,
+or setting <code>Comma</code> and <code>Comment</code> equal to each other.
+</p>
+<p>
+In the case of a syntax error in a CSV record that spans multiple input lines, <code>Reader</code>
+now reports the line on which the record started in the <a href="/pkg/encoding/csv/#ParseError"><code>ParseError</code></a>'s new <code>StartLine</code> field.
+</p>
+</dl>
+
+<dl id="encoding/hex"><dt><a href="/pkg/encoding/hex/">encoding/hex</a></dt>
+<dd>
+<p>
+The new functions
+<a href="/pkg/encoding/hex/#NewEncoder"><code>NewEncoder</code></a>
+and
+<a href="/pkg/encoding/hex/#NewDecoder"><code>NewDecoder</code></a>
+provide streaming conversions to and from hexadecimal,
+analogous to equivalent functions already in
+<a href="/pkg/encoding/base32/">encoding/base32</a>
+and
+<a href="/pkg/encoding/base64/">encoding/base64</a>.
+</p>
+
+<p>
+When the functions
+<a href="/pkg/encoding/hex/#Decode"><code>Decode</code></a>
+and
+<a href="/pkg/encoding/hex/#DecodeString"><code>DecodeString</code></a>
+encounter malformed input,
+they now return the number of bytes already converted
+along with the error.
+Previously they always returned a count of 0 with any error.
+</p>
+</dl>
+
+<dl id="encoding/json"><dt><a href="/pkg/encoding/json/">encoding/json</a></dt>
+<dd>
+<p>
+The <a href="/pkg/encoding/json/#Decoder"><code>Decoder</code></a>
+adds a new method
+<a href="/pkg/encoding/json/#Decoder.DisallowUnknownFields"><code>DisallowUnknownFields</code></a>
+that causes it to report inputs with unknown JSON fields as a decoding error.
+(The default behavior has always been to discard unknown fields.)
+</p>
+
+<p>
+As a result of <a href="#reflect">fixing a reflect bug</a>,
+<a href="/pkg/encoding/json/#Unmarshal"><code>Unmarshal</code></a>
+can no longer decode into fields inside
+embedded pointers to unexported struct types,
+because it cannot initialize the unexported embedded pointer
+to point at fresh storage.
+<code>Unmarshal</code> now returns an error in this case.
+</p>
+</dl>
+
+<dl id="encoding/pem"><dt><a href="/pkg/encoding/pem/">encoding/pem</a></dt>
+<dd>
+<p>
+<a href="/pkg/encoding/pem/#Encode"><code>Encode</code></a>
+and
+<a href="/pkg/encoding/pem/#EncodeToMemory"><code>EncodeToMemory</code></a>
+no longer generate partial output when presented with a
+block that is impossible to encode as PEM data.
+</p>
+</dl>
+
+<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
+<dd>
+<p>
+The new function
+<a href="/pkg/encoding/xml/#NewTokenDecoder"><code>NewTokenDecoder</code></a>
+is like
+<a href="/pkg/encoding/xml/#NewDecoder"><code>NewDecoder</code></a>
+but creates a decoder reading from a <a href="/pkg/encoding/xml/#TokenReader"><code>TokenReader</code></a>
+instead of an XML-formatted byte stream.
+This is meant to enable the construction of XML stream transformers in client libraries.
+</p>
+</dl>
+
+<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
+<dd>
+<p>
+The default
+<a href="/pkg/flag/#Usage"><code>Usage</code></a> function now prints
+its first line of output to
+<code>CommandLine.Output()</code>
+instead of assuming <code>os.Stderr</code>,
+so that the usage message is properly redirected for
+clients using <code>CommandLine.SetOutput</code>.
+</p>
+<p>
+<a href="/pkg/flag/#PrintDefaults"><code>PrintDefaults</code></a> now
+adds appropriate indentation after newlines in flag usage strings,
+so that multi-line usage strings display nicely.
+</p>
+<p>
+<a href="/pkg/flag/#FlagSet"><code>FlagSet</code></a> adds new methods
+<a href="/pkg/flag/#FlagSet.ErrorHandling"><code>ErrorHandling</code></a>,
+<a href="/pkg/flag/#FlagSet.Name"><code>Name</code></a>,
+and
+<a href="/pkg/flag/#FlagSet.Output"><code>Output</code></a>,
+to retrieve the settings passed to
+<a href="/pkg/flag/#NewFlagSet"><code>NewFlagSet</code></a>
+and
+<a href="/pkg/flag/#FlagSet.SetOutput"><code>FlagSet.SetOutput</code></a>.
+</p>
+</dl>
+
+<dl id="go/doc"><dt><a href="/pkg/go/doc/">go/doc</a></dt>
+<dd>
+<p>
+To support the <a href="#doc">doc change</a> described above,
+functions returning slices of <code>T</code>, <code>*T</code>, <code>**T</code>, and so on
+are now reported in <code>T</code>'s <a href="/pkg/go/doc/#Type"><code>Type</code></a>'s <code>Funcs</code> list,
+instead of in the <a href="/pkg/go/doc/#Package"><code>Package</code></a>'s <code>Funcs</code> list.
+</p>
+</dl>
+
+<dl id="go/importer"><dt><a href="/pkg/go/importer/">go/importer</a></dt>
+<dd>
+<p>
+The <a href="/pkg/go/importer/#For"><code>For</code></a> function now accepts a non-nil lookup argument.
+</p>
+</dl>
+
+<dl id="go/printer"><dt><a href="/pkg/go/printer/">go/printer</a></dt>
+<dd>
+<p>
+The changes to the default formatting of Go source code
+discussed in the <a href="#gofmt">gofmt section</a> above
+are implemented in the <a href="/pkg/go/printer/">go/printer</a> package
+and also affect the output of the higher-level <a href="/pkg/go/format/">go/format</a> package.
+</p>
+</dl>
+
+<dl id="hash"><dt><a href="/pkg/hash/">hash</a></dt>
+<dd>
+<p>
+Implementations of the <a href="/pkg/hash/#Hash"><code>Hash</code></a> interface are now
+encouraged to implement <a href="/pkg/encoding/#BinaryMarshaler"><code>encoding.BinaryMarshaler</code></a>
+and <a href="/pkg/encoding/#BinaryUnmarshaler"><code>encoding.BinaryUnmarshaler</code></a>
+to allow saving and recreating their internal state,
+and all implementations in the standard library
+(<a href="/pkg/hash/crc32/">hash/crc32</a>, <a href="/pkg/crypto/sha256/">crypto/sha256</a>, and so on)
+now implement those interfaces.
+</p>
+</dl>
+
+<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
+<dd>
+<p>
+The new <a href="/pkg/html/template#Srcset"><code>Srcset</code></a> content
+type allows for proper handling of values within the
+<a href="https://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset"><code>srcset</code></a>
+attribute of <code>img</code> tags.
+</p>
+</dl>
+
+<dl id="math/big"><dt><a href="/pkg/math/big/">math/big</a></dt>
+<dd>
+<p>
+<a href="/pkg/math/big/#Int"><code>Int</code></a> now supports conversions to and from bases 2 through 62
+in its <a href="/pkg/math/big/#Int.SetString"><code>SetString</code></a> and <a href="/pkg/math/big/#Text"><code>Text</code></a> methods.
+(Previously it only allowed bases 2 through 36.)
+The value of the constant <code>MaxBase</code> has been updated.
+</p>
+<p>
+<a href="/pkg/math/big/#Int"><code>Int</code></a> adds a new
+<a href="/pkg/math/big/#CmpAbs"><code>CmpAbs</code></a> method
+that is like <a href="/pkg/math/big/#Cmp"><code>Cmp</code></a> but
+compares only the absolute values (not the signs) of its arguments.
+</p>
+<p>
+<a href="/pkg/math/big/#Float"><code>Float</code></a> adds a new
+<a href="/pkg/math/big/#Float.Sqrt"><code>Sqrt</code></a> method to
+compute square roots.
+</p>
+</dl>
+
+<dl id="math/cmplx"><dt><a href="/pkg/math/cmplx/">math/cmplx</a></dt>
+<dd>
+<p>
+Branch cuts and other boundary cases in
+<a href="/pkg/math/cmplx/#Asin"><code>Asin</code></a>,
+<a href="/pkg/math/cmplx/#Asinh"><code>Asinh</code></a>,
+<a href="/pkg/math/cmplx/#Atan"><code>Atan</code></a>,
+and
+<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt</code></a>
+have been corrected to match the definitions used in the C99 standard.
+</p>
+</dl>
+
+<dl id="math/rand"><dt><a href="/pkg/math/rand/">math/rand</a></dt>
+<dd>
+<p>
+The new <a href="/pkg/math/rand/#Shuffle"><code>Shuffle</code></a> function and corresponding
+<a href="/pkg/math/rand/#Rand.Shuffle"><code>Rand.Shuffle</code></a> method
+shuffle an input sequence.
+</p>
+</dl>
+
+<dl id="math"><dt><a href="/pkg/math/">math</a></dt>
+<dd>
+<p>
+The new functions
+<a href="/pkg/math/#Round"><code>Round</code></a>
+and
+<a href="/pkg/math/#RoundToEven"><code>RoundToEven</code></a>
+round their arguments to the nearest floating-point integer;
+<code>Round</code> rounds a half-integer to its larger integer neighbor (away from zero)
+while <code>RoundToEven</code> rounds a half-integer to its even integer neighbor.
+</p>
+
+<p>
+The new functions
+<a href="/pkg/math/#Erfinv"><code>Erfinv</code></a>
+and
+<a href="/pkg/math/#Erfcinv"><code>Erfcinv</code></a>
+compute the inverse error function and the
+inverse complementary error function.
+</p>
+</dl>
+
+<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
+<dd>
+<p>
+<a href="/pkg/mime/multipart/#Reader"><code>Reader</code></a>
+now accepts parts with empty filename attributes.
+</p>
+</dl>
+
+<dl id="mime"><dt><a href="/pkg/mime/">mime</a></dt>
+<dd>
+<p>
+<a href="/pkg/mime/#ParseMediaType"><code>ParseMediaType</code></a> now discards
+invalid attribute values; previously it returned those values as empty strings.
+</p>
+</dl>
+
+<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
+<dd>
+<p>
+The <a href="/pkg/net/#Conn"><code>Conn</code></a> and
+<a href="/pkg/net/#Conn"><code>Listener</code></a> implementations
+in this package now guarantee that when <code>Close</code> returns,
+the underlying file descriptor has been closed.
+(In earlier releases, if the <code>Close</code> stopped pending I/O
+in other goroutines, the closing of the file descriptor could happen in one of those
+goroutines shortly after <code>Close</code> returned.)
+</p>
+
+<p>
+<a href="/pkg/net/#TCPListener"><code>TCPListener</code></a> and
+<a href="/pkg/net/#UnixListener"><code>UnixListener</code></a>
+now implement
+<a href="/pkg/syscall/#Conn"><code>syscall.Conn</code></a>,
+to allow setting options on the underlying file descriptor
+using <a href="/pkg/syscall/#RawConn"><code>syscall.RawConn.Control</code></a>.
+</p>
+
+<p>
+The <code>Conn</code> implementations returned by <a href="/pkg/net/#Pipe"><code>Pipe</code></a>
+now support setting read and write deadlines.
+</p>
+
+<p>
+The <a href="/pkg/net/#IPConn.ReadMsgIP"><code>IPConn.ReadMsgIP</code></a>,
+<a href="/pkg/net/#IPConn.WriteMsgIP"><code>IPConn.WriteMsgIP</code></a>,
+<a href="/pkg/net/#UDPConn.ReadMsgUDP"><code>UDPConn.ReadMsgUDP</code></a>,
+and
+<a href="/pkg/net/#UDPConn.WriteMsgUDP"><code>UDPConn.WriteMsgUDP</code></a>,
+methods are now implemented on Windows.
+</p>
+</dl>
+
+<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
+<dd>
+<p>
+On the client side, an HTTP proxy (most commonly configured by
+<a href="/pkg/net/http/#ProxyFromEnvironment"><code>ProxyFromEnvironment</code></a>)
+can now be specified as an <code>https://</code> URL,
+meaning that the client connects to the proxy over HTTPS before issuing a standard, proxied HTTP request.
+(Previously, HTTP proxy URLs were required to begin with <code>http://</code> or <code>socks5://</code>.)
+</p>
+<p>
+On the server side, <a href="/pkg/net/http/#FileServer"><code>FileServer</code></a> and its single-file equivalent <a href="/pkg/net/http/#ServeFile"><code>ServeFile</code></a>
+now apply <code>If-Range</code> checks to <code>HEAD</code> requests.
+<code>FileServer</code> also now reports directory read failures to the <a href="/pkg/net/http/#Server"><code>Server</code></a>'s <code>ErrorLog</code>.
+The content-serving handlers also now omit the <code>Content-Type</code> header when serving zero-length content.
+</p>
+<p>
+<a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter</code></a>'s <code>WriteHeader</code> method now panics
+if passed an invalid (non-3-digit) status code.
+</p>
+<p>
+<!-- CL 46631 -->
+The <code>Server</code> will no longer add an implicit Content-Type when a <code>Handler</code> does not write any output.
+</p>
+<p>
+<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
+</p>
+</dl>
+
+<dl id="net/mail"><dt><a href="/pkg/net/mail/">net/mail</a></dt>
+<dd>
+<p>
+<a href="/pkg/net/mail/#ParseAddress"><code>ParseAddress</code></a> and
+<a href="/pkg/net/mail/#ParseAddressList"><code>ParseAddressList</code></a>
+now support a variety of obsolete address formats.
+</p>
+</dl>
+
+<dl id="net/smtp"><dt><a href="/pkg/net/smtp/">net/smtp</a></dt>
+<dd>
+<p>
+The <a href="/pkg/net/smtp/#Client"><code>Client</code></a> adds a new
+<a href="/pkg/net/smtp/#Client.Noop"><code>Noop</code></a> method,
+to test whether the server is still responding.
+It also now defends against possible SMTP injection in the inputs
+to the <a href="/pkg/net/smtp/#Client.Hello"><code>Hello</code></a>
+and <a href="/pkg/net/smtp/#Client.Verify"><code>Verify</code></a> methods.
+</p>
+</dl>
+
+<dl id="net/textproto"><dt><a href="/pkg/net/textproto/">net/textproto</a></dt>
+<dd>
+<p>
+<a href="/pkg/net/textproto/#ReadMIMEHeader"><code>ReadMIMEHeader</code></a>
+now rejects any header that begins with a continuation (indented) header line.
+Previously a header with an indented first line was treated as if the first line
+were not indented.
+</p>
+</dl>
+
+<dl id="net/url"><dt><a href="/pkg/net/url/">net/url</a></dt>
+<dd>
+<p>
+<a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a>
+now preserves multiple leading slashes in the target URL.
+Previously it rewrote multiple leading slashes to a single slash,
+which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a>
+following certain redirects incorrectly.
+</p>
+<p>
+For example, this code's output has changed:
+</p>
+<pre>
+base, _ := url.Parse("http://host//path//to/page1")
+target, _ := url.Parse("page2")
+fmt.Println(base.ResolveReference(target))
+</pre>
+<p>
+Note the doubled slashes around <code>path</code>.
+In Go 1.9 and earlier, the resolved URL was <code>http://host/path//to/page2</code>:
+the doubled slash before <code>path</code> was incorrectly rewritten
+to a single slash, while the doubled slash after <code>path</code> was
+correctly preserved.
+Go 1.10 preserves both doubled slashes, resolving to <code>http://host//path//to/page2</code>
+as required by <a href="https://tools.ietf.org/html/rfc3986#section-5.2">RFC 3986</a>.
+</p>
+
+<p>This change may break existing buggy programs that unintentionally
+construct a base URL with a leading doubled slash in the path and inadvertently
+depend on <code>ResolveReference</code> to correct that mistake.
+For example, this can happen if code adds a host prefix
+like <code>http://host/</code> to a path like <code>/my/api</code>,
+resulting in a URL with a doubled slash: <code>http://host//my/api</code>.
+</p>
+
+<p>
+<a href="/pkg/net/url/#UserInfo"><code>UserInfo</code></a>'s methods
+now treat a nil receiver as equivalent to a pointer to a zero <code>UserInfo</code>.
+Previously, they panicked.
+</p>
+</dl>
+
+<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
+<dd>
+<p>
+<a href="/pkg/os/#File"><code>File</code></a> adds new methods
+<a href="/pkg/os/#File.SetDeadline"><code>SetDeadline</code></a>,
+<a href="/pkg/os/#File.SetReadDeadline"><code>SetReadDeadline</code></a>,
+and
+<a href="/pkg/os/#File.SetWriteDeadline"><code>SetWriteDeadline</code></a>
+that allow setting I/O deadlines when the
+underlying file descriptor supports non-blocking I/O operations.
+The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>.
+If an I/O method fails due to missing a deadline, it will return a
+timeout error; the
+new <a href="/pkg/os/#IsTimeout"><code>IsTimeout</code></a> function
+reports whether an error represents a timeout.
+</p>
+
+<p>
+Also matching <code>net.Conn</code>,
+<code>File</code>'s
+<a href="/pkg/os/#File.Close"><code>Close</code></a> method
+now guarantee that when <code>Close</code> returns,
+the underlying file descriptor has been closed.
+(In earlier releases,
+if the <code>Close</code> stopped pending I/O
+in other goroutines, the closing of the file descriptor could happen in one of those
+goroutines shortly after <code>Close</code> returned.)
+</p>
+
+<p>
+On BSD, macOS, and Solaris systems,
+<a href="/pkg/os/#Chtimes"><code>Chtimes</code></a>
+now supports setting file times with nanosecond precision
+(assuming the underlying file system can represent them).
+</p>
+</dl>
+
+<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
+<dd>
+<p>
+The <a href="/pkg/reflect/#Copy"><code>Copy</code></a> function now allows copying
+from a string into a byte array or byte slice, to match the
+<a href="/pkg/builtin/#copy">built-in copy function</a>.
+</p>
+
+<p>
+In structs, embedded pointers to unexported struct types were
+previously incorrectly reported with an empty <code>PkgPath</code>
+in the corresponding <a href="/pkg/reflect/#StructField">StructField</a>,
+with the result that for those fields,
+and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a>
+incorrectly returned true and
+<a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
+incorrectly succeeded.
+The underlying metadata has been corrected;
+for those fields,
+<code>CanSet</code> now correctly returns false
+and <code>Set</code> now correctly panics.
+This may affect reflection-based unmarshalers
+that could previously unmarshal into such fields
+but no longer can.
+For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>.
+</p>
+</dl>
+
+<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
+<dd>
+<p>
+As <a href="#pprof">noted above</a>, the blocking and mutex profiles
+now include symbol information so that they can be viewed without needing
+the binary that generated them.
+</p>
+</dl>
+
+<dl id="strconv"><dt><a href="/pkg/strconv/">strconv</a></dt>
+<dd>
+<p>
+<a href="/pkg/strconv/#ParseUint"><code>ParseUint</code></a> now returns
+the maximum magnitude integer of the appropriate size
+with any <code>ErrRange</code> error, as it was already documented to do.
+Previously it returned 0 with <code>ErrRange</code> errors.
+</p>
+</dl>
+
+<dl id="strings"><dt><a href="/pkg/strings/">strings</a></dt>
+<dd>
+<p>
+A new type
+<a href="/pkg/strings/#Builder"><code>Builder</code></a> is a replacement for
+<a href="/pkg/bytes/#Buffer"><code>bytes.Buffer</code></a> for the use case of
+accumulating text into a <code>string</code> result.
+The <code>Builder</code>'s API is a restricted subset of <code>bytes.Buffer</code>'s
+that allows it to safely avoid making a duplicate copy of the data
+during the <a href="/pkg/strings/#Builder.String"><code>String</code></a> method.
+</p>
+</dl>
+
+<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
+<dd>
+<p>
+On Windows,
+the new <a href="/pkg/syscall/#SysProcAttr"><code>SysProcAttr</code></a> field <code>Token</code>,
+of type <a href="/pkg/syscall/#Token"><code>Token</code></a> allows the creation of a process that
+runs as another user during <a href="/pkg/syscall/#StartProcess"><code>StartProcess</code></a>
+(and therefore also during <a href="/pkg/os/#StartProcess"><code>os.StartProcess</code></a> and
+<a href="/pkg/os/exec/#Cmd.Start"><code>exec.Cmd.Start</code></a>).
+The new function <a href="/pkg/syscall/#CreateProcessAsUser"><code>CreateProcessAsUser</code></a>
+gives access to the underlying system call.
+</p>
+
+<p>
+On BSD, macOS, and Solaris systems, <a href="/pkg/syscall/#UtimesNano"><code>UtimesNano</code></a>
+is now implemented.
+</p>
+</dl>
+
+<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
+<dd>
+<p>
+<a href="/pkg/time/#LoadLocation"><code>LoadLocation</code></a> now uses the directory
+or uncompressed zip file named by the <code>$ZONEINFO</code>
+environment variable before looking in the default system-specific list of
+known installation locations or in <code>$GOROOT/lib/time/zoneinfo.zip</code>.
+</p>
+<p>
+The new function <a href="/pkg/time/#LoadLocationFromTZData"><code>LoadLocationFromTZData</code></a>
+allows conversion of IANA time zone file data to a <a href="/pkg/time/#Location"><code>Location</code></a>.
+</p>
+</dl>
+
+<dl id="unicode"><dt><a href="/pkg/unicode/">unicode</a></dt>
+<dd>
+<p>
+The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
+support throughout the system has been upgraded from Unicode 9.0 to
+<a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>,
+which adds 8,518 new characters, including four new scripts, one new property,
+a Bitcoin currency symbol, and 56 new emoji.
+</p>
+</dl>
diff --git a/doc/go1.2.html b/doc/go1.2.html
index b9d36f2..5370bbb 100644
--- a/doc/go1.2.html
+++ b/doc/go1.2.html
@@ -266,7 +266,7 @@
 <p>
 On the ARM, the toolchain supports "external linking", which
 is a step towards being able to build shared libraries with the gc
-tool chain and to provide dynamic linking support for environments
+toolchain and to provide dynamic linking support for environments
 in which that is necessary.
 </p>
 
diff --git a/doc/go1.3.html b/doc/go1.3.html
index d51052b..18c638a 100644
--- a/doc/go1.3.html
+++ b/doc/go1.3.html
@@ -11,7 +11,7 @@
 and contains no language changes.
 It focuses primarily on implementation work, providing 
 precise garbage collection,
-a major refactoring of the compiler tool chain that results in
+a major refactoring of the compiler toolchain that results in
 faster builds, especially for large projects,
 significant performance improvements across the board,
 and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl).
@@ -285,7 +285,7 @@
 <h3 id="gc_flag">Command-line flag parsing</h3>
 
 <p>
-In the gc tool chain, the assemblers now use the
+In the gc toolchain, the assemblers now use the
 same command-line flag parsing rules as the Go flag package, a departure
 from the traditional Unix flag parsing.
 This may affect scripts that invoke the tool directly.
diff --git a/doc/go1.9.html b/doc/go1.9.html
index ce103cd..fa50ae7 100644
--- a/doc/go1.9.html
+++ b/doc/go1.9.html
@@ -719,6 +719,11 @@
         header when matching handlers. The host is matched unmodified for <code>CONNECT</code> requests.
       </li>
 
+      <li><!-- CL 44074 -->
+        The new <a href="/pkg/net/http/#Server.ServeTLS"><code>Server.ServeTLS</code></a> method wraps
+        <a href="/pkg/net/http/#Server.Serve"><code>Server.Serve</code></a> with added TLS support.
+      </li>
+
       <li><!-- CL 34727 -->
         <a href="/pkg/net/http/#Server.WriteTimeout"><code>Server.WriteTimeout</code></a>
         now applies to HTTP/2 connections and is enforced per-stream.
@@ -740,6 +745,11 @@
         and
         <a href="/pkg/context/#WithValue"><code>context.WithValue</code></a> instead.
       </li>
+
+      <li><!-- CL 35490 -->
+        <a href="/pkg/net/http/#LocalAddrContextKey"><code>LocalAddrContextKey</code></a> now contains
+        the connection's actual network address instead of the interface address used by the listener.
+      </li>
     </ul>
 
     <p>Client &amp; Transport changes:</p>
diff --git a/doc/go1.html b/doc/go1.html
index 1665d74..34e305b 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -775,7 +775,7 @@
 </p>
 
 {{code "/doc/progs/go1.go" `/ErrSyntax/`}}
-		
+
 <p>
 <em>Updating</em>:
 Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
@@ -1827,7 +1827,7 @@
 <tr><td>Uitob(x, b)</td> <td>FormatUint(uint64(x), b)</td></tr>
 <tr><td>Uitob64(x, b)</td> <td>FormatUint(x, b)</td></tr>
 </table>
-		
+
 <p>
 <em>Updating</em>:
 Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
@@ -1841,7 +1841,7 @@
 <h3 id="templates">The template packages</h3>
 
 <p>
-The <code>template</code> and <code>exp/template/html</code> packages have moved to 
+The <code>template</code> and <code>exp/template/html</code> packages have moved to
 <a href="/pkg/text/template/"><code>text/template</code></a> and
 <a href="/pkg/html/template/"><code>html/template</code></a>.
 More significant, the interface to these packages has been simplified.
@@ -2035,4 +2035,4 @@
 Installation details are described on the
 <a href="/doc/install">Getting Started</a> page, while
 the distributions themselves are listed on the
-<a href="https://golang.org/dl/">downloads page</a>.
+<a href="/dl/">downloads page</a>.
diff --git a/doc/go1compat.html b/doc/go1compat.html
index 607d354..a5624ef 100644
--- a/doc/go1compat.html
+++ b/doc/go1compat.html
@@ -190,8 +190,8 @@
 <h2 id="tools">Tools</h2>
 
 <p>
-Finally, the Go tool chain (compilers, linkers, build tools, and so
-on) are under active development and may change behavior. This
+Finally, the Go toolchain (compilers, linkers, build tools, and so
+on) is under active development and may change behavior. This
 means, for instance, that scripts that depend on the location and
 properties of the tools may be broken by a point release.
 </p>
diff --git a/doc/go_faq.html b/doc/go_faq.html
index f8322ef..f273688 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -479,6 +479,15 @@
 map access.
 </p>
 
+<p>
+Map access is unsafe only when updates are occurring.
+As long as all goroutines are only reading—looking up elements in the map,
+including iterating through it using a
+<code>for</code> <code>range</code> loop—and not changing the map
+by assigning to elements or doing deletions,
+it is safe for them to access the map concurrently without synchronization.
+</p>
+
 <h3 id="language_changes">
 Will you accept my language change?</h3>
 
@@ -1152,7 +1161,7 @@
 Work is underway on an experimental package management tool,
 <a href="https://github.com/golang/dep"><code>dep</code></a>, to learn
 more about how tooling can help package management. More information can be found in
-<a href="https://github.com/golang/dep/blob/master/FAQ.md">the <code>dep</code> FAQ</a>.
+<a href="https://github.com/golang/dep/blob/master/docs/FAQ.md">the <code>dep</code> FAQ</a>.
 </p>
 
 <h2 id="Pointers">Pointers and Allocation</h2>
@@ -1476,6 +1485,53 @@
 <a href="//blog.golang.org/2013/01/concurrency-is-not-parallelism.html">Concurrency
 is not Parallelism</a>.
 
+<h3 id="no_goroutine_id">
+Why is there no goroutine ID?</h3>
+
+<p>
+Goroutines do not have names; they are just anonymous workers.
+They expose no unique identifier, name, or data structure to the programmer.
+Some people are surprised by this, expecting the <code>go</code>
+statement to return some item that can be used to access and control
+the goroutine later.
+</p>
+
+<p>
+The fundamental reason goroutines are anonymous is so that
+the full Go language is available when programming concurrent code.
+By contrast, the usage patterns that develop when threads and goroutines are
+named can restrict what a library using them can do.
+</p>
+
+<p>
+Here is an illustration of the difficulties.
+Once one names a goroutine and constructs a model around
+it, it becomes special, and one is tempted to associate all computation
+with that goroutine, ignoring the possibility
+of using multiple, possibly shared goroutines for the processing.
+If the <code>net/http</code> package associated per-request
+state with a goroutine,
+clients would be unable to use more goroutines
+when serving a request.
+</p>
+
+<p>
+Moreover, experience with libraries such as those for graphics systems
+that require all processing to occur on the "main thread"
+has shown how awkward and limiting the approach can be when
+deployed in a concurrent language.
+The very existence of a special thread or goroutine forces
+the programmer to distort the program to avoid crashes
+and other problems caused by inadvertently operating
+on the wrong thread.
+</p>
+
+<p>
+For those cases where a particular goroutine is truly special,
+the language provides features such as channels that can be
+used in flexible ways to interact with it.
+</p>
+
 <h2 id="Functions_methods">Functions and Methods</h2>
 
 <h3 id="different_method_sets">
@@ -1795,7 +1851,7 @@
 Why is my trivial program such a large binary?</h3>
 
 <p>
-The linker in the <code>gc</code> tool chain
+The linker in the <code>gc</code> toolchain
 creates statically-linked binaries by default.  All Go binaries therefore include the Go
 run-time, along with the run-time type information necessary to support dynamic
 type checks, reflection, and even panic-time stack traces.
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 6642869..9a166cc 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of June 28, 2017",
+	"Subtitle": "Version of February 1, 2018",
 	"Path": "/ref/spec"
 }-->
 
@@ -16,8 +16,7 @@
 in mind. It is strongly typed and garbage-collected and has explicit
 support for concurrent programming.  Programs are constructed from
 <i>packages</i>, whose properties allow efficient management of
-dependencies. The existing implementations use a traditional
-compile/link model to generate executable binaries.
+dependencies.
 </p>
 
 <p>
@@ -577,11 +576,7 @@
 <a href="#Assignments">assignment</a> or as an
 operand in an <a href="#Expressions">expression</a>.
 It is an error if the constant value
-cannot be represented as a value of the respective type.
-For instance, <code>3.0</code> can be given any integer or any
-floating-point type, while <code>2147483648.0</code> (equal to <code>1&lt;&lt;31</code>)
-can be given the types <code>float32</code>, <code>float64</code>, or <code>uint32</code> but
-not <code>int32</code> or <code>string</code>.
+cannot be <a href="#Representability">represented</a> as a value of the respective type.
 </p>
 
 <p>
@@ -699,9 +694,8 @@
 </pre>
 
 <p>
-Named instances of the boolean, numeric, and string types are
-<a href="#Predeclared_identifiers">predeclared</a>.
-Other named types are introduced with <a href="#Type_declarations">type declarations</a>.
+The language <a href="#Predeclared_identifiers">predeclares</a> certain type names.
+Others are introduced with <a href="#Type_declarations">type declarations</a>.
 <i>Composite types</i>&mdash;array, struct, pointer, function,
 interface, slice, map, and channel types&mdash;may be constructed using
 type literals.
@@ -765,7 +759,8 @@
 <p>
 A <i>boolean type</i> represents the set of Boolean truth values
 denoted by the predeclared constants <code>true</code>
-and <code>false</code>. The predeclared boolean type is <code>bool</code>.
+and <code>false</code>. The predeclared boolean type is <code>bool</code>;
+it is a <a href="#Type_definitions">defined type</a>.
 </p>
 
 <h3 id="Numeric_types">Numeric types</h3>
@@ -812,8 +807,9 @@
 </pre>
 
 <p>
-To avoid portability issues all numeric types are distinct except
-<code>byte</code>, which is an alias for <code>uint8</code>, and
+To avoid portability issues all numeric types are <a href="#Type_definitions">defined
+types</a> and thus distinct except
+<code>byte</code>, which is an <a href="#Alias_declarations">alias</a> for <code>uint8</code>, and
 <code>rune</code>, which is an alias for <code>int32</code>.
 Conversions
 are required when different numeric types are mixed in an expression
@@ -829,7 +825,8 @@
 A string value is a (possibly empty) sequence of bytes.
 Strings are immutable: once created,
 it is impossible to change the contents of a string.
-The predeclared string type is <code>string</code>.
+The predeclared string type is <code>string</code>;
+it is a <a href="#Type_definitions">defined type</a>.
 </p>
 
 <p>
@@ -861,7 +858,8 @@
 
 <p>
 The length is part of the array's type; it must evaluate to a
-non-negative <a href="#Constants">constant</a> representable by a value
+non-negative <a href="#Constants">constant</a>
+<a href="#Representability">representable</a> by a value
 of type <code>int</code>.
 The length of array <code>a</code> can be discovered
 using the built-in function <a href="#Length_and_capacity"><code>len</code></a>.
@@ -1026,8 +1024,8 @@
 </p>
 
 <p>
-Given a struct type <code>S</code> and a type named <code>T</code>,
-promoted methods are included in the method set of the struct as follows:
+Given a struct type <code>S</code> and a <a href="#Type_definitions">defined type</a>
+<code>T</code>, promoted methods are included in the method set of the struct as follows:
 </p>
 <ul>
 	<li>
@@ -1454,9 +1452,9 @@
 	    <a href="#Exported_identifiers">Non-exported</a> method names from different
 	    packages are always different. The order of the methods is irrelevant.</li>
 
-	<li>Two map types are identical if they have identical key and value types.</li>
+	<li>Two map types are identical if they have identical key and element types.</li>
 
-	<li>Two channel types are identical if they have identical value types and
+	<li>Two channel types are identical if they have identical element types and
 	    the same direction.</li>
 </ul>
 
@@ -1496,7 +1494,7 @@
 A3 and int
 A4, func(int, float64) *[]string, and A5
 
-B0, B0, and C0
+B0 and C0
 []int and []int
 struct{ a, b *T5 } and struct{ a, b *T5 }
 func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
@@ -1514,7 +1512,7 @@
 
 <p>
 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:
+("<code>x</code> is assignable to <code>T</code>") if one of the following conditions applies:
 </p>
 
 <ul>
@@ -1540,12 +1538,68 @@
 is a pointer, function, slice, map, channel, or interface type.
 </li>
 <li>
-<code>x</code> is an untyped <a href="#Constants">constant</a> representable
+<code>x</code> is an untyped <a href="#Constants">constant</a>
+<a href="#Representability">representable</a>
 by a value of type <code>T</code>.
 </li>
 </ul>
 
 
+<h3 id="Representability">Representability</h3>
+
+<p>
+A <a href="#Constants">constant</a> <code>x</code> is <i>representable</i>
+by a value of type <code>T</code> if one of the following conditions applies:
+</p>
+
+<ul>
+<li>
+<code>x</code> is in the set of values <a href="#Types">determined</a> by <code>T</code>.
+</li>
+
+<li>
+<code>T</code> is a floating-point type and <code>x</code> can be rounded to <code>T</code>'s
+precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE
+negative zero further simplified to an unsigned zero. Note that constant values never result
+in an IEEE negative zero, NaN, or infinity.
+</li>
+
+<li>
+<code>T</code> is a complex type, and <code>x</code>'s
+<a href="#Complex_numbers">components</a> <code>real(x)</code> and <code>imag(x)</code>
+are representable by values of <code>T</code>'s component type (<code>float32</code> or
+<code>float64</code>).
+</li>
+</ul>
+
+<pre>
+x                   T           x is representable by a value of T because
+
+'a'                 byte        97 is in the set of byte values
+97                  rune        rune is an alias for int32, and 97 is in the set of 32-bit integers
+"foo"               string      "foo" is in the set of string values
+1024                int16       1024 is in the set of 16-bit integers
+42.0                byte        42 is in the set of unsigned 8-bit integers
+1e10                uint64      10000000000 is in the set of unsigned 64-bit integers
+2.718281828459045   float32     2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
+-1e-1000            float64     -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
+0i                  int         0 is an integer value
+(42 + 0i)           float32     42.0 (with zero imaginary part) is in the set of float32 values
+</pre>
+
+<pre>
+x                   T           x is not representable by a value of T because
+
+0                   bool        0 is not in the set of boolean values
+'a'                 string      'a' is a rune, it is not in the set of string values
+1024                byte        1024 is not in the set of unsigned 8-bit integers
+-1                  uint16      -1 is not in the set of unsigned 16-bit integers
+1.1                 int         1.1 is not an integer value
+42i                 float32     (0 + 42i) is not in the set of float32 values
+1e1000              float64     1e1000 overflows to IEEE +Inf after rounding
+</pre>
+
+
 <h2 id="Blocks">Blocks</h2>
 
 <p>
@@ -1781,7 +1835,7 @@
 
 <p>
 Within a parenthesized <code>const</code> declaration list the
-expression list may be omitted from any but the first declaration.
+expression list may be omitted from any but the first ConstSpec.
 Such an empty list is equivalent to the textual substitution of the
 first preceding non-empty expression list and its type if any.
 Omitting the list of expressions is therefore equivalent to
@@ -1810,52 +1864,51 @@
 <p>
 Within a <a href="#Constant_declarations">constant declaration</a>, the predeclared identifier
 <code>iota</code> represents successive untyped integer <a href="#Constants">
-constants</a>. It is reset to 0 whenever the reserved word <code>const</code>
-appears in the source and increments after each <a href="#ConstSpec">ConstSpec</a>.
+constants</a>. Its value is the index of the respective <a href="#ConstSpec">ConstSpec</a>
+in that constant declaration, starting at zero.
 It can be used to construct a set of related constants:
 </p>
 
 <pre>
-const ( // iota is reset to 0
+const (
 	c0 = iota  // c0 == 0
 	c1 = iota  // c1 == 1
 	c2 = iota  // c2 == 2
 )
 
-const ( // iota is reset to 0
-	a = 1 &lt;&lt; iota  // a == 1
-	b = 1 &lt;&lt; iota  // b == 2
-	c = 3          // c == 3  (iota is not used but still incremented)
-	d = 1 &lt;&lt; iota  // d == 8
+const (
+	a = 1 &lt;&lt; iota  // a == 1  (iota == 0)
+	b = 1 &lt;&lt; iota  // b == 2  (iota == 1)
+	c = 3          // c == 3  (iota == 2, unused)
+	d = 1 &lt;&lt; iota  // d == 8  (iota == 3)
 )
 
-const ( // iota is reset to 0
+const (
 	u         = iota * 42  // u == 0     (untyped integer constant)
 	v float64 = iota * 42  // v == 42.0  (float64 constant)
 	w         = iota * 42  // w == 84    (untyped integer constant)
 )
 
-const x = iota  // x == 0  (iota has been reset)
-const y = iota  // y == 0  (iota has been reset)
+const x = iota  // x == 0
+const y = iota  // y == 0
 </pre>
 
 <p>
-Within an ExpressionList, the value of each <code>iota</code> is the same because
-it is only incremented after each ConstSpec:
+By definition, multiple uses of <code>iota</code> in the same ConstSpec all have the same value:
 </p>
 
 <pre>
 const (
-	bit0, mask0 = 1 &lt;&lt; iota, 1&lt;&lt;iota - 1  // bit0 == 1, mask0 == 0
-	bit1, mask1                           // bit1 == 2, mask1 == 1
-	_, _                                  // skips iota == 2
-	bit3, mask3                           // bit3 == 8, mask3 == 7
+	bit0, mask0 = 1 &lt;&lt; iota, 1&lt;&lt;iota - 1  // bit0 == 1, mask0 == 0  (iota == 0)
+	bit1, mask1                           // bit1 == 2, mask1 == 1  (iota == 1)
+	_, _                                  //                        (iota == 2, unused)
+	bit3, mask3                           // bit3 == 8, mask3 == 7  (iota == 3)
 )
 </pre>
 
 <p>
-This last example exploits the implicit repetition of the
-last non-empty expression list.
+This last example exploits the <a href="#Constant_declarations">implicit repetition</a>
+of the last non-empty expression list.
 </p>
 
 
@@ -1946,7 +1999,7 @@
 // NewMutex has the same composition as Mutex but its method set is empty.
 type NewMutex Mutex
 
-// The method set of the <a href="#Pointer_types">base type</a> of PtrMutex remains unchanged,
+// The method set of PtrMutex's underlying type *Mutex remains unchanged,
 // but the method set of PtrMutex is empty.
 type PtrMutex *Mutex
 
@@ -2095,9 +2148,8 @@
 </p>
 
 <pre class="ebnf">
-FunctionDecl = "func" FunctionName ( Function | Signature ) .
+FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
 FunctionName = identifier .
-Function     = Signature FunctionBody .
 FunctionBody = Block .
 </pre>
 
@@ -2143,7 +2195,7 @@
 </p>
 
 <pre class="ebnf">
-MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
+MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
 Receiver   = Parameters .
 </pre>
 
@@ -2224,7 +2276,6 @@
 <a href="#Constant_declarations">constant</a>,
 <a href="#Variable_declarations">variable</a>, or
 <a href="#Function_declarations">function</a>,
-a <a href="#Method_expressions">method expression</a> yielding a function,
 or a parenthesized expression.
 </p>
 
@@ -2234,7 +2285,7 @@
 </p>
 
 <pre class="ebnf">
-Operand     = Literal | OperandName | MethodExpr | "(" Expression ")" .
+Operand     = Literal | OperandName | "(" Expression ")" .
 Literal     = BasicLit | CompositeLit | FunctionLit .
 BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
 OperandName = identifier | QualifiedIdent.
@@ -2348,7 +2399,8 @@
 	    its position in the array.
 	</li>
 	<li>An element with a key uses the key as its index. The
-	    key must be a non-negative constant representable by
+	    key must be a non-negative constant
+	    <a href="#Representability">representable</a> by
 	    a value of type <code>int</code>; and if it is typed
 	    it must be of integer type.
 	</li>
@@ -2465,7 +2517,7 @@
 </p>
 
 <pre class="ebnf">
-FunctionLit = "func" Function .
+FunctionLit = "func" Signature FunctionBody .
 </pre>
 
 <pre>
@@ -2499,6 +2551,7 @@
 PrimaryExpr =
 	Operand |
 	Conversion |
+	MethodExpr |
 	PrimaryExpr Selector |
 	PrimaryExpr Index |
 	PrimaryExpr Slice |
@@ -2588,8 +2641,8 @@
 </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
+As an exception, if the type of <code>x</code> is a <a href="#Type_definitions">defined</a>
+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>
 
@@ -2685,7 +2738,7 @@
 
 <pre class="ebnf">
 MethodExpr    = ReceiverType "." MethodName .
-ReceiverType  = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" .
+ReceiverType  = Type .
 </pre>
 
 <p>
@@ -2921,11 +2974,12 @@
 If <code>a</code> is not a map:
 </p>
 <ul>
-	<li>the index <code>x</code> must be of integer type or untyped;
-	    it is <i>in range</i> if <code>0 &lt;= x &lt; len(a)</code>,
+	<li>the index <code>x</code> must be of integer type or an untyped constant</li>
+	<li>a constant index must be non-negative and
+	    <a href="#Representability">representable</a> by a value of type <code>int</code></li>
+	<li>a constant index that is untyped is given type <code>int</code></li>
+	<li>the index <code>x</code> is <i>in range</i> if <code>0 &lt;= x &lt; len(a)</code>,
 	    otherwise it is <i>out of range</i></li>
-	<li>a <a href="#Constants">constant</a> index must be non-negative
-	    and representable by a value of type <code>int</code>
 </ul>
 
 <p>
@@ -2977,11 +3031,11 @@
 	    <a href="#Assignability">assignable</a>
 	    to the key type of <code>M</code></li>
 	<li>if the map contains an entry with key <code>x</code>,
-	    <code>a[x]</code> is the map value with key <code>x</code>
-	    and the type of <code>a[x]</code> is the value type of <code>M</code></li>
+	    <code>a[x]</code> is the map element with key <code>x</code>
+	    and the type of <code>a[x]</code> is the element type of <code>M</code></li>
 	<li>if the map is <code>nil</code> or does not contain such an entry,
 	    <code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
-	    for the value type of <code>M</code></li>
+	    for the element type of <code>M</code></li>
 </ul>
 
 <p>
@@ -3075,7 +3129,8 @@
 <code>0</code> &lt;= <code>low</code> &lt;= <code>high</code> &lt;= <code>len(a)</code>,
 otherwise they are <i>out of range</i>.
 For slices, the upper index bound is the slice capacity <code>cap(a)</code> rather than the length.
-A <a href="#Constants">constant</a> index must be non-negative and representable by a value of type
+A <a href="#Constants">constant</a> index must be non-negative and
+<a href="#Representability">representable</a> by a value of type
 <code>int</code>; for arrays or constant strings, constant indices must also be in range.
 If both indices are constant, they must satisfy <code>low &lt;= high</code>.
 If the indices are out of range at run time, a <a href="#Run_time_panics">run-time panic</a> occurs.
@@ -3091,8 +3146,8 @@
 
 <p>
 If the sliced operand of a valid slice expression is a <code>nil</code> slice, the result
-is a <code>nil</code> slice. Otherwise, the result shares its underlying array with the
-operand.
+is a <code>nil</code> slice. Otherwise, if the result is a slice, it shares its underlying
+array with the operand.
 </p>
 
 <h4>Full slice expressions</h4>
@@ -3135,7 +3190,8 @@
 <p>
 The indices are <i>in range</i> if <code>0 &lt;= low &lt;= high &lt;= max &lt;= cap(a)</code>,
 otherwise they are <i>out of range</i>.
-A <a href="#Constants">constant</a> index must be non-negative and representable by a value of type
+A <a href="#Constants">constant</a> index must be non-negative and
+<a href="#Representability">representable</a> by a value of type
 <code>int</code>; for arrays, constant indices must also be in range.
 If multiple indices are constant, the constants that are present must be in range relative to each
 other.
@@ -3384,7 +3440,8 @@
 
 <p>
 The right operand in a shift expression must have unsigned integer type
-or be an untyped constant representable by a value of type <code>uint</code>.
+or be an untyped constant <a href="#Representability">representable</a> by a
+value of type <code>uint</code>.
 If the left operand of a non-constant shift expression is an untyped constant,
 it is first converted to the type it would assume if the shift expression were
 replaced by its left operand alone.
@@ -3392,18 +3449,20 @@
 
 <pre>
 var s uint = 33
-var i = 1&lt;&lt;s           // 1 has type int
-var j int32 = 1&lt;&lt;s     // 1 has type int32; j == 0
-var k = uint64(1&lt;&lt;s)   // 1 has type uint64; k == 1&lt;&lt;33
-var m int = 1.0&lt;&lt;s     // 1.0 has type int; m == 0 if ints are 32bits in size
-var n = 1.0&lt;&lt;s == j    // 1.0 has type int32; n == true
-var o = 1&lt;&lt;s == 2&lt;&lt;s   // 1 and 2 have type int; o == true if ints are 32bits in size
-var p = 1&lt;&lt;s == 1&lt;&lt;33  // illegal if ints are 32bits in size: 1 has type int, but 1&lt;&lt;33 overflows int
-var u = 1.0&lt;&lt;s         // illegal: 1.0 has type float64, cannot shift
-var u1 = 1.0&lt;&lt;s != 0   // illegal: 1.0 has type float64, cannot shift
-var u2 = 1&lt;&lt;s != 1.0   // illegal: 1 has type float64, cannot shift
-var v float32 = 1&lt;&lt;s   // illegal: 1 has type float32, cannot shift
-var w int64 = 1.0&lt;&lt;33  // 1.0&lt;&lt;33 is a constant shift expression
+var i = 1&lt;&lt;s                  // 1 has type int
+var j int32 = 1&lt;&lt;s            // 1 has type int32; j == 0
+var k = uint64(1&lt;&lt;s)          // 1 has type uint64; k == 1&lt;&lt;33
+var m int = 1.0&lt;&lt;s            // 1.0 has type int; m == 0 if ints are 32bits in size
+var n = 1.0&lt;&lt;s == j           // 1.0 has type int32; n == true
+var o = 1&lt;&lt;s == 2&lt;&lt;s          // 1 and 2 have type int; o == true if ints are 32bits in size
+var p = 1&lt;&lt;s == 1&lt;&lt;33         // illegal if ints are 32bits in size: 1 has type int, but 1&lt;&lt;33 overflows int
+var u = 1.0&lt;&lt;s                // illegal: 1.0 has type float64, cannot shift
+var u1 = 1.0&lt;&lt;s != 0          // illegal: 1.0 has type float64, cannot shift
+var u2 = 1&lt;&lt;s != 1.0          // illegal: 1 has type float64, cannot shift
+var v float32 = 1&lt;&lt;s          // illegal: 1 has type float32, cannot shift
+var w int64 = 1.0&lt;&lt;33         // 1.0&lt;&lt;33 is a constant shift expression
+var x = a[1.0&lt;&lt;s]             // 1.0 has type int; x == a[0] if ints are 32bits in size
+var a = make([]byte, 1.0&lt;&lt;s)  // 1.0 has type int; len(a) == 0 if ints are 32bits in size
 </pre>
 
 
@@ -3497,9 +3556,10 @@
 </pre>
 
 <p>
-As an exception to this rule, if the dividend <code>x</code> is the most
-negative value for the int type of <code>x</code>, the quotient
-<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>).
+The one exception to this rule is that if the dividend <code>x</code> is
+the most negative value for the int type of <code>x</code>, the quotient
+<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>)
+due to two's-complement <a href="#Integer_overflow">integer overflow</a>:
 </p>
 
 <pre>
@@ -3558,15 +3618,15 @@
 computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of
 the <a href="#Numeric_types">unsigned integer</a>'s type.
 Loosely speaking, these unsigned integer operations
-discard high bits upon overflow, and programs may rely on ``wrap around''.
+discard high bits upon overflow, and programs may rely on "wrap around".
 </p>
 <p>
 For signed integers, the operations <code>+</code>,
-<code>-</code>, <code>*</code>, and <code>&lt;&lt;</code> may legally
+<code>-</code>, <code>*</code>, <code>/</code>, and <code>&lt;&lt;</code> may legally
 overflow and the resulting value exists and is deterministically defined
 by the signed integer representation, the operation, and its operands.
-No exception is raised as a result of overflow. A
-compiler may not optimize code under the assumption that overflow does
+No exception is raised as a result of overflow.
+A compiler may not optimize code under the assumption that overflow does
 not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true.
 </p>
 
@@ -3877,30 +3937,14 @@
 
 <p>
 A <a href="#Constants">constant</a> value <code>x</code> can be converted to
-type <code>T</code> in any of these cases:
+type <code>T</code> if <code>x</code> is <a href="#Representability">representable</a>
+by a value of <code>T</code>.
+As a special case, an integer constant <code>x</code> can be converted to a
+<a href="#String_types">string type</a> using the
+<a href="#Conversions_to_and_from_a_string_type">same rule</a>
+as for non-constant <code>x</code>.
 </p>
 
-<ul>
-	<li>
-	<code>x</code> is representable by a value of type <code>T</code>.
-	</li>
-	<li>
-	<code>x</code> is a floating-point constant,
-	<code>T</code> is a floating-point type,
-	and <code>x</code> is representable by a value
-	of type <code>T</code> after rounding using
-	IEEE 754 round-to-even rules, but with an IEEE <code>-0.0</code>
-	further rounded to an unsigned <code>0.0</code>.
-	The constant <code>T(x)</code> is the rounded value.
-	</li>
-	<li>
-	<code>x</code> is an integer constant and <code>T</code> is a
-	<a href="#String_types">string type</a>.
-	The <a href="#Conversions_to_and_from_a_string_type">same rule</a>
-	as for non-constant <code>x</code> applies in this case.
-	</li>
-</ul>
-
 <p>
 Converting a constant yields a typed constant as result.
 </p>
@@ -4187,7 +4231,8 @@
 </pre>
 
 <p>
-The values of <i>typed</i> constants must always be accurately representable as values
+The values of <i>typed</i> constants must always be accurately
+<a href="#Representability">representable</a> by values
 of the constant type. The following constant expressions are illegal:
 </p>
 
@@ -4310,7 +4355,9 @@
 <h3 id="Terminating_statements">Terminating statements</h3>
 
 <p>
-A terminating statement is one of the following:
+A <i>terminating statement</i> prevents execution of all statements that lexically
+appear after it in the same <a href="#Blocks">block</a>. The following statements
+are terminating:
 </p>
 
 <ol>
@@ -4820,8 +4867,9 @@
 </p>
 
 <p>
-The type in a case may be <a href="#Predeclared_identifiers"><code>nil</code></a>;
-that case is used when the expression in the TypeSwitchGuard
+Instead of a type, a case may use the predeclared identifier
+<a href="#Predeclared_identifiers"><code>nil</code></a>;
+that case is selected when the expression in the TypeSwitchGuard
 is a <code>nil</code> interface value.
 There may be at most one <code>nil</code> case.
 </p>
@@ -4979,12 +5027,10 @@
 </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 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.
+The range expression <code>x</code> is evaluated once before beginning the loop,
+with one exception: if at most one iteration variable is present and
+<code>len(x)</code> is <a href="#Length_and_capacity">constant</a>,
+the range expression is not evaluated.
 </p>
 
 <p>
@@ -5075,7 +5121,7 @@
 }
 
 var key string
-var val interface {}  // value type of m is assignable to val
+var val interface {}  // element type of m is assignable to val
 m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
 for key, val = range m {
 	h(key, val)
@@ -5680,9 +5726,10 @@
 
 
 <p>
-The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.
-A <a href="#Constants">constant</a> size argument must be non-negative and
-representable by a value of type <code>int</code>.
+Each of the size arguments <code>n</code> and <code>m</code> must be of integer type
+or an untyped <a href="#Constants">constant</a>.
+A constant size argument must be non-negative and <a href="#Representability">representable</a>
+by a value of type <code>int</code>; if it is an untyped constant it is given type <code>int</code>.
 If both <code>n</code> and <code>m</code> are provided and are constant, then
 <code>n</code> must be no larger than <code>m</code>.
 If <code>n</code> is negative or larger than <code>m</code> at run time,
@@ -6157,7 +6204,7 @@
 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>
+<code>0</code> for numeric types, <code>""</code>
 for strings, and <code>nil</code> for pointers, functions, interfaces, slices, channels, and maps.
 This initialization is done recursively, so for instance each element of an
 array of structs will have its fields zeroed if no value is specified.
@@ -6409,7 +6456,8 @@
 <h3 id="Package_unsafe">Package <code>unsafe</code></h3>
 
 <p>
-The built-in package <code>unsafe</code>, known to the compiler,
+The built-in package <code>unsafe</code>, known to the compiler
+and accessible through the <a href="#Import_declarations">import path</a> <code>"unsafe"</code>,
 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 and may not be portable.
diff --git a/doc/help.html b/doc/help.html
index 057d752..f668196 100644
--- a/doc/help.html
+++ b/doc/help.html
@@ -1,6 +1,7 @@
 <!--{
 	"Title": "Help",
-	"Path": "/help/"
+	"Path": "/help/",
+	"Template": true
 }-->
 
 <div id="manual-nav"></div>
@@ -9,6 +10,7 @@
 
 <img class="gopher" src="/doc/gopher/help.png"/>
 
+{{if not $.GoogleCN}}
 <h3 id="mailinglist"><a href="https://groups.google.com/group/golang-nuts">Go Nuts Mailing List</a></h3>
 <p>
 Get help from Go users, and share your work on the official mailing list.
@@ -31,10 +33,12 @@
 <h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
 <p>Get live support at <b>#go-nuts</b> on <b>irc.freenode.net</b>, the official
 Go IRC channel.</p>
+{{end}}
 
 <h3 id="faq"><a href="/doc/faq">Frequently Asked Questions (FAQ)</a></h3>
 <p>Answers to common questions about Go.</p>
 
+{{if not $.GoogleCN}}
 <h2 id="inform">Stay informed</h2>
 
 <h3 id="announce"><a href="https://groups.google.com/group/golang-announce">Go Announcements Mailing List</a></h3>
@@ -64,6 +68,7 @@
 The <a href="https://changelog.com/gotime">Go Time podcast</a> is a panel of Go experts and special guests
 discussing the Go programming language, the community, and everything in between.
 </p>
+{{end}}
 
 <h2 id="community">Community resources</h2>
 
@@ -73,11 +78,13 @@
 meet to talk about Go. Find a chapter near you.
 </p>
 
+{{if not $.GoogleCN}}
 <h3 id="playground"><a href="/play">Go Playground</a></h3>
 <p>A place to write, run, and share Go code.</p>
 
 <h3 id="wiki"><a href="/wiki">Go Wiki</a></h3>
 <p>A wiki maintained by the Go community.</p>
+{{end}}
 
 <h3 id="conduct"><a href="/conduct">Code of Conduct</a></h3>
 <p>
diff --git a/doc/install-source.html b/doc/install-source.html
index d120f7d..4ed9487 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -24,7 +24,7 @@
 <div class="detail">
 
 <p>
-There are two official Go compiler tool chains.
+There are two official Go compiler toolchains.
 This document focuses on the <code>gc</code> Go
 compiler and tools.
 For information on how to work on <code>gccgo</code>, a more traditional
@@ -119,7 +119,7 @@
 <h2 id="go14">Install Go compiler binaries</h2>
 
 <p>
-The Go tool chain is written in Go. To build it, you need a Go compiler installed.
+The Go toolchain is written in Go. To build it, you need a Go compiler installed.
 The scripts that do the initial build of the tools look for an existing Go tool
 chain in <code>$GOROOT_BOOTSTRAP</code>.
 If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
@@ -127,33 +127,34 @@
 </p>
 
 <p>
-There are many options for the bootstrap tool chain.
+There are many options for the bootstrap toolchain.
 After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
 directory containing the unpacked tree.
 For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
-the <code>go</code> command binary for the bootstrap tool chain.
+the <code>go</code> command binary for the bootstrap toolchain.
 </p>
 
 <p>
-To use a binary release as a bootstrap tool chain, see
+To use a binary release as a bootstrap toolchain, see
 <a href="/dl/">the downloads page</a> or use any other
 packaged Go distribution.
 </p>
 
 <p>
-To build a bootstrap tool chain from source, use
+To build a bootstrap toolchain from source, use
 either the git branch <code>release-branch.go1.4</code> or
-<a href="https://storage.googleapis.com/golang/go1.4-bootstrap-20170531.tar.gz">go1.4-bootstrap-20170531.tar.gz</a>,
+<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
 which contains the Go 1.4 source code plus accumulated fixes
 to keep the tools running on newer operating systems.
-(Go 1.4 was the last distribution in which the tool chain was written in C.)
+(Go 1.4 was the last distribution in which the toolchain was written in C.)
 After unpacking the Go 1.4 source, <code>cd</code> to
-the <code>src</code> subdirectory and run <code>make.bash</code> (or,
+the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
+the environment, and run <code>make.bash</code> (or,
 on Windows, <code>make.bat</code>).
 </p>
 
 <p>
-To cross-compile a bootstrap tool chain from source, which is
+To cross-compile a bootstrap toolchain from source, which is
 necessary on systems Go 1.4 did not target (for
 example, <code>linux/ppc64le</code>), install Go on a different system
 and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
@@ -445,6 +446,7 @@
 There is no need to set this unless you want to switch between multiple
 local copies of the repository.
 </p>
+</li>
 
 <li><code>$GOROOT_FINAL</code>
 <p>
@@ -455,12 +457,14 @@
 but move it elsewhere after the build, set
 <code>$GOROOT_FINAL</code> to the eventual location.
 </p>
+</li>
 
 <li><code>$GOOS</code> and <code>$GOARCH</code>
 <p>
 The name of the target operating system and compilation architecture.
 These default to the values of <code>$GOHOSTOS</code> and
 <code>$GOHOSTARCH</code> respectively (described below).
+</li>
 
 <p>
 Choices for <code>$GOOS</code> are
@@ -471,8 +475,9 @@
 <code>amd64</code> (64-bit x86, the most mature port),
 <code>386</code> (32-bit x86), <code>arm</code> (32-bit ARM), <code>arm64</code> (64-bit ARM),
 <code>ppc64le</code> (PowerPC 64-bit, little-endian), <code>ppc64</code> (PowerPC 64-bit, big-endian),
-<code>mips64le</code> (MIPS 64-bit, little-endian), and <code>mips64</code> (MIPS 64-bit, big-endian).
-<code>mipsle</code> (MIPS 32-bit, little-endian), and <code>mips</code> (MIPS 32-bit, big-endian).
+<code>mips64le</code> (MIPS 64-bit, little-endian), <code>mips64</code> (MIPS 64-bit, big-endian),
+<code>mipsle</code> (MIPS 32-bit, little-endian), <code>mips</code> (MIPS 32-bit, big-endian), and
+<code>s390x</code> (IBM System z 64-bit, big-endian).
 The valid combinations of <code>$GOOS</code> and <code>$GOARCH</code> are:
 <table cellpadding="0">
 <tr>
@@ -536,6 +541,9 @@
 <td></td><td><code>linux</code></td> <td><code>mips64le</code></td>
 </tr>
 <tr>
+<td></td><td><code>linux</code></td> <td><code>s390x</code></td>
+</tr>
+<tr>
 <td></td><td><code>netbsd</code></td> <td><code>386</code></td>
 </tr>
 <tr>
@@ -577,6 +585,7 @@
 These default to the local system's operating system and
 architecture.
 </p>
+</li>
 
 <p>
 Valid choices are the same as for <code>$GOOS</code> and
@@ -595,6 +604,7 @@
 If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a>
 installs all commands there.
 </p>
+</li>
 
 <li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
 if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
@@ -604,9 +614,10 @@
 floating point computations.
 </p>
 <ul>
-	<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).
-	<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.
+	<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).</li>
+	<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
 </ul>
+</li>
 
 <li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building
 on the target processor, 6 if not)
@@ -615,9 +626,9 @@
 should target. If you are compiling on the target system, its value will be auto-detected.
 </p>
 <ul>
-	<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor
-	<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)
-	<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores
+	<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor</li>
+	<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)</li>
+	<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores</li>
 </ul>
 <p>
 If in doubt, leave this variable unset, and adjust it if required
@@ -626,6 +637,17 @@
 on the <a href="//golang.org/wiki">Go community wiki</a>
 contains further details regarding Go's ARM support.
 </p>
+</li>
+
+<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only)
+<p>
+This sets whether to use floating point instructions.
+</p>
+<ul>
+	<li><code>GOMIPS=hardfloat</code>: use floating point instructions (the default)</li>
+	<li><code>GOMIPS=softfloat</code>: use soft floating point</li>
+</ul>
+</li>
 
 </ul>
 
diff --git a/doc/install.html b/doc/install.html
index 7f32f68..f17dce5 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -8,15 +8,15 @@
 <h2 id="download">Download the Go distribution</h2>
 
 <p>
-<a href="https://golang.org/dl/" id="start" class="download">
+<a href="/dl/" id="start" class="download">
 <span class="big">Download Go</span>
 <span class="desc">Click here to visit the downloads page</span>
 </a>
 </p>
 
 <p>
-<a href="https://golang.org/dl/" target="_blank">Official binary
-distributions</a> are available for the FreeBSD (release 8-STABLE and above),
+<a href="/dl/" target="_blank">Official binary
+distributions</a> are available for the FreeBSD (release 10-STABLE and above),
 Linux, Mac OS X (10.8 and above), and Windows operating systems and
 the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
 architectures.
@@ -33,7 +33,7 @@
 <h2 id="requirements">System requirements</h2>
 
 <p>
-Go <a href="https://golang.org/dl/">binary distributions</a> are available for these supported operating systems and architectures.
+Go <a href="/dl/">binary distributions</a> are available for these supported operating systems and architectures.
 Please ensure your system meets these requirements before proceeding.
 If your OS or architecture is not on the list, you may be able to
 <a href="/doc/install/source">install from source</a> or
@@ -47,7 +47,7 @@
 <th align="center">Notes</th>
 </tr>
 <tr><td colspan="3"><hr></td></tr>
-<tr><td>FreeBSD 9.3 or later</td> <td>amd64, 386</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
+<tr><td>FreeBSD 10.3 or later</td> <td>amd64, 386</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
 <tr valign='top'><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm, arm64,<br>s390x, ppc64le</td> <td>CentOS/RHEL 5.x not supported.<br>Install from source for other libc.</td></tr>
 <tr><td>macOS 10.8 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup> for <code>cgo</code> support</td></tr>
 <tr><td>Windows XP SP2 or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>
@@ -77,7 +77,7 @@
 <h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
 
 <p>
-<a href="https://golang.org/dl/">Download the archive</a>
+<a href="/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>
@@ -138,7 +138,7 @@
 <h3 id="osx">Mac OS X package installer</h3>
 
 <p>
-<a href="https://golang.org/dl/">Download the package file</a>,
+<a href="/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>
@@ -167,7 +167,7 @@
 <h4 id="windows_msi">MSI installer</h4>
 
 <p>
-Open the <a href="https://golang.org/dl/">MSI file</a>
+Open the <a href="/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>
@@ -185,7 +185,7 @@
 <h4 id="windows_zip">Zip archive</h4>
 
 <p>
-<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>).
+<a href="/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
 </p>
 
 <p>
diff --git a/doc/progs/run.go b/doc/progs/run.go
index 8479a66..06ea130 100644
--- a/doc/progs/run.go
+++ b/doc/progs/run.go
@@ -219,12 +219,5 @@
 		// cgo1 and cgo2 don't run on netbsd, srandom has a different signature
 		skipTest("cgo1")
 		skipTest("cgo2")
-		// cgo3 and cgo4 don't run on netbsd, since cgo cannot handle stdout correctly, see issue #10715.
-		skipTest("cgo3")
-		skipTest("cgo4")
-	case "openbsd", "solaris":
-		// cgo3 and cgo4 don't run on openbsd and solaris, since cgo cannot handle stdout correctly, see issue #10715.
-		skipTest("cgo3")
-		skipTest("cgo4")
 	}
 }
diff --git a/doc/root.html b/doc/root.html
index 9bdf927..a5119a9 100644
--- a/doc/root.html
+++ b/doc/root.html
@@ -58,7 +58,7 @@
 
 <div id="gopher"></div>
 
-<a href="https://golang.org/dl/" id="start">
+<a href="/dl/" id="start">
 <span class="big">Download Go</span>
 <span class="desc">
 Binary distributions available for<br>
diff --git a/lib/time/update.bash b/lib/time/update.bash
index 6261f81..b54fc9e 100755
--- a/lib/time/update.bash
+++ b/lib/time/update.bash
@@ -8,16 +8,16 @@
 # Consult http://www.iana.org/time-zones for the latest versions.
 
 # Versions to use.
-CODE=2017b
-DATA=2017b
+CODE=2017c
+DATA=2017c
 
 set -e
 rm -rf work
 mkdir work
 cd work
 mkdir zoneinfo
-curl -O http://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
-curl -O http://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
+curl -L -O http://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
+curl -L -O http://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
 tar xzf tzcode$CODE.tar.gz
 tar xzf tzdata$DATA.tar.gz
 
diff --git a/lib/time/zoneinfo.zip b/lib/time/zoneinfo.zip
index b60ae7f..0703e08 100644
--- a/lib/time/zoneinfo.zip
+++ b/lib/time/zoneinfo.zip
Binary files differ
diff --git a/misc/android/go_android_exec.go b/misc/android/go_android_exec.go
index 49b7ae9..5671479 100644
--- a/misc/android/go_android_exec.go
+++ b/misc/android/go_android_exec.go
@@ -21,6 +21,9 @@
 )
 
 func run(args ...string) string {
+	if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
+		args = append(strings.Split(flags, " "), args...)
+	}
 	buf := new(bytes.Buffer)
 	cmd := exec.Command("adb", args...)
 	cmd.Stdout = io.MultiWriter(os.Stdout, buf)
diff --git a/misc/cgo/errors/err1.go b/misc/cgo/errors/err1.go
deleted file mode 100644
index 61bbcd2..0000000
--- a/misc/cgo/errors/err1.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-/*
-#cgo LDFLAGS: -c
-
-void test() {
-	xxx;		// ERROR HERE
-}
-*/
-import "C"
-
-func main() {
-	C.test()
-}
diff --git a/misc/cgo/errors/errors_test.go b/misc/cgo/errors/errors_test.go
new file mode 100644
index 0000000..118187f
--- /dev/null
+++ b/misc/cgo/errors/errors_test.go
@@ -0,0 +1,161 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errorstest
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+func path(file string) string {
+	return filepath.Join("src", file)
+}
+
+func check(t *testing.T, file string) {
+	t.Run(file, func(t *testing.T) {
+		t.Parallel()
+
+		contents, err := ioutil.ReadFile(path(file))
+		if err != nil {
+			t.Fatal(err)
+		}
+		var errors []*regexp.Regexp
+		for i, line := range bytes.Split(contents, []byte("\n")) {
+			if bytes.HasSuffix(line, []byte("ERROR HERE")) {
+				re := regexp.MustCompile(regexp.QuoteMeta(fmt.Sprintf("%s:%d:", file, i+1)))
+				errors = append(errors, re)
+				continue
+			}
+
+			frags := bytes.SplitAfterN(line, []byte("ERROR HERE: "), 2)
+			if len(frags) == 1 {
+				continue
+			}
+			re, err := regexp.Compile(string(frags[1]))
+			if err != nil {
+				t.Errorf("Invalid regexp after `ERROR HERE: `: %#q", frags[1])
+				continue
+			}
+			errors = append(errors, re)
+		}
+		if len(errors) == 0 {
+			t.Fatalf("cannot find ERROR HERE")
+		}
+		expect(t, file, errors)
+	})
+}
+
+func expect(t *testing.T, file string, errors []*regexp.Regexp) {
+	dir, err := ioutil.TempDir("", filepath.Base(t.Name()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	dst := filepath.Join(dir, strings.TrimSuffix(file, ".go"))
+	cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		t.Errorf("expected cgo to fail but it succeeded")
+	}
+
+	lines := bytes.Split(out, []byte("\n"))
+	for _, re := range errors {
+		found := false
+		for _, line := range lines {
+			if re.Match(line) {
+				t.Logf("found match for %#q: %q", re, line)
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("expected error output to contain %#q", re)
+		}
+	}
+
+	if t.Failed() {
+		t.Logf("actual output:\n%s", out)
+	}
+}
+
+func sizeofLongDouble(t *testing.T) int {
+	cmd := exec.Command("go", "run", path("long_double_size.go"))
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out)
+	}
+
+	i, err := strconv.Atoi(strings.TrimSpace(string(out)))
+	if err != nil {
+		t.Fatalf("long_double_size.go printed invalid size: %s", out)
+	}
+	return i
+}
+
+func TestReportsTypeErrors(t *testing.T) {
+	for _, file := range []string{
+		"err1.go",
+		"err2.go",
+		"err3.go",
+		"issue7757.go",
+		"issue8442.go",
+		"issue11097a.go",
+		"issue11097b.go",
+		"issue13129.go",
+		"issue13423.go",
+		"issue13467.go",
+		"issue13635.go",
+		"issue13830.go",
+		"issue16116.go",
+		"issue16591.go",
+		"issue18452.go",
+		"issue18889.go",
+	} {
+		check(t, file)
+	}
+
+	if sizeofLongDouble(t) > 8 {
+		check(t, "err4.go")
+	}
+}
+
+func TestToleratesOptimizationFlag(t *testing.T) {
+	for _, cflags := range []string{
+		"",
+		"-O",
+	} {
+		cflags := cflags
+		t.Run(cflags, func(t *testing.T) {
+			t.Parallel()
+
+			cmd := exec.Command("go", "build", path("issue14669.go"))
+			cmd.Env = append(os.Environ(), "CGO_CFLAGS="+cflags)
+			out, err := cmd.CombinedOutput()
+			if err != nil {
+				t.Errorf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out)
+			}
+		})
+	}
+}
+
+func TestMallocCrashesOnNil(t *testing.T) {
+	t.Parallel()
+
+	cmd := exec.Command("go", "run", path("malloc.go"))
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		t.Logf("%#q:\n%s", strings.Join(cmd.Args, " "), out)
+		t.Fatalf("succeeded unexpectedly")
+	}
+}
diff --git a/misc/cgo/errors/issue13129.go b/misc/cgo/errors/issue13129.go
deleted file mode 100644
index f7ad7a7..0000000
--- a/misc/cgo/errors/issue13129.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// issue 13129: used to output error about C.unsignedshort with CC=clang
-
-package main
-
-import "C"
-
-func main() {
-	var x C.ushort
-	x = int(0) // ERROR HERE
-}
diff --git a/misc/cgo/errors/issue13635.go b/misc/cgo/errors/issue13635.go
deleted file mode 100644
index 0ce2b1e..0000000
--- a/misc/cgo/errors/issue13635.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// issue 13635: used to output error about C.unsignedchar.
-// This test tests all such types.
-
-package pkg
-
-import "C"
-
-func main() {
-	var (
-		_ C.uchar         = "uc"  // ERROR HERE
-		_ C.schar         = "sc"  // ERROR HERE
-		_ C.ushort        = "us"  // ERROR HERE
-		_ C.uint          = "ui"  // ERROR HERE
-		_ C.ulong         = "ul"  // ERROR HERE
-		_ C.longlong      = "ll"  // ERROR HERE
-		_ C.ulonglong     = "ull" // ERROR HERE
-		_ C.complexfloat  = "cf"  // ERROR HERE
-		_ C.complexdouble = "cd"  // ERROR HERE
-	)
-}
diff --git a/misc/cgo/errors/issue18452.go b/misc/cgo/errors/issue18452.go
deleted file mode 100644
index 36ef7f5..0000000
--- a/misc/cgo/errors/issue18452.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Issue 18452: show pos info in undefined name errors
-
-package p
-
-import (
-	"C"
-	"fmt"
-)
-
-func a() {
-	fmt.Println("Hello, world!")
-	C.function_that_does_not_exist() // line 16
-	C.pi                             // line 17
-}
diff --git a/misc/cgo/errors/ptr.go b/misc/cgo/errors/ptr.go
deleted file mode 100644
index 3e11766..0000000
--- a/misc/cgo/errors/ptr.go
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Tests that cgo detects invalid pointer passing at runtime.
-
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
-)
-
-// ptrTest is the tests without the boilerplate.
-type ptrTest struct {
-	name      string   // for reporting
-	c         string   // the cgo comment
-	imports   []string // a list of imports
-	support   string   // supporting functions
-	body      string   // the body of the main function
-	extra     []extra  // extra files
-	fail      bool     // whether the test should fail
-	expensive bool     // whether the test requires the expensive check
-}
-
-type extra struct {
-	name     string
-	contents string
-}
-
-var ptrTests = []ptrTest{
-	{
-		// Passing a pointer to a struct that contains a Go pointer.
-		name: "ptr1",
-		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
-		body: `C.f(&C.s{new(C.int)})`,
-		fail: true,
-	},
-	{
-		// Passing a pointer to a struct that contains a Go pointer.
-		name: "ptr2",
-		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
-		body: `p := &C.s{new(C.int)}; C.f(p)`,
-		fail: true,
-	},
-	{
-		// Passing a pointer to an int field of a Go struct
-		// that (irrelevantly) contains a Go pointer.
-		name: "ok1",
-		c:    `struct s { int i; int *p; }; void f(int *p) {}`,
-		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`,
-		fail: false,
-	},
-	{
-		// Passing a pointer to a pointer field of a Go struct.
-		name: "ptr-field",
-		c:    `struct s { int i; int *p; }; void f(int **p) {}`,
-		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`,
-		fail: true,
-	},
-	{
-		// Passing a pointer to a pointer field of a Go
-		// struct, where the field does not contain a Go
-		// pointer, but another field (irrelevantly) does.
-		name: "ptr-field-ok",
-		c:    `struct s { int *p1; int *p2; }; void f(int **p) {}`,
-		body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`,
-		fail: false,
-	},
-	{
-		// Passing the address of a slice with no Go pointers.
-		name:    "slice-ok-1",
-		c:       `void f(void **p) {}`,
-		imports: []string{"unsafe"},
-		body:    `s := []unsafe.Pointer{nil}; C.f(&s[0])`,
-		fail:    false,
-	},
-	{
-		// Passing the address of a slice with a Go pointer.
-		name:    "slice-ptr-1",
-		c:       `void f(void **p) {}`,
-		imports: []string{"unsafe"},
-		body:    `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`,
-		fail:    true,
-	},
-	{
-		// Passing the address of a slice with a Go pointer,
-		// where we are passing the address of an element that
-		// is not a Go pointer.
-		name:    "slice-ptr-2",
-		c:       `void f(void **p) {}`,
-		imports: []string{"unsafe"},
-		body:    `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`,
-		fail:    true,
-	},
-	{
-		// Passing the address of a slice that is an element
-		// in a struct only looks at the slice.
-		name:    "slice-ok-2",
-		c:       `void f(void **p) {}`,
-		imports: []string{"unsafe"},
-		support: `type S struct { p *int; s []unsafe.Pointer }`,
-		body:    `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`,
-		fail:    false,
-	},
-	{
-		// Passing the address of a slice of an array that is
-		// an element in a struct, with a type conversion.
-		name:    "slice-ok-3",
-		c:       `void f(void* p) {}`,
-		imports: []string{"unsafe"},
-		support: `type S struct { p *int; a [4]byte }`,
-		body:    `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`,
-		fail:    false,
-	},
-	{
-		// Passing the address of a slice of an array that is
-		// an element in a struct, with a type conversion.
-		name:    "slice-ok-4",
-		c:       `typedef void* PV; void f(PV p) {}`,
-		imports: []string{"unsafe"},
-		support: `type S struct { p *int; a [4]byte }`,
-		body:    `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
-		fail:    false,
-	},
-	{
-		// Passing the address of a static variable with no
-		// pointers doesn't matter.
-		name:    "varok",
-		c:       `void f(char** parg) {}`,
-		support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`,
-		body:    `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`,
-		fail:    false,
-	},
-	{
-		// Passing the address of a static variable with
-		// pointers does matter.
-		name:    "var",
-		c:       `void f(char*** parg) {}`,
-		support: `var hello = [...]*C.char{new(C.char)}`,
-		body:    `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`,
-		fail:    true,
-	},
-	{
-		// Storing a Go pointer into C memory should fail.
-		name: "barrier",
-		c: `#include <stdlib.h>
-                    char **f1() { return malloc(sizeof(char*)); }
-                    void f2(char **p) {}`,
-		body:      `p := C.f1(); *p = new(C.char); C.f2(p)`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// Storing a Go pointer into C memory by assigning a
-		// large value should fail.
-		name: "barrier-struct",
-		c: `#include <stdlib.h>
-                    struct s { char *a[10]; };
-                    struct s *f1() { return malloc(sizeof(struct s)); }
-                    void f2(struct s *p) {}`,
-		body:      `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// Storing a Go pointer into C memory using a slice
-		// copy should fail.
-		name: "barrier-slice",
-		c: `#include <stdlib.h>
-                    struct s { char *a[10]; };
-                    struct s *f1() { return malloc(sizeof(struct s)); }
-                    void f2(struct s *p) {}`,
-		body:      `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// A very large value uses a GC program, which is a
-		// different code path.
-		name: "barrier-gcprog-array",
-		c: `#include <stdlib.h>
-                    struct s { char *a[32769]; };
-                    struct s *f1() { return malloc(sizeof(struct s)); }
-                    void f2(struct s *p) {}`,
-		body:      `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// Similar case, with a source on the heap.
-		name: "barrier-gcprog-array-heap",
-		c: `#include <stdlib.h>
-                    struct s { char *a[32769]; };
-                    struct s *f1() { return malloc(sizeof(struct s)); }
-                    void f2(struct s *p) {}
-                    void f3(void *p) {}`,
-		imports:   []string{"unsafe"},
-		body:      `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// A GC program with a struct.
-		name: "barrier-gcprog-struct",
-		c: `#include <stdlib.h>
-                    struct s { char *a[32769]; };
-                    struct s2 { struct s f; };
-                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
-                    void f2(struct s2 *p) {}`,
-		body:      `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// Similar case, with a source on the heap.
-		name: "barrier-gcprog-struct-heap",
-		c: `#include <stdlib.h>
-                    struct s { char *a[32769]; };
-                    struct s2 { struct s f; };
-                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
-                    void f2(struct s2 *p) {}
-                    void f3(void *p) {}`,
-		imports:   []string{"unsafe"},
-		body:      `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`,
-		fail:      true,
-		expensive: true,
-	},
-	{
-		// Exported functions may not return Go pointers.
-		name: "export1",
-		c:    `extern unsigned char *GoFn();`,
-		support: `//export GoFn
-                          func GoFn() *byte { return new(byte) }`,
-		body: `C.GoFn()`,
-		fail: true,
-	},
-	{
-		// Returning a C pointer is fine.
-		name: "exportok",
-		c: `#include <stdlib.h>
-                    extern unsigned char *GoFn();`,
-		support: `//export GoFn
-                          func GoFn() *byte { return (*byte)(C.malloc(1)) }`,
-		body: `C.GoFn()`,
-	},
-	{
-		// Passing a Go string is fine.
-		name: "pass-string",
-		c: `#include <stddef.h>
-                    typedef struct { const char *p; ptrdiff_t n; } gostring;
-                    gostring f(gostring s) { return s; }`,
-		imports: []string{"unsafe"},
-		body:    `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
-	},
-	{
-		// Passing a slice of Go strings fails.
-		name:    "pass-string-slice",
-		c:       `void f(void *p) {}`,
-		imports: []string{"strings", "unsafe"},
-		support: `type S struct { a [1]string }`,
-		body:    `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`,
-		fail:    true,
-	},
-	{
-		// Exported functions may not return strings.
-		name:    "ret-string",
-		c:       `extern void f();`,
-		imports: []string{"strings"},
-		support: `//export GoStr
-                          func GoStr() string { return strings.Repeat("a", 2) }`,
-		body: `C.f()`,
-		extra: []extra{
-			{
-				"call.c",
-				`#include <stddef.h>
-                                 typedef struct { const char *p; ptrdiff_t n; } gostring;
-                                 extern gostring GoStr();
-                                 void f() { GoStr(); }`,
-			},
-		},
-		fail: true,
-	},
-	{
-		// Don't check non-pointer data.
-		// Uses unsafe code to get a pointer we shouldn't check.
-		// Although we use unsafe, the uintptr represents an integer
-		// that happens to have the same representation as a pointer;
-		// that is, we are testing something that is not unsafe.
-		name: "ptrdata1",
-		c: `#include <stdlib.h>
-                    void f(void* p) {}`,
-		imports: []string{"unsafe"},
-		support: `type S struct { p *int; a [8*8]byte; u uintptr }`,
-		body:    `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`,
-		fail:    false,
-	},
-	{
-		// Like ptrdata1, but with a type that uses a GC program.
-		name: "ptrdata2",
-		c: `#include <stdlib.h>
-                    void f(void* p) {}`,
-		imports: []string{"unsafe"},
-		support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
-		body:    `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`,
-		fail:    false,
-	},
-	{
-		// Check deferred pointers when they are used, not
-		// when the defer statement is run.
-		name: "defer",
-		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
-		body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`,
-		fail: true,
-	},
-	{
-		// Check a pointer to a union if the union has any
-		// pointer fields.
-		name:    "union1",
-		c:       `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`,
-		imports: []string{"unsafe"},
-		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
-		fail:    true,
-	},
-	{
-		// Don't check a pointer to a union if the union does
-		// not have any pointer fields.
-		// Like ptrdata1 above, the uintptr represents an
-		// integer that happens to have the same
-		// representation as a pointer.
-		name:    "union2",
-		c:       `typedef union { unsigned long i; } u; void f(u *pu) {}`,
-		imports: []string{"unsafe"},
-		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
-		fail:    false,
-	},
-	{
-		// Issue #21306.
-		name:    "preempt-during-call",
-		c:       `void f() {}`,
-		imports: []string{"runtime", "sync"},
-		body:    `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
-		fail:    false,
-	},
-}
-
-func main() {
-	os.Exit(doTests())
-}
-
-func doTests() int {
-	gopath, err := ioutil.TempDir("", "cgoerrors")
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		return 2
-	}
-	defer os.RemoveAll(gopath)
-
-	if err := os.MkdirAll(filepath.Join(gopath, "src"), 0777); err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		return 2
-	}
-
-	workers := runtime.NumCPU() + 1
-
-	var wg sync.WaitGroup
-	c := make(chan int)
-	errs := make(chan int)
-	for i := 0; i < workers; i++ {
-		wg.Add(1)
-		go func() {
-			worker(gopath, c, errs)
-			wg.Done()
-		}()
-	}
-
-	for i := range ptrTests {
-		c <- i
-	}
-	close(c)
-
-	go func() {
-		wg.Wait()
-		close(errs)
-	}()
-
-	tot := 0
-	for e := range errs {
-		tot += e
-	}
-	return tot
-}
-
-func worker(gopath string, c, errs chan int) {
-	e := 0
-	for i := range c {
-		if !doOne(gopath, i) {
-			e++
-		}
-	}
-	if e > 0 {
-		errs <- e
-	}
-}
-
-func doOne(gopath string, i int) bool {
-	t := &ptrTests[i]
-
-	dir := filepath.Join(gopath, "src", fmt.Sprintf("dir%d", i))
-	if err := os.Mkdir(dir, 0777); err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		return false
-	}
-
-	name := filepath.Join(dir, fmt.Sprintf("t%d.go", i))
-	f, err := os.Create(name)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		return false
-	}
-
-	b := bufio.NewWriter(f)
-	fmt.Fprintln(b, `package main`)
-	fmt.Fprintln(b)
-	fmt.Fprintln(b, `/*`)
-	fmt.Fprintln(b, t.c)
-	fmt.Fprintln(b, `*/`)
-	fmt.Fprintln(b, `import "C"`)
-	fmt.Fprintln(b)
-	for _, imp := range t.imports {
-		fmt.Fprintln(b, `import "`+imp+`"`)
-	}
-	if len(t.imports) > 0 {
-		fmt.Fprintln(b)
-	}
-	if len(t.support) > 0 {
-		fmt.Fprintln(b, t.support)
-		fmt.Fprintln(b)
-	}
-	fmt.Fprintln(b, `func main() {`)
-	fmt.Fprintln(b, t.body)
-	fmt.Fprintln(b, `}`)
-
-	if err := b.Flush(); err != nil {
-		fmt.Fprintf(os.Stderr, "flushing %s: %v\n", name, err)
-		return false
-	}
-	if err := f.Close(); err != nil {
-		fmt.Fprintf(os.Stderr, "closing %s: %v\n", name, err)
-		return false
-	}
-
-	for _, e := range t.extra {
-		if err := ioutil.WriteFile(filepath.Join(dir, e.name), []byte(e.contents), 0644); err != nil {
-			fmt.Fprintf(os.Stderr, "writing %s: %v\n", e.name, err)
-			return false
-		}
-	}
-
-	ok := true
-
-	cmd := exec.Command("go", "build")
-	cmd.Dir = dir
-	cmd.Env = addEnv("GOPATH", gopath)
-	buf, err := cmd.CombinedOutput()
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "test %s failed to build: %v\n%s", t.name, err, buf)
-		return false
-	}
-
-	exe := filepath.Join(dir, filepath.Base(dir))
-	cmd = exec.Command(exe)
-	cmd.Dir = dir
-
-	if t.expensive {
-		cmd.Env = cgocheckEnv("1")
-		buf, err := cmd.CombinedOutput()
-		if err != nil {
-			var errbuf bytes.Buffer
-			if t.fail {
-				fmt.Fprintf(&errbuf, "test %s marked expensive but failed when not expensive: %v\n", t.name, err)
-			} else {
-				fmt.Fprintf(&errbuf, "test %s failed unexpectedly with GODEBUG=cgocheck=1: %v\n", t.name, err)
-			}
-			reportTestOutput(&errbuf, t.name, buf)
-			os.Stderr.Write(errbuf.Bytes())
-			ok = false
-		}
-
-		cmd = exec.Command(exe)
-		cmd.Dir = dir
-	}
-
-	if t.expensive {
-		cmd.Env = cgocheckEnv("2")
-	}
-
-	buf, err = cmd.CombinedOutput()
-
-	if t.fail {
-		if err == nil {
-			var errbuf bytes.Buffer
-			fmt.Fprintf(&errbuf, "test %s did not fail as expected\n", t.name)
-			reportTestOutput(&errbuf, t.name, buf)
-			os.Stderr.Write(errbuf.Bytes())
-			ok = false
-		} else if !bytes.Contains(buf, []byte("Go pointer")) {
-			var errbuf bytes.Buffer
-			fmt.Fprintf(&errbuf, "test %s output does not contain expected error (failed with %v)\n", t.name, err)
-			reportTestOutput(&errbuf, t.name, buf)
-			os.Stderr.Write(errbuf.Bytes())
-			ok = false
-		}
-	} else {
-		if err != nil {
-			var errbuf bytes.Buffer
-			fmt.Fprintf(&errbuf, "test %s failed unexpectedly: %v\n", t.name, err)
-			reportTestOutput(&errbuf, t.name, buf)
-			os.Stderr.Write(errbuf.Bytes())
-			ok = false
-		}
-
-		if !t.expensive && ok {
-			// Make sure it passes with the expensive checks.
-			cmd := exec.Command(exe)
-			cmd.Dir = dir
-			cmd.Env = cgocheckEnv("2")
-			buf, err := cmd.CombinedOutput()
-			if err != nil {
-				var errbuf bytes.Buffer
-				fmt.Fprintf(&errbuf, "test %s failed unexpectedly with expensive checks: %v\n", t.name, err)
-				reportTestOutput(&errbuf, t.name, buf)
-				os.Stderr.Write(errbuf.Bytes())
-				ok = false
-			}
-		}
-	}
-
-	if t.fail && ok {
-		cmd = exec.Command(exe)
-		cmd.Dir = dir
-		cmd.Env = cgocheckEnv("0")
-		buf, err := cmd.CombinedOutput()
-		if err != nil {
-			var errbuf bytes.Buffer
-			fmt.Fprintf(&errbuf, "test %s failed unexpectedly with GODEBUG=cgocheck=0: %v\n", t.name, err)
-			reportTestOutput(&errbuf, t.name, buf)
-			os.Stderr.Write(errbuf.Bytes())
-			ok = false
-		}
-	}
-
-	return ok
-}
-
-func reportTestOutput(w io.Writer, name string, buf []byte) {
-	fmt.Fprintf(w, "=== test %s output ===\n", name)
-	fmt.Fprintf(w, "%s", buf)
-	fmt.Fprintf(w, "=== end of test %s output ===\n", name)
-}
-
-func cgocheckEnv(val string) []string {
-	return addEnv("GODEBUG", "cgocheck="+val)
-}
-
-func addEnv(key, val string) []string {
-	env := []string{key + "=" + val}
-	look := key + "="
-	for _, e := range os.Environ() {
-		if !strings.HasPrefix(e, look) {
-			env = append(env, e)
-		}
-	}
-	return env
-}
diff --git a/misc/cgo/errors/ptr_test.go b/misc/cgo/errors/ptr_test.go
new file mode 100644
index 0000000..fe8dfff
--- /dev/null
+++ b/misc/cgo/errors/ptr_test.go
@@ -0,0 +1,516 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Tests that cgo detects invalid pointer passing at runtime.
+
+package errorstest
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+// ptrTest is the tests without the boilerplate.
+type ptrTest struct {
+	name      string   // for reporting
+	c         string   // the cgo comment
+	imports   []string // a list of imports
+	support   string   // supporting functions
+	body      string   // the body of the main function
+	extra     []extra  // extra files
+	fail      bool     // whether the test should fail
+	expensive bool     // whether the test requires the expensive check
+}
+
+type extra struct {
+	name     string
+	contents string
+}
+
+var ptrTests = []ptrTest{
+	{
+		// Passing a pointer to a struct that contains a Go pointer.
+		name: "ptr1",
+		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
+		body: `C.f(&C.s{new(C.int)})`,
+		fail: true,
+	},
+	{
+		// Passing a pointer to a struct that contains a Go pointer.
+		name: "ptr2",
+		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
+		body: `p := &C.s{new(C.int)}; C.f(p)`,
+		fail: true,
+	},
+	{
+		// Passing a pointer to an int field of a Go struct
+		// that (irrelevantly) contains a Go pointer.
+		name: "ok1",
+		c:    `struct s { int i; int *p; }; void f(int *p) {}`,
+		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`,
+		fail: false,
+	},
+	{
+		// Passing a pointer to a pointer field of a Go struct.
+		name: "ptr-field",
+		c:    `struct s { int i; int *p; }; void f(int **p) {}`,
+		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`,
+		fail: true,
+	},
+	{
+		// Passing a pointer to a pointer field of a Go
+		// struct, where the field does not contain a Go
+		// pointer, but another field (irrelevantly) does.
+		name: "ptr-field-ok",
+		c:    `struct s { int *p1; int *p2; }; void f(int **p) {}`,
+		body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`,
+		fail: false,
+	},
+	{
+		// Passing the address of a slice with no Go pointers.
+		name:    "slice-ok-1",
+		c:       `void f(void **p) {}`,
+		imports: []string{"unsafe"},
+		body:    `s := []unsafe.Pointer{nil}; C.f(&s[0])`,
+		fail:    false,
+	},
+	{
+		// Passing the address of a slice with a Go pointer.
+		name:    "slice-ptr-1",
+		c:       `void f(void **p) {}`,
+		imports: []string{"unsafe"},
+		body:    `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`,
+		fail:    true,
+	},
+	{
+		// Passing the address of a slice with a Go pointer,
+		// where we are passing the address of an element that
+		// is not a Go pointer.
+		name:    "slice-ptr-2",
+		c:       `void f(void **p) {}`,
+		imports: []string{"unsafe"},
+		body:    `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`,
+		fail:    true,
+	},
+	{
+		// Passing the address of a slice that is an element
+		// in a struct only looks at the slice.
+		name:    "slice-ok-2",
+		c:       `void f(void **p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; s []unsafe.Pointer }`,
+		body:    `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`,
+		fail:    false,
+	},
+	{
+		// Passing the address of a slice of an array that is
+		// an element in a struct, with a type conversion.
+		name:    "slice-ok-3",
+		c:       `void f(void* p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; a [4]byte }`,
+		body:    `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`,
+		fail:    false,
+	},
+	{
+		// Passing the address of a slice of an array that is
+		// an element in a struct, with a type conversion.
+		name:    "slice-ok-4",
+		c:       `typedef void* PV; void f(PV p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; a [4]byte }`,
+		body:    `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
+		fail:    false,
+	},
+	{
+		// Passing the address of a static variable with no
+		// pointers doesn't matter.
+		name:    "varok",
+		c:       `void f(char** parg) {}`,
+		support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`,
+		body:    `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`,
+		fail:    false,
+	},
+	{
+		// Passing the address of a static variable with
+		// pointers does matter.
+		name:    "var",
+		c:       `void f(char*** parg) {}`,
+		support: `var hello = [...]*C.char{new(C.char)}`,
+		body:    `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`,
+		fail:    true,
+	},
+	{
+		// Storing a Go pointer into C memory should fail.
+		name: "barrier",
+		c: `#include <stdlib.h>
+                    char **f1() { return malloc(sizeof(char*)); }
+                    void f2(char **p) {}`,
+		body:      `p := C.f1(); *p = new(C.char); C.f2(p)`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// Storing a Go pointer into C memory by assigning a
+		// large value should fail.
+		name: "barrier-struct",
+		c: `#include <stdlib.h>
+                    struct s { char *a[10]; };
+                    struct s *f1() { return malloc(sizeof(struct s)); }
+                    void f2(struct s *p) {}`,
+		body:      `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// Storing a Go pointer into C memory using a slice
+		// copy should fail.
+		name: "barrier-slice",
+		c: `#include <stdlib.h>
+                    struct s { char *a[10]; };
+                    struct s *f1() { return malloc(sizeof(struct s)); }
+                    void f2(struct s *p) {}`,
+		body:      `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// A very large value uses a GC program, which is a
+		// different code path.
+		name: "barrier-gcprog-array",
+		c: `#include <stdlib.h>
+                    struct s { char *a[32769]; };
+                    struct s *f1() { return malloc(sizeof(struct s)); }
+                    void f2(struct s *p) {}`,
+		body:      `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// Similar case, with a source on the heap.
+		name: "barrier-gcprog-array-heap",
+		c: `#include <stdlib.h>
+                    struct s { char *a[32769]; };
+                    struct s *f1() { return malloc(sizeof(struct s)); }
+                    void f2(struct s *p) {}
+                    void f3(void *p) {}`,
+		imports:   []string{"unsafe"},
+		body:      `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// A GC program with a struct.
+		name: "barrier-gcprog-struct",
+		c: `#include <stdlib.h>
+                    struct s { char *a[32769]; };
+                    struct s2 { struct s f; };
+                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
+                    void f2(struct s2 *p) {}`,
+		body:      `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// Similar case, with a source on the heap.
+		name: "barrier-gcprog-struct-heap",
+		c: `#include <stdlib.h>
+                    struct s { char *a[32769]; };
+                    struct s2 { struct s f; };
+                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
+                    void f2(struct s2 *p) {}
+                    void f3(void *p) {}`,
+		imports:   []string{"unsafe"},
+		body:      `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`,
+		fail:      true,
+		expensive: true,
+	},
+	{
+		// Exported functions may not return Go pointers.
+		name: "export1",
+		c:    `extern unsigned char *GoFn();`,
+		support: `//export GoFn
+                          func GoFn() *byte { return new(byte) }`,
+		body: `C.GoFn()`,
+		fail: true,
+	},
+	{
+		// Returning a C pointer is fine.
+		name: "exportok",
+		c: `#include <stdlib.h>
+                    extern unsigned char *GoFn();`,
+		support: `//export GoFn
+                          func GoFn() *byte { return (*byte)(C.malloc(1)) }`,
+		body: `C.GoFn()`,
+	},
+	{
+		// Passing a Go string is fine.
+		name: "pass-string",
+		c: `#include <stddef.h>
+                    typedef struct { const char *p; ptrdiff_t n; } gostring;
+                    gostring f(gostring s) { return s; }`,
+		imports: []string{"unsafe"},
+		body:    `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
+	},
+	{
+		// Passing a slice of Go strings fails.
+		name:    "pass-string-slice",
+		c:       `void f(void *p) {}`,
+		imports: []string{"strings", "unsafe"},
+		support: `type S struct { a [1]string }`,
+		body:    `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`,
+		fail:    true,
+	},
+	{
+		// Exported functions may not return strings.
+		name:    "ret-string",
+		c:       `extern void f();`,
+		imports: []string{"strings"},
+		support: `//export GoStr
+                          func GoStr() string { return strings.Repeat("a", 2) }`,
+		body: `C.f()`,
+		extra: []extra{
+			{
+				"call.c",
+				`#include <stddef.h>
+                                 typedef struct { const char *p; ptrdiff_t n; } gostring;
+                                 extern gostring GoStr();
+                                 void f() { GoStr(); }`,
+			},
+		},
+		fail: true,
+	},
+	{
+		// Don't check non-pointer data.
+		// Uses unsafe code to get a pointer we shouldn't check.
+		// Although we use unsafe, the uintptr represents an integer
+		// that happens to have the same representation as a pointer;
+		// that is, we are testing something that is not unsafe.
+		name: "ptrdata1",
+		c: `#include <stdlib.h>
+                    void f(void* p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; a [8*8]byte; u uintptr }`,
+		body:    `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`,
+		fail:    false,
+	},
+	{
+		// Like ptrdata1, but with a type that uses a GC program.
+		name: "ptrdata2",
+		c: `#include <stdlib.h>
+                    void f(void* p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
+		body:    `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`,
+		fail:    false,
+	},
+	{
+		// Check deferred pointers when they are used, not
+		// when the defer statement is run.
+		name: "defer",
+		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
+		body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`,
+		fail: true,
+	},
+	{
+		// Check a pointer to a union if the union has any
+		// pointer fields.
+		name:    "union1",
+		c:       `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`,
+		imports: []string{"unsafe"},
+		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
+		fail:    true,
+	},
+	{
+		// Don't check a pointer to a union if the union does
+		// not have any pointer fields.
+		// Like ptrdata1 above, the uintptr represents an
+		// integer that happens to have the same
+		// representation as a pointer.
+		name:    "union2",
+		c:       `typedef union { unsigned long i; } u; void f(u *pu) {}`,
+		imports: []string{"unsafe"},
+		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
+		fail:    false,
+	},
+	{
+		// Test preemption while entering a cgo call. Issue #21306.
+		name:    "preempt-during-call",
+		c:       `void f() {}`,
+		imports: []string{"runtime", "sync"},
+		body:    `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
+		fail:    false,
+	},
+	{
+		// Test poller deadline with cgocheck=2.  Issue #23435.
+		name:    "deadline",
+		c:       `#define US 10`,
+		imports: []string{"os", "time"},
+		body:    `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
+		fail:    false,
+	},
+}
+
+func TestPointerChecks(t *testing.T) {
+	for _, pt := range ptrTests {
+		pt := pt
+		t.Run(pt.name, func(t *testing.T) {
+			testOne(t, pt)
+		})
+	}
+}
+
+func testOne(t *testing.T, pt ptrTest) {
+	t.Parallel()
+
+	gopath, err := ioutil.TempDir("", filepath.Base(t.Name()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(gopath)
+
+	src := filepath.Join(gopath, "src")
+	if err := os.Mkdir(src, 0777); err != nil {
+		t.Fatal(err)
+	}
+
+	name := filepath.Join(src, fmt.Sprintf("%s.go", filepath.Base(t.Name())))
+	f, err := os.Create(name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	b := bufio.NewWriter(f)
+	fmt.Fprintln(b, `package main`)
+	fmt.Fprintln(b)
+	fmt.Fprintln(b, `/*`)
+	fmt.Fprintln(b, pt.c)
+	fmt.Fprintln(b, `*/`)
+	fmt.Fprintln(b, `import "C"`)
+	fmt.Fprintln(b)
+	for _, imp := range pt.imports {
+		fmt.Fprintln(b, `import "`+imp+`"`)
+	}
+	if len(pt.imports) > 0 {
+		fmt.Fprintln(b)
+	}
+	if len(pt.support) > 0 {
+		fmt.Fprintln(b, pt.support)
+		fmt.Fprintln(b)
+	}
+	fmt.Fprintln(b, `func main() {`)
+	fmt.Fprintln(b, pt.body)
+	fmt.Fprintln(b, `}`)
+
+	if err := b.Flush(); err != nil {
+		t.Fatalf("flushing %s: %v", name, err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatalf("closing %s: %v", name, err)
+	}
+
+	for _, e := range pt.extra {
+		if err := ioutil.WriteFile(filepath.Join(src, e.name), []byte(e.contents), 0644); err != nil {
+			t.Fatalf("writing %s: %v", e.name, err)
+		}
+	}
+
+	args := func(cmd *exec.Cmd) string {
+		return strings.Join(cmd.Args, " ")
+	}
+
+	cmd := exec.Command("go", "build")
+	cmd.Dir = src
+	cmd.Env = addEnv("GOPATH", gopath)
+	buf, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Logf("%#q:\n%s", args(cmd), buf)
+		t.Fatalf("failed to build: %v", err)
+	}
+
+	exe := filepath.Join(src, filepath.Base(src))
+	cmd = exec.Command(exe)
+	cmd.Dir = src
+
+	if pt.expensive {
+		cmd.Env = cgocheckEnv("1")
+		buf, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Logf("%#q:\n%s", args(cmd), buf)
+			if pt.fail {
+				t.Fatalf("test marked expensive, but failed when not expensive: %v", err)
+			} else {
+				t.Errorf("failed unexpectedly with GODEBUG=cgocheck=1: %v", err)
+			}
+		}
+
+		cmd = exec.Command(exe)
+		cmd.Dir = src
+	}
+
+	if pt.expensive {
+		cmd.Env = cgocheckEnv("2")
+	}
+
+	buf, err = cmd.CombinedOutput()
+	if pt.fail {
+		if err == nil {
+			t.Logf("%#q:\n%s", args(cmd), buf)
+			t.Fatalf("did not fail as expected")
+		} else if !bytes.Contains(buf, []byte("Go pointer")) {
+			t.Logf("%#q:\n%s", args(cmd), buf)
+			t.Fatalf("did not print expected error (failed with %v)", err)
+		}
+	} else {
+		if err != nil {
+			t.Logf("%#q:\n%s", args(cmd), buf)
+			t.Fatalf("failed unexpectedly: %v", err)
+		}
+
+		if !pt.expensive {
+			// Make sure it passes with the expensive checks.
+			cmd := exec.Command(exe)
+			cmd.Dir = src
+			cmd.Env = cgocheckEnv("2")
+			buf, err := cmd.CombinedOutput()
+			if err != nil {
+				t.Logf("%#q:\n%s", args(cmd), buf)
+				t.Fatalf("failed unexpectedly with expensive checks: %v", err)
+			}
+		}
+	}
+
+	if pt.fail {
+		cmd = exec.Command(exe)
+		cmd.Dir = src
+		cmd.Env = cgocheckEnv("0")
+		buf, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Logf("%#q:\n%s", args(cmd), buf)
+			t.Fatalf("failed unexpectedly with GODEBUG=cgocheck=0: %v", err)
+		}
+	}
+}
+
+func cgocheckEnv(val string) []string {
+	return addEnv("GODEBUG", "cgocheck="+val)
+}
+
+func addEnv(key, val string) []string {
+	env := []string{key + "=" + val}
+	look := key + "="
+	for _, e := range os.Environ() {
+		if !strings.HasPrefix(e, look) {
+			env = append(env, e)
+		}
+	}
+	return env
+}
diff --git a/misc/cgo/errors/src/err1.go b/misc/cgo/errors/src/err1.go
new file mode 100644
index 0000000..2c232cf
--- /dev/null
+++ b/misc/cgo/errors/src/err1.go
@@ -0,0 +1,18 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+/*
+#cgo LDFLAGS: -L/nonexist
+
+void test() {
+	xxx;		// ERROR HERE
+}
+*/
+import "C"
+
+func main() {
+	C.test()
+}
diff --git a/misc/cgo/errors/err2.go b/misc/cgo/errors/src/err2.go
similarity index 100%
rename from misc/cgo/errors/err2.go
rename to misc/cgo/errors/src/err2.go
diff --git a/misc/cgo/errors/err3.go b/misc/cgo/errors/src/err3.go
similarity index 100%
rename from misc/cgo/errors/err3.go
rename to misc/cgo/errors/src/err3.go
diff --git a/misc/cgo/errors/src/err4.go b/misc/cgo/errors/src/err4.go
new file mode 100644
index 0000000..8e5f78e
--- /dev/null
+++ b/misc/cgo/errors/src/err4.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+/*
+long double x = 0;
+*/
+import "C"
+
+func main() {
+	_ = C.x // ERROR HERE
+	_ = C.x
+}
diff --git a/misc/cgo/errors/issue11097a.go b/misc/cgo/errors/src/issue11097a.go
similarity index 100%
rename from misc/cgo/errors/issue11097a.go
rename to misc/cgo/errors/src/issue11097a.go
diff --git a/misc/cgo/errors/issue11097b.go b/misc/cgo/errors/src/issue11097b.go
similarity index 100%
rename from misc/cgo/errors/issue11097b.go
rename to misc/cgo/errors/src/issue11097b.go
diff --git a/misc/cgo/errors/src/issue13129.go b/misc/cgo/errors/src/issue13129.go
new file mode 100644
index 0000000..057bce4
--- /dev/null
+++ b/misc/cgo/errors/src/issue13129.go
@@ -0,0 +1,14 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 13129: used to output error about C.unsignedshort with CC=clang
+
+package main
+
+import "C"
+
+func main() {
+	var x C.ushort
+	x = int(0) // ERROR HERE: C\.ushort
+}
diff --git a/misc/cgo/errors/issue13423.go b/misc/cgo/errors/src/issue13423.go
similarity index 100%
rename from misc/cgo/errors/issue13423.go
rename to misc/cgo/errors/src/issue13423.go
diff --git a/misc/cgo/errors/src/issue13467.go b/misc/cgo/errors/src/issue13467.go
new file mode 100644
index 0000000..e061880
--- /dev/null
+++ b/misc/cgo/errors/src/issue13467.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+/*
+static int transform(int x) { return x; }
+*/
+import "C"
+
+func F() {
+	var x rune = '✈'
+	var _ rune = C.transform(x) // ERROR HERE: C\.int
+}
diff --git a/misc/cgo/errors/src/issue13635.go b/misc/cgo/errors/src/issue13635.go
new file mode 100644
index 0000000..3f38f5d
--- /dev/null
+++ b/misc/cgo/errors/src/issue13635.go
@@ -0,0 +1,24 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 13635: used to output error about C.unsignedchar.
+// This test tests all such types.
+
+package pkg
+
+import "C"
+
+func main() {
+	var (
+		_ C.uchar         = "uc"  // ERROR HERE: C\.uchar
+		_ C.schar         = "sc"  // ERROR HERE: C\.schar
+		_ C.ushort        = "us"  // ERROR HERE: C\.ushort
+		_ C.uint          = "ui"  // ERROR HERE: C\.uint
+		_ C.ulong         = "ul"  // ERROR HERE: C\.ulong
+		_ C.longlong      = "ll"  // ERROR HERE: C\.longlong
+		_ C.ulonglong     = "ull" // ERROR HERE: C\.ulonglong
+		_ C.complexfloat  = "cf"  // ERROR HERE: C\.complexfloat
+		_ C.complexdouble = "cd"  // ERROR HERE: C\.complexdouble
+	)
+}
diff --git a/misc/cgo/errors/issue13830.go b/misc/cgo/errors/src/issue13830.go
similarity index 100%
rename from misc/cgo/errors/issue13830.go
rename to misc/cgo/errors/src/issue13830.go
diff --git a/misc/cgo/errors/issue14669.go b/misc/cgo/errors/src/issue14669.go
similarity index 100%
rename from misc/cgo/errors/issue14669.go
rename to misc/cgo/errors/src/issue14669.go
diff --git a/misc/cgo/errors/issue16116.go b/misc/cgo/errors/src/issue16116.go
similarity index 100%
rename from misc/cgo/errors/issue16116.go
rename to misc/cgo/errors/src/issue16116.go
diff --git a/misc/cgo/errors/issue16591.go b/misc/cgo/errors/src/issue16591.go
similarity index 100%
rename from misc/cgo/errors/issue16591.go
rename to misc/cgo/errors/src/issue16591.go
diff --git a/misc/cgo/errors/src/issue18452.go b/misc/cgo/errors/src/issue18452.go
new file mode 100644
index 0000000..0386d76
--- /dev/null
+++ b/misc/cgo/errors/src/issue18452.go
@@ -0,0 +1,18 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 18452: show pos info in undefined name errors
+
+package p
+
+import (
+	"C"
+	"fmt"
+)
+
+func a() {
+	fmt.Println("Hello, world!")
+	C.function_that_does_not_exist() // ERROR HERE
+	C.pi                             // ERROR HERE
+}
diff --git a/misc/cgo/errors/issue18889.go b/misc/cgo/errors/src/issue18889.go
similarity index 100%
rename from misc/cgo/errors/issue18889.go
rename to misc/cgo/errors/src/issue18889.go
diff --git a/misc/cgo/errors/issue7757.go b/misc/cgo/errors/src/issue7757.go
similarity index 100%
rename from misc/cgo/errors/issue7757.go
rename to misc/cgo/errors/src/issue7757.go
diff --git a/misc/cgo/errors/issue8442.go b/misc/cgo/errors/src/issue8442.go
similarity index 100%
rename from misc/cgo/errors/issue8442.go
rename to misc/cgo/errors/src/issue8442.go
diff --git a/misc/cgo/errors/src/long_double_size.go b/misc/cgo/errors/src/long_double_size.go
new file mode 100644
index 0000000..8b797f8
--- /dev/null
+++ b/misc/cgo/errors/src/long_double_size.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+/*
+const int sizeofLongDouble = sizeof(long double);
+*/
+import "C"
+
+import "fmt"
+
+func main() {
+	fmt.Println(C.sizeofLongDouble)
+}
diff --git a/misc/cgo/errors/malloc.go b/misc/cgo/errors/src/malloc.go
similarity index 100%
rename from misc/cgo/errors/malloc.go
rename to misc/cgo/errors/src/malloc.go
diff --git a/misc/cgo/errors/test.bash b/misc/cgo/errors/test.bash
deleted file mode 100755
index ed0b094..0000000
--- a/misc/cgo/errors/test.bash
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env bash
-
-# 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.
-
-check() {
-	file=$1
-	line=$(grep -n 'ERROR HERE' $file | sed 's/:.*//')
-	if [ "$line" = "" ]; then
-		echo 1>&2 misc/cgo/errors/test.bash: BUG: cannot find ERROR HERE in $file
-		exit 1
-	fi
-	expect $file $file:$line:
-}
-
-expect() {
-	file=$1
-	shift
-	if go build -gcflags=-C $file >errs 2>&1; then
-		echo 1>&2 misc/cgo/errors/test.bash: BUG: expected cgo to fail on $file but it succeeded
-		exit 1
-	fi
-	if ! test -s errs; then
-		echo 1>&2 misc/cgo/errors/test.bash: BUG: expected error output for $file but saw none
-		exit 1
-	fi
-	for error; do
-		if ! fgrep $error errs >/dev/null 2>&1; then
-			echo 1>&2 misc/cgo/errors/test.bash: BUG: expected error output for $file to contain \"$error\" but saw:
-			cat 1>&2 errs
-			exit 1
-		fi
-	done
-}
-
-check err1.go
-check err2.go
-check err3.go
-check issue7757.go
-check issue8442.go
-check issue11097a.go
-check issue11097b.go
-expect issue13129.go C.ushort
-check issue13423.go
-expect issue13635.go C.uchar C.schar C.ushort C.uint C.ulong C.longlong C.ulonglong C.complexfloat C.complexdouble
-check issue13830.go
-check issue16116.go
-check issue16591.go
-check issue18889.go
-expect issue18452.go issue18452.go:16 issue18452.go:17
-
-if ! go build issue14669.go; then
-	exit 1
-fi
-if ! CGO_CFLAGS="-O" go build issue14669.go; then
-	exit 1
-fi
-
-if ! go run ptr.go; then
-	exit 1
-fi
-
-# The malloc.go test should crash.
-rm -f malloc.out
-if go run malloc.go >malloc.out 2>&1; then
-	echo '`go run malloc.go` succeeded unexpectedly'
-	cat malloc.out
-	rm -f malloc.out
-	exit 1
-fi
-rm -f malloc.out
-
-rm -rf errs _obj
-exit 0
diff --git a/misc/cgo/life/main.go b/misc/cgo/life/main.go
index aa2f6d1..45376fd 100644
--- a/misc/cgo/life/main.go
+++ b/misc/cgo/life/main.go
@@ -1,4 +1,4 @@
-// cmpout
+// cmpout -tags=use_go_run
 
 // Copyright 2010 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -11,9 +11,10 @@
 package main
 
 import (
-	"."
 	"flag"
 	"fmt"
+
+	"."
 )
 
 const MAXDIM = 100
diff --git a/misc/cgo/stdio/chain.go b/misc/cgo/stdio/chain.go
index 03cddb7..0fa813c 100644
--- a/misc/cgo/stdio/chain.go
+++ b/misc/cgo/stdio/chain.go
@@ -1,4 +1,4 @@
-// cmpout
+// cmpout -tags=use_go_run
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/misc/cgo/stdio/fib.go b/misc/cgo/stdio/fib.go
index 61a1b83..56e3255 100644
--- a/misc/cgo/stdio/fib.go
+++ b/misc/cgo/stdio/fib.go
@@ -1,4 +1,4 @@
-// cmpout
+// cmpout -tags=use_go_run
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/misc/cgo/stdio/hello.go b/misc/cgo/stdio/hello.go
index 47179ba..63bff4c 100644
--- a/misc/cgo/stdio/hello.go
+++ b/misc/cgo/stdio/hello.go
@@ -1,4 +1,4 @@
-// cmpout
+// cmpout -tags=use_go_run
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/misc/cgo/test/buildid_linux.go b/misc/cgo/test/buildid_linux.go
index 47dd871..84d3edb 100644
--- a/misc/cgo/test/buildid_linux.go
+++ b/misc/cgo/test/buildid_linux.go
@@ -27,6 +27,7 @@
 	defer f.Close()
 
 	c := 0
+sections:
 	for i, s := range f.Sections {
 		if s.Type != elf.SHT_NOTE {
 			continue
@@ -47,7 +48,7 @@
 
 			if len(d) < 12 {
 				t.Logf("note section %d too short (%d < 12)", i, len(d))
-				continue
+				continue sections
 			}
 
 			namesz := f.ByteOrder.Uint32(d)
@@ -59,7 +60,7 @@
 
 			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
+				continue sections
 			}
 
 			// 3 == NT_GNU_BUILD_ID
diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go
index f7cf6f6..cfacb9c 100644
--- a/misc/cgo/test/cgo_test.go
+++ b/misc/cgo/test/cgo_test.go
@@ -80,5 +80,12 @@
 func Test18720(t *testing.T)                 { test18720(t) }
 func Test20266(t *testing.T)                 { test20266(t) }
 func Test20129(t *testing.T)                 { test20129(t) }
+func Test20910(t *testing.T)                 { test20910(t) }
+func Test21708(t *testing.T)                 { test21708(t) }
+func Test21809(t *testing.T)                 { test21809(t) }
+func Test6907(t *testing.T)                  { test6907(t) }
+func Test6907Go(t *testing.T)                { test6907Go(t) }
+func Test21897(t *testing.T)                 { test21897(t) }
+func Test22906(t *testing.T)                 { test22906(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/issue18720.go b/misc/cgo/test/issue18720.go
index a933044..3d64003 100644
--- a/misc/cgo/test/issue18720.go
+++ b/misc/cgo/test/issue18720.go
@@ -12,13 +12,39 @@
 struct foo { char c; };
 #define SIZE_OF(x) sizeof(x)
 #define SIZE_OF_FOO SIZE_OF(struct foo)
+#define VAR1 VAR
+#define VAR var
+int var = 5;
+
+#define ADDR &var
+
+#define CALL fn()
+int fn(void) {
+	return ++var;
+}
 */
 import "C"
 import "testing"
 
 func test18720(t *testing.T) {
-	if C.HELLO_WORLD != "hello\000world" {
-		t.Fatalf(`expected "hello\000world", but got %q`, C.HELLO_WORLD)
+	if got, want := C.HELLO_WORLD, "hello\000world"; got != want {
+		t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want)
+	}
+
+	if got, want := C.VAR1, C.int(5); got != want {
+		t.Errorf("C.VAR1 == %v, expected %v", got, want)
+	}
+
+	if got, want := *C.ADDR, C.int(5); got != want {
+		t.Errorf("*C.ADDR == %v, expected %v", got, want)
+	}
+
+	if got, want := C.CALL, C.int(6); got != want {
+		t.Errorf("C.CALL == %v, expected %v", got, want)
+	}
+
+	if got, want := C.CALL, C.int(7); got != want {
+		t.Errorf("C.CALL == %v, expected %v", got, want)
 	}
 
 	// Issue 20125.
diff --git a/misc/cgo/test/issue20910.c b/misc/cgo/test/issue20910.c
new file mode 100644
index 0000000..e8d623f
--- /dev/null
+++ b/misc/cgo/test/issue20910.c
@@ -0,0 +1,19 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "_cgo_export.h"
+
+/* Test calling a Go function with multiple return values.  */
+
+void
+callMulti(void)
+{
+	struct multi_return result = multi();
+	assert(strcmp(result.r0, "multi") == 0);
+	assert(result.r1 == 0);
+	free(result.r0);
+}
diff --git a/misc/cgo/test/issue20910.go b/misc/cgo/test/issue20910.go
new file mode 100644
index 0000000..69d7d92
--- /dev/null
+++ b/misc/cgo/test/issue20910.go
@@ -0,0 +1,19 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+//void callMulti(void);
+import "C"
+
+import "testing"
+
+//export multi
+func multi() (*C.char, C.int) {
+	return C.CString("multi"), 0
+}
+
+func test20910(t *testing.T) {
+	C.callMulti()
+}
diff --git a/misc/cgo/test/issue21668.go b/misc/cgo/test/issue21668.go
new file mode 100644
index 0000000..f15b920
--- /dev/null
+++ b/misc/cgo/test/issue21668.go
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fail to guess the kind of the constant "x".
+// No runtime test; just make sure it compiles.
+
+package cgotest
+
+// const int x = 42;
+import "C"
+
+var issue21668_X = C.x
diff --git a/misc/cgo/test/issue21708.go b/misc/cgo/test/issue21708.go
new file mode 100644
index 0000000..d413e3c
--- /dev/null
+++ b/misc/cgo/test/issue21708.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+// #include <stdint.h>
+// #define CAST_TO_INT64 (int64_t)(-1)
+import "C"
+import "testing"
+
+func test21708(t *testing.T) {
+	if got, want := C.CAST_TO_INT64, -1; got != want {
+		t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want)
+	}
+}
diff --git a/misc/cgo/test/issue21809.go b/misc/cgo/test/issue21809.go
new file mode 100644
index 0000000..a3a6b88
--- /dev/null
+++ b/misc/cgo/test/issue21809.go
@@ -0,0 +1,45 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+// Issue 21809.  Compile C `typedef` to go type aliases.
+
+// typedef long MySigned_t;
+// /* tests alias-to-alias */
+// typedef MySigned_t MySigned2_t;
+//
+// long takes_long(long x) { return x * x; }
+// MySigned_t takes_typedef(MySigned_t x) { return x * x; }
+import "C"
+
+import "testing"
+
+func test21809(t *testing.T) {
+	longVar := C.long(3)
+	typedefVar := C.MySigned_t(4)
+	typedefTypedefVar := C.MySigned2_t(5)
+
+	// all three should be considered identical to `long`
+	if ret := C.takes_long(longVar); ret != 9 {
+		t.Errorf("got %v but expected %v", ret, 9)
+	}
+	if ret := C.takes_long(typedefVar); ret != 16 {
+		t.Errorf("got %v but expected %v", ret, 16)
+	}
+	if ret := C.takes_long(typedefTypedefVar); ret != 25 {
+		t.Errorf("got %v but expected %v", ret, 25)
+	}
+
+	// They should also be identical to the typedef'd type
+	if ret := C.takes_typedef(longVar); ret != 9 {
+		t.Errorf("got %v but expected %v", ret, 9)
+	}
+	if ret := C.takes_typedef(typedefVar); ret != 16 {
+		t.Errorf("got %v but expected %v", ret, 16)
+	}
+	if ret := C.takes_typedef(typedefTypedefVar); ret != 25 {
+		t.Errorf("got %v but expected %v", ret, 25)
+	}
+}
diff --git a/misc/cgo/test/issue21897.go b/misc/cgo/test/issue21897.go
new file mode 100644
index 0000000..d13246b
--- /dev/null
+++ b/misc/cgo/test/issue21897.go
@@ -0,0 +1,56 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin,cgo,!internal
+
+package cgotest
+
+/*
+#cgo LDFLAGS: -framework CoreFoundation
+#include <CoreFoundation/CoreFoundation.h>
+*/
+import "C"
+import (
+	"runtime/debug"
+	"testing"
+	"unsafe"
+)
+
+func test21897(t *testing.T) {
+	// Please write barrier, kick in soon.
+	defer debug.SetGCPercent(debug.SetGCPercent(1))
+
+	for i := 0; i < 10000; i++ {
+		testCFNumberRef()
+		testCFDateRef()
+		testCFBooleanRef()
+		// Allocate some memory, so eventually the write barrier is enabled
+		// and it will see writes of bad pointers in the test* functions below.
+		byteSliceSink = make([]byte, 1024)
+	}
+}
+
+var byteSliceSink []byte
+
+func testCFNumberRef() {
+	var v int64 = 0
+	xCFNumberRef = C.CFNumberCreate(C.kCFAllocatorSystemDefault, C.kCFNumberSInt64Type, unsafe.Pointer(&v))
+	//fmt.Printf("CFNumberRef: %x\n", uintptr(unsafe.Pointer(xCFNumberRef)))
+}
+
+var xCFNumberRef C.CFNumberRef
+
+func testCFDateRef() {
+	xCFDateRef = C.CFDateCreate(C.kCFAllocatorSystemDefault, 0) // 0 value is 1 Jan 2001 00:00:00 GMT
+	//fmt.Printf("CFDateRef: %x\n", uintptr(unsafe.Pointer(xCFDateRef)))
+}
+
+var xCFDateRef C.CFDateRef
+
+func testCFBooleanRef() {
+	xCFBooleanRef = C.kCFBooleanFalse
+	//fmt.Printf("CFBooleanRef: %x\n", uintptr(unsafe.Pointer(xCFBooleanRef)))
+}
+
+var xCFBooleanRef C.CFBooleanRef
diff --git a/misc/cgo/test/issue21897b.go b/misc/cgo/test/issue21897b.go
new file mode 100644
index 0000000..08b5f4d
--- /dev/null
+++ b/misc/cgo/test/issue21897b.go
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin !cgo internal
+
+package cgotest
+
+import "testing"
+
+func test21897(t *testing.T) {
+	t.Skip("test runs only on darwin+cgo")
+}
diff --git a/misc/cgo/test/issue22958.go b/misc/cgo/test/issue22958.go
new file mode 100644
index 0000000..a5f058f
--- /dev/null
+++ b/misc/cgo/test/issue22958.go
@@ -0,0 +1,24 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+// Test handling of bitfields.
+
+/*
+typedef struct {
+	unsigned long long f8  : 8;
+	unsigned long long f16 : 16;
+	unsigned long long f24 : 24;
+	unsigned long long f32 : 32;
+	unsigned long long f40 : 40;
+	unsigned long long f48 : 48;
+	unsigned long long f56 : 56;
+	unsigned long long f64 : 64;
+} issue22958Type;
+*/
+import "C"
+
+// Nothing to run, just make sure this compiles.
+var Vissue22958 C.issue22958Type
diff --git a/misc/cgo/test/issue4029.c b/misc/cgo/test/issue4029.c
index eab3683..7205c5a 100644
--- a/misc/cgo/test/issue4029.c
+++ b/misc/cgo/test/issue4029.c
@@ -4,6 +4,25 @@
 
 // +build !windows
 
+#include <stdint.h>
+#include <dlfcn.h>
+
+// Write our own versions of dlopen/dlsym/dlclose so that we represent
+// the opaque handle as a Go uintptr rather than a Go pointer to avoid
+// garbage collector confusion.  See issue 23663.
+
+uintptr_t dlopen4029(char* name, int flags) {
+	return (uintptr_t)(dlopen(name, flags));
+}
+
+uintptr_t dlsym4029(uintptr_t handle, char* name) {
+	return (uintptr_t)(dlsym((void*)(handle), name));
+}
+
+int dlclose4029(uintptr_t handle) {
+	return dlclose((void*)(handle));
+}
+
 void call4029(void *arg) {
 	void (*fn)(void) = arg;
 	fn();
diff --git a/misc/cgo/test/issue4029.go b/misc/cgo/test/issue4029.go
index 5789b99..8e468d3 100644
--- a/misc/cgo/test/issue4029.go
+++ b/misc/cgo/test/issue4029.go
@@ -7,10 +7,15 @@
 package cgotest
 
 /*
+#include <stdint.h>
 #include <dlfcn.h>
 #cgo linux LDFLAGS: -ldl
 
-extern void call4029(void *arg);
+extern uintptr_t dlopen4029(char*, int);
+extern uintptr_t dlsym4029(uintptr_t, char*);
+extern int dlclose4029(uintptr_t);
+
+extern void call4029(uintptr_t arg);
 */
 import "C"
 
@@ -51,15 +56,15 @@
 }
 
 func loadThySelf(t *testing.T, symbol string) {
-	this_process := C.dlopen(nil, C.RTLD_NOW)
-	if this_process == nil {
+	this_process := C.dlopen4029(nil, C.RTLD_NOW)
+	if this_process == 0 {
 		t.Error("dlopen:", C.GoString(C.dlerror()))
 		return
 	}
-	defer C.dlclose(this_process)
+	defer C.dlclose4029(this_process)
 
-	symbol_address := C.dlsym(this_process, C.CString(symbol))
-	if symbol_address == nil {
+	symbol_address := C.dlsym4029(this_process, C.CString(symbol))
+	if symbol_address == 0 {
 		t.Error("dlsym:", C.GoString(C.dlerror()))
 		return
 	}
diff --git a/misc/cgo/test/issue6907.go b/misc/cgo/test/issue6907.go
new file mode 100644
index 0000000..00495ab
--- /dev/null
+++ b/misc/cgo/test/issue6907.go
@@ -0,0 +1,33 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+/*
+#include <stdlib.h>
+#include <string.h>
+
+char* Issue6907CopyString(_GoString_ s) {
+	size_t n;
+	const char *p;
+	char *r;
+
+	n = _GoStringLen(s);
+	p = _GoStringPtr(s);
+	r = malloc(n + 1);
+	memmove(r, p, n);
+	r[n] = '\0';
+	return r;
+}
+*/
+import "C"
+
+import "testing"
+
+func test6907(t *testing.T) {
+	want := "yarn"
+	if got := C.GoString(C.Issue6907CopyString(want)); got != want {
+		t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want)
+	}
+}
diff --git a/misc/cgo/test/issue6907export.go b/misc/cgo/test/issue6907export.go
new file mode 100644
index 0000000..d41899e
--- /dev/null
+++ b/misc/cgo/test/issue6907export.go
@@ -0,0 +1,30 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+/*
+extern int CheckIssue6907C(_GoString_);
+*/
+import "C"
+
+import (
+	"testing"
+)
+
+const CString = "C string"
+
+//export CheckIssue6907Go
+func CheckIssue6907Go(s string) C.int {
+	if s == CString {
+		return 1
+	}
+	return 0
+}
+
+func test6907Go(t *testing.T) {
+	if got := C.CheckIssue6907C(CString); got != 1 {
+		t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
+	}
+}
diff --git a/misc/cgo/test/issue6907export_c.c b/misc/cgo/test/issue6907export_c.c
new file mode 100644
index 0000000..9b1a4fc
--- /dev/null
+++ b/misc/cgo/test/issue6907export_c.c
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <string.h>
+
+#include "_cgo_export.h"
+
+int CheckIssue6907C(_GoString_ s) {
+	return CheckIssue6907Go(s);
+}
diff --git a/misc/cgo/test/issue7978.go b/misc/cgo/test/issue7978.go
index 7fb62e8..b057e3e 100644
--- a/misc/cgo/test/issue7978.go
+++ b/misc/cgo/test/issue7978.go
@@ -44,8 +44,8 @@
 import "C"
 
 import (
-	"os"
 	"runtime"
+	"runtime/debug"
 	"strings"
 	"sync/atomic"
 	"testing"
@@ -114,12 +114,7 @@
 	if C.HAS_SYNC_FETCH_AND_ADD == 0 {
 		t.Skip("clang required for __sync_fetch_and_add support on darwin/arm")
 	}
-	if runtime.GOOS == "android" || runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
-		t.Skip("GOTRACEBACK is not passed on to the exec wrapper")
-	}
-	if os.Getenv("GOTRACEBACK") != "2" {
-		t.Fatalf("GOTRACEBACK must be 2")
-	}
+	debug.SetTraceback("2")
 	issue7978sync = 0
 	go issue7978go()
 	// test in c code, before callback
diff --git a/misc/cgo/test/test22906.go b/misc/cgo/test/test22906.go
new file mode 100644
index 0000000..02bae9c
--- /dev/null
+++ b/misc/cgo/test/test22906.go
@@ -0,0 +1,74 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+
+package cgotest
+
+/*
+
+// It's going to be hard to include a whole real JVM to test this.
+// So we'll simulate a really easy JVM using just the parts we need.
+
+// This is the relevant part of jni.h.
+
+struct _jobject;
+
+typedef struct _jobject *jobject;
+typedef jobject jclass;
+typedef jobject jthrowable;
+typedef jobject jstring;
+typedef jobject jarray;
+typedef jarray jbooleanArray;
+typedef jarray jbyteArray;
+typedef jarray jcharArray;
+typedef jarray jshortArray;
+typedef jarray jintArray;
+typedef jarray jlongArray;
+typedef jarray jfloatArray;
+typedef jarray jdoubleArray;
+typedef jarray jobjectArray;
+
+typedef jobject jweak;
+
+// Note: jvalue is already a non-pointer type due to it being a C union.
+
+*/
+import "C"
+import (
+	"testing"
+)
+
+func test22906(t *testing.T) {
+	var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
+	_ = x1
+	var x2 C.jclass = 0
+	_ = x2
+	var x3 C.jthrowable = 0
+	_ = x3
+	var x4 C.jstring = 0
+	_ = x4
+	var x5 C.jarray = 0
+	_ = x5
+	var x6 C.jbooleanArray = 0
+	_ = x6
+	var x7 C.jbyteArray = 0
+	_ = x7
+	var x8 C.jcharArray = 0
+	_ = x8
+	var x9 C.jshortArray = 0
+	_ = x9
+	var x10 C.jintArray = 0
+	_ = x10
+	var x11 C.jlongArray = 0
+	_ = x11
+	var x12 C.jfloatArray = 0
+	_ = x12
+	var x13 C.jdoubleArray = 0
+	_ = x13
+	var x14 C.jobjectArray = 0
+	_ = x14
+	var x15 C.jweak = 0
+	_ = x15
+}
diff --git a/misc/cgo/testcarchive/carchive_test.go b/misc/cgo/testcarchive/carchive_test.go
index 74897c7..7963365 100644
--- a/misc/cgo/testcarchive/carchive_test.go
+++ b/misc/cgo/testcarchive/carchive_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"debug/elf"
 	"fmt"
 	"io/ioutil"
@@ -134,8 +135,10 @@
 }
 
 func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
+	t.Helper()
 	cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
 	cmd.Env = gopathEnv
+	t.Log(buildcmd)
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -171,7 +174,7 @@
 	testInstall(t, "./testp1"+exeSuffix,
 		filepath.Join("pkg", libgodir, "libgo.a"),
 		filepath.Join("pkg", libgodir, "libgo.h"),
-		"go", "install", "-buildmode=c-archive", "libgo")
+		"go", "install", "-i", "-buildmode=c-archive", "libgo")
 
 	// Test building libgo other than installing it.
 	// Header files are now present.
@@ -488,7 +491,7 @@
 		os.RemoveAll("pkg")
 	}()
 
-	cmd := exec.Command("go", "install", "-buildmode=c-archive", "libgo")
+	cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "libgo")
 	cmd.Env = gopathEnv
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("%s", out)
@@ -549,6 +552,8 @@
 	switch GOOS {
 	case "windows", "plan9":
 		t.Skipf("skipping SIGPROF test on %s", GOOS)
+	case "darwin":
+		t.Skipf("skipping SIGPROF test on %s; see https://golang.org/issue/19320", GOOS)
 	}
 
 	t.Parallel()
@@ -605,9 +610,26 @@
 	}
 
 	exe := "./testnoshared" + exeSuffix
-	ccArgs := append(cc, "-o", exe, "main5.c", "libgo2.a")
+
+	// In some cases, -no-pie is needed here, but not accepted everywhere. First try
+	// if -no-pie is accepted. See #22126.
+	ccArgs := append(cc, "-o", exe, "-no-pie", "main5.c", "libgo2.a")
 	t.Log(ccArgs)
 	out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
+
+	// If -no-pie unrecognized, try -nopie if this is possibly clang
+	if err != nil && bytes.Contains(out, []byte("unknown")) && !strings.Contains(cc[0], "gcc") {
+		ccArgs = append(cc, "-o", exe, "-nopie", "main5.c", "libgo2.a")
+		t.Log(ccArgs)
+		out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
+	}
+
+	// Don't use either -no-pie or -nopie
+	if err != nil && bytes.Contains(out, []byte("unrecognized")) {
+		ccArgs := append(cc, "-o", exe, "main5.c", "libgo2.a")
+		t.Log(ccArgs)
+		out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
+	}
 	t.Logf("%s", out)
 	if err != nil {
 		t.Fatal(err)
@@ -620,3 +642,50 @@
 	t.Logf("%s", out)
 	expectSignal(t, err, syscall.SIGPIPE)
 }
+
+// Test that installing a second time recreates the header files.
+func TestCachedInstall(t *testing.T) {
+	defer os.RemoveAll("pkg")
+
+	h1 := filepath.Join("pkg", libgodir, "libgo.h")
+	h2 := filepath.Join("pkg", libgodir, "p.h")
+
+	buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"}
+
+	cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
+	cmd.Env = gopathEnv
+	t.Log(buildcmd)
+	if out, err := cmd.CombinedOutput(); err != nil {
+		t.Logf("%s", out)
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(h1); err != nil {
+		t.Errorf("libgo.h not installed: %v", err)
+	}
+	if _, err := os.Stat(h2); err != nil {
+		t.Errorf("p.h not installed: %v", err)
+	}
+
+	if err := os.Remove(h1); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.Remove(h2); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
+	cmd.Env = gopathEnv
+	t.Log(buildcmd)
+	if out, err := cmd.CombinedOutput(); err != nil {
+		t.Logf("%s", out)
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(h1); err != nil {
+		t.Errorf("libgo.h not installed in second run: %v", err)
+	}
+	if _, err := os.Stat(h2); err != nil {
+		t.Errorf("p.h not installed in second run: %v", err)
+	}
+}
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
new file mode 100644
index 0000000..e43422d
--- /dev/null
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -0,0 +1,586 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cshared_test
+
+import (
+	"debug/elf"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"strings"
+	"sync"
+	"testing"
+	"unicode"
+)
+
+// C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)).
+var cc []string
+
+// An environment with GOPATH=$(pwd).
+var gopathEnv []string
+
+// ".exe" on Windows.
+var exeSuffix string
+
+var GOOS, GOARCH, GOROOT string
+var installdir, androiddir string
+var libSuffix, libgoname string
+
+func TestMain(m *testing.M) {
+	GOOS = goEnv("GOOS")
+	GOARCH = goEnv("GOARCH")
+	GOROOT = goEnv("GOROOT")
+
+	if _, err := os.Stat(GOROOT); os.IsNotExist(err) {
+		log.Fatalf("Unable able to find GOROOT at '%s'", GOROOT)
+	}
+
+	// Directory where cgo headers and outputs will be installed.
+	// The installation directory format varies depending on the platform.
+	installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared", GOOS, GOARCH))
+	switch GOOS {
+	case "darwin":
+		libSuffix = "dylib"
+	case "windows":
+		libSuffix = "dll"
+	default:
+		libSuffix = "so"
+		installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared_shared", GOOS, GOARCH))
+	}
+
+	androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
+	if GOOS == "android" {
+		args := append(adbCmd(), "shell", "mkdir", "-p", androiddir)
+		cmd := exec.Command(args[0], args[1:]...)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			log.Fatalf("setupAndroid failed: %v\n%s\n", err, out)
+		}
+	}
+
+	libgoname = "libgo." + libSuffix
+
+	cc = []string{goEnv("CC")}
+
+	out := goEnv("GOGCCFLAGS")
+	quote := '\000'
+	start := 0
+	lastSpace := true
+	backslash := false
+	s := string(out)
+	for i, c := range s {
+		if quote == '\000' && unicode.IsSpace(c) {
+			if !lastSpace {
+				cc = append(cc, s[start:i])
+				lastSpace = true
+			}
+		} else {
+			if lastSpace {
+				start = i
+				lastSpace = false
+			}
+			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
+				quote = c
+				backslash = false
+			} else if !backslash && quote == c {
+				quote = '\000'
+			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
+				backslash = true
+			} else {
+				backslash = false
+			}
+		}
+	}
+	if !lastSpace {
+		cc = append(cc, s[start:])
+	}
+
+	switch GOOS {
+	case "darwin":
+		// For Darwin/ARM.
+		// TODO(crawshaw): can we do better?
+		cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
+	case "android":
+		cc = append(cc, "-pie", "-fuse-ld=gold")
+	}
+	libgodir := GOOS + "_" + GOARCH
+	switch GOOS {
+	case "darwin":
+		if GOARCH == "arm" || GOARCH == "arm64" {
+			libgodir += "_shared"
+		}
+	case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
+		libgodir += "_shared"
+	}
+	cc = append(cc, "-I", filepath.Join("pkg", libgodir))
+
+	// Build an environment with GOPATH=$(pwd)
+	dir, err := os.Getwd()
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	gopathEnv = append(os.Environ(), "GOPATH="+dir)
+
+	if GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+
+	st := m.Run()
+
+	os.Remove(libgoname)
+	os.RemoveAll("pkg")
+	cleanupHeaders()
+	cleanupAndroid()
+
+	os.Exit(st)
+}
+
+func goEnv(key string) string {
+	out, err := exec.Command("go", "env", key).Output()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "go env %s failed:\n%s", key, err)
+		fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr)
+		os.Exit(2)
+	}
+	return strings.TrimSpace(string(out))
+}
+
+func cmdToRun(name string) string {
+	return "./" + name + exeSuffix
+}
+
+func adbCmd() []string {
+	cmd := []string{"adb"}
+	if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
+		cmd = append(cmd, strings.Split(flags, " ")...)
+	}
+	return cmd
+}
+
+func adbPush(t *testing.T, filename string) {
+	if GOOS != "android" {
+		return
+	}
+	args := append(adbCmd(), "push", filename, fmt.Sprintf("%s/%s", androiddir, filename))
+	cmd := exec.Command(args[0], args[1:]...)
+	if out, err := cmd.CombinedOutput(); err != nil {
+		t.Fatalf("adb command failed: %v\n%s\n", err, out)
+	}
+}
+
+func adbRun(t *testing.T, env []string, adbargs ...string) string {
+	if GOOS != "android" {
+		t.Fatalf("trying to run adb command when operating system is not android.")
+	}
+	args := append(adbCmd(), "shell")
+	// Propagate LD_LIBRARY_PATH to the adb shell invocation.
+	for _, e := range env {
+		if strings.Index(e, "LD_LIBRARY_PATH=") != -1 {
+			adbargs = append([]string{e}, adbargs...)
+			break
+		}
+	}
+	shellcmd := fmt.Sprintf("cd %s; %s", androiddir, strings.Join(adbargs, " "))
+	args = append(args, shellcmd)
+	cmd := exec.Command(args[0], args[1:]...)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("adb command failed: %v\n%s\n", err, out)
+	}
+	return strings.Replace(string(out), "\r", "", -1)
+}
+
+func run(t *testing.T, env []string, args ...string) string {
+	t.Helper()
+	cmd := exec.Command(args[0], args[1:]...)
+	cmd.Env = env
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)
+	} else {
+		t.Logf("run: %v", args)
+	}
+	return string(out)
+}
+
+func runExe(t *testing.T, env []string, args ...string) string {
+	t.Helper()
+	if GOOS == "android" {
+		return adbRun(t, env, args...)
+	}
+	return run(t, env, args...)
+}
+
+func runCC(t *testing.T, args ...string) string {
+	t.Helper()
+	// This function is run in parallel, so append to a copy of cc
+	// rather than cc itself.
+	return run(t, nil, append(append([]string(nil), cc...), args...)...)
+}
+
+func createHeaders() error {
+	args := []string{"go", "install", "-i", "-buildmode=c-shared",
+		"-installsuffix", "testcshared", "libgo"}
+	cmd := exec.Command(args[0], args[1:]...)
+	cmd.Env = gopathEnv
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
+	}
+
+	args = []string{"go", "build", "-buildmode=c-shared",
+		"-installsuffix", "testcshared",
+		"-o", libgoname,
+		filepath.Join("src", "libgo", "libgo.go")}
+	cmd = exec.Command(args[0], args[1:]...)
+	cmd.Env = gopathEnv
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
+	}
+
+	if GOOS == "android" {
+		args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
+		cmd = exec.Command(args[0], args[1:]...)
+		out, err = cmd.CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("adb command failed: %v\n%s\n", err, out)
+		}
+	}
+
+	return nil
+}
+
+var (
+	headersOnce sync.Once
+	headersErr  error
+)
+
+func createHeadersOnce(t *testing.T) {
+	headersOnce.Do(func() {
+		headersErr = createHeaders()
+	})
+	if headersErr != nil {
+		t.Fatal(headersErr)
+	}
+}
+
+func cleanupHeaders() {
+	os.Remove("libgo.h")
+}
+
+func cleanupAndroid() {
+	if GOOS != "android" {
+		return
+	}
+	args := append(adbCmd(), "shell", "rm", "-rf", androiddir)
+	cmd := exec.Command(args[0], args[1:]...)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
+	}
+}
+
+// test0: exported symbols in shared lib are accessible.
+func TestExportedSymbols(t *testing.T) {
+	t.Parallel()
+
+	cmd := "testp0"
+	bin := cmdToRun(cmd)
+
+	createHeadersOnce(t)
+
+	runCC(t, "-I", installdir, "-o", cmd, "main0.c", libgoname)
+	adbPush(t, cmd)
+
+	defer os.Remove(bin)
+
+	out := runExe(t, append(gopathEnv, "LD_LIBRARY_PATH=."), bin)
+	if strings.TrimSpace(out) != "PASS" {
+		t.Error(out)
+	}
+}
+
+// test1: shared library can be dynamically loaded and exported symbols are accessible.
+func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
+	t.Parallel()
+
+	if GOOS == "windows" {
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+
+	cmd := "testp1"
+	bin := cmdToRun(cmd)
+
+	createHeadersOnce(t)
+
+	runCC(t, "-o", cmd, "main1.c", "-ldl")
+	adbPush(t, cmd)
+
+	defer os.Remove(bin)
+
+	out := runExe(t, nil, bin, "./"+libgoname)
+	if strings.TrimSpace(out) != "PASS" {
+		t.Error(out)
+	}
+}
+
+// test2: tests libgo2 which does not export any functions.
+func TestUnexportedSymbols(t *testing.T) {
+	t.Parallel()
+
+	if GOOS == "windows" {
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+
+	cmd := "testp2"
+	bin := cmdToRun(cmd)
+	libname := "libgo2." + libSuffix
+
+	run(t,
+		gopathEnv,
+		"go", "build",
+		"-buildmode=c-shared",
+		"-installsuffix", "testcshared",
+		"-o", libname, "libgo2",
+	)
+	adbPush(t, libname)
+
+	linkFlags := "-Wl,--no-as-needed"
+	if GOOS == "darwin" {
+		linkFlags = ""
+	}
+
+	runCC(t, "-o", cmd, "main2.c", linkFlags, libname)
+	adbPush(t, cmd)
+
+	defer os.Remove(libname)
+	defer os.Remove(bin)
+
+	out := runExe(t, append(gopathEnv, "LD_LIBRARY_PATH=."), bin)
+
+	if strings.TrimSpace(out) != "PASS" {
+		t.Error(out)
+	}
+}
+
+// test3: tests main.main is exported on android.
+func TestMainExportedOnAndroid(t *testing.T) {
+	t.Parallel()
+
+	switch GOOS {
+	case "android":
+		break
+	default:
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+
+	cmd := "testp3"
+	bin := cmdToRun(cmd)
+
+	createHeadersOnce(t)
+
+	runCC(t, "-o", cmd, "main3.c", "-ldl")
+	adbPush(t, cmd)
+
+	defer os.Remove(bin)
+
+	out := runExe(t, nil, bin, "./"+libgoname)
+	if strings.TrimSpace(out) != "PASS" {
+		t.Error(out)
+	}
+}
+
+func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
+	libname := pkgname + "." + libSuffix
+	run(t,
+		gopathEnv,
+		"go", "build",
+		"-buildmode=c-shared",
+		"-installsuffix", "testcshared",
+		"-o", libname, pkgname,
+	)
+	adbPush(t, libname)
+	runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
+	adbPush(t, cmd)
+
+	bin := cmdToRun(cmd)
+
+	defer os.Remove(libname)
+	defer os.Remove(bin)
+	defer os.Remove(pkgname + ".h")
+
+	out := runExe(t, nil, bin, "./"+libname)
+	if strings.TrimSpace(out) != "PASS" {
+		t.Error(run(t, nil, bin, libname, "verbose"))
+	}
+}
+
+// test4: test signal handlers
+func TestSignalHandlers(t *testing.T) {
+	t.Parallel()
+	if GOOS == "windows" {
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+	testSignalHandlers(t, "libgo4", "main4.c", "testp4")
+}
+
+// test5: test signal handlers with os/signal.Notify
+func TestSignalHandlersWithNotify(t *testing.T) {
+	t.Parallel()
+	if GOOS == "windows" {
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+	testSignalHandlers(t, "libgo5", "main5.c", "testp5")
+}
+
+func TestPIE(t *testing.T) {
+	t.Parallel()
+
+	switch GOOS {
+	case "linux", "android":
+		break
+	default:
+		t.Logf("Skipping on %s", GOOS)
+		return
+	}
+
+	createHeadersOnce(t)
+
+	f, err := elf.Open(libgoname)
+	if err != nil {
+		t.Fatalf("elf.Open failed: %v", err)
+	}
+	defer f.Close()
+
+	ds := f.SectionByType(elf.SHT_DYNAMIC)
+	if ds == nil {
+		t.Fatalf("no SHT_DYNAMIC section")
+	}
+	d, err := ds.Data()
+	if err != nil {
+		t.Fatalf("can't read SHT_DYNAMIC contents: %v", err)
+	}
+	for len(d) > 0 {
+		var tag elf.DynTag
+		switch f.Class {
+		case elf.ELFCLASS32:
+			tag = elf.DynTag(f.ByteOrder.Uint32(d[:4]))
+			d = d[8:]
+		case elf.ELFCLASS64:
+			tag = elf.DynTag(f.ByteOrder.Uint64(d[:8]))
+			d = d[16:]
+		}
+		if tag == elf.DT_TEXTREL {
+			t.Fatalf("%s has DT_TEXTREL flag", libgoname)
+		}
+	}
+}
+
+// Test that installing a second time recreates the header files.
+func TestCachedInstall(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "cshared")
+	if err != nil {
+		t.Fatal(err)
+	}
+	// defer os.RemoveAll(tmpdir)
+
+	copyFile(t, filepath.Join(tmpdir, "src", "libgo", "libgo.go"), filepath.Join("src", "libgo", "libgo.go"))
+	copyFile(t, filepath.Join(tmpdir, "src", "p", "p.go"), filepath.Join("src", "p", "p.go"))
+
+	env := append(os.Environ(), "GOPATH="+tmpdir)
+
+	buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "libgo"}
+
+	cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
+	cmd.Env = env
+	t.Log(buildcmd)
+	out, err := cmd.CombinedOutput()
+	t.Logf("%s", out)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var libgoh, ph string
+
+	walker := func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			t.Fatal(err)
+		}
+		var ps *string
+		switch filepath.Base(path) {
+		case "libgo.h":
+			ps = &libgoh
+		case "p.h":
+			ps = &ph
+		}
+		if ps != nil {
+			if *ps != "" {
+				t.Fatalf("%s found again", *ps)
+			}
+			*ps = path
+		}
+		return nil
+	}
+
+	if err := filepath.Walk(tmpdir, walker); err != nil {
+		t.Fatal(err)
+	}
+
+	if libgoh == "" {
+		t.Fatal("libgo.h not installed")
+	}
+	if ph == "" {
+		t.Fatal("p.h not installed")
+	}
+
+	if err := os.Remove(libgoh); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.Remove(ph); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
+	cmd.Env = env
+	t.Log(buildcmd)
+	out, err = cmd.CombinedOutput()
+	t.Logf("%s", out)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(libgoh); err != nil {
+		t.Errorf("libgo.h not installed in second run: %v", err)
+	}
+	if _, err := os.Stat(ph); err != nil {
+		t.Errorf("p.h not installed in second run: %v", err)
+	}
+}
+
+// copyFile copies src to dst.
+func copyFile(t *testing.T, dst, src string) {
+	t.Helper()
+	data, err := ioutil.ReadFile(src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
+		t.Fatal(err)
+	}
+	if err := ioutil.WriteFile(dst, data, 0666); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/misc/cgo/testcshared/src/p/p.go b/misc/cgo/testcshared/src/p/p.go
index fb4b5ca..0f02cf3 100644
--- a/misc/cgo/testcshared/src/p/p.go
+++ b/misc/cgo/testcshared/src/p/p.go
@@ -8,5 +8,6 @@
 
 //export FromPkg
 func FromPkg() int32 { return 1024 }
+
 //export Divu
 func Divu(a, b uint32) uint32 { return a / b }
diff --git a/misc/cgo/testcshared/test.bash b/misc/cgo/testcshared/test.bash
deleted file mode 100755
index 315a0d4..0000000
--- a/misc/cgo/testcshared/test.bash
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2015 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# For testing Android, this script requires adb to push and run compiled
-# binaries on a target device.
-
-set -e
-
-if [ ! -f src/libgo/libgo.go ]; then
-	cwd=$(pwd)
-	echo "misc/cgo/testcshared/test.bash is running in $cwd" 1>&2
-	exit 1
-fi
-
-goos=$(go env GOOS)
-goarch=$(go env GOARCH)
-goroot=$(go env GOROOT)
-if [ ! -d "$goroot" ]; then
-	echo 'misc/cgo/testcshared/test.bash cannot find GOROOT' 1>&2
-	echo '$GOROOT:' "$GOROOT" 1>&2
-	echo 'go env GOROOT:' "$goroot" 1>&2
-	exit 1
-fi
-
-# Directory where cgo headers and outputs will be installed.
-# The installation directory format varies depending on the platform.
-installdir=pkg/${goos}_${goarch}_testcshared_shared
-if [ "${goos}" = "darwin" ]; then
-	installdir=pkg/${goos}_${goarch}_testcshared
-fi
-
-# Temporary directory on the android device.
-androidpath=/data/local/tmp/testcshared-$$
-
-function cleanup() {
-	rm -f libgo.$libext libgo2.$libext libgo4.$libext libgo5.$libext
-	rm -f libgo.h libgo4.h libgo5.h
-	rm -f testp testp2 testp3 testp4 testp5
-	rm -rf pkg "${goroot}/${installdir}"
-
-	if [ "$goos" = "android" ]; then
-		adb shell rm -rf "$androidpath"
-	fi
-}
-trap cleanup EXIT
-
-if [ "$goos" = "android" ]; then
-	adb shell mkdir -p "$androidpath"
-fi
-
-function run() {
-	case "$goos" in
-	"android")
-		local args=$@
-		output=$(adb shell "cd ${androidpath}; $@")
-		output=$(echo $output|tr -d '\r')
-		case $output in
-			*PASS) echo "PASS";; 
-			*) echo "$output";;
-		esac
-		;;
-	*)
-		echo $(env $@)
-		;;
-	esac
-}
-
-function binpush() {
-	bin=${1}
-	if [ "$goos" = "android" ]; then
-		adb push "$bin"  "${androidpath}/${bin}" 2>/dev/null
-	fi
-}
-
-rm -rf pkg
-
-suffix="-installsuffix testcshared"
-
-libext="so"
-if [ "$goos" = "darwin" ]; then
-	libext="dylib"
-fi
-
-# Create the header files.
-GOPATH=$(pwd) go install -buildmode=c-shared $suffix libgo
-
-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
-binpush libgo.$libext
-
-if [ "$goos" = "linux" ] || [ "$goos" = "android" ] ; then
-    if readelf -d libgo.$libext | grep TEXTREL >/dev/null; then
-        echo "libgo.$libext has TEXTREL set"
-        exit 1
-    fi
-fi
-
-GOGCCFLAGS=$(go env GOGCCFLAGS)
-if [ "$goos" = "android" ]; then
-	GOGCCFLAGS="${GOGCCFLAGS} -pie -fuse-ld=gold"
-fi
-
-status=0
-
-# test0: exported symbols in shared lib are accessible.
-# TODO(iant): using _shared here shouldn't really be necessary.
-$(go env CC) ${GOGCCFLAGS} -I ${installdir} -o testp main0.c ./libgo.$libext
-binpush testp
-
-output=$(run LD_LIBRARY_PATH=. ./testp)
-if [ "$output" != "PASS" ]; then
-	echo "FAIL test0 got ${output}"
-	status=1
-fi
-
-# test1: shared library can be dynamically loaded and exported symbols are accessible.
-$(go env CC) ${GOGCCFLAGS} -o testp main1.c -ldl
-binpush testp
-output=$(run ./testp ./libgo.$libext)
-if [ "$output" != "PASS" ]; then
-	echo "FAIL test1 got ${output}"
-	status=1
-fi
-
-# test2: tests libgo2 which does not export any functions.
-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo2.$libext libgo2
-binpush libgo2.$libext
-linkflags="-Wl,--no-as-needed"
-if [ "$goos" = "darwin" ]; then
-	linkflags=""
-fi
-$(go env CC) ${GOGCCFLAGS} -o testp2 main2.c $linkflags libgo2.$libext
-binpush testp2
-output=$(run LD_LIBRARY_PATH=. ./testp2)
-if [ "$output" != "PASS" ]; then
-	echo "FAIL test2 got ${output}"
-	status=1
-fi
-
-# test3: tests main.main is exported on android.
-if [ "$goos" = "android" ]; then
-	$(go env CC) ${GOGCCFLAGS} -o testp3 main3.c -ldl
-	binpush testp3
-	output=$(run ./testp ./libgo.so)
-	if [ "$output" != "PASS" ]; then
-		echo "FAIL test3 got ${output}"
-		status=1
-	fi
-fi
-
-# test4: tests signal handlers
-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo4.$libext libgo4
-binpush libgo4.$libext
-$(go env CC) ${GOGCCFLAGS} -pthread -o testp4 main4.c -ldl
-binpush testp4
-output=$(run ./testp4 ./libgo4.$libext 2>&1)
-if test "$output" != "PASS"; then
-    echo "FAIL test4 got ${output}"
-    if test "$goos" != "android"; then
-	echo "re-running test4 in verbose mode"
-	./testp4 ./libgo4.$libext verbose
-    fi
-    status=1
-fi
-
-# test5: tests signal handlers with os/signal.Notify
-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo5.$libext libgo5
-binpush libgo5.$libext
-$(go env CC) ${GOGCCFLAGS} -pthread -o testp5 main5.c -ldl
-binpush testp5
-output=$(run ./testp5 ./libgo5.$libext 2>&1)
-if test "$output" != "PASS"; then
-    echo "FAIL test5 got ${output}"
-    if test "$goos" != "android"; then
-	echo "re-running test5 in verbose mode"
-	./testp5 ./libgo5.$libext verbose
-    fi
-    status=1
-fi
-
-if test "$libext" = "dylib"; then
-	# make sure dylibs are well-formed
-	if ! otool -l libgo*.dylib >/dev/null; then
-		status=1
-	fi
-fi
-
-if test $status = 0; then
-    echo "ok"
-fi
-
-exit $status
diff --git a/misc/cgo/testplugin/src/host/host.go b/misc/cgo/testplugin/src/host/host.go
index 898f44e..0ca17da 100644
--- a/misc/cgo/testplugin/src/host/host.go
+++ b/misc/cgo/testplugin/src/host/host.go
@@ -126,14 +126,24 @@
 		log.Fatalf(`plugin1.F()=%d, want 17`, gotf)
 	}
 
-	// plugin2 has no exported symbols, only an init function.
-	if _, err := plugin.Open("plugin2.so"); err != nil {
+	p2, err := plugin.Open("plugin2.so")
+	if err != nil {
 		log.Fatalf("plugin.Open failed: %v", err)
 	}
+	// Check that plugin2's init function was called, and
+	// that it modifies the same global variable as the host.
 	if got, want := common.X, 2; got != want {
 		log.Fatalf("after loading plugin2, common.X=%d, want %d", got, want)
 	}
 
+	_, err = plugin.Open("plugin2-dup.so")
+	if err == nil {
+		log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open should have failed`)
+	}
+	if s := err.Error(); !strings.Contains(s, "already loaded") {
+		log.Fatal(`plugin.Open("plugin2.so"): error does not mention "already loaded"`)
+	}
+
 	_, err = plugin.Open("plugin-mismatch.so")
 	if err == nil {
 		log.Fatal(`plugin.Open("plugin-mismatch.so"): should have failed`)
@@ -142,6 +152,24 @@
 		log.Fatalf(`plugin.Open("plugin-mismatch.so"): error does not mention "different version": %v`, s)
 	}
 
+	_, err = plugin.Open("plugin2-dup.so")
+	if err == nil {
+		log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open after bad plugin should have failed`)
+	}
+	_, err = plugin.Open("plugin2.so")
+	if err != nil {
+		log.Fatalf(`plugin.Open("plugin2.so"): second open with same name failed: %v`, err)
+	}
+
+	// Test that unexported types with the same names in
+	// different plugins do not interfere with each other.
+	//
+	// See Issue #21386.
+	UnexportedNameReuse, _ := p.Lookup("UnexportedNameReuse")
+	UnexportedNameReuse.(func())()
+	UnexportedNameReuse, _ = p2.Lookup("UnexportedNameReuse")
+	UnexportedNameReuse.(func())()
+
 	testUnnamed()
 
 	fmt.Println("PASS")
diff --git a/misc/cgo/testplugin/src/issue18584/main.go b/misc/cgo/testplugin/src/issue18584/main.go
new file mode 100644
index 0000000..c280fd4
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue18584/main.go
@@ -0,0 +1,23 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "plugin"
+
+func main() {
+	p, err := plugin.Open("plugin.so")
+	if err != nil {
+		panic(err)
+	}
+
+	sym, err := p.Lookup("G")
+	if err != nil {
+		panic(err)
+	}
+	g := sym.(func() bool)
+	if !g() {
+		panic("expected types to match, Issue #18584")
+	}
+}
diff --git a/misc/cgo/testplugin/src/issue18584/plugin.go b/misc/cgo/testplugin/src/issue18584/plugin.go
new file mode 100644
index 0000000..be0868d
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue18584/plugin.go
@@ -0,0 +1,19 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "reflect"
+
+type C struct {
+}
+
+func F(c *C) *C {
+	return nil
+}
+
+func G() bool {
+	var c *C
+	return reflect.TypeOf(F).Out(0) == reflect.TypeOf(c)
+}
diff --git a/misc/cgo/testplugin/src/issue19418/main.go b/misc/cgo/testplugin/src/issue19418/main.go
new file mode 100644
index 0000000..2ec9f9a
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue19418/main.go
@@ -0,0 +1,29 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"plugin"
+)
+
+func main() {
+	p, err := plugin.Open("plugin.so")
+	if err != nil {
+		panic(err)
+	}
+
+	val, err := p.Lookup("Val")
+	if err != nil {
+		panic(err)
+	}
+	got := *val.(*string)
+	const want = "linkstr"
+	if got != want {
+		fmt.Fprintf(os.Stderr, "issue19418 value is %q, want %q\n", got, want)
+		os.Exit(2)
+	}
+}
diff --git a/misc/cgo/testplugin/src/issue19418/plugin.go b/misc/cgo/testplugin/src/issue19418/plugin.go
new file mode 100644
index 0000000..fe93b16
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue19418/plugin.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var Val = "val-unset"
diff --git a/misc/cgo/testplugin/src/issue19529/plugin.go b/misc/cgo/testplugin/src/issue19529/plugin.go
new file mode 100644
index 0000000..ad2df6c
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue19529/plugin.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+	"reflect"
+)
+
+type Foo struct {
+	Bar string `json:"Bar@baz,omitempty"`
+}
+
+func F() {
+	println(reflect.TypeOf(Foo{}).Field(0).Tag)
+}
+
+func main() {}
diff --git a/misc/cgo/testplugin/src/issue22175/main.go b/misc/cgo/testplugin/src/issue22175/main.go
new file mode 100644
index 0000000..9be9bab
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue22175/main.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"plugin"
+)
+
+func main() {
+	p2, err := plugin.Open("issue22175_plugin1.so")
+	if err != nil {
+		panic(err)
+	}
+	f, err := p2.Lookup("F")
+	if err != nil {
+		panic(err)
+	}
+	got := f.(func() int)()
+	const want = 971
+	if got != want {
+		fmt.Fprintf(os.Stderr, "issue22175: F()=%d, want %d", got, want)
+		os.Exit(1)
+	}
+}
diff --git a/misc/cgo/testplugin/src/issue22175/plugin1.go b/misc/cgo/testplugin/src/issue22175/plugin1.go
new file mode 100644
index 0000000..5ae6cb6
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue22175/plugin1.go
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "plugin"
+
+func F() int {
+	p2, err := plugin.Open("issue22175_plugin2.so")
+	if err != nil {
+		panic(err)
+	}
+	g, err := p2.Lookup("G")
+	if err != nil {
+		panic(err)
+	}
+	return g.(func() int)()
+}
+
+func main() {}
diff --git a/misc/cgo/testplugin/src/issue22175/plugin2.go b/misc/cgo/testplugin/src/issue22175/plugin2.go
new file mode 100644
index 0000000..f387a19
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue22175/plugin2.go
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func G() int { return 971 }
+
+func main() {}
diff --git a/misc/cgo/testplugin/src/issue22295.pkg/main.go b/misc/cgo/testplugin/src/issue22295.pkg/main.go
new file mode 100644
index 0000000..6cb186e
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue22295.pkg/main.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package main
+
+import (
+	"log"
+	"plugin"
+)
+
+func main() {
+	p, err := plugin.Open("issue.22295.so")
+	if err != nil {
+		log.Fatal(err)
+	}
+	f, err := p.Lookup("F")
+	if err != nil {
+		log.Fatal(err)
+	}
+	const want = 2503
+	got := f.(func() int)()
+	if got != want {
+		log.Fatalf("got %d, want %d", got, want)
+	}
+}
diff --git a/misc/cgo/testplugin/src/issue22295.pkg/plugin.go b/misc/cgo/testplugin/src/issue22295.pkg/plugin.go
new file mode 100644
index 0000000..46b08a4
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue22295.pkg/plugin.go
@@ -0,0 +1,16 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var f *int
+
+func init() {
+	f = new(int)
+	*f = 2503
+}
+
+func F() int { return *f }
+
+func main() {}
diff --git a/misc/cgo/testplugin/src/plugin1/plugin1.go b/misc/cgo/testplugin/src/plugin1/plugin1.go
index edcef2c..0a9fa2f 100644
--- a/misc/cgo/testplugin/src/plugin1/plugin1.go
+++ b/misc/cgo/testplugin/src/plugin1/plugin1.go
@@ -7,7 +7,10 @@
 // // No C code required.
 import "C"
 
-import "common"
+import (
+	"common"
+	"reflect"
+)
 
 func F() int {
 	_ = make([]byte, 1<<21) // trigger stack unwind, Issue #18190.
@@ -33,6 +36,21 @@
 	call(g)
 }
 
+type sameNameReusedInPlugins struct {
+	X string
+}
+
+type sameNameHolder struct {
+	F *sameNameReusedInPlugins
+}
+
+func UnexportedNameReuse() {
+	h := sameNameHolder{}
+	v := reflect.ValueOf(&h).Elem().Field(0)
+	newval := reflect.New(v.Type().Elem())
+	v.Set(newval)
+}
+
 func main() {
 	panic("plugin1.main called")
 }
diff --git a/misc/cgo/testplugin/src/plugin2/plugin2.go b/misc/cgo/testplugin/src/plugin2/plugin2.go
index 9c507fc..a67f2de 100644
--- a/misc/cgo/testplugin/src/plugin2/plugin2.go
+++ b/misc/cgo/testplugin/src/plugin2/plugin2.go
@@ -13,6 +13,7 @@
 
 import (
 	"common"
+	"reflect"
 	"strings"
 )
 
@@ -22,6 +23,21 @@
 	common.X = 2
 }
 
+type sameNameReusedInPlugins struct {
+	X string
+}
+
+type sameNameHolder struct {
+	F *sameNameReusedInPlugins
+}
+
+func UnexportedNameReuse() {
+	h := sameNameHolder{}
+	v := reflect.ValueOf(&h).Elem().Field(0)
+	newval := reflect.New(v.Type().Elem())
+	v.Set(newval)
+}
+
 func main() {
 	panic("plugin1.main called")
 }
diff --git a/misc/cgo/testplugin/test.bash b/misc/cgo/testplugin/test.bash
index 69df5bd..18e3803 100755
--- a/misc/cgo/testplugin/test.bash
+++ b/misc/cgo/testplugin/test.bash
@@ -15,38 +15,73 @@
 goarch=$(go env GOARCH)
 
 function cleanup() {
-	rm -f plugin*.so unnamed*.so iface*.so
-	rm -rf host pkg sub iface issue18676 issue19534
+	rm -f plugin*.so unnamed*.so iface*.so issue*
+	rm -rf host pkg sub iface
 }
 trap cleanup EXIT
 
 rm -rf pkg sub
 mkdir sub
 
-GOPATH=$(pwd) go build -buildmode=plugin plugin1
-GOPATH=$(pwd) go build -buildmode=plugin plugin2
-GOPATH=$(pwd)/altpath go build -buildmode=plugin plugin-mismatch
-GOPATH=$(pwd) go build -buildmode=plugin -o=sub/plugin1.so sub/plugin1
-GOPATH=$(pwd) go build -buildmode=plugin unnamed1.go
-GOPATH=$(pwd) go build -buildmode=plugin unnamed2.go
-GOPATH=$(pwd) go build host
+GOPATH=$(pwd) go build -i -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin1
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin2
+cp plugin2.so plugin2-dup.so
+GOPATH=$(pwd)/altpath go build -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin-mismatch
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=sub/plugin1.so sub/plugin1
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so unnamed1/main.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host
 
 LD_LIBRARY_PATH=$(pwd) ./host
 
 # Test that types and itabs get properly uniqified.
-GOPATH=$(pwd) go build -buildmode=plugin iface_a
-GOPATH=$(pwd) go build -buildmode=plugin iface_b
-GOPATH=$(pwd) go build iface
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin iface_a
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin iface_b
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" iface
 LD_LIBRARY_PATH=$(pwd) ./iface
 
+function _timeout() (
+	set -e
+	$2 &
+	p=$!
+	(sleep $1; kill $p 2>/dev/null) &
+	p2=$!
+	wait $p 2>/dev/null
+	kill -0 $p2 2>/dev/null
+)
+
 # Test for issue 18676 - make sure we don't add the same itab twice.
 # The buggy code hangs forever, so use a timeout to check for that.
-GOPATH=$(pwd) go build -buildmode=plugin -o plugin.so src/issue18676/plugin.go
-GOPATH=$(pwd) go build -o issue18676 src/issue18676/main.go
-timeout 10s ./issue18676
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue18676/plugin.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue18676 src/issue18676/main.go
+_timeout 10s ./issue18676
 
 # Test for issue 19534 - that we can load a plugin built in a path with non-alpha
 # characters
-GOPATH=$(pwd) go build -buildmode=plugin -ldflags='-pluginpath=issue.19534' -o plugin.so src/issue19534/plugin.go
-GOPATH=$(pwd) go build -o issue19534 src/issue19534/main.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -ldflags='-pluginpath=issue.19534' -o plugin.so src/issue19534/plugin.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue19534 src/issue19534/main.go
 ./issue19534
+
+# Test for issue 18584
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue18584/plugin.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue18584 src/issue18584/main.go
+./issue18584
+
+# Test for issue 19418
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin "-ldflags=-X main.Val=linkstr" -o plugin.so src/issue19418/plugin.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue19418 src/issue19418/main.go
+./issue19418
+
+# Test for issue 19529
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue19529/plugin.go
+
+# Test for issue 22175
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin1.so src/issue22175/plugin1.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin2.so src/issue22175/plugin2.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.go
+./issue22175
+
+# Test for issue 22295
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
+./issue22295
diff --git a/misc/cgo/testplugin/unnamed1.go b/misc/cgo/testplugin/unnamed1/main.go
similarity index 100%
rename from misc/cgo/testplugin/unnamed1.go
rename to misc/cgo/testplugin/unnamed1/main.go
diff --git a/misc/cgo/testplugin/unnamed2.go b/misc/cgo/testplugin/unnamed2/main.go
similarity index 100%
rename from misc/cgo/testplugin/unnamed2.go
rename to misc/cgo/testplugin/unnamed2/main.go
diff --git a/misc/cgo/testsanitizers/cc_test.go b/misc/cgo/testsanitizers/cc_test.go
new file mode 100644
index 0000000..306844b
--- /dev/null
+++ b/misc/cgo/testsanitizers/cc_test.go
@@ -0,0 +1,441 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// sanitizers_test checks the use of Go with sanitizers like msan, asan, etc.
+// See https://github.com/google/sanitizers.
+package sanitizers_test
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"syscall"
+	"testing"
+	"unicode"
+)
+
+var overcommit struct {
+	sync.Once
+	value int
+	err   error
+}
+
+// requireOvercommit skips t if the kernel does not allow overcommit.
+func requireOvercommit(t *testing.T) {
+	t.Helper()
+
+	overcommit.Once.Do(func() {
+		var out []byte
+		out, overcommit.err = ioutil.ReadFile("/proc/sys/vm/overcommit_memory")
+		if overcommit.err != nil {
+			return
+		}
+		overcommit.value, overcommit.err = strconv.Atoi(string(bytes.TrimSpace(out)))
+	})
+
+	if overcommit.err != nil {
+		t.Skipf("couldn't determine vm.overcommit_memory (%v); assuming no overcommit", overcommit.err)
+	}
+	if overcommit.value == 2 {
+		t.Skip("vm.overcommit_memory=2")
+	}
+}
+
+var env struct {
+	sync.Once
+	m   map[string]string
+	err error
+}
+
+// goEnv returns the output of $(go env) as a map.
+func goEnv(key string) (string, error) {
+	env.Once.Do(func() {
+		var out []byte
+		out, env.err = exec.Command("go", "env", "-json").Output()
+		if env.err != nil {
+			return
+		}
+
+		env.m = make(map[string]string)
+		env.err = json.Unmarshal(out, &env.m)
+	})
+	if env.err != nil {
+		return "", env.err
+	}
+
+	v, ok := env.m[key]
+	if !ok {
+		return "", fmt.Errorf("`go env`: no entry for %v", key)
+	}
+	return v, nil
+}
+
+// replaceEnv sets the key environment variable to value in cmd.
+func replaceEnv(cmd *exec.Cmd, key, value string) {
+	if cmd.Env == nil {
+		cmd.Env = os.Environ()
+	}
+	cmd.Env = append(cmd.Env, key+"="+value)
+}
+
+// mustRun executes t and fails cmd with a well-formatted message if it fails.
+func mustRun(t *testing.T, cmd *exec.Cmd) {
+	t.Helper()
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("%#q exited with %v\n%s", strings.Join(cmd.Args, " "), err, out)
+	}
+}
+
+// cc returns a cmd that executes `$(go env CC) $(go env GOGCCFLAGS) $args`.
+func cc(args ...string) (*exec.Cmd, error) {
+	CC, err := goEnv("CC")
+	if err != nil {
+		return nil, err
+	}
+
+	GOGCCFLAGS, err := goEnv("GOGCCFLAGS")
+	if err != nil {
+		return nil, err
+	}
+
+	// Split GOGCCFLAGS, respecting quoting.
+	//
+	// TODO(bcmills): This code also appears in
+	// misc/cgo/testcarchive/carchive_test.go, and perhaps ought to go in
+	// src/cmd/dist/test.go as well. Figure out where to put it so that it can be
+	// shared.
+	var flags []string
+	quote := '\000'
+	start := 0
+	lastSpace := true
+	backslash := false
+	for i, c := range GOGCCFLAGS {
+		if quote == '\000' && unicode.IsSpace(c) {
+			if !lastSpace {
+				flags = append(flags, GOGCCFLAGS[start:i])
+				lastSpace = true
+			}
+		} else {
+			if lastSpace {
+				start = i
+				lastSpace = false
+			}
+			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
+				quote = c
+				backslash = false
+			} else if !backslash && quote == c {
+				quote = '\000'
+			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
+				backslash = true
+			} else {
+				backslash = false
+			}
+		}
+	}
+	if !lastSpace {
+		flags = append(flags, GOGCCFLAGS[start:])
+	}
+
+	cmd := exec.Command(CC, flags...)
+	cmd.Args = append(cmd.Args, args...)
+	return cmd, nil
+}
+
+type version struct {
+	name         string
+	major, minor int
+}
+
+var compiler struct {
+	sync.Once
+	version
+	err error
+}
+
+// compilerVersion detects the version of $(go env CC).
+//
+// It returns a non-nil error if the compiler matches a known version schema but
+// the version could not be parsed, or if $(go env CC) could not be determined.
+func compilerVersion() (version, error) {
+	compiler.Once.Do(func() {
+		compiler.err = func() error {
+			compiler.name = "unknown"
+
+			cmd, err := cc("--version")
+			if err != nil {
+				return err
+			}
+			out, err := cmd.Output()
+			if err != nil {
+				// Compiler does not support "--version" flag: not Clang or GCC.
+				return nil
+			}
+
+			var match [][]byte
+			if bytes.HasPrefix(out, []byte("gcc")) {
+				compiler.name = "gcc"
+
+				cmd, err := cc("-dumpversion")
+				if err != nil {
+					return err
+				}
+				out, err := cmd.Output()
+				if err != nil {
+					// gcc, but does not support gcc's "-dumpversion" flag?!
+					return err
+				}
+				gccRE := regexp.MustCompile(`(\d+)\.(\d+)`)
+				match = gccRE.FindSubmatch(out)
+			} else {
+				clangRE := regexp.MustCompile(`clang version (\d+)\.(\d+)`)
+				if match = clangRE.FindSubmatch(out); len(match) > 0 {
+					compiler.name = "clang"
+				}
+			}
+
+			if len(match) < 3 {
+				return nil // "unknown"
+			}
+			if compiler.major, err = strconv.Atoi(string(match[1])); err != nil {
+				return err
+			}
+			if compiler.minor, err = strconv.Atoi(string(match[2])); err != nil {
+				return err
+			}
+			return nil
+		}()
+	})
+	return compiler.version, compiler.err
+}
+
+type compilerCheck struct {
+	once sync.Once
+	err  error
+	skip bool // If true, skip with err instead of failing with it.
+}
+
+type config struct {
+	sanitizer string
+
+	cFlags, ldFlags, goFlags []string
+
+	sanitizerCheck, runtimeCheck compilerCheck
+}
+
+var configs struct {
+	sync.Mutex
+	m map[string]*config
+}
+
+// configure returns the configuration for the given sanitizer.
+func configure(sanitizer string) *config {
+	configs.Lock()
+	defer configs.Unlock()
+	if c, ok := configs.m[sanitizer]; ok {
+		return c
+	}
+
+	c := &config{
+		sanitizer: sanitizer,
+		cFlags:    []string{"-fsanitize=" + sanitizer},
+		ldFlags:   []string{"-fsanitize=" + sanitizer},
+	}
+
+	if testing.Verbose() {
+		c.goFlags = append(c.goFlags, "-x")
+	}
+
+	switch sanitizer {
+	case "memory":
+		c.goFlags = append(c.goFlags, "-msan")
+
+	case "thread":
+		c.goFlags = append(c.goFlags, "--installsuffix=tsan")
+		compiler, _ := compilerVersion()
+		if compiler.name == "gcc" {
+			c.cFlags = append(c.cFlags, "-fPIC")
+			c.ldFlags = append(c.ldFlags, "-fPIC", "-static-libtsan")
+		}
+
+	default:
+		panic(fmt.Sprintf("unrecognized sanitizer: %q", sanitizer))
+	}
+
+	if configs.m == nil {
+		configs.m = make(map[string]*config)
+	}
+	configs.m[sanitizer] = c
+	return c
+}
+
+// goCmd returns a Cmd that executes "go $subcommand $args" with appropriate
+// additional flags and environment.
+func (c *config) goCmd(subcommand string, args ...string) *exec.Cmd {
+	cmd := exec.Command("go", subcommand)
+	cmd.Args = append(cmd.Args, c.goFlags...)
+	cmd.Args = append(cmd.Args, args...)
+	replaceEnv(cmd, "CGO_CFLAGS", strings.Join(c.cFlags, " "))
+	replaceEnv(cmd, "CGO_LDFLAGS", strings.Join(c.ldFlags, " "))
+	return cmd
+}
+
+// skipIfCSanitizerBroken skips t if the C compiler does not produce working
+// binaries as configured.
+func (c *config) skipIfCSanitizerBroken(t *testing.T) {
+	check := &c.sanitizerCheck
+	check.once.Do(func() {
+		check.skip, check.err = c.checkCSanitizer()
+	})
+	if check.err != nil {
+		t.Helper()
+		if check.skip {
+			t.Skip(check.err)
+		}
+		t.Fatal(check.err)
+	}
+}
+
+var cMain = []byte(`
+int main() {
+	return 0;
+}
+`)
+
+func (c *config) checkCSanitizer() (skip bool, err error) {
+	dir, err := ioutil.TempDir("", c.sanitizer)
+	if err != nil {
+		return false, fmt.Errorf("failed to create temp directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	src := filepath.Join(dir, "return0.c")
+	if err := ioutil.WriteFile(src, cMain, 0600); err != nil {
+		return false, fmt.Errorf("failed to write C source file: %v", err)
+	}
+
+	dst := filepath.Join(dir, "return0")
+	cmd, err := cc(c.cFlags...)
+	if err != nil {
+		return false, err
+	}
+	cmd.Args = append(cmd.Args, c.ldFlags...)
+	cmd.Args = append(cmd.Args, "-o", dst, src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		if bytes.Contains(out, []byte("-fsanitize")) &&
+			(bytes.Contains(out, []byte("unrecognized")) ||
+				bytes.Contains(out, []byte("unsupported"))) {
+			return true, errors.New(string(out))
+		}
+		return true, fmt.Errorf("%#q failed: %v\n%s", strings.Join(cmd.Args, " "), err, out)
+	}
+
+	if out, err := exec.Command(dst).CombinedOutput(); err != nil {
+		if os.IsNotExist(err) {
+			return true, fmt.Errorf("%#q failed to produce executable: %v", strings.Join(cmd.Args, " "), err)
+		}
+		snippet := bytes.SplitN(out, []byte{'\n'}, 2)[0]
+		return true, fmt.Errorf("%#q generated broken executable: %v\n%s", strings.Join(cmd.Args, " "), err, snippet)
+	}
+
+	return false, nil
+}
+
+// skipIfRuntimeIncompatible skips t if the Go runtime is suspected not to work
+// with cgo as configured.
+func (c *config) skipIfRuntimeIncompatible(t *testing.T) {
+	check := &c.runtimeCheck
+	check.once.Do(func() {
+		check.skip, check.err = c.checkRuntime()
+	})
+	if check.err != nil {
+		t.Helper()
+		if check.skip {
+			t.Skip(check.err)
+		}
+		t.Fatal(check.err)
+	}
+}
+
+func (c *config) checkRuntime() (skip bool, err error) {
+	if c.sanitizer != "thread" {
+		return false, nil
+	}
+
+	// libcgo.h sets CGO_TSAN if it detects TSAN support in the C compiler.
+	// Dump the preprocessor defines to check that that works.
+	// (Sometimes it doesn't: see https://golang.org/issue/15983.)
+	cmd, err := cc(c.cFlags...)
+	if err != nil {
+		return false, err
+	}
+	cmd.Args = append(cmd.Args, "-dM", "-E", "../../../src/runtime/cgo/libcgo.h")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return false, fmt.Errorf("%#q exited with %v\n%s", strings.Join(cmd.Args, " "), err, out)
+	}
+	if !bytes.Contains(out, []byte("#define CGO_TSAN")) {
+		return true, fmt.Errorf("%#q did not define CGO_TSAN")
+	}
+	return false, nil
+}
+
+// srcPath returns the path to the given file relative to this test's source tree.
+func srcPath(path string) string {
+	return filepath.Join("src", path)
+}
+
+// A tempDir manages a temporary directory within a test.
+type tempDir struct {
+	base string
+}
+
+func (d *tempDir) RemoveAll(t *testing.T) {
+	t.Helper()
+	if d.base == "" {
+		return
+	}
+	if err := os.RemoveAll(d.base); err != nil {
+		t.Fatalf("Failed to remove temp dir: %v", err)
+	}
+}
+
+func (d *tempDir) Join(name string) string {
+	return filepath.Join(d.base, name)
+}
+
+func newTempDir(t *testing.T) *tempDir {
+	t.Helper()
+	dir, err := ioutil.TempDir("", filepath.Dir(t.Name()))
+	if err != nil {
+		t.Fatalf("Failed to create temp dir: %v", err)
+	}
+	return &tempDir{base: dir}
+}
+
+// hangProneCmd returns an exec.Cmd for a command that is likely to hang.
+//
+// If one of these tests hangs, the caller is likely to kill the test process
+// using SIGINT, which will be sent to all of the processes in the test's group.
+// Unfortunately, TSAN in particular is prone to dropping signals, so the SIGINT
+// may terminate the test binary but leave the subprocess running. hangProneCmd
+// configures subprocess to receive SIGKILL instead to ensure that it won't
+// leak.
+func hangProneCmd(name string, arg ...string) *exec.Cmd {
+	cmd := exec.Command(name, arg...)
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		Pdeathsig: syscall.SIGKILL,
+	}
+	return cmd
+}
diff --git a/misc/cgo/testsanitizers/cshared_test.go b/misc/cgo/testsanitizers/cshared_test.go
new file mode 100644
index 0000000..56063ea
--- /dev/null
+++ b/misc/cgo/testsanitizers/cshared_test.go
@@ -0,0 +1,74 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sanitizers_test
+
+import (
+	"fmt"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func TestShared(t *testing.T) {
+	t.Parallel()
+	requireOvercommit(t)
+
+	GOOS, err := goEnv("GOOS")
+	if err != nil {
+		t.Fatal(err)
+	}
+	libExt := "so"
+	if GOOS == "darwin" {
+		libExt = "dylib"
+	}
+
+	cases := []struct {
+		src       string
+		sanitizer string
+	}{
+		{
+			src:       "msan_shared.go",
+			sanitizer: "memory",
+		},
+		{
+			src:       "tsan_shared.go",
+			sanitizer: "thread",
+		},
+	}
+
+	for _, tc := range cases {
+		tc := tc
+		name := strings.TrimSuffix(tc.src, ".go")
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			config := configure(tc.sanitizer)
+			config.skipIfCSanitizerBroken(t)
+
+			dir := newTempDir(t)
+			defer dir.RemoveAll(t)
+
+			lib := dir.Join(fmt.Sprintf("lib%s.%s", name, libExt))
+			mustRun(t, config.goCmd("build", "-buildmode=c-shared", "-o", lib, srcPath(tc.src)))
+
+			cSrc := dir.Join("main.c")
+			if err := ioutil.WriteFile(cSrc, cMain, 0600); err != nil {
+				t.Fatalf("failed to write C source file: %v", err)
+			}
+
+			dstBin := dir.Join(name)
+			cmd, err := cc(config.cFlags...)
+			if err != nil {
+				t.Fatal(err)
+			}
+			cmd.Args = append(cmd.Args, config.ldFlags...)
+			cmd.Args = append(cmd.Args, "-o", dstBin, cSrc, lib)
+			mustRun(t, cmd)
+
+			cmd = hangProneCmd(dstBin)
+			replaceEnv(cmd, "LD_LIBRARY_PATH", ".")
+			mustRun(t, cmd)
+		})
+	}
+}
diff --git a/misc/cgo/testsanitizers/msan_test.go b/misc/cgo/testsanitizers/msan_test.go
new file mode 100644
index 0000000..af5afa9
--- /dev/null
+++ b/misc/cgo/testsanitizers/msan_test.go
@@ -0,0 +1,55 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sanitizers_test
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestMSAN(t *testing.T) {
+	t.Parallel()
+	requireOvercommit(t)
+	config := configure("memory")
+	config.skipIfCSanitizerBroken(t)
+
+	mustRun(t, config.goCmd("build", "std"))
+
+	cases := []struct {
+		src     string
+		wantErr bool
+	}{
+		{src: "msan.go"},
+		{src: "msan2.go"},
+		{src: "msan2_cmsan.go"},
+		{src: "msan3.go"},
+		{src: "msan4.go"},
+		{src: "msan5.go"},
+		{src: "msan_fail.go", wantErr: true},
+	}
+	for _, tc := range cases {
+		tc := tc
+		name := strings.TrimSuffix(tc.src, ".go")
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			dir := newTempDir(t)
+			defer dir.RemoveAll(t)
+
+			outPath := dir.Join(name)
+			mustRun(t, config.goCmd("build", "-o", outPath, srcPath(tc.src)))
+
+			cmd := hangProneCmd(outPath)
+			if tc.wantErr {
+				out, err := cmd.CombinedOutput()
+				if err != nil {
+					return
+				}
+				t.Fatalf("%#q exited without error; want MSAN failure\n%s", strings.Join(cmd.Args, " "), out)
+			}
+			mustRun(t, cmd)
+		})
+	}
+}
diff --git a/misc/cgo/testsanitizers/msan.go b/misc/cgo/testsanitizers/src/msan.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan.go
rename to misc/cgo/testsanitizers/src/msan.go
diff --git a/misc/cgo/testsanitizers/msan2.go b/misc/cgo/testsanitizers/src/msan2.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan2.go
rename to misc/cgo/testsanitizers/src/msan2.go
diff --git a/misc/cgo/testsanitizers/src/msan2_cmsan.go b/misc/cgo/testsanitizers/src/msan2_cmsan.go
new file mode 100644
index 0000000..8fdaea9
--- /dev/null
+++ b/misc/cgo/testsanitizers/src/msan2_cmsan.go
@@ -0,0 +1,38 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+/*
+#cgo LDFLAGS: -fsanitize=memory
+#cgo CPPFLAGS: -fsanitize=memory
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+void f(int32_t *p, int n) {
+  int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n);
+  memcpy(p, q, n * sizeof(*p));
+  free(q);
+}
+
+void g(int32_t *p, int n) {
+  if (p[4] != 1) {
+    abort();
+  }
+}
+*/
+import "C"
+
+import (
+	"unsafe"
+)
+
+func main() {
+	a := make([]int32, 10)
+	C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a)))
+	a[4] = 1
+	C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a)))
+}
diff --git a/misc/cgo/testsanitizers/msan3.go b/misc/cgo/testsanitizers/src/msan3.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan3.go
rename to misc/cgo/testsanitizers/src/msan3.go
diff --git a/misc/cgo/testsanitizers/msan4.go b/misc/cgo/testsanitizers/src/msan4.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan4.go
rename to misc/cgo/testsanitizers/src/msan4.go
diff --git a/misc/cgo/testsanitizers/msan5.go b/misc/cgo/testsanitizers/src/msan5.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan5.go
rename to misc/cgo/testsanitizers/src/msan5.go
diff --git a/misc/cgo/testsanitizers/msan_fail.go b/misc/cgo/testsanitizers/src/msan_fail.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan_fail.go
rename to misc/cgo/testsanitizers/src/msan_fail.go
diff --git a/misc/cgo/testsanitizers/msan_shared.go b/misc/cgo/testsanitizers/src/msan_shared.go
similarity index 100%
rename from misc/cgo/testsanitizers/msan_shared.go
rename to misc/cgo/testsanitizers/src/msan_shared.go
diff --git a/misc/cgo/testsanitizers/tsan.go b/misc/cgo/testsanitizers/src/tsan.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan.go
rename to misc/cgo/testsanitizers/src/tsan.go
diff --git a/misc/cgo/testsanitizers/tsan10.go b/misc/cgo/testsanitizers/src/tsan10.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan10.go
rename to misc/cgo/testsanitizers/src/tsan10.go
diff --git a/misc/cgo/testsanitizers/tsan11.go b/misc/cgo/testsanitizers/src/tsan11.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan11.go
rename to misc/cgo/testsanitizers/src/tsan11.go
diff --git a/misc/cgo/testsanitizers/tsan12.go b/misc/cgo/testsanitizers/src/tsan12.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan12.go
rename to misc/cgo/testsanitizers/src/tsan12.go
diff --git a/misc/cgo/testsanitizers/tsan2.go b/misc/cgo/testsanitizers/src/tsan2.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan2.go
rename to misc/cgo/testsanitizers/src/tsan2.go
diff --git a/misc/cgo/testsanitizers/tsan3.go b/misc/cgo/testsanitizers/src/tsan3.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan3.go
rename to misc/cgo/testsanitizers/src/tsan3.go
diff --git a/misc/cgo/testsanitizers/tsan4.go b/misc/cgo/testsanitizers/src/tsan4.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan4.go
rename to misc/cgo/testsanitizers/src/tsan4.go
diff --git a/misc/cgo/testsanitizers/tsan5.go b/misc/cgo/testsanitizers/src/tsan5.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan5.go
rename to misc/cgo/testsanitizers/src/tsan5.go
diff --git a/misc/cgo/testsanitizers/tsan6.go b/misc/cgo/testsanitizers/src/tsan6.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan6.go
rename to misc/cgo/testsanitizers/src/tsan6.go
diff --git a/misc/cgo/testsanitizers/tsan7.go b/misc/cgo/testsanitizers/src/tsan7.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan7.go
rename to misc/cgo/testsanitizers/src/tsan7.go
diff --git a/misc/cgo/testsanitizers/tsan8.go b/misc/cgo/testsanitizers/src/tsan8.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan8.go
rename to misc/cgo/testsanitizers/src/tsan8.go
diff --git a/misc/cgo/testsanitizers/tsan9.go b/misc/cgo/testsanitizers/src/tsan9.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan9.go
rename to misc/cgo/testsanitizers/src/tsan9.go
diff --git a/misc/cgo/testsanitizers/tsan_shared.go b/misc/cgo/testsanitizers/src/tsan_shared.go
similarity index 100%
rename from misc/cgo/testsanitizers/tsan_shared.go
rename to misc/cgo/testsanitizers/src/tsan_shared.go
diff --git a/misc/cgo/testsanitizers/test.bash b/misc/cgo/testsanitizers/test.bash
deleted file mode 100755
index 9f80af6..0000000
--- a/misc/cgo/testsanitizers/test.bash
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2015 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# This directory is intended to test the use of Go with sanitizers
-# like msan, asan, etc.  See https://github.com/google/sanitizers .
-
-set -e
-
-# The sanitizers were originally developed with clang, so prefer it.
-CC=cc
-if test -x "$(type -p clang)"; then
-  CC=clang
-fi
-export CC
-
-if [ "$(sysctl -n vm.overcommit_memory)" = 2 ]; then
-  echo "skipping msan/tsan tests: vm.overcommit_memory=2" >&2
-  exit 0
-fi
-
-msan=yes
-
-TMPDIR=${TMPDIR:-/tmp}
-echo 'int main() { return 0; }' > ${TMPDIR}/testsanitizers$$.c
-if $CC -fsanitize=memory -o ${TMPDIR}/testsanitizers$$ ${TMPDIR}/testsanitizers$$.c 2>&1 | grep "unrecognized" >& /dev/null; then
-  echo "skipping msan tests: $CC -fsanitize=memory not supported"
-  msan=no
-elif ! test -x ${TMPDIR}/testsanitizers$$; then
-  echo "skipping msan tests: $CC -fsanitize-memory did not generate an executable"
-  msan=no
-elif ! ${TMPDIR}/testsanitizers$$ >/dev/null 2>&1; then
-  echo "skipping msan tests: $CC -fsanitize-memory generates broken executable"
-  msan=no
-fi
-rm -f ${TMPDIR}/testsanitizers$$.*
-
-tsan=yes
-
-# The memory and thread sanitizers in versions of clang before 3.6
-# don't work with Go.
-if test "$msan" = "yes" && $CC --version | grep clang >& /dev/null; then
-  ver=$($CC --version | sed -e 's/.* version \([0-9.-]*\).*/\1/')
-  major=$(echo $ver | sed -e 's/\([0-9]*\).*/\1/')
-  minor=$(echo $ver | sed -e 's/[0-9]*\.\([0-9]*\).*/\1/')
-  if test "$major" -lt 3 || test "$major" -eq 3 -a "$minor" -lt 6; then
-    echo "skipping msan/tsan tests: clang version $major.$minor (older than 3.6)"
-    msan=no
-    tsan=no
-  fi
-
-  # Clang before 3.8 does not work with Linux at or after 4.1.
-  # golang.org/issue/12898.
-  if test "$msan" = "yes" -a "$major" -lt 3 || test "$major" -eq 3 -a "$minor" -lt 8; then
-    if test "$(uname)" = Linux; then
-      linuxver=$(uname -r)
-      linuxmajor=$(echo $linuxver | sed -e 's/\([0-9]*\).*/\1/')
-      linuxminor=$(echo $linuxver | sed -e 's/[0-9]*\.\([0-9]*\).*/\1/')
-      if test "$linuxmajor" -gt 4 || test "$linuxmajor" -eq 4 -a "$linuxminor" -ge 1; then
-        echo "skipping msan/tsan tests: clang version $major.$minor (older than 3.8) incompatible with linux version $linuxmajor.$linuxminor (4.1 or newer)"
-	msan=no
-	tsan=no
-      fi
-    fi
-  fi
-fi
-
-status=0
-
-testmsanshared() {
-  goos=$(go env GOOS)
-  suffix="-installsuffix testsanitizers"
-  libext="so"
-  if [ "$goos" = "darwin" ]; then
-	  libext="dylib"
-  fi
-  go build -msan -buildmode=c-shared $suffix -o ${TMPDIR}/libmsanshared.$libext msan_shared.go
-
-  echo 'int main() { return 0; }' > ${TMPDIR}/testmsanshared.c
-  $CC $(go env GOGCCFLAGS) -fsanitize=memory -o ${TMPDIR}/testmsanshared ${TMPDIR}/testmsanshared.c ${TMPDIR}/libmsanshared.$libext
-
-  if ! LD_LIBRARY_PATH=. ${TMPDIR}/testmsanshared; then
-    echo "FAIL: msan_shared"
-    status=1
-  fi
-  rm -f ${TMPDIR}/{testmsanshared,testmsanshared.c,libmsanshared.$libext}
-}
-
-if test "$msan" = "yes"; then
-    if ! go build -msan std; then
-	echo "FAIL: build -msan std"
-	status=1
-    fi
-
-    if ! go run -msan msan.go; then
-	echo "FAIL: msan"
-	status=1
-    fi
-
-    if ! CGO_LDFLAGS="-fsanitize=memory" CGO_CPPFLAGS="-fsanitize=memory" go run -msan -a msan2.go; then
-	echo "FAIL: msan2 with -fsanitize=memory"
-	status=1
-    fi
-
-    if ! go run -msan -a msan2.go; then
-	echo "FAIL: msan2"
-	status=1
-    fi
-
-    if ! go run -msan msan3.go; then
-	echo "FAIL: msan3"
-	status=1
-    fi
-
-    if ! go run -msan msan4.go; then
-	echo "FAIL: msan4"
-	status=1
-    fi
-
-    if ! go run -msan msan5.go; then
-	echo "FAIL: msan5"
-	status=1
-    fi
-
-    if go run -msan msan_fail.go 2>/dev/null; then
-	echo "FAIL: msan_fail"
-	status=1
-    fi
-
-    testmsanshared
-fi
-
-testtsanshared() {
-  goos=$(go env GOOS)
-  suffix="-installsuffix tsan"
-  libext="so"
-  if [ "$goos" = "darwin" ]; then
-	  libext="dylib"
-  fi
-  go build -buildmode=c-shared $suffix -o ${TMPDIR}/libtsanshared.$libext tsan_shared.go
-
-  echo 'int main() { return 0; }' > ${TMPDIR}/testtsanshared.c
-  $CC $(go env GOGCCFLAGS) -fsanitize=thread -o ${TMPDIR}/testtsanshared ${TMPDIR}/testtsanshared.c ${TMPDIR}/libtsanshared.$libext
-
-  if ! LD_LIBRARY_PATH=. ${TMPDIR}/testtsanshared; then
-    echo "FAIL: tsan_shared"
-    status=1
-  fi
-  rm -f ${TMPDIR}/{testtsanshared,testtsanshared.c,libtsanshared.$libext}
-}
-
-if test "$tsan" = "yes"; then
-    echo 'int main() { return 0; }' > ${TMPDIR}/testsanitizers$$.c
-    ok=yes
-    if ! $CC -fsanitize=thread ${TMPDIR}/testsanitizers$$.c -o ${TMPDIR}/testsanitizers$$ &> ${TMPDIR}/testsanitizers$$.err; then
-	ok=no
-    fi
-    if grep "unrecognized" ${TMPDIR}/testsanitizers$$.err >& /dev/null; then
-	echo "skipping tsan tests: -fsanitize=thread not supported"
-	tsan=no
-    elif test "$ok" != "yes"; then
-	cat ${TMPDIR}/testsanitizers$$.err
-	echo "skipping tsan tests: -fsanitizer=thread build failed"
-	tsan=no
-    elif ! ${TMPDIR}/testsanitizers$$ 2>&1; then
-	echo "skipping tsan tests: running tsan program failed"
-	tsan=no
-    fi
-    rm -f ${TMPDIR}/testsanitizers$$*
-fi
-
-# Run a TSAN test.
-# $1 test name
-# $2 environment variables
-# $3 go run args
-testtsan() {
-    err=${TMPDIR}/tsanerr$$.out
-    if ! env $2 go run $3 $1 2>$err; then
-	cat $err
-	echo "FAIL: $1"
-	status=1
-    elif grep -i warning $err >/dev/null 2>&1; then
-	cat $err
-	echo "FAIL: $1"
-	status=1
-    fi
-    rm -f $err
-}
-
-if test "$tsan" = "yes"; then
-    testtsan tsan.go
-    testtsan tsan2.go
-    testtsan tsan3.go
-    testtsan tsan4.go
-    testtsan tsan8.go
-    testtsan tsan9.go
-
-    # These tests are only reliable using clang or GCC version 7 or later.
-    # Otherwise runtime/cgo/libcgo.h can't tell whether TSAN is in use.
-    ok=false
-    clang=false
-    if ${CC} --version | grep clang >/dev/null 2>&1; then
-	ok=true
-	clang=true
-    else
-	ver=$($CC -dumpversion)
-	major=$(echo $ver | sed -e 's/\([0-9]*\).*/\1/')
-	if test "$major" -lt 7; then
-	    echo "skipping remaining TSAN tests: GCC version $major (older than 7)"
-	else
-	    ok=true
-	fi
-    fi
-
-    if test "$ok" = "true"; then
-	# These tests require rebuilding os/user with -fsanitize=thread.
-	testtsan tsan5.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-	testtsan tsan6.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-	testtsan tsan7.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-
-	# The remaining tests reportedly hang when built with GCC; issue #21196.
-	if test "$clang" = "true"; then
-	    testtsan tsan10.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-	    testtsan tsan11.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-	    testtsan tsan12.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
-	fi
-
-	testtsanshared
-    fi
-fi
-
-exit $status
diff --git a/misc/cgo/testsanitizers/tsan_test.go b/misc/cgo/testsanitizers/tsan_test.go
new file mode 100644
index 0000000..ec4e003
--- /dev/null
+++ b/misc/cgo/testsanitizers/tsan_test.go
@@ -0,0 +1,56 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sanitizers_test
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestTSAN(t *testing.T) {
+	t.Parallel()
+	requireOvercommit(t)
+	config := configure("thread")
+	config.skipIfCSanitizerBroken(t)
+
+	mustRun(t, config.goCmd("build", "std"))
+
+	cases := []struct {
+		src          string
+		needsRuntime bool
+	}{
+		{src: "tsan.go"},
+		{src: "tsan2.go"},
+		{src: "tsan3.go"},
+		{src: "tsan4.go"},
+		{src: "tsan5.go", needsRuntime: true},
+		{src: "tsan6.go", needsRuntime: true},
+		{src: "tsan7.go", needsRuntime: true},
+		{src: "tsan8.go"},
+		{src: "tsan9.go"},
+		{src: "tsan10.go", needsRuntime: true},
+		{src: "tsan11.go", needsRuntime: true},
+		{src: "tsan12.go", needsRuntime: true},
+	}
+	for _, tc := range cases {
+		tc := tc
+		name := strings.TrimSuffix(tc.src, ".go")
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			dir := newTempDir(t)
+			defer dir.RemoveAll(t)
+
+			outPath := dir.Join(name)
+			mustRun(t, config.goCmd("build", "-o", outPath, srcPath(tc.src)))
+
+			cmd := hangProneCmd(outPath)
+			if tc.needsRuntime {
+				config.skipIfRuntimeIncompatible(t)
+			}
+			mustRun(t, cmd)
+		})
+	}
+}
diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go
index 9e682a2..cf049ec 100644
--- a/misc/cgo/testshared/shared_test.go
+++ b/misc/cgo/testshared/shared_test.go
@@ -10,6 +10,7 @@
 	"debug/elf"
 	"encoding/binary"
 	"errors"
+	"flag"
 	"fmt"
 	"go/build"
 	"io"
@@ -46,7 +47,7 @@
 func goCmd(t *testing.T, args ...string) {
 	newargs := []string{args[0], "-installsuffix=" + suffix}
 	if testing.Verbose() {
-		newargs = append(newargs, "-v")
+		newargs = append(newargs, "-x")
 	}
 	newargs = append(newargs, args[1:]...)
 	c := exec.Command("go", newargs...)
@@ -57,6 +58,7 @@
 		c.Stdout = os.Stdout
 		c.Stderr = os.Stderr
 		err = c.Run()
+		output = []byte("(output above)")
 	} else {
 		output, err = c.CombinedOutput()
 	}
@@ -161,6 +163,8 @@
 }
 
 func TestMain(m *testing.M) {
+	flag.Parse()
+
 	// Some of the tests install binaries into a custom GOPATH.
 	// That won't work if GOBIN is set.
 	os.Unsetenv("GOBIN")
@@ -347,10 +351,10 @@
 
 func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
 	f, err := elf.Open(path)
-	defer f.Close()
 	if err != nil {
 		t.Fatalf("elf.Open(%q) failed: %v", path, err)
 	}
+	defer f.Close()
 	dynstrings, err := f.DynString(flag)
 	if err != nil {
 		t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
@@ -461,13 +465,13 @@
 // that is not mapped into memory.
 func testPkgListNote(t *testing.T, f *elf.File, note *note) {
 	if note.section.Flags != 0 {
-		t.Errorf("package list section has flags %v", note.section.Flags)
+		t.Errorf("package list section has flags %v, want 0", note.section.Flags)
 	}
 	if isOffsetLoaded(f, note.section.Offset) {
 		t.Errorf("package list section contained in PT_LOAD segment")
 	}
 	if note.desc != "depBase\n" {
-		t.Errorf("incorrect package list %q", note.desc)
+		t.Errorf("incorrect package list %q, want %q", note.desc, "depBase\n")
 	}
 }
 
@@ -476,7 +480,7 @@
 // bytes into it.
 func testABIHashNote(t *testing.T, f *elf.File, note *note) {
 	if note.section.Flags != elf.SHF_ALLOC {
-		t.Errorf("abi hash section has flags %v", note.section.Flags)
+		t.Errorf("abi hash section has flags %v, want SHF_ALLOC", note.section.Flags)
 	}
 	if !isOffsetLoaded(f, note.section.Offset) {
 		t.Errorf("abihash section not contained in PT_LOAD segment")
@@ -497,13 +501,13 @@
 		return
 	}
 	if elf.ST_BIND(hashbytes.Info) != elf.STB_LOCAL {
-		t.Errorf("%s has incorrect binding %v", hashbytes.Name, elf.ST_BIND(hashbytes.Info))
+		t.Errorf("%s has incorrect binding %v, want STB_LOCAL", hashbytes.Name, elf.ST_BIND(hashbytes.Info))
 	}
 	if f.Sections[hashbytes.Section] != note.section {
-		t.Errorf("%s has incorrect section %v", hashbytes.Name, f.Sections[hashbytes.Section].Name)
+		t.Errorf("%s has incorrect section %v, want %s", hashbytes.Name, f.Sections[hashbytes.Section].Name, note.section.Name)
 	}
 	if hashbytes.Value-note.section.Addr != 16 {
-		t.Errorf("%s has incorrect offset into section %d", hashbytes.Name, hashbytes.Value-note.section.Addr)
+		t.Errorf("%s has incorrect offset into section %d, want 16", hashbytes.Name, hashbytes.Value-note.section.Addr)
 	}
 }
 
@@ -511,14 +515,14 @@
 // was linked against in an unmapped section.
 func testDepsNote(t *testing.T, f *elf.File, note *note) {
 	if note.section.Flags != 0 {
-		t.Errorf("package list section has flags %v", note.section.Flags)
+		t.Errorf("package list section has flags %v, want 0", note.section.Flags)
 	}
 	if isOffsetLoaded(f, note.section.Offset) {
 		t.Errorf("package list section contained in PT_LOAD segment")
 	}
 	// libdepBase.so just links against the lib containing the runtime.
 	if note.desc != soname {
-		t.Errorf("incorrect dependency list %q", note.desc)
+		t.Errorf("incorrect dependency list %q, want %q", note.desc, soname)
 	}
 }
 
@@ -556,7 +560,7 @@
 			abiHashNoteFound = true
 		case 3: // ELF_NOTE_GODEPS_TAG
 			if depsNoteFound {
-				t.Error("multiple abi hash notes")
+				t.Error("multiple depedency list notes")
 			}
 			testDepsNote(t, f, note)
 			depsNoteFound = true
@@ -696,18 +700,55 @@
 	reset(gorootInstallDir)
 }
 
-// touch makes path newer than the "old" time stamp used by resetFileStamps.
-func touch(path string) {
+// touch changes path and returns a function that changes it back.
+// It also sets the time of the file, so that we can see if it is rewritten.
+func touch(t *testing.T, path string) (cleanup func()) {
+	data, err := ioutil.ReadFile(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	old := make([]byte, len(data))
+	copy(old, data)
+	if bytes.HasPrefix(data, []byte("!<arch>\n")) {
+		// Change last digit of build ID.
+		// (Content ID in the new content-based build IDs.)
+		const marker = `build id "`
+		i := bytes.Index(data, []byte(marker))
+		if i < 0 {
+			t.Fatal("cannot find build id in archive")
+		}
+		j := bytes.IndexByte(data[i+len(marker):], '"')
+		if j < 0 {
+			t.Fatal("cannot find build id in archive")
+		}
+		i += len(marker) + j - 1
+		if data[i] == 'a' {
+			data[i] = 'b'
+		} else {
+			data[i] = 'a'
+		}
+	} else {
+		// assume it's a text file
+		data = append(data, '\n')
+	}
+	if err := ioutil.WriteFile(path, data, 0666); err != nil {
+		t.Fatal(err)
+	}
 	if err := os.Chtimes(path, nearlyNew, nearlyNew); err != nil {
-		log.Fatalf("os.Chtimes failed: %v", err)
+		t.Fatal(err)
+	}
+	return func() {
+		if err := ioutil.WriteFile(path, old, 0666); err != nil {
+			t.Fatal(err)
+		}
 	}
 }
 
 // isNew returns if the path is newer than the time stamp used by touch.
-func isNew(path string) bool {
+func isNew(t *testing.T, path string) bool {
 	fi, err := os.Stat(path)
 	if err != nil {
-		log.Fatalf("os.Stat failed: %v", err)
+		t.Fatal(err)
 	}
 	return fi.ModTime().After(stampTime)
 }
@@ -715,14 +756,16 @@
 // Fail unless path has been rebuilt (i.e. is newer than the time stamp used by
 // isNew)
 func AssertRebuilt(t *testing.T, msg, path string) {
-	if !isNew(path) {
+	t.Helper()
+	if !isNew(t, path) {
 		t.Errorf("%s was not rebuilt (%s)", msg, path)
 	}
 }
 
 // Fail if path has been rebuilt (i.e. is newer than the time stamp used by isNew)
 func AssertNotRebuilt(t *testing.T, msg, path string) {
-	if isNew(path) {
+	t.Helper()
+	if isNew(t, path) {
 		t.Errorf("%s was rebuilt (%s)", msg, path)
 	}
 }
@@ -732,41 +775,55 @@
 	goCmd(t, "install", "-linkshared", "exe")
 
 	// If the source is newer than both the .a file and the .so, both are rebuilt.
-	resetFileStamps()
-	touch("src/depBase/dep.go")
-	goCmd(t, "install", "-linkshared", "exe")
-	AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "depBase.a"))
-	AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "libdepBase.so"))
+	t.Run("newsource", func(t *testing.T) {
+		resetFileStamps()
+		cleanup := touch(t, "src/depBase/dep.go")
+		defer func() {
+			cleanup()
+			goCmd(t, "install", "-linkshared", "exe")
+		}()
+		goCmd(t, "install", "-linkshared", "exe")
+		AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "depBase.a"))
+		AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "libdepBase.so"))
+	})
 
 	// If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
-	resetFileStamps()
-	touch(filepath.Join(gopathInstallDir, "depBase.a"))
-	goCmd(t, "install", "-linkshared", "exe")
-	AssertNotRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "depBase.a"))
-	AssertRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "libdepBase.so"))
+	t.Run("newarchive", func(t *testing.T) {
+		resetFileStamps()
+		goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
+		AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
+		cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))
+		defer func() {
+			cleanup()
+			goCmd(t, "install", "-v", "-linkshared", "exe")
+		}()
+		goCmd(t, "install", "-v", "-linkshared", "exe")
+		AssertNotRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "depBase.a"))
+		AssertRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "libdepBase.so"))
+	})
 }
 
-func appendFile(path, content string) {
+func appendFile(t *testing.T, path, content string) {
 	f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0660)
 	if err != nil {
-		log.Fatalf("os.OpenFile failed: %v", err)
+		t.Fatalf("os.OpenFile failed: %v", err)
 	}
 	defer func() {
 		err := f.Close()
 		if err != nil {
-			log.Fatalf("f.Close failed: %v", err)
+			t.Fatalf("f.Close failed: %v", err)
 		}
 	}()
 	_, err = f.WriteString(content)
 	if err != nil {
-		log.Fatalf("f.WriteString failed: %v", err)
+		t.Fatalf("f.WriteString failed: %v", err)
 	}
 }
 
-func writeFile(path, content string) {
+func writeFile(t *testing.T, path, content string) {
 	err := ioutil.WriteFile(path, []byte(content), 0644)
 	if err != nil {
-		log.Fatalf("ioutil.WriteFile failed: %v", err)
+		t.Fatalf("ioutil.WriteFile failed: %v", err)
 	}
 }
 
@@ -780,7 +837,7 @@
 	// some senses but suffices for the narrow definition of ABI compatibility the
 	// toolchain uses today.
 	resetFileStamps()
-	appendFile("src/depBase/dep.go", "func ABIBreak() {}\n")
+	appendFile(t, "src/depBase/dep.go", "func ABIBreak() {}\n")
 	goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase")
 	c := exec.Command("./bin/exe")
 	output, err := c.CombinedOutput()
@@ -811,7 +868,7 @@
 	// function) and rebuild libdepBase.so, exe still works, even if new function
 	// is in a file by itself.
 	resetFileStamps()
-	writeFile("src/depBase/dep2.go", "package depBase\nfunc noABIBreak() {}\n")
+	writeFile(t, "src/depBase/dep2.go", "package depBase\nfunc noABIBreak() {}\n")
 	goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase")
 	run(t, "after non-ABI breaking change", "./bin/exe")
 }
@@ -838,3 +895,12 @@
 	goCmd(t, "install", "-linkshared", "iface")
 	run(t, "running type/itab uniqueness tester", "./bin/iface")
 }
+
+// Access a global variable from a library.
+func TestGlobal(t *testing.T) {
+	goCmd(t, "install", "-buildmode=shared", "-linkshared", "globallib")
+	goCmd(t, "install", "-linkshared", "global")
+	run(t, "global executable", "./bin/global")
+	AssertIsLinkedTo(t, "./bin/global", soname)
+	AssertHasRPath(t, "./bin/global", gorootInstallDir)
+}
diff --git a/misc/cgo/testshared/src/depBase/dep.go b/misc/cgo/testshared/src/depBase/dep.go
index 9f86710..569c210 100644
--- a/misc/cgo/testshared/src/depBase/dep.go
+++ b/misc/cgo/testshared/src/depBase/dep.go
@@ -22,7 +22,7 @@
 func (d *Dep) Method() int {
 	// This code below causes various go.itab.* symbols to be generated in
 	// the shared library. Similar code in ../exe/exe.go results in
-	// exercising https://github.com/golang/go/issues/17594
+	// exercising https://golang.org/issues/17594
 	reflect.TypeOf(os.Stdout).Elem()
 	return 10
 }
diff --git a/misc/cgo/testshared/src/division/division.go b/misc/cgo/testshared/src/division/division.go
index a0b11a5..bb5fc98 100644
--- a/misc/cgo/testshared/src/division/division.go
+++ b/misc/cgo/testshared/src/division/division.go
@@ -14,4 +14,4 @@
 	if a != 8 {
 		panic("FAIL")
 	}
-}
\ No newline at end of file
+}
diff --git a/misc/cgo/testshared/src/exe/exe.go b/misc/cgo/testshared/src/exe/exe.go
index 84302a8..bd864d8 100644
--- a/misc/cgo/testshared/src/exe/exe.go
+++ b/misc/cgo/testshared/src/exe/exe.go
@@ -25,7 +25,7 @@
 	defer depBase.ImplementedInAsm()
 	// This code below causes various go.itab.* symbols to be generated in
 	// the executable. Similar code in ../depBase/dep.go results in
-	// exercising https://github.com/golang/go/issues/17594
+	// exercising https://golang.org/issues/17594
 	reflect.TypeOf(os.Stdout).Elem()
 	runtime.GC()
 	depBase.V = depBase.F() + 1
diff --git a/misc/cgo/testshared/src/global/main.go b/misc/cgo/testshared/src/global/main.go
new file mode 100644
index 0000000..94e7f24
--- /dev/null
+++ b/misc/cgo/testshared/src/global/main.go
@@ -0,0 +1,71 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"globallib"
+)
+
+//go:noinline
+func testLoop() {
+	for i, s := range globallib.Data {
+		if s != int64(i) {
+			panic("testLoop: mismatch")
+		}
+	}
+}
+
+//go:noinline
+func ptrData() *[1<<20 + 10]int64 {
+	return &globallib.Data
+}
+
+//go:noinline
+func testMediumOffset() {
+	for i, s := range globallib.Data[1<<16-2:] {
+		if s != int64(i)+1<<16-2 {
+			panic("testMediumOffset: index mismatch")
+		}
+	}
+
+	x := globallib.Data[1<<16-1]
+	if x != 1<<16-1 {
+		panic("testMediumOffset: direct mismatch")
+	}
+
+	y := &globallib.Data[1<<16-3]
+	if y != &ptrData()[1<<16-3] {
+		panic("testMediumOffset: address mismatch")
+	}
+}
+
+//go:noinline
+func testLargeOffset() {
+	for i, s := range globallib.Data[1<<20:] {
+		if s != int64(i)+1<<20 {
+			panic("testLargeOffset: index mismatch")
+		}
+	}
+
+	x := globallib.Data[1<<20+1]
+	if x != 1<<20+1 {
+		panic("testLargeOffset: direct mismatch")
+	}
+
+	y := &globallib.Data[1<<20+2]
+	if y != &ptrData()[1<<20+2] {
+		panic("testLargeOffset: address mismatch")
+	}
+}
+
+func main() {
+	testLoop()
+
+	// SSA rules commonly merge offsets into addresses. These
+	// tests access global data in different ways to try
+	// and exercise different SSA rules.
+	testMediumOffset()
+	testLargeOffset()
+}
diff --git a/misc/cgo/testshared/src/globallib/global.go b/misc/cgo/testshared/src/globallib/global.go
new file mode 100644
index 0000000..b4372a2
--- /dev/null
+++ b/misc/cgo/testshared/src/globallib/global.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globallib
+
+// Data is large enough to that offsets into it do not fit into
+// 16-bit or 20-bit immediates. Ideally we'd also try and overrun
+// 32-bit immediates, but that requires the test machine to have
+// too much memory.
+var Data [1<<20 + 10]int64
+
+func init() {
+	for i := range Data {
+		Data[i] = int64(i)
+	}
+}
diff --git a/misc/ios/go_darwin_arm_exec.go b/misc/ios/go_darwin_arm_exec.go
index e84e513..56dbb00 100644
--- a/misc/ios/go_darwin_arm_exec.go
+++ b/misc/ios/go_darwin_arm_exec.go
@@ -49,6 +49,7 @@
 	appID    string
 	teamID   string
 	bundleID string
+	deviceID string
 )
 
 // lock is a file lock to serialize iOS runs. It is global to avoid the
@@ -77,6 +78,9 @@
 	// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
 	teamID = getenv("GOIOS_TEAM_ID")
 
+	// Device IDs as listed with ios-deploy -c.
+	deviceID = os.Getenv("GOIOS_DEVICE_ID")
+
 	parts := strings.SplitN(appID, ".", 2)
 	// For compatibility with the old builders, use a fallback bundle ID
 	bundleID = "golang.gotest"
@@ -96,7 +100,7 @@
 	//
 	// The lock file is never deleted, to avoid concurrent locks on distinct
 	// files with the same path.
-	lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec.lock")
+	lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
 	lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
 	if err != nil {
 		log.Fatal(err)
@@ -228,6 +232,16 @@
 		os.Stdout.Write(b)
 	}()
 
+	cond := func(out *buf) bool {
+		i0 := s.out.LastIndex([]byte("(lldb)"))
+		i1 := s.out.LastIndex([]byte("fruitstrap"))
+		i2 := s.out.LastIndex([]byte(" connect"))
+		return i0 > 0 && i1 > 0 && i2 > 0
+	}
+	if err := s.wait("lldb start", cond, 15*time.Second); err != nil {
+		panic(waitPanic{err})
+	}
+
 	// Script LLDB. Oh dear.
 	s.do(`process handle SIGHUP  --stop false --pass true --notify false`)
 	s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
@@ -294,7 +308,7 @@
 	if err != nil {
 		return nil, err
 	}
-	s.cmd = exec.Command(
+	cmdArgs := []string{
 		// lldb tries to be clever with terminals.
 		// So we wrap it in script(1) and be clever
 		// right back at it.
@@ -307,9 +321,13 @@
 		"-u",
 		"-r",
 		"-n",
-		`--args=`+strings.Join(args, " ")+``,
+		`--args=` + strings.Join(args, " ") + ``,
 		"--bundle", appdir,
-	)
+	}
+	if deviceID != "" {
+		cmdArgs = append(cmdArgs, "--id", deviceID)
+	}
+	s.cmd = exec.Command(cmdArgs[0], cmdArgs[1:]...)
 	if debug {
 		log.Println(strings.Join(s.cmd.Args, " "))
 	}
@@ -340,15 +358,6 @@
 		s.exited <- s.cmd.Wait()
 	}()
 
-	cond := func(out *buf) bool {
-		i0 := s.out.LastIndex([]byte("(lldb)"))
-		i1 := s.out.LastIndex([]byte("fruitstrap"))
-		i2 := s.out.LastIndex([]byte(" connect"))
-		return i0 > 0 && i1 > 0 && i2 > 0
-	}
-	if err := s.wait("lldb start", cond, 15*time.Second); err != nil {
-		panic(waitPanic{err})
-	}
 	return s, nil
 }
 
@@ -377,6 +386,9 @@
 			}
 			return fmt.Errorf("test timeout (%s)", reason)
 		case <-doTimedout:
+			if p := s.cmd.Process; p != nil {
+				p.Kill()
+			}
 			return fmt.Errorf("command timeout (%s for %v)", reason, doTimeout)
 		case err := <-s.exited:
 			return fmt.Errorf("exited (%s: %v)", reason, err)
diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto
index 8bf2540..f15a2ab 100644
--- a/misc/nacl/testzip.proto
+++ b/misc/nacl/testzip.proto
@@ -22,6 +22,9 @@
 				internal
 					syntax
 						parser.go
+			cover
+				testdata
+					+
 			doc
 				main.go
 				pkg.go
@@ -31,6 +34,9 @@
 			internal
 				objfile
 					objfile.go
+				buildid
+					testdata
+						+
 			gofmt
 				gofmt.go
 				gofmt_test.go
@@ -64,6 +70,10 @@
 								armasm
 									testdata
 										+
+							arm64
+								arm64asm
+									testdata
+										+
 							x86
 								x86asm
 									testdata
diff --git a/misc/swig/stdio/file.go b/misc/swig/stdio/file.go
new file mode 100644
index 0000000..a582f77
--- /dev/null
+++ b/misc/swig/stdio/file.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is here just to cause problems.
+// file.swig turns into a file also named file.go.
+// Make sure cmd/go keeps them separate
+// when both are passed to cgo.
+
+package file
+
+//int F(void) { return 1; }
+import "C"
+
+func F() int { return int(C.F()) }
diff --git a/misc/swig/stdio/file_test.go b/misc/swig/stdio/file_test.go
index b1a520e..aea92aa 100644
--- a/misc/swig/stdio/file_test.go
+++ b/misc/swig/stdio/file_test.go
@@ -20,3 +20,9 @@
 		t.Error("fclose failed")
 	}
 }
+
+func TestF(t *testing.T) {
+	if x := F(); x != 1 {
+		t.Fatalf("x = %d, want 1", x)
+	}
+}
diff --git a/misc/trace/trace_viewer_full.html b/misc/trace/trace_viewer_full.html
new file mode 100644
index 0000000..f0d2e60
--- /dev/null
+++ b/misc/trace/trace_viewer_full.html
@@ -0,0 +1,9525 @@
+<!DOCTYPE html>
+<html>
+  <head i18n-values="dir:textdirection;">
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+<template id="overlay-template">
+  <style>
+    overlay-mask {
+      left: 0;
+      padding: 8px;
+      position: absolute;
+      top: 0;
+      z-index: 1000;
+      font-family: sans-serif;
+      -webkit-justify-content: center;
+      background: rgba(0, 0, 0, 0.8);
+      display: flex;
+      height: 100%;
+      left: 0;
+      position: fixed;
+      top: 0;
+      width: 100%;
+    }
+    overlay-mask:focus {
+      outline: none;
+    }
+    overlay-vertical-centering-container {
+      -webkit-justify-content: center;
+      flex-direction: column;
+      display: flex;
+    }
+    overlay-frame {
+      z-index: 1100;
+      background: rgb(255, 255, 255);
+      border: 1px solid #ccc;
+      margin: 75px;
+      display: flex;
+      flex-direction: column;
+      min-height: 0;
+    }
+    title-bar {
+      -webkit-align-items: center;
+      flex-direction: row;
+      border-bottom: 1px solid #ccc;
+      background-color: #ddd;
+      display: flex;
+      padding: 5px;
+      flex: 0 0 auto;
+    }
+    title {
+      display: inline;
+      font-weight: bold;
+      flex: 1 1 auto;
+    }
+    close-button {
+      -webkit-align-self: flex-end;
+      border: 1px solid #eee;
+      background-color: #999;
+      font-size: 10pt;
+      font-weight: bold;
+      padding: 2px;
+      text-align: center;
+      width: 16px;
+    }
+    close-button:hover {
+      background-color: #ddd;
+      border-color: black;
+      cursor: pointer;
+    }
+    overlay-content {
+      display: flex;
+      flex: 1 1 auto;
+      flex-direction: column;
+      overflow-y: auto;
+      padding: 10px;
+      min-width: 300px;
+      min-height: 0;
+    }
+    button-bar {
+      -webkit-align-items: baseline;
+      border-top: 1px solid #ccc;
+      display: flex;
+      flex: 0 0 auto;
+      flex-direction: row-reverse;
+      padding: 4px;
+    }
+  </style>
+
+  <overlay-mask>
+    <overlay-vertical-centering-container>
+      <overlay-frame>
+        <title-bar>
+          <title></title>
+          <close-button>✕</close-button>
+        </title-bar>
+        <overlay-content>
+          <content></content>
+        </overlay-content>
+        <button-bar></button-bar>
+      </overlay-frame>
+    </overlay-vertical-centering-container>
+  </overlay-mask>
+</template><style>
+* /deep/ .labeled-checkbox {
+  display: flex;
+  white-space: nowrap;
+}
+</style><dom-module id="tr-ui-a-analysis-link">
+  <template>
+    <style>
+    :host {
+      display: inline;
+      cursor: pointer;
+      cursor: pointer;
+      white-space: nowrap;
+    }
+    a {
+      text-decoration: underline;
+    }
+    </style>
+    <a href="{{href}}" on-click="onClicked_" on-mouseenter="onMouseEnter_" on-mouseleave="onMouseLeave_"><content></content></a>
+
+  </template>
+</dom-module><dom-module id="tr-ui-b-table">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      table {
+        flex: 1 1 auto;
+        align-self: stretch;
+        border-collapse: separate;
+        border-spacing: 0;
+        border-width: 0;
+        -webkit-user-select: initial;
+      }
+
+      tr > td {
+        padding: 2px 4px 2px 4px;
+        vertical-align: top;
+      }
+
+      table > tbody:focus {
+        outline: none;
+      }
+      table > tbody:focus[selection-mode="row"] > tr[selected],
+      table > tbody:focus[selection-mode="cell"] > tr > td[selected],
+      table > tbody:focus > tr.empty-row > td {
+        outline: 1px dotted #666666;
+        outline-offset: -1px;
+      }
+
+      button.toggle-button {
+        height: 15px;
+        line-height: 60%;
+        vertical-align: middle;
+        width: 100%;
+      }
+
+      button > * {
+        height: 15px;
+        vertical-align: middle;
+      }
+
+      td.button-column {
+        width: 30px;
+      }
+
+      table > thead > tr > td.sensitive:hover {
+        background-color: #fcfcfc;
+      }
+
+      table > thead > tr > td {
+        font-weight: bold;
+        text-align: left;
+
+        background-color: #eee;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+
+        border-top: 1px solid #ffffff;
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot {
+        background-color: #eee;
+        font-weight: bold;
+      }
+
+      /* Light row and cell highlight. */
+      table > tbody[row-highlight-style="light"] > tr[selected],
+      table > tbody[cell-highlight-style="light"] > tr > td[selected] {
+        background-color: rgb(213, 236, 229);  /* light turquoise */
+      }
+      table > tbody[row-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #f6f6f6;  /* light grey */
+      }
+
+      /* Dark row and cell highlight. */
+      table > tbody[row-highlight-style="dark"] > tr[selected],
+      table > tbody[cell-highlight-style="dark"] > tr > td[selected] {
+        background-color: rgb(103, 199, 165);  /* turquoise */
+      }
+      table > tbody[row-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #e6e6e6;  /* grey */
+      }
+      table > tbody[row-highlight-style="dark"] > tr:hover[selected],
+      table > tbody[cell-highlight-style="dark"] > tr[selected] > td:hover {
+        background-color: rgb(171, 217, 202);  /* semi-light turquoise */
+      }
+
+      table > colgroup > col[selected] {
+        background-color: #e6e6e6;  /* grey */
+      }
+
+      table > tbody > tr.empty-row > td {
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      table > tbody.has-footer > tr:last-child > td {
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot > tr:first-child > td {
+        border-top: 1px solid #ffffff;
+      }
+
+      :host([zebra]) table tbody tr:nth-child(even) {
+        background-color: #f4f4f4;
+      }
+
+      expand-button {
+        -webkit-user-select: none;
+        cursor: pointer;
+        margin-right: 3px;
+        font-size: smaller;
+        height: 1rem;
+      }
+
+      expand-button.button-expanded {
+        transform: rotate(90deg);
+      }
+    </style>
+    <table>
+      <colgroup id="cols">
+      </colgroup>
+      <thead id="head">
+      </thead>
+      <tbody id="body">
+      </tbody>
+      <tfoot id="foot">
+      </tfoot>
+    </table>
+  </template>
+</dom-module><dom-module id="tr-ui-b-table-header-cell">
+  <template>
+  <style>
+    :host {
+      -webkit-user-select: none;
+      display: flex;
+    }
+
+    span {
+      flex: 0 1 auto;
+    }
+
+    #side {
+      -webkit-user-select: none;
+      flex: 0 0 auto;
+      padding-left: 2px;
+      padding-right: 2px;
+      vertical-align: top;
+      font-size: 15px;
+      font-family: sans-serif;
+      line-height: 85%;
+      margin-left: 5px;
+    }
+
+    #side.disabled {
+      color: rgb(140, 140, 140);
+    }
+
+    #title:empty, #side:empty {
+      display: none;
+    }
+  </style>
+
+    <span id="title"></span>
+    <span id="side"></span>
+  </template>
+</dom-module><dom-module id="tr-v-ui-scalar-context-controller">
+  <template></template>
+</dom-module><dom-module id="tr-v-ui-scalar-span">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
+      position: relative;
+      /* Limit the sparkline's negative z-index to the span only. */
+      isolation: isolate;
+    }
+
+    :host(.left-align) {
+      justify-content: flex-start;
+    }
+
+    :host(.inline) {
+      display: inline-flex;
+    }
+
+    #sparkline {
+      width: 0%;
+      position: absolute;
+      bottom: 0;
+      display: none;
+      height: 100%;
+      background-color: hsla(216, 100%, 94.5%, .75);
+      border-color: hsl(216, 100%, 89%);
+      box-sizing: border-box;
+      z-index: -1;
+    }
+    #sparkline.positive {
+      border-right-style: solid;
+      /* The border width must be kept in sync with buildSparklineStyle_(). */
+      border-right-width: 1px;
+    }
+    #sparkline:not(.positive) {
+      border-left-style: solid;
+      /* The border width must be kept in sync with buildSparklineStyle_(). */
+      border-left-width: 1px;
+    }
+    #sparkline.better {
+      background-color: hsla(115, 100%, 93%, .75);
+      border-color: hsl(118, 60%, 80%);
+    }
+    #sparkline.worse {
+      background-color: hsla(0, 100%, 88%, .75);
+      border-color: hsl(0, 100%, 80%);
+    }
+
+    #content, #significance, #warning {
+      flex-grow: 0;
+    }
+    #content.better {
+      color: green;
+    }
+    #content.worse {
+      color: red;
+    }
+
+    #significance svg {
+      margin-left: 4px;
+      display: none;
+      height: 1em;
+      vertical-align: text-top;
+      stroke-width: 4;
+      fill: rgba(0, 0, 0, 0);
+    }
+    #significance #insignificant {
+      stroke: black;
+    }
+    #significance #significantly_better {
+      stroke: green;
+    }
+    #significance #significantly_worse {
+      stroke: red;
+    }
+
+    #warning {
+      display: none;
+      margin-left: 4px;
+      height: 1em;
+      vertical-align: text-top;
+      stroke-width: 0;
+    }
+    #warning path {
+      fill: rgb(255, 185, 185);
+    }
+    #warning rect {
+      fill: red;
+    }
+    </style>
+
+    <span id="sparkline"></span>
+
+    <span id="content"></span>
+
+    <span id="significance">
+      
+      <svg id="insignificant" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <line x1="36" x2="92" y1="80" y2="80"></line>
+      </svg>
+
+      
+      <svg id="significantly_better" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <path d="M 28 64 Q 64 128 100 64"></path>
+      </svg>
+
+      
+      <svg id="significantly_worse" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <path d="M 36 96 Q 64 48 92 96"></path>
+      </svg>
+    </span>
+
+    <svg id="warning" viewBox="0 0 128 128">
+      <path d="M 64 0 L 128 128 L 0 128 L 64 0"></path>
+      <rect height="84" width="8" x="60" y="0"></rect>
+      <rect height="24" width="8" x="60" y="100"></rect>
+    </svg>
+  </template>
+</dom-module><dom-module id="tr-ui-a-generic-object-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+      font-family: monospace;
+    }
+    </style>
+    <div id="content">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-generic-object-view-with-label">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+  </template>
+</dom-module><dom-module id="tr-ui-b-drag-handle">
+  <template>
+    <style>
+    :host {
+      -webkit-user-select: none;
+      box-sizing: border-box;
+      display: block;
+    }
+
+    :host(.horizontal-drag-handle) {
+      background-image: -webkit-gradient(linear,
+                                         0 0, 0 100%,
+                                         from(#E5E5E5),
+                                         to(#D1D1D1));
+      border-bottom: 1px solid #8e8e8e;
+      border-top: 1px solid white;
+      cursor: ns-resize;
+      flex: 0 0 auto;
+      height: 7px;
+      position: relative;
+    }
+
+    :host(.vertical-drag-handle) {
+      background-image: -webkit-gradient(linear,
+                                         0 0, 100% 0,
+                                         from(#E5E5E5),
+                                         to(#D1D1D1));
+      border-left: 1px solid white;
+      border-right: 1px solid #8e8e8e;
+      cursor: ew-resize;
+      flex: 0 0 auto;
+      position: relative;
+      width: 7px;
+    }
+    </style>
+    <div></div>
+  </template>
+</dom-module><dom-module id="tv-ui-b-hotkey-controller">
+  <template>
+    <div></div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-info-bar">
+  <template>
+    <style>
+    :host {
+      align-items: center;
+      flex: 0 0 auto;
+      background-color: rgb(252, 235, 162);
+      border-bottom: 1px solid #A3A3A3;
+      border-left: 1px solid white;
+      border-right: 1px solid #A3A3A3;
+      border-top: 1px solid white;
+      display: flex;
+      height: 26px;
+      padding: 0 3px 0 3px;
+    }
+
+    :host([hidden]) {
+      display: none !important;
+    }
+
+    #message { flex: 1 1 auto; }
+    </style>
+
+    <span id="message"></span>
+    <span id="buttons"></span>
+  </template>
+</dom-module><style>
+* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
+</style><dom-module id="tr-ui-b-mouse-mode-icon">
+  <template>
+    <style>
+    :host {
+      display: block;
+      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
+      width: 27px;
+      height: 30px;
+    }
+    :host.active {
+      cursor: auto;
+    }
+    </style>
+  </template>
+</dom-module><dom-module id="tr-ui-b-mouse-mode-selector">
+  <template>
+    <style>
+    :host {
+
+      -webkit-user-drag: element;
+      -webkit-user-select: none;
+
+      background: #DDD;
+      border: 1px solid #BBB;
+      border-radius: 4px;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+      left: calc(100% - 120px);
+      position: absolute;
+      top: 100px;
+      user-select: none;
+      width: 29px;
+      z-index: 20;
+    }
+
+    .drag-handle {
+      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      cursor: move;
+      display: block;
+      height: 13px;
+      width: 27px;
+    }
+
+    .tool-button {
+      background-position: center center;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      border-top: 1px solid #F1F1F1;
+      cursor: pointer;
+    }
+
+    .buttons > .tool-button:last-child {
+      border-bottom: none;
+    }
+
+    </style>
+    <div class="drag-handle"></div>
+    <div class="buttons">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-e-chrome-cc-display-item-list-item">
+  <template>
+    <style>
+      :host {
+        border-bottom: 1px solid #555;
+        display: block;
+        font-size: 12px;
+        padding: 3px 5px;
+      }
+
+      :host(:hover) {
+        background-color: #f0f0f0;
+        cursor: pointer;
+      }
+
+      .header {
+        font-weight: bold;
+        margin: 2px 0;
+      }
+
+      .header > .extra {
+        background-color: #777;
+        border-radius: 4px;
+        color: white;
+        margin: 0 6px;
+        text-decoration: none;
+        padding: 2px 4px;
+      }
+
+      .raw-details {
+        white-space: pre-wrap;
+      }
+
+      .details > dl {
+        margin: 0;
+      }
+
+      :host(:not([selected])) .details {
+        display: none;
+      }
+    </style>
+    <div class="header">
+      {{name}}
+      <template if="{{_computeIf(richDetails)}}" is="dom-if">
+        <a class="extra" download="drawing.skp" href$="{{_computeHref(richDetails)}}" on-click="{{stopPropagation}}">SKP</a>
+      </template>
+    </div>
+    <div class="details">
+      <template if="{{rawDetails}}">
+        <div class="raw-details">{{rawDetails}}</div>
+      </template>
+      <template bind="{{richDetails}}" if="{{richDetails}}" is="dom-if">
+        <dl>
+          <template bind="{{cullRect}}" if="{{cullRect}}" is="dom-if">
+            <dt>Cull rect</dt>
+            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
+          </template>
+          <template bind="{{visualRect}}" if="{{visualRect}}" is="dom-if">
+            <dt>Visual rect</dt>
+            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
+          </template>
+        </dl>
+      </template>
+    </div>
+  </template>
+
+</dom-module><style>
+* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{flex-direction:column;border-top:1px solid grey;display:flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
+</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
+    flex: 1 1 auto;
+    display: flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
+    flex-direction: column;
+    display: flex;
+    min-width: 300px;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info {
+    flex: 1 1 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .export {
+    margin: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > tr-ui-b-drag-handle {
+    flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
+    flex: 1 1 auto;
+    display: flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > header {
+    border-bottom: 1px solid #555;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-b-drag-handle.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-list-view {
+    display: none;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-b-drag-handle {
+    display: none;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
+    flex: 1 1 auto;
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <display-item-info>
+      <header>
+        <span class="title">Display Item List</span>
+        <span class="size"></span>
+        <div class="export">
+          <input class="dlfilename" type="text" value="displayitemlist.json"/>
+          <button class="dlexport">Export display item list</button>
+        </div>
+        <div class="export">
+          <input class="skpfilename" type="text" value="skpicture.skp"/>
+          <button class="skpexport">Export list as SkPicture</button>
+        </div>
+      </header>
+    </display-item-info>
+  </left-panel>
+  <right-panel>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{flex:1 1 auto!important;display:flex}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-layer-picker{flex-direction:column;display:flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
+</style><style>
+* /deep/ quad-stack-view {
+  display: block;
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  position: relative; /* For the absolute positioned mouse-mode-selector */
+  width: 100%;
+}
+
+* /deep/ quad-stack-view > #header {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  left: 10px;
+  width: 800px;
+}
+* /deep/ quad-stack-view > #stacking-distance-slider {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  right: 10px;
+}
+
+* /deep/ quad-stack-view > #chrome-left {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-mid {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-right {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
+  display: none;
+}
+</style><template id="quad-stack-view-template">
+  <div id="header"></div>
+  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
+  
+  <canvas id="canvas"></canvas>
+  <img id="chrome-left"/>
+  <img id="chrome-mid"/>
+  <img id="chrome-right"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
+  position: relative;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
+  flex: 0 0 auto;
+  background-image: -webkit-gradient(linear,
+                                     0 0, 100% 0,
+                                     from(#E5E5E5),
+                                     to(#D1D1D1));
+  border-bottom: 1px solid #8e8e8e;
+  border-top: 1px solid white;
+  display: flex;
+  flex-flow: row wrap;
+  flex-direction: row;
+  font-size:  14px;
+  padding-left: 2px;
+  overflow: hidden;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
+      top-controls input[type='checkbox'] {
+  vertical-align: -2px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
+  color: -webkit-link;
+  cursor: pointer;
+  text-decoration: underline;
+  position: absolute;
+  bottom: 10px;
+  left: 10px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
+  display: none;
+}
+</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
+  <img id="input-event"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-view{flex-direction:column;display:flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{flex:1 1 100%;flex-direction:column;min-height:0;display:flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
+</style><style>
+* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{flex:1 1 auto!important;flex-direction:row;display:flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-b-drag-handle{flex:0 0 auto}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
+</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
+    flex: 1 1 auto;
+    flex-direction: row;
+    display: flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
+    flex-direction: column;
+    display: flex;
+    width: 400px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
+    flex-direction: column;
+    display: flex;
+    min-width: 300px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
+    flex: 0 0 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
+        picture-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-b-drag-handle {
+    flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
+    -webkit-user-select: text;
+    margin-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
+    flex: 1 1 auto;
+    flex-direction: column;
+    display: flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-chart-view {
+    min-height: 150px;
+    min-width : 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <picture-info>
+      <div>
+        <span class="title">Skia Picture</span>
+        <span class="size"></span>
+      </div>
+      <div>
+        <input class="filename" type="text" value="skpicture.skp"/>
+        <button class="export">Export</button>
+      </div>
+    </picture-info>
+  </left-panel>
+  <right-panel>
+    <tr-ui-e-chrome-cc-picture-ops-chart-view>
+    </tr-ui-e-chrome-cc-picture-ops-chart-view>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{flex:0 1 auto!important;display:flex}
+</style><dom-module id="tr-ui-a-stack-frame">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex: 0 1;
+      flex-direction: column;
+    }
+    #table {
+      flex: 0 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-chrome-cc-raster-task-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #heading {
+      flex: 0 0 auto;
+    }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+
+    <div id="heading">
+      Rasterization costs in
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </div>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+</dom-module><style>
+.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
+</style><dom-module id="tr-ui-a-layout-tree-sub-view">
+  <template>
+    <style>
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-e-s-frame-data-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      width: 600px;
+      flex-direction: column;
+    }
+    table-container {
+      display: flex;
+      overflow: auto;
+      font-size: 12px;
+    }
+    </style>
+    <div>
+      Organize by:
+      <select id="select">
+        <option value="none">None</option>
+        <option value="tree">Frame Tree</option>
+      </select>
+    </div>
+    <table-container>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </table-container>
+  </template>
+</dom-module><dom-module id="tr-ui-b-chart-legend-key">
+  <template>
+    <style>
+      #checkbox {
+        margin: 0;
+        visibility: hidden;
+        vertical-align: text-top;
+      }
+      #label, #link {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        display: inline-block;
+      }
+    </style>
+
+    <input checked="" id="checkbox" type="checkbox"/>
+    <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    <label id="label"></label>
+  </template>
+</dom-module><style>
+  * /deep/ .chart-base {
+    -webkit-user-select: none;
+    cursor: default;
+  }
+
+  * /deep/ .chart-base .axis path,
+  * /deep/ .chart-base .axis line {
+    fill: none;
+    shape-rendering: crispEdges;
+    stroke: #000;
+  }
+</style><template id="chart-base-template">
+  <svg> 
+    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
+      <g class="x axis"></g>
+      <g class="y axis"></g>
+      <text id="title"></text>
+    </g>
+  </svg>
+</template><style>
+  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
+    fill: rgb(103, 199, 165)
+  }
+
+  * /deep/ .chart-base-2d #brushes {
+    fill: rgb(213, 236, 229)
+  }
+</style><dom-module id="tr-ui-e-s-input-latency-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+</dom-module><dom-module id="tr-ui-b-heading">
+  <template>
+    <style>
+    :host {
+      background-color: rgb(243, 245, 247);
+      border-right: 1px solid #8e8e8e;
+      display: block;
+      height: 100%;
+      margin: 0;
+      padding: 0 5px 0 0;
+    }
+
+    heading {
+      display: block;
+      overflow-x: hidden;
+      text-align: left;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    #arrow {
+      flex: 0 0 auto;
+      font-family: sans-serif;
+      margin-left: 5px;
+      margin-right: 5px;
+      width: 8px;
+    }
+
+    #link, #heading_content {
+      display: none;
+    }
+    </style>
+    <heading id="heading" on-click="onHeadingDivClicked_">
+      <span id="arrow"></span>
+      <span id="heading_content"></span>
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </heading>
+  </template>
+</dom-module><style>
+.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
+</style><style>
+.object-instance-track{height:18px}
+</style><style>
+.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><style>
+.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
+</style><dom-module id="tr-ui-e-v8-gc-objects-stats-table">
+  <template>
+    <style>
+    tr-ui-b-table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+    .diff {
+      display: inline-block;
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    </style>
+    <div class="diff" id="diffOption">
+      Diff
+    </div>
+    <tr-ui-b-table id="diffTable"></tr-ui-b-table>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view">
+  <template>
+    <style>
+    </style>
+    <tr-ui-e-v8-gc-objects-stats-table id="gcObjectsStats">
+    </tr-ui-e-v8-gc-objects-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-v8-ic-stats-table">
+  <template>
+    <style>
+    tr-ui-b-table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+    #total {
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    #groupOption {
+      display: inline-block;
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    </style>
+    <div style="padding-right: 200px">
+      <div style="float:right;  border-style: solid; border-width: 1px; padding:20px">
+        0 uninitialized<br/>
+        . premonomorphic<br/>
+        1 monomorphic<br/>
+        ^ recompute handler<br/>
+        P polymorphic<br/>
+        N megamorphic<br/>
+        G generic
+      </div>
+    </div>
+    <div id="total">
+    </div>
+    <div id="groupOption">
+      Group Key
+    </div>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-e-v8-ic-stats-table id="table">
+    </tr-ui-e-v8-ic-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-v8-runtime-call-stats-table">
+  <template>
+    <style>
+    #table, #blink_rcs_table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+
+    #v8_rcs_heading, #blink_rcs_heading {
+        padding-top: 1em;
+        font-size: 18px;
+    }
+    </style>
+    <h1 id="v8_rcs_heading"></h1>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+    <h1 id="blink_rcs_heading"></h1>
+    <tr-ui-b-table id="blink_rcs_table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-multi-thread-slice-sub-view id="content"></tr-ui-a-multi-thread-slice-sub-view>
+    <tr-ui-e-v8-runtime-call-stats-table id="runtimeCallStats"></tr-ui-e-v8-runtime-call-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-gc-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <tr-ui-e-v8-gc-objects-stats-table id="gcObjectsStats"></tr-ui-e-v8-gc-objects-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-ic-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-e-v8-ic-stats-table id="table">
+    </tr-ui-e-v8-ic-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-single-thread-slice-sub-view id="content"></tr-ui-a-single-thread-slice-sub-view>
+    <tr-ui-e-v8-runtime-call-stats-table id="runtimeCallStats"></tr-ui-e-v8-runtime-call-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-alert-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-b-tab-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #selection_description, #tabs {
+        font-size: 12px;
+      }
+
+      #selection_description {
+        display: inline-block;
+        font-weight: bold;
+        margin: 9px 0px 4px 20px;
+      }
+
+      #tabs {
+        flex: 0 0 auto;
+        border-top: 1px solid #8e8e8e;
+        border-bottom: 1px solid #8e8e8e;
+        background-color: #ececec;
+        overflow: hidden;
+        margin: 0;
+      }
+
+      #tabs input[type=radio] {
+        display: none;
+      }
+
+      #tabs tab label {
+        cursor: pointer;
+        display: inline-block;
+        border: 1px solid #ececec;
+        margin: 5px 0px 0px 15px;
+        padding: 3px 10px 3px 10px;
+      }
+
+      #tabs tab label span {
+        font-weight: bold;
+      }
+
+      #tabs:focus input[type=radio]:checked ~ label {
+        outline: dotted 1px #8e8e8e;
+        outline-offset: -2px;
+      }
+
+      #tabs input[type=radio]:checked ~ label {
+        background-color: white;
+        border: 1px solid #8e8e8e;
+        border-bottom: 1px solid white;
+      }
+
+      #subView {
+        flex: 1 1 auto;
+        overflow: auto;
+      }
+    </style>
+    <div hidden="[[tabsHidden]]" id="tabs">
+      <label id="selection_description">[[label_]]</label>
+      <template is="dom-repeat" items="[[subViews_]]">
+        <tab>
+          <input checked="[[isChecked_(item)]]" id$="[[computeRadioId_(item)]]" name="tabs" on-change="onTabChanged_" type="radio"/>
+          <label for$="[[computeRadioId_(item)]]">
+            <template if="[[item.tabIcon]]" is="dom-if">
+              <span style$="[[item.tabIcon.style]]">[[item.tabIcon.text]]</span>
+            </template>
+            [[item.tabLabel]]
+          </label>
+        </tab>
+      </template>
+    </div>
+    <div id="subView"></div>
+    <content>
+    </content>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-breakdown-view">
+  <template>
+    <tr-ui-b-tab-view id="tabs"></tr-ui-b-tab-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-breakdown-view-tab">
+  <template>
+    <tr-v-ui-scalar-context-controller></tr-v-ui-scalar-context-controller>
+    <tr-ui-b-info-bar hidden="" id="info"></tr-ui-b-info-bar>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-path-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+    </style>
+    <tr-v-ui-scalar-context-controller></tr-v-ui-scalar-context-controller>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #header {
+        flex: 0 0 auto;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 8px;
+        font-size: 15px;
+        font-weight: bold;
+      }
+
+      #view_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #split_view {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+        flex-direction: row;
+      }
+
+      #path_view {
+        width: 50%;
+      }
+
+      #breakdown_view {
+        flex: 1 1 auto;
+        width: 0;
+      }
+
+      #path_view, #breakdown_view {
+        overflow-x: auto;  /* Show scrollbar if necessary. */
+      }
+    </style>
+    <div id="header">
+      <div id="label">Heap details</div>
+      <div id="view_mode_container">
+        <span>View mode:</span>
+        
+      </div>
+    </div>
+    <div id="contents">
+      <tr-ui-b-info-bar hidden="" id="info_bar">
+      </tr-ui-b-info-bar>
+
+      <div id="info_text">No heap dump selected</div>
+
+      <div id="split_view">
+        <tr-ui-a-memory-dump-heap-details-path-view id="path_view">
+        </tr-ui-a-memory-dump-heap-details-path-view>
+        <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
+        <tr-ui-a-memory-dump-heap-details-breakdown-view id="breakdown_view">
+        </tr-ui-a-memory-dump-heap-details-breakdown-view>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-allocator-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+    </style>
+    <div id="label">Component details</div>
+    <div id="contents">
+      <div id="info_text">No memory allocator dump selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-vm-regions-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+    </style>
+    <div id="label">Memory maps</div>
+    <div id="contents">
+      <div id="info_text">No memory maps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-color-legend">
+  <template>
+    <style>
+    :host {
+      display: inline-block;
+    }
+
+    #square {
+      font-size: 150%;  /* Make the square bigger. */
+      line-height: 0%;  /* Prevent the square from increasing legend height. */
+    }
+    </style>
+    <span id="square"></span>
+    <span id="label"></span>
+  </template>
+</dom-module><dom-module id="tr-ui-b-view-specific-brushing-state">
+  <template></template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-overview-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #label a {
+        font-weight: normal;
+        float: right;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+        overflow: auto;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+    </style>
+    <tr-ui-b-view-specific-brushing-state id="state" view-id="analysis.memory_dump_overview_pane">
+    </tr-ui-b-view-specific-brushing-state>
+    <div id="label">Overview <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra">Help</a></div>
+    <div id="contents">
+      <div id="info_text">No memory memory dumps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-header-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #d0d0d0;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 6px;
+        font-size: 15px;
+      }
+
+      #aggregation_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+    </style>
+    
+    <div id="label"></div>
+    <div id="aggregation_mode_container">
+      <span>Metric aggregation:</span>
+      
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-stacked-pane-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+
+    #pane_container > * {
+      flex: 0 0 auto;
+    }
+    </style>
+    <div id="pane_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-container-memory-dump-sub-view">
+  <template>
+    <style>
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-counter-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-event-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+</dom-module><dom-module id="tr-ui-a-selection-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+</dom-module><dom-module id="tr-ui-b-radio-picker">
+  <template>
+    <style>
+    :host([vertical]) #container {
+      flex-direction: column;
+    }
+    :host(:not[vertical]) #container {
+      flex-direction: row;
+    }
+    #container {
+      display: flex;
+    }
+    #container > div {
+      padding-left: 1em;
+      padding-bottom: 0.5em;
+    }
+    </style>
+    <div id="container"></div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-breakdown-span">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table_container {
+      display: flex;
+      flex: 0 0 auto;
+    }
+    #table {
+      max-height: 150px;
+      overflow-y: auto;
+    }
+    </style>
+
+    <div id="empty">(empty)</div>
+    <div id="table_container">
+      <div id="container"></div>
+      <span>
+        <tr-ui-b-table id="table"></tr-ui-b-table>
+      </span>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-collected-related-event-set-span">
+</dom-module><dom-module id="tr-v-ui-date-range-span">
+  <template>
+    <content></content>
+  </template>
+</dom-module><dom-module id="tr-v-ui-generic-set-span">
+  <template>
+    <style>
+      a {
+        display: block;
+      }
+    </style>
+
+    <tr-ui-a-generic-object-view id="generic"></tr-ui-a-generic-object-view>
+
+    <template is="dom-repeat" items="{{strings_}}">
+      <template if="[[isUrl_(item)]]" is="dom-if">
+        <a href="[[item]]">[[item]]</a>
+      </template>
+
+      <template if="[[!isUrl_(item)]]" is="dom-if">
+        <div>[[item]]</div>
+      </template>
+    </template>
+  </template>
+</dom-module><dom-module id="tr-v-ui-related-event-set-span">
+</dom-module><dom-module id="tr-v-ui-related-histogram-map-span">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-v-ui-scalar-diagnostic-span">
+  <template>
+    <tr-v-ui-scalar-span id="scalar"></tr-v-ui-scalar-span>
+  </template>
+</dom-module><dom-module id="tr-v-ui-tag-map-span">
+  <template>
+    <style>
+    #hide, #generic {
+      display: none;
+    }
+    </style>
+    <button id="show" on-click="onShow_">Show</button>
+    <button id="hide" on-click="onHide_">Hide</button>
+    <tr-ui-a-generic-object-view id="generic"></tr-ui-a-generic-object-view>
+  </template>
+</dom-module><dom-module id="tr-v-ui-unmergeable-diagnostic-set-span">
+</dom-module><dom-module id="tr-v-ui-diagnostic-map-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module name="tr-v-ui-scalar-map-table">
+  <template>
+    <style>
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-span">
+  <template>
+    <style>
+    #container {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+    }
+    #chart {
+      flex-grow: 1;
+      display: none;
+    }
+    #drag_handle, #diagnostics_tab_templates {
+      display: none;
+    }
+    #chart svg {
+      display: block;
+    }
+    #stats_container {
+      overflow-y: auto;
+    }
+    </style>
+
+    <div id="container">
+      <div id="chart"></div>
+      <div id="stats_container">
+        <tr-v-ui-scalar-map-table id="stats"></tr-v-ui-scalar-map-table>
+      </div>
+    </div>
+    <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
+
+    <tr-ui-b-tab-view id="diagnostics"></tr-ui-b-tab-view>
+
+    <div id="diagnostics_tab_templates">
+      <tr-v-ui-diagnostic-map-table id="metric_diagnostics"></tr-v-ui-diagnostic-map-table>
+
+      <tr-v-ui-diagnostic-map-table id="metadata_diagnostics"></tr-v-ui-diagnostic-map-table>
+
+      <div id="sample_diagnostics_container">
+        <div id="merge_sample_diagnostics_container">
+          <input checked="" id="merge_sample_diagnostics" on-change="updateDiagnostics_" type="checkbox"/>
+          <label for="merge_sample_diagnostics">Merge Sample Diagnostics</label>
+        </div>
+        <tr-v-ui-diagnostic-map-table id="sample_diagnostics"></tr-v-ui-diagnostic-map-table>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      overflow: auto;
+    }
+    #content {
+      display: flex;
+      flex-direction: column;
+      flex: 0 1 auto;
+      align-self: stretch;
+    }
+    #content > * {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    #histogramContainer {
+      display: flex;
+    }
+
+    tr-ui-a-multi-event-summary-table {
+      border-bottom: 1px solid #aaa;
+    }
+
+    tr-ui-a-selection-summary-table  {
+      margin-top: 1.25em;
+      border-top: 1px solid #aaa;
+      background-color: #eee;
+      font-weight: bold;
+      margin-bottom: 1.25em;
+      border-bottom: 1px solid #aaa;
+    }
+    </style>
+    <div id="content">
+      <tr-ui-a-multi-event-summary-table id="eventSummaryTable">
+      </tr-ui-a-multi-event-summary-table>
+      <tr-ui-a-selection-summary-table id="selectionSummaryTable">
+      </tr-ui-a-selection-summary-table>
+      <tr-ui-b-radio-picker id="radioPicker">
+      </tr-ui-b-radio-picker>
+      <div id="histogramContainer">
+        <tr-v-ui-histogram-span id="histogramSpan">
+        </tr-v-ui-histogram-span>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-related-events">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #container {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="container">
+      <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+      <div id="events">
+        <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-cpu-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-object-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-frame-power-usage-chart">
+  <template>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-power-sample-summary-table">
+  <template>
+    <style>
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-power-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #tables {
+      display: flex;
+      flex-direction: column;
+      width: 50%;
+    }
+    #chart {
+      width: 50%;
+    }
+    </style>
+    <div id="tables">
+      <tr-ui-a-power-sample-summary-table id="summaryTable">
+      </tr-ui-a-power-sample-summary-table>
+    </div>
+    <tr-ui-a-frame-power-usage-chart id="chart">
+    </tr-ui-a-frame-power-usage-chart>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+                                         from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+    #control::-webkit-scrollbar { height: 0px; }
+    #control {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+      margin: 1px;
+      margin-right: 2px;
+    }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <div id="control">
+      Sample View Option
+    </div>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #content > tr-ui-a-related-events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-thread-time-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-user-expectation-related-samples-table">
+  <template>
+    <style>
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-user-expectation-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="realView"></tr-ui-a-multi-event-sub-view>
+    <div id="events">
+      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display:flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-cpu-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-v-ui-scalar-span id="start">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-v-ui-scalar-span id="duration">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Active slices:</td><td id="running-thread"></td>
+      </tr>
+      <tr>
+        <td>Args:</td>
+        <td>
+          <tr-ui-a-generic-object-view id="args">
+          </tr-ui-a-generic-object-view>
+        </td>
+      </tr>
+    </tbody></table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <tr-ui-a-single-event-sub-view id="singleEventSubView">
+    </tr-ui-a-single-event-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-frame-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #asv {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-a-alert-sub-view id="asv">
+    </tr-ui-a-alert-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-object-instance-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #snapshots > * {
+      display: block;
+    }
+
+    :host {
+      overflow: auto;
+      display: block;
+    }
+
+    * {
+      -webkit-user-select: text;
+    }
+
+    .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-object-snapshot-sub-view">
+  <template>
+    <style>
+    #args {
+      white-space: pre;
+    }
+
+    :host {
+      overflow: auto;
+      display: flex;
+    }
+
+    ::content * {
+      -webkit-user-select: text;
+    }
+
+    ::content .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    ::content td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <content></content>
+  </template>
+</dom-module><dom-module id="tr-ui-a-power-sample-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-power-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    </style>
+    <tr-ui-a-power-sample-table id="samplesTable">
+    </tr-ui-a-power-sample-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
+
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents">
+      </tr-ui-a-related-events>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-thread-time-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>State:</td>
+        <td><b><span id="state"></span></b></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-v-ui-scalar-span id="start">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-v-ui-scalar-span id="duration">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+
+      <tr>
+        <td>On CPU:</td><td id="on-cpu"></td>
+      </tr>
+
+      <tr>
+        <td>Running instead:</td><td id="running-instead"></td>
+      </tr>
+
+      <tr>
+        <td>Args:</td><td id="args"></td>
+      </tr>
+    </tbody></table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-user-expectation-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-a-single-event-sub-view id="realView"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-analysis-view">
+  <template>
+    <style>
+      :host {
+        background-color: white;
+        display: flex;
+        flex-direction: column;
+        height: 275px;
+        overflow: auto;
+      }
+
+      :host(.tall-mode) {
+        height: 525px;
+      }
+    </style>
+    <content></content>
+  </template>
+</dom-module><dom-module id="tr-ui-b-dropdown">
+  <template>
+    <style>
+    :host {
+      position: relative;
+      display: flex;
+    }
+    #outer {
+      display: flex;
+      flex: 0 0 auto;
+      padding: 1px 4px 1px 4px;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #state {
+      display: flex;
+      flex: 0 0 auto;
+      margin-left: 2px;
+      margin-right: 0px;
+      flex: 0 0 auto;
+    }
+
+    #icon {
+      display: flex;
+      flex: 0 0 auto;
+      flex: 0 0 auto;
+    }
+    dialog {
+      position: absolute;
+      padding: 0;
+      border: 0;
+      margin: 0;
+    }
+    dialog::backdrop {
+      background: rgba(0,0,0,.05);
+    }
+
+    #dialog-frame {
+      background-color: #fff;
+      display: flex;
+      flex-direction: column;
+      flex: 1 1 auto;
+      padding: 6px;
+      border: 1px solid black;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+    </style>
+    <tr-ui-b-toolbar-button id="outer" on-click="onOuterClick_" on-keydown="onOuterKeyDown_">
+      <div id="icon">⚙</div>
+      <div id="state">▾</div>
+    </tr-ui-b-toolbar-button>
+    <dialog id="dialog" on-cancel="onDialogCancel_" on-click="onDialogClick_">
+      <div id="dialog-frame">
+        <content></content>
+      </div>
+    </dialog>
+  </template>
+</dom-module><dom-module id="tr-ui-b-info-bar-group">
+  <template>
+    <style>
+    :host {
+      flex: 0 0 auto;
+      flex-direction: column;
+      display: flex;
+    }
+    </style>
+    <div id="messages"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-toolbar-button">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      background-color: #f8f8f8;
+      border: 1px solid rgba(0, 0, 0, 0.5);
+      color: rgba(0,0,0,0.8);
+      justify-content: center;
+      align-self: stretch;
+      min-width: 23px;
+    }
+
+    :host(:hover) {
+      background-color: rgba(255, 255, 255, 1.0);
+      border-color: rgba(0, 0, 0, 0.8);
+      box-shadow: 0 0 .05em rgba(0, 0, 0, 0.4);
+      color: rgba(0, 0, 0, 1);
+    }
+
+    #aligner {
+      display: flex;
+      flex: 0 0 auto;
+      align-self: center;
+    }
+    </style>
+    <div id="aligner">
+      <content></content>
+    </div>
+  </template>
+</dom-module><style>
+.drawing-container{display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{display:block;pointer-events:none;position:absolute;top:0}
+</style><style>
+.letter-dot-track {
+  height: 18px;
+}
+</style><style>
+.chart-track {
+  height: 30px;
+  position: relative;
+}
+</style><style>
+.cpu-usage-track {
+  height: 90px;
+}
+</style><style>
+.power-series-track {
+  height: 90px;
+}
+</style><style>
+.spacing-track{height:4px}
+</style><style>
+.rect-track{height:18px}
+</style><style>
+.thread-track{flex-direction:column;display:flex;position:relative}
+</style><style>
+.process-track-header{flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}
+</style><style>
+.model-track {
+  flex-grow: 1;
+}
+</style><style>
+.x-axis-track {
+  height: 12px;
+}
+
+.x-axis-track.tall-mode {
+  height: 30px;
+}
+</style><dom-module id="tr-ui-timeline-track-view">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+      position: relative;
+    }
+
+    :host ::content * {
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #drag_box {
+      background-color: rgba(0, 0, 255, 0.25);
+      border: 1px solid rgb(0, 0, 96);
+      font-size: 75%;
+      position: fixed;
+    }
+
+    #hint_text {
+      position: absolute;
+      bottom: 6px;
+      right: 6px;
+      font-size: 8pt;
+    }
+    </style>
+    <content></content>
+
+    <div id="drag_box"></div>
+    <div id="hint_text"></div>
+
+    <tv-ui-b-hotkey-controller id="hotkey_controller">
+    </tv-ui-b-hotkey-controller>
+  </template>
+</dom-module><dom-module id="tr-ui-find-control">
+  <template>
+    <style>
+      :host {
+        -webkit-user-select: none;
+        display: flex;
+        position: relative;
+      }
+      input {
+        -webkit-user-select: auto;
+        background-color: #f8f8f8;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        box-sizing: border-box;
+        margin: 0;
+        padding: 0;
+        width: 170px;
+      }
+      input:focus {
+        background-color: white;
+      }
+      tr-ui-b-toolbar-button {
+        border-left: none;
+        margin: 0;
+      }
+      #hitCount {
+        left: 0;
+        opacity: 0.25;
+        pointer-events: none;
+        position: absolute;
+        text-align: right;
+        top: 2px;
+        width: 167px;
+        z-index: 1;
+      }
+      #spinner {
+        visibility: hidden;
+        width: 8px;
+        height: 8px;
+        left: 154px;
+        pointer-events: none;
+        position: absolute;
+        top: 4px;
+        z-index: 1;
+
+        border: 2px solid transparent;
+        border-bottom: 2px solid rgba(0, 0, 0, 0.5);
+        border-right: 2px solid rgba(0, 0, 0, 0.5);
+        border-radius: 50%;
+      }
+      @keyframes spin { 100% { transform: rotate(360deg); } }
+    </style>
+
+    <input id="filter" on-blur="filterBlur" on-focus="filterFocus" on-input="filterTextChanged" on-keydown="filterKeyDown" on-mouseup="filterMouseUp" type="text"/>
+    <div id="spinner"></div>
+    <tr-ui-b-toolbar-button on-click="findPrevious">
+      ←
+    </tr-ui-b-toolbar-button>
+    <tr-ui-b-toolbar-button on-click="findNext">
+      →
+    </tr-ui-b-toolbar-button>
+    <div id="hitCount">0 of 0</div>
+  </template>
+</dom-module><dom-module id="tr-ui-scripting-control">
+  <template>
+    <style>
+      :host {
+        flex: 1 1 auto;
+      }
+      .root {
+        font-family: monospace;
+        cursor: text;
+
+        padding: 2px;
+        margin: 2px;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        background: white;
+
+        height: 100px;
+        overflow-y: auto;
+
+        transition-property: opacity, height, padding, margin;
+        transition-duration: .2s;
+        transition-timing-function: ease-out;
+      }
+      .hidden {
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding-top: 0px;
+        padding-bottom: 0px;
+        height: 0px;
+        opacity: 0;
+      }
+      .focused {
+        outline: auto 5px -webkit-focus-ring-color;
+      }
+      #history {
+        -webkit-user-select: text;
+        color: #777;
+      }
+      #promptContainer {
+        display: flex;
+      }
+      #promptMark {
+        width: 1em;
+        color: #468;
+      }
+      #prompt {
+        flex: 1;
+        width: 100%;
+        border: none !important;
+        background-color: inherit !important;
+        font: inherit !important;
+        text-overflow: clip !important;
+        text-decoration: none !important;
+      }
+      #prompt:focus {
+        outline: none;
+      }
+    </style>
+
+    <div class="root hidden" id="root" on-focus="onConsoleFocus" tabindex="0">
+      <div id="history"></div>
+      <div id="promptContainer">
+        <span id="promptMark">&gt;</span>
+        <input id="prompt" on-blur="onConsoleBlur" on-keydown="promptKeyDown" on-keypress="promptKeyPress" type="text"/>
+       </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-side-panel-container">
+  <template>
+    <style>
+    :host {
+      align-items: stretch;
+      display: flex;
+      background-color: white;
+    }
+
+    :host([expanded]) > #side_panel_drag_handle,
+    :host([expanded]) > active-panel-container {
+      flex: 1 1 auto;
+      border-left: 1px solid black;
+      display: flex;
+    }
+
+    :host(:not([expanded])) > #side_panel_drag_handle,
+    :host(:not([expanded])) > active-panel-container {
+      display: none;
+    }
+
+    active-panel-container {
+      display: flex;
+    }
+
+    tab-strip {
+      flex: 0 0 auto;
+      flex-direction: column;
+      -webkit-user-select: none;
+      background-color: rgb(236, 236, 236);
+      border-left: 1px solid black;
+      cursor: default;
+      display: flex;
+      min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
+      padding: 10px 0 10px 0;
+      font-size: 12px;
+    }
+
+    tab-strip > tab-strip-label {
+      flex-shrink: 0;
+      -webkit-writing-mode: vertical-rl;
+      white-space: nowrap;
+      display: inline;
+      margin-right: 1px;
+      min-height: 20px;
+      padding: 15px 3px 15px 1px;
+    }
+
+    tab-strip >
+        tab-strip-label:not([enabled]) {
+      color: rgb(128, 128, 128);
+    }
+
+    tab-strip > tab-strip-label[selected] {
+      background-color: white;
+      border: 1px solid rgb(163, 163, 163);
+      border-left: none;
+      padding: 14px 2px 14px 1px;
+    }
+
+    #active_panel_container {
+      overflow: auto;
+    }
+    </style>
+
+    <tr-ui-b-drag-handle id="side_panel_drag_handle"></tr-ui-b-drag-handle>
+    <active-panel-container id="active_panel_container">
+    </active-panel-container>
+    <tab-strip id="tab_strip"></tab-strip>
+  </template>
+</dom-module><dom-module id="tr-ui-timeline-view-help-overlay">
+  <template>
+    <style>
+    :host {
+      flex: 1 1 auto;
+      flex-direction: row;
+      display: flex;
+      width: 700px;
+    }
+    .column {
+      width: 50%;
+    }
+    h2 {
+      font-size: 1.2em;
+      margin: 0;
+      margin-top: 5px;
+      text-align: center;
+    }
+    h3 {
+      margin: 0;
+      margin-left: 126px;
+      margin-top: 10px;
+    }
+    .pair {
+      flex: 1 1 auto;
+      flex-direction: row;
+      display: flex;
+    }
+    .command {
+      font-family: monospace;
+      margin-right: 5px;
+      text-align: right;
+      width: 150px;
+    }
+    .action {
+      font-size: 0.9em;
+      text-align: left;
+      width: 200px;
+    }
+    tr-ui-b-mouse-mode-icon {
+      border: 1px solid #888;
+      border-radius: 3px;
+      box-shadow: inset 0 0 2px rgba(0,0,0,0.3);
+      display: inline-block;
+      margin-right: 1px;
+      position: relative;
+      top: 4px;
+    }
+    .mouse-mode-icon.pan-mode {
+      background-position: -1px -11px;
+    }
+    .mouse-mode-icon.select-mode {
+      background-position: -1px -41px;
+    }
+    .mouse-mode-icon.zoom-mode {
+      background-position: -1px -71px;
+    }
+    .mouse-mode-icon.timing-mode {
+      background-position: -1px -101px;
+    }
+    </style>
+    <div class="column left">
+      <h2>Navigation</h2>
+      <div class="pair">
+        <div class="command">w/s</div>
+        <div class="action">Zoom in/out (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">a/d</div>
+        <div class="action">Pan left/right (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">→/shift-TAB</div>
+        <div class="action">Select previous event</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">←/TAB</div>
+        <div class="action">Select next event</div>
+      </div>
+
+      <h2>Mouse Controls</h2>
+      <div class="pair">
+        <div class="command">click</div>
+        <div class="action">Select event</div>
+      </div>
+      <div class="pair">
+        <div class="command">alt-mousewheel</div>
+        <div class="action">Zoom in/out</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon mode-name="SELECTION"></tr-ui-b-mouse-mode-icon>
+        Select mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Box select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command"><span class="mod"></span>-click/drag</div>
+        <div class="action">Add events to the current selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Select all events with same title</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon mode-name="PANSCAN"></tr-ui-b-mouse-mode-icon>
+        Pan mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Pan the view</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon mode-name="ZOOM"></tr-ui-b-mouse-mode-icon>
+        Zoom mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Zoom in/out by dragging up/down</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon mode-name="TIMING"></tr-ui-b-mouse-mode-icon>
+        Timing mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Create or move markers</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Set marker range to slice</div>
+      </div>
+    </div>
+
+    <div class="column right">
+      <h2>General</h2>
+      <div class="pair">
+        <div class="command">1-4</div>
+        <div class="action">Switch mouse mode</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">shift</div>
+        <div class="action">Hold for temporary select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">space</div>
+        <div class="action">Hold for temporary pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">/</div>
+        <div class="action">Search</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">enter</div>
+        <div class="action">Step through search results</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">f</div>
+        <div class="action">Zoom into selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">z/0</div>
+        <div class="action">Reset zoom and pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">g/G</div>
+        <div class="action">Toggle 60hz grid</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">v</div>
+        <div class="action">Highlight VSync</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">h</div>
+        <div class="action">Toggle low/high details</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">m</div>
+        <div class="action">Mark current selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">p</div>
+        <div class="action">Select power samples over current selection interval</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">`</div>
+        <div class="action">Show or hide the scripting console</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">?</div>
+        <div class="action">Show help</div>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-timeline-view-metadata-overlay">
+  <template>
+    <style>
+    :host {
+      width: 700px;
+
+      overflow: auto;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-timeline-view">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      cursor: default;
+      display: flex;
+      font-family: sans-serif;
+      padding: 0;
+    }
+
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+          from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+
+    #control::-webkit-scrollbar { height: 0px; }
+
+    #control > #bar {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      margin: 1px;
+    }
+
+    #control > #bar > #title {
+      display: flex;
+      align-items: center;
+      padding-left: 8px;
+      padding-right: 8px;
+      flex: 1 1 auto;
+    }
+
+    #control > #bar > #left_controls,
+    #control > #bar > #right_controls {
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+    }
+
+    #control > #bar > #left_controls > * { margin-right: 2px; }
+    #control > #bar > #right_controls > * { margin-left: 2px; }
+    #control > #collapsing_controls { display: flex; }
+
+    middle-container {
+      flex: 1 1 auto;
+      flex-direction: row;
+      border-bottom: 1px solid #8e8e8e;
+      display: flex;
+      min-height: 0;
+    }
+
+    middle-container ::content track-view-container {
+      flex: 1 1 auto;
+      display: flex;
+      min-height: 0;
+      min-width: 0;
+      overflow-x: hidden;
+    }
+
+    middle-container ::content track-view-container > * { flex: 1 1 auto; }
+    middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
+    tr-ui-b-drag-handle { flex: 0 0 auto; }
+    tr-ui-a-analysis-view { flex: 0 0 auto; }
+    </style>
+
+    <tv-ui-b-hotkey-controller id="hkc"></tv-ui-b-hotkey-controller>
+    <div id="control">
+      <div id="bar">
+        <div id="left_controls"></div>
+        <div id="title">^_^</div>
+        <div id="right_controls">
+          <tr-ui-b-toolbar-button id="view_metadata_button">
+            M
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-dropdown id="view_options_dropdown"></tr-ui-b-dropdown>
+          <tr-ui-find-control id="view_find_control"></tr-ui-find-control>
+          <tr-ui-b-toolbar-button id="view_console_button">
+            »
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-toolbar-button id="view_help_button">
+            ?
+          </tr-ui-b-toolbar-button>
+        </div>
+      </div>
+      <div id="collapsing_controls"></div>
+      <tr-ui-b-info-bar-group id="import-warnings">
+      </tr-ui-b-info-bar-group>
+    </div>
+    <middle-container>
+      <content></content>
+
+      <tr-ui-side-panel-container id="side_panel_container">
+      </tr-ui-side-panel-container>
+    </middle-container>
+    <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
+    <tr-ui-a-analysis-view id="analysis"></tr-ui-a-analysis-view>
+
+    <tr-v-ui-preferred-display-unit id="display_unit">
+    </tr-v-ui-preferred-display-unit>
+  </template>
+</dom-module><dom-module id="tr-ui-b-grouping-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-b-grouping-table-groupby-picker">
+  <template>
+    <style>
+    #container {
+      display: flex;
+    }
+    #container *:not(:first-child) {
+      padding-left: 3px;
+      border-left: 1px solid black;
+      margin-left: 3px;
+    }
+    </style>
+
+    <div id="container"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-grouping-table-groupby-picker-group">
+  <template>
+    <style>
+    :host {
+      white-space: nowrap;
+    }
+    #left, #right {
+      user-select: none;
+      cursor: pointer;
+    }
+    </style>
+
+    <span id="left" on-click="moveLeft_">◀</span>
+    <input id="enabled" on-change="onEnableChanged_" type="checkbox"/>
+    <label for="enabled" id="label"></label>
+    <span id="right" on-click="moveRight_">▶</span>
+  </template>
+</dom-module><dom-module id="tr-ui-sp-file-size-stats-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    toolbar {
+      align-items: center;
+      background-color: rgb(236, 236, 236);
+      border-bottom: 1px solid #8e8e8e;
+      display: flex;
+      flex-direction: row;
+      flex-direction: row;
+      flex: 0 0 auto;
+      font-size: 12px;
+      padding: 0 10px 0 10px;
+    }
+    table-container {
+      display: flex;
+      min-height: 0px;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar>
+      <span><b>Group by:</b></span>
+      <tr-ui-b-grouping-table-groupby-picker id="picker">
+      </tr-ui-b-grouping-table-groupby-picker>
+    </toolbar>
+    <table-container>
+      <tr-ui-b-grouping-table id="table"></tr-ui-b-grouping-table>
+    </table-container>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-controls">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #help, #feedback {
+      display: none;
+      margin-left: 20px;
+    }
+
+    #search {
+      max-width: 20em;
+      margin-right: 20px;
+    }
+
+    #controls {
+      white-space: nowrap;
+    }
+
+    #show_overview, #hide_overview {
+      height: 1em;
+      margin-right: 20px;
+    }
+
+    #show_overview {
+      stroke: blue;
+      stroke-width: 16;
+    }
+
+    #show_overview:hover {
+      background: blue;
+      stroke: white;
+    }
+
+    #hide_overview {
+      display: none;
+      stroke-width: 18;
+      stroke: black;
+    }
+
+    #hide_overview:hover {
+      background: black;
+      stroke: white;
+    }
+
+    #reference_display_label {
+      display: none;
+      margin-right: 20px;
+    }
+
+    #alpha, #alpha_slider_container {
+      display: none;
+    }
+
+    #alpha {
+      margin-right: 20px;
+    }
+
+    #alpha_slider_container {
+      background: white;
+      border: 1px solid black;
+      flex-direction: column;
+      padding: 0.5em;
+      position: absolute;
+      z-index: 10; /* scalar-span uses z-index :-( */
+    }
+
+    #alpha_slider {
+      -webkit-appearance: slider-vertical;
+      align-self: center;
+      height: 200px;
+      width: 30px;
+    }
+
+    #statistic {
+      display: none;
+      margin-right: 20px;
+    }
+
+    #download_csv {
+      margin-right: 20px;
+    }
+    </style>
+
+    <div id="controls">
+      <input id="search" placeholder="Find Histogram name" value="{{searchQuery::keyup}}"/>
+
+      <svg id="show_overview" on-click="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <line x1="19" x2="49" y1="109" y2="49"></line>
+        <line x1="49" x2="79" y1="49" y2="79"></line>
+        <line x1="79" x2="109" y1="79" y2="19"></line>
+      </svg>
+      <svg id="hide_overview" on-click="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <line x1="28" x2="100" y1="28" y2="100"></line>
+        <line x1="28" x2="100" y1="100" y2="28"></line>
+      </svg>
+
+      <select id="reference_display_label" value="{{referenceDisplayLabel::change}}">
+        <option value="">Select a reference column</option>
+      </select>
+
+      <button id="alpha" on-click="openAlphaSlider_">α=[[alphaString]]</button>
+      <div id="alpha_slider_container">
+        <input id="alpha_slider" max="18" min="0" on-blur="closeAlphaSlider_" on-input="updateAlpha_" type="range" value="{{alphaIndex::change}}"/>
+      </div>
+
+      <select id="statistic" value="{{displayStatisticName::change}}">
+      </select>
+
+      <button id="download_csv" on-click="downloadCSV_">⬇ CSV</button>
+
+      <input checked="{{showAll::change}}" id="show_all" title="When unchecked, less important histograms are hidden." type="checkbox"/>
+      <label for="show_all" title="When unchecked, less important histograms are hidden.">Show all</label>
+
+      <a id="help">Help</a>
+      <a id="feedback">Feedback</a>
+    </div>
+
+    <tr-ui-b-grouping-table-groupby-picker id="picker">
+    </tr-ui-b-grouping-table-groupby-picker>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-cell">
+  <template>
+    <style>
+    #histogram_container {
+      display: flex;
+      flex-direction: row;
+    }
+
+    #missing, #empty, #unmergeable, #scalar {
+      flex-grow: 1;
+    }
+
+    #open_histogram, #close_histogram, #open_histogram svg, #close_histogram svg {
+      height: 1em;
+    }
+
+    #open_histogram svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    :host(:hover) #open_histogram svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #scalar {
+      flex-grow: 1;
+      white-space: nowrap;
+    }
+
+    #histogram {
+      flex-grow: 1;
+    }
+
+    #close_histogram svg line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histogram:hover svg {
+      background: black;
+    }
+    #close_histogram:hover svg line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="histogram_container">
+      <span id="missing">(missing)</span>
+      <span id="empty">(empty)</span>
+      <span id="unmergeable">(unmergeable)</span>
+
+      <tr-v-ui-scalar-span id="scalar" on-click="openHistogram_"></tr-v-ui-scalar-span>
+
+      <span id="open_histogram" on-click="openHistogram_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
+
+      <span id="histogram"></span>
+
+      <span id="close_histogram" on-click="closeHistogram_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
+
+    <div id="overview_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-name-cell">
+  <template>
+    <style>
+    #name_container {
+      display: flex;
+    }
+
+    #name {
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    #show_overview, #hide_overview, #show_overview svg, #hide_overview svg {
+      height: 1em;
+      margin-left: 5px;
+    }
+
+    #show_overview svg {
+      stroke: blue;
+      stroke-width: 16;
+    }
+
+    #show_overview:hover svg {
+      background: blue;
+      stroke: white;
+    }
+
+    #hide_overview {
+      display: none;
+    }
+
+    #hide_overview svg {
+      stroke-width: 18;
+      stroke: black;
+    }
+
+    #hide_overview:hover svg {
+      background: black;
+      stroke: white;
+    }
+
+    #open_histograms, #close_histograms, #open_histograms svg, #close_histograms svg {
+      height: 1em;
+    }
+
+    #close_histograms {
+      display: none;
+    }
+
+    #open_histograms svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    #open_histograms:hover svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #close_histograms line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histograms:hover {
+      background: black;
+    }
+    #close_histograms:hover line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="name_container">
+      <span id="name"></span>
+
+      <span id="show_overview" on-click="showOverview_">
+        <svg viewBox="0 0 128 128">
+          <line x1="19" x2="49" y1="109" y2="49"></line>
+          <line x1="49" x2="79" y1="49" y2="79"></line>
+          <line x1="79" x2="109" y1="79" y2="19"></line>
+        </svg>
+      </span>
+
+      <span id="hide_overview" on-click="hideOverview_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+
+      <span id="open_histograms" on-click="openHistograms_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
+
+      <span id="close_histograms" on-click="closeHistograms_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
+
+    <div id="overview_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table">
+  <template>
+    <style>
+    :host {
+      min-height: 0px;
+      overflow: auto;
+    }
+    #table {
+      margin-top: 5px;
+    }
+    </style>
+
+    <tr-ui-b-table id="table">
+  </tr-ui-b-table></template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-view">
+  <template>
+    <style>
+    :host {
+      font-family: sans-serif;
+    }
+
+    #zero {
+      color: red;
+      /* histogram-set-table is used by both metrics-side-panel and results2.html.
+       * This font-size rule has no effect in results2.html, but improves
+       * legibility in the metrics-side-panel, which sets font-size in order to
+       * make this table denser.
+       */
+      font-size: initial;
+    }
+
+    #container {
+      display: none;
+    }
+    </style>
+
+    <div id="zero">zero Histograms</div>
+
+    <div id="container">
+      <tr-v-ui-histogram-set-controls id="controls">
+      </tr-v-ui-histogram-set-controls>
+
+      <tr-v-ui-histogram-set-table id="table"></tr-v-ui-histogram-set-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-sp-metrics-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    div#error {
+      color: red;
+    }
+    #results {
+      font-size: 12px;
+    }
+    </style>
+
+    <top-left-controls id="top_left_controls"></top-left-controls>
+
+    <tr-v-ui-histogram-set-view id="results"></tr-v-ui-histogram-set-view>
+
+    <div id="error"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-e-s-alerts-side-panel">
+  <template>
+    <style>
+    :host {
+      display: block;
+      width: 250px;
+    }
+    #content {
+      flex-direction: column;
+      display: flex;
+    }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+
+    <div id="content">
+      <toolbar id="toolbar"></toolbar>
+      <result-area id="result_area"></result-area>
+    </div>
+  </template>
+</dom-module><script>
+
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/* WARNING: This file is auto generated.
+ *
+ * Do not edit directly.
+ */
+
+'use strict';if(window.Polymer){throw new Error('Cannot proceed. Polymer already present.');}
+window.Polymer={};window.Polymer.dom='shadow';(function(){function resolve(){document.body.removeAttribute('unresolved');}
+if(window.WebComponents){addEventListener('WebComponentsReady',resolve);}else{if(document.readyState==='interactive'||document.readyState==='complete'){resolve();}else{addEventListener('DOMContentLoaded',resolve);}}}());window.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split('&');for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split('=');o[0]&&(settings[o[0]]=o[1]||true);}}
+settings.wantShadow=settings.dom==='shadow';settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean('import'in document.createElement('link'));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match('AppleWebKit/601')&&window.CSS&&CSS.supports&&CSS.supports('box-shadow','0 0 0 var(--foo)');settings.useNativeCSSProperties=settings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;settings.isIE=navigator.userAgent.match('Trident');return settings;}()};(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype==='function'){prototype=prototype.prototype;}
+if(!prototype){prototype={};}
+prototype=desugar(prototype);var customCtor=prototype===prototype.constructor.prototype?prototype.constructor:null;var options={prototype:prototype};if(prototype.extends){options.extends=prototype.extends;}
+Polymer.telemetry._registrate(prototype);var ctor=document.registerElement(prototype.is,options);return customCtor||ctor;};var desugar=function(prototype){var base=Polymer.Base;if(prototype.extends){base=Polymer.Base._getExtendedPrototype(prototype.extends);}
+prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype;};if(userPolymer){for(var i in userPolymer){Polymer[i]=userPolymer[i];}}
+Polymer.Class=function(prototype){if(!prototype.factoryImpl){prototype.factoryImpl=function(){};}
+return desugar(prototype).constructor;};}());Polymer.telemetry={registrations:[],_regLog:function(prototype){console.log('['+prototype.is+']: registered');},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype);},dumpRegistrations:function(){this.registrations.forEach(this._regLog);}};Object.defineProperty(window,'currentImport',{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument;}});Polymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready){cb();}else{this._callbacks.push(cb);}},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++){this._callbacks[i]();}
+this._callbacks=[];},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady();});},_afterNextRenderQueue:[],_waitingNextRender:false,afterNextRender:function(element,fn,args){this._watchNextRender();this._afterNextRenderQueue.push([element,fn,args]);},hasRendered:function(){return this._ready;},_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=true;var fn=function(){Polymer.RenderStatus._flushNextRender();};if(!this._ready){this.whenReady(fn);}else{requestAnimationFrame(fn);}}},_flushNextRender:function(){var self=this;setTimeout(function(){self._flushRenderCallbacks(self._afterNextRenderQueue);self._afterNextRenderQueue=[];self._waitingNextRender=false;});},_flushRenderCallbacks:function(callbacks){for(var i=0,h;i<callbacks.length;i++){h=callbacks[i];h[1].apply(h[0],h[2]||Polymer.nar);}}};if(window.HTMLImports){HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender();});}else{Polymer.RenderStatus._catchFirstRender();}
+Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;(function(){'use strict';var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.mixin(this,feature);},registerCallback:function(){if(settings.lazyRegister==='max'){if(this.beforeRegister){this.beforeRegister();}}else{this._desugarBehaviors();for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(this);}}
+if(this.beforeRegister){this.beforeRegister();}}
+this._registerFeatures();if(!settings.lazyRegister){this.ensureRegisterFinished();}},createdCallback:function(){if(settings.disableUpgradeEnabled){if(this.hasAttribute('disable-upgrade')){this._propertySetter=disableUpgradePropertySetter;this._configValue=null;this.__data__={};return;}else{this.__hasInitialized=true;}}
+this.__initialize();},__initialize:function(){if(!this.__hasRegisterFinished){this._ensureRegisterFinished(this.__proto__);}
+Polymer.telemetry.instanceCount++;this.root=this;for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.created){b.created.call(this);}}
+if(this.created){this.created();}
+this._initFeatures();},ensureRegisterFinished:function(){this._ensureRegisterFinished(this);},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is||!proto.is){if(settings.lazyRegister==='max'){proto._desugarBehaviors();for(var i=0,b;i<proto.behaviors.length;i++){b=proto.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(proto);}}}
+proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures){proto._finishRegisterFeatures();}
+for(var j=0,pb;j<proto.behaviors.length;j++){pb=proto.behaviors[j];if(pb.registered){pb.registered.call(proto);}}
+if(proto.registered){proto.registered();}
+if(settings.usePolyfillProto&&proto!==this){proto.extend(this,proto);}}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.attached){b.attached.call(self);}}
+if(self.attached){self.attached();}});},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=false;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.detached){b.detached.call(self);}}
+if(self.detached){self.detached();}});},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.attributeChanged){b.attributeChanged.call(this,name,oldValue,newValue);}}
+if(this.attributeChanged){this.attributeChanged(name,oldValue,newValue);}},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,name);},extend:function(target,source){if(target&&source){var n$=Object.getOwnPropertyNames(source);for(var i=0,n;i<n$.length&&(n=n$[i]);i++){this.copyOwnProperty(n,source,target);}}
+return target||source;},mixin:function(target,source){for(var i in source){target[i]=source[i];}
+return target;},copyOwnProperty:function(name,source,target){var pd=Object.getOwnPropertyDescriptor(source,name);if(pd){Object.defineProperty(target,name,pd);}},_logger:function(level,args){if(args.length===1&&Array.isArray(args[0])){args=args[0];}
+switch(level){case'log':case'warn':case'error':console[level].apply(console,args);break;}},_log:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('log',args);},_warn:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('warn',args);},_error:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('error',args);},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0));}};Polymer.Base._logPrefix=function(){var color=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent);return color?['%c[%s::%s]:','font-weight: bold; background-color:#EEEE00;']:['[%s::%s]:'];}();Polymer.Base.chainObject=function(object,inherited){if(object&&inherited&&object!==inherited){if(!Object.__proto__){object=Polymer.Base.extend(Object.create(inherited),object);}
+object.__proto__=inherited;}
+return object;};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors={};var disableUpgradePropertySetter;if(settings.disableUpgradeEnabled){disableUpgradePropertySetter=function(property,value){this.__data__[property]=value;};var origAttributeChangedCallback=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(name,oldValue,newValue){if(!this.__hasInitialized&&name==='disable-upgrade'){this.__hasInitialized=true;this._propertySetter=Polymer.Bind._modelApi._propertySetter;this._configValue=Polymer.Base._configValue;this.__initialize();}
+origAttributeChangedCallback.call(this,name,oldValue,newValue);};}
+if(window.CustomElements){Polymer.instanceof=CustomElements.instanceof;}else{Polymer.instanceof=function(obj,ctor){return obj instanceof ctor;};}
+Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__);};Polymer.telemetry.instanceCount=0;}());(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()];};var DomModule=function(){return document.createElement('dom-module');};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(DomModule.prototype,{createdCallback:function(){this.register();},register:function(id){id=id||this.id||this.getAttribute('name')||this.getAttribute('is');if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this;}},import:function(id,selector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id);}
+if(m&&selector){m=m.querySelector(selector);}
+return m;}}});Object.defineProperty(DomModule.prototype,'constructor',{value:DomModule,configurable:true,writable:true});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement('dom-module',DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||document;var modules=doc.querySelectorAll('dom-module');for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--){if(m.__upgraded__){return;}else{CustomElements.upgrade(m);}}}}}());Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName==='dom-module'){var id=module.id||module.getAttribute('name')||module.getAttribute('is');this.is=id;}}
+if(this.is){this.is=this.is.toLowerCase();}}});Polymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){if(this.behaviors.length){this.behaviors=this._desugarSomeBehaviors(this.behaviors);}},_desugarSomeBehaviors:function(behaviors){var behaviorSet=[];behaviors=this._flattenBehaviorsList(behaviors);for(var i=behaviors.length-1;i>=0;i--){var b=behaviors[i];if(behaviorSet.indexOf(b)===-1){this._mixinBehavior(b);behaviorSet.unshift(b);}}
+return behaviorSet;},_flattenBehaviorsList:function(behaviors){var flat=[];for(var i=0;i<behaviors.length;i++){var b=behaviors[i];if(b instanceof Array){flat=flat.concat(this._flattenBehaviorsList(b));}else if(b){flat.push(b);}else{this._warn(this._logf('_flattenBehaviorsList','behavior is null, check for missing or 404 import'));}}
+return flat;},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);var useAssignment=b._noAccessors;for(var i=0,n;i<n$.length&&(n=n$[i]);i++){if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n)){if(useAssignment){this[n]=b[n];}else{this.copyOwnProperty(n,b,this);}}}},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors);},_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++){this._prepBehavior(behaviors[i]);}
+this._prepBehavior(this);},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++){this._marshalBehavior(this.behaviors[i]);}
+this._marshalBehavior(this);}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true,_noAccessors:true};Polymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag);},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(Polymer.Base);for(var i=0,n;i<p$.length&&(n=p$[i]);i++){if(!Polymer.BaseDescriptors[n]){p[n]=Polymer.Base[n];}}
+Object.defineProperties(p,Polymer.BaseDescriptors);this._nativePrototypes[tag]=p;}
+return p;},getNativePrototype:function(tag){return Object.getPrototypeOf(document.createElement(tag));}});Polymer.Base._addFeature({_prepConstructor:function(){this._factoryArgs=this.extends?[this.extends,this.is]:[this.is];var ctor=function(){return this._factory(arguments);};if(this.hasOwnProperty('extends')){ctor.extends=this.extends;}
+Object.defineProperty(this,'constructor',{value:ctor,writable:true,configurable:true});ctor.prototype=this;},_factory:function(args){var elt=document.createElement.apply(document,this._factoryArgs);if(this.factoryImpl){this.factoryImpl.apply(elt,args);}
+return elt;}});Polymer.nob=Object.create(null);Polymer.Base._addFeature({getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info){for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info){return info;}}}
+return info||Polymer.nob;},_getPropertyInfo:function(property,properties){var p=properties&&properties[property];if(typeof p==='function'){p=properties[property]={type:p};}
+if(p){p.defined=true;}
+return p;},_prepPropertyInfo:function(){this._propertyInfo={};for(var i=0;i<this.behaviors.length;i++){this._addPropertyInfo(this._propertyInfo,this.behaviors[i].properties);}
+this._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects);},_addPropertyInfo:function(target,source){if(source){var t,s;for(var i in source){t=target[i];s=source[i];if(i[0]==='_'&&!s.readOnly){continue;}
+if(!target[i]){target[i]={type:typeof s==='function'?s:s.type,readOnly:s.readOnly,attribute:Polymer.CaseMap.camelToDashCase(i)};}else{if(!t.type){t.type=s.type;}
+if(!t.readOnly){t.readOnly=s.readOnly;}}}}}});(function(){var propertiesDesc={configurable:true,writable:true,enumerable:true,value:{}};Polymer.BaseDescriptors.properties=propertiesDesc;Object.defineProperty(Polymer.Base,'properties',propertiesDesc);}());Polymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf('-')<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase();}));},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,'-$1').toLowerCase());}};Polymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes){this._aggregatedAttributes={};}
+if(attributes){this.mixin(this._aggregatedAttributes,attributes);}},_marshalHostAttributes:function(){if(this._aggregatedAttributes){this._applyAttributes(this,this._aggregatedAttributes);}},_applyAttributes:function(node,attr$){for(var n in attr$){if(!this.hasAttribute(n)&&n!=='class'){var v=attr$[n];this.serializeValueToAttribute(v,n,this);}}},_marshalAttributes:function(){this._takeAttributesToModel(this);},_takeAttributesToModel:function(model){if(this.hasAttributes()){for(var i in this._propertyInfo){var info=this._propertyInfo[i];if(this.hasAttribute(info.attribute)){this._setAttributeToProperty(model,info.attribute,i,info);}}}},_setAttributeToProperty:function(model,attribute,property,info){if(!this._serializing){property=property||Polymer.CaseMap.dashToCamelCase(attribute);info=info||this._propertyInfo&&this._propertyInfo[property];if(info&&!info.readOnly){var v=this.getAttribute(attribute);model[property]=this.deserialize(v,info.type);}}},_serializing:false,reflectPropertyToAttribute:function(property,attribute,value){this._serializing=true;value=value===undefined?this[property]:value;this.serializeValueToAttribute(value,attribute||Polymer.CaseMap.camelToDashCase(property));this._serializing=false;},serializeValueToAttribute:function(value,attribute,node){var str=this.serialize(value);node=node||this;if(str===undefined){node.removeAttribute(attribute);}else{node.setAttribute(attribute,str);}},deserialize:function(value,type){switch(type){case Number:value=Number(value);break;case Boolean:value=value!=null;break;case Object:try{value=JSON.parse(value);}catch(x){}
+break;case Array:try{value=JSON.parse(value);}catch(x){value=null;console.warn('Polymer::Attributes: couldn`t decode Array as JSON');}
+break;case Date:value=new Date(value);break;case String:default:break;}
+return value;},serialize:function(value){switch(typeof value){case'boolean':return value?'':undefined;case'object':if(value instanceof Date){return value.toString();}else if(value){try{return JSON.stringify(value);}catch(x){return'';}}
+default:return value!=null?value:undefined;}}});Polymer.version="1.8.1";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors();}});Polymer.Base._addFeature({_prepTemplate:function(){if(this._template===undefined){this._template=Polymer.DomModule.import(this.is,'template');}
+if(this._template&&this._template.hasAttribute('is')){this._warn(this._logf('_prepTemplate','top-level Polymer template '+'must not be a type-extension, found',this._template,'Move inside simple <template>.'));}
+if(this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate){HTMLTemplateElement.decorate(this._template);}},_stampTemplate:function(){if(this._template){this.root=this.instanceTemplate(this._template);}},instanceTemplate:function(template){var dom=document.importNode(template._content||template.content,true);return dom;}});(function(){var baseAttachedCallback=Polymer.Base.attachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(host){this.dataHost=host=host||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1];if(host&&host._clients){host._clients.push(this);}
+this._clients=null;this._clientsReadied=false;},_beginHosting:function(){Polymer.Base._hostStack.push(this);if(!this._clients){this._clients=[];}},_endHosting:function(){Polymer.Base._hostStack.pop();},_tryReady:function(){this._readied=false;if(this._canReady()){this._ready();}},_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied;},_ready:function(){this._beforeClientsReady();if(this._template){this._setupRoot();this._readyClients();}
+this._clientsReadied=true;this._clients=null;this._afterClientsReady();this._readySelf();},_readyClients:function(){this._beginDistribute();var c$=this._clients;if(c$){for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._ready();}}
+this._finishDistribute();},_readySelf:function(){for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.ready){b.ready.call(this);}}
+if(this.ready){this.ready();}
+this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback();}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this);}else{this._attachedPending=true;}}});}());Polymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount};}
+var EDIT_LEAVE=0;var EDIT_UPDATE=1;var EDIT_ADD=2;var EDIT_DELETE=3;function ArraySplice(){}
+ArraySplice.prototype={calcEditDistances:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var rowCount=oldEnd-oldStart+1;var columnCount=currentEnd-currentStart+1;var distances=new Array(rowCount);for(var i=0;i<rowCount;i++){distances[i]=new Array(columnCount);distances[i][0]=i;}
+for(var j=0;j<columnCount;j++)
+distances[0][j]=j;for(i=1;i<rowCount;i++){for(j=1;j<columnCount;j++){if(this.equals(current[currentStart+j-1],old[oldStart+i-1]))
+distances[i][j]=distances[i-1][j-1];else{var north=distances[i-1][j]+1;var west=distances[i][j-1]+1;distances[i][j]=north<west?north:west;}}}
+return distances;},spliceOperationsFromEditDistances:function(distances){var i=distances.length-1;var j=distances[0].length-1;var current=distances[i][j];var edits=[];while(i>0||j>0){if(i==0){edits.push(EDIT_ADD);j--;continue;}
+if(j==0){edits.push(EDIT_DELETE);i--;continue;}
+var northWest=distances[i-1][j-1];var west=distances[i-1][j];var north=distances[i][j-1];var min;if(west<north)
+min=west<northWest?west:northWest;else
+min=north<northWest?north:northWest;if(min==northWest){if(northWest==current){edits.push(EDIT_LEAVE);}else{edits.push(EDIT_UPDATE);current=northWest;}
+i--;j--;}else if(min==west){edits.push(EDIT_DELETE);i--;current=west;}else{edits.push(EDIT_ADD);j--;current=north;}}
+edits.reverse();return edits;},calcSplices:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var prefixCount=0;var suffixCount=0;var minLength=Math.min(currentEnd-currentStart,oldEnd-oldStart);if(currentStart==0&&oldStart==0)
+prefixCount=this.sharedPrefix(current,old,minLength);if(currentEnd==current.length&&oldEnd==old.length)
+suffixCount=this.sharedSuffix(current,old,minLength-prefixCount);currentStart+=prefixCount;oldStart+=prefixCount;currentEnd-=suffixCount;oldEnd-=suffixCount;if(currentEnd-currentStart==0&&oldEnd-oldStart==0)
+return[];if(currentStart==currentEnd){var splice=newSplice(currentStart,[],0);while(oldStart<oldEnd)
+splice.removed.push(old[oldStart++]);return[splice];}else if(oldStart==oldEnd)
+return[newSplice(currentStart,[],currentEnd-currentStart)];var ops=this.spliceOperationsFromEditDistances(this.calcEditDistances(current,currentStart,currentEnd,old,oldStart,oldEnd));splice=undefined;var splices=[];var index=currentStart;var oldIndex=oldStart;for(var i=0;i<ops.length;i++){switch(ops[i]){case EDIT_LEAVE:if(splice){splices.push(splice);splice=undefined;}
+index++;oldIndex++;break;case EDIT_UPDATE:if(!splice)
+splice=newSplice(index,[],0);splice.addedCount++;index++;splice.removed.push(old[oldIndex]);oldIndex++;break;case EDIT_ADD:if(!splice)
+splice=newSplice(index,[],0);splice.addedCount++;index++;break;case EDIT_DELETE:if(!splice)
+splice=newSplice(index,[],0);splice.removed.push(old[oldIndex]);oldIndex++;break;}}
+if(splice){splices.push(splice);}
+return splices;},sharedPrefix:function(current,old,searchLength){for(var i=0;i<searchLength;i++)
+if(!this.equals(current[i],old[i]))
+return i;return searchLength;},sharedSuffix:function(current,old,searchLength){var index1=current.length;var index2=old.length;var count=0;while(count<searchLength&&this.equals(current[--index1],old[--index2]))
+count++;return count;},calculateSplices:function(current,previous){return this.calcSplices(current,0,current.length,previous,0,previous.length);},equals:function(currentValue,previousValue){return currentValue===previousValue;}};return new ArraySplice();}();Polymer.domInnerHTML=function(){var escapeAttrRegExp=/[&\u00A0"]/g;var escapeDataRegExp=/[&\u00A0<>]/g;function escapeReplace(c){switch(c){case'&':return'&amp;';case'<':return'&lt;';case'>':return'&gt;';case'"':return'&quot;';case'\xA0':return'&nbsp;';}}
+function escapeAttr(s){return s.replace(escapeAttrRegExp,escapeReplace);}
+function escapeData(s){return s.replace(escapeDataRegExp,escapeReplace);}
+function makeSet(arr){var set={};for(var i=0;i<arr.length;i++){set[arr[i]]=true;}
+return set;}
+var voidElements=makeSet(['area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr']);var plaintextParents=makeSet(['style','script','xmp','iframe','noembed','noframes','plaintext','noscript']);function getOuterHTML(node,parentNode,composed){switch(node.nodeType){case Node.ELEMENT_NODE:var tagName=node.localName;var s='<'+tagName;var attrs=node.attributes;for(var i=0,attr;attr=attrs[i];i++){s+=' '+attr.name+'="'+escapeAttr(attr.value)+'"';}
+s+='>';if(voidElements[tagName]){return s;}
+return s+getInnerHTML(node,composed)+'</'+tagName+'>';case Node.TEXT_NODE:var data=node.data;if(parentNode&&plaintextParents[parentNode.localName]){return data;}
+return escapeData(data);case Node.COMMENT_NODE:return'<!--'+node.data+'-->';default:console.error(node);throw new Error('not implemented');}}
+function getInnerHTML(node,composed){if(node instanceof HTMLTemplateElement)
+node=node.content;var s='';var c$=Polymer.dom(node).childNodes;for(var i=0,l=c$.length,child;i<l&&(child=c$[i]);i++){s+=getOuterHTML(child,node,composed);}
+return s;}
+return{getInnerHTML:getInnerHTML};}();(function(){'use strict';var nativeInsertBefore=Element.prototype.insertBefore;var nativeAppendChild=Element.prototype.appendChild;var nativeRemoveChild=Element.prototype.removeChild;Polymer.TreeApi={arrayCopyChildNodes:function(parent){var copy=[],i=0;for(var n=parent.firstChild;n;n=n.nextSibling){copy[i++]=n;}
+return copy;},arrayCopyChildren:function(parent){var copy=[],i=0;for(var n=parent.firstElementChild;n;n=n.nextElementSibling){copy[i++]=n;}
+return copy;},arrayCopy:function(a$){var l=a$.length;var copy=new Array(l);for(var i=0;i<l;i++){copy[i]=a$[i];}
+return copy;}};Polymer.TreeApi.Logical={hasParentNode:function(node){return Boolean(node.__dom&&node.__dom.parentNode);},hasChildNodes:function(node){return Boolean(node.__dom&&node.__dom.childNodes!==undefined);},getChildNodes:function(node){return this.hasChildNodes(node)?this._getChildNodes(node):node.childNodes;},_getChildNodes:function(node){if(!node.__dom.childNodes){node.__dom.childNodes=[];for(var n=node.__dom.firstChild;n;n=n.__dom.nextSibling){node.__dom.childNodes.push(n);}}
+return node.__dom.childNodes;},getParentNode:function(node){return node.__dom&&node.__dom.parentNode!==undefined?node.__dom.parentNode:node.parentNode;},getFirstChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?node.__dom.firstChild:node.firstChild;},getLastChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?node.__dom.lastChild:node.lastChild;},getNextSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?node.__dom.nextSibling:node.nextSibling;},getPreviousSibling:function(node){return node.__dom&&node.__dom.previousSibling!==undefined?node.__dom.previousSibling:node.previousSibling;},getFirstElementChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?this._getFirstElementChild(node):node.firstElementChild;},_getFirstElementChild:function(node){var n=node.__dom.firstChild;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.nextSibling;}
+return n;},getLastElementChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?this._getLastElementChild(node):node.lastElementChild;},_getLastElementChild:function(node){var n=node.__dom.lastChild;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.previousSibling;}
+return n;},getNextElementSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?this._getNextElementSibling(node):node.nextElementSibling;},_getNextElementSibling:function(node){var n=node.__dom.nextSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.nextSibling;}
+return n;},getPreviousElementSibling:function(node){return node.__dom&&node.__dom.previousSibling!==undefined?this._getPreviousElementSibling(node):node.previousElementSibling;},_getPreviousElementSibling:function(node){var n=node.__dom.previousSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.previousSibling;}
+return n;},saveChildNodes:function(node){if(!this.hasChildNodes(node)){node.__dom=node.__dom||{};node.__dom.firstChild=node.firstChild;node.__dom.lastChild=node.lastChild;node.__dom.childNodes=[];for(var n=node.firstChild;n;n=n.nextSibling){n.__dom=n.__dom||{};n.__dom.parentNode=node;node.__dom.childNodes.push(n);n.__dom.nextSibling=n.nextSibling;n.__dom.previousSibling=n.previousSibling;}}},recordInsertBefore:function(node,container,ref_node){container.__dom.childNodes=null;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){for(var n=node.firstChild;n;n=n.nextSibling){this._linkNode(n,container,ref_node);}}else{this._linkNode(node,container,ref_node);}},_linkNode:function(node,container,ref_node){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(ref_node){ref_node.__dom=ref_node.__dom||{};}
+node.__dom.previousSibling=ref_node?ref_node.__dom.previousSibling:container.__dom.lastChild;if(node.__dom.previousSibling){node.__dom.previousSibling.__dom.nextSibling=node;}
+node.__dom.nextSibling=ref_node||null;if(node.__dom.nextSibling){node.__dom.nextSibling.__dom.previousSibling=node;}
+node.__dom.parentNode=container;if(ref_node){if(ref_node===container.__dom.firstChild){container.__dom.firstChild=node;}}else{container.__dom.lastChild=node;if(!container.__dom.firstChild){container.__dom.firstChild=node;}}
+container.__dom.childNodes=null;},recordRemoveChild:function(node,container){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(node===container.__dom.firstChild){container.__dom.firstChild=node.__dom.nextSibling;}
+if(node===container.__dom.lastChild){container.__dom.lastChild=node.__dom.previousSibling;}
+var p=node.__dom.previousSibling;var n=node.__dom.nextSibling;if(p){p.__dom.nextSibling=n;}
+if(n){n.__dom.previousSibling=p;}
+node.__dom.parentNode=node.__dom.previousSibling=node.__dom.nextSibling=undefined;container.__dom.childNodes=null;}};Polymer.TreeApi.Composed={getChildNodes:function(node){return Polymer.TreeApi.arrayCopyChildNodes(node);},getParentNode:function(node){return node.parentNode;},clearChildNodes:function(node){node.textContent='';},insertBefore:function(parentNode,newChild,refChild){return nativeInsertBefore.call(parentNode,newChild,refChild||null);},appendChild:function(parentNode,newChild){return nativeAppendChild.call(parentNode,newChild);},removeChild:function(parentNode,node){return nativeRemoveChild.call(parentNode,node);}};}());Polymer.DomApi=function(){'use strict';var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=function(node){this.node=needsToWrap?DomApi.wrap(node):node;};var needsToWrap=Settings.hasShadow&&!Settings.nativeShadow;DomApi.wrap=window.wrap?window.wrap:function(node){return node;};DomApi.prototype={flush:function(){Polymer.dom.flush();},deepContains:function(node){if(this.node.contains(node)){return true;}
+var n=node;var doc=node.ownerDocument;while(n&&n!==doc&&n!==this.node){n=Polymer.dom(n).parentNode||n.host;}
+return n===this.node;},queryDistributedElements:function(selector){var c$=this.getEffectiveChildNodes();var list=[];for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.nodeType===Node.ELEMENT_NODE&&DomApi.matchesSelector.call(c,selector)){list.push(c);}}
+return list;},getEffectiveChildNodes:function(){var list=[];var c$=this.childNodes;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.localName===CONTENT){var d$=dom(c).getDistributedNodes();for(var j=0;j<d$.length;j++){list.push(d$[j]);}}else{list.push(c);}}
+return list;},observeNodes:function(callback){if(callback){if(!this.observer){this.observer=this.node.localName===CONTENT?new DomApi.DistributedNodesObserver(this):new DomApi.EffectiveNodesObserver(this);}
+return this.observer.addListener(callback);}},unobserveNodes:function(handle){if(this.observer){this.observer.removeListener(handle);}},notifyObserver:function(){if(this.observer){this.observer.notify();}},_query:function(matcher,node,halter){node=node||this.node;var list=[];this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list);return list;},_queryElements:function(elements,matcher,halter,list){for(var i=0,l=elements.length,c;i<l&&(c=elements[i]);i++){if(c.nodeType===Node.ELEMENT_NODE){if(this._queryElement(c,matcher,halter,list)){return true;}}}},_queryElement:function(node,matcher,halter,list){var result=matcher(node);if(result){list.push(node);}
+if(halter&&halter(result)){return result;}
+this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list);}};var CONTENT=DomApi.CONTENT='content';var dom=DomApi.factory=function(node){node=node||document;if(!node.__domApi){node.__domApi=new DomApi.ctor(node);}
+return node.__domApi;};DomApi.hasApi=function(node){return Boolean(node.__domApi);};DomApi.ctor=DomApi;Polymer.dom=function(obj,patch){if(obj instanceof Event){return Polymer.EventApi.factory(obj);}else{return DomApi.factory(obj,patch);}};var p=Element.prototype;DomApi.matchesSelector=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;return DomApi;}();(function(){'use strict';var Settings=Polymer.Settings;var DomApi=Polymer.DomApi;var dom=DomApi.factory;var TreeApi=Polymer.TreeApi;var getInnerHTML=Polymer.domInnerHTML.getInnerHTML;var CONTENT=DomApi.CONTENT;if(Settings.useShadow){return;}
+var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.mixin(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce('_distribute',host._distributeContent));}},appendChild:function(node){return this.insertBefore(node);},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node){throw Error('The ref_node to be inserted before is not a child '+'of this node');}
+if(node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var parent=TreeApi.Logical.getParentNode(node);if(parent){if(DomApi.hasApi(parent)){dom(parent).notifyObserver();}
+this._removeNode(node);}else{this._removeOwnerShadyRoot(node);}}
+if(!this._addNode(node,ref_node)){if(ref_node){ref_node=ref_node.localName===CONTENT?this._firstComposedNode(ref_node):ref_node;}
+var container=this.node._isShadyRoot?this.node.host:this.node;if(ref_node){TreeApi.Composed.insertBefore(container,node,ref_node);}else{TreeApi.Composed.appendChild(container,node);}}
+this.notifyObserver();return node;},_addNode:function(node,ref_node){var root=this.getOwnerRoot();if(root){var ipAdded=this._maybeAddInsertionPoint(node,this.node);if(!root._invalidInsertionPoints){root._invalidInsertionPoints=ipAdded;}
+this._addNodeToHost(root.host,node);}
+if(TreeApi.Logical.hasChildNodes(this.node)){TreeApi.Logical.recordInsertBefore(node,this.node,ref_node);}
+var handled=this._maybeDistribute(node)||this.node.shadyRoot;if(handled){if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){while(node.firstChild){TreeApi.Composed.removeChild(node,node.firstChild);}}else{var parent=TreeApi.Composed.getParentNode(node);if(parent){TreeApi.Composed.removeChild(parent,node);}}}
+return handled;},removeChild:function(node){if(TreeApi.Logical.getParentNode(node)!==this.node){throw Error('The node to be removed is not a child of this node: '+node);}
+if(!this._removeNode(node)){var container=this.node._isShadyRoot?this.node.host:this.node;var parent=TreeApi.Composed.getParentNode(node);if(container===parent){TreeApi.Composed.removeChild(container,node);}}
+this.notifyObserver();return node;},_removeNode:function(node){var logicalParent=TreeApi.Logical.hasParentNode(node)&&TreeApi.Logical.getParentNode(node);var distributed;var root=this._ownerShadyRootForNode(node);if(logicalParent){distributed=dom(node)._maybeDistributeParent();TreeApi.Logical.recordRemoveChild(node,logicalParent);if(root&&this._removeDistributedChildren(root,node)){root._invalidInsertionPoints=true;this._lazyDistribute(root.host);}}
+this._removeOwnerShadyRoot(node);if(root){this._removeNodeFromHost(root.host,node);}
+return distributed;},replaceChild:function(node,ref_node){this.insertBefore(node,ref_node);this.removeChild(ref_node);return node;},_hasCachedOwnerRoot:function(node){return Boolean(node._ownerShadyRoot!==undefined);},getOwnerRoot:function(){return this._ownerShadyRootForNode(this.node);},_ownerShadyRootForNode:function(node){if(!node){return;}
+var root=node._ownerShadyRoot;if(root===undefined){if(node._isShadyRoot){root=node;}else{var parent=TreeApi.Logical.getParentNode(node);if(parent){root=parent._isShadyRoot?parent:this._ownerShadyRootForNode(parent);}else{root=null;}}
+if(root||document.documentElement.contains(node)){node._ownerShadyRoot=root;}}
+return root;},_maybeDistribute:function(node){var fragContent=node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent&&dom(node).querySelector(CONTENT);var wrappedContent=fragContent&&TreeApi.Logical.getParentNode(fragContent).nodeType!==Node.DOCUMENT_FRAGMENT_NODE;var hasContent=fragContent||node.localName===CONTENT;if(hasContent){var root=this.getOwnerRoot();if(root){this._lazyDistribute(root.host);}}
+var needsDist=this._nodeNeedsDistribution(this.node);if(needsDist){this._lazyDistribute(this.node);}
+return needsDist||hasContent&&!wrappedContent;},_maybeAddInsertionPoint:function(node,parent){var added;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent){var c$=dom(node).querySelectorAll(CONTENT);for(var i=0,n,np,na;i<c$.length&&(n=c$[i]);i++){np=TreeApi.Logical.getParentNode(n);if(np===node){np=parent;}
+na=this._maybeAddInsertionPoint(n,np);added=added||na;}}else if(node.localName===CONTENT){TreeApi.Logical.saveChildNodes(parent);TreeApi.Logical.saveChildNodes(node);added=true;}
+return added;},_updateInsertionPoints:function(host){var i$=host.shadyRoot._insertionPoints=dom(host.shadyRoot).querySelectorAll(CONTENT);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c));}},_nodeNeedsDistribution:function(node){return node&&node.shadyRoot&&DomApi.hasInsertionPoint(node.shadyRoot);},_addNodeToHost:function(host,node){if(host._elementAdd){host._elementAdd(node);}},_removeNodeFromHost:function(host,node){if(host._elementRemove){host._elementRemove(node);}},_removeDistributedChildren:function(root,container){var hostNeedsDist;var ip$=root._insertionPoints;for(var i=0;i<ip$.length;i++){var content=ip$[i];if(this._contains(container,content)){var dc$=dom(content).getDistributedNodes();for(var j=0;j<dc$.length;j++){hostNeedsDist=true;var node=dc$[j];var parent=TreeApi.Composed.getParentNode(node);if(parent){TreeApi.Composed.removeChild(parent,node);}}}}
+return hostNeedsDist;},_contains:function(container,node){while(node){if(node==container){return true;}
+node=TreeApi.Logical.getParentNode(node);}},_removeOwnerShadyRoot:function(node){if(this._hasCachedOwnerRoot(node)){var c$=TreeApi.Logical.getChildNodes(node);for(var i=0,l=c$.length,n;i<l&&(n=c$[i]);i++){this._removeOwnerShadyRoot(n);}}
+node._ownerShadyRoot=undefined;},_firstComposedNode:function(content){var n$=dom(content).getDistributedNodes();for(var i=0,l=n$.length,n,p$;i<l&&(n=n$[i]);i++){p$=dom(n).getDestinationInsertionPoints();if(p$[p$.length-1]===content){return n;}}},querySelector:function(selector){var result=this._query(function(n){return DomApi.matchesSelector.call(n,selector);},this.node,function(n){return Boolean(n);})[0];return result||null;},querySelectorAll:function(selector){return this._query(function(n){return DomApi.matchesSelector.call(n,selector);},this.node);},getDestinationInsertionPoints:function(){return this.node._destinationInsertionPoints||[];},getDistributedNodes:function(){return this.node._distributedNodes||[];},_clear:function(){while(this.childNodes.length){this.removeChild(this.childNodes[0]);}},setAttribute:function(name,value){this.node.setAttribute(name,value);this._maybeDistributeParent();},removeAttribute:function(name){this.node.removeAttribute(name);this._maybeDistributeParent();},_maybeDistributeParent:function(){if(this._nodeNeedsDistribution(this.parentNode)){this._lazyDistribute(this.parentNode);return true;}},cloneNode:function(deep){var n=nativeCloneNode.call(this.node,false);if(deep){var c$=this.childNodes;var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(c$[i]).cloneNode(true);d.appendChild(nc);}}
+return n;},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;var n=nativeImportNode.call(doc,externalNode,false);if(deep){var c$=TreeApi.Logical.getChildNodes(externalNode);var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(doc).importNode(c$[i],true);d.appendChild(nc);}}
+return n;},_getComposedInnerHTML:function(){return getInnerHTML(this.node,true);}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var active=document.activeElement;if(!active){return null;}
+var isShadyRoot=!!this.node._isShadyRoot;if(this.node!==document){if(!isShadyRoot){return null;}
+if(this.node.host===active||!this.node.host.contains(active)){return null;}}
+var activeRoot=dom(active).getOwnerRoot();while(activeRoot&&activeRoot!==this.node){active=activeRoot.host;activeRoot=dom(active).getOwnerRoot();}
+if(this.node===document){return activeRoot?null:active;}else{return activeRoot===this.node?active:null;}},configurable:true},childNodes:{get:function(){var c$=TreeApi.Logical.getChildNodes(this.node);return Array.isArray(c$)?c$:TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){if(TreeApi.Logical.hasChildNodes(this.node)){return Array.prototype.filter.call(this.childNodes,function(n){return n.nodeType===Node.ELEMENT_NODE;});}else{return TreeApi.arrayCopyChildren(this.node);}},configurable:true},parentNode:{get:function(){return TreeApi.Logical.getParentNode(this.node);},configurable:true},firstChild:{get:function(){return TreeApi.Logical.getFirstChild(this.node);},configurable:true},lastChild:{get:function(){return TreeApi.Logical.getLastChild(this.node);},configurable:true},nextSibling:{get:function(){return TreeApi.Logical.getNextSibling(this.node);},configurable:true},previousSibling:{get:function(){return TreeApi.Logical.getPreviousSibling(this.node);},configurable:true},firstElementChild:{get:function(){return TreeApi.Logical.getFirstElementChild(this.node);},configurable:true},lastElementChild:{get:function(){return TreeApi.Logical.getLastElementChild(this.node);},configurable:true},nextElementSibling:{get:function(){return TreeApi.Logical.getNextElementSibling(this.node);},configurable:true},previousElementSibling:{get:function(){return TreeApi.Logical.getPreviousElementSibling(this.node);},configurable:true},textContent:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return this.node.textContent;}else{var tc=[];for(var i=0,cn=this.childNodes,c;c=cn[i];i++){if(c.nodeType!==Node.COMMENT_NODE){tc.push(c.textContent);}}
+return tc.join('');}},set:function(text){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){this.node.textContent=text;}else{this._clear();if(text){this.appendChild(document.createTextNode(text));}}},configurable:true},innerHTML:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return null;}else{return getInnerHTML(this.node);}},set:function(text){var nt=this.node.nodeType;if(nt!==Node.TEXT_NODE||nt!==Node.COMMENT_NODE){this._clear();var d=document.createElement('div');d.innerHTML=text;var c$=TreeApi.arrayCopyChildNodes(d);for(var i=0;i<c$.length;i++){this.appendChild(c$[i]);}}},configurable:true}});DomApi.hasInsertionPoint=function(root){return Boolean(root&&root._insertionPoints.length);};}());(function(){'use strict';var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=Polymer.DomApi;if(!Settings.useShadow){return;}
+Polymer.Base.mixin(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector));},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host){return n;}
+n=n.parentNode;}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;return doc.importNode(externalNode,deep);},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[];},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[];}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?activeElement:null;},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node);},configurable:true},textContent:{get:function(){return this.node.textContent;},set:function(value){return this.node.textContent=value;},configurable:true},innerHTML:{get:function(){return this.node.innerHTML;},set:function(value){return this.node.innerHTML=value;},configurable:true}});var forwardMethods=function(m$){for(var i=0;i<m$.length;i++){forwardMethod(m$[i]);}};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments);};};forwardMethods(['cloneNode','appendChild','insertBefore','removeChild','replaceChild','setAttribute','removeAttribute','querySelector']);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++){forwardProperty(f$[i]);}};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name];},configurable:true});};forwardProperties(['parentNode','firstChild','lastChild','nextSibling','previousSibling','firstElementChild','lastElementChild','nextElementSibling','previousElementSibling']);}());Polymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length){this._debouncers.shift().complete();}
+if(this._finishDebouncer){this._finishDebouncer.complete();}
+this._prepareFlush();this._flushGuard++;}
+if(this._flushGuard>=this._FLUSH_MAX){console.warn('Polymer.dom.flush aborted. Flush may not be complete.');}},_prepareFlush:function(){if(this._needsTakeRecords){CustomElements.takeRecords();}
+for(var i=0;i<this._staticFlushList.length;i++){this._staticFlushList[i]();}},addStaticFlush:function(fn){this._staticFlushList.push(fn);},removeStaticFlush:function(fn){var i=this._staticFlushList.indexOf(fn);if(i>=0){this._staticFlushList.splice(i,1);}},addDebouncer:function(debouncer){this._debouncers.push(debouncer);this._finishDebouncer=Polymer.Debounce(this._finishDebouncer,this._finishFlush);},_finishFlush:function(){Polymer.dom._debouncers=[];}});Polymer.EventApi=function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.Event=function(event){this.event=event;};if(Settings.useShadow){DomApi.Event.prototype={get rootTarget(){return this.event.path[0];},get localTarget(){return this.event.target;},get path(){var path=this.event.path;if(!Array.isArray(path)){path=Array.prototype.slice.call(path);}
+return path;}};}else{DomApi.Event.prototype={get rootTarget(){return this.event.target;},get localTarget(){var current=this.event.currentTarget;var currentRoot=current&&Polymer.dom(current).getOwnerRoot();var p$=this.path;for(var i=0;i<p$.length;i++){if(Polymer.dom(p$[i]).getOwnerRoot()===currentRoot){return p$[i];}}},get path(){if(!this.event._path){var path=[];var current=this.rootTarget;while(current){path.push(current);var insertionPoints=Polymer.dom(current).getDestinationInsertionPoints();if(insertionPoints.length){for(var i=0;i<insertionPoints.length-1;i++){path.push(insertionPoints[i]);}
+current=insertionPoints[insertionPoints.length-1];}else{current=Polymer.dom(current).parentNode||current.host;}}
+path.push(window);this.event._path=path;}
+return this.event._path;}};}
+var factory=function(event){if(!event.__eventApi){event.__eventApi=new DomApi.Event(event);}
+return event.__eventApi;};return{factory:factory};}();(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var useShadow=Polymer.Settings.useShadow;Object.defineProperty(DomApi.prototype,'classList',{get:function(){if(!this._classList){this._classList=new DomApi.ClassList(this);}
+return this._classList;},configurable:true});DomApi.ClassList=function(host){this.domApi=host;this.node=host.node;};DomApi.ClassList.prototype={add:function(){this.node.classList.add.apply(this.node.classList,arguments);this._distributeParent();},remove:function(){this.node.classList.remove.apply(this.node.classList,arguments);this._distributeParent();},toggle:function(){this.node.classList.toggle.apply(this.node.classList,arguments);this._distributeParent();},_distributeParent:function(){if(!useShadow){this.domApi._maybeDistributeParent();}},contains:function(){return this.node.classList.contains.apply(this.node.classList,arguments);}};}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.EffectiveNodesObserver=function(domApi){this.domApi=domApi;this.node=this.domApi.node;this._listeners=[];};DomApi.EffectiveNodesObserver.prototype={addListener:function(callback){if(!this._isSetup){this._setup();this._isSetup=true;}
+var listener={fn:callback,_nodes:[]};this._listeners.push(listener);this._scheduleNotify();return listener;},removeListener:function(handle){var i=this._listeners.indexOf(handle);if(i>=0){this._listeners.splice(i,1);handle._nodes=[];}
+if(!this._hasListeners()){this._cleanup();this._isSetup=false;}},_setup:function(){this._observeContentElements(this.domApi.childNodes);},_cleanup:function(){this._unobserveContentElements(this.domApi.childNodes);},_hasListeners:function(){return Boolean(this._listeners.length);},_scheduleNotify:function(){if(this._debouncer){this._debouncer.stop();}
+this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer);},notify:function(){if(this._hasListeners()){this._scheduleNotify();}},_notify:function(){this._beforeCallListeners();this._callListeners();},_beforeCallListeners:function(){this._updateContentElements();},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes);},_observeContentElements:function(elements){for(var i=0,n;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){n.__observeNodesMap=n.__observeNodesMap||new WeakMap();if(!n.__observeNodesMap.has(this)){n.__observeNodesMap.set(this,this._observeContent(n));}}}},_observeContent:function(content){var self=this;var h=Polymer.dom(content).observeNodes(function(){self._scheduleNotify();});h._avoidChangeCalculation=true;return h;},_unobserveContentElements:function(elements){for(var i=0,n,h;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){h=n.__observeNodesMap.get(this);if(h){Polymer.dom(n).unobserveNodes(h);n.__observeNodesMap.delete(this);}}}},_isContent:function(node){return node.localName==='content';},_callListeners:function(){var o$=this._listeners;var nodes=this._getEffectiveNodes();for(var i=0,o;i<o$.length&&(o=o$[i]);i++){var info=this._generateListenerInfo(o,nodes);if(info||o._alwaysNotify){this._callListener(o,info);}}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes();},_generateListenerInfo:function(listener,newNodes){if(listener._avoidChangeCalculation){return true;}
+var oldNodes=listener._nodes;var info={target:this.node,addedNodes:[],removedNodes:[]};var splices=Polymer.ArraySplice.calculateSplices(newNodes,oldNodes);for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){info.removedNodes.push(n);}}
+for(i=0,s;i<splices.length&&(s=splices[i]);i++){for(j=s.index;j<s.index+s.addedCount;j++){info.addedNodes.push(newNodes[j]);}}
+listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length){return info;}},_callListener:function(listener,info){return listener.fn.call(this.node,info);},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=DomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length){self._scheduleNotify();}};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush();};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true});}
+baseSetup.call(this);},_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this);},_flush:function(){if(this._observer){this._mutationHandler(this._observer.takeRecords());}},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host&&Polymer.dom(host).observer){Polymer.dom(host).observer.enableShadowAttributeTracking();}}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener;}}});}}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi);};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes();}});if(Settings.useShadow){Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify();});this._observer._isContentListener=true;if(this._hasAttrSelect()){Polymer.dom(host).observer.enableShadowAttributeTracking();}}}},_hasAttrSelect:function(){var select=this.node.getAttribute('select');return select&&select.match(/[[.]+/);},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){Polymer.dom(host).unobserveNodes(this._observer);}
+this._observer=null;}});}}());(function(){var DomApi=Polymer.DomApi;var TreeApi=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||Boolean(this._template);},_setupShady:function(){this.shadyRoot=null;if(!this.__domApi){this.__domApi=null;}
+if(!this.__dom){this.__dom=null;}
+if(!this._ownerShadyRoot){this._ownerShadyRoot=undefined;}},_poolContent:function(){if(this._useContent){TreeApi.Logical.saveChildNodes(this);}},_setupRoot:function(){if(this._useContent){this._createLocalRoot();if(!this.dataHost){upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this));}}},_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=false;this.shadyRoot._hasDistributed=false;this.shadyRoot._isShadyRoot=true;this.shadyRoot._dirtyRoots=[];var i$=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll('content'):[];TreeApi.Logical.saveChildNodes(this.shadyRoot);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(c.parentNode);}
+this.shadyRoot.host=this;},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host);}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false;}
+this._beginDistribute();this._distributeDirtyRoots();this._finishDistribute();}},_beginDistribute:function(){if(this._useContent&&DomApi.hasInsertionPoint(this.shadyRoot)){this._resetDistribution();this._distributePool(this.shadyRoot,this._collectPool());}},_distributeDirtyRoots:function(){var c$=this.shadyRoot._dirtyRoots;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._distributeContent();}
+this.shadyRoot._dirtyRoots=[];},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=true;if(DomApi.hasInsertionPoint(this.shadyRoot)){this._composeTree();notifyContentObservers(this.shadyRoot);}else{if(!this.shadyRoot._hasDistributed){TreeApi.Composed.clearChildNodes(this);this.appendChild(this.shadyRoot);}else{var children=this._composeNode(this);this._updateChildNodes(this,children);}}
+if(!this.shadyRoot._hasDistributed){notifyInitialDistribution(this);}
+this.shadyRoot._hasDistributed=true;}},elementMatches:function(selector,node){node=node||this;return DomApi.matchesSelector.call(node,selector);},_resetDistribution:function(){var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(child._destinationInsertionPoints){child._destinationInsertionPoints=undefined;}
+if(isInsertionPoint(child)){clearDistributedDestinationInsertionPoints(child);}}
+var root=this.shadyRoot;var p$=root._insertionPoints;for(var j=0;j<p$.length;j++){p$[j]._distributedNodes=[];}},_collectPool:function(){var pool=[];var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(isInsertionPoint(child)){pool.push.apply(pool,child._distributedNodes);}else{pool.push(child);}}
+return pool;},_distributePool:function(node,pool){var p$=node._insertionPoints;for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){this._distributeInsertionPoint(p,pool);maybeRedistributeParent(p,this);}},_distributeInsertionPoint:function(content,pool){var anyDistributed=false;for(var i=0,l=pool.length,node;i<l;i++){node=pool[i];if(!node){continue;}
+if(this._matchesContentSelect(node,content)){distributeNodeInto(node,content);pool[i]=undefined;anyDistributed=true;}}
+if(!anyDistributed){var children=TreeApi.Logical.getChildNodes(content);for(var j=0;j<children.length;j++){distributeNodeInto(children[j],content);}}},_composeTree:function(){this._updateChildNodes(this,this._composeNode(this));var p$=this.shadyRoot._insertionPoints;for(var i=0,l=p$.length,p,parent;i<l&&(p=p$[i]);i++){parent=TreeApi.Logical.getParentNode(p);if(!parent._useContent&&parent!==this&&parent!==this.shadyRoot){this._updateChildNodes(parent,this._composeNode(parent));}}},_composeNode:function(node){var children=[];var c$=TreeApi.Logical.getChildNodes(node.shadyRoot||node);for(var i=0;i<c$.length;i++){var child=c$[i];if(isInsertionPoint(child)){var distributedNodes=child._distributedNodes;for(var j=0;j<distributedNodes.length;j++){var distributedNode=distributedNodes[j];if(isFinalDestination(child,distributedNode)){children.push(distributedNode);}}}else{children.push(child);}}
+return children;},_updateChildNodes:function(container,children){var composed=TreeApi.Composed.getChildNodes(container);var splices=Polymer.ArraySplice.calculateSplices(children,composed);for(var i=0,d=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){if(TreeApi.Composed.getParentNode(n)===container){TreeApi.Composed.removeChild(container,n);}
+composed.splice(s.index+d,1);}
+d-=s.addedCount;}
+for(var i=0,s,next;i<splices.length&&(s=splices[i]);i++){next=composed[s.index];for(j=s.index,n;j<s.index+s.addedCount;j++){n=children[j];TreeApi.Composed.insertBefore(container,n,next);composed.splice(j,0,n);}}},_matchesContentSelect:function(node,contentElement){var select=contentElement.getAttribute('select');if(!select){return true;}
+select=select.trim();if(!select){return true;}
+if(!(node instanceof Element)){return false;}
+var validSelectors=/^(:not\()?[*.#[a-zA-Z_|]/;if(!validSelectors.test(select)){return false;}
+return this.elementMatches(select,node);},_elementAdd:function(){},_elementRemove:function(){}});var domHostDesc={get:function(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host;},configurable:true};Object.defineProperty(Polymer.Base,'domHost',domHostDesc);Polymer.BaseDescriptors.domHost=domHostDesc;function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points){child._destinationInsertionPoints=[insertionPoint];}else{points.push(insertionPoint);}}
+function clearDistributedDestinationInsertionPoints(content){var e$=content._distributedNodes;if(e$){for(var i=0;i<e$.length;i++){var d=e$[i]._destinationInsertionPoints;if(d){d.splice(d.indexOf(content)+1,d.length);}}}}
+function maybeRedistributeParent(content,host){var parent=TreeApi.Logical.getParentNode(content);if(parent&&parent.shadyRoot&&DomApi.hasInsertionPoint(parent.shadyRoot)&&parent.shadyRoot._distributionClean){parent.shadyRoot._distributionClean=false;host.shadyRoot._dirtyRoots.push(parent);}}
+function isFinalDestination(insertionPoint,node){var points=node._destinationInsertionPoints;return points&&points[points.length-1]===insertionPoint;}
+function isInsertionPoint(node){return node.localName=='content';}
+function getTopDistributingHost(host){while(host&&hostNeedsRedistribution(host)){host=host.domHost;}
+return host;}
+function hostNeedsRedistribution(host){var c$=TreeApi.Logical.getChildNodes(host);for(var i=0,c;i<c$.length;i++){c=c$[i];if(c.localName&&c.localName==='content'){return host.domHost;}}}
+function notifyContentObservers(root){for(var i=0,c;i<root._insertionPoints.length;i++){c=root._insertionPoints[i];if(DomApi.hasApi(c)){Polymer.dom(c).notifyObserver();}}}
+function notifyInitialDistribution(host){if(DomApi.hasApi(host)){Polymer.dom(host).notifyObserver();}}
+var needsUpgrade=window.CustomElements&&!CustomElements.useNative;function upgradeLogicalChildren(children){if(needsUpgrade&&children){for(var i=0;i<children.length;i++){CustomElements.upgrade(children[i]);}}}}());if(Polymer.Settings.useShadow){Polymer.Base._addFeature({_poolContent:function(){},_beginDistribute:function(){},distributeContent:function(){},_distributeContent:function(){},_finishDistribute:function(){},_createLocalRoot:function(){this.createShadowRoot();this.shadowRoot.appendChild(this.root);this.root=this.shadowRoot;}});}Polymer.Async={_currVal:0,_lastVal:0,_callbacks:[],_twiddleContent:0,_twiddle:document.createTextNode(''),run:function(callback,waitTime){if(waitTime>0){return~setTimeout(callback,waitTime);}else{this._twiddle.textContent=this._twiddleContent++;this._callbacks.push(callback);return this._currVal++;}},cancel:function(handle){if(handle<0){clearTimeout(~handle);}else{var idx=handle-this._lastVal;if(idx>=0){if(!this._callbacks[idx]){throw'invalid async handle: '+handle;}
+this._callbacks[idx]=null;}}},_atEndOfMicrotask:function(){var len=this._callbacks.length;for(var i=0;i<len;i++){var cb=this._callbacks[i];if(cb){try{cb();}catch(e){i++;this._callbacks.splice(0,i);this._lastVal+=i;this._twiddle.textContent=this._twiddleContent++;throw e;}}}
+this._callbacks.splice(0,len);this._lastVal+=len;}};new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask();}).observe(Polymer.Async._twiddle,{characterData:true});Polymer.Debounce=function(){var Async=Polymer.Async;var Debouncer=function(context){this.context=context;var self=this;this.boundComplete=function(){self.complete();};};Debouncer.prototype={go:function(callback,wait){var h;this.finish=function(){Async.cancel(h);};h=Async.run(this.boundComplete,wait);this.callback=callback;},stop:function(){if(this.finish){this.finish();this.finish=null;this.callback=null;}},complete:function(){if(this.finish){var callback=this.callback;this.stop();callback.call(this.context);}}};function debounce(debouncer,callback,wait){if(debouncer){debouncer.stop();}else{debouncer=new Debouncer(this);}
+debouncer.go(callback,wait);return debouncer;}
+return debounce;}();Polymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={};},debounce:function(jobName,callback,wait){return this._debouncers[jobName]=Polymer.Debounce.call(this,this._debouncers[jobName],callback,wait);},isDebouncerActive:function(jobName){var debouncer=this._debouncers[jobName];return!!(debouncer&&debouncer.finish);},flushDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.complete();}},cancelDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.stop();}}});Polymer.DomModule=document.createElement('dom-module');Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();}
+this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady();},_marshalBehavior:function(b){}});(function(){Polymer.nar=[];var disableUpgradeEnabled=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(template,stripWhiteSpace){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,stripWhiteSpace||template.hasAttribute('strip-whitespace'));return list;},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,list,stripWhiteSpace);},_bindingRegex:function(){var IDENT='(?:'+'[a-zA-Z_$][\\w.:$\\-*]*'+')';var NUMBER='(?:'+'[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?'+')';var SQUOTE_STRING='(?:'+'\'(?:[^\'\\\\]|\\\\.)*\''+')';var DQUOTE_STRING='(?:'+'"(?:[^"\\\\]|\\\\.)*"'+')';var STRING='(?:'+SQUOTE_STRING+'|'+DQUOTE_STRING+')';var ARGUMENT='(?:'+IDENT+'|'+NUMBER+'|'+STRING+'\\s*'+')';var ARGUMENTS='(?:'+ARGUMENT+'(?:,\\s*'+ARGUMENT+')*'+')';var ARGUMENT_LIST='(?:'+'\\(\\s*'+'(?:'+ARGUMENTS+'?'+')'+'\\)\\s*'+')';var BINDING='('+IDENT+'\\s*'+ARGUMENT_LIST+'?'+')';var OPEN_BRACKET='(\\[\\[|{{)'+'\\s*';var CLOSE_BRACKET='(?:]]|}})';var NEGATE='(?:(!)\\s*)?';var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,'g');}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex){parts.push({literal:text.slice(lastIndex,m.index)});}
+var mode=m[1][0];var negate=Boolean(m[2]);var value=m[3].trim();var customEvent,notifyEvent,colon;if(mode=='{'&&(colon=value.indexOf('::'))>0){notifyEvent=value.substring(colon+2);value=value.substring(0,colon);customEvent=true;}
+parts.push({compoundIndex:parts.length,value:value,mode:mode,negate:negate,event:notifyEvent,customEvent:customEvent});lastIndex=re.lastIndex;}
+if(lastIndex&&lastIndex<text.length){var literal=text.substring(lastIndex);if(literal){parts.push({literal:literal});}}
+if(parts.length){return parts;}},_literalFromParts:function(parts){var s='';for(var i=0;i<parts.length;i++){var literal=parts[i].literal;s+=literal||'';}
+return s;},_parseTextNodeAnnotation:function(node,list){var parts=this._parseBindings(node.textContent);if(parts){node.textContent=this._literalFromParts(parts)||' ';var annote={bindings:[{kind:'text',name:'textContent',parts:parts,isCompound:parts.length!==1}]};list.push(annote);return annote;}},_parseElementAnnotations:function(element,list,stripWhiteSpace){var annote={bindings:[],events:[]};if(element.localName==='content'){list._hasContent=true;}
+this._parseChildNodesAnnotations(element,annote,list,stripWhiteSpace);if(element.attributes){this._parseNodeAttributeAnnotations(element,annote,list);if(this.prepElement){this.prepElement(element);}}
+if(annote.bindings.length||annote.events.length||annote.id){list.push(annote);}
+return annote;},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName==='template'&&!node.hasAttribute('preserve-content')){this._parseTemplate(node,i,list,annote,stripWhiteSpace);}
+if(node.localName=='slot'){node=this._replaceSlotWithContent(node);}
+if(node.nodeType===Node.TEXT_NODE){var n=next;while(n&&n.nodeType===Node.TEXT_NODE){node.textContent+=n.textContent;next=n.nextSibling;root.removeChild(n);n=next;}
+if(stripWhiteSpace&&!node.textContent.trim()){root.removeChild(node);i--;}}
+if(node.parentNode){var childAnnotation=this._parseNodeAnnotations(node,list,stripWhiteSpace);if(childAnnotation){childAnnotation.parent=annote;childAnnotation.index=i;}}
+node=next;i++;}}},_replaceSlotWithContent:function(slot){var content=slot.ownerDocument.createElement('content');while(slot.firstChild){content.appendChild(slot.firstChild);}
+var attrs=slot.attributes;for(var i=0;i<attrs.length;i++){var attr=attrs[i];content.setAttribute(attr.name,attr.value);}
+var name=slot.getAttribute('name');if(name){content.setAttribute('select','[slot=\''+name+'\']');}
+slot.parentNode.replaceChild(content,slot);return content;},_parseTemplate:function(node,index,list,parent,stripWhiteSpace){var content=document.createDocumentFragment();content._notes=this.parseAnnotations(node,stripWhiteSpace);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index});},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)==='on-'){node.removeAttribute(n);annotation.events.push({name:n.slice(3),value:v});}else if(b=this._parseNodeAttributeAnnotation(node,n,v)){annotation.bindings.push(b);}else if(n==='id'){annotation.id=v;}}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind='property';if(name[name.length-1]=='$'){name=name.slice(0,-1);kind='attribute';}
+var literal=this._literalFromParts(parts);if(literal&&kind=='attribute'){node.setAttribute(name,literal);}
+if(node.localName==='input'&&origName==='value'){node.setAttribute(origName,'');}
+if(disableUpgradeEnabled&&origName==='disable-upgrade$'){node.setAttribute(name,'');}
+node.removeAttribute(origName);var propertyName=Polymer.CaseMap.dashToCamelCase(name);if(kind==='property'){name=propertyName;}
+return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1};}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent){for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===i++){return n;}}}else{return root;}}};}());(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+'\''+resolve(url.replace(/["']/g,''),ownerDocument)+'\''+post;});}
+function resolveAttrs(element,ownerDocument){for(var name in URL_ATTRS){var a$=URL_ATTRS[name];for(var i=0,l=a$.length,a,at,v;i<l&&(a=a$[i]);i++){if(name==='*'||element.localName===name){at=element.attributes[a];v=at&&at.value;if(v&&v.search(BINDING_RX)<0){at.value=a==='style'?resolveCss(v,ownerDocument):resolve(v,ownerDocument);}}}}}
+function resolve(url,ownerDocument){if(url&&ABS_URL.test(url)){return url;}
+var resolver=getUrlResolver(ownerDocument);resolver.href=url;return resolver.href||url;}
+var tempDoc;var tempDocBase;function resolveUrl(url,baseUri){if(!tempDoc){tempDoc=document.implementation.createHTMLDocument('temp');tempDocBase=tempDoc.createElement('base');tempDoc.head.appendChild(tempDocBase);}
+tempDocBase.href=baseUri;return resolve(url,tempDoc);}
+function getUrlResolver(ownerDocument){return ownerDocument.body.__urlResolver||(ownerDocument.body.__urlResolver=ownerDocument.createElement('a'));}
+var CSS_URL_RX=/(url\()([^)]*)(\))/g;var URL_ATTRS={'*':['href','src','style','url'],form:['action']};var ABS_URL=/(^\/)|(^#)|(^[\w-\d]*:)/;var BINDING_RX=/\{\{|\[\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl};}());Polymer.Path={root:function(path){var dotIndex=path.indexOf('.');if(dotIndex===-1){return path;}
+return path.slice(0,dotIndex);},isDeep:function(path){return path.indexOf('.')!==-1;},isAncestor:function(base,path){return base.indexOf(path+'.')===0;},isDescendant:function(base,path){return path.indexOf(base+'.')===0;},translate:function(base,newBase,path){return newBase+path.slice(base.length);},matches:function(base,wildcard,path){return base===path||this.isAncestor(base,path)||Boolean(wildcard)&&this.isDescendant(base,path);}};Polymer.Base._addFeature({_prepAnnotations:function(){if(!this._template){this._notes=[];}else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element);};if(this._template._content&&this._template._content._notes){this._notes=this._template._content._notes;}else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes);}
+Polymer.Annotations.prepElement=null;}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];for(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature){p.signature=signature;}else{p.model=Polymer.Path.root(p.value);}}}}
+if(note.templateContent){this._processAnnotations(note.templateContent._notes);var pp=note.templateContent._parentProps=this._discoverTemplateParentProps(note.templateContent._notes);var bindings=[];for(var prop in pp){var name='_parent_'+prop;bindings.push({index:note.index,kind:'property',name:name,propertyName:name,parts:[{mode:'{',model:prop,value:prop}]});}
+note.bindings=note.bindings.concat(bindings);}}},_discoverTemplateParentProps:function(notes){var pp={};for(var i=0,n;i<notes.length&&(n=notes[i]);i++){for(var j=0,b$=n.bindings,b;j<b$.length&&(b=b$[j]);j++){for(var k=0,p$=b.parts,p;k<p$.length&&(p=p$[k]);k++){if(p.signature){var args=p.signature.args;for(var kk=0;kk<args.length;kk++){var model=args[kk].model;if(model){pp[model]=true;}}
+if(p.signature.dynamicFn){pp[p.signature.method]=true;}}else{if(p.model){pp[p.model]=true;}}}}
+if(n.templateContent){var tpp=n.templateContent._parentProps;Polymer.Base.mixin(pp,tpp);}}
+return pp;},_prepElement:function(element){Polymer.ResolveUrl.resolveAttrs(element,this._template.ownerDocument);},_findAnnotatedNode:Polymer.Annotations.findAnnotatedNode,_marshalAnnotationReferences:function(){if(this._template){this._marshalIdNodes();this._marshalAnnotatedNodes();this._marshalAnnotatedListeners();}},_configureAnnotationReferences:function(){var notes=this._notes;var nodes=this._nodes;for(var i=0;i<notes.length;i++){var note=notes[i];var node=nodes[i];this._configureTemplateContent(note,node);this._configureCompoundBindings(note,node);}},_configureTemplateContent:function(note,node){if(note.templateContent){node._content=note.templateContent;}},_configureCompoundBindings:function(note,node){var bindings=note.bindings;for(var i=0;i<bindings.length;i++){var binding=bindings[i];if(binding.isCompound){var storage=node.__compoundStorage__||(node.__compoundStorage__={});var parts=binding.parts;var literals=new Array(parts.length);for(var j=0;j<parts.length;j++){literals[j]=parts[j].literal;}
+var name=binding.name;storage[name]=literals;if(binding.literal&&binding.kind=='property'){if(node._configValue){node._configValue(name,binding.literal);}else{node[name]=binding.literal;}}}}},_marshalIdNodes:function(){this.$={};for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++){if(a.id){this.$[a.id]=this._findAnnotatedNode(this.root,a);}}},_marshalAnnotatedNodes:function(){if(this._notes&&this._notes.length){var r=new Array(this._notes.length);for(var i=0;i<this._notes.length;i++){r[i]=this._findAnnotatedNode(this.root,this._notes[i]);}
+this._nodes=r;}},_marshalAnnotatedListeners:function(){for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++){if(a.events&&a.events.length){var node=this._findAnnotatedNode(this.root,a);for(var j=0,e$=a.events,e;j<e$.length&&(e=e$[j]);j++){this.listen(node,e.name,e.value);}}}}});Polymer.Base._addFeature({listeners:{},_listenListeners:function(listeners){var node,name,eventName;for(eventName in listeners){if(eventName.indexOf('.')<0){node=this;name=eventName;}else{name=eventName.split('.');node=this.$[name[0]];name=name[1];}
+this.listen(node,name,listeners[eventName]);}},listen:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(!handler){handler=this._createEventHandler(node,eventName,methodName);}
+if(handler._listening){return;}
+this._listen(node,eventName,handler);handler._listening=true;},_boundListenerKey:function(eventName,methodName){return eventName+':'+methodName;},_recordEventHandler:function(host,eventName,target,methodName,handler){var hbl=host.__boundListeners;if(!hbl){hbl=host.__boundListeners=new WeakMap();}
+var bl=hbl.get(target);if(!bl){bl={};if(!Polymer.Settings.isIE||target!=window){hbl.set(target,bl);}}
+var key=this._boundListenerKey(eventName,methodName);bl[key]=handler;},_recallEventHandler:function(host,eventName,target,methodName){var hbl=host.__boundListeners;if(!hbl){return;}
+var bl=hbl.get(target);if(!bl){return;}
+var key=this._boundListenerKey(eventName,methodName);return bl[key];},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName]){host[methodName](e,e.detail);}else{host._warn(host._logf('_createEventHandler','listener method `'+methodName+'` not defined'));}};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);return handler;},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false;}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler);},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler);}});(function(){'use strict';var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction==='string';var GESTURE_KEY='__polymerGestures';var HANDLED_OBJ='__polymerGesturesHandled';var TOUCH_ACTION='__polymerGesturesTouchAction';var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=['mousedown','mousemove','mouseup','click'];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return new MouseEvent('test',{buttons:1}).buttons===1;}catch(e){return false;}}();var SUPPORTS_PASSIVE=false;(function(){try{var opts=Object.defineProperty({},'passive',{get:function(){SUPPORTS_PASSIVE=true;}});window.addEventListener('test',null,opts);window.removeEventListener('test',null,opts);}catch(e){}}());var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){var sc=mouseEvent.sourceCapabilities;if(sc&&!sc.firesTouchEvents){return;}
+mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type==='click'){var path=Polymer.dom(mouseEvent).path;for(var i=0;i<path.length;i++){if(path[i]===POINTERSTATE.mouse.target){return;}}
+mouseEvent.preventDefault();mouseEvent.stopPropagation();}};function setupTeardownMouseCanceller(setup){var events=IS_TOUCH_ONLY?['click']:MOUSE_EVENTS;for(var i=0,en;i<events.length;i++){en=events[i];if(setup){document.addEventListener(en,mouseCanceller,true);}else{document.removeEventListener(en,mouseCanceller,true);}}}
+function ignoreMouse(ev){if(!POINTERSTATE.mouse.mouseIgnoreJob){setupTeardownMouseCanceller(true);}
+var unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null;};POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT);}
+function hasLeftMouseButton(ev){var type=ev.type;if(MOUSE_EVENTS.indexOf(type)===-1){return false;}
+if(type==='mousemove'){var buttons=ev.buttons===undefined?1:ev.buttons;if(ev instanceof window.MouseEvent&&!MOUSE_HAS_BUTTONS){buttons=MOUSE_WHICH_TO_BUTTONS[ev.which]||0;}
+return Boolean(buttons&1);}else{var button=ev.button===undefined?0:ev.button;return button===0;}}
+function isSyntheticClick(ev){if(ev.type==='click'){if(ev.detail===0){return true;}
+var t=Gestures.findOriginalTarget(ev);var bcr=t.getBoundingClientRect();var x=ev.pageX,y=ev.pageY;return!(x>=bcr.left&&x<=bcr.right&&(y>=bcr.top&&y<=bcr.bottom));}
+return false;}
+var POINTERSTATE={mouse:{target:null,mouseIgnoreJob:null},touch:{x:0,y:0,id:-1,scrollDecided:false}};function firstTouchAction(ev){var path=Polymer.dom(ev).path;var ta='auto';for(var i=0,n;i<path.length;i++){n=path[i];if(n[TOUCH_ACTION]){ta=n[TOUCH_ACTION];break;}}
+return ta;}
+function trackDocument(stateObj,movefn,upfn){stateObj.movefn=movefn;stateObj.upfn=upfn;document.addEventListener('mousemove',movefn);document.addEventListener('mouseup',upfn);}
+function untrackDocument(stateObj){document.removeEventListener('mousemove',stateObj.movefn);document.removeEventListener('mouseup',stateObj.upfn);stateObj.movefn=null;stateObj.upfn=null;}
+document.addEventListener('touchend',ignoreMouse,SUPPORTS_PASSIVE?{passive:true}:false);var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next){node=next;}}
+return node;},findOriginalTarget:function(ev){if(ev.path){return ev.path[0];}
+return ev.target;},handleNative:function(ev){var handled;var type=ev.type;var node=wrap(ev.currentTarget);var gobj=node[GESTURE_KEY];if(!gobj){return;}
+var gs=gobj[type];if(!gs){return;}
+if(!ev[HANDLED_OBJ]){ev[HANDLED_OBJ]={};if(type.slice(0,5)==='touch'){var t=ev.changedTouches[0];if(type==='touchstart'){if(ev.touches.length===1){POINTERSTATE.touch.id=t.identifier;}}
+if(POINTERSTATE.touch.id!==t.identifier){return;}
+if(!HAS_NATIVE_TA){if(type==='touchstart'||type==='touchmove'){Gestures.handleTouchAction(ev);}}}}
+handled=ev[HANDLED_OBJ];if(handled.skip){return;}
+var recognizers=Gestures.recognizers;for(var i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){if(r.flow&&r.flow.start.indexOf(ev.type)>-1&&r.reset){r.reset();}}}
+for(i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){handled[r.name]=true;r[type](ev);}}},handleTouchAction:function(ev){var t=ev.changedTouches[0];var type=ev.type;if(type==='touchstart'){POINTERSTATE.touch.x=t.clientX;POINTERSTATE.touch.y=t.clientY;POINTERSTATE.touch.scrollDecided=false;}else if(type==='touchmove'){if(POINTERSTATE.touch.scrollDecided){return;}
+POINTERSTATE.touch.scrollDecided=true;var ta=firstTouchAction(ev);var prevent=false;var dx=Math.abs(POINTERSTATE.touch.x-t.clientX);var dy=Math.abs(POINTERSTATE.touch.y-t.clientY);if(!ev.cancelable){}else if(ta==='none'){prevent=true;}else if(ta==='pan-x'){prevent=dy>dx;}else if(ta==='pan-y'){prevent=dx>dy;}
+if(prevent){ev.preventDefault();}else{Gestures.prevent('track');}}},add:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(!gobj){node[GESTURE_KEY]=gobj={};}
+for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&MOUSE_EVENTS.indexOf(dep)>-1&&dep!=='click'){continue;}
+gd=gobj[dep];if(!gd){gobj[dep]=gd={_count:0};}
+if(gd._count===0){node.addEventListener(dep,this.handleNative);}
+gd[name]=(gd[name]||0)+1;gd._count=(gd._count||0)+1;}
+node.addEventListener(evType,handler);if(recognizer.touchAction){this.setTouchAction(node,recognizer.touchAction);}},remove:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(gobj){for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];gd=gobj[dep];if(gd&&gd[name]){gd[name]=(gd[name]||1)-1;gd._count=(gd._count||1)-1;if(gd._count===0){node.removeEventListener(dep,this.handleNative);}}}}
+node.removeEventListener(evType,handler);},register:function(recog){this.recognizers.push(recog);for(var i=0;i<recog.emits.length;i++){this.gestures[recog.emits[i]]=recog;}},findRecognizerByEvent:function(evName){for(var i=0,r;i<this.recognizers.length;i++){r=this.recognizers[i];for(var j=0,n;j<r.emits.length;j++){n=r.emits[j];if(n===evName){return r;}}}
+return null;},setTouchAction:function(node,value){if(HAS_NATIVE_TA){node.style.touchAction=value;}
+node[TOUCH_ACTION]=value;},fire:function(target,type,detail){var ev=Polymer.Base.fire(type,detail,{node:target,bubbles:true,cancelable:true});if(ev.defaultPrevented){var preventer=detail.preventer||detail.sourceEvent;if(preventer&&preventer.preventDefault){preventer.preventDefault();}}},prevent:function(evName){var recognizer=this.findRecognizerByEvent(evName);if(recognizer.info){recognizer.info.prevent=true;}},resetMouseCanceller:function(){if(POINTERSTATE.mouse.mouseIgnoreJob){POINTERSTATE.mouse.mouseIgnoreJob.complete();}}};Gestures.register({name:'downup',deps:['mousedown','touchstart','touchend'],flow:{start:['mousedown','touchstart'],end:['mouseup','touchend']},emits:['down','up'],info:{movefn:null,upfn:null},reset:function(){untrackDocument(this.info);},mousedown:function(e){if(!hasLeftMouseButton(e)){return;}
+var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){if(!hasLeftMouseButton(e)){self.fire('up',t,e);untrackDocument(self.info);}};var upfn=function upfn(e){if(hasLeftMouseButton(e)){self.fire('up',t,e);}
+untrackDocument(self.info);};trackDocument(this.info,movefn,upfn);this.fire('down',t,e);},touchstart:function(e){this.fire('down',Gestures.findOriginalTarget(e),e.changedTouches[0],e);},touchend:function(e){this.fire('up',Gestures.findOriginalTarget(e),e.changedTouches[0],e);},fire:function(type,target,event,preventer){Gestures.fire(target,type,{x:event.clientX,y:event.clientY,sourceEvent:event,preventer:preventer,prevent:function(e){return Gestures.prevent(e);}});}});Gestures.register({name:'track',touchAction:'none',deps:['mousedown','touchstart','touchmove','touchend'],flow:{start:['mousedown','touchstart'],end:['mouseup','touchend']},emits:['track'],info:{x:0,y:0,state:'start',started:false,moves:[],addMove:function(move){if(this.moves.length>TRACK_LENGTH){this.moves.shift();}
+this.moves.push(move);},movefn:null,upfn:null,prevent:false},reset:function(){this.info.state='start';this.info.started=false;this.info.moves=[];this.info.x=0;this.info.y=0;this.info.prevent=false;untrackDocument(this.info);},hasMovedEnough:function(x,y){if(this.info.prevent){return false;}
+if(this.info.started){return true;}
+var dx=Math.abs(this.info.x-x);var dy=Math.abs(this.info.y-y);return dx>=TRACK_DISTANCE||dy>=TRACK_DISTANCE;},mousedown:function(e){if(!hasLeftMouseButton(e)){return;}
+var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){var x=e.clientX,y=e.clientY;if(self.hasMovedEnough(x,y)){self.info.state=self.info.started?e.type==='mouseup'?'end':'track':'start';if(self.info.state==='start'){Gestures.prevent('tap');}
+self.info.addMove({x:x,y:y});if(!hasLeftMouseButton(e)){self.info.state='end';untrackDocument(self.info);}
+self.fire(t,e);self.info.started=true;}};var upfn=function upfn(e){if(self.info.started){movefn(e);}
+untrackDocument(self.info);};trackDocument(this.info,movefn,upfn);this.info.x=e.clientX;this.info.y=e.clientY;},touchstart:function(e){var ct=e.changedTouches[0];this.info.x=ct.clientX;this.info.y=ct.clientY;},touchmove:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];var x=ct.clientX,y=ct.clientY;if(this.hasMovedEnough(x,y)){if(this.info.state==='start'){Gestures.prevent('tap');}
+this.info.addMove({x:x,y:y});this.fire(t,ct);this.info.state='track';this.info.started=true;}},touchend:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];if(this.info.started){this.info.state='end';this.info.addMove({x:ct.clientX,y:ct.clientY});this.fire(t,ct,e);}},fire:function(target,touch,preventer){var secondlast=this.info.moves[this.info.moves.length-2];var lastmove=this.info.moves[this.info.moves.length-1];var dx=lastmove.x-this.info.x;var dy=lastmove.y-this.info.y;var ddx,ddy=0;if(secondlast){ddx=lastmove.x-secondlast.x;ddy=lastmove.y-secondlast.y;}
+return Gestures.fire(target,'track',{state:this.info.state,x:touch.clientX,y:touch.clientY,dx:dx,dy:dy,ddx:ddx,ddy:ddy,sourceEvent:touch,preventer:preventer,hover:function(){return Gestures.deepTargetFind(touch.clientX,touch.clientY);}});}});Gestures.register({name:'tap',deps:['mousedown','click','touchstart','touchend'],flow:{start:['mousedown','touchstart'],end:['click','touchend']},emits:['tap'],info:{x:NaN,y:NaN,prevent:false},reset:function(){this.info.x=NaN;this.info.y=NaN;this.info.prevent=false;},save:function(e){this.info.x=e.clientX;this.info.y=e.clientY;},mousedown:function(e){if(hasLeftMouseButton(e)){this.save(e);}},click:function(e){if(hasLeftMouseButton(e)){this.forward(e);}},touchstart:function(e){this.save(e.changedTouches[0],e);},touchend:function(e){this.forward(e.changedTouches[0],e);},forward:function(e,preventer){var dx=Math.abs(e.clientX-this.info.x);var dy=Math.abs(e.clientY-this.info.y);var t=Gestures.findOriginalTarget(e);if(isNaN(dx)||isNaN(dy)||dx<=TAP_DISTANCE&&dy<=TAP_DISTANCE||isSyntheticClick(e)){if(!this.info.prevent){Gestures.fire(t,'tap',{x:e.clientX,y:e.clientY,sourceEvent:e,preventer:preventer});}}}});var DIRECTION_MAP={x:'pan-x',y:'pan-y',none:'none',all:'auto'};Polymer.Base._addFeature({_setupGestures:function(){this.__polymerGestures=null;},_listen:function(node,eventName,handler){if(Gestures.gestures[eventName]){Gestures.add(node,eventName,handler);}else{node.addEventListener(eventName,handler);}},_unlisten:function(node,eventName,handler){if(Gestures.gestures[eventName]){Gestures.remove(node,eventName,handler);}else{node.removeEventListener(eventName,handler);}},setScrollDirection:function(direction,node){node=node||this;Gestures.setTouchAction(node,DIRECTION_MAP[direction]||'auto');}});Polymer.Gestures=Gestures;}());(function(){'use strict';Polymer.Base._addFeature({$$:function(slctr){return Polymer.dom(this.root).querySelector(slctr);},toggleClass:function(name,bool,node){node=node||this;if(arguments.length==1){bool=!node.classList.contains(name);}
+if(bool){Polymer.dom(node).classList.add(name);}else{Polymer.dom(node).classList.remove(name);}},toggleAttribute:function(name,bool,node){node=node||this;if(arguments.length==1){bool=!node.hasAttribute(name);}
+if(bool){Polymer.dom(node).setAttribute(name,'');}else{Polymer.dom(node).removeAttribute(name);}},classFollows:function(name,toElement,fromElement){if(fromElement){Polymer.dom(fromElement).classList.remove(name);}
+if(toElement){Polymer.dom(toElement).classList.add(name);}},attributeFollows:function(name,toElement,fromElement){if(fromElement){Polymer.dom(fromElement).removeAttribute(name);}
+if(toElement){Polymer.dom(toElement).setAttribute(name,'');}},getEffectiveChildNodes:function(){return Polymer.dom(this).getEffectiveChildNodes();},getEffectiveChildren:function(){var list=Polymer.dom(this).getEffectiveChildNodes();return list.filter(function(n){return n.nodeType===Node.ELEMENT_NODE;});},getEffectiveTextContent:function(){var cn=this.getEffectiveChildNodes();var tc=[];for(var i=0,c;c=cn[i];i++){if(c.nodeType!==Node.COMMENT_NODE){tc.push(Polymer.dom(c).textContent);}}
+return tc.join('');},queryEffectiveChildren:function(slctr){var e$=Polymer.dom(this).queryDistributedElements(slctr);return e$&&e$[0];},queryAllEffectiveChildren:function(slctr){return Polymer.dom(this).queryDistributedElements(slctr);},getContentChildNodes:function(slctr){var content=Polymer.dom(this.root).querySelector(slctr||'content');return content?Polymer.dom(content).getDistributedNodes():[];},getContentChildren:function(slctr){return this.getContentChildNodes(slctr).filter(function(n){return n.nodeType===Node.ELEMENT_NODE;});},fire:function(type,detail,options){options=options||Polymer.nob;var node=options.node||this;detail=detail===null||detail===undefined?{}:detail;var bubbles=options.bubbles===undefined?true:options.bubbles;var cancelable=Boolean(options.cancelable);var useCache=options._useCache;var event=this._getEvent(type,bubbles,cancelable,useCache);event.detail=detail;if(useCache){this.__eventCache[type]=null;}
+node.dispatchEvent(event);if(useCache){this.__eventCache[type]=event;}
+return event;},__eventCache:{},_getEvent:function(type,bubbles,cancelable,useCache){var event=useCache&&this.__eventCache[type];if(!event||(event.bubbles!=bubbles||event.cancelable!=cancelable)){event=new Event(type,{bubbles:Boolean(bubbles),cancelable:cancelable});}
+return event;},async:function(callback,waitTime){var self=this;return Polymer.Async.run(function(){callback.call(self);},waitTime);},cancelAsync:function(handle){Polymer.Async.cancel(handle);},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0){return path.splice(index,1);}}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0){return this.splice(path,index,1);}}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform;},translate3d:function(x,y,z,node){node=node||this;this.transform('translate3d('+x+','+y+','+z+')',node);},importHref:function(href,onload,onerror,optAsync){var link=document.createElement('link');link.rel='import';link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onload.call(self,e);};var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onerror.call(self,e);};if(onload){imprt.addEventListener('load',loadListener);}
+if(onerror){imprt.addEventListener('error',errorListener);}
+if(cached){if(cached.__firedLoad){cached.dispatchEvent(new Event('load'));}
+if(cached.__firedError){cached.dispatchEvent(new Event('error'));}}else{list[link.href]=link;optAsync=Boolean(optAsync);if(optAsync){link.setAttribute('async','');}
+document.head.appendChild(link);}
+return imprt;},create:function(tag,props){var elt=document.createElement(tag);if(props){for(var n in props){elt[n]=props[n];}}
+return elt;},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot();},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot();}});if(!Polymer.Settings.useNativeCustomElements){var importHref=Polymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload){return onload.call(this,e);}};return importHref.call(this,href,loadFn,onerror,optAsync);};}}());Polymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi);},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+'-changed';this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===value)){this.__data__[property]=value;if(typeof value=='object'){this._clearPath(property);}
+if(this._propertyChanged){this._propertyChanged(property,value,old);}
+if(effects){this._effectEffects(property,value,effects,old,fromAbove);}}
+return old;},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects){node._propertySetter(property,value,effects,quiet);}else if(node[property]!==value){node[property]=value;}},_effectEffects:function(property,value,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++){fx.fn.call(this,property,this[property],fx.effect,old,fromAbove);}},_clearPath:function(path){for(var prop in this.__data__){if(Polymer.Path.isDescendant(path,prop)){this.__data__[prop]=undefined;}}}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects){model._propertyEffects={};}
+var fx=model._propertyEffects[property];if(!fx){fx=model._propertyEffects[property]=[];}
+return fx;},addPropertyEffect:function(model,property,kind,effect){var fx=this.ensurePropertyEffects(model,property);var propEffect={kind:kind,effect:effect,fn:Polymer.Bind['_'+kind+'Effect']};fx.push(propEffect);return propEffect;},createBindings:function(model){var fx$=model._propertyEffects;if(fx$){for(var n in fx$){var fx=fx$[n];fx.sort(this._sortPropertyEffects);this._createAccessors(model,n,fx);}}},_sortPropertyEffects:function(){var EFFECT_ORDER={'compute':0,'annotation':1,'annotatedComputation':2,'reflect':3,'notify':4,'observer':5,'complexObserver':6,'function':7};return function(a,b){return EFFECT_ORDER[a.kind]-EFFECT_ORDER[b.kind];};}(),_createAccessors:function(model,property,effects){var defun={get:function(){return this.__data__[property];}};var setter=function(value){this._propertySetter(property,value,effects);};var info=model.getPropertyInfo&&model.getPropertyInfo(property);if(info&&info.readOnly){if(!info.computed){model['_set'+this.upper(property)]=setter;}}else{defun.set=setter;}
+Object.defineProperty(model,property,defun);},upper:function(name){return name[0].toUpperCase()+name.substring(1);},_addAnnotatedListener:function(model,index,property,path,event,negated){if(!model._bindListeners){model._bindListeners=[];}
+var fn=this._notedListenerFactory(property,path,Polymer.Path.isDeep(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+'-changed';model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName});},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target;},_notedListenerFactory:function(property,path,isStructured,negated){return function(target,value,targetPath){if(targetPath){var newPath=Polymer.Path.translate(property,path,targetPath);this._notifyPath(newPath,value);}else{value=target[property];if(negated){value=!value;}
+if(!isStructured){this[path]=value;}else{if(this.__data__[path]!=value){this.set(path,value);}}}};},prepareInstance:function(inst){inst.__data__=Object.create(null);},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=inst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn);}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e);});}};Polymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!='attribute'&&effect.kind!='text'&&!effect.isCompound&&effect.parts[0].mode==='{';},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value;}
+this._applyEffectValue(effect,value);},_reflectEffect:function(source,value,effect){this.reflectPropertyToAttribute(source,effect.attribute,value);},_notifyEffect:function(source,value,effect,old,fromAbove){if(!fromAbove){this._notifyChange(source,effect.event,value);}},_functionEffect:function(source,value,fn,old,fromAbove){fn.call(this,source,value,old,fromAbove);},_observerEffect:function(source,value,effect,old){var fn=this[effect.method];if(fn){fn.call(this,value,old);}else{this._warn(this._logf('_observerEffect','observer method `'+effect.method+'` not defined'));}},_complexObserverEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){fn.apply(this,args);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_complexObserverEffect','observer method `'+effect.method+'` not defined'));}},_computeEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(this,args);this.__setProperty(effect.name,computedvalue);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_computeEffect','compute method `'+effect.method+'` not defined'));}},_annotatedComputationEffect:function(source,value,effect){var computedHost=this._rootDataHost||this;var fn=computedHost[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(computedHost,args);this._applyEffectValue(effect,computedvalue);}}else if(effect.dynamicFn){}else{computedHost._warn(computedHost._logf('_annotatedComputationEffect','compute method `'+effect.method+'` not defined'));}},_marshalArgs:function(model,effect,path,value){var values=[];var args=effect.args;var bailoutEarly=args.length>1||effect.dynamicFn;for(var i=0,l=args.length;i<l;i++){var arg=args[i];var name=arg.name;var v;if(arg.literal){v=arg.value;}else if(path===name){v=value;}else{v=model[name];if(v===undefined&&arg.structured){v=Polymer.Base._get(name,model);}}
+if(bailoutEarly&&v===undefined){return;}
+if(arg.wildcard){var matches=Polymer.Path.isAncestor(path,name);values[i]={path:matches?path:name,value:matches?value:v,base:v};}else{values[i]=v;}}
+return values;}});Polymer.Base._addFeature({_addPropertyEffect:function(property,kind,effect){var prop=Polymer.Bind.addPropertyEffect(this,property,kind,effect);prop.pathFn=this['_'+prop.kind+'PathEffect'];},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes);},_prepBindings:function(){Polymer.Bind.createBindings(this);},_addPropertyEffects:function(properties){if(properties){for(var p in properties){var prop=properties[p];if(prop.observer){this._addObserverEffect(p,prop.observer);}
+if(prop.computed){prop.readOnly=true;this._addComputedEffect(p,prop.computed);}
+if(prop.notify){this._addPropertyEffect(p,'notify',{event:Polymer.CaseMap.camelToDashCase(p)+'-changed'});}
+if(prop.reflectToAttribute){var attr=Polymer.CaseMap.camelToDashCase(p);if(attr[0]==='-'){this._warn(this._logf('_addPropertyEffects','Property '+p+' cannot be reflected to attribute '+attr+' because "-" is not a valid starting attribute name. Use a lowercase first letter for the property instead.'));}else{this._addPropertyEffect(p,'reflect',{attribute:attr});}}
+if(prop.readOnly){Polymer.Bind.ensurePropertyEffects(this,p);}}}},_addComputedEffect:function(name,expression){var sig=this._parseMethod(expression);var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){this._addPropertyEffect(arg.model,'compute',{method:sig.method,args:sig.args,trigger:arg,name:name,dynamicFn:dynamicFn});}
+if(dynamicFn){this._addPropertyEffect(sig.method,'compute',{method:sig.method,args:sig.args,trigger:null,name:name,dynamicFn:dynamicFn});}},_addObserverEffect:function(property,observer){this._addPropertyEffect(property,'observer',{method:observer,property:property});},_addComplexObserverEffects:function(observers){if(observers){for(var i=0,o;i<observers.length&&(o=observers[i]);i++){this._addComplexObserverEffect(o);}}},_addComplexObserverEffect:function(observer){var sig=this._parseMethod(observer);if(!sig){throw new Error('Malformed observer expression \''+observer+'\'');}
+var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){this._addPropertyEffect(arg.model,'complexObserver',{method:sig.method,args:sig.args,trigger:arg,dynamicFn:dynamicFn});}
+if(dynamicFn){this._addPropertyEffect(sig.method,'complexObserver',{method:sig.method,args:sig.args,trigger:null,dynamicFn:dynamicFn});}},_addAnnotationEffects:function(notes){for(var i=0,note;i<notes.length&&(note=notes[i]);i++){var b$=note.bindings;for(var j=0,binding;j<b$.length&&(binding=b$[j]);j++){this._addAnnotationEffect(binding,i);}}},_addAnnotationEffect:function(note,index){if(Polymer.Bind._shouldAddListener(note)){Polymer.Bind._addAnnotatedListener(this,index,note.name,note.parts[0].value,note.parts[0].event,note.parts[0].negate);}
+for(var i=0;i<note.parts.length;i++){var part=note.parts[i];if(part.signature){this._addAnnotatedComputationEffect(note,part,index);}else if(!part.literal){if(note.kind==='attribute'&&note.name[0]==='-'){this._warn(this._logf('_addAnnotationEffect','Cannot set attribute '+note.name+' because "-" is not a valid attribute starting character'));}else{this._addPropertyEffect(part.model,'annotation',{kind:note.kind,index:index,name:note.name,propertyName:note.propertyName,value:part.value,isCompound:note.isCompound,compoundIndex:part.compoundIndex,event:part.event,customEvent:part.customEvent,negate:part.negate});}}}},_addAnnotatedComputationEffect:function(note,part,index){var sig=part.signature;if(sig.static){this.__addAnnotatedComputationEffect('__static__',index,note,part,null);}else{for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){if(!arg.literal){this.__addAnnotatedComputationEffect(arg.model,index,note,part,arg);}}
+if(sig.dynamicFn){this.__addAnnotatedComputationEffect(sig.method,index,note,part,null);}}},__addAnnotatedComputationEffect:function(property,index,note,part,trigger){this._addPropertyEffect(property,'annotatedComputation',{index:index,isCompound:note.isCompound,compoundIndex:part.compoundIndex,kind:note.kind,name:note.name,negate:part.negate,method:part.signature.method,args:part.signature.args,trigger:trigger,dynamicFn:part.signature.dynamicFn});},_parseMethod:function(expression){var m=expression.match(/([^\s]+?)\(([\s\S]*)\)/);if(m){var sig={method:m[1],static:true};if(this.getPropertyInfo(sig.method)!==Polymer.nob){sig.static=false;sig.dynamicFn=true;}
+if(m[2].trim()){var args=m[2].replace(/\\,/g,'&comma;').split(',');return this._parseArgs(args,sig);}else{sig.args=Polymer.nar;return sig;}}},_parseArgs:function(argList,sig){sig.args=argList.map(function(rawArg){var arg=this._parseArg(rawArg);if(!arg.literal){sig.static=false;}
+return arg;},this);return sig;},_parseArg:function(rawArg){var arg=rawArg.trim().replace(/&comma;/g,',').replace(/\\(.)/g,'$1');var a={name:arg};var fc=arg[0];if(fc==='-'){fc=arg[1];}
+if(fc>='0'&&fc<='9'){fc='#';}
+switch(fc){case'\'':case'"':a.value=arg.slice(1,-1);a.literal=true;break;case'#':a.value=Number(arg);a.literal=true;break;}
+if(!a.literal){a.model=Polymer.Path.root(arg);a.structured=Polymer.Path.isDeep(arg);if(a.structured){a.wildcard=arg.slice(-2)=='.*';if(a.wildcard){a.name=arg.slice(0,-2);}}}
+return a;},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners){Polymer.Bind.setupBindListeners(this);}},_applyEffectValue:function(info,value){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.kind=='attribute'){this.serializeValueToAttribute(value,property,node);}else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly){return;}
+this.__setProperty(property,value,Polymer.Settings.suppressBindingNotifications,node);}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate){value=!value;}
+if(info.isCompound){var storage=node.__compoundStorage__[property];storage[info.compoundIndex]=value;value=storage.join('');}
+if(info.kind!=='attribute'){if(property==='className'){value=this._scopeElementClass(node,value);}
+if(property==='textContent'||node.localName=='input'&&property=='value'){value=value==undefined?'':value;}}
+return value;},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__){this._effectEffects('__static__',null,this._propertyEffects.__static__);}}});(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;var avoidInstanceProperties=Boolean(Object.getOwnPropertyDescriptor(document.documentElement,'properties'));Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig){for(var i in initialConfig){if(initialConfig[i]!==undefined){this._config[i]=initialConfig[i];}}}},_marshalAttributes:function(){this._takeAttributesToModel(this._config);},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name);},_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly){this._config[name]=value;}},_beforeClientsReady:function(){this._configure();},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++){this._configureProperties(this.behaviors[i].properties,config);}
+this._configureProperties(avoidInstanceProperties?this.__proto__.properties:this.properties,config);this.mixin(config,this._aboveConfig);this._config=config;if(this._clients&&this._clients.length){this._distributeConfig(this._config);}},_configureInstanceProperties:function(){for(var i in this._propertyEffects){if(!usePolyfillProto&&this.hasOwnProperty(i)){this._configValue(i,this[i]);delete this[i];}}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(c.value!==undefined){var value=c.value;if(typeof value=='function'){value=value.call(this,this._config);}
+config[i]=value;}}},_distributeConfig:function(config){var fx$=this._propertyEffects;if(fx$){for(var p in config){var fx=fx$[p];if(fx){for(var i=0,l=fx.length,x;i<l&&(x=fx[i]);i++){if(x.kind==='annotation'){var node=this._nodes[x.effect.index];var name=x.effect.propertyName;var isAttr=x.effect.kind=='attribute';var hasEffect=node._propertyEffects&&node._propertyEffects[name];if(node._configValue&&(hasEffect||!isAttr)){var value=p===x.effect.value?config[p]:this._get(x.effect.value,config);value=this._computeFinalAnnotationValue(node,name,value,x.effect);if(isAttr){value=node.deserialize(this.serialize(value),node._propertyInfo[name].type);}
+node._configValue(name,value);}}}}}}},_afterClientsReady:function(){this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers();},_applyConfig:function(config,aboveConfig){for(var n in config){if(this[n]===undefined){this.__setProperty(n,config[n],n in aboveConfig);}}},_notifyListener:function(fn,e){if(!Polymer.Bind._isEventBogus(e,e.target)){var value,path;if(e.detail){value=e.detail.value;path=e.detail.path;}
+if(!this._clientsReadied){this._queueHandler([fn,e.target,value,path]);}else{return fn.call(this,e.target,value,path);}}},_queueHandler:function(args){this._handlers.push(args);},_flushHandlers:function(){var h$=this._handlers;for(var i=0,l=h$.length,h;i<l&&(h=h$[i]);i++){h[0].call(this,h[1],h[2],h[3]);}
+this._handlers=[];}});}());(function(){'use strict';var Path=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1){value=v;}
+if(info.path){this._notifyPath(info.path,value,fromAbove);}},_notifyPath:function(path,value,fromAbove){var old=this._propertySetter(path,value);if(old!==value&&(old===old||value===value)){this._pathEffector(path,value);if(!fromAbove){this._notifyPathUp(path,value);}
+return true;}},_getPathParts:function(path){if(Array.isArray(path)){var parts=[];for(var i=0;i<path.length;i++){var args=path[i].toString().split('.');for(var j=0;j<args.length;j++){parts.push(args[j]);}}
+return parts;}else{return path.toString().split('.');}},set:function(path,value,root){var prop=root||this;var parts=this._getPathParts(path);var array;var last=parts[parts.length-1];if(parts.length>1){for(var i=0;i<parts.length-1;i++){var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
+if(!prop){return;}
+array=Array.isArray(prop)?prop:null;}
+if(array){var coll=Polymer.Collection.get(array);var old,key;if(last[0]=='#'){key=last;old=coll.getItem(key);last=array.indexOf(old);coll.setItem(key,value);}else if(parseInt(last,10)==last){old=prop[last];key=coll.getKey(old);parts[i]=key;coll.setItem(key,value);}}
+prop[last]=value;if(!root){this._notifyPath(parts.join('.'),value);}}else{prop[path]=value;}},get:function(path,root){return this._get(path,root);},_get:function(path,root,info){var prop=root||this;var parts=this._getPathParts(path);var array;for(var i=0;i<parts.length;i++){if(!prop){return;}
+var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(info&&array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
+array=Array.isArray(prop)?prop:null;}
+if(info){info.path=parts.join('.');}
+return prop;},_pathEffector:function(path,value){var model=Path.root(path);var fx$=this._propertyEffects&&this._propertyEffects[model];if(fx$){for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn){fxFn.call(this,path,value,fx.effect);}}}
+if(this._boundPaths){this._notifyBoundPaths(path,value);}},_annotationPathEffect:function(path,value,effect){if(Path.matches(effect.value,false,path)){Polymer.Bind._annotationEffect.call(this,path,value,effect);}else if(!effect.negate&&Path.isDescendant(effect.value,path)){var node=this._nodes[effect.index];if(node&&node._notifyPath){var newPath=Path.translate(effect.value,effect.name,path);node._notifyPath(newPath,value,true);}}},_complexObserverPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._complexObserverEffect.call(this,path,value,effect);}},_computePathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._computeEffect.call(this,path,value,effect);}},_annotatedComputationPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect);}},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from){this._boundPaths[to]=from;}else{this.unlinkPaths(to);}},unlinkPaths:function(path){if(this._boundPaths){delete this._boundPaths[path];}},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(Path.isDescendant(a,path)){this._notifyPath(Path.translate(a,b,path),value);}else if(Path.isDescendant(b,path)){this._notifyPath(Path.translate(b,a,path),value);}}},_notifyPathUp:function(path,value){var rootName=Path.root(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_EVENT_CHANGED:'-changed',notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,splices);},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+'.splices';this._notifyPath(splicesPath,change);this._notifyPath(path+'.length',array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null};},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:'splice'}]);},push:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length){this._notifySplice(array,info.path,len,args.length,[]);}
+return ret;},pop:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.pop.apply(array,args);if(hadLength){this._notifySplice(array,info.path,array.length,0,[ret]);}
+return ret;},splice:function(path,start){var info={};var array=this._get(path,this,info);if(start<0){start=array.length-Math.floor(-start);}else{start=Math.floor(start);}
+if(!start){start=0;}
+var args=Array.prototype.slice.call(arguments,1);var ret=array.splice.apply(array,args);var addedCount=Math.max(args.length-2,0);if(addedCount||ret.length){this._notifySplice(array,info.path,start,addedCount,ret);}
+return ret;},shift:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.shift.apply(array,args);if(hadLength){this._notifySplice(array,info.path,0,0,[ret]);}
+return ret;},unshift:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var ret=array.unshift.apply(array,args);if(args.length){this._notifySplice(array,info.path,0,args.length,[]);}
+return ret;},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,notifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,_getPathParts:Polymer.Base._getPathParts});}});}());Polymer.Base._addFeature({resolveUrl:function(url){var module=Polymer.DomModule.import(this.is);var root='';if(module){var assetPath=module.getAttribute('assetpath')||'';root=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI);}
+return Polymer.ResolveUrl.resolveUrl(url,root);}});Polymer.CssParse=function(){return{parse:function(text){text=this._clean(text);return this._parseCss(this._lex(text),text);},_clean:function(cssText){return cssText.replace(this._rx.comments,'').replace(this._rx.port,'');},_lex:function(text){var root={start:0,end:text.length};var n=root;for(var i=0,l=text.length;i<l;i++){switch(text[i]){case this.OPEN_BRACE:if(!n.rules){n.rules=[];}
+var p=n;var previous=p.rules[p.rules.length-1];n={start:i+1,parent:p,previous:previous};p.rules.push(n);break;case this.CLOSE_BRACE:n.end=i+1;n=n.parent||root;break;}}
+return root;},_parseCss:function(node,text){var t=text.substring(node.start,node.end-1);node.parsedCssText=node.cssText=t.trim();if(node.parent){var ss=node.previous?node.previous.end:node.parent.start;t=text.substring(ss,node.start-1);t=this._expandUnicodeEscapes(t);t=t.replace(this._rx.multipleSpaces,' ');t=t.substring(t.lastIndexOf(';')+1);var s=node.parsedSelector=node.selector=t.trim();node.atRule=s.indexOf(this.AT_START)===0;if(node.atRule){if(s.indexOf(this.MEDIA_START)===0){node.type=this.types.MEDIA_RULE;}else if(s.match(this._rx.keyframesRule)){node.type=this.types.KEYFRAMES_RULE;node.keyframesName=node.selector.split(this._rx.multipleSpaces).pop();}}else{if(s.indexOf(this.VAR_START)===0){node.type=this.types.MIXIN_RULE;}else{node.type=this.types.STYLE_RULE;}}}
+var r$=node.rules;if(r$){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){this._parseCss(r,text);}}
+return node;},_expandUnicodeEscapes:function(s){return s.replace(/\\([0-9a-f]{1,6})\s/gi,function(){var code=arguments[1],repeat=6-code.length;while(repeat--){code='0'+code;}
+return'\\'+code;});},stringify:function(node,preserveProperties,text){text=text||'';var cssText='';if(node.cssText||node.rules){var r$=node.rules;if(r$&&!this._hasMixinRules(r$)){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){cssText=this.stringify(r,preserveProperties,cssText);}}else{cssText=preserveProperties?node.cssText:this.removeCustomProps(node.cssText);cssText=cssText.trim();if(cssText){cssText='  '+cssText+'\n';}}}
+if(cssText){if(node.selector){text+=node.selector+' '+this.OPEN_BRACE+'\n';}
+text+=cssText;if(node.selector){text+=this.CLOSE_BRACE+'\n\n';}}
+return text;},_hasMixinRules:function(rules){return rules[0].selector.indexOf(this.VAR_START)===0;},removeCustomProps:function(cssText){cssText=this.removeCustomPropAssignment(cssText);return this.removeCustomPropApply(cssText);},removeCustomPropAssignment:function(cssText){return cssText.replace(this._rx.customProp,'').replace(this._rx.mixinProp,'');},removeCustomPropApply:function(cssText){return cssText.replace(this._rx.mixinApply,'').replace(this._rx.varApply,'');},types:{STYLE_RULE:1,KEYFRAMES_RULE:7,MEDIA_RULE:4,MIXIN_RULE:1000},OPEN_BRACE:'{',CLOSE_BRACE:'}',_rx:{comments:/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,port:/@import[^;]*;/gim,customProp:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,mixinProp:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,mixinApply:/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,varApply:/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,keyframesRule:/^@[^\s]*keyframes/,multipleSpaces:/\s+/g},VAR_START:'--',MEDIA_START:'@media',AT_START:'@'};}();Polymer.StyleUtil=function(){var settings=Polymer.Settings;return{NATIVE_VARIABLES:Polymer.Settings.useNativeCSSProperties,MODULE_STYLES_SELECTOR:'style, link[rel=import][type~=css], template',INCLUDE_ATTR:'include',toCssText:function(rules,callback){if(typeof rules==='string'){rules=this.parser.parse(rules);}
+if(callback){this.forEachRule(rules,callback);}
+return this.parser.stringify(rules,this.NATIVE_VARIABLES);},forRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles){for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback);}}},forActiveRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles){for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback,true);}}},rulesForStyle:function(style){if(!style.__cssRules&&style.textContent){style.__cssRules=this.parser.parse(style.textContent);}
+return style.__cssRules;},isKeyframesSelector:function(rule){return rule.parent&&rule.parent.type===this.ruleTypes.KEYFRAMES_RULE;},forEachRuleInStyle:function(style,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){var rules=this.rulesForStyle(style);var styleCallback,keyframeCallback;if(styleRuleCallback){styleCallback=function(rule){styleRuleCallback(rule,style);};}
+if(keyframesRuleCallback){keyframeCallback=function(rule){keyframesRuleCallback(rule,style);};}
+this.forEachRule(rules,styleCallback,keyframeCallback,onlyActiveRules);},forEachRule:function(node,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){if(!node){return;}
+var skipRules=false;if(onlyActiveRules){if(node.type===this.ruleTypes.MEDIA_RULE){var matchMedia=node.selector.match(this.rx.MEDIA_MATCH);if(matchMedia){if(!window.matchMedia(matchMedia[1]).matches){skipRules=true;}}}}
+if(node.type===this.ruleTypes.STYLE_RULE){styleRuleCallback(node);}else if(keyframesRuleCallback&&node.type===this.ruleTypes.KEYFRAMES_RULE){keyframesRuleCallback(node);}else if(node.type===this.ruleTypes.MIXIN_RULE){skipRules=true;}
+var r$=node.rules;if(r$&&!skipRules){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){this.forEachRule(r,styleRuleCallback,keyframesRuleCallback,onlyActiveRules);}}},applyCss:function(cssText,moniker,target,contextNode){var style=this.createScopeStyle(cssText,moniker);return this.applyStyle(style,target,contextNode);},applyStyle:function(style,target,contextNode){target=target||document.head;var after=contextNode&&contextNode.nextSibling||target.firstChild;this.__lastHeadApplyNode=style;return target.insertBefore(style,after);},createScopeStyle:function(cssText,moniker){var style=document.createElement('style');if(moniker){style.setAttribute('scope',moniker);}
+style.textContent=cssText;return style;},__lastHeadApplyNode:null,applyStylePlaceHolder:function(moniker){var placeHolder=document.createComment(' Shady DOM styles for '+moniker+' ');var after=this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null;var scope=document.head;scope.insertBefore(placeHolder,after||scope.firstChild);this.__lastHeadApplyNode=placeHolder;return placeHolder;},cssFromModules:function(moduleIds,warnIfNotFound){var modules=moduleIds.trim().split(' ');var cssText='';for(var i=0;i<modules.length;i++){cssText+=this.cssFromModule(modules[i],warnIfNotFound);}
+return cssText;},cssFromModule:function(moduleId,warnIfNotFound){var m=Polymer.DomModule.import(moduleId);if(m&&!m._cssText){m._cssText=this.cssFromElement(m);}
+if(!m&&warnIfNotFound){console.warn('Could not find style data in module named',moduleId);}
+return m&&m._cssText||'';},cssFromElement:function(element){var cssText='';var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName==='template'){if(!e.hasAttribute('preserve-content')){cssText+=this.cssFromElement(e);}}else{if(e.localName==='style'){var include=e.getAttribute(this.INCLUDE_ATTR);if(include){cssText+=this.cssFromModules(include,true);}
+e=e.__appliedElement||e;e.parentNode.removeChild(e);cssText+=this.resolveCss(e.textContent,element.ownerDocument);}else if(e.import&&e.import.body){cssText+=this.resolveCss(e.import.body.textContent,e.import);}}}
+return cssText;},styleIncludesToTemplate:function(targetTemplate){var styles=targetTemplate.content.querySelectorAll('style[include]');for(var i=0,s;i<styles.length;i++){s=styles[i];s.parentNode.insertBefore(this._includesToFragment(s.getAttribute('include')),s);}},_includesToFragment:function(styleIncludes){var includeArray=styleIncludes.trim().split(' ');var frag=document.createDocumentFragment();for(var i=0;i<includeArray.length;i++){var t=Polymer.DomModule.import(includeArray[i],'template');if(t){this._addStylesToFragment(frag,t.content);}}
+return frag;},_addStylesToFragment:function(frag,source){var s$=source.querySelectorAll('style');for(var i=0,s;i<s$.length;i++){s=s$[i];var include=s.getAttribute('include');if(include){frag.appendChild(this._includesToFragment(include));}
+if(s.textContent){frag.appendChild(s.cloneNode(true));}}},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType==='shadow':buildType==='shady';},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule.import(module);if(dm){return this.getCssBuildType(dm);}},getCssBuildType:function(element){return element.getAttribute('css-build');},_findMatchingParen:function(text,start){var level=0;for(var i=start,l=text.length;i<l;i++){switch(text[i]){case'(':level++;break;case')':if(--level===0){return i;}
+break;}}
+return-1;},processVariableAndFallback:function(str,callback){var start=str.indexOf('var(');if(start===-1){return callback(str,'','','');}
+var end=this._findMatchingParen(str,start+3);var inner=str.substring(start+4,end);var prefix=str.substring(0,start);var suffix=this.processVariableAndFallback(str.substring(end+1),callback);var comma=inner.indexOf(',');if(comma===-1){return callback(prefix,inner.trim(),'',suffix);}
+var value=inner.substring(0,comma).trim();var fallback=inner.substring(comma+1).trim();return callback(prefix,value,fallback,suffix);},rx:{VAR_ASSIGN:/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,MIXIN_MATCH:/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,VAR_CONSUMED:/(--[\w-]+)\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\s*:)|(animation-name\s*:)/,MEDIA_MATCH:/@media[^(]*(\([^)]*\))/,IS_VAR:/^--/,BRACKETED:/\{[^}]*\}/g,HOST_PREFIX:'(?:^|[^.#[:])',HOST_SUFFIX:'($|[.:[\\s>+~])'},resolveCss:Polymer.ResolveUrl.resolveCss,parser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types};}();Polymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||'',useAttr,shouldRemoveScope);},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute){this.element(node,selector,useAttr,shouldRemoveScope);}
+var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++){this._transformDom(c$[i],selector,useAttr,shouldRemoveScope);}},element:function(element,scope,useAttr,shouldRemoveScope){if(useAttr){if(shouldRemoveScope){element.removeAttribute(SCOPE_NAME);}else{element.setAttribute(SCOPE_NAME,scope);}}else{if(scope){if(element.classList){if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope);}else{element.classList.add(SCOPE_NAME);element.classList.add(scope);}}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c){element.setAttribute(CLASS,c.replace(SCOPE_NAME,'').replace(scope,''));}}else{element.setAttribute(CLASS,(c?c+' ':'')+SCOPE_NAME+' '+scope);}}}}},elementStyles:function(element,callback){var styles=element._styles;var cssText='';var cssBuildType=element.__cssBuild;var passthrough=settings.useNativeShadow||cssBuildType==='shady';var cb;if(passthrough){var self=this;cb=function(rule){rule.selector=self._slottedToContent(rule.selector);rule.selector=rule.selector.replace(ROOT,':host > *');if(callback){callback(rule);}};}
+for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);cssText+=passthrough?styleUtil.toCssText(rules,cb):this.css(rules,element.is,element.extends,callback,element._scopeCssViaAttr)+'\n\n';}
+return cssText.trim();},css:function(rules,scope,ext,callback,useAttr){var hostScope=this._calcHostScope(scope,ext);scope=this._calcElementScope(scope,useAttr);var self=this;return styleUtil.toCssText(rules,function(rule){if(!rule.isScoped){self.rule(rule,scope,hostScope);rule.isScoped=true;}
+if(callback){callback(rule,scope,hostScope);}});},_calcElementScope:function(scope,useAttr){if(scope){return useAttr?CSS_ATTR_PREFIX+scope+CSS_ATTR_SUFFIX:CSS_CLASS_PREFIX+scope;}else{return'';}},_calcHostScope:function(scope,ext){return ext?'[is='+scope+']':scope;},rule:function(rule,scope,hostScope){this._transformRule(rule,this._transformComplexSelector,scope,hostScope);},_transformRule:function(rule,transformer,scope,hostScope){rule.selector=rule.transformedSelector=this._transformRuleCss(rule,transformer,scope,hostScope);},_transformRuleCss:function(rule,transformer,scope,hostScope){var p$=rule.selector.split(COMPLEX_SELECTOR_SEP);if(!styleUtil.isKeyframesSelector(rule)){for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){p$[i]=transformer.call(this,p,scope,hostScope);}}
+return p$.join(COMPLEX_SELECTOR_SEP);},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var self=this;selector=selector.trim();selector=this._slottedToContent(selector);selector=selector.replace(ROOT,':host > *');selector=selector.replace(CONTENT_START,HOST+' $1');selector=selector.replace(SIMPLE_SELECTOR_SEP,function(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;c=info.combinator;s=info.value;}else{s=s.replace(SCOPE_JUMP,' ');}
+return c+s;});if(hostContext){selector=selector.replace(HOST_CONTEXT_PAREN,function(m,pre,paren,post){return pre+paren+' '+hostScope+post+COMPLEX_SELECTOR_SEP+' '+pre+hostScope+paren+post;});}
+return selector;},_transformCompoundSelector:function(selector,combinator,scope,hostScope){var jumpIndex=selector.search(SCOPE_JUMP);var hostContext=false;if(selector.indexOf(HOST_CONTEXT)>=0){hostContext=true;}else if(selector.indexOf(HOST)>=0){selector=this._transformHostSelector(selector,hostScope);}else if(jumpIndex!==0){selector=scope?this._transformSimpleSelector(selector,scope):selector;}
+if(selector.indexOf(CONTENT)>=0){combinator='';}
+var stop;if(jumpIndex>=0){selector=selector.replace(SCOPE_JUMP,' ');stop=true;}
+return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext};},_transformSimpleSelector:function(selector,scope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX);},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||'';if(paren){if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope){return paren;}else{return SELECTOR_NO_MATCH;}}else{return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren;});}}else{return selector.replace(HOST,hostScope);}},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow){this._transformRule(rule,this._transformDocumentSelector);}},normalizeRootSelector:function(rule){rule.selector=rule.selector.replace(ROOT,'html');},_transformDocumentSelector:function(selector){return selector.match(SCOPE_JUMP)?this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR):this._transformSimpleSelector(selector.trim(),SCOPE_DOC_SELECTOR);},_slottedToContent:function(cssText){return cssText.replace(SLOTTED_PAREN,CONTENT+'> $1');},SCOPE_NAME:'style-scope'};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=':not(['+SCOPE_NAME+'])'+':not(.'+SCOPE_NAME+')';var COMPLEX_SELECTOR_SEP=',';var SIMPLE_SELECTOR_SEP=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=':host';var ROOT=':root';var HOST_PAREN=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/;var HOST_CONTEXT=':host-context';var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;var CONTENT='::content';var SCOPE_JUMP=/::content|::shadow|\/deep\//;var CSS_CLASS_PREFIX='.';var CSS_ATTR_PREFIX='['+SCOPE_NAME+'~=';var CSS_ATTR_SUFFIX=']';var PSEUDO_PREFIX=':';var CLASS='class';var CONTENT_START=new RegExp('^('+CONTENT+')');var SELECTOR_NO_MATCH='should_not_match';var SLOTTED_PAREN=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;return api;}();Polymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND));},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor){self._extendRule(rule,extendor);}}}
+rule.cssText=rule.cssText.replace(self.rx.EXTEND,'');});return styleUtil.toCssText(rules,function(rule){if(rule.selector.match(self.rx.STRIP)){rule.cssText='';}},true);},_mapRuleOntoParent:function(rule){if(rule.parent){var map=rule.parent.map||(rule.parent.map={});var parts=rule.selector.split(',');for(var i=0,p;i<parts.length;i++){p=parts[i];map[p.trim()]=rule;}
+return map;}},_findExtendor:function(extend,rule){return rule.parent&&rule.parent.map&&rule.parent.map[extend]||this._findExtendor(extend,rule.parent);},_extendRule:function(target,source){if(target.parent!==source.parent){this._cloneAndAddRuleToParent(source,target.parent);}
+target.extends=target.extends||[];target.extends.push(source);source.selector=source.selector.replace(this.rx.STRIP,'');source.selector=(source.selector&&source.selector+',\n')+target.selector;if(source.extends){source.extends.forEach(function(e){this._extendRule(target,e);},this);}},_cloneAndAddRuleToParent:function(rule,parent){rule=Object.create(rule);rule.parent=parent;if(rule.extends){rule.extends=rule.extends.slice();}
+parent.rules.push(rule);},rx:{EXTEND:/@extends\(([^)]*)\)\s*?;/gim,STRIP:/%[^,]*$/}};}();Polymer.ApplyShim=function(){'use strict';var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var BAD_VAR=/var\(\s*(--[^,]*),\s*(--[^)]*)\)/g;var APPLY_NAME_CLEAN=/;\s*/m;var INITIAL_INHERIT=/^\s*(initial)|(inherit)\s*$/;var MIXIN_VAR_SEP='_-_';var mixinMap={};function mapSet(name,props){name=name.trim();mixinMap[name]={properties:props,dependants:{}};}
+function mapGet(name){name=name.trim();return mixinMap[name];}
+function replaceInitialOrInherit(property,value){var match=INITIAL_INHERIT.exec(value);if(match){if(match[1]){value=ApplyShim._getInitialValueForProperty(property);}else{value='apply-shim-inherit';}}
+return value;}
+function cssTextToMap(text){var props=text.split(';');var property,value;var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(':');if(sp.length>1){property=sp[0].trim();value=replaceInitialOrInherit(property,sp.slice(1).join(':'));out[property]=value;}}}
+return out;}
+function invalidateMixinEntry(mixinEntry){var currentProto=ApplyShim.__currentElementProto;var currentElementName=currentProto&&currentProto.is;for(var elementName in mixinEntry.dependants){if(elementName!==currentElementName){mixinEntry.dependants[elementName].__applyShimInvalid=true;}}}
+function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty){styleUtil.processVariableAndFallback(valueProperty,function(prefix,value){if(value&&mapGet(value)){valueMixin='@apply '+value+';';}});}
+if(!valueMixin){return matchText;}
+var mixinAsProperties=consumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf('--'));var mixinValues=cssTextToMap(mixinAsProperties);var combinedProps=mixinValues;var mixinEntry=mapGet(propertyName);var oldProps=mixinEntry&&mixinEntry.properties;if(oldProps){combinedProps=Object.create(oldProps);combinedProps=Polymer.Base.mixin(combinedProps,mixinValues);}else{mapSet(propertyName,combinedProps);}
+var out=[];var p,v;var needToInvalidate=false;for(p in combinedProps){v=mixinValues[p];if(v===undefined){v='initial';}
+if(oldProps&&!(p in oldProps)){needToInvalidate=true;}
+out.push(propertyName+MIXIN_VAR_SEP+p+': '+v);}
+if(needToInvalidate){invalidateMixinEntry(mixinEntry);}
+if(mixinEntry){mixinEntry.properties=combinedProps;}
+if(valueProperty){prefix=matchText+';'+prefix;}
+return prefix+out.join('; ')+';';}
+function fixVars(matchText,varA,varB){return'var('+varA+','+'var('+varB+'))';}
+function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,'');var vars=[];var mixinEntry=mapGet(mixinName);if(!mixinEntry){mapSet(mixinName,{});mixinEntry=mapGet(mixinName);}
+if(mixinEntry){var currentProto=ApplyShim.__currentElementProto;if(currentProto){mixinEntry.dependants[currentProto.is]=currentProto;}
+var p,parts,f;for(p in mixinEntry.properties){f=fallbacks&&fallbacks[p];parts=[p,': var(',mixinName,MIXIN_VAR_SEP,p];if(f){parts.push(',',f);}
+parts.push(')');vars.push(parts.join(''));}}
+return vars.join('; ');}
+function consumeCssProperties(text){var m;while(m=MIXIN_MATCH.exec(text)){var matchText=m[0];var mixinName=m[1];var idx=m.index;var applyPos=idx+matchText.indexOf('@apply');var afterApplyPos=idx+matchText.length;var textBeforeApply=text.slice(0,applyPos);var textAfterApply=text.slice(afterApplyPos);var defaults=cssTextToMap(textBeforeApply);var replacement=atApplyToCssProperties(mixinName,defaults);text=[textBeforeApply,replacement,textAfterApply].join('');MIXIN_MATCH.lastIndex=idx+replacement.length;}
+return text;}
+var ApplyShim={_measureElement:null,_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles,elementProto){this.__currentElementProto=elementProto;styleUtil.forRulesInStyles(styles,this._boundFindDefinitions);styleUtil.forRulesInStyles(styles,this._boundFindApplications);if(elementProto){elementProto.__applyShimInvalid=false;}
+this.__currentElementProto=null;},_findDefinitions:function(rule){var cssText=rule.parsedCssText;cssText=cssText.replace(BAD_VAR,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);rule.cssText=cssText;if(rule.selector===':root'){rule.selector=':host > *';}},_findApplications:function(rule){rule.cssText=consumeCssProperties(rule.cssText);},transformRule:function(rule){this._findDefinitions(rule);this._findApplications(rule);},_getInitialValueForProperty:function(property){if(!this._measureElement){this._measureElement=document.createElement('meta');this._measureElement.style.all='initial';document.head.appendChild(this._measureElement);}
+return window.getComputedStyle(this._measureElement).getPropertyValue(property);}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);ApplyShim._boundFindDefinitions=ApplyShim._findDefinitions.bind(ApplyShim);ApplyShim._boundFindApplications=ApplyShim._findApplications.bind(ApplyShim);return ApplyShim;}();(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!=='shady'){styleTransformer.element(element,this.is,this._scopeCssViaAttr);}
+prepElement.call(this,element);},_prepStyles:function(){if(this._encapsulateStyle===undefined){this._encapsulateStyle=!nativeShadow;}
+if(!nativeShadow){this._scopeStyle=styleUtil.applyStylePlaceHolder(this.is);}
+this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is);},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild==='shadow'&&hasTargetedCssBuild){if(settings.preserveStyleIncludes){styleUtil.styleIncludesToTemplate(this._template);}
+return;}
+this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild){applyShim.transform(this._styles,this);}
+var cssText=settings.useNativeCSSProperties&&hasTargetedCssBuild?this._styles.length&&this._styles[0].textContent.trim():styleTransformer.elementStyles(this);this._prepStyleProperties();if(!this._needsStyleProperties()&&cssText){styleUtil.applyCss(cssText,this.is,nativeShadow?this._template.content:null,this._scopeStyle);}}else{this._styles=[];}},_collectStyles:function(){var styles=[];var cssText='',m$=this.styleModules;if(m$){for(var i=0,l=m$.length,m;i<l&&(m=m$[i]);i++){cssText+=styleUtil.cssFromModule(m);}}
+cssText+=styleUtil.cssFromModule(this.is);var p=this._template&&this._template.parentNode;if(this._template&&(!p||p.id.toLowerCase()!==this.is)){cssText+=styleUtil.cssFromElement(this._template);}
+if(cssText){var style=document.createElement('style');style.textContent=cssText;if(styleExtends.hasExtends(style.textContent)){cssText=styleExtends.transform(style);}
+styles.push(style);}
+return styles;},_elementAdd:function(node){if(this._encapsulateStyle){if(node.__styleScoped){node.__styleScoped=false;}else{styleTransformer.dom(node,this.is,this._scopeCssViaAttr);}}},_elementRemove:function(node){if(this._encapsulateStyle){styleTransformer.dom(node,this.is,this._scopeCssViaAttr,true);}},scopeSubtree:function(container,shouldObserve){if(nativeShadow){return;}
+var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute('class');node.setAttribute('class',self._scopeElementClass(node,className));var n$=node.querySelectorAll('*');for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute('class');n.setAttribute('class',self._scopeElementClass(n,className));}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++){if(m.addedNodes){for(var j=0;j<m.addedNodes.length;j++){scopify(m.addedNodes[j]);}}}});mo.observe(container,{childList:true,subtree:true});return mo;}}});}());Polymer.StyleProperties=function(){'use strict';var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var IS_IE=navigator.userAgent.match('Trident');var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope.extends);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=ruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE){scope.__notStyleScopeCacheable=true;}
+if(info.isHost){var hostContextOrFunction=info.selector.split(' ').some(function(s){return s.indexOf(scopeSelector)===0&&s.length!==scopeSelector.length;});scope.__notStyleScopeCacheable=scope.__notStyleScopeCacheable||hostContextOrFunction;}});self.collectPropertiesInCssText(rule.propertyInfo.cssText,props);},function onKeyframesRule(rule){keyframes.push(rule);});styles._keyframes=keyframes;var names=[];for(var i in props){names.push(i);}
+return names;},decorateRule:function(rule){if(rule.propertyInfo){return rule.propertyInfo;}
+var info={},properties={};var hasProperties=this.collectProperties(rule,properties);if(hasProperties){info.properties=properties;rule.rules=null;}
+info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info;},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,info.properties);return true;}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var value;var any;while(m=rx.exec(cssText)){value=(m[2]||m[3]).trim();if(value!=='inherit'){properties[m[1].trim()]=value;}
+any=true;}
+return any;}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText);},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,'').replace(this.rx.VAR_ASSIGN,'');},collectPropertiesInCssText:function(cssText,props){var m;while(m=this.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==':'){props[name]=true;}}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props);}},valueForProperty:function(property,props){if(property){if(property.indexOf(';')>=0){property=this.valueForProperties(property,props);}else{var self=this;var fn=function(prefix,value,fallback,suffix){var propertyValue=self.valueForProperty(props[value],props);if(!propertyValue||propertyValue==='initial'){propertyValue=self.valueForProperty(props[fallback]||fallback,props)||fallback;}else if(propertyValue==='apply-shim-inherit'){propertyValue='inherit';}
+return prefix+(propertyValue||'')+suffix;};property=styleUtil.processVariableAndFallback(property,fn);}}
+return property&&property.trim()||'';},valueForProperties:function(property,props){var parts=property.split(';');for(var i=0,p,m;i<parts.length;i++){if(p=parts[i]){this.rx.MIXIN_MATCH.lastIndex=0;m=this.rx.MIXIN_MATCH.exec(p);if(m){p=this.valueForProperty(props[m[1]],props);}else{var colon=p.indexOf(':');if(colon!==-1){var pp=p.substring(colon);pp=pp.trim();pp=this.valueForProperty(pp,props)||pp;p=p.substring(0,colon)+pp;}}
+parts[i]=p&&p.lastIndexOf(';')===p.length-1?p.slice(0,-1):p||'';}}
+return parts.join(';');},applyProperties:function(rule,props){var output='';if(!rule.propertyInfo){this.decorateRule(rule);}
+if(rule.propertyInfo.cssText){output=this.valueForProperties(rule.propertyInfo.cssText,props);}
+rule.cssText=output;},applyKeyframeTransforms:function(rule,keyframeTransforms){var input=rule.cssText;var output=rule.cssText;if(rule.hasAnimations==null){rule.hasAnimations=this.rx.ANIMATION_MATCH.test(input);}
+if(rule.hasAnimations){var transform;if(rule.keyframeNamesToTransform==null){rule.keyframeNamesToTransform=[];for(var keyframe in keyframeTransforms){transform=keyframeTransforms[keyframe];output=transform(input);if(input!==output){input=output;rule.keyframeNamesToTransform.push(keyframe);}}}else{for(var i=0;i<rule.keyframeNamesToTransform.length;++i){transform=keyframeTransforms[rule.keyframeNamesToTransform[i]];input=transform(input);}
+output=input;}}
+rule.cssText=output;},propertyDataFromStyles:function(styles,element){var props={},self=this;var o=[];styleUtil.forActiveRulesInStyles(styles,function(rule){if(!rule.propertyInfo){self.decorateRule(rule);}
+var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch){if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);addToBitMask(rule.index,o);}}});return{properties:props,key:o};},_rootSelector:/:root|:host\s*>\s*\*/,_checkRoot:function(hostScope,selector){return Boolean(selector.match(this._rootSelector))||hostScope==='html'&&selector.indexOf('html')>-1;},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo){self.decorateRule(rule);}
+if(!rule.propertyInfo.properties){return;}
+var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope.extends):'html';var parsedSelector=rule.parsedSelector;var isRoot=this._checkRoot(hostScope,parsedSelector);var isHost=!isRoot&&parsedSelector.indexOf(':host')===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild==='shady'){isRoot=parsedSelector===hostScope+' > *.'+hostScope||parsedSelector.indexOf('html')>-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0;}
+if(!isRoot&&!isHost){return;}
+var selectorToMatch=hostScope;if(isHost){if(settings.useNativeShadow&&!rule.transformedSelector){rule.transformedSelector=styleTransformer._transformRuleCss(rule,styleTransformer._transformComplexSelector,scope.is,hostScope);}
+selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
+if(isRoot&&hostScope==='html'){selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
+callback({selector:selectorToMatch,isHost:isHost,isRoot:isRoot});},hostAndRootPropertiesForScope:function(scope){var hostProps={},rootProps={},self=this;styleUtil.forActiveRulesInStyles(scope._styles,function(rule,style){self.whenHostOrRootRule(scope,rule,style,function(info){var element=scope._element||scope;if(matchesSelector.call(element,info.selector)){if(info.isHost){self.collectProperties(rule,hostProps);}else{self.collectProperties(rule,rootProps);}}});});return{rootProps:rootProps,hostProps:hostProps};},transformStyles:function(element,properties,scopeSelector){var self=this;var hostSelector=styleTransformer._calcHostScope(element.is,element.extends);var rxHostSelector=element.extends?'\\'+hostSelector.slice(0,-1)+'\\]':hostSelector;var hostRx=new RegExp(this.rx.HOST_PREFIX+rxHostSelector+this.rx.HOST_SUFFIX);var keyframeTransforms=this._elementKeyframeTransforms(element,scopeSelector);return styleTransformer.elementStyles(element,function(rule){self.applyProperties(rule,properties);if(!settings.useNativeShadow&&!Polymer.StyleUtil.isKeyframesSelector(rule)&&rule.cssText){self.applyKeyframeTransforms(rule,keyframeTransforms);self._scopeSelector(rule,hostRx,hostSelector,element._scopeCssViaAttr,scopeSelector);}});},_elementKeyframeTransforms:function(element,scopeSelector){var keyframesRules=element._styles._keyframes;var keyframeTransforms={};if(!settings.useNativeShadow&&keyframesRules){for(var i=0,keyframesRule=keyframesRules[i];i<keyframesRules.length;keyframesRule=keyframesRules[++i]){this._scopeKeyframes(keyframesRule,scopeSelector);keyframeTransforms[keyframesRule.keyframesName]=this._keyframesRuleTransformer(keyframesRule);}}
+return keyframeTransforms;},_keyframesRuleTransformer:function(keyframesRule){return function(cssText){return cssText.replace(keyframesRule.keyframesNameRx,keyframesRule.transformedKeyframesName);};},_scopeKeyframes:function(rule,scopeId){rule.keyframesNameRx=new RegExp(rule.keyframesName,'g');rule.transformedKeyframesName=rule.keyframesName+'-'+scopeId;rule.transformedSelector=rule.transformedSelector||rule.selector;rule.selector=rule.transformedSelector.replace(rule.keyframesName,rule.transformedKeyframesName);},_scopeSelector:function(rule,hostRx,hostSelector,viaAttr,scopeId){rule.transformedSelector=rule.transformedSelector||rule.selector;var selector=rule.transformedSelector;var scope=viaAttr?'['+styleTransformer.SCOPE_NAME+'~='+scopeId+']':'.'+scopeId;var parts=selector.split(',');for(var i=0,l=parts.length,p;i<l&&(p=parts[i]);i++){parts[i]=p.match(hostRx)?p.replace(hostSelector,scope):scope+' '+p;}
+rule.selector=parts.join(',');},applyElementScopeSelector:function(element,selector,old,viaAttr){var c=viaAttr?element.getAttribute(styleTransformer.SCOPE_NAME):element.getAttribute('class')||'';var v=old?c.replace(old,selector):(c?c+' ':'')+this.XSCOPE_NAME+' '+selector;if(c!==v){if(viaAttr){element.setAttribute(styleTransformer.SCOPE_NAME,v);}else{element.setAttribute('class',v);}}},applyElementStyle:function(element,properties,selector,style){var cssText=style?style.textContent||'':this.transformStyles(element,properties,selector);var s=element._customStyle;if(s&&!settings.useNativeShadow&&s!==style){s._useCount--;if(s._useCount<=0&&s.parentNode){s.parentNode.removeChild(s);}}
+if(settings.useNativeShadow){if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle;}else if(cssText){style=styleUtil.applyCss(cssText,selector,element.root,element._scopeStyle);}}else{if(!style){if(cssText){style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle);}}else if(!style.parentNode){if(IS_IE&&cssText.indexOf('@media')>-1){style.textContent=cssText;}
+styleUtil.applyStyle(style,null,element._scopeStyle);}}
+if(style){style._useCount=style._useCount||0;if(element._customStyle!=style){style._useCount++;}
+element._customStyle=style;}
+return style;},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];if(v||v===0){props[i]=v;}}},updateNativeStyleProperties:function(element,properties){var oldPropertyNames=element.__customStyleProperties;if(oldPropertyNames){for(var i=0;i<oldPropertyNames.length;i++){element.style.removeProperty(oldPropertyNames[i]);}}
+var propertyNames=[];for(var p in properties){if(properties[p]!==null){element.style.setProperty(p,properties[p]);propertyNames.push(p);}}
+element.__customStyleProperties=propertyNames;},rx:styleUtil.rx,XSCOPE_NAME:'x-scope'};function addToBitMask(n,bits){var o=parseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v;}}();(function(){Polymer.StyleCache=function(){this.cache={};};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX){s$.shift();}},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache){for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues)){return data;}}}},clear:function(){this.cache={};},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t==='object'&&t?this._objectsStrictlyEqual(t,s):t===s)){return false;}}
+if(Array.isArray(target)){return target.length===source.length;}
+return true;},_objectsStrictlyEqual:function(target,source){return this._objectsEqual(target,source)&&this._objectsEqual(source,target);}};}());Polymer.StyleDefaults=function(){var styleProperties=Polymer.StyleProperties;var StyleCache=Polymer.StyleCache;var nativeVariables=Polymer.Settings.useNativeCSSProperties;var api={_styles:[],_properties:null,customStyle:{},_styleCache:new StyleCache(),_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(style){this._styles.push(style);this._properties=null;},get _styleProperties(){if(!this._properties){styleProperties.decorateStyles(this._styles,this);this._styles._scopeStyleProperties=null;this._properties=styleProperties.hostAndRootPropertiesForScope(this).rootProps;styleProperties.mixinCustomStyle(this._properties,this.customStyle);styleProperties.reify(this._properties);}
+return this._properties;},hasStyleProperties:function(){return Boolean(this._properties);},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties;},updateStyles:function(properties){this._properties=null;if(properties){Polymer.Base.mixin(this.customStyle,properties);}
+this._styleCache.clear();for(var i=0,s;i<this._styles.length;i++){s=this._styles[i];s=s.__importElement||s;s._apply();}
+if(nativeVariables){styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle);}}};return api;}();(function(){'use strict';var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables){this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,this):null;}},customStyle:null,getComputedStyleValue:function(property){if(!nativeVariables&&!this._styleProperties){this._computeStyleProperties();}
+return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property);},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null;},_needsStyleProperties:function(){return Boolean(!nativeVariables&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length);},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var cssText=styleTransformer.elementStyles(this);if(nativeShadow){var templateStyle=this._template.content.querySelector('style');if(templateStyle){templateStyle.textContent=cssText;}}else{var shadyStyle=this._scopeStyle&&this._scopeStyle.nextSibling;if(shadyStyle){shadyStyle.textContent=cssText;}}}},_beforeAttached:function(){if((!this._scopeSelector||this.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties();}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host)){return root.host;}
+e=root.host;}
+return styleDefaults;},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleProperties){scope._computeStyleProperties();}
+if(!scope._styleCache){scope._styleCache=new Polymer.StyleCache();}
+var scopeData=propertyUtils.propertyDataFromStyles(scope._styles,this);var scopeCacheable=!this.__notStyleScopeCacheable;if(scopeCacheable){scopeData.key.customStyle=this.customStyle;info=scope._styleCache.retrieve(this.is,scopeData.key,this._styles);}
+var scopeCached=Boolean(info);if(scopeCached){this._styleProperties=info._styleProperties;}else{this._computeStyleProperties(scopeData.properties);}
+this._computeOwnStyleProperties();if(!scopeCached){info=styleCache.retrieve(this.is,this._ownStyleProperties,this._styles);}
+var globalCached=Boolean(info)&&!scopeCached;var style=this._applyStyleProperties(info);if(!scopeCached){style=style&&nativeShadow?style.cloneNode(true):style;info={style:style,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties};if(scopeCacheable){scopeData.key.customStyle={};this.mixin(scopeData.key.customStyle,this.customStyle);scope._styleCache.store(this.is,info,scopeData.key,this._styles);}
+if(!globalCached){styleCache.store(this.is,Object.create(info),this._ownStyleProperties,this._styles);}}},_computeStyleProperties:function(scopeProps){var scope=this._findStyleHost();if(!scope._styleProperties){scope._computeStyleProperties();}
+var props=Object.create(scope._styleProperties);var hostAndRootProps=propertyUtils.hostAndRootPropertiesForScope(this);this.mixin(props,hostAndRootProps.hostProps);scopeProps=scopeProps||propertyUtils.propertyDataFromStyles(scope._styles,this).properties;this.mixin(props,scopeProps);this.mixin(props,hostAndRootProps.rootProps);propertyUtils.mixinCustomStyle(props,this.customStyle);propertyUtils.reify(props);this._styleProperties=props;},_computeOwnStyleProperties:function(){var props={};for(var i=0,n;i<this._ownStylePropertyNames.length;i++){n=this._ownStylePropertyNames[i];props[n]=this._styleProperties[n];}
+this._ownStyleProperties=props;},_scopeCount:0,_applyStyleProperties:function(info){var oldScopeSelector=this._scopeSelector;this._scopeSelector=info?info._scopeSelector:this.is+'-'+this.__proto__._scopeCount++;var style=propertyUtils.applyElementStyle(this,this._styleProperties,this._scopeSelector,info&&info.style);if(!nativeShadow){propertyUtils.applyElementScopeSelector(this,this._scopeSelector,oldScopeSelector,this._scopeCssViaAttr);}
+return style;},serializeValueToAttribute:function(value,attribute,node){node=node||this;if(attribute==='class'&&!nativeShadow){var host=node===this?this.domHost||this.dataHost:this;if(host){value=host._scopeElementClass(node,value);}}
+node=this.shadyRoot&&this.shadyRoot._hasDistributed?Polymer.dom(node):node;serializeValueToAttribute.call(this,value,attribute,node);},_scopeElementClass:function(element,selector){if(!nativeShadow&&!this._scopeCssViaAttr){selector=(selector?selector+' ':'')+SCOPE_NAME+' '+this.is+(element._scopeSelector?' '+XSCOPE_NAME+' '+element._scopeSelector:'');}
+return selector;},updateStyles:function(properties){if(properties){this.mixin(this.customStyle,properties);}
+if(nativeVariables){propertyUtils.updateNativeStyleProperties(this,this.customStyle);}else{if(this.isAttached){if(this._needsStyleProperties()){this._updateStyleProperties();}else{this._styleProperties=null;}}else{this.__stylePropertiesInvalid=true;}
+if(this._styleCache){this._styleCache.clear();}
+this._updateRootStyles();}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot;});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.updateStyles){c.updateStyles();}}}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document);};var styleCache=new Polymer.StyleCache();Polymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME;}());Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();if(this.factoryImpl){this._prepConstructor();}
+this._prepStyles();},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady();},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._setupGestures();this._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._validateApplyShim();this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences();}
+this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady();},_marshalBehavior:function(b){if(b.listeners){this._listenListeners(b.listeners);}}});(function(){var propertyUtils=Polymer.StyleProperties;var styleUtil=Polymer.StyleUtil;var cssParse=Polymer.CssParse;var styleDefaults=Polymer.StyleDefaults;var styleTransformer=Polymer.StyleTransformer;var applyShim=Polymer.ApplyShim;var debounce=Polymer.Debounce;var settings=Polymer.Settings;var updateDebouncer;Polymer({is:'custom-style',extends:'style',_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=styleUtil.getCssBuildType(this);if(this.__appliedElement!==this){this.__appliedElement.__cssBuild=this.__cssBuild;}
+this._tryApply();},attached:function(){this._tryApply();},_tryApply:function(){if(!this._appliesToDocument){if(this.parentNode&&this.parentNode.localName!=='dom-module'){this._appliesToDocument=true;var e=this.__appliedElement;if(!settings.useNativeCSSProperties){this.__needsUpdateStyles=styleDefaults.hasStyleProperties();styleDefaults.addStyle(e);}
+if(e.textContent||this.include){this._apply(true);}else{var self=this;var observer=new MutationObserver(function(){observer.disconnect();self._apply(true);});observer.observe(e,{childList:true});}}}},_updateStyles:function(){Polymer.updateStyles();},_apply:function(initialApply){var e=this.__appliedElement;if(this.include){e.textContent=styleUtil.cssFromModules(this.include,true)+e.textContent;}
+if(!e.textContent){return;}
+var buildType=this.__cssBuild;var targetedBuild=styleUtil.isTargetedBuild(buildType);if(settings.useNativeCSSProperties&&targetedBuild){return;}
+var styleRules=styleUtil.rulesForStyle(e);if(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule);});if(settings.useNativeCSSProperties&&!buildType){applyShim.transform([e]);}}
+if(settings.useNativeCSSProperties){e.textContent=styleUtil.toCssText(styleRules);}else{var self=this;var fn=function fn(){self._flushCustomProperties();};if(initialApply){Polymer.RenderStatus.whenReady(fn);}else{fn();}}},_flushCustomProperties:function(){if(this.__needsUpdateStyles){this.__needsUpdateStyles=false;updateDebouncer=debounce(updateDebouncer,this._updateStyles);}else{this._applyCustomProperties();}},_applyCustomProperties:function(){var element=this.__appliedElement;this._computeStyleProperties();var props=this._styleProperties;var rules=styleUtil.rulesForStyle(element);if(!rules){return;}
+element.textContent=styleUtil.toCssText(rules,function(rule){var css=rule.cssText=rule.parsedCssText;if(rule.propertyInfo&&rule.propertyInfo.cssText){css=cssParse.removeCustomPropAssignment(css);rule.cssText=propertyUtils.valueForProperties(css,props);}});}});}());Polymer.Templatizer={properties:{__hideTemplateChildren__:{observer:'_showHideChildren'}},_instanceProps:Polymer.nob,_parentPropPrefix:'_parent_',templatize:function(template){this._templatized=template;if(!template._content){template._content=template.content;}
+if(template._content._ctor){this.ctor=template._content._ctor;this._prepParentProperties(this.ctor.prototype,template);return;}
+var archetype=Object.create(Polymer.Base);this._customPrepAnnotations(archetype,template);this._prepParentProperties(archetype,template);archetype._prepEffects();this._customPrepEffects(archetype);archetype._prepBehaviors();archetype._prepPropertyInfo();archetype._prepBindings();archetype._notifyPathUp=this._notifyPathUpImpl;archetype._scopeElementClass=this._scopeElementClassImpl;archetype.listen=this._listenImpl;archetype._showHideChildren=this._showHideChildrenImpl;archetype.__setPropertyOrig=this.__setProperty;archetype.__setProperty=this.__setPropertyImpl;var _constructor=this._constructorImpl;var ctor=function TemplateInstance(model,host){_constructor.call(this,model,host);};ctor.prototype=archetype;archetype.constructor=ctor;template._content._ctor=ctor;this.ctor=ctor;},_getRootDataHost:function(){return this.dataHost&&this.dataHost._rootDataHost||this.dataHost;},_showHideChildrenImpl:function(hide){var c=this._children;for(var i=0;i<c.length;i++){var n=c[i];if(Boolean(hide)!=Boolean(n.__hideTemplateChildren__)){if(n.nodeType===Node.TEXT_NODE){if(hide){n.__polymerTextContent__=n.textContent;n.textContent='';}else{n.textContent=n.__polymerTextContent__;}}else if(n.style){if(hide){n.__polymerDisplay__=n.style.display;n.style.display='none';}else{n.style.display=n.__polymerDisplay__;}}}
+n.__hideTemplateChildren__=hide;}},__setPropertyImpl:function(property,value,fromAbove,node){if(node&&node.__hideTemplateChildren__&&property=='textContent'){property='__polymerTextContent__';}
+this.__setPropertyOrig(property,value,fromAbove,node);},_debounceTemplate:function(fn){Polymer.dom.addDebouncer(this.debounce('_debounceTemplate',fn));},_flushTemplates:function(){Polymer.dom.flush();},_customPrepEffects:function(archetype){var parentProps=archetype._parentProps;for(var prop in parentProps){archetype._addPropertyEffect(prop,'function',this._createHostPropEffector(prop));}
+for(prop in this._instanceProps){archetype._addPropertyEffect(prop,'function',this._createInstancePropEffector(prop));}},_customPrepAnnotations:function(archetype,template){archetype._template=template;var c=template._content;if(!c._notes){var rootDataHost=archetype._rootDataHost;if(rootDataHost){Polymer.Annotations.prepElement=function(){rootDataHost._prepElement();};}
+c._notes=Polymer.Annotations.parseAnnotations(template);Polymer.Annotations.prepElement=null;this._processAnnotations(c._notes);}
+archetype._notes=c._notes;archetype._parentProps=c._parentProps;},_prepParentProperties:function(archetype,template){var parentProps=this._parentProps=archetype._parentProps;if(this._forwardParentProp&&parentProps){var proto=archetype._parentPropProto;var prop;if(!proto){for(prop in this._instanceProps){delete parentProps[prop];}
+proto=archetype._parentPropProto=Object.create(null);if(template!=this){Polymer.Bind.prepareModel(proto);Polymer.Base.prepareModelNotifyPath(proto);}
+for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:'function',effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:'notify',fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+'-changed'}}];proto._propertyEffects=proto._propertyEffects||{};proto._propertyEffects[parentProp]=effects;Polymer.Bind._createAccessors(proto,parentProp,effects);}}
+var self=this;if(template!=this){Polymer.Bind.prepareInstance(template);template._forwardParentProp=function(source,value){self._forwardParentProp(source,value);};}
+this._extendTemplate(template,proto);template._pathEffector=function(path,value,fromAbove){return self._pathEffectorImpl(path,value,fromAbove);};}},_createForwardPropEffector:function(prop){return function(source,value){this._forwardParentProp(prop,value);};},_createHostPropEffector:function(prop){var prefix=this._parentPropPrefix;return function(source,value){this.dataHost._templatized[prefix+prop]=value;};},_createInstancePropEffector:function(prop){return function(source,value,old,fromAbove){if(!fromAbove){this.dataHost._forwardInstanceProp(this,prop,value);}};},_extendTemplate:function(template,proto){var n$=Object.getOwnPropertyNames(proto);if(proto._propertySetter){template._propertySetter=proto._propertySetter;}
+for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];if(val&&n=='_propertyEffects'){var pe=Polymer.Base.mixin({},val);template._propertyEffects=Polymer.Base.mixin(pe,proto._propertyEffects);}else{var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined){template._propertySetter(n,val);}}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var root=Polymer.Path.root(path);dataHost._forwardInstancePath.call(dataHost,this,path,value);if(root in dataHost._parentProps){dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value);}},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath){if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=Polymer.Path.root(subPath);if(model in this._parentProps){this._forwardParentPath(subPath,value);}}}
+Polymer.Base._pathEffector.call(this._templatized,path,value,fromAbove);},_constructorImpl:function(model,host){this._rootDataHost=host._getRootDataHost();this._setupConfigure(model);this._registerHost(host);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=true;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();this._marshalAnnotatedListeners();var children=[];for(var n=this.root.firstChild;n;n=n.nextSibling){children.push(n);n._templateInstance=this;}
+this._children=children;if(host.__hideTemplateChildren__){this._showHideChildren(true);}
+this._tryReady();},_listenImpl:function(node,eventName,methodName){var model=this;var host=this._rootDataHost;var handler=host._createEventHandler(node,eventName,methodName);var decorated=function(e){e.model=model;handler(e);};host._listen(node,eventName,decorated);},_scopeElementClassImpl:function(node,value){var host=this._rootDataHost;if(host){return host._scopeElementClass(node,value);}
+return value;},stamp:function(model){model=model||{};if(this._parentProps){var templatized=this._templatized;for(var prop in this._parentProps){if(model[prop]===undefined){model[prop]=templatized[this._parentPropPrefix+prop];}}}
+return new this.ctor(model,this);},modelForElement:function(el){var model;while(el){if(model=el._templateInstance){if(model.dataHost!=this){el=model.dataHost;}else{return model;}}else{el=el.parentNode;}}}};Polymer({is:'dom-template',extends:'template',_template:null,behaviors:[Polymer.Templatizer],ready:function(){this.templatize(this);}});Polymer._collections=new WeakMap();Polymer.Collection=function(userArray){Polymer._collections.set(userArray,this);this.userArray=userArray;this.store=userArray.slice();this.initMap();};Polymer.Collection.prototype={constructor:Polymer.Collection,initMap:function(){var omap=this.omap=new WeakMap();var pmap=this.pmap={};var s=this.store;for(var i=0;i<s.length;i++){var item=s[i];if(item&&typeof item=='object'){omap.set(item,i);}else{pmap[item]=i;}}},add:function(item){var key=this.store.push(item)-1;if(item&&typeof item=='object'){this.omap.set(item,key);}else{this.pmap[item]=key;}
+return'#'+key;},removeKey:function(key){if(key=this._parseKey(key)){this._removeFromMap(this.store[key]);delete this.store[key];}},_removeFromMap:function(item){if(item&&typeof item=='object'){this.omap.delete(item);}else{delete this.pmap[item];}},remove:function(item){var key=this.getKey(item);this.removeKey(key);return key;},getKey:function(item){var key;if(item&&typeof item=='object'){key=this.omap.get(item);}else{key=this.pmap[item];}
+if(key!=undefined){return'#'+key;}},getKeys:function(){return Object.keys(this.store).map(function(key){return'#'+key;});},_parseKey:function(key){if(key&&key[0]=='#'){return key.slice(1);}},setItem:function(key,item){if(key=this._parseKey(key)){var old=this.store[key];if(old){this._removeFromMap(old);}
+if(item&&typeof item=='object'){this.omap.set(item,key);}else{this.pmap[item]=key;}
+this.store[key]=item;}},getItem:function(key){if(key=this._parseKey(key)){return this.store[key];}},getItems:function(){var items=[],store=this.store;for(var key in store){items.push(store[key]);}
+return items;},_applySplices:function(splices){var keyMap={},key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){s.addedKeys=[];for(var j=0;j<s.removed.length;j++){key=this.getKey(s.removed[j]);keyMap[key]=keyMap[key]?null:-1;}
+for(j=0;j<s.addedCount;j++){var item=this.userArray[s.index+j];key=this.getKey(item);key=key===undefined?this.add(item):key;keyMap[key]=keyMap[key]?null:1;s.addedKeys.push(key);}}
+var removed=[];var added=[];for(key in keyMap){if(keyMap[key]<0){this.removeKey(key);removed.push(key);}
+if(keyMap[key]>0){added.push(key);}}
+return[{removed:removed,added:added}];}};Polymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray);};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null;};Polymer({is:'dom-repeat',extends:'template',_template:null,properties:{items:{type:Array},as:{type:String,value:'item'},indexAs:{type:String,value:'index'},sort:{type:Function,observer:'_sortChanged'},filter:{type:Function,observer:'_filterChanged'},observe:{type:String,observer:'_observeChanged'},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:true},initialCount:{type:Number,observer:'_initializeChunking'},targetFramerate:{type:Number,value:20},notifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:'_computeFrameTime(targetFramerate)'}},behaviors:[Polymer.Templatizer],observers:['_itemsChanged(items.*)'],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk();};},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++){this._detachInstance(i);}},attached:function(){if(this.__isDetached){this.__isDetached=false;var parent=Polymer.dom(Polymer.dom(this).parentNode);for(var i=0;i<this._instances.length;i++){this._attachInstance(i,parent);}}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor){this.templatize(this);}},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort=='function'?sort:function(){return dataHost[sort].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter=='function'?filter:function(){return dataHost[filter].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_computeFrameTime:function(rate){return Math.ceil(1000/rate);},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now();}},_tryRenderChunk:function(){if(this.items&&this._limit<this.items.length){this.debounce('renderChunk',this._requestRenderChunk);}},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk);},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render);},_observeChanged:function(){this._observePaths=this.observe&&this.observe.replace('.*','.').split(' ');},_itemsChanged:function(change){if(change.path=='items'){if(Array.isArray(this.items)){this.collection=Polymer.Collection.get(this.items);}else if(!this.items){this.collection=null;}else{this._error(this._logf('dom-repeat','expected array for `items`,'+' found',this.items));}
+this._keySplices=[];this._indexSplices=[];this._needFullRefresh=true;this._initializeChunking();this._debounceTemplate(this._render);}else if(change.path=='items.splices'){this._keySplices=this._keySplices.concat(change.value.keySplices);this._indexSplices=this._indexSplices.concat(change.value.indexSplices);this._debounceTemplate(this._render);}else{var subpath=change.path.slice(6);this._forwardItemPath(subpath,change.value);this._checkObservedPaths(subpath);}},_checkObservedPaths:function(path){if(this._observePaths){path=path.substring(path.indexOf('.')+1);var paths=this._observePaths;for(var i=0;i<paths.length;i++){if(path.indexOf(paths[i])===0){this._needFullRefresh=true;if(this.delay){this.debounce('render',this._render,this.delay);}else{this._debounceTemplate(this._render);}
+return;}}}},render:function(){this._needFullRefresh=true;this._debounceTemplate(this._render);this._flushTemplates();},_render:function(){if(this._needFullRefresh){this._applyFullRefresh();this._needFullRefresh=false;}else if(this._keySplices.length){if(this._sortFn){this._applySplicesUserSort(this._keySplices);}else{if(this._filterFn){this._applyFullRefresh();}else{this._applySplicesArrayOrder(this._indexSplices);}}}else{}
+this._keySplices=[];this._indexSplices=[];var keyToIdx=this._keyToInstIdx={};for(var i=this._instances.length-1;i>=0;i--){var inst=this._instances[i];if(inst.isPlaceholder&&i<this._limit){inst=this._insertInstance(i,inst.__key__);}else if(!inst.isPlaceholder&&i>=this._limit){inst=this._downgradeInstance(i,inst.__key__);}
+keyToIdx[inst.__key__]=i;if(!inst.isPlaceholder){inst.__setProperty(this.indexAs,i,true);}}
+this._pool.length=0;this._setRenderedItemCount(this._instances.length);if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._tryRenderChunk();},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn){keys=c?c.getKeys():[];}else{keys=[];var items=this.items;if(items){for(var i=0;i<items.length;i++){keys.push(c.getKey(items[i]));}}}
+var self=this;if(this._filterFn){keys=keys.filter(function(a){return self._filterFn(c.getItem(a));});}
+if(this._sortFn){keys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b));});}
+for(i=0;i<keys.length;i++){var key=keys[i];var inst=this._instances[i];if(inst){inst.__key__=key;if(!inst.isPlaceholder&&i<this._limit){inst.__setProperty(this.as,c.getItem(key),true);}}else if(i<this._limit){this._insertInstance(i,key);}else{this._insertPlaceholder(i,key);}}
+for(var j=this._instances.length-1;j>=i;j--){this._detachAndRemoveInstance(j);}},_numericSort:function(a,b){return a-b;},_applySplicesUserSort:function(splices){var c=this.collection;var keyMap={};var key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){key=s.removed[j];keyMap[key]=keyMap[key]?null:-1;}
+for(j=0;j<s.added.length;j++){key=s.added[j];keyMap[key]=keyMap[key]?null:1;}}
+var removedIdxs=[];var addedKeys=[];for(key in keyMap){if(keyMap[key]===-1){removedIdxs.push(this._keyToInstIdx[key]);}
+if(keyMap[key]===1){addedKeys.push(key);}}
+if(removedIdxs.length){removedIdxs.sort(this._numericSort);for(i=removedIdxs.length-1;i>=0;i--){var idx=removedIdxs[i];if(idx!==undefined){this._detachAndRemoveInstance(idx);}}}
+var self=this;if(addedKeys.length){if(this._filterFn){addedKeys=addedKeys.filter(function(a){return self._filterFn(c.getItem(a));});}
+addedKeys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b));});var start=0;for(i=0;i<addedKeys.length;i++){start=this._insertRowUserSort(start,addedKeys[i]);}}},_insertRowUserSort:function(start,key){var c=this.collection;var item=c.getItem(key);var end=this._instances.length-1;var idx=-1;while(start<=end){var mid=start+end>>1;var midKey=this._instances[mid].__key__;var cmp=this._sortFn(c.getItem(midKey),item);if(cmp<0){start=mid+1;}else if(cmp>0){end=mid-1;}else{idx=mid;break;}}
+if(idx<0){idx=end+1;}
+this._insertPlaceholder(idx,key);return idx;},_applySplicesArrayOrder:function(splices){for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){this._detachAndRemoveInstance(s.index);}
+for(j=0;j<s.addedKeys.length;j++){this._insertPlaceholder(s.index+j,s.addedKeys[j]);}}},_detachInstance:function(idx){var inst=this._instances[idx];if(!inst.isPlaceholder){for(var i=0;i<inst._children.length;i++){var el=inst._children[i];Polymer.dom(inst.root).appendChild(el);}
+return inst;}},_attachInstance:function(idx,parent){var inst=this._instances[idx];if(!inst.isPlaceholder){parent.insertBefore(inst.root,this);}},_detachAndRemoveInstance:function(idx){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
+this._instances.splice(idx,1);},_insertPlaceholder:function(idx,key){this._instances.splice(idx,0,{isPlaceholder:true,__key__:key});},_stampInstance:function(idx,key){var model={__key__:key};model[this.as]=this.collection.getItem(key);model[this.indexAs]=idx;return this.stamp(model);},_insertInstance:function(idx,key){var inst=this._pool.pop();if(inst){inst.__setProperty(this.as,this.collection.getItem(key),true);inst.__setProperty('__key__',key,true);}else{inst=this._stampInstance(idx,key);}
+var beforeRow=this._instances[idx+1];var beforeNode=beforeRow&&!beforeRow.isPlaceholder?beforeRow._children[0]:this;var parentNode=Polymer.dom(this).parentNode;Polymer.dom(parentNode).insertBefore(inst.root,beforeNode);this._instances[idx]=inst;return inst;},_downgradeInstance:function(idx,key){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
+inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst;},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++){if(!this._instances[i].isPlaceholder)
+this._instances[i]._showHideChildren(hidden);}},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn){idx=this.items.indexOf(this.collection.getItem(inst.__key__));}else{idx=inst[this.indexAs];}
+this.set('items.'+idx,value);}},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+'.')===0){this._notifyPath('items.'+inst.__key__+'.'+path.slice(this.as.length+1),value);}},_forwardParentProp:function(prop,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst.__setProperty(prop,value,true);}}},_forwardParentPath:function(path,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst._notifyPath(path,value,true);}}},_forwardItemPath:function(path,value){if(this._keyToInstIdx){var dot=path.indexOf('.');var key=path.substring(0,dot<0?path.length:dot);var idx=this._keyToInstIdx[key];var inst=this._instances[idx];if(inst&&!inst.isPlaceholder){if(dot>=0){path=this.as+'.'+path.substring(dot+1);inst._notifyPath(path,value,true);}else{inst.__setProperty(this.as,value,true);}}}},itemForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.as];},keyForElement:function(el){var instance=this.modelForElement(el);return instance&&instance.__key__;},indexForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.indexAs];}});Polymer({is:'array-selector',_template:null,properties:{items:{type:Array,observer:'clearSelection'},multi:{type:Boolean,value:false,observer:'clearSelection'},selected:{type:Object,notify:true},selectedItem:{type:Object,notify:true},toggle:{type:Boolean,value:false}},clearSelection:function(){if(Array.isArray(this.selected)){for(var i=0;i<this.selected.length;i++){this.unlinkPaths('selected.'+i);}}else{this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}
+if(this.multi){if(!this.selected||this.selected.length){this.selected=[];this._selectedColl=Polymer.Collection.get(this.selected);}}else{this.selected=null;this._selectedColl=null;}
+this.selectedItem=null;},isSelected:function(item){if(this.multi){return this._selectedColl.getKey(item)!==undefined;}else{return this.selected==item;}},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete('selected',item);this.unlinkPaths('selected.'+skey);}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi){if(this.isSelected(item)){if(this.toggle){this.deselect(item);}}else{this.push('selected',item);var skey=this._selectedColl.getKey(item);this.linkPaths('selected.'+skey,'items.'+key);}}else{if(this.toggle&&item==this.selected){this.deselect();}else{this.selected=item;this.selectedItem=item;this.linkPaths('selected','items.'+key);this.linkPaths('selectedItem','items.'+key);}}}});Polymer({is:'dom-if',extends:'template',_template:null,properties:{'if':{type:Boolean,value:false,observer:'_queueRender'},restamp:{type:Boolean,value:false,observer:'_queueRender'},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render);},detached:function(){if(!this.parentNode||this.parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(this.parentNode instanceof ShadowRoot))){this._teardownInstance();}},attached:function(){if(this.if&&this.ctor){this.async(this._ensureInstance);}},render:function(){this._flushTemplates();},_render:function(){if(this.if){if(!this.ctor){this.templatize(this);}
+this._ensureInstance();this._showHideChildren();}else if(this.restamp){this._teardownInstance();}
+if(!this.restamp&&this._instance){this._showHideChildren();}
+if(this.if!=this._lastIf){if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._lastIf=this.if;}},_ensureInstance:function(){var parentNode=Polymer.dom(this).parentNode;if(parentNode){var parent=Polymer.dom(parentNode);if(!this._instance){this._instance=this.stamp();var root=this._instance.root;parent.insertBefore(root,this);}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(this).previousSibling;if(lastChild!==c$[c$.length-1]){for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.insertBefore(n,this);}}}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=Polymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.removeChild(n);}}
+this._instance=null;}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this.if;if(this._instance){this._instance._showHideChildren(hidden);}},_forwardParentProp:function(prop,value){if(this._instance){this._instance.__setProperty(prop,value,true);}},_forwardParentPath:function(path,value){if(this._instance){this._instance._notifyPath(path,value,true);}}});Polymer({is:'dom-bind',properties:{notifyDomChange:{type:Boolean}},extends:'template',_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState=='loading'){document.addEventListener('DOMContentLoaded',function(){self._markImportsReady();});}else{self._markImportsReady();}});},_ensureReady:function(){if(!this._readied){this._readySelf();}},_markImportsReady:function(){this._importsReady=true;this._ensureReady();},_registerFeatures:function(){this._prepConstructor();},_insertChildren:function(){var parentDom=Polymer.dom(Polymer.dom(this).parentNode);parentDom.insertBefore(this.root,this);},_removeChildren:function(){if(this._children){for(var i=0;i<this._children.length;i++){this.root.appendChild(this._children[i]);}}},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost){return this.dataHost._scopeElementClass(element,selector);}else{return selector;}},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};for(var prop in this._propertyEffects){config[prop]=this[prop];}
+var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config);};},attached:function(){if(this._importsReady){this.render();}},detached:function(){this._removeChildren();},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);this._children=Polymer.TreeApi.arrayCopyChildNodes(this.root);}
+this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}}});'use strict';if(!Polymer.Settings.useNativeShadow){tr.showPanic('Polymer error','base only works in shadow mode');}'use strict';const global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+return cur;}
+function isExported(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+return true;}
+function isDefined(name){const parts=name.split('.');let curObject=global;for(let i=0;i<parts.length;i++){const partName=parts[i];const nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
+return true;}
+let panicElement=undefined;const rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;const panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
+if(panicDetails instanceof Error){panicDetails=panicDetails.stack;}
+showPanicElementIfNeeded();const panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+function hasPanic(){return rawPanicMessages.length!==0;}
+function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
+function exportTo(namespace,fn){const obj=exportPath(namespace);const exports=fn();for(const propertyName in exports){const propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
+function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
+tr.isHeadless=tr.isVinn||tr.isNode;}
+return{initialize,exportTo,isExported,isDefined,showPanic,hasPanic,getPanicText,};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+EventTarget.decorate=function(target){for(const k in EventTarget.prototype){if(k==='decorate')continue;const v=EventTarget.prototype[k];if(typeof v!=='function')continue;target[k]=v;}};EventTarget.prototype={addEventListener(type,handler){if(!this.listeners_){this.listeners_=Object.create(null);}
+if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{const handlers=this.listeners_[type];if(handlers.indexOf(handler)<0){handlers.push(handler);}}},removeEventListener(type,handler){if(!this.listeners_)return;if(type in this.listeners_){const handlers=this.listeners_[type];const index=handlers.indexOf(handler);if(index>=0){if(handlers.length===1){delete this.listeners_[type];}else{handlers.splice(index,1);}}}},dispatchEvent(event){if(!this.listeners_)return true;event.__defineGetter__('target',()=>this);const realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};const type=event.type;let prevented=0;if(type in this.listeners_){const handlers=this.listeners_[type].concat();for(let i=0,handler;handler=handlers[i];i++){if(handler.handleEvent){prevented|=handler.handleEvent.call(handler,event)===false;}else{prevented|=handler.call(this,event)===false;}}}
+return!prevented&&event.rawReturnValue;},async dispatchAsync(event){if(!this.listeners_)return true;const listeners=this.listeners_[event.type];if(listeners===undefined)return;await Promise.all(listeners.slice().map(listener=>{if(listener.handleEvent){return listener.handleEvent.call(listener,event);}
+return listener.call(this,event);}));},hasEventListener(type){return(this.listeners_!==undefined&&this.listeners_[type]!==undefined);}};return{EventTarget,};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;}
+const BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';const TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';const ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined){throw new Error('Mode is required');}
+if(!ALL_MODES[mode]){throw new Error('Not a mode.');}
+this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
+ExtensionRegistryOptions.prototype={freeze(){if(this.frozen_){throw new Error('Frozen');}
+this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_){throw new Error('Frozen');}
+this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_){throw new Error('Frozen');}
+this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
+return this.defaultTypeInfo_;},validateConstructor(constructor){if(!this.mandatoryBaseClass)return;let curProto=constructor.prototype.__proto__;let ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
+curProto=curProto.__proto__;}
+if(!ok){throw new Error(constructor+'must be subclass of '+registry);}}};return{BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions,RegisteredTypeInfo,};});'use strict';tr.exportTo('tr.b',function(){let Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;}
+HeadlessEvent.prototype={preventDefault(){this.defaultPrevented=true;},stopPropagation(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){const e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;}
+TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable,opt_fields){const e=new tr.b.Event(type,opt_bubbles,opt_cancelable);Object.assign(e,opt_fields);return target.dispatchEvent(e);}
+async function dispatchSimpleEventAsync(target,type,opt_fields){const e=new tr.b.Event(type,false,false);Object.assign(e,opt_fields);return await target.dispatchAsync(e);}
+return{Event,dispatchSimpleEvent,dispatchSimpleEventAsync,};});'use strict';tr.exportTo('tr.b',function(){const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined){throw new Error('Handler already registered for '+constructor);}
+extensionRegistryOptions.validateConstructor(constructor);const metadata={};for(const k in extensionRegistryOptions.defaultMetadata){metadata[k]=extensionRegistryOptions.defaultMetadata[k];}
+if(opt_metadata){for(const k in opt_metadata){metadata[k]=opt_metadata[k];}}
+const typeInfo=new RegisteredTypeInfo(constructor,metadata);let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){return i;}}
+return undefined;};registry.unregister=function(constructor){const foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined){throw new Error(constructor+' not registered');}
+registry.registeredTypeInfos_.splice(foundIndex,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){const foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined){return this.registeredTypeInfos_[foundIndex];}
+return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(let i=0;i<registry.registeredTypeInfos_.length;++i){const typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo)){return typeInfo;}}
+return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string'){throw new Error('Name is not a string.');}
+const typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)return typeInfo;return undefined;};}
+return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){const categoryPartsFor={};function getCategoryParts(category){let parts=categoryPartsFor[category];if(parts!==undefined)return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
+return{getCategoryParts,};});'use strict';tr.exportTo('tr.b',function(){const getCategoryParts=tr.b.getCategoryParts;const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_=new Map();registry.typeNameToTypeInfoMap_=new Map();registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);const typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName){typeInfo.typeNames.push(metadata.typeName);}
+if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
+if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
+if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0){throw new Error('typeName or typeNames must be provided');}
+typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_.has(typeName)){throw new Error('typeName '+typeName+' already registered');}});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_.has(categoryPart)){throw new Error('categoryPart '+categoryPart+' already registered');}});let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.set(typeName,typeInfo);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.set(categoryPart,typeInfo);});registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_=new Map();registry.categoryPartToTypeInfoMap_=new Map();const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){const state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){let typeInfoIndex=-1;for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){typeInfoIndex=i;break;}}
+if(typeInfoIndex===-1){throw new Error(constructor+' not registered');}
+const typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.delete(typeName);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.delete(categoryPart);});const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){const categoryParts=getCategoryParts(category);for(let i=0;i<categoryParts.length;i++){const categoryPart=categoryParts[i];const typeInfo=registry.categoryPartToTypeInfoMap_.get(categoryPart);if(typeInfo!==undefined)return typeInfo;}}
+const typeInfo=registry.typeNameToTypeInfoMap_.get(typeName);if(typeInfo!==undefined)return typeInfo;return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){const typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)return typeInfo.constructor;return undefined;};}
+return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){const URL_REGEX=/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)return value;if(typeof value==='string')return value.substring();if(typeof value==='boolean')return value;if(typeof value==='number')return value;throw new Error('Unrecognized: '+typeof value);}
+const object=value;if(object instanceof Array){const res=new Array(object.length);for(let i=0;i<object.length;i++){res[i]=deepCopy(object[i]);}
+return res;}
+if(object.__proto__!==Object.prototype){throw new Error('Can only clone simple types');}
+const res={};for(const key in object){res[key]=deepCopy(object[key]);}
+return res;}
+function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
+if(typeof(e)==='string'){return{typeName:'StringError',message:e,stack:[e]};}
+let typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+const msg=e.message?e.message:'Unknown';return{typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+function stackTraceAsString(){return new Error().stack+'';}
+function stackTrace(){let stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,fromDict){const parts=path.split('.');let cur=fromDict;for(let part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+return undefined;}
+function formatDate(date){return date.toISOString().replace('T',' ').slice(0,19);}
+function numberToJson(n){if(isNaN(n))return'NaN';if(n===Infinity)return'Infinity';if(n===-Infinity)return'-Infinity';return n;}
+function numberFromJson(n){if(n==='NaN'||n===null)return NaN;if(n==='Infinity')return Infinity;if(n==='-Infinity')return-Infinity;return n;}
+function runLengthEncoding(ary){const encodedArray=[];for(const element of ary){if(encodedArray.length===0||encodedArray[encodedArray.length-1].value!==element){encodedArray.push({value:element,count:1,});}else{encodedArray[encodedArray.length-1].count+=1;}}
+return encodedArray;}
+function isUrl(s){return typeof(s)==='string'&&s.match(URL_REGEX)!==null;}
+function getOnlyElement(iterable){const iterator=iterable[Symbol.iterator]();const firstIteration=iterator.next();if(firstIteration.done){throw new Error('getOnlyElement was passed an empty iterable.');}
+const secondIteration=iterator.next();if(!secondIteration.done){throw new Error('getOnlyElement was passed an iterable with multiple elements.');}
+return firstIteration.value;}
+function getFirstElement(iterable){const iterator=iterable[Symbol.iterator]();const result=iterator.next();if(result.done){throw new Error('getFirstElement was passed an empty iterable.');}
+return result.value;}
+function compareArrays(x,y,elementCmp){const minLength=Math.min(x.length,y.length);let i;for(i=0;i<minLength;i++){const tmp=elementCmp(x[i],y[i]);if(tmp)return tmp;}
+if(x.length===y.length)return 0;if(x[i]===undefined)return-1;return 1;}
+function groupIntoMap(ary,callback,opt_this,opt_arrayConstructor){const arrayConstructor=opt_arrayConstructor||Array;const results=new Map();for(const element of ary){const key=callback.call(opt_this,element);let items=results.get(key);if(items===undefined){items=new arrayConstructor();results.set(key,items);}
+items.push(element);}
+return results;}
+function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;let nextPosition=0;for(let i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))continue;if(nextPosition<i){array[nextPosition]=array[i];}
+nextPosition++;}
+if(nextPosition<array.length){array.length=nextPosition;}}
+function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;const result={};for(let i=0;i<array.length;i++){const item=array[i];if(item===undefined)continue;const dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)continue;for(const key in dict){let valueList=result[key];if(valueList===undefined){result[key]=valueList=new Array(array.length);}
+valueList[i]=dict[key];}}
+return result;}
+function setsEqual(a,b){if(!(a instanceof Set)||!(b instanceof Set))return false;if(a.size!==b.size)return false;for(const x of a){if(!b.has(x))return false;}
+return true;}
+function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length===0)return 1;let low=0;let high=ary.length-1;let i;let comparison;let hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
+return hitPos!==-1?hitPos:low;}
+function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){let lo=loVal||0;let hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){const mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0){lo=mid+1;}else{hi=mid;}}
+return hi;}
+function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){const first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first===0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}
+return-1;}
+if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}
+if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}
+return ary.length;}
+if(first===ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}
+return ary.length;}
+return ary.length;}
+function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){const i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}
+return-1;}
+if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
+if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}
+return ary.length;}
+if(i===ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
+return ary.length;}
+return ary.length;}
+function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length===0)return;if(loVal>hiVal)return;let i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i===-1){return;}
+if(i>0){const hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
+if(i===ary.length){return;}
+for(let n=ary.length;i<n;i++){const lo=mapLoFn(ary[i]);if(lo>=hiVal)break;cb(ary[i],i);}}
+function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)return null;let aftIdx=findLowIndexInSortedArray(ary,mapFn,val);const befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)aftIdx-=1;const befDiff=Math.abs(val-mapFn(ary[befIdx]));const aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)return null;const idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
+function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)return null;let idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)idx-=1;const hiInt=ary[idx];let loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length){loInt=ary[idx+1];}
+const loDiff=Math.abs(val-mapLoFn(loInt));const hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)return null;if(loDiff<hiDiff)return loInt;return hiInt;}
+return{compareArrays,deepCopy,findClosestElementInSortedArray,findClosestIntervalInSortedIntervals,findHighIndexInSortedArray,findIndexInSortedClosedIntervals,findIndexInSortedIntervals,findLowIndexInSortedArray,formatDate,getFirstElement,getOnlyElement,getUsingPath,groupIntoMap,inPlaceFilter,invertArrayOfDicts,isUrl,iterateOverIntersectingIntervals,normalizeException,numberFromJson,numberToJson,runLengthEncoding,setsEqual,stackTrace,stackTraceAsString,};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register){throw new Error('Already has registry');}
+registryOptions.freeze();if(registryOptions.mode===tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode===tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
+if(registry.addEventListener===undefined){tr.b.EventTarget.decorate(registry);}}
+return{decorateExtensionRegistry,};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
+Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer(){return false;},extractSubtraces(){return[];},importClockSyncMarkers(){},importEvents(){},importSampleData(){},finalizeImport(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){const typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo){return typeInfo.constructor;}
+return undefined;};return{Importer,};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
+GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
+const normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)return false;return normalizedEventData.slice(0,14)==='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces(){const traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace(){const events=[];const trace=JSON.parse(this.eventData_);const spanLength=trace.spans.length;for(let i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return{'traceEvents':events};},createEventForSpan(traceId,span){let newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
+newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
+return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter,};});'use strict';tr.exportTo('tr.b.math',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.math.Range.fromExplicitRange(event.start,event.end);});}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){const remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){const merged=[];if(remainingEvents.length===1){merged.push(mergeFunction(remainingEvents));}
+return merged;}
+const mergedEvents=[];let currentMergeBuffer=[];let rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+function flushCurrentMergeBuffer(){if(currentMergeBuffer.length===0)return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!==0)beginMerging();}
+beginMerging();while(remainingEvents.length){const currentEvent=remainingEvents[0];const distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+flushCurrentMergeBuffer();}
+flushCurrentMergeBuffer();return mergedEvents;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)opt_totalRange=undefined;const emptyRanges=[];if(!inRanges.length){if(opt_totalRange)emptyRanges.push(opt_totalRange);return emptyRanges;}
+inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
+inRanges.forEach(function(range,index){for(let otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)continue;const other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,other.min));return;}
+if(other.max>range.max){return;}}
+if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
+return{convertEventsToRanges,findEmptyRangesBetweenRanges,mergeRanges,};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){const glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');const glMatrixModule=require(glMatrixAbsPath);for(const exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const PREFERRED_NUMBER_SERIES_MULTIPLIERS=[1,2,5,10];function approximately(x,y,delta){if(delta===undefined)delta=1e-9;return Math.abs(x-y)<delta;}
+function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
+function lerp(percentage,lo,hi){const range=hi-lo;return lo+percentage*range;}
+function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
+function deg2rad(deg){return(Math.PI*deg)/180.0;}
+function erf(x){const sign=(x>=0)?1:-1;x=Math.abs(x);const a1=0.254829592;const a2=-0.284496736;const a3=1.421413741;const a4=-1.453152027;const a5=1.061405429;const p=0.3275911;const t=1.0/(1.0+p*x);const y=1.0-(((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-x*x);return sign*y;}
+const tmpVec2=vec2.create();const tmpVec2b=vec2.create();const tmpVec4=vec4.create();const tmpMat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!==2)throw new Error('Should be length 2');const v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){const v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmpVec2,u1,scale1);vec2.scale(tmpVec2b,u2,scale2);vec2.add(out,tmpVec2,tmpVec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])return points[0][1];for(let i=1;i<points.length;++i){if(x<points[i][0]){const percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){const v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.translate(out,out,tmpVec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.scale(out,out,tmpVec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmpVec4,a);vec2.copy(out,tmpVec4);};function logOrLog10(x,base){if(base===10)return Math.log10(x);return Math.log(x)/Math.log(base);}
+function lesserPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.floor(logOrLog10(x,base)));}
+function greaterPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.ceil(logOrLog10(x,base)));}
+function lesserWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.floor(x/pow10);}
+function greaterWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.ceil(x/pow10);}
+function preferredNumberLargerThanMin(min){const absMin=Math.abs(min);const conservativeGuess=tr.b.math.lesserPower(absMin);let minPreferedNumber=undefined;for(const multiplier of PREFERRED_NUMBER_SERIES_MULTIPLIERS){const tightenedGuess=conservativeGuess*multiplier;if(tightenedGuess>=absMin){minPreferedNumber=tightenedGuess;break;}}
+if(minPreferedNumber===undefined){throw new Error('Could not compute preferred number for '+min);}
+if(min<0)minPreferedNumber*=-1;return minPreferedNumber;}
+return{approximately,clamp,lerp,normalize,deg2rad,erf,lesserPower,greaterPower,lesserWholeNumber,greaterWholeNumber,preferredNumberLargerThanMin,};});'use strict';tr.exportTo('tr.b.math',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
+Range.prototype={__proto__:Object.prototype,clone(){if(this.isEmpty)return new Range();return Range.fromExplicitRange(this.min_,this.max_);},reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange(range){if(range.isEmpty)return;this.addValue(range.min);this.addValue(range.max);},addValue(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
+this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)return undefined;return this.min_;},get max(){if(this.isEmpty_)return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)return 0;return this.max_-this.min_;},enclosingPowers(opt_base){if(this.isEmpty)return new Range();return Range.fromExplicitRange(tr.b.math.lesserPower(this.min_,opt_base),tr.b.math.greaterPower(this.max_,opt_base));},normalize(x){return tr.b.math.normalize(x,this.min,this.max);},lerp(x){return tr.b.math.lerp(x,this.min,this.max);},clamp(x){return tr.b.math.clamp(x,this.min,this.max);},equals(that){if(this.isEmpty&&that.isEmpty)return true;if(this.isEmpty!==that.isEmpty)return false;return(tr.b.math.approximately(this.min,that.min)&&tr.b.math.approximately(this.max,that.max));},containsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<max&&min<this.max_;},containsRangeInclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findExplicitIntersectionDuration(min,max){min=Math.max(this.min,min);max=Math.min(this.max,max);if(max<min)return 0;return max-min;},findIntersection(range){if(this.isEmpty||range.isEmpty)return new Range();const min=Math.max(this.min,range.min);const max=Math.min(this.max,range.max);if(max<min)return new Range();return Range.fromExplicitRange(min,max);},toJSON(){if(this.isEmpty_)return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray(array,opt_keyFunc,opt_this){if(this.isEmpty_)return[];function binSearch(test){let i0=0;let i1=array.length;while(i0<i1){const i=Math.trunc((i0+i1)/2);if(test(i)){i1=i;}else{i0=i+1;}}
+return i1;}
+const keyFunc=opt_keyFunc||(x=>x);function getValue(index){return keyFunc.call(opt_this,array[index]);}
+const first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));const last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true)return new Range();if(d.isEmpty===false){const range=new Range();range.min=d.min;range.max=d.max;return range;}
+throw new Error('Not a range');};Range.fromExplicitRange=function(min,max){const range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)return-1;if(!a.isEmpty&&b.isEmpty)return 1;return 0;};Range.findDifference=function(rangeA,rangeB){if(!rangeA||rangeA.duration<0||!rangeB||rangeB.duration<0){throw new Error(`Couldn't subtract ranges`);}
+const resultRanges=[];if(rangeA.isEmpty)return resultRanges;if(rangeB.isEmpty)return[rangeA.clone()];const intersection=rangeA.findIntersection(rangeB);if(intersection.isEmpty){return[rangeA.clone()];}
+if(rangeA.duration===0&&rangeB.duration===0){if(intersection.empty)return[rangeA.clone()];else if(intersection.duration===0)return resultRanges;throw new Error(`Two points' intersection can only be a point or empty`);}
+const leftRange=tr.b.math.Range.fromExplicitRange(rangeA.min,intersection.min);if(leftRange.duration>0){resultRanges.push(leftRange);}
+const rightRange=tr.b.math.Range.fromExplicitRange(intersection.max,rangeA.max);if(rightRange.duration>0){resultRanges.push(rightRange);}
+return resultRanges;};Range.PERCENT_RANGE=Range.fromExplicitRange(0,1);Object.freeze(Range.PERCENT_RANGE);return{Range,};});'use strict';(function(exports){var rank={standard:function(array,key){array=array.sort(function(a,b){var x=a[key];var y=b[key];return((x<y)?-1:((x>y)?1:0));});for(var i=1;i<array.length+1;i++){array[i-1]['rank']=i;}
+return array;},fractional:function(array,key){array=this.standard(array,key);var pos=0;while(pos<array.length){var sum=0;var i=0;for(i=0;array[pos+i+1]&&(array[pos+i][key]===array[pos+i+1][key]);i++){sum+=array[pos+i]['rank'];}
+sum+=array[pos+i]['rank'];var endPos=pos+i+1;for(pos;pos<endPos;pos++){array[pos]['rank']=sum/(i+1);}
+pos=endPos;}
+return array;},rank:function(x,y){var nx=x.length,ny=y.length,combined=[],ranked;while(nx--){combined.push({set:'x',val:x[nx]});}
+while(ny--){combined.push({set:'y',val:y[ny]});}
+ranked=this.fractional(combined,'val');return ranked}};var erf=function erf(x){var cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,3.81e-16,7.106e-15,-1.523e-15,-9.4e-17,1.21e-16,-2.8e-17];var j=cof.length-1;var isneg=false;var d=0;var dd=0;var t,ty,tmp,res;if(x<0){x=-x;isneg=true;}
+t=2/(2+x);ty=4*t-2;for(;j>0;j--){tmp=d;d=ty*d-dd+cof[j];dd=tmp;}
+res=t*Math.exp(-x*x+0.5*(cof[0]+ty*d)-dd);return isneg?res-1:1-res;};var dnorm=function(x,mean,std){return 0.5*(1+erf((x-mean)/Math.sqrt(2*std*std)));}
+var statistic=function(x,y){var ranked=rank.rank(x,y),nr=ranked.length,nx=x.length,ny=y.length,ranksums={x:0,y:0},i=0,t=0,nt=1,tcf,ux,uy;while(i<nr){if(i>0){if(ranked[i].val==ranked[i-1].val){nt++;}else{if(nt>1){t+=Math.pow(nt,3)-nt
+nt=1;}}}
+ranksums[ranked[i].set]+=ranked[i].rank
+i++;}
+tcf=1-(t/(Math.pow(nr,3)-nr))
+ux=nx*ny+(nx*(nx+1)/2)-ranksums.x;uy=nx*ny-ux;return{tcf:tcf,ux:ux,uy:uy,big:Math.max(ux,uy),small:Math.min(ux,uy)}}
+exports.test=function(x,y,alt,corr){alt=typeof alt!=='undefined'?alt:'two-sided';corr=typeof corr!=='undefined'?corr:true;var nx=x.length,ny=y.length,f=1,u,mu,std,z,p;u=statistic(x,y);if(corr){mu=(nx*ny/2)+0.5;}else{mu=nx*ny/2;}
+std=Math.sqrt(u.tcf*nx*ny*(nx+ny+1)/12);if(alt=='less'){z=(u.ux-mu)/std;}else if(alt=='greater'){z=(u.uy-mu)/std;}else if(alt=='two-sided'){z=Math.abs((u.big-mu)/std);}else{console.log('Unknown alternative argument');}
+if(alt=='two-sided'){f=2;}
+p=dnorm(-z,0,1)*f;return{U:u.small,p:p};}})(typeof exports==='undefined'?this['mannwhitneyu']={}:exports);'use strict';(function(global){if(tr.isNode){const mwuAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/mannwhitneyu.js');const mwuModule=require(mwuAbsPath);for(const exportName in mwuModule){global[exportName]=mwuModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const Statistics={};Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=0;let i=0;for(const elt of ary){ret+=func.call(opt_this,elt,i++);}
+return ret;};Statistics.mean=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let sum=0;let i=0;for(const elt of ary){sum+=func.call(opt_this,elt,i++);}
+if(i===0)return undefined;return sum/i;};Statistics.geometricMean=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let i=0;let logsum=0;for(const elt of ary){const x=func.call(opt_this,elt,i++);if(x<=0)return 0;logsum+=Math.log(Math.abs(x));}
+if(i===0)return 1;return Math.exp(logsum/i);};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){const valueCallback=opt_valueCallback||(x=>x);let numerator=0;let denominator=0;let i=-1;for(const elt of ary){i++;const value=valueCallback.call(opt_this,elt,i);if(value===undefined)continue;const weight=weightCallback.call(opt_this,elt,i,value);numerator+=weight*value;denominator+=weight;}
+if(denominator===0)return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;if(ary.length===1)return 0;const func=opt_func||(x=>x);const mean=Statistics.mean(ary,func,opt_this);const sumOfSquaredDistances=Statistics.sum(ary,function(d,i){const v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=-Infinity;let i=0;for(const elt of ary){ret=Math.max(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.min=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=Infinity;let i=0;for(const elt of ary){ret=Math.min(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.range=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);const ret=new tr.b.math.Range();let i=0;for(const elt of ary){ret.addValue(func.call(opt_this,elt,i++));}
+return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
+const func=opt_func||(x=>x);const tmp=new Array(ary.length);let i=0;for(const elt of ary){tmp[i]=func.call(opt_this,elt,i++);}
+tmp.sort((a,b)=>a-b);const idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});const low=Math.min.apply(null,samples);const high=Math.max.apply(null,samples);const newLow=0.5/samples.length;const newHigh=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+const scale=(newHigh-newLow)/(high-low);for(let i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+newLow;}
+return{normalized_samples:samples,scale};};Statistics.discrepancy=function(samples,opt_locationCount){if(samples.length===0)return 0.0;let maxLocalDiscrepancy=0;const invSampleCount=1.0/samples.length;const locations=[];const countLess=[];const countLessEqual=[];if(opt_locationCount!==undefined){let sampleIndex=0;for(let i=0;i<opt_locationCount;i++){const location=i/(opt_locationCount-1);locations.push(location);while(sampleIndex<samples.length&&samples[sampleIndex]<location){sampleIndex+=1;}
+countLess.push(sampleIndex);while(sampleIndex<samples.length&&samples[sampleIndex]<=location){sampleIndex+=1;}
+countLessEqual.push(sampleIndex);}}else{if(samples[0]>0.0){locations.push(0.0);countLess.push(0);countLessEqual.push(0);}
+for(let i=0;i<samples.length;i++){locations.push(samples[i]);countLess.push(i);countLessEqual.push(i+1);}
+if(samples[-1]<1.0){locations.push(1.0);countLess.push(samples.length);countLessEqual.push(samples.length);}}
+let maxDiff=0;let minDiff=0;for(let i=1;i<locations.length;i++){const length=locations[i]-locations[i-1];const countClosed=countLessEqual[i]-countLess[i-1];const countOpen=countLess[i]-countLessEqual[i-1];const countClosedIncrement=countLessEqual[i]-countLessEqual[i-1];const countOpenIncrement=countLess[i]-countLess[i-1];maxDiff=Math.max(countClosedIncrement*invSampleCount-length+maxDiff,countClosed*invSampleCount-length);minDiff=Math.min(countOpenIncrement*invSampleCount-length+minDiff,countOpen*invSampleCount-length);maxLocalDiscrepancy=Math.max(maxDiff,-minDiff,maxLocalDiscrepancy);}
+return maxLocalDiscrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_locationCount){if(timestamps.length===0)return 0.0;if(opt_absolute===undefined)opt_absolute=true;if(Array.isArray(timestamps[0])){const rangeDiscrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,rangeDiscrepancies);}
+const s=Statistics.normalizeSamples(timestamps);const samples=s.normalized_samples;const sampleScale=s.scale;let discrepancy=Statistics.discrepancy(samples,opt_locationCount);const invSampleCount=1.0/samples.length;if(opt_absolute===true){discrepancy/=sampleScale;}else{discrepancy=tr.b.math.clamp((discrepancy-invSampleCount)/(1.0-invSampleCount),0.0,1.0);}
+return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_locationCount){if(durations.length===0)return 0.0;const timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_locationCount);};Statistics.uniformlySampleArray=function(samples,count){if(samples.length<=count){return samples;}
+while(samples.length>count){const i=parseInt(Math.random()*samples.length);samples.splice(i,1);}
+return samples;};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength){samples[streamLength-1]=newElement;}else{samples.push(newElement);}
+return;}
+const probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)return;const index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){const nbElements=Math.min(streamLengthB,samplesB.length);for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+return;}
+if(streamLengthA<numSamples){const nbElements=Math.min(streamLengthA,samplesA.length);const tempSamples=samplesB.slice();for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(let i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+return;}
+const nbElements=Math.min(numSamples,samplesB.length);const probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(let i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};function Distribution(){}
+Distribution.prototype={computeDensity(x){throw Error('Not implemented');},computePercentile(x){throw Error('Not implemented');},computeComplementaryPercentile(x){return 1-this.computePercentile(x);},get mean(){throw Error('Not implemented');},get mode(){throw Error('Not implemented');},get median(){throw Error('Not implemented');},get standardDeviation(){throw Error('Not implemented');},get variance(){throw Error('Not implemented');}};Statistics.UniformDistribution=function(opt_range){if(!opt_range)opt_range=tr.b.math.Range.fromExplicitRange(0,1);this.range=opt_range;};Statistics.UniformDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){return 1/this.range.range;},computePercentile(x){return tr.b.math.normalize(x,this.range.min,this.range.max);},get mean(){return this.range.center;},get mode(){return undefined;},get median(){return this.mean;},get standardDeviation(){return Math.sqrt(this.variance);},get variance(){return Math.pow(this.range.range,2)/12;}};Statistics.NormalDistribution=function(opt_mean,opt_variance){this.mean_=opt_mean||0;this.variance_=opt_variance||1;this.standardDeviation_=Math.sqrt(this.variance_);};Statistics.NormalDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){const scale=(1.0/(this.standardDeviation*Math.sqrt(2.0*Math.PI)));const exponent=-Math.pow(x-this.mean,2)/(2.0*this.variance);return scale*Math.exp(exponent);},computePercentile(x){const standardizedX=((x-this.mean)/Math.sqrt(2.0*this.variance));return(1.0+tr.b.math.erf(standardizedX))/2.0;},get mean(){return this.mean_;},get median(){return this.mean;},get mode(){return this.mean;},get standardDeviation(){return this.standardDeviation_;},get variance(){return this.variance_;}};Statistics.LogNormalDistribution=function(opt_location,opt_shape){this.normalDistribution_=new Statistics.NormalDistribution(opt_location,Math.pow(opt_shape||1,2));};Statistics.LogNormalDistribution.prototype={__proto__:Statistics.NormalDistribution.prototype,computeDensity(x){return this.normalDistribution_.computeDensity(Math.log(x))/x;},computePercentile(x){return this.normalDistribution_.computePercentile(Math.log(x));},get mean(){return Math.exp(this.normalDistribution_.mean+
+(this.normalDistribution_.variance/2));},get variance(){const nm=this.normalDistribution_.mean;const nv=this.normalDistribution_.variance;return(Math.exp(2*(nm+nv))-
+Math.exp(2*nm+nv));},get standardDeviation(){return Math.sqrt(this.variance);},get median(){return Math.exp(this.normalDistribution_.mean);},get mode(){return Math.exp(this.normalDistribution_.mean-
+this.normalDistribution_.variance);}};Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns=function(median,diminishingReturns){diminishingReturns=Math.log(diminishingReturns/median);const shape=Math.sqrt(1-3*diminishingReturns-
+Math.sqrt(Math.pow(diminishingReturns-3,2)-8))/2;const location=Math.log(median);return new Statistics.LogNormalDistribution(location,shape);};Statistics.DEFAULT_ALPHA=0.01;Statistics.MAX_SUGGESTED_SAMPLE_SIZE=20;Statistics.Significance={SIGNIFICANT:'REJECT',INSIGNIFICANT:'FAIL_TO_REJECT',NEED_MORE_DATA:'NEED_MORE_DATA',DONT_CARE:'DONT_CARE',};Statistics.mwu=function(a,b,opt_alpha,opt_reqSampleSize){const result=mannwhitneyu.test(a,b);const alpha=opt_alpha||Statistics.DEFAULT_ALPHA;if(result.p<alpha){result.significance=Statistics.Significance.SIGNIFICANT;}else if(opt_reqSampleSize&&(a.length<opt_reqSampleSize||b.length<opt_reqSampleSize)){result.significance=Statistics.Significance.NEED_MORE_DATA;}else{result.significance=Statistics.Significance.INSIGNIFICANT;}
+return result;};return{Statistics,};});'use strict';const GREEK_SMALL_LETTER_MU=String.fromCharCode(956);tr.exportTo('tr.b',function(){const SECONDS_IN_A_MINUTE=60;const SECONDS_IN_AN_HOUR=SECONDS_IN_A_MINUTE*60;const SECONDS_IN_A_DAY=SECONDS_IN_AN_HOUR*24;const SECONDS_IN_A_WEEK=SECONDS_IN_A_DAY*7;const SECONDS_IN_A_YEAR=SECONDS_IN_A_DAY*365.2422;const SECONDS_IN_A_MONTH=SECONDS_IN_A_YEAR/12;const UnitPrefixScale={};const UnitScale={};function defineUnitPrefixScale(name,prefixes){if(UnitPrefixScale[name]!==undefined){throw new Error('Unit prefix scale \''+name+'\' already exists');}
+if(prefixes.AUTO!==undefined){throw new Error('The \'AUTO\' unit prefix is not supported for unit'+'prefix scales and cannot be added to scale \''+name+'\'');}
+UnitPrefixScale[name]=prefixes;}
+UnitScale.defineUnitScale=function(name,unitScale){if(UnitScale[name]!==undefined){throw new Error('Unit scale \''+name+'\' already exists');}
+if(unitScale.AUTO!==undefined){throw new Error('\'AUTO\' unit scale will be added automatically '+'for unit scale \''+name+'\'');}
+unitScale.AUTO=Object.values(unitScale);unitScale.AUTO.sort((a,b)=>a.value-b.value);if(name)UnitScale[name]=unitScale;return unitScale;};UnitScale.defineUnitScaleFromPrefixScale=function(baseSymbol,baseName,prefixScale,opt_scaleName){if(baseSymbol===undefined){throw new Error('Cannot create UnitScale with undefined baseSymbol.');}
+if(!baseName){throw new Error('Cannot create UnitScale without a baseName.');}
+if(!prefixScale){throw new Error('Cannot create UnitScale without a prefix scale.');}
+const unitScale={};for(const curPrefix of Object.keys(prefixScale)){const curScale=prefixScale[curPrefix];if(curScale.symbol===undefined||!curScale.value){throw new Error(`Cannot convert PrefixScale with malformed prefix ${curScale}.`);}
+const name=curPrefix==='NONE'?baseName:`${curPrefix}_${baseName}`;unitScale[name]={value:curScale.value,symbol:curScale.symbol+baseSymbol,baseSymbol};}
+return UnitScale.defineUnitScale(opt_scaleName,unitScale);};function convertUnit(value,fromScale,toScale){if(value===undefined)return undefined;const fromScaleBase=fromScale.baseSymbol;const toScaleBase=toScale.baseSymbol;if(fromScaleBase!==undefined&&toScaleBase!==undefined&&fromScaleBase!==toScaleBase){throw new Error('Cannot convert between units with different base symbols.');}
+return value*(fromScale.value/toScale.value);}
+defineUnitPrefixScale('BINARY',{NONE:{value:Math.pow(1024,0),symbol:''},KIBI:{value:Math.pow(1024,1),symbol:'Ki'},MEBI:{value:Math.pow(1024,2),symbol:'Mi'},GIBI:{value:Math.pow(1024,3),symbol:'Gi'},TEBI:{value:Math.pow(1024,4),symbol:'Ti'}});defineUnitPrefixScale('METRIC',{NANO:{value:1e-9,symbol:'n'},MICRO:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU},MILLI:{value:1e-3,symbol:'m'},NONE:{value:1,symbol:''},KILO:{value:1e3,symbol:'k'},MEGA:{value:1e6,symbol:'M'},GIGA:{value:1e9,symbol:'G'}});UnitScale.defineUnitScale('TIME',{NANO_SEC:{value:1e-9,symbol:'ns',baseSymbol:'s'},MICRO_SEC:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU+'s',baseSymbol:'s'},MILLI_SEC:{value:1e-3,symbol:'ms',baseSymbol:'s'},SEC:{value:1,symbol:'s',baseSymbol:'s'},MINUTE:{value:SECONDS_IN_A_MINUTE,symbol:'min',baseSymbol:'s'},HOUR:{value:SECONDS_IN_AN_HOUR,symbol:'hr',baseSymbol:'s'},DAY:{value:SECONDS_IN_A_DAY,symbol:'days',baseSymbol:'s'},WEEK:{value:SECONDS_IN_A_WEEK,symbol:'weeks',baseSymbol:'s'},MONTH:{value:SECONDS_IN_A_MONTH,symbol:'months',baseSymbol:'s'},YEAR:{value:SECONDS_IN_A_YEAR,symbol:'years',baseSymbol:'s'}});UnitScale.defineUnitScaleFromPrefixScale('B','BYTE',UnitPrefixScale.BINARY,'MEMORY');return{UnitPrefixScale,UnitScale,convertUnit,};});'use strict';tr.exportTo('tr.b',function(){const msDisplayMode={scale:1e-3,suffix:'ms',roundedLess(a,b){return Math.round(a*1000)<Math.round(b*1000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.MILLI_SEC],minimumFractionDigits:3,}};const nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.NANO_SEC],maximumFractionDigits:0}};const TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes,};});'use strict';tr.exportTo('tr.ui.b',function(){function iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement&&cb.call(thisArg,element))return true;if(element.root&&element.root!==element&&iterateElementDeeplyImpl(element.root,cb,thisArg,false)){return true;}
+const children=Polymer.dom(element).children;for(let i=0;i<children.length;i++){if(iterateElementDeeplyImpl(children[i],cb,thisArg,true)){return true;}}
+return false;}
+function iterateElementDeeply(element,cb,thisArg){iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){let foundElement=undefined;function matches(element){const match=predicate(element);if(!match){return false;}
+foundElement=element;return true;}
+iterateElementDeeply(element,matches);return foundElement;}
+function findDeepElementsMatchingPredicate(element,predicate){const foundElements=[];function matches(element){const match=predicate(element);if(match){foundElements.push(element);}
+return false;}
+iterateElementDeeply(element,matches);return foundElements;}
+function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)return false;return re.test(Polymer.dom(element).textContent);});}
+return{findDeepElementMatching,findDeepElementsMatching,findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate,findDeepElementWithTextContent,};});'use strict';tr.exportTo('tr.b',function(){const TimeDisplayModes=tr.b.TimeDisplayModes;const PLUS_MINUS_SIGN=String.fromCharCode(177);const CACHED_FORMATTERS={};function getNumberFormatter(minSpec,maxSpec,minCtx,maxCtx){const key=minSpec+'-'+maxSpec+'-'+minCtx+'-'+maxCtx;let formatter=CACHED_FORMATTERS[key];if(formatter===undefined){let minimumFractionDigits=minCtx!==undefined?minCtx:minSpec;let maximumFractionDigits=maxCtx!==undefined?maxCtx:maxSpec;if(minimumFractionDigits>maximumFractionDigits){if(minCtx!==undefined&&maxCtx===undefined){maximumFractionDigits=minimumFractionDigits;}else if(minCtx===undefined&&maxCtx!==undefined){minimumFractionDigits=maximumFractionDigits;}}
+formatter=new Intl.NumberFormat(undefined,{minimumFractionDigits,maximumFractionDigits,});CACHED_FORMATTERS[key]=formatter;}
+return formatter;}
+function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return a.scale>b.scale?a:b;}
+const ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,formatSpec){this.unitName=unitName;this.jsonName=jsonName;this.scaleBaseUnit=scaleBaseUnit;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatSpec_=formatSpec;this.baseUnit=undefined;this.correspondingDeltaUnit=undefined;}
+Unit.prototype={asJSON(){return this.jsonName;},getUnitScale_(opt_context){let formatSpec=this.formatSpec_;let formatSpecWasFunction=false;if(typeof formatSpec==='function'){formatSpecWasFunction=true;formatSpec=formatSpec();}
+const context=opt_context||{};let scale=undefined;if(context.unitScale){scale=context.unitScale;}else if(context.unitPrefix){const symbol=formatSpec.baseSymbol?formatSpec.baseSymbol:this.scaleBaseUnit.baseSymbol;scale=tr.b.UnitScale.defineUnitScaleFromPrefixScale(symbol,symbol,[context.unitPrefix]).AUTO;}else{scale=formatSpec.unitScale;if(!scale){scale=[{value:1,symbol:formatSpec.baseSymbol||'',baseSymbol:formatSpec.baseSymbol||''}];if(!formatSpecWasFunction)formatSpec.unitScale=scale;}}
+if(!(scale instanceof Array)){throw new Error('Unit has a malformed unit scale.');}
+return scale;},get unitString(){const scale=this.getUnitScale_();if(!scale){throw new Error('A UnitScale could not be found for Unit '+this.unitName);}
+return scale[0].baseSymbol||scale[0].symbol;},format(value,opt_context){let signString='';if(value<0){signString='-';value=-value;}else if(this.isDelta){signString=value===0?PLUS_MINUS_SIGN:'+';}
+const context=opt_context||{};const scale=this.getUnitScale_(context);let deltaValue=context.deltaValue===undefined?value:context.deltaValue;deltaValue=Math.abs(deltaValue)*this.scaleBaseUnit.value;let i=0;while(i<scale.length-1&&deltaValue/scale[i+1].value>=1){i++;}
+const selectedSubUnit=scale[i];let formatSpec=this.formatSpec_;if(typeof formatSpec==='function')formatSpec=formatSpec();let unitString='';if(selectedSubUnit.symbol){if(!formatSpec.avoidSpacePrecedingUnit)unitString=' ';unitString+=selectedSubUnit.symbol;}
+value=tr.b.convertUnit(value,this.scaleBaseUnit,selectedSubUnit);const numberString=getNumberFormatter(formatSpec.minimumFractionDigits,formatSpec.maximumFractionDigits,context.minimumFractionDigits,context.maximumFractionDigits).format(value);return signString+numberString+unitString;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return tr.b.convertUnit(us,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);};Object.defineProperty(Unit,'currentTimeDisplayMode',{get(){return Unit.currentTimeDisplayMode_;},set(value){if(Unit.currentTimeDisplayMode_===value)return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){let largest=undefined;const els=tr.ui.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentTimeDisplayMode=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){const u=Unit.byJSONName[object];if(u){return u;}
+throw new Error(`Unrecognized unit "${object}"`);};Unit.define=function(params){const definedUnits=[];for(const improvementDirection of Object.values(ImprovementDirection)){const regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);const deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;definedUnits.push(regularUnit,deltaUnit);}
+const baseUnit=Unit.byName[params.baseUnitName];definedUnits.forEach(u=>u.baseUnit=baseUnit);};Unit.nameSuffixForImprovementDirection=function(improvementDirection){switch(improvementDirection){case ImprovementDirection.DONT_CARE:return'';case ImprovementDirection.BIGGER_IS_BETTER:return'_biggerIsBetter';case ImprovementDirection.SMALLER_IS_BETTER:return'_smallerIsBetter';default:throw new Error('Unknown improvement direction: '+improvementDirection);}};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){let nameSuffix=isDelta?'Delta':'';nameSuffix+=Unit.nameSuffixForImprovementDirection(improvementDirection);const unitName=params.baseUnitName+nameSuffix;const jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined){throw new Error('Unit \''+unitName+'\' already exists');}
+if(Unit.byJSONName[jsonName]!==undefined){throw new Error('JSON unit \''+jsonName+'\' alread exists');}
+let scaleBaseUnit=params.scaleBaseUnit;if(!scaleBaseUnit){let formatSpec=params.formatSpec;if(typeof formatSpec==='function')formatSpec=formatSpec();const baseSymbol=formatSpec.unitScale?formatSpec.unitScale[0].baseSymbol:(formatSpec.baseSymbol||'');scaleBaseUnit={value:1,symbol:baseSymbol,baseSymbol};}
+const unit=new Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,params.formatSpec);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeInMsAutoFormat',baseJsonName:'msBestFitFormat',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:{unitScale:tr.b.UnitScale.TIME.AUTO,minimumFractionDigits:0,maximumFractionDigits:3}});Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatSpec:{unitScale:[{value:0.01,symbol:'%'}],avoidSpacePrecedingUnit:true,minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatSpec:{unitScale:tr.b.UnitScale.MEMORY.AUTO,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatSpec:{baseSymbol:'J',minimumFractionDigits:3}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatSpec:{baseSymbol:'W',minimumFractionDigits:3}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatSpec:{minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'count',baseJsonName:'count',formatSpec:{minimumFractionDigits:0,maximumFractionDigits:0}});Unit.define({baseUnitName:'sigma',baseJsonName:'sigma',formatSpec:{baseSymbol:String.fromCharCode(963),minimumFractionDigits:1,maximumFractionDigits:1}});return{ImprovementDirection,Unit,};});'use strict';tr.exportTo('tr.b',function(){class Scalar{constructor(unit,value){if(!(unit instanceof tr.b.Unit)){throw new Error('Expected Unit');}
+if(!(typeof(value)==='number')){throw new Error('Expected value to be number');}
+this.unit=unit;this.value=value;}
+asDict(){return{unit:this.unit.asJSON(),value:tr.b.numberToJson(this.value),};}
+toString(){return this.unit.format(this.value);}
+static fromDict(d){return new Scalar(tr.b.Unit.fromJSON(d.unit),tr.b.numberFromJson(d.value));}}
+return{Scalar,};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate(){},installUserFriendlyCategoryDriverIfNeeded(){},runAudit(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor,};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
+Color.fromString=function(str){let tmp;let values;if(str.substr(0,4)==='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==3){throw new Error('Malformatted rgb-expression');}
+return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}
+if(str.substr(0,5)==='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==4){throw new Error('Malformatted rgb-expression');}
+return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}
+if(str[0]==='#'&&str.length===7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}
+throw new Error('Unrecognized string format.');};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined){return Color.lerpRGBA(a,b,percent);}
+return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){let r;let g;let b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
+if(s===0){r=g=b=l;}else{const q=l<0.5?l*(1+s):l+s-l*s;const p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
+return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);};Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);};Color.prototype={clone(){const c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver(bgColor){const oneMinusThisAlpha=1-this.a;const outA=this.a+bgColor.a*oneMinusThisAlpha;const bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten(opt_k){const k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten(k,opt_maxL){const maxL=opt_maxL!==undefined?opt_maxL:1.0;const hsl=this.toHSL();hsl.l=Math.min(hsl.l+k,maxL);return Color.fromHSL(hsl);},darken(opt_k){let k;if(opt_k!==undefined){k=opt_k;}else{k=0.45;}
+return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate(opt_desaturateFactor){let desaturateFactor;if(opt_desaturateFactor!==undefined){desaturateFactor=opt_desaturateFactor;}else{desaturateFactor=1;}
+const hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha(a){return new Color(this.r,this.g,this.b,a);},toString(){if(this.a!==undefined){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+this.a+')';}
+return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL(){const r=this.r/255;const g=this.g/255;const b=this.b/255;const max=Math.max(r,g,b);const min=Math.min(r,g,b);let h;let s;const l=(max+min)/2;if(min===max){h=0;s=0;}else{const delta=max-min;if(l>0.5){s=delta/(2-max-min);}else{s=delta/(max+min);}
+if(r===max){h=(g-b)/delta;if(g<b)h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
+h/=6;}
+return{h,s,l,a:this.a};},toStringWithAlphaOverride(alpha){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+alpha+')';}};return{Color,};});'use strict';tr.exportTo('tr.b',function(){const generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];const reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),background_memory_dump:new tr.b.Color(0,180,180),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),vsync_highlight_color:new tr.b.Color(0,0,255),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),grey:new tr.b.Color(221,221,221),white:new tr.b.Color(255,255,255),yellow:new tr.b.Color(255,255,0),olive:new tr.b.Color(100,100,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),startup:new tr.b.Color(230,230,0),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),heap_dump_child_node_arrow:new tr.b.Color(204,102,0),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};const numGeneralPurposeColorIds=generalPurposeColors.length;const numReservedColorIds=Object.keys(reservedColorsByName).length;const numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+const paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,Object.values(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant,};function pushVariant(func){const variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
+pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.8);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.85);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});const reservedColorNameToIdMap=(function(){const m=new Map();let i=generalPurposeColors.length;for(const key of Object.keys(reservedColorsByName)){m.set(key,i++);}
+return m;})();ColorScheme.getColorIdForReservedName=function(name){const id=reservedColorNameToIdMap.get(name);if(id===undefined){throw new Error('Unrecognized color '+name);}
+return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){const id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){let hash=0;for(let i=0;i<name.length;++i){hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;}
+return hash;};const stringColorIdCache=new Map();ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache.get(string)===undefined){const hash=ColorScheme.getStringHash(string);stringColorIdCache.set(string,hash%numGeneralPurposeColorIds);}
+return stringColorIdCache.get(string);};ColorScheme.getAnotherColorId=function(colorId,n){return(colorId+n)%numColorsPerVariant;};ColorScheme.getVariantColorId=function(colorId,offset){return colorId+offset;};return{ColorScheme,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
+return{EventInfo,};});'use strict';tr.exportTo('tr.b',function(){let nextGUID=1;const UUID4_PATTERN='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';const GUID={allocateSimple(){return nextGUID++;},getLastSimpleGuid(){return nextGUID-1;},allocateUUID4(){return UUID4_PATTERN.replace(/[xy]/g,function(c){let r=parseInt(Math.random()*16);if(c==='y')r=(r&3)+8;return r.toString(16);});}};return{GUID,};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.name===undefined){throw new Error('Registered events must provide name metadata');}
+if(metadata.pluralName===undefined){throw new Error('Registered events must provide pluralName metadata');}
+if(metadata.subTypes===undefined){metadata.subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=e.typeInfo.constructor;options.defaultConstructor=e.typeInfo.constructor;tr.b.decorateExtensionRegistry(metadata.subTypes,options);}else{if(!metadata.subTypes.register){throw new Error('metadata.subTypes must be an extension registry.');}}
+e.typeInfo.constructor.subTypes=metadata.subTypes;});let eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
+return eventsByTypeName[typeName];};EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){let result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
+EventRegistry.getUserFriendlySingularName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry,};});'use strict';tr.exportTo('tr.model',function(){const EventRegistry=tr.model.EventRegistry;const RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_=new tr.b.math.Range();this.events_=new Set();this.guid_=tr.b.GUID.allocateSimple();if(opt_events){if(opt_events instanceof Array){for(const event of opt_events){this.push(event);}}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
+EventSet.prototype={__proto__:Object.prototype,get bounds(){return this.bounds_;},get duration(){if(this.bounds_.isEmpty)return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.events_.size;},get guid(){return this.guid_;},*[Symbol.iterator](){for(const event of this.events_){yield event;}},clear(){this.bounds_=new tr.b.math.Range();this.events_.clear();},push(...events){let numPushed;for(const event of events){if(event.guid===undefined){throw new Error('Event must have a GUID');}
+if(!this.events_.has(event)){this.events_.add(event);if(event.addBoundsToRange){if(this.bounds_!==undefined){event.addBoundsToRange(this.bounds_);}}}
+numPushed++;}
+return numPushed;},contains(event){if(this.events_.has(event))return event;return undefined;},addEventSet(eventSet){for(const event of eventSet){this.push(event);}},intersectionIsEmpty(otherEventSet){return!this.some(event=>otherEventSet.contains(event));},equals(that){if(this.length!==that.length)return false;return this.every(event=>that.contains(event));},sortEvents(compare){const ary=this.toArray();ary.sort(compare);this.clear();for(const event of ary){this.push(event);}},getEventsOrganizedByBaseType(opt_pruneEmpty){const allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();const events=this.getEventsOrganizedByCallback(function(event){let maxEventIndex=-1;let maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex===-1){throw new Error(`Unrecognized event type: ${event.constructor.name}`);}
+return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined){events[eventTypeInfo.metadata.name]=new EventSet();}});}
+return events;},getEventsOrganizedByTitle(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined){throw new Error('An event didn\'t have a title!');}
+return event.title;});},getEventsOrganizedByCallback(cb,opt_this){const groupedEvents=tr.b.groupIntoMap(this,cb,opt_this||this);const groupedEventsDict={};for(const[k,events]of groupedEvents){groupedEventsDict[k]=new EventSet(events);}
+return groupedEventsDict;},enumEventsOfType(type,func){for(const event of this){if(event instanceof type){func(event);}}},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
+const eventsByBaseType=this.getEventsOrganizedByBaseType(true);const eventTypeName=Object.keys(eventsByBaseType)[0];if(this.length===1){const tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return tr.b.getOnlyElement(this.events_).userFriendlyName;}
+const numEventTypes=Object.keys(eventsByBaseType).length;if(numEventTypes!==1){return this.length+' events of various types';}
+const tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter(fn,opt_this){const res=new EventSet();for(const event of this){if(fn.call(opt_this,event)){res.push(event);}}
+return res;},toArray(){const ary=[];for(const event of this){ary.push(event);}
+return ary;},forEach(fn,opt_this){for(const event of this){fn.call(opt_this,event);}},map(fn,opt_this){const res=[];for(const event of this){res.push(fn.call(opt_this,event));}
+return res;},every(fn,opt_this){for(const event of this){if(!fn.call(opt_this,event)){return false;}}
+return true;},some(fn,opt_this){for(const event of this){if(fn.call(opt_this,event)){return true;}}
+return false;},asDict(){const stableIds=[];for(const event of this){stableIds.push(event.stableId);}
+return{'events':stableIds};},asSet(){return this.events_;}};EventSet.IMMUTABLE_EMPTY_SET=(function(){const s=new EventSet();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet,RequestSelectionChangeEvent,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};const brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];};const dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];};return{SelectionState,};});'use strict';tr.exportTo('tr.model',function(){const SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
+SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection(selection){const modelItem=this.modelItem_;if(!modelItem)return;selection.push(modelItem);},addToTrackMap(eventToTrackMap,track){const modelItem=this.modelItem_;if(!modelItem)return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;const IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocateSimple();this.selectionState=SelectionState.NONE;this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},get range(){const range=new tr.b.math.Range();this.addBoundsToRange(range);return range;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET){this.associatedAlerts=new tr.model.EventSet();}
+this.associatedAlerts.push(alert);},addBoundsToRange(range){}};return{Event,};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;this.contexts=Object.freeze([]);}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);},bounds(that,opt_precisionUnit){if(opt_precisionUnit===undefined){opt_precisionUnit=tr.b.TimeDisplayModes.ms;}
+const startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);const endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent,};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
+Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts'});return{Alert,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;}
+Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward(amount){this.start+=amount;this.end+=amount;for(let i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames'});return{Frame,FRAME_PERF_CLASS,};});'use strict';tr.exportTo('tr.model.helpers',function(){const Frame=tr.model.Frame;const Statistics=tr.b.math.Statistics;const UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};const UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};const RENDER_THREAD_DRAW_NAME='DrawFrame';const RENDER_THREAD_INDEP_DRAW_NAME='doFrame';const RENDER_THREAD_QUEUE_NAME='queueBuffer';const RENDER_THREAD_SWAP_NAME='eglSwapBuffers';const THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){const ret=[];threadTimeRanges.forEach(function(threadTimeRange){const slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){const args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){const start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args.deadline=surfaceFlinger.getFrameDeadline(start);args.frameKickoff=surfaceFlinger.getFrameKickoff(start);}
+const events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,uiDrawSlice){if(!renderThread)return undefined;let overlappingDrawFrame;const slices=tr.b.iterateOverIntersectingIntervals(renderThread.sliceGroup.slices,function(range){return range.start;},function(range){return range.end;},uiDrawSlice.start,uiDrawSlice.end,function(rtDrawSlice){if(rtDrawSlice.title===RENDER_THREAD_DRAW_NAME){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice&&rtSyncSlice.start>=uiDrawSlice.start&&rtSyncSlice.end<=uiDrawSlice.end){overlappingDrawFrame=rtDrawSlice;}}});return overlappingDrawFrame;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)return[];const preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title==='obtainView'||slice.title==='setupListItem'||slice.title==='deliverInputEvent'||slice.title==='RV Scroll'){preFrameEvents.push(slice);}});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title==='deliverInputEvent'){preFrameEvents.push(slice);}});return tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){const preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start;},function(range){return range.end;},traversalStart,3);if(preTraversalWorkRange){return preTraversalWorkRange.start;}
+return traversalStart;}
+function getRtFrameEndTime(rtDrawSlice){const rtQueueSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_QUEUE_NAME);if(rtQueueSlice){return rtQueueSlice.end;}
+const rtSwapSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_SWAP_NAME);if(rtSwapSlice){return rtSwapSlice.end;}
+return rtDrawSlice.end;}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)return[];let preTraversalWorkRanges=[];if(app.uiDrawType===UI_DRAW_TYPE.LEGACY){preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);}
+const frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+const threadTimeRanges=[];const uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);const rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice);if(rtDrawSlice){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:getRtFrameEndTime(rtDrawSlice)});}
+frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)return[];const frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){const threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getUiDrawType(uiThread){if(!uiThread){return UI_DRAW_TYPE.NONE;}
+const slices=uiThread.sliceGroup.slices;for(let i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+return UI_DRAW_TYPE.NONE;}
+function getInputSamples(process){let samples=undefined;for(const counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries===1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)return[];const inputSamples=[];let lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+lastValue=sample.value;});return inputSamples;}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)return[];const slices=[];for(const slice of uiThread.asyncSliceGroup.getDescendantEvents()){if(/^animator\:/.test(slice.title)){slices.push(slice);}}
+return slices;}
+function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;}
+AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){let uiThread=process.getThread(process.pid);const uiDrawType=getUiDrawType(uiThread);if(uiDrawType===UI_DRAW_TYPE.NONE){uiThread=undefined;}
+const renderThreads=process.findAllThreadsNamed('RenderThread');const renderThread=(renderThreads.length===1?renderThreads[0]:undefined);if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames(){if(!this.frames_){const uiFrames=getUiThreadDrivenFrames(this);const rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end;});}
+return this.frames_;},getInputSamples(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp,};});'use strict';tr.exportTo('tr.model.helpers',function(){const findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;const VSYNC_SF_NAME='android.VSYNC-sf';const VSYNC_APP_NAME='android.VSYNC-app';const VSYNC_FALLBACK_NAME='android.VSYNC';const TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){let vsync=process.counters[counterName];if(!vsync){vsync=process.counters[VSYNC_FALLBACK_NAME];}
+if(vsync&&vsync.numSeries===1&&vsync.numSamples>1){return vsync.series[0].timestamps;}
+return undefined;}
+function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);this.deadlineDelayMs_=this.appVsyncTimestamps_!==this.sfVsyncTimestamps_?5:TIMESTAMP_FUDGE_MS;}
+AndroidSurfaceFlinger.createForProcessIfPossible=function(process){const mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name)){return new AndroidSurfaceFlinger(process,mainThread);}
+const primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length===1){return new AndroidSurfaceFlinger(process,primaryThreads[0]);}
+return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+this.deadlineDelayMs_);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length){return undefined;}
+return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger,};});'use strict';tr.exportTo('tr.model.helpers',function(){const AndroidApp=tr.model.helpers.AndroidApp;const AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;const IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};const IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};const IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important){callback(slice);}});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;const processes=model.getAllProcesses();for(let i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){const app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app){this.apps.push(app);}},this);}
+AndroidModelHelper.guid=tr.b.GUID.allocateSimple();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper,};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){if(new.target){throw new Error('Can\'t instantiate pure virtual class Slice');}
+tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bindId;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined){this.duration=opt_duration;}
+if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
+if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
+if(opt_argsStripped!==undefined){this.argsStripped=true;}}
+Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+parentSliceGroup.slices.indexOf(this);},get bindId(){return this.bind_id_;},findDescendentSlice(targetTitle){if(!this.subSlices){return undefined;}
+for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},get mostTopLevelSlice(){if(!this.parentSlice)return this;return this.parentSlice.mostTopLevelSlice;},getProcess(){const thread=this.parentContainer;if(thread&&thread.getProcess){return thread.getProcess();}
+return undefined;},get model(){const process=this.getProcess();if(process!==undefined){return this.getProcess().model;}
+return undefined;},*findTopmostSlicesRelativeToThisSlice(eventPredicate){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},iterateAllSubsequentSlices(callback,opt_this){const parentStack=[];let started=false;const topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){const curSlice=parentStack.pop();if(started){callback.call(opt_this,curSlice);}else{started=(curSlice.guid===this.guid);}
+for(let i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){const res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},*enumerateAllAncestors(){let curSlice=this.parentSlice;while(curSlice){yield curSlice;curSlice=curSlice.parentSlice;}},get ancestorSlices(){return Array.from(this.enumerateAllAncestors());},iterateEntireHierarchy(callback,opt_this){const mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){const res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){const res=[];res.push(this);for(const aSlice of this.enumerateAllAncestors()){res.push(aSlice);}
+this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){yield*slice.enumerateAllDescendents();}},get descendentSlices(){const res=[];for(const slice of this.enumerateAllDescendents()){res.push(slice);}
+return res;}};return{Slice,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;const SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_(state){const getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice(){if(!this.cpuOnWhichThreadWasRunning)return undefined;const cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(let i=0;i<cpuSlices.length;i++){const cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)continue;if(cpuSlice.duration!==this.duration)continue;return cpuSlice;}
+return undefined;},getCpuSliceThatTookCpu(){if(this.cpuOnWhichThreadWasRunning)return undefined;let curIndex=this.thread.indexOfTimeSlice(this);let cpuSliceWhenLastRunning;while(curIndex>=0){const curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
+cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
+if(!cpuSliceWhenLastRunning)return undefined;const cpu=cpuSliceWhenLastRunning.cpu;const indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);const nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001){return nextRunningSlice;}
+return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices'});return{ThreadTimeSlice,SCHEDULING_STATE,};});'use strict';tr.exportTo('tr.model',function(){const CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState,};});'use strict';tr.exportTo('tr.model.um',function(){const CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorType,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorType_=initiatorType;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
+const INITIATOR_TYPE={KEYBOARD:'Keyboard',MOUSE:'Mouse',MOUSE_WHEEL:'MouseWheel',TAP:'Tap',PINCH:'Pinch',FLING:'Fling',TOUCH:'Touch',SCROLL:'Scroll',CSS:'CSS',WEBGL:'WebGL',VIDEO:'Video'};UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState(selection){let cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this)){cess|=CompoundEventSelectionState.EVENT_SELECTED;}
+if(this.associatedEvents.intersectionIsEmpty(selection)){return cess;}
+const allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained){cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;}else{cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;}
+return cess;},get associatedSamples(){const samples=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event instanceof tr.model.ThreadSlice){samples.addEventSet(event.overlappingSamples);}});return samples;},get userFriendlyName(){return this.title+' User Expectation at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+this.guid);},get typeInfo(){if(!this.typeInfo_){this.typeInfo_=UserExpectation.subTypes.findTypeInfo(this.constructor);}
+if(!this.typeInfo_){throw new Error('Unregistered UserExpectation');}
+return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorType(){return this.initiatorType_;},get title(){if(!this.initiatorType){return this.stageTitle;}
+return this.initiatorType+' '+this.stageTitle;},get totalCpuMs(){let cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}};const subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(subTypes,options);subTypes.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
+if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'userExpectation',pluralName:'userExpectations',subTypes});return{UserExpectation,INITIATOR_TYPE,};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
+ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.subTypes.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation,};});'use strict';tr.exportTo('tr.e.audits',function(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;const Auditor=tr.c.Auditor;const AndroidModelHelper=tr.model.helpers.AndroidModelHelper;const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;const Alert=tr.model.Alert;const EventInfo=tr.model.EventInfo;const Scalar=tr.b.Scalar;const timeDurationInMs=tr.b.Unit.byName.timeDurationInMs;const EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+function getDuration(e){return e.duration;}
+function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
+function frameIsActivityStart(frame){return frame.associatedEvents.any(x=>x.title==='activityStart');}
+function frameMissedDeadline(frame){return frame.args.deadline&&frame.args.deadline<frame.end;}
+function DocLinkBuilder(){this.docLinks=[];}
+DocLinkBuilder.prototype={addAppVideo(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);const helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger){this.helper=helper;}}
+AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){const badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;const saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;const ret=[];const events=[];frame.associatedEvents.forEach(function(slice){const match=badAlphaRegEx.exec(slice.title);if(match){const args={'view name':match[1],'width':parseInt(match[3]),'height':parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title)){events.push(slice);}},this);if(events.length>ret.length){const unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});const clippedSeen=events.length-unclippedSeen;const earliestStart=Statistics.min(events,function(slice){return slice.start;});const args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){const uploadRegEx=/^Generate Path Texture$/;const events=frame.associatedEvents.filter(function(event){return event.title==='Generate Path Texture';});const start=Statistics.min(events,getStart);const duration=Statistics.sum(events,getDuration);if(duration<3)return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){const uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;const events=[];let start=Number.POSITIVE_INFINITY;let duration=0;let pixelsUploaded=0;frame.associatedEvents.forEach(function(event){const match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length===0||duration<3)return undefined;const mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';const args={'Pixels uploaded':mPixels,'Time spent':new Scalar(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='obtainView'||event.title==='setupListItem';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;let hasInflation=false;for(const event of events){if(event.findDescendentSlice('inflate')){hasInflation=true;}}
+const start=Statistics.min(events,getStart);const args={'Time spent':new Scalar(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;const eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='measure'||event.title==='layout';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){let slice=undefined;for(const event of frame.associatedEvents){if(event.title==='getDisplayList'||event.title==='Record View#draw()'){slice=event;break;}}
+if(!slice||getCpuDuration(slice)<3)return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new Scalar(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='DVM Suspend'||event.title==='GC: Wait For Concurrent';});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){let totalDuration=0;const totalStats={};for(const ttr of frame.threadTimeRanges){const stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);for(const[key,value]of Object.entries(stats)){if(!(key in totalStats)){totalStats[key]=0;}
+totalStats[key]+=value;totalDuration+=value;}}
+if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration===0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3){return;}
+const args={};for(const[key,value]of Object.entries(totalStats)){let newKey=key;if(key===SCHEDULING_STATE.RUNNABLE){newKey='Not scheduled, but runnable';}else if(key===SCHEDULING_STATE.UNINTR_SLEEP){newKey='Blocking I/O delay';}
+args[newKey]=new Scalar(timeDurationInMs,value);}
+return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process===this.helper.surfaceFlinger.process){if(!process.name){process.name='SurfaceFlinger';}
+process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
+const uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name)){uiThread.name='a'+uiThread.name;}
+process.name=uiThread.name;uiThread.name='UI Thread';}
+process.sortIndex=0;for(const tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid===thread.parent.pid){thread.sortIndex=-3;}
+if(thread.name==='RenderThread'){thread.sortIndex=-2;}
+if(/^hwuiTask/.test(thread.name)){thread.sortIndex=-1;}});},pushFramesAndJudgeJank_(){let badFramesObserved=0;let framesObserved=0;const surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){const portionBad=badFramesObserved/framesObserved;if(portionBad>0.3){this.model.faviconHue='red';}else if(portionBad>0.05){this.model.faviconHue='yellow';}else{this.model.faviconHue='green';}}},pushEventInfo_(){const appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread){appAnnotator.applyEventInfos(app.uiThread.sliceGroup);}
+if(app.renderThread){appAnnotator.applyEventInfos(app.renderThread.sliceGroup);}});},runAnnotate(){if(!this.helper)return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit(){if(!this.helper)return;const alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass===FRAME_PERF_CLASS.NEUTRAL||frame.perfClass===FRAME_PERF_CLASS.GOOD){return;}
+let alert=AndroidAuditor.getPathAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getUploadAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getListViewAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords(){const events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords(){const inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);const inputRanges=inputSamples.map(function(sample){return tr.b.math.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.math.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup=new Map();this.titleParentLookup=new Map();this.build_();}
+AppAnnotator.prototype={build_(){const registerEventInfo=function(dict){this.titleInfoLookup.set(dict.title,new EventInfo(dict.title,dict.description,dict.docLinks));if(dict.parents){this.titleParentLookup.set(dict.title,dict.parents);}}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});const choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});const traversalParents=['Choreographer#doFrame','performTraversals'];const layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});const drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});const recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_(parentNames,slice){const checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)return true;return expectedParentNames.some(function(name){return parentNames.has(name);});};if(this.titleInfoLookup.has(slice.title)){if(checkExpectedParentNames(this.titleParentLookup.get(slice.title))){slice.info=this.titleInfoLookup.get(slice.title);}}
+if(slice.subSlices.length>0){if(!parentNames.has(slice.title)){parentNames.set(slice.title,0);}
+parentNames.set(slice.title,parentNames.get(slice.title)+1);slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames.set(slice.title,parentNames.get(slice.title)-1);if(parentNames.get(slice.title)===0){delete parentNames[slice.title];}}},applyEventInfos(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_(new Map(),slice);},this);}};return{AndroidAuditor,};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize(){},initialize(){},referencedAt(item,object,field){},addBoundsToRange(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+this.objectInstance.userFriendlyName+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots'});return{ObjectSnapshot,};});'use strict';tr.exportTo('tr.model',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.math.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange(range){range.addRange(this.bounds);},addSnapshot(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs){throw new Error('Snapshots must be >= instance.creationTs');}
+if(ts>=this.deletionTs){throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');}
+let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts===ts){throw new Error('Snapshots already exists at this time!');}
+if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
+if(opt_name&&(this.name!==opt_name)){if(!opt_baseTypeName){throw new Error('Must provide base type name for name update');}
+if(this.baseTypeName!==opt_baseTypeName){throw new Error('Cannot update type name: base types dont match');}
+this.name=opt_name;}
+const snapshotConstructor=tr.model.ObjectSnapshot.subTypes.getConstructor(this.category,this.name);const snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted(ts){let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts){throw new Error('Instance cannot be deleted at ts='+
+ts+'. A snapshot exists that is older.');}}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].preInitialize();}},initialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].initialize();}},isAliveAt(ts){if(ts<this.creationTs&&this.creationTsWasExplicit){return false;}
+if(ts>this.deletionTs){return false;}
+return true;},getSnapshotAt(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit){throw new Error('ts must be within lifetime of this instance');}
+return this.snapshots[0];}
+if(ts>this.deletionTs){throw new Error('ts must be within lifetime of this instance');}
+const snapshots=this.snapshots;const i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i===snapshots.length-1){return snapshots[i].objectInstance.deletionTs;}
+return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
+if(i>=this.snapshots.length){return this.snapshots[this.snapshots.length-1];}
+return this.snapshots[i];},updateBounds(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!==Number.MAX_VALUE){this.bounds.addValue(this.deletionTs);}else if(this.snapshots.length>0){this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);}},shiftTimestampsForward(amount){this.creationTs+=amount;if(this.deletionTs!==Number.MAX_VALUE){this.deletionTs+=amount;}
+this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances'});return{ObjectInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function BlameContextSnapshot(){ObjectSnapshot.apply(this,arguments);}
+BlameContextSnapshot.prototype={__proto__:ObjectSnapshot.prototype,get parentContext(){if(this.args.parent instanceof BlameContextSnapshot){return this.args.parent;}
+return undefined;},get userFriendlyName(){return'BlameContext';}};function BlameContextInstance(){ObjectInstance.apply(this,arguments);}
+BlameContextInstance.prototype={__proto__:ObjectInstance.prototype,get blameContextType(){throw new Error('Not implemented');}};return{BlameContextSnapshot,BlameContextInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function FrameTreeNodeSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+FrameTreeNodeSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get renderFrame(){if(this.args.renderFrame instanceof tr.e.chrome.RenderFrameSnapshot){return this.args.renderFrame;}
+return undefined;},get url(){return this.args.url;},get userFriendlyName(){return'FrameTreeNode';}};tr.model.ObjectSnapshot.subTypes.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){BlameContextInstance.apply(this,arguments);}
+FrameTreeNodeInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot,FrameTreeNodeInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function RenderFrameSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+RenderFrameSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,referencedAt(item,object,field){if(item instanceof tr.e.chrome.FrameTreeNodeSnapshot&&object===item.args&&field==='renderFrame'){this.args.frameTreeNode=item;}},get frameTreeNode(){if(this.args.frameTreeNode instanceof
+tr.e.chrome.FrameTreeNodeSnapshot){return this.args.frameTreeNode;}
+return undefined;},get url(){if(this.frameTreeNode){return this.frameTreeNode.url;}
+return undefined;},get userFriendlyName(){return'RenderFrame';}};tr.model.ObjectSnapshot.subTypes.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){BlameContextInstance.apply(this,arguments);}
+RenderFrameInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot,RenderFrameInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function TopLevelSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+TopLevelSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get userFriendlyName(){return'TopLevel';}};tr.model.ObjectSnapshot.subTypes.register(TopLevelSnapshot,{typeName:'TopLevel'});function TopLevelInstance(){BlameContextInstance.apply(this,arguments);}
+TopLevelInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'TopLevel';}};tr.model.ObjectInstance.subTypes.register(TopLevelInstance,{typeName:'TopLevel'});return{TopLevelSnapshot,TopLevelInstance,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
+if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
+if(opt_argsStripped!==undefined){this.argsStripped=opt_argsStripped;}}
+AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(let i=0;i<this.subSlices.length;i++){const subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined){subSlice.parentContainer=parentContainer;}}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},*findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},findDescendentSlice(targetTitle){if(!this.subSlices)return undefined;for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){yield*slice.enumerateAllDescendents();}},compareTo(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices'});return{AsyncSlice,};});'use strict';tr.exportTo('tr.model.helpers',function(){const MAIN_FRAMETIME_TYPE='main_frametime_type';const IMPL_FRAMETIME_TYPE='impl_frametime_type';const MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';const IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){const slicesInFilterRange=[];for(let i=0;i<slices.length;i++){const slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end)){slicesInFilterRange.push(slice);}}
+return slicesInFilterRange;}
+function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;this.telemetryInternalRanges_=undefined;}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},isTelemetryInternalEvent(slice){if(this.telemetryInternalRanges_===undefined){this.findTelemetryInternalRanges_();}
+for(const range of this.telemetryInternalRanges_){if(range.containsExplicitRangeInclusive(slice.start,slice.end)){return true;}}
+return false;},findTelemetryInternalRanges_(){this.telemetryInternalRanges_=[];let start=0;for(const thread of Object.values(this.process.threads)){for(const slice of thread.asyncSliceGroup.getDescendantEvents()){if(/^telemetry\.internal\.[^.]*\.start$/.test(slice.title)){start=slice.start;}else if(/^telemetry\.internal\.[^.]*\.end$/.test(slice.title)&&start!==undefined){this.telemetryInternalRanges_.push(tr.b.math.Range.fromExplicitRange(start,slice.end));start=undefined;}}}},getFrameEventsInRange(frametimeType,range){const titleToGet=(frametimeType===MAIN_FRAMETIME_TYPE?MAIN_RENDERING_STATS:IMPL_RENDERING_STATS);const frameEvents=[];for(const event of this.process.getDescendantEvents()){if(event.title===titleToGet){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){frameEvents.push(event);}}}
+frameEvents.sort(function(a,b){return a.start-b.start;});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){const frametimeData=[];for(let i=1;i<frameEvents.length;i++){const diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+return frametimeData;}
+return{ChromeProcessHelper,MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS,IMPL_RENDERING_STATS,getSlicesIntersectingRange,getFrametimeDataFromEvents,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');if(!process.name){process.name=ChromeBrowserHelper.PROCESS_NAME;}}
+ChromeBrowserHelper.PROCESS_NAME='Browser';ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get browserName(){const hasInProcessRendererThread=this.process.findAllThreadsNamed('Chrome_InProcRendererThread').length>0;return hasInProcessRendererThread?'webview':'chrome';},get mainThread(){return this.mainThread_;},get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){let hasLatency=false;for(const thread of this.modelHelper.model.getAllThreads()){for(const event of thread.getDescendantEvents()){if(!event.isTopLevel)continue;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){continue;}
+hasLatency=true;}}
+return hasLatency;},getLatencyEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching(pred,opt_this){const events=[];this.iterAllThreads(function(thread){for(const slice of thread.getDescendantEvents()){if(pred.call(opt_this,slice)){events.push(slice);}}});return events;},iterAllThreads(func,opt_this){for(const thread of Object.values(this.process.threads)){func.call(opt_this,thread);}
+for(const rendererHelper of Object.values(this.rendererHelpers)){const rendererProcess=rendererHelper.process;for(const thread of Object.values(rendererProcess.threads)){func.call(opt_this,thread);}}}};return{ChromeBrowserHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);if(!process.name){process.name=ChromeGpuHelper.PROCESS_NAME;}}
+ChromeGpuHelper.PROCESS_NAME='GPU Process';ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain')){return false;}
+return process.findAllThreadsNamed('CrGpuMain').length>0;};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype};return{ChromeGpuHelper,};});'use strict';tr.exportTo('tr.b',function(){function SinebowColorGenerator(opt_a,opt_brightness){this.a_=(opt_a===undefined)?1:opt_a;this.brightness_=(opt_brightness===undefined)?1:opt_brightness;this.colorIndex_=0;this.keyToColor={};}
+SinebowColorGenerator.prototype={colorForKey(key){if(!this.keyToColor[key]){this.keyToColor[key]=this.nextColor();}
+return this.keyToColor[key];},nextColor(){const components=SinebowColorGenerator.nthColor(this.colorIndex_++);return tr.b.Color.fromString(SinebowColorGenerator.calculateColor(components[0],components[1],components[2],this.a_,this.brightness_));}};SinebowColorGenerator.PHI=(1+Math.sqrt(5))/2;SinebowColorGenerator.sinebow_=function(h){h+=0.5;h=-h;let r=Math.sin(Math.PI*h);let g=Math.sin(Math.PI*(h+1/3));let b=Math.sin(Math.PI*(h+2/3));r*=r;g*=g;b*=b;const y=2*(0.2989*r+0.5870*g+0.1140*b);r/=y;g/=y;b/=y;return[256*r,256*g,256*b];};SinebowColorGenerator.nthColor=function(n){return SinebowColorGenerator.sinebow_(n*this.PHI);};SinebowColorGenerator.calculateColor=function(r,g,b,a,brightness){if(brightness<=1){r*=brightness;g*=brightness;b*=brightness;}else{r=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),r,255);g=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),g,255);b=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),b,255);}
+r=Math.round(r);g=Math.round(g);b=Math.round(b);return'rgba('+r+','+g+','+b+', '+a+')';};return{SinebowColorGenerator,};});'use strict';tr.exportTo('tr.e.chrome',function(){const SAME_AS_PARENT='same-as-parent';const TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser','HTMLDocumentParser::processTokenizedChunkFromBackgroundParser',],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['v8.parseOnBackground','V8.ScriptCompiler'],script_execute:['V8.Execute','WindowProxy::initialize'],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],v8_runtime:[],[SAME_AS_PARENT]:['SyncChannel::Send']};const COLOR_FOR_USER_FRIENDLY_CATEGORY=new tr.b.SinebowColorGenerator();const USER_FRIENDLY_CATEGORY_FOR_TITLE=new Map();for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE.set(title,category);});}
+const USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
+ChromeUserFriendlyCategoryDriver.fromEvent=function(event){let userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE.get(event.title);if(userFriendlyCategory){if(userFriendlyCategory===SAME_AS_PARENT){if(event.parentSlice){return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}}else{return userFriendlyCategory;}}
+const eventCategoryParts=tr.b.getCategoryParts(event.category);for(let i=0;i<eventCategoryParts.length;++i){const eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory){return userFriendlyCategory;}}
+return'other';};ChromeUserFriendlyCategoryDriver.getColor=function(ufc){return COLOR_FOR_USER_FRIENDLY_CATEGORY.colorForKey(ufc);};ChromeUserFriendlyCategoryDriver.ALL_TITLES=['other'];for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){if(category===SAME_AS_PARENT)continue;ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+for(const category of Object.values(USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY)){ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+ChromeUserFriendlyCategoryDriver.ALL_TITLES.sort();for(const category of ChromeUserFriendlyCategoryDriver.ALL_TITLES){ChromeUserFriendlyCategoryDriver.getColor(category);}
+return{ChromeUserFriendlyCategoryDriver,};});'use strict';tr.exportTo('tr.model.helpers',function(){const NET_CATEGORIES=new Set(['net','netlog','disabled-by-default-netlog','disabled-by-default-network']);class ChromeThreadHelper{constructor(thread){this.thread=thread;}
+getNetworkEvents(){const networkEvents=[];for(const slice of this.thread.asyncSliceGroup.slices){const categories=tr.b.getCategoryParts(slice.category);const isNetEvent=category=>NET_CATEGORIES.has(category);if(categories.filter(isNetEvent).length===0)continue;networkEvents.push(slice);}
+return networkEvents;}}
+return{ChromeThreadHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const ChromeThreadHelper=tr.model.helpers.ChromeThreadHelper;function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.indexOf('CompositorTileWorker')===0)return true;if(t.name.indexOf('CompositorRasterWorker')===0)return true;return false;});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
+ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeBrowserHelper.isBrowserProcess);}
+function findChromeRenderProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeRendererHelper.isRenderProcess);}
+function findChromeGpuProcess(model){const gpuProcesses=model.getAllProcesses(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!==1)return undefined;return gpuProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;const browserProcesses=findChromeBrowserProcesses(model);this.browserHelpers_=browserProcesses.map(p=>new tr.model.helpers.ChromeBrowserHelper(this,p));const gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+const rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){const rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);this.chromeBounds_=undefined;}
+ChromeModelHelper.guid=tr.b.GUID.allocateSimple();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcesses(model).length)return true;if(findChromeRenderProcesses(model).length)return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){if(this.browserHelper===undefined)return undefined;return this.browserHelper.process;},get browserHelper(){return this.browserHelpers_[0];},get browserHelpers(){return this.browserHelpers_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;},get rendererWithLargestPid(){let largestPid=-1;for(const pid in this.rendererHelpers){const rendererHelper=this.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;if(pid>largestPid)largestPid=pid;}
+if(largestPid===-1)return undefined;return this.rendererHelpers[largestPid];},get chromeBounds(){if(!this.chromeBounds_){this.chromeBounds_=new tr.b.math.Range();for(const browserHelper of
+Object.values(this.browserHelpers)){this.chromeBounds_.addRange(browserHelper.process.bounds);}}
+if(this.chromeBounds_.isEmpty){return undefined;}
+return this.chromeBounds_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){const AsyncSlice=tr.model.AsyncSlice;const EventSet=tr.model.EventSet;const UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';const ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';const BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';const END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';const MAIN_RENDERER_THREAD_NAME='CrRendererMain';const COMPOSITOR_THREAD_NAME='Compositor';const POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';const IPC_FLOW_EVENT='disabled-by-default-ipc.flow';const INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
+InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_){this.determineLegacyTypeName_();}
+return this.typeName_;},checkTypeName_(){if(!this.typeName_){throw new Error('Unable to determine typeName');}
+let found=false;for(const typeName in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[typeName]){found=true;break;}}
+if(!found){this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;}},determineModernTypeName_(){const lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)return;const characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_(){for(const subSlice of this.enumerateAllDescendents()){const subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)continue;if(!subSlice.typeName)continue;if(this.typeName_&&subSlice.typeName_){const subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames');}}
+this.typeName_=subSlice.typeName_;}
+if(!this.typeName_){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() failed');}
+this.checkTypeName_();},getRendererHelper(sourceSlices){const traceModel=this.startThread.parent.model;const modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)return undefined;let mainThread=undefined;let compositorThread=undefined;for(const i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME){mainThread=sourceSlices[i].parentContainer;}else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME){compositorThread=sourceSlices[i].parentContainer;}
+if(mainThread&&compositorThread)break;}
+const rendererHelpers=modelHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(let i=0;i<pids.length;i++){const pid=pids[i];const rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread){return rendererHelper;}}
+return undefined;},addEntireSliceHierarchy(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents(flowEvents){const slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);const newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1){slices.push(newSource);}},this);const lastFlowEvent=flowEvents[flowEvents.length-1];const lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1){slices.push(lastSource);}
+return slices;},addScrollUpdateEvents(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread){return;}
+const compositorThread=rendererHelper.compositorThread;const gestureScrollUpdateStart=this.start;const gestureScrollUpdateEnd=this.end;const allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(const i in allCompositorAsyncSlices){const slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')continue;const parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd){continue;}}else{if(parseInt(parentId)!==parseInt(this.id)){continue;}}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs(slice,flowEvents){let fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1){fromOtherInputs=true;}}},this);},this);return fromOtherInputs;},triggerOtherInputs(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0){return false;}
+const flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice){return false;}
+const endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents)){return true;}
+return false;},followSubsequentSlices(event,queue,visited,flowEvents){let stopFollowing=false;let inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)return;if(slice.title==='TaskQueueManager::RunTask')return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame'){return;}
+if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))return;}
+if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))return;}
+if(slice.title==='InputRouterImpl::ProcessInputEventAck'){inputAck=true;}
+if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent'){stopFollowing=true;}
+this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);const nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw(beginImplFrame,visited){const pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){const nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
+return a.guid-b.guid;});},addRasterizationEvents(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads){return;}
+const rasterWorkerThreads=rendererHelper.rasterWorkerThreads;const prepareTileId=prepareTiles.args.prepare_tiles_id;const pendingEventQueue=[];if(sortedRasterizerSlices.length===0){this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);}
+let numFinishedTasks=0;const RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';const IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';const FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(let i=0;i<sortedRasterizerSlices.length;i++){const task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepareTileId){this.addEntireSliceHierarchy(task.mostTopLevelSlice);}}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)break;}}}
+while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){const pendingEventQueue=[];const visitedEvents=new EventSet();let beginImplFrame=undefined;let prepareTiles=undefined;sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);const COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles){this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);}
+const COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame){this.backtraceFromDraw(beginImplFrame,visitedEvents);}}
+const INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU){this.addScrollUpdateEvents(rendererHelper);}},get associatedEvents(){if(this.associatedEvents_.length!==0){return this.associatedEvents_;}
+const modelIndices=this.startThread.parent.model.modelIndices;const flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0){return this.associatedEvents_;}
+const sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);const rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))return undefined;const data=this.args.data;if(!(END_COMP_NAME in data))return undefined;let latency=0;const endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};const eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];const allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.subTypes.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES,};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr',LOCAL_ID_PHASES:new Set(['N','D','O','(',')'])};});'use strict';tr.exportTo('tr.e.audits',function(){const Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);const modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}}
+ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate(){if(!this.modelHelper)return;for(const pid in this.modelHelper.rendererHelpers){const rendererHelper=this.modelHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI){rendererHelper.process.important=false;}}},installUserFriendlyCategoryDriverIfNeeded(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit(){if(!this.modelHelper)return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor,};});'use strict';tr.exportTo('tr.e.chrome',function(){const KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.math.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.math.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds){this.needsLayoutReasons_.push('self');}
+if(args.childNeeds){this.needsLayoutReasons_.push('child');}
+if(args.posChildNeeds){this.needsLayoutReasons_.push('positionedChild');}
+if(args.positionedMovement){this.needsLayoutReasons_.push('positionedMovement');}
+this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
+for(const property in args){if(!KNOWN_PROPERTIES[property]){this.otherProperties_[property]=args[property];}}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){const names=[];for(const name in this.otherProperties_){names.push(name);}
+return names;},getProperty(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
+LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.subTypes.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
+LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.subTypes.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});return{LayoutTreeInstance,LayoutTreeSnapshot,};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocateSimple();this.important=true;this.bounds_=new tr.b.math.Range();}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds(){throw new Error('Not implemented');},shiftTimestampsForward(amount){throw new Error('Not implemented');},*childEvents(){},*getDescendantEvents(){yield*this.childEvents();for(const container of this.childEventContainers()){yield*container.getDescendantEvents();}},*childEventContainers(){},*getDescendantEventContainers(){yield this;for(const container of this.childEventContainers()){yield*container.getDescendantEventContainers();}},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){},*findTopmostSlices(eventPredicate){for(const ec of this.getDescendantEventContainers()){yield*ec.findTopmostSlicesInThisContainer(eventPredicate);}},*findTopmostSlicesNamed(name){yield*this.findTopmostSlices(e=>e.title===name);}};return{EventContainer,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;class ResourceUsageSample extends Event{constructor(series,start,usage){super();this.series_=series;this.start_=start;this.usage_=usage;}
+get series(){return this.series_;}
+get start(){return this.start_;}
+set start(value){this.start_=value;}
+get usage(){return this.usage_;}
+set usage(value){this.usage_=value;}
+addBoundsToRange(range){range.addValue(this.start);}}
+EventRegistry.register(ResourceUsageSample,{name:'resourceUsageSample',pluralName:'resourceUsageSamples'});return{ResourceUsageSample,};});'use strict';tr.exportTo('tr.model',function(){const ResourceUsageSample=tr.model.ResourceUsageSample;class ResourceUsageSeries extends tr.model.EventContainer{constructor(device){super();this.device_=device;this.samples_=[];}
+get device(){return this.device_;}
+get samples(){return this.samples_;}
+get stableId(){return this.device_.stableId+'.ResourceUsageSeries';}
+addUsageSample(ts,val){const sample=new ResourceUsageSample(this,ts,val);this.samples_.push(sample);return sample;}
+computeResourceTimeConsumedInMs(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let resourceTimeInMs=0;let startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0)startIndex=0;for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);resourceTimeInMs+=intersectionRangeInMs.duration*sample.usage;}
+return resourceTimeInMs;}
+getSamplesWithinRange(start,end){const startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);}
+shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}}
+updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);}*childEvents(){yield*this.samples_;}}
+return{ResourceUsageSeries,};});'use strict';tr.exportTo('tr.e.audits',function(){class CpuUsageAuditor extends tr.c.Auditor{constructor(model){super();this.model_=model;}
+runAnnotate(){this.model_.device.cpuUsageSeries=this.computeCpuUsageSeries_(this.model_.bounds.min,this.model_.bounds.max,this.computeCpuUsage_());}
+computeBinSize_(start,end){const MIN_BIN_SIZE_MS=1.0;const MAX_NUM_BINS=100000;const interval=end-start;let binSize=MIN_BIN_SIZE_MS;while(binSize*MAX_NUM_BINS<interval)binSize*=2;return binSize;}
+computeCpuUsageSeries_(start,end,usageRecords){const series=new tr.model.ResourceUsageSeries();if(start===undefined||usageRecords.length===0)return series;const binSize=this.computeBinSize_(start,end);const numBins=Math.ceil((end-start)/binSize);const arr=new Array(numBins).fill(0);for(const record of usageRecords){const firstIndex=Math.ceil((record.start-start)/binSize);const lastIndex=Math.floor((record.end-start)/binSize);for(let i=firstIndex;i<=lastIndex;i++)arr[i]+=record.usage;}
+for(let i=0;i<numBins;i++){series.addUsageSample(start+(i*binSize),arr[i]);}
+return series;}
+computeCpuUsage_(){const model=this.model_;const result=[];for(const pid in model.processes){for(const e of model.processes[pid].getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration===0||e.cpuDuration===undefined){continue;}
+if(e.selfTime===0||e.selfTime===undefined||e.cpuSelfTime===undefined){continue;}
+const usage=tr.b.math.clamp(e.cpuSelfTime/e.selfTime,0,1);let lastTime=e.start;for(const subslice of e.subSlices){result.push({usage,start:lastTime,end:subslice.start});lastTime=subslice.end;}
+result.push({usage,start:lastTime,end:e.end});}}
+return result;}}
+tr.c.Auditor.register(CpuUsageAuditor);return{CpuUsageAuditor};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+function b64ToUint6(nChr){if(nChr>64&&nChr<91)return nChr-65;if(nChr>96&&nChr<123)return nChr-71;if(nChr>47&&nChr<58)return nChr+4;if(nChr===43)return 62;if(nChr===47)return 63;return 0;}
+Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){let binary='';const bytes=new Uint8Array(input);const len=bytes.byteLength;for(let i=0;i<len;i++){binary+=String.fromCharCode(bytes[i]);}
+return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){const nInLen=input.length;const nOutLen=nInLen*3+1>>2;let nMod3=0;let nMod4=0;let nUint24=0;let nOutIdx=0;if(nOutLen>output.byteLength){throw new Error('Output buffer too small to decode.');}
+for(let nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+nUint24=0;}}
+return nOutIdx-1;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';const kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version!==2){throw new Error('Incompatible EventTrace event version.');}
+const bufferSize=decoder.decodeUInt32();const version=decoder.decodeUInt32();const providerVersion=decoder.decodeUInt32();const numberOfProcessors=decoder.decodeUInt32();const endTime=decoder.decodeUInt64ToString();const timerResolution=decoder.decodeUInt32();const maxFileSize=decoder.decodeUInt32();const logFileMode=decoder.decodeUInt32();const buffersWritten=decoder.decodeUInt32();const startBuffers=decoder.decodeUInt32();const pointerSize=decoder.decodeUInt32();const eventsLost=decoder.decodeUInt32();const cpuSpeed=decoder.decodeUInt32();const loggerName=decoder.decodeUInteger(header.is64);const logFileName=decoder.decodeUInteger(header.is64);const timeZoneInformation=decoder.decodeTimeZoneInformation();const padding=decoder.decodeUInt32();const bootTime=decoder.decodeUInt64ToString();const perfFreq=decoder.decodeUInt64ToString();const startTime=decoder.decodeUInt64ToString();const reservedFlags=decoder.decodeUInt32();const buffersLost=decoder.decodeUInt32();const sessionNameString=decoder.decodeW16String();const logFileNameString=decoder.decodeW16String();return{bufferSize,version,providerVersion,numberOfProcessors,endTime,timerResolution,maxFileSize,logFileMode,buffersWritten,startBuffers,pointerSize,eventsLost,cpuSpeed,loggerName,logFileName,timeZoneInformation,bootTime,perfFreq,startTime,reservedFlags,buffersLost,sessionNameString,logFileNameString};},decodeHeader(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';const kProcessStartOpcode=1;const kProcessEndOpcode=2;const kProcessDCStartOpcode=3;const kProcessDCEndOpcode=4;const kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>5){throw new Error('Incompatible Process event version.');}
+let pageDirectoryBase;if(header.version===1){pageDirectoryBase=decoder.decodeUInteger(header.is64);}
+let uniqueProcessKey;if(header.version>=2){uniqueProcessKey=decoder.decodeUInteger(header.is64);}
+const processId=decoder.decodeUInt32();const parentId=decoder.decodeUInt32();let sessionId;let exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+let directoryTableBase;if(header.version>=3){directoryTableBase=decoder.decodeUInteger(header.is64);}
+let flags;if(header.version>=4){flags=decoder.decodeUInt32();}
+const userSID=decoder.decodeSID(header.is64);let imageFileName;if(header.version>=1){imageFileName=decoder.decodeString();}
+let commandLine;if(header.version>=2){commandLine=decoder.decodeW16String();}
+let packageFullName;let applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+let exitTime;if(header.version===5&&header.opcode===kProcessDefunctOpcode){exitTime=decoder.decodeUInt64ToString();}
+return{pageDirectoryBase,uniqueProcessKey,processId,parentId,sessionId,exitStatus,directoryTableBase,flags,userSID,imageFileName,commandLine,packageFullName,applicationId,exitTime};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadStartOpcode=1;const kThreadEndOpcode=2;const kThreadDCStartOpcode=3;const kThreadDCEndOpcode=4;const kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>3){throw new Error('Incompatible Thread event version.');}
+const processId=decoder.decodeUInt32();const threadId=decoder.decodeUInt32();let stackBase;let stackLimit;let userStackBase;let userStackLimit;let affinity;let startAddr;let win32StartAddr;let tebBase;let subProcessTag;let basePriority;let pagePriority;let ioPriority;let threadFlags;let waitMode;if(header.version===1){if(header.opcode===kThreadStartOpcode||header.opcode===kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version===2){startAddr=decoder.decodeUInteger(header.is64);}else{affinity=decoder.decodeUInteger(header.is64);}
+win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version===3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
+return{processId,threadId,stackBase,stackLimit,userStackBase,userStackLimit,affinity,startAddr,win32StartAddr,tebBase,subProcessTag,waitMode,basePriority,pagePriority,ioPriority,threadFlags};},decodeCSwitchFields(header,decoder){if(header.version!==2){throw new Error('Incompatible Thread event version.');}
+const newThreadId=decoder.decodeUInt32();const oldThreadId=decoder.decodeUInt32();const newThreadPriority=decoder.decodeInt8();const oldThreadPriority=decoder.decodeInt8();const previousCState=decoder.decodeUInt8();const spareByte=decoder.decodeInt8();const oldThreadWaitReason=decoder.decodeInt8();const oldThreadWaitMode=decoder.decodeInt8();const oldThreadState=decoder.decodeInt8();const oldThreadWaitIdealProcessor=decoder.decodeInt8();const newThreadWaitTime=decoder.decodeUInt32();const reserved=decoder.decodeUInt32();return{newThreadId,oldThreadId,newThreadPriority,oldThreadPriority,previousCState,spareByte,oldThreadWaitReason,oldThreadWaitMode,oldThreadState,oldThreadWaitIdealProcessor,newThreadWaitTime,reserved};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch(header,decoder){const fields=this.decodeCSwitchFields(header,decoder);const cpu=this.importer.getOrCreateCpu(header.cpu);const newThread=this.importer.getThreadFromWindowsTid(fields.newThreadId);let newThreadName;if(newThread&&newThread.userFriendlyName){newThreadName=newThread.userFriendlyName;}else{const newProcessId=this.importer.getPidFromWindowsTid(fields.newThreadId);const newProcess=this.model.getProcess(newProcessId);let newProcessName;if(newProcess){newProcessName=newProcess.name;}else{newProcessName='Unknown process';}
+newThreadName=newProcessName+' (tid '+fields.newThreadId+')';}
+cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,newThreadName,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser,};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return Math.max(a,b);}
+function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
+IntervalTree.prototype={insert(datum){const startPosition=this.beginPositionCb_(datum);const endPosition=this.endPositionCb_(datum);const node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_(root,node){if(root===undefined)return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed){this.flipNodeColour_(root);}
+if(node.key<root.key){root.leftNode=this.insertNode_(root.leftNode,node);}else if(node.key===root.key){root.merge(node);}else{root.rightNode=this.insertNode_(root.rightNode,node);}
+if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed)){root=this.rotateLeft_(root);}
+if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed){root=this.rotateRight_(root);}
+return root;},rotateRight_(node){const sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_(node){const sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues(){this.updateHighValues_(this.root_);},updateHighValues_(node){if(node===undefined)return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined){throw new Error('queryLow and queryHigh must be defined');}
+if((typeof queryLow!=='number')||(typeof queryHigh!=='number')){throw new Error('queryLow and queryHigh must be numbers');}},findIntersection(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)return[];const ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_(){if(this.root_===undefined)return[];return this.root_.dump();}};const Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.highValue>queryLow){for(let i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge(node){for(let i=0;i<node.data.length;i++){this.data_.push(node.data[i]);}
+this.data_.sort(function(a,b){return a.high-b.high;});},dump(){const ret={};if(this.leftNode_){ret.left=this.leftNode_.dump();}
+ret.data=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_){ret.right=this.rightNode_.dump();}
+return ret;}};return{IntervalTree,};});'use strict';tr.exportTo('tr.b.math',function(){const tmpVec2s=[];for(let i=0;i<8;i++){tmpVec2s[i]=vec2.create();}
+const tmpVec2a=vec4.create();const tmpVec4a=vec4.create();const tmpVec4b=vec4.create();const tmpMat4=mat4.create();const tmpMat4b=mat4.create();const p00=vec2.createXY(0,0);const p10=vec2.createXY(1,0);const p01=vec2.createXY(0,1);const p11=vec2.createXY(1,1);const lerpingVecA=vec2.create();const lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
+Quad.fromXYWH=function(x,y,w,h){const q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;};Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);};Quad.from4Vecs=function(p1,p2,p3,p4){const q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;};Quad.from8Array=function(arr){if(arr.length!==8){throw new Error('Array must be 8 long');}
+const q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect(){const x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);const x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.math.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone(){const q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale(s){const q=new Quad();this.scaleFast(q,s);return q;},scaleFast(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle(){const bounds=this.boundingRect();return(bounds.x===this.p1[0]&&bounds.y===this.p1[1]&&bounds.width===this.p2[0]-this.p1[0]&&bounds.y===this.p2[1]&&bounds.width===this.p3[0]-this.p1[0]&&bounds.height===this.p3[1]-this.p2[1]&&bounds.x===this.p4[0]&&bounds.height===this.p4[1]-this.p2[1]);},projectUnitRect(rect){const q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast(dstQuad,rect){const v12=tmpVec2s[0];const v14=tmpVec2s[1];const v23=tmpVec2s[2];const v43=tmpVec2s[3];vec2.sub(v12,this.p2,this.p1);const l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);const l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);const l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);const l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);const b12=tmpVec2s[0];const b14=tmpVec2s[1];const b23=tmpVec2s[2];const b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString(){return'Quad('+
+vec2.toString(this.p1)+', '+
+vec2.toString(this.p2)+', '+
+vec2.toString(this.p3)+', '+
+vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
+(p2[0]-p3[0])*(p1[1]-p3[1]);}
+function pointInTriangle2(pt,p1,p2,p3){const b1=sign(pt,p1,p2)<0.0;const b2=sign(pt,p2,p3)<0.0;const b3=sign(pt,p3,p1)<0.0;return((b1===b2)&&(b2===b3));}
+function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
+return{pointInTriangle2,pointInImplicitQuad,Quad,};});'use strict';tr.exportTo('tr.b',function(){const ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;const REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;const recordRAFStacks=false;let pendingPreAFs=[];let pendingRAFs=[];const pendingIdleCallbacks=[];let currentRAFDispatchList=undefined;let rafScheduled=false;let idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{const delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
+function nativeRequestIdleCallbackSupported(){return!tr.isHeadless&&window.requestIdleCallback;}
+function scheduleIdleWork(){if(idleWorkScheduled)return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
+idleWorkScheduled=true;window.requestIdleCallback(function(deadline,didTimeout){processIdleWork(false,deadline);},{timeout:REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS});}
+function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)throw e;if(opt_stack)console.log(opt_stack);if(e.message){console.error(e.message,e.stack);}else{console.error(e);}}
+function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
+function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;const currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];const hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(let i=0;i<currentPreAFs.length;i++){runTask(currentPreAFs[i],frameBeginTime);}
+while(currentRAFDispatchList.length>0){runTask(currentRAFDispatchList.shift(),frameBeginTime);}
+currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){const rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining(){return rafCompletionDeadline-window.performance.now();}});}
+if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
+function processIdleWork(forceAllTasksToRun,deadline){idleWorkScheduled=false;while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(!forceAllTasksToRun&&(tr.isHeadless||deadline.timeRemaining()<=0)){break;}}
+if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
+function getStack_(){if(!recordRAFStacks)return'';const stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
+currentRAFDispatchList.push({callback,context:opt_this||global,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function animationFrame(){return new Promise(resolve=>requestAnimationFrame(resolve));}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
+function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)return;processRequests(false,frameBeginTime);}
+function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)return;processRequests(true,0);}
+function timeout(ms){return new Promise(resolve=>window.setTimeout(resolve,ms));}
+function idle(){return new Promise(resolve=>requestIdleCallback(resolve));}
+return{animationFrame,forceAllPendingTasksToRunForTest,forcePendingRAFTasksToRun,idle,onAnimationFrameError,requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible,requestIdleCallback,requestPreAnimationFrame,timeout,};});'use strict';tr.exportTo('tr.b',function(){class Mark{constructor(groupName,functionName){if(tr.isHeadless)return;this.groupName_=groupName;this.functionName_=functionName;const guid=tr.b.GUID.allocateSimple();this.measureName_=`${groupName} ${functionName}`;this.startMarkName_=`${this.measureName} ${guid} start`;this.endMarkName_=`${this.measureName} ${guid} end`;window.performance.mark(this.startMarkName_);}
+get groupName(){return this.groupName_;}
+get functionName(){return this.functionName_;}
+get measureName(){return this.measureName_;}
+get startMark(){return tr.b.getOnlyElement(window.performance.getEntriesByName(this.startMarkName_));}
+get endMark(){return tr.b.getOnlyElement(window.performance.getEntriesByName(this.endMarkName_));}
+get durationMs(){return this.endMark.startTime-this.startMark.startTime;}
+end(){if(tr.isHeadless)return;window.performance.mark(this.endMarkName_);window.performance.measure(this.measureName_,this.startMarkName_,this.endMarkName_);if(!(window.ga instanceof Function))return;ga('send',{hitType:'event',eventCategory:this.groupName,eventAction:this.functionName,eventValue:this.durationMs,});}}
+class Timing{static mark(groupName,functionName){return new Mark(groupName,functionName);}
+static instant(groupName,functionName,opt_value){const valueString=opt_value===undefined?'':' '+opt_value;if(console&&console.timeStamp){console.timeStamp(`${groupName} ${functionName}${valueString}`);}
+if(window&&window.ga instanceof Function){ga('send',{hitType:'event',eventCategory:groupName,eventAction:functionName,eventValue:opt_value,});}}}
+return{Timing,};});'use strict';tr.exportTo('tr.b',function(){const Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined&&runCb.prototype!==undefined){throw new Error('Almost certainly you meant to pass a bound callback '+'or thisArg.');}
+this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];this.updatesUi_=false;}
+Task.prototype={get name(){return this.runCb_.name;},set updatesUi(value){this.updatesUi_=value;},subTask(cb,thisArg){if(cb instanceof Task){this.subTasks_.push(cb);}else{this.subTasks_.push(new Task(cb,thisArg));}
+return this.subTasks_[this.subTasks_.length-1];},run(){if(this.runCb_!==undefined)this.runCb_.call(this.thisArg_,this);const subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)return this.afterTask_;for(let i=1;i<subTasks.length;i++){subTasks[i-1].afterTask_=subTasks[i];}
+subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after(cb,thisArg){if(this.afterTask_){throw new Error('Has an after task already');}
+if(cb instanceof Task){this.afterTask_=cb;}else{this.afterTask_=new Task(cb,thisArg);}
+return this.afterTask_;},enqueue(cb,thisArg){if(!this.afterTask_)return this.after(cb,thisArg);return this.afterTask_.enqueue(cb,thisArg);}};Task.RunSynchronously=function(task){let curTask=task;while(curTask){curTask=curTask.run();}};Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){let curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);return;}
+if(curTask){if(curTask.updatesUi_){tr.b.requestAnimationFrameInThisFrameIfPossible(runAnother);}else{tr.b.requestIdleCallback(runAnother);}
+return;}
+resolve();}
+tr.b.requestIdleCallback(runAnother);});};return{Task,};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
+function Filter(){}
+Filter.prototype={__proto__:Object.prototype,matchCounter(counter){return true;},matchCpu(cpu){return true;},matchProcess(process){return true;},matchSlice(slice){return true;},matchThread(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length){throw new Error('Filter text is empty.');}}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){if(slice.title===undefined&&slice.category===undefined){return false;}
+return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length){throw new Error('Filter text is empty.');}}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_(obj){for(const key in obj){if(!obj.hasOwnProperty(key))continue;if(this.regex_.test(key))return true;if(this.regex_.test(obj[key]))return true;}
+return false;},matchSlice(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))return true;return this.matchObject_(slice.args);}};return{Filter,TitleOrCategoryFilter,ExactTitleFilter,FullTextFilter,};});'use strict';tr.exportTo('tr.model',function(){const ClockDomainId={BATTOR:'BATTOR',UNKNOWN_CHROME_LEGACY:'UNKNOWN_CHROME_LEGACY',LINUX_CLOCK_MONOTONIC:'LINUX_CLOCK_MONOTONIC',LINUX_FTRACE_GLOBAL:'LINUX_FTRACE_GLOBAL',MAC_MACH_ABSOLUTE_TIME:'MAC_MACH_ABSOLUTE_TIME',WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME',WIN_QPC:'WIN_QPC',SYSTRACE:'SYSTRACE',TELEMETRY:'TELEMETRY'};const POSSIBLE_CHROME_CLOCK_DOMAINS=new Set([ClockDomainId.UNKNOWN_CHROME_LEGACY,ClockDomainId.LINUX_CLOCK_MONOTONIC,ClockDomainId.MAC_MACH_ABSOLUTE_TIME,ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME,ClockDomainId.WIN_QPC]);const BATTOR_FAST_SYNC_THRESHOLD_MS=3;function ClockSyncManager(){this.domainsSeen_=new Set();this.markersBySyncId_=new Map();this.transformerMapByDomainId_={};}
+ClockSyncManager.prototype={addClockSyncMarker(domainId,syncId,startTs,opt_endTs){this.onDomainSeen_(domainId);if(Object.values(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
+if(this.modelDomainId_){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
+const marker=new ClockSyncMarker(domainId,startTs,opt_endTs);if(!this.markersBySyncId_.has(syncId)){this.markersBySyncId_.set(syncId,[marker]);return;}
+const markers=this.markersBySyncId_.get(syncId);if(markers.length===2){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
+if(markers[0].domainId===domainId){throw new Error('A clock domain cannot sync with itself.');}
+markers.push(marker);this.onSyncCompleted_(markers[0],marker);},get markersBySyncId(){return this.markersBySyncId_;},get domainsSeen(){return this.domainsSeen_;},getModelTimeTransformer(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
+return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getTimeTransformerError(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_(fromDomainId,toDomainId){const transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
+fromDomainId+'" '+'with target clock domain "'+
+toDomainId+'".');}
+return transformer;},getTransformerBetween_(fromDomainId,toDomainId){const visitedDomainIds=new Set();const queue=[{domainId:fromDomainId,transformer:Transformer.IDENTITY}];while(queue.length>0){queue.sort((domain1,domain2)=>domain1.transformer.error-domain2.transformer.error);const current=queue.shift();if(current.domainId===toDomainId){return current.transformer;}
+if(visitedDomainIds.has(current.domainId)){continue;}
+visitedDomainIds.add(current.domainId);const outgoingTransformers=this.transformerMapByDomainId_[current.domainId];if(!outgoingTransformers)continue;for(const outgoingDomainId in outgoingTransformers){const toNextDomainTransformer=outgoingTransformers[outgoingDomainId];const toCurrentDomainTransformer=current.transformer;queue.push({domainId:outgoingDomainId,transformer:Transformer.compose(toNextDomainTransformer,toCurrentDomainTransformer)});}}
+return undefined;},selectModelDomainId_(){this.ensureAllDomainsAreConnected_();for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(this.domainsSeen_.has(chromeDomainId)){this.modelDomainId_=chromeDomainId;return;}}
+const domainsSeenArray=Array.from(this.domainsSeen_);domainsSeenArray.sort();this.modelDomainId_=domainsSeenArray[0];},ensureAllDomainsAreConnected_(){let firstDomainId=undefined;for(const domainId of this.domainsSeen_){if(!firstDomainId){firstDomainId=domainId;continue;}
+if(!this.getTransformerBetween_(firstDomainId,domainId)){throw new Error('Unable to select a master clock domain because no '+'path can be found from "'+firstDomainId+'" to "'+domainId+'".');}}
+return true;},onDomainSeen_(domainId){if(domainId===ClockDomainId.UNKNOWN_CHROME_LEGACY&&!this.domainsSeen_.has(ClockDomainId.UNKNOWN_CHROME_LEGACY)){for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(chromeDomainId===ClockDomainId.UNKNOWN_CHROME_LEGACY){continue;}
+this.collapseDomains_(ClockDomainId.UNKNOWN_CHROME_LEGACY,chromeDomainId);}}
+this.domainsSeen_.add(domainId);},onSyncCompleted_(marker1,marker2){const forwardTransformer=Transformer.fromMarkers(marker1,marker2);const backwardTransformer=Transformer.fromMarkers(marker2,marker1);const existingTransformer=this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId];if(!existingTransformer||forwardTransformer.error<existingTransformer.error){this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId]=forwardTransformer;this.getOrCreateTransformerMap_(marker2.domainId)[marker1.domainId]=backwardTransformer;}},collapseDomains_(domain1Id,domain2Id){this.getOrCreateTransformerMap_(domain1Id)[domain2Id]=this.getOrCreateTransformerMap_(domain2Id)[domain1Id]=Transformer.IDENTITY;},getOrCreateTransformerMap_(domainId){if(!this.transformerMapByDomainId_[domainId]){this.transformerMapByDomainId_[domainId]={};}
+return this.transformerMapByDomainId_[domainId];},computeDotGraph(){let dotString='graph {\n';const domainsSeen=[...this.domainsSeen_].sort();for(const domainId of domainsSeen){dotString+=`  ${domainId}[shape=box]\n`;}
+const markersBySyncIdEntries=[...this.markersBySyncId_.entries()].sort(([syncId1,markers1],[syncId2,markers2])=>syncId1.localeCompare(syncId2));for(const[syncId,markers]of markersBySyncIdEntries){const sortedMarkers=markers.sort((a,b)=>a.domainId.localeCompare(b.domainId));for(const m of markers){dotString+=`  "${syncId}" -- ${m.domainId} `;dotString+=`[label="[${m.startTs}, ${m.endTs}]"]\n`;}}
+dotString+='}';return dotString;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
+ClockSyncMarker.prototype={get duration(){return this.endTs-this.startTs;},get ts(){return this.startTs+this.duration/2;}};function Transformer(fn,error){this.fn=fn;this.error=error;}
+Transformer.IDENTITY=new Transformer((x=>x),0);Transformer.compose=function(aToB,bToC){return new Transformer((ts)=>bToC.fn(aToB.fn(ts)),aToB.error+bToC.error);};Transformer.fromMarkers=function(fromMarker,toMarker){let fromTs=fromMarker.ts;let toTs=toMarker.ts;if(fromMarker.domainId===ClockDomainId.BATTOR&&toMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){toTs=toMarker.startTs;}else if(toMarker.domainId===ClockDomainId.BATTOR&&fromMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){fromTs=fromMarker.startTs;}
+const tsShift=toTs-fromTs;return new Transformer((ts)=>ts+tsShift,fromMarker.duration+toMarker.duration);};return{ClockDomainId,ClockSyncManager,};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){const samplesByTimestamp=tr.b.groupIntoMap(samples,s=>s.timestamp);const timestamps=Array.from(samplesByTimestamp.keys());timestamps.sort();const groups=[];for(const ts of timestamps){const group=samplesByTimestamp.get(ts);group.sort((x,y)=>x.series.seriesIndex-y.series.seriesIndex);groups.push(group);}
+return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange(range){range.addValue(this.timestamp);},getSampleIndex(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples'});return{CounterSample,};});'use strict';tr.exportTo('tr.model',function(){const CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample(idx){return this.samples_[idx];},getTimestamp(idx){return this.timestamps_[idx];},addCounterSample(ts,val){const sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics(sampleIndices){let sum=0;let min=Number.MAX_VALUE;let max=-Number.MAX_VALUE;for(let i=0;i<sampleIndices.length;++i){const sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min,max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward(amount){for(let i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},*childEvents(){yield*this.samples_;},*childEventContainers(){}};return{CounterSeries,};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},*childEvents(){},*childEventContainers(){yield*this.series;},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)return[];return this.series_[0].timestamps;},getSampleStatistics(sampleIndices){sampleIndices.sort();const ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward(amount){for(let i=0;i<this.series_.length;++i){this.series_[i].shiftTimestampsForward(amount);}},updateBounds(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)return;const firstSeries=this.series_[0];const lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));const numSeries=this.numSeries;this.maxTotal=-Infinity;for(let i=0;i<firstSeries.length;++i){let total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp!==0)return tmp;tmp=x.name.localeCompare(y.name);if(tmp===0)return x.tid-y.tid;return tmp;};return{Counter,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice(){if(!this.threadThatWasRunning){return undefined;}
+const timeSlices=this.threadThatWasRunning.timeSlices;for(let i=0;i<timeSlices.length;i++){const timeSlice=timeSlices[i];if(timeSlice.start!==this.start){continue;}
+if(timeSlice.duration!==this.duration){continue;}
+return timeSlice;}
+return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices'});return{CpuSlice,};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
+TimeToObjectInstanceMap.prototype={idWasCreated(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot(category,name,ts,args,opt_baseTypeName){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
+const i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);let instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
+if(instance.snapshots.length!==0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
+instance.snapshots[0].ts+' and creationTs was '+
+instance.creationTs);}
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{let lastValidIndex;for(let i=this.instances.length-1;i>=0;i--){const tmp=this.instances[i];if(ts>=tmp.deletionTs)break;if(tmp.creationTsWasExplicit===false&&tmp.snapshots.length===0){lastValidIndex=i;}}
+if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
+instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
+return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length===0)return undefined;return this.instances[this.instances.length-1];},idWasDeleted(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs){throw new Error('Cannot delete an id before it was created');}
+if(lastInstance.deletionTs===Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
+if(ts<lastInstance.deletionTs){throw new Error('id was already deleted earlier.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt(ts){const i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit){return undefined;}
+return this.instances[0];}else if(i>=this.instances.length){return undefined;}
+return this.instances[i];}};return{TimeToObjectInstanceMap,};});'use strict';tr.exportTo('tr.model',function(){const ObjectInstance=tr.model.ObjectInstance;const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,*childEvents(){for(const instance of this.getAllObjectInstances()){yield instance;yield*instance.snapshots;}},createObjectInstance_(parent,scopedId,category,name,creationTs,opt_baseTypeName){const constructor=tr.model.ObjectInstance.subTypes.getConstructor(category,name);const instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);const typeName=instance.typeName;let instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_(scopedId){let dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
+let instanceMap=dict[scopedId.id];if(instanceMap)return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot(scopedId,category,name,ts,args,opt_baseTypeName){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!==category){const msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+snapshot.objectInstance.category+' name='+
+snapshot.objectInstance.name;throw new Error(msg);}
+if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!==opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
+opt_baseTypeName+'. It '+'was previously created with name='+
+snapshot.objectInstance.baseTypeName);}
+if(snapshot.objectInstance.name!==name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
+snapshot.objectInstance.name);}
+return snapshot;},idWasDeleted(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)return;if(deletedInstance.category!==category){const msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
+deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
+if(deletedInstance.baseTypeName!==name){throw new Error('Deletion requested for name='+
+name+' could not proceed: '+'An existing object with baseTypeName='+
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects(maxTimestamp){for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){const lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!==Number.MAX_VALUE)continue;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;}}},getObjectInstanceAt(scopedId,ts){let instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_){instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];}
+if(!instanceMap)return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt(scopedId,ts){const instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances(iter,opt_this){opt_this=opt_this||this;for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){i2imap.instances.forEach(iter,opt_this);}}},getAllObjectInstances(){const instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName(){return this.instancesByTypeName_;},preInitializeAllObjects(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
+AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey(){if(!this.name_)return undefined;const parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name_;},push(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];slice.start=(slice.start+amount);const shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)return;for(let sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){let prefix='';if(this.name!==undefined){prefix=this.name+'.';}else{prefix='';}
+const subGroupsByTitle={};for(let i=0;i<this.slices.length;++i){const slice=this.slices[i];const subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
+subGroupsByTitle[subGroupTitle].push(slice);}
+this.viewSubGroups_=Object.values(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
+return this.viewSubGroups_;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const slice of this.slices){if(slice.isTopLevel){yield*slice.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}}},*childEvents(){for(const slice of this.slices){yield slice;if(slice.subSlices){yield*slice.subSlices;}}},*childEventContainers(){}};return{AsyncSliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId);this.subSlices=[];}
+ThreadSlice.prototype={__proto__:Slice.prototype,get overlappingSamples(){const samples=new tr.model.EventSet();if(!this.parentContainer||!this.parentContainer.samples){return samples;}
+this.parentContainer.samples.forEach(function(sample){if(this.start<=sample.start&&sample.start<=this.end){samples.push(sample);}},this);return samples;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices'});return{ThreadSlice,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const ThreadSlice=tr.model.ThreadSlice;function getSliceLo(s){return s.start;}
+function getSliceHi(s){return s.end;}
+function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;const sliceConstructor=opt_sliceConstructor||ThreadSlice;this.sliceConstructor=sliceConstructor;this.sliceConstructorSubTypes=this.sliceConstructor.subTypes;if(!this.sliceConstructorSubTypes){throw new Error('opt_sliceConstructor must have a subtype registry.');}
+this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined){throw new Error('SliceGroup must have model defined.');}}
+SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey(){if(!this.name_)return undefined;const parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){const prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start){throw new Error('Slices must be added in increasing timestamp order');}}
+const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd(ts){if(!this.openPartialSlices_.length)return true;const top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice(ts,opt_tts,opt_colorId){if(!this.openSliceCount){throw new Error('endSlice called without an open slice');}
+const slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start){throw new Error('Slice '+slice.title+' end time is before its start.');}
+slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined){slice.cpuDuration=opt_tts-slice.cpuStart;}
+return slice;},pushCompleteSlice(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bindId){const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bindId);if(duration===undefined){slice.didNotFinish=true;}
+this.pushSlice(slice);return slice;},autoCloseOpenSlices(){this.updateBounds();const maxTimestamp=this.bounds.max;for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];if(slice.didNotFinish){slice.duration=maxTimestamp-slice.start;}}
+this.openPartialSlices_=[];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice(slice){const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(slice.category,slice.title);const newSlice=new sliceType(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+for(const s of this.topLevelSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},*childEvents(){yield*this.slices;},*childEventContainers(){},getSlicesOfName(title){const slices=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].title===title){slices.push(this.slices[i]);}}
+return slices;},iterSlicesInTimeRange(callback,start,end){const ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);for(const slice of topLevelSlice.enumerateAllDescendents()){callback(slice);}});return ret;},findFirstSlice(){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+if(0===this.slices.length)return undefined;return this.slices[0];},findSliceAtTs(ts){if(!this.haveTopLevelSlicesBeenBuilt)throw new Error('Nope');let i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===this.topLevelSlices.length){return undefined;}
+let curSlice=this.topLevelSlices[i];while(true){i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===curSlice.subSlices.length){return curSlice;}
+curSlice=curSlice.subSlices[i];}},findNextSliceAfter(ts,refGuid){let i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length){return undefined;}
+for(;i<this.slices.length;i++){const slice=this.slices[i];if(slice.start>ts)return slice;if(slice.guid<=refGuid)continue;return slice;}
+return undefined;},hasCpuDuration_(){if(this.slices.some(function(slice){return slice.cpuDuration!==undefined;}))return true;return false;},createSubSlices(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(!this.hasCpuDuration_()&&this.parentContainer.timeSlices){this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);}
+this.slices.forEach(function(slice){let selfTime=slice.duration;for(let i=0;i<slice.subSlices.length;i++){selfTime-=slice.subSlices[i].duration;}
+slice.selfTime=selfTime;if(slice.cpuDuration===undefined)return;let cpuSelfTime=slice.cpuDuration;for(let i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined){cpuSelfTime-=slice.subSlices[i].cpuDuration;}}
+slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_(){const precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(parent,child){if(parent.bounds(child,precisionUnit)){child.parentSlice=parent;if(parent.subSlices===undefined){parent.subSlices=[];}
+parent.subSlices.push(child);return true;}
+return false;}
+if(!this.slices.length)return;const ops=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].subSlices){this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);}
+ops.push(i);}
+const originalSlices=this.slices;ops.sort(function(ix,iy){const x=originalSlices[ix];const y=originalSlices[iy];if(x.start!==y.start){return x.start-y.start;}
+return ix-iy;});const slices=new Array(this.slices.length);for(let i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
+let rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(let i=1;i<slices.length;i++){const slice=slices[i];while(rootSlice!==undefined&&(!addSliceIfBounds(rootSlice,slice))){rootSlice=rootSlice.parentSlice;}
+if(rootSlice===undefined){this.topLevelSlices.push(slice);slice.isTopLevel=true;}
+rootSlice=slice;}
+this.slices=slices;},addCpuTimeToSubslices_(timeSlices){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;let sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState===SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start){return slice.end<=timeSlice.end;}
+let duration=timeSlice.duration;if(slice.start>timeSlice.start){duration-=slice.start-timeSlice.start;}
+if(timeSlice.end>slice.end){duration-=timeSlice.end-slice.end;}
+if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
+for(let i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
+return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0){throw new Error('groupA has open partial slices');}
+if(groupB.openPartialSlices_.length>0){throw new Error('groupB has open partial slices');}
+if(groupA.parentContainer!==groupB.parentContainer){throw new Error('Different parent threads. Cannot merge');}
+if(groupA.sliceConstructor!==groupB.sliceConstructor){throw new Error('Different slice constructors. Cannot merge');}
+const result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);const slicesA=groupA.slices;const slicesB=groupB.slices;let idxA=0;let idxB=0;const openA=[];const openB=[];const splitOpenSlices=function(when){for(let i=0;i<openB.length;i++){const oldSlice=openB[i];const oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
+const newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')===-1){newSlice.title+=' (cont.)';}
+oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};const closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){const nextA=openA[openA.length-1];const nextB=openB[openB.length-1];const endA=nextA&&nextA.end;const endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
+if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){const sA=slicesA[idxA];const sB=slicesB[idxB];let nextSlice;let isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
+closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
+closeOpenSlices();return result;};return{SliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const AsyncSlice=tr.model.AsyncSlice;const AsyncSliceGroup=tr.model.AsyncSliceGroup;const SliceGroup=tr.model.SliceGroup;const ThreadSlice=tr.model.ThreadSlice;const ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent){throw new Error('Parent must be provided.');}
+tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
+Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo(that){return Thread.compare(this,that);},*childEventContainers(){if(this.sliceGroup.length){yield this.sliceGroup;}
+if(this.kernelSliceGroup.length){yield this.kernelSliceGroup;}
+if(this.asyncSliceGroup.length){yield this.asyncSliceGroup;}},*childEvents(){if(this.timeSlices){yield*this.timeSlices;}},iterateAllPersistableObjects(cb){cb(this);if(this.sliceGroup.length){cb(this.sliceGroup);}
+this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(let i=0;i<this.timeSlices.length;i++){const slice=this.timeSlices[i];slice.start+=amount;}}
+this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)return false;if(this.sliceGroup.openSliceCount)return false;if(this.timeSlices&&this.timeSlices.length)return false;if(this.kernelSliceGroup.length)return false;if(this.asyncSliceGroup.length)return false;if(this.samples_.length)return false;return true;},updateBounds(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict(categoriesDict){for(let i=0;i<this.sliceGroup.length;i++){categoriesDict[this.sliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.kernelSliceGroup.length;i++){categoriesDict[this.kernelSliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.asyncSliceGroup.length;i++){categoriesDict[this.asyncSliceGroup.slices[i].category]=true;}
+if(this.samples_){for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}}},autoCloseOpenSlices(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland(){if(this.kernelSliceGroup.length>0){const newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(sample=>sample.thread===this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+(this.name?', name: '+this.name:'');},getSettingsKey(){if(!this.name)return undefined;const parentKey=this.parent.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},getProcess(){return this.parent;},indexOfTimeSlice(timeSlice){const i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)return undefined;return i;},getCpuStatsForRange(range){const stats={};stats.total=0;if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const freqRange=tr.b.math.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);const intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState===tr.model.SCHEDULING_STATE.RUNNING){const cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats)){stats[cpu.cpuNumber]=0;}
+stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange(start,end){const stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const overlapStart=Math.max(threadTimeSlice.start,start);const overlapEnd=Math.min(threadTimeSlice.end,end);const schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;},get type(){const re=/^[^0-9|\/]+/;const matches=re.exec(this.name);if(matches&&matches[0])return matches[0];throw new Error('Could not determine thread type for thread name '+
+this.name);}};Thread.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp)return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)return tmp;if(x.name!==undefined){if(y.name!==undefined){tmp=x.name.localeCompare(y.name);}else{tmp=-1;}}else if(y.name!==undefined){tmp=1;}
+if(tmp)return tmp;return x.tid-y.tid;};return{Thread,};});'use strict';tr.exportTo('tr.model',function(){const Thread=tr.model.Thread;const Counter=tr.model.Counter;function ProcessBase(model){if(!model){throw new Error('Must provide a model');}
+tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;}
+ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},*childEventContainers(){yield*Object.values(this.threads);yield*Object.values(this.counters);yield this.objects;},iterateAllPersistableObjects(cb){cb(this);for(const tid in this.threads){this.threads[tid].iterateAllPersistableObjects(cb);}},get numThreads(){let n=0;for(const p in this.threads){n++;}
+return n;},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}},autoCloseOpenSlices(){for(const tid in this.threads){const thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects(){this.objects.preInitializeAllObjects();},initializeObjects(){this.objects.initializeAllObjects();},mergeKernelWithUserland(){for(const tid in this.threads){const thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds(){this.bounds.reset();for(const tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict(categoriesDict){for(const tid in this.threads){this.threads[tid].addCategoriesToDict(categoriesDict);}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching(predicate,opt_this){const threads=[];for(const tid in this.threads){const thread=this.threads[tid];if(predicate.call(opt_this,thread)){threads.push(thread);}}
+return threads;},findAllThreadsNamed(name){const threads=this.findAllThreadsMatching(function(thread){if(!thread.name)return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed(name){const threads=this.findAllThreadsNamed(name);if(threads.length===0)return undefined;if(threads.length>1){throw new Error('Expected no more than one '+name);}
+return threads[0];},pruneEmptyContainers(){const threadsToKeep={};for(const tid in this.threads){const thread=this.threads[tid];if(!thread.isEmpty){threadsToKeep[tid]=thread;}}
+this.threads=threadsToKeep;},getThread(tid){return this.threads[tid];},getOrCreateThread(tid){if(!this.threads[tid]){this.threads[tid]=new Thread(this,tid);}
+return this.threads[tid];},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getSettingsKey(){throw new Error('Not implemented');},createSubSlices(){for(const tid in this.threads){this.threads[tid].createSubSlices();}}};return{ProcessBase,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Counter=tr.model.Counter;const CpuSlice=tr.model.CpuSlice;function Cpu(kernel,number){if(kernel===undefined||number===undefined){throw new Error('Missing arguments');}
+this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds_=new tr.b.math.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;}
+Cpu.prototype={__proto__:tr.model.EventContainer.prototype,get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const s of this.slices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}},*childEvents(){yield*this.slices;if(this.samples_){yield*this.samples_;}},*childEventContainers(){yield*Object.values(this.counters);},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){return undefined;}
+return this.counters[id];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){this.slices[sI].start=(this.slices[sI].start+amount);}
+for(const id in this.counters){this.counters[id].shiftTimestampsForward(amount);}},updateBounds(){this.bounds_.reset();if(this.slices.length){this.bounds_.addValue(this.slices[0].start);this.bounds_.addValue(this.slices[this.slices.length-1].end);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds_.addRange(this.counters[id].bounds);}
+if(this.samples_&&this.samples_.length){this.bounds_.addValue(this.samples_[0].start);this.bounds_.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu===this;},this);},addCategoriesToDict(categoriesDict){for(let i=0;i<this.slices.length;i++){categoriesDict[this.slices[i].category]=true;}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}},indexOf(cpuSlice){const i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)return undefined;return i;},closeActiveThread(endTimestamp,args){if(this.lastActiveThread_===undefined||this.lastActiveThread_===0){return;}
+if(endTimestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
+this.cpuNumber+' is before its start timestamp.');}
+for(const key in args){this.lastActiveArgs_[key]=args[key];}
+const duration=endTimestamp-this.lastActiveTimestamp_;const slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread(timestamp,oldThreadArgs,newThreadId,newThreadName,newThreadArgs){this.closeActiveThread(timestamp,oldThreadArgs);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=newThreadId;this.lastActiveName_=newThreadName;this.lastActiveArgs_=newThreadArgs;},getFreqStatsForRange(range){const stats={};function addStatsForFreq(freqSample,index){const freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;const freqRange=tr.b.math.Range.fromExplicitRange(freqSample.timestamp,freqEnd);const intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats)){stats[freqSample.value]=0;}
+stats[freqSample.value]+=intersection.duration;}
+const freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){const freqSeries=freqCounter.getSeries(0);if(!freqSeries)return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){if(index<freqSeries.length-1){return freqSeries.samples_[index+1].timestamp;}
+return range.max;},range.min,range.max,addStatsForFreq);}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,powerInW){Event.call(this);this.series_=series;this.start_=parseFloat(start);this.powerInW_=parseFloat(powerInW);}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get powerInW(){return this.powerInW_;},set powerInW(value){this.powerInW_=value;},addBoundsToRange(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples'});return{PowerSample,};});'use strict';tr.exportTo('tr.model',function(){const PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample(ts,val){const sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumedInJ(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let energyConsumedInJ=0;let startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0){startIndex=0;}
+for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);const durationInS=tr.b.convertUnit(intersectionRangeInMs.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);energyConsumedInJ+=durationInS*sample.powerInW;}
+return energyConsumedInJ;},getSamplesWithinRange(start,end){const startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);},shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}},updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},*childEvents(){yield*this.samples_;},};return{PowerSeries,};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model){throw new Error('Must provide a model.');}
+tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.cpuUsageSeries_=undefined;this.vSyncTimestamps_=[];}
+Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get cpuUsageSeries(){return this.cpuUsageSeries_;},set cpuUsageSeries(cpuUsageSeries){this.cpuUsageSeries_=cpuUsageSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds(){this.bounds.reset();for(const child of this.childEventContainers()){child.updateBounds();this.bounds.addRange(child.bounds);}},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}
+for(let i=0;i<this.vSyncTimestamps_.length;i++){this.vSyncTimestamps_[i]+=amount;}},addCategoriesToDict(categoriesDict){},*childEventContainers(){if(this.powerSeries_){yield this.powerSeries_;}
+if(this.cpuUsageSeries_){yield this.cpuUsageSeries_;}}};return{Device,};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined){this.duration=opt_duration;}}
+FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents'});return{FlowEvent,};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;}
+ContainerMemoryDump.LevelOfDetail={BACKGROUND:0,LIGHT:1,DETAILED:2};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName(fullName){if(this.memoryAllocatorDumps_===undefined)return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){const index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});}
+addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps(fn,opt_this){if(this.memoryAllocatorDumps===undefined)return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;}
+MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
+this.containerMemoryDump.containerName;},getDescendantDumpByFullName(fullName){return this.containerMemoryDump.getMemoryAllocatorDumpByFullName(this.fullName+'/'+fullName);},isDescendantOf(otherDump){if(this===otherDump)return true;if(this.parent===undefined)return false;return this.parent.isDescendantOf(otherDump);},addNumeric(name,numeric){if(!(numeric instanceof tr.b.Scalar)){throw new Error('Numeric value must be an instance of Scalar.');}
+if(name in this.numerics){throw new Error('Duplicate numeric name: '+name+'.');}
+this.numerics[name]=numeric;},addDiagnostic(name,text){if(typeof text!=='string'){throw new Error('Diagnostic text must be a string.');}
+if(name in this.diagnostics){throw new Error('Duplicate diagnostic name: '+name+'.');}
+this.diagnostics[name]=text;},aggregateNumericsRecursively(opt_model){const numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);for(const[item,value]of Object.entries(child.numerics)){numericNames.add(item,value);}},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
+this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){let shouldLogWarning=!!opt_model;let aggregatedUnit=undefined;let aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)return;const unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
+aggregatedUnit.unitName+'\' and \''+unit.unitName+'\'.'});shouldLogWarning=false;}
+aggregatedUnit=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;}
+aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)return undefined;return new tr.b.Scalar(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
+const MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump,MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType,};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function getSize(dump){const numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;return numeric.value;}
+function hasSize(dump){return dump.numerics[SIZE_NUMERIC_NAME]!==undefined;}
+function optional(value,defaultValue){if(value===undefined)return defaultValue;return value;}
+GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){tr.b.inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
+removeWeakDumpsFromListRecursively(dump.children);tr.b.inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
+this.iterateContainerDumps(function(containerDump){const memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined){removeWeakDumpsFromListRecursively(memoryAllocatorDumps);}});},calculateSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_(dump){let shouldDefineSize=false;function getDependencySize(dependencyDump){const numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;shouldDefineSize=true;return numeric.value;}
+const sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];let size=0;let checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.b.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
+sizeNumeric.unit.unitName+'.'});}
+checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
+dump.fullName+'\''+
+tr.b.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
+tr.b.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize});}.bind(this);}
+let aggregatedChildrenSize=0;const allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){const ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){let ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump){ownedChildDump=ownedChildDump.parent;}
+if(childDump!==ownedChildDump){const ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){const previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;const updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
+return;}
+if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
+descendantDump.children.forEach(aggregateDescendantDump);}
+aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');let largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){const owner=ownershipLink.source;const ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){const virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_(dump){if(!hasSize(dump))return;if(dump.children===undefined||dump.children.length===0){const size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+let notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;let notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+let largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_(dump){if(!hasSize(dump))return;if(dump.ownedBy.length===0)return;const owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance){return a.notOwningSubSize-b.notOwningSubSize;}
+return b.importance-a.importance;});let currentImportanceStartPos=0;let alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){const currentImportance=owners[currentImportanceStartPos].importance;let nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+let attributedNotOwningSubSize=0;for(let pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){const owner=owners[pos];const notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+let owningCoefficient=0;if(notOwningSubSize!==0){owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;}
+owner.dump.owningCoefficient_=owningCoefficient;}
+currentImportanceStartPos=nextImportanceStartPos;}
+const notOwnedSubSize=optional(dump.notOwnedSubSize_,0);const remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;let ownedCoefficient=0;if(notOwnedSubSize!==0){ownedCoefficient=remainderSubSize/notOwnedSubSize;}
+dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_(dump){if(!hasSize(dump))return;let cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);const parent=dump.parent;if(dump.parent!==undefined){cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;}
+dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;let cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
+let effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
+dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);for(const processMemoryDump of Object.values(this.processMemoryDumps)){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);}},propagateNumericsAndDiagnosticsRecursively(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){for(const[name,value]of
+Object.entries(globalAllocatorDump[field])){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){const processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
+processAllocatorDump[field][name]=value;});}});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership(){for(const dump of Object.values(this.processMemoryDumps)){dump.setUpTracingOverheadOwnership(this.model);}},discountTracingOverheadFromVmRegions(){for(const dump of Object.values(this.processMemoryDumps)){dump.discountTracingOverheadFromVmRegions(this.model);}},forceRebuildingMemoryAllocatorDumpByFullNameIndices(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps(fn){fn.call(this,this);for(const processDump of Object.values(this.processMemoryDumps)){fn.call(this,processDump);}},iterateAllRootAllocatorDumps(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder(fn){const visitedDumps=new WeakSet();const openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(openDumps.has(dump)){throw new Error(dump.userFriendlyName+' contains a cycle');}
+openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder(fn){const visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target)){return;}
+if(dump.parent!==undefined&&!visitedDumps.has(dump.parent)){return;}
+fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps'});return{GlobalMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;}
+InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;}
+GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;}
+ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents'});return{GlobalInstantEvent,ProcessInstantEvent,InstantEventType,InstantEvent,};});'use strict';tr.exportTo('tr.model',function(){const Cpu=tr.model.Cpu;const ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;}
+Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu(cpuNumber){if(!this.cpus[cpuNumber]){this.cpus[cpuNumber]=new Cpu(this,cpuNumber);}
+return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
+this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){const realCpuCount=Object.keys(this.cpus).length;if(realCpuCount!==0){return realCpuCount;}
+return this.softwareMeasuredCpuCount;},updateBounds(){ProcessBase.prototype.updateBounds.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices(){ProcessBase.prototype.createSubSlices.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(const cpuNumber in this.cpus){this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);}},getSettingsKey(){return'kernel';},*childEventContainers(){yield*ProcessBase.prototype.childEventContainers.call(this);yield*Object.values(this.cpus);},};return{Kernel,};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=[];}
+this.flowEventsById_[fe.id].push(fe);}},this);}
+ModelIndices.prototype={addEventWithId(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=[];}
+this.flowEventsById_[id].push(event);},getFlowEventsWithId(id){if(!this.flowEventsById_.hasOwnProperty(id)){return[];}
+return this.flowEventsById_[id];}};return{ModelIndices,};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;this.traceImportDurationMs_=undefined;}
+ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent(phase,category,title,ts,opt_eventSizeinBytes){const key=phase+'/'+category+'/'+title;let eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase,category,title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
+eventStats.numEvents++;const timeIntervalKey=Math.floor(tr.b.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);let eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
+eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;},get traceImportDurationMs(){return this.traceImportDurationMs_;},set traceImportDurationMs(traceImportDurationMs){this.traceImportDurationMs_=traceImportDurationMs;}};return{ModelStats,};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};}
+VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_MAYSHARE?'s':'p'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,dict.byteStats);};function VMRegionClassificationNode(opt_rule){this.rule_=opt_rule||VMRegionClassificationNode.CLASSIFICATION_RULES;this.hasRegions=false;this.sizeInBytes=undefined;this.byteStats={};this.children_=undefined;this.regions_=[];}
+VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){const tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(let i=0;i<regions.length;i++){tree.addStatsFromRegion_(regions[i]);}
+return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode){return undefined;}
+if(this.children_===undefined){this.buildTree_();}
+return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
+return this.regions_;},get allRegionsForTesting(){if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
+return this.regions_;}
+let regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){const children=this.rule_.children;return children===undefined||children.length===0;},addRegion(region){this.addRegionRecursively_(region,true);},someRegion(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
+return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_(region,addStatsToThisNode){if(addStatsToThisNode){this.addStatsFromRegion_(region);}
+if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
+this.regions_.push(region);return;}
+function regionRowMatchesChildNide(child){const fileRegExp=child.rule_.file;if(fileRegExp===undefined)return true;return fileRegExp.test(region.mappedFile);}
+let matchedChild=this.children_.find(regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length){throw new Error('Internal error');}
+matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
+matchedChild.addRegionRecursively_(region,true);},buildTree_(){const cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(let i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
+if(this.regions_!==undefined&&this.regions_.length!==0){throw new Error('Internal error: Classification node should have no regions');}
+if(this.isLeafNode){return;}
+this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){const child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_(region){this.hasRegions=true;const regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined){this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;}
+const thisByteStats=this.byteStats;const regionByteStats=region.byteStats;for(const byteStatName in regionByteStats){const regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion,VMRegionClassificationNode,};});'use strict';tr.exportTo('tr.model',function(){const DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];const TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){const sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)return 0;return sizeNumeric.value;}
+function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;}
+ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){const dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership(opt_model){if(this.tracingOverheadOwnershipSetUp_)return;this.tracingOverheadOwnershipSetUp_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
+if(tracingDump.owns!==undefined)return;const hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){const allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined){return false;}
+let nextPathIndex=0;let currentDump=allocatorDump;let currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)break;currentDump=childDump;currentFullName=childFullName;}
+for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
+const ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps){this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();}},discountTracingOverheadFromVmRegions(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)return;this.tracingOverheadDiscountedFromVmRegions_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)return;const discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);const discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined){this.totals.residentBytes-=discountedResidentSize;}
+if(this.totals.peakResidentBytes!==undefined){this.totals.peakResidentBytes-=discountedResidentSize;}}
+if(this.vmRegions!==undefined){const hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;const hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;const hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){const byteStats={};if(hasPrivateDirtyResident){byteStats.privateDirtyResident=-discountedResidentSize;}
+if(hasProportionalResident){byteStats.proportionalResident=-discountedResidentSize;}
+this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){let mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined){mostRecentVmRegions=processDump.vmRegions;}
+processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps'});return{ProcessMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const ProcessBase=tr.model.ProcessBase;const ProcessInstantEvent=tr.model.ProcessInstantEvent;const Frame=tr.model.Frame;const ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined){throw new Error('model must be provided');}
+if(pid===undefined){throw new Error('pid must be provided');}
+tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.uptime_seconds=0;this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];}
+Process.compare=function(x,y){let tmp=tr.model.ProcessBase.compare(x,y);if(tmp)return tmp;if(x.name!==undefined){if(y.name!==undefined){tmp=x.name.localeCompare(y.name);}else{tmp=-1;}}else if(y.name!==undefined){tmp=1;}
+if(tmp)return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo(that){return Process.compare(this,that);},*childEvents(){yield*ProcessBase.prototype.childEvents.call(this);yield*this.instantEvents;yield*this.frames;yield*this.memoryDumps;},addLabelIfNeeded(labelName){for(let i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)return;}
+this.labels.push(labelName);},get userFriendlyName(){let res;if(this.name){res=this.name+' (pid '+this.pid+')';}else{res='Process '+this.pid;}
+if(this.labels.length){res+=': '+this.labels.join(', ');}
+if(this.uptime_seconds){res+=', uptime:'+this.uptime_seconds+'s';}
+return res;},get userFriendlyDetails(){if(this.name){return this.name+' (pid '+this.pid+')';}
+return'pid: '+this.pid;},getSettingsKey(){if(!this.name)return undefined;if(!this.labels.length)return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward(amount){for(let i=0;i<this.instantEvents.length;i++){this.instantEvents[i].start+=amount;}
+for(let i=0;i<this.frames.length;i++){this.frames[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].shiftTimestampsForward(amount);}
+tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(let i=0;i<this.frames.length;i++){this.frames[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].addBoundsToRange(this.bounds);}},sortMemoryDumps(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process,};});'use strict';tr.exportTo('tr.model',function(){function Sample(start,title,leafNode,thread,opt_cpu,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.start_=start;this.title_=title;this.leafNode_=leafNode;this.thread_=thread;this.colorId_=leafNode.colorId;this.cpu_=opt_cpu;this.weight_=opt_weight;this.args=opt_args||{};}
+Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.title_;},get colorId(){return this.colorId_;},get thread(){return this.thread_;},get leafNode(){return this.leafNode_;},get userFriendlyName(){return'Sample at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get userFriendlyStack(){return this.leafNode_.userFriendlyStack;},getNodesAsArray(){const nodes=[];let node=this.leafNode_;while(node!==undefined){nodes.push(node);node=node.parentNode;}
+return nodes;},get cpu(){return this.cpu_;},get weight(){return this.weight_;},};tr.model.EventRegistry.register(Sample,{name:'Sample',pluralName:'Samples'});return{Sample,};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined){throw new Error('id must be given');}
+this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_){this.parentFrame_.addChild(this);}}
+StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){const src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
+return this.title_;},get domain(){let result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain){result=this.sourceInfo_.domain;}
+if(result==='unknown'&&this.parentFrame){result=this.parentFrame.domain;}
+return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_){Polymer.dom(this.parentFrame_).removeChild(this);}
+this.parentFrame_=parentFrame;if(this.parentFrame_){this.parentFrame_.addChild(this);}},addChild(child){this.children.push(child);},removeChild(child){const i=this.children.indexOf(child.id);if(i===-1){throw new Error('omg');}
+this.children.splice(i,1);},removeAllChildren(){for(let i=0;i<this.children.length;i++){this.children[i].parentFrame_=undefined;}
+this.children.splice(0,this.children.length);},get stackTrace(){const stack=[this];let cur=this.parentFrame;while(cur){stack.push(cur);cur=cur.parentFrame;}
+return stack;},getUserFriendlyStackTrace(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
+get expectations(){return this.expectations_;}
+clone(){const clone=new Segment(this.start,this.duration);clone.expectations.push(...this.expectations);return clone;}
+addSegment(other){this.duration+=other.duration;this.expectations.push(...other.expectations);}}
+return{Segment,};});'use strict';tr.exportTo('tr.model.um',function(){class UserModel extends tr.model.EventContainer{constructor(parentModel){super();this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();this.segments_=[];}
+get stableId(){return'UserModel';}
+get parentModel(){return this.parentModel_;}
+sortExpectations(){this.expectations_.sortEvents((x,y)=>(x.start-y.start));}
+get expectations(){return this.expectations_;}
+shiftTimestampsForward(amount){}
+addCategoriesToDict(categoriesDict){}
+get segments(){return this.segments_;}*childEvents(){yield*this.expectations;}*childEventContainers(){}
+updateBounds(){this.bounds.reset();for(const expectation of this.expectations){expectation.addBoundsToRange(this.bounds);}}
+resegment(getKeyForSegment){const newSegments=[];let prevKey=undefined;let prevSegment=undefined;for(let i=0;i<this.segments.length;++i){const segment=this.segments[i];const key=getKeyForSegment(segment,i);if(prevSegment!==undefined&&key===prevKey){prevSegment.addSegment(segment);}else{prevSegment=segment.clone();newSegments.push(prevSegment);}
+prevKey=key;}
+return newSegments;}}
+return{UserModel,};});'use strict';tr.exportTo('tr',function(){const Process=tr.model.Process;const Device=tr.model.Device;const Kernel=tr.model.Kernel;const GlobalMemoryDump=tr.model.GlobalMemoryDump;const GlobalInstantEvent=tr.model.GlobalInstantEvent;const FlowEvent=tr.model.FlowEvent;const Alert=tr.model.Alert;const Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=true;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};this.eventsByStableId_=undefined;}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,getEventByStableId(stableId){if(this.eventsByStableId_===undefined){this.eventsByStableId_={};for(const event of this.getDescendantEvents()){this.eventsByStableId_[event.stableId]=event;}}
+return this.eventsByStableId_[stableId];},getOrCreateHelper(constructor){if(!constructor.guid){throw new Error('Helper constructors must have GUIDs');}
+if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
+if(!this.doesHelperGUIDSupportThisModel_[constructor.guid]){return undefined;}
+this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
+return this.helpersByConstructorGUID_[constructor.guid];},*childEvents(){yield*this.globalMemoryDumps;yield*this.instantEvents;yield*this.flowEvents;yield*this.alerts;yield*this.samples;},*childEventContainers(){yield this.userModel;yield this.device;yield this.kernel;yield*Object.values(this.processes);},iterateAllPersistableObjects(callback){this.kernel.iterateAllPersistableObjects(callback);for(const pid in this.processes){this.processes[pid].iterateAllPersistableObjects(callback);}},updateBounds(){this.bounds.reset();const bounds=this.bounds;for(const ec of this.childEventContainers()){ec.updateBounds();bounds.addRange(ec.bounds);}
+for(const event of this.childEvents()){event.addBoundsToRange(bounds);}},shiftWorldToZero(){const shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;for(const ec of this.childEventContainers()){ec.shiftTimestampsForward(shiftAmount);}
+for(const event of this.childEvents()){event.start+=shiftAmount;}
+this.updateBounds();},convertTimestampToModelTime(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
+return tr.b.Unit.timestampFromUs(ts)+
+this.timestampShiftToZeroAmount_;},get numProcesses(){let n=0;for(const p in this.processes){n++;}
+return n;},getProcess(pid){return this.processes[pid];},getOrCreateProcess(pid){if(!this.processes[pid]){this.processes[pid]=new Process(this,pid);}
+return this.processes[pid];},addStackFrame(stackFrame){if(this.stackFrames[stackFrame.id]){throw new Error('Stack frame already exists');}
+this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},updateCategories_(){const categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(const pid in this.processes){this.processes[pid].addCategoriesToDict(categoriesDict);}
+this.categories=[];for(const category in categoriesDict){if(category!==''){this.categories.push(category);}}},getAllThreads(){const threads=[];for(const tid in this.kernel.threads){threads.push(process.threads[tid]);}
+for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.threads){threads.push(process.threads[tid]);}}
+return threads;},getAllProcesses(opt_predicate){const processes=[];for(const pid in this.processes){const process=this.processes[pid];if(opt_predicate===undefined||opt_predicate(process)){processes.push(process);}}
+return processes;},getAllCounters(){const counters=[];counters.push.apply(counters,Object.values(this.device.counters||{}));counters.push.apply(counters,Object.values(this.kernel.counters||{}));for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.counters){counters.push(process.counters[tid]);}}
+return counters;},getAnnotationByGUID(guid){return this.annotationsByGuid_[guid];},addAnnotation(annotation){if(!annotation.guid){throw new Error('Annotation with undefined guid given');}
+this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations(){return Object.values(this.annotationsByGuid_);},addUserFriendlyCategoryDriver(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent(event){for(let i=0;i<this.userFriendlyCategoryDrivers_.length;i++){const ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)return ufc;}
+return undefined;},findAllThreadsNamed(name){const namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(const pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined){return tr.b.TimeDisplayModes.ms;}
+return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)return;if(this.intrinsicTimeUnit_!==undefined){throw new Error('Intrinsic time unit already set');}
+this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){return this.isTimeHighResolution_;},set isTimeHighResolution(value){this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)return;if(this.canonicalUrl_!==undefined){throw new Error('canonicalUrl already set');}
+this.canonicalUrl_=value;},importWarning(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)return;this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(const pid in this.processes){this.processes[pid].autoCloseOpenSlices();}},createSubSlices(){this.kernel.createSubSlices();for(const pid in this.processes){this.processes[pid].createSubSlices();}},preInitializeObjects(){for(const pid in this.processes){this.processes[pid].preInitializeObjects();}},initializeObjects(){for(const pid in this.processes){this.processes[pid].initializeObjects();}},pruneEmptyContainers(){this.kernel.pruneEmptyContainers();for(const pid in this.processes){this.processes[pid].pruneEmptyContainers();}},mergeKernelWithUserland(){for(const pid in this.processes){this.processes[pid].mergeKernelWithUserland();}},computeWorldBounds(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero){this.shiftWorldToZero();}},buildFlowEventIntervalTree(){for(let i=0;i<this.flowEvents.length;++i){const flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
+this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects(){for(const pid in this.processes){this.processes[pid].autoDeleteObjects(this.bounds.max);}},sortMemoryDumps(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(const pid in this.processes){this.processes[pid].sortMemoryDumps();}},finalizeMemoryGraphs(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups(){const unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){const snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;snapshot.referencedAt(patchup.item,patchup.object,patchup.field);return;}}
+unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups(oldPidRef,newPidRef){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===oldPidRef){patchup.pidRef=newPidRef;}});},joinRefs(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_(){for(const[pid,process]of Object.entries(this.processes)){this.joinObjectRefsForProcess_(pid,process);}},joinObjectRefsForProcess_(pid,process){for(const thread of Object.values(process.threads)){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_(pid,itemTimestampField,item){if(!item.args&&!item.contexts)return;const patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef)){return;}
+const scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;const idRef=fieldValue.id_ref||fieldValue.idRef;const scopedId=new tr.model.ScopedId(scope,idRef);const pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;const ts=item[itemTimestampField];patchupsToApply.push({item,object,field:fieldName,pidRef,scopedId,ts});}
+function iterObjectFieldsRecursively(object){if(!(object instanceof Object))return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.math.Quad)){return;}
+if(object instanceof Array){for(let i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
+return;}
+for(const key in object){const value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);iterObjectFieldsRecursively(item.contexts);}};return{Model,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));}
+Decoder.prototype={__proto__:Object.prototype,reset(base64Payload){const decodedSize=tr.b.Base64.getDecodedBufferLength(base64Payload);if(decodedSize>this.payload_.byteLength){this.payload_=new DataView(new ArrayBuffer(decodedSize));}
+tr.b.Base64.DecodeToTypedArray(base64Payload,this.payload_);this.position_=0;},skip(length){this.position_+=length;},decodeUInt8(){const result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16(){const result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32(){const result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString(){const low=this.decodeUInt32();const high=this.decodeUInt32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},decodeInt8(){const result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16(){const result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32(){const result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString(){return this.decodeUInt64ToString();},decodeUInteger(is64){if(is64){return this.decodeUInt64ToString();}
+return this.decodeUInt32();},decodeString(){let str='';while(true){const c=this.decodeUInt8();if(!c)return str;str=str+String.fromCharCode(c);}},decodeW16String(){let str='';while(true){const c=this.decodeUInt16();if(!c)return str;str=str+String.fromCharCode(c);}},decodeFixedW16String(length){const oldPosition=this.position_;let str='';for(let i=0;i<length;i++){const c=this.decodeUInt16();if(!c)break;str=str+String.fromCharCode(c);}
+this.position_=oldPosition+2*length;return str;},decodeBytes(length){const bytes=[];for(let i=0;i<length;++i){const c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID(is64){const pSid=this.decodeUInteger(is64);const attributes=this.decodeUInt32();if(is64){this.decodeUInt32();}
+const revision=this.decodeUInt8();const subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!==1){throw new Error('Invalid SID revision: could not decode the SID structure.');}
+const sid=this.decodeBytes(4*subAuthorityCount);return{pSid,attributes,sid};},decodeSystemTime(){const wYear=this.decodeInt16();const wMonth=this.decodeInt16();const wDayOfWeek=this.decodeInt16();const wDay=this.decodeInt16();const wHour=this.decodeInt16();const wMinute=this.decodeInt16();const wSecond=this.decodeInt16();const wMilliseconds=this.decodeInt16();return{wYear,wMonth,wDayOfWeek,wDay,wHour,wMinute,wSecond,wMilliseconds};},decodeTimeZoneInformation(){const bias=this.decodeUInt32();const standardName=this.decodeFixedW16String(32);const standardDate=this.decodeSystemTime();const standardBias=this.decodeUInt32();const daylightName=this.decodeFixedW16String(32);const daylightDate=this.decodeSystemTime();const daylightBias=this.decodeUInt32();return{bias,standardName,standardDate,standardBias,daylightName,daylightDate,daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};const allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid(tid){if(tid===0)return 0;const pid=this.tidsToPid_[tid];if(pid===undefined){return 0;}
+return pid;},getThreadFromWindowsTid(tid){const pid=this.getPidFromWindowsTid(tid);const process=this.model_.getProcess(pid);if(!process)return undefined;return process.getThread(tid);},getOrCreateCpu(cpuNumber){const cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_===undefined||this.ticks_===undefined){throw Error('Cannot find clock sync information in the system trace.');}
+if(this.is64bit_===undefined){throw Error('Cannot determine pointer size of the system trace.');}
+this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp(timestamp){const ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_===undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op===kThreadDCStartOpcode){const decodedSize=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver===1){if(decodedSize>=52){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===2){if(decodedSize>=64){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===3){if(decodedSize>=60){this.is64bit_=true;}else{this.is64bit_=false;}}}
+return true;},parseEvent(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+const timestamp=this.importTimestamp(event.ts);const header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp,is64:this.is64bit_};const decoder=this.decoder_;decoder.reset(event.payload);const handler=this.getEventHandler(header.guid,header.opcode);if(!handler)return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+event.payload+')'});return false;}
+return true;},registerEventHandler(guid,opcode,handler){if(this.handlers_[guid]===undefined){this.handlers_[guid]=[];}
+this.handlers_[guid][opcode]=handler;},getEventHandler(guid,opcode){if(this.handlers_[guid]===undefined){return undefined;}
+return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter,};});'use strict';tr.exportTo('tr.b',function(){class TraceStream{static get HEADER_SIZE(){return Math.pow(2,10);}
+static get CHUNK_SIZE(){return Math.pow(2,20);}
+get isBinary(){throw new Error('Not implemented');}
+get hasData(){throw new Error('Not implemented');}
+get header(){throw new Error('Not implemented');}
+readUntilDelimiter(delim){throw new Error('Not implemented');}
+readNumBytes(opt_size){throw new Error('Not implemented');}
+rewind(){throw new Error('Not implemented');}
+substream(offset,opt_length,opt_headerSize){throw new Error('Not implemented');}}
+return{TraceStream,};});'use strict';tr.exportTo('tr.e.importer.fuchsia',function(){const IMPORT_PRIORITY=0;const IDLE_THREAD_THRESHOLD=6444000000;class FuchsiaImporter extends tr.importer.Importer{constructor(model,eventData){super(model,eventData);this.importPriority=IMPORT_PRIORITY;this.model_=model;this.events_=eventData.events;this.parsers_=[];this.threadInfo_=new Map();this.processNames_=new Map();}
+static canImport(eventData){if(eventData instanceof tr.b.TraceStream){if(eventData.isBinary)return false;eventData=eventData.header;}
+if(eventData instanceof Object&&eventData.type==='fuchsia'){return true;}
+return false;}
+get importerName(){return'FuchsiaImporter';}
+get model(){return this.model_;}
+importClockSyncMarkers(){}
+finalizeImport(){}
+processContextSwitchEvent_(event){let tid=event.in.tid;let threadName=tid.toString();let procName='';if(this.threadInfo_.has(tid)){const threadInfo=this.threadInfo_.get(tid);threadName=threadInfo.name;const pid=threadInfo.pid;if(this.processNames_.has(pid)){procName=this.processNames_.get(pid)+':';}}
+const name=procName+threadName;if(tid>IDLE_THREAD_THRESHOLD){tid=undefined;}
+const cpu=this.model_.kernel.getOrCreateCpu(event.cpu);cpu.switchActiveThread(tr.b.Unit.timestampFromUs(event.ts),{},tid,name,tid);}
+processProcessInfoEvent_(event){const process=this.model_.getOrCreateProcess(event.pid);process.name=event.name;this.processNames_.set(event.pid,event.name);if('sort_index'in event){process.sortIndex=event.sort_index;}}
+processThreadInfoEvent_(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.name;this.threadInfo_.set(event.tid,{'name':event.name,'pid':event.pid});if('sort_index'in event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.sort_index;}}
+processEvent_(event){switch(event.ph){case'k':this.processContextSwitchEvent_(event);break;case'p':this.processProcessInfoEvent_(event);break;case't':this.processThreadInfoEvent_(event);break;}}
+importEvents(){for(const event of this.events_){this.processEvent_(event);}}}
+tr.importer.Importer.register(FuchsiaImporter);return{FuchsiaImporter,IMPORT_PRIORITY,};});'use strict';tr.exportTo('tr.b',function(){const MAX_FUNCTION_ARGS_COUNT=Math.pow(2,15)-1;class InMemoryTraceStream extends tr.b.TraceStream{constructor(buffer,isBinary,opt_headerSize){super();if(!buffer instanceof Uint8Array){throw new Error('buffer should be a Uint8Array');}
+const headerSize=opt_headerSize||tr.b.TraceStream.HEADER_SIZE;this.data_=buffer;this.isBinary_=isBinary;this.header_=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(0,headerSize));this.cursor_=0;}
+get isBinary(){return this.isBinary_;}
+get hasData(){return this.cursor_<this.data_.length;}
+get header(){return this.header_;}
+get data(){return this.data_;}
+toString(){this.rewind();return this.readNumBytes(Number.MAX_VALUE);}
+readUntilDelimiter(delim){if(delim.length!==1){throw new Error('delim must be exactly one character');}
+const offset=this.data_.indexOf(delim.charCodeAt(0),this.cursor_)+1;return this.readToOffset_(offset>0?Math.min(offset,this.data_.length):this.data_.length);}
+readNumBytes(opt_size){if(opt_size!==undefined&&opt_size<=0){throw new Error(`readNumBytes expects a positive size (${opt_size} given)`);}
+const size=opt_size||tr.b.TraceStream.CHUNK_SIZE;const offset=Math.min(this.cursor_+size,this.data_.length);return this.readToOffset_(offset);}
+rewind(){this.cursor_=0;}
+substream(startOffset,opt_endOffset,opt_headerSize){return new InMemoryTraceStream(this.data_.subarray(startOffset,opt_endOffset),this.isBinary_,opt_headerSize);}
+readToOffset_(offset){const out=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(this.cursor_,offset));this.cursor_=offset;return out;}
+static uint8ArrayToString_(arr){const c=[];for(let i=0;i<arr.length;i+=MAX_FUNCTION_ARGS_COUNT){c.push(String.fromCharCode(...arr.subarray(i,i+MAX_FUNCTION_ARGS_COUNT)));}
+return c.join('');}}
+return{InMemoryTraceStream,};});'use strict';if(tr.isVinn){global.window={};}
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){const jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');const jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){const GZIP_MEMBER_HEADER_ID_SIZE=3;const GZIP_HEADER_ID1=0x1f;const GZIP_HEADER_ID2=0x8b;const GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){this.inflateAsTraceStream=false;if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.data;this.inflateAsTraceStream_=true;}else{throw new Error('Unknown gzip data format');}
+this.model_=model;this.gzipData_=eventData;}
+GzipImporter.canImport=function(eventData){if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.header;}
+let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));}else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else{return false;}
+return header[0]===GZIP_HEADER_ID1&&header[1]===GZIP_HEADER_ID2&&header[2]===GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){let position=0;function getByte(){if(position>=data.length){throw new Error('Unexpected end of gzip data');}
+return data[position++];}
+function getWord(){const low=getByte();const high=getByte();return(high<<8)+low;}
+function skipBytes(amount){position+=amount;}
+function skipZeroTerminatedString(){while(getByte()!==0){}}
+const id1=getByte();const id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2){throw new Error('Not gzip data');}
+const compressionMethod=getByte();if(compressionMethod!==GZIP_DEFLATE_COMPRESSION){throw new Error('Unsupported compression method: '+compressionMethod);}
+const flags=getByte();const haveHeaderCrc=flags&(1<<1);const haveExtraFields=flags&(1<<2);const haveFileName=flags&(1<<3);const haveComment=flags&(1<<4);skipBytes(4+1+1);if(haveExtraFields){const bytesToSkip=getWord();skipBytes(bytesToSkip);}
+if(haveFileName)skipZeroTerminatedString();if(haveComment)skipZeroTerminatedString();if(haveHeaderCrc)getWord();const inflatedData=JSZip.compressions.DEFLATE.uncompress(data.subarray(position));if(this.inflateAsTraceStream_){return GzipImporter.transformToStream(inflatedData);}
+let string;try{string=GzipImporter.transformToString(inflatedData);}catch(err){return GzipImporter.transformToStream(inflatedData);}
+if(inflatedData.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflatedData.length+').');}
+return string;};GzipImporter.transformToStream=function(data){const type=JSZip.utils.getTypeOf(data);if(type==='uint8array')return new tr.b.InMemoryTraceStream(data,false);throw new Error(`Cannot transform ${type} to TraceStream.`);};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
+const type=JSZip.utils.getTypeOf(data);if(type==='string')return data;if(type==='array'){data=new Uint8Array(data);}
+const decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter,};});'use strict';tr.exportTo('tr.importer',function(){class SimpleLineReader{constructor(text){this.data_=text instanceof tr.b.TraceStream?text:text.split('\n');this.curLine_=0;this.readLastLine_=false;this.savedLines_=undefined;}*[Symbol.iterator](){let lastLine=undefined;while(this.hasData_){if(this.readLastLine_){this.curLine_++;this.readLastLine_=false;}else if(this.data_ instanceof tr.b.TraceStream){this.curLine_++;const line=this.data_.readUntilDelimiter('\n');lastLine=line.endsWith('\n')?line.slice(0,-1):line;}else{this.curLine_++;lastLine=this.data_[this.curLine_-1];}
+yield lastLine;}}
+get curLineNumber(){return this.curLine_;}
+get hasData_(){if(this.data_ instanceof tr.b.TraceStream)return this.data_.hasData;return this.curLine_<this.data_.length;}
+advanceToLineMatching(regex){for(const line of this){if(this.savedLines_!==undefined)this.savedLines_.push(line);if(regex.test(line)){this.goBack_();return true;}}
+return false;}
+goBack_(){if(this.readLastLine_){throw new Error('There should be at least one nextLine call between '+'any two goBack calls.');}
+if(this.curLine_===0){throw new Error('There should be at least one nextLine call before '+'the first goBack call.');}
+this.readLastLine_=true;this.curLine_--;}
+beginSavingLines(){this.savedLines_=[];}
+endSavingLinesAndGetResult(){const tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}}
+return{SimpleLineReader,};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];const r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$'))){break;}
+r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))return;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);const data64=rawEvents.join('\n');const buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));const len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+function _canImportFromHTML(text){if(!/^<!DOCTYPE html>/.test(text))return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)return false;return true;}
+Trace2HTMLImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)return false;return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer(){return true;},extractSubtraces(){return Trace2HTMLImporter.subtraces_;},importEvents(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){}
+SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
+this.splay_(key);if(this.root_.key===key){return;}
+const node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
+this.splay_(key);if(this.root_.key!==key){throw Error('Key not found: '+key);}
+const removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{const right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty())return null;this.splay_(key);return this.root_.key===key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty())return null;let current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty())return null;let current=opt_startNode||this.root_;while(current.right){current=current.right;}
+return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty())return null;this.splay_(key);if(this.root_.key<=key){return this.root_;}
+if(this.root_.left){return this.findMax(this.root_.left);}
+return null;};SplayTree.prototype.exportKeysAndValues=function(){const result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){const result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty())return;const dummy=new SplayTree.Node(null,null);let left=dummy;let right=dummy;let current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){const tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
+if(key>current.right.key){const tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+left.right=current;left=current;current=current.right;}else{break;}}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){const nodesToVisit=[this.root_];while(nodesToVisit.length>0){const node=nodesToVisit.shift();if(node===null)continue;f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];}
+CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){const removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){const removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(let addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){const toDelete=[];let addr=end-1;while(addr>=start){const node=tree.findGreatestLessThan(addr);if(!node)break;const start2=node.key;const end2=start2+node.value.size;if(start2<end&&start<end2)toDelete.push(start2);addr=start2-1;}
+for(let i=0,l=toDelete.length;i<l;++i)tree.remove(toDelete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){const node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntryInLibraries=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.libraries_,addr);}
+return undefined;};CodeMap.prototype.findEntry=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+const min=this.dynamics_.findMin();const max=this.dynamics_.findMax();if(max!==null&&addr<(max.key+max.value.size)&&addr>=min.key){const dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry===null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+return dynaEntry;}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){const node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeState={COMPILED:0,OPTIMIZABLE:1,OPTIMIZED:2};CodeMap.CodeEntry=function(size,opt_name,opt_type){this.id=tr.b.GUID.allocateSimple();this.size=size;this.name_=opt_name||'';this.type=opt_type||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype={__proto__:Object.prototype,get name(){return this.name_;},set name(value){this.name_=value;},toString(){this.name_+': '+this.size.toString(16);}};CodeMap.CodeEntry.TYPE={SHARED_LIB:'SHARED_LIB',CPP:'CPP'};CodeMap.DynamicFuncCodeEntry=function(size,type,func,state){CodeMap.CodeEntry.call(this,size,'',type);this.func=func;this.state=state;};CodeMap.DynamicFuncCodeEntry.STATE_PREFIX=['','~','*'];CodeMap.DynamicFuncCodeEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){return CodeMap.DynamicFuncCodeEntry.STATE_PREFIX[this.state]+
+this.func.name;},set name(value){this.name_=value;},getRawName(){return this.func.getName();},isJSFunction(){return true;},toString(){return this.type+': '+this.name+': '+this.size.toString(16);}};CodeMap.FunctionEntry=function(name){CodeMap.CodeEntry.call(this,0,name);};CodeMap.FunctionEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){let name=this.name_;if(name.length===0){name='<anonymous>';}else if(name.charAt(0)===' '){name='<anonymous>'+name;}
+return name;},set name(value){this.name_=value;}};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
+const count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){}
+CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){const fieldRe=CsvParser.CSV_FIELD_RE_;const doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;let pos=0;const endPos=line.length;const fields=[];if(endPos>0){do{const fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){const field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{const field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();}
+LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){const command=fields[0];if(!(command in this.dispatchTable_))return;const dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+const parsedFields=[];for(let i=0;i<dispatch.parsers.length;++i){const parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser==='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(let i=0,n=lines.length;i<n;++i,++this.lineNum_){const line=lines[i];if(!line){continue;}
+try{const fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+(e.message||e));}}};return{LogReader,};});'use strict';tr.exportTo('tr.model',function(){function ProfileNode(id,title,parentNode){this.id_=id;this.title_=title;this.parentNode_=parentNode;this.colorId_=-1;this.userFriendlyStack_=[];}
+ProfileNode.prototype={__proto__:Object.prototype,get title(){return this.title_;},get parentNode(){return this.parentNode_;},set parentNode(value){this.parentNode_=value;},get id(){return this.id_;},get colorId(){return this.colorId_;},set colorId(value){this.colorId_=value;},get userFriendlyName(){return this.title_;},get userFriendlyStack(){if(this.userFriendlyStack_.length===0){this.userFriendlyStack_=[this.userFriendlyName];if(this.parentNode_!==undefined){this.userFriendlyStack_=this.userFriendlyStack_.concat(this.parentNode_.userFriendlyStack);}}
+return this.userFriendlyStack_;},get sampleTitle(){throw new Error('Not implemented.');}};tr.model.EventRegistry.register(ProfileNode,{name:'Node',pluralName:'Nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.e.v8',function(){const ProfileNode=tr.model.ProfileNode;function V8CpuProfileNode(id,callFrame,parentNode){ProfileNode.call(this,id,callFrame.functionName,parentNode);this.callFrame_=tr.b.deepCopy(callFrame);this.deoptReason_='';this.colorId_=tr.b.ColorScheme.getColorIdForGeneralPurposeString(callFrame.functionName);}
+V8CpuProfileNode.prototype={__proto__:ProfileNode.prototype,get functionName(){return this.callFrame_.functionName;},get scriptId(){return this.callFrame_.scriptId;},get url(){if(!this.callFrame_.url){return'unknown';}
+let url=this.callFrame_.url;if(this.callFrame_.lineNumber===undefined){return url;}
+url=url+':'+this.callFrame_.lineNumber;if(this.callFrame_.columnNumber===undefined){return url;}
+url=url+':'+this.callFrame_.columnNumber;return url;},get deoptReason(){return this.deoptReason_;},set deoptReason(value){this.deoptReason_=value;},get userFriendlyName(){const name=this.functionName+' url: '+this.url;return!this.deoptReason_?name:name+' Deoptimized reason: '+this.deoptReason_;},get sampleTitle(){return'V8 Sample';}};V8CpuProfileNode.constructFromObject=function(profileTree,node){const nodeId=node.id;if(nodeId===1){return undefined;}
+const parentNode=profileTree.getNode(node.parent);const profileNode=new V8CpuProfileNode(nodeId,node.callFrame,parentNode);if(node.deoptReason!==undefined){profileNode.deoptReason=node.deoptReason;}
+return profileNode;};ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'cpuProfile',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'legacySample',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.model',function(){function ProfileTree(){this.startTime_=undefined;this.endTime_=undefined;this.tree_=new Map();this.pid_=-1;this.tid_=-1;}
+ProfileTree.prototype={__proto__:Object.prototype,get pid(){return this.pid_;},set pid(value){this.pid_=value;},get tid(){return this.tid_;},set tid(value){this.tid_=value;},get tree(){return this.tree_;},get startTime(){return this.startTime_;},set startTime(value){this.startTime_=value;this.endTime_=value;},get endTime(){return this.endTime_;},set endTime(value){this.endTime_=value;},add(node){if(this.tree_.has(node.id)){throw new Error('Conflict id in the profile tree.');}
+this.tree_.set(node.id,node);return node;},getNode(nodeId){return this.tree_.get(nodeId);}};return{ProfileTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){const CodeEntry=tr.e.importer.v8.CodeMap.CodeEntry;const CodeMap=tr.e.importer.v8.CodeMap;const ColorScheme=tr.b.ColorScheme;const DynamicFuncCodeEntry=tr.e.importer.v8.CodeMap.DynamicFuncCodeEntry;const FunctionEntry=tr.e.importer.v8.CodeMap.FunctionEntry;const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.profileTree_=new tr.model.ProfileTree();this.profileTree_.add(new ProfileNodeType(-1,{url:'',functionName:'unknown'}));this.v8_stack_timeline_=[];}
+const kV8BinarySuffixes=['/d8','/libv8.so'];const TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
+return eventData.substring(0,11)==='v8-version,'||eventData.substring(0,12)==='timer-event,'||eventData.substring(0,5)==='tick,'||eventData.substring(0,15)==='shared-library,'||eventData.substring(0,9)==='profiler,'||eventData.substring(0,14)==='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_(name,startInUs,lengthInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const lengthInMs=tr.b.convertUnit(lengthInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const colorId=ColorScheme.getColorIdForGeneralPurposeString(name);const slice=new tr.model.ThreadSlice('v8',name,colorId,startInMs,args,lengthInMs);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_(name,startInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,startInMs,args);},processTimerEventEnd_(name,endInUs){const endInMs=tr.b.convertUnit(endInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.endSlice(endInMs);},processCodeCreateEvent_(type,kind,address,size,name,maybeFunc){function parseState(s){switch(s){case'':return CodeMap.CodeState.COMPILED;case'~':return CodeMap.CodeState.OPTIMIZABLE;case'*':return CodeMap.CodeState.OPTIMIZED;}
+throw new Error('unknown code state: '+s);}
+if(maybeFunc.length){const funcAddr=parseInt(maybeFunc[0]);const state=parseState(maybeFunc[1]);let func=this.code_map_.findDynamicEntryByStartAddress(funcAddr);if(!func){func=new FunctionEntry(name);func.kind=kind;this.code_map_.addCode(funcAddr,func);}else if(func.name!==name){func.name=name;}
+let entry=this.code_map_.findDynamicEntryByStartAddress(address);if(entry){if(entry.size===size&&entry.func===func){entry.state=state;}}else{entry=new DynamicFuncCodeEntry(size,type,func,state);entry.kind=kind;this.code_map_.addCode(address,entry);}}else{const codeEntry=new CodeEntry(size,name);codeEntry.kind=kind;this.code_map_.addCode(address,codeEntry);}},processCodeMoveEvent_(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_(address){this.code_map_.deleteCode(address);},processSharedLibrary_(name,start,end){const codeEntry=new CodeEntry(end-start,name,CodeEntry.TYPE.SHARED_LIB);codeEntry.kind=-3;for(let i=0;i<kV8BinarySuffixes.length;i++){const suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){codeEntry.kind=-1;break;}}
+this.code_map_.addLibrary(start,codeEntry);},processCppSymbol_(address,size,name){const codeEntry=new CodeEntry(size,name,CodeEntry.TYPE.CPP);codeEntry.kind=-1;this.code_map_.addStaticCode(address,codeEntry);},processTickEvent_(pc,startInUs,isExternalCallback,tosOrExternalCallback,vmstate,stack){const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);function findChildWithEntryID(stackFrame,entryID){for(let i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID===entryID){return stackFrame.children[i];}}
+return undefined;}
+function processStack(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;}
+if(isExternalCallback){pc=tosOrExternalCallback;tosOrExternalCallback=0;}else if(tosOrExternalCallback){const funcEntry=this.code_map_.findEntry(tosOrExternalCallback);if(!funcEntry||!funcEntry.isJSFunction||!funcEntry.isJSFunction()){tosOrExternalCallback=0;}}
+let processedStack=processStack(pc,tosOrExternalCallback,stack);let node=undefined;let lastNode=undefined;processedStack=processedStack.reverse();for(let i=0,n=processedStack.length;i<n;i++){const frame=processedStack[i];if(!frame)break;const entry=this.code_map_.findEntry(frame);if(!entry&&i!==0){continue;}
+let sourceInfo=undefined;if(entry&&entry.type===CodeEntry.TYPE.CPP){const libEntry=this.code_map_.findEntryInLibraries(frame);if(libEntry){sourceInfo={file:libEntry.name};}}
+const entryId=entry?entry.id:-1;node=this.profileTree_.getNode(entryId);if(node===undefined){node=this.profileTree_.add(new ProfileNodeType(entryId,{functionName:entry.name,url:sourceInfo?sourceInfo.file:'',lineNumber:sourceInfo?sourceInfo.line:undefined,columnNumber:sourceInfo?sourceInfo.column:undefined,scriptId:sourceInfo?sourceInfo.scriptId:undefined},lastNode));}
+lastNode=node;}
+this.model_.samples.push(new tr.model.Sample(startInMs,'V8 PC',node,this.v8_thread_,undefined,1));},processDistortion_(distortionInPicoseconds){},processPlotRange_(start,end){},processV8Version_(major,minor,build,patch,candidate){},importEvents(){const logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null,'var-args'],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'cpp':{parsers:[parseInt,parseInt,null],processor:this.processCppSymbol_.bind(this)},'tick':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';const lines=this.logData_.split('\n');for(let i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+function addSlices(slices,thread){for(let i=0;i<slices.length;i++){const duration=slices[i].end-slices[i].start;const slice=new tr.model.ThreadSlice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter,};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}
+this.model_=model;this.eventData_=eventData;}
+ZipImporter.canImport=function(eventData){let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,2));}else if(typeof(eventData)==='string'||eventData instanceof String){header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];}else{return false;}
+return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const zip=new JSZip(this.eventData_);const subtraces=[];for(const idx in zip.files){subtraces.push(zip.files[idx].asBinary());}
+return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter,};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size,count,valuesAreTotals){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;this.count=count;this.valuesAreTotals=valuesAreTotals;}
+function HeapDump(processMemoryDump,allocatorName,isComplete){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.isComplete=isComplete;this.entries=[];}
+HeapDump.prototype={addEntry(leafStackFrame,objectTypeName,size,count,opt_valuesAreTotals){if(opt_valuesAreTotals===undefined)opt_valuesAreTotals=true;const valuesAreTotals=opt_valuesAreTotals;const entry=new HeapEntry(this,leafStackFrame,objectTypeName,size,count,valuesAreTotals);this.entries.push(entry);return entry;}};return{HeapEntry,HeapDump,};});'use strict';tr.exportTo('tr.e.importer',function(){function HeapDumpTraceEventImporter(heapProfileExpander,stackFrames,processMemoryDump,idPrefix,model){this.expander=heapProfileExpander;this.stackFrames=stackFrames;this.processMemoryDump=processMemoryDump;this.idPrefix=idPrefix;this.model=model;}
+HeapDumpTraceEventImporter.prototype={getLeafStackFrame(stackFrameId){if(stackFrameId==='')return undefined;const parentId=this.idPrefix+stackFrameId;const id=parentId+':self';if(!this.stackFrames[id]){const parentStackFrame=this.stackFrames[parentId];const stackFrame=new tr.model.StackFrame(parentStackFrame,id,'<self>',undefined);this.model.addStackFrame(stackFrame);}
+return this.stackFrames[id];},parseEntry(entry,heapDump){const size=entry.size;const count=entry.count;const leafStackFrame=this.getLeafStackFrame(entry.node.id);const objectTypeName=entry.type.name;const valuesAreTotals=false;if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+typeId+')',});}
+heapDump.addEntry(leafStackFrame,objectTypeName,size,count,valuesAreTotals);},parse(){const heapDumps={};const inflated=this.expander.inflated;for(const[allocatorName,entries]of Object.entries(inflated)){const heapDump=new tr.model.HeapDump(this.processMemoryDump,allocatorName);for(const entry of entries){this.parseEntry(entry,heapDump);}
+heapDump.isComplete=true;heapDumps[allocatorName]=heapDump;}
+return heapDumps;},};return{HeapDumpTraceEventImporter,};});'use strict';tr.exportTo('tr.e.importer',function(){function LegacyHeapDumpTraceEventImporter(model,processMemoryDump,processObjectTypeNameMap,idPrefix,dumpId,rawHeapDumps){this.model_=model;this.processObjectTypeNameMap_=processObjectTypeNameMap;this.idPrefix_=idPrefix;this.processMemoryDump_=processMemoryDump;this.pid_=this.processMemoryDump_.process.pid;this.dumpId_=dumpId;this.rawHeapDumps_=rawHeapDumps;}
+LegacyHeapDumpTraceEventImporter.prototype={parseRawHeapDump(rawHeapDump,allocatorName){const model=this.model_;const processMemoryDump=this.processMemoryDump_;const heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);const entries=rawHeapDump.entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+this.pid_+' and dump ID='+this.dumpId_+'.'});return undefined;}
+const isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&this.processObjectTypeNameMap_===undefined){return undefined;}
+for(let i=0;i<entries.length;i++){const entry=entries[i];const size=parseInt(entry.size,16);const leafStackFrameIndex=entry.bt;let leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{let leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
+leafStackFrameId+') of heap entry '+i+' (size '+
+size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
+leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}
+const leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}}
+const objectTypeId=entry.type;let objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(this.processObjectTypeNameMap_===undefined){continue;}else{objectTypeName=this.processObjectTypeNameMap_[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
+const count=entry.count===undefined?undefined:parseInt(entry.count,16);heapDump.addEntry(leafStackFrame,objectTypeName,size,count);}
+return heapDump;},parse(){const heapDumps={};for(const allocatorName in this.rawHeapDumps_){const rawHeapDump=this.rawHeapDumps_[allocatorName];const heapDump=this.parseRawHeapDump(rawHeapDump,allocatorName);if(heapDump!==undefined&&heapDump.entries.length>0){heapDumps[allocatorName]=heapDump;}}
+return heapDumps;},};return{LegacyHeapDumpTraceEventImporter,};});'use strict';if(tr.isHeadless){global.window={};}
+(function(window,Object,Array,Error,JSON,undefined){var partialComplete=varArgs(function(fn,args){var numBoundArgs=args.length;return varArgs(function(callArgs){for(var i=0;i<callArgs.length;i++){args[numBoundArgs+i]=callArgs[i];}
+args.length=numBoundArgs+callArgs.length;return fn.apply(this,args);});}),compose=varArgs(function(fns){var fnsList=arrayAsList(fns);function next(params,curFn){return[apply(params,curFn)];}
+return varArgs(function(startParams){return foldR(next,startParams,fnsList)[0];});});function compose2(f1,f2){return function(){return f1.call(this,f2.apply(this,arguments));}}
+function attr(key){return function(o){return o[key];};}
+var lazyUnion=varArgs(function(fns){return varArgs(function(params){var maybeValue;for(var i=0;i<len(fns);i++){maybeValue=apply(params,fns[i]);if(maybeValue){return maybeValue;}}});});function apply(args,fn){return fn.apply(undefined,args);}
+function varArgs(fn){var numberOfFixedArguments=fn.length-1,slice=Array.prototype.slice;if(numberOfFixedArguments==0){return function(){return fn.call(this,slice.call(arguments));}}else if(numberOfFixedArguments==1){return function(){return fn.call(this,arguments[0],slice.call(arguments,1));}}
+var argsHolder=Array(fn.length);return function(){for(var i=0;i<numberOfFixedArguments;i++){argsHolder[i]=arguments[i];}
+argsHolder[numberOfFixedArguments]=slice.call(arguments,numberOfFixedArguments);return fn.apply(this,argsHolder);}}
+function flip(fn){return function(a,b){return fn(b,a);}}
+function lazyIntersection(fn1,fn2){return function(param){return fn1(param)&&fn2(param);};}
+function noop(){}
+function always(){return true}
+function functor(val){return function(){return val;}}
+function isOfType(T,maybeSomething){return maybeSomething&&maybeSomething.constructor===T;}
+var len=attr('length'),isString=partialComplete(isOfType,String);function defined(value){return value!==undefined;}
+function hasAllProperties(fieldList,o){return(o instanceof Object)&&all(function(field){return(field in o);},fieldList);}
+function cons(x,xs){return[x,xs];}
+var emptyList=null,head=attr(0),tail=attr(1);function arrayAsList(inputArray){return reverseList(inputArray.reduce(flip(cons),emptyList));}
+var list=varArgs(arrayAsList);function listAsArray(list){return foldR(function(arraySoFar,listItem){arraySoFar.unshift(listItem);return arraySoFar;},[],list);}
+function map(fn,list){return list?cons(fn(head(list)),map(fn,tail(list))):emptyList;}
+function foldR(fn,startValue,list){return list?fn(foldR(fn,startValue,tail(list)),head(list)):startValue;}
+function foldR1(fn,list){return tail(list)?fn(foldR1(fn,tail(list)),head(list)):head(list);}
+function without(list,test,removedFn){return withoutInner(list,removedFn||noop);function withoutInner(subList,removedFn){return subList?(test(head(subList))?(removedFn(head(subList)),tail(subList)):cons(head(subList),withoutInner(tail(subList),removedFn))):emptyList;}}
+function all(fn,list){return!list||(fn(head(list))&&all(fn,tail(list)));}
+function applyEach(fnList,args){if(fnList){head(fnList).apply(null,args);applyEach(tail(fnList),args);}}
+function reverseList(list){function reverseInner(list,reversedAlready){if(!list){return reversedAlready;}
+return reverseInner(tail(list),cons(head(list),reversedAlready))}
+return reverseInner(list,emptyList);}
+function first(test,list){return list&&(test(head(list))?head(list):first(test,tail(list)));}
+function clarinet(eventBus){"use strict";var
+emitSaxKey=eventBus(SAX_KEY).emit,emitValueOpen=eventBus(SAX_VALUE_OPEN).emit,emitValueClose=eventBus(SAX_VALUE_CLOSE).emit,emitFail=eventBus(FAIL_EVENT).emit,MAX_BUFFER_LENGTH=64*1024,stringTokenPattern=/[\\"\n]/g,_n=0,BEGIN=_n++,VALUE=_n++,OPEN_OBJECT=_n++,CLOSE_OBJECT=_n++,OPEN_ARRAY=_n++,CLOSE_ARRAY=_n++,STRING=_n++,OPEN_KEY=_n++,CLOSE_KEY=_n++,TRUE=_n++,TRUE2=_n++,TRUE3=_n++,FALSE=_n++,FALSE2=_n++,FALSE3=_n++,FALSE4=_n++,NULL=_n++,NULL2=_n++,NULL3=_n++,NUMBER_DECIMAL_POINT=_n++,NUMBER_DIGIT=_n,bufferCheckPosition=MAX_BUFFER_LENGTH,latestError,c,p,textNode=undefined,numberNode="",slashed=false,closed=false,state=BEGIN,stack=[],unicodeS=null,unicodeI=0,depth=0,position=0,column=0,line=1;function checkBufferLength(){var maxActual=0;if(textNode!==undefined&&textNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: textNode");maxActual=Math.max(maxActual,textNode.length);}
+if(numberNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: numberNode");maxActual=Math.max(maxActual,numberNode.length);}
+bufferCheckPosition=(MAX_BUFFER_LENGTH-maxActual)
++position;}
+eventBus(STREAM_DATA).on(handleData);eventBus(STREAM_END).on(handleStreamEnd);function emitError(errorString){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+latestError=Error(errorString+"\nLn: "+line+"\nCol: "+column+"\nChr: "+c);emitFail(errorReport(undefined,undefined,latestError));}
+function handleStreamEnd(){if(state==BEGIN){emitValueOpen({});emitValueClose();closed=true;return;}
+if(state!==VALUE||depth!==0)
+emitError("Unexpected end");if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+closed=true;}
+function whitespace(c){return c=='\r'||c=='\n'||c==' '||c=='\t';}
+function handleData(chunk){if(latestError)
+return;if(closed){return emitError("Cannot write after close");}
+var i=0;c=chunk[0];while(c){p=c;c=chunk[i++];if(!c)break;position++;if(c=="\n"){line++;column=0;}else column++;switch(state){case BEGIN:if(c==="{")state=OPEN_OBJECT;else if(c==="[")state=OPEN_ARRAY;else if(!whitespace(c))
+return emitError("Non-whitespace before {[.");continue;case OPEN_KEY:case OPEN_OBJECT:if(whitespace(c))continue;if(state===OPEN_KEY)stack.push(CLOSE_KEY);else{if(c==='}'){emitValueOpen({});emitValueClose();state=stack.pop()||VALUE;continue;}else stack.push(CLOSE_OBJECT);}
+if(c==='"')
+state=STRING;else
+return emitError("Malformed object key should start with \" ");continue;case CLOSE_KEY:case CLOSE_OBJECT:if(whitespace(c))continue;if(c===':'){if(state===CLOSE_OBJECT){stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen({});emitSaxKey(textNode);textNode=undefined;}
+depth++;}else{if(textNode!==undefined){emitSaxKey(textNode);textNode=undefined;}}
+state=VALUE;}else if(c==='}'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(c===','){if(state===CLOSE_OBJECT)
+stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=OPEN_KEY;}else
+return emitError('Bad object');continue;case OPEN_ARRAY:case VALUE:if(whitespace(c))continue;if(state===OPEN_ARRAY){emitValueOpen([]);depth++;state=VALUE;if(c===']'){emitValueClose();depth--;state=stack.pop()||VALUE;continue;}else{stack.push(CLOSE_ARRAY);}}
+if(c==='"')state=STRING;else if(c==='{')state=OPEN_OBJECT;else if(c==='[')state=OPEN_ARRAY;else if(c==='t')state=TRUE;else if(c==='f')state=FALSE;else if(c==='n')state=NULL;else if(c==='-'){numberNode+=c;}else if(c==='0'){numberNode+=c;state=NUMBER_DIGIT;}else if('123456789'.indexOf(c)!==-1){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError("Bad value");continue;case CLOSE_ARRAY:if(c===','){stack.push(CLOSE_ARRAY);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=VALUE;}else if(c===']'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(whitespace(c))
+continue;else
+return emitError('Bad array');continue;case STRING:if(textNode===undefined){textNode="";}
+var starti=i-1;STRING_BIGLOOP:while(true){while(unicodeI>0){unicodeS+=c;c=chunk.charAt(i++);if(unicodeI===4){textNode+=String.fromCharCode(parseInt(unicodeS,16));unicodeI=0;starti=i-1;}else{unicodeI++;}
+if(!c)break STRING_BIGLOOP;}
+if(c==='"'&&!slashed){state=stack.pop()||VALUE;textNode+=chunk.substring(starti,i-1);break;}
+if(c==='\\'&&!slashed){slashed=true;textNode+=chunk.substring(starti,i-1);c=chunk.charAt(i++);if(!c)break;}
+if(slashed){slashed=false;if(c==='n'){textNode+='\n';}
+else if(c==='r'){textNode+='\r';}
+else if(c==='t'){textNode+='\t';}
+else if(c==='f'){textNode+='\f';}
+else if(c==='b'){textNode+='\b';}
+else if(c==='u'){unicodeI=1;unicodeS='';}else{textNode+=c;}
+c=chunk.charAt(i++);starti=i-1;if(!c)break;else continue;}
+stringTokenPattern.lastIndex=i;var reResult=stringTokenPattern.exec(chunk);if(!reResult){i=chunk.length+1;textNode+=chunk.substring(starti,i-1);break;}
+i=reResult.index+1;c=chunk.charAt(reResult.index);if(!c){textNode+=chunk.substring(starti,i-1);break;}}
+continue;case TRUE:if(!c)continue;if(c==='r')state=TRUE2;else
+return emitError('Invalid true started with t'+c);continue;case TRUE2:if(!c)continue;if(c==='u')state=TRUE3;else
+return emitError('Invalid true started with tr'+c);continue;case TRUE3:if(!c)continue;if(c==='e'){emitValueOpen(true);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid true started with tru'+c);continue;case FALSE:if(!c)continue;if(c==='a')state=FALSE2;else
+return emitError('Invalid false started with f'+c);continue;case FALSE2:if(!c)continue;if(c==='l')state=FALSE3;else
+return emitError('Invalid false started with fa'+c);continue;case FALSE3:if(!c)continue;if(c==='s')state=FALSE4;else
+return emitError('Invalid false started with fal'+c);continue;case FALSE4:if(!c)continue;if(c==='e'){emitValueOpen(false);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid false started with fals'+c);continue;case NULL:if(!c)continue;if(c==='u')state=NULL2;else
+return emitError('Invalid null started with n'+c);continue;case NULL2:if(!c)continue;if(c==='l')state=NULL3;else
+return emitError('Invalid null started with nu'+c);continue;case NULL3:if(!c)continue;if(c==='l'){emitValueOpen(null);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid null started with nul'+c);continue;case NUMBER_DECIMAL_POINT:if(c==='.'){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError('Leading zero not followed by .');continue;case NUMBER_DIGIT:if('0123456789'.indexOf(c)!==-1)numberNode+=c;else if(c==='.'){if(numberNode.indexOf('.')!==-1)
+return emitError('Invalid number has two dots');numberNode+=c;}else if(c==='e'||c==='E'){if(numberNode.indexOf('e')!==-1||numberNode.indexOf('E')!==-1)
+return emitError('Invalid number has two exponential');numberNode+=c;}else if(c==="+"||c==="-"){if(!(p==='e'||p==='E'))
+return emitError('Invalid symbol in number');numberNode+=c;}else{if(numberNode){emitValueOpen(parseFloat(numberNode));emitValueClose();numberNode="";}
+i--;state=stack.pop()||VALUE;}
+continue;default:return emitError("Unknown state: "+state);}}
+if(position>=bufferCheckPosition)
+checkBufferLength();}}
+function ascentManager(oboeBus,handlers){"use strict";var listenerId={},ascent;function stateAfter(handler){return function(param){ascent=handler(ascent,param);}}
+for(var eventName in handlers){oboeBus(eventName).on(stateAfter(handlers[eventName]),listenerId);}
+oboeBus(NODE_SWAP).on(function(newNode){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));parentNode[key]=newNode;}});oboeBus(NODE_DROP).on(function(){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));delete parentNode[key];}});oboeBus(ABORTING).on(function(){for(var eventName in handlers){oboeBus(eventName).un(listenerId);}});}
+function parseResponseHeaders(headerStr){var headers={};headerStr&&headerStr.split('\u000d\u000a').forEach(function(headerPair){var index=headerPair.indexOf('\u003a\u0020');headers[headerPair.substring(0,index)]=headerPair.substring(index+2);});return headers;}
+function isCrossOrigin(pageLocation,ajaxHost){function defaultPort(protocol){return{'http:':80,'https:':443}[protocol];}
+function portOf(location){return location.port||defaultPort(location.protocol||pageLocation.protocol);}
+return!!((ajaxHost.protocol&&(ajaxHost.protocol!=pageLocation.protocol))||(ajaxHost.host&&(ajaxHost.host!=pageLocation.host))||(ajaxHost.host&&(portOf(ajaxHost)!=portOf(pageLocation))));}
+function parseUrlOrigin(url){var URL_HOST_PATTERN=/(\w+:)?(?:\/\/)([\w.-]+)?(?::(\d+))?\/?/,urlHostMatch=URL_HOST_PATTERN.exec(url)||[];return{protocol:urlHostMatch[1]||'',host:urlHostMatch[2]||'',port:urlHostMatch[3]||''};}
+function httpTransport(){return new XMLHttpRequest();}
+function streamingHttp(oboeBus,xhr,method,url,data,headers,withCredentials){"use strict";var emitStreamData=oboeBus(STREAM_DATA).emit,emitFail=oboeBus(FAIL_EVENT).emit,numberOfCharsAlreadyGivenToCallback=0,stillToSendStartEvent=true;oboeBus(ABORTING).on(function(){xhr.onreadystatechange=null;xhr.abort();});function handleProgress(){var textSoFar=xhr.responseText,newText=textSoFar.substr(numberOfCharsAlreadyGivenToCallback);if(newText){emitStreamData(newText);}
+numberOfCharsAlreadyGivenToCallback=len(textSoFar);}
+if('onprogress'in xhr){xhr.onprogress=handleProgress;}
+xhr.onreadystatechange=function(){function sendStartIfNotAlready(){try{stillToSendStartEvent&&oboeBus(HTTP_START).emit(xhr.status,parseResponseHeaders(xhr.getAllResponseHeaders()));stillToSendStartEvent=false;}catch(e){}}
+switch(xhr.readyState){case 2:case 3:return sendStartIfNotAlready();case 4:sendStartIfNotAlready();var successful=String(xhr.status)[0]==2;if(successful){handleProgress();oboeBus(STREAM_END).emit();}else{emitFail(errorReport(xhr.status,xhr.responseText));}}};try{xhr.open(method,url,true);for(var headerName in headers){xhr.setRequestHeader(headerName,headers[headerName]);}
+if(!isCrossOrigin(window.location,parseUrlOrigin(url))){xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');}
+xhr.withCredentials=withCredentials;xhr.send(data);}catch(e){window.setTimeout(partialComplete(emitFail,errorReport(undefined,undefined,e)),0);}}
+var jsonPathSyntax=(function(){var
+regexDescriptor=function regexDescriptor(regex){return regex.exec.bind(regex);},jsonPathClause=varArgs(function(componentRegexes){componentRegexes.unshift(/^/);return regexDescriptor(RegExp(componentRegexes.map(attr('source')).join('')));}),possiblyCapturing=/(\$?)/,namedNode=/([\w-_]+|\*)/,namePlaceholder=/()/,nodeInArrayNotation=/\["([^"]+)"\]/,numberedNodeInArrayNotation=/\[(\d+|\*)\]/,fieldList=/{([\w ]*?)}/,optionalFieldList=/(?:{([\w ]*?)})?/
+,jsonPathNamedNodeInObjectNotation=jsonPathClause(possiblyCapturing,namedNode,optionalFieldList),jsonPathNamedNodeInArrayNotation=jsonPathClause(possiblyCapturing,nodeInArrayNotation,optionalFieldList),jsonPathNumberedNodeInArrayNotation=jsonPathClause(possiblyCapturing,numberedNodeInArrayNotation,optionalFieldList),jsonPathPureDuckTyping=jsonPathClause(possiblyCapturing,namePlaceholder,fieldList),jsonPathDoubleDot=jsonPathClause(/\.\./),jsonPathDot=jsonPathClause(/\./),jsonPathBang=jsonPathClause(possiblyCapturing,/!/),emptyString=jsonPathClause(/$/);return function(fn){return fn(lazyUnion(jsonPathNamedNodeInObjectNotation,jsonPathNamedNodeInArrayNotation,jsonPathNumberedNodeInArrayNotation,jsonPathPureDuckTyping),jsonPathDoubleDot,jsonPathDot,jsonPathBang,emptyString);};}());function namedNode(key,node){return{key:key,node:node};}
+var keyOf=attr('key');var nodeOf=attr('node');var ROOT_PATH={};function incrementalContentBuilder(oboeBus){var emitNodeOpened=oboeBus(NODE_OPENED).emit,emitNodeClosed=oboeBus(NODE_CLOSED).emit,emitRootOpened=oboeBus(ROOT_PATH_FOUND).emit,emitRootClosed=oboeBus(ROOT_NODE_FOUND).emit;function arrayIndicesAreKeys(possiblyInconsistentAscent,newDeepestNode){var parentNode=nodeOf(head(possiblyInconsistentAscent));return isOfType(Array,parentNode)?keyFound(possiblyInconsistentAscent,len(parentNode),newDeepestNode):possiblyInconsistentAscent;}
+function nodeOpened(ascent,newDeepestNode){if(!ascent){emitRootOpened(newDeepestNode);return keyFound(ascent,ROOT_PATH,newDeepestNode);}
+var arrayConsistentAscent=arrayIndicesAreKeys(ascent,newDeepestNode),ancestorBranches=tail(arrayConsistentAscent),previouslyUnmappedName=keyOf(head(arrayConsistentAscent));appendBuiltContent(ancestorBranches,previouslyUnmappedName,newDeepestNode);return cons(namedNode(previouslyUnmappedName,newDeepestNode),ancestorBranches);}
+function appendBuiltContent(ancestorBranches,key,node){nodeOf(head(ancestorBranches))[key]=node;}
+function keyFound(ascent,newDeepestName,maybeNewDeepestNode){if(ascent){appendBuiltContent(ascent,newDeepestName,maybeNewDeepestNode);}
+var ascentWithNewPath=cons(namedNode(newDeepestName,maybeNewDeepestNode),ascent);emitNodeOpened(ascentWithNewPath);return ascentWithNewPath;}
+function nodeClosed(ascent){emitNodeClosed(ascent);return tail(ascent)||emitRootClosed(nodeOf(head(ascent)));}
+var contentBuilderHandlers={};contentBuilderHandlers[SAX_VALUE_OPEN]=nodeOpened;contentBuilderHandlers[SAX_VALUE_CLOSE]=nodeClosed;contentBuilderHandlers[SAX_KEY]=keyFound;return contentBuilderHandlers;}
+var jsonPathCompiler=jsonPathSyntax(function(pathNodeSyntax,doubleDotSyntax,dotSyntax,bangSyntax,emptySyntax){var CAPTURING_INDEX=1;var NAME_INDEX=2;var FIELD_LIST_INDEX=3;var headKey=compose2(keyOf,head),headNode=compose2(nodeOf,head);function nameClause(previousExpr,detection){var name=detection[NAME_INDEX],matchesName=(!name||name=='*')?always:function(ascent){return headKey(ascent)==name};return lazyIntersection(matchesName,previousExpr);}
+function duckTypeClause(previousExpr,detection){var fieldListStr=detection[FIELD_LIST_INDEX];if(!fieldListStr)
+return previousExpr;var hasAllrequiredFields=partialComplete(hasAllProperties,arrayAsList(fieldListStr.split(/\W+/))),isMatch=compose2(hasAllrequiredFields,headNode);return lazyIntersection(isMatch,previousExpr);}
+function capture(previousExpr,detection){var capturing=!!detection[CAPTURING_INDEX];if(!capturing)
+return previousExpr;return lazyIntersection(previousExpr,head);}
+function skip1(previousExpr){if(previousExpr==always){return always;}
+function notAtRoot(ascent){return headKey(ascent)!=ROOT_PATH;}
+return lazyIntersection(notAtRoot,compose2(previousExpr,tail));}
+function skipMany(previousExpr){if(previousExpr==always){return always;}
+var
+terminalCaseWhenArrivingAtRoot=rootExpr(),terminalCaseWhenPreviousExpressionIsSatisfied=previousExpr,recursiveCase=skip1(function(ascent){return cases(ascent);}),cases=lazyUnion(terminalCaseWhenArrivingAtRoot,terminalCaseWhenPreviousExpressionIsSatisfied,recursiveCase);return cases;}
+function rootExpr(){return function(ascent){return headKey(ascent)==ROOT_PATH;};}
+function statementExpr(lastClause){return function(ascent){var exprMatch=lastClause(ascent);return exprMatch===true?head(ascent):exprMatch;};}
+function expressionsReader(exprs,parserGeneratedSoFar,detection){return foldR(function(parserGeneratedSoFar,expr){return expr(parserGeneratedSoFar,detection);},parserGeneratedSoFar,exprs);}
+function generateClauseReaderIfTokenFound(tokenDetector,clauseEvaluatorGenerators,jsonPath,parserGeneratedSoFar,onSuccess){var detected=tokenDetector(jsonPath);if(detected){var compiledParser=expressionsReader(clauseEvaluatorGenerators,parserGeneratedSoFar,detected),remainingUnparsedJsonPath=jsonPath.substr(len(detected[0]));return onSuccess(remainingUnparsedJsonPath,compiledParser);}}
+function clauseMatcher(tokenDetector,exprs){return partialComplete(generateClauseReaderIfTokenFound,tokenDetector,exprs);}
+var clauseForJsonPath=lazyUnion(clauseMatcher(pathNodeSyntax,list(capture,duckTypeClause,nameClause,skip1)),clauseMatcher(doubleDotSyntax,list(skipMany)),clauseMatcher(dotSyntax,list()),clauseMatcher(bangSyntax,list(capture,rootExpr)),clauseMatcher(emptySyntax,list(statementExpr)),function(jsonPath){throw Error('"'+jsonPath+'" could not be tokenised')});function returnFoundParser(_remainingJsonPath,compiledParser){return compiledParser}
+function compileJsonPathToFunction(uncompiledJsonPath,parserGeneratedSoFar){var onFind=uncompiledJsonPath?compileJsonPathToFunction:returnFoundParser;return clauseForJsonPath(uncompiledJsonPath,parserGeneratedSoFar,onFind);}
+return function(jsonPath){try{return compileJsonPathToFunction(jsonPath,always);}catch(e){throw Error('Could not compile "'+jsonPath+'" because '+e.message);}}});function singleEventPubSub(eventType,newListener,removeListener){var listenerTupleList,listenerList;function hasId(id){return function(tuple){return tuple.id==id;};}
+return{on:function(listener,listenerId){var tuple={listener:listener,id:listenerId||listener};if(newListener){newListener.emit(eventType,listener,tuple.id);}
+listenerTupleList=cons(tuple,listenerTupleList);listenerList=cons(listener,listenerList);return this;},emit:function(){applyEach(listenerList,arguments);},un:function(listenerId){var removed;listenerTupleList=without(listenerTupleList,hasId(listenerId),function(tuple){removed=tuple;});if(removed){listenerList=without(listenerList,function(listener){return listener==removed.listener;});if(removeListener){removeListener.emit(eventType,removed.listener,removed.id);}}},listeners:function(){return listenerList;},hasListener:function(listenerId){var test=listenerId?hasId(listenerId):always;return defined(first(test,listenerTupleList));}};}
+function pubSub(){var singles={},newListener=newSingle('newListener'),removeListener=newSingle('removeListener');function newSingle(eventName){return singles[eventName]=singleEventPubSub(eventName,newListener,removeListener);}
+function pubSubInstance(eventName){return singles[eventName]||newSingle(eventName);}
+['emit','on','un'].forEach(function(methodName){pubSubInstance[methodName]=varArgs(function(eventName,parameters){apply(parameters,pubSubInstance(eventName)[methodName]);});});return pubSubInstance;}
+var
+_S=1,NODE_OPENED=_S++,NODE_CLOSED=_S++,NODE_SWAP=_S++,NODE_DROP=_S++,FAIL_EVENT='fail',ROOT_NODE_FOUND=_S++,ROOT_PATH_FOUND=_S++,HTTP_START='start',STREAM_DATA='data',STREAM_END='end',ABORTING=_S++,SAX_KEY=_S++,SAX_VALUE_OPEN=_S++,SAX_VALUE_CLOSE=_S++;function errorReport(statusCode,body,error){try{var jsonBody=JSON.parse(body);}catch(e){}
+return{statusCode:statusCode,body:body,jsonBody:jsonBody,thrown:error};}
+function patternAdapter(oboeBus,jsonPathCompiler){var predicateEventMap={node:oboeBus(NODE_CLOSED),path:oboeBus(NODE_OPENED)};function emitMatchingNode(emitMatch,node,ascent){var descent=reverseList(ascent);emitMatch(node,listAsArray(tail(map(keyOf,descent))),listAsArray(map(nodeOf,descent)));}
+function addUnderlyingListener(fullEventName,predicateEvent,compiledJsonPath){var emitMatch=oboeBus(fullEventName).emit;predicateEvent.on(function(ascent){var maybeMatchingMapping=compiledJsonPath(ascent);if(maybeMatchingMapping!==false){emitMatchingNode(emitMatch,nodeOf(maybeMatchingMapping),ascent);}},fullEventName);oboeBus('removeListener').on(function(removedEventName){if(removedEventName==fullEventName){if(!oboeBus(removedEventName).listeners()){predicateEvent.un(fullEventName);}}});}
+oboeBus('newListener').on(function(fullEventName){var match=/(node|path):(.*)/.exec(fullEventName);if(match){var predicateEvent=predicateEventMap[match[1]];if(!predicateEvent.hasListener(fullEventName)){addUnderlyingListener(fullEventName,predicateEvent,jsonPathCompiler(match[2]));}}})}
+function instanceApi(oboeBus,contentSource){var oboeApi,fullyQualifiedNamePattern=/^(node|path):./,rootNodeFinishedEvent=oboeBus(ROOT_NODE_FOUND),emitNodeDrop=oboeBus(NODE_DROP).emit,emitNodeSwap=oboeBus(NODE_SWAP).emit,addListener=varArgs(function(eventId,parameters){if(oboeApi[eventId]){apply(parameters,oboeApi[eventId]);}else{var event=oboeBus(eventId),listener=parameters[0];if(fullyQualifiedNamePattern.test(eventId)){addForgettableCallback(event,listener);}else{event.on(listener);}}
+return oboeApi;}),removeListener=function(eventId,p2,p3){if(eventId=='done'){rootNodeFinishedEvent.un(p2);}else if(eventId=='node'||eventId=='path'){oboeBus.un(eventId+':'+p2,p3);}else{var listener=p2;oboeBus(eventId).un(listener);}
+return oboeApi;};function addProtectedCallback(eventName,callback){oboeBus(eventName).on(protectedCallback(callback),callback);return oboeApi;}
+function addForgettableCallback(event,callback,listenerId){listenerId=listenerId||callback;var safeCallback=protectedCallback(callback);event.on(function(){var discard=false;oboeApi.forget=function(){discard=true;};apply(arguments,safeCallback);delete oboeApi.forget;if(discard){event.un(listenerId);}},listenerId);return oboeApi;}
+function protectedCallback(callback){return function(){try{return callback.apply(oboeApi,arguments);}catch(e){setTimeout(function(){throw new Error(e.message);});}}}
+function fullyQualifiedPatternMatchEvent(type,pattern){return oboeBus(type+':'+pattern);}
+function wrapCallbackToSwapNodeIfSomethingReturned(callback){return function(){var returnValueFromCallback=callback.apply(this,arguments);if(defined(returnValueFromCallback)){if(returnValueFromCallback==oboe.drop){emitNodeDrop();}else{emitNodeSwap(returnValueFromCallback);}}}}
+function addSingleNodeOrPathListener(eventId,pattern,callback){var effectiveCallback;if(eventId=='node'){effectiveCallback=wrapCallbackToSwapNodeIfSomethingReturned(callback);}else{effectiveCallback=callback;}
+addForgettableCallback(fullyQualifiedPatternMatchEvent(eventId,pattern),effectiveCallback,callback);}
+function addMultipleNodeOrPathListeners(eventId,listenerMap){for(var pattern in listenerMap){addSingleNodeOrPathListener(eventId,pattern,listenerMap[pattern]);}}
+function addNodeOrPathListenerApi(eventId,jsonPathOrListenerMap,callback){if(isString(jsonPathOrListenerMap)){addSingleNodeOrPathListener(eventId,jsonPathOrListenerMap,callback);}else{addMultipleNodeOrPathListeners(eventId,jsonPathOrListenerMap);}
+return oboeApi;}
+oboeBus(ROOT_PATH_FOUND).on(function(rootNode){oboeApi.root=functor(rootNode);});oboeBus(HTTP_START).on(function(_statusCode,headers){oboeApi.header=function(name){return name?headers[name]:headers;}});return oboeApi={on:addListener,addListener:addListener,removeListener:removeListener,emit:oboeBus.emit,node:partialComplete(addNodeOrPathListenerApi,'node'),path:partialComplete(addNodeOrPathListenerApi,'path'),done:partialComplete(addForgettableCallback,rootNodeFinishedEvent),start:partialComplete(addProtectedCallback,HTTP_START),fail:oboeBus(FAIL_EVENT).on,abort:oboeBus(ABORTING).emit,write:oboeBus(STREAM_DATA).emit,finish:oboeBus(STREAM_END).emit,header:noop,root:noop,source:contentSource};}
+function wire(httpMethodName,contentSource,body,headers,withCredentials){var oboeBus=pubSub();if(contentSource){streamingHttp(oboeBus,httpTransport(),httpMethodName,contentSource,body,headers,withCredentials);}
+clarinet(oboeBus);ascentManager(oboeBus,incrementalContentBuilder(oboeBus));patternAdapter(oboeBus,jsonPathCompiler);return instanceApi(oboeBus,contentSource);}
+function applyDefaults(passthrough,url,httpMethodName,body,headers,withCredentials,cached){headers=headers?JSON.parse(JSON.stringify(headers)):{};if(body){if(!isString(body)){body=JSON.stringify(body);headers['Content-Type']=headers['Content-Type']||'application/json';}}else{body=null;}
+function modifiedUrl(baseUrl,cached){if(cached===false){if(baseUrl.indexOf('?')==-1){baseUrl+='?';}else{baseUrl+='&';}
+baseUrl+='_='+new Date().getTime();}
+return baseUrl;}
+return passthrough(httpMethodName||'GET',modifiedUrl(url,cached),body,headers,withCredentials||false);}
+function oboe(arg1){var nodeStreamMethodNames=list('resume','pause','pipe'),isStream=partialComplete(hasAllProperties,nodeStreamMethodNames);if(arg1){if(isStream(arg1)||isString(arg1)){return applyDefaults(wire,arg1);}else{return applyDefaults(wire,arg1.url,arg1.method,arg1.body,arg1.headers,arg1.withCredentials,arg1.cached);}}else{return wire();}}
+oboe.drop=function(){return oboe.drop;};if(typeof define==="function"&&define.amd){define("oboe",[],function(){return oboe;});}else if(typeof exports==='object'){module.exports=oboe;}else{window.oboe=oboe;}})((function(){try{return window;}catch(e){return self;}}()),Object,Array,Error,JSON);'use strict';if(tr.isVinn){global.oboe=global.window.oboe;global.window=undefined;}else if(tr.isNode){global.window=undefined;const path=HTMLImportsLoader.hrefToAbsolutePath('/oboe/dist/oboe-node.js');global.oboe=require(path);}'use strict';tr.exportTo('tr.e.importer',function(){const STRING_ID_SUFFIX='_sid';const PLURAL_STRING_ID_SUFFIX='_sids';function isStringReference(s){return s.endsWith(STRING_ID_SUFFIX)||s.endsWith(PLURAL_STRING_ID_SUFFIX);}
+function getStringReferenceName(name){if(name.endsWith(PLURAL_STRING_ID_SUFFIX)){return name.slice(0,-PLURAL_STRING_ID_SUFFIX.length);}
+return name.slice(0,-STRING_ID_SUFFIX.length);}
+function deferenceStrings(idToString,o){const clone=Object.assign({},o);for(const[key,value]of Object.entries(clone)){if(isStringReference(key)){const name=getStringReferenceName(key);clone[name]=idToString(value);}}
+return clone;}
+function singularize(word){if(word.endsWith('s')){return word.slice(0,-1);}
+return word;}
+function getMetadataPairs(dataJson){const isMetadata=v=>typeof v!=='object'||Array.isArray(v);const pairs=Object.entries(dataJson);const metadataPairs=pairs.filter(([_,v])=>isMetadata(v));return metadataPairs;}
+function getGroupPairs(dataJson){const pairs=Object.entries(dataJson);const nonMapPairs=pairs.filter(([k,_])=>k!=='maps');const groupPairs=nonMapPairs.filter(([_,v])=>typeof v==='object');return groupPairs;}
+function createMap(mapJson){const map=new Map();for(const entry of mapJson){if(entry.id===undefined){throw new Error('Missing required key "id" in streaming event.');}
+map.set(entry.id,entry);}
+return map;}
+function createMaps(mapsJson){const maps=new Map();for(const[name,mapJson]of Object.entries(mapsJson)){maps.set(name,createMap(mapJson));}
+return maps;}
+function createGroup(groupJson,opt_startTime){const entries=[];const n=Object.values(groupJson)[0].length;for(let i=0;i<n;i++){const entry={};for(const name in groupJson){entry[name]=groupJson[name][i];}
+entries.push(entry);}
+const timeDelta=groupJson.timeDelta;if(opt_startTime===undefined&&timeDelta!==undefined){throw new Error('Missing required key "startTime" in streaming event.');}
+if(opt_startTime){let delta=0;for(const entry of entries){delta+=entry.timeDelta?entry.timeDelta:0;entry.time=opt_startTime+delta;}}
+return entries;}
+function createGroups(groupsJson,opt_startTime){const groups=new Map();for(const[name,groupJson]of Object.entries(groupsJson)){groups.set(name,createGroup(groupJson,opt_startTime));}
+return groups;}
+function createMetadata(metadataPairs){const metadata=new Map();for(const[name,value]of metadataPairs){metadata.set(name,value);}
+if(metadata.get('version')===undefined){throw new Error('Missing required key "version" in streaming event.');}
+return metadata;}
+class ProfilingDictionaryReader{constructor(opt_metadata,opt_maps,opt_groups,opt_parent){this.metadata=opt_metadata||new Map();this.maps=opt_maps||new Map();this.groups=opt_groups||new Map();this.parent_=opt_parent||undefined;this.inflated_=undefined;this.raw_=undefined;this.boundGetString_=this.getString.bind(this);this.deferenceStrings_=o=>deferenceStrings(this.boundGetString_,o);}
+static empty(){return new ProfilingDictionaryReader();}
+get parent(){return this.parent_;}
+get raw(){if(this.raw_)return this.raw_;this.raw_={};for(const[name,group]of this.groups.entries()){this.raw_[name]=group;}
+return this.raw_;}
+get inflated(){if(this.inflated_)return this.inflated_;this.inflated_={};for(const[name,group]of this.groups.entries()){this.inflated_[name]=this.inflateGroup(group);}
+return this.inflated_;}
+getNewMap(name){return this.maps.get(name)||new Map();}
+getMapValue(mapName,id){let value=this.getNewMap(mapName).get(id);if(value===undefined&&this.parent){value=this.parent.getMapValue(mapName,id);}
+return value;}
+getString(id){const value=this.getMapValue('strings',id);if(value===undefined)return undefined;return value.string;}
+hasMap(name){if(this.maps.has(name))return true;if(this.parent===undefined)return false;return this.parent.hasMap(name);}
+inflateGroup(group){return group.map(this.inflateEntry.bind(this));}
+inflateEntry(entry){const inflatedEntry={};for(const[name,value]of Object.entries(entry)){let inflatedValue;if(this.hasMap(name)){const id=value;inflatedValue=this.deferenceStrings_(this.getMapValue(name,id));}else{inflatedValue=value;}
+inflatedEntry[singularize(name)]=inflatedValue;}
+return this.deferenceStrings_(inflatedEntry);}
+expandData(data){const mapsJson=data.maps||{};const groupsJson=data.allocators||{};const metadataPairs=getMetadataPairs(data);const metadata=createMetadata(metadataPairs);const opt_startTime=metadata.get('startTime');const maps=createMaps(mapsJson);const groups=createGroups(groupsJson,opt_startTime);return new ProfilingDictionaryReader(metadata,maps,groups,this);}
+expandEvent(event){return this.expandData(event.args.data);}}
+return{ProfilingDictionaryReader,singularize,deferenceStringsForTest:deferenceStrings,};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)return undefined;const domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString(){let str='';if(this.file_){str+=this.file_;}
+if(this.line_>0){str+=':'+this.line_;}
+if(this.column_>0){str+=':'+this.column_;}
+return str;}};return{SourceInfo,};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString(){const str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};const JSSourceState={COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown',};return{JSSourceInfo,JSSourceState,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocateSimple();this.address_=address;this.size_=size;const rePrefix=/^(\w*:)?([*~]?)(.*)$/m;const tokens=rePrefix.exec(name);const prefix=tokens[1];let state=tokens[2];const body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{state=tr.model.source_info.JSSourceState.UNKNOWN;}
+let rawName;let rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{const spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){const lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;const lineColumnMatch=lineColumnRegEx.exec(url);let lineNumber;let columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber,columnNumber};}
+const nativeSuffix=' native';const isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;const urlData=splitLineAndColumn(rawUrl);const url=urlData.url||'';const line=urlData.lineNumber||0;const column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);}
+TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
+TraceCodeMap.prototype={addEntry(addressHex,size,name,scriptId){const entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry(oldAddressHex,newAddressHex,size){const entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_(addressHex){const bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_(addressHex){addressHex=addressHex.slice(2);const bankSizeHexDigits=13;const maxHexDigits=16;const bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);let bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+return bank;}};function TraceCodeBank(){this.entries_=[];}
+TraceCodeBank.prototype={removeEntry(address){if(this.entries_.length===0)return undefined;const index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);const entry=this.entries_[index];if(!entry||entry.address!==address)return undefined;this.entries_.splice(index,1);return entry;},lookupEntry(address){const index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;const entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry(newEntry){if(this.entries_.length===0){this.entries_.push(newEntry);}
+const endAddress=newEntry.address+newEntry.size;const lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);let index;for(index=lastIndex-1;index>=0;--index){const entry=this.entries_[index];const entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)break;}
+++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap,};});'use strict';tr.exportTo('tr.importer',function(){function ContextProcessor(model){this.model_=model;this.activeContexts_=[];this.stackPerType_={};this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.seenSnapshots_={};}
+ContextProcessor.prototype={enterContext(contextType,scopedId){const newActiveContexts=[this.getOrCreateContext_(contextType,scopedId),];for(const oldContext of this.activeContexts_){if(oldContext.type===contextType){this.pushContext_(oldContext);}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},leaveContext(contextType,scopedId){this.leaveContextImpl_(context=>context.type===contextType&&context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},destroyContext(scopedId){for(const stack of Object.values(this.stackPerType_)){let newLength=0;for(let i=0;i<stack.length;++i){if(stack[i].snapshot.scope!==scopedId.scope||stack[i].snapshot.idRef!==scopedId.id){stack[newLength++]=stack[i];}}
+stack.length=newLength;}
+this.leaveContextImpl_(context=>context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},leaveContextImpl_(predicate){const newActiveContexts=[];for(const oldContext of this.activeContexts_){if(predicate(oldContext)){const previousContext=this.popContext_(oldContext.type);if(previousContext){newActiveContexts.push(previousContext);}}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},getOrCreateContext_(contextType,scopedId){const context={type:contextType,snapshot:{scope:scopedId.scope,idRef:scopedId.id}};const key=this.getContextKey_(context);if(key in this.contextCache_){return this.contextCache_[key];}
+this.contextCache_[key]=context;const snapshotKey=this.getSnapshotKey_(scopedId);this.seenSnapshots_[snapshotKey]=true;return context;},pushContext_(context){if(!(context.type in this.stackPerType_)){this.stackPerType_[context.type]=[];}
+this.stackPerType_[context.type].push(context);},popContext_(contextType){if(!(contextType in this.stackPerType_)){return undefined;}
+return this.stackPerType_[contextType].pop();},getContextKey_(context){return[context.type,context.snapshot.scope,context.snapshot.idRef].join('\x00');},getSnapshotKey_(scopedId){return[scopedId.scope,scopedId.idRef].join('\x00');},get activeContexts(){if(this.cachedEntryForActiveContexts_===undefined){let key=[];for(const context of this.activeContexts_){key.push(this.getContextKey_(context));}
+key.sort();key=key.join('\x00');if(key in this.contextSetCache_){this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}else{this.activeContexts_.sort(function(a,b){const keyA=this.getContextKey_(a);const keyB=this.getContextKey_(b);if(keyA<keyB){return-1;}
+if(keyA>keyB){return 1;}
+return 0;}.bind(this));this.contextSetCache_[key]=Object.freeze(this.activeContexts_);this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}}
+return this.cachedEntryForActiveContexts_;},invalidateContextCacheForSnapshot(scopedId){const snapshotKey=this.getSnapshotKey_(scopedId);if(!(snapshotKey in this.seenSnapshots_))return;this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.activeContexts_=this.activeContexts_.map(function(context){if(context.snapshot.scope!==scopedId.scope||context.snapshot.idRef!==scopedId.id){return context;}
+return{type:context.type,snapshot:{scope:context.snapshot.scope,idRef:context.snapshot.idRef}};});this.seenSnapshots_={};},};return{ContextProcessor,};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocateSimple();this.view_=undefined;}
+Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined){throw new Error('Missing typeName argument');}
+const typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');};Annotation.prototype={get guid(){return this.guid_;},onRemove(){},toDict(){throw new Error('Not implemented');},getOrCreateView(viewport){if(!this.view_){this.view_=this.createView_(viewport);}
+return this.view_;},createView_(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict')){throw new Error('Must have fromDict method');}
+if(!e.typeInfo.metadata.typeName){throw new Error('Registered Annotations must provide typeName');}});return{Annotation,};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
+YComponent.prototype={toDict(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;}
+Location.fromViewCoordinates=function(viewport,viewX,viewY){const dt=viewport.currentDisplayTransform;const xWorld=dt.xViewToWorld(viewX);const yComponents=[];let elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){const xWorld=ts;const yComponents=[];const containerToTrack=viewport.containerToTrackMap;let elem=containerToTrack.getTrackByStableId(stableId);if(!elem)return;const firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack(viewport){const containerToTrack=viewport.containerToTrackMap;for(const i in this.yComponents_){const yComponent=this.yComponents_[i];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)return track;}},toViewCoordinates(viewport){const dt=viewport.currentDisplayTransform;const containerToTrack=viewport.containerToTrackMap;const viewX=dt.xWorldToView(this.xWorld_);let viewY=-1;for(const index in this.yComponents_){const yComponent=this.yComponents_[index];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){const boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX,viewY};},toDict(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw(ctx){throw new Error('Not implemented');}};return{AnnotationView,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);const endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);let startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;const sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
+RectAnnotation.fromDict=function(dict){const args=dict.args;const startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);const endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);};RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea(){Polymer.dom(Polymer.dom(this.textArea_).parentNode).removeChild(this.textArea_);},draw(ctx){const coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_){this.textArea_.style.visibility='hidden';}
+return;}
+if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;Polymer.dom(Polymer.dom(ctx.canvas).parentNode).appendChild(this.textArea_);}
+this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
+this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
+this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
+ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
+CommentBoxAnnotation.fromDict=function(dict){const args=dict.args;const location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove(){this.view_.removeTextArea();},toDict(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation,};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id,pid){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
+tr.model.OBJECT_DEFAULT_SCOPE+'\' as the default scope.');}
+this.scope=scope;this.id=id;this.pid=pid;}
+ScopedId.prototype={toString(){const pidStr=this.pid===undefined?'':'pid: '+this.pid+', ';return'{'+pidStr+'scope: '+this.scope+', id: '+this.id+'}';},toStringWithDelimiter(delim){return(this.pid===undefined?'':this.pid)+delim+
+this.scope+delim+this.id;}};return{ScopedId,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);};XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation,};});'use strict';tr.exportTo('tr.e.importer',function(){const Base64=tr.b.Base64;const deepCopy=tr.b.deepCopy;const ColorScheme=tr.b.ColorScheme;const HeapDumpTraceEventImporter=tr.e.importer.HeapDumpTraceEventImporter;const LegacyHeapDumpTraceEventImporter=tr.e.importer.LegacyHeapDumpTraceEventImporter;const StreamingEventExpander=tr.e.importer.StreamingEventExpander;const ProfilingDictionaryReader=tr.e.importer.ProfilingDictionaryReader;function getEventColor(event,opt_customName){if(event.cname){return ColorScheme.getColorIdForReservedName(event.cname);}else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+function isLegacyChromeClockSyncEvent(event){return event.name!==undefined&&event.name.startsWith(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX)&&((event.ph==='S')||(event.ph==='F'));}
+const PRODUCER='producer';const CONSUMER='consumer';const STEP='step';const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,BACKGROUND,LIGHT,DETAILED];const GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';const LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX='ClockSyncEvent.';const BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};const WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;const OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];const SUBTRACE_FIELDS=new Set(['powerTraceAsString','systemTraceEvents',]);const NON_METADATA_FIELDS=new Set(['displayTimeUnit','samples','stackFrames','traceAnnotations','traceEvents',...SUBTRACE_FIELDS]);function TraceEventImporter(model,eventData){this.hasEvents_=undefined;this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.stackFrameTree_=new tr.model.ProfileTree();this.subtraces_=[];this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.contextProcessorPerThread={};this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.profileTrees_=new Map();this.profileInfo_=new Map();this.legacyChromeClockSyncStartEvent_=undefined;this.legacyChromeClockSyncFinishEvent_=undefined;this.allMemoryDumpEvents_={};this.heapProfileExpander=new ProfilingDictionaryReader();this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY;this.toModelTime_=undefined;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']'){eventData=eventData+']';}}
+this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
+if(this.events_.traceEvents){const container=this.events_;this.events_=this.events_.traceEvents;for(const subtraceField of SUBTRACE_FIELDS){if(container[subtraceField]){this.storeSubtrace_(container[subtraceField]);}}
+this.storeSamples_(container.samples);this.storeStackFrames_(container.stackFrames);this.storeDisplayTimeUnit_(container.displayTimeUnit);this.storeTraceAnnotations_(container.traceAnnotations);this.storeMetadata_(container);}else if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',function(e){return oboe.drop;}).node('!.powerTraceAsString',this.storeSubtrace_.bind(this)).node('!.systemTraceEvents',this.storeSubtrace_.bind(this)).node('!.samples',this.storeSamples_.bind(this)).node('!.stackFrames',this.storeStackFrames_.bind(this)).node('!.displayTimeUnit',this.storeDisplayTimeUnit_.bind(this)).node('!.traceAnnotations',this.storeTraceAnnotations_.bind(this)).done(this.storeMetadata_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}}
+TraceEventImporter.canImport=function(eventData){if(eventData instanceof tr.b.TraceStream){if(eventData.isBinary)return false;eventData=eventData.header;}
+if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(eventData instanceof Array&&eventData.length&&eventData[0].ph){return true;}
+if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph){return true;}
+if(eventData.samples&&eventData.samples.length&&eventData.stackFrames!==undefined){return true;}}}
+return false;};TraceEventImporter.scopedIdForEvent_=function(event){const scope=event.scope||tr.model.OBJECT_DEFAULT_SCOPE;let pid=undefined;if(event.id!==undefined){if(event.id2!==undefined){throw new Error('Event has both id and id2');}
+pid=tr.model.LOCAL_ID_PHASES.has(event.ph)?event.pid:undefined;return new tr.model.ScopedId(scope,event.id,pid);}else if(event.id2!==undefined){if(event.id2.global!==undefined){return new tr.model.ScopedId(scope,event.id2.global);}else if(event.id2.local!==undefined){return new tr.model.ScopedId(scope,event.id2.local,event.pid);}
+throw new Error('Event that uses id2 must have either a global or local ID');}
+return undefined;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces(){const subtraces=this.subtraces_;this.subtraces_=[];return subtraces;},deepCopyIfNeeded_(obj){if(obj===undefined)obj={};if(this.eventsWereFromString_)return obj;return deepCopy(obj);},deepCopyAlways_(obj){if(obj===undefined)obj={};return deepCopy(obj);},processAsyncEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event,thread});},processFlowEvent(event,opt_slice){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastSimpleGuid(),sequenceNumber:this.allFlowEvents_.length,event,slice:opt_slice,thread});},processCounterEvent(event){let ctrName;if(event.id!==undefined){ctrName=event.name+'['+event.id+']';}else{ctrName=event.name;}
+const ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctrName);const reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(const seriesName in event.args){const colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
+const ts=this.toModelTimeFromUs_(event.ts);ctr.series.forEach(function(series){const val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event,thread});if(thread.guid in this.contextProcessorPerThread){const processor=this.contextProcessorPerThread[thread.guid];const scopedId=TraceEventImporter.scopedIdForEvent_(event);if(event.ph==='D'){processor.destroyContext(scopedId);}
+processor.invalidateContextCacheForSnapshot(scopedId);}},processContextEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(!(thread.guid in this.contextProcessorPerThread)){this.contextProcessorPerThread[thread.guid]=new tr.importer.ContextProcessor(this.model_);}
+const scopedId=TraceEventImporter.scopedIdForEvent_(event);const contextType=event.name;const processor=this.contextProcessorPerThread[thread.guid];if(event.ph==='('){processor.enterContext(contextType,scopedId);}else if(event.ph===')'){processor.leaveContext(contextType,scopedId);}else{this.model_.importWarning({type:'unknown_context_phase',message:'Unknown context event phase: '+event.ph+'.'});}},setContextsFromThread_(thread,slice){if(thread.guid in this.contextProcessorPerThread){slice.contexts=this.contextProcessorPerThread[thread.guid].activeContexts;}},processDurationEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const ts=this.toModelTimeFromUs_(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){const slice=thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);this.setContextsFromThread_(thread,slice);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t'){throw new Error('This should never happen');}
+thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts),getEventColor(event));if(event.name&&slice.title!==event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+event.name+' in endSlice'});}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_(dstArgs,srcArgs,eventName){for(const arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1){return undefined;}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in){event.flowPhase=STEP;}else{event.flowPhase=PRODUCER;}}else if(event.flow_in){event.flowPhase=CONSUMER;}
+const slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.maybeToModelTimeFromUs_(event.dur),this.maybeToModelTimeFromUs_(event.tts),this.maybeToModelTimeFromUs_(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);this.setContextsFromThread_(thread,slice);return slice;},processJitCodeEvent(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined){this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();}
+const map=this.v8ProcessCodeMaps_[event.pid];const data=event.args.data;if(event.name==='JitCodeMoved'){map.moveEntry(data.code_start,data.new_code_start,data.code_len);}else{map.addEntry(data.code_start,data.code_len,data.name,data.script_id);}},processMetadataEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.argsStripped)return;if(event.name==='process_name'){const process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){const process=this.model_.getOrCreateProcess(event.pid);const labels=event.args.labels.split(',');for(let i=0;i<labels.length;i++){process.addLabelIfNeeded(labels[i]);}}else if(event.name==='process_uptime_seconds'){const process=this.model_.getOrCreateProcess(event.pid);process.uptime_seconds=event.args.uptime;}else if(event.name==='process_sort_index'){const process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){let n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined){n=Math.max(n,this.softwareMeasuredCpuCount_);}
+this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){const stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){const objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
+event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else if(event.name==='TraceConfig'){this.model_.metadata.push({name:'TraceConfig',value:event.args.value});}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
+let constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+const instantEvent=new constructor(event.cat,event.name,getEventColor(event),this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:{const process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;}
+default:throw new Error('Unknown instant event type: '+event.s);}},getOrCreateProfileTree_(sampleType,id){if(!this.profileTrees_.has(sampleType)){this.profileTrees_.set(sampleType,new Map());}
+const profileTreeMap=this.profileTrees_.get(sampleType);if(profileTreeMap.has(id)){return profileTreeMap.get(id);}
+const profileTree=new tr.model.ProfileTree();profileTreeMap.set(id,profileTree);const info=this.profileInfo_.get(id);if(info!==undefined){profileTree.startTime=info.startTime;profileTree.pid=info.pid;profileTree.tid=info.tid;}
+return profileTree;},processSample(event){if(event.args===undefined||event.args.data===undefined){return;}
+if(event.id===undefined){throw new Error('No event ID in sample');}
+const data=event.args.data;if(data.startTime!==undefined){this.profileInfo_.set(event.id,{startTime:data.startTime,pid:event.pid,tid:event.tid});}
+const timeDeltas=data.timeDeltas;for(const sampleType in data){if(sampleType==='timeDeltas'||sampleType==='startTime'){continue;}
+if(data[sampleType].samples&&timeDeltas&&data[sampleType].samples.length!==timeDeltas.length){throw new Error('samples and timeDeltas array should have same length');}
+const profileTree=this.getOrCreateProfileTree_(sampleType,event.id);const nodes=data[sampleType].nodes;const samples=data[sampleType].samples;if(nodes!==undefined){for(const node of nodes){const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);const profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
+profileTree.add(profileNode);}}
+if(samples!==undefined){const thread=this.model_.getOrCreateProcess(profileTree.pid).getOrCreateThread(profileTree.tid);for(let i=0,len=samples.length;i<len;++i){const node=profileTree.getNode(samples[i]);profileTree.endTime+=timeDeltas[i];const start=this.toModelTimeFromUs_(profileTree.endTime);this.model_.samples.push(new tr.model.Sample(start,node.sampleTitle,node,thread));}}}},processLegacyV8Sample(event){const data=event.args.data;const sampleType='legacySample';const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);if(data.vm_state==='js'&&!data.stack.length)return;const profileTree=this.getOrCreateProfileTree_(sampleType,event.pid);if(profileTree.getNode(-1)===undefined){profileTree.add(new ProfileNodeType(-1,{url:'',scriptId:-1,functionName:'unknown'},undefined));}
+let node=undefined;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){const map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();let parentNode=undefined;for(let i=0;i<data.stack.length;i++){const entry=map.lookupEntry(data.stack[i]);if(entry===undefined){node=profileTree.getNode(-1);}else{node=profileTree.getNode(entry.id);if(node===undefined){const sourceInfo=entry.sourceInfo;node=new ProfileNodeType(entry.id,{functionName:entry.name,url:entry.sourceInfo.file,lineNumber:sourceInfo.line!==-1?sourceInfo.line:undefined,columnNumber:sourceInfo.column!==-1?sourceInfo.column:undefined,scriptid:entry.sourceInfo.scriptId},parentNode);profileTree.add(node);}}
+parentNode=node;}}else{node=profileTree.getNode(data.vm_state);if(node===undefined){node=new ProfileNodeType(data.vm_state,{url:'',functionName:data.vm_state},undefined);profileTree.add(node);}}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.model_.samples.push(new tr.model.Sample(this.toModelTimeFromUs_(event.ts),node.sampleTitle,node,thread));},processTraceSampleEvent(event){if(event.name==='V8Sample'||event.name.startsWith('Profile')){this.v8SamplingData_.push(event);return;}
+let node=this.stackFrameTree_.getNode(event.name);if(node===undefined&&event.sf!==undefined){node=this.stackFrameTree_.getNode('g'+event.sf);}
+if(node===undefined){let id=event.name;if(event.sf){id='g'+event.sf;}
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');node=this.stackFrameTree_.add(new ProfileNodeType(id,{functionName:event.name},undefined));}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),'Trace Event Sample',node,thread,undefined,1,this.deepCopyIfNeeded_(event.args));this.setContextsFromThread_(thread,sample);this.model_.samples.push(sample);},processMemoryDumpEvent(event){if(event.ph!=='v'){throw new Error('Invalid memory dump event phase "'+event.ph+'".');}
+const dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
+const pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
+dumpId+'\') without a PID.'});return;}
+const allEvents=this.allMemoryDumpEvents_;let dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined){allEvents[dumpId]=dumpIdEvents={};}
+let processEvents=dumpIdEvents[pid];if(processEvents===undefined){dumpIdEvents[pid]=processEvents=[];}
+processEvents.push(event);},processClockSyncEvent(event){if(event.ph!=='c'){throw new Error('Invalid clock sync event phase "'+event.ph+'".');}
+const syncId=event.args.sync_id;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+event.ts+' without an ID.'});return;}
+if(event.args&&event.args.issue_ts!==undefined){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.args.issue_ts),tr.b.Unit.timestampFromUs(event.ts));}else{this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.ts));}},processLegacyChromeClockSyncEvent(event){if(event.ph==='S'){this.legacyChromeClockSyncStartEvent_=event;}else if(event.ph==='F'){this.legacyChromeClockSyncFinishEvent_=event;}
+if(this.legacyChromeClockSyncStartEvent_===undefined||this.legacyChromeClockSyncFinishEvent_===undefined){return;}
+const startSyncId=this.legacyChromeClockSyncStartEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);const finishSyncId=this.legacyChromeClockSyncFinishEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);if(startSyncId!==finishSyncId){throw new Error('Inconsistent clock sync ID of legacy Chrome clock sync events');}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,startSyncId,tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncStartEvent_.ts),tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncFinishEvent_.ts));},processV8Events(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)return a.ts-b.ts;if(a.ph==='M'||a.ph==='I'){return-1;}else if(b.ph==='M'||b.ph==='I'){return 1;}
+return 0;});const length=this.v8SamplingData_.length;for(let i=0;i<length;++i){const event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){if(event.name.startsWith('Profile')){this.processSample(event);}else{this.processLegacyV8Sample(event);}}}},importClockSyncMarkers(){if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.importClockSyncMarker_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let i=0;i<this.events_.length;i++){this.importClockSyncMarker_(this.events_[i]);}}},importClockSyncMarker_(event){const isLegacyChromeClockSync=isLegacyChromeClockSyncEvent(event);if(event.ph!=='c'&&!isLegacyChromeClockSync)return;const eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);if(isLegacyChromeClockSync){this.processLegacyChromeClockSyncEvent(event);}else{this.processClockSyncEvent(event);}},importEvents(){this.hasEvents_=false;if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g');}
+if(this.traceAnnotations_)this.importAnnotations_();if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.processEvent_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let eI=0;eI<this.events_.length;eI++){this.processEvent_(this.events_[eI]);}}
+this.processV8Events();for(const frame of Object.values(this.v8ProcessRootStackFrame_)){frame.removeAllChildren();}},storeSubtrace_(subtrace){this.subtraces_.push(subtrace);return oboe.drop;},storeSamples_(samples){this.sampleEvents_=samples;return oboe.drop;},storeStackFrames_(stackFrames){this.stackFrameEvents_=stackFrames;return oboe.drop;},storeDisplayTimeUnit_(unitName){if(!unitName)return;const unit=tr.b.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;return oboe.drop;},storeTraceAnnotations_(traceAnnotations){this.traceAnnotations_=traceAnnotations;return oboe.drop;},storeMetadata_(container){for(const fieldName of Object.keys(container)){if(NON_METADATA_FIELDS.has(fieldName))continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName!=='metadata')continue;const metadata=container[fieldName];if(metadata['highres-ticks']){this.model_.isTimeHighResolution=metadata['highres-ticks'];}
+if(metadata['clock-domain']){this.clockDomainId_=metadata['clock-domain'];}}
+return oboe.drop;},processEvent_(event){this.hasEvents_=true;const importOptions=this.model_.importOptions;const trackDetailedModelStats=importOptions.trackDetailedModelStats;const modelStats=this.model_.stats;if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+let eventSizeInBytes=undefined;if(trackDetailedModelStats){eventSizeInBytes=JSON.stringify(event).length;}
+switch(event.ph){case'B':case'E':modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);break;case'X':{modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);const slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined){this.processFlowEvent(event,slice);}
+break;}
+case'b':case'e':case'n':case'S':case'F':case'T':case'p':modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);break;case'I':case'i':case'R':modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);break;case'P':modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);break;case'C':modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);break;case'M':modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);break;case'N':case'D':case'O':modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);break;case's':case't':case'f':modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);break;case'v':modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);break;case'(':case')':this.processContextEvent(event);break;case'c':break;default:modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}
+return oboe.drop;},importStackFrames_(rawStackFrames,idPrefix){const model=this.model_;for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const fullId=idPrefix+id;const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(const id in rawStackFrames){const fullId=idPrefix+id;const stackFrame=model.stackFrames[fullId];if(stackFrame===undefined){throw new Error('Internal error');}
+const rawStackFrame=rawStackFrames[id];const parentId=rawStackFrame.parent;let parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{const parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
+stackFrame.parentFrame=parentStackFrame;}
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');if(idPrefix==='g'){for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const node=this.stackFrameTree_.add(new ProfileNodeType('g'+id,{functionName:rawStackFrame.name},undefined));node.colorId=ColorScheme.getColorIdForGeneralPurposeString(textForColor);node.parentId=rawStackFrame.parent;}
+for(const id in rawStackFrames){const node=this.stackFrameTree_.getNode('g'+id);const parentId=node.parentId;let parentNode=undefined;if(parentId!==undefined){parentNode=this.stackFrameTree_.getNode('g'+parentId);if(parentNode===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentId+' for stack frame \''+node.name+'\' (ID '+node.id+').'});}
+node.parentNode=parentNode;}}}},importObjectTypeNameMap_(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
+pid+' multiple times.'});return;}
+let objectTypeNamePrefix=undefined;let objectTypeNameSuffix=undefined;const objectTypeNameMap={};for(const objectTypeId in rawObjectTypeNameMap){const rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(let i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){const pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
+if(objectTypeNamePrefix!==undefined&&rawObjectTypeName.startsWith(objectTypeNamePrefix)&&rawObjectTypeName.endsWith(objectTypeNameSuffix)){objectTypeNameMap[objectTypeId]=rawObjectTypeName.substring(objectTypeNamePrefix.length,rawObjectTypeName.length-objectTypeNameSuffix.length);}else{objectTypeNameMap[objectTypeId]=rawObjectTypeName;}}
+this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_(){for(const id in this.traceAnnotations_){const annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.traceAnnotations_[id].typeName+'\"'});continue;}
+this.model_.addAnnotation(annotation);}},finalizeImport(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_(event,opt_lookForEndEvent){let sf;let stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
+if(stack!==undefined){return this.model_.resolveStackToStackFrame_(event.pid,stack);}
+if(sf===undefined)return undefined;const stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_(pid,stack){return undefined;},importSampleData(){if(!this.sampleEvents_)return;const m=this.model_;const events=this.sampleEvents_;if(this.hasEvents_===undefined){throw new Error('importEvents is not run before importSampleData');}else if(!this.hasEvents_){for(let i=0;i<events.length;i++){const event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+const threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(let i=0;i<events.length;i++){const event=events[i];const thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+let cpu;if(event.cpu!==undefined){cpu=m.kernel.getOrCreateCpu(event.cpu);}
+const leafNode=this.stackFrameTree_.getNode('g'+event.sf);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),event.name,leafNode,thread,cpu,event.weight);m.samples.push(sample);}},createAsyncSlices_(){if(this.allAsyncEvents_.length===0)return;this.allAsyncEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const legacyEvents=[];const nestableAsyncEventsByKey={};const nestableMeasureAsyncEventsByKey={};for(let i=0;i<this.allAsyncEvents_.length;i++){const asyncEventState=this.allAsyncEvents_[i];const event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
+if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+if(event.cat==='blink.user_timing'){const matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){const key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined){nestableMeasureAsyncEventsByKey[key]=[];}
+nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
+const key=event.cat+':'+id.toStringWithDelimiter(':');if(nestableAsyncEventsByKey[key]===undefined){nestableAsyncEventsByKey[key]=[];}
+nestableAsyncEventsByKey[key].push(asyncEventState);}
+this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_(legacyEvents){if(legacyEvents.length===0)return;legacyEvents.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const asyncEventStatesByNameThenID={};for(let i=0;i<legacyEvents.length;i++){const asyncEventState=legacyEvents[i];const event=asyncEventState.event;const name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+const key=id.toStringWithDelimiter(':');if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined){asyncEventStatesByNameThenID[name]={};}
+if(asyncEventStatesByNameThenID[name][key]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
+asyncEventStatesByNameThenID[name][key]=[];asyncEventStatesByNameThenID[name][key].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
+if(asyncEventStatesByNameThenID[name][key]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
+const events=asyncEventStatesByNameThenID[name][key];events.push(asyncEventState);if(event.ph==='F'){const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,name);const slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),this.toModelTimeFromUs_(events[0].event.ts),Object.assign({},events[0].event.args,events[events.length-1].event.args),this.toModelTimeFromUs_(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=key;const stepType=events[1].event.ph;let isValid=true;for(let j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)break;}
+if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named '+
+name+' with id='+id+' had a step before the start event.'});continue;}
+if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named '+
+name+' with id='+id+' had a step after the finish event.'});continue;}
+const startIndex=j+(stepType==='T'?0:-1);const endIndex=startIndex+1;let subName=name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p')){subName=events[j].event.args.step;}
+const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,subName);const subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),this.toModelTimeFromUs_(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),this.toModelTimeFromUs_(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=key;slice.subSlices.push(subSlice);}
+if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
+delete asyncEventStatesByNameThenID[name][key];}}}},createNestableAsyncSlices_(nestableEventsByKey){for(const key in nestableEventsByKey){const eventStateEntries=nestableEventsByKey[key];const parentStack=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){let parentIndex=-1;for(let k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
+if(parentStack.length>0){eventStateEntry.parentEntry=parentStack[parentStack.length-1];}
+if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
+const topLevelSlices=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+let startState=undefined;let endState=undefined;let sliceArgs=eventStateEntry.event.args||{};let sliceError=undefined;const id=TraceEventImporter.scopedIdForEvent_(eventStateEntry.event);if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined){return Object.assign({},args1,args2);}
+const args3={};args3.params=Object.assign({},args1.params,args2.params);return Object.assign({},args1,args2,args3);}
+const endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
+const isTopLevel=(eventStateEntry.parentEntry===undefined);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);let threadStart=undefined;let threadDuration=undefined;if(startState.event.tts&&startState.event.use_async_tts){threadStart=this.toModelTimeFromUs_(startState.event.tts);if(endState.event.tts){const threadEnd=this.toModelTimeFromUs_(endState.event.tts);threadDuration=threadEnd-threadStart;}}
+const slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),this.toModelTimeFromUs_(startState.event.ts),sliceArgs,this.toModelTimeFromUs_(endState.event.ts-startState.event.ts),isTopLevel,threadStart,threadDuration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined){slice.error=sliceError;}
+eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
+for(let si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_(stepType,event){if(stepType!==event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+
+TraceEventImporter.scopedIdForEvent_(event.event)+' had both begin and end steps, which is not allowed.'});return false;}
+return true;},validateFlowEvent_(event){if(event.name===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
+if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
+return true;}
+if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
+return true;}
+return false;},createFlowSlices_(){if(this.allFlowEvents_.length===0)return;const createFlowEvent=function(thread,event,opt_slice){let startSlice;let flowId;let flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=this.toModelTimeFromUs_(event.ts+event.dur);}else{const ts=this.toModelTimeFromUs_(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)return undefined;flowId=event.id;flowStartTs=ts;}
+const flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,this.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=this.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}.bind(this);const finishFlowEventWith=function(flowEvent,thread,event,refGuid,bindToParent,opt_slice){let endSlice;if(event.bind_id){endSlice=opt_slice;}else{const ts=this.toModelTimeFromUs_(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+if(endSlice===undefined)return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=this.toModelTimeFromUs_(event.ts)-flowEvent.start;flowEvent.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}.bind(this);const processFlowConsumer=function(flowIdToEvent,sliceGuidToEvent,event,slice){let flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){const flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+const refGuid=undefined;const ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+return true;}.bind(this);const processFlowProducer=function(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
+const flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;}.bind(this);this.allFlowEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const flowIdToEvent={};const sliceGuidToEvent={};const flowStatus={};for(let i=0;i<this.allFlowEvents_.length;++i){const data=this.allFlowEvents_[i];const refGuid=data.refGuid;const event=data.event;const thread=data.thread;if(!this.validateFlowEvent_(event))continue;if(event.bind_id){const slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
+flowStatus[event.bind_id]=true;}else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice)){continue;}
+flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
+flowStatus[event.bind_id]=true;}}
+continue;}
+let flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
+flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
+let bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1){bindToParent=true;}else if(event.cat.indexOf('ipc.flow')>-1){bindToParent=true;}}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+bindToParent=true;}}
+const ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_(){if(this.allObjectEvents_.length===0)return;const processEvent=function(objectEventState){const event=objectEventState.event;const scopedId=TraceEventImporter.scopedIdForEvent_(event);const thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+if(scopedId===undefined||scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
+const process=thread.parent;const ts=this.toModelTimeFromUs_(event.ts);let instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+scopedId+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+scopedId+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
+let snapshot;try{const args=this.deepCopyIfNeeded_(event.args.snapshot);let cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+let baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+snapshot=process.objects.addSnapshot(scopedId,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
+scopedId+' at ts='+ts+': '+e});return;}
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);const instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+scopedId+' at ts='+ts+': '+e});return;}}
+if(instance){instance.colorId=getEventColor(event,instance.typeName);}}.bind(this);this.allObjectEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const allObjectEvents=this.allObjectEvents_;for(let i=0;i<allObjectEvents.length;i++){const objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_(){for(const proc of Object.values(this.model_.processes)){this.createImplicitObjectsForProcess_(proc);}},createImplicitObjectsForProcess_(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)return;if(referencingObjectFieldValue instanceof
+tr.model.ObjectSnapshot){return null;}
+if(referencingObjectFieldValue.id===undefined)return;const implicitSnapshot=referencingObjectFieldValue;const rawId=implicitSnapshot.id;const m=/(.+)\/(.+)/.exec(rawId);if(!m){throw new Error('Implicit snapshots must have names.');}
+delete implicitSnapshot.id;const name=m[1];const id=m[2];let res;let cat;if(implicitSnapshot.cat!==undefined){cat=implicitSnapshot.cat;}else{cat=containingSnapshot.objectInstance.category;}
+let baseTypename;if(implicitSnapshot.base_type){baseTypename=implicitSnapshot.base_type;}else{baseTypename=undefined;}
+const scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
+res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot)){throw new Error('Created object must be instanceof snapshot');}
+return res.args;}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){const res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[i],func,containingSnapshot,thisArg);}}
+return;}
+for(const key in object){const res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[key],func,containingSnapshot,thisArg);}}}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined){throw new Error('args cannot have an id field inside it');}
+iterObject(snapshot.args,processField,snapshot,this);},this);},this);},minimalTimestampInPidToEvents_(pidToEvents){let smallestTs=Infinity;for(const events of Object.values(pidToEvents)){for(const event of events){if(event.ts<smallestTs){smallestTs=event.ts;}}}
+return smallestTs;},createMemoryDumps_(){const pairs=Object.entries(this.allMemoryDumpEvents_);const key=x=>this.minimalTimestampInPidToEvents_(x);pairs.sort((x,y)=>key(x[1])-key(y[1]));for(const[dumpId,pidToEvents]of pairs){this.createGlobalMemoryDump_(pidToEvents,dumpId);}},createGlobalMemoryDump_(dumpIdEvents,dumpId){const globalRange=new tr.b.math.Range();for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){globalRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}}
+if(globalRange.isEmpty){throw new Error('Internal error: Global memory dump without events');}
+const globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);const globalMemoryAllocatorDumpsByFullName={};const levelsOfDetail={};const allMemoryAllocatorDumpsByGuid={};for(const pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
+globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){const processRange=new tr.b.math.Range();for(let i=0;i<processEvents.length;i++){processRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}
+if(processRange.isEmpty){throw new Error('Internal error: Process memory dump without events');}
+const process=this.model_.getOrCreateProcess(pid);const processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;const processMemoryAllocatorDumpsByFullName={};for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+this.parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId);this.parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId);}
+if(levelsOfDetail.process===undefined){levelsOfDetail.process=processMemoryDump.vmRegions?DETAILED:LIGHT;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'global',levelsOfDetail.process)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for global memory'+' dump (dump ID='+dumpId+').'});}
+processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId){const rawTotals=dumps.process_totals;if(rawTotals===undefined)return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const totals={};let platformSpecificTotals=undefined;for(const rawTotalName in rawTotals){const rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
+if(rawTotalName==='peak_resident_set_bytes'){totals.peakResidentBytes=parseInt(rawTotalValue,16);continue;}
+if(rawTotalName==='is_peak_rss_resetable'){totals.arePeakResidentBytesResettable=!!rawTotalValue;continue;}
+if(platformSpecificTotals===undefined){platformSpecificTotals={};totals.platformSpecific=platformSpecificTotals;}
+platformSpecificTotals[rawTotalName]=parseInt(rawTotalValue,16);}
+if(totals.peakResidentBytes===undefined&&totals.arePeakResidentBytesResettable!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
+if(totals.arePeakResidentBytesResettable!==undefined&&totals.peakResidentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
+processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId){const rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)return;const rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const vmRegions=new Array(rawVmRegions.length);for(let i=0;i<rawVmRegions.length;i++){const rawVmRegion=rawVmRegions[i];const byteStats={};const rawByteStats=rawVmRegion.bs;for(const rawByteStatName in rawByteStats){const rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
+i+' ('+rawVmRegion.mf+') in process memory dump for '+'PID='+pid+' and dump ID='+dumpId+' does not have a value.'});continue;}
+const byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
+rawByteStatValue+') of VM region '+i+' ('+
+rawVmRegion.mf+') in process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+byteStats[byteStatName]=parseInt(rawByteStatValue,16);if(byteStatName==='proportionalResident'&&byteStats[byteStatName]===0){byteStats[byteStatName]=undefined;}}
+vmRegions[i]=new tr.model.VMRegion(parseInt(rawVmRegion.sa,16),parseInt(rawVmRegion.sz,16),rawVmRegion.pf,rawVmRegion.mf,byteStats);}
+processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId){const idPrefix='p'+pid+':';let importer;if(dumps.heaps){const processTypeMap=this.objectTypeNameMap_[pid];if(processTypeMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
+importer=new LegacyHeapDumpTraceEventImporter(this.model_,processMemoryDump,processTypeMap,idPrefix,dumpId,dumps.heaps);}else if(dumps.heaps_v2){const data=dumps.heaps_v2;this.heapProfileExpander=this.heapProfileExpander.expandData(data);this.addNewStackFramesFromExpander_(this.heapProfileExpander,idPrefix);importer=new HeapDumpTraceEventImporter(this.heapProfileExpander,this.model_.stackFrames,processMemoryDump,idPrefix,this.model_);}
+if(!importer)return;const heapDumps=importer.parse();if(!heapDumps)return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(Object.keys(heapDumps).length>0){processMemoryDump.heapDumps=heapDumps;}},addNewStackFramesFromExpander_(expander,idPrefix){const nodeMap=expander.getNewMap('nodes');const newStackFrames={};for(const[id,stackFrame]of nodeMap.entries()){if(!this.model_.stackFrames[idPrefix+id]){newStackFrames[id]={id,name:expander.getString(stackFrame.name_sid),};if(stackFrame.parent)newStackFrames[id].parent=stackFrame.parent;}}
+this.importStackFrames_(newStackFrames,idPrefix);},parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId){const rawLevelOfDetail=dumps.level_of_detail;let level;switch(rawLevelOfDetail){case'background':level=BACKGROUND;break;case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
+if(MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level)>MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])){levelsOfDetail[scope]=level;}
+return false;},parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){const rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)return;for(let fullName in rawAllocatorDumps){const rawAllocatorDump=rawAllocatorDumps[fullName];const guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
+const flags=rawAllocatorDump.flags||0;const isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);let containerMemoryDump;let dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+let allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+dstIndex[fullName].guid+', '+guid+' (ignored) for'+' PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined){allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+' dumped in different contexts.'});continue;}
+if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' for PID='+
+pid+' and dump ID='+dumpId+' has multiple names: '+
+allocatorDump.fullName+', '+fullName+' (ignored).'});continue;}
+if(!isWeakDump){allocatorDump.weak=false;}}
+let attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
+for(const attrName in attributes){const attrArgs=attributes[attrName];const attrType=attrArgs.type;const attrValue=attrArgs.value;switch(attrType){case'scalar':{if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+'.'});break;}
+const unit=attrArgs.units==='bytes'?tr.b.Unit.byName.sizeInBytes_smallerIsBetter:tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.b.Scalar(unit,value));break;}
+case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+'.'});break;}
+allocatorDump.addDiagnostic(attrName,attrValue);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown type provided for attribute '+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+': '+
+attrType});break;}}}},inferMemoryAllocatorDumpTree_(memoryAllocatorDumpsByFullName){const rootAllocatorDumps=[];const fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(let i=0;i<fullNames.length;i++){let fullName=fullNames[i];let allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){const lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+const parentFullName=fullName.substring(0,lastSlashIndex);let parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];let parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
+memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
+allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted){if(!allocatorDump.weak){while(parentAllocatorDump!==undefined&&parentAllocatorDump.weak===undefined){parentAllocatorDump.weak=false;parentAllocatorDump=parentAllocatorDump.parent;}}
+break;}
+fullName=parentFullName;allocatorDump=parentAllocatorDump;}}
+for(const fullName in memoryAllocatorDumpsByFullName){const allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined){allocatorDump.weak=true;}}
+return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined)continue;const rawEdges=dumps.allocators_graph;if(rawEdges===undefined)continue;for(let j=0;j<rawEdges.length;j++){const rawEdge=rawEdges[j];const sourceGuid=rawEdge.source;const sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
+sourceGuid+').'});continue;}
+const targetGuid=rawEdge.target;const targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
+targetGuid+').'});continue;}
+const importance=rawEdge.importance;const edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+sourceDump.owns.target.fullName+').'});}else{sourceDump.owns=edge;targetDump.ownedBy.push(edge);}
+break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}},toModelTimeFromUs_(ts){if(!this.toModelTime_){this.toModelTime_=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);}
+return this.toModelTime_(tr.b.Unit.timestampFromUs(ts));},maybeToModelTimeFromUs_(ts){if(ts===undefined){return undefined;}
+return this.toModelTimeFromUs_(ts);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter,};});'use strict';tr.exportTo('tr.e.measure',function(){const AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';const matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
+AsyncSlice.apply(this,arguments);}
+MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.subTypes.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice,};});'use strict';tr.exportTo('tr.e.net',function(){const AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
+NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
+if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
+this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_){return this.url_;}
+if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(let i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined){this.url_=this.subSlices[i].url;}}}
+this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined){return this.byteCount_;}
+this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
+for(let i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
+return this.byteCount_;}};AsyncSlice.subTypes.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+function parseArgs(argsString){const args={};if(argsString){const argsArray=argsString.split(';');for(let i=0;i<argsArray.length;++i){const parts=argsArray[i].split('=');if(parts[0]){args[parts.shift()]=parts.join('=');}}}
+return args;}
+AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice(thread,category,name,cookie,ts,args){const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);const key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
+this.openAsyncSlices[key]=slice;},closeAsyncSlice(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
+const key=category+':'+name+':'+cookie;const slice=this.openAsyncSlices[key];if(!slice){return;}
+for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
+slice.args[arg]=args[arg];}
+slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=eventBase.details.split('|');switch(eventData[0]){case'B':{const ppid=parseInt(eventData[1]);const title=eventData[2];const args=parseArgs(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;}
+case'E':{const ppid=this.ppids_[pid];if(ppid===undefined){break;}
+const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
+const slice=thread.sliceGroup.endSlice(ts);const args=parseArgs(eventData[3]);for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
+slice.args[arg]=args[arg];}
+break;}
+case'C':{const ppid=parseInt(eventData[1]);const name=eventData[2];const value=parseInt(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;}
+case'S':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;}
+case'F':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;}
+default:return false;}
+return true;}};Parser.register(AndroidParser);return{AndroidParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;const binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');const binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
+const TF_ONE_WAY=0x01;const TF_ROOT_OBJECT=0x04;const TF_STATUS_CODE=0x08;const TF_ACCEPT_FDS=0x10;const NO_FLAGS=0;function binderFlagsToHuman(num){const flag=parseInt(num,16);let str='';if(flag&TF_ONE_WAY){str+='this is a one-way call: async, no return; ';}
+if(flag&TF_ROOT_OBJECT){str+='contents are the components root object; ';}
+if(flag&TF_STATUS_CODE){str+='contents are a 32-bit status code; ';}
+if(flag&TF_ACCEPT_FDS){str+='allow replies with file descriptors; ';}
+if(flag===NO_FLAGS){str+='No Flags Set';}
+return str;}
+function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
+function binderCodeToHuman(code){return'Java Layer Dependent';}
+function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
+const kthread=trans.calling_kthread.thread;const internalSlice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internalSlice.title=slice.title;internalSlice.id=slice.id;internalSlice.colorId=slice.colorId;slice.subSlices.push(internalSlice);return internalSlice;}
+function generateBinderArgsForSlice(trans,cThreadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':cThreadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
+binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
+binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
+function BinderTransaction(events,callingPid,callingTs,callingKthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=callingPid;this.calling_ts=callingTs;this.calling_kthread=callingKthread;}
+function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
+BinderParser.prototype={__proto__:Parser.prototype,binderLock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventName.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const binderThread=isBinderThread(eventBase.threadName);const name=eventBase.threadName;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);const rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventBase.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const trans=new BinderTransaction(event,pid,ts,kthread);const args=generateBinderArgsForSlice(trans,eventBase.threadName);const priorReceive=this.getPriorReceiveOnPID(pid);if(priorReceive!==false){return this.modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event);}
+const recursiveTrans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursiveTrans!==false){return this.modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args);}
+const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply){slice.title='binder transaction';}else{slice.title='binder transaction async';}
+this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const transactionkey=parseInt(event[1]);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){const syncTrans=syncComplete[0];const syncSlice=syncTrans.slice;const responseTrans=syncComplete[1];const responseSlice=responseTrans.slice;syncSlice.duration=ts-syncSlice.start;const syncInternal=doInternalSlice(syncTrans,syncSlice,ts);const responseTs=responseSlice.start+responseSlice.duration;const responseInternal=doInternalSlice(responseTrans,responseSlice,responseTs);if(responseSlice.outFlowEvents.length===0||syncSlice.inFlowEvents.length===0){const flow=this.generateFlow(responseInternal,syncInternal,responseTrans,syncTrans);syncSlice.inFlowEvents.push(flow);responseSlice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
+for(let i=1;i<syncSlice.inFlowEvents.length;i++){syncSlice.inFlowEvents[i].duration=ts-syncSlice.inFlowEvents[i].start;}
+return true;}
+const trForRecv=this.getTransactionWaitingForRecv(transactionkey);if(trForRecv!==false){if(!trForRecv.expect_reply){const args=generateBinderArgsForSlice(trForRecv,eventBase.threadName);const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);const fakeEvent=[0,0,0,0,0,0,0];const fakeTrans=new BinderTransaction(fakeEvent,pid,ts,kthread);const flow=this.generateFlow(trForRecv.slice,slice,trForRecv,fakeTrans);this.model_.flowEvents.push(flow);trForRecv.slice.title='binder transaction async';trForRecv.slice.duration=.03;return true;}
+trForRecv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,trForRecv]);return true;}
+return false;},modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args){const recursiveSlice=recursiveTrans[1].slice;const origSlice=recursiveTrans[0].slice;recursiveSlice.duration=ts-recursiveSlice.start;trans.slice=recursiveSlice;if(trans.is_reply_transaction){origSlice.duration=ts-origSlice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursiveTrans);if(isReplyToOrigin(recursiveTrans[0],trans)){this.removeRecursiveTransaction(pid);}}else{const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
+return true;},modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event){const calleeSlice=priorReceive[1].slice;const calleeTrans=priorReceive[1];const recvTs=priorReceive[0];let slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recvTs,ts-recvTs,0,0,args);const flow=this.generateFlow(calleeSlice,slice,calleeTrans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[calleeTrans,trans]);}else{slice.title='binder reply';const trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recvTs,(ts-recvTs),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
+trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[calleeTrans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
+return true;},getRecursiveTransactionNeedingCompletion(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){return false;}
+const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction(pid){const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
+this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID(pid){if(this.receivedTransWaitingConversion[pid]===undefined){return false;}
+const len=this.receivedTransWaitingConversion[pid].length;if(len===0)return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion(transactionkey,tuple){const dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion(transactionkey){const ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv(transactionkey){const ret=this.transWaitingRecv[transactionkey];if(ret===undefined)return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow(from,to,fromTrans,toTrans){const title='Transaction from : '+
+this.pid2name(fromTrans.calling_pid)+' From PID: '+fromTrans.calling_pid+' to pid: '+
+toTrans.calling_pid+' Thread Name: '+this.pid2name(toTrans.calling_pid);const ts=from.start;const flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice(tgid,pid,name,kthread){return{'Thread Name':name,pid,'gid':tgid};},pid2name(pid){return this.kthreadlookup[pid];},doNameMappings(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName(pid,name){if(this.pid2name(pid)===undefined){this.kthreadlookup[pid]=name;}}};Parser.register(BinderParser);return{BinderParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');const event=re.exec(eventBase.details);const name=event[1];const rwBytes=parseInt(event[2]);const rBytes=parseInt(event[3]);const wBytes=parseInt(event[4]);const cycles=parseInt(event[5]);const ns=parseInt(event[6]);const sec=tr.b.convertUnit(ns,tr.b.UnitPrefixScale.METRIC.NANO,tr.b.UnitPrefixScale.METRIC.NONE);const readBandwidthInBps=rBytes/sec;const readBandwidthInMiBps=tr.b.convertUnit(readBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);const writeBandwidthInBps=wBytes/sec;const writeBandwidthInMiBps=tr.b.convertUnit(writeBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);let ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,readBandwidthInMiBps);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,writeBandwidthInMiBps);});return true;}};Parser.register(BusParser);return{BusParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);const name=event[1];const rate=parseInt(event[2]);const ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
+function splitData(input){const data={};const args=input.split(/\s+/);const len=args.length;for(let i=0;i<len;i++){const item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
+return data;}
+CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice(ts,eventName,cpu,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
+DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice(ts,category,threadName,pid,key,name){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
+kthread.openAsyncSlices[key]=slice;},closeAsyncSlice(ts,category,threadName,pid,key,args){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){const slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4WriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},f2fsSyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[5]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4SyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const datasync=(event[4]==='1')||(event[4]===1);const key=device+'-'+inode;const action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[3]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},blockRqIssueEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)return false;let action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
+if(event[2]){action+=' flush';}
+if(event[4]==='F'){action+=' fua';}
+if(event[5]==='A'){action+=' ahead';}
+if(event[6]==='S'){action+=' sync';}
+if(event[7]==='M'){action+=' meta';}
+const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)return false;const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const error=parseInt(event[10]);const key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device,sector,numSectors,error});return true;}};Parser.register(DiskParser);return{DiskParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
+DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)return false;const crtc=parseInt(event[1]);const seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc,seq});return true;}};Parser.register(DrmParser);return{DrmParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
+ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample(name,ts,frequency){const targetCpu=this.importer.getOrCreateCpu(0);const counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
+counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice(ts,pipe,fb,state){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice(ts,pipe,fb,args){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},pageFlipStateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)return false;const pipe=parseInt(event[1]);const fb=parseInt(event[2]);const state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe,fb});if(state!=='flipped'){this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);}
+return true;}};Parser.register(ExynosParser);return{ExynosParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
+GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice(title,ts,opt_args){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice(title,ts){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){const slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!==title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
+return true;},syncEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
+return true;},timerEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
+return true;}};Parser.register(GestureParser);return{GestureParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I2cParser(importer){Parser.call(this,importer);importer.registerEventHandler('i2c_write',I2cParser.prototype.i2cWriteEvent.bind(this));importer.registerEventHandler('i2c_read',I2cParser.prototype.i2cReadEvent.bind(this));importer.registerEventHandler('i2c_reply',I2cParser.prototype.i2cReplyEvent.bind(this));importer.registerEventHandler('i2c_result',I2cParser.prototype.i2cResultEvent.bind(this));}
+const i2cWriteReplyRE=new RegExp('i2c-(\\d+) #(\\d+) a=([\\da-fA-F]+) f=([\\da-fA-F]+) l=(\\d+) '+'(\\[[\\da-fA-F\\-]+\\])');const i2cReadRE=/i2c-(\d+) #(\d+) a=([\da-fA-F]+) f=([\da-fA-F]+) l=(\d+)/;const i2cResultRE=/i2c-(\d+) n=(\d+) ret=(\d+)/;I2cParser.prototype={__proto__:Parser.prototype,i2cWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c write';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cReadEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cReadRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c read';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength};return true;},i2cReplyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c reply';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cResultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cResultRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const numMessages=event[2];const ret=event[3];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);const args=thread.lastEntryArgs;if(args!==undefined){args['Number of messages']=numMessages;args.Return=ret;}
+pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle=undefined;thread.lastEntryTs=undefined;thread.lastEntryArgs=undefined;return true;},};function pushLastSliceIfNeeded(thread,id,currentTs){if(thread.lastEntryTs!==undefined){const duration=currentTs-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',thread.lastEntryTitle,ColorScheme.getColorIdForGeneralPurposeString(id),thread.lastEntryTs,thread.lastEntryArgs,duration);thread.thread.sliceGroup.pushSlice(slice);}}
+Parser.register(I2cParser);return{I2cParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
+I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice(ts,obj,plane){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice(ts,args){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},i915GemObjectSlice(ts,eventName,obj,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice(ts,eventName,dev,ring,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice(ts,eventName,reg,args){const kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj,size});return true;},gemObjectBindEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=event[2];const size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj,offset,size});return true;},gemObjectChangeDomainEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const read=event[2];const write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj,read,write});return true;},gemObjectPreadWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=parseInt(event[2]);const len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,offset,len});return true;},gemObjectFaultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const type=event[2];const index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,type,index});return true;},gemObjectDestroyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj});return true;},gemRingDispatchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingFlushEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const invalidate=event[3];const flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,invalidate,flush});return true;},gemRequestEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring});return true;},regRWEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)return false;const rw=event[1];const reg=event[2];const len=event[3];const data=event[3];this.i915RegSlice(ts,rw,reg,{rw,reg,len,data});return true;},flipEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)return false;const plane=parseInt(event[1]);const obj=event[2];if(eventName==='i915_flip_request'){this.i915FlipOpenSlice(ts,obj,plane);}else{this.i915FlipCloseSlice(ts,{obj,plane});}
+return true;},gpuFrequency(eventName,cpuNumver,pid,ts,eventBase){const event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)return false;const freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq});return true;}};Parser.register(I915Parser);return{I915Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
+const irqHandlerEntryRE=/irq=(\d+) name=(.+)/;const irqHandlerExitRE=/irq=(\d+) ret=(.+)/;const softirqRE=/vec=(\d+) \[action=(.+)\]/;const ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerEntryRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const name=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerExitRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const ret=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const vec=parseInt(event[1]);const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},ipiEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=ipiHandlerExitRE.exec(eventBase.details);if(!event)return false;const ipiName=event[1];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+const TestExports={};const funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=funcEnterRE.exec(eventBase.details);if(!eventData)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const name=eventData[1];const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+if(slices.openSliceCount>0){slices.endSlice(ts);}
+return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(let i=0;i<7;i++){const jobStr='JS'+i;const jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
+this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
+MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice(pid,tid,ts,func,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);const funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],blockinfo});},maliDDKCloseSlice(pid,tid,ts,args,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
+thread.sliceGroup.endSlice(ts);},autoDetectLineRE(line){const lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line)){return lineREWithThread;}
+const lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line)){return lineRENoThread;}
+return null;},lineRE:null,maliDDKEvent(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE===null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE===null)return false;}
+const maliEvent=this.lineRE.exec(eventBase.details);const tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
+return true;},dvfsSample(counterName,seriesName,ts,s){const value=parseInt(s);const counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/utilization=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/voltage=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample(cat,counterName,seriesName,ts,eventBase){const event=/val=(\d+)/.exec(eventBase.details);if(!event)return false;const value=parseInt(event[1]);const counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));importer.registerEventHandler('lowmemory_kill',MemReclaimParser.prototype.lowmemoryKill.bind(this));}
+const kswapdWakeRE=/nid=(\d+) order=(\d+)/;const kswapdSleepRE=/nid=(\d+)/;const reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;const reclaimEndRE=/nr_reclaimed=(\d+)/;const lowmemoryRE=/([^ ]+) \((\d+)\), page cache (\d+)kB \(limit (\d+)kB\), free (-?\d+)Kb/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake(eventName,cpuNumber,pid,ts,eventBase){const event=kswapdWakeRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const nid=parseInt(event[1]);const order=parseInt(event[2]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
+return true;},kswapdSleep(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
+kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimBeginRE.exec(eventBase.details);if(!event)return false;const order=parseInt(event[1]);const gfp=event[2];const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimEndRE.exec(eventBase.details);if(!event)return false;const nrReclaimed=parseInt(event[1]);const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nrReclaimed});}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;},lowmemoryKill(eventName,cpuNumber,pid,ts,eventBase){const event=lowmemoryRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const killedName=event[1];const killedPid=parseInt(event[2]);const cache=parseInt(event[3]);const free=parseInt(event[5]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.thread.sliceGroup.pushCompleteSlice('lowmemory','low memory kill',ts,0,0,0,{killed_name:killedName,killed_pid:killedPid,cache,free});return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice(ts,targetCpuNumber,eventType,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);if(eventType!=='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
+const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice(ts,targetCpuNumber,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
+const val=(cpuState!==4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice(ts,targetCpuNumber,powerState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
+powerCounter.series.forEach(function(series){if(series.name==='Min Frequency'){series.addCounterSample(ts,minFreq);}
+if(series.name==='Max Frequency'){series.addCounterSample(ts,maxFreq);}});},powerStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent(eventName,cpu,pid,ts,eventBase){const event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const minFreq=parseInt(event[1]);const maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
+const regulatorEnableRE=/name=(.+)/;const regulatorDisableRE=/name=(.+)/;const regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_(ctrName,valueName){const ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
+return ctr;},regulatorEnableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorEnableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorDisableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)return false;const name=event[1];const voltage=parseInt(event[2]);const ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
+const TestExports={};const schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');const schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;const schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+)(?: success=\d+)? target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedSwitchRE.exec(eventBase.details);if(!event)return false;const prevState=event[4];const nextComm=event[5];const nextPid=parseInt(event[6]);const nextPrio=parseInt(event[7]);if(eventBase.tgid!==undefined){const tgid=parseInt(eventBase.tgid);const process=this.importer.model_.getOrCreateProcess(tgid);if(!process.getThread(pid)){const thread=process.getOrCreateThread(pid);thread.name=eventBase.threadName;}}
+const nextThread=this.importer.threadsByLinuxPid[nextPid];let nextName;if(nextThread){nextName=nextThread.userFriendlyName;}else{nextName=nextComm;}
+const cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedWakeupRE.exec(eventBase.details);if(!event)return false;const fromPid=pid;const comm=event[1];pid=parseInt(event[2]);const prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)return false;cpuNumber=event[1];const state=event[2];const targetCpu=this.importer.getOrCreateCpu(cpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
+powerCounter.series.forEach(function(series){if(series.name==='State'){series.addCounterSample(ts,state.localeCompare('offline')?0:1);}});return true;},schedBlockedEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedBlockedRE.exec(eventBase.details);if(!event)return false;pid=parseInt(event[1]);const iowait=parseInt(event[2]);const caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+const syncTimelineRE=/name=(\S+) value=(\S*)/;const syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;const syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncTimelineRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;let value=thread.lastActiveValue;if(value===undefined)value=' ';const slice=new tr.model.ThreadSlice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncWaitRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const name='fence_wait("'+event[2]+'")';if(event[1]==='begin'){const slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]==='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
+return true;},syncPtEvent(eventName,cpuNumber,pid,ts,eventBase){return!!syncPtRE.exec(eventBase.details);}};Parser.register(SyncParser);return{SyncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
+const workqueueExecuteStartRE=/work struct (.+): function (\S+)/;const workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;return true;},executeQueueWork(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID='linux_clock_monotonic_to_ftrace_global';const IMPORT_PRIORITY=2;function FTraceImporter(model,events){this.importPriority=IMPORT_PRIORITY;this.model_=model;this.events_=events;this.wakeups_=[];this.blockedReasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};this.haveClockSyncedMonotonicToGlobal_=false;this.clockDomainId_=tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL;}
+const TestExports={};const lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithTGID=function(line){const groups=lineREWithTGID.exec(line);if(!groups)return groups;let tgid=groups[3];if(tgid[0]==='-')tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;const lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithIRQInfo=function(line){const groups=lineREWithIRQInfo.exec(line);if(!groups)return groups;return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;const lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;const lineParserWithLegacyFmt=function(line){const groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;const traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;const realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;const genericClockSyncRE=/trace_event_clock_sync: name=([\w\-]+)/;const pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]==='{')return false;if(lineREWithTGID.test(line))return lineParserWithTGID;if(lineREWithIRQInfo.test(line))return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))return lineParserWithLegacyFmt;return undefined;}
+TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)events=events.header;if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok){return true;}
+if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok){return true;}
+if(/^# tracer:/.test(events))return true;const lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!/^<!DOCTYPE html>/.test(header))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);if(!r.advanceToLineMatching(/^  <script>$/))return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))return failure;const eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
+function stripSuffix(str,suffix){if(!endsWith(str,suffix))return str;return str.substring(str,str.length-suffix.length);}
+let events=[];if(produceResult){for(let i=0;i<rawEvents.length;i++){let event=rawEvents[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[rawEvents[rawEvents.length-1]];}
+const oldLastEvent=events[events.length-1];const newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent===oldLastEvent)return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!(new RegExp('^<!DOCTYPE HTML>','i').test(header)))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);let events=[];let eventsBeginAtLine;while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/)){return failure;}
+eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
+if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine,};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importClockSyncMarkers(){this.lazyInit_();this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')return;if(traceEventClockSyncRE.exec(eventBase.details)||genericClockSyncRE.exec(eventBase.details)){this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}else if(realTimeClockSyncRE.exec(eventBase.details)){const match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}}.bind(this));},importEvents(){const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread(kernelThreadName,pid,tid){const key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[key];},getOrCreatePseudoThread(threadName){let thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
+return thread;},markPidRunnable(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts,tid:pid,fromTid:fromPid});},addPidBlockedReason(ts,pid,iowait,caller){this.blockedReasons_.push({ts,tid:pid,iowait,caller});},buildMapFromLinuxPidsToThreads_(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(const cpuNumber in this.model_.kernel.cpus){const cpu=this.model_.kernel.cpus[cpuNumber];for(let i=0;i<cpu.slices.length;i++){const cpuSlice=cpu.slices[i];const thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices){thread.tempCpuSlices=[];}
+thread.tempCpuSlices.push(cpuSlice);}}
+for(const i in this.wakeups_){const wakeup=this.wakeups_[i];const thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+for(const i in this.blockedReasons_){const reason=this.blockedReasons_[i];const thread=this.threadsByLinuxPid[reason.tid];if(!thread)continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
+this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)return;const origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});const wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});const reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});const slices=[];if(origSlices.length){const slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){const wakeup=wakeups.shift();const wakeupDuration=slice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
+let wakeup=undefined;for(let i=1;i<origSlices.length;i++){const prevSlice=origSlices[i-1];const nextSlice=origSlices[i];let midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){const w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+let blockedReason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){const r=reasons.shift();}
+if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blockedReason=reasons.shift();}
+const pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
+if(blockedReason!==undefined){const args={'kernel callsite when blocked:':blockedReason.caller};if(blockedReason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
+slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,args,midDuration));}else{slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));}
+if(wakeup!==undefined){const wakeupDuration=nextSlice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled==='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled==='R'||prevSlice.args.stateWhenDescheduled==='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled==='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled==='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+prevSlice.args.stateWhenDescheduled});}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
+thread.timeSlices=slices;},this);},createParsers_(){const allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();const parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase){let event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){const name=event[1];const pieces=event[2].split(' ');const args={perfTs:ts};for(let i=0;i<pieces.length;i++){const parts=pieces[i].split('=');if(parts.length!==2){throw new Error('omgbbq');}
+args[parts[0]]=parts[1];}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,name,ts);return true;}
+event=/name=([\w\-]+)/.exec(eventBase.details);if(event){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,event[1],ts);return true;}
+event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)return false;let monotonicTs=event[1]*1000;if(monotonicTs===0)monotonicTs=ts;if(this.haveClockSyncedMonotonicToGlobal_){return true;}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,ts);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,monotonicTs);this.haveClockSyncedMonotonicToGlobal_=true;return true;},traceMarkingWriteEvent_(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');const event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){const tag=eventBase.details.substring(0,2);if(tag==='B|'||tag==='E'||tag==='E|'||tag==='X|'||tag==='C|'||tag==='S|'||tag==='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+const writeEventName=eventName+':'+eventBase.subEventName;const handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importCpuData_(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;const handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_(){let extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok){extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);}
+let lineParser=undefined;if(extractResult.ok){for(const line of extractResult.lines){lineParser=this.parseLine_(line,lineParser);}}else{const r=new tr.importer.SimpleLineReader(this.events_);for(const line of r){lineParser=this.parseLine_(line,lineParser);}}},parseLine_(line,lineParser){line=line.trim();if(line.length===0)return lineParser;if(/^#/.test(line)){const clockType=/^# clock_type=([A-Z_]+)$/.exec(line);if(clockType){this.clockDomainId_=clockType[1];}
+return lineParser;}
+if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});return lineParser;}}
+const eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return lineParser;}
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);return lineParser;},forEachLine_(handler){for(let i=0;i<this.lines_.length;++i){const line=this.lines_[i];handler.apply(this,line);}},lazyInit_(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter,_FTraceImporterTestExports:TestExports,IMPORT_PRIORITY,};});'use strict';tr.exportTo('tr.e.importer.android.atrace_process_dump',function(){const IMPORT_PRIORITY=tr.e.importer.linux_perf.IMPORT_PRIORITY+1;const HEADER='ATRACE_PROCESS_DUMP';const PROTECTION_FLAG_LETTERS={'-':0,'r':tr.model.VMRegion.PROTECTION_FLAG_READ,'w':tr.model.VMRegion.PROTECTION_FLAG_WRITE,'x':tr.model.VMRegion.PROTECTION_FLAG_EXECUTE,'s':tr.model.VMRegion.PROTECTION_FLAG_MAYSHARE,};class AtraceProcessDumpImporter extends tr.importer.Importer{constructor(model,data){super(model,data);this.importPriority=IMPORT_PRIORITY;this.model_=model;this.raw_data_=data;this.clock_sync_markers_={};this.snapshots_=[];this.processes_={};}
+static canImport(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+return events.startsWith(HEADER);}
+get importerName(){return'AtraceProcessDumpImporter';}
+get model(){return this.model_;}
+lazyParseData(){if(this.raw_data_===undefined){return;}
+const dump=JSON.parse(this.raw_data_.slice(HEADER.length+1));this.clock_sync_markers_=dump.clock_sync_markers;this.snapshots_=dump.dump.snapshots;this.processes_=dump.dump.processes;this.raw_data_=undefined;}
+importClockSyncMarkers(){this.lazyParseData();for(const syncId in this.clock_sync_markers_){const ts=parseInt(this.clock_sync_markers_[syncId]);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,syncId,ts);}}
+setProcessMemoryDumpTotals_(pmd,processInfo){pmd.totals={'residentBytes':processInfo.rss*1024,'platformSpecific':{'vm':processInfo.vm*1024}};const totals=pmd.totals.platformSpecific;function importGpuMetric(name){if(processInfo[name]!==undefined&&processInfo[name]>0){totals[name]=processInfo[name]*1024;totals[name+'_pss']=processInfo[name+'_pss']*1024;}}
+importGpuMetric('gpu_egl');importGpuMetric('gpu_gl');importGpuMetric('gpu_etc');if(processInfo.pss!==undefined){totals.pss=processInfo.pss*1024;totals.swp=processInfo.swp*1024;totals.pc=processInfo.pc*1024;totals.pd=processInfo.pd*1024;totals.sc=processInfo.sc*1024;totals.sd=processInfo.sd*1024;}}
+setProcessMemoryDumpVmRegions_(pmd,processInfo){if(processInfo.mmaps===undefined){return;}
+const vmRegions=[];for(const memoryMap of processInfo.mmaps){const addr=memoryMap.vm.split('-').map(x=>parseInt(x,16));let flags=0;for(const letter of memoryMap.flags){flags|=PROTECTION_FLAG_LETTERS[letter];}
+const totals={'proportionalResident':memoryMap.pss*1024,'privateCleanResident':memoryMap.pc*1024,'privateDirtyResident':memoryMap.pd*1024,'sharedCleanResident':memoryMap.sc*1024,'sharedDirtyResident':memoryMap.sd*1024,'swapped':memoryMap.swp*1024,};vmRegions.push(new tr.model.VMRegion(addr[0],addr[1]-addr[0],flags,memoryMap.file,totals));}
+pmd.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);}
+importEvents(){this.lazyParseData();for(const[pid,process]of Object.entries(this.processes_)){const modelProcess=this.model_.getProcess(pid);if(modelProcess===undefined){continue;}
+modelProcess.name=process.name;const threads=process.threads;if(threads===undefined){continue;}
+for(const[tid,thread]of Object.entries(threads)){const modelThread=modelProcess.threads[tid];if(modelThread===undefined){continue;}
+modelThread.name=thread.name;}}
+for(const snapshot of this.snapshots_){const ts=parseInt(snapshot.ts);const memoryDump=snapshot.memdump;if(memoryDump===undefined){continue;}
+const gmd=new tr.model.GlobalMemoryDump(this.model_,ts);this.model_.globalMemoryDumps.push(gmd);for(const[pid,processInfo]of Object.entries(memoryDump)){if(processInfo.rss===undefined){continue;}
+const modelProcess=this.model_.getProcess(pid);if(modelProcess===undefined){continue;}
+const pmd=new tr.model.ProcessMemoryDump(gmd,modelProcess,ts);gmd.processMemoryDumps[pid]=pmd;modelProcess.memoryDumps.push(pmd);this.setProcessMemoryDumpTotals_(pmd,processInfo);this.setProcessMemoryDumpVmRegions_(pmd,processInfo);}}}}
+tr.importer.Importer.register(AtraceProcessDumpImporter);return{AtraceProcessDumpImporter,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;}
+Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity,};});'use strict';tr.exportTo('tr.e.importer.android',function(){const Importer=tr.importer.Importer;const ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};const activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+const eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');const amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');const amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');const amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');const amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(/^<!DOCTYPE html>/.test(events))return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName(component){const componentSplit=component.split('/');if(componentSplit[1].startsWith('.')){return componentSplit[0]+componentSplit[1];}
+return componentSplit[1];},getProcName(component){const componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity(activityName){if(activityName in activityMap){return activityMap[activityName];}
+const activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity(activityName){delete activityMap[activityName];},handleCreateActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity(ts,procName,activityName){const activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled(ts,pid,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max){this.addActivityToProcess(activity);}},handleLaunchTime(ts,activityName,launchTime){const activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess(activity){if(activity.pid===undefined)return;const process=this.model_.getOrCreateProcess(activity.pid);const range=tr.b.math.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);const newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_(line){let match=eventLogActivityRE.exec(line);if(!match)return;const firstRealtimeTs=this.model_.bounds.min-
+this.model_.realtime_to_monotonic_offset_ms;const year=new Date(firstRealtimeTs).getFullYear();const ts=match[1].substring(0,5)+'-'+year+' '+
+match[1].substring(5,match[1].length);const monotonicTs=Date.parse(ts)+
+this.model_.realtime_to_monotonic_offset_ms;const pid=match[2];const action=match[5];const data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonicTs,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2){this.handleOnResumeCalled(monotonicTs,pid,match[1]);}}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2){this.handleOnPauseCalled(monotonicTs,match[1]);}}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonicTs,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length===2){this.handleDestroyActivity(monotonicTs,this.getFullActivityName(match[1]));}}},importEvents(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();const lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(const activityName in activityMap){const activity=activityMap[activityName];if(activity.state===ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter,};});'use strict';tr.exportTo('tr.e.importer.android.process_data',function(){const Importer=tr.importer.Importer;const PROCESS_DUMP_HEADER='PROCESS DUMP';function ProcessDataImporter(model,processData){this.model_=model;this.processDataLines=processData.split('\n');this.importPriority=3;}
+ProcessDataImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(events.split('\n')[0]===PROCESS_DUMP_HEADER){return true;}
+return false;};ProcessDataImporter.prototype={__proto__:Importer.prototype,get importerName(){return'ProcessDataImporter';},get model(){return this.model_;},parseEventData(data){const allDumpedProcesses={};let parseProcesses=false;let parseThreads=false;let legacy=false;for(let i=1;i<data.length;i++){const cols=data[i].split(/\s+/);if(cols[0].startsWith('USER')){if(parseProcesses){parseProcesses=false;parseThreads=true;}else{parseThreads=false;parseProcesses=true;}
+const colCount=cols.length;if(parseProcesses&&colCount===9){legacy=false;}else if(parseProcesses&&colCount===8){legacy=true;}
+continue;}
+if(parseProcesses){const pid=Number(cols[1]);if(allDumpedProcesses[pid]===undefined){allDumpedProcesses[pid]={};}
+allDumpedProcesses[pid]={'name':cols[8],pid,'comm':cols[9]};continue;}
+if(parseThreads){let pid;let tid;let name;if(legacy){pid=Number(cols[1]);if(allDumpedProcesses[pid]!==undefined){tid=pid;}else{tid=pid;pid=Number(cols[2]);}
+name=cols.slice(8).join(' ');}else{pid=Number(cols[1]);tid=Number(cols[2]);name=cols.slice(3).join(' ');}
+if(allDumpedProcesses[pid]===undefined)continue;if(allDumpedProcesses[pid].threads===undefined){allDumpedProcesses[pid].threads={};}
+allDumpedProcesses[pid].threads[tid]={tid,name};continue;}}
+return allDumpedProcesses;},importEvents(){const allDumpedProcesses=this.parseEventData(this.processDataLines);const modelProcesses=this.model_.getAllProcesses();for(let i=0;i<modelProcesses.length;i++){const modelProcess=modelProcesses[i];const pid=modelProcess.pid;const dumpedProcess=allDumpedProcesses[pid];if(dumpedProcess===undefined){continue;}
+modelProcess.name=dumpedProcess.name;const processDumpThreads=dumpedProcess.threads;if(processDumpThreads!==undefined){for(const tid in modelProcess.threads){const modelThread=modelProcess.threads[tid];if(Number(pid)===Number(tid)){modelThread.name='UI thread';}else if(modelThread.name==='<...>'){if(processDumpThreads[tid]!==undefined){modelThread.name=processDumpThreads[tid].name;}}}}}}};Importer.register(ProcessDataImporter);return{ProcessDataImporter,};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.model_=model;this.samples_=[];this.syncTimestampsById_=new Map();this.parseTrace_(events);}
+const battorDataLineRE=new RegExp('^(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');const battorHeaderLineRE=/^# BattOr/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importClockSyncMarkers(){for(const[syncId,ts]of this.syncTimestampsById_){this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.BATTOR,syncId,ts);}},importEvents(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(tr.model.ClockDomainId.BATTOR);const powerSeries=this.model_.device.powerSeries=new tr.model.PowerSeries(this.model_.device);for(let i=0;i<this.samples_.length;i++){const sample=this.samples_[i];powerSeries.addPowerSample(modelTimeTransformer(sample.ts),sample.powerInW);}},parseTrace_(trace){const lines=trace.split('\n');for(let line of lines){line=line.trim();if(line.length===0)continue;if(line.startsWith('#'))continue;const groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line in BattOr trace: '+line});continue;}
+const ts=parseFloat(groups[1]);const voltageInV=tr.b.convertUnit(parseFloat(groups[2]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const currentInA=tr.b.convertUnit(parseFloat(groups[3]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const syncId=groups[4];if(syncId){this.syncTimestampsById_.set(syncId,ts);}
+if(voltageInV<0||currentInA<0){this.model_.importWarning({type:'parse_error',message:'The following line in the BattOr trace has a negative '+'voltage or current, neither of which are allowed: '+line+'. A common cause of this is that the device is charging '+'while the trace is being recorded.'});continue;}
+this.samples_.push(new Sample(ts,voltageInV,currentInA));}}};function Sample(ts,voltageInV,currentInA){this.ts=ts;this.voltageInV=voltageInV;this.currentInA=currentInA;}
+Sample.prototype={get powerInW(){return this.voltageInV*this.currentInA;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter,};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){const kPid=0;const kCategory='java';const kMethodLutEndMarker='\n*end\n';const kThreadsStart='\n*threads\n';const kMethodsStart='\n*methods\n';const kTraceMethodEnter=0x00;const kTraceMethodExit=0x01;const kTraceUnroll=0x02;const kTraceMethodActionMask=0x03;const kTraceHeaderLength=32;const kTraceMagicValue=0x574f4c53;const kTraceVersionSingleClock=2;const kTraceVersionDualClock=3;const kTraceRecordSizeSingleClock=10;const kTraceRecordSizeDualClock=14;function Reader(stringPayload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',stringPayload);}
+Reader.prototype={__proto__:Object.prototype,uint8(){const result=this.data_[this.position_];this.position_+=1;return result;},uint16(){let result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32(){let result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64(){const low=this.uint32();const high=this.uint32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},seekTo(position){this.position_=position;},hasMore(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
+DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){const header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents(){const divider=this.data_.indexOf(kMethodLutEndMarker)+
+kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();const traceReader=new Reader(this.data_.slice(divider));const magic=traceReader.uint32();if(magic!==kTraceMagicValue){throw Error('Failed to match magic value');}
+this.version_=traceReader.uint16();if(this.version_!==kTraceVersionDualClock){throw Error('Unknown version');}
+const dataOffest=traceReader.uint16();const startDateTime=traceReader.uint64();const recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry(reader){const tid=reader.uint16();const methodPacked=reader.uint32();const cpuSinceStart=reader.uint32();const wallClockSinceStart=reader.uint32();let method=methodPacked&~kTraceMethodActionMask;const action=methodPacked&kTraceMethodActionMask;const thread=this.getTid(tid);method=this.getMethodName(method);if(action===kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads(){let threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
+kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread(threadLine){const tid=threadLine.slice(0,threadLine.indexOf('\t'));const thread=this.getTid(parseInt(tid));thread.name=threadLine.slice(threadLine.indexOf('\t')+1);},getTid(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods(){let methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
+kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod(methodLine){const data=methodLine.split('\t');const methodId=parseInt(data[0]);const methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter,};});'use strict';tr.exportTo('tr.e.audits',function(){class LowMemoryAuditor extends tr.c.Auditor{constructor(model){super();this.model_=model;}
+runAnnotate(){this.model_.device.lowMemoryEvents=this.getLowMemoryEvents_();}
+getLowMemoryEvents_(){const model=this.model_;const result=[];for(const process of model.getAllProcesses()){for(const e of process.getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration!==0){continue;}
+if(e.category!=='lowmemory'){continue;}
+result.push(e);}}
+return result;}}
+tr.c.Auditor.register(LowMemoryAuditor);return{LowMemoryAuditor};});'use strict';function filterDuplicateTimestamps(timestamps){const dedupedTimestamps=[];let lastTs=0;for(const ts of timestamps){if(ts-lastTs>=1){dedupedTimestamps.push(ts);lastTs=ts;}}
+return dedupedTimestamps;}
+tr.exportTo('tr.e.audits',function(){const VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};const VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};const BEGIN_FRAME_SLICE_PRECISION={'DisplayScheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);}
+VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps(model){let times=[];let maxPrecision=Number.NEGATIVE_INFINITY;let maxTitle=undefined;function useInstead(title,precisions){const precision=precisions[title];if(precision===undefined)return false;if(title===maxTitle)return true;if(precision<=maxPrecision){if(precision===maxPrecision){model.importWarning({type:'VSyncAuditor',message:'Encountered two different VSync events ('+
+maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')',showToUser:false,});}
+return false;}
+maxPrecision=precision;maxTitle=title;times=[];return true;}
+for(const pid in model.processes){const process=model.processes[pid];for(const cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){const counter=process.counters[cid];for(let i=0;i<counter.series.length;i++){const series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
+for(const tid in process.threads){const thread=process.threads[tid];for(let i=0;i<thread.sliceGroup.slices.length;i++){const slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS)){times.push(slice.start);}else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us){times.push(slice.args.args.frame_time_us/1000.0);}}}}
+times.sort(function(x,y){return x-y;});return filterDuplicateTimestamps(times);}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor,};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;}
+EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length===0){return true;}
+if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length===0;}
+return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter,};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
+AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_){return this.frameEvents_;}
+this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){this.frameEvents_.push(event);}},this);return this.frameEvents_;}};tr.model.um.UserExpectation.subTypes.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(type,initiatorType){this.type=type;this.initiatorType=initiatorType;this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
+ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';const INITIATOR_HIERARCHY=[tr.model.um.INITIATOR_TYPE.PINCH,tr.model.um.INITIATOR_TYPE.FLING,tr.model.um.INITIATOR_TYPE.MOUSE_WHEEL,tr.model.um.INITIATOR_TYPE.SCROLL,tr.model.um.INITIATOR_TYPE.VIDEO,tr.model.um.INITIATOR_TYPE.WEBGL,tr.model.um.INITIATOR_TYPE.CSS,tr.model.um.INITIATOR_TYPE.MOUSE,tr.model.um.INITIATOR_TYPE.KEYBOARD,tr.model.um.INITIATOR_TYPE.TAP,tr.model.um.INITIATOR_TYPE.TOUCH];function combineInitiatorTypes(title1,title2){for(const item of INITIATOR_HIERARCHY){if(title1===item||title2===item)return item;}
+throw new Error('Invalid titles in combineInitiatorTypes');}
+ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames(typeNames){return this.associatedEvents.some(x=>typeNames.indexOf(x.typeName)>=0);},containsSliceTitle(title){return this.associatedEvents.some(x=>title===x.title);},createInteractionRecord(model){if(this.type!==ProtoExpectation.IGNORED_TYPE&&!this.isValid){model.importWarning({type:'ProtoExpectation',message:'Please file a bug with this trace. '+this.debug(),showToUser:true});return undefined;}
+const duration=this.end-this.start;let ir=undefined;switch(this.type){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,this.initiatorType,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,this.initiatorType,this.start,duration);break;}
+if(!ir)return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents){ir.associatedEvents.addEventSet(event.associatedEvents);}}
+this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices){event.subSlices.forEach(pushAssociatedEvents);}});return ir;},merge(other){this.initiatorType=combineInitiatorTypes(this.initiatorType,other.initiatorType);this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin){this.isAnimationBegin=true;}},pushEvent(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects(other){return(other.start<this.end)&&(other.end>this.start);},isNear(event,threshold){return(this.end+threshold)>event.start;},debug(){let debugString=this.type+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const ProtoExpectation=tr.importer.ProtoExpectation;const INITIATOR_TYPE=tr.model.um.INITIATOR_TYPE;const INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;const KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];const MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];const MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];const MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];const TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];const PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];const FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];const TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];const SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];const ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);const RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';const PLAYBACK_EVENT_TITLE='VideoPlayback';const CSS_ANIMATION_TITLE='Animation';const INPUT_MERGE_THRESHOLD_MS=200;const ANIMATION_MERGE_THRESHOLD_MS=32;const MOUSE_WHEEL_THRESHOLD_MS=40;const MOUSE_MOVE_THRESHOLD_MS=40;function compareEvents(x,y){if(x.start!==y.start){return x.start-y.start;}
+if(x.end!==y.end){return x.end-y.end;}
+if(x.guid&&y.guid){return x.guid-y.guid;}
+return 0;}
+function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
+function causedFrame(event){return event.associatedEvents.some(x=>x.title===tr.model.helpers.IMPL_RENDERING_STATS);}
+function getSortedFrameEventsByProcess(modelHelper){const frameEventsByPid={};for(const[pid,rendererHelper]of
+Object.entries(modelHelper.rendererHelpers)){frameEventsByPid[pid]=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);}
+return frameEventsByPid;}
+function getSortedInputEvents(modelHelper){const inputEvents=[];const browserProcess=modelHelper.browserHelper.process;const mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');for(const slice of mainThread.asyncSliceGroup.getDescendantEvents()){if(!slice.isTopLevel)continue;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))continue;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end)){continue;}
+inputEvents.push(slice);}
+return inputEvents.sort(compareEvents);}
+function findProtoExpectations(modelHelper,sortedInputEvents,warn){const protoExpectations=[];const handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations,handleWebGLAnimations,handleVideoAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents,warn));});protoExpectations.sort(compareEvents);return protoExpectations;}
+function handleKeyboardEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.KEYBOARD);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseResponseEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseWheelEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){const prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return;}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
+function handleMouseDragEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+protoExpectations.push(currentPE);}else{if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){const pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);}
+currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+mouseDownEvent=undefined;currentPE=undefined;break;}});if(mouseDownEvent){currentPE=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);currentPE.pushEvent(mouseDownEvent);protoExpectations.push(currentPE);}
+return protoExpectations;}
+function handleTapResponseEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handlePinchEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;const modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.type===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
+break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handleFlingEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+const browserHelper=modelHelper.browserHelper;const flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return;}
+switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){warn({type:'UserModelBuilder',message:'Unexpected FlingStart',showToUser:false,});currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+break;}});if(currentPE&&!currentPE.end){currentPE.end=modelHelper.model.bounds.max;}
+return protoExpectations;}
+function handleTouchEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
+break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
+if((sawFirstMove&&(currentPE.type===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){const prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handleScrollEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.type===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPE){warn({type:'UserModelBuilder',message:'Unexpected ScrollEnd',showToUser:false,});const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+currentPE.pushEvent(event);break;}});return protoExpectations;}
+function handleVideoAnimations(modelHelper,sortedInputEvents,warn){const events=[];for(const pid in modelHelper.rendererHelpers){for(const tid in modelHelper.rendererHelpers[pid].process.threads){for(const asyncSlice of
+modelHelper.rendererHelpers[pid].process.threads[tid].asyncSliceGroup.slices){if(asyncSlice.title===PLAYBACK_EVENT_TITLE){events.push(asyncSlice);}}}}
+events.sort(tr.importer.compareEvents);const protoExpectations=[];for(const event of events){const currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.VIDEO);currentPE.start=event.start;currentPE.end=event.end;currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return protoExpectations;}
+function handleCSSAnimations(modelHelper,sortedInputEvents,warn){const animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});const animationRanges=[];function pushAnimationRange(start,end,animation){const range=tr.b.math.Range.fromExplicitRange(start,end);range.animation=animation;animationRanges.push(range);}
+animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{let start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.data.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.data.state==='paused')||(sub.args.data.state==='idle')||(sub.args.data.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
+pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined){pushAnimationRange(start,animation.end,animation);}}});return animationRanges.map(function(range){const protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.CSS);protoExpectation.start=range.min;protoExpectation.end=range.max;protoExpectation.associatedEvents.push(range.animation);return protoExpectation;});}
+function findWebGLEvents(modelHelper,mailboxEvents,animationEvents){for(const event of modelHelper.model.getDescendantEvents()){if(event.title==='DrawingBuffer::prepareMailbox'){mailboxEvents.push(event);}else if(event.title==='PageAnimator::serviceScriptedAnimations'){animationEvents.push(event);}}}
+function findMailboxEventsNearAnimationEvents(mailboxEvents,animationEvents){if(animationEvents.length===0)return[];mailboxEvents.sort(compareEvents);animationEvents.sort(compareEvents);const animationIterator=animationEvents[Symbol.iterator]();let animationEvent=animationIterator.next().value;const filteredEvents=[];for(const event of mailboxEvents){while(animationEvent&&(animationEvent.start<(event.start-ANIMATION_MERGE_THRESHOLD_MS))){animationEvent=animationIterator.next().value;}
+if(!animationEvent)break;if(animationEvent.start<(event.start+ANIMATION_MERGE_THRESHOLD_MS)){filteredEvents.push(event);}}
+return filteredEvents;}
+function createProtoExpectationsFromMailboxEvents(mailboxEvents){const protoExpectations=[];let currentPE=undefined;for(const event of mailboxEvents){if(currentPE===undefined||!currentPE.isNear(event,ANIMATION_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.WEBGL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);}}
+return protoExpectations;}
+function handleWebGLAnimations(modelHelper,sortedInputEvents,warn){const prepareMailboxEvents=[];const scriptedAnimationEvents=[];findWebGLEvents(modelHelper,prepareMailboxEvents,scriptedAnimationEvents);const webGLMailboxEvents=findMailboxEventsNearAnimationEvents(prepareMailboxEvents,scriptedAnimationEvents);return createProtoExpectationsFromMailboxEvents(webGLMailboxEvents);}
+function postProcessProtoExpectations(modelHelper,protoExpectations){protoExpectations=findFrameEventsForAnimations(modelHelper,protoExpectations);protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
+function mergeIntersectingResponses(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.RESPONSE_TYPE)continue;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if(!otherPE.intersects(pe))continue;const typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function mergeIntersectingAnimations(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.ANIMATION_TYPE)continue;const isCSS=pe.initiatorType===INITIATOR_TYPE.CSS;const isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);const isVideo=pe.initiatorType===INITIATOR_TYPE.VIDEO;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if((isCSS&&otherPE.initiatorType!==INITIATOR_TYPE.CSS)||isFling!==otherPE.containsTypeNames([INPUT_TYPE.FLING_START])||isVideo&&otherPE.initiatorType!==INITIATOR_TYPE.VIDEO){continue;}
+if(isCSS){if(!pe.isNear(otherPE,ANIMATION_MERGE_THRESHOLD_MS)){continue;}}else if(!otherPE.intersects(pe)){continue;}
+pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function fixResponseAnimationStarts(protoExpectations){protoExpectations.forEach(function(ape){if(ape.type!==ProtoExpectation.ANIMATION_TYPE){return;}
+protoExpectations.forEach(function(rpe){if(rpe.type!==ProtoExpectation.RESPONSE_TYPE){return;}
+if(!ape.containsTimestampInclusive(rpe.end)){return;}
+if(ape.containsTimestampInclusive(rpe.start)){return;}
+ape.start=rpe.end;});});return protoExpectations;}
+function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.type===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
+function isTouchAnimation(pe){return(pe.type===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
+const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);const peIsTapResponse=isTapResponse(pe);const peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation){continue;}
+for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(!otherPE.intersects(pe))continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))continue;pe.type=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function findFrameEventsForAnimations(modelHelper,protoExpectations){const newPEs=[];const frameEventsByPid=getSortedFrameEventsByProcess(modelHelper);for(const pe of protoExpectations){if(pe.type!==ProtoExpectation.ANIMATION_TYPE){newPEs.push(pe);continue;}
+const frameEvents=[];for(const pid of Object.keys(modelHelper.rendererHelpers)){const range=tr.b.math.Range.fromExplicitRange(pe.start,pe.end);frameEvents.push.apply(frameEvents,range.filterArray(frameEventsByPid[pid],e=>e.start));}
+if(frameEvents.length===0&&!(pe.initiatorType===INITIATOR_TYPE.WEBGL)){pe.type=ProtoExpectation.IGNORED_TYPE;newPEs.push(pe);continue;}
+pe.associatedEvents.addEventSet(frameEvents);newPEs.push(pe);}
+return newPEs;}
+function checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations,warn){const handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0)){return;}
+if((handledEvents.indexOf(event)>=0)&&(event.title!==tr.model.helpers.IMPL_RENDERING_STATS)){warn({type:'UserModelBuilder',message:`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:false,});return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){warn({type:'UserModelBuilder',message:`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:false,});}});}
+function findInputExpectations(modelHelper){let warning;function warn(w){if(warning)return;warning=w;}
+const sortedInputEvents=getSortedInputEvents(modelHelper);let protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents,warn);protoExpectations=postProcessProtoExpectations(modelHelper,protoExpectations);checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations,warn);if(warning)modelHelper.model.importWarning(warning);const expectations=[];protoExpectations.forEach(function(protoExpectation){const ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir){expectations.push(ir);}});return expectations;}
+return{findInputExpectations,compareEvents,CSS_ANIMATION_TITLE,};});'use strict';tr.exportTo('tr.model.um',function(){const LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',};const DOES_LOAD_SUBTYPE_NAME_EXIST={};for(const key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;}
+function LoadExpectation(parentModel,initiatorTitle,start,duration){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle]){throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');}
+tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=undefined;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;}
+LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.subTypes.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES,LoadExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const NAVIGATION_START='NavigationTiming navigationStart';const FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function findLoadExpectations(modelHelper){const events=[];for(const event of modelHelper.model.getDescendantEvents()){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE)){events.push(event);}}
+events.sort(tr.importer.compareEvents);const loads=[];let startEvent=undefined;for(const event of events){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}}
+if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,modelHelper.model.bounds.max-startEvent.start));}
+return loads;}
+return{findLoadExpectations,};});'use strict';tr.exportTo('tr.model.um',function(){function StartupExpectation(parentModel,start,duration){tr.model.um.UserExpectation.call(this,parentModel,'',start,duration);}
+StartupExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:StartupExpectation};tr.model.um.UserExpectation.subTypes.register(StartupExpectation,{stageTitle:'Startup',colorId:tr.b.ColorScheme.getColorIdForReservedName('startup')});return{StartupExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function getAllFrameEvents(modelHelper){const frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));for(const renderer of Object.values(modelHelper.rendererHelpers)){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));}
+return frameEvents.sort(tr.importer.compareEvents);}
+function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
+const events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);const deduper=new tr.model.EventSet();events.forEach(function(event){const sliceGroup=event.parentContainer.sliceGroup;const slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice){deduper.push(slice);}});return deduper.toArray();}
+function findStartupExpectations(modelHelper){const openingEvents=getStartupEvents(modelHelper);const closingEvents=getAllFrameEvents(modelHelper);const startups=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)return;if(closingEvent.openingEvent)return;if(closingEvent.start<=openingEvent.start)return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid){return;}
+openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;const se=new tr.model.um.StartupExpectation(modelHelper.model,openingEvent.start,closingEvent.end-openingEvent.start);se.associatedEvents.push(openingEvent);se.associatedEvents.push(closingEvent);startups.push(se);});});return startups;}
+return{findStartupExpectations,};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){const allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
+function getUnassociatedEvents(model,associatedEvents){const unassociatedEvents=new tr.model.EventSet();for(const proc of model.getAllProcesses()){for(const thread of Object.values(proc.threads)){for(const event of thread.sliceGroup.getDescendantEvents()){if(!associatedEvents.contains(event)){unassociatedEvents.push(event);}}}}
+return unassociatedEvents;}
+function getTotalCpuDuration(events){let cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}
+function getIRCoverageFromModel(model){const associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)return undefined;const unassociatedEvents=getUnassociatedEvents(model,associatedEvents);const associatedCpuMs=getTotalCpuDuration(associatedEvents);const unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);const totalEventCount=associatedEvents.length+unassociatedEvents.length;const totalCpuMs=associatedCpuMs+unassociatedCpuMs;let coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0){coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;}
+return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio};}
+return{getIRCoverageFromModel,getAssociatedEvents,getUnassociatedEvents,};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){const initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
+IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.subTypes.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const INSIGNIFICANT_MS=1;class UserModelBuilder{constructor(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}
+static supportsModelHelper(modelHelper){return modelHelper.browserHelper!==undefined;}
+buildUserModel(){if(!this.modelHelper||!this.modelHelper.browserHelper)return;try{for(const ue of this.findUserExpectations()){this.model.userModel.expectations.push(ue);}
+this.model.userModel.segments.push(...this.findSegments());}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});}}
+findSegments(){let timestamps=new Set();for(const expectation of this.model.userModel.expectations){timestamps.add(expectation.start);timestamps.add(expectation.end);}
+timestamps=[...timestamps];timestamps.sort((x,y)=>x-y);const segments=[];for(let i=0;i<timestamps.length-1;++i){const segment=new tr.model.um.Segment(timestamps[i],timestamps[i+1]-timestamps[i]);segments.push(segment);const segmentRange=tr.b.math.Range.fromExplicitRange(segment.start,segment.end);for(const expectation of this.model.userModel.expectations){const expectationRange=tr.b.math.Range.fromExplicitRange(expectation.start,expectation.end);if(segmentRange.intersectsRangeExclusive(expectationRange)){segment.expectations.push(expectation);}}}
+return segments;}
+findUserExpectations(){const expectations=[];expectations.push.apply(expectations,tr.importer.findStartupExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;}
+collectUnassociatedEvents_(expectations){const vacuumUEs=[];for(const expectation of expectations){if(expectation instanceof tr.model.um.IdleExpectation||expectation instanceof tr.model.um.LoadExpectation||expectation instanceof tr.model.um.StartupExpectation){vacuumUEs.push(expectation);}}
+if(vacuumUEs.length===0)return;const allAssociatedEvents=tr.model.getAssociatedEvents(expectations);const unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);for(const event of unassociatedEvents){if(!(event instanceof tr.model.ThreadSlice))continue;if(!event.isTopLevel)continue;for(let index=0;index<vacuumUEs.length;++index){const expectation=vacuumUEs[index];if((event.start>=expectation.start)&&(event.start<expectation.end)){expectation.associatedEvents.addEventSet(event.entireHierarchy);break;}}}}
+findIdleExpectations(otherUEs){if(this.model.bounds.isEmpty)return;const emptyRanges=tr.b.math.findEmptyRangesBetweenRanges(tr.b.math.convertEventsToRanges(otherUEs),this.model.bounds);const expectations=[];const model=this.model;for(const range of emptyRanges){if(range.max<(range.min+INSIGNIFICANT_MS))continue;expectations.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));}
+return expectations;}}
+function createCustomizeModelLinesFromModel(model){const modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');const typeNames={};for(const typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+let modelEvents=new tr.model.EventSet();for(const ue of model.userModel.expectations){modelEvents.addEventSet(ue.sourceEvents);}
+modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);for(const event of modelEvents){const startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw new Error('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
+modelLines.push('          {'+startAndEnd);}
+modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
+function createExpectedUELinesFromModel(model){const expectedLines=[];const ueCount=model.userModel.expectations.length;for(let index=0;index<ueCount;++index){const expectation=model.userModel.expectations[index];let ueString='      {';ueString+='title: \''+expectation.title+'\', ';ueString+='start: '+parseInt(expectation.start)+', ';ueString+='end: '+parseInt(expectation.end)+', ';ueString+='eventCount: '+expectation.sourceEvents.length;ueString+='}';if(index<(ueCount-1))ueString+=',';expectedLines.push(ueString);}
+return expectedLines;}
+function createUEFinderTestCaseStringFromModel(model){const filename=window.location.hash.substr(1);let testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{const testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    const verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedUEs = [');testLines.push.apply(testLines,createExpectedUELinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{UserModelBuilder,createUEFinderTestCaseStringFromModel,};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){let elements;if(typeof source==='string'){elements=Polymer.dom(tr.doc).querySelectorAll(source);}else{elements=[source];}
+for(let i=0,el;el=elements[i];i++){if(!(el instanceof constr)){constr.decorate(el);}}}
+function define(className,opt_parentConstructor,opt_tagNS){if(typeof className==='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
+className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName){throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');}
+let tagName=className;let tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS){throw new Error('Must not specify tagNS if parentConstructor is given');}
+let parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
+function f(){if(opt_parentConstructor&&f.prototype.__proto__!==opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
+let el;if(tagNS===undefined){el=tr.doc.createElement(tagName);}else{el=tr.doc.createElementNS(tagNS,tagName);}
+f.decorate.call(this,el,arguments);return el;}
+f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor){return f.tagName;}
+return f.parentConstructor.toString()+'::'+f.className;};return f;}
+function elementIsChildOf(el,potentialParent){if(el===potentialParent)return false;let cur=el;while(Polymer.dom(cur).parentNode){if(cur===potentialParent)return true;cur=Polymer.dom(cur).parentNode;}
+return false;}
+return{decorate,define,elementIsChildOf,};});'use strict';tr.exportTo('tr.b.math',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;}
+Rect.fromXYWH=function(x,y,w,h){const rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;};Rect.fromArray=function(ary){if(ary.length!==4){throw new Error('ary.length must be 4');}
+const rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;};Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString(){return'Rect('+this.x+', '+this.y+', '+
+this.width+', '+this.height+')';},toArray(){return[this.x,this.y,this.width,this.height];},clone(){const rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge(pad){const rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size(){return{width:this.width,height:this.height};},scale(s){const rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate(v){const rect=new Rect();this.translateFast(rect,v);return rect;},translateFast(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside(containingRect){const rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects(that){let ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect,};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;const el=Polymer.dom(doc).querySelector(selector);if(!el){throw new Error('Element not found');}
+return doc.importNode(el.content,true);}
+function windowRectForElement(element){const position=[element.offsetLeft,element.offsetTop];const size=[element.offsetWidth,element.offsetHeight];let node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
+return tr.b.math.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
+function scrollIntoViewIfNeeded(el){const pr=el.parentElement.getBoundingClientRect();const cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
+function extractUrlString(url){let extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
+function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
+function isUnknownElementName(name){return document.createElement(name)instanceof HTMLUnknownElement;}
+return{isUnknownElementName,toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};const THIS_DOC=document.currentScript.ownerDocument;const Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);const createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;const e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_(){this.visible_?this.show_():this.hide_();},show_(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
+this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;const elList=Polymer.dom(this).querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)return elList[1].focus();}else{return elList[0].focus();}}
+this.focus();},hide_(){Polymer.dom(this.parentEl_).removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_){this.closeBtn_.removeEventListener('click',this.onClose_);}
+document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_(e){this.visible=false;if((e.type!=='keydown')||(e.type==='keydown'&&e.keyCode===27)){e.stopPropagation();}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_(e){let node=e.target;while(node){if(node===this){return;}
+node=node.parentNode;}
+tr.b.timeout(0).then(()=>this.focus());e.preventDefault();e.stopPropagation();},didButtonBarMutate_(e){const hasButtons=this.buttons.children.length>0;if(hasButtons){Polymer.dom(this.shadow_).querySelector('button-bar').style.display=undefined;}else{Polymer.dom(this.shadow_).querySelector('button-bar').style.display='none';}},onKeyDown_(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
+if(e.keyCode!==27)return;this.onClose_(e);},onClick_(e){e.stopPropagation();},onDocumentClick_(e){if(!this.userCanClose_)return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){const o=new Overlay();o.title='Error';Polymer.dom(o).textContent=msg;if(opt_err){const e=tr.b.normalizeException(opt_err);const stackDiv=document.createElement('pre');Polymer.dom(stackDiv).textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;Polymer.dom(o).appendChild(stackDiv);}
+const b=document.createElement('button');Polymer.dom(b).textContent='OK';b.addEventListener('click',function(){o.visible=false;});Polymer.dom(o.buttons).appendChild(b);o.visible=true;return o;};return{Overlay,};});'use strict';tr.exportTo('tr.importer',function(){const Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;const auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+function Import(model,opt_options){if(model===undefined){throw new Error('Must provide model to import into.');}
+this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
+Import.prototype={__proto__:Object.prototype,importTraces(traces){const progressMeter={update(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog(traces){if(tr.isHeadless){throw new Error('Cannot use this method in headless mode.');}
+const overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');Polymer.dom(overlay).appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){Polymer.dom(this.msgEl).textContent=msg;};overlay.visible=true;const promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask(progressMeter,traces){const importStartTimeMs=performance.now();if(this.importing_){throw new Error('Already importing.');}
+this.importing_=true;const importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);let lastTask=importTask;const importers=[];function addImportStage(title,callback){lastTask=lastTask.after(()=>progressMeter.update(title));lastTask.updatesUi=true;lastTask=lastTask.after(callback);}
+function addStageForEachImporter(title,callback){lastTask=lastTask.after((task)=>{importers.forEach((importer,index)=>{const uiSubTask=task.subTask(()=>{progressMeter.update(`${title} ${index + 1} of ${importers.length}`);});uiSubTask.updatesUi=true;task.subTask(()=>callback(importer));});});}
+addImportStage('Creating importers...',()=>{traces=traces.slice(0);progressMeter.update('Creating importers...');for(let i=0;i<traces.length;++i){importers.push(this.createImporter_(traces[i]));}
+for(let i=0;i<importers.length;i++){const subtraces=importers[i].extractSubtraces();for(let j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){this.model_.importWarning({type:error.name,message:error.message,showToUser:true,});continue;}}}
+if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
+importers.sort(function(x,y){return x.importPriority-y.importPriority;});});addStageForEachImporter('Importing clock sync markers',importer=>importer.importClockSyncMarkers());addStageForEachImporter('Importing',importer=>importer.importEvents());if(this.importOptions_.customizeModelCallback){addImportStage('Customizing',()=>{this.importOptions_.customizeModelCallback(this.model_);});}
+addStageForEachImporter('Importing sample data',importer=>importer.importSampleData());addImportStage('Autoclosing open slices...',()=>{this.model_.autoCloseOpenSlices();this.model_.createSubSlices();});addStageForEachImporter('Finalizing import',importer=>importer.finalizeImport());addImportStage('Initializing objects (step 1/2)...',()=>this.model_.preInitializeObjects());if(this.importOptions_.pruneEmptyContainers){addImportStage('Pruning empty containers...',()=>this.model_.pruneEmptyContainers());}
+addImportStage('Merging kernel with userland...',()=>this.model_.mergeKernelWithUserland());let auditors=[];addImportStage('Adding arbitrary data to model...',()=>{auditors=this.importOptions_.auditorConstructors.map(auditorConstructor=>new auditorConstructor(this.model_));auditors.forEach((auditor)=>{auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});});addImportStage('Computing final world bounds...',()=>{this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);});addImportStage('Building flow event map...',()=>this.model_.buildFlowEventIntervalTree());addImportStage('Joining object refs...',()=>this.model_.joinRefs());addImportStage('Cleaning up undeleted objects...',()=>this.model_.cleanupUndeletedObjects());addImportStage('Sorting memory dumps...',()=>this.model_.sortMemoryDumps());addImportStage('Finalizing memory dump graphs...',()=>this.model_.finalizeMemoryGraphs());addImportStage('Initializing objects (step 2/2)...',()=>this.model_.initializeObjects());addImportStage('Building event indices...',()=>this.model_.buildEventIndices());addImportStage('Building UserModel...',()=>{const userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();});addImportStage('Sorting user expectations...',()=>this.model_.userModel.sortExpectations());addImportStage('Running auditors...',()=>{auditors.forEach(auditor=>auditor.runAudit());});addImportStage('Updating alerts...',()=>this.model_.sortAlerts());addImportStage('Update bounds...',()=>this.model_.updateBounds());addImportStage('Looking for warnings...',()=>{if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}});lastTask.after(()=>{this.importing_=false;this.model_.stats.traceImportDurationMs=performance.now()-importStartTimeMs;});return importTask;},createImporter_(eventData){const importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_(importers){for(let i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())return true;}
+return false;}};return{ImportOptions,Import,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8GCStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.liveObjects_=JSON.parse(this.args.live);delete this.args.live;this.deadObjects_=JSON.parse(this.args.dead);delete this.args.dead;}
+V8GCStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get liveObjects(){return this.liveObjects_;},get deadObjects(){return this.deadObjects_;}};ThreadSlice.subTypes.register(V8GCStatsThreadSlice,{categoryParts:['disabled-by-default-v8.gc_stats'],name:'v8 gc stats slice',pluralName:'v8 gc stats slices'});return{V8GCStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ICStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.icStats_=undefined;if(this.args['ic-stats']){this.icStats_=this.args['ic-stats'].data;delete this.args['ic-stats'];}}
+V8ICStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get icStats(){return this.icStats_;}};ThreadSlice.subTypes.register(V8ICStatsThreadSlice,{categoryParts:['disabled-by-default-v8.ic_stats'],name:'v8 ic stats slice',pluralName:'v8 ic stats slices'});return{V8ICStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ThreadSlice(){ThreadSlice.apply(this,arguments);this.runtimeCallStats_=undefined;}
+V8ThreadSlice.prototype={__proto__:ThreadSlice.prototype,get runtimeCallStats(){if('runtime-call-stats'in this.args){this.runtimeCallStats_=this.args['runtime-call-stats'];delete this.args['runtime-call-stats'];}
+return this.runtimeCallStats_;}};ThreadSlice.subTypes.register(V8ThreadSlice,{categoryParts:['v8','disabled-by-default-v8.runtime_stats'],name:'v8 slice',pluralName:'v8 slices'});return{V8ThreadSlice,};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}}
+PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas(){if(!this.imageData_)return;const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData,};});'use strict';tr.exportTo('tr.e.cc',function(){const convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache){return convertedNameCache[name];}
+if(name[0]==='_'||name[name.length-1]==='_'){convertedNameCache[name]=name;return name;}
+const words=name.split('_');if(words.length===1){convertedNameCache[name]=words[0];return words[0];}
+for(let i=1;i<words.length;i++){words[i]=words[i][0].toUpperCase()+words[i].substring(1);}
+convertedNameCache[name]=words.join('');return convertedNameCache[name];}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined){throw Error('Expected field '+key+' not found in args');}
+if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
+object[key]=object.args[key];delete object.args[key];}}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined)continue;if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
+object[key]=object.args[key];delete object.args[key];}}
+function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){preInitializeObjectInner(object[i],true);}
+return;}
+if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance)){return;}
+for(let key in object){const newKey=convertNameToJSConvention(key);if(newKey!==key){const value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.math.Quad)){let q;try{q=tr.b.math.Quad.from8Array(object[key]);}catch(e){}
+object[key]=q;continue;}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.math.Rect)){let r;try{r=tr.b.math.Rect.fromArray(object[key]);}catch(e){}
+object[key]=r;}
+preInitializeObjectInner(object[key],true);}}
+return{preInitializeObject,convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const PictureCount=0;const OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocateSimple();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){return this.skp64_;},getOps(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops){console.error('Failed to get picture ops.');}
+return ops;},getOpTimings(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings){console.error('Failed to get picture op timings.');}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}
+if(opTimings[iteration].cmd_times.length!==ops.length){return ops;}}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+ops[opIndex].cmd_time=min;}
+return ops;},rasterize(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+const raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;const imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{const error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocateSimple();this.pictures_=pictures;this.layerRect_=undefined;}
+LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined){return this.layerRect_;}
+this.layerRect_={x:0,y:0,width:0,height:0};for(let i=0;i<this.pictures_.length;++i){const rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){throw new Error('Not available with a LayeredPicture.');},getOps(){let ops=[];for(let i=0;i<this.pictures_.length;++i){ops=ops.concat(this.pictures_[i].getOps());}
+return ops;},getOpTimings(){const opTimings=this.pictures_[0].getOpTimings();for(let i=1;i<this.pictures_.length;++i){const timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+ops[opIndex].cmd_time=min;}
+return ops;},rasterize(params,rasterCompleteCallback){this.picturesAsImageData_=[];const rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length){return;}
+const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(let i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(let i=0;i<this.pictures_.length;++i){this.pictures_[i].rasterize(params,rasterCallback);}}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');};PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.rasterize){return false;}
+return true;};PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getOps){return false;}
+return true;};PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getOpTimings){return false;}
+return true;};PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getInfo){return false;}
+return true;};PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless){return'Pictures only work in chrome';}
+const usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking')){return usualReason;}
+if(!global.chrome.skiaBenchmarking.rasterize){return'Your chrome is old';}
+if(!global.chrome.skiaBenchmarking.getOps){return'Your chrome is old: skiaBenchmarking.getOps not found';}
+if(!global.chrome.skiaBenchmarking.getOpTimings){return'Your chrome is old: skiaBenchmarking.getOpTimings not found';}
+if(!global.chrome.skiaBenchmarking.getInfo){return'Your chrome is old: skiaBenchmarking.getInfo not found';}
+return'Rasterizing is on';};PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize(){if(this.args.alias){this.args=this.args.alias.args;}
+if(!this.args.params.layerRect){throw new Error('Missing layer rect');}
+this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData(){return this.picture_.getBase64SkpData();},getOps(){return this.picture_.getOps();},getOpTimings(){return this.picture_.getOpTimings();},tagOpsWithTimings(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.subTypes.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot,Picture,LayeredPicture,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.subTypes.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot,DisplayItemList,};});'use strict';tr.exportTo('tr.b.math',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
+BBox2.prototype={__proto__:Object.prototype,reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2(bbox2){if(bbox2.isEmpty)return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone(){const bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+const size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
+return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
+return this.max_[1]-this.min_[1];},toString(){if(this.isEmpty_)return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect(){return tr.b.math.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+Region.fromArray=function(array){if(array.length%4!==0){throw new Error('Array must consist be a multiple of 4 in length');}
+const r=new Region();for(let i=0;i<array.length;i+=4){r.rects.push(tr.b.math.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;};Region.fromArrayOrUndefined=function(array){if(array===undefined)return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects(r){for(let i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))return true;}
+return false;},addRect(r){this.rects.push(r);}};return{Region,};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['children','maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.math.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.math.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+if(this.children){for(let i=0;i<this.children.length;i++){this.children[i].parentLayer=this;}}
+if(this.maskLayer){this.maskLayer.parentLayer=this;}
+if(this.replicaLayer){this.replicaLayer.parentLayer=this;}
+if(!this.geometryContentsScale){this.geometryContentsScale=1.0;}
+if(!this.idealContentsScale){this.idealContentsScale=1.0;}
+this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_){return this.layerTreeImpl_;}
+if(this.parentLayer){return this.parentLayer.layerTreeImpl;}
+return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree===constants.ACTIVE_TREE){return this;}
+const activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree===constants.PENDING_TREE){return this;}
+const pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
+if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(let i=0;i<this.args.annotatedInvalidationRects.length;++i){const annotatedRect=this.args.annotatedInvalidationRects[i];const rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
+delete this.args.annotatedInvalidationRects;}
+if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
+if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(let i=0;i<this.args.coverageTiles.length;++i){const rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);const tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.subTypes.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.subTypes.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SolidColorScrollbarLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot,PictureLayerImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['renderSurfaceLayerList']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['rootLayer','layers']);if(this.args.sourceFrameNumber){this.sourceFrameNumber=this.args.sourceFrameNumber;}
+if(this.rootLayer){this.rootLayer.layerTreeImpl=this;}else{for(let i=0;i<this.layers.length;i++){this.layers[i].layerTreeImpl=this;}}
+if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];const ownProcess=this.objectInstance.parent;const modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper){this._initializeTracedInputLatencies(modelHelper);}}},_initializeTracedInputLatencies(modelHelper){const latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(let i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id){continue;}
+if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i]){this.tracedInputLatencies.push(event);}}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree===tr.e.cc.constants.PENDING_TREE){return false;}
+if(this.sourceFrameNumber===undefined)return;const thisLTHI=this.layerTreeHostImpl;const thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);const prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length){return false;}
+const prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)return;return prevLTHI.activeTree.sourceFrameNumber===this.sourceFrameNumber;},get otherTree(){const other=this.whichTree===constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){let totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined){totalBytes+=layer.gpuMemoryUsageInBytes;}});return totalBytes;},iterLayers(func,thisArg){const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(let i=0;i<layer.children.length;i++){visitLayer(layer.children[i],depth+1);}}
+if(layer.maskLayer){visitLayer(layer.maskLayer,depth+1,true,false);}
+if(layer.replicaLayer){visitLayer(layer.replicaLayer,depth+1,false,true);}}
+if(this.rootLayer){visitLayer(this.rootLayer,0,false,false);}else{for(let i=0;i<this.layers.length;i++){visitLayer(this.layers[i],0,false,false);}}},findLayerWithId(id){let foundLayer=undefined;function visitLayer(layer){if(layer.layerId===id){foundLayer=layer;}}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.subTypes.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(!this.activeTiles){this.activeTiles=[];}
+this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames(){const scales={};for(let i=0;i<this.activeTiles.length;++i){const tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree(whichTree){if(whichTree===constants.ACTIVE_TREE){return this.activeTree;}
+if(whichTree===constants.PENDING_TREE){return this.pendingTree;}
+throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined){return this.tilesHaveGpuMemoryUsageInfo_;}
+for(let i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined){continue;}
+this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)return;let usage=0;for(let i=0;i<this.activeTiles.length;i++){const u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)usage+=u;}
+return usage;},get userFriendlyName(){let frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{frameNumber=this.activeTree.sourceFrameNumber;}}
+return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.subTypes.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
+LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_){return this.allContentsScales_;}
+const scales={};for(const tileID in this.allTileHistories_){const tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+this.allContentsScales_=Object.keys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_){return this.allLayersBBox_;}
+const bbox=new tr.b.math.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree){handleTree(lthi.pendingTree);}});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.subTypes.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot,LayerTreeHostImplInstance,};});'use strict';tr.exportTo('tr.e.cc',function(){const tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};const tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes,tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+if(this.contentRect){this.layerRect=this.contentRect.scale(1.0/this.contentsScale);}
+if(this.isSolidColor){this.type_=tr.e.cc.tileTypes.solidColor;}else if(!this.hasResource){this.type_=tr.e.cc.tileTypes.missing;}else if(this.resolution==='HIGH_RESOLUTION'){this.type_=tr.e.cc.tileTypes.highRes;}else if(this.resolution==='LOW_RESOLUTION'){this.type_=tr.e.cc.tileTypes.lowRes;}else{this.type_=tr.e.cc.tileTypes.unknown;}},getTypeForLayer(layer){let type=this.type_;if(type===tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale){type=tr.e.cc.tileTypes.extraLowRes;}else if(this.contentsScale>layer.idealContentsScale){type=tr.e.cc.tileTypes.extraHighRes;}}
+return type;}};ObjectSnapshot.subTypes.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;}
+UIState.fromUserFriendlyString=function(model,viewport,stateString){const navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;const match=navByFinderPattern.exec(stateString);if(!match)return;const timestamp=parseFloat(match[1]);const stableId=match[3];const scaleX=parseFloat(match[4]);if(scaleX<=0){throw new Error('Invalid ScaleX value in UI State string.');}
+if(!viewport.containerToTrackMap.getTrackByStableId(stableId)){throw new Error('Invalid StableID given in UI State String.');}
+const loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);};UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString(viewport){const timestamp=this.location_.xWorld;const stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;const scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState,};});'use strict';tr.exportTo('tr.ui.b',function(){const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocateSimple();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+BrushingState.prototype={get guid(){return this.guid_;},clone(){const that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals(that){if(!this.selection_.equals(that.selection_)){return false;}
+if(!this.findMatches_.equals(that.findMatches_)){return false;}
+if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
+if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
+return true;},get selectionOfInterest(){if(this.selection_.length){return this.selection_;}
+if(this.highlight_.length){return this.highlight_;}
+if(this.analysisViewRelatedEvents_.length){return this.analysisViewRelatedEvents_;}
+if(this.analysisLinkHoveredEvents_.length){return this.analysisLinkHoveredEvents_;}
+return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(selection===undefined){selection=new EventSet();}
+this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(findMatches===undefined){findMatches=new EventSet();}
+this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(analysisViewRelatedEvents===undefined){analysisViewRelatedEvents=new EventSet();}
+this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(analysisLinkHoveredEvents===undefined){analysisLinkHoveredEvents=new EventSet();}
+this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get dimmedEvents_(){const dimmedEvents=new EventSet();dimmedEvents.addEventSet(this.findMatches);dimmedEvents.addEventSet(this.analysisViewRelatedEvents_);return dimmedEvents;},get brightenedEvents_(){const brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToEventSelectionStates(model){this.appliedToModel_=model;const dimmedEvents=this.dimmedEvents_;if(model){const newDefaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);const currentDefaultState=tr.b.getFirstElement(model.getDescendantEvents()).selectionState;if(currentDefaultState!==newDefaultState){for(const e of model.getDescendantEvents()){e.selectionState=newDefaultState;}}}
+let score;for(const e of dimmedEvents){score=0;if(this.findMatches_.contains(e)){score++;}
+if(this.analysisViewRelatedEvents_.contains(e)){score++;}
+e.selectionState=SelectionState.getFromDimmingLevel(score);}
+for(const e of this.brightenedEvents_){score=0;if(this.selection_.contains(e)){score++;}
+if(this.analysisLinkHoveredEvents_.contains(e)){score++;}
+e.selectionState=SelectionState.getFromBrighteningLevel(score);}},transferModelOwnershipToClone(that){if(!this.appliedToModel_){throw new Error('Not applied');}
+that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromEventSelectionStates(){if(!this.appliedToModel_){throw new Error('Not applied');}
+const model=this.appliedToModel_;this.appliedToModel_=undefined;const dimmedEvents=this.dimmedEvents_;const defaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);for(const e of this.brightenedEvents_){e.selectionState=defaultState;}
+for(const e of dimmedEvents){e.selectionState=defaultState;}
+return defaultState;}};return{BrushingState,};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
+Animation.prototype={canTakeOverFor(existingAnimation){throw new Error('Not implemented');},takeOverFor(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start(timestamp,target){throw new Error('Not implemented');},didStopEarly(timestamp,target,willBeTakenOverByAnotherAnimation){},tick(timestamp,target){throw new Error('Not implemented');}};return{Animation,};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
+AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_){throw new Error('Cannot change target while animation is running.');}
+if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function'){throw new Error('target must have a cloneAnimationState function');}
+this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation(animation,opt_now){if(this.target_===undefined){throw new Error('Cannot queue animations without a target');}
+let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+if(this.activeAnimation_){const done=this.activeAnimation_.tick(now,this.target_);if(done){this.activeAnimation_=undefined;}}
+if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
+this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation(opt_now){if(!this.activeAnimation_)return;let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
+const oldTargetState=this.target_.cloneAnimationState();const done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done){this.activeAnimation_=undefined;}
+if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
+if(oldTargetState){const e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController,};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;}
+if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless){Settings.setAlternativeStorageInstance(new HeadlessStorage());}else{Settings.setAlternativeStorageInstance(global.sessionStorage);global.sessionStorage.clear();}});}
+function SessionSettings(){return SessionSettings;}
+function AddStaticStorageFunctionsToClass_(inputClass,storage){inputClass.storage_=storage;inputClass.get=function(key,opt_default,opt_namespace){key=inputClass.namespace_(key,opt_namespace);const rawVal=inputClass.storage_.getItem(key);if(rawVal===null||rawVal===undefined){return opt_default;}
+try{return JSON.parse(rawVal).value;}catch(e){inputClass.storage_.removeItem(key);return opt_default;}};inputClass.set=function(key,value,opt_namespace){if(value===undefined){throw new Error('Settings.set: value must not be undefined');}
+const v=JSON.stringify({value});inputClass.storage_.setItem(inputClass.namespace_(key,opt_namespace),v);};inputClass.keys=function(opt_namespace){const result=[];opt_namespace=opt_namespace||'';for(let i=0;i<inputClass.storage_.length;i++){const key=inputClass.storage_.key(i);if(inputClass.isnamespaced_(key,opt_namespace)){result.push(inputClass.unnamespace_(key,opt_namespace));}}
+return result;};inputClass.isnamespaced_=function(key,opt_namespace){return key.indexOf(inputClass.normalize_(opt_namespace))===0;};inputClass.namespace_=function(key,opt_namespace){return inputClass.normalize_(opt_namespace)+key;};inputClass.unnamespace_=function(key,opt_namespace){return key.replace(inputClass.normalize_(opt_namespace),'');};inputClass.normalize_=function(opt_namespace){return inputClass.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};inputClass.setAlternativeStorageInstance=function(instance){inputClass.storage_=instance;};inputClass.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&inputClass.storage_===localStorage){return undefined;}
+return inputClass.storage_;};inputClass.NAMESPACE='trace-viewer';}
+function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
+HeadlessStorage.prototype={key(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined){return this.itemsAsArray_;}
+const itemsAsArray=[];for(const k in this.items_){itemsAsArray.push(k);}
+this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem(key){if(!this.hasItem_[key]){return null;}
+return this.items_[key];},removeItem(key){if(!this.hasItem_[key]){return;}
+const value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
+return{Settings,SessionSettings,};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){let ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument){ownerDocument=opt_dictionary.ownerDocument;}
+const spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className){spanEl.className=opt_dictionary.className;}
+if(opt_dictionary.textContent){Polymer.dom(spanEl).textContent=opt_dictionary.textContent;}
+if(opt_dictionary.tooltip){spanEl.title=opt_dictionary.tooltip;}
+if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(spanEl);}
+if(opt_dictionary.bold){spanEl.style.fontWeight='bold';}
+if(opt_dictionary.italic){spanEl.style.fontStyle='italic';}
+if(opt_dictionary.marginLeft){spanEl.style.marginLeft=opt_dictionary.marginLeft;}
+if(opt_dictionary.marginRight){spanEl.style.marginRight=opt_dictionary.marginRight;}
+if(opt_dictionary.backgroundColor){spanEl.style.backgroundColor=opt_dictionary.backgroundColor;}
+if(opt_dictionary.color){spanEl.style.color=opt_dictionary.color;}}
+return spanEl;}
+function createLink(opt_args){let ownerDocument=document;if(opt_args&&opt_args.ownerDocument){ownerDocument=opt_args.ownerDocument;}
+const linkEl=ownerDocument.createElement('a');if(opt_args){if(opt_args.href)linkEl.href=opt_args.href;if(opt_args.tooltip)linkEl.title=opt_args.tooltip;if(opt_args.color)linkEl.style.color=opt_args.color;if(opt_args.bold)linkEl.style.fontWeight='bold';if(opt_args.italic)linkEl.style.fontStyle='italic';if(opt_args.className)linkEl.className=opt_args.className;if(opt_args.parent)Polymer.dom(opt_args.parent).appendChild(linkEl);if(opt_args.marginLeft)linkEl.style.marginLeft=opt_args.marginLeft;if(opt_args.marginRight)linkEl.style.marginRight=opt_args.marginRight;if(opt_args.backgroundColor){linkEl.style.backgroundColor=opt_args.backgroundColor;}
+if(opt_args.textContent){Polymer.dom(linkEl).textContent=opt_args.textContent;}}
+return linkEl;}
+function createDiv(opt_dictionary){const divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className){divEl.className=opt_dictionary.className;}
+if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(divEl);}
+if(opt_dictionary.textContent){Polymer.dom(divEl).textContent=opt_dictionary.textContent;}
+if(opt_dictionary.maxWidth){divEl.style.maxWidth=opt_dictionary.maxWidth;}}
+return divEl;}
+function createScopedStyle(styleContent){const styleEl=document.createElement('style');styleEl.scoped=true;Polymer.dom(styleEl).innerHTML=styleContent;return styleEl;}
+function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array){return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);}
+return a===b;}
+function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){let defaultValueIndex;for(let i=0;i<items.length;i++){const item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
+if(defaultValueIndex===undefined){throw new Error('defaultValue must be in the items list');}
+const selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+function onChange(e){const value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
+const oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;onChange();}
+return;}}
+throw new Error('Not a valid value');});const initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);let didSet=false;for(let i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
+if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
+return selectorEl;}
+function createEditCategorySpan(optionGroupEl,targetEl){const spanEl=createSpan({className:'edit-categories'});Polymer.dom(spanEl).textContent='Edit categories';Polymer.dom(spanEl).classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
+function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){let value=[];if(this.value.length){value=this.value.split(',');}
+tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
+const optionGroupEl=createSpan({className:'labeled-option-group'});const initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(let i=0;i<items.length;++i){const item=items[i];const id='category-preset-'+item.label.replace(/ /g,'-');const radioEl=document.createElement('input');radioEl.type='radio';Polymer.dom(radioEl).setAttribute('id',id);Polymer.dom(radioEl).setAttribute('name','category-presets-group');Polymer.dom(radioEl).setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value)){radioEl.checked=true;}
+const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=item.label;Polymer.dom(labelEl).setAttribute('for',id);const spanEl=createSpan({className:'labeled-option'});Polymer.dom(spanEl).appendChild(radioEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=radioEl.checked!==(!!opt_bool);if(!changed)return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});Polymer.dom(optionGroupEl).appendChild(spanEl);}
+Polymer.dom(optionGroupEl).appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length){Polymer.dom(optionGroupEl).classList.add('categories-expanded');}
+targetEl[targetElProperty]=initialValue;return optionGroupEl;}
+let nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){const buttonEl=document.createElement('input');buttonEl.type='checkbox';let initialValue=defaultValue;if(settingsKey!==undefined){initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;}
+if(targetEl){targetEl[targetElProperty]=initialValue;}
+function onChange(){if(settingsKey!==undefined){tr.b.Settings.set(settingsKey,buttonEl.checked);}
+if(targetEl){targetEl[targetElProperty]=buttonEl.checked;}
+if(opt_changeCb){opt_changeCb.call();}}
+buttonEl.addEventListener('change',onChange);const id='#checkbox-'+nextCheckboxId++;const spanEl=createSpan({className:'labeled-checkbox'});Polymer.dom(buttonEl).setAttribute('id',id);const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=label;Polymer.dom(labelEl).setAttribute('for',id);Polymer.dom(spanEl).appendChild(buttonEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=buttonEl.checked!==(!!opt_bool);if(!changed)return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function createButton(label,opt_callback,opt_this){const buttonEl=document.createElement('input');buttonEl.type='button';buttonEl.value=label;function onClick(){opt_callback.call(opt_this||buttonEl);}
+if(opt_callback){buttonEl.addEventListener('click',onClick);}
+return buttonEl;}
+function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){const initialValue=tr.b.Settings.get(settingsKey,defaultValue);const el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
+el.addEventListener('input',onChange);el.value=initialValue;targetEl[targetElProperty]=initialValue;return el;}
+function isElementAttachedToDocument(el){let cur=el;while(Polymer.dom(cur).parentNode){cur=Polymer.dom(cur).parentNode;}
+return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
+function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node){return value;}
+const ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
+return{createSpan,createLink,createDiv,createScopedStyle,createSelector,createOptionGroup,createCheckBox,createButton,createTextInput,isElementAttachedToDocument,asHTMLOrTextNode,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCacheDict=new Map();const elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap=new Map();}
+ElidedTitleCache.prototype={get(ctx,pixWidth,title,width,sliceDuration){let elidedDict=elidedTitleCacheDict.get(title);if(!elidedDict){elidedDict=new Map();elidedTitleCacheDict.set(title,elidedDict);}
+let elidedDictForPixWidth=elidedDict.get(pixWidth);if(!elidedDictForPixWidth){elidedDict.set(pixWidth,new Map());elidedDictForPixWidth=elidedDict.get(pixWidth);}
+let stringWidthPair=elidedDictForPixWidth.get(sliceDuration);if(stringWidthPair===undefined){let newtitle=title;let elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
+if(elided&&newtitle.length>3){newtitle=newtitle.substring(0,newtitle.length-3)+'...';}
+stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth.set(sliceDuration,stringWidthPair);}
+return stringWidthPair;},quickMeasureText_(ctx,text){let w=this.textWidthMap.get(text);if(!w){w=ctx.measureText(text).width;this.textWidthMap.set(text,w);}
+return w;},labelWidth(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
+return{ElidedTitleCache,};});'use strict';tr.exportTo('tr.ui.b',function(){const ColorScheme=tr.b.ColorScheme;const colors=ColorScheme.colors;const colorsAsStrings=ColorScheme.colorsAsStrings;const SelectionState=tr.model.SelectionState;const EventPresenter={getSelectableItemColorAsString(item){const offset=this.getColorIdOffset_(item);const colorId=ColorScheme.getVariantColorId(item.colorId,offset);return colorsAsStrings[colorId];},getColorIdOffset_(event){return event.selectionState;},getTextColor(event){if(event.selectionState===SelectionState.DIMMED){return'rgb(60,60,60)';}
+return'rgb(0,0,0)';},getSliceColorId(slice){const offset=this.getColorIdOffset_(slice);return ColorScheme.getVariantColorId(slice.colorId,offset);},getSliceAlpha(slice,async){let alpha=1;if(async){alpha*=0.3;}
+return alpha;},getInstantSliceColor(instant){const offset=this.getColorIdOffset_(instant);const colorId=ColorScheme.getVariantColorId(instant.colorId,offset);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor(instance){const offset=this.getColorIdOffset_(instance);const colorId=ColorScheme.getVariantColorId(instance.colorId,offset);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor(snapshot){const offset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getVariantColorId(colorId,offset);return colors[colorId];},getCounterSeriesColor(colorId,selectionState,opt_alphaMultiplier){const event={selectionState};const offset=this.getColorIdOffset_(event);const c=colors[ColorScheme.getVariantColorId(colorId,offset)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor(snapshot,offset){const snapshotOffset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getAnotherColorId(colorId,offset);colorId=ColorScheme.getVariantColorId(colorId,snapshotOffset);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCache=new tr.ui.b.ElidedTitleCache();const ColorScheme=tr.b.ColorScheme;const colorsAsStrings=ColorScheme.colorsAsStrings;const EventPresenter=tr.ui.b.EventPresenter;const blackColorId=ColorScheme.getColorIdForReservedName('black');const THIN_SLICE_HEIGHT=4;const SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;const SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;const SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
+function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
+function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){const dx=x2-x1;const dy=y2-y1;const len=Math.sqrt(dx*dx+dy*dy);const perc=(len-arrowLength)/len;const bx=x1+perc*dx;const by=y1+perc*dy;const ux=dx/len;const uy=dy/len;const ax=uy*arrowWidth;const ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
+function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;const viewL=dt.xWorldToView(viewLWorld);const viewR=dt.xWorldToView(viewRWorld);let darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight){darkRectHeight=0;}
+const lightRectHeight=height-darkRectHeight;ctx.save();const rect=new tr.ui.b.FastRectRenderer(ctx,viewL,viewR,2,2,colorsAsStrings);rect.setYandH(0,height);const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);let hadTopLevel=false;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;const xView=dt.xWorldToView(x);let wView=1;if(slice.duration>0){const w=Math.max(slice.duration,0.000001);wView=Math.max(dt.xWorldVectorToView(w),1);}
+const colorId=EventPresenter.getSliceColorId(slice);const alpha=EventPresenter.getSliceAlpha(slice,async);const lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
+if(!slice.cpuDuration){rect.fillRect(xView,wView,colorId,alpha);continue;}
+let activeWidth=wView*(slice.cpuDuration/slice.duration);let waitingWidth=wView-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD){activeWidth=0;waitingWidth=wView;}
+if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD){activeWidth=wView;waitingWidth=0;}
+if(activeWidth>0){rect.fillRect(xView,activeWidth,colorId,alpha);}
+if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(xView+activeWidth-1,waitingWidth+1,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(xView+activeWidth-1,waitingWidth+1,colorId,alpha);rect.setYandH(0,height);}}
+rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;if(!slice.isTopLevel)continue;const xView=dt.xWorldToView(x);let wView=1;if(slice.duration>0){const w=Math.max(slice.duration,0.000001);wView=Math.max(dt.xWorldVectorToView(w),1);}
+rect.fillRect(xView,wView,blackColorId,0.7);}
+rect.flush();}
+ctx.restore();}
+function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;ctx.save();ctx.lineWidth=lineWidthInPixels*pixelRatio;const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);const xView=dt.xWorldToView(x);ctx.beginPath();ctx.moveTo(xView,0);ctx.lineTo(xView,height);ctx.stroke();}
+ctx.restore();}
+function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){const pixelRatio=window.devicePixelRatio||1;const pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async){ctx.font='italic '+ctx.font;}
+const cY=yOffset*pixelRatio;const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);const quickDiscardThreshold=pixWidth*20;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];if(slice.start>viewRWorld)break;if(slice.duration<=quickDiscardThreshold)continue;const xLeftClipped=Math.max(slice.start,viewLWorld);const xRightClipped=Math.min(slice.start+slice.duration,viewRWorld);const visibleWidth=xRightClipped-xLeftClipped;const title=slice.title+
+(slice.didNotFinish?' (Did Not Finish)':'');let drawnTitle=title;let drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);const fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>visibleWidth){const elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,visibleWidth);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
+if(drawnWidth*pixWidth<visibleWidth){ctx.fillStyle=EventPresenter.getTextColor(slice);const cX=dt.xWorldToView((xLeftClipped+xRightClipped)/2);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
+ctx.restore();}
+return{drawSlices,drawInstantSlicesAsLines,drawLabels,drawLine,drawTriangle,drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT,};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
+this.scaleX=1;this.panX=0;this.panY=0;}
+TimelineDisplayTransform.prototype={set(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone(){return new TimelineDisplayTransform(this);},equals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos(worldX,viewX,viewWidth){if(typeof viewX==='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
+this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0){this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);}else if(this.xWorldToView(worldMax)>viewWidth){this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);}},xSetWorldBounds(worldMin,worldMax,viewWidth){const worldWidth=worldMax-worldMin;const scaleX=viewWidth/worldWidth;const panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale(p,s){this.scaleX=s;this.panX=p;},xWorldToView(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView(x){return x*this.scaleX;},xViewToWorld(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld(x){return x/this.scaleX;}};return{TimelineDisplayTransform,};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
+function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.math.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
+TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject(){const range=new tr.b.math.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_===leftSelected)return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_===rightSelected)return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)return;const dt=this.viewport_.currentDisplayTransform;const markerLWorld=this.min;const markerRWorld=this.max;const markerLView=Math.round(dt.xWorldToView(markerLWorld));const markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
+if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
+const pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
+ctx.lineWidth=1;},drawLine_(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)return;const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected){ctx.strokeStyle='rgb(255, 0, 0)';}else{ctx.strokeStyle='rgb(0, 0, 0)';}
+ctx.stroke();ctx.restore();},drawIndicators(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
+if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_(ctx,viewLWorld,viewRWorld,xWorld,si,selected){const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);const pixelRatio=window.devicePixelRatio||1;const viewY=si.y*devicePixelRatio;const viewHeight=si.height*devicePixelRatio;const arrowSize=4*pixelRatio;if(selected){ctx.fillStyle='rgb(255, 0, 0)';}else{ctx.fillStyle='rgb(0, 0, 0)';}
+tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator,TimelineInterestRange,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
+ContainerToTrackMap.prototype={addContainer(container,track){if(!track){throw new Error('Must provide a track.');}
+this.stableIdToTrackMap_[container.stableId]=track;},clear(){this.stableIdToTrackMap_={};},getTrackByStableId(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
+EventToTrackMap.prototype={addEvent(event,track){if(!track){throw new Error('Must provide a track.');}
+this[event.guid]=track;}};return{EventToTrackMap,};});'use strict';tr.exportTo('tr.ui',function(){const TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;const TimelineInterestRange=tr.ui.TimelineInterestRange;const IDEAL_MAJOR_MARK_DISTANCE_PX=150;const MAJOR_MARK_ROUNDING_FACTOR=100000;class AnimationControllerProxy{constructor(target){this.target_=target;}
+get panX(){return this.target_.currentDisplayTransform_.panX;}
+set panX(panX){this.target_.currentDisplayTransform_.panX=panX;}
+get panY(){return this.target_.currentDisplayTransform_.panY;}
+set panY(panY){this.target_.currentDisplayTransform_.panY=panY;}
+get scaleX(){return this.target_.currentDisplayTransform_.scaleX;}
+set scaleX(scaleX){this.target_.currentDisplayTransform_.scaleX=scaleX;}
+cloneAnimationState(){return this.target_.currentDisplayTransform_.clone();}
+xPanWorldPosToViewPos(xWorld,xView){this.target_.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,this.target_.modelTrackContainer_.canvas.clientWidth);}}
+function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.timeMode_=TimelineViewport.TimeMode.TIME_IN_MS;this.majorMarkWorldPositions_=[];this.majorMarkUnit_=undefined;this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();this.dispatchChangeEvent=this.dispatchChangeEvent.bind(this);}
+TimelineViewport.TimeMode={TIME_IN_MS:0,REVISIONS:1};TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_(){this.dispatchChangeEvent();},dispatchChangeEvent(){tr.b.dispatchSimpleEvent(this,'change');},detach(){window.removeEventListener('resize',this.dispatchChangeEvent);},initAnimationController_(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));this.dtAnimationController_.target=new AnimationControllerProxy(this);},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately(displayTransform){this.dtAnimationController_.cancelActiveAnimation();const oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation(animation){if(!(animation instanceof tr.ui.b.Animation)){throw new Error('animation must be instanceof tr.ui.b.Animation');}
+this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.math.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
+this.modelTrackContainer_.clientHeight);}
+const changed=!this.currentDisplayTransform.equals(oldDisplayTransform);const yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged){this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;}
+if(changed){this.dispatchChangeEvent();}},onModelTrackControllerScroll_(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY){this.dtAnimationController_.cancelActiveAnimation();}
+const panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_){this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);}
+this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_===enabled)return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_===timebase)return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},get majorMarkWorldPositions(){return this.majorMarkWorldPositions_;},get majorMarkUnit(){switch(this.timeMode_){case TimelineViewport.TimeMode.TIME_IN_MS:return tr.b.Unit.byName.timeInMsAutoFormat;case TimelineViewport.TimeMode.REVISIONS:return tr.b.Unit.byName.count;default:throw new Error('Cannot get Unit for unsupported time mode '+this.timeMode_);}},get timeMode(){return this.timeMode_;},set timeMode(mode){this.timeMode_=mode;this.dispatchChangeEvent();},updateMajorMarkData(viewLWorld,viewRWorld){const pixelRatio=window.devicePixelRatio||1;const dt=this.currentDisplayTransform;const idealMajorMarkDistancePix=IDEAL_MAJOR_MARK_DISTANCE_PX*pixelRatio;const idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);const majorMarkDistanceWorld=tr.b.math.preferredNumberLargerThanMin(idealMajorMarkDistanceWorld);const firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;this.majorMarkWorldPositions_=[];for(let curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){this.majorMarkWorldPositions_.push(Math.floor(MAJOR_MARK_ROUNDING_FACTOR*curX)/MAJOR_MARK_ROUNDING_FACTOR);}},drawMajorMarkLines(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(const majorMark of this.majorMarkWorldPositions_){const x=this.currentDisplayTransform.xWorldToView(majorMark);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
+ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)return;const dt=this.currentDisplayTransform;let x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){const vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
+x+=this.gridStep;}
+ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection(selection,offset){const newSelection=new tr.model.EventSet();for(const event of selection){if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
+continue;}
+const track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
+if(newSelection.length===0)return undefined;return newSelection;},rebuildEventToTrackMap(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport,};});'use strict';tr.exportTo('tr.c',function(){const BrushingState=tr.ui.b.BrushingState;const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;const Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
+BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_(){const e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_){return undefined;}
+return this.timelineView_.model;},get trackView(){if(!this.timelineView_){return undefined;}
+return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_){return undefined;}
+if(!this.timelineView_.trackView){return undefined;}
+return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled){window.addEventListener('popstate',this.onPopState_);}else{window.removeEventListener('popstate',this.onPopState_);}},modelWillChange(){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}},modelDidChange(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToEventSelectionStates(this.model);const e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_(){const selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;const state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_(e){if(e.state===null)return;const selection=this.selections_[e.state.selection_guid];if(selection){const newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
+e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel){throw new Error('Cannot apply this state, it is applied');}
+const hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
+this.currentBrushingState_=newBrushingState;return;}
+if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}
+this.currentBrushingState_=newBrushingState;this.currentBrushingState_.applyToEventSelectionStates(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const timelineView=this.timelineView_.trackView;if(!timelineView){return new tr.b.Task();}
+return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo(allPossibleMatches){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo(currentFocus){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState(viewId,newState){const oldStates=this.currentBrushingState_.viewSpecificBrushingStates;const newStates={};for(const id in oldStates){newStates[id]=oldStates[id];}
+if(newState===undefined){delete newStates[viewId];}else{newStates[viewId]=newState;}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless){throw new Error('Unsupported');}
+let currentElement=element;while(currentElement){if(currentElement.brushingStateController){return currentElement.brushingStateController;}
+if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
+let currentNode=currentElement;while(Polymer.dom(currentNode).parentNode){currentNode=Polymer.dom(currentNode).parentNode;}
+currentElement=currentNode.host;}
+return undefined;};return{BrushingStateController,};});'use strict';Polymer({is:'tr-ui-a-analysis-link',properties:{href:{type:String}},listeners:{'click':'onClicked_','mouseenter':'onMouseEnter_','mouseleave':'onMouseLeave_'},ready(){this.selection_=undefined;},attached(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached(){this.clearHighlight_();this.controller_=undefined;},set color(c){this.style.color=c;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;Polymer.dom(this).textContent=selection.userFriendlyName;},setSelectionAndContent(selection,opt_textContent){this.selection_=selection;if(opt_textContent){Polymer.dom(this).textContent=opt_textContent;}},getCurrentSelection_(){if(typeof this.selection_==='function'){return this.selection_();}
+return this.selection_;},setHighlight_(opt_eventSet){if(this.controller_){this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);}},clearHighlight_(opt_eventSet){this.setHighlight_();},onClicked_(clickEvent){if(!this.selection_)return;clickEvent.stopPropagation();const event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){const TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};TableFormat.ColumnAlignment={LEFT:0,RIGHT:1};return{TableFormat,};});'use strict';(function(){const RIGHT_ARROW=String.fromCharCode(0x25b6);const UNSORTED_ARROW=String.fromCharCode(0x25BF);const ASCENDING_ARROW=String.fromCharCode(0x25B4);const DESCENDING_ARROW=String.fromCharCode(0x25BE);const SelectionMode=tr.ui.b.TableFormat.SelectionMode;const SelectionModeValues=new Set(Object.values(SelectionMode));const HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;const HighlightStyleValues=new Set(Object.values(HighlightStyle));const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;const ColumnAlignmentValues=new Set(Object.values(ColumnAlignment));Polymer({is:'tr-ui-b-table',created(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;this.computedFontSizePx_=undefined;},ready(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.$.body.addEventListener('focus',this.onFocus_.bind(this),true);},clear(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;Polymer.dom(this).textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;},set zebra(zebra){if(zebra){this.setAttribute('zebra',true);}else{this.removeAttribute('zebra');}},get zebra(){return this.getAttribute('zebra');},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){const previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue){this.scheduleRebuildBody_();}},set tableColumns(columns){let columnsWithExpandButtons=[];for(let i=0;i<columns.length;i++){if(columns[i].showExpandButtons){columnsWithExpandButtons.push(i);}}
+if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
+for(let i=0;i<columns.length;i++){const colInfo=columns[i];if(colInfo.width===undefined)continue;const hasExpandButton=columnsWithExpandButtons.includes(i);const w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
+let sortIndex=undefined;const currentSortColumn=this.tableColumns[this.sortColumnIndex_];if(currentSortColumn){for(const[i,column]of columns.entries()){if(currentSortColumn.title===column.title){sortIndex=i;break;}}}
+this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.scheduleRebuildHeaders_();this.sortColumnIndex=sortIndex;this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},get userCanModifySortOrder(){return this.userCanModifySortOrder_;},set userCanModifySortOrder(userCanModifySortOrder){const newUserCanModifySortOrder=!!userCanModifySortOrder;if(newUserCanModifySortOrder===this.userCanModifySortOrder_){return;}
+this.userCanModifySortOrder_=newUserCanModifySortOrder;this.scheduleRebuildHeaders_();},set sortColumnIndex(number){if(number===this.sortColumnIndex_)return;if(number!==undefined){if(this.tableColumns_.length<=number){throw new Error('Column number '+number+' is out of bounds.');}
+if(!this.tableColumns_[number].cmp){throw new Error('Column '+number+' does not have a comparator.');}}
+this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){const newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_(){for(let i=0;i<this.headerCells_.length;i++){const headerCell=this.headerCells_[i];const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(!this.tableColumns_[i].cmp||(!this.userCanModifySortOrder_&&!isColumnCurrentlySorted)){headerCell.sideContent='';continue;}
+if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;headerCell.sideContentDisabled=false;continue;}
+headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;headerCell.sideContentDisabled=!this.userCanModifySortOrder_;}},generateHeaderColumns_(){const selectedTableColumnIndex=this.selectedTableColumnIndex;Polymer.dom(this.$.cols).textContent='';for(let i=0;i<this.tableColumns_.length;++i){const colElement=document.createElement('col');if(i===selectedTableColumnIndex){colElement.setAttribute('selected',true);}
+Polymer.dom(this.$.cols).appendChild(colElement);}
+this.headerCells_=[];Polymer.dom(this.$.head).textContent='';if(!this.showHeader_)return;const tr=this.appendNewElement_(this.$.head,'tr');for(let i=0;i<this.tableColumns_.length;i++){const td=this.appendNewElement_(tr,'td');const headerCell=document.createElement('tr-ui-b-table-header-cell');headerCell.column=this.tableColumns_[i];if(this.tableColumns_[i].cmp){const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(isColumnCurrentlySorted){headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;if(!this.userCanModifySortOrder_){headerCell.sideContentDisabled=true;}}
+if(this.userCanModifySortOrder_){Polymer.dom(td).classList.add('sensitive');if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;}
+headerCell.tapCallback=this.createSortCallback_(i);}}
+Polymer.dom(td).appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_(){if(this.tableRows_.length===0&&!this.showHeader)return;let rowToRemoveSizing;let rowToSize;if(this.showHeader){rowToSize=Polymer.dom(this.$.head).children[0];rowToRemoveSizing=Polymer.dom(this.$.body).children[0];}else{rowToSize=Polymer.dom(this.$.body).children[0];rowToRemoveSizing=Polymer.dom(this.$.head).children[0];}
+for(let i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&Polymer.dom(rowToRemoveSizing).children[i]){const tdToRemoveSizing=Polymer.dom(rowToRemoveSizing).children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
+const td=Polymer.dom(rowToSize).children[i];let delta;if(this.columnsWithExpandButtons_.includes(i)){td.style.paddingLeft=this.basicIndentation_+'px';delta=this.basicIndentation_+'px';}else{delta=undefined;}
+function calc(base,delta){if(delta){return'calc('+base+' - '+delta+')';}
+return base;}
+const w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_(columnNumber){return function(){if(!this.userCanModifySortOrder_)return;const previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber){this.sortDescending=false;}else{this.sortDescending=!this.sortDescending;}}.bind(this);},generateTableRowNodes_(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){let c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_){c=-c;}
+return c;}.bind(this));}
+for(let i=0;i<userRows.length;i++){const userRow=userRows[i];const rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);const htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){Polymer.dom(tableSection).insertBefore(htmlNode,Polymer.dom(tableSection).firstChild);}else{const nextSiblingOfLastAdded=Polymer.dom(lastAddedRow).nextSibling;Polymer.dom(tableSection).insertBefore(htmlNode,nextSiblingOfLastAdded);}
+lastAddedRow=htmlNode;if(!rowInfo.isExpanded)continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
+return lastAddedRow;},getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo){let rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow,htmlNode:undefined,parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
+rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_(userRow,trElement){if(!this.customizeTableRowCallback_)return;this.customizeTableRowCallback_(userRow,trElement);},get basicIndentation_(){if(this.computedFontSizePx_===undefined){this.computedFontSizePx_=parseInt(getComputedStyle(this).fontSize)||16;}
+return this.computedFontSizePx_-2;},getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
+const INDENT_SPACE=indentation*16;const INDENT_SPACE_NO_BUTTON=indentation*16+this.basicIndentation_;const trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);const isBodyRow=tableSection===this.$.body;const isExpandableRow=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;for(let i=0;i<this.tableColumns_.length;){const td=this.appendNewElement_(trElement,'td');td.columnIndex=i;const column=this.tableColumns_[i];const value=column.value(rowInfo.userRow);const colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;switch(column.align){case undefined:case ColumnAlignment.LEFT:break;case ColumnAlignment.RIGHT:td.style.textAlign='right';break;default:throw new Error('Invalid alignment of column at index='+i+': '+column.align);}
+if(this.doesColumnIndexSupportSelection(i)){Polymer.dom(td).classList.add('supports-selection');}
+if(this.columnsWithExpandButtons_.includes(i)){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';td.style.display='flex';const expandButton=this.appendNewElement_(td,'expand-button');Polymer.dom(expandButton).textContent=RIGHT_ARROW;if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');}}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
+if(value!==undefined){Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));}
+td.addEventListener('click',function(i,clickEvent){clickEvent.preventDefault();if(!isBodyRow&&!isExpandableRow)return;clickEvent.stopPropagation();if(clickEvent.target.tagName==='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
+if(isBodyRow&&this.selectionMode_!==SelectionMode.NONE){let shouldSelect=false;let shouldFocus=false;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;shouldFocus=true;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(i)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==i;shouldFocus=true;}
+break;default:throw new Error('Invalid selection mode '+
+this.selectionMode_);}
+if(shouldFocus){this.focus();}
+if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,i);return;}}
+if(isExpandableRow){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this,i));if(isBodyRow){td.addEventListener('dblclick',function(i,e){e.stopPropagation();this.dispatchStepIntoEvent_(rowInfo,i);}.bind(this,i));}
+i+=colSpan;}
+return rowInfo.htmlNode;},removeSubNodes_(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)return;for(let i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){const subRow=rowInfo.userRow[this.subRowsPropertyName_][i];const subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)continue;const subNode=subRowInfo.htmlNode;if(subNode&&Polymer.dom(subNode).parentNode===tableSection){Polymer.dom(tableSection).removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_(){if(this.rebuildPending_)return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_(){this.rebuild();},rebuild(){const wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
+if(this.bodyDirty_){Polymer.dom(this.$.body).textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){const trElement=this.ownerDocument.createElement('tr');Polymer.dom(this.$.body).appendChild(trElement);Polymer.dom(trElement).classList.add('empty-row');const td=this.ownerDocument.createElement('td');Polymer.dom(trElement).appendChild(td);td.colSpan=this.tableColumns_.length;const emptyValue=this.emptyValue_;Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
+this.bodyDirty_=false;}
+if(wasBodyOrHeaderDirty)this.applySizes_();if(this.footerDirty_){Polymer.dom(this.$.foot).textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){Polymer.dom(this.$.body).classList.add('has-footer');}else{Polymer.dom(this.$.body).classList.remove('has-footer');}
+this.footerDirty_=false;}},appendNewElement_(parent,tagName){const element=parent.ownerDocument.createElement(tagName);Polymer.dom(parent).appendChild(element);return element;},getExpandedForTableRow(userRow){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return rowInfo.isExpanded;},getExpandedForUserRow_(userRow){if(userRow[this.subRowsPropertyName_]===undefined){return false;}
+if(userRow[this.subRowsPropertyName_].length===0){return false;}
+if(userRow.isExpanded){return true;}
+if((userRow.isExpanded!==undefined)&&(userRow.isExpanded===false)){return false;}
+const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.isExpanded){return true;}
+if(this.defaultExpansionStateCallback_===undefined){return false;}
+let parentUserRow=undefined;if(rowInfo&&rowInfo.parentRowInfo){parentUserRow=rowInfo.parentRowInfo.userRow;}
+return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow(userRow,expanded){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();const rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+const wasExpanded=rowInfo.isExpanded;rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)return;if(rowInfo.htmlNode.parentElement!==tableSection){return;}
+const expandButton=Polymer.dom(rowInfo.htmlNode).querySelector('expand-button');if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');const lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{Polymer.dom(expandButton).classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
+if(wasExpanded!==rowInfo.isExpanded){const e=new tr.b.Event('row-expanded-changed');e.row=rowInfo.userRow;this.dispatchEvent(e);}
+this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!SelectionModeValues.has(selectionMode)){throw new Error('Invalid selection mode '+selectionMode);}
+this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!HighlightStyleValues.has(rowHighlightStyle)){throw new Error('Invalid row highlight style '+rowHighlightStyle);}
+this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT){return this.rowHighlightStyle_;}
+switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!HighlightStyleValues.has(cellHighlightStyle)){throw new Error('Invalid cell highlight style '+cellHighlightStyle);}
+this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT){return this.cellHighlightStyle_;}
+switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:Polymer.dom(this.$.body).removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
+resolvedHighlightStyle);}},didSelectionStateChange_(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);this.removeSelectedState_();switch(this.selectionMode_){case SelectionMode.ROW:Polymer.dom(this.$.body).setAttribute('selection-mode','row');Polymer.dom(this.$.body).setAttribute('tabindex',0);this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:Polymer.dom(this.$.body).setAttribute('selection-mode','cell');Polymer.dom(this.$.body).setAttribute('tabindex',0);if(this.selectedTableRowInfo_&&this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){this.selectedTableRowInfo_=undefined;}else{this.selectedColumnIndex_=i;}}
+break;case SelectionMode.NONE:Polymer.dom(this.$.body).removeAttribute('selection-mode');Polymer.dom(this.$.body).removeAttribute('tabindex');this.$.body.blur();this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_(){if(this.selectedTableRowInfo_===undefined)return;function isVisible(rowInfo){if(!rowInfo.htmlNode)return false;return!!rowInfo.htmlNode.parentElement;}
+if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
+this.removeSelectedState_();let curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo)){curRowInfo=curRowInfo.parentRowInfo;}
+this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_){this.updateSelectedState_();}else{this.selectedColumnIndex_=undefined;}},didTableRowInfoGetClicked_(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex)){return;}
+if(this.selectedColumnIndex!==columnIndex){this.selectedColumnIndex=columnIndex;}
+case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo){this.selectedTableRow=rowInfo.userRow;}}},dispatchStepIntoEvent_(rowInfo,columnIndex){const e=new tr.b.Event('step-into');e.tableRow=rowInfo.userRow;e.tableColumn=this.tableColumns_[columnIndex];e.columnIndex=columnIndex;this.dispatchEvent(e);},get selectedCell(){const row=this.selectedTableRow;const columnIndex=this.selectedColumnIndex;if(row===undefined||columnIndex===undefined||this.tableColumns_.length<=columnIndex){return undefined;}
+const column=this.tableColumns_[columnIndex];return{row,column,value:column.value(row)};},get selectedTableColumnIndex(){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(cols[i].getAttribute('selected')){return i;}}
+return undefined;},set selectedTableColumnIndex(selectedIndex){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(i===selectedIndex){cols[i].setAttribute('selected',true);}else{cols[i].removeAttribute('selected');}}},get selectedTableRow(){if(!this.selectedTableRowInfo_)return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
+let rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo){throw new Error('Row has not been seen, must expand its parents.');}}
+const e=this.prepareToChangeSelection_();if(!rowInfo){this.selectedColumnIndex_=undefined;}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){throw new Error('Cannot find a selectable column.');}
+this.selectedColumnIndex_=i;}
+break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+this.selectedTableRowInfo_=rowInfo;this.updateSelectedState_();this.dispatchEvent(e);},prepareToChangeSelection_(){const e=new tr.b.Event('selection-changed');const previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo){e.previousSelectedTableRow=previousSelectedRowInfo.userRow;}else{e.previousSelectedTableRow=undefined;}
+this.removeSelectedState_();return e;},removeSelectedState_(){this.setSelectedState_(false);},updateSelectedState_(){this.setSelectedState_(true);},setSelectedState_(select){if(this.selectedTableRowInfo_===undefined)return;const rowNode=this.selectedTableRowInfo_.htmlNode;if(select){Polymer.dom(rowNode).setAttribute('selected',true);}else{Polymer.dom(rowNode).removeAttribute('selected');}
+const cellNode=Polymer.dom(rowNode).children[this.selectedColumnIndex_];if(!cellNode)return;if(select){Polymer.dom(cellNode).setAttribute('selected',true);}else{Polymer.dom(cellNode).removeAttribute('selected');}},doesColumnIndexSupportSelection(columnIndex){const columnInfo=this.tableColumns_[columnIndex];const scs=columnInfo.supportsCellSelection;if(scs===false)return false;return true;},getFirstSelectableColumnIndex_(){for(let i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){return i;}}
+return-1;},getSelectableNodeGivenTableRowNode_(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return Polymer.dom(htmlNode).children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL){return undefined;}
+return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
+if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length){throw new Error('Invalid index');}
+if(!this.doesColumnIndexSupportSelection(selectedColumnIndex)){throw new Error('Selection is not supported on this column');}
+const e=this.prepareToChangeSelection_();if(this.selectedColumnIndex_===undefined){this.selectedTableRowInfo_=undefined;}else if(!this.selectedTableRowInfo_){if(this.tableRows_.length===0){throw new Error('No available row to be selected');}
+this.selectedTableRowInfo_=this.tableRowsInfo_.get(this.tableRows_[0]);}
+this.selectedColumnIndex_=selectedColumnIndex;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_(e){if(this.selectionMode_===SelectionMode.NONE)return;const CODE_TO_COMMAND_NAMES={13:'ENTER',32:'SPACE',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};const cmdName=CODE_TO_COMMAND_NAMES[e.keyCode];if(cmdName===undefined)return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},onFocus_(e){if(this.selectionMode_===SelectionMode.NONE||this.selectedTableRow||this.tableRows_.length===0){return;}
+if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+this.selectedTableRow=this.tableRows_[0];},focus(){this.$.body.focus();this.onFocus_();},blur(){this.$.body.blur();},get isFocused(){return this.root.activeElement===this.$.body;},performKeyCommand_(cmdName){this.rebuildIfNeeded_();switch(cmdName){case'ARROW_UP':this.selectPreviousOrFirstRowIfPossible_();return;case'ARROW_DOWN':this.selectNextOrFirstRowIfPossible_();return;case'ARROW_RIGHT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.expandRowAndSelectChildRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheRightIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+case'ARROW_LEFT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.collapseRowOrSelectParentRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheLeftIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+case'SPACE':this.toggleRowExpansionStateIfPossible_();return;case'ENTER':this.stepIntoSelectionIfPossible_();return;default:throw new Error('Unrecognized command '+cmdName);}},selectPreviousOrFirstRowIfPossible_(){const prev=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.previousElementSibling:this.$.body.firstChild;if(!prev)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;},selectNextOrFirstRowIfPossible_(){this.getFirstSelectableColumnIndex_;const next=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.nextElementSibling:this.$.body.firstChild;if(!next)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;},expandRowAndSelectChildRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+if(!selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,true);}
+this.selectedTableRow=selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow;},collapseRowOrSelectParentRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo)return;if(selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,false);}else{const parentRowInfo=selectedRowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;}}},selectNextSelectableCellToTheRightIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_+1;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},selectNextSelectableCellToTheLeftIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_-1;i>=0;i--){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},toggleRowExpansionStateIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+this.setExpandedForTableRow(selectedRowInfo.userRow,!selectedRowInfo.isExpanded);},stepIntoSelectionIfPossible_(){if(!this.selectedTableRowInfo_)return;this.dispatchStepIntoEvent_(this.selectedTableRowInfo_,this.selectedColumnIndex_);},dispatchSortingChangedEvent_(){const e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table-header-cell',created(){this.tapCallback_=undefined;this.cellTitle_='';this.align_=undefined;this.selectable_=false;this.column_=undefined;},ready(){this.addEventListener('click',this.onTap_.bind(this));},set column(column){this.column_=column;this.align=column.align;this.cellTitle=column.title;},get column(){return this.column_;},set cellTitle(value){this.cellTitle_=value;const titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';Polymer.dom(this.$.title).appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},set align(align){switch(align){case undefined:case ColumnAlignment.LEFT:this.style.justifyContent='';break;case ColumnAlignment.RIGHT:this.style.justifyContent='flex-end';break;default:throw new Error('Invalid alignment of column (title=\''+
+this.cellTitle_+'\'): '+align);}
+this.align_=align;},get align(){return this.align_;},clearSideContent(){Polymer.dom(this.$.side).textContent='';},set sideContent(content){Polymer.dom(this.$.side).textContent=content;this.$.side.style.display=content?'inline':'none';},get sideContent(){return Polymer.dom(this.$.side).textContent;},set sideContentDisabled(sideContentDisabled){this.$.side.classList.toggle('disabled',sideContentDisabled);},get sideContentDisabled(){return this.$.side.classList.contains('disabled');},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_(){if(this.tapCallback_){this.tapCallback_();}}});'use strict';tr.exportTo('tr.b.math',function(){class RunningStatistics{constructor(){this.mean_=0;this.count_=0;this.max_=-Infinity;this.min_=Infinity;this.sum_=0;this.variance_=0;this.meanlogs_=0;}
+get count(){return this.count_;}
+get geometricMean(){if(this.meanlogs_===undefined)return 0;return Math.exp(this.meanlogs_);}
+get mean(){if(this.count_===0)return undefined;return this.mean_;}
+get max(){return this.max_;}
+get min(){return this.min_;}
+get sum(){return this.sum_;}
+get variance(){if(this.count_===0)return undefined;if(this.count_===1)return 0;return this.variance_/(this.count_-1);}
+get stddev(){if(this.count_===0)return undefined;return Math.sqrt(this.variance);}
+add(x){this.count_++;this.max_=Math.max(this.max_,x);this.min_=Math.min(this.min_,x);this.sum_+=x;if(x<=0){this.meanlogs_=undefined;}else if(this.meanlogs_!==undefined){this.meanlogs_+=(Math.log(Math.abs(x))-this.meanlogs_)/this.count;}
+if(this.count_===1){this.mean_=x;this.variance_=0;}else{const oldMean=this.mean_;const oldVariance=this.variance_;if(oldMean===Infinity||oldMean===-Infinity){this.mean_=this.sum_/this.count_;}else{this.mean_=oldMean+(x-oldMean)/this.count_;}
+this.variance_=oldVariance+(x-oldMean)*(x-this.mean_);}}
+merge(other){const result=new RunningStatistics();result.count_=this.count_+other.count_;result.sum_=this.sum_+other.sum_;result.min_=Math.min(this.min_,other.min_);result.max_=Math.max(this.max_,other.max_);if(result.count===0){result.mean_=0;result.variance_=0;result.meanlogs_=0;}else{result.mean_=result.sum/result.count;const deltaMean=(this.mean||0)-(other.mean||0);result.variance_=this.variance_+other.variance_+
+(this.count*other.count*deltaMean*deltaMean/result.count);if(this.meanlogs_===undefined||other.meanlogs_===undefined){result.meanlogs_=undefined;}else{result.meanlogs_=(this.count*this.meanlogs_+
+other.count*other.meanlogs_)/result.count;}}
+return result;}
+asDict(){if(!this.count){return[];}
+return[this.count_,this.max_,this.meanlogs_,this.mean_,this.min_,this.sum_,this.variance_,];}
+static fromDict(dict){const result=new RunningStatistics();if(dict.length!==7){return result;}
+[result.count_,result.max_,result.meanlogs_,result.mean_,result.min_,result.sum_,result.variance_,]=dict;return result;}}
+return{RunningStatistics,};});'use strict';tr.exportTo('tr.v.d',function(){class Diagnostic{constructor(){this.guid_=undefined;}
+clone(){return new this.constructor();}
+canAddDiagnostic(otherDiagnostic){return false;}
+addDiagnostic(otherDiagnostic){throw new Error('Abstract virtual method: subclasses must override '+'this method if they override canAddDiagnostic');}
+get guid(){if(this.guid_===undefined){this.guid_=tr.b.GUID.allocateUUID4();}
+return this.guid_;}
+set guid(guid){if(this.guid_!==undefined){throw new Error('Cannot reset guid');}
+this.guid_=guid;}
+asDictOrReference(){if(this.guid_!==undefined){return this.guid_;}
+return this.asDict();}
+asDict(){const result={type:this.constructor.name};if(this.guid_!==undefined){result.guid=this.guid_;}
+this.asDictInto_(result);return result;}
+asDictInto_(d){throw new Error('Abstract virtual method: subclasses must override '+'this method if they override canAddDiagnostic');}
+static fromDict(d){const typeInfo=Diagnostic.findTypeInfoWithName(d.type);if(!typeInfo){throw new Error('Unrecognized diagnostic type: '+d.type);}
+const diagnostic=typeInfo.constructor.fromDict(d);if(d.guid!==undefined)diagnostic.guid=d.guid;return diagnostic;}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Diagnostic;tr.b.decorateExtensionRegistry(Diagnostic,options);Diagnostic.addEventListener('will-register',function(e){const constructor=e.typeInfo.constructor;if(!(constructor.fromDict instanceof Function)||(constructor.fromDict===Diagnostic.fromDict)||(constructor.fromDict.length!==1)){throw new Error('Diagnostics must define fromDict(d)');}});return{Diagnostic,};});'use strict';tr.exportTo('tr.v.d',function(){class Breakdown extends tr.v.d.Diagnostic{constructor(){super();this.values_=new Map();this.colorScheme=undefined;}
+clone(){const clone=new Breakdown();clone.colorScheme=this.colorScheme;clone.addDiagnostic(this);return clone;}
+canAddDiagnostic(otherDiagnostic){return((otherDiagnostic instanceof Breakdown)&&(otherDiagnostic.colorScheme===this.colorScheme));}
+addDiagnostic(otherDiagnostic){for(const[name,value]of otherDiagnostic){this.set(name,this.get(name)+value);}
+return this;}
+set(name,value){if(typeof name!=='string'||typeof value!=='number'){throw new Error('Breakdown maps from strings to numbers');}
+this.values_.set(name,value);}
+get(name){return this.values_.get(name)||0;}*[Symbol.iterator](){for(const pair of this.values_){yield pair;}}
+asDictInto_(d){d.values={};for(const[name,value]of this){d.values[name]=tr.b.numberToJson(value);}
+if(this.colorScheme){d.colorScheme=this.colorScheme;}}
+static fromDict(d){const breakdown=new Breakdown();for(const[name,value]of Object.entries(d.values)){breakdown.set(name,tr.b.numberFromJson(value));}
+if(d.colorScheme){breakdown.colorScheme=d.colorScheme;}
+return breakdown;}}
+tr.v.d.Diagnostic.register(Breakdown,{elementName:'tr-v-ui-breakdown-span'});return{Breakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class CollectedRelatedEventSet extends tr.v.d.Diagnostic{constructor(){super();this.eventSetsByCanonicalUrl_=new Map();}
+asDictInto_(d){d.events={};for(const[canonicalUrl,eventSet]of this){d.events[canonicalUrl]=[];for(const event of eventSet){d.events[canonicalUrl].push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}}
+static fromDict(d){const result=new CollectedRelatedEventSet();for(const[canonicalUrl,events]of Object.entries(d.events)){result.eventSetsByCanonicalUrl_.set(canonicalUrl,events.map(e=>new tr.v.d.EventRef(e)));}
+return result;}
+get size(){return this.eventSetsByCanonicalUrl_.size;}
+get(canonicalUrl){return this.eventSetsByCanonicalUrl_.get(canonicalUrl);}*[Symbol.iterator](){for(const[canonicalUrl,eventSet]of this.eventSetsByCanonicalUrl_){yield[canonicalUrl,eventSet];}}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof tr.v.d.RelatedEventSet||otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet;}
+addEventSetForCanonicalUrl(canonicalUrl,events){let myEventSet=this.eventSetsByCanonicalUrl_.get(canonicalUrl);if(myEventSet===undefined){myEventSet=new Set();this.eventSetsByCanonicalUrl_.set(canonicalUrl,myEventSet);}
+for(const event of events){myEventSet.add(event);}}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet){for(const[canonicalUrl,otherEventSet]of otherDiagnostic){this.addEventSetForCanonicalUrl(canonicalUrl,otherEventSet);}
+return;}
+if(!otherDiagnostic.canonicalUrl)return;this.addEventSetForCanonicalUrl(otherDiagnostic.canonicalUrl,otherDiagnostic);}}
+tr.v.d.Diagnostic.register(CollectedRelatedEventSet,{elementName:'tr-v-ui-collected-related-event-set-span'});return{CollectedRelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){class DateRange extends tr.v.d.Diagnostic{constructor(ms){super();this.range_=new tr.b.math.Range();this.range_.addValue(ms);}
+get minDate(){return new Date(this.range_.min);}
+get maxDate(){return new Date(this.range_.max);}
+get durationMs(){return this.range_.duration;}
+clone(){const clone=new tr.v.d.DateRange(this.range_.min);clone.addDiagnostic(this);return clone;}
+equals(other){if(!(other instanceof DateRange))return false;return this.range_.equals(other.range_);}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof DateRange;}
+addDiagnostic(other){this.range_.addRange(other.range_);}
+toString(){const minDate=tr.b.formatDate(this.minDate);if(this.durationMs===0)return minDate;const maxDate=tr.b.formatDate(this.maxDate);return`${minDate} - ${maxDate}`;}
+asDictInto_(d){d.min=this.range_.min;if(this.durationMs===0)return;d.max=this.range_.max;}
+static fromDict(d){const dateRange=new DateRange(d.min);if(d.max!==undefined)dateRange.range_.addValue(d.max);return dateRange;}}
+tr.v.d.Diagnostic.register(DateRange,{elementName:'tr-v-ui-date-range-span'});return{DateRange,};});'use strict';tr.exportTo('tr.v.d',function(){class DiagnosticRef{constructor(guid){this.guid=guid;}
+asDict(){return this.guid;}
+asDictOrReference(){return this.asDict();}}
+return{DiagnosticRef,};});'use strict';tr.exportTo('tr.v.d',function(){function stableStringify(obj){let replacer;if(!(obj instanceof Array))replacer=Object.keys(obj).sort();return JSON.stringify(obj,replacer);}
+class GenericSet extends tr.v.d.Diagnostic{constructor(values){super();this.values_=new Set(values);}
+get size(){return this.values_.size;}
+get length(){return this.values_.size;}*[Symbol.iterator](){for(const value of this.values_){yield value;}}
+has(value){if(typeof value!=='object')return this.values_.has(value);const json=JSON.stringify(value);for(const x of this){if(typeof x!=='object')continue;if(json===JSON.stringify(x))return true;}
+return false;}
+equals(other){if(!(other instanceof GenericSet))return false;if(this.size!==other.size)return false;for(const value of this){if(!other.has(value))return false;}
+return true;}
+asDictInto_(d){d.values=Array.from(this);}
+static fromDict(d){return new GenericSet(d.values);}
+clone(){return new GenericSet(this.values_);}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof GenericSet;}
+addDiagnostic(otherDiagnostic){const jsons=new Set();for(const value of this){if(typeof value!=='object')continue;jsons.add(stableStringify(value));}
+for(const value of otherDiagnostic){if(typeof value==='object'&&jsons.has(stableStringify(value))){continue;}
+this.values_.add(value);}}}
+tr.v.d.Diagnostic.register(GenericSet,{elementName:'tr-v-ui-generic-set-span'});return{GenericSet,};});'use strict';tr.exportTo('tr.v.d',function(){class GroupingPath extends tr.v.d.Diagnostic{constructor(groupingPath){super();this.groupingPath_=groupingPath;}
+clone(){return new GroupingPath(Array.from(this.groupingPath_));}
+addToHistogram(hist){hist.diagnostics.set(tr.v.d.RESERVED_NAMES.GROUPING_PATH,this);}
+static getFromHistogram(hist){return hist.diagnostics.get(tr.v.d.RESERVED_NAMES.GROUPING_PATH);}
+equals(other){return 0===tr.b.compareArrays(this.groupingPath_,other.groupingPath_,(x,y)=>x.localeCompare(y));}
+asDictInto_(d){d.groupingPath=this.groupingPath_;}
+static fromDict(d){return new GroupingPath(d.groupingPath);}}
+tr.v.d.Diagnostic.register(GroupingPath);return{GroupingPath,};});'use strict';tr.exportTo('tr.v.d',function(){class EventRef{constructor(event){this.stableId=event.stableId;this.title=event.title;this.start=event.start;this.duration=event.duration;this.end=this.start+this.duration;this.guid=tr.b.GUID.allocateSimple();}}
+return{EventRef,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedEventSet extends tr.v.d.Diagnostic{constructor(opt_events){super();this.eventsByStableId_=new Map();this.canonicalUrl_=undefined;if(opt_events){if(opt_events instanceof tr.model.EventSet||opt_events instanceof Array){for(const event of opt_events){this.add(event);}}else{this.add(opt_events);}}}
+clone(){const clone=new tr.v.d.CollectedRelatedEventSet();clone.addDiagnostic(this);return clone;}
+add(event){this.eventsByStableId_.set(event.stableId,event);}
+has(event){return this.eventsByStableId_.has(event.stableId);}
+get length(){return this.eventsByStableId_.size;}*[Symbol.iterator](){for(const event of this.eventsByStableId_.values()){yield event;}}
+get canonicalUrl(){return this.canonicalUrl_;}
+resolve(model,opt_required){for(const[stableId,value]of this.eventsByStableId_){if(!(value instanceof tr.v.d.EventRef))continue;const event=model.getEventByStableId(stableId);if(event instanceof tr.model.Event){this.eventsByStableId_.set(stableId,event);}else if(opt_required){throw new Error('Unable to find Event '+stableId);}}}
+asDictInto_(d){d.events=[];for(const event of this){d.events.push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}
+static fromDict(d){return new RelatedEventSet(d.events.map(event=>new tr.v.d.EventRef(event)));}}
+tr.v.d.Diagnostic.register(RelatedEventSet,{elementName:'tr-v-ui-related-event-set-span'});return{RelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){function HistogramRef(guid){this.guid=guid;}
+return{HistogramRef};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedHistogramMap extends tr.v.d.Diagnostic{constructor(){super();this.histogramsByName_=new Map();}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedHistogramMap;}
+addDiagnostic(otherDiagnostic){}
+mergeRelationships(otherDiagnostic,parentHist,otherParentHist){const parentGroupingPath=tr.v.d.GroupingPath.getFromHistogram(parentHist);for(const[name,otherRelatedHist]of otherDiagnostic){const mergedTo=otherRelatedHist.diagnostics.get(tr.v.d.RESERVED_NAMES.MERGED_TO);if(mergedTo===undefined)continue;for(const relatedHist of mergedTo.histogramsByName_.values()){const relatedGroupingPath=tr.v.d.GroupingPath.getFromHistogram(relatedHist);if(relatedGroupingPath===undefined)continue;if(!parentGroupingPath.equals(relatedGroupingPath))continue;this.set(name,relatedHist);}}}
+get(name){return this.histogramsByName_.get(name);}
+set(name,hist){if(!(hist instanceof tr.v.Histogram)&&!(hist instanceof tr.v.d.HistogramRef)){throw new Error('Must be instanceof Histogram or HistogramRef: '+
+hist);}
+this.histogramsByName_.set(name,hist);}
+add(hist){this.set(hist.name,hist);}
+get length(){return this.histogramsByName_.size;}*[Symbol.iterator](){for(const pair of this.histogramsByName_){yield pair;}}
+resolve(histograms,opt_required){for(const[name,value]of this){if(!(value instanceof tr.v.d.HistogramRef))continue;const guid=value.guid;const hist=histograms.lookupHistogram(guid);if(hist instanceof tr.v.Histogram){this.histogramsByName_.set(name,hist);}else if(opt_required){throw new Error('Unable to find Histogram '+guid);}}}
+asDictInto_(d){d.values={};for(const[name,hist]of this){d.values[name]=hist.guid;}}
+static fromDict(d){const map=new RelatedHistogramMap();for(const[name,guid]of Object.entries(d.values)){map.set(name,new tr.v.d.HistogramRef(guid));}
+return map;}}
+tr.v.d.Diagnostic.register(RelatedHistogramMap,{elementName:'tr-v-ui-related-histogram-map-span'});return{RelatedHistogramMap,};});'use strict';tr.exportTo('tr.v.d',function(){const COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER='ChromeUserFriendlyCategory';class RelatedHistogramBreakdown extends tr.v.d.RelatedHistogramMap{constructor(){super();this.colorScheme=undefined;}
+clone(){const clone=new RelatedHistogramBreakdown();clone.colorScheme=this.colorScheme;return clone;}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedHistogramBreakdown&&otherDiagnostic.colorScheme===this.colorScheme;}
+set(name,hist){if(!(hist instanceof tr.v.d.HistogramRef)){if(!(hist instanceof tr.v.Histogram)){throw new Error('RelatedHistogramBreakdown can only contain Histograms');}
+if((this.length>0)&&(hist.unit!==tr.b.getFirstElement(this)[1].unit)){throw new Error('Units mismatch',tr.b.getFirstElement(this)[1].unit,hist.unit);}}
+tr.v.d.RelatedHistogramMap.prototype.set.call(this,name,hist);}
+asDictInto_(d){tr.v.d.RelatedHistogramMap.prototype.asDictInto_.call(this,d);if(this.colorScheme)d.colorScheme=this.colorScheme;}
+static fromDict(d){const diagnostic=new RelatedHistogramBreakdown();for(const[name,guid]of Object.entries(d.values)){diagnostic.set(name,new tr.v.d.HistogramRef(guid));}
+if(d.colorScheme)diagnostic.colorScheme=d.colorScheme;return diagnostic;}
+static buildFromEvents(histograms,namePrefix,events,categoryForEvent,unit,opt_sampleForEvent,opt_binBoundaries,opt_this){const sampleForEvent=opt_sampleForEvent||((event)=>event.cpuSelfTime);const diagnostic=new RelatedHistogramBreakdown();for(const event of events){const sample=sampleForEvent.call(opt_this,event);if(sample===undefined)continue;const eventCategory=categoryForEvent.call(opt_this,event);let hist=diagnostic.get(eventCategory);if(hist===undefined){hist=new tr.v.Histogram(namePrefix+eventCategory,unit,opt_binBoundaries);histograms.addHistogram(hist);diagnostic.set(eventCategory,hist);}
+hist.addSample(sample,{relatedEvents:new tr.v.d.RelatedEventSet([event])});}
+return diagnostic;}}
+tr.v.d.Diagnostic.register(RelatedHistogramBreakdown,{elementName:'tr-v-ui-breakdown-span'});return{COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER,RelatedHistogramBreakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class Scalar extends tr.v.d.Diagnostic{constructor(value){super();if(!(value instanceof tr.b.Scalar)){throw new Error('expected Scalar');}
+this.value=value;}
+clone(){return new Scalar(this.value);}
+asDictInto_(d){d.value=this.value.asDict();}
+static fromDict(d){return new Scalar(tr.b.Scalar.fromDict(d.value));}}
+tr.v.d.Diagnostic.register(Scalar,{elementName:'tr-v-ui-scalar-diagnostic-span'});return{Scalar,};});'use strict';tr.exportTo('tr.v.d',function(){class TagMap extends tr.v.d.Diagnostic{constructor(opt_info){super();this.tagsToStoryNames_=new Map();if(opt_info){for(const[tag,storyDisplayNames]of Object.entries(opt_info.tagsToStoryNames||{})){this.tagsToStoryNames.set(tag,new Set(storyDisplayNames));}}}
+clone(){const clone=new TagMap();clone.addDiagnostic(this);return clone;}
+addToHistogram(hist){hist.diagnostics.set(tr.v.d.RESERVED_NAMES.TAG_MAP,this);}
+equals(other){if(!(other instanceof TagMap))return false;const keys1=new Set(this.tagsToStoryNames.keys());const keys2=new Set(other.tagsToStoryNames.keys());if(!tr.b.setsEqual(keys1,keys2)){return false;}
+for(const key of keys1){if(!tr.b.setsEqual(this.tagsToStoryNames.get(key),other.tagsToStoryNames.get(key))){return false;}}
+return true;}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof TagMap;}
+addDiagnostic(otherDiagnostic){for(const[name,storyDisplayNames]of
+otherDiagnostic.tagsToStoryNames){if(!this.tagsToStoryNames.has(name)){this.tagsToStoryNames.set(name,new Set());}
+for(const t of storyDisplayNames){this.tagsToStoryNames.get(name).add(t);}}
+return this;}
+asDictInto_(d){d.tagsToStoryNames={};for(const[name,value]of this.tagsToStoryNames){d.tagsToStoryNames[name]=Array.from(value);}}
+get tagsToStoryNames(){return this.tagsToStoryNames_;}
+static fromDict(d){const info=new TagMap();for(const[name,values]of
+Object.entries(d.tagsToStoryNames||{})){info.tagsToStoryNames.set(name,new Set(values));}
+return info;}}
+tr.v.d.Diagnostic.register(TagMap,{elementName:'tr-v-ui-tag-map-span'});return{TagMap,};});'use strict';tr.exportTo('tr.v.d',function(){class UnmergeableDiagnosticSet extends tr.v.d.Diagnostic{constructor(diagnostics){super();this._diagnostics=diagnostics;}
+clone(){const clone=new tr.v.d.UnmergeableDiagnosticSet();clone.addDiagnostic(this);return clone;}
+canAddDiagnostic(otherDiagnostic){return true;}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(const subOtherDiagnostic of otherDiagnostic){const clone=subOtherDiagnostic.clone();this.addDiagnostic(clone);}
+return;}
+for(let i=0;i<this._diagnostics.length;++i){if(this._diagnostics[i].canAddDiagnostic(otherDiagnostic)){this._diagnostics[i].addDiagnostic(otherDiagnostic);return;}}
+const clone=otherDiagnostic.clone();this._diagnostics.push(clone);}
+mergeRelationships(otherDiagnostic,parentHist,otherParentHist){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(const subDiagnostic of otherDiagnostic){this.mergeRelationships(subDiagnostic,parentHist,otherParentHist);}
+return;}
+for(const subDiagnostic of this){if(!(subDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(subDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)){continue;}
+subDiagnostic.mergeRelationships(otherDiagnostic,parentHist,otherParentHist);}}
+get length(){return this._diagnostics.length;}*[Symbol.iterator](){for(const diagnostic of this._diagnostics)yield diagnostic;}
+asDictInto_(d){d.diagnostics=this._diagnostics.map(d=>d.asDictOrReference());}
+static fromDict(d){return new UnmergeableDiagnosticSet(d.diagnostics.map(d=>((typeof d==='string')?new tr.v.d.DiagnosticRef(d):tr.v.d.Diagnostic.fromDict(d))));}}
+tr.v.d.Diagnostic.register(UnmergeableDiagnosticSet,{elementName:'tr-v-ui-unmergeable-diagnostic-set-span'});return{UnmergeableDiagnosticSet,};});'use strict';tr.exportTo('tr.v.d',function(){const RESERVED_INFOS={ANGLE_REVISIONS:{name:'angleRevisions',type:tr.v.d.GenericSet},ARCHITECTURES:{name:'architectures',type:tr.v.d.GenericSet},BENCHMARKS:{name:'benchmarks',type:tr.v.d.GenericSet},BENCHMARK_START:{name:'benchmarkStart',type:tr.v.d.DateRange},BOTS:{name:'bots',type:tr.v.d.GenericSet},BUG_COMPONENTS:{name:'bugComponents',type:tr.v.d.GenericSet},BUILDS:{name:'builds',type:tr.v.d.GenericSet},CATAPULT_REVISIONS:{name:'catapultRevisions',type:tr.v.d.GenericSet},CHROMIUM_COMMIT_POSITIONS:{name:'chromiumCommitPositions',type:tr.v.d.GenericSet},CHROMIUM_REVISIONS:{name:'chromiumRevisions',type:tr.v.d.GenericSet},GPUS:{name:'gpus',type:tr.v.d.GenericSet},GROUPING_PATH:{name:'groupingPath',type:tr.v.d.GroupingPath},LABELS:{name:'labels',type:tr.v.d.GenericSet},LOG_URLS:{name:'logUrls',type:tr.v.d.GenericSet},MASTERS:{name:'masters',type:tr.v.d.GenericSet},MEMORY_AMOUNTS:{name:'memoryAmounts',type:tr.v.d.GenericSet},MERGED_FROM:{name:'mergedFrom',type:tr.v.d.RelatedHistogramMap},MERGED_TO:{name:'mergedTo',type:tr.v.d.RelatedHistogramMap},OS_NAMES:{name:'osNames',type:tr.v.d.GenericSet},OS_VERSIONS:{name:'osVersions',type:tr.v.d.GenericSet},OWNERS:{name:'owners',type:tr.v.d.GenericSet},PRODUCT_VERSIONS:{name:'productVersions',type:tr.v.d.GenericSet},RELATED_NAMES:{name:'relatedNames',type:tr.v.d.GenericSet},SKIA_REVISIONS:{name:'skiaRevisions',type:tr.v.d.GenericSet},STORIES:{name:'stories',type:tr.v.d.GenericSet},STORYSET_REPEATS:{name:'storysetRepeats',type:tr.v.d.GenericSet},STORY_TAGS:{name:'storyTags',type:tr.v.d.GenericSet},TAG_MAP:{name:'tagmap',type:tr.v.d.TagMap},TRACE_START:{name:'traceStart',type:tr.v.d.DateRange},TRACE_URLS:{name:'traceUrls',type:tr.v.d.GenericSet},V8_COMMIT_POSITIONS:{name:'v8CommitPositions',type:tr.v.d.DateRange},V8_REVISIONS:{name:'v8Revisions',type:tr.v.d.GenericSet},WEBRTC_REVISIONS:{name:'webrtcRevisions',type:tr.v.d.GenericSet},};const RESERVED_NAMES={};const RESERVED_NAMES_TO_TYPES=new Map();for(const[codename,info]of Object.entries(RESERVED_INFOS)){RESERVED_NAMES[codename]=info.name;if(RESERVED_NAMES_TO_TYPES.has(info.name)){throw new Error(`Duplicate reserved name "${info.name}"`);}
+RESERVED_NAMES_TO_TYPES.set(info.name,info.type);}
+const RESERVED_NAMES_SET=new Set(Object.values(RESERVED_NAMES));return{RESERVED_INFOS,RESERVED_NAMES,RESERVED_NAMES_SET,RESERVED_NAMES_TO_TYPES,};});'use strict';tr.exportTo('tr.v.d',function(){class DiagnosticMap extends Map{constructor(opt_allowReservedNames){super();if(opt_allowReservedNames===undefined){opt_allowReservedNames=true;}
+this.allowReservedNames_=opt_allowReservedNames;}
+set(name,diagnostic){if(typeof(name)!=='string'){throw new Error(`name must be string, not ${name}`);}
+if(!(diagnostic instanceof tr.v.d.Diagnostic)&&!(diagnostic instanceof tr.v.d.DiagnosticRef)){throw new Error(`Must be instanceof Diagnostic: ${diagnostic}`);}
+if(!this.allowReservedNames_&&tr.v.d.RESERVED_NAMES_SET.has(name)&&!(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)&&!(diagnostic instanceof tr.v.d.DiagnosticRef)){const type=tr.v.d.RESERVED_NAMES_TO_TYPES.get(name);if(type&&!(diagnostic instanceof type)){throw new Error(`Diagnostics named "${name}" must be ${type.name}, `+`not ${diagnostic.constructor.name}`);}}
+Map.prototype.set.call(this,name,diagnostic);}
+delete(name){if(name===undefined)throw new Error('missing name');Map.prototype.delete.call(this,name);}
+addDicts(dict){for(const[name,diagnosticDict]of Object.entries(dict)){if(typeof diagnosticDict==='string'){this.set(name,new tr.v.d.DiagnosticRef(diagnosticDict));}else{this.set(name,tr.v.d.Diagnostic.fromDict(diagnosticDict));}}}
+resolveSharedDiagnostics(histograms,opt_required){for(const[name,value]of this){if(!(value instanceof tr.v.d.DiagnosticRef)){continue;}
+const guid=value.guid;const diagnostic=histograms.lookupDiagnostic(guid);if(diagnostic instanceof tr.v.d.Diagnostic){this.set(name,diagnostic);}else if(opt_required){throw new Error('Unable to find shared Diagnostic '+guid);}}}
+asDict(){const dict={};for(const[name,diagnostic]of this){dict[name]=diagnostic.asDictOrReference();}
+return dict;}
+static fromDict(d){const diagnostics=new DiagnosticMap();diagnostics.addDicts(d);return diagnostics;}
+static fromObject(obj){const diagnostics=new DiagnosticMap();for(const[name,diagnostic]of Object.entries(obj)){diagnostics.set(name,diagnostic);}
+return diagnostics;}
+addDiagnostics(other){for(const[name,otherDiagnostic]of other){if(name===tr.v.d.RESERVED_NAMES.MERGED_FROM||name===tr.v.d.RESERVED_NAMES.MERGED_TO||name===tr.v.d.RESERVED_NAMES.GROUPING_PATH){continue;}
+const myDiagnostic=this.get(name);if(myDiagnostic!==undefined&&myDiagnostic.canAddDiagnostic(otherDiagnostic)){myDiagnostic.addDiagnostic(otherDiagnostic);continue;}
+const clone=otherDiagnostic.clone();if(myDiagnostic===undefined){this.set(name,clone);continue;}
+this.set(name,new tr.v.d.UnmergeableDiagnosticSet([myDiagnostic,clone]));}}
+mergeRelationships(parentHist){for(const[name,diagnostic]of this){if(!(diagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(diagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
+for(const[unusedName,otherHist]of
+this.get(tr.v.d.RESERVED_NAMES.MERGED_FROM)){const otherDiagnostic=otherHist.diagnostics.get(name);if(!(otherDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(otherDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(otherDiagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
+diagnostic.mergeRelationships(otherDiagnostic,parentHist,otherHist);}}}}
+return{DiagnosticMap,};});'use strict';tr.exportTo('tr.v',function(){const MAX_DIAGNOSTIC_MAPS=16;const DEFAULT_SAMPLE_VALUES_PER_BIN=10;const DEFAULT_REBINNED_COUNT=40;const DEFAULT_BOUNDARIES_FOR_UNIT=new Map();const DELTA=String.fromCharCode(916);const Z_SCORE_NAME='z-score';const P_VALUE_NAME='p-value';const U_STATISTIC_NAME='U';function percentToString(percent,opt_force3){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
+if(percent===0)return'000';if(percent===1)return'100';let str=percent.toString();if(str[1]!=='.'){throw new Error('Unexpected percent');}
+str=str+'0'.repeat(Math.max(4-str.length,0));if(str.length>4){if(opt_force3){str=str.slice(0,4);}else{str=str.slice(0,4)+'_'+str.slice(4);}}
+return'0'+str.slice(2);}
+function percentFromString(s){return parseFloat(s[0]+'.'+s.substr(1).replace(/_/g,''));}
+class HistogramBin{constructor(range){this.range=range;this.count=0;this.diagnosticMaps=[];}
+addSample(value){this.count+=1;}
+addDiagnosticMap(diagnostics){tr.b.math.Statistics.uniformlySampleStream(this.diagnosticMaps,this.count,diagnostics,MAX_DIAGNOSTIC_MAPS);}
+addBin(other){if(!this.range.equals(other.range)){throw new Error('Merging incompatible Histogram bins.');}
+tr.b.math.Statistics.mergeSampledStreams(this.diagnosticMaps,this.count,other.diagnosticMaps,other.count,MAX_DIAGNOSTIC_MAPS);this.count+=other.count;}
+fromDict(dict){this.count=dict[0];if(dict.length>1){for(const map of dict[1]){this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}}
+asDict(){if(!this.diagnosticMaps.length){return[this.count];}
+return[this.count,this.diagnosticMaps.map(d=>d.asDict())];}}
+const DEFAULT_SUMMARY_OPTIONS=new Map([['avg',true],['count',true],['geometricMean',false],['max',true],['min',true],['nans',false],['std',true],['sum',true],]);class Histogram{constructor(name,unit,opt_binBoundaries){let binBoundaries=opt_binBoundaries;if(!binBoundaries){const baseUnit=unit.baseUnit?unit.baseUnit:unit;binBoundaries=DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName);}
+this.guid_=undefined;this.binBoundariesDict_=binBoundaries.asDict();this.allBins=binBoundaries.bins.slice();this.description='';const allowReservedNames=false;this.diagnostics_=new tr.v.d.DiagnosticMap(allowReservedNames);this.maxNumSampleValues_=this.defaultMaxNumSampleValues_;this.name_=name;this.nanDiagnosticMaps=[];this.numNans=0;this.running_=undefined;this.sampleValues_=[];this.shortName=undefined;this.summaryOptions=new Map(DEFAULT_SUMMARY_OPTIONS);this.summaryOptions.set('percentile',[]);this.summaryOptions.set('iprs',[]);this.unit=unit;}
+static create(name,unit,samples,opt_options){const options=opt_options||{};const hist=new Histogram(name,unit,options.binBoundaries);if(options.description)hist.description=options.description;if(options.shortName)hist.shortName=options.shortName;if(options.summaryOptions){let summaryOptions=options.summaryOptions;if(!(summaryOptions instanceof Map)){summaryOptions=Object.entries(summaryOptions);}
+for(const[name,value]of summaryOptions){hist.summaryOptions.set(name,value);}}
+if(options.diagnostics!==undefined){let diagnostics=options.diagnostics;if(!(diagnostics instanceof Map)){diagnostics=Object.entries(diagnostics);}
+for(const[name,diagnostic]of diagnostics){hist.diagnostics.set(name,diagnostic);}}
+if(!(samples instanceof Array))samples=[samples];for(const sample of samples){if(typeof sample==='object'){hist.addSample(sample.value,sample.diagnostics);}else{hist.addSample(sample);}}
+return hist;}
+get diagnostics(){return this.diagnostics_;}
+get running(){return this.running_;}
+get maxNumSampleValues(){return this.maxNumSampleValues_;}
+set maxNumSampleValues(n){this.maxNumSampleValues_=n;tr.b.math.Statistics.uniformlySampleArray(this.sampleValues_,this.maxNumSampleValues_);}
+get name(){return this.name_;}
+get guid(){if(this.guid_===undefined){this.guid_=tr.b.GUID.allocateUUID4();}
+return this.guid_;}
+set guid(guid){if(this.guid_!==undefined){throw new Error('Cannot reset guid');}
+this.guid_=guid;}
+static fromDict(dict){const hist=new Histogram(dict.name,tr.b.Unit.fromJSON(dict.unit),HistogramBinBoundaries.fromDict(dict.binBoundaries));hist.guid=dict.guid;if(dict.shortName){hist.shortName=dict.shortName;}
+if(dict.description){hist.description=dict.description;}
+if(dict.diagnostics){hist.diagnostics.addDicts(dict.diagnostics);}
+if(dict.allBins){if(dict.allBins.length!==undefined){for(let i=0;i<dict.allBins.length;++i){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(dict.allBins[i]);}}else{for(const[i,binDict]of Object.entries(dict.allBins)){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(binDict);}}}
+if(dict.running){hist.running_=tr.b.math.RunningStatistics.fromDict(dict.running);}
+if(dict.summaryOptions){if(dict.summaryOptions.iprs){dict.summaryOptions.iprs=dict.summaryOptions.iprs.map(r=>tr.b.math.Range.fromExplicitRange(r[0],r[1]));}
+hist.customizeSummaryOptions(dict.summaryOptions);}
+if(dict.maxNumSampleValues!==undefined){hist.maxNumSampleValues=dict.maxNumSampleValues;}
+if(dict.sampleValues){hist.sampleValues_=dict.sampleValues;}
+if(dict.numNans){hist.numNans=dict.numNans;}
+if(dict.nanDiagnostics){for(const map of dict.nanDiagnostics){hist.nanDiagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}
+return hist;}
+get numValues(){return this.running_?this.running_.count:0;}
+get average(){return this.running_?this.running_.mean:undefined;}
+get standardDeviation(){return this.running_?this.running_.stddev:undefined;}
+get geometricMean(){return this.running_?this.running_.geometricMean:0;}
+get sum(){return this.running_?this.running_.sum:0;}
+get min(){return this.running_?this.running_.min:Infinity;}
+get max(){return this.running_?this.running_.max:-Infinity;}
+getDifferenceSignificance(other,opt_alpha){if(this.unit!==other.unit){throw new Error('Cannot compare Histograms with different units');}
+if(this.unit.improvementDirection===tr.b.ImprovementDirection.DONT_CARE){return tr.b.math.Statistics.Significance.DONT_CARE;}
+if(!(other instanceof Histogram)){throw new Error('Unable to compute a p-value');}
+const testResult=tr.b.math.Statistics.mwu(this.sampleValues,other.sampleValues,opt_alpha);return testResult.significance;}
+getApproximatePercentile(percent){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
+if(this.numValues===0)return undefined;if(this.allBins.length===1){const sortedSampleValues=this.sampleValues.slice().sort((x,y)=>x-y);return sortedSampleValues[Math.floor((sortedSampleValues.length-1)*percent)];}
+let valuesToSkip=Math.floor((this.numValues-1)*percent);for(const bin of this.allBins){valuesToSkip-=bin.count;if(valuesToSkip>=0)continue;if(bin.range.min===-Number.MAX_VALUE){return bin.range.max;}
+if(bin.range.max===Number.MAX_VALUE){return bin.range.min;}
+return bin.range.center;}
+return this.allBins[this.allBins.length-1].range.min;}
+getBinIndexForValue(value){const i=tr.b.findHighIndexInSortedArray(this.allBins,b=>((value<b.range.max)?-1:1));if(0<=i&&i<this.allBins.length)return i;return this.allBins.length-1;}
+getBinForValue(value){return this.allBins[this.getBinIndexForValue(value)];}
+addSample(value,opt_diagnostics){if(opt_diagnostics&&!(opt_diagnostics instanceof tr.v.d.DiagnosticMap)){opt_diagnostics=tr.v.d.DiagnosticMap.fromObject(opt_diagnostics);}
+if(typeof(value)!=='number'||isNaN(value)){this.numNans++;if(opt_diagnostics){tr.b.math.Statistics.uniformlySampleStream(this.nanDiagnosticMaps,this.numNans,opt_diagnostics,MAX_DIAGNOSTIC_MAPS);}}else{if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+this.running_.add(value);const binIndex=this.getBinIndexForValue(value);let bin=this.allBins[binIndex];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[binIndex]=bin;}
+bin.addSample(value);if(opt_diagnostics){bin.addDiagnosticMap(opt_diagnostics);}}
+tr.b.math.Statistics.uniformlySampleStream(this.sampleValues_,this.numValues+this.numNans,value,this.maxNumSampleValues);}
+sampleValuesInto(samples){for(const sampleValue of this.sampleValues){samples.push(sampleValue);}}
+canAddHistogram(other){if(this.unit!==other.unit){return false;}
+if(this.binBoundariesDict_===other.binBoundariesDict_){return true;}
+if(this.binBoundariesDict_.length!==other.binBoundariesDict_.length){return false;}
+for(let i=0;i<this.binBoundariesDict_.length;++i){const slice=this.binBoundariesDict_[i];const otherSlice=other.binBoundariesDict_[i];if(slice instanceof Array){if(!(otherSlice instanceof Array)){return false;}
+if(slice[0]!==otherSlice[0]||!tr.b.math.approximately(slice[1],otherSlice[1])||slice[2]!==otherSlice[2]){return false;}}else{if(otherSlice instanceof Array){return false;}
+if(!tr.b.math.approximately(slice,otherSlice)){return false;}}}
+return true;}
+addHistogram(other){if(!this.canAddHistogram(other)){throw new Error('Merging incompatible Histograms');}
+tr.b.math.Statistics.mergeSampledStreams(this.nanDiagnosticMaps,this.numNans,other.nanDiagnosticMaps,other.numNans,MAX_DIAGNOSTIC_MAPS);tr.b.math.Statistics.mergeSampledStreams(this.sampleValues,this.numValues+this.numNans,other.sampleValues,other.numValues+other.numNans,(this.maxNumSampleValues+other.maxNumSampleValues)/2);this.numNans+=other.numNans;if(other.running_!==undefined){if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+this.running_=this.running_.merge(other.running_);}
+for(let i=0;i<this.allBins.length;++i){let bin=this.allBins[i];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[i]=bin;}
+bin.addBin(other.allBins[i]);}
+let mergedFrom=this.diagnostics.get(tr.v.d.RESERVED_NAMES.MERGED_FROM);if(!mergedFrom){mergedFrom=new tr.v.d.RelatedHistogramMap();this.diagnostics.set(tr.v.d.RESERVED_NAMES.MERGED_FROM,mergedFrom);}
+mergedFrom.set(mergedFrom.length,other);let mergedTo=other.diagnostics.get(tr.v.d.RESERVED_NAMES.MERGED_TO);if(!mergedTo){mergedTo=new tr.v.d.RelatedHistogramMap();other.diagnostics.set(tr.v.d.RESERVED_NAMES.MERGED_TO,mergedTo);}
+mergedTo.set(mergedTo.length,this);this.diagnostics.addDiagnostics(other.diagnostics);for(const[stat,option]of other.summaryOptions){if(stat==='percentile'){const percentiles=this.summaryOptions.get(stat);for(const percent of option){if(!percentiles.includes(percent))percentiles.push(percent);}}else if(stat==='iprs'){const thisIprs=this.summaryOptions.get(stat);for(const ipr of option){let found=false;for(const thisIpr of thisIprs){found=ipr.equals(thisIpr);if(found)break;}
+if(!found)thisIprs.push(ipr);}}else if(option&&!this.summaryOptions.get(stat)){this.summaryOptions.set(stat,true);}}}
+customizeSummaryOptions(summaryOptions){for(const[key,value]of Object.entries(summaryOptions)){this.summaryOptions.set(key,value);}}
+getStatisticScalar(statName,opt_referenceHistogram,opt_mwu){if(statName==='avg'){if(this.running_===undefined)return undefined;return new tr.b.Scalar(this.unit,this.average);}
+if(statName==='std'){if(this.standardDeviation===undefined)return undefined;return new tr.b.Scalar(this.unit,this.standardDeviation);}
+if(statName==='geometricMean'){return new tr.b.Scalar(this.unit,this.geometricMean);}
+if(statName==='min'||statName==='max'||statName==='sum'){if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+return new tr.b.Scalar(this.unit,this.running_[statName]);}
+if(statName==='nans'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numNans);}
+if(statName==='count'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numValues);}
+if(statName.substr(0,4)==='pct_'){const percent=percentFromString(statName.substr(4));if(this.numValues===0)return undefined;const percentile=this.getApproximatePercentile(percent);return new tr.b.Scalar(this.unit,percentile);}
+if(statName.substr(0,4)==='ipr_'){let lower=percentFromString(statName.substr(4,3));let upper=percentFromString(statName.substr(8));if(lower>=upper){throw new Error('Invalid inter-percentile range: '+statName);}
+lower=this.getApproximatePercentile(lower);upper=this.getApproximatePercentile(upper);return new tr.b.Scalar(this.unit,upper-lower);}
+if(!this.canCompare(opt_referenceHistogram)){throw new Error('Cannot compute '+statName+' when histograms are not comparable');}
+const suffix=tr.b.Unit.nameSuffixForImprovementDirection(this.unit.improvementDirection);const deltaIndex=statName.indexOf(DELTA);if(deltaIndex>=0){const baseStatName=statName.substr(deltaIndex+1);const thisStat=this.getStatisticScalar(baseStatName);const otherStat=opt_referenceHistogram.getStatisticScalar(baseStatName);const deltaValue=thisStat.value-otherStat.value;if(statName[0]==='%'){return new tr.b.Scalar(tr.b.Unit.byName['normalizedPercentageDelta'+suffix],deltaValue/otherStat.value);}
+return new tr.b.Scalar(thisStat.unit.correspondingDeltaUnit,deltaValue);}
+if(statName===Z_SCORE_NAME){return new tr.b.Scalar(tr.b.Unit.byName['sigmaDelta'+suffix],(this.average-opt_referenceHistogram.average)/opt_referenceHistogram.standardDeviation);}
+const mwu=opt_mwu||tr.b.math.Statistics.mwu(this.sampleValues,opt_referenceHistogram.sampleValues);if(statName===P_VALUE_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.p);}
+if(statName===U_STATISTIC_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.U);}
+throw new Error('Unrecognized statistic name: '+statName);}
+get statisticsNames(){const statisticsNames=new Set();for(const[statName,option]of this.summaryOptions){if(statName==='percentile'){for(const pctile of option){statisticsNames.add('pct_'+tr.v.percentToString(pctile));}}else if(statName==='iprs'){for(const range of option){statisticsNames.add('ipr_'+tr.v.percentToString(range.min,true)+'_'+tr.v.percentToString(range.max,true));}}else if(option){statisticsNames.add(statName);}}
+return statisticsNames;}
+canCompare(other){return other instanceof Histogram&&this.unit===other.unit&&this.numValues>0&&other.numValues>0;}
+getAvailableStatisticName(statName,opt_referenceHist){if(this.canCompare(opt_referenceHist))return statName;if(statName===Z_SCORE_NAME||statName===P_VALUE_NAME||statName===U_STATISTIC_NAME){return'avg';}
+const deltaIndex=statName.indexOf(DELTA);if(deltaIndex<0)return statName;return statName.substr(deltaIndex+1);}
+static getDeltaStatisticsNames(statNames){const deltaNames=[];for(const statName of statNames){deltaNames.push(`${DELTA}${statName}`);deltaNames.push(`%${DELTA}${statName}`);}
+return deltaNames.concat([Z_SCORE_NAME,P_VALUE_NAME,U_STATISTIC_NAME]);}
+get statisticsScalars(){const results=new Map();for(const statName of this.statisticsNames){const scalar=this.getStatisticScalar(statName);if(scalar===undefined)continue;results.set(statName,scalar);}
+return results;}
+get sampleValues(){return this.sampleValues_;}
+clone(){const binBoundaries=HistogramBinBoundaries.fromDict(this.binBoundariesDict_);const hist=new Histogram(this.name,this.unit,binBoundaries);for(const[stat,option]of this.summaryOptions){if(stat==='percentile'||stat==='iprs'){hist.summaryOptions.set(stat,Array.from(option));}else{hist.summaryOptions.set(stat,option);}}
+hist.addHistogram(this);return hist;}
+rebin(newBoundaries){const rebinned=new tr.v.Histogram(this.name,this.unit,newBoundaries);rebinned.description=this.description;for(const sample of this.sampleValues){rebinned.addSample(sample);}
+rebinned.running_=this.running_;for(const[name,diagnostic]of this.diagnostics){rebinned.diagnostics.set(name,diagnostic);}
+for(const[stat,option]of this.summaryOptions){if(stat==='percentile'){rebinned.summaryOptions.set(stat,Array.from(option));}else{rebinned.summaryOptions.set(stat,option);}}
+return rebinned;}
+asDict(){const dict={};dict.name=this.name;dict.unit=this.unit.asJSON();dict.guid=this.guid;if(this.binBoundariesDict_!==undefined){dict.binBoundaries=this.binBoundariesDict_;}
+if(this.shortName){dict.shortName=this.shortName;}
+if(this.description){dict.description=this.description;}
+if(this.diagnostics.size){dict.diagnostics=this.diagnostics.asDict();}
+if(this.maxNumSampleValues!==this.defaultMaxNumSampleValues_){dict.maxNumSampleValues=this.maxNumSampleValues;}
+if(this.numNans){dict.numNans=this.numNans;}
+if(this.nanDiagnosticMaps.length){dict.nanDiagnostics=this.nanDiagnosticMaps.map(dm=>dm.asDict());}
+if(this.numValues){dict.sampleValues=this.sampleValues.slice();dict.running=this.running_.asDict();dict.allBins=this.allBinsAsDict_();}
+const summaryOptions={};let anyOverriddenSummaryOptions=false;for(const[name,value]of this.summaryOptions){let option;if(name==='percentile'){if(value.length===0)continue;option=Array.from(value);}else if(name==='iprs'){if(value.length===0)continue;option=value.map(r=>[r.min,r.max]);}else if(value===DEFAULT_SUMMARY_OPTIONS.get(name)){continue;}else{option=value;}
+summaryOptions[name]=option;anyOverriddenSummaryOptions=true;}
+if(anyOverriddenSummaryOptions){dict.summaryOptions=summaryOptions;}
+return dict;}
+allBinsAsDict_(){const numBins=this.allBins.length;let emptyBins=0;for(let i=0;i<numBins;++i){if(this.allBins[i].count===0){++emptyBins;}}
+if(emptyBins===numBins){return undefined;}
+if(emptyBins>(numBins/2)){const allBinsDict={};for(let i=0;i<numBins;++i){const bin=this.allBins[i];if(bin.count>0){allBinsDict[i]=bin.asDict();}}
+return allBinsDict;}
+const allBinsArray=[];for(let i=0;i<numBins;++i){allBinsArray.push(this.allBins[i].asDict());}
+return allBinsArray;}
+get defaultMaxNumSampleValues_(){return DEFAULT_SAMPLE_VALUES_PER_BIN*Math.max(this.allBins.length,DEFAULT_REBINNED_COUNT);}}
+Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS={count:false,max:false,min:false,std:false,sum:false,};const HISTOGRAM_BIN_BOUNDARIES_CACHE=new Map();class HistogramBinBoundaries{static createLinear(min,max,numBins){return new HistogramBinBoundaries(min).addLinearBins(max,numBins);}
+static createExponential(min,max,numBins){return new HistogramBinBoundaries(min).addExponentialBins(max,numBins);}
+static createWithBoundaries(binBoundaries){const builder=new HistogramBinBoundaries(binBoundaries[0]);for(const boundary of binBoundaries.slice(1)){builder.addBinBoundary(boundary);}
+return builder;}
+constructor(minBinBoundary){this.builder_=[minBinBoundary];this.range_=new tr.b.math.Range();this.range_.addValue(minBinBoundary);this.binRanges_=undefined;this.bins_=undefined;}
+get range(){return this.range_;}
+asDict(){if(this.builder_.length===1&&this.builder_[0]===Number.MAX_VALUE){return undefined;}
+return this.builder_;}
+pushBuilderSlice_(slice){this.builder_.push(slice);this.builder_=this.builder_.slice();}
+static fromDict(dict){if(dict===undefined){return HistogramBinBoundaries.SINGULAR;}
+const cacheKey=JSON.stringify(dict);if(HISTOGRAM_BIN_BOUNDARIES_CACHE.has(cacheKey)){return HISTOGRAM_BIN_BOUNDARIES_CACHE.get(cacheKey);}
+const binBoundaries=new HistogramBinBoundaries(dict[0]);for(const slice of dict.slice(1)){if(!(slice instanceof Array)){binBoundaries.addBinBoundary(slice);continue;}
+switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:binBoundaries.addLinearBins(slice[1],slice[2]);break;case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:binBoundaries.addExponentialBins(slice[1],slice[2]);break;default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}}
+HISTOGRAM_BIN_BOUNDARIES_CACHE.set(cacheKey,binBoundaries);return binBoundaries;}
+get bins(){if(this.bins_===undefined){this.buildBins_();}
+return this.bins_;}
+buildBins_(){this.bins_=this.binRanges.map(r=>new HistogramBin(r));}
+get binRanges(){if(this.binRanges_===undefined){this.buildBinRanges_();}
+return this.binRanges_;}
+buildBinRanges_(){if(typeof this.builder_[0]!=='number'){throw new Error('Invalid start of builder_');}
+this.binRanges_=[];let prevBoundary=this.builder_[0];if(prevBoundary>-Number.MAX_VALUE){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(-Number.MAX_VALUE,prevBoundary));}
+for(const slice of this.builder_.slice(1)){if(!(slice instanceof Array)){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,slice));prevBoundary=slice;continue;}
+const nextMaxBinBoundary=slice[1];const binCount=slice[2];const sliceMinBinBoundary=prevBoundary;switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:{const binWidth=(nextMaxBinBoundary-prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary+i*binWidth;this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+break;}
+case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:{const binExponentWidth=Math.log(nextMaxBinBoundary/prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary*Math.exp(i*binExponentWidth);this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+break;}
+default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}
+this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,nextMaxBinBoundary));prevBoundary=nextMaxBinBoundary;}
+if(prevBoundary<Number.MAX_VALUE){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,Number.MAX_VALUE));}}
+addBinBoundary(nextMaxBinBoundary){if(nextMaxBinBoundary<=this.range.max){throw new Error('The added max bin boundary must be larger than '+'the current max boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_(nextMaxBinBoundary);this.range.addValue(nextMaxBinBoundary);return this;}
+addLinearBins(nextMaxBinBoundary,binCount){if(binCount<=0){throw new Error('Bin count must be positive');}
+if(nextMaxBinBoundary<=this.range.max){throw new Error('The new max bin boundary must be greater than '+'the previous max bin boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_([HistogramBinBoundaries.SLICE_TYPE.LINEAR,nextMaxBinBoundary,binCount]);this.range.addValue(nextMaxBinBoundary);return this;}
+addExponentialBins(nextMaxBinBoundary,binCount){if(binCount<=0){throw new Error('Bin count must be positive');}
+if(this.range.max<=0){throw new Error('Current max bin boundary must be positive');}
+if(this.range.max>=nextMaxBinBoundary){throw new Error('The last added max boundary must be greater than '+'the current max boundary boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_([HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL,nextMaxBinBoundary,binCount]);this.range.addValue(nextMaxBinBoundary);return this;}}
+HistogramBinBoundaries.SLICE_TYPE={LINEAR:0,EXPONENTIAL:1,};HistogramBinBoundaries.SINGULAR=new HistogramBinBoundaries(Number.MAX_VALUE);DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeDurationInMs.unitName,HistogramBinBoundaries.createExponential(1e-3,1e6,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeStampInMs.unitName,HistogramBinBoundaries.createLinear(0,1e10,1e3));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.normalizedPercentage.unitName,HistogramBinBoundaries.createLinear(0,1.0,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sizeInBytes.unitName,HistogramBinBoundaries.createExponential(1,1e12,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.energyInJoules.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.powerInWatts.unitName,HistogramBinBoundaries.createExponential(1e-3,1,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.unitlessNumber.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.count.unitName,HistogramBinBoundaries.createExponential(1,1e3,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sigma.unitName,HistogramBinBoundaries.createLinear(-5,5,50));return{DEFAULT_REBINNED_COUNT,DELTA,Histogram,HistogramBinBoundaries,P_VALUE_NAME,U_STATISTIC_NAME,Z_SCORE_NAME,percentFromString,percentToString,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-context-controller',created(){this.host_=undefined;this.groupToContext_=new Map();this.dirtyGroups_=new Set();},attached(){if(this.host_){throw new Error('Scalar context controller is already attached to a host');}
+const host=findParentOrHost(this);if(host.__scalarContextController){throw new Error('Multiple scalar context controllers attached to this host');}
+host.__scalarContextController=this;this.host_=host;},detached(){if(!this.host_){throw new Error('Scalar context controller is not attached to a host');}
+if(this.host_.__scalarContextController!==this){throw new Error('Scalar context controller is not attached to its host');}
+delete this.host_.__scalarContextController;this.host_=undefined;},getContext(group){return this.groupToContext_.get(group);},onScalarSpanAdded(group,span){let context=this.groupToContext_.get(group);if(context===undefined){context={spans:new Set(),range:new tr.b.math.Range()};this.groupToContext_.set(group,context);}
+if(context.spans.has(span)){throw new Error('Scalar span already registered with group: '+group);}
+context.spans.add(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanRemoved(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+context.spans.delete(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanUpdated(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+this.markGroupDirtyAndScheduleUpdate_(group);},markGroupDirtyAndScheduleUpdate_(group){const alreadyDirty=this.dirtyGroups_.size>0;this.dirtyGroups_.add(group);if(!alreadyDirty){tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContext,this);}},updateContext(){const groups=this.dirtyGroups_;if(groups.size===0)return;this.dirtyGroups_=new Set();for(const group of groups){this.updateGroup_(group);}
+const event=new tr.b.Event('context-updated');event.groups=groups;this.dispatchEvent(event);},updateGroup_(group){const context=this.groupToContext_.get(group);if(context.spans.size===0){this.groupToContext_.delete(group);return;}
+context.range.reset();for(const span of context.spans){context.range.addValue(span.value);}}});function getScalarContextControllerForElement(element){while(element){if(element.__scalarContextController){return element.__scalarContextController;}
+element=findParentOrHost(element);}
+return undefined;}
+function findParentOrHost(node){if(node.parentElement){return node.parentElement;}
+while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
+return node.host;}
+return{getScalarContextControllerForElement,};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)return'';const config=opt_config||{};const ownerDocument=config.ownerDocument||document;const span=ownerDocument.createElement('tr-v-ui-scalar-span');let numericValue;if(value instanceof tr.b.Scalar){span.value=value;numericValue=value.value;}else if(value instanceof tr.v.Histogram){numericValue=value.average;if(numericValue===undefined)return'';span.setValueAndUnit(numericValue,value.unit);}else{const unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
+span.setValueAndUnit(value,unit);numericValue=value;}
+if(config.context){span.context=config.context;}
+if(config.customContextRange){span.customContextRange=config.customContextRange;}
+if(config.leftAlign){span.leftAlign=true;}
+if(config.inline){span.inline=true;}
+if(config.significance!==undefined){span.significance=config.significance;}
+if(config.contextGroup!==undefined){span.contextGroup=config.contextGroup;}
+return span;}
+return{createScalarSpan,};});'use strict';Polymer({is:'tr-v-ui-scalar-span',properties:{contextGroup:{type:String,reflectToAttribute:true,observer:'contextGroupChanged_'}},created(){this.value_=undefined;this.unit_=undefined;this.context_=undefined;this.warning_=undefined;this.significance_=tr.b.math.Statistics.Significance.DONT_CARE;this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;this.onContextUpdated_=this.onContextUpdated_.bind(this);this.updateContents_=this.updateContents_.bind(this);this.customContextRange_=undefined;},get significance(){return this.significance_;},set significance(s){this.significance_=s;this.updateContents_();},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+this.updateContents_();if(this.hasContext_(this.contextGroup)){this.contextController_.onScalarSpanUpdated(this.contextGroup,this);}else{this.updateSparkline_();}},get contextController_(){if(this.shouldSearchForContextController_){this.lazyContextController_=tr.v.ui.getScalarContextControllerForElement(this);this.shouldSearchForContextController_=false;}
+return this.lazyContextController_;},hasContext_(contextGroup){return!!(contextGroup&&this.contextController_);},contextGroupChanged_(newContextGroup,oldContextGroup){this.detachFromContextControllerIfPossible_(oldContextGroup);if(!this.attachToContextControllerIfPossible_(newContextGroup)){this.onContextUpdated_();}},attachToContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return false;this.contextController_.addEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanAdded(contextGroup,this);return true;},detachFromContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return;this.contextController_.removeEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanRemoved(contextGroup,this);},attached(){tr.b.Unit.addEventListener('display-mode-changed',this.updateContents_);this.shouldSearchForContextController_=true;this.attachToContextControllerIfPossible_(this.contextGroup);},detached(){tr.b.Unit.removeEventListener('display-mode-changed',this.updateContents_);this.detachFromContextControllerIfPossible_(this.contextGroup);this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;},onContextUpdated_(){this.updateSparkline_();},get context(){return this.context_;},set context(context){this.context_=context;this.updateContents_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();this.updateSparkline_();},setValueAndUnit(value,unit){this.value_=value;this.unit_=unit;this.updateContents_();},get customContextRange(){return this.customContextRange_;},set customContextRange(customContextRange){this.customContextRange_=customContextRange;this.updateSparkline_();},get inline(){return Polymer.dom(this).classList.contains('inline');},set inline(inline){if(inline){Polymer.dom(this).classList.add('inline');}else{Polymer.dom(this).classList.remove('inline');}},get leftAlign(){return Polymer.dom(this).classList.contains('left-align');},set leftAlign(leftAlign){if(leftAlign){Polymer.dom(this).classList.add('left-align');}else{Polymer.dom(this).classList.remove('left-align');}},updateSparkline_(){Polymer.dom(this.$.sparkline).classList.remove('positive');Polymer.dom(this.$.sparkline).classList.remove('better');Polymer.dom(this.$.sparkline).classList.remove('worse');Polymer.dom(this.$.sparkline).classList.remove('same');this.$.sparkline.style.display='none';this.$.sparkline.style.left='0';this.$.sparkline.style.width='0';let range=this.customContextRange_;if(!range&&this.hasContext_(this.contextGroup)){const context=this.contextController_.getContext(this.contextGroup);if(context){range=context.range;}}
+if(!range||range.isEmpty)return;const leftPoint=Math.min(range.min,0);const rightPoint=Math.max(range.max,0);const pointDistance=rightPoint-leftPoint;if(pointDistance===0){return;}
+this.$.sparkline.style.display='block';let left;let width;if(this.value>0){width=Math.min(this.value,rightPoint);left=-leftPoint;Polymer.dom(this.$.sparkline).classList.add('positive');}else if(this.value<=0){width=-Math.max(this.value,leftPoint);left=(-leftPoint)-width;}
+this.$.sparkline.style.left=this.buildSparklineStyle_(left/pointDistance,false);this.$.sparkline.style.width=this.buildSparklineStyle_(width/pointDistance,true);const changeClass=this.changeClassName_;if(changeClass){Polymer.dom(this.$.sparkline).classList.add(changeClass);}},buildSparklineStyle_(ratio,isWidth){let position='calc('+ratio+' * (100% - 1px)';if(isWidth){position+=' + 1px';}
+position+=')';return position;},updateContents_(){Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).classList.remove('better');Polymer.dom(this.$.content).classList.remove('worse');Polymer.dom(this.$.content).classList.remove('same');this.$.insignificant.style.display='';this.$.significantly_better.style.display='';this.$.significantly_worse.style.display='';if(this.unit_===undefined)return;this.$.content.title='';Polymer.dom(this.$.content).textContent=this.unit_.format(this.value,this.context);this.updateDelta_();},updateDelta_(){let changeClass=this.changeClassName_;if(!changeClass){this.$.significance.style.display='none';return;}
+this.$.significance.style.display='inline';let title;switch(changeClass){case'better':title='improvement';break;case'worse':title='regression';break;case'same':title='no change';break;default:throw new Error('Unknown change class: '+changeClass);}
+Polymer.dom(this.$.content).classList.add(changeClass);switch(this.significance){case tr.b.math.Statistics.Significance.DONT_CARE:break;case tr.b.math.Statistics.Significance.INSIGNIFICANT:if(changeClass!=='same')title='insignificant '+title;this.$.insignificant.style.display='inline';changeClass='same';break;case tr.b.math.Statistics.Significance.SIGNIFICANT:if(changeClass==='same'){throw new Error('How can no change be significant?');}
+this.$['significantly_'+changeClass].style.display='inline';title='significant '+title;break;default:throw new Error('Unknown significance '+this.significance);}
+this.$.significance.title=title;this.$.content.title=title;},get changeClassName_(){if(!this.unit_||!this.unit_.isDelta)return undefined;switch(this.unit_.improvementDirection){case tr.b.ImprovementDirection.DONT_CARE:return undefined;case tr.b.ImprovementDirection.BIGGER_IS_BETTER:if(this.value===0)return'same';return this.value>0?'better':'worse';case tr.b.ImprovementDirection.SMALLER_IS_BETTER:if(this.value===0)return'same';return this.value<0?'better':'worse';default:throw new Error('Unknown improvement direction: '+
+this.unit_.improvementDirection);}},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;const warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='inline';}else{warningEl.title='';warningEl.style.display='';}},get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
+this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);},get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
+this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(const colName in object[0]){if(typeof colName!=='string')return false;}
+for(let i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(const colName in object[i]){if(i&&(object[0][colName]===undefined))return false;const cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!=='number')return false;}
+if(i){for(const colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+return true;}
+Polymer({is:'tr-ui-a-generic-object-view',ready(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_(){Polymer.dom(this.$.content).textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
+if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
+if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
+if(!(object instanceof Object)){const type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,object,suffix);}
+let objectReplaced=false;if((object[0]==='{'&&object[object.length-1]==='}')||(object[0]==='['&&object[object.length-1]===']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
+if(!objectReplaced){if(object.includes('\n')){const lines=object.split('\n');lines.forEach(function(line,i){let text;let ioff;let ll;let ss;if(i===0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
+const el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}
+if(tr.b.isUrl(object)){const link=document.createElement('a');link.href=object;link.textContent=object;this.appendElementWithLabel_(label,indent,link,suffix);return;}
+this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
+if(object instanceof tr.model.ObjectSnapshot){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectInstance){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.b.math.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
+if(object instanceof tr.b.Scalar){const el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;el.inline=true;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
+this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_(label,object,indent,depth,maxDepth,suffix){if(object.length===0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
+if(isTable(object)){const table=document.createElement('tr-ui-b-table');const columns=[];for(const colName of Object.keys(object[0])){let allStrings=true;let allNumbers=true;for(let i=0;i<object.length;++i){if(typeof(object[i][colName])!=='string'){allStrings=false;}
+if(typeof(object[i][colName])!=='number'){allNumbers=false;}
+if(!allStrings&&!allNumbers)break;}
+const column={title:colName};column.value=function(row){return row[colName];};if(allStrings){column.cmp=function(x,y){return x[colName].localeCompare(y[colName]);};}else if(allNumbers){column.cmp=function(x,y){return x[colName]-y[colName];};}
+columns.push(column);}
+table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
+this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(let i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
+return;},appendElementsForObject_(label,object,indent,depth,maxDepth,suffix){const keys=Object.keys(object);if(keys.length===0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
+this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(let i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_(label,indent,dataElement,suffix){const row=document.createElement('div');const indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(let i=0;i<indent;i++){Polymer.dom(indentSpan).textContent+=' ';}
+Polymer.dom(row).appendChild(indentSpan);const labelSpan=document.createElement('span');Polymer.dom(labelSpan).textContent=label;Polymer.dom(row).appendChild(labelSpan);Polymer.dom(row).appendChild(dataElement);const suffixSpan=document.createElement('span');Polymer.dom(suffixSpan).textContent=suffix;Polymer.dom(row).appendChild(suffixSpan);row.dataElement=dataElement;Polymer.dom(this.$.content).appendChild(row);},appendSimpleText_(label,indent,text,suffix){const el=this.ownerDocument.createElement('span');Polymer.dom(el).textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer({is:'tr-ui-a-generic-object-view-with-label',ready(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');Polymer.dom(this.root).appendChild(this.labelEl_);Polymer.dom(this.root).appendChild(this.genericObjectView_);},get label(){return Polymer.dom(this.labelEl_).textContent;},set label(label){Polymer.dom(this.labelEl_).textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView,};});'use strict';Polymer({is:'tr-ui-b-drag-handle',created(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className===''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_){this.className='horizontal-drag-handle';}else{this.className='vertical-drag-handle';}},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_(){const records=this.observer_.takeRecords();if(records.length){this.didTargetMutate_(records);}},didTargetMutate_(e){const modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
+this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_(){const targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
+const size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;tr.b.dispatchSimpleEvent(this,'drag-handle-resize',true,false);},applyDelta_(delta){const curSize=this.getTargetSize_();let newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
+this.setTargetSize_(newSize);},onMouseMove_(e){const curMousePos=this.horizontal_?e.clientY:e.clientX;const delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_(e){if(!this.target_)return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined){throw new Error('eventType must be given');}
+if(dict.keyCode===undefined&&dict.keyCodes===undefined){throw new Error('keyCode or keyCodes must be given');}
+if(dict.keyCode!==undefined&&dict.keyCodes!==undefined){throw new Error('Only keyCode or keyCodes can be given');}
+if(dict.callback===undefined){throw new Error('callback must be given');}
+this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode){this.pushKeyCode_(dict.keyCode);}else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
+this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey,};});'use strict';Polymer({is:'tv-ui-b-hotkey-controller',created(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached(){this.isAttached_=true;const host=this.findHost_();if(host.__hotkeyController){throw new Error('Multiple hotkey controllers attached to this host');}
+host.__hotkeyController=this;this.curHost_=host;let parentElement;if(host.parentElement){parentElement=host.parentElement;}else{parentElement=Polymer.dom(host).parentNode.host;}
+const parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached(){this.isAttached_=false;const host=this.curHost_;if(!host)return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
+host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i!==-1){throw new Error('Controller already registered');}
+this.childControllers_.push(controller);},removeChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i===-1){throw new Error('Controller not registered');}
+this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_(eventType,useCapture){if(eventType==='keydown'){if(!useCapture){return this.bubblingKeyDownHotKeys_;}
+return this.capturingKeyDownHotKeys_;}
+if(eventType==='keypress'){if(!useCapture){return this.bubblingKeyPressHotKeys_;}
+return this.capturingKeyPressHotKeys_;}
+throw new Error('Unsupported key event');},addHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(keyMap[keyCode]){throw new Error('Key is already bound for keyCode='+keyCode);}}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
+return hotKey;},removeHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode]){throw new Error('Key is not bound for keyCode='+keyCode);}
+keyMap[keyCode]=hotKey;}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){const wasAttached=this.isAttached_;if(wasAttached){this.detached();}
+this.globalMode_=!!globalMode;if(wasAttached){this.attached();}},get topmostConroller_(){if(this.slavedToParentController_){return this.slavedToParentController_.topmostConroller_;}
+return this;},childRequestsGeneralFocus(child){const topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement){document.activeElement.blur();}}}else{if(document.activeElement){document.activeElement.blur();}}},childRequestsBlur(child){child.blur();const topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_(){if(this.globalMode_)return document.body;if(this.parentElement)return this.parentElement;if(!Polymer.dom(this).parentNode)return this.host;let node=this.parentNode;while(Polymer.dom(node).parentNode)node=Polymer.dom(node).parentNode;return node.host;},appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e){const localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);const localHotKey=localKeyMap[e.keyCode];if(localHotKey){matchedHotKeys.push(localHotKey);}
+for(let i=0;i<this.childControllers_.length;i++){const controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_(useCapture,e){if(!useCapture&&e.path[0].tagName==='INPUT')return;let sortedControllers;const matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
+const hotKey=matchedHotKeys[0];let prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){let curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller'){return curElement;}
+if(curElement.__hotkeyController){return curElement.__hotkeyController;}
+if(curElement.parentElement){curElement=curElement.parentElement;continue;}
+curElement=findHost(curElement);}
+return undefined;}
+function findHost(initialNode){let node=initialNode;while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
+return node.host;}
+return{getHotkeyControllerForElement,};});'use strict';Polymer({is:'tr-ui-b-info-bar',ready(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';},get message(){return Polymer.dom(this.messageEl_).textContent;},set message(message){Polymer.dom(this.messageEl_).textContent=message;},get visible(){return!this.hidden;},set visible(visible){this.hidden=!visible;},removeAllButtons(){Polymer.dom(this.buttonsEl_).textContent='';},addButton(text,clickCallback){const button=document.createElement('button');Polymer.dom(button).textContent=text;button.addEventListener('click',event=>clickCallback(event,this));Polymer.dom(this.buttonsEl_).appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){const ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild(x){HTMLDivElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore(x,y){HTMLDivElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild(x){HTMLDivElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild(x,y){HTMLDivElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_(textContent){if(textContent!==''){throw new Error('textContent can only be set to \'\'.');}
+this.clear();},clear(){while(Polymer.dom(this).lastChild){HTMLDivElement.prototype.removeChild.call(this,Polymer.dom(this).lastChild);}
+this.didMutate_(this.observer_.takeRecords());},didMutate_(records){this.beginDecorating_();for(let i=0;i<records.length;i++){const addedNodes=records[i].addedNodes;if(addedNodes){for(let j=0;j<addedNodes.length;j++){this.decorateChild_(addedNodes[j]);}}
+const removedNodes=records[i].removedNodes;if(removedNodes){for(let j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_(child){throw new Error('Not implemented');},undecorateChild_(child){throw new Error('Not implemented');},beginDecorating_(){},doneDecoratingForNow_(){}};return{ContainerThatDecoratesItsChildren,};});'use strict';tr.exportTo('tr.ui.b',function(){const ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);Polymer.dom(this).classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_(item){Polymer.dom(item).classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);Object.defineProperty(item,'selected',{configurable:true,get:()=>item.hasAttribute('selected'),set:value=>{const oldSelection=this.selectedElement;if(oldSelection&&oldSelection!==item&&value){Polymer.dom(this.selectedElement).removeAttribute('selected');}
+if(value){Polymer.dom(item).setAttribute('selected','selected');}else{Polymer.dom(item).removeAttribute('selected');}
+const newSelection=this.selectedElement;if(newSelection!==oldSelection){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},});},undecorateChild_(item){this.selectionChanged_|=item.selected;Polymer.dom(item).classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_(){this.selectionChanged_=false;},doneDecoratingForNow_(){if(this.selectionChanged_){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},get selectedElement(){const el=Polymer.dom(this).querySelector('.list-item[selected]');if(!el)return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement){this.selectedElement.selected=false;}
+return;}
+if(el.parentElement!==this){throw new Error('Can only select elements that are children of this list view');}
+el.selected=true;},getElementByIndex(index){return Polymer.dom(this).querySelector('.list-item:nth-child('+index+')');},clear(){const changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},onItemClicked_(e){const currentSelectedElement=this.selectedElement;if(currentSelectedElement){Polymer.dom(currentSelectedElement).removeAttribute('selected');}
+let element=e.target;while(element.parentElement!==this){element=element.parentElement;}
+if(element!==currentSelectedElement){Polymer.dom(element).setAttribute('selected','selected');}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_(e){if(this.selectedElement===undefined)return;if(e.keyCode===38){const prev=Polymer.dom(this.selectedElement).previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode===40){const next=Polymer.dom(this.selectedElement).nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem(textContent){const item=document.createElement('div');Polymer.dom(item).textContent=textContent;Polymer.dom(this).appendChild(item);return item;}};return{ListView,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;const MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={name:'PANSCAN',mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={name:'SELECTION',mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={name:'ZOOM',mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={name:'TIMING',mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={name:'ROTATE',mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE,};});'use strict';Polymer({is:'tr-ui-b-mouse-mode-icon',properties:{modeName:{type:String,reflectToAttribute:true,observer:'modeNameChanged'},},created(){this.active_=false;this.acceleratorKey_=undefined;},ready(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(modeInfo===undefined){throw new Error('Unknown mode');}
+this.modeName=modeInfo.name;},modeNameChanged(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_){Polymer.dom(this).classList.add('active');}else{Polymer.dom(this).classList.remove('active');}
+this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_(){if(this.modeName===undefined)return;const mode=this.mode;if(mode===undefined){throw new Error('Invalid mode');}
+const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo){throw new Error('Invalid mode');}
+let title=modeInfo.title;if(this.acceleratorKey_){title=title+' ('+this.acceleratorKey_+')';}
+this.title=title;let bp;if(this.active_){bp=modeInfo.activeBackgroundPosition;}else{bp=modeInfo.defaultBackgroundPosition;}
+this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
+MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
+this.targetElement_=targetElement;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},onMouseDown_(e){if(e.button!==0)return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_(e,newType){const remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.removeEventListener('keyup',opt_keyUpHandler);}
+document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler){opt_mouseUpHandler(e);}}
+document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.addEventListener('keyup',opt_keyUpHandler);}
+document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
+return{MouseTracker,trackMouseMovesUntilMouseUp,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;const MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;const MIN_MOUSE_SELECTION_DISTANCE=4;const MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)return event.metaKey;return event.ctrlKey;}
+Polymer({is:'tr-ui-b-mouse-mode-selector',created(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready(){this.buttonsEl_=Polymer.dom(this.root).querySelector('.buttons');this.dragHandleEl_=Polymer.dom(this.root).querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
+this.targetElement_=target;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)return;let mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined){mode=undefined;}
+if((mode&this.supportedModeMask_)===0){mode=undefined;}
+if(!mode)mode=this.defaultMode_;this.mode=mode;const pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0){throw new Error('supportedModeMask must include current mode.');}
+function createButtonForMode(mode){return button;}
+this.supportedModeMask_=supportedModeMask;Polymer.dom(this.buttonsEl_).textContent='';for(const modeName in MOUSE_SELECTOR_MODE){if(modeName==='ALL_MODES')continue;const mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)continue;const button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;Polymer.dom(button).classList.add('tool-button');Polymer.dom(this.buttonsEl_).appendChild(button);}},getButtonForMode_(mode){for(let i=0;i<this.buttonsEl_.children.length;i++){const buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode){return buttonEl;}}
+return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number'){throw new Error('Mode must be a number');}
+if((newMode&this.supportedModeMask_)===0){throw new Error('Cannot switch to this mode, it is not supported');}
+if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined){throw new Error('Unrecognized mode');}}
+let modeInfo;if(this.currentMode_===newMode)return;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=false;if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
+modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
+this.currentMode_=newMode;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_){tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);}
+if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
+if(this.settingsKey_&&!this.isInAlternativeMode_){tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);}},setKeyCodeForMode(mode,keyCode){if((mode&this.supportedModeMask_)===0){throw new Error('Mode not supported');}
+this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)return;const buttonEl=this.getButtonForMode_(mode);if(buttonEl){buttonEl.acceleratorKey=String.fromCharCode(keyCode);}},setCurrentMousePosFromEvent_(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_(eventName,sourceEvent){const event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent){sourceEvent.preventDefault();}};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_(e){if(e.button!==0)return;this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION){mouseEvent.appendSelection=isCmdOrCtrlPressed(e);}
+this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_(e){this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_){this.checkIsClick_(e);}},onMouseUp_(e){if(e.button!==0)return;const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault){this.dispatchClickEvents_(e);}
+this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=true;}
+this.updateAlternativeModeState_(e);},onKeyUp_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=false;}
+let didHandleKey=false;for(const[modeStr,keyCode]of Object.entries(this.modeToKeyCodeMap_)){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;const mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}}
+if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
+this.updateAlternativeModeState_(e);},updateAlternativeModeState_(e){const shiftPressed=e.shiftKey;const spacePressed=this.spacePressed_;const cmdOrCtrlPressed=isCmdOrCtrlPressed(e);const smm=this.supportedModeMask_;let newMode;let isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
+if(this.mode===newMode||newMode===undefined)return;if(isNewModeAnAlternativeMode){this.modeBeforeAlternativeModeActivated_=this.mode;}
+this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_){tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);}},constrainPositionToBounds_(pos){const parent=this.offsetParent||document.body;const parentRect=tr.ui.b.windowRectForElement(parent);const top=0;const bottom=parentRect.height-this.offsetHeight;const left=0;const right=parentRect.width-this.offsetWidth;const res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();const mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){const pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_(e){if(!this.isInteracting_||!this.isClick_)return;const deltaX=this.mousePos_.x-this.mouseDownPos_.x;const deltaY=this.mousePos_.y-this.mouseDownPos_.y;const minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist){this.isClick_=false;}},dispatchClickEvents_(e){if(!this.isClick_)return;const modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];const eventNames=modeInfo.eventNames;let mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE,MODIFIER,};});'use strict';(function(){const DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer({is:'tr-ui-e-chrome-cc-display-item-list-item',created(){Polymer.dom(this).setAttribute('name','');Polymer.dom(this).setAttribute('rawDetails','');Polymer.dom(this).setAttribute('richDetails',undefined);Polymer.dom(this).setAttribute('data_',undefined);},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){const match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation(e){e.stopPropagation();},_computeIf(richDetails){return richDetails&&richDetails.skp64;},_computeHref(richDetails){return'data:application/octet-stream;base64,'+richDetails.skp64;}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;}
+Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis(){throw new Error('Not implemented');},findEquivalent(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined)){throw new Error('Render pass (with id) is required');}
+this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
+RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer){throw new Error('Layer is required');}
+this.layer_=layer;}
+LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization){dataView.label+=' (GPU-rasterized)';}
+dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent(lthi){const layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
+TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
+this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
+return analysis;},findEquivalent(lthi){const tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs){return undefined;}
+const tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
+LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
+AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection,RenderPassSelection,LayerSelection,TileSelection,LayerRectSelection,AnimationRectSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const ANNOTATION='Comment';const BEGIN_ANNOTATION='BeginCommentGroup';const END_ANNOTATION='EndCommentGroup';const ANNOTATION_ID='ID: ';const ANNOTATION_CLASS='CLASS: ';const ANNOTATION_TAG='TAG: ';const constants=tr.e.cc.constants;const PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.opsList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_(){this.opsList_.clear();if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(let i=0;i<ops.length;i++){const op=ops[i];const item=document.createElement('div');item.opIndex=op.opIndex;Polymer.dom(item).textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){const elementInfo=document.createElement('span');Polymer.dom(elementInfo).classList.add('elementInfo');const tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';const id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;const className=op.elementInfo.class?'class='+
+op.elementInfo.class:undefined;Polymer.dom(elementInfo).textContent='<'+tag+(id?' ':'')+
+(id?id:'')+(className?' ':'')+
+(className?className:'')+'>';Polymer.dom(item).appendChild(elementInfo);}
+if(op.info.length>0){const infoItem=document.createElement('div');Polymer.dom(infoItem).textContent=JSON.stringify(op.info);Polymer.dom(item).appendChild(infoItem);}
+if(op.cmd_time&&op.cmd_time>=0.0001){const time=document.createElement('span');Polymer.dom(time).classList.add('time');const rounded=op.cmd_time.toFixed(4);Polymer.dom(time).textContent='('+rounded+'ms)';Polymer.dom(item).appendChild(time);}
+Polymer.dom(this.opsList_).appendChild(item);}},onSelectionChanged_(e){let beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
+this.selectedOp_=this.opsList_.selectedElement;const ops=this.opsList_.children;for(let i=0;i<ops.length;i++){const op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){Polymer.dom(op).setAttribute('beforeSelection','beforeSelection');}else{Polymer.dom(op).removeAttribute('beforeSelection');}}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_(ops){const annotationGroups=[];const opsWithoutAnnotations=[];for(let opIndex=0;opIndex<ops.length;opIndex++){const op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push([]);break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:{const annotations=[];let elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.includes(ANNOTATION_TAG)){elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
+ANNOTATION_TAG.length).toLowerCase();}else if(info.includes(ANNOTATION_ID)){elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
+ANNOTATION_ID.length);}else if(info.includes(ANNOTATION_CLASS)){elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
+ANNOTATION_CLASS.length);}
+annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}}
+return opsWithoutAnnotations;}};return{PictureOpsListView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=Polymer.dom(this).querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));Polymer.dom(this.displayItemInfo_).appendChild(this.displayItemListView_);this.displayListFilename_=Polymer.dom(this).querySelector('.dlfilename');this.displayListExportButton_=Polymer.dom(this).querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=Polymer.dom(this).querySelector('.skpfilename');this.skpExportButton_=Polymer.dom(this).querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).insertBefore(this.infoBar_,this.rasterCanvas_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();Polymer.dom(rightPanel).insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;Polymer.dom(rightPanel).insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){const listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;Polymer.dom(this.displayItemListView_).appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;const showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);let width=parseInt(style.width);let height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
+return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_(e){const selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
+const index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);const displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64){this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);}else{this.picture=undefined;}},onDisplayItemInfoClick_(e){if(e&&e.target===this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){Polymer.dom(this.pictureOpsListView_).classList.add('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.add('hasPictureOps');}}else{Polymer.dom(this.pictureOpsListView_).classList.remove('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.remove('hasPictureOps');}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_(filename,rawData){if(!rawData)return;const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.URL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_(){const rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();Polymer.dom(this).appendChild(this.displayItemDebugger_);},updateContents(){if(this.objectSnapshot_&&this.displayItemDebugger_){this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;const LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));Polymer.dom(this.controls_).appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;const showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');Polymer.dom(showPureTransformLayers).classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';Polymer.dom(this.controls_).appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree===RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_(){if(!this.lthiSnapshot_)return[];const renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses){return renderPassInfo;}
+const renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(let i=0;i<renderPasses.length;++i){const info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
+return renderPassInfo;},getLayerInfos_(){if(!this.lthiSnapshot_)return[];const tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)return[];const layerInfos=[];const showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!==1&&layer.args.compositingReasons[0]!=='No reasons given'){return false;}
+if(layer.args.drawsContent)return false;return true;}
+const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;const info={layer,depth};if(layer.args.drawsContent){info.name=layer.objectInstance.name;}else{info.name='cc::LayerImpl';}
+if(layer.usingGpuRasterization){info.name+=' (G)';}
+info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer)){layerInfos.push(info);}}
+tree.iterLayers(visitLayer);return layerInfos;},updateContents_(){if(this.renderPassQuads_){this.updateRenderPassContents_();}else{this.updateLayerContents_();}},updateRenderPassContents_(){this.itemList_.clear();let selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId){selectedRenderPassId=this.selection_.associatedRenderPassId;}
+const renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){const renderPass=renderPassInfo.renderPass;const id=renderPassInfo.id;const item=this.createElementWithDepth_(renderPassInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;Polymer.dom(this.itemList_).appendChild(item);if(id===selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_(){this.changingItemSelection_=true;try{this.itemList_.clear();let selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId){selectedLayerId=this.selection_.associatedLayerId;}
+const layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){const layer=layerInfo.layer;const id=layer.layerId;const item=this.createElementWithDepth_(layerInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=layerInfo.name+' '+id;const notesEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer){Polymer.dom(notesEl).textContent+='(mask)';}
+if(layerInfo.isReplicaLayer){Polymer.dom(notesEl).textContent+='(replica)';}
+if((layer.gpuMemoryUsageInBytes!==undefined)&&(layer.gpuMemoryUsageInBytes>0)){const gpuUsageStr=tr.b.Unit.byName.sizeInBytes.format(layer.gpuMemoryUsageInBytes);Polymer.dom(notesEl).textContent+=' ('+gpuUsageStr+' MiB)';}
+item.layer=layer;Polymer.dom(this.itemList_).appendChild(item);if(layer.layerId===selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_(depth){const item=document.createElement('div');const indentEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(let i=0;i<depth;i++){Polymer.dom(indentEl).textContent=Polymer.dom(indentEl).textContent+' ';}
+return item;},onItemSelectionChanged_(e){if(this.changingItemSelection_)return;if(this.renderPassQuads_){this.onRenderPassSelected_(e);}else{this.onLayerSelected_(e);}
+tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_(e){let selectedRenderPass;let selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
+if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_(e){let selectedLayer;if(this.itemList_.selectedElement){selectedLayer=this.itemList_.selectedElement.layer;}
+if(selectedLayer){this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);}else{this.selection_=undefined;}},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.updateContents_();}};return{LayerPicker,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.subTypes.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const deg2rad=tr.b.math.deg2rad;const constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};const Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){const mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const aspectRatio=rect.width/rect.height;const matrix=mat4.create();mat4.perspective(matrix,deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){const gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];const settings=tr.b.SessionSettings();const keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
+if(this.deviceRect_){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
+this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta(delta){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];const length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);const halfFov=constants.FOV/2;const multiplier=2.0*length*Math.tan(deg2rad(halfFov))/rect.height;const up=[0,1,0];const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);const right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(let i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
+if(Math.abs(this.gazeTarget_[2])>1e-6){const gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];const newLength=tr.b.math.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(let i=0;i<3;++i){this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}}
+this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta(delta){let deltaY=delta[1];deltaY=tr.b.math.clamp(deltaY,-50,50);let scale=1.0-deltaY/100.0;const eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE){scale=constants.MINIMUM_DISTANCE/length;}else if(length*scale>constants.MAXIMUM_DISTANCE){scale=constants.MAXIMUM_DISTANCE/length;}
+vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT){return;}
+if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT){return;}
+const eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_(e){if(!this.panning_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_(e){this.panning_=false;},onZoomBegin_(e){this.zooming_=true;const p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_(e){if(!this.zooming_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_(e){if(!this.rotating_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_(e){this.rotating_=false;},getMousePosition_(e){const rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_(e,p){const newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera,};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;const constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){const tmpP0=[p0[0],p0[1]];const tmpP1=[p1[0],p1[1]];const tmpP2=[p2[0],p2[1]];const tmpT0=[t0[0],t0[1]];const tmpT1=[t1[0],t1[1]];const tmpT2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmpP0[0],tmpP0[1]);ctx.lineTo(tmpP1[0],tmpP1[1]);ctx.lineTo(tmpP2[0],tmpP2[1]);ctx.closePath();tmpP1[0]-=tmpP0[0];tmpP1[1]-=tmpP0[1];tmpP2[0]-=tmpP0[0];tmpP2[1]-=tmpP0[1];tmpT1[0]-=tmpT0[0];tmpT1[1]-=tmpT0[1];tmpT2[0]-=tmpT0[0];tmpT2[1]-=tmpT0[1];const det=1/(tmpT1[0]*tmpT2[1]-tmpT2[0]*tmpT1[1]);const a=(tmpT2[1]*tmpP1[0]-tmpT1[1]*tmpP2[0])*det;const b=(tmpT2[1]*tmpP1[1]-tmpT1[1]*tmpP2[1])*det;const c=(tmpT1[0]*tmpP2[0]-tmpT2[0]*tmpP1[0])*det;const d=(tmpT1[0]*tmpP2[1]-tmpT2[0]*tmpP1[1])*det;const e=tmpP0[0]-a*tmpT0[0]-c*tmpT0[1];const f=tmpP0[1]-b*tmpT0[0]-d*tmpT0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
+function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursionDepth){const depth=opt_recursionDepth||0;let subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=1;}
+if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=2;}
+if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=4;}}
+const p01=vec4.create();const p02=vec4.create();const p12=vec4.create();const t01=vec2.create();const t02=vec2.create();const t12=vec2.create();for(let i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
+for(let i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
+for(let i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
+for(let i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
+switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
+const tmpVec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmpVec4,point[0],point[1],0,1);vec4.transformMat4(tmpVec4,tmpVec4,matrix);let w=tmpVec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmpVec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmpVec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
+function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);const quadBBox=new tr.b.math.BBox2();quadBBox.addQuad(quad);const iw=quadCanvas.width;const ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
+if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
+function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor){ctx.strokeStyle=quad.borderColor;}else{ctx.strokeStyle='rgb(128,128,128)';}
+if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur){ctx.shadowBlur=quad.shadowBlur;}}
+if(quad.borderWidth){ctx.lineWidth=quad.borderWidth;}else{ctx.lineWidth=1;}
+ctx.stroke();ctx.restore();}
+function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
+function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
+const tmpP1=vec3.create();const tmpP2=vec3.create();const tmpP3=vec3.create();const tmpP4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(let passNumber=0;passNumber<numPasses;passNumber++){for(let i=0;i<quads.length;i++){const quad=quads[i];transform(tmpP1,quad.p1,matrix,viewport);transform(tmpP2,quad.p2,matrix,viewport);transform(tmpP3,quad.p3,matrix,viewport);transform(tmpP4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmpP1,tmpP2,tmpP3,tmpP4,opt_arg1,opt_arg2);}}}
+const QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.className='quad-stack-view';const node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.updateHeaderVisibility_();this.canvas_=Polymer.dom(this).querySelector('#canvas');this.chromeImages_={left:Polymer.dom(this).querySelector('#chrome-left'),mid:Polymer.dom(this).querySelector('#chrome-mid'),right:Polymer.dom(this).querySelector('#chrome-right')};const stackingDistanceSlider=Polymer.dom(this).querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.math.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_(){if(this.headerText){Polymer.dom(this).querySelector('#header').style.display='';}else{Polymer.dom(this).querySelector('#header').style.display='none';}},get headerText(){return Polymer.dom(this).querySelector('#header').textContent;},set headerText(headerText){Polymer.dom(this).querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return Polymer.dom(this).querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize(){if(!this.offsetParent)return true;const width=parseInt(window.getComputedStyle(this.offsetParent).width);const height=parseInt(window.getComputedStyle(this.offsetParent).height);const rect=tr.b.math.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
+return true;},readyToDraw(){if(!this.chromeImages_.left.src){let leftContent=window.getComputedStyle(this.chromeImages_.left).backgroundImage;leftContent=tr.ui.b.extractUrlString(leftContent);let midContent=window.getComputedStyle(this.chromeImages_.mid).backgroundImage;midContent=tr.ui.b.extractUrlString(midContent);let rightContent=window.getComputedStyle(this.chromeImages_.right).backgroundImage;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)return this.chromeQuad_;const chromeCanvas=document.createElement('canvas');const offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;const leftWidth=this.chromeImages_.left.width;const midWidth=this.chromeImages_.mid.width;const rightWidth=this.chromeImages_.right.width;const chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);const s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);const chromeRect=tr.b.math.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);const chromeQuad=tr.b.math.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender(){if(this.redrawScheduled_)return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_(e){this.scheduleRender();},stackTransformAndProcessQuads_(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){const mv=this.camera_.modelViewMatrix;const p=this.camera_.projectionMatrix;const viewport=tr.b.math.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);const quadStacks=[];for(let i=0;i<this.quads_.length;++i){const quad=this.quads_[i];const stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length){quadStacks.push([]);}
+quadStacks[stackingId].push(quad);}
+const mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;const effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(let i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
+if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
+if(!this.quads_)return;const canvasCtx=this.canvas_.getContext('2d');if(!this.resize()){canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);}
+const quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_(e){const br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_(e){const mousePos=this.extractRelativeMousePosition_(e);const res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.math.pointInImplicitQuad(mousePos,p1,p2,p3,p4)){res.push(quad);}}
+this.stackTransformAndProcessQuads_(1,handleQuad,false);e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const ColorScheme=tr.b.ColorScheme;const THIS_DOC=document.currentScript.ownerDocument;const TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';const cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
+const LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;const m=tr.ui.b.MOUSE_SELECTOR_MODE;const mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.infoBar_);Polymer.dom(this).appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());Polymer.dom(this.controls_).appendChild(this.tileRectsSelector_);const tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});Polymer.dom(this.controls_).appendChild(tileHeatmapText);const tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);Polymer.dom(this.controls_).appendChild(tileHeatmapSelector);const showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';Polymer.dom(this.controls_).appendChild(showOtherLayersCheckbox);const showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';Polymer.dom(this.controls_).appendChild(showInvalidationsCheckbox);const showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';Polymer.dom(this.controls_).appendChild(showUnrecordedRegionCheckbox);const showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';Polymer.dom(this.controls_).appendChild(showBottlenecksCheckbox);const showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';Polymer.dom(this.controls_).appendChild(showLayoutRectsCheckbox);const showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';Polymer.dom(this.controls_).appendChild(showContentsCheckbox);const showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';Polymer.dom(this.controls_).appendChild(showAnimationBoundsCheckbox);const showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';Polymer.dom(this.controls_).appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');Polymer.dom(this.whatRasterizedLink_).classList.add('what-rasterized');Polymer.dom(this.whatRasterizedLink_).textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));Polymer.dom(this).appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){if(val!=='none'&&val!=='coverage'&&isNaN(parseFloat(val))){throw new Error('howToShowTiles requires "none" or "coverage" or a number');}
+this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_(image,callback){const imageContent=window.getComputedStyle(image).backgroundImage;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);const imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);};},onQuadStackViewSelectionChange_(e){const selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length===0){this.selection=undefined;return;}
+selectableQuads.sort(function(x,y){const z=x.stackingGroupId-y.stackingGroupId;if(z!==0)return z;return x.selectionToSetIfClicked.specicifity-
+y.selectionToSetIfClicked.specicifity;});const quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
+const status=this.computePictureLoadingStatus_();if(!status.picturesComplete)return;const lthi=this.layerTreeImpl_.layerTreeHostImpl;const lthiInstance=lthi.objectInstance;const worldViewportRect=tr.b.math.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_){this.quadStackView_.quads=this.generateRenderPassQuads();}else{this.quadStackView_.quads=this.generateLayerQuads();}
+this.updateWhatRasterizedLinkState_();let message='';if(lthi.tilesHaveGpuMemoryUsageInfo){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;const otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
+thisTreeUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(otherTreeUsageInBytes){message+=', '+
+tr.b.convertUnit(otherTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on the other tree';}}else{if(this.layerTreeImpl_){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ??? MiB on other tree. ';}}}
+if(lthi.args.tileManagerBasicState){const tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
+tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
+tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
+tmgs.memoryLimitPolicy+')';}else{const thread=lthi.snapshottedOnThread;const didManageTilesSlices=thread.sliceGroup.slices.filter(s=>{if(s.category!=='tr.e.cc')return false;if(s.title!=='DidManage')return false;if(s.end>lthi.ts)return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){const newest=didManageTilesSlices[didManageTilesSlices.length-1];const tmgs=newest.args.state.global_state;message+=' (softMax='+
+tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
+tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
+tmgs.memoryLimitPolicy+')';}}
+if(this.layerTreeImpl_.otherTree){message+=' (Another tree exists)';}
+if(message.length){this.quadStackView_.headerText=message;}else{this.quadStackView_.headerText=undefined;}
+this.updateInfoBar_(status.messages);},updateTilesSelector_(){const data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const scaleNames=lthi.getContentsScaleNames();for(const scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
+const newSelector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(newSelector,this.tileRectsSelector_);this.tileRectsSelector_=newSelector;},computePictureLoadingStatus_(){const layers=this.layers;const status={messages:[],picturesComplete:true};if(this.showContents){let hasPendingRasterizeImage=false;let firstPictureError=undefined;let hasMissingLayerRect=false;let hasUnresolvedPictureRef=false;for(let i=0;i<layers.length;i++){const layer=layers[i];for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
+if(!picture.layerRect){hasMissingLayerRect=true;continue;}
+const pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){const picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
+if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
+if(pictureAsImageData.error){if(!firstPictureError){firstPictureError=pictureAsImageData.error;}
+break;}}}
+if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didn\'t have pictures for every layer. '+'Old chrome versions had this problem'});}
+if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
+if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
+if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){const image=Polymer.dom(this).querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
+status.picturesComplete=false;}
+return status;},get selectedRenderPass(){if(this.selection){return this.selection.renderPass_;}},get selectedLayer(){if(this.selection){const selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){let renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){const selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass){renderPasses=[selectedRenderPass];}}
+return renderPasses;},get layers(){let layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){const selectedLayer=this.selectedLayer;if(selectedLayer){layers=[selectedLayer];}}
+return layers;},appendImageQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(!picture.layerRect)continue;const unitRect=picture.layerRect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);const pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
+iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_(quads,layer,layerQuad){if(!layer.animationBoundsRect)return;const rect=layer.animationBoundsRect;const abq=tr.b.math.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)return;for(let ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){const rect=layer.annotatedInvalidation.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion'){iq.backgroundColor='rgba(0, 255, 128, 0.1)';}
+iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
+if(layer.annotatedInvalidation.rects.length===0){for(let ir=0;ir<layer.invalidation.rects.length;ir++){const rect=layer.invalidation.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.unrecordedRegion.rects.length;ir++){const rect=layer.unrecordedRegion.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){const backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)return;for(let ir=0;ir<region.rects.length;ir++){const rect=region.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
+processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)return;const tiles=[];for(let ct=0;ct<layer.tileCoverageRects.length;++ct){const tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)tiles.push(tile);}
+const lthi=this.layerTreeImpl_.layerTreeHostImpl;const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);let heatIndex=0;for(let ct=0;ct<layer.tileCoverageRects.length;++ct){let rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const tile=layer.tileCoverageRects[ct].tile;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;let type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
+quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;let label;if(tile){label='coverageRect';}else{label='checkerboard coverageRect';}
+quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_(quads,layer,layerQuad){if(!layer.layoutRects){return;}
+for(let ct=0;ct<layer.layoutRects.length;++ct){let rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;const label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_(tile,heatmapType){if(heatmapType===TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority===0?undefined:tile.scheduledPriority;}else if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_(tiles,heatmapType){const range=new tr.b.math.Range();if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
+for(let i=0;i<tiles.length;++i){const value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)continue;range.addValue(value);}
+if(range.range===0){range.addValue(1);}
+return range;},computeHeatmapColors_(tiles,minMax,heatmapType){const min=minMax.min;const max=minMax.max;const color=function(value){let hue=120*(1-(value-min)/(max-min));if(hue<0)hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};const values=[];for(let i=0;i<tiles.length;++i){const tile=tiles[i];const value=this.getValueForHeatmap_(tile,heatmapType);const res={value,color:value!==undefined?color(value):undefined};values.push(res);}
+return values;},appendTilesWithScaleQuads_(quads,layer,layerQuad,scale,heatmapType){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const tiles=[];for(let i=0;i<lthi.activeTiles.length;++i){const tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6){continue;}
+if(layer.layerId!==tile.layerId)continue;tiles.push(tile);}
+const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(let i=0;i<tiles.length;++i){const tile=tiles[i];const rect=tile.layerRect;if(!tile.layerRect)continue;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;const type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;const data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE){data[heatmapType]=heatmapResult[i].value;}
+quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){const rect=highlight.rect;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);let colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);const offset=ColorScheme.properties.brightenedOffsets[0];colorId=ColorScheme.getVariantColorId(colorId,offset);const color=ColorScheme.colors[colorId];const quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)return[];const renderPasses=this.renderPasses;if(!renderPasses)return[];const quads=[];for(let i=0;i<renderPasses.length;++i){const quadList=renderPasses[i].quadList;for(let j=0;j<quadList.length;++j){const drawQuad=quadList[j];const quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
+return quads;},generateLayerQuads(){this.updateContentsPending_=false;const layers=this.layers;const quads=[];let nextStackingGroupId=0;const alreadyVisitedLayerIds={};let selectionHighlightsByLayerId;if(this.selection){selectionHighlightsByLayerId=this.selection.highlightsByLayerId;}else{selectionHighlightsByLayerId={};}
+const extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(let i=1;i<=layers.length;i++){const layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name==='cc::NinePatchLayerImpl'){continue;}
+const layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){const pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
+layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer===layer){layerQuad.upperBorderColor='rgb(156,189,45)';}
+if(this.showAnimationBounds){this.appendAnimationQuads_(quads,layer,layerQuad);}
+this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations){this.appendInvalidationQuads_(quads,layer,layerQuad);}
+if(this.showUnrecordedRegion){this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);}
+if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);}
+if(this.showLayoutRects){this.appendLayoutRectQuads_(quads,layer,layerQuad);}
+if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
+let highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
+highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
+this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!==layer)return;if(alreadyVisitedLayerIds[layer.layerId])return;const layerQuad=layer.layerQuad;const stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);}},this);const tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(let i=0;i<tracedInputLatencies.length;i++){const coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(let j=0;j<coordinatesArray.length;j++){const inputQuad=tr.b.math.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
+return quads;},updateInfoBar_(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent='';infoBarMessages.forEach(function(message){const title=document.createElement('h3');Polymer.dom(title).textContent=message.header;const details=document.createElement('div');Polymer.dom(details).textContent=message.details;Polymer.dom(overlay).appendChild(title);Polymer.dom(overlay).appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_(){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const renderProcess=lthi.objectInstance.parent;const tasks=[];for(const event of renderProcess.getDescendantEvents()){if(!(event instanceof tr.model.Slice))continue;const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)continue;if(tile.containingSnapshot===lthi){tasks.push(event);}}
+return tasks;},updateWhatRasterizedLinkState_(){const tasks=this.getWhatRasterized_();if(tasks.length){Polymer.dom(this.whatRasterizedLink_).textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{Polymer.dom(this.whatRasterizedLink_).textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_(){const tasks=this.getWhatRasterized_();const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;Polymer.dom(this).appendChild(this.layerTreeQuadStackView_);Polymer.dom(this).appendChild(this.dragBar_);Polymer.dom(this).appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_(){const selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';Polymer.dom(this.analysisEl_).textContent='';const layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){Polymer.dom(this.analysisEl_).appendChild(this.createPictureBtn_(layer.args.pictures));}
+const analysis=selection.createAnalysis();Polymer.dom(this.analysisEl_).appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';const analysis=Polymer.dom(this.analysisEl_).firstChild;if(analysis){Polymer.dom(this.analysisEl_).removeChild(analysis);}
+this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
+tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_(pictures){if(!(pictures instanceof Array)){pictures=[pictures];}
+const link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){const layeredPicture=new tr.e.cc.LayeredPicture(pictures);const snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;const selection=new tr.model.EventSet();selection.push(snapshot);return selection;};Polymer.dom(link).textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection)){return;}
+e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;Polymer.dom(this).appendChild(this.layerPicker_);Polymer.dom(this).appendChild(this.dragHandle_);Polymer.dom(this).appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;const lthi=this.objectSnapshot;let layerTreeImpl;if(lthi){layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);}
+this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=40;const AXIS_PADDING_LEFT=60;const AXIS_PADDING_RIGHT=35;const AXIS_PADDING_TOP=25;const AXIS_PADDING_BOTTOM=45;const AXIS_LABEL_PADDING=5;const AXIS_TICK_SIZE=10;const LABEL_PADDING=5;const LABEL_INTERLEAVE_OFFSET=15;const BAR_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(Polymer.dom(this).classList.contains('hidden'))return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide(){Polymer.dom(this).classList.add('hidden');},show(){Polymer.dom(this).classList.remove('hidden');if(this.pictureDataProcessed_)return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;const x=e.offsetX;const y=e.offsetY;const chartLeft=CHART_PADDING_LEFT;const chartRight=this.chartWidth_-CHART_PADDING_RIGHT;const chartTop=AXIS_PADDING_TOP;const chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;const chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.math.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
+if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)return;this.drawChartContents_();},updateChartContents(){if(this.requiresRedraw){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
+this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)return;this.drawTooltip_();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_(){const tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const tooltipWidth=110;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=chartInnerWidth/this.opsTimingData_.length;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const barWidth=Math.floor(width/len);let opData;let opTiming;let opHeight;let opLabel;let barLeft;for(let b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
+height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_(opName){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
+CHART_PADDING_RIGHT;const barWidth=Math.floor(totalBarWidth/len);const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';let labelTickLeft;let labelTickBottom;for(let l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
+this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_(ops){const opsTimingDataIndexHash_={};const timingData=this.opsTimingData_;let op;let opIndex;for(let i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
+timingData[opIndex].cmd_time+=op.cmd_time;}
+timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_(count){const timingData=this.opsTimingData_;const otherSource=timingData.splice(count,timingData.length-count);let otherDestination=null;if(!otherSource.length)return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(let i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const BAR_PADDING=1;const BAR_WIDTH=5;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=30;const CHART_PADDING_BOTTOM=35;const CHART_PADDING_TOP=20;const AXIS_PADDING_LEFT=55;const AXIS_PADDING_RIGHT=30;const AXIS_PADDING_BOTTOM=35;const AXIS_PADDING_TOP=20;const AXIS_TICK_SIZE=5;const AXIS_LABEL_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');Polymer.dom(this.usePercentileScaleCheckbox_).classList.add('use-percentile-scale');Polymer.dom(this).appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_(){if(this.pictureOps_===undefined)return;let totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();const ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_(e){let index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0){return index;}
+const x=e.offsetX;const y=e.offsetY;const totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;const chartLeft=CHART_PADDING_LEFT;const chartTop=0;const chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;const chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom){return index;}
+index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.math.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_(e){const barClicked=this.extractBarIndex_(e);if(barClicked===undefined)return;if(barClicked===this.selectedOpIndex){this.selectedOpIndex=undefined;}else{this.selectedOpIndex=barClicked;}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget){return;}
+this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary(){if(this.selectedOpIndex===undefined){return;}
+const width=this.offsetWidth;const left=this.scrollLeft;const right=left+width;const targetLeft=CHART_PADDING_LEFT+
+(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right){return;}
+this.scrollLeft=(targetLeft-width*0.5);},updateChartContents(){if(this.dimensionsHaveChanged){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){if(!this.pictureOps_)return;let width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
+((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth){width=this.offsetWidth;}
+this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
+this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined){return;}
+this.drawTooltip_();},drawSelection_(){if(this.selectedOpIndex===undefined){return;}
+const width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_(){const min=this.opCosts_[0];const max=this.opCosts_[this.opCosts_.length-1];const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
+AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_(){const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
+this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_(){const tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);const tooltipWidth=120;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=BAR_WIDTH+BAR_PADDING;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
+toolTipTimePercentage+'%)',left+8,top+22);},drawBars_(){let op;let opColor=0;let opHeight=0;const opWidth=BAR_WIDTH+BAR_PADDING;let opHover=false;const bottom=this.chartHeight_-CHART_PADDING_BOTTOM;const maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
+CHART_PADDING_TOP;let maxValue;if(this.usePercentileScale){maxValue=this.ninetyFifthPercentileCost_;}else{maxValue=this.maxCost_;}
+for(let b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex){this.chartCtx_.fillStyle='#FFFF00';}else{this.chartCtx_.fillStyle=opColor;}
+this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_(opName,hover){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;const saturation=30;const lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=Polymer.dom(this).querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=Polymer.dom(this).querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();const overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');const chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');const pictureInfo=Polymer.dom(this).querySelector('picture-info');Polymer.dom(pictureInfo).appendChild(overdrawCheckbox);Polymer.dom(pictureInfo).appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');Polymer.dom(leftPanel).appendChild(this.drawOpsChartSummaryView_);Polymer.dom(leftPanel).appendChild(this.drawOpsView_);const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,Polymer.dom(rightPanel).querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).appendChild(this.infoBar_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;const hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));Polymer.dom(this).appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_(mutations){for(let m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.webkitURL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);const width=Math.max(parseInt(style.width),this.picture_.layerRect.width);const height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
+this.selectedOpIndex=tr.b.math.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible){this.drawOpsChartSummaryView_.show();}else{this.drawOpsChartSummaryView_.hide();}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();Polymer.dom(this).appendChild(this.pictureDebugger_);},updateContents(){if(this.objectSnapshot_&&this.pictureDebugger_){this.pictureDebugger_.picture=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView,};});'use strict';tr.exportTo('tr.e.cc',function(){const knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];const knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice))){return undefined;}
+let tileData;if(slice.args.data){tileData=slice.args.data;}else{tileData=slice.args.tileData;}
+if(tileData===undefined)return undefined;if(tileData.tile_id)return tileData.tile_id;const tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot)){return undefined;}
+return tileData.tileId;}
+function isSliceDoingRasterization(slice){return knownRasterTaskNames.includes(slice.title);}
+function isSliceDoingAnalysis(slice){return knownAnalysisTaskNames.includes(slice.title);}
+return{getTileFromRasterTaskSlice,isSliceDoingRasterization,isSliceDoingAnalysis};});'use strict';tr.exportTo('tr.ui.analysis',function(){const AnalysisSubView={set tabLabel(label){Polymer.dom(this).setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}};const allTypeInfosByEventProto=new Map();let onlyRootTypeInfosByEventProto=undefined;let eventProtoToRootTypeInfoMap=undefined;function AnalysisSubViewTypeInfo(eventConstructor,options){if(options.multi===undefined){throw new Error('missing field: multi');}
+if(options.title===undefined){throw new Error('missing field: title');}
+this.eventConstructor=eventConstructor;this.singleTagName=undefined;this.singleTitle=undefined;this.multiTagName=undefined;this.multiTitle=undefined;this.childrenTypeInfos_=undefined;}
+AnalysisSubViewTypeInfo.prototype={get childrenTypeInfos(){return this.childrenTypeInfos_;},resetchildrenTypeInfos(){this.childrenTypeInfos_=[];}};AnalysisSubView.register=function(tagName,eventConstructor,options){let typeInfo=allTypeInfosByEventProto.get(eventConstructor.prototype);if(typeInfo===undefined){typeInfo=new AnalysisSubViewTypeInfo(eventConstructor,options);allTypeInfosByEventProto.set(typeInfo.eventConstructor.prototype,typeInfo);onlyRootTypeInfosByEventProto=undefined;}
+if(!options.multi){if(typeInfo.singleTagName!==undefined){throw new Error('SingleTagName already set');}
+typeInfo.singleTagName=tagName;typeInfo.singleTitle=options.title;}else{if(typeInfo.multiTagName!==undefined){throw new Error('MultiTagName already set');}
+typeInfo.multiTagName=tagName;typeInfo.multiTitle=options.title;}
+return typeInfo;};function rebuildRootSubViewTypeInfos(){onlyRootTypeInfosByEventProto=new Map();allTypeInfosByEventProto.forEach(function(typeInfo){typeInfo.resetchildrenTypeInfos();});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let lastEventProto=eventPrototype;let curEventProto=eventPrototype.__proto__;while(true){if(!allTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=allTypeInfosByEventProto.get(lastEventProto);const rootEventProto=lastEventProto;const isNew=onlyRootTypeInfosByEventProto.has(rootEventProto);onlyRootTypeInfosByEventProto.set(rootEventProto,rootTypeInfo);break;}
+lastEventProto=curEventProto;curEventProto=curEventProto.__proto__;}});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;const parentEventProto=eventPrototype.__proto__;const parentTypeInfo=allTypeInfosByEventProto.get(parentEventProto);if(!parentTypeInfo)return;parentTypeInfo.childrenTypeInfos.push(typeInfo);});eventProtoToRootTypeInfoMap=new Map();allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let curEventProto=eventPrototype;while(true){if(onlyRootTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=onlyRootTypeInfosByEventProto.get(curEventProto);eventProtoToRootTypeInfoMap.set(eventPrototype,rootTypeInfo);break;}
+curEventProto=curEventProto.__proto__;}});}
+function findLowestTypeInfoForEvents(thisTypeInfo,events){if(events.length===0)return thisTypeInfo;const event0=tr.b.getFirstElement(events);let candidateSubTypeInfo;for(let i=0;i<thisTypeInfo.childrenTypeInfos.length;i++){const childTypeInfo=thisTypeInfo.childrenTypeInfos[i];if(event0 instanceof childTypeInfo.eventConstructor){candidateSubTypeInfo=childTypeInfo;break;}}
+if(!candidateSubTypeInfo)return thisTypeInfo;let allMatch=true;for(const event of events){if(event instanceof candidateSubTypeInfo.eventConstructor)continue;allMatch=false;break;}
+if(!allMatch){return thisTypeInfo;}
+return findLowestTypeInfoForEvents(candidateSubTypeInfo,events);}
+const primaryEventProtoToTypeInfoMap=new Map();function getRootTypeInfoForEvent(event){const curProto=event.__proto__;const typeInfo=primaryEventProtoToTypeInfoMap.get(curProto);if(typeInfo)return typeInfo;return getRootTypeInfoForEventSlow(event);}
+function getRootTypeInfoForEventSlow(event){let typeInfo;let curProto=event.__proto__;while(true){if(curProto===Object.prototype){throw new Error('No view registered for '+event.toString());}
+typeInfo=onlyRootTypeInfosByEventProto.get(curProto);if(typeInfo){primaryEventProtoToTypeInfoMap.set(event.__proto__,typeInfo);return typeInfo;}
+curProto=curProto.__proto__;}}
+AnalysisSubView.getEventsOrganizedByTypeInfo=function(selection){if(onlyRootTypeInfosByEventProto===undefined){rebuildRootSubViewTypeInfos();}
+const eventsByRootTypeInfo=tr.b.groupIntoMap(selection,function(event){return getRootTypeInfoForEvent(event);},this,tr.model.EventSet);const eventsByLowestTypeInfo=new Map();eventsByRootTypeInfo.forEach(function(events,typeInfo){const lowestTypeInfo=findLowestTypeInfoForEvents(typeInfo,events);eventsByLowestTypeInfo.set(lowestTypeInfo,events);});return eventsByLowestTypeInfo;};return{AnalysisSubView,AnalysisSubViewTypeInfo,};});Polymer({is:'tr-ui-a-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView]});'use strict';Polymer({is:'tr-ui-a-stack-frame',ready(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){const table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+let hasName=false;let hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});const cols=[];if(hasName){cols.push({title:'Name',value(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting(){return this.$.table;}});'use strict';Polymer({is:'tr-ui-a-single-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],properties:{isFlow:{type:Boolean,value:false}},ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;this.updateContents_();},getFlowEventRows_(event){const rows=this.getEventRowsHelper_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});Polymer.dom(linkEl).textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;},getEventRowsHelper_(event){const rows=[];if(event.error){rows.push({name:'Error',value:event.error});}
+if(event.title){rows.push({name:'Title',value:event.title});}
+if(event.category){rows.push({name:'Category',value:event.category});}
+if(event.model!==undefined){const ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined){rows.push({name:'User Friendly Category',value:ufc});}}
+if(event.name){rows.push({name:'Name',value:event.name});}
+rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.b.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.cpuSelfTime){const cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
+if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+function createStackFrameEl(sf){const sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
+if(event.info){const descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){const alertSubRows=[];event.associatedAlerts.forEach(function(alert){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},getEventRows_(event){if(this.isFlow){return this.getFlowEventRows_(event);}
+return this.getEventRowsHelper_(event);},addArgsToRows_(rows,args){let n=0;for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows});}}},addContextsToRows_(rows,contexts){if(contexts.length){const subRows=contexts.map(function(context){const contextView=document.createElement('tr-ui-a-generic-object-view');contextView.object=context;return{name:'Context',value:contextView};});rows.push({name:'Contexts',value:'',isExpanded:true,subRows});}},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const event=tr.b.getOnlyElement(this.currentSelection_);const rows=this.getEventRows_(event);if(event.argsStripped){rows.push({name:'Args',value:'Stripped'});}else{this.addArgsToRows_(rows,event.args);}
+this.addContextsToRows_(rows,event.contexts);const customizeRowsEvent=new tr.b.Event('customize-rows');customizeRowsEvent.rows=rows;this.dispatchEvent(customizeRowsEvent);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-e-chrome-cc-raster-task-view',created(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_(hadCpuDurations){const timeSpanConfig={unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};const columns=[{title:'Layer',value(row){if(row.isTotals)return'Totals';if(row.layer){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}
+return'Layer '+row.layerId;},width:'250px'},{title:'Num Tiles',value(row){return row.numTiles;},cmp(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value(row){return row.numAnalysisTasks;},cmp(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value(row){return row.numRasterTasks;},cmp(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp(a,b){return a.cpuDuration-b.cpuDuration;}});}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_(){const table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
+const lthi=tr.e.cc.getTileFromRasterTaskSlice(tr.b.getFirstElement(this.selection_)).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);const costsByLayerId={};function getCurrentCostsForLayerId(tile){const layerId=tile.layerId;const lthi=tile.containingSnapshot;let layer;if(lthi.activeTree){layer=lthi.activeTree.findLayerWithId(layerId);}
+if(layer===undefined&&lthi.pendingTree){layer=lthi.pendingTree.findLayerWithId(layerId);}
+if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId,layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
+return costsByLayerId[layerId];}
+let totalDuration=0;let totalCpuDuration=0;let totalNumAnalyzeTasks=0;let totalNumRasterizeTasks=0;let hadCpuDurations=false;const tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);const curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
+if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
+curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=Object.values(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:Object.keys(tilesThatWeHaveSeen).length,numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);const whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok){throw new Error('Fail: '+whySupported.why);}
+this.slices_=Array.from(selection);this.tiles_=this.slices_.map(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined){throw new Error('This should never happen due to .supports check.');}
+return tile;});}
+RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet)){return{ok:false,why:'Must be selection'};}
+if(selection.length===0){return{ok:false,why:'Selection must be non empty'};}
+let referenceSnapshot=undefined;for(const event of selection){if(!(event instanceof tr.model.Slice)){return{ok:false,why:'Not a slice'};}
+const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined){return{ok:false,why:'No tile found'};}
+if(!referenceSnapshot){referenceSnapshot=tile.containingSnapshot;}else{if(tile.containingSnapshot!==referenceSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
+return{ok:true};};RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){const tile0=this.tiles_[0];const allSameLayer=this.tiles_.every(function(tile){tile.layerId===tile0.layerId;});if(allSameLayer){return tile0.layerId;}
+return undefined;},get extraHighlightsByLayerId(){const highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined){highlights[tile.layerId]=[];}
+const slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis(){const sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});let analysis;if(sel.length===1){analysis=document.createElement('tr-ui-a-single-event-sub-view');}else{analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');}
+analysis.selection=sel;return analysis;},findEquivalent(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();Polymer.dom(this).appendChild(this.layerTreeView_);},updateContents(){const tile=this.objectSnapshot_;const layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView,};});'use strict';tr.exportTo('tr.e.gpu',function(){const AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
+GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category==='disabled-by-default-gpu.device'){return'Device.'+this.args.channel;}
+return'Service.'+this.args.channel;}
+return this.title;}};AsyncSlice.subTypes.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice,};});'use strict';tr.exportTo('tr.e.gpu',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
+StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){this.screenshot_=undefined;},initialize(){if(this.args.screenshot){this.screenshot_=this.args.screenshot;}},get screenshot(){return this.screenshot_;}};ObjectSnapshot.subTypes.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot,};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){const StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');Polymer.dom(this).appendChild(this.screenshotImage_);},updateContents(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-layout-tree-sub-view',behaviors:['tr-ui-a-sub-view'],set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_(){this.set('$.content.textContent','');if(!this.currentSelection_)return;const columns=[{title:'Tag/Name',value(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value(layoutObject){if(layoutObject.tableRow===undefined){return'';}
+return layoutObject.tableRow;}},{title:'col',value(layoutObject){if(layoutObject.tableCol===undefined){return'';}
+return layoutObject.tableCol;}},{title:'rowSpan',value(layoutObject){if(layoutObject.tableRowSpan===undefined){return'';}
+return layoutObject.tableRowSpan;}},{title:'colSpan',value(layoutObject){if(layoutObject.tableColSpan===undefined){return'';}
+return layoutObject.tableColSpan;}},{title:'address',value(layoutObject){return layoutObject.id.toString(16);}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();Polymer.dom(this.$.content).appendChild(table);},});return{};});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:false,title:'Layout Tree',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:true,title:'Layout Trees',});'use strict';tr.exportTo('tr.ui.behaviors',function(){const SidePanel={get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel(m){throw new Error('Not implemented');}};return{SidePanel,};});'use strict';tr.exportTo('tr.ui.side_panel',function(){function SidePanelRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(SidePanelRegistry,options);return{SidePanelRegistry,};});'use strict';tr.exportTo('tr.ui.e.s',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const FrameTreeNodeSnapshot=tr.e.chrome.FrameTreeNodeSnapshot;const RenderFrameSnapshot=tr.e.chrome.RenderFrameSnapshot;const TopLevelSnapshot=tr.e.chrome.TopLevelSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;const FrameTreeNodeInstance=tr.e.chrome.FrameTreeNodeInstance;const RenderFrameInstance=tr.e.chrome.RenderFrameInstance;const TopLevelInstance=tr.e.chrome.TopLevelInstance;function Row(context){this.subRows=undefined;this.contexts=[];this.type=undefined;this.renderer='N/A';this.url=undefined;this.time=0;this.eventsOfInterest=new tr.model.EventSet();if(context===undefined)return;this.type=context.objectInstance.blameContextType;this.contexts.push(context);if(context instanceof FrameTreeNodeSnapshot){if(context.renderFrame){this.contexts.push(context.renderFrame);this.renderer=context.renderFrame.objectInstance.parent.pid;}}else if(context instanceof RenderFrameSnapshot){if(context.frameTreeNode){this.contexts.push(context.frameTreeNode);}
+this.renderer=context.objectInstance.parent.pid;}else if(context instanceof TopLevelSnapshot){this.renderer=context.objectInstance.parent.pid;}else{throw new Error('Unknown context type');}
+this.eventsOfInterest.addEventSet(this.contexts);this.url=context.url;}
+const groupFunctions={none:rows=>rows,tree(rows,rowMap){const getParentRow=function(row){let pivot;row.contexts.forEach(function(context){if(context instanceof tr.e.chrome.FrameTreeNodeSnapshot){pivot=context;}});if(pivot&&pivot.parentContext){return rowMap[pivot.parentContext.guid];}
+return undefined;};const rootRows=[];rows.forEach(function(row){const parentRow=getParentRow(row);if(parentRow===undefined){rootRows.push(row);return;}
+if(parentRow.subRows===undefined){parentRow.subRows=[];}
+parentRow.subRows.push(row);});const aggregateAllDescendants=function(row){if(!row.subRows){if(getParentRow(row)){row.type='Subframe';}
+return row;}
+const result=new Row();result.type='Frame Tree';result.renderer=row.renderer;result.url=row.url;result.subRows=[row];row.subRows.forEach(subRow=>result.subRows.push(aggregateAllDescendants(subRow)));result.subRows.forEach(function(subRow){result.time+=subRow.time;result.eventsOfInterest.addEventSet(subRow.eventsOfInterest);});row.subRows=undefined;return result;};return rootRows.map(rootRow=>aggregateAllDescendants(rootRow));}};Polymer({is:'tr-ui-e-s-frame-data-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=new tr.b.math.Range();this.$.table.showHeader=true;this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=this.createFrameDataTableColumns_();this.$.table.addEventListener('selection-changed',function(e){this.selectEventSet_(this.$.table.selectedTableRow.eventsOfInterest);}.bind(this));this.$.select.addEventListener('change',function(e){this.updateContents_();}.bind(this));},selectEventSet_(eventSet){const event=new tr.model.RequestSelectionChangeEvent();event.selection=eventSet;this.dispatchEvent(event);},createFrameDataTableColumns_(){return[{title:'Renderer',value:row=>row.renderer,cmp:(a,b)=>a.renderer-b.renderer},{title:'Type',value:row=>row.type},{title:'Time',value:row=>tr.v.ui.createScalarSpan(row.time,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}),cmp:(a,b)=>a.time-b.time},{title:'URL',value:row=>row.url,cmp:(a,b)=>(a.url||'').localeCompare(b.url||'')}];},createFrameDataTableRows_(){if(!this.model_)return[];const rows=[];const rowMap={};for(const proc of Object.values(this.model_.processes)){proc.objects.iterObjectInstances(function(objectInstance){if(!(objectInstance instanceof BlameContextInstance)){return;}
+objectInstance.snapshots.forEach(function(snapshot){if(rowMap[snapshot.guid])return;const row=new Row(snapshot);row.contexts.forEach(context=>rowMap[context.guid]=row);rows.push(row);},this);},this);}
+for(const proc of Object.values(this.model_.processes)){for(const thread of Object.values(proc.threads)){thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice){topLevelSlice.contexts.forEach(function(context){if(!context.snapshot.guid||!rowMap[context.snapshot.guid]){return;}
+const row=rowMap[context.snapshot.guid];row.eventsOfInterest.push(topLevelSlice);row.time+=topLevelSlice.selfTime||0;});},this.currentRangeOfInterest.min,this.currentRangeOfInterest.max);}}
+const select=this.$.select;const groupOption=select.options[select.selectedIndex].value;const groupFunction=groupFunctions[groupOption];return groupFunction(rows,rowMap);},updateContents_(){this.$.table.tableRows=this.createFrameDataTableRows_();this.$.table.rebuild();},supportsModel(m){if(!m){return{supported:false,reason:'No model available.'};}
+const ans={supported:false};for(const proc of Object.values(m.processes)){proc.objects.iterObjectInstances(function(instance){if(instance instanceof BlameContextInstance){ans.supported=true;}});}
+if(!ans.supported){ans.reason='No frame data available';}
+return ans;},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
+return this.rangeOfInterest_;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},get selection(){},set selection(_){},get textLabel(){return'Frame Data';},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-frame-data-side-panel');});});'use strict';Polymer({is:'tr-ui-b-chart-legend-key',ready(){this.$.checkbox.addEventListener('change',this.onCheckboxChange_.bind(this));},onCheckboxChange_(){tr.b.dispatchSimpleEvent(this,tr.ui.b.DataSeriesEnableChangeEventType,true,false,{key:Polymer.dom(this).textContent,enabled:this.enabled});},set textContent(t){Polymer.dom(this.$.label).textContent=t;Polymer.dom(this.$.link).textContent=t;this.updateContents_();},set width(w){w-=20;this.$.link.style.width=w+'px';this.$.label.style.width=w+'px';},get textContent(){return Polymer.dom(this.$.label).textContent;},set optional(optional){this.$.checkbox.style.visibility=optional?'visible':'hidden';},get optional(){return this.$.checkbox.style.visibility==='visible';},set enabled(enabled){this.$.checkbox.checked=enabled?'checked':'';},get enabled(){return this.$.checkbox.checked;},set color(c){this.$.label.style.color=c;this.$.link.color=c;},set target(target){this.$.link.setSelectionAndContent(target,Polymer.dom(this.$.label).textContent);this.updateContents_();},get target(){return this.$.link.selection;},set title(title){this.$.link.title=title;},updateContents_(){this.$.link.style.display=this.target?'':'none';this.$.label.style.display=this.target?'none':'';this.$.label.htmlFor=this.optional?'checkbox':'';}});'use strict';(function(window){window.define=function(x){window.d3=x;};window.define.amd=true;})(this);!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';(function(window){window.define=undefined;}).call(this,this);'use strict';tr.exportTo('tr.ui.b',function(){const DataSeriesEnableChangeEventType='data-series-enabled-change';const THIS_DOC=document.currentScript.ownerDocument;const svgNS='http://www.w3.org/2000/svg';const ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){let id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected){id+=ColorScheme.properties.brightenedOffsets[0];}
+return ColorScheme.colorsAsStrings[id];}
+function getSVGTextSize(parentNode,text,opt_callback,opt_this){const textNode=document.createElementNS('http://www.w3.org/2000/svg','text');textNode.setAttributeNS(null,'x',0);textNode.setAttributeNS(null,'y',0);textNode.setAttributeNS(null,'fill','black');textNode.appendChild(document.createTextNode(text));parentNode.appendChild(textNode);if(opt_callback){opt_callback.call(opt_this||parentNode,textNode);}
+const width=textNode.getComputedTextLength();const height=textNode.getBBox().height;parentNode.removeChild(textNode);return{width,height};}
+function DataSeries(key){this.key_=key;this.target_=undefined;this.title_='';this.optional_=false;this.enabled_=true;this.color_=getColorOfKey(key,false);this.highlightedColor_=getColorOfKey(key,true);}
+DataSeries.prototype={get key(){return this.key_;},get title(){return this.title_;},set title(t){this.title_=t;},get color(){return this.color_;},set color(c){this.color_=c;},get highlightedColor(){return this.highlightedColor_;},set highlightedColor(c){this.highlightedColor_=c;},get optional(){return this.optional_;},set optional(optional){this.optional_=optional;},get enabled(){return this.enabled_;},set enabled(enabled){if(!this.optional&&!enabled){this.optional=true;}
+this.enabled_=enabled;},get target(){return this.target_;},set target(t){this.target_=t;}};const ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,getDataSeries(key){if(!this.seriesByKey_.has(key)){this.seriesByKey_.set(key,new DataSeries(key));}
+return this.seriesByKey_.get(key);},decorate(){Polymer.dom(this).classList.add('chart-base');this.chartTitle_=undefined;this.seriesByKey_=new Map();this.graphWidth_=undefined;this.graphHeight_=undefined;this.margin={top:0,right:0,bottom:0,left:0,};this.hideLegend_=false;const template=Polymer.dom(THIS_DOC).querySelector('#chart-base-template');const svgEl=Polymer.dom(template.content).querySelector('svg');for(let i=0;i<Polymer.dom(svgEl).children.length;i++){Polymer.dom(this).appendChild(Polymer.dom(svgEl.children[i]).cloneNode(true));}
+this.addEventListener(DataSeriesEnableChangeEventType,this.onDataSeriesEnableChange_.bind(this));},get hideLegend(){return this.hideLegend_;},set hideLegend(h){this.hideLegend_=h;this.updateContents_();},isSeriesEnabled(key){return this.getDataSeries(key).enabled;},onDataSeriesEnableChange_(event){this.getDataSeries(event.key).enabled=event.enabled;this.updateContents_();},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return Polymer.dom(this).querySelector('#chart-area');},get graphWidth(){if(this.graphWidth_===undefined)return this.defaultGraphWidth;return this.graphWidth_;},set graphWidth(width){this.graphWidth_=width;this.updateContents_();},get defaultGraphWidth(){return 0;},get graphHeight(){if(this.graphHeight_===undefined)return this.defaultGraphHeight;return this.graphHeight_;},set graphHeight(height){this.graphHeight_=height;this.updateContents_();},get defaultGraphHeight(){return 0;},get totalWidth(){return this.margin.left+this.graphWidth+this.margin.right;},get totalHeight(){return this.margin.top+this.graphHeight+this.margin.bottom;},updateMargins_(){const legendSize=this.computeLegendSize_();this.margin.right=Math.max(this.margin.right,legendSize.width);this.margin.bottom=Math.max(this.margin.bottom,legendSize.height-this.graphHeight);if(this.chartTitle_){const titleSize=getSVGTextSize(this,this.chartTitle_,textNode=>{textNode.style.fontSize='16pt';});this.margin.top=Math.max(this.margin.top,titleSize.height+15);const horizontalOverhangPx=(titleSize.width-this.graphWidth)/2;this.margin.left=Math.max(this.margin.left,horizontalOverhangPx);this.margin.right=Math.max(this.margin.right,horizontalOverhangPx);}},computeLegendSize_(){let width=0;let height=0;if(this.hideLegend)return{width,height};for(const series of this.seriesByKey_.values()){const textSize=getSVGTextSize(this,series.key);width=Math.max(width,textSize.width+20);height+=textSize.height;}
+return{width,height};},updateDimensions_(){const thisSel=d3.select(this);thisSel.attr('width',this.totalWidth);thisSel.attr('height',this.totalHeight);d3.select(this.chartAreaElement).attr('transform','translate('+this.margin.left+', '+this.margin.top+')');},updateContents_(){this.updateMargins_();this.updateDimensions_();this.updateTitle_();this.updateLegend_();},updateTitle_(){const titleSel=d3.select(this.chartAreaElement).select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+titleSel.attr('transform','translate('+this.graphWidth*0.5+',-15)').style('display',undefined).style('text-anchor','middle').style('font-size','16pt').attr('class','title').attr('width',this.graphWidth).text(this.chartTitle_);},updateLegend_(){const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.legend').remove();if(this.hideLegend)return;const series=[...this.seriesByKey_.values()].reverse();const legendEntriesSel=chartAreaSel.selectAll('.legend').data(series);legendEntriesSel.enter().append('foreignObject').attr('class','legend').attr('x',this.graphWidth+2).attr('width',this.margin.right).attr('height',18).attr('transform',(series,i)=>'translate(0,'+i*18+')').append('xhtml:body').style('margin',0).append('tr-ui-b-chart-legend-key').property('color',series=>((this.currentHighlightedLegendKey===series.key)?series.highlightedColor:series.color)).property('width',this.margin.right).property('target',series=>series.target).property('title',series=>series.title).property('optional',series=>series.optional).property('enabled',series=>series.enabled).text(series=>series.key);legendEntriesSel.exit().remove();},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_){return this.tempHighlightedLegendKey_;}
+return this.highlightedLegendKey_;},pushTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_){throw new Error('push cannot nest');}
+this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_!==key){throw new Error('pop cannot happen');}
+this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_(){const chartAreaSel=d3.select(this.chartAreaElement);const legendEntriesSel=chartAreaSel.selectAll('.legend');const getDataSeries=chart.getDataSeries.bind(chart);const currentHighlightedLegendKey=chart.currentHighlightedLegendKey;legendEntriesSel.each(function(key){const dataSeries=getDataSeries(key);if(key===currentHighlightedLegendKey){this.style.fill=dataSeries.highlightedColor;this.style.fontWeight='bold';}else{this.style.fill=dataSeries.color;this.style.fontWeight='';}});}};return{ChartBase,DataSeriesEnableChangeEventType,getColorOfKey,getSVGTextSize,};});'use strict';tr.exportTo('tr.ui.b',function(){const D3_Y_AXIS_WIDTH_PX=9;const D3_X_AXIS_HEIGHT_PX=23;function sanitizePower(x,defaultValue){if(!isNaN(x)&&isFinite(x)&&(x!==0))return x;return defaultValue;}
+const ChartBase2D=tr.ui.b.define('chart-base-2d',tr.ui.b.ChartBase);ChartBase2D.prototype={__proto__:tr.ui.b.ChartBase.prototype,decorate(){super.decorate();Polymer.dom(this).classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleBase_=10;this.yLogScaleMin_=undefined;this.autoDataRange_=new tr.b.math.Range();this.overrideDataRange_=undefined;this.hideXAxis_=false;this.hideYAxis_=false;this.data_=[];this.xAxisLabel_='';this.yAxisLabel_='';this.textHeightPx_=0;this.unit_=undefined;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get yLogScaleBase(){return this.yLogScaleBase_;},set yLogScaleBase(b){this.yLogScaleBase_=b;},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();},get xAxisLabel(){return this.xAxisLabel_;},set xAxisLabel(label){this.xAxisLabel_=label;},get yAxisLabel(){return this.yAxisLabel_;},set yAxisLabel(label){this.yAxisLabel_=label;},get hideXAxis(){return this.hideXAxis_;},set hideXAxis(h){this.hideXAxis_=h;this.updateContents_();},get hideYAxis(){return this.hideYAxis_;},set hideYAxis(h){this.hideYAxis_=h;this.updateContents_();},get data(){return this.data_;},set data(data){if(data===undefined){throw new Error('data must be an Array');}
+this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale){this.yScale_=d3.scale.log().base(this.yLogScaleBase);}else{this.yScale_=d3.scale.linear();}
+this.isYLogScale_=logScale;},getYScaleMin_(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_(minValue,maxValue){if(this.overrideDataRange_!==undefined){return[this.dataRange.min,this.dataRange.max];}
+if(this.isYLogScale_){return[this.getYScaleMin_(),maxValue];}
+return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_(data,index,leftSide){let leftIndex;let rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+const leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);const rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+this.getXForDatum_(data[index],index);return tr.b.math.Statistics.mean([leftWidth,rightWidth]);},updateSeriesKeys_(){this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key)){this.getDataSeries(key);}},this);},this);},isDatumFieldSeries_(fieldName){return fieldName!=='x';},getXForDatum_(datum,index){return datum.x;},updateMargins_(){this.margin.left=this.hideYAxis?0:this.yAxisWidth;this.margin.bottom=this.hideXAxis?0:this.xAxisHeight;if(this.hideXAxis&&!this.hideYAxis){this.margin.bottom=10;}
+if(this.hideYAxis&&!this.hideXAxis){this.margin.left=10;}
+this.margin.top=this.hideYAxis?0:10;if(this.yAxisLabel){this.margin.top+=this.textHeightPx_;}
+if(this.xAxisLabel){this.margin.right=Math.max(this.margin.right,16+tr.ui.b.getSVGTextSize(this,this.xAxisLabel).width);}
+super.updateMargins_();},get xAxisHeight(){return D3_X_AXIS_HEIGHT_PX;},computeScaleTickWidth_(scale){if(this.data.length===0)return 0;let tickValues=scale.ticks();let tickFormat=scale.tickFormat();if(this.isYLogScale_){const enclosingPowers=this.dataRange.enclosingPowers();tickValues=[];const maxPower=sanitizePower(enclosingPowers.max,this.yLogScaleBase);for(let power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=this.yLogScaleBase){tickValues.push(power);}
+tickFormat=v=>v.toString();}
+if(this.unit){tickFormat=v=>this.unit.format(v);}
+let maxTickWidth=0;for(const tickValue of tickValues){maxTickWidth=Math.max(maxTickWidth,tr.ui.b.getSVGTextSize(this,tickFormat(tickValue)).width);}
+return D3_Y_AXIS_WIDTH_PX+maxTickWidth;},get yAxisWidth(){return this.computeScaleTickWidth_(this.yScale_);},updateScales_(){if(this.data_.length===0)return;this.xScale_.range([0,this.graphWidth]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));this.yScale_.range([this.graphHeight,0]);this.yScale_.domain([this.dataRange.min,this.dataRange.max]);},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();},updateXAxis_(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;if(this.hideXAxis)return;this.drawXAxis_(xAxis);const label=xAxis.append('text').attr('class','label');this.drawXAxisTicks_(xAxis);this.drawXAxisLabel_(label);xAxis[0][0].style.opacity=1;},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));},drawXAxisLabel_(label){label.attr('x',this.graphWidth+16).attr('y',8).text(this.xAxisLabel);},drawXAxisTicks_(xAxis){let previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){const currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){const currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});},set overrideDataRange(range){this.overrideDataRange_=range;},get dataRange(){if(this.overrideDataRange_!==undefined){return this.overrideDataRange_;}
+return this.autoDataRange_;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;const dataBySeriesKey=this.getDataBySeriesKey_();this.autoDataRange_.reset();for(const[series,values]of Object.entries(dataBySeriesKey)){for(let i=0;i<values.length;i++){this.autoDataRange_.addValue(values[i][series]);}}
+this.yLogScaleMin_=undefined;if(this.autoDataRange_.min!==undefined){let minValue=this.autoDataRange_.min;if(minValue===0){minValue=1;}
+const onePowerLess=tr.b.math.lesserPower(minValue/this.yLogScaleBase);this.yLogScaleMin_=onePowerLess;}},updateYAxis_(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;if(this.hideYAxis)return;this.drawYAxis_(yAxis);this.drawYAxisTicks_(yAxis);const label=yAxis.append('text').attr('class','label');this.drawYAxisLabel_(label);},drawYAxis_(yAxis){let axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');let tickFormat;if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)return;const tickValues=[];const enclosingPowers=this.dataRange.enclosingPowers();const maxPower=sanitizePower(enclosingPowers.max,this.yLogScaleBase);for(let power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=this.yLogScaleBase){tickValues.push(power);}
+axisModifier=axisModifier.tickValues(tickValues);tickFormat=v=>v.toString();}
+if(this.unit){tickFormat=v=>this.unit.format(v);}
+if(tickFormat){axisModifier=axisModifier.tickFormat(tickFormat);}
+yAxis.call(axisModifier);},drawYAxisLabel_(label){const labelWidthPx=Math.ceil(tr.ui.b.getSVGTextSize(this.chartAreaElement,this.yAxisLabel).width);label.attr('x',-labelWidthPx).attr('y',-8).text(this.yAxisLabel);},drawYAxisTicks_(yAxis){let previousTop=undefined;yAxis.selectAll('.tick')[0].forEach(function(tick){const bbox=tick.getBBox();const currentTop=tick.transform.baseVal[0].matrix.f;const currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});yAxis[0][0].style.opacity=1;},updateContents_(){if(this.textHeightPx_===0){this.textHeightPx_=tr.ui.b.getSVGTextSize(this,'Ay').height;}
+this.updateScales_();super.updateContents_();const chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_(){const dataBySeriesKey={};for(const[key,series]of this.seriesByKey_){dataBySeriesKey[key]=[];}
+this.data_.forEach(function(multiSeriesDatum,index){const x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')return;if(multiSeriesDatum[seriesKey]===undefined)return;if(!this.isDatumFieldSeries_(seriesKey))return;const singleSeriesDatum={x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getChartPointAtClientPoint_(clientPoint){const rect=this.getBoundingClientRect();return{x:clientPoint.x-rect.left-this.margin.left,y:clientPoint.y-rect.top-this.margin.top};},getDataPointAtChartPoint_(chartPoint){return{x:tr.b.math.clamp(this.xScale_.invert(chartPoint.x),this.xScale_.domain()[0],this.xScale_.domain()[1]),y:tr.b.math.clamp(this.yScale_.invert(chartPoint.y),this.yScale_.domain()[0],this.yScale_.domain()[1])};},getDataPointAtClientPoint_(clientX,clientY){const chartPoint=this.getChartPointAtClientPoint_({x:clientX,y:clientY});return this.getDataPointAtChartPoint_(chartPoint);},prepareDataEvent_(mouseEvent,dataEvent){const dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;Polymer.dom(this).classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+const dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);Polymer.dom(this).classList.remove('updating-brushing-state');}};return{ChartBase2D,};});'use strict';tr.exportTo('tr.ui.b',function(){const ChartBase2D=tr.ui.b.ChartBase2D;const ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate(){super.decorate();this.brushedRange_=new tr.b.math.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},get brushedRange(){return tr.b.math.Range.fromDict(this.brushedRange_.toJSON());},computeBrushRangeFromIndices(indexA,indexB){indexA=tr.b.math.clamp(indexA,0,this.data_.length-1);indexB=tr.b.math.clamp(indexB,0,this.data_.length-1);const leftIndex=Math.min(indexA,indexB);const rightIndex=Math.max(indexA,indexB);const brushRange=new tr.b.math.Range();brushRange.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+this.getSampleWidth_(this.data_,leftIndex,true));brushRange.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
+this.getSampleWidth_(this.data_,rightIndex,false));return brushRange;},getDataIndex_(dataX){if(this.data.length===0)return undefined;const bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined){dataEvent.data=this.data_[dataEvent.index];}},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();const brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];const brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();this.drawBrush_(brushRectsSel);},drawBrush_(brushRectsSel){brushRectsSel.attr('x',d=>this.xScale_(d.min)).attr('y',0).attr('width',d=>this.xScale_(d.max)-this.xScale_(d.min)).attr('height',this.graphHeight);}};return{ChartBase2DBrushX,};});'use strict';tr.exportTo('tr.ui.b',function(){const ColumnChart=tr.ui.b.define('column-chart',tr.ui.b.ChartBase2DBrushX);ColumnChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.xCushion_=1;this.isStacked_=false;this.enableHoverBox=true;this.displayXInHover=false;},set isStacked(stacked){this.isStacked_=true;this.updateContents_();},get isStacked(){return this.isStacked_;},get defaultGraphHeight(){return 100;},get defaultGraphWidth(){return 10*this.data_.length;},updateScales_(){if(this.data_.length===0)return;let xDifferences=0;let currentX=undefined;let previousX=undefined;this.data_.forEach(function(datum,index){previousX=currentX;currentX=this.getXForDatum_(datum,index);if(previousX!==undefined){xDifferences+=currentX-previousX;}},this);this.xScale_.range([0,this.graphWidth]);const domain=d3.extent(this.data_,this.getXForDatum_.bind(this));if(this.data_.length>1){this.xCushion_=xDifferences/(this.data_.length-1);}
+this.xScale_.domain([domain[0],domain[1]+this.xCushion_]);this.yScale_.range([this.graphHeight,0]);this.yScale_.domain(this.getYScaleDomain_(this.dataRange.min,this.dataRange.max));},updateDataRange_(){if(!this.isStacked){super.updateDataRange_();return;}
+this.autoDataRange_.reset();this.autoDataRange_.addValue(0);for(const datum of this.data_){let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined){continue;}
+sum+=datum[key];}
+this.autoDataRange_.addValue(sum);}},getStackedRectsForDatum_(datum,index){const stacks=[];let bottom=this.yScale_.range()[0];let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
+sum+=this.dataRange.clamp(datum[key]);const heightPx=bottom-this.yScale_(sum);bottom-=heightPx;stacks.push({key,value:datum[key],color:this.getDataSeries(key).color,heightPx,topPx:bottom,underflow:sum<this.dataRange.min,overflow:sum>this.dataRange.max,});}
+return stacks;},getRectsForDatum_(datum,index){if(this.isStacked){return this.getStackedRectsForDatum_(datum,index);}
+const stacks=[];for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
+const clampedValue=this.dataRange.clamp(datum[key]);const topPx=this.yScale_(Math.max(clampedValue,this.getYScaleMin_()));stacks.push({key,value:datum[key],topPx,heightPx:this.yScale_.range()[0]-topPx,color:this.getDataSeries(key).color,underflow:datum[key]<this.dataRange.min,overflow:datum[key]>this.dataRange.max,});}
+stacks.sort(function(a,b){return b.topPx-a.topPx;});return stacks;},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width+5;keyHeightPx=this.textHeightPx_;}
+let xLabelWidthPx=0;let xLabelHeightPx=0;if(this.displayXInHover){xLabelWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.datum.x).width+5;xLabelHeightPx=this.textHeightPx_;}
+let value=rect.value;if(this.unit)value=this.unit.format(value);const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,value).width+5;const valueHeightPx=this.textHeightPx_;const hoverWidthPx=Math.max(keyWidthPx,valueWidthPx,xLabelWidthPx);let hoverLeftPx=rect.leftPx+(rect.widthPx/2);hoverLeftPx=Math.max(hoverLeftPx-hoverWidthPx,-this.margin.left);const hoverHeightPx=keyHeightPx+valueHeightPx+xLabelHeightPx+2;let hoverTopPx=rect.topPx;hoverTopPx=Math.min(hoverTopPx,this.getBoundingClientRect().height-hoverHeightPx-12);chartAreaSel.append('rect').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).attr('fill','white').attr('stroke','black').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',hoverHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-2).text(rect.key);}
+if(this.displayXInHover){chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+xLabelHeightPx-2).text(rect.datum.x);}
+chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+hoverHeightPx-2).text(value);},clearHoverValueBox_(rect){const event=window.event;if(event.relatedTarget&&Array.from(event.relatedTarget.classList).includes('hover')){return;}
+const rectHoverEvent=new tr.b.Event('rect-mouseleave');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);d3.select(this.chartAreaElement).selectAll('.hover').remove();},drawRect_(rect,sel){sel=sel.data([rect]);sel.enter().append('rect').attr('fill',rect.color).attr('x',rect.leftPx).attr('y',rect.topPx).attr('width',rect.widthPx).attr('height',rect.heightPx).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawUnderflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',this.graphHeight).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',0);sel.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const chartAreaSel=d3.select(this.chartAreaElement);const seriesKeys=[...this.seriesByKey_.keys()];const rectsSel=dataSel.selectAll('path');this.data_.forEach(function(datum,index){const currentX=this.getXForDatum_(datum,index);let width=undefined;if(index<(this.data_.length-1)){const nextX=this.getXForDatum_(this.data_[index+1],index+1);width=nextX-currentX;}else{width=this.xCushion_;}
+for(const rect of this.getRectsForDatum_(datum,index)){rect.datum=datum;rect.index=index;rect.leftPx=this.xScale_(currentX);rect.rightPx=this.xScale_(currentX+width);rect.widthPx=rect.rightPx-rect.leftPx;this.drawRect_(rect,rectsSel);if(rect.underflow){this.drawUnderflow_(rect,rectsSel);}
+if(rect.overflow){this.drawOverflow_(rect,rectsSel);}}},this);}};return{ColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.define('line-chart',tr.ui.b.ChartBase2DBrushX);LineChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.enableHoverBox=true;this.displayXInHover=false;},get defaultGraphWidth(){return 20*this.data_.length;},get defaultGraphHeight(){return 100;},drawHoverValueBox_(circle){tr.ui.b.ColumnChart.prototype.drawHoverValueBox_.call(this,circle);},clearHoverValueBox_(circle){tr.ui.b.ColumnChart.prototype.clearHoverValueBox_.call(this,circle);},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const dataBySeriesKey=this.getDataBySeriesKey_();const seriesKeys=[...this.seriesByKey_.keys()];const pathsSel=dataSel.selectAll('path').data(seriesKeys);pathsSel.enter().append('path').style('fill','none').style('stroke-width','1.5px').style('stroke',key=>this.getDataSeries(key).color).attr('d',key=>{const line=d3.svg.line().x(d=>this.xScale_(d.x)).y(d=>this.yScale_(this.dataRange.clamp(d[key])));return line(dataBySeriesKey[key]);});pathsSel.exit().remove();if(this.enableHoverBox){for(let index=0;index<this.data_.length;++index){const datum=this.data_[index];const x=this.getXForDatum_(datum,index);for(const[key,value]of Object.entries(datum)){if(key==='x')continue;if(value===undefined)continue;const color=this.getDataSeries(key).color;const circle=document.createElementNS('http://www.w3.org/2000/svg','circle');circle.setAttribute('cx',this.xScale_(x));circle.setAttribute('cy',this.yScale_(this.dataRange.clamp(value)));circle.setAttribute('r',5);circle.style.fill=color;circle.datum=datum;circle.key=key;circle.value=datum[key];circle.leftPx=this.xScale_(x);circle.widthPx=0;circle.color=color;circle.topPx=this.yScale_(this.dataRange.clamp(value));circle.heightPx=0;circle.addEventListener('mouseenter',()=>this.drawHoverValueBox_(circle));circle.addEventListener('mouseleave',()=>this.clearHoverValueBox_(circle));dataSel[0][0].appendChild(circle);}}}}};return{LineChart,};});'use strict';Polymer({is:'tr-ui-e-s-input-latency-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
+this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_(){if(this.latencyChart_===undefined)return;let r=new tr.b.math.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;let latencySlices=[];for(const thread of this.model_.getAllThreads()){for(const event of thread.getDescendantEvents()){if(event.title.indexOf('InputLatency:')===0){latencySlices.push(event);}}}
+latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button===undefined)return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_(){const browserProcess=this.modelHelper_.browserProcess;const labels=[];if(browserProcess!==undefined){const labelStr='Browser: '+browserProcess.pid;labels.push({label:labelStr,value:browserProcess.pid});}
+for(const rendererHelper of
+Object.values(this.modelHelper_.rendererHelpers)){const rendererProcess=rendererHelper.process;const labelStr='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:labelStr,value:rendererProcess.userFriendlyName});}
+if(labels.length===0)return;this.selectedProcessId_=labels[0].value;const toolbarEl=this.$.toolbar;Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
+return this.rangeOfInterest_;},createLatencyLineChart(data,title,parentNode){const chart=new tr.ui.b.LineChart();Polymer.dom(parentNode).appendChild(chart);let width=600;if(document.body.clientWidth!==undefined){width=document.body.clientWidth*0.5;}
+chart.graphWidth=width;chart.chartTitle=title;chart.data=data;return chart;},updateContents_(){const resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;Polymer.dom(resultArea).textContent='';if(this.modelHelper_===undefined)return;const rangeOfInterest=this.currentRangeOfInterest;let chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_]){chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];}else{chromeProcess=this.modelHelper_.browserHelper;}
+const frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);const frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);const averageFrametime=tr.b.math.Statistics.mean(frametimeData,d=>d.frametime);const latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);const latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});const averageLatency=tr.b.math.Statistics.mean(latencyData,function(d){return d.latency;});const latencySummaryText=document.createElement('div');Polymer.dom(latencySummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));Polymer.dom(resultArea).appendChild(latencySummaryText);const frametimeSummaryText=document.createElement('div');Polymer.dom(frametimeSummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));Polymer.dom(resultArea).appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time',resultArea);this.registerMouseEventForLatencyChart_();}
+if(frametimeData.length!==0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times',resultArea);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
+if(!tr.model.helpers.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
+const modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-input-latency-side-panel');});'use strict';tr.exportTo('tr.e.system_stats',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
+SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize(){if(this.args.length===0){throw new Error('No system stats snapshot data.');}
+this.stats_=this.args;},getStats(){return this.stats_;},setStats(stats){this.stats_=stats;}};ObjectSnapshot.subTypes.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const constants={HEADING_WIDTH:250};return{constants,};});'use strict';Polymer({is:'tr-ui-b-heading',DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_(){this.dispatchEvent(new tr.b.Event('heading-clicked',true));},updateContents_(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+if(this.arrowVisible_){Polymer.dom(this.$.arrow).textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;Polymer.dom(this.$.link).textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';Polymer.dom(this.$.heading_content).textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){const Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined){throw new Error('viewport is required when creating a Track.');}
+this.viewport_=viewport;Polymer.dom(this).classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){if(this instanceof tr.ui.tracks.DrawingContainer)return this;let cur=this.parentElement;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)return cur;cur=cur.parentElement;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer(){const dc=this.drawingContainer;if(dc)dc.invalidate();},context(){if(!Polymer.dom(this).parentNode)return undefined;if(!Polymer.dom(this).parentNode.context){throw new Error('Parent container does not support context() method.');}
+return Polymer.dom(this).parentNode.context();},decorateChild_(childTrack){},undecorateChild_(childTrack){if(childTrack.detach){childTrack.detach();}},updateContents_(){},drawTrack(type){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw(type,viewLWorld,viewRWorld){},addEventsToTrackMap(eventToTrackMap){},addContainersToTrackMap(containerToTrackMap){},addIntersectingEventsInRangeToSelection(loVX,hiVX,loVY,hiVY,selection){const pixelRatio=window.devicePixelRatio||1;const dt=this.viewport.currentDisplayTransform;const viewPixWidthWorld=dt.xViewVectorToWorld(1);const loWX=dt.xViewToWorld(loVX*pixelRatio);const hiWX=dt.xViewToWorld(hiVX*pixelRatio);const clientRect=this.getBoundingClientRect();const a=Math.max(loVY,clientRect.top);const b=Math.min(hiVY,clientRect.bottom);if(a>b)return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection(instantEvents,worldX,worldMaxDist,selection){const instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)return;selection.push(instantEvent);}};return{Track,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const EventPresenter=tr.ui.b.EventPresenter;const ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length===0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].baseTypeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawObjectInstances_(viewLWorld,viewRWorld);break;}},drawObjectInstances_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=dt.xViewVectorToWorld(height);const objectInstances=this.objectInstances_;let loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.save();ctx.strokeStyle='rgb(0,0,0)';for(let i=loI;i<objectInstances.length;++i){const instance=objectInstances[i];const x=instance.creationTs;if(x>viewRWorld)break;const right=instance.deletionTs===Number.MAX_VALUE?viewRWorld:instance.deletionTs;const xView=dt.xWorldToView(x);const widthView=dt.xWorldVectorToView(right-x);ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(xView,pixelRatio,widthView,height-2*pixelRatio);}
+ctx.restore();const objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(let i=loI;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)break;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;let selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){const width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){let foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,(value)=>{selection.push(value);});},addEventNearToProvidedEventToSelection(event,offset,selection){let events;if(event instanceof tr.model.ObjectSnapshot){events=this.objectSnapshots_;}else if(event instanceof tr.model.ObjectInstance){events=this.objectInstances_;}else{throw new Error('Unrecognized event');}
+const index=events.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap(eventToTrackMap){const objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+const snapshots=this.objectInstance_.snapshots;const maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i===snapshots.length-1){if(snapshots.length===1){return maxBounds;}
+return snapshots[i].ts-snapshots[i-1].ts;}
+return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot)){throw new Error('Unrecognized event');}
+const objectSnapshots=this.objectInstance_.snapshots;const index=objectSnapshots.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};return{StackedBarsTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const EventPresenter=tr.ui.b.EventPresenter;let statCount;const excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};const SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!==1){throw new Error('Bad object instance count.');}
+this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_(snapshots){for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();let prevSnapshot;if(i===0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
+const prevStats=prevSnapshot.getStats();let timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds===0){timeIntervalSeconds=1;}
+this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_(prevStats,stats,timeIntervalSeconds){for(const statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName==='sectors_read'){stats.bytes_read_per_sec=(stats.sectors_read-
+prevStats.sectors_read)*512/timeIntervalSeconds;}
+if(statName==='sectors_written'){stats.bytes_written_per_sec=(stats.sectors_written-
+prevStats.sectors_written)*512/timeIntervalSeconds;}
+if(statName==='pgmajfault'){stats.pgmajfault_per_sec=(stats.pgmajfault-
+prevStats.pgmajfault)/timeIntervalSeconds;}
+if(statName==='pswpin'){stats.bytes_swpin_per_sec=(stats.pswpin-
+prevStats.pswpin)*1000/timeIntervalSeconds;}
+if(statName==='pswpout'){stats.bytes_swpout_per_sec=(stats.pswpout-
+prevStats.pswpout)*1000/timeIntervalSeconds;}}}},computeMaxStats_(snapshots){const maxStats={};statCount=0;for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
+return maxStats;},computeMaxStatsRecursive_(stats,maxStats,excludedStats){for(const statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats)){maxStats[statName]={};}
+let excludedNested;if(excludedStats&&statName in excludedStats){excludedNested=excludedStats[statName];}else{excludedNested=null;}
+this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats){continue;}
+if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
+if(stats[statName]>maxStats[statName]){maxStats[statName]=stats[statName];}}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const width=bounds.width*pixelRatio;const height=(bounds.height*pixelRatio)/statCount;const vp=this.viewport.currentDisplayTransform;const maxStats=this.maxStats_;const objectSnapshots=this.objectInstance_.snapshots;let lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)lowIndex-=1;for(let i=lowIndex;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const trace=snapshot.getStats();const currentY=height;const left=snapshot.ts;if(left>viewRWorld)break;let leftView=vp.xWorldToView(left);if(leftView<0)leftView=0;let right;if(i!==objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1){right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);}else{right=this.objectInstance_.parent.model.bounds.max;}}
+let rightView=vp.xWorldToView(right);if(rightView>width){rightView=width;}
+leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i===lowIndex){this.drawStatNames_(leftView,height,currentY,'',maxStats);}}
+ctx.lineWidth=1;},drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats,maxStats,currentY){const ctx=this.context();for(const statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{const maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));let barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
+ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
+return currentY;},drawStatNames_(leftView,height,currentY,prefix,maxStats){const ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(const statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{let fullname=statName;if(prefix!==''){fullname=prefix+' :: '+statName;}
+ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents(){const snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){Polymer.dom(this).textContent='No system stats snapshot found.';return;}
+Polymer.dom(this).textContent='';const stats=snapshot.getStats();Polymer.dom(this).appendChild(this.buildList_(stats));},isFloat(n){return typeof n==='number'&&n%1!==0;},buildList_(stats){const statList=document.createElement('ul');for(const statName in stats){const statText=document.createElement('li');Polymer.dom(statText).textContent=''+statName+': ';Polymer.dom(statList).appendChild(statText);if(stats[statName]instanceof Object){Polymer.dom(statList).appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName])){Polymer.dom(statText).textContent+=stats[statName].toFixed(2);}else{Polymer.dom(statText).textContent+=stats[statName];}}}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const IGNORED_ENTRIES={match:full=>full.startsWith('*CODE_AGE_')};const INSTANCE_TYPE_GROUPS={FIXED_ARRAY_TYPE:{match:full=>full.startsWith('*FIXED_ARRAY_'),realEntry:'FIXED_ARRAY_TYPE',keyToName:key=>key.slice('*FIXED_ARRAY_'.length).slice(0,-('_SUB_TYPE'.length)),nameToKey:name=>'*FIXED_ARRAY_'+name+'_SUB_TYPE'},CODE_TYPE:{match:full=>full.startsWith('*CODE_'),realEntry:'CODE_TYPE',keyToName:key=>key.slice('*CODE_'.length),nameToKey:name=>'*CODE_'+name},JS_OBJECTS:{match:full=>full.startsWith('JS_'),keyToName:key=>key,nameToKey:name=>name},Strings:{match:full=>full.endsWith('STRING_TYPE'),keyToName:key=>key,nameToKey:name=>name}};const DIFF_COLOR={GREEN:'#64DD17',RED:'#D50000'};function computePercentage(valueA,valueB){if(valueA===0)return 0;return valueA/valueB*100;}
+class DiffEntry{constructor(originalEntry,diffEntry){this.originalEntry_=originalEntry;this.diffEntry_=diffEntry;}
+get title(){return this.diffEntry_.title;}
+get overall(){return this.diffEntry_.overall;}
+get overAllocated(){return this.diffEntry_.overAllocated;}
+get count(){return this.diffEntry_.count;}
+get overallPercent(){return this.diffEntry_.overallPercent;}
+get overAllocatedPercent(){return this.diffEntry_.overAllocatedPercent;}
+get origin(){return this.originalEntry_;}
+get diff(){return this.diffEntry_;}
+get subRows(){return this.diffEntry_.subRows;}}
+class Entry{constructor(title,count,overall,overAllocated,histogram,overAllocatedHistogram){this.title_=title;this.overall_=overall;this.count_=count;this.overAllocated_=overAllocated;this.histogram_=histogram;this.overAllocatedHistogram_=overAllocatedHistogram;this.bucketSize_=this.histogram_.length;this.overallPercent_=100;this.overAllocatedPercent_=100;}
+get title(){return this.title_;}
+get overall(){return this.overall_;}
+get count(){return this.count_;}
+get overAllocated(){return this.overAllocated_;}
+get histogram(){return this.histogram_;}
+get overAllocatedHistogram(){return this.overAllocatedHistogram_;}
+get bucketSize(){return this.bucketSize_;}
+get overallPercent(){return this.overallPercent_;}
+set overallPercent(value){this.overallPercent_=value;}
+get overAllocatedPercent(){return this.overAllocatedPercent_;}
+set overAllocatedPercent(value){this.overAllocatedPercent_=value;}
+setFromObject(obj){this.count_=obj.count;this.overall_=obj.overall/1024;this.overAllocated_=obj.over_allocated/1024;this.histogram_=obj.histogram;this.overAllocatedHistogram_=obj.over_allocated_histogram;}
+diff(other){const entry=new Entry(this.title_,other.count_-this.count,other.overall_-this.overall,other.overAllocated_-this.overAllocated,[],[]);entry.overallPercent=computePercentage(entry.overall,this.overall);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated);return new DiffEntry(this,entry);}}
+class GroupedEntry extends Entry{constructor(title,count,overall,overAllocated,histogram,overAllocatedHistogram){super(title,count,overall,overAllocated,histogram,overAllocatedHistogram);this.histogram_.fill(0);this.overAllocatedHistogram_.fill(0);this.entries_=new Map();}
+get title(){return this.title_;}
+set title(value){this.title_=value;}
+get subRows(){return Array.from(this.entries_.values());}
+getEntryFromTitle(title){return this.entries_.get(title);}
+add(entry){this.count_+=entry.count;this.overall_+=entry.overall;this.overAllocated_+=entry.overAllocated;if(this.bucketSize_===entry.bucketSize){for(let i=0;i<this.bucketSize_;++i){this.histogram_[i]+=entry.histogram[i];this.overAllocatedHistogram_[i]+=entry.overAllocatedHistogram[i];}}
+this.entries_.set(entry.title,entry);}
+accumulateUnknown(title){let unknownCount=this.count_;let unknownOverall=this.overall_;let unknownOverAllocated=this.overAllocated_;const unknownHistogram=tr.b.deepCopy(this.histogram_);const unknownOverAllocatedHistogram=tr.b.deepCopy(this.overAllocatedHistogram_);for(const entry of this.entries_.values()){unknownCount-=entry.count;unknownOverall-=entry.overall;unknownOverAllocated-=entry.overAllocated;for(let i=0;i<this.bucketSize_;++i){unknownHistogram[i]-=entry.histogram[i];unknownOverAllocatedHistogram[i]-=entry.overAllocatedHistogram[i];}}
+unknownOverAllocated=unknownOverAllocated<0?0:unknownOverAllocated;this.entries_.set(title,new Entry(title,unknownCount,unknownOverall,unknownOverAllocated,unknownHistogram,unknownOverAllocatedHistogram));}
+calculatePercentage(){for(const entry of this.entries_.values()){entry.overallPercent=computePercentage(entry.overall,this.overall_);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated_);if(entry instanceof GroupedEntry)entry.calculatePercentage();}}
+diff(other){let newTitle='';if(this.title_.startsWith('Isolate')){newTitle='Total';}else{newTitle=this.title_;}
+const result=new GroupedEntry(newTitle,0,0,0,[],[]);for(const entry of this.entries_){const otherEntry=other.getEntryFromTitle(entry[0]);if(otherEntry===undefined)continue;result.add(entry[1].diff(otherEntry));}
+result.overallPercent=computePercentage(result.overall,this.overall);result.overAllocatedPercent=computePercentage(result.overAllocated,this.overAllocated);return new DiffEntry(this,result);}}
+function createSelector(targetEl,defaultValue,items,callback){const selectorEl=document.createElement('select');selectorEl.addEventListener('change',callback.bind(targetEl));const defaultOptionEl=document.createElement('option');for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+selectorEl.__defineGetter__('selectedValue',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
+return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
+return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(value===v){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;callback();}
+return;}}
+throw new Error('Not a valid value');});selectorEl.selectedIndex=-1;return selectorEl;}
+function plusMinus(value,toFixed=3){return(value>0?'+':'')+value.toFixed(toFixed);}
+function addArrow(value){if(value===0)return value;if(value===Number.NEGATIVE_INFINITY)return'\u2193\u221E';if(value===Number.POSITIVE_INFINITY)return'\u2191\u221E';return(value>0?'\u2191':'\u2193')+Math.abs(value.toFixed(3));}
+Polymer({is:'tr-ui-e-v8-gc-objects-stats-table',ready(){this.$.diffOption.style.display='none';this.isolateEntries_=[];this.selector1_=undefined;this.selector2_=undefined;},constructDiffTable_(table){this.$.diffTable.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.diffTable.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overall.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overall-b.origin.overall;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overall);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overallPercent);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overAllocated.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overAllocated-b.origin.overAllocated;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overAllocated);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overAllocatedPercent);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Count',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.count;return spanEl;},cmp(a,b){return a.origin.count-b.origin.count;}},{title:'diff',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.count,0);if(row.count>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.count<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.count-b.count;}},];},buildOptions_(){const items=[];for(const isolateEntry of this.isolateEntries_){items.push({label:isolateEntry.title,value:isolateEntry});}
+this.$.diffOption.style.display='inline-block';this.selector1_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector1_);const spanEl=tr.ui.b.createSpan();spanEl.innerText=' VS ';Polymer.dom(this.$.diffOption).appendChild(spanEl);this.selector2_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector2_);},diffOptionChanged_(){const isolateEntry1=this.selector1_.selectedValue;const isolateEntry2=this.selector2_.selectedValue;if(isolateEntry1===undefined||isolateEntry2===undefined){return;}
+if(isolateEntry1===isolateEntry2){this.$.diffTable.tableRows=[];this.$.diffTable.rebuild();return;}
+this.$.diffTable.tableRows=[isolateEntry1.diff(isolateEntry2)];this.$.diffTable.rebuild();},constructTable_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overall.toFixed(3);return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocated.toFixed(3);return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Overall Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},cmp(a,b){return a.count-b.count;}},{title:'Overall Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overallPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Overall Allocated Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocatedPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}}];this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;},buildSubEntry_(objects,groupEntry,keyToName){const typeGroup=INSTANCE_TYPE_GROUPS[groupEntry.title];for(const instanceType of typeGroup){const e=objects[instanceType];if(e===undefined)continue;delete objects[instanceType];let title=instanceType;if(keyToName!==undefined)title=keyToName(title);groupEntry.add(new Entry(title,e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));}},buildUnGroupedEntries_(objects,objectEntry,bucketSize){for(const title of Object.getOwnPropertyNames(objects)){const obj=objects[title];const groupedEntry=new GroupedEntry(title,0,0,0,new Array(bucketSize),new Array(bucketSize));groupedEntry.setFromObject(obj);objectEntry.add(groupedEntry);}},createGroupEntries_(groupEntries,objects,bucketSize){for(const groupName of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const groupEntry=new GroupedEntry(groupName,0,0,0,new Array(bucketSize),new Array(bucketSize));if(INSTANCE_TYPE_GROUPS[groupName].realEntry!==undefined){groupEntry.savedRealEntry=objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];delete objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];}
+groupEntries[groupName]=groupEntry;}},buildGroupEntries_(groupEntries,objectEntry){for(const groupName of Object.getOwnPropertyNames(groupEntries)){const groupEntry=groupEntries[groupName];if(groupEntry.savedRealEntry!==undefined){groupEntry.setFromObject(groupEntry.savedRealEntry);groupEntry.accumulateUnknown('UNKNOWN');delete groupEntry.savedRealEntry;}
+objectEntry.add(groupEntry);}},buildSubEntriesForGroups_(groupEntries,objects){for(const instanceType of Object.getOwnPropertyNames(objects)){if(IGNORED_ENTRIES.match(instanceType)){delete objects[instanceType];continue;}
+const e=objects[instanceType];for(const name of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const group=INSTANCE_TYPE_GROUPS[name];if(group.match(instanceType)){groupEntries[name].add(new Entry(group.keyToName(instanceType),e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));delete objects[instanceType];}}}},build_(objects,objectEntry,bucketSize){delete objects.END;const groupEntries={};this.createGroupEntries_(groupEntries,objects,bucketSize);this.buildSubEntriesForGroups_(groupEntries,objects);this.buildGroupEntries_(groupEntries,objectEntry);this.buildUnGroupedEntries_(objects,objectEntry,bucketSize);},set selection(slices){slices.sortEvents(function(a,b){return b.start-a.start;});const previous=undefined;for(const slice of slices){if(!slice instanceof tr.e.v8.V8GCStatsThreadSlice)continue;const liveObjects=slice.liveObjects;const deadObjects=slice.deadObjects;const isolate=liveObjects.isolate;const isolateEntry=new GroupedEntry('Isolate_'+isolate+' at '+slice.start.toFixed(3)+' ms',0,0,0,[],[]);const liveEntry=new GroupedEntry('live objects',0,0,0,[],[]);const deadEntry=new GroupedEntry('dead objects',0,0,0,[],[]);const liveBucketSize=liveObjects.bucket_sizes.length;const deadBucketSize=deadObjects.bucket_sizes.length;this.build_(tr.b.deepCopy(liveObjects.type_data),liveEntry,liveBucketSize);isolateEntry.add(liveEntry);this.build_(tr.b.deepCopy(deadObjects.type_data),deadEntry,deadBucketSize);isolateEntry.add(deadEntry);isolateEntry.calculatePercentage();this.isolateEntries_.push(isolateEntry);}
+this.updateTable_();if(slices.length>1){this.buildOptions_();this.constructDiffTable_();}},updateTable_(){this.constructTable_();this.$.table.tableRows=this.isolateEntries_;this.$.table.rebuild();},});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:true,title:'V8 GC Stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){const IC_STATS_PROPERTIES=['type','category','scriptName','filePosition','state','isNative','map','propertiesMode','numberOfOwnProperties','instanceType'];class ICStatsEntry{constructor(obj){this.type_=obj.type;if(this.type_.includes('Store')){this.category_='Store';}else if(this.type_.includes('Load')){this.category_='Load';}
+this.state_=obj.state;if(obj.functionName){this.functionName_=obj.optimized?'*':'~';this.functionName_+=obj.functionName.length===0?'(anonymous function)':obj.functionName;}
+this.offset_=obj.offset;this.scriptName_=obj.scriptName?obj.scriptName:'unknown';this.isNative_=obj.scriptName&&obj.scriptName.includes('native');this.lineNum_=obj.lineNum?obj.lineNum:'unknown';this.filePosition_=this.scriptName_+':'+this.lineNum_;if(this.functionName_){this.filePosition_+=' '+this.functionName_+'+'+this.offset_;}
+this.constructor_=obj.constructor?false:true;this.map_=obj.map;if(this.map_){this.propertiesMode_=obj.dict===0?'slow':'fast';}else{this.propertiesMode_='unknown';}
+this.numberOfOwnProperties_=obj.own;this.instanceType_=obj.instanceType;this.key_=obj.key;}
+get type(){return this.type_;}
+get category(){return this.category_;}
+get state(){return this.state_;}
+get functionName(){return this.functionName_;}
+get offset(){return this.offset_;}
+get scriptName(){return this.scriptName_;}
+get isNative(){return this.isNative_;}
+get lineNumber(){return this.lineNum_;}
+get isConstructor(){return this.constructor_;}
+get map(){return this.map_;}
+get propertiesMode(){return this.propertiesMode_;}
+get numberOfOwnProperties(){return this.numberOfOwnProperties_;}
+get instanceType(){return this.instanceType_;}
+get filePosition(){return this.filePosition_;}}
+class ICStatsEntryGroup{constructor(property,key){this.property_=property;this.key_=key;this.percentage_=0;this.entries_=[];this.subGroup_=undefined;}
+static groupBy(groups,entries,property){for(const entry of entries){const key=entry[property];let group=groups.get(key);if(!group){group=new ICStatsEntryGroup(property,key);groups.set(key,group);}
+group.add(entry);}
+for(const group of groups.values()){group.percentage=group.length/entries.length;}}
+add(entry){this.entries_.push(entry);}
+createSubGroup(){if(this.subGroup_)return this.subGroup_;this.subGroup_=new Map();for(const property of IC_STATS_PROPERTIES){if(property===this.property_)continue;const groups=new Map();this.subGroup_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);}
+return this.subGroup_;}
+get entries(){return this.entries_;}
+get key(){return this.key_;}
+get length(){return this.entries_.length;}
+get percentage(){return this.percentage_;}
+set percentage(value){this.percentage_=value;}}
+class ICStatsCollection{constructor(){this.entries_=[];this.groupedEntries_=new Map();}
+add(entry){this.entries_.push(entry);}
+groupBy(property){if(this.groupedEntries_.has(property)){return Array.from(this.groupedEntries_.get(property).values());}
+const groups=new Map();this.groupedEntries_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);return Array.from(groups.values());}
+get entries(){return this.entries_;}
+get length(){return this.entries_.length;}}
+return{IC_STATS_PROPERTIES,ICStatsEntry,ICStatsEntryGroup,ICStatsCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const PROPERTIES=tr.e.v8.IC_STATS_PROPERTIES.map(x=>{return{label:x,value:x};});const ICStatsEntry=tr.e.v8.ICStatsEntry;const ICStatsEntryGroup=tr.e.v8.ICStatsEntryGroup;const ICStatsCollection=tr.e.v8.ICStatsCollection;Polymer({is:'tr-ui-e-v8-ic-stats-table',ready(){this.icStatsCollection_=new ICStatsCollection();this.groupKey_=PROPERTIES[0].value;this.selector_=tr.ui.b.createSelector(this,'groupKey','v8ICStatsGroupKey',this.groupKey_,PROPERTIES);Polymer.dom(this.$.groupOption).appendChild(this.selector_);},get groupKey(){return this.groupKey_;},set groupKey(key){this.groupKey_=key;if(this.icStatsCollection_.length===0)return;this.updateTable_(this.groupKey_);},constructTable_(table,groupKey){table.tableColumns=[{title:'',value:row=>{let expanded=false;const buttonEl=tr.ui.b.createButton('details',function(){const previousSibling=Polymer.dom(this).parentNode.parentNode;const parentNode=previousSibling.parentNode;if(expanded){const trEls=parentNode.getElementsByClassName('subTable');Array.from(trEls).map(x=>x.parentNode.removeChild(x));expanded=false;return;}
+expanded=true;const subGroups=row.createSubGroup();const tr=document.createElement('tr');tr.classList.add('subTable');tr.appendChild(document.createElement('td'));const td=document.createElement('td');td.colSpan=3;for(const subGroup of subGroups){const property=subGroup[0];const all=Array.from(subGroup[1].values());const group=all.slice(0,20);const divEl=document.createElement('div');const spanEl=document.createElement('span');const subTableEl=document.createElement('tr-ui-b-table');spanEl.innerText=`Top 20 out of ${all.length}`;spanEl.style.fontWeight='bold';spanEl.style.fontSize='14px';divEl.appendChild(spanEl);this.constructTable_(subTableEl,property);subTableEl.tableRows=group;subTableEl.rebuild();divEl.appendChild(subTableEl);td.appendChild(divEl);}
+tr.appendChild(td);parentNode.insertBefore(tr,previousSibling.nextSibling);});return buttonEl;}},{title:'Percentage',value(row){const spanEl=document.createElement('span');spanEl.innerText=(row.percentage*100).toFixed(3)+'%';return spanEl;},cmp:(a,b)=>a.percentage-b.percentage},{title:'Count',value(row){const spanEl=document.createElement('span');spanEl.innerText=row.length;return spanEl;},cmp:(a,b)=>a.length-b.length},{title:groupKey,value(row){const spanEl=document.createElement('span');spanEl.innerText=row.key?row.key:'';return spanEl;}}];table.sortColumnIndex=1;table.sortDescending=true;},updateTable_(groupKey){this.constructTable_(this.$.table,groupKey);this.$.table.tableRows=this.icStatsCollection_.groupBy(groupKey);this.$.table.rebuild();},set selection(slices){for(const slice of slices){for(const icStatsObj of slice.icStats){const entry=new ICStatsEntry(icStatsObj);this.icStatsCollection_.add(entry);}}
+this.$.total.innerText='Total items: '+this.icStatsCollection_.length;this.updateTable_(this.selector_.selectedValue);}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:true,title:'V8 IC stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){class RuntimeStatsEntry{constructor(name,count,time){this.name_=name;this.count_=count;this.time_=time;}
+get name(){return this.name_;}
+get count(){return this.count_;}
+get time(){return this.time_;}
+addSample(count,time){this.count_+=count;this.time_+=time;}}
+class RuntimeStatsGroup extends RuntimeStatsEntry{constructor(name,matchRegex){super(name,0,0);this.regex_=matchRegex;this.entries_=new Map();}
+match(name){return this.regex_&&name.match(this.regex_);}
+add(entry){const value=this.entries_.get(entry.name);if(value!==undefined){value.addSample(entry.count,entry.time);}else{this.entries_.set(entry.name,entry);}
+this.count_+=entry.count;this.time_+=entry.time;}
+get values(){return Array.from(this.entries_.values());}}
+class RuntimeStatsGroupCollection{constructor(){this.blink_rcs_group_=new RuntimeStatsGroup('Blink RCS',/Blink_(.*)/);this.blink_cpp_group_=new RuntimeStatsGroup('Blink C++',/.*Callback.*/);this.api_group_=new RuntimeStatsGroup('API',/.*API.*/);this.groups_=[new RuntimeStatsGroup('Total'),new RuntimeStatsGroup('IC',/.*IC_.*/),new RuntimeStatsGroup('Optimize',/StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/),new RuntimeStatsGroup('Compile-Background',/(.*CompileBackground.*)/),new RuntimeStatsGroup('Compile',/(^Compile.*)|(.*_Compile.*)/),new RuntimeStatsGroup('Parse-Background',/.*ParseBackground.*/),new RuntimeStatsGroup('Parse',/.*Parse.*/),this.blink_cpp_group_,this.api_group_,new RuntimeStatsGroup('GC',/GC|AllocateInTargetSpace/),new RuntimeStatsGroup('JavaScript',/JS_Execution/),new RuntimeStatsGroup('V8 C++',/.*/)];}
+addSlices(slices){for(const slice of slices){if(!(slice instanceof tr.e.v8.V8ThreadSlice))return;let runtimeCallStats;try{runtimeCallStats=JSON.parse(slice.runtimeCallStats);}catch(e){runtimeCallStats=slice.runtimeCallStats;}
+if(runtimeCallStats===undefined)continue;for(const[name,stat]of Object.entries(runtimeCallStats)){if(this.blink_rcs_group_.match(name)){if(name==='Blink_V8')continue;const entry=new RuntimeStatsEntry(name,stat[0],stat[1]);this.blink_rcs_group_.add(entry);continue;}
+for(let i=1;i<this.groups_.length;++i){if(this.groups_[i].match(name)){if(stat.length!==2)break;const entry=new RuntimeStatsEntry(name,stat[0],stat[1]);this.groups_[0].addSample(stat[0],stat[1]);this.groups_[i].add(entry);break;}}}}}
+get totalTime(){return this.groups_[0].time;}
+get totalCount(){return this.groups_[0].count;}
+get runtimeGroups(){return this.groups_;}
+get blinkRCSGroup(){return this.blink_rcs_group_;}
+get blinkCppTotalTime(){return this.blink_cpp_group_.time+this.api_group_.time;}}
+return{RuntimeStatsEntry,RuntimeStatsGroup,RuntimeStatsGroupCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const codeSearchURL_='https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';function removeBlinkPrefix_(name){if(name.startsWith('Blink_'))name=name.substring(6);return name;}
+function handleCodeSearchForV8_(event){if(event.target.parentNode===undefined)return;let name=event.target.parentNode.entryName;if(name.startsWith('API_'))name=name.substring(4);const url=codeSearchURL_+encodeURIComponent(name)+'+file:src/v8/src';window.open(url,'_blank');}
+function handleCodeSearchForBlink_(event){if(event.target.parentNode===undefined)return;const name=event.target.parentNode.entryName;const url=codeSearchURL_+
+encodeURIComponent('RuntimeCallStats::CounterId::k'+name)+'+file:src/third_party/WebKit/|src/out/Debug/';window.open(url,'_blank');}
+function createCodeSearchEl_(handleCodeSearch){const codeSearchEl=document.createElement('span');codeSearchEl.innerText='?';codeSearchEl.style.float='right';codeSearchEl.style.borderRadius='5px';codeSearchEl.style.backgroundColor='#EEE';codeSearchEl.addEventListener('click',handleCodeSearch.bind(this));return codeSearchEl;}
+const timeColumn_={title:'Time',value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/1000.0).toFixed(3)+' ms';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}};const countColumn_={title:'Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},width:'100px',cmp(a,b){return a.count-b.count;}};function percentColumn_(title,totalTime){return{title,value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/totalTime*100).toFixed(3)+'%';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}};}
+function nameColumn_(showExpandButtons,handleCodeSearch,modifyName){return{title:'Name',value(row){const typeEl=document.createElement('span');let name=row.name;if(modifyName)name=modifyName(name);typeEl.innerText=name;if(!(row instanceof tr.e.v8.RuntimeStatsGroup)){typeEl.title='click ? for code search';typeEl.entryName=name;const codeSearchEl=createCodeSearchEl_(handleCodeSearch);typeEl.appendChild(codeSearchEl);}
+return typeEl;},width:'200px',showExpandButtons};}
+function initializeCommonOptions_(table){table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.sortColumnIndex=1;table.sortDescending=true;}
+Polymer({is:'tr-ui-e-v8-runtime-call-stats-table',ready(){this.table_=this.$.table;this.blink_rcs_table_=this.$.blink_rcs_table;this.totalTime_=0;},constructV8RCSTable_(totalTime){this.table_.tableColumns=[nameColumn_(true,handleCodeSearchForV8_),timeColumn_,countColumn_,percentColumn_('Percent',totalTime)];initializeCommonOptions_(this.table_);this.table_.subRowsPropertyName='values';},constructBlinkRCSTable_(blinkCppTotalTime){this.blink_rcs_table_.tableColumns=[nameColumn_(false,handleCodeSearchForBlink_,removeBlinkPrefix_),timeColumn_,countColumn_,percentColumn_('Percent (of \'Blink C++\' + \'API\')',blinkCppTotalTime)];initializeCommonOptions_(this.blink_rcs_table_);},set slices(slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);if(runtimeGroupCollection.totalTime>0){this.$.v8_rcs_heading.textContent='V8 Runtime Call Stats';this.constructV8RCSTable_(runtimeGroupCollection.totalTime);this.table_.tableRows=runtimeGroupCollection.runtimeGroups;this.table_.rebuild();}
+const blinkRCSGroup=runtimeGroupCollection.blinkRCSGroup;if(runtimeGroupCollection.blinkCppTotalTime>0&&blinkRCSGroup.time>0){this.$.blink_rcs_heading.textContent='Blink Runtime Call Stats';this.constructBlinkRCSTable_(runtimeGroupCollection.blinkCppTotalTime);const rows=blinkRCSGroup.values;rows.unshift(new tr.e.v8.RuntimeStatsEntry('Total',blinkRCSGroup.count,blinkRCSGroup.time));this.blink_rcs_table_.tableRows=rows;this.blink_rcs_table_.rebuild();}}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:true,title:'V8 slices'});'use strict';Polymer({is:'tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:false,title:'V8 GC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:false,title:'V8 IC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:false,title:'V8 slice'});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged(model){}};return{ScriptingObject,};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));const typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+function ScriptingObjectRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged){v.onModelChanged(this.brushingStateController.model);}},this);},addScriptObject(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand(command){const f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController,ScriptingObjectRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};tr.b.decorateExtensionRegistry(MetricRegistry,options);function camelCaseToHackerString(camelCase){let hackerString='';for(const c of camelCase){const lowered=c.toLocaleLowerCase();if(lowered===c){hackerString+=c;}else{hackerString+='_'+lowered;}}
+return hackerString;}
+function getCallStack(){try{throw new Error();}catch(error){return error.stack;}}
+function getPathsFromStack(stack){return stack.split('\n').map(line=>{line=line.replace(/^ */,'').split(':');if(line.length<4)return'';return line[line.length-3].split('/');}).filter(x=>x);}
+MetricRegistry.checkFilename=function(metricName,opt_metricPathForTest){if(metricName==='runtimeStatsTotalMetric'||metricName==='v8AndMemoryMetrics'){return;}
+const expectedFilename=camelCaseToHackerString(metricName)+'.html';const stack=getCallStack();let metricPath=opt_metricPathForTest;if(metricPath===undefined){const paths=getPathsFromStack(stack);const METRIC_STACK_INDEX=5;if(paths.length<=METRIC_STACK_INDEX||paths[METRIC_STACK_INDEX].join('/')===paths[0].join('/')){return;}
+metricPath=paths[METRIC_STACK_INDEX].slice(paths[METRIC_STACK_INDEX].length-2);}
+if(!metricPath[1].endsWith('_test.html')&&metricPath[1]!==expectedFilename&&metricPath.join('_')!==expectedFilename){throw new Error('Expected '+metricName+' to be in a file named '+
+expectedFilename+'; actual: '+metricPath.join('/')+'; stack: '+stack.replace(/\n/g,'\n  '));}};MetricRegistry.addEventListener('will-register',function(e){const metric=e.typeInfo.constructor;if(!(metric instanceof Function)){throw new Error('Metrics must be functions.');}
+if(!metric.name.endsWith('Metric')&&!metric.name.endsWith('Metrics')){throw new Error('Metric names must end with "Metric" or "Metrics".');}
+if(metric.length<2){throw new Error('Metrics take a HistogramSet and a Model and '+'optionally an options dictionary.');}
+MetricRegistry.checkFilename(metric.name);});return{MetricRegistry,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS=2000;const MIN_DRAW_DELAY_IN_MS=80;const MAX_DRAW_DELAY_IN_MS=2000;function findProcess(processName,model){for(const pid in model.processes){const process=model.processes[pid];if(process.name===processName){return process;}}
+return undefined;}
+function findThreads(process,threadPrefix){if(process===undefined)return undefined;const threads=[];for(const tid in process.threads){const thread=process.threads[tid];if(thread.name.startsWith(threadPrefix)){threads.push(thread);}}
+return threads;}
+function findUIThread(process){if(process===undefined)return undefined;const threads=findThreads(process,'UI Thread');if(threads!==undefined&&threads.length===1){return threads[0];}
+return process.threads[process.pid];}
+function findLaunchSlices(model){const launches=[];const binders=findThreads(findProcess('system_server',model),'Binder');for(const binderId in binders){const binder=binders[binderId];for(const sliceId in binder.asyncSliceGroup.slices){const slice=binder.asyncSliceGroup.slices[sliceId];if(slice.title.startsWith('launching:')){launches.push(slice);}}}
+return launches;}
+function findDrawSlice(appName,startNotBefore,model){let drawSlice=undefined;const thread=findUIThread(findProcess(appName,model));if(thread===undefined)return undefined;for(const sliceId in thread.sliceGroup.slices){const slice=thread.sliceGroup.slices[sliceId];if(slice.start<startNotBefore+MIN_DRAW_DELAY_IN_MS||slice.start>startNotBefore+MAX_DRAW_DELAY_IN_MS)continue;if(slice.title!=='draw')continue;if(drawSlice===undefined||slice.start<drawSlice.start){drawSlice=slice;}}
+return drawSlice;}
+function findInputEventSlice(endNotAfter,model){const endNotBefore=endNotAfter-MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS;let inputSlice=undefined;const systemUi=findUIThread(findProcess('com.android.systemui',model));if(systemUi===undefined)return undefined;for(const sliceId in systemUi.asyncSliceGroup.slices){const slice=systemUi.asyncSliceGroup.slices[sliceId];if(slice.end>endNotAfter||slice.end<endNotBefore)continue;if(slice.title!=='deliverInputEvent')continue;if(inputSlice===undefined||slice.end>inputSlice.end){inputSlice=slice;}}
+return inputSlice;}
+function computeStartupTimeInMs(appName,launchSlice,model){let startupStart=launchSlice.start;let startupEnd=launchSlice.end;const drawSlice=findDrawSlice(appName,launchSlice.end,model);if(drawSlice!==undefined){startupEnd=drawSlice.end;}
+const inputSlice=findInputEventSlice(launchSlice.start,model);if(inputSlice!==undefined){startupStart=inputSlice.start;}
+return startupEnd-startupStart;}
+function measureStartup(histograms,model){const launches=findLaunchSlices(model);for(const sliceId in launches){const launchSlice=launches[sliceId];const appName=launchSlice.title.split(': ')[1];const startupMs=computeStartupTimeInMs(appName,launchSlice,model);histograms.createHistogram(`android:systrace:startup:${appName}`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,startupMs);}}
+function measureThreadStates(histograms,model,rangeOfInterest){for(const pid in model.processes){const process=model.processes[pid];if(process.name===undefined)continue;let hasSlices=false;let timeRunning=0;let timeRunnable=0;let timeSleeping=0;let timeUninterruptible=0;let timeBlockIO=0;let timeUnknown=0;for(const tid in process.threads){const thread=process.threads[tid];if(thread.timeSlices===undefined)continue;for(const sliceId in thread.timeSlices){const slice=thread.timeSlices[sliceId];const sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);const intersection=rangeOfInterest.findIntersection(sliceRange);const duration=intersection.duration;if(duration===0)continue;hasSlices=true;if(slice.title==='Running'){timeRunning+=duration;}else if(slice.title==='Runnable'){timeRunnable+=duration;}else if(slice.title==='Sleeping'){timeSleeping+=duration;}else if(slice.title.startsWith('Uninterruptible')){timeUninterruptible+=duration;if(slice.title.includes('Block I/O'))timeBlockIO+=duration;}else{timeUnknown+=duration;}}}
+if(hasSlices){const wall=rangeOfInterest.max-rangeOfInterest.min;histograms.createHistogram(`android:systrace:threadtime:${process.name}:running`,tr.b.Unit.byName.normalizedPercentage,timeRunning/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:runnable`,tr.b.Unit.byName.normalizedPercentage,timeRunnable/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:sleeping`,tr.b.Unit.byName.normalizedPercentage,timeSleeping/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:blockio`,tr.b.Unit.byName.normalizedPercentage,timeBlockIO/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:uninterruptible`,tr.b.Unit.byName.normalizedPercentage,timeUninterruptible/wall);if(timeUnknown>0){histograms.createHistogram(`android:systrace:threadtime:${process.name}:unknown`,tr.b.Unit.byName.normalizedPercentage,timeUnknown/wall);}}}}
+function androidSystraceMetric(histograms,model,options){let rangeOfInterest=model.bounds;if(options!==undefined&&options.rangeOfInterest!==undefined){rangeOfInterest=options.rangeOfInterest;}
+measureStartup(histograms,model);measureThreadStates(histograms,model,rangeOfInterest);}
+tr.metrics.MetricRegistry.register(androidSystraceMetric,{supportsRangeOfInterest:true});return{androidSystraceMetric,};});'use strict';tr.exportTo('tr.b.math',function(){const PERCENTILE_PRECISION=1e-7;function PiecewiseLinearFunction(){this.pieces=[];}
+PiecewiseLinearFunction.prototype={push(x1,y1,x2,y2){if(x1>=x2){throw new Error('Invalid segment');}
+if(this.pieces.length>0&&this.pieces[this.pieces.length-1].x2>x1){throw new Error('Potentially overlapping segments');}
+if(x1<x2){this.pieces.push(new Piece(x1,y1,x2,y2));}},partBelow(y){return this.pieces.reduce((acc,p)=>(acc+p.partBelow(y)),0);},get min(){return this.pieces.reduce((acc,p)=>Math.min(acc,p.min),Infinity);},get max(){return this.pieces.reduce((acc,p)=>Math.max(acc,p.max),-Infinity);},get average(){let weightedSum=0;let totalWeight=0;this.pieces.forEach(function(piece){weightedSum+=piece.width*piece.average;totalWeight+=piece.width;});if(totalWeight===0)return 0;return weightedSum/totalWeight;},percentile(percent){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
+let lower=this.min;let upper=this.max;const total=this.partBelow(upper);if(total===0)return 0;while(upper-lower>PERCENTILE_PRECISION){const middle=(lower+upper)/2;const below=this.partBelow(middle);if(below/total<percent){lower=middle;}else{upper=middle;}}
+return(lower+upper)/2;}};function Piece(x1,y1,x2,y2){this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;}
+Piece.prototype={partBelow(y){const width=this.width;if(width===0)return 0;const minY=this.min;const maxY=this.max;if(y>=maxY)return width;if(y<minY)return 0;return(y-minY)/(maxY-minY)*width;},get min(){return Math.min(this.y1,this.y2);},get max(){return Math.max(this.y1,this.y2);},get average(){return(this.y1+this.y2)/2;},get width(){return this.x2-this.x1;}};return{PiecewiseLinearFunction,};});'use strict';tr.exportTo('tr.metrics.v8.utils',function(){const IDLE_TASK_EVENT='SingleThreadIdleTaskRunner::RunTask';const V8_EXECUTE='V8.Execute';const GC_EVENT_PREFIX='V8.GC';const FULL_GC_EVENT='V8.GCCompactor';const LOW_MEMORY_EVENT='V8.GCLowMemoryNotification';const MAJOR_GC_EVENT='MajorGC';const MINOR_GC_EVENT='MinorGC';const TOP_GC_EVENTS={'V8.GCCompactor':'v8-gc-full-mark-compactor','V8.GCFinalizeMC':'v8-gc-latency-mark-compactor','V8.GCFinalizeMCReduceMemory':'v8-gc-memory-mark-compactor','V8.GCIncrementalMarking':'v8-gc-incremental-step','V8.GCIncrementalMarkingFinalize':'v8-gc-incremental-finalize','V8.GCIncrementalMarkingStart':'v8-gc-incremental-start','V8.GCPhantomHandleProcessingCallback':'v8-gc-phantom-handle-callback','V8.GCScavenger':'v8-gc-scavenger'};const LOW_MEMORY_MARK_COMPACTOR='v8-gc-low-memory-mark-compactor';function findParent(event,predicate){let parent=event.parentSlice;while(parent){if(predicate(parent)){return parent;}
+parent=parent.parentSlice;}
+return null;}
+function isIdleTask(event){return event.title===IDLE_TASK_EVENT;}
+function isLowMemoryEvent(event){return event.title===LOW_MEMORY_EVENT;}
+function isV8Event(event){return event.title.startsWith('V8.');}
+function isV8ExecuteEvent(event){return event.title===V8_EXECUTE;}
+function isTopV8ExecuteEvent(event){return isV8ExecuteEvent(event)&&findParent(isV8ExecuteEvent)===null;}
+function isGarbageCollectionEvent(event){return event.title&&event.title.startsWith(GC_EVENT_PREFIX)&&event.title!==LOW_MEMORY_EVENT;}
+function isTopGarbageCollectionEvent(event){return event.title in TOP_GC_EVENTS;}
+function isForcedGarbageCollectionEvent(event){return findParent(event,isLowMemoryEvent)!==null;}
+function isSubGarbageCollectionEvent(event){return isGarbageCollectionEvent(event)&&event.parentSlice&&(isTopGarbageCollectionEvent(event.parentSlice)||event.parentSlice.title===MAJOR_GC_EVENT||event.parentSlice.title===MINOR_GC_EVENT);}
+function isCompileOptimizeEvent(event){return(event.title==='V8.OptimizeCode'||event.title==='V8.RecompileSynchronous'||event.title==='V8.RecompileConcurrent');}
+function isCompileUnoptimizeEvent(event){return(event.title==='V8.CompileIgnition'||event.title==='V8.CompileUnoptimizedInnerFunctions'||event.title==='V8.Compile'||event.title==='V8.CompileEval'||event.title==='V8.CompileCode'||event.title==='V8.CompileScript');}
+function isCompileParseEvent(event){return(event.title==='V8.PreParse'||event.title==='V8.ParseFunction'||event.title==='V8.ParseProgram');}
+function isCompileEvent(event){return tr.b.getCategoryParts(event.category).includes('disabled-by-default-v8.compile');}
+function isFullMarkCompactorEvent(event){return event.title==='V8.GCCompactor';}
+function isIncrementalMarkingEvent(event){return event.title.startsWith('V8.GCIncrementalMarking');}
+function isLatencyMarkCompactorEvent(event){return event.title==='V8.GCFinalizeMC';}
+function isMemoryMarkCompactorEvent(event){return event.title==='V8.GCFinalizeMCReduceMemory';}
+function isScavengerEvent(event){return event.title==='V8.GCScavenger';}
+function topGarbageCollectionEventName(event){if(event.title===FULL_GC_EVENT){if(findParent(event,isLowMemoryEvent)){return LOW_MEMORY_MARK_COMPACTOR;}}
+return TOP_GC_EVENTS[event.title];}
+function subGarbageCollectionEventName(event){const topEvent=findParent(event,isTopGarbageCollectionEvent);const prefix=topEvent?topGarbageCollectionEventName(topEvent):'unknown';const name=event.title.replace('V8.GC_MC_','').replace('V8.GC_SCAVENGER_','').replace('V8.GC_','').replace(/_/g,'-').toLowerCase();return prefix+'-'+name;}
+function groupAndProcessEvents(model,filterCallback,nameCallback,processCallback){const nameToEvents={};for(const event of model.getDescendantEvents()){if(!filterCallback(event))continue;const name=nameCallback(event);nameToEvents[name]=nameToEvents[name]||[];nameToEvents[name].push(event);}
+for(const[name,events]of Object.entries(nameToEvents)){processCallback(name,events);}}
+function unionOfIntervals(intervals){if(intervals.length===0)return[];return tr.b.math.mergeRanges(intervals.map(x=>{return{min:x.start,max:x.end};}),1e-6,function(ranges){return{start:ranges.reduce((acc,x)=>Math.min(acc,x.min),ranges[0].min),end:ranges.reduce((acc,x)=>Math.max(acc,x.max),ranges[0].max)};});}
+function hasV8Stats(globalMemoryDump){let v8stats=undefined;globalMemoryDump.iterateContainerDumps(function(dump){v8stats=v8stats||dump.getMemoryAllocatorDumpByFullName('v8');});return!!v8stats;}
+function rangeForMemoryDumps(model){const startOfFirstDumpWithV8=model.globalMemoryDumps.filter(hasV8Stats).reduce((start,dump)=>Math.min(start,dump.start),Infinity);if(startOfFirstDumpWithV8===Infinity)return new tr.b.math.Range();return tr.b.math.Range.fromExplicitRange(startOfFirstDumpWithV8,Infinity);}
+return{findParent,groupAndProcessEvents,isCompileEvent,isCompileOptimizeEvent,isCompileUnoptimizeEvent,isCompileParseEvent,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMemoryMarkCompactorEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_GC_EVENTS={'BlinkGCMarking':'blink-gc-marking','ThreadState::completeSweep':'blink-gc-complete-sweep','ThreadState::performIdleLazySweep':'blink-gc-idle-lazy-sweep'};function isBlinkGarbageCollectionEvent(event){return event.title in BLINK_GC_EVENTS;}
+function blinkGarbageCollectionEventName(event){return BLINK_GC_EVENTS[event.title];}
+function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addIdleTimesOfTopEvents(histograms,model);addTotalIdleTimesOfTopEvents(histograms,model);}
+tr.metrics.MetricRegistry.register(blinkGcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForIdleTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
+function createPercentage(name,numerator,denominator){const histogram=new tr.v.Histogram(name,percentage_biggerIsBetter);if(denominator===0){histogram.addSample(0);}else{histogram.addSample(numerator/denominator);}
+return histogram;}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addIdleTimesOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){addIdleTimes(histograms,model,name,events);});}
+function addTotalIdleTimesOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){addIdleTimes(histograms,model,name,events);});}
+function addIdleTimes(histograms,model,name,events){const cpuDuration=createNumericForIdleTime(name+'_cpu');const insideIdle=createNumericForIdleTime(name+'_inside_idle');const outsideIdle=createNumericForIdleTime(name+'_outside_idle');const idleDeadlineOverrun=createNumericForIdleTime(name+'_idle_deadline_overrun');events.forEach(function(event){const idleTask=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isIdleTask);let inside=0;let overrun=0;if(idleTask){const allottedTime=idleTask.args.allotted_time_ms;if(event.duration>allottedTime){overrun=event.duration-allottedTime;inside=event.cpuDuration*allottedTime/event.duration;}else{inside=event.cpuDuration;}}
+cpuDuration.addSample(event.cpuDuration);insideIdle.addSample(inside);outsideIdle.addSample(event.cpuDuration-inside);idleDeadlineOverrun.addSample(overrun);});histograms.addHistogram(idleDeadlineOverrun);histograms.addHistogram(outsideIdle);const percentage=createPercentage(name+'_percentage_idle',insideIdle.sum,cpuDuration.sum);histograms.addHistogram(percentage);}
+return{blinkGcMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function getCpuSnapshotsFromModel(model){const snapshots=[];for(const pid in model.processes){const snapshotInstances=model.processes[pid].objects.getAllInstancesNamed('CPUSnapshots');if(!snapshotInstances)continue;for(const object of snapshotInstances[0].snapshots){snapshots.push(object.args.processes);}}
+return snapshots;}
+function getProcessSumsFromSnapshot(snapshot){const processSums=new Map();for(const processData of snapshot){const processName=processData.name;if(!(processSums.has(processName))){processSums.set(processName,{sum:0.0,paths:new Set()});}
+processSums.get(processName).sum+=parseFloat(processData.pCpu);if(processData.path){processSums.get(processName).paths.add(processData.path);}}
+return processSums;}
+function buildNumericsFromSnapshots(snapshots){const processNumerics=new Map();for(const snapshot of snapshots){const processSums=getProcessSumsFromSnapshot(snapshot);for(const[processName,processData]of processSums.entries()){if(!(processNumerics.has(processName))){processNumerics.set(processName,{numeric:new tr.v.Histogram('cpu:percent:'+processName,tr.b.Unit.byName.normalizedPercentage_smallerIsBetter),paths:new Set()});}
+processNumerics.get(processName).numeric.addSample(processData.sum/100.0);for(const path of processData.paths){processNumerics.get(processName).paths.add(path);}}}
+return processNumerics;}
+function cpuProcessMetric(histograms,model){const snapshots=getCpuSnapshotsFromModel(model);const processNumerics=buildNumericsFromSnapshots(snapshots);for(const[processName,processData]of processNumerics){const numeric=processData.numeric;const missingSnapshotCount=snapshots.length-numeric.numValues;for(let i=0;i<missingSnapshotCount;i++){numeric.addSample(0);}
+numeric.diagnostics.set('paths',new
+tr.v.d.GenericSet([...processData.paths]));histograms.addHistogram(numeric);}}
+tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(histograms,model){const hist=new tr.v.Histogram('foo',tr.b.Unit.byName.sizeInBytes_smallerIsBetter);hist.addSample(9);hist.addSample(91,{bar:new tr.v.d.GenericSet([{hello:42}])});for(const expectation of model.userModel.expectations){if(expectation instanceof tr.model.um.ResponseExpectation){}else if(expectation instanceof tr.model.um.AnimationExpectation){}else if(expectation instanceof tr.model.um.IdleExpectation){}else if(expectation instanceof tr.model.um.LoadExpectation){}}
+const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const[pid,process]of Object.entries(model.processes)){}
+histograms.addHistogram(hist);}
+tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const HANDLE_INPUT_EVENT_TITLE='WebViewImpl::handleInputEvent';function findPrecedingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>eventA.start)break;}
+if(eventsBIndex>0){events.set(eventA,eventsB[eventsBIndex-1]);}}
+return events;}
+function findFollowingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>=eventA.start)break;}
+if(eventsBIndex>=0&&eventsBIndex<eventsB.length){events.set(eventA,eventsB[eventsBIndex]);}}
+return events;}
+function getSpaNavigationStartCandidates_(rendererHelper,browserHelper){const isNavStartEvent=e=>{if(e.title===HANDLE_INPUT_EVENT_TITLE&&e.args.type==='MouseUp'){return true;}
+return e.title==='NavigationControllerImpl::GoToIndex';};return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents(),...browserHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavStartEvent);}
+function getSpaNavigationEvents_(rendererHelper){const isNavEvent=e=>e.category==='blink'&&e.title==='FrameLoader::updateForSameDocumentNavigation';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavEvent);}
+function getInputLatencyEvents_(browserHelper){const isInputLatencyEvent=e=>e.title==='InputLatency::MouseUp';return browserHelper.getAllAsyncSlicesMatching(isInputLatencyEvent);}
+function getInputLatencyEventByBindIdMap_(browserHelper){const inputLatencyEventByBindIdMap=new Map();for(const event of getInputLatencyEvents_(browserHelper)){inputLatencyEventByBindIdMap.set(event.args.data.trace_id,event);}
+return inputLatencyEventByBindIdMap;}
+function getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper){const mainThread=rendererHelper.mainThread;const spaNavEvents=getSpaNavigationEvents_(rendererHelper);const navStartCandidates=getSpaNavigationStartCandidates_(rendererHelper,browserHelper).sort(tr.importer.compareEvents);const spaNavEventToNavStartCandidateMap=findPrecedingEvents_(spaNavEvents,navStartCandidates);const inputLatencyEventByBindIdMap=getInputLatencyEventByBindIdMap_(browserHelper);const spaNavEventToNavStartEventMap=new Map();for(const[spaNavEvent,navStartCandidate]of
+spaNavEventToNavStartCandidateMap){if(navStartCandidate.title===HANDLE_INPUT_EVENT_TITLE){const inputLatencySlice=inputLatencyEventByBindIdMap.get(Number(navStartCandidate.parentSlice.bindId));if(inputLatencySlice){spaNavEventToNavStartEventMap.set(spaNavEvent,inputLatencySlice);}}else{spaNavEventToNavStartEventMap.set(spaNavEvent,navStartCandidate);}}
+return spaNavEventToNavStartEventMap;}
+function getFirstPaintEvents_(rendererHelper){const isFirstPaintEvent=e=>e.category==='blink'&&e.title==='PaintLayerCompositor::updateIfNeededRecursive';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isFirstPaintEvent);}
+function getSpaNavigationEventToFirstPaintEventMap_(rendererHelper){const spaNavEvents=getSpaNavigationEvents_(rendererHelper).sort(tr.importer.compareEvents);const firstPaintEvents=getFirstPaintEvents_(rendererHelper).sort(tr.importer.compareEvents);return findFollowingEvents_(spaNavEvents,firstPaintEvents);}
+function findSpaNavigationsOnRenderer(rendererHelper,browserHelper){const spaNavEventToNavStartMap=getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper);const spaNavEventToFirstPaintEventMap=getSpaNavigationEventToFirstPaintEventMap_(rendererHelper);const spaNavigations=[];for(const[spaNavEvent,navStartEvent]of
+spaNavEventToNavStartMap){if(spaNavEventToFirstPaintEventMap.has(spaNavEvent)){const firstPaintEvent=spaNavEventToFirstPaintEventMap.get(spaNavEvent);const isNavStartAsyncSlice=navStartEvent instanceof tr.model.AsyncSlice;spaNavigations.push({navStartCandidates:{inputLatencyAsyncSlice:isNavStartAsyncSlice?navStartEvent:undefined,goToIndexSlice:isNavStartAsyncSlice?undefined:navStartEvent},firstPaintEvent,url:spaNavEvent.args.url});}}
+return spaNavigations;}
+return{findSpaNavigationsOnRenderer,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
+function filterExpectationsByRange(irs,opt_range){const filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))return;if(!opt_range||opt_range.intersectsExplicitRangeInclusive(ir.start,ir.end)){filteredExpectations.push(ir);}});return filteredExpectations;}
+return{perceptualBlend,filterExpectationsByRange,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function generateTimeBreakdownTree(mainThread,rangeOfInterest,getEventStart,getEventDuration,getEventSelfTime){if(mainThread===null)return;const breakdownTree={};for(const title of
+tr.e.chrome.ChromeUserFriendlyCategoryDriver.ALL_TITLES){breakdownTree[title]={total:0,events:{}};}
+for(const event of mainThread.getDescendantEvents()){const eventStart=getEventStart(event);const eventDuration=getEventDuration(event);const eventSelfTime=getEventSelfTime(event);const eventEnd=eventStart+eventDuration;if(!rangeOfInterest.intersectsExplicitRangeExclusive(eventStart,eventEnd)){continue;}
+if(eventSelfTime===undefined)continue;const title=tr.e.chrome.ChromeUserFriendlyCategoryDriver.fromEvent(event);let timeIntersectionRatio=0;if(eventDuration>0){timeIntersectionRatio=rangeOfInterest.findExplicitIntersectionDuration(eventStart,eventEnd)/eventDuration;}
+const v8Runtime=event.args['runtime-call-stat'];if(v8Runtime!==undefined){const v8RuntimeObject=JSON.parse(v8Runtime);for(const runtimeCall in v8RuntimeObject){if(v8RuntimeObject[runtimeCall].length===2){if(breakdownTree.v8_runtime.events[runtimeCall]===undefined){breakdownTree.v8_runtime.events[runtimeCall]=0;}
+const runtimeTime=tr.b.Unit.timestampFromUs(v8RuntimeObject[runtimeCall][1]*timeIntersectionRatio);breakdownTree.v8_runtime.total+=runtimeTime;breakdownTree.v8_runtime.events[runtimeCall]+=runtimeTime;}}}
+const approximatedSelfTimeContribution=eventSelfTime*timeIntersectionRatio;breakdownTree[title].total+=approximatedSelfTimeContribution;if(breakdownTree[title].events[event.title]===undefined){breakdownTree[title].events[event.title]=0;}
+breakdownTree[title].events[event.title]+=approximatedSelfTimeContribution;}
+return breakdownTree;}
+function addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEvents,networkEvents,rangeOfInterest){let idleRanges=[rangeOfInterest];const mainThreadEventRanges=tr.b.math.convertEventsToRanges(mainThreadEvents);const networkEventRanges=tr.b.math.convertEventsToRanges(networkEvents);const eventRanges=mainThreadEventRanges.concat(networkEventRanges);eventRanges.sort((a,b)=>a.min-b.min);for(const eventRange of eventRanges){if(!eventRange||eventRange.isEmpty||eventRange.duration<0){throw new Error('Range is invalid');}
+const newLastIdleRanges=tr.b.math.Range.findDifference(idleRanges[idleRanges.length-1],eventRange);idleRanges.pop();idleRanges=idleRanges.concat(newLastIdleRanges);if(idleRanges.length===0)break;}
+const totalFreeDuration=tr.b.math.Statistics.sum(idleRanges,range=>range.duration);breakdownTree.idle={total:totalFreeDuration,events:{}};let totalBlockedDuration=rangeOfInterest.duration;for(const component of Object.values(breakdownTree)){totalBlockedDuration-=component.total;}
+breakdownTree.blocked_on_network={total:totalBlockedDuration,events:{}};}
+function generateWallClockTimeBreakdownTree(mainThread,networkEvents,rangeOfInterest){function getEventStart(e){return e.start;}
+function getEventDuration(e){return e.duration;}
+function getEventSelfTime(e){return e.selfTime;}
+const breakdownTree=generateTimeBreakdownTree(mainThread,rangeOfInterest,getEventStart,getEventDuration,getEventSelfTime);const mainThreadEventsInRange=tr.model.helpers.getSlicesIntersectingRange(rangeOfInterest,mainThread.sliceGroup.topLevelSlices);addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEventsInRange,networkEvents,rangeOfInterest);return breakdownTree;}
+function generateCpuTimeBreakdownTree(mainThread,rangeOfInterestCpuTime){function getEventStart(e){return e.cpuStart;}
+function getEventDuration(e){return e.cpuDuration;}
+function getEventSelfTime(e){return e.cpuSelfTime;}
+return generateTimeBreakdownTree(mainThread,rangeOfInterestCpuTime,getEventStart,getEventDuration,getEventSelfTime);}
+return{generateTimeBreakdownTree,generateWallClockTimeBreakdownTree,generateCpuTimeBreakdownTree,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const RESPONSIVENESS_THRESHOLD_MS=50;const INTERACTIVE_WINDOW_SIZE_MS=5*1000;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const RelatedEventSet=tr.v.d.RelatedEventSet;function getNetworkEventsInRange(process,range){const networkEvents=[];for(const thread of Object.values(process.threads)){const threadHelper=new tr.model.helpers.ChromeThreadHelper(thread);const events=threadHelper.getNetworkEvents();for(const event of events){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){networkEvents.push(event);}}}
+return networkEvents;}
+function hasCategoryAndName(event,category,title){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+function createBreakdownDiagnostic(breakdownTree){const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
+return breakdownDiagnostic;}
+function NavigationStartFinder(rendererHelper){this.navigationStartsForFrameId_={};for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(!hasCategoryAndName(ev,'blink.user_timing','navigationStart')){continue;}
+const frameIdRef=ev.args.frame;let list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined){this.navigationStartsForFrameId_[frameIdRef]=list=[];}
+list.unshift(ev);}}
+NavigationStartFinder.prototype={findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ts){const list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined)return undefined;let eventBeforeTimestamp;for(const ev of list){if(ev.start>ts)continue;if(eventBeforeTimestamp===undefined){eventBeforeTimestamp=ev;}}
+if(eventBeforeTimestamp===undefined)return undefined;return eventBeforeTimestamp;}};const FIRST_PAINT_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){const objects=rendererHelper.process.objects;const frameLoaderInstances=objects.instancesByTypeName_.FrameLoader;if(frameLoaderInstances===undefined)return undefined;let snapshot;for(const instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;const maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args.frame.id_ref)continue;snapshot=maybeSnapshot;}
+return snapshot;}
+function findAllEvents(rendererHelper,category,title){const targetEvents=[];for(const ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,category,title))continue;targetEvents.push(ev);}
+return targetEvents;}
+function findFirstMeaningfulPaintCandidates(rendererHelper){const candidatesForFrameId={};for(const ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,'loading','firstMeaningfulPaintCandidate')){continue;}
+if(rendererHelper.isTelemetryInternalEvent(ev))continue;const frameIdRef=ev.args.frame;if(frameIdRef===undefined)continue;let list=candidatesForFrameId[frameIdRef];if(list===undefined){candidatesForFrameId[frameIdRef]=list=[];}
+list.push(ev);}
+return candidatesForFrameId;}
+const URL_BLACKLIST=['about:blank','data:text/html,pluginplaceholderdata','data:text/html,chromewebdata'];function shouldIgnoreURL(url){return URL_BLACKLIST.includes(url);}
+function collectTimeToEvent(category,eventName,rendererHelper,navigationStartFinder){const targetEvents=findAllEvents(rendererHelper,category,eventName);const samples=[];for(const ev of targetEvents){if(rendererHelper.isTelemetryInternalEvent(ev))continue;const frameIdRef=ev.args.frame;const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ev.start);if(snapshot===undefined||!snapshot.args.isLoadingMainFrame)continue;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))continue;const navigationStartEvent=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartEvent===undefined)continue;const timeToEvent=ev.start-navigationStartEvent.start;samples.push({value:timeToEvent,diagnostics:{url:new tr.v.d.GenericSet([url])}});}
+return samples;}
+function addFirstMeaningfulPaintSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;const navStartToFMPRange=tr.b.math.Range.fromExplicitRange(navigationStart.start,fmpMarkerEvent.start);const networkEvents=getNetworkEventsInRange(rendererHelper.process,navStartToFMPRange);const timeToFirstMeaningfulPaint=navStartToFMPRange.duration;const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToFMPRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:timeToFirstMeaningfulPaint,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start,}]),}});return{firstMeaningfulPaint:fmpMarkerEvent.start,url};}
+function addFirstMeaningfulPaintCpuTimeSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){const navStartToFMPCpuRange=tr.b.math.Range.fromExplicitRange(navigationStart.cpuStart,fmpMarkerEvent.cpuStart);const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;const mainThreadCpuTime=getMainThreadCpuTime(rendererHelper,navStartToFMPCpuRange);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,navStartToFMPCpuRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:mainThreadCpuTime,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start,}]),}});}
+function getMainThreadCpuTime(rendererHelper,rangeOfInterest){let mainThreadCpuTime=0;for(const slice of rendererHelper.mainThread.sliceGroup.topLevelSlices){if(!slice.cpuDuration)continue;const sliceRange=tr.b.math.Range.fromExplicitRange(slice.cpuStart,slice.cpuStart+slice.cpuDuration);const intersection=rangeOfInterest.findIntersection(sliceRange);mainThreadCpuTime+=intersection.duration;}
+return mainThreadCpuTime;}
+function addFirstInteractiveSample(samples,rendererHelper,navigationStart,firstMeaningfulPaint,url){if(shouldIgnoreURL(url))return;const navigationStartTime=navigationStart.start;let firstInteractive=Infinity;let firstInteractiveCandidate=firstMeaningfulPaint;let lastLongTaskEvent=undefined;for(const ev of[...rendererHelper.mainThread.sliceGroup.childEvents()]){if(ev.start<firstInteractiveCandidate)continue;const interactiveDurationSoFar=ev.start-firstInteractiveCandidate;if(interactiveDurationSoFar>=INTERACTIVE_WINDOW_SIZE_MS){firstInteractive=firstInteractiveCandidate;break;}
+if(ev.title==='TaskQueueManager::ProcessTaskFromWorkQueue'&&ev.duration>RESPONSIVENESS_THRESHOLD_MS){firstInteractiveCandidate=ev.end-50;lastLongTaskEvent=ev;}}
+const navStartToFirstInteractiveRange=tr.b.math.Range.fromExplicitRange(navigationStartTime,firstInteractive);const networkEvents=getNetworkEventsInRange(rendererHelper.process,navStartToFirstInteractiveRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToFirstInteractiveRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);const timeToFirstInteractive=navStartToFirstInteractiveRange.duration;samples.push({value:timeToFirstInteractive,diagnostics:{'Start':new RelatedEventSet(navigationStart),'Last long task':new RelatedEventSet(lastLongTaskEvent),'Navigation infos':new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,start:navigationStartTime,interactive:firstInteractive,}]),'Breakdown of [navStart, Interactive]':breakdownDiagnostic,}});}
+function collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder){const firstMeaningfulPaintSamples=[];const firstMeaningfulPaintCpuTimeSamples=[];const firstInteractiveSamples=[];function addSamples(frameIdRef,navigationStart,fmpMarkerEvent){const data=addFirstMeaningfulPaintSample(firstMeaningfulPaintSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);addFirstMeaningfulPaintCpuTimeSample(firstMeaningfulPaintCpuTimeSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);if(data!==undefined){addFirstInteractiveSample(firstInteractiveSamples,rendererHelper,navigationStart,data.firstMeaningfulPaint,data.url);}}
+const candidatesForFrameId=findFirstMeaningfulPaintCandidates(rendererHelper);for(const frameIdRef in candidatesForFrameId){let navigationStart=undefined;let lastCandidate=undefined;for(const ev of candidatesForFrameId[frameIdRef]){const navigationStartForThisCandidate=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartForThisCandidate===undefined)continue;if(navigationStart!==navigationStartForThisCandidate){if(navigationStart!==undefined&&lastCandidate!==undefined){addSamples(frameIdRef,navigationStart,lastCandidate);}
+navigationStart=navigationStartForThisCandidate;}
+lastCandidate=ev;}
+if(lastCandidate!==undefined){addSamples(frameIdRef,navigationStart,lastCandidate);}}
+return{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples};}
+function collectLoadingMetricsForRenderer(rendererHelper){const navigationStartFinder=new NavigationStartFinder(rendererHelper);const firstPaintSamples=collectTimeToEvent('loading','firstPaint',rendererHelper,navigationStartFinder);const firstContentfulPaintSamples=collectTimeToEvent('loading','firstContentfulPaint',rendererHelper,navigationStartFinder);const onLoadSamples=collectTimeToEvent('blink.user_timing','loadEventStart',rendererHelper,navigationStartFinder);const{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples}=collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder);return{firstPaintSamples,firstContentfulPaintSamples,onLoadSamples,firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples};}
+function addSamplesToHistogram(samples,histogram){for(const sample of samples){histogram.addSample(sample.value,sample.diagnostics);}}
+function loadingMetric(histograms,model){const firstPaintHistogram=histograms.createHistogram('timeToFirstPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'time to first paint',summaryOptions:SUMMARY_OPTIONS,});const firstContentfulPaintHistogram=histograms.createHistogram('timeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,});const onLoadHistogram=histograms.createHistogram('timeToOnload',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintHistogram=histograms.createHistogram('timeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'CPU time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const firstInteractiveHistogram=histograms.createHistogram('timeToFirstInteractive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:FIRST_PAINT_BOUNDARIES,description:'time to first interactive',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;const samplesSet=collectLoadingMetricsForRenderer(rendererHelper);addSamplesToHistogram(samplesSet.firstPaintSamples,firstPaintHistogram);addSamplesToHistogram(samplesSet.firstContentfulPaintSamples,firstContentfulPaintHistogram);addSamplesToHistogram(samplesSet.onLoadSamples,onLoadHistogram);addSamplesToHistogram(samplesSet.firstMeaningfulPaintSamples,firstMeaningfulPaintHistogram);addSamplesToHistogram(samplesSet.firstMeaningfulPaintCpuTimeSamples,firstMeaningfulPaintCpuTimeHistogram);addSamplesToHistogram(samplesSet.firstInteractiveSamples,firstInteractiveHistogram);}}
+tr.metrics.MetricRegistry.register(loadingMetric);return{loadingMetric,getNetworkEventsInRange,collectLoadingMetricsForRenderer,RESPONSIVENESS_THRESHOLD_MS,INTERACTIVE_WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics',function(){const SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY=tr.v.HistogramBinBoundaries.createExponential(1,1000,50);function spaNavigationMetric(histograms,model){const histogram=new tr.v.Histogram('spaNavigationStartToFpDuration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY);histogram.description='Latency between the input event causing'+' a SPA navigation and the first paint event after it';histogram.customizeSummaryOptions({count:false,sum:false,});const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper){return;}
+const rendererHelpers=modelHelper.rendererHelpers;if(!rendererHelpers){return;}
+const browserHelper=modelHelper.browserHelper;for(const rendererHelper of Object.values(rendererHelpers)){const spaNavigations=tr.metrics.findSpaNavigationsOnRenderer(rendererHelper,browserHelper);for(const spaNav of spaNavigations){let beginTs=0;if(spaNav.navStartCandidates.inputLatencyAsyncSlice){const beginData=spaNav.navStartCandidates.inputLatencyAsyncSlice.args.data;beginTs=model.convertTimestampToModelTime('traceEventClock',beginData.INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT.time);}else{beginTs=spaNav.navStartCandidates.goToIndexSlice.start;}
+const rangeOfInterest=tr.b.math.Range.fromExplicitRange(beginTs,spaNav.firstPaintEvent.start);const networkEvents=tr.metrics.sh.getNetworkEventsInRange(rendererHelper.process,rangeOfInterest);const breakdownDict=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,rangeOfInterest);const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownDict){breakdownDiagnostic.set(label,parseInt(breakdownDict[label].total*1e3)/1e3);}
+histogram.addSample(rangeOfInterest.duration,{'Breakdown of [navStart, firstPaint]':breakdownDiagnostic,'Start':new tr.v.d.RelatedEventSet(spaNav.navigationStart),'End':new tr.v.d.RelatedEventSet(spaNav.firstPaintEvent),'Navigation infos':new tr.v.d.GenericSet([{url:spaNav.url,pid:rendererHelper.pid,navStart:beginTs,firstPaint:spaNav.firstPaintEvent.start}]),});}}
+histograms.addHistogram(histogram);}
+tr.metrics.MetricRegistry.register(spaNavigationMetric);return{spaNavigationMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LATENCY_BOUNDS=tr.v.HistogramBinBoundaries.createLinear(0,20,100);function clockSyncLatencyMetric(values,model){const domains=Array.from(model.clockSyncManager.domainsSeen).sort();for(let i=0;i<domains.length;i++){for(let j=i+1;j<domains.length;j++){const latency=model.clockSyncManager.getTimeTransformerError(domains[i],domains[j]);const hist=new tr.v.Histogram('clock_sync_latency_'+
+domains[i].toLowerCase()+'_to_'+domains[j].toLowerCase(),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,LATENCY_BOUNDS);hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,});hist.description='Clock sync latency for domain '+domains[i]+' to domain '+domains[j];hist.addSample(latency);values.addHistogram(hist);}}}
+tr.metrics.MetricRegistry.register(clockSyncLatencyMetric);return{clockSyncLatencyMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CPU_TIME_PERCENTAGE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,50,200);function cpuTimeMetric(histograms,model,opt_options){let rangeOfInterest=model.bounds;if(opt_options&&opt_options.rangeOfInterest){rangeOfInterest=opt_options.rangeOfInterest;}else{const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper){const chromeBounds=chromeHelper.chromeBounds;if(chromeBounds){rangeOfInterest=chromeBounds;}}}
+let allProcessCpuTime=0;for(const pid in model.processes){const process=model.processes[pid];if(tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)){continue;}
+let processCpuTime=0;for(const tid in process.threads){const thread=process.threads[tid];let threadCpuTime=0;thread.sliceGroup.topLevelSlices.forEach(function(slice){if(slice.duration===0)return;if(!slice.cpuDuration)return;const sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);const intersection=rangeOfInterest.findIntersection(sliceRange);const fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;threadCpuTime+=slice.cpuDuration*fractionOfSliceInsideRangeOfInterest;});processCpuTime+=threadCpuTime;}
+allProcessCpuTime+=processCpuTime;}
+let normalizedAllProcessCpuTime=0;if(rangeOfInterest.duration>0){normalizedAllProcessCpuTime=allProcessCpuTime/rangeOfInterest.duration;}
+const unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
+tr.metrics.MetricRegistry.register(cpuTimeMetric,{supportsRangeOfInterest:true});return{cpuTimeMetric,};});'use strict';tr.exportTo('tr.v.d',function(){function addRelatedNames(histograms){for(const hist of histograms){const relatedNames=new Set();for(const[name,diagnostic]of hist.diagnostics){if(diagnostic instanceof tr.v.d.RelatedHistogramMap){for(const[relationshipName,relatedHist]of diagnostic){relatedNames.add(relatedHist.name);}}}
+if(relatedNames.size){hist.diagnostics.set(tr.v.d.RESERVED_NAMES.RELATED_NAMES,new tr.v.d.GenericSet(relatedNames));}}}
+return{addRelatedNames,};});'use strict';tr.exportTo('tr.v',function(){class HistogramGrouping{constructor(key,callback){this.key_=key;this.callback_=callback;HistogramGrouping.BY_KEY.set(key,this);}
+get key(){return this.key_;}
+get callback(){return this.callback_;}
+get label(){return this.key;}
+static buildFromTags(tags,diagnosticName){const booleanTags=new Set();const keyValueTags=new Set();for(const tag of tags){if(tag.includes(':')){const key=tag.split(':')[0];if(booleanTags.has(key)){throw new Error(`Tag "${key}" cannot be both boolean and key-value`);}
+keyValueTags.add(key);}else{if(keyValueTags.has(tag)){throw new Error(`Tag "${tag}" cannot be both boolean and key-value`);}
+booleanTags.add(tag);}}
+const groupings=[];for(const tag of booleanTags){groupings.push(HistogramGrouping.buildBooleanTagGrouping_(tag,diagnosticName));}
+for(const tag of keyValueTags){groupings.push(HistogramGrouping.buildKeyValueTagGrouping_(tag,diagnosticName));}
+return groupings;}
+static buildBooleanTagGrouping_(tag,diagnosticName){return new HistogramGrouping(`${tag}Tag`,h=>{const tags=h.diagnostics.get(diagnosticName);if(tags===undefined||!tags.has(tag))return`~${tag}`;return tag;});}
+static buildKeyValueTagGrouping_(tag,diagnosticName){return new HistogramGrouping(`${tag}Tag`,h=>{const tags=h.diagnostics.get(diagnosticName);if(tags===undefined)return`~${tag}`;const values=new Set();for(const value of tags){const kvp=value.split(':');if(kvp.length<2||kvp[0]!==tag)continue;values.add(kvp[1]);}
+if(values.size===0)return`~${tag}`;const sortedValues=Array.from(values);sortedValues.sort();return sortedValues.join(',');},`${tag} tag`);}}
+HistogramGrouping.BY_KEY=new Map();HistogramGrouping.HISTOGRAM_NAME=new HistogramGrouping('name',h=>h.name);HistogramGrouping.DISPLAY_LABEL=new HistogramGrouping('displayLabel',hist=>{const labels=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.LABELS);if(labels!==undefined&&labels.size>0){return Array.from(labels).join(',');}
+const benchmarks=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARKS);const start=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARK_START);if(benchmarks===undefined){if(start===undefined)return'Value';return start.toString();}
+const benchmarksStr=Array.from(benchmarks).join('\n');if(start===undefined)return benchmarksStr;return benchmarksStr+'\n'+start.toString();});class GenericSetGrouping extends HistogramGrouping{constructor(name){super(name,undefined);this.callback_=this.compute_.bind(this);}
+compute_(hist){const diag=hist.diagnostics.get(this.key);if(diag===undefined)return'';const parts=Array.from(diag);parts.sort();return parts.join(',');}}
+GenericSetGrouping.NAMES=[tr.v.d.RESERVED_NAMES.ARCHITECTURES,tr.v.d.RESERVED_NAMES.BENCHMARKS,tr.v.d.RESERVED_NAMES.BOTS,tr.v.d.RESERVED_NAMES.BUILDS,tr.v.d.RESERVED_NAMES.MASTERS,tr.v.d.RESERVED_NAMES.MEMORY_AMOUNTS,tr.v.d.RESERVED_NAMES.OS_NAMES,tr.v.d.RESERVED_NAMES.OS_VERSIONS,tr.v.d.RESERVED_NAMES.PRODUCT_VERSIONS,tr.v.d.RESERVED_NAMES.STORIES,tr.v.d.RESERVED_NAMES.STORYSET_REPEATS,];for(const name of GenericSetGrouping.NAMES){new GenericSetGrouping(name);}
+class DateRangeGrouping extends HistogramGrouping{constructor(name){super(name,undefined);this.callback_=this.compute_.bind(this);}
+compute_(hist){const diag=hist.diagnostics.get(this.key);if(diag===undefined)return'';return diag.toString();}}
+DateRangeGrouping.NAMES=[tr.v.d.RESERVED_NAMES.BENCHMARK_START,tr.v.d.RESERVED_NAMES.TRACE_START,];for(const name of DateRangeGrouping.NAMES){new DateRangeGrouping(name);}
+return{HistogramGrouping,GenericSetGrouping,DateRangeGrouping,};});'use strict';tr.exportTo('tr.v',function(){class HistogramSet{constructor(opt_histograms){this.histogramsByGuid_=new Map();this.sharedDiagnosticsByGuid_=new Map();if(opt_histograms!==undefined){for(const hist of opt_histograms){this.addHistogram(hist);}}}
+createHistogram(name,unit,samples,opt_options){const hist=tr.v.Histogram.create(name,unit,samples,opt_options);this.addHistogram(hist);return hist;}
+addHistogram(hist,opt_diagnostics){if(this.histogramsByGuid_.has(hist.guid)){throw new Error('Cannot add same Histogram twice');}
+if(opt_diagnostics!==undefined){if(!(opt_diagnostics instanceof Map)){opt_diagnostics=Object.entries(opt_diagnostics);}
+for(const[name,diagnostic]of opt_diagnostics){hist.diagnostics.set(name,diagnostic);}}
+this.histogramsByGuid_.set(hist.guid,hist);}
+addSharedDiagnostic(name,diagnostic){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);for(const hist of this){hist.diagnostics.set(name,diagnostic);}}
+get length(){return this.histogramsByGuid_.size;}*[Symbol.iterator](){for(const hist of this.histogramsByGuid_.values()){yield hist;}}
+getHistogramsNamed(name){return[...this].filter(h=>h.name===name);}
+getHistogramNamed(name){const histograms=this.getHistogramsNamed(name);if(histograms.length===0)return undefined;if(histograms.length>1){throw new Error(`Unexpectedly found multiple histograms named "${name}"`);}
+return histograms[0];}
+lookupHistogram(guid){return this.histogramsByGuid_.get(guid);}
+lookupDiagnostic(guid){return this.sharedDiagnosticsByGuid_.get(guid);}
+resolveRelatedHistograms(){const handleDiagnosticMap=dm=>{for(const[name,diagnostic]of dm){if(diagnostic instanceof tr.v.d.RelatedHistogramMap){diagnostic.resolve(this);}}};for(const hist of this){hist.diagnostics.resolveSharedDiagnostics(this);handleDiagnosticMap(hist.diagnostics);for(const dm of hist.nanDiagnosticMaps){handleDiagnosticMap(dm);}
+for(const bin of hist.allBins){for(const dm of bin.diagnosticMaps){handleDiagnosticMap(dm);}}}}
+importDicts(dicts){for(const dict of dicts){if(dict.type&&tr.v.d.Diagnostic.findTypeInfoWithName(dict.type)){this.sharedDiagnosticsByGuid_.set(dict.guid,tr.v.d.Diagnostic.fromDict(dict));}else{this.addHistogram(tr.v.Histogram.fromDict(dict));}}}
+asDicts(){const dicts=[];for(const diagnostic of this.sharedDiagnosticsByGuid_.values()){dicts.push(diagnostic.asDict());}
+for(const hist of this){dicts.push(hist.asDict());}
+return dicts;}
+get sourceHistograms(){const sourceHistograms=new Map(this.histogramsByGuid_);function deleteSourceHistograms(diagnosticMap){for(const[name,diagnostic]of diagnosticMap){if(diagnostic instanceof tr.v.d.RelatedHistogramMap){for(const[name,relatedHist]of diagnostic){sourceHistograms.delete(relatedHist.guid);}}}}
+for(const hist of this){deleteSourceHistograms(hist.diagnostics);for(const dm of hist.nanDiagnosticMaps){deleteSourceHistograms(dm);}
+for(const b of hist.allBins){for(const dm of b.diagnosticMaps){deleteSourceHistograms(dm);}}}
+return new HistogramSet([...sourceHistograms.values()]);}
+groupHistogramsRecursively(groupings,opt_skipGroupingCallback){function recurse(histograms,level){if(level===groupings.length){return histograms;}
+const grouping=groupings[level];const groupedHistograms=tr.b.groupIntoMap(histograms,grouping.callback);if(opt_skipGroupingCallback&&opt_skipGroupingCallback(grouping,groupedHistograms)){return recurse(histograms,level+1);}
+for(const[key,group]of groupedHistograms){groupedHistograms.set(key,recurse(group,level+1));}
+return groupedHistograms;}
+return recurse([...this],0);}
+deduplicateDiagnostics(){const namesToCandidates=new Map();const diagnosticsToHistograms=new Map();for(const hist of this){for(const[name,candidate]of hist.diagnostics){if(candidate.equals===undefined)continue;diagnosticsToHistograms.set(candidate,hist);if(!namesToCandidates.has(name)){namesToCandidates.set(name,new Set());}
+namesToCandidates.get(name).add(candidate);}}
+for(const[name,candidates]of namesToCandidates){const diagnosticsToCounts=new Map();for(const candidate of candidates){let found=false;for(const[test,count]of diagnosticsToCounts){if(candidate.equals(test)){const hist=diagnosticsToHistograms.get(candidate);hist.diagnostics.set(name,test);diagnosticsToCounts.set(test,count+1);found=true;break;}}
+if(!found){diagnosticsToCounts.set(candidate,1);}}
+for(const[diagnostic,count]of diagnosticsToCounts){if(count>1){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);}}}}
+buildGroupingsFromTags(names){const tags=new Map();for(const hist of this){for(const name of names){if(!hist.diagnostics.has(name))continue;if(!tags.has(name))tags.set(name,new Set());for(const tag of hist.diagnostics.get(name)){tags.get(name).add(tag);}}}
+const groupings=[];for(const[name,values]of tags){const built=tr.v.HistogramGrouping.buildFromTags(values,name);for(const grouping of built){groupings.push(grouping);}}
+return groupings;}
+mergeRelationships(){for(const hist of this){hist.diagnostics.mergeRelationships(hist);}}}
+return{HistogramSet,};});'use strict';tr.exportTo('tr.e.chrome',function(){function hasTitleAndCategory(event,title,category){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+function getNavStartTimestamps(rendererHelper){const navStartTimestamps=[];for(const e of rendererHelper.mainThread.sliceGroup.childEvents()){if(hasTitleAndCategory(e,'navigationStart','blink.user_timing')){navStartTimestamps.push(e.start);}}
+return navStartTimestamps;}
+function getInteractiveTimestamps(model){const interactiveTimestampsMap=new Map();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const timestamps=[];interactiveTimestampsMap.set(rendererHelper.pid,timestamps);const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(const sample of samples){timestamps.push(tr.b.getOnlyElement(sample.diagnostics['Navigation infos']).interactive);}}
+return interactiveTimestampsMap;}
+function getPostInteractiveTaskWindows(interactiveTimestamps,navStartTimestamps,traceEndTimestamp){let navStartTsIndex=0;let lastTaskWindowEndTs=undefined;const taskWindows=[];for(const currTTI of interactiveTimestamps){while(navStartTsIndex<navStartTimestamps.length&&navStartTimestamps[navStartTsIndex]<currTTI){navStartTsIndex++;}
+const taskWindowEndTs=navStartTsIndex<navStartTimestamps.length?navStartTimestamps[navStartTsIndex]:traceEndTimestamp;if(taskWindowEndTs===lastTaskWindowEndTs){throw Error('Encountered two consecutive interactive timestamps '+'with no navigationStart between them. '+'PostInteractiveTaskWindow is not well defined in this case.');}
+taskWindows.push(tr.b.math.Range.fromExplicitRange(currTTI,taskWindowEndTs));lastTaskWindowEndTs=taskWindowEndTs;}
+return taskWindows;}
+function contributionToEQT(window,task){const startInWindow=Math.max(window.min,task.start);const endInWindow=Math.min(window.max,task.end);const durationInWindow=endInWindow-startInWindow;if(durationInWindow<=0)return 0;const probabilityOfTask=durationInWindow/(window.max-window.min);const minQueueingTime=task.end-endInWindow;const maxQueueingTime=task.end-startInWindow;const expectedQueueingTimeDueToTask=(maxQueueingTime+minQueueingTime)/2;return probabilityOfTask*expectedQueueingTimeDueToTask;}
+function weightedExpectedQueueingTime(window,weightedTasks){let result=0;for(const task of weightedTasks){result+=contributionToEQT(window,task)*task.weight;}
+return result;}
+function expectedQueueingTime(window,tasks){return weightedExpectedQueueingTime(window,tasks.map(function(task){return{start:task.start,end:task.end,weight:1};}));}
+class SlidingWindow{constructor(startTime,windowSize,sortedTasks){this.windowSize_=windowSize;this.sortedTasks_=sortedTasks;this.range_=tr.b.math.Range.fromExplicitRange(startTime,startTime+windowSize);this.firstTaskIndex_=sortedTasks.findIndex(task=>startTime<task.end);if(this.firstTaskIndex_===-1){this.firstTaskIndex_=sortedTasks.length;}
+this.lastTaskIndex_=-1;while(this.lastTaskIndex_+1<sortedTasks.length&&sortedTasks[this.lastTaskIndex_+1].start<startTime+windowSize){this.lastTaskIndex_++;}
+this.innerEQT_=0;for(let i=this.firstTaskIndex_+1;i<this.lastTaskIndex_;i++){this.innerEQT_+=contributionToEQT(this.range_,sortedTasks[i]);}}
+get getEQT(){let firstTaskEQT=0;if(this.firstTaskIndex_<this.sortedTasks_.length){firstTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}
+let lastTaskEQT=0;if(this.firstTaskIndex_<this.lastTaskIndex_){lastTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
+return firstTaskEQT+this.innerEQT_+lastTaskEQT;}
+slide(t){this.range_=tr.b.math.Range.fromExplicitRange(t,t+this.windowSize_);if(this.firstTaskIndex_<this.sortedTasks_.length&&this.sortedTasks_[this.firstTaskIndex_].end<=t){this.firstTaskIndex_++;if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_-=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}}
+if(this.lastTaskIndex_+1<this.sortedTasks_.length&&this.sortedTasks_[this.lastTaskIndex_+1].start<t+this.windowSize_){if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_+=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
+this.lastTaskIndex_++;}}}
+function maxExpectedQueueingTimeInSlidingWindow(startTime,endTime,windowSize,tasks){if(windowSize<=0){throw Error('The window size must be positive number');}
+if(startTime+windowSize>endTime){throw Error('The sliding window must fit in the specified time range');}
+const sortedTasks=tasks.slice().sort((a,b)=>a.start-b.start);for(let i=1;i<sortedTasks.length;i++){const PRECISION_MS=0.1;if(sortedTasks[i-1].end>sortedTasks[i].start+PRECISION_MS){throw Error('Tasks must not overlap');}
+if(sortedTasks[i-1].end>sortedTasks[i].start){const midpoint=(sortedTasks[i-1].end+sortedTasks[i].start)/2;sortedTasks[i-1].end=midpoint;sortedTasks[i].start=midpoint;}}
+let endpoints=[];endpoints.push(startTime);endpoints.push(endTime-windowSize);for(const task of tasks){endpoints.push(task.start-windowSize);endpoints.push(task.start);endpoints.push(task.end-windowSize);endpoints.push(task.end);}
+endpoints=endpoints.filter(x=>(startTime<=x&&x+windowSize<=endTime));endpoints.sort((a,b)=>a-b);const slidingWindow=new SlidingWindow(endpoints[0],windowSize,sortedTasks);let maxEQT=0;for(const t of endpoints){slidingWindow.slide(t);maxEQT=Math.max(maxEQT,slidingWindow.getEQT);}
+return maxEQT;}
+return{getPostInteractiveTaskWindows,getNavStartTimestamps,getInteractiveTimestamps,expectedQueueingTime,maxExpectedQueueingTimeInSlidingWindow,weightedExpectedQueueingTime};});'use strict';tr.exportTo('tr.metrics.sh',function(){const WINDOW_SIZE_MS=500;const EQT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,WINDOW_SIZE_MS,50);function containsForcedGC_(slice){return slice.findTopmostSlicesRelativeToThisSlice(tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length>0;}
+function createHistogramForEQT_(name,description){const histogram=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,EQT_BOUNDARIES);histogram.customizeSummaryOptions({avg:false,count:false,max:true,min:false,std:false,sum:false,});histogram.description=description;return histogram;}
+function expectedQueueingTimeMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);const rendererToInteractiveTimestamps=tr.e.chrome.getInteractiveTimestamps(model);addExpectedQueueingTimeMetric_('renderer_eqt',event=>{return{start:event.start,duration:event.duration};},rendererHelpers,rendererToInteractiveTimestamps,histograms,model);addExpectedQueueingTimeMetric_('renderer_eqt_cpu',event=>{return{start:event.cpuStart,duration:event.cpuDuration};},rendererHelpers,rendererToInteractiveTimestamps,histograms,model);}
+function addExpectedQueueingTimeMetric_(eqtName,getEventTimes,rendererHelpers,rendererToInteractiveTimestamps,histograms,model){function getTasks(rendererHelper){const tasks=[];for(const slice of rendererHelper.mainThread.sliceGroup.topLevelSlices){const times=getEventTimes(slice);if(times.duration>0&&!containsForcedGC_(slice)){tasks.push({start:times.start,end:times.start+times.duration});}}
+return tasks;}
+const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:${eqtName}`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:${eqtName}`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer while the page is interactive');for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=getTasks(rendererHelper);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
+const interactiveWindow=tr.b.math.Range.fromExplicitRange(interactiveTimestamps[0],Infinity).findIntersection(rendererHelper.mainThread.bounds);interactiveHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(interactiveWindow.min,interactiveWindow.max,WINDOW_SIZE_MS,tasks));}
+addV8ContributionToExpectedQueueingTime_(eqtName,getEventTimes,totalHistogram,interactiveHistogram,rendererToInteractiveTimestamps,histograms,model);histograms.addHistogram(totalHistogram);histograms.addHistogram(interactiveHistogram);}
+function addV8ContributionToExpectedQueueingTime_(eqtName,getEventTimes,totalEqtHistogram,interactiveEqtHistogram,rendererToInteractiveTimestamps,histograms,model){if(!model.categories.includes('v8'))return;const breakdownForTotal=new tr.v.d.RelatedHistogramMap();const breakdownForInteractive=new tr.v.d.RelatedHistogramMap();const eventNamesWithTaskExtractors=getV8EventNamesWithTaskExtractors_(getEventTimes);for(const[eventName,getTasks]of eventNamesWithTaskExtractors){const contribution=contributionToExpectedQueueingTime_(eqtName,eventName,getTasks,rendererToInteractiveTimestamps,histograms,model);breakdownForTotal.set(eventName,contribution.total);breakdownForInteractive.set(eventName,contribution.interactive);}
+totalEqtHistogram.diagnostics.set('v8',breakdownForTotal);interactiveEqtHistogram.diagnostics.set('v8',breakdownForInteractive);}
+function getV8EventNamesWithTaskExtractors_(getEventTimes){function durationOfTopmostSubSlices(slice,predicate,excludePredicate){let duration=0;for(const sub of slice.findTopmostSlicesRelativeToThisSlice(predicate)){duration+=getEventTimes(sub).duration;if(excludePredicate!==null&&excludePredicate!==undefined){duration-=durationOfTopmostSubSlices(sub,excludePredicate);}}
+return duration;}
+function taskExtractor(predicate,excludePredicate){return function(rendererHelper){const slices=rendererHelper.mainThread.sliceGroup.topLevelSlices;const result=[];for(const slice of slices){const times=getEventTimes(slice);if(times.duration>0&&!containsForcedGC_(slice)){const duration=durationOfTopmostSubSlices(slice,predicate,excludePredicate);result.push({start:times.start,end:times.start+duration});}}
+return result;};}
+return new Map([['v8',taskExtractor(tr.metrics.v8.utils.isV8Event)],['v8:compile',taskExtractor(tr.metrics.v8.utils.isCompileEvent)],['v8:compile:optimize',taskExtractor(tr.metrics.v8.utils.isCompileOptimizeEvent)],['v8:compile:parse',taskExtractor(tr.metrics.v8.utils.isCompileParseEvent)],['v8:compile:compile-unoptimize',taskExtractor(tr.metrics.v8.utils.isCompileUnoptimizeEvent,tr.metrics.v8.utils.isCompileParseEvent)],['v8:execute',taskExtractor(tr.metrics.v8.utils.isV8ExecuteEvent)],['v8:gc',taskExtractor(tr.metrics.v8.utils.isGarbageCollectionEvent)],['v8:gc:full-mark-compactor',taskExtractor(tr.metrics.v8.utils.isFullMarkCompactorEvent)],['v8:gc:incremental-marking',taskExtractor(tr.metrics.v8.utils.isIncrementalMarkingEvent)],['v8:gc:latency-mark-compactor',taskExtractor(tr.metrics.v8.utils.isLatencyMarkCompactorEvent)],['v8:gc:memory-mark-compactor',taskExtractor(tr.metrics.v8.utils.isMemoryMarkCompactorEvent)],['v8:gc:scavenger',taskExtractor(tr.metrics.v8.utils.isScavengerEvent)]]);}
+function contributionToExpectedQueueingTime_(eqtName,eventName,getTasks,rendererToInteractiveTimestamps,histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:${eqtName}:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer. It is computed as the maximum EQT in'+` a ${WINDOW_SIZE_MS}ms sliding window after shrinking top-level`+` tasks to contain only ${eventName} subevents`);const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:${eqtName}:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer while the page is interactive. It is computed'+` as the maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window after`+` shrinking top-level tasks to contain only ${eventName} subevents`);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=getTasks(rendererHelper);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
+const interactiveWindow=tr.b.math.Range.fromExplicitRange(interactiveTimestamps[0],Infinity).findIntersection(rendererHelper.mainThread.bounds);interactiveHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(interactiveWindow.min,interactiveWindow.max,WINDOW_SIZE_MS,tasks));}
+histograms.addHistogram(totalHistogram);histograms.addHistogram(interactiveHistogram);return{total:totalHistogram,interactive:interactiveHistogram};}
+tr.metrics.MetricRegistry.register(expectedQueueingTimeMetric);return{expectedQueueingTimeMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_MS=50;const LONGEST_TASK_MS=1000;function iterateLongTopLevelTasksOnThreadInRange(thread,opt_range,cb,opt_this){thread.sliceGroup.topLevelSlices.forEach(function(slice){if(opt_range&&!opt_range.intersectsExplicitRangeInclusive(slice.start,slice.end)){return;}
+if(slice.duration<LONG_TASK_MS)return;cb.call(opt_this,slice);});}
+function iterateRendererMainThreads(model,cb,opt_this){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper!==undefined){Object.values(modelHelper.rendererHelpers).forEach(function(rendererHelper){if(!rendererHelper.mainThread)return;cb.call(opt_this,rendererHelper.mainThread);});}}
+function longTasksMetric(histograms,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const longTaskHist=new tr.v.Histogram('long tasks',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(LONG_TASK_MS,LONGEST_TASK_MS,40));longTaskHist.description='durations of long tasks';const slices=new tr.model.EventSet();iterateRendererMainThreads(model,function(thread){iterateLongTopLevelTasksOnThreadInRange(thread,rangeOfInterest,function(task){longTaskHist.addSample(task.duration,{relatedEvents:new tr.v.d.RelatedEventSet([task])});slices.push(task);slices.addEventSet(task.descendentSlices);});});histograms.addHistogram(longTaskHist);const sampleForEvent=undefined;const breakdown=tr.v.d.RelatedHistogramBreakdown.buildFromEvents(histograms,'long tasks ',slices,e=>(model.getUserFriendlyCategoryFromEvent(e)||'unknown'),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,sampleForEvent,tr.v.HistogramBinBoundaries.createExponential(1,LONGEST_TASK_MS,40));breakdown.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;longTaskHist.diagnostics.set('category',breakdown);}
+tr.metrics.MetricRegistry.register(longTasksMetric,{supportsRangeOfInterest:true});return{longTasksMetric,iterateLongTopLevelTasksOnThreadInRange,iterateRendererMainThreads,LONG_TASK_MS,LONGEST_TASK_MS,};});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,valueCount){this.title=title;const dimensions=title.length;this.children=new Array(dimensions);for(let i=0;i<dimensions;i++){this.children[i]=new Map();}
+this.values=new Array(valueCount);for(let v=0;v<valueCount;v++){this.values[v]={self:0,total:0,totalState:NOT_PROVIDED};}}
+MultiDimensionalViewNode.TotalState={NOT_PROVIDED:0,LOWER_BOUND:1,EXACT:2};const NOT_PROVIDED=MultiDimensionalViewNode.TotalState.NOT_PROVIDED;const LOWER_BOUND=MultiDimensionalViewNode.TotalState.LOWER_BOUND;const EXACT=MultiDimensionalViewNode.TotalState.EXACT;MultiDimensionalViewNode.prototype={get subRows(){return Array.from(this.children[0].values());}};function MultiDimensionalViewBuilder(dimensions,valueCount){if(typeof(dimensions)!=='number'||dimensions<0){throw new Error('Dimensions must be a non-negative number');}
+this.dimensions_=dimensions;if(typeof(valueCount)!=='number'||valueCount<0){throw new Error('Number of values must be a non-negative number');}
+this.valueCount_=valueCount;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.complete_=false;this.maxDimensionDepths_=new Array(dimensions);for(let d=0;d<dimensions;d++){this.maxDimensionDepths_[d]=0;}}
+MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.ViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};MultiDimensionalViewBuilder.prototype={addPath(path,values,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
+if(path.length!==this.dimensions_){throw new Error('Path must be '+this.dimensions_+'-dimensional');}
+if(values.length!==this.valueCount_){throw new Error('Must provide '+this.valueCount_+' values');}
+let isTotal;switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:isTotal=false;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:isTotal=true;break;default:throw new Error('Invalid value kind: '+valueKind);}
+let node=this.buildRoot_;for(let d=0;d<path.length;d++){const singleDimensionPath=path[d];const singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(let i=0;i<singleDimensionPathLength;i++){node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}}
+for(let v=0;v<this.valueCount_;v++){const addedValue=values[v];if(addedValue===undefined)continue;const nodeValue=node.values[v];if(isTotal){nodeValue.total+=addedValue;nodeValue.totalState=EXACT;}else{nodeValue.self+=addedValue;nodeValue.totalState=Math.max(nodeValue.totalState,LOWER_BOUND);}}},get complete(){return this.complete_;},set complete(isComplete){if(this.buildRoot_===undefined){throw new Error('Can\'t set complete after any view has been built.');}
+this.complete_=isComplete;},buildView(viewType){switch(viewType){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView(){if(this.topDownTreeViewRoot_===undefined){const treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
+return this.topDownTreeViewRoot_;},buildTopDownHeavyView(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
+return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
+return this.bottomUpHeavyViewNode_;},createRootNode_(){return new MultiDimensionalViewNode(new Array(this.dimensions_),this.valueCount_);},getOrCreateChildNode_(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_){throw new Error('Invalid dimension');}
+const dimensionChildren=parentNode.children[dimension];let childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined){return childNode;}
+const childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,this.valueCount_);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_(node,firstDimensionToSetUp){for(let d=firstDimensionToSetUp;d<this.dimensions_;d++){const currentDimensionChildTitles=new Set(node.children[d].keys());for(let i=0;i<d;i++){for(const previousDimensionChildNode of node.children[i].values()){for(const previousDimensionGrandChildTitle of
+previousDimensionChildNode.children[d].keys()){currentDimensionChildTitles.add(previousDimensionGrandChildTitle);}}}
+for(const currentDimensionChildTitle of currentDimensionChildTitles){const currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(let i=0;i<d;i++){for(const previousDimensionChildNode of
+node.children[i].values()){const previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
+this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_(node,firstDimensionToFinalize,dimensionalSelfSumsMap){const dimensionalSelfSums=new Array(this.dimensions_);const minResidual=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++)minResidual[v]=0;const nodeValues=node.values;const nodeSelfSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]=nodeValues[v].self;}
+for(let d=0;d<this.dimensions_;d++){const childResidualSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){childResidualSums[v]=0;}
+for(const childNode of node.children[d].values()){if(d>=firstDimensionToFinalize){this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);}
+const childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);const childNodeValues=childNode.values;for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]+=childNodeSelfSums[d][v];const residual=childNodeValues[v].total-
+childNodeSelfSums[this.dimensions_-1][v];childResidualSums[v]+=residual;if(this.complete){nodeValues[v].totalState=EXACT;}else if(childNodeValues[v].totalState>NOT_PROVIDED){nodeValues[v].totalState=Math.max(nodeValues[v].totalState,LOWER_BOUND);}}}
+dimensionalSelfSums[d]=nodeSelfSums.slice();for(let v=0;v<this.valueCount_;v++){minResidual[v]=Math.max(minResidual[v],childResidualSums[v]);}}
+for(let v=0;v<this.valueCount_;v++){nodeValues[v].total=Math.max(nodeValues[v].total,nodeSelfSums[v]+minResidual[v]);}
+if(dimensionalSelfSumsMap.has(node)){throw new Error('Internal error: Node finalized more than once');}
+dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_(treeViewNodeHandler){const treeViewRoot=this.buildTopDownTreeView();const heavyViewRoot=this.createRootNode_();heavyViewRoot.values=treeViewRoot.values;const recursionDepthTrackers=new Array(this.dimensions_);for(let d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
+this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(let d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){const treeViewChildren=treeViewParentNode.children[currentDimension];const recursionDepthTracker=recursionDepthTrackers[currentDimension];for(const treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;const dimensionTitle=treeViewChildNode.title[currentDimension];const heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);this.addNodeValues_(treeViewChildNode,heavyViewChildNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(const treeViewGrandChildNode of
+treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const bottomIndex=recursionDepthTracker.bottomIndex;const topIndex=recursionDepthTracker.topIndex;const firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;const viewNodePath=recursionDepthTracker.viewNodePath;const trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;let heavyViewDescendantNode=heavyViewParentNode;for(let i=bottomIndex;i<topIndex;i++){const treeViewAncestorNode=viewNodePath[i];const dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);const currentDimensionRecursive=i<firstNonRecursiveIndex;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;this.addNodeValues_(treeViewChildNode,heavyViewDescendantNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}},addNodeValues_(sourceNode,targetNode,addTotal){const targetNodeValues=targetNode.values;const sourceNodeValues=sourceNode.values;for(let v=0;v<this.valueCount_;v++){const targetNodeValue=targetNodeValues[v];const sourceNodeValue=sourceNodeValues[v];targetNodeValue.self+=sourceNodeValue.self;if(addTotal){targetNodeValue.total+=sourceNodeValue.total;if(this.complete){targetNodeValue.totalState=EXACT;}else if(sourceNodeValue.totalState>NOT_PROVIDED){targetNodeValue.totalState=Math.max(targetNodeValue.totalState,LOWER_BOUND);}}}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
+RecursionDepthTracker.prototype={push(viewNode){if(this.bottomIndex===0){throw new Error('Cannot push to a full tracker');}
+const title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;let childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
+const maxLengths=zFunction(this.titlePath,this.bottomIndex);let recursionDepth=0;for(let i=0;i<maxLengths.length;i++){recursionDepth=Math.max(recursionDepth,maxLengths[i]);}
+childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop(){if(this.bottomIndex===this.topIndex){throw new Error('Cannot pop from an empty tracker');}
+this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_(recursionDepth,parent){return{recursionDepth,parent,children:new Map()};}};function zFunction(list,startIndex){const n=list.length-startIndex;if(n===0)return[];const z=new Array(n);z[0]=0;for(let i=1,left=0,right=0;i<n;++i){let maxLength;if(i<=right){maxLength=Math.min(right-i+1,z[i-left]);}else{maxLength=0;}
+while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
+if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
+z[i]=maxLength;}
+return z;}
+return{MultiDimensionalViewBuilder,MultiDimensionalViewNode,RecursionDepthTracker,zFunction,};});'use strict';tr.exportTo('tr.b',function(){class FixedColorScheme{constructor(namesToColors){this.namesToColors_=namesToColors;}
+static fromNames(names){const namesToColors=new Map();const generator=new tr.b.SinebowColorGenerator();for(const name of names){namesToColors.set(name,generator.colorForKey(name));}
+return new FixedColorScheme(namesToColors);}
+getColor(name){const color=this.namesToColors_.get(name);if(color===undefined)throw new Error('Unknown color: '+name);return color;}}
+const MemoryColumnColorScheme=new FixedColorScheme(new Map([['used_memory_column',new tr.b.Color(0,0,255)],['older_used_memory_column',new tr.b.Color(153,204,255)],['tracing_memory_column',new tr.b.Color(153,153,153)]]));function FixedColorSchemeRegistry(){}
+FixedColorSchemeRegistry.lookUp=function(name){const info=this.findTypeInfoMatching(info=>info.metadata.name===name);if(!info)return undefined;return info.constructor();};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(FixedColorSchemeRegistry,options);return{MemoryColumnColorScheme,FixedColorScheme,FixedColorSchemeRegistry,};});'use strict';tr.exportTo('tr.e.chrome.chrome_processes',function(){const CHROME_PROCESS_NAMES={BROWSER:'browser_process',RENDERER:'renderer_processes',ALL:'all_processes',GPU:'gpu_process',PPAPI:'ppapi_process',UNKNOWN:'unknown_processes',};const PROCESS_COLOR_SCHEME_NAME='ChromeProcessNames';const PROCESS_COLOR_SCHEME=tr.b.FixedColorScheme.fromNames(Object.values(CHROME_PROCESS_NAMES));tr.b.FixedColorSchemeRegistry.register(()=>PROCESS_COLOR_SCHEME,{name:PROCESS_COLOR_SCHEME_NAME,});function canonicalizeName(name){return name.toLowerCase().replace(' ','_');}
+function canonicalizeProcessName(rawProcessName){if(!rawProcessName)return CHROME_PROCESS_NAMES.UNKNOWN;const baseCanonicalName=canonicalizeName(rawProcessName);switch(baseCanonicalName){case'renderer':return CHROME_PROCESS_NAMES.RENDERER;case'browser':return CHROME_PROCESS_NAMES.BROWSER;}
+if(Object.values(CHROME_PROCESS_NAMES).includes(baseCanonicalName)){return baseCanonicalName;}
+throw new Error(`Unknown process name "${baseCanonicalName}".`+' Please add it to |CHROME_PROCESS_NAMES|.');}
+return{CHROME_PROCESS_NAMES,PROCESS_COLOR_SCHEME,PROCESS_COLOR_SCHEME_NAME,canonicalizeName,canonicalizeProcessName,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const LEVEL_OF_DETAIL_NAMES=new Map();LEVEL_OF_DETAIL_NAMES.set(BACKGROUND,'background');LEVEL_OF_DETAIL_NAMES.set(LIGHT,'light');LEVEL_OF_DETAIL_NAMES.set(DETAILED,'detailed');const HEAP_PROFILER_DETAIL_NAME='heap_profiler';const BOUNDARIES_FOR_UNIT_MAP=new WeakMap();BOUNDARIES_FOR_UNIT_MAP.set(count_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,20,20));BOUNDARIES_FOR_UNIT_MAP.set(sizeInBytes_smallerIsBetter,new tr.v.HistogramBinBoundaries(0).addBinBoundary(1024).addExponentialBins(16*1024*1024*1024,4*24));const CHROME_PROCESS_NAMES=tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES;function memoryMetric(values,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const browserNameToGlobalDumps=splitGlobalDumpsByBrowserName(model,rangeOfInterest);addGeneralMemoryDumpValues(browserNameToGlobalDumps,values);addDetailedMemoryDumpValues(browserNameToGlobalDumps,values);addMemoryDumpCountValues(browserNameToGlobalDumps,values);}
+function splitGlobalDumpsByBrowserName(model,opt_rangeOfInterest){const chromeModelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const browserNameToGlobalDumps=new Map();const globalDumpToBrowserHelper=new WeakMap();if(chromeModelHelper){chromeModelHelper.browserHelpers.forEach(function(helper){const globalDumps=skipDumpsThatDoNotIntersectRange(helper.process.memoryDumps.map(d=>d.globalMemoryDump),opt_rangeOfInterest);globalDumps.forEach(function(globalDump){const existingHelper=globalDumpToBrowserHelper.get(globalDump);if(existingHelper!==undefined){throw new Error('Memory dump ID clash across multiple browsers '+'with PIDs: '+existingHelper.pid+' and '+helper.pid);}
+globalDumpToBrowserHelper.set(globalDump,helper);});makeKeyUniqueAndSet(browserNameToGlobalDumps,tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName),globalDumps);});}
+const unclassifiedGlobalDumps=skipDumpsThatDoNotIntersectRange(model.globalMemoryDumps.filter(g=>!globalDumpToBrowserHelper.has(g)),opt_rangeOfInterest);if(unclassifiedGlobalDumps.length>0){makeKeyUniqueAndSet(browserNameToGlobalDumps,'unknown_browser',unclassifiedGlobalDumps);}
+return browserNameToGlobalDumps;}
+function skipDumpsThatDoNotIntersectRange(dumps,opt_range){if(!opt_range)return dumps;return dumps.filter(d=>opt_range.intersectsExplicitRangeInclusive(d.start,d.end));}
+const USER_FRIENDLY_BROWSER_NAMES={'chrome':'Chrome','webview':'WebView','unknown_browser':'an unknown browser'};function convertBrowserNameToUserFriendlyName(browserName){for(const baseName in USER_FRIENDLY_BROWSER_NAMES){if(!browserName.startsWith(baseName))continue;const userFriendlyBaseName=USER_FRIENDLY_BROWSER_NAMES[baseName];const suffix=browserName.substring(baseName.length);if(suffix.length===0){return userFriendlyBaseName;}else if(/^\d+$/.test(suffix)){return userFriendlyBaseName+'('+suffix+')';}}
+return'\''+browserName+'\' browser';}
+function convertProcessNameToUserFriendlyName(processName,opt_requirePlural){switch(processName){case CHROME_PROCESS_NAMES.BROWSER:return opt_requirePlural?'browser processes':'the browser process';case CHROME_PROCESS_NAMES.RENDERER:return'renderer processes';case CHROME_PROCESS_NAMES.GPU:return opt_requirePlural?'GPU processes':'the GPU process';case CHROME_PROCESS_NAMES.PPAPI:return opt_requirePlural?'PPAPI processes':'the PPAPI process';case CHROME_PROCESS_NAMES.ALL:return'all processes';case CHROME_PROCESS_NAMES.UNKNOWN:return'unknown processes';default:return'\''+processName+'\' processes';}}
+function makeKeyUniqueAndSet(map,key,value){let uniqueKey=key;let nextIndex=2;while(map.has(uniqueKey)){uniqueKey=key+nextIndex;nextIndex++;}
+map.set(uniqueKey,value);}
+function addGeneralMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,gmd=>true,function(processDump,addProcessScalar){addProcessScalar({source:'process_count',property:PROCESS_COUNT,value:1});if(processDump.totals!==undefined){addProcessScalar({source:'reported_by_os',property:RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.residentBytes});addProcessScalar({source:'reported_by_os',property:PEAK_RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.peakResidentBytes});}
+if(processDump.memoryAllocatorDumps===undefined)return;processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property,value:rootAllocatorDump.numerics[property.name]});});if(rootAllocatorDump.numerics.allocated_objects_size===undefined){const allocatedObjectsDump=rootAllocatorDump.getDescendantDumpByFullName('allocated_objects');if(allocatedObjectsDump!==undefined){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property:ALLOCATED_OBJECTS_SIZE,value:allocatedObjectsDump.numerics.size});}}});addV8MemoryDumpValues(processDump,addProcessScalar);},function(componentTree){const tracingNode=componentTree.children[1].get('tracing');if(tracingNode===undefined)return;for(let i=0;i<componentTree.values.length;i++){componentTree.values[i].total-=tracingNode.values[i].total;}},values);}
+function addV8MemoryDumpValues(processDump,addProcessScalar){const v8Dump=processDump.getMemoryAllocatorDumpByFullName('v8');if(v8Dump===undefined)return;v8Dump.children.forEach(function(isolateDump){const mallocDump=isolateDump.getDescendantDumpByFullName('malloc');if(mallocDump!==undefined){addV8ComponentValues(mallocDump,['v8','allocated_by_malloc'],addProcessScalar);}
+const heapDump=isolateDump.getDescendantDumpByFullName('heap_spaces');if(heapDump!==undefined){addV8ComponentValues(heapDump,['v8','heap'],addProcessScalar);heapDump.children.forEach(function(spaceDump){if(spaceDump.name==='other_spaces')return;addV8ComponentValues(spaceDump,['v8','heap',spaceDump.name],addProcessScalar);});}});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.code_and_metadata_size});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.bytecode_and_metadata_size});}
+function addV8ComponentValues(componentDump,componentPath,addProcessScalar){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:componentPath,property,value:componentDump.numerics[property.name]});});}
+const PROCESS_COUNT={unit:count_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){if(componentPath.length>0){throw new Error('Unexpected process count non-empty component path: '+
+componentPath.join(':'));}
+return'total number of '+convertProcessNameToUserFriendlyName(processName,true);}};const EFFECTIVE_SIZE={name:'effective_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'effective size',componentPreposition:'of'});}};const ALLOCATED_OBJECTS_SIZE={name:'allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated',totalUserFriendlyPropertyName:'size of all allocated objects',componentPreposition:'by'});}};const SHIM_ALLOCATED_OBJECTS_SIZE={name:'shim_allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated through shim',totalUserFriendlyPropertyName:'size of all allocated objects through shim',componentPreposition:'by'});}};const LOCKED_SIZE={name:'locked_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'locked (pinned) size',componentPreposition:'of'});}};const PEAK_SIZE={name:'peak_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'peak size',componentPreposition:'of'});}};const CODE_AND_METADATA_SIZE={name:'code_and_metadata_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyNamePrefix:'size of',userFriendlyPropertyName:'code and metadata'});}};const CHROME_VALUE_PROPERTIES=[EFFECTIVE_SIZE,ALLOCATED_OBJECTS_SIZE,SHIM_ALLOCATED_OBJECTS_SIZE,LOCKED_SIZE,PEAK_SIZE];function buildChromeValueDescriptionPrefix(componentPath,processName,formatSpec){const nameParts=[];if(componentPath.length===0){nameParts.push('total');if(formatSpec.totalUserFriendlyPropertyName){nameParts.push(formatSpec.totalUserFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(formatSpec.userFriendlyPropertyName);}
+nameParts.push('reported by Chrome for');}else{if(formatSpec.componentPreposition===undefined){if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(componentPath.join(':'));nameParts.push(formatSpec.userFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(formatSpec.userFriendlyPropertyName);nameParts.push(formatSpec.componentPreposition);if(componentPath[componentPath.length-1]==='allocated_by_malloc'){nameParts.push('objects allocated by malloc for');nameParts.push(componentPath.slice(0,componentPath.length-1).join(':'));}else{nameParts.push(componentPath.join(':'));}}
+nameParts.push('in');}
+nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
+const RESIDENT_SIZE={name:'resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'resident set size (RSS)');}};const PEAK_RESIDENT_SIZE={name:'peak_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'peak resident set size');}};const PROPORTIONAL_RESIDENT_SIZE={name:'proportional_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'proportional resident size (PSS)');}};const PRIVATE_DIRTY_SIZE={name:'private_dirty_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'private dirty size');}};function buildOsValueDescriptionPrefix(componentPath,processName,userFriendlyPropertyName){if(componentPath.length>2){throw new Error('OS value component path for \''+
+userFriendlyPropertyName+'\' too long: '+componentPath.join(':'));}
+const nameParts=[];if(componentPath.length<2){nameParts.push('total');}
+nameParts.push(userFriendlyPropertyName);if(componentPath.length>0){switch(componentPath[0]){case'system_memory':if(componentPath.length>1){const userFriendlyComponentName=SYSTEM_VALUE_COMPONENTS[componentPath[1]].userFriendlyName;if(userFriendlyComponentName===undefined){throw new Error('System value sub-component for \''+
+userFriendlyPropertyName+'\' unknown: '+
+componentPath.join(':'));}
+nameParts.push('of',userFriendlyComponentName,'in');}else{nameParts.push('of system memory (RAM) used by');}
+break;case'gpu_memory':if(componentPath.length>1){nameParts.push('of the',componentPath[1]);nameParts.push('Android memtrack component in');}else{nameParts.push('of GPU memory (Android memtrack) used by');}
+break;default:throw new Error('OS value component for \''+
+userFriendlyPropertyName+'\' unknown: '+
+componentPath.join(':'));}}else{nameParts.push('reported by the OS for');}
+nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
+function addDetailedMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,g=>g.levelOfDetail===DETAILED,function(processDump,addProcessScalar){for(const[componentName,componentSpec]of
+Object.entries(SYSTEM_VALUE_COMPONENTS)){const node=getDescendantVmRegionClassificationNode(processDump.vmRegions,componentSpec.classificationPath);const componentPath=['system_memory'];if(componentName)componentPath.push(componentName);addProcessScalar({source:'reported_by_os',component:componentPath,property:PROPORTIONAL_RESIDENT_SIZE,value:node===undefined?0:(node.byteStats.proportionalResident||0)});addProcessScalar({source:'reported_by_os',component:componentPath,property:PRIVATE_DIRTY_SIZE,value:node===undefined?0:(node.byteStats.privateDirtyResident||0)});}
+const memtrackDump=processDump.getMemoryAllocatorDumpByFullName('gpu/android_memtrack');if(memtrackDump!==undefined){memtrackDump.children.forEach(function(memtrackChildDump){addProcessScalar({source:'reported_by_os',component:['gpu_memory',memtrackChildDump.name],property:PROPORTIONAL_RESIDENT_SIZE,value:memtrackChildDump.numerics.memtrack_pss});});}},function(componentTree){},values);}
+const SYSTEM_VALUE_COMPONENTS={'':{classificationPath:[],},'java_heap':{classificationPath:['Android','Java runtime','Spaces'],userFriendlyName:'the Java heap'},'ashmem':{classificationPath:['Android','Ashmem'],userFriendlyName:'ashmem'},'native_heap':{classificationPath:['Native heap'],userFriendlyName:'the native heap'},'stack':{classificationPath:['Stack'],userFriendlyName:'the thread stacks'}};function getDescendantVmRegionClassificationNode(node,path){for(let i=0;i<path.length;i++){if(node===undefined)break;node=node.children.find(c=>c.title===path[i]);}
+return node;}
+function addMemoryDumpCountValues(browserNameToGlobalDumps,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){let totalDumpCount=0;const levelOfDetailNameToDumpCount={};LEVEL_OF_DETAIL_NAMES.forEach(function(levelOfDetailName){levelOfDetailNameToDumpCount[levelOfDetailName]=0;});levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]=0;globalDumps.forEach(function(globalDump){totalDumpCount++;const levelOfDetailName=LEVEL_OF_DETAIL_NAMES.get(globalDump.levelOfDetail);if(levelOfDetailName===undefined){return;}
+levelOfDetailNameToDumpCount[levelOfDetailName]++;if(globalDump.levelOfDetail===DETAILED){if(detectHeapProfilerInMemoryDump(globalDump)){levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]++;}}});reportMemoryDumpCountAsValue(browserName,undefined,totalDumpCount,values);for(const[levelOfDetailName,levelOfDetailDumpCount]of
+Object.entries(levelOfDetailNameToDumpCount)){reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values);}});}
+function detectHeapProfilerInMemoryDump(globalDump){for(const processDump of Object.values(globalDump.processMemoryDumps)){if(processDump.heapDumps&&processDump.heapDumps.malloc){const mallocDump=processDump.heapDumps.malloc;if(mallocDump.entries&&mallocDump.entries.length>0){return true;}}}
+return false;}
+function reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values){const nameParts=['memory',browserName,'all_processes','dump_count'];if(levelOfDetailName!==undefined){nameParts.push(levelOfDetailName);}
+const name=nameParts.join(':');const histogram=new tr.v.Histogram(name,count_smallerIsBetter,BOUNDARIES_FOR_UNIT_MAP.get(count_smallerIsBetter));histogram.addSample(levelOfDetailDumpCount);const userFriendlyLevelOfDetail=(levelOfDetailName||'all').replace('_',' ');histogram.description=['total number of',userFriendlyLevelOfDetail,'memory dumps added by',convertBrowserNameToUserFriendlyName(browserName),'to the trace'].join(' ');values.addHistogram(histogram);}
+function addMemoryDumpValues(browserNameToGlobalDumps,customGlobalDumpFilter,customProcessDumpValueExtractor,customComponentTreeModifier,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){const filteredGlobalDumps=globalDumps.filter(customGlobalDumpFilter);const sourceToPropertyToBuilder=extractDataFromGlobalDumps(filteredGlobalDumps,customProcessDumpValueExtractor);reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values);});}
+function extractDataFromGlobalDumps(globalDumps,customProcessDumpValueExtractor){const sourceToPropertyToBuilder=new Map();const dumpCount=globalDumps.length;globalDumps.forEach(function(globalDump,dumpIndex){for(const processDump of Object.values(globalDump.processMemoryDumps)){extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor);}});return sourceToPropertyToBuilder;}
+function extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor){const rawProcessName=processDump.process.name;const processNamePath=[tr.e.chrome.chrome_processes.canonicalizeProcessName(rawProcessName)];customProcessDumpValueExtractor(processDump,function addProcessScalar(spec){if(spec.value===undefined)return;const component=spec.component||[];function createDetailsForErrorMessage(){return['source=',spec.source,', property=',spec.property.name||'(undefined)',', component=',component.length===0?'(empty)':component.join(':'),' in ',processDump.process.userFriendlyName].join('');}
+let value;if(spec.value instanceof tr.b.Scalar){value=spec.value.value;if(spec.value.unit!==spec.property.unit){throw new Error('Scalar unit for '+
+createDetailsForErrorMessage()+' ('+
+spec.value.unit.unitName+') doesn\'t match the unit of the property ('+
+spec.property.unit.unitName+')');}}else{value=spec.value;}
+let propertyToBuilder=sourceToPropertyToBuilder.get(spec.source);if(propertyToBuilder===undefined){propertyToBuilder=new Map();sourceToPropertyToBuilder.set(spec.source,propertyToBuilder);}
+let builder=propertyToBuilder.get(spec.property);if(builder===undefined){builder=new tr.b.MultiDimensionalViewBuilder(2,dumpCount),propertyToBuilder.set(spec.property,builder);}
+const values=new Array(dumpCount);values[dumpIndex]=value;builder.addPath([processNamePath,component],values,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);});}
+function reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values){sourceToPropertyToBuilder.forEach(function(propertyToBuilder,sourceName){propertyToBuilder.forEach(function(builders,property){const tree=builders.buildTopDownTreeView();reportComponentDataAsValues(browserName,sourceName,property,[],[],tree,values,customComponentTreeModifier);});});}
+function reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,tree,values,customComponentTreeModifier,opt_cachedHistograms){const cachedHistograms=opt_cachedHistograms||new Map();function recurse(processPath,componentPath,node){return reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,node,values,customComponentTreeModifier,cachedHistograms);}
+function buildHistogram(processPath,componentPath,node){return buildNamedMemoryNumericFromNode(browserName,sourceName,property,processPath.length===0?'all_processes':processPath[0],componentPath,node);}
+customComponentTreeModifier(tree);const histogram=buildHistogram(processPath,componentPath,tree);if(cachedHistograms.has(histogram.name)){return cachedHistograms.get(histogram.name);}
+cachedHistograms.set(histogram.name,histogram);const processBreakdown=new tr.v.d.RelatedHistogramBreakdown();processBreakdown.colorScheme=tr.e.chrome.chrome_processes.PROCESS_COLOR_SCHEME_NAME;for(const[childProcessName,childProcessNode]of tree.children[0]){processPath.push(childProcessName);const childProcessHistogram=recurse(processPath,componentPath,childProcessNode);processBreakdown.set(childProcessName,childProcessHistogram);processPath.pop();}
+const componentBreakdown=new tr.v.d.RelatedHistogramBreakdown();for(const[childComponentName,childComponentNode]of tree.children[1]){componentPath.push(childComponentName);const childComponentHistogram=recurse(processPath,componentPath,childComponentNode);componentBreakdown.set(childComponentName,childComponentHistogram);componentPath.pop();}
+values.addHistogram(histogram);if(tree.children[0].size>0){histogram.diagnostics.set('processes',processBreakdown);}
+if(tree.children[1].size>0){histogram.diagnostics.set('components',componentBreakdown);}
+return histogram;}
+function getNumericName(browserName,sourceName,propertyName,processName,componentPath){const nameParts=['memory',browserName,processName,sourceName].concat(componentPath);if(propertyName!==undefined)nameParts.push(propertyName);return nameParts.join(':');}
+function getNumericDescription(property,browserName,processName,componentPath){return[property.buildDescriptionPrefix(componentPath,processName),'in',convertBrowserNameToUserFriendlyName(browserName)].join(' ');}
+function buildNamedMemoryNumericFromNode(browserName,sourceName,property,processName,componentPath,node){const name=getNumericName(browserName,sourceName,property.name,processName,componentPath);const description=getNumericDescription(property,browserName,processName,componentPath);const numeric=buildMemoryNumericFromNode(name,node,property.unit);numeric.description=description;return numeric;}
+function buildMemoryNumericFromNode(name,node,unit){const histogram=new tr.v.Histogram(name,unit,BOUNDARIES_FOR_UNIT_MAP.get(unit));node.values.forEach(v=>histogram.addSample(v.total));return histogram;}
+tr.metrics.MetricRegistry.register(memoryMetric,{supportsRangeOfInterest:true});return{memoryMetric,};});'use strict';tr.exportTo('tr.e.chrome',function(){class CpuTime{static getCpuTimeForThread(thread,range){let totalCpuTime=0;tr.b.iterateOverIntersectingIntervals(thread.sliceGroup.topLevelSlices,slice=>slice.start,slice=>slice.end,range.min,range.max,slice=>{if(slice.duration===0)return;if(!slice.cpuDuration)return;const intersection=range.findIntersection(slice.range);const fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;totalCpuTime+=slice.cpuDuration*fractionOfSliceInsideRangeOfInterest;});return totalCpuTime;}
+static getStageToInitiatorToSegmentBounds(segments,rangeOfInterest){const stageToInitiatorToRanges=new Map();stageToInitiatorToRanges.set('all_stages',new Map([['all_initiators',new Set()]]));const allRanges=stageToInitiatorToRanges.get('all_stages').get('all_initiators');for(const segment of segments){if(!rangeOfInterest.intersectsRangeInclusive(segment.range))continue;const intersectingRange=rangeOfInterest.findIntersection(segment.range);allRanges.add(intersectingRange);for(const expectation of segment.expectations){const stageTitle=expectation.stageTitle;if(!stageToInitiatorToRanges.has(stageTitle)){stageToInitiatorToRanges.set(stageTitle,new Map([['all_initiators',new Set()]]));}
+const initiatorToRanges=stageToInitiatorToRanges.get(stageTitle);initiatorToRanges.get('all_initiators').add(intersectingRange);const initiatorType=expectation.initiatorType;if(initiatorType){if(!initiatorToRanges.has(initiatorType)){initiatorToRanges.set(initiatorType,new Set());}
+initiatorToRanges.get(initiatorType).add(intersectingRange);}}}
+return stageToInitiatorToRanges;}
+static computeCpuTimesForRanges_(ranges,thread){const rangeToCpuTime=new Map();for(const range of ranges){rangeToCpuTime.set(range,CpuTime.getCpuTimeForThread(thread,range));}
+return rangeToCpuTime;}
+static constructMultiDimensionalView(model,rangeOfInterest){const mdvBuilder=new tr.b.MultiDimensionalViewBuilder(3,2);const stageToInitiatorToRanges=CpuTime.getStageToInitiatorToSegmentBounds(model.userModel.segments,rangeOfInterest);const allSegmentBoundsInRange=stageToInitiatorToRanges.get('all_stages').get('all_initiators');for(const[pid,process]of Object.entries(model.processes)){const processType=tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name);for(const[tid,thread]of Object.entries(process.threads)){const rangeToCpuTime=CpuTime.computeCpuTimesForRanges_(allSegmentBoundsInRange,thread);for(const[stage,initiatorToRanges]of stageToInitiatorToRanges){for(const[initiator,ranges]of initiatorToRanges){const cpuTime=tr.b.math.Statistics.sum(ranges,range=>rangeToCpuTime.get(range));const duration=tr.b.math.Statistics.sum(ranges,range=>range.duration);const cpuTimePerSecond=cpuTime/duration;mdvBuilder.addPath([[processType],[thread.type],[stage,initiator]],[cpuTimePerSecond,cpuTime],tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);}}}}
+return mdvBuilder.buildTopDownTreeView();}}
+return{CpuTime,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CPU_PERCENTAGE_UNIT=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const CPU_TIME_UNIT=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;function clonePath_(previousPath){return previousPath.map(subPath=>subPath.map(x=>x));}
+function decodePath_(path){return{processType:path[0][0],threadType:path[1][0],railStage:path[2][0],initiatorType:path[2][1]};}
+function stringifyPathName_(path){const decodedPath=decodePath_(path);return[decodedPath.processType,decodedPath.threadType,decodedPath.railStage,decodedPath.initiatorType].join(':');}
+class CpuTimeTreeDataReporter{constructor(){this.visitedSet_=new Set();}
+reportValuesFromNode_(node,path){const decodedPath=decodePath_(path);const processType=decodedPath.processType||'all_processes';const threadType=decodedPath.threadType||'all_threads';if(!decodedPath.railStage||!decodedPath.initiatorType)return;const{railStage,initiatorType}=decodedPath;const serializedPathName=[processType,threadType,railStage,initiatorType].join(':');const cpuPercentageValue=node.values[0].total;const cpuTimeValue=node.values[1].total;this.histogramSet_.createHistogram(`cpuPercentage:${serializedPathName}`,CPU_PERCENTAGE_UNIT,cpuPercentageValue);this.histogramSet_.createHistogram(`cpuTime:${serializedPathName}`,CPU_TIME_UNIT,cpuTimeValue);}
+reportDataFromTree_(root,rootPath){const rootPathString=stringifyPathName_(rootPath);if(this.visitedSet_.has(rootPathString))return;this.visitedSet_.add(rootPathString);this.reportValuesFromNode_(root,rootPath);for(let dimension=0;dimension<root.children.length;dimension++){const children=root.children[dimension];for(const[name,node]of children){const childPath=clonePath_(rootPath);childPath[dimension].push(name);this.reportDataFromTree_(node,childPath);}}}
+addTreeValuesToHistogramSet(rootNode,histogramSet){const rootPath=[[],[],[]];this.rootNode_=rootNode;this.histogramSet_=histogramSet;this.reportDataFromTree_(this.rootNode_,rootPath);}
+static reportToHistogramSet(rootNode,histogramSet){const reporter=new CpuTimeTreeDataReporter();reporter.addTreeValuesToHistogramSet(rootNode,histogramSet);}}
+return{CpuTimeTreeDataReporter,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function newCpuTimeMetric(histograms,model,opt_options){const rangeOfInterest=opt_options&&opt_options.rangeOfInterest?opt_options.rangeOfInterest:model.bounds;const rootNode=tr.e.chrome.CpuTime.constructMultiDimensionalView(model,rangeOfInterest);tr.metrics.sh.CpuTimeTreeDataReporter.reportToHistogramSet(rootNode,histograms);}
+tr.metrics.MetricRegistry.register(newCpuTimeMetric,{supportsRangeOfInterest:true});return{newCpuTimeMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CHROME_POWER_GRACE_PERIOD_MS=1;function createEmptyHistogram_(interval,histograms){if(interval.perSecond){return{perSecond:true,energy:histograms.createHistogram(`${interval.name}:power`,tr.b.Unit.byName.powerInWatts_smallerIsBetter,[],{description:`Energy consumption rate for ${interval.description}`,summaryOptions:{avg:true,count:false,max:true,min:true,std:false,sum:false,},}),};}
+return{perSecond:false,energy:histograms.createHistogram(`${interval.name}:energy`,tr.b.Unit.byName.energyInJoules_smallerIsBetter,[],{description:`Energy consumed in ${interval.description}`,summaryOptions:{avg:false,count:false,max:true,min:true,std:false,sum:true,},}),};}
+function createHistograms_(data,interval,histograms){if(data.histograms[interval.name]===undefined){data.histograms[interval.name]=createEmptyHistogram_(interval,histograms);}
+if(data.histograms[interval.name].perSecond){for(const sample of data.model.device.powerSeries.getSamplesWithinRange(interval.bounds.min,interval.bounds.max)){data.histograms[interval.name].energy.addSample(sample.powerInW);}}else{const energyInJ=data.model.device.powerSeries.getEnergyConsumedInJ(interval.bounds.min,interval.bounds.max);data.histograms[interval.name].energy.addSample(energyInJ);}}
+function getNavigationTTIIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const intervals=[];for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(const sample of samples){const info=tr.b.getOnlyElement(sample.diagnostics['Navigation infos']);intervals.push(tr.b.math.Range.fromExplicitRange(info.start,info.interactive));}}
+return intervals.sort((x,y)=>x.min-y.min);}
+function*computeTimeIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const powerSeries=model.device.powerSeries;if(powerSeries===undefined||powerSeries.samples.length===0){return;}
+yield{bounds:model.bounds,name:'story',description:'user story',perSecond:true};const chromeBounds=computeChromeBounds_(model);if(chromeBounds.isEmpty)return;const powerSeriesBoundsWithGracePeriod=tr.b.math.Range.fromExplicitRange(powerSeries.bounds.min-CHROME_POWER_GRACE_PERIOD_MS,powerSeries.bounds.max+CHROME_POWER_GRACE_PERIOD_MS);if(!powerSeriesBoundsWithGracePeriod.containsRangeExclusive(chromeBounds)){return;}
+for(const interval of getRailStageIntervals_(model)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}
+for(const interval of getLoadingIntervals_(model,chromeBounds)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}}
+function*getRailStageIntervals_(model){for(const exp of model.userModel.expectations){const histogramName=exp.title.toLowerCase().replace(' ','_');const energyHist=undefined;if(histogramName.includes('response')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:false};}else if(histogramName.includes('animation')||histogramName.includes('idle')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:true};}}}
+function*getLoadingIntervals_(model,chromeBounds){const ttiIntervals=getNavigationTTIIntervals_(model);let lastLoadTime=undefined;for(const ttiInterval of ttiIntervals){yield{bounds:ttiInterval,name:'load',description:'page loads',perSecond:false};lastLoadTime=lastLoadTime===undefined?ttiInterval.max:Math.max(lastLoadTime,ttiInterval.max);}
+if(lastLoadTime!==undefined){yield{bounds:tr.b.math.Range.fromExplicitRange(lastLoadTime,chromeBounds.max),name:'after_load',description:'period after load',perSecond:true};}}
+function computeChromeBounds_(model){const chromeBounds=new tr.b.math.Range();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return chromeBounds;for(const helper of chromeHelper.browserHelpers){if(helper.mainThread){chromeBounds.addRange(helper.mainThread.bounds);}}
+for(const pid in chromeHelper.rendererHelpers){if(chromeHelper.rendererHelpers[pid].mainThread){chromeBounds.addRange(chromeHelper.rendererHelpers[pid].mainThread.bounds);}}
+return chromeBounds;}
+function powerMetric(histograms,model){const data={model,histograms:{}};for(const interval of computeTimeIntervals_(model)){createHistograms_(data,interval,histograms);}}
+tr.metrics.MetricRegistry.register(powerMetric);return{powerMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function computeAnimationThroughput(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
+animationExpectation.stableId);}
+const durationInS=tr.b.convertUnit(animationExpectation.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return animationExpectation.frameEvents.length/durationInS;}
+function computeAnimationframeTimeDiscrepancy(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
+animationExpectation.stableId);}
+let frameTimestamps=animationExpectation.frameEvents;frameTimestamps=frameTimestamps.toArray().map(function(event){return event.start;});const absolute=true;return tr.b.math.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);}
+function responsivenessMetric(histograms,model,opt_options){const responseNumeric=new tr.v.Histogram('response latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(100,1e3,50));const throughputNumeric=new tr.v.Histogram('animation throughput',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,tr.v.HistogramBinBoundaries.createLinear(10,60,10));const frameTimeDiscrepancyNumeric=new tr.v.Histogram('animation frameTimeDiscrepancy',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,1e3,50).addExponentialBins(1e4,10));const latencyNumeric=new tr.v.Histogram('animation latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,300,60));model.userModel.expectations.forEach(function(ue){if(opt_options&&opt_options.rangeOfInterest&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){return;}
+const sampleDiagnosticMap=tr.v.d.DiagnosticMap.fromObject({relatedEvents:new tr.v.d.RelatedEventSet([ue])});if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.StartupExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){}else if(ue instanceof tr.model.um.ResponseExpectation){responseNumeric.addSample(ue.duration,sampleDiagnosticMap);}else if(ue instanceof tr.model.um.AnimationExpectation){if(ue.frameEvents===undefined||ue.frameEvents.length===0){return;}
+const throughput=computeAnimationThroughput(ue);if(throughput===undefined){throw new Error('Missing throughput for '+
+ue.stableId);}
+throughputNumeric.addSample(throughput,sampleDiagnosticMap);const frameTimeDiscrepancy=computeAnimationframeTimeDiscrepancy(ue);if(frameTimeDiscrepancy===undefined){throw new Error('Missing frameTimeDiscrepancy for '+
+ue.stableId);}
+frameTimeDiscrepancyNumeric.addSample(frameTimeDiscrepancy,sampleDiagnosticMap);ue.associatedEvents.forEach(function(event){if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){return;}
+latencyNumeric.addSample(event.duration,sampleDiagnosticMap);});}else{throw new Error('Unrecognized stage for '+ue.stableId);}});[responseNumeric,throughputNumeric,frameTimeDiscrepancyNumeric,latencyNumeric].forEach(function(numeric){numeric.customizeSummaryOptions({avg:true,max:true,min:true,std:true});});histograms.addHistogram(responseNumeric);histograms.addHistogram(throughputNumeric);histograms.addHistogram(frameTimeDiscrepancyNumeric);histograms.addHistogram(latencyNumeric);}
+tr.metrics.MetricRegistry.register(responsivenessMetric,{supportsRangeOfInterest:true});return{responsivenessMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';const startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';const loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';const loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
+if(slice.title==='WebViewBlankUrlLoadInterval'){loadWallHist.addSample(slice.duration);loadCPUHist.addSample(slice.cpuDuration);}}
+histograms.addHistogram(startupWallHist);histograms.addHistogram(startupCPUHist);histograms.addHistogram(loadWallHist);histograms.addHistogram(loadCPUHist);}
+tr.metrics.MetricRegistry.register(webviewStartupMetric);return{webviewStartupMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const MEMORY_INFRA_TRACING_CATEGORY='disabled-by-default-memory-infra';const TIME_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30);const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,30);const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e5,30);const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;function addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes){const memoryDumpCount=model.globalMemoryDumps.length;if(memoryDumpCount===0)return;let totalOverhead=0;let nonMemoryInfraThreadOverhead=0;const overheadByProvider={};for(const process of Object.values(model.processes)){for(const thread of Object.values(process.threads)){for(const slice of Object.values(thread.sliceGroup.slices)){if(slice.category!==MEMORY_INFRA_TRACING_CATEGORY)continue;totalOverhead+=slice.duration;if(thread.name!=='MemoryInfra'){nonMemoryInfraThreadOverhead+=slice.duration;}
+if(slice.args&&slice.args['dump_provider.name']){const providerName=slice.args['dump_provider.name'];let durationAndCount=overheadByProvider[providerName];if(durationAndCount===undefined){overheadByProvider[providerName]=durationAndCount={duration:0,count:0};}
+durationAndCount.duration+=slice.duration;durationAndCount.count++;}}}}
+histograms.createHistogram('memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,totalOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on all threads per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('nonmemory_thread_memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,nonMemoryInfraThreadOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on non-memory-infra threads '+'per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});for(const[providerName,overhead]of Object.entries(overheadByProvider)){histograms.createHistogram(`${providerName}_memory_dump_cpu_overhead`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,overhead.duration/overhead.count,{binBoundaries:TIME_BOUNDARIES,description:`Average CPU overhead of ${providerName} per OnMemoryDump call`,summaryOptions:SUMMARY_OPTIONS,});}
+const memoryInfraEventsSize=categoryNamesToTotalEventSizes.get(MEMORY_INFRA_TRACING_CATEGORY);const memoryInfraTraceBytesValue=new tr.v.Histogram('total_memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);memoryInfraTraceBytesValue.description='Total trace size of memory-infra dumps in bytes';memoryInfraTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);memoryInfraTraceBytesValue.addSample(memoryInfraEventsSize);histograms.addHistogram(memoryInfraTraceBytesValue);const traceBytesPerDumpValue=new tr.v.Histogram('memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);traceBytesPerDumpValue.description='Average trace size of memory-infra dumps in bytes';traceBytesPerDumpValue.customizeSummaryOptions(SUMMARY_OPTIONS);traceBytesPerDumpValue.addSample(memoryInfraEventsSize/memoryDumpCount);histograms.addHistogram(traceBytesPerDumpValue);}
+function tracingMetric(histograms,model){histograms.createHistogram('trace_import_duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,model.stats.traceImportDurationMs,{binBoundaries:TIME_BOUNDARIES,description:'Duration that trace viewer required to import the trace',summaryOptions:SUMMARY_OPTIONS,});if(!model.stats.hasEventSizesinBytes)return;const eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort((a,b)=>a.timeInterval-b.timeInterval);const totalTraceBytes=eventStats.reduce((a,b)=>a+b.totalEventSizeinBytes,0);let maxEventCountPerSec=0;let maxEventBytesPerSec=0;const INTERVALS_PER_SEC=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);let runningEventNumPerSec=0;let runningEventBytesPerSec=0;let start=0;let end=0;while(end<eventStats.length){runningEventNumPerSec+=eventStats[end].numEvents;runningEventBytesPerSec+=eventStats[end].totalEventSizeinBytes;end++;while((eventStats[end-1].timeInterval-
+eventStats[start].timeInterval)>=INTERVALS_PER_SEC){runningEventNumPerSec-=eventStats[start].numEvents;runningEventBytesPerSec-=eventStats[start].totalEventSizeinBytes;start++;}
+maxEventCountPerSec=Math.max(maxEventCountPerSec,runningEventNumPerSec);maxEventBytesPerSec=Math.max(maxEventBytesPerSec,runningEventBytesPerSec);}
+const stats=model.stats.allTraceEventStats;const categoryNamesToTotalEventSizes=(stats.reduce((map,stat)=>(map.set(stat.category,((map.get(stat.category)||0)+
+stat.totalEventSizeinBytes))),new Map()));const maxCatNameAndBytes=Array.from(categoryNamesToTotalEventSizes.entries()).reduce((a,b)=>((b[1]>=a[1])?b:a));const maxEventBytesPerCategory=maxCatNameAndBytes[1];const categoryWithMaxEventBytes=maxCatNameAndBytes[0];const maxEventCountPerSecValue=new tr.v.Histogram('peak_event_rate',tr.b.Unit.byName.count_smallerIsBetter,COUNT_BOUNDARIES);maxEventCountPerSecValue.description='Max number of events per second';maxEventCountPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventCountPerSecValue.addSample(maxEventCountPerSec);const maxEventBytesPerSecValue=new tr.v.Histogram('peak_event_size_rate',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);maxEventBytesPerSecValue.description='Max event size in bytes per second';maxEventBytesPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventBytesPerSecValue.addSample(maxEventBytesPerSec);const totalTraceBytesValue=new tr.v.Histogram('trace_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);totalTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);totalTraceBytesValue.addSample(totalTraceBytes);const biggestCategory={name:categoryWithMaxEventBytes,size_in_bytes:maxEventBytesPerCategory};totalTraceBytesValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(totalTraceBytesValue);maxEventCountPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(maxEventCountPerSecValue);maxEventBytesPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(maxEventBytesPerSecValue);addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes);}
+tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric,MEMORY_INFRA_TRACING_CATEGORY,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(4,200,100);function computeExecuteMetrics(histograms,model){const cpuTotalExecution=new tr.v.Histogram('v8_execution_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalExecution.description='cpu total time spent in script execution';const wallTotalExecution=new tr.v.Histogram('v8_execution_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalExecution.description='wall total time spent in script execution';const cpuSelfExecution=new tr.v.Histogram('v8_execution_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfExecution.description='cpu self time spent in script execution';const wallSelfExecution=new tr.v.Histogram('v8_execution_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfExecution.description='wall self time spent in script execution';for(const e of model.findTopmostSlicesNamed('V8.Execute')){cpuTotalExecution.addSample(e.cpuDuration);wallTotalExecution.addSample(e.duration);cpuSelfExecution.addSample(e.cpuSelfTime);wallSelfExecution.addSample(e.selfTime);}
+histograms.addHistogram(cpuTotalExecution);histograms.addHistogram(wallTotalExecution);histograms.addHistogram(cpuSelfExecution);histograms.addHistogram(wallSelfExecution);}
+function computeParseLazyMetrics(histograms,model){const cpuSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfParseLazy.description='cpu self time spent performing lazy parsing';const wallSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfParseLazy.description='wall self time spent performing lazy parsing';for(const e of model.findTopmostSlicesNamed('V8.ParseLazyMicroSeconds')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+for(const e of model.findTopmostSlicesNamed('V8.ParseLazy')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfParseLazy);histograms.addHistogram(wallSelfParseLazy);}
+function computeCompileFullCodeMetrics(histograms,model){const cpuSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileFullCode.description='cpu self time spent performing compiling full code';const wallSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileFullCode.description='wall self time spent performing compiling full code';for(const e of model.findTopmostSlicesNamed('V8.CompileFullCode')){cpuSelfCompileFullCode.addSample(e.cpuSelfTime);wallSelfCompileFullCode.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfCompileFullCode);histograms.addHistogram(wallSelfCompileFullCode);}
+function computeCompileIgnitionMetrics(histograms,model){const cpuSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileIgnition.description='cpu self time spent in compile ignition';const wallSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileIgnition.description='wall self time spent in compile ignition';for(const e of model.findTopmostSlicesNamed('V8.CompileIgnition')){cpuSelfCompileIgnition.addSample(e.cpuSelfTime);wallSelfCompileIgnition.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfCompileIgnition);histograms.addHistogram(wallSelfCompileIgnition);}
+function computeRecompileMetrics(histograms,model){const cpuTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileSynchronous.description='cpu total time spent in synchronous recompilation';const wallTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileSynchronous.description='wall total time spent in synchronous recompilation';const cpuTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileConcurrent.description='cpu total time spent in concurrent recompilation';const wallTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileConcurrent.description='wall total time spent in concurrent recompilation';const cpuTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileOverall.description='cpu total time spent in synchronous or concurrent recompilation';const wallTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileOverall.description='wall total time spent in synchronous or concurrent recompilation';for(const e of model.findTopmostSlicesNamed('V8.RecompileSynchronous')){cpuTotalRecompileSynchronous.addSample(e.cpuDuration);wallTotalRecompileSynchronous.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+histograms.addHistogram(cpuTotalRecompileSynchronous);histograms.addHistogram(wallTotalRecompileSynchronous);for(const e of model.findTopmostSlicesNamed('V8.RecompileConcurrent')){cpuTotalRecompileConcurrent.addSample(e.cpuDuration);wallTotalRecompileConcurrent.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+histograms.addHistogram(cpuTotalRecompileConcurrent);histograms.addHistogram(wallTotalRecompileConcurrent);histograms.addHistogram(cpuTotalRecompileOverall);histograms.addHistogram(wallTotalRecompileOverall);}
+function computeOptimizeCodeMetrics(histograms,model){const cpuTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalOptimizeCode.description='cpu total time spent in code optimization';const wallTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalOptimizeCode.description='wall total time spent in code optimization';for(const e of model.findTopmostSlicesNamed('V8.OptimizeCode')){cpuTotalOptimizeCode.addSample(e.cpuDuration);wallTotalOptimizeCode.addSample(e.duration);}
+histograms.addHistogram(cpuTotalOptimizeCode);histograms.addHistogram(wallTotalOptimizeCode);}
+function computeDeoptimizeCodeMetrics(histograms,model){const cpuTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalDeoptimizeCode.description='cpu total time spent in code deoptimization';const wallTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalDeoptimizeCode.description='wall total time spent in code deoptimization';for(const e of model.findTopmostSlicesNamed('V8.DeoptimizeCode')){cpuTotalDeoptimizeCode.addSample(e.cpuDuration);wallTotalDeoptimizeCode.addSample(e.duration);}
+histograms.addHistogram(cpuTotalDeoptimizeCode);histograms.addHistogram(wallTotalDeoptimizeCode);}
+function executionMetric(histograms,model){computeExecuteMetrics(histograms,model);computeParseLazyMetrics(histograms,model);computeCompileIgnitionMetrics(histograms,model);computeCompileFullCodeMetrics(histograms,model);computeRecompileMetrics(histograms,model);computeOptimizeCodeMetrics(histograms,model);computeDeoptimizeCodeMetrics(histograms,model);}
+tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const TARGET_FPS=60;const MS_PER_SECOND=1000;const WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;function gcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addDurationOfSubEvents(histograms,model);addPercentageInV8ExecuteOfTopEvents(histograms,model);addTotalPercentageInV8Execute(histograms,model);}
+tr.metrics.MetricRegistry.register(gcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForSubEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:false,percentile:[0.90]});return n;}
+function createNumericForIdleTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
+function createPercentage(name,numerator,denominator,unit){const hist=new tr.v.Histogram(name,unit);if(denominator===0){hist.addSample(0);}else{hist.addSample(numerator/denominator);}
+hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,percentile:[]});return hist;}
+function isNotForcedTopGarbageCollectionEvent(event){return tr.metrics.v8.utils.isTopGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
+function isNotForcedSubGarbageCollectionEvent(event){return tr.metrics.v8.utils.isSubGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addDurationOfSubEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedSubGarbageCollectionEvent,tr.metrics.v8.utils.subGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForSubEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addPercentageInV8ExecuteOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
+function addTotalPercentageInV8Execute(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
+function addPercentageInV8Execute(histograms,model,name,events){let cpuDurationInV8Execute=0;let cpuDurationTotal=0;events.forEach(function(event){const v8Execute=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isV8ExecuteEvent);if(v8Execute){cpuDurationInV8Execute+=event.cpuDuration;}
+cpuDurationTotal+=event.cpuDuration;});const percentage=createPercentage(name+'_percentage_in_v8_execute',cpuDurationInV8Execute,cpuDurationTotal,percentage_smallerIsBetter);histograms.addHistogram(percentage);}
+return{gcMetric,WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);const DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);const SUMMARY_OPTIONS={std:false,count:false,sum:false,min:false,max:false,};function computeDomContentLoadedTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let domContentLoadedTime=0;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title==='domContentLoadedEventEnd'&&ev.start>domContentLoadedTime){domContentLoadedTime=ev.start;}}}
+return domContentLoadedTime;}
+function computeInteractiveTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let interactiveTime=0;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;if(samples.length===0)continue;if(interactiveTime!==0)throw new Error('Too many navigations');const diagnostics=tr.b.getOnlyElement(samples).diagnostics;const infos=diagnostics['Navigation infos'];interactiveTime=tr.b.getOnlyElement(infos).interactive;}
+return interactiveTime;}
+function convertMicroToMilli_(time){return tr.b.convertUnit(time,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);}
+function computeRuntimeStats(histograms,slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);function addHistogramsForRuntimeGroup(runtimeGroup){const durationSamples=new tr.v.d.RelatedHistogramBreakdown();const countSamples=new tr.v.d.RelatedHistogramBreakdown();for(const entry of runtimeGroup.values){const durationSampleHistogram=histograms.createHistogram(`${entry.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(entry.time),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});durationSamples.set(durationSampleHistogram.name,durationSampleHistogram);const countSampleHistogram=histograms.createHistogram(`${entry.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,entry.count,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});countSamples.set(countSampleHistogram.name,countSampleHistogram);}
+histograms.createHistogram(`${runtimeGroup.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,{value:convertMicroToMilli_(runtimeGroup.time),diagnostics:{samples:durationSamples},},{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram(`${runtimeGroup.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,{value:runtimeGroup.count,diagnostics:{samples:countSamples},},{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});}
+for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addHistogramsForRuntimeGroup(runtimeGroup);}
+if(runtimeGroupCollection.blinkRCSGroup.count>0){addHistogramsForRuntimeGroup(runtimeGroupCollection.blinkRCSGroup);}}
+function runtimeStatsMetric(histograms,model){const interactiveTime=computeInteractiveTime_(model);const domContentLoadedTime=computeDomContentLoadedTime_(model);const endTime=Math.max(interactiveTime,domContentLoadedTime);const slices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice&&event.start<=endTime);computeRuntimeStats(histograms,slices);}
+function addDurationHistogram(railStageName,runtimeGroupName,sampleValue,histograms,durationRelatedHistsByGroupName){const durationHistogram=histograms.createHistogram(`${railStageName}_${runtimeGroupName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(sampleValue),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});if(durationRelatedHistsByGroupName.get(runtimeGroupName)===undefined){const durationHistogramMap=new tr.v.d.RelatedHistogramMap();durationHistogramMap.set(railStageName,durationHistogram);durationRelatedHistsByGroupName.set(runtimeGroupName,durationHistogramMap);}else{durationRelatedHistsByGroupName.get(runtimeGroupName).set(railStageName,durationHistogram);}}
+function addCountHistogram(railStageName,runtimeGroupName,sampleValue,histograms,countRelatedHistsByGroupName){const countHistogram=histograms.createHistogram(`${railStageName}_${runtimeGroupName}:count`,tr.b.Unit.byName.count_smallerIsBetter,sampleValue,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});if(countRelatedHistsByGroupName.get(runtimeGroupName)===undefined){const countHistogramMap=new tr.v.d.RelatedHistogramMap();countHistogramMap.set(railStageName,countHistogram);countRelatedHistsByGroupName.set(runtimeGroupName,countHistogramMap);}else{countRelatedHistsByGroupName.get(runtimeGroupName).set(railStageName,countHistogram);}}
+function addTotalDurationHistogram(histogramName,time,histograms,durationRelatedHistsByGroupName){const durationHistogram=histograms.createHistogram(`${histogramName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(time),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});const durationRelatedHistogram=durationRelatedHistsByGroupName.get(histogramName);if(durationRelatedHistogram!==undefined){durationHistogram.diagnostics.set('RAIL stages',durationRelatedHistogram);}}
+function addTotalCountHistogram(histogramName,count,histograms,countRelatedHistsByGroupName){const countHistogram=histograms.createHistogram(`${histogramName}:count`,tr.b.Unit.byName.count_smallerIsBetter,count,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});const countRelatedHistogram=countRelatedHistsByGroupName.get(histogramName);if(countRelatedHistogram!==undefined){countHistogram.diagnostics.set('RAIL stages',countRelatedHistogram);}}
+function computeRuntimeStatsBucketOnUE(histograms,slices,v8SlicesBucketOnUEMap){const durationRelatedHistsByGroupName=new Map();const countRelatedHistsByGroupName=new Map();for(const[name,slicesUE]of v8SlicesBucketOnUEMap){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slicesUE);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addDurationHistogram(name,runtimeGroup.name,runtimeGroup.time,histograms,durationRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addCountHistogram(name,runtimeGroup.name,runtimeGroup.count,histograms,countRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+addDurationHistogram(name,'V8-Only',overallV8Time,histograms,durationRelatedHistsByGroupName);addCountHistogram(name,'V8-Only',overallV8Count,histograms,countRelatedHistsByGroupName);}
+const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addTotalDurationHistogram(runtimeGroup.name,runtimeGroup.time,histograms,durationRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addTotalCountHistogram(runtimeGroup.name,runtimeGroup.count,histograms,countRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+addTotalDurationHistogram('V8-Only',overallV8Time,histograms,durationRelatedHistsByGroupName);addTotalCountHistogram('V8-Only',overallV8Count,histograms,countRelatedHistsByGroupName);}
+function runtimeStatsTotalMetric(histograms,model){const v8ThreadSlices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice).sort((e1,e2)=>e1.start-e2.start);const v8SlicesBucketOnUEMap=new Map();for(const expectation of model.userModel.expectations){const slices=expectation.range.filterArray(v8ThreadSlices,event=>event.start);if(slices.length===0)continue;const lastSlice=slices[slices.length-1];if(!expectation.range.intersectsRangeExclusive(lastSlice.range)){slices.pop();}
+if(v8SlicesBucketOnUEMap.get(expectation.stageTitle)===undefined){v8SlicesBucketOnUEMap.set(expectation.stageTitle,slices);}else{const totalSlices=v8SlicesBucketOnUEMap.get(expectation.stageTitle).concat(slices);v8SlicesBucketOnUEMap.set(expectation.stageTitle,totalSlices);}}
+computeRuntimeStatsBucketOnUE(histograms,v8ThreadSlices,v8SlicesBucketOnUEMap);}
+tr.metrics.MetricRegistry.register(runtimeStatsTotalMetric);tr.metrics.MetricRegistry.register(runtimeStatsMetric);return{runtimeStatsMetric,runtimeStatsTotalMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){function v8AndMemoryMetrics(histograms,model){tr.metrics.v8.executionMetric(histograms,model);tr.metrics.v8.gcMetric(histograms,model);tr.metrics.sh.memoryMetric(histograms,model,{rangeOfInterest:tr.metrics.v8.utils.rangeForMemoryDumps(model)});}
+tr.metrics.MetricRegistry.register(v8AndMemoryMetrics);return{v8AndMemoryMetrics,};});'use strict';tr.exportTo('tr.metrics.webrtc',function(){const DISPLAY_HERTZ=60.0;const VSYNC_DURATION_US=1e6/DISPLAY_HERTZ;const SEVERITY=3;const FROZEN_FRAME_VSYNC_COUNT_THRESHOLD=6;const WEB_MEDIA_PLAYER_UPDATE_TITLE='UpdateCurrentFrame';const IDEAL_RENDER_INSTANT_NAME='Ideal Render Instant';const ACTUAL_RENDER_BEGIN_NAME='Actual Render Begin';const ACTUAL_RENDER_END_NAME='Actual Render End';const STREAM_ID_NAME='Serial';const REQUIRED_EVENT_ARGS_NAMES=[IDEAL_RENDER_INSTANT_NAME,ACTUAL_RENDER_BEGIN_NAME,ACTUAL_RENDER_END_NAME,STREAM_ID_NAME];const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_biggerIsBetter=tr.b.Unit.byName.unitlessNumber_biggerIsBetter;function isValidEvent(event){if(event.title!==WEB_MEDIA_PLAYER_UPDATE_TITLE||!event.args){return false;}
+for(const parameter of REQUIRED_EVENT_ARGS_NAMES){if(!(parameter in event.args)){return false;}}
+return true;}
+function webrtcRenderingMetric(histograms,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let webMediaPlayerMSEvents=[];for(const rendererPid in modelHelper.rendererHelpers){const rendererHelper=modelHelper.rendererHelpers[rendererPid];const compositorThread=rendererHelper.compositorThread;if(compositorThread!==undefined){webMediaPlayerMSEvents=webMediaPlayerMSEvents.concat(compositorThread.sliceGroup.slices.filter(isValidEvent));}}
+const eventsByStreamName=tr.b.groupIntoMap(webMediaPlayerMSEvents,event=>event.args[STREAM_ID_NAME]);for(const[streamName,events]of eventsByStreamName){getTimeStats(histograms,streamName,events);}}
+tr.metrics.MetricRegistry.register(webrtcRenderingMetric);function getTimeStats(histograms,streamName,events){const frameHist=getFrameDistribution(histograms,events);addFpsFromFrameDistribution(histograms,frameHist);addFreezingScore(histograms,frameHist);const driftTimeStats=getDriftStats(events);histograms.createHistogram('WebRTCRendering_drift_time',timeDurationInMs_smallerIsBetter,driftTimeStats.driftTime,{summaryOptions:{count:false,min:false,percentile:[0.75,0.9],},});histograms.createHistogram('WebRTCRendering_rendering_length_error',percentage_smallerIsBetter,driftTimeStats.renderingLengthError,{summaryOptions:SUMMARY_OPTIONS,});const smoothnessStats=getSmoothnessStats(driftTimeStats.driftTime);histograms.createHistogram('WebRTCRendering_percent_badly_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentBadlyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_percent_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_smoothness_score',percentage_biggerIsBetter,smoothnessStats.smoothnessScore,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_out_of_sync',count_smallerIsBetter,smoothnessStats.framesOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_badly_out_of_sync',count_smallerIsBetter,smoothnessStats.framesSeverelyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});}
+const FRAME_DISTRIBUTION_BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(1,50,49);function getFrameDistribution(histograms,events){const cadence=tr.b.runLengthEncoding(events.map(e=>e.args[IDEAL_RENDER_INSTANT_NAME]));return histograms.createHistogram('WebRTCRendering_frame_distribution',count_smallerIsBetter,cadence.map(ticks=>ticks.count),{binBoundaries:FRAME_DISTRIBUTION_BIN_BOUNDARIES,summaryOptions:{percentile:[0.75,0.9],},});}
+function addFpsFromFrameDistribution(histograms,frameHist){let numberFrames=0;let numberVsyncs=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberFrames+=count;numberVsyncs+=ticks*count;}
+const meanRatio=numberVsyncs/numberFrames;histograms.createHistogram('WebRTCRendering_fps',unitlessNumber_biggerIsBetter,DISPLAY_HERTZ/meanRatio,{summaryOptions:SUMMARY_OPTIONS,});}
+function frozenPenaltyWeight(numberFrozenFrames){const penalty={5:1,6:5,7:15,8:25};return penalty[numberFrozenFrames]||(8*(numberFrozenFrames-4));}
+function addFreezingScore(histograms,frameHist){let numberVsyncs=0;let freezingScore=0;let frozenFramesCount=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberVsyncs+=ticks*count;if(ticks>=FROZEN_FRAME_VSYNC_COUNT_THRESHOLD){frozenFramesCount+=count*(ticks-1);freezingScore+=count*frozenPenaltyWeight(ticks-1);}}
+freezingScore=1-freezingScore/numberVsyncs;if(freezingScore<0){freezingScore=0;}
+histograms.createHistogram('WebRTCRendering_frozen_frames_count',count_smallerIsBetter,frozenFramesCount,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_freezing_score',percentage_biggerIsBetter,freezingScore,{summaryOptions:SUMMARY_OPTIONS,});}
+function getDriftStats(events){const driftTime=[];const discrepancy=[];let oldIdealRender=0;let expectedIdealRender=0;for(const event of events){const currentIdealRender=event.args[IDEAL_RENDER_INSTANT_NAME];expectedIdealRender+=VSYNC_DURATION_US;if(currentIdealRender===oldIdealRender){continue;}
+const actualRenderBegin=event.args[ACTUAL_RENDER_BEGIN_NAME];driftTime.push(actualRenderBegin-currentIdealRender);discrepancy.push(Math.abs(currentIdealRender-expectedIdealRender));expectedIdealRender=currentIdealRender;oldIdealRender=currentIdealRender;}
+const discrepancySum=tr.b.math.Statistics.sum(discrepancy)-
+discrepancy[0];const lastIdealRender=events[events.length-1].args[IDEAL_RENDER_INSTANT_NAME];const firstIdealRender=events[0].args[IDEAL_RENDER_INSTANT_NAME];const idealRenderSpan=lastIdealRender-firstIdealRender;const renderingLengthError=discrepancySum/idealRenderSpan;return{driftTime,renderingLengthError};}
+function getSmoothnessStats(driftTimes){const meanDriftTime=tr.b.math.Statistics.mean(driftTimes);const normDriftTimes=driftTimes.map(driftTime=>Math.abs(driftTime-meanDriftTime));const framesSeverelyOutOfSync=normDriftTimes.filter(driftTime=>driftTime>2*VSYNC_DURATION_US).length;const framesOutOfSync=normDriftTimes.filter(driftTime=>driftTime>VSYNC_DURATION_US).length;const percentBadlyOutOfSync=framesSeverelyOutOfSync/driftTimes.length;const percentOutOfSync=framesOutOfSync/driftTimes.length;const framesOutOfSyncOnlyOnce=framesOutOfSync-framesSeverelyOutOfSync;let smoothnessScore=1-(framesOutOfSyncOnlyOnce+
+SEVERITY*framesSeverelyOutOfSync)/driftTimes.length;if(smoothnessScore<0){smoothnessScore=0;}
+return{framesOutOfSync,framesSeverelyOutOfSync,percentBadlyOutOfSync,percentOutOfSync,smoothnessScore};}
+return{webrtcRenderingMetric,};});'use strict';Polymer({is:'tr-ui-a-alert-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_(alert){const rows=[];for(const argName in alert.args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.title);let valueString='';if(event instanceof tr.model.TimedEvent){valueString='took '+event.duration.toFixed(2)+'ms';}
+rows.push({name:linkEl,value:valueString});});}
+const descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_(alerts){if(alerts.length===1){const rows=[{name:'Alert',value:tr.b.getOnlyElement(alerts).title}];const detailRows=this.getRowsForSingleAlert_(tr.b.getOnlyElement(alerts));rows.push.apply(rows,detailRows);return rows;}
+return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const result=new tr.model.EventSet();for(const event of this.currentSelection_){result.addEventSet(event.associatedEvents);}
+return result;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:false,title:'Alert',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:true,title:'Alerts',});'use strict';tr.exportTo('tr.ui.analysis',function(){const NO_BREAK_SPACE=String.fromCharCode(160);const RIGHTWARDS_ARROW=String.fromCharCode(8594);const COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value(row){const formattedTitle=this.formatTitle(row);const contexts=row.contexts;if(contexts===undefined||contexts.length===0){return formattedTitle;}
+const firstContext=contexts[0];const lastContext=contexts[contexts.length-1];let changeDefinedContextCount=0;for(let i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined)){changeDefinedContextCount++;}}
+let color=undefined;let prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
+if(changeDefinedContextCount>1){color='purple';}
+if(color===undefined&&prefix===undefined){return formattedTitle;}
+const titleEl=document.createElement('span');if(prefix!==undefined){const prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';Polymer.dom(titleEl).appendChild(prefixEl);Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+if(color!==undefined){titleEl.style.color=color;}
+Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle(row){return row.title;},cmp(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.shouldSetContextGroup=false;this.aggregationMode=aggregationMode;}
+MemoryColumn.fromRows=function(rows,config){const cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)return;const fieldCells=row[config.cellKey];if(fieldCells!==undefined){for(const[fieldName,fieldCell]of Object.entries(fieldCells)){if(fieldCell===undefined||fieldCell.fields===undefined){continue;}
+cellNames.add(fieldName);}}
+const subRows=row.subRows;if(subRows!==undefined){gatherCellNames(subRows);}});}
+gatherCellNames(rows);const positions=[];cellNames.forEach(function(cellName){const cellPath=[config.cellKey,cellName];const matchingRule=MemoryColumn.findMatchingRule(cellName,config.rules);const constructor=matchingRule.columnConstructor;const column=new constructor(cellName,cellPath,config.aggregationMode);column.shouldSetContextGroup=!!config.shouldSetContextGroup;positions.push({importance:matchingRule.importance,column});});positions.sort(function(a,b){if(a.importance===b.importance){return COLLATOR.compare(a.column.name,b.column.name);}
+return b.importance-a.importance;});return positions.map(function(position){return position.column;});};MemoryColumn.spaceEqually=function(columns){const columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(let i=0;i<rules.length;i++){const rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition)){return rule;}}
+return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)return true;if(typeof(condition)==='string')return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell(row){let cell=row;const cellPath=this.cellPath;for(let i=0;i<cellPath.length;i++){if(cell===undefined)return undefined;cell=cell[cellPath[i]];}
+return cell;},aggregateCells(row,subRows){},fields(row){const cell=this.cell(row);if(cell===undefined)return undefined;return cell.fields;},value(row){const fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))return'';const contexts=row.contexts;const color=this.color(fields,contexts);const infos=[];this.addInfos(fields,contexts,infos);const formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0){return formattedFields;}
+const fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.style.justifyContent='flex-end';Polymer.dom(fieldEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){const infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';Polymer.dom(infoEl).textContent=info.icon;if(info.color!==undefined){infoEl.style.color=info.color;}
+infoEl.title=info.message;Polymer.dom(fieldEl).appendChild(infoEl);},this);if(color!==undefined){fieldEl.style.color=color;}
+return fieldEl;},hasAllRelevantFieldsUndefined(fields){if(fields===undefined)return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color(fields,contexts){return undefined;},formatFields(fields){if(fields.length===1){return this.formatSingleField(fields[0]);}
+return this.formatMultipleFields(fields);},formatSingleField(field){throw new Error('Not implemented');},formatMultipleFields(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax(fields){return this.formatSingleField(this.getMaxField(fields));},cmp(rowA,rowB){const fieldsA=this.fields(rowA);const fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length){throw new Error('Different number of fields');}
+const undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);const undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)return 0;if(undefinedA)return-1;if(undefinedB)return 1;return this.compareFields(fieldsA,fieldsB);},compareFields(fieldsA,fieldsB){if(fieldsA.length===1){return this.compareSingleFields(fieldsA[0],fieldsB[0]);}
+return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField(fields){return fields.reduce(function(accumulator,field){if(field===undefined){return accumulator;}
+if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
+return accumulator;}.bind(this),undefined);},addInfos(fields,contexts,infos){},getImportance(importanceRules){if(importanceRules.length===0)return 0;const matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined){return matchingRule.importance;}
+let minImportance=importanceRules[0].importance;for(let i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
+return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField(string){return string;},formatMultipleFieldsDiff(firstString,lastString){if(firstString===undefined){const spanEl=tr.ui.b.createSpan({color:'red'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('+'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){const spanEl=tr.ui.b.createSpan({color:'green'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('-'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}
+const spanEl=tr.ui.b.createSpan({color:'DarkOrange'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;},compareSingleFields(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined){return 1;}
+if(firstStringA!==undefined&&firstStringB===undefined){return-1;}
+if(firstStringA===undefined&&firstStringB===undefined){return this.compareSingleFields(lastStringA,lastStringB);}
+if(lastStringA===undefined&&lastStringB!==undefined){return-1;}
+if(lastStringA!==undefined&&lastStringB===undefined){return 1;}
+if(lastStringA===undefined&&lastStringB===undefined){return this.compareSingleFields(firstStringB,firstStringA);}
+const areStringsAEqual=firstStringA===lastStringA;const areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)return 0;if(areStringsAEqual)return-1;if(areStringsBEqual)return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,aggregateCells(row,subRows){const subRowCells=subRows.map(this.cell,this);let hasDefinedSubRowNumeric=false;let timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)return;const subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)return;if(timestampCount===undefined){timestampCount=subRowNumerics.length;}else if(timestampCount!==subRowNumerics.length){throw new Error('Sub-rows have different numbers of timestamps');}
+if(hasDefinedSubRowNumeric){return;}
+hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric){return;}
+const cellPath=this.cellPath;let rowCell=row;for(let i=0;i<cellPath.length;i++){const nextStepName=cellPath[i];let nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1){nextStep={};}else{nextStep=new MemoryCell(undefined);}
+rowCell[nextStepName]=nextStep;}
+rowCell=nextStep;}
+if(rowCell.fields===undefined){rowCell.fields=new Array(timestampCount);}else if(rowCell.fields.length!==timestampCount){throw new Error('Row has a different number of timestamps than sub-rows');}
+for(let i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined){return undefined;}
+return subRowCell.fields[i];}));}},formatSingleField(numeric){return tr.v.ui.createScalarSpan(numeric,{context:this.getFormattingContext(numeric.unit),contextGroup:this.shouldSetContextGroup?this.name:undefined,inline:true,});},getFormattingContext(unit){return undefined;},formatMultipleFieldsDiff(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
+this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_(firstNumeric,lastNumeric){const definedNumeric=firstNumeric||lastNumeric;return new tr.b.Scalar(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_(firstNumeric,lastNumeric){const firstValue=firstNumeric===undefined?0:firstNumeric.value;const lastValue=lastNumeric===undefined?0:lastNumeric.value;const diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
+MemoryCell.extractFields=function(cell){if(cell===undefined)return undefined;return cell.fields;};const RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){let currentLevelRows=table.tableRows;let totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){let nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
+const nextLevelRows=new Array(nextLevelRowCount);let nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
+function aggregateTableRowCellsRecursively(row,columns,opt_predicate){const subRows=row.subRows;if(subRows===undefined||subRows.length===0)return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts)){aggregateTableRowCells(row,subRows,columns);}}
+function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))return;column.aggregateCells(row,subRows);});}
+function createCells(timeToValues,valueFieldsGetter,opt_this){opt_this=opt_this||this;const fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter,opt_this);const result={};for(const[fieldName,fields]of Object.entries(fieldNameToFields)){result[fieldName]=new tr.ui.analysis.MemoryCell(fields);}
+return result;}
+function createWarningInfo(message){return{message,icon:String.fromCharCode(9888),color:'red'};}
+function DetailsNumericMemoryColumn(name,cellPath,aggregationMode){NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+DetailsNumericMemoryColumn.prototype={__proto__:NumericMemoryColumn.prototype,getFormattingContext(unit){if(unit.baseUnit===tr.b.Unit.byName.sizeInBytes){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.KIBI};}
+return undefined;}};return{TitleColumn,MemoryColumn,StringMemoryColumn,NumericMemoryColumn,MemoryCell,expandTableRowsRecursively,aggregateTableRowCellsRecursively,aggregateTableRowCells,createCells,createWarningInfo,DetailsNumericMemoryColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);const CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);const HeapDetailsRowDimension={ROOT:{},STACK_FRAME:{label:'Stack frame',symbol:LATIN_SMALL_LETTER_F_WITH_HOOK,color:'heap_dump_stack_frame'},OBJECT_TYPE:{label:'Object type',symbol:CIRCLED_LATIN_CAPITAL_LETTER_T,color:'heap_dump_object_type'}};function HeapDetailsTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+HeapDetailsTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.dimension===HeapDetailsRowDimension.ROOT){return row.title;}
+const symbolEl=document.createElement('span');Polymer.dom(symbolEl).textContent=row.dimension.symbol;symbolEl.title=row.dimension.label;symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(row.dimension.color);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.fontWeight='bold';const titleEl=document.createElement('span');Polymer.dom(titleEl).appendChild(symbolEl);Polymer.dom(titleEl).appendChild(document.createTextNode(row.title));return titleEl;}};function AllocationCountColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocationCountColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,getFormattingContext(unit){return{minimumFractionDigits:0};}};const HEAP_DETAILS_COLUMN_RULES=[{condition:'Size',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Count',importance:1,columnConstructor:AllocationCountColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];return{HeapDetailsRowDimension,HeapDetailsTitleColumn,AllocationCountColumn,HEAP_DETAILS_COLUMN_RULES,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const RebuildableBehavior={rebuild(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.onRebuild_();},scheduleRebuild_(){if(this.paneDirty_)return;this.paneDirty_=true;tr.b.requestAnimationFrame(this.rebuild.bind(this));},onRebuild_(){}};return{RebuildableBehavior,};});'use strict';Polymer({is:'tr-ui-b-tab-view',properties:{label_:{type:String,value:()=>''},selectedSubView_:Object,subViews_:{type:Array,value:()=>[]},tabsHidden:{type:Boolean,value:false,observer:'tabsHiddenChanged_'}},ready(){this.$.tabs.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.updateFocusability_();},set label(newLabel){this.set('label_',newLabel);},get tabs(){return this.get('subViews_');},get selectedSubView(){return this.selectedSubView_;},set selectedSubView(subView){if(subView===this.selectedSubView_)return;if(this.selectedSubView_){Polymer.dom(this.$.subView).removeChild(this.selectedSubView_);const oldInput=this.root.getElementById(this.computeRadioId_(this.selectedSubView_));if(oldInput){oldInput.checked=false;}}
+this.set('selectedSubView_',subView);if(subView){Polymer.dom(this.$.subView).appendChild(subView);const newInput=this.root.getElementById(this.computeRadioId_(subView));if(newInput){newInput.checked=true;}}
+this.fire('selected-tab-change');},clearSubViews(){this.splice('subViews_',0,this.subViews_.length);this.selectedSubView=undefined;this.updateFocusability_();},addSubView(subView){this.push('subViews_',subView);if(!this.selectedSubView_)this.selectedSubView=subView;this.updateFocusability_();},get subViews(){return this.subViews_;},resetSubViews(subViews){this.splice('subViews_',0,this.subViews_.length);if(subViews.length){for(const subView of subViews){this.push('subViews_',subView);}
+this.selectedSubView=subViews[0];}else{this.selectedSubView=undefined;}
+this.updateFocusability_();},onTabChanged_(event){this.selectedSubView=event.model.item;},isChecked_(subView){return this.selectedSubView_===subView;},tabsHiddenChanged_(){this.updateFocusability_();},onKeyDown_(e){if(this.tabsHidden)return;let keyHandled=false;switch(e.keyCode){case 37:keyHandled=this.selectPreviousTabIfPossible();break;case 39:keyHandled=this.selectNextTabIfPossible();break;}
+if(!keyHandled)return;e.stopPropagation();e.preventDefault();},selectNextTabIfPossible(){return this.selectTabByOffsetIfPossible_(1);},selectPreviousTabIfPossible(){return this.selectTabByOffsetIfPossible_(-1);},selectTabByOffsetIfPossible_(offset){if(!this.selectedSubView_)return false;const currentIndex=this.subViews_.indexOf(this.selectedSubView_);const newSubView=this.tabs[currentIndex+offset];if(!newSubView)return false;this.selectedSubView=newSubView;return true;},shouldBeFocusable_(){return!this.tabsHidden&&this.subViews_.length>0;},updateFocusability_(){if(this.shouldBeFocusable_()){Polymer.dom(this.$.tabs).setAttribute('tabindex',0);}else{Polymer.dom(this.$.tabs).removeAttribute('tabindex');}},computeRadioId_(subView){return subView.tagName+'-'+subView.tabLabel.replace(/ /g,'-');}});'use strict';tr.exportTo('tr.ui.analysis',function(){const RESONABLE_NUMBER_OF_ROWS=200;const TabUiState={NO_LONG_TAIL:0,HIDING_LONG_TAIL:1,SHOWING_LONG_TAIL:2,};function EmptyFillerColumn(){}
+EmptyFillerColumn.prototype={title:'',value(){return'';},};Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.displayedNode_=undefined;this.dimensionToTab_=new Map();},ready(){this.scheduleRebuild_();this.root.addEventListener('keydown',this.onKeyDown_.bind(this),true);},get displayedNode(){return this.displayedNode_;},set displayedNode(node){this.displayedNode_=node;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;for(const tab of this.$.tabs.tabs){tab.aggregationMode=aggregationMode;}},onRebuild_(){const previouslySelectedTab=this.$.tabs.selectedSubView;let previouslySelectedTabFocused=false;let previouslySelectedDimension=undefined;if(previouslySelectedTab){previouslySelectedTabFocused=previouslySelectedTab.isFocused;previouslySelectedDimension=previouslySelectedTab.dimension;}
+for(const tab of this.$.tabs.tabs){tab.nodes=undefined;}
+this.$.tabs.clearSubViews();if(this.displayedNode_===undefined){this.$.tabs.label='No heap node provided.';return;}
+for(const[dimension,children]of this.displayedNode_.childNodes){if(!this.dimensionToTab_.has(dimension)){this.dimensionToTab_.set(dimension,document.createElement('tr-ui-a-memory-dump-heap-details-breakdown-view-tab'));}
+const tab=this.dimensionToTab_.get(dimension);tab.aggregationMode=this.aggregationMode_;tab.dimension=dimension;tab.nodes=children;this.$.tabs.addSubView(tab);tab.rebuild();if(dimension===previouslySelectedDimension){this.$.tabs.selectedSubView=tab;if(previouslySelectedTabFocused){tab.focus();}}}
+if(this.$.tabs.tabs.length>0){this.$.tabs.label='Break selected node further by:';}else{this.$.tabs.label='Selected node cannot be broken down any further.';}},onKeyDown_(keyEvent){if(!this.displayedNode_)return;let keyHandled=false;switch(keyEvent.keyCode){case 8:{if(!this.displayedNode_.parentNode)break;const viewEvent=new tr.b.Event('enter-node');viewEvent.node=this.displayedNode_.parentNode;this.dispatchEvent(viewEvent);keyHandled=true;break;}
+case 37:case 39:{const wasFocused=this.$.tabs.selectedSubView.isFocused;keyHandled=keyEvent.keyCode===37?this.$.tabs.selectPreviousTabIfPossible():this.$.tabs.selectNextTabIfPossible();if(wasFocused&&keyHandled){this.$.tabs.selectedSubView.focus();}}}
+if(!keyHandled)return;keyEvent.stopPropagation();keyEvent.preventDefault();}});Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view-tab',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.dimension_=undefined;this.nodes_=undefined;this.aggregationMode_=undefined;this.displayLongTail_=false;},ready(){this.$.table.addEventListener('step-into',function(tableEvent){const viewEvent=new tr.b.Event('enter-node');viewEvent.node=tableEvent.tableRow;this.dispatchEvent(viewEvent);}.bind(this));},get displayLongTail(){return this.displayLongTail_;},set displayLongTail(newValue){if(this.displayLongTail===newValue)return;this.displayLongTail_=newValue;this.scheduleRebuild_();},get dimension(){return this.dimension_;},set dimension(dimension){this.dimension_=dimension;this.scheduleRebuild_();},get nodes(){return this.nodes_;},set nodes(nodes){this.nodes_=nodes;this.scheduleRebuild_();},get nodes(){return this.nodes_||[];},get dimensionLabel_(){if(this.dimension_===undefined)return'(undefined)';return this.dimension_.label;},get tabLabel(){let nodeCount=0;if(this.nodes_){nodeCount=this.nodes_.length;}
+return this.dimensionLabel_+' ('+nodeCount+')';},get tabIcon(){if(this.dimension_===undefined||this.dimension_===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return undefined;}
+return{text:this.dimension_.symbol,style:'color: '+tr.b.ColorScheme.getColorForReservedNameAsString(this.dimension_.color)+';'};},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},focus(){this.$.table.focus();},blur(){this.$.table.blur();},get isFocused(){return this.$.table.isFocused;},onRebuild_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.emptyValue='Cannot break down by '+
+this.dimensionLabel_.toLowerCase()+' any further.';const[state,rows]=this.getRows_();const total=this.nodes.length;const displayed=rows.length;const hidden=total-displayed;this.updateInfoBar_(state,[total,displayed,hidden]);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);if(this.$.table.sortColumnIndex===undefined){this.$.table.sortColumnIndex=0;this.$.table.sortDescending=false;}
+this.$.table.rebuild();},createColumns_(rows){const titleColumn=new tr.ui.analysis.HeapDetailsTitleColumn(this.dimensionLabel_);titleColumn.width='400px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});if(numericColumns.length===0){numericColumns.push(new EmptyFillerColumn());}
+tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);const columns=[titleColumn].concat(numericColumns);return columns;},getRows_(){let rows=this.nodes;if(rows.length<=RESONABLE_NUMBER_OF_ROWS){return[TabUiState.NO_LONG_TAIL,rows];}else if(this.displayLongTail){return[TabUiState.SHOWING_LONG_TAIL,rows];}
+const absSize=row=>Math.max(row.cells.Size.fields[0].value);rows.sort((a,b)=>absSize(b)-absSize(a));rows=rows.slice(0,RESONABLE_NUMBER_OF_ROWS);return[TabUiState.HIDING_LONG_TAIL,rows];},updateInfoBar_(state,rowStats){if(state===TabUiState.SHOWING_LONG_TAIL){this.longTailVisibleInfoBar_(rowStats);}else if(state===TabUiState.HIDING_LONG_TAIL){this.longTailHiddenInfoBar_(rowStats);}else{this.hideInfoBar_();}},longTailVisibleInfoBar_(rowStats){const[total,visible,hidden]=rowStats;const couldHide=total-RESONABLE_NUMBER_OF_ROWS;this.$.info.message='Showing '+total+' rows. This may be slow.';this.$.info.removeAllButtons();const buttonText='Hide '+couldHide+' rows.';this.$.info.addButton(buttonText,()=>this.displayLongTail=false);this.$.info.visible=true;},longTailHiddenInfoBar_(rowStats){const[total,visible,hidden]=rowStats;this.$.info.message='Hiding the smallest '+hidden+' rows.';this.$.info.removeAllButtons();this.$.info.addButton('Show all.',()=>this.displayLongTail=true);this.$.info.visible=true;},hideInfoBar_(){this.$.info.visible=false;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS=String.fromCharCode(0x21B3);function HeapDetailsPathColumn(title){tr.ui.analysis.HeapDetailsTitleColumn.call(this,title);}
+HeapDetailsPathColumn.prototype={__proto__:tr.ui.analysis.HeapDetailsTitleColumn.prototype,formatTitle(row){const title=tr.ui.analysis.HeapDetailsTitleColumn.prototype.formatTitle.call(this,row);if(row.dimension===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return title;}
+const arrowEl=document.createElement('span');Polymer.dom(arrowEl).textContent=DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS;arrowEl.style.paddingRight='2px';arrowEl.style.fontWeight='bold';arrowEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString('heap_dump_child_node_arrow');const rowEl=document.createElement('span');Polymer.dom(rowEl).appendChild(arrowEl);Polymer.dom(rowEl).appendChild(tr.ui.b.asHTMLOrTextNode(title));return rowEl;}};Polymer({is:'tr-ui-a-memory-dump-heap-details-path-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.selectedNode_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.addEventListener('selection-changed',function(event){this.selectedNode_=this.$.table.selectedTableRow;this.didSelectedNodeChange_();}.bind(this));},didSelectedNodeChange_(){this.dispatchEvent(new tr.b.Event('selected-node-changed'));},get selectedNode(){return this.selectedNode_;},set selectedNode(node){this.selectedNode_=node;this.didSelectedNodeChange_();this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},onRebuild_(){if(this.selectedNode_===undefined){this.$.table.clear();return;}
+if(this.$.table.tableRows.includes(this.selectedNode_)){this.$.table.selectedTableRow=this.selectedNode_;return;}
+this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.userCanModifySortOrder=false;const rows=this.createRows_(this.selectedNode_);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);this.$.table.selectedTableRow=rows[rows.length-1];},createRows_(node){const rows=[];while(node){rows.push(node);node=node.parentNode;}
+rows.reverse();return rows;},createColumns_(rows){const titleColumn=new HeapDetailsPathColumn('Current path');titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);return[titleColumn].concat(numericColumns);}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const StackedPaneImpl={set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended(){this.rebuild();}};const StackedPane=[tr.ui.analysis.RebuildableBehavior,StackedPaneImpl];return{StackedPane,};});Polymer({is:'tr-ui-a-stacked-pane',behaviors:[tr.ui.analysis.StackedPane]});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;const TotalState=tr.b.MultiDimensionalViewNode.TotalState;function HeapDumpTreeNode(stackFrameNodes,dimension,title,heavyView,parentNode){this.dimension=dimension;this.title=title;this.parentNode=parentNode;this.heavyView_=heavyView;this.stackFrameNodes_=stackFrameNodes;this.lazyCells_=undefined;this.lazyChildNodes_=undefined;}
+HeapDumpTreeNode.prototype={get minDisplayedTotalState_(){if(this.heavyView_){return TotalState.LOWER_BOUND;}
+return TotalState.EXACT;},get childNodes(){if(!this.lazyChildNodes_){this.lazyChildNodes_=new Map();this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.STACK_FRAME,0);this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.OBJECT_TYPE,1);this.releaseStackFrameNodesIfPossible_();}
+return this.lazyChildNodes_;},get cells(){if(!this.lazyCells_){this.addCells_();this.releaseStackFrameNodesIfPossible_();}
+return this.lazyCells_;},releaseStackFrameNodesIfPossible_(){if(this.lazyCells_&&this.lazyChildNodes_){this.stackFrameNodes_=undefined;}},addDimensionChildNodes_(dimension,dimensionIndex){const dimensionChildTitleToStackFrameNodes=tr.b.invertArrayOfDicts(this.stackFrameNodes_,node=>this.convertStackFrameNodeDimensionToChildDict_(node,dimensionIndex));const dimensionChildNodes=[];for(const[childTitle,childStackFrameNodes]of
+Object.entries(dimensionChildTitleToStackFrameNodes)){dimensionChildNodes.push(new HeapDumpTreeNode(childStackFrameNodes,dimension,childTitle,this.heavyView_,this));}
+this.lazyChildNodes_.set(dimension,dimensionChildNodes);},convertStackFrameNodeDimensionToChildDict_(stackFrameNode,dimensionIndex){const childDict={};let displayedChildrenTotalSize=0;let displayedChildrenTotalCount=0;let hasDisplayedChildren=false;let allDisplayedChildrenHaveDisplayedCounts=true;for(const child of stackFrameNode.children[dimensionIndex].values()){if(child.values[0].totalState<this.minDisplayedTotalState_){continue;}
+if(child.values[1].totalState<this.minDisplayedTotalState_){allDisplayedChildrenHaveDisplayedCounts=false;}
+childDict[child.title[dimensionIndex]]=child;displayedChildrenTotalSize+=child.values[0].total;displayedChildrenTotalCount+=child.values[1].total;hasDisplayedChildren=true;}
+const nodeTotalSize=stackFrameNode.values[0].total;const nodeTotalCount=stackFrameNode.values[1].total;const hasUnclassifiedSizeOrCount=displayedChildrenTotalSize<nodeTotalSize||displayedChildrenTotalCount<nodeTotalCount;if(!this.heavyView_&&hasUnclassifiedSizeOrCount&&hasDisplayedChildren){const otherTitle=stackFrameNode.title.slice();otherTitle[dimensionIndex]='<other>';const otherNode=new tr.b.MultiDimensionalViewNode(otherTitle,2);childDict[otherTitle[dimensionIndex]]=otherNode;otherNode.values[0].total=nodeTotalSize-displayedChildrenTotalSize;otherNode.values[0].totalState=this.minDisplayedTotalState_;otherNode.values[1].total=nodeTotalCount-displayedChildrenTotalCount;otherNode.values[1].totalState=allDisplayedChildrenHaveDisplayedCounts?this.minDisplayedTotalState_:TotalState.NOT_PROVIDED;}
+return childDict;},addCells_(){this.lazyCells_=tr.ui.analysis.createCells(this.stackFrameNodes_,function(stackFrameNode){const size=stackFrameNode.values[0].total;const numerics={'Size':new Scalar(sizeInBytes_smallerIsBetter,size)};const countValue=stackFrameNode.values[1];if(countValue.totalState>=this.minDisplayedTotalState_){const count=countValue.total;numerics.Count=new Scalar(count_smallerIsBetter,count);}
+return numerics;},this);}};Polymer({is:'tr-ui-a-memory-dump-heap-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.heapDumps_=undefined;this.viewMode_=undefined;this.aggregationMode_=undefined;this.cachedBuilders_=new Map();},ready(){this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';Polymer.dom(this.$.view_mode_container).appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]));this.$.drag_handle.target=this.$.path_view;this.$.drag_handle.horizontal=false;this.$.path_view.addEventListener('selected-node-changed',(function(e){this.$.breakdown_view.displayedNode=this.$.path_view.selectedNode;}).bind(this));this.$.breakdown_view.addEventListener('enter-node',(function(e){this.$.path_view.selectedNode=e.node;}).bind(this));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.$.path_view.aggregationMode=aggregationMode;this.$.breakdown_view.aggregationMode=aggregationMode;},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuild_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},onRebuild_(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.split_view.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.hidden=true;this.$.path_view.selectedNode=undefined;return;}
+this.$.info_text.style.display='none';this.$.split_view.style.display='flex';this.$.view_mode_container.style.display='block';this.$.info_bar.hidden=!this.heavyView;this.$.path_view.selectedNode=this.createHeapTree_();this.$.path_view.rebuild();this.$.breakdown_view.rebuild();},createHeapTree_(){const definedHeapDump=this.heapDumps_.find(x=>x);if(definedHeapDump===undefined)return undefined;const rootRowTitle=definedHeapDump.allocatorName;const stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);return new HeapDumpTreeNode(stackFrameTrees,tr.ui.analysis.HeapDetailsRowDimension.ROOT,rootRowTitle,this.heavyView);},createStackFrameTrees_(heapDumps){const builders=heapDumps.map(heapDump=>this.createBuilder_(heapDump));const views=builders.map(builder=>{if(builder===undefined)return undefined;return builder.buildView(this.viewMode);});return views;},createBuilder_(heapDump){if(heapDump===undefined)return undefined;if(this.cachedBuilders_.has(heapDump)){return this.cachedBuilders_.get(heapDump);}
+const dimensions=2;const valueCount=2;const builder=new MultiDimensionalViewBuilder(dimensions,valueCount);for(const entry of heapDump.entries){const leafStackFrame=entry.leafStackFrame;const stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();const objectTypeName=entry.objectTypeName;const objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];const valueKind=entry.valuesAreTotals?MultiDimensionalViewBuilder.ValueKind.TOTAL:MultiDimensionalViewBuilder.ValueKind.SELF;builder.addPath([stackTracePath,objectTypeNamePath],[entry.size,entry.count],valueKind);}
+builder.complete=heapDump.isComplete;this.cachedBuilders_.set(heapDump,builder);return builder;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const URL_TO_SIZE_VS_EFFECTIVE_SIZE='https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/README.md#effective_size-vs_size';const SUBALLOCATION_CONTEXT=true;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;const LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);const RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);const EN_DASH=String.fromCharCode(0x2013);const CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(!row.suballocation){return row.title;}
+return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){let entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
+entry.count++;return entry;}
+function SizeInfoMessageBuilder(){this.parts_=[];this.indent_=0;}
+SizeInfoMessageBuilder.prototype={append(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText){this.append(emptyText);}}else if(map.size===1){this.parts_.push(' ');const key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix){this.parts_.push('s');}
+this.parts_.push(':');this.indent_++;for(const key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
+this.indent_--;}},appendImportanceRange(range){this.append(' (importance: ');if(range.min===range.max){this.append(range.min);}else{this.append(range.min,EN_DASH,range.max);}
+this.append(')');},appendSizeIfDefined(size){if(size!==undefined){this.append(' (',tr.b.Unit.byName.sizeInBytes.format(size),')');}},appendSomeTimestampsQuantifier(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory used by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;const ownerNameToEntry=new Map();const ownedNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+dump.ownedBy.forEach(function(ownerLink){const ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);const ownedLink=dump.owns;if(ownedLink!==undefined){const ownedDump=ownedLink.target;const ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);const sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){const sharerDump=sharerLink.source;if(sharerDump===dump)return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
+if(ownerNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
+if(ownedNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);const ownedCount=ownedEntry.count;if(ownedCount<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_(map,dump,link,opt_withSharerNameToEntry){const entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.math.Range();if(opt_withSharerNameToEntry){newEntry.sharerNameToEntry=new Map();}});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+SizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory requested by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_(numerics,memoryAllocatorDumps,infos){const siblingNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+const ownedBySiblingSizes=dump.ownedBySiblingSizes;for(const siblingDump of ownedBySiblingSizes.keys()){const siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1){newEntry.size=ownedBySiblingSizes.get(siblingDump);}});}}
+if(siblingNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos){const infoTypeToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
+for(const infoType of infoTypeToEntry.keys()){const entry=infoTypeToEntry.get(infoType);const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);let dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
+messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};const NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer({is:'tr-ui-a-memory-dump-allocator-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuild_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){const pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_(dumps){const definedDump=dumps.find(x=>x);const title=definedDump.name;const fullName=definedDump.fullName;const numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});const diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});let suballocatedBy=undefined;if(title.startsWith('__')){for(let i=0;i<dumps.length;i++){const dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+const ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
+const row={title,fullNames:[fullName],contexts:dumps,numericCells,diagnosticCells,suballocatedBy};const childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){const results={};for(const child of dump.children){results[child.name]=child;}
+return results;});const subRows=[];let suballocationClassificationRootNode=undefined;for(const childDumps of Object.values(childDumpNameToDumps)){const childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}}
+if(suballocationClassificationRootNode!==undefined){const suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
+if(subRows.length>0){row.subRows=subRows;}
+return row;},classifySuballocationRow_(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+const suballocationLevels=suballocationRow.suballocatedBy.split('/');let currentNode=rootNode;for(let i=0;i<suballocationLevels.length;i++){const suballocationLevel=suballocationLevels[i];let nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+currentNode=nextNode;}
+const existingRow=currentNode.row;if(existingRow!==undefined){for(let i=0;i<suballocationRow.contexts.length;i++){const newContext=suballocationRow.contexts[i];if(newContext===undefined)continue;if(existingRow.contexts[i]!==undefined){throw new Error('Multiple suballocations with the same owner name');}
+existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){const suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)return;for(const[cellName,cell]of Object.entries(suballocationCells)){if(cell===undefined)continue;const fields=cell.fields;if(fields===undefined)continue;const field=fields[i];if(field===undefined)continue;let existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
+let existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
+existingCell.fields[i]=field;}});}
+existingRow.fullNames.push.apply(existingRow.fullNames,suballocationRow.fullNames);}else{currentNode.row=suballocationRow;}
+return rootNode;},createSuballocationRowRecursively_(name,node){const childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined){throw new Error('Suballocation node must have a row or children');}
+const row=node.row;row.title=name;row.suballocation=true;return row;}
+const subRows=[];for(const[subName,subNode]of Object.entries(node.children)){subRows.push(this.createSuballocationRowRecursively_(subName,subNode));}
+if(node.row!==undefined){const row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+const contexts=new Array(subRows[0].contexts.length);for(let i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined){contexts[index]=SUBALLOCATION_CONTEXT;}});}
+return{title:name,suballocation:true,contexts,subRows};},createColumns_(rows){const titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'numericCells',aggregationMode:this.aggregationMode_,rules:NUMERIC_COLUMN_RULES});const diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'diagnosticCells',aggregationMode:this.aggregationMode_,rules:DIAGNOSTIC_COLUMN_RULES});const fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn,EffectiveSizeColumn,SizeColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];const VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)return undefined;const hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)return;if(row.subRows[0].rule===undefined){return;}
+row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
+Polymer({is:'tr-ui-a-memory-dump-vm-regions-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuild_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_(this.vmRegions_);const columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_(timeToVmRegionTree){const is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow(timeToNode,is64BitAddress){const definedNode=timeToNode.find(x=>x);const childNodeIdToTimeToNode=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const children=node.children;if(children===undefined)return undefined;const childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)return;childMap[childNode.title]=childNode;});return childMap;}));const childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);const regionIdToTimeToRegion=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const regions=node.regions;if(regions===undefined)return undefined;const results={};for(const region of regions){results[region.uniqueIdWithinProcess]=region;}
+return results;}));const regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);const subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows};},createRegionRow_(timeToRegion,is64BitAddress){const definedRegion=timeToRegion.find(x=>x);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){const startAddress=region.startAddress;if(startAddress===undefined)return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){const fields={};const sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new Scalar(sizeInBytes_smallerIsBetter,sizeInBytes);}
+const protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined){fields['Protection flags']=protectionFlags;}
+for(const[byteStatName,columnName]of
+Object.entries(BYTE_STAT_COLUMN_MAP)){const byteStat=region.byteStats[byteStatName];if(byteStat===undefined)continue;fields[columnName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}
+return fields;});},createColumns_(rows){const titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';const constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'constantCells',aggregationMode:undefined,rules:CONSTANT_COLUMN_RULES});const variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'variableCells',aggregationMode:this.aggregationMode_,rules:VARIABLE_COLUMN_RULES});const fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer({is:'tr-ui-b-color-legend',ready(){const blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+const colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId(label,colorId){this.label_=label;Polymer.dom(this.$.label).textContent='';Polymer.dom(this.$.label).appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined){this.$.square.style.color='initial';}else{this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}}});'use strict';Polymer({is:'tr-ui-b-view-specific-brushing-state',get viewId(){return this.getAttribute('view-id');},set viewId(viewId){Polymer.dom(this).setAttribute('view-id',viewId);},get(){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set(state){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){const MemoryColumnColorScheme=tr.b.MemoryColumnColorScheme;const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;const RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);const RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);const GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);const UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);const TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;let result=undefined;list.forEach(function(item,index){const value=fn.call(opt_this,item,index);if(value===undefined)return;if(result===undefined){result=new Array(list.length);}
+result[index]=value;});return result;}
+function ProcessNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Process');}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.contexts===undefined){return row.title;}
+const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+UsedMemoryColumn.COLOR=MemoryColumnColorScheme.getColor('used_memory_column').toString();UsedMemoryColumn.OLDER_COLOR=MemoryColumnColorScheme.getColor('older_used_memory_column').toString();UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},color(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)return undefined;return function(){const pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let resettableValueCount=0;let nonResettableValueCount=0;for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;if(processMemoryDumps[i].arePeakResidentBytesResettable){resettableValueCount++;}else{nonResettableValueCount++;}}
+if(resettableValueCount>0&&nonResettableValueCount>0){infos.push(tr.ui.analysis.createWarningInfo('Both resettable and '+'non-resettable peak RSS values were provided by the process'));}else if(resettableValueCount>0){infos.push({icon:RIGHTWARDS_ARROW_WITH_HOOK,message:'Peak RSS since previous memory dump.'});}else{infos.push({icon:RIGHTWARDS_ARROW_FROM_BAR,message:'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
+GREATER_THAN_OR_EQUAL_TO+' 4.0.'});}}};function ByteStatColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color(numerics,processMemoryDumps){if(processMemoryDumps===undefined){return UsedMemoryColumn.COLOR;}
+const allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues){return UsedMemoryColumn.OLDER_COLOR;}
+return UsedMemoryColumn.COLOR;},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let olderValueCount=0;for(let i=0;i<numerics.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
+if(olderValueCount===0){return;}
+const infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP={'vm':'Total virtual','swp':'Swapped','pc':'Private clean','pd':'Private dirty','sc':'Shared clean','sd':'Shared dirty','gpu_egl':'GPU EGL','gpu_egl_pss':'GPU EGL PSS','gpu_gl':'GPU GL','gpu_gl_pss':'GPU GL PSS','gpu_etc':'GPU Other','gpu_etc_pss':'GPU Other PSS',};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let heapDumpCount=0;let missingSizeCount=0;for(let i=0;i<processMemoryDumps.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)continue;const heapDumps=processMemoryDump.heapDumps;if(heapDumps!==undefined&&heapDumps[this.name]!==undefined){heapDumpCount++;}
+const allocatorDump=processMemoryDump.getMemoryAllocatorDumpByFullName(this.name);if(allocatorDump!==undefined&&allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]===undefined){missingSizeCount++;}}
+if(heapDumpCount>0){const infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});}
+if(missingSizeCount>0){const infoQuantifier=missingSizeCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push(tr.ui.analysis.createWarningInfo('Size was not provided'+infoQuantifier+'.'));}},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)return undefined;const heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)return undefined;return pmd.heapDumps[this.name];},this);return function(){const pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
+TracingColumn.COLOR=MemoryColumnColorScheme.getColor('tracing_memory_column').toString();TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer({is:'tr-ui-a-memory-dump-overview-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuild_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];const selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},onRebuild_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);const footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_(){const timeToPidToProcessMemoryDump=this.processMemoryDumps_;const pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);const rows=[];for(const[pid,timeToDump]of
+Object.entries(pidToTimeToProcessMemoryDump)){const process=timeToDump.find(x=>x).process;const usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){const sizes={};const totals=dump.totals;if(totals!==undefined){for(const[totalName,cellName]of
+Object.entries(UsedMemoryColumn.TOTALS_MAP)){const total=totals[totalName];if(total===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,total);}
+const platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){for(const[name,size]of Object.entries(platformSpecific)){let newName=name;if(UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP[name]===undefined){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){newName=name.substring(0,name.length-
+PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX.length);}
+newName=newName.replace('_',' ').trim();newName=newName.charAt(0).toUpperCase()+newName.slice(1);}else{newName=UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP[name];}
+sizes[newName]=new Scalar(sizeInBytes_smallerIsBetter,size);}}}
+const vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){for(const[byteStatName,cellName]of
+Object.entries(UsedMemoryColumn.BYTE_STAT_MAP)){const byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}}
+return sizes;});const allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){const memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)return undefined;const sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){let rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric===undefined){rootDisplayedSizeNumeric=new Scalar(sizeInBytes_smallerIsBetter,0);}
+sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});rows.push({title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells,allocatorCells});}
+return rows;},createFooterRows_(rows,columns){if(rows.length<=1)return[];const totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_(rows){const titleColumn=new ProcessNameColumn();titleColumn.width='200px';const usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'usedMemoryCells',aggregationMode:this.aggregationMode_,rules:UsedMemoryColumn.RULES});const allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'allocatorCells',aggregationMode:this.aggregationMode_,rules:AllocatorColumn.RULES});const sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);const columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_(){let selectedRowTitle;const selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined){selectedRowTitle=selectedRow.title;}
+let selectedColumnName;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_(){const settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined){return;}
+const selectedColumnIndex=this.$.table.tableColumns.findIndex(col=>col.name===settings.columnName);if(selectedColumnIndex===-1)return;const selectedRowTitle=settings.rowTitle;const selectedRow=this.$.table.tableRows.find(row=>row.title===selectedRowTitle);if(selectedRow===undefined)return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn,UsedMemoryColumn,PeakMemoryColumn,ByteStatColumn,AllocatorColumn,TracingColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-memory-dump-header-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.containerMemoryDumps_=undefined;},ready(){Polymer.dom(this.$.aggregation_mode_container).appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuild_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_(){Polymer.dom(this.$.label).textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){Polymer.dom(this.$.label).textContent='No memory dumps selected';return;}
+const containerDumpCount=this.containerMemoryDumps_.length;const isMultiSelection=containerDumpCount>1;Polymer.dom(this.$.label).appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){const ELLIPSIS=String.fromCharCode(8230);Polymer.dom(this.$.label).appendChild(document.createTextNode(ELLIPSIS));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_(){let displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1){displayStyle='none';}else{displayStyle='initial';}
+this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){return undefined;}
+const overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer({is:'tr-ui-a-stacked-pane-view',setPaneBuilder(paneBuilder,opt_parentPane){const paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement)){throw new Error('Parent pane must be an HTML element');}
+if(opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane must be a child of the pane container');}}
+while(Polymer.dom(paneContainer).lastElementChild!==null&&Polymer.dom(paneContainer).lastElementChild!==opt_parentPane){const removedPane=Polymer.dom(this.$.pane_container).lastElementChild;const listener=this.listeners_.get(removedPane);if(listener===undefined){throw new Error('No listener associated with pane');}
+this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).removeChild(removedPane);}
+if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane was removed from the pane container');}
+if(!paneBuilder)return;const pane=paneBuilder();if(!pane)return;if(!(pane instanceof HTMLElement)){throw new Error('Pane must be an HTML element');}
+const listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).appendChild(pane);pane.appended();},rebuild(){let currentPane=Polymer.dom(this.$.pane_container).firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){const panes=[];let currentChild=Polymer.dom(this.$.pane_container).firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-container-memory-dump-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.groupIntoMap(this.currentSelection_.toArray(),dump=>dump.containerName);for(const dumps of this.dumpsByContainerName_.values()){dumps.sort((a,b)=>a.start-b.start);}
+this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_(){Polymer.dom(this.$.content).textContent='';if(this.dumpsByContainerName_===undefined)return;const containerNames=Array.from(this.dumpsByContainerName_.keys());if(containerNames.length===0)return;if(containerNames.length>1){this.buildViewForMultipleContainerNames_();}else{this.buildViewForSingleContainerName_();}},buildViewForSingleContainerName_(){const containerMemoryDumps=tr.b.getFirstElement(this.dumpsByContainerName_.values());const dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');Polymer.dom(this.$.content).appendChild(dumpView);dumpView.setPaneBuilder(function(){const headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_(){const ownerDocument=this.ownerDocument;const rows=[];for(const[containerName,dumps]of this.dumpsByContainerName_){rows.push({containerName,subRows:dumps,isExpanded:true,});}
+rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});const columns=[{title:'Dump',value(row){if(row.subRows===undefined){return this.singleDumpValue_(row);}
+return this.groupedDumpValue_(row);},singleDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));Polymer.dom(linkEl).appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument}));return linkEl;},groupedDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();Polymer.dom(this.$.content).appendChild(table);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:false,title:'Global Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:true,title:'Global Memory Dumps',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:false,title:'Process Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:true,title:'Process Memory Dumps',});return{};});'use strict';(function(){const COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value(row){return row.counter;}},{title:'Series',width:'150px',value(row){return row.series;}},{title:'Time',width:'150px',value(row){return row.start;}},{title:'Value',width:'100%',value(row){return row.value;}}];Polymer({is:'tr-ui-a-counter-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_(samples){const samplesByCounter=tr.b.groupIntoMap(samples,sample=>sample.series.counter.guid);const rows=[];for(const counterSamples of samplesByCounter.values()){const samplesBySeries=tr.b.groupIntoMap(counterSamples,sample=>sample.series.guid);for(const seriesSamples of samplesBySeries.values()){const seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+rows.push(seriesRows[0]);}}
+return rows;},getRowsForSamples_(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:false,title:'Counter Sample',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:true,title:'Counter Samples',});})();'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;}
+MultiEventSummary.prototype={set title(title){if(title==='Totals'){this.totalsRow=true;}
+this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.math.Statistics.sum(this.events_,function(event){return event.duration;});}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_(){if(this.cpuTimesComputed_)return;this.cpuTimesComputed_=true;let cpuSelfTime=0;let cpuDuration=0;let hasCpuData=false;for(const event of this.events_){if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(const event of this.events_){if(event.selfTime!==undefined){this.selfTime_+=event.selfTime;}}}
+return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.math.Statistics.sum(this.events_,event=>event.associatedAlerts.length);}
+return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.duration;});}
+return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
+return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.selfTime;});}
+return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_(){if(this.totalledArgs_!==undefined)return;const untotallableArgs={};const totalledArgs={};for(const event of this.events_){for(const argName in event.args){const argVal=event.args[argName];const type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+if(untotallableArgs[argName]){continue;}
+if(totalledArgs[argName]===undefined){totalledArgs[argName]=0;}
+totalledArgs[argName]+=argVal;}}
+this.untotallableArgs_=Object.keys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary,};});'use strict';Polymer({is:'tr-ui-a-multi-event-summary-table',ready(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_(rows,maxValues){let hasCpuData=false;let hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined){hasCpuData=true;}
+if(row.cpuSelfTime!==undefined){hasCpuData=true;}
+if(row.numAlerts){hasAlerts=true;}});const ownerDocument=this.ownerDocument;const columns=[];columns.push({title:'Name',value(row){if(row.title==='Totals')return'Totals';const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuDuration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.selfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuSelfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+if(this.eventsHaveDuration_){columns.push({title:'Average '+(hasCpuData?'CPU':'Wall')+' Duration',value(row){const totalDuration=hasCpuData?row.cpuDuration:row.duration;return tr.v.ui.createScalarSpan(totalDuration/row.numEvents,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){if(hasCpuData){return rowA.cpuDuration/rowA.numEvents-
+rowB.cpuDuration/rowB.numEvents;}
+return rowA.duration/rowA.numEvents-
+rowB.duration/rowB.numEvents;}});}
+columns.push({title:'Occurrences',value(row){return row.numEvents;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});let alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value(row){return row.numAlerts;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure(config){if(config.eventsByTitle===undefined){throw new Error('Required: eventsByTitle');}
+if(config.showTotals!==undefined){this.showTotals_=config.showTotals;}else{this.showTotals_=true;}
+if(config.eventsHaveDuration!==undefined){this.eventsHaveDuration_=config.eventsHaveDuration;}else{this.eventsHaveDuration_=true;}
+if(config.eventsHaveSubRows!==undefined){this.eventsHaveSubRows_=config.eventsHaveSubRows;}else{this.eventsHaveSubRows_=true;}
+this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_(){let eventsByTitle;if(this.eventsByTitle_!==undefined){eventsByTitle=this.eventsByTitle_;}else{eventsByTitle=[];}
+const allEvents=new tr.model.EventSet();const rows=[];for(const[title,eventsOfSingleTitle]of Object.entries(eventsByTitle)){for(const event of eventsOfSingleTitle)allEvents.push(event);const row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);}
+this.updateTableColumns_(rows);this.$.table.tableRows=rows;const maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(const column in maxValues){maxValues[column]=tr.b.math.Statistics.max(rows,function(event){return event[column];});}}
+const footerRows=[];if(this.showTotals_){const multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-selection-summary-table',created(){this.selection_=new tr.b.math.Range();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_(){const selection=this.selection_;const rows=[];let hasRange;if(this.selection_&&(!selection.bounds.isEmpty)){hasRange=true;}else{hasRange=false;}
+rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-b-radio-picker',created(){this.needsInit_=true;this.settingsKey_=undefined;this.isReady_=false;this.radioButtons_=undefined;this.selectedKey_=undefined;},ready(){this.isReady_=true;this.maybeInit_();this.maybeRenderRadioButtons_();},get vertical(){return this.getAttribute('vertical');},set vertical(vertical){if(vertical){this.setAttribute('vertical',true);}else{this.removeAttribute('vertical');}},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_){throw new Error('Already initialized.');}
+this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_(){if(!this.needsInit_)return;if(this.settingsKey_===undefined)return;this.needsInit_=false;this.select(tr.b.Settings.get(this.settingsKey_));},set items(items){this.radioButtons_={};items.forEach(function(e){if(e.key in this.radioButtons_){throw new Error(e.key+' already exists');}
+const radioButton=document.createElement('div');const input=document.createElement('input');const label=document.createElement('label');input.type='radio';input.id=e.label;input.addEventListener('click',function(){this.select(e.key);}.bind(this));Polymer.dom(label).innerHTML=e.label;label.htmlFor=e.label;label.style.display='inline';Polymer.dom(radioButton).appendChild(input);Polymer.dom(radioButton).appendChild(label);this.radioButtons_[e.key]=input;}.bind(this));this.maybeInit_();this.maybeRenderRadioButtons_();},maybeRenderRadioButtons_(){if(!this.isReady_)return;if(this.radioButtons_===undefined)return;for(const key in this.radioButtons_){Polymer.dom(this.$.container).appendChild(this.radioButtons_[key].parentElement);}
+if(this.selectedKey_!==undefined){this.select(this.selectedKey_);}},select(key){if(key===undefined||key===this.selectedKey_){return;}
+if(this.radioButtons_===undefined){this.selectedKey_=key;return;}
+if(!(key in this.radioButtons_)){throw new Error(key+' does not exists');}
+if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=false;}
+this.selectedKey_=key;tr.b.Settings.set(this.settingsKey_,this.selectedKey_);if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=true;}
+this.dispatchEvent(new tr.b.Event('change',false));},get selectedKey(){return this.selectedKey_;},});'use strict';tr.exportTo('tr.ui.b',function(){const MIN_GUIDELINE_HEIGHT_PX=3;const CHECKBOX_WIDTH_PX=18;const NameColumnChart=tr.ui.b.define('name-column-chart',tr.ui.b.ColumnChart);NameColumnChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},updateMargins_(){super.updateMargins_();let xAxisTickOverhangPx=0;for(let i=0;i<this.data_.length;++i){const datum=this.data_[i];xAxisTickOverhangPx=Math.max(xAxisTickOverhangPx,this.xScale_(i)+tr.ui.b.getSVGTextSize(this,datum.x).width-
+this.graphWidth);}
+this.margin.right=Math.max(this.margin.right,xAxisTickOverhangPx);},getXForDatum_(datum,index){return index;},get xAxisTickOffset(){return 0.5;},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;const nameTexts=xAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('transform',(d,index)=>'translate(0, '+
+this.textHeightPx_*(this.data_.length-index)+')').attr('x',(d,index)=>this.xScale_(index)).attr('y',d=>this.graphHeight).text(d=>d.x);nameTexts.exit().remove();const guideLines=xAxis.selectAll('line.guide').data(this.data_);guideLines.enter().append('line').attr('x1',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('x2',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('y1',()=>this.graphHeight).attr('y2',(d,index)=>this.graphHeight+Math.max(MIN_GUIDELINE_HEIGHT_PX,(this.textHeightPx_*(this.data_.length-index-1))));}};return{NameColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.LineChart;const NameLineChart=tr.ui.b.define('name-line-chart',LineChart);NameLineChart.prototype={__proto__:LineChart.prototype,getXForDatum_(datum,index){return index;},get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},get xAxisTickOffset(){return 0;},updateMargins_(){tr.ui.b.NameColumnChart.prototype.updateMargins_.call(this);},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length-1)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();}};return{NameLineChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BoxChart=tr.ui.b.define('box-chart',tr.ui.b.NameLineChart);BoxChart.prototype={__proto__:tr.ui.b.NameLineChart.prototype,get hideLegend(){return true;},updateDataRange_(){if(this.overrideDataRange_!==undefined){return;}
+this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateScales_(){super.updateScales_();this.xScale_.domain([0,this.data_.length]);},get xAxisTickOffset(){return 0.5;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const boxesSel=dataSel.selectAll('path');for(let index=0;index<this.data_.length;++index){const datum=this.data_[index];const color=datum.color||'black';let sel=boxesSel.data([datum]);sel.enter().append('rect').attr('fill',color).attr('x',this.xScale_(index+0.2)).attr('width',this.xScale_(index+0.8)-this.xScale_(index+0.2)).attr('y',this.yScale_(datum.percentile_75)).attr('height',this.yScale_(datum.percentile_25)-
+this.yScale_(datum.percentile_75));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index)).attr('x2',this.xScale_(index+1)).attr('y1',this.yScale_(datum.percentile_50)).attr('y2',this.yScale_(datum.percentile_50));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_0)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_100));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.5)).attr('x2',this.xScale_(index+0.5)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();}}};return{BoxChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BarChart=tr.ui.b.define('bar-chart',tr.ui.b.ColumnChart);BarChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,decorate(){super.decorate();this.verticalScale_=undefined;this.horizontalScale_=undefined;},updateScales_(){super.updateScales_();this.yScale_.range([this.graphWidth,0]);this.xScale_.range([0,this.graphHeight]);this.verticalScale_=this.isYLogScale_?d3.scale.log(10):d3.scale.linear();this.verticalScale_.domain(this.xScale_.domain());this.verticalScale_.range([this.graphHeight,0]);this.horizontalScale_=d3.scale.linear();this.horizontalScale_.domain(this.yScale_.domain());this.horizontalScale_.range([0,this.graphWidth]);},get defaultGraphHeight(){return Math.max(20,10*this.data_.length);},get defaultGraphWidth(){return 100;},get barHeight(){return this.graphHeight/this.data.length;},drawBrush_(brushRectsSel){brushRectsSel.attr('x',0).attr('width',this.graphWidth).attr('y',d=>this.verticalScale_(d.max)).attr('height',d=>this.verticalScale_(d.min)-this.verticalScale_(d.max));},getDataPointAtChartPoint_(chartPoint){const flippedPoint={x:this.graphHeight-chartPoint.y,y:this.graphWidth-chartPoint.x};return super.getDataPointAtChartPoint_(flippedPoint);},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.horizontalScale_).orient('bottom'));},get yAxisWidth(){return this.computeScaleTickWidth_(this.verticalScale_);},drawYAxis_(yAxis){const axisModifier=d3.svg.axis().scale(this.verticalScale_).orient('left');yAxis.call(axisModifier);},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;let xWidthPx=0;let xHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width;keyHeightPx=this.textHeightPx_;}
+if(this.data.length>1){xWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,''+rect.datum.x).width;xHeightPx=this.textHeightPx_;}
+const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width;const valueHeightPx=this.textHeightPx_;const hoverWidthPx=Math.min(Math.max(keyWidthPx,xWidthPx,valueWidthPx)+5,Math.max(50,rect.widthPx));const hoverTopPx=rect.topPx+(rect.heightPx/2);const hoverLeftPx=rect.leftPx+rect.widthPx-hoverWidthPx;chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',keyHeightPx+xHeightPx+valueHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-3).text(rect.key);}
+if(this.data.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+valueHeightPx-3).text(''+rect.datum.x);}
+chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+xHeightPx+keyHeightPx+valueHeightPx-3).text(rect.value);},flipRect_(rect){return{datum:rect.datum,index:rect.index,key:rect.key,value:rect.value,color:rect.color,topPx:this.graphHeight-rect.leftPx-rect.widthPx,leftPx:this.graphWidth-rect.topPx-rect.heightPx,widthPx:rect.heightPx,heightPx:rect.widthPx,underflow:rect.underflow,overflow:rect.overflow,};},drawRect_(rect,sel){super.drawRect_(this.flipRect_(rect),sel);},drawUnderflow_(rect,rectsSel){let sel=rectsSel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',0).attr('y',this.graphHeight-rect.leftPx+
+3+(rect.widthPx/2));sel.exit().remove();sel=rectsSel.data([rect]);sel.enter().append('rect').attr('fill','rgba(0, 0, 0, 0)').attr('x',0).attr('y',this.graphHeight-rect.leftPx-rect.widthPx).attr('width',10).attr('height',rect.widthPx).on('mouseenter',()=>this.drawHoverValueBox_(this.flipRect_(rect))).on('mouseleave',()=>this.clearHoverValueBox_(rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',this.graphWidth).attr('y',this.graphHeight-rect.leftPx+
+3+(rect.widthPx/2));sel.exit().remove();}};return{BarChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const NameBarChart=tr.ui.b.define('name-bar-chart',tr.ui.b.BarChart);const Y_AXIS_PADDING=2;NameBarChart.prototype={__proto__:tr.ui.b.BarChart.prototype,getDataPointAtChartPoint_(chartPoint){return{x:tr.ui.b.BarChart.prototype.getDataPointAtChartPoint_.call(this,chartPoint).x,y:parseInt(Math.floor((this.graphHeight-chartPoint.y)/this.barHeight))};},getXForDatum_(datum,index){return index;},get yAxisWidth(){if(this.data.length===0)return 0;return Y_AXIS_PADDING+tr.b.math.Statistics.max(this.data_,d=>tr.ui.b.getSVGTextSize(this,d.x).width);},get defaultGraphHeight(){return(3+this.textHeightPx_)*this.data.length;},updateYAxis_(yAxis){if(tr.ui.b.getSVGTextSize(this,'test').width===0){tr.b.requestAnimationFrame(()=>this.updateYAxis_(yAxis));return;}
+yAxis.selectAll('*').remove();const nameTexts=yAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('x',d=>-(tr.ui.b.getSVGTextSize(this,d.x).width+Y_AXIS_PADDING)).attr('y',(d,index)=>this.verticalScale_(index)).text(d=>d.x);nameTexts.exit().remove();let previousTop=undefined;for(const text of nameTexts[0]){const bbox=text.getBBox();if((previousTop===undefined)||(previousTop>(bbox.y+bbox.height))){previousTop=bbox.y;}else{text.style.opacity=0;}}}};return{NameBarChart,};});'use strict';tr.exportTo('tr.v.ui',function(){const DIAGNOSTIC_SPAN_BEHAVIOR={created(){this.diagnostic_=undefined;this.name_=undefined;this.histogram_=undefined;},attached(){if(this.diagnostic_)this.updateContents_();},get diagnostic(){return this.diagnostic_;},build(diagnostic,name,histogram){this.diagnostic_=diagnostic;this.name_=name;this.histogram_=histogram;if(this.isAttached)this.updateContents_();},updateContents_(){throw new Error('dom-modules must override updateContents_()');}};return{DIAGNOSTIC_SPAN_BEHAVIOR,};});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_COLOR_SCHEME=new tr.b.SinebowColorGenerator();class BreakdownTableSummaryRow{constructor(displayElement,histogramNames){this.displayElement_=displayElement;this.histogramNames_=histogramNames;this.keySpan_=undefined;}
+get numberValue(){return undefined;}
+get keySpan(){if(this.keySpan_===undefined){if(this.histogramNames_.length){this.keySpan_=document.createElement('tr-ui-a-analysis-link');this.keySpan_.setSelectionAndContent(this.histogramNames_,'Select All');}else{this.keySpan_='Sum';}}
+return this.keySpan_;}
+get name(){return'Sum';}
+get displayElement(){return this.displayElement_;}
+get stringPercent(){return'100%';}}
+class BreakdownTableRow{constructor(name,value,unit,color){this.name_=name;this.value=value;this.unit=unit;if(!this.isHistogram&&typeof value!=='number'){throw new Error('unsupported value '+value);}
+this.tableSum_=undefined;this.keySpan_=undefined;this.color_=color;const hsl=this.color.toHSL();hsl.l*=0.85;this.highlightedColor_=tr.b.Color.fromHSL(hsl);if(this.isHistogram){this.displayElement_=tr.v.ui.createScalarSpan(this.numberValue,{unit:this.value.unit,});}else{this.displayElement_=tr.ui.b.createSpan({textContent:this.stringValue,});}}
+get isHistogram(){return this.value instanceof tr.v.Histogram;}
+get name(){return this.name_;}
+get color(){return this.color_;}
+get highlightedColor(){return this.highlightedColor_;}
+get keySpan(){if(this.keySpan_===undefined){if(this.isHistogram){this.keySpan_=document.createElement('tr-ui-a-analysis-link');this.keySpan_.setSelectionAndContent([this.value.name],this.name);this.keySpan_.color=this.color;this.keySpan_.title=this.value.name;}else{this.keySpan_=document.createElement('span');this.keySpan_.innerText=this.name;this.keySpan_.style.color=this.color;}}
+return this.keySpan_;}
+get numberValue(){if(this.isHistogram)return this.value.sum;if(!isNaN(this.value)&&(this.value!==Infinity)&&(this.value!==-Infinity)&&(this.value>0))return this.value;return undefined;}
+get stringValue(){if(!this.isHistogram&&(isNaN(this.value)||this.value===Infinity||this.value===-Infinity)){return this.value.toString();}
+if(this.unit!==undefined)return this.unit.format(this.value);if(this.isHistogram)return this.value.sum.toString();return this.value.toString();}
+set tableSum(s){this.tableSum_=s;}
+get stringPercent(){if(this.tableSum_===undefined)return'';const num=this.numberValue;if(num===undefined)return'';return Math.floor(num*100.0/this.tableSum_)+'%';}
+get displayElement(){return this.displayElement_;}
+compare(other){if(this.numberValue===undefined){if(other.numberValue===undefined){return this.name.localeCompare(other.name);}
+return 1;}
+if(other.numberValue===undefined){return-1;}
+if(this.numberValue===other.numberValue){return this.name.localeCompare(other.name);}
+return other.numberValue-this.numberValue;}}
+Polymer({is:'tr-v-ui-breakdown-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],created(){this.chart_=new tr.ui.b.ColumnChart();this.chart_.graphHeight=130;this.chart_.isStacked=true;this.chart_.hideXAxis=true;this.chart_.hideLegend=true;this.chart_.enableHoverBox=false;this.chart_.addEventListener('rect-mouseenter',event=>this.onRectMouseEnter_(event));this.chart_.addEventListener('rect-mouseleave',event=>this.onRectMouseLeave_(event));},onRectMouseEnter_(event){for(const row of this.$.table.tableRows){if(row.name===event.rect.key){row.displayElement.style.background=event.rect.color;row.keySpan.scrollIntoViewIfNeeded();}else{row.displayElement.style.background='';}}},onRectMouseLeave_(event){for(const row of this.$.table.tableRows){row.displayElement.style.background='';}},ready(){Polymer.dom(this.$.container).appendChild(this.chart_);this.$.table.zebra=true;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row.keySpan,},{value:row=>row.displayElement,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},{value:row=>row.stringPercent,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},];},updateContents_(){this.$.container.style.display='none';this.$.table.style.display='none';this.$.empty.style.display='block';if(!this.diagnostic_){this.chart_.data=[];return;}
+if(this.histogram_)this.chart_.unit=this.histogram_.unit;let colorScheme=undefined;if(this.diagnostic.colorScheme===tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER){colorScheme=(name)=>{let cat=name.split(' ');cat=cat[cat.length-1];return tr.e.chrome.ChromeUserFriendlyCategoryDriver.getColor(cat);};}else if(this.diagnostic.colorScheme!==undefined){colorScheme=(name)=>tr.b.FixedColorSchemeRegistry.lookUp(this.diagnostic.colorScheme).getColor(name);}else{colorScheme=(name)=>DEFAULT_COLOR_SCHEME.colorForKey(name);}
+const tableRows=[];let tableSum=0;const histogramNames=[];for(const[name,value]of this.diagnostic){const row=new BreakdownTableRow(name,value,this.chart_.unit,colorScheme(name));tableRows.push(row);if(row.numberValue!==undefined)tableSum+=row.numberValue;if(row.isHistogram){histogramNames.push(value.name);}}
+tableRows.sort((x,y)=>x.compare(y));if(tableSum>0){let summaryDisplayElement=tableSum;if(this.chart_.unit!==undefined){summaryDisplayElement=this.chart_.unit.format(tableSum);}
+summaryDisplayElement=tr.ui.b.createSpan({textContent:summaryDisplayElement,});tableRows.unshift(new BreakdownTableSummaryRow(summaryDisplayElement,histogramNames));}
+const chartData={x:0};for(const row of tableRows){if(row.numberValue===undefined)continue;row.tableSum=tableSum;chartData[row.name]=row.numberValue;const dataSeries=this.chart_.getDataSeries(row.name);dataSeries.color=row.color;dataSeries.highlightedColor=row.highlightedColor;}
+if(tableRows.length>0){this.$.table.style.display='block';this.$.empty.style.display='none';this.$.table.tableRows=tableRows;this.$.table.rebuild();}
+if(Object.keys(chartData).length>1){this.$.container.style.display='block';this.$.empty.style.display='none';this.chart_.data=[chartData];}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-collected-related-event-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';for(const[canonicalUrl,events]of this.diagnostic){const link=document.createElement('a');if(events.length===1){const event=tr.b.getOnlyElement(events);link.textContent=event.title+' '+
+tr.b.Unit.byName.timeDurationInMs.format(event.duration);}else{link.textContent=events.length+' events';}
+link.href=canonicalUrl;Polymer.dom(this).appendChild(link);Polymer.dom(this).appendChild(document.createElement('br'));}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-date-range-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){if(this.diagnostic===undefined){Polymer.dom(this).textContent='';return;}
+Polymer.dom(this).textContent=this.diagnostic.toString();}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-generic-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],properties:{strings_:{type:Array,},},isUrl_(s){return tr.b.isUrl(s);},updateContents_(){if(this.diagnostic===undefined){this.$.generic.object=undefined;return;}
+const values=Array.from(this.diagnostic);let areAllStrings=true;let areAllNumbers=true;for(const value of values){if(typeof value!=='number'){areAllNumbers=false;if(typeof value!=='string'){areAllStrings=false;break;}}}
+if(areAllStrings){if(areAllNumbers){values.sort((x,y)=>x-y);}else{values.sort();}
+this.set('strings_',values);}else{this.$.generic.object=values;}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-related-event-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';const events=new tr.model.EventSet([...this.diagnostic]);const link=document.createElement('tr-ui-a-analysis-link');let label=events.length+' events';if(events.length===1){const event=tr.b.getOnlyElement(events);label=event.title+' ';label+=tr.b.Unit.byName.timeDurationInMs.format(event.duration);}
+link.setSelectionAndContent(events,label);Polymer.dom(this).appendChild(link);}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-related-histogram-map-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},updateContents_(){Polymer.dom(this).textContent='';const rows=[];const histogramNames=new Set();for(const[name,hist]of this.diagnostic){histogramNames.add(hist.name);}
+if(histogramNames.size>1){const link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent(Array.from(histogramNames),'Select All');rows.push([link,'']);}
+for(const[name,hist]of this.diagnostic){const link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent([hist.name],name);const scalarSpan=tr.v.ui.createScalarSpan(hist);rows.push([link,scalarSpan]);}
+this.$.table.tableRows=rows;this.$.table.rebuild();}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-diagnostic-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){this.$.scalar.setValueAndUnit(this.diagnostic.value.value,this.diagnostic.value.unit);}});return{};});'use strict';Polymer({is:'tr-v-ui-tag-map-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.generic.object=undefined;return;}
+const obj={};for(const[tag,stories]of this.diagnostic.tagsToStoryNames){obj[tag]=Array.from(stories);}
+this.$.generic.object=obj;},onShow_(){this.$.show.style.display='none';this.$.hide.style.display='block';this.$.generic.style.display='block';},onHide_(){this.$.show.style.display='block';this.$.hide.style.display='none';this.$.generic.style.display='none';},});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-unmergeable-diagnostic-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';for(const diagnostic of this.diagnostic){const div=document.createElement('div');div.appendChild(tr.v.ui.createDiagnosticSpan(diagnostic,this.name_,this.histogram_));Polymer.dom(this).appendChild(div);}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){function findElementNameForDiagnostic(diagnostic){let typeInfo=undefined;let curProto=diagnostic.constructor.prototype;while(curProto){typeInfo=tr.v.d.Diagnostic.findTypeInfo(curProto.constructor);if(typeInfo&&typeInfo.metadata.elementName)break;typeInfo=undefined;curProto=curProto.__proto__;}
+if(typeInfo===undefined){throw new Error(diagnostic.constructor.name+' or a base class must have a registered elementName');}
+const tagName=typeInfo.metadata.elementName;if(tr.ui.b.isUnknownElementName(tagName)){throw new Error('Element not registered: '+tagName);}
+return tagName;}
+function createDiagnosticSpan(diagnostic,name,histogram){const tagName=findElementNameForDiagnostic(diagnostic);const span=document.createElement(tagName);if(span.build===undefined)throw new Error(tagName);span.build(diagnostic,name,histogram);return span;}
+return{createDiagnosticSpan,};});'use strict';tr.exportTo('tr.v.ui',function(){function makeColumn(title,histogram){return{title,value(map){const diagnostic=map.get(title);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic,title,histogram);}};}
+Polymer({is:'tr-v-ui-diagnostic-map-table',created(){this.diagnosticMaps_=undefined;this.histogram_=undefined;this.isMetadata_=false;},set histogram(h){this.histogram_=h;},set isMetadata(m){this.isMetadata_=m;this.$.table.showHeader=!this.isMetadata_;},set diagnosticMaps(maps){this.diagnosticMaps_=maps;this.updateContents_();},get diagnosticMaps(){return this.diagnosticMaps_;},updateContents_(){if(this.isMetadata_&&this.diagnosticMaps_.length!==1){throw new Error('Metadata diagnostic-map-tables require exactly 1 DiagnosticMap');}
+if(this.diagnosticMaps_===undefined||this.diagnosticMaps_.length===0){this.$.table.tableRows=[];this.$.table.tableColumns=[];return;}
+let names=new Set();for(const map of this.diagnosticMaps_){for(const[name,diagnostic]of map){if(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)continue;if(diagnostic instanceof tr.v.d.CollectedRelatedEventSet)continue;if(diagnostic instanceof tr.v.d.GroupingPath)continue;names.add(name);}}
+names=Array.from(names).sort();const histogram=this.histogram_;if(this.isMetadata_){const diagnosticMap=this.diagnosticMaps_[0];this.$.table.tableColumns=[{value(name){return name.name;}},{value(name){const diagnostic=diagnosticMap.get(name.name);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic,name,histogram);}},];this.$.table.tableRows=names.map(name=>{return{name};});}else{this.$.table.tableColumns=names.map(name=>makeColumn(name,histogram));this.$.table.tableRows=this.diagnosticMaps_;}
+this.$.table.rebuild();}});return{};});'use strict';tr.exportTo('tr.b',function(){class Serializable{constructor(){Object.defineProperty(this,'properties_',{configurable:false,enumerable:false,value:new Map(),});}
+define(name,initialValue){if(this[name]!==undefined){throw new Error(`"${name}" is already defined.`);}
+if(name[name.length-1]==='_'){throw new Error(`"${name}" cannot end with an underscore.`);}
+this.properties_.set(name,initialValue);Object.defineProperty(this,name,{configurable:false,enumerable:true,get:()=>this.properties_.get(name),set:value=>this.setProperty_(name,value),});}
+setProperty_(name,value){this.properties_.set(name,value);}
+clone(){return Serializable.fromDict(this.asDict());}
+asDict(){function visit(obj){if(obj instanceof Serializable)return obj.asDict();if(obj instanceof Set)return Array.from(obj);if(obj instanceof Array)return obj.map(visit);if(!(obj instanceof Map))return obj;const result={};for(const[name,value]of obj){result[name]=visit(value);}
+return result;}
+const dict={type:this.constructor.name};for(const[name,value]of this.properties_){dict[name.replace(/_$/,'')]=visit(value);}
+return dict;}
+static fromDict(dict){function visit(d){if(d instanceof Array)return d.map(visit);if(!(d instanceof Object))return d;if(typeof d.type==='string')return Serializable.fromDict(d);const result=new Map();for(const[name,value]of Object.entries(d)){result.set(name,visit(value));}
+return result;}
+const typeInfo=Serializable.findTypeInfoWithName(dict.type);const result=new typeInfo.constructor();for(const[name,value]of Object.entries(dict)){result[name]=visit(value);}
+return result;}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Serializable;tr.b.decorateExtensionRegistry(Serializable,options);return{Serializable,};});'use strict';tr.exportTo('tr.b',function(){class ViewState extends tr.b.Serializable{constructor(){super();tr.b.EventTarget.decorate(this);}
+setProperty_(name,value){this.update(new Map([[name,value]]));}
+async updateFromViewState(other){await this.update(other.properties_);}
+async update(delta){if(!(delta instanceof Map))delta=new Map(Object.entries(delta));const actualDelta={};for(const[name,current]of delta){const previous=this[name];if(previous===current)continue;actualDelta[name]={previous,current};tr.b.Serializable.prototype.setProperty_.call(this,name,current);}
+if(Object.keys(actualDelta).length===0)return;await tr.b.dispatchSimpleEventAsync(this,this.updateEventName_,{delta:actualDelta});}
+get updateEventName_(){return this.constructor.name+'.update';}
+addUpdateListener(listener){this.addEventListener(this.updateEventName_,listener);}
+removeUpdateListener(listener){this.removeEventListener(this.updateEventName_,listener);}}
+return{ViewState,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetViewState extends tr.b.ViewState{constructor(){super();this.define('searchQuery','');this.define('referenceDisplayLabel','');this.define('displayStatisticName','');this.define('showAll',false);this.define('groupings',[]);this.define('sortColumnIndex',0);this.define('sortDescending',false);this.define('constrainNameColumn',true);this.define('tableRowStates',new Map());this.define('alpha',0.01);}}
+tr.b.ViewState.register(HistogramSetViewState);class HistogramSetTableRowState extends tr.b.ViewState{constructor(){super();this.define('isExpanded',false);this.define('isOverviewed',false);this.define('cells',new Map());this.define('subRows',new Map());this.define('diagnosticsTab','');}
+asCompactDict(){const result={};if(this.isExpanded)result.e='1';if(this.isOverviewed)result.o='1';if(this.diagnosticsTab)result.d=this.diagnosticsTab;const cells={};for(const[name,cell]of this.cells){const cellDict=cell.asCompactDict();if(cellDict===undefined)continue;cells[name]=cellDict;}
+if(Object.keys(cells).length>0)result.c=cells;const subRows={};for(const[name,row]of this.subRows){const rowDict=row.asCompactDict();if(rowDict===undefined)continue;subRows[name]=rowDict;}
+if(Object.keys(subRows).length>0)result.r=subRows;if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){await this.update({isExpanded:dict.e==='1',isOverviewed:dict.o==='1',diagnosticsTab:dict.d||'',});for(const[name,cellDict]of Object.entries(dict.c||{})){const cell=this.cells.get(name);if(cell===undefined)continue;await cell.updateFromCompactDict(cellDict);}
+for(const[name,subRowDict]of Object.entries(dict.r||{})){const subRow=this.subRows.get(name);if(subRow===undefined)continue;await subRow.updateFromCompactDict(subRowDict);}}*walk(){yield this;for(const row of this.subRows.values())yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}}
+tr.b.ViewState.register(HistogramSetTableRowState);class HistogramSetTableCellState extends tr.b.ViewState{constructor(){super();this.define('isOpen',false);this.define('brushedBinRange',new tr.b.math.Range());this.define('mergeSampleDiagnostics',true);}
+asCompactDict(){const result={};if(this.isOpen)result.o='1';if(!this.mergeSampleDiagnostics)result.m='0';if(!this.brushedBinRange.isEmpty){result.b=this.brushedBinRange.min+'_'+this.brushedBinRange.max;}
+if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){let binRange=this.brushedBinRange;if(dict.b){let[bMin,bMax]=dict.b.split('_');bMin=parseInt(bMin);bMax=parseInt(bMax);if(bMin!==binRange.min||bMax!==binRange.max){binRange=tr.b.math.Range.fromExplicitRange(bMin,bMax);}}
+await this.update({isOpen:dict.o==='1',brushedBinRange:binRange,mergeSampleDiagnostics:dict.m!=='0',});}}
+tr.b.ViewState.register(HistogramSetTableCellState);return{HistogramSetTableCellState,HistogramSetTableRowState,HistogramSetViewState,};});'use strict';Polymer({is:'tr-v-ui-scalar-map-table',created(){this.scalarMap_=new Map();this.significance_=new Map();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{value(row){return row.name;}},{value(row){const span=tr.v.ui.createScalarSpan(row.value);if(row.significance!==undefined){span.significance=row.significance;}else if(row.anyRowsHaveSignificance){span.style.marginRight='18px';}
+span.style.whiteSpace='nowrap';return span;}}];},get scalarMap(){return this.scalarMap_;},set scalarMap(map){this.scalarMap_=map;this.updateContents_();},setSignificanceForKey(key,significance){this.significance_.set(key,significance);this.updateContents_();},updateContents_(){const rows=[];for(const[key,scalar]of this.scalarMap){rows.push({name:key,value:scalar,significance:this.significance_.get(key),anyRowsHaveSignificance:(this.significance_.size>0)});}
+this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_BAR_HEIGHT_PX=5;const TRUNCATE_BIN_MARGIN=0.15;const IGNORE_DELTA_STATISTICS_NAMES=[`${tr.v.DELTA}min`,`%${tr.v.DELTA}min`,`${tr.v.DELTA}max`,`%${tr.v.DELTA}max`,`${tr.v.DELTA}sum`,`%${tr.v.DELTA}sum`,`${tr.v.DELTA}count`,`%${tr.v.DELTA}count`,];Polymer({is:'tr-v-ui-histogram-span',created(){this.viewStateListener_=this.onViewStateUpdate_.bind(this);this.viewState=new tr.v.ui.HistogramSetTableCellState();this.rowStateListener_=this.onRowStateUpdate_.bind(this);this.rowState=new tr.v.ui.HistogramSetTableRowState();this.histogram_=undefined;this.referenceHistogram_=undefined;this.graphWidth_=undefined;this.graphHeight_=undefined;this.mouseDownBin_=undefined;this.prevBrushedBinRange_=new tr.b.math.Range();this.anySampleDiagnostics_=false;this.canMergeSampleDiagnostics_=true;this.alpha_=undefined;},get rowState(){return this.rowState_;},set rowState(rs){if(this.rowState){this.rowState.removeUpdateListener(this.rowStateListener_);}
+this.rowState_=rs;this.rowState.addUpdateListener(this.rowStateListener_);if(this.isAttached)this.updateContents_();},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState){this.viewState.removeUpdateListener(this.viewStateListener_);}
+this.viewState_=vs;this.viewState.addUpdateListener(this.viewStateListener_);if(this.isAttached)this.updateContents_();},onViewStateUpdate_(event){if(event.delta.brushedBinRange){if(this.chart_!==undefined){this.chart_.brushedRange=this.viewState.brushedBinRange;}
+this.updateDiagnostics_();}
+if(event.delta.mergeSampleDiagnostics&&(this.viewState.mergeSampleDiagnostics!==this.$.merge_sample_diagnostics.checked)){this.$.merge_sample_diagnostics.checked=this.canMergeSampleDiagnostics&&this.viewState.mergeSampleDiagnostics;this.updateDiagnostics_();}},onRowStateUpdate_(event){if(event.delta.diagnosticsTab){if(this.rowState.diagnosticsTab===this.$.sample_diagnostics_container.tabLabel){this.updateDiagnostics_();}else{for(const tab of this.$.diagnostics.subViews){if(this.rowState.diagnosticsTab===tab.tabLabel){this.$.diagnostics.selectedSubView=tab;break;}}}}},ready(){this.$.metric_diagnostics.tabLabel='histogram diagnostics';this.$.sample_diagnostics_container.tabLabel='sample diagnostics';this.$.metadata_diagnostics.tabLabel='metadata';this.$.metadata_diagnostics.isMetadata=true;this.$.diagnostics.addEventListener('selected-tab-change',this.onSelectedDiagnosticsChanged_.bind(this));this.$.drag_handle.target=this.$.container;this.$.drag_handle.addEventListener('drag-handle-resize',this.onResize_.bind(this));},attached(){if(this.histogram_!==undefined)this.updateContents_();},get canMergeSampleDiagnostics(){return this.canMergeSampleDiagnostics_;},set canMergeSampleDiagnostics(merge){this.canMergeSampleDiagnostics_=merge;if(!merge)this.viewState.mergeSampleDiagnostics=false;this.$.merge_sample_diagnostics_container.style.display=(merge?'':'none');},onResize_(event){event.stopPropagation();let heightPx=parseInt(this.$.container.style.height);if(heightPx<this.defaultGraphHeight){heightPx=this.defaultGraphHeight;this.$.container.style.height=this.defaultGraphHeight+'px';}
+this.chart_.graphHeight=heightPx-(this.chart_.margin.top+
+this.chart_.margin.bottom);this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';},get graphWidth(){return this.graphWidth_||this.defaultGraphWidth;},set graphWidth(width){this.graphWidth_=width;},get graphHeight(){return this.graphHeight_||this.defaultGraphHeight;},set graphHeight(height){this.graphHeight_=height;},get barHeight(){return this.chart_.barHeight;},set barHeight(px){this.graphHeight=this.computeChartHeight_(px);},computeChartHeight_(barHeightPx){return(this.chart_.margin.top+
+this.chart_.margin.bottom+
+(barHeightPx*this.histogram.allBins.length));},get defaultGraphHeight(){if(this.histogram&&this.histogram.allBins.length===1){return 150;}
+return this.computeChartHeight_(DEFAULT_BAR_HEIGHT_PX);},get defaultGraphWidth(){if(this.histogram.allBins.length===1){return 100;}
+return 300;},get brushedBins(){const bins=[];if(this.histogram&&!this.viewState.brushedBinRange.isEmpty){for(let i=this.viewState.brushedBinRange.min;i<this.viewState.brushedBinRange.max;++i){bins.push(this.histogram.allBins[i]);}}
+return bins;},async updateBrushedRange_(binIndex){const brushedBinRange=new tr.b.math.Range();brushedBinRange.addValue(tr.b.math.clamp(this.mouseDownBinIndex_,0,this.histogram.allBins.length-1));brushedBinRange.addValue(tr.b.math.clamp(binIndex,0,this.histogram.allBins.length-1));brushedBinRange.max+=1;await this.viewState.update({brushedBinRange});},onMouseDown_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.prevBrushedBinRange_=this.viewState.brushedBinRange;this.mouseDownBinIndex_=chartEvent.y;this.updateBrushedRange_(chartEvent.y);},onMouseMove_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.updateBrushedRange_(chartEvent.y);},onMouseUp_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.updateBrushedRange_(chartEvent.y);if(this.prevBrushedBinRange_.range===1&&this.viewState.brushedBinRange.range===1&&(this.prevBrushedBinRange_.min===this.viewState.brushedBinRange.min)){tr.b.Timing.instant('histogram-span','clearBrushedBins');this.viewState.update({brushedBinRange:new tr.b.math.Range()});}else{tr.b.Timing.instant('histogram-span','brushBins');}
+this.mouseDownBinIndex_=undefined;},async onSelectedDiagnosticsChanged_(){await this.rowState.update({diagnosticsTab:this.$.diagnostics.selectedSubView.tabLabel,});if((this.$.diagnostics.selectedSubView===this.$.sample_diagnostics_container)&&this.histogram&&this.viewState.brushedBinRange.isEmpty){const brushedBinRange=tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length);await this.viewState.update({brushedBinRange});this.updateDiagnostics_();}},updateDiagnostics_(){let maps=[];for(const bin of this.brushedBins){for(const map of bin.diagnosticMaps){maps.push(map);}}
+if(this.$.merge_sample_diagnostics.checked!==this.viewState.mergeSampleDiagnostics){this.viewState.update({mergeSampleDiagnostics:this.$.merge_sample_diagnostics.checked});}
+if(this.viewState.mergeSampleDiagnostics){const merged=new tr.v.d.DiagnosticMap();for(const map of maps){merged.addDiagnostics(map);}
+maps=[merged];}
+const mark=tr.b.Timing.mark('histogram-span',(this.viewState.mergeSampleDiagnostics?'merge':'split')+'SampleDiagnostics');this.$.sample_diagnostics.diagnosticMaps=maps;mark.end();if(this.anySampleDiagnostics_){this.$.diagnostics.selectedSubView=this.$.sample_diagnostics_container;}},get histogram(){return this.histogram_;},set histogram(histogram){if(histogram===this.histogram_)return;this.histogram_=histogram;this.$.metric_diagnostics.histogram=histogram;this.$.sample_diagnostics.histogram=histogram;this.anySampleDiagnostics_=false;for(const bin of this.histogram.allBins){if(bin.diagnosticMaps.length>0){this.anySampleDiagnostics_=true;break;}}
+if(this.isAttached)this.updateContents_();},get referenceHistogram(){return this.referenceHistogram_;},set referenceHistogram(histogram){if(histogram===this.referenceHistogram_){return;}
+this.referenceHistogram_=histogram;if(this.histogram)this.updateContents_();},set alpha(a){if(tr.b.math.approximately(a,this.alpha_))return;this.alpha_=a;if(this.referenceHistogram)this.updateContents_();},getDeltaScalars_(statNames,scalarMap){if(!this.histogram.canCompare(this.referenceHistogram))return;const mwu=tr.b.math.Statistics.mwu(this.histogram.sampleValues,this.referenceHistogram.sampleValues,this.alpha_);for(const deltaStatName of tr.v.Histogram.getDeltaStatisticsNames(statNames)){if(IGNORE_DELTA_STATISTICS_NAMES.includes(deltaStatName))continue;const scalar=this.histogram.getStatisticScalar(deltaStatName,this.referenceHistogram,mwu);if(scalar===undefined)continue;scalarMap.set(deltaStatName,scalar);}
+if(this.histogram.unit.improvementDirection!==tr.b.ImprovementDirection.DONT_CARE){this.$.stats.setSignificanceForKey(`${tr.v.DELTA}avg`,mwu.significance);}},set isYLogScale(logScale){this.chart_.isYLogScale=logScale;},async updateContents_(){this.$.chart.style.display='none';this.$.drag_handle.style.display='none';this.$.container.style.justifyContent='';while(Polymer.dom(this.$.chart).lastChild){Polymer.dom(this.$.chart).removeChild(Polymer.dom(this.$.chart).lastChild);}
+if(!this.histogram)return;this.$.container.style.display='';const scalarMap=new Map();this.getDeltaScalars_(this.histogram.statisticsNames,scalarMap);for(const[name,scalar]of this.histogram.statisticsScalars){scalarMap.set(name,scalar);}
+this.$.stats.scalarMap=scalarMap;const metricDiagnosticMap=new tr.v.d.DiagnosticMap();const metadataDiagnosticMap=new tr.v.d.DiagnosticMap();for(const[key,diagnostic]of this.histogram.diagnostics){if(key===tr.v.d.RESERVED_NAMES.MERGED_FROM)continue;if(key===tr.v.d.RESERVED_NAMES.MERGED_TO)continue;if(tr.v.d.RESERVED_NAMES_SET.has(key)){metadataDiagnosticMap.set(key,diagnostic);}else{metricDiagnosticMap.set(key,diagnostic);}}
+const diagnosticTabs=[];if(metricDiagnosticMap.size){this.$.metric_diagnostics.diagnosticMaps=[metricDiagnosticMap];diagnosticTabs.push(this.$.metric_diagnostics);}
+if(this.anySampleDiagnostics_){diagnosticTabs.push(this.$.sample_diagnostics_container);}
+if(metadataDiagnosticMap.size){this.$.metadata_diagnostics.diagnosticMaps=[metadataDiagnosticMap];diagnosticTabs.push(this.$.metadata_diagnostics);}
+this.$.diagnostics.resetSubViews(diagnosticTabs);this.$.diagnostics.set('tabsHidden',diagnosticTabs.length<2);if(this.histogram.numValues<=1){await this.viewState.update({brushedBinRange:tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length)});this.$.container.style.justifyContent='flex-end';return;}
+this.$.chart.style.display='block';this.$.drag_handle.style.display='block';if(this.histogram.allBins.length===1){if(this.histogram.min!==this.histogram.max){this.chart_=new tr.ui.b.BoxChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.hideXAxis=true;this.chart_.data=[{x:'',color:'blue',percentile_0:this.histogram.running.min,percentile_25:this.histogram.getApproximatePercentile(0.25),percentile_50:this.histogram.getApproximatePercentile(0.5),percentile_75:this.histogram.getApproximatePercentile(0.75),percentile_100:this.histogram.running.max,}];}
+this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';await this.viewState.update({brushedBinRange:tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length)});return;}
+this.chart_=new tr.ui.b.NameBarChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.addEventListener('item-mousedown',this.onMouseDown_.bind(this));this.chart_.addEventListener('item-mousemove',this.onMouseMove_.bind(this));this.chart_.addEventListener('item-mouseup',this.onMouseUp_.bind(this));this.chart_.hideLegend=true;this.chart_.getDataSeries('y').color='blue';this.chart_.xAxisLabel='#';this.chart_.brushedRange=this.viewState.brushedBinRange;if(!this.viewState.brushedBinRange.isEmpty){this.updateDiagnostics_();}
+const chartData=[];const binCounts=[];for(const bin of this.histogram.allBins){let x=bin.range.min;if(x===-Number.MAX_VALUE){x='<'+new tr.b.Scalar(this.histogram.unit,bin.range.max).toString();}else{x=new tr.b.Scalar(this.histogram.unit,x).toString();}
+chartData.push({x,y:bin.count});binCounts.push(bin.count);}
+binCounts.sort((x,y)=>y-x);const dataRange=tr.b.math.Range.fromExplicitRange(0,binCounts[0]);if(binCounts[1]>0&&binCounts[0]>(binCounts[1]*2)){dataRange.max=binCounts[1]*(1+TRUNCATE_BIN_MARGIN);}
+if(binCounts[2]>0&&binCounts[1]>(binCounts[2]*2)){dataRange.max=binCounts[2]*(1+TRUNCATE_BIN_MARGIN);}
+this.chart_.overrideDataRange=dataRange;this.chart_.data=chartData;this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';}});});'use strict';tr.exportTo('tr.ui.analysis',function(){const EVENT_FIELD=[{key:'start',label:'Start'},{key:'cpuDuration',label:'CPU Duration'},{key:'duration',label:'Duration'},{key:'cpuSelfTime',label:'CPU Self Time'},{key:'selfTime',label:'Self Time'}];function buildDiagnostics_(slice){const diagnostics={};for(const item of EVENT_FIELD){const fieldName=item.key;if(slice[fieldName]===undefined)continue;diagnostics[fieldName]=new tr.v.d.Scalar(new tr.b.Scalar(tr.b.Unit.byName.timeDurationInMs,slice[fieldName]));}
+diagnostics.args=new tr.v.d.GenericSet([slice.args]);diagnostics.event=new tr.v.d.RelatedEventSet(slice);return diagnostics;}
+Polymer({is:'tr-ui-a-multi-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready(){this.$.radioPicker.style.display='none';this.$.radioPicker.items=EVENT_FIELD;this.$.radioPicker.select('cpuSelfTime');this.$.radioPicker.addEventListener('change',()=>{if(this.isAttached)this.updateContents_();});this.$.histogramSpan.graphWidth=400;this.$.histogramSpan.canMergeSampleDiagnostics=false;this.$.histogramContainer.style.display='none';},attached(){if(this.currentSelection_!==undefined)this.updateContents_();},set selection(selection){if(selection.length<=1){throw new Error('Only supports multiple items');}
+this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;if(this.isAttached)this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;if(this.isAttached)this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;if(this.isAttached)this.updateContents_();},buildHistogram_(selectedKey){let leftBoundary=Number.MAX_VALUE;let rightBoundary=tr.b.math.Statistics.percentile(this.currentSelection_,0.95,function(value){leftBoundary=Math.min(leftBoundary,value[selectedKey]);return value[selectedKey];});if(leftBoundary===rightBoundary)rightBoundary+=1;const histogram=new tr.v.Histogram('',tr.b.Unit.byName.timeDurationInMs,tr.v.HistogramBinBoundaries.createLinear(leftBoundary,rightBoundary,Math.ceil(Math.sqrt(this.currentSelection_.length))));histogram.customizeSummaryOptions({sum:false});for(const slice of this.currentSelection_){histogram.addSample(slice[selectedKey],buildDiagnostics_(slice));}
+return histogram;},updateContents_(){const selection=this.currentSelection_;if(!selection)return;const eventsByTitle=selection.getEventsOrganizedByTitle();const numTitles=Object.keys(eventsByTitle).length;this.$.eventSummaryTable.configure({showTotals:numTitles>1,eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.selectionSummaryTable.selection=this.currentSelection_;if(numTitles===1){this.$.radioPicker.style.display='block';this.$.histogramContainer.style.display='flex';this.$.histogramSpan.histogram=this.buildHistogram_(this.$.radioPicker.selectedKey);if(this.$.histogramSpan.histogram.numValues===0){this.$.histogramContainer.style.display='none';}}else{this.$.radioPicker.style.display='none';this.$.histogramContainer.style.display='none';}}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const FLOW_IN=0x1;const FLOW_OUT=0x2;const FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_(event){let fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents(){return this.numEvents_>0;},get inFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN){selection.push(fs.event);}}
+return selection;},get outFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT){selection.push(fs.event);}}
+return selection;},get internalFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT){selection.push(fs.event);}}
+return selection;}};return{FlowClassifier,};});'use strict';function*getEventInFlowEvents(event){if(!event.inFlowEvents)return;yield*event.inFlowEvents;}
+function*getEventOutFlowEvents(event){if(!event.outFlowEvents)return;yield*event.outFlowEvents;}
+function*getEventAncestors(event){if(!event.enumerateAllAncestors)return;yield*event.enumerateAllAncestors();}
+function*getEventDescendents(event){if(!event.enumerateAllDescendents)return;yield*event.enumerateAllDescendents();}
+Polymer({is:'tr-ui-a-related-events',ready(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedEvents(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addRuntimeCallStats_(eventSet);this.addOverlappingV8ICStats_(eventSet);this.addV8GCObjectStats_(eventSet);this.addV8Slices_(eventSet);this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_(eventSet){const classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())return;const addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventAncestors(event);if(event.startSlice){yield event.startSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function*(event){yield*getEventOutFlowEvents(event);yield*getEventDescendents(event);if(event.endSlice){yield event.endSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventOutFlowEvents(event);yield*getEventAncestors(event);yield*getEventDescendents(event);if(event.startSlice){yield event.startSlice;}
+if(event.endSlice){yield event.endSlice;}}.bind(this)));},createEventsLinkIfNeeded_(title,tooltip,events,connectedFn){events=new tr.model.EventSet(events);const eventsToProcess=new Set(events);let wasChanged=false;let task;let isCanceled=false;function addEventsUntilTimeout(){if(isCanceled)return;const timeout=window.performance.now()+8;while(eventsToProcess.size>0&&window.performance.now()<=timeout){const nextEvent=tr.b.getFirstElement(eventsToProcess);eventsToProcess.delete(nextEvent);for(const eventToAdd of connectedFn(nextEvent)){if(!events.contains(eventToAdd)){events.push(eventToAdd);eventsToProcess.add(eventToAdd);wasChanged=true;}}}
+if(eventsToProcess.size>0){const newTask=new tr.b.Task(addEventsUntilTimeout.bind(this),this);task.after(newTask);task=newTask;return;}
+if(!wasChanged)return;this.eventGroups_.push({type:title,tooltip,selection:events});this.updateContents_();}
+function cancelTask(){isCanceled=true;}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addOverlappingSamples_(eventSet){const samples=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.samples){continue;}
+const candidates=slice.parentContainer.samples;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSamples=range.filterArray(candidates,function(value){return value.start;});for(const sample of filteredSamples){samples.push(sample);}}
+if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},addV8Slices_(eventSet){const v8Slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.category==='v8'){v8Slices.push(slice);}}
+if(v8Slices.length>0){this.eventGroups_.push({type:'V8 Slices',tooltip:'All V8 slices in the selected slice(s).',selection:v8Slices});}},addRuntimeCallStats_(eventSet){const slices=eventSet.filter(function(slice){return(slice.category==='v8'||slice.category==='disabled-by-default-v8.runtime_stats')&&slice.runtimeCallStats;});if(slices.length>0){this.eventGroups_.push({type:'Runtime call stats table',tooltip:'All V8 slices containing runtime call stats table in the selected slice(s).',selection:slices});}},addV8GCObjectStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.title==='V8.GC_Objects_Stats'){slices.push(slice);}}
+if(slices.length>0){this.eventGroups_.push({type:'V8 GC stats table',tooltip:'All V8 GC statistics slices in the selected set.',selection:slices});}},addOverlappingV8ICStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.sliceGroup){continue;}
+const sliceGroup=slice.parentContainer.sliceGroup.slices;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSlices=range.filterArray(sliceGroup,value=>value.start);const icSlices=filteredSlices.filter(x=>x.title==='V8.ICStats');for(const icSlice of icSlices){slices.push(icSlice);}}
+if(slices.length>0){this.eventGroups_.push({type:'Overlapping V8 IC stats',tooltip:'All V8 IC statistics overlapping the selected set.',selection:slices});}},updateContents_(){const table=this.$.table;if(this.eventGroups_===undefined){table.tableRows=[];}else{table.tableRows=this.eventGroups_.slice();}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)return undefined;const selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)return selection;return undefined;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-async-slice-sub-view',tr.model.AsyncSlice,{multi:true,title:'Async Slices',});'use strict';Polymer({is:'tr-ui-a-multi-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-cpu-slice-sub-view',tr.model.CpuSlice,{multi:true,title:'CPU Slices',});'use strict';Polymer({is:'tr-ui-a-multi-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-flow-event-sub-view',tr.model.FlowEvent,{multi:true,title:'Flow Events',});'use strict';Polymer({is:'tr-ui-a-multi-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-frame-sub-view',tr.model.Frame,{multi:true,title:'Frames',});'use strict';Polymer({is:'tr-ui-a-multi-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this.$.content).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer({is:'tr-ui-a-multi-object-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;const objectEvents=Array.from(selection).sort(tr.b.math.Range.compareByMinTimes);const timeSpanConfig={unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};const table=this.$.content;table.tableColumns=[{title:'First',value(event){if(event instanceof tr.model.ObjectSnapshot){return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);}
+const spanEl=document.createElement('span');Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));Polymer.dom(spanEl).appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!==Number.MAX_VALUE){Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectInstance,{multi:true,title:'Object Instances',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectSnapshot,{multi:true,title:'Object Snapshots',});'use strict';const EventSet=tr.model.EventSet;const CHART_TITLE='Power (W) by ms since vertical sync';Polymer({is:'tr-ui-a-frame-power-usage-chart',ready(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},attached(){if(this.samples_)this.updateContents_();},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;if(this.isAttached)this.updateContents_();},updateContents_(){this.clearChart_();const data=this.getDataForLineChart_();if(data.length===0)return;this.chart_=new tr.ui.b.LineChart();Polymer.dom(this.$.content).appendChild(this.chart_);this.chart_.chartTitle=CHART_TITLE;this.chart_.data=data;},clearChart_(){const content=this.$.content;while(Polymer.dom(content).firstChild){Polymer.dom(content).removeChild(Polymer.dom(content).firstChild);}
+this.chart_=undefined;},getDataForLineChart_(){const sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);const vSyncTimestamps=this.vSyncTimestamps.slice();let lastVSyncTimestamp=undefined;const points=[];let frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)return;const point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.powerInW;points.push(point);});return points;},sortSamplesByTimestampAscending_(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer({is:'tr-ui-a-power-sample-summary-table',ready(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.min);}},{title:'Max power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.max);}},{title:'Time-weighted average',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.timeWeightedAverageInW);}},{title:'Energy consumed',width:'100px',value(row){return tr.b.Unit.byName.energyInJoules.format(row.energyConsumedInJ);}},{title:'Sample count',width:'100%',value(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverageInW:this.getTimeWeightedAverageInW(),energyConsumedInJ:this.getEnergyConsumedInJ(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin(){return Math.min.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getMax(){return Math.max.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getTimeWeightedAverageInW(){const energyConsumedInJ=this.getEnergyConsumedInJ();if(energyConsumedInJ==='N/A')return'N/A';const durationInS=tr.b.convertUnit(this.samples.bounds.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return energyConsumedInJ/durationInS;},getEnergyConsumedInJ(){if(this.samples.length<2)return'N/A';const bounds=this.samples.bounds;const series=tr.b.getFirstElement(this.samples).series;return series.getEnergyConsumedInJ(bounds.min,bounds.max);}});'use strict';Polymer({is:'tr-ui-a-multi-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){const samples=this.selection;const vSyncTimestamps=(!samples?[]:tr.b.getFirstElement(samples).series.device.vSyncTimestamps);this.$.summaryTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-power-sample-sub-view',tr.model.PowerSample,{multi:true,title:'Power Samples',});'use strict';(function(){const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;Polymer({is:'tr-ui-a-multi-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.viewOption_=undefined;this.selection_=undefined;},ready(){const viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]);Polymer.dom(this.$.control).appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_(selection,viewOption){const builder=new MultiDimensionalViewBuilder(1,1);const samples=selection.filter(event=>event instanceof tr.model.Sample);samples.forEach(function(sample){builder.addPath([sample.userFriendlyStack.reverse()],[1],MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},processSampleRows_(rows){for(const row of rows){let title=row.title[0];let results=/(.*) (Deoptimized reason: .*)/.exec(title);if(results!==null){row.deoptReason=results[2];title=results[1];}
+results=/(.*) url: (.*)/.exec(title);if(results!==null){row.functionName=results[1];row.url=results[2];if(row.functionName===''){row.functionName='(anonymous function)';}
+if(row.url===''){row.url='unknown';}}else{row.functionName=title;row.url='unknown';}
+this.processSampleRows_(row.subRows);}},updateContents_(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
+const samplingData=this.createSamplingSummary_(this.selection,this.viewOption);const total=samplingData.values[0].total;const columns=[this.createPercentColumn_('Total',total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',total),this.createSamplesColumn_('Self'),{title:'Function Name',value(row){if(row.deoptReason!==undefined){const spanEl=tr.ui.b.createSpan({italic:true,color:'#F44336',tooltip:row.deoptReason});spanEl.innerText=row.functionName;return spanEl;}
+return row.functionName;},width:'150px',cmp:(a,b)=>a.functionName.localeCompare(b.functionName),showExpandButtons:true},{title:'Location',value(row){return row.url;},width:'250px',cmp:(a,b)=>a.url.localeCompare(b.url),}];this.processSampleRows_(samplingData.subRows);this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_(title,samplingDataTotal){const field=title.toLowerCase();return{title:title+' percent',value(row){return tr.v.ui.createScalarSpan(row.values[0][field]/samplingDataTotal,{customContextRange:tr.b.math.Range.PERCENT_RANGE,unit:tr.b.Unit.byName.normalizedPercentage,context:{minimumFractionDigits:2,maximumFractionDigits:2},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};},createSamplesColumn_(title){const field=title.toLowerCase();return{title:title+' samples',value(row){return tr.v.ui.createScalarSpan(row.values[0][field],{unit:tr.b.Unit.byName.unitlessNumber,context:{maximumFractionDigits:0},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-sample-sub-view',tr.model.Sample,{multi:true,title:'Samples',});})();'use strict';Polymer({is:'tr-ui-a-multi-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){const ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);const ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).appendChild(ltv);this.requiresTallView_=true;return;}}
+Polymer.dom(this.$.content).textContent='';const mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;Polymer.dom(this.$.content).appendChild(mesv);const relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){Polymer.dom(this.$.content).appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)return false;const childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW'){return false;}
+return true;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-slice-sub-view',tr.model.ThreadSlice,{multi:true,title:'Slices',});'use strict';Polymer({is:'tr-ui-a-multi-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:true,title:'Thread Timeslices',});'use strict';Polymer({is:'tr-ui-a-user-expectation-related-samples-table',ready(){this.samples_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedSamples(){return(this.samples_&&this.samples_.length>0);},set selection(eventSet){this.samples_=[];const samples=new tr.model.EventSet;eventSet.forEach(function(ue){samples.addEventSet(ue.associatedSamples);}.bind(this));if(samples.length>0){this.samples_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected user expectation(s).',selection:samples});}
+this.updateContents_();},updateContents_(){const table=this.$.table;if(this.samples_&&this.samples_.length>0){table.tableRows=this.samples_.slice();}else{table.tableRows=[];}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-interaction-record-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:true,title:'User Expectations',});'use strict';Polymer({is:'tr-ui-a-single-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_(event){const rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-async-slice-sub-view',tr.model.AsyncSlice,{multi:false,title:'Async Slice',});'use strict';Polymer({is:'tr-ui-a-single-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const cpuSlice=tr.b.getOnlyElement(selection);if(!(cpuSlice instanceof tr.model.CpuSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=cpuSlice.threadThatWasRunning;const root=Polymer.dom(this.root);if(thread){Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;}else{root.querySelector('#process-name').parentElement.style.display='none';Polymer.dom(root.querySelector('#thread-name')).textContent=cpuSlice.title;}
+root.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.b.Unit.byName.timeDurationInMs);const runningThreadEl=root.querySelector('#running-thread');const timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{const threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);Polymer.dom(threadLink).textContent='Click to select';runningThreadEl.parentElement.style.display='';Polymer.dom(runningThreadEl).textContent='';Polymer.dom(runningThreadEl).appendChild(threadLink);}
+root.querySelector('#args').object=cpuSlice.args;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-cpu-slice-sub-view',tr.model.CpuSlice,{multi:false,title:'CPU Slice',});'use strict';function createAnalysisLinkTo(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.userFriendlyName);return linkEl;}
+Polymer({is:'tr-ui-a-single-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],listeners:{'singleEventSubView.customize-rows':'onCustomizeRows_'},set selection(selection){this.currentSelection_=selection;this.$.singleEventSubView.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},onCustomizeRows_(e){const event=tr.b.getOnlyElement(this.currentSelection_);const rows=e.rows;rows.unshift({name:'ID',value:event.id});rows.push({name:'From',value:createAnalysisLinkTo(event.startSlice)});rows.push({name:'To',value:createAnalysisLinkTo(event.endSlice)});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-flow-event-sub-view',tr.model.FlowEvent,{multi:false,title:'Flow Event',});'use strict';Polymer({is:'tr-ui-a-single-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.$.asv.selection=tr.b.getOnlyElement(selection).associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-frame-sub-view',tr.model.Frame,{multi:false,title:'Frame',});'use strict';Polymer({is:'tr-ui-a-single-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);Polymer.dom(this.$.content).appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-instant-event-sub-view',tr.model.InstantEvent,{multi:false,title:'Instant Event',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-instant-event-sub-view',tr.model.InstantEvent,{multi:true,title:'Instant Events',});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView,};});'use strict';Polymer({is:'tr-ui-a-single-object-instance-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0){return false;}
+if(this.$.content.children[0]instanceof
+tr.ui.analysis.ObjectInstanceView){return this.$.content.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const instance=tr.b.getOnlyElement(selection);if(!(instance instanceof tr.model.ObjectInstance)){throw new Error('Only supports object instances');}
+Polymer.dom(this.$.content).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this.$.content).appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_(instance){let html='';html+='<div class="title">'+
+instance.typeName+' '+
+instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
+instance.creationTs+'</td></tr>\n';if(instance.deletionTs!==Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
+instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';Polymer.dom(this.$.content).innerHTML=html;const snapshotsEl=Polymer.dom(this.$.content).querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){const snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);Polymer.dom(snapshotsEl).appendChild(snapshotLink);});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-instance-sub-view',tr.model.ObjectInstance,{multi:false,title:'Object Instance',});'use strict';Polymer({is:'tr-ui-a-single-object-snapshot-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0){return false;}
+if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView){return this.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const snapshot=tr.b.getOnlyElement(selection);if(!(snapshot instanceof tr.model.ObjectSnapshot)){throw new Error('Only supports object instances');}
+Polymer.dom(this).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this).appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_(snapshot){const instance=snapshot.objectInstance;Polymer.dom(this).textContent='';const titleEl=document.createElement('div');Polymer.dom(titleEl).classList.add('title');Polymer.dom(titleEl).appendChild(document.createTextNode('Snapshot of '));Polymer.dom(this).appendChild(titleEl);const instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);Polymer.dom(titleEl).appendChild(instanceLinkEl);Polymer.dom(titleEl).appendChild(document.createTextNode(' @ '));Polymer.dom(titleEl).appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument,inline:true,}));const tableEl=document.createElement('table');Polymer.dom(this).appendChild(tableEl);const rowEl=document.createElement('tr');Polymer.dom(tableEl).appendChild(rowEl);const labelEl=document.createElement('td');Polymer.dom(labelEl).textContent='args:';Polymer.dom(rowEl).appendChild(labelEl);const argsEl=document.createElement('td');argsEl.id='args';Polymer.dom(rowEl).appendChild(argsEl);const objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;Polymer.dom(argsEl).appendChild(objectViewEl);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-snapshot-sub-view',tr.model.ObjectSnapshot,{multi:false,title:'Object Snapshot',});'use strict';Polymer({is:'tr-ui-a-power-sample-table',ready(){this.$.table.tableColumns=[{title:'Time',width:'100px',value(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value(row){return tr.v.ui.createScalarSpan(row.powerInW,{unit:tr.b.Unit.byName.powerInWatts});}}];this.sample=undefined;},get sample(){return this.sample_;},set sample(sample){this.sample_=sample;this.updateContents_();},updateContents_(){if(this.sample===undefined){this.$.table.tableRows=[];}else{this.$.table.tableRows=[this.sample];}
+this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-single-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){if(this.selection.length!==1){throw new Error('Cannot pass multiple samples to sample table.');}
+this.$.samplesTable.sample=tr.b.getOnlyElement(this.selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-power-sample-sub-view',tr.model.PowerSample,{multi:false,title:'Power Sample',});'use strict';Polymer({is:'tr-ui-a-single-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.tableColumns=[{title:'',value:row=>row.title,width:'100px'},{title:'',value:row=>row.value,width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+const sample=tr.b.getOnlyElement(this.currentSelection_);const table=this.$.content;const rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});const callStackTableEl=document.createElement('tr-ui-b-table');callStackTableEl.tableRows=sample.getNodesAsArray().reverse();callStackTableEl.tableColumns=[{title:'function name',value:row=>row.functionName||'(anonymous function)'},{title:'location',value:row=>row.url}];callStackTableEl.rebuild();rows.push({title:'Call stack',value:callStackTableEl});table.tableRows=rows;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-sample-sub-view',tr.model.Sample,{multi:false,title:'Sample',});'use strict';Polymer({is:'tr-ui-a-single-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-slice-sub-view',tr.model.ThreadSlice,{multi:false,title:'Slice',});'use strict';Polymer({is:'tr-ui-a-single-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const timeSlice=tr.b.getOnlyElement(selection);if(!(timeSlice instanceof tr.model.ThreadTimeSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=timeSlice.thread;const root=Polymer.dom(this.root);Polymer.dom(root.querySelector('#state')).textContent=timeSlice.title;const stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];root.querySelector('#state').style.backgroundColor=stateColor;Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;root.querySelector('#start').setValueAndUnit(timeSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.b.Unit.byName.timeDurationInMs);const onCpuEl=root.querySelector('#on-cpu');Polymer.dom(onCpuEl).textContent='';const runningInsteadEl=root.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());Polymer.dom(cpuLink).textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;Polymer.dom(onCpuEl).appendChild(cpuLink);}else{Polymer.dom(onCpuEl.parentElement).removeChild(onCpuEl);const cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread){Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.thread.userFriendlyName;}else{Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.title;}
+Polymer.dom(runningInsteadEl).appendChild(cpuLink);}else{Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);}}
+const argsEl=root.querySelector('#args');if(Object.keys(timeSlice.args).length>0){const argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';Polymer.dom(argsEl).textContent='';Polymer.dom(argsEl).appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:false,title:'Thread Timeslice',});'use strict';Polymer({is:'tr-ui-a-single-user-expectation-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.$.realView.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;},onCustomizeRows_(event){const ue=tr.b.getOnlyElement(this.selection);if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.b.Unit.byName.timeDurationInMs})});}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:false,title:'User Expectation',});'use strict';(function(){const EventRegistry=tr.model.EventRegistry;function getTabStripLabel(numEvents){if(numEvents===0){return'Nothing selected. Tap stuff.';}else if(numEvents===1){return'1 item selected.';}
+return numEvents+' items selected.';}
+function createSubView(subViewTypeInfo,selection){let tagName;if(selection.length===1){tagName=subViewTypeInfo.singleTagName;}else{tagName=subViewTypeInfo.multiTagName;}
+if(tagName===undefined){throw new Error('No view registered for '+
+subViewTypeInfo.eventConstructor.name);}
+const subView=document.createElement(tagName);let title;if(selection.length===1){title=subViewTypeInfo.singleTitle;}else{title=subViewTypeInfo.multiTitle;}
+title+=' ('+selection.length+')';subView.tabLabel=title;subView.selection=selection;return subView;}
+Polymer({is:'tr-ui-a-analysis-view',ready(){this.brushingStateController_=undefined;this.lastSelection_=undefined;this.tabView_=document.createElement('tr-ui-b-tab-view');this.tabView_.addEventListener('selected-tab-change',this.onSelectedSubViewChanged_.bind(this));Polymer.dom(this).appendChild(this.tabView_);},set tallMode(value){Polymer.dom(this).classList.toggle('tall-mode',value);},get tallMode(){return Polymer.dom(this).classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_.bind(this));}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_.bind(this));}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_(e){if(this.lastSelection_&&this.selection.equals(this.lastSelection_)){return;}
+this.lastSelection_=this.selection;this.tallMode=false;this.tabView_.label=getTabStripLabel(this.selection.length);const eventsByBaseTypeName=this.selection.getEventsOrganizedByBaseType(true);const ASV=tr.ui.analysis.AnalysisSubView;const eventsByTagName=ASV.getEventsOrganizedByTypeInfo(this.selection);const newSubViews=[];eventsByTagName.forEach(function(events,typeInfo){newSubViews.push(createSubView(typeInfo,events));});this.tabView_.resetSubViews(newSubViews);},onSelectedSubViewChanged_(){const selectedSubView=this.tabView_.selectedSubView;if(!selectedSubView){this.tallMode=false;this.maybeChangeRelatedEvents_(undefined);return;}
+this.tallMode=selectedSubView.requiresTallView;this.maybeChangeRelatedEvents_(selectedSubView.relatedEventsToHighlight);},maybeChangeRelatedEvents_(events){if(this.brushingStateController){this.brushingStateController.changeAnalysisViewRelatedEvents(events);}}});})();'use strict';Polymer({is:'tr-ui-b-dropdown',ready(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_(e){const or=this.$.outer.getBoundingClientRect();let inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)return;e.preventDefault();this.toggle_();},toggle_(){if(!this.isOpen){this.show();}else{this.close();}},show(){if(this.isOpen)return;Polymer.dom(this.$.outer).classList.add('open');const ddr=this.$.outer.getBoundingClientRect();const rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();const ddw=this.$.outer.getBoundingClientRect().width;const w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_(e){if(!this.isOpen)return;if(e.srcElement!==this.$.dialog)return;e.preventDefault();this.close();},onDialogCancel_(e){e.preventDefault();this.close();},close(){if(!this.isOpen)return;this.$.dialog.close();Polymer.dom(this.$.outer).classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){const FaviconsByHue={blue:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAlrklEQVR4Ae2dCXwdVb3H5265yc3SpEk3ukEXCqVUBLT4Wm19oFKtaN0fKijy9CMguPBarIJsIiA8qsjTh7SllAoFeVBaEARkLV1ooXtL0yRdkqZp9u3uy/v/5uY/OZm75y659+acdnLOnP385zv/+58zZ2YMinTplIAhzsoDceaT2RKUQLwHIMFqh0V2ll0kn4XA6byv9/Vw834kX19e7keRQCzhRyk6bJJYRvD1YTXuhRdeqDj77LPPtNls400mU7HRaCzFFggEVJ/iSqhsicFgKIXUKL6bvB6fz9fj9/u7Kb4bPjaK67Xb7Q0HDhw49IUvfKEd2XUb7WpxHIYvXRgJ8AELkzRso1gmKrwkBfjG7373u5Zly5ZNKS8vn2G1Ws80m83YphPI0wnQUemQFp0IzQR9tdfrxXbI5XId6ujo+PCuu+6qXbNmjYfa9NMmngDoBmt+hIe944M53AUhwqwCvXTp0qJrr732opKSkk8XFhZ+imC+gIAryAZB0QnlJuB3OJ3Ot3p6el5/6KGHttxzzz0O6pse+GEP+3AGnKE2EhgG0tAFt99++4WkoT9tsVgW0DaH4guzAeg4+uD0eDxbaXuDNPzrt9xyy3bS8G4qB8BF6OOoKr+yDDfAB0B91VVXFf72t7+9lLT05QUFBZfQoYWtnA+ux+12v0ra/W+/+tWvXlq5cqWTBjUsYR8OgDPU8KGtjR9++OHHx4wZ8+2ioqKv0X4lbfnsWh0Ox9+bmprWzpgxYxsNFBpd1Op5bcbkM+AMtgr11q1bTz/zzDP/gy4Qv02zGtPzmehIY6MZmmq6UF176NChJ+bMmXOkD3QR9khFczY+HwEXwTbV1NTMI229FCYIXSTm43gTho8uUgMwYUir3zN16tR3qAIfbXkJej4dcIxF1dbkm44ePfqZqqqqpTT7MZf2pYsgAZqN2dTS0nLP5MmTX6EsDDrDHqFU7kTnA+Aa2BMmTDBv2bLliyNHjlxCZsgFuXMYhr6nZL7saGtru/eiiy7aUF9f76UeAfKcBz2XAUffVbgJbAuB/Y3KysoldONl5tDjkrs9oBtL+1tbWwH6UwS6/mZSzg0sVwHXTJG9e/deOGXKlOWksS/MOelncYdJo2+vra396axZs7ZTN0XTJYt7Hdq1XANc1dg0DNOqVatGLl68+DZa/3E1XTwCeOn6JLCly6ncU9+mNLnBZRLOYPAHHI5H2l5/8TdHbl3SRjUx6DkztZgrgKOfDLf5xIkT36moqLiLzJG0rAFJAomsKDp1W51S74IZnSIX8DcrXV3LlK/Oe5xqZPsckGc96LkAOPpowrZ79+5ZNK31BzkzQtKI4qxvV0dJTSLJ592kHKu7QfnPxXupFmhzbFkNeTb/tGsae/bs2Va6wr/lrLPO2izhTgLQZIuaaMp1yvTNyvNbb1HomFB1ZtrAUNYqymztGMNt2rhx44T58+evohs1n0r2+AyX8mnT4KIAvZ63lA82f1/55TX1FJ21tnk2As4zJObq6urP0BTgCmlri2TFDmcEcHQDtnlz4w+Uyz+Hm0Rsm2PuPGtcNpkomtZesGBBYXNz8210d+05CXfWsBLaEQNd5I+e8JyyYettCh0zyoBrpawyWbJFg2twv/jiixPnzZu3mhZFzQ2VqIyJRwIZ0+BiZzyeTcqebVcqS350nKKzxmTJBsDRB3WWZN++fXPpps060tpVouxkODEJDAng6GIg0KI0Hv+mcsXnN9FeVsyyDLWJwnCbadXfomnTpm2UcCcGc1blNhiqlNMmblT+9soi6hdmWKC4hlSJDiXgaBsCsNDKvysnTpz4JIWLaJMupyVgKFLGjHtSefrNK2kYFtpwjIeMs6FqWIOb7kr+Yty4cX+m2+0446XLBwkESHuPrPqz8uymX9BwhhTyoQBchZseQiigdcj30grAO+SDCPlAtW4MeLikdMQdyvqt9yp0rCl1SDR5pgFX4V64cGERvdhmRWlp6XU6scjdfJNAcfF1ysqNK5Q5C2F+ZhzyTF4AqHCPGjXKSjdwHqUHfr+ab8cyW8YzZLMo0QTgcj2jfO/S7ynNzS7KxtOI0UqkJC1TGlyFm3pccPDgwfsk3Ck5drlVidX6VWXFxvvAAG0Z0+SZAJzhtjQ2Ni6ld5D8KLeOjOxtyiRgK/6R8uy7S6m+jF14phtwmEBow3L8+PGr6FnJm1MmLFlRbkqgtOxm5am3rgITtIGNtJrJ6QQcHcdPkYUuKL9MsybLKSydlICijKxcrjz+0pdJFKzJ0wZ5ugBnuM27du2aT7ffV9JUIGCXTkqAJEAsjJ2wQlm1fj7tpPWOZzoAB9yo1/zSSy/NoLdJraMwFsdLJyUgSqBQGX/GOuX+FTMoEpCDmZRr8nQBbqIHgovnzp27mtaWlImjkmEpAU0CYGPmR1crF19cTHH4hU854KmuECcMOmo9derUAyNGjLiawtJlWAJZOQ8eTQb27keUyz7xM8qS8jnyVGpwNk0s+/fv/4qEO9oRlWkDJGArvVpZ89JXKC7lMyupApzhNm/YsGH6GWec8eCAAcgdKYFYEhhz2oPK3X+ZTtlSao+nEnDzxWRL0eNmj0q7O9bRlOkhEoA9ft6cR5WPq/Y4IE+J+ZyKSjS7m56jvK+srEzeqQw5epmNyDkbXBRPT8//Kl++6EaKSok9nqwG10yTHTt2fJpWB0q4xYMlw4lLoJhu5z/y3KepYEpMlWQBV7U3mSXFNN99H71YPfEByRJSAqIEwND4yfcpFyzgqcOkGE2mMGtvy2OPPXY9vZjnTLGfMiwlMGgJWCxnKktv/QmVT3pWZbCAM9zmxx9//IzRo0fj0STppARSJ4HykTcqN//3GVRhUqZKMoCrC6no6Zy7yTSxpW5ksiYpAZKA0WhTPj73dxRKakHWYABn7W3Zs2cPvjH5eXlApATSIoGi4i8oK56/tA9ysAr2EnKDARxlzJdddlkJ3dC5N6HWZGYpgUQlMH7SvbRWpYSKsamSUA2JAs7a2/ynP/3pOvrc9eSEWpOZpQQSlYDZPFn54a/xcDoDnpAWTxRw5DfRJ7DL6HUPP060rzK/lMCgJFA+8sfKZd/CqlRc9yXEbCKZWXtbli1b9gN6EX3loDorC0kJJCoBk6lS+ebVP6BiCU8bJgI48ppxU2fs2LHXJNpHmV9KICkJVFZdo3zsY7j5w6ZKXNXFCzhrb/PDDz/8HbK9x8ZVu8wkJZAqCZjNY5Wf3vkdqo4Bj8sWjxdw5DPRt3KKTjvtNNxhkk5KIPMSqBz1E2Xq7ITekBUP4Ky9LevWrfsGae9JmR+ZbFFKgCRgLpik3HL3NygUty0eD+Cq9h4/fnwBbTdIQUsJDKkERo+9QSkr47ubMfmNlQHaG5v56aef/ndaUDVtSAcnG5cSMFumKXc/fDGYpI35jCiXeADH3KOZ7lp+Sy6HjShHmZApCWA57dgJ3wKTtIFNQB7RxQIc6abLL7+cniEesTBiLTJBSiCTEiguWah8/isjqEkAHpXhaIk4M5BuXrp06ZfoOUtcvUonJTD0EjCaipSvff9L1JGYU4bRAEeaCjh9P+fr0jwZ+uMqe9AnAZgpo0Z/nfYY8IgcR0qA9sZmeuCBBybZbLZ/66taelIC2SEBKzF5zTJMWbMdDl5DXDTAVe29aNGib5D2jpQvpEIZISWQEQkYicm5C0QtnjDg6uwJPY72tYx0WDYiJZCoBMorGXDW4iE1hNPMOBMQb1qzZs0MmvueHlJKRmS1BCZYYZoOA2exTFd+dT/eTsuzKSFaPJwkNMDPO++8+fLiMvdA+Z8JJcqPN+9RGnocoZ0PBELjFF2cbjdYIEykvq4wWehd4APb05dBari4gaWCe/p8AT+uFOdT4j7aoJTB7oAGowFurqqqmicBV5QPmgLKX3b7lVbHANmRLLPVVSjnGT6hzFRa44dHHEqIHhQThXC8+YQiqQ66K9rnvakoD1O9DPiAJvSAo8vYjMXFxWZ6U9VFA3IP052fv+5VGntzBW4+SCYl4KtQ/L3tpCBJ0+WpC/hKLgKrvb29DDj41Q4WIvUOcaZHH310lslkGqlPHI77uQd38CgZTBbSVBVKXk+CGYwjS758/ywwS1sIz/oI1uCmmTNnflKaJ7l/OmuQG3migQ9xnvg0W2gaN/2TfYDzoLQDFw5wVYOT/T1XAq7JKacDKuS2csVg1B/unB6W2nkwaiiumEs7rMEBueZEG5zpN9Gt+QKyv+douWQg5yXAkPvtHYO78MxiCZisJXNsVRML7C3HndRN5li1w/WnNPaNDz744Ll0ZpRm8Zhk1wYhAYacjPJBlM7eIgHFUFryxZvPpR6q/Io9DavBJ0yYcJY0T0Qx5U84CDnNrtjb82dQZHqZysefRQPaRltEDc4JRlr7PS1/Ri9HopeAwWRWjLYKQiF/NLnBWgpmocGZY3XYoomCBOybaPXgNKnBVfnk7R8V8qLyvIAcrBoLiqaCXdoYcvXYMeB8KmPfSIBPUVPln7yWQD/kjEEOD7fABsBVfvtGoTIdYoOPHDnSXFhYODmHhyq7noAEgpCPUPyOTiql3QBMoIbsyGo0F04uInYdbW3RTZRbb711AnXZmh3dlr3IhAQYcpooz0RzaWmDTk1r0YLrwS4GwRaJuoMGmXrjOeecI5fHQiLDzKmQF9ILXFXIGYfc8q2jZ4JdBlyFnE9ZHolx1KhR8gJzmMHNw9Ugz8U7nrijWToyZCZFtMEBu7GoqGgiD1j6w08CKuTWUsXv6s65O56GApVdlWM+cnoNbqB3D+JzEdINYwkw5DlnkxvNYJetEdVEETU4Ioy0RLZEzoEPY7r7hh6EvIQ0eQ/FZP/sCpilPgNwKG0VbgyFdzTqCXC8ZFw6KQEAoxgLS3NoPbkR7GosIyxqcBxSgwQcYpCOJWDAOnIrKUbS5AH9M5GcKUt8OiEZcK1HbIMjQiVfAq7JRgb6JADIDQR5tpuuAaMGuGaisAbXIiTgkutwEujX5L2UnJ02uSEIOHdfZVpqcBaH9GNKIKjJQ6yAmOUylYHsa+6cprBZg3MfpA3OkpB+WAkENXmxEnDbs2+e3KABrvU9RINTih56LbMMSAlAAqomL7BRQFOU2SGYgMouOqV1jGHWIrxer50+8iofV8uOQ5a1vVA1OUEecOPtWdlhkxsUH/2saE5lmufBtVifz4erCOmkBGJKIKjJ8V0ETT/GLJPODAG/X8+uOg+O0087BaHB09kJWXd+SSCoyYuUgIceaB/qeXL/AA2uci3a4JB8QGrw/AIwE6NRNbmlcMht8oBftT40ZY2xsw2OsJogAYcopEtUAqomt5Am9w6dJg8ENPNagzysBs/2W7KJCl/mz4wE8OYsg3loNLnKbNAG1+DGqFmDI1LdpA2eGRjytRX19XAEecDr6kMqcyM1BNTrR41ltCxqcAYc6yOlkxIYtASCmhyP9WZ2doVmUXhtL1hWHWtw3lccDkcb1H22L6zROiwDWSmBoCa39mnyDHSRmPV7nG36lliDs1r3t7e31+kzyX0pgcFIQNPkGbrj6be3gV287Z95Vk0U7MCpkdXV1bXyIjMoEPk3eQmokJsKglOIAD1tm6J4Wo7UMsd9PQ+wBse+CvgzzzwjAe+TjvRSIwGGnB4qS02F4WohE8W58zk94CGzKP6XX3652+VyNdN6lFHh6pFxUgKDkQAgDygWxeDzDKZ47DJeV3PvvtfpVQChJgoKs80C+8Xf09NzRJopEIt0qZQAIFfou0GpXoUIVv0uxxHqq8ov+cxzyDShmsFut9elcmCyLikBloAKuZEm71Jsi/vdKrMi4GqTbIMz8cjgw0yK1OB8SKSfagkMgDwVlZMGDzg6oJR9tIFh5lmzwdEMR/pPnjxZiwjppATSJQHVJg/QRaffm3wT9Gvg624GswPgRsXhNLh//fr1u2nRFYCXTkogbRJQbybCXEl2diXgCzh2bthNFQHwAZAz4BgEgEaijz4C29zZ2VkjzRSIRbp0SiAIOT7MgCnExDeyThS/s7uma+vaZqpANFHUbusBZ8i9ra2tWyXgqozknzRLQIMcF56JOiLc19O6lYrB1hmgvVGVCDj2VQ1Ovq+mpmaLBBwikS4TElAhx7vJE55dIWhb6rZQH6G9WYNrXRYBh/ZmDe5buXLlVj85LacMSAmkWQIa5Im0Q4x2bXkUGpzhZo7VWsIBrp4JGzZsaCc7/KDU4olIW+ZNVgL9kMe2x4P2d+dB+86X8NFP1uARAUffWIPDnvHSdOE2CTjEIl0mJRCEPA57nAj3dzXj468qr+SzDa51V9TgiGTAcTZ4yQ7fLAHXZCUDGZSABnlUm5wgba3dDFZpE00Uraf6Bx5YveNM8C5fvnzbJZdc4iwuLqYH7Yavq+ytURq70rRIKIvEGlmZAYswDjZCRBchLUJ0ULeGqYzaQL8AfEj/PA5nz8u/Zw3O2ntAC+EAR0bVnnn33Xe7Gxsb35gyZcqlxhR9mGj/oU7liWfrlPZOd5jRZGfUbK9bmUnPGIYIeEB3B8i1PyUKBHTo+vPFEYrcfpR6orYfR6NZmiUQ8Cs9XU1vbDiyEysI2f5myLVe6wFHAqSlanDyPTt37nz+9NNPTxngv/3DHqW5lV4tkGPO67ErPi+9pgw/mYAGfjyO8zJo+vL6dH2dmc6vb1/fP31/9Pn1+7HK69P15fXt9eUP+LxKR/OB5yk7flrFOfABNehtcCSKgHuvu+66t2n5bGtk7TGgvpg7uQg3BmW22BSTGa8pIwehx+s4L3wxzOXFOM4j+sjHecSwmEcMi3nEsJhHDIt5ENY75IXjMhxWI+P4E6u8Pp3bYV/fHsWDRb/f1Vq3b9XblBzxAhNFowEOte+hlYWO+vr6f6QKcDSaq06F3FQYdeUEow9fDGfLmMU+ieFI/RPziOFU5Y9UT/T4gOJ2tP/D7e7Bmz+hwcNeYKKOcIAjHiaKZqa8+uqr6+l9KYgf9g6QG/sgxwHXbxAQgyCG9fmGal/skxiO1B8xjxhOVf5I9USLV8j+7mjd/Rz1RzRPwGuIiwQ4zBScFaDas3Tp0r0dHR2HpRYPyo8hD+7Jv5mUABj0eeyHjx58Yh+1y4CDVTAb4qIBzpCjEjfNiW+Qd+775dcPeTRdI9NCf+OSlQl98M3RvAFM0sbmCVhNCHAcSah8TYuvXr16PT2MjAql65OAapPjXXzRnP4iCnk5Llw5ToMvhsPlzYU4cQxiOFLfxTxiuC+/3+/xNB9/cz3tito7rHmCIpE0ONJwRrAd7l61alXjkSNHXpBaHKLpd5hZMfELJ3FA9Buy8oESw/p8vC/mEcOcnmu+OAYxHGkcYh4xTPlx38DtaHnhZP3rjZQEDR5xehBF4eIFXDVT1q5d+whp8YhnS7DK4fdXhdyEd/FJl04J+ANef3PDpkeoDTZPkgIcfR2gxe+7776aY8eO/VNq8dDD2A95sjamLE8/eSTggRsuLj2Otn821D5fQ4lxaW8cpWgaHOnQ1pqZQmHXU0899VePxxPWoEeB4ewYchwadhzmw4V4jhPDnJ6oL9YhhuOtRywjhuMtr88n1iGGOZ8YJ4Y5PZKv+H2BthOb/0pl8F5mEfCoFkUswNEHVICLTdVMufPOOw+QFn9TanGIJtTBHjeSucIHCjkQZsfhSOmcL14/2fqSLa/vZ6z6YqXr68M+1p24nK1vHq3++wHaZfMETEaFG2XjARzaWgOcwq4XX3zxYdLiKC9dGAkw5Pqf2czso0OMkRhGXG5u9N5vpb3p/YdpAKy9AR+YjGlJxAs4a3GcPa4lS5bsOnHixGapxUkaEVwQcnqrasYdw80wowMcl/HOJN0gtLfb1bH5yMHHd1FlDDhr75QAjk6yFsdVKyB3bty48UE5owLRRHYa5JgSY8dhniZDPMeJYU5P1BfrEMOR6hHzIBzLcV8j1aePR31cRgxzPjFODPel+xWvv6N5x4OUhCWoYA8MxqW9KV9cJgryAXBocQbcdeONN+6kd4k/J9eoQDyRnQq5se+Fk3yg2UcxDvcdULUmjotcbeQULhtvffr8XC6Sj5a5TORe9KdwXq5PXz5KOn0WUHH2nnyudt/qnVSMtXfMqcH+xuMHHGVYi6sXm2jwpptuWk4PJrfLNSqiSEPDGuShSTImggTUNSdee/uxA2uXUxaGO27bm6uNxwbnvKzF8fOABp2vvfZa89atW/8oLzhZRJF9zVyJnEWmCBKgb14qPZ01f2xv3o03VsE8AXNx295cVSKAo4yoxVXIFy9e/Aw91rZLXnCySCP7Jpo+NNLnPMQvHXAYfjz/UDuXEcNcVowTw5yeal9sQwxHakfMI4bF/HhiyuPq2LV/293PUB6GO2HtjfoHA7g4o4LGnWvWrLnL6XT6pKkCkUZ3gNxAL4HnA4rcCMfrOG+k8rHS420n3nyJthcrPxgK+D2+5oa37qI+qHyRj4vLhLU3xpAo4CjDgOOMUrX4HXfcse/AgQPr6I20SJcuhgQYcvVijS++pN938RpQHD0n1h378Cms99Zrb7CXkBsM4GiAIVenDGnfccMNNzzU0tLSKE2V+OSvmiuYXZFOkwDmvD2e7saa/X99iCLxOBoAF7W3ljfewGABZ1ucpw2d7733XusTTzxxE33+xCNNlfjED3vcqELON2WGr0+WCS03cXtaTmy6qbutppUkyHAnNO+tl/xgAUc9DLmmxWnacAeB/hDdANK3I/cjSCAIebi3d0QokKfRZHcrvZ01D9XtW72DhqjX3mBtUC5ZwGGqaFqcws5LL7109dGjR9+WN4DiPx7DHXLc0HE5Wt7es/m21WCob4PiTOimTjiJJwM46gPg2PiCE2ee/Wc/+9lvyB5vkvY4SSNO12+uxFkgT7LB7vZ6uptq9678DQ3JThsYggkAppgvCg7OJQs4WkUnMH2CMw6dc9ANoJNPPvnkL8ke90p7nCQSpzPS9CFscryHbzhsEEvA7/a2NLzzy46WXSdpV+WH/KQuLFEvu1QAzrY4mypqJ+lVE9u3bdv2Z9jjEnIWd2wfkBsM+W+T9813093K6j/X7l+9nSQjwp3UhaUo5VQAjvoY8gGmysKFC1fSgqxX3G6ckNLFKwEVcu3rY/k5swK729Hb9Mqed29fSXLRmyawCAZ9YSnKOVWAo06GHDTjQgGdti9atOjXdNH5noScpJGAU00VI74+ln+OXv2gOJ0t7x3cduevaXQqJ+TztGDK4IbkUg24aI+rkNNXIrquuOKKG+kBiYNyURZEHr/LR8j99OFXt6v94KH377/R4WjtImkAcBFuMJQS7Q1Jp0NFoHNiBw0Eube2tnbT/PnzFzz3UtMIA76mJV1cEjAYcIhInLgTkuMOZonH3XW8dvdff9zZur+JhtNLGwMO8zal2hviSgfgqBduAOhki7u6u7u3NHWO+yxNidkk5EEhxfM3CHmfSHN0zQq98Fjxunta6w+v+9GphneO0Wj0cKdUc7Nc0wW4qG608AcffNBrMlvfLx0x5XMGo7lAQs6HIbbfLytNnLELZUkOrO2mF2b2nDz64rX1hzccpG7p4YbmBuApd+kCHB3lI8G+2vnOlr0dBYVV+4tKxl1MswWW/gOX8rHlXYUsq+C8ChaeZv8/vOqYvo5hb2l48+d1+9fiNrwId8rmuyMd7HQCLrYJyDXQ20/tOGUxF+6wlU1aYDQWFPGBEwvIcHgJ9MtKE2f4jFkQq9rcnu72xrp//OTIgccx181wY8477XBDBJkGXAO9o2VPm+JzbioZMXWewVRQ2n/g0C3poklgoKyyc57cTxeUXnfHCVrXfU1D7fr9NJ4e2gA4w530OpNoMuK0TAGO9ljlaJB3tVd3u1yNb5ZVzPy40Wyt7L+Y4u5JP5IE+iFnsUbKmfl4zHN7nG3VdXtWXNvU8GYd9QBgZxxujDyTgKM9OAZc9e1dDY6ejoOvl1fNnm0yFY1TaApR/QhoMK/8G0UCGuQGEmUWKHK83jhA89z0gvoPDu1cfn1b864T1H29WZIRzc1iyzTgA+CmTqj7Lkeru6156xsVoy+cQk+fn44DJyHnQxTd1yBXRRk9bzpTsSrQ7/MoLvvJN/a/d9uSno5jLdQew40bOVghmFG4Md5MA4424UJA97rtvub6f71VPupcq9lSNttgNBLj8oZQUFzR/w6UU+ZVOeD2eV2B3u7ax/a9e/PvXI7OTuqxCDcuKDMON6Q2VICjbYacJ/jpHYte/8mjr35gtVUdLCwaPYfmyunDlFKbQ1ixXBByiDRzTl0RGPBiPXd7S8Pbyw68d+/TdAz5YlK8QzkkcEMSQwk42mfI4Wugt53c3uB0nHyttHz6THo4dywOnjRZIK7ojiHPxOw4lg4EYJI4mnfW7V95ff3h9bupd9DarLlhkohTgZk9+/pElS2AA27eVOjt3fW9p4699kr5qFkmc0HZR6TJ0nfEYngDzZUYmQeZrN6ZhEnSeXj1nk2/vr2nsw5vn4LGZrj1i6cG2VLyxYYacIyAz2zW4hro9HPnO3nstZ2FhZX7Cm1j5tCDAEWkyqU2j3HctV+7FJvjWE+CWRKvt6utpeGtX+7f/vv/6zNJGG7McfPFZNpuv8cY/oDkbAAcHRIhF0FXw21N2084HfWv2UonjaHPhEwJaikJ+oAjqdvRINfFD2ZXfSILF5I+Fz2kUP/akT0rlhyv2bCX6mKNDcD1N3CgqIbc4RzPJof+YOoEJx7eioNPl+FDlHSxqdgQnj77h5+oGPeJXxQUlE3Cg7qZ+EmmdnPWYYYjGRec/nMrbnfnsbaT2+6v2f3wZqoPJghDzVOAvNwVDbLCSqbplJTNNsAxKP5hBeR4OBGfSQDkDHpRYWFFyYzzf/Gd4oqpV5JGt+IZxlRqLGorr1zwmdjEmOMZEp/X4erpqFld/f4Djzud7ZghgabGBrDZ1sYsCa/lTqwhKphOly0min6MLCT42KAV2Kbzeb1Ob9Pxf+32utteLSqZOJ4++jRJmi16Efbv95/8rDsi++pzFX3mCM1kvXPkw7X/Vbd31eskc3H6D9pbhBvHJ7mfiv7upjSUjRpcHCD6xyYLa3PW6DBbVM0+4/yffKq88iPXmq0jJuOdf/J2vyjC/nBQk/fviyHRzva6u462N+96qHrng29RHtbUrLUx9cc3bljpsEISq8yKcLYDzkIC5Aw6bHNAzva5CrnZbC6c/pHrLykbefYVZmv5NAk6iy66PwBsV8fhrrYDj1Xv+uOr9GYyBpt9ntcWbe2s1NriiHMFcPSZtTlAhzZn0AE4ww7fOuP86z45ovLcKyzWkecEL0RN0kYnwYguaGP78MJLetl8277O1j2Pffj+n96mPAAZG8BmHxobYPMdSYCdtVqb+qa5XAKcO40+49qBQYc2Z42uAk77qj919tUfqxh1wZXWosrz6cEKslxQbPhOLwZNFKz4I7D9broL2fp+e/OO1TW7H3mPBMNgi75ojgBqvpCkYG64XAQckkW/sYlmCzQ6Ty2KoBeccc53Z5eP/uiXrIWjFpjNRTaD+no0FM1/2DWo6cIRb3D1eh12l7P5jY5TH6yv27cGt9cBsQg1wtDWvIl2dk5obeq75nIVcB4AQ86gs+nCoLNmV7V8YcnY4ikzvr3ANuKMz1mLqi4k0E3q+7nVu6OoIn+cOv9NUyJ4+ACfBKG3t263d9a9XPvh2jecPSdxg4a1M4BmyBlqnvaD1s4ZcyTc0ct1wHlMetBhi7CNziYM+6qmrzrtwtHjJi/6rK1k/OfoiblpAJ1hz0XNzpoai6AANTafu/uwvafh5cajG//ZcmL7KZIJA8xwiz7SoK1ZY+c02DQO1eUL4OJ4grZH0E6HRmetDsAZetE3T5q6eHr5mPPmWQurzjcXls8i0K20VFcx4iWYeA9JFpoyA4CmJatYI0JQu7zOjr0uZ8v7HU073zlW82w1dR7aGPAC5nA+0llj8z2HnDNFaAxhXb4BzoMMUtlvo0Ojs1bXA69qdEqHby4sLLeOm7p4Vln5tAsshRXnFxSMOJseirbgAhXPjAZvmrDYgn7/jRRuPjV+EGLUxbzRBSKWqdJ7RnChGKBPftAt9AMeZ/v7XR2HdzTWPLvX6eyAycFQA2jeGHBOY23NGhuNcEMUzA/HRyo/RhM6ChF0aHbRVhe1O0POceybiovH28ZNW/SR4pJJ55oLiieZzLZJJottPFY2BoHHWnWAT1Wr0owkUn18JJYoHv9xUQiQNd/roJfnNPi89mNed++x3p5jexoPb9zV29uAu4qAlDUx+ww2fI6Dz0CL9nWkzlD23HZ6qef2aKL3HmNl84VBZ83OQEfyOR98lDWOnjB3dFnFOZOttjGTLIWlk81m20RaMlBpUEw2Ay2QoRPARg1SffQXF7F9vtpFaOEgxbSrhuhDAV57gBZ+BBSf3e9ztXq99uMeZ/dRl73pWFf7vqOn6jfBhmYoRe0rwhsuLOZlu5p9tTv5/Gc4Ac7HEWMWN4ZW9AE6Q83Q8z6fHKKvQq+r10DmjrmoZEKx1Ta6yGItK7aYy7AiUvF4u+weV1evy37K4eip7yWzAmBCi4obwwyfta7oI8xAM8TYF/NwWbHevNXWNPYQNxwBF4Uggo4wg8q+CL0IuAg350Ec18H1oi0xjH3RMXiI4zBrVwZcDyxDy1DzPudnn+tjX2x32IQhfOmCEmBZMJDwGXQxLMYBbqSxz5AjDg4+b7wPH9DBMXz6fUCKOEAs+gwv+0gTw9jHBsd+cG+Y/uUDMUyHH3XYLBsGNJIvQq3PgwbEesQGGUDRR1i/Mez6eHEf9WJfOp0EWPi6aLkbQQIsLwYZ2aLFiekRqhwAJkPK8KJMtLhIdcr4PgnwwZECSU4Cejnq91G7Po7BFVvWx+n3xbwyHIcE/h9VLWRYHWXC/QAAAABJRU5ErkJggg==',green:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAltklEQVR4Ae2dCXQcxZnHR3NoNDp8SD7kU7bxFXCchBhMYoLNmhCcOBBykGw2gYTkPV6AhGXD2sTZJQcJG3jsgw3hscuCsTEsOAQW1sbY+MAHxpYtHzI+5EOy5UMStnWPZkZzab9/j75WTWt6NKO5Z6r82lVdXV1d9e/ffPq6uro7zyBDIhXIi7DyngjLyWJRKhDpCYiy2pwoztrpxSwCb+d1bayFm9f1Yu3+cj2MAgOJH2bXnNnEGiHWppW8d999d/inPvWp6YWFheNMJlOR0WgswdLT06PElFdM+xbn5eWVQDXK76TI7vP57H6/v5PyOxFjobwuh8Nx4dixYye+9rWvtaK4ZqFVNY/TiGUIoQCfsBCbcjaLNVHgJRUQG3/4wx9ali1bNmXYsGEzrFbrdLPZjGUagTyNAB2ZCLXoh3CJoD/p9XqxnOju7j7R1tZ2/LHHHqtbtWqVh47pp0X8AaAZbPmRzvnAJzPXhRBhVoBeunSp7b777ruuuLj4xoKCghsI5s8TcPnpIBT9oNwE/D6Xy7Xdbrd/8Oyzz+5+/PHHndQ2LfA5D3suA85QGwmMPLLQ+b///e/nkIW+0WKxLKBlLuUXpAPQEbTB5fF4KmnZShb+g0ceeaSKLLyb9gPgIvQRVJVdRXIN8CCo77777oI//vGPt5CV/n5+fv5NdGrhK2dDsLvd7k1k3f/n17/+9frly5e7qFM5CXsuAM5QI4a1Nh4/fvza0aNH/4PNZvs2rZfRks2h2el0/u2TTz55dcaMGXuoo7DoolXPajcmmwFnsBWoKysrJ02fPv3v6QLxH2hUY1o2E63XNxqhOUkXqq+eOHHitblz557pBV2EXW/XjM3PRsBFsE21tbXXk7VeCheELhKzsb9Rw0cXqT1wYciqP37FFVd8SBX4aMlK0LPphKMvirWm2FRfX//lESNGLKXRj3m0LoOOAjQas/Py5cuPV1RUbKQiDDrDrrNX5mRnA+Aq2OPHjzfv3r3766WlpUvIDfl85pyG1LeU3Jd9LS0tT1x33XVrzp8/76UWAfKMBz2TAUfbFbgJbAuBfUdZWdkSuvFyZepxydwW0I2lo83NzQD9rwS69mZSxnUsUwFXXZHDhw/PmTJlytNksedknPpp3GCy6FV1dXX/OGvWrCpqpui6pHGr+zct0wBXLDZ1w/TSSy+V3n777b+j+R8/pYtHAC9DrwIO9xHD5c5XDF5fS0ya0MWo3+nwvrBx47nfLLlvKypj0DNmaDFTAEc7GW5zQ0PDD4YPH/4YuSMJmQMSExVpsPPxhjsMHt/FuLWkp8dwqb3dt2zhnD2vUKXsnwPytAc9EwBHG01YDh06NIuGtf5DjoyQGmHC4XMLwmwd/Caft2fnmXr3A3d8Zf9hqgXWHEtaQ57Of9pViz179mwrXeE/MnPmzF0S7sEDGuueJnPevCuusO76sPq6R2bPHm2l+sy0gKG0NZTp2jCG27R27drx8+fPf4lu1NwQ6wnKlf0TZcFF/bwe//Z9uxw/vvfuj89Tftr65ukIOI+QmE+ePPllGgJ8UfraIloDp5MBOFoB37zxQvdPvr5gP24SsW+OsfO0CenkoqhWe8GCBQWXLl36Hd1de1vCnTas9GtIXp5h5LgJ1re3H7z2dwsWjMTUYlwrpZXLki4WXIV73bp1E66//vqVNClK3mLvh1RkGcmy4GJr3B7/zkOVXXfd86PD5yg/bVyWdAAcbVBGSY4cOTKPbtqsJqs9QhRPpqNTIBWAo4U0l+1yw1nXd29duH8nrabFKEuqXRSG20yz/hZPnTp1rYQ7OpjTqTRNUhwxtsK69t3tcxZTuzDCAsOVUiOaSsBxbAhgoZl/d02YMOF1SttokSGDFSCabeVj819/v3LOXdQNCy04xynjLFUHVuGmu5K/HDNmzHN0ux2/eBmyQoEe84gRluc2V13zS+pOSiFPBeAK3PQQQj7NQ36CZgA+Kh9EyAqqgzpBQ4h5w4aZH6URlidwrmljSix5sgFX4F60aJGNXmzzYklJyf1BqsiVrFOgqNh0/5ubJr24aFEp3M+kQ57MCwAF7pEjR1rpBs4KeuD3W1l3NtOkQ6kaRQnXfZfL/+Y3bqz7Ed3f6KZyPIwYbpe4bEuWBVfgphbn19TUPCnhjsu5y6hKCgqM33pr4+QnwQAtSbPkyQCc4bY0NjYupXeQ3JNRZ0Y2Nm4KFBab7tlSdc1SqjBpF56JBhwuEI5hOXfu3N30rOS/xk0tWVFGKjB0mPlfN1bOuRtM0AI2EuomJxJwNBx/iix0QfkNupJ+mtIySAUMpSPyn16z5fPfICnYkicM8kQBznCbq6ur59Pt9+U0FAjYZZAK4J6+aczE/BffWn/1fJIjoXc8EwE44Ea95vXr18+gt0mtpjQmx8sgFVAVIEgKJkzJX/2fq66aQZmAHMzE3ZInCnATPRBcNG/evJU0t2SI2iuZkAoIChiNeUM+O6d45cLbxxVRNv7Cxx3weFeIHwwaar148eJTQ4cO/SmlZUiyAuk4Dh5Ogs5O3wsLPrfnQSoT9zHyeFpw/FhQn+Xo0aPflHCHO6Vym6hASYnpp29v+dw3wQ4tYChuhjdegDPc5jVr1kybPHnyM2IHZFoqMJAC48Zbn/nzi1dNo3Jx9cfjCbh54cKFRfS42Qrpdw90OuV2rQLwx6/9QvGKhQsVfxyQx8WKx6MS/EgUv5vmGTw5ZMgQeadSe/aSvJ5pPrgoj73D91/zr97zEOXFxR+P1YKrrsm+fftupNmBEm7xbMl01AoUlRjvWb1u9o20Y1xclVgBV6w3uSVFNN79JL3LLuoOyR2kAqICYKhisu3JBQvG8tBhTIzGsjNbb8vLL7/8C3oxz3SxoTItFRisAhaLcfqyP435Oe0f86jKYAFnuM2vvPLK5FGjRuHRJBmkAnFToLTM8tCfnpk5mSqMyVWJBXBcWFro6Zw/0Z+Vwrj1TFYkFSAFwNQX5w/5N0rGNCFrMICz9bZ8/PHH+MbkV+UZkQokQoGiQtPX/rb+M7f0Qg5WwV5UYTCAYx/zrbfeWkw3dJ6I6miysFQgSgXGV9ieWHjrqGLajV2VqGqIFnC23ua//OUv99PnriuiOposLBWIUgGLJa9iya8q8HA6Ax6VFY8WcJQ30Sewh9DrHn4WZVtlcanAoBQYXmr62fe+NwGzUnHdFxWz0RRm621ZtmzZT+hF9GWDaq3cSSoQpQImU17ZnfeO+gntFvWwYTSAo6wZN3XKy8vvjbKNsrhUICYFykZa7r1mwUjc/GFXJaL6IgWcrbf5+eef/wH53uUR1S4LSQXipIDZklf+m99N/AFVx4BH5ItHCjjKmehbObaxY8fiDpMMUoGkK0BW/OezZxdH9YasSABn621ZvXr1HWS9Jya9Z/KAUgFSID8/b+KjT02/g5IR++KRAK5Y73HjxuXT8oBUWiqQSgVGlVseoCnZfHdzQH4HKgDrjcX8xhtv/B1NqJqays7JY0sFLPl5U59bVbEQTNLCfOoKEwngGHs0013L78npsLo6yg1JUgAMjhlb8D0wSQvYBOS6YSDAsd30/e9/n54hHrpItxa5QSqQRAWKh5gWffWbY4bSIQF4WIbDbcQvA9vNS5cuvY2es8TVqwxSgZQrYDQabHffU34bNWTAIcNwgGObAjh9P+c70j1J+XmVDehVACyOLs//Dq0y4Loc621g59301FNPTSwsLPyiVFcqkE4K2ArzvvjPv52GIWv2w0P64uEAV6z34sWL76BfjF65dOqzbEsOKQAm5/9diWjFowZcGT2hx9G+nUO6ya5mkAL0WBsDzla8X+tDWWa+uDStWrVqBo19T+u3l8xIawUsplFp3b54NY7mik/703/MxNtpeTSlnxWHk64NKuCf/exn58uLS6086b8+3Pqg4WDNHw0O5yf9Gkuf9+sX6N3twXmaVWwMkUWv+Q7eLVShHk1mv310Kg9Vrt/h/PStQoN/PlVxhBYYa7AbVCwc4PQxzxHXS8ANhkZ7jaGq8W8Gh6ed9MuM4C2ebrD7Jhp6CIJsDr481/UGw4nnqY8MeFB3tYDjF6BY8KKiIjO9qeq6oNI5urL+1L8bOt2XM673PrPf4OjwZDXk/p6e68BqV1cXAx5kxUP54MgzrVixYpbJZCrNuLOagAZnItyQwWQ2GgppXlKeEec8OwON75V+/YErZlHv2A8P6qieBTddeeWVX5LuSZBWGbnCkDs7PQa/PyO7EL7RZI5HTCj+EhXaTwt7IKpfprXgintCBU3kf8+TgIfXNlO2AnJbicVAt7izLoBR2xDLPOoYW/CgP1eiBWf6TXRrPp/877lZp0YOd4ghhyUPNUKRydJYbaa5IyYU5l8+53BRP5hjxYprf9NYNz7zzDOfpl9GSSZ3Wra9vwIMORm9rArUn5Kbfzzt09QphV+xcyEt+Pjx42dK90SUKXvSDDksedYEwnrYyIKZ1J89tOhacN5gpLnfU7Om87Ij/RRgyLPJiFlsZjALC84cK/1GBgdswLqJZg9OzabOcwdl3KcAIC8oNuMtrn2ZGZpCHyxW0xXU/H4Xmgw49xLrRgJ8Sob2VTY7CgVUyLNgnLwXcIXfXgkUpvv54KWlpeaCgoKKKHSSRTNYAQXyIrPB1eXVzOLIrE5ZrcaK0lKbuaXFCbDZYCsuCfcEmcbf/va34ym2cqaMs18BhjyTZ/3TmKB17ncngV1Y8X6AM/XGq65SPsaZ/WdV9jBIAUBuLSSfnPFgIjIoHj2pCFO7xR6oFpy7YRw5cqS8wAw69bmz0gc5cMiwQE0uKrH0G0kRfXDFQbfZbBMyrGuyuXFUQIGc3p/Q7fSRT65O6YjjERJXVX6hCewqHPNRsILAFjyP3j2Iz0XIkMMKBCA3ZdwQosloBLsqyziFogXHBiNNkS3OhrFRdE6GwSsAyPPJkrvJkmeCHVeYNeUBcPbBlc7ziko9AY6XjMsgFVDmkysXnqAjAwIN54NdlWWkRQuOLuRJwCGDDKyA0ZRnsNrM5JOn/zi5yZzHgHPz1VEUZCjkS8BVbWSiVwGGXCEkjVUxGlXA1b85bMHVDAl4Gp/BFDaNIXe7vGk7uEL+iOheK0zzKAqkkxY8hQBlwqEBeX4BJmilZ2uNRuX6UeGYW8gWnNelD85KyDikAgy5uzv9xslNRvUiU217PwtOW7TQq4VlQioABRTIrTQzNc1MeU9eD9gNacHVPzper9dBH3mVj6tJlsMqwJB7yJKnyzg5vTXAITRaYZrHwdV8n8/Xpa7IhFQgjAKAnOZhp83gSo/foGVXGQfHD1D9EcKCh+mT3CQVCFKAIfe6yZKrFAUVSdqK39cjsqtwLfrgaEiPtOBJOx9ZcyBAbs7H3JUUd8mnWPCgn5l4QalskICn+CRl6OEVyMld8brp9VkpMuU9fj+7KCrkIS14v9fpZqjostnJVYDuJJIlJ6RSYMrBrK9HAVyFG71nC45MZZE+eHKhyLajMeQ+jz/phtzvy4MPrrIMbUULzoDbs0102Z/kKgDITRZj0g253+8Huwy40mm24KoCTqezBeZezglXJZGJQSgAyA0EOSx5MgLcfp+7p0V7LLbgTL2/tbX1tLaQXJcKDEYBtuSD2Xcw+zg6u8EuflHMs+KiYAVByTx58mSdvMgMCCL/j12BpEFO9Laed9Yxx70t72ELjnUF8DfffFMC3quOjOKjAEOeyMEVfOyqevtFLeD9RlH8GzZs6Ozu7r5E81FGxqd7shapAI1mwCen5zz93sT45H5Pz6UTey52ktb9XBTor1jv3o1+u91+RropkEWGeCoAyI0EebyHV8Bqt8t7htoKuEMCjn4AcqWAw+E4jQwZpALxVkCBnG7tK5DDZ4nT4nb5wawIuNJ09sFFC+7DSIq04PE+tbI+VoAhj5dPjiHCbrsXgNNTGMEWXBwHVyFvamqq48bIWCqQCAUAeQ8ZcJoBGHP1+KF0NHvALCw4c6zUG8qC+995551DNOkq9iPH3HRZQTYrgJuJmKQVa6CvOffUfNhwiOoRXRSFXwYcx0AGCvjoI7CX2tvba6WbAllkSKQCsUKuXGB2eWsr37twidopuihKs7WAM+Te5ubmSgl4Ik+trJsVYMgHMz0E/ndXm6eS6qI3E+m7KHwsxYLTiq+2tna3BJxlkXGiFQDceDe5EiMd6UIPzLU0OneD2d4FDKtBz4L7li9fXkmzs4IKq3vJhFQgAQow5NFUTYT696w5DwsuuieK/416QgGu/BLWrFnTSn54jbTi0cgty8aqgAo5rj0HWHB7vtvhqTnyUVMrlWYLDrhDAo62YQOsNvwZLw0X7pGAkxIyJFWBgHsy8CHhf9tb3Pj4q8IrxWBXhRs1iBYc6ww4fg1e8sN3ScAhiwzJVoAhJ1dc/2YnNaq5oWsXRQBcdFHU5oo3epAJwBly79NPP73npptuchUVFRWoe+RgwnXRZmh3YBQqu4OuMQuyiX0a6GQHCuhs1D1GX7VBKVhp7APgtfvSS4dcm1bUsQVn6x105FCAo6Diz3z00UedjY2NW6dMmXKL0ag19kHtiHil9nyj4b2dVYaOLvEVFhHvnpKCXs9XDUa3m44dpF1QW7TiB23UWdHdR+cw8DlDBlCgE/S30A5h9tOpLubsaG/r6JWnJ+gNrtbmrRdO7sYMQva/GXK1nVrAsQGaoCDMvufgwYP/N2nSpLgB/sJb6w0tHWhTZgV3t4teidBNjYbkkEhPem2/uCyjpt1fu127f7LLa4+vbZ+2Pdry2vWB9tdu1+6vPV6gvN/vMzTUHv8/Ku2hBaz2gxs1hTLLqIEB995///07aPpss661QS1RhEyEG93LtxbQKxH4+7gQPdLAZRGLad5fzOMyYoxyXEZMi2XEtFhGTItlxLRYBmltQFkE3ofTSmYE/w20v3Y7H4dj7fECrorP42mu2rZhB23VvcDEnuEAh9n30MxC5/nz59+LF+A4aKaGAOT5wbxpO6M9X9jOedqyqVjntujxo21Tostrjxfheldnx3tuu91JxWHBQ15goqpQgCMfFpytuGfTpk3v0PtSkJ/zAZBbLL2QMyRiDIUYCjEtlkllWmyTmNZrk1hGTMervF49YfL99JbNpvrat6k5onsCXvsFPcDhpuBXofjhS5cuPdzW1nZKWvGAfhaGvJ+cMiPRCoBBj8t16tCOTUfoWAw4WAWz/UKoi0wUQmGGHJW4aUx8TVlZ2YP0DR9sz/kAyBG8HsgjQ7IUAOD2jvY1dDwMa0F8hjsk4HoWHO2FyVet+MqVK9+hh5Hl2YQyvQGQm/PJXQkXcKcCge9YcFrJDPFftOVDVJFWWdH2Z4Dy9PpjT92R/e9QH8EiPAwwGtI9oXxdHxzb8ItgP9z90ksvNZ45c+ZdOf8K0vQFC42sKJAzwNoYRfmkiWltOV4Xy4hp3p5psdgHMa3XD7GMmKbyALKrs/3dMx8faKQkLDgAB6MhrTflRww4fi3uV1999QWy4rq/FlSYi0GB3GLJxa4ntc9+r9d/5tjHL9BB2T2JCXA0PsiKP/nkk7Vnz559X1rx/ueVIQ9z8a+OJMsygYGmaHTAXVdnZ+f7x/bsqO0FfEC4cZbC+eDYDmutuimU7v7rX//63x6PR/dPAnbK1QDITcoQYq/fDSHwp5hjMR3I7b9d70+3Xj7XPdj6Yt1f266B6htou7a+3nW6c9lTf/Lwf9PuuJ0suidhPYqBAEdzUAEcecVN+cMf/nCMrPg2acUhTf9goYtOk5ncFT5RKII0B07rbedykcax1hfr/tp2DlTfQNu19dE6Rk4c9o5th3d+cIxW2T0Je3HJ1UQCOKy1Cjilu9etW/c8WXGuQ8YaBVTINflydXAK+H007+TUyedpb7begA9MDuhJRAo4W3H8erqXLFlS3dDQsEtacVJDJ0jIdYSJMhvW29nVuevAtvXVtCsDztY7LoCjSWzF4dgDctfatWufkSMqkEY/AHIzja5gLjMHTgcm9AfyOQ9lOM3bo43FOsS0Xj1iGaQHCtG2D/XxPmKa2yPmiWne3uP3+Zvqjj9D21y0gD0wGJH1pnIDXmSiDAIAD7rYfOihhw7Su8TflnNUFH10/zPTRafJbFZOMp9ojrETp/mEinm6lYbZEG192vLcDr042vZp69fuH247psR2tDS/XbVl/UHaj613RKMnLFEkLgqXZSuuXGzigA8//PDT9GByK/6MyKCvAEOuX0Ju0SoAprzd3a3VO9Y/TdsY7oh9b64vWsDZF8cBXZs3b75UWVn5Z3nByXLqxwHI5c0gfYWCt8B6Nzde+HPj6dN4VhDuCZiL2Pfm2qIBHPuIVlyB/Pbbb3+THmurlhecLKl+DH9cHULkYuyfI45kwX68j5jmfcU8Mc3b4x2LxxDTescRy4hpoTwezXN1dVVvfeuVN6kIwx219Ub1gwGcrbhysYkGrFq16jGXy+WTrgokDR8UyE00iZNPKIojHWngsnr7D7Q90uNEWi7a4w1QHgz5vF5f3ZEDj1ETADdfXEZtvdGFaAHHPgw4flGKFX/00UePHDt2bDW9kRbbZRhAAYYcWMslWAMDPcxgb768mm7qYL631nqDvajCYADHARhytuLOBx544NnLly83SlclMv0BuZFGV2ToU6CH4HY7nI37Nr/3LOXicTSt9e4rHGFqsICzL66Oi+/du7f5tddee5g+f+KRrkpk6pvplr4CObsbORwDKBpy9pyuqX74YkN9M60y3FGNe2uVHyzgqIchV604DRvuI9CfpRtA2uPIdR0FFMjlU1L0pQcvjZo0PHvggw37SCqt9QZrgwqxAg5XRbXilHbdcsstK+vr63fIG0CRnw+GPFf9cbpbaejqaNuxZfXylWCod+G7lmAsJYDjDOLgWPiCE788x4MPPvgb8sc/kf44qRFhCECeez45/O5up/OTqo3v/oakwuvOwBBcADDFfFFycCEWC85HRCMwfIJfHBrnpBtATa+//vqvyB/3Sn+cFIkw4Ja+URxCzHKfHGaZ/tJ76SmdX9FrIJpoVeGHYrDEw4KUHHyIB+BoJxrDrorSSHrVRNWePXuegz8uIY/8BCmQG7P/zQVgAn735aYLz+3fsq6KFBLhjunCUlQ7HoCjPoY8yFVZtGjRcpqQtdGtvLhSPKxMh1MgYMkBefZ65TRJ0NDZ1rpxy2vLl1NHta4JDCaYijnEC3A0hCHnURU02rF48eJ/oYvOvRLy6M6ViVwVoymepye64yeytI8sd1dH+94tb6z4FzDSu/CwYNzgRh/iqSAAF/1xNNhBX4nouPPOOx+iByRq5KQsSB55YMizyRXHiEm3vbNm99o3HnJ2dHSQGgBchBsMxcV6Q+lEOHtonNjAPILcW1dXt3P+/PkLPth/eGgePqclQ0QK4L3synvBs2BKMmYIuhz2c/s2rf1ZY33tJyRAFy0MONzbuFpvCJwIwFEvQhDo5It3d3Z27naYCm6mGXWFPNE9UFT+H04B/vhAgPHM9Mv9fvpglNPZfGjnpntOHzl0lvqrhTuulpv1TBTgogVX0wcOHOiix7j2Dx899is0HJYvIefTMHCc1/uFjUwckcL9EHphpv34gY/uq9nzUU0IuGG5AXjcQ6IAR0MZbI6VxjfV17UVlQw5OqR0xEKah2GRkEd+TlXIIW2GGHK86tjtcjnqjx74pwNb38dteNFyx228W0/FRAIuHhOQq6BfqD1+0WIp2Dds1KgFNCRmkz65KFX4tAp5Bvjk8LndDkfriQN7fn5g6waMdTPcGPNOONxQMtmAq6DTnasWn8e1s7R8wvVkyEv4xKFRMoRXQDUIiiGnz16n4b8eGud2d9kbqnd+cC+9bu0o9chOCwBnuHEzJyF+N9WrhmQBjgOyBVchv9xwobOro3XbqPGTrjVZLGV8MaW2TiZ0FQhATlKyqrolk78B49z0HsGT+zatua/uyMHT1AKAnXS40fNkAo7jITDgStx++aKz+cLZD8onTZ1NryEeA59c+uUBoQb6X4UcBdPAJ8dwJt5CRTMDD+xY88YvGs+caqCWad2SpFhu1i7ZgAfBTY1Q1umdz+7zp45uHXfFjCn0AstJeUYJOZ+ggWLVXUmxKcesQHqWkm6/t2zd+saKJW0Xmy5T2xlu3MjBDMGkwg3tkg04jonQD3S60vbVVh/cPmbyFGu+rXA2+eRkyGGWZBhIAdYpYMST75H30Bg3fcqlp62p4eWNry7/N3rVWju1WYQbF5RJhxu6pQpwHJsh5wsN+nit13+quupA4ZChNSVDh881mkw0wiKtOcQaKEAnCJrMoMwIpJESj6Orlaa8Ltv2v6++QeeQLybFO5QpgRtapBJwHJ8hR6yCfuFUzQX6U7d5RPn4K8kvL5cuC6QaOKiQJ8EfJ2/bgItJR3vbwb1b1v3iaOX2Q9RCWG223HBJxKHAZP/+FMHSBXDAzYsCPV18dp06eGBjecVkk7Ww6DPSZVHO14D/sbsyYMEYCuDOpNfj7mlpOL9yw6oXf996sQFvn4LFZri1k6diOFpsu6YacLSef9lsxVXQ6c+d79ShqoN05/NI0TByWYxwWWjAQPrmYc96nz7xNeWBhxRofNvpbDl7rPpX2/73f97qdUkYboxx88Vkwm6/h+28ZmM6AI4miZCLoCvp86eON9ibWzYPHVk+mlyWKXBZMC7WdyI1vZKrvdqwrLEJArAxSoJvgna0XNpctXntkqOVHx6mWtliA3DtDRwYqpQHkJJOAe3BXFr88PCmSist+OKqjZZCpK+55bYvVEy78pcFRcUT8eRL3zAZbZWhnwIAM5bAw3/dXfaz9SeO/vve99fsovrggjDUPATI011xwPj8smJpeO++6QY4mhUwzwHI8Zg5vrQKyBl0W0FJSfENt/39D0pHj73LYrVayXWR1pwE0guBGYjRMaeOkNBDtc1NDSs/XLP6FVdnJ0ZIYKmxAGz2tTFKwnO5ozsQ7ZjIkC4uiraPLBJiLLAK7NP5vG63t/bQvkMOR8emoWWjx9Fr0CZKt0UrYd96nyvHtkM/xhwudkfsra0fHtz6/j/v2/zuB6S5OPwH6y3CjfMT25+KvubGNZWOFlzsINrHLgtbc7bocFsUyz7vq9+6oXzK9PsKCgsraE6L4rb0nVSxutxOByx5aA3Yz/aRn+1yOOobT598dte6N7dTabbUbLUx9Mc3btjosEEKXXkKc9MdcJYGkDPo8M0BOfvnCuRms7lg7uJv31Q+ruJOa1HxVLzcEv65BJ0lDB0z2LiAJD/7VNOF+pcr1/5tE72uhMHmmMe1RV87La222NNMARxtZmsO0GHNGXQAzrAjtn5x0Te/VD556p0FxSVX4Y1RmIorQSdlhKCAjfFsL1lse+eRptOnXv7ovbd2UBGAjAVgcwyLDbD5jiTATlurTW1TQyYBzo1Gm3HtwKDDmrNFVwCndSW+5uavXzNu8oy7CocMuRpfVgi8hiF3hxcDLgpm/GFilMfg6OjYf+H08ZU0MrKXNGOwxVh0RwA1X0hSMjNCJgIOZdFuLKLbAovOQ4si6PlXz7959tipM28rKhm2wGzNL8TrGHLlopShxoQo3Fr3drsdXZ1tWxtO1byzf9v7uL0OiEWokYa15kX0szPCalPb1ZCpgHMHGHIGnV0XBp0tu2Lli4eNKPrc/C8vKC0v/0phybA5NI5uogldivuSbePpGAkB3JifjU+CODrbqlqamjYc2LZxq73tMm7QsHUG0Aw5Q83DfrDaGeOOMBRinOmAc1+0oPONInZfxFix9BOmXjVq+py5Nw8rG/kVmp47lV+XFvDVM8+NUS11H9R0S91xqq350oYTVZXvnzt15CKJxQAz3GKMbbDWbLEzGmwRDE5nQ8ygIwbksOhs1QE54NbG5qu+cMO0cZOmXW8bMvTqgsLiWQS7FW95hc+ersAHA+1XXmRJlrqbXqxz2NnRvv/CmZMfHtm1/ST1F9YY8ALmUDG2s8WGC5IVYFM/lJAtFpz7wzH6xbADdF4AuBZ4xaJTvrKtoLjYOuvaL80qGzPx8wVDSq622Yo/ZTSbLLhbqjwzqsxPp9JKCMiXqBGaAMQ4UMD1xU0Y8jsMmM2HJ9ZpLprH6bQfc3V07m9uPLvv8J4dh112O1wOhhpA88KA8za21myxldqpfFaFbAWcT5IIOvx00VcXrTtDznkcm4aWlRXOuGbeZ4aXjfm0xVYwMT/fOtFsLRhnwsMYyvCjUQG/76KVD62NtVIHoNWWUiAmoHFRCJAVX5pi+oKdk+zzBbe7+6zH6Trb2tz48fG9O6vbm5txVxGQsiXmmMFGzHmIGWjRvw7dGCqc6UGreqb3J1z70VcAzjFbddGVYbC1sVhW+aFUzPzMqNETJ1YUDyubaLUVVeRbrRNMFnOZyWguzAvAj9fToZ6AmwPLjxUKCk1EMltoir30OJOjhyD2+b0On8fb7O7uPtft7Kq3tzWf/eTs2fr6mmr40AylaH1FeEOlxbLsfnCstCeb/2PNs7mP2r6hz+ICeNmycwwwGWqGnde5jBgjjUWsN4/cHfPQ0lFF9PidzVpUWFRgK8KMSIPL2eXo7qLRuvZWZ3vLxS5yKwAmuwgcM8yI2eqKMdIMNEOMdbEM78t1ckzFciPkIuDimQ0CkjYwqByL8IuAY7u4jcujPqS5XkoGpbEuBhE4TrN1ZcC1wDK0DDWvc3mOuT6OxePmTDrXARdPNGvBcCLWgsvrDDEgRzmOOT9UXTgW5wM6BIZPuw5IkQeIxZjh5RjbxDTWsSBwHFjL0f9Z8BztfthuszaIwy0i1NpyOIBYj3hABlCMkdYuDLs2X1xHvViXQaMAi6/Jlqs6CrBeDDKKhcsTt+tUGQQmQ8rwYp9weXp1yvxeBfjkSEFiU0Cro3YdtWvzGFzxyNo87bpYVqYjUOD/AZrbm7Ts1rpFAAAAAElFTkSuQmCC',red:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAk/0lEQVR4Ae2dCZxUxZ3Hq8/pnhkGmOEQuQS5VCTxWHEDBlyNkciakMMkxujGuOvHO24IKCae0UQlKwmyroocoqtozGpA4oFiVAQU5IaRcchwDsPczNF39/5/b+bfVL/p7ume6bur+DyqXt31r2//5//q1XvPIJRLpgQMMVYeiDGfyhanBGKdgDirzYvsLLtIPguB0/lc7+vh5vNIvr68Oo8ige6EH6Vo3iSxjODrw1rcm2++2f+MM84YV1hYONRkMhUZjcY+OAKBgOZTXDGVLTYYDH0gNYpvIa/V5/O1+v3+FopvgY+D4tra29uP7N27d98VV1zRiOy6g06DcRyGr1wYCfCEhUnK2yiWiQYvSQG+8ac//all3rx5o/v16ze+oKBgnNlsxjGWQB5LgA5MhrToh1BL0Fd4vV4c+1wu176mpqYvHnnkkf0rVqzwUJt+OuQfALrBmh/hvHc8mfkuCBlmDei5c+fab7nllguLi4svttlsXyeYzyPgrJkgKPpBuQn4LU6n88PW1tZ1ixYt2vjoo486qG964PMe9nwGnKE2EhgG0tDWBx988HzS0BdbLJbpdEymeFsmAB1DH5wej2cTHR+Qhl937733biYN76ZyAFyGPoaqcitLvgEeAvX1119ve/jhhy8nLX211Wq9lKYWtnIuuFa3272WtPv/3nPPPW8tWbLESYPKS9jzAXCGGj60tfGLL764YPDgwT+x2+3fp/MyOnLZ1Tscjj/X1NS8OH78+E9poNDoslbPaTMmlwFnsDWoN23adNq4ceN+TBeIP6FVjbG5THSksdEKTQVdqL64b9++lyZPnlzVCboMe6SiWRufi4DLYJsqKyunkraeCxOELhJzcbxxw0cXqQGYMKTVHz399NM/pgp8dOQk6Lk04RiLpq3JNx04cOAbAwYMmEurH1PoXLkIEqDVmPV1dXWPjhw58l3KwqAz7BFKZU90LgAeBHvYsGHmjRs3/mtpaekcMkPOy55pSH9PyXzZ0tDQ8NiFF1646vDhw17qESDPetCzGXD0XYObwLYQ2FeVlZXNoRsvZ6Yfl+ztAd1Y2lNfXw/QXyHQ9TeTsm5g2Qp40BTZtWvX+aNHj15AGvv8rJN+BneYNPrm/fv3/2LixImbqZuy6ZLBve7atWwDXNPYNAzT0qVLS2fNmvUA7f+4gS4eAbxynRIwHN8ozDseFQZHTW9l4m/3BBa/8nnDfT97vKqBKmPQs2ZpMVsARz8ZbvPRo0ev6d+//yNkjiRlD0hvqUh3ecsrpwtD2+GEdcMfELUNbWLewNniBaqU7XNAnvGgZwPg6KMJx44dOybSstYf1coISSOKsy4tiJLa8ySPX6wvrxN3TLpX7KJaoM1xZDTkmfynPaixJ02aVEBX+PdOmDBhg4K754D2tqTFKKacPVhsOPEnce+kSQK/IjMdYChjFWWmdozhNq1evXrYtGnTltKNmq/3doLypXyyNLgsP49XfPhOpfjZzCcEbKGMtc0zEXBeITFXVFR8g5YAn1O2toxW9+FUAI5ewDY/UC9+PvrXAjeJ2DbH2nnGuEwyUYJae/r06bba2toH6O7a6wrujGGlS0eMBjFw1ADxetMT4oHpZ2lbi3GtlFEmS6Zo8CDca9asGT516tTltClK3WLvglRsEanS4HJvXF6x/v0vxHXfWigOUXzGmCyZADj6oK2S7N69ewrdtFlJWnuALDwVjk8C6QAcPSSTpa6iTvxwwm/EejrNiFWWdJsoDLeZdv3NHDNmzGoFd3wwZ1JuMlkGjBsoVlf9TsykfmGFBYorrUo0nYCjbQjAQjv/rhs+fPjLFLbToVwWS4Boto/sL14++ri4joZhoQNznDbO0tVwEG66K/nLIUOGPEW32/GLVy43JGAeUiKeqvsv8UsaTlohTwfgGtz0EIKV9iE/RjsAH1IPIuQG1SGjCAhDWaF4qHmBeGzwYIG3EaRFk6cacA3uGTNm2OnFNs/16dPn1hChqJOck0CJTdxaeY94bsZkzfxMOeSpvADQ4B44cGAB3cBZRg/8fi/nZjNDBpSuVZRow3d4xGsjHxT/VlsrXJSPlxGjFUlIWqo0uAY39dhaXl4+X8GdkLnLqkrsFvE90uTzwQAdKdPkqQCc4bZUV1fPpXeQ3JhVM6M6mzAJ9LGJG+v/IOZShSm78Ew24DCB0Ibl0KFD19Ozkr9JmLRURVkpgdIi8Zvqx8X1YIIOsJFUMzmZgKPj+FNkoQvK79CqyQIKK6ckIE4pEQsqHxbfIVGwJk8a5MkCnOE2b9++fRrdfl9CS4GAXTklATwiYRpVJp7bfb+YRuJI6h3PZAAOuFGv+a233hpPb5NaSeHkPGJCFSuXnRIgSGwTBomVb/2nGE8jAORgJuGaPFmAm+iB4KIpU6Ysp70lJdk5BarXyZaA0ShKLh4tls+6QBRRW/gLn3DAE10hfjDoaMHx48ef6Nu37w0UVi7FEsjEdfBoImh2iMX97hR3Up6Er5EnUoPjx4L6LHv27PmugjvalKo0WQJ97eKGLx8U3wU7dIChhCneRAHOcJtXrVo1dtSoUQvlAaiwkkB3EqAngxauuk2MpXwJtccTCbj5kksuKaLHzZYpu7u76VTpegnAHr9svFh2yQTNHgfkCdHiiagEPxLN7qbnKOeXlJSoO5X62UvxebbZ4LJ4yB5/muzx2RSXEHu8txo8aJps2bLlYtodqOCWZ0uF45YA7T68cfu94mIqmBBTpbeAa9qbzJIiWu+eTy9Wj3tAqoCSgCwBIETr4/OnjwsuHfaK0d4UZu1tef7552+nF/OMkzuqwkoCPZWA1SzGvXS9uI3K93pVpaeAM9zmF154YdSgQYPwaJJySgIJk8DgvmL2C/8hRlGFvTJVegM4Liwt9HTO78k0KUzYyFRFSgIkATJVCq88S/yOgr3akNUTwFl7W3bu3IlvTH5LzYiSQDIk0KdAXEEbsi7vhBysgr24XE8ARxnzlVdeWUw3dB6LqzWVWUkgTgmMHSgeu3Ky9oFeNlXiqiFewFl7m5988slb6XPXI+NqTWVWEohTAhaTGPnMLIGH0xnwuLR4vIAjv4k+gV1Cr3u4Kc6+quxKAj2SwIA+4qbrpwjsSsV1X1zMxpOZtbdl3rx5P6cX0Zf1qLeqkJJAnBIwmUTZ/TPFz6lY3MuG8QCOvGbc1DnllFNujrOPKruSQK8kQG/Kuple0Yx942yqxFRfrICz9jY/88wz15DtfUpMtatMSgIJkoDZJE5Z9mNxDVXHgMdki8cKOPKZ6Fs59lNPPRV3mJRTEki5BIb0FbdNOj2+N2TFAjhrb8vKlSuvIu09IuUjUw0qCZAErBYx4i/XiasoGLMtHgvgmvYeOnSolY47lKSVBNIpgWH9xR0lJcG7m93y210GaG8c5ldfffVfaEPVmHQOTrWtJEAbsca8f7O4BEzSwXxGFEwsgGPt0Ux3LX+ktsNGlKNKSJEEsJ121CDxIzBJB9gE5BFdd4Aj3XT11VfTM8R9Z0SsRSUoCaRQAn0LxIyrvyb6UpMAPCrD0RLxy0C6ee7cud+m5yzV50VIGMqlXwL0/Kb9nsvEt6kn3S4ZRgMcaRrg9P2cHyjzJP0Tq3rQIQGYKSP6iR/QGQMekeNICdDeOExPPPHEiMLCwq91VK3+VxLIDAkUWcXXnrhaYMma7XDw2sVFA1zT3jNnzryKtHekfF0qVBFKAqmQABFpnDUxRIvHDbi2ekKPo30/FR1WbSgJxCuBwcVBwFmLd6kinGbGLwHxphUrVoynte+xXUqpiIyWQKBoWEb3L1GdozXxsS/9u/Z2Wl5N6aLFYaTrXRDwr371q9PUxaVePJl/3nzef4uaN28S7hNHunQ2EOgSRa/r1rkuEXild1enr6unecJVHktd9OlwaOJp1LPddEApg92QotEANw8YMGCqApwktmen8K9cIURTI8kv810BdXGI72JR73LR9+ND5jvzOx9nD80u11QhVj1DxRjwkBr0gOMXoGnwoqIiM72p6sKQ3Hl64nv0fhGoPZ5Vo8ff7P5+v2jw+Eil5S7kfQKBC8FqW1sbAx6ixRGpd4gzLVu2bKLJZCrVJ+bjebbBzXNkoTsipfRQo0HTWRybWz7BWvqHkYMn0qjYDg8ZoB5w1uCmM8888yJlnoTIKitPGHIj3R3hyc0lHwCPLbRdRB4A56EF5yoc4Igzkf09RQEelFNWBwB5f3okJhfnE2MqNZumgFk6wC4gDzoZcKbfRLfmrWR/Tw7mUoGsl0Ao5DzVueEXmUyThxcW8heUeVDanMmAIwLnxoULF55Nv4w+Wg71X85IgCE3AoEccjScPr8ZderZNCSNX3lo8ioKk28aNmzYhFz8cyYPPF/DHZAbRKPXmzNrK6B6qM0ygbxP6WCOtaUjWYNzgpH2fo/JVwDyYdxmUuH9zWZN3eXKePuYjGAWPDPH2tD0GhwZTLR7cIzS4Jp8cvY/QN6PIG/KAU0OVouMxtPBLh0MuTZ3rMFBPRzOjQT4aO1M/ZfTEmDIc8Emt5s0wDV+OydNY5oBR5ym2ktLS802m21kTs+sGlxQAoC8r4nMFZp9DQAGIct8m9EwstRuh0XCw9DGqAfceP/992MrGrYzKJcnEjgJOdjIUhcQBbcPHQx2wXRwIGyDM/XGs846S22PzdI57k23AXkJmbAnfNm5dwUAn1mkbe3+ohNwRAVYgwcBHzhwoLrA7A0pWVxWg5xe5Wo8qQCzZjQAuNRs7rKSwhocAwHsRrvdPhwnyuWnBAB5H9LkLZomzy4ZFJmNYFfjmHuu1+AGevdgMScqPz8loEGuafLsGr/ZYAC7bI3A1x6751EgwkhbZIvVGjiLJH99QF5Mmrw1SzQ5mKVFcAAOpa3BjdnjkyD1BDheMq6ckoDQNDntQsQSYjY4ghzsBllGWLbBMQaDAhxiUI4lYCLNWEzmiqbJM/zBIKvByIBz9zUNzica+QpwFofyWQIMObGe0c4kAgx4sKeswYMRCvCMnsO0dY4hb/P5M/YZT7NJ0+AsI41pXkVBJCKUicLiUX4XCQDyIhNWyYP6sEuedEZE0+DcLwU4S0L5YSXAkLdrmjxslrRFGmOxwal3bLakraOq4cyWACAv1DR5ZvWTVlHArmaJcM/YRAn+zfF6ve2cqHwlgUgSYMi7rDNTASYs1b7PH5DZ1Zjm/gXH4fP52oInKqAkEEUCgJz2YWeMRU6Xv3p2NZWO1c3gCqfS4FFmVCV1kQBD7qS3aKX7LXE+v1/W4BrXbKJwxwNKg7MolB+rBAC5jd69Ql5anS8goMGDyhqdkS8otQQFeFrnKGsb1zQ5Qa5p8jSNwm8ImihByMNq8EC6/9akSUCq2d5JAK+H0zR576rpUWkwSyuXETW4Zq9QzQFlg/dIvqpQpwQYche9vDvVb7X1BgRs8CDL6JKswbUEAry1s6/KUxLokQQAeQFtQUz1HU96FzrYZcC1vss2uBbhcDgaoO7VnvAeza0q1CmBDsiFcPlTIxJQ7aTXoetbYw3O1PsbGxv/oc+kzpUEeiKBk5q8J6XjL9Pk9YBd/KSYZ81EwQmcFllRUbFfXWR2CET933sJAHKrZq4k9w4nelrldOwnLwg3wqzBka4lvPbaawpwSEO5hEkgCHkS18kB72v1zXrAg+vgTL3/7bffbnG5XLVms3lgwkaoKsp7CQByC0nBo+nRxIvD7ffXrjve1EI1dzFR0FoQcGRobW2tUmYKxKJcIiWgQU6gJ1qRg9U2X6CK+gq4wwKOcQByLUN7e/s/EKGckkCiJQDI6fUOCd9x2O7zgVkZcK3rbIPLGtyHlRSlwRM9tao+loAMOcf1xge8TT4vAPfREaLB5XXwIOTHjh3b35sGVVklge4kAMhhqngTsC0E9dR6fGA2BG70IZwG97/xxhs7aNMVgFdOSSBpEsDNxA5zpXdWuY/MjVW1zTuoowA8BHIGHIMA0Ej00Udga5ubmyuVmQKxKJdMCQByE/ENfd6Tf6C2xR+ofPFITS31UzZRtG7rAWfIvfX19ZsU4MmcWlU3SyAIeQ8UOYCt93g3keelI0R7o34ZcJxrGpx8X2Vl5UYFOESiXCokAMgBI3lxHTDkqxyujVQU2ps1eLDLMuD4MbAG9y1ZsmSTn1wwpwooCSRZAgx5PM3Qg3L+JTX10OAMN3OsVRMOcO2XsGrVqkayw8uVFo9H3CpvbyXAkMNa6e7AQ6DNXl/5W8fqGyk7a/CIgKNvrMFhz3hpufBTBTjEolwqJQDIAXd3DrDWuj34+KvGK/lsgweLyhockQw4fg1essM3KMCDslKBFEqAIY+mxdGdynbPBvIAuGyiIElz8o0eRLB6xy/Bu2DBgk8vvfRSZ1FRkU3Lnaf/VRaVCM/xmpwffSRlBijCuUjxyBsxLUJCpMfbkB39AvD6/jn8fufjh46wBmftHdJCOMCRUbNnPvnkk5bq6uoPRo8efbmRnphOhGvbWiGO/c9fhaeuORHVpaQOt+8rwlmCb7uHyC6k7UgpUctEKBStTEijnSf6iZfzRGhCyxJvO3K96Q7T42mi2nnig21N5dhByPY3Qx7snh5wJEAmmgYn37Nt27a/nnbaaQkDfP+dTwp3dT3aySrn9HtEu9+r2YYQUCw2IgbIeRk0lOO4cOmIk12q88ttI8x9jdR/fX79eXfl9en68pHG7w34xW5nzV8pv4cOeQ08pIpwahltMuDeW2+99SPaPlsfTUuE1NjNSTbCjSEVGS2i0NihD2KFG+U4L3w5jDQ4OY7zyL6cRw7LeeSwnEcOy3nksJwHYb1DXjguw2EtMob/uiuvT+d22Ne3h3iw6Az46he37PyITiNeYKJsNMCh9j20s9Bx+PDhvyUKcDSarQ6Q2wnyaNf4nMa3nTFWjsuEcXNfYu1fsvP3RCbQwLU+598a3W4HBaHBw15gou5wgCMeGpy1uGft2rVv0OskEJ/3DpDbjCYNWoZE9iEghkIOy3nSGZb7JIcj9UnOI4cTlT9SPdHiAeZ2Z93r5MnmCaK7uEiA40eCXwWo9sydO3dXU1PTl0qLd8iPIe84U/+nUgJgsC3g+XJJ8+7d1C4DDlbBbBcX7iITmZCZIUclbloTX1VWVnYnfcMH6XnvADmcKwDZKpcqCUBN13jbVpHnpoPNE+a1SzciaXBkRF1BLb58+fI36GFkVKhcpwQ0Td7lS4xKPMmUgFv4PG+3HXmD2pC1d1jzBP2IBjh+FSgIM8W9dOnS6qqqqjfV/iuShuSwsmJTkEsSSV4Qa9+1Pseb77ZWVVMr0OBgE4yC1bAuVsA1M+XFF19cTFo84q8lbAt5EKkgT80kuwMB/7q2I4upNTZPegU4eh2ixefPn1958ODBd5QW7zqhDHm0q3+V1nMJkPIW9f72d149UVHZCXi3cGOWomlwpENbB80UCrteeeWVZz0eT8Q/CSiUr64DciwhnnQcjnbjArk5PV6fy3KL+va6q6+35fX1d1dfd+n6+vjcL/yBjx3Vz1J5Fx2yeRLVougOcPQHFeBiUzNTfvvb3+4lLf53pcUhmq4ON4IKDB2QY3Lg2JfDPHFyHMLxOq67p/X1try+v93V1126vj6cd9jezr+vaCrfS6dsnoDJqHCjbCyAQ1sHAaewa82aNc+QFkd55cJIQA85w5cKH91hiORwKtpOVhs+4nij89gzNB7W3oAPTHZrScQKOGtx/Hpcc+bM2X706NENSouTNCI4QG4lTZ5qx3AzbGif41Ldl0S0B+1d73dtWNy4ezvVx4Cz9k4I4Ogna3EY9oDcuXr16oVqRQWiiexOavKTiOEyC44vtzisRXbGcxznicfnsrHWp8/P5SL5+v531zd9/fry3aV7aOVkk+P4QsrnpAPsgcGYtDfli8lEQT4ADi3OgLtmz569jd4l/rraowLxRHY2TZPjY6kd/5CTJ1kOR0qPXHP4FK471vr0+blcJF/uc/gehMbq69eXj5buoy2xR31trz/duGMblWPtHdPqCfciFhOF87IW1y420eBdd921gB5MblR7VFhE4X2GPHyqig0ngY49J97GxU27FlA6wx2z7c11xgs42+Jo0Pnee+/Vbtq06U/qgpPFGdkH5FhdUS42CeD5qb2exj997qzFG6tgnoC5mG1vbiUewFFG1uIa5LNmzXqNHmvbri44WaSR/QLaZstLiJyLrXP4sRwox2XkMJeV4+Qwpyfal9uQw5HakfPIYTk/tHej37X9vuMbX6M8DHfc2hv19wRw1uLaxSY6sGLFikecTifegYg6lYsiAUCO1RWeUGRFOFbHeSOV7y491nZizRdve93lB0Nu+qD8O22HH6E+AG6+uIxbe2MM8QKOMgw4flGaFn/ooYd27927dyW9kRbpynUjgSDkeP+HOkJkEKBfwCF/68oXmvdgv7dee4O9uFxPAEcDDDlrcccdd9yxqK6urlqZKrHJH5BbeqRfYqs/G3NhzftEwF39ZNPORdR/PI6m195xD6ungLMtzsuGzs8++6z+pZdeuos+f0JLl8pUiWUmGHL82c73A69hcwm/5/3WQ3eVOxrw2gWGO651b73cewo46mHIg1qclg23EOiL6AaQvh11HkECgNysNDltdPKLfe6GRU837d5CotJr7x5rzN4CDlMlqMUp7Lz88suXHzhw4CN1AygC0WGi8x1y3NCp8To++lXN+uVgqPPgu5ZgLC2AY6rQOA6+4MQvr/3OO++8j+zxGmWPkzRidJq5YuiNvomxoQzLBru72e+pWdS46z7qWjsdYAgmAJhivijYM5cIiaITWD7BLw6dc9ANoGMvv/zy3WSP0zeGevzjo6ryy2H50EKQR7pNnmvx0MvugN/7vuPw3Vucx47RbGv8kA+WeFmwVxAkAnAQjM6wqaJ1kl41sfnTTz99Cva4gjz2OQLk+DBTrjswAbt7r6fhqacbdm6m8cpw9+rCUpZdIgBHfQx5iKkyY8aMJbQh6123Gz9I5WKVwElNnrurK16C+4i39d05NeuXkFz0pgkUZkL+9CcKcMwdQw6acaGATrfPnDnz13TR+ZmCnKQRh4OpYs5Rm9yjXVS2f3ZX3YZfk0g0TsjnZcGEwQ1xJxpw2R7XIKevRJy49tprZ9MDEuVqUxZEHrtjyHNpjRwrJvU+R/nDjZtn13scJ0gaAFyGGwwlRHtD0snY3obOyR00EOTe/fv3r582bdr0pmXv9MVXbpWLTQImklWHQGWRxlY203IB7kaf69CC5p037XDU4osCbXQw4DBvE6q9Mf5kAI564UJAJ1vc1dLSsnFUZctltKOuUEHeIaRY/gfkcBBotq6k+KnzJwKe+mUnym9c13roIA1FD3dCNTfkBZcswGV1Ewxv3bq1rcBk+Xycpd836c+vVUHeMQmx/M+yCgozlkIZkoe2mYrWgKf19ROVt/y55cty6pYebmhuAJ5wlyzA0VGeC/a1zm9z1jaVme17hluKL6HVAgtPXMJHloMVsqxCBJrh4+yA292+tv3Ifz7btAu34WW4E7beHUkMyQRcbhNzEpyXTY5jx+kJly2jrSXTSZPbeeLkAiocXgIsq6Aww2fLiFjY3Cf8nsbX2/bf9mzjLqx1M9xY80463BBCqgEPgr7VWdvQbvCuH28tnUo2eR+eOHRKuegSCMqKTHOY55l44F0mDQHn0eXNX9z8yomKPTSiVjoAOMONmzlJsbup3qBLFeBokJVOEPJyV2PLUW/738+2DbjAZjCV8cVUsHcqEFECgDwoyIi50pOAde46n6NiYePuW9a2HfgH9QJgpxxujD6VgKM9OJ4XzT/gOeHY7W5Yd65t0CS70TRE24nRuWrQkV39H0kCDHmmrK1gZnH7/ZjXsfWRhs23b3HUHKW+682SlGhullmqAQ+Bmzqhndd6He5PHDUfTC48ZXShwXyagpynp3ufzRUIMp0OuwLpWUq6/d72wd21G+fsdzfVUX8YbtzIwQ7BlMINeaQacLQJ1wX0Fr/b9zfnwQ/PKxhUUGKyTjIJo4Enr6OI+j+SBGQ5YcU81Qfgdga8gQpP0/O/qP/4d41eB77yK8ONC8qUww15pQtwtM2Q84VGwEsbyN9srdo60FRYPsRin2wxmOzYS4AHc5WLLoGT5kr0fIlMxY5AvL+k2e9ufK/98Lz7aje9SnPIF5PyHcq0wI2xphNwtM+Qww+CvsFRfaTa2/beuILSM+0G0ynKZIGounephJxNkhpf+7aFjTtvp5WSHdRDaG3W3DBJ5KVAzHHKXaYADrj50KCv8rS0rXFUvXtOwSBTX5P1K8pkiY0NNleSSRNu3sAkKfc0L7+j9sMH97ua8fYpaGyGW795KrbOJyFXugHHkHgu4DPkmjanP3e+Na1V2waa7buHmAsn0/ZRu7YXQ5ksUVE4adIlducKcU0mCW7euBvWOo7c/UDtxr90miQMN9a4+WIyabffow5el5gJgKNLMuQy6Fp4g+PY0cNksoyylgymz4SM7nioS9nmurkMOT0JeUh0j05ga/toiuj78OKQr/W9RY3b57x64stdVBlrbACuv4EDJZV2l2lXb+gPrivxw8OXVgvosNFhp6MQ4TvKzvnni+yn/rLUaB2BJ1/4TzKlKRdGArCVe+PY1m70uw9+7Kz+wx/rt26g+mCCMNS8BMjbXbW/vr1pM5FlMw1wjA19wgHI8SVmKx2AnEG39zfbiu8vu+CasdZ+19HHWAvM2ESqzBYSUXgHDRwv5rxC0ub3uCrI1n6w/tMXGr1OrJBAU+MA2GxrY5WE93LH2xQVTZ7LFBNFP0IWEnwc0Aps0/mcfq/3rbYDO+r9zrUjLMVDaePWCGW26EV48px//Kw5ovl4wxSbI/Ty+Y+fa97zq0WNO9aRzOXlP2hvGW7MT0aYJCdH3RHCWDPZoX9ssrA2Z40Os0XT7HMGnP/1C2yDbulrtI7E64nx7lae1EweXKr7Bq0cybGd7SI7m9a1D3zmqln0WN3nH1J+1tSstbH0xzduWOlErjhSgymKz3TAWQyAnEGHbQ7I2T7XIDebzba7+p1z6STbgGv7GwvGKNBZdNF9GWx6J/eXO5x1z/++aetaejMZg80+r2vLtnZGam15xNkCOPrM2hygQ5sz6ACcYYdf8Kuy8y86zz7g2jKj7SwFOkkkjJPBJlNv9xZH3fOP12/+iLICZBwAm31obIDNdyQBdsZqbepb0GUT4Nxp9BnXDgw6tDlrdA1wOtf828rO+afJtkHXDTLZz7XiNQxUBIXz1XwB1KASa9n0Rilx3Of4fJPz+PKF9Vs/o2gGW/ZlcwRQ84UkBbPDZSPgkKzGKfmy2QKNzkuLMujWG0rPmnRhwZBvDzbbp9sN5kLAni8XpQy1n9AG1I6At51edPnBRlf1G4sbduP2OiCWoUYY2poP2c7OCq1NfQ+6bAWcB4D+A3IGnU0XBp01u6blh5qLi27od8b0Mdb+3xxosp9PoJvwch3Anmvr6Vi/BtRegprA9tX6HJu/dDe+vbhp7wf0RincoGHtDKAZcoaal/2gtbPGHKG+dnHZDjgPSA86TBi20dmEYV/T9FMKTx00q3j0ZSOsfb5ZYrCO0UyYLNbssqbuhBpfS/jyoLvl7f9r3f/O+vajx0kmDDDDLftIg7ZmjZ3VYNM4NJcrgMvjgTbHuAA5NDprdQDO0Mu++Yf9xo2dXDB4Kmn1c/uZCibShWkBPi+CR+gy1ZSRgcbmJzxJQ0t8riafaxdp6883uWo+Xtm0r4LGDG0MeAFzOB/prLFhguQE2DQOzeUa4PK4WKsDdD4Ath54TaNTvJbWz2wr+FHfsRMnWErPG2iyndvfVHAGwW7BBSqA7/jX0QwLL1kXrYAYjg1f+LhMBNC4UCSoPfSmqL21Pufn5Z6GLS83V+xq8jphcjDUAJoPBpzTWFuzxu6ongrkkuM5yqUxyWPB+Bh0va0ua3eGnOPYNw21FRX+oHDcV06zlpxdQvtfCg2mEYVGy1CrMNpZw7Mvwy93AmG9oBlafT6GGPYzQGbfLfyOdr/nSHvAd5B28x2scp/Y+Wr7vu1HnG24qwhIWROzz2DD5zj4DLRsX0fqDmXPbqeXe3aPJnrvGXT2WavLpgyDrfflvNoP5eLiYYMmWctGDjEVj+hrtowsMliG01cayugppEK6k2qnbWCFlNGMxhh81vRsXkAbgywizUuvWWinW+QOT8DX7vL76tsCnkPNXs+Bal/rwR3u+gPrWg/DhmYoZe0rwxsuLOdl84P96BLLgdR8Apynq4O5DqWKMOAFtLIPwBlqhp3P9Xk14DvrCKmbzB3zSGtx0RBjob2fuaCoj8GKHZGiJeBub/K62qr97Y4D7tY2MisAZofyPukzzPBZ68o+wgw0Q4xzOQ+X1ddN2fLD5SPg8syGAEkJMqx6kGXA9WlcDvUhzPWiLTmMc9kxeIjjMGtXBlwPLEPLUPM552ef62NfbjdvwhC+ch0SYFkwkPD14PI5QwzokY99jg9XF1rheEAHx/DpzwEp4gCx7DO87CNNDuMcBxz7HWd5+j8LPE+HH3XYLBv40Q4Zan0+NCDXIzfIAMo+wvqDYdfHy+eoF+fK6STAwtdFq9MIEmB5McjIFi1OTo9QZQiYDCnDizLR4iLVqeI7JcCTowTSOwno5ag/R+36OAZXblkfpz+X86pwDBL4fwN/IZwMBwH5AAAAAElFTkSuQmCC',yellow:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALcAAAC4CAYAAAChOH1KAAAlaElEQVR4Ae2dCZhUxbXHTy+zL8ywDDsSVhEVJQoCkoSIIr4kvohLxO2ZfC8an0mQrCQm+uJ7qHkv5hE/xSQaNokBogkxigaUuLDIpsiOMA4MOwyz7zPd7/yLOZfqnu7p7umeXut83+2qW7du3apTv3v63Lr31rWRkUhowOZViPc6Nutpbq/8WPVO8173sYtJ6kgDusI7yme2nYdTdIZQj0NH1vrgwYNtc+bMyb344otzCgsL87KysnLT0tKym5ub6+rr62vKy8urd+7cWfv444/XlJSUAGSB2VfoKw3HM9KBBqQzOsiSspsEXgmhCMTtDGT2TTfdNDwvL28kQzvC6XSOcDgcQ2w2Wzfenme323M5nuN2uwPql/O5OF+dy+Wq4X2rOV7Z2tpa3NLSsp9Pgv3V1dX7XnnllU/4RKnj7S5edNARl4WjRnQNBFS+njnJ4wKxHtp37NgxpG/fvlPY6l7CAI/kZTgv/YMBN1L64hPAzcAf5eUTXvax9d9x/PjxtZdcckkxH0OAF8gljNThE7acVIdbQLZzDyJuX7du3YChQ4dOycnJ+QJb5M+zFR4Qr73L1v4IW/h3amtr/3nw4MG1kyZNOsJ1FdglBOwpKakItwfQTz31VN4dd9wxnd2LL7J1/hzDPCxRSWDYD7BVf5fdmbeXLl26avbs2dXcFsCdkqCnCtwCNEL7gAEDnBs2bPh8QUHBnenp6TdyWi4vySY1TU1NKysqKl6cMGHCO0eOHGnhBuqQJ71FT3a4FczcqQgdu3btGtWvX787MzMzv8YWun+y0eyvPWzRjzY0NPzp2LFjL44ePXoP52vlRbfo/nZN6PRkhdvyoX/7299245GNe9iHvoMvBC9P6N6KQOX5gvRD9tGX8gjMovvuu6+SixRrjjCpJJngRluwAGz78uXLu0+dOvXbDPW3eL2QFyOeGihnyOevWbPm6VtvvfUsbwLcAnpSuCzJALcH1KtXr+4zduzYWbm5uf/OnZWMvrQnouGv1bD8ftu2bf937bXXnmgDPCkgT3S4lZXmDrGvX79+0EUXXTSbRz3u5fXM8Ps85Upo4FGWBbt3735q4sSJh7n1YskRJqQkKtyoN8B2vPzyyz2uueaaX2RnZ9/NN1bSE7IX4qjSfMOoqa6ubvFbb7318xkzZpRx1XDxKZY8jmoauCqJBjfqi8WB4bzNmzf/W/fu3R/j9R6Bm5o6OWyuErK1fMiKwuhfJ8VNZWUVtT/77MTHFrYNI8oIS8L444kEt7ggju3bt182bNiweXwHcXwnuy5pdwPYzrofMdiR8SaaW9wffFLc+N3RE/7xEStNrHhkCu/iXkgEuFFHBfb8+fMLb7vttkf4YvGb7II4u1g3CVm8vXEpORtfiGzdbbaWmpqW3724ou4/v/WDj8u5cMAd965KvMMt1tp56NCh24qKip7gmy99IttzyVWao3ERYekKcbnpxKmy5h/3HbVpGZcvdzzj1ooDnngUnHQOLI8++mhBZWXlC3369FlowI5tV9lt1KdPz7SFdaUTXnj00REF0kccxqWRjMdKWWBv2rTpUn7YfwnfWRwZ225NnKN3peXWtdDion0799TedfkXPvqY0+GLywWnni2m8Xiz3KgPLLbz6NGj3xgzZsw7BuyY8uH34E47jRxzUc47J/eN/wb6ixf0W1zxFC+VEWvtnDt3biE/ybagZ8+ez7CysngxEqcasNkoq6i785m6w1ctmDt3GB5xEMjjwiOIh0qgDjjJMG49hp9ae5Gt9fA47c+4r1a03BJvRbS43J/s3FN3R5ubIhebMR0Tj7XlFoudtm/fvmsuvfTSNQZsb2wSY91ptw0fMzrnrYObr7iGa5zGC9yUmBrPWMItYGOY7xZ+W/wvrIw8XowkqAa4Q/M+MzjjL0d2jL+FmxBzFyVWcOO4OLPT+AH6b/ELuAs5bp4LYSUkujDg6f37Ohee3ncVHjUWCx4TzmJxUAE7/eTJk4/06NHjKb7bGIt6JDpH8Vt/N9l7dnc8dfaTcY9wJWG0YjKSEm2oFNh80ZhRVlb2NL/D+KP47SFTs3A1UFiQ9qOakglPjx7dKyMWgEcTbgX2+PHjs3j6hCX8fMjXw1We2T/+NZCTY//65jeGLRk/vjuGdaNqwaN1NavA5salnz179jl+9evO+O+WxKxhrIYCA2mrtq71xdwLNt7P+Zp4kacLA+0W1vZoWG4BO4197McM2GH1V8LunJPtuLP84FWPcQOidpHZ1XCjfCxppaWl32Ef+6GE7R1T8bA1UJDveOjUnvHfAQ+8CBthl+uvgK6EGy6PAru4uPj23r17z/VXCZOeOhro1cs5t3T7uNu5xQJ4l7nGXQU3KqzGsfmF0+v79+8/P5oTR6YOKgnYUjfZ+vdLm7/vg7HXtwEOTroE8K6AWyy2kx9ZHTdkyJAlbY1IwJ4wVe4KDTAgacMHZy3Z9vbl47h83MkEhxEHvCvgRpnOefPmFfF49lLMU83rRowGPDRgs1POpRdlLZ33xJAi3iCAe+QJdyXSZ4sCmyuVwY+truA5RKaFW0Gzf2gaiNehQH+tqKt3vZkzaAOeRWnkRZ4m9Jc9pPRIWm6cKMrPPnz48HcN2CH1Q8pmzs6yTzux+8rvsgJkiDBiBjdScAvY8LOv4hd58UyBEaOBoDRQ1DPtEfa/r+LMEX2SMFJwoxzHE0880Yv97AXsZ6OSRowGgtIAeLl0VNaCJx4d0ot3wL9/RLiMxF8AKgKY4WcvY3dkOseNxEgDieZz62qqq29dlTNo422cFhH/O9wzBCeHgptfOHjAgK13lYmHqoHsLMf0ozvHPcD7yehJWMY3HLgtsBcvXnwB34F8ONTGmPxGA94a6FuU9vDiZy6+gNPDBjxcuNXoyA033PA4+01mLmzvnjLrIWuA36jP/dcb8h7nHcMePeks3JbV3rp167X8sVF8NMmI0UBENJCXa7/xo3fGXsuFhWW9Ows39nNed911uRdeeOEvI9IiU4jRgKaBi0Zk/vK663rDGxDAta3BRTsDt2W1n3/++Vk8jfDQ4A5lchkNBK+BNKdt6OJfD5rFewjcIV9chgq3BTZ/UGkY36wxz2cH318mZ4ga4Js7Dy1fMHpYZwHvDNzqIpI/1fEkX0Sab8+E2GEme/AasNltmdO/kP8k79Gpi8tQ4Las9rvvvjuBXxe7LvhqmpxGA53TQE6O7bp1r4+RW/PgNWj3JFS4ldXmW+zfY6vdudqavYwGQtAAOONb89/nXUK23sHCbVnt119//TKelmFqCPUzWY0GwtJAbq596j9eueQyLiSki8tQ4IbVdl555ZWzOTRmO6zuMjuHpgGbbfxlOeAOcIPDoPgLBm7LavM3H0fl5+d/KbSKmdxGA+FrID/P/qWXXxw1iksK2noHC7ey2pMnT8bQXzD7hN8aU4LRgIcGbPYpV3UDf0Fb70CgitV2LFq0aAhb7RkexzMrRgNR1ADPezJj0fyLhvAhYWzBbofuSbBwO6dOnfogX7miUCNGAzHRAA+cOP5lSt6DfPCgXJNg4HawO5LDs0XdFJMWmYMaDWgaKChw3DR5ck/MqBDwwrIjuMUlwTQN0/lzHvjuoBGjgZhqwG6ngmfnDsTbXgGtd0dwY5u6kBwwYMCt5qZNTPvUHLxNA+BwYP/0W3lVLiz9MuxvA6w2FsecOXN68fPaX2wr2wRGAzHXQF6O44tzZlsvEwur7erVEdzY5rz77rtv5s9S49anEaOBuNCA3W5L+/rt3W/mynTomnQEt3JJ+JvrmA3IiNFAXGmgX1FawC+m+YJbzLxjyZIlI/mNdtzTN2I0EFcayMqyXfbS7y4cyZWSURNw6yH+4MYOjokTJ95iLiQ99BX3K271Tx331Qy7guBy0vg8WG/FKoft4IbP4i3IpPztwsLCz3tvNOvxrYEW23iqKPs9VxKfnUlc4fncPSrvtUpYb2lygU+/frc33JZLcs899xSwS3KpxxFSdMVWv4dsle+Qzd0c9xqAGevm/AJVVBSTy+ViCDwhQQN8JLVLc1P7/bz39VXOuTye+/rK5zvNcz+U1ZG4XO5Lb5teWbBs1QHMUCXsWoV4w42yYLUd99133yQ2/dBVSoutbhc5997MmkscS4hOK2hxU1mlb7h9daj3f7r3uq99Yp3GJ67jnqktk5atopVcF3Dr0UnecKNNCu5+/fpNNv42m4PyN8jWdDTW/Rjy8TF22yPLTWeriFyWLQu5mLjeAbD26eaezMHfeQG3SLJaiwRdsK7g5icAJ+kbUjVuc+OziYkpPD0Cdc/nDk0EM9xJFedn2ybyrvizEnatknS4oQIsjlmzZvXMzs6+0MplIgmrAQHcwT0tHZxMYXaGe9QDX03vCW55kaap/vIFt33mzJlXt2VUmcxPYmsAgBfmsWkD4Nz9SbbYvnq1G7yC5Q7hRgYH35W82vjbiQ20d+11wL23JfI6OO1TSIBbXBMArsTbciu4eU4Sc1dSNJREoQKcZ9+DBY+U4F8AIv8GEleJUfrJyiTw2g5uGS0R2hXcPL79mSjVyxwmyhpwwkXJdVNFTeRGUQRwNEXiEkajedkZBF4FblUN/nHr5zDi9p/85Cd92NSzh2YkWTUAwAtgwcWkJXhD+UTKm3VLWh9uhmJYmiNwo5lY7Pw8yXDZaMLk1YAArkZRuOdhaRN5mXSxDdyCZ2FZrUgPKrj55s1QczEpKknuEIB347cRYcGFiEQMUf++3V1DubcEbtVx7Sw3v3UzLLm71LRO14AADqudyJKbaQO3ArdqjQ434naeB3CIsdyJ3M2h110Aj+QoSui16Pwe4DUnm4ZwCYphDhXcGC2Rcxahg0dKkMlIimkAgOdnu6mqzvdTg/Gujqx0G7jFiInFM0iHIME+atSo9MzMzAEqxfyknAbOAc4gMBWJdnGZke4eMOozmengmBcFuA63bdq0aYV4jDDletU02NIAAM/LOge3lZgYEceUMa2FXFWAbcEtKzaen4RHP42kugYE8M6Mg8uFqVh+6FLSfOlVtnU2v+yHcFCRG/xaPOt3KG29evUyN2989UAKpgHwXH4evKZee0A6SD0IsMgucQl9FaFvk7iEgfLr27vnucGvwK38E9lu42FAY7lFGyYkZcGz2YkFLgkg+TkOsdyqtjJaomjnZ7gN3AnQidGsosOhWXDrHZdo1iC4YwHgzEzfbglKsBm4g1NkquUSwGsb4neYEG5MTjp5WG6P0RIeBswxN3BSDd3g2gvAc/irox35wsGV1DW5UK/0DDemNlZeCI5ijQkikT91jY1GjAZ8asAX4AI7Qj3us4BOJOpl6nFfRaU77AI3Ntv00RK+gDBw+1KaSTuvgXOAu6mOZwqRuUcEOuSSuITn9+x8TC9L4hLqpTqdynIjCdbbc+6t1tbWFiQaMRroSAMAnF/MpXoA3lHGKG9rddk8+BWfG9WwNTU11fqaoSjKdTSHSwANAPCsjDYTGQf1xb9IYzPVclWU1UaVdLipoaEBG40YDQSlAR1wuYrzDlGQRZuPUmWb937+1r3L0/fnuQM9+NXhdhu4fWjfJHWoAQtwocwrtyQHC6vX7u1WvctDBkmrb7YBbstTErhVQl1dHb82asRoIDQNAHA8j+frIi+0ksLLzRe5wq/iGaMlQrq7oqLCw6yHdyizdypp4JwFd1MDzz4noyjRbD9OrMpaD8vtlqFAAO4uLy8X8qNZL3OsJNEAf6uGLfg5wKPdJMBdXuMCv4plHF/cElWX06dPV5vREqUK89NJDZwDPPouCv4tTpVTtV5tgVvRvnv37hoDt64eE++MBgB4Bs+hDGvqvaA8pIlIXPIhXdIkjx7KNskvIa4q9xyyA24Py40ViHvlypXVPNbNMzobMRoITwMW4F7FeMOJzZKmxwVa71DPg7hIczNVvba+SdwSJFszTgntbh4xKTHWW1RmwnA0AMDTYcG5kK5ccAXLIyUlfBiLY9Rb3BLEscFVW1tbghUjRgOR0IAFuOaKRKJc7zJqG2wlnObiRTwRBbfQjg0uHg781Fhu1oSRiGkAgKfxuJy3ixGpdVS0qtb9KQeKYQ4V02K5BXA3j5gUI7MRo4FIakAAj2SZelmnKuggr1scYxvg1hNaecTkoLHcUI2RSGtAAI+UxZZyUM89h1wwyviamcWzWG5sVyZ94cKFn/L3CxE3YjQQcQ0AcCfPjAMwIyVMq2vhasenXJ5iWMoVuIV2165duxp4xOSYZDCh0UCkNaADLtY3nLC+yXZs14EmfsPTuqAEz9ZoiQU3p7XW1NQY1wTaMdJlGsC7urDg4Qpc6JoGN/xtuCSw3MKyB9xi0l0nTpzYbPzucNVu9g+kAQE8lDFwlOnh0TDKJ8tsmznZ4pfjHpYb+yABGVq3bNmywbjdUImRrtYAAHeE4IML2HJC4OvIW/e3buB66pZbVbudz41MP/3pT3fziwvmNnxX96wpX2kAgHd2ZtnGFqr68QuO3eCWF59uCQ5iWe7q6uqms2fPbjWuCdRiJBoaEMBDORb4LKugLYwrvmGuw62KEcuNFQtujrccO3bsAwO30pH5iZIGBPBgR05QrWNltk0c4K33gHADcGRq2bBhw3rjd7MmjERVAwAccAcj8LfX7Wxdz3kFbvCLRYleDOIYnOEX9tWca93OnDmznmd+7aFypuiP48jjhMVIdDUQjNdQVecuK7iheSLXrJIXPO7KM6ko46wAl9fMOE0Rj0Q1YsJhC8O9mT+Vfb09Ub8EhFaFKc2taVReYRmDMEszu4eigY4Ad7HZPnyKMAQoVtvjYhLH0eHGusCNHVr27du3euDAgRGF21axm2zH1pLN3Yzjxb3YG89Qel02PzIM3bUXf9jjtSdf4i8def3s4veFW39l+StHHaODjaGW5zd/R8fw08pQy2ppddOuva2rGVPFKrdN4EYzlehuCRKwDuB5Pk/KGzlyZM/169e/z5/vi8gXFwC28x9fZrDh1ieOVNW7cBcscSqcAjWtbXRXf/l/K6/ed6rpDDcXr5fh9jtAtzrKl+XGRtDXzJa77siRI6tHjBhxUyRcE9vhV8lWe4SLTizJR3XZLtRiwMlIzDWAx/qOn6HV+04Rf1iQ4AKAV3Brgc1x6/Y74iIw71hwFjTxqMlKniBTtoUV2lyJS0c+f+GLJzc3EgcaYI+EthyilVwVAAVOhVmP2unj3LJBLLfyZe6///5NVVVVRzty7mXHZA8BeC6PJcF3M0tsdADbzF94OPq9P5OMb4NTsdweCPqDWwCHyW8uKSl5zcB9Tm95fDWSg8FSIzHRAC48SyvoNT64YpNDARvMeogvuJEBZh474axo5ikf/trM784bOacBATzYO2kmH1t5/quLxNLCCK/aSX8Fl7yI1Qav7cQf3DgLLL/7ySefLC4rK9turPd5/QHwbOODn1dIFGKw2uW1tP3/3qZiPpzub7ez2qhOMHDj7GjasWPHSy1qSBG7GYEGlAVnwI3/HR0dtLK53XWCXmLVC9hgE0Y4JLg5v9oBO8L8N82cOfM1nvah1FhvqOa85BoLfl4ZXRiD1a6sp9L7lil/G3CDS79goyr+LDe24Wyw/G5+9axh+/btf4jUsCAOkCwigEfCpzRl+PbN8ZDUzhP0h5oadbNG97d9Wm2wFQhuAVxZ729+85t/raysPGmsd/vTEoBn8dRhRiKvAWW1G+jk7OXqQlKstt9REqlBR3AjD8w+CgHcjUePHq3duXPnImO9WRs+xFhw31Y33H8jWO29J2jR0Qr1QSc8+QcewSX49CuB4IblRgHqopLDxm9/+9sr+E2dMmO9fesUY+DGgvvWTWdSYbVrmqjsxytpBfjjRS4mO/S3caxAcCOPWG8FOD9vUrVnz54XjfWGanyLAG5GUcIfRcFzJPtP0ov7jhPe6RWwA1pt9EwwcIv1Vn4379M4Z86cl9h6VxrrDRX6FgW4GQf3rZwgU2G1qxup8ud/V8N/YrXBYUCrjUMEAzfyifVWvvfGjRvLN2/e/LS5awnV+Bfc5MnCOHiE7s6lWjktTN22Unp6awmVs5aD9rWlR4KF29t6N8yYMWMFT96z07xnKar0HQLwTDOK4ls5HaTCHTlVTTvvWqR8bTyrLaMkQVltFB0s3MjrYb358yL1y5Ytm8vzm7iMewL1+BcB3PjgwfnguMPC85G4Xt5Gc3nShnrWbMhWG70RCtztrPfDDz/88f79+/9sLi79gy1bBHBZN6F/DeA2+4Ez9OdfvE4fc65OWW2UHgrcyC/WG38ROJsavv/97/+Gb8ufNdYb6ulY4H/DRUk13zmU9kKDlY109sd/pd9wFGDLhWRQIyTYXyRUuGG9cRAMC+Kg9e+9914ZX2D+mt0UXjUSSAMAPMP75b5AO6XQ9iama0sJ/XrjQSrjZotLAt7AHfgLWkKFGwUL4GrkhNfr+eJyJd+93Gbck+D0LoCHYtFSIS/uRJ6oom23v6BeIROwwVnIYKMnOgs33BPrriXHG+bNm/cIv45WY0ZPoNbAIoAHznk+By5IIXJhKnGV2JYuaXpe2R4o1PfR4/720/PocX/5O0rH6EhlA9U88096hPPp7gg4A28hWW0cqzNwYz/xvS3r/dxzzx1cvXr1L3j0hOfZCLkeKDPlBP43XBSAEcwCBQlEelz21dP0uGwPFOr76HF/++l59Li//P7S20ZHaO0++sXv31cfbvK22uAtZOks3DgQDijWG2da/V133fXm3r17l5ubO1BPcALA01PcB29mp4OnaVj+jcX0JmsNYMsIiVjt4JTplSscuGGeAbhYb1So7pZbbvnV8ePH9xr/20vTHaxaFpxNWyr41nob4WefrKG9dy6kX4EfXsQlAVfgq9NuQAS+SsKHPy829rt5gquWDydMmPCVjIyMdMzaKWI/8S5hMdJeA+r7MNyN6GwR0Zy/v/NIp+O4ckw9LsfR0/S4bA81xAx1VQ1U+8s19K1/7qVjXGYtL7Dc8oCUpg0cMTQJx3LjSDi4t3tSN3/+fPjfjxn/O7TOyGAXJQ2f0ODdsEAkPLfWtb9yLH/HD7Q9lNrhsqyBnY639tJjv39X+dlitQXssKw26hIu3ChDABf3BGdeHfvfq/jR2BVm/BsqCl4E8OD3SMycGM/ec4JW3LuYVnELADa4wb2TsN0RLkNJJOBGQTjLMBbpAfj06dOfLC4uft8ADhUFLwAcF5m6b5pMcVxAlpyl9298jp5krXiDDY7AU9gSKbhREVhwffSkjt+3rLn55pt/WFpa+rEZQQmtrwA3XJRkE4B9pJw+/trz9MPKOjVhvLc7Ao4iIpGGW/xv/L2o0ZMDBw5U8HyDD/HjscUteEDXSNAaEMCTxWrjgaiT1VT84Ev00IFTVMGKELDBiwz7RQzurrYNqqKHDh1q4tvzGyZfmHVNbsUHufz5byNBasDRZn7kvpiuOokj9LXgEJJHj/vKK/kk7Ex+7KOLlIUQdyBP19CJOa/Q/W/soSOchJERwB1RP5vLs6Qr4PZ55vHFZb2r1b1lXNHRa/muXKYB3OqDgBFfgOvg+CtAz6PHuyo/jqEvOA7WYbF5GrSKX71NDyzaQAc4SYb88O+O67SI+dlcliVdATcKB+CyyMFsH+w6WsnTAO+8pD9dx4CnGcBFNYFDAVwfBw+8V+xzAGyeKar+D+vpu798k7ZzjWCtxR3Rh/0iXtmugluvqECO0MbPD5zpmUs7RvamKQx4Rgp/S0rXUVBxAVwpkk1ivPviAPtsPVUv2Uizfvaq+jgToBarDbBhsdGcLpFowo0GqIas3kOnud0fjBlAk/nWc450Wpe0MMkKFV3BB9ddgHiLtzC27GOfmvcWPTj3DfqIuwFQY4ErolvshIab22KdnWiIasyGYqrkZwreu/ICmsivYBVIpyGzkY41IP92cpHZce7ob23icY/jVXToZ3+jB55fR59wDfCNSN1iR3xkxFcro2G55bhyhlqAf3yEanccp7WfG05j+XszRQAcf7VGAmsgHgHHyQawedqzXQ8up/949WNrVEQHO2J3IANpKZpwS10EbhV+eoYaV++lt68dRaPyM2mAAVzUFDgUwJEz1v436oBb6p+W0cZbX6CHNn1KpzkJUMPP1h+GYo/U+ifnaNdJtOHWwZZGus/UUMufPqS114+mfvkZNNxpLHjQPS6Ax9JFwRh2Hdtjnqzy9WnP0k9Ky9QNmpiCDQVGG27pNB1yxF31jeT63Xu07ooLqLx3N7oy3UFO6TjZyYS+NaAPqUbbgquhvkZq5FGwX13/ND3L/YgPnsLH9jXch76OmsQKbjRQQd0WWrAv30r7bXbaOLIPXZHppG7GTQmOBQ/AeZeuHj1B7/HEOXSikg4/vZZmzV5Ba/mwsNbiX8uoiNygQR9HVWIJtzQUjYaLYrkp6w5QOfvhb04aSn3YDx9m3BRRVcehAN7VFCk3hAfz9p6kN29fQD9Y+REd4poJ2GKx9TuPXV0ln4qJNdxotPeiQD9dTc3sprw39gI60zufxsFNkb9cny0xiUoDMtrUFTTBr1e30huo8e399D/TfkPPcj9V8oF1/1qeFRGLHbOeiTXcaLj0g1hvPXSv2EqfuG20bngRXc43fAod/H8rHRgzrcX5gS39tOlKjEI4IcDGmzPHKql43ts0i7/g+y6rQe44yoiIgC19GFNNwTWLF0FdcLJh4cf1Cd/p5Q9SqyW7ex7lLL2X7vjsILq3WyZ/vIBzWZ3ImYy01wDch3AFUOMZbJ5TpH7rYVrAs64uPVvtYan1N2hgrbGIwQr38GHtHw+WW28AlCKLnP0IW+ubyLX0A9pxqIzWXNib+vLk7oPlYtNArqvwfDwcvYgLUsu2eP9pemfOSvrBwyvpHe4HuCAyGgKwvZ/siwuwoYV4styojwieYsaCGT14dj1lxfl7YZYlz3j2drr6Xy6m2T3zqD+PqpAZNmTt+BGAiiVYgcWHC8L3H46+toOeenAZvc/7wuUAzAI01vVnRCLwP8ElRlDiFW40EXUTwAVyAG4tA3tR3oI76J4xA+mOvHTKgKtiIIfq2kswcANquCDVTdTIj0YsvXcpLSo9rcatYZ31RaDmU8Aa5Wp/0BinxDPcUA3qhwXuEwCHLw5LbgGO+MyraNCDk+nuEb1pOrsr6TyyYiBnxXiLP8ABNW6dswvStP8UrXrmPVr8x410mPfXgUYcUGOID1CLbx3CfwLvFUWJd7hFFagnrLhALq4KLjoF9IyvXkb9Zk+lmSOK6Cv8XfZMfl7cQC4a9BECatyIqW6gBob6b0+toT/+5SM1OQ5cDgEbcd0FAdRwQeIWaq6bkkSBG5VFXQVyWHFxVQC4QK7iU4ZTr4e/RLeN7kdfzcugXAU57xnOBRYfIykE1htv8yioG6lm1zH6y3/9nZat/UQ96CQgA2yJ+3JB4h5sdFYiwS1wCeDe/jjAFosOa57+2c9Q4X9/mW4Z3Zdm8J3OQszJJ3c7Uwl0AI0Fkw80sFPBU5iV7zpOL//0VVqx9VP1pTAALEAjrltq8asTwlpz3S1JRLil8gI5XBUs8MdlfFwgV8AX5lHW4zfSxCsG0vUDu9NEfnY8Xax5Ml+Awu0QK13bRE2lZ2n9llJ6g4f11pdXW4+h6hYacfjUcus8YVwQrnM7SWS40RjUXyAXn1wgB+ACucTTxw2mbj+cRlNH9aZp/QroYobcpmZ3QkFcUiJbdLHQ8Bnw0gC7Hu5jFbRzDz8Dwi/nrtlUom6VwzLLIhYa6zrUsNJiqRPCBeH6tpNEh1sa5AtyfXQFcAN6gVydAHdNoAF3j6PpQ3rQlIIcGoxRFoCubg5x5niHXYcZz3wAaIx6VNRSSXEZrV28iVYt2UBHuCkCrkCNdT0O10OsdMJDzW1Rkixw6+0R0MVd0V0WuQgV0MXKO798CRV9bRxdMbQHje3TjS7n0Za+cF0wdq7DjgPFwroDZIgCmkPAjDHpttGO4/zo6YcHy2jbnzbRlld30CnOAmB1qAVoPR1Ay4IjyMLRxJdkg1vvEbQNroq4KwI7ABeovUNsQz7nzHHU78YxdMWQnjSWn0q8LDuNemIObVyQAnbrwpQzQ3Tg9fi5rYF/BV7klLgijX9wIQiYEeKtcn7r5czJKvqo+AxtW7mdtvxxkxq+E+urwytwSyh5BGgu0XI/AlcywXIkM9zSFWLJBXSEFsQcB+BYF+glriBvS7dPGU6FUy+iwcOKaFBRPg3qlkUD89NpIFv4fmzdnQAez1OLK6POLK91bBPLq0IGFxd8AjHSsN5mlVt4/PlYVROV8qQ2paeq6DDPr3d4zW4q4WE7fAsdYAJWAVbiANk7DpiRJjAjVIflMGkFfZAqgrbqC+AF6Ahl8QU20mS7vo86WXIzyfm1K6jfZQNpQEEm5fP0w1lZaZTNw47Z7L9ns4XPZl8+i61+NsOdwQA3svWtY9+4ni1xHfvJdTw8V1fPS2Mz1Vc0UNVHpXTkT1voWE2DB5AAFFCK1RVgBWR9Xc8j+wjMEnJRyS2pBLfekzrkiCtQOdThFaB9wS0nhYRShne5so5jIy4CwCACmncolhWQCpwIJS7wAmyJ+8rrXS5nTx3RFZ46rfZsqQCohwK7Hgr4HaXpZUgcR9PjWBfo9LikIRSQBWZ93V8a0vUyJI5jpKRA6UY8NSAgeoeAGmmBQu/9UDrSvAXwQQRCPRRQA4X6PhI/V6r59al0oxZPDQisSPUVlzQ9lLx6iLi3AEiIHgqk3qHk886rCjA/7TWADjESugZ0vUncO5RSJV3W9VBAlTRZ9w6xXdIkrwkDaKAjxQfY1WwOoIFQdGvADaDMzmz+f6SMYEX4z7hMAAAAAElFTkSuQmCC'};return{FaviconsByHue,};});'use strict';Polymer({is:'tr-ui-b-info-bar-group',ready(){this.messages_=[];},clearMessages(){this.messages_=[];this.updateContents_();},addMessage(text,opt_buttons){opt_buttons=opt_buttons||[];for(let i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined){throw new Error('buttonText must be provided');}
+if(opt_buttons[i].onClick===undefined){throw new Error('onClick must be provided');}}
+this.messages_.push({text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_(){Polymer.dom(this.$.messages).textContent='';this.messages_.forEach(function(message){const bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);Polymer.dom(this.$.messages).appendChild(bar);},this);}});'use strict';Polymer({is:'tr-ui-b-toolbar-button'});'use strict';tr.exportTo('tr.ui',function(){const Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=[];this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;}
+FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_(operation){let task;if(operation instanceof tr.b.Task){task=operation;}else{task=new tr.b.Task(operation,this);}
+if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering(filterText){const sc=this.brushingStateController_;if(!sc)return;this.enqueueOperation_(function(){this.filterHits_=[];this.currentHitIndex_=-1;}.bind(this));let stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{const filter=new tr.c.FullTextFilter(filterText);const filterHitSet=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHitSet));this.enqueueOperation_(function(){this.filterHits_=filterHitSet.toArray();sc.findTextChangedTo(filterHitSet);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_(dir){const firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0){this.currentHitIndex_=0;}
+const N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)return;this.brushingStateController_.findFocusChangedTo(new tr.model.EventSet(this.filterHits[this.currentHitIndex]));},findNext(){this.find_(1);},findPrevious(){this.find_(-1);}};return{FindController,};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;}
+TimingTool.prototype={onEnterTiming(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY)){return;}
+const pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_(pt){if(!pt.snapped)return;const ir=this.viewport_.interestRange;if(ir.min===pt.x){ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}
+if(ir.max===pt.x){ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}},onUpdateTiming(e){const pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming(e){this.mouseUp_();},onExitTiming(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_(e){if(e.button)return;const worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_(e){},isTouchPointInsideTrackBounds_(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas){return false;}
+const canvas=this.viewport_.modelTrackContainer.canvas;const canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom){return true;}
+return false;},mouseDownAt_(worldX,y){const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_(worldX,y,mouseDown){if(mouseDown){this.updateMovingEdge_(worldX);return;}
+const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_(newWorldX){const ir=this.viewport_.interestRange;let a=ir.min;let b=ir.max;if(this.isMovingLeftEdge_){a=newWorldX;}else{b=newWorldX;}
+if(a<=b){ir.setMinAndMax(a,b);}else{ir.setMinAndMax(b,a);}
+if(ir.min===newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_(){const dt=this.viewport_.currentDisplayTransform;const ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;const pixelRatio=window.devicePixelRatio||1;const minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue){ir.reset();}},getWorldXFromEvent_(e){const pixelRatio=window.devicePixelRatio||1;const canvas=this.viewport_.modelTrackContainer.canvas;const worldOffset=canvas.getBoundingClientRect().left;const viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_(e){const pixelRatio=window.devicePixelRatio||1;const EVENT_SNAP_RANGE=16*pixelRatio;const modelTrackContainer=this.viewport_.modelTrackContainer;const modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();const viewport=this.viewport_;const dt=viewport.currentDisplayTransform;const worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);const worldX=this.getWorldXFromEvent_(e);const mouseY=e.clientY;const selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+let minDistX=worldMaxDist;let minDistY=Infinity;const pixWidth=dt.xViewVectorToWorld(1);const result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};const eventBounds=new tr.b.math.Range();for(const event of selection){const track=viewport.trackForEvent(event);const trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);let eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+const distX=eventX-worldX;const eventY=trackRect.top;const eventHeight=trackRect.height;const distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
+return result;}};return{TimingTool,};});'use strict';tr.exportTo('tr.ui',function(){const kDefaultPanAnimationDurationMs=100.0;const lerp=tr.b.math.lerp;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
+this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor(existing,timestamp,target){const remainingDeltaXOnExisting=existing.goalPanX-target.panX;const remainingDeltaYOnExisting=existing.goalPanY-target.panY;let remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.panX=lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalPanY);}
+return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
+this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!==this.goalFocalPointY;},canTakeOverFor(existingAnimation){return false;},takeOverFor(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.scaleX=lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};const MAX_OVERSIZE_MULTIPLE=3.0;const REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;const DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context(){return this.ctx_;},viewportChange_(){this.invalidate();},windowResized_(){this.invalidate();},scrollChanged_(){if(this.updateOffsetY_()){this.invalidate();}},invalidate(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);const typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(const idx in typesToDraw){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+this.children[i].drawTrack(typesToDraw[idx]);}}
+const pixelRatio=window.devicePixelRatio||1;const bounds=this.canvas_.getBoundingClientRect();const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateOffsetY_(){const maxYDelta=window.innerHeight*REDRAW_SLOP;let newOffset=this.scrollTop-maxYDelta;if(Math.abs(newOffset-this.offsetY_)<=maxYDelta)return false;const maxOffset=this.scrollHeight-
+this.canvas_.getBoundingClientRect().height;newOffset=Math.max(0,Math.min(newOffset,maxOffset));if(newOffset!==this.offsetY_){this.offsetY_=newOffset;return true;}
+return false;},updateCanvasSizeIfNeeded_(){const visibleChildTracks=Array.from(this.children).filter(this.visibleFilter_);if(visibleChildTracks.length===0){return;}
+const thisBounds=this.getBoundingClientRect();const firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();const lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();const innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;const innerHeight=Math.min(lastChildTrackBounds.bottom-firstChildTrackBounds.top,Math.floor(window.innerHeight*MAX_OVERSIZE_MULTIPLE));const pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!==innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+if(this.canvas_.height!==innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}
+if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+const trackClientRect=this.children[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
+ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){const modelItem=this.modelItem_;if(modelItem===undefined){return SelectionState.NONE;}
+return modelItem.selectionState;}};return{ProxySelectableItem,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld){if(this.items_===undefined)return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const dumpRadiusView=this.dumpRadiusView;const itemRadiusWorld=dt.xViewVectorToWorld(height);const items=this.items_;const loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);const oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';const drawItems=function(selected){for(let i=loI;i<items.length;++i){const item=items[i];const x=item.start;if(x-itemRadiusWorld>viewRWorld)break;if(item.selected!==selected)continue;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap(eventToTrackMap){if(this.items_===undefined)return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)return;const itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.items_===undefined)return;const index=this.items_.findIndex(item=>item.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex>=0&&newIndex<this.items_.length){this.items_[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)return;const item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;}
+LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack,LetterDot,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Task=tr.b.Task;const ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach(){Polymer.dom(this).textContent='';},get tracks_(){const tracks=[];for(let i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track){tracks.push(this.children[i]);}}
+return tracks;},drawTrack(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(const track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.tracks_.length;i++){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const task=new Task();for(let i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
+return task;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_(){this.tracks_.forEach(function(track){Polymer.dom(this).removeChild(track);},this);}};return{ContainerTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.dotLetter=undefined;this.yBase=opt_yBase;}
+ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype,};return{ChartPoint,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const ChartSeriesType={LINE:0,AREA:1};const DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,solidSelectedDots:false,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5,stepGraph:true};const LAST_POINT_WIDTH=16;const DOT_LETTER_RADIUS_PX=7;const DOT_LETTER_RADIUS_PADDING_PX=0.5;const DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX=3;const DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX=1.5;const DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX=1;const DOT_LETTER_FONT_WEIGHT=400;const DOT_LETTER_FONT_SIZE_PX=9;const DOT_LETTER_FONT='Arial';const ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,seriesYAxis,opt_renderingConfig){this.points=points;this.seriesYAxis=seriesYAxis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_(opt_renderingConfig){const config=opt_renderingConfig||{};for(const[key,defaultValue]of
+Object.entries(DEFAULT_RENDERING_CONFIG)){let value=config[key];if(value===undefined){value=defaultValue;}
+this[key+'_']=value;}
+this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){const range=new tr.b.math.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0){return;}
+if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
+if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_(ctx,transform,component,highDetails){let extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+const pixelRatio=transform.pixelRatio;const leftViewX=transform.leftViewX-extraPixels*pixelRatio;const rightViewX=transform.rightViewX+extraPixels*pixelRatio;const leftTimestamp=transform.leftTimestamp-extraPixels;const rightTimestamp=transform.rightTimestamp+extraPixels;const firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);let lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+const viewSkipDistance=this.skipDistance_*pixelRatio;let selectedCircleRadius;let letterDotRadius;let squareSize;let squareHalfSize;let squareOpacity;let unselectedSeriesColor;let currentStateSeriesColor;ctx.save();ctx.font=DOT_LETTER_FONT_WEIGHT+' '+
+Math.floor(DOT_LETTER_FONT_SIZE_PX*pixelRatio)+'px '+
+DOT_LETTER_FONT;ctx.textBaseline='middle';ctx.textAlign='center';switch(component){case ChartSeriesComponent.DOTS:{selectedCircleRadius=(this.selectedPointSize_/2)*pixelRatio;letterDotRadius=Math.max(selectedCircleRadius,DOT_LETTER_RADIUS_PX*pixelRatio);squareSize=this.unselectedPointSize_*pixelRatio;squareHalfSize=squareSize/2;unselectedSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);if(!highDetails){squareOpacity=0;break;}
+const visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+const visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
+const density=visibleIndexRange/visibleViewXRange;const clampedDensity=tr.b.math.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);const densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;}
+case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+let previousViewX=undefined;let previousViewY=undefined;let previousViewYBase=undefined;let lastSelectionState=undefined;let baseSteps=undefined;const startIndex=Math.max(firstVisibleIndex-1,0);let currentViewX;for(let i=startIndex;i<this.points.length;i++){const currentPoint=this.points[i];currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+break;}
+if(i+1<this.points.length){const nextPoint=this.points[i+1];const nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(currentViewX<leftViewX){currentViewX=leftViewX;}}
+if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
+const currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));let currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+const currentSelectionState=currentPoint.selectionState;if(currentSelectionState!==lastSelectionState){const opacity=currentSelectionState===SelectionState.SELECTED?1:squareOpacity;currentStateSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,opacity);}
+switch(component){case ChartSeriesComponent.DOTS:if(currentPoint.dotLetter){ctx.fillStyle=unselectedSeriesColor;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius+DOT_LETTER_RADIUS_PADDING_PX,0,2*Math.PI);ctx.fill();if(currentSelectionState===SelectionState.SELECTED){ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('olive');ctx.stroke();ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius,0,2*Math.PI);ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('yellow');ctx.stroke();}else{ctx.lineWidth=DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.stroke();}
+ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('white');ctx.fillText(currentPoint.dotLetter,currentViewX,currentViewY);}else{ctx.strokeStyle=unselectedSeriesColor;ctx.lineWidth=pixelRatio;if(currentSelectionState===SelectionState.SELECTED){if(this.solidSelectedDots_){ctx.fillStyle=ctx.strokeStyle;}else{ctx.fillStyle=currentStateSeriesColor;}
+ctx.beginPath();ctx.arc(currentViewX,currentViewY,selectedCircleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillStyle=currentStateSeriesColor;ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}}
+break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else if(this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}
+ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined&&this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}else{ctx.lineTo(currentViewX,currentViewY);}
+if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();}
+ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
+if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
+ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
+previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:{let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;}
+default:throw new Error('Not reachable');}}
+ctx.restore();},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){const points=this.points;function getPointWidth(point,i){if(i===points.length-1){return LAST_POINT_WIDTH*viewPixWidthWorld;}
+const nextPoint=points[i+1];return nextPoint.x-point.x;}
+function selectPoint(point){point.addToSelection(selection);}
+tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x;},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.points===undefined)return false;const index=this.points.findIndex(point=>point.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)return;const item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};return{ChartSeries,ChartSeriesType,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const IDEAL_MAJOR_MARK_HEIGHT_PX=30;const AXIS_LABLE_MARGIN_PX=10;const AXIS_LABLE_FONT_SIZE_PX=9;const AXIS_LABLE_FONT='Arial';function ChartSeriesYAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocateSimple();this.bounds=new tr.b.math.Range();if(opt_min!==undefined)this.bounds.addValue(opt_min);if(opt_max!==undefined)this.bounds.addValue(opt_max);}
+ChartSeriesYAxis.prototype={get guid(){return this.guid_;},valueToUnitRange(value){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+const bounds=this.bounds;if(bounds.range===0)return 0;return(value-bounds.min)/bounds.range;},unitRangeToValue(unitRange){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+return unitRange*this.bounds.range+this.bounds.min;},autoSetFromSeries(series,opt_config){const range=new tr.b.math.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange(range,opt_config){if(range.isEmpty)return;const bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)return;const useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);const useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}},majorMarkHeightWorld_(transform,pixelRatio){const idealMajorMarkHeightPx=IDEAL_MAJOR_MARK_HEIGHT_PX*pixelRatio;const idealMajorMarkHeightWorld=transform.vectorToWorldDistance(idealMajorMarkHeightPx);return tr.b.math.preferredNumberLargerThanMin(idealMajorMarkHeightWorld);},draw(ctx,transform,showYAxisLabels,showYGridLines){if(!showYAxisLabels&&!showYGridLines)return;const pixelRatio=transform.pixelRatio;const viewTop=transform.outerTopViewY;const worldTop=transform.viewYToWorldY(viewTop);const viewBottom=transform.outerBottomViewY;const viewHeight=viewBottom-viewTop;const viewLeft=transform.leftViewX;const viewRight=transform.rightViewX;const labelLeft=transform.leftYLabel;ctx.save();ctx.lineWidth=pixelRatio;ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.textAlign='left';ctx.textBaseline='center';ctx.font=(AXIS_LABLE_FONT_SIZE_PX*pixelRatio)+'px '+AXIS_LABLE_FONT;ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');tr.ui.b.drawLine(ctx,viewLeft,viewTop,viewLeft,viewBottom,viewLeft);ctx.stroke();ctx.closePath();ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('grey');const majorMarkHeight=this.majorMarkHeightWorld_(transform,pixelRatio);const maxMajorMark=Math.max(transform.viewYToWorldY(viewTop),Math.abs(transform.viewYToWorldY(viewBottom)));for(let curWorldY=0;curWorldY<=maxMajorMark;curWorldY+=majorMarkHeight){const roundedUnitValue=Math.floor(curWorldY*1000000)/1000000;const curViewYPositive=transform.worldYToViewY(curWorldY);if(curViewYPositive>=viewTop){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYPositive-AXIS_LABLE_MARGIN_PX);}
+if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYPositive,viewRight,curViewYPositive);}}
+const curViewYNegative=transform.worldYToViewY(-1*curWorldY);if(curViewYNegative<=viewBottom){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYNegative-AXIS_LABLE_MARGIN_PX);}
+if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYNegative,viewRight,curViewYNegative);}}}
+ctx.stroke();ctx.restore();}};return{ChartSeriesYAxis,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;}
+ChartTransform.prototype={worldXToViewX(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX(viewX){return this.displayTransform_.xViewToWorld(viewX);},vectorToWorldDistance(viewY){return this.axis_.bounds.range*Math.abs(viewY/this.innerHeight_);},viewYToWorldY(viewY){return this.axis_.unitRangeToValue(1-(viewY-this.innerTopViewY)/this.innerHeight_);},worldYToViewY(worldY){const innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('chart-track');this.series_=undefined;this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.showYAxisLabels_=undefined;this.showGridLines_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get showYAxisLabels(){return this.showYAxisLabels_;},set showYAxisLabels(showYAxisLabels){this.showYAxisLabels_=showYAxisLabels;this.invalidateDrawingContainer();},get showGridLines(){return this.showGridLines_;},set showGridLines(showGridLines){this.showGridLines_=showGridLines;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_(){if(!this.series_){this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+const axisGuidToAxisData={};let topPadding=0;let bottomPadding=0;this.series_.forEach(function(series){const seriesYAxis=series.seriesYAxis;const axisGuid=seriesYAxis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:seriesYAxis,series:[]};if(!this.axes_)this.axes_=[];this.axes_.push(seriesYAxis);}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_(viewLWorld,viewRWorld){if(!this.series_)return;const ctx=this.context();const displayTransform=this.viewport.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const highDetails=this.viewport.highDetails;const width=bounds.width*pixelRatio;const height=bounds.height*pixelRatio;const topPadding=this.topPadding_*pixelRatio;const bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();if(this.axes_){if((this.showGridLines_||this.showYAxisLabels_)&&this.axes_.length>1){throw new Error('Only one axis allowed when showing grid lines.');}
+for(const yAxis of this.axes_){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,yAxis,width,height,topPadding,bottomPadding,pixelRatio);yAxis.draw(ctx,chartTransform,this.showYAxisLabels_,this.showGridLines_);}}
+for(const series of this.series){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.seriesYAxis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);}
+ctx.restore();},addEventsToTrackMap(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection(event,offset,selection){let foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes(opt_config){for(const axisData of Object.values(this.axisGuidToAxisData_)){const seriesYAxis=axisData.axis;const series=axisData.series;seriesYAxis.autoSetFromSeries(series,opt_config);}},autoSetAxis(seriesYAxis,opt_config){const series=this.axisGuidToAxisData_[seriesYAxis.guid].series;seriesYAxis.autoSetFromSeries(series,opt_config);}};return{ChartTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const CpuUsageTrack=tr.ui.b.define('cpu-usage-track',ChartTrack);CpuUsageTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-usage-track');this.heading='CPU usage';this.cpuUsageSeries_=undefined;},initialize(model){if(model!==undefined){this.cpuUsageSeries_=model.device.cpuUsageSeries;}else{this.cpuUsageSeries_=undefined;}
+this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return!!this.cpuUsageSeries_&&this.cpuUsageSeries_.samples.length>0;},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.series_,this);},buildChartSeries_(yAxis,color){if(!this.hasVisibleContent)return[];yAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const usageSamples=this.cpuUsageSeries_.samples;const pts=new Array(usageSamples.length+1);for(let i=0;i<usageSamples.length;i++){pts[i]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[i].start,usageSamples[i].usage);}
+pts[usageSamples.length]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[usageSamples.length-1].start,0);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:color};return[new tr.ui.tracks.ChartSeries(pts,yAxis,renderingConfig)];},};return{CpuUsageTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_(){if(!this.hasVisibleContent)return[];const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.powerInW);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,seriesYAxis,renderingConfig)];}};return{PowerSeriesTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('spacing-track');this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},addAllEventsMatchingFilterToSelection(filter,selection){}};return{SpacingTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ContainerTrack=tr.ui.tracks.ContainerTrack;const DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate(viewport){ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){Polymer.dom(this).appendChild(this.powerSeriesTrack_);Polymer.dom(this).appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function extractGlobalMemoryDumpUsedSizes(globalMemoryDump,addSize){for(const[pid,pmd]of
+Object.entries(globalMemoryDump.processMemoryDumps)){const mostRecentVmRegions=pmd.mostRecentVmRegions;if(mostRecentVmRegions===undefined)continue;addSize(pid,mostRecentVmRegions.byteStats.proportionalResident||0,pmd.process.userFriendlyName);}}
+function extractProcessMemoryDumpAllocatorSizes(processMemoryDump,addSize){const allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)return;allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')return;const allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)return;const allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)return;addSize(allocatorDump.fullName,allocatorSizeValue);});}
+function extractGlobalMemoryDumpAllocatorSizes(globalMemoryDump,addSize){for(const pmd of Object.values(globalMemoryDump.processMemoryDumps)){extractProcessMemoryDumpAllocatorSizes(pmd,addSize);}}
+function buildMemoryChartSeries(memoryDumps,dumpSizeExtractor){const dumpCount=memoryDumps.length;const idToTimestampToPoint={};const idToName={};memoryDumps.forEach(function(dump,index){dumpSizeExtractor(dump,function addSize(id,size,opt_name){let timestampToPoint=idToTimestampToPoint[id];if(timestampToPoint===undefined){idToTimestampToPoint[id]=timestampToPoint=new Array(dumpCount);for(let i=0;i<dumpCount;i++){const modelItem=memoryDumps[i];timestampToPoint[i]=new tr.ui.tracks.ChartPoint(modelItem,modelItem.start,0);}}
+timestampToPoint[index].y+=size;if(opt_name!==undefined)idToName[id]=opt_name;});});const ids=Object.keys(idToTimestampToPoint);if(ids.length===0)return undefined;ids.sort();for(let i=0;i<dumpCount;i++){let baseSize=0;for(let j=ids.length-1;j>=0;j--){const point=idToTimestampToPoint[ids[j]][i];point.yBase=baseSize;point.y+=baseSize;baseSize=point.y;}}
+const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0);const series=ids.map(function(id){const colorId=ColorScheme.getColorIdForGeneralPurposeString(idToName[id]||id);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId,backgroundOpacity:0.8};return new tr.ui.tracks.ChartSeries(idToTimestampToPoint[id],seriesYAxis,renderingConfig);});series.reverse();return series;}
+function buildMemoryLetterDots(memoryDumps){const backgroundMemoryColorId=ColorScheme.getColorIdForReservedName('background_memory_dump');const lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');const detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){let memoryColorId;switch(memoryDump.levelOfDetail){case BACKGROUND:memoryColorId=backgroundMemoryColorId;break;case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
+return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
+function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpUsedSizes);}
+function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildMemoryChartSeries(processMemoryDumps,extractProcessMemoryDumpAllocatorSizes);}
+function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpAllocatorSizes);}
+return{buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const USED_MEMORY_TRACK_HEIGHT=50;const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_(){const items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)return;const track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;Polymer.dom(this).appendChild(track);},appendUsedMemoryTrack_(){const series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{GlobalMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,xMin,xMax,minRectSize,maxMergeDist,palette){this.ctx_=ctx;this.xMin_=xMin;this.xMax_=xMax;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.palette_=palette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH(y,h){if(this.y_===y&&this.h_===h){return;}
+this.flush();this.y_=y;this.h_=h;},fillRect(x,w,colorId,alpha){const r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_){this.flush();}
+if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_){this.flush();}
+this.ctx_.fillStyle=this.palette_[colorId];this.ctx_.globalAlpha=alpha;const xLeft=Math.max(x,this.xMin_);const xRight=Math.min(r,this.xMax_);if(xLeft<xRight){this.ctx_.fillRect(xLeft,this.y_,xRight-xLeft,this.h_);}}},flush(){if(this.merging_){this.ctx_.fillStyle=this.palette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;const xLeft=Math.max(this.mergeStartX_,this.xMin_);const xRight=Math.min(this.mergeCurRight_,this.xMax_);if(xLeft<xRight){this.ctx_.fillRect(xLeft,this.y_,xRight-xLeft,this.h_);}
+this.merging_=false;}}};return{FastRectRenderer,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_(viewLWorld,viewRWorld){const ctx=this.context();ctx.save();const bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)return;let fontSize;let yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap(eventToTrackMap){if(this.rects_===undefined||this.rects_===null){return;}
+this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);const instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration===0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection(event,offset,selection){const index=this.rects_.findIndex(rect=>rect.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.rects_.length;++i){const modelItem=this.rects_[i].modelItem;if(!modelItem)continue;if(filter.matchSlice(modelItem)){selection.push(modelItem);}}},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;}
+Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack,Rect,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)return false;const cpu=this.cpu_;if(cpu.slices.length)return true;if(cpu.samples&&cpu.samples.length)return true;if(Object.keys(cpu.counters).length>0)return true;return false;},updateContents_(){this.detach();if(!this.cpu_)return;const slices=this.cpu_.slices;if(slices.length){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';Polymer.dom(this).appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(const counterName in this.cpu_.counters){const counter=this.cpu_.counters[counterName];const track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;Polymer.dom(this).appendChild(track);}}},appendSamplesTracks_(){const samples=this.cpu_.samples;if(samples===undefined||samples.length===0){return;}
+const samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);}};return{CpuTrack,};});'use strict';tr.exportTo('tr.model',function(){const Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_(){const objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});const objectsByKey={};const NONUNIQUE_KEY='nonuniqueKey';for(let i=0;i<objects.length;i++){const object=objects[i];const objectKey=object.getSettingsKey();if(!objectKey)continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+objectsByKey[objectKey]=NONUNIQUE_KEY;}
+const nonuniqueKeys={};Object.keys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY){return;}
+delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_(){const settings=Settings.get('trace_model_settings',{});let settingsChanged=false;Object.keys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey]){return;}
+settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged){Settings.set('trace_model_settings',settings);}},hasUniqueSettingKey(object){const objectKey=object.getSettingsKey();if(!objectKey)return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor(object,objectLevelKey,defaultValue){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){const settings=this.getEphemeralSettingsFor_(object);const ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined){return ephemeralValue;}
+return defaultValue;}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+const value=settings[objectKey][objectLevelKey];if(value!==undefined){return value;}
+return defaultValue;},setSettingFor(object,objectLevelKey,value){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+if(settings[objectKey][objectLevelKey]===value){return;}
+settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_(object){if(object.guid===undefined){throw new Error('Only objects with GUIDs can be persisted');}
+if(this.ephemeralSettingsByGUID_[object.guid]===undefined){this.ephemeralSettingsByGUID_[object.guid]={};}
+return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){const numSeries=counter.series.length;const totals=counter.totals;const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const chartSeries=counter.series.map(function(series,seriesIndex){const chartPoints=series.samples.map(function(sample,sampleIndex){const total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,seriesYAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const startCompare=function(x,y){return x.start-y.start;};const FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_(e){if(this.subRows.length<=1)return;this.expanded=!this.expanded;if(this.groupingSource_){const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_(){if(this.groupingSource_){const numSubRows=this.subRows.length;const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){let defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_(){const minH=Math.max(2,Math.ceil(18/this.children.length));const h=(this.expanded_?18:minH)+'px';for(let i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0){this.children[i].arrowVisible=true;}
+this.children[i].expanded=this.expanded;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
+if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
+this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
+const subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(let srI=0;srI<subRows.length;srI++){const subRow=subRows[srI];if(!subRow.length)continue;const track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_(){if(!Polymer.dom(this).firstChild)return;Polymer.dom(this).firstChild.heading=this.heading_;Polymer.dom(this).firstChild.tooltip=this.tooltip_;},buildSubRows_(itemsToGroup){throw new Error('Not implemented');},addSubTrack_(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_(a,b){if(!a||!b)return false;if(!a.length||!b.length)return false;if(a.length!==b.length)return false;for(let i=0;i<a.length;++i){if(a[i]!==b[i])return false;}
+return true;}};return{MultiRowTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_(objectInstances){const hasMultipleRows=this.subRows.length>1;const track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;Polymer.dom(this).appendChild(track);return track;},buildSubRows_(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});const subRows=[];for(let i=0;i<objectInstances.length;i++){const objectInstance=objectInstances[i];let found=false;for(let j=0;j<subRows.length;j++){const subRow=subRows[j];const lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){subRows.push([objectInstance]);}}
+return subRows;},updateHeadingAndTooltip_(){}};return{ObjectInstanceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;const slices=[];for(const slice of this.group_.slices){if(slice.subSlices.length===1&&tr.b.math.approximately(slice.subSlices[0].start,slice.start,1)&&tr.b.math.approximately(slice.subSlices[0].duration,slice.duration,1)){slices.push(slice.subSlices[0]);}else{slices.push(slice);}}
+this.setItemsToGroup(slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
+const findLevel=function(sliceToPut,rows,n){if(n>=rows.length){return true;}
+const subRow=rows[n];const lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
+for(const subSlice of sliceToPut.subSlices){if(!findLevel(subSlice,rows,n+1)){return false;}}
+return true;}
+return false;};const subRows=[];for(const slice of slices){let found=false;let index=subRows.length;for(let j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
+if(!found){subRows.push([]);}
+subRows[index].push(slice);const fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0){return;}
+if(level===rows.length){rows.push([]);}
+for(const subSlice of subSlices){rows[level].push(subSlice);fitSubSlicesRecursively(subSlice.subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
+return subRows;}};return{AsyncSliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_(slices){const precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)return[];const ops=[];for(let i=0;i<slices.length;i++){if(slices[i].subSlices){slices[i].subSlices.splice(0,slices[i].subSlices.length);}
+ops.push(i);}
+ops.sort(function(ix,iy){const x=slices[ix];const y=slices[iy];if(x.start!==y.start)return x.start-y.start;return ix-iy;});const subRows=[[]];this.badSlices_=[];for(let i=0;i<ops.length;i++){const op=ops[i];const slice=slices[op];let inserted=false;for(let j=subRows.length-1;j>=0;j--){if(subRows[j].length===0)continue;const insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1){subRows.push([]);}
+subRows[j+1].push(slice);if(insertedSlice.subSlices){insertedSlice.subSlices.push(slice);}
+inserted=true;break;}}
+if(inserted)continue;subRows[0].push(slice);}
+return subRows;}};return{SliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('thread-track');this.heading_=document.createElement('tr-ui-b-heading');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get hasSlices(){return this.thread_.asyncSliceGroup.length>0||this.thread_.sliceGroup.length>0;},get hasTimeSlices(){return this.thread_.timeSlices;},get eventContainer(){return this.thread;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_(){this.detach();if(!this.thread_)return;this.heading_.heading=this.thread_.userFriendlyName;this.heading_.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length){this.appendAsyncSliceTracks_();}
+this.appendThreadSamplesTracks_();let needsHeading=false;if(this.thread_.timeSlices){const timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent){needsHeading=true;Polymer.dom(this).appendChild(timeSlicesTrack);}}
+if(this.thread_.sliceGroup.length){const track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent){needsHeading=false;Polymer.dom(this).appendChild(track);}}
+if(needsHeading){Polymer.dom(this).appendChild(this.heading_);}},appendAsyncSliceTracks_(){const subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){const asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);const title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent){Polymer.dom(this).appendChild(asyncTrack);}},this);},appendThreadSamplesTracks_(){const threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0){return;}
+const samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);},collapsedDidChange(collapsed){if(collapsed){let h=parseInt(this.tracks[0].height);for(let i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(let i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const OtherThreadsTrack=tr.ui.b.define('other-threads-track',tr.ui.tracks.OtherThreadsTrack);const SpacingTrack=tr.ui.tracks.SpacingTrack;OtherThreadsTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.header_=document.createElement('tr-ui-b-heading');this.header_.addEventListener('click',this.onHeaderClick_.bind(this));this.header_.heading='Other Threads';this.header_.tooltip='Threads with only scheduling information';this.header_.arrowVisible=true;this.threads_=[];this.expanded=false;this.collapsible_=true;},set threads(threads){this.threads_=threads;this.updateContents_();},set collapsible(collapsible){this.collapsible_=collapsible;this.updateContents_();},onHeaderClick_(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},get expanded(){return this.header_.expanded;},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;this.header_.expanded=expanded;this.viewport_.dispatchChangeEvent();this.updateContents_();},updateContents_(){this.detach();if(this.collapsible_){Polymer.dom(this).appendChild(this.header_);}
+if(this.expanded||!this.collapsible_){for(const thread of this.threads_){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}}};return{OtherThreadsTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)return[];const ops=[];const pushOp=function(isStart,time,slice){ops.push({isStart,time,slice});};for(const tid in process.threads){const sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});const rects=[];const genericColorId=ColorScheme.getColorIdForReservedName('generic_work');const pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));};let depth=0;let currentSlice=undefined;let lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice===currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth===1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!==lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth===0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;const ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;const SpacingTrack=tr.ui.tracks.SpacingTrack;const ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;Polymer.dom(this).classList.add('process-track-base');Polymer.dom(this).classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();Polymer.dom(this.processNameEl_).classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});Polymer.dom(this.headerEl_).appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));Polymer.dom(this).appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){const modelSettings=new tr.model.ModelSettings(this.processBase_.model);const defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return Polymer.dom(this).classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;Polymer.dom(this).classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)return;const modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded){return this.children.length>1;}
+return true;},onHeaderClick_(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_(){this.clearTracks_();if(!this.processBase_)return;Polymer.dom(this.processNameEl_).textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},willAppendTracks_(){},didAppendTracks_(){},appendMemoryDumpTrack_(){},appendSummaryTrack_(){const track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendFrameTrack_(){const frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)return;const track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;Polymer.dom(this).appendChild(track);},appendObjectInstanceTracks_(){const instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();const instanceTypeNames=Object.keys(instancesByTypeName);instanceTypeNames.sort();let didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){const allInstances=instancesByTypeName[typeName];let instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);let snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView){instanceViewInfo=undefined;}
+if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView){snapshotViewInfo=undefined;}
+const hasViewInfo=instanceViewInfo||snapshotViewInfo;const visibleInstances=[];for(let i=0;i<allInstances.length;i++){const instance=allInstances[i];if(instance.snapshots.length===0)continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)return;let trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+const track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}},appendCounterTracks_(){const counters=Object.values(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){const track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_(){const threads=Object.values(this.processBase.threads);threads.sort(tr.model.Thread.compare);const otherThreads=[];let hasVisibleThreads=false;threads.forEach(function(thread){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;if(track.hasSlices){hasVisibleThreads=true;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}else if(track.hasTimeSlices){otherThreads.push(thread);}}.bind(this));if(otherThreads.length>0){const track=new tr.ui.tracks.OtherThreadsTrack(this.viewport);track.threads=otherThreads;track.collapsible=otherThreads.length>1&&hasVisibleThreads;Polymer.dom(this).appendChild(track);}}};return{ProcessTrackBase,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Cpu=tr.model.Cpu;const CpuTrack=tr.ui.tracks.cpu_track;const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const SpacingTrack=tr.ui.tracks.SpacingTrack;const KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_(){const cpus=Object.values(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);let didAppendAtLeastOneTrack=false;for(let i=0;i<cpus.length;++i){const cpu=cpus[i];const track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}};return{KernelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocateSimple(),model,getSettingsKey(){return undefined;}});},buildSubRows_(slices){if(this.subRows_.length){return this.subRows_;}
+this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;}};return{InteractionTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const LetterDotTrack=tr.ui.tracks.LetterDotTrack;const MemoryTrack=tr.ui.b.define('memory-track',LetterDotTrack);MemoryTrack.prototype={__proto__:LetterDotTrack.prototype,decorate(viewport){LetterDotTrack.prototype.decorate.call(this,viewport);this.classList.add('memory-track');this.heading='Memory Events';this.lowMemoryEvents_=undefined;},initialize(model){if(model!==undefined){this.lowMemoryEvents_=model.device.lowMemoryEvents;}else{this.lowMemoryEvents_=undefined;}
+if(this.hasVisibleContent){this.items=this.buildMemoryLetterDots_(this.lowMemoryEvents_);}},get hasVisibleContent(){return!!this.lowMemoryEvents_&&this.lowMemoryEvents_.length!==0;},buildMemoryLetterDots_(memoryEvents){return memoryEvents.map(memoryEvent=>new tr.ui.tracks.LetterDot(memoryEvent,'K',ColorScheme.getColorIdForReservedName('background_memory_dump'),memoryEvent.start));},};return{MemoryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{ProcessMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:{if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0){break;}
+const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;}
+case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_(){const ctx=this.context();const canvasBounds=ctx.canvas.getBoundingClientRect();const pixelRatio=window.devicePixelRatio||1;let draw=false;ctx.fillStyle='#eee';for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
+draw=!draw;if(!draw)continue;const bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_(){const processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){const pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.VSYNC_HIGHLIGHT_ALPHA=0.1;ModelTrack.VSYNC_DENSITY_TRANSPARENT=0.20;ModelTrack.VSYNC_DENSITY_OPAQUE=0.10;ModelTrack.VSYNC_DENSITY_RANGE=ModelTrack.VSYNC_DENSITY_TRANSPARENT-ModelTrack.VSYNC_DENSITY_OPAQUE;ModelTrack.generateStripes_=function(times,minTime,maxTime){if(times.length===0)return[];const lowIndex=tr.b.findLowIndexInSortedArray(times,(x=>x),minTime);let highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
+const stripes=[];for(let i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){const left=i<lowIndex?minTime:times[i];const right=i+1>highIndex?maxTime:times[i+1];stripes.push(tr.b.math.Range.fromExplicitRange(left,right));}
+return stripes;};ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('model-track');this.upperMode_=false;this.annotationViews_=[];this.vSyncTimes_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_(){Polymer.dom(this).textContent='';if(!this.model_)return;if(this.upperMode_){this.updateContentsForUpperMode_();}else{this.updateContentsForLowerMode_();}},updateContentsForUpperMode_(){},updateContentsForLowerMode_(){if(this.model_.userModel.expectations.length>1){const mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;Polymer.dom(this).appendChild(mrt);}
+if(this.model_.alerts.length){const at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;Polymer.dom(this).appendChild(at);}
+if(this.model_.globalMemoryDumps.length){const gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;Polymer.dom(this).appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendCpuUsageTrack_();this.appendMemoryTrack_();this.appendKernelTrack_();const processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(let i=0;i<processes.length;++i){const process=processes[i];const track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();this.vSyncTimes_=this.model_.device.vSyncTimestamps;this.updateAnnotations_();},getContentBounds(){return this.model.bounds;},addAnnotation(annotation){this.model.addAnnotation(annotation);},removeAnnotation(annotation){this.model.removeAnnotation(annotation);},updateAnnotations_(){this.annotationViews_=[];const annotations=this.model_.getAllAnnotations();for(let i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap(eventToTrackMap){if(!this.model_)return;const tracks=this.children;for(let i=0;i<tracks.length;++i){tracks[i].addEventsToTrackMap(eventToTrackMap);}
+if(this.instantEvents===undefined)return;const vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_(){const device=this.model.device;const track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendKernelTrack_(){const kernel=this.model.kernel;const track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendCpuUsageTrack_(){const track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},appendMemoryTrack_(){const track=new tr.ui.tracks.MemoryTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},drawTrack(type){const ctx=this.context();if(!this.model_)return;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0){break;}
+tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:this.drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(let i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+ctx.restore();return;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_(viewLWorld,viewRWorld){const ctx=this.context();ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=1;const events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);const onlyHighlighted=!this.viewport.showFlowEvents;const canvasBounds=ctx.canvas.getBoundingClientRect();for(let i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED){continue;}
+this.drawFlowArrow_(ctx,events[i],canvasBounds);}},drawFlowArrow_(ctx,flowEvent,canvasBounds){const dt=this.viewport.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const startTrack=this.viewport.trackForEvent(flowEvent.startSlice);const endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)return;const startBounds=startTrack.getBoundingClientRect();const endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState===SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else if(flowEvent.selectionState===SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else if(flowEvent.selectionState===SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[flowEvent.colorId];}else{let hasBoost=false;const startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;const endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[flowEvent.colorId];}}
+const startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;const endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)return;const startY=this.calculateTrackY_(startTrack,canvasBounds);const endY=this.calculateTrackY_(endTrack,canvasBounds);const pixelStartY=pixelRatio*startY;const pixelEndY=pixelRatio*endY;const startXView=dt.xWorldToView(flowEvent.start);const endXView=dt.xWorldToView(flowEvent.end);const midXView=(startXView+endXView)/2;ctx.beginPath();ctx.moveTo(startXView,pixelStartY);ctx.bezierCurveTo(midXView,pixelStartY,midXView,pixelEndY,endXView,pixelEndY);ctx.stroke();const arrowWidth=5*pixelRatio;const distance=endXView-startXView;if(distance<=(2*arrowWidth))return;const tipX=endXView;const tipY=pixelEndY;const arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
+const stripes=ModelTrack.generateStripes_(this.vSyncTimes_,viewLWorld,viewRWorld);if(stripes.length===0){return;}
+const vSyncHighlightColor=new tr.b.Color(ColorScheme.getColorForReservedNameAsString('vsync_highlight_color'));const stripeRange=stripes[stripes.length-1].max-stripes[0].min;const stripeDensity=stripeRange?stripes.length/(dt.scaleX*stripeRange):0;const clampedStripeDensity=tr.b.math.clamp(stripeDensity,ModelTrack.VSYNC_DENSITY_OPAQUE,ModelTrack.VSYNC_DENSITY_TRANSPARENT);const opacity=(ModelTrack.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/ModelTrack.VSYNC_DENSITY_RANGE;if(opacity===0){return;}
+const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;ctx.fillStyle=vSyncHighlightColor.toStringWithAlphaOverride(ModelTrack.VSYNC_HIGHLIGHT_ALPHA*opacity);for(let i=0;i<stripes.length;i++){const xLeftView=dt.xWorldToView(stripes[i].min);const xRightView=dt.xWorldToView(stripes[i].max);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}},calculateTrackY_(track,canvasBounds){const bounds=track.getBoundingClientRect();const size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0){return this.calculateTrackY_(Polymer.dom(track).parentNode,canvasBounds);}
+return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const XAxisTrack=tr.ui.b.define('x-axis-track',tr.ui.tracks.Track);XAxisTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('x-axis-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);const heading=document.createElement('tr-ui-b-heading');heading.arrowVisible=false;Polymer.dom(this).appendChild(heading);},detach(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_(){if(this.viewport.interestRange.isEmpty){Polymer.dom(this).classList.remove('tall-mode');}else{Polymer.dom(this).classList.add('tall-mode');}},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);}
+break;}},drawGrid_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const canvasBounds=ctx.canvas.getBoundingClientRect();const trackBounds=this.getBoundingClientRect();const width=canvasBounds.width*pixelRatio;const height=trackBounds.height*pixelRatio;const hasInterestRange=!this.viewport.interestRange.isEmpty;const xAxisHeightPx=hasInterestRange?(height*2)/5:height;const vp=this.viewport;const dt=vp.currentDisplayTransform;vp.updateMajorMarkData(viewLWorld,viewRWorld);const majorMarkDistanceWorld=vp.majorMarkWorldPositions.length>1?vp.majorMarkWorldPositions[1]-vp.majorMarkWorldPositions[0]:0;const numTicksPerMajor=5;const minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;const minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);const minorTickHeight=Math.floor(xAxisHeightPx*0.25);ctx.save();ctx.lineWidth=Math.round(pixelRatio);const crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';const tickLabels=[];ctx.beginPath();for(let i=0;i<vp.majorMarkWorldPositions.length;i++){const curXWorld=vp.majorMarkWorldPositions[i];const curXView=dt.xWorldToView(curXWorld);const displayText=vp.majorMarkUnit.format(curXWorld,{deltaValue:majorMarkDistanceWorld});ctx.fillText(displayText,curXView+(2*pixelRatio),0);tr.ui.b.drawLine(ctx,curXView,0,curXView,xAxisHeightPx);if(minorMarkDistancePx){for(let j=1;j<numTicksPerMajor;++j){const xView=Math.floor(curXView+minorMarkDistancePx*j);tr.ui.b.drawLine(ctx,xView,xAxisHeightPx-minorTickHeight,xView,xAxisHeightPx);}}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)return;tr.ui.b.drawLine(ctx,0,xAxisHeightPx,width,xAxisHeightPx);ctx.stroke();let displayDistance;const displayTextColor='rgb(0,0,0)';const arrowSpacing=10*pixelRatio;const arrowColor='rgb(128,121,121)';const arrowPosY=xAxisHeightPx*1.75;const arrowWidthView=3*pixelRatio;const arrowLengthView=10*pixelRatio;const spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';const textPosY=arrowPosY;const interestRange=vp.interestRange;if(interestRange.range===0){const markerWorld=interestRange.min;const markerView=dt.xWorldToView(markerWorld);const textToDraw=vp.majorMarkUnit.format(markerWorld);let textLeftView=markerView+4*pixelRatio;const textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width){textLeftView=markerView-4*pixelRatio-textWidthView;}
+ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
+const leftMarker=interestRange.min;const rightMarker=interestRange.max;const leftMarkerView=dt.xWorldToView(leftMarker);const rightMarkerView=dt.xWorldToView(rightMarker);const distanceBetweenMarkers=interestRange.range;const distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);const positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);const textToDraw=vp.majorMarkUnit.format(distanceBetweenMarkers);const textWidthView=ctx.measureText(textToDraw).width;const spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;let textLeftView=positionInMiddleOfMarkersView-textWidthView/2;const textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width){textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;}
+ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){let leftArrowStart;let rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
+ctx.restore();},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection(filter,selection){}};return{XAxisTrack,};});'use strict';Polymer({is:'tr-ui-timeline-track-view',ready(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.pollIfViewportAttachedInterval_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrackContainer_.style.overflowY='hidden';this.rulerTrackContainer_.style.flexShrink='0';this.rulerTrack_=new tr.ui.tracks.XAxisTrack(this.viewport_);Polymer.dom(this.rulerTrackContainer_).appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;Polymer.dom(this.rulerTrackContainer_).appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.style.flexGrow='1';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);Polymer.dom(this.modelTrackContainer_).appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));const m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach(){this.modelTrack_.detach();this.upperModelTrack_.detach();if(this.pollIfViewportAttachedInterval_){window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;}
+this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model){throw new Error('Model cannot be undefined');}
+const modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged){this.pollIfViewportAttachedInterval_=window.setInterval(this.pollIfViewportAttached_.bind(this),250);}},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},pollIfViewportAttached_(){if(!this.viewport_.isAttachedToDocumentOrInTestMode||this.viewport_.clientWidth===0){return;}
+window.addEventListener('resize',this.viewport_.dispatchChangeEvent);window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;this.setInitialViewport_();},setInitialViewport_(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();const w=this.modelTrackContainer_.canvas.width;let min;let range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+const boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const modelTrack=this.modelTrack_;const firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);const lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_(e){if(this.isZooming_)return;this.storeLastMousePos_(e);},onTouchStart_(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKey(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);},addKeyPressHotKeys_(){this.addKeyPressHotKey({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback(e){this.zoomBy_(1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'g'.charCodeAt(0),callback(e){this.onGridToggle_(true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'G'.charCodeAt(0),callback(e){this.onGridToggle_(false);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback(e){this.zoomBy_(10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback(e){this.zoomBy_(1/10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'a'.charCodeAt(0),callback(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'A'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'D'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'0'.charCodeAt(0),callback(e){this.setInitialViewport_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'f'.charCodeAt(0),callback(e){this.zoomToSelection();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'m'.charCodeAt(0),callback(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'p'.charCodeAt(0),callback(e){this.selectPowerSamplesInCurrentTimeRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'h'.charCodeAt(0),callback(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_(){const addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+const curSelection=this.brushingStateController_.selection;if(!curSelection.length||!tr.b.getOnlyElement(curSelection).title){return;}
+const selection=new tr.model.EventSet();const filter=new tr.c.ExactTitleFilter(tr.b.getOnlyElement(curSelection).title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_(e){if(!e.altKey)return;const delta=e.wheelDelta/120;const zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+if(e.target!==this.rulerTrack_)return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+const dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)return;const relativePosition=this.extractRelativeMousePosition_(e);const loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+const state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_(viewDeltaX,deltaY){const deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;const vp=this.viewport_;const pixelRatio=window.devicePixelRatio||1;const goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;const goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)return;const worldCenter=bounds.center;const viewCenter=this.modelTrackContainer_.canvas.width/2;const adjustedWorldRange=bounds.range*1.25;const newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;const zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;const worldCenter=bounds.center;const viewWidth=this.viewWidth_;const dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+return;}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition(uiState,showNavLine){const location=uiState.location;const scaleX=uiState.scaleX;const track=location.getContainingTrack(this.viewport_);const worldCenter=location.xWorld;const viewCenter=this.modelTrackContainer_.canvas.width/5;const zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)return;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);}
+this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},selectPowerSamplesInCurrentTimeRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(this.model.device.powerSeries&&!selectionBounds.empty){const events=this.model.device.powerSeries.getSamplesWithinRange(selectionBounds.min,selectionBounds.max);const selection=new tr.model.EventSet(events);this.brushingStateController_.changeSelectionFromTimeline(selection);}},setCurrentSelectionAsInterestRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min===selectionBounds.min&&this.viewport_.interestRange.max===selectionBounds.max){this.viewport_.interestRange.reset();}else{this.viewport_.interestRange.set(selectionBounds);}},toggleHighDetails_(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_(xStart,yStart,xEnd,yEnd){const loY=Math.min(yStart,yEnd);const hiY=Math.max(yStart,yEnd);const loX=Math.min(xStart,xEnd);const hiX=Math.max(xStart,xEnd);const modelTrackRect=this.modelTrack_.getBoundingClientRect();const dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;const modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();const clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};const headingWidth=window.getComputedStyle(Polymer.dom(this).querySelector('tr-ui-b-heading')).width;const trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;const intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top){return false;}
+const results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};const finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';const pixelRatio=window.devicePixelRatio||1;const canv=this.modelTrackContainer_.canvas;const dt=this.viewport_.currentDisplayTransform;const loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);const hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);Polymer.dom(this.$.drag_box).textContent=tr.b.Unit.byName.timeDurationInMs.format(hiWX-loWX);const e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_(left){const selection=this.brushingStateController_.selection;const tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+const numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_(e){const canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_(e){const canv=this.modelTrackContainer_.canvas;const touches=[];for(let i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_(e){const position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_(e){const vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_(e){if(!this.isPanningAndScanning_)return;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);const yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick){e.preventDefault();}},onBeginSelection_(e){const canv=this.modelTrackContainer_.canvas;const rect=this.modelTrack_.getBoundingClientRect();const canvRect=canv.getBoundingClientRect();const inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_(e){if(!this.dragBeginEvent_)return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_(e){e.preventDefault();if(!this.dragBeginEvent_)return;this.hideDragBox_();const eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;const loY=Math.min(eDown.clientY,e.clientY);const hiY=Math.max(eDown.clientY,e.clientY);const loX=Math.min(eDown.clientX,e.clientX);const hiX=Math.max(eDown.clientX,e.clientX);const canv=this.modelTrackContainer_.canvas;const worldOffset=canv.getBoundingClientRect().left;const loVX=loX-worldOffset;const hiVX=hiX-worldOffset;const selection=new tr.model.EventSet();if(eDown.appendSelection){const previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined){selection.addEventSet(previousSelection);}}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const newPosition=this.extractRelativeMousePosition_(e);const zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_(e){this.isZooming_=false;if(!e.isClick){e.preventDefault();}},computeTouchCenter_(positions){let xSum=0;let ySum=0;for(let i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_(positions){let xMin=Number.MAX_VALUE;let yMin=Number.MAX_VALUE;let xMax=Number.MIN_VALUE;let yMax=Number.MIN_VALUE;for(let i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+return Math.sqrt((xMin-xMax)*(xMin-xMax)+
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_(e){const newPositions=this.extractRelativeTouchPositions_(e);const currentPositions=this.lastTouchViewPositions_;const newCenter=this.computeTouchCenter_(newPositions);const currentCenter=this.computeTouchCenter_(currentPositions);const newSpan=this.computeTouchSpan_(newPositions);const currentSpan=this.computeTouchSpan_(currentPositions);const vp=this.viewport_;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDelta=pixelRatio*(newCenter.x-currentCenter.x);const yDelta=newCenter.y-currentCenter.y;const zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;const viewFocus=pixelRatio*newCenter.x;const worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);Polymer.dom(this.$.hint_text).textContent=text;this.$.hint_text.style.display='';},hideHintText_(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer({is:'tr-ui-find-control',filterKeyDown(e){if(e.keyCode===27){const hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey){this.findPrevious();}else{this.findNext();}}},filterBlur(e){this.updateHitCountEl();},filterFocus(e){this.$.filter.select();},filterMouseUp(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged(){Polymer.dom(this.$.hitCount).textContent='';this.$.spinner.style.visibility='visible';this.$.spinner.style.animation='spin 1s linear infinite';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.$.spinner.style.animation='';this.updateHitCountEl();}.bind(this));},findNext(){if(this.controller){this.controller.findNext();}
+this.updateHitCountEl();},findPrevious(){if(this.controller){this.controller.findPrevious();}
+this.updateHitCountEl();},updateHitCountEl(){if(!this.controller||this.$.filter.value.length===0){Polymer.dom(this.$.hitCount).textContent='';return;}
+const n=this.controller.filterHits.length;const i=n===0?-1:this.controller.currentHitIndex;Polymer.dom(this.$.hitCount).textContent=(i+1)+' of '+n;},setText(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push(event){const ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop(event){const ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context,};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)==='string'||filterExpression instanceof RegExp){const filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate(context){throw new Error('Not implemented');},matchValue_(value,expected){if(expected instanceof RegExp){return expected.test(value);}else if(expected instanceof Function){return expected(value);}
+return value===expected;}};return{Filter,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context)){return false;}}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=[];for(let i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
+FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1){throw new Error('not() must have exactly one subexpression');}
+return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(!this.subExpression){return context.ancestors.length>0;}
+while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}}
+FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){if(context.event.duration===undefined)return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){const filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(context.ancestors.length>0)return false;if(!this.subExpression)return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel,};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;}
+TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter(filterExpression){const result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_(){const nodes=[this];while(nodes[nodes.length-1].parent_){nodes.push(nodes[nodes.length-1].parent_);}
+const rootTask=new tr.b.Task();let lastTask=rootTask;let node;for(let i=nodes.length-1;i>=0;i--){node=nodes[i];if(node.selection_!==undefined)continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{const prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask,lastTask,lastNode:node};},createFilterTaskForNode_(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_(inputSelection,outputSelection){const seenEvents={};inputSelection.forEach(function(event){const context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents){const event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context)){outputSelection.push(event);}}
+if(!event.subSlices)return;context=context.push(event);for(let i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_(selection){const filterTask=new tr.b.Task();for(const container of this.model_.getDescendantEventContainers()){filterTask.subTask(()=>{for(const event of container.childEvents()){addEventTreeToSelection(selection,event);}},this);}
+return filterTask;},ready(){return new Promise(function(resolve,reject){const graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){const graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery,};});'use strict';Polymer({is:'tr-ui-scripting-control',isEnterKey_(event){return event.keyCode!==229&&(event.key==='Enter'||event.keyIdentifier==='Enter');},setFocus_(focused){const promptEl=this.$.prompt;if(focused){promptEl.focus();Polymer.dom(this.$.root).classList.add('focused');if(promptEl.value.length>0){const sel=window.getSelection();sel.collapse(Polymer.dom(promptEl).firstChild,promptEl.value.length);}}else{promptEl.blur();Polymer.dom(this.$.root).classList.remove('focused');const parent=promptEl.parentElement;const nextEl=Polymer.dom(promptEl).nextSibling;promptEl.remove();Polymer.dom(parent).insertBefore(promptEl,nextEl);}},onConsoleFocus(e){e.stopPropagation();this.setFocus_(true);},onConsoleBlur(e){e.stopPropagation();this.setFocus_(false);},promptKeyDown(e){e.stopPropagation();if(!this.isEnterKey_(e))return;e.preventDefault();const promptEl=this.$.prompt;const command=promptEl.value;if(command.length===0)return;promptEl.value='';this.addLine_(String.fromCharCode(187)+' '+command);let result;try{result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}
+promptEl.scrollIntoView();},addLine_(line){const historyEl=this.$.history;if(historyEl.innerText.length!==0){historyEl.innerText+='\n';}
+historyEl.innerText+=line;},promptKeyPress(e){e.stopPropagation();},toggleVisibility(){const root=this.$.root;if(!this.visible){Polymer.dom(root).classList.remove('hidden');this.setFocus_(true);}else{Polymer.dom(root).classList.add('hidden');this.setFocus_(false);}},get hasFocus(){return this===document.activeElement;},get visible(){const root=this.$.root;return!Polymer.dom(root).classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer({is:'tr-ui-side-panel-container',ready(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.dragHandle_=this.$.side_panel_drag_handle;this.dragHandle_.horizontal=false;this.dragHandle_.target=this.activePanelContainer_;this.rangeOfInterest_=new tr.b.math.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);if(this.model){this.onModelChanged_();}}},onSelectionChanged_(){if(this.activePanel){this.activePanel.selection=this.selection;}},get model(){return this.brushingStateController_.model;},onModelChanged_(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined){throw new Error('Cannot activate panel without a model');}
+let panel=undefined;if(panelType){panel=document.createElement(panelType);}
+if(panel!==undefined&&!panel.supportsModel(this.model)){throw new Error('Cannot activate panel: does not support this model');}
+if(this.activePanelType){Polymer.dom(this.getLabelElementForPanelType_(this.activePanelType)).removeAttribute('selected');}
+if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
+if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
+if(panelType===undefined){Polymer.dom(this).removeAttribute('expanded');this.activePanelType_=undefined;return;}
+Polymer.dom(this.getLabelElementForPanelType_(panelType)).setAttribute('selected',true);Polymer.dom(this).setAttribute('expanded',true);Polymer.dom(this.activePanelContainer_).appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_(constructor){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor===constructor){return this.tabStrip_.children[i].panelType;}}},getLabelElementForPanelType_(panelType){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType===panelType){return this.tabStrip_.children[i];}}
+return undefined;},updateContents_(){const previouslyActivePanelType=this.activePanelType;Polymer.dom(this.tabStrip_).textContent='';const supportedPanelTypes=[];const panelTypeInfos=tr.ui.side_panel.SidePanelRegistry.getAllRegisteredTypeInfos();const unsupportedLabelEls=[];for(const panelTypeInfo of panelTypeInfos){const labelEl=document.createElement('tab-strip-label');const panel=panelTypeInfo.constructor();const panelType=panel.tagName;Polymer.dom(labelEl).textContent=panel.textLabel;labelEl.panelType=panelType;const supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);Polymer.dom(labelEl).setAttribute('enabled',true);labelEl.addEventListener('click',function(panelType){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this,panelType));Polymer.dom(this.tabStrip_).appendChild(labelEl);}else{if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
+this.removeAttribute('expanded');unsupportedLabelEls.push(labelEl);}}
+for(const labelEl of unsupportedLabelEls){Polymer.dom(this.tabStrip_).appendChild(labelEl);}
+if(previouslyActivePanelType&&supportedPanelTypes.includes(previouslyActivePanelType)){this.activePanelType=previouslyActivePanelType;Polymer.dom(this).setAttribute('expanded',true);}else{if(this.activePanel){Polymer.dom(this.activePanelContainer_).removeChild(this.activePanel);}
+Polymer.dom(this).removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range===undefined){throw new Error('Must not be undefined');}
+this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer({is:'tr-ui-timeline-view',created(){this.trackViewContainer_=undefined;this.queuedModel_=undefined;this.builtPromise_=undefined;this.doneBuilding_=undefined;},attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}
+if(this.queuedModel_)this.updateContents_();});},ready(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.optionsDropdown_=this.$.view_options_dropdown;Polymer.dom(this.optionsDropdown_.iconElement).textContent='View Options';this.showFlowEvents_=false;Polymer.dom(this.optionsDropdown_).appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
+let faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue.blue;}
+let link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_(){const helpButtonEl=this.$.view_help_button;const dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_(){const toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_(){const showEl=this.$.view_metadata_button;function onClick(e){const dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';const metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;Polymer.dom(dlg).appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_(){const showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return Polymer.dom(this.titleEl_).textContent.substring(Polymer.dom(this.titleEl_).textContent.length-2);},set viewTitle(text){if(text===undefined){Polymer.dom(this.titleEl_).textContent='';this.titleEl_.hidden=true;return;}
+this.titleEl_.hidden=false;Polymer.dom(this.titleEl_).textContent=text;},get model(){if(this.trackView_){return this.trackView_.model;}
+return undefined;},set model(model){this.build(model);},async build(model){this.queuedModel_=model;this.builtPromise_=new Promise((resolve,reject)=>{this.doneBuilding_=resolve;});if(this.trackViewContainer_)await this.updateContents_();},get builtPromise(){return this.builtPromise_;},async updateContents_(){if(this.trackViewContainer_===undefined){throw new Error('timeline-view.updateContents_ requires trackViewContainer_');}
+const model=this.queuedModel_;this.queuedModel_=undefined;const modelInstanceChanged=model!==this.model;const modelValid=model&&!model.bounds.isEmpty;const importWarningsEl=Polymer.dom(this.root).querySelector('#import-warnings');Polymer.dom(importWarningsEl).textContent='';if(modelInstanceChanged){if(this.railScoreSpan_){this.railScoreSpan_.model=undefined;}
+Polymer.dom(this.trackViewContainer_).textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
+this.brushingStateController_.modelWillChange();}
+if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;Polymer.dom(this.trackViewContainer_).appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
+if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_){this.railScoreSpan_.model=model;}
+this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
+if(model){for(const warning of model.importWarningsThatShouldBeShownToUser){importWarningsEl.addMessage(`Import Warning: ${warning.type}: ${warning.message}`,[{buttonText:'Dismiss',onClick(event,infobar){infobar.visible=false;}}]);}}
+if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}
+this.doneBuilding_();},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_){this.settings_=new tr.b.Settings();}
+return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_(){const hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus){this.focus();}
+e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){if(this.scriptingCtl_.hasFocus)return;if(this.findCtl_.hasFocus){this.focus();}else{this.findCtl_.focus();}
+e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_(e){const spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+const vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr)){spc.rangeOfInterest=vr;}
+if(this.railScoreSpan_&&this.model){this.railScoreSpan_.model=this.model;}},toggleHighlightVSync_(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined){groupingKeyFuncs=[];}
+this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
+Row.prototype={getCurrentGroupingKeyFunc_(){if(this.groupingKeyFuncs_.length===0)return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
+return this.rowStats_;},rebuildSubRowsIfNeeded_(){if(this.subRowsBuilt_)return;this.subRowsBuilt_=true;const groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
+const dataByKey={};let hasValues=false;this.data_.forEach(function(datum){const key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined){dataByKey[key]=[];}
+dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
+this.subRows_=[];for(const key in dataByKey){const row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer({is:'tr-ui-b-grouping-table',created(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild(){this.$.table.rebuild();},updateContents_(){const groupBy=this.groupBy_||[];const dataToGroup=this.dataToGroup_||[];const rowStatsConstructor=this.rowStatsConstructor_||function(){};const superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;Polymer({is:'tr-ui-b-grouping-table-groupby-picker-group',created(){this.picker_=undefined;this.group_=undefined;},get picker(){return this.picker_;},set picker(picker){this.picker_=picker;},get group(){return this.group_;},set group(g){this.group_=g;this.$.label.textContent=g.label;},get enabled(){return this.$.enabled.checked;},set enabled(enabled){this.$.enabled.checked=enabled;if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}},set isFirst(isFirst){this.$.left.style.display=(!this.enabled||isFirst)?'none':'inline';},set isLast(isLast){this.$.right.style.display=(!this.enabled||isLast)?'none':'inline';},moveLeft_(){this.picker.moveLeft_(this);},moveRight_(){this.picker.moveRight_(this);},onEnableChanged_(){if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}
+this.picker.onEnableChanged_(this);}});Polymer({is:'tr-ui-b-grouping-table-groupby-picker',created(){this.settingsKey_=undefined;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(this.$.container.children.length){this.restoreSetting_();}},restoreSetting_(){if(this.settingsKey_===undefined)return;this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.currentGroupKeys);},get possibleGroups(){return[...this.$.container.children].map(groupEl=>groupEl.group);},set possibleGroups(possibleGroups){Polymer.dom(this.$.container).textContent='';for(let i=0;i<possibleGroups.length;++i){const groupEl=document.createElement('tr-ui-b-grouping-table-groupby-picker-group');groupEl.picker=this;groupEl.group=possibleGroups[i];Polymer.dom(this.$.container).appendChild(groupEl);}
+this.restoreSetting_();this.updateFirstLast_();},updateFirstLast_(){const groupEls=this.$.container.children;const enabledGroupEls=[...groupEls].filter(el=>el.enabled);for(let i=0;i<enabledGroupEls.length;++i){enabledGroupEls[i].isFirst=i===0;enabledGroupEls[i].isLast=i===enabledGroupEls.length-1;}},get currentGroupKeys(){return this.currentGroups.map(group=>group.key);},get currentGroups(){const groups=[];for(const groupEl of this.$.container.children){if(groupEl.enabled){groups.push(groupEl.group);}}
+return groups;},set currentGroupKeys(newKeys){if(!tr.b.compareArrays(this.currentGroupKeys,newKeys,(x,y)=>x.localeCompare(y))){return;}
+const possibleGroups=new Map();for(const group of this.possibleGroups){possibleGroups.set(group.key,group);}
+const groupEls=this.$.container.children;let i=0;for(i=0;i<newKeys.length;++i){const group=possibleGroups.get(newKeys[i]);if(group===undefined){newKeys.splice(i,1);--i;continue;}
+groupEls[i].group=group;groupEls[i].enabled=true;possibleGroups.delete(newKeys[i]);}
+for(const group of possibleGroups.values()){groupEls[i].group=group;groupEls[i].enabled=false;++i;}
+this.updateFirstLast_();this.onCurrentGroupsChanged_();},moveLeft_(groupEl){const reference=groupEl.previousSibling;Polymer.dom(this.$.container).removeChild(groupEl);Polymer.dom(this.$.container).insertBefore(groupEl,reference);this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},moveRight_(groupEl){const reference=groupEl.nextSibling.nextSibling;Polymer.dom(this.$.container).removeChild(groupEl);if(reference){Polymer.dom(this.$.container).insertBefore(groupEl,reference);}else{Polymer.dom(this.$.container).appendChild(groupEl);}
+this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},onCurrentGroupsChanged_(){this.dispatchEvent(new tr.b.Event('current-groups-changed'));tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys);},onEnableChanged_(groupEl){this.updateFirstLast_();this.onCurrentGroupsChanged_();}});return{};});'use strict';(function(){Polymer({is:'tr-ui-sp-file-size-stats-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn(eventStat){return eventStat.title;}}];if(this.$.picker.currentGroupKeys.length===0){this.$.picker.currentGroupKeys=['phase','title'];}
+this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
+if(m.stats.allTraceEventStats.length===0){return{supported:false,reason:'No stats were collected for this file.'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_(stats){const columns=[{title:'Title',value(row){const titleEl=document.createElement('span');Polymer.dom(titleEl).textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,value(row){return row.rowStats.numEvents;},cmp(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',value(row){const value=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);const spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp(a,b){return a.rowStats.totalEventSizeinBytes-
+b.rowStats.totalEventSizeinBytes;},width:'80px'});}
+return columns;},updateContents_(){const table=this.$.table;const columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){const sum=tr.b.math.Statistics.sum(row.data,function(x){return x.numEvents;});const totalEventSizeinBytes=tr.b.math.Statistics.sum(row.data,x=>x.totalEventSizeinBytes);return{numEvents:sum,totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
+this.$.table.rebuild();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-file-size-stats-side-panel');});})();'use strict';tr.exportTo('tr.mre',function(){const FunctionRegistry={allFunctions_:[],allFunctionsByName_:{},get allFunctions(){return this.allFunctions_;},get allFunctionsByName(){return this.allFunctionsByName_;}};FunctionRegistry.getFunction=function(name){return this.allFunctionsByName_[name];};FunctionRegistry.register=function(func){if(func.name===''){throw new Error('Registered functions must not be anonymous');}
+if(this.allFunctionsByName[func.name]!==undefined){throw new Error('Function named '+func.name+'is already registered.');}
+this.allFunctionsByName[func.name]=func;this.allFunctions.push(func);};function ModuleToLoad(href,filename){if((href!==undefined)?(filename!==undefined):(filename===undefined)){throw new Error('ModuleToLoad must specify exactly one of href or '+'filename');}
+this.href=href;this.filename=filename;}
+ModuleToLoad.prototype={asDict(){if(this.href!==undefined){return{'href':this.href};}
+return{'filename':this.filename};},toString(){if(this.href!==undefined){return'ModuleToLoad(href="'+this.href+'")';}
+return'ModuleToLoad(filename="'+this.filename+'")';}};ModuleToLoad.fromDict=function(moduleDict){return new ModuleToLoad(moduleDict.href,moduleDict.filename);};function FunctionHandle(modulesToLoad,functionName,opt_options){if(!(modulesToLoad instanceof Array)){throw new Error('modulesToLoad in FunctionHandle must be an array');}
+if(typeof(functionName)!=='string'){throw new Error('functionName in FunctionHandle must be a string');}
+this.modulesToLoad=modulesToLoad;this.functionName=functionName;this.options_=opt_options;}
+FunctionHandle.prototype={get options(){return this.options_;},asDict(){return{'modules_to_load':this.modulesToLoad.map(function(m){return m.asDict();}),'function_name':this.functionName,'options':this.options_};},asUserFriendlyString(){const parts=this.modulesToLoad.map(mtl=>mtl.filename);parts.push(this.functionName);parts.push(JSON.stringify(this.options_));return parts.join(',');},hasHrefs(){for(const module in this.modulesToLoad){if(this.modulesToLoad[module].href!==undefined){return true;}}
+return false;},load(){if(this.hasHrefs()){const err=new Error('FunctionHandle named '+this.functionName+' specifies hrefs, which cannot be loaded.');err.name='FunctionLoadingError';throw err;}
+for(const module in this.modulesToLoad){const filename=this.modulesToLoad[module].filename;try{HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}}
+const func=FunctionRegistry.getFunction(this.functionName);if(func===undefined){const err=new Error('No registered function named '+this.functionName);err.name='FunctionNotDefinedError';throw err;}
+return func;},toString(){const modulesToLoadStr=this.modulesToLoad.map(function(module){return module.toString();});return'FunctionHandle(modulesToLoad=['+modulesToLoadStr+'], '+'functionName="'+this.functionName+'", options="'+
+JSON.stringify(this.options_)+'")';}};FunctionHandle.loadFromFilename_=function(filename){try{const numFunctionsBefore=FunctionRegistry.allFunctions.length;HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}
+const numFunctionsNow=FunctionRegistry.allFunctions.length;if(numFunctionsNow!==(numFunctionsBefore+1)){const err=new Error(filename+' didn\'t call FunctionRegistry.register');err.name='FunctionNotDefinedError';throw err;}
+return FunctionRegistry.allFunctions[numFunctionsNow-1];};FunctionHandle.fromDict=function(handleDict){const options=handleDict.options;let modulesToLoad;if(handleDict.modules_to_load!==undefined){modulesToLoad=handleDict.modules_to_load.map(function(module){return ModuleToLoad.fromDict(module);});}
+return new FunctionHandle(modulesToLoad,handleDict.function_name,options);};return{FunctionHandle,ModuleToLoad,FunctionRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function runMetrics(model,options){if(options===undefined){throw new Error('Options are required.');}
+const metricNames=options.metrics;if(!metricNames){throw new Error('Metric names should be specified.');}
+const histograms=new tr.v.HistogramSet();for(const metricName of metricNames){const metric=tr.metrics.MetricRegistry.findTypeInfoWithName(metricName);if(metric===undefined){throw new Error('"'+metricName+'" is not a registered metric.');}
+metric.constructor(histograms,model,options);}
+validateDiagnosticNames(histograms);return histograms;}
+function validateDiagnosticNames(histograms){for(const hist of histograms){for(const name of hist.diagnostics.keys()){if(tr.v.d.RESERVED_NAMES_SET.has(name)){throw new Error(`Illegal diagnostic name "${name}" on Histogram "${hist.name}"`);}}}}
+function addTelemetryInfo(histograms,model){for(const metadata of model.metadata){if(!metadata.value||!metadata.value.telemetry)continue;for(const[name,value]of Object.entries(metadata.value.telemetry)){const type=tr.v.d.RESERVED_NAMES_TO_TYPES.get(name);if(type===undefined){throw new Error(`Unexpected telemetry.${name}`);}
+histograms.addSharedDiagnostic(name,new type(value));}}}
+function metricMapFunction(result,model,options){const histograms=runMetrics(model,options);addTelemetryInfo(histograms,model);result.addPair('histograms',histograms.asDicts());const scalarDicts=[];for(const value of histograms){for(const[statName,scalar]of value.statisticsScalars){scalarDicts.push({name:value.name+'_'+statName,numeric:scalar.asDict(),description:value.description,});}}
+result.addPair('scalars',scalarDicts);}
+tr.mre.FunctionRegistry.register(metricMapFunction);return{metricMapFunction,runMetrics,};});'use strict';tr.exportTo('tr.mre',function(){function Failure(job,functionHandleString,traceCanonicalUrl,failureTypeName,description,stack){this.job=job;this.functionHandleString=functionHandleString;this.traceCanonicalUrl=traceCanonicalUrl;this.failureTypeName=failureTypeName;this.description=description;this.stack=stack;}
+Failure.prototype={asDict(){return{function_handle_string:this.functionHandleString,trace_canonical_url:this.traceCanonicalUrl,type:this.failureTypeName,description:this.description,stack:this.stack};}};Failure.fromDict=function(failureDict){return new Failure(undefined,failureDict.function_handle_string,failureDict.trace_canonical_url,failureDict.type,failureDict.description,failureDict.stack);};return{Failure,};});'use strict';tr.exportTo('tr.mre',function(){class MreResult{constructor(failures,pairs){if(failures===undefined){failures=[];}
+if(pairs===undefined){pairs={};}
+this.failures=failures;this.pairs=pairs;}
+addFailure(failure){this.failures.push(failure);}
+addPair(key,value){if(key in this.pairs){throw new Error('Key '+key+' already exists in result.');}
+this.pairs[key]=value;}
+asDict(){const d={pairs:this.pairs};if(this.failures){d.failures=this.failures.map(function(f){return f.asDict();});}
+return d;}
+hadFailures(){return this.failures.length>0;}
+static fromDict(resultDict){const failures=(resultDict.failures!==undefined)?resultDict.failures.map(tr.mre.Failure.fromDict):undefined;const pairs=resultDict.pairs;return new MreResult(failures,pairs);}}
+return{MreResult,};});'use strict';tr.exportTo('tr.ui',function(){class NullBrushingStateController extends tr.c.BrushingStateController{constructor(){super(undefined);this.parentController=undefined;}
+dispatchChangeEvent_(){if(this.parentController)this.parentController.dispatchChangeEvent_();}
+get model(){if(!this.parentController)return undefined;return this.parentController.model;}
+get trackView(){if(!this.parentController)return undefined;return this.parentController.trackView;}
+get viewport(){if(!this.parentController)return undefined;return this.parentController.viewport;}
+get historyEnabled(){if(!this.parentController)return undefined;return this.parentController.historyEnabled;}
+set historyEnabled(historyEnabled){if(this.parentController){this.parentController.historyEnabled=historyEnabled;}}
+modelWillChange(){if(this.parentController)this.parentController.modelWillChange();}
+modelDidChange(){if(this.parentController)this.parentController.modelDidChange();}
+onUserInitiatedSelectionChange_(){if(this.parentController){this.parentController.onUserInitiatedSelectionChange_();}}
+onPopState_(e){if(this.parentController)this.parentController.onPopState_(e);}
+get selection(){if(!this.parentController)return undefined;return this.parentController.selection;}
+get findMatches(){if(!this.parentController)return undefined;return this.parentController.findMatches;}
+get selectionOfInterest(){if(!this.parentController)return undefined;return this.parentController.selectionOfInterest;}
+get currentBrushingState(){if(!this.parentController)return undefined;return this.parentController.currentBrushingState;}
+set currentBrushingState(newBrushingState){if(this.parentController){this.parentController.currentBrushingState=newBrushingState;}}
+addAllEventsMatchingFilterToSelectionAsTask(filter,selection){if(this.parentController){this.parentController.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);}}
+findTextChangedTo(allPossibleMatches){if(this.parentController){this.parentController.findTextChangedTo(allPossibleMatches);}}
+findFocusChangedTo(currentFocus){if(this.parentController){this.parentController.findFocusChangedTo(currentFocus);}}
+findTextCleared(){if(this.parentController){this.parentController.findTextCleared();}}
+uiStateFromString(string){if(this.parentController){this.parentController.uiStateFromString(string);}}
+navToPosition(uiState,showNavLine){if(this.parentController){this.parentController.navToPosition(uiState,showNavLine);}}
+changeSelectionFromTimeline(selection){if(this.parentController){this.parentController.changeSelectionFromTimeline(selection);}}
+showScriptControlSelection(selection){if(this.parentController){this.parentController.showScriptControlSelection(selection);}}
+changeSelectionFromRequestSelectionChangeEvent(selection){if(this.parentController){this.parentController.changeSelectionFromRequestSelectionChangeEvent(selection);}}
+changeAnalysisViewRelatedEvents(eventSet){if(this.parentController&&(eventSet instanceof tr.model.EventSet)){this.parentController.changeAnalysisViewRelatedEvents(eventSet);}}
+changeAnalysisLinkHoveredEvents(eventSet){if(this.parentController&&(eventSet instanceof tr.model.EventSet)){this.parentController.changeAnalysisLinkHoveredEvents(eventSet);}}
+getViewSpecificBrushingState(viewId){if(this.parentController){this.parentController.getViewSpecificBrushingState(viewId);}}
+changeViewSpecificBrushingState(viewId,newState){if(this.parentController){this.parentController.changeViewSpecificBrushingState(viewId,newState);}}}
+return{NullBrushingStateController,};});'use strict';tr.exportTo('tr.v',function(){class CSVBuilder{constructor(histograms){this.histograms_=histograms;this.table_=[];this.statisticsNames_=new Set();this.groupings_=[];}
+build(){this.prepare_();this.buildHeader_();this.buildTable_();}
+prepare_(){for(const[key,grouping]of tr.v.HistogramGrouping.BY_KEY){if(key==='name')continue;this.groupings_.push(grouping);}
+this.groupings_.sort((a,b)=>a.key.localeCompare(b.key));for(const hist of this.histograms_){for(const name of hist.statisticsNames){this.statisticsNames_.add(name);}}
+this.statisticsNames_=Array.from(this.statisticsNames_);}
+buildHeader_(){const header=['name','unit'];for(const name of this.statisticsNames_){header.push(name);}
+for(const grouping of this.groupings_){header.push(grouping.key);}
+this.table_.push(header);}
+buildTable_(){for(const hist of this.histograms_){const row=[hist.name,hist.unit.unitString];this.table_.push(row);const stats=hist.statisticsScalars;for(const name of this.statisticsNames_){row.push(stats.has(name)?stats.get(name).value:'');}
+for(const grouping of this.groupings_){row.push(grouping.callback(hist));}}}
+toString(){let str='';for(const row of this.table_){for(let i=0;i<row.length;++i){if(i>0){str+=',';}
+let cell=''+row[i];cell=cell.replace(/\n/g,' ');if(cell.indexOf(',')>=0||cell.indexOf('"')>=0){cell='"'+cell.replace(/"/g,'""')+'"';}
+str+=cell;}
+str+='\n';}
+return str;}}
+return{CSVBuilder,};});'use strict';tr.exportTo('tr.v',function(){const getDisplayLabel=tr.v.HistogramGrouping.DISPLAY_LABEL.callback;const DEFAULT_POSSIBLE_GROUPS=[];DEFAULT_POSSIBLE_GROUPS.push(new tr.v.HistogramGrouping(tr.v.HistogramGrouping.HISTOGRAM_NAME.key,h=>h.shortName||h.name));const EXCLUDED_GROUPING_KEYS=[tr.v.HistogramGrouping.HISTOGRAM_NAME.key,tr.v.HistogramGrouping.DISPLAY_LABEL.key,];for(const group of tr.v.HistogramGrouping.BY_KEY.values()){if(EXCLUDED_GROUPING_KEYS.includes(group.key))continue;DEFAULT_POSSIBLE_GROUPS.push(group);}
+class HistogramParameterCollector{constructor(){this.statisticNames_=new Set(['avg']);this.labelsToStartTimes_=new Map();this.keysToGroupings_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,g]));this.keysToValues_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,new Set()]));this.keysToValues_.delete(tr.v.HistogramGrouping.HISTOGRAM_NAME.key);}
+process(histograms){const allStoryTags=new Set();let maxSampleCount=0;for(const hist of histograms){maxSampleCount=Math.max(maxSampleCount,hist.numValues);for(const statName of hist.statisticsNames){this.statisticNames_.add(statName);}
+let startTime=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARK_START);if(startTime!==undefined)startTime=startTime.minDate.getTime();const displayLabel=getDisplayLabel(hist);if(this.labelsToStartTimes_.has(displayLabel)){startTime=Math.min(startTime,this.labelsToStartTimes_.get(displayLabel));}
+this.labelsToStartTimes_.set(displayLabel,startTime);for(const[groupingKey,values]of this.keysToValues_){const grouping=this.keysToGroupings_.get(groupingKey);const value=grouping.callback(hist);if(!value)continue;values.add(value);if(values.size>1){this.keysToValues_.delete(groupingKey);}}
+const storyTags=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.STORY_TAGS);for(const tag of(storyTags||[])){allStoryTags.add(tag);}}
+tr.b.Timing.instant('HistogramParameterCollector','maxSampleCount',maxSampleCount);for(const tagGrouping of tr.v.HistogramGrouping.buildFromTags(allStoryTags,tr.v.d.RESERVED_NAMES.STORY_TAGS)){const values=new Set();for(const hist of histograms){values.add(tagGrouping.callback(hist));}
+if(values.size>1){this.keysToGroupings_.set(tagGrouping.key,tagGrouping);this.keysToValues_.set(tagGrouping.key,values);}}}
+get statisticNames(){return Array.from(this.statisticNames_);}
+get labels(){const displayLabels=Array.from(this.labelsToStartTimes_.keys());displayLabels.sort((x,y)=>this.labelsToStartTimes_.get(x)-this.labelsToStartTimes_.get(y));return displayLabels;}
+get possibleGroupings(){for(const[key,values]of this.keysToValues_){if(values.size>=2)continue;this.keysToGroupings_.delete(key);}
+return Array.from(this.keysToGroupings_.values());}}
+return{HistogramParameterCollector,};});'use strict';tr.exportTo('tr.v.ui',function(){const ALPHA_OPTIONS=[];for(let i=1;i<10;++i)ALPHA_OPTIONS.push(i*1e-3);for(let i=1;i<10;++i)ALPHA_OPTIONS.push(i*1e-2);ALPHA_OPTIONS.push(0.01);Polymer({is:'tr-v-ui-histogram-set-controls',properties:{searchQuery:{type:String,value:'',observer:'onUserChange_',},showAll:{type:Boolean,value:false,observer:'onUserChange_',},referenceDisplayLabel:{type:String,value:'',observer:'onUserChange_',},displayStatisticName:{type:String,value:'',observer:'onUserChange_',},alphaString:{type:String,computed:'getAlphaString_(alphaIndex)',},alphaIndex:{type:Number,value:9,observer:'onUserChange_',},},created(){this.viewState_=undefined;this.rowListener_=this.onRowViewStateUpdate_.bind(this);this.baseStatisticNames_=[];this.isInOnViewStateUpdate_=false;},ready(){this.$.picker.addEventListener('current-groups-changed',this.onGroupsChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},async onUserChange_(){if(!this.viewState)return;if(this.isInOnViewStateUpdate_)return;const marks=[];if(this.searchQuery!==this.viewState.searchQuery){marks.push(tr.b.Timing.mark('histogram-set-controls','search'));}
+if(this.showAll!==this.viewState.showAll){marks.push(tr.b.Timing.mark('histogram-set-controls','showAll'));}
+if(this.referenceDisplayLabel!==this.viewState.referenceDisplayLabel){marks.push(tr.b.Timing.mark('histogram-set-controls','referenceColumn'));}
+if(this.displayStatisticName!==this.viewState.displayStatisticName){marks.push(tr.b.Timing.mark('histogram-set-controls','statistic'));}
+if(parseInt(this.alphaIndex)!==this.getAlphaIndexFromViewState_()){marks.push(tr.b.Timing.mark('histogram-set-controls','alpha'));}
+let displayStatisticName=this.displayStatisticName;if(this.viewState.referenceDisplayLabel===''&&this.referenceDisplayLabel!==''&&this.baseStatisticNames.length){displayStatisticName=`${tr.v.DELTA}${this.displayStatisticName}`;}
+if(this.referenceDisplayLabel===''&&this.viewState.referenceDisplayLabel!==''&&this.baseStatisticNames.length){const deltaIndex=displayStatisticName.indexOf(tr.v.DELTA);if(deltaIndex>=0){displayStatisticName=displayStatisticName.slice(deltaIndex+1);}else if(!this.baseStatisticNames.includes(displayStatisticName)){displayStatisticName='avg';}}
+await this.viewState.update({searchQuery:this.searchQuery,showAll:this.showAll,referenceDisplayLabel:this.referenceDisplayLabel,displayStatisticName,alpha:ALPHA_OPTIONS[this.alphaIndex],});if(this.referenceDisplayLabel&&this.statisticNames.length===this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames.concat(tr.v.Histogram.getDeltaStatisticsNames(this.baseStatisticNames));}else if(!this.referenceDisplayLabel&&this.statisticNames.length>this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames;}
+for(const mark of marks)mark.end();},onViewStateUpdate_(event){this.isInOnViewStateUpdate_=true;if(event.delta.searchQuery){this.searchQuery=this.viewState.searchQuery;}
+if(event.delta.showAll)this.showAll=this.viewState.showAll;if(event.delta.displayStatisticName){this.displayStatisticName=this.viewState.displayStatisticName;}
+if(event.delta.referenceDisplayLabel){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;this.$.alpha.style.display=this.referenceDisplayLabel?'inline':'';}
+if(event.delta.groupings){this.$.picker.currentGroupKeys=this.viewState.groupings.map(g=>g.key);}
+if(event.delta.tableRowStates){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){row.addUpdateListener(this.rowListener_);}
+const anyShowing=this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+if(event.delta.alpha){this.alphaIndex=this.getAlphaIndexFromViewState_();}
+this.isInOnViewStateUpdate_=false;this.onUserChange_();},onRowViewStateUpdate_(event){if(event.delta.isOverviewed){const anyShowing=event.delta.isOverviewed.current||this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+if(event.delta.subRows){for(const subRow of event.delta.subRows.previous){subRow.removeUpdateListener(this.rowListener_);}
+for(const subRow of event.delta.subRows.current){subRow.addUpdateListener(this.rowListener_);}}},onGroupsChanged_(){if(this.$.picker.currentGroups.length===0&&this.$.picker.possibleGroups.length>0){this.$.picker.currentGroupKeys=[this.$.picker.possibleGroups[0].key];}
+this.viewState.groupings=this.$.picker.currentGroups;},set showAllEnabled(enable){if(!enable)this.$.show_all.checked=true;this.$.show_all.disabled=!enable;},set possibleGroupings(groupings){this.$.picker.possibleGroups=groupings;this.$.picker.style.display=(groupings.length<2)?'none':'block';this.onGroupsChanged_();},set displayLabels(labels){this.$.reference_display_label.style.display=(labels.length<2)?'none':'inline';while(this.$.reference_display_label.children.length>1){this.$.reference_display_label.removeChild(this.$.reference_display_label.lastChild);}
+for(const displayLabel of labels){const option=document.createElement('option');option.textContent=displayLabel;option.value=displayLabel;this.$.reference_display_label.appendChild(option);}
+if(labels.includes(this.viewState.referenceDisplayLabel)){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;}else{this.viewState.referenceDisplayLabel='';}},get baseStatisticNames(){return this.baseStatisticNames_;},set baseStatisticNames(names){this.baseStatisticNames_=names;this.statisticNames=names;},get statisticNames(){return Array.from(this.$.statistic.options).map(o=>o.value);},set statisticNames(names){this.$.statistic.style.display=(names.length<2)?'none':'inline';while(this.$.statistic.children.length){this.$.statistic.removeChild(this.$.statistic.lastChild);}
+for(const name of names){const option=document.createElement('option');option.textContent=name;this.$.statistic.appendChild(option);}
+if(names.includes(this.viewState.displayStatisticName)){this.displayStatisticName=this.viewState.displayStatisticName;this.$.statistic.value=this.displayStatisticName;}else{this.viewState.displayStatisticName=names[0]||'';}},get anyOverviewCharts_(){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){if(row.isOverviewed)return true;}
+return false;},async toggleOverviewLineCharts_(){const showOverviews=!this.anyOverviewCharts_;const mark=tr.b.Timing.mark('histogram-set-controls',(showOverviews?'show':'hide')+'OverviewCharts');for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){await row.update({isOverviewed:showOverviews});}
+this.$.hide_overview.style.display=showOverviews?'inline':'none';this.$.show_overview.style.display=showOverviews?'none':'inline';await tr.b.animationFrame();mark.end();},set helpHref(href){this.$.help.href=href;this.$.help.style.display='inline';},set feedbackHref(href){this.$.feedback.href=href;this.$.feedback.style.display='inline';},downloadCSV_(event){this.dispatchEvent(new tr.b.Event('download-csv'));},getAlphaString_(alphaIndex){return(''+ALPHA_OPTIONS[alphaIndex]).substr(0,5);},openAlphaSlider_(){const alphaButtonRect=this.$.alpha.getBoundingClientRect();this.$.alpha_slider_container.style.display='flex';this.$.alpha_slider_container.style.top=alphaButtonRect.bottom+'px';this.$.alpha_slider_container.style.left=alphaButtonRect.left+'px';this.$.alpha_slider.focus();},closeAlphaSlider_(){this.$.alpha_slider_container.style.display='';},updateAlpha_(){this.alphaIndex=this.$.alpha_slider.value;},getAlphaIndexFromViewState_(){for(let i=0;i<ALPHA_OPTIONS.length;++i){if(ALPHA_OPTIONS[i]>=this.viewState.alpha)return i;}
+return ALPHA_OPTIONS.length-1;},});return{};});'use strict';tr.exportTo('tr.v',function(){function deleteMergedToDiagnostics(histogramArrayMap){for(const[name,histograms]of histogramArrayMap){if(histograms instanceof Array){for(const histogram of histograms){histogram.diagnostics.delete(tr.v.d.RESERVED_NAMES.MERGED_TO);}}else if(histograms instanceof Map){deleteMergedToDiagnostics(histograms);}}}
+class HistogramSetHierarchy{constructor(name){this.name=name;this.description='';this.depth=0;this.subRows=[];this.columns=new Map();this.mergeRelationshipsForColumn_=new Map();}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+static build(histogramArrayMap){const rootRows=[];HistogramSetHierarchy.buildInternal_(histogramArrayMap,[],rootRows);const histograms=new tr.v.HistogramSet();for(const row of HistogramSetHierarchy.walkAll(rootRows)){for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+histograms.deduplicateDiagnostics();for(const row of HistogramSetHierarchy.walkAll(rootRows)){for(const[name,hist]of row.columns){if(!(hist instanceof tr.v.Histogram))continue;if(!row.mergeRelationshipsForColumn_.get(name))continue;hist.diagnostics.mergeRelationships(hist);}}
+deleteMergedToDiagnostics(histogramArrayMap);for(const row of HistogramSetHierarchy.walkAll(rootRows)){row.maybeRebin_();}
+return rootRows;}
+maybeRebin_(){const dataRange=new tr.b.math.Range();for(const hist of this.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;if(hist.allBins.length>1)return;if(hist.numValues===0)continue;dataRange.addValue(hist.min);dataRange.addValue(hist.max);}
+dataRange.addValue(tr.b.math.lesserWholeNumber(dataRange.min));dataRange.addValue(tr.b.math.greaterWholeNumber(dataRange.max));if(dataRange.min===dataRange.max)return;const boundaries=tr.v.HistogramBinBoundaries.createLinear(dataRange.min,dataRange.max,tr.v.DEFAULT_REBINNED_COUNT);for(const[name,hist]of this.columns){if(!(hist instanceof tr.v.Histogram))continue;this.columns.set(name,hist.rebin(boundaries));}}
+static mergeHistogramDownHierarchy_(histogram,hierarchy,columnName){let groupingPath=undefined;for(const row of hierarchy){if(groupingPath!==undefined){groupingPath.push(row.name);}else if(row.name===histogram.name){groupingPath=[];}
+if(!row.description){row.description=histogram.description;}
+const existing=row.columns.get(columnName);if(existing===undefined){const clone=histogram.clone();if(groupingPath!==undefined){new tr.v.d.GroupingPath(groupingPath).addToHistogram(clone);}
+row.columns.set(columnName,clone);row.mergeRelationshipsForColumn_.set(columnName,true);continue;}
+if(existing instanceof tr.v.HistogramSet){existing.addHistogram(histogram);continue;}
+if(!existing.canAddHistogram(histogram)){const unmergeableHistograms=new tr.v.HistogramSet([histogram]);const mergedFrom=existing.diagnostics.get(tr.v.d.RESERVED_NAMES.MERGED_FROM);if(mergedFrom!==undefined){for(const[unusedName,origHist]of mergedFrom){unmergeableHistograms.addHistogram(origHist);}}
+row.columns.set(columnName,unmergeableHistograms);continue;}
+if(existing.name!==histogram.name){row.mergeRelationshipsForColumn_.set(name,false);}
+existing.addHistogram(histogram);}}
+static buildInternal_(histogramArrayMap,hierarchy,rootRows){for(const[name,histograms]of histogramArrayMap){if(histograms instanceof Array){for(const histogram of histograms){HistogramSetHierarchy.mergeHistogramDownHierarchy_(histogram,hierarchy,name);}}else if(histograms instanceof Map){const row=new HistogramSetHierarchy(name);row.depth=hierarchy.length;hierarchy.push(row);HistogramSetHierarchy.buildInternal_(histograms,hierarchy,rootRows);hierarchy.pop();if(hierarchy.length===0){rootRows.push(row);}else{const parentRow=hierarchy[hierarchy.length-1];parentRow.subRows.push(row);}}}}
+static filter(rows,histograms){const results=[];for(const row of rows){let filteredSubRows=[];if(row.subRows.length>0){filteredSubRows=HistogramSetHierarchy.filter(row.subRows,histograms);if(filteredSubRows.length===0)continue;}else{let found=false;for(const testHist of row.columns.values()){if(testHist instanceof tr.v.HistogramSet){for(const origHist of testHist){if(histograms.lookupHistogram(origHist.guid)!==undefined){found=true;break;}}
+if(found)break;continue;}
+if(!(testHist instanceof tr.v.Histogram)){throw new Error('Cells can only contain Histogram or HistogramSet');}
+if(histograms.lookupHistogram(testHist.guid)!==undefined){found=true;break;}
+const mergedFrom=testHist.diagnostics.get(tr.v.d.RESERVED_NAMES.MERGED_FROM);if(mergedFrom!==undefined){for(const[unusedName,origHist]of mergedFrom){if(histograms.lookupHistogram(origHist.guid)!==undefined){found=true;break;}}}
+if(found)break;}
+if(!found)continue;}
+const clone=new HistogramSetHierarchy(row.name);clone.description=row.description;clone.depth=row.depth;clone.subRows=filteredSubRows;clone.columns=row.columns;results.push(clone);}
+return results;}}
+return{HistogramSetHierarchy,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-table-cell',created(){this.viewState_=undefined;this.rootListener_=this.onRootStateUpdate_.bind(this);this.row_=undefined;this.displayLabel_='';this.histogram_=undefined;this.histogramSpan_=undefined;this.overviewChart_=undefined;},ready(){this.addEventListener('click',this.onClick_.bind(this));},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},build(row,displayLabel,viewState){this.row_=row;this.displayLabel_=displayLabel;this.viewState_=viewState;this.histogram_=this.row.columns.get(displayLabel);if(this.viewState){this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));}
+this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+this.updateContents_();},get viewState(){return this.viewState_;},get row(){return this.row_;},get histogram(){return this.histogram_;},get referenceHistogram(){const referenceDisplayLabel=this.row.rootViewState.referenceDisplayLabel;if(!referenceDisplayLabel)return undefined;if(referenceDisplayLabel===this.displayLabel_)return undefined;return this.row.columns.get(referenceDisplayLabel);},get isHistogramOpen(){return(this.histogramSpan_!==undefined)&&(this.$.histogram.style.display==='block');},get brushedBinRange(){if(!this.isHistogramOpen)return new tr.b.math.Range();return this.histogramSpan_.brushedBinRange;},set brushedBinRange(r){if(this.histogramSpan_===undefined)return;this.histogramSpan_.brushedBinRange=r;},get mergeSampleDiagnostics(){if(!this.isHistogramOpen)return false;return this.histogramSpan_.mergeSampleDiagnostics;},set mergeSampleDiagnostics(m){if(this.histogramSpan_===undefined)return;this.histogramSpan_.mergeSampleDiagnostics=m;},set isHistogramOpen(open){if(!(this.histogram instanceof tr.v.Histogram)||(this.histogram.numValues===0)){return;}
+this.$.scalar.style.display=open?'none':'flex';this.$.open_histogram.style.display=open?'none':'block';this.$.close_histogram.style.display=open?'block':'none';this.$.histogram.style.display=open?'block':'none';if(open&&this.histogramSpan_===undefined){this.histogramSpan_=document.createElement('tr-v-ui-histogram-span');this.histogramSpan_.rowState=this.row.viewState;this.histogramSpan_.viewState=this.viewState;this.histogramSpan_.referenceHistogram=this.referenceHistogram;this.histogramSpan_.histogram=this.histogram;this.histogramSpan_.alpha=this.row.rootViewState.alpha;this.$.histogram.appendChild(this.histogramSpan_);}
+this.viewState.isOpen=open;},onViewStateUpdate_(event){if(event.delta.isOpen){this.isHistogramOpen=this.viewState.isOpen;}},onRowStateUpdate_(event){if(event.delta.isOverviewed===undefined)return;if(this.row.viewState.isOverviewed){this.showOverview();}else{this.hideOverview();}},onRootStateUpdate_(event){if(event.delta.displayStatisticName||event.delta.referenceDisplayLabel||event.delta.alpha){this.updateContents_();}
+if(this.row.viewState.isOverviewed&&(event.delta.sortColumnIndex||event.delta.sortDescending||event.delta.displayStatisticName||event.delta.referenceDisplayLabel)){if(this.overviewChart_!==undefined){this.$.overview_container.removeChild(this.overviewChart_);this.overviewChart_=undefined;}
+this.showOverview();}},onClick_(event){event.stopPropagation();},openHistogram_(){this.isHistogramOpen=true;tr.b.Timing.instant('histogram-set-table-cell','open');},closeHistogram_(){this.isHistogramOpen=false;tr.b.Timing.instant('histogram-set-table-cell','close');},updateContents_(){const isOpen=this.isHistogramOpen;this.$.empty.style.display='none';this.$.unmergeable.style.display='none';this.$.scalar.style.display='none';this.$.histogram.style.display='none';this.$.close_histogram.style.display='none';this.$.open_histogram.style.visibility='hidden';if(!this.histogram){this.$.missing.style.display='block';return;}
+this.$.missing.style.display='none';if(this.histogram instanceof tr.v.HistogramSet){this.$.unmergeable.style.display='block';return;}
+if(!(this.histogram instanceof tr.v.Histogram)){throw new Error('Invalid Histogram: '+this.histogram);}
+if(this.histogram.numValues===0){this.$.empty.style.display='block';return;}
+this.$.open_histogram.style.display='block';this.$.open_histogram.style.visibility='visible';this.$.scalar.style.display='flex';const referenceHistogram=this.referenceHistogram;if(this.histogramSpan_){this.histogramSpan_.referenceHistogram=referenceHistogram;this.histogramSpan_.alpha=this.row.rootViewState.alpha;}
+if((referenceHistogram instanceof tr.v.Histogram)&&(this.histogram.unit===referenceHistogram.unit)&&(referenceHistogram.numValues>0)){this.$.scalar.significance=this.histogram.getDifferenceSignificance(referenceHistogram,this.row.rootViewState.alpha);}
+const statName=this.histogram.getAvailableStatisticName(this.row.rootViewState.displayStatisticName,referenceHistogram);const statisticScalar=this.histogram.getStatisticScalar(statName,referenceHistogram);this.$.scalar.setValueAndUnit(statisticScalar.value,statisticScalar.unit);this.isHistogramOpen=isOpen;},showOverview(){this.$.overview_container.style.display='block';if(this.overviewChart_!==undefined)return;this.row.sortSubRows();let referenceDisplayLabel=this.row.rootViewState.referenceDisplayLabel;if(referenceDisplayLabel===this.displayLabel_){referenceDisplayLabel=undefined;}
+const displayStatisticName=this.row.rootViewState.displayStatisticName;const data=[];let unit;for(const subRow of this.row.subRows){const subHist=subRow.columns.get(this.displayLabel_);if(!(subHist instanceof tr.v.Histogram))continue;if(unit===undefined){unit=subHist.unit;}else if(unit!==subHist.unit){data.splice(0);break;}
+const refHist=subRow.columns.get(referenceDisplayLabel);const statName=subHist.getAvailableStatisticName(displayStatisticName,refHist);const statScalar=subHist.getStatisticScalar(statName,refHist);if(statScalar!==undefined){data.push({x:subRow.name,y:statScalar.value,});}}
+if(data.length<2)return;this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.displayXInHover=true;this.overviewChart_.hideLegend=true;this.overviewChart_.unit=unit;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;},hideOverview(){this.$.overview_container.style.display='none';}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){const NAME_COLUMN_WIDTH_PX=300;Polymer({is:'tr-v-ui-histogram-set-table-name-cell',created(){this.row_=undefined;this.overviewChart_=undefined;this.cellListener_=this.onCellStateUpdate_.bind(this);this.rootListener_=this.onRootStateUpdate_.bind(this);},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},get row(){return this.row_;},build(row){if(this.row_!==undefined){throw new Error('row must be set exactly once.');}
+this.row_=row;this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));this.constrainWidth=this.row.rootViewState.constrainNameColumn;if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+for(const cellState of this.row.viewState.cells.values()){cellState.addUpdateListener(this.cellListener_);}
+Polymer.dom(this.$.name).textContent=this.row.name;this.title=this.row.name;if(this.row.description){this.title+='\n'+this.row.description;}
+if(this.row.overviewDataRange.isEmpty||this.row.overviewDataRange.min===this.row.overviewDataRange.max){this.$.show_overview.style.display='none';}
+let histogramCount=0;for(const cell of this.row.columns.values()){if(cell instanceof tr.v.Histogram&&cell.numValues>0){++histogramCount;}}
+if(histogramCount<=1){this.$.open_histograms.style.display='none';}},set constrainWidth(constrain){this.$.name.style.maxWidth=constrain?(this.nameWidthPx+'px'):'none';},get nameWidthPx(){return NAME_COLUMN_WIDTH_PX-(16*this.row.depth);},get isOverflowing(){return this.$.name.style.maxWidth!=='none'&&this.$.name.getBoundingClientRect().width===this.nameWidthPx;},get isOverviewed(){return this.$.overview_container.style.display==='block';},set isOverviewed(isOverviewed){if(isOverviewed===this.isOverviewed)return;if(isOverviewed){this.showOverview_();}else{this.hideOverview_();}},hideOverview_(opt_event){this.$.overview_container.style.display='none';this.$.hide_overview.style.display='none';this.$.show_overview.style.display='block';if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','hideOverview');this.row.viewState.isOverviewed=this.isOverviewed;}},showOverview_(opt_event){if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','showOverview');this.row.viewState.isOverviewed=true;}
+this.$.overview_container.style.display='block';this.$.hide_overview.style.display='block';this.$.show_overview.style.display='none';if(this.overviewChart_===undefined){const displayStatisticName=this.row.rootViewState.displayStatisticName;const data=[];let unit;for(const[displayLabel,hist]of this.row.columns){if(!(hist instanceof tr.v.Histogram))continue;if(unit===undefined){unit=hist.unit;}else if(unit!==hist.unit){data.splice(0);break;}
+const statName=hist.getAvailableStatisticName(displayStatisticName);const statScalar=hist.getStatisticScalar(statName);if(statScalar!==undefined){data.push({x:displayLabel,y:statScalar.value,});}}
+if(data.length<2){return;}
+this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.displayXInHover=true;this.overviewChart_.hideLegend=true;this.overviewChart_.unit=unit;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;}},openHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','openHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=true;}
+this.$.close_histograms.style.display='block';this.$.open_histograms.style.display='none';},closeHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','closeHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=false;}
+this.$.open_histograms.style.display='block';this.$.close_histograms.style.display='none';},onRootStateUpdate_(event){if(event.delta.constrainNameColumn){this.constrainWidth=this.row.rootViewState.constrainNameColumn;}
+if(this.row.viewState.isOverviewed&&event.delta.displayStatisticName){this.row.resetOverviewDataRange();if(this.overviewChart_!==undefined){this.$.overview_container.removeChild(this.overviewChart_);this.overviewChart_=undefined;}
+this.showOverview_();}},onRowStateUpdate_(event){if(event.delta.isOverviewed){this.isOverviewed=this.row.viewState.isOverviewed;}},onCellStateUpdate_(event){if(!event.delta.isOpen)return;let cellCount=0;let openCellCount=0;for(const cell of this.row.cells.values()){if(!(cell.histogram instanceof tr.v.Histogram)||(cell.histogram.numValues===0)){continue;}
+++cellCount;if(cell.isHistogramOpen)++openCellCount;}
+if(cellCount<=1)return;const mostlyOpen=openCellCount>(cellCount/2);this.$.open_histograms.style.display=mostlyOpen?'none':'block';this.$.close_histograms.style.display=mostlyOpen?'block':'none';}});return{NAME_COLUMN_WIDTH_PX,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetTableRow{constructor(hierarchy,baseTable,rootViewState){this.hierarchy_=hierarchy;this.baseTable_=baseTable;this.rootViewState_=rootViewState;this.viewState_=new tr.v.ui.HistogramSetTableRowState();this.viewState_.addUpdateListener(this.onViewStateUpdate_.bind(this));this.overviewDataRange_=undefined;this.nameCell_=undefined;this.cells_=new Map();this.subRows_=[];for(const subHierarchy of hierarchy.subRows){const subRow=new HistogramSetTableRow(subHierarchy,baseTable,rootViewState);this.subRows_.push(subRow);this.viewState.subRows.set(subRow.name,subRow.viewState);}
+for(const columnName of this.columns.keys()){this.viewState.cells.set(columnName,new tr.v.ui.HistogramSetTableCellState());}}
+get name(){return this.hierarchy_.name;}
+get depth(){return this.hierarchy_.depth;}
+get description(){return this.hierarchy_.description;}
+get columns(){return this.hierarchy_.columns;}
+get overviewDataRange(){if(this.overviewDataRange_===undefined){this.overviewDataRange_=new tr.b.math.Range();const displayStatisticName=this.rootViewState.displayStatisticName;const referenceDisplayLabel=this.rootViewState.referenceDisplayLabel;for(const[displayLabel,hist]of this.columns){if(hist instanceof tr.v.Histogram){const statName=hist.getAvailableStatisticName(displayStatisticName);const statScalar=hist.getStatisticScalar(statName);if(statScalar!==undefined){this.overviewDataRange_.addValue(statScalar.value);}}
+for(const subRow of this.subRows){const subHist=subRow.columns.get(displayLabel);if(!(subHist instanceof tr.v.Histogram))continue;const refHist=subRow.columns.get(referenceDisplayLabel);const statName=subHist.getAvailableStatisticName(displayStatisticName,refHist);const statScalar=subHist.getStatisticScalar(statName,refHist);if(statScalar!==undefined){this.overviewDataRange_.addValue(statScalar.value);}}}}
+return this.overviewDataRange_;}
+resetOverviewDataRange(){this.overviewDataRange_=undefined;}
+get rootViewState(){return this.rootViewState_;}
+get cells(){return this.cells_;}
+get subRows(){return this.subRows_;}
+get viewState(){return this.viewState_;}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+get nameCell(){if(this.nameCell_===undefined){this.nameCell_=document.createElement('tr-v-ui-histogram-set-table-name-cell');this.nameCell_.build(this);}
+return this.nameCell_;}
+getCell(columnName){if(this.cells.has(columnName))return this.cells.get(columnName);const cell=document.createElement('tr-v-ui-histogram-set-table-cell');cell.build(this,columnName,this.viewState.cells.get(columnName));this.cells.set(columnName,cell);return cell;}
+compareNames(other){return this.name.localeCompare(other.name);}
+compareCells(other,displayLabel){const cellA=this.columns.get(displayLabel);const cellB=other.columns.get(displayLabel);if(!(cellA instanceof tr.v.Histogram)||!(cellB instanceof tr.v.Histogram)){return undefined;}
+let referenceCellA;let referenceCellB;const referenceDisplayLabel=this.rootViewState.referenceDisplayLabel;if(referenceDisplayLabel&&referenceDisplayLabel!==displayLabel){referenceCellA=this.columns.get(referenceDisplayLabel);referenceCellB=other.columns.get(referenceDisplayLabel);}
+const statisticA=cellA.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellA);const statisticB=cellB.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellB);const scalarA=cellA.getStatisticScalar(statisticA,referenceCellA);const scalarB=cellB.getStatisticScalar(statisticB,referenceCellB);const valueA=scalarA?scalarA.value:undefined;const valueB=scalarB?scalarB.value:undefined;return valueA-valueB;}
+onViewStateUpdate_(event){if(event.delta.isExpanded){this.baseTable_.setExpandedForTableRow(this,this.viewState.isExpanded);}
+if(event.delta.subRows){throw new Error('HistogramSetTableRow.subRows must not be reassigned.');}
+if(event.delta.cells){for(const[displayLabel,cell]of this.cells){if(cell.viewState!==this.viewState.cells.get(displayLabel)){throw new Error('Only HistogramSetTableRow may update cells');}}}}
+async restoreState(vs){await this.viewState.update({isExpanded:vs.isExpanded,isOverviewed:vs.isOverviewed,});for(const[displayLabel,cell]of this.cells){const previousState=vs.cells.get(displayLabel);if(!previousState)continue;await cell.viewState.updateFromViewState(previousState);}
+for(const row of this.subRows){const previousState=vs.subRows.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}
+sortSubRows(){const sortColumn=this.baseTable_.tableColumns[this.rootViewState_.sortColumnIndex];if(sortColumn===undefined)return;this.subRows_.sort(sortColumn.cmp);if(this.rootViewState_.sortDescending){this.subRows_.reverse();}}}
+return{HistogramSetTableRow,};});'use strict';tr.exportTo('tr.v.ui',function(){const MIDLINE_HORIZONTAL_ELLIPSIS=String.fromCharCode(0x22ef);function escapeRegExp(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&');}
+Polymer({is:'tr-v-ui-histogram-set-table',created(){this.viewState_=undefined;this.progress_=()=>Promise.resolve();this.nameColumnTitle_=undefined;this.displayLabels_=[];this.histograms_=undefined;this.sourceHistograms_=undefined;this.groupedHistograms_=undefined;this.hierarchies_=undefined;this.tableRows_=undefined;},ready(){this.$.table.zebra=true;this.addEventListener('sort-column-changed',this.onSortColumnChanged_.bind(this));this.addEventListener('requestSelectionChange',this.onRequestSelectionChange_.bind(this));this.addEventListener('row-expanded-changed',this.onRowExpandedChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},get histograms(){return this.histograms_;},async build(histograms,sourceHistograms,displayLabels,opt_progress){this.histograms_=histograms;this.sourceHistograms_=sourceHistograms;this.groupedHistograms_=undefined;this.displayLabels_=displayLabels;if(opt_progress!==undefined)this.progress_=opt_progress;if(histograms.length===0){throw new Error('histogram-set-table requires non-empty HistogramSet.');}
+await this.progress_('Building columns...');this.$.table.tableColumns=[{title:this.buildNameColumnTitle_(),value:row=>row.nameCell,cmp:(a,b)=>a.compareNames(b),}].concat(displayLabels.map(l=>this.buildColumn_(l)));tr.b.Timing.instant('histogram-set-table','columnCount',this.$.table.tableColumns.length);await this.updateContents_();this.fire('display-ready');this.progress_=()=>Promise.resolve();this.checkNameColumnOverflow_(tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows));},buildNameColumnTitle_(){this.nameColumnTitle_=document.createElement('span');this.nameColumnTitle_.style.display='inline-flex';const nameEl=document.createElement('span');nameEl.textContent='Name';this.nameColumnTitle_.appendChild(nameEl);const toggleWidthEl=document.createElement('span');toggleWidthEl.style.fontWeight='bold';toggleWidthEl.style.background='#bbb';toggleWidthEl.style.color='#333';toggleWidthEl.style.padding='0px 3px';toggleWidthEl.style.marginRight='8px';toggleWidthEl.style.display='none';toggleWidthEl.textContent=MIDLINE_HORIZONTAL_ELLIPSIS;toggleWidthEl.addEventListener('click',this.toggleNameColumnWidth_.bind(this));this.nameColumnTitle_.appendChild(toggleWidthEl);return this.nameColumnTitle_;},toggleNameColumnWidth_(opt_event){this.viewState.update({constrainNameColumn:!this.viewState.constrainNameColumn,});if(opt_event!==undefined){opt_event.stopPropagation();opt_event.preventDefault();tr.b.Timing.instant('histogram-set-table','nameColumn'+
+(this.viewState.constrainNameColumn?'Constrained':'Unconstrained'));}},buildColumn_(displayLabel){const title=document.createElement('span');title.textContent=displayLabel;title.style.whiteSpace='pre';return{title,value:row=>row.getCell(displayLabel),cmp:(rowA,rowB)=>rowA.compareCells(rowB,displayLabel),};},async updateContents_(){if(this.groupedHistograms_===undefined){await this.progress_('Grouping Histograms...');this.groupHistograms_();}
+if(this.hierarchies_===undefined){await this.progress_('Merging Histograms...');this.hierarchies_=tr.v.HistogramSetHierarchy.build(this.groupedHistograms_);this.tableRows_=undefined;}
+const tableRowsDirty=this.tableRows_===undefined;const previousRowStates=this.viewState.tableRowStates;if(tableRowsDirty){await this.progress_('Filtering rows...');let filteredHistograms=this.viewState.showAll?this.histograms:this.sourceHistograms_;if(this.viewState.searchQuery){let query=undefined;try{query=new RegExp(this.viewState.searchQuery);}catch(e){}
+if(query!==undefined){filteredHistograms=new tr.v.HistogramSet([...filteredHistograms].filter(hist=>hist.name.match(query)));}}
+const filteredHierarchies=tr.v.HistogramSetHierarchy.filter(this.hierarchies_,filteredHistograms);this.tableRows_=filteredHierarchies.map(hierarchy=>new tr.v.ui.HistogramSetTableRow(hierarchy,this.$.table,this.viewState));tr.b.Timing.instant('histogram-set-table','rootRowCount',this.tableRows_.length);const namesToRowStates=new Map();for(const row of this.tableRows_){namesToRowStates.set(row.name,row.viewState);}
+await this.viewState.update({tableRowStates:namesToRowStates});}
+await this.progress_('Configuring table...');this.nameColumnTitle_.children[1].style.filter=this.viewState.constrainNameColumn?'invert(100%)':'';const referenceDisplayLabelIndex=this.displayLabels_.indexOf(this.viewState.referenceDisplayLabel);this.$.table.selectedTableColumnIndex=(referenceDisplayLabelIndex<0)?undefined:(1+referenceDisplayLabelIndex);this.$.table.sortColumnIndex=this.viewState.sortColumnIndex;this.$.table.sortDescending=this.viewState.sortDescending;if(tableRowsDirty){await this.progress_('Building DOM...');this.$.table.tableRows=this.tableRows_;for(const row of this.tableRows_){const previousState=previousRowStates.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}
+this.$.table.rebuild();},async onRowExpandedChanged_(event){event.row.viewState.isExpanded=this.$.table.getExpandedForTableRow(event.row);tr.b.Timing.instant('histogram-set-table','row'+(event.row.viewState.isExpanded?'Expanded':'Collapsed'));if(this.nameColumnTitle_.children[1].style.display==='block')return;await tr.b.animationFrame();this.checkNameColumnOverflow_(event.row.subRows);},checkNameColumnOverflow_(rows){for(const row of rows){if(!row.nameCell.isOverflowing)continue;const[nameSpan,dots]=this.nameColumnTitle_.children;dots.style.display='block';const labelWidthPx=tr.v.ui.NAME_COLUMN_WIDTH_PX-
+dots.getBoundingClientRect().width;nameSpan.style.width=labelWidthPx+'px';return;}},groupHistograms_(){const groupings=this.viewState.groupings.slice();groupings.push(tr.v.HistogramGrouping.DISPLAY_LABEL);function canSkipGrouping(grouping,groupedHistograms){if(groupedHistograms.size>1)return false;if(grouping.key===groupings[0].key)return false;if(grouping.key===tr.v.HistogramGrouping.DISPLAY_LABEL.key){return false;}
+return true;}
+this.groupedHistograms_=this.histograms.groupHistogramsRecursively(groupings,canSkipGrouping);this.hierarchies_=undefined;},async onViewStateUpdate_(event){if(this.histograms_===undefined)return;if(event.delta.groupings!==undefined){this.groupedHistograms_=undefined;}
+if(event.delta.searchQuery!==undefined||event.delta.showAll!==undefined){this.tableRows_=undefined;}
+if(event.delta.displayStatistic!==undefined&&this.$.table.sortColumnIndex>0){this.$.table.sortColumnIndex=undefined;}
+if(event.delta.referenceDisplayLabel!==undefined||event.delta.displayStatisticName!==undefined){this.$.table.tableRows=this.$.table.tableRows;}
+if(event.delta.tableRowStates){if(this.tableRows_.length!==this.viewState.tableRowStates.size){throw new Error('Only histogram-set-table may update tableRowStates');}
+for(const row of this.tableRows_){if(this.viewState.tableRowStates.get(row.name)!==row.viewState){throw new Error('Only histogram-set-table may update tableRowStates');}}}
+await this.updateContents_();},onSortColumnChanged_(event){tr.b.Timing.instant('histogram-set-table','sortColumn');this.viewState.update({sortColumnIndex:event.sortColumnIndex,sortDescending:event.sortDescending,});},onRequestSelectionChange_(event){if(event.selection instanceof tr.model.EventSet)return;event.stopPropagation();tr.b.Timing.instant('histogram-set-table','selectHistogramNames');let histogramNames=event.selection;histogramNames.sort();histogramNames=histogramNames.map(escapeRegExp).join('|');this.viewState.update({showAll:true,searchQuery:`^(${histogramNames})$`,});},get leafHistograms(){const histograms=new tr.v.HistogramSet();for(const row of
+tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)){if(row.subRows.length)continue;for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+return histograms;}});return{MIDLINE_HORIZONTAL_ELLIPSIS,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-view',created(){this.brushingStateController_=new tr.ui.NullBrushingStateController();this.viewState_=new tr.v.ui.HistogramSetViewState();},ready(){this.$.table.viewState=this.viewState;this.$.controls.viewState=this.viewState;this.$.controls.addEventListener('download-csv',this.downloadCSV_.bind(this));},attached(){this.brushingStateController.parentController=tr.c.BrushingStateController.getControllerForElement(this.parentNode);},get brushingStateController(){return this.brushingStateController_;},get viewState(){return this.viewState_;},set helpHref(href){this.$.controls.helpHref=href;},set feedbackHref(href){this.$.controls.feedbackHref=href;},get histograms(){return this.$.table.histograms;},async build(histograms,opt_progress){const progress=opt_progress||(()=>Promise.resolve());if(histograms===undefined||histograms.length===0){this.$.container.style.display='none';this.$.zero.style.display='block';this.style.display='block';return;}
+this.$.zero.style.display='none';this.$.container.style.display='block';this.$.container.style.maxHeight=(window.innerHeight-16)+'px';const buildMark=tr.b.Timing.mark('histogram-set-view','build');await progress('Finding important Histograms...');const sourceHistogramsMark=tr.b.Timing.mark('histogram-set-view','sourceHistograms');const sourceHistograms=histograms.sourceHistograms;sourceHistogramsMark.end();this.$.controls.showAllEnabled=(sourceHistograms.length!==histograms.length);await progress('Collecting parameters...');const collectParametersMark=tr.b.Timing.mark('histogram-set-view','collectParameters');const parameterCollector=new tr.v.HistogramParameterCollector();parameterCollector.process(histograms);this.$.controls.baseStatisticNames=parameterCollector.statisticNames;this.$.controls.possibleGroupings=parameterCollector.possibleGroupings;const displayLabels=parameterCollector.labels;this.$.controls.displayLabels=displayLabels;collectParametersMark.end();await this.$.table.build(histograms,sourceHistograms,displayLabels,progress);buildMark.end();},downloadCSV_(){const downloadCSVMark=tr.b.Timing.mark('histogram-set-view','downloadCSV');const anchor=document.createElement('a');const path=window.location.pathname.split('/');const basename=path[path.length-1].split('.')[0]||'histograms';anchor.download=basename+'.csv';const csv=new tr.v.CSVBuilder(this.$.table.leafHistograms);csv.build();const blob=new window.Blob([csv.toString()],{type:'text/csv'});anchor.href=window.URL.createObjectURL(blob);anchor.click();downloadCSVMark.end();}});return{};});'use strict';tr.exportTo('tr.ui',function(){Polymer({is:'tr-ui-sp-metrics-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=undefined;this.metricLatenciesMs_=[];this.metrics_=[];tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(function(m){if(m.constructor.name==='sampleMetric')return;this.metrics_.push({label:m.constructor.name,value:m.constructor.name});},this);this.settingsKey_='metrics-side-panel-metric-name';this.currentMetricName_='responsivenessMetric';const metricSelector=tr.ui.b.createSelector(this,'currentMetricName_',this.settingsKey_,this.currentMetricName_,this.metrics_);Polymer.dom(this.$.top_left_controls).appendChild(metricSelector);metricSelector.addEventListener('change',this.onMetricChange_.bind(this));this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.recomputeButton_=tr.ui.b.createButton('Recompute',this.onRecompute_,this);Polymer.dom(this.$.top_left_controls).appendChild(this.recomputeButton_);this.$.results.addEventListener('display-ready',()=>{this.$.results.style.display='';});},async build(model){this.model_=model;await this.updateContents_();},get metricLatencyMs(){return tr.b.math.Statistics.mean(this.metricLatenciesMs_);},onMetricChange_(){this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.metricLatenciesMs_=[];this.updateContents_();},onRecompute_(){this.updateContents_();},get textLabel(){return'Metrics';},supportsModel(m){if(!m){return{supported:false,reason:'No model available'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.build(model);},get selection(){},set selection(_){},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){this.rangeOfInterest_=range;if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest){if((this.metricLatencyMs===undefined)||(this.metricLatencyMs<100)){this.updateContents_();}else{this.recomputeButton_.style.background='red';}}},async updateContents_(){Polymer.dom(this.$.error).textContent='';this.$.results.style.display='none';if(!this.model_){Polymer.dom(this.$.error).textContent='Missing model';return;}
+const options={metrics:[this.currentMetricName_]};if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest&&this.rangeOfInterest&&!this.rangeOfInterest.isEmpty){options.rangeOfInterest=this.rangeOfInterest;}
+const startDate=new Date();let histograms;try{histograms=tr.metrics.runMetrics(this.model_,options);}catch(err){Polymer.dom(this.$.error).textContent=err.message;return;}
+this.metricLatenciesMs_.push(new Date()-startDate);while(this.metricLatenciesMs_.length>20){this.metricLatenciesMs_.shift();}
+this.recomputeButton_.style.background='';await this.$.results.build(histograms);}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-metrics-side-panel');});return{};});'use strict';Polymer({is:'tr-ui-e-s-alerts-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType(alertTypeString){const alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_(alerts){const alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title]){alertsByType[alert.title]=[];}
+alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_(){return[{title:'Alert type',value(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value(row){return row.count;}}];},createAlertsTable_(alerts){const alertsByType=this.alertsByType_(alerts);const table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){const row=table.selectedTableRow;if(row){this.selectAlertsOfType(row.alertType);}}.bind(this));return table;},updateContents_(){Polymer.dom(this.$.result_area).textContent='';if(this.model_===undefined)return;const panel=this.createAlertsTable_(this.model_.alerts);Polymer.dom(this.$.result_area).appendChild(panel);},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+return{supported:true};},get textLabel(){return'Alerts';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-alerts-side-panel');});
+</script>
+</head>
+  <body>
+  </body>
+</html>
diff --git a/misc/trace/trace_viewer_lean.html b/misc/trace/trace_viewer_lean.html
deleted file mode 100644
index 076cb43..0000000
--- a/misc/trace/trace_viewer_lean.html
+++ /dev/null
@@ -1,7758 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head i18n-values="dir:textdirection;">
-  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
-<template id="overlay-template">
-  <style>
-    overlay-mask {
-      left: 0;
-      padding: 8px;
-      position: absolute;
-      top: 0;
-      z-index: 1000;
-      font-family: sans-serif;
-      -webkit-justify-content: center;
-      background: rgba(0, 0, 0, 0.8);
-      display: -webkit-flex;
-      height: 100%;
-      left: 0;
-      position: fixed;
-      top: 0;
-      width: 100%;
-    }
-    overlay-mask:focus {
-      outline: none;
-    }
-    overlay-vertical-centering-container {
-      -webkit-justify-content: center;
-      -webkit-flex-direction: column;
-      display: -webkit-flex;
-    }
-    overlay-frame {
-      z-index: 1100;
-      background: rgb(255, 255, 255);
-      border: 1px solid #ccc;
-      margin: 75px;
-      display: -webkit-flex;
-      -webkit-flex-direction: column;
-      min-height: 0;
-    }
-    title-bar {
-      -webkit-align-items: center;
-      -webkit-flex-direction: row;
-      border-bottom: 1px solid #ccc;
-      background-color: #ddd;
-      display: -webkit-flex;
-      padding: 5px;
-      -webkit-flex: 0 0 auto;
-    }
-    title {
-      display: inline;
-      font-weight: bold;
-      -webkit-box-flex: 1;
-      -webkit-flex: 1 1 auto;
-    }
-    close-button {
-      -webkit-align-self: flex-end;
-      border: 1px solid #eee;
-      background-color: #999;
-      font-size: 10pt;
-      font-weight: bold;
-      padding: 2px;
-      text-align: center;
-      width: 16px;
-    }
-    close-button:hover {
-      background-color: #ddd;
-      border-color: black;
-      cursor: pointer;
-    }
-    overlay-content {
-      display: -webkit-flex;
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: column;
-      overflow-y: auto;
-      padding: 10px;
-      min-width: 300px;
-      min-height: 0;
-    }
-    button-bar {
-      -webkit-align-items: baseline;
-      border-top: 1px solid #ccc;
-      display: -webkit-flex;
-      -webkit-flex: 0 0 auto;
-      -webkit-flex-direction: row-reverse;
-      padding: 4px;
-    }
-  </style>
-
-  <overlay-mask>
-    <overlay-vertical-centering-container>
-      <overlay-frame>
-        <title-bar>
-          <title></title>
-          <close-button>✕</close-button>
-        </title-bar>
-        <overlay-content>
-          <content></content>
-        </overlay-content>
-        <button-bar></button-bar>
-      </overlay-frame>
-    </overlay-vertical-centering-container>
-  </overlay-mask>
-</template><style>
-* /deep/ .labeled-checkbox {
-  display: flex;
-  white-space: nowrap;
-}
-</style><polymer-element is="a" name="tr-ui-a-analysis-link" on-click="{{onClicked_}}" on-mouseenter="{{onMouseEnter_}}" on-mouseleave="{{onMouseLeave_}}">
-  <template>
-    <style>
-    :host {
-      display: inline;
-      color: -webkit-link;
-      cursor: pointer;
-      text-decoration: underline;
-      cursor: pointer;
-    }
-    </style>
-    <content></content>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-table">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: column;
-      }
-
-      table {
-        font-size: 12px;
-
-        flex: 1 1 auto;
-        align-self: stretch;
-        border-collapse: separate;
-        border-spacing: 0;
-        border-width: 0;
-        -webkit-user-select: initial;
-      }
-
-      tr > td {
-        padding: 2px 4px 2px 4px;
-        vertical-align: text-top;
-      }
-
-      tr:focus,
-      td:focus {
-        outline: 1px dotted rgba(0,0,0,0.1);
-        outline-offset: 0;
-      }
-
-      button.toggle-button {
-        height: 15px;
-        line-height: 60%;
-        vertical-align: middle;
-        width: 100%;
-      }
-
-      button > * {
-        height: 15px;
-        vertical-align: middle;
-      }
-
-      td.button-column {
-        width: 30px;
-      }
-
-      table > thead > tr > td.sensitive:hover {
-        background-color: #fcfcfc;
-      }
-
-      table > thead > tr > td {
-        font-weight: bold;
-        text-align: left;
-
-        background-color: #eee;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-
-        border-top: 1px solid #ffffff;
-        border-bottom: 1px solid #aaa;
-      }
-
-      table > tfoot {
-        background-color: #eee;
-        font-weight: bold;
-      }
-
-      /* Light row and cell highlight. */
-      table > tbody[row-highlight-style="light"] > tr[selected],
-      table > tbody[cell-highlight-style="light"] > tr > td[selected] {
-        background-color: rgb(213, 236, 229);  /* light turquoise */
-      }
-      table > tbody[row-highlight-style="light"] >
-          tr:not(.empty-row):not([selected]):hover,
-      table > tbody[cell-highlight-style="light"] >
-          tr:not(.empty-row):not([selected]) > td:hover {
-        background-color: #f6f6f6;  /* light grey */
-      }
-
-      /* Dark row and cell highlight. */
-      table > tbody[row-highlight-style="dark"] > tr[selected],
-      table > tbody[cell-highlight-style="dark"] > tr > td[selected] {
-        background-color: rgb(103, 199, 165);  /* turquoise */
-      }
-      table > tbody[row-highlight-style="dark"] >
-          tr:not(.empty-row):not([selected]):hover,
-      table > tbody[cell-highlight-style="dark"] >
-          tr:not(.empty-row):not([selected]) > td:hover {
-        background-color: #e6e6e6;  /* grey */
-      }
-      table > tbody[row-highlight-style="dark"] > tr:hover[selected],
-      table > tbody[cell-highlight-style="dark"] > tr[selected] > td:hover {
-        background-color: rgb(171, 217, 202);  /* semi-light turquoise */
-      }
-
-      table > tbody > tr.empty-row > td {
-        color: #666;
-        font-style: italic;
-        text-align: center;
-      }
-
-      table > tbody.has-footer > tr:last-child > td {
-        border-bottom: 1px solid #aaa;
-      }
-
-      table > tfoot > tr:first-child > td {
-        border-top: 1px solid #ffffff;
-      }
-
-      expand-button {
-        -webkit-user-select: none;
-        display: inline-block;
-        cursor: pointer;
-        font-size: 9px;
-        min-width: 8px;
-        max-width: 8px;
-      }
-
-      .button-expanded {
-        transform: rotate(90deg);
-      }
-    </style>
-    <table>
-      <thead id="head">
-      </thead>
-      <tbody id="body">
-      </tbody>
-      <tfoot id="foot">
-      </tfoot>
-    </table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-table-header-cell" on-tap="onTap_">
-  <template>
-  <style>
-    :host {
-      -webkit-user-select: none;
-      display: flex;
-    }
-
-    span {
-      flex: 0 1 auto;
-    }
-
-    side-element {
-      -webkit-user-select: none;
-      flex: 1 0 auto;
-      padding-left: 4px;
-      vertical-align: top;
-      font-size: 15px;
-      font-family: sans-serif;
-      display: inline;
-      line-height: 85%;
-    }
-  </style>
-
-    <span id="title"></span><side-element id="side"></side-element>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-scalar-span">
-  <template>
-    <style>
-    :host {
-      display: block;
-      position: relative;
-    }
-    #content.right-align {
-      text-align: right;
-      position: relative;
-      display: block;
-    }
-    #sparkline {
-      width: 0%;
-      position: absolute;
-      bottom: 0;
-      right: 0;
-      display: none;
-      height: 100%;
-      background-color: hsla(216, 100%, 94.5%, .75);
-      border-left: 1px solid hsl(216, 100%, 89%);
-      box-sizing: border-box;
-    }
-    #warning {
-      margin-left: 4px;
-      font-size: 66%;
-    }
-    </style>
-    <span id="sparkline"></span>
-    <span id="content"></span>
-    <span id="warning" style="display:none">⚠</span>
-  </template>
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-      font-family: monospace;
-    }
-    </style>
-    <div id="content">
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view-with-label">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-    </style>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-drag-handle">
-  <template>
-    <style>
-    :host {
-      -webkit-user-select: none;
-      box-sizing: border-box;
-      display: block;
-    }
-
-    :host(.horizontal-drag-handle) {
-      background-image: -webkit-gradient(linear,
-                                         0 0, 0 100%,
-                                         from(#E5E5E5),
-                                         to(#D1D1D1));
-      border-bottom: 1px solid #8e8e8e;
-      border-top: 1px solid white;
-      cursor: ns-resize;
-      flex: 0 0 auto;
-      height: 7px;
-      position: relative;
-      z-index: 10;
-    }
-
-    :host(.vertical-drag-handle) {
-      background-image: -webkit-gradient(linear,
-                                         0 0, 100% 0,
-                                         from(#E5E5E5),
-                                         to(#D1D1D1));
-      border-left: 1px solid white;
-      border-right: 1px solid #8e8e8e;
-      cursor: ew-resize;
-      flex: 0 0 auto;
-      position: relative;
-      width: 7px;
-      z-index: 10;
-    }
-    </style>
-  </template>
-  
-</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
-  
-</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
-  <template>
-    <style>
-    :host {
-      align-items: center;
-      flex: 0 0 auto;
-      background-color: rgb(252, 235, 162);
-      border-bottom: 1px solid #A3A3A3;
-      border-left: 1px solid white;
-      border-right: 1px solid #A3A3A3;
-      border-top: 1px solid white;
-      display: flex;
-      height: 26px;
-      padding: 0 3px 0 3px;
-    }
-
-    :host(.info-bar-hidden) {
-      display: none;
-    }
-
-    #message { flex: 1 1 auto; }
-    </style>
-
-    <span id="message"></span>
-    <span id="buttons"></span>
-  </template>
-
-  
-</polymer-element><style>
-* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
-</style><polymer-element name="tr-ui-b-mouse-mode-icon">
-  <template>
-    <style>
-    :host {
-      display: block;
-      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
-      width: 27px;
-      height: 30px;
-    }
-    :host.active {
-      cursor: auto;
-    }
-    </style>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
-  <template>
-    <style>
-    :host {
-
-      -webkit-user-drag: element;
-      -webkit-user-select: none;
-
-      background: #DDD;
-      border: 1px solid #BBB;
-      border-radius: 4px;
-      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
-      left: calc(100% - 120px);
-      position: absolute;
-      top: 100px;
-      user-select: none;
-      width: 29px;
-      z-index: 20;
-    }
-
-    .drag-handle {
-      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
-      background-repeat: no-repeat;
-      border-bottom: 1px solid #BCBCBC;
-      cursor: move;
-      display: block;
-      height: 13px;
-      width: 27px;
-    }
-
-    .tool-button {
-      background-position: center center;
-      background-repeat: no-repeat;
-      border-bottom: 1px solid #BCBCBC;
-      border-top: 1px solid #F1F1F1;
-      cursor: pointer;
-    }
-
-    .buttons > .tool-button:last-child {
-      border-bottom: none;
-    }
-
-    </style>
-    <div class="drag-handle"></div>
-    <div class="buttons">
-    </div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-e-chrome-cc-display-item-list-item">
-  <template>
-    <style>
-      :host {
-        border-bottom: 1px solid #555;
-        display: block;
-        font-size: 12px;
-        padding: 3px 5px;
-      }
-
-      :host(:hover) {
-        background-color: #f0f0f0;
-        cursor: pointer;
-      }
-
-      .header {
-        font-weight: bold;
-        margin: 2px 0;
-      }
-
-      .header > .extra {
-        background-color: #777;
-        border-radius: 4px;
-        color: white;
-        margin: 0 6px;
-        text-decoration: none;
-        padding: 2px 4px;
-      }
-
-      .raw-details {
-        white-space: pre-wrap;
-      }
-
-      .details > dl {
-        margin: 0;
-      }
-
-      :host(:not([selected])) .details {
-        display: none;
-      }
-    </style>
-    <div class="header">
-      {{name}}
-      <template if="{{richDetails &amp;&amp; richDetails.skp64}}">
-        <a class="extra" download="drawing.skp" href="data:application/octet-stream;base64,{{richDetails.skp64}}" on-click="{{stopPropagation}}">SKP</a>
-      </template>
-    </div>
-    <div class="details">
-      <template if="{{rawDetails}}">
-        <div class="raw-details">{{rawDetails}}</div>
-      </template>
-      <template bind="{{richDetails}}" if="{{richDetails}}">
-        <dl>
-          <template bind="{{cullRect}}" if="{{cullRect}}">
-            <dt>Cull rect</dt>
-            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
-          </template>
-          <template bind="{{visualRect}}" if="{{visualRect}}">
-            <dt>Visual rect</dt>
-            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
-          </template>
-        </dl>
-      </template>
-    </div>
-  </template>
-  
-</polymer-element><style>
-* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
-</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
-  <style>
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info {
-    -webkit-flex: 1 1 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .export {
-    margin: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > tr-ui-b-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-      display-item-info > header {
-    border-bottom: 1px solid #555;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-b-drag-handle.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-list-view {
-    display: none;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-b-drag-handle {
-    display: none;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
-    -webkit-flex: 1 1 auto;
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
-  }
-  </style>
-
-  <left-panel>
-    <display-item-info>
-      <header>
-        <span class="title">Display Item List</span>
-        <span class="size"></span>
-        <div class="export">
-          <input class="dlfilename" type="text" value="displayitemlist.json"/>
-          <button class="dlexport">Export display item list</button>
-        </div>
-        <div class="export">
-          <input class="skpfilename" type="text" value="skpicture.skp"/>
-          <button class="skpexport">Export list as SkPicture</button>
-        </div>
-      </header>
-    </display-item-info>
-  </left-panel>
-  <right-panel>
-    <raster-area><canvas></canvas></raster-area>
-  </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
-</style><style>
-* /deep/ quad-stack-view {
-  display: block;
-  float: left;
-  height: 100%;
-  overflow: hidden;
-  position: relative; /* For the absolute positioned mouse-mode-selector */
-  width: 100%;
-}
-
-* /deep/ quad-stack-view > #header {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  left: 10px;
-  width: 800px;
-}
-* /deep/ quad-stack-view > #stacking-distance-slider {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  right: 10px;
-}
-
-* /deep/ quad-stack-view > #chrome-left {
-  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-mid {
-  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-right {
-  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
-  display: none;
-}
-</style><template id="quad-stack-view-template">
-  <div id="header"></div>
-  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
-  
-  <canvas id="canvas"></canvas>
-  <img id="chrome-left"/>
-  <img id="chrome-mid"/>
-  <img id="chrome-right"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
-  position: relative;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
-  -webkit-flex: 0 0 auto;
-  background-image: -webkit-gradient(linear,
-                                     0 0, 100% 0,
-                                     from(#E5E5E5),
-                                     to(#D1D1D1));
-  border-bottom: 1px solid #8e8e8e;
-  border-top: 1px solid white;
-  display: flex;
-  flex-flow: row wrap;
-  flex-direction: row;
-  font-size:  14px;
-  padding-left: 2px;
-  overflow: hidden;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
-      top-controls input[type='checkbox'] {
-  vertical-align: -2px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
-  color: -webkit-link;
-  cursor: pointer;
-  text-decoration: underline;
-  position: absolute;
-  bottom: 10px;
-  left: 10px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
-  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
-  display: none;
-}
-</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
-  <img id="input-event"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
-</style><style>
-* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-b-drag-handle{-webkit-flex:0 0 auto}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
-</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
-  <style>
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: row;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    width: 400px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
-    -webkit-flex: 0 0 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
-        picture-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-b-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
-    -webkit-user-select: text;
-    margin-left: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-chart-view {
-    min-height: 150px;
-    min-width : 0;
-    overflow-x: auto;
-    overflow-y: hidden;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
-  }
-  </style>
-
-  <left-panel>
-    <picture-info>
-      <div>
-        <span class="title">Skia Picture</span>
-        <span class="size"></span>
-      </div>
-      <div>
-        <input class="filename" type="text" value="skpicture.skp"/>
-        <button class="export">Export</button>
-      </div>
-    </picture-info>
-  </left-panel>
-  <right-panel>
-    <tr-ui-e-chrome-cc-picture-ops-chart-view>
-    </tr-ui-e-chrome-cc-picture-ops-chart-view>
-    <raster-area><canvas></canvas></raster-area>
-  </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
-</style><polymer-element name="tr-ui-a-sub-view">
-  
-</polymer-element><polymer-element name="tr-ui-a-stack-frame">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-      align-items: center;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #heading {
-      flex: 0 0 auto;
-    }
-    </style>
-
-    <div id="heading">
-      Rasterization costs in
-      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
-    </div>
-    <tr-ui-b-table id="content"></tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><style>
-.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
-</style><style>
-  * /deep/ .chart-base #title {
-    font-size: 16pt;
-  }
-
-  * /deep/ .chart-base {
-    font-size: 12pt;
-    -webkit-user-select: none;
-    cursor: default;
-  }
-
-  * /deep/ .chart-base .axis path,
-  * /deep/ .chart-base .axis line {
-    fill: none;
-    shape-rendering: crispEdges;
-    stroke: #000;
-  }
-</style><template id="chart-base-template">
-  <svg> 
-    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
-      <g class="x axis"></g>
-      <g class="y axis"></g>
-      <text id="title"></text>
-    </g>
-  </svg>
-</template><style>
-  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
-    fill: rgb(103, 199, 165)
-  }
-
-  * /deep/ .chart-base-2d #brushes {
-    fill: rgb(213, 236, 229)
-  }
-</style><style>
-* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
-</style><polymer-element name="tr-ui-side-panel">
-  
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
-  <template>
-    <style>
-    :host {
-      flex-direction: column;
-      display: flex;
-    }
-    toolbar {
-      flex: 0 0 auto;
-      border-bottom: 1px solid black;
-      display: flex;
-    }
-    result-area {
-      flex: 1 1 auto;
-      display: block;
-      min-height: 0;
-      overflow-y: auto;
-    }
-    </style>
-
-    <toolbar id="toolbar"></toolbar>
-    <result-area id="result_area"></result-area>
-  </template>
-
-  
-</polymer-element><style>
-* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
-</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
-  <template>
-    <style>
-    :host {
-      flex-direction: column;
-      display: flex;
-    }
-    toolbar {
-      flex: 0 0 auto;
-      border-bottom: 1px solid black;
-      display: flex;
-    }
-    result-area {
-      flex: 1 1 auto;
-      display: block;
-      min-height: 0;
-      overflow-y: auto;
-    }
-    </style>
-
-    <toolbar id="toolbar"></toolbar>
-    <result-area id="result_area"></result-area>
-  </template>
-
-  
-</polymer-element><style>
-.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
-</style><polymer-element name="tr-ui-heading">
-  <template>
-    <style>
-    :host {
-      background-color: rgb(243, 245, 247);
-      border-right: 1px solid #8e8e8e;
-      display: block;
-      height: 100%;
-      margin: 0;
-      padding: 0 5px 0 0;
-    }
-
-    heading {
-      display: block;
-      overflow-x: hidden;
-      text-align: left;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-
-    #arrow {
-      -webkit-flex: 0 0 auto;
-      font-family: sans-serif;
-      margin-left: 5px;
-      margin-right: 5px;
-      width: 8px;
-    }
-
-    #link, #heading_content {
-      display: none;
-    }
-    </style>
-    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
-      <span id="arrow"></span>
-      <span id="heading_content"></span>
-      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
-    </heading>
-  </template>
-
-  
-</polymer-element><style>
-.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
-</style><style>
-.object-instance-track{height:18px}
-</style><style>
-.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
-</style><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-stacked-pane">
-  
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-heap-details-pane">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: column;
-      }
-
-      #header {
-        flex: 0 0 auto;
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-
-        background-color: #eee;
-        border-bottom: 1px solid #8e8e8e;
-        border-top: 1px solid white;
-      }
-
-      #label {
-        flex: 1 1 auto;
-        padding: 8px;
-        font-size:  15px;
-        font-weight: bold;
-      }
-
-      #view_mode_container {
-        display: none;
-        flex: 0 0 auto;
-        padding: 5px;
-        font-size: 15px;
-      }
-
-      #contents {
-        flex: 1 0 auto;
-        align-self: stretch;
-        font-size: 12px;
-      }
-
-      #info_text {
-        padding: 8px;
-        color: #666;
-        font-style: italic;
-        text-align: center;
-      }
-
-      #table {
-        display: none;  /* Hide until memory allocator dumps are set. */
-        flex: 1 0 auto;
-        align-self: stretch;
-      }
-    </style>
-    <div id="header">
-      <div id="label">Heap details</div>
-      <div id="view_mode_container">
-        <span>View mode:</span>
-        
-      </div>
-    </div>
-    <div id="contents">
-      <tr-ui-b-info-bar class="info-bar-hidden" id="info_bar">
-      </tr-ui-b-info-bar>
-      <div id="info_text">No heap dump selected</div>
-      <tr-ui-b-table id="table"></tr-ui-b-table>
-    </div>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-allocator-details-pane">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: column;
-      }
-
-      #label {
-        flex: 0 0 auto;
-        padding: 8px;
-
-        background-color: #eee;
-        border-bottom: 1px solid #8e8e8e;
-        border-top: 1px solid white;
-
-        font-size:  15px;
-        font-weight: bold;
-      }
-
-      #contents {
-        flex: 1 0 auto;
-        align-self: stretch;
-        font-size: 12px;
-      }
-
-      #info_text {
-        padding: 8px;
-        color: #666;
-        font-style: italic;
-        text-align: center;
-      }
-
-      #table {
-        display: none;  /* Hide until memory allocator dumps are set. */
-        flex: 1 0 auto;
-        align-self: stretch;
-      }
-    </style>
-    <div id="label">Component details</div>
-    <div id="contents">
-      <div id="info_text">No memory allocator dump selected</div>
-      <tr-ui-b-table id="table"></tr-ui-b-table>
-    </div>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-vm-regions-details-pane">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: column;
-      }
-
-      #label {
-        flex: 0 0 auto;
-        padding: 8px;
-
-        background-color: #eee;
-        border-bottom: 1px solid #8e8e8e;
-        border-top: 1px solid white;
-
-        font-size:  15px;
-        font-weight: bold;
-      }
-
-      #contents {
-        flex: 1 0 auto;
-        align-self: stretch;
-        font-size: 12px;
-      }
-
-      #info_text {
-        padding: 8px;
-        color: #666;
-        font-style: italic;
-        text-align: center;
-      }
-
-      #table {
-        display: none;  /* Hide until memory dumps are set. */
-        flex: 1 0 auto;
-        align-self: stretch;
-      }
-    </style>
-    <div id="label">Memory maps</div>
-    <div id="contents">
-      <div id="info_text">No memory maps selected</div>
-      <tr-ui-b-table id="table"></tr-ui-b-table>
-    </div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-b-color-legend">
-  <template>
-    <style>
-    :host {
-      display: inline-block;
-    }
-
-    #square {
-      font-size: 150%;  /* Make the square bigger. */
-      line-height: 0%;  /* Prevent the square from increasing legend height. */
-    }
-    </style>
-    <span id="square"></span>
-    <span id="label"></span>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-view-specific-brushing-state">
-  
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-overview-pane">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: column;
-      }
-
-      #label {
-        flex: 0 0 auto;
-        padding: 8px;
-
-        background-color: #eee;
-        border-bottom: 1px solid #8e8e8e;
-        border-top: 1px solid white;
-
-        font-size:  15px;
-        font-weight: bold;
-      }
-
-      #contents {
-        flex: 1 0 auto;
-        align-self: stretch;
-        font-size: 12px;
-      }
-
-      #info_text {
-        padding: 8px;
-        color: #666;
-        font-style: italic;
-        text-align: center;
-      }
-
-      #table {
-        display: none;  /* Hide until memory dumps are set. */
-        flex: 1 0 auto;
-        align-self: stretch;
-      }
-    </style>
-    <tr-ui-b-view-specific-brushing-state id="state" view-id="analysis.memory_dump_overview_pane">
-    </tr-ui-b-view-specific-brushing-state>
-    <div id="label">Overview</div>
-    <div id="contents">
-      <div id="info_text">No memory memory dumps selected</div>
-      <tr-ui-b-table id="table"></tr-ui-b-table>
-    </div>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-header-pane">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-
-        background-color: #d0d0d0;
-        border-bottom: 1px solid #8e8e8e;
-        border-top: 1px solid white;
-      }
-
-      #label {
-        flex: 1 1 auto;
-        padding: 6px;
-        font-size: 15px;
-      }
-
-      #aggregation_mode_container {
-        display: none;
-        flex: 0 0 auto;
-        padding: 5px;
-        font-size: 15px;
-      }
-    </style>
-    
-    <div id="label"></div>
-    <div id="aggregation_mode_container">
-      <span>Metric aggregation:</span>
-      
-    </div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-a-stacked-pane-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-
-    #pane_container > * {
-      flex: 0 0 auto;
-    }
-    </style>
-    <div id="pane_container">
-    </div>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-container-memory-dump-sub-view">
-  <template>
-    <div id="content"></div>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-layout-tree-sub-view">
-  <template>
-    <div id="content"></div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-    
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-    
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-
-    #titletable {
-      font-weight: bold;
-    }
-
-    #title-info {
-      font-size: 12px;
-    }
-    </style>
-    <tr-ui-b-table id="titletable">
-    </tr-ui-b-table>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      overflow: auto;
-    }
-    #content {
-      display: flex;
-      flex-direction: column;
-      flex: 0 1 auto;
-      align-self: stretch;
-    }
-    #content > * {
-      flex: 0 0 auto;
-      align-self: stretch;
-    }
-    tr-ui-a-multi-event-summary-table {
-      border-bottom: 1px solid #aaa;
-    }
-
-    tr-ui-a-selection-summary-table  {
-      margin-top: 1.25em;
-      border-top: 1px solid #aaa;
-      background-color: #eee;
-      font-weight: bold;
-      margin-bottom: 1.25em;
-      border-bottom: 1px solid #aaa;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-related-events">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #container {
-      display: flex;
-      flex: 1 1 auto;
-    }
-    #events {
-      margin-left: 8px;
-      flex: 0 1 200px;
-    }
-    </style>
-    <div id="container">
-      <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-      <div id="events">
-        <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
-      </div>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      flex: 1 1 auto;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-b-table id="content"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-frame-power-usage-chart">
-  <template>
-    <div id="content"></div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
-  <template>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-power-sample-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-power-sample-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-    }
-    #tables {
-      display: flex;
-      flex-direction: column;
-      width: 50%;
-    }
-    #chart {
-      width: 50%;
-    }
-    </style>
-    <div id="tables">
-      <tr-ui-a-power-sample-summary-table id="summaryTable">
-      </tr-ui-a-power-sample-summary-table>
-      <tr-ui-a-power-sample-table id="samplesTable">
-      </tr-ui-a-power-sample-table>
-    </div>
-    <tr-ui-a-frame-power-usage-chart id="chart">
-    </tr-ui-a-frame-power-usage-chart>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
-  <template>
-    <style>
-    :host { display: block; }
-    #control {
-      background-color: #e6e6e6;
-      background-image: -webkit-gradient(linear, 0 0, 0 100%,
-                                         from(#E5E5E5), to(#D1D1D1));
-      flex: 0 0 auto;
-      overflow-x: auto;
-    }
-    #control::-webkit-scrollbar { height: 0px; }
-    #control {
-      font-size: 12px;
-      display: flex;
-      flex-direction: row;
-      align-items: stretch;
-      margin: 1px;
-      margin-right: 2px;
-    }
-    </style>
-    <div id="control">
-      Sample View Option
-    </div>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      display: flex;
-      flex: 1 1 auto;
-    }
-    #content > tr-ui-a-related-events {
-      margin-left: 8px;
-      flex: 0 1 200px;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      flex: 1 1 auto;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-a-user-expectation-related-samples-table">
-  <template>
-    <style>
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-user-expectation-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex: 1 1 auto;
-    }
-    #events {
-      margin-left: 8px;
-      flex: 0 1 200px;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="realView"></tr-ui-a-multi-event-sub-view>
-    <div id="events">
-      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
-    </div>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-async-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-    }
-    #events {
-      display:flex;
-      flex-direction: column;
-    }
-    </style>
-    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
-    <div id="events">
-      <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
-  <template>
-    <style>
-    table {
-      border-collapse: collapse;
-      border-width: 0;
-      margin-bottom: 25px;
-      width: 100%;
-    }
-
-    table tr > td:first-child {
-      padding-left: 2px;
-    }
-
-    table tr > td {
-      padding: 2px 4px 2px 4px;
-      vertical-align: text-top;
-      width: 150px;
-    }
-
-    table td td {
-      padding: 0 0 0 0;
-      width: auto;
-    }
-    tr {
-      vertical-align: top;
-    }
-
-    tr:nth-child(2n+0) {
-      background-color: #e2e2e2;
-    }
-    </style>
-    <table>
-      <tbody><tr>
-        <td>Running process:</td><td id="process-name"></td>
-      </tr>
-      <tr>
-        <td>Running thread:</td><td id="thread-name"></td>
-      </tr>
-      <tr>
-        <td>Start:</td>
-        <td>
-          <tr-v-ui-scalar-span id="start">
-          </tr-v-ui-scalar-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Duration:</td>
-        <td>
-          <tr-v-ui-scalar-span id="duration">
-          </tr-v-ui-scalar-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Active slices:</td><td id="running-thread"></td>
-      </tr>
-      <tr>
-        <td>Args:</td>
-        <td>
-          <tr-ui-a-generic-object-view id="args">
-          </tr-ui-a-generic-object-view>
-        </td>
-      </tr>
-    </tbody></table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #asv {
-      flex: 0 0 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-a-alert-sub-view id="asv">
-    </tr-ui-a-alert-sub-view>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-
-    #snapshots > * {
-      display: block;
-    }
-
-    :host {
-      overflow: auto;
-      display: block;
-    }
-
-    * {
-      -webkit-user-select: text;
-    }
-
-    .title {
-      border-bottom: 1px solid rgb(128, 128, 128);
-      font-size: 110%;
-      font-weight: bold;
-    }
-
-    td, th {
-      font-family: monospace;
-      vertical-align: top;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
-  <template>
-    <style>
-    #args {
-      white-space: pre;
-    }
-
-    :host {
-      overflow: auto;
-      display: flex;
-    }
-
-    ::content * {
-      -webkit-user-select: text;
-    }
-
-    ::content .title {
-      border-bottom: 1px solid rgb(128, 128, 128);
-      font-size: 110%;
-      font-weight: bold;
-    }
-
-    ::content td, th {
-      font-family: monospace;
-      vertical-align: top;
-    }
-    </style>
-    <content></content>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
-  <template>
-    <style>
-    :host { display: block; }
-    </style>
-    <tr-ui-a-power-sample-table id="samplesTable">
-    </tr-ui-a-power-sample-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-b-table id="content"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-    }
-    #events {
-      display: flex;
-      flex-direction: column;
-    }
-
-    </style>
-    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
-    <div id="events">
-      <tr-ui-a-related-events id="relatedEvents">
-      </tr-ui-a-related-events>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
-  <template>
-    <style>
-    table {
-      border-collapse: collapse;
-      border-width: 0;
-      margin-bottom: 25px;
-      width: 100%;
-    }
-
-    table tr > td:first-child {
-      padding-left: 2px;
-    }
-
-    table tr > td {
-      padding: 2px 4px 2px 4px;
-      vertical-align: text-top;
-      width: 150px;
-    }
-
-    table td td {
-      padding: 0 0 0 0;
-      width: auto;
-    }
-    tr {
-      vertical-align: top;
-    }
-
-    tr:nth-child(2n+0) {
-      background-color: #e2e2e2;
-    }
-    </style>
-    <table>
-      <tbody><tr>
-        <td>Running process:</td><td id="process-name"></td>
-      </tr>
-      <tr>
-        <td>Running thread:</td><td id="thread-name"></td>
-      </tr>
-      <tr>
-        <td>State:</td>
-        <td><b><span id="state"></span></b></td>
-      </tr>
-      <tr>
-        <td>Start:</td>
-        <td>
-          <tr-v-ui-scalar-span id="start">
-          </tr-v-ui-scalar-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Duration:</td>
-        <td>
-          <tr-v-ui-scalar-span id="duration">
-          </tr-v-ui-scalar-span>
-        </td>
-      </tr>
-
-      <tr>
-        <td>On CPU:</td><td id="on-cpu"></td>
-      </tr>
-
-      <tr>
-        <td>Running instead:</td><td id="running-instead"></td>
-      </tr>
-
-      <tr>
-        <td>Args:</td><td id="args"></td>
-      </tr>
-    </tbody></table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-user-expectation-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-    }
-    #events {
-      display: flex;
-      flex-direction: column;
-    }
-    </style>
-    <tr-ui-a-single-event-sub-view id="realView"></tr-ui-a-single-event-sub-view>
-    <div id="events">
-      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
-    </div>
-  </template>
-  
-</polymer-element><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-flow: column nowrap;
-        overflow: hidden;
-        box-sizing: border-box;
-      }
-
-      tab-strip[tabs-hidden] {
-        display: none;
-      }
-
-      tab-strip {
-        background-color: rgb(236, 236, 236);
-        border-bottom: 1px solid #8e8e8e;
-        display: flex;
-        flex: 0 0 auto;
-        flex-flow: row;
-        overflow-x: auto;
-        padding: 0 10px 0 10px;
-        font-size: 12px;
-      }
-
-      tab-button {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-      }
-
-      tab-button[selected=true] {
-        background-color: white;
-        border: 1px solid rgb(163, 163, 163);
-        border-bottom: none;
-        padding: 3px 14px 1px 14px;
-      }
-
-      tabs-content-container {
-        display: flex;
-        flex: 1 1 auto;
-        overflow: auto;
-        width: 100%;
-      }
-
-      ::content > * {
-        flex: 1 1 auto;
-      }
-
-      ::content > *:not([selected]) {
-        display: none;
-      }
-
-      button-label {
-        display: inline;
-      }
-
-      tab-strip-heading {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-        margin-before: 20px;
-        margin-after: 10px;
-      }
-      #tsh {
-        display: inline;
-        font-weight: bold;
-      }
-    </style>
-
-    <tab-strip>
-      <tab-strip-heading id="tshh">
-        <span id="tsh"></span>
-      </tab-strip-heading>
-      <template repeat="{{tab in tabs_}}">
-        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
-          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
-        </tab-button>
-      </template>
-    </tab-strip>
-
-    <tabs-content-container id="content-container">
-        <content></content>
-    </tabs-content-container>
-
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-a-analysis-view">
-  <template>
-    <style>
-      :host {
-        background-color: white;
-        display: flex;
-        flex-direction: column;
-        height: 275px;
-        overflow: auto;
-      }
-
-      :host(.tall-mode) {
-        height: 525px;
-      }
-
-      ::content > * {
-        flex: 1 0 auto;
-      }
-    </style>
-    <content></content>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-dropdown">
-  <template>
-    <style>
-    :host {
-      position: relative;
-      display: flex;
-    }
-    #outer {
-      display: flex;
-      flex: 0 0 auto;
-      padding: 1px 4px 1px 4px;
-      -webkit-user-select: none;
-      cursor: default;
-    }
-
-    #state {
-      display: flex;
-      flex: 0 0 auto;
-      margin-left: 2px;
-      margin-right: 0px;
-      flex: 0 0 auto;
-    }
-
-    #icon {
-      display: flex;
-      flex: 0 0 auto;
-      flex: 0 0 auto;
-    }
-    dialog {
-      position: absolute;
-      padding: 0;
-      border: 0;
-      margin: 0;
-    }
-    dialog::backdrop {
-      background: rgba(0,0,0,.05);
-    }
-
-    #dialog-frame {
-      background-color: #fff;
-      display: flex;
-      flex-direction: column;
-      flex: 1 1 auto;
-      padding: 6px;
-      border: 1px solid black;
-      -webkit-user-select: none;
-      cursor: default;
-    }
-    </style>
-    <tr-ui-b-toolbar-button id="outer" on-click="{{ onOuterClick_ }}" on-keydown="{{ onOuterKeyDown_ }}">
-      <div id="icon">⚙</div>
-      <div id="state">▾</div>
-    </tr-ui-b-toolbar-button>
-    <dialog id="dialog" on-cancel="{{ onDialogCancel_ }}" on-click="{{ onDialogClick_ }}">
-      <div id="dialog-frame">
-        <content></content>
-      </div>
-    </dialog>
-  </template>
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-b-info-bar-group">
-  <template>
-    <style>
-    :host {
-      flex: 0 0 auto;
-      flex-direction: column;
-      display: flex;
-    }
-    </style>
-    <div id="messages"></div>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-toolbar-button" noscript="">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      background-color: #f8f8f8;
-      border: 1px solid rgba(0, 0, 0, 0.5);
-      color: rgba(0,0,0,0.8);
-      justify-content: center;
-      align-self: stretch;
-      min-width: 23px;
-    }
-
-    :host(:hover) {
-      background-color: rgba(255, 255, 255, 1.0);
-      border-color: rgba(0, 0, 0, 0.8);
-      box-shadow: 0 0 .05em rgba(0, 0, 0, 0.4);
-      color: rgba(0, 0, 0, 1);
-    }
-
-    #aligner {
-      display: flex;
-      flex: 0 0 auto;
-      align-self: center;
-    }
-    </style>
-    <div id="aligner">
-      <content></content>
-    </div>
-  </template>
-</polymer-element><style>
-.drawing-container{-webkit-box-flex:1;display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{-webkit-box-flex:1;display:block;pointer-events:none;position:absolute;top:0}
-</style><style>
-.letter-dot-track {
-  height: 18px;
-}
-</style><style>
-.chart-track {
-  height: 30px;
-  position: relative;
-}
-</style><style>
-.power-series-track {
-  height: 90px;
-}
-</style><style>
-.spacing-track{height:4px}
-</style><style>
-.rect-track{height:18px}
-</style><style>
-.thread-track{-webkit-box-orient:vertical;display:-webkit-box;position:relative}
-</style><style>
-.process-track-header{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}
-</style><style>
-.model-track {
-  -webkit-box-flex: 1;
-}
-</style><style>
-.ruler-track{height:12px}.ruler-track.tall-mode{height:30px}
-</style><polymer-element name="tr-ui-timeline-track-view">
-  <template>
-    <style>
-    :host {
-      -webkit-box-orient: vertical;
-      display: -webkit-box;
-      position: relative;
-    }
-
-    :host ::content * {
-      -webkit-user-select: none;
-      cursor: default;
-    }
-
-    #drag_box {
-      background-color: rgba(0, 0, 255, 0.25);
-      border: 1px solid rgb(0, 0, 96);
-      font-size: 75%;
-      position: fixed;
-    }
-
-    #hint_text {
-      position: absolute;
-      bottom: 6px;
-      right: 6px;
-      font-size: 8pt;
-    }
-    </style>
-    <content></content>
-
-    <div id="drag_box"></div>
-    <div id="hint_text"></div>
-
-    <tv-ui-b-hotkey-controller id="hotkey_controller">
-    </tv-ui-b-hotkey-controller>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-find-control">
-  <template>
-    <style>
-      :host {
-        -webkit-user-select: none;
-        display: -webkit-flex;
-        position: relative;
-      }
-      input {
-        -webkit-user-select: auto;
-        background-color: #f8f8f8;
-        border: 1px solid rgba(0, 0, 0, 0.5);
-        box-sizing: border-box;
-        margin: 0;
-        padding: 0;
-        width: 170px;
-      }
-      input:focus {
-        background-color: white;
-      }
-      tr-ui-b-toolbar-button {
-        border-left: none;
-        margin: 0;
-      }
-      #hitCount {
-        left: 0;
-        opacity: 0.25;
-        pointer-events: none;
-        position: absolute;
-        text-align: right;
-        top: 2px;
-        width: 167px;
-        z-index: 1;
-      }
-      #spinner {
-        visibility: hidden;
-        width: 8px;
-        height: 8px;
-        left: 154px;
-        pointer-events: none;
-        position: absolute;
-        top: 4px;
-        z-index: 1;
-
-        border: 2px solid transparent;
-        border-bottom: 2px solid rgba(0, 0, 0, 0.5);
-        border-right: 2px solid rgba(0, 0, 0, 0.5);
-        border-radius: 50%;
-
-        animation: spin 1s linear infinite;
-      }
-      @keyframes spin { 100% { transform: rotate(360deg); } }
-    </style>
-
-    <input id="filter" on-blur="{{ filterBlur }}" on-focus="{{ filterFocus }}" on-input="{{ filterTextChanged }}" on-keydown="{{ filterKeyDown }}" on-mouseup="{{ filterMouseUp }}" type="text"/>
-    <div id="spinner"></div>
-    <tr-ui-b-toolbar-button on-click="{{ findPrevious }}">
-      ←
-    </tr-ui-b-toolbar-button>
-    <tr-ui-b-toolbar-button on-click="{{ findNext }}">
-      →
-    </tr-ui-b-toolbar-button>
-    <div id="hitCount">0 of 0</div>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-scripting-control">
-  <template>
-    <style>
-      :host {
-        flex: 1 1 auto;
-      }
-      .root {
-        font-family: monospace;
-        cursor: text;
-
-        padding: 2px;
-        margin: 2px;
-        border: 1px solid rgba(0, 0, 0, 0.5);
-        background: white;
-
-        height: 100px;
-        overflow-y: auto;
-
-        transition-property: opacity, height, padding, margin;
-        transition-duration: .2s;
-        transition-timing-function: ease-out;
-      }
-      .hidden {
-        margin-top: 0px;
-        margin-bottom: 0px;
-        padding-top: 0px;
-        padding-bottom: 0px;
-        height: 0px;
-        opacity: 0;
-      }
-      .focused {
-        outline: auto 5px -webkit-focus-ring-color;
-      }
-      #history {
-        -webkit-user-select: text;
-        color: #777;
-      }
-      #prompt {
-        -webkit-user-select: text;
-        -webkit-user-modify: read-write-plaintext-only;
-        text-overflow: clip !important;
-        text-decoration: none !important;
-      }
-      #prompt:focus {
-        outline: none;
-      }
-      #prompt br {
-        display: none;
-      }
-      #prompt ::before {
-        content: ">";
-        color: #468;
-      }
-    </style>
-
-    <div class="root hidden" id="root" on-focus="{{ onConsoleFocus }}" tabindex="0">
-      <div id="history"></div>
-      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}"></div>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-side-panel-container">
-  <template>
-    <style>
-    :host {
-      align-items: stretch;
-      display: -webkit-flex;
-    }
-
-    :host([expanded]) > active-panel-container {
-      -webkit-flex: 1 1 auto;
-      border-left: 1px solid black;
-      display: -webkit-flex;
-    }
-
-    :host(:not([expanded])) > active-panel-container {
-      display: none;
-    }
-
-    active-panel-container {
-      display: flex;
-    }
-
-    tab-strip {
-      -webkit-flex: 0 0 auto;
-      -webkit-flex-direction: column;
-      -webkit-user-select: none;
-      background-color: rgb(236, 236, 236);
-      border-left: 1px solid black;
-      cursor: default;
-      display: -webkit-flex;
-      min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
-      padding: 10px 0 10px 0;
-      font-size: 12px;
-    }
-
-    tab-strip > tab-strip-label {
-      -webkit-writing-mode: vertical-rl;
-      display: inline;
-      margin-right: 1px;
-      min-height: 20px;
-      padding: 15px 3px 15px 1px;
-    }
-
-    tab-strip >
-        tab-strip-label:not([enabled]) {
-      color: rgb(128, 128, 128);
-    }
-
-    tab-strip > tab-strip-label[selected] {
-      background-color: white;
-      border: 1px solid rgb(163, 163, 163);
-      border-left: none;
-      padding: 14px 2px 14px 1px;
-    }
-    </style>
-
-    <active-panel-container id="active_panel_container">
-    </active-panel-container>
-    <tab-strip id="tab_strip"></tab-strip>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-timeline-view-help-overlay">
-  <template>
-    <style>
-    :host {
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: row;
-      display: -webkit-flex;
-      width: 700px;
-    }
-    .column {
-      width: 50%;
-    }
-    h2 {
-      font-size: 1.2em;
-      margin: 0;
-      margin-top: 5px;
-      text-align: center;
-    }
-    h3 {
-      margin: 0;
-      margin-left: 126px;
-      margin-top: 10px;
-    }
-    .pair {
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: row;
-      display: -webkit-flex;
-    }
-    .command {
-      font-family: monospace;
-      margin-right: 5px;
-      text-align: right;
-      width: 150px;
-    }
-    .action {
-      font-size: 0.9em;
-      text-align: left;
-      width: 200px;
-    }
-    tr-ui-b-mouse-mode-icon {
-      border: 1px solid #888;
-      border-radius: 3px;
-      box-shadow: inset 0 0 2px rgba(0,0,0,0.3);
-      display: inline-block;
-      margin-right: 1px;
-      position: relative;
-      top: 4px;
-    }
-    .mouse-mode-icon.pan-mode {
-      background-position: -1px -11px;
-    }
-    .mouse-mode-icon.select-mode {
-      background-position: -1px -41px;
-    }
-    .mouse-mode-icon.zoom-mode {
-      background-position: -1px -71px;
-    }
-    .mouse-mode-icon.timing-mode {
-      background-position: -1px -101px;
-    }
-    </style>
-    <div class="column left">
-      <h2>Navigation</h2>
-      <div class="pair">
-        <div class="command">w/s</div>
-        <div class="action">Zoom in/out (+shift: faster)</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">a/d</div>
-        <div class="action">Pan left/right (+shift: faster)</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">→/shift-TAB</div>
-        <div class="action">Select previous event</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">←/TAB</div>
-        <div class="action">Select next event</div>
-      </div>
-
-      <h2>Mouse Controls</h2>
-      <div class="pair">
-        <div class="command">click</div>
-        <div class="action">Select event</div>
-      </div>
-      <div class="pair">
-        <div class="command">alt-mousewheel</div>
-        <div class="action">Zoom in/out</div>
-      </div>
-
-      <h3>
-        <tr-ui-b-mouse-mode-icon modename="SELECTION"></tr-ui-b-mouse-mode-icon>
-        Select mode
-      </h3>
-      <div class="pair">
-        <div class="command">drag</div>
-        <div class="action">Box select</div>
-      </div>
-
-      <div class="pair">
-        <div class="command"><span class="mod"></span>-click/drag</div>
-        <div class="action">Add events to the current selection</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">double click</div>
-        <div class="action">Select all events with same title</div>
-      </div>
-
-      <h3>
-        <tr-ui-b-mouse-mode-icon modename="PANSCAN"></tr-ui-b-mouse-mode-icon>
-        Pan mode
-      </h3>
-      <div class="pair">
-        <div class="command">drag</div>
-        <div class="action">Pan the view</div>
-      </div>
-
-      <h3>
-        <tr-ui-b-mouse-mode-icon modename="ZOOM"></tr-ui-b-mouse-mode-icon>
-        Zoom mode
-      </h3>
-      <div class="pair">
-        <div class="command">drag</div>
-        <div class="action">Zoom in/out by dragging up/down</div>
-      </div>
-
-      <h3>
-        <tr-ui-b-mouse-mode-icon modename="TIMING"></tr-ui-b-mouse-mode-icon>
-        Timing mode
-      </h3>
-      <div class="pair">
-        <div class="command">drag</div>
-        <div class="action">Create or move markers</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">double click</div>
-        <div class="action">Set marker range to slice</div>
-      </div>
-    </div>
-
-    <div class="column right">
-      <h2>General</h2>
-      <div class="pair">
-        <div class="command">1-4</div>
-        <div class="action">Switch mouse mode</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">shift</div>
-        <div class="action">Hold for temporary select</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">space</div>
-        <div class="action">Hold for temporary pan</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">/</div>
-        <div class="action">Search</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">enter</div>
-        <div class="action">Step through search results</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">f</div>
-        <div class="action">Zoom into selection</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">z/0</div>
-        <div class="action">Reset zoom and pan</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">g/G</div>
-        <div class="action">Toggle 60hz grid</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">v</div>
-        <div class="action">Highlight VSync</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">h</div>
-        <div class="action">Toggle low/high details</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">m</div>
-        <div class="action">Mark current selection</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">`</div>
-        <div class="action">Show or hide the scripting console</div>
-      </div>
-
-      <div class="pair">
-        <div class="command">?</div>
-        <div class="action">Show help</div>
-      </div>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-array-of-numbers-span">
-  <template>
-  </template>
-  
-</polymer-element><polymer-element name="tr-v-ui-generic-table-view">
-  <template>
-    <style>
-    :host {
-    display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element name="tr-ui-timeline-view-metadata-overlay">
-  <template>
-    <style>
-    :host {
-      width: 700px;
-
-      overflow: auto;
-    }
-    </style>
-    <tr-v-ui-generic-table-view id="gtv"></tr-v-ui-generic-table-view>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-preferred-display-unit">
-  
-</polymer-element><polymer-element name="tr-ui-timeline-view">
-  <template>
-    <style>
-    :host {
-      flex-direction: column;
-      cursor: default;
-      display: flex;
-      font-family: sans-serif;
-      padding: 0;
-    }
-
-    #control {
-      background-color: #e6e6e6;
-      background-image: -webkit-gradient(linear, 0 0, 0 100%,
-          from(#E5E5E5), to(#D1D1D1));
-      flex: 0 0 auto;
-      overflow-x: auto;
-    }
-
-    #control::-webkit-scrollbar { height: 0px; }
-
-    #control > #bar {
-      font-size: 12px;
-      display: flex;
-      flex-direction: row;
-      margin: 1px;
-    }
-
-    #control > #bar > #title {
-      display: flex;
-      align-items: center;
-      padding-left: 8px;
-      padding-right: 8px;
-      flex: 1 1 auto;
-    }
-
-    #control > #bar > #left_controls,
-    #control > #bar > #right_controls {
-      display: flex;
-      flex-direction: row;
-      align-items: stretch;
-    }
-
-    #control > #bar > #left_controls > * { margin-right: 2px; }
-    #control > #bar > #right_controls > * { margin-left: 2px; }
-    #control > #collapsing_controls { display: flex; }
-
-    middle-container {
-      flex: 1 1 auto;
-      flex-direction: row;
-      border-bottom: 1px solid #8e8e8e;
-      display: flex;
-      min-height: 0;
-    }
-
-    middle-container ::content track-view-container {
-      flex: 1 1 auto;
-      display: flex;
-      min-height: 0;
-      min-width: 0;
-    }
-
-    middle-container ::content track-view-container > * { flex: 1 1 auto; }
-    middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
-    tr-ui-b-drag-handle { flex: 0 0 auto; }
-    tr-ui-a-analysis-view { flex: 0 0 auto; }
-    </style>
-
-    <tv-ui-b-hotkey-controller id="hkc"></tv-ui-b-hotkey-controller>
-    <div id="control">
-      <div id="bar">
-        <div id="left_controls"></div>
-        <div id="title">^_^</div>
-        <div id="right_controls">
-          <tr-ui-b-toolbar-button id="view_metadata_button">
-            M
-          </tr-ui-b-toolbar-button>
-          <tr-ui-b-dropdown id="view_options_dropdown"></tr-ui-b-dropdown>
-          <tr-ui-find-control id="view_find_control"></tr-ui-find-control>
-          <tr-ui-b-toolbar-button id="view_console_button">
-            »
-          </tr-ui-b-toolbar-button>
-          <tr-ui-b-toolbar-button id="view_help_button">
-            ?
-          </tr-ui-b-toolbar-button>
-        </div>
-      </div>
-      <div id="collapsing_controls"></div>
-      <tr-ui-b-info-bar-group id="import-warnings">
-      </tr-ui-b-info-bar-group>
-    </div>
-    <middle-container>
-      <content></content>
-
-      <tr-ui-side-panel-container id="side_panel_container">
-      </tr-ui-side-panel-container>
-    </middle-container>
-    <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
-    <tr-ui-a-analysis-view id="analysis"></tr-ui-a-analysis-view>
-
-    <tr-v-ui-preferred-display-unit id="display_unit">
-    </tr-v-ui-preferred-display-unit>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-grouping-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element name="tr-ui-b-grouping-table-groupby-picker">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-      align-items: center;
-    }
-    groups {
-      -webkit-user-select: none;
-      display: flex;
-      flex-direction: row;
-      padding-left: 10px;
-    }
-
-    group, possible-group {
-      display: span;
-      padding-right: 10px;
-      padding-left: 10px;
-    }
-
-    group {
-      border-left: 1px solid rgba(0,0,0,0);
-      cursor: move;
-    }
-
-    group.dragging {
-      opacity: 0.2;
-    }
-
-    group.drop-targeted {
-      border-left: 1px solid black;
-    }
-
-
-    #remove {
-      cursor: default;
-    }
-
-    #remove:not([hovered]) {
-      visibility: hidden;
-    }
-    </style>
-    <groups>
-    </groups>
-    <tr-ui-b-dropdown id="add-group"></tr-ui-b-dropdown>
-  </template>
-</polymer-element><template id="tr-ui-b-grouping-table-groupby-picker-group-template">
-  <span id="key"></span>
-  <span id="remove">×</span>
-</template><polymer-element extends="tr-ui-side-panel" name="tr-ui-sp-file-size-stats-side-panel">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-      width: 600px;
-    }
-    toolbar {
-      align-items: center;
-      background-color: rgb(236, 236, 236);
-      border-bottom: 1px solid #8e8e8e;
-      display: flex;
-      flex-direction: row;
-      flex-direction: row;
-      flex: 0 0 auto;
-      font-size: 12px;
-      padding: 0 10px 0 10px;
-    }
-    table-container {
-      display: flex;
-      min-height: 0px;
-      overflow-y: auto;
-    }
-    </style>
-
-    <toolbar>
-      <span><b>Group by:</b></span>
-      <tr-ui-b-grouping-table-groupby-picker id="picker">
-      </tr-ui-b-grouping-table-groupby-picker>
-    </toolbar>
-    <table-container>
-      <tr-ui-b-grouping-table id="table"></tr-ui-b-grouping-table>
-    </table-container>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-alerts-side-panel">
-  <template>
-    <style>
-    :host {
-      display: block;
-      width: 250px;
-    }
-    #content {
-      flex-direction: column;
-      display: flex;
-    }
-    </style>
-
-    <div id="content">
-      <toolbar id="toolbar"></toolbar>
-      <result-area id="result_area"></result-area>
-    </div>
-  </template>
-
-  
-</polymer-element><script>
-
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/* WARNING: This file is auto generated.
- *
- * Do not edit directly.
- */
-
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.PolymerGestures={},function(a){var b=!1,c=document.createElement("meta");if(c.createShadowRoot){var d=c.createShadowRoot(),e=document.createElement("span");d.appendChild(e),c.addEventListener("testpath",function(a){a.path&&(b=a.path[0]===e),a.stopPropagation()});var f=new CustomEvent("testpath",{bubbles:!0});document.head.appendChild(c),e.dispatchEvent(f),c.parentNode.removeChild(c),d=e=null}c=null;var g={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){var d,e;return a?(d=a.elementFromPoint(b,c),d?e=this.targetingShadow(d):a!==document&&(e=this.olderShadow(a)),this.searchRoot(e,b,c)||d):void 0},owner:function(a){if(!a)return document;for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){if(b&&a.path&&a.path.length)return a.path[0];var c=a.clientX,d=a.clientY,e=this.owner(a.target);return e.elementFromPoint(c,d)||(e=document),this.searchRoot(e,c,d)},findTouchAction:function(a){var c;if(b&&a.path&&a.path.length){for(var d=a.path,e=0;e<d.length;e++)if(c=d[e],c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action")}else for(c=a.target;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action");c=c.parentNode||c.host}return"auto"},LCA:function(a,b){if(a===b)return a;if(a&&!b)return a;if(b&&!a)return b;if(!b&&!a)return document;if(a.contains&&a.contains(b))return a;if(b.contains&&b.contains(a))return b;var c=this.depth(a),d=this.depth(b),e=c-d;for(e>=0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=a.parentNode||a.host,b=b.parentNode||b.host;return a},walk:function(a,b){for(var c=0;a&&b>c;c++)a=a.parentNode||a.host;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode||a.host;return b},deepContains:function(a,b){var c=this.LCA(a,b);return c===a},insideNode:function(a,b,c){var d=a.getBoundingClientRect();return d.left<=b&&b<=d.right&&d.top<=c&&c<=d.bottom},path:function(a){var c;if(b&&a.path&&a.path.length)c=a.path;else{c=[];for(var d=this.findTarget(a);d;)c.push(d),d=d.parentNode||d.host}return c}};a.targetFinding=g,a.findTarget=g.findTarget.bind(g),a.deepContains=g.deepContains.bind(g),a.insideNode=g.insideNode}(window.PolymerGestures),function(){function a(a){return"html /deep/ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+";}"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]},"manipulation"],e="",f="string"==typeof document.head.style.touchAction,g=!window.ShadowDOMPolyfill&&document.head.createShadowRoot;if(f){d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",g&&(e+=a(d)+c(d)+"\n")):(e+=d.selectors.map(b)+c(d.rule)+"\n",g&&(e+=d.selectors.map(a)+c(d.rule)+"\n"))});var h=document.createElement("style");h.textContent=e,document.head.appendChild(h)}}(),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],d=function(){return function(){}},e={preventTap:d,makeBaseEvent:function(a,b){var c=document.createEvent("Event");return c.initEvent(a,b.bubbles||!1,b.cancelable||!1),c.preventTap=e.preventTap(c),c},makeGestureEvent:function(a,b){b=b||Object.create(null);for(var c,d=this.makeBaseEvent(a,b),e=0,f=Object.keys(b);e<f.length;e++)c=f[e],"bubbles"!==c&&"cancelable"!==c&&(d[c]=b[c]);return d},makePointerEvent:function(a,d){d=d||Object.create(null);for(var e,f=this.makeBaseEvent(a,d),g=2;g<b.length;g++)e=b[g],f[e]=d[e]||c[g];f.buttons=d.buttons||0;var h=0;return h=d.pressure?d.pressure:f.buttons?.5:0,f.x=f.clientX,f.y=f.clientY,f.pointerId=d.pointerId||0,f.width=d.width||0,f.height=d.height||0,f.pressure=h,f.tiltX=d.tiltX||0,f.tiltY=d.tiltY||0,f.pointerType=d.pointerType||"",f.hwTimestamp=d.hwTimestamp||0,f.isPrimary=d.isPrimary||!1,f._source=d._source||"",f}};a.eventFactory=e}(window.PolymerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PolymerGestures),function(a){var b,c=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp","preventTap","tapPrevented","_source"],d=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0,function(){},!1],e="undefined"!=typeof SVGElementInstance,f=a.eventFactory,g={IS_IOS:!1,pointermap:new a.PointerMap,requiredGestures:new a.PointerMap,eventMap:Object.create(null),eventSources:Object.create(null),eventSourceList:[],gestures:[],dependencyMap:{down:{listeners:0,index:-1},up:{listeners:0,index:-1}},gestureQueue:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},registerGesture:function(a,b){var c=Object.create(null);c.listeners=0,c.index=this.gestures.length;for(var d,e=0;e<b.exposes.length;e++)d=b.exposes[e].toLowerCase(),this.dependencyMap[d]=c;this.gestures.push(b)},register:function(a,b){for(var c,d=this.eventSourceList.length,e=0;d>e&&(c=this.eventSourceList[e]);e++)c.register.call(c,a,b)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},down:function(a){this.requiredGestures.set(a.pointerId,b),this.fireEvent("down",a)},move:function(a){a.type="move",this.fillGestureQueue(a)},up:function(a){this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},cancel:function(a){a.tapPrevented=!0,this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},addGestureDependency:function(a,b){var c=a._pgEvents;if(c&&b)for(var d,e,f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],c[f]>0&&(d=this.dependencyMap[f],e=d?d.index:-1,b[e]=!0)},eventHandler:function(c){var d=c.type;if("touchstart"===d||"mousedown"===d||"pointerdown"===d||"MSPointerDown"===d)if(c._handledByPG||(b={}),this.IS_IOS){var e=c;if("touchstart"===d){var f=c.changedTouches[0];e={target:c.target,clientX:f.clientX,clientY:f.clientY,path:c.path}}for(var g,h=c.path||a.targetFinding.path(e),i=0;i<h.length;i++)g=h[i],this.addGestureDependency(g,b)}else this.addGestureDependency(c.currentTarget,b);if(!c._handledByPG){var j=this.eventMap&&this.eventMap[d];j&&j(c),c._handledByPG=!0}},listen:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.addEvent(a,c)},unlisten:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.removeEvent(a,c)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){var c=f.makePointerEvent(a,b);return c.preventDefault=b.preventDefault,c.tapPrevented=b.tapPrevented,c._target=c._target||b.target,c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,f=Object.create(null),g=0;g<c.length;g++)b=c[g],f[b]=a[b]||d[g],("target"===b||"relatedTarget"===b)&&e&&f[b]instanceof SVGElementInstance&&(f[b]=f[b].correspondingUseElement);return f.preventDefault=function(){a.preventDefault()},f},dispatchEvent:function(a){var b=a._target;if(b){b.dispatchEvent(a);var c=this.cloneEvent(a);c.target=b,this.fillGestureQueue(c)}},gestureTrigger:function(){for(var a,b,c=0;c<this.gestureQueue.length;c++)if(a=this.gestureQueue[c],b=a._requiredGestures)for(var d,e,f=0;f<this.gestures.length;f++)b[f]&&(d=this.gestures[f],e=d[a.type],e&&e.call(d,a));this.gestureQueue.length=0},fillGestureQueue:function(a){this.gestureQueue.length||requestAnimationFrame(this.boundGestureTrigger),a._requiredGestures=this.requiredGestures.get(a.pointerId),this.gestureQueue.push(a)}};g.boundHandler=g.eventHandler.bind(g),g.boundGestureTrigger=g.gestureTrigger.bind(g),a.dispatcher=g,a.activateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];if(d){var e=g.gestures[d.index];if(a._pgListeners||(g.register(a),a._pgListeners=0),e){var f,h=e.defaultActions&&e.defaultActions[c];switch(a.nodeType){case Node.ELEMENT_NODE:f=a;break;case Node.DOCUMENT_FRAGMENT_NODE:f=a.host;break;default:f=null}h&&f&&!f.hasAttribute("touch-action")&&f.setAttribute("touch-action",h)}a._pgEvents||(a._pgEvents={}),a._pgEvents[c]=(a._pgEvents[c]||0)+1,a._pgListeners++}return Boolean(d)},a.addEventListener=function(b,c,d,e){d&&(a.activateGesture(b,c),b.addEventListener(c,d,e))},a.deactivateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];return d&&(a._pgListeners>0&&a._pgListeners--,0===a._pgListeners&&g.unregister(a),a._pgEvents&&(a._pgEvents[c]>0?a._pgEvents[c]--:a._pgEvents[c]=0)),Boolean(d)},a.removeEventListener=function(b,c,d,e){d&&(a.deactivateGesture(b,c),b.removeEventListener(c,d,e))}}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e=[0,1,4,2],f=0,g=/Linux.*Firefox\//i,h=function(){if(g.test(navigator.userAgent))return!1;try{return 1===new MouseEvent("test",{buttons:1}).buttons}catch(a){return!1}}(),i={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup"],exposes:["down","up","move"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a);if(c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c._source="mouse",!h){var d=a.type,g=e[a.which]||0;"mousedown"===d?f|=g:"mouseup"===d&&(f&=~g),c.buttons=f}return c},mousedown:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=(c.has(this.POINTER_ID),this.prepareEvent(d));e.target=a.findTarget(d),c.set(this.POINTER_ID,e.target),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d){var e=this.prepareEvent(a);e.target=d,0===(h?e.buttons:e.which)?(h||(f=e.buttons=0),b.cancel(e),this.cleanupMouse(e.buttons)):b.move(e)}}},mouseup:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(this.POINTER_ID),b.up(e),this.cleanupMouse(e.buttons)}},cleanupMouse:function(a){0===a&&c["delete"](this.POINTER_ID)}};a.mouseEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=(a.targetFinding.allShadows.bind(a.targetFinding),b.pointermap),d=(Array.prototype.map.call.bind(Array.prototype.map),2500),e=25,f=200,g=20,h=!1,i={IS_IOS:!1,events:["touchstart","touchmove","touchend","touchcancel"],exposes:["down","up","move"],register:function(a,c){(this.IS_IOS?c:!c)&&b.listen(a,this.events)},unregister:function(a){this.IS_IOS||b.unlisten(a,this.events)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y"},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return b===c.EMITTER?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":"XY"},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===c.pointers()||1===c.pointers()&&c.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.firstTarget=a.target,this.scrolling=null,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,f)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},findTarget:function(b,d){if("touchstart"===this.currentTouchEvent.type){if(this.isPrimaryTouch(b)){var e={clientX:b.clientX,clientY:b.clientY,path:this.currentTouchEvent.path,target:this.currentTouchEvent.target};return a.findTarget(e)}return a.findTarget(b)}return c.get(d)},touchToPointer:function(a){var c=this.currentTouchEvent,d=b.cloneEvent(a),e=d.pointerId=a.identifier+2;d.target=this.findTarget(a,e),d.bubbles=!0,d.cancelable=!0,d.detail=this.clickCount,d.buttons=this.typeToButtons(c.type),d.width=a.webkitRadiusX||a.radiusX||0,d.height=a.webkitRadiusY||a.radiusY||0,d.pressure=a.webkitForce||a.force||.5,d.isPrimary=this.isPrimaryTouch(a),d.pointerType=this.POINTER_TYPE,d._source="touch";var f=this;return d.preventDefault=function(){f.scrolling=!1,f.firstXY=null,c.preventDefault()},d},processTouches:function(a,b){var d=a.changedTouches;this.currentTouchEvent=a;for(var e,f,g=0;g<d.length;g++)e=d[g],f=this.touchToPointer(e),"touchstart"===a.type&&c.set(f.pointerId,f.target),c.has(f.pointerId)&&b.call(this,f),("touchend"===a.type||a._cancel)&&this.cleanUpPointer(f)},shouldScroll:function(b){if(this.firstXY){var c,d=a.targetFinding.findTouchAction(b),e=this.touchActionToScrollType(d);if("none"===e)c=!1;else if("XY"===e)c=!0;else{var f=b.changedTouches[0],g=e,h="Y"===e?"X":"Y",i=Math.abs(f["client"+g]-this.firstXY[g]),j=Math.abs(f["client"+h]-this.firstXY[h]);c=i>=j}return c}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(c.pointers()>=b.length){var d=[];c.forEach(function(a,c){if(1!==c&&!this.findTouch(b,c-2)){var e=a;d.push(e)}},this),d.forEach(function(a){this.cancel(a),c["delete"](a.pointerId)},this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.down))},down:function(a){b.down(a)},touchmove:function(a){if(h)a.cancelable&&this.processTouches(a,this.move);else if(this.scrolling){if(this.firstXY){var b=a.changedTouches[0],c=b.clientX-this.firstXY.X,d=b.clientY-this.firstXY.Y,e=Math.sqrt(c*c+d*d);e>=g&&(this.touchcancel(a),this.scrolling=!0,this.firstXY=null)}}else null===this.scrolling&&this.shouldScroll(a)?this.scrolling=!0:(this.scrolling=!1,a.preventDefault(),this.processTouches(a,this.move))},move:function(a){b.move(a)},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.up)},up:function(c){c.relatedTarget=a.findTarget(c),b.up(c)},cancel:function(a){b.cancel(a)},touchcancel:function(a){a._cancel=!0,this.processTouches(a,this.cancel)},cleanUpPointer:function(a){c["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,e=b.changedTouches[0];if(this.isPrimaryTouch(e)){var f={x:e.clientX,y:e.clientY};c.push(f);var g=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,f);setTimeout(g,d)}}},j=Event.prototype.stopImmediatePropagation||Event.prototype.stopPropagation;document.addEventListener("click",function(b){var c=b.clientX,d=b.clientY,f=function(a){var b=Math.abs(c-a.x),f=Math.abs(d-a.y);return e>=b&&e>=f},g=a.mouseEvents.lastTouches.some(f),h=a.targetFinding.path(b);if(g){for(var k=0;k<h.length;k++)if(h[k]===i.firstTarget)return;b.preventDefault(),j.call(b)}},!0),a.touchEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerCancel"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return c=b.cloneEvent(a),d&&(c.pointerType=this.POINTER_TYPES[a.pointerType]),c._source="ms",c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(d.pointerId,e.target),b.down(e)},MSPointerMove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},MSPointerUp:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},MSPointerCancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.msEvents=e}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],prepareEvent:function(a){var c=b.cloneEvent(a);return c._source="pointer",c},register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},cleanup:function(a){c["delete"](a)},pointerdown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(e.pointerId,e.target),b.down(e)},pointermove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},pointerup:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},pointercancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.pointerEvents=d}(window.PolymerGestures),function(a){var b=a.dispatcher,c=window.navigator;window.PointerEvent?b.registerSource("pointer",a.pointerEvents):c.msPointerEnabled?b.registerSource("ms",a.msEvents):(b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents));var d=navigator.userAgent,e=d.match(/iPad|iPhone|iPod/)&&"ontouchstart"in window;b.IS_IOS=e,a.touchEvents.IS_IOS=e,b.register(document,!0)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","move","up"],exposes:["trackstart","track","trackx","tracky","trackend"],defaultActions:{track:"none",trackx:"pan-y",tracky:"pan-x"},WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,b,d){var e=d,f=this.calcPositionDelta(e.downEvent,b),g=this.calcPositionDelta(e.lastMoveEvent,b);if(g.x)e.xDirection=this.clampDir(g.x);else if("trackx"===a)return;if(g.y)e.yDirection=this.clampDir(g.y);else if("tracky"===a)return;var h={bubbles:!0,cancelable:!0,trackInfo:e.trackInfo,relatedTarget:b.relatedTarget,pointerType:b.pointerType,pointerId:b.pointerId,_source:"track"};"tracky"!==a&&(h.x=b.x,h.dx=f.x,h.ddx=g.x,h.clientX=b.clientX,h.pageX=b.pageX,h.screenX=b.screenX,h.xDirection=e.xDirection),"trackx"!==a&&(h.dy=f.y,h.ddy=g.y,h.y=b.y,h.clientY=b.clientY,h.pageY=b.pageY,h.screenY=b.screenY,h.yDirection=e.yDirection);var i=c.makeGestureEvent(a,h);e.downTarget.dispatchEvent(i)},down:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};d.set(a.pointerId,b)}},move:function(a){var b=d.get(a.pointerId);if(b){if(!b.tracking){var c=this.calcPositionDelta(b.downEvent,a),e=c.x*c.x+c.y*c.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,b.lastMoveEvent=b.downEvent,this.fireTrack("trackstart",a,b))}b.tracking&&(this.fireTrack("track",a,b),this.fireTrack("trackx",a,b),this.fireTrack("tracky",a,b)),b.lastMoveEvent=a}},up:function(a){var b=d.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),d["delete"](a.pointerId))}};b.registerGesture("track",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["down","move","up"],exposes:["hold","holdpulse","release"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},down:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},up:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},move:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,b){var d={bubbles:!0,cancelable:!0,pointerType:this.heldPointer.pointerType,pointerId:this.heldPointer.pointerId,x:this.heldPointer.clientX,y:this.heldPointer.clientY,_source:"hold"};b&&(d.holdTime=b);var e=c.makeGestureEvent(a,d);this.target.dispatchEvent(e)}};b.registerGesture("hold",d)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","up"],exposes:["tap"],down:function(a){a.isPrimary&&!a.tapPrevented&&d.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},shouldTap:function(a,b){var c=!0;return"mouse"===a.pointerType&&(c=1^a.buttons&&1&b.buttons),c&&!a.tapPrevented},up:function(b){var e=d.get(b.pointerId);if(e&&this.shouldTap(b,e)){var f=a.targetFinding.LCA(e.target,b.relatedTarget);if(f){var g=c.makeGestureEvent("tap",{bubbles:!0,cancelable:!0,x:b.clientX,y:b.clientY,detail:b.detail,pointerType:b.pointerType,pointerId:b.pointerId,altKey:b.altKey,ctrlKey:b.ctrlKey,metaKey:b.metaKey,shiftKey:b.shiftKey,_source:"tap"});f.dispatchEvent(g)}}d["delete"](b.pointerId)}};c.preventTap=function(a){return function(){a.tapPrevented=!0,d["delete"](a.pointerId)}},b.registerGesture("tap",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e=180/Math.PI,f={events:["down","up","move","cancel"],exposes:["pinchstart","pinch","pinchend","rotate"],defaultActions:{pinch:"none",rotate:"none"},reference:{},down:function(b){if(d.set(b.pointerId,b),2==d.pointers()){var c=this.calcChord(),e=this.calcAngle(c);this.reference={angle:e,diameter:c.diameter,target:a.targetFinding.LCA(c.a.target,c.b.target)},this.firePinch("pinchstart",c.diameter,c)}},up:function(a){var b=d.get(a.pointerId),c=d.pointers();if(b){if(2===c){var e=this.calcChord();this.firePinch("pinchend",e.diameter,e)}d["delete"](a.pointerId)}},move:function(a){d.has(a.pointerId)&&(d.set(a.pointerId,a),d.pointers()>1&&this.calcPinchRotate())},cancel:function(a){this.up(a)},firePinch:function(a,b,d){var e=b/this.reference.diameter,f=c.makeGestureEvent(a,{bubbles:!0,cancelable:!0,scale:e,centerX:d.center.x,centerY:d.center.y,_source:"pinch"});this.reference.target.dispatchEvent(f)},fireRotate:function(a,b){var d=Math.round((a-this.reference.angle)%360),e=c.makeGestureEvent("rotate",{bubbles:!0,cancelable:!0,angle:d,centerX:b.center.x,centerY:b.center.y,_source:"pinch"});this.reference.target.dispatchEvent(e)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.firePinch("pinch",b,a),c!=this.reference.angle&&this.fireRotate(c,a)},calcChord:function(){var a=[];d.forEach(function(b){a.push(b)});for(var b,c,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),c=Math.abs(i.clientY-k.clientY),e=b+c,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,c=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:c},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*e)%360}};b.registerGesture("pinch",f)}(window.PolymerGestures),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b,c;for(a=C();;)if(v("["))c=G(),a=Z.createMemberExpression("[",a,c);else if(v("."))c=F(),a=Z.createMemberExpression(".",a,c);else{if(!v("("))break;b=D(),a=Z.createCallExpression(a,b)}return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};
-var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=q[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),q[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){this.computed="["==c,this.dynamicDeps="function"==typeof a||a.dynamicDeps||this.computed&&!(b instanceof d),this.simplePath=!this.dynamicDeps&&(b instanceof e||b instanceof d)&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property=!this.computed||this.simplePath?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a,b){for(;a[t]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[t];return a}function o(a){switch(a){case"":return!1;case"false":case"null":case"true":return!0}return isNaN(Number(a))?!1:!0}function p(){}var q=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length&&(a=n(a,this.path[0])),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof f?this.object.fullPath.slice():[this.object.name];a.push(this.property instanceof e?this.property.name:this.property.value),this.fullPath_=Path.get(a)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.computed){var c=this.property;this.valueFn_=function(b,d,e){var f=a(b,d,e),g=c(b,d,e);return d&&d.addPath(f,[g]),f?f[g]:void 0}}else{var b=Path.get(this.property.name);this.valueFn_=function(c,d,e){var f=a(c,d,e);return d&&d.addPath(f,b),b.getValueFrom(f)}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=a,g=f[this.name];if(!g&&(g=c[this.name],!g))return void console.error("Cannot find function or filter: "+this.name);if(d?g=g.toModel:"function"==typeof g.toDOM&&(g=g.toDOM),"function"!=typeof g)return void console.error("Cannot find function or filter: "+this.name);for(var h=e||[],j=0;j<this.args.length;j++)h.push(i(this.args[j])(a,b,c));return g.apply(f,h)}};var r={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},s={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!r[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d,e){return r[a](b(c,d,e))}},createBinaryExpression:function(a,b,c){if(!s[a])throw Error("Disallowed operator: "+a);switch(b=i(b),c=i(c),a){case"||":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)||c(a,d,e)};case"&&":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)&&c(a,d,e)}}return function(d,e,f){return s[a](b(d,e,f),c(d,e,f))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),this.dynamicDeps=!0,function(d,e,f){return a(d,e,f)?b(d,e,f):c(d,e,f)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createCallExpression:function(a,b){if(!(a instanceof e))throw Error("Only identifier function invocations are allowed");var c=new g(a.name,b);return function(a,b,d){return c.transform(a,b,d,!1)}},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c,d){for(var e=[],f=0;f<a.length;f++)e.push(a[f](b,c,d));return e}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c,d){for(var e={},f=0;f<a.length;f++)e[a[f].key]=a[f].value(b,c,d);return e}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){if(h)return h=!1,g;i.dynamicDeps&&f.startReset();var c=i.getValue(a,i.dynamicDeps?f:void 0,b);return i.dynamicDeps&&f.finishReset(),c}function e(c){return i.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver,g=this.getValue(a,f,b),h=!0,i=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b,c),e=0;e<this.filters.length;e++)d=this.filters[e].transform(a,b,c,!1,[d]);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(a,void 0,c,!0,[b]);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var t="@"+Math.random().toString(36).slice(2);p.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);{if(o(a)||!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=n(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){return u(c,a,b,d)}}}};var u="__proto__"in{}?function(a,b,c,d){var e={};return e[c]=b,e[d]=void 0,e[t]=a,e.__proto__=a,e}:function(a,b,c,d){var e=Object.create(a);return Object.defineProperty(e,c,{value:b,configurable:!0,writable:!0}),Object.defineProperty(e,d,{value:void 0,configurable:!0,writable:!0}),Object.defineProperty(e,t,{value:a,configurable:!0,writable:!0}),e};a.PolymerExpressions=p,p.getExpression=c}(this),Polymer={version:"0.5.5"},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.modularize=c,a.using=e}(window),window.WebComponents||(window.WebComponents||(WebComponents={flush:function(){},flags:{log:{}}},Platform=WebComponents,CustomElements={useNative:!0,ready:!0,takeRecords:function(){},"instanceof":function(a,b){return a instanceof b}},HTMLImports={useNative:!0},addEventListener("HTMLImportsLoaded",function(){document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))}),ShadowDOMPolyfill=null,wrap=unwrap=function(a){return a}),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){function b(a,b){b=b||o,d(function(){f(a,b)},b)}function c(a){return"complete"===a.readyState||a.readyState===r}function d(a,b){if(c(b))a&&a();else{var e=function(){("complete"===b.readyState||b.readyState===r)&&(b.removeEventListener(s,e),d(a,b))};b.addEventListener(s,e)}}function e(a){a.target.__loaded=!0}function f(a,b){function c(){h==i&&a&&a()}function d(a){e(a),h++,c()}var f=b.querySelectorAll("link[rel=import]"),h=0,i=f.length;if(i)for(var j,k=0;i>k&&(j=f[k]);k++)g(j)?d.call(j,{target:j}):(j.addEventListener("load",d),j.addEventListener("error",d));else c()}function g(a){return l?a.__loaded||a["import"]&&"loading"!==a["import"].readyState:a.__importParsed}function h(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)i(b)&&j(b)}function i(a){return"link"===a.localName&&"import"===a.rel}function j(a){var b=a["import"];b?e({target:a}):(a.addEventListener("load",e),a.addEventListener("error",e))}var k="import",l=Boolean(k in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),n=function(a){return m?ShadowDOMPolyfill.wrapIfNeeded(a):a},o=n(document),p={get:function(){var a=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return n(a)},configurable:!0};Object.defineProperty(document,"_currentScript",p),Object.defineProperty(o,"_currentScript",p);var q=/Trident/.test(navigator.userAgent),r=q?"complete":"interactive",s="readystatechange";l&&(new MutationObserver(function(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)b.addedNodes&&h(b.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var a,b=document.querySelectorAll("link[rel=import]"),c=0,d=b.length;d>c&&(a=b[c]);c++)j(a)}()),b(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),o.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),a.IMPORT_LINK_TYPE=k,a.useNative=l,a.rootDocument=o,a.whenReady=b,a.isIE=q}(HTMLImports),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform)),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={},d=[];return Object.observe(c,a),Array.observe(d,a),c.id=1,c.id=2,delete c.id,d.push(1,2),d.length=0,Object.deliverChangeRecords(a),5!==b.length?!1:"add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type||"splice"!=b[3].type||"splice"!=b[4].type?!1:(Object.unobserve(c,a),Array.unobserve(d,a),!0)}function c(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if("undefined"!=typeof navigator&&navigator.getDeviceStorage)return!1;try{var a=new Function("","return true;");return a()}catch(b){return!1}}function d(a){return+a===a>>>0&&""!==a}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:R(a)&&R(b)?!0:a!==a&&b!==b}function h(a){if(void 0===a)return"eof";var b=a.charCodeAt(0);switch(b){case 91:case 93:case 46:case 34:case 39:case 48:return a;case 95:case 36:return"ident";case 32:case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"ws"}return b>=97&&122>=b||b>=65&&90>=b?"ident":b>=49&&57>=b?"number":"else"}function i(){}function j(a){function b(){if(!(m>=a.length)){var b=a[m+1];return"inSingleQuote"==n&&"'"==b||"inDoubleQuote"==n&&'"'==b?(m++,d=b,o.append(),!0):void 0}}for(var c,d,e,f,g,j,k,l=[],m=-1,n="beforePath",o={push:function(){void 0!==e&&(l.push(e),e=void 0)},append:function(){void 0===e?e=d:e+=d}};n;)if(m++,c=a[m],"\\"!=c||!b(n)){if(f=h(c),k=W[n],g=k[f]||k["else"]||"error","error"==g)return;if(n=g[0],j=o[g[1]]||i,d=void 0===g[2]?c:g[2],j(),"afterPath"===n)return l}}function k(a){return V.test(a)}function l(a,b){if(b!==X)throw Error("Use Path.get to retrieve path objects");for(var c=0;c<a.length;c++)this.push(String(a[c]));Q&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())}function m(a){if(a instanceof l)return a;if((null==a||0==a.length)&&(a=""),"string"!=typeof a){if(d(a.length))return new l(a,X);a=String(a)}var b=Y[a];if(b)return b;var c=j(a);if(!c)return Z;var b=new l(c,X);return Y[a]=b,b}function n(a){return d(a)?"["+a+"]":'["'+a.replace(/"/g,'\\"')+'"]'}function o(b){for(var c=0;_>c&&b.check_();)c++;return O&&(a.dirtyCheckCycleCount=c),c>0}function p(a){for(var b in a)return!1;return!0}function q(a){return p(a.added)&&p(a.removed)&&p(a.changed)}function r(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function s(){if(!ab.length)return!1;for(var a=0;a<ab.length;a++)ab[a]();return ab.length=0,!0}function t(){function a(a){b&&b.state_===fb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),cb.push(this)}}}function u(a,b,c){var d=cb.pop()||t();return d.open(a),d.observe(b,c),d}function v(){function a(b,f){b&&(b===d&&(e[f]=!0),h.indexOf(b)<0&&(h.push(b),Object.observe(b,c)),a(Object.getPrototypeOf(b),f))}function b(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.object!==d||e[c.name]||"setPrototype"===c.type)return!1}return!0}function c(c){if(!b(c)){for(var d,e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.iterateObjects_(a);for(var e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.check_()}}var d,e,f=0,g=[],h=[],i={objects:h,get rootObject(){return d},set rootObject(a){d=a,e={}},open:function(b){g.push(b),f++,b.iterateObjects_(a)},close:function(){if(f--,!(f>0)){for(var a=0;a<h.length;a++)Object.unobserve(h[a],c),x.unobservedCount++;g.length=0,h.length=0,d=void 0,e=void 0,db.push(this),$===this&&($=null)}}};return i}function w(a,b){return $&&$.rootObject===b||($=db.pop()||v(),$.rootObject=b),$.open(a,b),$}function x(){this.state_=eb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=ib++}function y(a){x._allObserversCount++,kb&&jb.push(a)}function z(){x._allObserversCount--}function A(a){x.call(this),this.value_=a,this.oldObject_=void 0}function B(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");A.call(this,a)}function C(a,b){x.call(this),this.object_=a,this.path_=m(b),this.directObserver_=void 0}function D(a){x.call(this),this.reportChangesOnOpen_=a,this.value_=[],this.directObserver_=void 0,this.observed_=[]}function E(a){return a}function F(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||E,this.setValueFn_=c||E,this.dontPassThroughSet_=d}function G(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];nb[g.type]?(g.name in c||(c[g.name]=g.oldValue),"update"!=g.type&&("add"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function H(a,b,c){return{index:a,removed:b,addedCount:c}}function I(){}function J(a,b,c,d,e,f){return sb.calcSplices(a,b,c,d,e,f)}function K(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function L(a,b,c,d){for(var e=H(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=K(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function M(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":L(c,g.index,g.removed.slice(),g.addedCount);break;case"add":case"update":case"delete":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;L(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function N(a,b){var c=[];return M(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(J(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var O=a.testingExposeCycleCount,P=b(),Q=c(),R=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},S="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},T="[$_a-zA-Z]",U="[$_a-zA-Z0-9]",V=new RegExp("^"+T+"+"+U+"*$"),W={beforePath:{ws:["beforePath"],ident:["inIdent","append"],"[":["beforeElement"],eof:["afterPath"]},inPath:{ws:["inPath"],".":["beforeIdent"],"[":["beforeElement"],eof:["afterPath"]},beforeIdent:{ws:["beforeIdent"],ident:["inIdent","append"]},inIdent:{ident:["inIdent","append"],0:["inIdent","append"],number:["inIdent","append"],ws:["inPath","push"],".":["beforeIdent","push"],"[":["beforeElement","push"],eof:["afterPath","push"]},beforeElement:{ws:["beforeElement"],0:["afterZero","append"],number:["inIndex","append"],"'":["inSingleQuote","append",""],'"':["inDoubleQuote","append",""]},afterZero:{ws:["afterElement","push"],"]":["inPath","push"]},inIndex:{0:["inIndex","append"],number:["inIndex","append"],ws:["afterElement"],"]":["inPath","push"]},inSingleQuote:{"'":["afterElement"],eof:["error"],"else":["inSingleQuote","append"]},inDoubleQuote:{'"':["afterElement"],eof:["error"],"else":["inDoubleQuote","append"]},afterElement:{ws:["afterElement"],"]":["inPath","push"]}},X={},Y={};l.get=m,l.prototype=S({__proto__:[],valid:!0,toString:function(){for(var a="",b=0;b<this.length;b++){var c=this[b];a+=k(c)?b?"."+c:c:n(c)}return a},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!f(a))return;b(a,this[c])}},compiledGetValueFromFn:function(){var a="",b="obj";a+="if (obj != null";for(var c,d=0;d<this.length-1;d++)c=this[d],b+=k(c)?"."+c:n(c),a+=" &&\n     "+b+" != null";a+=")\n";var c=this[d];return b+=k(c)?"."+c:n(c),a+="  return "+b+";\nelse\n  return undefined;",new Function("obj",a)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var Z=new l("",X);Z.valid=!1,Z.getValueFrom=Z.setValueFrom=function(){};var $,_=1e3,ab=[],bb=P?function(){return function(a){return Promise.resolve().then(a)}}():function(){return function(a){ab.push(a)}}(),cb=[],db=[],eb=0,fb=1,gb=2,hb=3,ib=1;x.prototype={open:function(a,b){if(this.state_!=eb)throw Error("Observer has already been opened.");return y(this),this.callback_=a,this.target_=b,this.connect_(),this.state_=fb,this.value_},close:function(){this.state_==fb&&(z(this),this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0,this.state_=gb)},deliver:function(){this.state_==fb&&o(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){x._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var jb,kb=!P;x._allObserversCount=0,kb&&(jb=[]);var lb=!1;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!lb&&kb){lb=!0;var b,c,d=0;do{d++,c=jb,jb=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==fb&&(f.check_()&&(b=!0),jb.push(f))}s()&&(b=!0)}while(_>d&&b);O&&(a.dirtyCheckCycleCount=d),lb=!1}},kb&&(a.Platform.clearObservers=function(){jb=[]}),A.prototype=S({__proto__:x.prototype,arrayObserve:!1,connect_:function(){P?this.directObserver_=u(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(P){if(!a)return!1;c={},b=G(this.value_,a,c)}else c=this.oldObject_,b=r(this.value_,this.oldObject_);return q(b)?!1:(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){P?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==fb&&(P?this.directObserver_.deliver(!1):o(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),B.prototype=S({__proto__:A.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(P){if(!a)return!1;b=N(this.value_,a)}else b=J(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),B.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},C.prototype=S({__proto__:x.prototype,get path(){return this.path_},connect_:function(){P&&(this.directObserver_=w(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c,this]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var mb={};D.prototype=S({__proto__:x.prototype,connect_:function(){if(P){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==mb){b=!0;break}b&&(this.directObserver_=w(this,a))}this.check_(void 0,!this.reportChangesOnOpen_)},disconnect_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===mb&&this.observed_[a+1].close();this.observed_.length=0,this.value_.length=0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},addPath:function(a,b){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add paths once started.");var b=m(b);if(this.observed_.push(a,b),this.reportChangesOnOpen_){var c=this.observed_.length/2-1;this.value_[c]=b.getValueFrom(a)}},addObserver:function(a){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add observers once started.");if(this.observed_.push(mb,a),this.reportChangesOnOpen_){var b=this.observed_.length/2-1;this.value_[b]=a.open(this.deliver,this)}},startReset:function(){if(this.state_!=fb)throw Error("Can only reset while open");this.state_=hb,this.disconnect_()},finishReset:function(){if(this.state_!=hb)throw Error("Can only finishReset after startReset");return this.state_=fb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==mb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e,f=this.observed_[d],h=this.observed_[d+1];if(f===mb){var i=h;e=this.state_===eb?i.open(this.deliver,this):i.discardChanges()}else e=h.getValueFrom(f);b?this.value_[d/2]=e:g(e,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=e)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),F.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var nb={add:!0,update:!0,"delete":!0},ob=0,pb=1,qb=2,rb=3;I.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ob):(e.push(pb),d=g),b--,c--):f==h?(e.push(rb),b--,d=h):(e.push(qb),c--,d=i)}else e.push(rb),b--;else e.push(qb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=H(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[H(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ob:j&&(l.push(j),j=void 0),m++,n++;break;case pb:j||(j=H(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case qb:j||(j=H(m,[],0)),j.addedCount++,m++;break;case rb:j||(j=H(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var sb=new I,tb=a;"undefined"==typeof exports||exports.nodeType||("undefined"!=typeof module&&module.exports&&(exports=module.exports),tb=exports),tb.Observer=x,tb.Observer.runEOM_=bb,tb.Observer.observerSentinel_=mb,tb.Observer.hasObjectObserve=P,tb.ArrayObserver=B,tb.ArrayObserver.calculateSplices=function(a,b){return sb.calculateSplices(a,b)},tb.ArraySplice=I,tb.ObjectObserver=A,tb.PathObserver=C,tb.CompoundObserver=D,tb.Path=l,tb.ObserverTransform=F}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b,c){var d=a.bindings_;return d||(d=a.bindings_={}),d[b]&&c[b].close(),d[b]=c}function c(a,b,c){return c}function d(a){return null==a?"":a}function e(a,b){a.data=d(b)}function f(a){return function(b){return e(a,b)}}function g(a,b,c,e){return c?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,d(e))}function h(a,b,c){return function(d){g(a,b,c,d)}}function i(a){switch(a.type){case"checkbox":return u;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function j(a,b,c,e){a[b]=(e||d)(c)}function k(a,b,c){return function(d){return j(a,b,d,c)}}function l(){}function m(a,b,c,d){function e(){var e="value"==b&&"number"==a.type;c.setValue(e?a.valueAsNumber:a[b]),c.discardChanges(),(d||l)(a),Platform.performMicrotaskCheckpoint()}var f=i(a);return a.addEventListener(f,e),{close:function(){a.removeEventListener(f,e),c.close()},observable_:c}}function n(a){return Boolean(a)}function o(b){if(b.form)return s(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return s(d,function(a){return a!=b&&!a.form})}function p(a){"INPUT"===a.tagName&&"radio"===a.type&&o(a).forEach(function(a){var b=a.bindings_.checked;b&&b.observable_.setValue(!1)})}function q(a,b){var c,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings_&&g.bindings_.value&&(c=g,e=c.bindings_.value,f=c.value),a.value=d(b),c&&c.value!=f&&(e.observable_.setValue(c.value),e.observable_.discardChanges(),Platform.performMicrotaskCheckpoint())}function r(a){return function(b){q(a,b)}}var s=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.bindFinished=function(){};var t=c;Object.defineProperty(Platform,"enableBindingsReflection",{get:function(){return t===b},set:function(a){return t=a?b:c,a},configurable:!0}),Text.prototype.bind=function(a,b,c){if("textContent"!==a)return Node.prototype.bind.call(this,a,b,c);if(c)return e(this,b);var d=b;return e(this,d.open(f(this))),t(this,a,d)},Element.prototype.bind=function(a,b,c){var d="?"==a[a.length-1];if(d&&(this.removeAttribute(a),a=a.slice(0,-1)),c)return g(this,a,d,b);var e=b;return g(this,a,d,e.open(h(this,a,d))),t(this,a,e)};var u;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),u=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,c,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,c,e);this.removeAttribute(a);var f="checked"==a?n:d,g="checked"==a?p:l;if(e)return j(this,a,c,f);var h=c,i=m(this,a,h,g);return j(this,a,h.open(k(this,a,f)),f),b(this,a,i)},HTMLTextAreaElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return j(this,"value",b);var e=b,f=m(this,"value",e);return j(this,"value",e.open(k(this,"value",d))),t(this,a,f)},HTMLOptionElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return q(this,b);var d=b,e=m(this,"value",d);
-return q(this,d.open(r(this))),t(this,a,e)},HTMLSelectElement.prototype.bind=function(a,c,d){if("selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a)return HTMLElement.prototype.bind.call(this,a,c,d);if(this.removeAttribute(a),d)return j(this,a,c);var e=c,f=m(this,a,e);return j(this,a,e.open(k(this,a))),b(this,a,f)}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(L[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(N);h(a)&&b(a),G(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument(""),b.stagingDocument_.isStagingDocument=!0;var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];K[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){P?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l;var o=d&&d(n,b,c);e.push(null==o?Path.get(n):null),e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(a.bindFinished(),b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==J&&g!==H&&g!==I){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d["if"]=x(a,J,c),d.bind=x(a,H,c),d.repeat=x(a,I,c),!d["if"]||d.bind||d.repeat||(d.bind=s("{{}}",H,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){var b=a.id_;return b||(b=a.id_=S++),b}function D(a,b){var c=C(a);if(b){var d=b.bindingMaps[c];return d||(d=b.bindingMaps[c]=B(a,b.prepareBinding)||[]),d}var d=a.bindingMap_;return d||(d=a.bindingMap_=B(a,void 0)||[]),d}function E(a){this.closed=!1,this.templateElement_=a,this.instances=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var F,G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?F=a.Map:(F=function(){this.keys=[],this.values=[]},F.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var H="bind",I="repeat",J="if",K={template:!0,repeat:!0,bind:!0,ref:!0,"if":!0},L={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},M="undefined"!=typeof HTMLTemplateElement;M&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var N="template, "+Object.keys(L).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),M||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var O,P="__proto__"in{};"function"==typeof MutationObserver&&(O=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&M,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=M,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=M)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var Q=a.HTMLUnknownElement||HTMLElement,R={get:function(){return this.content_},enumerable:!0,configurable:!0};M||(HTMLTemplateElement.prototype=Object.create(Q.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",R)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.bindings_?this.bindings_.ref=b:this.bindings_={ref:b},b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a["if"]||a.bind||a.repeat?(this.iterator_||(this.iterator_=new E(this)),this.iterator_.updateDependencies(a,this.model_),O&&O.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0))},createInstance:function(a,b,c){b?c=this.newDelegate_(b):c||(c=this.delegate_),this.refContent_||(this.refContent_=this.ref_.content);var d=this.refContent_;if(null===d.firstChild)return T;var e=D(d,c),f=m(this),g=f.createDocumentFragment();g.templateCreator_=this,g.protoContent_=d,g.bindings_=[],g.terminator_=null;for(var h=g.templateInstance_={firstNode:null,lastNode:null,model:a},i=0,j=!1,k=d.firstChild;k;k=k.nextSibling){null===k.nextSibling&&(j=!0);var l=A(k,g,f,e.children[i++],a,c,g.bindings_);l.templateInstance_=h,j&&(g.terminator_=l)}return h.firstNode=g.firstChild,h.lastNode=g.lastChild,g.templateCreator_=void 0,g.protoContent_=void 0,g},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue()))},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_&&this.bindings_.ref&&this.bindings_.ref.close(),this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}if(a)return{bindingMaps:{},raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}});var S=1;Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}});var T=document.createDocumentFragment();T.bindings_=[],T.terminator_=null,E.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_,e=!0;if(a["if"]){if(c.hasIf=!0,c.ifOneTime=a["if"].onlyOneTime,c.ifValue=v(J,a["if"],d,b),e=c.ifValue,c.ifOneTime&&!e)return void this.valueChanged();c.ifOneTime||(e=e.open(this.updateIfValue,this))}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(I,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(H,a.bind,d,b));var f=c.value;return c.oneTime||(f=f.open(this.updateIteratedValue,this)),e?void this.updateValue(f):void this.valueChanged()},getUpdatedValue:function(){var a=this.deps.value;return this.deps.oneTime||(a=a.discardChanges()),a},updateIfValue:function(a){return a?void this.updateValue(this.getUpdatedValue()):void this.valueChanged()},updateIteratedValue:function(a){if(this.deps.hasIf){var b=this.deps.ifValue;if(this.deps.ifOneTime||(b=b.discardChanges()),!b)return void this.valueChanged()}this.updateValue(a)},updateValue:function(a){this.deps.repeat||(a=[a]);var b=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(a);this.valueChanged(a,b)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getLastInstanceNode:function(a){if(-1==a)return this.templateElement_;var b=this.instances[a],c=b.terminator_;if(!c)return this.getLastInstanceNode(a-1);if(c.nodeType!==Node.ELEMENT_NODE||this.templateElement_===c)return c;var d=c.iterator_;return d?d.getLastTemplateNode():c},getLastTemplateNode:function(){return this.getLastInstanceNode(this.instances.length-1)},insertInstanceAt:function(a,b){var c=this.getLastInstanceNode(a-1),d=this.templateElement_.parentNode;this.instances.splice(a,0,b),d.insertBefore(b,c.nextSibling)},extractInstanceAt:function(a){for(var b=this.getLastInstanceNode(a-1),c=this.getLastInstanceNode(a),d=this.templateElement_.parentNode,e=this.instances.splice(a,1)[0];c!==b;){var f=b.nextSibling;f==c&&(c=b),e.appendChild(d.removeChild(f))}return e},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));for(var d=new F,e=0,f=0;f<a.length;f++){for(var g=a[f],h=g.removed,i=0;i<h.length;i++){var j=h[i],k=this.extractInstanceAt(g.index+e);k!==T&&d.set(j,k)}e-=g.addedCount}for(var f=0;f<a.length;f++)for(var g=a[f],l=g.index;l<g.index+g.addedCount;l++){var j=this.iteratedValue[l],k=d.get(j);k?d["delete"](j):(this.instanceModelFn_&&(j=this.instanceModelFn_(j)),k=void 0===j?T:b.createInstance(j,void 0,c)),this.insertInstanceAt(l,k)}d.forEach(function(a){this.closeInstanceBindings(a)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.instances[a];b!==T&&this.instancePositionChangedFn_(b.templateInstance_,a)},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.instances.length;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=a.bindings_,c=0;c<b.length;c++)b[c].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=0;a<this.instances.length;a++)this.closeInstanceBindings(this.instances[a]);this.instances.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");k.pathname="c%20d",j="http://a/c%20d"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))},get origin(){var a;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return a=this.host,a?this._scheme+"://"+a:""}};var r=a.URL;r&&(i.createObjectURL=function(){return r.createObjectURL.apply(r,arguments)},i.revokeObjectURL=function(a){r.revokeObjectURL(a)}),a.URL=i}}(this),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b,Platform.endOfMicrotask=b}(Polymer),function(a){function b(){g||(g=!0,c(function(){g=!1,d.data&&console.group("flush"),Platform.performMicrotaskCheckpoint(),d.data&&console.groupEnd()}))}var c=a.endOfMicrotask,d=window.WebComponents?WebComponents.flags.log:{},e=document.createElement("style");e.textContent="template {display: none !important;} /* injected by platform.js */";var f=document.querySelector("head");f.insertBefore(e,f.firstChild);var g;if(Observer.hasObjectObserve)b=function(){};else{var h=125;window.addEventListener("WebComponentsReady",function(){b();var c=function(){"hidden"===document.visibilityState?a.flushPoll&&clearInterval(a.flushPoll):a.flushPoll=setInterval(b,h)};"string"==typeof document.visibilityState&&document.addEventListener("visibilitychange",c),c()})}if(window.CustomElements&&!CustomElements.useNative){var i=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=i.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b,Platform.flush=b}(window.Polymer),function(a){function b(a){var b=new URL(a.ownerDocument.baseURI);return b.search="",b.hash="",b}function c(a,b,c,e){return a.replace(e,function(a,e,f,g){var h=f.replace(/["']/g,"");return h=d(b,h,c),e+"'"+h+"'"+g})}function d(a,b,c){if(b&&"/"===b[0])return b;if(b&&"#"===b[0])return b;var d=new URL(b,a);return c?d.href:e(d.href)}function e(a){var c=b(document.documentElement),d=new URL(a,c);return d.host===c.host&&d.port===c.port&&d.protocol===c.protocol?f(c,d):a}function f(a,b){for(var c=a.pathname,d=b.pathname,e=c.split("/"),f=d.split("/");e.length&&e[0]===f[0];)e.shift(),f.shift();for(var g=0,h=e.length-1;h>g;g++)f.unshift("..");var i=b.href.slice(-1)===m?m:b.hash;return f.join("/")+b.search+i}var g={resolveDom:function(a,c){c=c||b(a),this.resolveAttributes(a,c),this.resolveStyles(a,c);var d=a.querySelectorAll("template");if(d)for(var e,f=0,g=d.length;g>f&&(e=d[f]);f++)e.content&&this.resolveDom(e.content,c)},resolveTemplate:function(a){this.resolveDom(a.content,b(a))},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,c){c=c||b(a),a.textContent=this.resolveCssText(a.textContent,c)},resolveCssText:function(a,b,d){return a=c(a,b,d,h),c(a,b,d,i)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(k);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,e){e=e||b(a),j.forEach(function(b){var f,g=a.attributes[b],i=g&&g.value;i&&i.search(l)<0&&(f="style"===b?c(i,e,!1,h):d(e,i),g.value=f)})}},h=/(url\()([^)]*)(\))/g,i=/(@import[\s]+(?!url\())([^;]*)(;)/g,j=["href","src","action","style","url"],k="["+j.join("],[")+"]",l="{{.*}}",m="#";a.urlResolver=g}(Polymer),function(a){function b(a){this.cache=Object.create(null),this.map=Object.create(null),this.requests=0,this.regex=a}var c=Polymer.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b),e=c.bind(null,this.map);this.fetch(d,e)},fetch:function(a,b){var c=a.length;if(!c)return b();for(var d,e,f,g=function(){0===--c&&b()},h=0;c>h;h++)d=a[h],f=d.url,e=this.cache[f],e||(e=this.xhr(f),e.match=d,this.cache[f]=e),e.wait(g)},handleXhr:function(a){var b=a.match,c=b.url,d=a.response||a.responseText||"";this.map[c]=d,this.fetch(this.extractUrls(d,c),a.resolve)},xhr:function(a){this.requests++;var b=new XMLHttpRequest;return b.open("GET",a,!0),b.send(),b.onerror=b.onload=this.handleXhr.bind(this,b),b.pending=[],b.resolve=function(){for(var a=b.pending,c=0;c<a.length;c++)a[c]();b.pending=null},b.wait=function(a){b.pending?b.pending.push(a):c(a)},b}},a.Loader=b}(Polymer),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b,c){var d=a.textContent,e=function(b){a.textContent=b,c(a)};this.resolve(d,b,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f,!0),g=this.flatten(g,b,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b,c){function d(){f++,f===g&&c&&c()}for(var e,f=0,g=a.length,h=0;g>h&&(e=a[h]);h++)this.resolveNode(e,b,d)}};var e=new b;a.styleResolver=e}(Polymer),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}function c(a){for(var b=a||{},c=1;c<arguments.length;c++){var e=arguments[c];try{for(var f in e)d(f,e,b)}catch(g){}}return b}function d(a,b,c){var d=e(b,a);Object.defineProperty(c,a,d)}function e(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||e(Object.getPrototypeOf(a),b)}}a.extend=b,a.mixin=c,Platform.mixin=c}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(a){function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c={};HTMLElement.register=function(a,b){c[a]=b},HTMLElement.getPrototypeForTag=function(a){var b=a?c[a]:HTMLElement.prototype;return b||Object.getPrototypeOf(document.createElement(a))};var d=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,d.apply(this,arguments)};var e=DOMTokenList.prototype.add,f=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)e.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)f.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype["switch"]=function(a,b){a&&this.remove(a),b&&this.add(b)};var g=function(){return Array.prototype.slice.call(this)},h=window.NamedNodeMap||window.MozNamedAttrMap||{};NodeList.prototype.array=g,h.prototype.array=g,HTMLCollection.prototype.array=g,a.createDOM=b}(Polymer),function(a){function b(a){var e=b.caller,g=e.nom,h=e._super;h||(g||(g=e.nom=c.call(this,e)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(e,g,f(this)));var i=h[g];return i?(i._super||d(i,g,h),i.apply(this,a||[])):void 0}function c(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function d(a,b,c){var d=e(c,b,a);return d[b]&&(d[b].nom=b),a._super=d}function e(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}return Object}function f(a){return a.__proto__}a["super"]=b}(Polymer),function(a){function b(a){return a}function c(a,b){var c=typeof b;return b instanceof Date&&(c="date"),d[c](a,b)}var d={string:b,undefined:b,date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=c}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Polymer.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:~e},cancelAsync:function(a){0>a?cancelAnimationFrame(~a):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=null===b||void 0===b?{}:b,g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)},injectBoundHTML:function(a,b){var c=document.createElement("template");c.innerHTML=a;var d=this.instanceTemplate(c);return b&&(b.textContent="",b.appendChild(d)),d}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;
-b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);for(var c in a){var d=a[c];PolymerGestures.addEventListener(this,c,this.element.getEventHandler(this,this,d))}},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Polymer.flush()}}};a.api.instance.events=d,a.addEventListener=function(a,b,c,d){PolymerGestures.addEventListener(wrap(a),b,c,d)},a.removeEventListener=function(a,b,c,d){PolymerGestures.removeEventListener(wrap(a),b,c,d)}}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b){return a===b?0!==a||1/a===1/b:f(a)&&f(b)?!0:a!==a&&b!==b}function c(a,b){return void 0===b&&null===a?b:null===b||void 0===b?a:b}var d=window.WebComponents?WebComponents.flags.log:{},e={object:void 0,type:"update",name:void 0,oldValue:void 0},f=Number.isNaN||function(a){return"number"==typeof a&&isNaN(a)},g={createPropertyObserver:function(){var a=this._observeNames;if(a&&a.length){var b=this._propertyObserver=new CompoundObserver(!0);this.registerObserver(b);for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.addPath(this,c),this.observeArrayValue(c,this[c],null)}},openPropertyObserver:function(){this._propertyObserver&&this._propertyObserver.open(this.notifyPropertyChanges,this)},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)if(d=c[2*g+1],e=this.observe[d]){var h=b[g],i=a[g];this.observeArrayValue(d,i,h),f[e]||(void 0!==h&&null!==h||void 0!==i&&null!==i)&&(f[e]=!0,this.invokeMethod(e,[h,i,arguments]))}},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},deliverChanges:function(){this._propertyObserver&&this._propertyObserver.deliver()},observeArrayValue:function(a,b,c){var e=this.observe[a];if(e&&(Array.isArray(c)&&(d.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.closeNamedObserver(a+"__array")),Array.isArray(b))){d.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a){this.invokeMethod(e,[a])},this),this.registerNamedObserver(a+"__array",f)}},emitPropertyChangeRecord:function(a,c,d){if(!b(c,d)&&(this._propertyChanged(a,c,d),Observer.hasObjectObserve)){var f=this._objectNotifier;f||(f=this._objectNotifier=Object.getNotifier(this)),e.object=this,e.name=a,e.oldValue=d,f.notify(e)}},_propertyChanged:function(a){this.reflect[a]&&this.reflectPropertyToAttribute(a)},bindProperty:function(a,b,d){if(d)return void(this[a]=b);var e=this.element.prototype.computed;if(e&&e[a]){var f=a+"ComputedBoundObservable_";return void(this[f]=b)}return this.bindToAccessor(a,b,c)},bindToAccessor:function(a,c,d){function e(b,c){j[f]=b;var d=j[h];d&&"function"==typeof d.setValue&&d.setValue(b),j.emitPropertyChangeRecord(a,b,c)}var f=a+"_",g=a+"Observable_",h=a+"ComputedBoundObservable_";this[g]=c;var i=this[f],j=this,k=c.open(e);if(d&&!b(i,k)){var l=d(i,k);b(k,l)||(k=l,c.setValue&&c.setValue(k))}e(k,i);var m={close:function(){c.close(),j[g]=void 0,j[h]=void 0}};return this.registerObserver(m),m},createComputedProperties:function(){if(this._computedNames)for(var a=0;a<this._computedNames.length;a++){var b=this._computedNames[a],c=this.computed[b];try{var d=PolymerExpressions.getExpression(c),e=d.getBinding(this,this.element.syntax);this.bindToAccessor(b,e)}catch(f){console.error("Failed to create computed property",f)}}},registerObserver:function(a){return this._observers?void this._observers.push(a):void(this._observers=[a])},closeObservers:function(){if(this._observers){for(var a=this._observers,b=0;b<a.length;b++){var c=a[b];c&&"function"==typeof c.close&&c.close()}this._observers=[]}},registerNamedObserver:function(a,b){var c=this._namedObservers||(this._namedObservers={});c[a]=b},closeNamedObserver:function(a){var b=this._namedObservers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},closeNamedObservers:function(){if(this._namedObservers){for(var a in this._namedObservers)this.closeNamedObserver(a);this._namedObservers={}}}};a.api.instance.properties=g}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c={instanceTemplate:function(a){HTMLTemplateElement.decorate(a);for(var b=this.syntax||!a.bindingDelegate&&this.element.syntax,c=a.createInstance(this,b),d=c.bindings_,e=0;e<d.length;e++)this.registerObserver(d[e]);return c},bind:function(a,b,c){var d=this.propertyForAttribute(a);if(d){var e=this.bindProperty(d,b,c);return Platform.enableBindingsReflection&&e&&(e.path=b.path_,this._recordBinding(d,e)),this.reflect[d]&&this.reflectPropertyToAttribute(d),e}return this.mixinSuper(arguments)},_recordBinding:function(a,b){this.bindings_=this.bindings_||{},this.bindings_[a]=b},bindFinished:function(){this.makeElementReady()},asyncUnbindAll:function(){this._unbound||(b.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){this._unbound||(this.closeObservers(),this.closeNamedObservers(),this._unbound=!0)},cancelUnbindAll:function(){return this._unbound?void(b.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(b.unbind&&console.log("[%s] cancelUnbindAll",this.localName),void(this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop())))}},d=/\{\{([^{}]*)}}/;a.bindPattern=d,a.api.instance.mdv=c}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d={PolymerBase:!0,job:function(a,b,c){if("string"!=typeof a)return Polymer.job.call(this,a,b,c);var d="___"+a;this[d]=Polymer.job.call(this,this[d],b,c)},"super":Polymer["super"],created:function(){},ready:function(){},createdCallback:function(){this.templateInstance&&this.templateInstance.model&&console.warn("Attributes on "+this.localName+" were data bound prior to Polymer upgrading the element. This may result in incorrect binding types."),this.created(),this.prepareElement(),this.ownerDocument.isStagingDocument||this.makeElementReady()},prepareElement:function(){return this._elementPrepared?void console.warn("Element already prepared",this.localName):(this._elementPrepared=!0,this.shadowRoots={},this.createPropertyObserver(),this.openPropertyObserver(),this.copyInstanceAttributes(),this.takeAttributes(),void this.addHostListeners())},makeElementReady:function(){this._readied||(this._readied=!0,this.createComputedProperties(),this.parseDeclarations(this.__proto__),this.removeAttribute("unresolved"),this.ready())},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},attachedCallback:function(){this.cancelUnbindAll(),this.attached&&this.attached(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot(),c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a,b){if(a){this.eventController=this;var c=this.instanceTemplate(a);return b?this.insertBefore(c,b):this.appendChild(c),this.shadowRootReady(this),c}},shadowRootReady:function(a){this.marshalNodeReferences(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=d,d.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=d}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=WebComponents.ShadowCSS.makeScopeSelector(c,d);return WebComponents.ShadowCSS.shimCssText(a,e)}var d=(window.WebComponents?WebComponents.flags.log:{},window.ShadowDOMPolyfill),e="element",f="controller",g={STYLE_SCOPE_ATTRIBUTE:e,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(f),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b,c){var c=c||this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,e){if(b=b||this.findStyleScope(),e=e||"",b){d&&(a=c(a,b.host));var g=this.element.cssTextToScopeStyle(a,f);Polymer.applyStyleToScope(g,b),this.styleCacheForScope(b)[this.localName+e]=!0}},findStyleScope:function(a){for(var b=a||this;b.parentNode;)b=b.parentNode;return b},scopeHasNamedStyle:function(a,b){var c=this.styleCacheForScope(a);return c[b]},styleCacheForScope:function(a){if(d){var b=a.host?a.host.localName:a.localName;return h[b]||(h[b]={})}return a._scopeStyles=a._scopeStyles||{}}},h={};a.api.instance.styles=g}(Polymer),function(a){function b(a,b){if("string"!=typeof a){var c=b||document._currentScript;if(b=a,a=c&&c.parentNode&&c.parentNode.getAttribute?c.parentNode.getAttribute("name"):"",!a)throw"Element name could not be inferred."}if(f(a))throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){i[a]=b}function d(a){i[a]&&(i[a].registerWhenReady(),delete i[a])}function e(a,b){return j[a]=b||{}}function f(a){return j[a]}function g(a,b){if("string"!=typeof b)return!1;var c=HTMLElement.getPrototypeForTag(b),d=c&&c.constructor;return d?CustomElements["instanceof"]?CustomElements["instanceof"](a,d):a instanceof d:!1}var h=a.extend,i=(a.api,{}),j={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,a.instanceOfType=g,window.Polymer=b,h(Polymer,a),WebComponents.consumeDeclarations&&WebComponents.consumeDeclarations(function(a){if(a)for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.apply(null,c)})}(Polymer),function(a){var b={resolveElementPaths:function(a){Polymer.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),i&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e);var f=b.firstElementChild;if(b===document.head){var g="style["+h+"]",j=document.head.querySelectorAll(g);j.length&&(f=j[j.length-1].nextElementSibling)}b.insertBefore(c,f)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return q?q.call(a,b):void 0}var g=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i=window.ShadowDOMPolyfill,j="style",k="@import",l="link[rel=stylesheet]",m="global",n="polymer-scope",o={loadStyles:function(a){var b=this.fetchTemplate(),c=b&&this.templateContent();if(c){this.convertSheetsToStyles(c);var d=this.findLoadableStyles(c);if(d.length){var e=b.ownerDocument.baseURI;return Polymer.styleResolver.loadStyles(d,e,a)}}a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(l),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(j),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(k)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(l),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(j+"["+n+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(n)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},installGlobalStyles:function(){var a=this.styleForScope(m);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+n+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},p=HTMLElement.prototype,q=p.matches||p.matchesSelector||p.webkitMatchesSelector||p.mozMatchesSelector;a.api.declaration.styles=o,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.events),c=b.EVENT_PREFIX,d={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){d[a.toLowerCase()]=a});var e={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(f)},findController:function(a){for(;a.parentNode;){if(a.eventController)return a.eventController;a=a.parentNode}return a.host},getEventHandler:function(a,b,c){var d=this;return function(e){a&&a.PolymerBase||(a=d.findController(b));var f=[e,e.detail,e.currentTarget];a.dispatchMethod(a,c,f)}},prepareEventBinding:function(a,b){if(this.hasEventPrefix(b)){var c=this.removeEventPrefix(b);c=d[c]||c;var e=this;return function(b,d,f){function g(){return"{{ "+a+" }}"}var h=e.getEventHandler(void 0,d,a);return PolymerGestures.addEventListener(d,c,h),f?void 0:{open:g,discardChanges:g,close:function(){PolymerGestures.removeEventListener(d,c,h)}}}}}},f=c.length;a.api.declaration.events=e}(Polymer),function(a){var b=["attribute"],c={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(b=d.slice(0,-7),this.canObserveProperty(b)&&(c||(c=a.observe={}),c[b]=c[b]||d))},canObserveProperty:function(a){return b.indexOf(a)<0},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}if(a.computed){var b=a._computedNames=[];for(var c in a.computed)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),this.filterInvalidAccessorNames(c),a._publishLC=this.lowerCaseMap(c));var d=a.computed;d&&this.filterInvalidAccessorNames(d)},filterInvalidAccessorNames:function(a){for(var b in a)this.propertyNameBlacklist[b]&&(console.warn('Cannot define property "'+b+'" for element "'+this.name+'" because it has the same name as an HTMLElement property, and not all browsers support overriding that. Consider giving it a different name.'),delete a[b])},requireProperties:function(a,b){b.reflect=b.reflect||{};for(var c in a){var d=a[c];d&&void 0!==d.reflect&&(b.reflect[c]=Boolean(d.reflect),d=d.value),void 0!==d&&(b[c]=d)}},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b},createPropertyAccessor:function(a,b){var c=this.prototype,d=a+"_",e=a+"Observable_";c[d]=c[a],Object.defineProperty(c,a,{get:function(){var a=this[e];return a&&a.deliver(),this[d]},set:function(c){if(b)return this[d];var f=this[e];if(f)return void f.setValue(c);var g=this[d];return this[d]=c,this.emitPropertyChangeRecord(a,c,g),c},configurable:!0})},createPropertyAccessors:function(a){var b=a._computedNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.createPropertyAccessor(c,!0);var b=a._publishNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)a.computed&&a.computed[c]||this.createPropertyAccessor(c)},propertyNameBlacklist:{children:1,"class":1,id:1,hidden:1,style:1,title:1}};a.api.declaration.properties=c}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a){var d=this.getAttribute(b);if(d)for(var e,f=a.publish||(a.publish={}),g=d.split(c),h=0,i=g.length;i>h;h++)e=g[h].trim(),e&&void 0===f[e]&&(f[e]=void 0)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){var b=a.api.declaration.events,c=new PolymerExpressions,d=c.prepareBinding;c.prepareBinding=function(a,e,f){return b.prepareEventBinding(a,e,f)||d.call(c,a,e,f)};var e={syntax:c,fetchTemplate:function(){return this.querySelector("template")},templateContent:function(){var a=this.fetchTemplate();return a&&a.content},installBindingDelegate:function(a){a&&(a.bindingDelegate=this.syntax)}};a.api.declaration.mdv=e}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f=window.ShadowDOMPolyfill,g={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("reflect",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.createPropertyAccessors(this.prototype),this.installBindingDelegate(this.fetchTemplate()),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),f&&WebComponents.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),h[a]=b}return b},findBasePrototype:function(a){return h[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c["extends"]=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element["extends"]):void 0}},h={};g.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=g}(Polymer),function(a){function b(a){return document.contains(a)?j:i}function c(){return i.length?i[0]:j[0]}function d(a){f.waitToReady=!0,Polymer.endOfMicrotask(function(){HTMLImports.whenReady(function(){f.addReadyCallback(a),f.waitToReady=!1,f.check()})})}function e(a){if(void 0===a)return void f.ready();var b=setTimeout(function(){f.ready()},a);Polymer.whenReady(function(){clearTimeout(b)})}var f={wait:function(a){a.__queue||(a.__queue={},g.push(a))},enqueue:function(a,c,d){var e=a.__queue&&!a.__queue.check;return e&&(b(a).push(a),a.__queue.check=c,a.__queue.go=d),0!==this.indexOf(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?i.length:1e9),c},go:function(a){var b=this.remove(a);b&&(a.__queue.flushable=!0,this.addToFlushQueue(b),this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__queue.check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){for(var a,b=0,c=g.length;c>b&&(a=g[b]);b++)if(a.__queue&&!a.__queue.flushable)return;return!0},addToFlushQueue:function(a){h.push(a)},flush:function(){if(!this.flushing){this.flushing=!0;for(var a;h.length;)a=h.shift(),a.__queue.go.call(a),a.__queue=null;this.flushing=!1}},ready:function(){var a=CustomElements.ready;CustomElements.ready=!1,this.flush(),CustomElements.useNative||CustomElements.upgradeDocumentTree(document),CustomElements.ready=a,Polymer.flush(),requestAnimationFrame(this.flushReadyCallbacks)},addReadyCallback:function(a){a&&k.push(a)},flushReadyCallbacks:function(){if(k)for(var a;k.length;)(a=k.shift())()},waitingFor:function(){for(var a,b=[],c=0,d=g.length;d>c&&(a=g[c]);c++)a.__queue&&!a.__queue.flushable&&b.push(a);return b},waitToReady:!0},g=[],h=[],i=[],j=[],k=[];a.elements=g,a.waitingFor=f.waitingFor.bind(f),a.forceReady=e,a.queue=f,a.whenReady=a.whenPolymerReady=d}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this["extends"]=this.getAttribute("extends"),f.wait(this),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this["extends"])&&!b(this["extends"])&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this["extends"]),this.register(this.name,this["extends"]),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){this.hasAttribute("noscript")&&!this.noscript&&(this.noscript=!0,Polymer(a))},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.enqueue(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenReady;a["import"]=c,a.importElements=b}(Polymer),function(){var a=document.createElement("polymer-element");a.setAttribute("name","auto-binding"),a.setAttribute("extends","template"),a.init(),Polymer("auto-binding",{createdCallback:function(){this.syntax=this.bindingDelegate=this.makeSyntax(),Polymer.whenPolymerReady(function(){this.model=this,this.setAttribute("bind",""),this.async(function(){this.marshalNodeReferences(this.parentNode),this.fire("template-bound")})}.bind(this))},makeSyntax:function(){var a=Object.create(Polymer.api.declaration.events),b=this;a.findController=function(){return b.model};var c=new PolymerExpressions,d=c.prepareBinding;return c.prepareBinding=function(b,e,f){return a.prepareEventBinding(b,e,f)||d.call(c,b,e,f)},c}})}();'use strict';var global=this;this.tr=(function(){if(global.tr){console.warn('Base was multiply initialized. First init wins.');return global.tr;}
-function exportPath(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
-return cur;};function isExported(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
-return true;}
-function isDefined(name){var parts=name.split('.');var curObject=global;for(var i=0;i<parts.length;i++){var partName=parts[i];var nextObject=curObject[partName];if(nextObject===undefined)
-return false;curObject=nextObject;}
-return true;}
-var panicElement=undefined;var rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)
-return;var panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
-function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)
-throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
-if(panicDetails instanceof Error)
-panicDetails=panicDetails.stack;showPanicElementIfNeeded();var panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
-function hasPanic(){return rawPanicMessages.length!==0;}
-function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
-function exportTo(namespace,fn){var obj=exportPath(namespace);var exports=fn();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor)
-Object.defineProperty(obj,propertyName,propertyDescriptor);}};function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
-tr.isHeadless=tr.isVinn||tr.isNode;}
-return{initialize:initialize,exportTo:exportTo,isExported:isExported,isDefined:isDefined,showPanic:showPanic,hasPanic:hasPanic,getPanicText:getPanicText};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function asArray(arrayish){var values=[];for(var i=0;i<arrayish.length;i++)
-values.push(arrayish[i]);return values;}
-function compareArrays(x,y,elementCmp){var minLength=Math.min(x.length,y.length);for(var i=0;i<minLength;i++){var tmp=elementCmp(x[i],y[i]);if(tmp)
-return tmp;}
-if(x.length==y.length)
-return 0;if(x[i]===undefined)
-return-1;return 1;}
-function comparePossiblyUndefinedValues(x,y,cmp,opt_this){if(x!==undefined&&y!==undefined)
-return cmp.call(opt_this,x,y);if(x!==undefined)
-return-1;if(y!==undefined)
-return 1;return 0;}
-function compareNumericWithNaNs(x,y){if(!isNaN(x)&&!isNaN(y))
-return x-y;if(isNaN(x))
-return 1;if(isNaN(y))
-return-1;return 0;}
-function concatenateArrays(){var values=[];for(var i=0;i<arguments.length;i++){if(!(arguments[i]instanceof Array))
-throw new Error('Arguments '+i+'is not an array');values.push.apply(values,arguments[i]);}
-return values;}
-function concatenateObjects(){var result={};for(var i=0;i<arguments.length;i++){var object=arguments[i];for(var j in object){result[j]=object[j];}}
-return result;}
-function cloneDictionary(dict){var clone={};for(var k in dict){clone[k]=dict[k];}
-return clone;}
-function dictionaryKeys(dict){var keys=[];for(var key in dict)
-keys.push(key);return keys;}
-function dictionaryValues(dict){var values=[];for(var key in dict)
-values.push(dict[key]);return values;}
-function dictionaryLength(dict){var n=0;for(var key in dict)
-n++;return n;}
-function dictionaryContainsValue(dict,value){for(var key in dict)
-if(dict[key]===value)
-return true;return false;}
-function group(ary,fn){return ary.reduce(function(accumulator,curr){var key=fn(curr);if(key in accumulator)
-accumulator[key].push(curr);else
-accumulator[key]=[curr];return accumulator;},{});}
-function iterItems(dict,fn,opt_this){opt_this=opt_this||this;var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];fn.call(opt_this,key,dict[key]);}}
-function mapItems(dict,fn,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
-return result;}
-function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];var value=dict[key];if(predicate.call(opt_this,key,value))
-result[key]=value;}
-return result;}
-function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
-return;}
-for(var key in object){var value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
-function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;var result={};for(var i=0;i<array.length;i++){var item=array[i];if(item===undefined)
-continue;var dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)
-continue;for(var key in dict){var valueList=result[key];if(valueList===undefined)
-result[key]=valueList=new Array(array.length);valueList[i]=dict[key];}}
-return result;}
-function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;var result={};var length=array.length;for(var i=0;i<length;i++){var value=array[i];var key=valueToKeyFn.call(opt_this,value);result[key]=value;}
-return result;}
-function identity(d){return d;}
-function findFirstIndexInArray(ary,opt_func,opt_this){var func=opt_func||identity;for(var i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))
-return i;}
-return-1;}
-function findFirstInArray(ary,opt_func,opt_this){var i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)
-return undefined;return ary[i];}
-function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key]))
-return key;}
-return undefined;}
-function mapValues(map){var values=[];for(var value of map.values())
-values.push(value);return values;}
-function iterMapItems(map,fn,opt_this){opt_this=opt_this||this;for(var key of map.keys())
-fn.call(opt_this,key,map.get(key));}
-return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,cloneDictionary:cloneDictionary,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching,mapValues:mapValues,iterMapItems:iterMapItems};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
-EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k=='decorate')
-continue;var v=EventTarget.prototype[k];if(typeof v!=='function')
-continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_)
-this.listeners_=Object.create(null);if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{var handlers=this.listeners_[type];if(handlers.indexOf(handler)<0)
-handlers.push(handler);}},removeEventListener:function(type,handler){if(!this.listeners_)
-return;if(type in this.listeners_){var handlers=this.listeners_[type];var index=handlers.indexOf(handler);if(index>=0){if(handlers.length==1)
-delete this.listeners_[type];else
-handlers.splice(index,1);}}},dispatchEvent:function(event){if(!this.listeners_)
-return true;var self=this;event.__defineGetter__('target',function(){return self;});var realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};var type=event.type;var prevented=0;if(type in this.listeners_){var handlers=this.listeners_[type].concat();for(var i=0,handler;handler=handlers[i];i++){if(handler.handleEvent)
-prevented|=handler.handleEvent.call(handler,event)===false;else
-prevented|=handler.call(this,event)===false;}}
-return!prevented&&event.rawReturnValue;},hasEventListener:function(type){return this.listeners_[type]!==undefined;}};var EventTargetHelper={decorate:function(target){for(var k in EventTargetHelper){if(k=='decorate')
-continue;var v=EventTargetHelper[k];if(typeof v!=='function')
-continue;target[k]=v;}
-target.listenerCounts_={};},addEventListener:function(type,listener,useCapture){this.__proto__.addEventListener.call(this,type,listener,useCapture);if(this.listenerCounts_[type]===undefined)
-this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
-function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
-return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
-throw new Error('Mode is required');if(!ALL_MODES[mode])
-throw new Error('Not a mode.');this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.mandatoryBaseClass_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
-ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_)
-throw new Error('Frozen');this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_)
-throw new Error('Frozen');this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_)
-throw new Error('Frozen');this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
-return this.defaultTypeInfo_;},validateConstructor:function(constructor){if(!this.mandatoryBaseClass)
-return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
-curProto=curProto.__proto__;}
-if(!ok)
-throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
-throw new Error('Handler already registered for '+constructor);extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata)
-metadata[k]=extensionRegistryOptions.defaultMetadata[k];if(opt_metadata){for(var k in opt_metadata)
-metadata[k]=opt_metadata[k];}
-var typeInfo=new RegisteredTypeInfo(constructor,metadata);var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(var i=0;i<registry.registeredTypeInfos_.length;i++)
-if(registry.registeredTypeInfos_[i].constructor==constructor)
-return i;return undefined;};registry.unregister=function(constructor){var foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined)
-throw new Error(constructor+' not registered');registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined)
-return this.registeredTypeInfos_[foundIndex];return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo))
-return typeInfo;}
-return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string')
-throw new Error('Name is not a string.');var typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)
-return typeInfo;return undefined;};}
-return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)
-return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
-return{getCategoryParts:getCategoryParts};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_={};registry.typeNameToTypeInfoMap_={};registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName)
-typeInfo.typeNames.push(metadata.typeName);if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
-if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
-if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0)
-throw new Error('typeName or typeNames must be provided');typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_[typeName])
-throw new Error('typeName '+typeName+' already registered');});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_[categoryPart]){throw new Error('categoryPart '+categoryPart+' already registered');}});var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_[typeName]=typeInfo;});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_[categoryPart]=typeInfo;});registry.registeredTypeInfos_.push(typeInfo);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_={};registry.categoryPartToTypeInfoMap_={};var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){var state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){var typeInfoIndex=-1;for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor==constructor){typeInfoIndex=i;break;}}
-if(typeInfoIndex===-1)
-throw new Error(constructor+' not registered');var typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){delete registry.typeNameToTypeInfoMap_[typeName];});typeInfo.categoryParts.forEach(function(categoryPart){delete registry.categoryPartToTypeInfoMap_[categoryPart];});var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){var categoryParts=getCategoryParts(category);for(var i=0;i<categoryParts.length;i++){var categoryPart=categoryParts[i];if(registry.categoryPartToTypeInfoMap_[categoryPart])
-return registry.categoryPartToTypeInfoMap_[categoryPart];}}
-if(registry.typeNameToTypeInfoMap_[typeName])
-return registry.typeNameToTypeInfoMap_[typeName];return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){var typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)
-return typeInfo.constructor;return undefined;};}
-return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register)
-throw new Error('Already has registry');registryOptions.freeze();if(registryOptions.mode==tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode==tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
-if(registry.addEventListener===undefined)
-tr.b.EventTarget.decorate(registry);}
-return{decorateExtensionRegistry:decorateExtensionRegistry};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
-Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importClockSyncMarkers:function(){},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
-return typeInfo.constructor;return undefined;};return{Importer:Importer};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
-GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
-return false;var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)
-return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
-return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
-newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
-return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
-function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
-return merged;}
-var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
-function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
-return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
-beginMerging();}
-beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
-flushCurrentMergeBuffer();}
-flushCurrentMergeBuffer();return mergedEvents;}
-function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
-opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
-emptyRanges.push(opt_totalRange);return emptyRanges;}
-inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
-inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
-continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
-if(other.max>range.max){return;}}
-if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
-return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
-return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
-this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)
-return undefined;return this.min_;},get max(){if(this.isEmpty_)
-return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)
-return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)
-return 0;return this.max_-this.min_;},equals:function(that){if(this.isEmpty&&that.isEmpty)
-return true;if(this.isEmpty!=that.isEmpty)
-return false;return this.min===that.min&&this.max===that.max;},containsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<max&&min<this.max_;},containsRangeInclusive:function(range){if(range.isEmpty)
-return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive:function(range){if(range.isEmpty)
-return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive:function(range){if(range.isEmpty)
-return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive:function(range){if(range.isEmpty)
-return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
-return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)
-return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)
-return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)
-return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1){var i=Math.trunc((i0+i1)/2);if(test(i))
-i1=i;else
-i0=i+1;}
-return i1;}
-var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
-var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true){return new Range();}else if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}else{throw new Error('Not a range');}};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)
-return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)
-return-1;if(!a.isEmpty&&b.isEmpty)
-return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
-function Statistics(){}
-Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
-return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
-ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){var valueCallback=opt_valueCallback||identity;var numerator=0;var denominator=0;for(var i=0;i<ary.length;i++){var value=valueCallback.call(opt_this,ary[i],i);if(value===undefined)
-continue;var weight=weightCallback.call(opt_this,ary[i],i,value);numerator+=weight*value;denominator+=weight;}
-if(denominator===0)
-return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
-ret.addValue(func.call(opt_this,ary[i],i));return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
-throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
-tmp[i]=func.call(opt_this,ary[i],i);tmp.sort((a,b)=>a-b);var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
-samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
-var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
-return{normalized_samples:samples,scale:scale};};Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
-return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
-count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
-count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
-for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
-if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
-for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
-return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
-return 0.0;if(opt_absolute===undefined)
-opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
-var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
-return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
-return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
-samples[streamLength-1]=newElement;else
-samples.push(newElement);return;}
-var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
-return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
-return;}
-if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
-for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
-return;}
-var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};return{Statistics:Statistics};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
-Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},installUserFriendlyCategoryDriverIfNeeded:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
-function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
-Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)=='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=3)
-throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}else if(str.substr(0,5)=='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=4)
-throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}else if(str[0]=='#'&&str.length==7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}else{throw new Error('Unrecognized string format.');}};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined)
-return Color.lerpRGBA(a,b,percent);return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){var r,g,b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
-if(s===0){r=g=b=l;}else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
-return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);}
-Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);}
-Color.prototype={clone:function(){var c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver:function(bgColor){var oneMinusThisAlpha=1-this.a;var outA=this.a+bgColor.a*oneMinusThisAlpha;var bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten:function(opt_k){var k;k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten:function(k,opt_max_l){var max_l=opt_max_l!==undefined?opt_max_l:1.0;var hsl=this.toHSL();hsl.l=clamp01(hsl.l+k);return Color.fromHSL(hsl);},darken:function(opt_k){var k;if(opt_k!==undefined)
-k=opt_k;else
-k=0.45;return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate:function(opt_desaturateFactor){var desaturateFactor;if(opt_desaturateFactor!==undefined)
-desaturateFactor=opt_desaturateFactor;else
-desaturateFactor=1;var hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha:function(a){return new Color(this.r,this.g,this.b,a);},toString:function(){if(this.a!==undefined){return'rgba('+
-this.r+','+this.g+','+
-this.b+','+this.a+')';}
-return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL:function(){var r=this.r/255;var g=this.g/255;var b=this.b/255;var max=Math.max(r,g,b);var min=Math.min(r,g,b);var h,s;var l=(max+min)/2;if(min===max){h=0;s=0;}else{var delta=max-min;if(l>0.5)
-s=delta/(2-max-min);else
-s=delta/(max+min);if(r===max){h=(g-b)/delta;if(g<b)
-h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
-h/=6;}
-return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
-this.r+','+this.g+','+
-this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
-var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant:numColorsPerVariant};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
-pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m={};var i=generalPurposeColors.length;tr.b.iterItems(reservedColorsByName,function(key,value){m[key]=i++;});return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap[name];if(id===undefined)
-throw new Error('Unrecognized color ')+name;return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i)
-hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;return hash;};var stringColorIdCache={};ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache[string]===undefined){var hash=ColorScheme.getStringHash(string);stringColorIdCache[string]=hash%numGeneralPurposeColorIds;}
-return stringColorIdCache[string];};return{ColorScheme:ColorScheme};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
-return{EventInfo:EventInfo};});'use strict';tr.exportTo('tr.b',function(){var nextGUID=1;var GUID={allocate:function(){return nextGUID++;},getLastGuid:function(){return nextGUID-1;}};return{GUID:GUID};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.name===undefined)
-throw new Error('Registered events must provide name metadata');var i=tr.b.findFirstInArray(EventRegistry.getAllRegisteredTypeInfos(),function(x){return x.metadata.name===metadata.name;});if(i!==undefined)
-throw new Error('Event type with that name already registered');if(metadata.pluralName===undefined)
-throw new Error('Registered events must provide pluralName metadata');if(metadata.singleViewElementName===undefined){throw new Error('Registered events must provide '+'singleViewElementName metadata');}
-if(metadata.multiViewElementName===undefined){throw new Error('Registered events must provide '+'multiViewElementName metadata');}});var eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
-return eventsByTypeName[typeName];}
-EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
-EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry:EventRegistry};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_dirty_=true;this.bounds_=new tr.b.Range();this.length_=0;this.guid_=tr.b.GUID.allocate();this.pushed_guids_={};if(opt_events){if(opt_events instanceof Array){for(var i=0;i<opt_events.length;i++)
-this.push(opt_events[i]);}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
-EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_)
-this.resolveBounds_();return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
-return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.length_;},get guid(){return this.guid_;},clear:function(){for(var i=0;i<this.length_;++i)
-delete this[i];this.length_=0;this.bounds_dirty_=true;},resolveBounds_:function(){this.bounds_.reset();for(var i=0;i<this.length_;i++)
-this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;},push:function(event){if(event.guid==undefined)
-throw new Error('Event must have a GUID');if(this.contains(event))
-return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},indexOf:function(event){for(var i=0;i<this.length;i++){if(this[i].guid===event.guid)
-return i;}
-return-1;},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
-this.push(eventSet[i]);},subEventSet:function(index,count){count=count||1;var eventSet=new EventSet();eventSet.bounds_dirty_=true;if(index<0||index+count>this.length_)
-throw new Error('Index out of bounds');for(var i=index;i<index+count;i++)
-eventSet.push(this[i]);return eventSet;},intersectionIsEmpty:function(otherEventSet){return!this.some(function(event){return otherEventSet.contains(event);});},equals:function(that){if(this.length!==that.length)
-return false;for(var i=0;i<this.length;i++){var event=this[i];if(that.pushed_guids_[event.guid]===undefined)
-return false;}
-return true;},getEventsOrganizedByBaseType:function(opt_pruneEmpty){var allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();var events=this.getEventsOrganizedByCallback(function(event){var maxEventIndex=-1;var maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))
-return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex==-1){console.log(event);throw new Error('Unrecognized event type');}
-return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined)
-events[eventTypeInfo.metadata.name]=new EventSet();});}
-return events;},getEventsOrganizedByTitle:function(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined)
-throw new Error('An event didn\'t have a title!');return event.title;});},getEventsOrganizedByCallback:function(cb){var eventsByCallback={};for(var i=0;i<this.length;i++){var event=this[i];var key=cb(event);if(key===undefined)
-throw new Error('An event could not be organized');if(eventsByCallback[key]===undefined)
-eventsByCallback[key]=new EventSet();eventsByCallback[key].push(event);}
-return eventsByCallback;},enumEventsOfType:function(type,func){for(var i=0;i<this.length_;i++)
-if(this[i]instanceof type)
-func(this[i]);},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
-var eventsByBaseType=this.getEventsOrganizedByBaseType(true);var eventTypeName=tr.b.dictionaryKeys(eventsByBaseType)[0];if(this.length===1){var tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return this[0].userFriendlyName;}
-var numEventTypes=tr.b.dictionaryLength(eventsByBaseType);if(numEventTypes!==1){return this.length+' events of various types';}
-var tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter:function(fn,opt_this){var res=new EventSet();this.forEach(function(slice){if(fn.call(this,slice))
-res.push(slice);},opt_this);return res;},toArray:function(){var ary=[];for(var i=0;i<this.length;i++)
-ary.push(this[i]);return ary;},forEach:function(fn,opt_this){for(var i=0;i<this.length;i++)
-fn.call(opt_this,this[i],i);},map:function(fn,opt_this){var res=[];for(var i=0;i<this.length;i++)
-res.push(fn.call(opt_this,this[i],i));return res;},every:function(fn,opt_this){for(var i=0;i<this.length;i++)
-if(!fn.call(opt_this,this[i],i))
-return false;return true;},some:function(fn,opt_this){for(var i=0;i<this.length;i++)
-if(fn.call(opt_this,this[i],i))
-return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};EventSet.IMMUTABLE_EMPTY_SET=(function(){var s=new EventSet();s.resolveBounds_();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
-var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];}
-return{SelectionState:SelectionState};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
-SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)
-return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)
-return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;var IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.info=undefined;}
-Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert:function(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET)
-this.associatedAlerts=new tr.model.EventSet();this.associatedAlerts.push(alert);},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.v',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
-TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,opt_precisionUnit){if(opt_precisionUnit===undefined)
-opt_precisionUnit=tr.v.TimeDisplayModes.ms;var startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);var endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.v',function(){var TimeDisplayModes=tr.v.TimeDisplayModes;var BINARY_PREFIXES=['','Ki','Mi','Gi','Ti'];var PLUS_MINUS_SIGN=String.fromCharCode(177);function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return a.scale>b.scale?a:b;}
-var ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,isDelta,improvementDirection,formatValue){this.unitName=unitName;this.jsonName=jsonName;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatValue_=formatValue;this.correspondingDeltaUnit=undefined;}
-Unit.prototype={asJSON:function(){return this.jsonName;},format:function(value){var formattedValue=this.formatValue_(value);if(!this.isDelta||value<0)
-return formattedValue;if(value===0)
-return PLUS_MINUS_SIGN+formattedValue;else
-return'+'+formattedValue;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return us/1000;};Unit.maybeTimestampFromUs=function(us){return us===undefined?undefined:us/1000;};Object.defineProperty(Unit,'currentTimeDisplayMode',{get:function(){return Unit.currentTimeDisplayMode_;},set:function(value){if(Unit.currentTimeDisplayMode_===value)
-return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){var u=Unit.byJSONName[object];if(u){return u;}
-throw new Error('Unrecognized unit');};Unit.define=function(params){tr.b.iterItems(ImprovementDirection,function(_,improvementDirection){var regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);var deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;});};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){var nameSuffix=isDelta?'Delta':'';switch(improvementDirection){case ImprovementDirection.DONT_CARE:break;case ImprovementDirection.BIGGER_IS_BETTER:nameSuffix+='_biggerIsBetter';break;case ImprovementDirection.SMALLER_IS_BETTER:nameSuffix+='_smallerIsBetter';break;default:throw new Error('Unknown improvement direction: '+improvementDirection);}
-var unitName=params.baseUnitName+nameSuffix;var jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined)
-throw new Error('Unit \''+unitName+'\' already exists');if(Unit.byJSONName[jsonName]!==undefined)
-throw new Error('JSON unit \''+jsonName+'\' alread exists');var unit=new Unit(unitName,jsonName,isDelta,improvementDirection,params.formatValue);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatValue:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatValue:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
-var i=0;while(value>=1024&&i<BINARY_PREFIXES.length-1){value/=1024;i++;}
-return signPrefix+value.toFixed(1)+' '+BINARY_PREFIXES[i]+'B';}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' W';}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}});return{ImprovementDirection:ImprovementDirection,Unit:Unit};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
-Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
-return 1;var low=0;var high=ary.length-1;var i,comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
-return hitPos!=-1?hitPos:low;}
-function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0)
-lo=mid+1;else
-hi=mid;}
-return hi;}
-function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){var first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first==0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}else{return-1;}}else if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}else if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
-mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else if(first==ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
-mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else{return ary.length;}}
-function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){var i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}else{return-1;}}else if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}else{return ary.length;}}else if(i==ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else{return ary.length;}}else{return ary.length;}}
-function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length==0)
-return;if(loVal>hiVal)return;var i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i==-1){return;}
-if(i>0){var hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
-if(i==ary.length){return;}
-for(var n=ary.length;i<n;i++){var lo=mapLoFn(ary[i]);if(lo>=hiVal)
-break;cb(ary[i],i);}}
-function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){var tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
-function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)
-return null;var aftIdx=findLowIndexInSortedArray(ary,mapFn,val);var befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)
-aftIdx-=1;var befDiff=Math.abs(val-mapFn(ary[befIdx]));var aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)
-return null;var idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
-function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)
-return null;var idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)
-idx-=1;var hiInt=ary[idx];var loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length)
-loInt=ary[idx+1];var loDiff=Math.abs(val-mapLoFn(loInt));var hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)
-return null;if(loDiff<hiDiff)
-return loInt;else
-return hiInt;}
-return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model.helpers',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
-function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
-var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
-function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
-return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
-return undefined;}
-function getPreTraversalWorkRanges(uiThread){if(!uiThread)
-return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
-preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
-preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
-function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
-return preTraversalWorkRange.start;return traversalStart;}
-function getUiThreadDrivenFrames(app){if(!app.uiThread)
-return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
-preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
-var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
-threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
-frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getRenderThreadDrivenFrames(app){if(!app.renderThread)
-return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getUiDrawType(uiThread){if(!uiThread)
-return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
-return UI_DRAW_TYPE.NONE;}
-function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
-if(!samples)
-return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
-lastValue=sample.value;});return inputSamples;}
-function getAnimationAsyncSlices(uiThread){if(!uiThread)
-return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
-slices.push(slice);});return slices;}
-function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
-var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
-return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
-return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
-return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.model.helpers',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
-vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
-return vsync.series[0].timestamps;return undefined;}
-function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
-return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
-return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
-return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
-return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.model.helpers',function(){var AndroidApp=tr.model.helpers.AndroidApp;var AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
-return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
-callback(slice);});}
-function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
-model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
-this.apps.push(app);},this);};AndroidModelHelper.guid=tr.b.GUID.allocate();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
-this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
-this.duration=opt_duration;if(opt_cpuStart!==undefined)
-this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
-this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
-this.argsStripped=true;}
-Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
-parentSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
-return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
-return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},get mostTopLevelSlice(){var curSlice=this;while(curSlice.parentSlice)
-curSlice=curSlice.parentSlice;return curSlice;},getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
-return thread.getProcess();return undefined;},get model(){var process=this.getProcess();if(process!==undefined)
-return this.getProcess().model;return undefined;},findTopmostSlicesRelativeToThisSlice:function(eventPredicate,callback,opt_this){if(eventPredicate(this)){callback.call(opt_this,this);return;}
-this.subSlices.forEach(function(s){s.findTopmostSlicesRelativeToThisSlice(eventPredicate,callback,opt_this);});},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
-callback.call(opt_this,curSlice);else
-started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
-ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
-return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)
-continue;if(cpuSlice.duration!==this.duration)
-continue;return cpuSlice;}
-return undefined;},getCpuSliceThatTookCpu:function(){if(this.cpuOnWhichThreadWasRunning)
-return undefined;var curIndex=this.thread.indexOfTimeSlice(this);var cpuSliceWhenLastRunning;while(curIndex>=0){var curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
-cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
-if(!cpuSliceWhenLastRunning)
-return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)
-return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001)
-return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model.um',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorTitle,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorTitle_=initiatorTitle;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
-UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
-cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
-return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
-cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
-cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;},get associatedSamples(){var samples=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event instanceof tr.model.ThreadSlice)
-samples.addEventSet(event.overlappingSamples);});return samples;},get userFriendlyName(){return this.title+' User Expectation at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+
-this.parentModel.userModel.expectations.indexOf(this));},get typeInfo(){if(!this.typeInfo_)
-this.typeInfo_=UserExpectation.findTypeInfo(this.constructor);if(!this.typeInfo_)
-throw new Error('Unregistered UserExpectation');return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorTitle(){return this.initiatorTitle_;},get title(){if(!this.initiatorTitle)
-return this.stageTitle;return this.initiatorTitle+' '+this.stageTitle;},get totalCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
-cpuMs+=event.cpuSelfTime;});return cpuMs;}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(UserExpectation,options);UserExpectation.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
-if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'user-expectation',pluralName:'user-expectations',singleViewElementName:'tr-ui-a-single-user-expectation-sub-view',multiViewElementName:'tr-ui-a-multi-user-expectation-sub-view'});return{UserExpectation:UserExpectation};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
-ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation:ResponseExpectation};});'use strict';tr.exportTo('tr.v',function(){var Range=tr.b.Range;var MAX_SOURCE_INFOS=16;function NumericBase(unit){if(!(unit instanceof tr.v.Unit))
-throw new Error('Expected provided unit to be instance of Unit');this.unit=unit;}
-NumericBase.prototype={asDict:function(){var d={unit:this.unit.asJSON()};this.asDictInto_(d);return d;}};NumericBase.fromDict=function(d){if(d.type==='scalar')
-return ScalarNumeric.fromDict(d);throw new Error('Not implemented');};function NumericBin(parentNumeric,opt_range){this.parentNumeric=parentNumeric;this.range=opt_range||(new tr.b.Range());this.count=0;this.sourceInfos=[];}
-NumericBin.fromDict=function(parentNumeric,d){var n=new NumericBin(parentNumeric);n.range.min=d.min;n.range.max=d.max;n.count=d.count;n.sourceInfos=d.sourceInfos;return n;};NumericBin.prototype={add:function(value,sourceInfo){this.count+=1;tr.b.Statistics.uniformlySampleStream(this.sourceInfos,this.count,sourceInfo,MAX_SOURCE_INFOS);},addBin:function(other){if(!this.range.equals(other.range))
-throw new Error('Merging incompatible Numeric bins.');tr.b.Statistics.mergeSampledStreams(this.sourceInfos,this.count,other.sourceInfos,other.count,MAX_SOURCE_INFOS);this.count+=other.count;},asDict:function(){return{min:this.range.min,max:this.range.max,count:this.count,sourceInfos:this.sourceInfos.slice(0)};},asJSON:function(){return this.asDict();}};function Numeric(unit,range,binInfo){NumericBase.call(this,unit);this.range=range;this.numNans=0;this.nanSourceInfos=[];this.runningSum=0;this.maxCount_=0;this.underflowBin=binInfo.underflowBin;this.centralBins=binInfo.centralBins;this.overflowBin=binInfo.overflowBin;this.allBins=[];this.allBins.push(this.underflowBin);this.allBins.push.apply(this.allBins,this.centralBins);this.allBins.push(this.overflowBin);this.allBins.forEach(function(bin){if(bin.count>this.maxCount_)
-this.maxCount_=bin.count;},this);}
-Numeric.fromDict=function(d){var range=Range.fromExplicitRange(d.min,d.max);var binInfo={};binInfo.underflowBin=NumericBin.fromDict(undefined,d.underflowBin);binInfo.centralBins=d.centralBins.map(function(binAsDict){return NumericBin.fromDict(undefined,binAsDict);});binInfo.overflowBin=NumericBin.fromDict(undefined,d.overflowBin);var n=new Numeric(tr.v.Unit.fromJSON(d.unit),range,binInfo);n.allBins.forEach(function(bin){bin.parentNumeric=n;});n.runningSum=d.runningSum;n.numNans=d.numNans;n.nanSourceInfos=d.nanSourceInfos;return n;};Numeric.prototype={__proto__:NumericBase.prototype,get numValues(){return tr.b.Statistics.sum(this.allBins,function(e){return e.count;});},get average(){return this.runningSum/this.numValues;},get maxCount(){return this.maxCount_;},getApproximatePercentile:function(percent){if(!(percent>=0&&percent<=1))
-throw new Error('percent must be [0,1]');if(this.numValues==0)
-return 0;var valuesToSkip=Math.floor((this.numValues-1)*percent);for(var i=0;i<this.allBins.length;i++){var bin=this.allBins[i];valuesToSkip-=bin.count;if(valuesToSkip<0){if(bin===this.underflowBin)
-return bin.range.max;else if(bin===this.overflowBin)
-return bin.range.min;else
-return bin.range.center;}}
-throw new Error('Unreachable');},getInterpolatedCountAt:function(value){var bin=this.getBinForValue(value);var idx=this.centralBins.indexOf(bin);if(idx<0){return bin.count;}
-var lesserBin=bin;var greaterBin=bin;var lesserBinCenter=undefined;var greaterBinCenter=undefined;if(value<greaterBin.range.center){if(idx>0){lesserBin=this.centralBins[idx-1];}else{lesserBin=this.underflowBin;lesserBinCenter=lesserBin.range.max;}}else{if(idx<(this.centralBins.length-1)){greaterBin=this.centralBins[idx+1];}else{greaterBin=this.overflowBin;greaterBinCenter=greaterBin.range.min;}}
-if(greaterBinCenter===undefined)
-greaterBinCenter=greaterBin.range.center;if(lesserBinCenter===undefined)
-lesserBinCenter=lesserBin.range.center;value=tr.b.normalize(value,lesserBinCenter,greaterBinCenter);return tr.b.lerp(value,lesserBin.count,greaterBin.count);},getBinForValue:function(value){var binIndex=tr.b.findHighIndexInSortedArray(this.allBins,b=>value<b.range.max?-1:1);return this.allBins[binIndex]||this.overflowBin;},add:function(value,sourceInfo){if(typeof(value)!=='number'||isNaN(value)){this.numNans++;tr.b.Statistics.uniformlySampleStream(this.nanSourceInfos,this.numNans,sourceInfo,MAX_SOURCE_INFOS);return;}
-var bin=this.getBinForValue(value);bin.add(value,sourceInfo);this.runningSum+=value;if(bin.count>this.maxCount_)
-this.maxCount_=bin.count;},addNumeric:function(other){if(!this.range.equals(other.range)||!this.unit===other.unit||this.allBins.length!==other.allBins.length){throw new Error('Merging incompatible Numerics.');}
-tr.b.Statistics.mergeSampledStreams(this.nanSourceInfos,this.numNans,other.nanSourceInfos,other.numNans,MAX_SOURCE_INFOS);this.numNans+=other.numNans;this.runningSum+=other.runningSum;for(var i=0;i<this.allBins.length;++i){this.allBins[i].addBin(other.allBins[i]);}},clone:function(){return Numeric.fromDict(this.asDict());},asDict:function(){var d={unit:this.unit.asJSON(),type:'numeric',min:this.range.min,max:this.range.max,numNans:this.numNans,nanSourceInfos:this.nanSourceInfos,runningSum:this.runningSum,underflowBin:this.underflowBin.asDict(),centralBins:this.centralBins.map(function(bin){return bin.asDict();}),overflowBin:this.overflowBin.asDict()};return d;},asJSON:function(){return this.asDict();}};function NumericBuilder(unit,minBinBoundary){this.unit_=unit;this.boundaries_=[minBinBoundary];}
-NumericBuilder.prototype={get minBinBoundary(){return this.boundaries_[0];},get maxBinBoundary(){return this.boundaries_[this.boundaries_.length-1];},addBinBoundary:function(nextMaxBinBoundary){if(nextMaxBinBoundary<=this.maxBinBoundary){throw new Error('The added max bin boundary must be larger than '+'the current max boundary');}
-this.boundaries_.push(nextMaxBinBoundary);return this;},addLinearBins:function(nextMaxBinBoundary,binCount){if(binCount<=0)
-throw new Error('Bin count must be positive');var curMaxBinBoundary=this.maxBinBoundary;if(curMaxBinBoundary>=nextMaxBinBoundary){throw new Error('The last added max boundary must be greater than '+'the current max boundary boundary');}
-var binWidth=(nextMaxBinBoundary-curMaxBinBoundary)/binCount;for(var i=1;i<binCount;i++)
-this.addBinBoundary(curMaxBinBoundary+i*binWidth);this.addBinBoundary(nextMaxBinBoundary);return this;},addExponentialBins:function(nextMaxBinBoundary,binCount){if(binCount<=0)
-throw new Error('Bin count must be positive');var curMaxBinBoundary=this.maxBinBoundary;if(curMaxBinBoundary<=0)
-throw new Error('Current max bin boundary must be positive');if(curMaxBinBoundary>=nextMaxBinBoundary){throw new Error('The last added max boundary must be greater than '+'the current max boundary boundary');}
-var binExponentWidth=Math.log(nextMaxBinBoundary/curMaxBinBoundary)/binCount;for(var i=1;i<binCount;i++){this.addBinBoundary(curMaxBinBoundary*Math.exp(i*binExponentWidth));}
-this.addBinBoundary(nextMaxBinBoundary);return this;},build:function(){var binInfo={underflowBin:new NumericBin(undefined,Range.fromExplicitRange(-Number.MAX_VALUE,this.minBinBoundary)),overflowBin:new NumericBin(undefined,Range.fromExplicitRange(this.maxBinBoundary,Number.MAX_VALUE)),centralBins:new Array(this.boundaries_.length-1)};for(var i=0;i<this.boundaries_.length-1;i++){binInfo.centralBins[i]=new NumericBin(undefined,Range.fromExplicitRange(this.boundaries_[i],this.boundaries_[i+1]));}
-var numeric=new Numeric(this.unit_,Range.fromExplicitRange(this.minBinBoundary,this.maxBinBoundary),binInfo);numeric.allBins.forEach(function(bin){bin.parentNumeric=numeric;});return numeric;}};NumericBuilder.createLinear=function(unit,range,numBins){if(range.isEmpty)
-throw new Error('Range must be non-empty');return new NumericBuilder(unit,range.min).addLinearBins(range.max,numBins);};function ScalarNumeric(unit,value){if(!(typeof(value)=='number'))
-throw new Error('Expected value to be number');NumericBase.call(this,unit);this.value=value;}
-ScalarNumeric.prototype={__proto__:NumericBase.prototype,asDictInto_:function(d){d.type='scalar';d.value=this.value;},toString:function(){return this.unit.format(this.value);}};ScalarNumeric.fromDict=function(d){return new ScalarNumeric(tr.v.Unit.fromJSON(d.unit),d.value);};return{NumericBase:NumericBase,NumericBin:NumericBin,Numeric:Numeric,NumericBuilder:NumericBuilder,ScalarNumeric:ScalarNumeric};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.model.helpers.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var ScalarNumeric=tr.v.ScalarNumeric;var timeDurationInMs=tr.v.Unit.byName.timeDurationInMs;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
-function getDuration(e){return e.duration;}
-function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
-function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
-return true;}
-return false;}
-function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
-function DocLinkBuilder(){this.docLinks=[];}
-DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger)
-this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
-events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
-return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
-return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
-return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new ScalarNumeric(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
-var start=Statistics.min(events,getStart);var args={'Time spent':new ScalarNumeric(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
-if(!slice||getCpuDuration(slice)<3)
-return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new ScalarNumeric(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
-totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
-return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
-key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
-key='Blocking I/O delay';args[key]=new ScalarNumeric(timeDurationInMs,value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
-process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
-var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
-uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
-process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
-thread.sortIndex=-3;if(thread.name=='RenderThread')
-thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
-thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
-this.model.faviconHue='red';else if(portionBad>0.05)
-this.model.faviconHue='yellow';else
-this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
-appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
-appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
-return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
-return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
-return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
-alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
-AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
-this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
-return true;return expectedParentNames.some(function(name){return name in parentNames;});};if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
-slice.info=this.titleInfoLookup[slice.title];}
-if(slice.subSlices.length>0){if(!(slice.title in parentNames))
-parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
-delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.model.helpers',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}
-function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
-ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
-titleToGet=MAIN_RENDERING_STATS;else
-titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
-return;if(range.intersectsExplicitRangeInclusive(event.start,event.end))
-frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
-return frametimeData;}
-return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
-ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
-return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
-events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
-if(!match)
-return;if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
-return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
-return false;if(t.name.indexOf('CompositorTileWorker')===0)
-return true;if(t.name.indexOf('CompositorRasterWorker')===0)
-return true;return false;});this.isChromeTracingUI_=process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))
-return true;if(process.findAtMostOneThreadNamed('Compositor'))
-return true;return false;};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get isChromeTracingUI(){return this.isChromeTracingUI_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeBrowserHelper.isBrowserProcess(process))
-return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
-return undefined;if(browserProcesses.length>1)
-return undefined;return browserProcesses[0];}
-function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeRendererHelper.isRenderProcess(process))
-return;rendererProcesses.push(process);});return rendererProcesses;}
-function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
-return undefined;return gpuProcesses[0];}
-function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.model.helpers.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
-var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
-var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
-ChromeModelHelper.guid=tr.b.GUID.allocate();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
-return true;if(findChromeRenderProcesses(model).length)
-return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
-this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
-this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
-this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(var i=0;i<this.subSlices.length;i++){var subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined)
-subSlice.parentContainer=parentContainer;}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
-parentAsyncSliceGroup.slices.indexOf(this);},findTopmostSlicesRelativeToThisSlice:function(eventPredicate,callback,opt_this){if(eventPredicate(this))
-callback.call(opt_this,this);else{this.subSlices.forEach(function(s){s.findTopmostSlicesRelativeToThisSlice(eventPredicate,callback,opt_this);});}},findDescendentSlice:function(targetTitle){if(!this.subSlices)
-return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
-return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
-this.determineModernTypeName_();}
-InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
-this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
-throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
-if(!found)
-this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
-return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
-return;if(!subSlice.typeName)
-return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
-this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
-throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;var modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)
-return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
-mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
-compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
-break;}
-var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
-return rendererHelper;}
-return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
-slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
-slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
-return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
-continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
-continue;}else{if(parseInt(parentId)!==parseInt(this.id))
-continue;}
-slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
-return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
-return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
-fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
-return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
-return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
-return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
-return;if(slice.title==='TaskQueueManager::RunTask')
-return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
-return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='InputRouterImpl::ProcessInputEventAck')
-inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
-stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
-return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
-return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
-return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
-this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
-this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
-break;}}}
-while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
-this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
-this.backtraceFromDraw(beginImplFrame,visitedEvents);}
-var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
-this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
-return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
-return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
-return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
-return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
-return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.chrome',function(){var SAME_AS_PARENT='same-as-parent';var TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser'],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],script:['EvaluateScript','FunctionCall','ScheduledAction::execute','Script','V8.Execute','v8.run','v8.callModuleMethod','v8.callFunction','WindowProxy::initialize'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['V8.RecompileSynchronous','V8.RecompileConcurrent','V8.PreParseMicroSeconds','v8.parseOnBackground','V8.ParseMicroSeconds','V8.ParseLazyMicroSeconds','V8.CompileScriptMicroSeconds','V8.CompileMicroSeconds','V8.CompileFullCode','V8.CompileEvalMicroSeconds','v8.compile'],script_parse:['V8Test.ParseScript','V8Test.ParseFunction',],script_compile:['V8Test.Compile','V8Test.CompileFullCode',],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],[SAME_AS_PARENT]:['SyncChannel::Send']};var USER_FRIENDLY_CATEGORY_FOR_TITLE={};for(var category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE[title]=category;});}
-var USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
-ChromeUserFriendlyCategoryDriver.fromEvent=function(event){var userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE[event.title];if(userFriendlyCategory){if(userFriendlyCategory==SAME_AS_PARENT){if(event.parentSlice)
-return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}else{return userFriendlyCategory;}}
-var eventCategoryParts=tr.b.getCategoryParts(event.category);for(var i=0;i<eventCategoryParts.length;++i){var eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory)
-return userFriendlyCategory;}
-return undefined;};return{ChromeUserFriendlyCategoryDriver:ChromeUserFriendlyCategoryDriver};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr'};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);var modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
-return;for(var pid in this.modelHelper.rendererHelpers){var rendererHelper=this.modelHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)
-rendererHelper.process.important=false;}},installUserFriendlyCategoryDriverIfNeeded:function(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit:function(){if(!this.modelHelper)
-return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
-ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
-this.objectInstance.typeName+' '+
-this.objectInstance.id+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
-ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
-throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
-throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
-throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
-if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
-throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
-throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
-var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
-throw new Error('Instance cannot be deleted at ts='+
-ts+'. A snapshot exists that is older.');}
-this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
-throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
-if(ts>this.deletionTs)
-throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
-return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
-if(i>=this.snapshots.length)
-return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
-this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
-this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
-this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function FrameTreeNodeSnapshot(){ObjectSnapshot.apply(this,arguments);}
-FrameTreeNodeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'FrameTreeNode';}};ObjectSnapshot.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){ObjectInstance.apply(this,arguments);}
-FrameTreeNodeInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot:FrameTreeNodeSnapshot,FrameTreeNodeInstance:FrameTreeNodeInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds)
-this.needsLayoutReasons_.push('self');if(args.childNeeds)
-this.needsLayoutReasons_.push('child');if(args.posChildNeeds)
-this.needsLayoutReasons_.push('positionedChild');if(args.positionedMovement)
-this.needsLayoutReasons_.push('positionedMovement');this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
-for(var property in args){if(!KNOWN_PROPERTIES[property])
-this.otherProperties_[property]=args[property];}}
-LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
-return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
-return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
-return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
-return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.chrome',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
-LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
-LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});tr.model.EventRegistry.register(LayoutTreeSnapshot,{name:'layoutTree',pluralName:'layoutTrees',singleViewElementName:'tr-ui-a-layout-tree-sub-view',multiViewElementName:'tr-ui-a-layout-tree-sub-view'});return{LayoutTreeInstance:LayoutTreeInstance,LayoutTreeSnapshot:LayoutTreeSnapshot};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function RenderFrameSnapshot(){ObjectSnapshot.apply(this,arguments);}
-RenderFrameSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'RenderFrame';}};ObjectSnapshot.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){ObjectInstance.apply(this,arguments);}
-RenderFrameInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot:RenderFrameSnapshot,RenderFrameInstance:RenderFrameInstance};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
-function b64ToUint6(nChr){if(nChr>64&&nChr<91)
-return nChr-65;if(nChr>96&&nChr<123)
-return nChr-71;if(nChr>47&&nChr<58)
-return nChr+4;if(nChr===43)
-return 62;if(nChr===47)
-return 63;return 0;}
-Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
-binary+=String.fromCharCode(bytes[i]);return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
-throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
-nUint24=0;}}
-return nOutIdx-1;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
-EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
-ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
-throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
-pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
-uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
-var directoryTableBase;if(header.version>=3)
-directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
-flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
-imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
-commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
-var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
-exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
-process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
-throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
-ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
-throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
-startAddr=decoder.decodeUInteger(header.is64);else
-affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
-return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
-new_process_name=new_process.name;else
-new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
-cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return Math.max(a,b);}
-function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
-IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
-return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
-this.flipNodeColour_(root);if(node.key<root.key)
-root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
-root.merge(node);else
-root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
-root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
-root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
-return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
-throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
-throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
-return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
-return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
-IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
-return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
-break;ret.push(this.data[i].datum);}}
-if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
-this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
-ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
-ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){var glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');var glMatrixModule=require(glMatrixAbsPath);for(var exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
-function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
-function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
-function deg2rad(deg){return(Math.PI*deg)/180.0;}
-var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
-throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
-return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
-return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);};return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
-tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
-function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
-Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
-Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
-Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
-Quad.from8Array=function(arr){if(arr.length!=8)
-throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
-vec2.toString(this.p1)+', '+
-vec2.toString(this.p2)+', '+
-vec2.toString(this.p3)+', '+
-vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
-(p2[0]-p3[0])*(p1[1]-p3[1]);}
-function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
-function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
-return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
-function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
-return value;if(typeof value=='string')
-return value.substring();if(typeof value=='boolean')
-return value;if(typeof value=='number')
-return value;throw new Error('Unrecognized: '+typeof value);}
-var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
-res[i]=deepCopy(object[i]);return res;}
-if(object.__proto__!=Object.prototype)
-throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
-return res;}
-function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
-if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
-var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
-var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
-function stackTraceAsString(){return new Error().stack+'';}
-function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
-function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
-return undefined;}
-return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;var REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;var idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)
-return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
-function nativeRequestIdleCallbackSupported(){return!tr.isHeadless&&window.requestIdleCallback;}
-function scheduleIdleWork(){if(idleWorkScheduled)
-return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
-idleWorkScheduled=true;window.requestIdleCallback(function(deadline,didTimeout){processIdleWork(false,deadline);},{timeout:REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS});}
-function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
-throw e;if(opt_stack)
-console.log(opt_stack);if(e.message)
-console.error(e.message,e.stack);else
-console.error(e);}
-function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
-function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
-runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
-runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){var rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining:function(){return rafCompletionDeadline-window.performance.now();}});}
-if(pendingIdleCallbacks.length>0)
-scheduleIdleWork();}
-function processIdleWork(forceAllTasksToRun,deadline){idleWorkScheduled=false;while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(!forceAllTasksToRun&&(tr.isHeadless||deadline.timeRemaining()<=0)){break;}}
-if(pendingIdleCallbacks.length>0)
-scheduleIdleWork();}
-function getStack_(){if(!recordRAFStacks)
-return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
-function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
-function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
-currentRAFDispatchList.push({callback:callback,context:opt_this||global,stack:getStack_()});return;}
-function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
-function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
-function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
-return;processRequests(false,frameBeginTime);}
-function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)
-return;processRequests(true,0);}
-return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun,forceAllPendingTasksToRunForTest:forceAllPendingTasksToRunForTest};});'use strict';tr.exportTo('tr.b',function(){var Base64=tr.b.Base64;function computeUserTimingMarkName(groupName,functionName,opt_args){if(groupName===undefined)
-throw new Error('getMeasureString should have group name');if(functionName===undefined)
-throw new Error('getMeasureString should have function name');var userTimingMarkName=groupName+':'+functionName;if(opt_args!==undefined){userTimingMarkName+='/';userTimingMarkName+=Base64.btoa(JSON.stringify(opt_args));}
-return userTimingMarkName;}
-function Timing(){}
-Timing.nextMarkNumber=0;Timing.mark=function(groupName,functionName,opt_args){if(tr.isHeadless){return{end:function(){}};}
-var userTimingMarkName=computeUserTimingMarkName(groupName,functionName,opt_args);var markBeginName='tvcm.mark'+Timing.nextMarkNumber++;var markEndName='tvcm.mark'+Timing.nextMarkNumber++;window.performance.mark(markBeginName);return{end:function(){window.performance.mark(markEndName);window.performance.measure(userTimingMarkName,markBeginName,markEndName);}};};Timing.wrap=function(groupName,callback,opt_args){if(groupName===undefined)
-throw new Error('Timing.wrap should have group name');if(callback.name==='')
-throw new Error('Anonymous function is not allowed');return Timing.wrapNamedFunction(groupName,callback.name,callback,opt_args);};Timing.wrapNamedFunction=function(groupName,functionName,callback,opt_args){function timedNamedFunction(){var markedTime=Timing.mark(groupName,functionName,opt_args);try{callback.apply(this,arguments);}finally{markedTime.end();}}
-return timedNamedFunction;};function TimedNamedPromise(groupName,name,executor,opt_args){var markedTime=Timing.mark(groupName,name,opt_args);var promise=new Promise(executor);promise.then(function(result){markedTime.end();return result;},function(e){markedTime.end();throw e;});return promise;}
-return{_computeUserTimingMarkName:computeUserTimingMarkName,TimedNamedPromise:TimedNamedPromise,Timing:Timing};});'use strict';tr.exportTo('tr.b',function(){var Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
-throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
-Task.prototype={get name(){return this.runCb_.name;},subTask:function(cb,thisArg){if(cb instanceof Task)
-this.subTasks_.push(cb);else
-this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
-this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
-return this.afterTask_;for(var i=1;i<subTasks.length;i++)
-subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
-throw new Error('Has an after task already');if(cb instanceof Task)
-this.afterTask_=cb;else
-this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},timedAfter:function(groupName,cb,thisArg,opt_args){if(cb.name==='')
-throw new Error('Anonymous Task is not allowed');return this.namedTimedAfter(groupName,cb.name,cb,thisArg,opt_args);},namedTimedAfter:function(groupName,name,cb,thisArg,opt_args){if(this.afterTask_)
-throw new Error('Has an after task already');var realTask;if(cb instanceof Task)
-realTask=cb;else
-realTask=new Task(cb,thisArg);this.afterTask_=new Task(function(task){var markedTask=Timing.mark(groupName,name,opt_args);task.subTask(realTask,thisArg);task.subTask(function(){markedTask.end();},thisArg);},thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
-lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
-curTask=curTask.run();}
-Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
-if(curTask){tr.b.requestIdleCallback(runAnother);return;}
-resolve();}
-tr.b.requestIdleCallback(runAnother);});}
-return{Task:Task};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
-function Filter(){}
-Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
-throw new Error('Filter text is empty.');}
-TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
-return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
-throw new Error('Filter text is empty.');}
-ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
-FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
-continue;if(this.regex_.test(key))
-return true;if(this.regex_.test(obj[key]))
-return true;}
-return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
-return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.model',function(){var ClockDomainId={BATTOR:'BATTOR',UNKNOWN_CHROME_LEGACY:'UNKNOWN_CHROME_LEGACY',LINUX_CLOCK_MONOTONIC:'LINUX_CLOCK_MONOTONIC',MAC_MACH_ABSOLUTE_TIME:'MAC_MACH_ABSOLUTE_TIME',WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME',WIN_QPC:'WIN_QPC'};var BATTOR_FAST_SYNC_THRESHOLD_MS=3;function ClockSyncManager(){this.markersBySyncId_={};this.modelDomainId_=undefined;this.modelTimeTransformerByDomainId_=undefined;}
-ClockSyncManager.prototype={addClockSyncMarker:function(domainId,syncId,startTs,opt_endTs){if(tr.b.dictionaryValues(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
-if(this.modelDomainId_!==undefined){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
-if(this.markersBySyncId_[syncId]===undefined)
-this.markersBySyncId_[syncId]=[];var markers=this.markersBySyncId_[syncId];if(markers.length===1&&markers[0].domainId===domainId){throw new Error('A clock domain cannot sync with itself.');}
-if(markers.length===1&&this.connectorExistsBetween_(markers[0].domainId,domainId)){throw new Error('Cannot add multiple connectors between the same '+'clock domains.');}
-if(markers.length===2){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
-markers.push(new ClockSyncMarker(domainId,startTs,opt_endTs));},getModelTimeTransformer:function(domainId){if(this.modelTimeTransformerByDomainId_===undefined)
-this.buildModelTimeTransformerMap_();var transformer=this.modelTimeTransformerByDomainId_[domainId];if(transformer===undefined){throw new Error('No clock sync markers exist pairing clock domain "'+
-domainId+'" '+'with model clock domain "'+
-this.modelDomainId_+'".');}
-return transformer;},buildModelTimeTransformerMap_(){var actualChromeDomain=this.getActualTraceEventImporterDomain_();if(actualChromeDomain!==undefined){this.substituteDomainInMarkers_(actualChromeDomain,ClockDomainId.UNKNOWN_CHROME_LEGACY);}
-this.buildModelTimeTransformerMapImpl_();if(actualChromeDomain!==undefined){var chromeModelTimeTransform=this.modelTimeTransformerByDomainId_[ClockDomainId.UNKNOWN_CHROME_LEGACY];this.modelTimeTransformerByDomainId_[actualChromeDomain]=chromeModelTimeTransform;}},buildModelTimeTransformerMapImpl_(){var connectorsByDomainId_=this.getConnectorsByDomainId_();var uniqueDomainIds=tr.b.dictionaryKeys(connectorsByDomainId_);uniqueDomainIds.sort();var isFullyConnected=function(domainId){return connectorsByDomainId_[domainId].length===uniqueDomainIds.length-1;};var eligibleModelDomainIds=uniqueDomainIds.filter(isFullyConnected);var chromeLegacyDomainExists=eligibleModelDomainIds.indexOf(ClockDomainId.UNKNOWN_CHROME_LEGACY)>=0;this.modelDomainId_=chromeLegacyDomainExists?ClockDomainId.UNKNOWN_CHROME_LEGACY:eligibleModelDomainIds[0];if(this.modelDomainId_===undefined){throw new Error('Unable to select a master clock domain because no '+'clock domain is directly connected to all others.');}
-this.modelTimeTransformerByDomainId_={};this.modelTimeTransformerByDomainId_[this.modelDomainId_]=tr.b.identity;var modelConnectors=connectorsByDomainId_[this.modelDomainId_];for(var i=0;i<modelConnectors.length;i++){var conn=modelConnectors[i];if(conn.marker1.domainId===this.modelDomainId_){this.modelTimeTransformerByDomainId_[conn.marker2.domainId]=conn.getTransformer(conn.marker2.domainId,conn.marker1.domainId);}else{this.modelTimeTransformerByDomainId_[conn.marker1.domainId]=conn.getTransformer(conn.marker1.domainId,conn.marker2.domainId);}}},getActualTraceEventImporterDomain_:function(){var connectorsByDomainId=this.getConnectorsByDomainId_();var uniqueDomainIds=tr.b.dictionaryKeys(connectorsByDomainId);if(uniqueDomainIds.indexOf(ClockDomainId.UNKNOWN_CHROME_LEGACY)<0)
-return undefined;if(uniqueDomainIds.indexOf(ClockDomainId.LINUX_CLOCK_MONOTONIC)>=0)
-return ClockDomainId.LINUX_CLOCK_MONOTONIC;if(uniqueDomainIds.indexOf(ClockDomainId.MAC_MACH_ABSOLUTE_TIME)>=0)
-return ClockDomainId.MAC_MACH_ABSOLUTE_TIME;if(uniqueDomainIds.indexOf(ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME)>=0){return ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME;}
-if(uniqueDomainIds.indexOf(ClockDomainId.WIN_QPC)>=0)
-return ClockDomainId.WIN_QPC;return undefined;},substituteDomainInMarkers_:function(original,replacement){for(var syncId in this.markersBySyncId_){for(var i=0;i<this.markersBySyncId_[syncId].length;i++){var marker=this.markersBySyncId_[syncId][i];if(marker.domainId===original)
-marker.domainId=replacement;}}},getConnectorsByDomainId_:function(){var connectorsByDomainId={};for(var syncId in this.markersBySyncId_){var markers=this.markersBySyncId_[syncId];if(markers.length===1){var markerDomainId=markers[0].domainId;if(connectorsByDomainId[markerDomainId]===undefined)
-connectorsByDomainId[markerDomainId]=[];continue;}
-var conn=new ClockSyncConnector(markers[0],markers[1]);var domain1=conn.marker1.domainId;if(connectorsByDomainId[domain1]===undefined)
-connectorsByDomainId[domain1]=[];var domain2=conn.marker2.domainId;if(connectorsByDomainId[domain2]===undefined)
-connectorsByDomainId[domain2]=[];connectorsByDomainId[markers[0].domainId].push(conn);connectorsByDomainId[markers[1].domainId].push(conn);}
-return connectorsByDomainId;},connectorExistsBetween_(domain1Id,domain2Id){for(var syncId in this.markersBySyncId_){var markers=this.markersBySyncId_[syncId];if(markers.length!==2)
-continue;var connector=new ClockSyncConnector(markers[0],markers[1]);if(connector.isBetween(domain1Id,domain2Id))
-return true;}
-return false;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
-ClockSyncMarker.prototype={get duration(){return this.endTs-this.startTs;},get ts(){return this.startTs+this.duration/2;}};function ClockSyncConnector(marker1,marker2){if(marker1===undefined||marker2===undefined)
-throw new Error('ClockSyncConnectors must consist of defined markers.');this.marker1=marker1;this.marker2=marker2;}
-ClockSyncConnector.prototype={getTransformer:function(fromDomainId,toDomainId){if(!this.isBetween(fromDomainId,toDomainId))
-throw new Error('This connector cannot perform this transformation.');var fromMarker,toMarker;if(this.marker1.domainId===fromDomainId){fromMarker=this.marker1;toMarker=this.marker2;}else{fromMarker=this.marker2;toMarker=this.marker1;}
-var fromTs=fromMarker.ts,toTs=toMarker.ts;if(fromDomainId==ClockDomainId.BATTOR&&toMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){toTs=toMarker.startTs;}else if(toDomainId==ClockDomainId.BATTOR&&fromMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){fromTs=fromMarker.startTs;}
-var tsShift=toTs-fromTs;return function(ts){return ts+tsShift;};},isBetween:function(domain1Id,domain2Id){if(this.marker1.domainId===domain1Id&&this.marker2.domainId===domain2Id){return true;}
-if(this.marker1.domainId===domain2Id&&this.marker2.domainId===domain1Id){return true;}
-return false;}};return{ClockDomainId:ClockDomainId,ClockSyncManager:ClockSyncManager};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
-EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
-visit(this);},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){throw new Error('Not implemented.');},findTopmostSlices:function(eventPredicate,callback,opt_this){this.iterateAllEventContainers(function(ec){ec.findTopmostSlicesInThisContainer(eventPredicate,callback,opt_this);});},findTopmostSlicesNamed:function(name,callback,opt_this){this.findTopmostSlices(e=>e.title===name,callback,opt_this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
-PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
-PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);var powerInWatts=sample.power/1000.0;var durationInSeconds=timeIntersection.duration/1000;energyConsumed+=durationInSeconds*powerInWatts;}
-return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
-this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
-return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
-this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
-throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
-this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
-callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
-this.duration=opt_duration;}
-FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.LevelOfDetail={LIGHT:0,DETAILED:1};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
-return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
-return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex:function(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
-return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
-this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
-return true;dump=dump.parent;}
-return false;},addNumeric:function(name,numeric){if(!(numeric instanceof tr.v.ScalarNumeric))
-throw new Error('Numeric value must be an instance of ScalarNumeric.');if(name in this.numerics)
-throw new Error('Duplicate numeric name: '+name+'.');this.numerics[name]=numeric;},addDiagnostic:function(name,text){if(typeof text!=='string')
-throw new Error('Diagnostic text must be a string.');if(name in this.diagnostics)
-throw new Error('Duplicate diagnostic name: '+name+'.');this.diagnostics[name]=text;},aggregateNumericsRecursively:function(opt_model){var numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);tr.b.iterItems(child.numerics,numericNames.add,numericNames);},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
-this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){var shouldLogWarning=!!opt_model;var aggregatedUnit=undefined;var aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)
-return;var unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
-aggregatedUnit.unitName+'\' and \''+unit.unitName+'\'.'});shouldLogWarning=false;}
-aggregatedUnit=tr.v.Unit.byName.unitlessNumber_smallerIsBetter;}
-aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)
-return undefined;return new tr.v.ScalarNumeric(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
-var MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType:MemoryAllocatorDumpInfoType};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
-var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;var nextPosition=0;for(var i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))
-continue;if(nextPosition<i)
-array[nextPosition]=array[i];nextPosition++;}
-if(nextPosition<array.length)
-array.length=nextPosition;}
-function getSize(dump){var numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
-return 0;return numeric.value;}
-function hasSize(dump){return dump.numerics[SIZE_NUMERIC_NAME]!==undefined;}
-function optional(value,defaultValue){if(value===undefined)
-return defaultValue;return value;}
-GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph:function(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps:function(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)
-return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
-removeWeakDumpsFromListRecursively(dump.children);inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
-this.iterateContainerDumps(function(containerDump){var memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined)
-removeWeakDumpsFromListRecursively(memoryAllocatorDumps);});},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
-return 0;shouldDefineSize=true;return numeric.value;}
-var sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];var size=0;var checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.v.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
-sizeNumeric.unit.unitName+'.'});}
-checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)
-return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
-dump.fullName+'\''+
-tr.v.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
-tr.v.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize:dependencySize});}.bind(this);}
-var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump)
-ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){var previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;var updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
-return;}
-if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
-descendantDump.children.forEach(aggregateDescendantDump);}
-aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
-size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
-return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
-var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
-return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
-var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;if(dump.ownedBy.length===0)
-return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
-return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
-var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
-var owningCoefficient=0;if(notOwningSubSize!==0)
-owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
-currentImportanceStartPos=nextImportanceStartPos;}
-var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
-ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
-cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
-dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
-var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
-return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
-dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);},this);},propagateNumericsAndDiagnosticsRecursively:function(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){tr.b.iterItems(globalAllocatorDump[field],function(name,value){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
-processAllocatorDump[field][name]=value;});});});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.setUpTracingOverheadOwnership(this.model);},this);},discountTracingOverheadFromVmRegions:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverheadFromVmRegions(this.model);},this);},forceRebuildingMemoryAllocatorDumpByFullNameIndices:function(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(openDumps.has(dump))
-throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
-this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
-return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
-return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
-this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
-CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
-return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
-CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
-return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
-Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
-callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
-return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
-return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
-this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
-return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
-return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
-return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
-CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning)
-return undefined;var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start)
-continue;if(timeSlice.duration!==this.duration)
-continue;return timeSlice;}
-return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices',singleViewElementName:'tr-ui-a-single-cpu-slice-sub-view',multiViewElementName:'tr-ui-a-multi-cpu-slice-sub-view'});return{CpuSlice:CpuSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Counter=tr.model.Counter;var CpuSlice=tr.model.CpuSlice;var Slice=tr.model.Slice;function Cpu(kernel,number){if(kernel===undefined||number===undefined)
-throw new Error('Missing arguments');this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds=new tr.b.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;};Cpu.prototype={get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){this.slices.forEach(function(s){s.findTopmostSlicesRelativeToThisSlice(eventPredicate,callback,opt_this);});},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CpuSlice))
-this.slices.forEach(callback,opt_this);if(this.samples_){if(eventTypePredicate.call(opt_this,tr.model.Sample))
-this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){for(var id in this.counters)
-callback.call(opt_this,this.counters[id]);},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-return undefined;return this.counters[id];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++)
-this.slices[sI].start=(this.slices[sI].start+amount);for(var id in this.counters)
-this.counters[id].shiftTimestampsForward(amount);},updateBounds:function(){this.bounds.reset();if(this.slices.length){this.bounds.addValue(this.slices[0].start);this.bounds.addValue(this.slices[this.slices.length-1].end);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
-if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices:function(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu==this;},this);},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.slices.length;i++)
-categoriesDict[this.slices[i].category]=true;for(var id in this.counters)
-categoriesDict[this.counters[id].category]=true;for(var i=0;i<this.samples_.length;i++)
-categoriesDict[this.samples_[i].category]=true;},indexOf:function(cpuSlice){var i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)
-return undefined;return i;},closeActiveThread:function(end_timestamp,args){if(this.lastActiveThread_==undefined||this.lastActiveThread_==0)
-return;if(end_timestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
-this.cpuNumber+' is before its start timestamp.');}
-for(var key in args){this.lastActiveArgs_[key]=args[key];}
-var duration=end_timestamp-this.lastActiveTimestamp_;var slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread:function(timestamp,old_thread_args,new_thread_id,new_thread_name,new_thread_args){this.closeActiveThread(timestamp,old_thread_args);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=new_thread_id;this.lastActiveName_=new_thread_name;this.lastActiveArgs_=new_thread_args;},getFreqStatsForRange:function(range){var stats={};function addStatsForFreq(freqSample,index){var freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;var freqRange=tr.b.Range.fromExplicitRange(freqSample.timestamp,freqEnd);var intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats))
-stats[freqSample.value]=0;stats[freqSample.value]+=intersection.duration;}
-var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)
-return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){return index<freqSeries.length-1?freqSeries.samples_[index+1].timestamp:range.max;},range.min,range.max,addStatsForFreq);}
-return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
-TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
-lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
-var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
-if(instance.snapshots.length!=0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
-instance.snapshots[0].ts+' and creationTs was '+
-instance.creationTs);}
-instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
-break;if(tmp.creationTsWasExplicit==false&&tmp.snapshots.length==0)
-lastValidIndex=i;}
-if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
-instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
-return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length==0)
-return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs)
-throw new Error('Cannot delete an id before it was created');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
-if(ts<lastInstance.deletionTs)
-throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
-return undefined;return this.instances[0];}else if(i>=this.instances.length){return undefined;}
-return this.instances[i];},logToConsole:function(){for(var i=0;i<this.instances.length;i++){var instance=this.instances[i];var cEF='';var dEF='';if(instance.creationTsWasExplicit)
-cEF='(explicitC)';if(instance.deletionTsWasExplicit)
-dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
-ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){var bI=!!eventTypePredicate.call(opt_this,ObjectInstance);var bS=!!eventTypePredicate.call(opt_this,ObjectSnapshot);if(bI===false&&bS===false)
-return;this.iterObjectInstances(function(instance){if(bI)
-callback.call(opt_this,instance);if(bS)
-instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,scopedId,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
-instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(scopedId){var dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
-var instanceMap=dict[scopedId.id];if(instanceMap)
-return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(scopedId,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
-snapshot.objectInstance.category+' name='+
-snapshot.objectInstance.name;throw new Error(msg);}
-if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!=opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
-opt_baseTypeName+'. It '+'was previously created with name='+
-snapshot.objectInstance.baseTypeName);}
-if(snapshot.objectInstance.name!=name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
-snapshot.objectInstance.name);}
-return snapshot;},idWasDeleted:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
-return;if(deletedInstance.category!=category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
-deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
-if(deletedInstance.baseTypeName!=name){throw new Error('Deletion requested for name='+
-name+' could not proceed: '+'An existing object with baseTypeName='+
-deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
-return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});});},getObjectInstanceAt:function(scopedId,ts){var instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_)
-instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];if(!instanceMap)
-return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(scopedId,ts){var instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)
-return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
-AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)
-return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)
-return;for(var sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){var prefix='';if(this.name!==undefined)
-prefix=this.name+'.';else
-prefix='';var subGroupsByTitle={};for(var i=0;i<this.slices.length;++i){var slice=this.slices[i];var subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
-subGroupsByTitle[subGroupTitle].push(slice);}
-this.viewSubGroups_=tr.b.dictionaryValues(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
-return this.viewSubGroups_;},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){for(var i=0;i<this.slices.length;i++){var slice=this.slices[i];if(slice.isTopLevel)
-slice.findTopmostSlicesRelativeToThisSlice(eventPredicate,callback,opt_this);}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.AsyncSlice)){for(var i=0;i<this.slices.length;i++){var slice=this.slices[i];callback.call(opt_this,slice);if(slice.subSlices)
-slice.subSlices.forEach(callback,opt_this);}}},iterateAllChildEventContainers:function(callback,opt_this){}};return{AsyncSliceGroup:AsyncSliceGroup};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Slice=tr.model.Slice;function getSliceLo(s){return s.start;}
-function getSliceHi(s){return s.end;}
-function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;var sliceConstructor=opt_sliceConstructor||Slice;this.sliceConstructor=sliceConstructor;this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined)
-throw new Error('SliceGroup must have model defined.');}
-SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey:function(){if(!this.name_)
-return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice:function(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices:function(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice:function(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){var prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start)
-throw new Error('Slices must be added in increasing timestamp order');}
-var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd:function(ts){if(!this.openPartialSlices_.length)
-return true;var top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)
-return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice:function(ts,opt_tts,opt_colorId){if(!this.openSliceCount)
-throw new Error('endSlice called without an open slice');var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start)
-throw new Error('Slice '+slice.title+' end time is before its start.');slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined)
-slice.cpuDuration=opt_tts-slice.cpuStart;return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bind_id){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bind_id);if(duration===undefined)
-slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(){this.updateBounds();var maxTimestamp=this.bounds.max;for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
-slice.duration=maxTimestamp-slice.start;}
-this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var newSlice=new this.sliceConstructor(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){if(!this.haveTopLevelSlicesBeenBuilt)
-throw new Error('Nope');this.topLevelSlices.forEach(function(s){s.findTopmostSlicesRelativeToThisSlice(eventPredicate,callback,opt_this);});},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,this.sliceConstructor))
-this.slices.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title==title){slices.push(this.slices[i]);}}
-return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);topLevelSlice.iterateAllDescendents(callback);});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt)
-throw new Error('Nope');if(0===this.slices.length)
-return undefined;return this.slices[0];},findSliceAtTs:function(ts){if(!this.haveTopLevelSlicesBeenBuilt)
-throw new Error('Nope');var i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==this.topLevelSlices.length)
-return undefined;var curSlice=this.topLevelSlices[i];while(true){var i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==curSlice.subSlices.length)
-return curSlice;curSlice=curSlice.subSlices[i];}},findNextSliceAfter:function(ts,refGuid){var i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length)
-return undefined;for(;i<this.slices.length;i++){var slice=this.slices[i];if(slice.start>ts)
-return slice;if(slice.guid<=refGuid)
-continue;return slice;}
-return undefined;},createSubSlices:function(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(this.parentContainer.timeSlices)
-this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);this.slices.forEach(function(slice){var selfTime=slice.duration;for(var i=0;i<slice.subSlices.length;i++)
-selfTime-=slice.subSlices[i].duration;slice.selfTime=selfTime;if(slice.cpuDuration===undefined)
-return;var cpuSelfTime=slice.cpuDuration;for(var i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined)
-cpuSelfTime-=slice.subSlices[i].cpuDuration;}
-slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_:function(){var precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(root,child){if(root.bounds(child,precisionUnit)){if(root.subSlices&&root.subSlices.length>0){if(addSliceIfBounds(root.subSlices[root.subSlices.length-1],child))
-return true;}
-child.parentSlice=root;if(root.subSlices===undefined)
-root.subSlices=[];root.subSlices.push(child);return true;}
-return false;}
-if(!this.slices.length)
-return;var ops=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].subSlices)
-this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);ops.push(i);}
-var originalSlices=this.slices;ops.sort(function(ix,iy){var x=originalSlices[ix];var y=originalSlices[iy];if(x.start!=y.start)
-return x.start-y.start;return ix-iy;});var slices=new Array(this.slices.length);for(var i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
-var rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(var i=1;i<slices.length;i++){var slice=slices[i];if(!addSliceIfBounds(rootSlice,slice)){rootSlice=slice;rootSlice.isTopLevel=true;this.topLevelSlices.push(rootSlice);}}
-this.slices=slices;},addCpuTimeToSubslices_:function(timeSlices){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState==SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_:function(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start)
-return slice.end<=timeSlice.end;var duration=timeSlice.duration;if(slice.start>timeSlice.start)
-duration-=slice.start-timeSlice.start;if(timeSlice.end>slice.end)
-duration-=timeSlice.end-slice.end;if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
-for(var i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
-return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0)
-throw new Error('groupA has open partial slices');if(groupB.openPartialSlices_.length>0)
-throw new Error('groupB has open partial slices');if(groupA.parentContainer!=groupB.parentContainer)
-throw new Error('Different parent threads. Cannot merge');if(groupA.sliceConstructor!=groupB.sliceConstructor)
-throw new Error('Different slice constructors. Cannot merge');var result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);var slicesA=groupA.slices;var slicesB=groupB.slices;var idxA=0;var idxB=0;var openA=[];var openB=[];var splitOpenSlices=function(when){for(var i=0;i<openB.length;i++){var oldSlice=openB[i];var oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
-var newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')==-1)
-newSlice.title+=' (cont.)';oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};var closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){var nextA=openA[openA.length-1];var nextB=openB[openB.length-1];var endA=nextA&&nextA.end;var endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
-if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice,isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
-closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
-closeOpenSlices();return result;};return{SliceGroup:SliceGroup};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id);this.subSlices=[];}
-ThreadSlice.prototype={__proto__:Slice.prototype,get overlappingSamples(){var samples=new tr.model.EventSet();if(!this.parentContainer||!this.parentContainer.samples)
-return samples;this.parentContainer.samples.forEach(function(sample){if(this.start<=sample.start&&sample.start<=this.end)
-samples.push(sample);},this);return samples;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
-throw new Error('Parent must be provided.');tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;var that=this;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
-Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.sliceGroup.length)
-callback.call(opt_this,this.sliceGroup);if(this.kernelSliceGroup.length)
-callback.call(opt_this,this.kernelSliceGroup);if(this.asyncSliceGroup.length)
-callback.call(opt_this,this.asyncSliceGroup);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(this.timeSlices&&this.timeSlices.length){if(eventTypePredicate.call(opt_this,ThreadTimeSlice))
-this.timeSlices.forEach(callback,opt_this);}},iterateAllPersistableObjects:function(cb){cb(this);if(this.sliceGroup.length)
-cb(this.sliceGroup);this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward:function(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(var i=0;i<this.timeSlices.length;i++){var slice=this.timeSlices[i];slice.start+=amount;}}
-this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)
-return false;if(this.sliceGroup.openSliceCount)
-return false;if(this.timeSlices&&this.timeSlices.length)
-return false;if(this.kernelSliceGroup.length)
-return false;if(this.asyncSliceGroup.length)
-return false;if(this.samples_.length)
-return false;return true;},updateBounds:function(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
-if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.sliceGroup.length;i++)
-categoriesDict[this.sliceGroup.slices[i].category]=true;for(var i=0;i<this.kernelSliceGroup.length;i++)
-categoriesDict[this.kernelSliceGroup.slices[i].category]=true;for(var i=0;i<this.asyncSliceGroup.length;i++)
-categoriesDict[this.asyncSliceGroup.slices[i].category]=true;if(this.samples_){for(var i=0;i<this.samples_.length;i++)
-categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
-(this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)
-return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)
-return undefined;return i;},getCpuStatsForRange:function(range){var stats={};stats.total=0;if(!this.timeSlices)
-return stats;function addStatsForSlice(threadTimeSlice){var freqRange=tr.b.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);var intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState==tr.model.SCHEDULING_STATE.RUNNING){var cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats))
-stats[cpu.cpuNumber]=0;stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
-tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange:function(start,end){var stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var overlapStart=Math.max(threadTimeSlice.start,start);var overlapEnd=Math.min(threadTimeSlice.end,end);var schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))
-stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
-tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;}};Thread.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp)
-return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)
-return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;return x.tid-y.tid;};return{Thread:Thread};});'use strict';tr.exportTo('tr.model',function(){var Thread=tr.model.Thread;var Counter=tr.model.Counter;function ProcessBase(model){if(!model)
-throw new Error('Must provide a model');tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;};ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var tid in this.threads)
-callback.call(opt_this,this.threads[tid]);for(var id in this.counters)
-callback.call(opt_this,this.counters[id]);callback.call(opt_this,this.objects);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads)
-this.threads[tid].iterateAllPersistableObjects(cb);},get numThreads(){var n=0;for(var p in this.threads){n++;}
-return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
-this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads)
-this.threads[tid].addCategoriesToDict(categoriesDict);for(var id in this.counters)
-categoriesDict[this.counters[id].category]=true;this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching:function(predicate,opt_this){var threads=[];for(var tid in this.threads){var thread=this.threads[tid];if(predicate.call(opt_this,thread))
-threads.push(thread);}
-return threads;},findAllThreadsNamed:function(name){var threads=this.findAllThreadsMatching(function(thread){if(!thread.name)
-return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed:function(name){var threads=this.findAllThreadsNamed(name);if(threads.length===0)
-return undefined;if(threads.length>1)
-throw new Error('Expected no more than one '+name);return threads[0];},pruneEmptyContainers:function(){var threadsToKeep={};for(var tid in this.threads){var thread=this.threads[tid];if(!thread.isEmpty)
-threadsToKeep[tid]=thread;}
-this.threads=threadsToKeep;},getThread:function(tid){return this.threads[tid];},getOrCreateThread:function(tid){if(!this.threads[tid])
-this.threads[tid]=new Thread(this,tid);return this.threads[tid];},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getSettingsKey:function(){throw new Error('Not implemented');},createSubSlices:function(){for(var tid in this.threads)
-this.threads[tid].createSubSlices();}};return{ProcessBase:ProcessBase};});'use strict';tr.exportTo('tr.model',function(){var Cpu=tr.model.Cpu;var ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;};Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo:function(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu:function(cpuNumber){if(!this.cpus[cpuNumber])
-this.cpus[cpuNumber]=new Cpu(this,cpuNumber);return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
-this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){var realCpuCount=tr.b.dictionaryLength(this.cpus);if(realCpuCount!==0)
-return realCpuCount;return this.softwareMeasuredCpuCount;},updateBounds:function(){ProcessBase.prototype.updateBounds.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices:function(){ProcessBase.prototype.createSubSlices.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict:function(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(var cpuNumber in this.cpus)
-this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);},getSettingsKey:function(){return'kernel';},iterateAllChildEventContainers:function(callback,opt_this){ProcessBase.prototype.iterateAllChildEventContainers.call(this,callback,opt_this);for(var cpuId in this.cpus)
-callback.call(opt_this,this.cpus[cpuId]);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);}};return{Kernel:Kernel};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=new Array();}
-this.flowEventsById_[fe.id].push(fe);}},this);}
-ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=new Array();}
-this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id))
-return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;}
-ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent:function(phase,category,title,ts,opt_eventSizeinBytes){var key=phase+'/'+category+'/'+title;var eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase:phase,category:category,title:title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
-eventStats.numEvents++;var timeIntervalKey=Math.floor(tr.v.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);var eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
-eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;}};return{ModelStats:ModelStats};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)
-return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
-(this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
-(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-')+
-(this.protectionFlags&VMRegion.PROTECTION_FLAG_MAYSHARE?'s':'p'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,dict.byteStats);};function VMRegionClassificationNode(opt_rule){this.rule_=opt_rule||VMRegionClassificationNode.CLASSIFICATION_RULES;this.hasRegions=false;this.sizeInBytes=undefined;this.byteStats={};this.children_=undefined;this.regions_=[];}
-VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){var tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(var i=0;i<regions.length;i++)
-tree.addStatsFromRegion_(regions[i]);return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode)
-return undefined;if(this.children_===undefined)
-this.buildTree_();return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
-return this.regions_;},get allRegionsForTesting(){if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
-return this.regions_;}
-var regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){var children=this.rule_.children;return children===undefined||children.length===0;},addRegion:function(region){this.addRegionRecursively_(region,true);},someRegion:function(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
-return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_:function(region,addStatsToThisNode){if(addStatsToThisNode)
-this.addStatsFromRegion_(region);if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
-this.regions_.push(region);return;}
-function regionRowMatchesChildNide(child){var fileRegExp=child.rule_.file;if(fileRegExp===undefined)
-return true;return fileRegExp.test(region.mappedFile);}
-var matchedChild=tr.b.findFirstInArray(this.children_,regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length)
-throw new Error('Internal error');matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
-matchedChild.addRegionRecursively_(region,true);},buildTree_:function(){var cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(var i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_:function(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
-if(this.regions_!==undefined&&this.regions_.length!==0){throw new Error('Internal error: Classification node should have no regions');}
-if(this.isLeafNode)
-return;this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){var child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_:function(region){this.hasRegions=true;var regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined)
-this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;var thisByteStats=this.byteStats;var regionByteStats=region.byteStats;for(var byteStatName in regionByteStats){var regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)
-continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion:VMRegion,VMRegionClassificationNode:VMRegionClassificationNode};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){var sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)
-return 0;return sizeNumeric.value;}
-function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership:function(opt_model){if(this.tracingOverheadOwnershipSetUp_)
-return;this.tracingOverheadOwnershipSetUp_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
-if(tracingDump.owns!==undefined)
-return;var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
-return false;var nextPathIndex=0;var currentDump=allocatorDump;var currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)
-break;currentDump=childDump;currentFullName=childFullName;}
-for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
-var ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps)
-this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},discountTracingOverheadFromVmRegions:function(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)
-return;this.tracingOverheadDiscountedFromVmRegions_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
-return;var discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);var discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)
-return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
-this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
-this.totals.peakResidentBytes-=discountedResidentSize;}
-if(this.vmRegions!==undefined){var hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;var hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;var hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){var byteStats={};if(hasPrivateDirtyResident)
-byteStats.privateDirtyResident=-discountedResidentSize;if(hasProportionalResident)
-byteStats.proportionalResident=-discountedResidentSize;this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats:byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined)
-mostRecentVmRegions=processDump.vmRegions;processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
-throw new Error('model must be provided');if(pid===undefined)
-throw new Error('pid must be provided');tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];};Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)
-return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessInstantEvent))
-this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Frame))
-this.frames.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessMemoryDump))
-this.memoryDumps.forEach(callback,opt_this);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
-return;}
-this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name)
-res=this.name+' (pid '+this.pid+')';else
-res='Process '+this.pid;if(this.labels.length)
-res+=': '+this.labels.join(', ');return res;},get userFriendlyDetails(){if(this.name)
-return this.name+' (pid '+this.pid+')';return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)
-return undefined;if(!this.labels.length)
-return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var i=0;i<this.instantEvents.length;i++)
-this.instantEvents[i].start+=amount;for(var i=0;i<this.frames.length;i++)
-this.frames[i].shiftTimestampsForward(amount);for(var i=0;i<this.memoryDumps.length;i++)
-this.memoryDumps[i].shiftTimestampsForward(amount);for(var i=0;i<this.activities.length;i++)
-this.activities[i].shiftTimestampsForward(amount);tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++)
-this.frames[i].addBoundsToRange(this.bounds);for(var i=0;i<this.memoryDumps.length;i++)
-this.memoryDumps[i].addBoundsToRange(this.bounds);for(var i=0;i<this.activities.length;i++)
-this.activities[i].addBoundsToRange(this.bounds);},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process:Process};});'use strict';tr.exportTo('tr.model',function(){function Sample(cpu,thread,title,start,leafStackFrame,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.title=title;this.cpu=cpu;this.thread=thread;this.leafStackFrame=leafStackFrame;this.weight=opt_weight;this.args=opt_args||{};}
-Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
-throw new Error('id must be given');this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_)
-this.parentFrame_.addChild(this);}
-StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
-return this.title_;},get domain(){var result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain)
-result=this.sourceInfo_.domain;if(result==='unknown'&&this.parentFrame)
-result=this.parentFrame.domain;return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_)
-this.parentFrame_.removeChild(this);this.parentFrame_=parentFrame;if(this.parentFrame_)
-this.parentFrame_.addChild(this);},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i==-1)
-throw new Error('omg');this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++)
-this.children[i].parentFrame_=undefined;this.children.splice(0,this.children.length);},get stackTrace(){var stack=[];var cur=this;while(cur){stack.push(cur);cur=cur.parentFrame;}
-return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.model.um',function(){function UserModel(parentModel){tr.model.EventContainer.call(this);this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();}
-UserModel.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){return'UserModel';},get parentModel(){return this.parentModel_;},sortExpectations:function(){Array.prototype.sort.call(this.expectations_,function(x,y){return x.start-y.start;});},get expectations(){return this.expectations_;},shiftTimestampsForward:function(amount){},addCategoriesToDict:function(categoriesDict){},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.um.UserExpectation))
-this.expectations.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},updateBounds:function(){this.bounds.reset();this.expectations.forEach(function(expectation){expectation.addBoundsToRange(this.bounds);},this);}};return{UserModel:UserModel};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
-elements=tr.doc.querySelectorAll(source);else
-elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))
-constr.decorate(el);}}
-function define(className,opt_parentConstructor,opt_tagNS){if(typeof className=='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
-var className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName)
-throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');var tagName=className;var tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS)
-throw new Error('Must not specify tagNS if parentConstructor is given');var parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
-function f(){if(opt_parentConstructor&&f.prototype.__proto__!=opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
-var el;if(tagNS===undefined)
-el=tr.doc.createElement(tagName);else
-el=tr.doc.createElementNS(tagNS,tagName);f.decorate.call(this,el,arguments);return el;}
-f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor)
-return f.tagName;return f.parentConstructor.toString()+'::'+f.className;};return f;}
-function elementIsChildOf(el,potentialParent){if(el==potentialParent)
-return false;var cur=el;while(cur.parentNode){if(cur==potentialParent)
-return true;cur=cur.parentNode;}
-return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
-Rect.fromArray=function(ary){if(ary.length!=4)
-throw new Error('ary.length must be 4');var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;}
-Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
-this.width+', '+this.height+')';},toArray:function(){return[this.x,this.y,this.width,this.height];},clone:function(){var rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge:function(pad){var rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast:function(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size:function(){return{width:this.width,height:this.height};},scale:function(s){var rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize:function(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast:function(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate:function(v){var rect=new Rect();this.translateFast(rect,v);return rect;},translateFast:function(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside:function(containingRect){var rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects:function(that){var ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo:function(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect:Rect};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;var el=doc.querySelector(selector);if(!el)
-throw new Error('Element not found');return el.createInstance();}
-function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
-return tr.b.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
-function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
-function extractUrlString(url){var extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
-function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
-return{toThreeDigitLocaleString:toThreeDigitLocaleString,instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded,extractUrlString:extractUrlString};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
-return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);this.shadow_.appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=this.shadow_.querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);this.shadow_.querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(this.shadow_.querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return this.shadow_.querySelector('title').textContent;},set:function(title){this.shadow_.querySelector('title').textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return this.shadow_.querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)
-return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){this.parentEl_.appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));}
-this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var focusEl=undefined;var elList=this.querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)
-focusEl=elList[1];}else{focusEl=elList[0];}}
-if(focusEl===undefined)
-focusEl=this;focusEl.focus();},hide_:function(){this.parentEl_.removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_)
-this.closeBtn_.removeEventListener('click',this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
-e.stopPropagation();e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)
-return;window.setTimeout(function(){this.focus();},0);e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons)
-this.shadow_.querySelector('button-bar').style.display=undefined;else
-this.shadow_.querySelector('button-bar').style.display='none';},onKeyDown_:function(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
-if(e.keyCode!==27)
-return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)
-return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';o.textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');stackDiv.textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;o.appendChild(stackDiv);}
-var b=document.createElement('button');b.textContent='OK';b.addEventListener('click',function(){o.visible=false;});o.buttons.appendChild(b);o.visible=true;return o;}
-return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=undefined;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};}
-Model.prototype={__proto__:tr.model.EventContainer.prototype,getOrCreateHelper:function(constructor){if(!constructor.guid)
-throw new Error('Helper constructors must have GUIDs');if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
-if(!this.doesHelperGUIDSupportThisModel_[constructor.guid])
-return undefined;this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
-return this.helpersByConstructorGUID_[constructor.guid];},findTopmostSlicesInThisContainer:function(eventPredicate,callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
-this.globalMemoryDumps.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,GlobalInstantEvent))
-this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,FlowEvent))
-this.flowEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Alert))
-this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
-this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.userModel);callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
-callback.call(opt_this,this.processes[pid]);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes)
-this.processes[pid].iterateAllPersistableObjects(callback);},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;this.iterateAllChildEventContainers(function(ec){ec.updateBounds();bounds.addRange(ec.bounds);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.addBoundsToRange(bounds);});},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;this.iterateAllChildEventContainers(function(ec){ec.shiftTimestampsForward(shiftAmount);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.start+=shiftAmount;});this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock')
-throw new Error('Only traceEventClock is supported.');return tr.v.Unit.timestampFromUs(ts)+
-this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes)
-n++;return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid])
-this.processes[pid]=new Process(this,pid);return this.processes[pid];},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
-throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},getClockSyncRecordsWithSyncId:function(syncId){return this.clockSyncRecords.filter(function(x){return x.syncId===syncId;});},updateCategories_:function(){var categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
-this.processes[pid].addCategoriesToDict(categoriesDict);this.categories=[];for(var category in categoriesDict)
-if(category!='')
-this.categories.push(category);},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
-for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.threads){threads.push(process.threads[tid]);}}
-return threads;},getAllProcesses:function(){var processes=[];for(var pid in this.processes)
-processes.push(this.processes[pid]);return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
-return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid)
-throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},addUserFriendlyCategoryDriver:function(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent:function(event){for(var i=0;i<this.userFriendlyCategoryDrivers_.length;i++){var ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)
-return ufc;}
-return undefined;},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
-return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
-return tr.v.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
-return;if(this.intrinsicTimeUnit_!==undefined)
-throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){if(this.isTimeHighResolution_===undefined)
-this.isTimeHighResolution_=this.isTimeHighResolutionHeuristic_();return this.isTimeHighResolution_;},set isTimeHighResolution(value){if(this.isTimeHighResolution_===value)
-return;if(this.isTimeHighResolution_!==undefined)
-throw new Error('isTimeHighResolution already set');this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)
-return;if(this.canonicalUrl_!==undefined)
-throw new Error('canonicalUrl already set');this.canonicalUrl_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
-return;if(this.importOptions_.showImportWarnings)
-console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(var pid in this.processes)
-this.processes[pid].autoCloseOpenSlices();},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
-this.processes[pid].createSubSlices();},preInitializeObjects:function(){for(var pid in this.processes)
-this.processes[pid].preInitializeObjects();},initializeObjects:function(){for(var pid in this.processes)
-this.processes[pid].initializeObjects();},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes)
-this.processes[pid].pruneEmptyContainers();},mergeKernelWithUserland:function(){for(var pid in this.processes)
-this.processes[pid].mergeKernelWithUserland();},computeWorldBounds:function(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero)
-this.shiftWorldToZero();},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
-this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes)
-this.processes[pid].autoDeleteObjects(this.bounds.max);},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes)
-this.processes[pid].sortMemoryDumps();},finalizeMemoryGraphs:function(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups:function(){var unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){var snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;return;}}
-unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups:function(old_pid_ref,new_pid_ref){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===old_pid_ref)
-patchup.pidRef=new_pid_ref;});},isTimeHighResolutionHeuristic_:function(){if(this.intrinsicTimeUnit!==tr.v.TimeDisplayModes.ms)
-return false;var nbEvents=0;var nbPerBin=[];var maxEvents=0;for(var i=0;i<100;++i)
-nbPerBin.push(0);this.iterateAllEvents(function(event){nbEvents++;if(event.start!==undefined){var remainder=Math.floor((event.start-Math.floor(event.start))*100);nbPerBin[remainder]++;maxEvents=Math.max(maxEvents,nbPerBin[remainder]);}});if(nbEvents<100)
-return true;return(maxEvents/nbEvents)<0.9;},joinRefs:function(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_:function(){tr.b.iterItems(this.processes,function(pid,process){this.joinObjectRefsForProcess_(pid,process);},this);},joinObjectRefsForProcess_:function(pid,process){tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_:function(pid,itemTimestampField,item){if(!item.args)
-return;var patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
-return;var scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;var idRef=fieldValue.id_ref||fieldValue.idRef;var scopedId=new tr.model.ScopedId(scope,idRef);var pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;var ts=item[itemTimestampField];patchupsToApply.push({object:object,field:fieldName,pidRef:pidRef,scopedId:scopedId,ts:ts});}
-function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
-return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
-return;}
-for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
-iterObjectFieldsRecursively(item.args);}};return{Model:Model};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
-this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
-return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
-break;str=str+String.fromCharCode(c);}
-this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
-return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
-this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
-throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
-EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
-return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
-return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
-return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
-return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
-throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
-throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
-if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
-this.is64bit_=true;else
-this.is64bit_=false;}}
-return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
-var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
-return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
-return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
-this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
-return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.window={};}'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){var jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');var jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
-throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
-GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
-return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
-throw new Error('Unexpected end of gzip data');return data[position++];}
-function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
-function skipBytes(amount){position+=amount;}
-function skipZeroTerminatedString(){while(getByte()!=0){}}
-var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
-throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
-throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
-if(have_file_name)
-skipZeroTerminatedString();if(have_comment)
-skipZeroTerminatedString();if(have_header_crc)
-getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));var string=GzipImporter.transformToString(inflated_data);if(inflated_data.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflated_data.length+').');}
-return string;};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
-var type=JSZip.utils.getTypeOf(data);if(type==='string')
-return data;if(type==='array'){data=new Uint8Array(data);}
-var decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
-SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined)
-this.savedLines_.push(line);if(regex.test(line))
-return true;}
-return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
-Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
-break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
-return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
-function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
-return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
-return false;return true;}
-Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
-this.splay_(key);if(this.root_.key==key){return;}
-var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
-this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
-this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
-var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
-return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
-var current=this.root_;while(current.left){current=current.left;}
-return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
-var current=opt_startNode||this.root_;while(current.right){current=current.right;}
-return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
-var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
-if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
-right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
-if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
-left.right=current;left=current;current=current.right;}else{break;}}
-left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
-f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
-for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
-var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
-return dynaEntry;}
-return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
-var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
-return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
-return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
-var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
-dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
-try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
-(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
-var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
-return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
-this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
-return stackFrame.children[i];}
-return undefined;}
-var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
-break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
-lastStackFrame=this.model_.stackFrames[pcEntryID];}
-var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
-this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
-addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
-eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
-ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
-header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
-return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
-subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
-SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
-return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
-str+=this.file_;if(this.line_>0)
-str+=':'+this.line_;if(this.column_>0)
-str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
-JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
-tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
-var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
-function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
-if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
-return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
-var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
-TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
-return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
-return bank;}};function TraceCodeBank(){this.entries_=[];}
-TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
-return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
-return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
-this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
-break;}
-++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.model',function(){function ClockSyncRecord(syncId,start,args){this.syncId_=syncId;this.start_=start;this.args_=args;};ClockSyncRecord.prototype={get syncId(){return this.syncId_;},get start(){return this.start_;},set start(value){this.start_=value;},get args(){return this.args_;}};function InstantClockSyncRecord(syncId,start,args){ClockSyncRecord.call(this,syncId,start,args);};InstantClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype};function PingPongClockSyncRecord(syncId,start,duration,args){ClockSyncRecord.call(this,syncId,start,args);this.duration_=duration;};PingPongClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype,get duration(){return this.duration_;},set duration(value){this.duration_=value;},};return{InstantClockSyncRecord:InstantClockSyncRecord,PingPongClockSyncRecord:PingPongClockSyncRecord};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
-YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
-elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
-return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
-elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
-return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
-return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
-throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
-return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
-Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
-this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
-throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
-throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
-AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
-ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
-RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
-RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
-CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
-this.textArea_.style.visibility='hidden';return;}
-if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
-this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
-this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
-this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
-ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
-CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;}
-function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
-HeapDump.prototype={addEntry:function(leafStackFrame,objectTypeName,size){var entry=new HeapEntry(this,leafStackFrame,objectTypeName,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
-tr.model.OBJECT_DEFAULT_SCOPE+'\' as the default scope.');}
-this.scope=scope;this.id=id;}
-ScopedId.prototype={toString:function(){return'{scope: '+this.scope+', id: '+this.id+'}';}};return{ScopedId:ScopedId};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
-XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
-XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var Base64=tr.b.Base64;var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
-return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
-var timestampFromUs=tr.v.Unit.timestampFromUs;var maybeTimestampFromUs=tr.v.Unit.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,LIGHT,DETAILED];var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};var WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;var OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.allMemoryDumpEvents_={};this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
-eventData=eventData+']';}
-this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
-this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.powerTraceAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.v.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
-this.model_.intrinsicTimeUnit=unit;}
-var knownFieldNames={powerTraceAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
-continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName==='metadata'){var metadata=container[fieldName];if(metadata['highres-ticks'])
-this.model_.isTimeHighResolution=metadata['highres-ticks'];if(metadata['clock-domain'])
-this.clockDomainId_=metadata['clock-domain'];}}}}
-TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
-if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
-return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
-return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
-return true;}}
-return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
-subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
-obj={};if(this.eventsWereFromString_)
-return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
-obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
-ctr_name=event.name+'['+event.id+']';else
-ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
-if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
-var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
-if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
-throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
-var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
-slice.title+' in openSlice, and is '+
-event.name+' in endSlice'});}
-slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
-dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
-return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
-event.flowPhase=STEP;else
-event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
-var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
-this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
-map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
-map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processMetadataEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
-if(event.argsStripped)
-return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
-process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
-n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){var objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
-event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
-if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
-var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
-var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
-return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
-function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
-var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
-return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
-var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
-lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.v8SamplingData_.push(event);return;}
-var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
-if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processMemoryDumpEvent:function(event){if(event.ph!=='v')
-throw new Error('Invalid memory dump event phase "'+event.ph+'".');var dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
-var pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
-dumpId+'\') without a PID.'});return;}
-var allEvents=this.allMemoryDumpEvents_;var dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined)
-allEvents[dumpId]=dumpIdEvents={};var processEvents=dumpIdEvents[pid];if(processEvents===undefined)
-dumpIdEvents[pid]=processEvents=[];processEvents.push(event);},processClockSyncEvent:function(event){if(event.ph!=='c')
-throw new Error('Invalid clock sync event phase "'+event.ph+'".');var syncId=event.args.sync_id;var issueStartTs=event.args.issue_ts;var issueEndTs=event.ts;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' without an ID.'});return;}
-if(issueStartTs===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' with ID '+syncId+' without a start timestamp.'});return;}
-this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs));this.model_.clockSyncRecords.push(new tr.model.PingPongClockSyncRecord(syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs)));},processV8Events:function(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)
-return a.ts-b.ts;if(a.ph==='M'||a.ph==='I')
-return-1;else if(b.ph==='M'||b.ph==='I')
-return 1;return 0;});var length=this.v8SamplingData_.length;for(var i=0;i<length;++i){var event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){this.processV8Sample(event);}}},importClockSyncMarkers:function(){this.model_.clockSyncRecords.push(new tr.model.InstantClockSyncRecord('ftrace_importer',0,{}));for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.ph!=='c')
-continue;var eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);this.processClockSyncEvent(event);}},importEvents:function(){if(this.stackFrameEvents_)
-this.importStackFrames_(this.stackFrameEvents_,'g');if(this.traceAnnotations_)
-this.importAnnotations_();var importOptions=this.model_.importOptions;var trackDetailedModelStats=importOptions.trackDetailedModelStats;var modelStats=this.model_.stats;var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
-var eventSizeInBytes;if(trackDetailedModelStats)
-eventSizeInBytes=JSON.stringify(event).length;else
-eventSizeInBytes=undefined;if(event.ph==='B'||event.ph==='E'){modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);}else if(event.ph==='X'){modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
-this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);}else if(event.ph==='P'){modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);}else if(event.ph==='C'){modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);}else if(event.ph==='M'){modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);}else if(event.ph==='v'){modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);}else if(event.ph==='c'){}else{modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
-event.ph+' ('+event.name+')'});}}
-this.processV8Events();tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix){var model=this.model_;for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
-for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
-throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
-stackFrame.parentFrame=parentStackFrame;}},importObjectTypeNameMap_:function(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
-pid+' multiple times.'});return;}
-var objectTypeNamePrefix=undefined;var objectTypeNameSuffix=undefined;var objectTypeNameMap={};for(var objectTypeId in rawObjectTypeNameMap){var rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(var i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){var pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
-if(objectTypeNamePrefix!==undefined&&rawObjectTypeName.startsWith(objectTypeNamePrefix)&&rawObjectTypeName.endsWith(objectTypeNameSuffix)){objectTypeNameMap[objectTypeId]=rawObjectTypeName.substring(objectTypeNamePrefix.length,rawObjectTypeName.length-objectTypeNameSuffix.length);}else{objectTypeNameMap[objectTypeId]=rawObjectTypeName;}}
-this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
-this.traceAnnotations_[id].typeName+'\"'});continue;}
-this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
-this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
-if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
-if(stack!==undefined)
-return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
-return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
-return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
-return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
-var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
-var cpu;if(event.cpu!==undefined)
-cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
-return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};var nestableMeasureAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
-if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
-if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
-if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
-if(event.cat==='blink.user_timing'){var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){var key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined)
-nestableMeasureAsyncEventsByKey[key]=[];nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
-var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
-nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
-this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
-return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
-var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
-if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
-asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
-asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
-if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
-var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
-break;}
-if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
-if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
-var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
-subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
-if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
-delete asyncEventStatesByNameThenID[name][id];}}}},createNestableAsyncSlices_:function(nestableEventsByKey){for(var key in nestableEventsByKey){var eventStateEntries=nestableEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
-if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
-if(parentStack.length>0)
-eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
-var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
-var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
-eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
-return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
-var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
-startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
-eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
-var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
-var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
-slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
-for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
-return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
-return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
-if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
-return true;}
-if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
-return true;}
-return false;}
-function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
-return undefined;flowId=event.id;flowStartTs=ts;}
-var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
-function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
-if(endSlice===undefined)
-return false;}
-endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
-function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
-var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
-return true;}
-function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
-var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
-flowIdToEvent[event.bind_id]=flowEvent;return;}
-this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
-continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}
-else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
-continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}}
-continue;}
-var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
-flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
-flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
-var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
-bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
-bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
-bindToParent=true;}}
-var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
-flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
-return;function processEvent(objectEventState){var event=objectEventState.event;var scopedId=new tr.model.ScopedId(event.scope||tr.model.OBJECT_DEFAULT_SCOPE,event.id);var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
-if(scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
-var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
-scopedId+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+scopedId+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
-var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
-var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
-snapshot=process.objects.addSnapshot(scopedId,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
-scopedId+' at ts='+ts+': '+e});return;}
-instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
-scopedId+' at ts='+ts+': '+e});return;}}
-if(instance)
-instance.colorId=getEventColor(event,instance.typeName);}
-this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
-return;if(referencingObjectFieldValue instanceof
-tr.model.ObjectSnapshot)
-return null;if(referencingObjectFieldValue.id===undefined)
-return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
-throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
-cat=implicitSnapshot.cat;else
-cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
-baseTypename=implicitSnapshot.base_type;else
-baseTypename=undefined;var scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
-rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
-res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
-throw new Error('Created object must be instanceof snapshot');return res.args;}
-function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[i],func,containingSnapshot,thisArg);}
-return;}
-for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[key],func,containingSnapshot,thisArg);}}
-process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
-throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){for(var dumpId in this.allMemoryDumpEvents_)
-this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId],dumpId);},createGlobalMemoryDump_:function(dumpIdEvents,dumpId){var globalRange=new tr.b.Range();for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++)
-globalRange.addValue(timestampFromUs(processEvents[i].ts));}
-if(globalRange.isEmpty)
-throw new Error('Internal error: Global memory dump without events');var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);var globalMemoryAllocatorDumpsByFullName={};var levelsOfDetail={};var allMemoryAllocatorDumpsByGuid={};for(var pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
-globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_:function(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){var processRange=new tr.b.Range();for(var i=0;i<processEvents.length;i++)
-processRange.addValue(timestampFromUs(processEvents[i].ts));if(processRange.isEmpty)
-throw new Error('Internal error: Process memory dump without events');var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;var processMemoryAllocatorDumpsByFullName={};for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-this.parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId);this.parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId);}
-if(levelsOfDetail.process===undefined){levelsOfDetail.process=processMemoryDump.vmRegions?DETAILED:LIGHT;}
-if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'global',levelsOfDetail.process)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for global memory'+' dump (dump ID='+dumpId+').'});}
-processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_:function(processMemoryDump,dumps,pid,dumpId){var rawTotals=dumps.process_totals;if(rawTotals===undefined)
-return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var totals={};var platformSpecificTotals=undefined;for(var rawTotalName in rawTotals){var rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)
-continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
-if(rawTotalName==='peak_resident_set_bytes'){totals.peakResidentBytes=parseInt(rawTotalValue,16);continue;}
-if(rawTotalName==='is_peak_rss_resetable'){totals.arePeakResidentBytesResettable=!!rawTotalValue;continue;}
-if(platformSpecificTotals===undefined){platformSpecificTotals={};totals.platformSpecific=platformSpecificTotals;}
-platformSpecificTotals[rawTotalName]=parseInt(rawTotalValue,16);}
-if(totals.peakResidentBytes===undefined&&totals.arePeakResidentBytesResettable!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
-if(totals.arePeakResidentBytesResettable!==undefined&&totals.peakResidentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
-processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_:function(processMemoryDump,dumps,pid,dumpId){var rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)
-return;var rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)
-return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var vmRegions=new Array(rawVmRegions.length);for(var i=0;i<rawVmRegions.length;i++){var rawVmRegion=rawVmRegions[i];var byteStats={};var rawByteStats=rawVmRegion.bs;for(var rawByteStatName in rawByteStats){var rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
-i+' ('+rawVmRegion.mf+') in process memory dump for '+'PID='+pid+' and dump ID='+dumpId+' does not have a value.'});continue;}
-var byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
-rawByteStatValue+') of VM region '+i+' ('+
-rawVmRegion.mf+') in process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-byteStats[byteStatName]=parseInt(rawByteStatValue,16);}
-vmRegions[i]=new tr.model.VMRegion(parseInt(rawVmRegion.sa,16),parseInt(rawVmRegion.sz,16),rawVmRegion.pf,rawVmRegion.mf,byteStats);}
-processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_:function(processMemoryDump,dumps,pid,dumpId){var rawHeapDumps=dumps.heaps;if(rawHeapDumps===undefined)
-return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var model=this.model_;var idPrefix='p'+pid+':';var heapDumps={};var objectTypeNameMap=this.objectTypeNameMap_[pid];if(objectTypeNameMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
-for(var allocatorName in rawHeapDumps){var entries=rawHeapDumps[allocatorName].entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-var isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&objectTypeNameMap===undefined){continue;}
-var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);for(var i=0;i<entries.length;i++){var entry=entries[i];var leafStackFrameIndex=entry.bt;var leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
-leafStackFrameId+') of heap entry '+i+' (size '+
-size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}}
-leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}
-var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
-allocatorName+' heap dump for PID='+pid+'.'});continue;}}}
-var objectTypeId=entry.type;var objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(objectTypeNameMap===undefined){continue;}else{objectTypeName=objectTypeNameMap[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
-allocatorName+' heap dump for pid='+pid+'.'});continue;}}
-var size=parseInt(entry.size,16);heapDump.addEntry(leafStackFrame,objectTypeName,size);}
-if(heapDump.entries.length>0)
-heapDumps[allocatorName]=heapDump;}
-if(Object.keys(heapDumps).length>0)
-processMemoryDump.heapDumps=heapDumps;},parseMemoryDumpLevelOfDetail_:function(levelsOfDetail,dumps,pid,dumpId){var rawLevelOfDetail=dumps.level_of_detail;var level;switch(rawLevelOfDetail){case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_:function(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
-if(MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level)>MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])){levelsOfDetail[scope]=level;}
-return false;},parseMemoryDumpAllocatorDumps_:function(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){var rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)
-return;for(var fullName in rawAllocatorDumps){var rawAllocatorDump=rawAllocatorDumps[fullName];var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
-var flags=rawAllocatorDump.flags||0;var isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
-var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
-dstIndex[fullName].guid+', '+guid+' (ignored) for'+' PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined)
-allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
-dumpId+' dumped in different contexts.'});continue;}
-if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' for PID='+
-pid+' and dump ID='+dumpId+' has multiple names: '+
-allocatorDump.fullName+', '+fullName+' (ignored).'});continue;}
-if(!isWeakDump){allocatorDump.weak=false;}}
-var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
-for(var attrName in attributes){var attrArgs=attributes[attrName];var attrType=attrArgs.type;var attrValue=attrArgs.value;switch(attrType){case'scalar':if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
-attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
-dumpId+'.'});break;}
-var unit=attrArgs.units==='bytes'?tr.v.Unit.byName.sizeInBytes_smallerIsBetter:tr.v.Unit.byName.unitlessNumber_smallerIsBetter;var value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.v.ScalarNumeric(unit,value));break;case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
-attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
-dumpId+'.'});break;}
-allocatorDump.addDiagnostic(attrName,attrValue);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown type provided for attribute '+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+': '+
-attrType});break;}}}},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(var i=0;i<fullNames.length;i++){var fullName=fullNames[i];var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
-var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
-memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
-allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted){if(!allocatorDump.weak){while(parentAllocatorDump!==undefined&&parentAllocatorDump.weak===undefined){parentAllocatorDump.weak=false;parentAllocatorDump=parentAllocatorDump.parent;}}
-break;}
-fullName=parentFullName;allocatorDump=parentAllocatorDump;}}
-for(var fullName in memoryAllocatorDumpsByFullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined)
-allocatorDump.weak=true;}
-return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_:function(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined)
-continue;var rawEdges=dumps.allocators_graph;if(rawEdges===undefined)
-continue;for(var j=0;j<rawEdges.length;j++){var rawEdge=rawEdges[j];var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
-sourceGuid+').'});continue;}
-var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
-targetGuid+').'});continue;}
-var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
-sourceDump.owns.target.fullName+').'});}else{sourceDump.owns=edge;targetDump.ownedBy.push(edge);}
-break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.measure',function(){var AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
-AsyncSlice.apply(this,arguments);}
-MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice:MeasureAsyncSlice};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
-NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel)
-return this.title_;if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
-this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_)
-return this.url_;if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(var i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined)
-this.url_=this.subSlices[i].url;}}
-this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined)
-return this.byteCount_;this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
-for(var i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
-return this.byteCount_;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
-var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;if(/^<!DOCTYPE html>/.test(events))
-return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
-return componentSplit[0]+componentSplit[1];return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap)
-return activityMap[activityName];var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max)
-this.addActivityToProcess(activity);},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)
-return;var process=this.model_.getOrCreateProcess(activity.pid);var range=tr.b.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);var newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_:function(line){var match=eventLogActivityRE.exec(line);if(!match)
-return;var first_realtime_ts=this.model_.bounds.min-
-this.model_.realtime_to_monotonic_offset_ms;var year=new Date(first_realtime_ts).getFullYear();var ts=match[1].substring(0,5)+'-'+year+' '+
-match[1].substring(5,match[1].length);var monotonic_ts=Date.parse(ts)+
-this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonic_ts,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2)
-this.handleOnResumeCalled(monotonic_ts,pid,match[1]);}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2)
-this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
-this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;this.explicitSyncMark_=undefined;}
-var TestExports={};var battorDataLineRE=new RegExp('^(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate (\d+) Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importEvents:function(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
-var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var shiftTs=this.explicitClockSync();if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'No clock sync marker for the BattOr could be found.'});return;}
-series.shiftTimestampsForward(shiftTs);this.model_.device.powerSeries=series;},importPowerSamples:function(series){var lines=this.events_.split('\n');this.model_.updateBounds();var minTs=0;if(this.model_.bounds.min!==undefined)
-minTs=this.model_.bounds.min;lines.forEach(function(line){line=line.trim();if(line.length===0)
-return;if(/^#/.test(line)){groups=sampleRateLineRE.exec(line);if(!groups)
-return;this.sampleRate_=parseInt(groups[1]);}else{var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return;}
-var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);if(groups[4]!==undefined&&this.explicitSyncMark_===undefined){var id=groups[4];this.explicitSyncMark_={'id':id,'ts':time};}}},this);},explicitClockSync:function(){if(this.explicitSyncMark_===undefined)
-return undefined;var syncMarks=this.model.getClockSyncRecordsWithSyncId(this.explicitSyncMark_['id']);if(syncMarks.length!==1){this.model_.importWarning({type:'missing_sync_marker',message:'No single clock sync record found for explicit clock sync.'});return undefined;}
-var clockSync=syncMarks[0];var syncTs=clockSync.start;var traceTs=this.explicitSyncMark_['ts'];return syncTs-traceTs;},foundExplicitSyncMark:function(){return this.explicitSyncMark_!==undefined;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
-Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
-DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
-return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents:function(){var divider=this.data_.indexOf(kMethodLutEndMarker)+
-kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!=kTraceMagicValue){throw Error('Failed to match magic value');}
-this.version_=traceReader.uint16();if(this.version_!=kTraceVersionDualClock){throw Error('Unknown version');}
-var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action==kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
-kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread:function(thread_line){var tid=thread_line.slice(0,thread_line.indexOf('\t'));var thread=this.getTid(parseInt(tid));thread.name=thread_line.slice(thread_line.indexOf('\t')+1);},getTid:function(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods:function(){var methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
-kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod:function(method_line){var data=method_line.split('\t');var methodId=parseInt(data[0]);var methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod:function(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName:function(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter:DdmsImporter};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-function parseArgs(argsString){var args={};if(argsString){var argsArray=argsString.split(';');for(var i=0;i<argsArray.length;++i){var parts=argsArray[i].split('=');if(parts[0])
-args[parts.shift()]=parts.join('=');}}
-return args;}
-AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(thread,category,name,cookie,ts,args){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);var key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
-this.openAsyncSlices[key]=slice;},closeAsyncSlice:function(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
-var key=category+':'+name+':'+cookie;var slice=this.openAsyncSlices[key];if(!slice){return;}
-for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
-slice.args[arg]=args[arg];}
-slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);slice.subSlices=[new tr.model.AsyncSlice(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=eventBase.details.split('|');switch(eventData[0]){case'B':var ppid=parseInt(eventData[1]);var title=eventData[2];var args=parseArgs(eventData[3]);var category=eventData[4];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;case'E':var ppid=this.ppids_[pid];if(ppid===undefined){break;}
-var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
-var slice=thread.sliceGroup.endSlice(ts);var args=parseArgs(eventData[3]);for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
-slice.args[arg]=args[arg];}
-break;case'C':var ppid=parseInt(eventData[1]);var name=eventData[2];var value=parseInt(eventData[3]);var category=eventData[4];if(category===undefined)
-category='android';var ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;case'S':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;case'F':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;default:return false;}
-return true;}};Parser.register(AndroidParser);return{AndroidParser:AndroidParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;var binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');var binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
-var TF_ONE_WAY=0x01;var TF_ROOT_OBJECT=0x04;var TF_STATUS_CODE=0x08;var TF_ACCEPT_FDS=0x10;var NO_FLAGS=0;function binderFlagsToHuman(num){var flag=parseInt(num,16);var str='';if(flag&TF_ONE_WAY)
-str+='this is a one-way call: async, no return; ';if(flag&TF_ROOT_OBJECT)
-str+='contents are the components root object; ';if(flag&TF_STATUS_CODE)
-str+='contents are a 32-bit status code; ';if(flag&TF_ACCEPT_FDS)
-str+='allow replies with file descriptors; ';if(flag===NO_FLAGS)
-str+='No Flags Set';return str;}
-function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
-function binderCodeToHuman(code){return'Java Layer Dependent';}
-function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
-var kthread=trans.calling_kthread.thread;var internal_slice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internal_slice.title=slice.title;internal_slice.id=slice.id;internal_slice.colorId=slice.colorId;slice.subSlices.push(internal_slice);return internal_slice;}
-function generateBinderArgsForSlice(trans,c_threadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':c_threadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
-binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
-binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
-function BinderTransaction(events,calling_pid,calling_ts,calling_kthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=calling_pid;this.calling_ts=calling_ts;this.calling_kthread=calling_kthread;}
-function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
-BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binder_thread=isBinderThread(eventBase.threadName);var tgid,name;var as_slice;var need_push=false;var kthread,rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)
-return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)
-return false;var args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
-return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var prior_receive=this.getPriorReceiveOnPID(pid);if(prior_receive!==false){return this.modelPriorReceive(prior_receive,ts,pid,tgid,kthread,trans,args,event);}
-var recursive_trans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursive_trans!==false)
-return this.modelRecursiveTransactions(recursive_trans,ts,pid,kthread,trans,args);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply)
-slice.title='binder transaction';else
-slice.title='binder transaction async';this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)
-return false;var transactionkey=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){var sync_trans=syncComplete[0];var sync_slice=sync_trans.slice;var response_trans=syncComplete[1];var response_slice=response_trans.slice;sync_slice.duration=ts-sync_slice.start;var sync_internal=doInternalSlice(sync_trans,sync_slice,ts);var response_ts=response_slice.start+response_slice.duration;var response_internal=doInternalSlice(response_trans,response_slice,response_ts);if(response_slice.outFlowEvents.length===0||sync_slice.inFlowEvents.length===0){var flow=this.generateFlow(response_internal,sync_internal,response_trans,sync_trans);sync_slice.inFlowEvents.push(flow);response_slice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
-for(var i=1;i<sync_slice.inFlowEvents.length;i++){sync_slice.inFlowEvents[i].duration=ts-sync_slice.inFlowEvents[i].start;}
-return true;}
-var tr_for_recv=this.getTransactionWaitingForRecv(transactionkey);if(tr_for_recv!==false){if(!tr_for_recv.expect_reply){var args=generateBinderArgsForSlice(tr_for_recv,eventBase.threadName);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);var fake_event=[0,0,0,0,0,0,0];var fake_trans=new BinderTransaction(fake_event,pid,ts,kthread);var flow=this.generateFlow(tr_for_recv.slice,slice,tr_for_recv,fake_trans);this.model_.flowEvents.push(flow);tr_for_recv.slice.title='binder transaction async';tr_for_recv.slice.duration=.03;return true;}
-tr_for_recv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,tr_for_recv]);return true;}
-return false;},modelRecursiveTransactions:function(recursive_trans,ts,pid,kthread,trans,args){var recursive_slice=recursive_trans[1].slice;var orig_slice=recursive_trans[0].slice;recursive_slice.duration=ts-recursive_slice.start;trans.slice=recursive_slice;if(trans.is_reply_transaction){orig_slice.duration=ts-orig_slice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursive_trans);if(isReplyToOrigin(recursive_trans[0],trans))
-this.removeRecursiveTransaction(pid);}else{var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
-return true;},modelPriorReceive:function(prior_receive,ts,pid,tgid,kthread,trans,args,event){var callee_slice=prior_receive[1].slice;var callee_trans=prior_receive[1];var recv_ts=prior_receive[0];var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recv_ts,ts-recv_ts,0,0,args);var flow=this.generateFlow(callee_slice,slice,callee_trans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[callee_trans,trans]);}else{slice.title='binder reply';var trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recv_ts,(ts-recv_ts),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
-trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[callee_trans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
-return true;},getRecursiveTransactionNeedingCompletion:function(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
-return false;var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)
-return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion:function(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
-this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction:function(pid){var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
-this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID:function(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
-this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID:function(pid){if(this.receivedTransWaitingConversion[pid]===undefined)
-return false;var len=this.receivedTransWaitingConversion[pid].length;if(len===0)
-return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion:function(transactionkey,tuple){var dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion:function(transactionkey){var ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)
-return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv:function(transactionkey){var ret=this.transWaitingRecv[transactionkey];if(ret===undefined)
-return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv:function(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow:function(from,to,from_trans,to_trans){var title='Transaction from : '+
-this.pid2name(from_trans.calling_pid)+' From PID: '+from_trans.calling_pid+' to pid: '+
-to_trans.calling_pid+' Thread Name: '+this.pid2name(to_trans.calling_pid);var ts=from.start;var flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice:function(tgid,pid,name,kthread){return{'Thread Name':name,'pid':pid,'gid':tgid};},pid2name:function(pid){return this.kthreadlookup[pid];},doNameMappings:function(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName:function(pid,name){if(this.pid2name(pid)===undefined)
-this.kthreadlookup[pid]=name;}};Parser.register(BinderParser);return{BinderParser:BinderParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');var event=re.exec(eventBase.details);var name=event[1];var rw_bytes=parseInt(event[2]);var r_bytes=parseInt(event[3]);var w_bytes=parseInt(event[4]);var cycles=parseInt(event[5]);var ns=parseInt(event[6]);var r_bw=r_bytes*1000000000/ns;r_bw/=1024*1024;var w_bw=w_bytes*1000000000/ns;w_bw/=1024*1024;var ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});return true;}};Parser.register(BusParser);return{BusParser:BusParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);var name=event[1];var rate=parseInt(event[2]);var ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser:ClockParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
-function splitData(input){var data={};var args=input.split(/\s+/);var len=args.length;for(var i=0;i<len;i++){var item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
-return data;}
-CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice:function(ts,eventName,cpu,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent:function(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser:CpufreqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
-DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(ts,category,threadName,pid,key,name){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
-kthread.openAsyncSlices[key]=slice;},closeAsyncSlice:function(ts,category,threadName,pid,key,args){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){var slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4WriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},f2fsSyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[5]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4SyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var datasync=event[4]==1;var key=device+'-'+inode;var action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[3]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},blockRqIssueEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)
-return false;var action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
-if(event[2]){action+=' flush';}
-if(event[4]=='F'){action+=' fua';}
-if(event[5]=='A'){action+=' ahead';}
-if(event[6]=='S'){action+=' sync';}
-if(event[7]=='M'){action+=' meta';}
-var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)
-return false;var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var error=parseInt(event[10]);var key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device:device,sector:sector,numSectors:numSectors,error:error});return true;}};Parser.register(DiskParser);return{DiskParser:DiskParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
-DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)
-return false;var crtc=parseInt(event[1]);var seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc:crtc,seq:seq});return true;}};Parser.register(DrmParser);return{DrmParser:DrmParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
-ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample:function(name,ts,frequency){var targetCpu=this.importer.getOrCreateCpu(0);var counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
-counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice:function(ts,pipe,fb,state){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice:function(ts,pipe,fb,args){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},pageFlipStateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)
-return false;var pipe=parseInt(event[1]);var fb=parseInt(event[2]);var state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe:pipe,fb:fb});if(state!=='flipped')
-this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);return true;}};Parser.register(ExynosParser);return{ExynosParser:ExynosParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
-GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice:function(title,ts,opt_args){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice:function(title,ts){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){var slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!=title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
-slice.title+' in openSlice, and is '+
-title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
-return true;},syncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
-return true;},timerEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
-return true;}};Parser.register(GestureParser);return{GestureParser:GestureParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
-I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice:function(ts,obj,plane){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice:function(ts,args){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},i915GemObjectSlice:function(ts,eventName,obj,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice:function(ts,eventName,dev,ring,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice:function(ts,eventName,reg,args){var kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,size:size});return true;},gemObjectBindEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var offset=event[2];var size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj:obj,offset:offset,size:size});return true;},gemObjectChangeDomainEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var read=event[2];var write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,read:read,write:write});return true;},gemObjectPreadWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var offset=parseInt(event[2]);var len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,offset:offset,len:len});return true;},gemObjectFaultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var type=event[2];var index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,type:type,index:index});return true;},gemObjectDestroyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj});return true;},gemRingDispatchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingFlushEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var invalidate=event[3];var flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,invalidate:invalidate,flush:flush});return true;},gemRequestEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring});return true;},regRWEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)
-return false;var rw=event[1];var reg=event[2];var len=event[3];var data=event[3];this.i915RegSlice(ts,rw,reg,{rw:rw,reg:reg,len:len,data:data});return true;},flipEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)
-return false;var plane=parseInt(event[1]);var obj=event[2];if(eventName=='i915_flip_request')
-this.i915FlipOpenSlice(ts,obj,plane);else
-this.i915FlipCloseSlice(ts,{obj:obj,plane:plane});return true;},gpuFrequency:function(eventName,cpuNumver,pid,ts,eventBase){var event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)
-return false;var freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq:freq});return true;}};Parser.register(I915Parser);return{I915Parser:I915Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
-var irqHandlerEntryRE=/irq=(\d+) name=(.+)/;var irqHandlerExitRE=/irq=(\d+) ret=(.+)/;var softirqRE=/vec=(\d+) \[action=(.+)\]/;var ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerEntryRE.exec(eventBase.details);if(!event)
-return false;var irq=parseInt(event[1]);var name=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerExitRE.exec(eventBase.details);if(!event)
-return false;var irq=parseInt(event[1]);var ret=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret:ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent:function(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
-return false;var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
-return false;var vec=parseInt(event[1]);var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec:vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;},ipiEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=ipiHandlerExitRE.exec(eventBase.details);if(!event)
-return false;var ipiName=event[1];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser:IrqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-var TestExports={};var funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=funcEnterRE.exec(eventBase.details);if(!eventData)
-return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var name=eventData[1];var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-if(slices.openSliceCount>0){slices.endSlice(ts);}
-return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser:KernelFuncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(var i=0;i<7;i++){var jobStr='JS'+i;var jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
-this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
-MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice:function(pid,tid,ts,func,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);var funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],'blockinfo':blockinfo});},maliDDKCloseSlice:function(pid,tid,ts,args,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
-thread.sliceGroup.endSlice(ts);},autoDetectLineRE:function(line){var lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line))
-return lineREWithThread;var lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line))
-return lineRENoThread;return null;},lineRE:null,maliDDKEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE==null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE==null)
-return false;}
-var maliEvent=this.lineRE.exec(eventBase.details);var tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
-return true;},dvfsSample:function(counterName,seriesName,ts,s){var value=parseInt(s);var counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/utilization=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/voltage=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample:function(cat,counterName,seriesName,ts,eventBase){var event=/val=(\d+)/.exec(eventBase.details);if(!event)
-return false;var value=parseInt(event[1]);var counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser:MaliParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
-var kswapdWakeRE=/nid=(\d+) order=(\d+)/;var kswapdSleepRE=/nid=(\d+)/;var reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;var reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake:function(eventName,cpuNumber,pid,ts,eventBase){var event=kswapdWakeRE.exec(eventBase.details);if(!event)
-return false;var tgid=parseInt(eventBase.tgid);var nid=parseInt(event[1]);var order=parseInt(event[2]);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
-return true;},kswapdSleep:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
-kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)
-return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)
-return false;var nr_reclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nr_reclaimed});}
-kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
-PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
-powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
-var val=(cpuState!=4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice:function(ts,targetCpuNumber,minFreq,maxFreq){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
-powerCounter.series.forEach(function(series){if(series.name=='Min Frequency')
-series.addCounterSample(ts,minFreq);if(series.name=='Max Frequency')
-series.addCounterSample(ts,maxFreq);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent:function(eventName,cpu,pid,ts,eventBase){var event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var minFreq=parseInt(event[1]);var maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser:PowerParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
-var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
-return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
-var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');var schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
-return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread)
-nextName=nextThread.userFriendlyName;else
-nextName=nextComm;var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)
-return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)
-return false;var cpuNumber=event[1];var state=event[2];var targetCpu=this.importer.getOrCreateCpu(cpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
-powerCounter.series.forEach(function(series){if(series.name=='State')
-series.addCounterSample(ts,state.localeCompare('offline')?0:1);});return true;},schedBlockedEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedBlockedRE.exec(eventBase.details);if(!event)
-return false;var pid=parseInt(event[1]);var iowait=parseInt(event[2]);var caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
-var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)
-return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value==undefined)
-value=' ';var slice=new tr.model.Slice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncWaitRE.exec(eventBase.details);if(!event)
-return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var name='fence_wait("'+event[2]+'")';if(event[1]=='begin'){var slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]=='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
-return true;},syncPtEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncPtRE.exec(eventBase.details);if(!event)
-return false;return true;var thread=this.importer.getOrCreateKernelThread(eventBase[1]).thread;thread.syncWaitSyncPts[event[1]]=event[2];return true;}};Parser.register(SyncParser);return{SyncParser:SyncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
-var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)
-return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)
-return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var InstantClockSyncRecord=tr.model.InstantClockSyncRecord;function FTraceImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.blocked_reasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
-var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
-var tgid=groups[3];if(tgid[0]==='-')
-tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;var lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;var lineParserWithLegacyFmt=function(line){var groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;var traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;var realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;var genericClockSyncRE=/trace_event_clock_sync: name=(\w+)/;var pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]=='{')
-return false;if(lineREWithTGID.test(line))
-return lineParserWithTGID;if(lineREWithIRQInfo.test(line))
-return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))
-return lineParserWithLegacyFmt;return undefined;};TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok)
-return true;if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
-return true;if(/^# tracer:/.test(events))
-return true;var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)
-events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))
-return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
-produce_result=true;if(/^<!DOCTYPE html>/.test(incoming_events)==false)
-return failure;var r=new tr.importer.SimpleLineReader(incoming_events);if(!r.advanceToLineMatching(/^  <script>$/))
-return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))
-return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
-return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))
-return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
-return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
-function stripSuffix(str,suffix){if(!endsWith(str,suffix))
-return str;return str.substring(str,str.length-suffix.length);}
-var events=[];if(produce_result){for(var i=0;i<raw_events.length;i++){var event=raw_events[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[raw_events[raw_events.length-1]];}
-var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent==oldLastEvent)
-return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
-produce_result=true;if(new RegExp('^<!DOCTYPE HTML>','i').test(incoming_events)==false)
-return failure;var r=new tr.importer.SimpleLineReader(incoming_events);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/))
-return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
-return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
-if(!r.advanceToLineMatching(/^<\/body>$/))
-return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
-return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importEvents:function(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();this.importClockSyncRecords_();var modelTimeTransformer=this.getModelTimeTransformer_();if(modelTimeTransformer===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
-this.shiftNewlyAddedClockSyncRecords_(modelTimeTransformer);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
-return thread;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},addPidBlockedReason:function(ts,pid,iowait,caller){this.blocked_reasons_.push({ts:ts,tid:pid,iowait:iowait,caller:caller});},buildMapFromLinuxPidsToThreads_:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
-continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices)
-thread.tempCpuSlices=[];thread.tempCpuSlices.push(cpuSlice);}}
-for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)
-continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
-for(var i in this.blocked_reasons_){var reason=this.blocked_reasons_[i];var thread=this.threadsByLinuxPid[reason.tid];if(!thread)
-continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
-this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)
-return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
-var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
-var blocked_reason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){var r=reasons.shift();}
-if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blocked_reason=reasons.shift();}
-var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
-if(blocked_reason!==undefined){var args={'kernel callsite when blocked:':blocked_reason.caller};if(blocked_reason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
-slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,args,midDuration));}else{slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));}
-if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
-prevSlice.args.stateWhenDescheduled});}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
-thread.timeSlices=slices;},this);},getModelTimeTransformer_:function(){var isAttachedToChromeTrace=this.model.getClockSyncRecordsWithSyncId('ftrace_importer').length!==0;var monotonicSyncs=this.model_.getClockSyncRecordsWithSyncId('ftrace_global_to_monotonic');if(monotonicSyncs.length==0)
-return isAttachedToChromeTrace?undefined:tr.b.identity;var ftraceGlobalTs=monotonicSyncs[0].start;var monotonicTs=monotonicSyncs[0].args.monotonicTs;if(monotonicTs===0)
-return tr.b.identity;return function(ts){return ts+monotonicTs-ftraceGlobalTs;};},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTs:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
-throw new Error('omgbbq');args[parts[0]]=parts[1];}
-this.addClockSyncRecord_(new InstantClockSyncRecord(name,ts,args));return true;}
-event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)
-return false;var monotonicTs=event[1]*1000;this.addClockSyncRecord_(new InstantClockSyncRecord('ftrace_global_to_monotonic',ts,{monotonicTs:monotonicTs}));return true;},traceMarkingWriteEvent_:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
-var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
-return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords_:function(){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
-return;if(traceEventClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
-if(genericClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord_:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords_:function(modelTimeTransformer){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.start=modelTimeTransformer(csr.start);});},importCpuData_:function(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
-ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_:function(){var lines=[];var extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
-extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=undefined;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
-continue;if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
-var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
-this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine_:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter:FTraceImporter,_FTraceImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
-return false;if(title===maxTitle)
-return true;if(precision<=maxPrecision){if(precision===maxPrecision){console.warn('Encountered two different VSync events ('+
-maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')');}
-return false;}
-maxPrecision=precision;maxTitle=title;times=[];return true;}
-for(var pid in model.processes){var process=model.processes[pid];for(var cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){var counter=process.counters[cid];for(var i=0;i<counter.series.length;i++){var series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
-for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS))
-times.push(slice.start);else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us)
-times.push(slice.args.args.frame_time_us/1000.0);}}}
-times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
-return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
-return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
-AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_)
-return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS)
-this.frameEvents_.push(event);},this);return this.frameEvents_;}};tr.model.um.UserExpectation.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation:AnimationExpectation};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
-ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
-return true;}
-return false;},containsSliceTitle:function(title){for(var i=0;i<this.associatedEvents.length;++i){if(title===this.associatedEvents[i].title)
-return true;}
-return false;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoExpectation: '+this.debug()+' File a bug with this trace!');return undefined;}
-var initiatorTitles=[];this.names.forEach(function(name){initiatorTitles.push(name);});initiatorTitles=initiatorTitles.sort().join(',');var duration=this.end-this.start;var ir=undefined;switch(this.irType){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,initiatorTitles,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,initiatorTitles,this.start,duration);break;}
-if(!ir)
-return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
-ir.associatedEvents.addEventSet(event.associatedEvents);}
-this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices)
-event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin)
-this.isAnimationBegin=true;},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation:ProtoExpectation};});'use strict';tr.exportTo('tr.importer',function(){var ProtoExpectation=tr.importer.ProtoExpectation;var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=32;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function compareEvents(x,y){if(x.start!==y.start)
-return x.start-y.start;if(x.end!==y.end)
-return x.end-y.end;if(x.guid&&y.guid)
-return x.guid-y.guid;return 0;}
-function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
-function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.model.helpers.IMPL_RENDERING_STATS)
-return true;}
-return false;}
-function getSortedInputEvents(modelHelper){var inputEvents=[];var browserProcess=modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
-return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
-return;inputEvents.push(slice);});return inputEvents.sort(compareEvents);}
-function findProtoExpectations(modelHelper,sortedInputEvents){var protoExpectations=[];var handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents));});protoExpectations.sort(compareEvents);return protoExpectations;}
-function handleKeyboardEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,KEYBOARD_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseWheelEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-return;}
-currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
-function handleMouseDragEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
-break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
-protoExpectations.push(currentPE);}else{if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
-break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
-currentPE.associatedEvents.push(mouseDownEvent);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-mouseDownEvent=undefined;currentPE=undefined;break;}});if(mouseDownEvent){currentPE=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);currentPE.pushEvent(mouseDownEvent);protoExpectations.push(currentPE);}
-return protoExpectations;}
-function handleTapResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-currentPE=undefined;break;}});return protoExpectations;}
-function handlePinchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;var modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
-currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.irType===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
-break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
-currentPE=undefined;break;}});return protoExpectations;}
-function handleFlingEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
-var browserHelper=modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-return;}
-switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){console.error('Another FlingStart? File a bug with this trace!');currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
-break;}});if(currentPE&&!currentPE.end)
-currentPE.end=modelHelper.model.bounds.max;return protoExpectations;}
-function handleTouchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
-break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
-if((sawFirstMove&&(currentPE.irType===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
-break;case INPUT_TYPE.TOUCH_END:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
-currentPE=undefined;break;}});return protoExpectations;}
-function handleScrollEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.irType===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.SCROLL_END:if(!currentPE){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-currentPE.pushEvent(event);break;}});return protoExpectations;}
-function handleCSSAnimations(modelHelper,sortedInputEvents){var animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});var framesForProcess={};function getFramesForAnimationProcess(animation){var frames=framesForProcess[animation.parentContainer.parent.guid];if(frames===undefined){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(modelHelper,animation.parentContainer.parent);frames=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);framesForProcess[animation.parentContainer.parent.guid]=frames;}
-return frames;}
-var animationRanges=[];function pushAnimationRange(start,end,animation){var range=tr.b.Range.fromExplicitRange(start,end);range.animation=animation;range.frames=range.filterArray(getFramesForAnimationProcess(animation),function(frameEvent){return frameEvent.start;});if(range.frames.length===0)
-return;animationRanges.push(range);}
-animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{var start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.state==='paused')||(sub.args.state==='idle')||(sub.args.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
-pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined)
-pushAnimationRange(start,modelHelper.model.bounds.max,animation);}});function merge(ranges){var protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoExpectation.start=Math.min(protoExpectation.start,range.min);protoExpectation.end=Math.max(protoExpectation.end,range.max);protoExpectation.associatedEvents.push(range.animation);protoExpectation.associatedEvents.addEventSet(range.frames);});return protoExpectation;}
-return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);}
-function postProcessProtoExpectations(protoExpectations){protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
-function mergeIntersectingResponses(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.RESPONSE_TYPE)
-continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
-continue;if(!otherPE.intersects(pe))
-continue;var typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))
-continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
-return newPEs;}
-function mergeIntersectingAnimations(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.ANIMATION_TYPE)
-continue;var isCSS=pe.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
-continue;if(isCSS!=otherPE.containsSliceTitle(CSS_ANIMATION_TITLE))
-continue;if(!otherPE.intersects(pe))
-continue;if(isFling!=otherPE.containsTypeNames([INPUT_TYPE.FLING_START]))
-continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
-return newPEs;}
-function fixResponseAnimationStarts(protoExpectations){protoExpectations.forEach(function(ape){if(ape.irType!==ProtoExpectation.ANIMATION_TYPE)
-return;protoExpectations.forEach(function(rpe){if(rpe.irType!==ProtoExpectation.RESPONSE_TYPE)
-return;if(!ape.containsTimestampInclusive(rpe.end))
-return;if(ape.containsTimestampInclusive(rpe.start))
-return;ape.start=rpe.end;});});return protoExpectations;}
-function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.irType===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
-function isTouchAnimation(pe){return(pe.irType===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
-var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);var peIsTapResponse=isTapResponse(pe);var peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation)
-continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(!otherPE.intersects(pe))
-continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))
-continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))
-continue;pe.irType=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
-return newPEs;}
-function checkAllInputEventsHandled(sortedInputEvents,protoExpectations){var handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0))
-return;if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoExpectation);return;}
-handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}
-function findInputExpectations(modelHelper){var sortedInputEvents=getSortedInputEvents(modelHelper);var protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents);protoExpectations=postProcessProtoExpectations(protoExpectations);checkAllInputEventsHandled(sortedInputEvents,protoExpectations);var irs=[];protoExpectations.forEach(function(protoExpectation){var ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir)
-irs.push(ir);});return irs;}
-return{findInputExpectations:findInputExpectations,compareEvents:compareEvents,CSS_ANIMATION_TITLE:CSS_ANIMATION_TITLE};});'use strict';tr.exportTo('tr.model.um',function(){var LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',STARTUP:'Startup'};var DOES_LOAD_SUBTYPE_NAME_EXIST={};for(var key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;;}
-function LoadExpectation(parentModel,initiatorTitle,start,duration){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle])
-throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=undefined;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;}
-LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES:LOAD_SUBTYPE_NAMES,LoadExpectation:LoadExpectation};});'use strict';tr.exportTo('tr.importer',function(){var NAVIGATION_START='NavigationTiming navigationStart';var FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function getAllFrameEvents(modelHelper){var frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));tr.b.iterItems(modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));});return frameEvents.sort(tr.importer.compareEvents);}
-function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
-var events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
-deduper.push(slice);});return deduper.toArray();}
-function findLoadExpectationsInternal(modelHelper,subtypeName,openingEvents,closingEvents){var loads=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
-return;if(closingEvent.openingEvent)
-return;if(closingEvent.start<=openingEvent.start)
-return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
-return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.model.um.LoadExpectation(modelHelper.model,subtypeName,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);loads.push(lir);});});return loads;}
-function findRenderLoadExpectations(modelHelper){var events=[];modelHelper.model.iterateAllEvents(function(event){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE))
-events.push(event);});events.sort(tr.importer.compareEvents);var loads=[];var startEvent=undefined;events.forEach(function(event){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}});if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,modelHelper.model.bounds.max-startEvent.start));}
-return loads;}
-function findLoadExpectations(modelHelper){var loads=[];var commitLoadEvents=modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(modelHelper.model.bounds);var startupEvents=getStartupEvents(modelHelper);var frameEvents=getAllFrameEvents(modelHelper);var startupLoads=findLoadExpectationsInternal(modelHelper,tr.model.um.LOAD_SUBTYPE_NAMES.STARTUP,startupEvents,frameEvents);loads.push.apply(loads,startupLoads);loads.push.apply(loads,findRenderLoadExpectations(modelHelper));return loads;}
-return{findLoadExpectations:findLoadExpectations};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
-return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
-function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();model.getAllProcesses().forEach(function(process){for(var tid in process.threads){var thread=process.threads[tid];thread.sliceGroup.iterateAllEvents(function(event){if(!associatedEvents.contains(event))
-unassociatedEvents.push(event);});}});return unassociatedEvents;}
-function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime)
-cpuMs+=event.cpuSelfTime;});return cpuMs;}
-function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)
-return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;var coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0)
-coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:coveredEventsCpuTimeRatio};}
-return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){var initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
-IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation:IdleExpectation};});'use strict';tr.exportTo('tr.importer',function(){var INSIGNIFICANT_MS=1;function UserModelBuilder(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);};UserModelBuilder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};UserModelBuilder.prototype={buildUserModel:function(){if(!this.modelHelper||!this.modelHelper.browserHelper)
-return;var expectations=undefined;try{expectations=this.findUserExpectations();}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});return;}
-expectations.forEach(function(expectation){this.model.userModel.expectations.push(expectation);},this);},findUserExpectations:function(){var expectations=[];expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.model.um.LoadExpectation||ir instanceof tr.model.um.IdleExpectation)
-vacuumIRs.push(ir);});if(vacuumIRs.length===0)
-return;var allAssociatedEvents=tr.model.getAssociatedEvents(rirs);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);unassociatedEvents.forEach(function(event){if(!(event instanceof tr.model.ThreadSlice))
-return;if(!event.isTopLevel)
-return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleExpectations:function(otherIRs){if(this.model.bounds.isEmpty)
-return;var emptyRanges=tr.b.findEmptyRangesBetweenRanges(tr.b.convertEventsToRanges(otherIRs),this.model.bounds);var irs=[];var model=this.model;emptyRanges.forEach(function(range){if(range.max<(range.min+INSIGNIFICANT_MS))
-return;irs.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));});return irs;}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
-var modelEvents=new tr.model.EventSet();model.userModel.expectations.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
-typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
-modelLines.push('          {'+startAndEnd);});modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
-function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.userModel.expectations.length;model.userModel.expectations.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
-irString+=',';expectedLines.push(irString);});return expectedLines;}
-function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
-return{UserModelBuilder:UserModelBuilder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.importer',function(){var Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
-function Import(model,opt_options){if(model===undefined)
-throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
-Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
-throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;};overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
-throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.timedAfter('TraceImport',function createImports(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
-importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
-if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
-importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.timedAfter('TraceImport',function importClockSyncMarkers(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportClockSyncMarkersOnOneImporter(){progressMeter.update('Importing clock sync markers '+(index+1)+' of '+
-importers.length);importer.importClockSyncMarkers();}),this);},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runImport(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportEventsOnOneImporter(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();}),this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.timedAfter('TraceImport',function runCustomizeCallbacks(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
-lastTask=lastTask.timedAfter('TraceImport',function importSampleData(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runAutoclosers(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeImport(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runPreinits(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.timedAfter('TraceImport',function runPruneEmptyContainers(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
-lastTask=lastTask.timedAfter('TraceImport',function runMergeKernelWithuserland(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.timedAfter('TraceImport',function createAuditorsAndRunAnnotate(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});},this);lastTask=lastTask.timedAfter('TraceImport',function computeWorldBounds(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.timedAfter('TraceImport',function buildFlowEventIntervalTree(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.timedAfter('TraceImport',function joinRefs(){progressMeter.update('Joining object refs...');this.model_.joinRefs();},this);lastTask=lastTask.timedAfter('TraceImport',function cleanupUndeletedObjects(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function sortMemoryDumps(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeMemoryGraphs(){progressMeter.update('Finalizing memory dump graphs...');this.model_.finalizeMemoryGraphs();},this);lastTask=lastTask.timedAfter('TraceImport',function initializeObjects(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function buildEventIndices(){progressMeter.update('Building event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.timedAfter('TraceImport',function buildUserModel(){progressMeter.update('Building UserModel...');var userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();},this);lastTask=lastTask.timedAfter('TraceImport',function sortExpectations(){progressMeter.update('Sorting user expectations...');this.model_.userModel.sortExpectations();},this);lastTask=lastTask.timedAfter('TraceImport',function runAudits(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.timedAfter('TraceImport',function sortAlerts(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.timedAfter('TraceImport',function lastUpdateBounds(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask=lastTask.timedAfter('TraceImport',function addModelWarnings(){progressMeter.update('Looking for warnings...');if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:false});}},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
-return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
-return true;}
-return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
-return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
-var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
-for(var i=1;i<words.length;i++)
-words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
-function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
-function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
-function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
-function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
-function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-continue;if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
-function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
-function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++)
-preInitializeObjectInner(object[i],true);return;}
-if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
-return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
-if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
-object[key]=q;continue;}
-if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
-object[key]=r;}
-preInitializeObjectInner(object[key],true);}}
-function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
-return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
-Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
-console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
-console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
-var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
-LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
-return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
-return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
-ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
-return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
-this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
-this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
-PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
-PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.rasterize)
-return false;return true;}
-PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOps)
-return false;return true;}
-PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
-return false;return true;}
-PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getInfo)
-return false;return true;}
-PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
-return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
-return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
-return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
-return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
-return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
-return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
-PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
-this.args=this.args.alias.args;if(!this.args.params.layerRect)
-throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
-DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
-DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
-Region.fromArray=function(array){if(array.length%4!=0)
-throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
-return r;}
-Region.fromArrayOrUndefined=function(array){if(array===undefined)
-return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
-return true;}
-return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
-return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
-for(var i=0;i<this.children.length;i++)
-this.children[i].parentLayer=this;if(this.maskLayer)
-this.maskLayer.parentLayer=this;if(this.replicaLayer)
-this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
-this.geometryContentsScale=1.0;if(!this.idealContentsScale)
-this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
-return this.layerTreeImpl_;if(this.parentLayer)
-return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
-return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
-return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
-PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
-if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
-delete this.args.annotatedInvalidationRects;}
-if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
-if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
-this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
-delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
-this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper)
-this._initializeTracedInputLatencies(modelHelper);}},_initializeTracedInputLatencies:function(modelHelper){var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
-continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
-this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
-return false;if(this.sourceFrameNumber===undefined)
-return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
-return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
-return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
-return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
-totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
-return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
-visitLayer(layer.children[i],depth+1);}
-if(layer.maskLayer)
-visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
-visitLayer(layer.replicaLayer,depth+1,false,true);}
-visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
-foundLayer=layer;}
-this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
-return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
-return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
-return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
-return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
-if(!this.activeTiles)
-this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
-return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
-return this.activeTree;if(whichTree==constants.PENDING_TREE)
-return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
-return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
-continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
-this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
-return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
-usage+=u;}
-return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
-frameNumber=this.objectInstance.snapshots.indexOf(this);else
-frameNumber=this.activeTree.sourceFrameNumber;}
-return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
-LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
-return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
-this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
-return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
-this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
-handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
-TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
-if(this.contentRect)
-this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
-this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
-this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.lowRes;else
-this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraHighRes;}
-return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
-BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_))
-return false;if(!this.findMatches_.equals(that.findMatches_))
-return false;if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
-if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
-return true;},get selectionOfInterest(){if(this.selection_.length)
-return this.selection_;if(this.highlight_.length)
-return this.highlight_;if(this.analysisViewRelatedEvents_.length)
-return this.analysisViewRelatedEvents_;if(this.analysisLinkHoveredEvents_.length)
-return this.analysisLinkHoveredEvents_;return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(selection===undefined)
-selection=new EventSet();this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(findMatches===undefined)
-findMatches=new EventSet();this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(analysisViewRelatedEvents===undefined)
-analysisViewRelatedEvents=new EventSet();this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(analysisLinkHoveredEvents===undefined)
-analysisLinkHoveredEvents=new EventSet();this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get causesDimming_(){return this.findMatches_.length>0||this.analysisViewRelatedEvents_.length>0;},get brightenedEvents_(){var brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToModelSelectionState:function(model){this.appliedToModel_=model;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){var score;score=0;if(this.selection_.contains(e))
-score++;if(this.analysisLinkHoveredEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);},this);return;}
-var brightenedEvents=this.brightenedEvents_;model.iterateAllEvents(function(e){var score;if(brightenedEvents.contains(e)){score=0;if(this.selection_.contains(e))
-score++;if(this.analysisLinkHoveredEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);}else{score=0;if(this.findMatches_.contains(e))
-score++;if(this.analysisViewRelatedEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromDimmingLevel(score);}}.bind(this));},transferModelOwnershipToClone:function(that){if(!this.appliedToModel_)
-throw new Error('Not applied');that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromModelSelectionState:function(){if(!this.appliedToModel_)
-throw new Error('Not applied');var model=this.appliedToModel_;this.appliedToModel_=undefined;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){e.selectionState=SelectionState.NONE;});return;}
-model.iterateAllEvents(function(e){e.selectionState=SelectionState.NONE;});}};return{BrushingState:BrushingState};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
-Animation.prototype={canTakeOverFor:function(existingAnimation){throw new Error('Not implemented');},takeOverFor:function(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start:function(timestamp,target){throw new Error('Not implemented');},didStopEarly:function(timestamp,target,willBeTakenOverByAnotherAnimation){},tick:function(timestamp,target){throw new Error('Not implemented');}};return{Animation:Animation};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
-AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_)
-throw new Error('Cannot change target while animation is running.');if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function')
-throw new Error('target must have a cloneAnimationState function');this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation:function(animation,opt_now){if(this.target_===undefined)
-throw new Error('Cannot queue animations without a target');var now;if(opt_now!==undefined)
-now=opt_now;else
-now=window.performance.now();if(this.activeAnimation_){var done=this.activeAnimation_.tick(now,this.target_);if(done)
-this.activeAnimation_=undefined;}
-if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
-this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)
-return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation:function(opt_now){if(!this.activeAnimation_)
-return;var now;if(opt_now!==undefined)
-now=opt_now;else
-now=window.performance.now();this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_:function(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)
-return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
-var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done)
-this.activeAnimation_=undefined;if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
-if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
-Settings.setAlternativeStorageInstance(new HeadlessStorage());else
-Settings.setAlternativeStorageInstance(global.sessionStorage);});}
-function SessionSettings(){return SessionSettings;}
-function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
-return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
-throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
-result.push(input_class.unnamespace_(key,opt_namespace));}
-return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
-return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
-HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
-return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
-itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
-return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
-return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
-this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
-return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
-ownerDocument=opt_dictionary.ownerDocument;var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className)
-spanEl.className=opt_dictionary.className;if(opt_dictionary.textContent)
-spanEl.textContent=opt_dictionary.textContent;if(opt_dictionary.tooltip)
-spanEl.title=opt_dictionary.tooltip;if(opt_dictionary.parent)
-opt_dictionary.parent.appendChild(spanEl);if(opt_dictionary.bold)
-spanEl.style.fontWeight='bold';if(opt_dictionary.italic)
-spanEl.style.fontStyle='italic';if(opt_dictionary.marginLeft)
-spanEl.style.marginLeft=opt_dictionary.marginLeft;if(opt_dictionary.marginRight)
-spanEl.style.marginRight=opt_dictionary.marginRight;if(opt_dictionary.backgroundColor)
-spanEl.style.backgroundColor=opt_dictionary.backgroundColor;if(opt_dictionary.color)
-spanEl.style.color=opt_dictionary.color;}
-return spanEl;};function createDiv(opt_dictionary){var divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className)
-divEl.className=opt_dictionary.className;if(opt_dictionary.parent)
-opt_dictionary.parent.appendChild(divEl);if(opt_dictionary.textContent)
-divEl.textContent=opt_dictionary.textContent;if(opt_dictionary.maxWidth)
-divEl.style.maxWidth=opt_dictionary.maxWidth;}
-return divEl;};function createScopedStyle(styleContent){var styleEl=document.createElement('style');styleEl.scoped=true;styleEl.innerHTML=styleContent;return styleEl;}
-function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array)
-return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);return a===b;}
-function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){var defaultValueIndex;for(var i=0;i<items.length;i++){var item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
-if(defaultValueIndex===undefined)
-throw new Error('defaultValue must be in the items list');var selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');optionEl.textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;selectorEl.appendChild(optionEl);}
-function onChange(e){var value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
-var oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){var changed=selectorEl.selectedIndex!=i;if(changed){selectorEl.selectedIndex=i;onChange();}
-return;}}
-throw new Error('Not a valid value');});var initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);var didSet=false;for(var i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
-if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
-return selectorEl;}
-function createEditCategorySpan(optionGroupEl,targetEl){var spanEl=createSpan({className:'edit-categories'});spanEl.textContent='Edit categories';spanEl.classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
-function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){var value=[];if(this.value.length)
-value=this.value.split(',');tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
-var optionGroupEl=createSpan({className:'labeled-option-group'});var initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(var i=0;i<items.length;++i){var item=items[i];var id='category-preset-'+item.label.replace(/ /g,'-');var radioEl=document.createElement('input');radioEl.type='radio';radioEl.setAttribute('id',id);radioEl.setAttribute('name','category-presets-group');radioEl.setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value))
-radioEl.checked=true;var labelEl=document.createElement('label');labelEl.textContent=item.label;labelEl.setAttribute('for',id);var spanEl=createSpan({className:'labeled-option'});spanEl.appendChild(radioEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=radioEl.checked!==(!!opt_bool);if(!changed)
-return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});optionGroupEl.appendChild(spanEl);}
-optionGroupEl.appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length)
-optionGroupEl.classList.add('categories-expanded');targetEl[targetElProperty]=initialValue;return optionGroupEl;}
-var nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='checkbox';var initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;if(targetEl)
-targetEl[targetElProperty]=initialValue;function onChange(){tr.b.Settings.set(settingsKey,buttonEl.checked);if(targetEl)
-targetEl[targetElProperty]=buttonEl.checked;if(opt_changeCb)
-opt_changeCb.call();}
-buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});buttonEl.setAttribute('id',id);var labelEl=document.createElement('label');labelEl.textContent=label;labelEl.setAttribute('for',id);spanEl.appendChild(buttonEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)
-return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
-function createButton(targetEl,targetElProperty,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='button';function onClick(){if(opt_changeCb)
-opt_changeCb.call();}
-buttonEl.addEventListener('click',onClick);buttonEl.value=label;return buttonEl;}
-function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){var initialValue=tr.b.Settings.get(settingsKey,defaultValue);var el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
-el.addEventListener('input',onChange);el.value=initialValue;targetEl[targetElProperty]=initialValue;return el;}
-function isElementAttachedToDocument(el){var cur=el;while(cur.parentNode)
-cur=cur.parentNode;return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
-function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node)
-return value;var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
-return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,createButton:createButton,createTextInput:createTextInput,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
-return'rgb(60,60,60)';return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async)
-alpha*=0.3;return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter:EventPresenter};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict={};var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap={};}
-ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict[title];if(!elidedDict){elidedDict={};elidedTitleCacheDict[title]=elidedDict;}
-var elidedDictForPixWidth=elidedDict[pixWidth];if(!elidedDictForPixWidth){elidedDict[pixWidth]={};elidedDictForPixWidth=elidedDict[pixWidth];}
-var stringWidthPair=elidedDictForPixWidth[sliceDuration];if(stringWidthPair===undefined){var newtitle=title;var elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)
-break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
-if(elided&&newtitle.length>3)
-newtitle=newtitle.substring(0,newtitle.length-3)+'...';stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth[sliceDuration]=stringWidthPair;}
-return stringWidthPair;},quickMeasureText_:function(ctx,text){var w=this.textWidthMap[text];if(!w){w=ctx.measureText(text).width;this.textWidthMap[text]=w;}
-return w;},labelWidth:function(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld:function(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
-return{ElidedTitleCache:ElidedTitleCache};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCache=new tr.ui.b.ElidedTitleCache();var ColorScheme=tr.b.ColorScheme;var colorsAsStrings=ColorScheme.colorsAsStrings;var EventPresenter=tr.ui.b.EventPresenter;var blackColorId=ColorScheme.getColorIdForReservedName('black');var THIN_SLICE_HEIGHT=4;var SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;var SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;var SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
-function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
-function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){var dx=x2-x1;var dy=y2-y1;var len=Math.sqrt(dx*dx+dy*dy);var perc=(len-arrowLength)/len;var bx=x1+perc*dx;var by=y1+perc*dy;var ux=dx/len;var uy=dy/len;var ax=uy*arrowWidth;var ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
-function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);var height=viewHeight*pixelRatio;var darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight)
-darkRectHeight=0;var lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);var rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var hadTopLevel=false;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
-w=pixWidth;}
-var colorId=EventPresenter.getSliceColorId(slice);var alpha=EventPresenter.getSliceAlpha(slice,async);var lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
-if(!slice.cpuDuration){rect.fillRect(x,w,colorId,alpha);continue;}
-var activeWidth=w*(slice.cpuDuration/slice.duration);var waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
-if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=w;waitingWidth=0;}
-if(activeWidth>0){rect.fillRect(x,activeWidth,colorId,alpha);}
-if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,alpha);rect.setYandH(0,height);}}
-rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;if(!slice.isTopLevel)
-continue;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
-w=pixWidth;}
-rect.fillRect(x,w,blackColorId,0.7);}
-rect.flush();}
-ctx.restore();}
-function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
-ctx.restore();}
-function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async)
-ctx.font='italic '+ctx.font;var cY=yOffset*pixelRatio;var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var quickDiscardThresshold=pixWidth*20;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];if(slice.start>viewRWorld)
-break;if(slice.duration<=quickDiscardThresshold)
-continue;var title=slice.title+
-(slice.didNotFinish?' (Did Not Finish)':'');var drawnTitle=title;var drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);var fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){var elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
-if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);var cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
-ctx.restore();}
-return{drawSlices:drawSlices,drawInstantSlicesAsLines:drawInstantSlicesAsLines,drawLabels:drawLabels,drawLine:drawLine,drawTriangle:drawTriangle,drawArrow:drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT:THIN_SLICE_HEIGHT};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
-function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
-TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset:function(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set:function(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax:function(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject:function(){var range=new tr.b.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_==leftSelected)
-return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_==rightSelected)
-return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw:function(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)
-return;var dt=this.viewport_.currentDisplayTransform;var markerLWorld=this.min;var markerRWorld=this.max;var markerLView=Math.round(dt.xWorldToView(markerLWorld));var markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
-if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
-var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
-ctx.lineWidth=1;},drawLine_:function(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)
-return;var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected)
-ctx.strokeStyle='rgb(255, 0, 0)';else
-ctx.strokeStyle='rgb(0, 0, 0)';ctx.stroke();ctx.restore();},drawIndicators:function(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
-if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_:function(ctx,viewLWorld,viewRWorld,xWorld,si,selected){var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);var pixelRatio=window.devicePixelRatio||1;var viewY=si.y*devicePixelRatio;var viewHeight=si.height*devicePixelRatio;var arrowSize=4*pixelRatio;if(selected)
-ctx.fillStyle='rgb(255, 0, 0)';else
-ctx.fillStyle='rgb(0, 0, 0)';tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator:SnapIndicator,TimelineInterestRange:TimelineInterestRange};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
-this.scaleX=1;this.panX=0;this.panY=0;}
-TimelineDisplayTransform.prototype={set:function(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone:function(){return new TimelineDisplayTransform(this);},equals:function(that){var eq=true;if(that===undefined||that===null)
-return false;eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals:function(that){var eq=true;if(that===undefined||that===null)
-return false;eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits:function(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos:function(worldX,viewX,viewWidth){if(typeof viewX=='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
-this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView:function(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0)
-this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);else if(this.xWorldToView(worldMax)>viewWidth)
-this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);},xSetWorldBounds:function(worldMin,worldMax,viewWidth){var worldWidth=worldMax-worldMin;var scaleX=viewWidth/worldWidth;var panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale:function(p,s){this.scaleX=s;this.panX=p;},xWorldToView:function(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView:function(x){return x*this.scaleX;},xViewToWorld:function(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld:function(x){return x/this.scaleX;},applyTransformToCanvas:function(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform:TimelineDisplayTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
-ContainerToTrackMap.prototype={addContainer:function(container,track){if(!track)
-throw new Error('Must provide a track.');this.stableIdToTrackMap_[container.stableId]=track;},clear:function(){this.stableIdToTrackMap_={};},getTrackByStableId:function(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap:ContainerToTrackMap};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
-EventToTrackMap.prototype={addEvent:function(event,track){if(!track)
-throw new Error('Must provide a track.');this[event.guid]=track;}};return{EventToTrackMap:EventToTrackMap};});'use strict';tr.exportTo('tr.ui',function(){var TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;var TimelineInterestRange=tr.ui.TimelineInterestRange;function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.checkForAttachInterval_=setInterval(this.checkForAttach_.bind(this),250);this.majorMarkPositions=[];this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();}
-TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,setWhenPossible:function(fn){this.pendingSetFunction_=fn;},get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)
-return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_:function(){this.dispatchChangeEvent();},checkForAttach_:function(){if(!this.isAttachedToDocumentOrInTestMode||this.clientWidth==0)
-return;if(!this.iframe_){this.iframe_=document.createElement('iframe');this.iframe_.style.cssText='position:absolute;width:100%;height:0;border:0;visibility:hidden;';this.parentEl_.appendChild(this.iframe_);this.iframe_.contentWindow.addEventListener('resize',this.onResize_);}
-var curSize=this.parentEl_.clientWidth+'x'+
-this.parentEl_.clientHeight;if(this.pendingSetFunction_){this.lastSize_=curSize;try{this.pendingSetFunction_();}catch(ex){console.log('While running setWhenPossible:',ex.message?ex.message+'\n'+ex.stack:ex.stack);}
-this.pendingSetFunction_=undefined;}
-window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;},dispatchChangeEvent:function(){tr.b.dispatchSimpleEvent(this,'change');},detach:function(){if(this.checkForAttachInterval_){window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;}
-if(this.iframe_){this.iframe_.removeEventListener('resize',this.onResize_);this.parentEl_.removeChild(this.iframe_);}},initAnimationController_:function(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));var that=this;this.dtAnimationController_.target={get panX(){return that.currentDisplayTransform_.panX;},set panX(panX){that.currentDisplayTransform_.panX=panX;},get panY(){return that.currentDisplayTransform_.panY;},set panY(panY){that.currentDisplayTransform_.panY=panY;},get scaleX(){return that.currentDisplayTransform_.scaleX;},set scaleX(scaleX){that.currentDisplayTransform_.scaleX=scaleX;},cloneAnimationState:function(){return that.currentDisplayTransform_.clone();},xPanWorldPosToViewPos:function(xWorld,xView){that.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,that.modelTrackContainer_.canvas.clientWidth);}};},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately:function(displayTransform){this.dtAnimationController_.cancelActiveAnimation();var oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation:function(animation){if(!(animation instanceof tr.ui.b.Animation))
-throw new Error('animation must be instanceof tr.ui.b.Animation');this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_:function(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
-this.modelTrackContainer_.clientHeight);}
-var changed=!this.currentDisplayTransform.equals(oldDisplayTransform);var yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged)
-this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;if(changed)
-this.dispatchChangeEvent();},onModelTrackControllerScroll_:function(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY)
-this.dtAnimationController_.cancelActiveAnimation();var panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_)
-this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_==enabled)
-return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_==timebase)
-return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},drawMajorMarkLines:function(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(var idx in this.majorMarkPositions){var x=Math.floor(this.majorMarkPositions[idx]);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
-ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines:function(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)
-return;var dt=this.currentDisplayTransform;var x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){var vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
-x+=this.gridStep;}
-ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection:function(selection,offset){var newSelection=new tr.model.EventSet();for(var i=0;i<selection.length;i++){var event=selection[i];if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
-continue;}
-var track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
-if(newSelection.length==0)
-return undefined;return newSelection;},rebuildEventToTrackMap:function(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap:function(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent:function(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport:TimelineViewport};});'use strict';tr.exportTo('tr.ui.b',function(){var Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;};UIState.fromUserFriendlyString=function(model,viewport,stateString){var navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;var match=navByFinderPattern.exec(stateString);if(!match)
-return;var timestamp=parseFloat(match[1]);var stableId=match[3];var scaleX=parseFloat(match[4]);if(scaleX<=0)
-throw new Error('Invalid ScaleX value in UI State string.');if(!viewport.containerToTrackMap.getTrackByStableId(stableId))
-throw new Error('Invalid StableID given in UI State String.');var loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);}
-UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString:function(viewport){var timestamp=this.location_.xWorld;var stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;var scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict:function(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState:UIState};});'use strict';tr.exportTo('tr.c',function(){var BrushingState=tr.ui.b.BrushingState;var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;var Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
-BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_:function(){var e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_)
-return undefined;return this.timelineView_.model;},get trackView(){if(!this.timelineView_)
-return undefined;return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_)
-return undefined;if(!this.timelineView_.trackView)
-return undefined;return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled)
-window.addEventListener('popstate',this.onPopState_);else
-window.removeEventListener('popstate',this.onPopState_);},modelWillChange:function(){if(this.currentBrushingState_.isAppliedToModel)
-this.currentBrushingState_.unapplyFromModelSelectionState();},modelDidChange:function(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToModelSelectionState(this.model);var e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_:function(){var selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;var state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_:function(e){if(e.state===null)
-return;var selection=this.selections_[e.state.selection_guid];if(selection){var newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
-e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel)
-throw new Error('Cannot apply this state, it is applied');var hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
-this.currentBrushingState_=newBrushingState;return;}
-if(this.currentBrushingState_.isAppliedToModel)
-this.currentBrushingState_.unapplyFromModelSelectionState();this.currentBrushingState_=newBrushingState;if(this.model)
-this.currentBrushingState_.applyToModelSelectionState(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var timelineView=this.timelineView_.trackView;if(!timelineView)
-return new tr.b.Task();return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo:function(allPossibleMatches){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo:function(currentFocus){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared:function(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
-if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
-var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString:function(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition:function(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState:function(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState:function(viewId,newState){var oldStates=this.currentBrushingState_.viewSpecificBrushingStates;var newStates={};for(var id in oldStates)
-newStates[id]=oldStates[id];if(newState===undefined)
-delete newStates[viewId];else
-newStates[viewId]=newState;var newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless)
-throw new Error('Unsupported');var currentElement=element;while(currentElement){if(currentElement.brushingStateController)
-return currentElement.brushingStateController;if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
-var currentNode=currentElement;while(currentNode.parentNode)
-currentNode=currentNode.parentNode;currentElement=currentNode.host;}
-return undefined;};return{BrushingStateController:BrushingStateController};});'use strict';Polymer('tr-ui-a-analysis-link',{ready:function(){this.selection_=undefined;},attached:function(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached:function(){this.clearHighlight_();this.controller_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.textContent=selection.userFriendlyName;},setSelectionAndContent:function(selection,opt_textContent){this.selection_=selection;if(opt_textContent)
-this.textContent=opt_textContent;},getCurrentSelection_:function(){if(typeof this.selection_==='function')
-return this.selection_();return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_)
-this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(){if(!this.selection_)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
-this.scheduleRebuildBody_();},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons)
-columnsWithExpandButtons.push(i);}
-if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
-for(var i=0;i<columns.length;i++){var colInfo=columns[i];if(colInfo.width===undefined)
-continue;var hasExpandButton=columnsWithExpandButtons.indexOf(i)!==-1;var w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
-this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.sortColumnIndex=undefined;this.scheduleRebuildHeaders_();this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.maybeUpdateSelectedRow_();this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},set sortColumnIndex(number){if(number===this.sortColumnIndex_)
-return;if(number===undefined){this.sortColumnIndex_=undefined;this.updateHeaderArrows_();this.dispatchSortingChangedEvent_();return;}
-if(this.tableColumns_.length<=number)
-throw new Error('Column number '+number+' is out of bounds.');if(!this.tableColumns_[number].cmp)
-throw new Error('Column '+number+' does not have a comparator.');this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){if(!this.tableColumns_[i].cmp){this.headerCells_[i].sideContent='';continue;}
-if(i!==this.sortColumnIndex_){this.headerCells_[i].sideContent=UNSORTED_ARROW;continue;}
-this.headerCells_[i].sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;}},sortRows_:function(rows){rows.sort(function(rowA,rowB){if(this.sortDescending_)
-return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(this.getExpandedForUserRow_(rows[i]))
-this.sortRows_(rows[i][this.subRowsPropertyName_]);}},generateHeaderColumns_:function(){this.headerCells_=[];this.$.head.textContent='';if(!this.showHeader_)
-return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');if(this.showHeader)
-headerCell.cellTitle=this.tableColumns_[i].title;else
-headerCell.cellTitle='';if(this.tableColumns_[i].cmp){td.classList.add('sensitive');headerCell.tapCallback=this.createSortCallback_(i);if(this.sortColumnIndex_===i)
-headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;else
-headerCell.sideContent=UNSORTED_ARROW;}
-td.appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_:function(){if(this.tableRows_.length===0&&!this.showHeader)
-return;var rowToRemoveSizing;var rowToSize;if(this.showHeader){rowToSize=this.$.head.children[0];rowToRemoveSizing=this.$.body.children[0];}else{rowToSize=this.$.body.children[0];rowToRemoveSizing=this.$.head.children[0];}
-for(var i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&rowToRemoveSizing.children[i]){var tdToRemoveSizing=rowToRemoveSizing.children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
-var td=rowToSize.children[i];var delta;if(this.columnsWithExpandButtons_.indexOf(i)!==-1){td.style.paddingLeft=BASIC_INDENTATION+'px';delta=BASIC_INDENTATION+'px';}else{delta=undefined;}
-function calc(base,delta){if(delta)
-return'calc('+base+' - '+delta+')';else
-return base;}
-var w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_:function(columnNumber){return function(){var previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber)
-this.sortDescending=false;else
-this.sortDescending=!this.sortDescending;}.bind(this);},generateTableRowNodes_:function(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){var c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_)
-c=-c;return c;}.bind(this));}
-for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){tableSection.insertBefore(htmlNode,tableSection.firstChild);}else{var nextSiblingOfLastAdded=lastAddedRow.nextSibling;tableSection.insertBefore(htmlNode,nextSiblingOfLastAdded);}
-this.updateTabIndexForTableRowNode_(htmlNode);lastAddedRow=htmlNode;if(!rowInfo.isExpanded)
-continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
-return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){var rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow:userRow,htmlNode:undefined,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
-rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
-return;this.customizeTableRowCallback_(userRow,trElement);},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
-var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+BASIC_INDENTATION;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;if(column.textAlign){td.style.textAlign=column.textAlign;}
-if(this.doesColumnIndexSupportSelection(i))
-td.classList.add('supports-selection');if(this.columnsWithExpandButtons_.indexOf(i)!=-1){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';var expandButton=this.appendNewElement_(td,'expand-button');expandButton.textContent=RIGHT_ARROW;if(rowInfo.isExpanded)
-expandButton.classList.add('button-expanded');}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
-if(value!==undefined)
-td.appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));i+=colSpan;}
-var isSelectable=tableSection===this.$.body;var isExpandable=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;if(isSelectable||isExpandable){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
-function getTD(cur){if(cur===trElement)
-throw new Error('woah');if(cur.parentElement===trElement)
-return cur;return getTD(cur.parentElement);}
-if(isSelectable&&this.selectionMode_!==SelectionMode.NONE){var shouldSelect=false;var columnIndex=getTD(e.target).columnIndex;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(columnIndex)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==columnIndex;}
-break;default:throw new Error('Invalid selection mode '+
-this.selectionMode_);}
-if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,columnIndex);return;}}
-if(isExpandable){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this));}
-return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)
-continue;var subNode=subRowInfo.htmlNode;if(subNode&&subNode.parentNode===tableSection){tableSection.removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)
-return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_:function(){this.rebuild();},rebuild:function(){var wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
-if(this.bodyDirty_){this.$.body.textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){var trElement=this.ownerDocument.createElement('tr');this.$.body.appendChild(trElement);trElement.classList.add('empty-row');var td=this.ownerDocument.createElement('td');trElement.appendChild(td);td.colSpan=this.tableColumns_.length;var emptyValue=this.emptyValue_;td.appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
-this.bodyDirty_=false;}
-if(wasBodyOrHeaderDirty)
-this.applySizes_();if(this.footerDirty_){this.$.foot.textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){this.$.body.classList.add('has-footer');}else{this.$.body.classList.remove('has-footer');}
-this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);parent.appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},getExpandedForUserRow_:function(userRow){if(userRow[this.subRowsPropertyName_]===undefined)
-return false;if(userRow[this.subRowsPropertyName_].length===0)
-return false;if(userRow.isExpanded)
-return true;if(userRow.isExpanded===false)
-return false;if(this.defaultExpansionStateCallback_===undefined)
-return false;var parentUserRow=undefined;var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.parentRowInfo)
-parentUserRow=rowInfo.parentRowInfo.userRow;return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)
-return;if(rowInfo.htmlNode.parentElement!==tableSection)
-return;var expandButton=rowInfo.htmlNode.querySelector('expand-button');if(rowInfo.isExpanded){expandButton.classList.add('button-expanded');var lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{expandButton.classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
-this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!tr.b.dictionaryContainsValue(SelectionMode,selectionMode))
-throw new Error('Invalid selection mode '+selectionMode);this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,rowHighlightStyle))
-throw new Error('Invalid row highlight style '+rowHighlightStyle);this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT)
-return this.rowHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,cellHighlightStyle))
-throw new Error('Invalid cell highlight style '+cellHighlightStyle);this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT)
-return this.cellHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_:function(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:this.$.body.removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:this.$.body.setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:this.$.body.setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
-resolvedHighlightStyle);}},didSelectionStateChange_:function(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);for(var i=0;i<this.$.body.children.length;i++)
-this.updateTabIndexForTableRowNode_(this.$.body.children[i]);this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_:function(){if(this.selectedTableRowInfo_===undefined)
-return;if(this.selectionMode_===SelectionMode.NONE){this.removeSelectedState_();this.selectedTableRowInfo_=undefined;return;}
-function isVisible(rowInfo){if(!rowInfo.htmlNode)
-return false;return!!rowInfo.htmlNode.parentElement;}
-if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
-this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo))
-curRowInfo=curRowInfo.parentRowInfo;this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_)
-this.updateSelectedState_();},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex))
-return;if(this.selectedColumnIndex!==columnIndex)
-this.selectedColumnIndex=columnIndex;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
-this.selectedTableRow=rowInfo.userRow;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
-return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
-throw new Error('Selection is off.');var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo)
-throw new Error('Row has not been seen, must expand its parents.');}
-var e=this.prepareToChangeSelection_();this.selectedTableRowInfo_=rowInfo;if(this.selectedTableRowInfo_===undefined){this.selectedColumnIndex_=undefined;this.removeSelectedState_();}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i==-1)
-throw new Error('Cannot find a selectable column.');this.selectedColumnIndex_=i;}
-break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
-this.updateSelectedState_();}
-this.dispatchEvent(e);},updateTabIndexForTableRowNode_:function(row){if(this.selectionMode_===SelectionMode.ROW)
-row.tabIndex=0;else
-row.removeAttribute('tabIndex');var enableCellTab=this.selectionMode_===SelectionMode.CELL;for(var i=0;i<this.tableColumns_.length;i++){var cell=row.children[i];if(enableCellTab&&this.doesColumnIndexSupportSelection(i))
-cell.tabIndex=0;else
-cell.removeAttribute('tabIndex');}},prepareToChangeSelection_:function(){var e=new tr.b.Event('selection-changed');var previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo)
-e.previousSelectedTableRow=previousSelectedRowInfo.userRow;else
-e.previousSelectedTableRow=undefined;this.removeSelectedState_();return e;},removeSelectedState_:function(){this.setSelectedState_(false);},updateSelectedState_:function(){this.setSelectedState_(true);},setSelectedState_:function(select){if(this.selectedTableRowInfo_===undefined)
-return;var rowNode=this.selectedTableRowInfo_.htmlNode;if(select)
-rowNode.setAttribute('selected',true);else
-rowNode.removeAttribute('selected');var cellNode=rowNode.children[this.selectedColumnIndex_];if(!cellNode)
-return;if(select)
-cellNode.setAttribute('selected',true);else
-cellNode.removeAttribute('selected');},doesColumnIndexSupportSelection:function(columnIndex){var columnInfo=this.tableColumns_[columnIndex];var scs=columnInfo.supportsCellSelection;if(scs===false)
-return false;return true;},getFirstSelectableColumnIndex_:function(){for(var i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i))
-return i;}
-return-1;},getSelectableNodeGivenTableRowNode_:function(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return htmlNode.children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL)
-return undefined;return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
-throw new Error('Selection is off.');if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length)
-throw new Error('Invalid index');if(!this.doesColumnIndexSupportSelection(selectedColumnIndex))
-throw new Error('Selection is not supported on this column');var e=this.prepareToChangeSelection_();this.selectedColumnIndex_=selectedColumnIndex;if(this.selectedColumnIndex_===undefined)
-this.selectedTableRowInfo_=undefined;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)
-return;if(this.selectedTableRowInfo_===undefined)
-return;var code_to_command_names={13:'ENTER',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
-return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();var rowInfo=this.selectedTableRowInfo_;var htmlNode=rowInfo.htmlNode;if(cmdName==='ARROW_UP'){var prev=htmlNode.previousElementSibling;if(prev){tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;this.focusSelected_();return;}
-return;}
-if(cmdName==='ARROW_DOWN'){var next=htmlNode.nextElementSibling;if(next){tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;this.focusSelected_();return;}
-return;}
-if(cmdName==='ARROW_RIGHT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
-return;if(!rowInfo.isExpanded)
-this.setExpandedForTableRow(rowInfo.userRow,true);this.selectedTableRow=htmlNode.nextElementSibling.rowInfo.userRow;this.focusSelected_();return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_+1;if(newIndex>=this.tableColumns_.length)
-return;if(!this.doesColumnIndexSupportSelection(newIndex))
-return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
-if(cmdName==='ARROW_LEFT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.isExpanded){this.setExpandedForTableRow(rowInfo.userRow,false);this.focusSelected_();return;}
-var parentRowInfo=rowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;this.focusSelected_();return;}
-return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_-1;if(newIndex<0)
-return;if(!this.doesColumnIndexSupportSelection(newIndex))
-return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
-if(cmdName==='ENTER'){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
-return;this.setExpandedForTableRow(rowInfo.userRow,!rowInfo.isExpanded);this.focusSelected_();return;}
-throw new Error('Unrecognized command '+cmdName);},focusSelected_:function(){if(!this.selectedTableRowInfo_)
-return;var node=this.getSelectableNodeGivenTableRowNode_(this.selectedTableRowInfo_.htmlNode);node.focus();},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';Polymer('tr-ui-b-table-header-cell',{created:function(){this.tapCallback_=undefined;this.cellTitle_='';},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';this.$.title.appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},clearSideContent:function(){this.$.side.textContent='';},set sideContent(content){this.$.side.textContent=content;},get sideContent(){return this.$.side.textContent;},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_)
-this.tapCallback_();}});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
-return true;}
-if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
-return true;}
-for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
-return true;}}
-function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
-function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
-return false;foundElement=element;return true;}
-iterateElementDeeply(element,matches);return foundElement;}
-function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
-return false;}
-iterateElementDeeply(element,matches);return foundElements;}
-function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
-return false;return re.test(element.textContent);});}
-return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.ui.b',function(){function getPolymerElementNamed(tagName){for(var i=0;i<Polymer.elements.length;i++){if(Polymer.elements[i].name===tagName)
-return Polymer.elements[i];}}
-function getPolymerElementsThatSubclass(tagName){if(Polymer.waitingFor().length){throw new Error('There are unresolved polymer elements. '+'Wait until Polymer.whenReady');}
-var baseElement;var elementNamesThatExtend={};Polymer.elements.forEach(function(element){if(element.name===tagName)
-baseElement=element;if(element.extends){if(elementNamesThatExtend[element.extends]===undefined)
-elementNamesThatExtend[element.extends]=[];elementNamesThatExtend[element.extends].push(element.name);}});if(!baseElement)
-throw new Error(tagName+' is not a polymer element');var allFoundSubElementNames=[baseElement.name];for(var i=0;i<allFoundSubElementNames.length;i++){var elementName=allFoundSubElementNames[i];allFoundSubElementNames.push.apply(allFoundSubElementNames,elementNamesThatExtend[elementName]);}
-allFoundSubElementNames.shift();return allFoundSubElementNames;}
-return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)
-return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-v-ui-scalar-span');var numericValue;if(value instanceof tr.v.ScalarNumeric){span.value=value;numericValue=value.value;}else{var unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
-span.setValueAndUnit(value,unit);numericValue=value;}
-if(config.total)
-span.percentage=numericValue/config.total;if(config.rightAlign)
-span.rightAlign=true;return span;}
-tr.v.Unit.addEventListener('display-mode-changed',function(e){var scalarSpanTagName='tr-v-ui-scalar-span';var subclassNames=tr.ui.b.getPolymerElementsThatSubclass(scalarSpanTagName);subclassNames.push(scalarSpanTagName);var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-v-ui-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.v.ScalarNumeric){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
-this.updateContent_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContent_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContent_();},get percentage(){return this.percentage_;},set percentage(percentage){this.percentage_=percentage;this.updateSparkline_();},get rightAlign(){return this.$.content.classList.contains('right-align');},set rightAlign(rightAlign){if(rightAlign)
-this.$.content.classList.add('right-align');else
-this.$.content.classList.remove('right-align');},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';this.$.content.style.color='';return;}
-this.$.content.textContent=this.unit_.format(this.value);var BIGGER_IS_BETTER=tr.v.ImprovementDirection.BIGGER_IS_BETTER;var SMALLER_IS_BETTER=tr.v.ImprovementDirection.SMALLER_IS_BETTER;var color='';if(this.unit_.isDelta){var improvementDirection=this.unit_.improvementDirection;if(this.value>0){switch(improvementDirection){case BIGGER_IS_BETTER:color='green';break;case SMALLER_IS_BETTER:color='red';break;}}else if(this.value<0){switch(improvementDirection){case BIGGER_IS_BETTER:color='red';break;case SMALLER_IS_BETTER:color='green';break;}}}
-this.$.content.style.color=color;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
-for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!='number')return false;}
-if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
-return true;}
-Polymer('tr-ui-a-generic-object-view',{ready:function(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_:function(){this.$.content.textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_:function(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
-if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
-if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
-if(!(object instanceof Object)){var type=typeof object;if(type=='string'){var objectReplaced=false;if((object[0]=='{'&&object[object.length-1]=='}')||(object[0]=='['&&object[object.length-1]==']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
-if(!objectReplaced){if(object.indexOf('\n')!==-1){var lines=object.split('\n');lines.forEach(function(line,i){var text,ioff,ll,ss;if(i==0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
-var el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}else{this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
-else{}}else{return this.appendSimpleText_(label,indent,object,suffix);}}
-if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
-if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
-if(object instanceof tr.b.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
-if(object instanceof tr.v.ScalarNumeric){var el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
-if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
-this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length==0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
-if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];tr.b.iterItems(object[0],function(colName){columns.push({title:colName,value:function(row){return row[colName];}});});table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
-this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
-return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=tr.b.dictionaryKeys(object);if(keys.length==0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
-this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++)
-indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-b-drag-handle',{__proto__:HTMLDivElement.prototype,created:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
-return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_)
-this.className='horizontal-drag-handle';else
-this.className='vertical-drag-handle';},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length)
-this.didTargetMutate_(records);},didTargetMutate_:function(e){var modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
-this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
-var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
-this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)
-return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
-throw new Error('eventType must be given');if(dict.keyCode===undefined&&dict.keyCodes===undefined)
-throw new Error('keyCode or keyCodes must be given');if(dict.keyCode!==undefined&&dict.keyCodes!==undefined)
-throw new Error('Only keyCode or keyCodes can be given');if(dict.callback===undefined)
-throw new Error('callback must be given');this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode)
-this.pushKeyCode_(dict.keyCode);else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
-this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
-HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){this.isAttached_=true;var host=this.findHost_();if(host.__hotkeyController)
-throw new Error('Multiple hotkey controllers attached to this host');host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement)
-parentElement=host.parentElement;else
-parentElement=host.parentNode.host;var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
-host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){this.isAttached_=false;var host=this.curHost_;if(!host)
-return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
-host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1)
-throw new Error('Controller already registered');this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1)
-throw new Error('Controller not registered');this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_:function(eventType,useCapture){if(eventType==='keydown'){if(!useCapture)
-return this.bubblingKeyDownHotKeys_;else
-return this.capturingKeyDownHotKeys_;}else if(eventType==='keypress'){if(!useCapture)
-return this.bubblingKeyPressHotKeys_;else
-return this.capturingKeyPressHotKeys_;}else{throw new Error('Unsupported key event');}},addHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
-throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(keyMap[keyCode])
-throw new Error('Key is already bound for keyCode='+keyCode);}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
-return hotKey;},removeHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
-throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode])
-throw new Error('Key is not bound for keyCode='+keyCode);keyMap[keyCode]=hotKey;}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
-return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){var wasAttached=this.isAttached_;if(wasAttached)
-this.detached();this.globalMode_=!!globalMode;if(wasAttached)
-this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
-return this.slavedToParentController_.topmostConroller_;return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement)
-document.activeElement.blur();}}else{if(document.activeElement)
-document.activeElement.blur();}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_){return document.body;}else{if(this.parentElement)
-return this.parentElement;var node=this;while(node.parentNode){node=node.parentNode;}
-return node.host;}},appendMatchingHotKeysTo_:function(matchedHotKeys,useCapture,e){var localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);var localHotKey=localKeyMap[e.keyCode];if(localHotKey)
-matchedHotKeys.push(localHotKey);for(var i=0;i<this.childControllers_.length;i++){var controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_:function(useCapture,e){if(useCapture==false&&e.path[0].tagName=='INPUT')
-return;var sortedControllers;var matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)
-return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
-var hotKey=matchedHotKeys[0];var prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){var curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller')
-return curElement;if(curElement.__hotkeyController)
-return curElement.__hotkeyController;if(curElement.parentElement){curElement=curElement.parentElement;continue;}
-curElement=findHost(curElement);}
-return undefined;}
-function findHost(initialNode){var node=initialNode;while(node.parentNode){node=node.parentNode;}
-return node.host;}
-return{getHotkeyControllerForElement:getHotkeyControllerForElement};});'use strict';Polymer('tr-ui-b-info-bar',{ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';this.visible=false;},get message(){return this.messageEl_.textContent;},set message(message){this.messageEl_.textContent=message;},get visible(){return!this.classList.contains('info-bar-hidden');},set visible(visible){if(visible)
-this.classList.remove('info-bar-hidden');else
-this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
-throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
-HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
-this.decorateChild_(addedNodes[j]);}
-var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
-this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
-listView.selectedElement.removeAttribute('selected');if(value)
-this.setAttribute('selected','selected');else
-this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
-tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
-return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
-this.selectedElement.selected=false;return;}
-if(el.parentElement!=this)
-throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
-currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
-element=element.parentElement;if(element!==currentSelectedElement)
-element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
-return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
-MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
-this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
-this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
-return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
-opt_mouseUpHandler(e);}
-document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
-return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
-throw new Error('Unknown mode');this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_)
-this.classList.add('active');else
-this.classList.remove('active');this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)
-return;var mode=this.mode;if(mode===undefined)
-throw new Error('Invalid mode');var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo)
-throw new Error('Invalid mode');var title=modeInfo.title;if(this.acceleratorKey_)
-title=title+' ('+this.acceleratorKey_+')';this.title=title;var bp;if(this.active_)
-bp=modeInfo.activeBackgroundPosition;else
-bp=modeInfo.defaultBackgroundPosition;this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;var MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;var MIN_MOUSE_SELECTION_DISTANCE=4;var MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)
-return event.metaKey;else
-return event.ctrlKey;}
-Polymer('tr-ui-b-mouse-mode-selector',{__proto__:HTMLDivElement.prototype,created:function(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready:function(){this.buttonsEl_=this.shadowRoot.querySelector('.buttons');this.dragHandleEl_=this.shadowRoot.querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached:function(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached:function(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_)
-this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=target;if(this.targetElement_)
-this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)
-return;var mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined)
-mode=undefined;if((mode&this.supportedModeMask_)===0)
-mode=undefined;if(!mode)
-mode=this.defaultMode_;this.mode=mode;var pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)
-this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0)
-throw new Error('supportedModeMask must include current mode.');function createButtonForMode(mode){return button;}
-this.supportedModeMask_=supportedModeMask;this.buttonsEl_.textContent='';for(var modeName in MOUSE_SELECTOR_MODE){if(modeName=='ALL_MODES')
-continue;var mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)
-continue;var button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;button.classList.add('tool-button');this.buttonsEl_.appendChild(button);}},getButtonForMode_:function(mode){for(var i=0;i<this.buttonsEl_.children.length;i++){var buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode)
-return buttonEl;}
-return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number')
-throw new Error('Mode must be a number');if((newMode&this.supportedModeMask_)===0)
-throw new Error('Cannot switch to this mode, it is not supported');if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined)
-throw new Error('Unrecognized mode');}
-var modeInfo;if(this.currentMode_===newMode)
-return;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
-buttonEl.active=false;if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
-modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
-this.currentMode_=newMode;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
-buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_)
-tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
-if(this.settingsKey_&&!this.isInAlternativeMode_)
-tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);},setKeyCodeForMode:function(mode,keyCode){if((mode&this.supportedModeMask_)===0)
-throw new Error('Mode not supported');this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)
-return;var buttonEl=this.getButtonForMode_(mode);if(buttonEl)
-buttonEl.acceleratorKey=String.fromCharCode(keyCode);},setCurrentMousePosFromEvent_:function(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_:function(eventName,sourceEvent){var event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent)
-sourceEvent.preventDefault();};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_:function(e){if(e.button!==0)
-return;this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION)
-mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_:function(e){this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_)
-this.checkIsClick_(e);},onMouseUp_:function(e){if(e.button!==0)
-return;var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault)
-this.dispatchClickEvents_(e);this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_:function(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_:function(e){if(e.path[0].tagName=='INPUT')
-return;if(e.keyCode===' '.charCodeAt(0))
-this.spacePressed_=true;this.updateAlternativeModeState_(e);},onKeyUp_:function(e){if(e.path[0].tagName=='INPUT')
-return;if(e.keyCode===' '.charCodeAt(0))
-this.spacePressed_=false;var didHandleKey=false;tr.b.iterItems(this.modeToKeyCodeMap_,function(modeStr,keyCode){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;var mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}},this);if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
-this.updateAlternativeModeState_(e);},updateAlternativeModeState_:function(e){var shiftPressed=e.shiftKey;var spacePressed=this.spacePressed_;var cmdOrCtrlPressed=isCmdOrCtrlPressed(e);var smm=this.supportedModeMask_;var newMode;var isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
-if(this.mode===newMode||newMode===undefined)
-return;if(isNewModeAnAlternativeMode)
-this.modeBeforeAlternativeModeActivated_=this.mode;this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode:function(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_)
-tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)
-return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist)
-this.isClick_=false;},dispatchClickEvents_:function(e){if(!this.isClick_)
-return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';(function(){var DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer('tr-ui-e-chrome-cc-display-item-list-item',{created:function(){this.name='';this.rawDetails='';this.richDetails=undefined;this.data_=undefined;},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){var match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation:function(e){e.stopPropagation();}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
-throw new Error('Render pass (with id) is required');this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
-RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer)
-throw new Error('Layer is required');this.layer_=layer;}
-LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization)
-dataView.label+=' (GPU-rasterized)';dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent:function(lthi){var layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)
-return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
-TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
-this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
-return analysis;},findEquivalent:function(lthi){var tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs)
-return undefined;var tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)
-return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
-LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent:function(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
-AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection:Selection,RenderPassSelection:RenderPassSelection,LayerSelection:LayerSelection,TileSelection:TileSelection,LayerRectSelection:LayerRectSelection,AnimationRectSelection:AnimationRectSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var ANNOTATION='Comment';var BEGIN_ANNOTATION='BeginCommentGroup';var END_ANNOTATION='EndCommentGroup';var ANNOTATION_ID='ID: ';var ANNOTATION_CLASS='CLASS: ';var ANNOTATION_TAG='TAG: ';var constants=tr.e.cc.constants;var PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.opsList_=new tr.ui.b.ListView();this.appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_:function(){this.opsList_.clear();if(!this.picture_)
-return;var ops=this.picture_.getOps();if(!ops)
-return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(var i=0;i<ops.length;i++){var op=ops[i];var item=document.createElement('div');item.opIndex=op.opIndex;item.textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){var elementInfo=document.createElement('span');elementInfo.classList.add('elementInfo');var tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';var id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;var className=op.elementInfo.class?'class='+
-op.elementInfo.class:undefined;elementInfo.textContent='<'+tag+(id?' ':'')+
-(id?id:'')+(className?' ':'')+
-(className?className:'')+'>';item.appendChild(elementInfo);}
-if(op.info.length>0){var infoItem=document.createElement('div');infoItem.textContent=JSON.stringify(op.info);item.appendChild(infoItem);}
-if(op.cmd_time&&op.cmd_time>=0.0001){var time=document.createElement('span');time.classList.add('time');var rounded=op.cmd_time.toFixed(4);time.textContent='('+rounded+'ms)';item.appendChild(time);}
-this.opsList_.appendChild(item);}},onSelectionChanged_:function(e){var beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
-this.selectedOp_=this.opsList_.selectedElement;var ops=this.opsList_.children;for(var i=0;i<ops.length;i++){var op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){op.setAttribute('beforeSelection','beforeSelection');}else{op.removeAttribute('beforeSelection');}}
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_:function(ops){var annotationGroups=new Array();var opsWithoutAnnotations=new Array();for(var opIndex=0;opIndex<ops.length;opIndex++){var op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push(new Array());break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:var annotations=new Array();var elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.indexOf(ANNOTATION_TAG)!=-1)
-elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
-ANNOTATION_TAG.length).toLowerCase();else if(info.indexOf(ANNOTATION_ID)!=-1)
-elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
-ANNOTATION_ID.length);else if(info.indexOf(ANNOTATION_CLASS)!=-1)
-elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
-ANNOTATION_CLASS.length);annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
-return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;this.displayItemListView_.appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
-return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
-this.picture_.layerRect.width+' x '+
-this.picture_.layerRect.height+')';}
-if(!this.pictureAsImageData_)
-return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
-this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
-this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)
-return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_:function(e){var selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
-var index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);var displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64)
-this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);else
-this.picture=undefined;},onDisplayItemInfoClick_:function(e){if(e&&e.target==this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.classList.add('hasPictureOps');this.pictureOpsListDragHandle_.classList.add('hasPictureOps');}}else{this.pictureOpsListView_.classList.remove('hasPictureOps');this.pictureOpsListDragHandle_.classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)
-return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
-uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
-this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView:DisplayItemSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();this.appendChild(this.controls_);this.appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));this.controls_.appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');showPureTransformLayers.classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';this.controls_.appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree==RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)
-return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)
-return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)
-return[];var renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses)
-return renderPassInfo;var renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(var i=0;i<renderPasses.length;++i){var info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
-return renderPassInfo;},getLayerInfos_:function(){if(!this.lthiSnapshot_)
-return[];var tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)
-return[];var layerInfos=[];var showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!=1&&layer.args.compositingReasons[0]!='No reasons given')
-return false;if(layer.args.drawsContent)
-return false;return true;}
-var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
-return;visitedLayers[layer.layerId]=true;var info={layer:layer,depth:depth};if(layer.args.drawsContent)
-info.name=layer.objectInstance.name;else
-info.name='cc::LayerImpl';if(layer.usingGpuRasterization)
-info.name+=' (G)';info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer))
-layerInfos.push(info);};tree.iterLayers(visitLayer);return layerInfos;},updateContents_:function(){if(this.renderPassQuads_)
-this.updateRenderPassContents_();else
-this.updateLayerContents_();},updateRenderPassContents_:function(){this.itemList_.clear();var selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId)
-selectedRenderPassId=this.selection_.associatedRenderPassId;var renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){var renderPass=renderPassInfo.renderPass;var id=renderPassInfo.id;var item=this.createElementWithDepth_(renderPassInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;this.itemList_.appendChild(item);if(id==selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_:function(){this.changingItemSelection_=true;try{this.itemList_.clear();var selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId)
-selectedLayerId=this.selection_.associatedLayerId;var layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){var layer=layerInfo.layer;var id=layer.layerId;var item=this.createElementWithDepth_(layerInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=layerInfo.name+' '+id;var notesEl=item.appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer)
-notesEl.textContent+='(mask)';if(layerInfo.isReplicaLayer)
-notesEl.textContent+='(replica)';if(layer.gpuMemoryUsageInBytes!==undefined){var rounded=bytesToRoundedMegabytes(layer.gpuMemoryUsageInBytes);if(rounded!==0)
-notesEl.textContent+=' ('+rounded+' MB)';}
-item.layer=layer;this.itemList_.appendChild(item);if(layer.layerId==selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_:function(depth){var item=document.createElement('div');var indentEl=item.appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(var i=0;i<depth;i++)
-indentEl.textContent=indentEl.textContent+' ';return item;},onItemSelectionChanged_:function(e){if(this.changingItemSelection_)
-return;if(this.renderPassQuads_)
-this.onRenderPassSelected_(e);else
-this.onLayerSelected_(e);tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_:function(e){var selectedRenderPass;var selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
-if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_:function(e){var selectedLayer;if(this.itemList_.selectedElement)
-selectedLayer=this.itemList_.selectedElement.layer;if(selectedLayer)
-this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);else
-this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
-return;this.selection_=selection;this.updateContents_();}};return{LayerPicker:LayerPicker};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
-RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot:RenderPassSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};var Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){var mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var aspectRatio=rect.width/rect.height;var matrix=mat4.create();mat4.perspective(matrix,tr.b.deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){var gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings:function(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings:function(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera:function(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];var settings=tr.b.SessionSettings();var keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
-if(this.deviceRect_){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
-this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta:function(delta){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];var length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);var halfFov=constants.FOV/2;var multiplier=2.0*length*Math.tan(tr.b.deg2rad(halfFov))/rect.height;var up=[0,1,0];var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);var right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(var i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
-if(Math.abs(this.gazeTarget_[2])>1e-6){var gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];var newLength=tr.b.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(var i=0;i<3;++i)
-this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}
-this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta:function(delta){var deltaY=delta[1];deltaY=tr.b.clamp(deltaY,-50,50);var scale=1.0-deltaY/100.0;var eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE)
-scale=constants.MINIMUM_DISTANCE/length;else if(length*scale>constants.MAXIMUM_DISTANCE)
-scale=constants.MAXIMUM_DISTANCE/length;vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta:function(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT)
-return;if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT)
-return;var eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_:function(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_:function(e){if(!this.panning_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_:function(e){this.panning_=false;},onZoomBegin_:function(e){this.zooming_=true;var p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_:function(e){if(!this.zooming_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_:function(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_:function(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_:function(e){if(!this.rotating_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_:function(e){this.rotating_=false;},getMousePosition_:function(e){var rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_:function(e,p){var newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_:function(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera:Camera};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){var tmp_p0=[p0[0],p0[1]];var tmp_p1=[p1[0],p1[1]];var tmp_p2=[p2[0],p2[1]];var tmp_t0=[t0[0],t0[1]];var tmp_t1=[t1[0],t1[1]];var tmp_t2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmp_p0[0],tmp_p0[1]);ctx.lineTo(tmp_p1[0],tmp_p1[1]);ctx.lineTo(tmp_p2[0],tmp_p2[1]);ctx.closePath();tmp_p1[0]-=tmp_p0[0];tmp_p1[1]-=tmp_p0[1];tmp_p2[0]-=tmp_p0[0];tmp_p2[1]-=tmp_p0[1];tmp_t1[0]-=tmp_t0[0];tmp_t1[1]-=tmp_t0[1];tmp_t2[0]-=tmp_t0[0];tmp_t2[1]-=tmp_t0[1];var det=1/(tmp_t1[0]*tmp_t2[1]-tmp_t2[0]*tmp_t1[1]),a=(tmp_t2[1]*tmp_p1[0]-tmp_t1[1]*tmp_p2[0])*det,b=(tmp_t2[1]*tmp_p1[1]-tmp_t1[1]*tmp_p2[1])*det,c=(tmp_t1[0]*tmp_p2[0]-tmp_t2[0]*tmp_p1[0])*det,d=(tmp_t1[0]*tmp_p2[1]-tmp_t2[0]*tmp_p1[1])*det,e=tmp_p0[0]-a*tmp_t0[0]-c*tmp_t0[1],f=tmp_p0[1]-b*tmp_t0[0]-d*tmp_t0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
-function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursion_depth){var depth=opt_recursion_depth||0;var subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=1;if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=2;if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=4;}
-var p01=vec4.create();var p02=vec4.create();var p12=vec4.create();var t01=vec2.create();var t02=vec2.create();var t12=vec2.create();for(var i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
-for(var i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
-for(var i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
-for(var i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
-switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
-var tmp_vec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmp_vec4,point[0],point[1],0,1);vec4.transformMat4(tmp_vec4,tmp_vec4,matrix);var w=tmp_vec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmp_vec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmp_vec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
-function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);var quadBBox=new tr.b.BBox2();quadBBox.addQuad(quad);var iw=quadCanvas.width;var ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
-if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
-function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor)
-ctx.strokeStyle=quad.borderColor;else
-ctx.strokeStyle='rgb(128,128,128)';if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur)
-ctx.shadowBlur=quad.shadowBlur;}
-if(quad.borderWidth)
-ctx.lineWidth=quad.borderWidth;else
-ctx.lineWidth=1;ctx.stroke();ctx.restore();}
-function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)
-return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
-function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
-var tmp_p1=vec3.create();var tmp_p2=vec3.create();var tmp_p3=vec3.create();var tmp_p4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(var passNumber=0;passNumber<numPasses;passNumber++){for(var i=0;i<quads.length;i++){var quad=quads[i];transform(tmp_p1,quad.p1,matrix,viewport);transform(tmp_p2,quad.p2,matrix,viewport);transform(tmp_p3,quad.p3,matrix,viewport);transform(tmp_p4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmp_p1,tmp_p2,tmp_p3,tmp_p4,opt_arg1,opt_arg2);}}}
-var QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.className='quad-stack-view';var node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);this.appendChild(node);this.updateHeaderVisibility_();this.canvas_=this.querySelector('#canvas');this.chromeImages_={left:this.querySelector('#chrome-left'),mid:this.querySelector('#chrome-mid'),right:this.querySelector('#chrome-right')};var stackingDistanceSlider=this.querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_:function(){if(this.headerText)
-this.querySelector('#header').style.display='';else
-this.querySelector('#header').style.display='none';},get headerText(){return this.querySelector('#header').textContent;},set headerText(headerText){this.querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_:function(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return this.querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))
-return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)
-return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))
-return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
-return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).backgroundImage;leftContent=tr.ui.b.extractUrlString(leftContent);var midContent=window.getComputedStyle(this.chromeImages_.mid).backgroundImage;midContent=tr.ui.b.extractUrlString(midContent);var rightContent=window.getComputedStyle(this.chromeImages_.right).backgroundImage;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
-return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)
-return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)
-return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length)
-quadStacks.push([]);quadStacks[stackingId].push(quad);}
-var mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;var effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(var i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
-if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render:function(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
-if(!this.quads_)
-return;var canvasCtx=this.canvas_.getContext('2d');if(!this.resize())
-canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);var quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_:function(e){var br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_:function(e){var mousePos=this.extractRelativeMousePosition_(e);var res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.pointInImplicitQuad(mousePos,p1,p2,p3,p4))
-res.push(quad);}
-this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView:QuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
-var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);this.appendChild(node);this.appendChild(this.controls_);this.appendChild(this.infoBar_);this.appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());this.controls_.appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});this.controls_.appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);this.controls_.appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';this.controls_.appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';this.controls_.appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';this.controls_.appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';this.controls_.appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';this.controls_.appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';this.controls_.appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';this.controls_.appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';this.controls_.appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');this.whatRasterizedLink_.classList.add('what-rasterized');this.whatRasterizedLink_.textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));this.appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)
-return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){console.assert((val==='none')||(val==='coverage')||!isNaN(parseFloat(val)));this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)
-return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).backgroundImage;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);};},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
-selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!=0)
-return z;return x.selectionToSetIfClicked.specicifity-
-y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_:function(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
-var status=this.computePictureLoadingStatus_();if(!status.picturesComplete)
-return;var lthi=this.layerTreeImpl_.layerTreeHostImpl;var lthiInstance=lthi.objectInstance;var worldViewportRect=tr.b.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_)
-this.quadStackView_.quads=this.generateRenderPassQuads();else
-this.quadStackView_.quads=this.generateLayerQuads();this.updateWhatRasterizedLinkState_();var message='';if(lthi.tilesHaveGpuMemoryUsageInfo){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;var otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
-thisTreeUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(otherTreeUsageInBytes){message+=', '+
-bytesToRoundedMegabytes(otherTreeUsageInBytes)+'MB on the other tree';}}else{if(this.layerTreeImpl_){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ???MB on other tree. ';}}}
-if(lthi.args.tileManagerBasicState){var tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
-bytesToRoundedMegabytes(tmgs.softMemoryLimitInBytes)+'MB, hardMax='+
-bytesToRoundedMegabytes(tmgs.hardMemoryLimitInBytes)+'MB, '+
-tmgs.memoryLimitPolicy+')';}else{var thread=lthi.snapshottedOnThread;var didManageTilesSlices=thread.sliceGroup.slices.filter(function(s){if(s.category!=='tr.e.cc')
-return false;if(s.title!=='DidManage')
-return false;if(s.end>lthi.ts)
-return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){var newest=didManageTilesSlices[didManageTilesSlices.length-1];var tmgs=newest.args.state.global_state;message+=' (softMax='+
-bytesToRoundedMegabytes(tmgs.soft_memory_limit_in_bytes)+'MB, hardMax='+
-bytesToRoundedMegabytes(tmgs.hard_memory_limit_in_bytes)+'MB, '+
-tmgs.memory_limit_policy+')';}}
-if(this.layerTreeImpl_.otherTree)
-message+=' (Another tree exists)';if(message.length)
-this.quadStackView_.headerText=message;else
-this.quadStackView_.headerText=undefined;this.updateInfoBar_(status.messages);},updateTilesSelector_:function(){var data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var scaleNames=lthi.getContentsScaleNames();for(var scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
-var new_selector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(new_selector,this.tileRectsSelector_);this.tileRectsSelector_=new_selector;},computePictureLoadingStatus_:function(){var layers=this.layers;var status={messages:[],picturesComplete:true};if(this.showContents){var hasPendingRasterizeImage=false;var firstPictureError=undefined;var hasMissingLayerRect=false;var hasUnresolvedPictureRef=false;for(var i=0;i<layers.length;i++){var layer=layers[i];for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
-if(!picture.layerRect){hasMissingLayerRect=true;continue;}
-var pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){var picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
-if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
-if(pictureAsImageData.error){if(!firstPictureError)
-firstPictureError=pictureAsImageData.error;break;}}}
-if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didnt have pictures for every layer. '+'Old chrome versions had this problem'});}
-if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
-if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
-if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){var image=this.querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
-status.picturesComplete=false;}
-return status;},get selectedRenderPass(){if(this.selection)
-return this.selection.renderPass_;},get selectedLayer(){if(this.selection){var selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){var renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){var selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass)
-renderPasses=[selectedRenderPass];}
-return renderPasses;},get layers(){var layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){var selectedLayer=this.selectedLayer;if(selectedLayer)
-layers=[selectedLayer];}
-return layers;},appendImageQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(!picture.layerRect)
-continue;var unitRect=picture.layerRect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);var pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
-iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_:function(quads,layer,layerQuad){if(!layer.animationBoundsRect)
-return;var rect=layer.animationBoundsRect;var abq=tr.b.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_:function(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)
-return;for(var ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){var rect=layer.annotatedInvalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion')
-iq.backgroundColor='rgba(0, 255, 128, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
-if(layer.annotatedInvalidation.rects.length===0){for(var ir=0;ir<layer.invalidation.rects.length;ir++){var rect=layer.invalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.unrecordedRegion.rects.length;ir++){var rect=layer.unrecordedRegion.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_:function(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){var backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)
-return;for(var ir=0;ir<region.rects.length;ir++){var rect=region.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
-processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_:function(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)
-return;var tiles=[];for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)
-tiles.push(tile);}
-var lthi=this.layerTreeImpl_.layerTreeHostImpl;var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);var heatIndex=0;for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var tile=layer.tileCoverageRects[ct].tile;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
-quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;var label;if(tile)
-label='coverageRect';else
-label='checkerboard coverageRect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_:function(quads,layer,layerQuad){if(!layer.layoutRects){return;}
-for(var ct=0;ct<layer.layoutRects.length;++ct){var rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;var label;label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_:function(tile,heatmapType){if(heatmapType==TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority==0?undefined:tile.scheduledPriority;}else if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)
-return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_:function(tiles,heatmapType){var range=new tr.b.Range();if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
-for(var i=0;i<tiles.length;++i){var value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)
-continue;range.addValue(value);}
-if(range.range===0)
-range.addValue(1);return range;},computeHeatmapColors_:function(tiles,minMax,heatmapType){var min=minMax.min;var max=minMax.max;var color=function(value){var hue=120*(1-(value-min)/(max-min));if(hue<0)
-hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};var values=[];for(var i=0;i<tiles.length;++i){var tile=tiles[i];var value=this.getValueForHeatmap_(tile,heatmapType);var res={value:value,color:value!==undefined?color(value):undefined};values.push(res);}
-return values;},appendTilesWithScaleQuads_:function(quads,layer,layerQuad,scale,heatmapType){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var tiles=[];for(var i=0;i<lthi.activeTiles.length;++i){var tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6)
-continue;if(layer.layerId!=tile.layerId)
-continue;tiles.push(tile);}
-var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(var i=0;i<tiles.length;++i){var tile=tiles[i];var rect=tile.layerRect;if(!tile.layerRect)
-continue;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;var data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE)
-data[heatmapType]=heatmapResult[i].value;quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_:function(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){var rect=highlight.rect;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);var colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);colorId+=ColorScheme.properties.brightenedOffsets[0];var color=ColorScheme.colors[colorId];var quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads:function(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)
-return[];var renderPasses=this.renderPasses;if(!renderPasses)
-return[];var quads=[];for(var i=0;i<renderPasses.length;++i){var quadList=renderPasses[i].quadList;for(var j=0;j<quadList.length;++j){var drawQuad=quadList[j];var quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
-return quads;},generateLayerQuads:function(){this.updateContentsPending_=false;var layers=this.layers;var quads=[];var nextStackingGroupId=0;var alreadyVisitedLayerIds={};var selectionHighlightsByLayerId;if(this.selection)
-selectionHighlightsByLayerId=this.selection.highlightsByLayerId;else
-selectionHighlightsByLayerId={};var extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(var i=1;i<=layers.length;i++){var layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name=='cc::NinePatchLayerImpl')
-continue;var layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){var pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
-layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer==layer)
-layerQuad.upperBorderColor='rgb(156,189,45)';if(this.showAnimationBounds)
-this.appendAnimationQuads_(quads,layer,layerQuad);this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations)
-this.appendInvalidationQuads_(quads,layer,layerQuad);if(this.showUnrecordedRegion)
-this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);if(this.showBottlenecks)
-this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);if(this.showLayoutRects)
-this.appendLayoutRectQuads_(quads,layer,layerQuad);if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
-var highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
-highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
-this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!=layer)
-return;if(alreadyVisitedLayerIds[layer.layerId])
-return;var layerQuad=layer.layerQuad;var stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks)
-this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);},this);var tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(var i=0;i<tracedInputLatencies.length;i++){var coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(var j=0;j<coordinatesArray.length;j++){var inputQuad=tr.b.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
-return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');title.textContent=message.header;var details=document.createElement('div');details.textContent=message.details;overlay.appendChild(title);overlay.appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];renderProcess.iterateAllEvents(function(event){if(!(event instanceof tr.model.Slice))
-return;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)
-return false;if(tile.containingSnapshot==lthi)
-tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
-var analysis=selection.createAnalysis();this.analysisEl_.appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=this.analysisEl_.firstChild;if(analysis)
-this.analysisEl_.removeChild(analysis);this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
-tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array))
-pictures=[pictures];var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};link.textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection))
-return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
-layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)
-return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
-return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView:LayerTreeHostImplSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(this.classList.contains('hidden'))
-return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide:function(){this.classList.add('hidden');},show:function(){this.classList.remove('hidden');if(this.pictureDataProcessed_)
-return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;var x=e.offsetX;var y=e.offsetY;var chartLeft=CHART_PADDING_LEFT;var chartRight=this.chartWidth_-CHART_PADDING_RIGHT;var chartTop=AXIS_PADDING_TOP;var chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;var chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
-if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
-return;this.drawChartContents_();},updateChartContents:function(){if(this.requiresRedraw)
-this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_:function(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)
-return;var ops=this.picture_.getOps();if(!ops)
-return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)
-return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_:function(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
-this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)
-return;this.drawTooltip_();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_:function(){var tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var tooltipWidth=110;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=chartInnerWidth/this.opsTimingData_.length;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var barWidth=Math.floor(width/len);var opData;var opTiming;var opHeight;var opLabel;var barLeft;for(var b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
-height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_:function(opName){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
-CHART_PADDING_RIGHT;var barWidth=Math.floor(totalBarWidth/len);var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';var labelTickLeft;var labelTickBottom;for(var l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
-this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_:function(ops){var opsTimingDataIndexHash_={};var timingData=this.opsTimingData_;var op;var opIndex;for(var i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)
-continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
-timingData[opIndex].cmd_time+=op.cmd_time;}
-timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_:function(count){var timingData=this.opsTimingData_;var otherSource=timingData.splice(count,timingData.length-count);var otherDestination=null;if(!otherSource.length)
-return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(var i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_:function(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_:function(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView:PictureOpsChartSummaryView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var BAR_PADDING=1;var BAR_WIDTH=5;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=30;var CHART_PADDING_BOTTOM=35;var CHART_PADDING_TOP=20;var AXIS_PADDING_LEFT=55;var AXIS_PADDING_RIGHT=30;var AXIS_PADDING_BOTTOM=35;var AXIS_PADDING_TOP=20;var AXIS_TICK_SIZE=5;var AXIS_LABEL_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');this.usePercentileScaleCheckbox_.classList.add('use-percentile-scale');this.appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_:function(){if(this.pictureOps_===undefined)
-return;var totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();var ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_:function(e){var index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0)
-return index;var x=e.offsetX;var y=e.offsetY;var totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;var chartLeft=CHART_PADDING_LEFT;var chartTop=0;var chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;var chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom)
-return index;index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_:function(e){var barClicked=this.extractBarIndex_(e);if(barClicked===undefined)
-return;if(barClicked===this.selectedOpIndex)
-this.selectedOpIndex=undefined;else
-this.selectedOpIndex=barClicked;e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
-return;this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary:function(){if(this.selectedOpIndex===undefined)
-return;var width=this.offsetWidth;var left=this.scrollLeft;var right=left+width;var targetLeft=CHART_PADDING_LEFT+
-(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right)
-return;this.scrollLeft=(targetLeft-width*0.5);},updateChartContents:function(){if(this.dimensionsHaveChanged)
-this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){if(!this.pictureOps_)
-return;var width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
-((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth)
-width=this.offsetWidth;this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_:function(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
-this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined)
-return;this.drawTooltip_();},drawSelection_:function(){if(this.selectedOpIndex===undefined)
-return;var width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_:function(){var min=this.opCosts_[0];var max=this.opCosts_[this.opCosts_.length-1];var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
-AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_:function(){var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
-this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_:function(){var tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);var tooltipWidth=120;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=BAR_WIDTH+BAR_PADDING;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
-toolTipTimePercentage+'%)',left+8,top+22);},drawBars_:function(){var op;var opColor=0;var opHeight=0;var opWidth=BAR_WIDTH+BAR_PADDING;var opHover=false;var bottom=this.chartHeight_-CHART_PADDING_BOTTOM;var maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
-CHART_PADDING_TOP;var maxValue;if(this.usePercentileScale)
-maxValue=this.ninetyFifthPercentileCost_;else
-maxValue=this.maxCost_;for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex)
-this.chartCtx_.fillStyle='#FFFF00';else
-this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
-uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
-this.picture_.layerRect.width+' x '+
-this.picture_.layerRect.height+')';}
-this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)
-return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
-this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
-this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)
-return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy:function(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
-this.selectedOpIndex=tr.b.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_:function(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_:function(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible)
-this.drawOpsChartSummaryView_.show();else
-this.drawOpsChartSummaryView_.hide();},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger:PictureDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();this.appendChild(this.pictureDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.pictureDebugger_)
-this.pictureDebugger_.picture=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView:PictureSnapshotView};});'use strict';tr.exportTo('tr.e.cc',function(){var knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];var knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice)))
-return undefined;var tileData;if(slice.args.data)
-tileData=slice.args.data;else
-tileData=slice.args.tileData;if(tileData===undefined)
-return undefined;if(tileData.tile_id)
-return tileData.tile_id;var tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot))
-return undefined;return tileData.tileId;}
-function isSliceDoingRasterization(slice){if(knownRasterTaskNames.indexOf(slice.title)!==-1)
-return true;return false;}
-function isSliceDoingAnalysis(slice){if(knownAnalysisTaskNames.indexOf(slice.title)!==-1)
-return true;return false;}
-return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
-var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
-if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
-table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
-rows.push({name:'Error',value:event.error});if(event.title)
-rows.push({name:'Title',value:event.title});if(event.category)
-rows.push({name:'Category',value:event.category});if(event.model!==undefined){var ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined)
-rows.push({name:'User Friendly Category',value:ufc});}
-if(event.name)
-rows.push({name:'Name',value:event.name});rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.v.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.cpuSelfTime){var cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
-rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
-if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
-if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
-if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
-if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
-return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
-if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
-rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
-return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
-rows.push({name:'Args',value:'Stripped'});else
-this.addArgsToRows_(rows,event.args);var event=new tr.b.Event('customize-rows');event.rows=rows;this.dispatchEvent(event);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
-return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_:function(){var table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
-var lthi=tr.e.cc.getTileFromRasterTaskSlice(this.selection_[0]).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);var costsByLayerId={};function getCurrentCostsForLayerId(tile){var layerId=tile.layerId;var lthi=tile.containingSnapshot;var layer;if(lthi.activeTree)
-layer=lthi.activeTree.findLayerWithId(layerId);if(layer===undefined&&lthi.pendingTree)
-layer=lthi.pendingTree.findLayerWithId(layerId);if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId:layerId,layer:layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
-return costsByLayerId[layerId];}
-var totalDuration=0;var totalCpuDuration=0;var totalNumAnalyzeTasks=0;var totalNumRasterizeTasks=0;var hadCpuDurations=false;var tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);var curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
-if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
-curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=tr.b.dictionaryValues(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:tr.b.dictionaryLength(tilesThatWeHaveSeen),numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);var whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok)
-throw new Error('Fail: '+whySupported.why);this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined)
-throw new Error('This should never happen due to .supports check.');return tile;});}
-RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet))
-return{ok:false,why:'Must be selection'};if(selection.length===0)
-return{ok:false,why:'Selection must be non empty'};var tile0;for(var i=0;i<selection.length;i++){var event=selection[i];if(!(event instanceof tr.model.Slice))
-return{ok:false,why:'Not a slice'};var tile=tr.e.cc.getTileFromRasterTaskSlice(selection[i]);if(tile===undefined)
-return{ok:false,why:'No tile found'};if(i===0){tile0=tile;}else{if(tile.containingSnapshot!=tile0.containingSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
-return{ok:true};}
-RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){var tile0=this.tiles_[0];var allSameLayer=this.tiles_.every(function(tile){tile.layerId==tile0.layerId;});if(allSameLayer)
-return tile0.layerId;return undefined;},get extraHighlightsByLayerId(){var highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined)
-highlights[tile.layerId]=[];var slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis:function(){var sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});var analysis;if(sel.length==1)
-analysis=document.createElement('tr-ui-a-single-event-sub-view');else
-analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');analysis.selection=sel;return analysis;},findEquivalent:function(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection:RasterTaskSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();this.appendChild(this.layerTreeView_);},updateContents:function(){var tile=this.objectSnapshot_;var layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)
-return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView:TileSnapshotView};});'use strict';tr.exportTo('tr.e.gpu',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
-StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){this.screenshot_=undefined;},initialize:function(){if(this.args.screenshot)
-this.screenshot_=this.args.screenshot;},get screenshot(){return this.screenshot_;}};ObjectSnapshot.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot:StateSnapshot};});'use strict';tr.exportTo('tr.e.gpu',function(){var AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
-GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category=='disabled-by-default-gpu.device')
-return'Device.'+this.args.channel;else
-return'Service.'+this.args.channel;}
-return this.title;}};AsyncSlice.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice:GpuAsyncSlice};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');this.appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
-this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
-id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
-var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
-this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
-margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
-var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
-return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
-return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
-throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
-throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
-this.style.fontWeight='bold';else
-this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleMin_=undefined;this.dataRange_=new tr.b.Range();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
-throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale)
-this.yScale_=d3.scale.log(10);else
-this.yScale_=d3.scale.linear();this.isYLogScale_=logScale;},getYScaleMin_:function(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_:function(minValue,maxValue){if(this.isYLogScale_)
-return[this.getYScaleMin_(),maxValue];return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
-var leftWidth=this.getXForDatum_(data[index],index)-
-this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
-this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
-return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
-keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
-yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateDataRange_:function(){var dataBySeriesKey=this.getDataBySeriesKey_();this.dataRange_.reset();tr.b.iterItems(dataBySeriesKey,function(series,values){for(var i=0;i<values.length;i++){this.dataRange_.addValue(values[i][series]);}},this);this.yLogScaleMin_=undefined;if(this.dataRange_.min!==undefined){var minValue=this.dataRange_.min;if(minValue==0)
-minValue=1;var onePowerLess=Math.floor(Math.log(minValue)/Math.log(10))-1;this.yLogScaleMin_=Math.pow(10,onePowerLess);}},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;var axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)
-return;var minValue=this.dataRange_.min;if(minValue==0)
-minValue=1;var largestPower=Math.ceil(Math.log(this.dataRange_.max)/Math.log(10))+1;var smallestPower=Math.floor(Math.log(minValue)/Math.log(10));var tickValues=[];for(var i=smallestPower;i<largestPower;i++){tickValues.push(Math.pow(10,i));}
-axisModifier=axisModifier.tickValues(tickValues).tickFormat(function(d){return d;});}
-yAxis.call(axisModifier);window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
-return;if(multiSeriesDatum[seriesKey]===undefined)
-return;if(!this.isDatumFieldSeries_(seriesKey))
-return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
-var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
-this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
-this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
-return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
-dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
-this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
-return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
-return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
-return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
-return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
-r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
-latencySlices.push(event);});});latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
-return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
-tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
-return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
-return this.model_.bounds;else
-return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
-width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
-return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
-chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
-chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
-return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
-if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
-if(!tr.model.helpers.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
-var modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
-return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
-throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
-this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
-margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
-return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
-var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
-return'';if(d.endAngle-d.startAngle<0.4)
-return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
-return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
-ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
-continue;return 0;}
-cpuDuration+=x.cpuDuration;}
-return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
-throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
-sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
-groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
-break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
-break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
-if(getValue(otherGroup)>0)
-groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.v.Unit.byName.timeDurationInMs.format(value),resultsForGroup:resultsForGroup});}
-chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
-return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
-data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
-this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
-this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
-this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
-return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
-this.showCpuIdleTimeCheckbox_.style.display='';else
-this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
-return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
-return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
-return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
-rangeOfInterest=this.model_.bounds;else
-rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
-resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
-return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.v.ui.createScalarSpan(getValueFromGroup(allGroup),{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.v.Unit.byName.timeDurationInMs.format(idleTime)});extraValue+=idleTime;}
-var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
-this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
-return;if(selection.timeSummaryGroupName)
-this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
-this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
-SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length==0)
-throw new Error('No system stats snapshot data.');this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot:SystemStatsSnapshot};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){this.textContent='No system stats snapshot found.';return;}
-this.textContent='';var stats=snapshot.getStats();this.appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');statText.textContent=''+statName+': ';statList.appendChild(statText);if(stats[statName]instanceof Object){statList.appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName]))
-statText.textContent+=stats[statName].toFixed(2);else
-statText.textContent+=stats[statName];}}
-return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
-return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
-return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
-return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
-return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
-if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
-this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
-throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
-return cur;cur=cur.parentElement;}
-return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
-dc.invalidate();},context:function(){if(!this.parentNode)
-return undefined;if(!this.parentNode.context)
-throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
-childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
-return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
-return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
-var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i==snapshots.length-1){if(snapshots.length==1)
-return maxBounds;return snapshots[i].ts-snapshots[i-1].ts;}
-return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot))
-throw new Error('Unrecognized event');var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
-this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
-break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
-ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
-break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
-ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
-if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
-if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
-var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
-return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
-events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
-events=this.objectInstances_;else
-throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
-if(objectInstances.length!=1)
-throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i==0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
-prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds==0)
-timeIntervalSeconds=1;this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_:function(prevStats,stats,timeIntervalSeconds){for(var statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName=='sectors_read'){stats['bytes_read_per_sec']=(stats['sectors_read']-
-prevStats['sectors_read'])*512/timeIntervalSeconds;}
-if(statName=='sectors_written'){stats['bytes_written_per_sec']=(stats['sectors_written']-
-prevStats['sectors_written'])*512/timeIntervalSeconds;}
-if(statName=='pgmajfault'){stats['pgmajfault_per_sec']=(stats['pgmajfault']-
-prevStats['pgmajfault'])/timeIntervalSeconds;}
-if(statName=='pswpin'){stats['bytes_swpin_per_sec']=(stats['pswpin']-
-prevStats['pswpin'])*1000/timeIntervalSeconds;}
-if(statName=='pswpout'){stats['bytes_swpout_per_sec']=(stats['pswpout']-
-prevStats['pswpout'])*1000/timeIntervalSeconds;}}}},computeMaxStats_:function(snapshots){var maxStats=new Object();statCount=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
-return maxStats;},computeMaxStatsRecursive_:function(stats,maxStats,excludedStats){for(var statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats))
-maxStats[statName]=new Object();var excludedNested;if(excludedStats&&statName in excludedStats)
-excludedNested=excludedStats[statName];else
-excludedNested=null;this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats)
-continue;if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
-if(stats[statName]>maxStats[statName])
-maxStats[statName]=stats[statName];}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=(bounds.height*pixelRatio)/statCount;var vp=this.viewport.currentDisplayTransform;var maxStats=this.maxStats_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
-lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var trace=snapshot.getStats();var currentY=height;var left=snapshot.ts;if(left>viewRWorld)
-break;var leftView=vp.xWorldToView(left);if(leftView<0)
-leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
-right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
-objectSnapshots[i-1].ts);else
-right=this.objectInstance_.parent.model.bounds.max;}
-var rightView=vp.xWorldToView(right);if(rightView>width)
-rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i==lowIndex)
-this.drawStatNames_(leftView,height,currentY,'',maxStats);}
-ctx.lineWidth=1;},drawStatBarsRecursive_:function(snapshot,leftView,rightView,height,stats,maxStats,currentY){var ctx=this.context();for(var statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{var maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));var barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
-ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
-return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!='')
-fullname=prefix+' :: '+statName;ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
-return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
-ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
-function ScriptingObjectRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
-v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Function;tr.b.decorateExtensionRegistry(MetricRegistry,options);return{MetricRegistry:MetricRegistry};});'use strict';tr.exportTo('tr.v',function(){function Value(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){if(typeof(name)!=='string')
-throw new Error('Expected value_name grouping key to be provided');this.groupingKeys={name:name};if(opt_groupingKeys){for(var keyName in opt_groupingKeys){this.addGroupingKey(keyName,opt_groupingKeys[keyName]);}}
-this.diagnostics=opt_diagnostics||{};this.diagnostics.canonical_url=canonicalUrl;var options=opt_options||{};this.description=options.description;this.important=options.important!==undefined?options.important:false;}
-Value.fromDict=function(d){if(d.type==='numeric')
-return NumericValue.fromDict(d);if(d.type==='dict')
-return DictValue.fromDict(d);if(d.type=='failure')
-return FailureValue.fromDict(d);if(d.type==='skip')
-return SkipValue.fromDict(d);throw new Error('Not implemented');};Value.prototype={get name(){return this.groupingKeys.name;},get canonicalUrl(){return this.diagnostics.canonical_url;},addGroupingKey:function(keyName,key){if(keyName==='name')
-throw new Error('Invalid groupingKey name "name"');if(this.groupingKeys.hasOwnProperty(keyName))
-throw new Error('Tried to redefine grouping key '+keyName);this.groupingKeys[keyName]=key;},asDict:function(){return this.asJSON();},asJSON:function(){var d={grouping_keys:tr.b.cloneDictionary(this.groupingKeys),description:this.description,important:this.important,diagnostics:this.diagnostics};this._asDictInto(d);if(d.type===undefined)
-throw new Error('_asDictInto must set type field');return d;},_asDictInto:function(d){throw new Error('Not implemented');}};function NumericValue(canonicalUrl,name,numeric,opt_options,opt_groupingKeys,opt_diagnostics){if(!(numeric instanceof tr.v.NumericBase))
-throw new Error('Expected numeric to be instance of tr.v.NumericBase');Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.numeric=numeric;}
-NumericValue.fromDict=function(d){if(d.numeric===undefined)
-throw new Error('Expected numeric to be provided');var numeric=tr.v.NumericBase.fromDict(d.numeric);var name=d.grouping_keys.name;d.grouping_keys=tr.b.cloneDictionary(d.groupingKeys);delete d.grouping_keys.name;return new NumericValue(d.diagnostics.canonical_url,name,numeric,d,d.grouping_keys,d.diagnostics);};NumericValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='numeric';d.numeric=this.numeric.asDict();}};function DictValue(canonicalUrl,name,value,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.value=value;}
-DictValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');if(d.value===undefined)
-throw new Error('Expected value to be provided');var name=d.grouping_keys.name;d.grouping_keys=tr.b.cloneDictionary(d.groupingKeys);delete d.grouping_keys.name;return new DictValue(d.diagnostics.canonical_url,name,d.value,d,d.groupingKeys,d.diagnostics);};DictValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='dict';d.value=this.value;}};function FailureValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){var options=opt_options||{};var stack;if(options.stack===undefined){if(options.stack_str===undefined){throw new Error('Expected stack_str or stack to be provided');}else{stack=options.stack_str;}}else{stack=options.stack;}
-if(typeof stack!=='string')
-throw new Error('stack must be provided as a string');if(canonicalUrl===undefined){throw new Error('FailureValue must provide canonicalUrl');}
-Value.call(this,canonicalUrl,name,options,opt_groupingKeys,opt_diagnostics);this.stack=stack;}
-FailureValue.fromError=function(canonicalUrl,e){var ex=tr.b.normalizeException(e);return new FailureValue(canonicalUrl,ex.typeName,{description:ex.message,stack:ex.stack});};FailureValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');if(d.stack_str===undefined)
-throw new Error('Expected stack_str to be provided');var name=d.grouping_keys.name;d.grouping_keys=tr.b.cloneDictionary(d.groupingKeys);delete d.grouping_keys.name;return new FailureValue(d.diagnostics.canonical_url,name,d,d.grouping_keys,d.diagnostics);};FailureValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='failure';d.stack_str=this.stack;}};function SkipValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);}
-SkipValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');var name=d.grouping_keys.name;d.grouping_keys=tr.b.cloneDictionary(d.groupingKeys);delete d.grouping_keys.name;return new SkipValue(d.diagnostics.canonical_url,name,d,d.grouping_keys,d.diagnostics);};SkipValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='skip';}};return{Value:Value,NumericValue:NumericValue,DictValue:DictValue,FailureValue:FailureValue,SkipValue:SkipValue};});'use strict';tr.exportTo('tr.metrics',function(){var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var SIZE_NUMERIC_BUILDER=tr.v.NumericBuilder.createLinear(sizeInBytes_smallerIsBetter,tr.b.Range.fromExplicitRange(1,100),100);function sampleMetric(valueList,model){var n1=new tr.v.ScalarNumeric(sizeInBytes_smallerIsBetter,1);var n2=new tr.v.ScalarNumeric(sizeInBytes_smallerIsBetter,2);var n3=SIZE_NUMERIC_BUILDER.build();n3.add(1);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'foo',n1));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'bar',n2));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'baz',n3));}
-sampleMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric:sampleMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
-function filterExpectationsByRange(irs,opt_range){var filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))
-return;if(!opt_range||opt_range.intersectsExplicitRangeExclusive(ir.start,ir.end))
-filteredExpectations.push(ir);});return filteredExpectations;}
-return{perceptualBlend:perceptualBlend,filterExpectationsByRange:filterExpectationsByRange};});'use strict';tr.exportTo('tr.metrics.sh',function(){var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Normalized CPU budget consumption';function EfficiencyMetric(valueList,model){var scores=[];model.userModel.expectations.forEach(function(ue){var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var score=undefined;if((ue.totalCpuMs===undefined)||(ue.totalCpuMs==0))
-return;var cpuFractionBudget=tr.b.Range.fromExplicitRange(0.5,1.5);if(ue instanceof tr.model.um.IdleExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(0.1,1);}else if(ue instanceof tr.model.um.AnimationExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(1,2);}
-var cpuMsBudget=tr.b.Range.fromExplicitRange(ue.duration*cpuFractionBudget.min,ue.duration*cpuFractionBudget.max);var normalizedCpu=tr.b.normalize(ue.totalCpuMs,cpuMsBudget.min,cpuMsBudget.max);score=1-tr.b.clamp(normalizedCpu,0,1);scores.push(score);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});var options={};options.description=DESCRIPTION;var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
-return;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys));}
-EfficiencyMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(EfficiencyMetric);return{EfficiencyMetric:EfficiencyMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var timeDurationInMs_smallerIsBetter=tr.v.Unit.byName.timeDurationInMs_smallerIsBetter;function findTargetRendererHelper(model){var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var largestPid=-1;for(var pid in chromeHelper.rendererHelpers){var rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)
-continue;if(pid>largestPid)
-largestPid=pid;}
-if(largestPid===-1)
-return undefined;return chromeHelper.rendererHelpers[largestPid];}
-function findNavigationStartEvent(rendererHelper){var navigationStartEvent=undefined;rendererHelper.mainThread.sliceGroup.iterateAllEventsInThisContainer(()=>true,function(ev){if(navigationStartEvent!==undefined||ev.category!=='blink.user_timing')
-return;if(ev.title==='navigationStart')
-navigationStartEvent=ev;},this);return navigationStartEvent;}
-function findFirstPaintEvent(rendererHelper,title,frame){var firstPaintEvent=undefined;rendererHelper.process.iterateAllEvents(function(ev){if(firstPaintEvent!==undefined||ev.category!=='blink.user_timing'||ev.title!==title||ev.args===undefined||ev.args['frame']!==frame)
-return;firstPaintEvent=ev;},this);return firstPaintEvent;}
-function firstPaintMetric(valueList,model){var rendererHelper=findTargetRendererHelper(model);var navigationStartEvent=findNavigationStartEvent(rendererHelper);if(navigationStartEvent===undefined)
-throw new Error('Failed to find navigationStartEvent.');var frame=navigationStartEvent.args['frame'];var firstContentfulPaintEvent=findFirstPaintEvent(rendererHelper,'firstContentfulPaint',frame);if(firstContentfulPaintEvent===undefined)
-throw new Error('Failed to find firstContentfulPaintEvent for frame '+frame);var grouping_keys={};var timeToFirstContentfulPaint=firstContentfulPaintEvent.start-navigationStartEvent.start;valueList.addValue(new tr.v.NumericValue(model.canonicalUrlThatCreatedThisTrace,'firstContentfulPaint',new tr.v.ScalarNumeric(timeDurationInMs_smallerIsBetter,timeToFirstContentfulPaint),{description:'time to first contentful paint'},grouping_keys));}
-firstPaintMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(firstPaintMetric);return{firstPaintMetric:firstPaintMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:150,max:5000,centralBinWidth:485,underflowBin:{min:-Number.MAX_VALUE,max:150,count:1000},centralBins:[{min:150,max:635,count:708},{min:635,max:1120,count:223},{min:1120,max:1605,count:50},{min:1605,max:2090,count:33},{min:2090,max:2575,count:23},{min:2575,max:3060,count:17},{min:3060,max:3545,count:12},{min:3545,max:4030,count:8},{min:4030,max:4515,count:4},{min:4515,max:5000,count:1}],overflowBin:{min:5000,max:Number.MAX_VALUE,count:0}});var FAST_RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:66,max:2200,centralBinWidth:214,underflowBin:{min:-Number.MAX_VALUE,max:66,count:1000},centralBins:[{min:66,max:280,count:708},{min:280,max:493,count:223},{min:493,max:706,count:50},{min:706,max:920,count:33},{min:920,max:1133,count:23},{min:1133,max:1346,count:17},{min:1346,max:1560,count:12},{min:1560,max:1773,count:8},{min:1773,max:1987,count:4},{min:1987,max:2200,count:1}],overflowBin:{min:2200,max:Number.MAX_VALUE,count:0}});var LOAD_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:1000,max:60000,centralBinWidth:5900,underflowBin:{min:-Number.MAX_VALUE,max:1000,count:1000},centralBins:[{min:1000,max:6900,count:901},{min:6900,max:12800,count:574},{min:12800,max:18700,count:298},{min:18700,max:24600,count:65},{min:24600,max:30500,count:35},{min:30500,max:36400,count:23},{min:36400,max:42300,count:16},{min:42300,max:48200,count:10},{min:48200,max:54100,count:5},{min:54100,max:60000,count:2}],overflowBin:{min:60000,max:Number.MAX_VALUE,count:0}});var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;function computeDurationResponsiveness(histogram,duration){return histogram.getInterpolatedCountAt(duration)/histogram.maxCount;}
-function groupingKeysForUserExpectation(ue){var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;return groupingKeys;}
-var MAX_FPS=60;var MIN_FPS=10;function computeAnimationThroughput(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0)
-throw new Error('Animation missing frameEvents '+
-animationExpectation.stableId);var durationSeconds=animationExpectation.duration/1000;var avgSpf=durationSeconds/animationExpectation.frameEvents.length;var throughput=1-tr.b.normalize(avgSpf,1/MAX_FPS,1/MIN_FPS);return tr.b.clamp(throughput,0,1);}
-var MIN_DISCREPANCY=0.05;var MAX_DISCREPANCY=0.3;function computeAnimationSmoothness(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0)
-throw new Error('Animation missing frameEvents '+
-animationExpectation.stableId);var frameTimestamps=animationExpectation.frameEvents;frameTimestamps=frameTimestamps.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);var smoothness=1-tr.b.normalize(discrepancy,MIN_DISCREPANCY,MAX_DISCREPANCY);return tr.b.clamp(smoothness,0,1);}
-function computeAnimationResponsiveness(animationExpectation,diagnosticValues){var throughput=computeAnimationThroughput(animationExpectation);if(throughput===undefined)
-throw new Error('Missing throughput for '+
-animationExpectation.stableId);var options={};options.description='Mean Opinion Score for Animation throughput';diagnosticValues.addValue(new tr.v.NumericValue(animationExpectation.parentModel.canonicalUrl,'throughput',new tr.v.ScalarNumeric(UNIT,throughput),options,groupingKeysForUserExpectation(animationExpectation)));var smoothness=computeAnimationSmoothness(animationExpectation);if(smoothness===undefined)
-throw new Error('Missing smoothness for '+
-animationExpectation.stableId);options={};options.description='Mean Opinion Score for Animation smoothness';diagnosticValues.addValue(new tr.v.NumericValue(animationExpectation.parentModel.canonicalUrl,'smoothness',new tr.v.ScalarNumeric(UNIT,smoothness),options,groupingKeysForUserExpectation(animationExpectation)));return tr.b.Statistics.weightedMean([throughput,smoothness],tr.metrics.sh.perceptualBlend);}
-function computeResponsiveness(ue,diagnosticValues){var score=undefined;var options={};if(ue instanceof tr.model.um.IdleExpectation){throw new Error('Responsiveness is not defined for Idle');}else if(ue instanceof tr.model.um.LoadExpectation){score=computeDurationResponsiveness(LOAD_HISTOGRAM,ue.duration);options.description='Mean Opinion Score of Time to First ContentfulPaint';}else if(ue instanceof tr.model.um.ResponseExpectation){var histogram=RESPONSE_HISTOGRAM;if(ue.isAnimationBegin)
-histogram=FAST_RESPONSE_HISTOGRAM;score=computeDurationResponsiveness(histogram,ue.duration);options.description='Mean Opinion Score of input latency';}else if(ue instanceof tr.model.um.AnimationExpectation){score=computeAnimationResponsiveness(ue,diagnosticValues);options.description='Mean Opinion Score of perceptual blend of throughput and smoothness';}else{throw new Error('Unrecognized stage for '+ue.stableId);}
-if(score===undefined)
-throw new Error('Unable to compute responsiveness for '+ue.stableId);diagnosticValues.addValue(new tr.v.NumericValue(ue.parentModel.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeysForUserExpectation(ue)));return score;}
-function responsivenessMetric(valueList,model){var scores=[];var diagnosticValues=new tr.metrics.ValueList();model.userModel.expectations.forEach(function(ue){if(ue instanceof tr.model.um.IdleExpectation)
-return;scores.push(computeResponsiveness(ue,diagnosticValues));});var options={};options.description='Perceptual blend of responsiveness of RAIL user expectations';var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
-return;var diagnostics={values:diagnosticValues.valueDicts};valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys,diagnostics));}
-responsivenessMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(responsivenessMetric);return{responsivenessMetric:responsivenessMetric,computeDurationResponsiveness:computeDurationResponsiveness,FAST_RESPONSE_HISTOGRAM:FAST_RESPONSE_HISTOGRAM};});'use strict';tr.exportTo('tr.metrics.sh',function(){var LONG_TASK_MS=50;var normalizedPercentage_smallerIsBetter=tr.v.Unit.byName.normalizedPercentage_smallerIsBetter;var timeDurationInMs_smallerIsBetter=tr.v.Unit.byName.timeDurationInMs_smallerIsBetter;function findLongTasks(ue){var longTasks=[];ue.associatedEvents.forEach(function(event){if((event instanceof tr.model.ThreadSlice)&&(event.duration>LONG_TASK_MS)&&event.isTopLevel)
-longTasks.push(event);});return longTasks;}
-function computeResponsivenessRisk(durationMs){durationMs+=16;return 1-tr.metrics.sh.computeDurationResponsiveness(tr.metrics.sh.FAST_RESPONSE_HISTOGRAM,durationMs);}
-function perceptualBlendSmallerIsBetter(hazardScore){return Math.exp(hazardScore);}
-function computeLongIdleTaskHazard(hazardScores,valueList,ue){var longTaskScores=[];var durationValues=new tr.metrics.ValueList();findLongTasks(ue).forEach(function(longTask){longTaskScores.push(computeResponsivenessRisk(longTask.duration));durationValues.addValue(new tr.v.NumericValue(ue.parentModel.canonicalUrlThatCreatedThisTrace,'long idle task duration',new tr.v.ScalarNumeric(timeDurationInMs_smallerIsBetter,longTask.duration),{description:'Duration of a long idle task'}));});var options={description:'Risk of impacting responsiveness'};var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var diagnostics={values:durationValues.valueDicts};var hazardScore=tr.b.Statistics.weightedMean(longTaskScores,perceptualBlendSmallerIsBetter);if(hazardScore===undefined)
-hazardScore=0;hazardScores.push(hazardScore);valueList.addValue(new tr.v.NumericValue(ue.parentModel.canonicalUrlThatCreatedThisTrace,'long idle tasks hazard',new tr.v.ScalarNumeric(normalizedPercentage_smallerIsBetter,hazardScore),options,groupingKeys,diagnostics));}
-function hazardMetric(valueList,model){var hazardScores=[];var hazardValues=new tr.metrics.ValueList();model.userModel.expectations.forEach(function(ue){if(ue instanceof tr.model.um.IdleExpectation)
-computeLongIdleTaskHazard(hazardScores,hazardValues,ue);});var options={description:'Risk of impacting responsiveness'};var groupingKeys={};var diagnostics={values:hazardValues.valueDicts};var overallHazard=tr.b.Statistics.weightedMean(hazardScores,perceptualBlendSmallerIsBetter);if(overallHazard===undefined)
-overallHazard=0;valueList.addValue(new tr.v.NumericValue(model.canonicalUrlThatCreatedThisTrace,'hazard',new tr.v.ScalarNumeric(normalizedPercentage_smallerIsBetter,overallHazard),options,groupingKeys,diagnostics));}
-hazardMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(hazardMetric);return{hazardMetric:hazardMetric,computeLongIdleTaskHazard:computeLongIdleTaskHazard};});'use strict';tr.exportTo('tr.metrics.sh',function(){var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var unitlessNumber_smallerIsBetter=tr.v.Unit.byName.unitlessNumber_smallerIsBetter;var MMAPS_METRICS={'overall_pss':{path:[],byteStat:'proportionalResident'},'private_dirty':{path:[],byteStat:'privateDirtyResident'},'java_heap':{path:['Android','Java runtime','Spaces'],byteStat:'proportionalResident'},'ashmem':{path:['Android','Ashmem'],byteStat:'proportionalResident'},'native_heap':{path:['Native heap'],byteStat:'proportionalResident'}};var LEVEL_OF_DETAIL_NAMES=new Map();LEVEL_OF_DETAIL_NAMES.set(LIGHT,'light');LEVEL_OF_DETAIL_NAMES.set(DETAILED,'detailed');var MEMORY_NUMERIC_BUILDER_MAP=new WeakMap();MEMORY_NUMERIC_BUILDER_MAP.set(unitlessNumber_smallerIsBetter,tr.v.NumericBuilder.createLinear(tr.v.Unit.byName.unitlessNumber_smallerIsBetter,tr.b.Range.fromExplicitRange(0,20),20));MEMORY_NUMERIC_BUILDER_MAP.set(sizeInBytes_smallerIsBetter,new tr.v.NumericBuilder(sizeInBytes_smallerIsBetter,0).addBinBoundary(1024).addExponentialBins(16*1024*1024*1024,4*24));function memoryMetric(valueList,model){addGeneralMemoryDumpValues(valueList,model);addDetailedMemoryDumpValues(valueList,model);addMemoryDumpCountValues(valueList,model);}
-memoryMetric.prototype={__proto__:Function.prototype};function addGeneralMemoryDumpValues(valueList,model){addPerProcessNameMemoryDumpValues(model.globalMemoryDumps,function(processDump,addProcessScalar){addProcessScalar('process_count',new ScalarNumeric(unitlessNumber_smallerIsBetter,1));if(processDump.memoryAllocatorDumps===undefined)
-return;processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump){addProcessScalar('allocator_'+rootAllocatorDump.name,rootAllocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]);addProcessScalar('allocated_objects_'+rootAllocatorDump.name,rootAllocatorDump.numerics['allocated_objects_size']);});var memtrackDump=processDump.getMemoryAllocatorDumpByFullName('gpu/android_memtrack');if(memtrackDump!==undefined){memtrackDump.children.forEach(function(memtrackChildDump){addProcessScalar('android_memtrack_'+memtrackChildDump.name,memtrackChildDump.numerics['memtrack_pss']);});}},valueList,model);}
-function addDetailedMemoryDumpValues(valueList,model){var heavyGlobalMemoryDumps=model.globalMemoryDumps.filter(g=>g.levelOfDetail===DETAILED);addPerProcessNameMemoryDumpValues(heavyGlobalMemoryDumps,function(processDump,addProcessScalar){tr.b.iterItems(MMAPS_METRICS,function(metricName,metricSpec){var node=getDescendantVmRegionClassificationNode(processDump.vmRegions,metricSpec.path);var value=node?(node.byteStats[metricSpec.byteStat]||0):0;addProcessScalar('mmaps_'+metricName,new ScalarNumeric(sizeInBytes_smallerIsBetter,value));});},valueList,model);}
-function getDescendantVmRegionClassificationNode(node,path){for(var i=0;i<path.length;i++){if(node===undefined)
-break;node=tr.b.findFirstInArray(node.children,c=>c.title===path[i]);}
-return node;}
-function addMemoryDumpCountValues(valueList,model){var levelOfDetailNameToDumpCount={'total':0};LEVEL_OF_DETAIL_NAMES.forEach(function(levelOfDetailName){levelOfDetailNameToDumpCount[levelOfDetailName]=0;});model.globalMemoryDumps.forEach(function(globalDump){levelOfDetailNameToDumpCount.total++;var levelOfDetailName=LEVEL_OF_DETAIL_NAMES.get(globalDump.levelOfDetail);if(!(levelOfDetailName in levelOfDetailNameToDumpCount))
-return;levelOfDetailNameToDumpCount[levelOfDetailName]++;});tr.b.iterItems(levelOfDetailNameToDumpCount,function(levelOfDetailName,levelOfDetailDumpCount){valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'memory_dump_count_'+levelOfDetailName,new ScalarNumeric(unitlessNumber_smallerIsBetter,levelOfDetailDumpCount)));});}
-function addPerProcessNameMemoryDumpValues(globalDumps,customProcessDumpValueExtractor,valueList,model){var timeToProcessNameToValueNameToScalar=calculatePerProcessNameMemoryDumpValues(globalDumps,customProcessDumpValueExtractor);injectTotalsIntoPerProcessNameMemoryDumpValues(timeToProcessNameToValueNameToScalar);reportPerProcessNameMemoryDumpValues(timeToProcessNameToValueNameToScalar,valueList,model);}
-function calculatePerProcessNameMemoryDumpValues(globalDumps,customProcessDumpValueExtractor){return globalDumps.map(function(globalDump){var processNameToValueNameToScalar={};tr.b.iterItems(globalDump.processMemoryDumps,function(_,processDump){var rawProcessName=processDump.process.name||'unknown';var processName=rawProcessName.toLowerCase().replace(' ','_');var valueNameToScalar=processNameToValueNameToScalar[processName];if(valueNameToScalar===undefined)
-processNameToValueNameToScalar[processName]=valueNameToScalar={};customProcessDumpValueExtractor(processDump,function addProcessScalar(name,processDumpScalar){if(processDumpScalar===undefined)
-return;var processNameSumScalar=valueNameToScalar[name];if(processNameSumScalar===undefined){valueNameToScalar[name]=processNameSumScalar=new ScalarNumeric(processDumpScalar.unit,processDumpScalar.value);}else{if(processDumpScalar.unit!==processNameSumScalar.unit){throw new Error('Multiple units provided for value \''+
-name+'\' of \''+processName+'\' processes: '+
-processNameSumScalar.unit.unitName+' and '+
-processDumpScalar.unit.unitName);}
-processNameSumScalar.value+=processDumpScalar.value;}});});return processNameToValueNameToScalar;});}
-function injectTotalsIntoPerProcessNameMemoryDumpValues(timeToProcessNameToValueNameToScalar){timeToProcessNameToValueNameToScalar.forEach(function(processNameToValueNameToScalar){var valueNameToProcessNameToScalar=tr.b.invertArrayOfDicts(tr.b.dictionaryValues(processNameToValueNameToScalar));processNameToValueNameToScalar.total=tr.b.mapItems(valueNameToProcessNameToScalar,function(valueName,perProcessScalars){var unit=tr.b.findFirstInArray(perProcessScalars).unit;var value=perProcessScalars.reduce(function(accumulator,scalar){if(scalar===undefined)
-return accumulator;if(scalar.unit!==unit){throw new Error('Multiple units provided for value \''+
-valueName+'\' of different processes: '+
-unit.unitName+' and '+scalar.unit.unitName);}
-return accumulator+scalar.value;},0);return new ScalarNumeric(unit,value);});});}
-function reportPerProcessNameMemoryDumpValues(timeToProcessNameToValueNameToScalar,valueList,model){var processNameToTimeToValueNameToScalar=tr.b.invertArrayOfDicts(timeToProcessNameToValueNameToScalar);tr.b.iterItems(processNameToTimeToValueNameToScalar,function(processName,timeToValueNameToScalar){var valueNameToTimeToScalar=tr.b.invertArrayOfDicts(timeToValueNameToScalar);tr.b.iterItems(valueNameToTimeToScalar,function(valueName,timeToScalar){valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'memory_'+valueName+'_'+processName,mergeScalarsIntoNumeric(timeToScalar)));});});}
-function mergeScalarsIntoNumeric(scalars){var unit=tr.b.findFirstInArray(scalars).unit;var numeric=MEMORY_NUMERIC_BUILDER_MAP.get(unit).build();for(var i=0;i<scalars.length;i++){var scalar=scalars[i];numeric.add(scalar===undefined?0:scalar.value);}
-return numeric;}
-tr.metrics.MetricRegistry.register(memoryMetric);return{memoryMetric:memoryMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function SystemHealthMetrics(valueList,model){tr.metrics.sh.responsivenessMetric(valueList,model);tr.metrics.sh.EfficiencyMetric(valueList,model);tr.metrics.sh.hazardMetric(valueList,model);}
-SystemHealthMetrics.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(SystemHealthMetrics);return{SystemHealthMetrics:SystemHealthMetrics};});'use strict';tr.exportTo('tr.metrics',function(){function tracingMetric(valueList,model){if(!model.stats.hasEventSizesinBytes){throw new Error('Model stats does not have event size information. '+'Please enable ImportOptions.trackDetailedModelStats.');}
-var eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort(function(a,b){return a.timeInterval-b.timeInterval;});var maxEventCountPerSec=0;var maxEventBytesPerSec=0;var totalTraceBytes=0;var WINDOW_SIZE=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);var runningEventNumPerSec=0;var runningEventBytesPerSec=0;var start=0;var end=0;while(end<eventStats.length){var startEventStats=eventStats[start];var endEventStats=eventStats[end];var timeWindow=endEventStats.timeInterval-startEventStats.timeInterval;if(timeWindow>=WINDOW_SIZE){runningEventNumPerSec-=startEventStats.numEvents;runningEventBytesPerSec-=startEventStats.totalEventSizeinBytes;start++;continue;}
-runningEventNumPerSec+=endEventStats.numEvents;if(maxEventCountPerSec<runningEventNumPerSec)
-maxEventCountPerSec=runningEventNumPerSec;runningEventBytesPerSec+=endEventStats.totalEventSizeinBytes;if(maxEventBytesPerSec<runningEventBytesPerSec)
-maxEventBytesPerSec=runningEventBytesPerSec;totalTraceBytes+=endEventStats.totalEventSizeinBytes;end++;}
-var stats=model.stats.allTraceEventStats;var categoryStatsMap=new Map();var categoryStats=[];for(var i=0;i<stats.length;i++){var categoryStat=categoryStatsMap.get(stats[i].category);if(categoryStat===undefined){categoryStat={category:stats[i].category,totalEventSizeinBytes:0};categoryStatsMap.set(stats[i].category,categoryStat);categoryStats.push(categoryStat);}
-categoryStat.totalEventSizeinBytes+=stats[i].totalEventSizeinBytes;}
-var maxCategoryStats=categoryStats.reduce(function(a,b){return a.totalEventSizeinBytes<b.totalEventSizeinBytes?b:a;});var maxEventBytesPerCategory=maxCategoryStats.totalEventSizeinBytes;var maxCategoryName=maxCategoryStats.category;var maxEventCountPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.unitlessNumber_smallerIsBetter,maxEventCountPerSec);var maxEventBytesPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,maxEventBytesPerSec);var totalTraceBytesValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,totalTraceBytes);var diagnostics={category_with_max_event_size:{name:maxCategoryName,size_in_bytes:maxEventBytesPerCategory}};valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Total trace size in bytes',totalTraceBytesValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max number of events per second',maxEventCountPerSecValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max event size in bytes per second',maxEventBytesPerSecValue,undefined,undefined,diagnostics));}
-tracingMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric:tracingMetric};});'use strict';tr.exportTo('tr.metrics.v8',function(){var DURATION_NUMERIC_BUILDER=tr.v.NumericBuilder.createLinear(tr.v.Unit.byName.timeDurationInMs_smallerIsBetter,tr.b.Range.fromExplicitRange(4,200),100);function computeExecuteMetrics(valueList,model){var cpuTotalExecution=DURATION_NUMERIC_BUILDER.build();var wallTotalExecution=DURATION_NUMERIC_BUILDER.build();var cpuSelfExecution=DURATION_NUMERIC_BUILDER.build();var wallSelfExecution=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.Execute',function(e){cpuTotalExecution.add(e.cpuDuration);wallTotalExecution.add(e.duration);cpuSelfExecution.add(e.cpuSelfTime);wallSelfExecution.add(e.selfTime);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_execution_cpu_total',cpuTotalExecution,{description:'cpu total time spent in script execution'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_execution_wall_total',wallTotalExecution,{description:'wall total time spent in script execution'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_execution_cpu_self',cpuSelfExecution,{description:'cpu self time spent in script execution'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_execution_wall_self',wallSelfExecution,{description:'wall self time spent in script execution'}));}
-function computeParseLazyMetrics(valueList,model){var cpuSelfParseLazy=DURATION_NUMERIC_BUILDER.build();var wallSelfParseLazy=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.ParseLazyMicroSeconds',function(e){cpuSelfParseLazy.add(e.cpuSelfTime);wallSelfParseLazy.add(e.selfTime);});model.findTopmostSlicesNamed('V8.ParseLazy',function(e){cpuSelfParseLazy.add(e.cpuSelfTime);wallSelfParseLazy.add(e.selfTime);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_parse_lazy_cpu_self',cpuSelfParseLazy,{description:'cpu self time spent performing lazy parsing'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_parse_lazy_wall_self',wallSelfParseLazy,{description:'wall self time spent performing lazy parsing'}));}
-function computeCompileFullCodeMetrics(valueList,model){var cpuSelfCompileFullCode=DURATION_NUMERIC_BUILDER.build();var wallSelfCompileFullCode=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.CompileFullCode',function(e){cpuSelfCompileFullCode.add(e.cpuSelfTime);wallSelfCompileFullCode.add(e.selfTime);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_compile_full_code_cpu_self',cpuSelfCompileFullCode,{description:'cpu self time spent performing compiling full code'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_compile_full_code_wall_self',wallSelfCompileFullCode,{description:'wall self time spent performing compiling full code'}));}
-function computeCompileIgnitionMetrics(valueList,model){var cpuSelfCompileIgnition=DURATION_NUMERIC_BUILDER.build();var wallSelfCompileIgnition=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.CompileIgnition',function(e){cpuSelfCompileIgnition.add(e.cpuSelfTime);wallSelfCompileIgnition.add(e.selfTime);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_compile_ignition_cpu_self',cpuSelfCompileIgnition,{description:'cpu self time spent in compile ignition'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_compile_ignition_wall_self',wallSelfCompileIgnition,{description:'wall self time spent in compile ignition'}));}
-function computeRecompileMetrics(valueList,model){var cpuTotalRecompileSynchronous=DURATION_NUMERIC_BUILDER.build();var wallTotalRecompileSynchronous=DURATION_NUMERIC_BUILDER.build();var cpuTotalRecompileConcurrent=DURATION_NUMERIC_BUILDER.build();var wallTotalRecompileConcurrent=DURATION_NUMERIC_BUILDER.build();var cpuTotalRecompileOverall=DURATION_NUMERIC_BUILDER.build();var wallTotalRecompileOverall=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.RecompileSynchronous',function(e){cpuTotalRecompileSynchronous.add(e.cpuDuration);wallTotalRecompileSynchronous.add(e.duration);cpuTotalRecompileOverall.add(e.cpuDuration);wallTotalRecompileOverall.add(e.duration);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_synchronous_cpu_total',cpuTotalRecompileSynchronous,{description:'cpu total time spent in synchronous recompilation'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_synchronous_wall_total',wallTotalRecompileSynchronous,{description:'wall total time spent in synchronous recompilation'}));model.findTopmostSlicesNamed('V8.RecompileConcurrent',function(e){cpuTotalRecompileConcurrent.add(e.cpuDuration);wallTotalRecompileConcurrent.add(e.duration);cpuTotalRecompileOverall.add(e.cpuDuration);wallTotalRecompileOverall.add(e.duration);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_concurrent_cpu_total',cpuTotalRecompileConcurrent,{description:'cpu total time spent in concurrent recompilation'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_concurrent_wall_total',wallTotalRecompileConcurrent,{description:'wall total time spent in concurrent recompilation'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_overall_cpu_total',cpuTotalRecompileOverall,{description:'cpu total time spent in synchronous or concurrent recompilation'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_recompile_overall_wall_total',wallTotalRecompileOverall,{description:'wall total time spent in synchronous or concurrent recompilation'}));}
-function computeOptimizeCodeMetrics(valueList,model){var cpuTotalOptimizeCode=DURATION_NUMERIC_BUILDER.build();var wallTotalOptimizeCode=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.OptimizeCode',function(e){cpuTotalOptimizeCode.add(e.cpuDuration);wallTotalOptimizeCode.add(e.duration);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_optimize_code_cpu_total',cpuTotalOptimizeCode,{description:'cpu total time spent in code optimization'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_optimize_code_wall_total',wallTotalOptimizeCode,{description:'wall total time spent in code optimization'}));}
-function computeDeoptimizeCodeMetrics(valueList,model){var cpuTotalDeoptimizeCode=DURATION_NUMERIC_BUILDER.build();var wallTotalDeoptimizeCode=DURATION_NUMERIC_BUILDER.build();model.findTopmostSlicesNamed('V8.DeoptimizeCode',function(e){cpuTotalDeoptimizeCode.add(e.cpuDuration);wallTotalDeoptimizeCode.add(e.duration);});valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_deoptimize_code_cpu_total',cpuTotalDeoptimizeCode,{description:'cpu total time spent in code deoptimization'}));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'v8_deoptimize_code_wall_total',wallTotalDeoptimizeCode,{description:'wall total time spent in code deoptimization'}));}
-function executionMetric(valueList,model){computeExecuteMetrics(valueList,model);computeParseLazyMetrics(valueList,model);computeCompileIgnitionMetrics(valueList,model);computeCompileFullCodeMetrics(valueList,model);computeRecompileMetrics(valueList,model);computeOptimizeCodeMetrics(valueList,model);computeDeoptimizeCodeMetrics(valueList,model);}
-executionMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric:executionMetric};});'use strict';tr.exportTo('tr.metrics.v8',function(){function V8Metrics(valueList,model){tr.metrics.v8.V8ExecutionMetric(valueList,model);}
-V8Metrics.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(V8Metrics);return{V8Metrics:V8Metrics};});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
-if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
-valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
-var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
-return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,isLowerBound){this.title=title;var dimensions=title.length;this.children=new Array(dimensions);for(var i=0;i<dimensions;i++)
-this.children[i]=new Map();this.total=0;this.self=0;this.isLowerBound=!!isLowerBound;}
-MultiDimensionalViewNode.prototype={get subRows(){return tr.b.mapValues(this.children[0]);}};var MultiDimensionalViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};function MultiDimensionalViewBuilder(dimensions){if(dimensions<0)
-throw new Error('Dimensions must be non-negative');this.dimensions_=dimensions;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.maxDimensionDepths_=new Array(dimensions);for(var d=0;d<dimensions;d++)
-this.maxDimensionDepths_[d]=0;}
-MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.prototype={addPath:function(path,value,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
-if(path.length!==this.dimensions_)
-throw new Error('Path must be '+this.dimensions_+'-dimensional');var node=this.buildRoot_;for(var d=0;d<path.length;d++){var singleDimensionPath=path[d];var singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(var i=0;i<singleDimensionPathLength;i++)
-node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}
-switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:node.self+=value;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:node.total+=value;break;default:throw new Error('Invalid value kind: '+valueKind);}
-node.isLowerBound=false;},buildView:function(viewType){switch(viewType){case MultiDimensionalViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView:function(){if(this.topDownTreeViewRoot_===undefined){var treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
-return this.topDownTreeViewRoot_;},buildTopDownHeavyView:function(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
-return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView:function(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
-return this.bottomUpHeavyViewNode_;},createRootNode_:function(){return new MultiDimensionalViewNode(new Array(this.dimensions_),true);},getOrCreateChildNode_:function(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_)
-throw new Error('Invalid dimension');var dimensionChildren=parentNode.children[dimension];var childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined)
-return childNode;var childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,true);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_:function(node,firstDimensionToSetUp){for(var d=firstDimensionToSetUp;d<this.dimensions_;d++){var currentDimensionChildTitles=new Set(node.children[d].keys());for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){for(var previousDimensionGrandChildTitle of
-previousDimensionChildNode.children[d].keys()){currentDimensionChildTitles.add(previousDimensionGrandChildTitle);}}}
-for(var currentDimensionChildTitle of currentDimensionChildTitles){var currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){var previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
-this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_:function(node,firstDimensionToFinalize,dimensionalSelfSumsMap){var dimensionalSelfSums=new Array(this.dimensions_);var maxChildResidualSum=0;var nodeSelfSum=node.self;for(var d=0;d<this.dimensions_;d++){var childResidualSum=0;for(var childNode of node.children[d].values()){if(d>=firstDimensionToFinalize)
-this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);var childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);nodeSelfSum+=childNodeSelfSums[d];var residual=childNode.total-childNodeSelfSums[this.dimensions_-1];childResidualSum+=residual;}
-dimensionalSelfSums[d]=nodeSelfSum;maxChildResidualSum=Math.max(maxChildResidualSum,childResidualSum);}
-node.total=Math.max(node.total,nodeSelfSum+maxChildResidualSum);if(dimensionalSelfSumsMap.has(node))
-throw new Error('Internal error: Node finalized more than once');dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_:function(treeViewNodeHandler){var treeViewRoot=this.buildTopDownTreeView();var heavyViewRoot=this.createRootNode_();heavyViewRoot.total=treeViewRoot.total;heavyViewRoot.self=treeViewRoot.self;heavyViewRoot.isLowerBound=treeViewRoot.isLowerBound;var recursionDepthTrackers=new Array(this.dimensions_);for(var d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
-this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(var d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){var treeViewChildren=treeViewParentNode.children[currentDimension];var recursionDepthTracker=recursionDepthTrackers[currentDimension];for(var treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;var dimensionTitle=treeViewChildNode.title[currentDimension];var heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);heavyViewChildNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
-heavyViewChildNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(var treeViewGrandChildNode of
-treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var bottomIndex=recursionDepthTracker.bottomIndex;var topIndex=recursionDepthTracker.topIndex;var firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;var viewNodePath=recursionDepthTracker.viewNodePath;var trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;var heavyViewDescendantNode=heavyViewParentNode;for(var i=bottomIndex;i<topIndex;i++){var treeViewAncestorNode=viewNodePath[i];var dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);var currentDimensionRecursive=i<firstNonRecursiveIndex;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;heavyViewDescendantNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
-heavyViewDescendantNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
-RecursionDepthTracker.prototype={push:function(viewNode){if(this.bottomIndex===0)
-throw new Error('Cannot push to a full tracker');var title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;var childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
-var maxLengths=zFunction(this.titlePath,this.bottomIndex);var recursionDepth=0;for(var i=0;i<maxLengths.length;i++)
-recursionDepth=Math.max(recursionDepth,maxLengths[i]);childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop:function(){if(this.bottomIndex===this.topIndex)
-throw new Error('Cannot pop from an empty tracker');this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_:function(recursionDepth,parent){return{recursionDepth:recursionDepth,parent:parent,children:new Map()};}};function zFunction(list,startIndex){var n=list.length-startIndex;if(n===0)
-return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
-maxLength=Math.min(right-i+1,z[i-left]);else
-maxLength=0;while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
-if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
-z[i]=maxLength;}
-return z;}
-return{MultiDimensionalViewBuilder:MultiDimensionalViewBuilder,MultiDimensionalViewType:MultiDimensionalViewType,MultiDimensionalViewNode:MultiDimensionalViewNode,RecursionDepthTracker:RecursionDepthTracker,zFunction:zFunction};});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var RIGHTWARDS_ARROW=String.fromCharCode(8594);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
-TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var contexts=row.contexts;if(contexts===undefined||contexts.length===0)
-return formattedTitle;var firstContext=contexts[0];var lastContext=contexts[contexts.length-1];var changeDefinedContextCount=0;for(var i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined))
-changeDefinedContextCount++;}
-var color=undefined;var prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
-if(changeDefinedContextCount>1){color='purple';}
-if(color===undefined&&prefix===undefined)
-return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
-if(color!==undefined)
-titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.aggregationMode=aggregationMode;}
-MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,rules){var cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)
-return;var fieldCells=row[cellKey];if(fieldCells!==undefined){tr.b.iterItems(fieldCells,function(fieldName,fieldCell){if(fieldCell===undefined||fieldCell.fields===undefined)
-return;cellNames.add(fieldName);});}
-var subRows=row.subRows;if(subRows!==undefined)
-gatherCellNames(subRows);});}
-gatherCellNames(rows);var positions=[];cellNames.forEach(function(cellName){var cellPath=[cellKey,cellName];var matchingRule=MemoryColumn.findMatchingRule(cellName,rules);var constructor=matchingRule.columnConstructor;var column=new constructor(cellName,cellPath,aggregationMode);positions.push({importance:matchingRule.importance,column:column});});positions.sort(function(a,b){if(a.importance===b.importance)
-return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});return positions.map(function(position){return position.column});};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(var i=0;i<rules.length;i++){var rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition))
-return rule;}
-return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)
-return true;if(typeof(condition)==='string')
-return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell:function(row){var cell=row;var cellPath=this.cellPath;for(var i=0;i<cellPath.length;i++){if(cell===undefined)
-return undefined;cell=cell[cellPath[i]];}
-return cell;},aggregateCells:function(row,subRows){},fields:function(row){var cell=this.cell(row);if(cell===undefined)
-return undefined;return cell.fields;},value:function(row){var fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))
-return'';var contexts=row.contexts;var color=this.color(fields,contexts);var infos=[];this.addInfos(fields,contexts,infos);var formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0)
-return formattedFields;var fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';infoEl.textContent=info.icon;if(info.color!==undefined)
-infoEl.style.color=info.color;infoEl.title=info.message;fieldEl.appendChild(infoEl);},this);if(color!==undefined)
-fieldEl.style.color=color;return fieldEl;},hasAllRelevantFieldsUndefined:function(fields){if(fields===undefined)
-return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color:function(fields,contexts){return undefined;},formatFields:function(fields){if(fields.length===1)
-return this.formatSingleField(fields[0]);else
-return this.formatMultipleFields(fields);},formatSingleField:function(field){throw new Error('Not implemented');},formatMultipleFields:function(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff:function(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax:function(fields){return this.formatSingleField(this.getMaxField(fields));},cmp:function(rowA,rowB){var fieldsA=this.fields(rowA);var fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length)
-throw new Error('Different number of fields');var undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);var undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)
-return 0;if(undefinedA)
-return-1;if(undefinedB)
-return 1;return this.compareFields(fieldsA,fieldsB);},compareFields:function(fieldsA,fieldsB){if(fieldsA.length===1)
-return this.compareSingleFields(fieldsA[0],fieldsB[0]);else
-return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields:function(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields:function(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff:function(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax:function(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField:function(fields){return fields.reduce(function(accumulator,field){if(field===undefined)
-return accumulator;if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
-return accumulator;}.bind(this),undefined);},addInfos:function(fields,contexts,infos){},getImportance:function(importanceRules){if(importanceRules.length===0)
-return 0;var matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined)
-return matchingRule.importance;var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++)
-minImportance=Math.min(minImportance,importanceRules[i].importance);return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField:function(string){return string;},formatMultipleFieldsDiff:function(firstString,lastString){if(firstString===undefined){var spanEl=tr.ui.b.createSpan({color:'red'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('+'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){var spanEl=tr.ui.b.createSpan({color:'green'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('-'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}else{var spanEl=tr.ui.b.createSpan({color:'DarkOrange'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}},compareSingleFields:function(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff:function(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined)
-return 1;if(firstStringA!==undefined&&firstStringB===undefined)
-return-1;if(firstStringA===undefined&&firstStringB===undefined)
-return this.compareSingleFields(lastStringA,lastStringB);if(lastStringA===undefined&&lastStringB!==undefined)
-return-1;if(lastStringA!==undefined&&lastStringB===undefined)
-return 1;if(lastStringA===undefined&&lastStringB===undefined)
-return this.compareSingleFields(firstStringB,firstStringA);var areStringsAEqual=firstStringA===lastStringA;var areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)
-return 0;if(areStringsAEqual)
-return-1;if(areStringsBEqual)
-return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,aggregateCells:function(row,subRows){var subRowCells=subRows.map(this.cell,this);var hasDefinedSubRowNumeric=false;var timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)
-return;var subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)
-return;if(timestampCount===undefined)
-timestampCount=subRowNumerics.length;else if(timestampCount!==subRowNumerics.length)
-throw new Error('Sub-rows have different numbers of timestamps');if(hasDefinedSubRowNumeric)
-return;hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric)
-return;var cellPath=this.cellPath;var rowCell=row;for(var i=0;i<cellPath.length;i++){var nextStepName=cellPath[i];var nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1)
-nextStep={};else
-nextStep=new MemoryCell(undefined);rowCell[nextStepName]=nextStep;}
-rowCell=nextStep;}
-if(rowCell.fields===undefined){rowCell.fields=new Array(timestampCount);}else if(rowCell.fields.length!==timestampCount){throw new Error('Row has a different number of timestamps than sub-rows');}
-for(var i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)
-continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined)
-return undefined;return subRowCell.fields[i];}));}},formatSingleField:function(numeric){if(numeric===undefined)
-return'';return tr.v.ui.createScalarSpan(numeric);},formatMultipleFieldsDiff:function(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields:function(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff:function(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
-this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_:function(firstNumeric,lastNumeric){var definedNumeric=firstNumeric||lastNumeric;return new tr.v.ScalarNumeric(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_:function(firstNumeric,lastNumeric){var firstValue=firstNumeric===undefined?0:firstNumeric.value;var lastValue=lastNumeric===undefined?0:lastNumeric.value;var diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
-MemoryCell.extractFields=function(cell){if(cell===undefined)
-return undefined;return cell.fields;};var RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){var currentLevelRows=table.tableRows;var totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){var nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
-return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
-var nextLevelRows=new Array(nextLevelRowCount);var nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
-return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
-function aggregateTableRowCellsRecursively(row,columns,opt_predicate){var subRows=row.subRows;if(subRows===undefined||subRows.length===0)
-return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts))
-aggregateTableRowCells(row,subRows,columns);}
-function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))
-return;column.aggregateCells(row,subRows);});}
-function createCells(timeToValues,valueFieldsGetter){var fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter);return tr.b.mapItems(fieldNameToFields,function(fieldName,fields){return new tr.ui.analysis.MemoryCell(fields);});}
-function createWarningInfo(message){return{message:message,icon:String.fromCharCode(9888),color:'red'};}
-return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,StringMemoryColumn:StringMemoryColumn,NumericMemoryColumn:NumericMemoryColumn,MemoryCell:MemoryCell,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,createWarningInfo:createWarningInfo};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
-this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
-return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var RowDimension={ROOT:-1,STACK_FRAME:0,OBJECT_TYPE:1};var LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);var CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);function HeapDumpNodeTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
-HeapDumpNodeTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){var title=row.title;var dimension=row.dimension;switch(dimension){case RowDimension.ROOT:return title;case RowDimension.STACK_FRAME:case RowDimension.OBJECT_TYPE:return this.formatSubRow_(title,dimension);default:throw new Error('Invalid row dimension: '+row.dimension);}},cmp:function(rowA,rowB){if(rowA.dimension!==rowB.dimension)
-return rowA.dimension-rowB.dimension;return tr.ui.analysis.TitleColumn.prototype.cmp.call(this,rowA,rowB);},formatSubRow_:function(title,dimension){var titleEl=document.createElement('span');var symbolEl=document.createElement('span');var symbolColorName;if(dimension===RowDimension.STACK_FRAME){symbolEl.textContent=LATIN_SMALL_LETTER_F_WITH_HOOK;symbolEl.title='Stack frame';symbolColorName='heap_dump_stack_frame';}else{symbolEl.textContent=CIRCLED_LATIN_CAPITAL_LETTER_T;symbolEl.title='Object type';symbolColorName='heap_dump_object_type';}
-symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(symbolColorName);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.weight='bold';titleEl.appendChild(symbolEl);titleEl.appendChild(document.createTextNode(title));return titleEl;}};var COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.viewMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuildPane_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:case tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.visible=false;this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';this.$.info_bar.visible=this.heavyView;var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
-return undefined;var builder=new tr.b.MultiDimensionalViewBuilder(2);heapDump.entries.forEach(function(entry){var leafStackFrame=entry.leafStackFrame;var stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();var objectTypeName=entry.objectTypeName;var objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];builder.addPath([stackTracePath,objectTypeNamePath],entry.size,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);},this);return builder.buildView(this.viewMode);},this);},createRows_:function(stackFrameTrees){var definedHeapDump=tr.b.findFirstInArray(this.heapDumps);if(definedHeapDump===undefined)
-return[];var rootRowTitle=definedHeapDump.allocatorName;return[this.createHeapRowRecursively_(stackFrameTrees,RowDimension.ROOT,rootRowTitle)];},createHeapRowRecursively_:function(nodes,dimension,title){var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Size':new ScalarNumeric(sizeInBytes_smallerIsBetter,node.total)};});var row={dimension:dimension,title:title,contexts:nodes,cells:cells};var stackFrameSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.STACK_FRAME);var objectTypeSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.OBJECT_TYPE);var subRows=stackFrameSubRows.concat(objectTypeSubRows);if(subRows.length>0)
-row.subRows=subRows;return row;},createHeapDimensionSubRowsRecursively_:function(nodes,dimension){var dimensionGroupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){var childDict={};var displayedChildrenTotal=0;var hasDisplayedChildren=false;for(var child of node.children[dimension].values()){if(!this.heavyView&&child.isLowerBound)
-continue;childDict[child.title[dimension]]=child;displayedChildrenTotal+=child.total;hasDisplayedChildren=true;}
-if(!this.heavyView&&displayedChildrenTotal<node.total&&hasDisplayedChildren){var otherTitle=node.title.slice();otherTitle[dimension]='<other>';childDict['<other>']={title:otherTitle,total:node.total-displayedChildrenTotal,children:[new Map(),new Map()]};}
-return childDict;},this));return dimensionGroupedChildNodes.map(function(subRowNodes){var subRowTitle=tr.b.findFirstInArray(subRowNodes).title[dimension];return this.createHeapRowRecursively_(subRowNodes,dimension,subRowTitle);},this);},createColumns_:function(rows){var titleColumn=new HeapDumpNodeTitleColumn('Stack frame');titleColumn.width='500px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_,COLUMN_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);var columns=[titleColumn].concat(numericColumns);return columns;}});return{RowDimension:RowDimension};});'use strict';tr.exportTo('tr.ui.analysis',function(){var SUBALLOCATION_CONTEXT=true;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;var LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);var RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);var EN_DASH=String.fromCharCode(0x2013);var CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
-AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
-return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){var entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
-entry.count++;return entry;}
-function SizeInfoMessageBuilder(){this.parts_=[];this.indent_=0;}
-SizeInfoMessageBuilder.prototype={append:function(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap:function(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText)
-this.append(emptyText);}else if(map.size===1){this.parts_.push(' ');var key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix)
-this.parts_.push('s');this.parts_.push(':');this.indent_++;for(var key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
-this.indent_--;}},appendImportanceRange:function(range){this.append(' (importance: ');if(range.min===range.max)
-this.append(range.min);else
-this.append(range.min,EN_DASH,range.max);this.append(')');},appendSizeIfDefined:function(size){if(size!==undefined)
-this.append(' (',tr.v.Unit.byName.sizeInBytes.format(size),')');},appendSomeTimestampsQuantifier:function(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build:function(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
-return;var ownerNameToEntry=new Map();var ownedNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;dump.ownedBy.forEach(function(ownerLink){var ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);var ownedLink=dump.owns;if(ownedLink!==undefined){var ownedDump=ownedLink.target;var ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);var sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){var sharerDump=sharerLink.source;if(sharerDump===dump)
-return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
-if(ownerNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
-if(ownedNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);var ownedCount=ownedEntry.count;if(ownedCount<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_:function(map,dump,link,opt_withSharerNameToEntry){var entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.Range();if(opt_withSharerNameToEntry)
-newEntry.sharerNameToEntry=new Map();});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-SizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
-return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_:function(numerics,memoryAllocatorDumps,infos){var siblingNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;var ownedBySiblingSizes=dump.ownedBySiblingSizes;for(var siblingDump of ownedBySiblingSizes.keys()){var siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1)
-newEntry.size=ownedBySiblingSizes.get(siblingDump);});}}
-if(siblingNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_:function(numerics,memoryAllocatorDumps,infos){var infoTypeToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
-for(var infoType of infoTypeToEntry.keys()){var entry=infoTypeToEntry.get(infoType);var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);var dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
-messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};var NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});var diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
-var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
-if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
-var row={title:title,fullNames:[fullName],contexts:dumps,numericCells:numericCells,diagnosticCells:diagnosticCells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
-if(subRows.length>0)
-row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
-var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
-var currentNode=nextNode;}
-var existingRow=currentNode.row;if(existingRow!==undefined){for(var i=0;i<suballocationRow.contexts.length;i++){var newContext=suballocationRow.contexts[i];if(newContext===undefined)
-continue;if(existingRow.contexts[i]!==undefined)
-throw new Error('Multiple suballocations with the same owner name');existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){var suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)
-return;tr.b.iterItems(suballocationCells,function(cellName,cell){if(cell===undefined)
-return;var fields=cell.fields;if(fields===undefined)
-return;var field=fields[i];if(field===undefined)
-return;var existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
-var existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
-existingCell.fields[i]=field;});});}
-existingRow.fullNames.push.apply(existingRow.fullNames,suballocationRow.fullNames);}else{currentNode.row=suballocationRow;}
-return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
-throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
-var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
-var contexts=new Array(subRows[0].contexts.length);for(var i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined)
-contexts[index]=SUBALLOCATION_CONTEXT;});}
-return{title:name,suballocation:true,contexts:contexts,subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'numericCells',this.aggregationMode_,NUMERIC_COLUMN_RULES);var diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'diagnosticCells',this.aggregationMode_,DIAGNOSTIC_COLUMN_RULES);var fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT:SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn:AllocatorDumpNameColumn,EffectiveSizeColumn:EffectiveSizeColumn,SizeColumn:SizeColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];var VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)
-return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
-function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
-return;if(row.subRows[0].rule===undefined){return;}
-row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
-Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_(this.vmRegions_);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_:function(timeToVmRegionTree){var is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)
-return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)
-return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow:function(timeToNode,is64BitAddress){var definedNode=tr.b.findFirstInArray(timeToNode);var childNodeIdToTimeToNode=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var children=node.children;if(children===undefined)
-return undefined;var childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)
-return;childMap[childNode.title]=childNode;});return childMap;}));var childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);var regionIdToTimeToRegion=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var regions=node.regions;if(regions===undefined)
-return undefined;return tr.b.arrayToDict(regions,function(region){return region.uniqueIdWithinProcess;});}));var regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);var subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows:subRows};},createRegionRow_:function(timeToRegion,is64BitAddress){var definedRegion=tr.b.findFirstInArray(timeToRegion);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_:function(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){var startAddress=region.startAddress;if(startAddress===undefined)
-return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_:function(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){var fields={};var sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new ScalarNumeric(sizeInBytes_smallerIsBetter,sizeInBytes);}
-var protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined)
-fields['Protection flags']=protectionFlags;tr.b.iterItems(BYTE_STAT_COLUMN_MAP,function(byteStatName,columnName){var byteStat=region.byteStats[byteStatName];if(byteStat===undefined)
-return;fields[columnName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});return fields;});},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells',undefined,CONSTANT_COLUMN_RULES);var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_,VARIABLE_COLUMN_RULES);var fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
-var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
-this.$.square.style.color='initial';else
-this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;var RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);var RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);var GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);var UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);var TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;var result=undefined;list.forEach(function(item,index){var value=fn.call(opt_this,item,index);if(value===undefined)
-return;if(result===undefined)
-result=new Array(list.length);result[index]=value;});return result;}
-function ProcessNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Process');}
-ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.contexts===undefined)
-return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-UsedMemoryColumn.COLOR=ColorScheme.getColorForReservedNameAsString('used_memory_column');UsedMemoryColumn.OLDER_COLOR=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},color:function(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
-return undefined;var vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
-return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)
-return undefined;return function(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var resettableValueCount=0;var nonResettableValueCount=0;for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;if(processMemoryDumps[i].arePeakResidentBytesResettable)
-resettableValueCount++;else
-nonResettableValueCount++;}
-if(resettableValueCount>0&&nonResettableValueCount>0){infos.push(tr.ui.analysis.createWarningInfo('Both resettable and '+'non-resettable peak RSS values were provided by the process'));}else if(resettableValueCount>0){infos.push({icon:RIGHTWARDS_ARROW_WITH_HOOK,message:'Peak RSS since previous memory dump.'});}else{infos.push({icon:RIGHTWARDS_ARROW_FROM_BAR,message:'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
-GREATER_THAN_OR_EQUAL_TO+' 4.0.'});}}};function ByteStatColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color:function(numerics,processMemoryDumps){if(processMemoryDumps===undefined)
-return UsedMemoryColumn.COLOR;var allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)
-return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues)
-return UsedMemoryColumn.OLDER_COLOR;else
-return UsedMemoryColumn.COLOR;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var olderValueCount=0;for(var i=0;i<numerics.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
-if(olderValueCount===0)
-return;var infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var heapDumpCount=0;for(var i=0;i<processMemoryDumps.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)
-continue;var heapDumps=processMemoryDump.heapDumps;if(heapDumps===undefined)
-continue;if(heapDumps[this.name]!==undefined)
-heapDumpCount++;}
-if(heapDumpCount===0)
-return;var infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
-return undefined;var memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
-return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)
-return undefined;var heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)
-return undefined;return pmd.heapDumps[this.name];},this);return function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
-TracingColumn.COLOR=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color:function(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
-return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
-return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
-return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
-return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);var footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};var totals=dump.totals;if(totals!==undefined){tr.b.iterItems(UsedMemoryColumn.TOTALS_MAP,function(totalName,cellName){var total=totals[totalName];if(total===undefined)
-return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,total);});var platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){tr.b.iterItems(platformSpecific,function(name,size){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){name=name.substring(0,name.length-
-PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX.length);}
-name=name.replace('_',' ').trim();name=name.charAt(0).toUpperCase()+name.slice(1);sizes[name]=new ScalarNumeric(sizeInBytes_smallerIsBetter,size);});}}
-var vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){tr.b.iterItems(UsedMemoryColumn.BYTE_STAT_MAP,function(byteStatName,cellName){var byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)
-return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});}
-return sizes;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){var memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)
-return undefined;var sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){var rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric!==undefined)
-sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});return{title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows,columns){if(rows.length<=1)
-return[];var totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn();titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_,UsedMemoryColumn.RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,AllocatorColumn.RULES);var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
-selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
-this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
-return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
-return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
-return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn:ProcessNameColumn,UsedMemoryColumn:UsedMemoryColumn,PeakMemoryColumn:PeakMemoryColumn,ByteStatColumn:ByteStatColumn,AllocatorColumn:AllocatorColumn,TracingColumn:TracingColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
-var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
-(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
-displayStyle='none';else
-displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
-return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
-throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane must be a child of the pane container');}
-while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
-throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
-if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
-return;var pane=paneBuilder();if(!pane)
-return;if(!(pane instanceof HTMLElement))
-throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
-this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
-return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
-selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
-return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
-return;if(containerNames.length>1)
-this.buildViewForMultipleContainerNames_();else
-this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=tr.b.dictionaryValues(this.dumpsByContainerName_)[0];var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
-return this.singleDumpValue_(row);else
-return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
-(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
-rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-layout-tree-sub-view',{set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_:function(){this.$.content.textContent='';if(!this.currentSelection_)
-return;var columns=[{title:'Tag/Name',value:function(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value:function(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value:function(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value:function(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value:function(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value:function(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value:function(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value:function(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value:function(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value:function(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value:function(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value:function(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value:function(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value:function(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value:function(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value:function(layoutObject){if(layoutObject.tableRow===undefined)
-return'';return layoutObject.tableRow;}},{title:'col',value:function(layoutObject){if(layoutObject.tableCol===undefined)
-return'';return layoutObject.tableCol;}},{title:'rowSpan',value:function(layoutObject){if(layoutObject.tableRowSpan===undefined)
-return'';return layoutObject.tableRowSpan;}},{title:'colSpan',value:function(layoutObject){if(layoutObject.tableColSpan===undefined)
-return'';return layoutObject.tableColSpan;}},{title:'address',value:function(layoutObject){return layoutObject.id.toString(16);}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
-hasRange=true;else
-hasRange=false;rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
-this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
-return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
-return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
-if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
-if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
-this.selfTime_+=this.events[i].selfTime;}}
-return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
-return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
-return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
-return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
-return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
-return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
-return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
-if(untotallableArgs[argName]){continue;}
-if(totalledArgs[argName]===undefined)
-totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
-this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
-hasCpuData=true;if(row.cpuSelfTime!==undefined)
-hasCpuData=true;if(row.numAlerts)
-hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
-return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
-throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
-this.showTotals_=config.showTotals;else
-this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
-this.eventsHaveDuration_=config.eventsHaveDuration;else
-this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
-this.eventsHaveSubRows_=config.eventsHaveSubRows;else
-this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
-eventsByTitle=this.eventsByTitle_;else
-eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
-var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
-this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
-var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
-title=this.selection_[0].title;else
-title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
-hasCpuData=true;if(summary.cpuSelfTime!==undefined)
-hasCpuData=true;var colWidthPercentage;if(hasCpuData)
-colWidthPercentage='20%';else
-colWidthPercentage='33.3333%';var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
-var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
-if(hasTotal)
-return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];};}
-columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
-return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
-obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
-Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
-throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
-return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
-FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
-return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
-selection.push(fs.event);}
-return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
-selection.push(fs.event);}
-return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
-selection.push(fs.event);}
-return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
-typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
-linkEl.setSelectionAndContent(row.selection,row.name);else
-linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
-if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
-return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
-events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
-events.push(event.startSlice);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
-return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
-if(lengthBefore===events.length)
-return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
-task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
-return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
-return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
-return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
-return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
-return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
-table.tableRows=[];else
-table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)
-return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
-return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
-return selection;return undefined;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
-return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
-return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (W) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
-return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
-content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
-if(lastVSyncTimestamp===undefined)
-return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power/1000;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.v.Unit.byName.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
-return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
-this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
-return'N/A';var energyInMillijoules=this.getEnergyConsumed()*1000;var durationInSeconds=this.samples.bounds.duration/1000;return energyInMillijoules/durationInSeconds;},getEnergyConsumed:function(){if(this.samples.length<2)
-return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value:function(row){return tr.v.ui.createScalarSpan(row.power/1000,{unit:tr.v.Unit.byName.powerInWatts});}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){var SAMPLE_TYPE={COMPILER:'compiler',EXTERNAL:'external',GC:'gc',NATIVEV8:'[native v8]',OTHER:'other',UNKNOWN:'unknown'};Polymer('tr-ui-a-multi-sample-sub-view',{created:function(){this.viewOption_=undefined;this.selection_=undefined;},ready:function(){var viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]);this.$.control.appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var builder=new tr.b.MultiDimensionalViewBuilder(1);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){builder.addPath([sample.getUserFriendlyStackTrace().reverse()],1,tr.b.MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},processTypedSampleRow_:function(row){var title=row.title[0];switch(title){case SAMPLE_TYPE.COMPILER:case SAMPLE_TYPE.EXTERNAL:case SAMPLE_TYPE.GC:case SAMPLE_TYPE.OTHER:row.functionName=title;row.fileName='N/A';return true;case SAMPLE_TYPE.UNKNOWN:row.functionName=SAMPLE_TYPE.UNKNOWN;row.fileName=SAMPLE_TYPE.UNKNOWN;return true;default:return false;}},processNativeV8SampleRow_:function(row){var title=row.title[0];if(!title.includes(SAMPLE_TYPE.NATIVEV8))
-return false;var arr=title.split(SAMPLE_TYPE.NATIVEV8);row.functionName=arr[0].trim();if(row.functionName==='')
-row.functionName='(anonymous function)';row.fileName=SAMPLE_TYPE.NATIVEV8;var fileNameSuffix=arr[1].trim();if(fileNameSuffix!=='')
-row.fileName+=' '+fileNameSuffix;return true;},processGeneralSampleRow_:function(row){var title=row.title[0];var idx=title.lastIndexOf(' ');if(idx===-1){row.functionName=title;row.fileName='unknown';return;}
-var prefix=title.substr(0,idx);var suffix=title.substr(idx+1);if(suffix.startsWith('v8/')){row.functionName=suffix;row.fileName='unknown';}else if(suffix===''){row.functionName=prefix;row.fileName='unknown';}else if(prefix===''){row.functionName='(anonymous function)';row.fileName=suffix.substr(suffix.lastIndexOf('/')+1);}else{row.functionName=prefix;row.fileName=suffix.substr(suffix.lastIndexOf('/')+1);}},processSampleRows_:function(rows){rows.forEach(function(row){if(!this.processTypedSampleRow_(row)&&!this.processNativeV8SampleRow_(row))
-this.processGeneralSampleRow_(row);this.processSampleRows_(row.subRows);},this);},updateContents_:function(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
-var samplingData=this.createSamplingSummary_(this.selection,this.viewOption);var columns=[this.createPercentColumn_('Total',samplingData.total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',samplingData.total),this.createSamplesColumn_('Self'),{title:'Function Name',value:function(row){return row.functionName;},width:'150px',cmp:function(a,b){return a.functionName.localeCompare(b.functionName);},showExpandButtons:true},{title:'Location',value:function(row){return row.fileName;},width:'250px',cmp:function(a,b){return a.fileName.localeCompare(b.fileName);}}];this.processSampleRows_(samplingData.subRows);this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_:function(title,samplingDataTotal){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/samplingDataTotal;var span=document.createElement('tr-v-ui-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.v.Unit.byName.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
-this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
-return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
-return false;return true;}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-user-expectation-related-samples-table',{ready:function(){this.samples_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
-typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
-linkEl.setSelectionAndContent(row.selection,row.name);else
-linkEl.selection=row.selection;return linkEl;}}];},hasRelatedSamples:function(){return(this.samples_&&this.samples_.length>0);},set selection(eventSet){this.samples_=[];var samples=new tr.model.EventSet;eventSet.forEach(function(ue){samples.addEventSet(ue.associatedSamples);}.bind(this));if(samples.length>0){this.samples_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected user expectation(s).',selection:samples});}
-this.updateContents_();},updateContents_:function(){var table=this.$.table;if(this.samples_&&this.samples_.length>0)
-table.tableRows=this.samples_.slice();else
-table.tableRows=[];table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples())
-this.$.events.style.display='';else
-this.$.events.style.display='none';},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
-shadowRoot.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.v.Unit.byName.timeDurationInMs);var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
-shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
-rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
-throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
-return false;if(this.$.content.children[0]instanceof
-tr.ui.analysis.ObjectInstanceView)
-return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
-throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
-instance.typeName+' '+
-instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
-instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
-instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
-html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
-return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
-return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
-throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
-var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
-this.$.relatedEvents.style.display='';else
-this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').setValueAndUnit(timeSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.v.Unit.byName.timeDurationInMs);var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
-cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
-cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
-var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';tr.exportTo('tr.metrics',function(){function ValueList(values){this.values_=[];if(values!==undefined)
-values.forEach(this.addValue,this);}
-ValueList.prototype={get valueDicts(){return this.values_.map(function(v){return v.asDict();});},getValuesWithName:function(name){return this.values_.filter(function(value){return value.name.indexOf(name)>-1;});},addValue:function(v){if(!(v instanceof tr.v.NumericValue)){var err=new Error('Tried to add value '+v+' which is non-Numeric');err.name='ValueError';throw err;}
-this.values_.push(v);if(v.numeric instanceof tr.v.Numeric){this.values_.push.apply(this.values_,ValueList.computeSummaryValuesForNumericValue(v));}}};ValueList.computeSummaryValuesForNumericValue=function(value){if(!(value instanceof tr.v.NumericValue&&value.numeric instanceof tr.v.Numeric))
-throw new Error('Tried to compute summary values for non-numeric');var canonicalUrl=value.canonicalUrl;var name=value.name;var n=value.numeric;var description=value.description;var sumNumeric=new tr.v.ScalarNumeric(n.unit,n.runningSum);var countNumeric=new tr.v.ScalarNumeric(tr.v.Unit.byName.unitlessNumber_smallerIsBetter,n.numValues);var avgNumeric=new tr.v.ScalarNumeric(n.unit,n.average);return[new tr.v.NumericValue(canonicalUrl,name+'_sum',sumNumeric,{description:description}),new tr.v.NumericValue(canonicalUrl,name+'_count',countNumeric,{description:description}),new tr.v.NumericValue(canonicalUrl,name+'_avg',avgNumeric,{description:description})];};return{ValueList:ValueList};});'use strict';Polymer('tr-ui-a-single-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.$.realView.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples())
-this.$.events.style.display='';else
-this.$.events.style.display='none';},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;},onCustomizeRows_:function(event){var ue=this.selection[0];var valueList=new tr.metrics.ValueList();function runMetric(metricInfo){try{metricInfo.constructor(valueList,ue.parentModel);}catch(failure){console.error(metricInfo,failure);}}
-tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(runMetric);var metricValues={};valueList.valueDicts.forEach(function(value){if(value.grouping_keys.userExpectationStableId!==ue.stableId)
-return;if((value.type!=='numeric')||(value.numeric.type!=='scalar'))
-return;metricValues[value.grouping_keys.name]=value.numeric;});for(var name in metricValues){event.rows.push({name:name,value:tr.v.ui.createScalarSpan(metricValues[name].value,{unit:tr.v.Unit.fromJSON(metricValues[name].unit)})});}
-if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.v.Unit.byName.timeDurationInMs})});}}});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
-this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
-this.$.tshh.style.display='';else
-this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
-return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
-var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
-if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
-if(contentTabId===undefined)
-return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
-ts.setAttribute('tabs-hidden',true);else
-ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
-child.removeAttribute('selected');else
-this.setSelectedTabById_(tabObject.id);}
-var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
-var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
-tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
-child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
-child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
-if(!tabObject)
-return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
-tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
-this.changeSelectedTabById_(tabObject.id);else
-this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
-this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
-this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
-if(changed)
-this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
-this.classList.add('tall-mode');else
-this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
-this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
-return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
-this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
-this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
-var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
-var tab;if(lastSelectedTabTagName)
-tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
-if(!tab)
-tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
-tagName=eventTypeInfo.metadata.singleViewElementName;else
-tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
-throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
-subView=previousSubView;else
-subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
-camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
-camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
-brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
-return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
-this.show();else
-this.close();},show:function(){if(this.isOpen)
-return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
-return;if(e.srcElement!==this.$.dialog)
-return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
-return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
-throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
-throw new Error('onClick must be provided');}
-this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
-task=operation;else
-task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
-return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
-if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
-return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
-this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
-return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
-return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
-return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
-ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
-ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
-return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
-return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
-return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
-if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
-if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
-ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
-var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
-if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
-ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
-a=newWorldX;else
-b=newWorldX;if(a<=b)
-ir.setMinAndMax(a,b);else
-ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
-ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
-var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
-var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
-modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
-return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimationDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimationDurationMs;else
-this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
-TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
-target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimationDurationMs;else
-this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
-TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
-target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
-return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].drawTrack(typesToDraw[idx]);}}
-var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
-tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
-if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
-return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
-return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
-return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
-break;if(item.selected!==selected)
-continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
-ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
-return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
-return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
-return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
-this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
-tracks.push(this.children[i]);}
-return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
-this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
-tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
-this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
-this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
-return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
-this.bounds.addValue(opt_min);if(opt_max!==undefined)
-this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
-throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
-return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
-return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
-if(!opt_config)
-return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
-return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
-if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
-ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
-value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
-return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
-if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
-this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
-var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
-extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
-var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
-var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
-var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
-transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
-var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
-this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
-var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
-break;}
-if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
-if(currentViewX<leftViewX){currentViewX=leftViewX;}}
-if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
-var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
-var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
-if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
-break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
-ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
-ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();}
-ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
-if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
-ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
-previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
-if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
-return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
-function selectPoint(point){point.addToSelection(selection);}
-tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
-return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
-return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
-var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
-axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
-return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
-return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
-existingValue=0;dstDict[key]=existingValue+value;});}
-function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
-return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
-return;var allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)
-return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
-return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
-function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
-return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
-function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
-return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
-function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
-if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
-return true;return false;});if(!containsVmRegions)
-return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var cumulativePss=pssBase;if(processMemoryDump!==undefined){var vmRegions=processMemoryDump.mostRecentVmRegions;if(vmRegions!==undefined)
-cumulativePss+=vmRegions.byteStats.proportionalResident||0;}
-points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
-function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
-function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
-return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
-return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
-this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
-ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
-continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
-objectsByKey[objectKey]=NONUNIQUE_KEY;}
-var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
-return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
-return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
-Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
-return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
-return ephemeralValue;return defaultValue;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
-return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
-return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
-throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
-this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
-var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
-return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
-FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
-return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
-return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
-e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
-this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
-this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
-if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
-if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
-this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
-var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
-continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
-this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
-return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
-return false;if(!a.length||!b.length)
-return false;if(a.length!=b.length)
-return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
-return false;}
-return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
-if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
-return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
-FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
-return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
-this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
-this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
-return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
-tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
-return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
-onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
-return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
-continue;if(filter.matchSlice(modelItem))
-selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
-return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
-return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
-ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
-var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
-currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
-var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
-return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
-for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
-return false;}
-return true;}
-return false;};var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
-if(!found)
-subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
-return;if(level===rows.length)
-rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
-return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
-return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
-slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
-ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
-return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
-continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
-if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
-subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
-insertedSlice.subSlices.push(slice);inserted=true;break;}}
-if(inserted)
-continue;subRows[0].push(slice);}
-return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
-return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
-this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
-this.appendChild(timeSlicesTrack);}
-if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
-this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
-this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
-return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
-return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
-h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
-this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
-return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
-return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
-return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
-return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
-this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
-return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
-instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
-snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
-continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
-continue;visibleInstances.push(instance);}
-if(visibleInstances.length===0)
-return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
-var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
-return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
-return false;var cpu=this.cpu_;if(cpu.slices.length)
-return true;if(cpu.samples&&cpu.samples.length)
-return true;if(tr.b.dictionaryLength(cpu.counters)>0)
-return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
-return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
-if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
-counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
-return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
-return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
-continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
-if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
-return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
-break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
-tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
-continue;draw=!draw;if(!draw)
-continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
-return;if(this.upperMode_)
-this.updateContentsForUpperMode_();else
-this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.userModel.expectations.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
-if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
-if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
-this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
-continue;this.appendChild(track);}
-this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
-this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
-this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
-return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
-tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
-return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
-return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
-return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
-this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
-break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
-ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
-ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
-ctx.restore();return;}
-ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
-continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
-return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
-var startSize=startBounds.left+startBounds.top+
-startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
-endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
-return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
-return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
-return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
-RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
-this.classList.remove('tall-mode');else
-this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
-this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
-continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
-var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
-var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
-tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
-ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
-return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
-textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
-var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
-displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
-textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
-ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
-ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
-throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
-this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
-var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
-return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
-return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
-return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;if(e.target!==this.rulerTrack_)
-return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
-var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
-return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
-return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
-var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
-smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
-return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
-return;}
-this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
-return;if(this.xNavStringMarker_)
-this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
-if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
-this.viewport_.interestRange.reset();else
-this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
-return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.v.Unit.byName.timeDurationInMs.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
-var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
-(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
-return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
-return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
-this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
-this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
-e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
-return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
-return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
-return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
-selection.addEventSet(previousSelection);}
-this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
-newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
-e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
-return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
-return Math.sqrt((xMin-xMax)*(xMin-xMax)+
-(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
-this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
-e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
-this.findPrevious();else
-this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
-this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
-this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
-var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
-Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
-Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
-return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
-return expected.test(value);else if(expected instanceof Function)
-return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
-FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
-return false;}
-return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
-return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
-FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1)
-throw new Error('not() must have exactly one subexpression');return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot:FilterNot};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
-return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
-return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
-return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
-FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
-FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
-return false;if(!this.subExpression)
-return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
-return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
-function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
-var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
-continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
-return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
-outputSelection.push(event);}
-if(!event.subSlices)
-return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
-return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
-return;e.preventDefault();var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
-return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
-if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}
-promptEl.scrollIntoView();},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
-historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
-this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
-return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
-throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
-panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
-throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
-this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
-this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
-return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
-return this.tabStrip_.children[i];}
-return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
-supported.reason;labelEl.style.display='none';}
-this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
-throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
-this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.v',function(){function GenericTable(items){if(items!==undefined)
-this.items=items;else
-this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.v.ui',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-v-ui-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.v.ui.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
-if(!(numbers instanceof Array))
-throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
-var ArrayOfNumbersSummaryModes=tr.v.ui.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
-value=tr.b.Statistics.mean(this.numbers_);else
-value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.v.ui',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
-return true;else if(value instanceof Number)
-return true;return false;}
-function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
-this.values=opt_values;else
-this.values=[];}
-function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
-GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
-return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
-return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
-if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-this.columnMode_=TEXT_COLUMN_MODE;return;}
-if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue))
-return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-if(this.columnMode_===NUMERIC_COLUMN_MODE)
-this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-v-ui-array-of-numbers-span');span.summaryMode=tr.v.ui.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
-if(fieldValue===undefined)
-return'-';if(fieldValue instanceof HTMLElement)
-return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
-return fieldValue;}};Polymer('tr-v-ui-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.v.GenericTable){this.items_=itemsOrGenericTable.items;}
-this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
-colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
-return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
-return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
-return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
-return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
-return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
-columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
-this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-v-ui-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},detached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
-return;this.preferredTimeDisplayMode_=v;tr.v.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
-hue='blue';else
-hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
-faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
-link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
-return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
-return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
-helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
-toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
-showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
-this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
-return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
-this.railScoreSpan_.model=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
-this.brushingStateController_.modelWillChange();}
-if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
-if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_)
-this.railScoreSpan_.model=model;this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
-if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
-importWarning.message);},this);}
-if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
-this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
-this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
-return;if(this.findCtl_.hasFocus)
-this.focus();else
-this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
-var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
-spc.rangeOfInterest=vr;if(this.railScoreSpan_&&this.model)
-this.railScoreSpan_.model=this.model;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
-VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR=new tr.b.Color(0,0,255);VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA=0.1;VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT=0.20;VSyncHighlighter.VSYNC_DENSITY_OPAQUE=0.10;VSyncHighlighter.VSYNC_DENSITY_RANGE=VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-
-VSyncHighlighter.VSYNC_DENSITY_OPAQUE;VSyncHighlighter.generateStripes=function(times,minTime,maxTime){if(times.length===0)
-return[];var stripes=[];var lowIndex=tr.b.findLowIndexInSortedArray(times,function(time){return time;},minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
-for(var i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){var left=i<lowIndex?minTime:times[i];var right=i+1>highIndex?maxTime:times[i+1];stripes.push([left,right]);}
-return stripes;}
-VSyncHighlighter.prototype={__proto__:Highlighter.prototype,processModel:function(model){this.times_=model.device.vSyncTimestamps;},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
-var stripes=VSyncHighlighter.generateStripes(this.times_,viewLWorld,viewRWorld);if(stripes.length==0){return;}
-var stripeRange=stripes[stripes.length-1][1]-stripes[0][0];var stripeDensity=stripes.length/(dt.scaleX*stripeRange);var clampedStripeDensity=tr.b.clamp(stripeDensity,VSyncHighlighter.VSYNC_DENSITY_OPAQUE,VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT);var opacity=(VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/VSyncHighlighter.VSYNC_DENSITY_RANGE;if(opacity==0){return;}
-var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined)
-groupingKeyFuncs=[];this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
-Row.prototype={getCurrentGroupingKeyFunc_:function(){if(this.groupingKeyFuncs_.length===0)
-return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
-return this.rowStats_;},rebuildSubRowsIfNeeded_:function(){if(this.subRowsBuilt_)
-return;this.subRowsBuilt_=true;var groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
-var dataByKey={};var hasValues=false;this.data_.forEach(function(datum){var key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined)
-dataByKey[key]=[];dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
-this.subRows_=[];for(var key in dataByKey){var row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer('tr-ui-b-grouping-table',{created:function(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild:function(){this.$.table.rebuild();},updateContents_:function(){var groupBy=this.groupBy_||[];var dataToGroup=this.dataToGroup_||[];var rowStatsConstructor=this.rowStatsConstructor_||function(){};var superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document._currentScript.ownerDocument;Polymer('tr-ui-b-grouping-table-groupby-picker',{created:function(){this.needsInit_=true;this.defaultGroupKeys_=undefined;this.possibleGroups_=[];this.settingsKey_=[];this.currentGroupKeys_=undefined;this.dragging_=false;},get defaultGroupKeys(){return this.defaultGroupKeys_;},set defaultGroupKeys(defaultGroupKeys){if(!this.needsInit_)
-throw new Error('Already initialized.');this.defaultGroupKeys_=defaultGroupKeys;this.maybeInit_();},get possibleGroups(){return this.possibleGroups_;},set possibleGroups(possibleGroups){if(!this.needsInit_)
-throw new Error('Already initialized.');this.possibleGroups_=possibleGroups;this.maybeInit_();},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_)
-throw new Error('Already initialized.');this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_:function(){if(!this.needsInit_)
-return;if(this.settingsKey_===undefined)
-return;if(this.defaultGroupKeys_===undefined)
-return;if(this.possibleGroups_===undefined)
-return;this.needsInit_=false;var addGroupEl=this.shadowRoot.querySelector('#add-group');addGroupEl.iconElement.textContent='Add another...';this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.defaultGroupKeys_);},get currentGroupKeys(){return this.currentGroupKeys_;},get currentGroups(){var groupsByKey={};this.possibleGroups_.forEach(function(group){groupsByKey[group.key]=group;});return this.currentGroupKeys_.map(function(groupKey){return groupsByKey[groupKey];});},set currentGroupKeys(currentGroupKeys){if(this.currentGroupKeys_===currentGroupKeys)
-return;if(!(currentGroupKeys instanceof Array))
-throw new Error('Must be array');this.currentGroupKeys_=currentGroupKeys;this.updateGroups_();tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys_);var e=new tr.b.Event('current-groups-changed');this.dispatchEvent(e);},updateGroups_:function(){var groupsEl=this.shadowRoot.querySelector('groups');var addGroupEl=this.shadowRoot.querySelector('#add-group');groupsEl.textContent='';addGroupEl.textContent='';var unusedGroups={};var groupsByKey={};this.possibleGroups_.forEach(function(group){unusedGroups[group.key]=group;groupsByKey[group.key]=group;});this.currentGroupKeys_.forEach(function(key){delete unusedGroups[key];});var groupTemplateEl=THIS_DOC.querySelector('#tr-ui-b-grouping-table-groupby-picker-group-template');this.currentGroupKeys_.forEach(function(key,index){var group=groupsByKey[key];var groupEl=document.createElement('group');groupEl.groupKey=key;groupEl.appendChild(document.importNode(groupTemplateEl.content,true));groupEl.querySelector('#key').textContent=group.label;groupsEl.appendChild(groupEl);this.configureRemoveButtonForGroup_(groupEl);this.configureDragAndDropForGroup_(groupEl);},this);tr.b.iterItems(unusedGroups,function(key,group){var groupEl=document.createElement('possible-group');groupEl.textContent=group.label;groupEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();newKeys.push(key);this.currentGroupKeys=newKeys;addGroupEl.close();}.bind(this));addGroupEl.appendChild(groupEl);},this);if(tr.b.dictionaryLength(unusedGroups)==0){addGroupEl.style.display='none';}else{addGroupEl.style.display='';}},configureRemoveButtonForGroup_:function(groupEl){var removeEl=groupEl.querySelector('#remove');removeEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();var i=newKeys.indexOf(groupEl.groupKey);newKeys.splice(i,1);this.currentGroupKeys=newKeys;}.bind(this));groupEl.addEventListener('mouseenter',function(){removeEl.setAttribute('hovered',true);});groupEl.addEventListener('mouseleave',function(){removeEl.removeAttribute('hovered');});},configureDragAndDropForGroup_:function(groupEl){var groupsEl=groupEl.parentElement;groupEl.setAttribute('draggable',true);groupEl.addEventListener('dragstart',function(e){e.dataTransfer.setData('groupKey',groupEl.groupKey);groupEl.querySelector('#remove').removeAttribute('hovered');groupEl.classList.add('dragging');this.dragging_=true;}.bind(this));groupEl.addEventListener('dragend',function(e){console.log(e.type,groupEl.groupKey);for(var i=0;i<groupsEl.children.length;i++)
-groupsEl.children[i].classList.remove('drop-targeted');groupEl.classList.remove('dragging');this.dragging_=false;}.bind(this));groupEl.addEventListener('dragenter',function(e){if(!this.dragging_)
-return;groupEl.classList.add('drop-targeted');if(this.dragging_)
-e.preventDefault();}.bind(this));groupEl.addEventListener('dragleave',function(e){if(!this.dragging_)
-return;groupEl.classList.remove('drop-targeted');e.preventDefault();}.bind(this));groupEl.addEventListener('dragover',function(e){if(!this.dragging_)
-return;e.preventDefault();groupEl.classList.add('drop-targeted');}.bind(this));groupEl.addEventListener('drop',function(e){if(!this.dragging_)
-return;var srcKey=e.dataTransfer.getData('groupKey');var dstKey=groupEl.groupKey;if(srcKey===dstKey)
-return;var newKeys=this.currentGroupKeys_.slice();var srcIndex=this.currentGroupKeys_.indexOf(srcKey);newKeys.splice(srcIndex,1);var dstIndex=this.currentGroupKeys_.indexOf(dstKey);newKeys.splice(dstIndex,0,srcKey);this.currentGroupKeys=newKeys;e.dataTransfer.clearData();e.preventDefault();e.stopPropagation();}.bind(this));}});return{};});'use strict';(function(){Polymer('tr-ui-sp-file-size-stats-side-panel',{ready:function(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn:function(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn:function(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn:function(eventStat){return eventStat.title;}}];this.$.picker.defaultGroupKeys=['phase','title'];this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel:function(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
-if(m.stats.allTraceEventStats.length===0){return{supported:false,reason:'No stats were collected for this file.'};}
-return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_:function(stats){var columns=[{title:'Title',value:function(row){var titleEl=document.createElement('span');titleEl.textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp:function(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',textAlign:'right',value:function(row){return row.rowStats.numEvents;},cmp:function(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',textAlign:'right',value:function(row){var value=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);var spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp:function(a,b){return a.rowStats.totalEventSizeinBytes-
-b.rowStats.totalEventSizeinBytes;},width:'80px'});}
-return columns;},updateContents_:function(){var table=this.$.table;var columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){var sum=tr.b.Statistics.sum(row.data,function(x){return x.numEvents;});var totalEventSizeinBytes=tr.b.Statistics.sum(row.data,function(x){return x.totalEventSizeinBytes;});return{numEvents:sum,totalEventSizeinBytes:totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
-this.$.table.rebuild();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
-alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
-this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
-return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
-return{supported:true};},get textLabel(){return'Alerts';}});
-</script>
-</head>
-  <body>
-  </body>
-</html>
diff --git a/pkg/darwin_amd64/archive/tar.a b/pkg/darwin_amd64/archive/tar.a
index 39d3dd5..d05c1d4 100644
--- a/pkg/darwin_amd64/archive/tar.a
+++ b/pkg/darwin_amd64/archive/tar.a
Binary files differ
diff --git a/pkg/darwin_amd64/archive/zip.a b/pkg/darwin_amd64/archive/zip.a
index 257d66c..f1af181 100644
--- a/pkg/darwin_amd64/archive/zip.a
+++ b/pkg/darwin_amd64/archive/zip.a
Binary files differ
diff --git a/pkg/darwin_amd64/bufio.a b/pkg/darwin_amd64/bufio.a
index 22d81e0..adcad24 100644
--- a/pkg/darwin_amd64/bufio.a
+++ b/pkg/darwin_amd64/bufio.a
Binary files differ
diff --git a/pkg/darwin_amd64/bytes.a b/pkg/darwin_amd64/bytes.a
index 288b3ae..a628e20 100644
--- a/pkg/darwin_amd64/bytes.a
+++ b/pkg/darwin_amd64/bytes.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/asm/internal/arch.a b/pkg/darwin_amd64/cmd/asm/internal/arch.a
index 0367d3a..4e1ccba 100644
--- a/pkg/darwin_amd64/cmd/asm/internal/arch.a
+++ b/pkg/darwin_amd64/cmd/asm/internal/arch.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/asm/internal/asm.a b/pkg/darwin_amd64/cmd/asm/internal/asm.a
index 3d45b45..5e01794 100644
--- a/pkg/darwin_amd64/cmd/asm/internal/asm.a
+++ b/pkg/darwin_amd64/cmd/asm/internal/asm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/asm/internal/flags.a b/pkg/darwin_amd64/cmd/asm/internal/flags.a
index c9b8430..11dc28e 100644
--- a/pkg/darwin_amd64/cmd/asm/internal/flags.a
+++ b/pkg/darwin_amd64/cmd/asm/internal/flags.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/asm/internal/lex.a b/pkg/darwin_amd64/cmd/asm/internal/lex.a
index 02b0648..f1c4371 100644
--- a/pkg/darwin_amd64/cmd/asm/internal/lex.a
+++ b/pkg/darwin_amd64/cmd/asm/internal/lex.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/amd64.a b/pkg/darwin_amd64/cmd/compile/internal/amd64.a
index 1c49173..934abfd 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/amd64.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/amd64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/arm.a b/pkg/darwin_amd64/cmd/compile/internal/arm.a
index 208cb54..9a82d1e 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/arm.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/arm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/arm64.a b/pkg/darwin_amd64/cmd/compile/internal/arm64.a
index 966854b..6783910 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/arm64.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/arm64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/gc.a b/pkg/darwin_amd64/cmd/compile/internal/gc.a
index 512a32f..2e31938 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/gc.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/gc.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/mips.a b/pkg/darwin_amd64/cmd/compile/internal/mips.a
index 8cc1036..e214633 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/mips.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/mips.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/mips64.a b/pkg/darwin_amd64/cmd/compile/internal/mips64.a
index acfa40b..65d13f2 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/mips64.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/mips64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/ppc64.a b/pkg/darwin_amd64/cmd/compile/internal/ppc64.a
index b342c88..a6a7997 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/ppc64.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/ppc64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/s390x.a b/pkg/darwin_amd64/cmd/compile/internal/s390x.a
index ef97570..74592e0 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/s390x.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/s390x.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/ssa.a b/pkg/darwin_amd64/cmd/compile/internal/ssa.a
index 0be9a85..061e418 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/ssa.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/ssa.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/syntax.a b/pkg/darwin_amd64/cmd/compile/internal/syntax.a
index ddf200e..840e0d5 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/syntax.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/syntax.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/test.a b/pkg/darwin_amd64/cmd/compile/internal/test.a
index d8c02fd..cc783d6 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/test.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/test.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/types.a b/pkg/darwin_amd64/cmd/compile/internal/types.a
index dfc4d25..84ef294 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/types.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/types.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/x86.a b/pkg/darwin_amd64/cmd/compile/internal/x86.a
index c33f8d5..5a0a5e9 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/x86.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/x86.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/base.a b/pkg/darwin_amd64/cmd/go/internal/base.a
index 33ab94b..2e8a127 100644
--- a/pkg/darwin_amd64/cmd/go/internal/base.a
+++ b/pkg/darwin_amd64/cmd/go/internal/base.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/bug.a b/pkg/darwin_amd64/cmd/go/internal/bug.a
index fa5d0af..51f1618 100644
--- a/pkg/darwin_amd64/cmd/go/internal/bug.a
+++ b/pkg/darwin_amd64/cmd/go/internal/bug.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/buildid.a b/pkg/darwin_amd64/cmd/go/internal/buildid.a
deleted file mode 100644
index c9afea9..0000000
--- a/pkg/darwin_amd64/cmd/go/internal/buildid.a
+++ /dev/null
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/cache.a b/pkg/darwin_amd64/cmd/go/internal/cache.a
new file mode 100644
index 0000000..ae15930
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/go/internal/cache.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/cfg.a b/pkg/darwin_amd64/cmd/go/internal/cfg.a
index 7768463..c2d226f 100644
--- a/pkg/darwin_amd64/cmd/go/internal/cfg.a
+++ b/pkg/darwin_amd64/cmd/go/internal/cfg.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/clean.a b/pkg/darwin_amd64/cmd/go/internal/clean.a
index b897765..1e6c521 100644
--- a/pkg/darwin_amd64/cmd/go/internal/clean.a
+++ b/pkg/darwin_amd64/cmd/go/internal/clean.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/cmdflag.a b/pkg/darwin_amd64/cmd/go/internal/cmdflag.a
index b320a04..f88609d 100644
--- a/pkg/darwin_amd64/cmd/go/internal/cmdflag.a
+++ b/pkg/darwin_amd64/cmd/go/internal/cmdflag.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/doc.a b/pkg/darwin_amd64/cmd/go/internal/doc.a
index b2d5675..14e9acd 100644
--- a/pkg/darwin_amd64/cmd/go/internal/doc.a
+++ b/pkg/darwin_amd64/cmd/go/internal/doc.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/envcmd.a b/pkg/darwin_amd64/cmd/go/internal/envcmd.a
index 9e7c61d..7c4f7d4 100644
--- a/pkg/darwin_amd64/cmd/go/internal/envcmd.a
+++ b/pkg/darwin_amd64/cmd/go/internal/envcmd.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/fix.a b/pkg/darwin_amd64/cmd/go/internal/fix.a
index c389d9f..b8cd89b 100644
--- a/pkg/darwin_amd64/cmd/go/internal/fix.a
+++ b/pkg/darwin_amd64/cmd/go/internal/fix.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/fmtcmd.a b/pkg/darwin_amd64/cmd/go/internal/fmtcmd.a
index f64a5a0..1593ddf 100644
--- a/pkg/darwin_amd64/cmd/go/internal/fmtcmd.a
+++ b/pkg/darwin_amd64/cmd/go/internal/fmtcmd.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/generate.a b/pkg/darwin_amd64/cmd/go/internal/generate.a
index 55eada0..6396805 100644
--- a/pkg/darwin_amd64/cmd/go/internal/generate.a
+++ b/pkg/darwin_amd64/cmd/go/internal/generate.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/get.a b/pkg/darwin_amd64/cmd/go/internal/get.a
index 411c7fb..1e55e14 100644
--- a/pkg/darwin_amd64/cmd/go/internal/get.a
+++ b/pkg/darwin_amd64/cmd/go/internal/get.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/help.a b/pkg/darwin_amd64/cmd/go/internal/help.a
index f169ac2..b002744 100644
--- a/pkg/darwin_amd64/cmd/go/internal/help.a
+++ b/pkg/darwin_amd64/cmd/go/internal/help.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/list.a b/pkg/darwin_amd64/cmd/go/internal/list.a
index 846d5d2..2eed9b4 100644
--- a/pkg/darwin_amd64/cmd/go/internal/list.a
+++ b/pkg/darwin_amd64/cmd/go/internal/list.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/load.a b/pkg/darwin_amd64/cmd/go/internal/load.a
index 3c659f4..f81a85c 100644
--- a/pkg/darwin_amd64/cmd/go/internal/load.a
+++ b/pkg/darwin_amd64/cmd/go/internal/load.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/run.a b/pkg/darwin_amd64/cmd/go/internal/run.a
index 5120cec..69de433 100644
--- a/pkg/darwin_amd64/cmd/go/internal/run.a
+++ b/pkg/darwin_amd64/cmd/go/internal/run.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/str.a b/pkg/darwin_amd64/cmd/go/internal/str.a
index 35c514a..a9e42b4 100644
--- a/pkg/darwin_amd64/cmd/go/internal/str.a
+++ b/pkg/darwin_amd64/cmd/go/internal/str.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/test.a b/pkg/darwin_amd64/cmd/go/internal/test.a
index 394f394..009370a 100644
--- a/pkg/darwin_amd64/cmd/go/internal/test.a
+++ b/pkg/darwin_amd64/cmd/go/internal/test.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/tool.a b/pkg/darwin_amd64/cmd/go/internal/tool.a
index fff7da3..50063eb 100644
--- a/pkg/darwin_amd64/cmd/go/internal/tool.a
+++ b/pkg/darwin_amd64/cmd/go/internal/tool.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/version.a b/pkg/darwin_amd64/cmd/go/internal/version.a
index 2cc4abd..5e4eac7 100644
--- a/pkg/darwin_amd64/cmd/go/internal/version.a
+++ b/pkg/darwin_amd64/cmd/go/internal/version.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/vet.a b/pkg/darwin_amd64/cmd/go/internal/vet.a
index 4461d23..8778f3a 100644
--- a/pkg/darwin_amd64/cmd/go/internal/vet.a
+++ b/pkg/darwin_amd64/cmd/go/internal/vet.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/web.a b/pkg/darwin_amd64/cmd/go/internal/web.a
index 4938856..4ad9b19 100644
--- a/pkg/darwin_amd64/cmd/go/internal/web.a
+++ b/pkg/darwin_amd64/cmd/go/internal/web.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/work.a b/pkg/darwin_amd64/cmd/go/internal/work.a
index ae6ed7a..c72f799 100644
--- a/pkg/darwin_amd64/cmd/go/internal/work.a
+++ b/pkg/darwin_amd64/cmd/go/internal/work.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/bio.a b/pkg/darwin_amd64/cmd/internal/bio.a
index 7fc8d05..dd90ebd 100644
--- a/pkg/darwin_amd64/cmd/internal/bio.a
+++ b/pkg/darwin_amd64/cmd/internal/bio.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/browser.a b/pkg/darwin_amd64/cmd/internal/browser.a
index 3cf3529..e798ce6 100644
--- a/pkg/darwin_amd64/cmd/internal/browser.a
+++ b/pkg/darwin_amd64/cmd/internal/browser.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/buildid.a b/pkg/darwin_amd64/cmd/internal/buildid.a
new file mode 100644
index 0000000..4958b8b
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/internal/buildid.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/dwarf.a b/pkg/darwin_amd64/cmd/internal/dwarf.a
index 0422e25..84f4280 100644
--- a/pkg/darwin_amd64/cmd/internal/dwarf.a
+++ b/pkg/darwin_amd64/cmd/internal/dwarf.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/edit.a b/pkg/darwin_amd64/cmd/internal/edit.a
new file mode 100644
index 0000000..310e97e
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/internal/edit.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/gcprog.a b/pkg/darwin_amd64/cmd/internal/gcprog.a
index 7060e80..4399231 100644
--- a/pkg/darwin_amd64/cmd/internal/gcprog.a
+++ b/pkg/darwin_amd64/cmd/internal/gcprog.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/goobj.a b/pkg/darwin_amd64/cmd/internal/goobj.a
index 8256c53..a70a633 100644
--- a/pkg/darwin_amd64/cmd/internal/goobj.a
+++ b/pkg/darwin_amd64/cmd/internal/goobj.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj.a b/pkg/darwin_amd64/cmd/internal/obj.a
index c9844e0..cb5dacd 100644
--- a/pkg/darwin_amd64/cmd/internal/obj.a
+++ b/pkg/darwin_amd64/cmd/internal/obj.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/arm.a b/pkg/darwin_amd64/cmd/internal/obj/arm.a
index e7dc675..2e102ad 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/arm.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/arm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/arm64.a b/pkg/darwin_amd64/cmd/internal/obj/arm64.a
index b8a04b7..4a102ca 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/arm64.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/arm64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/mips.a b/pkg/darwin_amd64/cmd/internal/obj/mips.a
index 9eceb6d..f9bd49a 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/mips.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/mips.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/ppc64.a b/pkg/darwin_amd64/cmd/internal/obj/ppc64.a
index 1cf2278..4d9d86f 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/ppc64.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/ppc64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/s390x.a b/pkg/darwin_amd64/cmd/internal/obj/s390x.a
index 7be7777..52fec86 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/s390x.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/s390x.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/obj/x86.a b/pkg/darwin_amd64/cmd/internal/obj/x86.a
index b586547..50dbeb6 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/x86.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/x86.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/objabi.a b/pkg/darwin_amd64/cmd/internal/objabi.a
index 4b56ad1..04a3da8 100644
--- a/pkg/darwin_amd64/cmd/internal/objabi.a
+++ b/pkg/darwin_amd64/cmd/internal/objabi.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/objfile.a b/pkg/darwin_amd64/cmd/internal/objfile.a
index 0b083b2..bce0bf4 100644
--- a/pkg/darwin_amd64/cmd/internal/objfile.a
+++ b/pkg/darwin_amd64/cmd/internal/objfile.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/src.a b/pkg/darwin_amd64/cmd/internal/src.a
index 342e8b4..bdd2fe7 100644
--- a/pkg/darwin_amd64/cmd/internal/src.a
+++ b/pkg/darwin_amd64/cmd/internal/src.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/sys.a b/pkg/darwin_amd64/cmd/internal/sys.a
index 351b992..de57803 100644
--- a/pkg/darwin_amd64/cmd/internal/sys.a
+++ b/pkg/darwin_amd64/cmd/internal/sys.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/test2json.a b/pkg/darwin_amd64/cmd/internal/test2json.a
new file mode 100644
index 0000000..63c15c6
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/internal/test2json.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/amd64.a b/pkg/darwin_amd64/cmd/link/internal/amd64.a
index c6a36b3..89ed121 100644
--- a/pkg/darwin_amd64/cmd/link/internal/amd64.a
+++ b/pkg/darwin_amd64/cmd/link/internal/amd64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/arm.a b/pkg/darwin_amd64/cmd/link/internal/arm.a
index 7cc246c..92751f8 100644
--- a/pkg/darwin_amd64/cmd/link/internal/arm.a
+++ b/pkg/darwin_amd64/cmd/link/internal/arm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/arm64.a b/pkg/darwin_amd64/cmd/link/internal/arm64.a
index 7f0b1b0..f3bd61c 100644
--- a/pkg/darwin_amd64/cmd/link/internal/arm64.a
+++ b/pkg/darwin_amd64/cmd/link/internal/arm64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/ld.a b/pkg/darwin_amd64/cmd/link/internal/ld.a
index 014eab3..d7f423a 100644
--- a/pkg/darwin_amd64/cmd/link/internal/ld.a
+++ b/pkg/darwin_amd64/cmd/link/internal/ld.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loadelf.a b/pkg/darwin_amd64/cmd/link/internal/loadelf.a
new file mode 100644
index 0000000..453edb2
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/link/internal/loadelf.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loadmacho.a b/pkg/darwin_amd64/cmd/link/internal/loadmacho.a
new file mode 100644
index 0000000..e804f66
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/link/internal/loadmacho.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loadpe.a b/pkg/darwin_amd64/cmd/link/internal/loadpe.a
new file mode 100644
index 0000000..be8e0e5
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/link/internal/loadpe.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/mips.a b/pkg/darwin_amd64/cmd/link/internal/mips.a
index 3b5380e..6b77e0b 100644
--- a/pkg/darwin_amd64/cmd/link/internal/mips.a
+++ b/pkg/darwin_amd64/cmd/link/internal/mips.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/mips64.a b/pkg/darwin_amd64/cmd/link/internal/mips64.a
index 45cdc17..53fa1a7 100644
--- a/pkg/darwin_amd64/cmd/link/internal/mips64.a
+++ b/pkg/darwin_amd64/cmd/link/internal/mips64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/objfile.a b/pkg/darwin_amd64/cmd/link/internal/objfile.a
new file mode 100644
index 0000000..cbed1b0
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/link/internal/objfile.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/ppc64.a b/pkg/darwin_amd64/cmd/link/internal/ppc64.a
index 678285e..e6be07f 100644
--- a/pkg/darwin_amd64/cmd/link/internal/ppc64.a
+++ b/pkg/darwin_amd64/cmd/link/internal/ppc64.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/s390x.a b/pkg/darwin_amd64/cmd/link/internal/s390x.a
index e662156..bcf0e15 100644
--- a/pkg/darwin_amd64/cmd/link/internal/s390x.a
+++ b/pkg/darwin_amd64/cmd/link/internal/s390x.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/sym.a b/pkg/darwin_amd64/cmd/link/internal/sym.a
new file mode 100644
index 0000000..36f8855
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/link/internal/sym.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/x86.a b/pkg/darwin_amd64/cmd/link/internal/x86.a
index 4bb00f8..9ee21e3 100644
--- a/pkg/darwin_amd64/cmd/link/internal/x86.a
+++ b/pkg/darwin_amd64/cmd/link/internal/x86.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/driver.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/driver.a
index d3e6c69..13f922e 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/driver.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/driver.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/binutils.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/binutils.a
index 3ed6212..49d6216 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/binutils.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/binutils.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/driver.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/driver.a
index d737e0c..2f1bb02 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/driver.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/driver.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/elfexec.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/elfexec.a
index fa8c1a7..b228cd7 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/elfexec.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/elfexec.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/graph.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/graph.a
index e845a80..29f0f98 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/graph.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/graph.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/measurement.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/measurement.a
index fb4a8fb..71993da 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/measurement.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/measurement.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/plugin.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/plugin.a
index 61c73ea..3b49946 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/plugin.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/plugin.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/proftest.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/proftest.a
index ef73fbe..b806d3a 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/proftest.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/proftest.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/report.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/report.a
index 34a4581..a9af5ba 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/report.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/report.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolizer.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolizer.a
index 4b4922f..9c17c5a 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolizer.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolizer.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolz.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolz.a
index a2187ae..151df0f 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolz.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/symbolz.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/profile.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/profile.a
index 9dcad56..2be63d5 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/profile.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/profile.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svg.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svg.a
index 9430118..a63e21a 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svg.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svg.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a b/pkg/darwin_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a
index 76bb617..f762ec8 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm/armasm.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm/armasm.a
index d6dc90e..d346985 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm/armasm.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm/armasm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm64/arm64asm.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm64/arm64asm.a
new file mode 100644
index 0000000..af71ec5
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/arm64/arm64asm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm.a
index 16e1456..e00023a 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/x86/x86asm.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/x86/x86asm.a
index 4839a0f..c432601 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/x86/x86asm.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/arch/x86/x86asm.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vet/internal/cfg.a b/pkg/darwin_amd64/cmd/vet/internal/cfg.a
index 1e021e0..e715d03 100644
--- a/pkg/darwin_amd64/cmd/vet/internal/cfg.a
+++ b/pkg/darwin_amd64/cmd/vet/internal/cfg.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vet/internal/whitelist.a b/pkg/darwin_amd64/cmd/vet/internal/whitelist.a
index a86c4da..e8e82b3 100644
--- a/pkg/darwin_amd64/cmd/vet/internal/whitelist.a
+++ b/pkg/darwin_amd64/cmd/vet/internal/whitelist.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/bzip2.a b/pkg/darwin_amd64/compress/bzip2.a
index 6dcf4ed..7bddfc9 100644
--- a/pkg/darwin_amd64/compress/bzip2.a
+++ b/pkg/darwin_amd64/compress/bzip2.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/flate.a b/pkg/darwin_amd64/compress/flate.a
index 3bdbe4d..68f5644 100644
--- a/pkg/darwin_amd64/compress/flate.a
+++ b/pkg/darwin_amd64/compress/flate.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/gzip.a b/pkg/darwin_amd64/compress/gzip.a
index 0f4d956..f0faac5 100644
--- a/pkg/darwin_amd64/compress/gzip.a
+++ b/pkg/darwin_amd64/compress/gzip.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/lzw.a b/pkg/darwin_amd64/compress/lzw.a
index be3c961..04c944e 100644
--- a/pkg/darwin_amd64/compress/lzw.a
+++ b/pkg/darwin_amd64/compress/lzw.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/zlib.a b/pkg/darwin_amd64/compress/zlib.a
index 1d5f5a7..e6d7248 100644
--- a/pkg/darwin_amd64/compress/zlib.a
+++ b/pkg/darwin_amd64/compress/zlib.a
Binary files differ
diff --git a/pkg/darwin_amd64/container/heap.a b/pkg/darwin_amd64/container/heap.a
index 3bad30a..0ee0a06 100644
--- a/pkg/darwin_amd64/container/heap.a
+++ b/pkg/darwin_amd64/container/heap.a
Binary files differ
diff --git a/pkg/darwin_amd64/container/list.a b/pkg/darwin_amd64/container/list.a
index fd2996a..3d386bb 100644
--- a/pkg/darwin_amd64/container/list.a
+++ b/pkg/darwin_amd64/container/list.a
Binary files differ
diff --git a/pkg/darwin_amd64/container/ring.a b/pkg/darwin_amd64/container/ring.a
index d8c14e2..7f7e01e 100644
--- a/pkg/darwin_amd64/container/ring.a
+++ b/pkg/darwin_amd64/container/ring.a
Binary files differ
diff --git a/pkg/darwin_amd64/context.a b/pkg/darwin_amd64/context.a
index 20e2406..3d2080f 100644
--- a/pkg/darwin_amd64/context.a
+++ b/pkg/darwin_amd64/context.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto.a b/pkg/darwin_amd64/crypto.a
index 520020b..9d9c4f4 100644
--- a/pkg/darwin_amd64/crypto.a
+++ b/pkg/darwin_amd64/crypto.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/aes.a b/pkg/darwin_amd64/crypto/aes.a
index c4bb084..6a1228d 100644
--- a/pkg/darwin_amd64/crypto/aes.a
+++ b/pkg/darwin_amd64/crypto/aes.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/cipher.a b/pkg/darwin_amd64/crypto/cipher.a
index 64023d3..9a5a34e 100644
--- a/pkg/darwin_amd64/crypto/cipher.a
+++ b/pkg/darwin_amd64/crypto/cipher.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/des.a b/pkg/darwin_amd64/crypto/des.a
index e07059a..f1d21c3 100644
--- a/pkg/darwin_amd64/crypto/des.a
+++ b/pkg/darwin_amd64/crypto/des.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/dsa.a b/pkg/darwin_amd64/crypto/dsa.a
index 72237c8..a84cb1b 100644
--- a/pkg/darwin_amd64/crypto/dsa.a
+++ b/pkg/darwin_amd64/crypto/dsa.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/ecdsa.a b/pkg/darwin_amd64/crypto/ecdsa.a
index 9405b21..ab64c75 100644
--- a/pkg/darwin_amd64/crypto/ecdsa.a
+++ b/pkg/darwin_amd64/crypto/ecdsa.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/elliptic.a b/pkg/darwin_amd64/crypto/elliptic.a
index 610a5a2..4c4c60c 100644
--- a/pkg/darwin_amd64/crypto/elliptic.a
+++ b/pkg/darwin_amd64/crypto/elliptic.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/hmac.a b/pkg/darwin_amd64/crypto/hmac.a
index 0b357d7..5304f5c 100644
--- a/pkg/darwin_amd64/crypto/hmac.a
+++ b/pkg/darwin_amd64/crypto/hmac.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/internal/cipherhw.a b/pkg/darwin_amd64/crypto/internal/cipherhw.a
index 8a6217e..efff707 100644
--- a/pkg/darwin_amd64/crypto/internal/cipherhw.a
+++ b/pkg/darwin_amd64/crypto/internal/cipherhw.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/md5.a b/pkg/darwin_amd64/crypto/md5.a
index 9b20970..d376297 100644
--- a/pkg/darwin_amd64/crypto/md5.a
+++ b/pkg/darwin_amd64/crypto/md5.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/rand.a b/pkg/darwin_amd64/crypto/rand.a
index 7393396..52ca2d0 100644
--- a/pkg/darwin_amd64/crypto/rand.a
+++ b/pkg/darwin_amd64/crypto/rand.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/rc4.a b/pkg/darwin_amd64/crypto/rc4.a
index 40bed4c..a554c6a 100644
--- a/pkg/darwin_amd64/crypto/rc4.a
+++ b/pkg/darwin_amd64/crypto/rc4.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/rsa.a b/pkg/darwin_amd64/crypto/rsa.a
index db03a14..43afe2d 100644
--- a/pkg/darwin_amd64/crypto/rsa.a
+++ b/pkg/darwin_amd64/crypto/rsa.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/sha1.a b/pkg/darwin_amd64/crypto/sha1.a
index d27b1e0..5e91756 100644
--- a/pkg/darwin_amd64/crypto/sha1.a
+++ b/pkg/darwin_amd64/crypto/sha1.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/sha256.a b/pkg/darwin_amd64/crypto/sha256.a
index d90438c..580c753 100644
--- a/pkg/darwin_amd64/crypto/sha256.a
+++ b/pkg/darwin_amd64/crypto/sha256.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/sha512.a b/pkg/darwin_amd64/crypto/sha512.a
index f894b04..4f11d65 100644
--- a/pkg/darwin_amd64/crypto/sha512.a
+++ b/pkg/darwin_amd64/crypto/sha512.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/subtle.a b/pkg/darwin_amd64/crypto/subtle.a
index 8a9ee9e..8802179 100644
--- a/pkg/darwin_amd64/crypto/subtle.a
+++ b/pkg/darwin_amd64/crypto/subtle.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/tls.a b/pkg/darwin_amd64/crypto/tls.a
index e4c6e71..c9de4a9 100644
--- a/pkg/darwin_amd64/crypto/tls.a
+++ b/pkg/darwin_amd64/crypto/tls.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/x509.a b/pkg/darwin_amd64/crypto/x509.a
index 2cd4d7e..10d19f3 100644
--- a/pkg/darwin_amd64/crypto/x509.a
+++ b/pkg/darwin_amd64/crypto/x509.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/x509/pkix.a b/pkg/darwin_amd64/crypto/x509/pkix.a
index 0570186..0861afc 100644
--- a/pkg/darwin_amd64/crypto/x509/pkix.a
+++ b/pkg/darwin_amd64/crypto/x509/pkix.a
Binary files differ
diff --git a/pkg/darwin_amd64/database/sql.a b/pkg/darwin_amd64/database/sql.a
index 572cdc9..2788006 100644
--- a/pkg/darwin_amd64/database/sql.a
+++ b/pkg/darwin_amd64/database/sql.a
Binary files differ
diff --git a/pkg/darwin_amd64/database/sql/driver.a b/pkg/darwin_amd64/database/sql/driver.a
index 1f7f7d9..7b482fa 100644
--- a/pkg/darwin_amd64/database/sql/driver.a
+++ b/pkg/darwin_amd64/database/sql/driver.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/dwarf.a b/pkg/darwin_amd64/debug/dwarf.a
index ff6fa9d..51ba39d 100644
--- a/pkg/darwin_amd64/debug/dwarf.a
+++ b/pkg/darwin_amd64/debug/dwarf.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/elf.a b/pkg/darwin_amd64/debug/elf.a
index 3a519c7..dd53e76 100644
--- a/pkg/darwin_amd64/debug/elf.a
+++ b/pkg/darwin_amd64/debug/elf.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/gosym.a b/pkg/darwin_amd64/debug/gosym.a
index 4c081d2..119a66a 100644
--- a/pkg/darwin_amd64/debug/gosym.a
+++ b/pkg/darwin_amd64/debug/gosym.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/macho.a b/pkg/darwin_amd64/debug/macho.a
index 802ada0..6626303 100644
--- a/pkg/darwin_amd64/debug/macho.a
+++ b/pkg/darwin_amd64/debug/macho.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/pe.a b/pkg/darwin_amd64/debug/pe.a
index 7824a18..20d7f98 100644
--- a/pkg/darwin_amd64/debug/pe.a
+++ b/pkg/darwin_amd64/debug/pe.a
Binary files differ
diff --git a/pkg/darwin_amd64/debug/plan9obj.a b/pkg/darwin_amd64/debug/plan9obj.a
index dcaec0b..9b433df 100644
--- a/pkg/darwin_amd64/debug/plan9obj.a
+++ b/pkg/darwin_amd64/debug/plan9obj.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding.a b/pkg/darwin_amd64/encoding.a
index 4b84188..dbb6b7c 100644
--- a/pkg/darwin_amd64/encoding.a
+++ b/pkg/darwin_amd64/encoding.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/ascii85.a b/pkg/darwin_amd64/encoding/ascii85.a
index bd5d5bb..6919a14 100644
--- a/pkg/darwin_amd64/encoding/ascii85.a
+++ b/pkg/darwin_amd64/encoding/ascii85.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/asn1.a b/pkg/darwin_amd64/encoding/asn1.a
index 1cb0049..99a56a6 100644
--- a/pkg/darwin_amd64/encoding/asn1.a
+++ b/pkg/darwin_amd64/encoding/asn1.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/base32.a b/pkg/darwin_amd64/encoding/base32.a
index b61ae69..4655658 100644
--- a/pkg/darwin_amd64/encoding/base32.a
+++ b/pkg/darwin_amd64/encoding/base32.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/base64.a b/pkg/darwin_amd64/encoding/base64.a
index 834d7ec..b8fba30 100644
--- a/pkg/darwin_amd64/encoding/base64.a
+++ b/pkg/darwin_amd64/encoding/base64.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/binary.a b/pkg/darwin_amd64/encoding/binary.a
index ee6bb81..b6268c7 100644
--- a/pkg/darwin_amd64/encoding/binary.a
+++ b/pkg/darwin_amd64/encoding/binary.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/csv.a b/pkg/darwin_amd64/encoding/csv.a
index 4a2698d..14ca743 100644
--- a/pkg/darwin_amd64/encoding/csv.a
+++ b/pkg/darwin_amd64/encoding/csv.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/gob.a b/pkg/darwin_amd64/encoding/gob.a
index 75f3b66..1bd40d8 100644
--- a/pkg/darwin_amd64/encoding/gob.a
+++ b/pkg/darwin_amd64/encoding/gob.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/hex.a b/pkg/darwin_amd64/encoding/hex.a
index ee9a769..b758a7c 100644
--- a/pkg/darwin_amd64/encoding/hex.a
+++ b/pkg/darwin_amd64/encoding/hex.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/json.a b/pkg/darwin_amd64/encoding/json.a
index 634d8f8..2ea9f21 100644
--- a/pkg/darwin_amd64/encoding/json.a
+++ b/pkg/darwin_amd64/encoding/json.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/pem.a b/pkg/darwin_amd64/encoding/pem.a
index fe7c790..bb92cdf 100644
--- a/pkg/darwin_amd64/encoding/pem.a
+++ b/pkg/darwin_amd64/encoding/pem.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding/xml.a b/pkg/darwin_amd64/encoding/xml.a
index bc7d378..a47c7dd 100644
--- a/pkg/darwin_amd64/encoding/xml.a
+++ b/pkg/darwin_amd64/encoding/xml.a
Binary files differ
diff --git a/pkg/darwin_amd64/errors.a b/pkg/darwin_amd64/errors.a
index c280105..27f8832 100644
--- a/pkg/darwin_amd64/errors.a
+++ b/pkg/darwin_amd64/errors.a
Binary files differ
diff --git a/pkg/darwin_amd64/expvar.a b/pkg/darwin_amd64/expvar.a
index 98cc161..b31b660 100644
--- a/pkg/darwin_amd64/expvar.a
+++ b/pkg/darwin_amd64/expvar.a
Binary files differ
diff --git a/pkg/darwin_amd64/flag.a b/pkg/darwin_amd64/flag.a
index 9dfd635..6f3fed5 100644
--- a/pkg/darwin_amd64/flag.a
+++ b/pkg/darwin_amd64/flag.a
Binary files differ
diff --git a/pkg/darwin_amd64/fmt.a b/pkg/darwin_amd64/fmt.a
index d021633..02c169a 100644
--- a/pkg/darwin_amd64/fmt.a
+++ b/pkg/darwin_amd64/fmt.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/ast.a b/pkg/darwin_amd64/go/ast.a
index 66f3551..920224d 100644
--- a/pkg/darwin_amd64/go/ast.a
+++ b/pkg/darwin_amd64/go/ast.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/build.a b/pkg/darwin_amd64/go/build.a
index 09d39df..b2fba25 100644
--- a/pkg/darwin_amd64/go/build.a
+++ b/pkg/darwin_amd64/go/build.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/constant.a b/pkg/darwin_amd64/go/constant.a
index fcda994..8742aef 100644
--- a/pkg/darwin_amd64/go/constant.a
+++ b/pkg/darwin_amd64/go/constant.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/doc.a b/pkg/darwin_amd64/go/doc.a
index 248deba..7c27123 100644
--- a/pkg/darwin_amd64/go/doc.a
+++ b/pkg/darwin_amd64/go/doc.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/format.a b/pkg/darwin_amd64/go/format.a
index 122f6ab..c846d40 100644
--- a/pkg/darwin_amd64/go/format.a
+++ b/pkg/darwin_amd64/go/format.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/importer.a b/pkg/darwin_amd64/go/importer.a
index c276d41..c77a4b8 100644
--- a/pkg/darwin_amd64/go/importer.a
+++ b/pkg/darwin_amd64/go/importer.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/internal/gccgoimporter.a b/pkg/darwin_amd64/go/internal/gccgoimporter.a
index d3290d6..7607faf 100644
--- a/pkg/darwin_amd64/go/internal/gccgoimporter.a
+++ b/pkg/darwin_amd64/go/internal/gccgoimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/internal/gcimporter.a b/pkg/darwin_amd64/go/internal/gcimporter.a
index a0fc446..d540aa7 100644
--- a/pkg/darwin_amd64/go/internal/gcimporter.a
+++ b/pkg/darwin_amd64/go/internal/gcimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/internal/srcimporter.a b/pkg/darwin_amd64/go/internal/srcimporter.a
index 9968635..29174ad 100644
--- a/pkg/darwin_amd64/go/internal/srcimporter.a
+++ b/pkg/darwin_amd64/go/internal/srcimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/parser.a b/pkg/darwin_amd64/go/parser.a
index c632fc3..4d4bec3 100644
--- a/pkg/darwin_amd64/go/parser.a
+++ b/pkg/darwin_amd64/go/parser.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/printer.a b/pkg/darwin_amd64/go/printer.a
index 6a19f46..b468135 100644
--- a/pkg/darwin_amd64/go/printer.a
+++ b/pkg/darwin_amd64/go/printer.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/scanner.a b/pkg/darwin_amd64/go/scanner.a
index ef8ff62..b94e47f 100644
--- a/pkg/darwin_amd64/go/scanner.a
+++ b/pkg/darwin_amd64/go/scanner.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/token.a b/pkg/darwin_amd64/go/token.a
index 747db5c..33e0ab4 100644
--- a/pkg/darwin_amd64/go/token.a
+++ b/pkg/darwin_amd64/go/token.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/types.a b/pkg/darwin_amd64/go/types.a
index 2bdf468..1354250 100644
--- a/pkg/darwin_amd64/go/types.a
+++ b/pkg/darwin_amd64/go/types.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash.a b/pkg/darwin_amd64/hash.a
index 0c7a2f8..d8b177c 100644
--- a/pkg/darwin_amd64/hash.a
+++ b/pkg/darwin_amd64/hash.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash/adler32.a b/pkg/darwin_amd64/hash/adler32.a
index 55ce6a0..e61e2e9 100644
--- a/pkg/darwin_amd64/hash/adler32.a
+++ b/pkg/darwin_amd64/hash/adler32.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash/crc32.a b/pkg/darwin_amd64/hash/crc32.a
index 2c81ea6..7d89f04 100644
--- a/pkg/darwin_amd64/hash/crc32.a
+++ b/pkg/darwin_amd64/hash/crc32.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash/crc64.a b/pkg/darwin_amd64/hash/crc64.a
index b5b7a57..133ba6e 100644
--- a/pkg/darwin_amd64/hash/crc64.a
+++ b/pkg/darwin_amd64/hash/crc64.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash/fnv.a b/pkg/darwin_amd64/hash/fnv.a
index f3ee5be..ee9e1d4 100644
--- a/pkg/darwin_amd64/hash/fnv.a
+++ b/pkg/darwin_amd64/hash/fnv.a
Binary files differ
diff --git a/pkg/darwin_amd64/html.a b/pkg/darwin_amd64/html.a
index f56f138..f385356 100644
--- a/pkg/darwin_amd64/html.a
+++ b/pkg/darwin_amd64/html.a
Binary files differ
diff --git a/pkg/darwin_amd64/html/template.a b/pkg/darwin_amd64/html/template.a
index 76ebfcb..b14056f 100644
--- a/pkg/darwin_amd64/html/template.a
+++ b/pkg/darwin_amd64/html/template.a
Binary files differ
diff --git a/pkg/darwin_amd64/image.a b/pkg/darwin_amd64/image.a
index 592c031..1691f5b 100644
--- a/pkg/darwin_amd64/image.a
+++ b/pkg/darwin_amd64/image.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/color.a b/pkg/darwin_amd64/image/color.a
index ea9acf2..ea0441e 100644
--- a/pkg/darwin_amd64/image/color.a
+++ b/pkg/darwin_amd64/image/color.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/color/palette.a b/pkg/darwin_amd64/image/color/palette.a
index 34c769b..6882811 100644
--- a/pkg/darwin_amd64/image/color/palette.a
+++ b/pkg/darwin_amd64/image/color/palette.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/draw.a b/pkg/darwin_amd64/image/draw.a
index 5366e92..251df24 100644
--- a/pkg/darwin_amd64/image/draw.a
+++ b/pkg/darwin_amd64/image/draw.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/gif.a b/pkg/darwin_amd64/image/gif.a
index 4a03b23..3461ba6 100644
--- a/pkg/darwin_amd64/image/gif.a
+++ b/pkg/darwin_amd64/image/gif.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/internal/imageutil.a b/pkg/darwin_amd64/image/internal/imageutil.a
index 956693e..4098d42 100644
--- a/pkg/darwin_amd64/image/internal/imageutil.a
+++ b/pkg/darwin_amd64/image/internal/imageutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/jpeg.a b/pkg/darwin_amd64/image/jpeg.a
index 5fe7eeb..f54c530 100644
--- a/pkg/darwin_amd64/image/jpeg.a
+++ b/pkg/darwin_amd64/image/jpeg.a
Binary files differ
diff --git a/pkg/darwin_amd64/image/png.a b/pkg/darwin_amd64/image/png.a
index 4a641d7..8735b32 100644
--- a/pkg/darwin_amd64/image/png.a
+++ b/pkg/darwin_amd64/image/png.a
Binary files differ
diff --git a/pkg/darwin_amd64/index/suffixarray.a b/pkg/darwin_amd64/index/suffixarray.a
index 607a8c5..35fcff2 100644
--- a/pkg/darwin_amd64/index/suffixarray.a
+++ b/pkg/darwin_amd64/index/suffixarray.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/cpu.a b/pkg/darwin_amd64/internal/cpu.a
index 6875ffa..368a214 100644
--- a/pkg/darwin_amd64/internal/cpu.a
+++ b/pkg/darwin_amd64/internal/cpu.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/nettrace.a b/pkg/darwin_amd64/internal/nettrace.a
index f0c02ae..c6e08e2 100644
--- a/pkg/darwin_amd64/internal/nettrace.a
+++ b/pkg/darwin_amd64/internal/nettrace.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/poll.a b/pkg/darwin_amd64/internal/poll.a
index 02d244f..ff50ed2 100644
--- a/pkg/darwin_amd64/internal/poll.a
+++ b/pkg/darwin_amd64/internal/poll.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/race.a b/pkg/darwin_amd64/internal/race.a
index 15d39c0..7d355a1 100644
--- a/pkg/darwin_amd64/internal/race.a
+++ b/pkg/darwin_amd64/internal/race.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/singleflight.a b/pkg/darwin_amd64/internal/singleflight.a
index 21f5db8..cc57e8c 100644
--- a/pkg/darwin_amd64/internal/singleflight.a
+++ b/pkg/darwin_amd64/internal/singleflight.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/syscall/windows.a b/pkg/darwin_amd64/internal/syscall/windows.a
index ea25dc4..f8f1e79 100644
--- a/pkg/darwin_amd64/internal/syscall/windows.a
+++ b/pkg/darwin_amd64/internal/syscall/windows.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/syscall/windows/registry.a b/pkg/darwin_amd64/internal/syscall/windows/registry.a
index 9d36a9a..81b903b 100644
--- a/pkg/darwin_amd64/internal/syscall/windows/registry.a
+++ b/pkg/darwin_amd64/internal/syscall/windows/registry.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/syscall/windows/sysdll.a b/pkg/darwin_amd64/internal/syscall/windows/sysdll.a
index 97e2cdc..c36201c 100644
--- a/pkg/darwin_amd64/internal/syscall/windows/sysdll.a
+++ b/pkg/darwin_amd64/internal/syscall/windows/sysdll.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/testenv.a b/pkg/darwin_amd64/internal/testenv.a
index 75ce388..a0d1dac 100644
--- a/pkg/darwin_amd64/internal/testenv.a
+++ b/pkg/darwin_amd64/internal/testenv.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/testlog.a b/pkg/darwin_amd64/internal/testlog.a
new file mode 100644
index 0000000..a9c47d2
--- /dev/null
+++ b/pkg/darwin_amd64/internal/testlog.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/trace.a b/pkg/darwin_amd64/internal/trace.a
index 73cda60..79dc039 100644
--- a/pkg/darwin_amd64/internal/trace.a
+++ b/pkg/darwin_amd64/internal/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64/io.a b/pkg/darwin_amd64/io.a
index 75a341d..3f59b1d 100644
--- a/pkg/darwin_amd64/io.a
+++ b/pkg/darwin_amd64/io.a
Binary files differ
diff --git a/pkg/darwin_amd64/io/ioutil.a b/pkg/darwin_amd64/io/ioutil.a
index f9938a6..7b6aded 100644
--- a/pkg/darwin_amd64/io/ioutil.a
+++ b/pkg/darwin_amd64/io/ioutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/log.a b/pkg/darwin_amd64/log.a
index 42627d9..40a430b 100644
--- a/pkg/darwin_amd64/log.a
+++ b/pkg/darwin_amd64/log.a
Binary files differ
diff --git a/pkg/darwin_amd64/log/syslog.a b/pkg/darwin_amd64/log/syslog.a
index 336c19c..e5f25ce 100644
--- a/pkg/darwin_amd64/log/syslog.a
+++ b/pkg/darwin_amd64/log/syslog.a
Binary files differ
diff --git a/pkg/darwin_amd64/math.a b/pkg/darwin_amd64/math.a
index 85840f3..3c76b26 100644
--- a/pkg/darwin_amd64/math.a
+++ b/pkg/darwin_amd64/math.a
Binary files differ
diff --git a/pkg/darwin_amd64/math/big.a b/pkg/darwin_amd64/math/big.a
index ed44c0b..2dca820 100644
--- a/pkg/darwin_amd64/math/big.a
+++ b/pkg/darwin_amd64/math/big.a
Binary files differ
diff --git a/pkg/darwin_amd64/math/bits.a b/pkg/darwin_amd64/math/bits.a
index 02ed9d8..017932c 100644
--- a/pkg/darwin_amd64/math/bits.a
+++ b/pkg/darwin_amd64/math/bits.a
Binary files differ
diff --git a/pkg/darwin_amd64/math/cmplx.a b/pkg/darwin_amd64/math/cmplx.a
index f31e2d8..a8013cd 100644
--- a/pkg/darwin_amd64/math/cmplx.a
+++ b/pkg/darwin_amd64/math/cmplx.a
Binary files differ
diff --git a/pkg/darwin_amd64/math/rand.a b/pkg/darwin_amd64/math/rand.a
index f63707b..e704d5d 100644
--- a/pkg/darwin_amd64/math/rand.a
+++ b/pkg/darwin_amd64/math/rand.a
Binary files differ
diff --git a/pkg/darwin_amd64/mime.a b/pkg/darwin_amd64/mime.a
index 95615f9..fc23ba1 100644
--- a/pkg/darwin_amd64/mime.a
+++ b/pkg/darwin_amd64/mime.a
Binary files differ
diff --git a/pkg/darwin_amd64/mime/multipart.a b/pkg/darwin_amd64/mime/multipart.a
index aec8aa8..a7be31f 100644
--- a/pkg/darwin_amd64/mime/multipart.a
+++ b/pkg/darwin_amd64/mime/multipart.a
Binary files differ
diff --git a/pkg/darwin_amd64/mime/quotedprintable.a b/pkg/darwin_amd64/mime/quotedprintable.a
index f21864a..e5273df 100644
--- a/pkg/darwin_amd64/mime/quotedprintable.a
+++ b/pkg/darwin_amd64/mime/quotedprintable.a
Binary files differ
diff --git a/pkg/darwin_amd64/net.a b/pkg/darwin_amd64/net.a
index 9cf04e2..aa9b98c 100644
--- a/pkg/darwin_amd64/net.a
+++ b/pkg/darwin_amd64/net.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http.a b/pkg/darwin_amd64/net/http.a
index 5ff585b..e63f9b3 100644
--- a/pkg/darwin_amd64/net/http.a
+++ b/pkg/darwin_amd64/net/http.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/cgi.a b/pkg/darwin_amd64/net/http/cgi.a
index cd01d5b..fcd8e1a 100644
--- a/pkg/darwin_amd64/net/http/cgi.a
+++ b/pkg/darwin_amd64/net/http/cgi.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/cookiejar.a b/pkg/darwin_amd64/net/http/cookiejar.a
index 4369e18..12d6990 100644
--- a/pkg/darwin_amd64/net/http/cookiejar.a
+++ b/pkg/darwin_amd64/net/http/cookiejar.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/fcgi.a b/pkg/darwin_amd64/net/http/fcgi.a
index 1da4ed0..ca54fca 100644
--- a/pkg/darwin_amd64/net/http/fcgi.a
+++ b/pkg/darwin_amd64/net/http/fcgi.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/httptest.a b/pkg/darwin_amd64/net/http/httptest.a
index 17328c9..4f36311 100644
--- a/pkg/darwin_amd64/net/http/httptest.a
+++ b/pkg/darwin_amd64/net/http/httptest.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/httptrace.a b/pkg/darwin_amd64/net/http/httptrace.a
index 11268af..b98c024 100644
--- a/pkg/darwin_amd64/net/http/httptrace.a
+++ b/pkg/darwin_amd64/net/http/httptrace.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/httputil.a b/pkg/darwin_amd64/net/http/httputil.a
index 52c37c5..552efa7 100644
--- a/pkg/darwin_amd64/net/http/httputil.a
+++ b/pkg/darwin_amd64/net/http/httputil.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/internal.a b/pkg/darwin_amd64/net/http/internal.a
index 8b74f73..7fae1c7 100644
--- a/pkg/darwin_amd64/net/http/internal.a
+++ b/pkg/darwin_amd64/net/http/internal.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/pprof.a b/pkg/darwin_amd64/net/http/pprof.a
index 1a49b7e..459f24f 100644
--- a/pkg/darwin_amd64/net/http/pprof.a
+++ b/pkg/darwin_amd64/net/http/pprof.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/internal/socktest.a b/pkg/darwin_amd64/net/internal/socktest.a
index a1c4236..22e0dd6 100644
--- a/pkg/darwin_amd64/net/internal/socktest.a
+++ b/pkg/darwin_amd64/net/internal/socktest.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/mail.a b/pkg/darwin_amd64/net/mail.a
index 208fac4..e129bab 100644
--- a/pkg/darwin_amd64/net/mail.a
+++ b/pkg/darwin_amd64/net/mail.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/rpc.a b/pkg/darwin_amd64/net/rpc.a
index 90a886c..80b5d7e 100644
--- a/pkg/darwin_amd64/net/rpc.a
+++ b/pkg/darwin_amd64/net/rpc.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/rpc/jsonrpc.a b/pkg/darwin_amd64/net/rpc/jsonrpc.a
index ec5318b..1631459 100644
--- a/pkg/darwin_amd64/net/rpc/jsonrpc.a
+++ b/pkg/darwin_amd64/net/rpc/jsonrpc.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/smtp.a b/pkg/darwin_amd64/net/smtp.a
index fc7efe0..70513db 100644
--- a/pkg/darwin_amd64/net/smtp.a
+++ b/pkg/darwin_amd64/net/smtp.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/textproto.a b/pkg/darwin_amd64/net/textproto.a
index e7b521f..183d4ed 100644
--- a/pkg/darwin_amd64/net/textproto.a
+++ b/pkg/darwin_amd64/net/textproto.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/url.a b/pkg/darwin_amd64/net/url.a
index 659065b..20f3957 100644
--- a/pkg/darwin_amd64/net/url.a
+++ b/pkg/darwin_amd64/net/url.a
Binary files differ
diff --git a/pkg/darwin_amd64/os.a b/pkg/darwin_amd64/os.a
index 09fb578..c434d67 100644
--- a/pkg/darwin_amd64/os.a
+++ b/pkg/darwin_amd64/os.a
Binary files differ
diff --git a/pkg/darwin_amd64/os/exec.a b/pkg/darwin_amd64/os/exec.a
index c96bb1c..51ba335 100644
--- a/pkg/darwin_amd64/os/exec.a
+++ b/pkg/darwin_amd64/os/exec.a
Binary files differ
diff --git a/pkg/darwin_amd64/os/signal.a b/pkg/darwin_amd64/os/signal.a
index 6073024..7b009f9 100644
--- a/pkg/darwin_amd64/os/signal.a
+++ b/pkg/darwin_amd64/os/signal.a
Binary files differ
diff --git a/pkg/darwin_amd64/os/signal/internal/pty.a b/pkg/darwin_amd64/os/signal/internal/pty.a
new file mode 100644
index 0000000..43c9809
--- /dev/null
+++ b/pkg/darwin_amd64/os/signal/internal/pty.a
Binary files differ
diff --git a/pkg/darwin_amd64/os/user.a b/pkg/darwin_amd64/os/user.a
index 577d99d..0d834de 100644
--- a/pkg/darwin_amd64/os/user.a
+++ b/pkg/darwin_amd64/os/user.a
Binary files differ
diff --git a/pkg/darwin_amd64/path.a b/pkg/darwin_amd64/path.a
index 880caf6..2392094 100644
--- a/pkg/darwin_amd64/path.a
+++ b/pkg/darwin_amd64/path.a
Binary files differ
diff --git a/pkg/darwin_amd64/path/filepath.a b/pkg/darwin_amd64/path/filepath.a
index 79d440e..49a61f2 100644
--- a/pkg/darwin_amd64/path/filepath.a
+++ b/pkg/darwin_amd64/path/filepath.a
Binary files differ
diff --git a/pkg/darwin_amd64/plugin.a b/pkg/darwin_amd64/plugin.a
index 8afceb8..c504611 100644
--- a/pkg/darwin_amd64/plugin.a
+++ b/pkg/darwin_amd64/plugin.a
Binary files differ
diff --git a/pkg/darwin_amd64/reflect.a b/pkg/darwin_amd64/reflect.a
index 23632b1..53f7c86 100644
--- a/pkg/darwin_amd64/reflect.a
+++ b/pkg/darwin_amd64/reflect.a
Binary files differ
diff --git a/pkg/darwin_amd64/regexp.a b/pkg/darwin_amd64/regexp.a
index 391f41e..dd629a0 100644
--- a/pkg/darwin_amd64/regexp.a
+++ b/pkg/darwin_amd64/regexp.a
Binary files differ
diff --git a/pkg/darwin_amd64/regexp/syntax.a b/pkg/darwin_amd64/regexp/syntax.a
index 7b7fdd7..fbb8d75 100644
--- a/pkg/darwin_amd64/regexp/syntax.a
+++ b/pkg/darwin_amd64/regexp/syntax.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime.a b/pkg/darwin_amd64/runtime.a
index 0aabc1e..362be9b 100644
--- a/pkg/darwin_amd64/runtime.a
+++ b/pkg/darwin_amd64/runtime.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/cgo.a b/pkg/darwin_amd64/runtime/cgo.a
index d89e808..dd41a70 100644
--- a/pkg/darwin_amd64/runtime/cgo.a
+++ b/pkg/darwin_amd64/runtime/cgo.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/debug.a b/pkg/darwin_amd64/runtime/debug.a
index d4a4d86..f47c3e8 100644
--- a/pkg/darwin_amd64/runtime/debug.a
+++ b/pkg/darwin_amd64/runtime/debug.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/internal/atomic.a b/pkg/darwin_amd64/runtime/internal/atomic.a
index 9dbd5c8..2f1447c 100644
--- a/pkg/darwin_amd64/runtime/internal/atomic.a
+++ b/pkg/darwin_amd64/runtime/internal/atomic.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/internal/sys.a b/pkg/darwin_amd64/runtime/internal/sys.a
index 2feb4bd..41a15a1 100644
--- a/pkg/darwin_amd64/runtime/internal/sys.a
+++ b/pkg/darwin_amd64/runtime/internal/sys.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/pprof.a b/pkg/darwin_amd64/runtime/pprof.a
index 093efe7..b28d7db 100644
--- a/pkg/darwin_amd64/runtime/pprof.a
+++ b/pkg/darwin_amd64/runtime/pprof.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/pprof/internal/profile.a b/pkg/darwin_amd64/runtime/pprof/internal/profile.a
index 4ea18da..31fd339 100644
--- a/pkg/darwin_amd64/runtime/pprof/internal/profile.a
+++ b/pkg/darwin_amd64/runtime/pprof/internal/profile.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/race.a b/pkg/darwin_amd64/runtime/race.a
index 9f298e3..42c8bea 100644
--- a/pkg/darwin_amd64/runtime/race.a
+++ b/pkg/darwin_amd64/runtime/race.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/trace.a b/pkg/darwin_amd64/runtime/trace.a
index 88bb64a..d9db48a 100644
--- a/pkg/darwin_amd64/runtime/trace.a
+++ b/pkg/darwin_amd64/runtime/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64/sort.a b/pkg/darwin_amd64/sort.a
index 68046e7..d452bcf 100644
--- a/pkg/darwin_amd64/sort.a
+++ b/pkg/darwin_amd64/sort.a
Binary files differ
diff --git a/pkg/darwin_amd64/strconv.a b/pkg/darwin_amd64/strconv.a
index 199e376..320495a 100644
--- a/pkg/darwin_amd64/strconv.a
+++ b/pkg/darwin_amd64/strconv.a
Binary files differ
diff --git a/pkg/darwin_amd64/strings.a b/pkg/darwin_amd64/strings.a
index 0ba5b59..981bf8e 100644
--- a/pkg/darwin_amd64/strings.a
+++ b/pkg/darwin_amd64/strings.a
Binary files differ
diff --git a/pkg/darwin_amd64/sync.a b/pkg/darwin_amd64/sync.a
index 1f49baa..4bdb261 100644
--- a/pkg/darwin_amd64/sync.a
+++ b/pkg/darwin_amd64/sync.a
Binary files differ
diff --git a/pkg/darwin_amd64/sync/atomic.a b/pkg/darwin_amd64/sync/atomic.a
index ae275f0..9d262fb 100644
--- a/pkg/darwin_amd64/sync/atomic.a
+++ b/pkg/darwin_amd64/sync/atomic.a
Binary files differ
diff --git a/pkg/darwin_amd64/syscall.a b/pkg/darwin_amd64/syscall.a
index 0392d2e..ac5db3b 100644
--- a/pkg/darwin_amd64/syscall.a
+++ b/pkg/darwin_amd64/syscall.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing.a b/pkg/darwin_amd64/testing.a
index f550acb..76c81b0 100644
--- a/pkg/darwin_amd64/testing.a
+++ b/pkg/darwin_amd64/testing.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing/internal/testdeps.a b/pkg/darwin_amd64/testing/internal/testdeps.a
index 848d6ca..c27b8f4 100644
--- a/pkg/darwin_amd64/testing/internal/testdeps.a
+++ b/pkg/darwin_amd64/testing/internal/testdeps.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing/iotest.a b/pkg/darwin_amd64/testing/iotest.a
index 963fa89..7e66faa 100644
--- a/pkg/darwin_amd64/testing/iotest.a
+++ b/pkg/darwin_amd64/testing/iotest.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing/quick.a b/pkg/darwin_amd64/testing/quick.a
index 5dc3f1b..9d37c9d 100644
--- a/pkg/darwin_amd64/testing/quick.a
+++ b/pkg/darwin_amd64/testing/quick.a
Binary files differ
diff --git a/pkg/darwin_amd64/text/scanner.a b/pkg/darwin_amd64/text/scanner.a
index 1c86c5a..a56bfbc 100644
--- a/pkg/darwin_amd64/text/scanner.a
+++ b/pkg/darwin_amd64/text/scanner.a
Binary files differ
diff --git a/pkg/darwin_amd64/text/tabwriter.a b/pkg/darwin_amd64/text/tabwriter.a
index 698cbb3..278b269 100644
--- a/pkg/darwin_amd64/text/tabwriter.a
+++ b/pkg/darwin_amd64/text/tabwriter.a
Binary files differ
diff --git a/pkg/darwin_amd64/text/template.a b/pkg/darwin_amd64/text/template.a
index 0c364e8..93a74c3 100644
--- a/pkg/darwin_amd64/text/template.a
+++ b/pkg/darwin_amd64/text/template.a
Binary files differ
diff --git a/pkg/darwin_amd64/text/template/parse.a b/pkg/darwin_amd64/text/template/parse.a
index dd75cba..96a9c16 100644
--- a/pkg/darwin_amd64/text/template/parse.a
+++ b/pkg/darwin_amd64/text/template/parse.a
Binary files differ
diff --git a/pkg/darwin_amd64/time.a b/pkg/darwin_amd64/time.a
index f230da1..fb4c67b 100644
--- a/pkg/darwin_amd64/time.a
+++ b/pkg/darwin_amd64/time.a
Binary files differ
diff --git a/pkg/darwin_amd64/unicode.a b/pkg/darwin_amd64/unicode.a
index 2bf271a..1ec0098 100644
--- a/pkg/darwin_amd64/unicode.a
+++ b/pkg/darwin_amd64/unicode.a
Binary files differ
diff --git a/pkg/darwin_amd64/unicode/utf16.a b/pkg/darwin_amd64/unicode/utf16.a
index 370ee11..8a65a2a 100644
--- a/pkg/darwin_amd64/unicode/utf16.a
+++ b/pkg/darwin_amd64/unicode/utf16.a
Binary files differ
diff --git a/pkg/darwin_amd64/unicode/utf8.a b/pkg/darwin_amd64/unicode/utf8.a
index 61d7a11..6d84b70 100644
--- a/pkg/darwin_amd64/unicode/utf8.a
+++ b/pkg/darwin_amd64/unicode/utf8.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305.a
index e073099..f2e9c3e 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
index 0e2430d..0ec24a5 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte.a
new file mode 100644
index 0000000..3d4a161
--- /dev/null
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte/asn1.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte/asn1.a
new file mode 100644
index 0000000..5cf3649
--- /dev/null
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte/asn1.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/curve25519.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/curve25519.a
index 5b9be08..ae44312 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/crypto/curve25519.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/curve25519.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/crypto/poly1305.a b/pkg/darwin_amd64/vendor/golang_org/x/crypto/poly1305.a
index 49bb265..ef1bb02 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/crypto/poly1305.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/crypto/poly1305.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/http2/hpack.a b/pkg/darwin_amd64/vendor/golang_org/x/net/http2/hpack.a
index d49610b..a4539b1 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/http2/hpack.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/http2/hpack.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/idna.a b/pkg/darwin_amd64/vendor/golang_org/x/net/idna.a
index 700633c..73d9185 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/idna.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/idna.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/internal/nettest.a b/pkg/darwin_amd64/vendor/golang_org/x/net/internal/nettest.a
new file mode 100644
index 0000000..9425a1f
--- /dev/null
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/internal/nettest.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/lex/httplex.a b/pkg/darwin_amd64/vendor/golang_org/x/net/lex/httplex.a
index 7856367..aaadbb0 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/lex/httplex.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/lex/httplex.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/nettest.a b/pkg/darwin_amd64/vendor/golang_org/x/net/nettest.a
index c2ce1fa..27bca36 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/nettest.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/nettest.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/proxy.a b/pkg/darwin_amd64/vendor/golang_org/x/net/proxy.a
index 0e351b0..1dc5a1d 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/proxy.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/proxy.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/net/route.a b/pkg/darwin_amd64/vendor/golang_org/x/net/route.a
index 4dc655d..bb361fa 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/net/route.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/net/route.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/secure.a b/pkg/darwin_amd64/vendor/golang_org/x/text/secure.a
index f106c05..2d43660 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/secure.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/secure.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/secure/bidirule.a b/pkg/darwin_amd64/vendor/golang_org/x/text/secure/bidirule.a
index 9491d6b..9ff9f66 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/secure/bidirule.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/secure/bidirule.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/transform.a b/pkg/darwin_amd64/vendor/golang_org/x/text/transform.a
index 07c8ec4..f5cfa55 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/transform.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/transform.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode.a b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode.a
index 6738085..34c6672 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/bidi.a b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/bidi.a
index a864fe2..7b25dd8 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/bidi.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/bidi.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/norm.a b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/norm.a
index fa22d8a..fb87e89 100644
--- a/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/norm.a
+++ b/pkg/darwin_amd64/vendor/golang_org/x/text/unicode/norm.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/archive/tar.a b/pkg/darwin_amd64_race/archive/tar.a
index c27e45f..80dea3b 100644
--- a/pkg/darwin_amd64_race/archive/tar.a
+++ b/pkg/darwin_amd64_race/archive/tar.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/archive/zip.a b/pkg/darwin_amd64_race/archive/zip.a
index e1262d3..58a7e1e 100644
--- a/pkg/darwin_amd64_race/archive/zip.a
+++ b/pkg/darwin_amd64_race/archive/zip.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/bufio.a b/pkg/darwin_amd64_race/bufio.a
index a5b952d..4c54b41 100644
--- a/pkg/darwin_amd64_race/bufio.a
+++ b/pkg/darwin_amd64_race/bufio.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/bytes.a b/pkg/darwin_amd64_race/bytes.a
index 2f0ccce..97435e4 100644
--- a/pkg/darwin_amd64_race/bytes.a
+++ b/pkg/darwin_amd64_race/bytes.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/compress/bzip2.a b/pkg/darwin_amd64_race/compress/bzip2.a
index ac9a300..1e69a4e 100644
--- a/pkg/darwin_amd64_race/compress/bzip2.a
+++ b/pkg/darwin_amd64_race/compress/bzip2.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/compress/flate.a b/pkg/darwin_amd64_race/compress/flate.a
index ad84498..69db808 100644
--- a/pkg/darwin_amd64_race/compress/flate.a
+++ b/pkg/darwin_amd64_race/compress/flate.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/compress/gzip.a b/pkg/darwin_amd64_race/compress/gzip.a
index 1cb1e8b..9b916ae 100644
--- a/pkg/darwin_amd64_race/compress/gzip.a
+++ b/pkg/darwin_amd64_race/compress/gzip.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/compress/lzw.a b/pkg/darwin_amd64_race/compress/lzw.a
index e8e9f3f..1760a5a 100644
--- a/pkg/darwin_amd64_race/compress/lzw.a
+++ b/pkg/darwin_amd64_race/compress/lzw.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/compress/zlib.a b/pkg/darwin_amd64_race/compress/zlib.a
index db42311..9f3f861 100644
--- a/pkg/darwin_amd64_race/compress/zlib.a
+++ b/pkg/darwin_amd64_race/compress/zlib.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/container/heap.a b/pkg/darwin_amd64_race/container/heap.a
index dac3285..38766c0 100644
--- a/pkg/darwin_amd64_race/container/heap.a
+++ b/pkg/darwin_amd64_race/container/heap.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/container/list.a b/pkg/darwin_amd64_race/container/list.a
index f179d2e..37e0226 100644
--- a/pkg/darwin_amd64_race/container/list.a
+++ b/pkg/darwin_amd64_race/container/list.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/container/ring.a b/pkg/darwin_amd64_race/container/ring.a
index 52ce753..45c0fa4 100644
--- a/pkg/darwin_amd64_race/container/ring.a
+++ b/pkg/darwin_amd64_race/container/ring.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/context.a b/pkg/darwin_amd64_race/context.a
index 718296d..eeae81f 100644
--- a/pkg/darwin_amd64_race/context.a
+++ b/pkg/darwin_amd64_race/context.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto.a b/pkg/darwin_amd64_race/crypto.a
index d704abd..8e776c1 100644
--- a/pkg/darwin_amd64_race/crypto.a
+++ b/pkg/darwin_amd64_race/crypto.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/aes.a b/pkg/darwin_amd64_race/crypto/aes.a
index adfb03b..38662bc 100644
--- a/pkg/darwin_amd64_race/crypto/aes.a
+++ b/pkg/darwin_amd64_race/crypto/aes.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/cipher.a b/pkg/darwin_amd64_race/crypto/cipher.a
index ad0f3b1..2049e0e 100644
--- a/pkg/darwin_amd64_race/crypto/cipher.a
+++ b/pkg/darwin_amd64_race/crypto/cipher.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/des.a b/pkg/darwin_amd64_race/crypto/des.a
index 5a71482..39d43da 100644
--- a/pkg/darwin_amd64_race/crypto/des.a
+++ b/pkg/darwin_amd64_race/crypto/des.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/dsa.a b/pkg/darwin_amd64_race/crypto/dsa.a
index 8ee79a3..b792cd2 100644
--- a/pkg/darwin_amd64_race/crypto/dsa.a
+++ b/pkg/darwin_amd64_race/crypto/dsa.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/ecdsa.a b/pkg/darwin_amd64_race/crypto/ecdsa.a
index e45aaca..ce39a32 100644
--- a/pkg/darwin_amd64_race/crypto/ecdsa.a
+++ b/pkg/darwin_amd64_race/crypto/ecdsa.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/elliptic.a b/pkg/darwin_amd64_race/crypto/elliptic.a
index ed14704..931b807 100644
--- a/pkg/darwin_amd64_race/crypto/elliptic.a
+++ b/pkg/darwin_amd64_race/crypto/elliptic.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/hmac.a b/pkg/darwin_amd64_race/crypto/hmac.a
index bbe6795..8930c15 100644
--- a/pkg/darwin_amd64_race/crypto/hmac.a
+++ b/pkg/darwin_amd64_race/crypto/hmac.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/internal/cipherhw.a b/pkg/darwin_amd64_race/crypto/internal/cipherhw.a
index 78988a4..0ac2d53 100644
--- a/pkg/darwin_amd64_race/crypto/internal/cipherhw.a
+++ b/pkg/darwin_amd64_race/crypto/internal/cipherhw.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/md5.a b/pkg/darwin_amd64_race/crypto/md5.a
index e96c11c..29745fb 100644
--- a/pkg/darwin_amd64_race/crypto/md5.a
+++ b/pkg/darwin_amd64_race/crypto/md5.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/rand.a b/pkg/darwin_amd64_race/crypto/rand.a
index facbe58..27df240 100644
--- a/pkg/darwin_amd64_race/crypto/rand.a
+++ b/pkg/darwin_amd64_race/crypto/rand.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/rc4.a b/pkg/darwin_amd64_race/crypto/rc4.a
index d56448a..0cdf4fc 100644
--- a/pkg/darwin_amd64_race/crypto/rc4.a
+++ b/pkg/darwin_amd64_race/crypto/rc4.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/rsa.a b/pkg/darwin_amd64_race/crypto/rsa.a
index 3caae21..0ce305b 100644
--- a/pkg/darwin_amd64_race/crypto/rsa.a
+++ b/pkg/darwin_amd64_race/crypto/rsa.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/sha1.a b/pkg/darwin_amd64_race/crypto/sha1.a
index 6dc87bd..285a160 100644
--- a/pkg/darwin_amd64_race/crypto/sha1.a
+++ b/pkg/darwin_amd64_race/crypto/sha1.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/sha256.a b/pkg/darwin_amd64_race/crypto/sha256.a
index 854db62..ceee86e 100644
--- a/pkg/darwin_amd64_race/crypto/sha256.a
+++ b/pkg/darwin_amd64_race/crypto/sha256.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/sha512.a b/pkg/darwin_amd64_race/crypto/sha512.a
index b2827cd..486caf3 100644
--- a/pkg/darwin_amd64_race/crypto/sha512.a
+++ b/pkg/darwin_amd64_race/crypto/sha512.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/subtle.a b/pkg/darwin_amd64_race/crypto/subtle.a
index b44ac87..bd2a2f7 100644
--- a/pkg/darwin_amd64_race/crypto/subtle.a
+++ b/pkg/darwin_amd64_race/crypto/subtle.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/tls.a b/pkg/darwin_amd64_race/crypto/tls.a
index f7ed0d3..2269a30 100644
--- a/pkg/darwin_amd64_race/crypto/tls.a
+++ b/pkg/darwin_amd64_race/crypto/tls.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/x509.a b/pkg/darwin_amd64_race/crypto/x509.a
index 15debf5..7f17514 100644
--- a/pkg/darwin_amd64_race/crypto/x509.a
+++ b/pkg/darwin_amd64_race/crypto/x509.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/x509/pkix.a b/pkg/darwin_amd64_race/crypto/x509/pkix.a
index 3fed4ed..d4cb13f 100644
--- a/pkg/darwin_amd64_race/crypto/x509/pkix.a
+++ b/pkg/darwin_amd64_race/crypto/x509/pkix.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/database/sql.a b/pkg/darwin_amd64_race/database/sql.a
index 5930532..697d97f 100644
--- a/pkg/darwin_amd64_race/database/sql.a
+++ b/pkg/darwin_amd64_race/database/sql.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/database/sql/driver.a b/pkg/darwin_amd64_race/database/sql/driver.a
index 6c69f49..6a2a271 100644
--- a/pkg/darwin_amd64_race/database/sql/driver.a
+++ b/pkg/darwin_amd64_race/database/sql/driver.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/dwarf.a b/pkg/darwin_amd64_race/debug/dwarf.a
index adf20cb..c1cdc51 100644
--- a/pkg/darwin_amd64_race/debug/dwarf.a
+++ b/pkg/darwin_amd64_race/debug/dwarf.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/elf.a b/pkg/darwin_amd64_race/debug/elf.a
index 5ae475a..5648321 100644
--- a/pkg/darwin_amd64_race/debug/elf.a
+++ b/pkg/darwin_amd64_race/debug/elf.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/gosym.a b/pkg/darwin_amd64_race/debug/gosym.a
index 8dd94fe..921db78 100644
--- a/pkg/darwin_amd64_race/debug/gosym.a
+++ b/pkg/darwin_amd64_race/debug/gosym.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/macho.a b/pkg/darwin_amd64_race/debug/macho.a
index b83f2a2..9d2e6fd 100644
--- a/pkg/darwin_amd64_race/debug/macho.a
+++ b/pkg/darwin_amd64_race/debug/macho.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/pe.a b/pkg/darwin_amd64_race/debug/pe.a
index afbb2bd..9ce213b 100644
--- a/pkg/darwin_amd64_race/debug/pe.a
+++ b/pkg/darwin_amd64_race/debug/pe.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/debug/plan9obj.a b/pkg/darwin_amd64_race/debug/plan9obj.a
index 2e5092d..e6afd69 100644
--- a/pkg/darwin_amd64_race/debug/plan9obj.a
+++ b/pkg/darwin_amd64_race/debug/plan9obj.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding.a b/pkg/darwin_amd64_race/encoding.a
index 0670bd0..1e8692b 100644
--- a/pkg/darwin_amd64_race/encoding.a
+++ b/pkg/darwin_amd64_race/encoding.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/ascii85.a b/pkg/darwin_amd64_race/encoding/ascii85.a
index b154657..26558f8 100644
--- a/pkg/darwin_amd64_race/encoding/ascii85.a
+++ b/pkg/darwin_amd64_race/encoding/ascii85.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/asn1.a b/pkg/darwin_amd64_race/encoding/asn1.a
index fd9acab..072f8b7 100644
--- a/pkg/darwin_amd64_race/encoding/asn1.a
+++ b/pkg/darwin_amd64_race/encoding/asn1.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/base32.a b/pkg/darwin_amd64_race/encoding/base32.a
index 4dab656..9b65703 100644
--- a/pkg/darwin_amd64_race/encoding/base32.a
+++ b/pkg/darwin_amd64_race/encoding/base32.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/base64.a b/pkg/darwin_amd64_race/encoding/base64.a
index f5b7960..17b1ec9 100644
--- a/pkg/darwin_amd64_race/encoding/base64.a
+++ b/pkg/darwin_amd64_race/encoding/base64.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/binary.a b/pkg/darwin_amd64_race/encoding/binary.a
index 217a0b9..d50b413 100644
--- a/pkg/darwin_amd64_race/encoding/binary.a
+++ b/pkg/darwin_amd64_race/encoding/binary.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/csv.a b/pkg/darwin_amd64_race/encoding/csv.a
index da4374e..19b0a19 100644
--- a/pkg/darwin_amd64_race/encoding/csv.a
+++ b/pkg/darwin_amd64_race/encoding/csv.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/gob.a b/pkg/darwin_amd64_race/encoding/gob.a
index 2f11181..cfa6b01 100644
--- a/pkg/darwin_amd64_race/encoding/gob.a
+++ b/pkg/darwin_amd64_race/encoding/gob.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/hex.a b/pkg/darwin_amd64_race/encoding/hex.a
index 21ce4e9..2dee322 100644
--- a/pkg/darwin_amd64_race/encoding/hex.a
+++ b/pkg/darwin_amd64_race/encoding/hex.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/json.a b/pkg/darwin_amd64_race/encoding/json.a
index 50597be..c85ad9c 100644
--- a/pkg/darwin_amd64_race/encoding/json.a
+++ b/pkg/darwin_amd64_race/encoding/json.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/pem.a b/pkg/darwin_amd64_race/encoding/pem.a
index c6d2251..11b7a11 100644
--- a/pkg/darwin_amd64_race/encoding/pem.a
+++ b/pkg/darwin_amd64_race/encoding/pem.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding/xml.a b/pkg/darwin_amd64_race/encoding/xml.a
index dae4fd3..f60c65f 100644
--- a/pkg/darwin_amd64_race/encoding/xml.a
+++ b/pkg/darwin_amd64_race/encoding/xml.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/errors.a b/pkg/darwin_amd64_race/errors.a
index 134ed17..1eb027f 100644
--- a/pkg/darwin_amd64_race/errors.a
+++ b/pkg/darwin_amd64_race/errors.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/expvar.a b/pkg/darwin_amd64_race/expvar.a
index 0429121..8d2d4ff 100644
--- a/pkg/darwin_amd64_race/expvar.a
+++ b/pkg/darwin_amd64_race/expvar.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/flag.a b/pkg/darwin_amd64_race/flag.a
index e0b7a77..5eb72f0 100644
--- a/pkg/darwin_amd64_race/flag.a
+++ b/pkg/darwin_amd64_race/flag.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/fmt.a b/pkg/darwin_amd64_race/fmt.a
index c2ab143..176442b 100644
--- a/pkg/darwin_amd64_race/fmt.a
+++ b/pkg/darwin_amd64_race/fmt.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/ast.a b/pkg/darwin_amd64_race/go/ast.a
index 24579c8..99ed565 100644
--- a/pkg/darwin_amd64_race/go/ast.a
+++ b/pkg/darwin_amd64_race/go/ast.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/build.a b/pkg/darwin_amd64_race/go/build.a
index 2a5b06e..7e44f31 100644
--- a/pkg/darwin_amd64_race/go/build.a
+++ b/pkg/darwin_amd64_race/go/build.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/constant.a b/pkg/darwin_amd64_race/go/constant.a
index 5a848a3..e0b333a 100644
--- a/pkg/darwin_amd64_race/go/constant.a
+++ b/pkg/darwin_amd64_race/go/constant.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/doc.a b/pkg/darwin_amd64_race/go/doc.a
index 84839d0..6695f90 100644
--- a/pkg/darwin_amd64_race/go/doc.a
+++ b/pkg/darwin_amd64_race/go/doc.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/format.a b/pkg/darwin_amd64_race/go/format.a
index 37ad3ef..a3e468c 100644
--- a/pkg/darwin_amd64_race/go/format.a
+++ b/pkg/darwin_amd64_race/go/format.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/importer.a b/pkg/darwin_amd64_race/go/importer.a
index 7f5b9a8..ab67293 100644
--- a/pkg/darwin_amd64_race/go/importer.a
+++ b/pkg/darwin_amd64_race/go/importer.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/internal/gccgoimporter.a b/pkg/darwin_amd64_race/go/internal/gccgoimporter.a
index 8127674..1353038 100644
--- a/pkg/darwin_amd64_race/go/internal/gccgoimporter.a
+++ b/pkg/darwin_amd64_race/go/internal/gccgoimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/internal/gcimporter.a b/pkg/darwin_amd64_race/go/internal/gcimporter.a
index ba939e8..6e171e9 100644
--- a/pkg/darwin_amd64_race/go/internal/gcimporter.a
+++ b/pkg/darwin_amd64_race/go/internal/gcimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/internal/srcimporter.a b/pkg/darwin_amd64_race/go/internal/srcimporter.a
index ef84e07..cb2a021 100644
--- a/pkg/darwin_amd64_race/go/internal/srcimporter.a
+++ b/pkg/darwin_amd64_race/go/internal/srcimporter.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/parser.a b/pkg/darwin_amd64_race/go/parser.a
index 4c60cda..d21a910 100644
--- a/pkg/darwin_amd64_race/go/parser.a
+++ b/pkg/darwin_amd64_race/go/parser.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/printer.a b/pkg/darwin_amd64_race/go/printer.a
index 279f281..211aca6 100644
--- a/pkg/darwin_amd64_race/go/printer.a
+++ b/pkg/darwin_amd64_race/go/printer.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/scanner.a b/pkg/darwin_amd64_race/go/scanner.a
index 4c1b4a1..dab7dff 100644
--- a/pkg/darwin_amd64_race/go/scanner.a
+++ b/pkg/darwin_amd64_race/go/scanner.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/token.a b/pkg/darwin_amd64_race/go/token.a
index 409c7ab..31d3faa 100644
--- a/pkg/darwin_amd64_race/go/token.a
+++ b/pkg/darwin_amd64_race/go/token.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/types.a b/pkg/darwin_amd64_race/go/types.a
index 4151c8b..7166219 100644
--- a/pkg/darwin_amd64_race/go/types.a
+++ b/pkg/darwin_amd64_race/go/types.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/hash.a b/pkg/darwin_amd64_race/hash.a
index 1dd6591..1a31ef6 100644
--- a/pkg/darwin_amd64_race/hash.a
+++ b/pkg/darwin_amd64_race/hash.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/hash/adler32.a b/pkg/darwin_amd64_race/hash/adler32.a
index 3ddee2a..a456758 100644
--- a/pkg/darwin_amd64_race/hash/adler32.a
+++ b/pkg/darwin_amd64_race/hash/adler32.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/hash/crc32.a b/pkg/darwin_amd64_race/hash/crc32.a
index 70bafd4..2e9868e 100644
--- a/pkg/darwin_amd64_race/hash/crc32.a
+++ b/pkg/darwin_amd64_race/hash/crc32.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/hash/crc64.a b/pkg/darwin_amd64_race/hash/crc64.a
index d024656..480df1b 100644
--- a/pkg/darwin_amd64_race/hash/crc64.a
+++ b/pkg/darwin_amd64_race/hash/crc64.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/hash/fnv.a b/pkg/darwin_amd64_race/hash/fnv.a
index af3b8f9..c35e569 100644
--- a/pkg/darwin_amd64_race/hash/fnv.a
+++ b/pkg/darwin_amd64_race/hash/fnv.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/html.a b/pkg/darwin_amd64_race/html.a
index 4bac590..7c54307 100644
--- a/pkg/darwin_amd64_race/html.a
+++ b/pkg/darwin_amd64_race/html.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/html/template.a b/pkg/darwin_amd64_race/html/template.a
index 9c82baa..b1d2696 100644
--- a/pkg/darwin_amd64_race/html/template.a
+++ b/pkg/darwin_amd64_race/html/template.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image.a b/pkg/darwin_amd64_race/image.a
index d672c17..6404300 100644
--- a/pkg/darwin_amd64_race/image.a
+++ b/pkg/darwin_amd64_race/image.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/color.a b/pkg/darwin_amd64_race/image/color.a
index 05e4522..f401d73 100644
--- a/pkg/darwin_amd64_race/image/color.a
+++ b/pkg/darwin_amd64_race/image/color.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/color/palette.a b/pkg/darwin_amd64_race/image/color/palette.a
index 72c96ab..f464b75 100644
--- a/pkg/darwin_amd64_race/image/color/palette.a
+++ b/pkg/darwin_amd64_race/image/color/palette.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/draw.a b/pkg/darwin_amd64_race/image/draw.a
index 68d089e..ca2ca07 100644
--- a/pkg/darwin_amd64_race/image/draw.a
+++ b/pkg/darwin_amd64_race/image/draw.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/gif.a b/pkg/darwin_amd64_race/image/gif.a
index dd757f0..698c5f3 100644
--- a/pkg/darwin_amd64_race/image/gif.a
+++ b/pkg/darwin_amd64_race/image/gif.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/internal/imageutil.a b/pkg/darwin_amd64_race/image/internal/imageutil.a
index 8fb2dd1..3183cc9 100644
--- a/pkg/darwin_amd64_race/image/internal/imageutil.a
+++ b/pkg/darwin_amd64_race/image/internal/imageutil.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/jpeg.a b/pkg/darwin_amd64_race/image/jpeg.a
index 338689c..113e747 100644
--- a/pkg/darwin_amd64_race/image/jpeg.a
+++ b/pkg/darwin_amd64_race/image/jpeg.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/image/png.a b/pkg/darwin_amd64_race/image/png.a
index ae625ce..f575746 100644
--- a/pkg/darwin_amd64_race/image/png.a
+++ b/pkg/darwin_amd64_race/image/png.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/index/suffixarray.a b/pkg/darwin_amd64_race/index/suffixarray.a
index 14b4dbb..70593ac 100644
--- a/pkg/darwin_amd64_race/index/suffixarray.a
+++ b/pkg/darwin_amd64_race/index/suffixarray.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/cpu.a b/pkg/darwin_amd64_race/internal/cpu.a
index 0cf257e..f18ac8c 100644
--- a/pkg/darwin_amd64_race/internal/cpu.a
+++ b/pkg/darwin_amd64_race/internal/cpu.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/nettrace.a b/pkg/darwin_amd64_race/internal/nettrace.a
index 3dd1935..c6faa5e 100644
--- a/pkg/darwin_amd64_race/internal/nettrace.a
+++ b/pkg/darwin_amd64_race/internal/nettrace.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/poll.a b/pkg/darwin_amd64_race/internal/poll.a
index 55d8f75..0ec873d 100644
--- a/pkg/darwin_amd64_race/internal/poll.a
+++ b/pkg/darwin_amd64_race/internal/poll.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/race.a b/pkg/darwin_amd64_race/internal/race.a
index c97ba7c..2b86e06 100644
--- a/pkg/darwin_amd64_race/internal/race.a
+++ b/pkg/darwin_amd64_race/internal/race.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/singleflight.a b/pkg/darwin_amd64_race/internal/singleflight.a
index 012f717..90d3850 100644
--- a/pkg/darwin_amd64_race/internal/singleflight.a
+++ b/pkg/darwin_amd64_race/internal/singleflight.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/syscall/windows.a b/pkg/darwin_amd64_race/internal/syscall/windows.a
index defb8fe..fb518dc 100644
--- a/pkg/darwin_amd64_race/internal/syscall/windows.a
+++ b/pkg/darwin_amd64_race/internal/syscall/windows.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/syscall/windows/registry.a b/pkg/darwin_amd64_race/internal/syscall/windows/registry.a
index 5fd4f3b..ab170d2 100644
--- a/pkg/darwin_amd64_race/internal/syscall/windows/registry.a
+++ b/pkg/darwin_amd64_race/internal/syscall/windows/registry.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/syscall/windows/sysdll.a b/pkg/darwin_amd64_race/internal/syscall/windows/sysdll.a
index fe0dd89..aaaf830 100644
--- a/pkg/darwin_amd64_race/internal/syscall/windows/sysdll.a
+++ b/pkg/darwin_amd64_race/internal/syscall/windows/sysdll.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/testenv.a b/pkg/darwin_amd64_race/internal/testenv.a
index e9a6a93..260f091 100644
--- a/pkg/darwin_amd64_race/internal/testenv.a
+++ b/pkg/darwin_amd64_race/internal/testenv.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/testlog.a b/pkg/darwin_amd64_race/internal/testlog.a
new file mode 100644
index 0000000..04cba44
--- /dev/null
+++ b/pkg/darwin_amd64_race/internal/testlog.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/trace.a b/pkg/darwin_amd64_race/internal/trace.a
index 7b412b9..bd4891c 100644
--- a/pkg/darwin_amd64_race/internal/trace.a
+++ b/pkg/darwin_amd64_race/internal/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/io.a b/pkg/darwin_amd64_race/io.a
index 27513f0..db252ad 100644
--- a/pkg/darwin_amd64_race/io.a
+++ b/pkg/darwin_amd64_race/io.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/io/ioutil.a b/pkg/darwin_amd64_race/io/ioutil.a
index 254cfaa..796c585 100644
--- a/pkg/darwin_amd64_race/io/ioutil.a
+++ b/pkg/darwin_amd64_race/io/ioutil.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/log.a b/pkg/darwin_amd64_race/log.a
index 348f4a7..8bdc3f6 100644
--- a/pkg/darwin_amd64_race/log.a
+++ b/pkg/darwin_amd64_race/log.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/log/syslog.a b/pkg/darwin_amd64_race/log/syslog.a
index 2da3fa2..05b7480 100644
--- a/pkg/darwin_amd64_race/log/syslog.a
+++ b/pkg/darwin_amd64_race/log/syslog.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/math.a b/pkg/darwin_amd64_race/math.a
index a3a9826..38b54ce 100644
--- a/pkg/darwin_amd64_race/math.a
+++ b/pkg/darwin_amd64_race/math.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/math/big.a b/pkg/darwin_amd64_race/math/big.a
index ba0a052..28bbcff 100644
--- a/pkg/darwin_amd64_race/math/big.a
+++ b/pkg/darwin_amd64_race/math/big.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/math/bits.a b/pkg/darwin_amd64_race/math/bits.a
index 15ecc1e..9b62d89 100644
--- a/pkg/darwin_amd64_race/math/bits.a
+++ b/pkg/darwin_amd64_race/math/bits.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/math/cmplx.a b/pkg/darwin_amd64_race/math/cmplx.a
index 13184de..7d95dc9 100644
--- a/pkg/darwin_amd64_race/math/cmplx.a
+++ b/pkg/darwin_amd64_race/math/cmplx.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/math/rand.a b/pkg/darwin_amd64_race/math/rand.a
index 7882025..703aeea 100644
--- a/pkg/darwin_amd64_race/math/rand.a
+++ b/pkg/darwin_amd64_race/math/rand.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/mime.a b/pkg/darwin_amd64_race/mime.a
index e9d7a1a..91456b2 100644
--- a/pkg/darwin_amd64_race/mime.a
+++ b/pkg/darwin_amd64_race/mime.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/mime/multipart.a b/pkg/darwin_amd64_race/mime/multipart.a
index 2a92554..dcaf777 100644
--- a/pkg/darwin_amd64_race/mime/multipart.a
+++ b/pkg/darwin_amd64_race/mime/multipart.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/mime/quotedprintable.a b/pkg/darwin_amd64_race/mime/quotedprintable.a
index 608cada..0e4cbd6 100644
--- a/pkg/darwin_amd64_race/mime/quotedprintable.a
+++ b/pkg/darwin_amd64_race/mime/quotedprintable.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net.a b/pkg/darwin_amd64_race/net.a
index e2b93c7..bbaf0c7 100644
--- a/pkg/darwin_amd64_race/net.a
+++ b/pkg/darwin_amd64_race/net.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http.a b/pkg/darwin_amd64_race/net/http.a
index 9ab7f2f..7dad3ee 100644
--- a/pkg/darwin_amd64_race/net/http.a
+++ b/pkg/darwin_amd64_race/net/http.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/cgi.a b/pkg/darwin_amd64_race/net/http/cgi.a
index e32f6d6..4c8d82e 100644
--- a/pkg/darwin_amd64_race/net/http/cgi.a
+++ b/pkg/darwin_amd64_race/net/http/cgi.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/cookiejar.a b/pkg/darwin_amd64_race/net/http/cookiejar.a
index 3ac8b8b..68c2afe 100644
--- a/pkg/darwin_amd64_race/net/http/cookiejar.a
+++ b/pkg/darwin_amd64_race/net/http/cookiejar.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/fcgi.a b/pkg/darwin_amd64_race/net/http/fcgi.a
index 76d15b2..424a17b 100644
--- a/pkg/darwin_amd64_race/net/http/fcgi.a
+++ b/pkg/darwin_amd64_race/net/http/fcgi.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/httptest.a b/pkg/darwin_amd64_race/net/http/httptest.a
index 996cfee..4830ff9 100644
--- a/pkg/darwin_amd64_race/net/http/httptest.a
+++ b/pkg/darwin_amd64_race/net/http/httptest.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/httptrace.a b/pkg/darwin_amd64_race/net/http/httptrace.a
index cf65b5a..6360c8a 100644
--- a/pkg/darwin_amd64_race/net/http/httptrace.a
+++ b/pkg/darwin_amd64_race/net/http/httptrace.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/httputil.a b/pkg/darwin_amd64_race/net/http/httputil.a
index 84cb42b..8a457d7 100644
--- a/pkg/darwin_amd64_race/net/http/httputil.a
+++ b/pkg/darwin_amd64_race/net/http/httputil.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/internal.a b/pkg/darwin_amd64_race/net/http/internal.a
index fab757d..d8b5e64 100644
--- a/pkg/darwin_amd64_race/net/http/internal.a
+++ b/pkg/darwin_amd64_race/net/http/internal.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/pprof.a b/pkg/darwin_amd64_race/net/http/pprof.a
index 483c2c3..5a149cb 100644
--- a/pkg/darwin_amd64_race/net/http/pprof.a
+++ b/pkg/darwin_amd64_race/net/http/pprof.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/internal/socktest.a b/pkg/darwin_amd64_race/net/internal/socktest.a
index fcffc83..8316e2a 100644
--- a/pkg/darwin_amd64_race/net/internal/socktest.a
+++ b/pkg/darwin_amd64_race/net/internal/socktest.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/mail.a b/pkg/darwin_amd64_race/net/mail.a
index 7da49ce..57351ab 100644
--- a/pkg/darwin_amd64_race/net/mail.a
+++ b/pkg/darwin_amd64_race/net/mail.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/rpc.a b/pkg/darwin_amd64_race/net/rpc.a
index 9405de4..c1997e7 100644
--- a/pkg/darwin_amd64_race/net/rpc.a
+++ b/pkg/darwin_amd64_race/net/rpc.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/rpc/jsonrpc.a b/pkg/darwin_amd64_race/net/rpc/jsonrpc.a
index c221b97..89f30b8 100644
--- a/pkg/darwin_amd64_race/net/rpc/jsonrpc.a
+++ b/pkg/darwin_amd64_race/net/rpc/jsonrpc.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/smtp.a b/pkg/darwin_amd64_race/net/smtp.a
index 7ccfe2a..8e4cef4 100644
--- a/pkg/darwin_amd64_race/net/smtp.a
+++ b/pkg/darwin_amd64_race/net/smtp.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/textproto.a b/pkg/darwin_amd64_race/net/textproto.a
index e87b1f6..db08a2d 100644
--- a/pkg/darwin_amd64_race/net/textproto.a
+++ b/pkg/darwin_amd64_race/net/textproto.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/url.a b/pkg/darwin_amd64_race/net/url.a
index 48bc972..7bbb3e1 100644
--- a/pkg/darwin_amd64_race/net/url.a
+++ b/pkg/darwin_amd64_race/net/url.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/os.a b/pkg/darwin_amd64_race/os.a
index feb156d..7cd6a06 100644
--- a/pkg/darwin_amd64_race/os.a
+++ b/pkg/darwin_amd64_race/os.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/os/exec.a b/pkg/darwin_amd64_race/os/exec.a
index 84e549c..62ea116 100644
--- a/pkg/darwin_amd64_race/os/exec.a
+++ b/pkg/darwin_amd64_race/os/exec.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/os/signal.a b/pkg/darwin_amd64_race/os/signal.a
index e8a04e0..b0f2139 100644
--- a/pkg/darwin_amd64_race/os/signal.a
+++ b/pkg/darwin_amd64_race/os/signal.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/os/signal/internal/pty.a b/pkg/darwin_amd64_race/os/signal/internal/pty.a
new file mode 100644
index 0000000..6329318
--- /dev/null
+++ b/pkg/darwin_amd64_race/os/signal/internal/pty.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/os/user.a b/pkg/darwin_amd64_race/os/user.a
index bdd00f6..ae67938 100644
--- a/pkg/darwin_amd64_race/os/user.a
+++ b/pkg/darwin_amd64_race/os/user.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/path.a b/pkg/darwin_amd64_race/path.a
index f173b48..6e687f4 100644
--- a/pkg/darwin_amd64_race/path.a
+++ b/pkg/darwin_amd64_race/path.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/path/filepath.a b/pkg/darwin_amd64_race/path/filepath.a
index 3f5329b..a00e336 100644
--- a/pkg/darwin_amd64_race/path/filepath.a
+++ b/pkg/darwin_amd64_race/path/filepath.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/plugin.a b/pkg/darwin_amd64_race/plugin.a
index 7c73839..52b22e3 100644
--- a/pkg/darwin_amd64_race/plugin.a
+++ b/pkg/darwin_amd64_race/plugin.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/reflect.a b/pkg/darwin_amd64_race/reflect.a
index 822bf2e..5a6df79 100644
--- a/pkg/darwin_amd64_race/reflect.a
+++ b/pkg/darwin_amd64_race/reflect.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/regexp.a b/pkg/darwin_amd64_race/regexp.a
index b5b4d7f..5c5e70e 100644
--- a/pkg/darwin_amd64_race/regexp.a
+++ b/pkg/darwin_amd64_race/regexp.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/regexp/syntax.a b/pkg/darwin_amd64_race/regexp/syntax.a
index 96e227f..0882535 100644
--- a/pkg/darwin_amd64_race/regexp/syntax.a
+++ b/pkg/darwin_amd64_race/regexp/syntax.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime.a b/pkg/darwin_amd64_race/runtime.a
index 02a87a1..472d84d 100644
--- a/pkg/darwin_amd64_race/runtime.a
+++ b/pkg/darwin_amd64_race/runtime.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/cgo.a b/pkg/darwin_amd64_race/runtime/cgo.a
index e2a5114..ccfb999 100644
--- a/pkg/darwin_amd64_race/runtime/cgo.a
+++ b/pkg/darwin_amd64_race/runtime/cgo.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/debug.a b/pkg/darwin_amd64_race/runtime/debug.a
index 4cad9b2..a40b313 100644
--- a/pkg/darwin_amd64_race/runtime/debug.a
+++ b/pkg/darwin_amd64_race/runtime/debug.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/internal/atomic.a b/pkg/darwin_amd64_race/runtime/internal/atomic.a
index 9dbd5c8..5cbf727 100644
--- a/pkg/darwin_amd64_race/runtime/internal/atomic.a
+++ b/pkg/darwin_amd64_race/runtime/internal/atomic.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/internal/sys.a b/pkg/darwin_amd64_race/runtime/internal/sys.a
index 2feb4bd..dff8dee 100644
--- a/pkg/darwin_amd64_race/runtime/internal/sys.a
+++ b/pkg/darwin_amd64_race/runtime/internal/sys.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/pprof.a b/pkg/darwin_amd64_race/runtime/pprof.a
index c464fed..b80165c 100644
--- a/pkg/darwin_amd64_race/runtime/pprof.a
+++ b/pkg/darwin_amd64_race/runtime/pprof.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/pprof/internal/profile.a b/pkg/darwin_amd64_race/runtime/pprof/internal/profile.a
index ed78fb9..865d509 100644
--- a/pkg/darwin_amd64_race/runtime/pprof/internal/profile.a
+++ b/pkg/darwin_amd64_race/runtime/pprof/internal/profile.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/race.a b/pkg/darwin_amd64_race/runtime/race.a
index bdd48e3..12d00d0 100644
--- a/pkg/darwin_amd64_race/runtime/race.a
+++ b/pkg/darwin_amd64_race/runtime/race.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/trace.a b/pkg/darwin_amd64_race/runtime/trace.a
index 633f980..be9fbac 100644
--- a/pkg/darwin_amd64_race/runtime/trace.a
+++ b/pkg/darwin_amd64_race/runtime/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/sort.a b/pkg/darwin_amd64_race/sort.a
index 113dad1..06c6e09 100644
--- a/pkg/darwin_amd64_race/sort.a
+++ b/pkg/darwin_amd64_race/sort.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/strconv.a b/pkg/darwin_amd64_race/strconv.a
index 54d6a2a..f05ab46 100644
--- a/pkg/darwin_amd64_race/strconv.a
+++ b/pkg/darwin_amd64_race/strconv.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/strings.a b/pkg/darwin_amd64_race/strings.a
index fa00a4b..adb2df9 100644
--- a/pkg/darwin_amd64_race/strings.a
+++ b/pkg/darwin_amd64_race/strings.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/sync.a b/pkg/darwin_amd64_race/sync.a
index 34e1bbe..5e155b6 100644
--- a/pkg/darwin_amd64_race/sync.a
+++ b/pkg/darwin_amd64_race/sync.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/sync/atomic.a b/pkg/darwin_amd64_race/sync/atomic.a
index 1d40bd1..0319bff 100644
--- a/pkg/darwin_amd64_race/sync/atomic.a
+++ b/pkg/darwin_amd64_race/sync/atomic.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/syscall.a b/pkg/darwin_amd64_race/syscall.a
index 9437d2e..bf2dec7 100644
--- a/pkg/darwin_amd64_race/syscall.a
+++ b/pkg/darwin_amd64_race/syscall.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/testing.a b/pkg/darwin_amd64_race/testing.a
index e59f664..4fe4194 100644
--- a/pkg/darwin_amd64_race/testing.a
+++ b/pkg/darwin_amd64_race/testing.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/testing/internal/testdeps.a b/pkg/darwin_amd64_race/testing/internal/testdeps.a
index 504f4c6..6fc33fb 100644
--- a/pkg/darwin_amd64_race/testing/internal/testdeps.a
+++ b/pkg/darwin_amd64_race/testing/internal/testdeps.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/testing/iotest.a b/pkg/darwin_amd64_race/testing/iotest.a
index c7d5ffd..c1740ce 100644
--- a/pkg/darwin_amd64_race/testing/iotest.a
+++ b/pkg/darwin_amd64_race/testing/iotest.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/testing/quick.a b/pkg/darwin_amd64_race/testing/quick.a
index 6b67b34..8892554 100644
--- a/pkg/darwin_amd64_race/testing/quick.a
+++ b/pkg/darwin_amd64_race/testing/quick.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/text/scanner.a b/pkg/darwin_amd64_race/text/scanner.a
index 6129473..4fe4762 100644
--- a/pkg/darwin_amd64_race/text/scanner.a
+++ b/pkg/darwin_amd64_race/text/scanner.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/text/tabwriter.a b/pkg/darwin_amd64_race/text/tabwriter.a
index aa99461..727d748 100644
--- a/pkg/darwin_amd64_race/text/tabwriter.a
+++ b/pkg/darwin_amd64_race/text/tabwriter.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/text/template.a b/pkg/darwin_amd64_race/text/template.a
index 196a7ce..af5a371 100644
--- a/pkg/darwin_amd64_race/text/template.a
+++ b/pkg/darwin_amd64_race/text/template.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/text/template/parse.a b/pkg/darwin_amd64_race/text/template/parse.a
index 4af3632..292c518 100644
--- a/pkg/darwin_amd64_race/text/template/parse.a
+++ b/pkg/darwin_amd64_race/text/template/parse.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/time.a b/pkg/darwin_amd64_race/time.a
index 77eff7e..27570d6 100644
--- a/pkg/darwin_amd64_race/time.a
+++ b/pkg/darwin_amd64_race/time.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/unicode.a b/pkg/darwin_amd64_race/unicode.a
index bad99fa..c2ee376 100644
--- a/pkg/darwin_amd64_race/unicode.a
+++ b/pkg/darwin_amd64_race/unicode.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/unicode/utf16.a b/pkg/darwin_amd64_race/unicode/utf16.a
index a8cb657..9cd7bf9 100644
--- a/pkg/darwin_amd64_race/unicode/utf16.a
+++ b/pkg/darwin_amd64_race/unicode/utf16.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/unicode/utf8.a b/pkg/darwin_amd64_race/unicode/utf8.a
index 5e67c49..8c9b70e 100644
--- a/pkg/darwin_amd64_race/unicode/utf8.a
+++ b/pkg/darwin_amd64_race/unicode/utf8.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305.a
index a11a715..2779d0d 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
index d68f7de..26cb442 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte.a
new file mode 100644
index 0000000..f8faf86
--- /dev/null
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte/asn1.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte/asn1.a
new file mode 100644
index 0000000..2ba9b7f
--- /dev/null
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/cryptobyte/asn1.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/curve25519.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/curve25519.a
index 3cad723..f1ae966 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/curve25519.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/curve25519.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/poly1305.a b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/poly1305.a
index 1a1b701..93ab9bb 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/poly1305.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/crypto/poly1305.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/http2/hpack.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/http2/hpack.a
index c7acb8c..ff7326f 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/http2/hpack.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/http2/hpack.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/idna.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/idna.a
index 7922238..d50c421 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/idna.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/idna.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/internal/nettest.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/internal/nettest.a
new file mode 100644
index 0000000..7a3e6fc
--- /dev/null
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/internal/nettest.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/lex/httplex.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/lex/httplex.a
index e3f5adf..db3a1d2 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/lex/httplex.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/lex/httplex.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/nettest.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/nettest.a
index 8bcdea8..b26ebba 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/nettest.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/nettest.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/proxy.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/proxy.a
index 845574f..6084235 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/proxy.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/proxy.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/net/route.a b/pkg/darwin_amd64_race/vendor/golang_org/x/net/route.a
index bead7df..166d985 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/net/route.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/net/route.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure.a
index 5a3216d..b426435 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure/bidirule.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure/bidirule.a
index 5245a60..0f2f356 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure/bidirule.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/secure/bidirule.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/transform.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/transform.a
index 0da4bff..71be4f3 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/transform.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/transform.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode.a
index 3b22b33..ea5f9ad 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/bidi.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/bidi.a
index 9963435..af69acc 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/bidi.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/bidi.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/norm.a b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/norm.a
index f319774..51a1b9c 100644
--- a/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/norm.a
+++ b/pkg/darwin_amd64_race/vendor/golang_org/x/text/unicode/norm.a
Binary files differ
diff --git a/pkg/tool/darwin_amd64/addr2line b/pkg/tool/darwin_amd64/addr2line
index 60e4ba8..52ffae6 100755
--- a/pkg/tool/darwin_amd64/addr2line
+++ b/pkg/tool/darwin_amd64/addr2line
Binary files differ
diff --git a/pkg/tool/darwin_amd64/api b/pkg/tool/darwin_amd64/api
index fdcd4b2..49eea6a 100755
--- a/pkg/tool/darwin_amd64/api
+++ b/pkg/tool/darwin_amd64/api
Binary files differ
diff --git a/pkg/tool/darwin_amd64/asm b/pkg/tool/darwin_amd64/asm
index 2e2e875..4e1b08a 100755
--- a/pkg/tool/darwin_amd64/asm
+++ b/pkg/tool/darwin_amd64/asm
Binary files differ
diff --git a/pkg/tool/darwin_amd64/buildid b/pkg/tool/darwin_amd64/buildid
new file mode 100755
index 0000000..855cff3
--- /dev/null
+++ b/pkg/tool/darwin_amd64/buildid
Binary files differ
diff --git a/pkg/tool/darwin_amd64/cgo b/pkg/tool/darwin_amd64/cgo
index f3a3aa6..6cd904f 100755
--- a/pkg/tool/darwin_amd64/cgo
+++ b/pkg/tool/darwin_amd64/cgo
Binary files differ
diff --git a/pkg/tool/darwin_amd64/compile b/pkg/tool/darwin_amd64/compile
index a96fe66..a567ff9 100755
--- a/pkg/tool/darwin_amd64/compile
+++ b/pkg/tool/darwin_amd64/compile
Binary files differ
diff --git a/pkg/tool/darwin_amd64/cover b/pkg/tool/darwin_amd64/cover
index 9f95196..cd401d3 100755
--- a/pkg/tool/darwin_amd64/cover
+++ b/pkg/tool/darwin_amd64/cover
Binary files differ
diff --git a/pkg/tool/darwin_amd64/dist b/pkg/tool/darwin_amd64/dist
index fef5f8b..dff2ef1 100755
--- a/pkg/tool/darwin_amd64/dist
+++ b/pkg/tool/darwin_amd64/dist
Binary files differ
diff --git a/pkg/tool/darwin_amd64/doc b/pkg/tool/darwin_amd64/doc
index 0054217..efde12f 100755
--- a/pkg/tool/darwin_amd64/doc
+++ b/pkg/tool/darwin_amd64/doc
Binary files differ
diff --git a/pkg/tool/darwin_amd64/fix b/pkg/tool/darwin_amd64/fix
index ae351a2..eee741a 100755
--- a/pkg/tool/darwin_amd64/fix
+++ b/pkg/tool/darwin_amd64/fix
Binary files differ
diff --git a/pkg/tool/darwin_amd64/link b/pkg/tool/darwin_amd64/link
index 3c695bb..ad4bdbf 100755
--- a/pkg/tool/darwin_amd64/link
+++ b/pkg/tool/darwin_amd64/link
Binary files differ
diff --git a/pkg/tool/darwin_amd64/nm b/pkg/tool/darwin_amd64/nm
index 2c81449..9fa9c64 100755
--- a/pkg/tool/darwin_amd64/nm
+++ b/pkg/tool/darwin_amd64/nm
Binary files differ
diff --git a/pkg/tool/darwin_amd64/objdump b/pkg/tool/darwin_amd64/objdump
index 7041541..1dbc565 100755
--- a/pkg/tool/darwin_amd64/objdump
+++ b/pkg/tool/darwin_amd64/objdump
Binary files differ
diff --git a/pkg/tool/darwin_amd64/pack b/pkg/tool/darwin_amd64/pack
index c51af2e..ef623bc 100755
--- a/pkg/tool/darwin_amd64/pack
+++ b/pkg/tool/darwin_amd64/pack
Binary files differ
diff --git a/pkg/tool/darwin_amd64/pprof b/pkg/tool/darwin_amd64/pprof
index b05f617..0bd39bb 100755
--- a/pkg/tool/darwin_amd64/pprof
+++ b/pkg/tool/darwin_amd64/pprof
Binary files differ
diff --git a/pkg/tool/darwin_amd64/test2json b/pkg/tool/darwin_amd64/test2json
new file mode 100755
index 0000000..f3a6259
--- /dev/null
+++ b/pkg/tool/darwin_amd64/test2json
Binary files differ
diff --git a/pkg/tool/darwin_amd64/trace b/pkg/tool/darwin_amd64/trace
index b2a30f8..be47c85 100755
--- a/pkg/tool/darwin_amd64/trace
+++ b/pkg/tool/darwin_amd64/trace
Binary files differ
diff --git a/pkg/tool/darwin_amd64/vet b/pkg/tool/darwin_amd64/vet
index b0f852d..0d0053f 100755
--- a/pkg/tool/darwin_amd64/vet
+++ b/pkg/tool/darwin_amd64/vet
Binary files differ
diff --git a/src/androidtest.bash b/src/androidtest.bash
index 3ac56d1..a790f95 100755
--- a/src/androidtest.bash
+++ b/src/androidtest.bash
@@ -77,8 +77,8 @@
 cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/"
 
 echo '# Syncing test files to android device'
-adb shell mkdir -p /data/local/tmp/goroot
-time adb sync data &> /dev/null
+adb $GOANDROID_ADB_FLAGS shell mkdir -p /data/local/tmp/goroot
+time adb $GOANDROID_ADB_FLAGS sync data &> /dev/null
 
 export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$
 cp ../misc/android/cleaner.go $CLEANER.go
@@ -86,8 +86,8 @@
 (cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go)
 echo '`' >> $CLEANER.go
 go build -o $CLEANER $CLEANER.go
-adb push $CLEANER /data/local/tmp/cleaner
-adb shell /data/local/tmp/cleaner
+adb $GOANDROID_ADB_FLAGS push $CLEANER /data/local/tmp/cleaner
+adb $GOANDROID_ADB_FLAGS shell /data/local/tmp/cleaner
 
 echo ''
 
diff --git a/src/archive/tar/common.go b/src/archive/tar/common.go
index d49c5c3..4a2c173 100644
--- a/src/archive/tar/common.go
+++ b/src/archive/tar/common.go
@@ -3,20 +3,22 @@
 // license that can be found in the LICENSE file.
 
 // Package tar implements access to tar archives.
-// It aims to cover most of the variations, including those produced
-// by GNU and BSD tars.
 //
-// References:
-//   http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
-//   http://www.gnu.org/software/tar/manual/html_node/Standard.html
-//   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html
+// Tape archives (tar) are a file format for storing a sequence of files that
+// can be read and written in a streaming manner.
+// This package aims to cover most variations of the format,
+// including those produced by GNU and BSD tar tools.
 package tar
 
 import (
 	"errors"
 	"fmt"
+	"math"
 	"os"
 	"path"
+	"reflect"
+	"strconv"
+	"strings"
 	"time"
 )
 
@@ -24,42 +26,500 @@
 // architectures. If a large value is encountered when decoding, the result
 // stored in Header will be the truncated version.
 
-// Header type flags.
-const (
-	TypeReg           = '0'    // regular file
-	TypeRegA          = '\x00' // regular file
-	TypeLink          = '1'    // hard link
-	TypeSymlink       = '2'    // symbolic link
-	TypeChar          = '3'    // character device node
-	TypeBlock         = '4'    // block device node
-	TypeDir           = '5'    // directory
-	TypeFifo          = '6'    // fifo node
-	TypeCont          = '7'    // reserved
-	TypeXHeader       = 'x'    // extended header
-	TypeXGlobalHeader = 'g'    // global extended header
-	TypeGNULongName   = 'L'    // Next file has a long name
-	TypeGNULongLink   = 'K'    // Next file symlinks to a file w/ a long name
-	TypeGNUSparse     = 'S'    // sparse file
+var (
+	ErrHeader          = errors.New("archive/tar: invalid tar header")
+	ErrWriteTooLong    = errors.New("archive/tar: write too long")
+	ErrFieldTooLong    = errors.New("archive/tar: header field too long")
+	ErrWriteAfterClose = errors.New("archive/tar: write after close")
+	errMissData        = errors.New("archive/tar: sparse file references non-existent data")
+	errUnrefData       = errors.New("archive/tar: sparse file contains unreferenced data")
+	errWriteHole       = errors.New("archive/tar: write non-NUL byte in sparse hole")
 )
 
+type headerError []string
+
+func (he headerError) Error() string {
+	const prefix = "archive/tar: cannot encode header"
+	var ss []string
+	for _, s := range he {
+		if s != "" {
+			ss = append(ss, s)
+		}
+	}
+	if len(ss) == 0 {
+		return prefix
+	}
+	return fmt.Sprintf("%s: %v", prefix, strings.Join(ss, "; and "))
+}
+
+// Type flags for Header.Typeflag.
+const (
+	// Type '0' indicates a regular file.
+	TypeReg  = '0'
+	TypeRegA = '\x00' // For legacy support; use TypeReg instead
+
+	// Type '1' to '6' are header-only flags and may not have a data body.
+	TypeLink    = '1' // Hard link
+	TypeSymlink = '2' // Symbolic link
+	TypeChar    = '3' // Character device node
+	TypeBlock   = '4' // Block device node
+	TypeDir     = '5' // Directory
+	TypeFifo    = '6' // FIFO node
+
+	// Type '7' is reserved.
+	TypeCont = '7'
+
+	// Type 'x' is used by the PAX format to store key-value records that
+	// are only relevant to the next file.
+	// This package transparently handles these types.
+	TypeXHeader = 'x'
+
+	// Type 'g' is used by the PAX format to store key-value records that
+	// are relevant to all subsequent files.
+	// This package only supports parsing and composing such headers,
+	// but does not currently support persisting the global state across files.
+	TypeXGlobalHeader = 'g'
+
+	// Type 'S' indicates a sparse file in the GNU format.
+	TypeGNUSparse = 'S'
+
+	// Types 'L' and 'K' are used by the GNU format for a meta file
+	// used to store the path or link name for the next file.
+	// This package transparently handles these types.
+	TypeGNULongName = 'L'
+	TypeGNULongLink = 'K'
+)
+
+// Keywords for PAX extended header records.
+const (
+	paxNone     = "" // Indicates that no PAX key is suitable
+	paxPath     = "path"
+	paxLinkpath = "linkpath"
+	paxSize     = "size"
+	paxUid      = "uid"
+	paxGid      = "gid"
+	paxUname    = "uname"
+	paxGname    = "gname"
+	paxMtime    = "mtime"
+	paxAtime    = "atime"
+	paxCtime    = "ctime"   // Removed from later revision of PAX spec, but was valid
+	paxCharset  = "charset" // Currently unused
+	paxComment  = "comment" // Currently unused
+
+	paxSchilyXattr = "SCHILY.xattr."
+
+	// Keywords for GNU sparse files in a PAX extended header.
+	paxGNUSparse          = "GNU.sparse."
+	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"
+)
+
+// basicKeys is a set of the PAX keys for which we have built-in support.
+// This does not contain "charset" or "comment", which are both PAX-specific,
+// so adding them as first-class features of Header is unlikely.
+// Users can use the PAXRecords field to set it themselves.
+var basicKeys = map[string]bool{
+	paxPath: true, paxLinkpath: true, paxSize: true, paxUid: true, paxGid: true,
+	paxUname: true, paxGname: true, paxMtime: true, paxAtime: true, paxCtime: true,
+}
+
 // A Header represents a single header in a tar archive.
 // Some fields may not be populated.
+//
+// For forward compatibility, users that retrieve a Header from Reader.Next,
+// mutate it in some ways, and then pass it back to Writer.WriteHeader
+// should do so by creating a new Header and copying the fields
+// that they are interested in preserving.
 type Header struct {
-	Name       string    // name of header file entry
-	Mode       int64     // permission and mode bits
-	Uid        int       // user id of owner
-	Gid        int       // group id of owner
-	Size       int64     // length in bytes
-	ModTime    time.Time // modified time
-	Typeflag   byte      // type of header entry
-	Linkname   string    // target name of link
-	Uname      string    // user name of owner
-	Gname      string    // group name of owner
-	Devmajor   int64     // major number of character or block device
-	Devminor   int64     // minor number of character or block device
-	AccessTime time.Time // access time
-	ChangeTime time.Time // status change time
-	Xattrs     map[string]string
+	Typeflag byte // Type of header entry (should be TypeReg for most files)
+
+	Name     string // Name of file entry
+	Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
+
+	Size  int64  // Logical file size in bytes
+	Mode  int64  // Permission and mode bits
+	Uid   int    // User ID of owner
+	Gid   int    // Group ID of owner
+	Uname string // User name of owner
+	Gname string // Group name of owner
+
+	// If the Format is unspecified, then Writer.WriteHeader rounds ModTime
+	// to the nearest second and ignores the AccessTime and ChangeTime fields.
+	//
+	// To use AccessTime or ChangeTime, specify the Format as PAX or GNU.
+	// To use sub-second resolution, specify the Format as PAX.
+	ModTime    time.Time // Modification time
+	AccessTime time.Time // Access time (requires either PAX or GNU support)
+	ChangeTime time.Time // Change time (requires either PAX or GNU support)
+
+	Devmajor int64 // Major device number (valid for TypeChar or TypeBlock)
+	Devminor int64 // Minor device number (valid for TypeChar or TypeBlock)
+
+	// Xattrs stores extended attributes as PAX records under the
+	// "SCHILY.xattr." namespace.
+	//
+	// The following are semantically equivalent:
+	//  h.Xattrs[key] = value
+	//  h.PAXRecords["SCHILY.xattr."+key] = value
+	//
+	// When Writer.WriteHeader is called, the contents of Xattrs will take
+	// precedence over those in PAXRecords.
+	//
+	// Deprecated: Use PAXRecords instead.
+	Xattrs map[string]string
+
+	// PAXRecords is a map of PAX extended header records.
+	//
+	// User-defined records should have keys of the following form:
+	//	VENDOR.keyword
+	// Where VENDOR is some namespace in all uppercase, and keyword may
+	// not contain the '=' character (e.g., "GOLANG.pkg.version").
+	// The key and value should be non-empty UTF-8 strings.
+	//
+	// When Writer.WriteHeader is called, PAX records derived from the
+	// the other fields in Header take precedence over PAXRecords.
+	PAXRecords map[string]string
+
+	// Format specifies the format of the tar header.
+	//
+	// This is set by Reader.Next as a best-effort guess at the format.
+	// Since the Reader liberally reads some non-compliant files,
+	// it is possible for this to be FormatUnknown.
+	//
+	// If the format is unspecified when Writer.WriteHeader is called,
+	// then it uses the first format (in the order of USTAR, PAX, GNU)
+	// capable of encoding this Header (see Format).
+	Format Format
+}
+
+// sparseEntry represents a Length-sized fragment at Offset in the file.
+type sparseEntry struct{ Offset, Length int64 }
+
+func (s sparseEntry) endOffset() int64 { return s.Offset + s.Length }
+
+// A sparse file can be represented as either a sparseDatas or a sparseHoles.
+// As long as the total size is known, they are equivalent and one can be
+// converted to the other form and back. The various tar formats with sparse
+// file support represent sparse files in the sparseDatas form. That is, they
+// specify the fragments in the file that has data, and treat everything else as
+// having zero bytes. As such, the encoding and decoding logic in this package
+// deals with sparseDatas.
+//
+// However, the external API uses sparseHoles instead of sparseDatas because the
+// zero value of sparseHoles logically represents a normal file (i.e., there are
+// no holes in it). On the other hand, the zero value of sparseDatas implies
+// that the file has no data in it, which is rather odd.
+//
+// As an example, if the underlying raw file contains the 10-byte data:
+//	var compactFile = "abcdefgh"
+//
+// And the sparse map has the following entries:
+//	var spd sparseDatas = []sparseEntry{
+//		{Offset: 2,  Length: 5},  // Data fragment for 2..6
+//		{Offset: 18, Length: 3},  // Data fragment for 18..20
+//	}
+//	var sph sparseHoles = []sparseEntry{
+//		{Offset: 0,  Length: 2},  // Hole fragment for 0..1
+//		{Offset: 7,  Length: 11}, // Hole fragment for 7..17
+//		{Offset: 21, Length: 4},  // Hole fragment for 21..24
+//	}
+//
+// Then the content of the resulting sparse file with a Header.Size of 25 is:
+//	var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4
+type (
+	sparseDatas []sparseEntry
+	sparseHoles []sparseEntry
+)
+
+// validateSparseEntries reports whether sp is a valid sparse map.
+// It does not matter whether sp represents data fragments or hole fragments.
+func validateSparseEntries(sp []sparseEntry, size int64) bool {
+	// Validate all sparse entries. These are the same checks as performed by
+	// the BSD tar utility.
+	if size < 0 {
+		return false
+	}
+	var pre sparseEntry
+	for _, cur := range sp {
+		switch {
+		case cur.Offset < 0 || cur.Length < 0:
+			return false // Negative values are never okay
+		case cur.Offset > math.MaxInt64-cur.Length:
+			return false // Integer overflow with large length
+		case cur.endOffset() > size:
+			return false // Region extends beyond the actual size
+		case pre.endOffset() > cur.Offset:
+			return false // Regions cannot overlap and must be in order
+		}
+		pre = cur
+	}
+	return true
+}
+
+// alignSparseEntries mutates src and returns dst where each fragment's
+// starting offset is aligned up to the nearest block edge, and each
+// ending offset is aligned down to the nearest block edge.
+//
+// Even though the Go tar Reader and the BSD tar utility can handle entries
+// with arbitrary offsets and lengths, the GNU tar utility can only handle
+// offsets and lengths that are multiples of blockSize.
+func alignSparseEntries(src []sparseEntry, size int64) []sparseEntry {
+	dst := src[:0]
+	for _, s := range src {
+		pos, end := s.Offset, s.endOffset()
+		pos += blockPadding(+pos) // Round-up to nearest blockSize
+		if end != size {
+			end -= blockPadding(-end) // Round-down to nearest blockSize
+		}
+		if pos < end {
+			dst = append(dst, sparseEntry{Offset: pos, Length: end - pos})
+		}
+	}
+	return dst
+}
+
+// invertSparseEntries converts a sparse map from one form to the other.
+// If the input is sparseHoles, then it will output sparseDatas and vice-versa.
+// The input must have been already validated.
+//
+// This function mutates src and returns a normalized map where:
+//	* adjacent fragments are coalesced together
+//	* only the last fragment may be empty
+//	* the endOffset of the last fragment is the total size
+func invertSparseEntries(src []sparseEntry, size int64) []sparseEntry {
+	dst := src[:0]
+	var pre sparseEntry
+	for _, cur := range src {
+		if cur.Length == 0 {
+			continue // Skip empty fragments
+		}
+		pre.Length = cur.Offset - pre.Offset
+		if pre.Length > 0 {
+			dst = append(dst, pre) // Only add non-empty fragments
+		}
+		pre.Offset = cur.endOffset()
+	}
+	pre.Length = size - pre.Offset // Possibly the only empty fragment
+	return append(dst, pre)
+}
+
+// fileState tracks the number of logical (includes sparse holes) and physical
+// (actual in tar archive) bytes remaining for the current file.
+//
+// Invariant: LogicalRemaining >= PhysicalRemaining
+type fileState interface {
+	LogicalRemaining() int64
+	PhysicalRemaining() int64
+}
+
+// allowedFormats determines which formats can be used.
+// The value returned is the logical OR of multiple possible formats.
+// If the value is FormatUnknown, then the input Header cannot be encoded
+// and an error is returned explaining why.
+//
+// As a by-product of checking the fields, this function returns paxHdrs, which
+// contain all fields that could not be directly encoded.
+// A value receiver ensures that this method does not mutate the source Header.
+func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error) {
+	format = FormatUSTAR | FormatPAX | FormatGNU
+	paxHdrs = make(map[string]string)
+
+	var whyNoUSTAR, whyNoPAX, whyNoGNU string
+	var preferPAX bool // Prefer PAX over USTAR
+	verifyString := func(s string, size int, name, paxKey string) {
+		// NUL-terminator is optional for path and linkpath.
+		// Technically, it is required for uname and gname,
+		// but neither GNU nor BSD tar checks for it.
+		tooLong := len(s) > size
+		allowLongGNU := paxKey == paxPath || paxKey == paxLinkpath
+		if hasNUL(s) || (tooLong && !allowLongGNU) {
+			whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%q", name, s)
+			format.mustNotBe(FormatGNU)
+		}
+		if !isASCII(s) || tooLong {
+			canSplitUSTAR := paxKey == paxPath
+			if _, _, ok := splitUSTARPath(s); !canSplitUSTAR || !ok {
+				whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%q", name, s)
+				format.mustNotBe(FormatUSTAR)
+			}
+			if paxKey == paxNone {
+				whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%q", name, s)
+				format.mustNotBe(FormatPAX)
+			} else {
+				paxHdrs[paxKey] = s
+			}
+		}
+		if v, ok := h.PAXRecords[paxKey]; ok && v == s {
+			paxHdrs[paxKey] = v
+		}
+	}
+	verifyNumeric := func(n int64, size int, name, paxKey string) {
+		if !fitsInBase256(size, n) {
+			whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%d", name, n)
+			format.mustNotBe(FormatGNU)
+		}
+		if !fitsInOctal(size, n) {
+			whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%d", name, n)
+			format.mustNotBe(FormatUSTAR)
+			if paxKey == paxNone {
+				whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%d", name, n)
+				format.mustNotBe(FormatPAX)
+			} else {
+				paxHdrs[paxKey] = strconv.FormatInt(n, 10)
+			}
+		}
+		if v, ok := h.PAXRecords[paxKey]; ok && v == strconv.FormatInt(n, 10) {
+			paxHdrs[paxKey] = v
+		}
+	}
+	verifyTime := func(ts time.Time, size int, name, paxKey string) {
+		if ts.IsZero() {
+			return // Always okay
+		}
+		if !fitsInBase256(size, ts.Unix()) {
+			whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%v", name, ts)
+			format.mustNotBe(FormatGNU)
+		}
+		isMtime := paxKey == paxMtime
+		fitsOctal := fitsInOctal(size, ts.Unix())
+		if (isMtime && !fitsOctal) || !isMtime {
+			whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%v", name, ts)
+			format.mustNotBe(FormatUSTAR)
+		}
+		needsNano := ts.Nanosecond() != 0
+		if !isMtime || !fitsOctal || needsNano {
+			preferPAX = true // USTAR may truncate sub-second measurements
+			if paxKey == paxNone {
+				whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%v", name, ts)
+				format.mustNotBe(FormatPAX)
+			} else {
+				paxHdrs[paxKey] = formatPAXTime(ts)
+			}
+		}
+		if v, ok := h.PAXRecords[paxKey]; ok && v == formatPAXTime(ts) {
+			paxHdrs[paxKey] = v
+		}
+	}
+
+	// Check basic fields.
+	var blk block
+	v7 := blk.V7()
+	ustar := blk.USTAR()
+	gnu := blk.GNU()
+	verifyString(h.Name, len(v7.Name()), "Name", paxPath)
+	verifyString(h.Linkname, len(v7.LinkName()), "Linkname", paxLinkpath)
+	verifyString(h.Uname, len(ustar.UserName()), "Uname", paxUname)
+	verifyString(h.Gname, len(ustar.GroupName()), "Gname", paxGname)
+	verifyNumeric(h.Mode, len(v7.Mode()), "Mode", paxNone)
+	verifyNumeric(int64(h.Uid), len(v7.UID()), "Uid", paxUid)
+	verifyNumeric(int64(h.Gid), len(v7.GID()), "Gid", paxGid)
+	verifyNumeric(h.Size, len(v7.Size()), "Size", paxSize)
+	verifyNumeric(h.Devmajor, len(ustar.DevMajor()), "Devmajor", paxNone)
+	verifyNumeric(h.Devminor, len(ustar.DevMinor()), "Devminor", paxNone)
+	verifyTime(h.ModTime, len(v7.ModTime()), "ModTime", paxMtime)
+	verifyTime(h.AccessTime, len(gnu.AccessTime()), "AccessTime", paxAtime)
+	verifyTime(h.ChangeTime, len(gnu.ChangeTime()), "ChangeTime", paxCtime)
+
+	// Check for header-only types.
+	var whyOnlyPAX, whyOnlyGNU string
+	switch h.Typeflag {
+	case TypeReg, TypeChar, TypeBlock, TypeFifo, TypeGNUSparse:
+		// Exclude TypeLink and TypeSymlink, since they may reference directories.
+		if strings.HasSuffix(h.Name, "/") {
+			return FormatUnknown, nil, headerError{"filename may not have trailing slash"}
+		}
+	case TypeXHeader, TypeGNULongName, TypeGNULongLink:
+		return FormatUnknown, nil, headerError{"cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers"}
+	case TypeXGlobalHeader:
+		h2 := Header{Name: h.Name, Typeflag: h.Typeflag, Xattrs: h.Xattrs, PAXRecords: h.PAXRecords, Format: h.Format}
+		if !reflect.DeepEqual(h, h2) {
+			return FormatUnknown, nil, headerError{"only PAXRecords should be set for TypeXGlobalHeader"}
+		}
+		whyOnlyPAX = "only PAX supports TypeXGlobalHeader"
+		format.mayOnlyBe(FormatPAX)
+	}
+	if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {
+		return FormatUnknown, nil, headerError{"negative size on header-only type"}
+	}
+
+	// Check PAX records.
+	if len(h.Xattrs) > 0 {
+		for k, v := range h.Xattrs {
+			paxHdrs[paxSchilyXattr+k] = v
+		}
+		whyOnlyPAX = "only PAX supports Xattrs"
+		format.mayOnlyBe(FormatPAX)
+	}
+	if len(h.PAXRecords) > 0 {
+		for k, v := range h.PAXRecords {
+			switch _, exists := paxHdrs[k]; {
+			case exists:
+				continue // Do not overwrite existing records
+			case h.Typeflag == TypeXGlobalHeader:
+				paxHdrs[k] = v // Copy all records
+			case !basicKeys[k] && !strings.HasPrefix(k, paxGNUSparse):
+				paxHdrs[k] = v // Ignore local records that may conflict
+			}
+		}
+		whyOnlyPAX = "only PAX supports PAXRecords"
+		format.mayOnlyBe(FormatPAX)
+	}
+	for k, v := range paxHdrs {
+		if !validPAXRecord(k, v) {
+			return FormatUnknown, nil, headerError{fmt.Sprintf("invalid PAX record: %q", k+" = "+v)}
+		}
+	}
+
+	// TODO(dsnet): Re-enable this when adding sparse support.
+	// See https://golang.org/issue/22735
+	/*
+		// Check sparse files.
+		if len(h.SparseHoles) > 0 || h.Typeflag == TypeGNUSparse {
+			if isHeaderOnlyType(h.Typeflag) {
+				return FormatUnknown, nil, headerError{"header-only type cannot be sparse"}
+			}
+			if !validateSparseEntries(h.SparseHoles, h.Size) {
+				return FormatUnknown, nil, headerError{"invalid sparse holes"}
+			}
+			if h.Typeflag == TypeGNUSparse {
+				whyOnlyGNU = "only GNU supports TypeGNUSparse"
+				format.mayOnlyBe(FormatGNU)
+			} else {
+				whyNoGNU = "GNU supports sparse files only with TypeGNUSparse"
+				format.mustNotBe(FormatGNU)
+			}
+			whyNoUSTAR = "USTAR does not support sparse files"
+			format.mustNotBe(FormatUSTAR)
+		}
+	*/
+
+	// Check desired format.
+	if wantFormat := h.Format; wantFormat != FormatUnknown {
+		if wantFormat.has(FormatPAX) && !preferPAX {
+			wantFormat.mayBe(FormatUSTAR) // PAX implies USTAR allowed too
+		}
+		format.mayOnlyBe(wantFormat) // Set union of formats allowed and format wanted
+	}
+	if format == FormatUnknown {
+		switch h.Format {
+		case FormatUSTAR:
+			err = headerError{"Format specifies USTAR", whyNoUSTAR, whyOnlyPAX, whyOnlyGNU}
+		case FormatPAX:
+			err = headerError{"Format specifies PAX", whyNoPAX, whyOnlyGNU}
+		case FormatGNU:
+			err = headerError{"Format specifies GNU", whyNoGNU, whyOnlyPAX}
+		default:
+			err = headerError{whyNoUSTAR, whyNoPAX, whyNoGNU, whyOnlyPAX, whyOnlyGNU}
+		}
+	}
+	return format, paxHdrs, err
 }
 
 // FileInfo returns an os.FileInfo for the Header.
@@ -92,63 +552,43 @@
 
 	// Set setuid, setgid and sticky bits.
 	if fi.h.Mode&c_ISUID != 0 {
-		// setuid
 		mode |= os.ModeSetuid
 	}
 	if fi.h.Mode&c_ISGID != 0 {
-		// setgid
 		mode |= os.ModeSetgid
 	}
 	if fi.h.Mode&c_ISVTX != 0 {
-		// sticky
 		mode |= os.ModeSticky
 	}
 
-	// Set file mode bits.
-	// clear perm, setuid, setgid and sticky bits.
-	m := os.FileMode(fi.h.Mode) &^ 07777
-	if m == c_ISDIR {
-		// directory
+	// Set file mode bits; clear perm, setuid, setgid, and sticky bits.
+	switch m := os.FileMode(fi.h.Mode) &^ 07777; m {
+	case c_ISDIR:
 		mode |= os.ModeDir
-	}
-	if m == c_ISFIFO {
-		// named pipe (FIFO)
+	case c_ISFIFO:
 		mode |= os.ModeNamedPipe
-	}
-	if m == c_ISLNK {
-		// symbolic link
+	case c_ISLNK:
 		mode |= os.ModeSymlink
-	}
-	if m == c_ISBLK {
-		// device file
+	case c_ISBLK:
 		mode |= os.ModeDevice
-	}
-	if m == c_ISCHR {
-		// Unix character device
+	case c_ISCHR:
 		mode |= os.ModeDevice
 		mode |= os.ModeCharDevice
-	}
-	if m == c_ISSOCK {
-		// Unix domain socket
+	case c_ISSOCK:
 		mode |= os.ModeSocket
 	}
 
 	switch fi.h.Typeflag {
 	case TypeSymlink:
-		// symbolic link
 		mode |= os.ModeSymlink
 	case TypeChar:
-		// character device node
 		mode |= os.ModeDevice
 		mode |= os.ModeCharDevice
 	case TypeBlock:
-		// block device node
 		mode |= os.ModeDevice
 	case TypeDir:
-		// directory
 		mode |= os.ModeDir
 	case TypeFifo:
-		// fifo node
 		mode |= os.ModeNamedPipe
 	}
 
@@ -176,33 +616,16 @@
 	c_ISSOCK = 0140000 // Socket
 )
 
-// Keywords for the PAX Extended Header
-const (
-	paxAtime    = "atime"
-	paxCharset  = "charset"
-	paxComment  = "comment"
-	paxCtime    = "ctime" // please note that ctime is not a valid pax header.
-	paxGid      = "gid"
-	paxGname    = "gname"
-	paxLinkpath = "linkpath"
-	paxMtime    = "mtime"
-	paxPath     = "path"
-	paxSize     = "size"
-	paxUid      = "uid"
-	paxUname    = "uname"
-	paxXattr    = "SCHILY.xattr."
-	paxNone     = ""
-)
-
 // FileInfoHeader creates a partially-populated Header from fi.
 // If fi describes a symlink, FileInfoHeader records link as the link target.
 // If fi describes a directory, a slash is appended to the name.
-// Because os.FileInfo's Name method returns only the base name of
-// the file it describes, it may be necessary to modify the Name field
-// of the returned header to provide the full path name of the file.
+//
+// Since os.FileInfo's Name method only returns the base name of
+// the file it describes, it may be necessary to modify Header.Name
+// to provide the full path name of the file.
 func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
 	if fi == nil {
-		return nil, errors.New("tar: FileInfo is nil")
+		return nil, errors.New("archive/tar: FileInfo is nil")
 	}
 	fm := fi.Mode()
 	h := &Header{
@@ -265,6 +688,12 @@
 			h.Size = 0
 			h.Linkname = sys.Linkname
 		}
+		if sys.PAXRecords != nil {
+			h.PAXRecords = make(map[string]string)
+			for k, v := range sys.PAXRecords {
+				h.PAXRecords[k] = v
+			}
+		}
 	}
 	if sysStat != nil {
 		return h, sysStat(fi, h)
@@ -282,3 +711,10 @@
 		return false
 	}
 }
+
+func min(a, b int64) int64 {
+	if a < b {
+		return a
+	}
+	return b
+}
diff --git a/src/archive/tar/example_test.go b/src/archive/tar/example_test.go
index 5f0ce2f..a2474b9 100644
--- a/src/archive/tar/example_test.go
+++ b/src/archive/tar/example_test.go
@@ -13,14 +13,10 @@
 	"os"
 )
 
-func Example() {
-	// Create a buffer to write our archive to.
-	buf := new(bytes.Buffer)
-
-	// Create a new tar archive.
-	tw := tar.NewWriter(buf)
-
-	// Add some files to the archive.
+func Example_minimal() {
+	// Create and add some files to the archive.
+	var buf bytes.Buffer
+	tw := tar.NewWriter(&buf)
 	var files = []struct {
 		Name, Body string
 	}{
@@ -35,34 +31,29 @@
 			Size: int64(len(file.Body)),
 		}
 		if err := tw.WriteHeader(hdr); err != nil {
-			log.Fatalln(err)
+			log.Fatal(err)
 		}
 		if _, err := tw.Write([]byte(file.Body)); err != nil {
-			log.Fatalln(err)
+			log.Fatal(err)
 		}
 	}
-	// Make sure to check the error on Close.
 	if err := tw.Close(); err != nil {
-		log.Fatalln(err)
+		log.Fatal(err)
 	}
 
-	// Open the tar archive for reading.
-	r := bytes.NewReader(buf.Bytes())
-	tr := tar.NewReader(r)
-
-	// Iterate through the files in the archive.
+	// Open and iterate through the files in the archive.
+	tr := tar.NewReader(&buf)
 	for {
 		hdr, err := tr.Next()
 		if err == io.EOF {
-			// end of tar archive
-			break
+			break // End of archive
 		}
 		if err != nil {
-			log.Fatalln(err)
+			log.Fatal(err)
 		}
 		fmt.Printf("Contents of %s:\n", hdr.Name)
 		if _, err := io.Copy(os.Stdout, tr); err != nil {
-			log.Fatalln(err)
+			log.Fatal(err)
 		}
 		fmt.Println()
 	}
diff --git a/src/archive/tar/format.go b/src/archive/tar/format.go
index c2c9910..6e29698 100644
--- a/src/archive/tar/format.go
+++ b/src/archive/tar/format.go
@@ -4,38 +4,133 @@
 
 package tar
 
+import "strings"
+
+// Format represents the tar archive format.
+//
+// The original tar format was introduced in Unix V7.
+// Since then, there have been multiple competing formats attempting to
+// standardize or extend the V7 format to overcome its limitations.
+// The most common formats are the USTAR, PAX, and GNU formats,
+// each with their own advantages and limitations.
+//
+// The following table captures the capabilities of each format:
+//
+//	                  |  USTAR |       PAX |       GNU
+//	------------------+--------+-----------+----------
+//	Name              |   256B | unlimited | unlimited
+//	Linkname          |   100B | unlimited | unlimited
+//	Size              | uint33 | unlimited |    uint89
+//	Mode              | uint21 |    uint21 |    uint57
+//	Uid/Gid           | uint21 | unlimited |    uint57
+//	Uname/Gname       |    32B | unlimited |       32B
+//	ModTime           | uint33 | unlimited |     int89
+//	AccessTime        |    n/a | unlimited |     int89
+//	ChangeTime        |    n/a | unlimited |     int89
+//	Devmajor/Devminor | uint21 |    uint21 |    uint57
+//	------------------+--------+-----------+----------
+//	string encoding   |  ASCII |     UTF-8 |    binary
+//	sub-second times  |     no |       yes |        no
+//	sparse files      |     no |       yes |       yes
+//
+// The table's upper portion shows the Header fields, where each format reports
+// the maximum number of bytes allowed for each string field and
+// the integer type used to store each numeric field
+// (where timestamps are stored as the number of seconds since the Unix epoch).
+//
+// The table's lower portion shows specialized features of each format,
+// such as supported string encodings, support for sub-second timestamps,
+// or support for sparse files.
+//
+// The Writer currently provides no support for sparse files.
+type Format int
+
 // Constants to identify various tar formats.
 const (
-	// The format is unknown.
-	formatUnknown = (1 << iota) / 2 // Sequence of 0, 1, 2, 4, 8, etc...
+	// Deliberately hide the meaning of constants from public API.
+	_ Format = (1 << iota) / 4 // Sequence of 0, 0, 1, 2, 4, 8, etc...
+
+	// FormatUnknown indicates that the format is unknown.
+	FormatUnknown
 
 	// The format of the original Unix V7 tar tool prior to standardization.
 	formatV7
 
-	// The old and new GNU formats, which are incompatible with USTAR.
-	// This does cover the old GNU sparse extension.
-	// This does not cover the GNU sparse extensions using PAX headers,
-	// versions 0.0, 0.1, and 1.0; these fall under the PAX format.
-	formatGNU
+	// FormatUSTAR represents the USTAR header format defined in POSIX.1-1988.
+	//
+	// While this format is compatible with most tar readers,
+	// the format has several limitations making it unsuitable for some usages.
+	// Most notably, it cannot support sparse files, files larger than 8GiB,
+	// filenames larger than 256 characters, and non-ASCII filenames.
+	//
+	// Reference:
+	//	http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06
+	FormatUSTAR
+
+	// FormatPAX represents the PAX header format defined in POSIX.1-2001.
+	//
+	// PAX extends USTAR by writing a special file with Typeflag TypeXHeader
+	// preceding the original header. This file contains a set of key-value
+	// records, which are used to overcome USTAR's shortcomings, in addition to
+	// providing the ability to have sub-second resolution for timestamps.
+	//
+	// Some newer formats add their own extensions to PAX by defining their
+	// own keys and assigning certain semantic meaning to the associated values.
+	// For example, sparse file support in PAX is implemented using keys
+	// defined by the GNU manual (e.g., "GNU.sparse.map").
+	//
+	// Reference:
+	//	http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html
+	FormatPAX
+
+	// FormatGNU represents the GNU header format.
+	//
+	// The GNU header format is older than the USTAR and PAX standards and
+	// is not compatible with them. The GNU format supports
+	// arbitrary file sizes, filenames of arbitrary encoding and length,
+	// sparse files, and other features.
+	//
+	// It is recommended that PAX be chosen over GNU unless the target
+	// application can only parse GNU formatted archives.
+	//
+	// Reference:
+	//	http://www.gnu.org/software/tar/manual/html_node/Standard.html
+	FormatGNU
 
 	// Schily's tar format, which is incompatible with USTAR.
 	// This does not cover STAR extensions to the PAX format; these fall under
 	// the PAX format.
 	formatSTAR
 
-	// USTAR is the former standardization of tar defined in POSIX.1-1988.
-	// This is incompatible with the GNU and STAR formats.
-	formatUSTAR
-
-	// PAX is the latest standardization of tar defined in POSIX.1-2001.
-	// This is an extension of USTAR and is "backwards compatible" with it.
-	//
-	// Some newer formats add their own extensions to PAX, such as GNU sparse
-	// files and SCHILY extended attributes. Since they are backwards compatible
-	// with PAX, they will be labelled as "PAX".
-	formatPAX
+	formatMax
 )
 
+func (f Format) has(f2 Format) bool   { return f&f2 != 0 }
+func (f *Format) mayBe(f2 Format)     { *f |= f2 }
+func (f *Format) mayOnlyBe(f2 Format) { *f &= f2 }
+func (f *Format) mustNotBe(f2 Format) { *f &^= f2 }
+
+var formatNames = map[Format]string{
+	formatV7: "V7", FormatUSTAR: "USTAR", FormatPAX: "PAX", FormatGNU: "GNU", formatSTAR: "STAR",
+}
+
+func (f Format) String() string {
+	var ss []string
+	for f2 := Format(1); f2 < formatMax; f2 <<= 1 {
+		if f.has(f2) {
+			ss = append(ss, formatNames[f2])
+		}
+	}
+	switch len(ss) {
+	case 0:
+		return "<unknown>"
+	case 1:
+		return ss[0]
+	default:
+		return "(" + strings.Join(ss, " | ") + ")"
+	}
+}
+
 // Magics used to identify various formats.
 const (
 	magicGNU, versionGNU     = "ustar ", " \x00"
@@ -50,6 +145,12 @@
 	prefixSize = 155 // Max length of the prefix field in USTAR format
 )
 
+// blockPadding computes the number of bytes needed to pad offset up to the
+// nearest block edge where 0 <= n < blockSize.
+func blockPadding(offset int64) (n int64) {
+	return -offset & (blockSize - 1)
+}
+
 var zeroBlock block
 
 type block [blockSize]byte
@@ -63,14 +164,14 @@
 
 // GetFormat checks that the block is a valid tar header based on the checksum.
 // It then attempts to guess the specific format based on magic values.
-// If the checksum fails, then formatUnknown is returned.
-func (b *block) GetFormat() (format int) {
+// If the checksum fails, then FormatUnknown is returned.
+func (b *block) GetFormat() Format {
 	// Verify checksum.
 	var p parser
 	value := p.parseOctal(b.V7().Chksum())
 	chksum1, chksum2 := b.ComputeChecksum()
 	if p.err != nil || (value != chksum1 && value != chksum2) {
-		return formatUnknown
+		return FormatUnknown
 	}
 
 	// Guess the magic values.
@@ -81,9 +182,9 @@
 	case magic == magicUSTAR && trailer == trailerSTAR:
 		return formatSTAR
 	case magic == magicUSTAR:
-		return formatUSTAR
+		return FormatUSTAR | FormatPAX
 	case magic == magicGNU && version == versionGNU:
-		return formatGNU
+		return FormatGNU
 	default:
 		return formatV7
 	}
@@ -91,19 +192,19 @@
 
 // SetFormat writes the magic values necessary for specified format
 // and then updates the checksum accordingly.
-func (b *block) SetFormat(format int) {
+func (b *block) SetFormat(format Format) {
 	// Set the magic values.
-	switch format {
-	case formatV7:
+	switch {
+	case format.has(formatV7):
 		// Do nothing.
-	case formatGNU:
+	case format.has(FormatGNU):
 		copy(b.GNU().Magic(), magicGNU)
 		copy(b.GNU().Version(), versionGNU)
-	case formatSTAR:
+	case format.has(formatSTAR):
 		copy(b.STAR().Magic(), magicUSTAR)
 		copy(b.STAR().Version(), versionUSTAR)
 		copy(b.STAR().Trailer(), trailerSTAR)
-	case formatUSTAR, formatPAX:
+	case format.has(FormatUSTAR | FormatPAX):
 		copy(b.USTAR().Magic(), magicUSTAR)
 		copy(b.USTAR().Version(), versionUSTAR)
 	default:
@@ -128,12 +229,17 @@
 		if 148 <= i && i < 156 {
 			c = ' ' // Treat the checksum field itself as all spaces.
 		}
-		unsigned += int64(uint8(c))
+		unsigned += int64(c)
 		signed += int64(int8(c))
 	}
 	return unsigned, signed
 }
 
+// Reset clears the block with all zeros.
+func (b *block) Reset() {
+	*b = block{}
+}
+
 type headerV7 [blockSize]byte
 
 func (h *headerV7) Name() []byte     { return h[000:][:100] }
@@ -187,11 +293,11 @@
 
 type sparseArray []byte
 
-func (s sparseArray) Entry(i int) sparseNode { return (sparseNode)(s[i*24:]) }
+func (s sparseArray) Entry(i int) sparseElem { return (sparseElem)(s[i*24:]) }
 func (s sparseArray) IsExtended() []byte     { return s[24*s.MaxEntries():][:1] }
 func (s sparseArray) MaxEntries() int        { return len(s) / 24 }
 
-type sparseNode []byte
+type sparseElem []byte
 
-func (s sparseNode) Offset() []byte   { return s[00:][:12] }
-func (s sparseNode) NumBytes() []byte { return s[12:][:12] }
+func (s sparseElem) Offset() []byte { return s[00:][:12] }
+func (s sparseElem) Length() []byte { return s[12:][:12] }
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
index 9abe888..f4eeb55 100644
--- a/src/archive/tar/reader.go
+++ b/src/archive/tar/reader.go
@@ -4,33 +4,23 @@
 
 package tar
 
-// TODO(dsymonds):
-//   - pax extensions
-
 import (
 	"bytes"
-	"errors"
 	"io"
 	"io/ioutil"
-	"math"
 	"strconv"
 	"strings"
 	"time"
 )
 
-var (
-	ErrHeader = errors.New("archive/tar: invalid tar header")
-)
-
-// 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.
+// Reader provides sequential access to the contents of a tar archive.
+// Reader.Next advances to the next file in the archive (including the first),
+// and then Reader can be treated as an io.Reader to access the file's data.
 type Reader struct {
 	r    io.Reader
-	pad  int64          // amount of padding (ignored) after current file entry
-	curr numBytesReader // reader for current file entry
-	blk  block          // buffer to use as temporary local storage
+	pad  int64      // Amount of padding (ignored) after current file entry
+	curr fileReader // Reader for current file entry
+	blk  block      // Buffer to use as temporary local storage
 
 	// err is a persistent error.
 	// It is only the responsibility of every exported method of Reader to
@@ -38,68 +28,21 @@
 	err error
 }
 
-// A numBytesReader is an io.Reader with a numBytes method, returning the number
-// of bytes remaining in the underlying encoded data.
-type numBytesReader interface {
+type fileReader interface {
 	io.Reader
-	numBytes() int64
-}
+	fileState
 
-// 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
+	WriteTo(io.Writer) (int64, error)
 }
 
-// A sparseFileReader is a numBytesReader for reading sparse file data from a
-// tar archive.
-type sparseFileReader struct {
-	rfr   numBytesReader // Reads the sparse-encoded file data
-	sp    []sparseEntry  // The sparse map for the file
-	pos   int64          // Keeps track of file position
-	total int64          // Total size of the file
-}
-
-// A sparseEntry holds a single entry in a sparse file's sparse map.
-//
-// Sparse files are represented using a series of sparseEntrys.
-// Despite the name, a sparseEntry represents an actual data fragment that
-// references data found in the underlying archive stream. All regions not
-// covered by a sparseEntry are logically filled with zeros.
-//
-// For example, if the underlying raw file contains the 10-byte data:
-//	var compactData = "abcdefgh"
-//
-// And the sparse map has the following entries:
-//	var sp = []sparseEntry{
-//		{offset: 2,  numBytes: 5} // Data fragment for [2..7]
-//		{offset: 18, numBytes: 3} // Data fragment for [18..21]
-//	}
-//
-// Then the content of the resulting sparse file with a "real" size of 25 is:
-//	var sparseData = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4
-type sparseEntry struct {
-	offset   int64 // Starting position of the fragment
-	numBytes int64 // Length of the fragment
-}
-
-// 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"
-)
-
 // NewReader creates a new Reader reading from r.
-func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
+func NewReader(r io.Reader) *Reader {
+	return &Reader{r: r, curr: &regFileReader{r, 0}}
+}
 
 // Next advances to the next entry in the tar archive.
+// The Header.Size determines how many bytes can be read for the next file.
+// Any remaining data in the current file is automatically discarded.
 //
 // io.EOF is returned at the end of the input.
 func (tr *Reader) Next() (*Header, error) {
@@ -112,18 +55,26 @@
 }
 
 func (tr *Reader) next() (*Header, error) {
-	var extHdrs map[string]string
+	var paxHdrs map[string]string
+	var gnuLongName, gnuLongLink string
 
 	// Externally, Next iterates through the tar archive as if it is a series of
 	// files. Internally, the tar format often uses fake "files" to add meta
 	// data that describes the next file. These meta data "files" should not
 	// normally be visible to the outside. As such, this loop iterates through
 	// one or more "header files" until it finds a "normal file".
+	format := FormatUSTAR | FormatPAX | FormatGNU
 loop:
 	for {
-		if err := tr.skipUnread(); err != nil {
+		// Discard the remainder of the file and any padding.
+		if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil {
 			return nil, err
 		}
+		if _, err := tryReadFull(tr.r, tr.blk[:tr.pad]); err != nil {
+			return nil, err
+		}
+		tr.pad = 0
+
 		hdr, rawHdr, err := tr.readHeader()
 		if err != nil {
 			return nil, err
@@ -131,43 +82,58 @@
 		if err := tr.handleRegularFile(hdr); err != nil {
 			return nil, err
 		}
+		format.mayOnlyBe(hdr.Format)
 
 		// Check for PAX/GNU special headers and files.
 		switch hdr.Typeflag {
-		case TypeXHeader:
-			extHdrs, err = parsePAX(tr)
+		case TypeXHeader, TypeXGlobalHeader:
+			format.mayOnlyBe(FormatPAX)
+			paxHdrs, err = parsePAX(tr)
 			if err != nil {
 				return nil, err
 			}
+			if hdr.Typeflag == TypeXGlobalHeader {
+				mergePAX(hdr, paxHdrs)
+				return &Header{
+					Name:       hdr.Name,
+					Typeflag:   hdr.Typeflag,
+					Xattrs:     hdr.Xattrs,
+					PAXRecords: hdr.PAXRecords,
+					Format:     format,
+				}, nil
+			}
 			continue loop // This is a meta header affecting the next header
 		case TypeGNULongName, TypeGNULongLink:
+			format.mayOnlyBe(FormatGNU)
 			realname, err := ioutil.ReadAll(tr)
 			if err != nil {
 				return nil, err
 			}
 
-			// Convert GNU extensions to use PAX headers.
-			if extHdrs == nil {
-				extHdrs = make(map[string]string)
-			}
 			var p parser
 			switch hdr.Typeflag {
 			case TypeGNULongName:
-				extHdrs[paxPath] = p.parseString(realname)
+				gnuLongName = p.parseString(realname)
 			case TypeGNULongLink:
-				extHdrs[paxLinkpath] = p.parseString(realname)
-			}
-			if p.err != nil {
-				return nil, p.err
+				gnuLongLink = p.parseString(realname)
 			}
 			continue loop // This is a meta header affecting the next header
 		default:
 			// The old GNU sparse format is handled here since it is technically
 			// just a regular file with additional attributes.
 
-			if err := mergePAX(hdr, extHdrs); err != nil {
+			if err := mergePAX(hdr, paxHdrs); err != nil {
 				return nil, err
 			}
+			if gnuLongName != "" {
+				hdr.Name = gnuLongName
+			}
+			if gnuLongLink != "" {
+				hdr.Linkname = gnuLongLink
+			}
+			if hdr.Typeflag == TypeRegA && strings.HasSuffix(hdr.Name, "/") {
+				hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
+			}
 
 			// The extended headers may have updated the size.
 			// Thus, setup the regFileReader again after merging PAX headers.
@@ -177,9 +143,15 @@
 
 			// Sparse formats rely on being able to read from the logical data
 			// section; there must be a preceding call to handleRegularFile.
-			if err := tr.handleSparseFile(hdr, rawHdr, extHdrs); err != nil {
+			if err := tr.handleSparseFile(hdr, rawHdr); err != nil {
 				return nil, err
 			}
+
+			// Set the final guess at the format.
+			if format.has(FormatUSTAR) && format.has(FormatPAX) {
+				format.mayOnlyBe(FormatUSTAR)
+			}
+			hdr.Format = format
 			return hdr, nil // This is a file, so stop
 		}
 	}
@@ -197,105 +169,86 @@
 		return ErrHeader
 	}
 
-	tr.pad = -nb & (blockSize - 1) // blockSize is a power of two
+	tr.pad = blockPadding(nb)
 	tr.curr = &regFileReader{r: tr.r, nb: nb}
 	return nil
 }
 
 // handleSparseFile checks if the current file is a sparse format of any type
 // and sets the curr reader appropriately.
-func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block, extHdrs map[string]string) error {
-	var sp []sparseEntry
+func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
+	var spd sparseDatas
 	var err error
 	if hdr.Typeflag == TypeGNUSparse {
-		sp, err = tr.readOldGNUSparseMap(hdr, rawHdr)
-		if err != nil {
-			return err
-		}
+		spd, err = tr.readOldGNUSparseMap(hdr, rawHdr)
 	} else {
-		sp, err = tr.checkForGNUSparsePAXHeaders(hdr, extHdrs)
-		if err != nil {
-			return err
-		}
+		spd, err = tr.readGNUSparsePAXHeaders(hdr)
 	}
 
 	// If sp is non-nil, then this is a sparse file.
-	// Note that it is possible for len(sp) to be zero.
-	if sp != nil {
-		tr.curr, err = newSparseFileReader(tr.curr, sp, hdr.Size)
+	// Note that it is possible for len(sp) == 0.
+	if err == nil && spd != nil {
+		if isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) {
+			return ErrHeader
+		}
+		sph := invertSparseEntries(spd, hdr.Size)
+		tr.curr = &sparseFileReader{tr.curr, sph, 0}
 	}
 	return 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
+// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
+// If they are found, then this function reads the sparse map and returns it.
+// This assumes that 0.0 headers have already been converted to 0.1 headers
+// by the the PAX header parsing logic.
+func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
+	// Identify the version of GNU headers.
+	var is1x0 bool
+	major, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor]
+	switch {
+	case major == "0" && (minor == "0" || minor == "1"):
+		is1x0 = false
+	case major == "1" && minor == "0":
+		is1x0 = true
+	case major != "" || minor != "":
+		return nil, nil // Unknown GNU sparse PAX version
+	case hdr.PAXRecords[paxGNUSparseMap] != "":
+		is1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess
+	default:
+		return nil, nil // Not a PAX format GNU sparse file.
 	}
+	hdr.Format.mayOnlyBe(FormatPAX)
 
-	// 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 name := hdr.PAXRecords[paxGNUSparseName]; name != "" {
+		hdr.Name = name
 	}
-
-	// Update hdr from GNU sparse PAX headers
-	if sparseNameOk {
-		hdr.Name = sparseName
+	size := hdr.PAXRecords[paxGNUSparseSize]
+	if size == "" {
+		size = hdr.PAXRecords[paxGNUSparseRealSize]
 	}
-	if sparseSizeOk {
-		realSize, err := strconv.ParseInt(sparseSize, 10, 64)
+	if size != "" {
+		n, err := strconv.ParseInt(size, 10, 64)
 		if err != nil {
 			return nil, ErrHeader
 		}
-		hdr.Size = realSize
-	} else if sparseRealSizeOk {
-		realSize, err := strconv.ParseInt(sparseRealSize, 10, 64)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		hdr.Size = realSize
+		hdr.Size = n
 	}
 
-	// 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)
+	// Read the sparse map according to the appropriate format.
+	if is1x0 {
+		return readGNUSparseMap1x0(tr.curr)
 	}
-	return sp, err
+	return readGNUSparseMap0x1(hdr.PAXRecords)
 }
 
-// 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) (err error) {
-	var id64 int64
-	for k, v := range headers {
+// mergePAX merges paxHdrs into hdr for all relevant fields of Header.
+func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
+	for k, v := range paxHdrs {
+		if v == "" {
+			continue // Keep the original USTAR value
+		}
+		var id64 int64
 		switch k {
 		case paxPath:
 			hdr.Name = v
@@ -320,17 +273,18 @@
 		case paxSize:
 			hdr.Size, err = strconv.ParseInt(v, 10, 64)
 		default:
-			if strings.HasPrefix(k, paxXattr) {
+			if strings.HasPrefix(k, paxSchilyXattr) {
 				if hdr.Xattrs == nil {
 					hdr.Xattrs = make(map[string]string)
 				}
-				hdr.Xattrs[k[len(paxXattr):]] = v
+				hdr.Xattrs[k[len(paxSchilyXattr):]] = v
 			}
 		}
 		if err != nil {
 			return ErrHeader
 		}
 	}
+	hdr.PAXRecords = paxHdrs
 	return nil
 }
 
@@ -348,7 +302,7 @@
 	// headers since 0.0 headers were not PAX compliant.
 	var sparseMap []string
 
-	extHdrs := make(map[string]string)
+	paxHdrs := make(map[string]string)
 	for len(sbuf) > 0 {
 		key, value, residual, err := parsePAXRecord(sbuf)
 		if err != nil {
@@ -366,58 +320,13 @@
 			}
 			sparseMap = append(sparseMap, value)
 		default:
-			// According to PAX specification, a value is stored only if it is
-			// non-empty. Otherwise, the key is deleted.
-			if len(value) > 0 {
-				extHdrs[key] = value
-			} else {
-				delete(extHdrs, key)
-			}
+			paxHdrs[key] = value
 		}
 	}
 	if len(sparseMap) > 0 {
-		extHdrs[paxGNUSparseMap] = strings.Join(sparseMap, ",")
+		paxHdrs[paxGNUSparseMap] = strings.Join(sparseMap, ",")
 	}
-	return extHdrs, nil
-}
-
-// skipUnread skips any unread bytes in the existing file entry, as well as any
-// alignment padding. It returns io.ErrUnexpectedEOF if any io.EOF is
-// encountered in the data portion; it is okay to hit io.EOF in the padding.
-//
-// Note that this function still works properly even when sparse files are being
-// used since numBytes returns the bytes remaining in the underlying io.Reader.
-func (tr *Reader) skipUnread() error {
-	dataSkip := tr.numBytes()      // Number of data bytes to skip
-	totalSkip := dataSkip + tr.pad // Total number of bytes to skip
-	tr.curr, tr.pad = nil, 0
-
-	// If possible, Seek to the last byte before the end of the data section.
-	// Do this because Seek is often lazy about reporting errors; this will mask
-	// the fact that the tar stream may be truncated. We can rely on the
-	// io.CopyN done shortly afterwards to trigger any IO errors.
-	var seekSkipped int64 // Number of bytes skipped via Seek
-	if sr, ok := tr.r.(io.Seeker); ok && dataSkip > 1 {
-		// Not all io.Seeker can actually Seek. For example, os.Stdin implements
-		// io.Seeker, but calling Seek always returns an error and performs
-		// no action. Thus, we try an innocent seek to the current position
-		// to see if Seek is really supported.
-		pos1, err := sr.Seek(0, io.SeekCurrent)
-		if err == nil {
-			// Seek seems supported, so perform the real Seek.
-			pos2, err := sr.Seek(dataSkip-1, io.SeekCurrent)
-			if err != nil {
-				return err
-			}
-			seekSkipped = pos2 - pos1
-		}
-	}
-
-	copySkipped, err := io.CopyN(ioutil.Discard, tr.r, totalSkip-seekSkipped)
-	if err == io.EOF && seekSkipped+copySkipped < dataSkip {
-		err = io.ErrUnexpectedEOF
-	}
-	return err
+	return paxHdrs, nil
 }
 
 // readHeader reads the next block header and assumes that the underlying reader
@@ -445,7 +354,7 @@
 
 	// Verify the header matches a known format.
 	format := tr.blk.GetFormat()
-	if format == formatUnknown {
+	if format == FormatUnknown {
 		return nil, nil, ErrHeader
 	}
 
@@ -454,59 +363,86 @@
 
 	// Unpack the V7 header.
 	v7 := tr.blk.V7()
+	hdr.Typeflag = v7.TypeFlag()[0]
 	hdr.Name = p.parseString(v7.Name())
+	hdr.Linkname = p.parseString(v7.LinkName())
+	hdr.Size = p.parseNumeric(v7.Size())
 	hdr.Mode = p.parseNumeric(v7.Mode())
 	hdr.Uid = int(p.parseNumeric(v7.UID()))
 	hdr.Gid = int(p.parseNumeric(v7.GID()))
-	hdr.Size = p.parseNumeric(v7.Size())
 	hdr.ModTime = time.Unix(p.parseNumeric(v7.ModTime()), 0)
-	hdr.Typeflag = v7.TypeFlag()[0]
-	hdr.Linkname = p.parseString(v7.LinkName())
-
-	// The atime and ctime fields are often left unused. Some versions of Go
-	// had a bug in the tar.Writer where it would output an invalid tar file
-	// in certain rare situations because the logic incorrectly believed that
-	// the old GNU format had a prefix field. This is wrong and leads to
-	// an outputted file that actually mangles the atime and ctime fields.
-	//
-	// In order to continue reading tar files created by a buggy writer, we
-	// try to parse the atime and ctime fields, but just return the zero value
-	// of time.Time when we cannot parse them.
-	//
-	// See https://golang.org/issues/12594
-	tryParseTime := func(b []byte) time.Time {
-		var p parser
-		n := p.parseNumeric(b)
-		if b[0] != 0x00 && p.err == nil {
-			return time.Unix(n, 0)
-		}
-		return time.Time{}
-	}
 
 	// Unpack format specific fields.
 	if format > formatV7 {
 		ustar := tr.blk.USTAR()
 		hdr.Uname = p.parseString(ustar.UserName())
 		hdr.Gname = p.parseString(ustar.GroupName())
-		if hdr.Typeflag == TypeChar || hdr.Typeflag == TypeBlock {
-			hdr.Devmajor = p.parseNumeric(ustar.DevMajor())
-			hdr.Devminor = p.parseNumeric(ustar.DevMinor())
-		}
+		hdr.Devmajor = p.parseNumeric(ustar.DevMajor())
+		hdr.Devminor = p.parseNumeric(ustar.DevMinor())
 
 		var prefix string
-		switch format {
-		case formatUSTAR:
+		switch {
+		case format.has(FormatUSTAR | FormatPAX):
+			hdr.Format = format
 			ustar := tr.blk.USTAR()
 			prefix = p.parseString(ustar.Prefix())
-		case formatSTAR:
+
+			// For Format detection, check if block is properly formatted since
+			// the parser is more liberal than what USTAR actually permits.
+			notASCII := func(r rune) bool { return r >= 0x80 }
+			if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {
+				hdr.Format = FormatUnknown // Non-ASCII characters in block.
+			}
+			nul := func(b []byte) bool { return int(b[len(b)-1]) == 0 }
+			if !(nul(v7.Size()) && nul(v7.Mode()) && nul(v7.UID()) && nul(v7.GID()) &&
+				nul(v7.ModTime()) && nul(ustar.DevMajor()) && nul(ustar.DevMinor())) {
+				hdr.Format = FormatUnknown // Numeric fields must end in NUL
+			}
+		case format.has(formatSTAR):
 			star := tr.blk.STAR()
 			prefix = p.parseString(star.Prefix())
 			hdr.AccessTime = time.Unix(p.parseNumeric(star.AccessTime()), 0)
 			hdr.ChangeTime = time.Unix(p.parseNumeric(star.ChangeTime()), 0)
-		case formatGNU:
+		case format.has(FormatGNU):
+			hdr.Format = format
+			var p2 parser
 			gnu := tr.blk.GNU()
-			hdr.AccessTime = tryParseTime(gnu.AccessTime())
-			hdr.ChangeTime = tryParseTime(gnu.ChangeTime())
+			if b := gnu.AccessTime(); b[0] != 0 {
+				hdr.AccessTime = time.Unix(p2.parseNumeric(b), 0)
+			}
+			if b := gnu.ChangeTime(); b[0] != 0 {
+				hdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0)
+			}
+
+			// Prior to Go1.8, the Writer had a bug where it would output
+			// an invalid tar file in certain rare situations because the logic
+			// incorrectly believed that the old GNU format had a prefix field.
+			// This is wrong and leads to an output file that mangles the
+			// atime and ctime fields, which are often left unused.
+			//
+			// In order to continue reading tar files created by former, buggy
+			// versions of Go, we skeptically parse the atime and ctime fields.
+			// If we are unable to parse them and the prefix field looks like
+			// an ASCII string, then we fallback on the pre-Go1.8 behavior
+			// of treating these fields as the USTAR prefix field.
+			//
+			// Note that this will not use the fallback logic for all possible
+			// files generated by a pre-Go1.8 toolchain. If the generated file
+			// happened to have a prefix field that parses as valid
+			// atime and ctime fields (e.g., when they are valid octal strings),
+			// then it is impossible to distinguish between an valid GNU file
+			// and an invalid pre-Go1.8 file.
+			//
+			// See https://golang.org/issues/12594
+			// See https://golang.org/issues/21005
+			if p2.err != nil {
+				hdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{}
+				ustar := tr.blk.USTAR()
+				if s := p.parseString(ustar.Prefix()); isASCII(s) {
+					prefix = s
+				}
+				hdr.Format = FormatUnknown // Buggy file is not GNU
+			}
 		}
 		if len(prefix) > 0 {
 			hdr.Name = prefix + "/" + hdr.Name
@@ -523,21 +459,22 @@
 // The Header.Size does not reflect the size of any extended headers used.
 // Thus, this function will read from the raw io.Reader to fetch extra headers.
 // This method mutates blk in the process.
-func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) ([]sparseEntry, error) {
+func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) {
 	// Make sure that the input format is GNU.
 	// Unfortunately, the STAR format also has a sparse header format that uses
 	// the same type flag but has a completely different layout.
-	if blk.GetFormat() != formatGNU {
+	if blk.GetFormat() != FormatGNU {
 		return nil, ErrHeader
 	}
+	hdr.Format.mayOnlyBe(FormatGNU)
 
 	var p parser
 	hdr.Size = p.parseNumeric(blk.GNU().RealSize())
 	if p.err != nil {
 		return nil, p.err
 	}
-	var s sparseArray = blk.GNU().Sparse()
-	var sp = make([]sparseEntry, 0, s.MaxEntries())
+	s := blk.GNU().Sparse()
+	spd := make(sparseDatas, 0, s.MaxEntries())
 	for {
 		for i := 0; i < s.MaxEntries(); i++ {
 			// This termination condition is identical to GNU and BSD tar.
@@ -545,25 +482,22 @@
 				break // Don't return, need to process extended headers (even if empty)
 			}
 			offset := p.parseNumeric(s.Entry(i).Offset())
-			numBytes := p.parseNumeric(s.Entry(i).NumBytes())
+			length := p.parseNumeric(s.Entry(i).Length())
 			if p.err != nil {
 				return nil, p.err
 			}
-			sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+			spd = append(spd, sparseEntry{Offset: offset, Length: length})
 		}
 
 		if s.IsExtended()[0] > 0 {
 			// There are more entries. Read an extension header and parse its entries.
-			if _, err := io.ReadFull(tr.r, blk[:]); err != nil {
-				if err == io.EOF {
-					err = io.ErrUnexpectedEOF
-				}
+			if _, err := mustReadFull(tr.r, blk[:]); err != nil {
 				return nil, err
 			}
 			s = blk.Sparse()
 			continue
 		}
-		return sp, nil // Done
+		return spd, nil // Done
 	}
 }
 
@@ -571,28 +505,27 @@
 // version 1.0. The format of the sparse map consists of a series of
 // newline-terminated numeric fields. The first field is the number of entries
 // and is always present. Following this are the entries, consisting of two
-// fields (offset, numBytes). This function must stop reading at the end
+// fields (offset, length). This function must stop reading at the end
 // boundary of the block containing the last newline.
 //
 // Note that the GNU manual says that numeric values should be encoded in octal
 // format. However, the GNU tar utility itself outputs these values in decimal.
 // As such, this library treats values as being encoded in decimal.
-func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) {
-	var cntNewline int64
-	var buf bytes.Buffer
-	var blk = make([]byte, blockSize)
+func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
+	var (
+		cntNewline int64
+		buf        bytes.Buffer
+		blk        block
+	)
 
-	// feedTokens copies data in numBlock chunks from r into buf until there are
+	// feedTokens copies data in blocks from r into buf until there are
 	// at least cnt newlines in buf. It will not read more blocks than needed.
-	var feedTokens = func(cnt int64) error {
-		for cntNewline < cnt {
-			if _, err := io.ReadFull(r, blk); err != nil {
-				if err == io.EOF {
-					err = io.ErrUnexpectedEOF
-				}
+	feedTokens := func(n int64) error {
+		for cntNewline < n {
+			if _, err := mustReadFull(r, blk[:]); err != nil {
 				return err
 			}
-			buf.Write(blk)
+			buf.Write(blk[:])
 			for _, c := range blk {
 				if c == '\n' {
 					cntNewline++
@@ -604,10 +537,10 @@
 
 	// nextToken gets the next token delimited by a newline. This assumes that
 	// at least one newline exists in the buffer.
-	var nextToken = func() string {
+	nextToken := func() string {
 		cntNewline--
 		tok, _ := buf.ReadString('\n')
-		return tok[:len(tok)-1] // Cut off newline
+		return strings.TrimRight(tok, "\n")
 	}
 
 	// Parse for the number of entries.
@@ -626,80 +559,67 @@
 	if err := feedTokens(2 * numEntries); err != nil {
 		return nil, err
 	}
-	sp := make([]sparseEntry, 0, numEntries)
+	spd := make(sparseDatas, 0, numEntries)
 	for i := int64(0); i < numEntries; i++ {
-		offset, err := strconv.ParseInt(nextToken(), 10, 64)
-		if err != nil {
+		offset, err1 := strconv.ParseInt(nextToken(), 10, 64)
+		length, err2 := strconv.ParseInt(nextToken(), 10, 64)
+		if err1 != nil || err2 != nil {
 			return nil, ErrHeader
 		}
-		numBytes, err := strconv.ParseInt(nextToken(), 10, 64)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+		spd = append(spd, sparseEntry{Offset: offset, Length: length})
 	}
-	return sp, nil
+	return spd, 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(extHdrs map[string]string) ([]sparseEntry, error) {
+func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
 	// Get number of entries.
 	// Use integer overflow resistant math to check this.
-	numEntriesStr := extHdrs[paxGNUSparseNumBlocks]
+	numEntriesStr := paxHdrs[paxGNUSparseNumBlocks]
 	numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int
 	if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
 		return nil, ErrHeader
 	}
 
 	// There should be two numbers in sparseMap for each entry.
-	sparseMap := strings.Split(extHdrs[paxGNUSparseMap], ",")
+	sparseMap := strings.Split(paxHdrs[paxGNUSparseMap], ",")
+	if len(sparseMap) == 1 && sparseMap[0] == "" {
+		sparseMap = sparseMap[:0]
+	}
 	if int64(len(sparseMap)) != 2*numEntries {
 		return nil, ErrHeader
 	}
 
 	// Loop through the entries in the sparse map.
 	// numEntries is trusted now.
-	sp := make([]sparseEntry, 0, numEntries)
-	for i := int64(0); i < numEntries; i++ {
-		offset, err := strconv.ParseInt(sparseMap[2*i], 10, 64)
-		if err != nil {
+	spd := make(sparseDatas, 0, numEntries)
+	for len(sparseMap) >= 2 {
+		offset, err1 := strconv.ParseInt(sparseMap[0], 10, 64)
+		length, err2 := strconv.ParseInt(sparseMap[1], 10, 64)
+		if err1 != nil || err2 != nil {
 			return nil, ErrHeader
 		}
-		numBytes, err := strconv.ParseInt(sparseMap[2*i+1], 10, 64)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+		spd = append(spd, sparseEntry{Offset: offset, Length: length})
+		sparseMap = sparseMap[2:]
 	}
-	return sp, nil
+	return spd, 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.
+// Read reads from the current file in the tar archive.
+// It returns (0, io.EOF) when it reaches the end of that file,
+// until Next is called to advance to the next file.
 //
-// Calling Read on special types like TypeLink, TypeSymLink, TypeChar,
-// TypeBlock, TypeDir, and TypeFifo returns 0, io.EOF regardless of what
+// If the current file is sparse, then the regions marked as a hole
+// are read back as NUL-bytes.
+//
+// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,
+// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what
 // the Header.Size claims.
 func (tr *Reader) Read(b []byte) (int, error) {
 	if tr.err != nil {
 		return 0, tr.err
 	}
-	if tr.curr == nil {
-		return 0, io.EOF
-	}
-
 	n, err := tr.curr.Read(b)
 	if err != nil && err != io.EOF {
 		tr.err = err
@@ -707,116 +627,229 @@
 	return n, err
 }
 
-func (rfr *regFileReader) Read(b []byte) (n int, err error) {
-	if rfr.nb == 0 {
-		// file consumed
-		return 0, io.EOF
+// writeTo writes the content of the current file to w.
+// The bytes written matches the number of remaining bytes in the current file.
+//
+// If the current file is sparse and w is an io.WriteSeeker,
+// then writeTo uses Seek to skip past holes defined in Header.SparseHoles,
+// assuming that skipped regions are filled with NULs.
+// This always writes the last byte to ensure w is the right size.
+//
+// TODO(dsnet): Re-export this when adding sparse file support.
+// See https://golang.org/issue/22735
+func (tr *Reader) writeTo(w io.Writer) (int64, error) {
+	if tr.err != nil {
+		return 0, tr.err
 	}
-	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
-}
-
-// newSparseFileReader creates a new sparseFileReader, but validates all of the
-// sparse entries before doing so.
-func newSparseFileReader(rfr numBytesReader, sp []sparseEntry, total int64) (*sparseFileReader, error) {
-	if total < 0 {
-		return nil, ErrHeader // Total size cannot be negative
-	}
-
-	// Validate all sparse entries. These are the same checks as performed by
-	// the BSD tar utility.
-	for i, s := range sp {
-		switch {
-		case s.offset < 0 || s.numBytes < 0:
-			return nil, ErrHeader // Negative values are never okay
-		case s.offset > math.MaxInt64-s.numBytes:
-			return nil, ErrHeader // Integer overflow with large length
-		case s.offset+s.numBytes > total:
-			return nil, ErrHeader // Region extends beyond the "real" size
-		case i > 0 && sp[i-1].offset+sp[i-1].numBytes > s.offset:
-			return nil, ErrHeader // Regions can't overlap and must be in order
-		}
-	}
-	return &sparseFileReader{rfr: rfr, sp: sp, total: total}, nil
-}
-
-// readHole reads a sparse hole ending at endOffset.
-func (sfr *sparseFileReader) readHole(b []byte, endOffset int64) int {
-	n64 := endOffset - 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) {
-	// Skip past all empty fragments.
-	for len(sfr.sp) > 0 && sfr.sp[0].numBytes == 0 {
-		sfr.sp = sfr.sp[1:]
-	}
-
-	// If there are no more fragments, then it is possible that there
-	// is one last sparse hole.
-	if len(sfr.sp) == 0 {
-		// This behavior matches the BSD tar utility.
-		// However, GNU tar stops returning data even if sfr.total is unmet.
-		if sfr.pos < sfr.total {
-			return sfr.readHole(b, sfr.total), nil
-		}
-		return 0, io.EOF
-	}
-
-	// In front of a data fragment, so read a hole.
-	if sfr.pos < sfr.sp[0].offset {
-		return sfr.readHole(b, sfr.sp[0].offset), nil
-	}
-
-	// In a data fragment, so read from it.
-	// This math is overflow free since we verify that offset and numBytes can
-	// be safely added when creating the sparseFileReader.
-	endPos := sfr.sp[0].offset + sfr.sp[0].numBytes // End offset of fragment
-	bytesLeft := endPos - sfr.pos                   // Bytes left in fragment
-	if int64(len(b)) > bytesLeft {
-		b = b[:bytesLeft]
-	}
-
-	n, err = sfr.rfr.Read(b)
-	sfr.pos += int64(n)
-	if err == io.EOF {
-		if sfr.pos < endPos {
-			err = io.ErrUnexpectedEOF // There was supposed to be more data
-		} else if sfr.pos < sfr.total {
-			err = nil // There is still an implicit sparse hole at the end
-		}
-	}
-
-	if sfr.pos == endPos {
-		sfr.sp = sfr.sp[1:] // We are done with this fragment, so pop it
+	n, err := tr.curr.WriteTo(w)
+	if err != nil {
+		tr.err = err
 	}
 	return n, err
 }
 
-// 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.numBytes()
+// regFileReader is a fileReader for reading data from a regular file entry.
+type regFileReader struct {
+	r  io.Reader // Underlying Reader
+	nb int64     // Number of remaining bytes to read
+}
+
+func (fr *regFileReader) Read(b []byte) (n int, err error) {
+	if int64(len(b)) > fr.nb {
+		b = b[:fr.nb]
+	}
+	if len(b) > 0 {
+		n, err = fr.r.Read(b)
+		fr.nb -= int64(n)
+	}
+	switch {
+	case err == io.EOF && fr.nb > 0:
+		return n, io.ErrUnexpectedEOF
+	case err == nil && fr.nb == 0:
+		return n, io.EOF
+	default:
+		return n, err
+	}
+}
+
+func (fr *regFileReader) WriteTo(w io.Writer) (int64, error) {
+	return io.Copy(w, struct{ io.Reader }{fr})
+}
+
+func (fr regFileReader) LogicalRemaining() int64 {
+	return fr.nb
+}
+
+func (fr regFileReader) PhysicalRemaining() int64 {
+	return fr.nb
+}
+
+// sparseFileReader is a fileReader for reading data from a sparse file entry.
+type sparseFileReader struct {
+	fr  fileReader  // Underlying fileReader
+	sp  sparseHoles // Normalized list of sparse holes
+	pos int64       // Current position in sparse file
+}
+
+func (sr *sparseFileReader) Read(b []byte) (n int, err error) {
+	finished := int64(len(b)) >= sr.LogicalRemaining()
+	if finished {
+		b = b[:sr.LogicalRemaining()]
+	}
+
+	b0 := b
+	endPos := sr.pos + int64(len(b))
+	for endPos > sr.pos && err == nil {
+		var nf int // Bytes read in fragment
+		holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
+		if sr.pos < holeStart { // In a data fragment
+			bf := b[:min(int64(len(b)), holeStart-sr.pos)]
+			nf, err = tryReadFull(sr.fr, bf)
+		} else { // In a hole fragment
+			bf := b[:min(int64(len(b)), holeEnd-sr.pos)]
+			nf, err = tryReadFull(zeroReader{}, bf)
+		}
+		b = b[nf:]
+		sr.pos += int64(nf)
+		if sr.pos >= holeEnd && len(sr.sp) > 1 {
+			sr.sp = sr.sp[1:] // Ensure last fragment always remains
+		}
+	}
+
+	n = len(b0) - len(b)
+	switch {
+	case err == io.EOF:
+		return n, errMissData // Less data in dense file than sparse file
+	case err != nil:
+		return n, err
+	case sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0:
+		return n, errUnrefData // More data in dense file than sparse file
+	case finished:
+		return n, io.EOF
+	default:
+		return n, nil
+	}
+}
+
+func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) {
+	ws, ok := w.(io.WriteSeeker)
+	if ok {
+		if _, err := ws.Seek(0, io.SeekCurrent); err != nil {
+			ok = false // Not all io.Seeker can really seek
+		}
+	}
+	if !ok {
+		return io.Copy(w, struct{ io.Reader }{sr})
+	}
+
+	var writeLastByte bool
+	pos0 := sr.pos
+	for sr.LogicalRemaining() > 0 && !writeLastByte && err == nil {
+		var nf int64 // Size of fragment
+		holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
+		if sr.pos < holeStart { // In a data fragment
+			nf = holeStart - sr.pos
+			nf, err = io.CopyN(ws, sr.fr, nf)
+		} else { // In a hole fragment
+			nf = holeEnd - sr.pos
+			if sr.PhysicalRemaining() == 0 {
+				writeLastByte = true
+				nf--
+			}
+			_, err = ws.Seek(nf, io.SeekCurrent)
+		}
+		sr.pos += nf
+		if sr.pos >= holeEnd && len(sr.sp) > 1 {
+			sr.sp = sr.sp[1:] // Ensure last fragment always remains
+		}
+	}
+
+	// If the last fragment is a hole, then seek to 1-byte before EOF, and
+	// write a single byte to ensure the file is the right size.
+	if writeLastByte && err == nil {
+		_, err = ws.Write([]byte{0})
+		sr.pos++
+	}
+
+	n = sr.pos - pos0
+	switch {
+	case err == io.EOF:
+		return n, errMissData // Less data in dense file than sparse file
+	case err != nil:
+		return n, err
+	case sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0:
+		return n, errUnrefData // More data in dense file than sparse file
+	default:
+		return n, nil
+	}
+}
+
+func (sr sparseFileReader) LogicalRemaining() int64 {
+	return sr.sp[len(sr.sp)-1].endOffset() - sr.pos
+}
+func (sr sparseFileReader) PhysicalRemaining() int64 {
+	return sr.fr.PhysicalRemaining()
+}
+
+type zeroReader struct{}
+
+func (zeroReader) Read(b []byte) (int, error) {
+	for i := range b {
+		b[i] = 0
+	}
+	return len(b), nil
+}
+
+// mustReadFull is like io.ReadFull except it returns
+// io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.
+func mustReadFull(r io.Reader, b []byte) (int, error) {
+	n, err := tryReadFull(r, b)
+	if err == io.EOF {
+		err = io.ErrUnexpectedEOF
+	}
+	return n, err
+}
+
+// tryReadFull is like io.ReadFull except it returns
+// io.EOF when it is hit before len(b) bytes are read.
+func tryReadFull(r io.Reader, b []byte) (n int, err error) {
+	for len(b) > n && err == nil {
+		var nn int
+		nn, err = r.Read(b[n:])
+		n += nn
+	}
+	if len(b) == n && err == io.EOF {
+		err = nil
+	}
+	return n, err
+}
+
+// discard skips n bytes in r, reporting an error if unable to do so.
+func discard(r io.Reader, n int64) error {
+	// If possible, Seek to the last byte before the end of the data section.
+	// Do this because Seek is often lazy about reporting errors; this will mask
+	// the fact that the stream may be truncated. We can rely on the
+	// io.CopyN done shortly afterwards to trigger any IO errors.
+	var seekSkipped int64 // Number of bytes skipped via Seek
+	if sr, ok := r.(io.Seeker); ok && n > 1 {
+		// Not all io.Seeker can actually Seek. For example, os.Stdin implements
+		// io.Seeker, but calling Seek always returns an error and performs
+		// no action. Thus, we try an innocent seek to the current position
+		// to see if Seek is really supported.
+		pos1, err := sr.Seek(0, io.SeekCurrent)
+		if pos1 >= 0 && err == nil {
+			// Seek seems supported, so perform the real Seek.
+			pos2, err := sr.Seek(n-1, io.SeekCurrent)
+			if pos2 < 0 || err != nil {
+				return err
+			}
+			seekSkipped = pos2 - pos1
+		}
+	}
+
+	copySkipped, err := io.CopyN(ioutil.Discard, r, n-seekSkipped)
+	if err == io.EOF && seekSkipped+copySkipped < n {
+		err = io.ErrUnexpectedEOF
+	}
+	return err
 }
diff --git a/src/archive/tar/reader_test.go b/src/archive/tar/reader_test.go
index 3386868..a6832d3 100644
--- a/src/archive/tar/reader_test.go
+++ b/src/archive/tar/reader_test.go
@@ -7,12 +7,15 @@
 import (
 	"bytes"
 	"crypto/md5"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"math"
 	"os"
+	"path"
 	"reflect"
+	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -36,6 +39,7 @@
 			Typeflag: '0',
 			Uname:    "dsymonds",
 			Gname:    "eng",
+			Format:   FormatGNU,
 		}, {
 			Name:     "small2.txt",
 			Mode:     0640,
@@ -46,6 +50,7 @@
 			Typeflag: '0',
 			Uname:    "dsymonds",
 			Gname:    "eng",
+			Format:   FormatGNU,
 		}},
 		chksums: []string{
 			"e38b27eaccb4391bdec553a7f3ae6b2f",
@@ -66,6 +71,7 @@
 			Gname:    "david",
 			Devmajor: 0,
 			Devminor: 0,
+			Format:   FormatGNU,
 		}, {
 			Name:     "sparse-posix-0.0",
 			Mode:     420,
@@ -79,6 +85,12 @@
 			Gname:    "david",
 			Devmajor: 0,
 			Devminor: 0,
+			PAXRecords: map[string]string{
+				"GNU.sparse.size":      "200",
+				"GNU.sparse.numblocks": "95",
+				"GNU.sparse.map":       "1,1,3,1,5,1,7,1,9,1,11,1,13,1,15,1,17,1,19,1,21,1,23,1,25,1,27,1,29,1,31,1,33,1,35,1,37,1,39,1,41,1,43,1,45,1,47,1,49,1,51,1,53,1,55,1,57,1,59,1,61,1,63,1,65,1,67,1,69,1,71,1,73,1,75,1,77,1,79,1,81,1,83,1,85,1,87,1,89,1,91,1,93,1,95,1,97,1,99,1,101,1,103,1,105,1,107,1,109,1,111,1,113,1,115,1,117,1,119,1,121,1,123,1,125,1,127,1,129,1,131,1,133,1,135,1,137,1,139,1,141,1,143,1,145,1,147,1,149,1,151,1,153,1,155,1,157,1,159,1,161,1,163,1,165,1,167,1,169,1,171,1,173,1,175,1,177,1,179,1,181,1,183,1,185,1,187,1,189,1",
+			},
+			Format: FormatPAX,
 		}, {
 			Name:     "sparse-posix-0.1",
 			Mode:     420,
@@ -92,6 +104,13 @@
 			Gname:    "david",
 			Devmajor: 0,
 			Devminor: 0,
+			PAXRecords: map[string]string{
+				"GNU.sparse.size":      "200",
+				"GNU.sparse.numblocks": "95",
+				"GNU.sparse.map":       "1,1,3,1,5,1,7,1,9,1,11,1,13,1,15,1,17,1,19,1,21,1,23,1,25,1,27,1,29,1,31,1,33,1,35,1,37,1,39,1,41,1,43,1,45,1,47,1,49,1,51,1,53,1,55,1,57,1,59,1,61,1,63,1,65,1,67,1,69,1,71,1,73,1,75,1,77,1,79,1,81,1,83,1,85,1,87,1,89,1,91,1,93,1,95,1,97,1,99,1,101,1,103,1,105,1,107,1,109,1,111,1,113,1,115,1,117,1,119,1,121,1,123,1,125,1,127,1,129,1,131,1,133,1,135,1,137,1,139,1,141,1,143,1,145,1,147,1,149,1,151,1,153,1,155,1,157,1,159,1,161,1,163,1,165,1,167,1,169,1,171,1,173,1,175,1,177,1,179,1,181,1,183,1,185,1,187,1,189,1",
+				"GNU.sparse.name":      "sparse-posix-0.1",
+			},
+			Format: FormatPAX,
 		}, {
 			Name:     "sparse-posix-1.0",
 			Mode:     420,
@@ -105,6 +124,13 @@
 			Gname:    "david",
 			Devmajor: 0,
 			Devminor: 0,
+			PAXRecords: map[string]string{
+				"GNU.sparse.major":    "1",
+				"GNU.sparse.minor":    "0",
+				"GNU.sparse.realsize": "200",
+				"GNU.sparse.name":     "sparse-posix-1.0",
+			},
+			Format: FormatPAX,
 		}, {
 			Name:     "end",
 			Mode:     420,
@@ -118,6 +144,7 @@
 			Gname:    "david",
 			Devmajor: 0,
 			Devminor: 0,
+			Format:   FormatGNU,
 		}},
 		chksums: []string{
 			"6f53234398c2449fe67c1812d993012f",
@@ -186,6 +213,13 @@
 			ChangeTime: time.Unix(1350244992, 23960108),
 			AccessTime: time.Unix(1350244992, 23960108),
 			Typeflag:   TypeReg,
+			PAXRecords: map[string]string{
+				"path":  "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100",
+				"mtime": "1350244992.023960108",
+				"atime": "1350244992.023960108",
+				"ctime": "1350244992.023960108",
+			},
+			Format: FormatPAX,
 		}, {
 			Name:       "a/b",
 			Mode:       0777,
@@ -199,6 +233,13 @@
 			AccessTime: time.Unix(1350266320, 910238425),
 			Typeflag:   TypeSymlink,
 			Linkname:   "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100",
+			PAXRecords: map[string]string{
+				"linkpath": "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100",
+				"mtime":    "1350266320.910238425",
+				"atime":    "1350266320.910238425",
+				"ctime":    "1350266320.910238425",
+			},
+			Format: FormatPAX,
 		}},
 	}, {
 		file: "testdata/pax-bad-hdr-file.tar",
@@ -218,11 +259,64 @@
 			Typeflag: '0',
 			Uname:    "joetsai",
 			Gname:    "eng",
+			PAXRecords: map[string]string{
+				"size": "000000000000000000000999",
+			},
+			Format: FormatPAX,
 		}},
 		chksums: []string{
 			"0afb597b283fe61b5d4879669a350556",
 		},
 	}, {
+		file: "testdata/pax-records.tar",
+		headers: []*Header{{
+			Typeflag: TypeReg,
+			Name:     "file",
+			Uname:    strings.Repeat("long", 10),
+			ModTime:  time.Unix(0, 0),
+			PAXRecords: map[string]string{
+				"GOLANG.pkg": "tar",
+				"comment":    "Hello, 世界",
+				"uname":      strings.Repeat("long", 10),
+			},
+			Format: FormatPAX,
+		}},
+	}, {
+		file: "testdata/pax-global-records.tar",
+		headers: []*Header{{
+			Typeflag:   TypeXGlobalHeader,
+			Name:       "global1",
+			PAXRecords: map[string]string{"path": "global1", "mtime": "1500000000.0"},
+			Format:     FormatPAX,
+		}, {
+			Typeflag: TypeReg,
+			Name:     "file1",
+			ModTime:  time.Unix(0, 0),
+			Format:   FormatUSTAR,
+		}, {
+			Typeflag:   TypeReg,
+			Name:       "file2",
+			PAXRecords: map[string]string{"path": "file2"},
+			ModTime:    time.Unix(0, 0),
+			Format:     FormatPAX,
+		}, {
+			Typeflag:   TypeXGlobalHeader,
+			Name:       "GlobalHead.0.0",
+			PAXRecords: map[string]string{"path": ""},
+			Format:     FormatPAX,
+		}, {
+			Typeflag: TypeReg,
+			Name:     "file3",
+			ModTime:  time.Unix(0, 0),
+			Format:   FormatUSTAR,
+		}, {
+			Typeflag:   TypeReg,
+			Name:       "file4",
+			ModTime:    time.Unix(1400000000, 0),
+			PAXRecords: map[string]string{"mtime": "1400000000"},
+			Format:     FormatPAX,
+		}},
+	}, {
 		file: "testdata/nil-uid.tar", // golang.org/issue/5290
 		headers: []*Header{{
 			Name:     "P1050238.JPG.log",
@@ -237,6 +331,7 @@
 			Gname:    "eyefi",
 			Devmajor: 0,
 			Devminor: 0,
+			Format:   FormatGNU,
 		}},
 	}, {
 		file: "testdata/xattrs.tar",
@@ -258,6 +353,15 @@
 				// Interestingly, selinux encodes the terminating null inside the xattr
 				"security.selinux": "unconfined_u:object_r:default_t:s0\x00",
 			},
+			PAXRecords: map[string]string{
+				"mtime":                         "1386065770.44825232",
+				"atime":                         "1389782991.41987522",
+				"ctime":                         "1389782956.794414986",
+				"SCHILY.xattr.user.key":         "value",
+				"SCHILY.xattr.user.key2":        "value2",
+				"SCHILY.xattr.security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+			},
+			Format: FormatPAX,
 		}, {
 			Name:       "small2.txt",
 			Mode:       0644,
@@ -273,6 +377,13 @@
 			Xattrs: map[string]string{
 				"security.selinux": "unconfined_u:object_r:default_t:s0\x00",
 			},
+			PAXRecords: map[string]string{
+				"mtime": "1386065770.449252304",
+				"atime": "1389782991.41987522",
+				"ctime": "1386065770.449252304",
+				"SCHILY.xattr.security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+			},
+			Format: FormatPAX,
 		}},
 	}, {
 		// Matches the behavior of GNU, BSD, and STAR tar utilities.
@@ -282,6 +393,7 @@
 			Linkname: "GNU4/GNU4/long-linkpath-name",
 			ModTime:  time.Unix(0, 0),
 			Typeflag: '2',
+			Format:   FormatGNU,
 		}},
 	}, {
 		// GNU tar file with atime and ctime fields set.
@@ -300,6 +412,7 @@
 			Gname:      "dsnet",
 			AccessTime: time.Unix(1441974501, 0),
 			ChangeTime: time.Unix(1441973436, 0),
+			Format:     FormatGNU,
 		}, {
 			Name:       "test2/foo",
 			Mode:       33188,
@@ -312,6 +425,7 @@
 			Gname:      "dsnet",
 			AccessTime: time.Unix(1441974501, 0),
 			ChangeTime: time.Unix(1441973436, 0),
+			Format:     FormatGNU,
 		}, {
 			Name:       "test2/sparse",
 			Mode:       33188,
@@ -324,6 +438,7 @@
 			Gname:      "dsnet",
 			AccessTime: time.Unix(1441991948, 0),
 			ChangeTime: time.Unix(1441973436, 0),
+			Format:     FormatGNU,
 		}},
 	}, {
 		// Matches the behavior of GNU and BSD tar utilities.
@@ -333,8 +448,76 @@
 			Linkname: "PAX4/PAX4/long-linkpath-name",
 			ModTime:  time.Unix(0, 0),
 			Typeflag: '2',
+			PAXRecords: map[string]string{
+				"linkpath": "PAX4/PAX4/long-linkpath-name",
+			},
+			Format: FormatPAX,
 		}},
 	}, {
+		// Both BSD and GNU tar truncate long names at first NUL even
+		// if there is data following that NUL character.
+		// This is reasonable as GNU long names are C-strings.
+		file: "testdata/gnu-long-nul.tar",
+		headers: []*Header{{
+			Name:     "0123456789",
+			Mode:     0644,
+			Uid:      1000,
+			Gid:      1000,
+			ModTime:  time.Unix(1486082191, 0),
+			Typeflag: '0',
+			Uname:    "rawr",
+			Gname:    "dsnet",
+			Format:   FormatGNU,
+		}},
+	}, {
+		// This archive was generated by Writer but is readable by both
+		// GNU and BSD tar utilities.
+		// The archive generated by GNU is nearly byte-for-byte identical
+		// to the Go version except the Go version sets a negative Devminor
+		// just to force the GNU format.
+		file: "testdata/gnu-utf8.tar",
+		headers: []*Header{{
+			Name: "☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹",
+			Mode: 0644,
+			Uid:  1000, Gid: 1000,
+			ModTime:  time.Unix(0, 0),
+			Typeflag: '0',
+			Uname:    "☺",
+			Gname:    "⚹",
+			Format:   FormatGNU,
+		}},
+	}, {
+		// This archive was generated by Writer but is readable by both
+		// GNU and BSD tar utilities.
+		// The archive generated by GNU is nearly byte-for-byte identical
+		// to the Go version except the Go version sets a negative Devminor
+		// just to force the GNU format.
+		file: "testdata/gnu-not-utf8.tar",
+		headers: []*Header{{
+			Name:     "hi\x80\x81\x82\x83bye",
+			Mode:     0644,
+			Uid:      1000,
+			Gid:      1000,
+			ModTime:  time.Unix(0, 0),
+			Typeflag: '0',
+			Uname:    "rawr",
+			Gname:    "dsnet",
+			Format:   FormatGNU,
+		}},
+	}, {
+		// BSD tar v3.1.2 and GNU tar v1.27.1 both rejects PAX records
+		// with NULs in the key.
+		file: "testdata/pax-nul-xattrs.tar",
+		err:  ErrHeader,
+	}, {
+		// BSD tar v3.1.2 rejects a PAX path with NUL in the value, while
+		// GNU tar v1.27.1 simply truncates at first NUL.
+		// We emulate the behavior of BSD since it is strange doing NUL
+		// truncations since PAX records are length-prefix strings instead
+		// of NUL-terminated C-strings.
+		file: "testdata/pax-nul-path.tar",
+		err:  ErrHeader,
+	}, {
 		file: "testdata/neg-size.tar",
 		err:  ErrHeader,
 	}, {
@@ -346,483 +529,214 @@
 	}, {
 		file: "testdata/issue12435.tar",
 		err:  ErrHeader,
+	}, {
+		// Ensure that we can read back the original Header as written with
+		// a buggy pre-Go1.8 tar.Writer.
+		file: "testdata/invalid-go17.tar",
+		headers: []*Header{{
+			Name:    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
+			Uid:     010000000,
+			ModTime: time.Unix(0, 0),
+		}},
+	}, {
+		// USTAR archive with a regular entry with non-zero device numbers.
+		file: "testdata/ustar-file-devs.tar",
+		headers: []*Header{{
+			Name:     "file",
+			Mode:     0644,
+			Typeflag: '0',
+			ModTime:  time.Unix(0, 0),
+			Devmajor: 1,
+			Devminor: 1,
+			Format:   FormatUSTAR,
+		}},
+	}, {
+		// Generated by Go, works on BSD tar v3.1.2 and GNU tar v.1.27.1.
+		file: "testdata/gnu-nil-sparse-data.tar",
+		headers: []*Header{{
+			Name:     "sparse.db",
+			Typeflag: TypeGNUSparse,
+			Size:     1000,
+			ModTime:  time.Unix(0, 0),
+			Format:   FormatGNU,
+		}},
+	}, {
+		// Generated by Go, works on BSD tar v3.1.2 and GNU tar v.1.27.1.
+		file: "testdata/gnu-nil-sparse-hole.tar",
+		headers: []*Header{{
+			Name:     "sparse.db",
+			Typeflag: TypeGNUSparse,
+			Size:     1000,
+			ModTime:  time.Unix(0, 0),
+			Format:   FormatGNU,
+		}},
+	}, {
+		// Generated by Go, works on BSD tar v3.1.2 and GNU tar v.1.27.1.
+		file: "testdata/pax-nil-sparse-data.tar",
+		headers: []*Header{{
+			Name:     "sparse.db",
+			Typeflag: TypeReg,
+			Size:     1000,
+			ModTime:  time.Unix(0, 0),
+			PAXRecords: map[string]string{
+				"size":                "1512",
+				"GNU.sparse.major":    "1",
+				"GNU.sparse.minor":    "0",
+				"GNU.sparse.realsize": "1000",
+				"GNU.sparse.name":     "sparse.db",
+			},
+			Format: FormatPAX,
+		}},
+	}, {
+		// Generated by Go, works on BSD tar v3.1.2 and GNU tar v.1.27.1.
+		file: "testdata/pax-nil-sparse-hole.tar",
+		headers: []*Header{{
+			Name:     "sparse.db",
+			Typeflag: TypeReg,
+			Size:     1000,
+			ModTime:  time.Unix(0, 0),
+			PAXRecords: map[string]string{
+				"size":                "512",
+				"GNU.sparse.major":    "1",
+				"GNU.sparse.minor":    "0",
+				"GNU.sparse.realsize": "1000",
+				"GNU.sparse.name":     "sparse.db",
+			},
+			Format: FormatPAX,
+		}},
+	}, {
+		file: "testdata/trailing-slash.tar",
+		headers: []*Header{{
+			Typeflag: TypeDir,
+			Name:     strings.Repeat("123456789/", 30),
+			ModTime:  time.Unix(0, 0),
+			PAXRecords: map[string]string{
+				"path": strings.Repeat("123456789/", 30),
+			},
+			Format: FormatPAX,
+		}},
 	}}
 
-	for i, v := range vectors {
-		f, err := os.Open(v.file)
-		if err != nil {
-			t.Errorf("file %s, test %d: unexpected error: %v", v.file, i, err)
-			continue
-		}
-		defer f.Close()
-
-		// Capture all headers and checksums.
-		var (
-			tr      = NewReader(f)
-			hdrs    []*Header
-			chksums []string
-			rdbuf   = make([]byte, 8)
-		)
-		for {
-			var hdr *Header
-			hdr, err = tr.Next()
+	for _, v := range vectors {
+		t.Run(path.Base(v.file), func(t *testing.T) {
+			f, err := os.Open(v.file)
 			if err != nil {
-				if err == io.EOF {
-					err = nil // Expected error
+				t.Fatalf("unexpected error: %v", err)
+			}
+			defer f.Close()
+
+			// Capture all headers and checksums.
+			var (
+				tr      = NewReader(f)
+				hdrs    []*Header
+				chksums []string
+				rdbuf   = make([]byte, 8)
+			)
+			for {
+				var hdr *Header
+				hdr, err = tr.Next()
+				if err != nil {
+					if err == io.EOF {
+						err = nil // Expected error
+					}
+					break
 				}
-				break
-			}
-			hdrs = append(hdrs, hdr)
+				hdrs = append(hdrs, hdr)
 
-			if v.chksums == nil {
-				continue
+				if v.chksums == nil {
+					continue
+				}
+				h := md5.New()
+				_, err = io.CopyBuffer(h, tr, rdbuf) // Effectively an incremental read
+				if err != nil {
+					break
+				}
+				chksums = append(chksums, fmt.Sprintf("%x", h.Sum(nil)))
 			}
-			h := md5.New()
-			_, err = io.CopyBuffer(h, tr, rdbuf) // Effectively an incremental read
-			if err != nil {
-				break
-			}
-			chksums = append(chksums, fmt.Sprintf("%x", h.Sum(nil)))
-		}
 
-		for j, hdr := range hdrs {
-			if j >= len(v.headers) {
-				t.Errorf("file %s, test %d, entry %d: unexpected header:\ngot %+v",
-					v.file, i, j, *hdr)
-				continue
+			for i, hdr := range hdrs {
+				if i >= len(v.headers) {
+					t.Fatalf("entry %d: unexpected header:\ngot %+v", i, *hdr)
+					continue
+				}
+				if !reflect.DeepEqual(*hdr, *v.headers[i]) {
+					t.Fatalf("entry %d: incorrect header:\ngot  %+v\nwant %+v", i, *hdr, *v.headers[i])
+				}
 			}
-			if !reflect.DeepEqual(*hdr, *v.headers[j]) {
-				t.Errorf("file %s, test %d, entry %d: incorrect header:\ngot  %+v\nwant %+v",
-					v.file, i, j, *hdr, *v.headers[j])
+			if len(hdrs) != len(v.headers) {
+				t.Fatalf("got %d headers, want %d headers", len(hdrs), len(v.headers))
 			}
-		}
-		if len(hdrs) != len(v.headers) {
-			t.Errorf("file %s, test %d: got %d headers, want %d headers",
-				v.file, i, len(hdrs), len(v.headers))
-		}
 
-		for j, sum := range chksums {
-			if j >= len(v.chksums) {
-				t.Errorf("file %s, test %d, entry %d: unexpected sum: got %s",
-					v.file, i, j, sum)
-				continue
+			for i, sum := range chksums {
+				if i >= len(v.chksums) {
+					t.Fatalf("entry %d: unexpected sum: got %s", i, sum)
+					continue
+				}
+				if sum != v.chksums[i] {
+					t.Fatalf("entry %d: incorrect checksum: got %s, want %s", i, sum, v.chksums[i])
+				}
 			}
-			if sum != v.chksums[j] {
-				t.Errorf("file %s, test %d, entry %d: incorrect checksum: got %s, want %s",
-					v.file, i, j, sum, v.chksums[j])
-			}
-		}
 
-		if err != v.err {
-			t.Errorf("file %s, test %d: unexpected error: got %v, want %v",
-				v.file, i, err, v.err)
-		}
-		f.Close()
+			if err != v.err {
+				t.Fatalf("unexpected error: got %v, want %v", err, v.err)
+			}
+			f.Close()
+		})
 	}
 }
 
 func TestPartialRead(t *testing.T) {
-	f, err := os.Open("testdata/gnu.tar")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
+	type testCase struct {
+		cnt    int    // Number of bytes to read
+		output string // Expected value of string read
 	}
-	defer f.Close()
-
-	tr := NewReader(f)
-
-	// Read the first four bytes; Next() should skip the last byte.
-	hdr, err := tr.Next()
-	if err != nil || hdr == nil {
-		t.Fatalf("Didn't get first file: %v", err)
-	}
-	buf := make([]byte, 4)
-	if _, err := io.ReadFull(tr, buf); err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
-	if expected := []byte("Kilt"); !bytes.Equal(buf, expected) {
-		t.Errorf("Contents = %v, want %v", buf, expected)
-	}
-
-	// Second file
-	hdr, err = tr.Next()
-	if err != nil || hdr == nil {
-		t.Fatalf("Didn't get second file: %v", err)
-	}
-	buf = make([]byte, 6)
-	if _, err := io.ReadFull(tr, buf); err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
-	if expected := []byte("Google"); !bytes.Equal(buf, expected) {
-		t.Errorf("Contents = %v, want %v", buf, expected)
-	}
-}
-
-func TestSparseFileReader(t *testing.T) {
 	vectors := []struct {
-		realSize   int64         // Real size of the output file
-		sparseMap  []sparseEntry // Input sparse map
-		sparseData string        // Input compact data
-		expected   string        // Expected output data
-		err        error         // Expected error outcome
+		file  string
+		cases []testCase
 	}{{
-		realSize: 8,
-		sparseMap: []sparseEntry{
-			{offset: 0, numBytes: 2},
-			{offset: 5, numBytes: 3},
+		file: "testdata/gnu.tar",
+		cases: []testCase{
+			{4, "Kilt"},
+			{6, "Google"},
 		},
-		sparseData: "abcde",
-		expected:   "ab\x00\x00\x00cde",
 	}, {
-		realSize: 10,
-		sparseMap: []sparseEntry{
-			{offset: 0, numBytes: 2},
-			{offset: 5, numBytes: 3},
+		file: "testdata/sparse-formats.tar",
+		cases: []testCase{
+			{2, "\x00G"},
+			{4, "\x00G\x00o"},
+			{6, "\x00G\x00o\x00G"},
+			{8, "\x00G\x00o\x00G\x00o"},
+			{4, "end\n"},
 		},
-		sparseData: "abcde",
-		expected:   "ab\x00\x00\x00cde\x00\x00",
-	}, {
-		realSize: 8,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 2},
-		},
-		sparseData: "abcde",
-		expected:   "\x00abc\x00\x00de",
-	}, {
-		realSize: 8,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 0},
-			{offset: 6, numBytes: 0},
-			{offset: 6, numBytes: 2},
-		},
-		sparseData: "abcde",
-		expected:   "\x00abc\x00\x00de",
-	}, {
-		realSize: 10,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 2},
-		},
-		sparseData: "abcde",
-		expected:   "\x00abc\x00\x00de\x00\x00",
-	}, {
-		realSize: 10,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 2},
-			{offset: 8, numBytes: 0},
-			{offset: 8, numBytes: 0},
-			{offset: 8, numBytes: 0},
-			{offset: 8, numBytes: 0},
-		},
-		sparseData: "abcde",
-		expected:   "\x00abc\x00\x00de\x00\x00",
-	}, {
-		realSize:   2,
-		sparseMap:  []sparseEntry{},
-		sparseData: "",
-		expected:   "\x00\x00",
-	}, {
-		realSize:  -2,
-		sparseMap: []sparseEntry{},
-		err:       ErrHeader,
-	}, {
-		realSize: -10,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 2},
-		},
-		sparseData: "abcde",
-		err:        ErrHeader,
-	}, {
-		realSize: 10,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 5},
-		},
-		sparseData: "abcde",
-		err:        ErrHeader,
-	}, {
-		realSize: 35,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: 5},
-		},
-		sparseData: "abcde",
-		err:        io.ErrUnexpectedEOF,
-	}, {
-		realSize: 35,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 6, numBytes: -5},
-		},
-		sparseData: "abcde",
-		err:        ErrHeader,
-	}, {
-		realSize: 35,
-		sparseMap: []sparseEntry{
-			{offset: math.MaxInt64, numBytes: 3},
-			{offset: 6, numBytes: -5},
-		},
-		sparseData: "abcde",
-		err:        ErrHeader,
-	}, {
-		realSize: 10,
-		sparseMap: []sparseEntry{
-			{offset: 1, numBytes: 3},
-			{offset: 2, numBytes: 2},
-		},
-		sparseData: "abcde",
-		err:        ErrHeader,
 	}}
 
-	for i, v := range vectors {
-		r := bytes.NewReader([]byte(v.sparseData))
-		rfr := &regFileReader{r: r, nb: int64(len(v.sparseData))}
+	for _, v := range vectors {
+		t.Run(path.Base(v.file), func(t *testing.T) {
+			f, err := os.Open(v.file)
+			if err != nil {
+				t.Fatalf("Open() error: %v", err)
+			}
+			defer f.Close()
 
-		var (
-			sfr *sparseFileReader
-			err error
-			buf []byte
-		)
+			tr := NewReader(f)
+			for i, tc := range v.cases {
+				hdr, err := tr.Next()
+				if err != nil || hdr == nil {
+					t.Fatalf("entry %d, Next(): got %v, want %v", i, err, nil)
+				}
+				buf := make([]byte, tc.cnt)
+				if _, err := io.ReadFull(tr, buf); err != nil {
+					t.Fatalf("entry %d, ReadFull(): got %v, want %v", i, err, nil)
+				}
+				if string(buf) != tc.output {
+					t.Fatalf("entry %d, ReadFull(): got %q, want %q", i, string(buf), tc.output)
+				}
+			}
 
-		sfr, err = newSparseFileReader(rfr, v.sparseMap, v.realSize)
-		if err != nil {
-			goto fail
-		}
-		if sfr.numBytes() != int64(len(v.sparseData)) {
-			t.Errorf("test %d, numBytes() before reading: got %d, want %d", i, sfr.numBytes(), len(v.sparseData))
-		}
-		buf, err = ioutil.ReadAll(sfr)
-		if err != nil {
-			goto fail
-		}
-		if string(buf) != v.expected {
-			t.Errorf("test %d, ReadAll(): got %q, want %q", i, string(buf), v.expected)
-		}
-		if sfr.numBytes() != 0 {
-			t.Errorf("test %d, numBytes() after reading: got %d, want %d", i, sfr.numBytes(), 0)
-		}
-
-	fail:
-		if err != v.err {
-			t.Errorf("test %d, unexpected error: got %v, want %v", i, err, v.err)
-		}
-	}
-}
-
-func TestReadOldGNUSparseMap(t *testing.T) {
-	const (
-		t00 = "00000000000\x0000000000000\x00"
-		t11 = "00000000001\x0000000000001\x00"
-		t12 = "00000000001\x0000000000002\x00"
-		t21 = "00000000002\x0000000000001\x00"
-	)
-
-	mkBlk := func(size, sp0, sp1, sp2, sp3, ext string, format int) *block {
-		var blk block
-		copy(blk.GNU().RealSize(), size)
-		copy(blk.GNU().Sparse().Entry(0), sp0)
-		copy(blk.GNU().Sparse().Entry(1), sp1)
-		copy(blk.GNU().Sparse().Entry(2), sp2)
-		copy(blk.GNU().Sparse().Entry(3), sp3)
-		copy(blk.GNU().Sparse().IsExtended(), ext)
-		if format != formatUnknown {
-			blk.SetFormat(format)
-		}
-		return &blk
-	}
-
-	vectors := []struct {
-		data   string        // Input data
-		rawHdr *block        // Input raw header
-		want   []sparseEntry // Expected sparse entries to be outputted
-		err    error         // Expected error to be returned
-	}{
-		{"", mkBlk("", "", "", "", "", "", formatUnknown), nil, ErrHeader},
-		{"", mkBlk("1234", "fewa", "", "", "", "", formatGNU), nil, ErrHeader},
-		{"", mkBlk("0031", "", "", "", "", "", formatGNU), nil, nil},
-		{"", mkBlk("1234", t00, t11, "", "", "", formatGNU),
-			[]sparseEntry{{0, 0}, {1, 1}}, nil},
-		{"", mkBlk("1234", t11, t12, t21, t11, "", formatGNU),
-			[]sparseEntry{{1, 1}, {1, 2}, {2, 1}, {1, 1}}, nil},
-		{"", mkBlk("1234", t11, t12, t21, t11, "\x80", formatGNU),
-			[]sparseEntry{}, io.ErrUnexpectedEOF},
-		{t11 + t11,
-			mkBlk("1234", t11, t12, t21, t11, "\x80", formatGNU),
-			[]sparseEntry{}, io.ErrUnexpectedEOF},
-		{t11 + t21 + strings.Repeat("\x00", 512),
-			mkBlk("1234", t11, t12, t21, t11, "\x80", formatGNU),
-			[]sparseEntry{{1, 1}, {1, 2}, {2, 1}, {1, 1}, {1, 1}, {2, 1}}, nil},
-	}
-
-	for i, v := range vectors {
-		tr := Reader{r: strings.NewReader(v.data)}
-		hdr := new(Header)
-		got, err := tr.readOldGNUSparseMap(hdr, v.rawHdr)
-		if !reflect.DeepEqual(got, v.want) && !(len(got) == 0 && len(v.want) == 0) {
-			t.Errorf("test %d, readOldGNUSparseMap(...): got %v, want %v", i, got, v.want)
-		}
-		if err != v.err {
-			t.Errorf("test %d, unexpected error: got %v, want %v", i, err, v.err)
-		}
-	}
-}
-
-func TestReadGNUSparseMap0x1(t *testing.T) {
-	const (
-		maxUint = ^uint(0)
-		maxInt  = int(maxUint >> 1)
-	)
-	var (
-		big1 = fmt.Sprintf("%d", int64(maxInt))
-		big2 = fmt.Sprintf("%d", (int64(maxInt)/2)+1)
-		big3 = fmt.Sprintf("%d", (int64(maxInt) / 3))
-	)
-
-	vectors := []struct {
-		extHdrs   map[string]string // Input data
-		sparseMap []sparseEntry     // Expected sparse entries to be outputted
-		err       error             // Expected errors that may be raised
-	}{{
-		extHdrs: map[string]string{paxGNUSparseNumBlocks: "-4"},
-		err:     ErrHeader,
-	}, {
-		extHdrs: map[string]string{paxGNUSparseNumBlocks: "fee "},
-		err:     ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: big1,
-			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: big2,
-			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: big3,
-			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: "4",
-			paxGNUSparseMap:       "0.5,5,10,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: "4",
-			paxGNUSparseMap:       "0,5.5,10,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: "4",
-			paxGNUSparseMap:       "0,fewafewa.5,fewafw,5,20,5,30,5",
-		},
-		err: ErrHeader,
-	}, {
-		extHdrs: map[string]string{
-			paxGNUSparseNumBlocks: "4",
-			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
-		},
-		sparseMap: []sparseEntry{{0, 5}, {10, 5}, {20, 5}, {30, 5}},
-	}}
-
-	for i, v := range vectors {
-		sp, err := readGNUSparseMap0x1(v.extHdrs)
-		if !reflect.DeepEqual(sp, v.sparseMap) && !(len(sp) == 0 && len(v.sparseMap) == 0) {
-			t.Errorf("test %d, readGNUSparseMap0x1(...): got %v, want %v", i, sp, v.sparseMap)
-		}
-		if err != v.err {
-			t.Errorf("test %d, unexpected error: got %v, want %v", i, err, v.err)
-		}
-	}
-}
-
-func TestReadGNUSparseMap1x0(t *testing.T) {
-	sp := []sparseEntry{{1, 2}, {3, 4}}
-	for i := 0; i < 98; i++ {
-		sp = append(sp, sparseEntry{54321, 12345})
-	}
-
-	vectors := []struct {
-		input     string        // Input data
-		sparseMap []sparseEntry // Expected sparse entries to be outputted
-		cnt       int           // Expected number of bytes read
-		err       error         // Expected errors that may be raised
-	}{{
-		input: "",
-		cnt:   0,
-		err:   io.ErrUnexpectedEOF,
-	}, {
-		input: "ab",
-		cnt:   2,
-		err:   io.ErrUnexpectedEOF,
-	}, {
-		input: strings.Repeat("\x00", 512),
-		cnt:   512,
-		err:   io.ErrUnexpectedEOF,
-	}, {
-		input: strings.Repeat("\x00", 511) + "\n",
-		cnt:   512,
-		err:   ErrHeader,
-	}, {
-		input: strings.Repeat("\n", 512),
-		cnt:   512,
-		err:   ErrHeader,
-	}, {
-		input:     "0\n" + strings.Repeat("\x00", 510) + strings.Repeat("a", 512),
-		sparseMap: []sparseEntry{},
-		cnt:       512,
-	}, {
-		input:     strings.Repeat("0", 512) + "0\n" + strings.Repeat("\x00", 510),
-		sparseMap: []sparseEntry{},
-		cnt:       1024,
-	}, {
-		input:     strings.Repeat("0", 1024) + "1\n2\n3\n" + strings.Repeat("\x00", 506),
-		sparseMap: []sparseEntry{{2, 3}},
-		cnt:       1536,
-	}, {
-		input: strings.Repeat("0", 1024) + "1\n2\n\n" + strings.Repeat("\x00", 509),
-		cnt:   1536,
-		err:   ErrHeader,
-	}, {
-		input: strings.Repeat("0", 1024) + "1\n2\n" + strings.Repeat("\x00", 508),
-		cnt:   1536,
-		err:   io.ErrUnexpectedEOF,
-	}, {
-		input: "-1\n2\n\n" + strings.Repeat("\x00", 506),
-		cnt:   512,
-		err:   ErrHeader,
-	}, {
-		input: "1\nk\n2\n" + strings.Repeat("\x00", 506),
-		cnt:   512,
-		err:   ErrHeader,
-	}, {
-		input:     "100\n1\n2\n3\n4\n" + strings.Repeat("54321\n0000000000000012345\n", 98) + strings.Repeat("\x00", 512),
-		cnt:       2560,
-		sparseMap: sp,
-	}}
-
-	for i, v := range vectors {
-		r := strings.NewReader(v.input)
-		sp, err := readGNUSparseMap1x0(r)
-		if !reflect.DeepEqual(sp, v.sparseMap) && !(len(sp) == 0 && len(v.sparseMap) == 0) {
-			t.Errorf("test %d, readGNUSparseMap1x0(...): got %v, want %v", i, sp, v.sparseMap)
-		}
-		if numBytes := len(v.input) - r.Len(); numBytes != v.cnt {
-			t.Errorf("test %d, bytes read: got %v, want %v", i, numBytes, v.cnt)
-		}
-		if err != v.err {
-			t.Errorf("test %d, unexpected error: got %v, want %v", i, err, v.err)
-		}
+			if _, err := tr.Next(); err != io.EOF {
+				t.Fatalf("Next(): got %v, want EOF", err)
+			}
+		})
 	}
 }
 
@@ -950,17 +864,17 @@
 				}
 				cnt++
 				if s2 == "manual" {
-					if _, err = io.Copy(ioutil.Discard, tr); err != nil {
+					if _, err = tr.writeTo(ioutil.Discard); err != nil {
 						break
 					}
 				}
 			}
 			if err != v.err {
-				t.Errorf("test %d, NewReader(%s(...)) with %s discard: got %v, want %v",
+				t.Errorf("test %d, NewReader(%s) with %s discard: got %v, want %v",
 					i, s1, s2, err, v.err)
 			}
 			if cnt != v.cnt {
-				t.Errorf("test %d, NewReader(%s(...)) with %s discard: got %d headers, want %d headers",
+				t.Errorf("test %d, NewReader(%s) with %s discard: got %d headers, want %d headers",
 					i, s1, s2, cnt, v.cnt)
 			}
 		}
@@ -1025,12 +939,18 @@
 			Name:    "a/b/c",
 			Uid:     1000,
 			ModTime: time.Unix(1350244992, 23960108),
+			PAXRecords: map[string]string{
+				"path":  "a/b/c",
+				"uid":   "1000",
+				"mtime": "1350244992.023960108",
+			},
 		},
 		ok: true,
 	}, {
 		in: map[string]string{
 			"gid": "gtgergergersagersgers",
 		},
+		ok: false,
 	}, {
 		in: map[string]string{
 			"missing":          "missing",
@@ -1038,6 +958,10 @@
 		},
 		want: &Header{
 			Xattrs: map[string]string{"key": "value"},
+			PAXRecords: map[string]string{
+				"missing":          "missing",
+				"SCHILY.xattr.key": "value",
+			},
 		},
 		ok: true,
 	}}
@@ -1070,7 +994,7 @@
 		{"13 key1=haha\n13 key2=nana\n13 key3=kaka\n",
 			map[string]string{"key1": "haha", "key2": "nana", "key3": "kaka"}, true},
 		{"13 key1=val1\n13 key2=val2\n8 key1=\n",
-			map[string]string{"key2": "val2"}, true},
+			map[string]string{"key1": "", "key2": "val2"}, true},
 		{"22 GNU.sparse.size=10\n26 GNU.sparse.numblocks=2\n" +
 			"23 GNU.sparse.offset=1\n25 GNU.sparse.numbytes=2\n" +
 			"23 GNU.sparse.offset=3\n25 GNU.sparse.numbytes=4\n",
@@ -1087,10 +1011,600 @@
 		r := strings.NewReader(v.in)
 		got, err := parsePAX(r)
 		if !reflect.DeepEqual(got, v.want) && !(len(got) == 0 && len(v.want) == 0) {
-			t.Errorf("test %d, parsePAX(...):\ngot  %v\nwant %v", i, got, v.want)
+			t.Errorf("test %d, parsePAX():\ngot  %v\nwant %v", i, got, v.want)
 		}
 		if ok := err == nil; ok != v.ok {
-			t.Errorf("test %d, parsePAX(...): got %v, want %v", i, ok, v.ok)
+			t.Errorf("test %d, parsePAX(): got %v, want %v", i, ok, v.ok)
+		}
+	}
+}
+
+func TestReadOldGNUSparseMap(t *testing.T) {
+	populateSparseMap := func(sa sparseArray, sps []string) []string {
+		for i := 0; len(sps) > 0 && i < sa.MaxEntries(); i++ {
+			copy(sa.Entry(i), sps[0])
+			sps = sps[1:]
+		}
+		if len(sps) > 0 {
+			copy(sa.IsExtended(), "\x80")
+		}
+		return sps
+	}
+
+	makeInput := func(format Format, size string, sps ...string) (out []byte) {
+		// Write the initial GNU header.
+		var blk block
+		gnu := blk.GNU()
+		sparse := gnu.Sparse()
+		copy(gnu.RealSize(), size)
+		sps = populateSparseMap(sparse, sps)
+		if format != FormatUnknown {
+			blk.SetFormat(format)
+		}
+		out = append(out, blk[:]...)
+
+		// Write extended sparse blocks.
+		for len(sps) > 0 {
+			var blk block
+			sps = populateSparseMap(blk.Sparse(), sps)
+			out = append(out, blk[:]...)
+		}
+		return out
+	}
+
+	makeSparseStrings := func(sp []sparseEntry) (out []string) {
+		var f formatter
+		for _, s := range sp {
+			var b [24]byte
+			f.formatNumeric(b[:12], s.Offset)
+			f.formatNumeric(b[12:], s.Length)
+			out = append(out, string(b[:]))
+		}
+		return out
+	}
+
+	vectors := []struct {
+		input    []byte
+		wantMap  sparseDatas
+		wantSize int64
+		wantErr  error
+	}{{
+		input:   makeInput(FormatUnknown, ""),
+		wantErr: ErrHeader,
+	}, {
+		input:    makeInput(FormatGNU, "1234", "fewa"),
+		wantSize: 01234,
+		wantErr:  ErrHeader,
+	}, {
+		input:    makeInput(FormatGNU, "0031"),
+		wantSize: 031,
+	}, {
+		input:   makeInput(FormatGNU, "80"),
+		wantErr: ErrHeader,
+	}, {
+		input: makeInput(FormatGNU, "1234",
+			makeSparseStrings(sparseDatas{{0, 0}, {1, 1}})...),
+		wantMap:  sparseDatas{{0, 0}, {1, 1}},
+		wantSize: 01234,
+	}, {
+		input: makeInput(FormatGNU, "1234",
+			append(makeSparseStrings(sparseDatas{{0, 0}, {1, 1}}), []string{"", "blah"}...)...),
+		wantMap:  sparseDatas{{0, 0}, {1, 1}},
+		wantSize: 01234,
+	}, {
+		input: makeInput(FormatGNU, "3333",
+			makeSparseStrings(sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}})...),
+		wantMap:  sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}},
+		wantSize: 03333,
+	}, {
+		input: makeInput(FormatGNU, "",
+			append(append(
+				makeSparseStrings(sparseDatas{{0, 1}, {2, 1}}),
+				[]string{"", ""}...),
+				makeSparseStrings(sparseDatas{{4, 1}, {6, 1}})...)...),
+		wantMap: sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}},
+	}, {
+		input: makeInput(FormatGNU, "",
+			makeSparseStrings(sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}, {8, 1}, {10, 1}})...)[:blockSize],
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		input: makeInput(FormatGNU, "",
+			makeSparseStrings(sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}, {8, 1}, {10, 1}})...)[:3*blockSize/2],
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		input: makeInput(FormatGNU, "",
+			makeSparseStrings(sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}, {8, 1}, {10, 1}})...),
+		wantMap: sparseDatas{{0, 1}, {2, 1}, {4, 1}, {6, 1}, {8, 1}, {10, 1}},
+	}, {
+		input: makeInput(FormatGNU, "",
+			makeSparseStrings(sparseDatas{{10 << 30, 512}, {20 << 30, 512}})...),
+		wantMap: sparseDatas{{10 << 30, 512}, {20 << 30, 512}},
+	}}
+
+	for i, v := range vectors {
+		var blk block
+		var hdr Header
+		v.input = v.input[copy(blk[:], v.input):]
+		tr := Reader{r: bytes.NewReader(v.input)}
+		got, err := tr.readOldGNUSparseMap(&hdr, &blk)
+		if !equalSparseEntries(got, v.wantMap) {
+			t.Errorf("test %d, readOldGNUSparseMap(): got %v, want %v", i, got, v.wantMap)
+		}
+		if err != v.wantErr {
+			t.Errorf("test %d, readOldGNUSparseMap() = %v, want %v", i, err, v.wantErr)
+		}
+		if hdr.Size != v.wantSize {
+			t.Errorf("test %d, Header.Size = %d, want %d", i, hdr.Size, v.wantSize)
+		}
+	}
+}
+
+func TestReadGNUSparsePAXHeaders(t *testing.T) {
+	padInput := func(s string) string {
+		return s + string(zeroBlock[:blockPadding(int64(len(s)))])
+	}
+
+	vectors := []struct {
+		inputData string
+		inputHdrs map[string]string
+		wantMap   sparseDatas
+		wantSize  int64
+		wantName  string
+		wantErr   error
+	}{{
+		inputHdrs: nil,
+		wantErr:   nil,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: strconv.FormatInt(math.MaxInt64, 10),
+			paxGNUSparseMap:       "0,1,2,3",
+		},
+		wantErr: ErrHeader,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "4\x00",
+			paxGNUSparseMap:       "0,1,2,3",
+		},
+		wantErr: ErrHeader,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "4",
+			paxGNUSparseMap:       "0,1,2,3",
+		},
+		wantErr: ErrHeader,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "2",
+			paxGNUSparseMap:       "0,1,2,3",
+		},
+		wantMap: sparseDatas{{0, 1}, {2, 3}},
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "2",
+			paxGNUSparseMap:       "0, 1,2,3",
+		},
+		wantErr: ErrHeader,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "2",
+			paxGNUSparseMap:       "0,1,02,3",
+			paxGNUSparseRealSize:  "4321",
+		},
+		wantMap:  sparseDatas{{0, 1}, {2, 3}},
+		wantSize: 4321,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseNumBlocks: "2",
+			paxGNUSparseMap:       "0,one1,2,3",
+		},
+		wantErr: ErrHeader,
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseMajor:     "0",
+			paxGNUSparseMinor:     "0",
+			paxGNUSparseNumBlocks: "2",
+			paxGNUSparseMap:       "0,1,2,3",
+			paxGNUSparseSize:      "1234",
+			paxGNUSparseRealSize:  "4321",
+			paxGNUSparseName:      "realname",
+		},
+		wantMap:  sparseDatas{{0, 1}, {2, 3}},
+		wantSize: 1234,
+		wantName: "realname",
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseMajor:     "0",
+			paxGNUSparseMinor:     "0",
+			paxGNUSparseNumBlocks: "1",
+			paxGNUSparseMap:       "10737418240,512",
+			paxGNUSparseSize:      "10737418240",
+			paxGNUSparseName:      "realname",
+		},
+		wantMap:  sparseDatas{{10737418240, 512}},
+		wantSize: 10737418240,
+		wantName: "realname",
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseMajor:     "0",
+			paxGNUSparseMinor:     "0",
+			paxGNUSparseNumBlocks: "0",
+			paxGNUSparseMap:       "",
+		},
+		wantMap: sparseDatas{},
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseMajor:     "0",
+			paxGNUSparseMinor:     "1",
+			paxGNUSparseNumBlocks: "4",
+			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
+		},
+		wantMap: sparseDatas{{0, 5}, {10, 5}, {20, 5}, {30, 5}},
+	}, {
+		inputHdrs: map[string]string{
+			paxGNUSparseMajor:     "1",
+			paxGNUSparseMinor:     "0",
+			paxGNUSparseNumBlocks: "4",
+			paxGNUSparseMap:       "0,5,10,5,20,5,30,5",
+		},
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		inputData: padInput("0\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{},
+	}, {
+		inputData: padInput("0\n")[:blockSize-1] + "#",
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{},
+	}, {
+		inputData: padInput("0"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   io.ErrUnexpectedEOF,
+	}, {
+		inputData: padInput("ab\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   ErrHeader,
+	}, {
+		inputData: padInput("1\n2\n3\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{{2, 3}},
+	}, {
+		inputData: padInput("1\n2\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   io.ErrUnexpectedEOF,
+	}, {
+		inputData: padInput("1\n2\n\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   ErrHeader,
+	}, {
+		inputData: string(zeroBlock[:]) + padInput("0\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   ErrHeader,
+	}, {
+		inputData: strings.Repeat("0", blockSize) + padInput("1\n5\n1\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{{5, 1}},
+	}, {
+		inputData: padInput(fmt.Sprintf("%d\n", int64(math.MaxInt64))),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantErr:   ErrHeader,
+	}, {
+		inputData: padInput(strings.Repeat("0", 300) + "1\n" + strings.Repeat("0", 1000) + "5\n" + strings.Repeat("0", 800) + "2\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{{5, 2}},
+	}, {
+		inputData: padInput("2\n10737418240\n512\n21474836480\n512\n"),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap:   sparseDatas{{10737418240, 512}, {21474836480, 512}},
+	}, {
+		inputData: padInput("100\n" + func() string {
+			var ss []string
+			for i := 0; i < 100; i++ {
+				ss = append(ss, fmt.Sprintf("%d\n%d\n", int64(i)<<30, 512))
+			}
+			return strings.Join(ss, "")
+		}()),
+		inputHdrs: map[string]string{paxGNUSparseMajor: "1", paxGNUSparseMinor: "0"},
+		wantMap: func() (spd sparseDatas) {
+			for i := 0; i < 100; i++ {
+				spd = append(spd, sparseEntry{int64(i) << 30, 512})
+			}
+			return spd
+		}(),
+	}}
+
+	for i, v := range vectors {
+		var hdr Header
+		hdr.PAXRecords = v.inputHdrs
+		r := strings.NewReader(v.inputData + "#") // Add canary byte
+		tr := Reader{curr: &regFileReader{r, int64(r.Len())}}
+		got, err := tr.readGNUSparsePAXHeaders(&hdr)
+		if !equalSparseEntries(got, v.wantMap) {
+			t.Errorf("test %d, readGNUSparsePAXHeaders(): got %v, want %v", i, got, v.wantMap)
+		}
+		if err != v.wantErr {
+			t.Errorf("test %d, readGNUSparsePAXHeaders() = %v, want %v", i, err, v.wantErr)
+		}
+		if hdr.Size != v.wantSize {
+			t.Errorf("test %d, Header.Size = %d, want %d", i, hdr.Size, v.wantSize)
+		}
+		if hdr.Name != v.wantName {
+			t.Errorf("test %d, Header.Name = %s, want %s", i, hdr.Name, v.wantName)
+		}
+		if v.wantErr == nil && r.Len() == 0 {
+			t.Errorf("test %d, canary byte unexpectedly consumed", i)
+		}
+	}
+}
+
+// testNonEmptyReader wraps an io.Reader and ensures that
+// Read is never called with an empty buffer.
+type testNonEmptyReader struct{ io.Reader }
+
+func (r testNonEmptyReader) Read(b []byte) (int, error) {
+	if len(b) == 0 {
+		return 0, errors.New("unexpected empty Read call")
+	}
+	return r.Reader.Read(b)
+}
+
+func TestFileReader(t *testing.T) {
+	type (
+		testRead struct { // Read(cnt) == (wantStr, wantErr)
+			cnt     int
+			wantStr string
+			wantErr error
+		}
+		testWriteTo struct { // WriteTo(testFile{ops}) == (wantCnt, wantErr)
+			ops     fileOps
+			wantCnt int64
+			wantErr error
+		}
+		testRemaining struct { // LogicalRemaining() == wantLCnt, PhysicalRemaining() == wantPCnt
+			wantLCnt int64
+			wantPCnt int64
+		}
+		testFnc interface{} // testRead | testWriteTo | testRemaining
+	)
+
+	type (
+		makeReg struct {
+			str  string
+			size int64
+		}
+		makeSparse struct {
+			makeReg makeReg
+			spd     sparseDatas
+			size    int64
+		}
+		fileMaker interface{} // makeReg | makeSparse
+	)
+
+	vectors := []struct {
+		maker fileMaker
+		tests []testFnc
+	}{{
+		maker: makeReg{"", 0},
+		tests: []testFnc{
+			testRemaining{0, 0},
+			testRead{0, "", io.EOF},
+			testRead{1, "", io.EOF},
+			testWriteTo{nil, 0, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{"", 1},
+		tests: []testFnc{
+			testRemaining{1, 1},
+			testRead{5, "", io.ErrUnexpectedEOF},
+			testWriteTo{nil, 0, io.ErrUnexpectedEOF},
+			testRemaining{1, 1},
+		},
+	}, {
+		maker: makeReg{"hello", 5},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testRead{5, "hello", io.EOF},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{"hello, world", 50},
+		tests: []testFnc{
+			testRemaining{50, 50},
+			testRead{7, "hello, ", nil},
+			testRemaining{43, 43},
+			testRead{5, "world", nil},
+			testRemaining{38, 38},
+			testWriteTo{nil, 0, io.ErrUnexpectedEOF},
+			testRead{1, "", io.ErrUnexpectedEOF},
+			testRemaining{38, 38},
+		},
+	}, {
+		maker: makeReg{"hello, world", 5},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testRead{0, "", nil},
+			testRead{4, "hell", nil},
+			testRemaining{1, 1},
+			testWriteTo{fileOps{"o"}, 1, nil},
+			testRemaining{0, 0},
+			testWriteTo{nil, 0, nil},
+			testRead{0, "", io.EOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{0, 2}, {5, 3}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testRead{3, "ab\x00", nil},
+			testRead{10, "\x00\x00cde", io.EOF},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{0, 2}, {5, 3}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testWriteTo{fileOps{"ab", int64(3), "cde"}, 8, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{0, 2}, {5, 3}}, 10},
+		tests: []testFnc{
+			testRemaining{10, 5},
+			testRead{100, "ab\x00\x00\x00cde\x00\x00", io.EOF},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abc", 5}, sparseDatas{{0, 2}, {5, 3}}, 10},
+		tests: []testFnc{
+			testRemaining{10, 5},
+			testRead{100, "ab\x00\x00\x00c", io.ErrUnexpectedEOF},
+			testRemaining{4, 2},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 2}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testRead{8, "\x00abc\x00\x00de", io.EOF},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 0}, {6, 0}, {6, 2}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testRead{8, "\x00abc\x00\x00de", io.EOF},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 0}, {6, 0}, {6, 2}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testWriteTo{fileOps{int64(1), "abc", int64(2), "de"}, 8, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 2}}, 10},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00de\x00\x00", io.EOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 2}}, 10},
+		tests: []testFnc{
+			testWriteTo{fileOps{int64(1), "abc", int64(2), "de", int64(1), "\x00"}, 10, nil},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 2}, {8, 0}, {8, 0}, {8, 0}, {8, 0}}, 10},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00de\x00\x00", io.EOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"", 0}, sparseDatas{}, 2},
+		tests: []testFnc{
+			testRead{100, "\x00\x00", io.EOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"", 8}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00", io.ErrUnexpectedEOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"ab", 2}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00ab", errMissData},
+		},
+	}, {
+		maker: makeSparse{makeReg{"ab", 8}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00ab", io.ErrUnexpectedEOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abc", 3}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00", errMissData},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abc", 8}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00", io.ErrUnexpectedEOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00de", errMissData},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 5}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testWriteTo{fileOps{int64(1), "abc", int64(2), "de"}, 8, errMissData},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcde", 8}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRead{100, "\x00abc\x00\x00de", io.ErrUnexpectedEOF},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcdefghEXTRA", 13}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRemaining{15, 13},
+			testRead{100, "\x00abc\x00\x00defgh\x00\x00\x00\x00", errUnrefData},
+			testWriteTo{nil, 0, errUnrefData},
+			testRemaining{0, 5},
+		},
+	}, {
+		maker: makeSparse{makeReg{"abcdefghEXTRA", 13}, sparseDatas{{1, 3}, {6, 5}}, 15},
+		tests: []testFnc{
+			testRemaining{15, 13},
+			testWriteTo{fileOps{int64(1), "abc", int64(2), "defgh", int64(4)}, 15, errUnrefData},
+			testRead{100, "", errUnrefData},
+			testRemaining{0, 5},
+		},
+	}}
+
+	for i, v := range vectors {
+		var fr fileReader
+		switch maker := v.maker.(type) {
+		case makeReg:
+			r := testNonEmptyReader{strings.NewReader(maker.str)}
+			fr = &regFileReader{r, maker.size}
+		case makeSparse:
+			if !validateSparseEntries(maker.spd, maker.size) {
+				t.Fatalf("invalid sparse map: %v", maker.spd)
+			}
+			sph := invertSparseEntries(maker.spd, maker.size)
+			r := testNonEmptyReader{strings.NewReader(maker.makeReg.str)}
+			fr = &regFileReader{r, maker.makeReg.size}
+			fr = &sparseFileReader{fr, sph, 0}
+		default:
+			t.Fatalf("test %d, unknown make operation: %T", i, maker)
+		}
+
+		for j, tf := range v.tests {
+			switch tf := tf.(type) {
+			case testRead:
+				b := make([]byte, tf.cnt)
+				n, err := fr.Read(b)
+				if got := string(b[:n]); got != tf.wantStr || err != tf.wantErr {
+					t.Errorf("test %d.%d, Read(%d):\ngot  (%q, %v)\nwant (%q, %v)", i, j, tf.cnt, got, err, tf.wantStr, tf.wantErr)
+				}
+			case testWriteTo:
+				f := &testFile{ops: tf.ops}
+				got, err := fr.WriteTo(f)
+				if _, ok := err.(testError); ok {
+					t.Errorf("test %d.%d, WriteTo(): %v", i, j, err)
+				} else if got != tf.wantCnt || err != tf.wantErr {
+					t.Errorf("test %d.%d, WriteTo() = (%d, %v), want (%d, %v)", i, j, got, err, tf.wantCnt, tf.wantErr)
+				}
+				if len(f.ops) > 0 {
+					t.Errorf("test %d.%d, expected %d more operations", i, j, len(f.ops))
+				}
+			case testRemaining:
+				if got := fr.LogicalRemaining(); got != tf.wantLCnt {
+					t.Errorf("test %d.%d, LogicalRemaining() = %d, want %d", i, j, got, tf.wantLCnt)
+				}
+				if got := fr.PhysicalRemaining(); got != tf.wantPCnt {
+					t.Errorf("test %d.%d, PhysicalRemaining() = %d, want %d", i, j, got, tf.wantPCnt)
+				}
+			default:
+				t.Fatalf("test %d.%d, unknown test operation: %T", i, j, tf)
+			}
 		}
 	}
 }
diff --git a/src/archive/tar/stat_atim.go b/src/archive/tar/stat_actime1.go
similarity index 100%
rename from src/archive/tar/stat_atim.go
rename to src/archive/tar/stat_actime1.go
diff --git a/src/archive/tar/stat_atimespec.go b/src/archive/tar/stat_actime2.go
similarity index 100%
rename from src/archive/tar/stat_atimespec.go
rename to src/archive/tar/stat_actime2.go
diff --git a/src/archive/tar/stat_unix.go b/src/archive/tar/stat_unix.go
index cb843db..868105f 100644
--- a/src/archive/tar/stat_unix.go
+++ b/src/archive/tar/stat_unix.go
@@ -8,6 +8,10 @@
 
 import (
 	"os"
+	"os/user"
+	"runtime"
+	"strconv"
+	"sync"
 	"syscall"
 )
 
@@ -15,6 +19,10 @@
 	sysStat = statUnix
 }
 
+// userMap and groupMap caches UID and GID lookups for performance reasons.
+// The downside is that renaming uname or gname by the OS never takes effect.
+var userMap, groupMap sync.Map // map[int]string
+
 func statUnix(fi os.FileInfo, h *Header) error {
 	sys, ok := fi.Sys().(*syscall.Stat_t)
 	if !ok {
@@ -22,11 +30,67 @@
 	}
 	h.Uid = int(sys.Uid)
 	h.Gid = int(sys.Gid)
-	// TODO(bradfitz): populate username & group.  os/user
-	// doesn't cache LookupId lookups, and lacks group
-	// lookup functions.
+
+	// Best effort at populating Uname and Gname.
+	// The os/user functions may fail for any number of reasons
+	// (not implemented on that platform, cgo not enabled, etc).
+	if u, ok := userMap.Load(h.Uid); ok {
+		h.Uname = u.(string)
+	} else if u, err := user.LookupId(strconv.Itoa(h.Uid)); err == nil {
+		h.Uname = u.Username
+		userMap.Store(h.Uid, h.Uname)
+	}
+	if g, ok := groupMap.Load(h.Gid); ok {
+		h.Gname = g.(string)
+	} else if g, err := user.LookupGroupId(strconv.Itoa(h.Gid)); err == nil {
+		h.Gname = g.Name
+		groupMap.Store(h.Gid, h.Gname)
+	}
+
 	h.AccessTime = statAtime(sys)
 	h.ChangeTime = statCtime(sys)
-	// TODO(bradfitz): major/minor device numbers?
+
+	// Best effort at populating Devmajor and Devminor.
+	if h.Typeflag == TypeChar || h.Typeflag == TypeBlock {
+		dev := uint64(sys.Rdev) // May be int32 or uint32
+		switch runtime.GOOS {
+		case "linux":
+			// Copied from golang.org/x/sys/unix/dev_linux.go.
+			major := uint32((dev & 0x00000000000fff00) >> 8)
+			major |= uint32((dev & 0xfffff00000000000) >> 32)
+			minor := uint32((dev & 0x00000000000000ff) >> 0)
+			minor |= uint32((dev & 0x00000ffffff00000) >> 12)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		case "darwin":
+			// Copied from golang.org/x/sys/unix/dev_darwin.go.
+			major := uint32((dev >> 24) & 0xff)
+			minor := uint32(dev & 0xffffff)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		case "dragonfly":
+			// Copied from golang.org/x/sys/unix/dev_dragonfly.go.
+			major := uint32((dev >> 8) & 0xff)
+			minor := uint32(dev & 0xffff00ff)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		case "freebsd":
+			// Copied from golang.org/x/sys/unix/dev_freebsd.go.
+			major := uint32((dev >> 8) & 0xff)
+			minor := uint32(dev & 0xffff00ff)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		case "netbsd":
+			// Copied from golang.org/x/sys/unix/dev_netbsd.go.
+			major := uint32((dev & 0x000fff00) >> 8)
+			minor := uint32((dev & 0x000000ff) >> 0)
+			minor |= uint32((dev & 0xfff00000) >> 12)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		case "openbsd":
+			// Copied from golang.org/x/sys/unix/dev_openbsd.go.
+			major := uint32((dev & 0x0000ff00) >> 8)
+			minor := uint32((dev & 0x000000ff) >> 0)
+			minor |= uint32((dev & 0xffff0000) >> 8)
+			h.Devmajor, h.Devminor = int64(major), int64(minor)
+		default:
+			// TODO: Implement solaris (see https://golang.org/issue/8106)
+		}
+	}
 	return nil
 }
diff --git a/src/archive/tar/strconv.go b/src/archive/tar/strconv.go
index bb5b51c..d144485 100644
--- a/src/archive/tar/strconv.go
+++ b/src/archive/tar/strconv.go
@@ -12,26 +12,34 @@
 	"time"
 )
 
+// hasNUL reports whether the NUL character exists within s.
+func hasNUL(s string) bool {
+	return strings.IndexByte(s, 0) >= 0
+}
+
+// isASCII reports whether the input is an ASCII C-style string.
 func isASCII(s string) bool {
 	for _, c := range s {
-		if c >= 0x80 {
+		if c >= 0x80 || c == 0x00 {
 			return false
 		}
 	}
 	return true
 }
 
+// toASCII converts the input to an ASCII C-style string.
+// This a best effort conversion, so invalid characters are dropped.
 func toASCII(s string) string {
 	if isASCII(s) {
 		return s
 	}
-	var buf bytes.Buffer
+	b := make([]byte, 0, len(s))
 	for _, c := range s {
-		if c < 0x80 {
-			buf.WriteByte(byte(c))
+		if c < 0x80 && c != 0x00 {
+			b = append(b, byte(c))
 		}
 	}
-	return buf.String()
+	return string(b)
 }
 
 type parser struct {
@@ -45,23 +53,28 @@
 // parseString 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 (*parser) parseString(b []byte) string {
-	n := 0
-	for n < len(b) && b[n] != 0 {
-		n++
+	if i := bytes.IndexByte(b, 0); i >= 0 {
+		return string(b[:i])
 	}
-	return string(b[0:n])
+	return string(b)
 }
 
-// Write s into b, terminating it with a NUL if there is room.
+// formatString copies s into b, NUL-terminating if possible.
 func (f *formatter) formatString(b []byte, s string) {
 	if len(s) > len(b) {
 		f.err = ErrFieldTooLong
-		return
 	}
-	ascii := toASCII(s)
-	copy(b, ascii)
-	if len(ascii) < len(b) {
-		b[len(ascii)] = 0
+	copy(b, s)
+	if len(s) < len(b) {
+		b[len(s)] = 0
+	}
+
+	// Some buggy readers treat regular files with a trailing slash
+	// in the V7 path field as a directory even though the full path
+	// recorded elsewhere (e.g., via PAX record) contains no trailing slash.
+	if len(s) > len(b) && b[len(b)-1] == '/' {
+		n := len(strings.TrimRight(s[:len(b)], "/"))
+		b[n] = 0 // Replace trailing slash with NUL terminator
 	}
 }
 
@@ -73,7 +86,7 @@
 // that the first byte can only be either 0x80 or 0xff. Thus, the first byte is
 // equivalent to the sign bit in two's complement form.
 func fitsInBase256(n int, x int64) bool {
-	var binBits = uint(n-1) * 8
+	binBits := uint(n-1) * 8
 	return n >= 9 || (x >= -1<<binBits && x < 1<<binBits)
 }
 
@@ -121,8 +134,14 @@
 	return p.parseOctal(b)
 }
 
-// Write x into b, as binary (GNUtar/star extension).
+// formatNumeric encodes x into b using base-8 (octal) encoding if possible.
+// Otherwise it will attempt to use base-256 (binary) encoding.
 func (f *formatter) formatNumeric(b []byte, x int64) {
+	if fitsInOctal(len(b), x) {
+		f.formatOctal(b, x)
+		return
+	}
+
 	if fitsInBase256(len(b), x) {
 		for i := len(b) - 1; i >= 0; i-- {
 			b[i] = byte(x)
@@ -155,6 +174,11 @@
 }
 
 func (f *formatter) formatOctal(b []byte, x int64) {
+	if !fitsInOctal(len(b), x) {
+		x = 0 // Last resort, just write zero
+		f.err = ErrFieldTooLong
+	}
+
 	s := strconv.FormatInt(x, 8)
 	// Add leading zeros, but leave room for a NUL.
 	if n := len(b) - len(s) - 1; n > 0 {
@@ -163,6 +187,13 @@
 	f.formatString(b, s)
 }
 
+// fitsInOctal reports whether the integer x fits in a field n-bytes long
+// using octal encoding with the appropriate NUL terminator.
+func fitsInOctal(n int, x int64) bool {
+	octBits := uint(n-1) * 3
+	return x >= 0 && (n >= 22 || x < 1<<octBits)
+}
+
 // parsePAXTime takes a string of the form %d.%d as described in the PAX
 // specification. Note that this implementation allows for negative timestamps,
 // which is allowed for by the PAX specification, but not always portable.
@@ -195,19 +226,32 @@
 	}
 	nsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed
 	if len(ss) > 0 && ss[0] == '-' {
-		return time.Unix(secs, -1*int64(nsecs)), nil // Negative correction
+		return time.Unix(secs, -1*nsecs), nil // Negative correction
 	}
-	return time.Unix(secs, int64(nsecs)), nil
+	return time.Unix(secs, nsecs), nil
 }
 
-// TODO(dsnet): Implement formatPAXTime.
+// formatPAXTime converts ts into a time of the form %d.%d as described in the
+// PAX specification. This function is capable of negative timestamps.
+func formatPAXTime(ts time.Time) (s string) {
+	secs, nsecs := ts.Unix(), ts.Nanosecond()
+	if nsecs == 0 {
+		return strconv.FormatInt(secs, 10)
+	}
+
+	// If seconds is negative, then perform correction.
+	sign := ""
+	if secs < 0 {
+		sign = "-"             // Remember sign
+		secs = -(secs + 1)     // Add a second to secs
+		nsecs = -(nsecs - 1E9) // Take that second away from nsecs
+	}
+	return strings.TrimRight(fmt.Sprintf("%s%d.%09d", sign, secs, nsecs), "0")
+}
 
 // parsePAXRecord parses the input PAX record string into a key-value pair.
 // If parsing is successful, it will slice off the currently read record and
 // return the remainder as r.
-//
-// A PAX record is of the following form:
-//	"%d %s=%s\n" % (size, key, value)
 func parsePAXRecord(s string) (k, v, r string, err error) {
 	// The size field ends at the first space.
 	sp := strings.IndexByte(s, ' ')
@@ -232,21 +276,51 @@
 	if eq == -1 {
 		return "", "", s, ErrHeader
 	}
-	return rec[:eq], rec[eq+1:], rem, nil
+	k, v = rec[:eq], rec[eq+1:]
+
+	if !validPAXRecord(k, v) {
+		return "", "", s, ErrHeader
+	}
+	return k, v, rem, nil
 }
 
 // formatPAXRecord formats a single PAX record, prefixing it with the
 // appropriate length.
-func formatPAXRecord(k, v string) string {
+func formatPAXRecord(k, v string) (string, error) {
+	if !validPAXRecord(k, v) {
+		return "", ErrHeader
+	}
+
 	const padding = 3 // Extra padding for ' ', '=', and '\n'
 	size := len(k) + len(v) + padding
 	size += len(strconv.Itoa(size))
-	record := fmt.Sprintf("%d %s=%s\n", size, k, v)
+	record := strconv.Itoa(size) + " " + k + "=" + v + "\n"
 
 	// Final adjustment if adding size field increased the record size.
 	if len(record) != size {
 		size = len(record)
-		record = fmt.Sprintf("%d %s=%s\n", size, k, v)
+		record = strconv.Itoa(size) + " " + k + "=" + v + "\n"
 	}
-	return record
+	return record, nil
+}
+
+// validPAXRecord reports whether the key-value pair is valid where each
+// record is formatted as:
+//	"%d %s=%s\n" % (size, key, value)
+//
+// Keys and values should be UTF-8, but the number of bad writers out there
+// forces us to be a more liberal.
+// Thus, we only reject all keys with NUL, and only reject NULs in values
+// for the PAX version of the USTAR string fields.
+// The key must not contain an '=' character.
+func validPAXRecord(k, v string) bool {
+	if k == "" || strings.IndexByte(k, '=') >= 0 {
+		return false
+	}
+	switch k {
+	case paxPath, paxLinkpath, paxUname, paxGname:
+		return !hasNUL(v)
+	default:
+		return !hasNUL(k)
+	}
 }
diff --git a/src/archive/tar/strconv_test.go b/src/archive/tar/strconv_test.go
index beb7093..4cc388c 100644
--- a/src/archive/tar/strconv_test.go
+++ b/src/archive/tar/strconv_test.go
@@ -110,6 +110,25 @@
 		want string
 		ok   bool
 	}{
+		// Test base-8 (octal) encoded values.
+		{0, "0\x00", true},
+		{7, "7\x00", true},
+		{8, "\x80\x08", true},
+		{077, "77\x00", true},
+		{0100, "\x80\x00\x40", true},
+		{0, "0000000\x00", true},
+		{0123, "0000123\x00", true},
+		{07654321, "7654321\x00", true},
+		{07777777, "7777777\x00", true},
+		{010000000, "\x80\x00\x00\x00\x00\x20\x00\x00", true},
+		{0, "00000000000\x00", true},
+		{000001234567, "00001234567\x00", true},
+		{076543210321, "76543210321\x00", true},
+		{012345670123, "12345670123\x00", true},
+		{077777777777, "77777777777\x00", true},
+		{0100000000000, "\x80\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00", true},
+		{math.MaxInt64, "777777777777777777777\x00", true},
+
 		// Test base-256 (binary) encoded values.
 		{-1, "\xff", true},
 		{-1, "\xff\xff", true},
@@ -155,6 +174,45 @@
 	}
 }
 
+func TestFitsInOctal(t *testing.T) {
+	vectors := []struct {
+		input int64
+		width int
+		ok    bool
+	}{
+		{-1, 1, false},
+		{-1, 2, false},
+		{-1, 3, false},
+		{0, 1, true},
+		{0 + 1, 1, false},
+		{0, 2, true},
+		{07, 2, true},
+		{07 + 1, 2, false},
+		{0, 4, true},
+		{0777, 4, true},
+		{0777 + 1, 4, false},
+		{0, 8, true},
+		{07777777, 8, true},
+		{07777777 + 1, 8, false},
+		{0, 12, true},
+		{077777777777, 12, true},
+		{077777777777 + 1, 12, false},
+		{math.MaxInt64, 22, true},
+		{012345670123, 12, true},
+		{01564164, 12, true},
+		{-012345670123, 12, false},
+		{-01564164, 12, false},
+		{-1564164, 30, false},
+	}
+
+	for _, v := range vectors {
+		ok := fitsInOctal(v.width, v.input)
+		if ok != v.ok {
+			t.Errorf("checkOctal(%d, %d): got %v, want %v", v.input, v.width, ok, v.ok)
+		}
+	}
+}
+
 func TestParsePAXTime(t *testing.T) {
 	vectors := []struct {
 		in   string
@@ -236,6 +294,51 @@
 	}
 }
 
+func TestFormatPAXTime(t *testing.T) {
+	vectors := []struct {
+		sec, nsec int64
+		want      string
+	}{
+		{1350244992, 0, "1350244992"},
+		{1350244992, 300000000, "1350244992.3"},
+		{1350244992, 23960100, "1350244992.0239601"},
+		{1350244992, 23960108, "1350244992.023960108"},
+		{+1, +1E9 - 1E0, "1.999999999"},
+		{+1, +1E9 - 1E3, "1.999999"},
+		{+1, +1E9 - 1E6, "1.999"},
+		{+1, +0E0 - 0E0, "1"},
+		{+1, +1E6 - 0E0, "1.001"},
+		{+1, +1E3 - 0E0, "1.000001"},
+		{+1, +1E0 - 0E0, "1.000000001"},
+		{0, 1E9 - 1E0, "0.999999999"},
+		{0, 1E9 - 1E3, "0.999999"},
+		{0, 1E9 - 1E6, "0.999"},
+		{0, 0E0, "0"},
+		{0, 1E6 + 0E0, "0.001"},
+		{0, 1E3 + 0E0, "0.000001"},
+		{0, 1E0 + 0E0, "0.000000001"},
+		{-1, -1E9 + 1E0, "-1.999999999"},
+		{-1, -1E9 + 1E3, "-1.999999"},
+		{-1, -1E9 + 1E6, "-1.999"},
+		{-1, -0E0 + 0E0, "-1"},
+		{-1, -1E6 + 0E0, "-1.001"},
+		{-1, -1E3 + 0E0, "-1.000001"},
+		{-1, -1E0 + 0E0, "-1.000000001"},
+		{-1350244992, 0, "-1350244992"},
+		{-1350244992, -300000000, "-1350244992.3"},
+		{-1350244992, -23960100, "-1350244992.0239601"},
+		{-1350244992, -23960108, "-1350244992.023960108"},
+	}
+
+	for _, v := range vectors {
+		got := formatPAXTime(time.Unix(v.sec, v.nsec))
+		if got != v.want {
+			t.Errorf("formatPAXTime(%ds, %dns): got %q, want %q",
+				v.sec, v.nsec, got, v.want)
+		}
+	}
+}
+
 func TestParsePAXRecord(t *testing.T) {
 	medName := strings.Repeat("CD", 50)
 	longName := strings.Repeat("AB", 100)
@@ -256,7 +359,7 @@
 		{"18 foo=b=\nar=\n==\x00\n", "", "foo", "b=\nar=\n==\x00", true},
 		{"27 foo=hello9 foo=ba\nworld\n", "", "foo", "hello9 foo=ba\nworld", true},
 		{"27 ☺☻☹=日a本b語ç\nmeow mix", "meow mix", "☺☻☹", "日a本b語ç", true},
-		{"17 \x00hello=\x00world\n", "", "\x00hello", "\x00world", true},
+		{"17 \x00hello=\x00world\n", "17 \x00hello=\x00world\n", "", "", false},
 		{"1 k=1\n", "1 k=1\n", "", "", false},
 		{"6 k~1\n", "6 k~1\n", "", "", false},
 		{"6_k=1\n", "6_k=1\n", "", "", false},
@@ -296,21 +399,33 @@
 		inKey string
 		inVal string
 		want  string
+		ok    bool
 	}{
-		{"k", "v", "6 k=v\n"},
-		{"path", "/etc/hosts", "19 path=/etc/hosts\n"},
-		{"path", longName, "210 path=" + longName + "\n"},
-		{"path", medName, "110 path=" + medName + "\n"},
-		{"foo", "ba", "9 foo=ba\n"},
-		{"foo", "bar", "11 foo=bar\n"},
-		{"foo", "b=\nar=\n==\x00", "18 foo=b=\nar=\n==\x00\n"},
-		{"foo", "hello9 foo=ba\nworld", "27 foo=hello9 foo=ba\nworld\n"},
-		{"☺☻☹", "日a本b語ç", "27 ☺☻☹=日a本b語ç\n"},
-		{"\x00hello", "\x00world", "17 \x00hello=\x00world\n"},
+		{"k", "v", "6 k=v\n", true},
+		{"path", "/etc/hosts", "19 path=/etc/hosts\n", true},
+		{"path", longName, "210 path=" + longName + "\n", true},
+		{"path", medName, "110 path=" + medName + "\n", true},
+		{"foo", "ba", "9 foo=ba\n", true},
+		{"foo", "bar", "11 foo=bar\n", true},
+		{"foo", "b=\nar=\n==\x00", "18 foo=b=\nar=\n==\x00\n", true},
+		{"foo", "hello9 foo=ba\nworld", "27 foo=hello9 foo=ba\nworld\n", true},
+		{"☺☻☹", "日a本b語ç", "27 ☺☻☹=日a本b語ç\n", true},
+		{"xhello", "\x00world", "17 xhello=\x00world\n", true},
+		{"path", "null\x00", "", false},
+		{"null\x00", "value", "", false},
+		{paxSchilyXattr + "key", "null\x00", "26 SCHILY.xattr.key=null\x00\n", true},
 	}
 
 	for _, v := range vectors {
-		got := formatPAXRecord(v.inKey, v.inVal)
+		got, err := formatPAXRecord(v.inKey, v.inVal)
+		ok := (err == nil)
+		if ok != v.ok {
+			if v.ok {
+				t.Errorf("formatPAXRecord(%q, %q): got format failure, want success", v.inKey, v.inVal)
+			} else {
+				t.Errorf("formatPAXRecord(%q, %q): got format success, want failure", v.inKey, v.inVal)
+			}
+		}
 		if got != v.want {
 			t.Errorf("formatPAXRecord(%q, %q): got %q, want %q",
 				v.inKey, v.inVal, got, v.want)
diff --git a/src/archive/tar/tar_test.go b/src/archive/tar/tar_test.go
index fb7a9dc..af80d6e 100644
--- a/src/archive/tar/tar_test.go
+++ b/src/archive/tar/tar_test.go
@@ -6,8 +6,12 @@
 
 import (
 	"bytes"
+	"errors"
+	"fmt"
 	"internal/testenv"
+	"io"
 	"io/ioutil"
+	"math"
 	"os"
 	"path"
 	"path/filepath"
@@ -17,6 +21,193 @@
 	"time"
 )
 
+type testError struct{ error }
+
+type fileOps []interface{} // []T where T is (string | int64)
+
+// testFile is an io.ReadWriteSeeker where the IO operations performed
+// on it must match the list of operations in ops.
+type testFile struct {
+	ops fileOps
+	pos int64
+}
+
+func (f *testFile) Read(b []byte) (int, error) {
+	if len(b) == 0 {
+		return 0, nil
+	}
+	if len(f.ops) == 0 {
+		return 0, io.EOF
+	}
+	s, ok := f.ops[0].(string)
+	if !ok {
+		return 0, errors.New("unexpected Read operation")
+	}
+
+	n := copy(b, s)
+	if len(s) > n {
+		f.ops[0] = s[n:]
+	} else {
+		f.ops = f.ops[1:]
+	}
+	f.pos += int64(len(b))
+	return n, nil
+}
+
+func (f *testFile) Write(b []byte) (int, error) {
+	if len(b) == 0 {
+		return 0, nil
+	}
+	if len(f.ops) == 0 {
+		return 0, errors.New("unexpected Write operation")
+	}
+	s, ok := f.ops[0].(string)
+	if !ok {
+		return 0, errors.New("unexpected Write operation")
+	}
+
+	if !strings.HasPrefix(s, string(b)) {
+		return 0, testError{fmt.Errorf("got Write(%q), want Write(%q)", b, s)}
+	}
+	if len(s) > len(b) {
+		f.ops[0] = s[len(b):]
+	} else {
+		f.ops = f.ops[1:]
+	}
+	f.pos += int64(len(b))
+	return len(b), nil
+}
+
+func (f *testFile) Seek(pos int64, whence int) (int64, error) {
+	if pos == 0 && whence == io.SeekCurrent {
+		return f.pos, nil
+	}
+	if len(f.ops) == 0 {
+		return 0, errors.New("unexpected Seek operation")
+	}
+	s, ok := f.ops[0].(int64)
+	if !ok {
+		return 0, errors.New("unexpected Seek operation")
+	}
+
+	if s != pos || whence != io.SeekCurrent {
+		return 0, testError{fmt.Errorf("got Seek(%d, %d), want Seek(%d, %d)", pos, whence, s, io.SeekCurrent)}
+	}
+	f.pos += s
+	f.ops = f.ops[1:]
+	return f.pos, nil
+}
+
+func equalSparseEntries(x, y []sparseEntry) bool {
+	return (len(x) == 0 && len(y) == 0) || reflect.DeepEqual(x, y)
+}
+
+func TestSparseEntries(t *testing.T) {
+	vectors := []struct {
+		in   []sparseEntry
+		size int64
+
+		wantValid    bool          // Result of validateSparseEntries
+		wantAligned  []sparseEntry // Result of alignSparseEntries
+		wantInverted []sparseEntry // Result of invertSparseEntries
+	}{{
+		in: []sparseEntry{}, size: 0,
+		wantValid:    true,
+		wantInverted: []sparseEntry{{0, 0}},
+	}, {
+		in: []sparseEntry{}, size: 5000,
+		wantValid:    true,
+		wantInverted: []sparseEntry{{0, 5000}},
+	}, {
+		in: []sparseEntry{{0, 5000}}, size: 5000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{0, 5000}},
+		wantInverted: []sparseEntry{{5000, 0}},
+	}, {
+		in: []sparseEntry{{1000, 4000}}, size: 5000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{1024, 3976}},
+		wantInverted: []sparseEntry{{0, 1000}, {5000, 0}},
+	}, {
+		in: []sparseEntry{{0, 3000}}, size: 5000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{0, 2560}},
+		wantInverted: []sparseEntry{{3000, 2000}},
+	}, {
+		in: []sparseEntry{{3000, 2000}}, size: 5000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{3072, 1928}},
+		wantInverted: []sparseEntry{{0, 3000}, {5000, 0}},
+	}, {
+		in: []sparseEntry{{2000, 2000}}, size: 5000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{2048, 1536}},
+		wantInverted: []sparseEntry{{0, 2000}, {4000, 1000}},
+	}, {
+		in: []sparseEntry{{0, 2000}, {8000, 2000}}, size: 10000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{0, 1536}, {8192, 1808}},
+		wantInverted: []sparseEntry{{2000, 6000}, {10000, 0}},
+	}, {
+		in: []sparseEntry{{0, 2000}, {2000, 2000}, {4000, 0}, {4000, 3000}, {7000, 1000}, {8000, 0}, {8000, 2000}}, size: 10000,
+		wantValid:    true,
+		wantAligned:  []sparseEntry{{0, 1536}, {2048, 1536}, {4096, 2560}, {7168, 512}, {8192, 1808}},
+		wantInverted: []sparseEntry{{10000, 0}},
+	}, {
+		in: []sparseEntry{{0, 0}, {1000, 0}, {2000, 0}, {3000, 0}, {4000, 0}, {5000, 0}}, size: 5000,
+		wantValid:    true,
+		wantInverted: []sparseEntry{{0, 5000}},
+	}, {
+		in: []sparseEntry{{1, 0}}, size: 0,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{-1, 0}}, size: 100,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{0, -1}}, size: 100,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{0, 0}}, size: -100,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{math.MaxInt64, 3}, {6, -5}}, size: 35,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{1, 3}, {6, -5}}, size: 35,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{math.MaxInt64, math.MaxInt64}}, size: math.MaxInt64,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{3, 3}}, size: 5,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{2, 0}, {1, 0}, {0, 0}}, size: 3,
+		wantValid: false,
+	}, {
+		in: []sparseEntry{{1, 3}, {2, 2}}, size: 10,
+		wantValid: false,
+	}}
+
+	for i, v := range vectors {
+		gotValid := validateSparseEntries(v.in, v.size)
+		if gotValid != v.wantValid {
+			t.Errorf("test %d, validateSparseEntries() = %v, want %v", i, gotValid, v.wantValid)
+		}
+		if !v.wantValid {
+			continue
+		}
+		gotAligned := alignSparseEntries(append([]sparseEntry{}, v.in...), v.size)
+		if !equalSparseEntries(gotAligned, v.wantAligned) {
+			t.Errorf("test %d, alignSparseEntries():\ngot  %v\nwant %v", i, gotAligned, v.wantAligned)
+		}
+		gotInverted := invertSparseEntries(append([]sparseEntry{}, v.in...), v.size)
+		if !equalSparseEntries(gotInverted, v.wantInverted) {
+			t.Errorf("test %d, inverseSparseEntries():\ngot  %v\nwant %v", i, gotInverted, v.wantInverted)
+		}
+	}
+}
+
 func TestFileInfoHeader(t *testing.T) {
 	fi, err := os.Stat("testdata/small.txt")
 	if err != nil {
@@ -109,15 +300,12 @@
 	var b bytes.Buffer
 	tw := NewWriter(&b)
 	hdr := &Header{
-		Name: "file.txt",
-		Uid:  1 << 21, // too big for 8 octal digits
-		Size: int64(len(data)),
-		// AddDate to strip monotonic clock reading,
-		// and Round to discard sub-second precision,
-		// both of which are not included in the tar header
-		// and would otherwise break the round-trip check
-		// below.
-		ModTime: time.Now().AddDate(0, 0, 0).Round(1 * time.Second),
+		Name:       "file.txt",
+		Uid:        1 << 21, // Too big for 8 octal digits
+		Size:       int64(len(data)),
+		ModTime:    time.Now().Round(time.Second),
+		PAXRecords: map[string]string{"uid": "2097152"},
+		Format:     FormatPAX,
 	}
 	if err := tw.WriteHeader(hdr); err != nil {
 		t.Fatalf("tw.WriteHeader: %v", err)
@@ -329,3 +517,338 @@
 		}
 	}
 }
+
+func TestHeaderAllowedFormats(t *testing.T) {
+	vectors := []struct {
+		header  *Header           // Input header
+		paxHdrs map[string]string // Expected PAX headers that may be needed
+		formats Format            // Expected formats that can encode the header
+	}{{
+		header:  &Header{},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Size: 077777777777},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Size: 077777777777, Format: FormatUSTAR},
+		formats: FormatUSTAR,
+	}, {
+		header:  &Header{Size: 077777777777, Format: FormatPAX},
+		formats: FormatUSTAR | FormatPAX,
+	}, {
+		header:  &Header{Size: 077777777777, Format: FormatGNU},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Size: 077777777777 + 1},
+		paxHdrs: map[string]string{paxSize: "8589934592"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Size: 077777777777 + 1, Format: FormatPAX},
+		paxHdrs: map[string]string{paxSize: "8589934592"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{Size: 077777777777 + 1, Format: FormatGNU},
+		paxHdrs: map[string]string{paxSize: "8589934592"},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Mode: 07777777},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Mode: 07777777 + 1},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Devmajor: -123},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Devmajor: 1<<56 - 1},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Devmajor: 1 << 56},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Devmajor: -1 << 56},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Devmajor: -1<<56 - 1},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Name: "用戶名", Devmajor: -1 << 56},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{Size: math.MaxInt64},
+		paxHdrs: map[string]string{paxSize: "9223372036854775807"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Size: math.MinInt64},
+		paxHdrs: map[string]string{paxSize: "-9223372036854775808"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Uname: "0123456789abcdef0123456789abcdef"},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Uname: "0123456789abcdef0123456789abcdefx"},
+		paxHdrs: map[string]string{paxUname: "0123456789abcdef0123456789abcdefx"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{Name: "foobar"},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Name: strings.Repeat("a", nameSize)},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Name: strings.Repeat("a", nameSize+1)},
+		paxHdrs: map[string]string{paxPath: strings.Repeat("a", nameSize+1)},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Linkname: "用戶名"},
+		paxHdrs: map[string]string{paxLinkpath: "用戶名"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Linkname: strings.Repeat("用戶名\x00", nameSize)},
+		paxHdrs: map[string]string{paxLinkpath: strings.Repeat("用戶名\x00", nameSize)},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Linkname: "\x00hello"},
+		paxHdrs: map[string]string{paxLinkpath: "\x00hello"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Uid: 07777777},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Uid: 07777777 + 1},
+		paxHdrs: map[string]string{paxUid: "2097152"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Xattrs: nil},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Xattrs: map[string]string{"foo": "bar"}},
+		paxHdrs: map[string]string{paxSchilyXattr + "foo": "bar"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{Xattrs: map[string]string{"foo": "bar"}, Format: FormatGNU},
+		paxHdrs: map[string]string{paxSchilyXattr + "foo": "bar"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Xattrs: map[string]string{"用戶名": "\x00hello"}},
+		paxHdrs: map[string]string{paxSchilyXattr + "用戶名": "\x00hello"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{Xattrs: map[string]string{"foo=bar": "baz"}},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Xattrs: map[string]string{"foo": ""}},
+		paxHdrs: map[string]string{paxSchilyXattr + "foo": ""},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{ModTime: time.Unix(0, 0)},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(077777777777, 0)},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(077777777777+1, 0)},
+		paxHdrs: map[string]string{paxMtime: "8589934592"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(math.MaxInt64, 0)},
+		paxHdrs: map[string]string{paxMtime: "9223372036854775807"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(math.MaxInt64, 0), Format: FormatUSTAR},
+		paxHdrs: map[string]string{paxMtime: "9223372036854775807"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{ModTime: time.Unix(-1, 0)},
+		paxHdrs: map[string]string{paxMtime: "-1"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 500)},
+		paxHdrs: map[string]string{paxMtime: "1.0000005"},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 0)},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 0), Format: FormatPAX},
+		formats: FormatUSTAR | FormatPAX,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 500), Format: FormatUSTAR},
+		paxHdrs: map[string]string{paxMtime: "1.0000005"},
+		formats: FormatUSTAR,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 500), Format: FormatPAX},
+		paxHdrs: map[string]string{paxMtime: "1.0000005"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{ModTime: time.Unix(1, 500), Format: FormatGNU},
+		paxHdrs: map[string]string{paxMtime: "1.0000005"},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(-1, 500)},
+		paxHdrs: map[string]string{paxMtime: "-0.9999995"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ModTime: time.Unix(-1, 500), Format: FormatGNU},
+		paxHdrs: map[string]string{paxMtime: "-0.9999995"},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{AccessTime: time.Unix(0, 0)},
+		paxHdrs: map[string]string{paxAtime: "0"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{AccessTime: time.Unix(0, 0), Format: FormatUSTAR},
+		paxHdrs: map[string]string{paxAtime: "0"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{AccessTime: time.Unix(0, 0), Format: FormatPAX},
+		paxHdrs: map[string]string{paxAtime: "0"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{AccessTime: time.Unix(0, 0), Format: FormatGNU},
+		paxHdrs: map[string]string{paxAtime: "0"},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{AccessTime: time.Unix(-123, 0)},
+		paxHdrs: map[string]string{paxAtime: "-123"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{AccessTime: time.Unix(-123, 0), Format: FormatPAX},
+		paxHdrs: map[string]string{paxAtime: "-123"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{ChangeTime: time.Unix(123, 456)},
+		paxHdrs: map[string]string{paxCtime: "123.000000456"},
+		formats: FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{ChangeTime: time.Unix(123, 456), Format: FormatUSTAR},
+		paxHdrs: map[string]string{paxCtime: "123.000000456"},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{ChangeTime: time.Unix(123, 456), Format: FormatGNU},
+		paxHdrs: map[string]string{paxCtime: "123.000000456"},
+		formats: FormatGNU,
+	}, {
+		header:  &Header{ChangeTime: time.Unix(123, 456), Format: FormatPAX},
+		paxHdrs: map[string]string{paxCtime: "123.000000456"},
+		formats: FormatPAX,
+	}, {
+		header:  &Header{Name: "foo/", Typeflag: TypeDir},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}, {
+		header:  &Header{Name: "foo/", Typeflag: TypeReg},
+		formats: FormatUnknown,
+	}, {
+		header:  &Header{Name: "foo/", Typeflag: TypeSymlink},
+		formats: FormatUSTAR | FormatPAX | FormatGNU,
+	}}
+
+	for i, v := range vectors {
+		formats, paxHdrs, err := v.header.allowedFormats()
+		if formats != v.formats {
+			t.Errorf("test %d, allowedFormats(): got %v, want %v", i, formats, v.formats)
+		}
+		if formats&FormatPAX > 0 && !reflect.DeepEqual(paxHdrs, v.paxHdrs) && !(len(paxHdrs) == 0 && len(v.paxHdrs) == 0) {
+			t.Errorf("test %d, allowedFormats():\ngot  %v\nwant %s", i, paxHdrs, v.paxHdrs)
+		}
+		if (formats != FormatUnknown) && (err != nil) {
+			t.Errorf("test %d, unexpected error: %v", i, err)
+		}
+		if (formats == FormatUnknown) && (err == nil) {
+			t.Errorf("test %d, got nil-error, want non-nil error", i)
+		}
+	}
+}
+
+func Benchmark(b *testing.B) {
+	type file struct {
+		hdr  *Header
+		body []byte
+	}
+
+	vectors := []struct {
+		label string
+		files []file
+	}{{
+		"USTAR",
+		[]file{{
+			&Header{Name: "bar", Mode: 0640, Size: int64(3)},
+			[]byte("foo"),
+		}, {
+			&Header{Name: "world", Mode: 0640, Size: int64(5)},
+			[]byte("hello"),
+		}},
+	}, {
+		"GNU",
+		[]file{{
+			&Header{Name: "bar", Mode: 0640, Size: int64(3), Devmajor: -1},
+			[]byte("foo"),
+		}, {
+			&Header{Name: "world", Mode: 0640, Size: int64(5), Devmajor: -1},
+			[]byte("hello"),
+		}},
+	}, {
+		"PAX",
+		[]file{{
+			&Header{Name: "bar", Mode: 0640, Size: int64(3), Xattrs: map[string]string{"foo": "bar"}},
+			[]byte("foo"),
+		}, {
+			&Header{Name: "world", Mode: 0640, Size: int64(5), Xattrs: map[string]string{"foo": "bar"}},
+			[]byte("hello"),
+		}},
+	}}
+
+	b.Run("Writer", func(b *testing.B) {
+		for _, v := range vectors {
+			b.Run(v.label, func(b *testing.B) {
+				b.ReportAllocs()
+				for i := 0; i < b.N; i++ {
+					// Writing to ioutil.Discard because we want to
+					// test purely the writer code and not bring in disk performance into this.
+					tw := NewWriter(ioutil.Discard)
+					for _, file := range v.files {
+						if err := tw.WriteHeader(file.hdr); err != nil {
+							b.Errorf("unexpected WriteHeader error: %v", err)
+						}
+						if _, err := tw.Write(file.body); err != nil {
+							b.Errorf("unexpected Write error: %v", err)
+						}
+					}
+					if err := tw.Close(); err != nil {
+						b.Errorf("unexpected Close error: %v", err)
+					}
+				}
+			})
+		}
+	})
+
+	b.Run("Reader", func(b *testing.B) {
+		for _, v := range vectors {
+			var buf bytes.Buffer
+			var r bytes.Reader
+
+			// Write the archive to a byte buffer.
+			tw := NewWriter(&buf)
+			for _, file := range v.files {
+				tw.WriteHeader(file.hdr)
+				tw.Write(file.body)
+			}
+			tw.Close()
+			b.Run(v.label, func(b *testing.B) {
+				b.ReportAllocs()
+				// Read from the byte buffer.
+				for i := 0; i < b.N; i++ {
+					r.Reset(buf.Bytes())
+					tr := NewReader(&r)
+					if _, err := tr.Next(); err != nil {
+						b.Errorf("unexpected Next error: %v", err)
+					}
+					if _, err := io.Copy(ioutil.Discard, tr); err != nil {
+						b.Errorf("unexpected Copy error : %v", err)
+					}
+				}
+			})
+		}
+	})
+
+}
diff --git a/src/archive/tar/testdata/gnu-long-nul.tar b/src/archive/tar/testdata/gnu-long-nul.tar
new file mode 100644
index 0000000..28bc812
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-long-nul.tar
Binary files differ
diff --git a/src/archive/tar/testdata/gnu-nil-sparse-data.tar b/src/archive/tar/testdata/gnu-nil-sparse-data.tar
new file mode 100644
index 0000000..df1aa83
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-nil-sparse-data.tar
Binary files differ
diff --git a/src/archive/tar/testdata/gnu-nil-sparse-hole.tar b/src/archive/tar/testdata/gnu-nil-sparse-hole.tar
new file mode 100644
index 0000000..496abfe
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-nil-sparse-hole.tar
Binary files differ
diff --git a/src/archive/tar/testdata/gnu-not-utf8.tar b/src/archive/tar/testdata/gnu-not-utf8.tar
new file mode 100644
index 0000000..81cec67
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-not-utf8.tar
Binary files differ
diff --git a/src/archive/tar/testdata/gnu-sparse-big.tar b/src/archive/tar/testdata/gnu-sparse-big.tar
new file mode 100644
index 0000000..1a5cfc9
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-sparse-big.tar
Binary files differ
diff --git a/src/archive/tar/testdata/gnu-utf8.tar b/src/archive/tar/testdata/gnu-utf8.tar
new file mode 100644
index 0000000..2c9c807
--- /dev/null
+++ b/src/archive/tar/testdata/gnu-utf8.tar
Binary files differ
diff --git a/src/archive/tar/testdata/invalid-go17.tar b/src/archive/tar/testdata/invalid-go17.tar
new file mode 100644
index 0000000..58f2488
--- /dev/null
+++ b/src/archive/tar/testdata/invalid-go17.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-global-records.tar b/src/archive/tar/testdata/pax-global-records.tar
new file mode 100644
index 0000000..3d3d241
--- /dev/null
+++ b/src/archive/tar/testdata/pax-global-records.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-nil-sparse-data.tar b/src/archive/tar/testdata/pax-nil-sparse-data.tar
new file mode 100644
index 0000000..e59bd94
--- /dev/null
+++ b/src/archive/tar/testdata/pax-nil-sparse-data.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-nil-sparse-hole.tar b/src/archive/tar/testdata/pax-nil-sparse-hole.tar
new file mode 100644
index 0000000..b44327b
--- /dev/null
+++ b/src/archive/tar/testdata/pax-nil-sparse-hole.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-nul-path.tar b/src/archive/tar/testdata/pax-nul-path.tar
new file mode 100644
index 0000000..c78f82b
--- /dev/null
+++ b/src/archive/tar/testdata/pax-nul-path.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-nul-xattrs.tar b/src/archive/tar/testdata/pax-nul-xattrs.tar
new file mode 100644
index 0000000..881f517
--- /dev/null
+++ b/src/archive/tar/testdata/pax-nul-xattrs.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-pos-size-file.tar b/src/archive/tar/testdata/pax-pos-size-file.tar
index aed9a8a..ea5ccf9 100644
--- a/src/archive/tar/testdata/pax-pos-size-file.tar
+++ b/src/archive/tar/testdata/pax-pos-size-file.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-records.tar b/src/archive/tar/testdata/pax-records.tar
new file mode 100644
index 0000000..276c211
--- /dev/null
+++ b/src/archive/tar/testdata/pax-records.tar
Binary files differ
diff --git a/src/archive/tar/testdata/pax-sparse-big.tar b/src/archive/tar/testdata/pax-sparse-big.tar
new file mode 100644
index 0000000..65d1f8e
--- /dev/null
+++ b/src/archive/tar/testdata/pax-sparse-big.tar
Binary files differ
diff --git a/src/archive/tar/testdata/trailing-slash.tar b/src/archive/tar/testdata/trailing-slash.tar
new file mode 100644
index 0000000..bf1b2ec
--- /dev/null
+++ b/src/archive/tar/testdata/trailing-slash.tar
Binary files differ
diff --git a/src/archive/tar/testdata/ustar-file-devs.tar b/src/archive/tar/testdata/ustar-file-devs.tar
new file mode 100644
index 0000000..146e25b
--- /dev/null
+++ b/src/archive/tar/testdata/ustar-file-devs.tar
Binary files differ
diff --git a/src/archive/tar/testdata/ustar.issue12594.tar b/src/archive/tar/testdata/ustar.issue12594.tar
deleted file mode 100644
index 50fcd00..0000000
--- a/src/archive/tar/testdata/ustar.issue12594.tar
+++ /dev/null
Binary files differ
diff --git a/src/archive/tar/testdata/writer-big-long.tar b/src/archive/tar/testdata/writer-big-long.tar
index ea9bfa8..09fc5dd 100644
--- a/src/archive/tar/testdata/writer-big-long.tar
+++ b/src/archive/tar/testdata/writer-big-long.tar
Binary files differ
diff --git a/src/archive/tar/testdata/writer-big.tar b/src/archive/tar/testdata/writer-big.tar
index 753e883..435dcbc 100644
--- a/src/archive/tar/testdata/writer-big.tar
+++ b/src/archive/tar/testdata/writer-big.tar
Binary files differ
diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go
index c51c243..97d23f8 100644
--- a/src/archive/tar/writer.go
+++ b/src/archive/tar/writer.go
@@ -4,255 +4,391 @@
 
 package tar
 
-// TODO(dsymonds):
-// - catch more errors (no first header, etc.)
-
 import (
 	"bytes"
-	"errors"
 	"fmt"
 	"io"
 	"path"
 	"sort"
-	"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")
-	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.
+// Writer provides sequential writing of a tar archive.
+// Write.WriteHeader begins a new file with the provided Header,
+// and then Writer can be treated as an io.Writer to supply that file's data.
 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    block // buffer to use in writeHeader when writing a regular header
-	paxHdrBuff block // buffer to use in writeHeader when writing a PAX header
+	w    io.Writer
+	pad  int64      // Amount of padding to write after current file entry
+	curr fileWriter // Writer for current file entry
+	hdr  Header     // Shallow copy of Header that is safe for mutations
+	blk  block      // Buffer to use as temporary local storage
+
+	// err is a persistent error.
+	// It is only the responsibility of every exported method of Writer to
+	// ensure that this error is sticky.
+	err error
 }
 
 // NewWriter creates a new Writer writing to w.
-func NewWriter(w io.Writer) *Writer { return &Writer{w: w} }
+func NewWriter(w io.Writer) *Writer {
+	return &Writer{w: w, curr: &regFileWriter{w, 0}}
+}
 
-// Flush finishes writing the current file (optional).
+type fileWriter interface {
+	io.Writer
+	fileState
+
+	ReadFrom(io.Reader) (int64, error)
+}
+
+// Flush finishes writing the current file's block padding.
+// The current file must be fully written before Flush can be called.
+//
+// This is unnecessary as the next call to WriteHeader or Close
+// will implicitly flush out the file's padding.
 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
-}
-
-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(dsnet): 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
-
-	// 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
+	if nb := tw.curr.LogicalRemaining(); nb > 0 {
+		return fmt.Errorf("archive/tar: missed writing %d bytes", nb)
 	}
-	copy(header[:], zeroBlock[:])
-
-	// Wrappers around formatter that automatically sets paxHeaders if the
-	// argument extends beyond the capacity of the input byte slice.
-	var f formatter
-	var formatString = func(b []byte, s string, paxKeyword string) {
-		needsPaxHeader := paxKeyword != paxNone && len(s) > len(b) || !isASCII(s)
-		if needsPaxHeader {
-			paxHeaders[paxKeyword] = s
-		}
-
-		// Write string in a best-effort manner to satisfy readers that expect
-		// the field to be non-empty.
-		s = toASCII(s)
-		if len(s) > len(b) {
-			s = s[:len(b)]
-		}
-		f.formatString(b, s) // Should never error
-	}
-	var formatNumeric = func(b []byte, x int64, paxKeyword string) {
-		// Try octal first.
-		s := strconv.FormatInt(x, 8)
-		if len(s) < len(b) {
-			f.formatOctal(b, x)
-			return
-		}
-
-		// If it is too long for octal, and PAX is preferred, use a PAX header.
-		if paxKeyword != paxNone && tw.preferPax {
-			f.formatOctal(b, 0)
-			s := strconv.FormatInt(x, 10)
-			paxHeaders[paxKeyword] = s
-			return
-		}
-
-		tw.usedBinary = true
-		f.formatNumeric(b, x)
-	}
-
-	// Handle out of range ModTime carefully.
-	var modTime int64
-	if !hdr.ModTime.Before(minTime) && !hdr.ModTime.After(maxTime) {
-		modTime = hdr.ModTime.Unix()
-	}
-
-	v7 := header.V7()
-	formatString(v7.Name(), hdr.Name, paxPath)
-	// TODO(dsnet): The GNU format permits the mode field to be encoded in
-	// base-256 format. Thus, we can use formatNumeric instead of formatOctal.
-	f.formatOctal(v7.Mode(), hdr.Mode)
-	formatNumeric(v7.UID(), int64(hdr.Uid), paxUid)
-	formatNumeric(v7.GID(), int64(hdr.Gid), paxGid)
-	formatNumeric(v7.Size(), hdr.Size, paxSize)
-	// TODO(dsnet): Consider using PAX for finer time granularity.
-	formatNumeric(v7.ModTime(), modTime, paxNone)
-	v7.TypeFlag()[0] = hdr.Typeflag
-	formatString(v7.LinkName(), hdr.Linkname, paxLinkpath)
-
-	ustar := header.USTAR()
-	formatString(ustar.UserName(), hdr.Uname, paxUname)
-	formatString(ustar.GroupName(), hdr.Gname, paxGname)
-	formatNumeric(ustar.DevMajor(), hdr.Devmajor, paxNone)
-	formatNumeric(ustar.DevMinor(), hdr.Devminor, paxNone)
-
-	// TODO(dsnet): The logic surrounding the prefix field is broken when trying
-	// to encode the header as GNU format. The challenge with the current logic
-	// is that we are unsure what format we are using at any given moment until
-	// we have processed *all* of the fields. The problem is that by the time
-	// all fields have been processed, some work has already been done to handle
-	// each field under the assumption that it is for one given format or
-	// another. In some situations, this causes the Writer to be confused and
-	// encode a prefix field when the format being used is GNU. Thus, producing
-	// an invalid tar file.
-	//
-	// As a short-term fix, we disable the logic to use the prefix field, which
-	// will force the badly generated GNU files to become encoded as being
-	// the PAX format.
-	//
-	// As an alternative fix, we could hard-code preferPax to be true. However,
-	// this is problematic for the following reasons:
-	//	* The preferPax functionality is not tested at all.
-	//	* This can result in headers that try to use both the GNU and PAX
-	//	features at the same time, which is also wrong.
-	//
-	// The proper fix for this is to use a two-pass method:
-	//	* The first pass simply determines what set of formats can possibly
-	//	encode the given header.
-	//	* The second pass actually encodes the header as that given format
-	//	without worrying about violating the format.
-	//
-	// See the following:
-	//	https://golang.org/issue/12594
-	//	https://golang.org/issue/17630
-	//	https://golang.org/issue/9683
-	const usePrefix = false
-
-	// try to use a ustar header when only the name is too long
-	_, paxPathUsed := paxHeaders[paxPath]
-	if usePrefix && !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
-		prefix, suffix, ok := splitUSTARPath(hdr.Name)
-		if ok {
-			// Since we can encode in USTAR format, disable PAX header.
-			delete(paxHeaders, paxPath)
-
-			// Update the path fields
-			formatString(v7.Name(), suffix, paxNone)
-			formatString(ustar.Prefix(), prefix, paxNone)
-		}
-	}
-
-	if tw.usedBinary {
-		header.SetFormat(formatGNU)
-	} else {
-		header.SetFormat(formatUSTAR)
-	}
-
-	// Check if there were any formatting errors.
-	if f.err != nil {
-		tw.err = f.err
+	if _, tw.err = tw.w.Write(zeroBlock[:tw.pad]); tw.err != nil {
 		return tw.err
 	}
+	tw.pad = 0
+	return nil
+}
 
-	if allowPax {
-		for k, v := range hdr.Xattrs {
-			paxHeaders[paxXattr+k] = v
+// WriteHeader writes hdr and prepares to accept the file's contents.
+// The Header.Size determines how many bytes can be written for the next file.
+// If the current file is not fully written, then this returns an error.
+// This implicitly flushes any padding necessary before writing the header.
+func (tw *Writer) WriteHeader(hdr *Header) error {
+	if err := tw.Flush(); err != nil {
+		return err
+	}
+	tw.hdr = *hdr // Shallow copy of Header
+
+	// Round ModTime and ignore AccessTime and ChangeTime unless
+	// the format is explicitly chosen.
+	// This ensures nominal usage of WriteHeader (without specifying the format)
+	// does not always result in the PAX format being chosen, which
+	// causes a 1KiB increase to every header.
+	if tw.hdr.Format == FormatUnknown {
+		tw.hdr.ModTime = tw.hdr.ModTime.Round(time.Second)
+		tw.hdr.AccessTime = time.Time{}
+		tw.hdr.ChangeTime = time.Time{}
+	}
+
+	allowedFormats, paxHdrs, err := tw.hdr.allowedFormats()
+	switch {
+	case allowedFormats.has(FormatUSTAR):
+		tw.err = tw.writeUSTARHeader(&tw.hdr)
+		return tw.err
+	case allowedFormats.has(FormatPAX):
+		tw.err = tw.writePAXHeader(&tw.hdr, paxHdrs)
+		return tw.err
+	case allowedFormats.has(FormatGNU):
+		tw.err = tw.writeGNUHeader(&tw.hdr)
+		return tw.err
+	default:
+		return err // Non-fatal error
+	}
+}
+
+func (tw *Writer) writeUSTARHeader(hdr *Header) error {
+	// Check if we can use USTAR prefix/suffix splitting.
+	var namePrefix string
+	if prefix, suffix, ok := splitUSTARPath(hdr.Name); ok {
+		namePrefix, hdr.Name = prefix, suffix
+	}
+
+	// Pack the main header.
+	var f formatter
+	blk := tw.templateV7Plus(hdr, f.formatString, f.formatOctal)
+	f.formatString(blk.USTAR().Prefix(), namePrefix)
+	blk.SetFormat(FormatUSTAR)
+	if f.err != nil {
+		return f.err // Should never happen since header is validated
+	}
+	return tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag)
+}
+
+func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
+	realName, realSize := hdr.Name, hdr.Size
+
+	// TODO(dsnet): Re-enable this when adding sparse support.
+	// See https://golang.org/issue/22735
+	/*
+		// Handle sparse files.
+		var spd sparseDatas
+		var spb []byte
+		if len(hdr.SparseHoles) > 0 {
+			sph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map
+			sph = alignSparseEntries(sph, hdr.Size)
+			spd = invertSparseEntries(sph, hdr.Size)
+
+			// Format the sparse map.
+			hdr.Size = 0 // Replace with encoded size
+			spb = append(strconv.AppendInt(spb, int64(len(spd)), 10), '\n')
+			for _, s := range spd {
+				hdr.Size += s.Length
+				spb = append(strconv.AppendInt(spb, s.Offset, 10), '\n')
+				spb = append(strconv.AppendInt(spb, s.Length, 10), '\n')
+			}
+			pad := blockPadding(int64(len(spb)))
+			spb = append(spb, zeroBlock[:pad]...)
+			hdr.Size += int64(len(spb)) // Accounts for encoded sparse map
+
+			// Add and modify appropriate PAX records.
+			dir, file := path.Split(realName)
+			hdr.Name = path.Join(dir, "GNUSparseFile.0", file)
+			paxHdrs[paxGNUSparseMajor] = "1"
+			paxHdrs[paxGNUSparseMinor] = "0"
+			paxHdrs[paxGNUSparseName] = realName
+			paxHdrs[paxGNUSparseRealSize] = strconv.FormatInt(realSize, 10)
+			paxHdrs[paxSize] = strconv.FormatInt(hdr.Size, 10)
+			delete(paxHdrs, paxPath) // Recorded by paxGNUSparseName
+		}
+	*/
+	_ = realSize
+
+	// Write PAX records to the output.
+	isGlobal := hdr.Typeflag == TypeXGlobalHeader
+	if len(paxHdrs) > 0 || isGlobal {
+		// Sort keys for deterministic ordering.
+		var keys []string
+		for k := range paxHdrs {
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+
+		// Write each record to a buffer.
+		var buf bytes.Buffer
+		for _, k := range keys {
+			rec, err := formatPAXRecord(k, paxHdrs[k])
+			if err != nil {
+				return err
+			}
+			buf.WriteString(rec)
+		}
+
+		// Write the extended header file.
+		var name string
+		var flag byte
+		if isGlobal {
+			name = realName
+			if name == "" {
+				name = "GlobalHead.0.0"
+			}
+			flag = TypeXGlobalHeader
+		} else {
+			dir, file := path.Split(realName)
+			name = path.Join(dir, "PaxHeaders.0", file)
+			flag = TypeXHeader
+		}
+		data := buf.String()
+		if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {
+			return err // Global headers return here
 		}
 	}
 
-	if len(paxHeaders) > 0 {
-		if !allowPax {
-			return errInvalidHeader
+	// Pack the main header.
+	var f formatter // Ignore errors since they are expected
+	fmtStr := func(b []byte, s string) { f.formatString(b, toASCII(s)) }
+	blk := tw.templateV7Plus(hdr, fmtStr, f.formatOctal)
+	blk.SetFormat(FormatPAX)
+	if err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil {
+		return err
+	}
+
+	// TODO(dsnet): Re-enable this when adding sparse support.
+	// See https://golang.org/issue/22735
+	/*
+		// Write the sparse map and setup the sparse writer if necessary.
+		if len(spd) > 0 {
+			// Use tw.curr since the sparse map is accounted for in hdr.Size.
+			if _, err := tw.curr.Write(spb); err != nil {
+				return err
+			}
+			tw.curr = &sparseFileWriter{tw.curr, spd, 0}
 		}
-		if err := tw.writePAXHeader(hdr, paxHeaders); err != nil {
+	*/
+	return nil
+}
+
+func (tw *Writer) writeGNUHeader(hdr *Header) error {
+	// Use long-link files if Name or Linkname exceeds the field size.
+	const longName = "././@LongLink"
+	if len(hdr.Name) > nameSize {
+		data := hdr.Name + "\x00"
+		if err := tw.writeRawFile(longName, data, TypeGNULongName, FormatGNU); err != nil {
 			return err
 		}
 	}
-	tw.nb = hdr.Size
-	tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize
+	if len(hdr.Linkname) > nameSize {
+		data := hdr.Linkname + "\x00"
+		if err := tw.writeRawFile(longName, data, TypeGNULongLink, FormatGNU); err != nil {
+			return err
+		}
+	}
 
-	_, tw.err = tw.w.Write(header[:])
-	return tw.err
+	// Pack the main header.
+	var f formatter // Ignore errors since they are expected
+	var spd sparseDatas
+	var spb []byte
+	blk := tw.templateV7Plus(hdr, f.formatString, f.formatNumeric)
+	if !hdr.AccessTime.IsZero() {
+		f.formatNumeric(blk.GNU().AccessTime(), hdr.AccessTime.Unix())
+	}
+	if !hdr.ChangeTime.IsZero() {
+		f.formatNumeric(blk.GNU().ChangeTime(), hdr.ChangeTime.Unix())
+	}
+	// TODO(dsnet): Re-enable this when adding sparse support.
+	// See https://golang.org/issue/22735
+	/*
+		if hdr.Typeflag == TypeGNUSparse {
+			sph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map
+			sph = alignSparseEntries(sph, hdr.Size)
+			spd = invertSparseEntries(sph, hdr.Size)
+
+			// Format the sparse map.
+			formatSPD := func(sp sparseDatas, sa sparseArray) sparseDatas {
+				for i := 0; len(sp) > 0 && i < sa.MaxEntries(); i++ {
+					f.formatNumeric(sa.Entry(i).Offset(), sp[0].Offset)
+					f.formatNumeric(sa.Entry(i).Length(), sp[0].Length)
+					sp = sp[1:]
+				}
+				if len(sp) > 0 {
+					sa.IsExtended()[0] = 1
+				}
+				return sp
+			}
+			sp2 := formatSPD(spd, blk.GNU().Sparse())
+			for len(sp2) > 0 {
+				var spHdr block
+				sp2 = formatSPD(sp2, spHdr.Sparse())
+				spb = append(spb, spHdr[:]...)
+			}
+
+			// Update size fields in the header block.
+			realSize := hdr.Size
+			hdr.Size = 0 // Encoded size; does not account for encoded sparse map
+			for _, s := range spd {
+				hdr.Size += s.Length
+			}
+			copy(blk.V7().Size(), zeroBlock[:]) // Reset field
+			f.formatNumeric(blk.V7().Size(), hdr.Size)
+			f.formatNumeric(blk.GNU().RealSize(), realSize)
+		}
+	*/
+	blk.SetFormat(FormatGNU)
+	if err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil {
+		return err
+	}
+
+	// Write the extended sparse map and setup the sparse writer if necessary.
+	if len(spd) > 0 {
+		// Use tw.w since the sparse map is not accounted for in hdr.Size.
+		if _, err := tw.w.Write(spb); err != nil {
+			return err
+		}
+		tw.curr = &sparseFileWriter{tw.curr, spd, 0}
+	}
+	return nil
+}
+
+type (
+	stringFormatter func([]byte, string)
+	numberFormatter func([]byte, int64)
+)
+
+// templateV7Plus fills out the V7 fields of a block using values from hdr.
+// It also fills out fields (uname, gname, devmajor, devminor) that are
+// shared in the USTAR, PAX, and GNU formats using the provided formatters.
+//
+// The block returned is only valid until the next call to
+// templateV7Plus or writeRawFile.
+func (tw *Writer) templateV7Plus(hdr *Header, fmtStr stringFormatter, fmtNum numberFormatter) *block {
+	tw.blk.Reset()
+
+	modTime := hdr.ModTime
+	if modTime.IsZero() {
+		modTime = time.Unix(0, 0)
+	}
+
+	v7 := tw.blk.V7()
+	v7.TypeFlag()[0] = hdr.Typeflag
+	fmtStr(v7.Name(), hdr.Name)
+	fmtStr(v7.LinkName(), hdr.Linkname)
+	fmtNum(v7.Mode(), hdr.Mode)
+	fmtNum(v7.UID(), int64(hdr.Uid))
+	fmtNum(v7.GID(), int64(hdr.Gid))
+	fmtNum(v7.Size(), hdr.Size)
+	fmtNum(v7.ModTime(), modTime.Unix())
+
+	ustar := tw.blk.USTAR()
+	fmtStr(ustar.UserName(), hdr.Uname)
+	fmtStr(ustar.GroupName(), hdr.Gname)
+	fmtNum(ustar.DevMajor(), hdr.Devmajor)
+	fmtNum(ustar.DevMinor(), hdr.Devminor)
+
+	return &tw.blk
+}
+
+// writeRawFile writes a minimal file with the given name and flag type.
+// It uses format to encode the header format and will write data as the body.
+// It uses default values for all of the other fields (as BSD and GNU tar does).
+func (tw *Writer) writeRawFile(name, data string, flag byte, format Format) error {
+	tw.blk.Reset()
+
+	// Best effort for the filename.
+	name = toASCII(name)
+	if len(name) > nameSize {
+		name = name[:nameSize]
+	}
+	name = strings.TrimRight(name, "/")
+
+	var f formatter
+	v7 := tw.blk.V7()
+	v7.TypeFlag()[0] = flag
+	f.formatString(v7.Name(), name)
+	f.formatOctal(v7.Mode(), 0)
+	f.formatOctal(v7.UID(), 0)
+	f.formatOctal(v7.GID(), 0)
+	f.formatOctal(v7.Size(), int64(len(data))) // Must be < 8GiB
+	f.formatOctal(v7.ModTime(), 0)
+	tw.blk.SetFormat(format)
+	if f.err != nil {
+		return f.err // Only occurs if size condition is violated
+	}
+
+	// Write the header and data.
+	if err := tw.writeRawHeader(&tw.blk, int64(len(data)), flag); err != nil {
+		return err
+	}
+	_, err := io.WriteString(tw, data)
+	return err
+}
+
+// writeRawHeader writes the value of blk, regardless of its value.
+// It sets up the Writer such that it can accept a file of the given size.
+// If the flag is a special header-only flag, then the size is treated as zero.
+func (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error {
+	if err := tw.Flush(); err != nil {
+		return err
+	}
+	if _, err := tw.w.Write(blk[:]); err != nil {
+		return err
+	}
+	if isHeaderOnlyType(flag) {
+		size = 0
+	}
+	tw.curr = &regFileWriter{tw.w, size}
+	tw.pad = blockPadding(size)
+	return nil
 }
 
 // splitUSTARPath splits a path according to USTAR prefix and suffix rules.
@@ -276,95 +412,233 @@
 	return name[:i], name[i+1:], true
 }
 
-// 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. However, this results in differing outputs
-	// for identical inputs. As such, the constant 0 is now used instead.
-	// golang.org/issue/12358
-	dir, file := path.Split(hdr.Name)
-	fullName := path.Join(dir, "PaxHeaders.0", file)
-
-	ascii := toASCII(fullName)
-	if len(ascii) > nameSize {
-		ascii = ascii[:nameSize]
-	}
-	ext.Name = ascii
-	// Construct the body
-	var buf bytes.Buffer
-
-	// Keys are sorted before writing to body to allow deterministic output.
-	keys := make([]string, 0, len(paxHeaders))
-	for k := range paxHeaders {
-		keys = append(keys, k)
-	}
-	sort.Strings(keys)
-
-	for _, k := range keys {
-		fmt.Fprint(&buf, formatPAXRecord(k, paxHeaders[k]))
-	}
-
-	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
-}
-
-// Write writes to the current entry in the tar archive.
+// Write writes to the current file 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 = ErrWriteAfterClose
-		return
+// Header.Size bytes are written after WriteHeader.
+//
+// Calling Write on special types like TypeLink, TypeSymlink, TypeChar,
+// TypeBlock, TypeDir, and TypeFifo returns (0, ErrWriteTooLong) regardless
+// of what the Header.Size claims.
+func (tw *Writer) Write(b []byte) (int, error) {
+	if tw.err != nil {
+		return 0, tw.err
 	}
-	overwrite := false
-	if int64(len(b)) > tw.nb {
-		b = b[0:tw.nb]
-		overwrite = true
+	n, err := tw.curr.Write(b)
+	if err != nil && err != ErrWriteTooLong {
+		tw.err = err
 	}
-	n, err = tw.w.Write(b)
-	tw.nb -= int64(n)
-	if err == nil && overwrite {
-		err = ErrWriteTooLong
-		return
-	}
-	tw.err = err
-	return
+	return n, err
 }
 
-// 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
+// readFrom populates the content of the current file by reading from r.
+// The bytes read must match the number of remaining bytes in the current file.
+//
+// If the current file is sparse and r is an io.ReadSeeker,
+// then readFrom uses Seek to skip past holes defined in Header.SparseHoles,
+// assuming that skipped regions are all NULs.
+// This always reads the last byte to ensure r is the right size.
+//
+// TODO(dsnet): Re-export this when adding sparse file support.
+// See https://golang.org/issue/22735
+func (tw *Writer) readFrom(r io.Reader) (int64, error) {
+	if tw.err != nil {
+		return 0, tw.err
 	}
-	tw.Flush()
-	tw.closed = true
+	n, err := tw.curr.ReadFrom(r)
+	if err != nil && err != ErrWriteTooLong {
+		tw.err = err
+	}
+	return n, err
+}
+
+// Close closes the tar archive by flushing the padding, and writing the footer.
+// If the current file (from a prior call to WriteHeader) is not fully written,
+// then this returns an error.
+func (tw *Writer) Close() error {
+	if tw.err == ErrWriteAfterClose {
+		return nil
+	}
 	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
+	// Trailer: two zero blocks.
+	err := tw.Flush()
+	for i := 0; i < 2 && err == nil; i++ {
+		_, err = tw.w.Write(zeroBlock[:])
+	}
+
+	// Ensure all future actions are invalid.
+	tw.err = ErrWriteAfterClose
+	return err // Report IO errors
+}
+
+// regFileWriter is a fileWriter for writing data to a regular file entry.
+type regFileWriter struct {
+	w  io.Writer // Underlying Writer
+	nb int64     // Number of remaining bytes to write
+}
+
+func (fw *regFileWriter) Write(b []byte) (n int, err error) {
+	overwrite := int64(len(b)) > fw.nb
+	if overwrite {
+		b = b[:fw.nb]
+	}
+	if len(b) > 0 {
+		n, err = fw.w.Write(b)
+		fw.nb -= int64(n)
+	}
+	switch {
+	case err != nil:
+		return n, err
+	case overwrite:
+		return n, ErrWriteTooLong
+	default:
+		return n, nil
+	}
+}
+
+func (fw *regFileWriter) ReadFrom(r io.Reader) (int64, error) {
+	return io.Copy(struct{ io.Writer }{fw}, r)
+}
+
+func (fw regFileWriter) LogicalRemaining() int64 {
+	return fw.nb
+}
+func (fw regFileWriter) PhysicalRemaining() int64 {
+	return fw.nb
+}
+
+// sparseFileWriter is a fileWriter for writing data to a sparse file entry.
+type sparseFileWriter struct {
+	fw  fileWriter  // Underlying fileWriter
+	sp  sparseDatas // Normalized list of data fragments
+	pos int64       // Current position in sparse file
+}
+
+func (sw *sparseFileWriter) Write(b []byte) (n int, err error) {
+	overwrite := int64(len(b)) > sw.LogicalRemaining()
+	if overwrite {
+		b = b[:sw.LogicalRemaining()]
+	}
+
+	b0 := b
+	endPos := sw.pos + int64(len(b))
+	for endPos > sw.pos && err == nil {
+		var nf int // Bytes written in fragment
+		dataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset()
+		if sw.pos < dataStart { // In a hole fragment
+			bf := b[:min(int64(len(b)), dataStart-sw.pos)]
+			nf, err = zeroWriter{}.Write(bf)
+		} else { // In a data fragment
+			bf := b[:min(int64(len(b)), dataEnd-sw.pos)]
+			nf, err = sw.fw.Write(bf)
+		}
+		b = b[nf:]
+		sw.pos += int64(nf)
+		if sw.pos >= dataEnd && len(sw.sp) > 1 {
+			sw.sp = sw.sp[1:] // Ensure last fragment always remains
 		}
 	}
-	return tw.err
+
+	n = len(b0) - len(b)
+	switch {
+	case err == ErrWriteTooLong:
+		return n, errMissData // Not possible; implies bug in validation logic
+	case err != nil:
+		return n, err
+	case sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0:
+		return n, errUnrefData // Not possible; implies bug in validation logic
+	case overwrite:
+		return n, ErrWriteTooLong
+	default:
+		return n, nil
+	}
+}
+
+func (sw *sparseFileWriter) ReadFrom(r io.Reader) (n int64, err error) {
+	rs, ok := r.(io.ReadSeeker)
+	if ok {
+		if _, err := rs.Seek(0, io.SeekCurrent); err != nil {
+			ok = false // Not all io.Seeker can really seek
+		}
+	}
+	if !ok {
+		return io.Copy(struct{ io.Writer }{sw}, r)
+	}
+
+	var readLastByte bool
+	pos0 := sw.pos
+	for sw.LogicalRemaining() > 0 && !readLastByte && err == nil {
+		var nf int64 // Size of fragment
+		dataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset()
+		if sw.pos < dataStart { // In a hole fragment
+			nf = dataStart - sw.pos
+			if sw.PhysicalRemaining() == 0 {
+				readLastByte = true
+				nf--
+			}
+			_, err = rs.Seek(nf, io.SeekCurrent)
+		} else { // In a data fragment
+			nf = dataEnd - sw.pos
+			nf, err = io.CopyN(sw.fw, rs, nf)
+		}
+		sw.pos += nf
+		if sw.pos >= dataEnd && len(sw.sp) > 1 {
+			sw.sp = sw.sp[1:] // Ensure last fragment always remains
+		}
+	}
+
+	// If the last fragment is a hole, then seek to 1-byte before EOF, and
+	// read a single byte to ensure the file is the right size.
+	if readLastByte && err == nil {
+		_, err = mustReadFull(rs, []byte{0})
+		sw.pos++
+	}
+
+	n = sw.pos - pos0
+	switch {
+	case err == io.EOF:
+		return n, io.ErrUnexpectedEOF
+	case err == ErrWriteTooLong:
+		return n, errMissData // Not possible; implies bug in validation logic
+	case err != nil:
+		return n, err
+	case sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0:
+		return n, errUnrefData // Not possible; implies bug in validation logic
+	default:
+		return n, ensureEOF(rs)
+	}
+}
+
+func (sw sparseFileWriter) LogicalRemaining() int64 {
+	return sw.sp[len(sw.sp)-1].endOffset() - sw.pos
+}
+func (sw sparseFileWriter) PhysicalRemaining() int64 {
+	return sw.fw.PhysicalRemaining()
+}
+
+// zeroWriter may only be written with NULs, otherwise it returns errWriteHole.
+type zeroWriter struct{}
+
+func (zeroWriter) Write(b []byte) (int, error) {
+	for i, c := range b {
+		if c != 0 {
+			return i, errWriteHole
+		}
+	}
+	return len(b), nil
+}
+
+// ensureEOF checks whether r is at EOF, reporting ErrWriteTooLong if not so.
+func ensureEOF(r io.Reader) error {
+	n, err := tryReadFull(r, []byte{0})
+	switch {
+	case n > 0:
+		return ErrWriteTooLong
+	case err == io.EOF:
+		return nil
+	default:
+		return err
+	}
 }
diff --git a/src/archive/tar/writer_test.go b/src/archive/tar/writer_test.go
index d88b8f4..24e8da2 100644
--- a/src/archive/tar/writer_test.go
+++ b/src/archive/tar/writer_test.go
@@ -6,10 +6,12 @@
 
 import (
 	"bytes"
-	"fmt"
+	"encoding/hex"
+	"errors"
 	"io"
 	"io/ioutil"
 	"os"
+	"path"
 	"reflect"
 	"sort"
 	"strings"
@@ -18,120 +20,127 @@
 	"time"
 )
 
-// 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)
+func bytediff(a, b []byte) string {
+	const (
+		uniqueA  = "-  "
+		uniqueB  = "+  "
+		identity = "   "
+	)
+	var ss []string
+	sa := strings.Split(strings.TrimSpace(hex.Dump(a)), "\n")
+	sb := strings.Split(strings.TrimSpace(hex.Dump(b)), "\n")
+	for len(sa) > 0 && len(sb) > 0 {
+		if sa[0] == sb[0] {
+			ss = append(ss, identity+sa[0])
+		} else {
+			ss = append(ss, uniqueA+sa[0])
+			ss = append(ss, uniqueB+sb[0])
 		}
+		sa, sb = sa[1:], sb[1:]
 	}
-	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:]
+	for len(sa) > 0 {
+		ss = append(ss, uniqueA+sa[0])
+		sa = sa[1:]
 	}
-	return s
+	for len(sb) > 0 {
+		ss = append(ss, uniqueB+sb[0])
+		sb = sb[1:]
+	}
+	return strings.Join(ss, "\n")
 }
 
 func TestWriter(t *testing.T) {
-	type entry struct {
-		header   *Header
-		contents string
-	}
+	type (
+		testHeader struct { // WriteHeader(hdr) == wantErr
+			hdr     Header
+			wantErr error
+		}
+		testWrite struct { // Write(str) == (wantCnt, wantErr)
+			str     string
+			wantCnt int
+			wantErr error
+		}
+		testReadFrom struct { // ReadFrom(testFile{ops}) == (wantCnt, wantErr)
+			ops     fileOps
+			wantCnt int64
+			wantErr error
+		}
+		testClose struct { // Close() == wantErr
+			wantErr error
+		}
+		testFnc interface{} // testHeader | testWrite | testReadFrom | testClose
+	)
 
 	vectors := []struct {
-		file    string // filename of expected output
-		entries []*entry
+		file  string // Optional filename of expected output
+		tests []testFnc
 	}{{
 		// 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: []*entry{{
-			header: &Header{
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
 				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{
+				ModTime:  time.Unix(1246508266, 0),
+			}, nil},
+			testWrite{"Kilts", 5, nil},
+
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "small2.txt",
+				Size:     11,
+				Mode:     0640,
+				Uid:      73025,
+				Uname:    "dsymonds",
+				Gname:    "eng",
+				Gid:      5000,
+				ModTime:  time.Unix(1245217492, 0),
+			}, nil},
+			testWrite{"Google.com\n", 11, nil},
+
+			testHeader{Header{
+				Typeflag: TypeSymlink,
 				Name:     "link.txt",
+				Linkname: "small.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
-		}},
+				ModTime:  time.Unix(1314603082, 0),
+			}, nil},
+			testWrite{"", 0, nil},
+
+			testClose{nil},
+		},
 	}, {
 		// 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: []*entry{{
-			header: &Header{
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
 				Name:     "tmp/16gig.txt",
+				Size:     16 << 30,
 				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),
-		}},
+				ModTime:  time.Unix(1254699560, 0),
+				Format:   FormatGNU,
+			}, nil},
+		},
 	}, {
 		// This truncated file was produced using this library.
 		// It was verified to work with GNU tar 1.27.1 and BSD tar 3.1.2.
@@ -141,117 +150,377 @@
 		//
 		// This file is in PAX format.
 		file: "testdata/writer-big-long.tar",
-		entries: []*entry{{
-			header: &Header{
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
 				Name:     strings.Repeat("longname/", 15) + "16gig.txt",
+				Size:     16 << 30,
 				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),
-		}},
+				ModTime:  time.Unix(1399583047, 0),
+			}, nil},
+		},
 	}, {
-		// TODO(dsnet): The Writer output should match the following file.
-		// To fix an issue (see https://golang.org/issue/12594), we disabled
-		// prefix support, which alters the generated output.
-		/*
-			// This file was produced using gnu tar 1.17
-			// gnutar  -b 4 --format=ustar (longname/)*15 + file.txt
-			file: "testdata/ustar.tar"
-		*/
-		file: "testdata/ustar.issue12594.tar", // This is a valid tar file, but not expected
-		entries: []*entry{{
-			header: &Header{
+		// This file was produced using GNU tar v1.17.
+		//	gnutar -b 4 --format=ustar (longname/)*15 + file.txt
+		file: "testdata/ustar.tar",
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
 				Name:     strings.Repeat("longname/", 15) + "file.txt",
+				Size:     6,
 				Mode:     0644,
-				Uid:      0765,
-				Gid:      024,
-				Size:     06,
-				ModTime:  time.Unix(1360135598, 0),
-				Typeflag: '0',
+				Uid:      501,
+				Gid:      20,
 				Uname:    "shane",
 				Gname:    "staff",
-			},
-			contents: "hello\n",
-		}},
+				ModTime:  time.Unix(1360135598, 0),
+			}, nil},
+			testWrite{"hello\n", 6, nil},
+			testClose{nil},
+		},
 	}, {
-		// This file was produced using gnu tar 1.26
-		// echo "Slartibartfast" > file.txt
-		// ln file.txt hard.txt
-		// tar -b 1 --format=ustar -c -f hardlink.tar file.txt hard.txt
+		// This file was produced using GNU tar v1.26:
+		//	echo "Slartibartfast" > file.txt
+		//	ln file.txt hard.txt
+		//	tar -b 1 --format=ustar -c -f hardlink.tar file.txt hard.txt
 		file: "testdata/hardlink.tar",
-		entries: []*entry{{
-			header: &Header{
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
 				Name:     "file.txt",
-				Mode:     0644,
-				Uid:      1000,
-				Gid:      100,
 				Size:     15,
-				ModTime:  time.Unix(1425484303, 0),
-				Typeflag: '0',
-				Uname:    "vbatts",
-				Gname:    "users",
-			},
-			contents: "Slartibartfast\n",
-		}, {
-			header: &Header{
-				Name:     "hard.txt",
 				Mode:     0644,
 				Uid:      1000,
 				Gid:      100,
-				Size:     0,
-				ModTime:  time.Unix(1425484303, 0),
-				Typeflag: '1',
-				Linkname: "file.txt",
 				Uname:    "vbatts",
 				Gname:    "users",
-			},
-			// no contents
-		}},
+				ModTime:  time.Unix(1425484303, 0),
+			}, nil},
+			testWrite{"Slartibartfast\n", 15, nil},
+
+			testHeader{Header{
+				Typeflag: TypeLink,
+				Name:     "hard.txt",
+				Linkname: "file.txt",
+				Mode:     0644,
+				Uid:      1000,
+				Gid:      100,
+				Uname:    "vbatts",
+				Gname:    "users",
+				ModTime:  time.Unix(1425484303, 0),
+			}, nil},
+			testWrite{"", 0, nil},
+
+			testClose{nil},
+		},
+	}, {
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "bad-null.txt",
+				Xattrs:   map[string]string{"null\x00null\x00": "fizzbuzz"},
+			}, headerError{}},
+		},
+	}, {
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "null\x00.txt",
+			}, headerError{}},
+		},
+	}, {
+		file: "testdata/pax-records.tar",
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "file",
+				Uname:    strings.Repeat("long", 10),
+				PAXRecords: map[string]string{
+					"path":           "FILE", // Should be ignored
+					"GNU.sparse.map": "0,0",  // Should be ignored
+					"comment":        "Hello, 世界",
+					"GOLANG.pkg":     "tar",
+				},
+			}, nil},
+			testClose{nil},
+		},
+	}, {
+		// Craft a theoretically valid PAX archive with global headers.
+		// The GNU and BSD tar tools do not parse these the same way.
+		//
+		// BSD tar v3.1.2 parses and ignores all global headers;
+		// the behavior is verified by researching the source code.
+		//
+		//	$ bsdtar -tvf pax-global-records.tar
+		//	----------  0 0      0           0 Dec 31  1969 file1
+		//	----------  0 0      0           0 Dec 31  1969 file2
+		//	----------  0 0      0           0 Dec 31  1969 file3
+		//	----------  0 0      0           0 May 13  2014 file4
+		//
+		// GNU tar v1.27.1 applies global headers to subsequent records,
+		// but does not do the following properly:
+		//	* It does not treat an empty record as deletion.
+		//	* It does not use subsequent global headers to update previous ones.
+		//
+		//	$ gnutar -tvf pax-global-records.tar
+		//	---------- 0/0               0 2017-07-13 19:40 global1
+		//	---------- 0/0               0 2017-07-13 19:40 file2
+		//	gnutar: Substituting `.' for empty member name
+		//	---------- 0/0               0 1969-12-31 16:00
+		//	gnutar: Substituting `.' for empty member name
+		//	---------- 0/0               0 2014-05-13 09:53
+		//
+		// According to the PAX specification, this should have been the result:
+		//	---------- 0/0               0 2017-07-13 19:40 global1
+		//	---------- 0/0               0 2017-07-13 19:40 file2
+		//	---------- 0/0               0 2017-07-13 19:40 file3
+		//	---------- 0/0               0 2014-05-13 09:53 file4
+		file: "testdata/pax-global-records.tar",
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag:   TypeXGlobalHeader,
+				PAXRecords: map[string]string{"path": "global1", "mtime": "1500000000.0"},
+			}, nil},
+			testHeader{Header{
+				Typeflag: TypeReg, Name: "file1",
+			}, nil},
+			testHeader{Header{
+				Typeflag:   TypeReg,
+				Name:       "file2",
+				PAXRecords: map[string]string{"path": "file2"},
+			}, nil},
+			testHeader{Header{
+				Typeflag:   TypeXGlobalHeader,
+				PAXRecords: map[string]string{"path": ""}, // Should delete "path", but keep "mtime"
+			}, nil},
+			testHeader{Header{
+				Typeflag: TypeReg, Name: "file3",
+			}, nil},
+			testHeader{Header{
+				Typeflag:   TypeReg,
+				Name:       "file4",
+				ModTime:    time.Unix(1400000000, 0),
+				PAXRecords: map[string]string{"mtime": "1400000000"},
+			}, nil},
+			testClose{nil},
+		},
+	}, {
+		file: "testdata/gnu-utf8.tar",
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹",
+				Mode:     0644,
+				Uid:      1000, Gid: 1000,
+				Uname:   "☺",
+				Gname:   "⚹",
+				ModTime: time.Unix(0, 0),
+				Format:  FormatGNU,
+			}, nil},
+			testClose{nil},
+		},
+	}, {
+		file: "testdata/gnu-not-utf8.tar",
+		tests: []testFnc{
+			testHeader{Header{
+				Typeflag: TypeReg,
+				Name:     "hi\x80\x81\x82\x83bye",
+				Mode:     0644,
+				Uid:      1000,
+				Gid:      1000,
+				Uname:    "rawr",
+				Gname:    "dsnet",
+				ModTime:  time.Unix(0, 0),
+				Format:   FormatGNU,
+			}, nil},
+			testClose{nil},
+		},
+		// TODO(dsnet): Re-enable this test when adding sparse support.
+		// See https://golang.org/issue/22735
+		/*
+			}, {
+				file: "testdata/gnu-nil-sparse-data.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag:    TypeGNUSparse,
+						Name:        "sparse.db",
+						Size:        1000,
+						SparseHoles: []sparseEntry{{Offset: 1000, Length: 0}},
+					}, nil},
+					testWrite{strings.Repeat("0123456789", 100), 1000, nil},
+					testClose{},
+				},
+			}, {
+				file: "testdata/gnu-nil-sparse-hole.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag:    TypeGNUSparse,
+						Name:        "sparse.db",
+						Size:        1000,
+						SparseHoles: []sparseEntry{{Offset: 0, Length: 1000}},
+					}, nil},
+					testWrite{strings.Repeat("\x00", 1000), 1000, nil},
+					testClose{},
+				},
+			}, {
+				file: "testdata/pax-nil-sparse-data.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag:    TypeReg,
+						Name:        "sparse.db",
+						Size:        1000,
+						SparseHoles: []sparseEntry{{Offset: 1000, Length: 0}},
+					}, nil},
+					testWrite{strings.Repeat("0123456789", 100), 1000, nil},
+					testClose{},
+				},
+			}, {
+				file: "testdata/pax-nil-sparse-hole.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag:    TypeReg,
+						Name:        "sparse.db",
+						Size:        1000,
+						SparseHoles: []sparseEntry{{Offset: 0, Length: 1000}},
+					}, nil},
+					testWrite{strings.Repeat("\x00", 1000), 1000, nil},
+					testClose{},
+				},
+			}, {
+				file: "testdata/gnu-sparse-big.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag: TypeGNUSparse,
+						Name:     "gnu-sparse",
+						Size:     6e10,
+						SparseHoles: []sparseEntry{
+							{Offset: 0e10, Length: 1e10 - 100},
+							{Offset: 1e10, Length: 1e10 - 100},
+							{Offset: 2e10, Length: 1e10 - 100},
+							{Offset: 3e10, Length: 1e10 - 100},
+							{Offset: 4e10, Length: 1e10 - 100},
+							{Offset: 5e10, Length: 1e10 - 100},
+						},
+					}, nil},
+					testReadFrom{fileOps{
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+					}, 6e10, nil},
+					testClose{nil},
+				},
+			}, {
+				file: "testdata/pax-sparse-big.tar",
+				tests: []testFnc{
+					testHeader{Header{
+						Typeflag: TypeReg,
+						Name:     "pax-sparse",
+						Size:     6e10,
+						SparseHoles: []sparseEntry{
+							{Offset: 0e10, Length: 1e10 - 100},
+							{Offset: 1e10, Length: 1e10 - 100},
+							{Offset: 2e10, Length: 1e10 - 100},
+							{Offset: 3e10, Length: 1e10 - 100},
+							{Offset: 4e10, Length: 1e10 - 100},
+							{Offset: 5e10, Length: 1e10 - 100},
+						},
+					}, nil},
+					testReadFrom{fileOps{
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+						int64(1e10 - blockSize),
+						strings.Repeat("\x00", blockSize-100) + strings.Repeat("0123456789", 10),
+					}, 6e10, nil},
+					testClose{nil},
+				},
+		*/
+	}, {
+		file: "testdata/trailing-slash.tar",
+		tests: []testFnc{
+			testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
+			testClose{nil},
+		},
 	}}
 
-testLoop:
-	for i, v := range vectors {
-		expected, err := ioutil.ReadFile(v.file)
-		if err != nil {
-			t.Errorf("test %d: Unexpected error: %v", i, err)
-			continue
+	equalError := func(x, y error) bool {
+		_, ok1 := x.(headerError)
+		_, ok2 := y.(headerError)
+		if ok1 || ok2 {
+			return ok1 && ok2
 		}
+		return x == y
+	}
+	for _, v := range vectors {
+		t.Run(path.Base(v.file), func(t *testing.T) {
+			const maxSize = 10 << 10 // 10KiB
+			buf := new(bytes.Buffer)
+			tw := NewWriter(iotest.TruncateWriter(buf, maxSize))
 
-		buf := new(bytes.Buffer)
-		tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
-		big := false
-		for j, entry := range v.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
+			for i, tf := range v.tests {
+				switch tf := tf.(type) {
+				case testHeader:
+					err := tw.WriteHeader(&tf.hdr)
+					if !equalError(err, tf.wantErr) {
+						t.Fatalf("test %d, WriteHeader() = %v, want %v", i, err, tf.wantErr)
+					}
+				case testWrite:
+					got, err := tw.Write([]byte(tf.str))
+					if got != tf.wantCnt || !equalError(err, tf.wantErr) {
+						t.Fatalf("test %d, Write() = (%d, %v), want (%d, %v)", i, got, err, tf.wantCnt, tf.wantErr)
+					}
+				case testReadFrom:
+					f := &testFile{ops: tf.ops}
+					got, err := tw.readFrom(f)
+					if _, ok := err.(testError); ok {
+						t.Errorf("test %d, ReadFrom(): %v", i, err)
+					} else if got != tf.wantCnt || !equalError(err, tf.wantErr) {
+						t.Errorf("test %d, ReadFrom() = (%d, %v), want (%d, %v)", i, got, err, tf.wantCnt, tf.wantErr)
+					}
+					if len(f.ops) > 0 {
+						t.Errorf("test %d, expected %d more operations", i, len(f.ops))
+					}
+				case testClose:
+					err := tw.Close()
+					if !equalError(err, tf.wantErr) {
+						t.Fatalf("test %d, Close() = %v, want %v", i, err, tf.wantErr)
+					}
+				default:
+					t.Fatalf("test %d, unknown test operation: %T", i, tf)
+				}
 			}
-			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
-		}
+			if v.file != "" {
+				want, err := ioutil.ReadFile(v.file)
+				if err != nil {
+					t.Fatalf("ReadFile() = %v, want nil", err)
+				}
+				got := buf.Bytes()
+				if !bytes.Equal(want, got) {
+					t.Fatalf("incorrect result: (-got +want)\n%v", bytediff(got, want))
+				}
+			}
+		})
 	}
 }
 
@@ -546,21 +815,104 @@
 	}
 }
 
-func TestWriteAfterClose(t *testing.T) {
-	var buffer bytes.Buffer
-	tw := NewWriter(&buffer)
+// failOnceWriter fails exactly once and then always reports success.
+type failOnceWriter bool
 
-	hdr := &Header{
-		Name: "small.txt",
-		Size: 5,
+func (w *failOnceWriter) Write(b []byte) (int, error) {
+	if !*w {
+		return 0, io.ErrShortWrite
 	}
-	if err := tw.WriteHeader(hdr); err != nil {
-		t.Fatalf("Failed to write header: %s", err)
-	}
-	tw.Close()
-	if _, err := tw.Write([]byte("Kilts")); err != ErrWriteAfterClose {
-		t.Fatalf("Write: got %v; want ErrWriteAfterClose", err)
-	}
+	*w = true
+	return len(b), nil
+}
+
+func TestWriterErrors(t *testing.T) {
+	t.Run("HeaderOnly", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		hdr := &Header{Name: "dir/", Typeflag: TypeDir}
+		if err := tw.WriteHeader(hdr); err != nil {
+			t.Fatalf("WriteHeader() = %v, want nil", err)
+		}
+		if _, err := tw.Write([]byte{0x00}); err != ErrWriteTooLong {
+			t.Fatalf("Write() = %v, want %v", err, ErrWriteTooLong)
+		}
+	})
+
+	t.Run("NegativeSize", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		hdr := &Header{Name: "small.txt", Size: -1}
+		if err := tw.WriteHeader(hdr); err == nil {
+			t.Fatalf("WriteHeader() = nil, want non-nil error")
+		}
+	})
+
+	t.Run("BeforeHeader", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		if _, err := tw.Write([]byte("Kilts")); err != ErrWriteTooLong {
+			t.Fatalf("Write() = %v, want %v", err, ErrWriteTooLong)
+		}
+	})
+
+	t.Run("AfterClose", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		hdr := &Header{Name: "small.txt"}
+		if err := tw.WriteHeader(hdr); err != nil {
+			t.Fatalf("WriteHeader() = %v, want nil", err)
+		}
+		if err := tw.Close(); err != nil {
+			t.Fatalf("Close() = %v, want nil", err)
+		}
+		if _, err := tw.Write([]byte("Kilts")); err != ErrWriteAfterClose {
+			t.Fatalf("Write() = %v, want %v", err, ErrWriteAfterClose)
+		}
+		if err := tw.Flush(); err != ErrWriteAfterClose {
+			t.Fatalf("Flush() = %v, want %v", err, ErrWriteAfterClose)
+		}
+		if err := tw.Close(); err != nil {
+			t.Fatalf("Close() = %v, want nil", err)
+		}
+	})
+
+	t.Run("PrematureFlush", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		hdr := &Header{Name: "small.txt", Size: 5}
+		if err := tw.WriteHeader(hdr); err != nil {
+			t.Fatalf("WriteHeader() = %v, want nil", err)
+		}
+		if err := tw.Flush(); err == nil {
+			t.Fatalf("Flush() = %v, want non-nil error", err)
+		}
+	})
+
+	t.Run("PrematureClose", func(t *testing.T) {
+		tw := NewWriter(new(bytes.Buffer))
+		hdr := &Header{Name: "small.txt", Size: 5}
+		if err := tw.WriteHeader(hdr); err != nil {
+			t.Fatalf("WriteHeader() = %v, want nil", err)
+		}
+		if err := tw.Close(); err == nil {
+			t.Fatalf("Close() = %v, want non-nil error", err)
+		}
+	})
+
+	t.Run("Persistence", func(t *testing.T) {
+		tw := NewWriter(new(failOnceWriter))
+		if err := tw.WriteHeader(&Header{}); err != io.ErrShortWrite {
+			t.Fatalf("WriteHeader() = %v, want %v", err, io.ErrShortWrite)
+		}
+		if err := tw.WriteHeader(&Header{Name: "small.txt"}); err == nil {
+			t.Errorf("WriteHeader() = got %v, want non-nil error", err)
+		}
+		if _, err := tw.Write(nil); err == nil {
+			t.Errorf("Write() = %v, want non-nil error", err)
+		}
+		if err := tw.Flush(); err == nil {
+			t.Errorf("Flush() = %v, want non-nil error", err)
+		}
+		if err := tw.Close(); err == nil {
+			t.Errorf("Close() = %v, want non-nil error", err)
+		}
+	})
 }
 
 func TestSplitUSTARPath(t *testing.T) {
@@ -631,7 +983,7 @@
 		if i := strings.IndexByte(prefix, 0); i >= 0 {
 			prefix = prefix[:i] // Truncate at the NUL terminator
 		}
-		if blk.GetFormat() == formatGNU && len(prefix) > 0 && strings.HasPrefix(name, prefix) {
+		if blk.GetFormat() == FormatGNU && len(prefix) > 0 && strings.HasPrefix(name, prefix) {
 			t.Errorf("test %d, found prefix in GNU format: %s", i, prefix)
 		}
 
@@ -645,3 +997,306 @@
 		}
 	}
 }
+
+// testNonEmptyWriter wraps an io.Writer and ensures that
+// Write is never called with an empty buffer.
+type testNonEmptyWriter struct{ io.Writer }
+
+func (w testNonEmptyWriter) Write(b []byte) (int, error) {
+	if len(b) == 0 {
+		return 0, errors.New("unexpected empty Write call")
+	}
+	return w.Writer.Write(b)
+}
+
+func TestFileWriter(t *testing.T) {
+	type (
+		testWrite struct { // Write(str) == (wantCnt, wantErr)
+			str     string
+			wantCnt int
+			wantErr error
+		}
+		testReadFrom struct { // ReadFrom(testFile{ops}) == (wantCnt, wantErr)
+			ops     fileOps
+			wantCnt int64
+			wantErr error
+		}
+		testRemaining struct { // LogicalRemaining() == wantLCnt, PhysicalRemaining() == wantPCnt
+			wantLCnt int64
+			wantPCnt int64
+		}
+		testFnc interface{} // testWrite | testReadFrom | testRemaining
+	)
+
+	type (
+		makeReg struct {
+			size    int64
+			wantStr string
+		}
+		makeSparse struct {
+			makeReg makeReg
+			sph     sparseHoles
+			size    int64
+		}
+		fileMaker interface{} // makeReg | makeSparse
+	)
+
+	vectors := []struct {
+		maker fileMaker
+		tests []testFnc
+	}{{
+		maker: makeReg{0, ""},
+		tests: []testFnc{
+			testRemaining{0, 0},
+			testWrite{"", 0, nil},
+			testWrite{"a", 0, ErrWriteTooLong},
+			testReadFrom{fileOps{""}, 0, nil},
+			testReadFrom{fileOps{"a"}, 0, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{1, "a"},
+		tests: []testFnc{
+			testRemaining{1, 1},
+			testWrite{"", 0, nil},
+			testWrite{"a", 1, nil},
+			testWrite{"bcde", 0, ErrWriteTooLong},
+			testWrite{"", 0, nil},
+			testReadFrom{fileOps{""}, 0, nil},
+			testReadFrom{fileOps{"a"}, 0, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{5, "hello"},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testWrite{"hello", 5, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{5, "\x00\x00\x00\x00\x00"},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testReadFrom{fileOps{"\x00\x00\x00\x00\x00"}, 5, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{5, "\x00\x00\x00\x00\x00"},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testReadFrom{fileOps{"\x00\x00\x00\x00\x00extra"}, 5, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{5, "abc\x00\x00"},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testWrite{"abc", 3, nil},
+			testRemaining{2, 2},
+			testReadFrom{fileOps{"\x00\x00"}, 2, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeReg{5, "\x00\x00abc"},
+		tests: []testFnc{
+			testRemaining{5, 5},
+			testWrite{"\x00\x00", 2, nil},
+			testRemaining{3, 3},
+			testWrite{"abc", 3, nil},
+			testReadFrom{fileOps{"z"}, 0, ErrWriteTooLong},
+			testWrite{"z", 0, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testRemaining{8, 5},
+			testWrite{"ab\x00\x00\x00cde", 8, nil},
+			testWrite{"a", 0, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testWrite{"ab\x00\x00\x00cdez", 8, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testWrite{"ab\x00", 3, nil},
+			testRemaining{5, 3},
+			testWrite{"\x00\x00cde", 5, nil},
+			testWrite{"a", 0, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testWrite{"ab", 2, nil},
+			testRemaining{6, 3},
+			testReadFrom{fileOps{int64(3), "cde"}, 6, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testReadFrom{fileOps{"ab", int64(3), "cde"}, 8, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{5, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testReadFrom{fileOps{"ab", int64(3), "cdeX"}, 8, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{4, "abcd"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testReadFrom{fileOps{"ab", int64(3), "cd"}, 7, io.ErrUnexpectedEOF},
+			testRemaining{1, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{4, "abcd"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testReadFrom{fileOps{"ab", int64(3), "cde"}, 7, errMissData},
+			testRemaining{1, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{6, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testReadFrom{fileOps{"ab", int64(3), "cde"}, 8, errUnrefData},
+			testRemaining{0, 1},
+		},
+	}, {
+		maker: makeSparse{makeReg{4, "abcd"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testWrite{"ab", 2, nil},
+			testRemaining{6, 2},
+			testWrite{"\x00\x00\x00", 3, nil},
+			testRemaining{3, 2},
+			testWrite{"cde", 2, errMissData},
+			testRemaining{1, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{6, "abcde"}, sparseHoles{{2, 3}}, 8},
+		tests: []testFnc{
+			testWrite{"ab", 2, nil},
+			testRemaining{6, 4},
+			testWrite{"\x00\x00\x00", 3, nil},
+			testRemaining{3, 4},
+			testWrite{"cde", 3, errUnrefData},
+			testRemaining{0, 1},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testRemaining{7, 3},
+			testWrite{"\x00\x00abc\x00\x00", 7, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testRemaining{7, 3},
+			testReadFrom{fileOps{int64(2), "abc", int64(1), "\x00"}, 7, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, ""}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"abcdefg", 0, errWriteHole},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"\x00\x00abcde", 5, errWriteHole},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"\x00\x00abc\x00\x00z", 7, ErrWriteTooLong},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{3, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"\x00\x00", 2, nil},
+			testRemaining{5, 3},
+			testWrite{"abc", 3, nil},
+			testRemaining{2, 0},
+			testWrite{"\x00\x00", 2, nil},
+			testRemaining{0, 0},
+		},
+	}, {
+		maker: makeSparse{makeReg{2, "ab"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"\x00\x00", 2, nil},
+			testWrite{"abc", 2, errMissData},
+			testWrite{"\x00\x00", 0, errMissData},
+		},
+	}, {
+		maker: makeSparse{makeReg{4, "abc"}, sparseHoles{{0, 2}, {5, 2}}, 7},
+		tests: []testFnc{
+			testWrite{"\x00\x00", 2, nil},
+			testWrite{"abc", 3, nil},
+			testWrite{"\x00\x00", 2, errUnrefData},
+		},
+	}}
+
+	for i, v := range vectors {
+		var wantStr string
+		bb := new(bytes.Buffer)
+		w := testNonEmptyWriter{bb}
+		var fw fileWriter
+		switch maker := v.maker.(type) {
+		case makeReg:
+			fw = &regFileWriter{w, maker.size}
+			wantStr = maker.wantStr
+		case makeSparse:
+			if !validateSparseEntries(maker.sph, maker.size) {
+				t.Fatalf("invalid sparse map: %v", maker.sph)
+			}
+			spd := invertSparseEntries(maker.sph, maker.size)
+			fw = &regFileWriter{w, maker.makeReg.size}
+			fw = &sparseFileWriter{fw, spd, 0}
+			wantStr = maker.makeReg.wantStr
+		default:
+			t.Fatalf("test %d, unknown make operation: %T", i, maker)
+		}
+
+		for j, tf := range v.tests {
+			switch tf := tf.(type) {
+			case testWrite:
+				got, err := fw.Write([]byte(tf.str))
+				if got != tf.wantCnt || err != tf.wantErr {
+					t.Errorf("test %d.%d, Write(%s):\ngot  (%d, %v)\nwant (%d, %v)", i, j, tf.str, got, err, tf.wantCnt, tf.wantErr)
+				}
+			case testReadFrom:
+				f := &testFile{ops: tf.ops}
+				got, err := fw.ReadFrom(f)
+				if _, ok := err.(testError); ok {
+					t.Errorf("test %d.%d, ReadFrom(): %v", i, j, err)
+				} else if got != tf.wantCnt || err != tf.wantErr {
+					t.Errorf("test %d.%d, ReadFrom() = (%d, %v), want (%d, %v)", i, j, got, err, tf.wantCnt, tf.wantErr)
+				}
+				if len(f.ops) > 0 {
+					t.Errorf("test %d.%d, expected %d more operations", i, j, len(f.ops))
+				}
+			case testRemaining:
+				if got := fw.LogicalRemaining(); got != tf.wantLCnt {
+					t.Errorf("test %d.%d, LogicalRemaining() = %d, want %d", i, j, got, tf.wantLCnt)
+				}
+				if got := fw.PhysicalRemaining(); got != tf.wantPCnt {
+					t.Errorf("test %d.%d, PhysicalRemaining() = %d, want %d", i, j, got, tf.wantPCnt)
+				}
+			default:
+				t.Fatalf("test %d.%d, unknown test operation: %T", i, j, tf)
+			}
+		}
+
+		if got := bb.String(); got != wantStr {
+			t.Fatalf("test %d, String() = %q, want %q", i, got, wantStr)
+		}
+	}
+}
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index f6c3ead..1563e74 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -13,6 +13,7 @@
 	"hash/crc32"
 	"io"
 	"os"
+	"time"
 )
 
 var (
@@ -94,7 +95,7 @@
 
 	// 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
+	// a bad one, and then only report an ErrFormat or UnexpectedEOF if
 	// the file count modulo 65536 is incorrect.
 	for {
 		f := &File{zip: z, zipr: r, zipsize: size}
@@ -280,52 +281,128 @@
 	f.Extra = d[filenameLen : filenameLen+extraLen]
 	f.Comment = string(d[filenameLen+extraLen:])
 
+	// Determine the character encoding.
+	utf8Valid1, utf8Require1 := detectUTF8(f.Name)
+	utf8Valid2, utf8Require2 := detectUTF8(f.Comment)
+	switch {
+	case !utf8Valid1 || !utf8Valid2:
+		// Name and Comment definitely not UTF-8.
+		f.NonUTF8 = true
+	case !utf8Require1 && !utf8Require2:
+		// Name and Comment use only single-byte runes that overlap with UTF-8.
+		f.NonUTF8 = false
+	default:
+		// Might be UTF-8, might be some other encoding; preserve existing flag.
+		// Some ZIP writers use UTF-8 encoding without setting the UTF-8 flag.
+		// Since it is impossible to always distinguish valid UTF-8 from some
+		// other encoding (e.g., GBK or Shift-JIS), we trust the flag.
+		f.NonUTF8 = f.Flags&0x800 == 0
+	}
+
 	needUSize := f.UncompressedSize == ^uint32(0)
 	needCSize := f.CompressedSize == ^uint32(0)
 	needHeaderOffset := f.headerOffset == int64(^uint32(0))
 
-	if len(f.Extra) > 0 {
-		// Best effort to find what we need.
-		// Other zip authors might not even follow the basic format,
-		// and we'll just ignore the Extra content in that case.
-		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) {
-				break
-			}
-			if tag == zip64ExtraId {
-				// update directory values from the zip64 extra block.
-				// They should only be consulted if the sizes read earlier
-				// are maxed out.
-				// See golang.org/issue/13367.
-				eb := readBuf(b[:size])
+	// Best effort to find what we need.
+	// Other zip authors might not even follow the basic format,
+	// and we'll just ignore the Extra content in that case.
+	var modified time.Time
+parseExtras:
+	for extra := readBuf(f.Extra); len(extra) >= 4; { // need at least tag and size
+		fieldTag := extra.uint16()
+		fieldSize := int(extra.uint16())
+		if len(extra) < fieldSize {
+			break
+		}
+		fieldBuf := extra.sub(fieldSize)
 
-				if needUSize {
-					needUSize = false
-					if len(eb) < 8 {
-						return ErrFormat
-					}
-					f.UncompressedSize64 = eb.uint64()
+		switch fieldTag {
+		case zip64ExtraID:
+			// update directory values from the zip64 extra block.
+			// They should only be consulted if the sizes read earlier
+			// are maxed out.
+			// See golang.org/issue/13367.
+			if needUSize {
+				needUSize = false
+				if len(fieldBuf) < 8 {
+					return ErrFormat
 				}
-				if needCSize {
-					needCSize = false
-					if len(eb) < 8 {
-						return ErrFormat
-					}
-					f.CompressedSize64 = eb.uint64()
-				}
-				if needHeaderOffset {
-					needHeaderOffset = false
-					if len(eb) < 8 {
-						return ErrFormat
-					}
-					f.headerOffset = int64(eb.uint64())
-				}
-				break
+				f.UncompressedSize64 = fieldBuf.uint64()
 			}
-			b = b[size:]
+			if needCSize {
+				needCSize = false
+				if len(fieldBuf) < 8 {
+					return ErrFormat
+				}
+				f.CompressedSize64 = fieldBuf.uint64()
+			}
+			if needHeaderOffset {
+				needHeaderOffset = false
+				if len(fieldBuf) < 8 {
+					return ErrFormat
+				}
+				f.headerOffset = int64(fieldBuf.uint64())
+			}
+		case ntfsExtraID:
+			if len(fieldBuf) < 4 {
+				continue parseExtras
+			}
+			fieldBuf.uint32()        // reserved (ignored)
+			for len(fieldBuf) >= 4 { // need at least tag and size
+				attrTag := fieldBuf.uint16()
+				attrSize := int(fieldBuf.uint16())
+				if len(fieldBuf) < attrSize {
+					continue parseExtras
+				}
+				attrBuf := fieldBuf.sub(attrSize)
+				if attrTag != 1 || attrSize != 24 {
+					continue // Ignore irrelevant attributes
+				}
+
+				const ticksPerSecond = 1e7    // Windows timestamp resolution
+				ts := int64(attrBuf.uint64()) // ModTime since Windows epoch
+				secs := int64(ts / ticksPerSecond)
+				nsecs := (1e9 / ticksPerSecond) * int64(ts%ticksPerSecond)
+				epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
+				modified = time.Unix(epoch.Unix()+secs, nsecs)
+			}
+		case unixExtraID:
+			if len(fieldBuf) < 8 {
+				continue parseExtras
+			}
+			fieldBuf.uint32()              // AcTime (ignored)
+			ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
+			modified = time.Unix(ts, 0)
+		case extTimeExtraID:
+			if len(fieldBuf) < 5 || fieldBuf.uint8()&1 == 0 {
+				continue parseExtras
+			}
+			ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
+			modified = time.Unix(ts, 0)
+		case infoZipUnixExtraID:
+			if len(fieldBuf) < 4 {
+				continue parseExtras
+			}
+			ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
+			modified = time.Unix(ts, 0)
+		}
+	}
+
+	msdosModified := msDosTimeToTime(f.ModifiedDate, f.ModifiedTime)
+	f.Modified = msdosModified
+	if !modified.IsZero() {
+		f.Modified = modified.UTC()
+
+		// If legacy MS-DOS timestamps are set, we can use the delta between
+		// the legacy and extended versions to estimate timezone offset.
+		//
+		// A non-UTC timezone is always used (even if offset is zero).
+		// Thus, FileHeader.Modified.Location() == time.UTC is useful for
+		// determining whether extended timestamps are present.
+		// This is necessary for users that need to do additional time
+		// calculations when dealing with legacy ZIP formats.
+		if f.ModifiedTime != 0 || f.ModifiedDate != 0 {
+			f.Modified = modified.In(timeZone(msdosModified.Sub(modified)))
 		}
 	}
 
@@ -508,6 +585,12 @@
 
 type readBuf []byte
 
+func (b *readBuf) uint8() uint8 {
+	v := (*b)[0]
+	*b = (*b)[1:]
+	return v
+}
+
 func (b *readBuf) uint16() uint16 {
 	v := binary.LittleEndian.Uint16(*b)
 	*b = (*b)[2:]
@@ -525,3 +608,9 @@
 	*b = (*b)[8:]
 	return v
 }
+
+func (b *readBuf) sub(n int) readBuf {
+	b2 := (*b)[:n]
+	*b = (*b)[n:]
+	return b2
+}
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index dfaae78..0d9040f 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -27,9 +27,11 @@
 }
 
 type ZipTestFile struct {
-	Name  string
-	Mode  os.FileMode
-	Mtime string // optional, modified time in format "mm-dd-yy hh:mm:ss"
+	Name     string
+	Mode     os.FileMode
+	NonUTF8  bool
+	ModTime  time.Time
+	Modified time.Time
 
 	// Information describing expected zip file content.
 	// First, reading the entire content should produce the error ContentErr.
@@ -47,32 +49,22 @@
 	Size       uint64
 }
 
-// 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:     "test.txt",
+				Content:  []byte("This is a test text file.\n"),
+				Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
+				Mode:     0644,
 			},
 			{
-				Name:  "gophercolor16x16.png",
-				File:  "gophercolor16x16.png",
-				Mtime: "09-05-10 15:52:58",
-				Mode:  0644,
+				Name:     "gophercolor16x16.png",
+				File:     "gophercolor16x16.png",
+				Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -81,16 +73,16 @@
 		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:     "test.txt",
+				Content:  []byte("This is a test text file.\n"),
+				Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
+				Mode:     0644,
 			},
 			{
-				Name:  "gophercolor16x16.png",
-				File:  "gophercolor16x16.png",
-				Mtime: "09-05-10 15:52:58",
-				Mode:  0644,
+				Name:     "gophercolor16x16.png",
+				File:     "gophercolor16x16.png",
+				Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -99,10 +91,10 @@
 		Source: returnRecursiveZip,
 		File: []ZipTestFile{
 			{
-				Name:    "r/r.zip",
-				Content: rZipBytes(),
-				Mtime:   "03-04-10 00:24:16",
-				Mode:    0666,
+				Name:     "r/r.zip",
+				Content:  rZipBytes(),
+				Modified: time.Date(2010, 3, 4, 0, 24, 16, 0, time.UTC),
+				Mode:     0666,
 			},
 		},
 	},
@@ -110,9 +102,10 @@
 		Name: "symlink.zip",
 		File: []ZipTestFile{
 			{
-				Name:    "symlink",
-				Content: []byte("../target"),
-				Mode:    0777 | os.ModeSymlink,
+				Name:     "symlink",
+				Content:  []byte("../target"),
+				Modified: time.Date(2012, 2, 3, 19, 56, 48, 0, timeZone(-2*time.Hour)),
+				Mode:     0777 | os.ModeSymlink,
 			},
 		},
 	},
@@ -127,22 +120,72 @@
 		Name: "dd.zip",
 		File: []ZipTestFile{
 			{
-				Name:    "filename",
-				Content: []byte("This is a test textfile.\n"),
-				Mtime:   "02-02-11 13:06:20",
-				Mode:    0666,
+				Name:     "filename",
+				Content:  []byte("This is a test textfile.\n"),
+				Modified: time.Date(2011, 2, 2, 13, 6, 20, 0, time.UTC),
+				Mode:     0666,
 			},
 		},
 	},
 	{
 		// created in windows XP file manager.
 		Name: "winxp.zip",
-		File: crossPlatform,
+		File: []ZipTestFile{
+			{
+				Name:     "hello",
+				Content:  []byte("world \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, time.UTC),
+				Mode:     0666,
+			},
+			{
+				Name:     "dir/bar",
+				Content:  []byte("foo \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, time.UTC),
+				Mode:     0666,
+			},
+			{
+				Name:     "dir/empty/",
+				Content:  []byte{},
+				Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, time.UTC),
+				Mode:     os.ModeDir | 0777,
+			},
+			{
+				Name:     "readonly",
+				Content:  []byte("important \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, time.UTC),
+				Mode:     0444,
+			},
+		},
 	},
 	{
 		// created by Zip 3.0 under Linux
 		Name: "unix.zip",
-		File: crossPlatform,
+		File: []ZipTestFile{
+			{
+				Name:     "hello",
+				Content:  []byte("world \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, timeZone(0)),
+				Mode:     0666,
+			},
+			{
+				Name:     "dir/bar",
+				Content:  []byte("foo \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, timeZone(0)),
+				Mode:     0666,
+			},
+			{
+				Name:     "dir/empty/",
+				Content:  []byte{},
+				Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, timeZone(0)),
+				Mode:     os.ModeDir | 0777,
+			},
+			{
+				Name:     "readonly",
+				Content:  []byte("important \r\n"),
+				Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, timeZone(0)),
+				Mode:     0444,
+			},
+		},
 	},
 	{
 		// created by Go, before we wrote the "optional" data
@@ -150,16 +193,16 @@
 		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:     "foo.txt",
+				Content:  []byte("foo\n"),
+				Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
+				Mode:     0644,
 			},
 			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
+				Name:     "bar.txt",
+				Content:  []byte("bar\n"),
+				Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -169,14 +212,16 @@
 		Name: "go-with-datadesc-sig.zip",
 		File: []ZipTestFile{
 			{
-				Name:    "foo.txt",
-				Content: []byte("foo\n"),
-				Mode:    0666,
+				Name:     "foo.txt",
+				Content:  []byte("foo\n"),
+				Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
+				Mode:     0666,
 			},
 			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mode:    0666,
+				Name:     "bar.txt",
+				Content:  []byte("bar\n"),
+				Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
+				Mode:     0666,
 			},
 		},
 	},
@@ -187,13 +232,15 @@
 			{
 				Name:       "foo.txt",
 				Content:    []byte("foo\n"),
+				Modified:   time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
 				Mode:       0666,
 				ContentErr: ErrChecksum,
 			},
 			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mode:    0666,
+				Name:     "bar.txt",
+				Content:  []byte("bar\n"),
+				Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
+				Mode:     0666,
 			},
 		},
 	},
@@ -203,16 +250,16 @@
 		Name: "crc32-not-streamed.zip",
 		File: []ZipTestFile{
 			{
-				Name:    "foo.txt",
-				Content: []byte("foo\n"),
-				Mtime:   "03-08-12 16:59:10",
-				Mode:    0644,
+				Name:     "foo.txt",
+				Content:  []byte("foo\n"),
+				Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
+				Mode:     0644,
 			},
 			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
+				Name:     "bar.txt",
+				Content:  []byte("bar\n"),
+				Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -225,15 +272,15 @@
 			{
 				Name:       "foo.txt",
 				Content:    []byte("foo\n"),
-				Mtime:      "03-08-12 16:59:10",
+				Modified:   time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
 				Mode:       0644,
 				ContentErr: ErrChecksum,
 			},
 			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
+				Name:     "bar.txt",
+				Content:  []byte("bar\n"),
+				Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -241,10 +288,10 @@
 		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,
+				Name:     "README",
+				Content:  []byte("This small file is in ZIP64 format.\n"),
+				Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, time.UTC),
+				Mode:     0644,
 			},
 		},
 	},
@@ -253,10 +300,10 @@
 		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,
+				Name:     "README",
+				Content:  []byte("This small file is in ZIP64 format.\n"),
+				Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, timeZone(-4*time.Hour)),
+				Mode:     0644,
 			},
 		},
 	},
@@ -266,41 +313,179 @@
 		Source: returnBigZipBytes,
 		File: []ZipTestFile{
 			{
-				Name:    "big.file",
-				Content: nil,
-				Size:    1<<32 - 1,
-				Mode:    0666,
+				Name:     "big.file",
+				Content:  nil,
+				Size:     1<<32 - 1,
+				Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "utf8-7zip.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "世界",
+				Content:  []byte{},
+				Mode:     0666,
+				Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
+			},
+		},
+	},
+	{
+		Name: "utf8-infozip.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "世界",
+				Content: []byte{},
+				Mode:    0644,
+				// Name is valid UTF-8, but format does not have UTF-8 flag set.
+				// We don't do UTF-8 detection for multi-byte runes due to
+				// false-positives with other encodings (e.g., Shift-JIS).
+				// Format says encoding is not UTF-8, so we trust it.
+				NonUTF8:  true,
+				Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
+			},
+		},
+	},
+	{
+		Name: "utf8-osx.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "世界",
+				Content: []byte{},
+				Mode:    0644,
+				// Name is valid UTF-8, but format does not have UTF-8 set.
+				NonUTF8:  true,
+				Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
+			},
+		},
+	},
+	{
+		Name: "utf8-winrar.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "世界",
+				Content:  []byte{},
+				Mode:     0666,
+				Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
+			},
+		},
+	},
+	{
+		Name: "utf8-winzip.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "世界",
+				Content:  []byte{},
+				Mode:     0666,
+				Modified: time.Date(2017, 11, 6, 13, 9, 27, 867000000, timeZone(-8*time.Hour)),
+			},
+		},
+	},
+	{
+		Name: "time-7zip.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "time-infozip.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
+				Mode:     0644,
+			},
+		},
+	},
+	{
+		Name: "time-osx.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 17, 27, 0, timeZone(-7*time.Hour)),
+				Mode:     0644,
+			},
+		},
+	},
+	{
+		Name: "time-win7.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 58, 0, time.UTC),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "time-winrar.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "time-winzip.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 57, 244000000, timeZone(-7*time.Hour)),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "time-go.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "test.txt",
+				Content:  []byte{},
+				Size:     1<<32 - 1,
+				Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
+				Mode:     0666,
+			},
+		},
+	},
+	{
+		Name: "time-22738.zip",
+		File: []ZipTestFile{
+			{
+				Name:     "file",
+				Content:  []byte{},
+				Mode:     0666,
+				Modified: time.Date(1999, 12, 31, 19, 0, 0, 0, timeZone(-5*time.Hour)),
+				ModTime:  time.Date(1999, 12, 31, 19, 0, 0, 0, time.UTC),
 			},
 		},
 	},
 }
 
-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)
+		t.Run(zt.Name, func(t *testing.T) {
+			readTestZip(t, zt)
+		})
 	}
 }
 
@@ -319,7 +504,7 @@
 		}
 	}
 	if err != zt.Error {
-		t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error)
+		t.Errorf("error=%v, want %v", err, zt.Error)
 		return
 	}
 
@@ -335,16 +520,19 @@
 	}
 
 	if z.Comment != zt.Comment {
-		t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
+		t.Errorf("comment=%q, want %q", 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))
+		t.Fatalf("file count=%d, want %d", len(z.File), len(zt.File))
 	}
 
 	// test read of each file
 	for i, ft := range zt.File {
 		readTestFile(t, zt, ft, z.File[i])
 	}
+	if t.Failed() {
+		return
+	}
 
 	// test simultaneous reads
 	n := 0
@@ -363,23 +551,24 @@
 	}
 }
 
+func equalTimeAndZone(t1, t2 time.Time) bool {
+	name1, offset1 := t1.Zone()
+	name2, offset2 := t2.Zone()
+	return t1.Equal(t2) && name1 == name2 && offset1 == offset2
+}
+
 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)
+		t.Errorf("name=%q, want %q", f.Name, ft.Name)
+	}
+	if !ft.Modified.IsZero() && !equalTimeAndZone(f.Modified, ft.Modified) {
+		t.Errorf("%s: Modified=%s, want %s", f.Name, f.Modified, ft.Modified)
+	}
+	if !ft.ModTime.IsZero() && !equalTimeAndZone(f.ModTime(), ft.ModTime) {
+		t.Errorf("%s: ModTime=%s, want %s", f.Name, f.ModTime(), ft.ModTime)
 	}
 
-	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)
+	testFileMode(t, f, ft.Mode)
 
 	size := uint64(f.UncompressedSize)
 	if size == uint32max {
@@ -390,7 +579,7 @@
 
 	r, err := f.Open()
 	if err != nil {
-		t.Errorf("%s: %v", zt.Name, err)
+		t.Errorf("%v", err)
 		return
 	}
 
@@ -408,7 +597,7 @@
 	var b bytes.Buffer
 	_, err = io.Copy(&b, r)
 	if err != ft.ContentErr {
-		t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
+		t.Errorf("copying contents: %v (want %v)", err, ft.ContentErr)
 	}
 	if err != nil {
 		return
@@ -440,12 +629,12 @@
 	}
 }
 
-func testFileMode(t *testing.T, zipName string, f *File, want os.FileMode) {
+func testFileMode(t *testing.T, f *File, want os.FileMode) {
 	mode := f.Mode()
 	if want == 0 {
-		t.Errorf("%s: %s mode: got %v, want none", zipName, f.Name, mode)
+		t.Errorf("%s mode: got %v, want none", f.Name, mode)
 	} else if mode != want {
-		t.Errorf("%s: %s mode: want %v, got %v", zipName, f.Name, want, mode)
+		t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
 	}
 }
 
diff --git a/src/archive/zip/struct.go b/src/archive/zip/struct.go
index 0be210e..f613ebd 100644
--- a/src/archive/zip/struct.go
+++ b/src/archive/zip/struct.go
@@ -27,8 +27,8 @@
 
 // Compression methods.
 const (
-	Store   uint16 = 0
-	Deflate uint16 = 8
+	Store   uint16 = 0 // no compression
+	Deflate uint16 = 8 // DEFLATE compressed
 )
 
 const (
@@ -46,40 +46,79 @@
 	directory64LocLen        = 20         //
 	directory64EndLen        = 56         // + extra
 
-	// Constants for the first byte in CreatorVersion
+	// Constants for the first byte in CreatorVersion.
 	creatorFAT    = 0
 	creatorUnix   = 3
 	creatorNTFS   = 11
 	creatorVFAT   = 14
 	creatorMacOSX = 19
 
-	// version numbers
+	// Version numbers.
 	zipVersion20 = 20 // 2.0
 	zipVersion45 = 45 // 4.5 (reads and writes zip64 archives)
 
-	// limits for non zip64 files
+	// Limits for non zip64 files.
 	uint16max = (1 << 16) - 1
 	uint32max = (1 << 32) - 1
 
-	// extra header id's
-	zip64ExtraId = 0x0001 // zip64 Extended Information Extra Field
+	// Extra header IDs.
+	//
+	// IDs 0..31 are reserved for official use by PKWARE.
+	// IDs above that range are defined by third-party vendors.
+	// Since ZIP lacked high precision timestamps (nor a official specification
+	// of the timezone used for the date fields), many competing extra fields
+	// have been invented. Pervasive use effectively makes them "official".
+	//
+	// See http://mdfs.net/Docs/Comp/Archiving/Zip/ExtraField
+	zip64ExtraID       = 0x0001 // Zip64 extended information
+	ntfsExtraID        = 0x000a // NTFS
+	unixExtraID        = 0x000d // UNIX
+	extTimeExtraID     = 0x5455 // Extended timestamp
+	infoZipUnixExtraID = 0x5855 // Info-ZIP Unix extension
 )
 
 // FileHeader describes a file within a zip file.
 // See the zip spec for details.
 type FileHeader struct {
 	// Name is the name of the file.
-	// It 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.
+	// It must be a relative path, not start with a drive letter (e.g. C:),
+	// and must use forward slashes instead of back slashes.
 	Name string
 
-	CreatorVersion     uint16
-	ReaderVersion      uint16
-	Flags              uint16
-	Method             uint16
-	ModifiedTime       uint16 // MS-DOS time
-	ModifiedDate       uint16 // MS-DOS date
+	// Comment is any arbitrary user-defined string shorter than 64KiB.
+	Comment string
+
+	// NonUTF8 indicates that Name and Comment are not encoded in UTF-8.
+	//
+	// By specification, the only other encoding permitted should be CP-437,
+	// but historically many ZIP readers interpret Name and Comment as whatever
+	// the system's local character encoding happens to be.
+	//
+	// This flag should only be set if the user intends to encode a non-portable
+	// ZIP file for a specific localized region. Otherwise, the Writer
+	// automatically sets the ZIP format's UTF-8 flag for valid UTF-8 strings.
+	NonUTF8 bool
+
+	CreatorVersion uint16
+	ReaderVersion  uint16
+	Flags          uint16
+
+	// Method is the compression method. If zero, Store is used.
+	Method uint16
+
+	// Modified is the modified time of the file.
+	//
+	// When reading, an extended timestamp is preferred over the legacy MS-DOS
+	// date field, and the offset between the times is used as the timezone.
+	// If only the MS-DOS date is present, the timezone is assumed to be UTC.
+	//
+	// When writing, an extended timestamp (which is timezone-agnostic) is
+	// always emitted. The legacy MS-DOS date field is encoded according to the
+	// location of the Modified time.
+	Modified     time.Time
+	ModifiedTime uint16 // Deprecated: Legacy MS-DOS date; use Modified instead.
+	ModifiedDate uint16 // Deprecated: Legacy MS-DOS time; use Modified instead.
+
 	CRC32              uint32
 	CompressedSize     uint32 // Deprecated: Use CompressedSize64 instead.
 	UncompressedSize   uint32 // Deprecated: Use UncompressedSize64 instead.
@@ -87,7 +126,6 @@
 	UncompressedSize64 uint64
 	Extra              []byte
 	ExternalAttrs      uint32 // Meaning depends on CreatorVersion
-	Comment            string
 }
 
 // FileInfo returns an os.FileInfo for the FileHeader.
@@ -117,6 +155,8 @@
 // Because os.FileInfo's Name method returns only the base name of
 // the file it describes, it may be necessary to modify the Name field
 // of the returned header to provide the full path name of the file.
+// If compression is desired, callers should set the FileHeader.Method
+// field; it is unset by default.
 func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) {
 	size := fi.Size()
 	fh := &FileHeader{
@@ -144,6 +184,21 @@
 	comment            string
 }
 
+// timeZone returns a *time.Location based on the provided offset.
+// If the offset is non-sensible, then this uses an offset of zero.
+func timeZone(offset time.Duration) *time.Location {
+	const (
+		minOffset   = -12 * time.Hour  // E.g., Baker island at -12:00
+		maxOffset   = +14 * time.Hour  // E.g., Line island at +14:00
+		offsetAlias = 15 * time.Minute // E.g., Nepal at +5:45
+	)
+	offset = offset.Round(offsetAlias)
+	if offset < minOffset || maxOffset < offset {
+		offset = 0
+	}
+	return time.FixedZone("", int(offset/time.Second))
+}
+
 // msDosTimeToTime converts an MS-DOS date and time into a time.Time.
 // The resolution is 2s.
 // See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
@@ -168,21 +223,26 @@
 // The resolution is 2s.
 // See: http://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx
 func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
-	t = t.In(time.UTC)
 	fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9)
 	fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11)
 	return
 }
 
-// ModTime returns the modification time in UTC.
-// The resolution is 2s.
+// ModTime returns the modification time in UTC using the legacy
+// ModifiedDate and ModifiedTime fields.
+//
+// Deprecated: Use Modified instead.
 func (h *FileHeader) ModTime() time.Time {
 	return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
 }
 
-// SetModTime sets the ModifiedTime and ModifiedDate fields to the given time in UTC.
-// The resolution is 2s.
+// SetModTime sets the Modified, ModifiedTime, and ModifiedDate fields
+// to the given time in UTC.
+//
+// Deprecated: Use Modified instead.
 func (h *FileHeader) SetModTime(t time.Time) {
+	t = t.UTC() // Convert to UTC for compatibility
+	h.Modified = t
 	h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
 }
 
diff --git a/src/archive/zip/testdata/time-22738.zip b/src/archive/zip/testdata/time-22738.zip
new file mode 100644
index 0000000..eb85b57
--- /dev/null
+++ b/src/archive/zip/testdata/time-22738.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-7zip.zip b/src/archive/zip/testdata/time-7zip.zip
new file mode 100644
index 0000000..4f74819
--- /dev/null
+++ b/src/archive/zip/testdata/time-7zip.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-go.zip b/src/archive/zip/testdata/time-go.zip
new file mode 100644
index 0000000..f008805
--- /dev/null
+++ b/src/archive/zip/testdata/time-go.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-infozip.zip b/src/archive/zip/testdata/time-infozip.zip
new file mode 100644
index 0000000..8e63948
--- /dev/null
+++ b/src/archive/zip/testdata/time-infozip.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-osx.zip b/src/archive/zip/testdata/time-osx.zip
new file mode 100644
index 0000000..e82c5c2
--- /dev/null
+++ b/src/archive/zip/testdata/time-osx.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-win7.zip b/src/archive/zip/testdata/time-win7.zip
new file mode 100644
index 0000000..8ba222b
--- /dev/null
+++ b/src/archive/zip/testdata/time-win7.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-winrar.zip b/src/archive/zip/testdata/time-winrar.zip
new file mode 100644
index 0000000..a8a19b0
--- /dev/null
+++ b/src/archive/zip/testdata/time-winrar.zip
Binary files differ
diff --git a/src/archive/zip/testdata/time-winzip.zip b/src/archive/zip/testdata/time-winzip.zip
new file mode 100644
index 0000000..f6e8f8b
--- /dev/null
+++ b/src/archive/zip/testdata/time-winzip.zip
Binary files differ
diff --git a/src/archive/zip/testdata/utf8-7zip.zip b/src/archive/zip/testdata/utf8-7zip.zip
new file mode 100644
index 0000000..0e97884
--- /dev/null
+++ b/src/archive/zip/testdata/utf8-7zip.zip
Binary files differ
diff --git a/src/archive/zip/testdata/utf8-infozip.zip b/src/archive/zip/testdata/utf8-infozip.zip
new file mode 100644
index 0000000..25a8926
--- /dev/null
+++ b/src/archive/zip/testdata/utf8-infozip.zip
Binary files differ
diff --git a/src/archive/zip/testdata/utf8-osx.zip b/src/archive/zip/testdata/utf8-osx.zip
new file mode 100644
index 0000000..9b0c058
--- /dev/null
+++ b/src/archive/zip/testdata/utf8-osx.zip
Binary files differ
diff --git a/src/archive/zip/testdata/utf8-winrar.zip b/src/archive/zip/testdata/utf8-winrar.zip
new file mode 100644
index 0000000..4bad6c3
--- /dev/null
+++ b/src/archive/zip/testdata/utf8-winrar.zip
Binary files differ
diff --git a/src/archive/zip/testdata/utf8-winzip.zip b/src/archive/zip/testdata/utf8-winzip.zip
new file mode 100644
index 0000000..909d52e
--- /dev/null
+++ b/src/archive/zip/testdata/utf8-winzip.zip
Binary files differ
diff --git a/src/archive/zip/writer.go b/src/archive/zip/writer.go
index 9f4fcee..14a5ee4 100644
--- a/src/archive/zip/writer.go
+++ b/src/archive/zip/writer.go
@@ -14,6 +14,11 @@
 	"unicode/utf8"
 )
 
+var (
+	errLongName  = errors.New("zip: FileHeader.Name too long")
+	errLongExtra = errors.New("zip: FileHeader.Extra too long")
+)
+
 // Writer implements a zip file writer.
 type Writer struct {
 	cw          *countWriter
@@ -21,6 +26,7 @@
 	last        *fileWriter
 	closed      bool
 	compressors map[uint16]Compressor
+	comment     string
 
 	// testHookCloseSizeOffset if non-nil is called with the size
 	// of offset of the central directory at Close.
@@ -54,6 +60,16 @@
 	return w.cw.w.(*bufio.Writer).Flush()
 }
 
+// SetComment sets the end-of-central-directory comment field.
+// It can only be called before Close.
+func (w *Writer) SetComment(comment string) error {
+	if len(comment) > uint16max {
+		return errors.New("zip: Writer.Comment too long")
+	}
+	w.comment = comment
+	return nil
+}
+
 // Close finishes writing the zip file by writing the central directory.
 // It does not (and cannot) close the underlying writer.
 func (w *Writer) Close() error {
@@ -91,7 +107,7 @@
 			// append a zip64 extra block to Extra
 			var buf [28]byte // 2x uint16 + 3x uint64
 			eb := writeBuf(buf[:])
-			eb.uint16(zip64ExtraId)
+			eb.uint16(zip64ExtraID)
 			eb.uint16(24) // size = 3x uint64
 			eb.uint64(h.UncompressedSize64)
 			eb.uint64(h.CompressedSize64)
@@ -172,21 +188,25 @@
 	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)
+	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
+	b.uint16(uint16(len(w.comment))) // byte size of EOCD comment
 	if _, err := w.cw.Write(buf[:]); err != nil {
 		return err
 	}
+	if _, err := io.WriteString(w.cw, w.comment); 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 file contents will be compressed using the Deflate method.
 // 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.
@@ -200,27 +220,36 @@
 	return w.CreateHeader(header)
 }
 
-func hasValidUTF8(s string) bool {
-	n := 0
-	for _, r := range s {
-		// By default, ZIP uses CP437, which is only identical to ASCII for the printable characters.
-		if r < 0x20 || r >= 0x7f {
-			if !utf8.ValidRune(r) {
-				return false
+// detectUTF8 reports whether s is a valid UTF-8 string, and whether the string
+// must be considered UTF-8 encoding (i.e., not compatible with CP-437, ASCII,
+// or any other common encoding).
+func detectUTF8(s string) (valid, require bool) {
+	for i := 0; i < len(s); {
+		r, size := utf8.DecodeRuneInString(s[i:])
+		i += size
+		// Officially, ZIP uses CP-437, but many readers use the system's
+		// local character encoding. Most encoding are compatible with a large
+		// subset of CP-437, which itself is ASCII-like.
+		//
+		// Forbid 0x7e and 0x5c since EUC-KR and Shift-JIS replace those
+		// characters with localized currency and overline characters.
+		if r < 0x20 || r > 0x7d || r == 0x5c {
+			if !utf8.ValidRune(r) || (r == utf8.RuneError && size == 1) {
+				return false, false
 			}
-			n++
+			require = true
 		}
 	}
-	return n > 0
+	return true, require
 }
 
-// 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.
+// CreateHeader adds a file to the zip archive using the provided FileHeader
+// for the file metadata. Writer takes ownership of fh and may mutate
+// its fields. The caller must not modify fh after calling CreateHeader.
 //
+// This 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. The provided FileHeader fh
-// must not be modified after a call to CreateHeader.
+// 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 {
@@ -234,13 +263,62 @@
 
 	fh.Flags |= 0x8 // we will write a data descriptor
 
-	if hasValidUTF8(fh.Name) || hasValidUTF8(fh.Comment) {
-		fh.Flags |= 0x800 // filename or comment have valid utf-8 string
+	// The ZIP format has a sad state of affairs regarding character encoding.
+	// Officially, the name and comment fields are supposed to be encoded
+	// in CP-437 (which is mostly compatible with ASCII), unless the UTF-8
+	// flag bit is set. However, there are several problems:
+	//
+	//	* Many ZIP readers still do not support UTF-8.
+	//	* If the UTF-8 flag is cleared, several readers simply interpret the
+	//	name and comment fields as whatever the local system encoding is.
+	//
+	// In order to avoid breaking readers without UTF-8 support,
+	// we avoid setting the UTF-8 flag if the strings are CP-437 compatible.
+	// However, if the strings require multibyte UTF-8 encoding and is a
+	// valid UTF-8 string, then we set the UTF-8 bit.
+	//
+	// For the case, where the user explicitly wants to specify the encoding
+	// as UTF-8, they will need to set the flag bit themselves.
+	utf8Valid1, utf8Require1 := detectUTF8(fh.Name)
+	utf8Valid2, utf8Require2 := detectUTF8(fh.Comment)
+	switch {
+	case fh.NonUTF8:
+		fh.Flags &^= 0x800
+	case (utf8Require1 || utf8Require2) && (utf8Valid1 && utf8Valid2):
+		fh.Flags |= 0x800
 	}
 
 	fh.CreatorVersion = fh.CreatorVersion&0xff00 | zipVersion20 // preserve compatibility byte
 	fh.ReaderVersion = zipVersion20
 
+	// If Modified is set, this takes precedence over MS-DOS timestamp fields.
+	if !fh.Modified.IsZero() {
+		// Contrary to the FileHeader.SetModTime method, we intentionally
+		// do not convert to UTC, because we assume the user intends to encode
+		// the date using the specified timezone. A user may want this control
+		// because many legacy ZIP readers interpret the timestamp according
+		// to the local timezone.
+		//
+		// The timezone is only non-UTC if a user directly sets the Modified
+		// field directly themselves. All other approaches sets UTC.
+		fh.ModifiedDate, fh.ModifiedTime = timeToMsDosTime(fh.Modified)
+
+		// Use "extended timestamp" format since this is what Info-ZIP uses.
+		// Nearly every major ZIP implementation uses a different format,
+		// but at least most seem to be able to understand the other formats.
+		//
+		// This format happens to be identical for both local and central header
+		// if modification time is the only timestamp being encoded.
+		var mbuf [9]byte // 2*SizeOf(uint16) + SizeOf(uint8) + SizeOf(uint32)
+		mt := uint32(fh.Modified.Unix())
+		eb := writeBuf(mbuf[:])
+		eb.uint16(extTimeExtraID)
+		eb.uint16(5)  // Size: SizeOf(uint8) + SizeOf(uint32)
+		eb.uint8(1)   // Flags: ModTime
+		eb.uint32(mt) // ModTime
+		fh.Extra = append(fh.Extra, mbuf[:]...)
+	}
+
 	fw := &fileWriter{
 		zipw:      w.cw,
 		compCount: &countWriter{w: w.cw},
@@ -273,6 +351,14 @@
 }
 
 func writeHeader(w io.Writer, h *FileHeader) error {
+	const maxUint16 = 1<<16 - 1
+	if len(h.Name) > maxUint16 {
+		return errLongName
+	}
+	if len(h.Extra) > maxUint16 {
+		return errLongExtra
+	}
+
 	var buf [fileHeaderLen]byte
 	b := writeBuf(buf[:])
 	b.uint32(uint32(fileHeaderSignature))
@@ -402,6 +488,11 @@
 
 type writeBuf []byte
 
+func (b *writeBuf) uint8(v uint8) {
+	(*b)[0] = v
+	*b = (*b)[1:]
+}
+
 func (b *writeBuf) uint16(v uint16) {
 	binary.LittleEndian.PutUint16(*b, v)
 	*b = (*b)[2:]
diff --git a/src/archive/zip/writer_test.go b/src/archive/zip/writer_test.go
index 92fb6ec..38f3229 100644
--- a/src/archive/zip/writer_test.go
+++ b/src/archive/zip/writer_test.go
@@ -6,11 +6,14 @@
 
 import (
 	"bytes"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"math/rand"
 	"os"
+	"strings"
 	"testing"
+	"time"
 )
 
 // TODO(adg): a more sophisticated test suite
@@ -57,8 +60,8 @@
 
 func TestWriter(t *testing.T) {
 	largeData := make([]byte, 1<<17)
-	for i := range largeData {
-		largeData[i] = byte(rand.Int())
+	if _, err := rand.Read(largeData); err != nil {
+		t.Fatal("rand.Read failed:", err)
 	}
 	writeTests[1].Data = largeData
 	defer func() {
@@ -87,31 +90,100 @@
 	}
 }
 
+// TestWriterComment is test for EOCD comment read/write.
+func TestWriterComment(t *testing.T) {
+	var tests = []struct {
+		comment string
+		ok      bool
+	}{
+		{"hi, hello", true},
+		{"hi, こんにちわ", true},
+		{strings.Repeat("a", uint16max), true},
+		{strings.Repeat("a", uint16max+1), false},
+	}
+
+	for _, test := range tests {
+		// write a zip file
+		buf := new(bytes.Buffer)
+		w := NewWriter(buf)
+		if err := w.SetComment(test.comment); err != nil {
+			if test.ok {
+				t.Fatalf("SetComment: unexpected error %v", err)
+			}
+			continue
+		} else {
+			if !test.ok {
+				t.Fatalf("SetComment: unexpected success, want error")
+			}
+		}
+
+		if err := w.Close(); test.ok == (err != nil) {
+			t.Fatal(err)
+		}
+
+		if w.closed != test.ok {
+			t.Fatalf("Writer.closed: got %v, want %v", w.closed, test.ok)
+		}
+
+		// skip read test in failure cases
+		if !test.ok {
+			continue
+		}
+
+		// read it back
+		r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if r.Comment != test.comment {
+			t.Fatalf("Reader.Comment: got %v, want %v", r.Comment, test.comment)
+		}
+	}
+}
+
 func TestWriterUTF8(t *testing.T) {
 	var utf8Tests = []struct {
 		name    string
 		comment string
-		expect  uint16
+		nonUTF8 bool
+		flags   uint16
 	}{
 		{
 			name:    "hi, hello",
 			comment: "in the world",
-			expect:  0x8,
+			flags:   0x8,
 		},
 		{
 			name:    "hi, こんにちわ",
 			comment: "in the world",
-			expect:  0x808,
+			flags:   0x808,
+		},
+		{
+			name:    "hi, こんにちわ",
+			comment: "in the world",
+			nonUTF8: true,
+			flags:   0x8,
 		},
 		{
 			name:    "hi, hello",
 			comment: "in the 世界",
-			expect:  0x808,
+			flags:   0x808,
 		},
 		{
 			name:    "hi, こんにちわ",
 			comment: "in the 世界",
-			expect:  0x808,
+			flags:   0x808,
+		},
+		{
+			name:    "the replacement rune is �",
+			comment: "the replacement rune is �",
+			flags:   0x808,
+		},
+		{
+			// Name is Japanese encoded in Shift JIS.
+			name:    "\x93\xfa\x96{\x8c\xea.txt",
+			comment: "in the 世界",
+			flags:   0x008, // UTF-8 must not be set
 		},
 	}
 
@@ -123,6 +195,7 @@
 		h := &FileHeader{
 			Name:    test.name,
 			Comment: test.comment,
+			NonUTF8: test.nonUTF8,
 			Method:  Deflate,
 		}
 		w, err := w.CreateHeader(h)
@@ -142,18 +215,41 @@
 		t.Fatal(err)
 	}
 	for i, test := range utf8Tests {
-		got := r.File[i].Flags
-		t.Logf("name %v, comment %v", test.name, test.comment)
-		if got != test.expect {
-			t.Fatalf("Flags: got %v, want %v", got, test.expect)
+		flags := r.File[i].Flags
+		if flags != test.flags {
+			t.Errorf("CreateHeader(name=%q comment=%q nonUTF8=%v): flags=%#x, want %#x", test.name, test.comment, test.nonUTF8, flags, test.flags)
 		}
 	}
 }
 
+func TestWriterTime(t *testing.T) {
+	var buf bytes.Buffer
+	h := &FileHeader{
+		Name:     "test.txt",
+		Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
+	}
+	w := NewWriter(&buf)
+	if _, err := w.CreateHeader(h); err != nil {
+		t.Fatalf("unexpected CreateHeader error: %v", err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("unexpected Close error: %v", err)
+	}
+
+	want, err := ioutil.ReadFile("testdata/time-go.zip")
+	if err != nil {
+		t.Fatalf("unexpected ReadFile error: %v", err)
+	}
+	if got := buf.Bytes(); !bytes.Equal(got, want) {
+		fmt.Printf("%x\n%x\n", got, want)
+		t.Error("contents of time-go.zip differ")
+	}
+}
+
 func TestWriterOffset(t *testing.T) {
 	largeData := make([]byte, 1<<17)
-	for i := range largeData {
-		largeData[i] = byte(rand.Int())
+	if _, err := rand.Read(largeData); err != nil {
+		t.Fatal("rand.Read failed:", err)
 	}
 	writeTests[1].Data = largeData
 	defer func() {
@@ -225,7 +321,7 @@
 	if f.Name != wt.Name {
 		t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
 	}
-	testFileMode(t, wt.Name, f, wt.Mode)
+	testFileMode(t, f, wt.Mode)
 	rc, err := f.Open()
 	if err != nil {
 		t.Fatal("opening:", err)
diff --git a/src/archive/zip/zip_test.go b/src/archive/zip/zip_test.go
index 18c2171..7e02cb0 100644
--- a/src/archive/zip/zip_test.go
+++ b/src/archive/zip/zip_test.go
@@ -645,16 +645,54 @@
 	h := FileHeader{
 		Name:   "foo.txt",
 		Method: Deflate,
-		Extra:  []byte{zip64ExtraId}, // missing size and second half of tag, but Extra is best-effort parsing
+		Extra:  []byte{zip64ExtraID}, // missing size and second half of tag, but Extra is best-effort parsing
 	}
 	testValidHeader(&h, t)
 }
 
+func TestHeaderTooLongErr(t *testing.T) {
+	var headerTests = []struct {
+		name    string
+		extra   []byte
+		wanterr error
+	}{
+		{
+			name:    strings.Repeat("x", 1<<16),
+			extra:   []byte{},
+			wanterr: errLongName,
+		},
+		{
+			name:    "long_extra",
+			extra:   bytes.Repeat([]byte{0xff}, 1<<16),
+			wanterr: errLongExtra,
+		},
+	}
+
+	// write a zip file
+	buf := new(bytes.Buffer)
+	w := NewWriter(buf)
+
+	for _, test := range headerTests {
+		h := &FileHeader{
+			Name:  test.name,
+			Extra: test.extra,
+		}
+		_, err := w.CreateHeader(h)
+		if err != test.wanterr {
+			t.Errorf("error=%v, want %v", err, test.wanterr)
+		}
+	}
+
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestHeaderIgnoredSize(t *testing.T) {
 	h := FileHeader{
 		Name:   "foo.txt",
 		Method: Deflate,
-		Extra:  []byte{zip64ExtraId & 0xFF, zip64ExtraId >> 8, 24, 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, // bad size but shouldn't be consulted
+		Extra:  []byte{zip64ExtraID & 0xFF, zip64ExtraID >> 8, 24, 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, // bad size but shouldn't be consulted
 	}
 	testValidHeader(&h, t)
 }
diff --git a/src/bootstrap.bash b/src/bootstrap.bash
index da3dff4..32b736a 100755
--- a/src/bootstrap.bash
+++ b/src/bootstrap.bash
@@ -14,6 +14,15 @@
 #
 # Only changes that have been committed to Git (at least locally,
 # not necessary reviewed and submitted to master) are included in the tree.
+#
+# As a special case for Go's internal use only, if the
+# BOOTSTRAP_FORMAT environment variable is set to "mintgz", the
+# resulting archive is intended for use by the Go build system and
+# differs in that the mintgz file:
+#   * is a tar.gz file instead of bz2
+#   * has many unnecessary files deleted to reduce its size
+#   * does not have a shared directory component for each tar entry
+# Do not depend on the mintgz format.
 
 set -e
 
@@ -28,6 +37,11 @@
 	exit 2
 fi
 
+if [ "$BOOTSTRAP_FORMAT" != "mintgz" -a "$BOOTSTRAP_FORMAT" != "" ]; then
+	echo "unknown BOOTSTRAP_FORMAT format"
+	exit 2
+fi
+
 unset GOROOT
 src=$(cd .. && pwd)
 echo "#### Copying to $targ"
@@ -62,8 +76,40 @@
 	rmdir bin/*_*
 	rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
 fi
+
+if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
+	# Fetch git revision before rm -rf .git.
+	GITREV=$(git rev-parse --short HEAD)
+fi
+
 rm -rf pkg/bootstrap pkg/obj .git
 
+# Support for building minimal tar.gz for the builders.
+# The build system doesn't support bzip2, and by deleting more stuff,
+# they start faster, especially on machines without fast filesystems
+# and things like tmpfs configures.
+# Do not depend on this format. It's for internal use only.
+if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
+	OUTGZ="gobootstrap-${GOOS}-${GOARCH}-${GITREV}.tar.gz"
+	echo "Preparing to generate build system's ${OUTGZ}; cleaning ..."
+	rm -rf bin/gofmt
+	rm -rf src/runtime/race/race_*.syso
+	rm -rf api test doc misc/cgo/test misc/trace
+	rm -rf pkg/tool/*_*/{addr2line,api,cgo,cover,doc,fix,nm,objdump,pack,pprof,test2json,trace,vet}
+	rm -rf pkg/*_*/{image,database,cmd}
+	rm -rf $(find . -type d -name testdata)
+	find . -type f -name '*_test.go' -exec rm {} \;
+	# git clean doesn't clean symlinks apparently, and the buildlet
+	# rejects them, so:
+	find . -type l -exec rm {} \;
+
+	echo "Writing ${OUTGZ} ..."
+	tar cf - . | gzip -9 > ../$OUTGZ
+	cd ..
+	ls -l "$(pwd)/$OUTGZ"
+	exit 0
+fi
+
 echo ----
 echo Bootstrap toolchain for "$GOOS/$GOARCH" installed in "$(pwd)".
 echo Building tbz.
diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go
index da94a25..ad9c9f5 100644
--- a/src/bufio/bufio.go
+++ b/src/bufio/bufio.go
@@ -62,6 +62,9 @@
 	return NewReaderSize(rd, defaultBufSize)
 }
 
+// Size returns the size of the underlying buffer in bytes.
+func (r *Reader) Size() int { return len(r.buf) }
+
 // Reset discards any buffered data, resets all state, and switches
 // the buffered reader to read from r.
 func (b *Reader) Reset(r io.Reader) {
@@ -548,6 +551,9 @@
 	return NewWriterSize(w, defaultBufSize)
 }
 
+// Size returns the size of the underlying buffer in bytes.
+func (b *Writer) Size() int { return len(b.buf) }
+
 // 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) {
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
index ef0f6c8..c829d2b 100644
--- a/src/bufio/bufio_test.go
+++ b/src/bufio/bufio_test.go
@@ -1418,6 +1418,24 @@
 
 }
 
+func TestReaderSize(t *testing.T) {
+	if got, want := NewReader(nil).Size(), DefaultBufSize; got != want {
+		t.Errorf("NewReader's Reader.Size = %d; want %d", got, want)
+	}
+	if got, want := NewReaderSize(nil, 1234).Size(), 1234; got != want {
+		t.Errorf("NewReaderSize's Reader.Size = %d; want %d", got, want)
+	}
+}
+
+func TestWriterSize(t *testing.T) {
+	if got, want := NewWriter(nil).Size(), DefaultBufSize; got != want {
+		t.Errorf("NewWriter's Writer.Size = %d; want %d", got, want)
+	}
+	if got, want := NewWriterSize(nil, 1234).Size(), 1234; got != want {
+		t.Errorf("NewWriterSize's Writer.Size = %d; want %d", got, want)
+	}
+}
+
 // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
 type onlyReader struct {
 	io.Reader
diff --git a/src/bufio/export_test.go b/src/bufio/export_test.go
index 3d3bb27..1667f01 100644
--- a/src/bufio/export_test.go
+++ b/src/bufio/export_test.go
@@ -11,6 +11,8 @@
 
 var IsSpace = isSpace
 
+const DefaultBufSize = defaultBufSize
+
 func (s *Scanner) MaxTokenSize(n int) {
 	if n < utf8.UTFMax || n > 1e9 {
 		panic("bad max token size")
diff --git a/src/bufio/scan.go b/src/bufio/scan.go
index 9f741c9..40aaa4a 100644
--- a/src/bufio/scan.go
+++ b/src/bufio/scan.go
@@ -123,8 +123,9 @@
 // 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.
-// Scan panics if the split function returns 100 empty tokens without
-// advancing the input. This is a common error mode for scanners.
+// Scan panics if the split function returns too many empty
+// tokens without advancing the input. This is a common error mode for
+// scanners.
 func (s *Scanner) Scan() bool {
 	if s.done {
 		return false
@@ -156,8 +157,8 @@
 				} else {
 					// Returning tokens not advancing input at EOF.
 					s.empties++
-					if s.empties > 100 {
-						panic("bufio.Scan: 100 empty tokens without progressing")
+					if s.empties > maxConsecutiveEmptyReads {
+						panic("bufio.Scan: too many empty tokens without progressing")
 					}
 				}
 				return true
diff --git a/src/builtin/builtin.go b/src/builtin/builtin.go
index 1c7c041..4578c85 100644
--- a/src/builtin/builtin.go
+++ b/src/builtin/builtin.go
@@ -171,8 +171,9 @@
 //	Slice: The size specifies the length. The capacity of the slice is
 //	equal to its length. A second integer argument may be provided to
 //	specify a different capacity; it must be no smaller than the
-//	length, so make([]int, 0, 10) allocates a slice of length 0 and
-//	capacity 10.
+//	length. For example, make([]int, 0, 10) allocates an underlying array
+//	of size 10 and returns a slice of length 0 and capacity 10 that is
+//	backed by this underlying array.
 //	Map: An empty map is allocated with enough space to hold the
 //	specified number of elements. The size may be omitted, in which case
 //	a small starting size is allocated.
diff --git a/src/bytes/boundary_test.go b/src/bytes/boundary_test.go
new file mode 100644
index 0000000..ea84f1e
--- /dev/null
+++ b/src/bytes/boundary_test.go
@@ -0,0 +1,84 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// +build linux
+
+package bytes_test
+
+import (
+	. "bytes"
+	"syscall"
+	"testing"
+)
+
+// This file tests the situation where byte operations are checking
+// data very near to a page boundary. We want to make sure those
+// operations do not read across the boundary and cause a page
+// fault where they shouldn't.
+
+// These tests run only on linux. The code being tested is
+// not OS-specific, so it does not need to be tested on all
+// operating systems.
+
+// dangerousSlice returns a slice which is immediately
+// preceded and followed by a faulting page.
+func dangerousSlice(t *testing.T) []byte {
+	pagesize := syscall.Getpagesize()
+	b, err := syscall.Mmap(0, 0, 3*pagesize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANONYMOUS|syscall.MAP_PRIVATE)
+	if err != nil {
+		t.Fatalf("mmap failed %s", err)
+	}
+	err = syscall.Mprotect(b[:pagesize], syscall.PROT_NONE)
+	if err != nil {
+		t.Fatalf("mprotect low failed %s\n", err)
+	}
+	err = syscall.Mprotect(b[2*pagesize:], syscall.PROT_NONE)
+	if err != nil {
+		t.Fatalf("mprotect high failed %s\n", err)
+	}
+	return b[pagesize : 2*pagesize]
+}
+
+func TestEqualNearPageBoundary(t *testing.T) {
+	t.Parallel()
+	b := dangerousSlice(t)
+	for i := range b {
+		b[i] = 'A'
+	}
+	for i := 0; i <= len(b); i++ {
+		Equal(b[:i], b[len(b)-i:])
+		Equal(b[len(b)-i:], b[:i])
+	}
+}
+
+func TestIndexByteNearPageBoundary(t *testing.T) {
+	t.Parallel()
+	b := dangerousSlice(t)
+	for i := range b {
+		idx := IndexByte(b[i:], 1)
+		if idx != -1 {
+			t.Fatalf("IndexByte(b[%d:])=%d, want -1\n", i, idx)
+		}
+	}
+}
+
+func TestIndexNearPageBoundary(t *testing.T) {
+	t.Parallel()
+	var q [64]byte
+	b := dangerousSlice(t)
+	if len(b) > 256 {
+		// Only worry about when we're near the end of a page.
+		b = b[len(b)-256:]
+	}
+	for j := 1; j < len(q); j++ {
+		q[j-1] = 1 // difference is only found on the last byte
+		for i := range b {
+			idx := Index(b[i:], q[:j])
+			if idx != -1 {
+				t.Fatalf("Index(b[%d:], q[:%d])=%d, want -1\n", i, j, idx)
+			}
+		}
+		q[j-1] = 0
+	}
+}
diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go
index 20e42bb..dc9d5e9 100644
--- a/src/bytes/buffer.go
+++ b/src/bytes/buffer.go
@@ -15,34 +15,37 @@
 // A Buffer is a variable-sized buffer of bytes with Read and Write methods.
 // The zero value for Buffer is an empty buffer ready to use.
 type Buffer struct {
-	buf      []byte // contents are the bytes buf[off : len(buf)]
-	off      int    // read at &buf[off], write at &buf[len(buf)]
-	lastRead readOp // last read operation, so that Unread* can work correctly.
-	// FIXME: lastRead can fit in a single byte
+	buf       []byte   // contents are the bytes buf[off : len(buf)]
+	off       int      // read at &buf[off], write at &buf[len(buf)]
+	bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
+	lastRead  readOp   // last read operation, so that Unread* can work correctly.
 
-	// memory to hold first slice; helps small buffers avoid allocation.
 	// FIXME: it would be advisable to align Buffer to cachelines to avoid false
 	// sharing.
-	bootstrap [64]byte
 }
 
 // The readOp constants describe the last action performed on
 // the buffer, so that UnreadRune and UnreadByte can check for
 // invalid usage. opReadRuneX constants are chosen such that
 // converted to int they correspond to the rune size that was read.
-type readOp int
+type readOp int8
 
+// Don't use iota for these, as the values need to correspond with the
+// names and comments, which is easier to see when being explicit.
 const (
 	opRead      readOp = -1 // Any other read operation.
-	opInvalid          = 0  // Non-read operation.
-	opReadRune1        = 1  // Read rune of size 1.
-	opReadRune2        = 2  // Read rune of size 2.
-	opReadRune3        = 3  // Read rune of size 3.
-	opReadRune4        = 4  // Read rune of size 4.
+	opInvalid   readOp = 0  // Non-read operation.
+	opReadRune1 readOp = 1  // Read rune of size 1.
+	opReadRune2 readOp = 2  // Read rune of size 2.
+	opReadRune3 readOp = 3  // Read rune of size 3.
+	opReadRune4 readOp = 4  // Read rune of size 4.
 )
 
 // ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
 var ErrTooLarge = errors.New("bytes.Buffer: too large")
+var errNegativeRead = errors.New("bytes.Buffer: reader returned negative count from Read")
+
+const maxInt = int(^uint(0) >> 1)
 
 // Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
 // The slice is valid for use only until the next buffer modification (that is,
@@ -53,6 +56,8 @@
 
 // String returns the contents of the unread portion of the buffer
 // as a string. If the Buffer is a nil pointer, it returns "<nil>".
+//
+// To build strings more efficiently, see the strings.Builder type.
 func (b *Buffer) String() string {
 	if b == nil {
 		// Special case, useful in debugging.
@@ -61,6 +66,9 @@
 	return string(b.buf[b.off:])
 }
 
+// empty returns whether the unread portion of the buffer is empty.
+func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
+
 // Len returns the number of bytes of the unread portion of the buffer;
 // b.Len() == len(b.Bytes()).
 func (b *Buffer) Len() int { return len(b.buf) - b.off }
@@ -81,7 +89,7 @@
 	if n < 0 || n > b.Len() {
 		panic("bytes.Buffer: truncation out of range")
 	}
-	b.buf = b.buf[0 : b.off+n]
+	b.buf = b.buf[:b.off+n]
 }
 
 // Reset resets the buffer to be empty,
@@ -97,7 +105,7 @@
 // internal buffer only needs to be resliced.
 // It returns the index where bytes should be written and whether it succeeded.
 func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
-	if l := len(b.buf); l+n <= cap(b.buf) {
+	if l := len(b.buf); n <= cap(b.buf)-l {
 		b.buf = b.buf[:l+n]
 		return l, true
 	}
@@ -122,15 +130,18 @@
 		b.buf = b.bootstrap[:n]
 		return 0
 	}
-	if m+n <= cap(b.buf)/2 {
+	c := cap(b.buf)
+	if n <= c/2-m {
 		// We can slide things down instead of allocating a new
-		// slice. We only need m+n <= cap(b.buf) to slide, but
+		// slice. We only need m+n <= c to slide, but
 		// we instead let capacity get twice as large so we
 		// don't spend all our time copying.
-		copy(b.buf[:], b.buf[b.off:])
+		copy(b.buf, b.buf[b.off:])
+	} else if c > maxInt-c-n {
+		panic(ErrTooLarge)
 	} else {
 		// Not enough space anywhere, we need to allocate.
-		buf := makeSlice(2*cap(b.buf) + n)
+		buf := makeSlice(2*c + n)
 		copy(buf, b.buf[b.off:])
 		b.buf = buf
 	}
@@ -150,7 +161,7 @@
 		panic("bytes.Buffer.Grow: negative count")
 	}
 	m := b.grow(n)
-	b.buf = b.buf[0:m]
+	b.buf = b.buf[:m]
 }
 
 // Write appends the contents of p to the buffer, growing the buffer as
@@ -189,34 +200,22 @@
 // buffer becomes too large, ReadFrom will panic with ErrTooLarge.
 func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
 	b.lastRead = opInvalid
-	// If buffer is empty, reset to recover space.
-	if b.off >= len(b.buf) {
-		b.Reset()
-	}
 	for {
-		if free := cap(b.buf) - len(b.buf); free < MinRead {
-			// not enough space at end
-			newBuf := b.buf
-			if b.off+free < MinRead {
-				// not enough space using beginning of buffer;
-				// double buffer capacity
-				newBuf = makeSlice(2*cap(b.buf) + MinRead)
-			}
-			copy(newBuf, b.buf[b.off:])
-			b.buf = newBuf[:len(b.buf)-b.off]
-			b.off = 0
+		i := b.grow(MinRead)
+		m, e := r.Read(b.buf[i:cap(b.buf)])
+		if m < 0 {
+			panic(errNegativeRead)
 		}
-		m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
-		b.buf = b.buf[0 : len(b.buf)+m]
+
+		b.buf = b.buf[:i+m]
 		n += int64(m)
 		if e == io.EOF {
-			break
+			return n, nil // e is EOF, so return nil explicitly
 		}
 		if e != nil {
 			return n, e
 		}
 	}
-	return n, nil // err is EOF, so return nil explicitly
 }
 
 // makeSlice allocates a slice of size n. If the allocation fails, it panics
@@ -237,8 +236,7 @@
 // encountered during the write is also returned.
 func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
 	b.lastRead = opInvalid
-	if b.off < len(b.buf) {
-		nBytes := b.Len()
+	if nBytes := b.Len(); nBytes > 0 {
 		m, e := w.Write(b.buf[b.off:])
 		if m > nBytes {
 			panic("bytes.Buffer.WriteTo: invalid Write count")
@@ -256,7 +254,7 @@
 	}
 	// Buffer is now empty; reset.
 	b.Reset()
-	return
+	return n, nil
 }
 
 // WriteByte appends the byte c to the buffer, growing the buffer as needed.
@@ -298,11 +296,11 @@
 // otherwise it is nil.
 func (b *Buffer) Read(p []byte) (n int, err error) {
 	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
+	if b.empty() {
 		// Buffer is empty, reset to recover space.
 		b.Reset()
 		if len(p) == 0 {
-			return
+			return 0, nil
 		}
 		return 0, io.EOF
 	}
@@ -311,7 +309,7 @@
 	if n > 0 {
 		b.lastRead = opRead
 	}
-	return
+	return n, nil
 }
 
 // Next returns a slice containing the next n bytes from the buffer,
@@ -335,8 +333,7 @@
 // ReadByte reads and returns the next byte from the buffer.
 // If no byte is available, it returns error io.EOF.
 func (b *Buffer) ReadByte() (byte, error) {
-	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
+	if b.empty() {
 		// Buffer is empty, reset to recover space.
 		b.Reset()
 		return 0, io.EOF
@@ -353,8 +350,7 @@
 // If the bytes are an erroneous UTF-8 encoding, it
 // consumes one byte and returns U+FFFD, 1.
 func (b *Buffer) ReadRune() (r rune, size int, err error) {
-	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
+	if b.empty() {
 		// Buffer is empty, reset to recover space.
 		b.Reset()
 		return 0, 0, io.EOF
@@ -413,7 +409,7 @@
 	// return a copy of slice. The buffer's backing array may
 	// be overwritten by later calls.
 	line = append(line, slice...)
-	return
+	return line, err
 }
 
 // readSlice is like ReadBytes but returns a reference to internal buffer data.
diff --git a/src/bytes/buffer_test.go b/src/bytes/buffer_test.go
index ce2f01a..e4bbc12 100644
--- a/src/bytes/buffer_test.go
+++ b/src/bytes/buffer_test.go
@@ -6,25 +6,27 @@
 
 import (
 	. "bytes"
-	"internal/testenv"
 	"io"
 	"math/rand"
-	"os/exec"
 	"runtime"
 	"testing"
 	"unicode/utf8"
 )
 
-const N = 10000      // make this bigger for a larger (and slower) test
-var data string      // test data for write tests
-var testBytes []byte // test data; same as data but as a slice.
+const N = 10000       // make this bigger for a larger (and slower) test
+var testString string // test data for write tests
+var testBytes []byte  // test data; same as testString but as a slice.
+
+type negativeReader struct{}
+
+func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
 
 func init() {
 	testBytes = make([]byte, N)
 	for i := 0; i < N; i++ {
 		testBytes[i] = 'a' + byte(i%26)
 	}
-	data = string(testBytes)
+	testString = string(testBytes)
 }
 
 // Verify that contents of buf match the string s.
@@ -88,12 +90,12 @@
 
 func TestNewBuffer(t *testing.T) {
 	buf := NewBuffer(testBytes)
-	check(t, "NewBuffer", buf, data)
+	check(t, "NewBuffer", buf, testString)
 }
 
 func TestNewBufferString(t *testing.T) {
-	buf := NewBufferString(data)
-	check(t, "NewBufferString", buf, data)
+	buf := NewBufferString(testString)
+	check(t, "NewBufferString", buf, testString)
 }
 
 // Empty buf through repeated reads into fub.
@@ -128,7 +130,7 @@
 		buf.Truncate(0)
 		check(t, "TestBasicOperations (3)", &buf, "")
 
-		n, err := buf.Write([]byte(data[0:1]))
+		n, err := buf.Write(testBytes[0:1])
 		if n != 1 {
 			t.Errorf("wrote 1 byte, but n == %d", n)
 		}
@@ -137,30 +139,30 @@
 		}
 		check(t, "TestBasicOperations (4)", &buf, "a")
 
-		buf.WriteByte(data[1])
+		buf.WriteByte(testString[1])
 		check(t, "TestBasicOperations (5)", &buf, "ab")
 
-		n, err = buf.Write([]byte(data[2:26]))
+		n, err = buf.Write(testBytes[2:26])
 		if n != 24 {
-			t.Errorf("wrote 25 bytes, but n == %d", n)
+			t.Errorf("wrote 24 bytes, but n == %d", n)
 		}
-		check(t, "TestBasicOperations (6)", &buf, string(data[0:26]))
+		check(t, "TestBasicOperations (6)", &buf, testString[0:26])
 
 		buf.Truncate(26)
-		check(t, "TestBasicOperations (7)", &buf, string(data[0:26]))
+		check(t, "TestBasicOperations (7)", &buf, testString[0:26])
 
 		buf.Truncate(20)
-		check(t, "TestBasicOperations (8)", &buf, string(data[0:20]))
+		check(t, "TestBasicOperations (8)", &buf, testString[0:20])
 
-		empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5))
+		empty(t, "TestBasicOperations (9)", &buf, testString[0:20], make([]byte, 5))
 		empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
 
-		buf.WriteByte(data[1])
+		buf.WriteByte(testString[1])
 		c, err := buf.ReadByte()
 		if err != nil {
 			t.Error("ReadByte unexpected eof")
 		}
-		if c != data[1] {
+		if c != testString[1] {
 			t.Errorf("ReadByte wrong value c=%v", c)
 		}
 		c, err = buf.ReadByte()
@@ -177,8 +179,8 @@
 		limit = 9
 	}
 	for i := 3; i < limit; i += 3 {
-		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, data)
-		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(data)/i))
+		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, testString)
+		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(testString)/i))
 	}
 	check(t, "TestLargeStringWrites (3)", &buf, "")
 }
@@ -191,7 +193,7 @@
 	}
 	for i := 3; i < limit; i += 3 {
 		s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
-		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))
+		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(testString)/i))
 	}
 	check(t, "TestLargeByteWrites (3)", &buf, "")
 }
@@ -199,8 +201,8 @@
 func TestLargeStringReads(t *testing.T) {
 	var buf Buffer
 	for i := 3; i < 30; i += 3 {
-		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, data[0:len(data)/i])
-		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
+		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, testString[0:len(testString)/i])
+		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
 	}
 	check(t, "TestLargeStringReads (3)", &buf, "")
 }
@@ -209,7 +211,7 @@
 	var buf Buffer
 	for i := 3; i < 30; i += 3 {
 		s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
-		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
+		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
 	}
 	check(t, "TestLargeByteReads (3)", &buf, "")
 }
@@ -218,14 +220,14 @@
 	var buf Buffer
 	s := ""
 	for i := 0; i < 50; i++ {
-		wlen := rand.Intn(len(data))
+		wlen := rand.Intn(len(testString))
 		if i%2 == 0 {
-			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, data[0:wlen])
+			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testString[0:wlen])
 		} else {
 			s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
 		}
 
-		rlen := rand.Intn(len(data))
+		rlen := rand.Intn(len(testString))
 		fub := make([]byte, rlen)
 		n, _ := buf.Read(fub)
 		s = s[n:]
@@ -263,17 +265,37 @@
 		s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
 		var b Buffer
 		b.ReadFrom(&buf)
-		empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
+		empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(testString)))
 	}
 }
 
+func TestReadFromNegativeReader(t *testing.T) {
+	var b Buffer
+	defer func() {
+		switch err := recover().(type) {
+		case nil:
+			t.Fatal("bytes.Buffer.ReadFrom didn't panic")
+		case error:
+			// this is the error string of errNegativeRead
+			wantError := "bytes.Buffer: reader returned negative count from Read"
+			if err.Error() != wantError {
+				t.Fatalf("recovered panic: got %v, want %v", err.Error(), wantError)
+			}
+		default:
+			t.Fatalf("unexpected panic value: %#v", err)
+		}
+	}()
+
+	b.ReadFrom(new(negativeReader))
+}
+
 func TestWriteTo(t *testing.T) {
 	var buf Buffer
 	for i := 3; i < 30; i += 3 {
 		s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
 		var b Buffer
 		buf.WriteTo(&b)
-		empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
+		empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(testString)))
 	}
 }
 
@@ -473,6 +495,18 @@
 	}
 }
 
+func TestGrowOverflow(t *testing.T) {
+	defer func() {
+		if err := recover(); err != ErrTooLarge {
+			t.Errorf("after too-large Grow, recover() = %v; want %v", err, ErrTooLarge)
+		}
+	}()
+
+	buf := NewBuffer(make([]byte, 1))
+	const maxInt = int(^uint(0) >> 1)
+	buf.Grow(maxInt)
+}
+
 // Was a bug: used to give EOF reading empty slice at EOF.
 func TestReadEmptyAtEOF(t *testing.T) {
 	b := new(Buffer)
@@ -548,26 +582,6 @@
 	}
 }
 
-// Test that tryGrowByReslice is inlined.
-// Only execute on "linux-amd64" builder in order to avoid breakage.
-func TestTryGrowByResliceInlined(t *testing.T) {
-	targetBuilder := "linux-amd64"
-	if testenv.Builder() != targetBuilder {
-		t.Skipf("%q gets executed on %q builder only", t.Name(), targetBuilder)
-	}
-	t.Parallel()
-	goBin := testenv.GoToolPath(t)
-	out, err := exec.Command(goBin, "tool", "nm", goBin).CombinedOutput()
-	if err != nil {
-		t.Fatalf("go tool nm: %v: %s", err, out)
-	}
-	// Verify this doesn't exist:
-	sym := "bytes.(*Buffer).tryGrowByReslice"
-	if Contains(out, []byte(sym)) {
-		t.Errorf("found symbol %q in cmd/go, but should be inlined", sym)
-	}
-}
-
 func BenchmarkWriteByte(b *testing.B) {
 	const n = 4 << 10
 	b.SetBytes(n)
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
index 7c878af..9af177f 100644
--- a/src/bytes/bytes.go
+++ b/src/bytes/bytes.go
@@ -39,7 +39,7 @@
 			break
 		}
 		_, size = utf8.DecodeRune(s)
-		a[na] = s[0:size]
+		a[na] = s[0:size:size]
 		s = s[size:]
 		na++
 	}
@@ -68,12 +68,12 @@
 	return Index(b, subslice) != -1
 }
 
-// ContainsAny reports whether any of the UTF-8-encoded Unicode code points in chars are within b.
+// ContainsAny reports whether any of the UTF-8-encoded code points in chars are within b.
 func ContainsAny(b []byte, chars string) bool {
 	return IndexAny(b, chars) >= 0
 }
 
-// ContainsRune reports whether the Unicode code point r is within b.
+// ContainsRune reports whether the rune is contained in the UTF-8-encoded byte slice b.
 func ContainsRune(b []byte, r rune) bool {
 	return IndexRune(b, r) >= 0
 }
@@ -112,7 +112,7 @@
 	return -1
 }
 
-// IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
+// IndexRune interprets s as a sequence of UTF-8-encoded 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.
 // If r is utf8.RuneError, it returns the first instance of any
@@ -144,30 +144,32 @@
 // 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 {
-		if len(s) > 8 {
-			if as, isASCII := makeASCIISet(chars); isASCII {
-				for i, c := range s {
-					if as.contains(c) {
-						return i
-					}
-				}
-				return -1
-			}
-		}
-		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 {
+	if chars == "" {
+		// Avoid scanning all of s.
+		return -1
+	}
+	if len(s) > 8 {
+		if as, isASCII := makeASCIISet(chars); isASCII {
+			for i, c := range s {
+				if as.contains(c) {
 					return i
 				}
 			}
+			return -1
+		}
+	}
+	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
@@ -178,25 +180,27 @@
 // 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 {
-		if len(s) > 8 {
-			if as, isASCII := makeASCIISet(chars); isASCII {
-				for i := len(s) - 1; i >= 0; i-- {
-					if as.contains(s[i]) {
-						return i
-					}
-				}
-				return -1
-			}
-		}
-		for i := len(s); i > 0; {
-			r, size := utf8.DecodeLastRune(s[:i])
-			i -= size
-			for _, c := range chars {
-				if r == c {
+	if chars == "" {
+		// Avoid scanning all of s.
+		return -1
+	}
+	if len(s) > 8 {
+		if as, isASCII := makeASCIISet(chars); isASCII {
+			for i := len(s) - 1; i >= 0; i-- {
+				if as.contains(s[i]) {
 					return i
 				}
 			}
+			return -1
+		}
+	}
+	for i := len(s); i > 0; {
+		r, size := utf8.DecodeLastRune(s[:i])
+		i -= size
+		for _, c := range chars {
+			if r == c {
+				return i
+			}
 		}
 	}
 	return -1
@@ -223,7 +227,7 @@
 		if m < 0 {
 			break
 		}
-		a[i] = s[:m+sepSave]
+		a[i] = s[: m+sepSave : m+sepSave]
 		s = s[m+len(sep):]
 		i++
 	}
@@ -265,52 +269,112 @@
 	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.
+var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
+
+// Fields interprets s as a sequence of UTF-8-encoded code points.
+// It splits the slice s around each instance of one or more consecutive white space
+// characters, as defined by unicode.IsSpace, returning a slice of subslices of s or an
+// empty slice if s contains only white space.
 func Fields(s []byte) [][]byte {
-	return FieldsFunc(s, unicode.IsSpace)
+	// First count the fields.
+	// This is an exact count if s is ASCII, otherwise it is an approximation.
+	n := 0
+	wasSpace := 1
+	// setBits is used to track which bits are set in the bytes of s.
+	setBits := uint8(0)
+	for i := 0; i < len(s); i++ {
+		r := s[i]
+		setBits |= r
+		isSpace := int(asciiSpace[r])
+		n += wasSpace & ^isSpace
+		wasSpace = isSpace
+	}
+
+	if setBits >= utf8.RuneSelf {
+		// Some runes in the input slice are not ASCII.
+		return FieldsFunc(s, unicode.IsSpace)
+	}
+
+	// ASCII fast path
+	a := make([][]byte, n)
+	na := 0
+	fieldStart := 0
+	i := 0
+	// Skip spaces in the front of the input.
+	for i < len(s) && asciiSpace[s[i]] != 0 {
+		i++
+	}
+	fieldStart = i
+	for i < len(s) {
+		if asciiSpace[s[i]] == 0 {
+			i++
+			continue
+		}
+		a[na] = s[fieldStart:i:i]
+		na++
+		i++
+		// Skip spaces in between fields.
+		for i < len(s) && asciiSpace[s[i]] != 0 {
+			i++
+		}
+		fieldStart = i
+	}
+	if fieldStart < len(s) { // Last field might end at EOF.
+		a[na] = s[fieldStart:len(s):len(s)]
+	}
+	return a
 }
 
-// FieldsFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
+// FieldsFunc interprets s as a sequence of UTF-8-encoded 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
+	// A span is used to record a slice of s of the form s[start:end].
+	// The start index is inclusive and the end index is exclusive.
+	type span struct {
+		start int
+		end   int
+	}
+	spans := make([]span, 0, 32)
+
+	// Find the field start and end indices.
+	wasField := false
+	fromIndex := 0
 	for i := 0; i < len(s); {
-		r, size := utf8.DecodeRune(s[i:])
-		wasInField := inField
-		inField = !f(r)
-		if inField && !wasInField {
-			n++
+		size := 1
+		r := rune(s[i])
+		if r >= utf8.RuneSelf {
+			r, size = utf8.DecodeRune(s[i:])
+		}
+		if f(r) {
+			if wasField {
+				spans = append(spans, span{start: fromIndex, end: i})
+				wasField = false
+			}
+		} else {
+			if !wasField {
+				fromIndex = i
+				wasField = true
+			}
 		}
 		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
+	// Last field might end at EOF.
+	if wasField {
+		spans = append(spans, span{fromIndex, len(s)})
 	}
-	return a[0:na]
+
+	// Create subslices from recorded field indices.
+	a := make([][]byte, len(spans))
+	for i, span := range spans {
+		a[i] = s[span.start:span.end:span.end]
+	}
+
+	return a
 }
 
 // Join concatenates the elements of s to create a new byte slice. The separator
@@ -349,8 +413,8 @@
 
 // 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.
+// dropped from the byte slice with no replacement. The characters in s and the
+// output are interpreted as UTF-8-encoded 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
@@ -408,28 +472,28 @@
 	return nb
 }
 
-// ToUpper returns a copy of the byte slice s with all Unicode letters mapped to their upper case.
+// ToUpper treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters within it 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.
+// ToLower treats s as UTF-8-encoded bytes and returns a copy with all the 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.
+// ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the 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
+// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
 // upper case, giving priority to the special casing rules.
 func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
 	return Map(func(r rune) rune { return c.ToUpper(r) }, s)
 }
 
-// ToLowerSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
+// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
 // lower case, giving priority to the special casing rules.
 func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
 	return Map(func(r rune) rune { return c.ToLower(r) }, s)
 }
 
-// ToTitleSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
+// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
 // title case, giving priority to the special casing rules.
 func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
 	return Map(func(r rune) rune { return c.ToTitle(r) }, s)
@@ -460,8 +524,8 @@
 	return unicode.IsSpace(r)
 }
 
-// Title returns a copy of s with all Unicode letters that begin words
-// mapped to their title case.
+// Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
+// words mapped to their title case.
 //
 // BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
 func Title(s []byte) []byte {
@@ -481,8 +545,8 @@
 		s)
 }
 
-// TrimLeftFunc returns a subslice of s by slicing off all leading UTF-8-encoded
-// Unicode code points c that satisfy f(c).
+// TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
+// all leading UTF-8-encoded 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 {
@@ -491,8 +555,8 @@
 	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).
+// TrimRightFunc returns a subslice of s by slicing off all trailing
+// UTF-8-encoded 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 {
@@ -505,7 +569,7 @@
 }
 
 // TrimFunc returns a subslice of s by slicing off all leading and trailing
-// UTF-8-encoded Unicode code points c that satisfy f(c).
+// UTF-8-encoded code points c that satisfy f(c).
 func TrimFunc(s []byte, f func(r rune) bool) []byte {
 	return TrimRightFunc(TrimLeftFunc(s, f), f)
 }
@@ -528,14 +592,14 @@
 	return s
 }
 
-// IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
+// IndexFunc interprets s as a sequence of UTF-8-encoded 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.
+// LastIndexFunc interprets s as a sequence of UTF-8-encoded 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 {
@@ -626,19 +690,19 @@
 }
 
 // Trim returns a subslice of s by slicing off all leading and
-// trailing UTF-8-encoded Unicode code points contained in cutset.
+// trailing UTF-8-encoded 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.
+// UTF-8-encoded 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.
+// UTF-8-encoded code points that are contained in cutset.
 func TrimRight(s []byte, cutset string) []byte {
 	return TrimRightFunc(s, makeCutsetFunc(cutset))
 }
@@ -649,7 +713,8 @@
 	return TrimFunc(s, unicode.IsSpace)
 }
 
-// Runes returns a slice of runes (Unicode code points) equivalent to s.
+// Runes interprets s as a sequence of UTF-8-encoded code points.
+// It returns a slice of runes (Unicode code points) equivalent to s.
 func Runes(s []byte) []rune {
 	t := make([]rune, utf8.RuneCount(s))
 	i := 0
@@ -758,3 +823,46 @@
 	// One string is empty. Are both?
 	return len(s) == len(t)
 }
+
+func indexRabinKarp(s, sep []byte) int {
+	// Rabin-Karp search
+	hashsep, pow := hashStr(sep)
+	n := len(sep)
+	var h uint32
+	for i := 0; i < n; i++ {
+		h = h*primeRK + uint32(s[i])
+	}
+	if h == hashsep && Equal(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 && Equal(s[i-n:i], sep) {
+			return i - n
+		}
+	}
+	return -1
+}
+
+// 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 []byte) (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
+}
diff --git a/src/bytes/bytes_amd64.go b/src/bytes/bytes_amd64.go
index 77d5970..0c9d613 100644
--- a/src/bytes/bytes_amd64.go
+++ b/src/bytes/bytes_amd64.go
@@ -75,52 +75,14 @@
 		}
 		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 && Equal(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 && Equal(s[i-n:i], sep) {
-			return i - n
-		}
-	}
-	return -1
+	return indexRabinKarp(s, sep)
 }
 
 // Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
 func Count(s, sep []byte) int {
 	if len(sep) == 1 && cpu.X86.HasPOPCNT {
 		return countByte(s, sep[0])
 	}
 	return countGeneric(s, sep)
 }
-
-// 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 []byte) (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
-}
diff --git a/src/bytes/bytes_arm64.go b/src/bytes/bytes_arm64.go
new file mode 100644
index 0000000..846eeba
--- /dev/null
+++ b/src/bytes/bytes_arm64.go
@@ -0,0 +1,68 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bytes
+
+func countByte(s []byte, c byte) int // bytes_arm64.s
+
+// 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)
+	switch {
+	case n == 0:
+		return 0
+	case n == 1:
+		return IndexByte(s, sep[0])
+	case n == len(s):
+		if Equal(sep, s) {
+			return 0
+		}
+		return -1
+	case n > len(s):
+		return -1
+	}
+	c := sep[0]
+	i := 0
+	fails := 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++
+		fails++
+		if fails >= 4+i>>4 && i < len(t) {
+			// Give up on IndexByte, it isn't skipping ahead
+			// far enough to be better than Rabin-Karp.
+			// Experiments (using IndexPeriodic) suggest
+			// the cutover is about 16 byte skips.
+			// TODO: if large prefixes of sep are matching
+			// we should cutover at even larger average skips,
+			// because Equal becomes that much more expensive.
+			// This code does not take that effect into account.
+			j := indexRabinKarp(s[i:], sep)
+			if j < 0 {
+				return -1
+			}
+			return i + j
+		}
+	}
+	return -1
+}
+
+// Count counts the number of non-overlapping instances of sep in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
+func Count(s, sep []byte) int {
+	if len(sep) == 1 {
+		return countByte(s, sep[0])
+	}
+	return countGeneric(s, sep)
+}
diff --git a/src/bytes/bytes_arm64.s b/src/bytes/bytes_arm64.s
new file mode 100644
index 0000000..5e229d7
--- /dev/null
+++ b/src/bytes/bytes_arm64.s
@@ -0,0 +1,74 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// countByte(s []byte, c byte) int
+TEXT bytes·countByte(SB),NOSPLIT,$0-40
+	MOVD	s_base+0(FP), R0
+	MOVD	s_len+8(FP), R2
+	MOVBU	c+24(FP), R1
+	// R11 = count of byte to search
+	MOVD	$0, R11
+	// short path to handle 0-byte case
+	CBZ	R2, done
+	CMP	$0x20, R2
+	// jump directly to tail if length < 32
+	BLO	tail
+	ANDS	$0x1f, R0, R9
+	BEQ	chunk
+	// Work with not 32-byte aligned head
+	BIC	$0x1f, R0, R3
+	ADD	$0x20, R3
+head_loop:
+	MOVBU.P	1(R0), R5
+	CMP	R5, R1
+	CINC	EQ, R11, R11
+	SUB	$1, R2, R2
+	CMP	R0, R3
+	BNE	head_loop
+	// Work with 32-byte aligned chunks
+chunk:
+	BIC	$0x1f, R2, R9
+	// The first chunk can also be the last
+	CBZ	R9, tail
+	// R3 = end of 32-byte chunks
+	ADD	R0, R9, R3
+	MOVD	$1, R5
+	VMOV	R5, V5.B16
+	// R2 = length of tail
+	SUB	R9, R2, R2
+	// Duplicate R1 (byte to search) to 16 1-byte elements of V0
+	VMOV	R1, V0.B16
+	// Clear the low 64-bit element of V7 and V8
+	VEOR	V7.B8, V7.B8, V7.B8
+	VEOR	V8.B8, V8.B8, V8.B8
+	// Count the target byte in 32-byte chunk
+chunk_loop:
+	VLD1.P	(R0), [V1.B16, V2.B16]
+	CMP	R0, R3
+	VCMEQ	V0.B16, V1.B16, V3.B16
+	VCMEQ	V0.B16, V2.B16, V4.B16
+	// Clear the higher 7 bits
+	VAND	V5.B16, V3.B16, V3.B16
+	VAND	V5.B16, V4.B16, V4.B16
+	// Count lanes match the requested byte
+	VADDP	V4.B16, V3.B16, V6.B16 // 32B->16B
+	VUADDLV	V6.B16, V7
+	// Accumulate the count in low 64-bit element of V8 when inside the loop
+	VADD	V7, V8
+	BNE	chunk_loop
+	VMOV	V8.D[0], R6
+	ADD	R6, R11, R11
+	CBZ	R2, done
+tail:
+	// Work with tail shorter than 32 bytes
+	MOVBU.P	1(R0), R5
+	SUB	$1, R2, R2
+	CMP	R5, R1
+	CINC	EQ, R11, R11
+	CBNZ	R2, tail
+done:
+	MOVD	R11, ret+32(FP)
+	RET
diff --git a/src/bytes/bytes_generic.go b/src/bytes/bytes_generic.go
index 98454bc..0e7d33f 100644
--- a/src/bytes/bytes_generic.go
+++ b/src/bytes/bytes_generic.go
@@ -2,27 +2,29 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!s390x
+// +build !amd64,!s390x,!arm64
 
 package bytes
 
-// TODO: implements short string optimization on non amd64 platforms
-// and get rid of bytes_amd64.go
-
 // 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 {
+	switch {
+	case n == 0:
 		return 0
-	}
-	if n > len(s) {
+	case n == 1:
+		return IndexByte(s, sep[0])
+	case n == len(s):
+		if Equal(sep, s) {
+			return 0
+		}
+		return -1
+	case n > len(s):
 		return -1
 	}
 	c := sep[0]
-	if n == 1 {
-		return IndexByte(s, c)
-	}
 	i := 0
+	fails := 0
 	t := s[:len(s)-n+1]
 	for i < len(t) {
 		if t[i] != c {
@@ -36,12 +38,28 @@
 			return i
 		}
 		i++
+		fails++
+		if fails >= 4+i>>4 && i < len(t) {
+			// Give up on IndexByte, it isn't skipping ahead
+			// far enough to be better than Rabin-Karp.
+			// Experiments (using IndexPeriodic) suggest
+			// the cutover is about 16 byte skips.
+			// TODO: if large prefixes of sep are matching
+			// we should cutover at even larger average skips,
+			// because Equal becomes that much more expensive.
+			// This code does not take that effect into account.
+			j := indexRabinKarp(s[i:], sep)
+			if j < 0 {
+				return -1
+			}
+			return i + j
+		}
 	}
 	return -1
 }
 
 // Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
 func Count(s, sep []byte) int {
 	return countGeneric(s, sep)
 }
diff --git a/src/bytes/bytes_s390x.go b/src/bytes/bytes_s390x.go
index 68b5730..c59b891 100644
--- a/src/bytes/bytes_s390x.go
+++ b/src/bytes/bytes_s390x.go
@@ -76,49 +76,11 @@
 		}
 		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 && Equal(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 && Equal(s[i-n:i], sep) {
-			return i - n
-		}
-	}
-	return -1
+	return indexRabinKarp(s, sep)
 }
 
 // Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
 func Count(s, sep []byte) int {
 	return countGeneric(s, sep)
 }
-
-// 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 []byte) (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
-}
diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
index ca0cdbb..1e56571 100644
--- a/src/bytes/bytes_test.go
+++ b/src/bytes/bytes_test.go
@@ -139,6 +139,9 @@
 	{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
 	{"foofyfoobarfoobar", "y", 4},
 	{"oooooooooooooooooooooo", "r", -1},
+	// test fallback to Rabin-Karp.
+	{"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22},
+	{"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1},
 }
 
 var lastIndexTests = []BinOpTest{
@@ -736,6 +739,13 @@
 func TestSplit(t *testing.T) {
 	for _, tt := range splittests {
 		a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
+
+		// Appending to the results should not change future results.
+		var x []byte
+		for _, v := range a {
+			x = append(v, 'z')
+		}
+
 		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)
@@ -744,6 +754,11 @@
 		if tt.n == 0 {
 			continue
 		}
+
+		if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+			t.Errorf("last appended result was %s; want %s", x, want)
+		}
+
 		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)
@@ -782,11 +797,23 @@
 func TestSplitAfter(t *testing.T) {
 	for _, tt := range splitaftertests {
 		a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
+
+		// Appending to the results should not change future results.
+		var x []byte
+		for _, v := range a {
+			x = append(v, 'z')
+		}
+
 		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 want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+			t.Errorf("last appended result was %s; want %s", x, want)
+		}
+
 		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)
@@ -821,12 +848,29 @@
 
 func TestFields(t *testing.T) {
 	for _, tt := range fieldstests {
-		a := Fields([]byte(tt.s))
+		b := []byte(tt.s)
+		a := Fields(b)
+
+		// Appending to the results should not change future results.
+		var x []byte
+		for _, v := range a {
+			x = append(v, 'z')
+		}
+
 		result := sliceOfString(a)
 		if !eq(result, tt.a) {
 			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
 			continue
 		}
+
+		if string(b) != tt.s {
+			t.Errorf("slice changed to %s; want %s", string(b), tt.s)
+		}
+		if len(tt.a) > 0 {
+			if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+				t.Errorf("last appended result was %s; want %s", x, want)
+			}
+		}
 	}
 }
 
@@ -847,11 +891,28 @@
 		{"aXXbXXXcX", []string{"a", "b", "c"}},
 	}
 	for _, tt := range fieldsFuncTests {
-		a := FieldsFunc([]byte(tt.s), pred)
+		b := []byte(tt.s)
+		a := FieldsFunc(b, pred)
+
+		// Appending to the results should not change future results.
+		var x []byte
+		for _, v := range a {
+			x = append(v, 'z')
+		}
+
 		result := sliceOfString(a)
 		if !eq(result, tt.a) {
 			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
 		}
+
+		if string(b) != tt.s {
+			t.Errorf("slice changed to %s; want %s", b, tt.s)
+		}
+		if len(tt.a) > 0 {
+			if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+				t.Errorf("last appended result was %s; want %s", x, want)
+			}
+		}
 	}
 }
 
@@ -1502,19 +1563,58 @@
 	return x
 }
 
-var fieldsInput = makeFieldsInput()
+var makeFieldsInputASCII = func() []byte {
+	x := make([]byte, 1<<20)
+	// Input is ~10% space, rest ASCII non-space.
+	for i := range x {
+		if rand.Intn(10) == 0 {
+			x[i] = ' '
+		} else {
+			x[i] = 'x'
+		}
+	}
+	return x
+}
+
+var bytesdata = []struct {
+	name string
+	data []byte
+}{
+	{"ASCII", makeFieldsInputASCII()},
+	{"Mixed", makeFieldsInput()},
+}
 
 func BenchmarkFields(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		Fields(fieldsInput)
+	for _, sd := range bytesdata {
+		b.Run(sd.name, func(b *testing.B) {
+			for j := 1 << 4; j <= 1<<20; j <<= 4 {
+				b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
+					b.ReportAllocs()
+					b.SetBytes(int64(j))
+					data := sd.data[:j]
+					for i := 0; i < b.N; i++ {
+						Fields(data)
+					}
+				})
+			}
+		})
 	}
 }
 
 func BenchmarkFieldsFunc(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		FieldsFunc(fieldsInput, unicode.IsSpace)
+	for _, sd := range bytesdata {
+		b.Run(sd.name, func(b *testing.B) {
+			for j := 1 << 4; j <= 1<<20; j <<= 4 {
+				b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
+					b.ReportAllocs()
+					b.SetBytes(int64(j))
+					data := sd.data[:j]
+					for i := 0; i < b.N; i++ {
+						FieldsFunc(data, unicode.IsSpace)
+					}
+				})
+			}
+		})
 	}
 }
 
@@ -1633,3 +1733,18 @@
 		}
 	}
 }
+
+func BenchmarkIndexPeriodic(b *testing.B) {
+	key := []byte{1, 1}
+	for _, skip := range [...]int{2, 4, 8, 16, 32, 64} {
+		b.Run(fmt.Sprintf("IndexPeriodic%d", skip), func(b *testing.B) {
+			buf := make([]byte, 1<<16)
+			for i := 0; i < len(buf); i += skip {
+				buf[i] = 1
+			}
+			for i := 0; i < b.N; i++ {
+				Index(buf, key)
+			}
+		})
+	}
+}
diff --git a/src/bytes/equal_test.go b/src/bytes/equal_test.go
deleted file mode 100644
index 9fdead8..0000000
--- a/src/bytes/equal_test.go
+++ /dev/null
@@ -1,47 +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
-
-package bytes_test
-
-import (
-	. "bytes"
-	"syscall"
-	"testing"
-	"unsafe"
-)
-
-// This file tests the situation where memeq is checking
-// data very near to a page boundary. We want to make sure
-// equal does not read across the boundary and cause a page
-// fault where it shouldn't.
-
-// This test runs only on linux. The code being tested is
-// not OS-specific, so it does not need to be tested on all
-// operating systems.
-
-func TestEqualNearPageBoundary(t *testing.T) {
-	pagesize := syscall.Getpagesize()
-	b := make([]byte, 4*pagesize)
-	i := pagesize
-	for ; uintptr(unsafe.Pointer(&b[i]))%uintptr(pagesize) != 0; i++ {
-	}
-	syscall.Mprotect(b[i-pagesize:i], 0)
-	syscall.Mprotect(b[i+pagesize:i+2*pagesize], 0)
-	defer syscall.Mprotect(b[i-pagesize:i], syscall.PROT_READ|syscall.PROT_WRITE)
-	defer syscall.Mprotect(b[i+pagesize:i+2*pagesize], syscall.PROT_READ|syscall.PROT_WRITE)
-
-	// both of these should fault
-	//pagesize += int(b[i-1])
-	//pagesize += int(b[i+pagesize])
-
-	for j := 0; j < pagesize; j++ {
-		b[i+j] = 'A'
-	}
-	for j := 0; j <= pagesize; j++ {
-		Equal(b[i:i+j], b[i+pagesize-j:i+pagesize])
-		Equal(b[i+pagesize-j:i+pagesize], b[i:i+j])
-	}
-}
diff --git a/src/bytes/example_test.go b/src/bytes/example_test.go
index 9397277..5b7a460 100644
--- a/src/bytes/example_test.go
+++ b/src/bytes/example_test.go
@@ -119,6 +119,32 @@
 	// true
 }
 
+func ExampleContainsAny() {
+	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), "fÄo!"))
+	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), "去是伟大的."))
+	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), ""))
+	fmt.Println(bytes.ContainsAny([]byte(""), ""))
+	// Output:
+	// true
+	// true
+	// false
+	// false
+}
+
+func ExampleContainsRune() {
+	fmt.Println(bytes.ContainsRune([]byte("I like seafood."), 'f'))
+	fmt.Println(bytes.ContainsRune([]byte("I like seafood."), 'ö'))
+	fmt.Println(bytes.ContainsRune([]byte("去是伟大的!"), '大'))
+	fmt.Println(bytes.ContainsRune([]byte("去是伟大的!"), '!'))
+	fmt.Println(bytes.ContainsRune([]byte(""), '@'))
+	// Output:
+	// true
+	// false
+	// true
+	// true
+	// false
+}
+
 func ExampleCount() {
 	fmt.Println(bytes.Count([]byte("cheese"), []byte("e")))
 	fmt.Println(bytes.Count([]byte("five"), []byte(""))) // before & after each rune
@@ -127,6 +153,14 @@
 	// 5
 }
 
+func ExampleEqual() {
+	fmt.Println(bytes.Equal([]byte("Go"), []byte("Go")))
+	fmt.Println(bytes.Equal([]byte("Go"), []byte("C++")))
+	// Output:
+	// true
+	// false
+}
+
 func ExampleEqualFold() {
 	fmt.Println(bytes.EqualFold([]byte("Go"), []byte("go")))
 	// Output: true
@@ -162,6 +196,14 @@
 	// -1
 }
 
+func ExampleIndexByte() {
+	fmt.Println(bytes.IndexByte([]byte("chicken"), byte('k')))
+	fmt.Println(bytes.IndexByte([]byte("chicken"), byte('g')))
+	// Output:
+	// 4
+	// -1
+}
+
 func ExampleIndexFunc() {
 	f := func(c rune) bool {
 		return unicode.Is(unicode.Han, c)
@@ -199,6 +241,36 @@
 	// -1
 }
 
+func ExampleLastIndexAny() {
+	fmt.Println(bytes.LastIndexAny([]byte("go gopher"), "MüQp"))
+	fmt.Println(bytes.LastIndexAny([]byte("go 地鼠"), "地大"))
+	fmt.Println(bytes.LastIndexAny([]byte("go gopher"), "z,!."))
+	// Output:
+	// 5
+	// 3
+	// -1
+}
+
+func ExampleLastIndexByte() {
+	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('g')))
+	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('r')))
+	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('z')))
+	// Output:
+	// 3
+	// 8
+	// -1
+}
+
+func ExampleLastIndexFunc() {
+	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsLetter))
+	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsPunct))
+	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsNumber))
+	// Output:
+	// 8
+	// 9
+	// -1
+}
+
 func ExampleJoin() {
 	s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
 	fmt.Printf("%s", bytes.Join(s, []byte(", ")))
@@ -218,6 +290,23 @@
 	// moo moo moo
 }
 
+func ExampleRunes() {
+	rs := bytes.Runes([]byte("go gopher"))
+	for _, r := range rs {
+		fmt.Printf("%#U\n", r)
+	}
+	// Output:
+	// U+0067 'g'
+	// U+006F 'o'
+	// U+0020 ' '
+	// U+0067 'g'
+	// U+006F 'o'
+	// U+0070 'p'
+	// U+0068 'h'
+	// U+0065 'e'
+	// U+0072 'r'
+}
+
 func ExampleSplit() {
 	fmt.Printf("%q\n", bytes.Split([]byte("a,b,c"), []byte(",")))
 	fmt.Printf("%q\n", bytes.Split([]byte("a man a plan a canal panama"), []byte("a ")))
@@ -267,6 +356,18 @@
 	// Output: ["Achtung! Achtung"]
 }
 
+func ExampleTrimFunc() {
+	fmt.Println(string(bytes.TrimFunc([]byte("go-gopher!"), unicode.IsLetter)))
+	fmt.Println(string(bytes.TrimFunc([]byte("\"go-gopher!\""), unicode.IsLetter)))
+	fmt.Println(string(bytes.TrimFunc([]byte("go-gopher!"), unicode.IsPunct)))
+	fmt.Println(string(bytes.TrimFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
+	// Output:
+	// -gopher!
+	// "go-gopher!"
+	// go-gopher
+	// go-gopher!
+}
+
 func ExampleMap() {
 	rot13 := func(r rune) rune {
 		switch {
@@ -281,11 +382,43 @@
 	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
 }
 
+func ExampleTrimLeft() {
+	fmt.Print(string(bytes.TrimLeft([]byte("453gopher8257"), "0123456789")))
+	// Output:
+	// gopher8257
+}
+
+func ExampleTrimLeftFunc() {
+	fmt.Println(string(bytes.TrimLeftFunc([]byte("go-gopher"), unicode.IsLetter)))
+	fmt.Println(string(bytes.TrimLeftFunc([]byte("go-gopher!"), unicode.IsPunct)))
+	fmt.Println(string(bytes.TrimLeftFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
+	// Output:
+	// -gopher
+	// go-gopher!
+	// go-gopher!567
+}
+
 func ExampleTrimSpace() {
 	fmt.Printf("%s", bytes.TrimSpace([]byte(" \t\n a lone gopher \n\t\r\n")))
 	// Output: a lone gopher
 }
 
+func ExampleTrimRight() {
+	fmt.Print(string(bytes.TrimRight([]byte("453gopher8257"), "0123456789")))
+	// Output:
+	// 453gopher
+}
+
+func ExampleTrimRightFunc() {
+	fmt.Println(string(bytes.TrimRightFunc([]byte("go-gopher"), unicode.IsLetter)))
+	fmt.Println(string(bytes.TrimRightFunc([]byte("go-gopher!"), unicode.IsPunct)))
+	fmt.Println(string(bytes.TrimRightFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
+	// Output:
+	// go-
+	// go-gopher
+	// 1234go-gopher!
+}
+
 func ExampleToUpper() {
 	fmt.Printf("%s", bytes.ToUpper([]byte("Gopher")))
 	// Output: GOPHER
@@ -295,3 +428,11 @@
 	fmt.Printf("%s", bytes.ToLower([]byte("Gopher")))
 	// Output: gopher
 }
+
+func ExampleReader_Len() {
+	fmt.Println(bytes.NewReader([]byte("Hi!")).Len())
+	fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len())
+	// Output:
+	// 3
+	// 16
+}
diff --git a/src/bytes/reader.go b/src/bytes/reader.go
index 28cfc7a..08464c2 100644
--- a/src/bytes/reader.go
+++ b/src/bytes/reader.go
@@ -35,6 +35,7 @@
 // to any other method.
 func (r *Reader) Size() int64 { return int64(len(r.s)) }
 
+// Read implements the io.Reader interface.
 func (r *Reader) Read(b []byte) (n int, err error) {
 	if r.i >= int64(len(r.s)) {
 		return 0, io.EOF
@@ -45,6 +46,7 @@
 	return
 }
 
+// ReadAt implements the io.ReaderAt interface.
 func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
 	// cannot modify state - see io.ReaderAt
 	if off < 0 {
@@ -60,6 +62,7 @@
 	return
 }
 
+// ReadByte implements the io.ByteReader interface.
 func (r *Reader) ReadByte() (byte, error) {
 	r.prevRune = -1
 	if r.i >= int64(len(r.s)) {
@@ -70,6 +73,7 @@
 	return b, nil
 }
 
+// UnreadByte complements ReadByte in implementing the io.ByteScanner interface.
 func (r *Reader) UnreadByte() error {
 	r.prevRune = -1
 	if r.i <= 0 {
@@ -79,6 +83,7 @@
 	return nil
 }
 
+// ReadRune implements the io.RuneReader interface.
 func (r *Reader) ReadRune() (ch rune, size int, err error) {
 	if r.i >= int64(len(r.s)) {
 		r.prevRune = -1
@@ -94,6 +99,7 @@
 	return
 }
 
+// UnreadRune complements ReadRune in implementing the io.RuneScanner interface.
 func (r *Reader) UnreadRune() error {
 	if r.prevRune < 0 {
 		return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune")
diff --git a/src/bytes/reader_test.go b/src/bytes/reader_test.go
index 7b3034d..8806876 100644
--- a/src/bytes/reader_test.go
+++ b/src/bytes/reader_test.go
@@ -140,9 +140,9 @@
 	for i := 0; i < 30; i += 3 {
 		var l int
 		if i > 0 {
-			l = len(data) / i
+			l = len(testString) / i
 		}
-		s := data[:l]
+		s := testString[:l]
 		r := NewReader(testBytes[:l])
 		var b Buffer
 		n, err := r.WriteTo(&b)
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index 936f9e5..8cc78c0 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -27,6 +27,18 @@
 	"strings"
 )
 
+func goCmd() string {
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
+	if _, err := os.Stat(path); err == nil {
+		return path
+	}
+	return "go"
+}
+
 // Flags
 var (
 	checkFile  = flag.String("c", "", "optional comma-separated filename(s) to check API against")
@@ -127,7 +139,7 @@
 	if flag.NArg() > 0 {
 		pkgNames = flag.Args()
 	} else {
-		stds, err := exec.Command("go", "list", "std").Output()
+		stds, err := exec.Command(goCmd(), "list", "std").Output()
 		if err != nil {
 			log.Fatal(err)
 		}
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
index 0d00f6a..3c4e50a 100644
--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -9,6 +9,7 @@
 	"flag"
 	"fmt"
 	"go/build"
+	"internal/testenv"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -163,7 +164,7 @@
 }
 
 func BenchmarkAll(b *testing.B) {
-	stds, err := exec.Command("go", "list", "std").Output()
+	stds, err := exec.Command(testenv.GoToolPath(b), "list", "std").Output()
 	if err != nil {
 		b.Fatal(err)
 	}
diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go
index 20cddb7..a36f117 100644
--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -14,8 +14,22 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
+	"strings"
 )
 
+func goCmd() string {
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
+	if _, err := os.Stat(path); err == nil {
+		return path
+	}
+	return "go"
+}
+
 var goroot string
 
 func main() {
@@ -25,21 +39,34 @@
 		log.Fatal("No $GOROOT set.")
 	}
 
-	out, err := exec.Command("go", "tool", "api",
-		"-c", file("go1", "go1.1", "go1.2", "go1.3", "go1.4", "go1.5", "go1.6", "go1.7", "go1.8", "go1.9"),
-		"-next", file("next"),
-		"-except", file("except")).CombinedOutput()
+	apiDir := filepath.Join(goroot, "api")
+	out, err := exec.Command(goCmd(), "tool", "api",
+		"-c", findAPIDirFiles(apiDir),
+		"-next", filepath.Join(apiDir, "next.txt"),
+		"-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
 	if err != nil {
 		log.Fatalf("Error running API checker: %v\n%s", err, out)
 	}
 	fmt.Print(string(out))
 }
 
-// file expands s to $GOROOT/api/s.txt.
-// If there are more than 1, they're comma-separated.
-func file(s ...string) string {
-	if len(s) > 1 {
-		return file(s[0]) + "," + file(s[1:]...)
+// findAPIDirFiles returns a comma-separated list of Go API files
+// (go1.txt, go1.1.txt, etc.) located in apiDir.
+func findAPIDirFiles(apiDir string) string {
+	dir, err := os.Open(apiDir)
+	if err != nil {
+		log.Fatal(err)
 	}
-	return filepath.Join(goroot, "api", s[0]+".txt")
+	defer dir.Close()
+	fs, err := dir.Readdirnames(-1)
+	if err != nil {
+		log.Fatal(err)
+	}
+	var apiFiles []string
+	for _, fn := range fs {
+		if strings.HasPrefix(fn, "go1") {
+			apiFiles = append(apiFiles, filepath.Join(apiDir, fn))
+		}
+	}
+	return strings.Join(apiFiles, ",")
 }
diff --git a/src/cmd/asm/doc.go b/src/cmd/asm/doc.go
index aa62147..c39cab3 100644
--- a/src/cmd/asm/doc.go
+++ b/src/cmd/asm/doc.go
@@ -19,23 +19,26 @@
 
 Flags:
 
-	-D value
-		predefined symbol with optional simple value -D=identifier=value;
-		can be set multiple times
-	-I value
-		include directory; can be set multiple times
-	-S	print assembly and machine code
+	-D name[=value]
+		Predefine symbol name with an optional simple value.
+		Can be repeated to define multiple symbols.
+	-I dir1 -I dir2
+		Search for #include files in dir1, dir2, etc,
+		after consulting $GOROOT/pkg/$GOOS_$GOARCH.
+	-S
+		Print assembly and machine code.
+	-V
+		Print assembler version and exit.
 	-debug
-		dump instructions as they are parsed
+		Dump instructions as they are parsed.
 	-dynlink
-		support references to Go symbols defined in other shared libraries
-	-o string
-		output file; default foo.o for /a/b/c/foo.s
+		Support references to Go symbols defined in other shared libraries.
+	-o file
+		Write output to file. The default is foo.o for /a/b/c/foo.s.
 	-shared
-		generate code that can be linked into a shared library
-	-trimpath string
-		remove prefix from recorded source file paths
-
+		Generate code that can be linked into a shared library.
+	-trimpath prefix
+		Remove prefix from recorded source file paths.
 Input language:
 
 The assembler uses mostly the same syntax for all architectures,
diff --git a/src/cmd/asm/internal/arch/amd64.go b/src/cmd/asm/internal/arch/amd64.go
deleted file mode 100644
index ff20d32..0000000
--- a/src/cmd/asm/internal/arch/amd64.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file encapsulates some of the odd characteristics of the
-// AMD64 instruction set, to minimize its interaction
-// with the core of the assembler.
-
-package arch
-
-import (
-	"cmd/internal/obj"
-	"cmd/internal/obj/x86"
-)
-
-// IsAMD4OP reports whether the op (as defined by an amd64.A* constant) is
-// a 4-operand instruction.
-func IsAMD4OP(op obj.As) bool {
-	switch op {
-	case x86.AVPERM2F128,
-		x86.AVPALIGNR,
-		x86.AVPERM2I128,
-		x86.AVINSERTI128,
-		x86.AVPBLENDD:
-		return true
-	}
-	return false
-}
diff --git a/src/cmd/asm/internal/arch/arm.go b/src/cmd/asm/internal/arch/arm.go
index 40443d5..6e86ac0 100644
--- a/src/cmd/asm/internal/arch/arm.go
+++ b/src/cmd/asm/internal/arch/arm.go
@@ -122,6 +122,16 @@
 	return false
 }
 
+// IsARMBFX reports whether the op (as defined by an arm.A* constant) is one the
+// BFX-like instructions which are in the form of "op $width, $LSB, (Reg,) Reg".
+func IsARMBFX(op obj.As) bool {
+	switch op {
+	case arm.ABFX, arm.ABFXU, arm.ABFC, arm.ABFI:
+		return true
+	}
+	return false
+}
+
 // IsARMFloatCmp reports whether the op is a floating comparison instruction.
 func IsARMFloatCmp(op obj.As) bool {
 	switch op {
diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go
index dd04719..63664d6 100644
--- a/src/cmd/asm/internal/arch/arm64.go
+++ b/src/cmd/asm/internal/arch/arm64.go
@@ -11,6 +11,7 @@
 import (
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
+	"errors"
 )
 
 var arm64LS = map[string]uint8{
@@ -56,7 +57,9 @@
 func IsARM64CMP(op obj.As) bool {
 	switch op {
 	case arm64.ACMN, arm64.ACMP, arm64.ATST,
-		arm64.ACMNW, arm64.ACMPW, arm64.ATSTW:
+		arm64.ACMNW, arm64.ACMPW, arm64.ATSTW,
+		arm64.AFCMPS, arm64.AFCMPD,
+		arm64.AFCMPES, arm64.AFCMPED:
 		return true
 	}
 	return false
@@ -67,7 +70,8 @@
 // handling.
 func IsARM64STLXR(op obj.As) bool {
 	switch op {
-	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR:
+	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR,
+		arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR:
 		return true
 	}
 	return false
@@ -115,3 +119,167 @@
 	}
 	return 0, false
 }
+
+// ARM64RegisterExtension parses an ARM64 register with extension or arrangment.
+func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
+	rm := uint32(reg)
+	if isAmount {
+		if num < 0 || num > 7 {
+			return errors.New("shift amount out of range")
+		}
+	}
+	switch ext {
+	case "UXTB":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_UXTB + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (uint32(num) << 10))
+	case "UXTH":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_UXTH + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (1 << 13) | (uint32(num) << 10))
+	case "UXTW":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_UXTW + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (2 << 13) | (uint32(num) << 10))
+	case "UXTX":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_UXTX + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (3 << 13) | (uint32(num) << 10))
+	case "SXTB":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_SXTB + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (4 << 13) | (uint32(num) << 10))
+	case "SXTH":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_SXTH + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (5 << 13) | (uint32(num) << 10))
+	case "SXTW":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_SXTW + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (6 << 13) | (uint32(num) << 10))
+	case "SXTX":
+		if !isAmount {
+			return errors.New("invalid register extension")
+		}
+		a.Reg = arm64.REG_SXTX + (reg & 31) + int16(num<<5)
+		a.Offset = int64(((rm & 31) << 16) | (7 << 13) | (uint32(num) << 10))
+	case "B8":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5)
+	case "B16":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5)
+	case "H4":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5)
+	case "H8":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5)
+	case "S2":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5)
+	case "S4":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5)
+	case "D2":
+		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5)
+	case "B":
+		if !isIndex {
+			return nil
+		}
+		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_B & 15) << 5)
+		a.Index = num
+	case "H":
+		if !isIndex {
+			return nil
+		}
+		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_H & 15) << 5)
+		a.Index = num
+	case "S":
+		if !isIndex {
+			return nil
+		}
+		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_S & 15) << 5)
+		a.Index = num
+	case "D":
+		if !isIndex {
+			return nil
+		}
+		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_D & 15) << 5)
+		a.Index = num
+	default:
+		return errors.New("unsupported register extension type: " + ext)
+	}
+	a.Type = obj.TYPE_REG
+	return nil
+}
+
+// ARM64RegisterArrangement parses an ARM64 vector register arrangment.
+func ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) {
+	var curQ, curSize uint16
+	if name[0] != 'V' {
+		return 0, errors.New("expect V0 through V31; found: " + name)
+	}
+	if reg < 0 {
+		return 0, errors.New("invalid register number: " + name)
+	}
+	switch arng {
+	case "B8":
+		curSize = 0
+		curQ = 0
+	case "B16":
+		curSize = 0
+		curQ = 1
+	case "H4":
+		curSize = 1
+		curQ = 0
+	case "H8":
+		curSize = 1
+		curQ = 1
+	case "S2":
+		curSize = 1
+		curQ = 0
+	case "S4":
+		curSize = 2
+		curQ = 1
+	case "D1":
+		curSize = 3
+		curQ = 0
+	case "D2":
+		curSize = 3
+		curQ = 1
+	default:
+		return 0, errors.New("invalid arrangement in ARM64 register list")
+	}
+	return (int64(curQ) & 1 << 30) | (int64(curSize&3) << 10), nil
+}
+
+// ARM64RegisterListOffset generates offset encoding according to AArch64 specification.
+func ARM64RegisterListOffset(firstReg, regCnt int, arrangement int64) (int64, error) {
+	offset := int64(firstReg)
+	switch regCnt {
+	case 1:
+		offset |= 0x7 << 12
+	case 2:
+		offset |= 0xa << 12
+	case 3:
+		offset |= 0x6 << 12
+	case 4:
+		offset |= 0x2 << 12
+	default:
+		return 0, errors.New("invalid register numbers in ARM64 register list")
+	}
+	offset |= arrangement
+	// arm64 uses the 60th bit to differentiate from other archs
+	// For more details, refer to: obj/arm64/list7.go
+	offset |= 1 << 60
+	return offset, nil
+}
diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go
index df23856..bf3545b 100644
--- a/src/cmd/asm/internal/asm/asm.go
+++ b/src/cmd/asm/internal/asm/asm.go
@@ -384,7 +384,7 @@
 				prog.Reg = p.getRegister(prog, op, &a[1])
 			} else {
 				// Compare register with immediate and jump.
-				prog.From3 = newAddr(a[1])
+				prog.SetFrom3(a[1])
 			}
 			break
 		}
@@ -507,27 +507,6 @@
 				break
 			}
 			// Strange special cases.
-			if arch.IsARMSTREX(op) {
-				/*
-					STREX x, (y)
-						from=(y) reg=x to=x
-					STREX (x), y
-						from=(x) reg=y to=y
-				*/
-				if a[0].Type == obj.TYPE_REG && a[1].Type != obj.TYPE_REG {
-					prog.From = a[1]
-					prog.Reg = a[0].Reg
-					prog.To = a[0]
-					break
-				} else if a[0].Type != obj.TYPE_REG && a[1].Type == obj.TYPE_REG {
-					prog.From = a[0]
-					prog.Reg = a[1].Reg
-					prog.To = a[1]
-					break
-				}
-				p.errorf("unrecognized addressing for %s", op)
-				return
-			}
 			if arch.IsARMFloatCmp(op) {
 				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[1])
@@ -564,18 +543,20 @@
 				prog.To = a[2]
 				break
 			}
+			if arch.IsARMBFX(op) {
+				// a[0] and a[1] must be constants, a[2] must be a register
+				prog.From = a[0]
+				prog.SetFrom3(a[1])
+				prog.To = a[2]
+				break
+			}
 			// Otherwise the 2nd operand (a[1]) must be a register.
 			prog.From = a[0]
 			prog.Reg = p.getRegister(prog, op, &a[1])
 			prog.To = a[2]
 		case sys.AMD64:
-			// Catch missing operand here, because we store immediate as part of From3, and can't distinguish
-			// missing operand from legal value 0 in obj/x86/asm6.
-			if arch.IsAMD4OP(op) {
-				p.errorf("4 operands required, but only 3 are provided for %s instruction", op)
-			}
 			prog.From = a[0]
-			prog.From3 = newAddr(a[1])
+			prog.SetFrom3(a[1])
 			prog.To = a[2]
 		case sys.ARM64:
 			// ARM64 instructions with one input and two outputs.
@@ -594,7 +575,7 @@
 			prog.To = a[2]
 		case sys.I386:
 			prog.From = a[0]
-			prog.From3 = newAddr(a[1])
+			prog.SetFrom3(a[1])
 			prog.To = a[2]
 		case sys.PPC64:
 			if arch.IsPPC64CMP(op) {
@@ -616,7 +597,7 @@
 				prog.To = a[2]
 			case obj.TYPE_CONST:
 				prog.From = a[0]
-				prog.From3 = newAddr(a[1])
+				prog.SetFrom3(a[1])
 				prog.To = a[2]
 			default:
 				p.errorf("invalid addressing modes for %s instruction", op)
@@ -627,7 +608,7 @@
 			if a[1].Type == obj.TYPE_REG {
 				prog.Reg = p.getRegister(prog, op, &a[1])
 			} else {
-				prog.From3 = newAddr(a[1])
+				prog.SetFrom3(a[1])
 			}
 			prog.To = a[2]
 		default:
@@ -635,40 +616,39 @@
 			return
 		}
 	case 4:
-		if p.arch.Family == sys.ARM && arch.IsARMMULA(op) {
-			// All must be registers.
-			p.getRegister(prog, op, &a[0])
-			r1 := p.getRegister(prog, op, &a[1])
-			r2 := p.getRegister(prog, op, &a[2])
-			p.getRegister(prog, op, &a[3])
-			prog.From = a[0]
-			prog.To = a[3]
-			prog.To.Type = obj.TYPE_REGREG2
-			prog.To.Offset = int64(r2)
-			prog.Reg = r1
-			break
+		if p.arch.Family == sys.ARM {
+			if arch.IsARMBFX(op) {
+				// a[0] and a[1] must be constants, a[2] and a[3] must be registers
+				prog.From = a[0]
+				prog.SetFrom3(a[1])
+				prog.Reg = p.getRegister(prog, op, &a[2])
+				prog.To = a[3]
+				break
+			}
+			if arch.IsARMMULA(op) {
+				// All must be registers.
+				p.getRegister(prog, op, &a[0])
+				r1 := p.getRegister(prog, op, &a[1])
+				r2 := p.getRegister(prog, op, &a[2])
+				p.getRegister(prog, op, &a[3])
+				prog.From = a[0]
+				prog.To = a[3]
+				prog.To.Type = obj.TYPE_REGREG2
+				prog.To.Offset = int64(r2)
+				prog.Reg = r1
+				break
+			}
 		}
 		if p.arch.Family == sys.AMD64 {
-			// 4 operand instruction have form  ymm1, ymm2, ymm3/m256, imm8
-			// So From3 is always just a register, so we store imm8 in Offset field,
-			// to avoid increasing size of Prog.
-			prog.From = a[1]
-			prog.From3 = newAddr(a[2])
-			if a[0].Type != obj.TYPE_CONST {
-				p.errorf("first operand must be an immediate in %s instruction", op)
-			}
-			if prog.From3.Type != obj.TYPE_REG {
-				p.errorf("third operand must be a register in %s instruction", op)
-			}
-			prog.From3.Offset = int64(p.getImmediate(prog, op, &a[0]))
+			prog.From = a[0]
+			prog.RestArgs = []obj.Addr{a[1], a[2]}
 			prog.To = a[3]
-			prog.RegTo2 = -1
 			break
 		}
 		if p.arch.Family == sys.ARM64 {
 			prog.From = a[0]
 			prog.Reg = p.getRegister(prog, op, &a[1])
-			prog.From3 = newAddr(a[2])
+			prog.SetFrom3(a[2])
 			prog.To = a[3]
 			break
 		}
@@ -676,12 +656,12 @@
 			if arch.IsPPC64RLD(op) {
 				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[1])
-				prog.From3 = newAddr(a[2])
+				prog.SetFrom3(a[2])
 				prog.To = a[3]
 				break
 			} else if arch.IsPPC64ISEL(op) {
 				// ISEL BC,RB,RA,RT becomes isel rt,ra,rb,bc
-				prog.From3 = newAddr(a[2])                // ra
+				prog.SetFrom3(a[2])                       // ra
 				prog.From = a[0]                          // bc
 				prog.Reg = p.getRegister(prog, op, &a[1]) // rb
 				prog.To = a[3]                            // rt
@@ -695,13 +675,13 @@
 			if a[1].Type == obj.TYPE_REG {
 				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[1])
-				prog.From3 = newAddr(a[2])
+				prog.SetFrom3(a[2])
 				prog.To = a[3]
 				break
 			} else if a[1].Type == obj.TYPE_CONST {
 				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[2])
-				prog.From3 = newAddr(a[1])
+				prog.SetFrom3(a[1])
 				prog.To = a[3]
 				break
 			} else {
@@ -716,7 +696,7 @@
 			}
 			prog.From = a[0]
 			prog.Reg = p.getRegister(prog, op, &a[1])
-			prog.From3 = newAddr(a[2])
+			prog.SetFrom3(a[2])
 			prog.To = a[3]
 			break
 		}
@@ -735,10 +715,10 @@
 			} else {
 				mask = (^uint32(0) >> uint(mask2+1)) & (^uint32(0) << uint(31-(mask1-1)))
 			}
-			prog.From3 = &obj.Addr{
+			prog.SetFrom3(obj.Addr{
 				Type:   obj.TYPE_CONST,
 				Offset: int64(mask),
-			}
+			})
 			prog.To = a[4]
 			break
 		}
diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go
index e5bc34e..d8a447d 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -186,7 +186,7 @@
 		t.Errorf(format, args...)
 		ok = false
 	}
-	obj.Flushplist(ctxt, pList, nil)
+	obj.Flushplist(ctxt, pList, nil, "")
 
 	for p := top; p != nil; p = p.Link {
 		if p.As == obj.ATEXT {
@@ -290,7 +290,7 @@
 		errBuf.WriteString(s)
 	}
 	pList.Firstpc, ok = parser.Parse()
-	obj.Flushplist(ctxt, pList, nil)
+	obj.Flushplist(ctxt, pList, nil, "")
 	if ok && !failed {
 		t.Errorf("asm: %s had no errors", goarch)
 	}
@@ -385,12 +385,17 @@
 	testEndToEnd(t, "arm64", "arm64enc")
 }
 
+func TestARM64Errors(t *testing.T) {
+	testErrors(t, "arm64", "arm64error")
+}
+
 func TestAMD64EndToEnd(t *testing.T) {
 	testEndToEnd(t, "amd64", "amd64")
 }
 
 func TestAMD64Encoder(t *testing.T) {
 	testEndToEnd(t, "amd64", "amd64enc")
+	testEndToEnd(t, "amd64", "amd64enc_extra")
 }
 
 func TestAMD64Errors(t *testing.T) {
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index a6e13db..1d5d073 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -258,11 +258,11 @@
 }
 
 // operand parses a general operand and stores the result in *a.
-func (p *Parser) operand(a *obj.Addr) bool {
+func (p *Parser) operand(a *obj.Addr) {
 	//fmt.Printf("Operand: %v\n", p.input)
 	if len(p.input) == 0 {
 		p.errorf("empty operand: cannot happen")
-		return false
+		return
 	}
 	// General address (with a few exceptions) looks like
 	//	$sym±offset(SB)(reg)(index*scale)
@@ -290,7 +290,7 @@
 		p.symbolReference(a, name, prefix)
 		// fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a))
 		if p.peek() == scanner.EOF {
-			return true
+			return
 		}
 	}
 
@@ -301,7 +301,7 @@
 		}
 		p.registerList(a)
 		p.expectOperandEnd()
-		return true
+		return
 	}
 
 	// Register: R1
@@ -321,6 +321,10 @@
 				a.Reg, _ = p.registerReference(name)
 				p.get(')')
 			}
+		} else if p.atRegisterExtension() {
+			p.registerExtension(a, tok.String(), prefix)
+			p.expectOperandEnd()
+			return
 		} else if r1, r2, scale, ok := p.register(tok.String(), prefix); ok {
 			if scale != 0 {
 				p.errorf("expected simple register reference")
@@ -335,7 +339,7 @@
 		}
 		// fmt.Printf("REG %s\n", obj.Dconv(&emptyProg, 0, a))
 		p.expectOperandEnd()
-		return true
+		return
 	}
 
 	// Constant.
@@ -348,7 +352,7 @@
 		tok := p.next()
 		if tok.ScanToken == scanner.EOF {
 			p.errorf("missing right parenthesis")
-			return false
+			return
 		}
 		rname := tok.String()
 		p.back()
@@ -367,12 +371,12 @@
 			a.Val = p.floatExpr()
 			// fmt.Printf("FCONST %s\n", obj.Dconv(&emptyProg, 0, a))
 			p.expectOperandEnd()
-			return true
+			return
 		}
 		if p.have(scanner.String) {
 			if prefix != '$' {
 				p.errorf("string constant must be an immediate")
-				return false
+				return
 			}
 			str, err := strconv.Unquote(p.get(scanner.String).String())
 			if err != nil {
@@ -382,7 +386,7 @@
 			a.Val = str
 			// fmt.Printf("SCONST %s\n", obj.Dconv(&emptyProg, 0, a))
 			p.expectOperandEnd()
-			return true
+			return
 		}
 		a.Offset = int64(p.expr())
 		if p.peek() != '(' {
@@ -396,7 +400,7 @@
 			}
 			// fmt.Printf("CONST %d %s\n", a.Offset, obj.Dconv(&emptyProg, 0, a))
 			p.expectOperandEnd()
-			return true
+			return
 		}
 		// fmt.Printf("offset %d \n", a.Offset)
 	}
@@ -406,7 +410,7 @@
 	// fmt.Printf("DONE %s\n", p.arch.Dconv(&emptyProg, 0, a))
 
 	p.expectOperandEnd()
-	return true
+	return
 }
 
 // atStartOfRegister reports whether the parser is at the start of a register definition.
@@ -439,6 +443,20 @@
 	return p.at('(', scanner.Int, ')') && lex.IsRegisterShift(p.input[p.inputPos+3].ScanToken)
 }
 
+// atRegisterExtension reports whether we are at the start of an ARM64 extended register.
+// We have consumed the register or R prefix.
+func (p *Parser) atRegisterExtension() bool {
+	// ARM64 only.
+	if p.arch.Family != sys.ARM64 {
+		return false
+	}
+	// R1.xxx
+	if p.peek() == '.' {
+		return true
+	}
+	return false
+}
+
 // registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10).
 func (p *Parser) registerReference(name string) (int16, bool) {
 	r, present := p.arch.Register[name]
@@ -573,6 +591,59 @@
 	}
 }
 
+// registerExtension parses a register with extension or arrangment.
+// There is known to be a register (current token) and an extension operator (peeked token).
+func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) {
+	if prefix != 0 {
+		p.errorf("prefix %c not allowed for shifted register: $%s", prefix, name)
+	}
+
+	reg, ok := p.registerReference(name)
+	if !ok {
+		p.errorf("unexpected %s in register extension", name)
+		return
+	}
+
+	p.get('.')
+	tok := p.next()
+	ext := tok.String()
+	isIndex := false
+	num := int16(0)
+	isAmount := true // Amount is zero by default
+	if p.peek() == lex.LSH {
+		// parses left shift amount applied after extension: <<Amount
+		p.get(lex.LSH)
+		tok := p.get(scanner.Int)
+		amount, err := strconv.ParseInt(tok.String(), 10, 16)
+		if err != nil {
+			p.errorf("parsing left shift amount: %s", err)
+		}
+		num = int16(amount)
+	} else if p.peek() == '[' {
+		// parses an element: [Index]
+		p.get('[')
+		tok := p.get(scanner.Int)
+		index, err := strconv.ParseInt(tok.String(), 10, 16)
+		p.get(']')
+		if err != nil {
+			p.errorf("parsing element index: %s", err)
+		}
+		isIndex = true
+		isAmount = false
+		num = int16(index)
+	}
+
+	switch p.arch.Family {
+	case sys.ARM64:
+		err := arch.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex)
+		if err != nil {
+			p.errorf(err.Error())
+		}
+	default:
+		p.errorf("register extension not supported on this architecture")
+	}
+}
+
 // symbolReference parses a symbol that is known not to be a register.
 func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
 	// Identifier is a name.
@@ -720,7 +791,12 @@
 			p.errorf("unimplemented two-register form")
 		}
 		a.Index = r1
-		a.Scale = int16(scale)
+		if scale == 0 && p.arch.Family == sys.ARM64 {
+			// scale is 1 by default for ARM64
+			a.Scale = 1
+		} else {
+			a.Scale = int16(scale)
+		}
 		p.get(')')
 	} else if scale != 0 {
 		// First (R) was missing, all we have is (R*scale).
@@ -730,14 +806,28 @@
 	}
 }
 
-// registerList parses an ARM register list expression, a list of registers in [].
-// There may be comma-separated ranges or individual registers, as in
-// [R1,R3-R5]. Only R0 through R15 may appear.
+// registerList parses an ARM or ARM64 register list expression, a list of
+// registers in []. There may be comma-separated ranges or individual
+// registers, as in [R1,R3-R5] or [V1.S4, V2.S4, V3.S4, V4.S4].
+// For ARM, only R0 through R15 may appear.
+// For ARM64, V0 through V31 with arrangement may appear.
 // The opening bracket has been consumed.
 func (p *Parser) registerList(a *obj.Addr) {
 	// One range per loop.
-	const maxReg = 16
+	var maxReg int
 	var bits uint16
+	var arrangement int64
+	switch p.arch.Family {
+	case sys.ARM:
+		maxReg = 16
+	case sys.ARM64:
+		maxReg = 32
+	default:
+		p.errorf("unexpected register list")
+	}
+	firstReg := -1
+	nextReg := -1
+	regCnt := 0
 ListLoop:
 	for {
 		tok := p.next()
@@ -748,30 +838,73 @@
 			p.errorf("missing ']' in register list")
 			return
 		}
-		// Parse the upper and lower bounds.
-		lo := p.registerNumber(tok.String())
-		hi := lo
-		if p.peek() == '-' {
-			p.next()
-			hi = p.registerNumber(p.next().String())
-		}
-		if hi < lo {
-			lo, hi = hi, lo
-		}
-		// Check there are no duplicates in the register list.
-		for i := 0; lo <= hi && i < maxReg; i++ {
-			if bits&(1<<lo) != 0 {
-				p.errorf("register R%d already in list", lo)
+		switch p.arch.Family {
+		case sys.ARM64:
+			// Vn.T
+			name := tok.String()
+			r, ok := p.registerReference(name)
+			if !ok {
+				p.errorf("invalid register: %s", name)
 			}
-			bits |= 1 << lo
-			lo++
+			reg := r - p.arch.Register["V0"]
+			p.get('.')
+			tok := p.next()
+			ext := tok.String()
+			curArrangement, err := arch.ARM64RegisterArrangement(reg, name, ext)
+			if err != nil {
+				p.errorf(err.Error())
+			}
+			if firstReg == -1 {
+				// only record the first register and arrangement
+				firstReg = int(reg)
+				nextReg = firstReg
+				arrangement = curArrangement
+			} else if curArrangement != arrangement {
+				p.errorf("inconsistent arrangement in ARM64 register list")
+			} else if nextReg != int(reg) {
+				p.errorf("incontiguous register in ARM64 register list: %s", name)
+			}
+			regCnt++
+			nextReg = (nextReg + 1) % 32
+		case sys.ARM:
+			// Parse the upper and lower bounds.
+			lo := p.registerNumber(tok.String())
+			hi := lo
+			if p.peek() == '-' {
+				p.next()
+				hi = p.registerNumber(p.next().String())
+			}
+			if hi < lo {
+				lo, hi = hi, lo
+			}
+			// Check there are no duplicates in the register list.
+			for i := 0; lo <= hi && i < maxReg; i++ {
+				if bits&(1<<lo) != 0 {
+					p.errorf("register R%d already in list", lo)
+				}
+				bits |= 1 << lo
+				lo++
+			}
+		default:
+			p.errorf("unexpected register list")
 		}
 		if p.peek() != ']' {
 			p.get(',')
 		}
 	}
 	a.Type = obj.TYPE_REGLIST
-	a.Offset = int64(bits)
+	switch p.arch.Family {
+	case sys.ARM:
+		a.Offset = int64(bits)
+	case sys.ARM64:
+		offset, err := arch.ARM64RegisterListOffset(firstReg, regCnt, arrangement)
+		if err != nil {
+			p.errorf(err.Error())
+		}
+		a.Offset = offset
+	default:
+		p.errorf("register list not supported on this architecuture")
+	}
 }
 
 // register number is ARM-specific. It returns the number of the specified register.
diff --git a/src/cmd/asm/internal/asm/testdata/amd64enc.s b/src/cmd/asm/internal/asm/testdata/amd64enc.s
index ec888bc..c7e787f 100644
--- a/src/cmd/asm/internal/asm/testdata/amd64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/amd64enc.s
@@ -84,22 +84,22 @@
 	ADCB (R11), DL                          // 411213
 	ADCB (BX), R11                          // 44121b
 	ADCB (R11), R11                         // 45121b
-	//TODO: ADCXL (BX), DX                  // 660f38f613
-	//TODO: ADCXL (R11), DX                 // 66410f38f613
-	//TODO: ADCXL DX, DX                    // 660f38f6d2
-	//TODO: ADCXL R11, DX                   // 66410f38f6d3
-	//TODO: ADCXL (BX), R11                 // 66440f38f61b
-	//TODO: ADCXL (R11), R11                // 66450f38f61b
-	//TODO: ADCXL DX, R11                   // 66440f38f6da
-	//TODO: ADCXL R11, R11                  // 66450f38f6db
-	//TODO: ADCXQ (BX), DX                  // 66480f38f613
-	//TODO: ADCXQ (R11), DX                 // 66490f38f613
-	//TODO: ADCXQ DX, DX                    // 66480f38f6d2
-	//TODO: ADCXQ R11, DX                   // 66490f38f6d3
-	//TODO: ADCXQ (BX), R11                 // 664c0f38f61b
-	//TODO: ADCXQ (R11), R11                // 664d0f38f61b
-	//TODO: ADCXQ DX, R11                   // 664c0f38f6da
-	//TODO: ADCXQ R11, R11                  // 664d0f38f6db
+	ADCXL (BX), DX                          // 660f38f613
+	ADCXL (R11), DX                         // 66410f38f613
+	ADCXL DX, DX                            // 660f38f6d2
+	ADCXL R11, DX                           // 66410f38f6d3
+	ADCXL (BX), R11                         // 66440f38f61b
+	ADCXL (R11), R11                        // 66450f38f61b
+	ADCXL DX, R11                           // 66440f38f6da
+	ADCXL R11, R11                          // 66450f38f6db
+	ADCXQ (BX), DX                          // 66480f38f613
+	ADCXQ (R11), DX                         // 66490f38f613
+	ADCXQ DX, DX                            // 66480f38f6d2
+	ADCXQ R11, DX                           // 66490f38f6d3
+	ADCXQ (BX), R11                         // 664c0f38f61b
+	ADCXQ (R11), R11                        // 664d0f38f61b
+	ADCXQ DX, R11                           // 664c0f38f6da
+	ADCXQ R11, R11                          // 664d0f38f6db
 	ADDB $7, AL                             // 0407
 	ADDW $61731, AX                         // 660523f1
 	ADDL $4045620583, AX                    // 05674523f1
@@ -212,38 +212,38 @@
 	ADDSS (R11), X11                        // f3450f581b
 	ADDSS X2, X11                           // f3440f58da
 	ADDSS X11, X11                          // f3450f58db
-	//TODO: ADDSUBPD (BX), X2               // 660fd013
-	//TODO: ADDSUBPD (R11), X2              // 66410fd013
-	//TODO: ADDSUBPD X2, X2                 // 660fd0d2
-	//TODO: ADDSUBPD X11, X2                // 66410fd0d3
-	//TODO: ADDSUBPD (BX), X11              // 66440fd01b
-	//TODO: ADDSUBPD (R11), X11             // 66450fd01b
-	//TODO: ADDSUBPD X2, X11                // 66440fd0da
-	//TODO: ADDSUBPD X11, X11               // 66450fd0db
-	//TODO: ADDSUBPS (BX), X2               // f20fd013
-	//TODO: ADDSUBPS (R11), X2              // f2410fd013
-	//TODO: ADDSUBPS X2, X2                 // f20fd0d2
-	//TODO: ADDSUBPS X11, X2                // f2410fd0d3
-	//TODO: ADDSUBPS (BX), X11              // f2440fd01b
-	//TODO: ADDSUBPS (R11), X11             // f2450fd01b
-	//TODO: ADDSUBPS X2, X11                // f2440fd0da
-	//TODO: ADDSUBPS X11, X11               // f2450fd0db
-	//TODO: ADOXL (BX), DX                  // f30f38f613
-	//TODO: ADOXL (R11), DX                 // f3410f38f613
-	//TODO: ADOXL DX, DX                    // f30f38f6d2
-	//TODO: ADOXL R11, DX                   // f3410f38f6d3
-	//TODO: ADOXL (BX), R11                 // f3440f38f61b
-	//TODO: ADOXL (R11), R11                // f3450f38f61b
-	//TODO: ADOXL DX, R11                   // f3440f38f6da
-	//TODO: ADOXL R11, R11                  // f3450f38f6db
-	//TODO: ADOXQ (BX), DX                  // f3480f38f613
-	//TODO: ADOXQ (R11), DX                 // f3490f38f613
-	//TODO: ADOXQ DX, DX                    // f3480f38f6d2
-	//TODO: ADOXQ R11, DX                   // f3490f38f6d3
-	//TODO: ADOXQ (BX), R11                 // f34c0f38f61b
-	//TODO: ADOXQ (R11), R11                // f34d0f38f61b
-	//TODO: ADOXQ DX, R11                   // f34c0f38f6da
-	//TODO: ADOXQ R11, R11                  // f34d0f38f6db
+	ADDSUBPD (BX), X2                       // 660fd013
+	ADDSUBPD (R11), X2                      // 66410fd013
+	ADDSUBPD X2, X2                         // 660fd0d2
+	ADDSUBPD X11, X2                        // 66410fd0d3
+	ADDSUBPD (BX), X11                      // 66440fd01b
+	ADDSUBPD (R11), X11                     // 66450fd01b
+	ADDSUBPD X2, X11                        // 66440fd0da
+	ADDSUBPD X11, X11                       // 66450fd0db
+	ADDSUBPS (BX), X2                       // f20fd013
+	ADDSUBPS (R11), X2                      // f2410fd013
+	ADDSUBPS X2, X2                         // f20fd0d2
+	ADDSUBPS X11, X2                        // f2410fd0d3
+	ADDSUBPS (BX), X11                      // f2440fd01b
+	ADDSUBPS (R11), X11                     // f2450fd01b
+	ADDSUBPS X2, X11                        // f2440fd0da
+	ADDSUBPS X11, X11                       // f2450fd0db
+	ADOXL (BX), DX                          // f30f38f613
+	ADOXL (R11), DX                         // f3410f38f613
+	ADOXL DX, DX                            // f30f38f6d2
+	ADOXL R11, DX                           // f3410f38f6d3
+	ADOXL (BX), R11                         // f3440f38f61b
+	ADOXL (R11), R11                        // f3450f38f61b
+	ADOXL DX, R11                           // f3440f38f6da
+	ADOXL R11, R11                          // f3450f38f6db
+	ADOXQ (BX), DX                          // f3480f38f613
+	ADOXQ (R11), DX                         // f3490f38f613
+	ADOXQ DX, DX                            // f3480f38f6d2
+	ADOXQ R11, DX                           // f3490f38f6d3
+	ADOXQ (BX), R11                         // f34c0f38f61b
+	ADOXQ (R11), R11                        // f34d0f38f61b
+	ADOXQ DX, R11                           // f34c0f38f6da
+	ADOXQ R11, R11                          // f34d0f38f6db
 	AESDEC (BX), X2                         // 660f38de13
 	AESDEC (R11), X2                        // 66410f38de13
 	AESDEC X2, X2                           // 660f38ded2
@@ -436,22 +436,22 @@
 	BEXTRQ R14, (R11), R11                  // c44288f71b
 	BEXTRQ R14, DX, R11                     // c46288f7da
 	BEXTRQ R14, R11, R11                    // c44288f7db
-	//TODO: BLENDPD $7, (BX), X2            // 660f3a0d1307
-	//TODO: BLENDPD $7, (R11), X2           // 66410f3a0d1307
-	//TODO: BLENDPD $7, X2, X2              // 660f3a0dd207
-	//TODO: BLENDPD $7, X11, X2             // 66410f3a0dd307
-	//TODO: BLENDPD $7, (BX), X11           // 66440f3a0d1b07
-	//TODO: BLENDPD $7, (R11), X11          // 66450f3a0d1b07
-	//TODO: BLENDPD $7, X2, X11             // 66440f3a0dda07
-	//TODO: BLENDPD $7, X11, X11            // 66450f3a0ddb07
-	//TODO: BLENDPS $7, (BX), X2            // 660f3a0c1307
-	//TODO: BLENDPS $7, (R11), X2           // 66410f3a0c1307
-	//TODO: BLENDPS $7, X2, X2              // 660f3a0cd207
-	//TODO: BLENDPS $7, X11, X2             // 66410f3a0cd307
-	//TODO: BLENDPS $7, (BX), X11           // 66440f3a0c1b07
-	//TODO: BLENDPS $7, (R11), X11          // 66450f3a0c1b07
-	//TODO: BLENDPS $7, X2, X11             // 66440f3a0cda07
-	//TODO: BLENDPS $7, X11, X11            // 66450f3a0cdb07
+	BLENDPD $7, (BX), X2                    // 660f3a0d1307
+	BLENDPD $7, (R11), X2                   // 66410f3a0d1307
+	BLENDPD $7, X2, X2                      // 660f3a0dd207
+	BLENDPD $7, X11, X2                     // 66410f3a0dd307
+	BLENDPD $7, (BX), X11                   // 66440f3a0d1b07
+	BLENDPD $7, (R11), X11                  // 66450f3a0d1b07
+	BLENDPD $7, X2, X11                     // 66440f3a0dda07
+	BLENDPD $7, X11, X11                    // 66450f3a0ddb07
+	BLENDPS $7, (BX), X2                    // 660f3a0c1307
+	BLENDPS $7, (R11), X2                   // 66410f3a0c1307
+	BLENDPS $7, X2, X2                      // 660f3a0cd207
+	BLENDPS $7, X11, X2                     // 66410f3a0cd307
+	BLENDPS $7, (BX), X11                   // 66440f3a0c1b07
+	BLENDPS $7, (R11), X11                  // 66450f3a0c1b07
+	BLENDPS $7, X2, X11                     // 66440f3a0cda07
+	BLENDPS $7, X11, X11                    // 66450f3a0cdb07
 	//TODO: BLENDVPD XMM0, (BX), X2         // 660f381513
 	//TODO: BLENDVPD XMM0, (R11), X2        // 66410f381513
 	//TODO: BLENDVPD XMM0, X2, X2           // 660f3815d2
@@ -468,30 +468,30 @@
 	//TODO: BLENDVPS XMM0, (R11), X11       // 66450f38141b
 	//TODO: BLENDVPS XMM0, X2, X11          // 66440f3814da
 	//TODO: BLENDVPS XMM0, X11, X11         // 66450f3814db
-	//TODO: BLSIL (BX), R9                  // c4e230f31b
-	//TODO: BLSIL (R11), R9                 // c4c230f31b
-	//TODO: BLSIL DX, R9                    // c4e230f3da
-	//TODO: BLSIL R11, R9                   // c4c230f3db
-	//TODO: BLSIQ (BX), R14                 // c4e288f31b
-	//TODO: BLSIQ (R11), R14                // c4c288f31b
-	//TODO: BLSIQ DX, R14                   // c4e288f3da
-	//TODO: BLSIQ R11, R14                  // c4c288f3db
-	//TODO: BLSMSKL (BX), R9                // c4e230f313
-	//TODO: BLSMSKL (R11), R9               // c4c230f313
-	//TODO: BLSMSKL DX, R9                  // c4e230f3d2
-	//TODO: BLSMSKL R11, R9                 // c4c230f3d3
-	//TODO: BLSMSKQ (BX), R14               // c4e288f313
-	//TODO: BLSMSKQ (R11), R14              // c4c288f313
-	//TODO: BLSMSKQ DX, R14                 // c4e288f3d2
-	//TODO: BLSMSKQ R11, R14                // c4c288f3d3
-	//TODO: BLSRL (BX), R9                  // c4e230f30b
-	//TODO: BLSRL (R11), R9                 // c4c230f30b
-	//TODO: BLSRL DX, R9                    // c4e230f3ca
-	//TODO: BLSRL R11, R9                   // c4c230f3cb
-	//TODO: BLSRQ (BX), R14                 // c4e288f30b
-	//TODO: BLSRQ (R11), R14                // c4c288f30b
-	//TODO: BLSRQ DX, R14                   // c4e288f3ca
-	//TODO: BLSRQ R11, R14                  // c4c288f3cb
+	BLSIL (BX), R9                          // c4e230f31b
+	BLSIL (R11), R9                         // c4c230f31b
+	BLSIL DX, R9                            // c4e230f3da
+	BLSIL R11, R9                           // c4c230f3db
+	BLSIQ (BX), R14                         // c4e288f31b
+	BLSIQ (R11), R14                        // c4c288f31b
+	BLSIQ DX, R14                           // c4e288f3da
+	BLSIQ R11, R14                          // c4c288f3db
+	BLSMSKL (BX), R9                        // c4e230f313
+	BLSMSKL (R11), R9                       // c4c230f313
+	BLSMSKL DX, R9                          // c4e230f3d2
+	BLSMSKL R11, R9                         // c4c230f3d3
+	BLSMSKQ (BX), R14                       // c4e288f313
+	BLSMSKQ (R11), R14                      // c4c288f313
+	BLSMSKQ DX, R14                         // c4e288f3d2
+	BLSMSKQ R11, R14                        // c4c288f3d3
+	BLSRL (BX), R9                          // c4e230f30b
+	BLSRL (R11), R9                         // c4c230f30b
+	BLSRL DX, R9                            // c4e230f3ca
+	BLSRL R11, R9                           // c4c230f3cb
+	BLSRQ (BX), R14                         // c4e288f30b
+	BLSRQ (R11), R14                        // c4c288f30b
+	BLSRQ DX, R14                           // c4e288f3ca
+	BLSRQ R11, R14                          // c4c288f3cb
 	//TODO: BNDCL (BX), BND2                // f30f1a13
 	//TODO: BNDCL (R11), BND2               // f3410f1a13
 	//TODO: BNDCL DX, BND2                  // f30f1ad2
@@ -771,8 +771,8 @@
 	//TODO: CLAC                            // 0f01ca
 	CLC                                     // f8
 	CLD                                     // fc
-	//TODO: CLFLUSH (BX)                    // 0fae3b
-	//TODO: CLFLUSH (R11)                   // 410fae3b
+	CLFLUSH (BX)                            // 0fae3b
+	CLFLUSH (R11)                           // 410fae3b
 	//TODO: CLFLUSHOPT (BX)                 // 660fae3b
 	//TODO: CLFLUSHOPT (R11)                // 66410fae3b
 	CLI                                     // fa
@@ -1622,32 +1622,32 @@
 	DIVSS (R11), X11                        // f3450f5e1b
 	DIVSS X2, X11                           // f3440f5eda
 	DIVSS X11, X11                          // f3450f5edb
-	//TODO: DPPD $7, (BX), X2               // 660f3a411307
-	//TODO: DPPD $7, (R11), X2              // 66410f3a411307
-	//TODO: DPPD $7, X2, X2                 // 660f3a41d207
-	//TODO: DPPD $7, X11, X2                // 66410f3a41d307
-	//TODO: DPPD $7, (BX), X11              // 66440f3a411b07
-	//TODO: DPPD $7, (R11), X11             // 66450f3a411b07
-	//TODO: DPPD $7, X2, X11                // 66440f3a41da07
-	//TODO: DPPD $7, X11, X11               // 66450f3a41db07
-	//TODO: DPPS $7, (BX), X2               // 660f3a401307
-	//TODO: DPPS $7, (R11), X2              // 66410f3a401307
-	//TODO: DPPS $7, X2, X2                 // 660f3a40d207
-	//TODO: DPPS $7, X11, X2                // 66410f3a40d307
-	//TODO: DPPS $7, (BX), X11              // 66440f3a401b07
-	//TODO: DPPS $7, (R11), X11             // 66450f3a401b07
-	//TODO: DPPS $7, X2, X11                // 66440f3a40da07
-	//TODO: DPPS $7, X11, X11               // 66450f3a40db07
+	DPPD $7, (BX), X2                       // 660f3a411307
+	DPPD $7, (R11), X2                      // 66410f3a411307
+	DPPD $7, X2, X2                         // 660f3a41d207
+	DPPD $7, X11, X2                        // 66410f3a41d307
+	DPPD $7, (BX), X11                      // 66440f3a411b07
+	DPPD $7, (R11), X11                     // 66450f3a411b07
+	DPPD $7, X2, X11                        // 66440f3a41da07
+	DPPD $7, X11, X11                       // 66450f3a41db07
+	DPPS $7, (BX), X2                       // 660f3a401307
+	DPPS $7, (R11), X2                      // 66410f3a401307
+	DPPS $7, X2, X2                         // 660f3a40d207
+	DPPS $7, X11, X2                        // 66410f3a40d307
+	DPPS $7, (BX), X11                      // 66440f3a401b07
+	DPPS $7, (R11), X11                     // 66450f3a401b07
+	DPPS $7, X2, X11                        // 66440f3a40da07
+	DPPS $7, X11, X11                       // 66450f3a40db07
 	EMMS                                    // 0f77
 	//TODO: ENTERQ $0x12, $0xf123           // c823f112
-	//TODO: EXTRACTPS $7, X2, (BX)          // 660f3a171307
-	//TODO: EXTRACTPS $7, X11, (BX)         // 66440f3a171b07
-	//TODO: EXTRACTPS $7, X2, (R11)         // 66410f3a171307
-	//TODO: EXTRACTPS $7, X11, (R11)        // 66450f3a171b07
-	//TODO: EXTRACTPS $7, X2, DX            // 660f3a17d207
-	//TODO: EXTRACTPS $7, X11, DX           // 66440f3a17da07
-	//TODO: EXTRACTPS $7, X2, R11           // 66410f3a17d307
-	//TODO: EXTRACTPS $7, X11, R11          // 66450f3a17db07
+	EXTRACTPS $0, X2, (BX)                  // 660f3a171300
+	EXTRACTPS $1, X11, (BX)                 // 66440f3a171b01
+	EXTRACTPS $2, X2, (R11)                 // 66410f3a171302
+	EXTRACTPS $3, X11, (R11)                // 66450f3a171b03
+	EXTRACTPS $3, X2, DX                    // 660f3a17d203
+	EXTRACTPS $2, X11, DX                   // 66440f3a17da02
+	EXTRACTPS $1, X2, R11                   // 66410f3a17d301
+	EXTRACTPS $0, X11, R11                  // 66450f3a17db00
 	F2XM1                                   // d9f0
 	FABS                                    // d9e1
 	FADDD F2, F0                            // d8c2
@@ -2042,14 +2042,14 @@
 	INCB R11                                // 41fec3
 	INSB                                    // 6c
 	INSL                                    // 6d
-	//TODO: INSERTPS $7, (BX), X2           // 660f3a211307
-	//TODO: INSERTPS $7, (R11), X2          // 66410f3a211307
-	//TODO: INSERTPS $7, X2, X2             // 660f3a21d207
-	//TODO: INSERTPS $7, X11, X2            // 66410f3a21d307
-	//TODO: INSERTPS $7, (BX), X11          // 66440f3a211b07
-	//TODO: INSERTPS $7, (R11), X11         // 66450f3a211b07
-	//TODO: INSERTPS $7, X2, X11            // 66440f3a21da07
-	//TODO: INSERTPS $7, X11, X11           // 66450f3a21db07
+	INSERTPS $7, (BX), X2                   // 660f3a211307
+	INSERTPS $7, (R11), X2                  // 66410f3a211307
+	INSERTPS $7, X2, X2                     // 660f3a21d207
+	INSERTPS $7, X11, X2                    // 66410f3a21d307
+	INSERTPS $7, (BX), X11                  // 66440f3a211b07
+	INSERTPS $7, (R11), X11                 // 66450f3a211b07
+	INSERTPS $7, X2, X11                    // 66440f3a21da07
+	INSERTPS $7, X11, X11                   // 66450f3a21db07
 	INSW                                    // 666d
 	//TODO: INT $3                          // cc
 	INT $7                                  // cd07
@@ -2641,10 +2641,10 @@
 	MOVNTO X11, (BX)                        // 66440fe71b
 	MOVNTO X2, (R11)                        // 66410fe713
 	MOVNTO X11, (R11)                       // 66450fe71b
-	//TODO: MOVNTDQA (BX), X2               // 660f382a13
-	//TODO: MOVNTDQA (R11), X2              // 66410f382a13
-	//TODO: MOVNTDQA (BX), X11              // 66440f382a1b
-	//TODO: MOVNTDQA (R11), X11             // 66450f382a1b
+	MOVNTDQA (BX), X2                       // 660f382a13
+	MOVNTDQA (R11), X2                      // 66410f382a13
+	MOVNTDQA (BX), X11                      // 66440f382a1b
+	MOVNTDQA (R11), X11                     // 66450f382a1b
 	MOVNTIL DX, (BX)                        // 0fc313
 	MOVNTIL R11, (BX)                       // 440fc31b
 	MOVNTIL DX, (R11)                       // 410fc313
@@ -2857,14 +2857,14 @@
 	//TODO: MOVBQZX (R11), R11              // 4d0fb61b
 	//TODO: MOVBQZX DL, R11                 // 4c0fb6da
 	//TODO: MOVBQZX R11, R11                // 4d0fb6db
-	//TODO: MPSADBW $7, (BX), X2            // 660f3a421307
-	//TODO: MPSADBW $7, (R11), X2           // 66410f3a421307
-	//TODO: MPSADBW $7, X2, X2              // 660f3a42d207
-	//TODO: MPSADBW $7, X11, X2             // 66410f3a42d307
-	//TODO: MPSADBW $7, (BX), X11           // 66440f3a421b07
-	//TODO: MPSADBW $7, (R11), X11          // 66450f3a421b07
-	//TODO: MPSADBW $7, X2, X11             // 66440f3a42da07
-	//TODO: MPSADBW $7, X11, X11            // 66450f3a42db07
+	MPSADBW $7, (BX), X2                    // 660f3a421307
+	MPSADBW $7, (R11), X2                   // 66410f3a421307
+	MPSADBW $7, X2, X2                      // 660f3a42d207
+	MPSADBW $7, X11, X2                     // 66410f3a42d307
+	MPSADBW $7, (BX), X11                   // 66440f3a421b07
+	MPSADBW $7, (R11), X11                  // 66450f3a421b07
+	MPSADBW $7, X2, X11                     // 66440f3a42da07
+	MPSADBW $7, X11, X11                    // 66450f3a42db07
 	MULW (BX)                               // 66f723
 	MULW (R11)                              // 6641f723
 	MULW DX                                 // 66f7e2
@@ -3083,14 +3083,14 @@
 	//TODO: PABSB (R11), M3                 // 410f381c1b
 	//TODO: PABSB M2, M3                    // 0f381cda
 	//TODO: PABSB M3, M3                    // 0f381cdb
-	//TODO: PABSB (BX), X2                  // 660f381c13
-	//TODO: PABSB (R11), X2                 // 66410f381c13
-	//TODO: PABSB X2, X2                    // 660f381cd2
-	//TODO: PABSB X11, X2                   // 66410f381cd3
-	//TODO: PABSB (BX), X11                 // 66440f381c1b
-	//TODO: PABSB (R11), X11                // 66450f381c1b
-	//TODO: PABSB X2, X11                   // 66440f381cda
-	//TODO: PABSB X11, X11                  // 66450f381cdb
+	PABSB (BX), X2                          // 660f381c13
+	PABSB (R11), X2                         // 66410f381c13
+	PABSB X2, X2                            // 660f381cd2
+	PABSB X11, X2                           // 66410f381cd3
+	PABSB (BX), X11                         // 66440f381c1b
+	PABSB (R11), X11                        // 66450f381c1b
+	PABSB X2, X11                           // 66440f381cda
+	PABSB X11, X11                          // 66450f381cdb
 	//TODO: PABSD (BX), M2                  // 0f381e13
 	//TODO: PABSD (R11), M2                 // 410f381e13
 	//TODO: PABSD M2, M2                    // 0f381ed2
@@ -3099,14 +3099,14 @@
 	//TODO: PABSD (R11), M3                 // 410f381e1b
 	//TODO: PABSD M2, M3                    // 0f381eda
 	//TODO: PABSD M3, M3                    // 0f381edb
-	//TODO: PABSD (BX), X2                  // 660f381e13
-	//TODO: PABSD (R11), X2                 // 66410f381e13
-	//TODO: PABSD X2, X2                    // 660f381ed2
-	//TODO: PABSD X11, X2                   // 66410f381ed3
-	//TODO: PABSD (BX), X11                 // 66440f381e1b
-	//TODO: PABSD (R11), X11                // 66450f381e1b
-	//TODO: PABSD X2, X11                   // 66440f381eda
-	//TODO: PABSD X11, X11                  // 66450f381edb
+	PABSD (BX), X2                          // 660f381e13
+	PABSD (R11), X2                         // 66410f381e13
+	PABSD X2, X2                            // 660f381ed2
+	PABSD X11, X2                           // 66410f381ed3
+	PABSD (BX), X11                         // 66440f381e1b
+	PABSD (R11), X11                        // 66450f381e1b
+	PABSD X2, X11                           // 66440f381eda
+	PABSD X11, X11                          // 66450f381edb
 	//TODO: PABSW (BX), M2                  // 0f381d13
 	//TODO: PABSW (R11), M2                 // 410f381d13
 	//TODO: PABSW M2, M2                    // 0f381dd2
@@ -3115,14 +3115,14 @@
 	//TODO: PABSW (R11), M3                 // 410f381d1b
 	//TODO: PABSW M2, M3                    // 0f381dda
 	//TODO: PABSW M3, M3                    // 0f381ddb
-	//TODO: PABSW (BX), X2                  // 660f381d13
-	//TODO: PABSW (R11), X2                 // 66410f381d13
-	//TODO: PABSW X2, X2                    // 660f381dd2
-	//TODO: PABSW X11, X2                   // 66410f381dd3
-	//TODO: PABSW (BX), X11                 // 66440f381d1b
-	//TODO: PABSW (R11), X11                // 66450f381d1b
-	//TODO: PABSW X2, X11                   // 66440f381dda
-	//TODO: PABSW X11, X11                  // 66450f381ddb
+	PABSW (BX), X2                          // 660f381d13
+	PABSW (R11), X2                         // 66410f381d13
+	PABSW X2, X2                            // 660f381dd2
+	PABSW X11, X2                           // 66410f381dd3
+	PABSW (BX), X11                         // 66440f381d1b
+	PABSW (R11), X11                        // 66450f381d1b
+	PABSW X2, X11                           // 66440f381dda
+	PABSW X11, X11                          // 66450f381ddb
 	PACKSSLW (BX), M2                       // 0f6b13
 	PACKSSLW (R11), M2                      // 410f6b13
 	PACKSSLW M2, M2                         // 0f6bd2
@@ -3155,14 +3155,14 @@
 	PACKSSWB (R11), X11                     // 66450f631b
 	PACKSSWB X2, X11                        // 66440f63da
 	PACKSSWB X11, X11                       // 66450f63db
-	//TODO: PACKUSDW (BX), X2               // 660f382b13
-	//TODO: PACKUSDW (R11), X2              // 66410f382b13
-	//TODO: PACKUSDW X2, X2                 // 660f382bd2
-	//TODO: PACKUSDW X11, X2                // 66410f382bd3
-	//TODO: PACKUSDW (BX), X11              // 66440f382b1b
-	//TODO: PACKUSDW (R11), X11             // 66450f382b1b
-	//TODO: PACKUSDW X2, X11                // 66440f382bda
-	//TODO: PACKUSDW X11, X11               // 66450f382bdb
+	PACKUSDW (BX), X2                       // 660f382b13
+	PACKUSDW (R11), X2                      // 66410f382b13
+	PACKUSDW X2, X2                         // 660f382bd2
+	PACKUSDW X11, X2                        // 66410f382bd3
+	PACKUSDW (BX), X11                      // 66440f382b1b
+	PACKUSDW (R11), X11                     // 66450f382b1b
+	PACKUSDW X2, X11                        // 66440f382bda
+	PACKUSDW X11, X11                       // 66450f382bdb
 	PACKUSWB (BX), M2                       // 0f6713
 	PACKUSWB (R11), M2                      // 410f6713
 	PACKUSWB M2, M2                         // 0f67d2
@@ -3315,14 +3315,14 @@
 	//TODO: PALIGNR $7, (R11), M3           // 410f3a0f1b07
 	//TODO: PALIGNR $7, M2, M3              // 0f3a0fda07
 	//TODO: PALIGNR $7, M3, M3              // 0f3a0fdb07
-	//TODO: PALIGNR $7, (BX), X2            // 660f3a0f1307
-	//TODO: PALIGNR $7, (R11), X2           // 66410f3a0f1307
-	//TODO: PALIGNR $7, X2, X2              // 660f3a0fd207
-	//TODO: PALIGNR $7, X11, X2             // 66410f3a0fd307
-	//TODO: PALIGNR $7, (BX), X11           // 66440f3a0f1b07
-	//TODO: PALIGNR $7, (R11), X11          // 66450f3a0f1b07
-	//TODO: PALIGNR $7, X2, X11             // 66440f3a0fda07
-	//TODO: PALIGNR $7, X11, X11            // 66450f3a0fdb07
+	PALIGNR $7, (BX), X2                    // 660f3a0f1307
+	PALIGNR $7, (R11), X2                   // 66410f3a0f1307
+	PALIGNR $7, X2, X2                      // 660f3a0fd207
+	PALIGNR $7, X11, X2                     // 66410f3a0fd307
+	PALIGNR $7, (BX), X11                   // 66440f3a0f1b07
+	PALIGNR $7, (R11), X11                  // 66450f3a0f1b07
+	PALIGNR $7, X2, X11                     // 66440f3a0fda07
+	PALIGNR $7, X11, X11                    // 66450f3a0fdb07
 	PAND (BX), M2                           // 0fdb13
 	PAND (R11), M2                          // 410fdb13
 	PAND M2, M2                             // 0fdbd2
@@ -3395,14 +3395,14 @@
 	//TODO: PBLENDVB XMM0, (R11), X11       // 66450f38101b
 	//TODO: PBLENDVB XMM0, X2, X11          // 66440f3810da
 	//TODO: PBLENDVB XMM0, X11, X11         // 66450f3810db
-	//TODO: PBLENDW $7, (BX), X2            // 660f3a0e1307
-	//TODO: PBLENDW $7, (R11), X2           // 66410f3a0e1307
-	//TODO: PBLENDW $7, X2, X2              // 660f3a0ed207
-	//TODO: PBLENDW $7, X11, X2             // 66410f3a0ed307
-	//TODO: PBLENDW $7, (BX), X11           // 66440f3a0e1b07
-	//TODO: PBLENDW $7, (R11), X11          // 66450f3a0e1b07
-	//TODO: PBLENDW $7, X2, X11             // 66440f3a0eda07
-	//TODO: PBLENDW $7, X11, X11            // 66450f3a0edb07
+	PBLENDW $7, (BX), X2                    // 660f3a0e1307
+	PBLENDW $7, (R11), X2                   // 66410f3a0e1307
+	PBLENDW $7, X2, X2                      // 660f3a0ed207
+	PBLENDW $7, X11, X2                     // 66410f3a0ed307
+	PBLENDW $7, (BX), X11                   // 66440f3a0e1b07
+	PBLENDW $7, (R11), X11                  // 66450f3a0e1b07
+	PBLENDW $7, X2, X11                     // 66440f3a0eda07
+	PBLENDW $7, X11, X11                    // 66450f3a0edb07
 	PCLMULQDQ $7, (BX), X2                  // 660f3a441307
 	PCLMULQDQ $7, (R11), X2                 // 66410f3a441307
 	PCLMULQDQ $7, X2, X2                    // 660f3a44d207
@@ -3443,14 +3443,14 @@
 	PCMPEQL (R11), X11                      // 66450f761b
 	PCMPEQL X2, X11                         // 66440f76da
 	PCMPEQL X11, X11                        // 66450f76db
-	//TODO: PCMPEQQ (BX), X2                // 660f382913
-	//TODO: PCMPEQQ (R11), X2               // 66410f382913
-	//TODO: PCMPEQQ X2, X2                  // 660f3829d2
-	//TODO: PCMPEQQ X11, X2                 // 66410f3829d3
-	//TODO: PCMPEQQ (BX), X11               // 66440f38291b
-	//TODO: PCMPEQQ (R11), X11              // 66450f38291b
-	//TODO: PCMPEQQ X2, X11                 // 66440f3829da
-	//TODO: PCMPEQQ X11, X11                // 66450f3829db
+	PCMPEQQ (BX), X2                        // 660f382913
+	PCMPEQQ (R11), X2                       // 66410f382913
+	PCMPEQQ X2, X2                          // 660f3829d2
+	PCMPEQQ X11, X2                         // 66410f3829d3
+	PCMPEQQ (BX), X11                       // 66440f38291b
+	PCMPEQQ (R11), X11                      // 66450f38291b
+	PCMPEQQ X2, X11                         // 66440f3829da
+	PCMPEQQ X11, X11                        // 66450f3829db
 	PCMPEQW (BX), M2                        // 0f7513
 	PCMPEQW (R11), M2                       // 410f7513
 	PCMPEQW M2, M2                          // 0f75d2
@@ -3467,22 +3467,22 @@
 	PCMPEQW (R11), X11                      // 66450f751b
 	PCMPEQW X2, X11                         // 66440f75da
 	PCMPEQW X11, X11                        // 66450f75db
-	//TODO: PCMPESTRI $7, (BX), X2          // 660f3a611307
-	//TODO: PCMPESTRI $7, (R11), X2         // 66410f3a611307
-	//TODO: PCMPESTRI $7, X2, X2            // 660f3a61d207
-	//TODO: PCMPESTRI $7, X11, X2           // 66410f3a61d307
-	//TODO: PCMPESTRI $7, (BX), X11         // 66440f3a611b07
-	//TODO: PCMPESTRI $7, (R11), X11        // 66450f3a611b07
-	//TODO: PCMPESTRI $7, X2, X11           // 66440f3a61da07
-	//TODO: PCMPESTRI $7, X11, X11          // 66450f3a61db07
-	//TODO: PCMPESTRM $7, (BX), X2          // 660f3a601307
-	//TODO: PCMPESTRM $7, (R11), X2         // 66410f3a601307
-	//TODO: PCMPESTRM $7, X2, X2            // 660f3a60d207
-	//TODO: PCMPESTRM $7, X11, X2           // 66410f3a60d307
-	//TODO: PCMPESTRM $7, (BX), X11         // 66440f3a601b07
-	//TODO: PCMPESTRM $7, (R11), X11        // 66450f3a601b07
-	//TODO: PCMPESTRM $7, X2, X11           // 66440f3a60da07
-	//TODO: PCMPESTRM $7, X11, X11          // 66450f3a60db07
+	PCMPESTRI $7, (BX), X2                  // 660f3a611307
+	PCMPESTRI $7, (R11), X2                 // 66410f3a611307
+	PCMPESTRI $7, X2, X2                    // 660f3a61d207
+	PCMPESTRI $7, X11, X2                   // 66410f3a61d307
+	PCMPESTRI $7, (BX), X11                 // 66440f3a611b07
+	PCMPESTRI $7, (R11), X11                // 66450f3a611b07
+	PCMPESTRI $7, X2, X11                   // 66440f3a61da07
+	PCMPESTRI $7, X11, X11                  // 66450f3a61db07
+	PCMPESTRM $7, (BX), X2                  // 660f3a601307
+	PCMPESTRM $7, (R11), X2                 // 66410f3a601307
+	PCMPESTRM $7, X2, X2                    // 660f3a60d207
+	PCMPESTRM $7, X11, X2                   // 66410f3a60d307
+	PCMPESTRM $7, (BX), X11                 // 66440f3a601b07
+	PCMPESTRM $7, (R11), X11                // 66450f3a601b07
+	PCMPESTRM $7, X2, X11                   // 66440f3a60da07
+	PCMPESTRM $7, X11, X11                  // 66450f3a60db07
 	PCMPGTB (BX), M2                        // 0f6413
 	PCMPGTB (R11), M2                       // 410f6413
 	PCMPGTB M2, M2                          // 0f64d2
@@ -3515,14 +3515,14 @@
 	PCMPGTL (R11), X11                      // 66450f661b
 	PCMPGTL X2, X11                         // 66440f66da
 	PCMPGTL X11, X11                        // 66450f66db
-	//TODO: PCMPGTQ (BX), X2                // 660f383713
-	//TODO: PCMPGTQ (R11), X2               // 66410f383713
-	//TODO: PCMPGTQ X2, X2                  // 660f3837d2
-	//TODO: PCMPGTQ X11, X2                 // 66410f3837d3
-	//TODO: PCMPGTQ (BX), X11               // 66440f38371b
-	//TODO: PCMPGTQ (R11), X11              // 66450f38371b
-	//TODO: PCMPGTQ X2, X11                 // 66440f3837da
-	//TODO: PCMPGTQ X11, X11                // 66450f3837db
+	PCMPGTQ (BX), X2                        // 660f383713
+	PCMPGTQ (R11), X2                       // 66410f383713
+	PCMPGTQ X2, X2                          // 660f3837d2
+	PCMPGTQ X11, X2                         // 66410f3837d3
+	PCMPGTQ (BX), X11                       // 66440f38371b
+	PCMPGTQ (R11), X11                      // 66450f38371b
+	PCMPGTQ X2, X11                         // 66440f3837da
+	PCMPGTQ X11, X11                        // 66450f3837db
 	PCMPGTW (BX), M2                        // 0f6513
 	PCMPGTW (R11), M2                       // 410f6513
 	PCMPGTW M2, M2                          // 0f65d2
@@ -3539,22 +3539,22 @@
 	PCMPGTW (R11), X11                      // 66450f651b
 	PCMPGTW X2, X11                         // 66440f65da
 	PCMPGTW X11, X11                        // 66450f65db
-	//TODO: PCMPISTRI $7, (BX), X2          // 660f3a631307
-	//TODO: PCMPISTRI $7, (R11), X2         // 66410f3a631307
-	//TODO: PCMPISTRI $7, X2, X2            // 660f3a63d207
-	//TODO: PCMPISTRI $7, X11, X2           // 66410f3a63d307
-	//TODO: PCMPISTRI $7, (BX), X11         // 66440f3a631b07
-	//TODO: PCMPISTRI $7, (R11), X11        // 66450f3a631b07
-	//TODO: PCMPISTRI $7, X2, X11           // 66440f3a63da07
-	//TODO: PCMPISTRI $7, X11, X11          // 66450f3a63db07
-	//TODO: PCMPISTRM $7, (BX), X2          // 660f3a621307
-	//TODO: PCMPISTRM $7, (R11), X2         // 66410f3a621307
-	//TODO: PCMPISTRM $7, X2, X2            // 660f3a62d207
-	//TODO: PCMPISTRM $7, X11, X2           // 66410f3a62d307
-	//TODO: PCMPISTRM $7, (BX), X11         // 66440f3a621b07
-	//TODO: PCMPISTRM $7, (R11), X11        // 66450f3a621b07
-	//TODO: PCMPISTRM $7, X2, X11           // 66440f3a62da07
-	//TODO: PCMPISTRM $7, X11, X11          // 66450f3a62db07
+	PCMPISTRI $7, (BX), X2                  // 660f3a631307
+	PCMPISTRI $7, (R11), X2                 // 66410f3a631307
+	PCMPISTRI $7, X2, X2                    // 660f3a63d207
+	PCMPISTRI $7, X11, X2                   // 66410f3a63d307
+	PCMPISTRI $7, (BX), X11                 // 66440f3a631b07
+	PCMPISTRI $7, (R11), X11                // 66450f3a631b07
+	PCMPISTRI $7, X2, X11                   // 66440f3a63da07
+	PCMPISTRI $7, X11, X11                  // 66450f3a63db07
+	PCMPISTRM $7, (BX), X2                  // 660f3a621307
+	PCMPISTRM $7, (R11), X2                 // 66410f3a621307
+	PCMPISTRM $7, X2, X2                    // 660f3a62d207
+	PCMPISTRM $7, X11, X2                   // 66410f3a62d307
+	PCMPISTRM $7, (BX), X11                 // 66440f3a621b07
+	PCMPISTRM $7, (R11), X11                // 66450f3a621b07
+	PCMPISTRM $7, X2, X11                   // 66440f3a62da07
+	PCMPISTRM $7, X11, X11                  // 66450f3a62db07
 	PDEPL (BX), R9, DX                      // c4e233f513
 	PDEPL (R11), R9, DX                     // c4c233f513
 	PDEPL DX, R9, DX                        // c4e233f5d2
@@ -3647,14 +3647,14 @@
 	//TODO: PHADDSW (R11), M3               // 410f38031b
 	//TODO: PHADDSW M2, M3                  // 0f3803da
 	//TODO: PHADDSW M3, M3                  // 0f3803db
-	//TODO: PHADDSW (BX), X2                // 660f380313
-	//TODO: PHADDSW (R11), X2               // 66410f380313
-	//TODO: PHADDSW X2, X2                  // 660f3803d2
-	//TODO: PHADDSW X11, X2                 // 66410f3803d3
-	//TODO: PHADDSW (BX), X11               // 66440f38031b
-	//TODO: PHADDSW (R11), X11              // 66450f38031b
-	//TODO: PHADDSW X2, X11                 // 66440f3803da
-	//TODO: PHADDSW X11, X11                // 66450f3803db
+	PHADDSW (BX), X2                        // 660f380313
+	PHADDSW (R11), X2                       // 66410f380313
+	PHADDSW X2, X2                          // 660f3803d2
+	PHADDSW X11, X2                         // 66410f3803d3
+	PHADDSW (BX), X11                       // 66440f38031b
+	PHADDSW (R11), X11                      // 66450f38031b
+	PHADDSW X2, X11                         // 66440f3803da
+	PHADDSW X11, X11                        // 66450f3803db
 	//TODO: PHADDW (BX), M2                 // 0f380113
 	//TODO: PHADDW (R11), M2                // 410f380113
 	//TODO: PHADDW M2, M2                   // 0f3801d2
@@ -3663,22 +3663,22 @@
 	//TODO: PHADDW (R11), M3                // 410f38011b
 	//TODO: PHADDW M2, M3                   // 0f3801da
 	//TODO: PHADDW M3, M3                   // 0f3801db
-	//TODO: PHADDW (BX), X2                 // 660f380113
-	//TODO: PHADDW (R11), X2                // 66410f380113
-	//TODO: PHADDW X2, X2                   // 660f3801d2
-	//TODO: PHADDW X11, X2                  // 66410f3801d3
-	//TODO: PHADDW (BX), X11                // 66440f38011b
-	//TODO: PHADDW (R11), X11               // 66450f38011b
-	//TODO: PHADDW X2, X11                  // 66440f3801da
-	//TODO: PHADDW X11, X11                 // 66450f3801db
-	//TODO: PHMINPOSUW (BX), X2             // 660f384113
-	//TODO: PHMINPOSUW (R11), X2            // 66410f384113
-	//TODO: PHMINPOSUW X2, X2               // 660f3841d2
-	//TODO: PHMINPOSUW X11, X2              // 66410f3841d3
-	//TODO: PHMINPOSUW (BX), X11            // 66440f38411b
-	//TODO: PHMINPOSUW (R11), X11           // 66450f38411b
-	//TODO: PHMINPOSUW X2, X11              // 66440f3841da
-	//TODO: PHMINPOSUW X11, X11             // 66450f3841db
+	PHADDW (BX), X2                         // 660f380113
+	PHADDW (R11), X2                        // 66410f380113
+	PHADDW X2, X2                           // 660f3801d2
+	PHADDW X11, X2                          // 66410f3801d3
+	PHADDW (BX), X11                        // 66440f38011b
+	PHADDW (R11), X11                       // 66450f38011b
+	PHADDW X2, X11                          // 66440f3801da
+	PHADDW X11, X11                         // 66450f3801db
+	PHMINPOSUW (BX), X2                     // 660f384113
+	PHMINPOSUW (R11), X2                    // 66410f384113
+	PHMINPOSUW X2, X2                       // 660f3841d2
+	PHMINPOSUW X11, X2                      // 66410f3841d3
+	PHMINPOSUW (BX), X11                    // 66440f38411b
+	PHMINPOSUW (R11), X11                   // 66450f38411b
+	PHMINPOSUW X2, X11                      // 66440f3841da
+	PHMINPOSUW X11, X11                     // 66450f3841db
 	//TODO: PHSUBD (BX), M2                 // 0f380613
 	//TODO: PHSUBD (R11), M2                // 410f380613
 	//TODO: PHSUBD M2, M2                   // 0f3806d2
@@ -3687,14 +3687,14 @@
 	//TODO: PHSUBD (R11), M3                // 410f38061b
 	//TODO: PHSUBD M2, M3                   // 0f3806da
 	//TODO: PHSUBD M3, M3                   // 0f3806db
-	//TODO: PHSUBD (BX), X2                 // 660f380613
-	//TODO: PHSUBD (R11), X2                // 66410f380613
-	//TODO: PHSUBD X2, X2                   // 660f3806d2
-	//TODO: PHSUBD X11, X2                  // 66410f3806d3
-	//TODO: PHSUBD (BX), X11                // 66440f38061b
-	//TODO: PHSUBD (R11), X11               // 66450f38061b
-	//TODO: PHSUBD X2, X11                  // 66440f3806da
-	//TODO: PHSUBD X11, X11                 // 66450f3806db
+	PHSUBD (BX), X2                         // 660f380613
+	PHSUBD (R11), X2                        // 66410f380613
+	PHSUBD X2, X2                           // 660f3806d2
+	PHSUBD X11, X2                          // 66410f3806d3
+	PHSUBD (BX), X11                        // 66440f38061b
+	PHSUBD (R11), X11                       // 66450f38061b
+	PHSUBD X2, X11                          // 66440f3806da
+	PHSUBD X11, X11                         // 66450f3806db
 	//TODO: PHSUBSW (BX), M2                // 0f380713
 	//TODO: PHSUBSW (R11), M2               // 410f380713
 	//TODO: PHSUBSW M2, M2                  // 0f3807d2
@@ -3703,14 +3703,14 @@
 	//TODO: PHSUBSW (R11), M3               // 410f38071b
 	//TODO: PHSUBSW M2, M3                  // 0f3807da
 	//TODO: PHSUBSW M3, M3                  // 0f3807db
-	//TODO: PHSUBSW (BX), X2                // 660f380713
-	//TODO: PHSUBSW (R11), X2               // 66410f380713
-	//TODO: PHSUBSW X2, X2                  // 660f3807d2
-	//TODO: PHSUBSW X11, X2                 // 66410f3807d3
-	//TODO: PHSUBSW (BX), X11               // 66440f38071b
-	//TODO: PHSUBSW (R11), X11              // 66450f38071b
-	//TODO: PHSUBSW X2, X11                 // 66440f3807da
-	//TODO: PHSUBSW X11, X11                // 66450f3807db
+	PHSUBSW (BX), X2                        // 660f380713
+	PHSUBSW (R11), X2                       // 66410f380713
+	PHSUBSW X2, X2                          // 660f3807d2
+	PHSUBSW X11, X2                         // 66410f3807d3
+	PHSUBSW (BX), X11                       // 66440f38071b
+	PHSUBSW (R11), X11                      // 66450f38071b
+	PHSUBSW X2, X11                         // 66440f3807da
+	PHSUBSW X11, X11                        // 66450f3807db
 	//TODO: PHSUBW (BX), M2                 // 0f380513
 	//TODO: PHSUBW (R11), M2                // 410f380513
 	//TODO: PHSUBW M2, M2                   // 0f3805d2
@@ -3719,14 +3719,14 @@
 	//TODO: PHSUBW (R11), M3                // 410f38051b
 	//TODO: PHSUBW M2, M3                   // 0f3805da
 	//TODO: PHSUBW M3, M3                   // 0f3805db
-	//TODO: PHSUBW (BX), X2                 // 660f380513
-	//TODO: PHSUBW (R11), X2                // 66410f380513
-	//TODO: PHSUBW X2, X2                   // 660f3805d2
-	//TODO: PHSUBW X11, X2                  // 66410f3805d3
-	//TODO: PHSUBW (BX), X11                // 66440f38051b
-	//TODO: PHSUBW (R11), X11               // 66450f38051b
-	//TODO: PHSUBW X2, X11                  // 66440f3805da
-	//TODO: PHSUBW X11, X11                 // 66450f3805db
+	PHSUBW (BX), X2                         // 660f380513
+	PHSUBW (R11), X2                        // 66410f380513
+	PHSUBW X2, X2                           // 660f3805d2
+	PHSUBW X11, X2                          // 66410f3805d3
+	PHSUBW (BX), X11                        // 66440f38051b
+	PHSUBW (R11), X11                       // 66450f38051b
+	PHSUBW X2, X11                          // 66440f3805da
+	PHSUBW X11, X11                         // 66450f3805db
 	PINSRB $7, (BX), X2                     // 660f3a201307
 	PINSRB $7, (R11), X2                    // 66410f3a201307
 	PINSRB $7, DX, X2                       // 660f3a20d207
@@ -3775,14 +3775,14 @@
 	//TODO: PMADDUBSW (R11), M3             // 410f38041b
 	//TODO: PMADDUBSW M2, M3                // 0f3804da
 	//TODO: PMADDUBSW M3, M3                // 0f3804db
-	//TODO: PMADDUBSW (BX), X2              // 660f380413
-	//TODO: PMADDUBSW (R11), X2             // 66410f380413
-	//TODO: PMADDUBSW X2, X2                // 660f3804d2
-	//TODO: PMADDUBSW X11, X2               // 66410f3804d3
-	//TODO: PMADDUBSW (BX), X11             // 66440f38041b
-	//TODO: PMADDUBSW (R11), X11            // 66450f38041b
-	//TODO: PMADDUBSW X2, X11               // 66440f3804da
-	//TODO: PMADDUBSW X11, X11              // 66450f3804db
+	PMADDUBSW (BX), X2                      // 660f380413
+	PMADDUBSW (R11), X2                     // 66410f380413
+	PMADDUBSW X2, X2                        // 660f3804d2
+	PMADDUBSW X11, X2                       // 66410f3804d3
+	PMADDUBSW (BX), X11                     // 66440f38041b
+	PMADDUBSW (R11), X11                    // 66450f38041b
+	PMADDUBSW X2, X11                       // 66440f3804da
+	PMADDUBSW X11, X11                      // 66450f3804db
 	PMADDWL (BX), M2                        // 0ff513
 	PMADDWL (R11), M2                       // 410ff513
 	PMADDWL M2, M2                          // 0ff5d2
@@ -3799,22 +3799,22 @@
 	PMADDWL (R11), X11                      // 66450ff51b
 	PMADDWL X2, X11                         // 66440ff5da
 	PMADDWL X11, X11                        // 66450ff5db
-	//TODO: PMAXSB (BX), X2                 // 660f383c13
-	//TODO: PMAXSB (R11), X2                // 66410f383c13
-	//TODO: PMAXSB X2, X2                   // 660f383cd2
-	//TODO: PMAXSB X11, X2                  // 66410f383cd3
-	//TODO: PMAXSB (BX), X11                // 66440f383c1b
-	//TODO: PMAXSB (R11), X11               // 66450f383c1b
-	//TODO: PMAXSB X2, X11                  // 66440f383cda
-	//TODO: PMAXSB X11, X11                 // 66450f383cdb
-	//TODO: PMAXSD (BX), X2                 // 660f383d13
-	//TODO: PMAXSD (R11), X2                // 66410f383d13
-	//TODO: PMAXSD X2, X2                   // 660f383dd2
-	//TODO: PMAXSD X11, X2                  // 66410f383dd3
-	//TODO: PMAXSD (BX), X11                // 66440f383d1b
-	//TODO: PMAXSD (R11), X11               // 66450f383d1b
-	//TODO: PMAXSD X2, X11                  // 66440f383dda
-	//TODO: PMAXSD X11, X11                 // 66450f383ddb
+	PMAXSB (BX), X2                         // 660f383c13
+	PMAXSB (R11), X2                        // 66410f383c13
+	PMAXSB X2, X2                           // 660f383cd2
+	PMAXSB X11, X2                          // 66410f383cd3
+	PMAXSB (BX), X11                        // 66440f383c1b
+	PMAXSB (R11), X11                       // 66450f383c1b
+	PMAXSB X2, X11                          // 66440f383cda
+	PMAXSB X11, X11                         // 66450f383cdb
+	PMAXSD (BX), X2                         // 660f383d13
+	PMAXSD (R11), X2                        // 66410f383d13
+	PMAXSD X2, X2                           // 660f383dd2
+	PMAXSD X11, X2                          // 66410f383dd3
+	PMAXSD (BX), X11                        // 66440f383d1b
+	PMAXSD (R11), X11                       // 66450f383d1b
+	PMAXSD X2, X11                          // 66440f383dda
+	PMAXSD X11, X11                         // 66450f383ddb
 	//TODO: PMAXSW (BX), M2                 // 0fee13
 	//TODO: PMAXSW (R11), M2                // 410fee13
 	//TODO: PMAXSW M2, M2                   // 0feed2
@@ -3847,38 +3847,38 @@
 	PMAXUB (R11), X11                       // 66450fde1b
 	PMAXUB X2, X11                          // 66440fdeda
 	PMAXUB X11, X11                         // 66450fdedb
-	//TODO: PMAXUD (BX), X2                 // 660f383f13
-	//TODO: PMAXUD (R11), X2                // 66410f383f13
-	//TODO: PMAXUD X2, X2                   // 660f383fd2
-	//TODO: PMAXUD X11, X2                  // 66410f383fd3
-	//TODO: PMAXUD (BX), X11                // 66440f383f1b
-	//TODO: PMAXUD (R11), X11               // 66450f383f1b
-	//TODO: PMAXUD X2, X11                  // 66440f383fda
-	//TODO: PMAXUD X11, X11                 // 66450f383fdb
-	//TODO: PMAXUW (BX), X2                 // 660f383e13
-	//TODO: PMAXUW (R11), X2                // 66410f383e13
-	//TODO: PMAXUW X2, X2                   // 660f383ed2
-	//TODO: PMAXUW X11, X2                  // 66410f383ed3
-	//TODO: PMAXUW (BX), X11                // 66440f383e1b
-	//TODO: PMAXUW (R11), X11               // 66450f383e1b
-	//TODO: PMAXUW X2, X11                  // 66440f383eda
-	//TODO: PMAXUW X11, X11                 // 66450f383edb
-	//TODO: PMINSB (BX), X2                 // 660f383813
-	//TODO: PMINSB (R11), X2                // 66410f383813
-	//TODO: PMINSB X2, X2                   // 660f3838d2
-	//TODO: PMINSB X11, X2                  // 66410f3838d3
-	//TODO: PMINSB (BX), X11                // 66440f38381b
-	//TODO: PMINSB (R11), X11               // 66450f38381b
-	//TODO: PMINSB X2, X11                  // 66440f3838da
-	//TODO: PMINSB X11, X11                 // 66450f3838db
-	//TODO: PMINSD (BX), X2                 // 660f383913
-	//TODO: PMINSD (R11), X2                // 66410f383913
-	//TODO: PMINSD X2, X2                   // 660f3839d2
-	//TODO: PMINSD X11, X2                  // 66410f3839d3
-	//TODO: PMINSD (BX), X11                // 66440f38391b
-	//TODO: PMINSD (R11), X11               // 66450f38391b
-	//TODO: PMINSD X2, X11                  // 66440f3839da
-	//TODO: PMINSD X11, X11                 // 66450f3839db
+	PMAXUD (BX), X2                         // 660f383f13
+	PMAXUD (R11), X2                        // 66410f383f13
+	PMAXUD X2, X2                           // 660f383fd2
+	PMAXUD X11, X2                          // 66410f383fd3
+	PMAXUD (BX), X11                        // 66440f383f1b
+	PMAXUD (R11), X11                       // 66450f383f1b
+	PMAXUD X2, X11                          // 66440f383fda
+	PMAXUD X11, X11                         // 66450f383fdb
+	PMAXUW (BX), X2                         // 660f383e13
+	PMAXUW (R11), X2                        // 66410f383e13
+	PMAXUW X2, X2                           // 660f383ed2
+	PMAXUW X11, X2                          // 66410f383ed3
+	PMAXUW (BX), X11                        // 66440f383e1b
+	PMAXUW (R11), X11                       // 66450f383e1b
+	PMAXUW X2, X11                          // 66440f383eda
+	PMAXUW X11, X11                         // 66450f383edb
+	PMINSB (BX), X2                         // 660f383813
+	PMINSB (R11), X2                        // 66410f383813
+	PMINSB X2, X2                           // 660f3838d2
+	PMINSB X11, X2                          // 66410f3838d3
+	PMINSB (BX), X11                        // 66440f38381b
+	PMINSB (R11), X11                       // 66450f38381b
+	PMINSB X2, X11                          // 66440f3838da
+	PMINSB X11, X11                         // 66450f3838db
+	PMINSD (BX), X2                         // 660f383913
+	PMINSD (R11), X2                        // 66410f383913
+	PMINSD X2, X2                           // 660f3839d2
+	PMINSD X11, X2                          // 66410f3839d3
+	PMINSD (BX), X11                        // 66440f38391b
+	PMINSD (R11), X11                       // 66450f38391b
+	PMINSD X2, X11                          // 66440f3839da
+	PMINSD X11, X11                         // 66450f3839db
 	//TODO: PMINSW (BX), M2                 // 0fea13
 	//TODO: PMINSW (R11), M2                // 410fea13
 	//TODO: PMINSW M2, M2                   // 0fead2
@@ -3911,22 +3911,22 @@
 	PMINUB (R11), X11                       // 66450fda1b
 	PMINUB X2, X11                          // 66440fdada
 	PMINUB X11, X11                         // 66450fdadb
-	//TODO: PMINUD (BX), X2                 // 660f383b13
-	//TODO: PMINUD (R11), X2                // 66410f383b13
-	//TODO: PMINUD X2, X2                   // 660f383bd2
-	//TODO: PMINUD X11, X2                  // 66410f383bd3
-	//TODO: PMINUD (BX), X11                // 66440f383b1b
-	//TODO: PMINUD (R11), X11               // 66450f383b1b
-	//TODO: PMINUD X2, X11                  // 66440f383bda
-	//TODO: PMINUD X11, X11                 // 66450f383bdb
-	//TODO: PMINUW (BX), X2                 // 660f383a13
-	//TODO: PMINUW (R11), X2                // 66410f383a13
-	//TODO: PMINUW X2, X2                   // 660f383ad2
-	//TODO: PMINUW X11, X2                  // 66410f383ad3
-	//TODO: PMINUW (BX), X11                // 66440f383a1b
-	//TODO: PMINUW (R11), X11               // 66450f383a1b
-	//TODO: PMINUW X2, X11                  // 66440f383ada
-	//TODO: PMINUW X11, X11                 // 66450f383adb
+	PMINUD (BX), X2                         // 660f383b13
+	PMINUD (R11), X2                        // 66410f383b13
+	PMINUD X2, X2                           // 660f383bd2
+	PMINUD X11, X2                          // 66410f383bd3
+	PMINUD (BX), X11                        // 66440f383b1b
+	PMINUD (R11), X11                       // 66450f383b1b
+	PMINUD X2, X11                          // 66440f383bda
+	PMINUD X11, X11                         // 66450f383bdb
+	PMINUW (BX), X2                         // 660f383a13
+	PMINUW (R11), X2                        // 66410f383a13
+	PMINUW X2, X2                           // 660f383ad2
+	PMINUW X11, X2                          // 66410f383ad3
+	PMINUW (BX), X11                        // 66440f383a1b
+	PMINUW (R11), X11                       // 66450f383a1b
+	PMINUW X2, X11                          // 66440f383ada
+	PMINUW X11, X11                         // 66450f383adb
 	PMOVMSKB M2, DX                         // 0fd7d2
 	PMOVMSKB M3, DX                         // 0fd7d3
 	PMOVMSKB M2, R11                        // 440fd7da
@@ -4047,14 +4047,14 @@
 	//TODO: PMULHRSW (R11), M3              // 410f380b1b
 	//TODO: PMULHRSW M2, M3                 // 0f380bda
 	//TODO: PMULHRSW M3, M3                 // 0f380bdb
-	//TODO: PMULHRSW (BX), X2               // 660f380b13
-	//TODO: PMULHRSW (R11), X2              // 66410f380b13
-	//TODO: PMULHRSW X2, X2                 // 660f380bd2
-	//TODO: PMULHRSW X11, X2                // 66410f380bd3
-	//TODO: PMULHRSW (BX), X11              // 66440f380b1b
-	//TODO: PMULHRSW (R11), X11             // 66450f380b1b
-	//TODO: PMULHRSW X2, X11                // 66440f380bda
-	//TODO: PMULHRSW X11, X11               // 66450f380bdb
+	PMULHRSW (BX), X2                       // 660f380b13
+	PMULHRSW (R11), X2                      // 66410f380b13
+	PMULHRSW X2, X2                         // 660f380bd2
+	PMULHRSW X11, X2                        // 66410f380bd3
+	PMULHRSW (BX), X11                      // 66440f380b1b
+	PMULHRSW (R11), X11                     // 66450f380b1b
+	PMULHRSW X2, X11                        // 66440f380bda
+	PMULHRSW X11, X11                       // 66450f380bdb
 	PMULHUW (BX), M2                        // 0fe413
 	PMULHUW (R11), M2                       // 410fe413
 	PMULHUW M2, M2                          // 0fe4d2
@@ -4283,14 +4283,14 @@
 	//TODO: PSIGNB (R11), M3                // 410f38081b
 	//TODO: PSIGNB M2, M3                   // 0f3808da
 	//TODO: PSIGNB M3, M3                   // 0f3808db
-	//TODO: PSIGNB (BX), X2                 // 660f380813
-	//TODO: PSIGNB (R11), X2                // 66410f380813
-	//TODO: PSIGNB X2, X2                   // 660f3808d2
-	//TODO: PSIGNB X11, X2                  // 66410f3808d3
-	//TODO: PSIGNB (BX), X11                // 66440f38081b
-	//TODO: PSIGNB (R11), X11               // 66450f38081b
-	//TODO: PSIGNB X2, X11                  // 66440f3808da
-	//TODO: PSIGNB X11, X11                 // 66450f3808db
+	PSIGNB (BX), X2                         // 660f380813
+	PSIGNB (R11), X2                        // 66410f380813
+	PSIGNB X2, X2                           // 660f3808d2
+	PSIGNB X11, X2                          // 66410f3808d3
+	PSIGNB (BX), X11                        // 66440f38081b
+	PSIGNB (R11), X11                       // 66450f38081b
+	PSIGNB X2, X11                          // 66440f3808da
+	PSIGNB X11, X11                         // 66450f3808db
 	//TODO: PSIGND (BX), M2                 // 0f380a13
 	//TODO: PSIGND (R11), M2                // 410f380a13
 	//TODO: PSIGND M2, M2                   // 0f380ad2
@@ -4299,14 +4299,14 @@
 	//TODO: PSIGND (R11), M3                // 410f380a1b
 	//TODO: PSIGND M2, M3                   // 0f380ada
 	//TODO: PSIGND M3, M3                   // 0f380adb
-	//TODO: PSIGND (BX), X2                 // 660f380a13
-	//TODO: PSIGND (R11), X2                // 66410f380a13
-	//TODO: PSIGND X2, X2                   // 660f380ad2
-	//TODO: PSIGND X11, X2                  // 66410f380ad3
-	//TODO: PSIGND (BX), X11                // 66440f380a1b
-	//TODO: PSIGND (R11), X11               // 66450f380a1b
-	//TODO: PSIGND X2, X11                  // 66440f380ada
-	//TODO: PSIGND X11, X11                 // 66450f380adb
+	PSIGND (BX), X2                         // 660f380a13
+	PSIGND (R11), X2                        // 66410f380a13
+	PSIGND X2, X2                           // 660f380ad2
+	PSIGND X11, X2                          // 66410f380ad3
+	PSIGND (BX), X11                        // 66440f380a1b
+	PSIGND (R11), X11                       // 66450f380a1b
+	PSIGND X2, X11                          // 66440f380ada
+	PSIGND X11, X11                         // 66450f380adb
 	//TODO: PSIGNW (BX), M2                 // 0f380913
 	//TODO: PSIGNW (R11), M2                // 410f380913
 	//TODO: PSIGNW M2, M2                   // 0f3809d2
@@ -4315,14 +4315,14 @@
 	//TODO: PSIGNW (R11), M3                // 410f38091b
 	//TODO: PSIGNW M2, M3                   // 0f3809da
 	//TODO: PSIGNW M3, M3                   // 0f3809db
-	//TODO: PSIGNW (BX), X2                 // 660f380913
-	//TODO: PSIGNW (R11), X2                // 66410f380913
-	//TODO: PSIGNW X2, X2                   // 660f3809d2
-	//TODO: PSIGNW X11, X2                  // 66410f3809d3
-	//TODO: PSIGNW (BX), X11                // 66440f38091b
-	//TODO: PSIGNW (R11), X11               // 66450f38091b
-	//TODO: PSIGNW X2, X11                  // 66440f3809da
-	//TODO: PSIGNW X11, X11                 // 66450f3809db
+	PSIGNW (BX), X2                         // 660f380913
+	PSIGNW (R11), X2                        // 66410f380913
+	PSIGNW X2, X2                           // 660f3809d2
+	PSIGNW X11, X2                          // 66410f3809d3
+	PSIGNW (BX), X11                        // 66440f38091b
+	PSIGNW (R11), X11                       // 66450f38091b
+	PSIGNW X2, X11                          // 66440f3809da
+	PSIGNW X11, X11                         // 66450f3809db
 	PSLLL (BX), M2                          // 0ff213
 	PSLLL (R11), M2                         // 410ff213
 	PSLLL M2, M2                            // 0ff2d2
@@ -4615,14 +4615,14 @@
 	PSUBW (R11), X11                        // 66450ff91b
 	PSUBW X2, X11                           // 66440ff9da
 	PSUBW X11, X11                          // 66450ff9db
-	//TODO: PTEST (BX), X2                  // 660f381713
-	//TODO: PTEST (R11), X2                 // 66410f381713
-	//TODO: PTEST X2, X2                    // 660f3817d2
-	//TODO: PTEST X11, X2                   // 66410f3817d3
-	//TODO: PTEST (BX), X11                 // 66440f38171b
-	//TODO: PTEST (R11), X11                // 66450f38171b
-	//TODO: PTEST X2, X11                   // 66440f3817da
-	//TODO: PTEST X11, X11                  // 66450f3817db
+	PTEST (BX), X2                          // 660f381713
+	PTEST (R11), X2                         // 66410f381713
+	PTEST X2, X2                            // 660f3817d2
+	PTEST X11, X2                           // 66410f3817d3
+	PTEST (BX), X11                         // 66440f38171b
+	PTEST (R11), X11                        // 66450f38171b
+	PTEST X2, X11                           // 66440f3817da
+	PTEST X11, X11                          // 66450f3817db
 	PUNPCKHBW (BX), M2                      // 0f6813
 	PUNPCKHBW (R11), M2                     // 410f6813
 	PUNPCKHBW M2, M2                        // 0f68d2
@@ -5854,270 +5854,270 @@
 	UNPCKLPS (R11), X11                     // 450f141b
 	UNPCKLPS X2, X11                        // 440f14da
 	UNPCKLPS X11, X11                       // 450f14db
-	//TODO: VADDPD (BX), X9, X2             // c4e1315813 or c5b15813
-	//TODO: VADDPD (R11), X9, X2            // c4c1315813
-	//TODO: VADDPD X2, X9, X2               // c4e13158d2 or c5b158d2
-	//TODO: VADDPD X11, X9, X2              // c4c13158d3
-	//TODO: VADDPD (BX), X9, X11            // c46131581b or c531581b
-	//TODO: VADDPD (R11), X9, X11           // c44131581b
-	//TODO: VADDPD X2, X9, X11              // c4613158da or c53158da
-	//TODO: VADDPD X11, X9, X11             // c4413158db
-	//TODO: VADDPD (BX), Y15, Y2            // c4e1055813 or c5855813
-	//TODO: VADDPD (R11), Y15, Y2           // c4c1055813
-	//TODO: VADDPD Y2, Y15, Y2              // c4e10558d2 or c58558d2
-	//TODO: VADDPD Y11, Y15, Y2             // c4c10558d3
-	//TODO: VADDPD (BX), Y15, Y11           // c46105581b or c505581b
-	//TODO: VADDPD (R11), Y15, Y11          // c44105581b
-	//TODO: VADDPD Y2, Y15, Y11             // c4610558da or c50558da
-	//TODO: VADDPD Y11, Y15, Y11            // c4410558db
-	//TODO: VADDPS (BX), X9, X2             // c4e1305813 or c5b05813
-	//TODO: VADDPS (R11), X9, X2            // c4c1305813
-	//TODO: VADDPS X2, X9, X2               // c4e13058d2 or c5b058d2
-	//TODO: VADDPS X11, X9, X2              // c4c13058d3
-	//TODO: VADDPS (BX), X9, X11            // c46130581b or c530581b
-	//TODO: VADDPS (R11), X9, X11           // c44130581b
-	//TODO: VADDPS X2, X9, X11              // c4613058da or c53058da
-	//TODO: VADDPS X11, X9, X11             // c4413058db
-	//TODO: VADDPS (BX), Y15, Y2            // c4e1045813 or c5845813
-	//TODO: VADDPS (R11), Y15, Y2           // c4c1045813
-	//TODO: VADDPS Y2, Y15, Y2              // c4e10458d2 or c58458d2
-	//TODO: VADDPS Y11, Y15, Y2             // c4c10458d3
-	//TODO: VADDPS (BX), Y15, Y11           // c46104581b or c504581b
-	//TODO: VADDPS (R11), Y15, Y11          // c44104581b
-	//TODO: VADDPS Y2, Y15, Y11             // c4610458da or c50458da
-	//TODO: VADDPS Y11, Y15, Y11            // c4410458db
-	//TODO: VADDSD (BX), X9, X2             // c4e1335813 or c5b35813
-	//TODO: VADDSD (R11), X9, X2            // c4c1335813
-	//TODO: VADDSD X2, X9, X2               // c4e13358d2 or c5b358d2
-	//TODO: VADDSD X11, X9, X2              // c4c13358d3
-	//TODO: VADDSD (BX), X9, X11            // c46133581b or c533581b
-	//TODO: VADDSD (R11), X9, X11           // c44133581b
-	//TODO: VADDSD X2, X9, X11              // c4613358da or c53358da
-	//TODO: VADDSD X11, X9, X11             // c4413358db
-	//TODO: VADDSS (BX), X9, X2             // c4e1325813 or c5b25813
-	//TODO: VADDSS (R11), X9, X2            // c4c1325813
-	//TODO: VADDSS X2, X9, X2               // c4e13258d2 or c5b258d2
-	//TODO: VADDSS X11, X9, X2              // c4c13258d3
-	//TODO: VADDSS (BX), X9, X11            // c46132581b or c532581b
-	//TODO: VADDSS (R11), X9, X11           // c44132581b
-	//TODO: VADDSS X2, X9, X11              // c4613258da or c53258da
-	//TODO: VADDSS X11, X9, X11             // c4413258db
-	//TODO: VADDSUBPD (BX), X9, X2          // c4e131d013 or c5b1d013
-	//TODO: VADDSUBPD (R11), X9, X2         // c4c131d013
-	//TODO: VADDSUBPD X2, X9, X2            // c4e131d0d2 or c5b1d0d2
-	//TODO: VADDSUBPD X11, X9, X2           // c4c131d0d3
-	//TODO: VADDSUBPD (BX), X9, X11         // c46131d01b or c531d01b
-	//TODO: VADDSUBPD (R11), X9, X11        // c44131d01b
-	//TODO: VADDSUBPD X2, X9, X11           // c46131d0da or c531d0da
-	//TODO: VADDSUBPD X11, X9, X11          // c44131d0db
-	//TODO: VADDSUBPD (BX), Y15, Y2         // c4e105d013 or c585d013
-	//TODO: VADDSUBPD (R11), Y15, Y2        // c4c105d013
-	//TODO: VADDSUBPD Y2, Y15, Y2           // c4e105d0d2 or c585d0d2
-	//TODO: VADDSUBPD Y11, Y15, Y2          // c4c105d0d3
-	//TODO: VADDSUBPD (BX), Y15, Y11        // c46105d01b or c505d01b
-	//TODO: VADDSUBPD (R11), Y15, Y11       // c44105d01b
-	//TODO: VADDSUBPD Y2, Y15, Y11          // c46105d0da or c505d0da
-	//TODO: VADDSUBPD Y11, Y15, Y11         // c44105d0db
-	//TODO: VADDSUBPS (BX), X9, X2          // c4e133d013 or c5b3d013
-	//TODO: VADDSUBPS (R11), X9, X2         // c4c133d013
-	//TODO: VADDSUBPS X2, X9, X2            // c4e133d0d2 or c5b3d0d2
-	//TODO: VADDSUBPS X11, X9, X2           // c4c133d0d3
-	//TODO: VADDSUBPS (BX), X9, X11         // c46133d01b or c533d01b
-	//TODO: VADDSUBPS (R11), X9, X11        // c44133d01b
-	//TODO: VADDSUBPS X2, X9, X11           // c46133d0da or c533d0da
-	//TODO: VADDSUBPS X11, X9, X11          // c44133d0db
-	//TODO: VADDSUBPS (BX), Y15, Y2         // c4e107d013 or c587d013
-	//TODO: VADDSUBPS (R11), Y15, Y2        // c4c107d013
-	//TODO: VADDSUBPS Y2, Y15, Y2           // c4e107d0d2 or c587d0d2
-	//TODO: VADDSUBPS Y11, Y15, Y2          // c4c107d0d3
-	//TODO: VADDSUBPS (BX), Y15, Y11        // c46107d01b or c507d01b
-	//TODO: VADDSUBPS (R11), Y15, Y11       // c44107d01b
-	//TODO: VADDSUBPS Y2, Y15, Y11          // c46107d0da or c507d0da
-	//TODO: VADDSUBPS Y11, Y15, Y11         // c44107d0db
-	//TODO: VAESDEC (BX), X9, X2            // c4e231de13
-	//TODO: VAESDEC (R11), X9, X2           // c4c231de13
-	//TODO: VAESDEC X2, X9, X2              // c4e231ded2
-	//TODO: VAESDEC X11, X9, X2             // c4c231ded3
-	//TODO: VAESDEC (BX), X9, X11           // c46231de1b
-	//TODO: VAESDEC (R11), X9, X11          // c44231de1b
-	//TODO: VAESDEC X2, X9, X11             // c46231deda
-	//TODO: VAESDEC X11, X9, X11            // c44231dedb
-	//TODO: VAESDECLAST (BX), X9, X2        // c4e231df13
-	//TODO: VAESDECLAST (R11), X9, X2       // c4c231df13
-	//TODO: VAESDECLAST X2, X9, X2          // c4e231dfd2
-	//TODO: VAESDECLAST X11, X9, X2         // c4c231dfd3
-	//TODO: VAESDECLAST (BX), X9, X11       // c46231df1b
-	//TODO: VAESDECLAST (R11), X9, X11      // c44231df1b
-	//TODO: VAESDECLAST X2, X9, X11         // c46231dfda
-	//TODO: VAESDECLAST X11, X9, X11        // c44231dfdb
-	//TODO: VAESENC (BX), X9, X2            // c4e231dc13
-	//TODO: VAESENC (R11), X9, X2           // c4c231dc13
-	//TODO: VAESENC X2, X9, X2              // c4e231dcd2
-	//TODO: VAESENC X11, X9, X2             // c4c231dcd3
-	//TODO: VAESENC (BX), X9, X11           // c46231dc1b
-	//TODO: VAESENC (R11), X9, X11          // c44231dc1b
-	//TODO: VAESENC X2, X9, X11             // c46231dcda
-	//TODO: VAESENC X11, X9, X11            // c44231dcdb
-	//TODO: VAESENCLAST (BX), X9, X2        // c4e231dd13
-	//TODO: VAESENCLAST (R11), X9, X2       // c4c231dd13
-	//TODO: VAESENCLAST X2, X9, X2          // c4e231ddd2
-	//TODO: VAESENCLAST X11, X9, X2         // c4c231ddd3
-	//TODO: VAESENCLAST (BX), X9, X11       // c46231dd1b
-	//TODO: VAESENCLAST (R11), X9, X11      // c44231dd1b
-	//TODO: VAESENCLAST X2, X9, X11         // c46231ddda
-	//TODO: VAESENCLAST X11, X9, X11        // c44231dddb
-	//TODO: VAESIMC (BX), X2                // c4e279db13
-	//TODO: VAESIMC (R11), X2               // c4c279db13
-	//TODO: VAESIMC X2, X2                  // c4e279dbd2
-	//TODO: VAESIMC X11, X2                 // c4c279dbd3
-	//TODO: VAESIMC (BX), X11               // c46279db1b
-	//TODO: VAESIMC (R11), X11              // c44279db1b
-	//TODO: VAESIMC X2, X11                 // c46279dbda
-	//TODO: VAESIMC X11, X11                // c44279dbdb
-	//TODO: VAESKEYGENASSIST $7, (BX), X2   // c4e379df1307
-	//TODO: VAESKEYGENASSIST $7, (R11), X2  // c4c379df1307
-	//TODO: VAESKEYGENASSIST $7, X2, X2     // c4e379dfd207
-	//TODO: VAESKEYGENASSIST $7, X11, X2    // c4c379dfd307
-	//TODO: VAESKEYGENASSIST $7, (BX), X11  // c46379df1b07
-	//TODO: VAESKEYGENASSIST $7, (R11), X11 // c44379df1b07
-	//TODO: VAESKEYGENASSIST $7, X2, X11    // c46379dfda07
-	//TODO: VAESKEYGENASSIST $7, X11, X11   // c44379dfdb07
-	//TODO: VANDNPD (BX), X9, X2            // c4e1315513 or c5b15513
-	//TODO: VANDNPD (R11), X9, X2           // c4c1315513
-	//TODO: VANDNPD X2, X9, X2              // c4e13155d2 or c5b155d2
-	//TODO: VANDNPD X11, X9, X2             // c4c13155d3
-	//TODO: VANDNPD (BX), X9, X11           // c46131551b or c531551b
-	//TODO: VANDNPD (R11), X9, X11          // c44131551b
-	//TODO: VANDNPD X2, X9, X11             // c4613155da or c53155da
-	//TODO: VANDNPD X11, X9, X11            // c4413155db
-	//TODO: VANDNPD (BX), Y15, Y2           // c4e1055513 or c5855513
-	//TODO: VANDNPD (R11), Y15, Y2          // c4c1055513
-	//TODO: VANDNPD Y2, Y15, Y2             // c4e10555d2 or c58555d2
-	//TODO: VANDNPD Y11, Y15, Y2            // c4c10555d3
-	//TODO: VANDNPD (BX), Y15, Y11          // c46105551b or c505551b
-	//TODO: VANDNPD (R11), Y15, Y11         // c44105551b
-	//TODO: VANDNPD Y2, Y15, Y11            // c4610555da or c50555da
-	//TODO: VANDNPD Y11, Y15, Y11           // c4410555db
-	//TODO: VANDNPS (BX), X9, X2            // c4e1305513 or c5b05513
-	//TODO: VANDNPS (R11), X9, X2           // c4c1305513
-	//TODO: VANDNPS X2, X9, X2              // c4e13055d2 or c5b055d2
-	//TODO: VANDNPS X11, X9, X2             // c4c13055d3
-	//TODO: VANDNPS (BX), X9, X11           // c46130551b or c530551b
-	//TODO: VANDNPS (R11), X9, X11          // c44130551b
-	//TODO: VANDNPS X2, X9, X11             // c4613055da or c53055da
-	//TODO: VANDNPS X11, X9, X11            // c4413055db
-	//TODO: VANDNPS (BX), Y15, Y2           // c4e1045513 or c5845513
-	//TODO: VANDNPS (R11), Y15, Y2          // c4c1045513
-	//TODO: VANDNPS Y2, Y15, Y2             // c4e10455d2 or c58455d2
-	//TODO: VANDNPS Y11, Y15, Y2            // c4c10455d3
-	//TODO: VANDNPS (BX), Y15, Y11          // c46104551b or c504551b
-	//TODO: VANDNPS (R11), Y15, Y11         // c44104551b
-	//TODO: VANDNPS Y2, Y15, Y11            // c4610455da or c50455da
-	//TODO: VANDNPS Y11, Y15, Y11           // c4410455db
-	//TODO: VANDPD (BX), X9, X2             // c4e1315413 or c5b15413
-	//TODO: VANDPD (R11), X9, X2            // c4c1315413
-	//TODO: VANDPD X2, X9, X2               // c4e13154d2 or c5b154d2
-	//TODO: VANDPD X11, X9, X2              // c4c13154d3
-	//TODO: VANDPD (BX), X9, X11            // c46131541b or c531541b
-	//TODO: VANDPD (R11), X9, X11           // c44131541b
-	//TODO: VANDPD X2, X9, X11              // c4613154da or c53154da
-	//TODO: VANDPD X11, X9, X11             // c4413154db
-	//TODO: VANDPD (BX), Y15, Y2            // c4e1055413 or c5855413
-	//TODO: VANDPD (R11), Y15, Y2           // c4c1055413
-	//TODO: VANDPD Y2, Y15, Y2              // c4e10554d2 or c58554d2
-	//TODO: VANDPD Y11, Y15, Y2             // c4c10554d3
-	//TODO: VANDPD (BX), Y15, Y11           // c46105541b or c505541b
-	//TODO: VANDPD (R11), Y15, Y11          // c44105541b
-	//TODO: VANDPD Y2, Y15, Y11             // c4610554da or c50554da
-	//TODO: VANDPD Y11, Y15, Y11            // c4410554db
-	//TODO: VANDPS (BX), X9, X2             // c4e1305413 or c5b05413
-	//TODO: VANDPS (R11), X9, X2            // c4c1305413
-	//TODO: VANDPS X2, X9, X2               // c4e13054d2 or c5b054d2
-	//TODO: VANDPS X11, X9, X2              // c4c13054d3
-	//TODO: VANDPS (BX), X9, X11            // c46130541b or c530541b
-	//TODO: VANDPS (R11), X9, X11           // c44130541b
-	//TODO: VANDPS X2, X9, X11              // c4613054da or c53054da
-	//TODO: VANDPS X11, X9, X11             // c4413054db
-	//TODO: VANDPS (BX), Y15, Y2            // c4e1045413 or c5845413
-	//TODO: VANDPS (R11), Y15, Y2           // c4c1045413
-	//TODO: VANDPS Y2, Y15, Y2              // c4e10454d2 or c58454d2
-	//TODO: VANDPS Y11, Y15, Y2             // c4c10454d3
-	//TODO: VANDPS (BX), Y15, Y11           // c46104541b or c504541b
-	//TODO: VANDPS (R11), Y15, Y11          // c44104541b
-	//TODO: VANDPS Y2, Y15, Y11             // c4610454da or c50454da
-	//TODO: VANDPS Y11, Y15, Y11            // c4410454db
-	//TODO: VBLENDPD $7, (BX), X9, X2       // c4e3310d1307
-	//TODO: VBLENDPD $7, (R11), X9, X2      // c4c3310d1307
-	//TODO: VBLENDPD $7, X2, X9, X2         // c4e3310dd207
-	//TODO: VBLENDPD $7, X11, X9, X2        // c4c3310dd307
-	//TODO: VBLENDPD $7, (BX), X9, X11      // c463310d1b07
-	//TODO: VBLENDPD $7, (R11), X9, X11     // c443310d1b07
-	//TODO: VBLENDPD $7, X2, X9, X11        // c463310dda07
-	//TODO: VBLENDPD $7, X11, X9, X11       // c443310ddb07
-	//TODO: VBLENDPD $7, (BX), Y15, Y2      // c4e3050d1307
-	//TODO: VBLENDPD $7, (R11), Y15, Y2     // c4c3050d1307
-	//TODO: VBLENDPD $7, Y2, Y15, Y2        // c4e3050dd207
-	//TODO: VBLENDPD $7, Y11, Y15, Y2       // c4c3050dd307
-	//TODO: VBLENDPD $7, (BX), Y15, Y11     // c463050d1b07
-	//TODO: VBLENDPD $7, (R11), Y15, Y11    // c443050d1b07
-	//TODO: VBLENDPD $7, Y2, Y15, Y11       // c463050dda07
-	//TODO: VBLENDPD $7, Y11, Y15, Y11      // c443050ddb07
-	//TODO: VBLENDPS $7, (BX), X9, X2       // c4e3310c1307
-	//TODO: VBLENDPS $7, (R11), X9, X2      // c4c3310c1307
-	//TODO: VBLENDPS $7, X2, X9, X2         // c4e3310cd207
-	//TODO: VBLENDPS $7, X11, X9, X2        // c4c3310cd307
-	//TODO: VBLENDPS $7, (BX), X9, X11      // c463310c1b07
-	//TODO: VBLENDPS $7, (R11), X9, X11     // c443310c1b07
-	//TODO: VBLENDPS $7, X2, X9, X11        // c463310cda07
-	//TODO: VBLENDPS $7, X11, X9, X11       // c443310cdb07
-	//TODO: VBLENDPS $7, (BX), Y15, Y2      // c4e3050c1307
-	//TODO: VBLENDPS $7, (R11), Y15, Y2     // c4c3050c1307
-	//TODO: VBLENDPS $7, Y2, Y15, Y2        // c4e3050cd207
-	//TODO: VBLENDPS $7, Y11, Y15, Y2       // c4c3050cd307
-	//TODO: VBLENDPS $7, (BX), Y15, Y11     // c463050c1b07
-	//TODO: VBLENDPS $7, (R11), Y15, Y11    // c443050c1b07
-	//TODO: VBLENDPS $7, Y2, Y15, Y11       // c463050cda07
-	//TODO: VBLENDPS $7, Y11, Y15, Y11      // c443050cdb07
-	//TODO: VBLENDVPD XMM12, (BX), X9, X2   // c4e3314b13c0
-	//TODO: VBLENDVPD XMM12, (R11), X9, X2  // c4c3314b13c0
-	//TODO: VBLENDVPD XMM12, X2, X9, X2     // c4e3314bd2c0
-	//TODO: VBLENDVPD XMM12, X11, X9, X2    // c4c3314bd3c0
-	//TODO: VBLENDVPD XMM12, (BX), X9, X11  // c463314b1bc0
-	//TODO: VBLENDVPD XMM12, (R11), X9, X11 // c443314b1bc0
-	//TODO: VBLENDVPD XMM12, X2, X9, X11    // c463314bdac0
-	//TODO: VBLENDVPD XMM12, X11, X9, X11   // c443314bdbc0
-	//TODO: VBLENDVPD YMM13, (BX), Y15, Y2  // c4e3054b13d0
-	//TODO: VBLENDVPD YMM13, (R11), Y15, Y2 // c4c3054b13d0
-	//TODO: VBLENDVPD YMM13, Y2, Y15, Y2    // c4e3054bd2d0
-	//TODO: VBLENDVPD YMM13, Y11, Y15, Y2   // c4c3054bd3d0
-	//TODO: VBLENDVPD YMM13, (BX), Y15, Y11 // c463054b1bd0
-	//TODO: VBLENDVPD YMM13, (R11), Y15, Y11 // c443054b1bd0
-	//TODO: VBLENDVPD YMM13, Y2, Y15, Y11   // c463054bdad0
-	//TODO: VBLENDVPD YMM13, Y11, Y15, Y11  // c443054bdbd0
-	//TODO: VBLENDVPS XMM12, (BX), X9, X2   // c4e3314a13c0
-	//TODO: VBLENDVPS XMM12, (R11), X9, X2  // c4c3314a13c0
-	//TODO: VBLENDVPS XMM12, X2, X9, X2     // c4e3314ad2c0
-	//TODO: VBLENDVPS XMM12, X11, X9, X2    // c4c3314ad3c0
-	//TODO: VBLENDVPS XMM12, (BX), X9, X11  // c463314a1bc0
-	//TODO: VBLENDVPS XMM12, (R11), X9, X11 // c443314a1bc0
-	//TODO: VBLENDVPS XMM12, X2, X9, X11    // c463314adac0
-	//TODO: VBLENDVPS XMM12, X11, X9, X11   // c443314adbc0
-	//TODO: VBLENDVPS YMM13, (BX), Y15, Y2  // c4e3054a13d0
-	//TODO: VBLENDVPS YMM13, (R11), Y15, Y2 // c4c3054a13d0
-	//TODO: VBLENDVPS YMM13, Y2, Y15, Y2    // c4e3054ad2d0
-	//TODO: VBLENDVPS YMM13, Y11, Y15, Y2   // c4c3054ad3d0
-	//TODO: VBLENDVPS YMM13, (BX), Y15, Y11 // c463054a1bd0
-	//TODO: VBLENDVPS YMM13, (R11), Y15, Y11 // c443054a1bd0
-	//TODO: VBLENDVPS YMM13, Y2, Y15, Y11   // c463054adad0
-	//TODO: VBLENDVPS YMM13, Y11, Y15, Y11  // c443054adbd0
-	//TODO: VBROADCASTF128 (BX), Y2         // c4e27d1a13
-	//TODO: VBROADCASTF128 (R11), Y2        // c4c27d1a13
-	//TODO: VBROADCASTF128 (BX), Y11        // c4627d1a1b
-	//TODO: VBROADCASTF128 (R11), Y11       // c4427d1a1b
-	//TODO: VBROADCASTI128 (BX), Y2         // c4e27d5a13
-	//TODO: VBROADCASTI128 (R11), Y2        // c4c27d5a13
-	//TODO: VBROADCASTI128 (BX), Y11        // c4627d5a1b
-	//TODO: VBROADCASTI128 (R11), Y11       // c4427d5a1b
+	VADDPD (BX), X9, X2                     // c4e1315813 or c5b15813
+	VADDPD (R11), X9, X2                    // c4c1315813
+	VADDPD X2, X9, X2                       // c4e13158d2 or c5b158d2
+	VADDPD X11, X9, X2                      // c4c13158d3
+	VADDPD (BX), X9, X11                    // c46131581b or c531581b
+	VADDPD (R11), X9, X11                   // c44131581b
+	VADDPD X2, X9, X11                      // c4613158da or c53158da
+	VADDPD X11, X9, X11                     // c4413158db
+	VADDPD (BX), Y15, Y2                    // c4e1055813 or c5855813
+	VADDPD (R11), Y15, Y2                   // c4c1055813
+	VADDPD Y2, Y15, Y2                      // c4e10558d2 or c58558d2
+	VADDPD Y11, Y15, Y2                     // c4c10558d3
+	VADDPD (BX), Y15, Y11                   // c46105581b or c505581b
+	VADDPD (R11), Y15, Y11                  // c44105581b
+	VADDPD Y2, Y15, Y11                     // c4610558da or c50558da
+	VADDPD Y11, Y15, Y11                    // c4410558db
+	VADDPS (BX), X9, X2                     // c4e1305813 or c5b05813
+	VADDPS (R11), X9, X2                    // c4c1305813
+	VADDPS X2, X9, X2                       // c4e13058d2 or c5b058d2
+	VADDPS X11, X9, X2                      // c4c13058d3
+	VADDPS (BX), X9, X11                    // c46130581b or c530581b
+	VADDPS (R11), X9, X11                   // c44130581b
+	VADDPS X2, X9, X11                      // c4613058da or c53058da
+	VADDPS X11, X9, X11                     // c4413058db
+	VADDPS (BX), Y15, Y2                    // c4e1045813 or c5845813
+	VADDPS (R11), Y15, Y2                   // c4c1045813
+	VADDPS Y2, Y15, Y2                      // c4e10458d2 or c58458d2
+	VADDPS Y11, Y15, Y2                     // c4c10458d3
+	VADDPS (BX), Y15, Y11                   // c46104581b or c504581b
+	VADDPS (R11), Y15, Y11                  // c44104581b
+	VADDPS Y2, Y15, Y11                     // c4610458da or c50458da
+	VADDPS Y11, Y15, Y11                    // c4410458db
+	VADDSD (BX), X9, X2                     // c4e1335813 or c5b35813
+	VADDSD (R11), X9, X2                    // c4c1335813
+	VADDSD X2, X9, X2                       // c4e13358d2 or c5b358d2
+	VADDSD X11, X9, X2                      // c4c13358d3
+	VADDSD (BX), X9, X11                    // c46133581b or c533581b
+	VADDSD (R11), X9, X11                   // c44133581b
+	VADDSD X2, X9, X11                      // c4613358da or c53358da
+	VADDSD X11, X9, X11                     // c4413358db
+	VADDSS (BX), X9, X2                     // c4e1325813 or c5b25813
+	VADDSS (R11), X9, X2                    // c4c1325813
+	VADDSS X2, X9, X2                       // c4e13258d2 or c5b258d2
+	VADDSS X11, X9, X2                      // c4c13258d3
+	VADDSS (BX), X9, X11                    // c46132581b or c532581b
+	VADDSS (R11), X9, X11                   // c44132581b
+	VADDSS X2, X9, X11                      // c4613258da or c53258da
+	VADDSS X11, X9, X11                     // c4413258db
+	VADDSUBPD (BX), X9, X2                  // c4e131d013 or c5b1d013
+	VADDSUBPD (R11), X9, X2                 // c4c131d013
+	VADDSUBPD X2, X9, X2                    // c4e131d0d2 or c5b1d0d2
+	VADDSUBPD X11, X9, X2                   // c4c131d0d3
+	VADDSUBPD (BX), X9, X11                 // c46131d01b or c531d01b
+	VADDSUBPD (R11), X9, X11                // c44131d01b
+	VADDSUBPD X2, X9, X11                   // c46131d0da or c531d0da
+	VADDSUBPD X11, X9, X11                  // c44131d0db
+	VADDSUBPD (BX), Y15, Y2                 // c4e105d013 or c585d013
+	VADDSUBPD (R11), Y15, Y2                // c4c105d013
+	VADDSUBPD Y2, Y15, Y2                   // c4e105d0d2 or c585d0d2
+	VADDSUBPD Y11, Y15, Y2                  // c4c105d0d3
+	VADDSUBPD (BX), Y15, Y11                // c46105d01b or c505d01b
+	VADDSUBPD (R11), Y15, Y11               // c44105d01b
+	VADDSUBPD Y2, Y15, Y11                  // c46105d0da or c505d0da
+	VADDSUBPD Y11, Y15, Y11                 // c44105d0db
+	VADDSUBPS (BX), X9, X2                  // c4e133d013 or c5b3d013
+	VADDSUBPS (R11), X9, X2                 // c4c133d013
+	VADDSUBPS X2, X9, X2                    // c4e133d0d2 or c5b3d0d2
+	VADDSUBPS X11, X9, X2                   // c4c133d0d3
+	VADDSUBPS (BX), X9, X11                 // c46133d01b or c533d01b
+	VADDSUBPS (R11), X9, X11                // c44133d01b
+	VADDSUBPS X2, X9, X11                   // c46133d0da or c533d0da
+	VADDSUBPS X11, X9, X11                  // c44133d0db
+	VADDSUBPS (BX), Y15, Y2                 // c4e107d013 or c587d013
+	VADDSUBPS (R11), Y15, Y2                // c4c107d013
+	VADDSUBPS Y2, Y15, Y2                   // c4e107d0d2 or c587d0d2
+	VADDSUBPS Y11, Y15, Y2                  // c4c107d0d3
+	VADDSUBPS (BX), Y15, Y11                // c46107d01b or c507d01b
+	VADDSUBPS (R11), Y15, Y11               // c44107d01b
+	VADDSUBPS Y2, Y15, Y11                  // c46107d0da or c507d0da
+	VADDSUBPS Y11, Y15, Y11                 // c44107d0db
+	VAESDEC (BX), X9, X2                    // c4e231de13
+	VAESDEC (R11), X9, X2                   // c4c231de13
+	VAESDEC X2, X9, X2                      // c4e231ded2
+	VAESDEC X11, X9, X2                     // c4c231ded3
+	VAESDEC (BX), X9, X11                   // c46231de1b
+	VAESDEC (R11), X9, X11                  // c44231de1b
+	VAESDEC X2, X9, X11                     // c46231deda
+	VAESDEC X11, X9, X11                    // c44231dedb
+	VAESDECLAST (BX), X9, X2                // c4e231df13
+	VAESDECLAST (R11), X9, X2               // c4c231df13
+	VAESDECLAST X2, X9, X2                  // c4e231dfd2
+	VAESDECLAST X11, X9, X2                 // c4c231dfd3
+	VAESDECLAST (BX), X9, X11               // c46231df1b
+	VAESDECLAST (R11), X9, X11              // c44231df1b
+	VAESDECLAST X2, X9, X11                 // c46231dfda
+	VAESDECLAST X11, X9, X11                // c44231dfdb
+	VAESENC (BX), X9, X2                    // c4e231dc13
+	VAESENC (R11), X9, X2                   // c4c231dc13
+	VAESENC X2, X9, X2                      // c4e231dcd2
+	VAESENC X11, X9, X2                     // c4c231dcd3
+	VAESENC (BX), X9, X11                   // c46231dc1b
+	VAESENC (R11), X9, X11                  // c44231dc1b
+	VAESENC X2, X9, X11                     // c46231dcda
+	VAESENC X11, X9, X11                    // c44231dcdb
+	VAESENCLAST (BX), X9, X2                // c4e231dd13
+	VAESENCLAST (R11), X9, X2               // c4c231dd13
+	VAESENCLAST X2, X9, X2                  // c4e231ddd2
+	VAESENCLAST X11, X9, X2                 // c4c231ddd3
+	VAESENCLAST (BX), X9, X11               // c46231dd1b
+	VAESENCLAST (R11), X9, X11              // c44231dd1b
+	VAESENCLAST X2, X9, X11                 // c46231ddda
+	VAESENCLAST X11, X9, X11                // c44231dddb
+	VAESIMC (BX), X2                        // c4e279db13
+	VAESIMC (R11), X2                       // c4c279db13
+	VAESIMC X2, X2                          // c4e279dbd2
+	VAESIMC X11, X2                         // c4c279dbd3
+	VAESIMC (BX), X11                       // c46279db1b
+	VAESIMC (R11), X11                      // c44279db1b
+	VAESIMC X2, X11                         // c46279dbda
+	VAESIMC X11, X11                        // c44279dbdb
+	VAESKEYGENASSIST $7, (BX), X2           // c4e379df1307
+	VAESKEYGENASSIST $7, (R11), X2          // c4c379df1307
+	VAESKEYGENASSIST $7, X2, X2             // c4e379dfd207
+	VAESKEYGENASSIST $7, X11, X2            // c4c379dfd307
+	VAESKEYGENASSIST $7, (BX), X11          // c46379df1b07
+	VAESKEYGENASSIST $7, (R11), X11         // c44379df1b07
+	VAESKEYGENASSIST $7, X2, X11            // c46379dfda07
+	VAESKEYGENASSIST $7, X11, X11           // c44379dfdb07
+	VANDNPD (BX), X9, X2                    // c4e1315513 or c5b15513
+	VANDNPD (R11), X9, X2                   // c4c1315513
+	VANDNPD X2, X9, X2                      // c4e13155d2 or c5b155d2
+	VANDNPD X11, X9, X2                     // c4c13155d3
+	VANDNPD (BX), X9, X11                   // c46131551b or c531551b
+	VANDNPD (R11), X9, X11                  // c44131551b
+	VANDNPD X2, X9, X11                     // c4613155da or c53155da
+	VANDNPD X11, X9, X11                    // c4413155db
+	VANDNPD (BX), Y15, Y2                   // c4e1055513 or c5855513
+	VANDNPD (R11), Y15, Y2                  // c4c1055513
+	VANDNPD Y2, Y15, Y2                     // c4e10555d2 or c58555d2
+	VANDNPD Y11, Y15, Y2                    // c4c10555d3
+	VANDNPD (BX), Y15, Y11                  // c46105551b or c505551b
+	VANDNPD (R11), Y15, Y11                 // c44105551b
+	VANDNPD Y2, Y15, Y11                    // c4610555da or c50555da
+	VANDNPD Y11, Y15, Y11                   // c4410555db
+	VANDNPS (BX), X9, X2                    // c4e1305513 or c5b05513
+	VANDNPS (R11), X9, X2                   // c4c1305513
+	VANDNPS X2, X9, X2                      // c4e13055d2 or c5b055d2
+	VANDNPS X11, X9, X2                     // c4c13055d3
+	VANDNPS (BX), X9, X11                   // c46130551b or c530551b
+	VANDNPS (R11), X9, X11                  // c44130551b
+	VANDNPS X2, X9, X11                     // c4613055da or c53055da
+	VANDNPS X11, X9, X11                    // c4413055db
+	VANDNPS (BX), Y15, Y2                   // c4e1045513 or c5845513
+	VANDNPS (R11), Y15, Y2                  // c4c1045513
+	VANDNPS Y2, Y15, Y2                     // c4e10455d2 or c58455d2
+	VANDNPS Y11, Y15, Y2                    // c4c10455d3
+	VANDNPS (BX), Y15, Y11                  // c46104551b or c504551b
+	VANDNPS (R11), Y15, Y11                 // c44104551b
+	VANDNPS Y2, Y15, Y11                    // c4610455da or c50455da
+	VANDNPS Y11, Y15, Y11                   // c4410455db
+	VANDPD (BX), X9, X2                     // c4e1315413 or c5b15413
+	VANDPD (R11), X9, X2                    // c4c1315413
+	VANDPD X2, X9, X2                       // c4e13154d2 or c5b154d2
+	VANDPD X11, X9, X2                      // c4c13154d3
+	VANDPD (BX), X9, X11                    // c46131541b or c531541b
+	VANDPD (R11), X9, X11                   // c44131541b
+	VANDPD X2, X9, X11                      // c4613154da or c53154da
+	VANDPD X11, X9, X11                     // c4413154db
+	VANDPD (BX), Y15, Y2                    // c4e1055413 or c5855413
+	VANDPD (R11), Y15, Y2                   // c4c1055413
+	VANDPD Y2, Y15, Y2                      // c4e10554d2 or c58554d2
+	VANDPD Y11, Y15, Y2                     // c4c10554d3
+	VANDPD (BX), Y15, Y11                   // c46105541b or c505541b
+	VANDPD (R11), Y15, Y11                  // c44105541b
+	VANDPD Y2, Y15, Y11                     // c4610554da or c50554da
+	VANDPD Y11, Y15, Y11                    // c4410554db
+	VANDPS (BX), X9, X2                     // c4e1305413 or c5b05413
+	VANDPS (R11), X9, X2                    // c4c1305413
+	VANDPS X2, X9, X2                       // c4e13054d2 or c5b054d2
+	VANDPS X11, X9, X2                      // c4c13054d3
+	VANDPS (BX), X9, X11                    // c46130541b or c530541b
+	VANDPS (R11), X9, X11                   // c44130541b
+	VANDPS X2, X9, X11                      // c4613054da or c53054da
+	VANDPS X11, X9, X11                     // c4413054db
+	VANDPS (BX), Y15, Y2                    // c4e1045413 or c5845413
+	VANDPS (R11), Y15, Y2                   // c4c1045413
+	VANDPS Y2, Y15, Y2                      // c4e10454d2 or c58454d2
+	VANDPS Y11, Y15, Y2                     // c4c10454d3
+	VANDPS (BX), Y15, Y11                   // c46104541b or c504541b
+	VANDPS (R11), Y15, Y11                  // c44104541b
+	VANDPS Y2, Y15, Y11                     // c4610454da or c50454da
+	VANDPS Y11, Y15, Y11                    // c4410454db
+	VBLENDPD $7, (BX), X9, X2               // c4e3310d1307
+	VBLENDPD $7, (R11), X9, X2              // c4c3310d1307
+	VBLENDPD $7, X2, X9, X2                 // c4e3310dd207
+	VBLENDPD $7, X11, X9, X2                // c4c3310dd307
+	VBLENDPD $7, (BX), X9, X11              // c463310d1b07
+	VBLENDPD $7, (R11), X9, X11             // c443310d1b07
+	VBLENDPD $7, X2, X9, X11                // c463310dda07
+	VBLENDPD $7, X11, X9, X11               // c443310ddb07
+	VBLENDPD $7, (BX), Y15, Y2              // c4e3050d1307
+	VBLENDPD $7, (R11), Y15, Y2             // c4c3050d1307
+	VBLENDPD $7, Y2, Y15, Y2                // c4e3050dd207
+	VBLENDPD $7, Y11, Y15, Y2               // c4c3050dd307
+	VBLENDPD $7, (BX), Y15, Y11             // c463050d1b07
+	VBLENDPD $7, (R11), Y15, Y11            // c443050d1b07
+	VBLENDPD $7, Y2, Y15, Y11               // c463050dda07
+	VBLENDPD $7, Y11, Y15, Y11              // c443050ddb07
+	VBLENDPS $7, (BX), X9, X2               // c4e3310c1307
+	VBLENDPS $7, (R11), X9, X2              // c4c3310c1307
+	VBLENDPS $7, X2, X9, X2                 // c4e3310cd207
+	VBLENDPS $7, X11, X9, X2                // c4c3310cd307
+	VBLENDPS $7, (BX), X9, X11              // c463310c1b07
+	VBLENDPS $7, (R11), X9, X11             // c443310c1b07
+	VBLENDPS $7, X2, X9, X11                // c463310cda07
+	VBLENDPS $7, X11, X9, X11               // c443310cdb07
+	VBLENDPS $7, (BX), Y15, Y2              // c4e3050c1307
+	VBLENDPS $7, (R11), Y15, Y2             // c4c3050c1307
+	VBLENDPS $7, Y2, Y15, Y2                // c4e3050cd207
+	VBLENDPS $7, Y11, Y15, Y2               // c4c3050cd307
+	VBLENDPS $7, (BX), Y15, Y11             // c463050c1b07
+	VBLENDPS $7, (R11), Y15, Y11            // c443050c1b07
+	VBLENDPS $7, Y2, Y15, Y11               // c463050cda07
+	VBLENDPS $7, Y11, Y15, Y11              // c443050cdb07
+	VBLENDVPD X12, (BX), X9, X2             // c4e3314b13c0
+	VBLENDVPD X12, (R11), X9, X2            // c4c3314b13c0
+	VBLENDVPD X12, X2, X9, X2               // c4e3314bd2c0
+	VBLENDVPD X12, X11, X9, X2              // c4c3314bd3c0
+	VBLENDVPD X12, (BX), X9, X11            // c463314b1bc0
+	VBLENDVPD X12, (R11), X9, X11           // c443314b1bc0
+	VBLENDVPD X12, X2, X9, X11              // c463314bdac0
+	VBLENDVPD X12, X11, X9, X11             // c443314bdbc0
+	VBLENDVPD Y13, (BX), Y15, Y2            // c4e3054b13d0
+	VBLENDVPD Y13, (R11), Y15, Y2           // c4c3054b13d0
+	VBLENDVPD Y13, Y2, Y15, Y2              // c4e3054bd2d0
+	VBLENDVPD Y13, Y11, Y15, Y2             // c4c3054bd3d0
+	VBLENDVPD Y13, (BX), Y15, Y11           // c463054b1bd0
+	VBLENDVPD Y13, (R11), Y15, Y11          // c443054b1bd0
+	VBLENDVPD Y13, Y2, Y15, Y11             // c463054bdad0
+	VBLENDVPD Y13, Y11, Y15, Y11            // c443054bdbd0
+	VBLENDVPS X12, (BX), X9, X2             // c4e3314a13c0
+	VBLENDVPS X12, (R11), X9, X2            // c4c3314a13c0
+	VBLENDVPS X12, X2, X9, X2               // c4e3314ad2c0
+	VBLENDVPS X12, X11, X9, X2              // c4c3314ad3c0
+	VBLENDVPS X12, (BX), X9, X11            // c463314a1bc0
+	VBLENDVPS X12, (R11), X9, X11           // c443314a1bc0
+	VBLENDVPS X12, X2, X9, X11              // c463314adac0
+	VBLENDVPS X12, X11, X9, X11             // c443314adbc0
+	VBLENDVPS Y13, (BX), Y15, Y2            // c4e3054a13d0
+	VBLENDVPS Y13, (R11), Y15, Y2           // c4c3054a13d0
+	VBLENDVPS Y13, Y2, Y15, Y2              // c4e3054ad2d0
+	VBLENDVPS Y13, Y11, Y15, Y2             // c4c3054ad3d0
+	VBLENDVPS Y13, (BX), Y15, Y11           // c463054a1bd0
+	VBLENDVPS Y13, (R11), Y15, Y11          // c443054a1bd0
+	VBLENDVPS Y13, Y2, Y15, Y11             // c463054adad0
+	VBLENDVPS Y13, Y11, Y15, Y11            // c443054adbd0
+	VBROADCASTF128 (BX), Y2                 // c4e27d1a13
+	VBROADCASTF128 (R11), Y2                // c4c27d1a13
+	VBROADCASTF128 (BX), Y11                // c4627d1a1b
+	VBROADCASTF128 (R11), Y11               // c4427d1a1b
+	VBROADCASTI128 (BX), Y2                 // c4e27d5a13
+	VBROADCASTI128 (R11), Y2                // c4c27d5a13
+	VBROADCASTI128 (BX), Y11                // c4627d5a1b
+	VBROADCASTI128 (R11), Y11               // c4427d5a1b
 	VBROADCASTSD (BX), Y2                   // c4e27d1913
 	VBROADCASTSD (R11), Y2                  // c4c27d1913
 	VBROADCASTSD (BX), Y11                  // c4627d191b
@@ -6142,414 +6142,414 @@
 	VBROADCASTSS X11, Y2                    // c4c27d18d3
 	VBROADCASTSS X2, Y11                    // c4627d18da
 	VBROADCASTSS X11, Y11                   // c4427d18db
-	//TODO: VCMPPD $7, (BX), X9, X2         // c4e131c21307 or c5b1c21307
-	//TODO: VCMPPD $7, (R11), X9, X2        // c4c131c21307
-	//TODO: VCMPPD $7, X2, X9, X2           // c4e131c2d207 or c5b1c2d207
-	//TODO: VCMPPD $7, X11, X9, X2          // c4c131c2d307
-	//TODO: VCMPPD $7, (BX), X9, X11        // c46131c21b07 or c531c21b07
-	//TODO: VCMPPD $7, (R11), X9, X11       // c44131c21b07
-	//TODO: VCMPPD $7, X2, X9, X11          // c46131c2da07 or c531c2da07
-	//TODO: VCMPPD $7, X11, X9, X11         // c44131c2db07
-	//TODO: VCMPPD $7, (BX), Y15, Y2        // c4e105c21307 or c585c21307
-	//TODO: VCMPPD $7, (R11), Y15, Y2       // c4c105c21307
-	//TODO: VCMPPD $7, Y2, Y15, Y2          // c4e105c2d207 or c585c2d207
-	//TODO: VCMPPD $7, Y11, Y15, Y2         // c4c105c2d307
-	//TODO: VCMPPD $7, (BX), Y15, Y11       // c46105c21b07 or c505c21b07
-	//TODO: VCMPPD $7, (R11), Y15, Y11      // c44105c21b07
-	//TODO: VCMPPD $7, Y2, Y15, Y11         // c46105c2da07 or c505c2da07
-	//TODO: VCMPPD $7, Y11, Y15, Y11        // c44105c2db07
-	//TODO: VCMPPS $7, (BX), X9, X2         // c4e130c21307 or c5b0c21307
-	//TODO: VCMPPS $7, (R11), X9, X2        // c4c130c21307
-	//TODO: VCMPPS $7, X2, X9, X2           // c4e130c2d207 or c5b0c2d207
-	//TODO: VCMPPS $7, X11, X9, X2          // c4c130c2d307
-	//TODO: VCMPPS $7, (BX), X9, X11        // c46130c21b07 or c530c21b07
-	//TODO: VCMPPS $7, (R11), X9, X11       // c44130c21b07
-	//TODO: VCMPPS $7, X2, X9, X11          // c46130c2da07 or c530c2da07
-	//TODO: VCMPPS $7, X11, X9, X11         // c44130c2db07
-	//TODO: VCMPPS $7, (BX), Y15, Y2        // c4e104c21307 or c584c21307
-	//TODO: VCMPPS $7, (R11), Y15, Y2       // c4c104c21307
-	//TODO: VCMPPS $7, Y2, Y15, Y2          // c4e104c2d207 or c584c2d207
-	//TODO: VCMPPS $7, Y11, Y15, Y2         // c4c104c2d307
-	//TODO: VCMPPS $7, (BX), Y15, Y11       // c46104c21b07 or c504c21b07
-	//TODO: VCMPPS $7, (R11), Y15, Y11      // c44104c21b07
-	//TODO: VCMPPS $7, Y2, Y15, Y11         // c46104c2da07 or c504c2da07
-	//TODO: VCMPPS $7, Y11, Y15, Y11        // c44104c2db07
-	//TODO: VCMPSD $7, (BX), X9, X2         // c4e133c21307 or c5b3c21307
-	//TODO: VCMPSD $7, (R11), X9, X2        // c4c133c21307
-	//TODO: VCMPSD $7, X2, X9, X2           // c4e133c2d207 or c5b3c2d207
-	//TODO: VCMPSD $7, X11, X9, X2          // c4c133c2d307
-	//TODO: VCMPSD $7, (BX), X9, X11        // c46133c21b07 or c533c21b07
-	//TODO: VCMPSD $7, (R11), X9, X11       // c44133c21b07
-	//TODO: VCMPSD $7, X2, X9, X11          // c46133c2da07 or c533c2da07
-	//TODO: VCMPSD $7, X11, X9, X11         // c44133c2db07
-	//TODO: VCMPSS $7, (BX), X9, X2         // c4e132c21307 or c5b2c21307
-	//TODO: VCMPSS $7, (R11), X9, X2        // c4c132c21307
-	//TODO: VCMPSS $7, X2, X9, X2           // c4e132c2d207 or c5b2c2d207
-	//TODO: VCMPSS $7, X11, X9, X2          // c4c132c2d307
-	//TODO: VCMPSS $7, (BX), X9, X11        // c46132c21b07 or c532c21b07
-	//TODO: VCMPSS $7, (R11), X9, X11       // c44132c21b07
-	//TODO: VCMPSS $7, X2, X9, X11          // c46132c2da07 or c532c2da07
-	//TODO: VCMPSS $7, X11, X9, X11         // c44132c2db07
-	//TODO: VCOMISD (BX), X2                // c4e1792f13 or c5f92f13
-	//TODO: VCOMISD (R11), X2               // c4c1792f13
-	//TODO: VCOMISD X2, X2                  // c4e1792fd2 or c5f92fd2
-	//TODO: VCOMISD X11, X2                 // c4c1792fd3
-	//TODO: VCOMISD (BX), X11               // c461792f1b or c5792f1b
-	//TODO: VCOMISD (R11), X11              // c441792f1b
-	//TODO: VCOMISD X2, X11                 // c461792fda or c5792fda
-	//TODO: VCOMISD X11, X11                // c441792fdb
-	//TODO: VCOMISS (BX), X2                // c4e1782f13 or c5f82f13
-	//TODO: VCOMISS (R11), X2               // c4c1782f13
-	//TODO: VCOMISS X2, X2                  // c4e1782fd2 or c5f82fd2
-	//TODO: VCOMISS X11, X2                 // c4c1782fd3
-	//TODO: VCOMISS (BX), X11               // c461782f1b or c5782f1b
-	//TODO: VCOMISS (R11), X11              // c441782f1b
-	//TODO: VCOMISS X2, X11                 // c461782fda or c5782fda
-	//TODO: VCOMISS X11, X11                // c441782fdb
-	//TODO: VCVTDQ2PD (BX), X2              // c4e17ae613 or c5fae613
-	//TODO: VCVTDQ2PD (R11), X2             // c4c17ae613
-	//TODO: VCVTDQ2PD X2, X2                // c4e17ae6d2 or c5fae6d2
-	//TODO: VCVTDQ2PD X11, X2               // c4c17ae6d3
-	//TODO: VCVTDQ2PD (BX), X11             // c4617ae61b or c57ae61b
-	//TODO: VCVTDQ2PD (R11), X11            // c4417ae61b
-	//TODO: VCVTDQ2PD X2, X11               // c4617ae6da or c57ae6da
-	//TODO: VCVTDQ2PD X11, X11              // c4417ae6db
-	//TODO: VCVTDQ2PD (BX), Y2              // c4e17ee613 or c5fee613
-	//TODO: VCVTDQ2PD (R11), Y2             // c4c17ee613
-	//TODO: VCVTDQ2PD X2, Y2                // c4e17ee6d2 or c5fee6d2
-	//TODO: VCVTDQ2PD X11, Y2               // c4c17ee6d3
-	//TODO: VCVTDQ2PD (BX), Y11             // c4617ee61b or c57ee61b
-	//TODO: VCVTDQ2PD (R11), Y11            // c4417ee61b
-	//TODO: VCVTDQ2PD X2, Y11               // c4617ee6da or c57ee6da
-	//TODO: VCVTDQ2PD X11, Y11              // c4417ee6db
-	//TODO: VCVTDQ2PS (BX), X2              // c4e1785b13 or c5f85b13
-	//TODO: VCVTDQ2PS (R11), X2             // c4c1785b13
-	//TODO: VCVTDQ2PS X2, X2                // c4e1785bd2 or c5f85bd2
-	//TODO: VCVTDQ2PS X11, X2               // c4c1785bd3
-	//TODO: VCVTDQ2PS (BX), X11             // c461785b1b or c5785b1b
-	//TODO: VCVTDQ2PS (R11), X11            // c441785b1b
-	//TODO: VCVTDQ2PS X2, X11               // c461785bda or c5785bda
-	//TODO: VCVTDQ2PS X11, X11              // c441785bdb
-	//TODO: VCVTDQ2PS (BX), Y2              // c4e17c5b13 or c5fc5b13
-	//TODO: VCVTDQ2PS (R11), Y2             // c4c17c5b13
-	//TODO: VCVTDQ2PS Y2, Y2                // c4e17c5bd2 or c5fc5bd2
-	//TODO: VCVTDQ2PS Y11, Y2               // c4c17c5bd3
-	//TODO: VCVTDQ2PS (BX), Y11             // c4617c5b1b or c57c5b1b
-	//TODO: VCVTDQ2PS (R11), Y11            // c4417c5b1b
-	//TODO: VCVTDQ2PS Y2, Y11               // c4617c5bda or c57c5bda
-	//TODO: VCVTDQ2PS Y11, Y11              // c4417c5bdb
-	//TODO: VCVTPD2DQX (BX), X2             // c4e17be613 or c5fbe613
-	//TODO: VCVTPD2DQX (R11), X2            // c4c17be613
-	//TODO: VCVTPD2DQX X2, X2               // c4e17be6d2 or c5fbe6d2
-	//TODO: VCVTPD2DQX X11, X2              // c4c17be6d3
-	//TODO: VCVTPD2DQX (BX), X11            // c4617be61b or c57be61b
-	//TODO: VCVTPD2DQX (R11), X11           // c4417be61b
-	//TODO: VCVTPD2DQX X2, X11              // c4617be6da or c57be6da
-	//TODO: VCVTPD2DQX X11, X11             // c4417be6db
-	//TODO: VCVTPD2DQY (BX), X2             // c4e17fe613 or c5ffe613
-	//TODO: VCVTPD2DQY (R11), X2            // c4c17fe613
-	//TODO: VCVTPD2DQY Y2, X2               // c4e17fe6d2 or c5ffe6d2
-	//TODO: VCVTPD2DQY Y11, X2              // c4c17fe6d3
-	//TODO: VCVTPD2DQY (BX), X11            // c4617fe61b or c57fe61b
-	//TODO: VCVTPD2DQY (R11), X11           // c4417fe61b
-	//TODO: VCVTPD2DQY Y2, X11              // c4617fe6da or c57fe6da
-	//TODO: VCVTPD2DQY Y11, X11             // c4417fe6db
-	//TODO: VCVTPD2PSX (BX), X2             // c4e1795a13 or c5f95a13
-	//TODO: VCVTPD2PSX (R11), X2            // c4c1795a13
-	//TODO: VCVTPD2PSX X2, X2               // c4e1795ad2 or c5f95ad2
-	//TODO: VCVTPD2PSX X11, X2              // c4c1795ad3
-	//TODO: VCVTPD2PSX (BX), X11            // c461795a1b or c5795a1b
-	//TODO: VCVTPD2PSX (R11), X11           // c441795a1b
-	//TODO: VCVTPD2PSX X2, X11              // c461795ada or c5795ada
-	//TODO: VCVTPD2PSX X11, X11             // c441795adb
-	//TODO: VCVTPD2PSY (BX), X2             // c4e17d5a13 or c5fd5a13
-	//TODO: VCVTPD2PSY (R11), X2            // c4c17d5a13
-	//TODO: VCVTPD2PSY Y2, X2               // c4e17d5ad2 or c5fd5ad2
-	//TODO: VCVTPD2PSY Y11, X2              // c4c17d5ad3
-	//TODO: VCVTPD2PSY (BX), X11            // c4617d5a1b or c57d5a1b
-	//TODO: VCVTPD2PSY (R11), X11           // c4417d5a1b
-	//TODO: VCVTPD2PSY Y2, X11              // c4617d5ada or c57d5ada
-	//TODO: VCVTPD2PSY Y11, X11             // c4417d5adb
-	//TODO: VCVTPH2PS (BX), X2              // c4e2791313
-	//TODO: VCVTPH2PS (R11), X2             // c4c2791313
-	//TODO: VCVTPH2PS X2, X2                // c4e27913d2
-	//TODO: VCVTPH2PS X11, X2               // c4c27913d3
-	//TODO: VCVTPH2PS (BX), X11             // c46279131b
-	//TODO: VCVTPH2PS (R11), X11            // c44279131b
-	//TODO: VCVTPH2PS X2, X11               // c4627913da
-	//TODO: VCVTPH2PS X11, X11              // c4427913db
-	//TODO: VCVTPH2PS (BX), Y2              // c4e27d1313
-	//TODO: VCVTPH2PS (R11), Y2             // c4c27d1313
-	//TODO: VCVTPH2PS X2, Y2                // c4e27d13d2
-	//TODO: VCVTPH2PS X11, Y2               // c4c27d13d3
-	//TODO: VCVTPH2PS (BX), Y11             // c4627d131b
-	//TODO: VCVTPH2PS (R11), Y11            // c4427d131b
-	//TODO: VCVTPH2PS X2, Y11               // c4627d13da
-	//TODO: VCVTPH2PS X11, Y11              // c4427d13db
-	//TODO: VCVTPS2DQ (BX), X2              // c4e1795b13 or c5f95b13
-	//TODO: VCVTPS2DQ (R11), X2             // c4c1795b13
-	//TODO: VCVTPS2DQ X2, X2                // c4e1795bd2 or c5f95bd2
-	//TODO: VCVTPS2DQ X11, X2               // c4c1795bd3
-	//TODO: VCVTPS2DQ (BX), X11             // c461795b1b or c5795b1b
-	//TODO: VCVTPS2DQ (R11), X11            // c441795b1b
-	//TODO: VCVTPS2DQ X2, X11               // c461795bda or c5795bda
-	//TODO: VCVTPS2DQ X11, X11              // c441795bdb
-	//TODO: VCVTPS2DQ (BX), Y2              // c4e17d5b13 or c5fd5b13
-	//TODO: VCVTPS2DQ (R11), Y2             // c4c17d5b13
-	//TODO: VCVTPS2DQ Y2, Y2                // c4e17d5bd2 or c5fd5bd2
-	//TODO: VCVTPS2DQ Y11, Y2               // c4c17d5bd3
-	//TODO: VCVTPS2DQ (BX), Y11             // c4617d5b1b or c57d5b1b
-	//TODO: VCVTPS2DQ (R11), Y11            // c4417d5b1b
-	//TODO: VCVTPS2DQ Y2, Y11               // c4617d5bda or c57d5bda
-	//TODO: VCVTPS2DQ Y11, Y11              // c4417d5bdb
-	//TODO: VCVTPS2PD (BX), X2              // c4e1785a13 or c5f85a13
-	//TODO: VCVTPS2PD (R11), X2             // c4c1785a13
-	//TODO: VCVTPS2PD X2, X2                // c4e1785ad2 or c5f85ad2
-	//TODO: VCVTPS2PD X11, X2               // c4c1785ad3
-	//TODO: VCVTPS2PD (BX), X11             // c461785a1b or c5785a1b
-	//TODO: VCVTPS2PD (R11), X11            // c441785a1b
-	//TODO: VCVTPS2PD X2, X11               // c461785ada or c5785ada
-	//TODO: VCVTPS2PD X11, X11              // c441785adb
-	//TODO: VCVTPS2PD (BX), Y2              // c4e17c5a13 or c5fc5a13
-	//TODO: VCVTPS2PD (R11), Y2             // c4c17c5a13
-	//TODO: VCVTPS2PD X2, Y2                // c4e17c5ad2 or c5fc5ad2
-	//TODO: VCVTPS2PD X11, Y2               // c4c17c5ad3
-	//TODO: VCVTPS2PD (BX), Y11             // c4617c5a1b or c57c5a1b
-	//TODO: VCVTPS2PD (R11), Y11            // c4417c5a1b
-	//TODO: VCVTPS2PD X2, Y11               // c4617c5ada or c57c5ada
-	//TODO: VCVTPS2PD X11, Y11              // c4417c5adb
-	//TODO: VCVTPS2PH $7, Y2, (BX)          // c4e37d1d1307
-	//TODO: VCVTPS2PH $7, Y11, (BX)         // c4637d1d1b07
-	//TODO: VCVTPS2PH $7, Y2, (R11)         // c4c37d1d1307
-	//TODO: VCVTPS2PH $7, Y11, (R11)        // c4437d1d1b07
-	//TODO: VCVTPS2PH $7, Y2, X2            // c4e37d1dd207
-	//TODO: VCVTPS2PH $7, Y11, X2           // c4637d1dda07
-	//TODO: VCVTPS2PH $7, Y2, X11           // c4c37d1dd307
-	//TODO: VCVTPS2PH $7, Y11, X11          // c4437d1ddb07
-	//TODO: VCVTPS2PH $7, X2, (BX)          // c4e3791d1307
-	//TODO: VCVTPS2PH $7, X11, (BX)         // c463791d1b07
-	//TODO: VCVTPS2PH $7, X2, (R11)         // c4c3791d1307
-	//TODO: VCVTPS2PH $7, X11, (R11)        // c443791d1b07
-	//TODO: VCVTPS2PH $7, X2, X2            // c4e3791dd207
-	//TODO: VCVTPS2PH $7, X11, X2           // c463791dda07
-	//TODO: VCVTPS2PH $7, X2, X11           // c4c3791dd307
-	//TODO: VCVTPS2PH $7, X11, X11          // c443791ddb07
-	//TODO: VCVTSD2SI (BX), DX              // c4e17b2d13 or c5fb2d13
-	//TODO: VCVTSD2SI (R11), DX             // c4c17b2d13
-	//TODO: VCVTSD2SI X2, DX                // c4e17b2dd2 or c5fb2dd2
-	//TODO: VCVTSD2SI X11, DX               // c4c17b2dd3
-	//TODO: VCVTSD2SI (BX), R11             // c4617b2d1b or c57b2d1b
-	//TODO: VCVTSD2SI (R11), R11            // c4417b2d1b
-	//TODO: VCVTSD2SI X2, R11               // c4617b2dda or c57b2dda
-	//TODO: VCVTSD2SI X11, R11              // c4417b2ddb
-	//TODO: VCVTSD2SIQ (BX), DX             // c4e1fb2d13
-	//TODO: VCVTSD2SIQ (R11), DX            // c4c1fb2d13
-	//TODO: VCVTSD2SIQ X2, DX               // c4e1fb2dd2
-	//TODO: VCVTSD2SIQ X11, DX              // c4c1fb2dd3
-	//TODO: VCVTSD2SIQ (BX), R11            // c461fb2d1b
-	//TODO: VCVTSD2SIQ (R11), R11           // c441fb2d1b
-	//TODO: VCVTSD2SIQ X2, R11              // c461fb2dda
-	//TODO: VCVTSD2SIQ X11, R11             // c441fb2ddb
-	//TODO: VCVTSD2SS (BX), X9, X2          // c4e1335a13 or c5b35a13
-	//TODO: VCVTSD2SS (R11), X9, X2         // c4c1335a13
-	//TODO: VCVTSD2SS X2, X9, X2            // c4e1335ad2 or c5b35ad2
-	//TODO: VCVTSD2SS X11, X9, X2           // c4c1335ad3
-	//TODO: VCVTSD2SS (BX), X9, X11         // c461335a1b or c5335a1b
-	//TODO: VCVTSD2SS (R11), X9, X11        // c441335a1b
-	//TODO: VCVTSD2SS X2, X9, X11           // c461335ada or c5335ada
-	//TODO: VCVTSD2SS X11, X9, X11          // c441335adb
-	//TODO: VCVTSI2SDL (BX), X9, X2         // c4e1332a13 or c5b32a13
-	//TODO: VCVTSI2SDL (R11), X9, X2        // c4c1332a13
-	//TODO: VCVTSI2SDL DX, X9, X2           // c4e1332ad2 or c5b32ad2
-	//TODO: VCVTSI2SDL R11, X9, X2          // c4c1332ad3
-	//TODO: VCVTSI2SDL (BX), X9, X11        // c461332a1b or c5332a1b
-	//TODO: VCVTSI2SDL (R11), X9, X11       // c441332a1b
-	//TODO: VCVTSI2SDL DX, X9, X11          // c461332ada or c5332ada
-	//TODO: VCVTSI2SDL R11, X9, X11         // c441332adb
-	//TODO: VCVTSI2SDQ (BX), X9, X2         // c4e1b32a13
-	//TODO: VCVTSI2SDQ (R11), X9, X2        // c4c1b32a13
-	//TODO: VCVTSI2SDQ DX, X9, X2           // c4e1b32ad2
-	//TODO: VCVTSI2SDQ R11, X9, X2          // c4c1b32ad3
-	//TODO: VCVTSI2SDQ (BX), X9, X11        // c461b32a1b
-	//TODO: VCVTSI2SDQ (R11), X9, X11       // c441b32a1b
-	//TODO: VCVTSI2SDQ DX, X9, X11          // c461b32ada
-	//TODO: VCVTSI2SDQ R11, X9, X11         // c441b32adb
-	//TODO: VCVTSI2SSL (BX), X9, X2         // c4e1322a13 or c5b22a13
-	//TODO: VCVTSI2SSL (R11), X9, X2        // c4c1322a13
-	//TODO: VCVTSI2SSL DX, X9, X2           // c4e1322ad2 or c5b22ad2
-	//TODO: VCVTSI2SSL R11, X9, X2          // c4c1322ad3
-	//TODO: VCVTSI2SSL (BX), X9, X11        // c461322a1b or c5322a1b
-	//TODO: VCVTSI2SSL (R11), X9, X11       // c441322a1b
-	//TODO: VCVTSI2SSL DX, X9, X11          // c461322ada or c5322ada
-	//TODO: VCVTSI2SSL R11, X9, X11         // c441322adb
-	//TODO: VCVTSI2SSQ (BX), X9, X2         // c4e1b22a13
-	//TODO: VCVTSI2SSQ (R11), X9, X2        // c4c1b22a13
-	//TODO: VCVTSI2SSQ DX, X9, X2           // c4e1b22ad2
-	//TODO: VCVTSI2SSQ R11, X9, X2          // c4c1b22ad3
-	//TODO: VCVTSI2SSQ (BX), X9, X11        // c461b22a1b
-	//TODO: VCVTSI2SSQ (R11), X9, X11       // c441b22a1b
-	//TODO: VCVTSI2SSQ DX, X9, X11          // c461b22ada
-	//TODO: VCVTSI2SSQ R11, X9, X11         // c441b22adb
-	//TODO: VCVTSS2SD (BX), X9, X2          // c4e1325a13 or c5b25a13
-	//TODO: VCVTSS2SD (R11), X9, X2         // c4c1325a13
-	//TODO: VCVTSS2SD X2, X9, X2            // c4e1325ad2 or c5b25ad2
-	//TODO: VCVTSS2SD X11, X9, X2           // c4c1325ad3
-	//TODO: VCVTSS2SD (BX), X9, X11         // c461325a1b or c5325a1b
-	//TODO: VCVTSS2SD (R11), X9, X11        // c441325a1b
-	//TODO: VCVTSS2SD X2, X9, X11           // c461325ada or c5325ada
-	//TODO: VCVTSS2SD X11, X9, X11          // c441325adb
-	//TODO: VCVTSS2SI (BX), DX              // c4e17a2d13 or c5fa2d13
-	//TODO: VCVTSS2SI (R11), DX             // c4c17a2d13
-	//TODO: VCVTSS2SI X2, DX                // c4e17a2dd2 or c5fa2dd2
-	//TODO: VCVTSS2SI X11, DX               // c4c17a2dd3
-	//TODO: VCVTSS2SI (BX), R11             // c4617a2d1b or c57a2d1b
-	//TODO: VCVTSS2SI (R11), R11            // c4417a2d1b
-	//TODO: VCVTSS2SI X2, R11               // c4617a2dda or c57a2dda
-	//TODO: VCVTSS2SI X11, R11              // c4417a2ddb
-	//TODO: VCVTSS2SIQ (BX), DX             // c4e1fa2d13
-	//TODO: VCVTSS2SIQ (R11), DX            // c4c1fa2d13
-	//TODO: VCVTSS2SIQ X2, DX               // c4e1fa2dd2
-	//TODO: VCVTSS2SIQ X11, DX              // c4c1fa2dd3
-	//TODO: VCVTSS2SIQ (BX), R11            // c461fa2d1b
-	//TODO: VCVTSS2SIQ (R11), R11           // c441fa2d1b
-	//TODO: VCVTSS2SIQ X2, R11              // c461fa2dda
-	//TODO: VCVTSS2SIQ X11, R11             // c441fa2ddb
-	//TODO: VCVTTPD2DQX (BX), X2            // c4e179e613 or c5f9e613
-	//TODO: VCVTTPD2DQX (R11), X2           // c4c179e613
-	//TODO: VCVTTPD2DQX X2, X2              // c4e179e6d2 or c5f9e6d2
-	//TODO: VCVTTPD2DQX X11, X2             // c4c179e6d3
-	//TODO: VCVTTPD2DQX (BX), X11           // c46179e61b or c579e61b
-	//TODO: VCVTTPD2DQX (R11), X11          // c44179e61b
-	//TODO: VCVTTPD2DQX X2, X11             // c46179e6da or c579e6da
-	//TODO: VCVTTPD2DQX X11, X11            // c44179e6db
-	//TODO: VCVTTPD2DQY (BX), X2            // c4e17de613 or c5fde613
-	//TODO: VCVTTPD2DQY (R11), X2           // c4c17de613
-	//TODO: VCVTTPD2DQY Y2, X2              // c4e17de6d2 or c5fde6d2
-	//TODO: VCVTTPD2DQY Y11, X2             // c4c17de6d3
-	//TODO: VCVTTPD2DQY (BX), X11           // c4617de61b or c57de61b
-	//TODO: VCVTTPD2DQY (R11), X11          // c4417de61b
-	//TODO: VCVTTPD2DQY Y2, X11             // c4617de6da or c57de6da
-	//TODO: VCVTTPD2DQY Y11, X11            // c4417de6db
-	//TODO: VCVTTPS2DQ (BX), X2             // c4e17a5b13 or c5fa5b13
-	//TODO: VCVTTPS2DQ (R11), X2            // c4c17a5b13
-	//TODO: VCVTTPS2DQ X2, X2               // c4e17a5bd2 or c5fa5bd2
-	//TODO: VCVTTPS2DQ X11, X2              // c4c17a5bd3
-	//TODO: VCVTTPS2DQ (BX), X11            // c4617a5b1b or c57a5b1b
-	//TODO: VCVTTPS2DQ (R11), X11           // c4417a5b1b
-	//TODO: VCVTTPS2DQ X2, X11              // c4617a5bda or c57a5bda
-	//TODO: VCVTTPS2DQ X11, X11             // c4417a5bdb
-	//TODO: VCVTTPS2DQ (BX), Y2             // c4e17e5b13 or c5fe5b13
-	//TODO: VCVTTPS2DQ (R11), Y2            // c4c17e5b13
-	//TODO: VCVTTPS2DQ Y2, Y2               // c4e17e5bd2 or c5fe5bd2
-	//TODO: VCVTTPS2DQ Y11, Y2              // c4c17e5bd3
-	//TODO: VCVTTPS2DQ (BX), Y11            // c4617e5b1b or c57e5b1b
-	//TODO: VCVTTPS2DQ (R11), Y11           // c4417e5b1b
-	//TODO: VCVTTPS2DQ Y2, Y11              // c4617e5bda or c57e5bda
-	//TODO: VCVTTPS2DQ Y11, Y11             // c4417e5bdb
-	//TODO: VCVTTSD2SI (BX), DX             // c4e17b2c13 or c5fb2c13
-	//TODO: VCVTTSD2SI (R11), DX            // c4c17b2c13
-	//TODO: VCVTTSD2SI X2, DX               // c4e17b2cd2 or c5fb2cd2
-	//TODO: VCVTTSD2SI X11, DX              // c4c17b2cd3
-	//TODO: VCVTTSD2SI (BX), R11            // c4617b2c1b or c57b2c1b
-	//TODO: VCVTTSD2SI (R11), R11           // c4417b2c1b
-	//TODO: VCVTTSD2SI X2, R11              // c4617b2cda or c57b2cda
-	//TODO: VCVTTSD2SI X11, R11             // c4417b2cdb
-	//TODO: VCVTTSD2SIQ (BX), DX            // c4e1fb2c13
-	//TODO: VCVTTSD2SIQ (R11), DX           // c4c1fb2c13
-	//TODO: VCVTTSD2SIQ X2, DX              // c4e1fb2cd2
-	//TODO: VCVTTSD2SIQ X11, DX             // c4c1fb2cd3
-	//TODO: VCVTTSD2SIQ (BX), R11           // c461fb2c1b
-	//TODO: VCVTTSD2SIQ (R11), R11          // c441fb2c1b
-	//TODO: VCVTTSD2SIQ X2, R11             // c461fb2cda
-	//TODO: VCVTTSD2SIQ X11, R11            // c441fb2cdb
-	//TODO: VCVTTSS2SI (BX), DX             // c4e17a2c13 or c5fa2c13
-	//TODO: VCVTTSS2SI (R11), DX            // c4c17a2c13
-	//TODO: VCVTTSS2SI X2, DX               // c4e17a2cd2 or c5fa2cd2
-	//TODO: VCVTTSS2SI X11, DX              // c4c17a2cd3
-	//TODO: VCVTTSS2SI (BX), R11            // c4617a2c1b or c57a2c1b
-	//TODO: VCVTTSS2SI (R11), R11           // c4417a2c1b
-	//TODO: VCVTTSS2SI X2, R11              // c4617a2cda or c57a2cda
-	//TODO: VCVTTSS2SI X11, R11             // c4417a2cdb
-	//TODO: VCVTTSS2SIQ (BX), DX            // c4e1fa2c13
-	//TODO: VCVTTSS2SIQ (R11), DX           // c4c1fa2c13
-	//TODO: VCVTTSS2SIQ X2, DX              // c4e1fa2cd2
-	//TODO: VCVTTSS2SIQ X11, DX             // c4c1fa2cd3
-	//TODO: VCVTTSS2SIQ (BX), R11           // c461fa2c1b
-	//TODO: VCVTTSS2SIQ (R11), R11          // c441fa2c1b
-	//TODO: VCVTTSS2SIQ X2, R11             // c461fa2cda
-	//TODO: VCVTTSS2SIQ X11, R11            // c441fa2cdb
-	//TODO: VDIVPD (BX), X9, X2             // c4e1315e13 or c5b15e13
-	//TODO: VDIVPD (R11), X9, X2            // c4c1315e13
-	//TODO: VDIVPD X2, X9, X2               // c4e1315ed2 or c5b15ed2
-	//TODO: VDIVPD X11, X9, X2              // c4c1315ed3
-	//TODO: VDIVPD (BX), X9, X11            // c461315e1b or c5315e1b
-	//TODO: VDIVPD (R11), X9, X11           // c441315e1b
-	//TODO: VDIVPD X2, X9, X11              // c461315eda or c5315eda
-	//TODO: VDIVPD X11, X9, X11             // c441315edb
-	//TODO: VDIVPD (BX), Y15, Y2            // c4e1055e13 or c5855e13
-	//TODO: VDIVPD (R11), Y15, Y2           // c4c1055e13
-	//TODO: VDIVPD Y2, Y15, Y2              // c4e1055ed2 or c5855ed2
-	//TODO: VDIVPD Y11, Y15, Y2             // c4c1055ed3
-	//TODO: VDIVPD (BX), Y15, Y11           // c461055e1b or c5055e1b
-	//TODO: VDIVPD (R11), Y15, Y11          // c441055e1b
-	//TODO: VDIVPD Y2, Y15, Y11             // c461055eda or c5055eda
-	//TODO: VDIVPD Y11, Y15, Y11            // c441055edb
-	//TODO: VDIVPS (BX), X9, X2             // c4e1305e13 or c5b05e13
-	//TODO: VDIVPS (R11), X9, X2            // c4c1305e13
-	//TODO: VDIVPS X2, X9, X2               // c4e1305ed2 or c5b05ed2
-	//TODO: VDIVPS X11, X9, X2              // c4c1305ed3
-	//TODO: VDIVPS (BX), X9, X11            // c461305e1b or c5305e1b
-	//TODO: VDIVPS (R11), X9, X11           // c441305e1b
-	//TODO: VDIVPS X2, X9, X11              // c461305eda or c5305eda
-	//TODO: VDIVPS X11, X9, X11             // c441305edb
-	//TODO: VDIVPS (BX), Y15, Y2            // c4e1045e13 or c5845e13
-	//TODO: VDIVPS (R11), Y15, Y2           // c4c1045e13
-	//TODO: VDIVPS Y2, Y15, Y2              // c4e1045ed2 or c5845ed2
-	//TODO: VDIVPS Y11, Y15, Y2             // c4c1045ed3
-	//TODO: VDIVPS (BX), Y15, Y11           // c461045e1b or c5045e1b
-	//TODO: VDIVPS (R11), Y15, Y11          // c441045e1b
-	//TODO: VDIVPS Y2, Y15, Y11             // c461045eda or c5045eda
-	//TODO: VDIVPS Y11, Y15, Y11            // c441045edb
-	//TODO: VDIVSD (BX), X9, X2             // c4e1335e13 or c5b35e13
-	//TODO: VDIVSD (R11), X9, X2            // c4c1335e13
-	//TODO: VDIVSD X2, X9, X2               // c4e1335ed2 or c5b35ed2
-	//TODO: VDIVSD X11, X9, X2              // c4c1335ed3
-	//TODO: VDIVSD (BX), X9, X11            // c461335e1b or c5335e1b
-	//TODO: VDIVSD (R11), X9, X11           // c441335e1b
-	//TODO: VDIVSD X2, X9, X11              // c461335eda or c5335eda
-	//TODO: VDIVSD X11, X9, X11             // c441335edb
-	//TODO: VDIVSS (BX), X9, X2             // c4e1325e13 or c5b25e13
-	//TODO: VDIVSS (R11), X9, X2            // c4c1325e13
-	//TODO: VDIVSS X2, X9, X2               // c4e1325ed2 or c5b25ed2
-	//TODO: VDIVSS X11, X9, X2              // c4c1325ed3
-	//TODO: VDIVSS (BX), X9, X11            // c461325e1b or c5325e1b
-	//TODO: VDIVSS (R11), X9, X11           // c441325e1b
-	//TODO: VDIVSS X2, X9, X11              // c461325eda or c5325eda
-	//TODO: VDIVSS X11, X9, X11             // c441325edb
-	//TODO: VDPPD $7, (BX), X9, X2          // c4e331411307
-	//TODO: VDPPD $7, (R11), X9, X2         // c4c331411307
-	//TODO: VDPPD $7, X2, X9, X2            // c4e33141d207
-	//TODO: VDPPD $7, X11, X9, X2           // c4c33141d307
-	//TODO: VDPPD $7, (BX), X9, X11         // c46331411b07
-	//TODO: VDPPD $7, (R11), X9, X11        // c44331411b07
-	//TODO: VDPPD $7, X2, X9, X11           // c4633141da07
-	//TODO: VDPPD $7, X11, X9, X11          // c4433141db07
-	//TODO: VDPPS $7, (BX), X9, X2          // c4e331401307
-	//TODO: VDPPS $7, (R11), X9, X2         // c4c331401307
-	//TODO: VDPPS $7, X2, X9, X2            // c4e33140d207
-	//TODO: VDPPS $7, X11, X9, X2           // c4c33140d307
-	//TODO: VDPPS $7, (BX), X9, X11         // c46331401b07
-	//TODO: VDPPS $7, (R11), X9, X11        // c44331401b07
-	//TODO: VDPPS $7, X2, X9, X11           // c4633140da07
-	//TODO: VDPPS $7, X11, X9, X11          // c4433140db07
-	//TODO: VDPPS $7, (BX), Y15, Y2         // c4e305401307
-	//TODO: VDPPS $7, (R11), Y15, Y2        // c4c305401307
-	//TODO: VDPPS $7, Y2, Y15, Y2           // c4e30540d207
-	//TODO: VDPPS $7, Y11, Y15, Y2          // c4c30540d307
-	//TODO: VDPPS $7, (BX), Y15, Y11        // c46305401b07
-	//TODO: VDPPS $7, (R11), Y15, Y11       // c44305401b07
-	//TODO: VDPPS $7, Y2, Y15, Y11          // c4630540da07
-	//TODO: VDPPS $7, Y11, Y15, Y11         // c4430540db07
+	VCMPPD $7, (BX), X9, X2                 // c4e131c21307 or c5b1c21307
+	VCMPPD $7, (R11), X9, X2                // c4c131c21307
+	VCMPPD $7, X2, X9, X2                   // c4e131c2d207 or c5b1c2d207
+	VCMPPD $7, X11, X9, X2                  // c4c131c2d307
+	VCMPPD $7, (BX), X9, X11                // c46131c21b07 or c531c21b07
+	VCMPPD $7, (R11), X9, X11               // c44131c21b07
+	VCMPPD $7, X2, X9, X11                  // c46131c2da07 or c531c2da07
+	VCMPPD $7, X11, X9, X11                 // c44131c2db07
+	VCMPPD $7, (BX), Y15, Y2                // c4e105c21307 or c585c21307
+	VCMPPD $7, (R11), Y15, Y2               // c4c105c21307
+	VCMPPD $7, Y2, Y15, Y2                  // c4e105c2d207 or c585c2d207
+	VCMPPD $7, Y11, Y15, Y2                 // c4c105c2d307
+	VCMPPD $7, (BX), Y15, Y11               // c46105c21b07 or c505c21b07
+	VCMPPD $7, (R11), Y15, Y11              // c44105c21b07
+	VCMPPD $7, Y2, Y15, Y11                 // c46105c2da07 or c505c2da07
+	VCMPPD $7, Y11, Y15, Y11                // c44105c2db07
+	VCMPPS $7, (BX), X9, X2                 // c4e130c21307 or c5b0c21307
+	VCMPPS $7, (R11), X9, X2                // c4c130c21307
+	VCMPPS $7, X2, X9, X2                   // c4e130c2d207 or c5b0c2d207
+	VCMPPS $7, X11, X9, X2                  // c4c130c2d307
+	VCMPPS $7, (BX), X9, X11                // c46130c21b07 or c530c21b07
+	VCMPPS $7, (R11), X9, X11               // c44130c21b07
+	VCMPPS $7, X2, X9, X11                  // c46130c2da07 or c530c2da07
+	VCMPPS $7, X11, X9, X11                 // c44130c2db07
+	VCMPPS $7, (BX), Y15, Y2                // c4e104c21307 or c584c21307
+	VCMPPS $7, (R11), Y15, Y2               // c4c104c21307
+	VCMPPS $7, Y2, Y15, Y2                  // c4e104c2d207 or c584c2d207
+	VCMPPS $7, Y11, Y15, Y2                 // c4c104c2d307
+	VCMPPS $7, (BX), Y15, Y11               // c46104c21b07 or c504c21b07
+	VCMPPS $7, (R11), Y15, Y11              // c44104c21b07
+	VCMPPS $7, Y2, Y15, Y11                 // c46104c2da07 or c504c2da07
+	VCMPPS $7, Y11, Y15, Y11                // c44104c2db07
+	VCMPSD $7, (BX), X9, X2                 // c4e133c21307 or c5b3c21307
+	VCMPSD $7, (R11), X9, X2                // c4c133c21307
+	VCMPSD $7, X2, X9, X2                   // c4e133c2d207 or c5b3c2d207
+	VCMPSD $7, X11, X9, X2                  // c4c133c2d307
+	VCMPSD $7, (BX), X9, X11                // c46133c21b07 or c533c21b07
+	VCMPSD $7, (R11), X9, X11               // c44133c21b07
+	VCMPSD $7, X2, X9, X11                  // c46133c2da07 or c533c2da07
+	VCMPSD $7, X11, X9, X11                 // c44133c2db07
+	VCMPSS $7, (BX), X9, X2                 // c4e132c21307 or c5b2c21307
+	VCMPSS $7, (R11), X9, X2                // c4c132c21307
+	VCMPSS $7, X2, X9, X2                   // c4e132c2d207 or c5b2c2d207
+	VCMPSS $7, X11, X9, X2                  // c4c132c2d307
+	VCMPSS $7, (BX), X9, X11                // c46132c21b07 or c532c21b07
+	VCMPSS $7, (R11), X9, X11               // c44132c21b07
+	VCMPSS $7, X2, X9, X11                  // c46132c2da07 or c532c2da07
+	VCMPSS $7, X11, X9, X11                 // c44132c2db07
+	VCOMISD (BX), X2                        // c4e1792f13 or c5f92f13
+	VCOMISD (R11), X2                       // c4c1792f13
+	VCOMISD X2, X2                          // c4e1792fd2 or c5f92fd2
+	VCOMISD X11, X2                         // c4c1792fd3
+	VCOMISD (BX), X11                       // c461792f1b or c5792f1b
+	VCOMISD (R11), X11                      // c441792f1b
+	VCOMISD X2, X11                         // c461792fda or c5792fda
+	VCOMISD X11, X11                        // c441792fdb
+	VCOMISS (BX), X2                        // c4e1782f13 or c5f82f13
+	VCOMISS (R11), X2                       // c4c1782f13
+	VCOMISS X2, X2                          // c4e1782fd2 or c5f82fd2
+	VCOMISS X11, X2                         // c4c1782fd3
+	VCOMISS (BX), X11                       // c461782f1b or c5782f1b
+	VCOMISS (R11), X11                      // c441782f1b
+	VCOMISS X2, X11                         // c461782fda or c5782fda
+	VCOMISS X11, X11                        // c441782fdb
+	VCVTDQ2PD (BX), X2                      // c4e17ae613 or c5fae613
+	VCVTDQ2PD (R11), X2                     // c4c17ae613
+	VCVTDQ2PD X2, X2                        // c4e17ae6d2 or c5fae6d2
+	VCVTDQ2PD X11, X2                       // c4c17ae6d3
+	VCVTDQ2PD (BX), X11                     // c4617ae61b or c57ae61b
+	VCVTDQ2PD (R11), X11                    // c4417ae61b
+	VCVTDQ2PD X2, X11                       // c4617ae6da or c57ae6da
+	VCVTDQ2PD X11, X11                      // c4417ae6db
+	VCVTDQ2PD (BX), Y2                      // c4e17ee613 or c5fee613
+	VCVTDQ2PD (R11), Y2                     // c4c17ee613
+	VCVTDQ2PD X2, Y2                        // c4e17ee6d2 or c5fee6d2
+	VCVTDQ2PD X11, Y2                       // c4c17ee6d3
+	VCVTDQ2PD (BX), Y11                     // c4617ee61b or c57ee61b
+	VCVTDQ2PD (R11), Y11                    // c4417ee61b
+	VCVTDQ2PD X2, Y11                       // c4617ee6da or c57ee6da
+	VCVTDQ2PD X11, Y11                      // c4417ee6db
+	VCVTDQ2PS (BX), X2                      // c4e1785b13 or c5f85b13
+	VCVTDQ2PS (R11), X2                     // c4c1785b13
+	VCVTDQ2PS X2, X2                        // c4e1785bd2 or c5f85bd2
+	VCVTDQ2PS X11, X2                       // c4c1785bd3
+	VCVTDQ2PS (BX), X11                     // c461785b1b or c5785b1b
+	VCVTDQ2PS (R11), X11                    // c441785b1b
+	VCVTDQ2PS X2, X11                       // c461785bda or c5785bda
+	VCVTDQ2PS X11, X11                      // c441785bdb
+	VCVTDQ2PS (BX), Y2                      // c4e17c5b13 or c5fc5b13
+	VCVTDQ2PS (R11), Y2                     // c4c17c5b13
+	VCVTDQ2PS Y2, Y2                        // c4e17c5bd2 or c5fc5bd2
+	VCVTDQ2PS Y11, Y2                       // c4c17c5bd3
+	VCVTDQ2PS (BX), Y11                     // c4617c5b1b or c57c5b1b
+	VCVTDQ2PS (R11), Y11                    // c4417c5b1b
+	VCVTDQ2PS Y2, Y11                       // c4617c5bda or c57c5bda
+	VCVTDQ2PS Y11, Y11                      // c4417c5bdb
+	VCVTPD2DQX (BX), X2                     // c4e17be613 or c5fbe613
+	VCVTPD2DQX (R11), X2                    // c4c17be613
+	VCVTPD2DQX X2, X2                       // c4e17be6d2 or c5fbe6d2
+	VCVTPD2DQX X11, X2                      // c4c17be6d3
+	VCVTPD2DQX (BX), X11                    // c4617be61b or c57be61b
+	VCVTPD2DQX (R11), X11                   // c4417be61b
+	VCVTPD2DQX X2, X11                      // c4617be6da or c57be6da
+	VCVTPD2DQX X11, X11                     // c4417be6db
+	VCVTPD2DQY (BX), X2                     // c4e17fe613 or c5ffe613
+	VCVTPD2DQY (R11), X2                    // c4c17fe613
+	VCVTPD2DQY Y2, X2                       // c4e17fe6d2 or c5ffe6d2
+	VCVTPD2DQY Y11, X2                      // c4c17fe6d3
+	VCVTPD2DQY (BX), X11                    // c4617fe61b or c57fe61b
+	VCVTPD2DQY (R11), X11                   // c4417fe61b
+	VCVTPD2DQY Y2, X11                      // c4617fe6da or c57fe6da
+	VCVTPD2DQY Y11, X11                     // c4417fe6db
+	VCVTPD2PSX (BX), X2                     // c4e1795a13 or c5f95a13
+	VCVTPD2PSX (R11), X2                    // c4c1795a13
+	VCVTPD2PSX X2, X2                       // c4e1795ad2 or c5f95ad2
+	VCVTPD2PSX X11, X2                      // c4c1795ad3
+	VCVTPD2PSX (BX), X11                    // c461795a1b or c5795a1b
+	VCVTPD2PSX (R11), X11                   // c441795a1b
+	VCVTPD2PSX X2, X11                      // c461795ada or c5795ada
+	VCVTPD2PSX X11, X11                     // c441795adb
+	VCVTPD2PSY (BX), X2                     // c4e17d5a13 or c5fd5a13
+	VCVTPD2PSY (R11), X2                    // c4c17d5a13
+	VCVTPD2PSY Y2, X2                       // c4e17d5ad2 or c5fd5ad2
+	VCVTPD2PSY Y11, X2                      // c4c17d5ad3
+	VCVTPD2PSY (BX), X11                    // c4617d5a1b or c57d5a1b
+	VCVTPD2PSY (R11), X11                   // c4417d5a1b
+	VCVTPD2PSY Y2, X11                      // c4617d5ada or c57d5ada
+	VCVTPD2PSY Y11, X11                     // c4417d5adb
+	VCVTPH2PS (BX), X2                      // c4e2791313
+	VCVTPH2PS (R11), X2                     // c4c2791313
+	VCVTPH2PS X2, X2                        // c4e27913d2
+	VCVTPH2PS X11, X2                       // c4c27913d3
+	VCVTPH2PS (BX), X11                     // c46279131b
+	VCVTPH2PS (R11), X11                    // c44279131b
+	VCVTPH2PS X2, X11                       // c4627913da
+	VCVTPH2PS X11, X11                      // c4427913db
+	VCVTPH2PS (BX), Y2                      // c4e27d1313
+	VCVTPH2PS (R11), Y2                     // c4c27d1313
+	VCVTPH2PS X2, Y2                        // c4e27d13d2
+	VCVTPH2PS X11, Y2                       // c4c27d13d3
+	VCVTPH2PS (BX), Y11                     // c4627d131b
+	VCVTPH2PS (R11), Y11                    // c4427d131b
+	VCVTPH2PS X2, Y11                       // c4627d13da
+	VCVTPH2PS X11, Y11                      // c4427d13db
+	VCVTPS2DQ (BX), X2                      // c4e1795b13 or c5f95b13
+	VCVTPS2DQ (R11), X2                     // c4c1795b13
+	VCVTPS2DQ X2, X2                        // c4e1795bd2 or c5f95bd2
+	VCVTPS2DQ X11, X2                       // c4c1795bd3
+	VCVTPS2DQ (BX), X11                     // c461795b1b or c5795b1b
+	VCVTPS2DQ (R11), X11                    // c441795b1b
+	VCVTPS2DQ X2, X11                       // c461795bda or c5795bda
+	VCVTPS2DQ X11, X11                      // c441795bdb
+	VCVTPS2DQ (BX), Y2                      // c4e17d5b13 or c5fd5b13
+	VCVTPS2DQ (R11), Y2                     // c4c17d5b13
+	VCVTPS2DQ Y2, Y2                        // c4e17d5bd2 or c5fd5bd2
+	VCVTPS2DQ Y11, Y2                       // c4c17d5bd3
+	VCVTPS2DQ (BX), Y11                     // c4617d5b1b or c57d5b1b
+	VCVTPS2DQ (R11), Y11                    // c4417d5b1b
+	VCVTPS2DQ Y2, Y11                       // c4617d5bda or c57d5bda
+	VCVTPS2DQ Y11, Y11                      // c4417d5bdb
+	VCVTPS2PD (BX), X2                      // c4e1785a13 or c5f85a13
+	VCVTPS2PD (R11), X2                     // c4c1785a13
+	VCVTPS2PD X2, X2                        // c4e1785ad2 or c5f85ad2
+	VCVTPS2PD X11, X2                       // c4c1785ad3
+	VCVTPS2PD (BX), X11                     // c461785a1b or c5785a1b
+	VCVTPS2PD (R11), X11                    // c441785a1b
+	VCVTPS2PD X2, X11                       // c461785ada or c5785ada
+	VCVTPS2PD X11, X11                      // c441785adb
+	VCVTPS2PD (BX), Y2                      // c4e17c5a13 or c5fc5a13
+	VCVTPS2PD (R11), Y2                     // c4c17c5a13
+	VCVTPS2PD X2, Y2                        // c4e17c5ad2 or c5fc5ad2
+	VCVTPS2PD X11, Y2                       // c4c17c5ad3
+	VCVTPS2PD (BX), Y11                     // c4617c5a1b or c57c5a1b
+	VCVTPS2PD (R11), Y11                    // c4417c5a1b
+	VCVTPS2PD X2, Y11                       // c4617c5ada or c57c5ada
+	VCVTPS2PD X11, Y11                      // c4417c5adb
+	VCVTPS2PH $7, Y2, (BX)                  // c4e37d1d1307
+	VCVTPS2PH $7, Y11, (BX)                 // c4637d1d1b07
+	VCVTPS2PH $7, Y2, (R11)                 // c4c37d1d1307
+	VCVTPS2PH $7, Y11, (R11)                // c4437d1d1b07
+	VCVTPS2PH $7, Y2, X2                    // c4e37d1dd207
+	VCVTPS2PH $7, Y11, X2                   // c4637d1dda07
+	VCVTPS2PH $7, Y2, X11                   // c4c37d1dd307
+	VCVTPS2PH $7, Y11, X11                  // c4437d1ddb07
+	VCVTPS2PH $7, X2, (BX)                  // c4e3791d1307
+	VCVTPS2PH $7, X11, (BX)                 // c463791d1b07
+	VCVTPS2PH $7, X2, (R11)                 // c4c3791d1307
+	VCVTPS2PH $7, X11, (R11)                // c443791d1b07
+	VCVTPS2PH $7, X2, X2                    // c4e3791dd207
+	VCVTPS2PH $7, X11, X2                   // c463791dda07
+	VCVTPS2PH $7, X2, X11                   // c4c3791dd307
+	VCVTPS2PH $7, X11, X11                  // c443791ddb07
+	VCVTSD2SI (BX), DX                      // c4e17b2d13 or c5fb2d13
+	VCVTSD2SI (R11), DX                     // c4c17b2d13
+	VCVTSD2SI X2, DX                        // c4e17b2dd2 or c5fb2dd2
+	VCVTSD2SI X11, DX                       // c4c17b2dd3
+	VCVTSD2SI (BX), R11                     // c4617b2d1b or c57b2d1b
+	VCVTSD2SI (R11), R11                    // c4417b2d1b
+	VCVTSD2SI X2, R11                       // c4617b2dda or c57b2dda
+	VCVTSD2SI X11, R11                      // c4417b2ddb
+	VCVTSD2SIQ (BX), DX                     // c4e1fb2d13
+	VCVTSD2SIQ (R11), DX                    // c4c1fb2d13
+	VCVTSD2SIQ X2, DX                       // c4e1fb2dd2
+	VCVTSD2SIQ X11, DX                      // c4c1fb2dd3
+	VCVTSD2SIQ (BX), R11                    // c461fb2d1b
+	VCVTSD2SIQ (R11), R11                   // c441fb2d1b
+	VCVTSD2SIQ X2, R11                      // c461fb2dda
+	VCVTSD2SIQ X11, R11                     // c441fb2ddb
+	VCVTSD2SS (BX), X9, X2                  // c4e1335a13 or c5b35a13
+	VCVTSD2SS (R11), X9, X2                 // c4c1335a13
+	VCVTSD2SS X2, X9, X2                    // c4e1335ad2 or c5b35ad2
+	VCVTSD2SS X11, X9, X2                   // c4c1335ad3
+	VCVTSD2SS (BX), X9, X11                 // c461335a1b or c5335a1b
+	VCVTSD2SS (R11), X9, X11                // c441335a1b
+	VCVTSD2SS X2, X9, X11                   // c461335ada or c5335ada
+	VCVTSD2SS X11, X9, X11                  // c441335adb
+	VCVTSI2SDL (BX), X9, X2                 // c4e1332a13 or c5b32a13
+	VCVTSI2SDL (R11), X9, X2                // c4c1332a13
+	VCVTSI2SDL DX, X9, X2                   // c4e1332ad2 or c5b32ad2
+	VCVTSI2SDL R11, X9, X2                  // c4c1332ad3
+	VCVTSI2SDL (BX), X9, X11                // c461332a1b or c5332a1b
+	VCVTSI2SDL (R11), X9, X11               // c441332a1b
+	VCVTSI2SDL DX, X9, X11                  // c461332ada or c5332ada
+	VCVTSI2SDL R11, X9, X11                 // c441332adb
+	VCVTSI2SDQ (BX), X9, X2                 // c4e1b32a13
+	VCVTSI2SDQ (R11), X9, X2                // c4c1b32a13
+	VCVTSI2SDQ DX, X9, X2                   // c4e1b32ad2
+	VCVTSI2SDQ R11, X9, X2                  // c4c1b32ad3
+	VCVTSI2SDQ (BX), X9, X11                // c461b32a1b
+	VCVTSI2SDQ (R11), X9, X11               // c441b32a1b
+	VCVTSI2SDQ DX, X9, X11                  // c461b32ada
+	VCVTSI2SDQ R11, X9, X11                 // c441b32adb
+	VCVTSI2SSL (BX), X9, X2                 // c4e1322a13 or c5b22a13
+	VCVTSI2SSL (R11), X9, X2                // c4c1322a13
+	VCVTSI2SSL DX, X9, X2                   // c4e1322ad2 or c5b22ad2
+	VCVTSI2SSL R11, X9, X2                  // c4c1322ad3
+	VCVTSI2SSL (BX), X9, X11                // c461322a1b or c5322a1b
+	VCVTSI2SSL (R11), X9, X11               // c441322a1b
+	VCVTSI2SSL DX, X9, X11                  // c461322ada or c5322ada
+	VCVTSI2SSL R11, X9, X11                 // c441322adb
+	VCVTSI2SSQ (BX), X9, X2                 // c4e1b22a13
+	VCVTSI2SSQ (R11), X9, X2                // c4c1b22a13
+	VCVTSI2SSQ DX, X9, X2                   // c4e1b22ad2
+	VCVTSI2SSQ R11, X9, X2                  // c4c1b22ad3
+	VCVTSI2SSQ (BX), X9, X11                // c461b22a1b
+	VCVTSI2SSQ (R11), X9, X11               // c441b22a1b
+	VCVTSI2SSQ DX, X9, X11                  // c461b22ada
+	VCVTSI2SSQ R11, X9, X11                 // c441b22adb
+	VCVTSS2SD (BX), X9, X2                  // c4e1325a13 or c5b25a13
+	VCVTSS2SD (R11), X9, X2                 // c4c1325a13
+	VCVTSS2SD X2, X9, X2                    // c4e1325ad2 or c5b25ad2
+	VCVTSS2SD X11, X9, X2                   // c4c1325ad3
+	VCVTSS2SD (BX), X9, X11                 // c461325a1b or c5325a1b
+	VCVTSS2SD (R11), X9, X11                // c441325a1b
+	VCVTSS2SD X2, X9, X11                   // c461325ada or c5325ada
+	VCVTSS2SD X11, X9, X11                  // c441325adb
+	VCVTSS2SI (BX), DX                      // c4e17a2d13 or c5fa2d13
+	VCVTSS2SI (R11), DX                     // c4c17a2d13
+	VCVTSS2SI X2, DX                        // c4e17a2dd2 or c5fa2dd2
+	VCVTSS2SI X11, DX                       // c4c17a2dd3
+	VCVTSS2SI (BX), R11                     // c4617a2d1b or c57a2d1b
+	VCVTSS2SI (R11), R11                    // c4417a2d1b
+	VCVTSS2SI X2, R11                       // c4617a2dda or c57a2dda
+	VCVTSS2SI X11, R11                      // c4417a2ddb
+	VCVTSS2SIQ (BX), DX                     // c4e1fa2d13
+	VCVTSS2SIQ (R11), DX                    // c4c1fa2d13
+	VCVTSS2SIQ X2, DX                       // c4e1fa2dd2
+	VCVTSS2SIQ X11, DX                      // c4c1fa2dd3
+	VCVTSS2SIQ (BX), R11                    // c461fa2d1b
+	VCVTSS2SIQ (R11), R11                   // c441fa2d1b
+	VCVTSS2SIQ X2, R11                      // c461fa2dda
+	VCVTSS2SIQ X11, R11                     // c441fa2ddb
+	VCVTTPD2DQX (BX), X2                    // c4e179e613 or c5f9e613
+	VCVTTPD2DQX (R11), X2                   // c4c179e613
+	VCVTTPD2DQX X2, X2                      // c4e179e6d2 or c5f9e6d2
+	VCVTTPD2DQX X11, X2                     // c4c179e6d3
+	VCVTTPD2DQX (BX), X11                   // c46179e61b or c579e61b
+	VCVTTPD2DQX (R11), X11                  // c44179e61b
+	VCVTTPD2DQX X2, X11                     // c46179e6da or c579e6da
+	VCVTTPD2DQX X11, X11                    // c44179e6db
+	VCVTTPD2DQY (BX), X2                    // c4e17de613 or c5fde613
+	VCVTTPD2DQY (R11), X2                   // c4c17de613
+	VCVTTPD2DQY Y2, X2                      // c4e17de6d2 or c5fde6d2
+	VCVTTPD2DQY Y11, X2                     // c4c17de6d3
+	VCVTTPD2DQY (BX), X11                   // c4617de61b or c57de61b
+	VCVTTPD2DQY (R11), X11                  // c4417de61b
+	VCVTTPD2DQY Y2, X11                     // c4617de6da or c57de6da
+	VCVTTPD2DQY Y11, X11                    // c4417de6db
+	VCVTTPS2DQ (BX), X2                     // c4e17a5b13 or c5fa5b13
+	VCVTTPS2DQ (R11), X2                    // c4c17a5b13
+	VCVTTPS2DQ X2, X2                       // c4e17a5bd2 or c5fa5bd2
+	VCVTTPS2DQ X11, X2                      // c4c17a5bd3
+	VCVTTPS2DQ (BX), X11                    // c4617a5b1b or c57a5b1b
+	VCVTTPS2DQ (R11), X11                   // c4417a5b1b
+	VCVTTPS2DQ X2, X11                      // c4617a5bda or c57a5bda
+	VCVTTPS2DQ X11, X11                     // c4417a5bdb
+	VCVTTPS2DQ (BX), Y2                     // c4e17e5b13 or c5fe5b13
+	VCVTTPS2DQ (R11), Y2                    // c4c17e5b13
+	VCVTTPS2DQ Y2, Y2                       // c4e17e5bd2 or c5fe5bd2
+	VCVTTPS2DQ Y11, Y2                      // c4c17e5bd3
+	VCVTTPS2DQ (BX), Y11                    // c4617e5b1b or c57e5b1b
+	VCVTTPS2DQ (R11), Y11                   // c4417e5b1b
+	VCVTTPS2DQ Y2, Y11                      // c4617e5bda or c57e5bda
+	VCVTTPS2DQ Y11, Y11                     // c4417e5bdb
+	VCVTTSD2SI (BX), DX                     // c4e17b2c13 or c5fb2c13
+	VCVTTSD2SI (R11), DX                    // c4c17b2c13
+	VCVTTSD2SI X2, DX                       // c4e17b2cd2 or c5fb2cd2
+	VCVTTSD2SI X11, DX                      // c4c17b2cd3
+	VCVTTSD2SI (BX), R11                    // c4617b2c1b or c57b2c1b
+	VCVTTSD2SI (R11), R11                   // c4417b2c1b
+	VCVTTSD2SI X2, R11                      // c4617b2cda or c57b2cda
+	VCVTTSD2SI X11, R11                     // c4417b2cdb
+	VCVTTSD2SIQ (BX), DX                    // c4e1fb2c13
+	VCVTTSD2SIQ (R11), DX                   // c4c1fb2c13
+	VCVTTSD2SIQ X2, DX                      // c4e1fb2cd2
+	VCVTTSD2SIQ X11, DX                     // c4c1fb2cd3
+	VCVTTSD2SIQ (BX), R11                   // c461fb2c1b
+	VCVTTSD2SIQ (R11), R11                  // c441fb2c1b
+	VCVTTSD2SIQ X2, R11                     // c461fb2cda
+	VCVTTSD2SIQ X11, R11                    // c441fb2cdb
+	VCVTTSS2SI (BX), DX                     // c4e17a2c13 or c5fa2c13
+	VCVTTSS2SI (R11), DX                    // c4c17a2c13
+	VCVTTSS2SI X2, DX                       // c4e17a2cd2 or c5fa2cd2
+	VCVTTSS2SI X11, DX                      // c4c17a2cd3
+	VCVTTSS2SI (BX), R11                    // c4617a2c1b or c57a2c1b
+	VCVTTSS2SI (R11), R11                   // c4417a2c1b
+	VCVTTSS2SI X2, R11                      // c4617a2cda or c57a2cda
+	VCVTTSS2SI X11, R11                     // c4417a2cdb
+	VCVTTSS2SIQ (BX), DX                    // c4e1fa2c13
+	VCVTTSS2SIQ (R11), DX                   // c4c1fa2c13
+	VCVTTSS2SIQ X2, DX                      // c4e1fa2cd2
+	VCVTTSS2SIQ X11, DX                     // c4c1fa2cd3
+	VCVTTSS2SIQ (BX), R11                   // c461fa2c1b
+	VCVTTSS2SIQ (R11), R11                  // c441fa2c1b
+	VCVTTSS2SIQ X2, R11                     // c461fa2cda
+	VCVTTSS2SIQ X11, R11                    // c441fa2cdb
+	VDIVPD (BX), X9, X2                     // c4e1315e13 or c5b15e13
+	VDIVPD (R11), X9, X2                    // c4c1315e13
+	VDIVPD X2, X9, X2                       // c4e1315ed2 or c5b15ed2
+	VDIVPD X11, X9, X2                      // c4c1315ed3
+	VDIVPD (BX), X9, X11                    // c461315e1b or c5315e1b
+	VDIVPD (R11), X9, X11                   // c441315e1b
+	VDIVPD X2, X9, X11                      // c461315eda or c5315eda
+	VDIVPD X11, X9, X11                     // c441315edb
+	VDIVPD (BX), Y15, Y2                    // c4e1055e13 or c5855e13
+	VDIVPD (R11), Y15, Y2                   // c4c1055e13
+	VDIVPD Y2, Y15, Y2                      // c4e1055ed2 or c5855ed2
+	VDIVPD Y11, Y15, Y2                     // c4c1055ed3
+	VDIVPD (BX), Y15, Y11                   // c461055e1b or c5055e1b
+	VDIVPD (R11), Y15, Y11                  // c441055e1b
+	VDIVPD Y2, Y15, Y11                     // c461055eda or c5055eda
+	VDIVPD Y11, Y15, Y11                    // c441055edb
+	VDIVPS (BX), X9, X2                     // c4e1305e13 or c5b05e13
+	VDIVPS (R11), X9, X2                    // c4c1305e13
+	VDIVPS X2, X9, X2                       // c4e1305ed2 or c5b05ed2
+	VDIVPS X11, X9, X2                      // c4c1305ed3
+	VDIVPS (BX), X9, X11                    // c461305e1b or c5305e1b
+	VDIVPS (R11), X9, X11                   // c441305e1b
+	VDIVPS X2, X9, X11                      // c461305eda or c5305eda
+	VDIVPS X11, X9, X11                     // c441305edb
+	VDIVPS (BX), Y15, Y2                    // c4e1045e13 or c5845e13
+	VDIVPS (R11), Y15, Y2                   // c4c1045e13
+	VDIVPS Y2, Y15, Y2                      // c4e1045ed2 or c5845ed2
+	VDIVPS Y11, Y15, Y2                     // c4c1045ed3
+	VDIVPS (BX), Y15, Y11                   // c461045e1b or c5045e1b
+	VDIVPS (R11), Y15, Y11                  // c441045e1b
+	VDIVPS Y2, Y15, Y11                     // c461045eda or c5045eda
+	VDIVPS Y11, Y15, Y11                    // c441045edb
+	VDIVSD (BX), X9, X2                     // c4e1335e13 or c5b35e13
+	VDIVSD (R11), X9, X2                    // c4c1335e13
+	VDIVSD X2, X9, X2                       // c4e1335ed2 or c5b35ed2
+	VDIVSD X11, X9, X2                      // c4c1335ed3
+	VDIVSD (BX), X9, X11                    // c461335e1b or c5335e1b
+	VDIVSD (R11), X9, X11                   // c441335e1b
+	VDIVSD X2, X9, X11                      // c461335eda or c5335eda
+	VDIVSD X11, X9, X11                     // c441335edb
+	VDIVSS (BX), X9, X2                     // c4e1325e13 or c5b25e13
+	VDIVSS (R11), X9, X2                    // c4c1325e13
+	VDIVSS X2, X9, X2                       // c4e1325ed2 or c5b25ed2
+	VDIVSS X11, X9, X2                      // c4c1325ed3
+	VDIVSS (BX), X9, X11                    // c461325e1b or c5325e1b
+	VDIVSS (R11), X9, X11                   // c441325e1b
+	VDIVSS X2, X9, X11                      // c461325eda or c5325eda
+	VDIVSS X11, X9, X11                     // c441325edb
+	VDPPD $7, (BX), X9, X2                  // c4e331411307
+	VDPPD $7, (R11), X9, X2                 // c4c331411307
+	VDPPD $7, X2, X9, X2                    // c4e33141d207
+	VDPPD $7, X11, X9, X2                   // c4c33141d307
+	VDPPD $7, (BX), X9, X11                 // c46331411b07
+	VDPPD $7, (R11), X9, X11                // c44331411b07
+	VDPPD $7, X2, X9, X11                   // c4633141da07
+	VDPPD $7, X11, X9, X11                  // c4433141db07
+	VDPPS $7, (BX), X9, X2                  // c4e331401307
+	VDPPS $7, (R11), X9, X2                 // c4c331401307
+	VDPPS $7, X2, X9, X2                    // c4e33140d207
+	VDPPS $7, X11, X9, X2                   // c4c33140d307
+	VDPPS $7, (BX), X9, X11                 // c46331401b07
+	VDPPS $7, (R11), X9, X11                // c44331401b07
+	VDPPS $7, X2, X9, X11                   // c4633140da07
+	VDPPS $7, X11, X9, X11                  // c4433140db07
+	VDPPS $7, (BX), Y15, Y2                 // c4e305401307
+	VDPPS $7, (R11), Y15, Y2                // c4c305401307
+	VDPPS $7, Y2, Y15, Y2                   // c4e30540d207
+	VDPPS $7, Y11, Y15, Y2                  // c4c30540d307
+	VDPPS $7, (BX), Y15, Y11                // c46305401b07
+	VDPPS $7, (R11), Y15, Y11               // c44305401b07
+	VDPPS $7, Y2, Y15, Y11                  // c4630540da07
+	VDPPS $7, Y11, Y15, Y11                 // c4430540db07
 	VERR (BX)                               // 0f0023
 	VERR (R11)                              // 410f0023
 	VERR DX                                 // 0f00e2
@@ -6558,870 +6558,870 @@
 	VERW (R11)                              // 410f002b
 	VERW DX                                 // 0f00ea
 	VERW R11                                // 410f00eb
-	//TODO: VEXTRACTF128 $7, Y2, (BX)       // c4e37d191307
-	//TODO: VEXTRACTF128 $7, Y11, (BX)      // c4637d191b07
-	//TODO: VEXTRACTF128 $7, Y2, (R11)      // c4c37d191307
-	//TODO: VEXTRACTF128 $7, Y11, (R11)     // c4437d191b07
-	//TODO: VEXTRACTF128 $7, Y2, X2         // c4e37d19d207
-	//TODO: VEXTRACTF128 $7, Y11, X2        // c4637d19da07
-	//TODO: VEXTRACTF128 $7, Y2, X11        // c4c37d19d307
-	//TODO: VEXTRACTF128 $7, Y11, X11       // c4437d19db07
-	//TODO: VEXTRACTI128 $7, Y2, (BX)       // c4e37d391307
-	//TODO: VEXTRACTI128 $7, Y11, (BX)      // c4637d391b07
-	//TODO: VEXTRACTI128 $7, Y2, (R11)      // c4c37d391307
-	//TODO: VEXTRACTI128 $7, Y11, (R11)     // c4437d391b07
-	//TODO: VEXTRACTI128 $7, Y2, X2         // c4e37d39d207
-	//TODO: VEXTRACTI128 $7, Y11, X2        // c4637d39da07
-	//TODO: VEXTRACTI128 $7, Y2, X11        // c4c37d39d307
-	//TODO: VEXTRACTI128 $7, Y11, X11       // c4437d39db07
-	//TODO: VEXTRACTPS $7, X2, (BX)         // c4e379171307
-	//TODO: VEXTRACTPS $7, X11, (BX)        // c46379171b07
-	//TODO: VEXTRACTPS $7, X2, (R11)        // c4c379171307
-	//TODO: VEXTRACTPS $7, X11, (R11)       // c44379171b07
-	//TODO: VEXTRACTPS $7, X2, DX           // c4e37917d207
-	//TODO: VEXTRACTPS $7, X11, DX          // c4637917da07
-	//TODO: VEXTRACTPS $7, X2, R11          // c4c37917d307
-	//TODO: VEXTRACTPS $7, X11, R11         // c4437917db07
-	//TODO: VFMADD132PD (BX), X9, X2        // c4e2b19813
-	//TODO: VFMADD132PD (R11), X9, X2       // c4c2b19813
-	//TODO: VFMADD132PD X2, X9, X2          // c4e2b198d2
-	//TODO: VFMADD132PD X11, X9, X2         // c4c2b198d3
-	//TODO: VFMADD132PD (BX), X9, X11       // c462b1981b
-	//TODO: VFMADD132PD (R11), X9, X11      // c442b1981b
-	//TODO: VFMADD132PD X2, X9, X11         // c462b198da
-	//TODO: VFMADD132PD X11, X9, X11        // c442b198db
-	//TODO: VFMADD132PD (BX), Y15, Y2       // c4e2859813
-	//TODO: VFMADD132PD (R11), Y15, Y2      // c4c2859813
-	//TODO: VFMADD132PD Y2, Y15, Y2         // c4e28598d2
-	//TODO: VFMADD132PD Y11, Y15, Y2        // c4c28598d3
-	//TODO: VFMADD132PD (BX), Y15, Y11      // c46285981b
-	//TODO: VFMADD132PD (R11), Y15, Y11     // c44285981b
-	//TODO: VFMADD132PD Y2, Y15, Y11        // c4628598da
-	//TODO: VFMADD132PD Y11, Y15, Y11       // c4428598db
-	//TODO: VFMADD132PS (BX), X9, X2        // c4e2319813
-	//TODO: VFMADD132PS (R11), X9, X2       // c4c2319813
-	//TODO: VFMADD132PS X2, X9, X2          // c4e23198d2
-	//TODO: VFMADD132PS X11, X9, X2         // c4c23198d3
-	//TODO: VFMADD132PS (BX), X9, X11       // c46231981b
-	//TODO: VFMADD132PS (R11), X9, X11      // c44231981b
-	//TODO: VFMADD132PS X2, X9, X11         // c4623198da
-	//TODO: VFMADD132PS X11, X9, X11        // c4423198db
-	//TODO: VFMADD132PS (BX), Y15, Y2       // c4e2059813
-	//TODO: VFMADD132PS (R11), Y15, Y2      // c4c2059813
-	//TODO: VFMADD132PS Y2, Y15, Y2         // c4e20598d2
-	//TODO: VFMADD132PS Y11, Y15, Y2        // c4c20598d3
-	//TODO: VFMADD132PS (BX), Y15, Y11      // c46205981b
-	//TODO: VFMADD132PS (R11), Y15, Y11     // c44205981b
-	//TODO: VFMADD132PS Y2, Y15, Y11        // c4620598da
-	//TODO: VFMADD132PS Y11, Y15, Y11       // c4420598db
-	//TODO: VFMADD132SD (BX), X9, X2        // c4e2b19913
-	//TODO: VFMADD132SD (R11), X9, X2       // c4c2b19913
-	//TODO: VFMADD132SD X2, X9, X2          // c4e2b199d2
-	//TODO: VFMADD132SD X11, X9, X2         // c4c2b199d3
-	//TODO: VFMADD132SD (BX), X9, X11       // c462b1991b
-	//TODO: VFMADD132SD (R11), X9, X11      // c442b1991b
-	//TODO: VFMADD132SD X2, X9, X11         // c462b199da
-	//TODO: VFMADD132SD X11, X9, X11        // c442b199db
-	//TODO: VFMADD132SS (BX), X9, X2        // c4e2319913
-	//TODO: VFMADD132SS (R11), X9, X2       // c4c2319913
-	//TODO: VFMADD132SS X2, X9, X2          // c4e23199d2
-	//TODO: VFMADD132SS X11, X9, X2         // c4c23199d3
-	//TODO: VFMADD132SS (BX), X9, X11       // c46231991b
-	//TODO: VFMADD132SS (R11), X9, X11      // c44231991b
-	//TODO: VFMADD132SS X2, X9, X11         // c4623199da
-	//TODO: VFMADD132SS X11, X9, X11        // c4423199db
-	//TODO: VFMADD213PD (BX), X9, X2        // c4e2b1a813
-	//TODO: VFMADD213PD (R11), X9, X2       // c4c2b1a813
-	//TODO: VFMADD213PD X2, X9, X2          // c4e2b1a8d2
-	//TODO: VFMADD213PD X11, X9, X2         // c4c2b1a8d3
-	//TODO: VFMADD213PD (BX), X9, X11       // c462b1a81b
-	//TODO: VFMADD213PD (R11), X9, X11      // c442b1a81b
-	//TODO: VFMADD213PD X2, X9, X11         // c462b1a8da
-	//TODO: VFMADD213PD X11, X9, X11        // c442b1a8db
-	//TODO: VFMADD213PD (BX), Y15, Y2       // c4e285a813
-	//TODO: VFMADD213PD (R11), Y15, Y2      // c4c285a813
-	//TODO: VFMADD213PD Y2, Y15, Y2         // c4e285a8d2
-	//TODO: VFMADD213PD Y11, Y15, Y2        // c4c285a8d3
-	//TODO: VFMADD213PD (BX), Y15, Y11      // c46285a81b
-	//TODO: VFMADD213PD (R11), Y15, Y11     // c44285a81b
-	//TODO: VFMADD213PD Y2, Y15, Y11        // c46285a8da
-	//TODO: VFMADD213PD Y11, Y15, Y11       // c44285a8db
-	//TODO: VFMADD213PS (BX), X9, X2        // c4e231a813
-	//TODO: VFMADD213PS (R11), X9, X2       // c4c231a813
-	//TODO: VFMADD213PS X2, X9, X2          // c4e231a8d2
-	//TODO: VFMADD213PS X11, X9, X2         // c4c231a8d3
-	//TODO: VFMADD213PS (BX), X9, X11       // c46231a81b
-	//TODO: VFMADD213PS (R11), X9, X11      // c44231a81b
-	//TODO: VFMADD213PS X2, X9, X11         // c46231a8da
-	//TODO: VFMADD213PS X11, X9, X11        // c44231a8db
-	//TODO: VFMADD213PS (BX), Y15, Y2       // c4e205a813
-	//TODO: VFMADD213PS (R11), Y15, Y2      // c4c205a813
-	//TODO: VFMADD213PS Y2, Y15, Y2         // c4e205a8d2
-	//TODO: VFMADD213PS Y11, Y15, Y2        // c4c205a8d3
-	//TODO: VFMADD213PS (BX), Y15, Y11      // c46205a81b
-	//TODO: VFMADD213PS (R11), Y15, Y11     // c44205a81b
-	//TODO: VFMADD213PS Y2, Y15, Y11        // c46205a8da
-	//TODO: VFMADD213PS Y11, Y15, Y11       // c44205a8db
-	//TODO: VFMADD213SD (BX), X9, X2        // c4e2b1a913
-	//TODO: VFMADD213SD (R11), X9, X2       // c4c2b1a913
-	//TODO: VFMADD213SD X2, X9, X2          // c4e2b1a9d2
-	//TODO: VFMADD213SD X11, X9, X2         // c4c2b1a9d3
-	//TODO: VFMADD213SD (BX), X9, X11       // c462b1a91b
-	//TODO: VFMADD213SD (R11), X9, X11      // c442b1a91b
-	//TODO: VFMADD213SD X2, X9, X11         // c462b1a9da
-	//TODO: VFMADD213SD X11, X9, X11        // c442b1a9db
-	//TODO: VFMADD213SS (BX), X9, X2        // c4e231a913
-	//TODO: VFMADD213SS (R11), X9, X2       // c4c231a913
-	//TODO: VFMADD213SS X2, X9, X2          // c4e231a9d2
-	//TODO: VFMADD213SS X11, X9, X2         // c4c231a9d3
-	//TODO: VFMADD213SS (BX), X9, X11       // c46231a91b
-	//TODO: VFMADD213SS (R11), X9, X11      // c44231a91b
-	//TODO: VFMADD213SS X2, X9, X11         // c46231a9da
-	//TODO: VFMADD213SS X11, X9, X11        // c44231a9db
-	//TODO: VFMADD231PD (BX), X9, X2        // c4e2b1b813
-	//TODO: VFMADD231PD (R11), X9, X2       // c4c2b1b813
-	//TODO: VFMADD231PD X2, X9, X2          // c4e2b1b8d2
-	//TODO: VFMADD231PD X11, X9, X2         // c4c2b1b8d3
-	//TODO: VFMADD231PD (BX), X9, X11       // c462b1b81b
-	//TODO: VFMADD231PD (R11), X9, X11      // c442b1b81b
-	//TODO: VFMADD231PD X2, X9, X11         // c462b1b8da
-	//TODO: VFMADD231PD X11, X9, X11        // c442b1b8db
-	//TODO: VFMADD231PD (BX), Y15, Y2       // c4e285b813
-	//TODO: VFMADD231PD (R11), Y15, Y2      // c4c285b813
-	//TODO: VFMADD231PD Y2, Y15, Y2         // c4e285b8d2
-	//TODO: VFMADD231PD Y11, Y15, Y2        // c4c285b8d3
-	//TODO: VFMADD231PD (BX), Y15, Y11      // c46285b81b
-	//TODO: VFMADD231PD (R11), Y15, Y11     // c44285b81b
-	//TODO: VFMADD231PD Y2, Y15, Y11        // c46285b8da
-	//TODO: VFMADD231PD Y11, Y15, Y11       // c44285b8db
-	//TODO: VFMADD231PS (BX), X9, X2        // c4e231b813
-	//TODO: VFMADD231PS (R11), X9, X2       // c4c231b813
-	//TODO: VFMADD231PS X2, X9, X2          // c4e231b8d2
-	//TODO: VFMADD231PS X11, X9, X2         // c4c231b8d3
-	//TODO: VFMADD231PS (BX), X9, X11       // c46231b81b
-	//TODO: VFMADD231PS (R11), X9, X11      // c44231b81b
-	//TODO: VFMADD231PS X2, X9, X11         // c46231b8da
-	//TODO: VFMADD231PS X11, X9, X11        // c44231b8db
-	//TODO: VFMADD231PS (BX), Y15, Y2       // c4e205b813
-	//TODO: VFMADD231PS (R11), Y15, Y2      // c4c205b813
-	//TODO: VFMADD231PS Y2, Y15, Y2         // c4e205b8d2
-	//TODO: VFMADD231PS Y11, Y15, Y2        // c4c205b8d3
-	//TODO: VFMADD231PS (BX), Y15, Y11      // c46205b81b
-	//TODO: VFMADD231PS (R11), Y15, Y11     // c44205b81b
-	//TODO: VFMADD231PS Y2, Y15, Y11        // c46205b8da
-	//TODO: VFMADD231PS Y11, Y15, Y11       // c44205b8db
-	//TODO: VFMADD231SD (BX), X9, X2        // c4e2b1b913
-	//TODO: VFMADD231SD (R11), X9, X2       // c4c2b1b913
-	//TODO: VFMADD231SD X2, X9, X2          // c4e2b1b9d2
-	//TODO: VFMADD231SD X11, X9, X2         // c4c2b1b9d3
-	//TODO: VFMADD231SD (BX), X9, X11       // c462b1b91b
-	//TODO: VFMADD231SD (R11), X9, X11      // c442b1b91b
-	//TODO: VFMADD231SD X2, X9, X11         // c462b1b9da
-	//TODO: VFMADD231SD X11, X9, X11        // c442b1b9db
-	//TODO: VFMADD231SS (BX), X9, X2        // c4e231b913
-	//TODO: VFMADD231SS (R11), X9, X2       // c4c231b913
-	//TODO: VFMADD231SS X2, X9, X2          // c4e231b9d2
-	//TODO: VFMADD231SS X11, X9, X2         // c4c231b9d3
-	//TODO: VFMADD231SS (BX), X9, X11       // c46231b91b
-	//TODO: VFMADD231SS (R11), X9, X11      // c44231b91b
-	//TODO: VFMADD231SS X2, X9, X11         // c46231b9da
-	//TODO: VFMADD231SS X11, X9, X11        // c44231b9db
-	//TODO: VFMADDSUB132PD (BX), X9, X2     // c4e2b19613
-	//TODO: VFMADDSUB132PD (R11), X9, X2    // c4c2b19613
-	//TODO: VFMADDSUB132PD X2, X9, X2       // c4e2b196d2
-	//TODO: VFMADDSUB132PD X11, X9, X2      // c4c2b196d3
-	//TODO: VFMADDSUB132PD (BX), X9, X11    // c462b1961b
-	//TODO: VFMADDSUB132PD (R11), X9, X11   // c442b1961b
-	//TODO: VFMADDSUB132PD X2, X9, X11      // c462b196da
-	//TODO: VFMADDSUB132PD X11, X9, X11     // c442b196db
-	//TODO: VFMADDSUB132PD (BX), Y15, Y2    // c4e2859613
-	//TODO: VFMADDSUB132PD (R11), Y15, Y2   // c4c2859613
-	//TODO: VFMADDSUB132PD Y2, Y15, Y2      // c4e28596d2
-	//TODO: VFMADDSUB132PD Y11, Y15, Y2     // c4c28596d3
-	//TODO: VFMADDSUB132PD (BX), Y15, Y11   // c46285961b
-	//TODO: VFMADDSUB132PD (R11), Y15, Y11  // c44285961b
-	//TODO: VFMADDSUB132PD Y2, Y15, Y11     // c4628596da
-	//TODO: VFMADDSUB132PD Y11, Y15, Y11    // c4428596db
-	//TODO: VFMADDSUB132PS (BX), X9, X2     // c4e2319613
-	//TODO: VFMADDSUB132PS (R11), X9, X2    // c4c2319613
-	//TODO: VFMADDSUB132PS X2, X9, X2       // c4e23196d2
-	//TODO: VFMADDSUB132PS X11, X9, X2      // c4c23196d3
-	//TODO: VFMADDSUB132PS (BX), X9, X11    // c46231961b
-	//TODO: VFMADDSUB132PS (R11), X9, X11   // c44231961b
-	//TODO: VFMADDSUB132PS X2, X9, X11      // c4623196da
-	//TODO: VFMADDSUB132PS X11, X9, X11     // c4423196db
-	//TODO: VFMADDSUB132PS (BX), Y15, Y2    // c4e2059613
-	//TODO: VFMADDSUB132PS (R11), Y15, Y2   // c4c2059613
-	//TODO: VFMADDSUB132PS Y2, Y15, Y2      // c4e20596d2
-	//TODO: VFMADDSUB132PS Y11, Y15, Y2     // c4c20596d3
-	//TODO: VFMADDSUB132PS (BX), Y15, Y11   // c46205961b
-	//TODO: VFMADDSUB132PS (R11), Y15, Y11  // c44205961b
-	//TODO: VFMADDSUB132PS Y2, Y15, Y11     // c4620596da
-	//TODO: VFMADDSUB132PS Y11, Y15, Y11    // c4420596db
-	//TODO: VFMADDSUB213PD (BX), X9, X2     // c4e2b1a613
-	//TODO: VFMADDSUB213PD (R11), X9, X2    // c4c2b1a613
-	//TODO: VFMADDSUB213PD X2, X9, X2       // c4e2b1a6d2
-	//TODO: VFMADDSUB213PD X11, X9, X2      // c4c2b1a6d3
-	//TODO: VFMADDSUB213PD (BX), X9, X11    // c462b1a61b
-	//TODO: VFMADDSUB213PD (R11), X9, X11   // c442b1a61b
-	//TODO: VFMADDSUB213PD X2, X9, X11      // c462b1a6da
-	//TODO: VFMADDSUB213PD X11, X9, X11     // c442b1a6db
-	//TODO: VFMADDSUB213PD (BX), Y15, Y2    // c4e285a613
-	//TODO: VFMADDSUB213PD (R11), Y15, Y2   // c4c285a613
-	//TODO: VFMADDSUB213PD Y2, Y15, Y2      // c4e285a6d2
-	//TODO: VFMADDSUB213PD Y11, Y15, Y2     // c4c285a6d3
-	//TODO: VFMADDSUB213PD (BX), Y15, Y11   // c46285a61b
-	//TODO: VFMADDSUB213PD (R11), Y15, Y11  // c44285a61b
-	//TODO: VFMADDSUB213PD Y2, Y15, Y11     // c46285a6da
-	//TODO: VFMADDSUB213PD Y11, Y15, Y11    // c44285a6db
-	//TODO: VFMADDSUB213PS (BX), X9, X2     // c4e231a613
-	//TODO: VFMADDSUB213PS (R11), X9, X2    // c4c231a613
-	//TODO: VFMADDSUB213PS X2, X9, X2       // c4e231a6d2
-	//TODO: VFMADDSUB213PS X11, X9, X2      // c4c231a6d3
-	//TODO: VFMADDSUB213PS (BX), X9, X11    // c46231a61b
-	//TODO: VFMADDSUB213PS (R11), X9, X11   // c44231a61b
-	//TODO: VFMADDSUB213PS X2, X9, X11      // c46231a6da
-	//TODO: VFMADDSUB213PS X11, X9, X11     // c44231a6db
-	//TODO: VFMADDSUB213PS (BX), Y15, Y2    // c4e205a613
-	//TODO: VFMADDSUB213PS (R11), Y15, Y2   // c4c205a613
-	//TODO: VFMADDSUB213PS Y2, Y15, Y2      // c4e205a6d2
-	//TODO: VFMADDSUB213PS Y11, Y15, Y2     // c4c205a6d3
-	//TODO: VFMADDSUB213PS (BX), Y15, Y11   // c46205a61b
-	//TODO: VFMADDSUB213PS (R11), Y15, Y11  // c44205a61b
-	//TODO: VFMADDSUB213PS Y2, Y15, Y11     // c46205a6da
-	//TODO: VFMADDSUB213PS Y11, Y15, Y11    // c44205a6db
-	//TODO: VFMADDSUB231PD (BX), X9, X2     // c4e2b1b613
-	//TODO: VFMADDSUB231PD (R11), X9, X2    // c4c2b1b613
-	//TODO: VFMADDSUB231PD X2, X9, X2       // c4e2b1b6d2
-	//TODO: VFMADDSUB231PD X11, X9, X2      // c4c2b1b6d3
-	//TODO: VFMADDSUB231PD (BX), X9, X11    // c462b1b61b
-	//TODO: VFMADDSUB231PD (R11), X9, X11   // c442b1b61b
-	//TODO: VFMADDSUB231PD X2, X9, X11      // c462b1b6da
-	//TODO: VFMADDSUB231PD X11, X9, X11     // c442b1b6db
-	//TODO: VFMADDSUB231PD (BX), Y15, Y2    // c4e285b613
-	//TODO: VFMADDSUB231PD (R11), Y15, Y2   // c4c285b613
-	//TODO: VFMADDSUB231PD Y2, Y15, Y2      // c4e285b6d2
-	//TODO: VFMADDSUB231PD Y11, Y15, Y2     // c4c285b6d3
-	//TODO: VFMADDSUB231PD (BX), Y15, Y11   // c46285b61b
-	//TODO: VFMADDSUB231PD (R11), Y15, Y11  // c44285b61b
-	//TODO: VFMADDSUB231PD Y2, Y15, Y11     // c46285b6da
-	//TODO: VFMADDSUB231PD Y11, Y15, Y11    // c44285b6db
-	//TODO: VFMADDSUB231PS (BX), X9, X2     // c4e231b613
-	//TODO: VFMADDSUB231PS (R11), X9, X2    // c4c231b613
-	//TODO: VFMADDSUB231PS X2, X9, X2       // c4e231b6d2
-	//TODO: VFMADDSUB231PS X11, X9, X2      // c4c231b6d3
-	//TODO: VFMADDSUB231PS (BX), X9, X11    // c46231b61b
-	//TODO: VFMADDSUB231PS (R11), X9, X11   // c44231b61b
-	//TODO: VFMADDSUB231PS X2, X9, X11      // c46231b6da
-	//TODO: VFMADDSUB231PS X11, X9, X11     // c44231b6db
-	//TODO: VFMADDSUB231PS (BX), Y15, Y2    // c4e205b613
-	//TODO: VFMADDSUB231PS (R11), Y15, Y2   // c4c205b613
-	//TODO: VFMADDSUB231PS Y2, Y15, Y2      // c4e205b6d2
-	//TODO: VFMADDSUB231PS Y11, Y15, Y2     // c4c205b6d3
-	//TODO: VFMADDSUB231PS (BX), Y15, Y11   // c46205b61b
-	//TODO: VFMADDSUB231PS (R11), Y15, Y11  // c44205b61b
-	//TODO: VFMADDSUB231PS Y2, Y15, Y11     // c46205b6da
-	//TODO: VFMADDSUB231PS Y11, Y15, Y11    // c44205b6db
-	//TODO: VFMSUB132PD (BX), X9, X2        // c4e2b19a13
-	//TODO: VFMSUB132PD (R11), X9, X2       // c4c2b19a13
-	//TODO: VFMSUB132PD X2, X9, X2          // c4e2b19ad2
-	//TODO: VFMSUB132PD X11, X9, X2         // c4c2b19ad3
-	//TODO: VFMSUB132PD (BX), X9, X11       // c462b19a1b
-	//TODO: VFMSUB132PD (R11), X9, X11      // c442b19a1b
-	//TODO: VFMSUB132PD X2, X9, X11         // c462b19ada
-	//TODO: VFMSUB132PD X11, X9, X11        // c442b19adb
-	//TODO: VFMSUB132PD (BX), Y15, Y2       // c4e2859a13
-	//TODO: VFMSUB132PD (R11), Y15, Y2      // c4c2859a13
-	//TODO: VFMSUB132PD Y2, Y15, Y2         // c4e2859ad2
-	//TODO: VFMSUB132PD Y11, Y15, Y2        // c4c2859ad3
-	//TODO: VFMSUB132PD (BX), Y15, Y11      // c462859a1b
-	//TODO: VFMSUB132PD (R11), Y15, Y11     // c442859a1b
-	//TODO: VFMSUB132PD Y2, Y15, Y11        // c462859ada
-	//TODO: VFMSUB132PD Y11, Y15, Y11       // c442859adb
-	//TODO: VFMSUB132PS (BX), X9, X2        // c4e2319a13
-	//TODO: VFMSUB132PS (R11), X9, X2       // c4c2319a13
-	//TODO: VFMSUB132PS X2, X9, X2          // c4e2319ad2
-	//TODO: VFMSUB132PS X11, X9, X2         // c4c2319ad3
-	//TODO: VFMSUB132PS (BX), X9, X11       // c462319a1b
-	//TODO: VFMSUB132PS (R11), X9, X11      // c442319a1b
-	//TODO: VFMSUB132PS X2, X9, X11         // c462319ada
-	//TODO: VFMSUB132PS X11, X9, X11        // c442319adb
-	//TODO: VFMSUB132PS (BX), Y15, Y2       // c4e2059a13
-	//TODO: VFMSUB132PS (R11), Y15, Y2      // c4c2059a13
-	//TODO: VFMSUB132PS Y2, Y15, Y2         // c4e2059ad2
-	//TODO: VFMSUB132PS Y11, Y15, Y2        // c4c2059ad3
-	//TODO: VFMSUB132PS (BX), Y15, Y11      // c462059a1b
-	//TODO: VFMSUB132PS (R11), Y15, Y11     // c442059a1b
-	//TODO: VFMSUB132PS Y2, Y15, Y11        // c462059ada
-	//TODO: VFMSUB132PS Y11, Y15, Y11       // c442059adb
-	//TODO: VFMSUB132SD (BX), X9, X2        // c4e2b19b13
-	//TODO: VFMSUB132SD (R11), X9, X2       // c4c2b19b13
-	//TODO: VFMSUB132SD X2, X9, X2          // c4e2b19bd2
-	//TODO: VFMSUB132SD X11, X9, X2         // c4c2b19bd3
-	//TODO: VFMSUB132SD (BX), X9, X11       // c462b19b1b
-	//TODO: VFMSUB132SD (R11), X9, X11      // c442b19b1b
-	//TODO: VFMSUB132SD X2, X9, X11         // c462b19bda
-	//TODO: VFMSUB132SD X11, X9, X11        // c442b19bdb
-	//TODO: VFMSUB132SS (BX), X9, X2        // c4e2319b13
-	//TODO: VFMSUB132SS (R11), X9, X2       // c4c2319b13
-	//TODO: VFMSUB132SS X2, X9, X2          // c4e2319bd2
-	//TODO: VFMSUB132SS X11, X9, X2         // c4c2319bd3
-	//TODO: VFMSUB132SS (BX), X9, X11       // c462319b1b
-	//TODO: VFMSUB132SS (R11), X9, X11      // c442319b1b
-	//TODO: VFMSUB132SS X2, X9, X11         // c462319bda
-	//TODO: VFMSUB132SS X11, X9, X11        // c442319bdb
-	//TODO: VFMSUB213PD (BX), X9, X2        // c4e2b1aa13
-	//TODO: VFMSUB213PD (R11), X9, X2       // c4c2b1aa13
-	//TODO: VFMSUB213PD X2, X9, X2          // c4e2b1aad2
-	//TODO: VFMSUB213PD X11, X9, X2         // c4c2b1aad3
-	//TODO: VFMSUB213PD (BX), X9, X11       // c462b1aa1b
-	//TODO: VFMSUB213PD (R11), X9, X11      // c442b1aa1b
-	//TODO: VFMSUB213PD X2, X9, X11         // c462b1aada
-	//TODO: VFMSUB213PD X11, X9, X11        // c442b1aadb
-	//TODO: VFMSUB213PD (BX), Y15, Y2       // c4e285aa13
-	//TODO: VFMSUB213PD (R11), Y15, Y2      // c4c285aa13
-	//TODO: VFMSUB213PD Y2, Y15, Y2         // c4e285aad2
-	//TODO: VFMSUB213PD Y11, Y15, Y2        // c4c285aad3
-	//TODO: VFMSUB213PD (BX), Y15, Y11      // c46285aa1b
-	//TODO: VFMSUB213PD (R11), Y15, Y11     // c44285aa1b
-	//TODO: VFMSUB213PD Y2, Y15, Y11        // c46285aada
-	//TODO: VFMSUB213PD Y11, Y15, Y11       // c44285aadb
-	//TODO: VFMSUB213PS (BX), X9, X2        // c4e231aa13
-	//TODO: VFMSUB213PS (R11), X9, X2       // c4c231aa13
-	//TODO: VFMSUB213PS X2, X9, X2          // c4e231aad2
-	//TODO: VFMSUB213PS X11, X9, X2         // c4c231aad3
-	//TODO: VFMSUB213PS (BX), X9, X11       // c46231aa1b
-	//TODO: VFMSUB213PS (R11), X9, X11      // c44231aa1b
-	//TODO: VFMSUB213PS X2, X9, X11         // c46231aada
-	//TODO: VFMSUB213PS X11, X9, X11        // c44231aadb
-	//TODO: VFMSUB213PS (BX), Y15, Y2       // c4e205aa13
-	//TODO: VFMSUB213PS (R11), Y15, Y2      // c4c205aa13
-	//TODO: VFMSUB213PS Y2, Y15, Y2         // c4e205aad2
-	//TODO: VFMSUB213PS Y11, Y15, Y2        // c4c205aad3
-	//TODO: VFMSUB213PS (BX), Y15, Y11      // c46205aa1b
-	//TODO: VFMSUB213PS (R11), Y15, Y11     // c44205aa1b
-	//TODO: VFMSUB213PS Y2, Y15, Y11        // c46205aada
-	//TODO: VFMSUB213PS Y11, Y15, Y11       // c44205aadb
-	//TODO: VFMSUB213SD (BX), X9, X2        // c4e2b1ab13
-	//TODO: VFMSUB213SD (R11), X9, X2       // c4c2b1ab13
-	//TODO: VFMSUB213SD X2, X9, X2          // c4e2b1abd2
-	//TODO: VFMSUB213SD X11, X9, X2         // c4c2b1abd3
-	//TODO: VFMSUB213SD (BX), X9, X11       // c462b1ab1b
-	//TODO: VFMSUB213SD (R11), X9, X11      // c442b1ab1b
-	//TODO: VFMSUB213SD X2, X9, X11         // c462b1abda
-	//TODO: VFMSUB213SD X11, X9, X11        // c442b1abdb
-	//TODO: VFMSUB213SS (BX), X9, X2        // c4e231ab13
-	//TODO: VFMSUB213SS (R11), X9, X2       // c4c231ab13
-	//TODO: VFMSUB213SS X2, X9, X2          // c4e231abd2
-	//TODO: VFMSUB213SS X11, X9, X2         // c4c231abd3
-	//TODO: VFMSUB213SS (BX), X9, X11       // c46231ab1b
-	//TODO: VFMSUB213SS (R11), X9, X11      // c44231ab1b
-	//TODO: VFMSUB213SS X2, X9, X11         // c46231abda
-	//TODO: VFMSUB213SS X11, X9, X11        // c44231abdb
-	//TODO: VFMSUB231PD (BX), X9, X2        // c4e2b1ba13
-	//TODO: VFMSUB231PD (R11), X9, X2       // c4c2b1ba13
-	//TODO: VFMSUB231PD X2, X9, X2          // c4e2b1bad2
-	//TODO: VFMSUB231PD X11, X9, X2         // c4c2b1bad3
-	//TODO: VFMSUB231PD (BX), X9, X11       // c462b1ba1b
-	//TODO: VFMSUB231PD (R11), X9, X11      // c442b1ba1b
-	//TODO: VFMSUB231PD X2, X9, X11         // c462b1bada
-	//TODO: VFMSUB231PD X11, X9, X11        // c442b1badb
-	//TODO: VFMSUB231PD (BX), Y15, Y2       // c4e285ba13
-	//TODO: VFMSUB231PD (R11), Y15, Y2      // c4c285ba13
-	//TODO: VFMSUB231PD Y2, Y15, Y2         // c4e285bad2
-	//TODO: VFMSUB231PD Y11, Y15, Y2        // c4c285bad3
-	//TODO: VFMSUB231PD (BX), Y15, Y11      // c46285ba1b
-	//TODO: VFMSUB231PD (R11), Y15, Y11     // c44285ba1b
-	//TODO: VFMSUB231PD Y2, Y15, Y11        // c46285bada
-	//TODO: VFMSUB231PD Y11, Y15, Y11       // c44285badb
-	//TODO: VFMSUB231PS (BX), X9, X2        // c4e231ba13
-	//TODO: VFMSUB231PS (R11), X9, X2       // c4c231ba13
-	//TODO: VFMSUB231PS X2, X9, X2          // c4e231bad2
-	//TODO: VFMSUB231PS X11, X9, X2         // c4c231bad3
-	//TODO: VFMSUB231PS (BX), X9, X11       // c46231ba1b
-	//TODO: VFMSUB231PS (R11), X9, X11      // c44231ba1b
-	//TODO: VFMSUB231PS X2, X9, X11         // c46231bada
-	//TODO: VFMSUB231PS X11, X9, X11        // c44231badb
-	//TODO: VFMSUB231PS (BX), Y15, Y2       // c4e205ba13
-	//TODO: VFMSUB231PS (R11), Y15, Y2      // c4c205ba13
-	//TODO: VFMSUB231PS Y2, Y15, Y2         // c4e205bad2
-	//TODO: VFMSUB231PS Y11, Y15, Y2        // c4c205bad3
-	//TODO: VFMSUB231PS (BX), Y15, Y11      // c46205ba1b
-	//TODO: VFMSUB231PS (R11), Y15, Y11     // c44205ba1b
-	//TODO: VFMSUB231PS Y2, Y15, Y11        // c46205bada
-	//TODO: VFMSUB231PS Y11, Y15, Y11       // c44205badb
-	//TODO: VFMSUB231SD (BX), X9, X2        // c4e2b1bb13
-	//TODO: VFMSUB231SD (R11), X9, X2       // c4c2b1bb13
-	//TODO: VFMSUB231SD X2, X9, X2          // c4e2b1bbd2
-	//TODO: VFMSUB231SD X11, X9, X2         // c4c2b1bbd3
-	//TODO: VFMSUB231SD (BX), X9, X11       // c462b1bb1b
-	//TODO: VFMSUB231SD (R11), X9, X11      // c442b1bb1b
-	//TODO: VFMSUB231SD X2, X9, X11         // c462b1bbda
-	//TODO: VFMSUB231SD X11, X9, X11        // c442b1bbdb
-	//TODO: VFMSUB231SS (BX), X9, X2        // c4e231bb13
-	//TODO: VFMSUB231SS (R11), X9, X2       // c4c231bb13
-	//TODO: VFMSUB231SS X2, X9, X2          // c4e231bbd2
-	//TODO: VFMSUB231SS X11, X9, X2         // c4c231bbd3
-	//TODO: VFMSUB231SS (BX), X9, X11       // c46231bb1b
-	//TODO: VFMSUB231SS (R11), X9, X11      // c44231bb1b
-	//TODO: VFMSUB231SS X2, X9, X11         // c46231bbda
-	//TODO: VFMSUB231SS X11, X9, X11        // c44231bbdb
-	//TODO: VFMSUBADD132PD (BX), X9, X2     // c4e2b19713
-	//TODO: VFMSUBADD132PD (R11), X9, X2    // c4c2b19713
-	//TODO: VFMSUBADD132PD X2, X9, X2       // c4e2b197d2
-	//TODO: VFMSUBADD132PD X11, X9, X2      // c4c2b197d3
-	//TODO: VFMSUBADD132PD (BX), X9, X11    // c462b1971b
-	//TODO: VFMSUBADD132PD (R11), X9, X11   // c442b1971b
-	//TODO: VFMSUBADD132PD X2, X9, X11      // c462b197da
-	//TODO: VFMSUBADD132PD X11, X9, X11     // c442b197db
-	//TODO: VFMSUBADD132PD (BX), Y15, Y2    // c4e2859713
-	//TODO: VFMSUBADD132PD (R11), Y15, Y2   // c4c2859713
-	//TODO: VFMSUBADD132PD Y2, Y15, Y2      // c4e28597d2
-	//TODO: VFMSUBADD132PD Y11, Y15, Y2     // c4c28597d3
-	//TODO: VFMSUBADD132PD (BX), Y15, Y11   // c46285971b
-	//TODO: VFMSUBADD132PD (R11), Y15, Y11  // c44285971b
-	//TODO: VFMSUBADD132PD Y2, Y15, Y11     // c4628597da
-	//TODO: VFMSUBADD132PD Y11, Y15, Y11    // c4428597db
-	//TODO: VFMSUBADD132PS (BX), X9, X2     // c4e2319713
-	//TODO: VFMSUBADD132PS (R11), X9, X2    // c4c2319713
-	//TODO: VFMSUBADD132PS X2, X9, X2       // c4e23197d2
-	//TODO: VFMSUBADD132PS X11, X9, X2      // c4c23197d3
-	//TODO: VFMSUBADD132PS (BX), X9, X11    // c46231971b
-	//TODO: VFMSUBADD132PS (R11), X9, X11   // c44231971b
-	//TODO: VFMSUBADD132PS X2, X9, X11      // c4623197da
-	//TODO: VFMSUBADD132PS X11, X9, X11     // c4423197db
-	//TODO: VFMSUBADD132PS (BX), Y15, Y2    // c4e2059713
-	//TODO: VFMSUBADD132PS (R11), Y15, Y2   // c4c2059713
-	//TODO: VFMSUBADD132PS Y2, Y15, Y2      // c4e20597d2
-	//TODO: VFMSUBADD132PS Y11, Y15, Y2     // c4c20597d3
-	//TODO: VFMSUBADD132PS (BX), Y15, Y11   // c46205971b
-	//TODO: VFMSUBADD132PS (R11), Y15, Y11  // c44205971b
-	//TODO: VFMSUBADD132PS Y2, Y15, Y11     // c4620597da
-	//TODO: VFMSUBADD132PS Y11, Y15, Y11    // c4420597db
-	//TODO: VFMSUBADD213PD (BX), X9, X2     // c4e2b1a713
-	//TODO: VFMSUBADD213PD (R11), X9, X2    // c4c2b1a713
-	//TODO: VFMSUBADD213PD X2, X9, X2       // c4e2b1a7d2
-	//TODO: VFMSUBADD213PD X11, X9, X2      // c4c2b1a7d3
-	//TODO: VFMSUBADD213PD (BX), X9, X11    // c462b1a71b
-	//TODO: VFMSUBADD213PD (R11), X9, X11   // c442b1a71b
-	//TODO: VFMSUBADD213PD X2, X9, X11      // c462b1a7da
-	//TODO: VFMSUBADD213PD X11, X9, X11     // c442b1a7db
-	//TODO: VFMSUBADD213PD (BX), Y15, Y2    // c4e285a713
-	//TODO: VFMSUBADD213PD (R11), Y15, Y2   // c4c285a713
-	//TODO: VFMSUBADD213PD Y2, Y15, Y2      // c4e285a7d2
-	//TODO: VFMSUBADD213PD Y11, Y15, Y2     // c4c285a7d3
-	//TODO: VFMSUBADD213PD (BX), Y15, Y11   // c46285a71b
-	//TODO: VFMSUBADD213PD (R11), Y15, Y11  // c44285a71b
-	//TODO: VFMSUBADD213PD Y2, Y15, Y11     // c46285a7da
-	//TODO: VFMSUBADD213PD Y11, Y15, Y11    // c44285a7db
-	//TODO: VFMSUBADD213PS (BX), X9, X2     // c4e231a713
-	//TODO: VFMSUBADD213PS (R11), X9, X2    // c4c231a713
-	//TODO: VFMSUBADD213PS X2, X9, X2       // c4e231a7d2
-	//TODO: VFMSUBADD213PS X11, X9, X2      // c4c231a7d3
-	//TODO: VFMSUBADD213PS (BX), X9, X11    // c46231a71b
-	//TODO: VFMSUBADD213PS (R11), X9, X11   // c44231a71b
-	//TODO: VFMSUBADD213PS X2, X9, X11      // c46231a7da
-	//TODO: VFMSUBADD213PS X11, X9, X11     // c44231a7db
-	//TODO: VFMSUBADD213PS (BX), Y15, Y2    // c4e205a713
-	//TODO: VFMSUBADD213PS (R11), Y15, Y2   // c4c205a713
-	//TODO: VFMSUBADD213PS Y2, Y15, Y2      // c4e205a7d2
-	//TODO: VFMSUBADD213PS Y11, Y15, Y2     // c4c205a7d3
-	//TODO: VFMSUBADD213PS (BX), Y15, Y11   // c46205a71b
-	//TODO: VFMSUBADD213PS (R11), Y15, Y11  // c44205a71b
-	//TODO: VFMSUBADD213PS Y2, Y15, Y11     // c46205a7da
-	//TODO: VFMSUBADD213PS Y11, Y15, Y11    // c44205a7db
-	//TODO: VFMSUBADD231PD (BX), X9, X2     // c4e2b1b713
-	//TODO: VFMSUBADD231PD (R11), X9, X2    // c4c2b1b713
-	//TODO: VFMSUBADD231PD X2, X9, X2       // c4e2b1b7d2
-	//TODO: VFMSUBADD231PD X11, X9, X2      // c4c2b1b7d3
-	//TODO: VFMSUBADD231PD (BX), X9, X11    // c462b1b71b
-	//TODO: VFMSUBADD231PD (R11), X9, X11   // c442b1b71b
-	//TODO: VFMSUBADD231PD X2, X9, X11      // c462b1b7da
-	//TODO: VFMSUBADD231PD X11, X9, X11     // c442b1b7db
-	//TODO: VFMSUBADD231PD (BX), Y15, Y2    // c4e285b713
-	//TODO: VFMSUBADD231PD (R11), Y15, Y2   // c4c285b713
-	//TODO: VFMSUBADD231PD Y2, Y15, Y2      // c4e285b7d2
-	//TODO: VFMSUBADD231PD Y11, Y15, Y2     // c4c285b7d3
-	//TODO: VFMSUBADD231PD (BX), Y15, Y11   // c46285b71b
-	//TODO: VFMSUBADD231PD (R11), Y15, Y11  // c44285b71b
-	//TODO: VFMSUBADD231PD Y2, Y15, Y11     // c46285b7da
-	//TODO: VFMSUBADD231PD Y11, Y15, Y11    // c44285b7db
-	//TODO: VFMSUBADD231PS (BX), X9, X2     // c4e231b713
-	//TODO: VFMSUBADD231PS (R11), X9, X2    // c4c231b713
-	//TODO: VFMSUBADD231PS X2, X9, X2       // c4e231b7d2
-	//TODO: VFMSUBADD231PS X11, X9, X2      // c4c231b7d3
-	//TODO: VFMSUBADD231PS (BX), X9, X11    // c46231b71b
-	//TODO: VFMSUBADD231PS (R11), X9, X11   // c44231b71b
-	//TODO: VFMSUBADD231PS X2, X9, X11      // c46231b7da
-	//TODO: VFMSUBADD231PS X11, X9, X11     // c44231b7db
-	//TODO: VFMSUBADD231PS (BX), Y15, Y2    // c4e205b713
-	//TODO: VFMSUBADD231PS (R11), Y15, Y2   // c4c205b713
-	//TODO: VFMSUBADD231PS Y2, Y15, Y2      // c4e205b7d2
-	//TODO: VFMSUBADD231PS Y11, Y15, Y2     // c4c205b7d3
-	//TODO: VFMSUBADD231PS (BX), Y15, Y11   // c46205b71b
-	//TODO: VFMSUBADD231PS (R11), Y15, Y11  // c44205b71b
-	//TODO: VFMSUBADD231PS Y2, Y15, Y11     // c46205b7da
-	//TODO: VFMSUBADD231PS Y11, Y15, Y11    // c44205b7db
-	//TODO: VFNMADD132PD (BX), X9, X2       // c4e2b19c13
-	//TODO: VFNMADD132PD (R11), X9, X2      // c4c2b19c13
-	//TODO: VFNMADD132PD X2, X9, X2         // c4e2b19cd2
-	//TODO: VFNMADD132PD X11, X9, X2        // c4c2b19cd3
-	//TODO: VFNMADD132PD (BX), X9, X11      // c462b19c1b
-	//TODO: VFNMADD132PD (R11), X9, X11     // c442b19c1b
-	//TODO: VFNMADD132PD X2, X9, X11        // c462b19cda
-	//TODO: VFNMADD132PD X11, X9, X11       // c442b19cdb
-	//TODO: VFNMADD132PD (BX), Y15, Y2      // c4e2859c13
-	//TODO: VFNMADD132PD (R11), Y15, Y2     // c4c2859c13
-	//TODO: VFNMADD132PD Y2, Y15, Y2        // c4e2859cd2
-	//TODO: VFNMADD132PD Y11, Y15, Y2       // c4c2859cd3
-	//TODO: VFNMADD132PD (BX), Y15, Y11     // c462859c1b
-	//TODO: VFNMADD132PD (R11), Y15, Y11    // c442859c1b
-	//TODO: VFNMADD132PD Y2, Y15, Y11       // c462859cda
-	//TODO: VFNMADD132PD Y11, Y15, Y11      // c442859cdb
-	//TODO: VFNMADD132PS (BX), X9, X2       // c4e2319c13
-	//TODO: VFNMADD132PS (R11), X9, X2      // c4c2319c13
-	//TODO: VFNMADD132PS X2, X9, X2         // c4e2319cd2
-	//TODO: VFNMADD132PS X11, X9, X2        // c4c2319cd3
-	//TODO: VFNMADD132PS (BX), X9, X11      // c462319c1b
-	//TODO: VFNMADD132PS (R11), X9, X11     // c442319c1b
-	//TODO: VFNMADD132PS X2, X9, X11        // c462319cda
-	//TODO: VFNMADD132PS X11, X9, X11       // c442319cdb
-	//TODO: VFNMADD132PS (BX), Y15, Y2      // c4e2059c13
-	//TODO: VFNMADD132PS (R11), Y15, Y2     // c4c2059c13
-	//TODO: VFNMADD132PS Y2, Y15, Y2        // c4e2059cd2
-	//TODO: VFNMADD132PS Y11, Y15, Y2       // c4c2059cd3
-	//TODO: VFNMADD132PS (BX), Y15, Y11     // c462059c1b
-	//TODO: VFNMADD132PS (R11), Y15, Y11    // c442059c1b
-	//TODO: VFNMADD132PS Y2, Y15, Y11       // c462059cda
-	//TODO: VFNMADD132PS Y11, Y15, Y11      // c442059cdb
-	//TODO: VFNMADD132SD (BX), X9, X2       // c4e2b19d13
-	//TODO: VFNMADD132SD (R11), X9, X2      // c4c2b19d13
-	//TODO: VFNMADD132SD X2, X9, X2         // c4e2b19dd2
-	//TODO: VFNMADD132SD X11, X9, X2        // c4c2b19dd3
-	//TODO: VFNMADD132SD (BX), X9, X11      // c462b19d1b
-	//TODO: VFNMADD132SD (R11), X9, X11     // c442b19d1b
-	//TODO: VFNMADD132SD X2, X9, X11        // c462b19dda
-	//TODO: VFNMADD132SD X11, X9, X11       // c442b19ddb
-	//TODO: VFNMADD132SS (BX), X9, X2       // c4e2319d13
-	//TODO: VFNMADD132SS (R11), X9, X2      // c4c2319d13
-	//TODO: VFNMADD132SS X2, X9, X2         // c4e2319dd2
-	//TODO: VFNMADD132SS X11, X9, X2        // c4c2319dd3
-	//TODO: VFNMADD132SS (BX), X9, X11      // c462319d1b
-	//TODO: VFNMADD132SS (R11), X9, X11     // c442319d1b
-	//TODO: VFNMADD132SS X2, X9, X11        // c462319dda
-	//TODO: VFNMADD132SS X11, X9, X11       // c442319ddb
-	//TODO: VFNMADD213PD (BX), X9, X2       // c4e2b1ac13
-	//TODO: VFNMADD213PD (R11), X9, X2      // c4c2b1ac13
-	//TODO: VFNMADD213PD X2, X9, X2         // c4e2b1acd2
-	//TODO: VFNMADD213PD X11, X9, X2        // c4c2b1acd3
-	//TODO: VFNMADD213PD (BX), X9, X11      // c462b1ac1b
-	//TODO: VFNMADD213PD (R11), X9, X11     // c442b1ac1b
-	//TODO: VFNMADD213PD X2, X9, X11        // c462b1acda
-	//TODO: VFNMADD213PD X11, X9, X11       // c442b1acdb
-	//TODO: VFNMADD213PD (BX), Y15, Y2      // c4e285ac13
-	//TODO: VFNMADD213PD (R11), Y15, Y2     // c4c285ac13
-	//TODO: VFNMADD213PD Y2, Y15, Y2        // c4e285acd2
-	//TODO: VFNMADD213PD Y11, Y15, Y2       // c4c285acd3
-	//TODO: VFNMADD213PD (BX), Y15, Y11     // c46285ac1b
-	//TODO: VFNMADD213PD (R11), Y15, Y11    // c44285ac1b
-	//TODO: VFNMADD213PD Y2, Y15, Y11       // c46285acda
-	//TODO: VFNMADD213PD Y11, Y15, Y11      // c44285acdb
-	//TODO: VFNMADD213PS (BX), X9, X2       // c4e231ac13
-	//TODO: VFNMADD213PS (R11), X9, X2      // c4c231ac13
-	//TODO: VFNMADD213PS X2, X9, X2         // c4e231acd2
-	//TODO: VFNMADD213PS X11, X9, X2        // c4c231acd3
-	//TODO: VFNMADD213PS (BX), X9, X11      // c46231ac1b
-	//TODO: VFNMADD213PS (R11), X9, X11     // c44231ac1b
-	//TODO: VFNMADD213PS X2, X9, X11        // c46231acda
-	//TODO: VFNMADD213PS X11, X9, X11       // c44231acdb
-	//TODO: VFNMADD213PS (BX), Y15, Y2      // c4e205ac13
-	//TODO: VFNMADD213PS (R11), Y15, Y2     // c4c205ac13
-	//TODO: VFNMADD213PS Y2, Y15, Y2        // c4e205acd2
-	//TODO: VFNMADD213PS Y11, Y15, Y2       // c4c205acd3
-	//TODO: VFNMADD213PS (BX), Y15, Y11     // c46205ac1b
-	//TODO: VFNMADD213PS (R11), Y15, Y11    // c44205ac1b
-	//TODO: VFNMADD213PS Y2, Y15, Y11       // c46205acda
-	//TODO: VFNMADD213PS Y11, Y15, Y11      // c44205acdb
-	//TODO: VFNMADD213SD (BX), X9, X2       // c4e2b1ad13
-	//TODO: VFNMADD213SD (R11), X9, X2      // c4c2b1ad13
-	//TODO: VFNMADD213SD X2, X9, X2         // c4e2b1add2
-	//TODO: VFNMADD213SD X11, X9, X2        // c4c2b1add3
-	//TODO: VFNMADD213SD (BX), X9, X11      // c462b1ad1b
-	//TODO: VFNMADD213SD (R11), X9, X11     // c442b1ad1b
-	//TODO: VFNMADD213SD X2, X9, X11        // c462b1adda
-	//TODO: VFNMADD213SD X11, X9, X11       // c442b1addb
-	//TODO: VFNMADD213SS (BX), X9, X2       // c4e231ad13
-	//TODO: VFNMADD213SS (R11), X9, X2      // c4c231ad13
-	//TODO: VFNMADD213SS X2, X9, X2         // c4e231add2
-	//TODO: VFNMADD213SS X11, X9, X2        // c4c231add3
-	//TODO: VFNMADD213SS (BX), X9, X11      // c46231ad1b
-	//TODO: VFNMADD213SS (R11), X9, X11     // c44231ad1b
-	//TODO: VFNMADD213SS X2, X9, X11        // c46231adda
-	//TODO: VFNMADD213SS X11, X9, X11       // c44231addb
-	//TODO: VFNMADD231PD (BX), X9, X2       // c4e2b1bc13
-	//TODO: VFNMADD231PD (R11), X9, X2      // c4c2b1bc13
-	//TODO: VFNMADD231PD X2, X9, X2         // c4e2b1bcd2
-	//TODO: VFNMADD231PD X11, X9, X2        // c4c2b1bcd3
-	//TODO: VFNMADD231PD (BX), X9, X11      // c462b1bc1b
-	//TODO: VFNMADD231PD (R11), X9, X11     // c442b1bc1b
-	//TODO: VFNMADD231PD X2, X9, X11        // c462b1bcda
-	//TODO: VFNMADD231PD X11, X9, X11       // c442b1bcdb
-	//TODO: VFNMADD231PD (BX), Y15, Y2      // c4e285bc13
-	//TODO: VFNMADD231PD (R11), Y15, Y2     // c4c285bc13
-	//TODO: VFNMADD231PD Y2, Y15, Y2        // c4e285bcd2
-	//TODO: VFNMADD231PD Y11, Y15, Y2       // c4c285bcd3
-	//TODO: VFNMADD231PD (BX), Y15, Y11     // c46285bc1b
-	//TODO: VFNMADD231PD (R11), Y15, Y11    // c44285bc1b
-	//TODO: VFNMADD231PD Y2, Y15, Y11       // c46285bcda
-	//TODO: VFNMADD231PD Y11, Y15, Y11      // c44285bcdb
-	//TODO: VFNMADD231PS (BX), X9, X2       // c4e231bc13
-	//TODO: VFNMADD231PS (R11), X9, X2      // c4c231bc13
-	//TODO: VFNMADD231PS X2, X9, X2         // c4e231bcd2
-	//TODO: VFNMADD231PS X11, X9, X2        // c4c231bcd3
-	//TODO: VFNMADD231PS (BX), X9, X11      // c46231bc1b
-	//TODO: VFNMADD231PS (R11), X9, X11     // c44231bc1b
-	//TODO: VFNMADD231PS X2, X9, X11        // c46231bcda
-	//TODO: VFNMADD231PS X11, X9, X11       // c44231bcdb
-	//TODO: VFNMADD231PS (BX), Y15, Y2      // c4e205bc13
-	//TODO: VFNMADD231PS (R11), Y15, Y2     // c4c205bc13
-	//TODO: VFNMADD231PS Y2, Y15, Y2        // c4e205bcd2
-	//TODO: VFNMADD231PS Y11, Y15, Y2       // c4c205bcd3
-	//TODO: VFNMADD231PS (BX), Y15, Y11     // c46205bc1b
-	//TODO: VFNMADD231PS (R11), Y15, Y11    // c44205bc1b
-	//TODO: VFNMADD231PS Y2, Y15, Y11       // c46205bcda
-	//TODO: VFNMADD231PS Y11, Y15, Y11      // c44205bcdb
-	//TODO: VFNMADD231SD (BX), X9, X2       // c4e2b1bd13
-	//TODO: VFNMADD231SD (R11), X9, X2      // c4c2b1bd13
-	//TODO: VFNMADD231SD X2, X9, X2         // c4e2b1bdd2
-	//TODO: VFNMADD231SD X11, X9, X2        // c4c2b1bdd3
-	//TODO: VFNMADD231SD (BX), X9, X11      // c462b1bd1b
-	//TODO: VFNMADD231SD (R11), X9, X11     // c442b1bd1b
-	//TODO: VFNMADD231SD X2, X9, X11        // c462b1bdda
-	//TODO: VFNMADD231SD X11, X9, X11       // c442b1bddb
-	//TODO: VFNMADD231SS (BX), X9, X2       // c4e231bd13
-	//TODO: VFNMADD231SS (R11), X9, X2      // c4c231bd13
-	//TODO: VFNMADD231SS X2, X9, X2         // c4e231bdd2
-	//TODO: VFNMADD231SS X11, X9, X2        // c4c231bdd3
-	//TODO: VFNMADD231SS (BX), X9, X11      // c46231bd1b
-	//TODO: VFNMADD231SS (R11), X9, X11     // c44231bd1b
-	//TODO: VFNMADD231SS X2, X9, X11        // c46231bdda
-	//TODO: VFNMADD231SS X11, X9, X11       // c44231bddb
-	//TODO: VFNMSUB132PD (BX), X9, X2       // c4e2b19e13
-	//TODO: VFNMSUB132PD (R11), X9, X2      // c4c2b19e13
-	//TODO: VFNMSUB132PD X2, X9, X2         // c4e2b19ed2
-	//TODO: VFNMSUB132PD X11, X9, X2        // c4c2b19ed3
-	//TODO: VFNMSUB132PD (BX), X9, X11      // c462b19e1b
-	//TODO: VFNMSUB132PD (R11), X9, X11     // c442b19e1b
-	//TODO: VFNMSUB132PD X2, X9, X11        // c462b19eda
-	//TODO: VFNMSUB132PD X11, X9, X11       // c442b19edb
-	//TODO: VFNMSUB132PD (BX), Y15, Y2      // c4e2859e13
-	//TODO: VFNMSUB132PD (R11), Y15, Y2     // c4c2859e13
-	//TODO: VFNMSUB132PD Y2, Y15, Y2        // c4e2859ed2
-	//TODO: VFNMSUB132PD Y11, Y15, Y2       // c4c2859ed3
-	//TODO: VFNMSUB132PD (BX), Y15, Y11     // c462859e1b
-	//TODO: VFNMSUB132PD (R11), Y15, Y11    // c442859e1b
-	//TODO: VFNMSUB132PD Y2, Y15, Y11       // c462859eda
-	//TODO: VFNMSUB132PD Y11, Y15, Y11      // c442859edb
-	//TODO: VFNMSUB132PS (BX), X9, X2       // c4e2319e13
-	//TODO: VFNMSUB132PS (R11), X9, X2      // c4c2319e13
-	//TODO: VFNMSUB132PS X2, X9, X2         // c4e2319ed2
-	//TODO: VFNMSUB132PS X11, X9, X2        // c4c2319ed3
-	//TODO: VFNMSUB132PS (BX), X9, X11      // c462319e1b
-	//TODO: VFNMSUB132PS (R11), X9, X11     // c442319e1b
-	//TODO: VFNMSUB132PS X2, X9, X11        // c462319eda
-	//TODO: VFNMSUB132PS X11, X9, X11       // c442319edb
-	//TODO: VFNMSUB132PS (BX), Y15, Y2      // c4e2059e13
-	//TODO: VFNMSUB132PS (R11), Y15, Y2     // c4c2059e13
-	//TODO: VFNMSUB132PS Y2, Y15, Y2        // c4e2059ed2
-	//TODO: VFNMSUB132PS Y11, Y15, Y2       // c4c2059ed3
-	//TODO: VFNMSUB132PS (BX), Y15, Y11     // c462059e1b
-	//TODO: VFNMSUB132PS (R11), Y15, Y11    // c442059e1b
-	//TODO: VFNMSUB132PS Y2, Y15, Y11       // c462059eda
-	//TODO: VFNMSUB132PS Y11, Y15, Y11      // c442059edb
-	//TODO: VFNMSUB132SD (BX), X9, X2       // c4e2b19f13
-	//TODO: VFNMSUB132SD (R11), X9, X2      // c4c2b19f13
-	//TODO: VFNMSUB132SD X2, X9, X2         // c4e2b19fd2
-	//TODO: VFNMSUB132SD X11, X9, X2        // c4c2b19fd3
-	//TODO: VFNMSUB132SD (BX), X9, X11      // c462b19f1b
-	//TODO: VFNMSUB132SD (R11), X9, X11     // c442b19f1b
-	//TODO: VFNMSUB132SD X2, X9, X11        // c462b19fda
-	//TODO: VFNMSUB132SD X11, X9, X11       // c442b19fdb
-	//TODO: VFNMSUB132SS (BX), X9, X2       // c4e2319f13
-	//TODO: VFNMSUB132SS (R11), X9, X2      // c4c2319f13
-	//TODO: VFNMSUB132SS X2, X9, X2         // c4e2319fd2
-	//TODO: VFNMSUB132SS X11, X9, X2        // c4c2319fd3
-	//TODO: VFNMSUB132SS (BX), X9, X11      // c462319f1b
-	//TODO: VFNMSUB132SS (R11), X9, X11     // c442319f1b
-	//TODO: VFNMSUB132SS X2, X9, X11        // c462319fda
-	//TODO: VFNMSUB132SS X11, X9, X11       // c442319fdb
-	//TODO: VFNMSUB213PD (BX), X9, X2       // c4e2b1ae13
-	//TODO: VFNMSUB213PD (R11), X9, X2      // c4c2b1ae13
-	//TODO: VFNMSUB213PD X2, X9, X2         // c4e2b1aed2
-	//TODO: VFNMSUB213PD X11, X9, X2        // c4c2b1aed3
-	//TODO: VFNMSUB213PD (BX), X9, X11      // c462b1ae1b
-	//TODO: VFNMSUB213PD (R11), X9, X11     // c442b1ae1b
-	//TODO: VFNMSUB213PD X2, X9, X11        // c462b1aeda
-	//TODO: VFNMSUB213PD X11, X9, X11       // c442b1aedb
-	//TODO: VFNMSUB213PD (BX), Y15, Y2      // c4e285ae13
-	//TODO: VFNMSUB213PD (R11), Y15, Y2     // c4c285ae13
-	//TODO: VFNMSUB213PD Y2, Y15, Y2        // c4e285aed2
-	//TODO: VFNMSUB213PD Y11, Y15, Y2       // c4c285aed3
-	//TODO: VFNMSUB213PD (BX), Y15, Y11     // c46285ae1b
-	//TODO: VFNMSUB213PD (R11), Y15, Y11    // c44285ae1b
-	//TODO: VFNMSUB213PD Y2, Y15, Y11       // c46285aeda
-	//TODO: VFNMSUB213PD Y11, Y15, Y11      // c44285aedb
-	//TODO: VFNMSUB213PS (BX), X9, X2       // c4e231ae13
-	//TODO: VFNMSUB213PS (R11), X9, X2      // c4c231ae13
-	//TODO: VFNMSUB213PS X2, X9, X2         // c4e231aed2
-	//TODO: VFNMSUB213PS X11, X9, X2        // c4c231aed3
-	//TODO: VFNMSUB213PS (BX), X9, X11      // c46231ae1b
-	//TODO: VFNMSUB213PS (R11), X9, X11     // c44231ae1b
-	//TODO: VFNMSUB213PS X2, X9, X11        // c46231aeda
-	//TODO: VFNMSUB213PS X11, X9, X11       // c44231aedb
-	//TODO: VFNMSUB213PS (BX), Y15, Y2      // c4e205ae13
-	//TODO: VFNMSUB213PS (R11), Y15, Y2     // c4c205ae13
-	//TODO: VFNMSUB213PS Y2, Y15, Y2        // c4e205aed2
-	//TODO: VFNMSUB213PS Y11, Y15, Y2       // c4c205aed3
-	//TODO: VFNMSUB213PS (BX), Y15, Y11     // c46205ae1b
-	//TODO: VFNMSUB213PS (R11), Y15, Y11    // c44205ae1b
-	//TODO: VFNMSUB213PS Y2, Y15, Y11       // c46205aeda
-	//TODO: VFNMSUB213PS Y11, Y15, Y11      // c44205aedb
-	//TODO: VFNMSUB213SD (BX), X9, X2       // c4e2b1af13
-	//TODO: VFNMSUB213SD (R11), X9, X2      // c4c2b1af13
-	//TODO: VFNMSUB213SD X2, X9, X2         // c4e2b1afd2
-	//TODO: VFNMSUB213SD X11, X9, X2        // c4c2b1afd3
-	//TODO: VFNMSUB213SD (BX), X9, X11      // c462b1af1b
-	//TODO: VFNMSUB213SD (R11), X9, X11     // c442b1af1b
-	//TODO: VFNMSUB213SD X2, X9, X11        // c462b1afda
-	//TODO: VFNMSUB213SD X11, X9, X11       // c442b1afdb
-	//TODO: VFNMSUB213SS (BX), X9, X2       // c4e231af13
-	//TODO: VFNMSUB213SS (R11), X9, X2      // c4c231af13
-	//TODO: VFNMSUB213SS X2, X9, X2         // c4e231afd2
-	//TODO: VFNMSUB213SS X11, X9, X2        // c4c231afd3
-	//TODO: VFNMSUB213SS (BX), X9, X11      // c46231af1b
-	//TODO: VFNMSUB213SS (R11), X9, X11     // c44231af1b
-	//TODO: VFNMSUB213SS X2, X9, X11        // c46231afda
-	//TODO: VFNMSUB213SS X11, X9, X11       // c44231afdb
-	//TODO: VFNMSUB231PD (BX), X9, X2       // c4e2b1be13
-	//TODO: VFNMSUB231PD (R11), X9, X2      // c4c2b1be13
-	//TODO: VFNMSUB231PD X2, X9, X2         // c4e2b1bed2
-	//TODO: VFNMSUB231PD X11, X9, X2        // c4c2b1bed3
-	//TODO: VFNMSUB231PD (BX), X9, X11      // c462b1be1b
-	//TODO: VFNMSUB231PD (R11), X9, X11     // c442b1be1b
-	//TODO: VFNMSUB231PD X2, X9, X11        // c462b1beda
-	//TODO: VFNMSUB231PD X11, X9, X11       // c442b1bedb
-	//TODO: VFNMSUB231PD (BX), Y15, Y2      // c4e285be13
-	//TODO: VFNMSUB231PD (R11), Y15, Y2     // c4c285be13
-	//TODO: VFNMSUB231PD Y2, Y15, Y2        // c4e285bed2
-	//TODO: VFNMSUB231PD Y11, Y15, Y2       // c4c285bed3
-	//TODO: VFNMSUB231PD (BX), Y15, Y11     // c46285be1b
-	//TODO: VFNMSUB231PD (R11), Y15, Y11    // c44285be1b
-	//TODO: VFNMSUB231PD Y2, Y15, Y11       // c46285beda
-	//TODO: VFNMSUB231PD Y11, Y15, Y11      // c44285bedb
-	//TODO: VFNMSUB231PS (BX), X9, X2       // c4e231be13
-	//TODO: VFNMSUB231PS (R11), X9, X2      // c4c231be13
-	//TODO: VFNMSUB231PS X2, X9, X2         // c4e231bed2
-	//TODO: VFNMSUB231PS X11, X9, X2        // c4c231bed3
-	//TODO: VFNMSUB231PS (BX), X9, X11      // c46231be1b
-	//TODO: VFNMSUB231PS (R11), X9, X11     // c44231be1b
-	//TODO: VFNMSUB231PS X2, X9, X11        // c46231beda
-	//TODO: VFNMSUB231PS X11, X9, X11       // c44231bedb
-	//TODO: VFNMSUB231PS (BX), Y15, Y2      // c4e205be13
-	//TODO: VFNMSUB231PS (R11), Y15, Y2     // c4c205be13
-	//TODO: VFNMSUB231PS Y2, Y15, Y2        // c4e205bed2
-	//TODO: VFNMSUB231PS Y11, Y15, Y2       // c4c205bed3
-	//TODO: VFNMSUB231PS (BX), Y15, Y11     // c46205be1b
-	//TODO: VFNMSUB231PS (R11), Y15, Y11    // c44205be1b
-	//TODO: VFNMSUB231PS Y2, Y15, Y11       // c46205beda
-	//TODO: VFNMSUB231PS Y11, Y15, Y11      // c44205bedb
-	//TODO: VFNMSUB231SD (BX), X9, X2       // c4e2b1bf13
-	//TODO: VFNMSUB231SD (R11), X9, X2      // c4c2b1bf13
-	//TODO: VFNMSUB231SD X2, X9, X2         // c4e2b1bfd2
-	//TODO: VFNMSUB231SD X11, X9, X2        // c4c2b1bfd3
-	//TODO: VFNMSUB231SD (BX), X9, X11      // c462b1bf1b
-	//TODO: VFNMSUB231SD (R11), X9, X11     // c442b1bf1b
-	//TODO: VFNMSUB231SD X2, X9, X11        // c462b1bfda
-	//TODO: VFNMSUB231SD X11, X9, X11       // c442b1bfdb
-	//TODO: VFNMSUB231SS (BX), X9, X2       // c4e231bf13
-	//TODO: VFNMSUB231SS (R11), X9, X2      // c4c231bf13
-	//TODO: VFNMSUB231SS X2, X9, X2         // c4e231bfd2
-	//TODO: VFNMSUB231SS X11, X9, X2        // c4c231bfd3
-	//TODO: VFNMSUB231SS (BX), X9, X11      // c46231bf1b
-	//TODO: VFNMSUB231SS (R11), X9, X11     // c44231bf1b
-	//TODO: VFNMSUB231SS X2, X9, X11        // c46231bfda
-	//TODO: VFNMSUB231SS X11, X9, X11       // c44231bfdb
-	//TODO: VHADDPD (BX), X9, X2            // c4e1317c13 or c5b17c13
-	//TODO: VHADDPD (R11), X9, X2           // c4c1317c13
-	//TODO: VHADDPD X2, X9, X2              // c4e1317cd2 or c5b17cd2
-	//TODO: VHADDPD X11, X9, X2             // c4c1317cd3
-	//TODO: VHADDPD (BX), X9, X11           // c461317c1b or c5317c1b
-	//TODO: VHADDPD (R11), X9, X11          // c441317c1b
-	//TODO: VHADDPD X2, X9, X11             // c461317cda or c5317cda
-	//TODO: VHADDPD X11, X9, X11            // c441317cdb
-	//TODO: VHADDPD (BX), Y15, Y2           // c4e1057c13 or c5857c13
-	//TODO: VHADDPD (R11), Y15, Y2          // c4c1057c13
-	//TODO: VHADDPD Y2, Y15, Y2             // c4e1057cd2 or c5857cd2
-	//TODO: VHADDPD Y11, Y15, Y2            // c4c1057cd3
-	//TODO: VHADDPD (BX), Y15, Y11          // c461057c1b or c5057c1b
-	//TODO: VHADDPD (R11), Y15, Y11         // c441057c1b
-	//TODO: VHADDPD Y2, Y15, Y11            // c461057cda or c5057cda
-	//TODO: VHADDPD Y11, Y15, Y11           // c441057cdb
-	//TODO: VHADDPS (BX), X9, X2            // c4e1337c13 or c5b37c13
-	//TODO: VHADDPS (R11), X9, X2           // c4c1337c13
-	//TODO: VHADDPS X2, X9, X2              // c4e1337cd2 or c5b37cd2
-	//TODO: VHADDPS X11, X9, X2             // c4c1337cd3
-	//TODO: VHADDPS (BX), X9, X11           // c461337c1b or c5337c1b
-	//TODO: VHADDPS (R11), X9, X11          // c441337c1b
-	//TODO: VHADDPS X2, X9, X11             // c461337cda or c5337cda
-	//TODO: VHADDPS X11, X9, X11            // c441337cdb
-	//TODO: VHADDPS (BX), Y15, Y2           // c4e1077c13 or c5877c13
-	//TODO: VHADDPS (R11), Y15, Y2          // c4c1077c13
-	//TODO: VHADDPS Y2, Y15, Y2             // c4e1077cd2 or c5877cd2
-	//TODO: VHADDPS Y11, Y15, Y2            // c4c1077cd3
-	//TODO: VHADDPS (BX), Y15, Y11          // c461077c1b or c5077c1b
-	//TODO: VHADDPS (R11), Y15, Y11         // c441077c1b
-	//TODO: VHADDPS Y2, Y15, Y11            // c461077cda or c5077cda
-	//TODO: VHADDPS Y11, Y15, Y11           // c441077cdb
-	//TODO: VHSUBPD (BX), X9, X2            // c4e1317d13 or c5b17d13
-	//TODO: VHSUBPD (R11), X9, X2           // c4c1317d13
-	//TODO: VHSUBPD X2, X9, X2              // c4e1317dd2 or c5b17dd2
-	//TODO: VHSUBPD X11, X9, X2             // c4c1317dd3
-	//TODO: VHSUBPD (BX), X9, X11           // c461317d1b or c5317d1b
-	//TODO: VHSUBPD (R11), X9, X11          // c441317d1b
-	//TODO: VHSUBPD X2, X9, X11             // c461317dda or c5317dda
-	//TODO: VHSUBPD X11, X9, X11            // c441317ddb
-	//TODO: VHSUBPD (BX), Y15, Y2           // c4e1057d13 or c5857d13
-	//TODO: VHSUBPD (R11), Y15, Y2          // c4c1057d13
-	//TODO: VHSUBPD Y2, Y15, Y2             // c4e1057dd2 or c5857dd2
-	//TODO: VHSUBPD Y11, Y15, Y2            // c4c1057dd3
-	//TODO: VHSUBPD (BX), Y15, Y11          // c461057d1b or c5057d1b
-	//TODO: VHSUBPD (R11), Y15, Y11         // c441057d1b
-	//TODO: VHSUBPD Y2, Y15, Y11            // c461057dda or c5057dda
-	//TODO: VHSUBPD Y11, Y15, Y11           // c441057ddb
-	//TODO: VHSUBPS (BX), X9, X2            // c4e1337d13 or c5b37d13
-	//TODO: VHSUBPS (R11), X9, X2           // c4c1337d13
-	//TODO: VHSUBPS X2, X9, X2              // c4e1337dd2 or c5b37dd2
-	//TODO: VHSUBPS X11, X9, X2             // c4c1337dd3
-	//TODO: VHSUBPS (BX), X9, X11           // c461337d1b or c5337d1b
-	//TODO: VHSUBPS (R11), X9, X11          // c441337d1b
-	//TODO: VHSUBPS X2, X9, X11             // c461337dda or c5337dda
-	//TODO: VHSUBPS X11, X9, X11            // c441337ddb
-	//TODO: VHSUBPS (BX), Y15, Y2           // c4e1077d13 or c5877d13
-	//TODO: VHSUBPS (R11), Y15, Y2          // c4c1077d13
-	//TODO: VHSUBPS Y2, Y15, Y2             // c4e1077dd2 or c5877dd2
-	//TODO: VHSUBPS Y11, Y15, Y2            // c4c1077dd3
-	//TODO: VHSUBPS (BX), Y15, Y11          // c461077d1b or c5077d1b
-	//TODO: VHSUBPS (R11), Y15, Y11         // c441077d1b
-	//TODO: VHSUBPS Y2, Y15, Y11            // c461077dda or c5077dda
-	//TODO: VHSUBPS Y11, Y15, Y11           // c441077ddb
-	//TODO: VINSERTF128 $7, (BX), Y15, Y2   // c4e305181307
-	//TODO: VINSERTF128 $7, (R11), Y15, Y2  // c4c305181307
-	//TODO: VINSERTF128 $7, X2, Y15, Y2     // c4e30518d207
-	//TODO: VINSERTF128 $7, X11, Y15, Y2    // c4c30518d307
-	//TODO: VINSERTF128 $7, (BX), Y15, Y11  // c46305181b07
-	//TODO: VINSERTF128 $7, (R11), Y15, Y11 // c44305181b07
-	//TODO: VINSERTF128 $7, X2, Y15, Y11    // c4630518da07
-	//TODO: VINSERTF128 $7, X11, Y15, Y11   // c4430518db07
+	VEXTRACTF128 $7, Y2, (BX)               // c4e37d191307
+	VEXTRACTF128 $7, Y11, (BX)              // c4637d191b07
+	VEXTRACTF128 $7, Y2, (R11)              // c4c37d191307
+	VEXTRACTF128 $7, Y11, (R11)             // c4437d191b07
+	VEXTRACTF128 $7, Y2, X2                 // c4e37d19d207
+	VEXTRACTF128 $7, Y11, X2                // c4637d19da07
+	VEXTRACTF128 $7, Y2, X11                // c4c37d19d307
+	VEXTRACTF128 $7, Y11, X11               // c4437d19db07
+	VEXTRACTI128 $7, Y2, (BX)               // c4e37d391307
+	VEXTRACTI128 $7, Y11, (BX)              // c4637d391b07
+	VEXTRACTI128 $7, Y2, (R11)              // c4c37d391307
+	VEXTRACTI128 $7, Y11, (R11)             // c4437d391b07
+	VEXTRACTI128 $7, Y2, X2                 // c4e37d39d207
+	VEXTRACTI128 $7, Y11, X2                // c4637d39da07
+	VEXTRACTI128 $7, Y2, X11                // c4c37d39d307
+	VEXTRACTI128 $7, Y11, X11               // c4437d39db07
+	VEXTRACTPS $7, X2, (BX)                 // c4e379171307
+	VEXTRACTPS $7, X11, (BX)                // c46379171b07
+	VEXTRACTPS $7, X2, (R11)                // c4c379171307
+	VEXTRACTPS $7, X11, (R11)               // c44379171b07
+	VEXTRACTPS $7, X2, DX                   // c4e37917d207
+	VEXTRACTPS $7, X11, DX                  // c4637917da07
+	VEXTRACTPS $7, X2, R11                  // c4c37917d307
+	VEXTRACTPS $7, X11, R11                 // c4437917db07
+	VFMADD132PD (BX), X9, X2                // c4e2b19813
+	VFMADD132PD (R11), X9, X2               // c4c2b19813
+	VFMADD132PD X2, X9, X2                  // c4e2b198d2
+	VFMADD132PD X11, X9, X2                 // c4c2b198d3
+	VFMADD132PD (BX), X9, X11               // c462b1981b
+	VFMADD132PD (R11), X9, X11              // c442b1981b
+	VFMADD132PD X2, X9, X11                 // c462b198da
+	VFMADD132PD X11, X9, X11                // c442b198db
+	VFMADD132PD (BX), Y15, Y2               // c4e2859813
+	VFMADD132PD (R11), Y15, Y2              // c4c2859813
+	VFMADD132PD Y2, Y15, Y2                 // c4e28598d2
+	VFMADD132PD Y11, Y15, Y2                // c4c28598d3
+	VFMADD132PD (BX), Y15, Y11              // c46285981b
+	VFMADD132PD (R11), Y15, Y11             // c44285981b
+	VFMADD132PD Y2, Y15, Y11                // c4628598da
+	VFMADD132PD Y11, Y15, Y11               // c4428598db
+	VFMADD132PS (BX), X9, X2                // c4e2319813
+	VFMADD132PS (R11), X9, X2               // c4c2319813
+	VFMADD132PS X2, X9, X2                  // c4e23198d2
+	VFMADD132PS X11, X9, X2                 // c4c23198d3
+	VFMADD132PS (BX), X9, X11               // c46231981b
+	VFMADD132PS (R11), X9, X11              // c44231981b
+	VFMADD132PS X2, X9, X11                 // c4623198da
+	VFMADD132PS X11, X9, X11                // c4423198db
+	VFMADD132PS (BX), Y15, Y2               // c4e2059813
+	VFMADD132PS (R11), Y15, Y2              // c4c2059813
+	VFMADD132PS Y2, Y15, Y2                 // c4e20598d2
+	VFMADD132PS Y11, Y15, Y2                // c4c20598d3
+	VFMADD132PS (BX), Y15, Y11              // c46205981b
+	VFMADD132PS (R11), Y15, Y11             // c44205981b
+	VFMADD132PS Y2, Y15, Y11                // c4620598da
+	VFMADD132PS Y11, Y15, Y11               // c4420598db
+	VFMADD132SD (BX), X9, X2                // c4e2b19913
+	VFMADD132SD (R11), X9, X2               // c4c2b19913
+	VFMADD132SD X2, X9, X2                  // c4e2b199d2
+	VFMADD132SD X11, X9, X2                 // c4c2b199d3
+	VFMADD132SD (BX), X9, X11               // c462b1991b
+	VFMADD132SD (R11), X9, X11              // c442b1991b
+	VFMADD132SD X2, X9, X11                 // c462b199da
+	VFMADD132SD X11, X9, X11                // c442b199db
+	VFMADD132SS (BX), X9, X2                // c4e2319913
+	VFMADD132SS (R11), X9, X2               // c4c2319913
+	VFMADD132SS X2, X9, X2                  // c4e23199d2
+	VFMADD132SS X11, X9, X2                 // c4c23199d3
+	VFMADD132SS (BX), X9, X11               // c46231991b
+	VFMADD132SS (R11), X9, X11              // c44231991b
+	VFMADD132SS X2, X9, X11                 // c4623199da
+	VFMADD132SS X11, X9, X11                // c4423199db
+	VFMADD213PD (BX), X9, X2                // c4e2b1a813
+	VFMADD213PD (R11), X9, X2               // c4c2b1a813
+	VFMADD213PD X2, X9, X2                  // c4e2b1a8d2
+	VFMADD213PD X11, X9, X2                 // c4c2b1a8d3
+	VFMADD213PD (BX), X9, X11               // c462b1a81b
+	VFMADD213PD (R11), X9, X11              // c442b1a81b
+	VFMADD213PD X2, X9, X11                 // c462b1a8da
+	VFMADD213PD X11, X9, X11                // c442b1a8db
+	VFMADD213PD (BX), Y15, Y2               // c4e285a813
+	VFMADD213PD (R11), Y15, Y2              // c4c285a813
+	VFMADD213PD Y2, Y15, Y2                 // c4e285a8d2
+	VFMADD213PD Y11, Y15, Y2                // c4c285a8d3
+	VFMADD213PD (BX), Y15, Y11              // c46285a81b
+	VFMADD213PD (R11), Y15, Y11             // c44285a81b
+	VFMADD213PD Y2, Y15, Y11                // c46285a8da
+	VFMADD213PD Y11, Y15, Y11               // c44285a8db
+	VFMADD213PS (BX), X9, X2                // c4e231a813
+	VFMADD213PS (R11), X9, X2               // c4c231a813
+	VFMADD213PS X2, X9, X2                  // c4e231a8d2
+	VFMADD213PS X11, X9, X2                 // c4c231a8d3
+	VFMADD213PS (BX), X9, X11               // c46231a81b
+	VFMADD213PS (R11), X9, X11              // c44231a81b
+	VFMADD213PS X2, X9, X11                 // c46231a8da
+	VFMADD213PS X11, X9, X11                // c44231a8db
+	VFMADD213PS (BX), Y15, Y2               // c4e205a813
+	VFMADD213PS (R11), Y15, Y2              // c4c205a813
+	VFMADD213PS Y2, Y15, Y2                 // c4e205a8d2
+	VFMADD213PS Y11, Y15, Y2                // c4c205a8d3
+	VFMADD213PS (BX), Y15, Y11              // c46205a81b
+	VFMADD213PS (R11), Y15, Y11             // c44205a81b
+	VFMADD213PS Y2, Y15, Y11                // c46205a8da
+	VFMADD213PS Y11, Y15, Y11               // c44205a8db
+	VFMADD213SD (BX), X9, X2                // c4e2b1a913
+	VFMADD213SD (R11), X9, X2               // c4c2b1a913
+	VFMADD213SD X2, X9, X2                  // c4e2b1a9d2
+	VFMADD213SD X11, X9, X2                 // c4c2b1a9d3
+	VFMADD213SD (BX), X9, X11               // c462b1a91b
+	VFMADD213SD (R11), X9, X11              // c442b1a91b
+	VFMADD213SD X2, X9, X11                 // c462b1a9da
+	VFMADD213SD X11, X9, X11                // c442b1a9db
+	VFMADD213SS (BX), X9, X2                // c4e231a913
+	VFMADD213SS (R11), X9, X2               // c4c231a913
+	VFMADD213SS X2, X9, X2                  // c4e231a9d2
+	VFMADD213SS X11, X9, X2                 // c4c231a9d3
+	VFMADD213SS (BX), X9, X11               // c46231a91b
+	VFMADD213SS (R11), X9, X11              // c44231a91b
+	VFMADD213SS X2, X9, X11                 // c46231a9da
+	VFMADD213SS X11, X9, X11                // c44231a9db
+	VFMADD231PD (BX), X9, X2                // c4e2b1b813
+	VFMADD231PD (R11), X9, X2               // c4c2b1b813
+	VFMADD231PD X2, X9, X2                  // c4e2b1b8d2
+	VFMADD231PD X11, X9, X2                 // c4c2b1b8d3
+	VFMADD231PD (BX), X9, X11               // c462b1b81b
+	VFMADD231PD (R11), X9, X11              // c442b1b81b
+	VFMADD231PD X2, X9, X11                 // c462b1b8da
+	VFMADD231PD X11, X9, X11                // c442b1b8db
+	VFMADD231PD (BX), Y15, Y2               // c4e285b813
+	VFMADD231PD (R11), Y15, Y2              // c4c285b813
+	VFMADD231PD Y2, Y15, Y2                 // c4e285b8d2
+	VFMADD231PD Y11, Y15, Y2                // c4c285b8d3
+	VFMADD231PD (BX), Y15, Y11              // c46285b81b
+	VFMADD231PD (R11), Y15, Y11             // c44285b81b
+	VFMADD231PD Y2, Y15, Y11                // c46285b8da
+	VFMADD231PD Y11, Y15, Y11               // c44285b8db
+	VFMADD231PS (BX), X9, X2                // c4e231b813
+	VFMADD231PS (R11), X9, X2               // c4c231b813
+	VFMADD231PS X2, X9, X2                  // c4e231b8d2
+	VFMADD231PS X11, X9, X2                 // c4c231b8d3
+	VFMADD231PS (BX), X9, X11               // c46231b81b
+	VFMADD231PS (R11), X9, X11              // c44231b81b
+	VFMADD231PS X2, X9, X11                 // c46231b8da
+	VFMADD231PS X11, X9, X11                // c44231b8db
+	VFMADD231PS (BX), Y15, Y2               // c4e205b813
+	VFMADD231PS (R11), Y15, Y2              // c4c205b813
+	VFMADD231PS Y2, Y15, Y2                 // c4e205b8d2
+	VFMADD231PS Y11, Y15, Y2                // c4c205b8d3
+	VFMADD231PS (BX), Y15, Y11              // c46205b81b
+	VFMADD231PS (R11), Y15, Y11             // c44205b81b
+	VFMADD231PS Y2, Y15, Y11                // c46205b8da
+	VFMADD231PS Y11, Y15, Y11               // c44205b8db
+	VFMADD231SD (BX), X9, X2                // c4e2b1b913
+	VFMADD231SD (R11), X9, X2               // c4c2b1b913
+	VFMADD231SD X2, X9, X2                  // c4e2b1b9d2
+	VFMADD231SD X11, X9, X2                 // c4c2b1b9d3
+	VFMADD231SD (BX), X9, X11               // c462b1b91b
+	VFMADD231SD (R11), X9, X11              // c442b1b91b
+	VFMADD231SD X2, X9, X11                 // c462b1b9da
+	VFMADD231SD X11, X9, X11                // c442b1b9db
+	VFMADD231SS (BX), X9, X2                // c4e231b913
+	VFMADD231SS (R11), X9, X2               // c4c231b913
+	VFMADD231SS X2, X9, X2                  // c4e231b9d2
+	VFMADD231SS X11, X9, X2                 // c4c231b9d3
+	VFMADD231SS (BX), X9, X11               // c46231b91b
+	VFMADD231SS (R11), X9, X11              // c44231b91b
+	VFMADD231SS X2, X9, X11                 // c46231b9da
+	VFMADD231SS X11, X9, X11                // c44231b9db
+	VFMADDSUB132PD (BX), X9, X2             // c4e2b19613
+	VFMADDSUB132PD (R11), X9, X2            // c4c2b19613
+	VFMADDSUB132PD X2, X9, X2               // c4e2b196d2
+	VFMADDSUB132PD X11, X9, X2              // c4c2b196d3
+	VFMADDSUB132PD (BX), X9, X11            // c462b1961b
+	VFMADDSUB132PD (R11), X9, X11           // c442b1961b
+	VFMADDSUB132PD X2, X9, X11              // c462b196da
+	VFMADDSUB132PD X11, X9, X11             // c442b196db
+	VFMADDSUB132PD (BX), Y15, Y2            // c4e2859613
+	VFMADDSUB132PD (R11), Y15, Y2           // c4c2859613
+	VFMADDSUB132PD Y2, Y15, Y2              // c4e28596d2
+	VFMADDSUB132PD Y11, Y15, Y2             // c4c28596d3
+	VFMADDSUB132PD (BX), Y15, Y11           // c46285961b
+	VFMADDSUB132PD (R11), Y15, Y11          // c44285961b
+	VFMADDSUB132PD Y2, Y15, Y11             // c4628596da
+	VFMADDSUB132PD Y11, Y15, Y11            // c4428596db
+	VFMADDSUB132PS (BX), X9, X2             // c4e2319613
+	VFMADDSUB132PS (R11), X9, X2            // c4c2319613
+	VFMADDSUB132PS X2, X9, X2               // c4e23196d2
+	VFMADDSUB132PS X11, X9, X2              // c4c23196d3
+	VFMADDSUB132PS (BX), X9, X11            // c46231961b
+	VFMADDSUB132PS (R11), X9, X11           // c44231961b
+	VFMADDSUB132PS X2, X9, X11              // c4623196da
+	VFMADDSUB132PS X11, X9, X11             // c4423196db
+	VFMADDSUB132PS (BX), Y15, Y2            // c4e2059613
+	VFMADDSUB132PS (R11), Y15, Y2           // c4c2059613
+	VFMADDSUB132PS Y2, Y15, Y2              // c4e20596d2
+	VFMADDSUB132PS Y11, Y15, Y2             // c4c20596d3
+	VFMADDSUB132PS (BX), Y15, Y11           // c46205961b
+	VFMADDSUB132PS (R11), Y15, Y11          // c44205961b
+	VFMADDSUB132PS Y2, Y15, Y11             // c4620596da
+	VFMADDSUB132PS Y11, Y15, Y11            // c4420596db
+	VFMADDSUB213PD (BX), X9, X2             // c4e2b1a613
+	VFMADDSUB213PD (R11), X9, X2            // c4c2b1a613
+	VFMADDSUB213PD X2, X9, X2               // c4e2b1a6d2
+	VFMADDSUB213PD X11, X9, X2              // c4c2b1a6d3
+	VFMADDSUB213PD (BX), X9, X11            // c462b1a61b
+	VFMADDSUB213PD (R11), X9, X11           // c442b1a61b
+	VFMADDSUB213PD X2, X9, X11              // c462b1a6da
+	VFMADDSUB213PD X11, X9, X11             // c442b1a6db
+	VFMADDSUB213PD (BX), Y15, Y2            // c4e285a613
+	VFMADDSUB213PD (R11), Y15, Y2           // c4c285a613
+	VFMADDSUB213PD Y2, Y15, Y2              // c4e285a6d2
+	VFMADDSUB213PD Y11, Y15, Y2             // c4c285a6d3
+	VFMADDSUB213PD (BX), Y15, Y11           // c46285a61b
+	VFMADDSUB213PD (R11), Y15, Y11          // c44285a61b
+	VFMADDSUB213PD Y2, Y15, Y11             // c46285a6da
+	VFMADDSUB213PD Y11, Y15, Y11            // c44285a6db
+	VFMADDSUB213PS (BX), X9, X2             // c4e231a613
+	VFMADDSUB213PS (R11), X9, X2            // c4c231a613
+	VFMADDSUB213PS X2, X9, X2               // c4e231a6d2
+	VFMADDSUB213PS X11, X9, X2              // c4c231a6d3
+	VFMADDSUB213PS (BX), X9, X11            // c46231a61b
+	VFMADDSUB213PS (R11), X9, X11           // c44231a61b
+	VFMADDSUB213PS X2, X9, X11              // c46231a6da
+	VFMADDSUB213PS X11, X9, X11             // c44231a6db
+	VFMADDSUB213PS (BX), Y15, Y2            // c4e205a613
+	VFMADDSUB213PS (R11), Y15, Y2           // c4c205a613
+	VFMADDSUB213PS Y2, Y15, Y2              // c4e205a6d2
+	VFMADDSUB213PS Y11, Y15, Y2             // c4c205a6d3
+	VFMADDSUB213PS (BX), Y15, Y11           // c46205a61b
+	VFMADDSUB213PS (R11), Y15, Y11          // c44205a61b
+	VFMADDSUB213PS Y2, Y15, Y11             // c46205a6da
+	VFMADDSUB213PS Y11, Y15, Y11            // c44205a6db
+	VFMADDSUB231PD (BX), X9, X2             // c4e2b1b613
+	VFMADDSUB231PD (R11), X9, X2            // c4c2b1b613
+	VFMADDSUB231PD X2, X9, X2               // c4e2b1b6d2
+	VFMADDSUB231PD X11, X9, X2              // c4c2b1b6d3
+	VFMADDSUB231PD (BX), X9, X11            // c462b1b61b
+	VFMADDSUB231PD (R11), X9, X11           // c442b1b61b
+	VFMADDSUB231PD X2, X9, X11              // c462b1b6da
+	VFMADDSUB231PD X11, X9, X11             // c442b1b6db
+	VFMADDSUB231PD (BX), Y15, Y2            // c4e285b613
+	VFMADDSUB231PD (R11), Y15, Y2           // c4c285b613
+	VFMADDSUB231PD Y2, Y15, Y2              // c4e285b6d2
+	VFMADDSUB231PD Y11, Y15, Y2             // c4c285b6d3
+	VFMADDSUB231PD (BX), Y15, Y11           // c46285b61b
+	VFMADDSUB231PD (R11), Y15, Y11          // c44285b61b
+	VFMADDSUB231PD Y2, Y15, Y11             // c46285b6da
+	VFMADDSUB231PD Y11, Y15, Y11            // c44285b6db
+	VFMADDSUB231PS (BX), X9, X2             // c4e231b613
+	VFMADDSUB231PS (R11), X9, X2            // c4c231b613
+	VFMADDSUB231PS X2, X9, X2               // c4e231b6d2
+	VFMADDSUB231PS X11, X9, X2              // c4c231b6d3
+	VFMADDSUB231PS (BX), X9, X11            // c46231b61b
+	VFMADDSUB231PS (R11), X9, X11           // c44231b61b
+	VFMADDSUB231PS X2, X9, X11              // c46231b6da
+	VFMADDSUB231PS X11, X9, X11             // c44231b6db
+	VFMADDSUB231PS (BX), Y15, Y2            // c4e205b613
+	VFMADDSUB231PS (R11), Y15, Y2           // c4c205b613
+	VFMADDSUB231PS Y2, Y15, Y2              // c4e205b6d2
+	VFMADDSUB231PS Y11, Y15, Y2             // c4c205b6d3
+	VFMADDSUB231PS (BX), Y15, Y11           // c46205b61b
+	VFMADDSUB231PS (R11), Y15, Y11          // c44205b61b
+	VFMADDSUB231PS Y2, Y15, Y11             // c46205b6da
+	VFMADDSUB231PS Y11, Y15, Y11            // c44205b6db
+	VFMSUB132PD (BX), X9, X2                // c4e2b19a13
+	VFMSUB132PD (R11), X9, X2               // c4c2b19a13
+	VFMSUB132PD X2, X9, X2                  // c4e2b19ad2
+	VFMSUB132PD X11, X9, X2                 // c4c2b19ad3
+	VFMSUB132PD (BX), X9, X11               // c462b19a1b
+	VFMSUB132PD (R11), X9, X11              // c442b19a1b
+	VFMSUB132PD X2, X9, X11                 // c462b19ada
+	VFMSUB132PD X11, X9, X11                // c442b19adb
+	VFMSUB132PD (BX), Y15, Y2               // c4e2859a13
+	VFMSUB132PD (R11), Y15, Y2              // c4c2859a13
+	VFMSUB132PD Y2, Y15, Y2                 // c4e2859ad2
+	VFMSUB132PD Y11, Y15, Y2                // c4c2859ad3
+	VFMSUB132PD (BX), Y15, Y11              // c462859a1b
+	VFMSUB132PD (R11), Y15, Y11             // c442859a1b
+	VFMSUB132PD Y2, Y15, Y11                // c462859ada
+	VFMSUB132PD Y11, Y15, Y11               // c442859adb
+	VFMSUB132PS (BX), X9, X2                // c4e2319a13
+	VFMSUB132PS (R11), X9, X2               // c4c2319a13
+	VFMSUB132PS X2, X9, X2                  // c4e2319ad2
+	VFMSUB132PS X11, X9, X2                 // c4c2319ad3
+	VFMSUB132PS (BX), X9, X11               // c462319a1b
+	VFMSUB132PS (R11), X9, X11              // c442319a1b
+	VFMSUB132PS X2, X9, X11                 // c462319ada
+	VFMSUB132PS X11, X9, X11                // c442319adb
+	VFMSUB132PS (BX), Y15, Y2               // c4e2059a13
+	VFMSUB132PS (R11), Y15, Y2              // c4c2059a13
+	VFMSUB132PS Y2, Y15, Y2                 // c4e2059ad2
+	VFMSUB132PS Y11, Y15, Y2                // c4c2059ad3
+	VFMSUB132PS (BX), Y15, Y11              // c462059a1b
+	VFMSUB132PS (R11), Y15, Y11             // c442059a1b
+	VFMSUB132PS Y2, Y15, Y11                // c462059ada
+	VFMSUB132PS Y11, Y15, Y11               // c442059adb
+	VFMSUB132SD (BX), X9, X2                // c4e2b19b13
+	VFMSUB132SD (R11), X9, X2               // c4c2b19b13
+	VFMSUB132SD X2, X9, X2                  // c4e2b19bd2
+	VFMSUB132SD X11, X9, X2                 // c4c2b19bd3
+	VFMSUB132SD (BX), X9, X11               // c462b19b1b
+	VFMSUB132SD (R11), X9, X11              // c442b19b1b
+	VFMSUB132SD X2, X9, X11                 // c462b19bda
+	VFMSUB132SD X11, X9, X11                // c442b19bdb
+	VFMSUB132SS (BX), X9, X2                // c4e2319b13
+	VFMSUB132SS (R11), X9, X2               // c4c2319b13
+	VFMSUB132SS X2, X9, X2                  // c4e2319bd2
+	VFMSUB132SS X11, X9, X2                 // c4c2319bd3
+	VFMSUB132SS (BX), X9, X11               // c462319b1b
+	VFMSUB132SS (R11), X9, X11              // c442319b1b
+	VFMSUB132SS X2, X9, X11                 // c462319bda
+	VFMSUB132SS X11, X9, X11                // c442319bdb
+	VFMSUB213PD (BX), X9, X2                // c4e2b1aa13
+	VFMSUB213PD (R11), X9, X2               // c4c2b1aa13
+	VFMSUB213PD X2, X9, X2                  // c4e2b1aad2
+	VFMSUB213PD X11, X9, X2                 // c4c2b1aad3
+	VFMSUB213PD (BX), X9, X11               // c462b1aa1b
+	VFMSUB213PD (R11), X9, X11              // c442b1aa1b
+	VFMSUB213PD X2, X9, X11                 // c462b1aada
+	VFMSUB213PD X11, X9, X11                // c442b1aadb
+	VFMSUB213PD (BX), Y15, Y2               // c4e285aa13
+	VFMSUB213PD (R11), Y15, Y2              // c4c285aa13
+	VFMSUB213PD Y2, Y15, Y2                 // c4e285aad2
+	VFMSUB213PD Y11, Y15, Y2                // c4c285aad3
+	VFMSUB213PD (BX), Y15, Y11              // c46285aa1b
+	VFMSUB213PD (R11), Y15, Y11             // c44285aa1b
+	VFMSUB213PD Y2, Y15, Y11                // c46285aada
+	VFMSUB213PD Y11, Y15, Y11               // c44285aadb
+	VFMSUB213PS (BX), X9, X2                // c4e231aa13
+	VFMSUB213PS (R11), X9, X2               // c4c231aa13
+	VFMSUB213PS X2, X9, X2                  // c4e231aad2
+	VFMSUB213PS X11, X9, X2                 // c4c231aad3
+	VFMSUB213PS (BX), X9, X11               // c46231aa1b
+	VFMSUB213PS (R11), X9, X11              // c44231aa1b
+	VFMSUB213PS X2, X9, X11                 // c46231aada
+	VFMSUB213PS X11, X9, X11                // c44231aadb
+	VFMSUB213PS (BX), Y15, Y2               // c4e205aa13
+	VFMSUB213PS (R11), Y15, Y2              // c4c205aa13
+	VFMSUB213PS Y2, Y15, Y2                 // c4e205aad2
+	VFMSUB213PS Y11, Y15, Y2                // c4c205aad3
+	VFMSUB213PS (BX), Y15, Y11              // c46205aa1b
+	VFMSUB213PS (R11), Y15, Y11             // c44205aa1b
+	VFMSUB213PS Y2, Y15, Y11                // c46205aada
+	VFMSUB213PS Y11, Y15, Y11               // c44205aadb
+	VFMSUB213SD (BX), X9, X2                // c4e2b1ab13
+	VFMSUB213SD (R11), X9, X2               // c4c2b1ab13
+	VFMSUB213SD X2, X9, X2                  // c4e2b1abd2
+	VFMSUB213SD X11, X9, X2                 // c4c2b1abd3
+	VFMSUB213SD (BX), X9, X11               // c462b1ab1b
+	VFMSUB213SD (R11), X9, X11              // c442b1ab1b
+	VFMSUB213SD X2, X9, X11                 // c462b1abda
+	VFMSUB213SD X11, X9, X11                // c442b1abdb
+	VFMSUB213SS (BX), X9, X2                // c4e231ab13
+	VFMSUB213SS (R11), X9, X2               // c4c231ab13
+	VFMSUB213SS X2, X9, X2                  // c4e231abd2
+	VFMSUB213SS X11, X9, X2                 // c4c231abd3
+	VFMSUB213SS (BX), X9, X11               // c46231ab1b
+	VFMSUB213SS (R11), X9, X11              // c44231ab1b
+	VFMSUB213SS X2, X9, X11                 // c46231abda
+	VFMSUB213SS X11, X9, X11                // c44231abdb
+	VFMSUB231PD (BX), X9, X2                // c4e2b1ba13
+	VFMSUB231PD (R11), X9, X2               // c4c2b1ba13
+	VFMSUB231PD X2, X9, X2                  // c4e2b1bad2
+	VFMSUB231PD X11, X9, X2                 // c4c2b1bad3
+	VFMSUB231PD (BX), X9, X11               // c462b1ba1b
+	VFMSUB231PD (R11), X9, X11              // c442b1ba1b
+	VFMSUB231PD X2, X9, X11                 // c462b1bada
+	VFMSUB231PD X11, X9, X11                // c442b1badb
+	VFMSUB231PD (BX), Y15, Y2               // c4e285ba13
+	VFMSUB231PD (R11), Y15, Y2              // c4c285ba13
+	VFMSUB231PD Y2, Y15, Y2                 // c4e285bad2
+	VFMSUB231PD Y11, Y15, Y2                // c4c285bad3
+	VFMSUB231PD (BX), Y15, Y11              // c46285ba1b
+	VFMSUB231PD (R11), Y15, Y11             // c44285ba1b
+	VFMSUB231PD Y2, Y15, Y11                // c46285bada
+	VFMSUB231PD Y11, Y15, Y11               // c44285badb
+	VFMSUB231PS (BX), X9, X2                // c4e231ba13
+	VFMSUB231PS (R11), X9, X2               // c4c231ba13
+	VFMSUB231PS X2, X9, X2                  // c4e231bad2
+	VFMSUB231PS X11, X9, X2                 // c4c231bad3
+	VFMSUB231PS (BX), X9, X11               // c46231ba1b
+	VFMSUB231PS (R11), X9, X11              // c44231ba1b
+	VFMSUB231PS X2, X9, X11                 // c46231bada
+	VFMSUB231PS X11, X9, X11                // c44231badb
+	VFMSUB231PS (BX), Y15, Y2               // c4e205ba13
+	VFMSUB231PS (R11), Y15, Y2              // c4c205ba13
+	VFMSUB231PS Y2, Y15, Y2                 // c4e205bad2
+	VFMSUB231PS Y11, Y15, Y2                // c4c205bad3
+	VFMSUB231PS (BX), Y15, Y11              // c46205ba1b
+	VFMSUB231PS (R11), Y15, Y11             // c44205ba1b
+	VFMSUB231PS Y2, Y15, Y11                // c46205bada
+	VFMSUB231PS Y11, Y15, Y11               // c44205badb
+	VFMSUB231SD (BX), X9, X2                // c4e2b1bb13
+	VFMSUB231SD (R11), X9, X2               // c4c2b1bb13
+	VFMSUB231SD X2, X9, X2                  // c4e2b1bbd2
+	VFMSUB231SD X11, X9, X2                 // c4c2b1bbd3
+	VFMSUB231SD (BX), X9, X11               // c462b1bb1b
+	VFMSUB231SD (R11), X9, X11              // c442b1bb1b
+	VFMSUB231SD X2, X9, X11                 // c462b1bbda
+	VFMSUB231SD X11, X9, X11                // c442b1bbdb
+	VFMSUB231SS (BX), X9, X2                // c4e231bb13
+	VFMSUB231SS (R11), X9, X2               // c4c231bb13
+	VFMSUB231SS X2, X9, X2                  // c4e231bbd2
+	VFMSUB231SS X11, X9, X2                 // c4c231bbd3
+	VFMSUB231SS (BX), X9, X11               // c46231bb1b
+	VFMSUB231SS (R11), X9, X11              // c44231bb1b
+	VFMSUB231SS X2, X9, X11                 // c46231bbda
+	VFMSUB231SS X11, X9, X11                // c44231bbdb
+	VFMSUBADD132PD (BX), X9, X2             // c4e2b19713
+	VFMSUBADD132PD (R11), X9, X2            // c4c2b19713
+	VFMSUBADD132PD X2, X9, X2               // c4e2b197d2
+	VFMSUBADD132PD X11, X9, X2              // c4c2b197d3
+	VFMSUBADD132PD (BX), X9, X11            // c462b1971b
+	VFMSUBADD132PD (R11), X9, X11           // c442b1971b
+	VFMSUBADD132PD X2, X9, X11              // c462b197da
+	VFMSUBADD132PD X11, X9, X11             // c442b197db
+	VFMSUBADD132PD (BX), Y15, Y2            // c4e2859713
+	VFMSUBADD132PD (R11), Y15, Y2           // c4c2859713
+	VFMSUBADD132PD Y2, Y15, Y2              // c4e28597d2
+	VFMSUBADD132PD Y11, Y15, Y2             // c4c28597d3
+	VFMSUBADD132PD (BX), Y15, Y11           // c46285971b
+	VFMSUBADD132PD (R11), Y15, Y11          // c44285971b
+	VFMSUBADD132PD Y2, Y15, Y11             // c4628597da
+	VFMSUBADD132PD Y11, Y15, Y11            // c4428597db
+	VFMSUBADD132PS (BX), X9, X2             // c4e2319713
+	VFMSUBADD132PS (R11), X9, X2            // c4c2319713
+	VFMSUBADD132PS X2, X9, X2               // c4e23197d2
+	VFMSUBADD132PS X11, X9, X2              // c4c23197d3
+	VFMSUBADD132PS (BX), X9, X11            // c46231971b
+	VFMSUBADD132PS (R11), X9, X11           // c44231971b
+	VFMSUBADD132PS X2, X9, X11              // c4623197da
+	VFMSUBADD132PS X11, X9, X11             // c4423197db
+	VFMSUBADD132PS (BX), Y15, Y2            // c4e2059713
+	VFMSUBADD132PS (R11), Y15, Y2           // c4c2059713
+	VFMSUBADD132PS Y2, Y15, Y2              // c4e20597d2
+	VFMSUBADD132PS Y11, Y15, Y2             // c4c20597d3
+	VFMSUBADD132PS (BX), Y15, Y11           // c46205971b
+	VFMSUBADD132PS (R11), Y15, Y11          // c44205971b
+	VFMSUBADD132PS Y2, Y15, Y11             // c4620597da
+	VFMSUBADD132PS Y11, Y15, Y11            // c4420597db
+	VFMSUBADD213PD (BX), X9, X2             // c4e2b1a713
+	VFMSUBADD213PD (R11), X9, X2            // c4c2b1a713
+	VFMSUBADD213PD X2, X9, X2               // c4e2b1a7d2
+	VFMSUBADD213PD X11, X9, X2              // c4c2b1a7d3
+	VFMSUBADD213PD (BX), X9, X11            // c462b1a71b
+	VFMSUBADD213PD (R11), X9, X11           // c442b1a71b
+	VFMSUBADD213PD X2, X9, X11              // c462b1a7da
+	VFMSUBADD213PD X11, X9, X11             // c442b1a7db
+	VFMSUBADD213PD (BX), Y15, Y2            // c4e285a713
+	VFMSUBADD213PD (R11), Y15, Y2           // c4c285a713
+	VFMSUBADD213PD Y2, Y15, Y2              // c4e285a7d2
+	VFMSUBADD213PD Y11, Y15, Y2             // c4c285a7d3
+	VFMSUBADD213PD (BX), Y15, Y11           // c46285a71b
+	VFMSUBADD213PD (R11), Y15, Y11          // c44285a71b
+	VFMSUBADD213PD Y2, Y15, Y11             // c46285a7da
+	VFMSUBADD213PD Y11, Y15, Y11            // c44285a7db
+	VFMSUBADD213PS (BX), X9, X2             // c4e231a713
+	VFMSUBADD213PS (R11), X9, X2            // c4c231a713
+	VFMSUBADD213PS X2, X9, X2               // c4e231a7d2
+	VFMSUBADD213PS X11, X9, X2              // c4c231a7d3
+	VFMSUBADD213PS (BX), X9, X11            // c46231a71b
+	VFMSUBADD213PS (R11), X9, X11           // c44231a71b
+	VFMSUBADD213PS X2, X9, X11              // c46231a7da
+	VFMSUBADD213PS X11, X9, X11             // c44231a7db
+	VFMSUBADD213PS (BX), Y15, Y2            // c4e205a713
+	VFMSUBADD213PS (R11), Y15, Y2           // c4c205a713
+	VFMSUBADD213PS Y2, Y15, Y2              // c4e205a7d2
+	VFMSUBADD213PS Y11, Y15, Y2             // c4c205a7d3
+	VFMSUBADD213PS (BX), Y15, Y11           // c46205a71b
+	VFMSUBADD213PS (R11), Y15, Y11          // c44205a71b
+	VFMSUBADD213PS Y2, Y15, Y11             // c46205a7da
+	VFMSUBADD213PS Y11, Y15, Y11            // c44205a7db
+	VFMSUBADD231PD (BX), X9, X2             // c4e2b1b713
+	VFMSUBADD231PD (R11), X9, X2            // c4c2b1b713
+	VFMSUBADD231PD X2, X9, X2               // c4e2b1b7d2
+	VFMSUBADD231PD X11, X9, X2              // c4c2b1b7d3
+	VFMSUBADD231PD (BX), X9, X11            // c462b1b71b
+	VFMSUBADD231PD (R11), X9, X11           // c442b1b71b
+	VFMSUBADD231PD X2, X9, X11              // c462b1b7da
+	VFMSUBADD231PD X11, X9, X11             // c442b1b7db
+	VFMSUBADD231PD (BX), Y15, Y2            // c4e285b713
+	VFMSUBADD231PD (R11), Y15, Y2           // c4c285b713
+	VFMSUBADD231PD Y2, Y15, Y2              // c4e285b7d2
+	VFMSUBADD231PD Y11, Y15, Y2             // c4c285b7d3
+	VFMSUBADD231PD (BX), Y15, Y11           // c46285b71b
+	VFMSUBADD231PD (R11), Y15, Y11          // c44285b71b
+	VFMSUBADD231PD Y2, Y15, Y11             // c46285b7da
+	VFMSUBADD231PD Y11, Y15, Y11            // c44285b7db
+	VFMSUBADD231PS (BX), X9, X2             // c4e231b713
+	VFMSUBADD231PS (R11), X9, X2            // c4c231b713
+	VFMSUBADD231PS X2, X9, X2               // c4e231b7d2
+	VFMSUBADD231PS X11, X9, X2              // c4c231b7d3
+	VFMSUBADD231PS (BX), X9, X11            // c46231b71b
+	VFMSUBADD231PS (R11), X9, X11           // c44231b71b
+	VFMSUBADD231PS X2, X9, X11              // c46231b7da
+	VFMSUBADD231PS X11, X9, X11             // c44231b7db
+	VFMSUBADD231PS (BX), Y15, Y2            // c4e205b713
+	VFMSUBADD231PS (R11), Y15, Y2           // c4c205b713
+	VFMSUBADD231PS Y2, Y15, Y2              // c4e205b7d2
+	VFMSUBADD231PS Y11, Y15, Y2             // c4c205b7d3
+	VFMSUBADD231PS (BX), Y15, Y11           // c46205b71b
+	VFMSUBADD231PS (R11), Y15, Y11          // c44205b71b
+	VFMSUBADD231PS Y2, Y15, Y11             // c46205b7da
+	VFMSUBADD231PS Y11, Y15, Y11            // c44205b7db
+	VFNMADD132PD (BX), X9, X2               // c4e2b19c13
+	VFNMADD132PD (R11), X9, X2              // c4c2b19c13
+	VFNMADD132PD X2, X9, X2                 // c4e2b19cd2
+	VFNMADD132PD X11, X9, X2                // c4c2b19cd3
+	VFNMADD132PD (BX), X9, X11              // c462b19c1b
+	VFNMADD132PD (R11), X9, X11             // c442b19c1b
+	VFNMADD132PD X2, X9, X11                // c462b19cda
+	VFNMADD132PD X11, X9, X11               // c442b19cdb
+	VFNMADD132PD (BX), Y15, Y2              // c4e2859c13
+	VFNMADD132PD (R11), Y15, Y2             // c4c2859c13
+	VFNMADD132PD Y2, Y15, Y2                // c4e2859cd2
+	VFNMADD132PD Y11, Y15, Y2               // c4c2859cd3
+	VFNMADD132PD (BX), Y15, Y11             // c462859c1b
+	VFNMADD132PD (R11), Y15, Y11            // c442859c1b
+	VFNMADD132PD Y2, Y15, Y11               // c462859cda
+	VFNMADD132PD Y11, Y15, Y11              // c442859cdb
+	VFNMADD132PS (BX), X9, X2               // c4e2319c13
+	VFNMADD132PS (R11), X9, X2              // c4c2319c13
+	VFNMADD132PS X2, X9, X2                 // c4e2319cd2
+	VFNMADD132PS X11, X9, X2                // c4c2319cd3
+	VFNMADD132PS (BX), X9, X11              // c462319c1b
+	VFNMADD132PS (R11), X9, X11             // c442319c1b
+	VFNMADD132PS X2, X9, X11                // c462319cda
+	VFNMADD132PS X11, X9, X11               // c442319cdb
+	VFNMADD132PS (BX), Y15, Y2              // c4e2059c13
+	VFNMADD132PS (R11), Y15, Y2             // c4c2059c13
+	VFNMADD132PS Y2, Y15, Y2                // c4e2059cd2
+	VFNMADD132PS Y11, Y15, Y2               // c4c2059cd3
+	VFNMADD132PS (BX), Y15, Y11             // c462059c1b
+	VFNMADD132PS (R11), Y15, Y11            // c442059c1b
+	VFNMADD132PS Y2, Y15, Y11               // c462059cda
+	VFNMADD132PS Y11, Y15, Y11              // c442059cdb
+	VFNMADD132SD (BX), X9, X2               // c4e2b19d13
+	VFNMADD132SD (R11), X9, X2              // c4c2b19d13
+	VFNMADD132SD X2, X9, X2                 // c4e2b19dd2
+	VFNMADD132SD X11, X9, X2                // c4c2b19dd3
+	VFNMADD132SD (BX), X9, X11              // c462b19d1b
+	VFNMADD132SD (R11), X9, X11             // c442b19d1b
+	VFNMADD132SD X2, X9, X11                // c462b19dda
+	VFNMADD132SD X11, X9, X11               // c442b19ddb
+	VFNMADD132SS (BX), X9, X2               // c4e2319d13
+	VFNMADD132SS (R11), X9, X2              // c4c2319d13
+	VFNMADD132SS X2, X9, X2                 // c4e2319dd2
+	VFNMADD132SS X11, X9, X2                // c4c2319dd3
+	VFNMADD132SS (BX), X9, X11              // c462319d1b
+	VFNMADD132SS (R11), X9, X11             // c442319d1b
+	VFNMADD132SS X2, X9, X11                // c462319dda
+	VFNMADD132SS X11, X9, X11               // c442319ddb
+	VFNMADD213PD (BX), X9, X2               // c4e2b1ac13
+	VFNMADD213PD (R11), X9, X2              // c4c2b1ac13
+	VFNMADD213PD X2, X9, X2                 // c4e2b1acd2
+	VFNMADD213PD X11, X9, X2                // c4c2b1acd3
+	VFNMADD213PD (BX), X9, X11              // c462b1ac1b
+	VFNMADD213PD (R11), X9, X11             // c442b1ac1b
+	VFNMADD213PD X2, X9, X11                // c462b1acda
+	VFNMADD213PD X11, X9, X11               // c442b1acdb
+	VFNMADD213PD (BX), Y15, Y2              // c4e285ac13
+	VFNMADD213PD (R11), Y15, Y2             // c4c285ac13
+	VFNMADD213PD Y2, Y15, Y2                // c4e285acd2
+	VFNMADD213PD Y11, Y15, Y2               // c4c285acd3
+	VFNMADD213PD (BX), Y15, Y11             // c46285ac1b
+	VFNMADD213PD (R11), Y15, Y11            // c44285ac1b
+	VFNMADD213PD Y2, Y15, Y11               // c46285acda
+	VFNMADD213PD Y11, Y15, Y11              // c44285acdb
+	VFNMADD213PS (BX), X9, X2               // c4e231ac13
+	VFNMADD213PS (R11), X9, X2              // c4c231ac13
+	VFNMADD213PS X2, X9, X2                 // c4e231acd2
+	VFNMADD213PS X11, X9, X2                // c4c231acd3
+	VFNMADD213PS (BX), X9, X11              // c46231ac1b
+	VFNMADD213PS (R11), X9, X11             // c44231ac1b
+	VFNMADD213PS X2, X9, X11                // c46231acda
+	VFNMADD213PS X11, X9, X11               // c44231acdb
+	VFNMADD213PS (BX), Y15, Y2              // c4e205ac13
+	VFNMADD213PS (R11), Y15, Y2             // c4c205ac13
+	VFNMADD213PS Y2, Y15, Y2                // c4e205acd2
+	VFNMADD213PS Y11, Y15, Y2               // c4c205acd3
+	VFNMADD213PS (BX), Y15, Y11             // c46205ac1b
+	VFNMADD213PS (R11), Y15, Y11            // c44205ac1b
+	VFNMADD213PS Y2, Y15, Y11               // c46205acda
+	VFNMADD213PS Y11, Y15, Y11              // c44205acdb
+	VFNMADD213SD (BX), X9, X2               // c4e2b1ad13
+	VFNMADD213SD (R11), X9, X2              // c4c2b1ad13
+	VFNMADD213SD X2, X9, X2                 // c4e2b1add2
+	VFNMADD213SD X11, X9, X2                // c4c2b1add3
+	VFNMADD213SD (BX), X9, X11              // c462b1ad1b
+	VFNMADD213SD (R11), X9, X11             // c442b1ad1b
+	VFNMADD213SD X2, X9, X11                // c462b1adda
+	VFNMADD213SD X11, X9, X11               // c442b1addb
+	VFNMADD213SS (BX), X9, X2               // c4e231ad13
+	VFNMADD213SS (R11), X9, X2              // c4c231ad13
+	VFNMADD213SS X2, X9, X2                 // c4e231add2
+	VFNMADD213SS X11, X9, X2                // c4c231add3
+	VFNMADD213SS (BX), X9, X11              // c46231ad1b
+	VFNMADD213SS (R11), X9, X11             // c44231ad1b
+	VFNMADD213SS X2, X9, X11                // c46231adda
+	VFNMADD213SS X11, X9, X11               // c44231addb
+	VFNMADD231PD (BX), X9, X2               // c4e2b1bc13
+	VFNMADD231PD (R11), X9, X2              // c4c2b1bc13
+	VFNMADD231PD X2, X9, X2                 // c4e2b1bcd2
+	VFNMADD231PD X11, X9, X2                // c4c2b1bcd3
+	VFNMADD231PD (BX), X9, X11              // c462b1bc1b
+	VFNMADD231PD (R11), X9, X11             // c442b1bc1b
+	VFNMADD231PD X2, X9, X11                // c462b1bcda
+	VFNMADD231PD X11, X9, X11               // c442b1bcdb
+	VFNMADD231PD (BX), Y15, Y2              // c4e285bc13
+	VFNMADD231PD (R11), Y15, Y2             // c4c285bc13
+	VFNMADD231PD Y2, Y15, Y2                // c4e285bcd2
+	VFNMADD231PD Y11, Y15, Y2               // c4c285bcd3
+	VFNMADD231PD (BX), Y15, Y11             // c46285bc1b
+	VFNMADD231PD (R11), Y15, Y11            // c44285bc1b
+	VFNMADD231PD Y2, Y15, Y11               // c46285bcda
+	VFNMADD231PD Y11, Y15, Y11              // c44285bcdb
+	VFNMADD231PS (BX), X9, X2               // c4e231bc13
+	VFNMADD231PS (R11), X9, X2              // c4c231bc13
+	VFNMADD231PS X2, X9, X2                 // c4e231bcd2
+	VFNMADD231PS X11, X9, X2                // c4c231bcd3
+	VFNMADD231PS (BX), X9, X11              // c46231bc1b
+	VFNMADD231PS (R11), X9, X11             // c44231bc1b
+	VFNMADD231PS X2, X9, X11                // c46231bcda
+	VFNMADD231PS X11, X9, X11               // c44231bcdb
+	VFNMADD231PS (BX), Y15, Y2              // c4e205bc13
+	VFNMADD231PS (R11), Y15, Y2             // c4c205bc13
+	VFNMADD231PS Y2, Y15, Y2                // c4e205bcd2
+	VFNMADD231PS Y11, Y15, Y2               // c4c205bcd3
+	VFNMADD231PS (BX), Y15, Y11             // c46205bc1b
+	VFNMADD231PS (R11), Y15, Y11            // c44205bc1b
+	VFNMADD231PS Y2, Y15, Y11               // c46205bcda
+	VFNMADD231PS Y11, Y15, Y11              // c44205bcdb
+	VFNMADD231SD (BX), X9, X2               // c4e2b1bd13
+	VFNMADD231SD (R11), X9, X2              // c4c2b1bd13
+	VFNMADD231SD X2, X9, X2                 // c4e2b1bdd2
+	VFNMADD231SD X11, X9, X2                // c4c2b1bdd3
+	VFNMADD231SD (BX), X9, X11              // c462b1bd1b
+	VFNMADD231SD (R11), X9, X11             // c442b1bd1b
+	VFNMADD231SD X2, X9, X11                // c462b1bdda
+	VFNMADD231SD X11, X9, X11               // c442b1bddb
+	VFNMADD231SS (BX), X9, X2               // c4e231bd13
+	VFNMADD231SS (R11), X9, X2              // c4c231bd13
+	VFNMADD231SS X2, X9, X2                 // c4e231bdd2
+	VFNMADD231SS X11, X9, X2                // c4c231bdd3
+	VFNMADD231SS (BX), X9, X11              // c46231bd1b
+	VFNMADD231SS (R11), X9, X11             // c44231bd1b
+	VFNMADD231SS X2, X9, X11                // c46231bdda
+	VFNMADD231SS X11, X9, X11               // c44231bddb
+	VFNMSUB132PD (BX), X9, X2               // c4e2b19e13
+	VFNMSUB132PD (R11), X9, X2              // c4c2b19e13
+	VFNMSUB132PD X2, X9, X2                 // c4e2b19ed2
+	VFNMSUB132PD X11, X9, X2                // c4c2b19ed3
+	VFNMSUB132PD (BX), X9, X11              // c462b19e1b
+	VFNMSUB132PD (R11), X9, X11             // c442b19e1b
+	VFNMSUB132PD X2, X9, X11                // c462b19eda
+	VFNMSUB132PD X11, X9, X11               // c442b19edb
+	VFNMSUB132PD (BX), Y15, Y2              // c4e2859e13
+	VFNMSUB132PD (R11), Y15, Y2             // c4c2859e13
+	VFNMSUB132PD Y2, Y15, Y2                // c4e2859ed2
+	VFNMSUB132PD Y11, Y15, Y2               // c4c2859ed3
+	VFNMSUB132PD (BX), Y15, Y11             // c462859e1b
+	VFNMSUB132PD (R11), Y15, Y11            // c442859e1b
+	VFNMSUB132PD Y2, Y15, Y11               // c462859eda
+	VFNMSUB132PD Y11, Y15, Y11              // c442859edb
+	VFNMSUB132PS (BX), X9, X2               // c4e2319e13
+	VFNMSUB132PS (R11), X9, X2              // c4c2319e13
+	VFNMSUB132PS X2, X9, X2                 // c4e2319ed2
+	VFNMSUB132PS X11, X9, X2                // c4c2319ed3
+	VFNMSUB132PS (BX), X9, X11              // c462319e1b
+	VFNMSUB132PS (R11), X9, X11             // c442319e1b
+	VFNMSUB132PS X2, X9, X11                // c462319eda
+	VFNMSUB132PS X11, X9, X11               // c442319edb
+	VFNMSUB132PS (BX), Y15, Y2              // c4e2059e13
+	VFNMSUB132PS (R11), Y15, Y2             // c4c2059e13
+	VFNMSUB132PS Y2, Y15, Y2                // c4e2059ed2
+	VFNMSUB132PS Y11, Y15, Y2               // c4c2059ed3
+	VFNMSUB132PS (BX), Y15, Y11             // c462059e1b
+	VFNMSUB132PS (R11), Y15, Y11            // c442059e1b
+	VFNMSUB132PS Y2, Y15, Y11               // c462059eda
+	VFNMSUB132PS Y11, Y15, Y11              // c442059edb
+	VFNMSUB132SD (BX), X9, X2               // c4e2b19f13
+	VFNMSUB132SD (R11), X9, X2              // c4c2b19f13
+	VFNMSUB132SD X2, X9, X2                 // c4e2b19fd2
+	VFNMSUB132SD X11, X9, X2                // c4c2b19fd3
+	VFNMSUB132SD (BX), X9, X11              // c462b19f1b
+	VFNMSUB132SD (R11), X9, X11             // c442b19f1b
+	VFNMSUB132SD X2, X9, X11                // c462b19fda
+	VFNMSUB132SD X11, X9, X11               // c442b19fdb
+	VFNMSUB132SS (BX), X9, X2               // c4e2319f13
+	VFNMSUB132SS (R11), X9, X2              // c4c2319f13
+	VFNMSUB132SS X2, X9, X2                 // c4e2319fd2
+	VFNMSUB132SS X11, X9, X2                // c4c2319fd3
+	VFNMSUB132SS (BX), X9, X11              // c462319f1b
+	VFNMSUB132SS (R11), X9, X11             // c442319f1b
+	VFNMSUB132SS X2, X9, X11                // c462319fda
+	VFNMSUB132SS X11, X9, X11               // c442319fdb
+	VFNMSUB213PD (BX), X9, X2               // c4e2b1ae13
+	VFNMSUB213PD (R11), X9, X2              // c4c2b1ae13
+	VFNMSUB213PD X2, X9, X2                 // c4e2b1aed2
+	VFNMSUB213PD X11, X9, X2                // c4c2b1aed3
+	VFNMSUB213PD (BX), X9, X11              // c462b1ae1b
+	VFNMSUB213PD (R11), X9, X11             // c442b1ae1b
+	VFNMSUB213PD X2, X9, X11                // c462b1aeda
+	VFNMSUB213PD X11, X9, X11               // c442b1aedb
+	VFNMSUB213PD (BX), Y15, Y2              // c4e285ae13
+	VFNMSUB213PD (R11), Y15, Y2             // c4c285ae13
+	VFNMSUB213PD Y2, Y15, Y2                // c4e285aed2
+	VFNMSUB213PD Y11, Y15, Y2               // c4c285aed3
+	VFNMSUB213PD (BX), Y15, Y11             // c46285ae1b
+	VFNMSUB213PD (R11), Y15, Y11            // c44285ae1b
+	VFNMSUB213PD Y2, Y15, Y11               // c46285aeda
+	VFNMSUB213PD Y11, Y15, Y11              // c44285aedb
+	VFNMSUB213PS (BX), X9, X2               // c4e231ae13
+	VFNMSUB213PS (R11), X9, X2              // c4c231ae13
+	VFNMSUB213PS X2, X9, X2                 // c4e231aed2
+	VFNMSUB213PS X11, X9, X2                // c4c231aed3
+	VFNMSUB213PS (BX), X9, X11              // c46231ae1b
+	VFNMSUB213PS (R11), X9, X11             // c44231ae1b
+	VFNMSUB213PS X2, X9, X11                // c46231aeda
+	VFNMSUB213PS X11, X9, X11               // c44231aedb
+	VFNMSUB213PS (BX), Y15, Y2              // c4e205ae13
+	VFNMSUB213PS (R11), Y15, Y2             // c4c205ae13
+	VFNMSUB213PS Y2, Y15, Y2                // c4e205aed2
+	VFNMSUB213PS Y11, Y15, Y2               // c4c205aed3
+	VFNMSUB213PS (BX), Y15, Y11             // c46205ae1b
+	VFNMSUB213PS (R11), Y15, Y11            // c44205ae1b
+	VFNMSUB213PS Y2, Y15, Y11               // c46205aeda
+	VFNMSUB213PS Y11, Y15, Y11              // c44205aedb
+	VFNMSUB213SD (BX), X9, X2               // c4e2b1af13
+	VFNMSUB213SD (R11), X9, X2              // c4c2b1af13
+	VFNMSUB213SD X2, X9, X2                 // c4e2b1afd2
+	VFNMSUB213SD X11, X9, X2                // c4c2b1afd3
+	VFNMSUB213SD (BX), X9, X11              // c462b1af1b
+	VFNMSUB213SD (R11), X9, X11             // c442b1af1b
+	VFNMSUB213SD X2, X9, X11                // c462b1afda
+	VFNMSUB213SD X11, X9, X11               // c442b1afdb
+	VFNMSUB213SS (BX), X9, X2               // c4e231af13
+	VFNMSUB213SS (R11), X9, X2              // c4c231af13
+	VFNMSUB213SS X2, X9, X2                 // c4e231afd2
+	VFNMSUB213SS X11, X9, X2                // c4c231afd3
+	VFNMSUB213SS (BX), X9, X11              // c46231af1b
+	VFNMSUB213SS (R11), X9, X11             // c44231af1b
+	VFNMSUB213SS X2, X9, X11                // c46231afda
+	VFNMSUB213SS X11, X9, X11               // c44231afdb
+	VFNMSUB231PD (BX), X9, X2               // c4e2b1be13
+	VFNMSUB231PD (R11), X9, X2              // c4c2b1be13
+	VFNMSUB231PD X2, X9, X2                 // c4e2b1bed2
+	VFNMSUB231PD X11, X9, X2                // c4c2b1bed3
+	VFNMSUB231PD (BX), X9, X11              // c462b1be1b
+	VFNMSUB231PD (R11), X9, X11             // c442b1be1b
+	VFNMSUB231PD X2, X9, X11                // c462b1beda
+	VFNMSUB231PD X11, X9, X11               // c442b1bedb
+	VFNMSUB231PD (BX), Y15, Y2              // c4e285be13
+	VFNMSUB231PD (R11), Y15, Y2             // c4c285be13
+	VFNMSUB231PD Y2, Y15, Y2                // c4e285bed2
+	VFNMSUB231PD Y11, Y15, Y2               // c4c285bed3
+	VFNMSUB231PD (BX), Y15, Y11             // c46285be1b
+	VFNMSUB231PD (R11), Y15, Y11            // c44285be1b
+	VFNMSUB231PD Y2, Y15, Y11               // c46285beda
+	VFNMSUB231PD Y11, Y15, Y11              // c44285bedb
+	VFNMSUB231PS (BX), X9, X2               // c4e231be13
+	VFNMSUB231PS (R11), X9, X2              // c4c231be13
+	VFNMSUB231PS X2, X9, X2                 // c4e231bed2
+	VFNMSUB231PS X11, X9, X2                // c4c231bed3
+	VFNMSUB231PS (BX), X9, X11              // c46231be1b
+	VFNMSUB231PS (R11), X9, X11             // c44231be1b
+	VFNMSUB231PS X2, X9, X11                // c46231beda
+	VFNMSUB231PS X11, X9, X11               // c44231bedb
+	VFNMSUB231PS (BX), Y15, Y2              // c4e205be13
+	VFNMSUB231PS (R11), Y15, Y2             // c4c205be13
+	VFNMSUB231PS Y2, Y15, Y2                // c4e205bed2
+	VFNMSUB231PS Y11, Y15, Y2               // c4c205bed3
+	VFNMSUB231PS (BX), Y15, Y11             // c46205be1b
+	VFNMSUB231PS (R11), Y15, Y11            // c44205be1b
+	VFNMSUB231PS Y2, Y15, Y11               // c46205beda
+	VFNMSUB231PS Y11, Y15, Y11              // c44205bedb
+	VFNMSUB231SD (BX), X9, X2               // c4e2b1bf13
+	VFNMSUB231SD (R11), X9, X2              // c4c2b1bf13
+	VFNMSUB231SD X2, X9, X2                 // c4e2b1bfd2
+	VFNMSUB231SD X11, X9, X2                // c4c2b1bfd3
+	VFNMSUB231SD (BX), X9, X11              // c462b1bf1b
+	VFNMSUB231SD (R11), X9, X11             // c442b1bf1b
+	VFNMSUB231SD X2, X9, X11                // c462b1bfda
+	VFNMSUB231SD X11, X9, X11               // c442b1bfdb
+	VFNMSUB231SS (BX), X9, X2               // c4e231bf13
+	VFNMSUB231SS (R11), X9, X2              // c4c231bf13
+	VFNMSUB231SS X2, X9, X2                 // c4e231bfd2
+	VFNMSUB231SS X11, X9, X2                // c4c231bfd3
+	VFNMSUB231SS (BX), X9, X11              // c46231bf1b
+	VFNMSUB231SS (R11), X9, X11             // c44231bf1b
+	VFNMSUB231SS X2, X9, X11                // c46231bfda
+	VFNMSUB231SS X11, X9, X11               // c44231bfdb
+	VHADDPD (BX), X9, X2                    // c4e1317c13 or c5b17c13
+	VHADDPD (R11), X9, X2                   // c4c1317c13
+	VHADDPD X2, X9, X2                      // c4e1317cd2 or c5b17cd2
+	VHADDPD X11, X9, X2                     // c4c1317cd3
+	VHADDPD (BX), X9, X11                   // c461317c1b or c5317c1b
+	VHADDPD (R11), X9, X11                  // c441317c1b
+	VHADDPD X2, X9, X11                     // c461317cda or c5317cda
+	VHADDPD X11, X9, X11                    // c441317cdb
+	VHADDPD (BX), Y15, Y2                   // c4e1057c13 or c5857c13
+	VHADDPD (R11), Y15, Y2                  // c4c1057c13
+	VHADDPD Y2, Y15, Y2                     // c4e1057cd2 or c5857cd2
+	VHADDPD Y11, Y15, Y2                    // c4c1057cd3
+	VHADDPD (BX), Y15, Y11                  // c461057c1b or c5057c1b
+	VHADDPD (R11), Y15, Y11                 // c441057c1b
+	VHADDPD Y2, Y15, Y11                    // c461057cda or c5057cda
+	VHADDPD Y11, Y15, Y11                   // c441057cdb
+	VHADDPS (BX), X9, X2                    // c4e1337c13 or c5b37c13
+	VHADDPS (R11), X9, X2                   // c4c1337c13
+	VHADDPS X2, X9, X2                      // c4e1337cd2 or c5b37cd2
+	VHADDPS X11, X9, X2                     // c4c1337cd3
+	VHADDPS (BX), X9, X11                   // c461337c1b or c5337c1b
+	VHADDPS (R11), X9, X11                  // c441337c1b
+	VHADDPS X2, X9, X11                     // c461337cda or c5337cda
+	VHADDPS X11, X9, X11                    // c441337cdb
+	VHADDPS (BX), Y15, Y2                   // c4e1077c13 or c5877c13
+	VHADDPS (R11), Y15, Y2                  // c4c1077c13
+	VHADDPS Y2, Y15, Y2                     // c4e1077cd2 or c5877cd2
+	VHADDPS Y11, Y15, Y2                    // c4c1077cd3
+	VHADDPS (BX), Y15, Y11                  // c461077c1b or c5077c1b
+	VHADDPS (R11), Y15, Y11                 // c441077c1b
+	VHADDPS Y2, Y15, Y11                    // c461077cda or c5077cda
+	VHADDPS Y11, Y15, Y11                   // c441077cdb
+	VHSUBPD (BX), X9, X2                    // c4e1317d13 or c5b17d13
+	VHSUBPD (R11), X9, X2                   // c4c1317d13
+	VHSUBPD X2, X9, X2                      // c4e1317dd2 or c5b17dd2
+	VHSUBPD X11, X9, X2                     // c4c1317dd3
+	VHSUBPD (BX), X9, X11                   // c461317d1b or c5317d1b
+	VHSUBPD (R11), X9, X11                  // c441317d1b
+	VHSUBPD X2, X9, X11                     // c461317dda or c5317dda
+	VHSUBPD X11, X9, X11                    // c441317ddb
+	VHSUBPD (BX), Y15, Y2                   // c4e1057d13 or c5857d13
+	VHSUBPD (R11), Y15, Y2                  // c4c1057d13
+	VHSUBPD Y2, Y15, Y2                     // c4e1057dd2 or c5857dd2
+	VHSUBPD Y11, Y15, Y2                    // c4c1057dd3
+	VHSUBPD (BX), Y15, Y11                  // c461057d1b or c5057d1b
+	VHSUBPD (R11), Y15, Y11                 // c441057d1b
+	VHSUBPD Y2, Y15, Y11                    // c461057dda or c5057dda
+	VHSUBPD Y11, Y15, Y11                   // c441057ddb
+	VHSUBPS (BX), X9, X2                    // c4e1337d13 or c5b37d13
+	VHSUBPS (R11), X9, X2                   // c4c1337d13
+	VHSUBPS X2, X9, X2                      // c4e1337dd2 or c5b37dd2
+	VHSUBPS X11, X9, X2                     // c4c1337dd3
+	VHSUBPS (BX), X9, X11                   // c461337d1b or c5337d1b
+	VHSUBPS (R11), X9, X11                  // c441337d1b
+	VHSUBPS X2, X9, X11                     // c461337dda or c5337dda
+	VHSUBPS X11, X9, X11                    // c441337ddb
+	VHSUBPS (BX), Y15, Y2                   // c4e1077d13 or c5877d13
+	VHSUBPS (R11), Y15, Y2                  // c4c1077d13
+	VHSUBPS Y2, Y15, Y2                     // c4e1077dd2 or c5877dd2
+	VHSUBPS Y11, Y15, Y2                    // c4c1077dd3
+	VHSUBPS (BX), Y15, Y11                  // c461077d1b or c5077d1b
+	VHSUBPS (R11), Y15, Y11                 // c441077d1b
+	VHSUBPS Y2, Y15, Y11                    // c461077dda or c5077dda
+	VHSUBPS Y11, Y15, Y11                   // c441077ddb
+	VINSERTF128 $7, (BX), Y15, Y2           // c4e305181307
+	VINSERTF128 $7, (R11), Y15, Y2          // c4c305181307
+	VINSERTF128 $7, X2, Y15, Y2             // c4e30518d207
+	VINSERTF128 $7, X11, Y15, Y2            // c4c30518d307
+	VINSERTF128 $7, (BX), Y15, Y11          // c46305181b07
+	VINSERTF128 $7, (R11), Y15, Y11         // c44305181b07
+	VINSERTF128 $7, X2, Y15, Y11            // c4630518da07
+	VINSERTF128 $7, X11, Y15, Y11           // c4430518db07
 	VINSERTI128 $7, (BX), Y15, Y2   // c4e305381307
 	VINSERTI128 $7, (R11), Y15, Y2  // c4c305381307
 	VINSERTI128 $7, X2, Y15, Y2     // c4e30538d207
@@ -7430,220 +7430,220 @@
 	VINSERTI128 $7, (R11), Y15, Y11 // c44305381b07
 	VINSERTI128 $7, X2, Y15, Y11    // c4630538da07
 	VINSERTI128 $7, X11, Y15, Y11   // c4430538db07
-	//TODO: VINSERTPS $7, (BX), X9, X2      // c4e331211307
-	//TODO: VINSERTPS $7, (R11), X9, X2     // c4c331211307
-	//TODO: VINSERTPS $7, X2, X9, X2        // c4e33121d207
-	//TODO: VINSERTPS $7, X11, X9, X2       // c4c33121d307
-	//TODO: VINSERTPS $7, (BX), X9, X11     // c46331211b07
-	//TODO: VINSERTPS $7, (R11), X9, X11    // c44331211b07
-	//TODO: VINSERTPS $7, X2, X9, X11       // c4633121da07
-	//TODO: VINSERTPS $7, X11, X9, X11      // c4433121db07
-	//TODO: VLDDQU (BX), X2                 // c4e17bf013 or c5fbf013
-	//TODO: VLDDQU (R11), X2                // c4c17bf013
-	//TODO: VLDDQU (BX), X11                // c4617bf01b or c57bf01b
-	//TODO: VLDDQU (R11), X11               // c4417bf01b
-	//TODO: VLDDQU (BX), Y2                 // c4e17ff013 or c5fff013
-	//TODO: VLDDQU (R11), Y2                // c4c17ff013
-	//TODO: VLDDQU (BX), Y11                // c4617ff01b or c57ff01b
-	//TODO: VLDDQU (R11), Y11               // c4417ff01b
-	//TODO: VLDMXCSR (BX)                   // c4e178ae13 or c5f8ae13
-	//TODO: VLDMXCSR (R11)                  // c4c178ae13
-	//TODO: VMASKMOVDQU X2, X2              // c4e179f7d2 or c5f9f7d2
-	//TODO: VMASKMOVDQU X11, X2             // c4c179f7d3
-	//TODO: VMASKMOVDQU X2, X11             // c46179f7da or c579f7da
-	//TODO: VMASKMOVDQU X11, X11            // c44179f7db
-	//TODO: VMASKMOVPD X2, X9, (BX)         // c4e2312f13
-	//TODO: VMASKMOVPD X11, X9, (BX)        // c462312f1b
-	//TODO: VMASKMOVPD X2, X9, (R11)        // c4c2312f13
-	//TODO: VMASKMOVPD X11, X9, (R11)       // c442312f1b
-	//TODO: VMASKMOVPD Y2, Y15, (BX)        // c4e2052f13
-	//TODO: VMASKMOVPD Y11, Y15, (BX)       // c462052f1b
-	//TODO: VMASKMOVPD Y2, Y15, (R11)       // c4c2052f13
-	//TODO: VMASKMOVPD Y11, Y15, (R11)      // c442052f1b
-	//TODO: VMASKMOVPD (BX), X9, X2         // c4e2312d13
-	//TODO: VMASKMOVPD (R11), X9, X2        // c4c2312d13
-	//TODO: VMASKMOVPD (BX), X9, X11        // c462312d1b
-	//TODO: VMASKMOVPD (R11), X9, X11       // c442312d1b
-	//TODO: VMASKMOVPD (BX), Y15, Y2        // c4e2052d13
-	//TODO: VMASKMOVPD (R11), Y15, Y2       // c4c2052d13
-	//TODO: VMASKMOVPD (BX), Y15, Y11       // c462052d1b
-	//TODO: VMASKMOVPD (R11), Y15, Y11      // c442052d1b
-	//TODO: VMASKMOVPS X2, X9, (BX)         // c4e2312e13
-	//TODO: VMASKMOVPS X11, X9, (BX)        // c462312e1b
-	//TODO: VMASKMOVPS X2, X9, (R11)        // c4c2312e13
-	//TODO: VMASKMOVPS X11, X9, (R11)       // c442312e1b
-	//TODO: VMASKMOVPS Y2, Y15, (BX)        // c4e2052e13
-	//TODO: VMASKMOVPS Y11, Y15, (BX)       // c462052e1b
-	//TODO: VMASKMOVPS Y2, Y15, (R11)       // c4c2052e13
-	//TODO: VMASKMOVPS Y11, Y15, (R11)      // c442052e1b
-	//TODO: VMASKMOVPS (BX), X9, X2         // c4e2312c13
-	//TODO: VMASKMOVPS (R11), X9, X2        // c4c2312c13
-	//TODO: VMASKMOVPS (BX), X9, X11        // c462312c1b
-	//TODO: VMASKMOVPS (R11), X9, X11       // c442312c1b
-	//TODO: VMASKMOVPS (BX), Y15, Y2        // c4e2052c13
-	//TODO: VMASKMOVPS (R11), Y15, Y2       // c4c2052c13
-	//TODO: VMASKMOVPS (BX), Y15, Y11       // c462052c1b
-	//TODO: VMASKMOVPS (R11), Y15, Y11      // c442052c1b
-	//TODO: VMAXPD (BX), X9, X2             // c4e1315f13 or c5b15f13
-	//TODO: VMAXPD (R11), X9, X2            // c4c1315f13
-	//TODO: VMAXPD X2, X9, X2               // c4e1315fd2 or c5b15fd2
-	//TODO: VMAXPD X11, X9, X2              // c4c1315fd3
-	//TODO: VMAXPD (BX), X9, X11            // c461315f1b or c5315f1b
-	//TODO: VMAXPD (R11), X9, X11           // c441315f1b
-	//TODO: VMAXPD X2, X9, X11              // c461315fda or c5315fda
-	//TODO: VMAXPD X11, X9, X11             // c441315fdb
-	//TODO: VMAXPD (BX), Y15, Y2            // c4e1055f13 or c5855f13
-	//TODO: VMAXPD (R11), Y15, Y2           // c4c1055f13
-	//TODO: VMAXPD Y2, Y15, Y2              // c4e1055fd2 or c5855fd2
-	//TODO: VMAXPD Y11, Y15, Y2             // c4c1055fd3
-	//TODO: VMAXPD (BX), Y15, Y11           // c461055f1b or c5055f1b
-	//TODO: VMAXPD (R11), Y15, Y11          // c441055f1b
-	//TODO: VMAXPD Y2, Y15, Y11             // c461055fda or c5055fda
-	//TODO: VMAXPD Y11, Y15, Y11            // c441055fdb
-	//TODO: VMAXPS (BX), X9, X2             // c4e1305f13 or c5b05f13
-	//TODO: VMAXPS (R11), X9, X2            // c4c1305f13
-	//TODO: VMAXPS X2, X9, X2               // c4e1305fd2 or c5b05fd2
-	//TODO: VMAXPS X11, X9, X2              // c4c1305fd3
-	//TODO: VMAXPS (BX), X9, X11            // c461305f1b or c5305f1b
-	//TODO: VMAXPS (R11), X9, X11           // c441305f1b
-	//TODO: VMAXPS X2, X9, X11              // c461305fda or c5305fda
-	//TODO: VMAXPS X11, X9, X11             // c441305fdb
-	//TODO: VMAXPS (BX), Y15, Y2            // c4e1045f13 or c5845f13
-	//TODO: VMAXPS (R11), Y15, Y2           // c4c1045f13
-	//TODO: VMAXPS Y2, Y15, Y2              // c4e1045fd2 or c5845fd2
-	//TODO: VMAXPS Y11, Y15, Y2             // c4c1045fd3
-	//TODO: VMAXPS (BX), Y15, Y11           // c461045f1b or c5045f1b
-	//TODO: VMAXPS (R11), Y15, Y11          // c441045f1b
-	//TODO: VMAXPS Y2, Y15, Y11             // c461045fda or c5045fda
-	//TODO: VMAXPS Y11, Y15, Y11            // c441045fdb
-	//TODO: VMAXSD (BX), X9, X2             // c4e1335f13 or c5b35f13
-	//TODO: VMAXSD (R11), X9, X2            // c4c1335f13
-	//TODO: VMAXSD X2, X9, X2               // c4e1335fd2 or c5b35fd2
-	//TODO: VMAXSD X11, X9, X2              // c4c1335fd3
-	//TODO: VMAXSD (BX), X9, X11            // c461335f1b or c5335f1b
-	//TODO: VMAXSD (R11), X9, X11           // c441335f1b
-	//TODO: VMAXSD X2, X9, X11              // c461335fda or c5335fda
-	//TODO: VMAXSD X11, X9, X11             // c441335fdb
-	//TODO: VMAXSS (BX), X9, X2             // c4e1325f13 or c5b25f13
-	//TODO: VMAXSS (R11), X9, X2            // c4c1325f13
-	//TODO: VMAXSS X2, X9, X2               // c4e1325fd2 or c5b25fd2
-	//TODO: VMAXSS X11, X9, X2              // c4c1325fd3
-	//TODO: VMAXSS (BX), X9, X11            // c461325f1b or c5325f1b
-	//TODO: VMAXSS (R11), X9, X11           // c441325f1b
-	//TODO: VMAXSS X2, X9, X11              // c461325fda or c5325fda
-	//TODO: VMAXSS X11, X9, X11             // c441325fdb
-	//TODO: VMINPD (BX), X9, X2             // c4e1315d13 or c5b15d13
-	//TODO: VMINPD (R11), X9, X2            // c4c1315d13
-	//TODO: VMINPD X2, X9, X2               // c4e1315dd2 or c5b15dd2
-	//TODO: VMINPD X11, X9, X2              // c4c1315dd3
-	//TODO: VMINPD (BX), X9, X11            // c461315d1b or c5315d1b
-	//TODO: VMINPD (R11), X9, X11           // c441315d1b
-	//TODO: VMINPD X2, X9, X11              // c461315dda or c5315dda
-	//TODO: VMINPD X11, X9, X11             // c441315ddb
-	//TODO: VMINPD (BX), Y15, Y2            // c4e1055d13 or c5855d13
-	//TODO: VMINPD (R11), Y15, Y2           // c4c1055d13
-	//TODO: VMINPD Y2, Y15, Y2              // c4e1055dd2 or c5855dd2
-	//TODO: VMINPD Y11, Y15, Y2             // c4c1055dd3
-	//TODO: VMINPD (BX), Y15, Y11           // c461055d1b or c5055d1b
-	//TODO: VMINPD (R11), Y15, Y11          // c441055d1b
-	//TODO: VMINPD Y2, Y15, Y11             // c461055dda or c5055dda
-	//TODO: VMINPD Y11, Y15, Y11            // c441055ddb
-	//TODO: VMINPS (BX), X9, X2             // c4e1305d13 or c5b05d13
-	//TODO: VMINPS (R11), X9, X2            // c4c1305d13
-	//TODO: VMINPS X2, X9, X2               // c4e1305dd2 or c5b05dd2
-	//TODO: VMINPS X11, X9, X2              // c4c1305dd3
-	//TODO: VMINPS (BX), X9, X11            // c461305d1b or c5305d1b
-	//TODO: VMINPS (R11), X9, X11           // c441305d1b
-	//TODO: VMINPS X2, X9, X11              // c461305dda or c5305dda
-	//TODO: VMINPS X11, X9, X11             // c441305ddb
-	//TODO: VMINPS (BX), Y15, Y2            // c4e1045d13 or c5845d13
-	//TODO: VMINPS (R11), Y15, Y2           // c4c1045d13
-	//TODO: VMINPS Y2, Y15, Y2              // c4e1045dd2 or c5845dd2
-	//TODO: VMINPS Y11, Y15, Y2             // c4c1045dd3
-	//TODO: VMINPS (BX), Y15, Y11           // c461045d1b or c5045d1b
-	//TODO: VMINPS (R11), Y15, Y11          // c441045d1b
-	//TODO: VMINPS Y2, Y15, Y11             // c461045dda or c5045dda
-	//TODO: VMINPS Y11, Y15, Y11            // c441045ddb
-	//TODO: VMINSD (BX), X9, X2             // c4e1335d13 or c5b35d13
-	//TODO: VMINSD (R11), X9, X2            // c4c1335d13
-	//TODO: VMINSD X2, X9, X2               // c4e1335dd2 or c5b35dd2
-	//TODO: VMINSD X11, X9, X2              // c4c1335dd3
-	//TODO: VMINSD (BX), X9, X11            // c461335d1b or c5335d1b
-	//TODO: VMINSD (R11), X9, X11           // c441335d1b
-	//TODO: VMINSD X2, X9, X11              // c461335dda or c5335dda
-	//TODO: VMINSD X11, X9, X11             // c441335ddb
-	//TODO: VMINSS (BX), X9, X2             // c4e1325d13 or c5b25d13
-	//TODO: VMINSS (R11), X9, X2            // c4c1325d13
-	//TODO: VMINSS X2, X9, X2               // c4e1325dd2 or c5b25dd2
-	//TODO: VMINSS X11, X9, X2              // c4c1325dd3
-	//TODO: VMINSS (BX), X9, X11            // c461325d1b or c5325d1b
-	//TODO: VMINSS (R11), X9, X11           // c441325d1b
-	//TODO: VMINSS X2, X9, X11              // c461325dda or c5325dda
-	//TODO: VMINSS X11, X9, X11             // c441325ddb
-	//TODO: VMOVAPD (BX), X2                // c4e1792813 or c5f92813
-	//TODO: VMOVAPD (R11), X2               // c4c1792813
-	//TODO: VMOVAPD X2, X2                  // c4e17928d2 or c5f928d2 or c4e17929d2 or c5f929d2
-	//TODO: VMOVAPD X11, X2                 // c4c17928d3 or c4617929da or c57929da
-	//TODO: VMOVAPD (BX), X11               // c46179281b or c579281b
-	//TODO: VMOVAPD (R11), X11              // c44179281b
-	//TODO: VMOVAPD X2, X11                 // c4617928da or c57928da or c4c17929d3
-	//TODO: VMOVAPD X11, X11                // c4417928db or c4417929db
-	//TODO: VMOVAPD X2, (BX)                // c4e1792913 or c5f92913
-	//TODO: VMOVAPD X11, (BX)               // c46179291b or c579291b
-	//TODO: VMOVAPD X2, (R11)               // c4c1792913
-	//TODO: VMOVAPD X11, (R11)              // c44179291b
-	//TODO: VMOVAPD (BX), Y2                // c4e17d2813 or c5fd2813
-	//TODO: VMOVAPD (R11), Y2               // c4c17d2813
-	//TODO: VMOVAPD Y2, Y2                  // c4e17d28d2 or c5fd28d2 or c4e17d29d2 or c5fd29d2
-	//TODO: VMOVAPD Y11, Y2                 // c4c17d28d3 or c4617d29da or c57d29da
-	//TODO: VMOVAPD (BX), Y11               // c4617d281b or c57d281b
-	//TODO: VMOVAPD (R11), Y11              // c4417d281b
-	//TODO: VMOVAPD Y2, Y11                 // c4617d28da or c57d28da or c4c17d29d3
-	//TODO: VMOVAPD Y11, Y11                // c4417d28db or c4417d29db
-	//TODO: VMOVAPD Y2, (BX)                // c4e17d2913 or c5fd2913
-	//TODO: VMOVAPD Y11, (BX)               // c4617d291b or c57d291b
-	//TODO: VMOVAPD Y2, (R11)               // c4c17d2913
-	//TODO: VMOVAPD Y11, (R11)              // c4417d291b
-	//TODO: VMOVAPS (BX), X2                // c4e1782813 or c5f82813
-	//TODO: VMOVAPS (R11), X2               // c4c1782813
-	//TODO: VMOVAPS X2, X2                  // c4e17828d2 or c5f828d2 or c4e17829d2 or c5f829d2
-	//TODO: VMOVAPS X11, X2                 // c4c17828d3 or c4617829da or c57829da
-	//TODO: VMOVAPS (BX), X11               // c46178281b or c578281b
-	//TODO: VMOVAPS (R11), X11              // c44178281b
-	//TODO: VMOVAPS X2, X11                 // c4617828da or c57828da or c4c17829d3
-	//TODO: VMOVAPS X11, X11                // c4417828db or c4417829db
-	//TODO: VMOVAPS X2, (BX)                // c4e1782913 or c5f82913
-	//TODO: VMOVAPS X11, (BX)               // c46178291b or c578291b
-	//TODO: VMOVAPS X2, (R11)               // c4c1782913
-	//TODO: VMOVAPS X11, (R11)              // c44178291b
-	//TODO: VMOVAPS (BX), Y2                // c4e17c2813 or c5fc2813
-	//TODO: VMOVAPS (R11), Y2               // c4c17c2813
-	//TODO: VMOVAPS Y2, Y2                  // c4e17c28d2 or c5fc28d2 or c4e17c29d2 or c5fc29d2
-	//TODO: VMOVAPS Y11, Y2                 // c4c17c28d3 or c4617c29da or c57c29da
-	//TODO: VMOVAPS (BX), Y11               // c4617c281b or c57c281b
-	//TODO: VMOVAPS (R11), Y11              // c4417c281b
-	//TODO: VMOVAPS Y2, Y11                 // c4617c28da or c57c28da or c4c17c29d3
-	//TODO: VMOVAPS Y11, Y11                // c4417c28db or c4417c29db
-	//TODO: VMOVAPS Y2, (BX)                // c4e17c2913 or c5fc2913
-	//TODO: VMOVAPS Y11, (BX)               // c4617c291b or c57c291b
-	//TODO: VMOVAPS Y2, (R11)               // c4c17c2913
-	//TODO: VMOVAPS Y11, (R11)              // c4417c291b
-	//TODO: VMOVD X2, (BX)                  // c4e1797e13 or c5f97e13
-	//TODO: VMOVD X11, (BX)                 // c461797e1b or c5797e1b
-	//TODO: VMOVD X2, (R11)                 // c4c1797e13
-	//TODO: VMOVD X11, (R11)                // c441797e1b
-	//TODO: VMOVD X2, DX                    // c4e1797ed2 or c5f97ed2
-	//TODO: VMOVD X11, DX                   // c461797eda or c5797eda
-	//TODO: VMOVD X2, R11                   // c4c1797ed3
-	//TODO: VMOVD X11, R11                  // c441797edb
-	//TODO: VMOVD (BX), X2                  // c4e1796e13 or c5f96e13
-	//TODO: VMOVD (R11), X2                 // c4c1796e13
-	//TODO: VMOVD DX, X2                    // c4e1796ed2 or c5f96ed2
-	//TODO: VMOVD R11, X2                   // c4c1796ed3
-	//TODO: VMOVD (BX), X11                 // c461796e1b or c5796e1b
-	//TODO: VMOVD (R11), X11                // c441796e1b
-	//TODO: VMOVD DX, X11                   // c461796eda or c5796eda
-	//TODO: VMOVD R11, X11                  // c441796edb
+	VINSERTPS $7, (BX), X9, X2              // c4e331211307
+	VINSERTPS $7, (R11), X9, X2             // c4c331211307
+	VINSERTPS $7, X2, X9, X2                // c4e33121d207
+	VINSERTPS $7, X11, X9, X2               // c4c33121d307
+	VINSERTPS $7, (BX), X9, X11             // c46331211b07
+	VINSERTPS $7, (R11), X9, X11            // c44331211b07
+	VINSERTPS $7, X2, X9, X11               // c4633121da07
+	VINSERTPS $7, X11, X9, X11              // c4433121db07
+	VLDDQU (BX), X2                         // c4e17bf013 or c5fbf013
+	VLDDQU (R11), X2                        // c4c17bf013
+	VLDDQU (BX), X11                        // c4617bf01b or c57bf01b
+	VLDDQU (R11), X11                       // c4417bf01b
+	VLDDQU (BX), Y2                         // c4e17ff013 or c5fff013
+	VLDDQU (R11), Y2                        // c4c17ff013
+	VLDDQU (BX), Y11                        // c4617ff01b or c57ff01b
+	VLDDQU (R11), Y11                       // c4417ff01b
+	VLDMXCSR (BX)                           // c4e178ae13 or c5f8ae13
+	VLDMXCSR (R11)                          // c4c178ae13
+	VMASKMOVDQU X2, X2                      // c4e179f7d2 or c5f9f7d2
+	VMASKMOVDQU X11, X2                     // c4c179f7d3
+	VMASKMOVDQU X2, X11                     // c46179f7da or c579f7da
+	VMASKMOVDQU X11, X11                    // c44179f7db
+	VMASKMOVPD X2, X9, (BX)                 // c4e2312f13
+	VMASKMOVPD X11, X9, (BX)                // c462312f1b
+	VMASKMOVPD X2, X9, (R11)                // c4c2312f13
+	VMASKMOVPD X11, X9, (R11)               // c442312f1b
+	VMASKMOVPD Y2, Y15, (BX)                // c4e2052f13
+	VMASKMOVPD Y11, Y15, (BX)               // c462052f1b
+	VMASKMOVPD Y2, Y15, (R11)               // c4c2052f13
+	VMASKMOVPD Y11, Y15, (R11)              // c442052f1b
+	VMASKMOVPD (BX), X9, X2                 // c4e2312d13
+	VMASKMOVPD (R11), X9, X2                // c4c2312d13
+	VMASKMOVPD (BX), X9, X11                // c462312d1b
+	VMASKMOVPD (R11), X9, X11               // c442312d1b
+	VMASKMOVPD (BX), Y15, Y2                // c4e2052d13
+	VMASKMOVPD (R11), Y15, Y2               // c4c2052d13
+	VMASKMOVPD (BX), Y15, Y11               // c462052d1b
+	VMASKMOVPD (R11), Y15, Y11              // c442052d1b
+	VMASKMOVPS X2, X9, (BX)                 // c4e2312e13
+	VMASKMOVPS X11, X9, (BX)                // c462312e1b
+	VMASKMOVPS X2, X9, (R11)                // c4c2312e13
+	VMASKMOVPS X11, X9, (R11)               // c442312e1b
+	VMASKMOVPS Y2, Y15, (BX)                // c4e2052e13
+	VMASKMOVPS Y11, Y15, (BX)               // c462052e1b
+	VMASKMOVPS Y2, Y15, (R11)               // c4c2052e13
+	VMASKMOVPS Y11, Y15, (R11)              // c442052e1b
+	VMASKMOVPS (BX), X9, X2                 // c4e2312c13
+	VMASKMOVPS (R11), X9, X2                // c4c2312c13
+	VMASKMOVPS (BX), X9, X11                // c462312c1b
+	VMASKMOVPS (R11), X9, X11               // c442312c1b
+	VMASKMOVPS (BX), Y15, Y2                // c4e2052c13
+	VMASKMOVPS (R11), Y15, Y2               // c4c2052c13
+	VMASKMOVPS (BX), Y15, Y11               // c462052c1b
+	VMASKMOVPS (R11), Y15, Y11              // c442052c1b
+	VMAXPD (BX), X9, X2                     // c4e1315f13 or c5b15f13
+	VMAXPD (R11), X9, X2                    // c4c1315f13
+	VMAXPD X2, X9, X2                       // c4e1315fd2 or c5b15fd2
+	VMAXPD X11, X9, X2                      // c4c1315fd3
+	VMAXPD (BX), X9, X11                    // c461315f1b or c5315f1b
+	VMAXPD (R11), X9, X11                   // c441315f1b
+	VMAXPD X2, X9, X11                      // c461315fda or c5315fda
+	VMAXPD X11, X9, X11                     // c441315fdb
+	VMAXPD (BX), Y15, Y2                    // c4e1055f13 or c5855f13
+	VMAXPD (R11), Y15, Y2                   // c4c1055f13
+	VMAXPD Y2, Y15, Y2                      // c4e1055fd2 or c5855fd2
+	VMAXPD Y11, Y15, Y2                     // c4c1055fd3
+	VMAXPD (BX), Y15, Y11                   // c461055f1b or c5055f1b
+	VMAXPD (R11), Y15, Y11                  // c441055f1b
+	VMAXPD Y2, Y15, Y11                     // c461055fda or c5055fda
+	VMAXPD Y11, Y15, Y11                    // c441055fdb
+	VMAXPS (BX), X9, X2                     // c4e1305f13 or c5b05f13
+	VMAXPS (R11), X9, X2                    // c4c1305f13
+	VMAXPS X2, X9, X2                       // c4e1305fd2 or c5b05fd2
+	VMAXPS X11, X9, X2                      // c4c1305fd3
+	VMAXPS (BX), X9, X11                    // c461305f1b or c5305f1b
+	VMAXPS (R11), X9, X11                   // c441305f1b
+	VMAXPS X2, X9, X11                      // c461305fda or c5305fda
+	VMAXPS X11, X9, X11                     // c441305fdb
+	VMAXPS (BX), Y15, Y2                    // c4e1045f13 or c5845f13
+	VMAXPS (R11), Y15, Y2                   // c4c1045f13
+	VMAXPS Y2, Y15, Y2                      // c4e1045fd2 or c5845fd2
+	VMAXPS Y11, Y15, Y2                     // c4c1045fd3
+	VMAXPS (BX), Y15, Y11                   // c461045f1b or c5045f1b
+	VMAXPS (R11), Y15, Y11                  // c441045f1b
+	VMAXPS Y2, Y15, Y11                     // c461045fda or c5045fda
+	VMAXPS Y11, Y15, Y11                    // c441045fdb
+	VMAXSD (BX), X9, X2                     // c4e1335f13 or c5b35f13
+	VMAXSD (R11), X9, X2                    // c4c1335f13
+	VMAXSD X2, X9, X2                       // c4e1335fd2 or c5b35fd2
+	VMAXSD X11, X9, X2                      // c4c1335fd3
+	VMAXSD (BX), X9, X11                    // c461335f1b or c5335f1b
+	VMAXSD (R11), X9, X11                   // c441335f1b
+	VMAXSD X2, X9, X11                      // c461335fda or c5335fda
+	VMAXSD X11, X9, X11                     // c441335fdb
+	VMAXSS (BX), X9, X2                     // c4e1325f13 or c5b25f13
+	VMAXSS (R11), X9, X2                    // c4c1325f13
+	VMAXSS X2, X9, X2                       // c4e1325fd2 or c5b25fd2
+	VMAXSS X11, X9, X2                      // c4c1325fd3
+	VMAXSS (BX), X9, X11                    // c461325f1b or c5325f1b
+	VMAXSS (R11), X9, X11                   // c441325f1b
+	VMAXSS X2, X9, X11                      // c461325fda or c5325fda
+	VMAXSS X11, X9, X11                     // c441325fdb
+	VMINPD (BX), X9, X2                     // c4e1315d13 or c5b15d13
+	VMINPD (R11), X9, X2                    // c4c1315d13
+	VMINPD X2, X9, X2                       // c4e1315dd2 or c5b15dd2
+	VMINPD X11, X9, X2                      // c4c1315dd3
+	VMINPD (BX), X9, X11                    // c461315d1b or c5315d1b
+	VMINPD (R11), X9, X11                   // c441315d1b
+	VMINPD X2, X9, X11                      // c461315dda or c5315dda
+	VMINPD X11, X9, X11                     // c441315ddb
+	VMINPD (BX), Y15, Y2                    // c4e1055d13 or c5855d13
+	VMINPD (R11), Y15, Y2                   // c4c1055d13
+	VMINPD Y2, Y15, Y2                      // c4e1055dd2 or c5855dd2
+	VMINPD Y11, Y15, Y2                     // c4c1055dd3
+	VMINPD (BX), Y15, Y11                   // c461055d1b or c5055d1b
+	VMINPD (R11), Y15, Y11                  // c441055d1b
+	VMINPD Y2, Y15, Y11                     // c461055dda or c5055dda
+	VMINPD Y11, Y15, Y11                    // c441055ddb
+	VMINPS (BX), X9, X2                     // c4e1305d13 or c5b05d13
+	VMINPS (R11), X9, X2                    // c4c1305d13
+	VMINPS X2, X9, X2                       // c4e1305dd2 or c5b05dd2
+	VMINPS X11, X9, X2                      // c4c1305dd3
+	VMINPS (BX), X9, X11                    // c461305d1b or c5305d1b
+	VMINPS (R11), X9, X11                   // c441305d1b
+	VMINPS X2, X9, X11                      // c461305dda or c5305dda
+	VMINPS X11, X9, X11                     // c441305ddb
+	VMINPS (BX), Y15, Y2                    // c4e1045d13 or c5845d13
+	VMINPS (R11), Y15, Y2                   // c4c1045d13
+	VMINPS Y2, Y15, Y2                      // c4e1045dd2 or c5845dd2
+	VMINPS Y11, Y15, Y2                     // c4c1045dd3
+	VMINPS (BX), Y15, Y11                   // c461045d1b or c5045d1b
+	VMINPS (R11), Y15, Y11                  // c441045d1b
+	VMINPS Y2, Y15, Y11                     // c461045dda or c5045dda
+	VMINPS Y11, Y15, Y11                    // c441045ddb
+	VMINSD (BX), X9, X2                     // c4e1335d13 or c5b35d13
+	VMINSD (R11), X9, X2                    // c4c1335d13
+	VMINSD X2, X9, X2                       // c4e1335dd2 or c5b35dd2
+	VMINSD X11, X9, X2                      // c4c1335dd3
+	VMINSD (BX), X9, X11                    // c461335d1b or c5335d1b
+	VMINSD (R11), X9, X11                   // c441335d1b
+	VMINSD X2, X9, X11                      // c461335dda or c5335dda
+	VMINSD X11, X9, X11                     // c441335ddb
+	VMINSS (BX), X9, X2                     // c4e1325d13 or c5b25d13
+	VMINSS (R11), X9, X2                    // c4c1325d13
+	VMINSS X2, X9, X2                       // c4e1325dd2 or c5b25dd2
+	VMINSS X11, X9, X2                      // c4c1325dd3
+	VMINSS (BX), X9, X11                    // c461325d1b or c5325d1b
+	VMINSS (R11), X9, X11                   // c441325d1b
+	VMINSS X2, X9, X11                      // c461325dda or c5325dda
+	VMINSS X11, X9, X11                     // c441325ddb
+	VMOVAPD (BX), X2                        // c4e1792813 or c5f92813
+	VMOVAPD (R11), X2                       // c4c1792813
+	VMOVAPD X2, X2                          // c4e17928d2 or c5f928d2 or c4e17929d2 or c5f929d2
+	VMOVAPD X11, X2                         // c4c17928d3 or c4617929da or c57929da
+	VMOVAPD (BX), X11                       // c46179281b or c579281b
+	VMOVAPD (R11), X11                      // c44179281b
+	VMOVAPD X2, X11                         // c4617928da or c57928da or c4c17929d3
+	VMOVAPD X11, X11                        // c4417928db or c4417929db
+	VMOVAPD X2, (BX)                        // c4e1792913 or c5f92913
+	VMOVAPD X11, (BX)                       // c46179291b or c579291b
+	VMOVAPD X2, (R11)                       // c4c1792913
+	VMOVAPD X11, (R11)                      // c44179291b
+	VMOVAPD (BX), Y2                        // c4e17d2813 or c5fd2813
+	VMOVAPD (R11), Y2                       // c4c17d2813
+	VMOVAPD Y2, Y2                          // c4e17d28d2 or c5fd28d2 or c4e17d29d2 or c5fd29d2
+	VMOVAPD Y11, Y2                         // c4c17d28d3 or c4617d29da or c57d29da
+	VMOVAPD (BX), Y11                       // c4617d281b or c57d281b
+	VMOVAPD (R11), Y11                      // c4417d281b
+	VMOVAPD Y2, Y11                         // c4617d28da or c57d28da or c4c17d29d3
+	VMOVAPD Y11, Y11                        // c4417d28db or c4417d29db
+	VMOVAPD Y2, (BX)                        // c4e17d2913 or c5fd2913
+	VMOVAPD Y11, (BX)                       // c4617d291b or c57d291b
+	VMOVAPD Y2, (R11)                       // c4c17d2913
+	VMOVAPD Y11, (R11)                      // c4417d291b
+	VMOVAPS (BX), X2                        // c4e1782813 or c5f82813
+	VMOVAPS (R11), X2                       // c4c1782813
+	VMOVAPS X2, X2                          // c4e17828d2 or c5f828d2 or c4e17829d2 or c5f829d2
+	VMOVAPS X11, X2                         // c4c17828d3 or c4617829da or c57829da
+	VMOVAPS (BX), X11                       // c46178281b or c578281b
+	VMOVAPS (R11), X11                      // c44178281b
+	VMOVAPS X2, X11                         // c4617828da or c57828da or c4c17829d3
+	VMOVAPS X11, X11                        // c4417828db or c4417829db
+	VMOVAPS X2, (BX)                        // c4e1782913 or c5f82913
+	VMOVAPS X11, (BX)                       // c46178291b or c578291b
+	VMOVAPS X2, (R11)                       // c4c1782913
+	VMOVAPS X11, (R11)                      // c44178291b
+	VMOVAPS (BX), Y2                        // c4e17c2813 or c5fc2813
+	VMOVAPS (R11), Y2                       // c4c17c2813
+	VMOVAPS Y2, Y2                          // c4e17c28d2 or c5fc28d2 or c4e17c29d2 or c5fc29d2
+	VMOVAPS Y11, Y2                         // c4c17c28d3 or c4617c29da or c57c29da
+	VMOVAPS (BX), Y11                       // c4617c281b or c57c281b
+	VMOVAPS (R11), Y11                      // c4417c281b
+	VMOVAPS Y2, Y11                         // c4617c28da or c57c28da or c4c17c29d3
+	VMOVAPS Y11, Y11                        // c4417c28db or c4417c29db
+	VMOVAPS Y2, (BX)                        // c4e17c2913 or c5fc2913
+	VMOVAPS Y11, (BX)                       // c4617c291b or c57c291b
+	VMOVAPS Y2, (R11)                       // c4c17c2913
+	VMOVAPS Y11, (R11)                      // c4417c291b
+	VMOVD X2, (BX)                          // c4e1797e13 or c5f97e13
+	VMOVD X11, (BX)                         // c461797e1b or c5797e1b
+	VMOVD X2, (R11)                         // c4c1797e13
+	VMOVD X11, (R11)                        // c441797e1b
+	VMOVD X2, DX                            // c4e1797ed2 or c5f97ed2
+	VMOVD X11, DX                           // c461797eda or c5797eda
+	VMOVD X2, R11                           // c4c1797ed3
+	VMOVD X11, R11                          // c441797edb
+	VMOVD (BX), X2                          // c4e1796e13 or c5f96e13
+	VMOVD (R11), X2                         // c4c1796e13
+	VMOVD DX, X2                            // c4e1796ed2 or c5f96ed2
+	VMOVD R11, X2                           // c4c1796ed3
+	VMOVD (BX), X11                         // c461796e1b or c5796e1b
+	VMOVD (R11), X11                        // c441796e1b
+	VMOVD DX, X11                           // c461796eda or c5796eda
+	VMOVD R11, X11                          // c441796edb
 	VMOVDDUP (BX), X2                       // c4e17b1213 or c5fb1213
 	VMOVDDUP (R11), X2                      // c4c17b1213
 	VMOVDDUP X2, X2                         // c4e17b12d2 or c5fb12d2
@@ -7708,62 +7708,62 @@
 	VMOVDQU Y11, (BX)                       // c4617e7f1b or c57e7f1b
 	VMOVDQU Y2, (R11)                       // c4c17e7f13
 	VMOVDQU Y11, (R11)                      // c4417e7f1b
-	//TODO: VMOVHLPS X2, X9, X2             // c4e13012d2 or c5b012d2
-	//TODO: VMOVHLPS X11, X9, X2            // c4c13012d3
-	//TODO: VMOVHLPS X2, X9, X11            // c4613012da or c53012da
-	//TODO: VMOVHLPS X11, X9, X11           // c4413012db
-	//TODO: VMOVHPD X2, (BX)                // c4e1791713 or c5f91713
-	//TODO: VMOVHPD X11, (BX)               // c46179171b or c579171b
-	//TODO: VMOVHPD X2, (R11)               // c4c1791713
-	//TODO: VMOVHPD X11, (R11)              // c44179171b
-	//TODO: VMOVHPD (BX), X9, X2            // c4e1311613 or c5b11613
-	//TODO: VMOVHPD (R11), X9, X2           // c4c1311613
-	//TODO: VMOVHPD (BX), X9, X11           // c46131161b or c531161b
-	//TODO: VMOVHPD (R11), X9, X11          // c44131161b
-	//TODO: VMOVHPS X2, (BX)                // c4e1781713 or c5f81713
-	//TODO: VMOVHPS X11, (BX)               // c46178171b or c578171b
-	//TODO: VMOVHPS X2, (R11)               // c4c1781713
-	//TODO: VMOVHPS X11, (R11)              // c44178171b
-	//TODO: VMOVHPS (BX), X9, X2            // c4e1301613 or c5b01613
-	//TODO: VMOVHPS (R11), X9, X2           // c4c1301613
-	//TODO: VMOVHPS (BX), X9, X11           // c46130161b or c530161b
-	//TODO: VMOVHPS (R11), X9, X11          // c44130161b
-	//TODO: VMOVLHPS X2, X9, X2             // c4e13016d2 or c5b016d2
-	//TODO: VMOVLHPS X11, X9, X2            // c4c13016d3
-	//TODO: VMOVLHPS X2, X9, X11            // c4613016da or c53016da
-	//TODO: VMOVLHPS X11, X9, X11           // c4413016db
-	//TODO: VMOVLPD X2, (BX)                // c4e1791313 or c5f91313
-	//TODO: VMOVLPD X11, (BX)               // c46179131b or c579131b
-	//TODO: VMOVLPD X2, (R11)               // c4c1791313
-	//TODO: VMOVLPD X11, (R11)              // c44179131b
-	//TODO: VMOVLPD (BX), X9, X2            // c4e1311213 or c5b11213
-	//TODO: VMOVLPD (R11), X9, X2           // c4c1311213
-	//TODO: VMOVLPD (BX), X9, X11           // c46131121b or c531121b
-	//TODO: VMOVLPD (R11), X9, X11          // c44131121b
-	//TODO: VMOVLPS X2, (BX)                // c4e1781313 or c5f81313
-	//TODO: VMOVLPS X11, (BX)               // c46178131b or c578131b
-	//TODO: VMOVLPS X2, (R11)               // c4c1781313
-	//TODO: VMOVLPS X11, (R11)              // c44178131b
-	//TODO: VMOVLPS (BX), X9, X2            // c4e1301213 or c5b01213
-	//TODO: VMOVLPS (R11), X9, X2           // c4c1301213
-	//TODO: VMOVLPS (BX), X9, X11           // c46130121b or c530121b
-	//TODO: VMOVLPS (R11), X9, X11          // c44130121b
-	//TODO: VMOVMSKPD X2, DX                // c4e17950d2 or c5f950d2
-	//TODO: VMOVMSKPD X11, DX               // c4c17950d3
-	//TODO: VMOVMSKPD X2, R11               // c4617950da or c57950da
-	//TODO: VMOVMSKPD X11, R11              // c4417950db
-	//TODO: VMOVMSKPD Y2, DX                // c4e17d50d2 or c5fd50d2
-	//TODO: VMOVMSKPD Y11, DX               // c4c17d50d3
-	//TODO: VMOVMSKPD Y2, R11               // c4617d50da or c57d50da
-	//TODO: VMOVMSKPD Y11, R11              // c4417d50db
-	//TODO: VMOVMSKPS X2, DX                // c4e17850d2 or c5f850d2
-	//TODO: VMOVMSKPS X11, DX               // c4c17850d3
-	//TODO: VMOVMSKPS X2, R11               // c4617850da or c57850da
-	//TODO: VMOVMSKPS X11, R11              // c4417850db
-	//TODO: VMOVMSKPS Y2, DX                // c4e17c50d2 or c5fc50d2
-	//TODO: VMOVMSKPS Y11, DX               // c4c17c50d3
-	//TODO: VMOVMSKPS Y2, R11               // c4617c50da or c57c50da
-	//TODO: VMOVMSKPS Y11, R11              // c4417c50db
+	VMOVHLPS X2, X9, X2                     // c4e13012d2 or c5b012d2
+	VMOVHLPS X11, X9, X2                    // c4c13012d3
+	VMOVHLPS X2, X9, X11                    // c4613012da or c53012da
+	VMOVHLPS X11, X9, X11                   // c4413012db
+	VMOVHPD X2, (BX)                        // c4e1791713 or c5f91713
+	VMOVHPD X11, (BX)                       // c46179171b or c579171b
+	VMOVHPD X2, (R11)                       // c4c1791713
+	VMOVHPD X11, (R11)                      // c44179171b
+	VMOVHPD (BX), X9, X2                    // c4e1311613 or c5b11613
+	VMOVHPD (R11), X9, X2                   // c4c1311613
+	VMOVHPD (BX), X9, X11                   // c46131161b or c531161b
+	VMOVHPD (R11), X9, X11                  // c44131161b
+	VMOVHPS X2, (BX)                        // c4e1781713 or c5f81713
+	VMOVHPS X11, (BX)                       // c46178171b or c578171b
+	VMOVHPS X2, (R11)                       // c4c1781713
+	VMOVHPS X11, (R11)                      // c44178171b
+	VMOVHPS (BX), X9, X2                    // c4e1301613 or c5b01613
+	VMOVHPS (R11), X9, X2                   // c4c1301613
+	VMOVHPS (BX), X9, X11                   // c46130161b or c530161b
+	VMOVHPS (R11), X9, X11                  // c44130161b
+	VMOVLHPS X2, X9, X2                     // c4e13016d2 or c5b016d2
+	VMOVLHPS X11, X9, X2                    // c4c13016d3
+	VMOVLHPS X2, X9, X11                    // c4613016da or c53016da
+	VMOVLHPS X11, X9, X11                   // c4413016db
+	VMOVLPD X2, (BX)                        // c4e1791313 or c5f91313
+	VMOVLPD X11, (BX)                       // c46179131b or c579131b
+	VMOVLPD X2, (R11)                       // c4c1791313
+	VMOVLPD X11, (R11)                      // c44179131b
+	VMOVLPD (BX), X9, X2                    // c4e1311213 or c5b11213
+	VMOVLPD (R11), X9, X2                   // c4c1311213
+	VMOVLPD (BX), X9, X11                   // c46131121b or c531121b
+	VMOVLPD (R11), X9, X11                  // c44131121b
+	VMOVLPS X2, (BX)                        // c4e1781313 or c5f81313
+	VMOVLPS X11, (BX)                       // c46178131b or c578131b
+	VMOVLPS X2, (R11)                       // c4c1781313
+	VMOVLPS X11, (R11)                      // c44178131b
+	VMOVLPS (BX), X9, X2                    // c4e1301213 or c5b01213
+	VMOVLPS (R11), X9, X2                   // c4c1301213
+	VMOVLPS (BX), X9, X11                   // c46130121b or c530121b
+	VMOVLPS (R11), X9, X11                  // c44130121b
+	VMOVMSKPD X2, DX                        // c4e17950d2 or c5f950d2
+	VMOVMSKPD X11, DX                       // c4c17950d3
+	VMOVMSKPD X2, R11                       // c4617950da or c57950da
+	VMOVMSKPD X11, R11                      // c4417950db
+	VMOVMSKPD Y2, DX                        // c4e17d50d2 or c5fd50d2
+	VMOVMSKPD Y11, DX                       // c4c17d50d3
+	VMOVMSKPD Y2, R11                       // c4617d50da or c57d50da
+	VMOVMSKPD Y11, R11                      // c4417d50db
+	VMOVMSKPS X2, DX                        // c4e17850d2 or c5f850d2
+	VMOVMSKPS X11, DX                       // c4c17850d3
+	VMOVMSKPS X2, R11                       // c4617850da or c57850da
+	VMOVMSKPS X11, R11                      // c4417850db
+	VMOVMSKPS Y2, DX                        // c4e17c50d2 or c5fc50d2
+	VMOVMSKPS Y11, DX                       // c4c17c50d3
+	VMOVMSKPS Y2, R11                       // c4617c50da or c57c50da
+	VMOVMSKPS Y11, R11                      // c4417c50db
 	VMOVNTDQ X2, (BX)                       // c4e179e713 or c5f9e713
 	VMOVNTDQ X11, (BX)                      // c46179e71b or c579e71b
 	VMOVNTDQ X2, (R11)                      // c4c179e713
@@ -7772,62 +7772,62 @@
 	VMOVNTDQ Y11, (BX)                      // c4617de71b or c57de71b
 	VMOVNTDQ Y2, (R11)                      // c4c17de713
 	VMOVNTDQ Y11, (R11)                     // c4417de71b
-	//TODO: VMOVNTDQA (BX), X2              // c4e2792a13
-	//TODO: VMOVNTDQA (R11), X2             // c4c2792a13
-	//TODO: VMOVNTDQA (BX), X11             // c462792a1b
-	//TODO: VMOVNTDQA (R11), X11            // c442792a1b
-	//TODO: VMOVNTDQA (BX), Y2              // c4e27d2a13
-	//TODO: VMOVNTDQA (R11), Y2             // c4c27d2a13
-	//TODO: VMOVNTDQA (BX), Y11             // c4627d2a1b
-	//TODO: VMOVNTDQA (R11), Y11            // c4427d2a1b
-	//TODO: VMOVNTPD X2, (BX)               // c4e1792b13 or c5f92b13
-	//TODO: VMOVNTPD X11, (BX)              // c461792b1b or c5792b1b
-	//TODO: VMOVNTPD X2, (R11)              // c4c1792b13
-	//TODO: VMOVNTPD X11, (R11)             // c441792b1b
-	//TODO: VMOVNTPD Y2, (BX)               // c4e17d2b13 or c5fd2b13
-	//TODO: VMOVNTPD Y11, (BX)              // c4617d2b1b or c57d2b1b
-	//TODO: VMOVNTPD Y2, (R11)              // c4c17d2b13
-	//TODO: VMOVNTPD Y11, (R11)             // c4417d2b1b
-	//TODO: VMOVNTPS X2, (BX)               // c4e1782b13 or c5f82b13
-	//TODO: VMOVNTPS X11, (BX)              // c461782b1b or c5782b1b
-	//TODO: VMOVNTPS X2, (R11)              // c4c1782b13
-	//TODO: VMOVNTPS X11, (R11)             // c441782b1b
-	//TODO: VMOVNTPS Y2, (BX)               // c4e17c2b13 or c5fc2b13
-	//TODO: VMOVNTPS Y11, (BX)              // c4617c2b1b or c57c2b1b
-	//TODO: VMOVNTPS Y2, (R11)              // c4c17c2b13
-	//TODO: VMOVNTPS Y11, (R11)             // c4417c2b1b
-	//TODO: VMOVQ X2, (BX)                  // c4e1f97e13 or c4e179d613 or c5f9d613
-	//TODO: VMOVQ X11, (BX)                 // c461f97e1b or c46179d61b or c579d61b
-	//TODO: VMOVQ X2, (R11)                 // c4c1f97e13 or c4c179d613
-	//TODO: VMOVQ X11, (R11)                // c441f97e1b or c44179d61b
-	//TODO: VMOVQ X2, DX                    // c4e1f97ed2
-	//TODO: VMOVQ X11, DX                   // c461f97eda
-	//TODO: VMOVQ X2, R11                   // c4c1f97ed3
-	//TODO: VMOVQ X11, R11                  // c441f97edb
-	//TODO: VMOVQ (BX), X2                  // c4e17a7e13 or c5fa7e13 or c4e1f96e13
-	//TODO: VMOVQ (R11), X2                 // c4c17a7e13 or c4c1f96e13
-	//TODO: VMOVQ (BX), X11                 // c4617a7e1b or c57a7e1b or c461f96e1b
-	//TODO: VMOVQ (R11), X11                // c4417a7e1b or c441f96e1b
-	//TODO: VMOVQ DX, X2                    // c4e1f96ed2
-	//TODO: VMOVQ R11, X2                   // c4c1f96ed3
-	//TODO: VMOVQ DX, X11                   // c461f96eda
-	//TODO: VMOVQ R11, X11                  // c441f96edb
-	//TODO: VMOVQ X2, X2                    // c4e17a7ed2 or c5fa7ed2 or c4e179d6d2 or c5f9d6d2
-	//TODO: VMOVQ X11, X2                   // c4c17a7ed3 or c46179d6da or c579d6da
-	//TODO: VMOVQ X2, X11                   // c4617a7eda or c57a7eda or c4c179d6d3
-	//TODO: VMOVQ X11, X11                  // c4417a7edb or c44179d6db
-	//TODO: VMOVSD X2, (BX)                 // c4e17b1113 or c5fb1113
-	//TODO: VMOVSD X11, (BX)                // c4617b111b or c57b111b
-	//TODO: VMOVSD X2, (R11)                // c4c17b1113
-	//TODO: VMOVSD X11, (R11)               // c4417b111b
-	//TODO: VMOVSD (BX), X2                 // c4e17b1013 or c5fb1013
-	//TODO: VMOVSD (R11), X2                // c4c17b1013
-	//TODO: VMOVSD (BX), X11                // c4617b101b or c57b101b
-	//TODO: VMOVSD (R11), X11               // c4417b101b
-	//TODO: VMOVSD X2, X9, X2               // c4e13310d2 or c5b310d2 or c4e13311d2 or c5b311d2
-	//TODO: VMOVSD X11, X9, X2              // c4c13310d3 or c4613311da or c53311da
-	//TODO: VMOVSD X2, X9, X11              // c4613310da or c53310da or c4c13311d3
-	//TODO: VMOVSD X11, X9, X11             // c4413310db or c4413311db
+	VMOVNTDQA (BX), X2                      // c4e2792a13
+	VMOVNTDQA (R11), X2                     // c4c2792a13
+	VMOVNTDQA (BX), X11                     // c462792a1b
+	VMOVNTDQA (R11), X11                    // c442792a1b
+	VMOVNTDQA (BX), Y2                      // c4e27d2a13
+	VMOVNTDQA (R11), Y2                     // c4c27d2a13
+	VMOVNTDQA (BX), Y11                     // c4627d2a1b
+	VMOVNTDQA (R11), Y11                    // c4427d2a1b
+	VMOVNTPD X2, (BX)                       // c4e1792b13 or c5f92b13
+	VMOVNTPD X11, (BX)                      // c461792b1b or c5792b1b
+	VMOVNTPD X2, (R11)                      // c4c1792b13
+	VMOVNTPD X11, (R11)                     // c441792b1b
+	VMOVNTPD Y2, (BX)                       // c4e17d2b13 or c5fd2b13
+	VMOVNTPD Y11, (BX)                      // c4617d2b1b or c57d2b1b
+	VMOVNTPD Y2, (R11)                      // c4c17d2b13
+	VMOVNTPD Y11, (R11)                     // c4417d2b1b
+	VMOVNTPS X2, (BX)                       // c4e1782b13 or c5f82b13
+	VMOVNTPS X11, (BX)                      // c461782b1b or c5782b1b
+	VMOVNTPS X2, (R11)                      // c4c1782b13
+	VMOVNTPS X11, (R11)                     // c441782b1b
+	VMOVNTPS Y2, (BX)                       // c4e17c2b13 or c5fc2b13
+	VMOVNTPS Y11, (BX)                      // c4617c2b1b or c57c2b1b
+	VMOVNTPS Y2, (R11)                      // c4c17c2b13
+	VMOVNTPS Y11, (R11)                     // c4417c2b1b
+	VMOVQ X2, (BX)                          // c4e1f97e13 or c4e179d613 or c5f9d613
+	VMOVQ X11, (BX)                         // c461f97e1b or c46179d61b or c579d61b
+	VMOVQ X2, (R11)                         // c4c1f97e13 or c4c179d613
+	VMOVQ X11, (R11)                        // c441f97e1b or c44179d61b
+	VMOVQ X2, DX                            // c4e1f97ed2
+	VMOVQ X11, DX                           // c461f97eda
+	VMOVQ X2, R11                           // c4c1f97ed3
+	VMOVQ X11, R11                          // c441f97edb
+	VMOVQ (BX), X2                          // c4e17a7e13 or c5fa7e13 or c4e1f96e13
+	VMOVQ (R11), X2                         // c4c17a7e13 or c4c1f96e13
+	VMOVQ (BX), X11                         // c4617a7e1b or c57a7e1b or c461f96e1b
+	VMOVQ (R11), X11                        // c4417a7e1b or c441f96e1b
+	VMOVQ DX, X2                            // c4e1f96ed2
+	VMOVQ R11, X2                           // c4c1f96ed3
+	VMOVQ DX, X11                           // c461f96eda
+	VMOVQ R11, X11                          // c441f96edb
+	VMOVQ X2, X2                            // c4e17a7ed2 or c5fa7ed2 or c4e179d6d2 or c5f9d6d2
+	VMOVQ X11, X2                           // c4c17a7ed3 or c46179d6da or c579d6da
+	VMOVQ X2, X11                           // c4617a7eda or c57a7eda or c4c179d6d3
+	VMOVQ X11, X11                          // c4417a7edb or c44179d6db
+	VMOVSD X2, (BX)                         // c4e17b1113 or c5fb1113
+	VMOVSD X11, (BX)                        // c4617b111b or c57b111b
+	VMOVSD X2, (R11)                        // c4c17b1113
+	VMOVSD X11, (R11)                       // c4417b111b
+	VMOVSD (BX), X2                         // c4e17b1013 or c5fb1013
+	VMOVSD (R11), X2                        // c4c17b1013
+	VMOVSD (BX), X11                        // c4617b101b or c57b101b
+	VMOVSD (R11), X11                       // c4417b101b
+	VMOVSD X2, X9, X2                       // c4e13310d2 or c5b310d2 or c4e13311d2 or c5b311d2
+	VMOVSD X11, X9, X2                      // c4c13310d3 or c4613311da or c53311da
+	VMOVSD X2, X9, X11                      // c4613310da or c53310da or c4c13311d3
+	VMOVSD X11, X9, X11                     // c4413310db or c4413311db
 	VMOVSHDUP (BX), X2                      // c4e17a1613 or c5fa1613
 	VMOVSHDUP (R11), X2                     // c4c17a1613
 	VMOVSHDUP X2, X2                        // c4e17a16d2 or c5fa16d2
@@ -7860,290 +7860,290 @@
 	VMOVSLDUP (R11), Y11                    // c4417e121b
 	VMOVSLDUP Y2, Y11                       // c4617e12da or c57e12da
 	VMOVSLDUP Y11, Y11                      // c4417e12db
-	//TODO: VMOVSS X2, (BX)                 // c4e17a1113 or c5fa1113
-	//TODO: VMOVSS X11, (BX)                // c4617a111b or c57a111b
-	//TODO: VMOVSS X2, (R11)                // c4c17a1113
-	//TODO: VMOVSS X11, (R11)               // c4417a111b
-	//TODO: VMOVSS (BX), X2                 // c4e17a1013 or c5fa1013
-	//TODO: VMOVSS (R11), X2                // c4c17a1013
-	//TODO: VMOVSS (BX), X11                // c4617a101b or c57a101b
-	//TODO: VMOVSS (R11), X11               // c4417a101b
-	//TODO: VMOVSS X2, X9, X2               // c4e13210d2 or c5b210d2 or c4e13211d2 or c5b211d2
-	//TODO: VMOVSS X11, X9, X2              // c4c13210d3 or c4613211da or c53211da
-	//TODO: VMOVSS X2, X9, X11              // c4613210da or c53210da or c4c13211d3
-	//TODO: VMOVSS X11, X9, X11             // c4413210db or c4413211db
-	//TODO: VMOVUPD (BX), X2                // c4e1791013 or c5f91013
-	//TODO: VMOVUPD (R11), X2               // c4c1791013
-	//TODO: VMOVUPD X2, X2                  // c4e17910d2 or c5f910d2 or c4e17911d2 or c5f911d2
-	//TODO: VMOVUPD X11, X2                 // c4c17910d3 or c4617911da or c57911da
-	//TODO: VMOVUPD (BX), X11               // c46179101b or c579101b
-	//TODO: VMOVUPD (R11), X11              // c44179101b
-	//TODO: VMOVUPD X2, X11                 // c4617910da or c57910da or c4c17911d3
-	//TODO: VMOVUPD X11, X11                // c4417910db or c4417911db
-	//TODO: VMOVUPD X2, (BX)                // c4e1791113 or c5f91113
-	//TODO: VMOVUPD X11, (BX)               // c46179111b or c579111b
-	//TODO: VMOVUPD X2, (R11)               // c4c1791113
-	//TODO: VMOVUPD X11, (R11)              // c44179111b
-	//TODO: VMOVUPD (BX), Y2                // c4e17d1013 or c5fd1013
-	//TODO: VMOVUPD (R11), Y2               // c4c17d1013
-	//TODO: VMOVUPD Y2, Y2                  // c4e17d10d2 or c5fd10d2 or c4e17d11d2 or c5fd11d2
-	//TODO: VMOVUPD Y11, Y2                 // c4c17d10d3 or c4617d11da or c57d11da
-	//TODO: VMOVUPD (BX), Y11               // c4617d101b or c57d101b
-	//TODO: VMOVUPD (R11), Y11              // c4417d101b
-	//TODO: VMOVUPD Y2, Y11                 // c4617d10da or c57d10da or c4c17d11d3
-	//TODO: VMOVUPD Y11, Y11                // c4417d10db or c4417d11db
-	//TODO: VMOVUPD Y2, (BX)                // c4e17d1113 or c5fd1113
-	//TODO: VMOVUPD Y11, (BX)               // c4617d111b or c57d111b
-	//TODO: VMOVUPD Y2, (R11)               // c4c17d1113
-	//TODO: VMOVUPD Y11, (R11)              // c4417d111b
-	//TODO: VMOVUPS (BX), X2                // c4e1781013 or c5f81013
-	//TODO: VMOVUPS (R11), X2               // c4c1781013
-	//TODO: VMOVUPS X2, X2                  // c4e17810d2 or c5f810d2 or c4e17811d2 or c5f811d2
-	//TODO: VMOVUPS X11, X2                 // c4c17810d3 or c4617811da or c57811da
-	//TODO: VMOVUPS (BX), X11               // c46178101b or c578101b
-	//TODO: VMOVUPS (R11), X11              // c44178101b
-	//TODO: VMOVUPS X2, X11                 // c4617810da or c57810da or c4c17811d3
-	//TODO: VMOVUPS X11, X11                // c4417810db or c4417811db
-	//TODO: VMOVUPS X2, (BX)                // c4e1781113 or c5f81113
-	//TODO: VMOVUPS X11, (BX)               // c46178111b or c578111b
-	//TODO: VMOVUPS X2, (R11)               // c4c1781113
-	//TODO: VMOVUPS X11, (R11)              // c44178111b
-	//TODO: VMOVUPS (BX), Y2                // c4e17c1013 or c5fc1013
-	//TODO: VMOVUPS (R11), Y2               // c4c17c1013
-	//TODO: VMOVUPS Y2, Y2                  // c4e17c10d2 or c5fc10d2 or c4e17c11d2 or c5fc11d2
-	//TODO: VMOVUPS Y11, Y2                 // c4c17c10d3 or c4617c11da or c57c11da
-	//TODO: VMOVUPS (BX), Y11               // c4617c101b or c57c101b
-	//TODO: VMOVUPS (R11), Y11              // c4417c101b
-	//TODO: VMOVUPS Y2, Y11                 // c4617c10da or c57c10da or c4c17c11d3
-	//TODO: VMOVUPS Y11, Y11                // c4417c10db or c4417c11db
-	//TODO: VMOVUPS Y2, (BX)                // c4e17c1113 or c5fc1113
-	//TODO: VMOVUPS Y11, (BX)               // c4617c111b or c57c111b
-	//TODO: VMOVUPS Y2, (R11)               // c4c17c1113
-	//TODO: VMOVUPS Y11, (R11)              // c4417c111b
-	//TODO: VMPSADBW $7, (BX), X9, X2       // c4e331421307
-	//TODO: VMPSADBW $7, (R11), X9, X2      // c4c331421307
-	//TODO: VMPSADBW $7, X2, X9, X2         // c4e33142d207
-	//TODO: VMPSADBW $7, X11, X9, X2        // c4c33142d307
-	//TODO: VMPSADBW $7, (BX), X9, X11      // c46331421b07
-	//TODO: VMPSADBW $7, (R11), X9, X11     // c44331421b07
-	//TODO: VMPSADBW $7, X2, X9, X11        // c4633142da07
-	//TODO: VMPSADBW $7, X11, X9, X11       // c4433142db07
-	//TODO: VMPSADBW $7, (BX), Y15, Y2      // c4e305421307
-	//TODO: VMPSADBW $7, (R11), Y15, Y2     // c4c305421307
-	//TODO: VMPSADBW $7, Y2, Y15, Y2        // c4e30542d207
-	//TODO: VMPSADBW $7, Y11, Y15, Y2       // c4c30542d307
-	//TODO: VMPSADBW $7, (BX), Y15, Y11     // c46305421b07
-	//TODO: VMPSADBW $7, (R11), Y15, Y11    // c44305421b07
-	//TODO: VMPSADBW $7, Y2, Y15, Y11       // c4630542da07
-	//TODO: VMPSADBW $7, Y11, Y15, Y11      // c4430542db07
-	//TODO: VMULPD (BX), X9, X2             // c4e1315913 or c5b15913
-	//TODO: VMULPD (R11), X9, X2            // c4c1315913
-	//TODO: VMULPD X2, X9, X2               // c4e13159d2 or c5b159d2
-	//TODO: VMULPD X11, X9, X2              // c4c13159d3
-	//TODO: VMULPD (BX), X9, X11            // c46131591b or c531591b
-	//TODO: VMULPD (R11), X9, X11           // c44131591b
-	//TODO: VMULPD X2, X9, X11              // c4613159da or c53159da
-	//TODO: VMULPD X11, X9, X11             // c4413159db
-	//TODO: VMULPD (BX), Y15, Y2            // c4e1055913 or c5855913
-	//TODO: VMULPD (R11), Y15, Y2           // c4c1055913
-	//TODO: VMULPD Y2, Y15, Y2              // c4e10559d2 or c58559d2
-	//TODO: VMULPD Y11, Y15, Y2             // c4c10559d3
-	//TODO: VMULPD (BX), Y15, Y11           // c46105591b or c505591b
-	//TODO: VMULPD (R11), Y15, Y11          // c44105591b
-	//TODO: VMULPD Y2, Y15, Y11             // c4610559da or c50559da
-	//TODO: VMULPD Y11, Y15, Y11            // c4410559db
-	//TODO: VMULPS (BX), X9, X2             // c4e1305913 or c5b05913
-	//TODO: VMULPS (R11), X9, X2            // c4c1305913
-	//TODO: VMULPS X2, X9, X2               // c4e13059d2 or c5b059d2
-	//TODO: VMULPS X11, X9, X2              // c4c13059d3
-	//TODO: VMULPS (BX), X9, X11            // c46130591b or c530591b
-	//TODO: VMULPS (R11), X9, X11           // c44130591b
-	//TODO: VMULPS X2, X9, X11              // c4613059da or c53059da
-	//TODO: VMULPS X11, X9, X11             // c4413059db
-	//TODO: VMULPS (BX), Y15, Y2            // c4e1045913 or c5845913
-	//TODO: VMULPS (R11), Y15, Y2           // c4c1045913
-	//TODO: VMULPS Y2, Y15, Y2              // c4e10459d2 or c58459d2
-	//TODO: VMULPS Y11, Y15, Y2             // c4c10459d3
-	//TODO: VMULPS (BX), Y15, Y11           // c46104591b or c504591b
-	//TODO: VMULPS (R11), Y15, Y11          // c44104591b
-	//TODO: VMULPS Y2, Y15, Y11             // c4610459da or c50459da
-	//TODO: VMULPS Y11, Y15, Y11            // c4410459db
-	//TODO: VMULSD (BX), X9, X2             // c4e1335913 or c5b35913
-	//TODO: VMULSD (R11), X9, X2            // c4c1335913
-	//TODO: VMULSD X2, X9, X2               // c4e13359d2 or c5b359d2
-	//TODO: VMULSD X11, X9, X2              // c4c13359d3
-	//TODO: VMULSD (BX), X9, X11            // c46133591b or c533591b
-	//TODO: VMULSD (R11), X9, X11           // c44133591b
-	//TODO: VMULSD X2, X9, X11              // c4613359da or c53359da
-	//TODO: VMULSD X11, X9, X11             // c4413359db
-	//TODO: VMULSS (BX), X9, X2             // c4e1325913 or c5b25913
-	//TODO: VMULSS (R11), X9, X2            // c4c1325913
-	//TODO: VMULSS X2, X9, X2               // c4e13259d2 or c5b259d2
-	//TODO: VMULSS X11, X9, X2              // c4c13259d3
-	//TODO: VMULSS (BX), X9, X11            // c46132591b or c532591b
-	//TODO: VMULSS (R11), X9, X11           // c44132591b
-	//TODO: VMULSS X2, X9, X11              // c4613259da or c53259da
-	//TODO: VMULSS X11, X9, X11             // c4413259db
-	//TODO: VORPD (BX), X9, X2              // c4e1315613 or c5b15613
-	//TODO: VORPD (R11), X9, X2             // c4c1315613
-	//TODO: VORPD X2, X9, X2                // c4e13156d2 or c5b156d2
-	//TODO: VORPD X11, X9, X2               // c4c13156d3
-	//TODO: VORPD (BX), X9, X11             // c46131561b or c531561b
-	//TODO: VORPD (R11), X9, X11            // c44131561b
-	//TODO: VORPD X2, X9, X11               // c4613156da or c53156da
-	//TODO: VORPD X11, X9, X11              // c4413156db
-	//TODO: VORPD (BX), Y15, Y2             // c4e1055613 or c5855613
-	//TODO: VORPD (R11), Y15, Y2            // c4c1055613
-	//TODO: VORPD Y2, Y15, Y2               // c4e10556d2 or c58556d2
-	//TODO: VORPD Y11, Y15, Y2              // c4c10556d3
-	//TODO: VORPD (BX), Y15, Y11            // c46105561b or c505561b
-	//TODO: VORPD (R11), Y15, Y11           // c44105561b
-	//TODO: VORPD Y2, Y15, Y11              // c4610556da or c50556da
-	//TODO: VORPD Y11, Y15, Y11             // c4410556db
-	//TODO: VORPS (BX), X9, X2              // c4e1305613 or c5b05613
-	//TODO: VORPS (R11), X9, X2             // c4c1305613
-	//TODO: VORPS X2, X9, X2                // c4e13056d2 or c5b056d2
-	//TODO: VORPS X11, X9, X2               // c4c13056d3
-	//TODO: VORPS (BX), X9, X11             // c46130561b or c530561b
-	//TODO: VORPS (R11), X9, X11            // c44130561b
-	//TODO: VORPS X2, X9, X11               // c4613056da or c53056da
-	//TODO: VORPS X11, X9, X11              // c4413056db
-	//TODO: VORPS (BX), Y15, Y2             // c4e1045613 or c5845613
-	//TODO: VORPS (R11), Y15, Y2            // c4c1045613
-	//TODO: VORPS Y2, Y15, Y2               // c4e10456d2 or c58456d2
-	//TODO: VORPS Y11, Y15, Y2              // c4c10456d3
-	//TODO: VORPS (BX), Y15, Y11            // c46104561b or c504561b
-	//TODO: VORPS (R11), Y15, Y11           // c44104561b
-	//TODO: VORPS Y2, Y15, Y11              // c4610456da or c50456da
-	//TODO: VORPS Y11, Y15, Y11             // c4410456db
-	//TODO: VPABSB (BX), X2                 // c4e2791c13
-	//TODO: VPABSB (R11), X2                // c4c2791c13
-	//TODO: VPABSB X2, X2                   // c4e2791cd2
-	//TODO: VPABSB X11, X2                  // c4c2791cd3
-	//TODO: VPABSB (BX), X11                // c462791c1b
-	//TODO: VPABSB (R11), X11               // c442791c1b
-	//TODO: VPABSB X2, X11                  // c462791cda
-	//TODO: VPABSB X11, X11                 // c442791cdb
-	//TODO: VPABSB (BX), Y2                 // c4e27d1c13
-	//TODO: VPABSB (R11), Y2                // c4c27d1c13
-	//TODO: VPABSB Y2, Y2                   // c4e27d1cd2
-	//TODO: VPABSB Y11, Y2                  // c4c27d1cd3
-	//TODO: VPABSB (BX), Y11                // c4627d1c1b
-	//TODO: VPABSB (R11), Y11               // c4427d1c1b
-	//TODO: VPABSB Y2, Y11                  // c4627d1cda
-	//TODO: VPABSB Y11, Y11                 // c4427d1cdb
-	//TODO: VPABSD (BX), X2                 // c4e2791e13
-	//TODO: VPABSD (R11), X2                // c4c2791e13
-	//TODO: VPABSD X2, X2                   // c4e2791ed2
-	//TODO: VPABSD X11, X2                  // c4c2791ed3
-	//TODO: VPABSD (BX), X11                // c462791e1b
-	//TODO: VPABSD (R11), X11               // c442791e1b
-	//TODO: VPABSD X2, X11                  // c462791eda
-	//TODO: VPABSD X11, X11                 // c442791edb
-	//TODO: VPABSD (BX), Y2                 // c4e27d1e13
-	//TODO: VPABSD (R11), Y2                // c4c27d1e13
-	//TODO: VPABSD Y2, Y2                   // c4e27d1ed2
-	//TODO: VPABSD Y11, Y2                  // c4c27d1ed3
-	//TODO: VPABSD (BX), Y11                // c4627d1e1b
-	//TODO: VPABSD (R11), Y11               // c4427d1e1b
-	//TODO: VPABSD Y2, Y11                  // c4627d1eda
-	//TODO: VPABSD Y11, Y11                 // c4427d1edb
-	//TODO: VPABSW (BX), X2                 // c4e2791d13
-	//TODO: VPABSW (R11), X2                // c4c2791d13
-	//TODO: VPABSW X2, X2                   // c4e2791dd2
-	//TODO: VPABSW X11, X2                  // c4c2791dd3
-	//TODO: VPABSW (BX), X11                // c462791d1b
-	//TODO: VPABSW (R11), X11               // c442791d1b
-	//TODO: VPABSW X2, X11                  // c462791dda
-	//TODO: VPABSW X11, X11                 // c442791ddb
-	//TODO: VPABSW (BX), Y2                 // c4e27d1d13
-	//TODO: VPABSW (R11), Y2                // c4c27d1d13
-	//TODO: VPABSW Y2, Y2                   // c4e27d1dd2
-	//TODO: VPABSW Y11, Y2                  // c4c27d1dd3
-	//TODO: VPABSW (BX), Y11                // c4627d1d1b
-	//TODO: VPABSW (R11), Y11               // c4427d1d1b
-	//TODO: VPABSW Y2, Y11                  // c4627d1dda
-	//TODO: VPABSW Y11, Y11                 // c4427d1ddb
-	//TODO: VPACKSSDW (BX), X9, X2          // c4e1316b13 or c5b16b13
-	//TODO: VPACKSSDW (R11), X9, X2         // c4c1316b13
-	//TODO: VPACKSSDW X2, X9, X2            // c4e1316bd2 or c5b16bd2
-	//TODO: VPACKSSDW X11, X9, X2           // c4c1316bd3
-	//TODO: VPACKSSDW (BX), X9, X11         // c461316b1b or c5316b1b
-	//TODO: VPACKSSDW (R11), X9, X11        // c441316b1b
-	//TODO: VPACKSSDW X2, X9, X11           // c461316bda or c5316bda
-	//TODO: VPACKSSDW X11, X9, X11          // c441316bdb
-	//TODO: VPACKSSDW (BX), Y15, Y2         // c4e1056b13 or c5856b13
-	//TODO: VPACKSSDW (R11), Y15, Y2        // c4c1056b13
-	//TODO: VPACKSSDW Y2, Y15, Y2           // c4e1056bd2 or c5856bd2
-	//TODO: VPACKSSDW Y11, Y15, Y2          // c4c1056bd3
-	//TODO: VPACKSSDW (BX), Y15, Y11        // c461056b1b or c5056b1b
-	//TODO: VPACKSSDW (R11), Y15, Y11       // c441056b1b
-	//TODO: VPACKSSDW Y2, Y15, Y11          // c461056bda or c5056bda
-	//TODO: VPACKSSDW Y11, Y15, Y11         // c441056bdb
-	//TODO: VPACKSSWB (BX), X9, X2          // c4e1316313 or c5b16313
-	//TODO: VPACKSSWB (R11), X9, X2         // c4c1316313
-	//TODO: VPACKSSWB X2, X9, X2            // c4e13163d2 or c5b163d2
-	//TODO: VPACKSSWB X11, X9, X2           // c4c13163d3
-	//TODO: VPACKSSWB (BX), X9, X11         // c46131631b or c531631b
-	//TODO: VPACKSSWB (R11), X9, X11        // c44131631b
-	//TODO: VPACKSSWB X2, X9, X11           // c4613163da or c53163da
-	//TODO: VPACKSSWB X11, X9, X11          // c4413163db
-	//TODO: VPACKSSWB (BX), Y15, Y2         // c4e1056313 or c5856313
-	//TODO: VPACKSSWB (R11), Y15, Y2        // c4c1056313
-	//TODO: VPACKSSWB Y2, Y15, Y2           // c4e10563d2 or c58563d2
-	//TODO: VPACKSSWB Y11, Y15, Y2          // c4c10563d3
-	//TODO: VPACKSSWB (BX), Y15, Y11        // c46105631b or c505631b
-	//TODO: VPACKSSWB (R11), Y15, Y11       // c44105631b
-	//TODO: VPACKSSWB Y2, Y15, Y11          // c4610563da or c50563da
-	//TODO: VPACKSSWB Y11, Y15, Y11         // c4410563db
-	//TODO: VPACKUSDW (BX), X9, X2          // c4e2312b13
-	//TODO: VPACKUSDW (R11), X9, X2         // c4c2312b13
-	//TODO: VPACKUSDW X2, X9, X2            // c4e2312bd2
-	//TODO: VPACKUSDW X11, X9, X2           // c4c2312bd3
-	//TODO: VPACKUSDW (BX), X9, X11         // c462312b1b
-	//TODO: VPACKUSDW (R11), X9, X11        // c442312b1b
-	//TODO: VPACKUSDW X2, X9, X11           // c462312bda
-	//TODO: VPACKUSDW X11, X9, X11          // c442312bdb
-	//TODO: VPACKUSDW (BX), Y15, Y2         // c4e2052b13
-	//TODO: VPACKUSDW (R11), Y15, Y2        // c4c2052b13
-	//TODO: VPACKUSDW Y2, Y15, Y2           // c4e2052bd2
-	//TODO: VPACKUSDW Y11, Y15, Y2          // c4c2052bd3
-	//TODO: VPACKUSDW (BX), Y15, Y11        // c462052b1b
-	//TODO: VPACKUSDW (R11), Y15, Y11       // c442052b1b
-	//TODO: VPACKUSDW Y2, Y15, Y11          // c462052bda
-	//TODO: VPACKUSDW Y11, Y15, Y11         // c442052bdb
-	//TODO: VPACKUSWB (BX), X9, X2          // c4e1316713 or c5b16713
-	//TODO: VPACKUSWB (R11), X9, X2         // c4c1316713
-	//TODO: VPACKUSWB X2, X9, X2            // c4e13167d2 or c5b167d2
-	//TODO: VPACKUSWB X11, X9, X2           // c4c13167d3
-	//TODO: VPACKUSWB (BX), X9, X11         // c46131671b or c531671b
-	//TODO: VPACKUSWB (R11), X9, X11        // c44131671b
-	//TODO: VPACKUSWB X2, X9, X11           // c4613167da or c53167da
-	//TODO: VPACKUSWB X11, X9, X11          // c4413167db
-	//TODO: VPACKUSWB (BX), Y15, Y2         // c4e1056713 or c5856713
-	//TODO: VPACKUSWB (R11), Y15, Y2        // c4c1056713
-	//TODO: VPACKUSWB Y2, Y15, Y2           // c4e10567d2 or c58567d2
-	//TODO: VPACKUSWB Y11, Y15, Y2          // c4c10567d3
-	//TODO: VPACKUSWB (BX), Y15, Y11        // c46105671b or c505671b
-	//TODO: VPACKUSWB (R11), Y15, Y11       // c44105671b
-	//TODO: VPACKUSWB Y2, Y15, Y11          // c4610567da or c50567da
-	//TODO: VPACKUSWB Y11, Y15, Y11         // c4410567db
-	//TODO: VPADDB (BX), X9, X2             // c4e131fc13 or c5b1fc13
-	//TODO: VPADDB (R11), X9, X2            // c4c131fc13
-	//TODO: VPADDB X2, X9, X2               // c4e131fcd2 or c5b1fcd2
-	//TODO: VPADDB X11, X9, X2              // c4c131fcd3
-	//TODO: VPADDB (BX), X9, X11            // c46131fc1b or c531fc1b
-	//TODO: VPADDB (R11), X9, X11           // c44131fc1b
-	//TODO: VPADDB X2, X9, X11              // c46131fcda or c531fcda
-	//TODO: VPADDB X11, X9, X11             // c44131fcdb
-	//TODO: VPADDB (BX), Y15, Y2            // c4e105fc13 or c585fc13
-	//TODO: VPADDB (R11), Y15, Y2           // c4c105fc13
-	//TODO: VPADDB Y2, Y15, Y2              // c4e105fcd2 or c585fcd2
-	//TODO: VPADDB Y11, Y15, Y2             // c4c105fcd3
-	//TODO: VPADDB (BX), Y15, Y11           // c46105fc1b or c505fc1b
-	//TODO: VPADDB (R11), Y15, Y11          // c44105fc1b
-	//TODO: VPADDB Y2, Y15, Y11             // c46105fcda or c505fcda
-	//TODO: VPADDB Y11, Y15, Y11            // c44105fcdb
+	VMOVSS X2, (BX)                         // c4e17a1113 or c5fa1113
+	VMOVSS X11, (BX)                        // c4617a111b or c57a111b
+	VMOVSS X2, (R11)                        // c4c17a1113
+	VMOVSS X11, (R11)                       // c4417a111b
+	VMOVSS (BX), X2                         // c4e17a1013 or c5fa1013
+	VMOVSS (R11), X2                        // c4c17a1013
+	VMOVSS (BX), X11                        // c4617a101b or c57a101b
+	VMOVSS (R11), X11                       // c4417a101b
+	VMOVSS X2, X9, X2                       // c4e13210d2 or c5b210d2 or c4e13211d2 or c5b211d2
+	VMOVSS X11, X9, X2                      // c4c13210d3 or c4613211da or c53211da
+	VMOVSS X2, X9, X11                      // c4613210da or c53210da or c4c13211d3
+	VMOVSS X11, X9, X11                     // c4413210db or c4413211db
+	VMOVUPD (BX), X2                        // c4e1791013 or c5f91013
+	VMOVUPD (R11), X2                       // c4c1791013
+	VMOVUPD X2, X2                          // c4e17910d2 or c5f910d2 or c4e17911d2 or c5f911d2
+	VMOVUPD X11, X2                         // c4c17910d3 or c4617911da or c57911da
+	VMOVUPD (BX), X11                       // c46179101b or c579101b
+	VMOVUPD (R11), X11                      // c44179101b
+	VMOVUPD X2, X11                         // c4617910da or c57910da or c4c17911d3
+	VMOVUPD X11, X11                        // c4417910db or c4417911db
+	VMOVUPD X2, (BX)                        // c4e1791113 or c5f91113
+	VMOVUPD X11, (BX)                       // c46179111b or c579111b
+	VMOVUPD X2, (R11)                       // c4c1791113
+	VMOVUPD X11, (R11)                      // c44179111b
+	VMOVUPD (BX), Y2                        // c4e17d1013 or c5fd1013
+	VMOVUPD (R11), Y2                       // c4c17d1013
+	VMOVUPD Y2, Y2                          // c4e17d10d2 or c5fd10d2 or c4e17d11d2 or c5fd11d2
+	VMOVUPD Y11, Y2                         // c4c17d10d3 or c4617d11da or c57d11da
+	VMOVUPD (BX), Y11                       // c4617d101b or c57d101b
+	VMOVUPD (R11), Y11                      // c4417d101b
+	VMOVUPD Y2, Y11                         // c4617d10da or c57d10da or c4c17d11d3
+	VMOVUPD Y11, Y11                        // c4417d10db or c4417d11db
+	VMOVUPD Y2, (BX)                        // c4e17d1113 or c5fd1113
+	VMOVUPD Y11, (BX)                       // c4617d111b or c57d111b
+	VMOVUPD Y2, (R11)                       // c4c17d1113
+	VMOVUPD Y11, (R11)                      // c4417d111b
+	VMOVUPS (BX), X2                        // c4e1781013 or c5f81013
+	VMOVUPS (R11), X2                       // c4c1781013
+	VMOVUPS X2, X2                          // c4e17810d2 or c5f810d2 or c4e17811d2 or c5f811d2
+	VMOVUPS X11, X2                         // c4c17810d3 or c4617811da or c57811da
+	VMOVUPS (BX), X11                       // c46178101b or c578101b
+	VMOVUPS (R11), X11                      // c44178101b
+	VMOVUPS X2, X11                         // c4617810da or c57810da or c4c17811d3
+	VMOVUPS X11, X11                        // c4417810db or c4417811db
+	VMOVUPS X2, (BX)                        // c4e1781113 or c5f81113
+	VMOVUPS X11, (BX)                       // c46178111b or c578111b
+	VMOVUPS X2, (R11)                       // c4c1781113
+	VMOVUPS X11, (R11)                      // c44178111b
+	VMOVUPS (BX), Y2                        // c4e17c1013 or c5fc1013
+	VMOVUPS (R11), Y2                       // c4c17c1013
+	VMOVUPS Y2, Y2                          // c4e17c10d2 or c5fc10d2 or c4e17c11d2 or c5fc11d2
+	VMOVUPS Y11, Y2                         // c4c17c10d3 or c4617c11da or c57c11da
+	VMOVUPS (BX), Y11                       // c4617c101b or c57c101b
+	VMOVUPS (R11), Y11                      // c4417c101b
+	VMOVUPS Y2, Y11                         // c4617c10da or c57c10da or c4c17c11d3
+	VMOVUPS Y11, Y11                        // c4417c10db or c4417c11db
+	VMOVUPS Y2, (BX)                        // c4e17c1113 or c5fc1113
+	VMOVUPS Y11, (BX)                       // c4617c111b or c57c111b
+	VMOVUPS Y2, (R11)                       // c4c17c1113
+	VMOVUPS Y11, (R11)                      // c4417c111b
+	VMPSADBW $7, (BX), X9, X2               // c4e331421307
+	VMPSADBW $7, (R11), X9, X2              // c4c331421307
+	VMPSADBW $7, X2, X9, X2                 // c4e33142d207
+	VMPSADBW $7, X11, X9, X2                // c4c33142d307
+	VMPSADBW $7, (BX), X9, X11              // c46331421b07
+	VMPSADBW $7, (R11), X9, X11             // c44331421b07
+	VMPSADBW $7, X2, X9, X11                // c4633142da07
+	VMPSADBW $7, X11, X9, X11               // c4433142db07
+	VMPSADBW $7, (BX), Y15, Y2              // c4e305421307
+	VMPSADBW $7, (R11), Y15, Y2             // c4c305421307
+	VMPSADBW $7, Y2, Y15, Y2                // c4e30542d207
+	VMPSADBW $7, Y11, Y15, Y2               // c4c30542d307
+	VMPSADBW $7, (BX), Y15, Y11             // c46305421b07
+	VMPSADBW $7, (R11), Y15, Y11            // c44305421b07
+	VMPSADBW $7, Y2, Y15, Y11               // c4630542da07
+	VMPSADBW $7, Y11, Y15, Y11              // c4430542db07
+	VMULPD (BX), X9, X2                     // c4e1315913 or c5b15913
+	VMULPD (R11), X9, X2                    // c4c1315913
+	VMULPD X2, X9, X2                       // c4e13159d2 or c5b159d2
+	VMULPD X11, X9, X2                      // c4c13159d3
+	VMULPD (BX), X9, X11                    // c46131591b or c531591b
+	VMULPD (R11), X9, X11                   // c44131591b
+	VMULPD X2, X9, X11                      // c4613159da or c53159da
+	VMULPD X11, X9, X11                     // c4413159db
+	VMULPD (BX), Y15, Y2                    // c4e1055913 or c5855913
+	VMULPD (R11), Y15, Y2                   // c4c1055913
+	VMULPD Y2, Y15, Y2                      // c4e10559d2 or c58559d2
+	VMULPD Y11, Y15, Y2                     // c4c10559d3
+	VMULPD (BX), Y15, Y11                   // c46105591b or c505591b
+	VMULPD (R11), Y15, Y11                  // c44105591b
+	VMULPD Y2, Y15, Y11                     // c4610559da or c50559da
+	VMULPD Y11, Y15, Y11                    // c4410559db
+	VMULPS (BX), X9, X2                     // c4e1305913 or c5b05913
+	VMULPS (R11), X9, X2                    // c4c1305913
+	VMULPS X2, X9, X2                       // c4e13059d2 or c5b059d2
+	VMULPS X11, X9, X2                      // c4c13059d3
+	VMULPS (BX), X9, X11                    // c46130591b or c530591b
+	VMULPS (R11), X9, X11                   // c44130591b
+	VMULPS X2, X9, X11                      // c4613059da or c53059da
+	VMULPS X11, X9, X11                     // c4413059db
+	VMULPS (BX), Y15, Y2                    // c4e1045913 or c5845913
+	VMULPS (R11), Y15, Y2                   // c4c1045913
+	VMULPS Y2, Y15, Y2                      // c4e10459d2 or c58459d2
+	VMULPS Y11, Y15, Y2                     // c4c10459d3
+	VMULPS (BX), Y15, Y11                   // c46104591b or c504591b
+	VMULPS (R11), Y15, Y11                  // c44104591b
+	VMULPS Y2, Y15, Y11                     // c4610459da or c50459da
+	VMULPS Y11, Y15, Y11                    // c4410459db
+	VMULSD (BX), X9, X2                     // c4e1335913 or c5b35913
+	VMULSD (R11), X9, X2                    // c4c1335913
+	VMULSD X2, X9, X2                       // c4e13359d2 or c5b359d2
+	VMULSD X11, X9, X2                      // c4c13359d3
+	VMULSD (BX), X9, X11                    // c46133591b or c533591b
+	VMULSD (R11), X9, X11                   // c44133591b
+	VMULSD X2, X9, X11                      // c4613359da or c53359da
+	VMULSD X11, X9, X11                     // c4413359db
+	VMULSS (BX), X9, X2                     // c4e1325913 or c5b25913
+	VMULSS (R11), X9, X2                    // c4c1325913
+	VMULSS X2, X9, X2                       // c4e13259d2 or c5b259d2
+	VMULSS X11, X9, X2                      // c4c13259d3
+	VMULSS (BX), X9, X11                    // c46132591b or c532591b
+	VMULSS (R11), X9, X11                   // c44132591b
+	VMULSS X2, X9, X11                      // c4613259da or c53259da
+	VMULSS X11, X9, X11                     // c4413259db
+	VORPD (BX), X9, X2                      // c4e1315613 or c5b15613
+	VORPD (R11), X9, X2                     // c4c1315613
+	VORPD X2, X9, X2                        // c4e13156d2 or c5b156d2
+	VORPD X11, X9, X2                       // c4c13156d3
+	VORPD (BX), X9, X11                     // c46131561b or c531561b
+	VORPD (R11), X9, X11                    // c44131561b
+	VORPD X2, X9, X11                       // c4613156da or c53156da
+	VORPD X11, X9, X11                      // c4413156db
+	VORPD (BX), Y15, Y2                     // c4e1055613 or c5855613
+	VORPD (R11), Y15, Y2                    // c4c1055613
+	VORPD Y2, Y15, Y2                       // c4e10556d2 or c58556d2
+	VORPD Y11, Y15, Y2                      // c4c10556d3
+	VORPD (BX), Y15, Y11                    // c46105561b or c505561b
+	VORPD (R11), Y15, Y11                   // c44105561b
+	VORPD Y2, Y15, Y11                      // c4610556da or c50556da
+	VORPD Y11, Y15, Y11                     // c4410556db
+	VORPS (BX), X9, X2                      // c4e1305613 or c5b05613
+	VORPS (R11), X9, X2                     // c4c1305613
+	VORPS X2, X9, X2                        // c4e13056d2 or c5b056d2
+	VORPS X11, X9, X2                       // c4c13056d3
+	VORPS (BX), X9, X11                     // c46130561b or c530561b
+	VORPS (R11), X9, X11                    // c44130561b
+	VORPS X2, X9, X11                       // c4613056da or c53056da
+	VORPS X11, X9, X11                      // c4413056db
+	VORPS (BX), Y15, Y2                     // c4e1045613 or c5845613
+	VORPS (R11), Y15, Y2                    // c4c1045613
+	VORPS Y2, Y15, Y2                       // c4e10456d2 or c58456d2
+	VORPS Y11, Y15, Y2                      // c4c10456d3
+	VORPS (BX), Y15, Y11                    // c46104561b or c504561b
+	VORPS (R11), Y15, Y11                   // c44104561b
+	VORPS Y2, Y15, Y11                      // c4610456da or c50456da
+	VORPS Y11, Y15, Y11                     // c4410456db
+	VPABSB (BX), X2                         // c4e2791c13
+	VPABSB (R11), X2                        // c4c2791c13
+	VPABSB X2, X2                           // c4e2791cd2
+	VPABSB X11, X2                          // c4c2791cd3
+	VPABSB (BX), X11                        // c462791c1b
+	VPABSB (R11), X11                       // c442791c1b
+	VPABSB X2, X11                          // c462791cda
+	VPABSB X11, X11                         // c442791cdb
+	VPABSB (BX), Y2                         // c4e27d1c13
+	VPABSB (R11), Y2                        // c4c27d1c13
+	VPABSB Y2, Y2                           // c4e27d1cd2
+	VPABSB Y11, Y2                          // c4c27d1cd3
+	VPABSB (BX), Y11                        // c4627d1c1b
+	VPABSB (R11), Y11                       // c4427d1c1b
+	VPABSB Y2, Y11                          // c4627d1cda
+	VPABSB Y11, Y11                         // c4427d1cdb
+	VPABSD (BX), X2                         // c4e2791e13
+	VPABSD (R11), X2                        // c4c2791e13
+	VPABSD X2, X2                           // c4e2791ed2
+	VPABSD X11, X2                          // c4c2791ed3
+	VPABSD (BX), X11                        // c462791e1b
+	VPABSD (R11), X11                       // c442791e1b
+	VPABSD X2, X11                          // c462791eda
+	VPABSD X11, X11                         // c442791edb
+	VPABSD (BX), Y2                         // c4e27d1e13
+	VPABSD (R11), Y2                        // c4c27d1e13
+	VPABSD Y2, Y2                           // c4e27d1ed2
+	VPABSD Y11, Y2                          // c4c27d1ed3
+	VPABSD (BX), Y11                        // c4627d1e1b
+	VPABSD (R11), Y11                       // c4427d1e1b
+	VPABSD Y2, Y11                          // c4627d1eda
+	VPABSD Y11, Y11                         // c4427d1edb
+	VPABSW (BX), X2                         // c4e2791d13
+	VPABSW (R11), X2                        // c4c2791d13
+	VPABSW X2, X2                           // c4e2791dd2
+	VPABSW X11, X2                          // c4c2791dd3
+	VPABSW (BX), X11                        // c462791d1b
+	VPABSW (R11), X11                       // c442791d1b
+	VPABSW X2, X11                          // c462791dda
+	VPABSW X11, X11                         // c442791ddb
+	VPABSW (BX), Y2                         // c4e27d1d13
+	VPABSW (R11), Y2                        // c4c27d1d13
+	VPABSW Y2, Y2                           // c4e27d1dd2
+	VPABSW Y11, Y2                          // c4c27d1dd3
+	VPABSW (BX), Y11                        // c4627d1d1b
+	VPABSW (R11), Y11                       // c4427d1d1b
+	VPABSW Y2, Y11                          // c4627d1dda
+	VPABSW Y11, Y11                         // c4427d1ddb
+	VPACKSSDW (BX), X9, X2                  // c4e1316b13 or c5b16b13
+	VPACKSSDW (R11), X9, X2                 // c4c1316b13
+	VPACKSSDW X2, X9, X2                    // c4e1316bd2 or c5b16bd2
+	VPACKSSDW X11, X9, X2                   // c4c1316bd3
+	VPACKSSDW (BX), X9, X11                 // c461316b1b or c5316b1b
+	VPACKSSDW (R11), X9, X11                // c441316b1b
+	VPACKSSDW X2, X9, X11                   // c461316bda or c5316bda
+	VPACKSSDW X11, X9, X11                  // c441316bdb
+	VPACKSSDW (BX), Y15, Y2                 // c4e1056b13 or c5856b13
+	VPACKSSDW (R11), Y15, Y2                // c4c1056b13
+	VPACKSSDW Y2, Y15, Y2                   // c4e1056bd2 or c5856bd2
+	VPACKSSDW Y11, Y15, Y2                  // c4c1056bd3
+	VPACKSSDW (BX), Y15, Y11                // c461056b1b or c5056b1b
+	VPACKSSDW (R11), Y15, Y11               // c441056b1b
+	VPACKSSDW Y2, Y15, Y11                  // c461056bda or c5056bda
+	VPACKSSDW Y11, Y15, Y11                 // c441056bdb
+	VPACKSSWB (BX), X9, X2                  // c4e1316313 or c5b16313
+	VPACKSSWB (R11), X9, X2                 // c4c1316313
+	VPACKSSWB X2, X9, X2                    // c4e13163d2 or c5b163d2
+	VPACKSSWB X11, X9, X2                   // c4c13163d3
+	VPACKSSWB (BX), X9, X11                 // c46131631b or c531631b
+	VPACKSSWB (R11), X9, X11                // c44131631b
+	VPACKSSWB X2, X9, X11                   // c4613163da or c53163da
+	VPACKSSWB X11, X9, X11                  // c4413163db
+	VPACKSSWB (BX), Y15, Y2                 // c4e1056313 or c5856313
+	VPACKSSWB (R11), Y15, Y2                // c4c1056313
+	VPACKSSWB Y2, Y15, Y2                   // c4e10563d2 or c58563d2
+	VPACKSSWB Y11, Y15, Y2                  // c4c10563d3
+	VPACKSSWB (BX), Y15, Y11                // c46105631b or c505631b
+	VPACKSSWB (R11), Y15, Y11               // c44105631b
+	VPACKSSWB Y2, Y15, Y11                  // c4610563da or c50563da
+	VPACKSSWB Y11, Y15, Y11                 // c4410563db
+	VPACKUSDW (BX), X9, X2                  // c4e2312b13
+	VPACKUSDW (R11), X9, X2                 // c4c2312b13
+	VPACKUSDW X2, X9, X2                    // c4e2312bd2
+	VPACKUSDW X11, X9, X2                   // c4c2312bd3
+	VPACKUSDW (BX), X9, X11                 // c462312b1b
+	VPACKUSDW (R11), X9, X11                // c442312b1b
+	VPACKUSDW X2, X9, X11                   // c462312bda
+	VPACKUSDW X11, X9, X11                  // c442312bdb
+	VPACKUSDW (BX), Y15, Y2                 // c4e2052b13
+	VPACKUSDW (R11), Y15, Y2                // c4c2052b13
+	VPACKUSDW Y2, Y15, Y2                   // c4e2052bd2
+	VPACKUSDW Y11, Y15, Y2                  // c4c2052bd3
+	VPACKUSDW (BX), Y15, Y11                // c462052b1b
+	VPACKUSDW (R11), Y15, Y11               // c442052b1b
+	VPACKUSDW Y2, Y15, Y11                  // c462052bda
+	VPACKUSDW Y11, Y15, Y11                 // c442052bdb
+	VPACKUSWB (BX), X9, X2                  // c4e1316713 or c5b16713
+	VPACKUSWB (R11), X9, X2                 // c4c1316713
+	VPACKUSWB X2, X9, X2                    // c4e13167d2 or c5b167d2
+	VPACKUSWB X11, X9, X2                   // c4c13167d3
+	VPACKUSWB (BX), X9, X11                 // c46131671b or c531671b
+	VPACKUSWB (R11), X9, X11                // c44131671b
+	VPACKUSWB X2, X9, X11                   // c4613167da or c53167da
+	VPACKUSWB X11, X9, X11                  // c4413167db
+	VPACKUSWB (BX), Y15, Y2                 // c4e1056713 or c5856713
+	VPACKUSWB (R11), Y15, Y2                // c4c1056713
+	VPACKUSWB Y2, Y15, Y2                   // c4e10567d2 or c58567d2
+	VPACKUSWB Y11, Y15, Y2                  // c4c10567d3
+	VPACKUSWB (BX), Y15, Y11                // c46105671b or c505671b
+	VPACKUSWB (R11), Y15, Y11               // c44105671b
+	VPACKUSWB Y2, Y15, Y11                  // c4610567da or c50567da
+	VPACKUSWB Y11, Y15, Y11                 // c4410567db
+	VPADDB (BX), X9, X2                     // c4e131fc13 or c5b1fc13
+	VPADDB (R11), X9, X2                    // c4c131fc13
+	VPADDB X2, X9, X2                       // c4e131fcd2 or c5b1fcd2
+	VPADDB X11, X9, X2                      // c4c131fcd3
+	VPADDB (BX), X9, X11                    // c46131fc1b or c531fc1b
+	VPADDB (R11), X9, X11                   // c44131fc1b
+	VPADDB X2, X9, X11                      // c46131fcda or c531fcda
+	VPADDB X11, X9, X11                     // c44131fcdb
+	VPADDB (BX), Y15, Y2                    // c4e105fc13 or c585fc13
+	VPADDB (R11), Y15, Y2                   // c4c105fc13
+	VPADDB Y2, Y15, Y2                      // c4e105fcd2 or c585fcd2
+	VPADDB Y11, Y15, Y2                     // c4c105fcd3
+	VPADDB (BX), Y15, Y11                   // c46105fc1b or c505fc1b
+	VPADDB (R11), Y15, Y11                  // c44105fc1b
+	VPADDB Y2, Y15, Y11                     // c46105fcda or c505fcda
+	VPADDB Y11, Y15, Y11                    // c44105fcdb
 	VPADDD (BX), X9, X2             // c4e131fe13 or c5b1fe13
 	VPADDD (R11), X9, X2            // c4c131fe13
 	VPADDD X2, X9, X2               // c4e131fed2 or c5b1fed2
@@ -8176,94 +8176,94 @@
 	VPADDQ (R11), Y15, Y11          // c44105d41b
 	VPADDQ Y2, Y15, Y11             // c46105d4da or c505d4da
 	VPADDQ Y11, Y15, Y11            // c44105d4db
-	//TODO: VPADDSB (BX), X9, X2            // c4e131ec13 or c5b1ec13
-	//TODO: VPADDSB (R11), X9, X2           // c4c131ec13
-	//TODO: VPADDSB X2, X9, X2              // c4e131ecd2 or c5b1ecd2
-	//TODO: VPADDSB X11, X9, X2             // c4c131ecd3
-	//TODO: VPADDSB (BX), X9, X11           // c46131ec1b or c531ec1b
-	//TODO: VPADDSB (R11), X9, X11          // c44131ec1b
-	//TODO: VPADDSB X2, X9, X11             // c46131ecda or c531ecda
-	//TODO: VPADDSB X11, X9, X11            // c44131ecdb
-	//TODO: VPADDSB (BX), Y15, Y2           // c4e105ec13 or c585ec13
-	//TODO: VPADDSB (R11), Y15, Y2          // c4c105ec13
-	//TODO: VPADDSB Y2, Y15, Y2             // c4e105ecd2 or c585ecd2
-	//TODO: VPADDSB Y11, Y15, Y2            // c4c105ecd3
-	//TODO: VPADDSB (BX), Y15, Y11          // c46105ec1b or c505ec1b
-	//TODO: VPADDSB (R11), Y15, Y11         // c44105ec1b
-	//TODO: VPADDSB Y2, Y15, Y11            // c46105ecda or c505ecda
-	//TODO: VPADDSB Y11, Y15, Y11           // c44105ecdb
-	//TODO: VPADDSW (BX), X9, X2            // c4e131ed13 or c5b1ed13
-	//TODO: VPADDSW (R11), X9, X2           // c4c131ed13
-	//TODO: VPADDSW X2, X9, X2              // c4e131edd2 or c5b1edd2
-	//TODO: VPADDSW X11, X9, X2             // c4c131edd3
-	//TODO: VPADDSW (BX), X9, X11           // c46131ed1b or c531ed1b
-	//TODO: VPADDSW (R11), X9, X11          // c44131ed1b
-	//TODO: VPADDSW X2, X9, X11             // c46131edda or c531edda
-	//TODO: VPADDSW X11, X9, X11            // c44131eddb
-	//TODO: VPADDSW (BX), Y15, Y2           // c4e105ed13 or c585ed13
-	//TODO: VPADDSW (R11), Y15, Y2          // c4c105ed13
-	//TODO: VPADDSW Y2, Y15, Y2             // c4e105edd2 or c585edd2
-	//TODO: VPADDSW Y11, Y15, Y2            // c4c105edd3
-	//TODO: VPADDSW (BX), Y15, Y11          // c46105ed1b or c505ed1b
-	//TODO: VPADDSW (R11), Y15, Y11         // c44105ed1b
-	//TODO: VPADDSW Y2, Y15, Y11            // c46105edda or c505edda
-	//TODO: VPADDSW Y11, Y15, Y11           // c44105eddb
-	//TODO: VPADDUSB (BX), X9, X2           // c4e131dc13 or c5b1dc13
-	//TODO: VPADDUSB (R11), X9, X2          // c4c131dc13
-	//TODO: VPADDUSB X2, X9, X2             // c4e131dcd2 or c5b1dcd2
-	//TODO: VPADDUSB X11, X9, X2            // c4c131dcd3
-	//TODO: VPADDUSB (BX), X9, X11          // c46131dc1b or c531dc1b
-	//TODO: VPADDUSB (R11), X9, X11         // c44131dc1b
-	//TODO: VPADDUSB X2, X9, X11            // c46131dcda or c531dcda
-	//TODO: VPADDUSB X11, X9, X11           // c44131dcdb
-	//TODO: VPADDUSB (BX), Y15, Y2          // c4e105dc13 or c585dc13
-	//TODO: VPADDUSB (R11), Y15, Y2         // c4c105dc13
-	//TODO: VPADDUSB Y2, Y15, Y2            // c4e105dcd2 or c585dcd2
-	//TODO: VPADDUSB Y11, Y15, Y2           // c4c105dcd3
-	//TODO: VPADDUSB (BX), Y15, Y11         // c46105dc1b or c505dc1b
-	//TODO: VPADDUSB (R11), Y15, Y11        // c44105dc1b
-	//TODO: VPADDUSB Y2, Y15, Y11           // c46105dcda or c505dcda
-	//TODO: VPADDUSB Y11, Y15, Y11          // c44105dcdb
-	//TODO: VPADDUSW (BX), X9, X2           // c4e131dd13 or c5b1dd13
-	//TODO: VPADDUSW (R11), X9, X2          // c4c131dd13
-	//TODO: VPADDUSW X2, X9, X2             // c4e131ddd2 or c5b1ddd2
-	//TODO: VPADDUSW X11, X9, X2            // c4c131ddd3
-	//TODO: VPADDUSW (BX), X9, X11          // c46131dd1b or c531dd1b
-	//TODO: VPADDUSW (R11), X9, X11         // c44131dd1b
-	//TODO: VPADDUSW X2, X9, X11            // c46131ddda or c531ddda
-	//TODO: VPADDUSW X11, X9, X11           // c44131dddb
-	//TODO: VPADDUSW (BX), Y15, Y2          // c4e105dd13 or c585dd13
-	//TODO: VPADDUSW (R11), Y15, Y2         // c4c105dd13
-	//TODO: VPADDUSW Y2, Y15, Y2            // c4e105ddd2 or c585ddd2
-	//TODO: VPADDUSW Y11, Y15, Y2           // c4c105ddd3
-	//TODO: VPADDUSW (BX), Y15, Y11         // c46105dd1b or c505dd1b
-	//TODO: VPADDUSW (R11), Y15, Y11        // c44105dd1b
-	//TODO: VPADDUSW Y2, Y15, Y11           // c46105ddda or c505ddda
-	//TODO: VPADDUSW Y11, Y15, Y11          // c44105dddb
-	//TODO: VPADDW (BX), X9, X2             // c4e131fd13 or c5b1fd13
-	//TODO: VPADDW (R11), X9, X2            // c4c131fd13
-	//TODO: VPADDW X2, X9, X2               // c4e131fdd2 or c5b1fdd2
-	//TODO: VPADDW X11, X9, X2              // c4c131fdd3
-	//TODO: VPADDW (BX), X9, X11            // c46131fd1b or c531fd1b
-	//TODO: VPADDW (R11), X9, X11           // c44131fd1b
-	//TODO: VPADDW X2, X9, X11              // c46131fdda or c531fdda
-	//TODO: VPADDW X11, X9, X11             // c44131fddb
-	//TODO: VPADDW (BX), Y15, Y2            // c4e105fd13 or c585fd13
-	//TODO: VPADDW (R11), Y15, Y2           // c4c105fd13
-	//TODO: VPADDW Y2, Y15, Y2              // c4e105fdd2 or c585fdd2
-	//TODO: VPADDW Y11, Y15, Y2             // c4c105fdd3
-	//TODO: VPADDW (BX), Y15, Y11           // c46105fd1b or c505fd1b
-	//TODO: VPADDW (R11), Y15, Y11          // c44105fd1b
-	//TODO: VPADDW Y2, Y15, Y11             // c46105fdda or c505fdda
-	//TODO: VPADDW Y11, Y15, Y11            // c44105fddb
-	//TODO: VPALIGNR $7, (BX), X9, X2       // c4e3310f1307
-	//TODO: VPALIGNR $7, (R11), X9, X2      // c4c3310f1307
-	//TODO: VPALIGNR $7, X2, X9, X2         // c4e3310fd207
-	//TODO: VPALIGNR $7, X11, X9, X2        // c4c3310fd307
-	//TODO: VPALIGNR $7, (BX), X9, X11      // c463310f1b07
-	//TODO: VPALIGNR $7, (R11), X9, X11     // c443310f1b07
-	//TODO: VPALIGNR $7, X2, X9, X11        // c463310fda07
-	//TODO: VPALIGNR $7, X11, X9, X11       // c443310fdb07
+	VPADDSB (BX), X9, X2                    // c4e131ec13 or c5b1ec13
+	VPADDSB (R11), X9, X2                   // c4c131ec13
+	VPADDSB X2, X9, X2                      // c4e131ecd2 or c5b1ecd2
+	VPADDSB X11, X9, X2                     // c4c131ecd3
+	VPADDSB (BX), X9, X11                   // c46131ec1b or c531ec1b
+	VPADDSB (R11), X9, X11                  // c44131ec1b
+	VPADDSB X2, X9, X11                     // c46131ecda or c531ecda
+	VPADDSB X11, X9, X11                    // c44131ecdb
+	VPADDSB (BX), Y15, Y2                   // c4e105ec13 or c585ec13
+	VPADDSB (R11), Y15, Y2                  // c4c105ec13
+	VPADDSB Y2, Y15, Y2                     // c4e105ecd2 or c585ecd2
+	VPADDSB Y11, Y15, Y2                    // c4c105ecd3
+	VPADDSB (BX), Y15, Y11                  // c46105ec1b or c505ec1b
+	VPADDSB (R11), Y15, Y11                 // c44105ec1b
+	VPADDSB Y2, Y15, Y11                    // c46105ecda or c505ecda
+	VPADDSB Y11, Y15, Y11                   // c44105ecdb
+	VPADDSW (BX), X9, X2                    // c4e131ed13 or c5b1ed13
+	VPADDSW (R11), X9, X2                   // c4c131ed13
+	VPADDSW X2, X9, X2                      // c4e131edd2 or c5b1edd2
+	VPADDSW X11, X9, X2                     // c4c131edd3
+	VPADDSW (BX), X9, X11                   // c46131ed1b or c531ed1b
+	VPADDSW (R11), X9, X11                  // c44131ed1b
+	VPADDSW X2, X9, X11                     // c46131edda or c531edda
+	VPADDSW X11, X9, X11                    // c44131eddb
+	VPADDSW (BX), Y15, Y2                   // c4e105ed13 or c585ed13
+	VPADDSW (R11), Y15, Y2                  // c4c105ed13
+	VPADDSW Y2, Y15, Y2                     // c4e105edd2 or c585edd2
+	VPADDSW Y11, Y15, Y2                    // c4c105edd3
+	VPADDSW (BX), Y15, Y11                  // c46105ed1b or c505ed1b
+	VPADDSW (R11), Y15, Y11                 // c44105ed1b
+	VPADDSW Y2, Y15, Y11                    // c46105edda or c505edda
+	VPADDSW Y11, Y15, Y11                   // c44105eddb
+	VPADDUSB (BX), X9, X2                   // c4e131dc13 or c5b1dc13
+	VPADDUSB (R11), X9, X2                  // c4c131dc13
+	VPADDUSB X2, X9, X2                     // c4e131dcd2 or c5b1dcd2
+	VPADDUSB X11, X9, X2                    // c4c131dcd3
+	VPADDUSB (BX), X9, X11                  // c46131dc1b or c531dc1b
+	VPADDUSB (R11), X9, X11                 // c44131dc1b
+	VPADDUSB X2, X9, X11                    // c46131dcda or c531dcda
+	VPADDUSB X11, X9, X11                   // c44131dcdb
+	VPADDUSB (BX), Y15, Y2                  // c4e105dc13 or c585dc13
+	VPADDUSB (R11), Y15, Y2                 // c4c105dc13
+	VPADDUSB Y2, Y15, Y2                    // c4e105dcd2 or c585dcd2
+	VPADDUSB Y11, Y15, Y2                   // c4c105dcd3
+	VPADDUSB (BX), Y15, Y11                 // c46105dc1b or c505dc1b
+	VPADDUSB (R11), Y15, Y11                // c44105dc1b
+	VPADDUSB Y2, Y15, Y11                   // c46105dcda or c505dcda
+	VPADDUSB Y11, Y15, Y11                  // c44105dcdb
+	VPADDUSW (BX), X9, X2                   // c4e131dd13 or c5b1dd13
+	VPADDUSW (R11), X9, X2                  // c4c131dd13
+	VPADDUSW X2, X9, X2                     // c4e131ddd2 or c5b1ddd2
+	VPADDUSW X11, X9, X2                    // c4c131ddd3
+	VPADDUSW (BX), X9, X11                  // c46131dd1b or c531dd1b
+	VPADDUSW (R11), X9, X11                 // c44131dd1b
+	VPADDUSW X2, X9, X11                    // c46131ddda or c531ddda
+	VPADDUSW X11, X9, X11                   // c44131dddb
+	VPADDUSW (BX), Y15, Y2                  // c4e105dd13 or c585dd13
+	VPADDUSW (R11), Y15, Y2                 // c4c105dd13
+	VPADDUSW Y2, Y15, Y2                    // c4e105ddd2 or c585ddd2
+	VPADDUSW Y11, Y15, Y2                   // c4c105ddd3
+	VPADDUSW (BX), Y15, Y11                 // c46105dd1b or c505dd1b
+	VPADDUSW (R11), Y15, Y11                // c44105dd1b
+	VPADDUSW Y2, Y15, Y11                   // c46105ddda or c505ddda
+	VPADDUSW Y11, Y15, Y11                  // c44105dddb
+	VPADDW (BX), X9, X2                     // c4e131fd13 or c5b1fd13
+	VPADDW (R11), X9, X2                    // c4c131fd13
+	VPADDW X2, X9, X2                       // c4e131fdd2 or c5b1fdd2
+	VPADDW X11, X9, X2                      // c4c131fdd3
+	VPADDW (BX), X9, X11                    // c46131fd1b or c531fd1b
+	VPADDW (R11), X9, X11                   // c44131fd1b
+	VPADDW X2, X9, X11                      // c46131fdda or c531fdda
+	VPADDW X11, X9, X11                     // c44131fddb
+	VPADDW (BX), Y15, Y2                    // c4e105fd13 or c585fd13
+	VPADDW (R11), Y15, Y2                   // c4c105fd13
+	VPADDW Y2, Y15, Y2                      // c4e105fdd2 or c585fdd2
+	VPADDW Y11, Y15, Y2                     // c4c105fdd3
+	VPADDW (BX), Y15, Y11                   // c46105fd1b or c505fd1b
+	VPADDW (R11), Y15, Y11                  // c44105fd1b
+	VPADDW Y2, Y15, Y11                     // c46105fdda or c505fdda
+	VPADDW Y11, Y15, Y11                    // c44105fddb
+	VPALIGNR $7, (BX), X9, X2               // c4e3310f1307
+	VPALIGNR $7, (R11), X9, X2              // c4c3310f1307
+	VPALIGNR $7, X2, X9, X2                 // c4e3310fd207
+	VPALIGNR $7, X11, X9, X2                // c4c3310fd307
+	VPALIGNR $7, (BX), X9, X11              // c463310f1b07
+	VPALIGNR $7, (R11), X9, X11             // c443310f1b07
+	VPALIGNR $7, X2, X9, X11                // c463310fda07
+	VPALIGNR $7, X11, X9, X11               // c443310fdb07
 	VPALIGNR $7, (BX), Y15, Y2      // c4e3050f1307
 	VPALIGNR $7, (R11), Y15, Y2     // c4c3050f1307
 	VPALIGNR $7, Y2, Y15, Y2        // c4e3050fd207
@@ -8288,62 +8288,62 @@
 	VPAND (R11), Y15, Y11                   // c44105db1b
 	VPAND Y2, Y15, Y11                      // c46105dbda or c505dbda
 	VPAND Y11, Y15, Y11                     // c44105dbdb
-	//TODO: VPANDN (BX), X9, X2             // c4e131df13 or c5b1df13
-	//TODO: VPANDN (R11), X9, X2            // c4c131df13
-	//TODO: VPANDN X2, X9, X2               // c4e131dfd2 or c5b1dfd2
-	//TODO: VPANDN X11, X9, X2              // c4c131dfd3
-	//TODO: VPANDN (BX), X9, X11            // c46131df1b or c531df1b
-	//TODO: VPANDN (R11), X9, X11           // c44131df1b
-	//TODO: VPANDN X2, X9, X11              // c46131dfda or c531dfda
-	//TODO: VPANDN X11, X9, X11             // c44131dfdb
-	//TODO: VPANDN (BX), Y15, Y2            // c4e105df13 or c585df13
-	//TODO: VPANDN (R11), Y15, Y2           // c4c105df13
-	//TODO: VPANDN Y2, Y15, Y2              // c4e105dfd2 or c585dfd2
-	//TODO: VPANDN Y11, Y15, Y2             // c4c105dfd3
-	//TODO: VPANDN (BX), Y15, Y11           // c46105df1b or c505df1b
-	//TODO: VPANDN (R11), Y15, Y11          // c44105df1b
-	//TODO: VPANDN Y2, Y15, Y11             // c46105dfda or c505dfda
-	//TODO: VPANDN Y11, Y15, Y11            // c44105dfdb
-	//TODO: VPAVGB (BX), X9, X2             // c4e131e013 or c5b1e013
-	//TODO: VPAVGB (R11), X9, X2            // c4c131e013
-	//TODO: VPAVGB X2, X9, X2               // c4e131e0d2 or c5b1e0d2
-	//TODO: VPAVGB X11, X9, X2              // c4c131e0d3
-	//TODO: VPAVGB (BX), X9, X11            // c46131e01b or c531e01b
-	//TODO: VPAVGB (R11), X9, X11           // c44131e01b
-	//TODO: VPAVGB X2, X9, X11              // c46131e0da or c531e0da
-	//TODO: VPAVGB X11, X9, X11             // c44131e0db
-	//TODO: VPAVGB (BX), Y15, Y2            // c4e105e013 or c585e013
-	//TODO: VPAVGB (R11), Y15, Y2           // c4c105e013
-	//TODO: VPAVGB Y2, Y15, Y2              // c4e105e0d2 or c585e0d2
-	//TODO: VPAVGB Y11, Y15, Y2             // c4c105e0d3
-	//TODO: VPAVGB (BX), Y15, Y11           // c46105e01b or c505e01b
-	//TODO: VPAVGB (R11), Y15, Y11          // c44105e01b
-	//TODO: VPAVGB Y2, Y15, Y11             // c46105e0da or c505e0da
-	//TODO: VPAVGB Y11, Y15, Y11            // c44105e0db
-	//TODO: VPAVGW (BX), X9, X2             // c4e131e313 or c5b1e313
-	//TODO: VPAVGW (R11), X9, X2            // c4c131e313
-	//TODO: VPAVGW X2, X9, X2               // c4e131e3d2 or c5b1e3d2
-	//TODO: VPAVGW X11, X9, X2              // c4c131e3d3
-	//TODO: VPAVGW (BX), X9, X11            // c46131e31b or c531e31b
-	//TODO: VPAVGW (R11), X9, X11           // c44131e31b
-	//TODO: VPAVGW X2, X9, X11              // c46131e3da or c531e3da
-	//TODO: VPAVGW X11, X9, X11             // c44131e3db
-	//TODO: VPAVGW (BX), Y15, Y2            // c4e105e313 or c585e313
-	//TODO: VPAVGW (R11), Y15, Y2           // c4c105e313
-	//TODO: VPAVGW Y2, Y15, Y2              // c4e105e3d2 or c585e3d2
-	//TODO: VPAVGW Y11, Y15, Y2             // c4c105e3d3
-	//TODO: VPAVGW (BX), Y15, Y11           // c46105e31b or c505e31b
-	//TODO: VPAVGW (R11), Y15, Y11          // c44105e31b
-	//TODO: VPAVGW Y2, Y15, Y11             // c46105e3da or c505e3da
-	//TODO: VPAVGW Y11, Y15, Y11            // c44105e3db
-	//TODO: VPBLENDD $7, (BX), X9, X2       // c4e331021307
-	//TODO: VPBLENDD $7, (R11), X9, X2      // c4c331021307
-	//TODO: VPBLENDD $7, X2, X9, X2         // c4e33102d207
-	//TODO: VPBLENDD $7, X11, X9, X2        // c4c33102d307
-	//TODO: VPBLENDD $7, (BX), X9, X11      // c46331021b07
-	//TODO: VPBLENDD $7, (R11), X9, X11     // c44331021b07
-	//TODO: VPBLENDD $7, X2, X9, X11        // c4633102da07
-	//TODO: VPBLENDD $7, X11, X9, X11       // c4433102db07
+	VPANDN (BX), X9, X2                     // c4e131df13 or c5b1df13
+	VPANDN (R11), X9, X2                    // c4c131df13
+	VPANDN X2, X9, X2                       // c4e131dfd2 or c5b1dfd2
+	VPANDN X11, X9, X2                      // c4c131dfd3
+	VPANDN (BX), X9, X11                    // c46131df1b or c531df1b
+	VPANDN (R11), X9, X11                   // c44131df1b
+	VPANDN X2, X9, X11                      // c46131dfda or c531dfda
+	VPANDN X11, X9, X11                     // c44131dfdb
+	VPANDN (BX), Y15, Y2                    // c4e105df13 or c585df13
+	VPANDN (R11), Y15, Y2                   // c4c105df13
+	VPANDN Y2, Y15, Y2                      // c4e105dfd2 or c585dfd2
+	VPANDN Y11, Y15, Y2                     // c4c105dfd3
+	VPANDN (BX), Y15, Y11                   // c46105df1b or c505df1b
+	VPANDN (R11), Y15, Y11                  // c44105df1b
+	VPANDN Y2, Y15, Y11                     // c46105dfda or c505dfda
+	VPANDN Y11, Y15, Y11                    // c44105dfdb
+	VPAVGB (BX), X9, X2                     // c4e131e013 or c5b1e013
+	VPAVGB (R11), X9, X2                    // c4c131e013
+	VPAVGB X2, X9, X2                       // c4e131e0d2 or c5b1e0d2
+	VPAVGB X11, X9, X2                      // c4c131e0d3
+	VPAVGB (BX), X9, X11                    // c46131e01b or c531e01b
+	VPAVGB (R11), X9, X11                   // c44131e01b
+	VPAVGB X2, X9, X11                      // c46131e0da or c531e0da
+	VPAVGB X11, X9, X11                     // c44131e0db
+	VPAVGB (BX), Y15, Y2                    // c4e105e013 or c585e013
+	VPAVGB (R11), Y15, Y2                   // c4c105e013
+	VPAVGB Y2, Y15, Y2                      // c4e105e0d2 or c585e0d2
+	VPAVGB Y11, Y15, Y2                     // c4c105e0d3
+	VPAVGB (BX), Y15, Y11                   // c46105e01b or c505e01b
+	VPAVGB (R11), Y15, Y11                  // c44105e01b
+	VPAVGB Y2, Y15, Y11                     // c46105e0da or c505e0da
+	VPAVGB Y11, Y15, Y11                    // c44105e0db
+	VPAVGW (BX), X9, X2                     // c4e131e313 or c5b1e313
+	VPAVGW (R11), X9, X2                    // c4c131e313
+	VPAVGW X2, X9, X2                       // c4e131e3d2 or c5b1e3d2
+	VPAVGW X11, X9, X2                      // c4c131e3d3
+	VPAVGW (BX), X9, X11                    // c46131e31b or c531e31b
+	VPAVGW (R11), X9, X11                   // c44131e31b
+	VPAVGW X2, X9, X11                      // c46131e3da or c531e3da
+	VPAVGW X11, X9, X11                     // c44131e3db
+	VPAVGW (BX), Y15, Y2                    // c4e105e313 or c585e313
+	VPAVGW (R11), Y15, Y2                   // c4c105e313
+	VPAVGW Y2, Y15, Y2                      // c4e105e3d2 or c585e3d2
+	VPAVGW Y11, Y15, Y2                     // c4c105e3d3
+	VPAVGW (BX), Y15, Y11                   // c46105e31b or c505e31b
+	VPAVGW (R11), Y15, Y11                  // c44105e31b
+	VPAVGW Y2, Y15, Y11                     // c46105e3da or c505e3da
+	VPAVGW Y11, Y15, Y11                    // c44105e3db
+	VPBLENDD $7, (BX), X9, X2               // c4e331021307
+	VPBLENDD $7, (R11), X9, X2              // c4c331021307
+	VPBLENDD $7, X2, X9, X2                 // c4e33102d207
+	VPBLENDD $7, X11, X9, X2                // c4c33102d307
+	VPBLENDD $7, (BX), X9, X11              // c46331021b07
+	VPBLENDD $7, (R11), X9, X11             // c44331021b07
+	VPBLENDD $7, X2, X9, X11                // c4633102da07
+	VPBLENDD $7, X11, X9, X11               // c4433102db07
 	VPBLENDD $7, (BX), Y15, Y2      // c4e305021307
 	VPBLENDD $7, (R11), Y15, Y2     // c4c305021307
 	VPBLENDD $7, Y2, Y15, Y2        // c4e30502d207
@@ -8352,38 +8352,38 @@
 	VPBLENDD $7, (R11), Y15, Y11    // c44305021b07
 	VPBLENDD $7, Y2, Y15, Y11       // c4630502da07
 	VPBLENDD $7, Y11, Y15, Y11      // c4430502db07
-	//TODO: VPBLENDVB XMM12, (BX), X9, X2   // c4e3314c13c0
-	//TODO: VPBLENDVB XMM12, (R11), X9, X2  // c4c3314c13c0
-	//TODO: VPBLENDVB XMM12, X2, X9, X2     // c4e3314cd2c0
-	//TODO: VPBLENDVB XMM12, X11, X9, X2    // c4c3314cd3c0
-	//TODO: VPBLENDVB XMM12, (BX), X9, X11  // c463314c1bc0
-	//TODO: VPBLENDVB XMM12, (R11), X9, X11 // c443314c1bc0
-	//TODO: VPBLENDVB XMM12, X2, X9, X11    // c463314cdac0
-	//TODO: VPBLENDVB XMM12, X11, X9, X11   // c443314cdbc0
-	//TODO: VPBLENDVB YMM13, (BX), Y15, Y2  // c4e3054c13d0
-	//TODO: VPBLENDVB YMM13, (R11), Y15, Y2 // c4c3054c13d0
-	//TODO: VPBLENDVB YMM13, Y2, Y15, Y2    // c4e3054cd2d0
-	//TODO: VPBLENDVB YMM13, Y11, Y15, Y2   // c4c3054cd3d0
-	//TODO: VPBLENDVB YMM13, (BX), Y15, Y11 // c463054c1bd0
-	//TODO: VPBLENDVB YMM13, (R11), Y15, Y11 // c443054c1bd0
-	//TODO: VPBLENDVB YMM13, Y2, Y15, Y11   // c463054cdad0
-	//TODO: VPBLENDVB YMM13, Y11, Y15, Y11  // c443054cdbd0
-	//TODO: VPBLENDW $7, (BX), X9, X2       // c4e3310e1307
-	//TODO: VPBLENDW $7, (R11), X9, X2      // c4c3310e1307
-	//TODO: VPBLENDW $7, X2, X9, X2         // c4e3310ed207
-	//TODO: VPBLENDW $7, X11, X9, X2        // c4c3310ed307
-	//TODO: VPBLENDW $7, (BX), X9, X11      // c463310e1b07
-	//TODO: VPBLENDW $7, (R11), X9, X11     // c443310e1b07
-	//TODO: VPBLENDW $7, X2, X9, X11        // c463310eda07
-	//TODO: VPBLENDW $7, X11, X9, X11       // c443310edb07
-	//TODO: VPBLENDW $7, (BX), Y15, Y2      // c4e3050e1307
-	//TODO: VPBLENDW $7, (R11), Y15, Y2     // c4c3050e1307
-	//TODO: VPBLENDW $7, Y2, Y15, Y2        // c4e3050ed207
-	//TODO: VPBLENDW $7, Y11, Y15, Y2       // c4c3050ed307
-	//TODO: VPBLENDW $7, (BX), Y15, Y11     // c463050e1b07
-	//TODO: VPBLENDW $7, (R11), Y15, Y11    // c443050e1b07
-	//TODO: VPBLENDW $7, Y2, Y15, Y11       // c463050eda07
-	//TODO: VPBLENDW $7, Y11, Y15, Y11      // c443050edb07
+	VPBLENDVB X12, (BX), X9, X2             // c4e3314c13c0
+	VPBLENDVB X12, (R11), X9, X2            // c4c3314c13c0
+	VPBLENDVB X12, X2, X9, X2               // c4e3314cd2c0
+	VPBLENDVB X12, X11, X9, X2              // c4c3314cd3c0
+	VPBLENDVB X12, (BX), X9, X11            // c463314c1bc0
+	VPBLENDVB X12, (R11), X9, X11           // c443314c1bc0
+	VPBLENDVB X12, X2, X9, X11              // c463314cdac0
+	VPBLENDVB X12, X11, X9, X11             // c443314cdbc0
+	VPBLENDVB Y13, (BX), Y15, Y2            // c4e3054c13d0
+	VPBLENDVB Y13, (R11), Y15, Y2           // c4c3054c13d0
+	VPBLENDVB Y13, Y2, Y15, Y2              // c4e3054cd2d0
+	VPBLENDVB Y13, Y11, Y15, Y2             // c4c3054cd3d0
+	VPBLENDVB Y13, (BX), Y15, Y11           // c463054c1bd0
+	VPBLENDVB Y13, (R11), Y15, Y11          // c443054c1bd0
+	VPBLENDVB Y13, Y2, Y15, Y11             // c463054cdad0
+	VPBLENDVB Y13, Y11, Y15, Y11            // c443054cdbd0
+	VPBLENDW $7, (BX), X9, X2               // c4e3310e1307
+	VPBLENDW $7, (R11), X9, X2              // c4c3310e1307
+	VPBLENDW $7, X2, X9, X2                 // c4e3310ed207
+	VPBLENDW $7, X11, X9, X2                // c4c3310ed307
+	VPBLENDW $7, (BX), X9, X11              // c463310e1b07
+	VPBLENDW $7, (R11), X9, X11             // c443310e1b07
+	VPBLENDW $7, X2, X9, X11                // c463310eda07
+	VPBLENDW $7, X11, X9, X11               // c443310edb07
+	VPBLENDW $7, (BX), Y15, Y2              // c4e3050e1307
+	VPBLENDW $7, (R11), Y15, Y2             // c4c3050e1307
+	VPBLENDW $7, Y2, Y15, Y2                // c4e3050ed207
+	VPBLENDW $7, Y11, Y15, Y2               // c4c3050ed307
+	VPBLENDW $7, (BX), Y15, Y11             // c463050e1b07
+	VPBLENDW $7, (R11), Y15, Y11            // c443050e1b07
+	VPBLENDW $7, Y2, Y15, Y11               // c463050eda07
+	VPBLENDW $7, Y11, Y15, Y11              // c443050edb07
 	VPBROADCASTB (BX), X2                   // c4e2797813
 	VPBROADCASTB (R11), X2                  // c4c2797813
 	VPBROADCASTB X2, X2                     // c4e27978d2
@@ -8400,62 +8400,62 @@
 	VPBROADCASTB (R11), Y11                 // c4427d781b
 	VPBROADCASTB X2, Y11                    // c4627d78da
 	VPBROADCASTB X11, Y11                   // c4427d78db
-	//TODO: VPBROADCASTD (BX), X2           // c4e2795813
-	//TODO: VPBROADCASTD (R11), X2          // c4c2795813
-	//TODO: VPBROADCASTD X2, X2             // c4e27958d2
-	//TODO: VPBROADCASTD X11, X2            // c4c27958d3
-	//TODO: VPBROADCASTD (BX), X11          // c46279581b
-	//TODO: VPBROADCASTD (R11), X11         // c44279581b
-	//TODO: VPBROADCASTD X2, X11            // c4627958da
-	//TODO: VPBROADCASTD X11, X11           // c4427958db
-	//TODO: VPBROADCASTD (BX), Y2           // c4e27d5813
-	//TODO: VPBROADCASTD (R11), Y2          // c4c27d5813
-	//TODO: VPBROADCASTD X2, Y2             // c4e27d58d2
-	//TODO: VPBROADCASTD X11, Y2            // c4c27d58d3
-	//TODO: VPBROADCASTD (BX), Y11          // c4627d581b
-	//TODO: VPBROADCASTD (R11), Y11         // c4427d581b
-	//TODO: VPBROADCASTD X2, Y11            // c4627d58da
-	//TODO: VPBROADCASTD X11, Y11           // c4427d58db
-	//TODO: VPBROADCASTQ (BX), X2           // c4e2795913
-	//TODO: VPBROADCASTQ (R11), X2          // c4c2795913
-	//TODO: VPBROADCASTQ X2, X2             // c4e27959d2
-	//TODO: VPBROADCASTQ X11, X2            // c4c27959d3
-	//TODO: VPBROADCASTQ (BX), X11          // c46279591b
-	//TODO: VPBROADCASTQ (R11), X11         // c44279591b
-	//TODO: VPBROADCASTQ X2, X11            // c4627959da
-	//TODO: VPBROADCASTQ X11, X11           // c4427959db
-	//TODO: VPBROADCASTQ (BX), Y2           // c4e27d5913
-	//TODO: VPBROADCASTQ (R11), Y2          // c4c27d5913
-	//TODO: VPBROADCASTQ X2, Y2             // c4e27d59d2
-	//TODO: VPBROADCASTQ X11, Y2            // c4c27d59d3
-	//TODO: VPBROADCASTQ (BX), Y11          // c4627d591b
-	//TODO: VPBROADCASTQ (R11), Y11         // c4427d591b
-	//TODO: VPBROADCASTQ X2, Y11            // c4627d59da
-	//TODO: VPBROADCASTQ X11, Y11           // c4427d59db
-	//TODO: VPBROADCASTW (BX), X2           // c4e2797913
-	//TODO: VPBROADCASTW (R11), X2          // c4c2797913
-	//TODO: VPBROADCASTW X2, X2             // c4e27979d2
-	//TODO: VPBROADCASTW X11, X2            // c4c27979d3
-	//TODO: VPBROADCASTW (BX), X11          // c46279791b
-	//TODO: VPBROADCASTW (R11), X11         // c44279791b
-	//TODO: VPBROADCASTW X2, X11            // c4627979da
-	//TODO: VPBROADCASTW X11, X11           // c4427979db
-	//TODO: VPBROADCASTW (BX), Y2           // c4e27d7913
-	//TODO: VPBROADCASTW (R11), Y2          // c4c27d7913
-	//TODO: VPBROADCASTW X2, Y2             // c4e27d79d2
-	//TODO: VPBROADCASTW X11, Y2            // c4c27d79d3
-	//TODO: VPBROADCASTW (BX), Y11          // c4627d791b
-	//TODO: VPBROADCASTW (R11), Y11         // c4427d791b
-	//TODO: VPBROADCASTW X2, Y11            // c4627d79da
-	//TODO: VPBROADCASTW X11, Y11           // c4427d79db
-	//TODO: VPCLMULQDQ $7, (BX), X9, X2     // c4e331441307
-	//TODO: VPCLMULQDQ $7, (R11), X9, X2    // c4c331441307
-	//TODO: VPCLMULQDQ $7, X2, X9, X2       // c4e33144d207
-	//TODO: VPCLMULQDQ $7, X11, X9, X2      // c4c33144d307
-	//TODO: VPCLMULQDQ $7, (BX), X9, X11    // c46331441b07
-	//TODO: VPCLMULQDQ $7, (R11), X9, X11   // c44331441b07
-	//TODO: VPCLMULQDQ $7, X2, X9, X11      // c4633144da07
-	//TODO: VPCLMULQDQ $7, X11, X9, X11     // c4433144db07
+	VPBROADCASTD (BX), X2                   // c4e2795813
+	VPBROADCASTD (R11), X2                  // c4c2795813
+	VPBROADCASTD X2, X2                     // c4e27958d2
+	VPBROADCASTD X11, X2                    // c4c27958d3
+	VPBROADCASTD (BX), X11                  // c46279581b
+	VPBROADCASTD (R11), X11                 // c44279581b
+	VPBROADCASTD X2, X11                    // c4627958da
+	VPBROADCASTD X11, X11                   // c4427958db
+	VPBROADCASTD (BX), Y2                   // c4e27d5813
+	VPBROADCASTD (R11), Y2                  // c4c27d5813
+	VPBROADCASTD X2, Y2                     // c4e27d58d2
+	VPBROADCASTD X11, Y2                    // c4c27d58d3
+	VPBROADCASTD (BX), Y11                  // c4627d581b
+	VPBROADCASTD (R11), Y11                 // c4427d581b
+	VPBROADCASTD X2, Y11                    // c4627d58da
+	VPBROADCASTD X11, Y11                   // c4427d58db
+	VPBROADCASTQ (BX), X2                   // c4e2795913
+	VPBROADCASTQ (R11), X2                  // c4c2795913
+	VPBROADCASTQ X2, X2                     // c4e27959d2
+	VPBROADCASTQ X11, X2                    // c4c27959d3
+	VPBROADCASTQ (BX), X11                  // c46279591b
+	VPBROADCASTQ (R11), X11                 // c44279591b
+	VPBROADCASTQ X2, X11                    // c4627959da
+	VPBROADCASTQ X11, X11                   // c4427959db
+	VPBROADCASTQ (BX), Y2                   // c4e27d5913
+	VPBROADCASTQ (R11), Y2                  // c4c27d5913
+	VPBROADCASTQ X2, Y2                     // c4e27d59d2
+	VPBROADCASTQ X11, Y2                    // c4c27d59d3
+	VPBROADCASTQ (BX), Y11                  // c4627d591b
+	VPBROADCASTQ (R11), Y11                 // c4427d591b
+	VPBROADCASTQ X2, Y11                    // c4627d59da
+	VPBROADCASTQ X11, Y11                   // c4427d59db
+	VPBROADCASTW (BX), X2                   // c4e2797913
+	VPBROADCASTW (R11), X2                  // c4c2797913
+	VPBROADCASTW X2, X2                     // c4e27979d2
+	VPBROADCASTW X11, X2                    // c4c27979d3
+	VPBROADCASTW (BX), X11                  // c46279791b
+	VPBROADCASTW (R11), X11                 // c44279791b
+	VPBROADCASTW X2, X11                    // c4627979da
+	VPBROADCASTW X11, X11                   // c4427979db
+	VPBROADCASTW (BX), Y2                   // c4e27d7913
+	VPBROADCASTW (R11), Y2                  // c4c27d7913
+	VPBROADCASTW X2, Y2                     // c4e27d79d2
+	VPBROADCASTW X11, Y2                    // c4c27d79d3
+	VPBROADCASTW (BX), Y11                  // c4627d791b
+	VPBROADCASTW (R11), Y11                 // c4427d791b
+	VPBROADCASTW X2, Y11                    // c4627d79da
+	VPBROADCASTW X11, Y11                   // c4427d79db
+	VPCLMULQDQ $7, (BX), X9, X2             // c4e331441307
+	VPCLMULQDQ $7, (R11), X9, X2            // c4c331441307
+	VPCLMULQDQ $7, X2, X9, X2               // c4e33144d207
+	VPCLMULQDQ $7, X11, X9, X2              // c4c33144d307
+	VPCLMULQDQ $7, (BX), X9, X11            // c46331441b07
+	VPCLMULQDQ $7, (R11), X9, X11           // c44331441b07
+	VPCLMULQDQ $7, X2, X9, X11              // c4633144da07
+	VPCLMULQDQ $7, X11, X9, X11             // c4433144db07
 	VPCMPEQB (BX), X9, X2                   // c4e1317413 or c5b17413
 	VPCMPEQB (R11), X9, X2                  // c4c1317413
 	VPCMPEQB X2, X9, X2                     // c4e13174d2 or c5b174d2
@@ -8472,150 +8472,150 @@
 	VPCMPEQB (R11), Y15, Y11                // c44105741b
 	VPCMPEQB Y2, Y15, Y11                   // c4610574da or c50574da
 	VPCMPEQB Y11, Y15, Y11                  // c4410574db
-	//TODO: VPCMPEQD (BX), X9, X2           // c4e1317613 or c5b17613
-	//TODO: VPCMPEQD (R11), X9, X2          // c4c1317613
-	//TODO: VPCMPEQD X2, X9, X2             // c4e13176d2 or c5b176d2
-	//TODO: VPCMPEQD X11, X9, X2            // c4c13176d3
-	//TODO: VPCMPEQD (BX), X9, X11          // c46131761b or c531761b
-	//TODO: VPCMPEQD (R11), X9, X11         // c44131761b
-	//TODO: VPCMPEQD X2, X9, X11            // c4613176da or c53176da
-	//TODO: VPCMPEQD X11, X9, X11           // c4413176db
-	//TODO: VPCMPEQD (BX), Y15, Y2          // c4e1057613 or c5857613
-	//TODO: VPCMPEQD (R11), Y15, Y2         // c4c1057613
-	//TODO: VPCMPEQD Y2, Y15, Y2            // c4e10576d2 or c58576d2
-	//TODO: VPCMPEQD Y11, Y15, Y2           // c4c10576d3
-	//TODO: VPCMPEQD (BX), Y15, Y11         // c46105761b or c505761b
-	//TODO: VPCMPEQD (R11), Y15, Y11        // c44105761b
-	//TODO: VPCMPEQD Y2, Y15, Y11           // c4610576da or c50576da
-	//TODO: VPCMPEQD Y11, Y15, Y11          // c4410576db
-	//TODO: VPCMPEQQ (BX), X9, X2           // c4e2312913
-	//TODO: VPCMPEQQ (R11), X9, X2          // c4c2312913
-	//TODO: VPCMPEQQ X2, X9, X2             // c4e23129d2
-	//TODO: VPCMPEQQ X11, X9, X2            // c4c23129d3
-	//TODO: VPCMPEQQ (BX), X9, X11          // c46231291b
-	//TODO: VPCMPEQQ (R11), X9, X11         // c44231291b
-	//TODO: VPCMPEQQ X2, X9, X11            // c4623129da
-	//TODO: VPCMPEQQ X11, X9, X11           // c4423129db
-	//TODO: VPCMPEQQ (BX), Y15, Y2          // c4e2052913
-	//TODO: VPCMPEQQ (R11), Y15, Y2         // c4c2052913
-	//TODO: VPCMPEQQ Y2, Y15, Y2            // c4e20529d2
-	//TODO: VPCMPEQQ Y11, Y15, Y2           // c4c20529d3
-	//TODO: VPCMPEQQ (BX), Y15, Y11         // c46205291b
-	//TODO: VPCMPEQQ (R11), Y15, Y11        // c44205291b
-	//TODO: VPCMPEQQ Y2, Y15, Y11           // c4620529da
-	//TODO: VPCMPEQQ Y11, Y15, Y11          // c4420529db
-	//TODO: VPCMPEQW (BX), X9, X2           // c4e1317513 or c5b17513
-	//TODO: VPCMPEQW (R11), X9, X2          // c4c1317513
-	//TODO: VPCMPEQW X2, X9, X2             // c4e13175d2 or c5b175d2
-	//TODO: VPCMPEQW X11, X9, X2            // c4c13175d3
-	//TODO: VPCMPEQW (BX), X9, X11          // c46131751b or c531751b
-	//TODO: VPCMPEQW (R11), X9, X11         // c44131751b
-	//TODO: VPCMPEQW X2, X9, X11            // c4613175da or c53175da
-	//TODO: VPCMPEQW X11, X9, X11           // c4413175db
-	//TODO: VPCMPEQW (BX), Y15, Y2          // c4e1057513 or c5857513
-	//TODO: VPCMPEQW (R11), Y15, Y2         // c4c1057513
-	//TODO: VPCMPEQW Y2, Y15, Y2            // c4e10575d2 or c58575d2
-	//TODO: VPCMPEQW Y11, Y15, Y2           // c4c10575d3
-	//TODO: VPCMPEQW (BX), Y15, Y11         // c46105751b or c505751b
-	//TODO: VPCMPEQW (R11), Y15, Y11        // c44105751b
-	//TODO: VPCMPEQW Y2, Y15, Y11           // c4610575da or c50575da
-	//TODO: VPCMPEQW Y11, Y15, Y11          // c4410575db
-	//TODO: VPCMPESTRI $7, (BX), X2         // c4e379611307
-	//TODO: VPCMPESTRI $7, (R11), X2        // c4c379611307
-	//TODO: VPCMPESTRI $7, X2, X2           // c4e37961d207
-	//TODO: VPCMPESTRI $7, X11, X2          // c4c37961d307
-	//TODO: VPCMPESTRI $7, (BX), X11        // c46379611b07
-	//TODO: VPCMPESTRI $7, (R11), X11       // c44379611b07
-	//TODO: VPCMPESTRI $7, X2, X11          // c4637961da07
-	//TODO: VPCMPESTRI $7, X11, X11         // c4437961db07
-	//TODO: VPCMPESTRM $7, (BX), X2         // c4e379601307
-	//TODO: VPCMPESTRM $7, (R11), X2        // c4c379601307
-	//TODO: VPCMPESTRM $7, X2, X2           // c4e37960d207
-	//TODO: VPCMPESTRM $7, X11, X2          // c4c37960d307
-	//TODO: VPCMPESTRM $7, (BX), X11        // c46379601b07
-	//TODO: VPCMPESTRM $7, (R11), X11       // c44379601b07
-	//TODO: VPCMPESTRM $7, X2, X11          // c4637960da07
-	//TODO: VPCMPESTRM $7, X11, X11         // c4437960db07
-	//TODO: VPCMPGTB (BX), X9, X2           // c4e1316413 or c5b16413
-	//TODO: VPCMPGTB (R11), X9, X2          // c4c1316413
-	//TODO: VPCMPGTB X2, X9, X2             // c4e13164d2 or c5b164d2
-	//TODO: VPCMPGTB X11, X9, X2            // c4c13164d3
-	//TODO: VPCMPGTB (BX), X9, X11          // c46131641b or c531641b
-	//TODO: VPCMPGTB (R11), X9, X11         // c44131641b
-	//TODO: VPCMPGTB X2, X9, X11            // c4613164da or c53164da
-	//TODO: VPCMPGTB X11, X9, X11           // c4413164db
-	//TODO: VPCMPGTB (BX), Y15, Y2          // c4e1056413 or c5856413
-	//TODO: VPCMPGTB (R11), Y15, Y2         // c4c1056413
-	//TODO: VPCMPGTB Y2, Y15, Y2            // c4e10564d2 or c58564d2
-	//TODO: VPCMPGTB Y11, Y15, Y2           // c4c10564d3
-	//TODO: VPCMPGTB (BX), Y15, Y11         // c46105641b or c505641b
-	//TODO: VPCMPGTB (R11), Y15, Y11        // c44105641b
-	//TODO: VPCMPGTB Y2, Y15, Y11           // c4610564da or c50564da
-	//TODO: VPCMPGTB Y11, Y15, Y11          // c4410564db
-	//TODO: VPCMPGTD (BX), X9, X2           // c4e1316613 or c5b16613
-	//TODO: VPCMPGTD (R11), X9, X2          // c4c1316613
-	//TODO: VPCMPGTD X2, X9, X2             // c4e13166d2 or c5b166d2
-	//TODO: VPCMPGTD X11, X9, X2            // c4c13166d3
-	//TODO: VPCMPGTD (BX), X9, X11          // c46131661b or c531661b
-	//TODO: VPCMPGTD (R11), X9, X11         // c44131661b
-	//TODO: VPCMPGTD X2, X9, X11            // c4613166da or c53166da
-	//TODO: VPCMPGTD X11, X9, X11           // c4413166db
-	//TODO: VPCMPGTD (BX), Y15, Y2          // c4e1056613 or c5856613
-	//TODO: VPCMPGTD (R11), Y15, Y2         // c4c1056613
-	//TODO: VPCMPGTD Y2, Y15, Y2            // c4e10566d2 or c58566d2
-	//TODO: VPCMPGTD Y11, Y15, Y2           // c4c10566d3
-	//TODO: VPCMPGTD (BX), Y15, Y11         // c46105661b or c505661b
-	//TODO: VPCMPGTD (R11), Y15, Y11        // c44105661b
-	//TODO: VPCMPGTD Y2, Y15, Y11           // c4610566da or c50566da
-	//TODO: VPCMPGTD Y11, Y15, Y11          // c4410566db
-	//TODO: VPCMPGTQ (BX), X9, X2           // c4e2313713
-	//TODO: VPCMPGTQ (R11), X9, X2          // c4c2313713
-	//TODO: VPCMPGTQ X2, X9, X2             // c4e23137d2
-	//TODO: VPCMPGTQ X11, X9, X2            // c4c23137d3
-	//TODO: VPCMPGTQ (BX), X9, X11          // c46231371b
-	//TODO: VPCMPGTQ (R11), X9, X11         // c44231371b
-	//TODO: VPCMPGTQ X2, X9, X11            // c4623137da
-	//TODO: VPCMPGTQ X11, X9, X11           // c4423137db
-	//TODO: VPCMPGTQ (BX), Y15, Y2          // c4e2053713
-	//TODO: VPCMPGTQ (R11), Y15, Y2         // c4c2053713
-	//TODO: VPCMPGTQ Y2, Y15, Y2            // c4e20537d2
-	//TODO: VPCMPGTQ Y11, Y15, Y2           // c4c20537d3
-	//TODO: VPCMPGTQ (BX), Y15, Y11         // c46205371b
-	//TODO: VPCMPGTQ (R11), Y15, Y11        // c44205371b
-	//TODO: VPCMPGTQ Y2, Y15, Y11           // c4620537da
-	//TODO: VPCMPGTQ Y11, Y15, Y11          // c4420537db
-	//TODO: VPCMPGTW (BX), X9, X2           // c4e1316513 or c5b16513
-	//TODO: VPCMPGTW (R11), X9, X2          // c4c1316513
-	//TODO: VPCMPGTW X2, X9, X2             // c4e13165d2 or c5b165d2
-	//TODO: VPCMPGTW X11, X9, X2            // c4c13165d3
-	//TODO: VPCMPGTW (BX), X9, X11          // c46131651b or c531651b
-	//TODO: VPCMPGTW (R11), X9, X11         // c44131651b
-	//TODO: VPCMPGTW X2, X9, X11            // c4613165da or c53165da
-	//TODO: VPCMPGTW X11, X9, X11           // c4413165db
-	//TODO: VPCMPGTW (BX), Y15, Y2          // c4e1056513 or c5856513
-	//TODO: VPCMPGTW (R11), Y15, Y2         // c4c1056513
-	//TODO: VPCMPGTW Y2, Y15, Y2            // c4e10565d2 or c58565d2
-	//TODO: VPCMPGTW Y11, Y15, Y2           // c4c10565d3
-	//TODO: VPCMPGTW (BX), Y15, Y11         // c46105651b or c505651b
-	//TODO: VPCMPGTW (R11), Y15, Y11        // c44105651b
-	//TODO: VPCMPGTW Y2, Y15, Y11           // c4610565da or c50565da
-	//TODO: VPCMPGTW Y11, Y15, Y11          // c4410565db
-	//TODO: VPCMPISTRI $7, (BX), X2         // c4e379631307
-	//TODO: VPCMPISTRI $7, (R11), X2        // c4c379631307
-	//TODO: VPCMPISTRI $7, X2, X2           // c4e37963d207
-	//TODO: VPCMPISTRI $7, X11, X2          // c4c37963d307
-	//TODO: VPCMPISTRI $7, (BX), X11        // c46379631b07
-	//TODO: VPCMPISTRI $7, (R11), X11       // c44379631b07
-	//TODO: VPCMPISTRI $7, X2, X11          // c4637963da07
-	//TODO: VPCMPISTRI $7, X11, X11         // c4437963db07
-	//TODO: VPCMPISTRM $7, (BX), X2         // c4e379621307
-	//TODO: VPCMPISTRM $7, (R11), X2        // c4c379621307
-	//TODO: VPCMPISTRM $7, X2, X2           // c4e37962d207
-	//TODO: VPCMPISTRM $7, X11, X2          // c4c37962d307
-	//TODO: VPCMPISTRM $7, (BX), X11        // c46379621b07
-	//TODO: VPCMPISTRM $7, (R11), X11       // c44379621b07
-	//TODO: VPCMPISTRM $7, X2, X11          // c4637962da07
-	//TODO: VPCMPISTRM $7, X11, X11         // c4437962db07
+	VPCMPEQD (BX), X9, X2                   // c4e1317613 or c5b17613
+	VPCMPEQD (R11), X9, X2                  // c4c1317613
+	VPCMPEQD X2, X9, X2                     // c4e13176d2 or c5b176d2
+	VPCMPEQD X11, X9, X2                    // c4c13176d3
+	VPCMPEQD (BX), X9, X11                  // c46131761b or c531761b
+	VPCMPEQD (R11), X9, X11                 // c44131761b
+	VPCMPEQD X2, X9, X11                    // c4613176da or c53176da
+	VPCMPEQD X11, X9, X11                   // c4413176db
+	VPCMPEQD (BX), Y15, Y2                  // c4e1057613 or c5857613
+	VPCMPEQD (R11), Y15, Y2                 // c4c1057613
+	VPCMPEQD Y2, Y15, Y2                    // c4e10576d2 or c58576d2
+	VPCMPEQD Y11, Y15, Y2                   // c4c10576d3
+	VPCMPEQD (BX), Y15, Y11                 // c46105761b or c505761b
+	VPCMPEQD (R11), Y15, Y11                // c44105761b
+	VPCMPEQD Y2, Y15, Y11                   // c4610576da or c50576da
+	VPCMPEQD Y11, Y15, Y11                  // c4410576db
+	VPCMPEQQ (BX), X9, X2                   // c4e2312913
+	VPCMPEQQ (R11), X9, X2                  // c4c2312913
+	VPCMPEQQ X2, X9, X2                     // c4e23129d2
+	VPCMPEQQ X11, X9, X2                    // c4c23129d3
+	VPCMPEQQ (BX), X9, X11                  // c46231291b
+	VPCMPEQQ (R11), X9, X11                 // c44231291b
+	VPCMPEQQ X2, X9, X11                    // c4623129da
+	VPCMPEQQ X11, X9, X11                   // c4423129db
+	VPCMPEQQ (BX), Y15, Y2                  // c4e2052913
+	VPCMPEQQ (R11), Y15, Y2                 // c4c2052913
+	VPCMPEQQ Y2, Y15, Y2                    // c4e20529d2
+	VPCMPEQQ Y11, Y15, Y2                   // c4c20529d3
+	VPCMPEQQ (BX), Y15, Y11                 // c46205291b
+	VPCMPEQQ (R11), Y15, Y11                // c44205291b
+	VPCMPEQQ Y2, Y15, Y11                   // c4620529da
+	VPCMPEQQ Y11, Y15, Y11                  // c4420529db
+	VPCMPEQW (BX), X9, X2                   // c4e1317513 or c5b17513
+	VPCMPEQW (R11), X9, X2                  // c4c1317513
+	VPCMPEQW X2, X9, X2                     // c4e13175d2 or c5b175d2
+	VPCMPEQW X11, X9, X2                    // c4c13175d3
+	VPCMPEQW (BX), X9, X11                  // c46131751b or c531751b
+	VPCMPEQW (R11), X9, X11                 // c44131751b
+	VPCMPEQW X2, X9, X11                    // c4613175da or c53175da
+	VPCMPEQW X11, X9, X11                   // c4413175db
+	VPCMPEQW (BX), Y15, Y2                  // c4e1057513 or c5857513
+	VPCMPEQW (R11), Y15, Y2                 // c4c1057513
+	VPCMPEQW Y2, Y15, Y2                    // c4e10575d2 or c58575d2
+	VPCMPEQW Y11, Y15, Y2                   // c4c10575d3
+	VPCMPEQW (BX), Y15, Y11                 // c46105751b or c505751b
+	VPCMPEQW (R11), Y15, Y11                // c44105751b
+	VPCMPEQW Y2, Y15, Y11                   // c4610575da or c50575da
+	VPCMPEQW Y11, Y15, Y11                  // c4410575db
+	VPCMPESTRI $7, (BX), X2                 // c4e379611307
+	VPCMPESTRI $7, (R11), X2                // c4c379611307
+	VPCMPESTRI $7, X2, X2                   // c4e37961d207
+	VPCMPESTRI $7, X11, X2                  // c4c37961d307
+	VPCMPESTRI $7, (BX), X11                // c46379611b07
+	VPCMPESTRI $7, (R11), X11               // c44379611b07
+	VPCMPESTRI $7, X2, X11                  // c4637961da07
+	VPCMPESTRI $7, X11, X11                 // c4437961db07
+	VPCMPESTRM $7, (BX), X2                 // c4e379601307
+	VPCMPESTRM $7, (R11), X2                // c4c379601307
+	VPCMPESTRM $7, X2, X2                   // c4e37960d207
+	VPCMPESTRM $7, X11, X2                  // c4c37960d307
+	VPCMPESTRM $7, (BX), X11                // c46379601b07
+	VPCMPESTRM $7, (R11), X11               // c44379601b07
+	VPCMPESTRM $7, X2, X11                  // c4637960da07
+	VPCMPESTRM $7, X11, X11                 // c4437960db07
+	VPCMPGTB (BX), X9, X2                   // c4e1316413 or c5b16413
+	VPCMPGTB (R11), X9, X2                  // c4c1316413
+	VPCMPGTB X2, X9, X2                     // c4e13164d2 or c5b164d2
+	VPCMPGTB X11, X9, X2                    // c4c13164d3
+	VPCMPGTB (BX), X9, X11                  // c46131641b or c531641b
+	VPCMPGTB (R11), X9, X11                 // c44131641b
+	VPCMPGTB X2, X9, X11                    // c4613164da or c53164da
+	VPCMPGTB X11, X9, X11                   // c4413164db
+	VPCMPGTB (BX), Y15, Y2                  // c4e1056413 or c5856413
+	VPCMPGTB (R11), Y15, Y2                 // c4c1056413
+	VPCMPGTB Y2, Y15, Y2                    // c4e10564d2 or c58564d2
+	VPCMPGTB Y11, Y15, Y2                   // c4c10564d3
+	VPCMPGTB (BX), Y15, Y11                 // c46105641b or c505641b
+	VPCMPGTB (R11), Y15, Y11                // c44105641b
+	VPCMPGTB Y2, Y15, Y11                   // c4610564da or c50564da
+	VPCMPGTB Y11, Y15, Y11                  // c4410564db
+	VPCMPGTD (BX), X9, X2                   // c4e1316613 or c5b16613
+	VPCMPGTD (R11), X9, X2                  // c4c1316613
+	VPCMPGTD X2, X9, X2                     // c4e13166d2 or c5b166d2
+	VPCMPGTD X11, X9, X2                    // c4c13166d3
+	VPCMPGTD (BX), X9, X11                  // c46131661b or c531661b
+	VPCMPGTD (R11), X9, X11                 // c44131661b
+	VPCMPGTD X2, X9, X11                    // c4613166da or c53166da
+	VPCMPGTD X11, X9, X11                   // c4413166db
+	VPCMPGTD (BX), Y15, Y2                  // c4e1056613 or c5856613
+	VPCMPGTD (R11), Y15, Y2                 // c4c1056613
+	VPCMPGTD Y2, Y15, Y2                    // c4e10566d2 or c58566d2
+	VPCMPGTD Y11, Y15, Y2                   // c4c10566d3
+	VPCMPGTD (BX), Y15, Y11                 // c46105661b or c505661b
+	VPCMPGTD (R11), Y15, Y11                // c44105661b
+	VPCMPGTD Y2, Y15, Y11                   // c4610566da or c50566da
+	VPCMPGTD Y11, Y15, Y11                  // c4410566db
+	VPCMPGTQ (BX), X9, X2                   // c4e2313713
+	VPCMPGTQ (R11), X9, X2                  // c4c2313713
+	VPCMPGTQ X2, X9, X2                     // c4e23137d2
+	VPCMPGTQ X11, X9, X2                    // c4c23137d3
+	VPCMPGTQ (BX), X9, X11                  // c46231371b
+	VPCMPGTQ (R11), X9, X11                 // c44231371b
+	VPCMPGTQ X2, X9, X11                    // c4623137da
+	VPCMPGTQ X11, X9, X11                   // c4423137db
+	VPCMPGTQ (BX), Y15, Y2                  // c4e2053713
+	VPCMPGTQ (R11), Y15, Y2                 // c4c2053713
+	VPCMPGTQ Y2, Y15, Y2                    // c4e20537d2
+	VPCMPGTQ Y11, Y15, Y2                   // c4c20537d3
+	VPCMPGTQ (BX), Y15, Y11                 // c46205371b
+	VPCMPGTQ (R11), Y15, Y11                // c44205371b
+	VPCMPGTQ Y2, Y15, Y11                   // c4620537da
+	VPCMPGTQ Y11, Y15, Y11                  // c4420537db
+	VPCMPGTW (BX), X9, X2                   // c4e1316513 or c5b16513
+	VPCMPGTW (R11), X9, X2                  // c4c1316513
+	VPCMPGTW X2, X9, X2                     // c4e13165d2 or c5b165d2
+	VPCMPGTW X11, X9, X2                    // c4c13165d3
+	VPCMPGTW (BX), X9, X11                  // c46131651b or c531651b
+	VPCMPGTW (R11), X9, X11                 // c44131651b
+	VPCMPGTW X2, X9, X11                    // c4613165da or c53165da
+	VPCMPGTW X11, X9, X11                   // c4413165db
+	VPCMPGTW (BX), Y15, Y2                  // c4e1056513 or c5856513
+	VPCMPGTW (R11), Y15, Y2                 // c4c1056513
+	VPCMPGTW Y2, Y15, Y2                    // c4e10565d2 or c58565d2
+	VPCMPGTW Y11, Y15, Y2                   // c4c10565d3
+	VPCMPGTW (BX), Y15, Y11                 // c46105651b or c505651b
+	VPCMPGTW (R11), Y15, Y11                // c44105651b
+	VPCMPGTW Y2, Y15, Y11                   // c4610565da or c50565da
+	VPCMPGTW Y11, Y15, Y11                  // c4410565db
+	VPCMPISTRI $7, (BX), X2                 // c4e379631307
+	VPCMPISTRI $7, (R11), X2                // c4c379631307
+	VPCMPISTRI $7, X2, X2                   // c4e37963d207
+	VPCMPISTRI $7, X11, X2                  // c4c37963d307
+	VPCMPISTRI $7, (BX), X11                // c46379631b07
+	VPCMPISTRI $7, (R11), X11               // c44379631b07
+	VPCMPISTRI $7, X2, X11                  // c4637963da07
+	VPCMPISTRI $7, X11, X11                 // c4437963db07
+	VPCMPISTRM $7, (BX), X2                 // c4e379621307
+	VPCMPISTRM $7, (R11), X2                // c4c379621307
+	VPCMPISTRM $7, X2, X2                   // c4e37962d207
+	VPCMPISTRM $7, X11, X2                  // c4c37962d307
+	VPCMPISTRM $7, (BX), X11                // c46379621b07
+	VPCMPISTRM $7, (R11), X11               // c44379621b07
+	VPCMPISTRM $7, X2, X11                  // c4637962da07
+	VPCMPISTRM $7, X11, X11                 // c4437962db07
 	VPERM2F128 $7, (BX), Y15, Y2    // c4e305061307
 	VPERM2F128 $7, (R11), Y15, Y2   // c4c305061307
 	VPERM2F128 $7, Y2, Y15, Y2      // c4e30506d207
@@ -8632,526 +8632,526 @@
 	VPERM2I128 $7, (R11), Y15, Y11  // c44305461b07
 	VPERM2I128 $7, Y2, Y15, Y11     // c4630546da07
 	VPERM2I128 $7, Y11, Y15, Y11    // c4430546db07
-	//TODO: VPERMD (BX), Y15, Y2            // c4e2053613
-	//TODO: VPERMD (R11), Y15, Y2           // c4c2053613
-	//TODO: VPERMD Y2, Y15, Y2              // c4e20536d2
-	//TODO: VPERMD Y11, Y15, Y2             // c4c20536d3
-	//TODO: VPERMD (BX), Y15, Y11           // c46205361b
-	//TODO: VPERMD (R11), Y15, Y11          // c44205361b
-	//TODO: VPERMD Y2, Y15, Y11             // c4620536da
-	//TODO: VPERMD Y11, Y15, Y11            // c4420536db
-	//TODO: VPERMILPD $7, (BX), X2          // c4e379051307
-	//TODO: VPERMILPD $7, (R11), X2         // c4c379051307
-	//TODO: VPERMILPD $7, X2, X2            // c4e37905d207
-	//TODO: VPERMILPD $7, X11, X2           // c4c37905d307
-	//TODO: VPERMILPD $7, (BX), X11         // c46379051b07
-	//TODO: VPERMILPD $7, (R11), X11        // c44379051b07
-	//TODO: VPERMILPD $7, X2, X11           // c4637905da07
-	//TODO: VPERMILPD $7, X11, X11          // c4437905db07
-	//TODO: VPERMILPD (BX), X9, X2          // c4e2310d13
-	//TODO: VPERMILPD (R11), X9, X2         // c4c2310d13
-	//TODO: VPERMILPD X2, X9, X2            // c4e2310dd2
-	//TODO: VPERMILPD X11, X9, X2           // c4c2310dd3
-	//TODO: VPERMILPD (BX), X9, X11         // c462310d1b
-	//TODO: VPERMILPD (R11), X9, X11        // c442310d1b
-	//TODO: VPERMILPD X2, X9, X11           // c462310dda
-	//TODO: VPERMILPD X11, X9, X11          // c442310ddb
-	//TODO: VPERMILPD $7, (BX), Y2          // c4e37d051307
-	//TODO: VPERMILPD $7, (R11), Y2         // c4c37d051307
-	//TODO: VPERMILPD $7, Y2, Y2            // c4e37d05d207
-	//TODO: VPERMILPD $7, Y11, Y2           // c4c37d05d307
-	//TODO: VPERMILPD $7, (BX), Y11         // c4637d051b07
-	//TODO: VPERMILPD $7, (R11), Y11        // c4437d051b07
-	//TODO: VPERMILPD $7, Y2, Y11           // c4637d05da07
-	//TODO: VPERMILPD $7, Y11, Y11          // c4437d05db07
-	//TODO: VPERMILPD (BX), Y15, Y2         // c4e2050d13
-	//TODO: VPERMILPD (R11), Y15, Y2        // c4c2050d13
-	//TODO: VPERMILPD Y2, Y15, Y2           // c4e2050dd2
-	//TODO: VPERMILPD Y11, Y15, Y2          // c4c2050dd3
-	//TODO: VPERMILPD (BX), Y15, Y11        // c462050d1b
-	//TODO: VPERMILPD (R11), Y15, Y11       // c442050d1b
-	//TODO: VPERMILPD Y2, Y15, Y11          // c462050dda
-	//TODO: VPERMILPD Y11, Y15, Y11         // c442050ddb
-	//TODO: VPERMILPS $7, (BX), X2          // c4e379041307
-	//TODO: VPERMILPS $7, (R11), X2         // c4c379041307
-	//TODO: VPERMILPS $7, X2, X2            // c4e37904d207
-	//TODO: VPERMILPS $7, X11, X2           // c4c37904d307
-	//TODO: VPERMILPS $7, (BX), X11         // c46379041b07
-	//TODO: VPERMILPS $7, (R11), X11        // c44379041b07
-	//TODO: VPERMILPS $7, X2, X11           // c4637904da07
-	//TODO: VPERMILPS $7, X11, X11          // c4437904db07
-	//TODO: VPERMILPS (BX), X9, X2          // c4e2310c13
-	//TODO: VPERMILPS (R11), X9, X2         // c4c2310c13
-	//TODO: VPERMILPS X2, X9, X2            // c4e2310cd2
-	//TODO: VPERMILPS X11, X9, X2           // c4c2310cd3
-	//TODO: VPERMILPS (BX), X9, X11         // c462310c1b
-	//TODO: VPERMILPS (R11), X9, X11        // c442310c1b
-	//TODO: VPERMILPS X2, X9, X11           // c462310cda
-	//TODO: VPERMILPS X11, X9, X11          // c442310cdb
-	//TODO: VPERMILPS $7, (BX), Y2          // c4e37d041307
-	//TODO: VPERMILPS $7, (R11), Y2         // c4c37d041307
-	//TODO: VPERMILPS $7, Y2, Y2            // c4e37d04d207
-	//TODO: VPERMILPS $7, Y11, Y2           // c4c37d04d307
-	//TODO: VPERMILPS $7, (BX), Y11         // c4637d041b07
-	//TODO: VPERMILPS $7, (R11), Y11        // c4437d041b07
-	//TODO: VPERMILPS $7, Y2, Y11           // c4637d04da07
-	//TODO: VPERMILPS $7, Y11, Y11          // c4437d04db07
-	//TODO: VPERMILPS (BX), Y15, Y2         // c4e2050c13
-	//TODO: VPERMILPS (R11), Y15, Y2        // c4c2050c13
-	//TODO: VPERMILPS Y2, Y15, Y2           // c4e2050cd2
-	//TODO: VPERMILPS Y11, Y15, Y2          // c4c2050cd3
-	//TODO: VPERMILPS (BX), Y15, Y11        // c462050c1b
-	//TODO: VPERMILPS (R11), Y15, Y11       // c442050c1b
-	//TODO: VPERMILPS Y2, Y15, Y11          // c462050cda
-	//TODO: VPERMILPS Y11, Y15, Y11         // c442050cdb
-	//TODO: VPERMPD $7, (BX), Y2            // c4e3fd011307
-	//TODO: VPERMPD $7, (R11), Y2           // c4c3fd011307
-	//TODO: VPERMPD $7, Y2, Y2              // c4e3fd01d207
-	//TODO: VPERMPD $7, Y11, Y2             // c4c3fd01d307
-	//TODO: VPERMPD $7, (BX), Y11           // c463fd011b07
-	//TODO: VPERMPD $7, (R11), Y11          // c443fd011b07
-	//TODO: VPERMPD $7, Y2, Y11             // c463fd01da07
-	//TODO: VPERMPD $7, Y11, Y11            // c443fd01db07
-	//TODO: VPERMPS (BX), Y15, Y2           // c4e2051613
-	//TODO: VPERMPS (R11), Y15, Y2          // c4c2051613
-	//TODO: VPERMPS Y2, Y15, Y2             // c4e20516d2
-	//TODO: VPERMPS Y11, Y15, Y2            // c4c20516d3
-	//TODO: VPERMPS (BX), Y15, Y11          // c46205161b
-	//TODO: VPERMPS (R11), Y15, Y11         // c44205161b
-	//TODO: VPERMPS Y2, Y15, Y11            // c4620516da
-	//TODO: VPERMPS Y11, Y15, Y11           // c4420516db
-	//TODO: VPERMQ $7, (BX), Y2             // c4e3fd001307
-	//TODO: VPERMQ $7, (R11), Y2            // c4c3fd001307
-	//TODO: VPERMQ $7, Y2, Y2               // c4e3fd00d207
-	//TODO: VPERMQ $7, Y11, Y2              // c4c3fd00d307
-	//TODO: VPERMQ $7, (BX), Y11            // c463fd001b07
-	//TODO: VPERMQ $7, (R11), Y11           // c443fd001b07
-	//TODO: VPERMQ $7, Y2, Y11              // c463fd00da07
-	//TODO: VPERMQ $7, Y11, Y11             // c443fd00db07
-	//TODO: VPEXTRB $7, X2, (BX)            // c4e379141307
-	//TODO: VPEXTRB $7, X11, (BX)           // c46379141b07
-	//TODO: VPEXTRB $7, X2, (R11)           // c4c379141307
-	//TODO: VPEXTRB $7, X11, (R11)          // c44379141b07
-	//TODO: VPEXTRB $7, X2, DX              // c4e37914d207
-	//TODO: VPEXTRB $7, X11, DX             // c4637914da07
-	//TODO: VPEXTRB $7, X2, R11             // c4c37914d307
-	//TODO: VPEXTRB $7, X11, R11            // c4437914db07
-	//TODO: VPEXTRD $7, X2, (BX)            // c4e379161307
-	//TODO: VPEXTRD $7, X11, (BX)           // c46379161b07
-	//TODO: VPEXTRD $7, X2, (R11)           // c4c379161307
-	//TODO: VPEXTRD $7, X11, (R11)          // c44379161b07
-	//TODO: VPEXTRD $7, X2, DX              // c4e37916d207
-	//TODO: VPEXTRD $7, X11, DX             // c4637916da07
-	//TODO: VPEXTRD $7, X2, R11             // c4c37916d307
-	//TODO: VPEXTRD $7, X11, R11            // c4437916db07
-	//TODO: VPEXTRQ $7, X2, (BX)            // c4e3f9161307
-	//TODO: VPEXTRQ $7, X11, (BX)           // c463f9161b07
-	//TODO: VPEXTRQ $7, X2, (R11)           // c4c3f9161307
-	//TODO: VPEXTRQ $7, X11, (R11)          // c443f9161b07
-	//TODO: VPEXTRQ $7, X2, DX              // c4e3f916d207
-	//TODO: VPEXTRQ $7, X11, DX             // c463f916da07
-	//TODO: VPEXTRQ $7, X2, R11             // c4c3f916d307
-	//TODO: VPEXTRQ $7, X11, R11            // c443f916db07
-	//TODO: VPEXTRW $7, X2, DX              // c4e179c5d207 or c5f9c5d207 or c4e37915d207
-	//TODO: VPEXTRW $7, X11, DX             // c4c179c5d307 or c4637915da07
-	//TODO: VPEXTRW $7, X2, R11             // c46179c5da07 or c579c5da07 or c4c37915d307
-	//TODO: VPEXTRW $7, X11, R11            // c44179c5db07 or c4437915db07
-	//TODO: VPEXTRW $7, X2, (BX)            // c4e379151307
-	//TODO: VPEXTRW $7, X11, (BX)           // c46379151b07
-	//TODO: VPEXTRW $7, X2, (R11)           // c4c379151307
-	//TODO: VPEXTRW $7, X11, (R11)          // c44379151b07
-	//TODO: VPHADDD (BX), X9, X2            // c4e2310213
-	//TODO: VPHADDD (R11), X9, X2           // c4c2310213
-	//TODO: VPHADDD X2, X9, X2              // c4e23102d2
-	//TODO: VPHADDD X11, X9, X2             // c4c23102d3
-	//TODO: VPHADDD (BX), X9, X11           // c46231021b
-	//TODO: VPHADDD (R11), X9, X11          // c44231021b
-	//TODO: VPHADDD X2, X9, X11             // c4623102da
-	//TODO: VPHADDD X11, X9, X11            // c4423102db
-	//TODO: VPHADDD (BX), Y15, Y2           // c4e2050213
-	//TODO: VPHADDD (R11), Y15, Y2          // c4c2050213
-	//TODO: VPHADDD Y2, Y15, Y2             // c4e20502d2
-	//TODO: VPHADDD Y11, Y15, Y2            // c4c20502d3
-	//TODO: VPHADDD (BX), Y15, Y11          // c46205021b
-	//TODO: VPHADDD (R11), Y15, Y11         // c44205021b
-	//TODO: VPHADDD Y2, Y15, Y11            // c4620502da
-	//TODO: VPHADDD Y11, Y15, Y11           // c4420502db
-	//TODO: VPHADDSW (BX), X9, X2           // c4e2310313
-	//TODO: VPHADDSW (R11), X9, X2          // c4c2310313
-	//TODO: VPHADDSW X2, X9, X2             // c4e23103d2
-	//TODO: VPHADDSW X11, X9, X2            // c4c23103d3
-	//TODO: VPHADDSW (BX), X9, X11          // c46231031b
-	//TODO: VPHADDSW (R11), X9, X11         // c44231031b
-	//TODO: VPHADDSW X2, X9, X11            // c4623103da
-	//TODO: VPHADDSW X11, X9, X11           // c4423103db
-	//TODO: VPHADDSW (BX), Y15, Y2          // c4e2050313
-	//TODO: VPHADDSW (R11), Y15, Y2         // c4c2050313
-	//TODO: VPHADDSW Y2, Y15, Y2            // c4e20503d2
-	//TODO: VPHADDSW Y11, Y15, Y2           // c4c20503d3
-	//TODO: VPHADDSW (BX), Y15, Y11         // c46205031b
-	//TODO: VPHADDSW (R11), Y15, Y11        // c44205031b
-	//TODO: VPHADDSW Y2, Y15, Y11           // c4620503da
-	//TODO: VPHADDSW Y11, Y15, Y11          // c4420503db
-	//TODO: VPHADDW (BX), X9, X2            // c4e2310113
-	//TODO: VPHADDW (R11), X9, X2           // c4c2310113
-	//TODO: VPHADDW X2, X9, X2              // c4e23101d2
-	//TODO: VPHADDW X11, X9, X2             // c4c23101d3
-	//TODO: VPHADDW (BX), X9, X11           // c46231011b
-	//TODO: VPHADDW (R11), X9, X11          // c44231011b
-	//TODO: VPHADDW X2, X9, X11             // c4623101da
-	//TODO: VPHADDW X11, X9, X11            // c4423101db
-	//TODO: VPHADDW (BX), Y15, Y2           // c4e2050113
-	//TODO: VPHADDW (R11), Y15, Y2          // c4c2050113
-	//TODO: VPHADDW Y2, Y15, Y2             // c4e20501d2
-	//TODO: VPHADDW Y11, Y15, Y2            // c4c20501d3
-	//TODO: VPHADDW (BX), Y15, Y11          // c46205011b
-	//TODO: VPHADDW (R11), Y15, Y11         // c44205011b
-	//TODO: VPHADDW Y2, Y15, Y11            // c4620501da
-	//TODO: VPHADDW Y11, Y15, Y11           // c4420501db
-	//TODO: VPHMINPOSUW (BX), X2            // c4e2794113
-	//TODO: VPHMINPOSUW (R11), X2           // c4c2794113
-	//TODO: VPHMINPOSUW X2, X2              // c4e27941d2
-	//TODO: VPHMINPOSUW X11, X2             // c4c27941d3
-	//TODO: VPHMINPOSUW (BX), X11           // c46279411b
-	//TODO: VPHMINPOSUW (R11), X11          // c44279411b
-	//TODO: VPHMINPOSUW X2, X11             // c4627941da
-	//TODO: VPHMINPOSUW X11, X11            // c4427941db
-	//TODO: VPHSUBD (BX), X9, X2            // c4e2310613
-	//TODO: VPHSUBD (R11), X9, X2           // c4c2310613
-	//TODO: VPHSUBD X2, X9, X2              // c4e23106d2
-	//TODO: VPHSUBD X11, X9, X2             // c4c23106d3
-	//TODO: VPHSUBD (BX), X9, X11           // c46231061b
-	//TODO: VPHSUBD (R11), X9, X11          // c44231061b
-	//TODO: VPHSUBD X2, X9, X11             // c4623106da
-	//TODO: VPHSUBD X11, X9, X11            // c4423106db
-	//TODO: VPHSUBD (BX), Y15, Y2           // c4e2050613
-	//TODO: VPHSUBD (R11), Y15, Y2          // c4c2050613
-	//TODO: VPHSUBD Y2, Y15, Y2             // c4e20506d2
-	//TODO: VPHSUBD Y11, Y15, Y2            // c4c20506d3
-	//TODO: VPHSUBD (BX), Y15, Y11          // c46205061b
-	//TODO: VPHSUBD (R11), Y15, Y11         // c44205061b
-	//TODO: VPHSUBD Y2, Y15, Y11            // c4620506da
-	//TODO: VPHSUBD Y11, Y15, Y11           // c4420506db
-	//TODO: VPHSUBSW (BX), X9, X2           // c4e2310713
-	//TODO: VPHSUBSW (R11), X9, X2          // c4c2310713
-	//TODO: VPHSUBSW X2, X9, X2             // c4e23107d2
-	//TODO: VPHSUBSW X11, X9, X2            // c4c23107d3
-	//TODO: VPHSUBSW (BX), X9, X11          // c46231071b
-	//TODO: VPHSUBSW (R11), X9, X11         // c44231071b
-	//TODO: VPHSUBSW X2, X9, X11            // c4623107da
-	//TODO: VPHSUBSW X11, X9, X11           // c4423107db
-	//TODO: VPHSUBSW (BX), Y15, Y2          // c4e2050713
-	//TODO: VPHSUBSW (R11), Y15, Y2         // c4c2050713
-	//TODO: VPHSUBSW Y2, Y15, Y2            // c4e20507d2
-	//TODO: VPHSUBSW Y11, Y15, Y2           // c4c20507d3
-	//TODO: VPHSUBSW (BX), Y15, Y11         // c46205071b
-	//TODO: VPHSUBSW (R11), Y15, Y11        // c44205071b
-	//TODO: VPHSUBSW Y2, Y15, Y11           // c4620507da
-	//TODO: VPHSUBSW Y11, Y15, Y11          // c4420507db
-	//TODO: VPHSUBW (BX), X9, X2            // c4e2310513
-	//TODO: VPHSUBW (R11), X9, X2           // c4c2310513
-	//TODO: VPHSUBW X2, X9, X2              // c4e23105d2
-	//TODO: VPHSUBW X11, X9, X2             // c4c23105d3
-	//TODO: VPHSUBW (BX), X9, X11           // c46231051b
-	//TODO: VPHSUBW (R11), X9, X11          // c44231051b
-	//TODO: VPHSUBW X2, X9, X11             // c4623105da
-	//TODO: VPHSUBW X11, X9, X11            // c4423105db
-	//TODO: VPHSUBW (BX), Y15, Y2           // c4e2050513
-	//TODO: VPHSUBW (R11), Y15, Y2          // c4c2050513
-	//TODO: VPHSUBW Y2, Y15, Y2             // c4e20505d2
-	//TODO: VPHSUBW Y11, Y15, Y2            // c4c20505d3
-	//TODO: VPHSUBW (BX), Y15, Y11          // c46205051b
-	//TODO: VPHSUBW (R11), Y15, Y11         // c44205051b
-	//TODO: VPHSUBW Y2, Y15, Y11            // c4620505da
-	//TODO: VPHSUBW Y11, Y15, Y11           // c4420505db
-	//TODO: VPINSRB $7, (BX), X9, X2        // c4e331201307
-	//TODO: VPINSRB $7, (R11), X9, X2       // c4c331201307
-	//TODO: VPINSRB $7, DX, X9, X2          // c4e33120d207
-	//TODO: VPINSRB $7, R11, X9, X2         // c4c33120d307
-	//TODO: VPINSRB $7, (BX), X9, X11       // c46331201b07
-	//TODO: VPINSRB $7, (R11), X9, X11      // c44331201b07
-	//TODO: VPINSRB $7, DX, X9, X11         // c4633120da07
-	//TODO: VPINSRB $7, R11, X9, X11        // c4433120db07
-	//TODO: VPINSRD $7, (BX), X9, X2        // c4e331221307
-	//TODO: VPINSRD $7, (R11), X9, X2       // c4c331221307
-	//TODO: VPINSRD $7, DX, X9, X2          // c4e33122d207
-	//TODO: VPINSRD $7, R11, X9, X2         // c4c33122d307
-	//TODO: VPINSRD $7, (BX), X9, X11       // c46331221b07
-	//TODO: VPINSRD $7, (R11), X9, X11      // c44331221b07
-	//TODO: VPINSRD $7, DX, X9, X11         // c4633122da07
-	//TODO: VPINSRD $7, R11, X9, X11        // c4433122db07
-	//TODO: VPINSRQ $7, (BX), X9, X2        // c4e3b1221307
-	//TODO: VPINSRQ $7, (R11), X9, X2       // c4c3b1221307
-	//TODO: VPINSRQ $7, DX, X9, X2          // c4e3b122d207
-	//TODO: VPINSRQ $7, R11, X9, X2         // c4c3b122d307
-	//TODO: VPINSRQ $7, (BX), X9, X11       // c463b1221b07
-	//TODO: VPINSRQ $7, (R11), X9, X11      // c443b1221b07
-	//TODO: VPINSRQ $7, DX, X9, X11         // c463b122da07
-	//TODO: VPINSRQ $7, R11, X9, X11        // c443b122db07
-	//TODO: VPINSRW $7, (BX), X9, X2        // c4e131c41307 or c5b1c41307
-	//TODO: VPINSRW $7, (R11), X9, X2       // c4c131c41307
-	//TODO: VPINSRW $7, DX, X9, X2          // c4e131c4d207 or c5b1c4d207
-	//TODO: VPINSRW $7, R11, X9, X2         // c4c131c4d307
-	//TODO: VPINSRW $7, (BX), X9, X11       // c46131c41b07 or c531c41b07
-	//TODO: VPINSRW $7, (R11), X9, X11      // c44131c41b07
-	//TODO: VPINSRW $7, DX, X9, X11         // c46131c4da07 or c531c4da07
-	//TODO: VPINSRW $7, R11, X9, X11        // c44131c4db07
-	//TODO: VPMADDUBSW (BX), X9, X2         // c4e2310413
-	//TODO: VPMADDUBSW (R11), X9, X2        // c4c2310413
-	//TODO: VPMADDUBSW X2, X9, X2           // c4e23104d2
-	//TODO: VPMADDUBSW X11, X9, X2          // c4c23104d3
-	//TODO: VPMADDUBSW (BX), X9, X11        // c46231041b
-	//TODO: VPMADDUBSW (R11), X9, X11       // c44231041b
-	//TODO: VPMADDUBSW X2, X9, X11          // c4623104da
-	//TODO: VPMADDUBSW X11, X9, X11         // c4423104db
-	//TODO: VPMADDUBSW (BX), Y15, Y2        // c4e2050413
-	//TODO: VPMADDUBSW (R11), Y15, Y2       // c4c2050413
-	//TODO: VPMADDUBSW Y2, Y15, Y2          // c4e20504d2
-	//TODO: VPMADDUBSW Y11, Y15, Y2         // c4c20504d3
-	//TODO: VPMADDUBSW (BX), Y15, Y11       // c46205041b
-	//TODO: VPMADDUBSW (R11), Y15, Y11      // c44205041b
-	//TODO: VPMADDUBSW Y2, Y15, Y11         // c4620504da
-	//TODO: VPMADDUBSW Y11, Y15, Y11        // c4420504db
-	//TODO: VPMADDWD (BX), X9, X2           // c4e131f513 or c5b1f513
-	//TODO: VPMADDWD (R11), X9, X2          // c4c131f513
-	//TODO: VPMADDWD X2, X9, X2             // c4e131f5d2 or c5b1f5d2
-	//TODO: VPMADDWD X11, X9, X2            // c4c131f5d3
-	//TODO: VPMADDWD (BX), X9, X11          // c46131f51b or c531f51b
-	//TODO: VPMADDWD (R11), X9, X11         // c44131f51b
-	//TODO: VPMADDWD X2, X9, X11            // c46131f5da or c531f5da
-	//TODO: VPMADDWD X11, X9, X11           // c44131f5db
-	//TODO: VPMADDWD (BX), Y15, Y2          // c4e105f513 or c585f513
-	//TODO: VPMADDWD (R11), Y15, Y2         // c4c105f513
-	//TODO: VPMADDWD Y2, Y15, Y2            // c4e105f5d2 or c585f5d2
-	//TODO: VPMADDWD Y11, Y15, Y2           // c4c105f5d3
-	//TODO: VPMADDWD (BX), Y15, Y11         // c46105f51b or c505f51b
-	//TODO: VPMADDWD (R11), Y15, Y11        // c44105f51b
-	//TODO: VPMADDWD Y2, Y15, Y11           // c46105f5da or c505f5da
-	//TODO: VPMADDWD Y11, Y15, Y11          // c44105f5db
-	//TODO: VPMASKMOVD X2, X9, (BX)         // c4e2318e13
-	//TODO: VPMASKMOVD X11, X9, (BX)        // c462318e1b
-	//TODO: VPMASKMOVD X2, X9, (R11)        // c4c2318e13
-	//TODO: VPMASKMOVD X11, X9, (R11)       // c442318e1b
-	//TODO: VPMASKMOVD Y2, Y15, (BX)        // c4e2058e13
-	//TODO: VPMASKMOVD Y11, Y15, (BX)       // c462058e1b
-	//TODO: VPMASKMOVD Y2, Y15, (R11)       // c4c2058e13
-	//TODO: VPMASKMOVD Y11, Y15, (R11)      // c442058e1b
-	//TODO: VPMASKMOVD (BX), X9, X2         // c4e2318c13
-	//TODO: VPMASKMOVD (R11), X9, X2        // c4c2318c13
-	//TODO: VPMASKMOVD (BX), X9, X11        // c462318c1b
-	//TODO: VPMASKMOVD (R11), X9, X11       // c442318c1b
-	//TODO: VPMASKMOVD (BX), Y15, Y2        // c4e2058c13
-	//TODO: VPMASKMOVD (R11), Y15, Y2       // c4c2058c13
-	//TODO: VPMASKMOVD (BX), Y15, Y11       // c462058c1b
-	//TODO: VPMASKMOVD (R11), Y15, Y11      // c442058c1b
-	//TODO: VPMASKMOVQ X2, X9, (BX)         // c4e2b18e13
-	//TODO: VPMASKMOVQ X11, X9, (BX)        // c462b18e1b
-	//TODO: VPMASKMOVQ X2, X9, (R11)        // c4c2b18e13
-	//TODO: VPMASKMOVQ X11, X9, (R11)       // c442b18e1b
-	//TODO: VPMASKMOVQ Y2, Y15, (BX)        // c4e2858e13
-	//TODO: VPMASKMOVQ Y11, Y15, (BX)       // c462858e1b
-	//TODO: VPMASKMOVQ Y2, Y15, (R11)       // c4c2858e13
-	//TODO: VPMASKMOVQ Y11, Y15, (R11)      // c442858e1b
-	//TODO: VPMASKMOVQ (BX), X9, X2         // c4e2b18c13
-	//TODO: VPMASKMOVQ (R11), X9, X2        // c4c2b18c13
-	//TODO: VPMASKMOVQ (BX), X9, X11        // c462b18c1b
-	//TODO: VPMASKMOVQ (R11), X9, X11       // c442b18c1b
-	//TODO: VPMASKMOVQ (BX), Y15, Y2        // c4e2858c13
-	//TODO: VPMASKMOVQ (R11), Y15, Y2       // c4c2858c13
-	//TODO: VPMASKMOVQ (BX), Y15, Y11       // c462858c1b
-	//TODO: VPMASKMOVQ (R11), Y15, Y11      // c442858c1b
-	//TODO: VPMAXSB (BX), X9, X2            // c4e2313c13
-	//TODO: VPMAXSB (R11), X9, X2           // c4c2313c13
-	//TODO: VPMAXSB X2, X9, X2              // c4e2313cd2
-	//TODO: VPMAXSB X11, X9, X2             // c4c2313cd3
-	//TODO: VPMAXSB (BX), X9, X11           // c462313c1b
-	//TODO: VPMAXSB (R11), X9, X11          // c442313c1b
-	//TODO: VPMAXSB X2, X9, X11             // c462313cda
-	//TODO: VPMAXSB X11, X9, X11            // c442313cdb
-	//TODO: VPMAXSB (BX), Y15, Y2           // c4e2053c13
-	//TODO: VPMAXSB (R11), Y15, Y2          // c4c2053c13
-	//TODO: VPMAXSB Y2, Y15, Y2             // c4e2053cd2
-	//TODO: VPMAXSB Y11, Y15, Y2            // c4c2053cd3
-	//TODO: VPMAXSB (BX), Y15, Y11          // c462053c1b
-	//TODO: VPMAXSB (R11), Y15, Y11         // c442053c1b
-	//TODO: VPMAXSB Y2, Y15, Y11            // c462053cda
-	//TODO: VPMAXSB Y11, Y15, Y11           // c442053cdb
-	//TODO: VPMAXSD (BX), X9, X2            // c4e2313d13
-	//TODO: VPMAXSD (R11), X9, X2           // c4c2313d13
-	//TODO: VPMAXSD X2, X9, X2              // c4e2313dd2
-	//TODO: VPMAXSD X11, X9, X2             // c4c2313dd3
-	//TODO: VPMAXSD (BX), X9, X11           // c462313d1b
-	//TODO: VPMAXSD (R11), X9, X11          // c442313d1b
-	//TODO: VPMAXSD X2, X9, X11             // c462313dda
-	//TODO: VPMAXSD X11, X9, X11            // c442313ddb
-	//TODO: VPMAXSD (BX), Y15, Y2           // c4e2053d13
-	//TODO: VPMAXSD (R11), Y15, Y2          // c4c2053d13
-	//TODO: VPMAXSD Y2, Y15, Y2             // c4e2053dd2
-	//TODO: VPMAXSD Y11, Y15, Y2            // c4c2053dd3
-	//TODO: VPMAXSD (BX), Y15, Y11          // c462053d1b
-	//TODO: VPMAXSD (R11), Y15, Y11         // c442053d1b
-	//TODO: VPMAXSD Y2, Y15, Y11            // c462053dda
-	//TODO: VPMAXSD Y11, Y15, Y11           // c442053ddb
-	//TODO: VPMAXSW (BX), X9, X2            // c4e131ee13 or c5b1ee13
-	//TODO: VPMAXSW (R11), X9, X2           // c4c131ee13
-	//TODO: VPMAXSW X2, X9, X2              // c4e131eed2 or c5b1eed2
-	//TODO: VPMAXSW X11, X9, X2             // c4c131eed3
-	//TODO: VPMAXSW (BX), X9, X11           // c46131ee1b or c531ee1b
-	//TODO: VPMAXSW (R11), X9, X11          // c44131ee1b
-	//TODO: VPMAXSW X2, X9, X11             // c46131eeda or c531eeda
-	//TODO: VPMAXSW X11, X9, X11            // c44131eedb
-	//TODO: VPMAXSW (BX), Y15, Y2           // c4e105ee13 or c585ee13
-	//TODO: VPMAXSW (R11), Y15, Y2          // c4c105ee13
-	//TODO: VPMAXSW Y2, Y15, Y2             // c4e105eed2 or c585eed2
-	//TODO: VPMAXSW Y11, Y15, Y2            // c4c105eed3
-	//TODO: VPMAXSW (BX), Y15, Y11          // c46105ee1b or c505ee1b
-	//TODO: VPMAXSW (R11), Y15, Y11         // c44105ee1b
-	//TODO: VPMAXSW Y2, Y15, Y11            // c46105eeda or c505eeda
-	//TODO: VPMAXSW Y11, Y15, Y11           // c44105eedb
-	//TODO: VPMAXUB (BX), X9, X2            // c4e131de13 or c5b1de13
-	//TODO: VPMAXUB (R11), X9, X2           // c4c131de13
-	//TODO: VPMAXUB X2, X9, X2              // c4e131ded2 or c5b1ded2
-	//TODO: VPMAXUB X11, X9, X2             // c4c131ded3
-	//TODO: VPMAXUB (BX), X9, X11           // c46131de1b or c531de1b
-	//TODO: VPMAXUB (R11), X9, X11          // c44131de1b
-	//TODO: VPMAXUB X2, X9, X11             // c46131deda or c531deda
-	//TODO: VPMAXUB X11, X9, X11            // c44131dedb
-	//TODO: VPMAXUB (BX), Y15, Y2           // c4e105de13 or c585de13
-	//TODO: VPMAXUB (R11), Y15, Y2          // c4c105de13
-	//TODO: VPMAXUB Y2, Y15, Y2             // c4e105ded2 or c585ded2
-	//TODO: VPMAXUB Y11, Y15, Y2            // c4c105ded3
-	//TODO: VPMAXUB (BX), Y15, Y11          // c46105de1b or c505de1b
-	//TODO: VPMAXUB (R11), Y15, Y11         // c44105de1b
-	//TODO: VPMAXUB Y2, Y15, Y11            // c46105deda or c505deda
-	//TODO: VPMAXUB Y11, Y15, Y11           // c44105dedb
-	//TODO: VPMAXUD (BX), X9, X2            // c4e2313f13
-	//TODO: VPMAXUD (R11), X9, X2           // c4c2313f13
-	//TODO: VPMAXUD X2, X9, X2              // c4e2313fd2
-	//TODO: VPMAXUD X11, X9, X2             // c4c2313fd3
-	//TODO: VPMAXUD (BX), X9, X11           // c462313f1b
-	//TODO: VPMAXUD (R11), X9, X11          // c442313f1b
-	//TODO: VPMAXUD X2, X9, X11             // c462313fda
-	//TODO: VPMAXUD X11, X9, X11            // c442313fdb
-	//TODO: VPMAXUD (BX), Y15, Y2           // c4e2053f13
-	//TODO: VPMAXUD (R11), Y15, Y2          // c4c2053f13
-	//TODO: VPMAXUD Y2, Y15, Y2             // c4e2053fd2
-	//TODO: VPMAXUD Y11, Y15, Y2            // c4c2053fd3
-	//TODO: VPMAXUD (BX), Y15, Y11          // c462053f1b
-	//TODO: VPMAXUD (R11), Y15, Y11         // c442053f1b
-	//TODO: VPMAXUD Y2, Y15, Y11            // c462053fda
-	//TODO: VPMAXUD Y11, Y15, Y11           // c442053fdb
-	//TODO: VPMAXUW (BX), X9, X2            // c4e2313e13
-	//TODO: VPMAXUW (R11), X9, X2           // c4c2313e13
-	//TODO: VPMAXUW X2, X9, X2              // c4e2313ed2
-	//TODO: VPMAXUW X11, X9, X2             // c4c2313ed3
-	//TODO: VPMAXUW (BX), X9, X11           // c462313e1b
-	//TODO: VPMAXUW (R11), X9, X11          // c442313e1b
-	//TODO: VPMAXUW X2, X9, X11             // c462313eda
-	//TODO: VPMAXUW X11, X9, X11            // c442313edb
-	//TODO: VPMAXUW (BX), Y15, Y2           // c4e2053e13
-	//TODO: VPMAXUW (R11), Y15, Y2          // c4c2053e13
-	//TODO: VPMAXUW Y2, Y15, Y2             // c4e2053ed2
-	//TODO: VPMAXUW Y11, Y15, Y2            // c4c2053ed3
-	//TODO: VPMAXUW (BX), Y15, Y11          // c462053e1b
-	//TODO: VPMAXUW (R11), Y15, Y11         // c442053e1b
-	//TODO: VPMAXUW Y2, Y15, Y11            // c462053eda
-	//TODO: VPMAXUW Y11, Y15, Y11           // c442053edb
-	//TODO: VPMINSB (BX), X9, X2            // c4e2313813
-	//TODO: VPMINSB (R11), X9, X2           // c4c2313813
-	//TODO: VPMINSB X2, X9, X2              // c4e23138d2
-	//TODO: VPMINSB X11, X9, X2             // c4c23138d3
-	//TODO: VPMINSB (BX), X9, X11           // c46231381b
-	//TODO: VPMINSB (R11), X9, X11          // c44231381b
-	//TODO: VPMINSB X2, X9, X11             // c4623138da
-	//TODO: VPMINSB X11, X9, X11            // c4423138db
-	//TODO: VPMINSB (BX), Y15, Y2           // c4e2053813
-	//TODO: VPMINSB (R11), Y15, Y2          // c4c2053813
-	//TODO: VPMINSB Y2, Y15, Y2             // c4e20538d2
-	//TODO: VPMINSB Y11, Y15, Y2            // c4c20538d3
-	//TODO: VPMINSB (BX), Y15, Y11          // c46205381b
-	//TODO: VPMINSB (R11), Y15, Y11         // c44205381b
-	//TODO: VPMINSB Y2, Y15, Y11            // c4620538da
-	//TODO: VPMINSB Y11, Y15, Y11           // c4420538db
-	//TODO: VPMINSD (BX), X9, X2            // c4e2313913
-	//TODO: VPMINSD (R11), X9, X2           // c4c2313913
-	//TODO: VPMINSD X2, X9, X2              // c4e23139d2
-	//TODO: VPMINSD X11, X9, X2             // c4c23139d3
-	//TODO: VPMINSD (BX), X9, X11           // c46231391b
-	//TODO: VPMINSD (R11), X9, X11          // c44231391b
-	//TODO: VPMINSD X2, X9, X11             // c4623139da
-	//TODO: VPMINSD X11, X9, X11            // c4423139db
-	//TODO: VPMINSD (BX), Y15, Y2           // c4e2053913
-	//TODO: VPMINSD (R11), Y15, Y2          // c4c2053913
-	//TODO: VPMINSD Y2, Y15, Y2             // c4e20539d2
-	//TODO: VPMINSD Y11, Y15, Y2            // c4c20539d3
-	//TODO: VPMINSD (BX), Y15, Y11          // c46205391b
-	//TODO: VPMINSD (R11), Y15, Y11         // c44205391b
-	//TODO: VPMINSD Y2, Y15, Y11            // c4620539da
-	//TODO: VPMINSD Y11, Y15, Y11           // c4420539db
-	//TODO: VPMINSW (BX), X9, X2            // c4e131ea13 or c5b1ea13
-	//TODO: VPMINSW (R11), X9, X2           // c4c131ea13
-	//TODO: VPMINSW X2, X9, X2              // c4e131ead2 or c5b1ead2
-	//TODO: VPMINSW X11, X9, X2             // c4c131ead3
-	//TODO: VPMINSW (BX), X9, X11           // c46131ea1b or c531ea1b
-	//TODO: VPMINSW (R11), X9, X11          // c44131ea1b
-	//TODO: VPMINSW X2, X9, X11             // c46131eada or c531eada
-	//TODO: VPMINSW X11, X9, X11            // c44131eadb
-	//TODO: VPMINSW (BX), Y15, Y2           // c4e105ea13 or c585ea13
-	//TODO: VPMINSW (R11), Y15, Y2          // c4c105ea13
-	//TODO: VPMINSW Y2, Y15, Y2             // c4e105ead2 or c585ead2
-	//TODO: VPMINSW Y11, Y15, Y2            // c4c105ead3
-	//TODO: VPMINSW (BX), Y15, Y11          // c46105ea1b or c505ea1b
-	//TODO: VPMINSW (R11), Y15, Y11         // c44105ea1b
-	//TODO: VPMINSW Y2, Y15, Y11            // c46105eada or c505eada
-	//TODO: VPMINSW Y11, Y15, Y11           // c44105eadb
-	//TODO: VPMINUB (BX), X9, X2            // c4e131da13 or c5b1da13
-	//TODO: VPMINUB (R11), X9, X2           // c4c131da13
-	//TODO: VPMINUB X2, X9, X2              // c4e131dad2 or c5b1dad2
-	//TODO: VPMINUB X11, X9, X2             // c4c131dad3
-	//TODO: VPMINUB (BX), X9, X11           // c46131da1b or c531da1b
-	//TODO: VPMINUB (R11), X9, X11          // c44131da1b
-	//TODO: VPMINUB X2, X9, X11             // c46131dada or c531dada
-	//TODO: VPMINUB X11, X9, X11            // c44131dadb
-	//TODO: VPMINUB (BX), Y15, Y2           // c4e105da13 or c585da13
-	//TODO: VPMINUB (R11), Y15, Y2          // c4c105da13
-	//TODO: VPMINUB Y2, Y15, Y2             // c4e105dad2 or c585dad2
-	//TODO: VPMINUB Y11, Y15, Y2            // c4c105dad3
-	//TODO: VPMINUB (BX), Y15, Y11          // c46105da1b or c505da1b
-	//TODO: VPMINUB (R11), Y15, Y11         // c44105da1b
-	//TODO: VPMINUB Y2, Y15, Y11            // c46105dada or c505dada
-	//TODO: VPMINUB Y11, Y15, Y11           // c44105dadb
-	//TODO: VPMINUD (BX), X9, X2            // c4e2313b13
-	//TODO: VPMINUD (R11), X9, X2           // c4c2313b13
-	//TODO: VPMINUD X2, X9, X2              // c4e2313bd2
-	//TODO: VPMINUD X11, X9, X2             // c4c2313bd3
-	//TODO: VPMINUD (BX), X9, X11           // c462313b1b
-	//TODO: VPMINUD (R11), X9, X11          // c442313b1b
-	//TODO: VPMINUD X2, X9, X11             // c462313bda
-	//TODO: VPMINUD X11, X9, X11            // c442313bdb
-	//TODO: VPMINUD (BX), Y15, Y2           // c4e2053b13
-	//TODO: VPMINUD (R11), Y15, Y2          // c4c2053b13
-	//TODO: VPMINUD Y2, Y15, Y2             // c4e2053bd2
-	//TODO: VPMINUD Y11, Y15, Y2            // c4c2053bd3
-	//TODO: VPMINUD (BX), Y15, Y11          // c462053b1b
-	//TODO: VPMINUD (R11), Y15, Y11         // c442053b1b
-	//TODO: VPMINUD Y2, Y15, Y11            // c462053bda
-	//TODO: VPMINUD Y11, Y15, Y11           // c442053bdb
-	//TODO: VPMINUW (BX), X9, X2            // c4e2313a13
-	//TODO: VPMINUW (R11), X9, X2           // c4c2313a13
-	//TODO: VPMINUW X2, X9, X2              // c4e2313ad2
-	//TODO: VPMINUW X11, X9, X2             // c4c2313ad3
-	//TODO: VPMINUW (BX), X9, X11           // c462313a1b
-	//TODO: VPMINUW (R11), X9, X11          // c442313a1b
-	//TODO: VPMINUW X2, X9, X11             // c462313ada
-	//TODO: VPMINUW X11, X9, X11            // c442313adb
-	//TODO: VPMINUW (BX), Y15, Y2           // c4e2053a13
-	//TODO: VPMINUW (R11), Y15, Y2          // c4c2053a13
-	//TODO: VPMINUW Y2, Y15, Y2             // c4e2053ad2
-	//TODO: VPMINUW Y11, Y15, Y2            // c4c2053ad3
-	//TODO: VPMINUW (BX), Y15, Y11          // c462053a1b
-	//TODO: VPMINUW (R11), Y15, Y11         // c442053a1b
-	//TODO: VPMINUW Y2, Y15, Y11            // c462053ada
-	//TODO: VPMINUW Y11, Y15, Y11           // c442053adb
+	VPERMD (BX), Y15, Y2                    // c4e2053613
+	VPERMD (R11), Y15, Y2                   // c4c2053613
+	VPERMD Y2, Y15, Y2                      // c4e20536d2
+	VPERMD Y11, Y15, Y2                     // c4c20536d3
+	VPERMD (BX), Y15, Y11                   // c46205361b
+	VPERMD (R11), Y15, Y11                  // c44205361b
+	VPERMD Y2, Y15, Y11                     // c4620536da
+	VPERMD Y11, Y15, Y11                    // c4420536db
+	VPERMILPD $7, (BX), X2                  // c4e379051307
+	VPERMILPD $7, (R11), X2                 // c4c379051307
+	VPERMILPD $7, X2, X2                    // c4e37905d207
+	VPERMILPD $7, X11, X2                   // c4c37905d307
+	VPERMILPD $7, (BX), X11                 // c46379051b07
+	VPERMILPD $7, (R11), X11                // c44379051b07
+	VPERMILPD $7, X2, X11                   // c4637905da07
+	VPERMILPD $7, X11, X11                  // c4437905db07
+	VPERMILPD (BX), X9, X2                  // c4e2310d13
+	VPERMILPD (R11), X9, X2                 // c4c2310d13
+	VPERMILPD X2, X9, X2                    // c4e2310dd2
+	VPERMILPD X11, X9, X2                   // c4c2310dd3
+	VPERMILPD (BX), X9, X11                 // c462310d1b
+	VPERMILPD (R11), X9, X11                // c442310d1b
+	VPERMILPD X2, X9, X11                   // c462310dda
+	VPERMILPD X11, X9, X11                  // c442310ddb
+	VPERMILPD $7, (BX), Y2                  // c4e37d051307
+	VPERMILPD $7, (R11), Y2                 // c4c37d051307
+	VPERMILPD $7, Y2, Y2                    // c4e37d05d207
+	VPERMILPD $7, Y11, Y2                   // c4c37d05d307
+	VPERMILPD $7, (BX), Y11                 // c4637d051b07
+	VPERMILPD $7, (R11), Y11                // c4437d051b07
+	VPERMILPD $7, Y2, Y11                   // c4637d05da07
+	VPERMILPD $7, Y11, Y11                  // c4437d05db07
+	VPERMILPD (BX), Y15, Y2                 // c4e2050d13
+	VPERMILPD (R11), Y15, Y2                // c4c2050d13
+	VPERMILPD Y2, Y15, Y2                   // c4e2050dd2
+	VPERMILPD Y11, Y15, Y2                  // c4c2050dd3
+	VPERMILPD (BX), Y15, Y11                // c462050d1b
+	VPERMILPD (R11), Y15, Y11               // c442050d1b
+	VPERMILPD Y2, Y15, Y11                  // c462050dda
+	VPERMILPD Y11, Y15, Y11                 // c442050ddb
+	VPERMILPS $7, (BX), X2                  // c4e379041307
+	VPERMILPS $7, (R11), X2                 // c4c379041307
+	VPERMILPS $7, X2, X2                    // c4e37904d207
+	VPERMILPS $7, X11, X2                   // c4c37904d307
+	VPERMILPS $7, (BX), X11                 // c46379041b07
+	VPERMILPS $7, (R11), X11                // c44379041b07
+	VPERMILPS $7, X2, X11                   // c4637904da07
+	VPERMILPS $7, X11, X11                  // c4437904db07
+	VPERMILPS (BX), X9, X2                  // c4e2310c13
+	VPERMILPS (R11), X9, X2                 // c4c2310c13
+	VPERMILPS X2, X9, X2                    // c4e2310cd2
+	VPERMILPS X11, X9, X2                   // c4c2310cd3
+	VPERMILPS (BX), X9, X11                 // c462310c1b
+	VPERMILPS (R11), X9, X11                // c442310c1b
+	VPERMILPS X2, X9, X11                   // c462310cda
+	VPERMILPS X11, X9, X11                  // c442310cdb
+	VPERMILPS $7, (BX), Y2                  // c4e37d041307
+	VPERMILPS $7, (R11), Y2                 // c4c37d041307
+	VPERMILPS $7, Y2, Y2                    // c4e37d04d207
+	VPERMILPS $7, Y11, Y2                   // c4c37d04d307
+	VPERMILPS $7, (BX), Y11                 // c4637d041b07
+	VPERMILPS $7, (R11), Y11                // c4437d041b07
+	VPERMILPS $7, Y2, Y11                   // c4637d04da07
+	VPERMILPS $7, Y11, Y11                  // c4437d04db07
+	VPERMILPS (BX), Y15, Y2                 // c4e2050c13
+	VPERMILPS (R11), Y15, Y2                // c4c2050c13
+	VPERMILPS Y2, Y15, Y2                   // c4e2050cd2
+	VPERMILPS Y11, Y15, Y2                  // c4c2050cd3
+	VPERMILPS (BX), Y15, Y11                // c462050c1b
+	VPERMILPS (R11), Y15, Y11               // c442050c1b
+	VPERMILPS Y2, Y15, Y11                  // c462050cda
+	VPERMILPS Y11, Y15, Y11                 // c442050cdb
+	VPERMPD $7, (BX), Y2                    // c4e3fd011307
+	VPERMPD $7, (R11), Y2                   // c4c3fd011307
+	VPERMPD $7, Y2, Y2                      // c4e3fd01d207
+	VPERMPD $7, Y11, Y2                     // c4c3fd01d307
+	VPERMPD $7, (BX), Y11                   // c463fd011b07
+	VPERMPD $7, (R11), Y11                  // c443fd011b07
+	VPERMPD $7, Y2, Y11                     // c463fd01da07
+	VPERMPD $7, Y11, Y11                    // c443fd01db07
+	VPERMPS (BX), Y15, Y2                   // c4e2051613
+	VPERMPS (R11), Y15, Y2                  // c4c2051613
+	VPERMPS Y2, Y15, Y2                     // c4e20516d2
+	VPERMPS Y11, Y15, Y2                    // c4c20516d3
+	VPERMPS (BX), Y15, Y11                  // c46205161b
+	VPERMPS (R11), Y15, Y11                 // c44205161b
+	VPERMPS Y2, Y15, Y11                    // c4620516da
+	VPERMPS Y11, Y15, Y11                   // c4420516db
+	VPERMQ $7, (BX), Y2                     // c4e3fd001307
+	VPERMQ $7, (R11), Y2                    // c4c3fd001307
+	VPERMQ $7, Y2, Y2                       // c4e3fd00d207
+	VPERMQ $7, Y11, Y2                      // c4c3fd00d307
+	VPERMQ $7, (BX), Y11                    // c463fd001b07
+	VPERMQ $7, (R11), Y11                   // c443fd001b07
+	VPERMQ $7, Y2, Y11                      // c463fd00da07
+	VPERMQ $7, Y11, Y11                     // c443fd00db07
+	VPEXTRB $7, X2, (BX)                    // c4e379141307
+	VPEXTRB $7, X11, (BX)                   // c46379141b07
+	VPEXTRB $7, X2, (R11)                   // c4c379141307
+	VPEXTRB $7, X11, (R11)                  // c44379141b07
+	VPEXTRB $7, X2, DX                      // c4e37914d207
+	VPEXTRB $7, X11, DX                     // c4637914da07
+	VPEXTRB $7, X2, R11                     // c4c37914d307
+	VPEXTRB $7, X11, R11                    // c4437914db07
+	VPEXTRD $7, X2, (BX)                    // c4e379161307
+	VPEXTRD $7, X11, (BX)                   // c46379161b07
+	VPEXTRD $7, X2, (R11)                   // c4c379161307
+	VPEXTRD $7, X11, (R11)                  // c44379161b07
+	VPEXTRD $7, X2, DX                      // c4e37916d207
+	VPEXTRD $7, X11, DX                     // c4637916da07
+	VPEXTRD $7, X2, R11                     // c4c37916d307
+	VPEXTRD $7, X11, R11                    // c4437916db07
+	VPEXTRQ $7, X2, (BX)                    // c4e3f9161307
+	VPEXTRQ $7, X11, (BX)                   // c463f9161b07
+	VPEXTRQ $7, X2, (R11)                   // c4c3f9161307
+	VPEXTRQ $7, X11, (R11)                  // c443f9161b07
+	VPEXTRQ $7, X2, DX                      // c4e3f916d207
+	VPEXTRQ $7, X11, DX                     // c463f916da07
+	VPEXTRQ $7, X2, R11                     // c4c3f916d307
+	VPEXTRQ $7, X11, R11                    // c443f916db07
+	VPEXTRW $7, X2, DX                      // c4e179c5d207 or c5f9c5d207 or c4e37915d207
+	VPEXTRW $7, X11, DX                     // c4c179c5d307 or c4637915da07
+	VPEXTRW $7, X2, R11                     // c46179c5da07 or c579c5da07 or c4c37915d307
+	VPEXTRW $7, X11, R11                    // c44179c5db07 or c4437915db07
+	VPEXTRW $7, X2, (BX)                    // c4e379151307
+	VPEXTRW $7, X11, (BX)                   // c46379151b07
+	VPEXTRW $7, X2, (R11)                   // c4c379151307
+	VPEXTRW $7, X11, (R11)                  // c44379151b07
+	VPHADDD (BX), X9, X2                    // c4e2310213
+	VPHADDD (R11), X9, X2                   // c4c2310213
+	VPHADDD X2, X9, X2                      // c4e23102d2
+	VPHADDD X11, X9, X2                     // c4c23102d3
+	VPHADDD (BX), X9, X11                   // c46231021b
+	VPHADDD (R11), X9, X11                  // c44231021b
+	VPHADDD X2, X9, X11                     // c4623102da
+	VPHADDD X11, X9, X11                    // c4423102db
+	VPHADDD (BX), Y15, Y2                   // c4e2050213
+	VPHADDD (R11), Y15, Y2                  // c4c2050213
+	VPHADDD Y2, Y15, Y2                     // c4e20502d2
+	VPHADDD Y11, Y15, Y2                    // c4c20502d3
+	VPHADDD (BX), Y15, Y11                  // c46205021b
+	VPHADDD (R11), Y15, Y11                 // c44205021b
+	VPHADDD Y2, Y15, Y11                    // c4620502da
+	VPHADDD Y11, Y15, Y11                   // c4420502db
+	VPHADDSW (BX), X9, X2                   // c4e2310313
+	VPHADDSW (R11), X9, X2                  // c4c2310313
+	VPHADDSW X2, X9, X2                     // c4e23103d2
+	VPHADDSW X11, X9, X2                    // c4c23103d3
+	VPHADDSW (BX), X9, X11                  // c46231031b
+	VPHADDSW (R11), X9, X11                 // c44231031b
+	VPHADDSW X2, X9, X11                    // c4623103da
+	VPHADDSW X11, X9, X11                   // c4423103db
+	VPHADDSW (BX), Y15, Y2                  // c4e2050313
+	VPHADDSW (R11), Y15, Y2                 // c4c2050313
+	VPHADDSW Y2, Y15, Y2                    // c4e20503d2
+	VPHADDSW Y11, Y15, Y2                   // c4c20503d3
+	VPHADDSW (BX), Y15, Y11                 // c46205031b
+	VPHADDSW (R11), Y15, Y11                // c44205031b
+	VPHADDSW Y2, Y15, Y11                   // c4620503da
+	VPHADDSW Y11, Y15, Y11                  // c4420503db
+	VPHADDW (BX), X9, X2                    // c4e2310113
+	VPHADDW (R11), X9, X2                   // c4c2310113
+	VPHADDW X2, X9, X2                      // c4e23101d2
+	VPHADDW X11, X9, X2                     // c4c23101d3
+	VPHADDW (BX), X9, X11                   // c46231011b
+	VPHADDW (R11), X9, X11                  // c44231011b
+	VPHADDW X2, X9, X11                     // c4623101da
+	VPHADDW X11, X9, X11                    // c4423101db
+	VPHADDW (BX), Y15, Y2                   // c4e2050113
+	VPHADDW (R11), Y15, Y2                  // c4c2050113
+	VPHADDW Y2, Y15, Y2                     // c4e20501d2
+	VPHADDW Y11, Y15, Y2                    // c4c20501d3
+	VPHADDW (BX), Y15, Y11                  // c46205011b
+	VPHADDW (R11), Y15, Y11                 // c44205011b
+	VPHADDW Y2, Y15, Y11                    // c4620501da
+	VPHADDW Y11, Y15, Y11                   // c4420501db
+	VPHMINPOSUW (BX), X2                    // c4e2794113
+	VPHMINPOSUW (R11), X2                   // c4c2794113
+	VPHMINPOSUW X2, X2                      // c4e27941d2
+	VPHMINPOSUW X11, X2                     // c4c27941d3
+	VPHMINPOSUW (BX), X11                   // c46279411b
+	VPHMINPOSUW (R11), X11                  // c44279411b
+	VPHMINPOSUW X2, X11                     // c4627941da
+	VPHMINPOSUW X11, X11                    // c4427941db
+	VPHSUBD (BX), X9, X2                    // c4e2310613
+	VPHSUBD (R11), X9, X2                   // c4c2310613
+	VPHSUBD X2, X9, X2                      // c4e23106d2
+	VPHSUBD X11, X9, X2                     // c4c23106d3
+	VPHSUBD (BX), X9, X11                   // c46231061b
+	VPHSUBD (R11), X9, X11                  // c44231061b
+	VPHSUBD X2, X9, X11                     // c4623106da
+	VPHSUBD X11, X9, X11                    // c4423106db
+	VPHSUBD (BX), Y15, Y2                   // c4e2050613
+	VPHSUBD (R11), Y15, Y2                  // c4c2050613
+	VPHSUBD Y2, Y15, Y2                     // c4e20506d2
+	VPHSUBD Y11, Y15, Y2                    // c4c20506d3
+	VPHSUBD (BX), Y15, Y11                  // c46205061b
+	VPHSUBD (R11), Y15, Y11                 // c44205061b
+	VPHSUBD Y2, Y15, Y11                    // c4620506da
+	VPHSUBD Y11, Y15, Y11                   // c4420506db
+	VPHSUBSW (BX), X9, X2                   // c4e2310713
+	VPHSUBSW (R11), X9, X2                  // c4c2310713
+	VPHSUBSW X2, X9, X2                     // c4e23107d2
+	VPHSUBSW X11, X9, X2                    // c4c23107d3
+	VPHSUBSW (BX), X9, X11                  // c46231071b
+	VPHSUBSW (R11), X9, X11                 // c44231071b
+	VPHSUBSW X2, X9, X11                    // c4623107da
+	VPHSUBSW X11, X9, X11                   // c4423107db
+	VPHSUBSW (BX), Y15, Y2                  // c4e2050713
+	VPHSUBSW (R11), Y15, Y2                 // c4c2050713
+	VPHSUBSW Y2, Y15, Y2                    // c4e20507d2
+	VPHSUBSW Y11, Y15, Y2                   // c4c20507d3
+	VPHSUBSW (BX), Y15, Y11                 // c46205071b
+	VPHSUBSW (R11), Y15, Y11                // c44205071b
+	VPHSUBSW Y2, Y15, Y11                   // c4620507da
+	VPHSUBSW Y11, Y15, Y11                  // c4420507db
+	VPHSUBW (BX), X9, X2                    // c4e2310513
+	VPHSUBW (R11), X9, X2                   // c4c2310513
+	VPHSUBW X2, X9, X2                      // c4e23105d2
+	VPHSUBW X11, X9, X2                     // c4c23105d3
+	VPHSUBW (BX), X9, X11                   // c46231051b
+	VPHSUBW (R11), X9, X11                  // c44231051b
+	VPHSUBW X2, X9, X11                     // c4623105da
+	VPHSUBW X11, X9, X11                    // c4423105db
+	VPHSUBW (BX), Y15, Y2                   // c4e2050513
+	VPHSUBW (R11), Y15, Y2                  // c4c2050513
+	VPHSUBW Y2, Y15, Y2                     // c4e20505d2
+	VPHSUBW Y11, Y15, Y2                    // c4c20505d3
+	VPHSUBW (BX), Y15, Y11                  // c46205051b
+	VPHSUBW (R11), Y15, Y11                 // c44205051b
+	VPHSUBW Y2, Y15, Y11                    // c4620505da
+	VPHSUBW Y11, Y15, Y11                   // c4420505db
+	VPINSRB $7, (BX), X9, X2                // c4e331201307
+	VPINSRB $7, (R11), X9, X2               // c4c331201307
+	VPINSRB $7, DX, X9, X2                  // c4e33120d207
+	VPINSRB $7, R11, X9, X2                 // c4c33120d307
+	VPINSRB $7, (BX), X9, X11               // c46331201b07
+	VPINSRB $7, (R11), X9, X11              // c44331201b07
+	VPINSRB $7, DX, X9, X11                 // c4633120da07
+	VPINSRB $7, R11, X9, X11                // c4433120db07
+	VPINSRD $7, (BX), X9, X2                // c4e331221307
+	VPINSRD $7, (R11), X9, X2               // c4c331221307
+	VPINSRD $7, DX, X9, X2                  // c4e33122d207
+	VPINSRD $7, R11, X9, X2                 // c4c33122d307
+	VPINSRD $7, (BX), X9, X11               // c46331221b07
+	VPINSRD $7, (R11), X9, X11              // c44331221b07
+	VPINSRD $7, DX, X9, X11                 // c4633122da07
+	VPINSRD $7, R11, X9, X11                // c4433122db07
+	VPINSRQ $7, (BX), X9, X2                // c4e3b1221307
+	VPINSRQ $7, (R11), X9, X2               // c4c3b1221307
+	VPINSRQ $7, DX, X9, X2                  // c4e3b122d207
+	VPINSRQ $7, R11, X9, X2                 // c4c3b122d307
+	VPINSRQ $7, (BX), X9, X11               // c463b1221b07
+	VPINSRQ $7, (R11), X9, X11              // c443b1221b07
+	VPINSRQ $7, DX, X9, X11                 // c463b122da07
+	VPINSRQ $7, R11, X9, X11                // c443b122db07
+	VPINSRW $7, (BX), X9, X2                // c4e131c41307 or c5b1c41307
+	VPINSRW $7, (R11), X9, X2               // c4c131c41307
+	VPINSRW $7, DX, X9, X2                  // c4e131c4d207 or c5b1c4d207
+	VPINSRW $7, R11, X9, X2                 // c4c131c4d307
+	VPINSRW $7, (BX), X9, X11               // c46131c41b07 or c531c41b07
+	VPINSRW $7, (R11), X9, X11              // c44131c41b07
+	VPINSRW $7, DX, X9, X11                 // c46131c4da07 or c531c4da07
+	VPINSRW $7, R11, X9, X11                // c44131c4db07
+	VPMADDUBSW (BX), X9, X2                 // c4e2310413
+	VPMADDUBSW (R11), X9, X2                // c4c2310413
+	VPMADDUBSW X2, X9, X2                   // c4e23104d2
+	VPMADDUBSW X11, X9, X2                  // c4c23104d3
+	VPMADDUBSW (BX), X9, X11                // c46231041b
+	VPMADDUBSW (R11), X9, X11               // c44231041b
+	VPMADDUBSW X2, X9, X11                  // c4623104da
+	VPMADDUBSW X11, X9, X11                 // c4423104db
+	VPMADDUBSW (BX), Y15, Y2                // c4e2050413
+	VPMADDUBSW (R11), Y15, Y2               // c4c2050413
+	VPMADDUBSW Y2, Y15, Y2                  // c4e20504d2
+	VPMADDUBSW Y11, Y15, Y2                 // c4c20504d3
+	VPMADDUBSW (BX), Y15, Y11               // c46205041b
+	VPMADDUBSW (R11), Y15, Y11              // c44205041b
+	VPMADDUBSW Y2, Y15, Y11                 // c4620504da
+	VPMADDUBSW Y11, Y15, Y11                // c4420504db
+	VPMADDWD (BX), X9, X2                   // c4e131f513 or c5b1f513
+	VPMADDWD (R11), X9, X2                  // c4c131f513
+	VPMADDWD X2, X9, X2                     // c4e131f5d2 or c5b1f5d2
+	VPMADDWD X11, X9, X2                    // c4c131f5d3
+	VPMADDWD (BX), X9, X11                  // c46131f51b or c531f51b
+	VPMADDWD (R11), X9, X11                 // c44131f51b
+	VPMADDWD X2, X9, X11                    // c46131f5da or c531f5da
+	VPMADDWD X11, X9, X11                   // c44131f5db
+	VPMADDWD (BX), Y15, Y2                  // c4e105f513 or c585f513
+	VPMADDWD (R11), Y15, Y2                 // c4c105f513
+	VPMADDWD Y2, Y15, Y2                    // c4e105f5d2 or c585f5d2
+	VPMADDWD Y11, Y15, Y2                   // c4c105f5d3
+	VPMADDWD (BX), Y15, Y11                 // c46105f51b or c505f51b
+	VPMADDWD (R11), Y15, Y11                // c44105f51b
+	VPMADDWD Y2, Y15, Y11                   // c46105f5da or c505f5da
+	VPMADDWD Y11, Y15, Y11                  // c44105f5db
+	VPMASKMOVD X2, X9, (BX)                 // c4e2318e13
+	VPMASKMOVD X11, X9, (BX)                // c462318e1b
+	VPMASKMOVD X2, X9, (R11)                // c4c2318e13
+	VPMASKMOVD X11, X9, (R11)               // c442318e1b
+	VPMASKMOVD Y2, Y15, (BX)                // c4e2058e13
+	VPMASKMOVD Y11, Y15, (BX)               // c462058e1b
+	VPMASKMOVD Y2, Y15, (R11)               // c4c2058e13
+	VPMASKMOVD Y11, Y15, (R11)              // c442058e1b
+	VPMASKMOVD (BX), X9, X2                 // c4e2318c13
+	VPMASKMOVD (R11), X9, X2                // c4c2318c13
+	VPMASKMOVD (BX), X9, X11                // c462318c1b
+	VPMASKMOVD (R11), X9, X11               // c442318c1b
+	VPMASKMOVD (BX), Y15, Y2                // c4e2058c13
+	VPMASKMOVD (R11), Y15, Y2               // c4c2058c13
+	VPMASKMOVD (BX), Y15, Y11               // c462058c1b
+	VPMASKMOVD (R11), Y15, Y11              // c442058c1b
+	VPMASKMOVQ X2, X9, (BX)                 // c4e2b18e13
+	VPMASKMOVQ X11, X9, (BX)                // c462b18e1b
+	VPMASKMOVQ X2, X9, (R11)                // c4c2b18e13
+	VPMASKMOVQ X11, X9, (R11)               // c442b18e1b
+	VPMASKMOVQ Y2, Y15, (BX)                // c4e2858e13
+	VPMASKMOVQ Y11, Y15, (BX)               // c462858e1b
+	VPMASKMOVQ Y2, Y15, (R11)               // c4c2858e13
+	VPMASKMOVQ Y11, Y15, (R11)              // c442858e1b
+	VPMASKMOVQ (BX), X9, X2                 // c4e2b18c13
+	VPMASKMOVQ (R11), X9, X2                // c4c2b18c13
+	VPMASKMOVQ (BX), X9, X11                // c462b18c1b
+	VPMASKMOVQ (R11), X9, X11               // c442b18c1b
+	VPMASKMOVQ (BX), Y15, Y2                // c4e2858c13
+	VPMASKMOVQ (R11), Y15, Y2               // c4c2858c13
+	VPMASKMOVQ (BX), Y15, Y11               // c462858c1b
+	VPMASKMOVQ (R11), Y15, Y11              // c442858c1b
+	VPMAXSB (BX), X9, X2                    // c4e2313c13
+	VPMAXSB (R11), X9, X2                   // c4c2313c13
+	VPMAXSB X2, X9, X2                      // c4e2313cd2
+	VPMAXSB X11, X9, X2                     // c4c2313cd3
+	VPMAXSB (BX), X9, X11                   // c462313c1b
+	VPMAXSB (R11), X9, X11                  // c442313c1b
+	VPMAXSB X2, X9, X11                     // c462313cda
+	VPMAXSB X11, X9, X11                    // c442313cdb
+	VPMAXSB (BX), Y15, Y2                   // c4e2053c13
+	VPMAXSB (R11), Y15, Y2                  // c4c2053c13
+	VPMAXSB Y2, Y15, Y2                     // c4e2053cd2
+	VPMAXSB Y11, Y15, Y2                    // c4c2053cd3
+	VPMAXSB (BX), Y15, Y11                  // c462053c1b
+	VPMAXSB (R11), Y15, Y11                 // c442053c1b
+	VPMAXSB Y2, Y15, Y11                    // c462053cda
+	VPMAXSB Y11, Y15, Y11                   // c442053cdb
+	VPMAXSD (BX), X9, X2                    // c4e2313d13
+	VPMAXSD (R11), X9, X2                   // c4c2313d13
+	VPMAXSD X2, X9, X2                      // c4e2313dd2
+	VPMAXSD X11, X9, X2                     // c4c2313dd3
+	VPMAXSD (BX), X9, X11                   // c462313d1b
+	VPMAXSD (R11), X9, X11                  // c442313d1b
+	VPMAXSD X2, X9, X11                     // c462313dda
+	VPMAXSD X11, X9, X11                    // c442313ddb
+	VPMAXSD (BX), Y15, Y2                   // c4e2053d13
+	VPMAXSD (R11), Y15, Y2                  // c4c2053d13
+	VPMAXSD Y2, Y15, Y2                     // c4e2053dd2
+	VPMAXSD Y11, Y15, Y2                    // c4c2053dd3
+	VPMAXSD (BX), Y15, Y11                  // c462053d1b
+	VPMAXSD (R11), Y15, Y11                 // c442053d1b
+	VPMAXSD Y2, Y15, Y11                    // c462053dda
+	VPMAXSD Y11, Y15, Y11                   // c442053ddb
+	VPMAXSW (BX), X9, X2                    // c4e131ee13 or c5b1ee13
+	VPMAXSW (R11), X9, X2                   // c4c131ee13
+	VPMAXSW X2, X9, X2                      // c4e131eed2 or c5b1eed2
+	VPMAXSW X11, X9, X2                     // c4c131eed3
+	VPMAXSW (BX), X9, X11                   // c46131ee1b or c531ee1b
+	VPMAXSW (R11), X9, X11                  // c44131ee1b
+	VPMAXSW X2, X9, X11                     // c46131eeda or c531eeda
+	VPMAXSW X11, X9, X11                    // c44131eedb
+	VPMAXSW (BX), Y15, Y2                   // c4e105ee13 or c585ee13
+	VPMAXSW (R11), Y15, Y2                  // c4c105ee13
+	VPMAXSW Y2, Y15, Y2                     // c4e105eed2 or c585eed2
+	VPMAXSW Y11, Y15, Y2                    // c4c105eed3
+	VPMAXSW (BX), Y15, Y11                  // c46105ee1b or c505ee1b
+	VPMAXSW (R11), Y15, Y11                 // c44105ee1b
+	VPMAXSW Y2, Y15, Y11                    // c46105eeda or c505eeda
+	VPMAXSW Y11, Y15, Y11                   // c44105eedb
+	VPMAXUB (BX), X9, X2                    // c4e131de13 or c5b1de13
+	VPMAXUB (R11), X9, X2                   // c4c131de13
+	VPMAXUB X2, X9, X2                      // c4e131ded2 or c5b1ded2
+	VPMAXUB X11, X9, X2                     // c4c131ded3
+	VPMAXUB (BX), X9, X11                   // c46131de1b or c531de1b
+	VPMAXUB (R11), X9, X11                  // c44131de1b
+	VPMAXUB X2, X9, X11                     // c46131deda or c531deda
+	VPMAXUB X11, X9, X11                    // c44131dedb
+	VPMAXUB (BX), Y15, Y2                   // c4e105de13 or c585de13
+	VPMAXUB (R11), Y15, Y2                  // c4c105de13
+	VPMAXUB Y2, Y15, Y2                     // c4e105ded2 or c585ded2
+	VPMAXUB Y11, Y15, Y2                    // c4c105ded3
+	VPMAXUB (BX), Y15, Y11                  // c46105de1b or c505de1b
+	VPMAXUB (R11), Y15, Y11                 // c44105de1b
+	VPMAXUB Y2, Y15, Y11                    // c46105deda or c505deda
+	VPMAXUB Y11, Y15, Y11                   // c44105dedb
+	VPMAXUD (BX), X9, X2                    // c4e2313f13
+	VPMAXUD (R11), X9, X2                   // c4c2313f13
+	VPMAXUD X2, X9, X2                      // c4e2313fd2
+	VPMAXUD X11, X9, X2                     // c4c2313fd3
+	VPMAXUD (BX), X9, X11                   // c462313f1b
+	VPMAXUD (R11), X9, X11                  // c442313f1b
+	VPMAXUD X2, X9, X11                     // c462313fda
+	VPMAXUD X11, X9, X11                    // c442313fdb
+	VPMAXUD (BX), Y15, Y2                   // c4e2053f13
+	VPMAXUD (R11), Y15, Y2                  // c4c2053f13
+	VPMAXUD Y2, Y15, Y2                     // c4e2053fd2
+	VPMAXUD Y11, Y15, Y2                    // c4c2053fd3
+	VPMAXUD (BX), Y15, Y11                  // c462053f1b
+	VPMAXUD (R11), Y15, Y11                 // c442053f1b
+	VPMAXUD Y2, Y15, Y11                    // c462053fda
+	VPMAXUD Y11, Y15, Y11                   // c442053fdb
+	VPMAXUW (BX), X9, X2                    // c4e2313e13
+	VPMAXUW (R11), X9, X2                   // c4c2313e13
+	VPMAXUW X2, X9, X2                      // c4e2313ed2
+	VPMAXUW X11, X9, X2                     // c4c2313ed3
+	VPMAXUW (BX), X9, X11                   // c462313e1b
+	VPMAXUW (R11), X9, X11                  // c442313e1b
+	VPMAXUW X2, X9, X11                     // c462313eda
+	VPMAXUW X11, X9, X11                    // c442313edb
+	VPMAXUW (BX), Y15, Y2                   // c4e2053e13
+	VPMAXUW (R11), Y15, Y2                  // c4c2053e13
+	VPMAXUW Y2, Y15, Y2                     // c4e2053ed2
+	VPMAXUW Y11, Y15, Y2                    // c4c2053ed3
+	VPMAXUW (BX), Y15, Y11                  // c462053e1b
+	VPMAXUW (R11), Y15, Y11                 // c442053e1b
+	VPMAXUW Y2, Y15, Y11                    // c462053eda
+	VPMAXUW Y11, Y15, Y11                   // c442053edb
+	VPMINSB (BX), X9, X2                    // c4e2313813
+	VPMINSB (R11), X9, X2                   // c4c2313813
+	VPMINSB X2, X9, X2                      // c4e23138d2
+	VPMINSB X11, X9, X2                     // c4c23138d3
+	VPMINSB (BX), X9, X11                   // c46231381b
+	VPMINSB (R11), X9, X11                  // c44231381b
+	VPMINSB X2, X9, X11                     // c4623138da
+	VPMINSB X11, X9, X11                    // c4423138db
+	VPMINSB (BX), Y15, Y2                   // c4e2053813
+	VPMINSB (R11), Y15, Y2                  // c4c2053813
+	VPMINSB Y2, Y15, Y2                     // c4e20538d2
+	VPMINSB Y11, Y15, Y2                    // c4c20538d3
+	VPMINSB (BX), Y15, Y11                  // c46205381b
+	VPMINSB (R11), Y15, Y11                 // c44205381b
+	VPMINSB Y2, Y15, Y11                    // c4620538da
+	VPMINSB Y11, Y15, Y11                   // c4420538db
+	VPMINSD (BX), X9, X2                    // c4e2313913
+	VPMINSD (R11), X9, X2                   // c4c2313913
+	VPMINSD X2, X9, X2                      // c4e23139d2
+	VPMINSD X11, X9, X2                     // c4c23139d3
+	VPMINSD (BX), X9, X11                   // c46231391b
+	VPMINSD (R11), X9, X11                  // c44231391b
+	VPMINSD X2, X9, X11                     // c4623139da
+	VPMINSD X11, X9, X11                    // c4423139db
+	VPMINSD (BX), Y15, Y2                   // c4e2053913
+	VPMINSD (R11), Y15, Y2                  // c4c2053913
+	VPMINSD Y2, Y15, Y2                     // c4e20539d2
+	VPMINSD Y11, Y15, Y2                    // c4c20539d3
+	VPMINSD (BX), Y15, Y11                  // c46205391b
+	VPMINSD (R11), Y15, Y11                 // c44205391b
+	VPMINSD Y2, Y15, Y11                    // c4620539da
+	VPMINSD Y11, Y15, Y11                   // c4420539db
+	VPMINSW (BX), X9, X2                    // c4e131ea13 or c5b1ea13
+	VPMINSW (R11), X9, X2                   // c4c131ea13
+	VPMINSW X2, X9, X2                      // c4e131ead2 or c5b1ead2
+	VPMINSW X11, X9, X2                     // c4c131ead3
+	VPMINSW (BX), X9, X11                   // c46131ea1b or c531ea1b
+	VPMINSW (R11), X9, X11                  // c44131ea1b
+	VPMINSW X2, X9, X11                     // c46131eada or c531eada
+	VPMINSW X11, X9, X11                    // c44131eadb
+	VPMINSW (BX), Y15, Y2                   // c4e105ea13 or c585ea13
+	VPMINSW (R11), Y15, Y2                  // c4c105ea13
+	VPMINSW Y2, Y15, Y2                     // c4e105ead2 or c585ead2
+	VPMINSW Y11, Y15, Y2                    // c4c105ead3
+	VPMINSW (BX), Y15, Y11                  // c46105ea1b or c505ea1b
+	VPMINSW (R11), Y15, Y11                 // c44105ea1b
+	VPMINSW Y2, Y15, Y11                    // c46105eada or c505eada
+	VPMINSW Y11, Y15, Y11                   // c44105eadb
+	VPMINUB (BX), X9, X2                    // c4e131da13 or c5b1da13
+	VPMINUB (R11), X9, X2                   // c4c131da13
+	VPMINUB X2, X9, X2                      // c4e131dad2 or c5b1dad2
+	VPMINUB X11, X9, X2                     // c4c131dad3
+	VPMINUB (BX), X9, X11                   // c46131da1b or c531da1b
+	VPMINUB (R11), X9, X11                  // c44131da1b
+	VPMINUB X2, X9, X11                     // c46131dada or c531dada
+	VPMINUB X11, X9, X11                    // c44131dadb
+	VPMINUB (BX), Y15, Y2                   // c4e105da13 or c585da13
+	VPMINUB (R11), Y15, Y2                  // c4c105da13
+	VPMINUB Y2, Y15, Y2                     // c4e105dad2 or c585dad2
+	VPMINUB Y11, Y15, Y2                    // c4c105dad3
+	VPMINUB (BX), Y15, Y11                  // c46105da1b or c505da1b
+	VPMINUB (R11), Y15, Y11                 // c44105da1b
+	VPMINUB Y2, Y15, Y11                    // c46105dada or c505dada
+	VPMINUB Y11, Y15, Y11                   // c44105dadb
+	VPMINUD (BX), X9, X2                    // c4e2313b13
+	VPMINUD (R11), X9, X2                   // c4c2313b13
+	VPMINUD X2, X9, X2                      // c4e2313bd2
+	VPMINUD X11, X9, X2                     // c4c2313bd3
+	VPMINUD (BX), X9, X11                   // c462313b1b
+	VPMINUD (R11), X9, X11                  // c442313b1b
+	VPMINUD X2, X9, X11                     // c462313bda
+	VPMINUD X11, X9, X11                    // c442313bdb
+	VPMINUD (BX), Y15, Y2                   // c4e2053b13
+	VPMINUD (R11), Y15, Y2                  // c4c2053b13
+	VPMINUD Y2, Y15, Y2                     // c4e2053bd2
+	VPMINUD Y11, Y15, Y2                    // c4c2053bd3
+	VPMINUD (BX), Y15, Y11                  // c462053b1b
+	VPMINUD (R11), Y15, Y11                 // c442053b1b
+	VPMINUD Y2, Y15, Y11                    // c462053bda
+	VPMINUD Y11, Y15, Y11                   // c442053bdb
+	VPMINUW (BX), X9, X2                    // c4e2313a13
+	VPMINUW (R11), X9, X2                   // c4c2313a13
+	VPMINUW X2, X9, X2                      // c4e2313ad2
+	VPMINUW X11, X9, X2                     // c4c2313ad3
+	VPMINUW (BX), X9, X11                   // c462313a1b
+	VPMINUW (R11), X9, X11                  // c442313a1b
+	VPMINUW X2, X9, X11                     // c462313ada
+	VPMINUW X11, X9, X11                    // c442313adb
+	VPMINUW (BX), Y15, Y2                   // c4e2053a13
+	VPMINUW (R11), Y15, Y2                  // c4c2053a13
+	VPMINUW Y2, Y15, Y2                     // c4e2053ad2
+	VPMINUW Y11, Y15, Y2                    // c4c2053ad3
+	VPMINUW (BX), Y15, Y11                  // c462053a1b
+	VPMINUW (R11), Y15, Y11                 // c442053a1b
+	VPMINUW Y2, Y15, Y11                    // c462053ada
+	VPMINUW Y11, Y15, Y11                   // c442053adb
 	VPMOVMSKB X2, DX                        // c4e179d7d2 or c5f9d7d2
 	VPMOVMSKB X11, DX                       // c4c179d7d3
 	VPMOVMSKB X2, R11                       // c46179d7da or c579d7da
@@ -9160,310 +9160,310 @@
 	VPMOVMSKB Y11, DX                       // c4c17dd7d3
 	VPMOVMSKB Y2, R11                       // c4617dd7da or c57dd7da
 	VPMOVMSKB Y11, R11                      // c4417dd7db
-	//TODO: VPMOVSXBD (BX), X2              // c4e2792113
-	//TODO: VPMOVSXBD (R11), X2             // c4c2792113
-	//TODO: VPMOVSXBD X2, X2                // c4e27921d2
-	//TODO: VPMOVSXBD X11, X2               // c4c27921d3
-	//TODO: VPMOVSXBD (BX), X11             // c46279211b
-	//TODO: VPMOVSXBD (R11), X11            // c44279211b
-	//TODO: VPMOVSXBD X2, X11               // c4627921da
-	//TODO: VPMOVSXBD X11, X11              // c4427921db
-	//TODO: VPMOVSXBD (BX), Y2              // c4e27d2113
-	//TODO: VPMOVSXBD (R11), Y2             // c4c27d2113
-	//TODO: VPMOVSXBD X2, Y2                // c4e27d21d2
-	//TODO: VPMOVSXBD X11, Y2               // c4c27d21d3
-	//TODO: VPMOVSXBD (BX), Y11             // c4627d211b
-	//TODO: VPMOVSXBD (R11), Y11            // c4427d211b
-	//TODO: VPMOVSXBD X2, Y11               // c4627d21da
-	//TODO: VPMOVSXBD X11, Y11              // c4427d21db
-	//TODO: VPMOVSXBQ (BX), X2              // c4e2792213
-	//TODO: VPMOVSXBQ (R11), X2             // c4c2792213
-	//TODO: VPMOVSXBQ X2, X2                // c4e27922d2
-	//TODO: VPMOVSXBQ X11, X2               // c4c27922d3
-	//TODO: VPMOVSXBQ (BX), X11             // c46279221b
-	//TODO: VPMOVSXBQ (R11), X11            // c44279221b
-	//TODO: VPMOVSXBQ X2, X11               // c4627922da
-	//TODO: VPMOVSXBQ X11, X11              // c4427922db
-	//TODO: VPMOVSXBQ (BX), Y2              // c4e27d2213
-	//TODO: VPMOVSXBQ (R11), Y2             // c4c27d2213
-	//TODO: VPMOVSXBQ X2, Y2                // c4e27d22d2
-	//TODO: VPMOVSXBQ X11, Y2               // c4c27d22d3
-	//TODO: VPMOVSXBQ (BX), Y11             // c4627d221b
-	//TODO: VPMOVSXBQ (R11), Y11            // c4427d221b
-	//TODO: VPMOVSXBQ X2, Y11               // c4627d22da
-	//TODO: VPMOVSXBQ X11, Y11              // c4427d22db
-	//TODO: VPMOVSXBW (BX), X2              // c4e2792013
-	//TODO: VPMOVSXBW (R11), X2             // c4c2792013
-	//TODO: VPMOVSXBW X2, X2                // c4e27920d2
-	//TODO: VPMOVSXBW X11, X2               // c4c27920d3
-	//TODO: VPMOVSXBW (BX), X11             // c46279201b
-	//TODO: VPMOVSXBW (R11), X11            // c44279201b
-	//TODO: VPMOVSXBW X2, X11               // c4627920da
-	//TODO: VPMOVSXBW X11, X11              // c4427920db
-	//TODO: VPMOVSXBW (BX), Y2              // c4e27d2013
-	//TODO: VPMOVSXBW (R11), Y2             // c4c27d2013
-	//TODO: VPMOVSXBW X2, Y2                // c4e27d20d2
-	//TODO: VPMOVSXBW X11, Y2               // c4c27d20d3
-	//TODO: VPMOVSXBW (BX), Y11             // c4627d201b
-	//TODO: VPMOVSXBW (R11), Y11            // c4427d201b
-	//TODO: VPMOVSXBW X2, Y11               // c4627d20da
-	//TODO: VPMOVSXBW X11, Y11              // c4427d20db
-	//TODO: VPMOVSXDQ (BX), X2              // c4e2792513
-	//TODO: VPMOVSXDQ (R11), X2             // c4c2792513
-	//TODO: VPMOVSXDQ X2, X2                // c4e27925d2
-	//TODO: VPMOVSXDQ X11, X2               // c4c27925d3
-	//TODO: VPMOVSXDQ (BX), X11             // c46279251b
-	//TODO: VPMOVSXDQ (R11), X11            // c44279251b
-	//TODO: VPMOVSXDQ X2, X11               // c4627925da
-	//TODO: VPMOVSXDQ X11, X11              // c4427925db
-	//TODO: VPMOVSXDQ (BX), Y2              // c4e27d2513
-	//TODO: VPMOVSXDQ (R11), Y2             // c4c27d2513
-	//TODO: VPMOVSXDQ X2, Y2                // c4e27d25d2
-	//TODO: VPMOVSXDQ X11, Y2               // c4c27d25d3
-	//TODO: VPMOVSXDQ (BX), Y11             // c4627d251b
-	//TODO: VPMOVSXDQ (R11), Y11            // c4427d251b
-	//TODO: VPMOVSXDQ X2, Y11               // c4627d25da
-	//TODO: VPMOVSXDQ X11, Y11              // c4427d25db
-	//TODO: VPMOVSXWD (BX), X2              // c4e2792313
-	//TODO: VPMOVSXWD (R11), X2             // c4c2792313
-	//TODO: VPMOVSXWD X2, X2                // c4e27923d2
-	//TODO: VPMOVSXWD X11, X2               // c4c27923d3
-	//TODO: VPMOVSXWD (BX), X11             // c46279231b
-	//TODO: VPMOVSXWD (R11), X11            // c44279231b
-	//TODO: VPMOVSXWD X2, X11               // c4627923da
-	//TODO: VPMOVSXWD X11, X11              // c4427923db
-	//TODO: VPMOVSXWD (BX), Y2              // c4e27d2313
-	//TODO: VPMOVSXWD (R11), Y2             // c4c27d2313
-	//TODO: VPMOVSXWD X2, Y2                // c4e27d23d2
-	//TODO: VPMOVSXWD X11, Y2               // c4c27d23d3
-	//TODO: VPMOVSXWD (BX), Y11             // c4627d231b
-	//TODO: VPMOVSXWD (R11), Y11            // c4427d231b
-	//TODO: VPMOVSXWD X2, Y11               // c4627d23da
-	//TODO: VPMOVSXWD X11, Y11              // c4427d23db
-	//TODO: VPMOVSXWQ (BX), X2              // c4e2792413
-	//TODO: VPMOVSXWQ (R11), X2             // c4c2792413
-	//TODO: VPMOVSXWQ X2, X2                // c4e27924d2
-	//TODO: VPMOVSXWQ X11, X2               // c4c27924d3
-	//TODO: VPMOVSXWQ (BX), X11             // c46279241b
-	//TODO: VPMOVSXWQ (R11), X11            // c44279241b
-	//TODO: VPMOVSXWQ X2, X11               // c4627924da
-	//TODO: VPMOVSXWQ X11, X11              // c4427924db
-	//TODO: VPMOVSXWQ (BX), Y2              // c4e27d2413
-	//TODO: VPMOVSXWQ (R11), Y2             // c4c27d2413
-	//TODO: VPMOVSXWQ X2, Y2                // c4e27d24d2
-	//TODO: VPMOVSXWQ X11, Y2               // c4c27d24d3
-	//TODO: VPMOVSXWQ (BX), Y11             // c4627d241b
-	//TODO: VPMOVSXWQ (R11), Y11            // c4427d241b
-	//TODO: VPMOVSXWQ X2, Y11               // c4627d24da
-	//TODO: VPMOVSXWQ X11, Y11              // c4427d24db
-	//TODO: VPMOVZXBD (BX), X2              // c4e2793113
-	//TODO: VPMOVZXBD (R11), X2             // c4c2793113
-	//TODO: VPMOVZXBD X2, X2                // c4e27931d2
-	//TODO: VPMOVZXBD X11, X2               // c4c27931d3
-	//TODO: VPMOVZXBD (BX), X11             // c46279311b
-	//TODO: VPMOVZXBD (R11), X11            // c44279311b
-	//TODO: VPMOVZXBD X2, X11               // c4627931da
-	//TODO: VPMOVZXBD X11, X11              // c4427931db
-	//TODO: VPMOVZXBD (BX), Y2              // c4e27d3113
-	//TODO: VPMOVZXBD (R11), Y2             // c4c27d3113
-	//TODO: VPMOVZXBD X2, Y2                // c4e27d31d2
-	//TODO: VPMOVZXBD X11, Y2               // c4c27d31d3
-	//TODO: VPMOVZXBD (BX), Y11             // c4627d311b
-	//TODO: VPMOVZXBD (R11), Y11            // c4427d311b
-	//TODO: VPMOVZXBD X2, Y11               // c4627d31da
-	//TODO: VPMOVZXBD X11, Y11              // c4427d31db
-	//TODO: VPMOVZXBQ (BX), X2              // c4e2793213
-	//TODO: VPMOVZXBQ (R11), X2             // c4c2793213
-	//TODO: VPMOVZXBQ X2, X2                // c4e27932d2
-	//TODO: VPMOVZXBQ X11, X2               // c4c27932d3
-	//TODO: VPMOVZXBQ (BX), X11             // c46279321b
-	//TODO: VPMOVZXBQ (R11), X11            // c44279321b
-	//TODO: VPMOVZXBQ X2, X11               // c4627932da
-	//TODO: VPMOVZXBQ X11, X11              // c4427932db
-	//TODO: VPMOVZXBQ (BX), Y2              // c4e27d3213
-	//TODO: VPMOVZXBQ (R11), Y2             // c4c27d3213
-	//TODO: VPMOVZXBQ X2, Y2                // c4e27d32d2
-	//TODO: VPMOVZXBQ X11, Y2               // c4c27d32d3
-	//TODO: VPMOVZXBQ (BX), Y11             // c4627d321b
-	//TODO: VPMOVZXBQ (R11), Y11            // c4427d321b
-	//TODO: VPMOVZXBQ X2, Y11               // c4627d32da
-	//TODO: VPMOVZXBQ X11, Y11              // c4427d32db
-	//TODO: VPMOVZXBW (BX), X2              // c4e2793013
-	//TODO: VPMOVZXBW (R11), X2             // c4c2793013
-	//TODO: VPMOVZXBW X2, X2                // c4e27930d2
-	//TODO: VPMOVZXBW X11, X2               // c4c27930d3
-	//TODO: VPMOVZXBW (BX), X11             // c46279301b
-	//TODO: VPMOVZXBW (R11), X11            // c44279301b
-	//TODO: VPMOVZXBW X2, X11               // c4627930da
-	//TODO: VPMOVZXBW X11, X11              // c4427930db
-	//TODO: VPMOVZXBW (BX), Y2              // c4e27d3013
-	//TODO: VPMOVZXBW (R11), Y2             // c4c27d3013
-	//TODO: VPMOVZXBW X2, Y2                // c4e27d30d2
-	//TODO: VPMOVZXBW X11, Y2               // c4c27d30d3
-	//TODO: VPMOVZXBW (BX), Y11             // c4627d301b
-	//TODO: VPMOVZXBW (R11), Y11            // c4427d301b
-	//TODO: VPMOVZXBW X2, Y11               // c4627d30da
-	//TODO: VPMOVZXBW X11, Y11              // c4427d30db
-	//TODO: VPMOVZXDQ (BX), X2              // c4e2793513
-	//TODO: VPMOVZXDQ (R11), X2             // c4c2793513
-	//TODO: VPMOVZXDQ X2, X2                // c4e27935d2
-	//TODO: VPMOVZXDQ X11, X2               // c4c27935d3
-	//TODO: VPMOVZXDQ (BX), X11             // c46279351b
-	//TODO: VPMOVZXDQ (R11), X11            // c44279351b
-	//TODO: VPMOVZXDQ X2, X11               // c4627935da
-	//TODO: VPMOVZXDQ X11, X11              // c4427935db
-	//TODO: VPMOVZXDQ (BX), Y2              // c4e27d3513
-	//TODO: VPMOVZXDQ (R11), Y2             // c4c27d3513
-	//TODO: VPMOVZXDQ X2, Y2                // c4e27d35d2
-	//TODO: VPMOVZXDQ X11, Y2               // c4c27d35d3
-	//TODO: VPMOVZXDQ (BX), Y11             // c4627d351b
-	//TODO: VPMOVZXDQ (R11), Y11            // c4427d351b
-	//TODO: VPMOVZXDQ X2, Y11               // c4627d35da
-	//TODO: VPMOVZXDQ X11, Y11              // c4427d35db
-	//TODO: VPMOVZXWD (BX), X2              // c4e2793313
-	//TODO: VPMOVZXWD (R11), X2             // c4c2793313
-	//TODO: VPMOVZXWD X2, X2                // c4e27933d2
-	//TODO: VPMOVZXWD X11, X2               // c4c27933d3
-	//TODO: VPMOVZXWD (BX), X11             // c46279331b
-	//TODO: VPMOVZXWD (R11), X11            // c44279331b
-	//TODO: VPMOVZXWD X2, X11               // c4627933da
-	//TODO: VPMOVZXWD X11, X11              // c4427933db
-	//TODO: VPMOVZXWD (BX), Y2              // c4e27d3313
-	//TODO: VPMOVZXWD (R11), Y2             // c4c27d3313
-	//TODO: VPMOVZXWD X2, Y2                // c4e27d33d2
-	//TODO: VPMOVZXWD X11, Y2               // c4c27d33d3
-	//TODO: VPMOVZXWD (BX), Y11             // c4627d331b
-	//TODO: VPMOVZXWD (R11), Y11            // c4427d331b
-	//TODO: VPMOVZXWD X2, Y11               // c4627d33da
-	//TODO: VPMOVZXWD X11, Y11              // c4427d33db
-	//TODO: VPMOVZXWQ (BX), X2              // c4e2793413
-	//TODO: VPMOVZXWQ (R11), X2             // c4c2793413
-	//TODO: VPMOVZXWQ X2, X2                // c4e27934d2
-	//TODO: VPMOVZXWQ X11, X2               // c4c27934d3
-	//TODO: VPMOVZXWQ (BX), X11             // c46279341b
-	//TODO: VPMOVZXWQ (R11), X11            // c44279341b
-	//TODO: VPMOVZXWQ X2, X11               // c4627934da
-	//TODO: VPMOVZXWQ X11, X11              // c4427934db
-	//TODO: VPMOVZXWQ (BX), Y2              // c4e27d3413
-	//TODO: VPMOVZXWQ (R11), Y2             // c4c27d3413
-	//TODO: VPMOVZXWQ X2, Y2                // c4e27d34d2
-	//TODO: VPMOVZXWQ X11, Y2               // c4c27d34d3
-	//TODO: VPMOVZXWQ (BX), Y11             // c4627d341b
-	//TODO: VPMOVZXWQ (R11), Y11            // c4427d341b
-	//TODO: VPMOVZXWQ X2, Y11               // c4627d34da
-	//TODO: VPMOVZXWQ X11, Y11              // c4427d34db
-	//TODO: VPMULDQ (BX), X9, X2            // c4e2312813
-	//TODO: VPMULDQ (R11), X9, X2           // c4c2312813
-	//TODO: VPMULDQ X2, X9, X2              // c4e23128d2
-	//TODO: VPMULDQ X11, X9, X2             // c4c23128d3
-	//TODO: VPMULDQ (BX), X9, X11           // c46231281b
-	//TODO: VPMULDQ (R11), X9, X11          // c44231281b
-	//TODO: VPMULDQ X2, X9, X11             // c4623128da
-	//TODO: VPMULDQ X11, X9, X11            // c4423128db
-	//TODO: VPMULDQ (BX), Y15, Y2           // c4e2052813
-	//TODO: VPMULDQ (R11), Y15, Y2          // c4c2052813
-	//TODO: VPMULDQ Y2, Y15, Y2             // c4e20528d2
-	//TODO: VPMULDQ Y11, Y15, Y2            // c4c20528d3
-	//TODO: VPMULDQ (BX), Y15, Y11          // c46205281b
-	//TODO: VPMULDQ (R11), Y15, Y11         // c44205281b
-	//TODO: VPMULDQ Y2, Y15, Y11            // c4620528da
-	//TODO: VPMULDQ Y11, Y15, Y11           // c4420528db
-	//TODO: VPMULHRSW (BX), X9, X2          // c4e2310b13
-	//TODO: VPMULHRSW (R11), X9, X2         // c4c2310b13
-	//TODO: VPMULHRSW X2, X9, X2            // c4e2310bd2
-	//TODO: VPMULHRSW X11, X9, X2           // c4c2310bd3
-	//TODO: VPMULHRSW (BX), X9, X11         // c462310b1b
-	//TODO: VPMULHRSW (R11), X9, X11        // c442310b1b
-	//TODO: VPMULHRSW X2, X9, X11           // c462310bda
-	//TODO: VPMULHRSW X11, X9, X11          // c442310bdb
-	//TODO: VPMULHRSW (BX), Y15, Y2         // c4e2050b13
-	//TODO: VPMULHRSW (R11), Y15, Y2        // c4c2050b13
-	//TODO: VPMULHRSW Y2, Y15, Y2           // c4e2050bd2
-	//TODO: VPMULHRSW Y11, Y15, Y2          // c4c2050bd3
-	//TODO: VPMULHRSW (BX), Y15, Y11        // c462050b1b
-	//TODO: VPMULHRSW (R11), Y15, Y11       // c442050b1b
-	//TODO: VPMULHRSW Y2, Y15, Y11          // c462050bda
-	//TODO: VPMULHRSW Y11, Y15, Y11         // c442050bdb
-	//TODO: VPMULHUW (BX), X9, X2           // c4e131e413 or c5b1e413
-	//TODO: VPMULHUW (R11), X9, X2          // c4c131e413
-	//TODO: VPMULHUW X2, X9, X2             // c4e131e4d2 or c5b1e4d2
-	//TODO: VPMULHUW X11, X9, X2            // c4c131e4d3
-	//TODO: VPMULHUW (BX), X9, X11          // c46131e41b or c531e41b
-	//TODO: VPMULHUW (R11), X9, X11         // c44131e41b
-	//TODO: VPMULHUW X2, X9, X11            // c46131e4da or c531e4da
-	//TODO: VPMULHUW X11, X9, X11           // c44131e4db
-	//TODO: VPMULHUW (BX), Y15, Y2          // c4e105e413 or c585e413
-	//TODO: VPMULHUW (R11), Y15, Y2         // c4c105e413
-	//TODO: VPMULHUW Y2, Y15, Y2            // c4e105e4d2 or c585e4d2
-	//TODO: VPMULHUW Y11, Y15, Y2           // c4c105e4d3
-	//TODO: VPMULHUW (BX), Y15, Y11         // c46105e41b or c505e41b
-	//TODO: VPMULHUW (R11), Y15, Y11        // c44105e41b
-	//TODO: VPMULHUW Y2, Y15, Y11           // c46105e4da or c505e4da
-	//TODO: VPMULHUW Y11, Y15, Y11          // c44105e4db
-	//TODO: VPMULHW (BX), X9, X2            // c4e131e513 or c5b1e513
-	//TODO: VPMULHW (R11), X9, X2           // c4c131e513
-	//TODO: VPMULHW X2, X9, X2              // c4e131e5d2 or c5b1e5d2
-	//TODO: VPMULHW X11, X9, X2             // c4c131e5d3
-	//TODO: VPMULHW (BX), X9, X11           // c46131e51b or c531e51b
-	//TODO: VPMULHW (R11), X9, X11          // c44131e51b
-	//TODO: VPMULHW X2, X9, X11             // c46131e5da or c531e5da
-	//TODO: VPMULHW X11, X9, X11            // c44131e5db
-	//TODO: VPMULHW (BX), Y15, Y2           // c4e105e513 or c585e513
-	//TODO: VPMULHW (R11), Y15, Y2          // c4c105e513
-	//TODO: VPMULHW Y2, Y15, Y2             // c4e105e5d2 or c585e5d2
-	//TODO: VPMULHW Y11, Y15, Y2            // c4c105e5d3
-	//TODO: VPMULHW (BX), Y15, Y11          // c46105e51b or c505e51b
-	//TODO: VPMULHW (R11), Y15, Y11         // c44105e51b
-	//TODO: VPMULHW Y2, Y15, Y11            // c46105e5da or c505e5da
-	//TODO: VPMULHW Y11, Y15, Y11           // c44105e5db
-	//TODO: VPMULLD (BX), X9, X2            // c4e2314013
-	//TODO: VPMULLD (R11), X9, X2           // c4c2314013
-	//TODO: VPMULLD X2, X9, X2              // c4e23140d2
-	//TODO: VPMULLD X11, X9, X2             // c4c23140d3
-	//TODO: VPMULLD (BX), X9, X11           // c46231401b
-	//TODO: VPMULLD (R11), X9, X11          // c44231401b
-	//TODO: VPMULLD X2, X9, X11             // c4623140da
-	//TODO: VPMULLD X11, X9, X11            // c4423140db
-	//TODO: VPMULLD (BX), Y15, Y2           // c4e2054013
-	//TODO: VPMULLD (R11), Y15, Y2          // c4c2054013
-	//TODO: VPMULLD Y2, Y15, Y2             // c4e20540d2
-	//TODO: VPMULLD Y11, Y15, Y2            // c4c20540d3
-	//TODO: VPMULLD (BX), Y15, Y11          // c46205401b
-	//TODO: VPMULLD (R11), Y15, Y11         // c44205401b
-	//TODO: VPMULLD Y2, Y15, Y11            // c4620540da
-	//TODO: VPMULLD Y11, Y15, Y11           // c4420540db
-	//TODO: VPMULLW (BX), X9, X2            // c4e131d513 or c5b1d513
-	//TODO: VPMULLW (R11), X9, X2           // c4c131d513
-	//TODO: VPMULLW X2, X9, X2              // c4e131d5d2 or c5b1d5d2
-	//TODO: VPMULLW X11, X9, X2             // c4c131d5d3
-	//TODO: VPMULLW (BX), X9, X11           // c46131d51b or c531d51b
-	//TODO: VPMULLW (R11), X9, X11          // c44131d51b
-	//TODO: VPMULLW X2, X9, X11             // c46131d5da or c531d5da
-	//TODO: VPMULLW X11, X9, X11            // c44131d5db
-	//TODO: VPMULLW (BX), Y15, Y2           // c4e105d513 or c585d513
-	//TODO: VPMULLW (R11), Y15, Y2          // c4c105d513
-	//TODO: VPMULLW Y2, Y15, Y2             // c4e105d5d2 or c585d5d2
-	//TODO: VPMULLW Y11, Y15, Y2            // c4c105d5d3
-	//TODO: VPMULLW (BX), Y15, Y11          // c46105d51b or c505d51b
-	//TODO: VPMULLW (R11), Y15, Y11         // c44105d51b
-	//TODO: VPMULLW Y2, Y15, Y11            // c46105d5da or c505d5da
-	//TODO: VPMULLW Y11, Y15, Y11           // c44105d5db
-	//TODO: VPMULUDQ (BX), X9, X2           // c4e131f413 or c5b1f413
-	//TODO: VPMULUDQ (R11), X9, X2          // c4c131f413
-	//TODO: VPMULUDQ X2, X9, X2             // c4e131f4d2 or c5b1f4d2
-	//TODO: VPMULUDQ X11, X9, X2            // c4c131f4d3
-	//TODO: VPMULUDQ (BX), X9, X11          // c46131f41b or c531f41b
-	//TODO: VPMULUDQ (R11), X9, X11         // c44131f41b
-	//TODO: VPMULUDQ X2, X9, X11            // c46131f4da or c531f4da
-	//TODO: VPMULUDQ X11, X9, X11           // c44131f4db
-	//TODO: VPMULUDQ (BX), Y15, Y2          // c4e105f413 or c585f413
-	//TODO: VPMULUDQ (R11), Y15, Y2         // c4c105f413
-	//TODO: VPMULUDQ Y2, Y15, Y2            // c4e105f4d2 or c585f4d2
-	//TODO: VPMULUDQ Y11, Y15, Y2           // c4c105f4d3
-	//TODO: VPMULUDQ (BX), Y15, Y11         // c46105f41b or c505f41b
-	//TODO: VPMULUDQ (R11), Y15, Y11        // c44105f41b
-	//TODO: VPMULUDQ Y2, Y15, Y11           // c46105f4da or c505f4da
-	//TODO: VPMULUDQ Y11, Y15, Y11          // c44105f4db
+	VPMOVSXBD (BX), X2                      // c4e2792113
+	VPMOVSXBD (R11), X2                     // c4c2792113
+	VPMOVSXBD X2, X2                        // c4e27921d2
+	VPMOVSXBD X11, X2                       // c4c27921d3
+	VPMOVSXBD (BX), X11                     // c46279211b
+	VPMOVSXBD (R11), X11                    // c44279211b
+	VPMOVSXBD X2, X11                       // c4627921da
+	VPMOVSXBD X11, X11                      // c4427921db
+	VPMOVSXBD (BX), Y2                      // c4e27d2113
+	VPMOVSXBD (R11), Y2                     // c4c27d2113
+	VPMOVSXBD X2, Y2                        // c4e27d21d2
+	VPMOVSXBD X11, Y2                       // c4c27d21d3
+	VPMOVSXBD (BX), Y11                     // c4627d211b
+	VPMOVSXBD (R11), Y11                    // c4427d211b
+	VPMOVSXBD X2, Y11                       // c4627d21da
+	VPMOVSXBD X11, Y11                      // c4427d21db
+	VPMOVSXBQ (BX), X2                      // c4e2792213
+	VPMOVSXBQ (R11), X2                     // c4c2792213
+	VPMOVSXBQ X2, X2                        // c4e27922d2
+	VPMOVSXBQ X11, X2                       // c4c27922d3
+	VPMOVSXBQ (BX), X11                     // c46279221b
+	VPMOVSXBQ (R11), X11                    // c44279221b
+	VPMOVSXBQ X2, X11                       // c4627922da
+	VPMOVSXBQ X11, X11                      // c4427922db
+	VPMOVSXBQ (BX), Y2                      // c4e27d2213
+	VPMOVSXBQ (R11), Y2                     // c4c27d2213
+	VPMOVSXBQ X2, Y2                        // c4e27d22d2
+	VPMOVSXBQ X11, Y2                       // c4c27d22d3
+	VPMOVSXBQ (BX), Y11                     // c4627d221b
+	VPMOVSXBQ (R11), Y11                    // c4427d221b
+	VPMOVSXBQ X2, Y11                       // c4627d22da
+	VPMOVSXBQ X11, Y11                      // c4427d22db
+	VPMOVSXBW (BX), X2                      // c4e2792013
+	VPMOVSXBW (R11), X2                     // c4c2792013
+	VPMOVSXBW X2, X2                        // c4e27920d2
+	VPMOVSXBW X11, X2                       // c4c27920d3
+	VPMOVSXBW (BX), X11                     // c46279201b
+	VPMOVSXBW (R11), X11                    // c44279201b
+	VPMOVSXBW X2, X11                       // c4627920da
+	VPMOVSXBW X11, X11                      // c4427920db
+	VPMOVSXBW (BX), Y2                      // c4e27d2013
+	VPMOVSXBW (R11), Y2                     // c4c27d2013
+	VPMOVSXBW X2, Y2                        // c4e27d20d2
+	VPMOVSXBW X11, Y2                       // c4c27d20d3
+	VPMOVSXBW (BX), Y11                     // c4627d201b
+	VPMOVSXBW (R11), Y11                    // c4427d201b
+	VPMOVSXBW X2, Y11                       // c4627d20da
+	VPMOVSXBW X11, Y11                      // c4427d20db
+	VPMOVSXDQ (BX), X2                      // c4e2792513
+	VPMOVSXDQ (R11), X2                     // c4c2792513
+	VPMOVSXDQ X2, X2                        // c4e27925d2
+	VPMOVSXDQ X11, X2                       // c4c27925d3
+	VPMOVSXDQ (BX), X11                     // c46279251b
+	VPMOVSXDQ (R11), X11                    // c44279251b
+	VPMOVSXDQ X2, X11                       // c4627925da
+	VPMOVSXDQ X11, X11                      // c4427925db
+	VPMOVSXDQ (BX), Y2                      // c4e27d2513
+	VPMOVSXDQ (R11), Y2                     // c4c27d2513
+	VPMOVSXDQ X2, Y2                        // c4e27d25d2
+	VPMOVSXDQ X11, Y2                       // c4c27d25d3
+	VPMOVSXDQ (BX), Y11                     // c4627d251b
+	VPMOVSXDQ (R11), Y11                    // c4427d251b
+	VPMOVSXDQ X2, Y11                       // c4627d25da
+	VPMOVSXDQ X11, Y11                      // c4427d25db
+	VPMOVSXWD (BX), X2                      // c4e2792313
+	VPMOVSXWD (R11), X2                     // c4c2792313
+	VPMOVSXWD X2, X2                        // c4e27923d2
+	VPMOVSXWD X11, X2                       // c4c27923d3
+	VPMOVSXWD (BX), X11                     // c46279231b
+	VPMOVSXWD (R11), X11                    // c44279231b
+	VPMOVSXWD X2, X11                       // c4627923da
+	VPMOVSXWD X11, X11                      // c4427923db
+	VPMOVSXWD (BX), Y2                      // c4e27d2313
+	VPMOVSXWD (R11), Y2                     // c4c27d2313
+	VPMOVSXWD X2, Y2                        // c4e27d23d2
+	VPMOVSXWD X11, Y2                       // c4c27d23d3
+	VPMOVSXWD (BX), Y11                     // c4627d231b
+	VPMOVSXWD (R11), Y11                    // c4427d231b
+	VPMOVSXWD X2, Y11                       // c4627d23da
+	VPMOVSXWD X11, Y11                      // c4427d23db
+	VPMOVSXWQ (BX), X2                      // c4e2792413
+	VPMOVSXWQ (R11), X2                     // c4c2792413
+	VPMOVSXWQ X2, X2                        // c4e27924d2
+	VPMOVSXWQ X11, X2                       // c4c27924d3
+	VPMOVSXWQ (BX), X11                     // c46279241b
+	VPMOVSXWQ (R11), X11                    // c44279241b
+	VPMOVSXWQ X2, X11                       // c4627924da
+	VPMOVSXWQ X11, X11                      // c4427924db
+	VPMOVSXWQ (BX), Y2                      // c4e27d2413
+	VPMOVSXWQ (R11), Y2                     // c4c27d2413
+	VPMOVSXWQ X2, Y2                        // c4e27d24d2
+	VPMOVSXWQ X11, Y2                       // c4c27d24d3
+	VPMOVSXWQ (BX), Y11                     // c4627d241b
+	VPMOVSXWQ (R11), Y11                    // c4427d241b
+	VPMOVSXWQ X2, Y11                       // c4627d24da
+	VPMOVSXWQ X11, Y11                      // c4427d24db
+	VPMOVZXBD (BX), X2                      // c4e2793113
+	VPMOVZXBD (R11), X2                     // c4c2793113
+	VPMOVZXBD X2, X2                        // c4e27931d2
+	VPMOVZXBD X11, X2                       // c4c27931d3
+	VPMOVZXBD (BX), X11                     // c46279311b
+	VPMOVZXBD (R11), X11                    // c44279311b
+	VPMOVZXBD X2, X11                       // c4627931da
+	VPMOVZXBD X11, X11                      // c4427931db
+	VPMOVZXBD (BX), Y2                      // c4e27d3113
+	VPMOVZXBD (R11), Y2                     // c4c27d3113
+	VPMOVZXBD X2, Y2                        // c4e27d31d2
+	VPMOVZXBD X11, Y2                       // c4c27d31d3
+	VPMOVZXBD (BX), Y11                     // c4627d311b
+	VPMOVZXBD (R11), Y11                    // c4427d311b
+	VPMOVZXBD X2, Y11                       // c4627d31da
+	VPMOVZXBD X11, Y11                      // c4427d31db
+	VPMOVZXBQ (BX), X2                      // c4e2793213
+	VPMOVZXBQ (R11), X2                     // c4c2793213
+	VPMOVZXBQ X2, X2                        // c4e27932d2
+	VPMOVZXBQ X11, X2                       // c4c27932d3
+	VPMOVZXBQ (BX), X11                     // c46279321b
+	VPMOVZXBQ (R11), X11                    // c44279321b
+	VPMOVZXBQ X2, X11                       // c4627932da
+	VPMOVZXBQ X11, X11                      // c4427932db
+	VPMOVZXBQ (BX), Y2                      // c4e27d3213
+	VPMOVZXBQ (R11), Y2                     // c4c27d3213
+	VPMOVZXBQ X2, Y2                        // c4e27d32d2
+	VPMOVZXBQ X11, Y2                       // c4c27d32d3
+	VPMOVZXBQ (BX), Y11                     // c4627d321b
+	VPMOVZXBQ (R11), Y11                    // c4427d321b
+	VPMOVZXBQ X2, Y11                       // c4627d32da
+	VPMOVZXBQ X11, Y11                      // c4427d32db
+	VPMOVZXBW (BX), X2                      // c4e2793013
+	VPMOVZXBW (R11), X2                     // c4c2793013
+	VPMOVZXBW X2, X2                        // c4e27930d2
+	VPMOVZXBW X11, X2                       // c4c27930d3
+	VPMOVZXBW (BX), X11                     // c46279301b
+	VPMOVZXBW (R11), X11                    // c44279301b
+	VPMOVZXBW X2, X11                       // c4627930da
+	VPMOVZXBW X11, X11                      // c4427930db
+	VPMOVZXBW (BX), Y2                      // c4e27d3013
+	VPMOVZXBW (R11), Y2                     // c4c27d3013
+	VPMOVZXBW X2, Y2                        // c4e27d30d2
+	VPMOVZXBW X11, Y2                       // c4c27d30d3
+	VPMOVZXBW (BX), Y11                     // c4627d301b
+	VPMOVZXBW (R11), Y11                    // c4427d301b
+	VPMOVZXBW X2, Y11                       // c4627d30da
+	VPMOVZXBW X11, Y11                      // c4427d30db
+	VPMOVZXDQ (BX), X2                      // c4e2793513
+	VPMOVZXDQ (R11), X2                     // c4c2793513
+	VPMOVZXDQ X2, X2                        // c4e27935d2
+	VPMOVZXDQ X11, X2                       // c4c27935d3
+	VPMOVZXDQ (BX), X11                     // c46279351b
+	VPMOVZXDQ (R11), X11                    // c44279351b
+	VPMOVZXDQ X2, X11                       // c4627935da
+	VPMOVZXDQ X11, X11                      // c4427935db
+	VPMOVZXDQ (BX), Y2                      // c4e27d3513
+	VPMOVZXDQ (R11), Y2                     // c4c27d3513
+	VPMOVZXDQ X2, Y2                        // c4e27d35d2
+	VPMOVZXDQ X11, Y2                       // c4c27d35d3
+	VPMOVZXDQ (BX), Y11                     // c4627d351b
+	VPMOVZXDQ (R11), Y11                    // c4427d351b
+	VPMOVZXDQ X2, Y11                       // c4627d35da
+	VPMOVZXDQ X11, Y11                      // c4427d35db
+	VPMOVZXWD (BX), X2                      // c4e2793313
+	VPMOVZXWD (R11), X2                     // c4c2793313
+	VPMOVZXWD X2, X2                        // c4e27933d2
+	VPMOVZXWD X11, X2                       // c4c27933d3
+	VPMOVZXWD (BX), X11                     // c46279331b
+	VPMOVZXWD (R11), X11                    // c44279331b
+	VPMOVZXWD X2, X11                       // c4627933da
+	VPMOVZXWD X11, X11                      // c4427933db
+	VPMOVZXWD (BX), Y2                      // c4e27d3313
+	VPMOVZXWD (R11), Y2                     // c4c27d3313
+	VPMOVZXWD X2, Y2                        // c4e27d33d2
+	VPMOVZXWD X11, Y2                       // c4c27d33d3
+	VPMOVZXWD (BX), Y11                     // c4627d331b
+	VPMOVZXWD (R11), Y11                    // c4427d331b
+	VPMOVZXWD X2, Y11                       // c4627d33da
+	VPMOVZXWD X11, Y11                      // c4427d33db
+	VPMOVZXWQ (BX), X2                      // c4e2793413
+	VPMOVZXWQ (R11), X2                     // c4c2793413
+	VPMOVZXWQ X2, X2                        // c4e27934d2
+	VPMOVZXWQ X11, X2                       // c4c27934d3
+	VPMOVZXWQ (BX), X11                     // c46279341b
+	VPMOVZXWQ (R11), X11                    // c44279341b
+	VPMOVZXWQ X2, X11                       // c4627934da
+	VPMOVZXWQ X11, X11                      // c4427934db
+	VPMOVZXWQ (BX), Y2                      // c4e27d3413
+	VPMOVZXWQ (R11), Y2                     // c4c27d3413
+	VPMOVZXWQ X2, Y2                        // c4e27d34d2
+	VPMOVZXWQ X11, Y2                       // c4c27d34d3
+	VPMOVZXWQ (BX), Y11                     // c4627d341b
+	VPMOVZXWQ (R11), Y11                    // c4427d341b
+	VPMOVZXWQ X2, Y11                       // c4627d34da
+	VPMOVZXWQ X11, Y11                      // c4427d34db
+	VPMULDQ (BX), X9, X2                    // c4e2312813
+	VPMULDQ (R11), X9, X2                   // c4c2312813
+	VPMULDQ X2, X9, X2                      // c4e23128d2
+	VPMULDQ X11, X9, X2                     // c4c23128d3
+	VPMULDQ (BX), X9, X11                   // c46231281b
+	VPMULDQ (R11), X9, X11                  // c44231281b
+	VPMULDQ X2, X9, X11                     // c4623128da
+	VPMULDQ X11, X9, X11                    // c4423128db
+	VPMULDQ (BX), Y15, Y2                   // c4e2052813
+	VPMULDQ (R11), Y15, Y2                  // c4c2052813
+	VPMULDQ Y2, Y15, Y2                     // c4e20528d2
+	VPMULDQ Y11, Y15, Y2                    // c4c20528d3
+	VPMULDQ (BX), Y15, Y11                  // c46205281b
+	VPMULDQ (R11), Y15, Y11                 // c44205281b
+	VPMULDQ Y2, Y15, Y11                    // c4620528da
+	VPMULDQ Y11, Y15, Y11                   // c4420528db
+	VPMULHRSW (BX), X9, X2                  // c4e2310b13
+	VPMULHRSW (R11), X9, X2                 // c4c2310b13
+	VPMULHRSW X2, X9, X2                    // c4e2310bd2
+	VPMULHRSW X11, X9, X2                   // c4c2310bd3
+	VPMULHRSW (BX), X9, X11                 // c462310b1b
+	VPMULHRSW (R11), X9, X11                // c442310b1b
+	VPMULHRSW X2, X9, X11                   // c462310bda
+	VPMULHRSW X11, X9, X11                  // c442310bdb
+	VPMULHRSW (BX), Y15, Y2                 // c4e2050b13
+	VPMULHRSW (R11), Y15, Y2                // c4c2050b13
+	VPMULHRSW Y2, Y15, Y2                   // c4e2050bd2
+	VPMULHRSW Y11, Y15, Y2                  // c4c2050bd3
+	VPMULHRSW (BX), Y15, Y11                // c462050b1b
+	VPMULHRSW (R11), Y15, Y11               // c442050b1b
+	VPMULHRSW Y2, Y15, Y11                  // c462050bda
+	VPMULHRSW Y11, Y15, Y11                 // c442050bdb
+	VPMULHUW (BX), X9, X2                   // c4e131e413 or c5b1e413
+	VPMULHUW (R11), X9, X2                  // c4c131e413
+	VPMULHUW X2, X9, X2                     // c4e131e4d2 or c5b1e4d2
+	VPMULHUW X11, X9, X2                    // c4c131e4d3
+	VPMULHUW (BX), X9, X11                  // c46131e41b or c531e41b
+	VPMULHUW (R11), X9, X11                 // c44131e41b
+	VPMULHUW X2, X9, X11                    // c46131e4da or c531e4da
+	VPMULHUW X11, X9, X11                   // c44131e4db
+	VPMULHUW (BX), Y15, Y2                  // c4e105e413 or c585e413
+	VPMULHUW (R11), Y15, Y2                 // c4c105e413
+	VPMULHUW Y2, Y15, Y2                    // c4e105e4d2 or c585e4d2
+	VPMULHUW Y11, Y15, Y2                   // c4c105e4d3
+	VPMULHUW (BX), Y15, Y11                 // c46105e41b or c505e41b
+	VPMULHUW (R11), Y15, Y11                // c44105e41b
+	VPMULHUW Y2, Y15, Y11                   // c46105e4da or c505e4da
+	VPMULHUW Y11, Y15, Y11                  // c44105e4db
+	VPMULHW (BX), X9, X2                    // c4e131e513 or c5b1e513
+	VPMULHW (R11), X9, X2                   // c4c131e513
+	VPMULHW X2, X9, X2                      // c4e131e5d2 or c5b1e5d2
+	VPMULHW X11, X9, X2                     // c4c131e5d3
+	VPMULHW (BX), X9, X11                   // c46131e51b or c531e51b
+	VPMULHW (R11), X9, X11                  // c44131e51b
+	VPMULHW X2, X9, X11                     // c46131e5da or c531e5da
+	VPMULHW X11, X9, X11                    // c44131e5db
+	VPMULHW (BX), Y15, Y2                   // c4e105e513 or c585e513
+	VPMULHW (R11), Y15, Y2                  // c4c105e513
+	VPMULHW Y2, Y15, Y2                     // c4e105e5d2 or c585e5d2
+	VPMULHW Y11, Y15, Y2                    // c4c105e5d3
+	VPMULHW (BX), Y15, Y11                  // c46105e51b or c505e51b
+	VPMULHW (R11), Y15, Y11                 // c44105e51b
+	VPMULHW Y2, Y15, Y11                    // c46105e5da or c505e5da
+	VPMULHW Y11, Y15, Y11                   // c44105e5db
+	VPMULLD (BX), X9, X2                    // c4e2314013
+	VPMULLD (R11), X9, X2                   // c4c2314013
+	VPMULLD X2, X9, X2                      // c4e23140d2
+	VPMULLD X11, X9, X2                     // c4c23140d3
+	VPMULLD (BX), X9, X11                   // c46231401b
+	VPMULLD (R11), X9, X11                  // c44231401b
+	VPMULLD X2, X9, X11                     // c4623140da
+	VPMULLD X11, X9, X11                    // c4423140db
+	VPMULLD (BX), Y15, Y2                   // c4e2054013
+	VPMULLD (R11), Y15, Y2                  // c4c2054013
+	VPMULLD Y2, Y15, Y2                     // c4e20540d2
+	VPMULLD Y11, Y15, Y2                    // c4c20540d3
+	VPMULLD (BX), Y15, Y11                  // c46205401b
+	VPMULLD (R11), Y15, Y11                 // c44205401b
+	VPMULLD Y2, Y15, Y11                    // c4620540da
+	VPMULLD Y11, Y15, Y11                   // c4420540db
+	VPMULLW (BX), X9, X2                    // c4e131d513 or c5b1d513
+	VPMULLW (R11), X9, X2                   // c4c131d513
+	VPMULLW X2, X9, X2                      // c4e131d5d2 or c5b1d5d2
+	VPMULLW X11, X9, X2                     // c4c131d5d3
+	VPMULLW (BX), X9, X11                   // c46131d51b or c531d51b
+	VPMULLW (R11), X9, X11                  // c44131d51b
+	VPMULLW X2, X9, X11                     // c46131d5da or c531d5da
+	VPMULLW X11, X9, X11                    // c44131d5db
+	VPMULLW (BX), Y15, Y2                   // c4e105d513 or c585d513
+	VPMULLW (R11), Y15, Y2                  // c4c105d513
+	VPMULLW Y2, Y15, Y2                     // c4e105d5d2 or c585d5d2
+	VPMULLW Y11, Y15, Y2                    // c4c105d5d3
+	VPMULLW (BX), Y15, Y11                  // c46105d51b or c505d51b
+	VPMULLW (R11), Y15, Y11                 // c44105d51b
+	VPMULLW Y2, Y15, Y11                    // c46105d5da or c505d5da
+	VPMULLW Y11, Y15, Y11                   // c44105d5db
+	VPMULUDQ (BX), X9, X2                   // c4e131f413 or c5b1f413
+	VPMULUDQ (R11), X9, X2                  // c4c131f413
+	VPMULUDQ X2, X9, X2                     // c4e131f4d2 or c5b1f4d2
+	VPMULUDQ X11, X9, X2                    // c4c131f4d3
+	VPMULUDQ (BX), X9, X11                  // c46131f41b or c531f41b
+	VPMULUDQ (R11), X9, X11                 // c44131f41b
+	VPMULUDQ X2, X9, X11                    // c46131f4da or c531f4da
+	VPMULUDQ X11, X9, X11                   // c44131f4db
+	VPMULUDQ (BX), Y15, Y2                  // c4e105f413 or c585f413
+	VPMULUDQ (R11), Y15, Y2                 // c4c105f413
+	VPMULUDQ Y2, Y15, Y2                    // c4e105f4d2 or c585f4d2
+	VPMULUDQ Y11, Y15, Y2                   // c4c105f4d3
+	VPMULUDQ (BX), Y15, Y11                 // c46105f41b or c505f41b
+	VPMULUDQ (R11), Y15, Y11                // c44105f41b
+	VPMULUDQ Y2, Y15, Y11                   // c46105f4da or c505f4da
+	VPMULUDQ Y11, Y15, Y11                  // c44105f4db
 	VPOR (BX), X9, X2               // c4e131eb13 or c5b1eb13
 	VPOR (R11), X9, X2              // c4c131eb13
 	VPOR X2, X9, X2                 // c4e131ebd2 or c5b1ebd2
@@ -9480,22 +9480,22 @@
 	VPOR (R11), Y15, Y11            // c44105eb1b
 	VPOR Y2, Y15, Y11               // c46105ebda or c505ebda
 	VPOR Y11, Y15, Y11              // c44105ebdb
-	//TODO: VPSADBW (BX), X9, X2            // c4e131f613 or c5b1f613
-	//TODO: VPSADBW (R11), X9, X2           // c4c131f613
-	//TODO: VPSADBW X2, X9, X2              // c4e131f6d2 or c5b1f6d2
-	//TODO: VPSADBW X11, X9, X2             // c4c131f6d3
-	//TODO: VPSADBW (BX), X9, X11           // c46131f61b or c531f61b
-	//TODO: VPSADBW (R11), X9, X11          // c44131f61b
-	//TODO: VPSADBW X2, X9, X11             // c46131f6da or c531f6da
-	//TODO: VPSADBW X11, X9, X11            // c44131f6db
-	//TODO: VPSADBW (BX), Y15, Y2           // c4e105f613 or c585f613
-	//TODO: VPSADBW (R11), Y15, Y2          // c4c105f613
-	//TODO: VPSADBW Y2, Y15, Y2             // c4e105f6d2 or c585f6d2
-	//TODO: VPSADBW Y11, Y15, Y2            // c4c105f6d3
-	//TODO: VPSADBW (BX), Y15, Y11          // c46105f61b or c505f61b
-	//TODO: VPSADBW (R11), Y15, Y11         // c44105f61b
-	//TODO: VPSADBW Y2, Y15, Y11            // c46105f6da or c505f6da
-	//TODO: VPSADBW Y11, Y15, Y11           // c44105f6db
+	VPSADBW (BX), X9, X2                    // c4e131f613 or c5b1f613
+	VPSADBW (R11), X9, X2                   // c4c131f613
+	VPSADBW X2, X9, X2                      // c4e131f6d2 or c5b1f6d2
+	VPSADBW X11, X9, X2                     // c4c131f6d3
+	VPSADBW (BX), X9, X11                   // c46131f61b or c531f61b
+	VPSADBW (R11), X9, X11                  // c44131f61b
+	VPSADBW X2, X9, X11                     // c46131f6da or c531f6da
+	VPSADBW X11, X9, X11                    // c44131f6db
+	VPSADBW (BX), Y15, Y2                   // c4e105f613 or c585f613
+	VPSADBW (R11), Y15, Y2                  // c4c105f613
+	VPSADBW Y2, Y15, Y2                     // c4e105f6d2 or c585f6d2
+	VPSADBW Y11, Y15, Y2                    // c4c105f6d3
+	VPSADBW (BX), Y15, Y11                  // c46105f61b or c505f61b
+	VPSADBW (R11), Y15, Y11                 // c44105f61b
+	VPSADBW Y2, Y15, Y11                    // c46105f6da or c505f6da
+	VPSADBW Y11, Y15, Y11                   // c44105f6db
 	VPSHUFB (BX), X9, X2            // c4e2310013
 	VPSHUFB (R11), X9, X2           // c4c2310013
 	VPSHUFB X2, X9, X2              // c4e23100d2
@@ -9528,86 +9528,86 @@
 	VPSHUFD $7, (R11), Y11          // c4417d701b07
 	VPSHUFD $7, Y2, Y11             // c4617d70da07 or c57d70da07
 	VPSHUFD $7, Y11, Y11            // c4417d70db07
-	//TODO: VPSHUFHW $7, (BX), X2           // c4e17a701307 or c5fa701307
-	//TODO: VPSHUFHW $7, (R11), X2          // c4c17a701307
-	//TODO: VPSHUFHW $7, X2, X2             // c4e17a70d207 or c5fa70d207
-	//TODO: VPSHUFHW $7, X11, X2            // c4c17a70d307
-	//TODO: VPSHUFHW $7, (BX), X11          // c4617a701b07 or c57a701b07
-	//TODO: VPSHUFHW $7, (R11), X11         // c4417a701b07
-	//TODO: VPSHUFHW $7, X2, X11            // c4617a70da07 or c57a70da07
-	//TODO: VPSHUFHW $7, X11, X11           // c4417a70db07
-	//TODO: VPSHUFHW $7, (BX), Y2           // c4e17e701307 or c5fe701307
-	//TODO: VPSHUFHW $7, (R11), Y2          // c4c17e701307
-	//TODO: VPSHUFHW $7, Y2, Y2             // c4e17e70d207 or c5fe70d207
-	//TODO: VPSHUFHW $7, Y11, Y2            // c4c17e70d307
-	//TODO: VPSHUFHW $7, (BX), Y11          // c4617e701b07 or c57e701b07
-	//TODO: VPSHUFHW $7, (R11), Y11         // c4417e701b07
-	//TODO: VPSHUFHW $7, Y2, Y11            // c4617e70da07 or c57e70da07
-	//TODO: VPSHUFHW $7, Y11, Y11           // c4417e70db07
-	//TODO: VPSHUFLW $7, (BX), X2           // c4e17b701307 or c5fb701307
-	//TODO: VPSHUFLW $7, (R11), X2          // c4c17b701307
-	//TODO: VPSHUFLW $7, X2, X2             // c4e17b70d207 or c5fb70d207
-	//TODO: VPSHUFLW $7, X11, X2            // c4c17b70d307
-	//TODO: VPSHUFLW $7, (BX), X11          // c4617b701b07 or c57b701b07
-	//TODO: VPSHUFLW $7, (R11), X11         // c4417b701b07
-	//TODO: VPSHUFLW $7, X2, X11            // c4617b70da07 or c57b70da07
-	//TODO: VPSHUFLW $7, X11, X11           // c4417b70db07
-	//TODO: VPSHUFLW $7, (BX), Y2           // c4e17f701307 or c5ff701307
-	//TODO: VPSHUFLW $7, (R11), Y2          // c4c17f701307
-	//TODO: VPSHUFLW $7, Y2, Y2             // c4e17f70d207 or c5ff70d207
-	//TODO: VPSHUFLW $7, Y11, Y2            // c4c17f70d307
-	//TODO: VPSHUFLW $7, (BX), Y11          // c4617f701b07 or c57f701b07
-	//TODO: VPSHUFLW $7, (R11), Y11         // c4417f701b07
-	//TODO: VPSHUFLW $7, Y2, Y11            // c4617f70da07 or c57f70da07
-	//TODO: VPSHUFLW $7, Y11, Y11           // c4417f70db07
-	//TODO: VPSIGNB (BX), X9, X2            // c4e2310813
-	//TODO: VPSIGNB (R11), X9, X2           // c4c2310813
-	//TODO: VPSIGNB X2, X9, X2              // c4e23108d2
-	//TODO: VPSIGNB X11, X9, X2             // c4c23108d3
-	//TODO: VPSIGNB (BX), X9, X11           // c46231081b
-	//TODO: VPSIGNB (R11), X9, X11          // c44231081b
-	//TODO: VPSIGNB X2, X9, X11             // c4623108da
-	//TODO: VPSIGNB X11, X9, X11            // c4423108db
-	//TODO: VPSIGNB (BX), Y15, Y2           // c4e2050813
-	//TODO: VPSIGNB (R11), Y15, Y2          // c4c2050813
-	//TODO: VPSIGNB Y2, Y15, Y2             // c4e20508d2
-	//TODO: VPSIGNB Y11, Y15, Y2            // c4c20508d3
-	//TODO: VPSIGNB (BX), Y15, Y11          // c46205081b
-	//TODO: VPSIGNB (R11), Y15, Y11         // c44205081b
-	//TODO: VPSIGNB Y2, Y15, Y11            // c4620508da
-	//TODO: VPSIGNB Y11, Y15, Y11           // c4420508db
-	//TODO: VPSIGND (BX), X9, X2            // c4e2310a13
-	//TODO: VPSIGND (R11), X9, X2           // c4c2310a13
-	//TODO: VPSIGND X2, X9, X2              // c4e2310ad2
-	//TODO: VPSIGND X11, X9, X2             // c4c2310ad3
-	//TODO: VPSIGND (BX), X9, X11           // c462310a1b
-	//TODO: VPSIGND (R11), X9, X11          // c442310a1b
-	//TODO: VPSIGND X2, X9, X11             // c462310ada
-	//TODO: VPSIGND X11, X9, X11            // c442310adb
-	//TODO: VPSIGND (BX), Y15, Y2           // c4e2050a13
-	//TODO: VPSIGND (R11), Y15, Y2          // c4c2050a13
-	//TODO: VPSIGND Y2, Y15, Y2             // c4e2050ad2
-	//TODO: VPSIGND Y11, Y15, Y2            // c4c2050ad3
-	//TODO: VPSIGND (BX), Y15, Y11          // c462050a1b
-	//TODO: VPSIGND (R11), Y15, Y11         // c442050a1b
-	//TODO: VPSIGND Y2, Y15, Y11            // c462050ada
-	//TODO: VPSIGND Y11, Y15, Y11           // c442050adb
-	//TODO: VPSIGNW (BX), X9, X2            // c4e2310913
-	//TODO: VPSIGNW (R11), X9, X2           // c4c2310913
-	//TODO: VPSIGNW X2, X9, X2              // c4e23109d2
-	//TODO: VPSIGNW X11, X9, X2             // c4c23109d3
-	//TODO: VPSIGNW (BX), X9, X11           // c46231091b
-	//TODO: VPSIGNW (R11), X9, X11          // c44231091b
-	//TODO: VPSIGNW X2, X9, X11             // c4623109da
-	//TODO: VPSIGNW X11, X9, X11            // c4423109db
-	//TODO: VPSIGNW (BX), Y15, Y2           // c4e2050913
-	//TODO: VPSIGNW (R11), Y15, Y2          // c4c2050913
-	//TODO: VPSIGNW Y2, Y15, Y2             // c4e20509d2
-	//TODO: VPSIGNW Y11, Y15, Y2            // c4c20509d3
-	//TODO: VPSIGNW (BX), Y15, Y11          // c46205091b
-	//TODO: VPSIGNW (R11), Y15, Y11         // c44205091b
-	//TODO: VPSIGNW Y2, Y15, Y11            // c4620509da
-	//TODO: VPSIGNW Y11, Y15, Y11           // c4420509db
+	VPSHUFHW $7, (BX), X2                   // c4e17a701307 or c5fa701307
+	VPSHUFHW $7, (R11), X2                  // c4c17a701307
+	VPSHUFHW $7, X2, X2                     // c4e17a70d207 or c5fa70d207
+	VPSHUFHW $7, X11, X2                    // c4c17a70d307
+	VPSHUFHW $7, (BX), X11                  // c4617a701b07 or c57a701b07
+	VPSHUFHW $7, (R11), X11                 // c4417a701b07
+	VPSHUFHW $7, X2, X11                    // c4617a70da07 or c57a70da07
+	VPSHUFHW $7, X11, X11                   // c4417a70db07
+	VPSHUFHW $7, (BX), Y2                   // c4e17e701307 or c5fe701307
+	VPSHUFHW $7, (R11), Y2                  // c4c17e701307
+	VPSHUFHW $7, Y2, Y2                     // c4e17e70d207 or c5fe70d207
+	VPSHUFHW $7, Y11, Y2                    // c4c17e70d307
+	VPSHUFHW $7, (BX), Y11                  // c4617e701b07 or c57e701b07
+	VPSHUFHW $7, (R11), Y11                 // c4417e701b07
+	VPSHUFHW $7, Y2, Y11                    // c4617e70da07 or c57e70da07
+	VPSHUFHW $7, Y11, Y11                   // c4417e70db07
+	VPSHUFLW $7, (BX), X2                   // c4e17b701307 or c5fb701307
+	VPSHUFLW $7, (R11), X2                  // c4c17b701307
+	VPSHUFLW $7, X2, X2                     // c4e17b70d207 or c5fb70d207
+	VPSHUFLW $7, X11, X2                    // c4c17b70d307
+	VPSHUFLW $7, (BX), X11                  // c4617b701b07 or c57b701b07
+	VPSHUFLW $7, (R11), X11                 // c4417b701b07
+	VPSHUFLW $7, X2, X11                    // c4617b70da07 or c57b70da07
+	VPSHUFLW $7, X11, X11                   // c4417b70db07
+	VPSHUFLW $7, (BX), Y2                   // c4e17f701307 or c5ff701307
+	VPSHUFLW $7, (R11), Y2                  // c4c17f701307
+	VPSHUFLW $7, Y2, Y2                     // c4e17f70d207 or c5ff70d207
+	VPSHUFLW $7, Y11, Y2                    // c4c17f70d307
+	VPSHUFLW $7, (BX), Y11                  // c4617f701b07 or c57f701b07
+	VPSHUFLW $7, (R11), Y11                 // c4417f701b07
+	VPSHUFLW $7, Y2, Y11                    // c4617f70da07 or c57f70da07
+	VPSHUFLW $7, Y11, Y11                   // c4417f70db07
+	VPSIGNB (BX), X9, X2                    // c4e2310813
+	VPSIGNB (R11), X9, X2                   // c4c2310813
+	VPSIGNB X2, X9, X2                      // c4e23108d2
+	VPSIGNB X11, X9, X2                     // c4c23108d3
+	VPSIGNB (BX), X9, X11                   // c46231081b
+	VPSIGNB (R11), X9, X11                  // c44231081b
+	VPSIGNB X2, X9, X11                     // c4623108da
+	VPSIGNB X11, X9, X11                    // c4423108db
+	VPSIGNB (BX), Y15, Y2                   // c4e2050813
+	VPSIGNB (R11), Y15, Y2                  // c4c2050813
+	VPSIGNB Y2, Y15, Y2                     // c4e20508d2
+	VPSIGNB Y11, Y15, Y2                    // c4c20508d3
+	VPSIGNB (BX), Y15, Y11                  // c46205081b
+	VPSIGNB (R11), Y15, Y11                 // c44205081b
+	VPSIGNB Y2, Y15, Y11                    // c4620508da
+	VPSIGNB Y11, Y15, Y11                   // c4420508db
+	VPSIGND (BX), X9, X2                    // c4e2310a13
+	VPSIGND (R11), X9, X2                   // c4c2310a13
+	VPSIGND X2, X9, X2                      // c4e2310ad2
+	VPSIGND X11, X9, X2                     // c4c2310ad3
+	VPSIGND (BX), X9, X11                   // c462310a1b
+	VPSIGND (R11), X9, X11                  // c442310a1b
+	VPSIGND X2, X9, X11                     // c462310ada
+	VPSIGND X11, X9, X11                    // c442310adb
+	VPSIGND (BX), Y15, Y2                   // c4e2050a13
+	VPSIGND (R11), Y15, Y2                  // c4c2050a13
+	VPSIGND Y2, Y15, Y2                     // c4e2050ad2
+	VPSIGND Y11, Y15, Y2                    // c4c2050ad3
+	VPSIGND (BX), Y15, Y11                  // c462050a1b
+	VPSIGND (R11), Y15, Y11                 // c442050a1b
+	VPSIGND Y2, Y15, Y11                    // c462050ada
+	VPSIGND Y11, Y15, Y11                   // c442050adb
+	VPSIGNW (BX), X9, X2                    // c4e2310913
+	VPSIGNW (R11), X9, X2                   // c4c2310913
+	VPSIGNW X2, X9, X2                      // c4e23109d2
+	VPSIGNW X11, X9, X2                     // c4c23109d3
+	VPSIGNW (BX), X9, X11                   // c46231091b
+	VPSIGNW (R11), X9, X11                  // c44231091b
+	VPSIGNW X2, X9, X11                     // c4623109da
+	VPSIGNW X11, X9, X11                    // c4423109db
+	VPSIGNW (BX), Y15, Y2                   // c4e2050913
+	VPSIGNW (R11), Y15, Y2                  // c4c2050913
+	VPSIGNW Y2, Y15, Y2                     // c4e20509d2
+	VPSIGNW Y11, Y15, Y2                    // c4c20509d3
+	VPSIGNW (BX), Y15, Y11                  // c46205091b
+	VPSIGNW (R11), Y15, Y11                 // c44205091b
+	VPSIGNW Y2, Y15, Y11                    // c4620509da
+	VPSIGNW Y11, Y15, Y11                   // c4420509db
 	VPSLLD (BX), X9, X2             // c4e131f213 or c5b1f213
 	VPSLLD (R11), X9, X2            // c4c131f213
 	VPSLLD X2, X9, X2               // c4e131f2d2 or c5b1f2d2
@@ -9632,114 +9632,114 @@
 	VPSLLQ X11, X9, X11             // c44131f3db
 	VPSLLQ $7, X2, X9               // c4e13173f207 or c5b173f207
 	VPSLLQ $7, X11, X9              // c4c13173f307
-	//TODO: VPSLLVD (BX), X9, X2            // c4e2314713
-	//TODO: VPSLLVD (R11), X9, X2           // c4c2314713
-	//TODO: VPSLLVD X2, X9, X2              // c4e23147d2
-	//TODO: VPSLLVD X11, X9, X2             // c4c23147d3
-	//TODO: VPSLLVD (BX), X9, X11           // c46231471b
-	//TODO: VPSLLVD (R11), X9, X11          // c44231471b
-	//TODO: VPSLLVD X2, X9, X11             // c4623147da
-	//TODO: VPSLLVD X11, X9, X11            // c4423147db
-	//TODO: VPSLLVD (BX), Y15, Y2           // c4e2054713
-	//TODO: VPSLLVD (R11), Y15, Y2          // c4c2054713
-	//TODO: VPSLLVD Y2, Y15, Y2             // c4e20547d2
-	//TODO: VPSLLVD Y11, Y15, Y2            // c4c20547d3
-	//TODO: VPSLLVD (BX), Y15, Y11          // c46205471b
-	//TODO: VPSLLVD (R11), Y15, Y11         // c44205471b
-	//TODO: VPSLLVD Y2, Y15, Y11            // c4620547da
-	//TODO: VPSLLVD Y11, Y15, Y11           // c4420547db
-	//TODO: VPSLLVQ (BX), X9, X2            // c4e2b14713
-	//TODO: VPSLLVQ (R11), X9, X2           // c4c2b14713
-	//TODO: VPSLLVQ X2, X9, X2              // c4e2b147d2
-	//TODO: VPSLLVQ X11, X9, X2             // c4c2b147d3
-	//TODO: VPSLLVQ (BX), X9, X11           // c462b1471b
-	//TODO: VPSLLVQ (R11), X9, X11          // c442b1471b
-	//TODO: VPSLLVQ X2, X9, X11             // c462b147da
-	//TODO: VPSLLVQ X11, X9, X11            // c442b147db
-	//TODO: VPSLLVQ (BX), Y15, Y2           // c4e2854713
-	//TODO: VPSLLVQ (R11), Y15, Y2          // c4c2854713
-	//TODO: VPSLLVQ Y2, Y15, Y2             // c4e28547d2
-	//TODO: VPSLLVQ Y11, Y15, Y2            // c4c28547d3
-	//TODO: VPSLLVQ (BX), Y15, Y11          // c46285471b
-	//TODO: VPSLLVQ (R11), Y15, Y11         // c44285471b
-	//TODO: VPSLLVQ Y2, Y15, Y11            // c4628547da
-	//TODO: VPSLLVQ Y11, Y15, Y11           // c4428547db
-	//TODO: VPSLLW (BX), X9, X2             // c4e131f113 or c5b1f113
-	//TODO: VPSLLW (R11), X9, X2            // c4c131f113
-	//TODO: VPSLLW X2, X9, X2               // c4e131f1d2 or c5b1f1d2
-	//TODO: VPSLLW X11, X9, X2              // c4c131f1d3
-	//TODO: VPSLLW (BX), X9, X11            // c46131f11b or c531f11b
-	//TODO: VPSLLW (R11), X9, X11           // c44131f11b
-	//TODO: VPSLLW X2, X9, X11              // c46131f1da or c531f1da
-	//TODO: VPSLLW X11, X9, X11             // c44131f1db
-	//TODO: VPSLLW $7, X2, X9               // c4e13171f207 or c5b171f207
-	//TODO: VPSLLW $7, X11, X9              // c4c13171f307
-	//TODO: VPSLLW (BX), Y15, Y2            // c4e105f113 or c585f113
-	//TODO: VPSLLW (R11), Y15, Y2           // c4c105f113
-	//TODO: VPSLLW X2, Y15, Y2              // c4e105f1d2 or c585f1d2
-	//TODO: VPSLLW X11, Y15, Y2             // c4c105f1d3
-	//TODO: VPSLLW (BX), Y15, Y11           // c46105f11b or c505f11b
-	//TODO: VPSLLW (R11), Y15, Y11          // c44105f11b
-	//TODO: VPSLLW X2, Y15, Y11             // c46105f1da or c505f1da
-	//TODO: VPSLLW X11, Y15, Y11            // c44105f1db
-	//TODO: VPSLLW $7, Y2, Y15              // c4e10571f207 or c58571f207
-	//TODO: VPSLLW $7, Y11, Y15             // c4c10571f307
-	//TODO: VPSRAD (BX), X9, X2             // c4e131e213 or c5b1e213
-	//TODO: VPSRAD (R11), X9, X2            // c4c131e213
-	//TODO: VPSRAD X2, X9, X2               // c4e131e2d2 or c5b1e2d2
-	//TODO: VPSRAD X11, X9, X2              // c4c131e2d3
-	//TODO: VPSRAD (BX), X9, X11            // c46131e21b or c531e21b
-	//TODO: VPSRAD (R11), X9, X11           // c44131e21b
-	//TODO: VPSRAD X2, X9, X11              // c46131e2da or c531e2da
-	//TODO: VPSRAD X11, X9, X11             // c44131e2db
-	//TODO: VPSRAD $7, X2, X9               // c4e13172e207 or c5b172e207
-	//TODO: VPSRAD $7, X11, X9              // c4c13172e307
-	//TODO: VPSRAD (BX), Y15, Y2            // c4e105e213 or c585e213
-	//TODO: VPSRAD (R11), Y15, Y2           // c4c105e213
-	//TODO: VPSRAD X2, Y15, Y2              // c4e105e2d2 or c585e2d2
-	//TODO: VPSRAD X11, Y15, Y2             // c4c105e2d3
-	//TODO: VPSRAD (BX), Y15, Y11           // c46105e21b or c505e21b
-	//TODO: VPSRAD (R11), Y15, Y11          // c44105e21b
-	//TODO: VPSRAD X2, Y15, Y11             // c46105e2da or c505e2da
-	//TODO: VPSRAD X11, Y15, Y11            // c44105e2db
-	//TODO: VPSRAD $7, Y2, Y15              // c4e10572e207 or c58572e207
-	//TODO: VPSRAD $7, Y11, Y15             // c4c10572e307
-	//TODO: VPSRAVD (BX), X9, X2            // c4e2314613
-	//TODO: VPSRAVD (R11), X9, X2           // c4c2314613
-	//TODO: VPSRAVD X2, X9, X2              // c4e23146d2
-	//TODO: VPSRAVD X11, X9, X2             // c4c23146d3
-	//TODO: VPSRAVD (BX), X9, X11           // c46231461b
-	//TODO: VPSRAVD (R11), X9, X11          // c44231461b
-	//TODO: VPSRAVD X2, X9, X11             // c4623146da
-	//TODO: VPSRAVD X11, X9, X11            // c4423146db
-	//TODO: VPSRAVD (BX), Y15, Y2           // c4e2054613
-	//TODO: VPSRAVD (R11), Y15, Y2          // c4c2054613
-	//TODO: VPSRAVD Y2, Y15, Y2             // c4e20546d2
-	//TODO: VPSRAVD Y11, Y15, Y2            // c4c20546d3
-	//TODO: VPSRAVD (BX), Y15, Y11          // c46205461b
-	//TODO: VPSRAVD (R11), Y15, Y11         // c44205461b
-	//TODO: VPSRAVD Y2, Y15, Y11            // c4620546da
-	//TODO: VPSRAVD Y11, Y15, Y11           // c4420546db
-	//TODO: VPSRAW (BX), X9, X2             // c4e131e113 or c5b1e113
-	//TODO: VPSRAW (R11), X9, X2            // c4c131e113
-	//TODO: VPSRAW X2, X9, X2               // c4e131e1d2 or c5b1e1d2
-	//TODO: VPSRAW X11, X9, X2              // c4c131e1d3
-	//TODO: VPSRAW (BX), X9, X11            // c46131e11b or c531e11b
-	//TODO: VPSRAW (R11), X9, X11           // c44131e11b
-	//TODO: VPSRAW X2, X9, X11              // c46131e1da or c531e1da
-	//TODO: VPSRAW X11, X9, X11             // c44131e1db
-	//TODO: VPSRAW $7, X2, X9               // c4e13171e207 or c5b171e207
-	//TODO: VPSRAW $7, X11, X9              // c4c13171e307
-	//TODO: VPSRAW (BX), Y15, Y2            // c4e105e113 or c585e113
-	//TODO: VPSRAW (R11), Y15, Y2           // c4c105e113
-	//TODO: VPSRAW X2, Y15, Y2              // c4e105e1d2 or c585e1d2
-	//TODO: VPSRAW X11, Y15, Y2             // c4c105e1d3
-	//TODO: VPSRAW (BX), Y15, Y11           // c46105e11b or c505e11b
-	//TODO: VPSRAW (R11), Y15, Y11          // c44105e11b
-	//TODO: VPSRAW X2, Y15, Y11             // c46105e1da or c505e1da
-	//TODO: VPSRAW X11, Y15, Y11            // c44105e1db
-	//TODO: VPSRAW $7, Y2, Y15              // c4e10571e207 or c58571e207
-	//TODO: VPSRAW $7, Y11, Y15             // c4c10571e307
+	VPSLLVD (BX), X9, X2                    // c4e2314713
+	VPSLLVD (R11), X9, X2                   // c4c2314713
+	VPSLLVD X2, X9, X2                      // c4e23147d2
+	VPSLLVD X11, X9, X2                     // c4c23147d3
+	VPSLLVD (BX), X9, X11                   // c46231471b
+	VPSLLVD (R11), X9, X11                  // c44231471b
+	VPSLLVD X2, X9, X11                     // c4623147da
+	VPSLLVD X11, X9, X11                    // c4423147db
+	VPSLLVD (BX), Y15, Y2                   // c4e2054713
+	VPSLLVD (R11), Y15, Y2                  // c4c2054713
+	VPSLLVD Y2, Y15, Y2                     // c4e20547d2
+	VPSLLVD Y11, Y15, Y2                    // c4c20547d3
+	VPSLLVD (BX), Y15, Y11                  // c46205471b
+	VPSLLVD (R11), Y15, Y11                 // c44205471b
+	VPSLLVD Y2, Y15, Y11                    // c4620547da
+	VPSLLVD Y11, Y15, Y11                   // c4420547db
+	VPSLLVQ (BX), X9, X2                    // c4e2b14713
+	VPSLLVQ (R11), X9, X2                   // c4c2b14713
+	VPSLLVQ X2, X9, X2                      // c4e2b147d2
+	VPSLLVQ X11, X9, X2                     // c4c2b147d3
+	VPSLLVQ (BX), X9, X11                   // c462b1471b
+	VPSLLVQ (R11), X9, X11                  // c442b1471b
+	VPSLLVQ X2, X9, X11                     // c462b147da
+	VPSLLVQ X11, X9, X11                    // c442b147db
+	VPSLLVQ (BX), Y15, Y2                   // c4e2854713
+	VPSLLVQ (R11), Y15, Y2                  // c4c2854713
+	VPSLLVQ Y2, Y15, Y2                     // c4e28547d2
+	VPSLLVQ Y11, Y15, Y2                    // c4c28547d3
+	VPSLLVQ (BX), Y15, Y11                  // c46285471b
+	VPSLLVQ (R11), Y15, Y11                 // c44285471b
+	VPSLLVQ Y2, Y15, Y11                    // c4628547da
+	VPSLLVQ Y11, Y15, Y11                   // c4428547db
+	VPSLLW (BX), X9, X2                     // c4e131f113 or c5b1f113
+	VPSLLW (R11), X9, X2                    // c4c131f113
+	VPSLLW X2, X9, X2                       // c4e131f1d2 or c5b1f1d2
+	VPSLLW X11, X9, X2                      // c4c131f1d3
+	VPSLLW (BX), X9, X11                    // c46131f11b or c531f11b
+	VPSLLW (R11), X9, X11                   // c44131f11b
+	VPSLLW X2, X9, X11                      // c46131f1da or c531f1da
+	VPSLLW X11, X9, X11                     // c44131f1db
+	VPSLLW $7, X2, X9                       // c4e13171f207 or c5b171f207
+	VPSLLW $7, X11, X9                      // c4c13171f307
+	VPSLLW (BX), Y15, Y2                    // c4e105f113 or c585f113
+	VPSLLW (R11), Y15, Y2                   // c4c105f113
+	VPSLLW X2, Y15, Y2                      // c4e105f1d2 or c585f1d2
+	VPSLLW X11, Y15, Y2                     // c4c105f1d3
+	VPSLLW (BX), Y15, Y11                   // c46105f11b or c505f11b
+	VPSLLW (R11), Y15, Y11                  // c44105f11b
+	VPSLLW X2, Y15, Y11                     // c46105f1da or c505f1da
+	VPSLLW X11, Y15, Y11                    // c44105f1db
+	VPSLLW $7, Y2, Y15                      // c4e10571f207 or c58571f207
+	VPSLLW $7, Y11, Y15                     // c4c10571f307
+	VPSRAD (BX), X9, X2                     // c4e131e213 or c5b1e213
+	VPSRAD (R11), X9, X2                    // c4c131e213
+	VPSRAD X2, X9, X2                       // c4e131e2d2 or c5b1e2d2
+	VPSRAD X11, X9, X2                      // c4c131e2d3
+	VPSRAD (BX), X9, X11                    // c46131e21b or c531e21b
+	VPSRAD (R11), X9, X11                   // c44131e21b
+	VPSRAD X2, X9, X11                      // c46131e2da or c531e2da
+	VPSRAD X11, X9, X11                     // c44131e2db
+	VPSRAD $7, X2, X9                       // c4e13172e207 or c5b172e207
+	VPSRAD $7, X11, X9                      // c4c13172e307
+	VPSRAD (BX), Y15, Y2                    // c4e105e213 or c585e213
+	VPSRAD (R11), Y15, Y2                   // c4c105e213
+	VPSRAD X2, Y15, Y2                      // c4e105e2d2 or c585e2d2
+	VPSRAD X11, Y15, Y2                     // c4c105e2d3
+	VPSRAD (BX), Y15, Y11                   // c46105e21b or c505e21b
+	VPSRAD (R11), Y15, Y11                  // c44105e21b
+	VPSRAD X2, Y15, Y11                     // c46105e2da or c505e2da
+	VPSRAD X11, Y15, Y11                    // c44105e2db
+	VPSRAD $7, Y2, Y15                      // c4e10572e207 or c58572e207
+	VPSRAD $7, Y11, Y15                     // c4c10572e307
+	VPSRAVD (BX), X9, X2                    // c4e2314613
+	VPSRAVD (R11), X9, X2                   // c4c2314613
+	VPSRAVD X2, X9, X2                      // c4e23146d2
+	VPSRAVD X11, X9, X2                     // c4c23146d3
+	VPSRAVD (BX), X9, X11                   // c46231461b
+	VPSRAVD (R11), X9, X11                  // c44231461b
+	VPSRAVD X2, X9, X11                     // c4623146da
+	VPSRAVD X11, X9, X11                    // c4423146db
+	VPSRAVD (BX), Y15, Y2                   // c4e2054613
+	VPSRAVD (R11), Y15, Y2                  // c4c2054613
+	VPSRAVD Y2, Y15, Y2                     // c4e20546d2
+	VPSRAVD Y11, Y15, Y2                    // c4c20546d3
+	VPSRAVD (BX), Y15, Y11                  // c46205461b
+	VPSRAVD (R11), Y15, Y11                 // c44205461b
+	VPSRAVD Y2, Y15, Y11                    // c4620546da
+	VPSRAVD Y11, Y15, Y11                   // c4420546db
+	VPSRAW (BX), X9, X2                     // c4e131e113 or c5b1e113
+	VPSRAW (R11), X9, X2                    // c4c131e113
+	VPSRAW X2, X9, X2                       // c4e131e1d2 or c5b1e1d2
+	VPSRAW X11, X9, X2                      // c4c131e1d3
+	VPSRAW (BX), X9, X11                    // c46131e11b or c531e11b
+	VPSRAW (R11), X9, X11                   // c44131e11b
+	VPSRAW X2, X9, X11                      // c46131e1da or c531e1da
+	VPSRAW X11, X9, X11                     // c44131e1db
+	VPSRAW $7, X2, X9                       // c4e13171e207 or c5b171e207
+	VPSRAW $7, X11, X9                      // c4c13171e307
+	VPSRAW (BX), Y15, Y2                    // c4e105e113 or c585e113
+	VPSRAW (R11), Y15, Y2                   // c4c105e113
+	VPSRAW X2, Y15, Y2                      // c4e105e1d2 or c585e1d2
+	VPSRAW X11, Y15, Y2                     // c4c105e1d3
+	VPSRAW (BX), Y15, Y11                   // c46105e11b or c505e11b
+	VPSRAW (R11), Y15, Y11                  // c44105e11b
+	VPSRAW X2, Y15, Y11                     // c46105e1da or c505e1da
+	VPSRAW X11, Y15, Y11                    // c44105e1db
+	VPSRAW $7, Y2, Y15                      // c4e10571e207 or c58571e207
+	VPSRAW $7, Y11, Y15                     // c4c10571e307
 	VPSRLD (BX), X9, X2             // c4e131d213 or c5b1d213
 	VPSRLD (R11), X9, X2            // c4c131d213
 	VPSRLD X2, X9, X2               // c4e131d2d2 or c5b1d2d2
@@ -9764,186 +9764,186 @@
 	VPSRLQ X11, X9, X11             // c44131d3db
 	VPSRLQ $7, X2, X9               // c4e13173d207 or c5b173d207
 	VPSRLQ $7, X11, X9              // c4c13173d307
-	//TODO: VPSRLVD (BX), X9, X2            // c4e2314513
-	//TODO: VPSRLVD (R11), X9, X2           // c4c2314513
-	//TODO: VPSRLVD X2, X9, X2              // c4e23145d2
-	//TODO: VPSRLVD X11, X9, X2             // c4c23145d3
-	//TODO: VPSRLVD (BX), X9, X11           // c46231451b
-	//TODO: VPSRLVD (R11), X9, X11          // c44231451b
-	//TODO: VPSRLVD X2, X9, X11             // c4623145da
-	//TODO: VPSRLVD X11, X9, X11            // c4423145db
-	//TODO: VPSRLVD (BX), Y15, Y2           // c4e2054513
-	//TODO: VPSRLVD (R11), Y15, Y2          // c4c2054513
-	//TODO: VPSRLVD Y2, Y15, Y2             // c4e20545d2
-	//TODO: VPSRLVD Y11, Y15, Y2            // c4c20545d3
-	//TODO: VPSRLVD (BX), Y15, Y11          // c46205451b
-	//TODO: VPSRLVD (R11), Y15, Y11         // c44205451b
-	//TODO: VPSRLVD Y2, Y15, Y11            // c4620545da
-	//TODO: VPSRLVD Y11, Y15, Y11           // c4420545db
-	//TODO: VPSRLVQ (BX), X9, X2            // c4e2b14513
-	//TODO: VPSRLVQ (R11), X9, X2           // c4c2b14513
-	//TODO: VPSRLVQ X2, X9, X2              // c4e2b145d2
-	//TODO: VPSRLVQ X11, X9, X2             // c4c2b145d3
-	//TODO: VPSRLVQ (BX), X9, X11           // c462b1451b
-	//TODO: VPSRLVQ (R11), X9, X11          // c442b1451b
-	//TODO: VPSRLVQ X2, X9, X11             // c462b145da
-	//TODO: VPSRLVQ X11, X9, X11            // c442b145db
-	//TODO: VPSRLVQ (BX), Y15, Y2           // c4e2854513
-	//TODO: VPSRLVQ (R11), Y15, Y2          // c4c2854513
-	//TODO: VPSRLVQ Y2, Y15, Y2             // c4e28545d2
-	//TODO: VPSRLVQ Y11, Y15, Y2            // c4c28545d3
-	//TODO: VPSRLVQ (BX), Y15, Y11          // c46285451b
-	//TODO: VPSRLVQ (R11), Y15, Y11         // c44285451b
-	//TODO: VPSRLVQ Y2, Y15, Y11            // c4628545da
-	//TODO: VPSRLVQ Y11, Y15, Y11           // c4428545db
-	//TODO: VPSRLW (BX), X9, X2             // c4e131d113 or c5b1d113
-	//TODO: VPSRLW (R11), X9, X2            // c4c131d113
-	//TODO: VPSRLW X2, X9, X2               // c4e131d1d2 or c5b1d1d2
-	//TODO: VPSRLW X11, X9, X2              // c4c131d1d3
-	//TODO: VPSRLW (BX), X9, X11            // c46131d11b or c531d11b
-	//TODO: VPSRLW (R11), X9, X11           // c44131d11b
-	//TODO: VPSRLW X2, X9, X11              // c46131d1da or c531d1da
-	//TODO: VPSRLW X11, X9, X11             // c44131d1db
-	//TODO: VPSRLW $7, X2, X9               // c4e13171d207 or c5b171d207
-	//TODO: VPSRLW $7, X11, X9              // c4c13171d307
-	//TODO: VPSRLW (BX), Y15, Y2            // c4e105d113 or c585d113
-	//TODO: VPSRLW (R11), Y15, Y2           // c4c105d113
-	//TODO: VPSRLW X2, Y15, Y2              // c4e105d1d2 or c585d1d2
-	//TODO: VPSRLW X11, Y15, Y2             // c4c105d1d3
-	//TODO: VPSRLW (BX), Y15, Y11           // c46105d11b or c505d11b
-	//TODO: VPSRLW (R11), Y15, Y11          // c44105d11b
-	//TODO: VPSRLW X2, Y15, Y11             // c46105d1da or c505d1da
-	//TODO: VPSRLW X11, Y15, Y11            // c44105d1db
-	//TODO: VPSRLW $7, Y2, Y15              // c4e10571d207 or c58571d207
-	//TODO: VPSRLW $7, Y11, Y15             // c4c10571d307
-	//TODO: VPSUBB (BX), X9, X2             // c4e131f813 or c5b1f813
-	//TODO: VPSUBB (R11), X9, X2            // c4c131f813
-	//TODO: VPSUBB X2, X9, X2               // c4e131f8d2 or c5b1f8d2
-	//TODO: VPSUBB X11, X9, X2              // c4c131f8d3
-	//TODO: VPSUBB (BX), X9, X11            // c46131f81b or c531f81b
-	//TODO: VPSUBB (R11), X9, X11           // c44131f81b
-	//TODO: VPSUBB X2, X9, X11              // c46131f8da or c531f8da
-	//TODO: VPSUBB X11, X9, X11             // c44131f8db
-	//TODO: VPSUBB (BX), Y15, Y2            // c4e105f813 or c585f813
-	//TODO: VPSUBB (R11), Y15, Y2           // c4c105f813
-	//TODO: VPSUBB Y2, Y15, Y2              // c4e105f8d2 or c585f8d2
-	//TODO: VPSUBB Y11, Y15, Y2             // c4c105f8d3
-	//TODO: VPSUBB (BX), Y15, Y11           // c46105f81b or c505f81b
-	//TODO: VPSUBB (R11), Y15, Y11          // c44105f81b
-	//TODO: VPSUBB Y2, Y15, Y11             // c46105f8da or c505f8da
-	//TODO: VPSUBB Y11, Y15, Y11            // c44105f8db
-	//TODO: VPSUBD (BX), X9, X2             // c4e131fa13 or c5b1fa13
-	//TODO: VPSUBD (R11), X9, X2            // c4c131fa13
-	//TODO: VPSUBD X2, X9, X2               // c4e131fad2 or c5b1fad2
-	//TODO: VPSUBD X11, X9, X2              // c4c131fad3
-	//TODO: VPSUBD (BX), X9, X11            // c46131fa1b or c531fa1b
-	//TODO: VPSUBD (R11), X9, X11           // c44131fa1b
-	//TODO: VPSUBD X2, X9, X11              // c46131fada or c531fada
-	//TODO: VPSUBD X11, X9, X11             // c44131fadb
-	//TODO: VPSUBD (BX), Y15, Y2            // c4e105fa13 or c585fa13
-	//TODO: VPSUBD (R11), Y15, Y2           // c4c105fa13
-	//TODO: VPSUBD Y2, Y15, Y2              // c4e105fad2 or c585fad2
-	//TODO: VPSUBD Y11, Y15, Y2             // c4c105fad3
-	//TODO: VPSUBD (BX), Y15, Y11           // c46105fa1b or c505fa1b
-	//TODO: VPSUBD (R11), Y15, Y11          // c44105fa1b
-	//TODO: VPSUBD Y2, Y15, Y11             // c46105fada or c505fada
-	//TODO: VPSUBD Y11, Y15, Y11            // c44105fadb
-	//TODO: VPSUBQ (BX), X9, X2             // c4e131fb13 or c5b1fb13
-	//TODO: VPSUBQ (R11), X9, X2            // c4c131fb13
-	//TODO: VPSUBQ X2, X9, X2               // c4e131fbd2 or c5b1fbd2
-	//TODO: VPSUBQ X11, X9, X2              // c4c131fbd3
-	//TODO: VPSUBQ (BX), X9, X11            // c46131fb1b or c531fb1b
-	//TODO: VPSUBQ (R11), X9, X11           // c44131fb1b
-	//TODO: VPSUBQ X2, X9, X11              // c46131fbda or c531fbda
-	//TODO: VPSUBQ X11, X9, X11             // c44131fbdb
-	//TODO: VPSUBQ (BX), Y15, Y2            // c4e105fb13 or c585fb13
-	//TODO: VPSUBQ (R11), Y15, Y2           // c4c105fb13
-	//TODO: VPSUBQ Y2, Y15, Y2              // c4e105fbd2 or c585fbd2
-	//TODO: VPSUBQ Y11, Y15, Y2             // c4c105fbd3
-	//TODO: VPSUBQ (BX), Y15, Y11           // c46105fb1b or c505fb1b
-	//TODO: VPSUBQ (R11), Y15, Y11          // c44105fb1b
-	//TODO: VPSUBQ Y2, Y15, Y11             // c46105fbda or c505fbda
-	//TODO: VPSUBQ Y11, Y15, Y11            // c44105fbdb
-	//TODO: VPSUBSB (BX), X9, X2            // c4e131e813 or c5b1e813
-	//TODO: VPSUBSB (R11), X9, X2           // c4c131e813
-	//TODO: VPSUBSB X2, X9, X2              // c4e131e8d2 or c5b1e8d2
-	//TODO: VPSUBSB X11, X9, X2             // c4c131e8d3
-	//TODO: VPSUBSB (BX), X9, X11           // c46131e81b or c531e81b
-	//TODO: VPSUBSB (R11), X9, X11          // c44131e81b
-	//TODO: VPSUBSB X2, X9, X11             // c46131e8da or c531e8da
-	//TODO: VPSUBSB X11, X9, X11            // c44131e8db
-	//TODO: VPSUBSB (BX), Y15, Y2           // c4e105e813 or c585e813
-	//TODO: VPSUBSB (R11), Y15, Y2          // c4c105e813
-	//TODO: VPSUBSB Y2, Y15, Y2             // c4e105e8d2 or c585e8d2
-	//TODO: VPSUBSB Y11, Y15, Y2            // c4c105e8d3
-	//TODO: VPSUBSB (BX), Y15, Y11          // c46105e81b or c505e81b
-	//TODO: VPSUBSB (R11), Y15, Y11         // c44105e81b
-	//TODO: VPSUBSB Y2, Y15, Y11            // c46105e8da or c505e8da
-	//TODO: VPSUBSB Y11, Y15, Y11           // c44105e8db
-	//TODO: VPSUBSW (BX), X9, X2            // c4e131e913 or c5b1e913
-	//TODO: VPSUBSW (R11), X9, X2           // c4c131e913
-	//TODO: VPSUBSW X2, X9, X2              // c4e131e9d2 or c5b1e9d2
-	//TODO: VPSUBSW X11, X9, X2             // c4c131e9d3
-	//TODO: VPSUBSW (BX), X9, X11           // c46131e91b or c531e91b
-	//TODO: VPSUBSW (R11), X9, X11          // c44131e91b
-	//TODO: VPSUBSW X2, X9, X11             // c46131e9da or c531e9da
-	//TODO: VPSUBSW X11, X9, X11            // c44131e9db
-	//TODO: VPSUBSW (BX), Y15, Y2           // c4e105e913 or c585e913
-	//TODO: VPSUBSW (R11), Y15, Y2          // c4c105e913
-	//TODO: VPSUBSW Y2, Y15, Y2             // c4e105e9d2 or c585e9d2
-	//TODO: VPSUBSW Y11, Y15, Y2            // c4c105e9d3
-	//TODO: VPSUBSW (BX), Y15, Y11          // c46105e91b or c505e91b
-	//TODO: VPSUBSW (R11), Y15, Y11         // c44105e91b
-	//TODO: VPSUBSW Y2, Y15, Y11            // c46105e9da or c505e9da
-	//TODO: VPSUBSW Y11, Y15, Y11           // c44105e9db
-	//TODO: VPSUBUSB (BX), X9, X2           // c4e131d813 or c5b1d813
-	//TODO: VPSUBUSB (R11), X9, X2          // c4c131d813
-	//TODO: VPSUBUSB X2, X9, X2             // c4e131d8d2 or c5b1d8d2
-	//TODO: VPSUBUSB X11, X9, X2            // c4c131d8d3
-	//TODO: VPSUBUSB (BX), X9, X11          // c46131d81b or c531d81b
-	//TODO: VPSUBUSB (R11), X9, X11         // c44131d81b
-	//TODO: VPSUBUSB X2, X9, X11            // c46131d8da or c531d8da
-	//TODO: VPSUBUSB X11, X9, X11           // c44131d8db
-	//TODO: VPSUBUSB (BX), Y15, Y2          // c4e105d813 or c585d813
-	//TODO: VPSUBUSB (R11), Y15, Y2         // c4c105d813
-	//TODO: VPSUBUSB Y2, Y15, Y2            // c4e105d8d2 or c585d8d2
-	//TODO: VPSUBUSB Y11, Y15, Y2           // c4c105d8d3
-	//TODO: VPSUBUSB (BX), Y15, Y11         // c46105d81b or c505d81b
-	//TODO: VPSUBUSB (R11), Y15, Y11        // c44105d81b
-	//TODO: VPSUBUSB Y2, Y15, Y11           // c46105d8da or c505d8da
-	//TODO: VPSUBUSB Y11, Y15, Y11          // c44105d8db
-	//TODO: VPSUBUSW (BX), X9, X2           // c4e131d913 or c5b1d913
-	//TODO: VPSUBUSW (R11), X9, X2          // c4c131d913
-	//TODO: VPSUBUSW X2, X9, X2             // c4e131d9d2 or c5b1d9d2
-	//TODO: VPSUBUSW X11, X9, X2            // c4c131d9d3
-	//TODO: VPSUBUSW (BX), X9, X11          // c46131d91b or c531d91b
-	//TODO: VPSUBUSW (R11), X9, X11         // c44131d91b
-	//TODO: VPSUBUSW X2, X9, X11            // c46131d9da or c531d9da
-	//TODO: VPSUBUSW X11, X9, X11           // c44131d9db
-	//TODO: VPSUBUSW (BX), Y15, Y2          // c4e105d913 or c585d913
-	//TODO: VPSUBUSW (R11), Y15, Y2         // c4c105d913
-	//TODO: VPSUBUSW Y2, Y15, Y2            // c4e105d9d2 or c585d9d2
-	//TODO: VPSUBUSW Y11, Y15, Y2           // c4c105d9d3
-	//TODO: VPSUBUSW (BX), Y15, Y11         // c46105d91b or c505d91b
-	//TODO: VPSUBUSW (R11), Y15, Y11        // c44105d91b
-	//TODO: VPSUBUSW Y2, Y15, Y11           // c46105d9da or c505d9da
-	//TODO: VPSUBUSW Y11, Y15, Y11          // c44105d9db
-	//TODO: VPSUBW (BX), X9, X2             // c4e131f913 or c5b1f913
-	//TODO: VPSUBW (R11), X9, X2            // c4c131f913
-	//TODO: VPSUBW X2, X9, X2               // c4e131f9d2 or c5b1f9d2
-	//TODO: VPSUBW X11, X9, X2              // c4c131f9d3
-	//TODO: VPSUBW (BX), X9, X11            // c46131f91b or c531f91b
-	//TODO: VPSUBW (R11), X9, X11           // c44131f91b
-	//TODO: VPSUBW X2, X9, X11              // c46131f9da or c531f9da
-	//TODO: VPSUBW X11, X9, X11             // c44131f9db
-	//TODO: VPSUBW (BX), Y15, Y2            // c4e105f913 or c585f913
-	//TODO: VPSUBW (R11), Y15, Y2           // c4c105f913
-	//TODO: VPSUBW Y2, Y15, Y2              // c4e105f9d2 or c585f9d2
-	//TODO: VPSUBW Y11, Y15, Y2             // c4c105f9d3
-	//TODO: VPSUBW (BX), Y15, Y11           // c46105f91b or c505f91b
-	//TODO: VPSUBW (R11), Y15, Y11          // c44105f91b
-	//TODO: VPSUBW Y2, Y15, Y11             // c46105f9da or c505f9da
-	//TODO: VPSUBW Y11, Y15, Y11            // c44105f9db
+	VPSRLVD (BX), X9, X2                    // c4e2314513
+	VPSRLVD (R11), X9, X2                   // c4c2314513
+	VPSRLVD X2, X9, X2                      // c4e23145d2
+	VPSRLVD X11, X9, X2                     // c4c23145d3
+	VPSRLVD (BX), X9, X11                   // c46231451b
+	VPSRLVD (R11), X9, X11                  // c44231451b
+	VPSRLVD X2, X9, X11                     // c4623145da
+	VPSRLVD X11, X9, X11                    // c4423145db
+	VPSRLVD (BX), Y15, Y2                   // c4e2054513
+	VPSRLVD (R11), Y15, Y2                  // c4c2054513
+	VPSRLVD Y2, Y15, Y2                     // c4e20545d2
+	VPSRLVD Y11, Y15, Y2                    // c4c20545d3
+	VPSRLVD (BX), Y15, Y11                  // c46205451b
+	VPSRLVD (R11), Y15, Y11                 // c44205451b
+	VPSRLVD Y2, Y15, Y11                    // c4620545da
+	VPSRLVD Y11, Y15, Y11                   // c4420545db
+	VPSRLVQ (BX), X9, X2                    // c4e2b14513
+	VPSRLVQ (R11), X9, X2                   // c4c2b14513
+	VPSRLVQ X2, X9, X2                      // c4e2b145d2
+	VPSRLVQ X11, X9, X2                     // c4c2b145d3
+	VPSRLVQ (BX), X9, X11                   // c462b1451b
+	VPSRLVQ (R11), X9, X11                  // c442b1451b
+	VPSRLVQ X2, X9, X11                     // c462b145da
+	VPSRLVQ X11, X9, X11                    // c442b145db
+	VPSRLVQ (BX), Y15, Y2                   // c4e2854513
+	VPSRLVQ (R11), Y15, Y2                  // c4c2854513
+	VPSRLVQ Y2, Y15, Y2                     // c4e28545d2
+	VPSRLVQ Y11, Y15, Y2                    // c4c28545d3
+	VPSRLVQ (BX), Y15, Y11                  // c46285451b
+	VPSRLVQ (R11), Y15, Y11                 // c44285451b
+	VPSRLVQ Y2, Y15, Y11                    // c4628545da
+	VPSRLVQ Y11, Y15, Y11                   // c4428545db
+	VPSRLW (BX), X9, X2                     // c4e131d113 or c5b1d113
+	VPSRLW (R11), X9, X2                    // c4c131d113
+	VPSRLW X2, X9, X2                       // c4e131d1d2 or c5b1d1d2
+	VPSRLW X11, X9, X2                      // c4c131d1d3
+	VPSRLW (BX), X9, X11                    // c46131d11b or c531d11b
+	VPSRLW (R11), X9, X11                   // c44131d11b
+	VPSRLW X2, X9, X11                      // c46131d1da or c531d1da
+	VPSRLW X11, X9, X11                     // c44131d1db
+	VPSRLW $7, X2, X9                       // c4e13171d207 or c5b171d207
+	VPSRLW $7, X11, X9                      // c4c13171d307
+	VPSRLW (BX), Y15, Y2                    // c4e105d113 or c585d113
+	VPSRLW (R11), Y15, Y2                   // c4c105d113
+	VPSRLW X2, Y15, Y2                      // c4e105d1d2 or c585d1d2
+	VPSRLW X11, Y15, Y2                     // c4c105d1d3
+	VPSRLW (BX), Y15, Y11                   // c46105d11b or c505d11b
+	VPSRLW (R11), Y15, Y11                  // c44105d11b
+	VPSRLW X2, Y15, Y11                     // c46105d1da or c505d1da
+	VPSRLW X11, Y15, Y11                    // c44105d1db
+	VPSRLW $7, Y2, Y15                      // c4e10571d207 or c58571d207
+	VPSRLW $7, Y11, Y15                     // c4c10571d307
+	VPSUBB (BX), X9, X2                     // c4e131f813 or c5b1f813
+	VPSUBB (R11), X9, X2                    // c4c131f813
+	VPSUBB X2, X9, X2                       // c4e131f8d2 or c5b1f8d2
+	VPSUBB X11, X9, X2                      // c4c131f8d3
+	VPSUBB (BX), X9, X11                    // c46131f81b or c531f81b
+	VPSUBB (R11), X9, X11                   // c44131f81b
+	VPSUBB X2, X9, X11                      // c46131f8da or c531f8da
+	VPSUBB X11, X9, X11                     // c44131f8db
+	VPSUBB (BX), Y15, Y2                    // c4e105f813 or c585f813
+	VPSUBB (R11), Y15, Y2                   // c4c105f813
+	VPSUBB Y2, Y15, Y2                      // c4e105f8d2 or c585f8d2
+	VPSUBB Y11, Y15, Y2                     // c4c105f8d3
+	VPSUBB (BX), Y15, Y11                   // c46105f81b or c505f81b
+	VPSUBB (R11), Y15, Y11                  // c44105f81b
+	VPSUBB Y2, Y15, Y11                     // c46105f8da or c505f8da
+	VPSUBB Y11, Y15, Y11                    // c44105f8db
+	VPSUBD (BX), X9, X2                     // c4e131fa13 or c5b1fa13
+	VPSUBD (R11), X9, X2                    // c4c131fa13
+	VPSUBD X2, X9, X2                       // c4e131fad2 or c5b1fad2
+	VPSUBD X11, X9, X2                      // c4c131fad3
+	VPSUBD (BX), X9, X11                    // c46131fa1b or c531fa1b
+	VPSUBD (R11), X9, X11                   // c44131fa1b
+	VPSUBD X2, X9, X11                      // c46131fada or c531fada
+	VPSUBD X11, X9, X11                     // c44131fadb
+	VPSUBD (BX), Y15, Y2                    // c4e105fa13 or c585fa13
+	VPSUBD (R11), Y15, Y2                   // c4c105fa13
+	VPSUBD Y2, Y15, Y2                      // c4e105fad2 or c585fad2
+	VPSUBD Y11, Y15, Y2                     // c4c105fad3
+	VPSUBD (BX), Y15, Y11                   // c46105fa1b or c505fa1b
+	VPSUBD (R11), Y15, Y11                  // c44105fa1b
+	VPSUBD Y2, Y15, Y11                     // c46105fada or c505fada
+	VPSUBD Y11, Y15, Y11                    // c44105fadb
+	VPSUBQ (BX), X9, X2                     // c4e131fb13 or c5b1fb13
+	VPSUBQ (R11), X9, X2                    // c4c131fb13
+	VPSUBQ X2, X9, X2                       // c4e131fbd2 or c5b1fbd2
+	VPSUBQ X11, X9, X2                      // c4c131fbd3
+	VPSUBQ (BX), X9, X11                    // c46131fb1b or c531fb1b
+	VPSUBQ (R11), X9, X11                   // c44131fb1b
+	VPSUBQ X2, X9, X11                      // c46131fbda or c531fbda
+	VPSUBQ X11, X9, X11                     // c44131fbdb
+	VPSUBQ (BX), Y15, Y2                    // c4e105fb13 or c585fb13
+	VPSUBQ (R11), Y15, Y2                   // c4c105fb13
+	VPSUBQ Y2, Y15, Y2                      // c4e105fbd2 or c585fbd2
+	VPSUBQ Y11, Y15, Y2                     // c4c105fbd3
+	VPSUBQ (BX), Y15, Y11                   // c46105fb1b or c505fb1b
+	VPSUBQ (R11), Y15, Y11                  // c44105fb1b
+	VPSUBQ Y2, Y15, Y11                     // c46105fbda or c505fbda
+	VPSUBQ Y11, Y15, Y11                    // c44105fbdb
+	VPSUBSB (BX), X9, X2                    // c4e131e813 or c5b1e813
+	VPSUBSB (R11), X9, X2                   // c4c131e813
+	VPSUBSB X2, X9, X2                      // c4e131e8d2 or c5b1e8d2
+	VPSUBSB X11, X9, X2                     // c4c131e8d3
+	VPSUBSB (BX), X9, X11                   // c46131e81b or c531e81b
+	VPSUBSB (R11), X9, X11                  // c44131e81b
+	VPSUBSB X2, X9, X11                     // c46131e8da or c531e8da
+	VPSUBSB X11, X9, X11                    // c44131e8db
+	VPSUBSB (BX), Y15, Y2                   // c4e105e813 or c585e813
+	VPSUBSB (R11), Y15, Y2                  // c4c105e813
+	VPSUBSB Y2, Y15, Y2                     // c4e105e8d2 or c585e8d2
+	VPSUBSB Y11, Y15, Y2                    // c4c105e8d3
+	VPSUBSB (BX), Y15, Y11                  // c46105e81b or c505e81b
+	VPSUBSB (R11), Y15, Y11                 // c44105e81b
+	VPSUBSB Y2, Y15, Y11                    // c46105e8da or c505e8da
+	VPSUBSB Y11, Y15, Y11                   // c44105e8db
+	VPSUBSW (BX), X9, X2                    // c4e131e913 or c5b1e913
+	VPSUBSW (R11), X9, X2                   // c4c131e913
+	VPSUBSW X2, X9, X2                      // c4e131e9d2 or c5b1e9d2
+	VPSUBSW X11, X9, X2                     // c4c131e9d3
+	VPSUBSW (BX), X9, X11                   // c46131e91b or c531e91b
+	VPSUBSW (R11), X9, X11                  // c44131e91b
+	VPSUBSW X2, X9, X11                     // c46131e9da or c531e9da
+	VPSUBSW X11, X9, X11                    // c44131e9db
+	VPSUBSW (BX), Y15, Y2                   // c4e105e913 or c585e913
+	VPSUBSW (R11), Y15, Y2                  // c4c105e913
+	VPSUBSW Y2, Y15, Y2                     // c4e105e9d2 or c585e9d2
+	VPSUBSW Y11, Y15, Y2                    // c4c105e9d3
+	VPSUBSW (BX), Y15, Y11                  // c46105e91b or c505e91b
+	VPSUBSW (R11), Y15, Y11                 // c44105e91b
+	VPSUBSW Y2, Y15, Y11                    // c46105e9da or c505e9da
+	VPSUBSW Y11, Y15, Y11                   // c44105e9db
+	VPSUBUSB (BX), X9, X2                   // c4e131d813 or c5b1d813
+	VPSUBUSB (R11), X9, X2                  // c4c131d813
+	VPSUBUSB X2, X9, X2                     // c4e131d8d2 or c5b1d8d2
+	VPSUBUSB X11, X9, X2                    // c4c131d8d3
+	VPSUBUSB (BX), X9, X11                  // c46131d81b or c531d81b
+	VPSUBUSB (R11), X9, X11                 // c44131d81b
+	VPSUBUSB X2, X9, X11                    // c46131d8da or c531d8da
+	VPSUBUSB X11, X9, X11                   // c44131d8db
+	VPSUBUSB (BX), Y15, Y2                  // c4e105d813 or c585d813
+	VPSUBUSB (R11), Y15, Y2                 // c4c105d813
+	VPSUBUSB Y2, Y15, Y2                    // c4e105d8d2 or c585d8d2
+	VPSUBUSB Y11, Y15, Y2                   // c4c105d8d3
+	VPSUBUSB (BX), Y15, Y11                 // c46105d81b or c505d81b
+	VPSUBUSB (R11), Y15, Y11                // c44105d81b
+	VPSUBUSB Y2, Y15, Y11                   // c46105d8da or c505d8da
+	VPSUBUSB Y11, Y15, Y11                  // c44105d8db
+	VPSUBUSW (BX), X9, X2                   // c4e131d913 or c5b1d913
+	VPSUBUSW (R11), X9, X2                  // c4c131d913
+	VPSUBUSW X2, X9, X2                     // c4e131d9d2 or c5b1d9d2
+	VPSUBUSW X11, X9, X2                    // c4c131d9d3
+	VPSUBUSW (BX), X9, X11                  // c46131d91b or c531d91b
+	VPSUBUSW (R11), X9, X11                 // c44131d91b
+	VPSUBUSW X2, X9, X11                    // c46131d9da or c531d9da
+	VPSUBUSW X11, X9, X11                   // c44131d9db
+	VPSUBUSW (BX), Y15, Y2                  // c4e105d913 or c585d913
+	VPSUBUSW (R11), Y15, Y2                 // c4c105d913
+	VPSUBUSW Y2, Y15, Y2                    // c4e105d9d2 or c585d9d2
+	VPSUBUSW Y11, Y15, Y2                   // c4c105d9d3
+	VPSUBUSW (BX), Y15, Y11                 // c46105d91b or c505d91b
+	VPSUBUSW (R11), Y15, Y11                // c44105d91b
+	VPSUBUSW Y2, Y15, Y11                   // c46105d9da or c505d9da
+	VPSUBUSW Y11, Y15, Y11                  // c44105d9db
+	VPSUBW (BX), X9, X2                     // c4e131f913 or c5b1f913
+	VPSUBW (R11), X9, X2                    // c4c131f913
+	VPSUBW X2, X9, X2                       // c4e131f9d2 or c5b1f9d2
+	VPSUBW X11, X9, X2                      // c4c131f9d3
+	VPSUBW (BX), X9, X11                    // c46131f91b or c531f91b
+	VPSUBW (R11), X9, X11                   // c44131f91b
+	VPSUBW X2, X9, X11                      // c46131f9da or c531f9da
+	VPSUBW X11, X9, X11                     // c44131f9db
+	VPSUBW (BX), Y15, Y2                    // c4e105f913 or c585f913
+	VPSUBW (R11), Y15, Y2                   // c4c105f913
+	VPSUBW Y2, Y15, Y2                      // c4e105f9d2 or c585f9d2
+	VPSUBW Y11, Y15, Y2                     // c4c105f9d3
+	VPSUBW (BX), Y15, Y11                   // c46105f91b or c505f91b
+	VPSUBW (R11), Y15, Y11                  // c44105f91b
+	VPSUBW Y2, Y15, Y11                     // c46105f9da or c505f9da
+	VPSUBW Y11, Y15, Y11                    // c44105f9db
 	VPTEST (BX), X2                         // c4e2791713
 	VPTEST (R11), X2                        // c4c2791713
 	VPTEST X2, X2                           // c4e27917d2
@@ -9960,134 +9960,134 @@
 	VPTEST (R11), Y11                       // c4427d171b
 	VPTEST Y2, Y11                          // c4627d17da
 	VPTEST Y11, Y11                         // c4427d17db
-	//TODO: VPUNPCKHBW (BX), X9, X2         // c4e1316813 or c5b16813
-	//TODO: VPUNPCKHBW (R11), X9, X2        // c4c1316813
-	//TODO: VPUNPCKHBW X2, X9, X2           // c4e13168d2 or c5b168d2
-	//TODO: VPUNPCKHBW X11, X9, X2          // c4c13168d3
-	//TODO: VPUNPCKHBW (BX), X9, X11        // c46131681b or c531681b
-	//TODO: VPUNPCKHBW (R11), X9, X11       // c44131681b
-	//TODO: VPUNPCKHBW X2, X9, X11          // c4613168da or c53168da
-	//TODO: VPUNPCKHBW X11, X9, X11         // c4413168db
-	//TODO: VPUNPCKHBW (BX), Y15, Y2        // c4e1056813 or c5856813
-	//TODO: VPUNPCKHBW (R11), Y15, Y2       // c4c1056813
-	//TODO: VPUNPCKHBW Y2, Y15, Y2          // c4e10568d2 or c58568d2
-	//TODO: VPUNPCKHBW Y11, Y15, Y2         // c4c10568d3
-	//TODO: VPUNPCKHBW (BX), Y15, Y11       // c46105681b or c505681b
-	//TODO: VPUNPCKHBW (R11), Y15, Y11      // c44105681b
-	//TODO: VPUNPCKHBW Y2, Y15, Y11         // c4610568da or c50568da
-	//TODO: VPUNPCKHBW Y11, Y15, Y11        // c4410568db
-	//TODO: VPUNPCKHDQ (BX), X9, X2         // c4e1316a13 or c5b16a13
-	//TODO: VPUNPCKHDQ (R11), X9, X2        // c4c1316a13
-	//TODO: VPUNPCKHDQ X2, X9, X2           // c4e1316ad2 or c5b16ad2
-	//TODO: VPUNPCKHDQ X11, X9, X2          // c4c1316ad3
-	//TODO: VPUNPCKHDQ (BX), X9, X11        // c461316a1b or c5316a1b
-	//TODO: VPUNPCKHDQ (R11), X9, X11       // c441316a1b
-	//TODO: VPUNPCKHDQ X2, X9, X11          // c461316ada or c5316ada
-	//TODO: VPUNPCKHDQ X11, X9, X11         // c441316adb
-	//TODO: VPUNPCKHDQ (BX), Y15, Y2        // c4e1056a13 or c5856a13
-	//TODO: VPUNPCKHDQ (R11), Y15, Y2       // c4c1056a13
-	//TODO: VPUNPCKHDQ Y2, Y15, Y2          // c4e1056ad2 or c5856ad2
-	//TODO: VPUNPCKHDQ Y11, Y15, Y2         // c4c1056ad3
-	//TODO: VPUNPCKHDQ (BX), Y15, Y11       // c461056a1b or c5056a1b
-	//TODO: VPUNPCKHDQ (R11), Y15, Y11      // c441056a1b
-	//TODO: VPUNPCKHDQ Y2, Y15, Y11         // c461056ada or c5056ada
-	//TODO: VPUNPCKHDQ Y11, Y15, Y11        // c441056adb
-	//TODO: VPUNPCKHQDQ (BX), X9, X2        // c4e1316d13 or c5b16d13
-	//TODO: VPUNPCKHQDQ (R11), X9, X2       // c4c1316d13
-	//TODO: VPUNPCKHQDQ X2, X9, X2          // c4e1316dd2 or c5b16dd2
-	//TODO: VPUNPCKHQDQ X11, X9, X2         // c4c1316dd3
-	//TODO: VPUNPCKHQDQ (BX), X9, X11       // c461316d1b or c5316d1b
-	//TODO: VPUNPCKHQDQ (R11), X9, X11      // c441316d1b
-	//TODO: VPUNPCKHQDQ X2, X9, X11         // c461316dda or c5316dda
-	//TODO: VPUNPCKHQDQ X11, X9, X11        // c441316ddb
-	//TODO: VPUNPCKHQDQ (BX), Y15, Y2       // c4e1056d13 or c5856d13
-	//TODO: VPUNPCKHQDQ (R11), Y15, Y2      // c4c1056d13
-	//TODO: VPUNPCKHQDQ Y2, Y15, Y2         // c4e1056dd2 or c5856dd2
-	//TODO: VPUNPCKHQDQ Y11, Y15, Y2        // c4c1056dd3
-	//TODO: VPUNPCKHQDQ (BX), Y15, Y11      // c461056d1b or c5056d1b
-	//TODO: VPUNPCKHQDQ (R11), Y15, Y11     // c441056d1b
-	//TODO: VPUNPCKHQDQ Y2, Y15, Y11        // c461056dda or c5056dda
-	//TODO: VPUNPCKHQDQ Y11, Y15, Y11       // c441056ddb
-	//TODO: VPUNPCKHWD (BX), X9, X2         // c4e1316913 or c5b16913
-	//TODO: VPUNPCKHWD (R11), X9, X2        // c4c1316913
-	//TODO: VPUNPCKHWD X2, X9, X2           // c4e13169d2 or c5b169d2
-	//TODO: VPUNPCKHWD X11, X9, X2          // c4c13169d3
-	//TODO: VPUNPCKHWD (BX), X9, X11        // c46131691b or c531691b
-	//TODO: VPUNPCKHWD (R11), X9, X11       // c44131691b
-	//TODO: VPUNPCKHWD X2, X9, X11          // c4613169da or c53169da
-	//TODO: VPUNPCKHWD X11, X9, X11         // c4413169db
-	//TODO: VPUNPCKHWD (BX), Y15, Y2        // c4e1056913 or c5856913
-	//TODO: VPUNPCKHWD (R11), Y15, Y2       // c4c1056913
-	//TODO: VPUNPCKHWD Y2, Y15, Y2          // c4e10569d2 or c58569d2
-	//TODO: VPUNPCKHWD Y11, Y15, Y2         // c4c10569d3
-	//TODO: VPUNPCKHWD (BX), Y15, Y11       // c46105691b or c505691b
-	//TODO: VPUNPCKHWD (R11), Y15, Y11      // c44105691b
-	//TODO: VPUNPCKHWD Y2, Y15, Y11         // c4610569da or c50569da
-	//TODO: VPUNPCKHWD Y11, Y15, Y11        // c4410569db
-	//TODO: VPUNPCKLBW (BX), X9, X2         // c4e1316013 or c5b16013
-	//TODO: VPUNPCKLBW (R11), X9, X2        // c4c1316013
-	//TODO: VPUNPCKLBW X2, X9, X2           // c4e13160d2 or c5b160d2
-	//TODO: VPUNPCKLBW X11, X9, X2          // c4c13160d3
-	//TODO: VPUNPCKLBW (BX), X9, X11        // c46131601b or c531601b
-	//TODO: VPUNPCKLBW (R11), X9, X11       // c44131601b
-	//TODO: VPUNPCKLBW X2, X9, X11          // c4613160da or c53160da
-	//TODO: VPUNPCKLBW X11, X9, X11         // c4413160db
-	//TODO: VPUNPCKLBW (BX), Y15, Y2        // c4e1056013 or c5856013
-	//TODO: VPUNPCKLBW (R11), Y15, Y2       // c4c1056013
-	//TODO: VPUNPCKLBW Y2, Y15, Y2          // c4e10560d2 or c58560d2
-	//TODO: VPUNPCKLBW Y11, Y15, Y2         // c4c10560d3
-	//TODO: VPUNPCKLBW (BX), Y15, Y11       // c46105601b or c505601b
-	//TODO: VPUNPCKLBW (R11), Y15, Y11      // c44105601b
-	//TODO: VPUNPCKLBW Y2, Y15, Y11         // c4610560da or c50560da
-	//TODO: VPUNPCKLBW Y11, Y15, Y11        // c4410560db
-	//TODO: VPUNPCKLDQ (BX), X9, X2         // c4e1316213 or c5b16213
-	//TODO: VPUNPCKLDQ (R11), X9, X2        // c4c1316213
-	//TODO: VPUNPCKLDQ X2, X9, X2           // c4e13162d2 or c5b162d2
-	//TODO: VPUNPCKLDQ X11, X9, X2          // c4c13162d3
-	//TODO: VPUNPCKLDQ (BX), X9, X11        // c46131621b or c531621b
-	//TODO: VPUNPCKLDQ (R11), X9, X11       // c44131621b
-	//TODO: VPUNPCKLDQ X2, X9, X11          // c4613162da or c53162da
-	//TODO: VPUNPCKLDQ X11, X9, X11         // c4413162db
-	//TODO: VPUNPCKLDQ (BX), Y15, Y2        // c4e1056213 or c5856213
-	//TODO: VPUNPCKLDQ (R11), Y15, Y2       // c4c1056213
-	//TODO: VPUNPCKLDQ Y2, Y15, Y2          // c4e10562d2 or c58562d2
-	//TODO: VPUNPCKLDQ Y11, Y15, Y2         // c4c10562d3
-	//TODO: VPUNPCKLDQ (BX), Y15, Y11       // c46105621b or c505621b
-	//TODO: VPUNPCKLDQ (R11), Y15, Y11      // c44105621b
-	//TODO: VPUNPCKLDQ Y2, Y15, Y11         // c4610562da or c50562da
-	//TODO: VPUNPCKLDQ Y11, Y15, Y11        // c4410562db
-	//TODO: VPUNPCKLQDQ (BX), X9, X2        // c4e1316c13 or c5b16c13
-	//TODO: VPUNPCKLQDQ (R11), X9, X2       // c4c1316c13
-	//TODO: VPUNPCKLQDQ X2, X9, X2          // c4e1316cd2 or c5b16cd2
-	//TODO: VPUNPCKLQDQ X11, X9, X2         // c4c1316cd3
-	//TODO: VPUNPCKLQDQ (BX), X9, X11       // c461316c1b or c5316c1b
-	//TODO: VPUNPCKLQDQ (R11), X9, X11      // c441316c1b
-	//TODO: VPUNPCKLQDQ X2, X9, X11         // c461316cda or c5316cda
-	//TODO: VPUNPCKLQDQ X11, X9, X11        // c441316cdb
-	//TODO: VPUNPCKLQDQ (BX), Y15, Y2       // c4e1056c13 or c5856c13
-	//TODO: VPUNPCKLQDQ (R11), Y15, Y2      // c4c1056c13
-	//TODO: VPUNPCKLQDQ Y2, Y15, Y2         // c4e1056cd2 or c5856cd2
-	//TODO: VPUNPCKLQDQ Y11, Y15, Y2        // c4c1056cd3
-	//TODO: VPUNPCKLQDQ (BX), Y15, Y11      // c461056c1b or c5056c1b
-	//TODO: VPUNPCKLQDQ (R11), Y15, Y11     // c441056c1b
-	//TODO: VPUNPCKLQDQ Y2, Y15, Y11        // c461056cda or c5056cda
-	//TODO: VPUNPCKLQDQ Y11, Y15, Y11       // c441056cdb
-	//TODO: VPUNPCKLWD (BX), X9, X2         // c4e1316113 or c5b16113
-	//TODO: VPUNPCKLWD (R11), X9, X2        // c4c1316113
-	//TODO: VPUNPCKLWD X2, X9, X2           // c4e13161d2 or c5b161d2
-	//TODO: VPUNPCKLWD X11, X9, X2          // c4c13161d3
-	//TODO: VPUNPCKLWD (BX), X9, X11        // c46131611b or c531611b
-	//TODO: VPUNPCKLWD (R11), X9, X11       // c44131611b
-	//TODO: VPUNPCKLWD X2, X9, X11          // c4613161da or c53161da
-	//TODO: VPUNPCKLWD X11, X9, X11         // c4413161db
-	//TODO: VPUNPCKLWD (BX), Y15, Y2        // c4e1056113 or c5856113
-	//TODO: VPUNPCKLWD (R11), Y15, Y2       // c4c1056113
-	//TODO: VPUNPCKLWD Y2, Y15, Y2          // c4e10561d2 or c58561d2
-	//TODO: VPUNPCKLWD Y11, Y15, Y2         // c4c10561d3
-	//TODO: VPUNPCKLWD (BX), Y15, Y11       // c46105611b or c505611b
-	//TODO: VPUNPCKLWD (R11), Y15, Y11      // c44105611b
-	//TODO: VPUNPCKLWD Y2, Y15, Y11         // c4610561da or c50561da
-	//TODO: VPUNPCKLWD Y11, Y15, Y11        // c4410561db
+	VPUNPCKHBW (BX), X9, X2                 // c4e1316813 or c5b16813
+	VPUNPCKHBW (R11), X9, X2                // c4c1316813
+	VPUNPCKHBW X2, X9, X2                   // c4e13168d2 or c5b168d2
+	VPUNPCKHBW X11, X9, X2                  // c4c13168d3
+	VPUNPCKHBW (BX), X9, X11                // c46131681b or c531681b
+	VPUNPCKHBW (R11), X9, X11               // c44131681b
+	VPUNPCKHBW X2, X9, X11                  // c4613168da or c53168da
+	VPUNPCKHBW X11, X9, X11                 // c4413168db
+	VPUNPCKHBW (BX), Y15, Y2                // c4e1056813 or c5856813
+	VPUNPCKHBW (R11), Y15, Y2               // c4c1056813
+	VPUNPCKHBW Y2, Y15, Y2                  // c4e10568d2 or c58568d2
+	VPUNPCKHBW Y11, Y15, Y2                 // c4c10568d3
+	VPUNPCKHBW (BX), Y15, Y11               // c46105681b or c505681b
+	VPUNPCKHBW (R11), Y15, Y11              // c44105681b
+	VPUNPCKHBW Y2, Y15, Y11                 // c4610568da or c50568da
+	VPUNPCKHBW Y11, Y15, Y11                // c4410568db
+	VPUNPCKHDQ (BX), X9, X2                 // c4e1316a13 or c5b16a13
+	VPUNPCKHDQ (R11), X9, X2                // c4c1316a13
+	VPUNPCKHDQ X2, X9, X2                   // c4e1316ad2 or c5b16ad2
+	VPUNPCKHDQ X11, X9, X2                  // c4c1316ad3
+	VPUNPCKHDQ (BX), X9, X11                // c461316a1b or c5316a1b
+	VPUNPCKHDQ (R11), X9, X11               // c441316a1b
+	VPUNPCKHDQ X2, X9, X11                  // c461316ada or c5316ada
+	VPUNPCKHDQ X11, X9, X11                 // c441316adb
+	VPUNPCKHDQ (BX), Y15, Y2                // c4e1056a13 or c5856a13
+	VPUNPCKHDQ (R11), Y15, Y2               // c4c1056a13
+	VPUNPCKHDQ Y2, Y15, Y2                  // c4e1056ad2 or c5856ad2
+	VPUNPCKHDQ Y11, Y15, Y2                 // c4c1056ad3
+	VPUNPCKHDQ (BX), Y15, Y11               // c461056a1b or c5056a1b
+	VPUNPCKHDQ (R11), Y15, Y11              // c441056a1b
+	VPUNPCKHDQ Y2, Y15, Y11                 // c461056ada or c5056ada
+	VPUNPCKHDQ Y11, Y15, Y11                // c441056adb
+	VPUNPCKHQDQ (BX), X9, X2                // c4e1316d13 or c5b16d13
+	VPUNPCKHQDQ (R11), X9, X2               // c4c1316d13
+	VPUNPCKHQDQ X2, X9, X2                  // c4e1316dd2 or c5b16dd2
+	VPUNPCKHQDQ X11, X9, X2                 // c4c1316dd3
+	VPUNPCKHQDQ (BX), X9, X11               // c461316d1b or c5316d1b
+	VPUNPCKHQDQ (R11), X9, X11              // c441316d1b
+	VPUNPCKHQDQ X2, X9, X11                 // c461316dda or c5316dda
+	VPUNPCKHQDQ X11, X9, X11                // c441316ddb
+	VPUNPCKHQDQ (BX), Y15, Y2               // c4e1056d13 or c5856d13
+	VPUNPCKHQDQ (R11), Y15, Y2              // c4c1056d13
+	VPUNPCKHQDQ Y2, Y15, Y2                 // c4e1056dd2 or c5856dd2
+	VPUNPCKHQDQ Y11, Y15, Y2                // c4c1056dd3
+	VPUNPCKHQDQ (BX), Y15, Y11              // c461056d1b or c5056d1b
+	VPUNPCKHQDQ (R11), Y15, Y11             // c441056d1b
+	VPUNPCKHQDQ Y2, Y15, Y11                // c461056dda or c5056dda
+	VPUNPCKHQDQ Y11, Y15, Y11               // c441056ddb
+	VPUNPCKHWD (BX), X9, X2                 // c4e1316913 or c5b16913
+	VPUNPCKHWD (R11), X9, X2                // c4c1316913
+	VPUNPCKHWD X2, X9, X2                   // c4e13169d2 or c5b169d2
+	VPUNPCKHWD X11, X9, X2                  // c4c13169d3
+	VPUNPCKHWD (BX), X9, X11                // c46131691b or c531691b
+	VPUNPCKHWD (R11), X9, X11               // c44131691b
+	VPUNPCKHWD X2, X9, X11                  // c4613169da or c53169da
+	VPUNPCKHWD X11, X9, X11                 // c4413169db
+	VPUNPCKHWD (BX), Y15, Y2                // c4e1056913 or c5856913
+	VPUNPCKHWD (R11), Y15, Y2               // c4c1056913
+	VPUNPCKHWD Y2, Y15, Y2                  // c4e10569d2 or c58569d2
+	VPUNPCKHWD Y11, Y15, Y2                 // c4c10569d3
+	VPUNPCKHWD (BX), Y15, Y11               // c46105691b or c505691b
+	VPUNPCKHWD (R11), Y15, Y11              // c44105691b
+	VPUNPCKHWD Y2, Y15, Y11                 // c4610569da or c50569da
+	VPUNPCKHWD Y11, Y15, Y11                // c4410569db
+	VPUNPCKLBW (BX), X9, X2                 // c4e1316013 or c5b16013
+	VPUNPCKLBW (R11), X9, X2                // c4c1316013
+	VPUNPCKLBW X2, X9, X2                   // c4e13160d2 or c5b160d2
+	VPUNPCKLBW X11, X9, X2                  // c4c13160d3
+	VPUNPCKLBW (BX), X9, X11                // c46131601b or c531601b
+	VPUNPCKLBW (R11), X9, X11               // c44131601b
+	VPUNPCKLBW X2, X9, X11                  // c4613160da or c53160da
+	VPUNPCKLBW X11, X9, X11                 // c4413160db
+	VPUNPCKLBW (BX), Y15, Y2                // c4e1056013 or c5856013
+	VPUNPCKLBW (R11), Y15, Y2               // c4c1056013
+	VPUNPCKLBW Y2, Y15, Y2                  // c4e10560d2 or c58560d2
+	VPUNPCKLBW Y11, Y15, Y2                 // c4c10560d3
+	VPUNPCKLBW (BX), Y15, Y11               // c46105601b or c505601b
+	VPUNPCKLBW (R11), Y15, Y11              // c44105601b
+	VPUNPCKLBW Y2, Y15, Y11                 // c4610560da or c50560da
+	VPUNPCKLBW Y11, Y15, Y11                // c4410560db
+	VPUNPCKLDQ (BX), X9, X2                 // c4e1316213 or c5b16213
+	VPUNPCKLDQ (R11), X9, X2                // c4c1316213
+	VPUNPCKLDQ X2, X9, X2                   // c4e13162d2 or c5b162d2
+	VPUNPCKLDQ X11, X9, X2                  // c4c13162d3
+	VPUNPCKLDQ (BX), X9, X11                // c46131621b or c531621b
+	VPUNPCKLDQ (R11), X9, X11               // c44131621b
+	VPUNPCKLDQ X2, X9, X11                  // c4613162da or c53162da
+	VPUNPCKLDQ X11, X9, X11                 // c4413162db
+	VPUNPCKLDQ (BX), Y15, Y2                // c4e1056213 or c5856213
+	VPUNPCKLDQ (R11), Y15, Y2               // c4c1056213
+	VPUNPCKLDQ Y2, Y15, Y2                  // c4e10562d2 or c58562d2
+	VPUNPCKLDQ Y11, Y15, Y2                 // c4c10562d3
+	VPUNPCKLDQ (BX), Y15, Y11               // c46105621b or c505621b
+	VPUNPCKLDQ (R11), Y15, Y11              // c44105621b
+	VPUNPCKLDQ Y2, Y15, Y11                 // c4610562da or c50562da
+	VPUNPCKLDQ Y11, Y15, Y11                // c4410562db
+	VPUNPCKLQDQ (BX), X9, X2                // c4e1316c13 or c5b16c13
+	VPUNPCKLQDQ (R11), X9, X2               // c4c1316c13
+	VPUNPCKLQDQ X2, X9, X2                  // c4e1316cd2 or c5b16cd2
+	VPUNPCKLQDQ X11, X9, X2                 // c4c1316cd3
+	VPUNPCKLQDQ (BX), X9, X11               // c461316c1b or c5316c1b
+	VPUNPCKLQDQ (R11), X9, X11              // c441316c1b
+	VPUNPCKLQDQ X2, X9, X11                 // c461316cda or c5316cda
+	VPUNPCKLQDQ X11, X9, X11                // c441316cdb
+	VPUNPCKLQDQ (BX), Y15, Y2               // c4e1056c13 or c5856c13
+	VPUNPCKLQDQ (R11), Y15, Y2              // c4c1056c13
+	VPUNPCKLQDQ Y2, Y15, Y2                 // c4e1056cd2 or c5856cd2
+	VPUNPCKLQDQ Y11, Y15, Y2                // c4c1056cd3
+	VPUNPCKLQDQ (BX), Y15, Y11              // c461056c1b or c5056c1b
+	VPUNPCKLQDQ (R11), Y15, Y11             // c441056c1b
+	VPUNPCKLQDQ Y2, Y15, Y11                // c461056cda or c5056cda
+	VPUNPCKLQDQ Y11, Y15, Y11               // c441056cdb
+	VPUNPCKLWD (BX), X9, X2                 // c4e1316113 or c5b16113
+	VPUNPCKLWD (R11), X9, X2                // c4c1316113
+	VPUNPCKLWD X2, X9, X2                   // c4e13161d2 or c5b161d2
+	VPUNPCKLWD X11, X9, X2                  // c4c13161d3
+	VPUNPCKLWD (BX), X9, X11                // c46131611b or c531611b
+	VPUNPCKLWD (R11), X9, X11               // c44131611b
+	VPUNPCKLWD X2, X9, X11                  // c4613161da or c53161da
+	VPUNPCKLWD X11, X9, X11                 // c4413161db
+	VPUNPCKLWD (BX), Y15, Y2                // c4e1056113 or c5856113
+	VPUNPCKLWD (R11), Y15, Y2               // c4c1056113
+	VPUNPCKLWD Y2, Y15, Y2                  // c4e10561d2 or c58561d2
+	VPUNPCKLWD Y11, Y15, Y2                 // c4c10561d3
+	VPUNPCKLWD (BX), Y15, Y11               // c46105611b or c505611b
+	VPUNPCKLWD (R11), Y15, Y11              // c44105611b
+	VPUNPCKLWD Y2, Y15, Y11                 // c4610561da or c50561da
+	VPUNPCKLWD Y11, Y15, Y11                // c4410561db
 	VPXOR (BX), X9, X2                      // c4e131ef13 or c5b1ef13
 	VPXOR (R11), X9, X2                     // c4c131ef13
 	VPXOR X2, X9, X2                        // c4e131efd2 or c5b1efd2
@@ -10104,377 +10104,377 @@
 	VPXOR (R11), Y15, Y11                   // c44105ef1b
 	VPXOR Y2, Y15, Y11                      // c46105efda or c505efda
 	VPXOR Y11, Y15, Y11                     // c44105efdb
-	//TODO: VRCPPS (BX), X2                 // c4e1785313 or c5f85313
-	//TODO: VRCPPS (R11), X2                // c4c1785313
-	//TODO: VRCPPS X2, X2                   // c4e17853d2 or c5f853d2
-	//TODO: VRCPPS X11, X2                  // c4c17853d3
-	//TODO: VRCPPS (BX), X11                // c46178531b or c578531b
-	//TODO: VRCPPS (R11), X11               // c44178531b
-	//TODO: VRCPPS X2, X11                  // c4617853da or c57853da
-	//TODO: VRCPPS X11, X11                 // c4417853db
-	//TODO: VRCPPS (BX), Y2                 // c4e17c5313 or c5fc5313
-	//TODO: VRCPPS (R11), Y2                // c4c17c5313
-	//TODO: VRCPPS Y2, Y2                   // c4e17c53d2 or c5fc53d2
-	//TODO: VRCPPS Y11, Y2                  // c4c17c53d3
-	//TODO: VRCPPS (BX), Y11                // c4617c531b or c57c531b
-	//TODO: VRCPPS (R11), Y11               // c4417c531b
-	//TODO: VRCPPS Y2, Y11                  // c4617c53da or c57c53da
-	//TODO: VRCPPS Y11, Y11                 // c4417c53db
-	//TODO: VRCPSS (BX), X9, X2             // c4e1325313 or c5b25313
-	//TODO: VRCPSS (R11), X9, X2            // c4c1325313
-	//TODO: VRCPSS X2, X9, X2               // c4e13253d2 or c5b253d2
-	//TODO: VRCPSS X11, X9, X2              // c4c13253d3
-	//TODO: VRCPSS (BX), X9, X11            // c46132531b or c532531b
-	//TODO: VRCPSS (R11), X9, X11           // c44132531b
-	//TODO: VRCPSS X2, X9, X11              // c4613253da or c53253da
-	//TODO: VRCPSS X11, X9, X11             // c4413253db
-	//TODO: VROUNDPD $7, (BX), X2           // c4e379091307
-	//TODO: VROUNDPD $7, (R11), X2          // c4c379091307
-	//TODO: VROUNDPD $7, X2, X2             // c4e37909d207
-	//TODO: VROUNDPD $7, X11, X2            // c4c37909d307
-	//TODO: VROUNDPD $7, (BX), X11          // c46379091b07
-	//TODO: VROUNDPD $7, (R11), X11         // c44379091b07
-	//TODO: VROUNDPD $7, X2, X11            // c4637909da07
-	//TODO: VROUNDPD $7, X11, X11           // c4437909db07
-	//TODO: VROUNDPD $7, (BX), Y2           // c4e37d091307
-	//TODO: VROUNDPD $7, (R11), Y2          // c4c37d091307
-	//TODO: VROUNDPD $7, Y2, Y2             // c4e37d09d207
-	//TODO: VROUNDPD $7, Y11, Y2            // c4c37d09d307
-	//TODO: VROUNDPD $7, (BX), Y11          // c4637d091b07
-	//TODO: VROUNDPD $7, (R11), Y11         // c4437d091b07
-	//TODO: VROUNDPD $7, Y2, Y11            // c4637d09da07
-	//TODO: VROUNDPD $7, Y11, Y11           // c4437d09db07
-	//TODO: VROUNDPS $7, (BX), X2           // c4e379081307
-	//TODO: VROUNDPS $7, (R11), X2          // c4c379081307
-	//TODO: VROUNDPS $7, X2, X2             // c4e37908d207
-	//TODO: VROUNDPS $7, X11, X2            // c4c37908d307
-	//TODO: VROUNDPS $7, (BX), X11          // c46379081b07
-	//TODO: VROUNDPS $7, (R11), X11         // c44379081b07
-	//TODO: VROUNDPS $7, X2, X11            // c4637908da07
-	//TODO: VROUNDPS $7, X11, X11           // c4437908db07
-	//TODO: VROUNDPS $7, (BX), Y2           // c4e37d081307
-	//TODO: VROUNDPS $7, (R11), Y2          // c4c37d081307
-	//TODO: VROUNDPS $7, Y2, Y2             // c4e37d08d207
-	//TODO: VROUNDPS $7, Y11, Y2            // c4c37d08d307
-	//TODO: VROUNDPS $7, (BX), Y11          // c4637d081b07
-	//TODO: VROUNDPS $7, (R11), Y11         // c4437d081b07
-	//TODO: VROUNDPS $7, Y2, Y11            // c4637d08da07
-	//TODO: VROUNDPS $7, Y11, Y11           // c4437d08db07
-	//TODO: VROUNDSD $7, (BX), X9, X2       // c4e3310b1307
-	//TODO: VROUNDSD $7, (R11), X9, X2      // c4c3310b1307
-	//TODO: VROUNDSD $7, X2, X9, X2         // c4e3310bd207
-	//TODO: VROUNDSD $7, X11, X9, X2        // c4c3310bd307
-	//TODO: VROUNDSD $7, (BX), X9, X11      // c463310b1b07
-	//TODO: VROUNDSD $7, (R11), X9, X11     // c443310b1b07
-	//TODO: VROUNDSD $7, X2, X9, X11        // c463310bda07
-	//TODO: VROUNDSD $7, X11, X9, X11       // c443310bdb07
-	//TODO: VROUNDSS $7, (BX), X9, X2       // c4e3310a1307
-	//TODO: VROUNDSS $7, (R11), X9, X2      // c4c3310a1307
-	//TODO: VROUNDSS $7, X2, X9, X2         // c4e3310ad207
-	//TODO: VROUNDSS $7, X11, X9, X2        // c4c3310ad307
-	//TODO: VROUNDSS $7, (BX), X9, X11      // c463310a1b07
-	//TODO: VROUNDSS $7, (R11), X9, X11     // c443310a1b07
-	//TODO: VROUNDSS $7, X2, X9, X11        // c463310ada07
-	//TODO: VROUNDSS $7, X11, X9, X11       // c443310adb07
-	//TODO: VRSQRTPS (BX), X2               // c4e1785213 or c5f85213
-	//TODO: VRSQRTPS (R11), X2              // c4c1785213
-	//TODO: VRSQRTPS X2, X2                 // c4e17852d2 or c5f852d2
-	//TODO: VRSQRTPS X11, X2                // c4c17852d3
-	//TODO: VRSQRTPS (BX), X11              // c46178521b or c578521b
-	//TODO: VRSQRTPS (R11), X11             // c44178521b
-	//TODO: VRSQRTPS X2, X11                // c4617852da or c57852da
-	//TODO: VRSQRTPS X11, X11               // c4417852db
-	//TODO: VRSQRTPS (BX), Y2               // c4e17c5213 or c5fc5213
-	//TODO: VRSQRTPS (R11), Y2              // c4c17c5213
-	//TODO: VRSQRTPS Y2, Y2                 // c4e17c52d2 or c5fc52d2
-	//TODO: VRSQRTPS Y11, Y2                // c4c17c52d3
-	//TODO: VRSQRTPS (BX), Y11              // c4617c521b or c57c521b
-	//TODO: VRSQRTPS (R11), Y11             // c4417c521b
-	//TODO: VRSQRTPS Y2, Y11                // c4617c52da or c57c52da
-	//TODO: VRSQRTPS Y11, Y11               // c4417c52db
-	//TODO: VRSQRTSS (BX), X9, X2           // c4e1325213 or c5b25213
-	//TODO: VRSQRTSS (R11), X9, X2          // c4c1325213
-	//TODO: VRSQRTSS X2, X9, X2             // c4e13252d2 or c5b252d2
-	//TODO: VRSQRTSS X11, X9, X2            // c4c13252d3
-	//TODO: VRSQRTSS (BX), X9, X11          // c46132521b or c532521b
-	//TODO: VRSQRTSS (R11), X9, X11         // c44132521b
-	//TODO: VRSQRTSS X2, X9, X11            // c4613252da or c53252da
-	//TODO: VRSQRTSS X11, X9, X11           // c4413252db
-	//TODO: VSHUFPD $7, (BX), X9, X2        // c4e131c61307 or c5b1c61307
-	//TODO: VSHUFPD $7, (R11), X9, X2       // c4c131c61307
-	//TODO: VSHUFPD $7, X2, X9, X2          // c4e131c6d207 or c5b1c6d207
-	//TODO: VSHUFPD $7, X11, X9, X2         // c4c131c6d307
-	//TODO: VSHUFPD $7, (BX), X9, X11       // c46131c61b07 or c531c61b07
-	//TODO: VSHUFPD $7, (R11), X9, X11      // c44131c61b07
-	//TODO: VSHUFPD $7, X2, X9, X11         // c46131c6da07 or c531c6da07
-	//TODO: VSHUFPD $7, X11, X9, X11        // c44131c6db07
-	//TODO: VSHUFPD $7, (BX), Y15, Y2       // c4e105c61307 or c585c61307
-	//TODO: VSHUFPD $7, (R11), Y15, Y2      // c4c105c61307
-	//TODO: VSHUFPD $7, Y2, Y15, Y2         // c4e105c6d207 or c585c6d207
-	//TODO: VSHUFPD $7, Y11, Y15, Y2        // c4c105c6d307
-	//TODO: VSHUFPD $7, (BX), Y15, Y11      // c46105c61b07 or c505c61b07
-	//TODO: VSHUFPD $7, (R11), Y15, Y11     // c44105c61b07
-	//TODO: VSHUFPD $7, Y2, Y15, Y11        // c46105c6da07 or c505c6da07
-	//TODO: VSHUFPD $7, Y11, Y15, Y11       // c44105c6db07
-	//TODO: VSHUFPS $7, (BX), X9, X2        // c4e130c61307 or c5b0c61307
-	//TODO: VSHUFPS $7, (R11), X9, X2       // c4c130c61307
-	//TODO: VSHUFPS $7, X2, X9, X2          // c4e130c6d207 or c5b0c6d207
-	//TODO: VSHUFPS $7, X11, X9, X2         // c4c130c6d307
-	//TODO: VSHUFPS $7, (BX), X9, X11       // c46130c61b07 or c530c61b07
-	//TODO: VSHUFPS $7, (R11), X9, X11      // c44130c61b07
-	//TODO: VSHUFPS $7, X2, X9, X11         // c46130c6da07 or c530c6da07
-	//TODO: VSHUFPS $7, X11, X9, X11        // c44130c6db07
-	//TODO: VSHUFPS $7, (BX), Y15, Y2       // c4e104c61307 or c584c61307
-	//TODO: VSHUFPS $7, (R11), Y15, Y2      // c4c104c61307
-	//TODO: VSHUFPS $7, Y2, Y15, Y2         // c4e104c6d207 or c584c6d207
-	//TODO: VSHUFPS $7, Y11, Y15, Y2        // c4c104c6d307
-	//TODO: VSHUFPS $7, (BX), Y15, Y11      // c46104c61b07 or c504c61b07
-	//TODO: VSHUFPS $7, (R11), Y15, Y11     // c44104c61b07
-	//TODO: VSHUFPS $7, Y2, Y15, Y11        // c46104c6da07 or c504c6da07
-	//TODO: VSHUFPS $7, Y11, Y15, Y11       // c44104c6db07
-	//TODO: VSQRTPD (BX), X2                // c4e1795113 or c5f95113
-	//TODO: VSQRTPD (R11), X2               // c4c1795113
-	//TODO: VSQRTPD X2, X2                  // c4e17951d2 or c5f951d2
-	//TODO: VSQRTPD X11, X2                 // c4c17951d3
-	//TODO: VSQRTPD (BX), X11               // c46179511b or c579511b
-	//TODO: VSQRTPD (R11), X11              // c44179511b
-	//TODO: VSQRTPD X2, X11                 // c4617951da or c57951da
-	//TODO: VSQRTPD X11, X11                // c4417951db
-	//TODO: VSQRTPD (BX), Y2                // c4e17d5113 or c5fd5113
-	//TODO: VSQRTPD (R11), Y2               // c4c17d5113
-	//TODO: VSQRTPD Y2, Y2                  // c4e17d51d2 or c5fd51d2
-	//TODO: VSQRTPD Y11, Y2                 // c4c17d51d3
-	//TODO: VSQRTPD (BX), Y11               // c4617d511b or c57d511b
-	//TODO: VSQRTPD (R11), Y11              // c4417d511b
-	//TODO: VSQRTPD Y2, Y11                 // c4617d51da or c57d51da
-	//TODO: VSQRTPD Y11, Y11                // c4417d51db
-	//TODO: VSQRTPS (BX), X2                // c4e1785113 or c5f85113
-	//TODO: VSQRTPS (R11), X2               // c4c1785113
-	//TODO: VSQRTPS X2, X2                  // c4e17851d2 or c5f851d2
-	//TODO: VSQRTPS X11, X2                 // c4c17851d3
-	//TODO: VSQRTPS (BX), X11               // c46178511b or c578511b
-	//TODO: VSQRTPS (R11), X11              // c44178511b
-	//TODO: VSQRTPS X2, X11                 // c4617851da or c57851da
-	//TODO: VSQRTPS X11, X11                // c4417851db
-	//TODO: VSQRTPS (BX), Y2                // c4e17c5113 or c5fc5113
-	//TODO: VSQRTPS (R11), Y2               // c4c17c5113
-	//TODO: VSQRTPS Y2, Y2                  // c4e17c51d2 or c5fc51d2
-	//TODO: VSQRTPS Y11, Y2                 // c4c17c51d3
-	//TODO: VSQRTPS (BX), Y11               // c4617c511b or c57c511b
-	//TODO: VSQRTPS (R11), Y11              // c4417c511b
-	//TODO: VSQRTPS Y2, Y11                 // c4617c51da or c57c51da
-	//TODO: VSQRTPS Y11, Y11                // c4417c51db
-	//TODO: VSQRTSD (BX), X9, X2            // c4e1335113 or c5b35113
-	//TODO: VSQRTSD (R11), X9, X2           // c4c1335113
-	//TODO: VSQRTSD X2, X9, X2              // c4e13351d2 or c5b351d2
-	//TODO: VSQRTSD X11, X9, X2             // c4c13351d3
-	//TODO: VSQRTSD (BX), X9, X11           // c46133511b or c533511b
-	//TODO: VSQRTSD (R11), X9, X11          // c44133511b
-	//TODO: VSQRTSD X2, X9, X11             // c4613351da or c53351da
-	//TODO: VSQRTSD X11, X9, X11            // c4413351db
-	//TODO: VSQRTSS (BX), X9, X2            // c4e1325113 or c5b25113
-	//TODO: VSQRTSS (R11), X9, X2           // c4c1325113
-	//TODO: VSQRTSS X2, X9, X2              // c4e13251d2 or c5b251d2
-	//TODO: VSQRTSS X11, X9, X2             // c4c13251d3
-	//TODO: VSQRTSS (BX), X9, X11           // c46132511b or c532511b
-	//TODO: VSQRTSS (R11), X9, X11          // c44132511b
-	//TODO: VSQRTSS X2, X9, X11             // c4613251da or c53251da
-	//TODO: VSQRTSS X11, X9, X11            // c4413251db
-	//TODO: VSTMXCSR (BX)                   // c4e178ae1b or c5f8ae1b
-	//TODO: VSTMXCSR (R11)                  // c4c178ae1b
-	//TODO: VSUBPD (BX), X9, X2             // c4e1315c13 or c5b15c13
-	//TODO: VSUBPD (R11), X9, X2            // c4c1315c13
-	//TODO: VSUBPD X2, X9, X2               // c4e1315cd2 or c5b15cd2
-	//TODO: VSUBPD X11, X9, X2              // c4c1315cd3
-	//TODO: VSUBPD (BX), X9, X11            // c461315c1b or c5315c1b
-	//TODO: VSUBPD (R11), X9, X11           // c441315c1b
-	//TODO: VSUBPD X2, X9, X11              // c461315cda or c5315cda
-	//TODO: VSUBPD X11, X9, X11             // c441315cdb
-	//TODO: VSUBPD (BX), Y15, Y2            // c4e1055c13 or c5855c13
-	//TODO: VSUBPD (R11), Y15, Y2           // c4c1055c13
-	//TODO: VSUBPD Y2, Y15, Y2              // c4e1055cd2 or c5855cd2
-	//TODO: VSUBPD Y11, Y15, Y2             // c4c1055cd3
-	//TODO: VSUBPD (BX), Y15, Y11           // c461055c1b or c5055c1b
-	//TODO: VSUBPD (R11), Y15, Y11          // c441055c1b
-	//TODO: VSUBPD Y2, Y15, Y11             // c461055cda or c5055cda
-	//TODO: VSUBPD Y11, Y15, Y11            // c441055cdb
-	//TODO: VSUBPS (BX), X9, X2             // c4e1305c13 or c5b05c13
-	//TODO: VSUBPS (R11), X9, X2            // c4c1305c13
-	//TODO: VSUBPS X2, X9, X2               // c4e1305cd2 or c5b05cd2
-	//TODO: VSUBPS X11, X9, X2              // c4c1305cd3
-	//TODO: VSUBPS (BX), X9, X11            // c461305c1b or c5305c1b
-	//TODO: VSUBPS (R11), X9, X11           // c441305c1b
-	//TODO: VSUBPS X2, X9, X11              // c461305cda or c5305cda
-	//TODO: VSUBPS X11, X9, X11             // c441305cdb
-	//TODO: VSUBPS (BX), Y15, Y2            // c4e1045c13 or c5845c13
-	//TODO: VSUBPS (R11), Y15, Y2           // c4c1045c13
-	//TODO: VSUBPS Y2, Y15, Y2              // c4e1045cd2 or c5845cd2
-	//TODO: VSUBPS Y11, Y15, Y2             // c4c1045cd3
-	//TODO: VSUBPS (BX), Y15, Y11           // c461045c1b or c5045c1b
-	//TODO: VSUBPS (R11), Y15, Y11          // c441045c1b
-	//TODO: VSUBPS Y2, Y15, Y11             // c461045cda or c5045cda
-	//TODO: VSUBPS Y11, Y15, Y11            // c441045cdb
-	//TODO: VSUBSD (BX), X9, X2             // c4e1335c13 or c5b35c13
-	//TODO: VSUBSD (R11), X9, X2            // c4c1335c13
-	//TODO: VSUBSD X2, X9, X2               // c4e1335cd2 or c5b35cd2
-	//TODO: VSUBSD X11, X9, X2              // c4c1335cd3
-	//TODO: VSUBSD (BX), X9, X11            // c461335c1b or c5335c1b
-	//TODO: VSUBSD (R11), X9, X11           // c441335c1b
-	//TODO: VSUBSD X2, X9, X11              // c461335cda or c5335cda
-	//TODO: VSUBSD X11, X9, X11             // c441335cdb
-	//TODO: VSUBSS (BX), X9, X2             // c4e1325c13 or c5b25c13
-	//TODO: VSUBSS (R11), X9, X2            // c4c1325c13
-	//TODO: VSUBSS X2, X9, X2               // c4e1325cd2 or c5b25cd2
-	//TODO: VSUBSS X11, X9, X2              // c4c1325cd3
-	//TODO: VSUBSS (BX), X9, X11            // c461325c1b or c5325c1b
-	//TODO: VSUBSS (R11), X9, X11           // c441325c1b
-	//TODO: VSUBSS X2, X9, X11              // c461325cda or c5325cda
-	//TODO: VSUBSS X11, X9, X11             // c441325cdb
-	//TODO: VTESTPD (BX), X2                // c4e2790f13
-	//TODO: VTESTPD (R11), X2               // c4c2790f13
-	//TODO: VTESTPD X2, X2                  // c4e2790fd2
-	//TODO: VTESTPD X11, X2                 // c4c2790fd3
-	//TODO: VTESTPD (BX), X11               // c462790f1b
-	//TODO: VTESTPD (R11), X11              // c442790f1b
-	//TODO: VTESTPD X2, X11                 // c462790fda
-	//TODO: VTESTPD X11, X11                // c442790fdb
-	//TODO: VTESTPD (BX), Y2                // c4e27d0f13
-	//TODO: VTESTPD (R11), Y2               // c4c27d0f13
-	//TODO: VTESTPD Y2, Y2                  // c4e27d0fd2
-	//TODO: VTESTPD Y11, Y2                 // c4c27d0fd3
-	//TODO: VTESTPD (BX), Y11               // c4627d0f1b
-	//TODO: VTESTPD (R11), Y11              // c4427d0f1b
-	//TODO: VTESTPD Y2, Y11                 // c4627d0fda
-	//TODO: VTESTPD Y11, Y11                // c4427d0fdb
-	//TODO: VTESTPS (BX), X2                // c4e2790e13
-	//TODO: VTESTPS (R11), X2               // c4c2790e13
-	//TODO: VTESTPS X2, X2                  // c4e2790ed2
-	//TODO: VTESTPS X11, X2                 // c4c2790ed3
-	//TODO: VTESTPS (BX), X11               // c462790e1b
-	//TODO: VTESTPS (R11), X11              // c442790e1b
-	//TODO: VTESTPS X2, X11                 // c462790eda
-	//TODO: VTESTPS X11, X11                // c442790edb
-	//TODO: VTESTPS (BX), Y2                // c4e27d0e13
-	//TODO: VTESTPS (R11), Y2               // c4c27d0e13
-	//TODO: VTESTPS Y2, Y2                  // c4e27d0ed2
-	//TODO: VTESTPS Y11, Y2                 // c4c27d0ed3
-	//TODO: VTESTPS (BX), Y11               // c4627d0e1b
-	//TODO: VTESTPS (R11), Y11              // c4427d0e1b
-	//TODO: VTESTPS Y2, Y11                 // c4627d0eda
-	//TODO: VTESTPS Y11, Y11                // c4427d0edb
-	//TODO: VUCOMISD (BX), X2               // c4e1792e13 or c5f92e13
-	//TODO: VUCOMISD (R11), X2              // c4c1792e13
-	//TODO: VUCOMISD X2, X2                 // c4e1792ed2 or c5f92ed2
-	//TODO: VUCOMISD X11, X2                // c4c1792ed3
-	//TODO: VUCOMISD (BX), X11              // c461792e1b or c5792e1b
-	//TODO: VUCOMISD (R11), X11             // c441792e1b
-	//TODO: VUCOMISD X2, X11                // c461792eda or c5792eda
-	//TODO: VUCOMISD X11, X11               // c441792edb
-	//TODO: VUCOMISS (BX), X2               // c4e1782e13 or c5f82e13
-	//TODO: VUCOMISS (R11), X2              // c4c1782e13
-	//TODO: VUCOMISS X2, X2                 // c4e1782ed2 or c5f82ed2
-	//TODO: VUCOMISS X11, X2                // c4c1782ed3
-	//TODO: VUCOMISS (BX), X11              // c461782e1b or c5782e1b
-	//TODO: VUCOMISS (R11), X11             // c441782e1b
-	//TODO: VUCOMISS X2, X11                // c461782eda or c5782eda
-	//TODO: VUCOMISS X11, X11               // c441782edb
-	//TODO: VUNPCKHPD (BX), X9, X2          // c4e1311513 or c5b11513
-	//TODO: VUNPCKHPD (R11), X9, X2         // c4c1311513
-	//TODO: VUNPCKHPD X2, X9, X2            // c4e13115d2 or c5b115d2
-	//TODO: VUNPCKHPD X11, X9, X2           // c4c13115d3
-	//TODO: VUNPCKHPD (BX), X9, X11         // c46131151b or c531151b
-	//TODO: VUNPCKHPD (R11), X9, X11        // c44131151b
-	//TODO: VUNPCKHPD X2, X9, X11           // c4613115da or c53115da
-	//TODO: VUNPCKHPD X11, X9, X11          // c4413115db
-	//TODO: VUNPCKHPD (BX), Y15, Y2         // c4e1051513 or c5851513
-	//TODO: VUNPCKHPD (R11), Y15, Y2        // c4c1051513
-	//TODO: VUNPCKHPD Y2, Y15, Y2           // c4e10515d2 or c58515d2
-	//TODO: VUNPCKHPD Y11, Y15, Y2          // c4c10515d3
-	//TODO: VUNPCKHPD (BX), Y15, Y11        // c46105151b or c505151b
-	//TODO: VUNPCKHPD (R11), Y15, Y11       // c44105151b
-	//TODO: VUNPCKHPD Y2, Y15, Y11          // c4610515da or c50515da
-	//TODO: VUNPCKHPD Y11, Y15, Y11         // c4410515db
-	//TODO: VUNPCKHPS (BX), X9, X2          // c4e1301513 or c5b01513
-	//TODO: VUNPCKHPS (R11), X9, X2         // c4c1301513
-	//TODO: VUNPCKHPS X2, X9, X2            // c4e13015d2 or c5b015d2
-	//TODO: VUNPCKHPS X11, X9, X2           // c4c13015d3
-	//TODO: VUNPCKHPS (BX), X9, X11         // c46130151b or c530151b
-	//TODO: VUNPCKHPS (R11), X9, X11        // c44130151b
-	//TODO: VUNPCKHPS X2, X9, X11           // c4613015da or c53015da
-	//TODO: VUNPCKHPS X11, X9, X11          // c4413015db
-	//TODO: VUNPCKHPS (BX), Y15, Y2         // c4e1041513 or c5841513
-	//TODO: VUNPCKHPS (R11), Y15, Y2        // c4c1041513
-	//TODO: VUNPCKHPS Y2, Y15, Y2           // c4e10415d2 or c58415d2
-	//TODO: VUNPCKHPS Y11, Y15, Y2          // c4c10415d3
-	//TODO: VUNPCKHPS (BX), Y15, Y11        // c46104151b or c504151b
-	//TODO: VUNPCKHPS (R11), Y15, Y11       // c44104151b
-	//TODO: VUNPCKHPS Y2, Y15, Y11          // c4610415da or c50415da
-	//TODO: VUNPCKHPS Y11, Y15, Y11         // c4410415db
-	//TODO: VUNPCKLPD (BX), X9, X2          // c4e1311413 or c5b11413
-	//TODO: VUNPCKLPD (R11), X9, X2         // c4c1311413
-	//TODO: VUNPCKLPD X2, X9, X2            // c4e13114d2 or c5b114d2
-	//TODO: VUNPCKLPD X11, X9, X2           // c4c13114d3
-	//TODO: VUNPCKLPD (BX), X9, X11         // c46131141b or c531141b
-	//TODO: VUNPCKLPD (R11), X9, X11        // c44131141b
-	//TODO: VUNPCKLPD X2, X9, X11           // c4613114da or c53114da
-	//TODO: VUNPCKLPD X11, X9, X11          // c4413114db
-	//TODO: VUNPCKLPD (BX), Y15, Y2         // c4e1051413 or c5851413
-	//TODO: VUNPCKLPD (R11), Y15, Y2        // c4c1051413
-	//TODO: VUNPCKLPD Y2, Y15, Y2           // c4e10514d2 or c58514d2
-	//TODO: VUNPCKLPD Y11, Y15, Y2          // c4c10514d3
-	//TODO: VUNPCKLPD (BX), Y15, Y11        // c46105141b or c505141b
-	//TODO: VUNPCKLPD (R11), Y15, Y11       // c44105141b
-	//TODO: VUNPCKLPD Y2, Y15, Y11          // c4610514da or c50514da
-	//TODO: VUNPCKLPD Y11, Y15, Y11         // c4410514db
-	//TODO: VUNPCKLPS (BX), X9, X2          // c4e1301413 or c5b01413
-	//TODO: VUNPCKLPS (R11), X9, X2         // c4c1301413
-	//TODO: VUNPCKLPS X2, X9, X2            // c4e13014d2 or c5b014d2
-	//TODO: VUNPCKLPS X11, X9, X2           // c4c13014d3
-	//TODO: VUNPCKLPS (BX), X9, X11         // c46130141b or c530141b
-	//TODO: VUNPCKLPS (R11), X9, X11        // c44130141b
-	//TODO: VUNPCKLPS X2, X9, X11           // c4613014da or c53014da
-	//TODO: VUNPCKLPS X11, X9, X11          // c4413014db
-	//TODO: VUNPCKLPS (BX), Y15, Y2         // c4e1041413 or c5841413
-	//TODO: VUNPCKLPS (R11), Y15, Y2        // c4c1041413
-	//TODO: VUNPCKLPS Y2, Y15, Y2           // c4e10414d2 or c58414d2
-	//TODO: VUNPCKLPS Y11, Y15, Y2          // c4c10414d3
-	//TODO: VUNPCKLPS (BX), Y15, Y11        // c46104141b or c504141b
-	//TODO: VUNPCKLPS (R11), Y15, Y11       // c44104141b
-	//TODO: VUNPCKLPS Y2, Y15, Y11          // c4610414da or c50414da
-	//TODO: VUNPCKLPS Y11, Y15, Y11         // c4410414db
-	//TODO: VXORPD (BX), X9, X2             // c4e1315713 or c5b15713
-	//TODO: VXORPD (R11), X9, X2            // c4c1315713
-	//TODO: VXORPD X2, X9, X2               // c4e13157d2 or c5b157d2
-	//TODO: VXORPD X11, X9, X2              // c4c13157d3
-	//TODO: VXORPD (BX), X9, X11            // c46131571b or c531571b
-	//TODO: VXORPD (R11), X9, X11           // c44131571b
-	//TODO: VXORPD X2, X9, X11              // c4613157da or c53157da
-	//TODO: VXORPD X11, X9, X11             // c4413157db
-	//TODO: VXORPD (BX), Y15, Y2            // c4e1055713 or c5855713
-	//TODO: VXORPD (R11), Y15, Y2           // c4c1055713
-	//TODO: VXORPD Y2, Y15, Y2              // c4e10557d2 or c58557d2
-	//TODO: VXORPD Y11, Y15, Y2             // c4c10557d3
-	//TODO: VXORPD (BX), Y15, Y11           // c46105571b or c505571b
-	//TODO: VXORPD (R11), Y15, Y11          // c44105571b
-	//TODO: VXORPD Y2, Y15, Y11             // c4610557da or c50557da
-	//TODO: VXORPD Y11, Y15, Y11            // c4410557db
-	//TODO: VXORPS (BX), X9, X2             // c4e1305713 or c5b05713
-	//TODO: VXORPS (R11), X9, X2            // c4c1305713
-	//TODO: VXORPS X2, X9, X2               // c4e13057d2 or c5b057d2
-	//TODO: VXORPS X11, X9, X2              // c4c13057d3
-	//TODO: VXORPS (BX), X9, X11            // c46130571b or c530571b
-	//TODO: VXORPS (R11), X9, X11           // c44130571b
-	//TODO: VXORPS X2, X9, X11              // c4613057da or c53057da
-	//TODO: VXORPS X11, X9, X11             // c4413057db
-	//TODO: VXORPS (BX), Y15, Y2            // c4e1045713 or c5845713
-	//TODO: VXORPS (R11), Y15, Y2           // c4c1045713
-	//TODO: VXORPS Y2, Y15, Y2              // c4e10457d2 or c58457d2
-	//TODO: VXORPS Y11, Y15, Y2             // c4c10457d3
-	//TODO: VXORPS (BX), Y15, Y11           // c46104571b or c504571b
-	//TODO: VXORPS (R11), Y15, Y11          // c44104571b
-	//TODO: VXORPS Y2, Y15, Y11             // c4610457da or c50457da
-	//TODO: VXORPS Y11, Y15, Y11            // c4410457db
-	//TODO: VZEROALL                        // c4e17c77 or c5fc77
+	VRCPPS (BX), X2                         // c4e1785313 or c5f85313
+	VRCPPS (R11), X2                        // c4c1785313
+	VRCPPS X2, X2                           // c4e17853d2 or c5f853d2
+	VRCPPS X11, X2                          // c4c17853d3
+	VRCPPS (BX), X11                        // c46178531b or c578531b
+	VRCPPS (R11), X11                       // c44178531b
+	VRCPPS X2, X11                          // c4617853da or c57853da
+	VRCPPS X11, X11                         // c4417853db
+	VRCPPS (BX), Y2                         // c4e17c5313 or c5fc5313
+	VRCPPS (R11), Y2                        // c4c17c5313
+	VRCPPS Y2, Y2                           // c4e17c53d2 or c5fc53d2
+	VRCPPS Y11, Y2                          // c4c17c53d3
+	VRCPPS (BX), Y11                        // c4617c531b or c57c531b
+	VRCPPS (R11), Y11                       // c4417c531b
+	VRCPPS Y2, Y11                          // c4617c53da or c57c53da
+	VRCPPS Y11, Y11                         // c4417c53db
+	VRCPSS (BX), X9, X2                     // c4e1325313 or c5b25313
+	VRCPSS (R11), X9, X2                    // c4c1325313
+	VRCPSS X2, X9, X2                       // c4e13253d2 or c5b253d2
+	VRCPSS X11, X9, X2                      // c4c13253d3
+	VRCPSS (BX), X9, X11                    // c46132531b or c532531b
+	VRCPSS (R11), X9, X11                   // c44132531b
+	VRCPSS X2, X9, X11                      // c4613253da or c53253da
+	VRCPSS X11, X9, X11                     // c4413253db
+	VROUNDPD $7, (BX), X2                   // c4e379091307
+	VROUNDPD $7, (R11), X2                  // c4c379091307
+	VROUNDPD $7, X2, X2                     // c4e37909d207
+	VROUNDPD $7, X11, X2                    // c4c37909d307
+	VROUNDPD $7, (BX), X11                  // c46379091b07
+	VROUNDPD $7, (R11), X11                 // c44379091b07
+	VROUNDPD $7, X2, X11                    // c4637909da07
+	VROUNDPD $7, X11, X11                   // c4437909db07
+	VROUNDPD $7, (BX), Y2                   // c4e37d091307
+	VROUNDPD $7, (R11), Y2                  // c4c37d091307
+	VROUNDPD $7, Y2, Y2                     // c4e37d09d207
+	VROUNDPD $7, Y11, Y2                    // c4c37d09d307
+	VROUNDPD $7, (BX), Y11                  // c4637d091b07
+	VROUNDPD $7, (R11), Y11                 // c4437d091b07
+	VROUNDPD $7, Y2, Y11                    // c4637d09da07
+	VROUNDPD $7, Y11, Y11                   // c4437d09db07
+	VROUNDPS $7, (BX), X2                   // c4e379081307
+	VROUNDPS $7, (R11), X2                  // c4c379081307
+	VROUNDPS $7, X2, X2                     // c4e37908d207
+	VROUNDPS $7, X11, X2                    // c4c37908d307
+	VROUNDPS $7, (BX), X11                  // c46379081b07
+	VROUNDPS $7, (R11), X11                 // c44379081b07
+	VROUNDPS $7, X2, X11                    // c4637908da07
+	VROUNDPS $7, X11, X11                   // c4437908db07
+	VROUNDPS $7, (BX), Y2                   // c4e37d081307
+	VROUNDPS $7, (R11), Y2                  // c4c37d081307
+	VROUNDPS $7, Y2, Y2                     // c4e37d08d207
+	VROUNDPS $7, Y11, Y2                    // c4c37d08d307
+	VROUNDPS $7, (BX), Y11                  // c4637d081b07
+	VROUNDPS $7, (R11), Y11                 // c4437d081b07
+	VROUNDPS $7, Y2, Y11                    // c4637d08da07
+	VROUNDPS $7, Y11, Y11                   // c4437d08db07
+	VROUNDSD $7, (BX), X9, X2               // c4e3310b1307
+	VROUNDSD $7, (R11), X9, X2              // c4c3310b1307
+	VROUNDSD $7, X2, X9, X2                 // c4e3310bd207
+	VROUNDSD $7, X11, X9, X2                // c4c3310bd307
+	VROUNDSD $7, (BX), X9, X11              // c463310b1b07
+	VROUNDSD $7, (R11), X9, X11             // c443310b1b07
+	VROUNDSD $7, X2, X9, X11                // c463310bda07
+	VROUNDSD $7, X11, X9, X11               // c443310bdb07
+	VROUNDSS $7, (BX), X9, X2               // c4e3310a1307
+	VROUNDSS $7, (R11), X9, X2              // c4c3310a1307
+	VROUNDSS $7, X2, X9, X2                 // c4e3310ad207
+	VROUNDSS $7, X11, X9, X2                // c4c3310ad307
+	VROUNDSS $7, (BX), X9, X11              // c463310a1b07
+	VROUNDSS $7, (R11), X9, X11             // c443310a1b07
+	VROUNDSS $7, X2, X9, X11                // c463310ada07
+	VROUNDSS $7, X11, X9, X11               // c443310adb07
+	VRSQRTPS (BX), X2                       // c4e1785213 or c5f85213
+	VRSQRTPS (R11), X2                      // c4c1785213
+	VRSQRTPS X2, X2                         // c4e17852d2 or c5f852d2
+	VRSQRTPS X11, X2                        // c4c17852d3
+	VRSQRTPS (BX), X11                      // c46178521b or c578521b
+	VRSQRTPS (R11), X11                     // c44178521b
+	VRSQRTPS X2, X11                        // c4617852da or c57852da
+	VRSQRTPS X11, X11                       // c4417852db
+	VRSQRTPS (BX), Y2                       // c4e17c5213 or c5fc5213
+	VRSQRTPS (R11), Y2                      // c4c17c5213
+	VRSQRTPS Y2, Y2                         // c4e17c52d2 or c5fc52d2
+	VRSQRTPS Y11, Y2                        // c4c17c52d3
+	VRSQRTPS (BX), Y11                      // c4617c521b or c57c521b
+	VRSQRTPS (R11), Y11                     // c4417c521b
+	VRSQRTPS Y2, Y11                        // c4617c52da or c57c52da
+	VRSQRTPS Y11, Y11                       // c4417c52db
+	VRSQRTSS (BX), X9, X2                   // c4e1325213 or c5b25213
+	VRSQRTSS (R11), X9, X2                  // c4c1325213
+	VRSQRTSS X2, X9, X2                     // c4e13252d2 or c5b252d2
+	VRSQRTSS X11, X9, X2                    // c4c13252d3
+	VRSQRTSS (BX), X9, X11                  // c46132521b or c532521b
+	VRSQRTSS (R11), X9, X11                 // c44132521b
+	VRSQRTSS X2, X9, X11                    // c4613252da or c53252da
+	VRSQRTSS X11, X9, X11                   // c4413252db
+	VSHUFPD $7, (BX), X9, X2                // c4e131c61307 or c5b1c61307
+	VSHUFPD $7, (R11), X9, X2               // c4c131c61307
+	VSHUFPD $7, X2, X9, X2                  // c4e131c6d207 or c5b1c6d207
+	VSHUFPD $7, X11, X9, X2                 // c4c131c6d307
+	VSHUFPD $7, (BX), X9, X11               // c46131c61b07 or c531c61b07
+	VSHUFPD $7, (R11), X9, X11              // c44131c61b07
+	VSHUFPD $7, X2, X9, X11                 // c46131c6da07 or c531c6da07
+	VSHUFPD $7, X11, X9, X11                // c44131c6db07
+	VSHUFPD $7, (BX), Y15, Y2               // c4e105c61307 or c585c61307
+	VSHUFPD $7, (R11), Y15, Y2              // c4c105c61307
+	VSHUFPD $7, Y2, Y15, Y2                 // c4e105c6d207 or c585c6d207
+	VSHUFPD $7, Y11, Y15, Y2                // c4c105c6d307
+	VSHUFPD $7, (BX), Y15, Y11              // c46105c61b07 or c505c61b07
+	VSHUFPD $7, (R11), Y15, Y11             // c44105c61b07
+	VSHUFPD $7, Y2, Y15, Y11                // c46105c6da07 or c505c6da07
+	VSHUFPD $7, Y11, Y15, Y11               // c44105c6db07
+	VSHUFPS $7, (BX), X9, X2                // c4e130c61307 or c5b0c61307
+	VSHUFPS $7, (R11), X9, X2               // c4c130c61307
+	VSHUFPS $7, X2, X9, X2                  // c4e130c6d207 or c5b0c6d207
+	VSHUFPS $7, X11, X9, X2                 // c4c130c6d307
+	VSHUFPS $7, (BX), X9, X11               // c46130c61b07 or c530c61b07
+	VSHUFPS $7, (R11), X9, X11              // c44130c61b07
+	VSHUFPS $7, X2, X9, X11                 // c46130c6da07 or c530c6da07
+	VSHUFPS $7, X11, X9, X11                // c44130c6db07
+	VSHUFPS $7, (BX), Y15, Y2               // c4e104c61307 or c584c61307
+	VSHUFPS $7, (R11), Y15, Y2              // c4c104c61307
+	VSHUFPS $7, Y2, Y15, Y2                 // c4e104c6d207 or c584c6d207
+	VSHUFPS $7, Y11, Y15, Y2                // c4c104c6d307
+	VSHUFPS $7, (BX), Y15, Y11              // c46104c61b07 or c504c61b07
+	VSHUFPS $7, (R11), Y15, Y11             // c44104c61b07
+	VSHUFPS $7, Y2, Y15, Y11                // c46104c6da07 or c504c6da07
+	VSHUFPS $7, Y11, Y15, Y11               // c44104c6db07
+	VSQRTPD (BX), X2                        // c4e1795113 or c5f95113
+	VSQRTPD (R11), X2                       // c4c1795113
+	VSQRTPD X2, X2                          // c4e17951d2 or c5f951d2
+	VSQRTPD X11, X2                         // c4c17951d3
+	VSQRTPD (BX), X11                       // c46179511b or c579511b
+	VSQRTPD (R11), X11                      // c44179511b
+	VSQRTPD X2, X11                         // c4617951da or c57951da
+	VSQRTPD X11, X11                        // c4417951db
+	VSQRTPD (BX), Y2                        // c4e17d5113 or c5fd5113
+	VSQRTPD (R11), Y2                       // c4c17d5113
+	VSQRTPD Y2, Y2                          // c4e17d51d2 or c5fd51d2
+	VSQRTPD Y11, Y2                         // c4c17d51d3
+	VSQRTPD (BX), Y11                       // c4617d511b or c57d511b
+	VSQRTPD (R11), Y11                      // c4417d511b
+	VSQRTPD Y2, Y11                         // c4617d51da or c57d51da
+	VSQRTPD Y11, Y11                        // c4417d51db
+	VSQRTPS (BX), X2                        // c4e1785113 or c5f85113
+	VSQRTPS (R11), X2                       // c4c1785113
+	VSQRTPS X2, X2                          // c4e17851d2 or c5f851d2
+	VSQRTPS X11, X2                         // c4c17851d3
+	VSQRTPS (BX), X11                       // c46178511b or c578511b
+	VSQRTPS (R11), X11                      // c44178511b
+	VSQRTPS X2, X11                         // c4617851da or c57851da
+	VSQRTPS X11, X11                        // c4417851db
+	VSQRTPS (BX), Y2                        // c4e17c5113 or c5fc5113
+	VSQRTPS (R11), Y2                       // c4c17c5113
+	VSQRTPS Y2, Y2                          // c4e17c51d2 or c5fc51d2
+	VSQRTPS Y11, Y2                         // c4c17c51d3
+	VSQRTPS (BX), Y11                       // c4617c511b or c57c511b
+	VSQRTPS (R11), Y11                      // c4417c511b
+	VSQRTPS Y2, Y11                         // c4617c51da or c57c51da
+	VSQRTPS Y11, Y11                        // c4417c51db
+	VSQRTSD (BX), X9, X2                    // c4e1335113 or c5b35113
+	VSQRTSD (R11), X9, X2                   // c4c1335113
+	VSQRTSD X2, X9, X2                      // c4e13351d2 or c5b351d2
+	VSQRTSD X11, X9, X2                     // c4c13351d3
+	VSQRTSD (BX), X9, X11                   // c46133511b or c533511b
+	VSQRTSD (R11), X9, X11                  // c44133511b
+	VSQRTSD X2, X9, X11                     // c4613351da or c53351da
+	VSQRTSD X11, X9, X11                    // c4413351db
+	VSQRTSS (BX), X9, X2                    // c4e1325113 or c5b25113
+	VSQRTSS (R11), X9, X2                   // c4c1325113
+	VSQRTSS X2, X9, X2                      // c4e13251d2 or c5b251d2
+	VSQRTSS X11, X9, X2                     // c4c13251d3
+	VSQRTSS (BX), X9, X11                   // c46132511b or c532511b
+	VSQRTSS (R11), X9, X11                  // c44132511b
+	VSQRTSS X2, X9, X11                     // c4613251da or c53251da
+	VSQRTSS X11, X9, X11                    // c4413251db
+	VSTMXCSR (BX)                           // c4e178ae1b or c5f8ae1b
+	VSTMXCSR (R11)                          // c4c178ae1b
+	VSUBPD (BX), X9, X2                     // c4e1315c13 or c5b15c13
+	VSUBPD (R11), X9, X2                    // c4c1315c13
+	VSUBPD X2, X9, X2                       // c4e1315cd2 or c5b15cd2
+	VSUBPD X11, X9, X2                      // c4c1315cd3
+	VSUBPD (BX), X9, X11                    // c461315c1b or c5315c1b
+	VSUBPD (R11), X9, X11                   // c441315c1b
+	VSUBPD X2, X9, X11                      // c461315cda or c5315cda
+	VSUBPD X11, X9, X11                     // c441315cdb
+	VSUBPD (BX), Y15, Y2                    // c4e1055c13 or c5855c13
+	VSUBPD (R11), Y15, Y2                   // c4c1055c13
+	VSUBPD Y2, Y15, Y2                      // c4e1055cd2 or c5855cd2
+	VSUBPD Y11, Y15, Y2                     // c4c1055cd3
+	VSUBPD (BX), Y15, Y11                   // c461055c1b or c5055c1b
+	VSUBPD (R11), Y15, Y11                  // c441055c1b
+	VSUBPD Y2, Y15, Y11                     // c461055cda or c5055cda
+	VSUBPD Y11, Y15, Y11                    // c441055cdb
+	VSUBPS (BX), X9, X2                     // c4e1305c13 or c5b05c13
+	VSUBPS (R11), X9, X2                    // c4c1305c13
+	VSUBPS X2, X9, X2                       // c4e1305cd2 or c5b05cd2
+	VSUBPS X11, X9, X2                      // c4c1305cd3
+	VSUBPS (BX), X9, X11                    // c461305c1b or c5305c1b
+	VSUBPS (R11), X9, X11                   // c441305c1b
+	VSUBPS X2, X9, X11                      // c461305cda or c5305cda
+	VSUBPS X11, X9, X11                     // c441305cdb
+	VSUBPS (BX), Y15, Y2                    // c4e1045c13 or c5845c13
+	VSUBPS (R11), Y15, Y2                   // c4c1045c13
+	VSUBPS Y2, Y15, Y2                      // c4e1045cd2 or c5845cd2
+	VSUBPS Y11, Y15, Y2                     // c4c1045cd3
+	VSUBPS (BX), Y15, Y11                   // c461045c1b or c5045c1b
+	VSUBPS (R11), Y15, Y11                  // c441045c1b
+	VSUBPS Y2, Y15, Y11                     // c461045cda or c5045cda
+	VSUBPS Y11, Y15, Y11                    // c441045cdb
+	VSUBSD (BX), X9, X2                     // c4e1335c13 or c5b35c13
+	VSUBSD (R11), X9, X2                    // c4c1335c13
+	VSUBSD X2, X9, X2                       // c4e1335cd2 or c5b35cd2
+	VSUBSD X11, X9, X2                      // c4c1335cd3
+	VSUBSD (BX), X9, X11                    // c461335c1b or c5335c1b
+	VSUBSD (R11), X9, X11                   // c441335c1b
+	VSUBSD X2, X9, X11                      // c461335cda or c5335cda
+	VSUBSD X11, X9, X11                     // c441335cdb
+	VSUBSS (BX), X9, X2                     // c4e1325c13 or c5b25c13
+	VSUBSS (R11), X9, X2                    // c4c1325c13
+	VSUBSS X2, X9, X2                       // c4e1325cd2 or c5b25cd2
+	VSUBSS X11, X9, X2                      // c4c1325cd3
+	VSUBSS (BX), X9, X11                    // c461325c1b or c5325c1b
+	VSUBSS (R11), X9, X11                   // c441325c1b
+	VSUBSS X2, X9, X11                      // c461325cda or c5325cda
+	VSUBSS X11, X9, X11                     // c441325cdb
+	VTESTPD (BX), X2                        // c4e2790f13
+	VTESTPD (R11), X2                       // c4c2790f13
+	VTESTPD X2, X2                          // c4e2790fd2
+	VTESTPD X11, X2                         // c4c2790fd3
+	VTESTPD (BX), X11                       // c462790f1b
+	VTESTPD (R11), X11                      // c442790f1b
+	VTESTPD X2, X11                         // c462790fda
+	VTESTPD X11, X11                        // c442790fdb
+	VTESTPD (BX), Y2                        // c4e27d0f13
+	VTESTPD (R11), Y2                       // c4c27d0f13
+	VTESTPD Y2, Y2                          // c4e27d0fd2
+	VTESTPD Y11, Y2                         // c4c27d0fd3
+	VTESTPD (BX), Y11                       // c4627d0f1b
+	VTESTPD (R11), Y11                      // c4427d0f1b
+	VTESTPD Y2, Y11                         // c4627d0fda
+	VTESTPD Y11, Y11                        // c4427d0fdb
+	VTESTPS (BX), X2                        // c4e2790e13
+	VTESTPS (R11), X2                       // c4c2790e13
+	VTESTPS X2, X2                          // c4e2790ed2
+	VTESTPS X11, X2                         // c4c2790ed3
+	VTESTPS (BX), X11                       // c462790e1b
+	VTESTPS (R11), X11                      // c442790e1b
+	VTESTPS X2, X11                         // c462790eda
+	VTESTPS X11, X11                        // c442790edb
+	VTESTPS (BX), Y2                        // c4e27d0e13
+	VTESTPS (R11), Y2                       // c4c27d0e13
+	VTESTPS Y2, Y2                          // c4e27d0ed2
+	VTESTPS Y11, Y2                         // c4c27d0ed3
+	VTESTPS (BX), Y11                       // c4627d0e1b
+	VTESTPS (R11), Y11                      // c4427d0e1b
+	VTESTPS Y2, Y11                         // c4627d0eda
+	VTESTPS Y11, Y11                        // c4427d0edb
+	VUCOMISD (BX), X2                       // c4e1792e13 or c5f92e13
+	VUCOMISD (R11), X2                      // c4c1792e13
+	VUCOMISD X2, X2                         // c4e1792ed2 or c5f92ed2
+	VUCOMISD X11, X2                        // c4c1792ed3
+	VUCOMISD (BX), X11                      // c461792e1b or c5792e1b
+	VUCOMISD (R11), X11                     // c441792e1b
+	VUCOMISD X2, X11                        // c461792eda or c5792eda
+	VUCOMISD X11, X11                       // c441792edb
+	VUCOMISS (BX), X2                       // c4e1782e13 or c5f82e13
+	VUCOMISS (R11), X2                      // c4c1782e13
+	VUCOMISS X2, X2                         // c4e1782ed2 or c5f82ed2
+	VUCOMISS X11, X2                        // c4c1782ed3
+	VUCOMISS (BX), X11                      // c461782e1b or c5782e1b
+	VUCOMISS (R11), X11                     // c441782e1b
+	VUCOMISS X2, X11                        // c461782eda or c5782eda
+	VUCOMISS X11, X11                       // c441782edb
+	VUNPCKHPD (BX), X9, X2                  // c4e1311513 or c5b11513
+	VUNPCKHPD (R11), X9, X2                 // c4c1311513
+	VUNPCKHPD X2, X9, X2                    // c4e13115d2 or c5b115d2
+	VUNPCKHPD X11, X9, X2                   // c4c13115d3
+	VUNPCKHPD (BX), X9, X11                 // c46131151b or c531151b
+	VUNPCKHPD (R11), X9, X11                // c44131151b
+	VUNPCKHPD X2, X9, X11                   // c4613115da or c53115da
+	VUNPCKHPD X11, X9, X11                  // c4413115db
+	VUNPCKHPD (BX), Y15, Y2                 // c4e1051513 or c5851513
+	VUNPCKHPD (R11), Y15, Y2                // c4c1051513
+	VUNPCKHPD Y2, Y15, Y2                   // c4e10515d2 or c58515d2
+	VUNPCKHPD Y11, Y15, Y2                  // c4c10515d3
+	VUNPCKHPD (BX), Y15, Y11                // c46105151b or c505151b
+	VUNPCKHPD (R11), Y15, Y11               // c44105151b
+	VUNPCKHPD Y2, Y15, Y11                  // c4610515da or c50515da
+	VUNPCKHPD Y11, Y15, Y11                 // c4410515db
+	VUNPCKHPS (BX), X9, X2                  // c4e1301513 or c5b01513
+	VUNPCKHPS (R11), X9, X2                 // c4c1301513
+	VUNPCKHPS X2, X9, X2                    // c4e13015d2 or c5b015d2
+	VUNPCKHPS X11, X9, X2                   // c4c13015d3
+	VUNPCKHPS (BX), X9, X11                 // c46130151b or c530151b
+	VUNPCKHPS (R11), X9, X11                // c44130151b
+	VUNPCKHPS X2, X9, X11                   // c4613015da or c53015da
+	VUNPCKHPS X11, X9, X11                  // c4413015db
+	VUNPCKHPS (BX), Y15, Y2                 // c4e1041513 or c5841513
+	VUNPCKHPS (R11), Y15, Y2                // c4c1041513
+	VUNPCKHPS Y2, Y15, Y2                   // c4e10415d2 or c58415d2
+	VUNPCKHPS Y11, Y15, Y2                  // c4c10415d3
+	VUNPCKHPS (BX), Y15, Y11                // c46104151b or c504151b
+	VUNPCKHPS (R11), Y15, Y11               // c44104151b
+	VUNPCKHPS Y2, Y15, Y11                  // c4610415da or c50415da
+	VUNPCKHPS Y11, Y15, Y11                 // c4410415db
+	VUNPCKLPD (BX), X9, X2                  // c4e1311413 or c5b11413
+	VUNPCKLPD (R11), X9, X2                 // c4c1311413
+	VUNPCKLPD X2, X9, X2                    // c4e13114d2 or c5b114d2
+	VUNPCKLPD X11, X9, X2                   // c4c13114d3
+	VUNPCKLPD (BX), X9, X11                 // c46131141b or c531141b
+	VUNPCKLPD (R11), X9, X11                // c44131141b
+	VUNPCKLPD X2, X9, X11                   // c4613114da or c53114da
+	VUNPCKLPD X11, X9, X11                  // c4413114db
+	VUNPCKLPD (BX), Y15, Y2                 // c4e1051413 or c5851413
+	VUNPCKLPD (R11), Y15, Y2                // c4c1051413
+	VUNPCKLPD Y2, Y15, Y2                   // c4e10514d2 or c58514d2
+	VUNPCKLPD Y11, Y15, Y2                  // c4c10514d3
+	VUNPCKLPD (BX), Y15, Y11                // c46105141b or c505141b
+	VUNPCKLPD (R11), Y15, Y11               // c44105141b
+	VUNPCKLPD Y2, Y15, Y11                  // c4610514da or c50514da
+	VUNPCKLPD Y11, Y15, Y11                 // c4410514db
+	VUNPCKLPS (BX), X9, X2                  // c4e1301413 or c5b01413
+	VUNPCKLPS (R11), X9, X2                 // c4c1301413
+	VUNPCKLPS X2, X9, X2                    // c4e13014d2 or c5b014d2
+	VUNPCKLPS X11, X9, X2                   // c4c13014d3
+	VUNPCKLPS (BX), X9, X11                 // c46130141b or c530141b
+	VUNPCKLPS (R11), X9, X11                // c44130141b
+	VUNPCKLPS X2, X9, X11                   // c4613014da or c53014da
+	VUNPCKLPS X11, X9, X11                  // c4413014db
+	VUNPCKLPS (BX), Y15, Y2                 // c4e1041413 or c5841413
+	VUNPCKLPS (R11), Y15, Y2                // c4c1041413
+	VUNPCKLPS Y2, Y15, Y2                   // c4e10414d2 or c58414d2
+	VUNPCKLPS Y11, Y15, Y2                  // c4c10414d3
+	VUNPCKLPS (BX), Y15, Y11                // c46104141b or c504141b
+	VUNPCKLPS (R11), Y15, Y11               // c44104141b
+	VUNPCKLPS Y2, Y15, Y11                  // c4610414da or c50414da
+	VUNPCKLPS Y11, Y15, Y11                 // c4410414db
+	VXORPD (BX), X9, X2                     // c4e1315713 or c5b15713
+	VXORPD (R11), X9, X2                    // c4c1315713
+	VXORPD X2, X9, X2                       // c4e13157d2 or c5b157d2
+	VXORPD X11, X9, X2                      // c4c13157d3
+	VXORPD (BX), X9, X11                    // c46131571b or c531571b
+	VXORPD (R11), X9, X11                   // c44131571b
+	VXORPD X2, X9, X11                      // c4613157da or c53157da
+	VXORPD X11, X9, X11                     // c4413157db
+	VXORPD (BX), Y15, Y2                    // c4e1055713 or c5855713
+	VXORPD (R11), Y15, Y2                   // c4c1055713
+	VXORPD Y2, Y15, Y2                      // c4e10557d2 or c58557d2
+	VXORPD Y11, Y15, Y2                     // c4c10557d3
+	VXORPD (BX), Y15, Y11                   // c46105571b or c505571b
+	VXORPD (R11), Y15, Y11                  // c44105571b
+	VXORPD Y2, Y15, Y11                     // c4610557da or c50557da
+	VXORPD Y11, Y15, Y11                    // c4410557db
+	VXORPS (BX), X9, X2                     // c4e1305713 or c5b05713
+	VXORPS (R11), X9, X2                    // c4c1305713
+	VXORPS X2, X9, X2                       // c4e13057d2 or c5b057d2
+	VXORPS X11, X9, X2                      // c4c13057d3
+	VXORPS (BX), X9, X11                    // c46130571b or c530571b
+	VXORPS (R11), X9, X11                   // c44130571b
+	VXORPS X2, X9, X11                      // c4613057da or c53057da
+	VXORPS X11, X9, X11                     // c4413057db
+	VXORPS (BX), Y15, Y2                    // c4e1045713 or c5845713
+	VXORPS (R11), Y15, Y2                   // c4c1045713
+	VXORPS Y2, Y15, Y2                      // c4e10457d2 or c58457d2
+	VXORPS Y11, Y15, Y2                     // c4c10457d3
+	VXORPS (BX), Y15, Y11                   // c46104571b or c504571b
+	VXORPS (R11), Y15, Y11                  // c44104571b
+	VXORPS Y2, Y15, Y11                     // c4610457da or c50457da
+	VXORPS Y11, Y15, Y11                    // c4410457db
+	VZEROALL                                // c4e17c77 or c5fc77
 	VZEROUPPER                              // c4e17877 or c5f877
 	WBINVD                                  // 0f09
 	//TODO: WRFSBASE DX                     // f30faed2 or f3480faed2
diff --git a/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s b/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s
new file mode 100644
index 0000000..a5bcb0f
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s
@@ -0,0 +1,239 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This input extends auto-generated amd64enc.s test suite
+// with manually added tests.
+
+#include "../../../../../runtime/textflag.h"
+
+TEXT asmtest(SB),DUPOK|NOSPLIT,$0
+	// AVX2GATHER: basic combinations.
+	VPGATHERDQ Y2, (BP)(X7*2), Y1           // c4e2ed904c7d00
+	VPGATHERDQ X12, (R13)(X14*2), X11       // c40299905c7500
+	VPGATHERDQ Y12, (R13)(X14*2), Y11       // c4029d905c7500
+	VPGATHERDQ Y0, 8(X4*1), Y6              // c4e2fd90342508000000
+	VPGATHERDQ Y0, -8(X4*1), Y6             // c4e2fd903425f8ffffff
+	VPGATHERDQ Y0, 0(X4*1), Y6              // c4e2fd90342500000000
+	VPGATHERDQ Y0, 664(X4*1), Y6            // c4e2fd90342598020000
+	VPGATHERDQ Y0, 8(X4*8), Y6              // c4e2fd9034e508000000
+	VPGATHERDQ Y0, -8(X4*8), Y6             // c4e2fd9034e5f8ffffff
+	VPGATHERDQ Y0, 0(X4*8), Y6              // c4e2fd9034e500000000
+	VPGATHERDQ Y0, 664(X4*8), Y6            // c4e2fd9034e598020000
+	VPGATHERDQ Y0, 8(X14*1), Y6             // c4a2fd90343508000000
+	VPGATHERDQ Y0, -8(X14*1), Y6            // c4a2fd903435f8ffffff
+	VPGATHERDQ Y0, 0(X14*1), Y6             // c4a2fd90343500000000
+	VPGATHERDQ Y0, 664(X14*1), Y6           // c4a2fd90343598020000
+	VPGATHERDQ Y0, 8(X14*8), Y6             // c4a2fd9034f508000000
+	VPGATHERDQ Y0, -8(X14*8), Y6            // c4a2fd9034f5f8ffffff
+	VPGATHERDQ Y0, 0(X14*8), Y6             // c4a2fd9034f500000000
+	VPGATHERDQ Y0, 664(X14*8), Y6           // c4a2fd9034f598020000
+	VPGATHERDQ X2, (BP)(X7*2), X1           // c4e2e9904c7d00
+	VPGATHERDQ Y2, (BP)(X7*2), Y1           // c4e2ed904c7d00
+	VPGATHERDQ X12, (R13)(X14*2), X11       // c40299905c7500
+	VPGATHERDQ Y12, (R13)(X14*2), Y11       // c4029d905c7500
+	VPGATHERDQ Y0, 8(X4*1), Y6              // c4e2fd90342508000000
+	VPGATHERDQ Y0, -8(X4*1), Y6             // c4e2fd903425f8ffffff
+	VPGATHERDQ Y0, 0(X4*1), Y6              // c4e2fd90342500000000
+	VPGATHERDQ Y0, 664(X4*1), Y6            // c4e2fd90342598020000
+	VPGATHERDQ Y0, 8(X4*8), Y6              // c4e2fd9034e508000000
+	VPGATHERDQ Y0, -8(X4*8), Y6             // c4e2fd9034e5f8ffffff
+	VPGATHERDQ Y0, 0(X4*8), Y6              // c4e2fd9034e500000000
+	VPGATHERDQ Y0, 664(X4*8), Y6            // c4e2fd9034e598020000
+	VPGATHERDQ Y0, 8(X14*1), Y6             // c4a2fd90343508000000
+	VPGATHERDQ Y0, -8(X14*1), Y6            // c4a2fd903435f8ffffff
+	VPGATHERDQ Y0, 0(X14*1), Y6             // c4a2fd90343500000000
+	VPGATHERDQ Y0, 664(X14*1), Y6           // c4a2fd90343598020000
+	VPGATHERDQ Y0, 8(X14*8), Y6             // c4a2fd9034f508000000
+	VPGATHERDQ Y0, -8(X14*8), Y6            // c4a2fd9034f5f8ffffff
+	VPGATHERDQ Y0, 0(X14*8), Y6             // c4a2fd9034f500000000
+	VPGATHERDQ Y0, 664(X14*8), Y6           // c4a2fd9034f598020000
+	VPGATHERQQ X2, (BP)(X7*2), X1           // c4e2e9914c7d00
+	VPGATHERQQ Y2, (BP)(Y7*2), Y1           // c4e2ed914c7d00
+	VPGATHERQQ X12, (R13)(X14*2), X11       // c40299915c7500
+	VPGATHERQQ Y12, (R13)(Y14*2), Y11       // c4029d915c7500
+	VPGATHERQQ X2, (BP)(X7*2), X1           // c4e2e9914c7d00
+	VPGATHERQQ Y2, (BP)(Y7*2), Y1           // c4e2ed914c7d00
+	VPGATHERQQ X12, (R13)(X14*2), X11       // c40299915c7500
+	VPGATHERQQ Y12, (R13)(Y14*2), Y11       // c4029d915c7500
+	VGATHERDPD X2, (BP)(X7*2), X1           // c4e2e9924c7d00
+	VGATHERDPD Y2, (BP)(X7*2), Y1           // c4e2ed924c7d00
+	VGATHERDPD X12, (R13)(X14*2), X11       // c40299925c7500
+	VGATHERDPD Y12, (R13)(X14*2), Y11       // c4029d925c7500
+	VGATHERDPD Y0, 8(X4*1), Y6              // c4e2fd92342508000000
+	VGATHERDPD Y0, -8(X4*1), Y6             // c4e2fd923425f8ffffff
+	VGATHERDPD Y0, 0(X4*1), Y6              // c4e2fd92342500000000
+	VGATHERDPD Y0, 664(X4*1), Y6            // c4e2fd92342598020000
+	VGATHERDPD Y0, 8(X4*8), Y6              // c4e2fd9234e508000000
+	VGATHERDPD Y0, -8(X4*8), Y6             // c4e2fd9234e5f8ffffff
+	VGATHERDPD Y0, 0(X4*8), Y6              // c4e2fd9234e500000000
+	VGATHERDPD Y0, 664(X4*8), Y6            // c4e2fd9234e598020000
+	VGATHERDPD Y0, 8(X14*1), Y6             // c4a2fd92343508000000
+	VGATHERDPD Y0, -8(X14*1), Y6            // c4a2fd923435f8ffffff
+	VGATHERDPD Y0, 0(X14*1), Y6             // c4a2fd92343500000000
+	VGATHERDPD Y0, 664(X14*1), Y6           // c4a2fd92343598020000
+	VGATHERDPD Y0, 8(X14*8), Y6             // c4a2fd9234f508000000
+	VGATHERDPD Y0, -8(X14*8), Y6            // c4a2fd9234f5f8ffffff
+	VGATHERDPD Y0, 0(X14*8), Y6             // c4a2fd9234f500000000
+	VGATHERDPD Y0, 664(X14*8), Y6           // c4a2fd9234f598020000
+	VGATHERDPD X2, (BP)(X7*2), X1           // c4e2e9924c7d00
+	VGATHERDPD Y2, (BP)(X7*2), Y1           // c4e2ed924c7d00
+	VGATHERDPD X12, (R13)(X14*2), X11       // c40299925c7500
+	VGATHERDPD Y12, (R13)(X14*2), Y11       // c4029d925c7500
+	VGATHERDPD Y0, 8(X4*1), Y6              // c4e2fd92342508000000
+	VGATHERDPD Y0, -8(X4*1), Y6             // c4e2fd923425f8ffffff
+	VGATHERDPD Y0, 0(X4*1), Y6              // c4e2fd92342500000000
+	VGATHERDPD Y0, 664(X4*1), Y6            // c4e2fd92342598020000
+	VGATHERDPD Y0, 8(X4*8), Y6              // c4e2fd9234e508000000
+	VGATHERDPD Y0, -8(X4*8), Y6             // c4e2fd9234e5f8ffffff
+	VGATHERDPD Y0, 0(X4*8), Y6              // c4e2fd9234e500000000
+	VGATHERDPD Y0, 664(X4*8), Y6            // c4e2fd9234e598020000
+	VGATHERDPD Y0, 8(X14*1), Y6             // c4a2fd92343508000000
+	VGATHERDPD Y0, -8(X14*1), Y6            // c4a2fd923435f8ffffff
+	VGATHERDPD Y0, 0(X14*1), Y6             // c4a2fd92343500000000
+	VGATHERDPD Y0, 664(X14*1), Y6           // c4a2fd92343598020000
+	VGATHERDPD Y0, 8(X14*8), Y6             // c4a2fd9234f508000000
+	VGATHERDPD Y0, -8(X14*8), Y6            // c4a2fd9234f5f8ffffff
+	VGATHERDPD Y0, 0(X14*8), Y6             // c4a2fd9234f500000000
+	VGATHERDPD Y0, 664(X14*8), Y6           // c4a2fd9234f598020000
+	VGATHERQPD X2, (BP)(X7*2), X1           // c4e2e9934c7d00
+	VGATHERQPD Y2, (BP)(Y7*2), Y1           // c4e2ed934c7d00
+	VGATHERQPD X12, (R13)(X14*2), X11       // c40299935c7500
+	VGATHERQPD Y12, (R13)(Y14*2), Y11       // c4029d935c7500
+	VGATHERQPD X2, (BP)(X7*2), X1           // c4e2e9934c7d00
+	VGATHERQPD Y2, (BP)(Y7*2), Y1           // c4e2ed934c7d00
+	VGATHERQPD X12, (R13)(X14*2), X11       // c40299935c7500
+	VGATHERQPD Y12, (R13)(Y14*2), Y11       // c4029d935c7500
+	VGATHERDPS X2, (BP)(X7*2), X1           // c4e269924c7d00
+	VGATHERDPS Y2, (BP)(Y7*2), Y1           // c4e26d924c7d00
+	VGATHERDPS X12, (R13)(X14*2), X11       // c40219925c7500
+	VGATHERDPS Y12, (R13)(Y14*2), Y11       // c4021d925c7500
+	VGATHERDPS X3, 8(X4*1), X6              // c4e26192342508000000
+	VGATHERDPS X3, -8(X4*1), X6             // c4e261923425f8ffffff
+	VGATHERDPS X3, 0(X4*1), X6              // c4e26192342500000000
+	VGATHERDPS X3, 664(X4*1), X6            // c4e26192342598020000
+	VGATHERDPS X3, 8(X4*8), X6              // c4e2619234e508000000
+	VGATHERDPS X3, -8(X4*8), X6             // c4e2619234e5f8ffffff
+	VGATHERDPS X3, 0(X4*8), X6              // c4e2619234e500000000
+	VGATHERDPS X3, 664(X4*8), X6            // c4e2619234e598020000
+	VGATHERDPS X3, 8(X14*1), X6             // c4a26192343508000000
+	VGATHERDPS X3, -8(X14*1), X6            // c4a261923435f8ffffff
+	VGATHERDPS X3, 0(X14*1), X6             // c4a26192343500000000
+	VGATHERDPS X3, 664(X14*1), X6           // c4a26192343598020000
+	VGATHERDPS X3, 8(X14*8), X6             // c4a2619234f508000000
+	VGATHERDPS X3, -8(X14*8), X6            // c4a2619234f5f8ffffff
+	VGATHERDPS X3, 0(X14*8), X6             // c4a2619234f500000000
+	VGATHERDPS X3, 664(X14*8), X6           // c4a2619234f598020000
+	VGATHERDPS X2, (BP)(X7*2), X1           // c4e269924c7d00
+	VGATHERDPS Y2, (BP)(Y7*2), Y1           // c4e26d924c7d00
+	VGATHERDPS X12, (R13)(X14*2), X11       // c40219925c7500
+	VGATHERDPS Y12, (R13)(Y14*2), Y11       // c4021d925c7500
+	VGATHERDPS X5, 8(X4*1), X6              // c4e25192342508000000
+	VGATHERDPS X3, -8(X4*1), X6             // c4e261923425f8ffffff
+	VGATHERDPS X3, 0(X4*1), X6              // c4e26192342500000000
+	VGATHERDPS X3, 664(X4*1), X6            // c4e26192342598020000
+	VGATHERDPS X3, 8(X4*8), X6              // c4e2619234e508000000
+	VGATHERDPS X3, -8(X4*8), X6             // c4e2619234e5f8ffffff
+	VGATHERDPS X3, 0(X4*8), X6              // c4e2619234e500000000
+	VGATHERDPS X3, 664(X4*8), X6            // c4e2619234e598020000
+	VGATHERDPS X3, 8(X14*1), X6             // c4a26192343508000000
+	VGATHERDPS X3, -8(X14*1), X6            // c4a261923435f8ffffff
+	VGATHERDPS X3, 0(X14*1), X6             // c4a26192343500000000
+	VGATHERDPS X3, 664(X14*1), X6           // c4a26192343598020000
+	VGATHERDPS X3, 8(X14*8), X6             // c4a2619234f508000000
+	VGATHERDPS X3, -8(X14*8), X6            // c4a2619234f5f8ffffff
+	VGATHERDPS X3, 0(X14*8), X6             // c4a2619234f500000000
+	VGATHERDPS X3, 664(X14*8), X6           // c4a2619234f598020000
+	VGATHERQPS X2, (BP)(X7*2), X1           // c4e269934c7d00
+	VGATHERQPS X2, (BP)(Y7*2), X1           // c4e26d934c7d00
+	VGATHERQPS X12, (R13)(X14*2), X11       // c40219935c7500
+	VGATHERQPS X12, (R13)(Y14*2), X11       // c4021d935c7500
+	VGATHERQPS X2, (BP)(X7*2), X1           // c4e269934c7d00
+	VGATHERQPS X2, (BP)(Y7*2), X1           // c4e26d934c7d00
+	VGATHERQPS X12, (R13)(X14*2), X11       // c40219935c7500
+	VGATHERQPS X12, (R13)(Y14*2), X11       // c4021d935c7500
+	VPGATHERDD X2, (BP)(X7*2), X1           // c4e269904c7d00
+	VPGATHERDD Y2, (BP)(Y7*2), Y1           // c4e26d904c7d00
+	VPGATHERDD X12, (R13)(X14*2), X11       // c40219905c7500
+	VPGATHERDD Y12, (R13)(Y14*2), Y11       // c4021d905c7500
+	VPGATHERDD X3, 8(X4*1), X6              // c4e26190342508000000
+	VPGATHERDD X3, -8(X4*1), X6             // c4e261903425f8ffffff
+	VPGATHERDD X3, 0(X4*1), X6              // c4e26190342500000000
+	VPGATHERDD X3, 664(X4*1), X6            // c4e26190342598020000
+	VPGATHERDD X3, 8(X4*8), X6              // c4e2619034e508000000
+	VPGATHERDD X3, -8(X4*8), X6             // c4e2619034e5f8ffffff
+	VPGATHERDD X3, 0(X4*8), X6              // c4e2619034e500000000
+	VPGATHERDD X3, 664(X4*8), X6            // c4e2619034e598020000
+	VPGATHERDD X3, 8(X14*1), X6             // c4a26190343508000000
+	VPGATHERDD X3, -8(X14*1), X6            // c4a261903435f8ffffff
+	VPGATHERDD X3, 0(X14*1), X6             // c4a26190343500000000
+	VPGATHERDD X3, 664(X14*1), X6           // c4a26190343598020000
+	VPGATHERDD X3, 8(X14*8), X6             // c4a2619034f508000000
+	VPGATHERDD X3, -8(X14*8), X6            // c4a2619034f5f8ffffff
+	VPGATHERDD X3, 0(X14*8), X6             // c4a2619034f500000000
+	VPGATHERDD X3, 664(X14*8), X6           // c4a2619034f598020000
+	VPGATHERDD X2, (BP)(X7*2), X1           // c4e269904c7d00
+	VPGATHERDD Y2, (BP)(Y7*2), Y1           // c4e26d904c7d00
+	VPGATHERDD X12, (R13)(X14*2), X11       // c40219905c7500
+	VPGATHERDD Y12, (R13)(Y14*2), Y11       // c4021d905c7500
+	VPGATHERDD X3, 8(X4*1), X6              // c4e26190342508000000
+	VPGATHERDD X3, -8(X4*1), X6             // c4e261903425f8ffffff
+	VPGATHERDD X3, 0(X4*1), X6              // c4e26190342500000000
+	VPGATHERDD X3, 664(X4*1), X6            // c4e26190342598020000
+	VPGATHERDD X3, 8(X4*8), X6              // c4e2619034e508000000
+	VPGATHERDD X3, -8(X4*8), X6             // c4e2619034e5f8ffffff
+	VPGATHERDD X3, 0(X4*8), X6              // c4e2619034e500000000
+	VPGATHERDD X3, 664(X4*8), X6            // c4e2619034e598020000
+	VPGATHERDD X3, 8(X14*1), X6             // c4a26190343508000000
+	VPGATHERDD X3, -8(X14*1), X6            // c4a261903435f8ffffff
+	VPGATHERDD X3, 0(X14*1), X6             // c4a26190343500000000
+	VPGATHERDD X3, 664(X14*1), X6           // c4a26190343598020000
+	VPGATHERDD X3, 8(X14*8), X6             // c4a2619034f508000000
+	VPGATHERDD X3, -8(X14*8), X6            // c4a2619034f5f8ffffff
+	VPGATHERDD X3, 0(X14*8), X6             // c4a2619034f500000000
+	VPGATHERDD X3, 664(X14*8), X6           // c4a2619034f598020000
+	VPGATHERQD X2, (BP)(X7*2), X1           // c4e269914c7d00
+	VPGATHERQD X2, (BP)(Y7*2), X1           // c4e26d914c7d00
+	VPGATHERQD X12, (R13)(X14*2), X11       // c40219915c7500
+	VPGATHERQD X12, (R13)(Y14*2), X11       // c4021d915c7500
+	VPGATHERQD X2, (BP)(X7*2), X1           // c4e269914c7d00
+	VPGATHERQD X2, (BP)(Y7*2), X1           // c4e26d914c7d00
+	VPGATHERQD X12, (R13)(X14*2), X11       // c40219915c7500
+	VPGATHERQD X12, (R13)(Y14*2), X11       // c4021d915c7500
+	VPGATHERQQ X0, 0(X1*1), X2              // c4e2f991140d00000000
+	VPGATHERQQ Y0, 0(Y1*1), Y2              // c4e2fd91140d00000000
+	VPGATHERQQ X8, 0(X9*1), X10             // c422b991140d00000000
+	VPGATHERQQ Y8, 0(Y9*1), Y10             // c422bd91140d00000000
+	VPGATHERQQ X0, 0(X1*4), X2              // c4e2f991148d00000000
+	VPGATHERQQ Y0, 0(Y1*4), Y2              // c4e2fd91148d00000000
+	VPGATHERQQ X8, 0(X9*4), X10             // c422b991148d00000000
+	VPGATHERQQ Y8, 0(Y9*4), Y10             // c422bd91148d00000000
+	// AVX2GATHER: test SP/BP base with different displacements.
+	VPGATHERQQ X0, (SP)(X1*1), X2           // c4e2f991140c
+	VPGATHERQQ X0, 16(SP)(X1*1), X2         // c4e2f991540c10
+	VPGATHERQQ X0, 512(SP)(X1*1), X2        // c4e2f991940c00020000
+	VPGATHERQQ X0, (R12)(X1*1), X2          // c4c2f991140c
+	VPGATHERQQ X0, 16(R12)(X1*1), X2        // c4c2f991540c10
+	VPGATHERQQ X0, 512(R12)(X1*1), X2       // c4c2f991940c00020000
+	VPGATHERQQ X0, (BP)(X1*1), X2           // c4e2f991540d00
+	VPGATHERQQ X0, 16(BP)(X1*1), X2         // c4e2f991540d10
+	VPGATHERQQ X0, 512(BP)(X1*1), X2        // c4e2f991940d00020000
+	VPGATHERQQ X0, (R13)(X1*1), X2          // c4c2f991540d00
+	VPGATHERQQ X0, 16(R13)(X1*1), X2        // c4c2f991540d10
+	VPGATHERQQ X0, 512(R13)(X1*1), X2       // c4c2f991940d00020000
+	VPGATHERQQ Y0, (SP)(Y1*1), Y2           // c4e2fd91140c
+	VPGATHERQQ Y0, 16(SP)(Y1*1), Y2         // c4e2fd91540c10
+	VPGATHERQQ Y0, 512(SP)(Y1*1), Y2        // c4e2fd91940c00020000
+	VPGATHERQQ Y0, (R12)(Y1*1), Y2          // c4c2fd91140c
+	VPGATHERQQ Y0, 16(R12)(Y1*1), Y2        // c4c2fd91540c10
+	VPGATHERQQ Y0, 512(R12)(Y1*1), Y2       // c4c2fd91940c00020000
+	VPGATHERQQ Y0, (BP)(Y1*1), Y2           // c4e2fd91540d00
+	VPGATHERQQ Y0, 16(BP)(Y1*1), Y2         // c4e2fd91540d10
+	VPGATHERQQ Y0, 512(BP)(Y1*1), Y2        // c4e2fd91940d00020000
+	VPGATHERQQ Y0, (R13)(Y1*1), Y2          // c4c2fd91540d00
+	VPGATHERQQ Y0, 16(R13)(Y1*1), Y2        // c4c2fd91540d10
+	VPGATHERQQ Y0, 512(R13)(Y1*1), Y2       // c4c2fd91940d00020000
+	// Test low-8 register for /is4 "hr" operand.
+	VPBLENDVB X0, (BX), X1, X2              // c4e3714c1300
+	// End of tests.
+	RET
diff --git a/src/cmd/asm/internal/asm/testdata/amd64error.s b/src/cmd/asm/internal/asm/testdata/amd64error.s
index fe3ebec..7d850f7 100644
--- a/src/cmd/asm/internal/asm/testdata/amd64error.s
+++ b/src/cmd/asm/internal/asm/testdata/amd64error.s
@@ -5,4 +5,31 @@
 TEXT errors(SB),$0
 	MOVL	foo<>(SB)(AX), AX	// ERROR "invalid instruction"
 	MOVL	(AX)(SP*1), AX		// ERROR "invalid instruction"
+	EXTRACTPS $4, X2, (BX)          // ERROR "invalid instruction"
+	EXTRACTPS $-1, X2, (BX)         // ERROR "invalid instruction"
+	// VSIB addressing does not permit non-vector (X/Y)
+	// scaled index register.
+	VPGATHERDQ X12,(R13)(AX*2), X11 // ERROR "invalid instruction"
+	VPGATHERDQ X2, 664(BX*1), X1    // ERROR "invalid instruction"
+	VPGATHERDQ Y2, (BP)(AX*2), Y1   // ERROR "invalid instruction"
+	VPGATHERDQ Y5, 664(DX*8), Y6    // ERROR "invalid instruction"
+	VPGATHERDQ Y5, (DX), Y0         // ERROR "invalid instruction"
+	// VM/X rejects Y index register.
+	VPGATHERDQ Y5, 664(Y14*8), Y6   // ERROR "invalid instruction"
+	VPGATHERQQ X2, (BP)(Y7*2), X1   // ERROR "invalid instruction"
+	// VM/Y rejects X index register.
+	VPGATHERQQ Y2, (BP)(X7*2), Y1   // ERROR "invalid instruction"
+	VPGATHERDD Y5, -8(X14*8), Y6    // ERROR "invalid instruction"
+	// No VSIB for legacy instructions.
+	MOVL (AX)(X0*1), AX             // ERROR "invalid instruction"
+	MOVL (AX)(Y0*1), AX             // ERROR "invalid instruction"
+	// AVX2GATHER mask/index/dest #UD cases.
+	VPGATHERQQ Y2, (BP)(X2*2), Y2   // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERQQ Y2, (BP)(X2*2), Y7   // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERQQ Y2, (BP)(X7*2), Y2   // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERQQ Y7, (BP)(X2*2), Y2   // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERDQ X2, 664(X2*8), X2    // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERDQ X2, 664(X2*8), X7    // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERDQ X2, 664(X7*8), X2    // ERROR "mask, index, and destination registers should be distinct"
+	VPGATHERDQ X7, 664(X2*8), X2    // ERROR "mask, index, and destination registers should be distinct"
 	RET
diff --git a/src/cmd/asm/internal/asm/testdata/arm.s b/src/cmd/asm/internal/asm/testdata/arm.s
index 8f743e7..bc6cf07 100644
--- a/src/cmd/asm/internal/asm/testdata/arm.s
+++ b/src/cmd/asm/internal/asm/testdata/arm.s
@@ -57,7 +57,7 @@
 //		outcode($1, $2, &$3, 0, &$5);
 //	}
 	MOVW.S	R1, R2
-	MOVW.S	$1, R2
+	MOVW	$1, R2
 	MOVW.S	R1<<R2, R3
 
 //
@@ -156,18 +156,6 @@
 //	}
 	STREX	R1, (R2), R3 // STREX (R2), R1, R3
 
-//	LTYPE9 cond reg ',' ireg
-//	{
-//		outcode($1, $2, &$5, int32($3.Reg), &$3);
-//	}
-	STREX	R1, (R2) // STREX (R2), R1, R1
-
-//	LTYPE9 cond comma ireg ',' reg
-//	{
-//		outcode($1, $2, &$4, int32($6.Reg), &$6);
-//	}
-	STREX	(R2), R3 // STREX (R2), R3, R3
-
 //
 // word
 //
@@ -771,21 +759,21 @@
 	B	jmp_label_0 // JMP     // ffffffea
 jmp_label_0:
 	ADD	$0, R0, R0
-	BEQ	jmp_label_0 // BEQ 521 // fdffff0a
-	BNE	jmp_label_0 // BNE 521 // fcffff1a
-	BCS	jmp_label_0 // BCS 521 // fbffff2a
-	BCC	jmp_label_0 // BCC 521 // faffff3a
-	BMI	jmp_label_0 // BMI 521 // f9ffff4a
-	BPL	jmp_label_0 // BPL 521 // f8ffff5a
-	BVS	jmp_label_0 // BVS 521 // f7ffff6a
-	BVC	jmp_label_0 // BVC 521 // f6ffff7a
-	BHI	jmp_label_0 // BHI 521 // f5ffff8a
-	BLS	jmp_label_0 // BLS 521 // f4ffff9a
-	BGE	jmp_label_0 // BGE 521 // f3ffffaa
-	BLT	jmp_label_0 // BLT 521 // f2ffffba
-	BGT	jmp_label_0 // BGT 521 // f1ffffca
-	BLE	jmp_label_0 // BLE 521 // f0ffffda
-	B	jmp_label_0 // JMP 521 // efffffea
+	BEQ	jmp_label_0 // BEQ 519 // fdffff0a
+	BNE	jmp_label_0 // BNE 519 // fcffff1a
+	BCS	jmp_label_0 // BCS 519 // fbffff2a
+	BCC	jmp_label_0 // BCC 519 // faffff3a
+	BMI	jmp_label_0 // BMI 519 // f9ffff4a
+	BPL	jmp_label_0 // BPL 519 // f8ffff5a
+	BVS	jmp_label_0 // BVS 519 // f7ffff6a
+	BVC	jmp_label_0 // BVC 519 // f6ffff7a
+	BHI	jmp_label_0 // BHI 519 // f5ffff8a
+	BLS	jmp_label_0 // BLS 519 // f4ffff9a
+	BGE	jmp_label_0 // BGE 519 // f3ffffaa
+	BLT	jmp_label_0 // BLT 519 // f2ffffba
+	BGT	jmp_label_0 // BGT 519 // f1ffffca
+	BLE	jmp_label_0 // BLE 519 // f0ffffda
+	B	jmp_label_0 // JMP 519 // efffffea
 	B	0(PC)    // JMP 0(PC)  // feffffea
 jmp_label_1:
 	B	jmp_label_1 // JMP     // feffffea
@@ -816,21 +804,21 @@
 	BL	jmp_label_2 // CALL        // ffffffeb
 jmp_label_2:
 	ADD	$0, R0, R0
-	BL.EQ	jmp_label_2 // CALL.EQ 562 // fdffff0b
-	BL.NE	jmp_label_2 // CALL.NE 562 // fcffff1b
-	BL.CS	jmp_label_2 // CALL.CS 562 // fbffff2b
-	BL.CC	jmp_label_2 // CALL.CC 562 // faffff3b
-	BL.MI	jmp_label_2 // CALL.MI 562 // f9ffff4b
-	BL.PL	jmp_label_2 // CALL.PL 562 // f8ffff5b
-	BL.VS	jmp_label_2 // CALL.VS 562 // f7ffff6b
-	BL.VC	jmp_label_2 // CALL.VC 562 // f6ffff7b
-	BL.HI	jmp_label_2 // CALL.HI 562 // f5ffff8b
-	BL.LS	jmp_label_2 // CALL.LS 562 // f4ffff9b
-	BL.GE	jmp_label_2 // CALL.GE 562 // f3ffffab
-	BL.LT	jmp_label_2 // CALL.LT 562 // f2ffffbb
-	BL.GT	jmp_label_2 // CALL.GT 562 // f1ffffcb
-	BL.LE	jmp_label_2 // CALL.LE 562 // f0ffffdb
-	BL	jmp_label_2 // CALL 562    // efffffeb
+	BL.EQ	jmp_label_2 // CALL.EQ 560 // fdffff0b
+	BL.NE	jmp_label_2 // CALL.NE 560 // fcffff1b
+	BL.CS	jmp_label_2 // CALL.CS 560 // fbffff2b
+	BL.CC	jmp_label_2 // CALL.CC 560 // faffff3b
+	BL.MI	jmp_label_2 // CALL.MI 560 // f9ffff4b
+	BL.PL	jmp_label_2 // CALL.PL 560 // f8ffff5b
+	BL.VS	jmp_label_2 // CALL.VS 560 // f7ffff6b
+	BL.VC	jmp_label_2 // CALL.VC 560 // f6ffff7b
+	BL.HI	jmp_label_2 // CALL.HI 560 // f5ffff8b
+	BL.LS	jmp_label_2 // CALL.LS 560 // f4ffff9b
+	BL.GE	jmp_label_2 // CALL.GE 560 // f3ffffab
+	BL.LT	jmp_label_2 // CALL.LT 560 // f2ffffbb
+	BL.GT	jmp_label_2 // CALL.GT 560 // f1ffffcb
+	BL.LE	jmp_label_2 // CALL.LE 560 // f0ffffdb
+	BL	jmp_label_2 // CALL 560    // efffffeb
 	BL	0(PC)    // CALL 0(PC)     // feffffeb
 jmp_label_3:
 	BL	jmp_label_3 // CALL        // feffffeb
@@ -985,6 +973,40 @@
 	REVSH	R1, R2               // b12fffe6
 	RBIT	R1, R2               // 312fffe6
 
+// XTAB/XTAH/XTABU/XTAHU
+	XTAB	R2@>0, R8            // 7280a8e6
+	XTAB	R2@>8, R8            // 7284a8e6
+	XTAB	R2@>16, R8           // 7288a8e6
+	XTAB	R2@>24, R8           // 728ca8e6
+	XTAH	R3@>0, R9            // 7390b9e6
+	XTAH	R3@>8, R9            // 7394b9e6
+	XTAH	R3@>16, R9           // 7398b9e6
+	XTAH	R3@>24, R9           // 739cb9e6
+	XTABU	R4@>0, R7            // 7470e7e6
+	XTABU	R4@>8, R7            // 7474e7e6
+	XTABU	R4@>16, R7           // 7478e7e6
+	XTABU	R4@>24, R7           // 747ce7e6
+	XTAHU	R5@>0, R1            // 7510f1e6
+	XTAHU	R5@>8, R1            // 7514f1e6
+	XTAHU	R5@>16, R1           // 7518f1e6
+	XTAHU	R5@>24, R1           // 751cf1e6
+	XTAB	R2@>0, R4, R8        // 7280a4e6
+	XTAB	R2@>8, R4, R8        // 7284a4e6
+	XTAB	R2@>16, R4, R8       // 7288a4e6
+	XTAB	R2@>24, R4, R8       // 728ca4e6
+	XTAH	R3@>0, R4, R9        // 7390b4e6
+	XTAH	R3@>8, R4, R9        // 7394b4e6
+	XTAH	R3@>16, R4, R9       // 7398b4e6
+	XTAH	R3@>24, R4, R9       // 739cb4e6
+	XTABU	R4@>0, R0, R7        // 7470e0e6
+	XTABU	R4@>8, R0, R7        // 7474e0e6
+	XTABU	R4@>16, R0, R7       // 7478e0e6
+	XTABU	R4@>24, R0, R7       // 747ce0e6
+	XTAHU	R5@>0, R9, R1        // 7510f9e6
+	XTAHU	R5@>8, R9, R1        // 7514f9e6
+	XTAHU	R5@>16, R9, R1       // 7518f9e6
+	XTAHU	R5@>24, R9, R1       // 751cf9e6
+
 // DIVHW R0, R1, R2: R1 / R0 -> R2
 	DIVHW	R0, R1, R2           // 11f012e7
 	DIVUHW	R0, R1, R2           // 11f032e7
@@ -1007,6 +1029,15 @@
 	SWI	$65535         // ffff00ef
 	SWI	               // 000000ef
 
+// BFX/BFXU/BFC/BFI
+	BFX	$16, $8, R1, R2 // BFX $16, R1, $8, R2   // 5124afe7
+	BFX	$29, $2, R8                              // 5881bce7
+	BFXU	$16, $8, R1, R2 // BFXU $16, R1, $8, R2  // 5124efe7
+	BFXU	$29, $2, R8                              // 5881fce7
+	BFC	$29, $2, R8                              // 1f81dee7
+	BFI	$29, $2, R8                              // 1881dee7
+	BFI	$16, $8, R1, R2 // BFI $16, R1, $8, R2   // 1124d7e7
+
 // synthetic arithmatic
 	ADD	$0xffffffaa, R2, R3 // ADD $4294967210, R2, R3   // 55b0e0e30b3082e0
 	ADD	$0xffffff55, R5     // ADD $4294967125, R5       // aab0e0e30b5085e0
@@ -1088,8 +1119,6 @@
 // MVN
 	MVN	$0xff, R1        // MVN $255, R1          // ff10e0e3
 	MVN	$0xff000000, R1  // MVN $4278190080, R1   // ff14e0e3
-	MVN.S	$0xff, R1        // MVN.S $255, R1        // ff10f0e3
-	MVN.S	$0xff000000, R1  // MVN.S $4278190080, R1 // ff14f0e3
 	MVN	R9<<30, R7       // 097fe0e1
 	MVN	R9>>30, R7       // 297fe0e1
 	MVN	R9->30, R7       // 497fe0e1
@@ -1106,8 +1135,7 @@
 	MVN.S	R9>>R8, R7       // 3978f0e1
 	MVN.S	R9->R8, R7       // 5978f0e1
 	MVN.S	R9@>R8, R7       // 7978f0e1
-	MVN	$0xffffffae, R5  // MVN $4294967214, R5   // 51b0e0e30b50e0e1
-	MVN.S	$0xffffffae, R5  // MVN.S $4294967214, R5 // 51b0e0e30b50f0e1
+	MVN	$0xffffffbe, R5  // MVN $4294967230, R5   // 4150a0e3
 
 // MOVM
 	MOVM.IA   [R0,R2,R4,R6], (R1)        // MOVM.U [R0,R2,R4,R6], (R1)                      // 550081e8
@@ -1145,11 +1173,23 @@
 
 // MOVW
 	MOVW	R3, R4                                            // 0340a0e1
+	MOVW.S	R3, R4                                            // 0340b0e1
 	MOVW	R9, R2                                            // 0920a0e1
+	MOVW.S	R9, R2                                            // 0920b0e1
+	MOVW	R5>>1, R2                                         // a520a0e1
+	MOVW.S	R5>>1, R2                                         // a520b0e1
+	MOVW	R5<<1, R2                                         // 8520a0e1
+	MOVW.S	R5<<1, R2                                         // 8520b0e1
+	MOVW	R5->1, R2                                         // c520a0e1
+	MOVW.S	R5->1, R2                                         // c520b0e1
+	MOVW	R5@>1, R2                                         // e520a0e1
+	MOVW.S	R5@>1, R2                                         // e520b0e1
 	MOVW	$0xff, R9            // MOVW $255, R9             // ff90a0e3
 	MOVW	$0xff000000, R9      // MOVW $4278190080, R9      // ff94a0e3
 	MOVW	$0xff(R0), R1        // MOVW $255(R0), R1         // ff1080e2
+	MOVW.S	$0xff(R0), R1        // MOVW.S $255(R0), R1       // ff1090e2
 	MOVW	$-0xff(R0), R1       // MOVW $-255(R0), R1        // ff1040e2
+	MOVW.S	$-0xff(R0), R1       // MOVW.S $-255(R0), R1      // ff1050e2
 	MOVW	$0xffffffae, R1      // MOVW $4294967214, R1      // 5110e0e3
 	MOVW	$0xaaaaaaaa, R1      // MOVW $2863311530, R1
 	MOVW	R1, (R2)                                          // 001082e5
@@ -1388,6 +1428,18 @@
 	MOVB.U	R0<<0(R1), R2                                     // d02011e1
 	MOVB.W	R0<<0(R1), R2                                     // d020b1e1
 	MOVB.P	R0<<0(R1), R2                                     // d02091e0
+	MOVBS	R2@>0, R8                                         // 7280afe6
+	MOVBS	R2@>8, R8                                         // 7284afe6
+	MOVBS	R2@>16, R8                                        // 7288afe6
+	MOVBS	R2@>24, R8                                        // 728cafe6
+	MOVB	R2@>0, R8                                         // 7280afe6
+	MOVB	R2@>8, R8                                         // 7284afe6
+	MOVB	R2@>16, R8                                        // 7288afe6
+	MOVB	R2@>24, R8                                        // 728cafe6
+	MOVBU	R4@>0, R7                                         // 7470efe6
+	MOVBU	R4@>8, R7                                         // 7474efe6
+	MOVBU	R4@>16, R7                                        // 7478efe6
+	MOVBU	R4@>24, R7                                        // 747cefe6
 
 // MOVH
 	MOVH	R3, R4                                            // 0340a0e1
@@ -1490,6 +1542,42 @@
 	MOVHS	math·Exp(SB), R0     // MOVHS math.Exp(SB), R0
 	MOVHU	R0, math·Exp(SB)     // MOVHU R0, math.Exp(SB)
 	MOVHU	math·Exp(SB), R0     // MOVHU math.Exp(SB), R0
+	MOVHS	R0<<0(R1), R2                                     // f02091e1
+	MOVHS.U	R0<<0(R1), R2                                     // f02011e1
+	MOVHS.W	R0<<0(R1), R2                                     // f020b1e1
+	MOVHS.P	R0<<0(R1), R2                                     // f02091e0
+	MOVH	R0<<0(R1), R2                                     // f02091e1
+	MOVH.U	R0<<0(R1), R2                                     // f02011e1
+	MOVH.W	R0<<0(R1), R2                                     // f020b1e1
+	MOVH.P	R0<<0(R1), R2                                     // f02091e0
+	MOVHU	R0<<0(R1), R2                                     // b02091e1
+	MOVHU.U	R0<<0(R1), R2                                     // b02011e1
+	MOVHU.W	R0<<0(R1), R2                                     // b020b1e1
+	MOVHU.P	R0<<0(R1), R2                                     // b02091e0
+	MOVHS	R2, R5<<0(R1)                                     // b52081e1
+	MOVHS.U	R2, R5<<0(R1)                                     // b52001e1
+	MOVHS.W	R2, R5<<0(R1)                                     // b520a1e1
+	MOVHS.P	R2, R5<<0(R1)                                     // b52081e0
+	MOVH	R2, R5<<0(R1)                                     // b52081e1
+	MOVH.U	R2, R5<<0(R1)                                     // b52001e1
+	MOVH.W	R2, R5<<0(R1)                                     // b520a1e1
+	MOVH.P	R2, R5<<0(R1)                                     // b52081e0
+	MOVHU	R2, R5<<0(R1)                                     // b52081e1
+	MOVHU.U	R2, R5<<0(R1)                                     // b52001e1
+	MOVHU.W	R2, R5<<0(R1)                                     // b520a1e1
+	MOVHU.P	R2, R5<<0(R1)                                     // b52081e0
+	MOVHS	R3@>0, R9                                         // 7390bfe6
+	MOVHS	R3@>8, R9                                         // 7394bfe6
+	MOVHS	R3@>16, R9                                        // 7398bfe6
+	MOVHS	R3@>24, R9                                        // 739cbfe6
+	MOVH	R3@>0, R9                                         // 7390bfe6
+	MOVH	R3@>8, R9                                         // 7394bfe6
+	MOVH	R3@>16, R9                                        // 7398bfe6
+	MOVH	R3@>24, R9                                        // 739cbfe6
+	MOVHU	R5@>0, R1                                         // 7510ffe6
+	MOVHU	R5@>8, R1                                         // 7514ffe6
+	MOVHU	R5@>16, R1                                        // 7518ffe6
+	MOVHU	R5@>24, R1                                        // 751cffe6
 
 //
 // END
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 1b6dc18..cb563bb 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -29,6 +29,45 @@
 	ADD	R1<<22, R2, R3
 	ADD	R1->33, R2, R3
 	AND	R1@>33, R2, R3
+	ADD	R1.UXTB, R2, R3                 // 4300218b
+	ADD	R1.UXTB<<4, R2, R3              // 4310218b
+	ADDW	R2.SXTW, R10, R12               // 4cc1220b
+	ADD	R18.UXTX, R14, R17              // d161328b
+	ADDSW	R18.UXTW, R14, R17              // d141322b
+	ADDS	R12.SXTX, R3, R1                // 61e02cab
+	SUB	R19.UXTH<<4, R2, R21            // 553033cb
+	SUBW	R1.UXTX<<1, R3, R2              // 6264214b
+	SUBS	R3.UXTX, R8, R9                 // 096123eb
+	SUBSW	R17.UXTH, R15, R21              // f521316b
+	CMP	R2.SXTH, R13                    // bfa122eb
+	CMN	R1.SXTX<<2, R10                 // 5fe921ab
+	CMPW	R2.UXTH<<3, R11                 // 7f2d226b
+	CMNW	R1.SXTB, R9                     // 3f81212b
+	VADDP	V1.B16, V2.B16, V3.B16          // 43bc214e
+	VADDP	V1.S4, V2.S4, V3.S4             // 43bca14e
+	VADDP	V1.D2, V2.D2, V3.D2             // 43bce14e
+	VAND	V21.B8, V12.B8, V3.B8           // 831d350e
+	VCMEQ	V1.H4, V2.H4, V3.H4             // 438c612e
+	VORR	V5.B16, V4.B16, V3.B16          // 831ca54e
+	VADD	V16.S4, V5.S4, V9.S4            // a984b04e
+	VEOR	V0.B16, V1.B16, V0.B16          // 201c206e
+	SHA256H	V9.S4, V3, V2                   // 6240095e
+	SHA256H2	V9.S4, V4, V3           // 8350095e
+	SHA256SU0	V8.S4, V7.S4            // 0729285e
+	SHA256SU1	V6.S4, V5.S4, V7.S4     // a760065e
+	SHA1SU0	V11.S4, V8.S4, V6.S4            // 06310b5e
+	SHA1SU1	V5.S4, V1.S4                    // a118285e
+	SHA1C	V1.S4, V2, V3                   // 4300015e
+	SHA1H	V5, V4                          // a408285e
+	SHA1M	V8.S4, V7, V6                   // e620085e
+	SHA1P	V11.S4, V10, V9                 // 49110b5e
+	VADDV	V0.S4, V0                       // 00b8b14e
+	VMOVI	$82, V0.B16                     // 40e6024f
+	VUADDLV	V6.B16, V6                      // c638306e
+	VADD	V1, V2, V3                      // 4384e15e
+	VADD	V1, V3, V3                      // 6384e15e
+	VSUB	V12, V30, V30                   // de87ec7e
+	VSUB	V12, V20, V30                   // 9e86ec7e
 
 //	LTYPE1 imsr ',' spreg ','
 //	{
@@ -84,6 +123,18 @@
 	MOVD	$1, ZR
 	MOVD	$1, R1
 	MOVD	ZR, (R1)
+	VLD1	(R8), [V1.B16, V2.B16]                          // 01a1404c
+	VLD1.P	(R3), [V31.H8, V0.H8]                           // 7fa4df4c
+	VLD1.P	(R8)(R20), [V21.B16, V22.B16]                   // VLD1.P	(R8)(R20*1), [V21.B16,V22.B16] // 15a1d44c
+	VLD1.P	64(R1), [V5.B16, V6.B16, V7.B16, V8.B16]        // 2520df4c
+	VST1.P	[V4.S4, V5.S4], 32(R1)                          // 24a89f4c
+	VST1	[V0.S4, V1.S4], (R0)                            // 00a8004c
+	VMOVS	V20, (R0)                                       // 140000bd
+	VMOVS.P	V20, 4(R0)                                      // 144400bc
+	VMOVS.W	V20, 4(R0)                                      // 144c00bc
+	VMOVS	(R0), V20                                       // 140040bd
+	VMOVS.P	8(R0), V20                                      // 148440bc
+	VMOVS.W	8(R0), V20                                      // 148c40bc
 
 	// small offset fits into instructions
 	MOVB	1(R1), R2 // 22048039
@@ -147,7 +198,16 @@
 //		outcode($1, &$2, NREG, &$4);
 //	}
 	MOVK	$1, R1
-
+	VMOV	V8.S[1], R1       // 013d0c0e
+	VMOV	V0.D[0], R11      // 0b3c084e
+	VMOV	V0.D[1], R11      // 0b3c184e
+	VMOV	R20, V1.S[0]      // 811e044e
+	VMOV	R1, V9.H4         // 290c020e
+	VMOV	R22, V11.D2       // cb0e084e
+	VMOV 	V2.B16, V4.B16    // 441ca24e
+	VMOV	V20.S[0], V20     // 9406045e
+	VREV32	V5.B16, V5.B16    // a508206e
+	VDUP	V19.S[0], V17.S4  // 7106044e
 //
 // B/BL
 //
@@ -193,6 +253,7 @@
 	CMP	R1->11, R2
 	CMP	R1>>22, R2
 	CMP	R1<<33, R2
+	CMP	R22.SXTX, RSP // ffe336eb
 //
 // CBZ
 //
@@ -338,6 +399,20 @@
 	JMP	foo(SB)
 	CALL	foo(SB)
 
+// LDP/STP
+	LDP	(R0), (R1, R2)
+	LDP	8(R0), (R1, R2)
+	LDP.W	8(R0), (R1, R2)
+	LDP.P	8(R0), (R1, R2)
+	LDP	x(SB), (R1, R2)
+	LDP	x+8(SB), (R1, R2)
+	STP	(R3, R4), (R5)
+	STP	(R3, R4), 8(R5)
+	STP.W	(R3, R4), 8(R5)
+	STP.P	(R3, R4), 8(R5)
+	STP	(R3, R4), x(SB)
+	STP	(R3, R4), x+8(SB)
+
 // END
 //
 //	LTYPEE comma
diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s
index ec89474..b02e0b3 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s
@@ -57,7 +57,7 @@
    CALL -1(PC)                                // ffffff97
    CALL (R15)                                 // e0013fd6
    JMP  (R29)                                 // a0031fd6
-   // BRK $35943                              // e08c31d4
+   BRK $35943                                 // e08c31d4
    CBNZW R2, -1(PC)                           // e2ffff35
    CBNZ R7, -1(PC)                            // e7ffffb5
    CBZW R15, -1(PC)                           // efffff34
@@ -81,8 +81,8 @@
    CINVW EQ, R2, R17                          // 5110825a
    CINV VS, R12, R7                           // 87718cda
    CINV VS, R30, R30                          // de739eda
-   // CLREX $4                                // 5f3403d5
-   // CLREX $0                                // 5f3003d5
+   CLREX $4                                   // 5f3403d5
+   CLREX $0                                   // 5f3003d5
    CLSW R15, R6                               // e615c05a
    CLS R15, ZR                                // ff15c0da
    CLZW R1, R14                               // 2e10c05a
@@ -128,9 +128,9 @@
    CSNEGW HS, R16, R29, R10                   // 0a269d5a
    CSNEG NE, R21, R18, R11                    // ab1692da
    //TODO DC
-   // DCPS1 $11378                            // 418ea5d4
-   // DCPS2 $10699                            // 6239a5d4
-   // DCPS3 $24415                            // e3ebabd4
+   DCPS1 $11378                               // 418ea5d4
+   DCPS2 $10699                               // 6239a5d4
+   DCPS3 $24415                               // e3ebabd4
    DMB $1                                     // bf3103d5
    DMB $0                                     // bf3003d5
    DRPS                                       // e003bfd6
@@ -145,8 +145,8 @@
    EXTR $35, R22, R12, R8                     // 888dd693
    SEVL                                       // bf2003d5
    HINT $6                                    // df2003d5
-   // HLT $65509                              // a0fc5fd4
-   // HVC $61428                              // 82fe1dd4
+   HLT $65509                                 // a0fc5fd4
+   HVC $61428                                 // 82fe1dd4
    ISB $1                                     // df3103d5
    ISB $15                                    // df3f03d5
    LDARW (R12), R29                           // 9dfddf88
@@ -242,15 +242,15 @@
    ORRW $16252928, ZR, R21                    // f5130d32
    MOVD $-4260607558625, R11                  // eb6b16b2
    MOVD R30, R7                               // e7031eaa
-   // MOVKW $(3905<<0), R21                   // MOVKW $3905, R21              // 35e88172
-   // MOVKW $(3905<<16), R21                  // MOVKW $255918080, R21         // 35e8a172
-   // MOVK $(3905<<32), R21                   // MOVK $16771847290880, R21     // 35e8c1f2
+   MOVKW $(3905<<0), R21                      // MOVKW $3905, R21              // 35e88172
+   MOVKW $(3905<<16), R21                     // MOVKW $255918080, R21         // 35e8a172
+   MOVK $(3905<<32), R21                      // MOVK $16771847290880, R21     // 35e8c1f2
    MOVD $0, R5                                // 050080d2
-   // MRS $4567, R16                          // f03a32d5
-   // MRS $32345, R6                          // 26cb3fd5
-   // MSR R25, $3452                          // 99af11d5
-   // MSR R25, $16896                         // 194018d5
-   // MSR $6, DAIFClr                         // ff4603d5
+   MSR $1, SPSel                              // bf4100d5
+   MSR $9, DAIFSet                            // df4903d5
+   MSR $6, DAIFClr                            // ff4603d5
+   MRS ELR_EL1, R8                            // 284038d5
+   MSR R16, ELR_EL1                           // 304018d5
    MSUBW R1, R1, R12, R5                      // 8585011b
    MSUB R19, R16, R26, R2                     // 42c3139b
    MULW R26, R5, R22                          // b67c1a1b
@@ -304,7 +304,7 @@
    SMNEGL R26, R3, R15                        // 6ffc3a9b
    SMULH R17, R21, R21                        // b57e519b
    SMULL R0, R5, R0                           // a07c209b
-   // SMC $37977                              // 238b12d4
+   SMC $37977                                 // 238b12d4
    STLRW R16, (R22)                           // d0fe9f88
    STLR R3, (R24)                             // 03ff9fc8
    //TODO STLRB R11, (R22)                    // cbfe9f08
@@ -345,10 +345,10 @@
    //TODO STTRH 9(R10), R18                   // 52990078
    //TODO STXP (R20), R18, R5, ZR             // 854a3f88
    //TODO STXP (R22), R9, R17, R0             // d12620c8
-   // STXRW R2, (R19), R18                    // 627e1288
-   // STXR R15, (R21), R13                    // af7e0dc8
-   // STXRB R7, (R9), R24                     // 277d1808
-   // STXRH R12, (R3), R8                     // 6c7c0848
+   STXRW R2, (R19), R18                       // 627e1288
+   STXR R15, (R21), R13                       // af7e0dc8
+   STXRB R7, (R9), R24                        // 277d1808
+   STXRH R12, (R3), R8                        // 6c7c0848
    //TODO SUBW R20.UXTW<<7, R23, R18          // f25e344b
    //TODO SUB R5.SXTW<<2, R1, R26             // 3ac825cb
    SUB $(1923<<12), R4, R27                   // SUB $7876608, R4, R27         // 9b0c5ed1
@@ -398,16 +398,16 @@
    FCCMPD HI, F11, F15, $15                   // ef856b1e
    FCCMPES HS, F28, F13, $13                  // bd253c1e
    FCCMPED LT, F20, F4, $9                    // 99b4741e
-   // FCMPS F3, F17                           // 2022231e
-   // FCMPS $(0.0), F8                        // 0821201e
-   // FCMPD F11, F27                          // 60236b1e
-   // FCMPD $(0.0), F25                       // 2823601e
-   // FCMPES F16, F30                         // d023301e
-   // FCMPES $(0.0), F29                      // b823201e
-   // FCMPED F13, F10                         // 50216d1e
-   // FCMPED $(0.0), F25                      // 3823601e
-   // FCSELS EQ, F26, F27, F25                // 590f3b1e
-   // FCSELD PL, F8, F22, F7                  // 075d761e
+   FCMPS F3, F17                              // 2022231e
+   FCMPS $(0.0), F8                           // 0821201e
+   FCMPD F11, F27                             // 60236b1e
+   FCMPD $(0.0), F25                          // 2823601e
+   FCMPES F16, F30                            // d023301e
+   FCMPES $(0.0), F29                         // b823201e
+   FCMPED F13, F10                            // 50216d1e
+   FCMPED $(0.0), F25                         // 3823601e
+   FCSELS EQ, F26, F27, F25                   // 590f3b1e
+   FCSELD PL, F8, F22, F7                     // 075d761e
    //TODO FCVTASW F21, R15                    // af02241e
    //TODO FCVTAS F20, ZR                      // 9f02249e
    //TODO FCVTASW F6, R11                     // cb00641e
diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s
new file mode 100644
index 0000000..e4fad9c
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/arm64error.s
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT errors(SB),$0
+	MOVD.P	300(R2), R3            // ERROR "offset out of range [-255,254]"
+	MOVD.P	R3, 344(R2)            // ERROR "offset out of range [-255,254]"
+	VLD1	(R8)(R13), [V2.B16]    // ERROR "illegal combination"
+	VLD1	8(R9), [V2.B16]        // ERROR "illegal combination"
+	VST1	[V1.B16], (R8)(R13)    // ERROR "illegal combination"
+	VST1	[V1.B16], 9(R2)        // ERROR "illegal combination"
+	VLD1	8(R8)(R13), [V2.B16]   // ERROR "illegal combination"
+	ADD	R1.UXTB<<5, R2, R3     // ERROR "shift amount out of range 0 to 4"
+	ADDS	R1.UXTX<<7, R2, R3     // ERROR "shift amount out of range 0 to 4"
+	RET
diff --git a/src/cmd/asm/internal/asm/testdata/armerror.s b/src/cmd/asm/internal/asm/testdata/armerror.s
index 2959a2f..f2bed8d 100644
--- a/src/cmd/asm/internal/asm/testdata/armerror.s
+++ b/src/cmd/asm/internal/asm/testdata/armerror.s
@@ -35,6 +35,22 @@
 	BL	4(R4)              // ERROR "non-zero offset"
 	ADDF	F0, R1, F2         // ERROR "illegal combination"
 	SWI	(R0)               // ERROR "illegal combination"
+	MULAD	F0, F1             // ERROR "illegal combination"
+	MULAF	F0, F1             // ERROR "illegal combination"
+	MULSD	F0, F1             // ERROR "illegal combination"
+	MULSF	F0, F1             // ERROR "illegal combination"
+	NMULAD	F0, F1             // ERROR "illegal combination"
+	NMULAF	F0, F1             // ERROR "illegal combination"
+	NMULSD	F0, F1             // ERROR "illegal combination"
+	NMULSF	F0, F1             // ERROR "illegal combination"
+	FMULAD	F0, F1             // ERROR "illegal combination"
+	FMULAF	F0, F1             // ERROR "illegal combination"
+	FMULSD	F0, F1             // ERROR "illegal combination"
+	FMULSF	F0, F1             // ERROR "illegal combination"
+	FNMULAD	F0, F1             // ERROR "illegal combination"
+	FNMULAF	F0, F1             // ERROR "illegal combination"
+	FNMULSD	F0, F1             // ERROR "illegal combination"
+	FNMULSF	F0, F1             // ERROR "illegal combination"
 	NEGF	F0, F1, F2         // ERROR "illegal combination"
 	NEGD	F0, F1, F2         // ERROR "illegal combination"
 	ABSF	F0, F1, F2         // ERROR "illegal combination"
@@ -63,6 +79,8 @@
 	MOVW	errors(SB), F0     // ERROR "illegal combination"
 	MOVW	$20, errors(SB)    // ERROR "illegal combination"
 	MOVW	errors(SB), $20    // ERROR "illegal combination"
+	MOVW	(R1), [R0-R4]      // ERROR "illegal combination"
+	MOVW	[R0-R4], (R1)      // ERROR "illegal combination"
 	MOVB	$245, R1           // ERROR "illegal combination"
 	MOVH	$245, R1           // ERROR "illegal combination"
 	MOVB	$0xff000000, R1    // ERROR "illegal combination"
@@ -85,10 +103,10 @@
 	MOVH	$0xffffff00, CPSR  // ERROR "illegal combination"
 	MOVB	$0xfffffff0, FPSR  // ERROR "illegal combination"
 	MOVH	$0xfffffff0, FPSR  // ERROR "illegal combination"
-	MOVB.IA	4(R1), [R0-R4]     // ERROR "illegal combination"
-	MOVB.DA	4(R1), [R0-R4]     // ERROR "illegal combination"
-	MOVH.IA	4(R1), [R0-R4]     // ERROR "illegal combination"
-	MOVH.DA	4(R1), [R0-R4]     // ERROR "illegal combination"
+	MOVB	(R1), [R0-R4]      // ERROR "illegal combination"
+	MOVB	[R0-R4], (R1)      // ERROR "illegal combination"
+	MOVH	(R1), [R0-R4]      // ERROR "illegal combination"
+	MOVH	[R0-R4], (R1)      // ERROR "illegal combination"
 	MOVB	$0xff(R0), R1      // ERROR "illegal combination"
 	MOVH	$0xff(R0), R1      // ERROR "illegal combination"
 	MOVB	$errors(SB), R2    // ERROR "illegal combination"
@@ -124,5 +142,123 @@
 	MOVFW	CPSR, R2           // ERROR "illegal combination"
 	MOVDW	R1, CPSR           // ERROR "illegal combination"
 	MOVFW	R1, CPSR           // ERROR "illegal combination"
+	BFX	$12, $41, R2, R3   // ERROR "wrong width or LSB"
+	BFX	$12, $-2, R2       // ERROR "wrong width or LSB"
+	BFXU	$40, $4, R2, R3    // ERROR "wrong width or LSB"
+	BFXU	$-40, $4, R2       // ERROR "wrong width or LSB"
+	BFX	$-2, $4, R2, R3    // ERROR "wrong width or LSB"
+	BFXU	$4, R2, R5, R2     // ERROR "missing or wrong LSB"
+	BFXU	$4, R2, R5         // ERROR "missing or wrong LSB"
+	BFC	$12, $8, R2, R3    // ERROR "illegal combination"
+	MOVB	R0>>8, R2          // ERROR "illegal shift"
+	MOVH	R0<<16, R2         // ERROR "illegal shift"
+	MOVBS	R0->8, R2          // ERROR "illegal shift"
+	MOVHS	R0<<24, R2         // ERROR "illegal shift"
+	MOVBU	R0->24, R2         // ERROR "illegal shift"
+	MOVHU	R0@>1, R2          // ERROR "illegal shift"
+	XTAB	R0>>8, R2          // ERROR "illegal shift"
+	XTAH	R0<<16, R2         // ERROR "illegal shift"
+	XTABU	R0->24, R2         // ERROR "illegal shift"
+	XTAHU	R0@>1, R2          // ERROR "illegal shift"
+	XTAB	R0>>8, R5, R2      // ERROR "illegal shift"
+	XTAH	R0<<16, R5, R2     // ERROR "illegal shift"
+	XTABU	R0->24, R5, R2     // ERROR "illegal shift"
+	XTAHU	R0@>1, R5, R2      // ERROR "illegal shift"
+	AND.W	R0, R1             // ERROR "invalid .W suffix"
+	ORR.P	R2, R3, R4         // ERROR "invalid .P suffix"
+	CMP.S	R1, R2	           // ERROR "invalid .S suffix"
+	BIC.P	$124, R1, R2       // ERROR "invalid .P suffix"
+	MOVW.S	$124, R1           // ERROR "invalid .S suffix"
+	MVN.S	$123, g            // ERROR "invalid .S suffix"
+	RSB.U	$0, R9             // ERROR "invalid .U suffix"
+	CMP.S	$29, g             // ERROR "invalid .S suffix"
+	ADD.W	R1<<R2, R3         // ERROR "invalid .W suffix"
+	SUB.U	R1<<R2, R3, R9     // ERROR "invalid .U suffix"
+	CMN.S	R5->R2, R1         // ERROR "invalid .S suffix"
+	SLL.P	R1, R2, R3         // ERROR "invalid .P suffix"
+	SRA.U	R2, R8             // ERROR "invalid .U suffix"
+	SWI.S                      // ERROR "invalid .S suffix"
+	SWI.P	$0                 // ERROR "invalid .P suffix"
+	MOVW.S	$0xaaaaaaaa, R7    // ERROR "invalid .S suffix"
+	MOVW.P	$0xffffff44, R1    // ERROR "invalid .P suffix"
+	MOVW.S	$0xffffff77, R1    // ERROR "invalid .S suffix"
+	MVN.S	$0xffffffaa, R8    // ERROR "invalid .S suffix"
+	MVN.S	$0xaaaaaaaa, R8    // ERROR "invalid .S suffix"
+	ADD.U	$0xaaaaaaaa, R4    // ERROR "invalid .U suffix"
+	ORR.P	$0x555555, R7, R3  // ERROR "invalid .P suffix"
+	TST.S	$0xabcd1234, R2    // ERROR "invalid .S suffix"
+	MOVB.S	R1, R2             // ERROR "invalid .S suffix"
+	MOVBU.P	R1, R2             // ERROR "invalid .P suffix"
+	MOVBS.U	R1, R2             // ERROR "invalid .U suffix"
+	MOVH.S	R1, R2             // ERROR "invalid .S suffix"
+	MOVHU.P	R1, R2             // ERROR "invalid .P suffix"
+	MOVHS.U	R1, R2             // ERROR "invalid .U suffix"
+	MUL.P	R0, R1, R2         // ERROR "invalid .P suffix"
+	MULU.W	R1, R2             // ERROR "invalid .W suffix"
+	DIVHW.S	R0, R1, R2         // ERROR "invalid .S suffix"
+	DIVHW.W	R1, R2             // ERROR "invalid .W suffix"
+	MULL.W	R2, R0, (R5, R8)   // ERROR "invalid .W suffix"
+	MULLU.U	R2, R0, (R5, R8)   // ERROR "invalid .U suffix"
+	BFX.S	$2, $4, R3         // ERROR "invalid .S suffix"
+	BFXU.W	$2, $4, R3, R0     // ERROR "invalid .W suffix"
+	MOVB.S	R1, 4(R2)          // ERROR "invalid .S suffix"
+	MOVHU.S	R1, 4(R2)          // ERROR "invalid .S suffix"
+	MOVW.S	R1, 4(R2)          // ERROR "invalid .S suffix"
+	MOVBU.S	4(R2), R3          // ERROR "invalid .S suffix"
+	MOVH.S	4(R2), R3          // ERROR "invalid .S suffix"
+	MOVW.S	4(R2), R3          // ERROR "invalid .S suffix"
+	XTAB.S	R0@>0, R2          // ERROR "invalid .S suffix"
+	XTAB.W	R0@>8, R2, R9      // ERROR "invalid .W suffix"
+	MOVBU.S	R0@>24, R1         // ERROR "invalid .S suffix"
+	MOVHS.S	R0@>16, R1         // ERROR "invalid .S suffix"
+	MOVB.S	R1, 0xaaaa(R2)     // ERROR "invalid .S suffix"
+	MOVHU.S	R1, 0xaaaa(R2)     // ERROR "invalid .S suffix"
+	MOVW.S	R1, 0xaaaa(R2)     // ERROR "invalid .S suffix"
+	MOVBU.S	0xaaaa(R2), R3     // ERROR "invalid .S suffix"
+	MOVH.S	0xaaaa(R2), R3     // ERROR "invalid .S suffix"
+	MOVW.S	0xaaaa(R2), R3     // ERROR "invalid .S suffix"
+	MOVW.S	CPSR, R1           // ERROR "invalid .S suffix"
+	MOVW.S	R3, CPSR           // ERROR "invalid .S suffix"
+	MOVW.S	$0, CPSR           // ERROR "invalid .S suffix"
+	MOVM.S	(R0), [R2-R4]      // ERROR "invalid .S suffix"
+	MOVM.S	[R1-R6], (R9)      // ERROR "invalid .S suffix"
+	SWPW.S	R1, (R2), R3       // ERROR "invalid .S suffix"
+	MOVF.S	(R0), F1           // ERROR "invalid .S suffix"
+	MOVF.S	F9, (R4)           // ERROR "invalid .S suffix"
+	MOVF.S	0xfff0(R0), F1     // ERROR "invalid .S suffix"
+	MOVF.S	F9, 0xfff0(R4)     // ERROR "invalid .S suffix"
+	ADDF.S	F1, F2, F3         // ERROR "invalid .S suffix"
+	SUBD.U	F1, F2             // ERROR "invalid .U suffix"
+	NEGF.W	F9, F10            // ERROR "invalid .W suffix"
+	ABSD.P	F9, F10            // ERROR "invalid .P suffix"
+	MOVW.S	FPSR, R0           // ERROR "invalid .S suffix"
+	MOVW.P	g, FPSR            // ERROR "invalid .P suffix"
+	MOVW.S	R1->4(R6), R2      // ERROR "invalid .S suffix"
+	MOVB.S	R9, R2<<8(R4)      // ERROR "invalid .S suffix"
+	MOVHU.S	R9, R2<<0(R4)      // ERROR "invalid .S suffix"
+	STREX.S R0, (R1), R2       // ERROR "invalid .S suffix"
+	LDREX.S	(R2), R8           // ERROR "invalid .S suffix"
+	MOVF.S	$0.0, F3           // ERROR "invalid .S suffix"
+	CMPF.S	F1, F2             // ERROR "invalid .S suffix"
+	MOVFW.S	F0, F9             // ERROR "invalid .S suffix"
+	MOVWF.W	F3, F1             // ERROR "invalid .W suffix"
+	MOVFW.P	F0, R9             // ERROR "invalid .P suffix"
+	MOVWF.W	R3, F1             // ERROR "invalid .W suffix"
+	MOVW.S	F0, R9             // ERROR "invalid .S suffix"
+	MOVW.U	R3, F1             // ERROR "invalid .U suffix"
+	PLD.S	4(R1)              // ERROR "invalid .S suffix"
+	CLZ.S	R1, R2             // ERROR "invalid .S suffix"
+	MULBB.S	R0, R1, R2         // ERROR "invalid .S suffix"
+	MULA.W	R9, R6, R1, g      // ERROR "invalid .W suffix"
+	MULS.S	R2, R3, R4, g      // ERROR "invalid .S suffix"
+
+	STREX	R1, (R0)           // ERROR "illegal combination"
+	STREX	(R1), R0           // ERROR "illegal combination"
+	STREX	R1, (R0), R1       // ERROR "cannot use same register as both source and destination"
+	STREX	R1, (R0), R0       // ERROR "cannot use same register as both source and destination"
+	STREXD	R0, (R2), R0       // ERROR "cannot use same register as both source and destination"
+	STREXD	R0, (R2), R1       // ERROR "cannot use same register as both source and destination"
+	STREXD	R0, (R2), R2       // ERROR "cannot use same register as both source and destination"
+	STREXD	R1, (R4), R7       // ERROR "must be even"
 
 	END
diff --git a/src/cmd/asm/internal/asm/testdata/armv6.s b/src/cmd/asm/internal/asm/testdata/armv6.s
index cc79275..361867f 100644
--- a/src/cmd/asm/internal/asm/testdata/armv6.s
+++ b/src/cmd/asm/internal/asm/testdata/armv6.s
@@ -18,6 +18,26 @@
 	MULD.EQ	F3, F4, F5    // 035b240e
 	MULF.NE	F0, F2        // 002a221e
 	MULD	F3, F5        // 035b25ee
+	NMULF	F0, F1, F2    // 402a21ee
+	NMULF	F3, F7        // 437a27ee
+	NMULD	F0, F1, F2    // 402b21ee
+	NMULD	F3, F7        // 437b27ee
+	MULAF	F5, F6, F7    // 057a06ee
+	MULAD	F5, F6, F7    // 057b06ee
+	MULSF	F5, F6, F7    // 457a06ee
+	MULSD	F5, F6, F7    // 457b06ee
+	NMULAF	F5, F6, F7    // 457a16ee
+	NMULAD	F5, F6, F7    // 457b16ee
+	NMULSF	F5, F6, F7    // 057a16ee
+	NMULSD	F5, F6, F7    // 057b16ee
+	FMULAF  F5, F6, F7    // 057aa6ee
+	FMULAD  F5, F6, F7    // 057ba6ee
+	FMULSF  F5, F6, F7    // 457aa6ee
+	FMULSD  F5, F6, F7    // 457ba6ee
+	FNMULAF F5, F6, F7    // 457a96ee
+	FNMULAD F5, F6, F7    // 457b96ee
+	FNMULSF F5, F6, F7    // 057a96ee
+	FNMULSD F5, F6, F7    // 057b96ee
 	DIVF	F0, F1, F2    // 002a81ee
 	DIVD.EQ	F3, F4, F5    // 035b840e
 	DIVF.NE	F0, F2        // 002a821e
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s
index 30fb0f2..2909c39 100644
--- a/src/cmd/asm/internal/asm/testdata/ppc64.s
+++ b/src/cmd/asm/internal/asm/testdata/ppc64.s
@@ -550,6 +550,14 @@
 //	ftsqrt	BF, FRB
 	FTSQRT	F2,$7
 
+//	FCFID	
+//	FCFIDS
+
+	FCFID	F2,F3
+	FCFIDCC	F3,F3
+	FCFIDS	F2,F3
+	FCFIDSCC F2,F3
+
 //
 // CMP
 //
@@ -581,6 +589,10 @@
 //	cmpb  RA,RS,RB
 	CMPB  R2,R2,R1
 
+//	CMPEQB	RA,RB,BF produces
+//	cmpeqb	BF,RA,RB
+	CMPEQB	R1, R2, CR0
+
 //
 // rotate extended mnemonics map onto other shift instructions
 //
@@ -706,6 +718,14 @@
 //	}
 	DCBF	(R1)
 	DCBF	(R1+R2) // DCBF	(R1)(R2*1)
+	DCBF	(R1), $1
+	DCBF	(R1)(R2*1), $1
+	DCBT	(R1), $1
+	DCBT	(R1)(R2*1), $1
+
+//	LDMX  (RB)(RA*1),RT produces
+//	ldmx  RT,RA,RB
+	LDMX  (R2)(R1*1), R3
 
 //	Population count, X-form
 //	<MNEMONIC> RS,RA produces
@@ -714,6 +734,20 @@
 	POPCNTW	R1,R2
 	POPCNTB R1,R2
 
+//	Copysign
+	FCPSGN F1,F2,F3
+
+//	Random number generator, X-form
+//	DARN  L,RT produces
+//	darn  RT,L
+	DARN $1, R1
+
+//	Copy/Paste facility
+//	<MNEMONIC> RB,RA produces
+//	<mnemonic> RA,RB
+	COPY R2,R1
+	PASTECC R2,R1
+
 //	VMX instructions
 
 //	Described as:
@@ -788,6 +822,11 @@
 	VPMSUMW	V2, V3, V1
 	VPMSUMD	V2, V3, V1
 
+//	Vector multiply-sum, VA-form
+//	<MNEMONIC> VRA, VRB, VRC, VRT produces
+//	<mnemonic> VRT, VRA, VRB, VRC
+	VMSUMUDM V4, V3, V2, V1
+
 //	Vector SUB, VX-form
 //	<MNEMONIC> VRA,VRB,VRT produces
 //	<mnemonic> VRT,VRA,VRB
@@ -885,12 +924,20 @@
 	VCMPGTSWCC  V3, V2, V1
 	VCMPGTSD    V3, V2, V1
 	VCMPGTSDCC  V3, V2, V1
+	VCMPNEZB    V3, V2, V1
+	VCMPNEZBCC  V3, V2, V1
 
 //	Vector permute, VA-form
 //	<MNEMONIC> VRA,VRB,VRC,VRT produces
 //	<mnemonic> VRT,VRA,VRB,VRC
 	VPERM V3, V2, V1, V0
 
+//	Vector bit permute, VX-form
+//	<MNEMONIC> VRA,VRB,VRT produces
+//	<mnemonic> VRT,VRA,VRB
+	VBPERMQ	V3,V1,V2
+	VBPERMD	V3,V1,V2
+
 //	Vector select, VA-form
 //	<MNEMONIC> VRA,VRB,VRC,VRT produces
 //	<mnemonic> VRT,VRA,VRB,VRC
@@ -958,6 +1005,7 @@
 //	<mnemonic> RA,XS
 	MFVSRD	    VS0, R1
 	MFVSRWZ	    VS33, R1
+	MFVSRLD	    VS63, R1
 
 //	VSX move to VSR, XX1-form
 //	<MNEMONIC> RA,XT produces
@@ -965,6 +1013,8 @@
 	MTVSRD	    R1, VS0
 	MTVSRWA	    R1, VS31
 	MTVSRWZ	    R1, VS63
+	MTVSRDD	    R1, R2, VS0
+	MTVSRWS	    R1, VS32
 
 //	VSX AND, XX3-form
 //	<MNEMONIC> XA,XB,XT produces
@@ -1062,6 +1112,17 @@
 	XVCVUXDSP   VS0,VS32
 	XVCVUXWSP   VS0,VS32
 
+// Multiply-Add High Doubleword
+//      <MNEMONIC> RA,RB,RC,RT produces
+//      <mnemonic> RT,RA,RB,RC
+        MADDHD R1,R2,R3,R4
+        MADDHDU R1,R2,R3,R4
+
+// Add Extended using alternate carry bit
+//	ADDEX RA,RB,CY,RT produces
+//	addex RT, RA, RB, CY
+	ADDEX R1, R2, $0, R3
+
 //
 // NOP
 //
diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s
index 6cc129c..884f6b2 100644
--- a/src/cmd/asm/internal/asm/testdata/s390x.s
+++ b/src/cmd/asm/internal/asm/testdata/s390x.s
@@ -213,6 +213,11 @@
 	CMPWU	R1, R2                 // 1512
 	CMPWU	R3, $4294967295        // c23fffffffff
 
+	TMHH	R1, $65535             // a712ffff
+	TMHL	R2, $1                 // a7230001
+	TMLH	R3, $0                 // a7300000
+	TMLL	R4, $32768             // a7418000
+
 	BNE	0(PC)                  // a7740000
 	BEQ	0(PC)                  // a7840000
 	BLT	0(PC)                  // a7440000
@@ -296,6 +301,9 @@
 	FMADDS	F1, F2, F3             // b30e3012
 	FMSUB	F4, F5, F5             // b31f5045
 	FMSUBS	F6, F6, F7             // b30f7066
+	LPDFR	F1, F2                 // b3700021
+	LNDFR	F3, F4                 // b3710043
+	CPSDR	F5, F6, F7             // b3725076
 
 	VL	(R15), V1               // e710f0000006
 	VST	V1, (R15)               // e710f000000e
diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index bd90b82..6acde29 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -6,6 +6,7 @@
 package flags
 
 import (
+	"cmd/internal/objabi"
 	"flag"
 	"fmt"
 	"os"
@@ -31,6 +32,7 @@
 func init() {
 	flag.Var(&D, "D", "predefined symbol with optional simple value -D=identifier=value; can be set multiple times")
 	flag.Var(&I, "I", "include directory; can be set multiple times")
+	objabi.AddVersionFlag() // -V
 }
 
 // MultiFlag allows setting a value multiple times to collect a list, as in -I=dir1 -I=dir2.
diff --git a/src/cmd/asm/internal/lex/input.go b/src/cmd/asm/internal/lex/input.go
index ddfcddf..666611e 100644
--- a/src/cmd/asm/internal/lex/input.go
+++ b/src/cmd/asm/internal/lex/input.go
@@ -13,6 +13,7 @@
 	"text/scanner"
 
 	"cmd/asm/internal/flags"
+	"cmd/internal/objabi"
 	"cmd/internal/src"
 )
 
@@ -454,7 +455,7 @@
 		in.Error("unexpected token at end of #line: ", tok)
 	}
 	pos := src.MakePos(in.Base(), uint(in.Line()), uint(in.Col()))
-	in.Stack.SetBase(src.NewLinePragmaBase(pos, file, uint(line)))
+	in.Stack.SetBase(src.NewLinePragmaBase(pos, file, objabi.AbsFile(objabi.WorkingDir(), file, *flags.TrimPath), uint(line)))
 }
 
 // #undef processing
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
index 2e79916..04f56f9 100644
--- a/src/cmd/asm/main.go
+++ b/src/cmd/asm/main.go
@@ -72,7 +72,7 @@
 			break
 		}
 		// reports errors to parser.Errorf
-		obj.Flushplist(ctxt, pList, nil)
+		obj.Flushplist(ctxt, pList, nil, "")
 	}
 	if ok {
 		obj.WriteObjFile(ctxt, buf)
diff --git a/src/cmd/buildid/buildid.go b/src/cmd/buildid/buildid.go
new file mode 100644
index 0000000..1c7b228
--- /dev/null
+++ b/src/cmd/buildid/buildid.go
@@ -0,0 +1,90 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"strings"
+
+	"cmd/internal/buildid"
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: go tool buildid [-w] file\n")
+	flag.PrintDefaults()
+	os.Exit(2)
+}
+
+var wflag = flag.Bool("w", false, "write build ID")
+
+// taken from cmd/go/internal/work/buildid.go
+func hashToString(h [32]byte) string {
+	const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+	const chunks = 5
+	var dst [chunks * 4]byte
+	for i := 0; i < chunks; i++ {
+		v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
+		dst[4*i+0] = b64[(v>>18)&0x3F]
+		dst[4*i+1] = b64[(v>>12)&0x3F]
+		dst[4*i+2] = b64[(v>>6)&0x3F]
+		dst[4*i+3] = b64[v&0x3F]
+	}
+	return string(dst[:])
+}
+
+func main() {
+	log.SetPrefix("buildid: ")
+	log.SetFlags(0)
+	flag.Usage = usage
+	flag.Parse()
+	if flag.NArg() != 1 {
+		usage()
+	}
+
+	file := flag.Arg(0)
+	id, err := buildid.ReadFile(file)
+	if err != nil {
+		log.Fatal(err)
+	}
+	if !*wflag {
+		fmt.Printf("%s\n", id)
+		return
+	}
+
+	// Keep in sync with src/cmd/go/internal/work/buildid.go:updateBuildID
+
+	f, err := os.Open(file)
+	if err != nil {
+		log.Fatal(err)
+	}
+	matches, hash, err := buildid.FindAndHash(f, id, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+	f.Close()
+
+	newID := id[:strings.LastIndex(id, "/")] + "/" + hashToString(hash)
+	if len(newID) != len(id) {
+		log.Fatalf("%s: build ID length mismatch %q vs %q", file, id, newID)
+	}
+
+	if len(matches) == 0 {
+		return
+	}
+
+	f, err = os.OpenFile(file, os.O_WRONLY, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := buildid.Rewrite(f, matches, newID); err != nil {
+		log.Fatal(err)
+	}
+	if err := f.Close(); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/src/cmd/buildid/doc.go b/src/cmd/buildid/doc.go
new file mode 100644
index 0000000..d1ec155
--- /dev/null
+++ b/src/cmd/buildid/doc.go
@@ -0,0 +1,18 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Buildid displays or updates the build ID stored in a Go package or binary.
+
+Usage:
+	go tool buildid [-w] file
+
+By default, buildid prints the build ID found in the named file.
+If the -w option is given, buildid rewrites the build ID found in
+the file to accurately record a content hash of the file.
+
+This tool is only intended for use by the go command or
+other build systems.
+*/
+package main
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index 7122a9d..58e0ee7 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -58,11 +58,14 @@
 	// so we use ast1 to look for the doc comments on import "C"
 	// and on exported functions, and we use ast2 for translating
 	// and reprinting.
+	// In cgo mode, we ignore ast2 and just apply edits directly
+	// the text behind ast1. In godefs mode we modify and print ast2.
 	ast1 := parse(name, src, parser.ParseComments)
 	ast2 := parse(name, src, 0)
 
 	f.Package = ast1.Name.Name
 	f.Name = make(map[string]*Name)
+	f.NamePos = make(map[*Name]token.Pos)
 
 	// In ast1, find the import "C" line and get any extra C preamble.
 	sawC := false
@@ -96,36 +99,53 @@
 	}
 
 	// In ast2, strip the import "C" line.
-	w := 0
-	for _, decl := range ast2.Decls {
-		d, ok := decl.(*ast.GenDecl)
-		if !ok {
-			ast2.Decls[w] = decl
+	if *godefs {
+		w := 0
+		for _, decl := range ast2.Decls {
+			d, ok := decl.(*ast.GenDecl)
+			if !ok {
+				ast2.Decls[w] = decl
+				w++
+				continue
+			}
+			ws := 0
+			for _, spec := range d.Specs {
+				s, ok := spec.(*ast.ImportSpec)
+				if !ok || s.Path.Value != `"C"` {
+					d.Specs[ws] = spec
+					ws++
+				}
+			}
+			if ws == 0 {
+				continue
+			}
+			d.Specs = d.Specs[0:ws]
+			ast2.Decls[w] = d
 			w++
-			continue
 		}
-		ws := 0
-		for _, spec := range d.Specs {
-			s, ok := spec.(*ast.ImportSpec)
-			if !ok || s.Path.Value != `"C"` {
-				d.Specs[ws] = spec
-				ws++
+		ast2.Decls = ast2.Decls[0:w]
+	} else {
+		for _, decl := range ast2.Decls {
+			d, ok := decl.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+			for _, spec := range d.Specs {
+				if s, ok := spec.(*ast.ImportSpec); ok && s.Path.Value == `"C"` {
+					// Replace "C" with _ "unsafe", to keep program valid.
+					// (Deleting import statement or clause is not safe if it is followed
+					// in the source by an explicit semicolon.)
+					f.Edit.Replace(f.offset(s.Path.Pos()), f.offset(s.Path.End()), `_ "unsafe"`)
+				}
 			}
 		}
-		if ws == 0 {
-			continue
-		}
-		d.Specs = d.Specs[0:ws]
-		ast2.Decls[w] = d
-		w++
 	}
-	ast2.Decls = ast2.Decls[0:w]
 
 	// Accumulate pointers to uses of C.x.
 	if f.Ref == nil {
 		f.Ref = make([]*Ref, 0, 8)
 	}
-	f.walk(ast2, "prog", (*File).saveExprs)
+	f.walk(ast2, ctxProg, (*File).saveExprs)
 
 	// Accumulate exported functions.
 	// The comments are only on ast1 but we need to
@@ -133,8 +153,8 @@
 	// The first walk fills in ExpFunc, and the
 	// second walk changes the entries to
 	// refer to ast2 instead.
-	f.walk(ast1, "prog", (*File).saveExport)
-	f.walk(ast2, "prog", (*File).saveExport2)
+	f.walk(ast1, ctxProg, (*File).saveExport)
+	f.walk(ast2, ctxProg, (*File).saveExport2)
 
 	f.Comments = ast1.Comments
 	f.AST = ast2
@@ -143,9 +163,6 @@
 // Like ast.CommentGroup's Text method but preserves
 // leading blank lines, so that line numbers line up.
 func commentText(g *ast.CommentGroup) string {
-	if g == nil {
-		return ""
-	}
 	var pieces []string
 	for _, com := range g.List {
 		c := com.Text
@@ -165,7 +182,7 @@
 }
 
 // Save various references we are going to need later.
-func (f *File) saveExprs(x interface{}, context string) {
+func (f *File) saveExprs(x interface{}, context astContext) {
 	switch x := x.(type) {
 	case *ast.Expr:
 		switch (*x).(type) {
@@ -178,7 +195,7 @@
 }
 
 // Save references to C.xxx for later processing.
-func (f *File) saveRef(n *ast.Expr, context string) {
+func (f *File) saveRef(n *ast.Expr, context astContext) {
 	sel := (*n).(*ast.SelectorExpr)
 	// For now, assume that the only instance of capital C is when
 	// used as the imported package identifier.
@@ -188,10 +205,10 @@
 	if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
 		return
 	}
-	if context == "as2" {
-		context = "expr"
+	if context == ctxAssign2 {
+		context = ctxExpr
 	}
-	if context == "embed-type" {
+	if context == ctxEmbedType {
 		error_(sel.Pos(), "cannot embed C type")
 	}
 	goname := sel.Sel.Name
@@ -212,6 +229,7 @@
 			Go: goname,
 		}
 		f.Name[goname] = name
+		f.NamePos[name] = sel.Pos()
 	}
 	f.Ref = append(f.Ref, &Ref{
 		Name:    name,
@@ -221,7 +239,7 @@
 }
 
 // Save calls to C.xxx for later processing.
-func (f *File) saveCall(call *ast.CallExpr, context string) {
+func (f *File) saveCall(call *ast.CallExpr, context astContext) {
 	sel, ok := call.Fun.(*ast.SelectorExpr)
 	if !ok {
 		return
@@ -229,12 +247,12 @@
 	if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
 		return
 	}
-	c := &Call{Call: call, Deferred: context == "defer"}
+	c := &Call{Call: call, Deferred: context == ctxDefer}
 	f.Calls = append(f.Calls, c)
 }
 
 // If a function should be exported add it to ExpFunc.
-func (f *File) saveExport(x interface{}, context string) {
+func (f *File) saveExport(x interface{}, context astContext) {
 	n, ok := x.(*ast.FuncDecl)
 	if !ok {
 		return
@@ -274,7 +292,7 @@
 }
 
 // Make f.ExpFunc[i] point at the Func from this AST instead of the other one.
-func (f *File) saveExport2(x interface{}, context string) {
+func (f *File) saveExport2(x interface{}, context astContext) {
 	n, ok := x.(*ast.FuncDecl)
 	if !ok {
 		return
@@ -288,8 +306,30 @@
 	}
 }
 
+type astContext int
+
+const (
+	ctxProg astContext = iota
+	ctxEmbedType
+	ctxType
+	ctxStmt
+	ctxExpr
+	ctxField
+	ctxParam
+	ctxAssign2 // assignment of a single expression to two variables
+	ctxSwitch
+	ctxTypeSwitch
+	ctxFile
+	ctxDecl
+	ctxSpec
+	ctxDefer
+	ctxCall  // any function call other than ctxCall2
+	ctxCall2 // function call whose result is assigned to two variables
+	ctxSelector
+)
+
 // walk walks the AST x, calling visit(f, x, context) for each node.
-func (f *File) walk(x interface{}, context string, visit func(*File, interface{}, string)) {
+func (f *File) walk(x interface{}, context astContext, visit func(*File, interface{}, astContext)) {
 	visit(f, x, context)
 	switch n := x.(type) {
 	case *ast.Expr:
@@ -304,10 +344,10 @@
 
 	// 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)
+		if len(n.Names) == 0 && context == ctxField {
+			f.walk(&n.Type, ctxEmbedType, visit)
 		} else {
-			f.walk(&n.Type, "type", visit)
+			f.walk(&n.Type, ctxType, visit)
 		}
 	case *ast.FieldList:
 		for _, field := range n.List {
@@ -318,163 +358,163 @@
 	case *ast.Ellipsis:
 	case *ast.BasicLit:
 	case *ast.FuncLit:
-		f.walk(n.Type, "type", visit)
-		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Type, ctxType, visit)
+		f.walk(n.Body, ctxStmt, visit)
 	case *ast.CompositeLit:
-		f.walk(&n.Type, "type", visit)
-		f.walk(n.Elts, "expr", visit)
+		f.walk(&n.Type, ctxType, visit)
+		f.walk(n.Elts, ctxExpr, visit)
 	case *ast.ParenExpr:
 		f.walk(&n.X, context, visit)
 	case *ast.SelectorExpr:
-		f.walk(&n.X, "selector", visit)
+		f.walk(&n.X, ctxSelector, visit)
 	case *ast.IndexExpr:
-		f.walk(&n.X, "expr", visit)
-		f.walk(&n.Index, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
+		f.walk(&n.Index, ctxExpr, visit)
 	case *ast.SliceExpr:
-		f.walk(&n.X, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
 		if n.Low != nil {
-			f.walk(&n.Low, "expr", visit)
+			f.walk(&n.Low, ctxExpr, visit)
 		}
 		if n.High != nil {
-			f.walk(&n.High, "expr", visit)
+			f.walk(&n.High, ctxExpr, visit)
 		}
 		if n.Max != nil {
-			f.walk(&n.Max, "expr", visit)
+			f.walk(&n.Max, ctxExpr, visit)
 		}
 	case *ast.TypeAssertExpr:
-		f.walk(&n.X, "expr", visit)
-		f.walk(&n.Type, "type", visit)
+		f.walk(&n.X, ctxExpr, visit)
+		f.walk(&n.Type, ctxType, visit)
 	case *ast.CallExpr:
-		if context == "as2" {
-			f.walk(&n.Fun, "call2", visit)
+		if context == ctxAssign2 {
+			f.walk(&n.Fun, ctxCall2, visit)
 		} else {
-			f.walk(&n.Fun, "call", visit)
+			f.walk(&n.Fun, ctxCall, visit)
 		}
-		f.walk(n.Args, "expr", visit)
+		f.walk(n.Args, ctxExpr, visit)
 	case *ast.StarExpr:
 		f.walk(&n.X, context, visit)
 	case *ast.UnaryExpr:
-		f.walk(&n.X, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
 	case *ast.BinaryExpr:
-		f.walk(&n.X, "expr", visit)
-		f.walk(&n.Y, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
+		f.walk(&n.Y, ctxExpr, visit)
 	case *ast.KeyValueExpr:
-		f.walk(&n.Key, "expr", visit)
-		f.walk(&n.Value, "expr", visit)
+		f.walk(&n.Key, ctxExpr, visit)
+		f.walk(&n.Value, ctxExpr, visit)
 
 	case *ast.ArrayType:
-		f.walk(&n.Len, "expr", visit)
-		f.walk(&n.Elt, "type", visit)
+		f.walk(&n.Len, ctxExpr, visit)
+		f.walk(&n.Elt, ctxType, visit)
 	case *ast.StructType:
-		f.walk(n.Fields, "field", visit)
+		f.walk(n.Fields, ctxField, visit)
 	case *ast.FuncType:
-		f.walk(n.Params, "param", visit)
+		f.walk(n.Params, ctxParam, visit)
 		if n.Results != nil {
-			f.walk(n.Results, "param", visit)
+			f.walk(n.Results, ctxParam, visit)
 		}
 	case *ast.InterfaceType:
-		f.walk(n.Methods, "field", visit)
+		f.walk(n.Methods, ctxField, visit)
 	case *ast.MapType:
-		f.walk(&n.Key, "type", visit)
-		f.walk(&n.Value, "type", visit)
+		f.walk(&n.Key, ctxType, visit)
+		f.walk(&n.Value, ctxType, visit)
 	case *ast.ChanType:
-		f.walk(&n.Value, "type", visit)
+		f.walk(&n.Value, ctxType, visit)
 
 	case *ast.BadStmt:
 	case *ast.DeclStmt:
-		f.walk(n.Decl, "decl", visit)
+		f.walk(n.Decl, ctxDecl, visit)
 	case *ast.EmptyStmt:
 	case *ast.LabeledStmt:
-		f.walk(n.Stmt, "stmt", visit)
+		f.walk(n.Stmt, ctxStmt, visit)
 	case *ast.ExprStmt:
-		f.walk(&n.X, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
 	case *ast.SendStmt:
-		f.walk(&n.Chan, "expr", visit)
-		f.walk(&n.Value, "expr", visit)
+		f.walk(&n.Chan, ctxExpr, visit)
+		f.walk(&n.Value, ctxExpr, visit)
 	case *ast.IncDecStmt:
-		f.walk(&n.X, "expr", visit)
+		f.walk(&n.X, ctxExpr, visit)
 	case *ast.AssignStmt:
-		f.walk(n.Lhs, "expr", visit)
+		f.walk(n.Lhs, ctxExpr, visit)
 		if len(n.Lhs) == 2 && len(n.Rhs) == 1 {
-			f.walk(n.Rhs, "as2", visit)
+			f.walk(n.Rhs, ctxAssign2, visit)
 		} else {
-			f.walk(n.Rhs, "expr", visit)
+			f.walk(n.Rhs, ctxExpr, visit)
 		}
 	case *ast.GoStmt:
-		f.walk(n.Call, "expr", visit)
+		f.walk(n.Call, ctxExpr, visit)
 	case *ast.DeferStmt:
-		f.walk(n.Call, "defer", visit)
+		f.walk(n.Call, ctxDefer, visit)
 	case *ast.ReturnStmt:
-		f.walk(n.Results, "expr", visit)
+		f.walk(n.Results, ctxExpr, visit)
 	case *ast.BranchStmt:
 	case *ast.BlockStmt:
 		f.walk(n.List, context, visit)
 	case *ast.IfStmt:
-		f.walk(n.Init, "stmt", visit)
-		f.walk(&n.Cond, "expr", visit)
-		f.walk(n.Body, "stmt", visit)
-		f.walk(n.Else, "stmt", visit)
+		f.walk(n.Init, ctxStmt, visit)
+		f.walk(&n.Cond, ctxExpr, visit)
+		f.walk(n.Body, ctxStmt, visit)
+		f.walk(n.Else, ctxStmt, visit)
 	case *ast.CaseClause:
-		if context == "typeswitch" {
-			context = "type"
+		if context == ctxTypeSwitch {
+			context = ctxType
 		} else {
-			context = "expr"
+			context = ctxExpr
 		}
 		f.walk(n.List, context, visit)
-		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Body, ctxStmt, visit)
 	case *ast.SwitchStmt:
-		f.walk(n.Init, "stmt", visit)
-		f.walk(&n.Tag, "expr", visit)
-		f.walk(n.Body, "switch", visit)
+		f.walk(n.Init, ctxStmt, visit)
+		f.walk(&n.Tag, ctxExpr, visit)
+		f.walk(n.Body, ctxSwitch, visit)
 	case *ast.TypeSwitchStmt:
-		f.walk(n.Init, "stmt", visit)
-		f.walk(n.Assign, "stmt", visit)
-		f.walk(n.Body, "typeswitch", visit)
+		f.walk(n.Init, ctxStmt, visit)
+		f.walk(n.Assign, ctxStmt, visit)
+		f.walk(n.Body, ctxTypeSwitch, visit)
 	case *ast.CommClause:
-		f.walk(n.Comm, "stmt", visit)
-		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Comm, ctxStmt, visit)
+		f.walk(n.Body, ctxStmt, visit)
 	case *ast.SelectStmt:
-		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Body, ctxStmt, visit)
 	case *ast.ForStmt:
-		f.walk(n.Init, "stmt", visit)
-		f.walk(&n.Cond, "expr", visit)
-		f.walk(n.Post, "stmt", visit)
-		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Init, ctxStmt, visit)
+		f.walk(&n.Cond, ctxExpr, visit)
+		f.walk(n.Post, ctxStmt, visit)
+		f.walk(n.Body, ctxStmt, visit)
 	case *ast.RangeStmt:
-		f.walk(&n.Key, "expr", visit)
-		f.walk(&n.Value, "expr", visit)
-		f.walk(&n.X, "expr", visit)
-		f.walk(n.Body, "stmt", visit)
+		f.walk(&n.Key, ctxExpr, visit)
+		f.walk(&n.Value, ctxExpr, visit)
+		f.walk(&n.X, ctxExpr, visit)
+		f.walk(n.Body, ctxStmt, visit)
 
 	case *ast.ImportSpec:
 	case *ast.ValueSpec:
-		f.walk(&n.Type, "type", visit)
+		f.walk(&n.Type, ctxType, visit)
 		if len(n.Names) == 2 && len(n.Values) == 1 {
-			f.walk(&n.Values[0], "as2", visit)
+			f.walk(&n.Values[0], ctxAssign2, visit)
 		} else {
-			f.walk(n.Values, "expr", visit)
+			f.walk(n.Values, ctxExpr, visit)
 		}
 	case *ast.TypeSpec:
-		f.walk(&n.Type, "type", visit)
+		f.walk(&n.Type, ctxType, visit)
 
 	case *ast.BadDecl:
 	case *ast.GenDecl:
-		f.walk(n.Specs, "spec", visit)
+		f.walk(n.Specs, ctxSpec, visit)
 	case *ast.FuncDecl:
 		if n.Recv != nil {
-			f.walk(n.Recv, "param", visit)
+			f.walk(n.Recv, ctxParam, visit)
 		}
-		f.walk(n.Type, "type", visit)
+		f.walk(n.Type, ctxType, visit)
 		if n.Body != nil {
-			f.walk(n.Body, "stmt", visit)
+			f.walk(n.Body, ctxStmt, visit)
 		}
 
 	case *ast.File:
-		f.walk(n.Decls, "decl", visit)
+		f.walk(n.Decls, ctxDecl, visit)
 
 	case *ast.Package:
 		for _, file := range n.Files {
-			f.walk(file, "file", visit)
+			f.walk(file, ctxFile, visit)
 		}
 
 	case []ast.Decl:
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index b238882..c16b63a 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -45,8 +45,8 @@
 	// #include <png.h>
 	import "C"
 
-Alternatively, CPPFLAGS and LDFLAGS may be obtained via the pkg-config
-tool using a '#cgo pkg-config:' directive followed by the package names.
+Alternatively, CPPFLAGS and LDFLAGS may be obtained via the pkg-config tool
+using a '#cgo pkg-config:' directive followed by the package names.
 For example:
 
 	// #cgo pkg-config: png cairo
@@ -55,11 +55,21 @@
 
 The default pkg-config tool may be changed by setting the PKG_CONFIG environment variable.
 
+For security reasons, only a limited set of flags are allowed, notably -D, -I, and -l.
+To allow additional flags, set CGO_CFLAGS_ALLOW to a regular expression
+matching the new flags. To disallow flags that would otherwise be allowed,
+set CGO_CFLAGS_DISALLOW to a regular expression matching arguments
+that must be disallowed. In both cases the regular expression must match
+a full argument: to allow -mfoo=bar, use CGO_CFLAGS_ALLOW='-mfoo.*',
+not just CGO_CFLAGS_ALLOW='-mfoo'. Similarly named variables control
+the allowed CPPFLAGS, CXXFLAGS, FFLAGS, and LDFLAGS.
+
 When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS, CGO_FFLAGS and
 CGO_LDFLAGS environment variables are added to the flags derived from
 these directives. Package-specific flags should be set using the
 directives, not the environment variables, so that builds work in
-unmodified environments.
+unmodified environments. Flags obtained from environment variables
+are not subject to the security limitations described above.
 
 All the cgo CPPFLAGS and CFLAGS directives in a package are concatenated and
 used to compile C files in that package. All the CPPFLAGS and CXXFLAGS
@@ -102,11 +112,13 @@
 build constraint "cgo" if cgo is enabled.
 
 When cross-compiling, you must specify a C cross-compiler for cgo to
-use. You can do this by setting the CC_FOR_TARGET environment
-variable when building the toolchain using make.bash, or by setting
-the CC environment variable any time you run the go tool. The
-CXX_FOR_TARGET and CXX environment variables work in a similar way for
-C++ code.
+use. You can do this by setting the generic CC_FOR_TARGET or the
+more specific CC_FOR_${GOOS}_${GOARCH} (for example, CC_FOR_linux_arm)
+environment variable when building the toolchain using make.bash,
+or you can set the CC environment variable any time you run the go tool.
+
+The CXX_FOR_TARGET, CXX_FOR_${GOOS}_${GOARCH}, and CXX
+environment variables work in a similar way for C++ code.
 
 Go references to C
 
@@ -126,12 +138,29 @@
 The C type void* is represented by Go's unsafe.Pointer.
 The C types __int128_t and __uint128_t are represented by [16]byte.
 
+A few special C types which would normally be represented by a pointer
+type in Go are instead represented by a uintptr.  See the Special
+cases section below.
+
 To access a struct, union, or enum type directly, prefix it with
 struct_, union_, or enum_, as in C.struct_stat.
 
 The size of any C type T is available as C.sizeof_T, as in
 C.sizeof_struct_stat.
 
+A C function may be declared in the Go file with a parameter type of
+the special name _GoString_. This function may be called with an
+ordinary Go string value. The string length, and a pointer to the
+string contents, may be accessed by calling the C functions
+
+	size_t _GoStringLen(_GoString_ s);
+	const char *_GoStringPtr(_GoString_ s);
+
+These functions are only available in the preamble, not in other C
+files. The C code must not modify the contents of the pointer returned
+by _GoStringPtr. Note that the string contents may not have a trailing
+NUL byte.
+
 As Go doesn't have support for C's union type in the general case,
 C's union types are represented as a Go byte array with the same length.
 
@@ -241,7 +270,16 @@
 found in the _cgo_export.h generated header, after any preambles
 copied from the cgo input files. Functions with multiple
 return values are mapped to functions returning a struct.
+
 Not all Go types can be mapped to C types in a useful way.
+Go struct types are not supported; use a C struct type.
+Go array types are not supported; use a C pointer.
+
+Go functions that take arguments of type string may be called with the
+C type _GoString_, described above. The _GoString_ type will be
+automatically defined in the preamble. Note that there is no way for C
+code to create a value of this type; this is only useful for passing
+string values from Go to C and back to Go.
 
 Using //export in a file places a restriction on the preamble:
 since it is copied into two different C output files, it must not
@@ -264,6 +302,14 @@
 determined by how the memory was allocated; it has nothing to do with
 the type of the pointer.
 
+Note that values of some Go types, other than the type's zero value,
+always include Go pointers. This is true of string, slice, interface,
+channel, map, and function types. A pointer type may hold a Go pointer
+or a C pointer. Array and struct types may or may not include Go
+pointers, depending on the element types. All the discussion below
+about Go pointers applies not just to pointer types, but also to other
+types that include Go pointers.
+
 Go code may pass a Go pointer to C provided the Go memory to which it
 points does not contain any Go pointers. The C code must preserve
 this property: it must not store any Go pointers in Go memory, even
@@ -274,14 +320,17 @@
 array of the slice.
 
 C code may not keep a copy of a Go pointer after the call returns.
+This includes the _GoString_ type, which, as noted above, includes a
+Go pointer; _GoString_ values may not be retained by C code.
 
-A Go function called by C code may not return a Go pointer. A Go
-function called by C code may take C pointers as arguments, and it may
-store non-pointer or C pointer data through those pointers, but it may
-not store a Go pointer in memory pointed to by a C pointer. A Go
-function called by C code may take a Go pointer as an argument, but it
-must preserve the property that the Go memory to which it points does
-not contain any Go pointers.
+A Go function called by C code may not return a Go pointer (which
+implies that it may not return a string, slice, channel, and so
+forth). A Go function called by C code may take C pointers as
+arguments, and it may store non-pointer or C pointer data through
+those pointers, but it may not store a Go pointer in memory pointed to
+by a C pointer. A Go function called by C code may take a Go pointer
+as an argument, but it must preserve the property that the Go memory
+to which it points does not contain any Go pointers.
 
 Go code may not store a Go pointer in C memory. C code may store Go
 pointers in C memory, subject to the rule above: it must stop storing
@@ -299,6 +348,45 @@
 it likes. However, programs that break these rules are likely to fail
 in unexpected and unpredictable ways.
 
+Special cases
+
+A few special C types which would normally be represented by a pointer
+type in Go are instead represented by a uintptr. Those include:
+
+1. The *Ref types on Darwin, rooted at CoreFoundation's CFTypeRef type.
+
+2. The object types from Java's JNI interface:
+
+	jobject
+	jclass
+	jthrowable
+	jstring
+	jarray
+	jbooleanArray
+	jbyteArray
+	jcharArray
+	jshortArray
+	jintArray
+	jlongArray
+	jfloatArray
+	jdoubleArray
+	jobjectArray
+	jweak
+
+These types are uintptr on the Go side because they would otherwise
+confuse the Go garbage collector; they are sometimes not really
+pointers but data structures encoded in a pointer type. All operations
+on these types must happen in C. The proper constant to initialize an
+empty such reference is 0, not nil.
+
+These special cases were introduced in Go 1.10. For auto-updating code
+from Go 1.9 and earlier, use the cftype or jni rewrites in the Go fix tool:
+
+	go tool fix -r cftype <pkg>
+	go tool fix -r jni <pkg>
+
+It will replace nil with 0 in the appropriate places.
+
 Using cgo directly
 
 Usage:
@@ -312,32 +400,35 @@
 
 The following options are available when running cgo directly:
 
+	-V
+		Print cgo version and exit.
+	-debug-define
+		Debugging option. Print #defines.
+	-debug-gcc
+		Debugging option. Trace C compiler execution and output.
 	-dynimport file
 		Write list of symbols imported by file. Write to
 		-dynout argument or to standard output. Used by go
 		build when building a cgo package.
+	-dynlinker
+		Write dynamic linker as part of -dynimport output.
 	-dynout file
 		Write -dynimport output to file.
 	-dynpackage package
 		Set Go package for -dynimport output.
-	-dynlinker
-		Write dynamic linker as part of -dynimport output.
-	-godefs
-		Write out input file in Go syntax replacing C package
-		names with real values. Used to generate files in the
-		syscall package when bootstrapping a new target.
-	-srcdir directory
-		Find the Go input files, listed on the command line,
-		in directory.
-	-objdir directory
-		Put all generated files in directory.
-	-importpath string
-		The import path for the Go package. Optional; used for
-		nicer comments in the generated files.
 	-exportheader file
 		If there are any exported functions, write the
 		generated export declarations to file.
 		C code can #include this to see the declarations.
+	-importpath string
+		The import path for the Go package. Optional; used for
+		nicer comments in the generated files.
+	-import_runtime_cgo
+		If set (which it is by default) import runtime/cgo in
+		generated output.
+	-import_syscall
+		If set (which it is by default) import syscall in
+		generated output.
 	-gccgo
 		Generate output for the gccgo compiler rather than the
 		gc compiler.
@@ -345,16 +436,13 @@
 		The -fgo-prefix option to be used with gccgo.
 	-gccgopkgpath path
 		The -fgo-pkgpath option to be used with gccgo.
-	-import_runtime_cgo
-		If set (which it is by default) import runtime/cgo in
-		generated output.
-	-import_syscall
-		If set (which it is by default) import syscall in
-		generated output.
-	-debug-define
-		Debugging option. Print #defines.
-	-debug-gcc
-		Debugging option. Trace C compiler execution and output.
+	-godefs
+		Write out input file in Go syntax replacing C package
+		names with real values. Used to generate files in the
+		syscall package when bootstrapping a new target.
+	-objdir directory
+		Put all generated files in directory.
+	-srcdir directory
 */
 package main
 
@@ -403,21 +491,19 @@
 for later use.
 
 Next, cgo needs to identify the kinds for each identifier. For the
-identifiers C.foo and C.bar, cgo generates this C program:
+identifiers C.foo, cgo generates this C program:
 
 	<preamble>
 	#line 1 "not-declared"
-	void __cgo_f_xxx_1(void) { __typeof__(foo) *__cgo_undefined__; }
+	void __cgo_f_1_1(void) { __typeof__(foo) *__cgo_undefined__1; }
 	#line 1 "not-type"
-	void __cgo_f_xxx_2(void) { foo *__cgo_undefined__; }
-	#line 1 "not-const"
-	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (foo)*1 }; }
-	#line 2 "not-declared"
-	void __cgo_f_xxx_1(void) { __typeof__(bar) *__cgo_undefined__; }
-	#line 2 "not-type"
-	void __cgo_f_xxx_2(void) { bar *__cgo_undefined__; }
-	#line 2 "not-const"
-	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (bar)*1 }; }
+	void __cgo_f_1_2(void) { foo *__cgo_undefined__2; }
+	#line 1 "not-int-const"
+	void __cgo_f_1_3(void) { enum { __cgo_undefined__3 = (foo)*1 }; }
+	#line 1 "not-num-const"
+	void __cgo_f_1_4(void) { static const double __cgo_undefined__4 = (foo); }
+	#line 1 "not-str-lit"
+	void __cgo_f_1_5(void) { static const char __cgo_undefined__5[] = (foo); }
 
 This program will not compile, but cgo can use the presence or absence
 of an error message on a given line to deduce the information it
@@ -427,45 +513,72 @@
 
 An error on not-declared:1 indicates that foo is undeclared.
 An error on not-type:1 indicates that foo is not a type (if declared at all, it is an identifier).
-An error on not-const:1 indicates that foo is not an integer constant.
+An error on not-int-const:1 indicates that foo is not an integer constant.
+An error on not-num-const:1 indicates that foo is not a number constant.
+An error on not-str-lit:1 indicates that foo is not a string literal.
+An error on not-signed-int-const:1 indicates that foo is not a signed integer constant.
 
-The line number specifies the name involved. In the example, 1 is foo and 2 is bar.
+The line number specifies the name involved. In the example, 1 is foo.
 
 Next, cgo must learn the details of each type, variable, function, or
 constant. It can do this by reading object files. If cgo has decided
-that t1 is a type, v2 and v3 are variables or functions, and c4, c5,
-and c6 are constants, it generates:
+that t1 is a type, v2 and v3 are variables or functions, and i4, i5
+are integer constants, u6 is an unsigned integer constant, and f7 and f8
+are float constants, and s9 and s10 are string constants, it generates:
 
 	<preamble>
 	__typeof__(t1) *__cgo__1;
 	__typeof__(v2) *__cgo__2;
 	__typeof__(v3) *__cgo__3;
-	__typeof__(c4) *__cgo__4;
-	enum { __cgo_enum__4 = c4 };
-	__typeof__(c5) *__cgo__5;
-	enum { __cgo_enum__5 = c5 };
-	__typeof__(c6) *__cgo__6;
-	enum { __cgo_enum__6 = c6 };
+	__typeof__(i4) *__cgo__4;
+	enum { __cgo_enum__4 = i4 };
+	__typeof__(i5) *__cgo__5;
+	enum { __cgo_enum__5 = i5 };
+	__typeof__(u6) *__cgo__6;
+	enum { __cgo_enum__6 = u6 };
+	__typeof__(f7) *__cgo__7;
+	__typeof__(f8) *__cgo__8;
+	__typeof__(s9) *__cgo__9;
+	__typeof__(s10) *__cgo__10;
 
-	long long __cgo_debug_data[] = {
+	long long __cgodebug_ints[] = {
 		0, // t1
 		0, // v2
 		0, // v3
-		c4,
-		c5,
-		c6,
+		i4,
+		i5,
+		u6,
+		0, // f7
+		0, // f8
+		0, // s9
+		0, // s10
 		1
 	};
 
+	double __cgodebug_floats[] = {
+		0, // t1
+		0, // v2
+		0, // v3
+		0, // i4
+		0, // i5
+		0, // u6
+		f7,
+		f8,
+		0, // s9
+		0, // s10
+		1
+	};
+
+	const char __cgodebug_str__9[] = s9;
+	const unsigned long long __cgodebug_strlen__9 = sizeof(s9)-1;
+	const char __cgodebug_str__10[] = s10;
+	const unsigned long long __cgodebug_strlen__10 = sizeof(s10)-1;
+
 and again invokes the system C compiler, to produce an object file
 containing debug information. Cgo parses the DWARF debug information
 for __cgo__N to learn the type of each identifier. (The types also
-distinguish functions from global variables.) If using a standard gcc,
-cgo can parse the DWARF debug information for the __cgo_enum__N to
-learn the identifier's value. The LLVM-based gcc on OS X emits
-incomplete DWARF information for enums; in that case cgo reads the
-constant values from the __cgo_debug_data from the object file's data
-segment.
+distinguish functions from global variables.) Cgo reads the constant
+values from the __cgodebug_* from the object file's data segment.
 
 At this point cgo knows the meaning of each C.xxx well enough to start
 the translation process.
@@ -550,9 +663,12 @@
 
 	int main() { return 0; }
 	void crosscall2(void(*fn)(void*, int, uintptr_t), void *a, int c, uintptr_t ctxt) { }
-	uintptr_t _cgo_wait_runtime_init_done() { }
+	uintptr_t _cgo_wait_runtime_init_done() { return 0; }
+	void _cgo_release_context(uintptr_t ctxt) { }
+	char* _cgo_topofstack(void) { return (char*)0; }
 	void _cgo_allocate(void *a, int c) { }
 	void _cgo_panic(void *a, int c) { }
+	void _cgo_reginit(void) { }
 
 The extra functions here are stubs to satisfy the references in the C
 code generated for gcc. The build process links this stub, along with
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index ff8b813..2ebe906 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -169,21 +169,8 @@
 		p.loadDWARF(f, needType)
 	}
 	if p.rewriteCalls(f) {
-		// Add `import _cgo_unsafe "unsafe"` as the first decl
-		// after the package statement.
-		imp := &ast.GenDecl{
-			Tok: token.IMPORT,
-			Specs: []ast.Spec{
-				&ast.ImportSpec{
-					Name: ast.NewIdent("_cgo_unsafe"),
-					Path: &ast.BasicLit{
-						Kind:  token.STRING,
-						Value: `"unsafe"`,
-					},
-				},
-			},
-		}
-		f.AST.Decls = append([]ast.Decl{imp}, f.AST.Decls...)
+		// Add `import _cgo_unsafe "unsafe"` after the package statement.
+		f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
 	}
 	p.rewriteRef(f)
 }
@@ -192,8 +179,8 @@
 // in the file f and saves relevant renamings in f.Name[name].Define.
 func (p *Package) loadDefines(f *File) {
 	var b bytes.Buffer
-	b.WriteString(f.Preamble)
 	b.WriteString(builtinProlog)
+	b.WriteString(f.Preamble)
 	stdout := p.gccDefines(b.Bytes())
 
 	for _, line := range strings.Split(stdout, "\n") {
@@ -237,6 +224,7 @@
 	// Determine kinds for names we already know about,
 	// like #defines or 'struct foo', before bothering with gcc.
 	var names, needType []*Name
+	optional := map[*Name]bool{}
 	for _, key := range nameKeys(f.Name) {
 		n := f.Name[key]
 		// If we've already found this name as a #define
@@ -264,10 +252,6 @@
 			if n.IsConst() {
 				continue
 			}
-
-			if isName(n.Define) {
-				n.C = n.Define
-			}
 		}
 
 		// If this is a struct, union, or enum type name, no need to guess the kind.
@@ -277,6 +261,14 @@
 			continue
 		}
 
+		if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
+			// For FooRef, find out if FooGetTypeID exists.
+			s := n.C[:len(n.C)-3] + "GetTypeID"
+			n := &Name{Go: s, C: s}
+			names = append(names, n)
+			optional[n] = true
+		}
+
 		// Otherwise, we'll need to find out from gcc.
 		names = append(names, n)
 	}
@@ -296,57 +288,45 @@
 	// For each name, we generate these lines, where xxx is the index in toSniff plus one.
 	//
 	//	#line xxx "not-declared"
-	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
+	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
 	//	#line xxx "not-type"
-	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
+	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
 	//	#line xxx "not-int-const"
-	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
+	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
 	//	#line xxx "not-num-const"
-	//	void __cgo_f_xxx_4(void) { static const double x = (name); }
+	//	void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
 	//	#line xxx "not-str-lit"
-	//	void __cgo_f_xxx_5(void) { static const char x[] = (name); }
-	//	#line xxx "not-signed-int-const"
-	//	#if 0 < -(name)
-	//	#line xxx "not-signed-int-const"
-	//	#error found unsigned int
-	//	#endif
+	//	void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
 	//
 	// If we see an error at not-declared:xxx, the corresponding name is not declared.
 	// If we see an error at not-type:xxx, the corresponding name is a type.
 	// If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
 	// If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
 	// If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
-	// If we see an error at not-signed-int-const:xxx, the corresponding name is not a signed integer literal.
 	//
 	// The specific input forms are chosen so that they are valid C syntax regardless of
 	// whether name denotes a type or an expression.
 
 	var b bytes.Buffer
-	b.WriteString(f.Preamble)
 	b.WriteString(builtinProlog)
+	b.WriteString(f.Preamble)
 
 	for i, n := range names {
 		fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
-			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
+			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
 			"#line %d \"not-type\"\n"+
-			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
+			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
 			"#line %d \"not-int-const\"\n"+
-			"void __cgo_f_%d_3(void) { enum { __cgo_undefined__ = (%s)*1 }; }\n"+
+			"void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
 			"#line %d \"not-num-const\"\n"+
-			"void __cgo_f_%d_4(void) { static const double x = (%s); }\n"+
+			"void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
 			"#line %d \"not-str-lit\"\n"+
-			"void __cgo_f_%d_5(void) { static const char s[] = (%s); }\n"+
-			"#line %d \"not-signed-int-const\"\n"+
-			"#if 0 < (%s)\n"+
-			"#line %d \"not-signed-int-const\"\n"+
-			"#error found unsigned int\n"+
-			"#endif\n",
+			"void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
 			i+1, i+1, n.C,
 			i+1, i+1, n.C,
 			i+1, i+1, n.C,
 			i+1, i+1, n.C,
 			i+1, i+1, n.C,
-			i+1, n.C, i+1,
 		)
 	}
 	fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
@@ -365,7 +345,6 @@
 		notNumConst
 		notStrLiteral
 		notDeclared
-		notSignedIntConst
 	)
 	sawUnmatchedErrors := false
 	for _, line := range strings.Split(stderr, "\n") {
@@ -419,8 +398,6 @@
 			sniff[i] |= notNumConst
 		case "not-str-lit":
 			sniff[i] |= notStrLiteral
-		case "not-signed-int-const":
-			sniff[i] |= notSignedIntConst
 		default:
 			if isError {
 				sawUnmatchedErrors = true
@@ -436,22 +413,16 @@
 	}
 
 	for i, n := range names {
-		switch sniff[i] &^ notSignedIntConst {
+		switch sniff[i] {
 		default:
-			var tpos token.Pos
-			for _, ref := range f.Ref {
-				if ref.Name == n {
-					tpos = ref.Pos()
-					break
-				}
+			if sniff[i]&notDeclared != 0 && optional[n] {
+				// Ignore optional undeclared identifiers.
+				// Don't report an error, and skip adding n to the needType array.
+				continue
 			}
-			error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go))
+			error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
 		case notStrLiteral | notType:
-			if sniff[i]&notSignedIntConst != 0 {
-				n.Kind = "uconst"
-			} else {
-				n.Kind = "iconst"
-			}
+			n.Kind = "iconst"
 		case notIntConst | notStrLiteral | notType:
 			n.Kind = "fconst"
 		case notIntConst | notNumConst | notType:
@@ -461,6 +432,7 @@
 		case notIntConst | notNumConst | notStrLiteral | notType:
 			n.Kind = "not-type"
 		}
+		needType = append(needType, n)
 	}
 	if nerrors > 0 {
 		// Check if compiling the preamble by itself causes any errors,
@@ -474,7 +446,6 @@
 		fatalf("unresolved names")
 	}
 
-	needType = append(needType, names...)
 	return needType
 }
 
@@ -491,12 +462,12 @@
 	// for each entry in names and then dereference the type we
 	// learn for __cgo__i.
 	var b bytes.Buffer
-	b.WriteString(f.Preamble)
 	b.WriteString(builtinProlog)
+	b.WriteString(f.Preamble)
 	b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
 	for i, n := range names {
 		fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
-		if n.Kind == "iconst" || n.Kind == "uconst" {
+		if n.Kind == "iconst" {
 			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
 		}
 	}
@@ -505,7 +476,7 @@
 	// so we can read them out of the object file.
 	fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
 	for _, n := range names {
-		if n.Kind == "iconst" || n.Kind == "uconst" {
+		if n.Kind == "iconst" {
 			fmt.Fprintf(&b, "\t%s,\n", n.C)
 		} else {
 			fmt.Fprintf(&b, "\t0,\n")
@@ -543,14 +514,6 @@
 
 	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
 	types := make([]dwarf.Type, len(names))
-	nameToIndex := make(map[*Name]int)
-	for i, n := range names {
-		nameToIndex[n] = i
-	}
-	nameToRef := make(map[*Name]*Ref)
-	for _, ref := range f.Ref {
-		nameToRef[ref.Name] = ref
-	}
 	r := d.Reader()
 	for {
 		e, err := r.Next()
@@ -598,13 +561,15 @@
 	var conv typeConv
 	conv.Init(p.PtrSize, p.IntSize)
 	for i, n := range names {
+		if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
+			conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
+		}
+	}
+	for i, n := range names {
 		if types[i] == nil {
 			continue
 		}
-		pos := token.NoPos
-		if ref, ok := nameToRef[n]; ok {
-			pos = ref.Pos()
-		}
+		pos := f.NamePos[n]
 		f, fok := types[i].(*dwarf.FuncType)
 		if n.Kind != "type" && fok {
 			n.Kind = "func"
@@ -614,11 +579,11 @@
 			switch n.Kind {
 			case "iconst":
 				if i < len(ints) {
-					n.Const = fmt.Sprintf("%#x", ints[i])
-				}
-			case "uconst":
-				if i < len(ints) {
-					n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
+					if _, ok := types[i].(*dwarf.UintType); ok {
+						n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
+					} else {
+						n.Const = fmt.Sprintf("%#x", ints[i])
+					}
 				}
 			case "fconst":
 				if i < len(floats) {
@@ -759,8 +724,9 @@
 		stmts = append(stmts, stmt)
 	}
 
+	const cgoMarker = "__cgo__###__marker__"
 	fcall := &ast.CallExpr{
-		Fun:  call.Call.Fun,
+		Fun:  ast.NewIdent(cgoMarker),
 		Args: nargs,
 	}
 	ftype := &ast.FuncType{
@@ -782,31 +748,26 @@
 		}
 	}
 
-	// There is a Ref pointing to the old call.Call.Fun.
+	// If this call expects two results, we have to
+	// adjust the results of the function we generated.
 	for _, ref := range f.Ref {
-		if ref.Expr == &call.Call.Fun {
-			ref.Expr = &fcall.Fun
-
-			// If this call expects two results, we have to
-			// adjust the results of the function we generated.
-			if ref.Context == "call2" {
-				if ftype.Results == nil {
-					// An explicit void argument
-					// looks odd but it seems to
-					// be how cgo has worked historically.
-					ftype.Results = &ast.FieldList{
-						List: []*ast.Field{
-							&ast.Field{
-								Type: ast.NewIdent("_Ctype_void"),
-							},
+		if ref.Expr == &call.Call.Fun && ref.Context == ctxCall2 {
+			if ftype.Results == nil {
+				// An explicit void argument
+				// looks odd but it seems to
+				// be how cgo has worked historically.
+				ftype.Results = &ast.FieldList{
+					List: []*ast.Field{
+						&ast.Field{
+							Type: ast.NewIdent("_Ctype_void"),
 						},
-					}
+					},
 				}
-				ftype.Results.List = append(ftype.Results.List,
-					&ast.Field{
-						Type: ast.NewIdent("error"),
-					})
 			}
+			ftype.Results.List = append(ftype.Results.List,
+				&ast.Field{
+					Type: ast.NewIdent("error"),
+				})
 		}
 	}
 
@@ -820,14 +781,16 @@
 			Results: []ast.Expr{fcall},
 		}
 	}
-	call.Call.Fun = &ast.FuncLit{
+	lit := &ast.FuncLit{
 		Type: ftype,
 		Body: &ast.BlockStmt{
 			List: append(stmts, fbody),
 		},
 	}
-	call.Call.Lparen = token.NoPos
-	call.Call.Rparen = token.NoPos
+	text := strings.Replace(gofmt(lit), "\n", ";", -1)
+	repl := strings.Split(text, cgoMarker)
+	f.Edit.Insert(f.offset(call.Call.Fun.Pos()), repl[0])
+	f.Edit.Insert(f.offset(call.Call.Fun.End()), repl[1])
 
 	return needsUnsafe
 }
@@ -981,8 +944,8 @@
 // effect is a function call.
 func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
 	found := false
-	f.walk(x, "expr",
-		func(f *File, x interface{}, context string) {
+	f.walk(x, ctxExpr,
+		func(f *File, x interface{}, context astContext) {
 			switch x.(type) {
 			case *ast.CallExpr:
 				found = true
@@ -1091,7 +1054,17 @@
 	// Assign mangled names.
 	for _, n := range f.Name {
 		if n.Kind == "not-type" {
-			n.Kind = "var"
+			if n.Define == "" {
+				n.Kind = "var"
+			} else {
+				n.Kind = "macro"
+				n.FuncType = &FuncType{
+					Result: n.Type,
+					Go: &ast.FuncType{
+						Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
+					},
+				}
+			}
 		}
 		if n.Mangle == "" {
 			p.mangleName(n)
@@ -1111,10 +1084,10 @@
 		}
 		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
 		switch r.Context {
-		case "call", "call2":
+		case ctxCall, ctxCall2:
 			if r.Name.Kind != "func" {
 				if r.Name.Kind == "type" {
-					r.Context = "type"
+					r.Context = ctxType
 					if r.Name.Type == nil {
 						error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
 						break
@@ -1126,7 +1099,7 @@
 				break
 			}
 			functions[r.Name.Go] = true
-			if r.Context == "call2" {
+			if r.Context == ctxCall2 {
 				if r.Name.Go == "_CMalloc" {
 					error_(r.Pos(), "no two-result form for C.malloc")
 					break
@@ -1144,8 +1117,9 @@
 				r.Name = n
 				break
 			}
-		case "expr":
-			if r.Name.Kind == "func" {
+		case ctxExpr:
+			switch r.Name.Kind {
+			case "func":
 				if builtinDefs[r.Name.C] != "" {
 					error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
 				}
@@ -1172,25 +1146,25 @@
 					Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
 					Args: []ast.Expr{ast.NewIdent(name.Mangle)},
 				}
-			} else if r.Name.Kind == "type" {
+			case "type":
 				// Okay - might be new(T)
 				if r.Name.Type == nil {
 					error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
 					break
 				}
 				expr = r.Name.Type.Go
-			} else if r.Name.Kind == "var" {
+			case "var":
 				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
+			case "macro":
+				expr = &ast.CallExpr{Fun: expr}
 			}
-
-		case "selector":
+		case ctxSelector:
 			if r.Name.Kind == "var" {
 				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
 			} else {
 				error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
 			}
-
-		case "type":
+		case ctxType:
 			if r.Name.Kind != "type" {
 				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
 			} else if r.Name.Type == nil {
@@ -1205,6 +1179,7 @@
 				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
 			}
 		}
+
 		if *godefs {
 			// Substitute definition for mangled type name.
 			if id, ok := expr.(*ast.Ident); ok {
@@ -1226,7 +1201,17 @@
 			expr = &ast.Ident{NamePos: pos, Name: x.Name}
 		}
 
+		// Change AST, because some later processing depends on it,
+		// and also because -godefs mode still prints the AST.
+		old := *r.Expr
 		*r.Expr = expr
+
+		// Record source-level edit for cgo output.
+		repl := gofmt(expr)
+		if r.Name.Kind != "type" {
+			repl = "(" + repl + ")"
+		}
+		f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
 	}
 
 	// Remove functions only used as expressions, so their respective
@@ -1251,7 +1236,7 @@
 	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
 		return ret
 	}
-	return strings.Fields(defaultCC)
+	return strings.Fields(defaultCC(goos, goarch))
 }
 
 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
@@ -1676,6 +1661,9 @@
 	// Keys of ptrs in insertion order (deterministic worklist)
 	ptrKeys []dwarf.Type
 
+	// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
+	getTypeIDs map[string]bool
+
 	// Predeclared types.
 	bool                                   ast.Expr
 	byte                                   ast.Expr // denotes padding
@@ -1705,6 +1693,7 @@
 	c.intSize = intSize
 	c.m = make(map[dwarf.Type]*Type)
 	c.ptrs = make(map[dwarf.Type][]*Type)
+	c.getTypeIDs = make(map[string]bool)
 	c.bool = c.Ident("bool")
 	c.byte = c.Ident("byte")
 	c.int8 = c.Ident("int8")
@@ -2091,6 +2080,12 @@
 		name := c.Ident("_Ctype_" + dt.Name)
 		goIdent[name.Name] = name
 		sub := c.Type(dt.Type, pos)
+		if c.badPointerTypedef(dt) {
+			// Treat this typedef as a uintptr.
+			s := *sub
+			s.Go = c.uintptr
+			sub = &s
+		}
 		t.Go = name
 		if unionWithPointer[sub.Go] {
 			unionWithPointer[t.Go] = true
@@ -2171,7 +2166,7 @@
 			if ss, ok := dwarfToName[s]; ok {
 				s = ss
 			}
-			s = strings.Join(strings.Split(s, " "), "") // strip spaces
+			s = strings.Replace(s, " ", "", -1)
 			name := c.Ident("_Ctype_" + s)
 			tt := *t
 			typedef[name.Name] = &tt
@@ -2249,6 +2244,11 @@
 			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
 				break
 			}
+			// ...or the typedef is one in which we expect bad pointers.
+			// It will be a uintptr instead of *X.
+			if c.badPointerTypedef(dt) {
+				break
+			}
 
 			t = c.Type(ptr, pos)
 			if t == nil {
@@ -2405,7 +2405,9 @@
 		size := t.Size
 		talign := t.Align
 		if f.BitSize > 0 {
-			if f.BitSize%8 != 0 {
+			switch f.BitSize {
+			case 8, 16, 32, 64:
+			default:
 				continue
 			}
 			size = f.BitSize / 8
@@ -2581,3 +2583,139 @@
 	}
 	return prefix
 }
+
+// badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
+// A typedef is bad if C code sometimes stores non-pointers in this type.
+// TODO: Currently our best solution is to find these manually and list them as
+// they come up. A better solution is desired.
+func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
+	if c.badCFType(dt) {
+		return true
+	}
+	if c.badJNI(dt) {
+		return true
+	}
+	return false
+}
+
+func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
+	// The real bad types are CFNumberRef and CFDateRef.
+	// Sometimes non-pointers are stored in these types.
+	// CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
+	// We return true for the other *Ref types just so casting between them is easier.
+	// We identify the correct set of types as those ending in Ref and for which
+	// there exists a corresponding GetTypeID function.
+	// See comment below for details about the bad pointers.
+	if goos != "darwin" {
+		return false
+	}
+	s := dt.Name
+	if !strings.HasSuffix(s, "Ref") {
+		return false
+	}
+	s = s[:len(s)-3]
+	if s == "CFType" {
+		return true
+	}
+	if c.getTypeIDs[s] {
+		return true
+	}
+	if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
+		// Mutable and immutable variants share a type ID.
+		return true
+	}
+	return false
+}
+
+// Comment from Darwin's CFInternal.h
+/*
+// Tagged pointer support
+// Low-bit set means tagged object, next 3 bits (currently)
+// define the tagged object class, next 4 bits are for type
+// information for the specific tagged object class.  Thus,
+// the low byte is for type info, and the rest of a pointer
+// (32 or 64-bit) is for payload, whatever the tagged class.
+//
+// Note that the specific integers used to identify the
+// specific tagged classes can and will change from release
+// to release (that's why this stuff is in CF*Internal*.h),
+// as can the definition of type info vs payload above.
+//
+#if __LP64__
+#define CF_IS_TAGGED_OBJ(PTR)	((uintptr_t)(PTR) & 0x1)
+#define CF_TAGGED_OBJ_TYPE(PTR)	((uintptr_t)(PTR) & 0xF)
+#else
+#define CF_IS_TAGGED_OBJ(PTR)	0
+#define CF_TAGGED_OBJ_TYPE(PTR)	0
+#endif
+
+enum {
+    kCFTaggedObjectID_Invalid = 0,
+    kCFTaggedObjectID_Atom = (0 << 1) + 1,
+    kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
+    kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
+    kCFTaggedObjectID_Integer = (3 << 1) + 1,
+    kCFTaggedObjectID_DateTS = (4 << 1) + 1,
+    kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
+    kCFTaggedObjectID_Date = (6 << 1) + 1,
+    kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
+};
+*/
+
+func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
+	// In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
+	// property that it is sometimes (always?) a small integer instead of a real pointer.
+	// Note: although only the android JVMs are bad in this respect, we declare the JNI types
+	// bad regardless of platform, so the same Go code compiles on both android and non-android.
+	if parent, ok := jniTypes[dt.Name]; ok {
+		// Try to make sure we're talking about a JNI type, not just some random user's
+		// type that happens to use the same name.
+		// C doesn't have the notion of a package, so it's hard to be certain.
+
+		// Walk up to jobject, checking each typedef on the way.
+		w := dt
+		for parent != "" {
+			t, ok := w.Type.(*dwarf.TypedefType)
+			if !ok || t.Name != parent {
+				return false
+			}
+			w = t
+			parent, ok = jniTypes[w.Name]
+			if !ok {
+				return false
+			}
+		}
+
+		// Check that the typedef is:
+		//     struct _jobject;
+		//     typedef struct _jobject *jobject;
+		if ptr, ok := w.Type.(*dwarf.PtrType); ok {
+			if str, ok := ptr.Type.(*dwarf.StructType); ok {
+				if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+
+// jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
+// they are mapped.  The base "jobject" maps to the empty string.
+var jniTypes = map[string]string{
+	"jobject":       "",
+	"jclass":        "jobject",
+	"jthrowable":    "jobject",
+	"jstring":       "jobject",
+	"jarray":        "jobject",
+	"jbooleanArray": "jarray",
+	"jbyteArray":    "jarray",
+	"jcharArray":    "jarray",
+	"jshortArray":   "jarray",
+	"jintArray":     "jarray",
+	"jlongArray":    "jarray",
+	"jfloatArray":   "jarray",
+	"jdoubleArray":  "jarray",
+	"jobjectArray":  "jarray",
+	"jweak":         "jobject",
+}
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index 3dc3d14..0c1c863 100644
--- a/src/cmd/cgo/main.go
+++ b/src/cmd/cgo/main.go
@@ -24,6 +24,9 @@
 	"runtime"
 	"sort"
 	"strings"
+
+	"cmd/internal/edit"
+	"cmd/internal/objabi"
 )
 
 // A Package collects information about the package we're going to write.
@@ -54,6 +57,12 @@
 	Calls    []*Call             // all calls to C.xxx in AST
 	ExpFunc  []*ExpFunc          // exported functions for this file
 	Name     map[string]*Name    // map from Go name to Name
+	NamePos  map[*Name]token.Pos // map from Name to position of the first reference
+	Edit     *edit.Buffer
+}
+
+func (f *File) offset(p token.Pos) int {
+	return fset.Position(p).Offset
 }
 
 func nameKeys(m map[string]*Name) []string {
@@ -75,7 +84,7 @@
 type Ref struct {
 	Name    *Name
 	Expr    *ast.Expr
-	Context string // "type", "expr", "call", or "call2"
+	Context astContext
 }
 
 func (r *Ref) Pos() token.Pos {
@@ -88,7 +97,7 @@
 	Mangle   string // name used in generated Go
 	C        string // name used in C
 	Define   string // #define expansion
-	Kind     string // "iconst", "uconst", "fconst", "sconst", "type", "var", "fpvar", "func", "not-type"
+	Kind     string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"
 	Type     *Type  // the type of xxx
 	FuncType *FuncType
 	AddError bool
@@ -100,12 +109,12 @@
 	return n.Kind == "var" || n.Kind == "fpvar"
 }
 
-// IsConst reports whether Kind is either "iconst", "uconst", "fconst" or "sconst"
+// IsConst reports whether Kind is either "iconst", "fconst" or "sconst"
 func (n *Name) IsConst() bool {
 	return strings.HasSuffix(n.Kind, "const")
 }
 
-// A ExpFunc is an exported function, callable from C.
+// An ExpFunc is an exported function, callable from C.
 // Such functions are identified in the Go input file
 // by doc comments containing the line //export ExpName
 type ExpFunc struct {
@@ -200,6 +209,7 @@
 var goarch, goos string
 
 func main() {
+	objabi.AddVersionFlag() // -V
 	flag.Usage = usage
 	flag.Parse()
 
@@ -280,6 +290,7 @@
 		}
 
 		f := new(File)
+		f.Edit = edit.NewBuffer(b)
 		f.ParseGo(input, b)
 		f.DiscardCgoDirectives()
 		fs[i] = f
@@ -300,11 +311,13 @@
 		p.Translate(f)
 		for _, cref := range f.Ref {
 			switch cref.Context {
-			case "call", "call2":
+			case ctxCall, ctxCall2:
 				if cref.Name.Kind != "type" {
 					break
 				}
+				old := *cref.Expr
 				*cref.Expr = cref.Name.Type.Go
+				f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), gofmt(cref.Name.Type.Go))
 			}
 		}
 		if nerrors > 0 {
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 9ab6bd8..070429f 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -15,6 +15,7 @@
 	"go/token"
 	"io"
 	"os"
+	"path/filepath"
 	"sort"
 	"strings"
 )
@@ -110,7 +111,13 @@
 		// Which is not useful. Moreover we never override source info,
 		// so subsequent source code uses the same source info.
 		// Moreover, empty file name makes compile emit no source debug info at all.
-		noSourceConf.Fprint(fgo2, fset, def.Go)
+		var buf bytes.Buffer
+		noSourceConf.Fprint(&buf, fset, def.Go)
+		if bytes.HasPrefix(buf.Bytes(), []byte("_Ctype_")) {
+			// This typedef is of the form `typedef a b` and should be an alias.
+			fmt.Fprintf(fgo2, "= ")
+		}
+		fmt.Fprintf(fgo2, "%s", buf.Bytes())
 		fmt.Fprintf(fgo2, "\n\n")
 	}
 	if *gccgo {
@@ -400,10 +407,12 @@
 	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 d.Type.Params != 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 {
@@ -502,8 +511,10 @@
 		fmt.Fprintf(fgo2, "\tif errno != 0 { r2 = syscall.Errno(errno) }\n")
 	}
 	fmt.Fprintf(fgo2, "\tif _Cgo_always_false {\n")
-	for i := range d.Type.Params.List {
-		fmt.Fprintf(fgo2, "\t\t_Cgo_use(p%d)\n", i)
+	if d.Type.Params != nil {
+		for i := range d.Type.Params.List {
+			fmt.Fprintf(fgo2, "\t\t_Cgo_use(p%d)\n", i)
+		}
 	}
 	fmt.Fprintf(fgo2, "\t}\n")
 	fmt.Fprintf(fgo2, "\treturn\n")
@@ -516,7 +527,7 @@
 	if strings.HasSuffix(base, ".go") {
 		base = base[0 : len(base)-3]
 	}
-	base = strings.Map(slashToUnderscore, base)
+	base = filepath.Base(base)
 	fgo1 := creat(*objDir + base + ".cgo1.go")
 	fgcc := creat(*objDir + base + ".cgo2.c")
 
@@ -525,10 +536,12 @@
 
 	// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
 	fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n\n")
-	conf.Fprint(fgo1, fset, f.AST)
+	fmt.Fprintf(fgo1, "//line %s:1\n", srcfile)
+	fgo1.Write(f.Edit.Bytes())
 
 	// While we process the vars and funcs, also write gcc output.
 	// Gcc output starts with the preamble.
+	fmt.Fprintf(fgcc, "%s\n", builtinProlog)
 	fmt.Fprintf(fgcc, "%s\n", f.Preamble)
 	fmt.Fprintf(fgcc, "%s\n", gccProlog)
 	fmt.Fprintf(fgcc, "%s\n", tsanProlog)
@@ -615,14 +628,18 @@
 			fmt.Fprint(fgcc, "(__typeof__(a->r)) ")
 		}
 	}
-	fmt.Fprintf(fgcc, "%s(", n.C)
-	for i := range n.FuncType.Params {
-		if i > 0 {
-			fmt.Fprintf(fgcc, ", ")
+	if n.Kind == "macro" {
+		fmt.Fprintf(fgcc, "%s;\n", n.C)
+	} else {
+		fmt.Fprintf(fgcc, "%s(", n.C)
+		for i := range n.FuncType.Params {
+			if i > 0 {
+				fmt.Fprintf(fgcc, ", ")
+			}
+			fmt.Fprintf(fgcc, "a->p%d", i)
 		}
-		fmt.Fprintf(fgcc, "a->p%d", i)
+		fmt.Fprintf(fgcc, ");\n")
 	}
-	fmt.Fprintf(fgcc, ");\n")
 	if n.AddError {
 		fmt.Fprintf(fgcc, "\t_cgo_errno = errno;\n")
 	}
@@ -678,14 +695,18 @@
 			fmt.Fprintf(fgcc, "(void*)")
 		}
 	}
-	fmt.Fprintf(fgcc, "%s(", n.C)
-	for i := range n.FuncType.Params {
-		if i > 0 {
-			fmt.Fprintf(fgcc, ", ")
+	if n.Kind == "macro" {
+		fmt.Fprintf(fgcc, "%s;\n", n.C)
+	} else {
+		fmt.Fprintf(fgcc, "%s(", n.C)
+		for i := range n.FuncType.Params {
+			if i > 0 {
+				fmt.Fprintf(fgcc, ", ")
+			}
+			fmt.Fprintf(fgcc, "p%d", i)
 		}
-		fmt.Fprintf(fgcc, "p%d", i)
+		fmt.Fprintf(fgcc, ");\n")
 	}
-	fmt.Fprintf(fgcc, ");\n")
 	fmt.Fprintf(fgcc, "\t_cgo_tsan_release();\n")
 	if t := n.FuncType.Result; t != nil {
 		fmt.Fprintf(fgcc, "\treturn ")
@@ -985,7 +1006,7 @@
 		default:
 			// Declare a result struct.
 			fmt.Fprintf(fgcch, "\n/* Return type for %s */\n", exp.ExpName)
-			fmt.Fprintf(fgcch, "struct %s_result {\n", exp.ExpName)
+			fmt.Fprintf(fgcch, "struct %s_return {\n", exp.ExpName)
 			forFieldList(fntype.Results,
 				func(i int, aname string, atype ast.Expr) {
 					t := p.cgoType(atype)
@@ -996,7 +1017,7 @@
 					fmt.Fprint(fgcch, "\n")
 				})
 			fmt.Fprintf(fgcch, "};\n")
-			fmt.Fprintf(cdeclBuf, "struct %s_result", exp.ExpName)
+			fmt.Fprintf(cdeclBuf, "struct %s_return", exp.ExpName)
 		}
 
 		cRet := cdeclBuf.String()
@@ -1022,7 +1043,7 @@
 			fmt.Fprintf(fgcch, "\n%s", exp.Doc)
 		}
 
-		fmt.Fprintf(fgcch, "extern %s %s %s;\n", cRet, exp.ExpName, cParams)
+		fmt.Fprintf(fgcch, "extern %s %s%s;\n", cRet, exp.ExpName, cParams)
 
 		// We need to use a name that will be exported by the
 		// Go code; otherwise gccgo will make it static and we
@@ -1131,6 +1152,7 @@
 		pkg = p.PackagePath
 	}
 	fmt.Fprintf(fgcch, "/* package %s */\n\n", pkg)
+	fmt.Fprintf(fgcch, "%s\n", builtinExportProlog)
 
 	fmt.Fprintf(fgcch, "/* Start of preamble from import \"C\" comments.  */\n\n")
 	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
@@ -1223,8 +1245,9 @@
 			// Slice: pointer, len, cap.
 			return &Type{Size: p.PtrSize * 3, Align: p.PtrSize, C: c("GoSlice")}
 		}
+		// Non-slice array types are not supported.
 	case *ast.StructType:
-		// TODO
+		// Not supported.
 	case *ast.FuncType:
 		return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*")}
 	case *ast.InterfaceType:
@@ -1374,7 +1397,7 @@
 /* Define intgo when compiling with GCC.  */
 typedef ptrdiff_t intgo;
 
-typedef struct { char *p; intgo n; } _GoString_;
+typedef struct { const char *p; intgo n; } _GoString_;
 typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
 _GoString_ GoString(char *p);
 _GoString_ GoStringN(char *p, int l);
@@ -1382,6 +1405,12 @@
 char *CString(_GoString_);
 void *CBytes(_GoBytes_);
 void *_CMalloc(size_t);
+
+__attribute__ ((unused))
+static size_t _GoStringLen(_GoString_ s) { return s.n; }
+
+__attribute__ ((unused))
+static const char *_GoStringPtr(_GoString_ s) { return s.p; }
 `
 
 const goProlog = `
@@ -1613,6 +1642,25 @@
 }
 `
 
+// builtinExportProlog is a shorter version of builtinProlog,
+// to be put into the _cgo_export.h file.
+// For historical reasons we can't use builtinProlog in _cgo_export.h,
+// because _cgo_export.h defines GoString as a struct while builtinProlog
+// defines it as a function. We don't change this to avoid unnecessarily
+// breaking existing code.
+const builtinExportProlog = `
+#line 1 "cgo-builtin-prolog"
+
+#include <stddef.h> /* for ptrdiff_t below */
+
+#ifndef GO_CGO_EXPORT_PROLOGUE_H
+#define GO_CGO_EXPORT_PROLOGUE_H
+
+typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+
+#endif
+`
+
 func (p *Package) gccExportHeaderProlog() string {
 	return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
 }
@@ -1646,7 +1694,7 @@
 */
 typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
 
-typedef struct { const char *p; GoInt n; } GoString;
+typedef _GoString_ GoString;
 typedef void *GoMap;
 typedef void *GoChan;
 typedef struct { void *t; void *v; } GoInterface;
diff --git a/src/cmd/cgo/zdefaultcc.go b/src/cmd/cgo/zdefaultcc.go
index 91177e9..bcdbb28 100644
--- a/src/cmd/cgo/zdefaultcc.go
+++ b/src/cmd/cgo/zdefaultcc.go
@@ -1,7 +1,15 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package main
 
-const defaultCC = `clang`
-const defaultCXX = `clang++`
 const defaultPkgConfig = `pkg-config`
+func defaultCC(goos, goarch string) string {
+	switch goos+`/`+goarch {
+	}
+	return "clang"
+}
+func defaultCXX(goos, goarch string) string {
+	switch goos+`/`+goarch {
+	}
+	return "clang++"
+}
diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go
index 59de326..7342b54 100644
--- a/src/cmd/compile/fmt_test.go
+++ b/src/cmd/compile/fmt_test.go
@@ -229,7 +229,7 @@
 			}
 		}
 		if mismatch {
-			t.Errorf("knownFormats is out of date; please run with -v to regenerate")
+			t.Errorf("knownFormats is out of date; please 'go test -v fmt_test.go > foo', then extract new definition of knownFormats from foo")
 		}
 	}
 
@@ -419,7 +419,7 @@
 // formatIter iterates through the string s in increasing
 // index order and calls f for each format specifier '%..v'.
 // The arguments for f describe the specifier's index range.
-// If a format specifier contains a  "*", f is called with
+// If a format specifier contains a "*", f is called with
 // the index range for "*" alone, before being called for
 // the entire specifier. The result of f is the index of
 // the rune at which iteration continues.
@@ -571,9 +571,14 @@
 	"*cmd/compile/internal/ssa.Block %s":              "",
 	"*cmd/compile/internal/ssa.Block %v":              "",
 	"*cmd/compile/internal/ssa.Func %s":               "",
+	"*cmd/compile/internal/ssa.Func %v":               "",
+	"*cmd/compile/internal/ssa.LocalSlot %+v":         "",
+	"*cmd/compile/internal/ssa.LocalSlot %v":          "",
+	"*cmd/compile/internal/ssa.Register %s":           "",
 	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
 	"*cmd/compile/internal/ssa.Value %s":              "",
 	"*cmd/compile/internal/ssa.Value %v":              "",
+	"*cmd/compile/internal/ssa.VarLoc %v":             "",
 	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
 	"*cmd/compile/internal/types.Field %p":            "",
 	"*cmd/compile/internal/types.Field %v":            "",
@@ -592,25 +597,30 @@
 	"*cmd/compile/internal/types.Type %p":             "",
 	"*cmd/compile/internal/types.Type %s":             "",
 	"*cmd/compile/internal/types.Type %v":             "",
+	"*cmd/internal/dwarf.Location %#v":                "",
 	"*cmd/internal/obj.Addr %v":                       "",
 	"*cmd/internal/obj.LSym %v":                       "",
-	"*cmd/internal/obj.Prog %s":                       "",
 	"*math/big.Int %#x":                               "",
 	"*math/big.Int %s":                                "",
 	"[16]byte %x":                                     "",
 	"[]*cmd/compile/internal/gc.Node %v":              "",
 	"[]*cmd/compile/internal/gc.Sig %#v":              "",
 	"[]*cmd/compile/internal/ssa.Value %v":            "",
+	"[][]cmd/compile/internal/ssa.SlotID %v":          "",
 	"[]byte %s":                                       "",
 	"[]byte %x":                                       "",
 	"[]cmd/compile/internal/ssa.Edge %v":              "",
 	"[]cmd/compile/internal/ssa.ID %v":                "",
+	"[]cmd/compile/internal/ssa.VarLocList %v":        "",
+	"[]cmd/compile/internal/syntax.token %s":          "",
 	"[]string %v":                                     "",
 	"bool %v":                                         "",
 	"byte %08b":                                       "",
 	"byte %c":                                         "",
 	"cmd/compile/internal/arm.shift %d":               "",
 	"cmd/compile/internal/gc.Class %d":                "",
+	"cmd/compile/internal/gc.Class %s":                "",
+	"cmd/compile/internal/gc.Class %v":                "",
 	"cmd/compile/internal/gc.Ctype %d":                "",
 	"cmd/compile/internal/gc.Ctype %v":                "",
 	"cmd/compile/internal/gc.Level %d":                "",
@@ -620,21 +630,25 @@
 	"cmd/compile/internal/gc.Nodes %.v":               "",
 	"cmd/compile/internal/gc.Nodes %v":                "",
 	"cmd/compile/internal/gc.Op %#v":                  "",
+	"cmd/compile/internal/gc.Op %d":                   "",
 	"cmd/compile/internal/gc.Op %v":                   "",
 	"cmd/compile/internal/gc.Val %#v":                 "",
 	"cmd/compile/internal/gc.Val %T":                  "",
 	"cmd/compile/internal/gc.Val %v":                  "",
 	"cmd/compile/internal/gc.fmtMode %d":              "",
 	"cmd/compile/internal/gc.initKind %d":             "",
+	"cmd/compile/internal/gc.locID %v":                "",
 	"cmd/compile/internal/ssa.BranchPrediction %d":    "",
 	"cmd/compile/internal/ssa.Edge %v":                "",
 	"cmd/compile/internal/ssa.GCNode %v":              "",
 	"cmd/compile/internal/ssa.ID %d":                  "",
-	"cmd/compile/internal/ssa.LocalSlot %v":           "",
-	"cmd/compile/internal/ssa.Location %v":            "",
+	"cmd/compile/internal/ssa.ID %v":                  "",
+	"cmd/compile/internal/ssa.LocalSlot %s":           "",
+	"cmd/compile/internal/ssa.Location %s":            "",
 	"cmd/compile/internal/ssa.Op %s":                  "",
 	"cmd/compile/internal/ssa.Op %v":                  "",
 	"cmd/compile/internal/ssa.ValAndOff %s":           "",
+	"cmd/compile/internal/ssa.VarLocList %v":          "",
 	"cmd/compile/internal/ssa.rbrank %d":              "",
 	"cmd/compile/internal/ssa.regMask %d":             "",
 	"cmd/compile/internal/ssa.register %d":            "",
@@ -648,6 +662,7 @@
 	"cmd/compile/internal/types.EType %d":             "",
 	"cmd/compile/internal/types.EType %s":             "",
 	"cmd/compile/internal/types.EType %v":             "",
+	"cmd/internal/dwarf.Location %#v":                 "",
 	"cmd/internal/src.Pos %s":                         "",
 	"cmd/internal/src.Pos %v":                         "",
 	"error %v":                                        "",
@@ -658,6 +673,7 @@
 	"int %-12d":                                       "",
 	"int %-6d":                                        "",
 	"int %-8o":                                        "",
+	"int %02d":                                        "",
 	"int %6d":                                         "",
 	"int %c":                                          "",
 	"int %d":                                          "",
@@ -670,6 +686,7 @@
 	"int32 %x":                                        "",
 	"int64 %+d":                                       "",
 	"int64 %-10d":                                     "",
+	"int64 %.5d":                                      "",
 	"int64 %X":                                        "",
 	"int64 %d":                                        "",
 	"int64 %v":                                        "",
@@ -687,6 +704,7 @@
 	"rune %c":          "",
 	"string %-*s":      "",
 	"string %-16s":     "",
+	"string %-6s":      "",
 	"string %.*s":      "",
 	"string %q":        "",
 	"string %s":        "",
diff --git a/src/cmd/compile/internal/amd64/ggen.go b/src/cmd/compile/internal/amd64/ggen.go
index e294bce..df0a69a 100644
--- a/src/cmd/compile/internal/amd64/ggen.go
+++ b/src/cmd/compile/internal/amd64/ggen.go
@@ -14,14 +14,14 @@
 // no floating point in note handlers on Plan 9
 var isPlan9 = objabi.GOOS == "plan9"
 
-// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
+// DUFFZERO consists of repeated blocks of 4 MOVUPSs + LEAQ,
 // See runtime/mkduff.go.
 const (
 	dzBlocks    = 16 // number of MOV/ADD blocks
 	dzBlockLen  = 4  // number of clears per block
 	dzBlockSize = 19 // size of instructions in a single block
 	dzMovSize   = 4  // size of single MOV instruction w/ offset
-	dzAddSize   = 4  // size of single ADD instruction
+	dzLeaqSize  = 4  // size of single LEAQ instruction
 	dzClearStep = 16 // number of bytes cleared by each MOV instruction
 
 	dzClearLen = dzClearStep * dzBlockLen // bytes cleared by one block
@@ -35,7 +35,7 @@
 	off -= b / dzClearLen * dzBlockSize
 	tailLen := b % dzClearLen
 	if tailLen >= dzClearStep {
-		off -= dzAddSize + dzMovSize*(tailLen/dzClearStep)
+		off -= dzLeaqSize + dzMovSize*(tailLen/dzClearStep)
 	}
 	return off
 }
diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go
index 2d7727b..ce322e5 100644
--- a/src/cmd/compile/internal/amd64/ssa.go
+++ b/src/cmd/compile/internal/amd64/ssa.go
@@ -117,7 +117,7 @@
 	return p
 }
 
-// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
+// DUFFZERO consists of repeated blocks of 4 MOVUPSs + LEAQ,
 // See runtime/mkduff.go.
 func duffStart(size int64) int64 {
 	x, _ := duff(size)
@@ -140,7 +140,7 @@
 	off := dzBlockSize * (dzBlocks - blocks)
 	var adj int64
 	if steps != 0 {
-		off -= dzAddSize
+		off -= dzLeaqSize
 		off -= dzMovSize * steps
 		adj -= dzClearStep * (dzBlockLen - steps)
 	}
@@ -494,6 +494,18 @@
 		p.To.Reg = v.Args[0].Reg()
 	case ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
 		x := v.Reg()
+
+		// If flags aren't live (indicated by v.Aux == nil),
+		// then we can rewrite MOV $0, AX into XOR AX, AX.
+		if v.AuxInt == 0 && v.Aux == nil {
+			p := s.Prog(x86.AXORL)
+			p.From.Type = obj.TYPE_REG
+			p.From.Reg = x
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = x
+			break
+		}
+
 		asm := v.Op.Asm()
 		// Use MOVL to move a small constant into a register
 		// when the constant is positive and fits into 32 bits.
@@ -506,11 +518,6 @@
 		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = x
-		// If flags are live at this instruction, suppress the
-		// MOV $0,AX -> XOR AX,AX optimization.
-		if v.Aux != nil {
-			p.Mark |= x86.PRESERVEFLAGS
-		}
 	case ssa.OpAMD64MOVSSconst, ssa.OpAMD64MOVSDconst:
 		x := v.Reg()
 		p := s.Prog(v.Op.Asm())
@@ -525,7 +532,7 @@
 		gc.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpAMD64MOVQloadidx8, ssa.OpAMD64MOVSDloadidx8:
+	case ssa.OpAMD64MOVQloadidx8, ssa.OpAMD64MOVSDloadidx8, ssa.OpAMD64MOVLloadidx8:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
@@ -573,7 +580,7 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 		gc.AddAux(&p.To, v)
-	case ssa.OpAMD64MOVQstoreidx8, ssa.OpAMD64MOVSDstoreidx8:
+	case ssa.OpAMD64MOVQstoreidx8, ssa.OpAMD64MOVSDstoreidx8, ssa.OpAMD64MOVLstoreidx8:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[2].Reg()
@@ -614,6 +621,29 @@
 		p.To.Scale = 1
 		p.To.Index = i
 		gc.AddAux(&p.To, v)
+	case ssa.OpAMD64ADDQconstmem, ssa.OpAMD64ADDLconstmem:
+		sc := v.AuxValAndOff()
+		off := sc.Off()
+		val := sc.Val()
+		if val == 1 {
+			var asm obj.As
+			if v.Op == ssa.OpAMD64ADDQconstmem {
+				asm = x86.AINCQ
+			} else {
+				asm = x86.AINCL
+			}
+			p := s.Prog(asm)
+			p.To.Type = obj.TYPE_MEM
+			p.To.Reg = v.Args[0].Reg()
+			gc.AddAux2(&p.To, v, off)
+		} else {
+			p := s.Prog(v.Op.Asm())
+			p.From.Type = obj.TYPE_CONST
+			p.From.Offset = val
+			p.To.Type = obj.TYPE_MEM
+			p.To.Reg = v.Args[0].Reg()
+			gc.AddAux2(&p.To, v, off)
+		}
 	case ssa.OpAMD64MOVQstoreconst, ssa.OpAMD64MOVLstoreconst, ssa.OpAMD64MOVWstoreconst, ssa.OpAMD64MOVBstoreconst:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
@@ -655,6 +685,18 @@
 		// Break false dependency on destination register.
 		opregreg(s, x86.AXORPS, r, r)
 		opregreg(s, v.Op.Asm(), r, v.Args[0].Reg())
+	case ssa.OpAMD64MOVQi2f, ssa.OpAMD64MOVQf2i:
+		p := s.Prog(x86.AMOVQ)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+	case ssa.OpAMD64MOVLi2f, ssa.OpAMD64MOVLf2i:
+		p := s.Prog(x86.AMOVL)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpAMD64ADDQmem, ssa.OpAMD64ADDLmem, ssa.OpAMD64SUBQmem, ssa.OpAMD64SUBLmem,
 		ssa.OpAMD64ANDQmem, ssa.OpAMD64ANDLmem, ssa.OpAMD64ORQmem, ssa.OpAMD64ORLmem,
 		ssa.OpAMD64XORQmem, ssa.OpAMD64XORLmem, ssa.OpAMD64ADDSDmem, ssa.OpAMD64ADDSSmem,
@@ -673,9 +715,10 @@
 		adj := duffAdj(v.AuxInt)
 		var p *obj.Prog
 		if adj != 0 {
-			p = s.Prog(x86.AADDQ)
-			p.From.Type = obj.TYPE_CONST
+			p = s.Prog(x86.ALEAQ)
+			p.From.Type = obj.TYPE_MEM
 			p.From.Offset = adj
+			p.From.Reg = x86.REG_DI
 			p.To.Type = obj.TYPE_REG
 			p.To.Reg = x86.REG_DI
 		}
@@ -695,7 +738,11 @@
 		p.To.Sym = gc.Duffcopy
 		p.To.Offset = v.AuxInt
 
-	case ssa.OpCopy, ssa.OpAMD64MOVQconvert, ssa.OpAMD64MOVLconvert: // TODO: use MOVQreg for reg->reg copies instead of OpCopy?
+	case ssa.OpAMD64MOVQconvert, ssa.OpAMD64MOVLconvert:
+		if v.Args[0].Reg() != v.Reg() {
+			v.Fatalf("MOVXconvert should be a no-op")
+		}
+	case ssa.OpCopy: // TODO: use MOVQreg for reg->reg copies instead of OpCopy?
 		if v.Type.IsMemory() {
 			return
 		}
@@ -755,6 +802,34 @@
 		}
 	case ssa.OpAMD64CALLstatic, ssa.OpAMD64CALLclosure, ssa.OpAMD64CALLinter:
 		s.Call(v)
+
+	case ssa.OpAMD64LoweredGetCallerPC:
+		p := s.Prog(x86.AMOVQ)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Offset = -8 // PC is stored 8 bytes below first parameter.
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+
+	case ssa.OpAMD64LoweredGetCallerSP:
+		// caller's SP is the address of the first arg
+		mov := x86.AMOVQ
+		if gc.Widthptr == 4 {
+			mov = x86.AMOVL
+		}
+		p := s.Prog(mov)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on amd64, just to be consistent with other architectures
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+
+	case ssa.OpAMD64LoweredWB:
+		p := s.Prog(obj.ACALL)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = v.Aux.(*obj.LSym)
+
 	case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
 		ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
 		ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
@@ -777,6 +852,18 @@
 		p.From.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
+	case ssa.OpAMD64ROUNDSD:
+		p := s.Prog(v.Op.Asm())
+		val := v.AuxInt
+		// 0 means math.RoundToEven, 1 Floor, 2 Ceil, 3 Trunc
+		if val != 0 && val != 1 && val != 2 && val != 3 {
+			v.Fatalf("Invalid rounding mode")
+		}
+		p.From.Offset = val
+		p.From.Type = obj.TYPE_CONST
+		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpAMD64POPCNTQ, ssa.OpAMD64POPCNTL:
 		if v.Args[0].Reg() != v.Reg() {
 			// POPCNT on Intel has a false dependency on the destination register.
@@ -792,6 +879,7 @@
 		p.From.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
+
 	case ssa.OpAMD64SETEQ, ssa.OpAMD64SETNE,
 		ssa.OpAMD64SETL, ssa.OpAMD64SETLE,
 		ssa.OpAMD64SETG, ssa.OpAMD64SETGE,
@@ -803,6 +891,16 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
+	case ssa.OpAMD64SETEQmem, ssa.OpAMD64SETNEmem,
+		ssa.OpAMD64SETLmem, ssa.OpAMD64SETLEmem,
+		ssa.OpAMD64SETGmem, ssa.OpAMD64SETGEmem,
+		ssa.OpAMD64SETBmem, ssa.OpAMD64SETBEmem,
+		ssa.OpAMD64SETAmem, ssa.OpAMD64SETAEmem:
+		p := s.Prog(v.Op.Asm())
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		gc.AddAux(&p.To, v)
+
 	case ssa.OpAMD64SETNEF:
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
@@ -838,7 +936,7 @@
 	case ssa.OpAMD64LoweredNilCheck:
 		// Issue a load which will fault if the input is nil.
 		// TODO: We currently use the 2-byte instruction TESTB AX, (reg).
-		// Should we use the 3-byte TESTB $0, (reg) instead?  It is larger
+		// Should we use the 3-byte TESTB $0, (reg) instead? It is larger
 		// but it doesn't have false dependency on AX.
 		// Or maybe allocate an output register and use MOVL (reg),reg2 ?
 		// That trades clobbering flags for clobbering a register.
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 93abee3..300672d 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -13,6 +13,7 @@
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm"
+	"cmd/internal/objabi"
 )
 
 // loadByType returns the load instruction of the given type.
@@ -184,6 +185,8 @@
 		ssa.OpARMSUBD,
 		ssa.OpARMMULF,
 		ssa.OpARMMULD,
+		ssa.OpARMNMULF,
+		ssa.OpARMNMULD,
 		ssa.OpARMDIVF,
 		ssa.OpARMDIVD:
 		r := v.Reg()
@@ -195,6 +198,20 @@
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
+	case ssa.OpARMMULAF, ssa.OpARMMULAD, ssa.OpARMMULSF, ssa.OpARMMULSD:
+		r := v.Reg()
+		r0 := v.Args[0].Reg()
+		r1 := v.Args[1].Reg()
+		r2 := v.Args[2].Reg()
+		if r != r0 {
+			v.Fatalf("result and addend are not in the same register: %v", v.LongString())
+		}
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = r2
+		p.Reg = r1
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = r
 	case ssa.OpARMADDS,
 		ssa.OpARMSUBS:
 		r := v.Reg0()
@@ -242,6 +259,14 @@
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
+	case ssa.OpARMBFX, ssa.OpARMBFXU:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = v.AuxInt >> 8
+		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt & 0xff})
+		p.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpARMADDconst,
 		ssa.OpARMADCconst,
 		ssa.OpARMSUBconst,
@@ -402,7 +427,7 @@
 		p.To.Type = obj.TYPE_REGREG
 		p.To.Reg = v.Reg0()           // high 32-bit
 		p.To.Offset = int64(v.Reg1()) // low 32-bit
-	case ssa.OpARMMULA:
+	case ssa.OpARMMULA, ssa.OpARMMULS:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
@@ -449,17 +474,17 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-	case ssa.OpARMCMPshiftLL:
+	case ssa.OpARMCMPshiftLL, ssa.OpARMCMNshiftLL, ssa.OpARMTSTshiftLL, ssa.OpARMTEQshiftLL:
 		genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_LL, v.AuxInt)
-	case ssa.OpARMCMPshiftRL:
+	case ssa.OpARMCMPshiftRL, ssa.OpARMCMNshiftRL, ssa.OpARMTSTshiftRL, ssa.OpARMTEQshiftRL:
 		genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_LR, v.AuxInt)
-	case ssa.OpARMCMPshiftRA:
+	case ssa.OpARMCMPshiftRA, ssa.OpARMCMNshiftRA, ssa.OpARMTSTshiftRA, ssa.OpARMTEQshiftRA:
 		genshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), 0, arm.SHIFT_AR, v.AuxInt)
-	case ssa.OpARMCMPshiftLLreg:
+	case ssa.OpARMCMPshiftLLreg, ssa.OpARMCMNshiftLLreg, ssa.OpARMTSTshiftLLreg, ssa.OpARMTEQshiftLLreg:
 		genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_LL)
-	case ssa.OpARMCMPshiftRLreg:
+	case ssa.OpARMCMPshiftRLreg, ssa.OpARMCMNshiftRLreg, ssa.OpARMTSTshiftRLreg, ssa.OpARMTEQshiftRLreg:
 		genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_LR)
-	case ssa.OpARMCMPshiftRAreg:
+	case ssa.OpARMCMPshiftRAreg, ssa.OpARMCMNshiftRAreg, ssa.OpARMTSTshiftRAreg, ssa.OpARMTEQshiftRAreg:
 		genregshift(s, v.Op.Asm(), v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg(), 0, arm.SHIFT_AR)
 	case ssa.OpARMMOVWaddr:
 		p := s.Prog(arm.AMOVW)
@@ -477,10 +502,10 @@
 		switch v.Aux.(type) {
 		default:
 			v.Fatalf("aux is of unknown type %T", v.Aux)
-		case *ssa.ExternSymbol:
+		case *obj.LSym:
 			wantreg = "SB"
 			gc.AddAux(&p.From, v)
-		case *ssa.ArgSymbol, *ssa.AutoSymbol:
+		case *gc.Node:
 			wantreg = "SP"
 			gc.AddAux(&p.From, v)
 		case nil:
@@ -516,7 +541,7 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 		gc.AddAux(&p.To, v)
-	case ssa.OpARMMOVWloadidx:
+	case ssa.OpARMMOVWloadidx, ssa.OpARMMOVBUloadidx, ssa.OpARMMOVBloadidx, ssa.OpARMMOVHUloadidx, ssa.OpARMMOVHloadidx:
 		// this is just shift 0 bits
 		fallthrough
 	case ssa.OpARMMOVWloadshiftLL:
@@ -528,7 +553,7 @@
 	case ssa.OpARMMOVWloadshiftRA:
 		p := genshift(s, v.Op.Asm(), 0, v.Args[1].Reg(), v.Reg(), arm.SHIFT_AR, v.AuxInt)
 		p.From.Reg = v.Args[0].Reg()
-	case ssa.OpARMMOVWstoreidx:
+	case ssa.OpARMMOVWstoreidx, ssa.OpARMMOVBstoreidx, ssa.OpARMMOVHstoreidx:
 		// this is just shift 0 bits
 		fallthrough
 	case ssa.OpARMMOVWstoreshiftLL:
@@ -580,6 +605,11 @@
 			default:
 			}
 		}
+		if objabi.GOARM >= 6 {
+			// generate more efficient "MOVB/MOVBU/MOVH/MOVHU Reg@>0, Reg" on ARMv6 & ARMv7
+			genshift(s, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm.SHIFT_RR, 0)
+			return
+		}
 		fallthrough
 	case ssa.OpARMMVN,
 		ssa.OpARMCLZ,
@@ -754,6 +784,14 @@
 	case ssa.OpARMLoweredGetClosurePtr:
 		// Closure pointer is R7 (arm.REGCTXT).
 		gc.CheckLoweredGetClosurePtr(v)
+	case ssa.OpARMLoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(arm.AMOVW)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpARMFlagEQ,
 		ssa.OpARMFlagLT_ULT,
 		ssa.OpARMFlagLT_UGT,
diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go
index 52a8e3f..f7b3851 100644
--- a/src/cmd/compile/internal/arm64/ggen.go
+++ b/src/cmd/compile/internal/arm64/ggen.go
@@ -31,13 +31,18 @@
 			p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
 		}
 	} else if cnt <= int64(128*gc.Widthptr) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
+		if cnt%(2*int64(gc.Widthptr)) != 0 {
+			p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
+			off += int64(gc.Widthptr)
+			cnt -= int64(gc.Widthptr)
+		}
 		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
-		p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGRT1, 0)
+		p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REGRT1, 0)
 		p.Reg = arm64.REGRT1
 		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
 		p.To.Name = obj.NAME_EXTERN
 		p.To.Sym = gc.Duffzero
-		p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
+		p.To.Offset = 4 * (64 - cnt/(2*int64(gc.Widthptr)))
 	} else {
 		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGTMP, 0)
 		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index 0f9e82c..6fa0191 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -273,10 +273,10 @@
 		switch v.Aux.(type) {
 		default:
 			v.Fatalf("aux is of unknown type %T", v.Aux)
-		case *ssa.ExternSymbol:
+		case *obj.LSym:
 			wantreg = "SB"
 			gc.AddAux(&p.From, v)
-		case *ssa.ArgSymbol, *ssa.AutoSymbol:
+		case *gc.Node:
 			wantreg = "SP"
 			gc.AddAux(&p.From, v)
 		case nil:
@@ -324,6 +324,14 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 		gc.AddAux(&p.To, v)
+	case ssa.OpARM64STP:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REGREG
+		p.From.Reg = v.Args[1].Reg()
+		p.From.Offset = int64(v.Args[2].Reg())
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		gc.AddAux(&p.To, v)
 	case ssa.OpARM64MOVBstorezero,
 		ssa.OpARM64MOVHstorezero,
 		ssa.OpARM64MOVWstorezero,
@@ -334,6 +342,14 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 		gc.AddAux(&p.To, v)
+	case ssa.OpARM64MOVQstorezero:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REGREG
+		p.From.Reg = arm64.REGZERO
+		p.From.Offset = int64(arm64.REGZERO)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		gc.AddAux(&p.To, v)
 	case ssa.OpARM64LoweredAtomicExchange64,
 		ssa.OpARM64LoweredAtomicExchange32:
 		// LDAXR	(Rarg0), Rout
@@ -555,34 +571,29 @@
 		p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
 		p.From.Reg = arm64.COND_LO
 		p.Reg = v.Args[0].Reg()
-		p.From3 = &obj.Addr{Type: obj.TYPE_REG, Reg: r1}
+		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r1})
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpARM64DUFFZERO:
-		// runtime.duffzero expects start address - 8 in R16
-		p := s.Prog(arm64.ASUB)
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = 8
-		p.Reg = v.Args[0].Reg()
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = arm64.REG_R16
-		p = s.Prog(obj.ADUFFZERO)
+		// runtime.duffzero expects start address in R16
+		p := s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
 		p.To.Sym = gc.Duffzero
 		p.To.Offset = v.AuxInt
 	case ssa.OpARM64LoweredZero:
-		// MOVD.P	ZR, 8(R16)
+		// STP.P	(ZR,ZR), 16(R16)
 		// CMP	Rarg1, R16
 		// BLE	-2(PC)
-		// arg1 is the address of the last element to zero
-		p := s.Prog(arm64.AMOVD)
+		// arg1 is the address of the last 16-byte unit to zero
+		p := s.Prog(arm64.ASTP)
 		p.Scond = arm64.C_XPOST
-		p.From.Type = obj.TYPE_REG
+		p.From.Type = obj.TYPE_REGREG
 		p.From.Reg = arm64.REGZERO
+		p.From.Offset = int64(arm64.REGZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = arm64.REG_R16
-		p.To.Offset = 8
+		p.To.Offset = 16
 		p2 := s.Prog(arm64.ACMP)
 		p2.From.Type = obj.TYPE_REG
 		p2.From.Reg = v.Args[1].Reg()
@@ -655,6 +666,14 @@
 	case ssa.OpARM64LoweredGetClosurePtr:
 		// Closure pointer is R26 (arm64.REGCTXT).
 		gc.CheckLoweredGetClosurePtr(v)
+	case ssa.OpARM64LoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(arm64.AMOVD)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpARM64FlagEQ,
 		ssa.OpARM64FlagLT_ULT,
 		ssa.OpARM64FlagLT_UGT,
@@ -686,20 +705,22 @@
 var blockJump = map[ssa.BlockKind]struct {
 	asm, invasm obj.As
 }{
-	ssa.BlockARM64EQ:  {arm64.ABEQ, arm64.ABNE},
-	ssa.BlockARM64NE:  {arm64.ABNE, arm64.ABEQ},
-	ssa.BlockARM64LT:  {arm64.ABLT, arm64.ABGE},
-	ssa.BlockARM64GE:  {arm64.ABGE, arm64.ABLT},
-	ssa.BlockARM64LE:  {arm64.ABLE, arm64.ABGT},
-	ssa.BlockARM64GT:  {arm64.ABGT, arm64.ABLE},
-	ssa.BlockARM64ULT: {arm64.ABLO, arm64.ABHS},
-	ssa.BlockARM64UGE: {arm64.ABHS, arm64.ABLO},
-	ssa.BlockARM64UGT: {arm64.ABHI, arm64.ABLS},
-	ssa.BlockARM64ULE: {arm64.ABLS, arm64.ABHI},
-	ssa.BlockARM64Z:   {arm64.ACBZ, arm64.ACBNZ},
-	ssa.BlockARM64NZ:  {arm64.ACBNZ, arm64.ACBZ},
-	ssa.BlockARM64ZW:  {arm64.ACBZW, arm64.ACBNZW},
-	ssa.BlockARM64NZW: {arm64.ACBNZW, arm64.ACBZW},
+	ssa.BlockARM64EQ:   {arm64.ABEQ, arm64.ABNE},
+	ssa.BlockARM64NE:   {arm64.ABNE, arm64.ABEQ},
+	ssa.BlockARM64LT:   {arm64.ABLT, arm64.ABGE},
+	ssa.BlockARM64GE:   {arm64.ABGE, arm64.ABLT},
+	ssa.BlockARM64LE:   {arm64.ABLE, arm64.ABGT},
+	ssa.BlockARM64GT:   {arm64.ABGT, arm64.ABLE},
+	ssa.BlockARM64ULT:  {arm64.ABLO, arm64.ABHS},
+	ssa.BlockARM64UGE:  {arm64.ABHS, arm64.ABLO},
+	ssa.BlockARM64UGT:  {arm64.ABHI, arm64.ABLS},
+	ssa.BlockARM64ULE:  {arm64.ABLS, arm64.ABHI},
+	ssa.BlockARM64Z:    {arm64.ACBZ, arm64.ACBNZ},
+	ssa.BlockARM64NZ:   {arm64.ACBNZ, arm64.ACBZ},
+	ssa.BlockARM64ZW:   {arm64.ACBZW, arm64.ACBNZW},
+	ssa.BlockARM64NZW:  {arm64.ACBNZW, arm64.ACBZW},
+	ssa.BlockARM64TBZ:  {arm64.ATBZ, arm64.ATBNZ},
+	ssa.BlockARM64TBNZ: {arm64.ATBNZ, arm64.ATBZ},
 }
 
 func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
@@ -770,6 +791,35 @@
 			p.From.Type = obj.TYPE_REG
 			p.From.Reg = b.Control.Reg()
 		}
+	case ssa.BlockARM64TBZ, ssa.BlockARM64TBNZ:
+		jmp := blockJump[b.Kind]
+		var p *obj.Prog
+		switch next {
+		case b.Succs[0].Block():
+			p = s.Prog(jmp.invasm)
+			p.To.Type = obj.TYPE_BRANCH
+			p.From.Offset = b.Aux.(int64)
+			p.From.Type = obj.TYPE_CONST
+			p.Reg = b.Control.Reg()
+			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		case b.Succs[1].Block():
+			p = s.Prog(jmp.asm)
+			p.To.Type = obj.TYPE_BRANCH
+			p.From.Offset = b.Aux.(int64)
+			p.From.Type = obj.TYPE_CONST
+			p.Reg = b.Control.Reg()
+			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+		default:
+			p = s.Prog(jmp.asm)
+			p.To.Type = obj.TYPE_BRANCH
+			p.From.Offset = b.Aux.(int64)
+			p.From.Type = obj.TYPE_CONST
+			p.Reg = b.Control.Reg()
+			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			q := s.Prog(obj.AJMP)
+			q.To.Type = obj.TYPE_BRANCH
+			s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+		}
 
 	default:
 		b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index 0b4c9c7..e98df71 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -292,7 +292,7 @@
 		dumplist("genhash body", fn.Nbody)
 	}
 
-	funcbody(fn)
+	funcbody()
 	Curfn = fn
 	fn.Func.SetDupok(true)
 	fn = typecheck(fn, Etop)
@@ -476,7 +476,7 @@
 		dumplist("geneq body", fn.Nbody)
 	}
 
-	funcbody(fn)
+	funcbody()
 	Curfn = fn
 	fn.Func.SetDupok(true)
 	fn = typecheck(fn, Etop)
diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go
index f29c587..dc2d04a 100644
--- a/src/cmd/compile/internal/gc/align.go
+++ b/src/cmd/compile/internal/gc/align.go
@@ -176,6 +176,7 @@
 		}
 
 		t.Width = 0
+		t.Align = 1
 		return
 	}
 
@@ -290,6 +291,7 @@
 
 	case TFORW: // should have been filled in
 		if !t.Broke() {
+			t.SetBroke(true)
 			yyerror("invalid recursive type %v", t)
 		}
 		w = 1 // anything will do
diff --git a/src/cmd/compile/internal/gc/asm_test.go b/src/cmd/compile/internal/gc/asm_test.go
index 08ec638..50857e6 100644
--- a/src/cmd/compile/internal/gc/asm_test.go
+++ b/src/cmd/compile/internal/gc/asm_test.go
@@ -18,6 +18,52 @@
 	"testing"
 )
 
+// This file contains code generation tests.
+//
+// Each test is defined in a variable of type asmTest. Tests are
+// architecture-specific, and they are grouped in arrays of tests, one
+// for each architecture.
+//
+// Each asmTest consists of a function to compile, an array of
+// positive regexps that must match the generated assembly and
+// an array of negative regexps that must not match generated assembly.
+// For example, the following amd64 test
+//
+//   {
+// 	  fn: `
+// 	  func f0(x int) int {
+// 		  return x * 64
+// 	  }
+// 	  `,
+// 	  pos: []string{"\tSHLQ\t[$]6,"},
+//	  neg: []string{"MULQ"}
+//   }
+//
+// verifies that the code the compiler generates for a multiplication
+// by 64 contains a 'SHLQ' instruction and does not contain a MULQ.
+//
+// Since all the tests for a given architecture are dumped in the same
+// file, the function names must be unique. As a workaround for this
+// restriction, the test harness supports the use of a '$' placeholder
+// for function names. The func f0 above can be also written as
+//
+//   {
+// 	  fn: `
+// 	  func $(x int) int {
+// 		  return x * 64
+// 	  }
+// 	  `,
+// 	  pos: []string{"\tSHLQ\t[$]6,"},
+//	  neg: []string{"MULQ"}
+//   }
+//
+// Each '$'-function will be given a unique name of form f<N>_<arch>,
+// where <N> is the test index in the test array, and <arch> is the
+// test's architecture.
+//
+// It is allowed to mix named and unnamed functions in the same test
+// array; the named functions will retain their original names.
+
 // TestAssembly checks to make sure the assembly generated for
 // functions contains certain expected instructions.
 func TestAssembly(t *testing.T) {
@@ -41,8 +87,13 @@
 
 				asm := ats.compileToAsm(tt, dir)
 
-				for _, at := range ats.tests {
-					funcName := nameRegexp.FindString(at.function)[len("func "):]
+				for i, at := range ats.tests {
+					var funcName string
+					if strings.Contains(at.fn, "func $") {
+						funcName = fmt.Sprintf("f%d_%s", i, ats.arch)
+					} else {
+						funcName = nameRegexp.FindString(at.fn)[len("func "):]
+					}
 					fa := funcAsm(tt, asm, funcName)
 					if fa != "" {
 						at.verifyAsm(tt, fa)
@@ -74,17 +125,23 @@
 }
 
 type asmTest struct {
-	// function to compile, must be named fX,
-	// where X is this test's index in asmTests.tests.
-	function string
-	// regexps that must match the generated assembly
-	regexps []string
+	// function to compile
+	fn string
+	// regular expressions that must match the generated assembly
+	pos []string
+	// regular expressions that must not match the generated assembly
+	neg []string
 }
 
 func (at asmTest) verifyAsm(t *testing.T, fa string) {
-	for _, r := range at.regexps {
+	for _, r := range at.pos {
 		if b, err := regexp.MatchString(r, fa); !b || err != nil {
-			t.Errorf("expected:%s\ngo:%s\nasm:%s\n", r, at.function, fa)
+			t.Errorf("expected:%s\ngo:%s\nasm:%s\n", r, at.fn, fa)
+		}
+	}
+	for _, r := range at.neg {
+		if b, err := regexp.MatchString(r, fa); b || err != nil {
+			t.Errorf("not expected:%s\ngo:%s\nasm:%s\n", r, at.fn, fa)
 		}
 	}
 }
@@ -103,8 +160,9 @@
 		fmt.Fprintf(&buf, "import %q\n", s)
 	}
 
-	for _, t := range ats.tests {
-		fmt.Fprintln(&buf, t.function)
+	for i, t := range ats.tests {
+		function := strings.Replace(t.fn, "func $", fmt.Sprintf("func f%d_%s", i, ats.arch), 1)
+		fmt.Fprintln(&buf, function)
 	}
 
 	return buf.Bytes()
@@ -166,7 +224,7 @@
 	{
 		arch:    "amd64",
 		os:      "linux",
-		imports: []string{"encoding/binary", "math/bits", "unsafe"},
+		imports: []string{"encoding/binary", "math", "math/bits", "unsafe", "runtime"},
 		tests:   linuxAMD64Tests,
 	},
 	{
@@ -178,13 +236,13 @@
 	{
 		arch:    "s390x",
 		os:      "linux",
-		imports: []string{"encoding/binary", "math/bits"},
+		imports: []string{"encoding/binary", "math", "math/bits"},
 		tests:   linuxS390XTests,
 	},
 	{
 		arch:    "arm",
 		os:      "linux",
-		imports: []string{"math/bits"},
+		imports: []string{"math/bits", "runtime"},
 		tests:   linuxARMTests,
 	},
 	{
@@ -200,173 +258,196 @@
 		tests:   linuxMIPSTests,
 	},
 	{
-		arch:  "ppc64le",
+		arch:  "mips64",
 		os:    "linux",
-		tests: linuxPPC64LETests,
+		tests: linuxMIPS64Tests,
+	},
+	{
+		arch:    "ppc64le",
+		os:      "linux",
+		imports: []string{"encoding/binary", "math", "math/bits"},
+		tests:   linuxPPC64LETests,
+	},
+	{
+		arch:  "amd64",
+		os:    "plan9",
+		tests: plan9AMD64Tests,
 	},
 }
 
 var linuxAMD64Tests = []*asmTest{
+	// multiplication by powers of two
 	{
-		`
-		func f0(x int) int {
-			return x * 64
+		fn: `
+		func $(n int) int {
+			return n * 64
 		}
 		`,
-		[]string{"\tSHLQ\t\\$6,"},
+		pos: []string{"\tSHLQ\t\\$6,"},
+		neg: []string{"IMULQ"},
 	},
 	{
-		`
-		func f1(x int) int {
+		fn: `
+		func $(n int) int {
+			return -128*n
+		}
+		`,
+		pos: []string{"SHLQ"},
+		neg: []string{"IMULQ"},
+	},
+
+	{
+		fn: `
+		func $(x int) int {
 			return x * 96
 		}
 		`,
-		[]string{"\tSHLQ\t\\$5,", "\tLEAQ\t\\(.*\\)\\(.*\\*2\\),"},
+		pos: []string{"\tSHLQ\t\\$5,", "\tLEAQ\t\\(.*\\)\\(.*\\*2\\),"},
 	},
 	// Load-combining tests.
 	{
-		`
+		fn: `
 		func f2(b []byte) uint64 {
 			return binary.LittleEndian.Uint64(b)
 		}
 		`,
-		[]string{"\tMOVQ\t\\(.*\\),"},
+		pos: []string{"\tMOVQ\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f3(b []byte, i int) uint64 {
 			return binary.LittleEndian.Uint64(b[i:])
 		}
 		`,
-		[]string{"\tMOVQ\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVQ\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f4(b []byte) uint32 {
 			return binary.LittleEndian.Uint32(b)
 		}
 		`,
-		[]string{"\tMOVL\t\\(.*\\),"},
+		pos: []string{"\tMOVL\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f5(b []byte, i int) uint32 {
 			return binary.LittleEndian.Uint32(b[i:])
 		}
 		`,
-		[]string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f6(b []byte) uint64 {
 			return binary.BigEndian.Uint64(b)
 		}
 		`,
-		[]string{"\tBSWAPQ\t"},
+		pos: []string{"\tBSWAPQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f7(b []byte, i int) uint64 {
 			return binary.BigEndian.Uint64(b[i:])
 		}
 		`,
-		[]string{"\tBSWAPQ\t"},
+		pos: []string{"\tBSWAPQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f8(b []byte, v uint64) {
 			binary.BigEndian.PutUint64(b, v)
 		}
 		`,
-		[]string{"\tBSWAPQ\t"},
+		pos: []string{"\tBSWAPQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f9(b []byte, i int, v uint64) {
 			binary.BigEndian.PutUint64(b[i:], v)
 		}
 		`,
-		[]string{"\tBSWAPQ\t"},
+		pos: []string{"\tBSWAPQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f10(b []byte) uint32 {
 			return binary.BigEndian.Uint32(b)
 		}
 		`,
-		[]string{"\tBSWAPL\t"},
+		pos: []string{"\tBSWAPL\t"},
 	},
 	{
-		`
+		fn: `
 		func f11(b []byte, i int) uint32 {
 			return binary.BigEndian.Uint32(b[i:])
 		}
 		`,
-		[]string{"\tBSWAPL\t"},
+		pos: []string{"\tBSWAPL\t"},
 	},
 	{
-		`
+		fn: `
 		func f12(b []byte, v uint32) {
 			binary.BigEndian.PutUint32(b, v)
 		}
 		`,
-		[]string{"\tBSWAPL\t"},
+		pos: []string{"\tBSWAPL\t"},
 	},
 	{
-		`
+		fn: `
 		func f13(b []byte, i int, v uint32) {
 			binary.BigEndian.PutUint32(b[i:], v)
 		}
 		`,
-		[]string{"\tBSWAPL\t"},
+		pos: []string{"\tBSWAPL\t"},
 	},
 	{
-		`
+		fn: `
 		func f14(b []byte) uint16 {
 			return binary.BigEndian.Uint16(b)
 		}
 		`,
-		[]string{"\tROLW\t\\$8,"},
+		pos: []string{"\tROLW\t\\$8,"},
 	},
 	{
-		`
+		fn: `
 		func f15(b []byte, i int) uint16 {
 			return binary.BigEndian.Uint16(b[i:])
 		}
 		`,
-		[]string{"\tROLW\t\\$8,"},
+		pos: []string{"\tROLW\t\\$8,"},
 	},
 	{
-		`
+		fn: `
 		func f16(b []byte, v uint16) {
 			binary.BigEndian.PutUint16(b, v)
 		}
 		`,
-		[]string{"\tROLW\t\\$8,"},
+		pos: []string{"\tROLW\t\\$8,"},
 	},
 	{
-		`
+		fn: `
 		func f17(b []byte, i int, v uint16) {
 			binary.BigEndian.PutUint16(b[i:], v)
 		}
 		`,
-		[]string{"\tROLW\t\\$8,"},
+		pos: []string{"\tROLW\t\\$8,"},
 	},
 	// Structure zeroing.  See issue #18370.
 	{
-		`
+		fn: `
 		type T1 struct {
 			a, b, c int
 		}
-		func f18(t *T1) {
+		func $(t *T1) {
 			*t = T1{}
 		}
 		`,
-		[]string{"\tMOVQ\t\\$0, \\(.*\\)", "\tMOVQ\t\\$0, 8\\(.*\\)", "\tMOVQ\t\\$0, 16\\(.*\\)"},
+		pos: []string{"\tXORPS\tX., X", "\tMOVUPS\tX., \\(.*\\)", "\tMOVQ\t\\$0, 16\\(.*\\)"},
 	},
 	// SSA-able composite literal initialization. Issue 18872.
 	{
-		`
+		fn: `
 		type T18872 struct {
 			a, b, c, d int
 		}
@@ -375,11 +456,11 @@
 			*p = T18872{1, 2, 3, 4}
 		}
 		`,
-		[]string{"\tMOVQ\t[$]1", "\tMOVQ\t[$]2", "\tMOVQ\t[$]3", "\tMOVQ\t[$]4"},
+		pos: []string{"\tMOVQ\t[$]1", "\tMOVQ\t[$]2", "\tMOVQ\t[$]3", "\tMOVQ\t[$]4"},
 	},
 	// Also test struct containing pointers (this was special because of write barriers).
 	{
-		`
+		fn: `
 		type T2 struct {
 			a, b, c *int
 		}
@@ -387,108 +468,108 @@
 			*t = T2{}
 		}
 		`,
-		[]string{"\tMOVQ\t\\$0, \\(.*\\)", "\tMOVQ\t\\$0, 8\\(.*\\)", "\tMOVQ\t\\$0, 16\\(.*\\)", "\tCALL\truntime\\.writebarrierptr\\(SB\\)"},
+		pos: []string{"\tXORPS\tX., X", "\tMOVUPS\tX., \\(.*\\)", "\tMOVQ\t\\$0, 16\\(.*\\)", "\tCALL\truntime\\.(writebarrierptr|gcWriteBarrier)\\(SB\\)"},
 	},
 	// Rotate tests
 	{
-		`
+		fn: `
 		func f20(x uint64) uint64 {
 			return x<<7 | x>>57
 		}
 		`,
-		[]string{"\tROLQ\t[$]7,"},
+		pos: []string{"\tROLQ\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f21(x uint64) uint64 {
 			return x<<7 + x>>57
 		}
 		`,
-		[]string{"\tROLQ\t[$]7,"},
+		pos: []string{"\tROLQ\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f22(x uint64) uint64 {
 			return x<<7 ^ x>>57
 		}
 		`,
-		[]string{"\tROLQ\t[$]7,"},
+		pos: []string{"\tROLQ\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f23(x uint32) uint32 {
 			return x<<7 + x>>25
 		}
 		`,
-		[]string{"\tROLL\t[$]7,"},
+		pos: []string{"\tROLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f24(x uint32) uint32 {
 			return x<<7 | x>>25
 		}
 		`,
-		[]string{"\tROLL\t[$]7,"},
+		pos: []string{"\tROLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f25(x uint32) uint32 {
 			return x<<7 ^ x>>25
 		}
 		`,
-		[]string{"\tROLL\t[$]7,"},
+		pos: []string{"\tROLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f26(x uint16) uint16 {
 			return x<<7 + x>>9
 		}
 		`,
-		[]string{"\tROLW\t[$]7,"},
+		pos: []string{"\tROLW\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f27(x uint16) uint16 {
 			return x<<7 | x>>9
 		}
 		`,
-		[]string{"\tROLW\t[$]7,"},
+		pos: []string{"\tROLW\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f28(x uint16) uint16 {
 			return x<<7 ^ x>>9
 		}
 		`,
-		[]string{"\tROLW\t[$]7,"},
+		pos: []string{"\tROLW\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f29(x uint8) uint8 {
 			return x<<7 + x>>1
 		}
 		`,
-		[]string{"\tROLB\t[$]7,"},
+		pos: []string{"\tROLB\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f30(x uint8) uint8 {
 			return x<<7 | x>>1
 		}
 		`,
-		[]string{"\tROLB\t[$]7,"},
+		pos: []string{"\tROLB\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f31(x uint8) uint8 {
 			return x<<7 ^ x>>1
 		}
 		`,
-		[]string{"\tROLB\t[$]7,"},
+		pos: []string{"\tROLB\t[$]7,"},
 	},
 	// Rotate after inlining (see issue 18254).
 	{
-		`
+		fn: `
 		func f32(x uint32) uint32 {
 			return g(x, 7)
 		}
@@ -496,46 +577,46 @@
 			return x<<k | x>>(32-k)
 		}
 		`,
-		[]string{"\tROLL\t[$]7,"},
+		pos: []string{"\tROLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f33(m map[int]int) int {
 			return m[5]
 		}
 		`,
-		[]string{"\tMOVQ\t[$]5,"},
+		pos: []string{"\tMOVQ\t[$]5,"},
 	},
 	// Direct use of constants in fast map access calls. Issue 19015.
 	{
-		`
+		fn: `
 		func f34(m map[int]int) bool {
 			_, ok := m[5]
 			return ok
 		}
 		`,
-		[]string{"\tMOVQ\t[$]5,"},
+		pos: []string{"\tMOVQ\t[$]5,"},
 	},
 	{
-		`
+		fn: `
 		func f35(m map[string]int) int {
 			return m["abc"]
 		}
 		`,
-		[]string{"\"abc\""},
+		pos: []string{"\"abc\""},
 	},
 	{
-		`
+		fn: `
 		func f36(m map[string]int) bool {
 			_, ok := m["abc"]
 			return ok
 		}
 		`,
-		[]string{"\"abc\""},
+		pos: []string{"\"abc\""},
 	},
 	// Bit test ops on amd64, issue 18943.
 	{
-		`
+		fn: `
 		func f37(a, b uint64) int {
 			if a&(1<<(b&63)) != 0 {
 				return 1
@@ -543,18 +624,18 @@
 			return -1
 		}
 		`,
-		[]string{"\tBTQ\t"},
+		pos: []string{"\tBTQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f38(a, b uint64) bool {
 			return a&(1<<(b&63)) != 0
 		}
 		`,
-		[]string{"\tBTQ\t"},
+		pos: []string{"\tBTQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f39(a uint64) int {
 			if a&(1<<60) != 0 {
 				return 1
@@ -562,1107 +643,2414 @@
 			return -1
 		}
 		`,
-		[]string{"\tBTQ\t\\$60"},
+		pos: []string{"\tBTQ\t\\$60"},
 	},
 	{
-		`
+		fn: `
 		func f40(a uint64) bool {
 			return a&(1<<60) != 0
 		}
 		`,
-		[]string{"\tBTQ\t\\$60"},
+		pos: []string{"\tBTQ\t\\$60"},
 	},
 	// Intrinsic tests for math/bits
 	{
-		`
+		fn: `
 		func f41(a uint64) int {
 			return bits.TrailingZeros64(a)
 		}
 		`,
-		[]string{"\tBSFQ\t", "\tMOVL\t\\$64,", "\tCMOVQEQ\t"},
+		pos: []string{"\tBSFQ\t", "\tMOVL\t\\$64,", "\tCMOVQEQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f42(a uint32) int {
 			return bits.TrailingZeros32(a)
 		}
 		`,
-		[]string{"\tBSFQ\t", "\tORQ\t[^$]", "\tMOVQ\t\\$4294967296,"},
+		pos: []string{"\tBSFQ\t", "\tORQ\t[^$]", "\tMOVQ\t\\$4294967296,"},
 	},
 	{
-		`
+		fn: `
 		func f43(a uint16) int {
 			return bits.TrailingZeros16(a)
 		}
 		`,
-		[]string{"\tBSFQ\t", "\tORQ\t\\$65536,"},
+		pos: []string{"\tBSFQ\t", "\tORQ\t\\$65536,"},
 	},
 	{
-		`
+		fn: `
 		func f44(a uint8) int {
 			return bits.TrailingZeros8(a)
 		}
 		`,
-		[]string{"\tBSFQ\t", "\tORQ\t\\$256,"},
+		pos: []string{"\tBSFQ\t", "\tORQ\t\\$256,"},
 	},
 	{
-		`
+		fn: `
 		func f45(a uint64) uint64 {
 			return bits.ReverseBytes64(a)
 		}
 		`,
-		[]string{"\tBSWAPQ\t"},
+		pos: []string{"\tBSWAPQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f46(a uint32) uint32 {
 			return bits.ReverseBytes32(a)
 		}
 		`,
-		[]string{"\tBSWAPL\t"},
+		pos: []string{"\tBSWAPL\t"},
 	},
 	{
-		`
+		fn: `
 		func f47(a uint16) uint16 {
 			return bits.ReverseBytes16(a)
 		}
 		`,
-		[]string{"\tROLW\t\\$8,"},
+		pos: []string{"\tROLW\t\\$8,"},
 	},
 	{
-		`
+		fn: `
 		func f48(a uint64) int {
 			return bits.Len64(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f49(a uint32) int {
 			return bits.Len32(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f50(a uint16) int {
 			return bits.Len16(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	/* see ssa.go
 	{
-		`
+		fn:`
 		func f51(a uint8) int {
 			return bits.Len8(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos:[]string{"\tBSRQ\t"},
 	},
 	*/
 	{
-		`
+		fn: `
 		func f52(a uint) int {
 			return bits.Len(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f53(a uint64) int {
 			return bits.LeadingZeros64(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f54(a uint32) int {
 			return bits.LeadingZeros32(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func f55(a uint16) int {
 			return bits.LeadingZeros16(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	/* see ssa.go
 	{
-		`
+		fn:`
 		func f56(a uint8) int {
 			return bits.LeadingZeros8(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos:[]string{"\tBSRQ\t"},
 	},
 	*/
 	{
-		`
+		fn: `
 		func f57(a uint) int {
 			return bits.LeadingZeros(a)
 		}
 		`,
-		[]string{"\tBSRQ\t"},
+		pos: []string{"\tBSRQ\t"},
 	},
 	{
-		`
+		fn: `
 		func pop1(x uint64) int {
 			return bits.OnesCount64(x)
 		}`,
-		[]string{"\tPOPCNTQ\t", "support_popcnt"},
+		pos: []string{"\tPOPCNTQ\t", "support_popcnt"},
 	},
 	{
-		`
+		fn: `
 		func pop2(x uint32) int {
 			return bits.OnesCount32(x)
 		}`,
-		[]string{"\tPOPCNTL\t", "support_popcnt"},
+		pos: []string{"\tPOPCNTL\t", "support_popcnt"},
 	},
 	{
-		`
+		fn: `
 		func pop3(x uint16) int {
 			return bits.OnesCount16(x)
 		}`,
-		[]string{"\tPOPCNTL\t", "support_popcnt"},
+		pos: []string{"\tPOPCNTL\t", "support_popcnt"},
 	},
 	{
-		`
+		fn: `
 		func pop4(x uint) int {
 			return bits.OnesCount(x)
 		}`,
-		[]string{"\tPOPCNTQ\t", "support_popcnt"},
+		pos: []string{"\tPOPCNTQ\t", "support_popcnt"},
 	},
+	// multiplication merging tests
+	{
+		fn: `
+		func mul1(n int) int {
+			return 15*n + 31*n
+		}`,
+		pos: []string{"\tIMULQ\t[$]46"}, // 46*n
+	},
+	{
+		fn: `
+		func mul2(n int) int {
+			return 5*n + 7*(n+1) + 11*(n+2)
+		}`,
+		pos: []string{"\tIMULQ\t[$]23", "\tADDQ\t[$]29"}, // 23*n + 29
+	},
+	{
+		fn: `
+		func mul3(a, n int) int {
+			return a*n + 19*n
+		}`,
+		pos: []string{"\tADDQ\t[$]19", "\tIMULQ"}, // (a+19)*n
+	},
+	{
+		fn: `
+		func mul4(n int) int {
+			return 23*n - 9*n
+		}`,
+		pos: []string{"\tIMULQ\t[$]14"}, // 14*n
+	},
+	{
+		fn: `
+		func mul5(a, n int) int {
+			return a*n - 19*n
+		}`,
+		pos: []string{"\tADDQ\t[$]-19", "\tIMULQ"}, // (a-19)*n
+	},
+
 	// see issue 19595.
 	// We want to merge load+op in f58, but not in f59.
 	{
-		`
+		fn: `
 		func f58(p, q *int) {
 			x := *p
 			*q += x
 		}`,
-		[]string{"\tADDQ\t\\("},
+		pos: []string{"\tADDQ\t\\("},
 	},
 	{
-		`
+		fn: `
 		func f59(p, q *int) {
 			x := *p
 			for i := 0; i < 10; i++ {
 				*q += x
 			}
 		}`,
-		[]string{"\tADDQ\t[A-Z]"},
+		pos: []string{"\tADDQ\t[A-Z]"},
 	},
 	// Floating-point strength reduction
 	{
-		`
+		fn: `
 		func f60(f float64) float64 {
 			return f * 2.0
 		}`,
-		[]string{"\tADDSD\t"},
+		pos: []string{"\tADDSD\t"},
 	},
 	{
-		`
+		fn: `
 		func f62(f float64) float64 {
 			return f / 16.0
 		}`,
-		[]string{"\tMULSD\t"},
+		pos: []string{"\tMULSD\t"},
 	},
 	{
-		`
+		fn: `
 		func f63(f float64) float64 {
 			return f / 0.125
 		}`,
-		[]string{"\tMULSD\t"},
+		pos: []string{"\tMULSD\t"},
 	},
 	{
-		`
+		fn: `
 		func f64(f float64) float64 {
 			return f / 0.5
 		}`,
-		[]string{"\tADDSD\t"},
+		pos: []string{"\tADDSD\t"},
 	},
 	// Check that compare to constant string uses 2/4/8 byte compares
 	{
-		`
+		fn: `
 		func f65(a string) bool {
 		    return a == "xx"
 		}`,
-		[]string{"\tCMPW\t[A-Z]"},
+		pos: []string{"\tCMPW\t[A-Z]"},
 	},
 	{
-		`
+		fn: `
 		func f66(a string) bool {
 		    return a == "xxxx"
 		}`,
-		[]string{"\tCMPL\t[A-Z]"},
+		pos: []string{"\tCMPL\t[A-Z]"},
 	},
 	{
-		`
+		fn: `
 		func f67(a string) bool {
 		    return a == "xxxxxxxx"
 		}`,
-		[]string{"\tCMPQ\t[A-Z]"},
+		pos: []string{"\tCMPQ\t[A-Z]"},
 	},
 	// Non-constant rotate
 	{
-		`func rot64l(x uint64, y int) uint64 {
+		fn: `func rot64l(x uint64, y int) uint64 {
 			z := uint(y & 63)
 			return x << z | x >> (64-z)
 		}`,
-		[]string{"\tROLQ\t"},
+		pos: []string{"\tROLQ\t"},
 	},
 	{
-		`func rot64r(x uint64, y int) uint64 {
+		fn: `func rot64r(x uint64, y int) uint64 {
 			z := uint(y & 63)
 			return x >> z | x << (64-z)
 		}`,
-		[]string{"\tRORQ\t"},
+		pos: []string{"\tRORQ\t"},
 	},
 	{
-		`func rot32l(x uint32, y int) uint32 {
+		fn: `func rot32l(x uint32, y int) uint32 {
 			z := uint(y & 31)
 			return x << z | x >> (32-z)
 		}`,
-		[]string{"\tROLL\t"},
+		pos: []string{"\tROLL\t"},
 	},
 	{
-		`func rot32r(x uint32, y int) uint32 {
+		fn: `func rot32r(x uint32, y int) uint32 {
 			z := uint(y & 31)
 			return x >> z | x << (32-z)
 		}`,
-		[]string{"\tRORL\t"},
+		pos: []string{"\tRORL\t"},
 	},
 	{
-		`func rot16l(x uint16, y int) uint16 {
+		fn: `func rot16l(x uint16, y int) uint16 {
 			z := uint(y & 15)
 			return x << z | x >> (16-z)
 		}`,
-		[]string{"\tROLW\t"},
+		pos: []string{"\tROLW\t"},
 	},
 	{
-		`func rot16r(x uint16, y int) uint16 {
+		fn: `func rot16r(x uint16, y int) uint16 {
 			z := uint(y & 15)
 			return x >> z | x << (16-z)
 		}`,
-		[]string{"\tRORW\t"},
+		pos: []string{"\tRORW\t"},
 	},
 	{
-		`func rot8l(x uint8, y int) uint8 {
+		fn: `func rot8l(x uint8, y int) uint8 {
 			z := uint(y & 7)
 			return x << z | x >> (8-z)
 		}`,
-		[]string{"\tROLB\t"},
+		pos: []string{"\tROLB\t"},
 	},
 	{
-		`func rot8r(x uint8, y int) uint8 {
+		fn: `func rot8r(x uint8, y int) uint8 {
 			z := uint(y & 7)
 			return x >> z | x << (8-z)
 		}`,
-		[]string{"\tRORB\t"},
+		pos: []string{"\tRORB\t"},
 	},
 	// Check that array compare uses 2/4/8 byte compares
 	{
-		`
+		fn: `
 		func f68(a,b [2]byte) bool {
 		    return a == b
 		}`,
-		[]string{"\tCMPW\t[A-Z]"},
+		pos: []string{"\tCMPW\t[A-Z]"},
 	},
 	{
-		`
+		fn: `
 		func f69(a,b [3]uint16) bool {
 		    return a == b
 		}`,
-		[]string{"\tCMPL\t[A-Z]"},
+		pos: []string{"\tCMPL\t[A-Z]"},
 	},
 	{
-		`
+		fn: `
+		func $(a,b [3]int16) bool {
+		    return a == b
+		}`,
+		pos: []string{"\tCMPL\t[A-Z]"},
+	},
+	{
+		fn: `
+		func $(a,b [12]int8) bool {
+		    return a == b
+		}`,
+		pos: []string{"\tCMPQ\t[A-Z]", "\tCMPL\t[A-Z]"},
+	},
+	{
+		fn: `
 		func f70(a,b [15]byte) bool {
 		    return a == b
 		}`,
-		[]string{"\tCMPQ\t[A-Z]"},
+		pos: []string{"\tCMPQ\t[A-Z]"},
 	},
 	{
-		`
+		fn: `
 		func f71(a,b unsafe.Pointer) bool { // This was a TODO in mapaccess1_faststr
 		    return *((*[4]byte)(a)) != *((*[4]byte)(b))
 		}`,
-		[]string{"\tCMPL\t[A-Z]"},
+		pos: []string{"\tCMPL\t[A-Z]"},
 	},
 	{
 		// make sure assembly output has matching offset and base register.
-		`
+		fn: `
 		func f72(a, b int) int {
-			var x [16]byte // use some frame
-			_ = x
+			runtime.GC() // use some frame
 			return b
 		}
 		`,
-		[]string{"b\\+40\\(SP\\)"},
+		pos: []string{"b\\+24\\(SP\\)"},
+	},
+	{
+		// check load combining
+		fn: `
+		func f73(a, b byte) (byte,byte) {
+		    return f73(f73(a,b))
+		}
+		`,
+		pos: []string{"\tMOVW\t"},
+	},
+	{
+		fn: `
+		func f74(a, b uint16) (uint16,uint16) {
+		    return f74(f74(a,b))
+		}
+		`,
+		pos: []string{"\tMOVL\t"},
+	},
+	{
+		fn: `
+		func f75(a, b uint32) (uint32,uint32) {
+		    return f75(f75(a,b))
+		}
+		`,
+		pos: []string{"\tMOVQ\t"},
+	},
+	// Make sure we don't put pointers in SSE registers across safe points.
+	{
+		fn: `
+		func $(p, q *[2]*int)  {
+		    a, b := p[0], p[1]
+		    runtime.GC()
+		    q[0], q[1] = a, b
+		}
+		`,
+		neg: []string{"MOVUPS"},
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]0-8"},
+	},
+	// math.Abs using integer registers
+	{
+		fn: `
+		func $(x float64) float64 {
+			return math.Abs(x)
+		}
+		`,
+		pos: []string{"\tSHLQ\t[$]1,", "\tSHRQ\t[$]1,"},
+	},
+	// math.Copysign using integer registers
+	{
+		fn: `
+		func $(x, y float64) float64 {
+			return math.Copysign(x, y)
+		}
+		`,
+		pos: []string{"\tSHLQ\t[$]1,", "\tSHRQ\t[$]1,", "\tSHRQ\t[$]63,", "\tSHLQ\t[$]63,", "\tORQ\t"},
+	},
+	// int <-> fp moves
+	{
+		fn: `
+		func $(x float64) uint64 {
+			return math.Float64bits(x+1) + 1
+		}
+		`,
+		pos: []string{"\tMOVQ\tX.*, [^X].*"},
+	},
+	{
+		fn: `
+		func $(x float32) uint32 {
+			return math.Float32bits(x+1) + 1
+		}
+		`,
+		pos: []string{"\tMOVL\tX.*, [^X].*"},
+	},
+	{
+		fn: `
+		func $(x uint64) float64 {
+			return math.Float64frombits(x+1) + 1
+		}
+		`,
+		pos: []string{"\tMOVQ\t[^X].*, X.*"},
+	},
+	{
+		fn: `
+		func $(x uint32) float32 {
+			return math.Float32frombits(x+1) + 1
+		}
+		`,
+		pos: []string{"\tMOVL\t[^X].*, X.*"},
+	},
+	{
+		fn: `
+		func $(x uint32) bool {
+			return x > 4
+		}
+		`,
+		pos: []string{"\tSETHI\t\\("},
+	},
+	// Check that len() and cap() div by a constant power of two
+	// are compiled into SHRQ.
+	{
+		fn: `
+		func $(a []int) int {
+			return len(a) / 1024
+		}
+		`,
+		pos: []string{"\tSHRQ\t\\$10,"},
+	},
+	{
+		fn: `
+		func $(s string) int {
+			return len(s) / (4097 >> 1)
+		}
+		`,
+		pos: []string{"\tSHRQ\t\\$11,"},
+	},
+	{
+		fn: `
+		func $(a []int) int {
+			return cap(a) / ((1 << 11) + 2048)
+		}
+		`,
+		pos: []string{"\tSHRQ\t\\$12,"},
+	},
+	// Check that len() and cap() mod by a constant power of two
+	// are compiled into ANDQ.
+	{
+		fn: `
+		func $(a []int) int {
+			return len(a) % 1024
+		}
+		`,
+		pos: []string{"\tANDQ\t\\$1023,"},
+	},
+	{
+		fn: `
+		func $(s string) int {
+			return len(s) % (4097 >> 1)
+		}
+		`,
+		pos: []string{"\tANDQ\t\\$2047,"},
+	},
+	{
+		fn: `
+		func $(a []int) int {
+			return cap(a) % ((1 << 11) + 2048)
+		}
+		`,
+		pos: []string{"\tANDQ\t\\$4095,"},
+	},
+	{
+		// Test that small memmove was replaced with direct movs
+		fn: `
+                func $() {
+                       x := [...]byte{1, 2, 3, 4, 5, 6, 7}
+                       copy(x[1:], x[:])
+                }
+		`,
+		neg: []string{"memmove"},
+	},
+	{
+		// Same as above but with different size
+		fn: `
+                func $() {
+                       x := [...]byte{1, 2, 3, 4}
+                       copy(x[1:], x[:])
+                }
+		`,
+		neg: []string{"memmove"},
+	},
+	{
+		// Same as above but with different size
+		fn: `
+                func $() {
+                       x := [...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
+                       copy(x[1:], x[:])
+                }
+		`,
+		neg: []string{"memmove"},
+	},
+	// Nil checks before calling interface methods
+	{
+		fn: `
+		type I interface {
+			foo000()
+			foo001()
+			foo002()
+			foo003()
+			foo004()
+			foo005()
+			foo006()
+			foo007()
+			foo008()
+			foo009()
+			foo010()
+			foo011()
+			foo012()
+			foo013()
+			foo014()
+			foo015()
+			foo016()
+			foo017()
+			foo018()
+			foo019()
+			foo020()
+			foo021()
+			foo022()
+			foo023()
+			foo024()
+			foo025()
+			foo026()
+			foo027()
+			foo028()
+			foo029()
+			foo030()
+			foo031()
+			foo032()
+			foo033()
+			foo034()
+			foo035()
+			foo036()
+			foo037()
+			foo038()
+			foo039()
+			foo040()
+			foo041()
+			foo042()
+			foo043()
+			foo044()
+			foo045()
+			foo046()
+			foo047()
+			foo048()
+			foo049()
+			foo050()
+			foo051()
+			foo052()
+			foo053()
+			foo054()
+			foo055()
+			foo056()
+			foo057()
+			foo058()
+			foo059()
+			foo060()
+			foo061()
+			foo062()
+			foo063()
+			foo064()
+			foo065()
+			foo066()
+			foo067()
+			foo068()
+			foo069()
+			foo070()
+			foo071()
+			foo072()
+			foo073()
+			foo074()
+			foo075()
+			foo076()
+			foo077()
+			foo078()
+			foo079()
+			foo080()
+			foo081()
+			foo082()
+			foo083()
+			foo084()
+			foo085()
+			foo086()
+			foo087()
+			foo088()
+			foo089()
+			foo090()
+			foo091()
+			foo092()
+			foo093()
+			foo094()
+			foo095()
+			foo096()
+			foo097()
+			foo098()
+			foo099()
+			foo100()
+			foo101()
+			foo102()
+			foo103()
+			foo104()
+			foo105()
+			foo106()
+			foo107()
+			foo108()
+			foo109()
+			foo110()
+			foo111()
+			foo112()
+			foo113()
+			foo114()
+			foo115()
+			foo116()
+			foo117()
+			foo118()
+			foo119()
+			foo120()
+			foo121()
+			foo122()
+			foo123()
+			foo124()
+			foo125()
+			foo126()
+			foo127()
+			foo128()
+			foo129()
+			foo130()
+			foo131()
+			foo132()
+			foo133()
+			foo134()
+			foo135()
+			foo136()
+			foo137()
+			foo138()
+			foo139()
+			foo140()
+			foo141()
+			foo142()
+			foo143()
+			foo144()
+			foo145()
+			foo146()
+			foo147()
+			foo148()
+			foo149()
+			foo150()
+			foo151()
+			foo152()
+			foo153()
+			foo154()
+			foo155()
+			foo156()
+			foo157()
+			foo158()
+			foo159()
+			foo160()
+			foo161()
+			foo162()
+			foo163()
+			foo164()
+			foo165()
+			foo166()
+			foo167()
+			foo168()
+			foo169()
+			foo170()
+			foo171()
+			foo172()
+			foo173()
+			foo174()
+			foo175()
+			foo176()
+			foo177()
+			foo178()
+			foo179()
+			foo180()
+			foo181()
+			foo182()
+			foo183()
+			foo184()
+			foo185()
+			foo186()
+			foo187()
+			foo188()
+			foo189()
+			foo190()
+			foo191()
+			foo192()
+			foo193()
+			foo194()
+			foo195()
+			foo196()
+			foo197()
+			foo198()
+			foo199()
+			foo200()
+			foo201()
+			foo202()
+			foo203()
+			foo204()
+			foo205()
+			foo206()
+			foo207()
+			foo208()
+			foo209()
+			foo210()
+			foo211()
+			foo212()
+			foo213()
+			foo214()
+			foo215()
+			foo216()
+			foo217()
+			foo218()
+			foo219()
+			foo220()
+			foo221()
+			foo222()
+			foo223()
+			foo224()
+			foo225()
+			foo226()
+			foo227()
+			foo228()
+			foo229()
+			foo230()
+			foo231()
+			foo232()
+			foo233()
+			foo234()
+			foo235()
+			foo236()
+			foo237()
+			foo238()
+			foo239()
+			foo240()
+			foo241()
+			foo242()
+			foo243()
+			foo244()
+			foo245()
+			foo246()
+			foo247()
+			foo248()
+			foo249()
+			foo250()
+			foo251()
+			foo252()
+			foo253()
+			foo254()
+			foo255()
+			foo256()
+			foo257()
+			foo258()
+			foo259()
+			foo260()
+			foo261()
+			foo262()
+			foo263()
+			foo264()
+			foo265()
+			foo266()
+			foo267()
+			foo268()
+			foo269()
+			foo270()
+			foo271()
+			foo272()
+			foo273()
+			foo274()
+			foo275()
+			foo276()
+			foo277()
+			foo278()
+			foo279()
+			foo280()
+			foo281()
+			foo282()
+			foo283()
+			foo284()
+			foo285()
+			foo286()
+			foo287()
+			foo288()
+			foo289()
+			foo290()
+			foo291()
+			foo292()
+			foo293()
+			foo294()
+			foo295()
+			foo296()
+			foo297()
+			foo298()
+			foo299()
+			foo300()
+			foo301()
+			foo302()
+			foo303()
+			foo304()
+			foo305()
+			foo306()
+			foo307()
+			foo308()
+			foo309()
+			foo310()
+			foo311()
+			foo312()
+			foo313()
+			foo314()
+			foo315()
+			foo316()
+			foo317()
+			foo318()
+			foo319()
+			foo320()
+			foo321()
+			foo322()
+			foo323()
+			foo324()
+			foo325()
+			foo326()
+			foo327()
+			foo328()
+			foo329()
+			foo330()
+			foo331()
+			foo332()
+			foo333()
+			foo334()
+			foo335()
+			foo336()
+			foo337()
+			foo338()
+			foo339()
+			foo340()
+			foo341()
+			foo342()
+			foo343()
+			foo344()
+			foo345()
+			foo346()
+			foo347()
+			foo348()
+			foo349()
+			foo350()
+			foo351()
+			foo352()
+			foo353()
+			foo354()
+			foo355()
+			foo356()
+			foo357()
+			foo358()
+			foo359()
+			foo360()
+			foo361()
+			foo362()
+			foo363()
+			foo364()
+			foo365()
+			foo366()
+			foo367()
+			foo368()
+			foo369()
+			foo370()
+			foo371()
+			foo372()
+			foo373()
+			foo374()
+			foo375()
+			foo376()
+			foo377()
+			foo378()
+			foo379()
+			foo380()
+			foo381()
+			foo382()
+			foo383()
+			foo384()
+			foo385()
+			foo386()
+			foo387()
+			foo388()
+			foo389()
+			foo390()
+			foo391()
+			foo392()
+			foo393()
+			foo394()
+			foo395()
+			foo396()
+			foo397()
+			foo398()
+			foo399()
+			foo400()
+			foo401()
+			foo402()
+			foo403()
+			foo404()
+			foo405()
+			foo406()
+			foo407()
+			foo408()
+			foo409()
+			foo410()
+			foo411()
+			foo412()
+			foo413()
+			foo414()
+			foo415()
+			foo416()
+			foo417()
+			foo418()
+			foo419()
+			foo420()
+			foo421()
+			foo422()
+			foo423()
+			foo424()
+			foo425()
+			foo426()
+			foo427()
+			foo428()
+			foo429()
+			foo430()
+			foo431()
+			foo432()
+			foo433()
+			foo434()
+			foo435()
+			foo436()
+			foo437()
+			foo438()
+			foo439()
+			foo440()
+			foo441()
+			foo442()
+			foo443()
+			foo444()
+			foo445()
+			foo446()
+			foo447()
+			foo448()
+			foo449()
+			foo450()
+			foo451()
+			foo452()
+			foo453()
+			foo454()
+			foo455()
+			foo456()
+			foo457()
+			foo458()
+			foo459()
+			foo460()
+			foo461()
+			foo462()
+			foo463()
+			foo464()
+			foo465()
+			foo466()
+			foo467()
+			foo468()
+			foo469()
+			foo470()
+			foo471()
+			foo472()
+			foo473()
+			foo474()
+			foo475()
+			foo476()
+			foo477()
+			foo478()
+			foo479()
+			foo480()
+			foo481()
+			foo482()
+			foo483()
+			foo484()
+			foo485()
+			foo486()
+			foo487()
+			foo488()
+			foo489()
+			foo490()
+			foo491()
+			foo492()
+			foo493()
+			foo494()
+			foo495()
+			foo496()
+			foo497()
+			foo498()
+			foo499()
+			foo500()
+			foo501()
+			foo502()
+			foo503()
+			foo504()
+			foo505()
+			foo506()
+			foo507()
+			foo508()
+			foo509()
+			foo510()
+			foo511()
+		}
+		func $(i I) {
+			i.foo511()
+		}
+		`,
+		pos: []string{"TESTB"},
+	},
+	{
+		fn: `
+		func $(i I) {
+			i.foo001()
+		}
+		`,
+		neg: []string{"TESTB"},
 	},
 }
 
 var linux386Tests = []*asmTest{
 	{
-		`
+		fn: `
 		func f0(b []byte) uint32 {
 			return binary.LittleEndian.Uint32(b)
 		}
 		`,
-		[]string{"\tMOVL\t\\(.*\\),"},
+		pos: []string{"\tMOVL\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f1(b []byte, i int) uint32 {
 			return binary.LittleEndian.Uint32(b[i:])
 		}
 		`,
-		[]string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
+	},
+
+	// multiplication by powers of two
+	{
+		fn: `
+		func $(n int) int {
+			return 32*n
+		}
+		`,
+		pos: []string{"SHLL"},
+		neg: []string{"IMULL"},
+	},
+	{
+		fn: `
+		func $(n int) int {
+			return -64*n
+		}
+		`,
+		pos: []string{"SHLL"},
+		neg: []string{"IMULL"},
+	},
+
+	// multiplication merging tests
+	{
+		fn: `
+		func $(n int) int {
+			return 9*n + 14*n
+		}`,
+		pos: []string{"\tIMULL\t[$]23"}, // 23*n
+	},
+	{
+		fn: `
+		func $(a, n int) int {
+			return 19*a + a*n
+		}`,
+		pos: []string{"\tADDL\t[$]19", "\tIMULL"}, // (n+19)*a
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]0-4"},
+	},
+	{
+		fn: `
+		func mul3(n int) int {
+			return 23*n - 9*n
+		}`,
+		pos: []string{"\tIMULL\t[$]14"}, // 14*n
+	},
+	{
+		fn: `
+		func mul4(a, n int) int {
+			return n*a - a*19
+		}`,
+		pos: []string{"\tADDL\t[$]-19", "\tIMULL"}, // (n-19)*a
+	},
+	// Check that len() and cap() div by a constant power of two
+	// are compiled into SHRL.
+	{
+		fn: `
+		func $(a []int) int {
+			return len(a) / 1024
+		}
+		`,
+		pos: []string{"\tSHRL\t\\$10,"},
+	},
+	{
+		fn: `
+		func $(s string) int {
+			return len(s) / (4097 >> 1)
+		}
+		`,
+		pos: []string{"\tSHRL\t\\$11,"},
+	},
+	{
+		fn: `
+		func $(a []int) int {
+			return cap(a) / ((1 << 11) + 2048)
+		}
+		`,
+		pos: []string{"\tSHRL\t\\$12,"},
+	},
+	// Check that len() and cap() mod by a constant power of two
+	// are compiled into ANDL.
+	{
+		fn: `
+		func $(a []int) int {
+			return len(a) % 1024
+		}
+		`,
+		pos: []string{"\tANDL\t\\$1023,"},
+	},
+	{
+		fn: `
+		func $(s string) int {
+			return len(s) % (4097 >> 1)
+		}
+		`,
+		pos: []string{"\tANDL\t\\$2047,"},
+	},
+	{
+		fn: `
+		func $(a []int) int {
+			return cap(a) % ((1 << 11) + 2048)
+		}
+		`,
+		pos: []string{"\tANDL\t\\$4095,"},
+	},
+	{
+		// Test that small memmove was replaced with direct movs
+		fn: `
+                func $() {
+                       x := [...]byte{1, 2, 3, 4, 5, 6, 7}
+                       copy(x[1:], x[:])
+                }
+		`,
+		neg: []string{"memmove"},
+	},
+	{
+		// Same as above but with different size
+		fn: `
+                func $() {
+                       x := [...]byte{1, 2, 3, 4}
+                       copy(x[1:], x[:])
+                }
+		`,
+		neg: []string{"memmove"},
 	},
 }
 
 var linuxS390XTests = []*asmTest{
 	{
-		`
+		fn: `
 		func f0(b []byte) uint32 {
 			return binary.LittleEndian.Uint32(b)
 		}
 		`,
-		[]string{"\tMOVWBR\t\\(.*\\),"},
+		pos: []string{"\tMOVWBR\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f1(b []byte, i int) uint32 {
 			return binary.LittleEndian.Uint32(b[i:])
 		}
 		`,
-		[]string{"\tMOVWBR\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVWBR\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f2(b []byte) uint64 {
 			return binary.LittleEndian.Uint64(b)
 		}
 		`,
-		[]string{"\tMOVDBR\t\\(.*\\),"},
+		pos: []string{"\tMOVDBR\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f3(b []byte, i int) uint64 {
 			return binary.LittleEndian.Uint64(b[i:])
 		}
 		`,
-		[]string{"\tMOVDBR\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVDBR\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f4(b []byte) uint32 {
 			return binary.BigEndian.Uint32(b)
 		}
 		`,
-		[]string{"\tMOVWZ\t\\(.*\\),"},
+		pos: []string{"\tMOVWZ\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f5(b []byte, i int) uint32 {
 			return binary.BigEndian.Uint32(b[i:])
 		}
 		`,
-		[]string{"\tMOVWZ\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVWZ\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f6(b []byte) uint64 {
 			return binary.BigEndian.Uint64(b)
 		}
 		`,
-		[]string{"\tMOVD\t\\(.*\\),"},
+		pos: []string{"\tMOVD\t\\(.*\\),"},
 	},
 	{
-		`
+		fn: `
 		func f7(b []byte, i int) uint64 {
 			return binary.BigEndian.Uint64(b[i:])
 		}
 		`,
-		[]string{"\tMOVD\t\\(.*\\)\\(.*\\*1\\),"},
+		pos: []string{"\tMOVD\t\\(.*\\)\\(.*\\*1\\),"},
 	},
 	{
-		`
+		fn: `
 		func f8(x uint64) uint64 {
 			return x<<7 + x>>57
 		}
 		`,
-		[]string{"\tRLLG\t[$]7,"},
+		pos: []string{"\tRLLG\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f9(x uint64) uint64 {
 			return x<<7 | x>>57
 		}
 		`,
-		[]string{"\tRLLG\t[$]7,"},
+		pos: []string{"\tRLLG\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f10(x uint64) uint64 {
 			return x<<7 ^ x>>57
 		}
 		`,
-		[]string{"\tRLLG\t[$]7,"},
+		pos: []string{"\tRLLG\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f11(x uint32) uint32 {
 			return x<<7 + x>>25
 		}
 		`,
-		[]string{"\tRLL\t[$]7,"},
+		pos: []string{"\tRLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f12(x uint32) uint32 {
 			return x<<7 | x>>25
 		}
 		`,
-		[]string{"\tRLL\t[$]7,"},
+		pos: []string{"\tRLL\t[$]7,"},
 	},
 	{
-		`
+		fn: `
 		func f13(x uint32) uint32 {
 			return x<<7 ^ x>>25
 		}
 		`,
-		[]string{"\tRLL\t[$]7,"},
+		pos: []string{"\tRLL\t[$]7,"},
 	},
 	// Fused multiply-add/sub instructions.
 	{
-		`
+		fn: `
 		func f14(x, y, z float64) float64 {
 			return x * y + z
 		}
 		`,
-		[]string{"\tFMADD\t"},
+		pos: []string{"\tFMADD\t"},
 	},
 	{
-		`
+		fn: `
 		func f15(x, y, z float64) float64 {
 			return x * y - z
 		}
 		`,
-		[]string{"\tFMSUB\t"},
+		pos: []string{"\tFMSUB\t"},
 	},
 	{
-		`
+		fn: `
 		func f16(x, y, z float32) float32 {
 			return x * y + z
 		}
 		`,
-		[]string{"\tFMADDS\t"},
+		pos: []string{"\tFMADDS\t"},
 	},
 	{
-		`
+		fn: `
 		func f17(x, y, z float32) float32 {
 			return x * y - z
 		}
 		`,
-		[]string{"\tFMSUBS\t"},
+		pos: []string{"\tFMSUBS\t"},
 	},
 	// Intrinsic tests for math/bits
 	{
-		`
+		fn: `
 		func f18(a uint64) int {
 			return bits.TrailingZeros64(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f19(a uint32) int {
 			return bits.TrailingZeros32(a)
 		}
 		`,
-		[]string{"\tFLOGR\t", "\tMOVWZ\t"},
+		pos: []string{"\tFLOGR\t", "\tMOVWZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f20(a uint16) int {
 			return bits.TrailingZeros16(a)
 		}
 		`,
-		[]string{"\tFLOGR\t", "\tOR\t\\$65536,"},
+		pos: []string{"\tFLOGR\t", "\tOR\t\\$65536,"},
 	},
 	{
-		`
+		fn: `
 		func f21(a uint8) int {
 			return bits.TrailingZeros8(a)
 		}
 		`,
-		[]string{"\tFLOGR\t", "\tOR\t\\$256,"},
+		pos: []string{"\tFLOGR\t", "\tOR\t\\$256,"},
 	},
 	// Intrinsic tests for math/bits
 	{
-		`
+		fn: `
 		func f22(a uint64) uint64 {
 			return bits.ReverseBytes64(a)
 		}
 		`,
-		[]string{"\tMOVDBR\t"},
+		pos: []string{"\tMOVDBR\t"},
 	},
 	{
-		`
+		fn: `
 		func f23(a uint32) uint32 {
 			return bits.ReverseBytes32(a)
 		}
 		`,
-		[]string{"\tMOVWBR\t"},
+		pos: []string{"\tMOVWBR\t"},
 	},
 	{
-		`
+		fn: `
 		func f24(a uint64) int {
 			return bits.Len64(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f25(a uint32) int {
 			return bits.Len32(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f26(a uint16) int {
 			return bits.Len16(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f27(a uint8) int {
 			return bits.Len8(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f28(a uint) int {
 			return bits.Len(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f29(a uint64) int {
 			return bits.LeadingZeros64(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f30(a uint32) int {
 			return bits.LeadingZeros32(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f31(a uint16) int {
 			return bits.LeadingZeros16(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f32(a uint8) int {
 			return bits.LeadingZeros8(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
 	},
 	{
-		`
+		fn: `
 		func f33(a uint) int {
 			return bits.LeadingZeros(a)
 		}
 		`,
-		[]string{"\tFLOGR\t"},
+		pos: []string{"\tFLOGR\t"},
+	},
+	// Intrinsic tests for math.
+	{
+		fn: `
+		func ceil(x float64) float64 {
+			return math.Ceil(x)
+		}
+		`,
+		pos: []string{"\tFIDBR\t[$]6"},
+	},
+	{
+		fn: `
+		func floor(x float64) float64 {
+			return math.Floor(x)
+		}
+		`,
+		pos: []string{"\tFIDBR\t[$]7"},
+	},
+	{
+		fn: `
+		func round(x float64) float64 {
+			return math.Round(x)
+		}
+		`,
+		pos: []string{"\tFIDBR\t[$]1"},
+	},
+	{
+		fn: `
+		func trunc(x float64) float64 {
+			return math.Trunc(x)
+		}
+		`,
+		pos: []string{"\tFIDBR\t[$]5"},
+	},
+	{
+		fn: `
+		func roundToEven(x float64) float64 {
+			return math.RoundToEven(x)
+		}
+		`,
+		pos: []string{"\tFIDBR\t[$]4"},
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]0-8"},
+	},
+	// Constant propagation through raw bits conversions.
+	{
+		// uint32 constant converted to float32 constant
+		fn: `
+		func $(x float32) float32 {
+			if x > math.Float32frombits(0x3f800000) {
+				return -x
+			}
+			return x
+		}
+		`,
+		pos: []string{"\tFMOVS\t[$]f32.3f800000\\(SB\\)"},
+	},
+	{
+		// float32 constant converted to uint32 constant
+		fn: `
+		func $(x uint32) uint32 {
+			if x > math.Float32bits(1) {
+				return -x
+			}
+			return x
+		}
+		`,
+		neg: []string{"\tFMOVS\t"},
+	},
+	// Constant propagation through float comparisons.
+	{
+		fn: `
+		func $() bool {
+			return 0.5 == float64(uint32(1)) ||
+				1.5 > float64(uint64(1<<63)) ||
+				math.NaN() == math.NaN()
+		}
+		`,
+		pos: []string{"\tMOV(B|BZ|D)\t[$]0,"},
+		neg: []string{"\tFCMPU\t", "\tMOV(B|BZ|D)\t[$]1,"},
+	},
+	{
+		fn: `
+		func $() bool {
+			return float32(0.5) <= float32(int64(1)) &&
+				float32(1.5) >= float32(int32(-1<<31)) &&
+				float32(math.NaN()) != float32(math.NaN())
+		}
+		`,
+		pos: []string{"\tMOV(B|BZ|D)\t[$]1,"},
+		neg: []string{"\tCEBR\t", "\tMOV(B|BZ|D)\t[$]0,"},
+	},
+	// math tests
+	{
+		fn: `
+		func $(x float64) float64 {
+			return math.Abs(x)
+		}
+		`,
+		pos: []string{"\tLPDFR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
+	},
+	{
+		fn: `
+		func $(x float32) float32 {
+			return float32(math.Abs(float64(x)))
+		}
+		`,
+		pos: []string{"\tLPDFR\t"},
+		neg: []string{"\tLDEBR\t", "\tLEDBR\t"}, // no float64 conversion
+	},
+	{
+		fn: `
+		func $(x float64) float64 {
+			return math.Float64frombits(math.Float64bits(x)|1<<63)
+		}
+		`,
+		pos: []string{"\tLNDFR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
+	},
+	{
+		fn: `
+		func $(x float64) float64 {
+			return -math.Abs(x)
+		}
+		`,
+		pos: []string{"\tLNDFR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
+	},
+	{
+		fn: `
+		func $(x, y float64) float64 {
+			return math.Copysign(x, y)
+		}
+		`,
+		pos: []string{"\tCPSDR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
+	},
+	{
+		fn: `
+		func $(x float64) float64 {
+			return math.Copysign(x, -1)
+		}
+		`,
+		pos: []string{"\tLNDFR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
+	},
+	{
+		fn: `
+		func $(x float64) float64 {
+			return math.Copysign(-1, x)
+		}
+		`,
+		pos: []string{"\tCPSDR\t"},
+		neg: []string{"\tMOVD\t"}, // no integer loads/stores
 	},
 }
 
 var linuxARMTests = []*asmTest{
+	// multiplication by powers of two
 	{
-		`
+		fn: `
+		func $(n int) int {
+			return 16*n
+		}
+		`,
+		pos: []string{"\tSLL\t[$]4"},
+		neg: []string{"\tMUL\t"},
+	},
+	{
+		fn: `
+		func $(n int) int {
+			return -32*n
+		}
+		`,
+		pos: []string{"\tSLL\t[$]5"},
+		neg: []string{"\tMUL\t"},
+	},
+
+	{
+		fn: `
 		func f0(x uint32) uint32 {
 			return x<<7 + x>>25
 		}
 		`,
-		[]string{"\tMOVW\tR[0-9]+@>25,"},
+		pos: []string{"\tMOVW\tR[0-9]+@>25,"},
 	},
 	{
-		`
+		fn: `
 		func f1(x uint32) uint32 {
 			return x<<7 | x>>25
 		}
 		`,
-		[]string{"\tMOVW\tR[0-9]+@>25,"},
+		pos: []string{"\tMOVW\tR[0-9]+@>25,"},
 	},
 	{
-		`
+		fn: `
 		func f2(x uint32) uint32 {
 			return x<<7 ^ x>>25
 		}
 		`,
-		[]string{"\tMOVW\tR[0-9]+@>25,"},
+		pos: []string{"\tMOVW\tR[0-9]+@>25,"},
 	},
 	{
-		`
+		fn: `
 		func f3(a uint64) int {
 			return bits.Len64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f4(a uint32) int {
 			return bits.Len32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f5(a uint16) int {
 			return bits.Len16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f6(a uint8) int {
 			return bits.Len8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f7(a uint) int {
 			return bits.Len(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f8(a uint64) int {
 			return bits.LeadingZeros64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f9(a uint32) int {
 			return bits.LeadingZeros32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f10(a uint16) int {
 			return bits.LeadingZeros16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f11(a uint8) int {
 			return bits.LeadingZeros8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f12(a uint) int {
 			return bits.LeadingZeros(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
 		// make sure assembly output has matching offset and base register.
-		`
+		fn: `
 		func f13(a, b int) int {
-			var x [16]byte // use some frame
-			_ = x
+			runtime.GC() // use some frame
 			return b
 		}
 		`,
-		[]string{"b\\+4\\(FP\\)"},
+		pos: []string{"b\\+4\\(FP\\)"},
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]-4-4"},
 	},
 }
 
 var linuxARM64Tests = []*asmTest{
+	// multiplication by powers of two
 	{
-		`
+		fn: `
+		func $(n int) int {
+			return 64*n
+		}
+		`,
+		pos: []string{"\tLSL\t[$]6"},
+		neg: []string{"\tMUL\t"},
+	},
+	{
+		fn: `
+		func $(n int) int {
+			return -128*n
+		}
+		`,
+		pos: []string{"\tLSL\t[$]7"},
+		neg: []string{"\tMUL\t"},
+	},
+
+	{
+		fn: `
 		func f0(x uint64) uint64 {
 			return x<<7 + x>>57
 		}
 		`,
-		[]string{"\tROR\t[$]57,"},
+		pos: []string{"\tROR\t[$]57,"},
 	},
 	{
-		`
+		fn: `
 		func f1(x uint64) uint64 {
 			return x<<7 | x>>57
 		}
 		`,
-		[]string{"\tROR\t[$]57,"},
+		pos: []string{"\tROR\t[$]57,"},
 	},
 	{
-		`
+		fn: `
 		func f2(x uint64) uint64 {
 			return x<<7 ^ x>>57
 		}
 		`,
-		[]string{"\tROR\t[$]57,"},
+		pos: []string{"\tROR\t[$]57,"},
 	},
 	{
-		`
+		fn: `
 		func f3(x uint32) uint32 {
 			return x<<7 + x>>25
 		}
 		`,
-		[]string{"\tRORW\t[$]25,"},
+		pos: []string{"\tRORW\t[$]25,"},
 	},
 	{
-		`
+		fn: `
 		func f4(x uint32) uint32 {
 			return x<<7 | x>>25
 		}
 		`,
-		[]string{"\tRORW\t[$]25,"},
+		pos: []string{"\tRORW\t[$]25,"},
 	},
 	{
-		`
+		fn: `
 		func f5(x uint32) uint32 {
 			return x<<7 ^ x>>25
 		}
 		`,
-		[]string{"\tRORW\t[$]25,"},
+		pos: []string{"\tRORW\t[$]25,"},
 	},
 	{
-		`
+		fn: `
 		func f22(a uint64) uint64 {
 			return bits.ReverseBytes64(a)
 		}
 		`,
-		[]string{"\tREV\t"},
+		pos: []string{"\tREV\t"},
 	},
 	{
-		`
+		fn: `
 		func f23(a uint32) uint32 {
 			return bits.ReverseBytes32(a)
 		}
 		`,
-		[]string{"\tREVW\t"},
+		pos: []string{"\tREVW\t"},
 	},
 	{
-		`
+		fn: `
 		func f24(a uint64) int {
 			return bits.Len64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f25(a uint32) int {
 			return bits.Len32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f26(a uint16) int {
 			return bits.Len16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f27(a uint8) int {
 			return bits.Len8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f28(a uint) int {
 			return bits.Len(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f29(a uint64) int {
 			return bits.LeadingZeros64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f30(a uint32) int {
 			return bits.LeadingZeros32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f31(a uint16) int {
 			return bits.LeadingZeros16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f32(a uint8) int {
 			return bits.LeadingZeros8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f33(a uint) int {
 			return bits.LeadingZeros(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f34(a uint64) uint64 {
 			return a & ((1<<63)-1)
 		}
 		`,
-		[]string{"\tAND\t"},
+		pos: []string{"\tAND\t"},
 	},
 	{
-		`
+		fn: `
 		func f35(a uint64) uint64 {
 			return a & (1<<63)
 		}
 		`,
-		[]string{"\tAND\t"},
+		pos: []string{"\tAND\t"},
 	},
 	{
 		// make sure offsets are folded into load and store.
-		`
+		fn: `
 		func f36(_, a [20]byte) (b [20]byte) {
 			b = a
 			return
 		}
 		`,
-		[]string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(FP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(FP\\)"},
+		pos: []string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(FP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(FP\\)"},
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]-8-8"},
+	},
+	{
+		// check that we don't emit comparisons for constant shift
+		fn: `
+//go:nosplit
+		func $(x int) int {
+			return x << 17
+		}
+		`,
+		pos: []string{"LSL\t\\$17"},
+		neg: []string{"CMP"},
 	},
 }
 
 var linuxMIPSTests = []*asmTest{
 	{
-		`
+		fn: `
 		func f0(a uint64) int {
 			return bits.Len64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f1(a uint32) int {
 			return bits.Len32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f2(a uint16) int {
 			return bits.Len16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f3(a uint8) int {
 			return bits.Len8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f4(a uint) int {
 			return bits.Len(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f5(a uint64) int {
 			return bits.LeadingZeros64(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f6(a uint32) int {
 			return bits.LeadingZeros32(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f7(a uint16) int {
 			return bits.LeadingZeros16(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f8(a uint8) int {
 			return bits.LeadingZeros8(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
 	},
 	{
-		`
+		fn: `
 		func f9(a uint) int {
 			return bits.LeadingZeros(a)
 		}
 		`,
-		[]string{"\tCLZ\t"},
+		pos: []string{"\tCLZ\t"},
+	},
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]-4-4"},
+	},
+}
+
+var linuxMIPS64Tests = []*asmTest{
+	{
+		// check that we don't emit comparisons for constant shift
+		fn: `
+		func $(x int) int {
+			return x << 17
+		}
+		`,
+		pos: []string{"SLLV\t\\$17"},
+		neg: []string{"SGT"},
 	},
 }
 
 var linuxPPC64LETests = []*asmTest{
 	// Fused multiply-add/sub instructions.
 	{
-		`
+		fn: `
 		func f0(x, y, z float64) float64 {
 			return x * y + z
 		}
 		`,
-		[]string{"\tFMADD\t"},
+		pos: []string{"\tFMADD\t"},
 	},
 	{
-		`
+		fn: `
 		func f1(x, y, z float64) float64 {
 			return x * y - z
 		}
 		`,
-		[]string{"\tFMSUB\t"},
+		pos: []string{"\tFMSUB\t"},
 	},
 	{
-		`
+		fn: `
 		func f2(x, y, z float32) float32 {
 			return x * y + z
 		}
 		`,
-		[]string{"\tFMADDS\t"},
+		pos: []string{"\tFMADDS\t"},
 	},
 	{
-		`
+		fn: `
 		func f3(x, y, z float32) float32 {
 			return x * y - z
 		}
 		`,
-		[]string{"\tFMSUBS\t"},
+		pos: []string{"\tFMSUBS\t"},
 	},
 	{
-		`
+		fn: `
 		func f4(x uint32) uint32 {
 			return x<<7 | x>>25
 		}
 		`,
-		[]string{"\tROTLW\t"},
+		pos: []string{"\tROTLW\t"},
 	},
 	{
-		`
+		fn: `
 		func f5(x uint32) uint32 {
 			return x<<7 + x>>25
 		}
 		`,
-		[]string{"\tROTLW\t"},
+		pos: []string{"\tROTLW\t"},
 	},
 	{
-		`
+		fn: `
 		func f6(x uint32) uint32 {
 			return x<<7 ^ x>>25
 		}
 		`,
-		[]string{"\tROTLW\t"},
+		pos: []string{"\tROTLW\t"},
 	},
 	{
-		`
+		fn: `
 		func f7(x uint64) uint64 {
 			return x<<7 | x>>57
 		}
 		`,
-		[]string{"\tROTL\t"},
+		pos: []string{"\tROTL\t"},
 	},
 	{
-		`
+		fn: `
 		func f8(x uint64) uint64 {
 			return x<<7 + x>>57
 		}
 		`,
-		[]string{"\tROTL\t"},
+		pos: []string{"\tROTL\t"},
 	},
 	{
-		`
+		fn: `
 		func f9(x uint64) uint64 {
 			return x<<7 ^ x>>57
 		}
 		`,
-		[]string{"\tROTL\t"},
+		pos: []string{"\tROTL\t"},
+	},
+	{
+		fn: `
+		func f10(a uint32) uint32 {
+			return bits.RotateLeft32(a, 9)
+		}
+		`,
+		pos: []string{"\tROTLW\t"},
+	},
+	{
+		fn: `
+		func f11(a uint64) uint64 {
+			return bits.RotateLeft64(a, 37)
+		}
+		`,
+		pos: []string{"\tROTL\t"},
+	},
+
+	{
+		fn: `
+                func f12(a, b float64) float64 {
+                        return math.Copysign(a, b)
+                }
+                `,
+		pos: []string{"\tFCPSGN\t"},
+	},
+
+	{
+		fn: `
+                func f13(a float64) float64 {
+                        return math.Abs(a)
+                }
+                `,
+		pos: []string{"\tFABS\t"},
+	},
+
+	{
+		fn: `
+		func f14(b []byte) uint16 {
+			return binary.LittleEndian.Uint16(b)
+	}
+		`,
+		pos: []string{"\tMOVHZ\t"},
+	},
+	{
+		fn: `
+		func f15(b []byte) uint32 {
+			return binary.LittleEndian.Uint32(b)
+		}
+		`,
+		pos: []string{"\tMOVWZ\t"},
+	},
+
+	{
+		fn: `
+		func f16(b []byte) uint64 {
+			return binary.LittleEndian.Uint64(b)
+		}
+		`,
+		pos: []string{"\tMOVD\t"},
+		neg: []string{"MOVBZ", "MOVHZ", "MOVWZ"},
+	},
+
+	{
+		fn: `
+		func f17(b []byte, v uint16) {
+			binary.LittleEndian.PutUint16(b, v)
+		}
+		`,
+		pos: []string{"\tMOVH\t"},
+	},
+
+	{
+		fn: `
+		func f18(b []byte, v uint32) {
+			binary.LittleEndian.PutUint32(b, v)
+		}
+		`,
+		pos: []string{"\tMOVW\t"},
+	},
+
+	{
+		fn: `
+		func f19(b []byte, v uint64) {
+			binary.LittleEndian.PutUint64(b, v)
+		}
+		`,
+		pos: []string{"\tMOVD\t"},
+		neg: []string{"MOVB", "MOVH", "MOVW"},
+	},
+
+	{
+		// check that stack store is optimized away
+		fn: `
+		func $() int {
+			var x int
+			return *(&x)
+		}
+		`,
+		pos: []string{"TEXT\t.*, [$]0-8"},
+	},
+	// Constant propagation through raw bits conversions.
+	{
+		// uint32 constant converted to float32 constant
+		fn: `
+		func $(x float32) float32 {
+			if x > math.Float32frombits(0x3f800000) {
+				return -x
+			}
+			return x
+		}
+		`,
+		pos: []string{"\tFMOVS\t[$]f32.3f800000\\(SB\\)"},
+	},
+	{
+		// float32 constant converted to uint32 constant
+		fn: `
+		func $(x uint32) uint32 {
+			if x > math.Float32bits(1) {
+				return -x
+			}
+			return x
+		}
+		`,
+		neg: []string{"\tFMOVS\t"},
+	},
+}
+
+var plan9AMD64Tests = []*asmTest{
+	// We should make sure that the compiler doesn't generate floating point
+	// instructions for non-float operations on Plan 9, because floating point
+	// operations are not allowed in the note handler.
+	// Array zeroing.
+	{
+		fn: `
+		func $() [16]byte {
+			var a [16]byte
+			return a
+		}
+		`,
+		pos: []string{"\tMOVQ\t\\$0, \"\""},
+	},
+	// Array copy.
+	{
+		fn: `
+		func $(a [16]byte) (b [16]byte) {
+			b = a
+			return
+		}
+		`,
+		pos: []string{"\tMOVQ\t\"\"\\.a\\+[0-9]+\\(SP\\), (AX|CX)", "\tMOVQ\t(AX|CX), \"\"\\.b\\+[0-9]+\\(SP\\)"},
 	},
 }
 
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index 3ac8136..52ee4de 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -174,6 +174,8 @@
 	typIndex  map[*types.Type]int
 	funcList  []*Func
 
+	marked map[*types.Type]bool // types already seen by markType
+
 	// position encoding
 	posInfoFormat bool
 	prevFile      string
@@ -230,6 +232,23 @@
 		p.tracef("\n")
 	}
 
+	// Mark all inlineable functions that the importer could call.
+	// This is done by tracking down all inlineable methods
+	// reachable from exported types.
+	p.marked = make(map[*types.Type]bool)
+	for _, n := range exportlist {
+		sym := n.Sym
+		if sym.Exported() {
+			// Closures are added to exportlist, but with Exported
+			// already set. The export code below skips over them, so
+			// we have to here as well.
+			// TODO(mdempsky): Investigate why. This seems suspicious.
+			continue
+		}
+		p.markType(asNode(sym.Def).Type)
+	}
+	p.marked = nil
+
 	// export objects
 	//
 	// First, export all exported (package-level) objects; i.e., all objects
@@ -377,6 +396,7 @@
 				p.tracef("\n----\nfunc { %#v }\n", f.Inl)
 			}
 			p.int(i)
+			p.int(int(f.InlCost))
 			p.stmtList(f.Inl)
 			if p.trace {
 				p.tracef("\n")
@@ -435,6 +455,72 @@
 	return typ
 }
 
+// markType recursively visits types reachable from t to identify
+// functions whose inline bodies may be needed.
+func (p *exporter) markType(t *types.Type) {
+	if p.marked[t] {
+		return
+	}
+	p.marked[t] = true
+
+	// If this is a named type, mark all of its associated
+	// methods. Skip interface types because t.Methods contains
+	// only their unexpanded method set (i.e., exclusive of
+	// interface embeddings), and the switch statement below
+	// handles their full method set.
+	if t.Sym != nil && t.Etype != TINTER {
+		for _, m := range t.Methods().Slice() {
+			if exportname(m.Sym.Name) {
+				p.markType(m.Type)
+			}
+		}
+	}
+
+	// Recursively mark any types that can be produced given a
+	// value of type t: dereferencing a pointer; indexing an
+	// array, slice, or map; receiving from a channel; accessing a
+	// struct field or interface method; or calling a function.
+	//
+	// Notably, we don't mark map key or function parameter types,
+	// because the user already needs some way to construct values
+	// of those types.
+	//
+	// It's not critical for correctness that this algorithm is
+	// perfect. Worst case, we might miss opportunities to inline
+	// some function calls in downstream packages.
+	switch t.Etype {
+	case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN:
+		p.markType(t.Elem())
+
+	case TMAP:
+		p.markType(t.Val())
+
+	case TSTRUCT:
+		for _, f := range t.FieldSlice() {
+			if exportname(f.Sym.Name) || f.Embedded != 0 {
+				p.markType(f.Type)
+			}
+		}
+
+	case TFUNC:
+		// If t is the type of a function or method, then
+		// t.Nname() is its ONAME. Mark its inline body and
+		// any recursively called functions for export.
+		inlFlood(asNode(t.Nname()))
+
+		for _, f := range t.Results().FieldSlice() {
+			p.markType(f.Type)
+		}
+
+	case TINTER:
+		for _, f := range t.FieldSlice() {
+			if exportname(f.Sym.Name) {
+				p.markType(f.Type)
+			}
+		}
+	}
+}
+
 func (p *exporter) obj(sym *types.Sym) {
 	// Exported objects may be from different packages because they
 	// may be re-exported via an exported alias or as dependencies in
@@ -504,7 +590,7 @@
 			p.paramList(sig.Results(), inlineable)
 
 			var f *Func
-			if inlineable {
+			if inlineable && asNode(sym.Def).Func.ExportInline() {
 				f = asNode(sym.Def).Func
 				// TODO(gri) re-examine reexportdeplist:
 				// Because we can trivially export types
@@ -590,10 +676,28 @@
 }
 
 func isInlineable(n *Node) bool {
-	if exportInlined && n != nil && n.Func != nil && n.Func.Inl.Len() != 0 {
-		// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
-		// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
-		if Debug['l'] < 2 {
+	if exportInlined && n != nil && n.Func != nil {
+		// When lazily typechecking inlined bodies, some
+		// re-exported ones may not have been typechecked yet.
+		// Currently that can leave unresolved ONONAMEs in
+		// import-dot-ed packages in the wrong package.
+		//
+		// TODO(mdempsky): Having the ExportInline check here
+		// instead of the outer if statement means we end up
+		// exporting parameter names even for functions whose
+		// inline body won't be exported by this package. This
+		// is currently necessary because we might first
+		// import a function/method from a package where it
+		// doesn't need to be re-exported, and then from a
+		// package where it does. If this happens, we'll need
+		// the parameter names.
+		//
+		// We could initially do without the parameter names,
+		// and then fill them in when importing the inline
+		// body. But parameter names are attached to the
+		// function type, and modifying types after the fact
+		// is a little sketchy.
+		if Debug_typecheckinl == 0 && n.Func.ExportInline() {
 			typecheckinl(n)
 		}
 		return true
@@ -601,8 +705,6 @@
 	return false
 }
 
-var errorInterface *types.Type // lazily initialized
-
 func (p *exporter) typ(t *types.Type) {
 	if t == nil {
 		Fatalf("exporter: nil type")
@@ -654,19 +756,7 @@
 		p.qualifiedName(tsym)
 
 		// write underlying type
-		orig := t.Orig
-		if orig == types.Errortype {
-			// The error type is the only predeclared type which has
-			// a composite underlying type. When we encode that type,
-			// make sure to encode the underlying interface rather than
-			// the named type again. See also the comment in universe.go
-			// regarding the errortype and issue #15920.
-			if errorInterface == nil {
-				errorInterface = makeErrorInterface()
-			}
-			orig = errorInterface
-		}
-		p.typ(orig)
+		p.typ(t.Orig)
 
 		// interfaces don't have associated methods
 		if t.Orig.IsInterface() {
@@ -677,9 +767,7 @@
 		// TODO(gri) Determine if they are already sorted
 		// in which case we can drop this step.
 		var methods []*types.Field
-		for _, m := range t.Methods().Slice() {
-			methods = append(methods, m)
-		}
+		methods = append(methods, t.Methods().Slice()...)
 		sort.Sort(methodbyname(methods))
 		p.int(len(methods))
 
@@ -708,7 +796,7 @@
 			p.bool(m.Nointerface()) // record go:nointerface pragma value (see also #16243)
 
 			var f *Func
-			if inlineable {
+			if inlineable && mfn.Func.ExportInline() {
 				f = mfn.Func
 				reexportdeplist(mfn.Func.Inl)
 			}
@@ -968,18 +1056,17 @@
 	// Take the name from the original, lest we substituted it with ~r%d or ~b%d.
 	// ~r%d is a (formerly) unnamed result.
 	if asNode(f.Nname) != nil {
-		if asNode(f.Nname).Orig != nil {
-			s = asNode(f.Nname).Orig.Sym
-			if s != nil && s.Name[0] == '~' {
-				if s.Name[1] == 'r' { // originally an unnamed result
-					return "" // s = nil
-				} else if s.Name[1] == 'b' { // originally the blank identifier _
-					return "_" // belongs to localpkg
-				}
-			}
-		} else {
+		if asNode(f.Nname).Orig == nil {
 			return "" // s = nil
 		}
+		s = asNode(f.Nname).Orig.Sym
+		if s != nil && s.Name[0] == '~' {
+			if s.Name[1] == 'r' { // originally an unnamed result
+				return "" // s = nil
+			} else if s.Name[1] == 'b' { // originally the blank identifier _
+				return "_" // belongs to localpkg
+			}
+		}
 	}
 
 	if s == nil {
@@ -1204,26 +1291,10 @@
 		p.value(n.Val())
 
 	case ONAME:
-		// Special case: name used as local variable in export.
-		// _ becomes ~b%d internally; print as _ for export
-		if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
-			p.op(ONAME)
-			p.pos(n)
-			p.string("_") // inlined and customized version of p.sym(n)
-			break
-		}
-
-		if n.Sym != nil && !isblank(n) && n.Name.Vargen > 0 {
-			p.op(ONAME)
-			p.pos(n)
-			p.sym(n)
-			break
-		}
-
 		// 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.
 		// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
-		if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
+		if n.isMethodExpression() {
 			p.op(OXDOT)
 			p.pos(n)
 			p.expr(n.Left) // n.Left.Op == OTYPE
@@ -1241,11 +1312,7 @@
 	case OTYPE:
 		p.op(OTYPE)
 		p.pos(n)
-		if p.bool(n.Type == nil) {
-			p.sym(n)
-		} else {
-			p.typ(n.Type)
-		}
+		p.typ(n.Type)
 
 	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
 	// 	should have been resolved by typechecking - handled by default case
@@ -1345,7 +1412,7 @@
 		if op == OAPPEND {
 			p.bool(n.Isddd())
 		} else if n.Isddd() {
-			Fatalf("exporter: unexpected '...' with %s call", opnames[op])
+			Fatalf("exporter: unexpected '...' with %v call", op)
 		}
 
 	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
@@ -1520,8 +1587,8 @@
 		p.stmtList(n.List)
 		p.stmtList(n.Nbody)
 
-	case OFALL, OXFALL:
-		p.op(OXFALL)
+	case OFALL:
+		p.op(OFALL)
 		p.pos(n)
 
 	case OBREAK, OCONTINUE:
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 2962962..71d20ec 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -187,7 +187,8 @@
 		// them only for functions with inlineable bodies. funchdr does
 		// parameter renaming which doesn't matter if we don't have a body.
 
-		if f := p.funcList[i]; f != nil {
+		inlCost := p.int()
+		if f := p.funcList[i]; f != nil && f.Func.Inl.Len() == 0 {
 			// function not yet imported - read body and set it
 			funchdr(f)
 			body := p.stmtList()
@@ -200,7 +201,15 @@
 				body = []*Node{nod(OEMPTY, nil, nil)}
 			}
 			f.Func.Inl.Set(body)
-			funcbody(f)
+			f.Func.InlCost = int32(inlCost)
+			if Debug['E'] > 0 && Debug['m'] > 2 && f.Func.Inl.Len() != 0 {
+				if Debug['m'] > 3 {
+					fmt.Printf("inl body for %v: %+v\n", f, f.Func.Inl)
+				} else {
+					fmt.Printf("inl body for %v: %v\n", f, f.Func.Inl)
+				}
+			}
+			funcbody()
 		} else {
 			// function already imported - read body but discard declarations
 			dclcontext = PDISCARD // throw away any declarations
@@ -326,55 +335,59 @@
 func (p *importer) obj(tag int) {
 	switch tag {
 	case constTag:
-		p.pos()
+		pos := p.pos()
 		sym := p.qualifiedName()
 		typ := p.typ()
 		val := p.value(typ)
-		importconst(p.imp, sym, idealType(typ), nodlit(val))
+		importconst(p.imp, sym, idealType(typ), npos(pos, nodlit(val)))
 
 	case aliasTag:
-		p.pos()
+		pos := p.pos()
 		sym := p.qualifiedName()
 		typ := p.typ()
-		importalias(p.imp, sym, typ)
+		importalias(pos, p.imp, sym, typ)
 
 	case typeTag:
 		p.typ()
 
 	case varTag:
-		p.pos()
+		pos := p.pos()
 		sym := p.qualifiedName()
 		typ := p.typ()
-		importvar(p.imp, sym, typ)
+		importvar(pos, p.imp, sym, typ)
 
 	case funcTag:
-		p.pos()
+		pos := p.pos()
 		sym := p.qualifiedName()
 		params := p.paramList()
 		result := p.paramList()
 
 		sig := functypefield(nil, params, result)
 		importsym(p.imp, sym, ONAME)
-		if asNode(sym.Def) != nil && asNode(sym.Def).Op == ONAME {
+		if old := asNode(sym.Def); old != nil && old.Op == ONAME {
 			// function was imported before (via another import)
-			if !eqtype(sig, asNode(sym.Def).Type) {
-				p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, asNode(sym.Def).Type, sig)
+			if !eqtype(sig, old.Type) {
+				p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, old.Type, sig)
 			}
-			p.funcList = append(p.funcList, nil)
+			n := asNode(old.Type.Nname())
+			p.funcList = append(p.funcList, n)
 			break
 		}
 
-		n := newfuncname(sym)
+		n := newfuncnamel(pos, sym)
 		n.Type = sig
+		// TODO(mdempsky): Stop clobbering n.Pos in declare.
+		savedlineno := lineno
+		lineno = pos
 		declare(n, PFUNC)
+		lineno = savedlineno
 		p.funcList = append(p.funcList, n)
 		importlist = append(importlist, n)
 
+		sig.SetNname(asTypesNode(n))
+
 		if Debug['E'] > 0 {
 			fmt.Printf("import [%q] func %v \n", p.imp.Path, n)
-			if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
-				fmt.Printf("inl body: %v\n", n.Func.Inl)
-			}
 		}
 
 	default:
@@ -479,15 +492,20 @@
 	var t *types.Type
 	switch i {
 	case namedTag:
-		p.pos()
+		pos := p.pos()
 		tsym := p.qualifiedName()
 
-		t = pkgtype(p.imp, tsym)
+		t = pkgtype(pos, p.imp, tsym)
 		p.typList = append(p.typList, t)
+		dup := !t.IsKind(types.TFORW) // type already imported
 
 		// read underlying type
 		t0 := p.typ()
+		// TODO(mdempsky): Stop clobbering n.Pos in declare.
+		savedlineno := lineno
+		lineno = pos
 		p.importtype(t, t0)
+		lineno = savedlineno
 
 		// interfaces don't have associated methods
 		if t0.IsInterface() {
@@ -501,7 +519,7 @@
 
 		// read associated methods
 		for i := p.int(); i > 0; i-- {
-			p.pos()
+			mpos := p.pos()
 			sym := p.fieldSym()
 
 			// during import unexported method names should be in the type's package
@@ -514,10 +532,21 @@
 			result := p.paramList()
 			nointerface := p.bool()
 
-			n := newfuncname(methodname(sym, recv[0].Type))
-			n.Type = functypefield(recv[0], params, result)
+			mt := functypefield(recv[0], params, result)
+			oldm := addmethod(sym, mt, false, nointerface)
+
+			if dup {
+				// An earlier import already declared this type and its methods.
+				// Discard the duplicate method declaration.
+				n := asNode(oldm.Type.Nname())
+				p.funcList = append(p.funcList, n)
+				continue
+			}
+
+			n := newfuncnamel(mpos, methodname(sym, recv[0].Type))
+			n.Type = mt
+			n.SetClass(PFUNC)
 			checkwidth(n.Type)
-			addmethod(sym, n.Type, false, nointerface)
 			p.funcList = append(p.funcList, n)
 			importlist = append(importlist, n)
 
@@ -526,13 +555,10 @@
 			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
 			// out by typecheck's lookdot as this $$.ttype. So by providing
 			// this back link here we avoid special casing there.
-			n.Type.FuncType().Nname = asTypesNode(n)
+			mt.SetNname(asTypesNode(n))
 
 			if Debug['E'] > 0 {
 				fmt.Printf("import [%q] meth %v \n", p.imp.Path, n)
-				if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
-					fmt.Printf("inl body: %v\n", n.Func.Inl)
-				}
 			}
 		}
 
@@ -616,7 +642,7 @@
 }
 
 func (p *importer) field() *types.Field {
-	p.pos()
+	pos := p.pos()
 	sym, alias := p.fieldName()
 	typ := p.typ()
 	note := p.string()
@@ -636,7 +662,7 @@
 	}
 
 	f.Sym = sym
-	f.Nname = asTypesNode(newname(sym))
+	f.Nname = asTypesNode(newnamel(pos, sym))
 	f.Type = typ
 	f.Note = note
 
@@ -660,14 +686,14 @@
 }
 
 func (p *importer) method() *types.Field {
-	p.pos()
+	pos := p.pos()
 	sym := p.methodName()
 	params := p.paramList()
 	result := p.paramList()
 
 	f := types.NewField()
 	f.Sym = sym
-	f.Nname = asTypesNode(newname(sym))
+	f.Nname = asTypesNode(newnamel(pos, sym))
 	f.Type = functypefield(fakeRecvField(), params, result)
 	return f
 }
@@ -922,10 +948,10 @@
 			// again. Re-introduce explicit uintptr(c) conversion.
 			// (issue 16317).
 			if typ.IsUnsafePtr() {
-				n = nod(OCONV, n, nil)
+				n = nodl(pos, OCONV, n, nil)
 				n.Type = types.Types[TUINTPTR]
 			}
-			n = nod(OCONV, n, nil)
+			n = nodl(pos, OCONV, n, nil)
 			n.Type = typ
 		}
 		return n
@@ -937,11 +963,7 @@
 	// 	unreachable - should have been resolved by typechecking
 
 	case OTYPE:
-		pos := p.pos()
-		if p.bool() {
-			return npos(pos, mkname(p.sym()))
-		}
-		return npos(pos, typenod(p.typ()))
+		return npos(p.pos(), typenod(p.typ()))
 
 	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
 	//      unreachable - should have been resolved by typechecking
@@ -950,21 +972,26 @@
 	//	unimplemented
 
 	case OPTRLIT:
-		n := npos(p.pos(), p.expr())
+		pos := p.pos()
+		n := npos(pos, p.expr())
 		if !p.bool() /* !implicit, i.e. '&' operator */ {
 			if n.Op == OCOMPLIT {
 				// Special case for &T{...}: turn into (*T){...}.
-				n.Right = nod(OIND, n.Right, nil)
+				n.Right = nodl(pos, OIND, n.Right, nil)
 				n.Right.SetImplicit(true)
 			} else {
-				n = nod(OADDR, n, nil)
+				n = nodl(pos, OADDR, n, nil)
 			}
 		}
 		return n
 
 	case OSTRUCTLIT:
-		n := nodl(p.pos(), OCOMPLIT, nil, typenod(p.typ()))
+		// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
+		savedlineno := lineno
+		lineno = p.pos()
+		n := nodl(lineno, OCOMPLIT, nil, typenod(p.typ()))
 		n.List.Set(p.elemList()) // special handling of field names
+		lineno = savedlineno
 		return n
 
 	// case OARRAYLIT, OSLICELIT, OMAPLIT:
@@ -1128,62 +1155,50 @@
 		return nodl(p.pos(), op, p.expr(), nil)
 
 	case OIF:
-		types.Markdcl()
 		n := nodl(p.pos(), OIF, nil, nil)
 		n.Ninit.Set(p.stmtList())
 		n.Left = p.expr()
 		n.Nbody.Set(p.stmtList())
 		n.Rlist.Set(p.stmtList())
-		types.Popdcl()
 		return n
 
 	case OFOR:
-		types.Markdcl()
 		n := nodl(p.pos(), OFOR, nil, nil)
 		n.Ninit.Set(p.stmtList())
 		n.Left, n.Right = p.exprsOrNil()
 		n.Nbody.Set(p.stmtList())
-		types.Popdcl()
 		return n
 
 	case ORANGE:
-		types.Markdcl()
 		n := nodl(p.pos(), ORANGE, nil, nil)
 		n.List.Set(p.stmtList())
 		n.Right = p.expr()
 		n.Nbody.Set(p.stmtList())
-		types.Popdcl()
 		return n
 
 	case OSELECT, OSWITCH:
-		types.Markdcl()
 		n := nodl(p.pos(), op, nil, nil)
 		n.Ninit.Set(p.stmtList())
 		n.Left, _ = p.exprsOrNil()
 		n.List.Set(p.stmtList())
-		types.Popdcl()
 		return n
 
 	// case OCASE, OXCASE:
 	// 	unreachable - mapped to OXCASE case below by exporter
 
 	case OXCASE:
-		types.Markdcl()
 		n := nodl(p.pos(), OXCASE, nil, nil)
-		n.Xoffset = int64(types.Block)
 		n.List.Set(p.exprList())
 		// TODO(gri) eventually we must declare variables for type switch
 		// statements (type switch statements are not yet exported)
 		n.Nbody.Set(p.stmtList())
-		types.Popdcl()
 		return n
 
 	// case OFALL:
 	// 	unreachable - mapped to OXFALL case below by exporter
 
-	case OXFALL:
-		n := nodl(p.pos(), OXFALL, nil, nil)
-		n.Xoffset = int64(types.Block)
+	case OFALL:
+		n := nodl(p.pos(), OFALL, nil, nil)
 		return n
 
 	case OBREAK, OCONTINUE:
diff --git a/src/cmd/compile/internal/gc/bitset.go b/src/cmd/compile/internal/gc/bitset.go
index 90babd5..ed5eea0 100644
--- a/src/cmd/compile/internal/gc/bitset.go
+++ b/src/cmd/compile/internal/gc/bitset.go
@@ -14,6 +14,16 @@
 	}
 }
 
+type bitset16 uint16
+
+func (f *bitset16) set(mask uint16, b bool) {
+	if b {
+		*(*uint16)(f) |= mask
+	} else {
+		*(*uint16)(f) &^= mask
+	}
+}
+
 type bitset32 uint32
 
 func (f *bitset32) set(mask uint32, b bool) {
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index f21a4da..0733a46 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -39,116 +39,122 @@
 	{"concatstring5", funcTag, 29},
 	{"concatstrings", funcTag, 31},
 	{"cmpstring", funcTag, 33},
-	{"eqstring", funcTag, 34},
-	{"intstring", funcTag, 37},
-	{"slicebytetostring", funcTag, 39},
-	{"slicebytetostringtmp", funcTag, 40},
-	{"slicerunetostring", funcTag, 43},
-	{"stringtoslicebyte", funcTag, 44},
-	{"stringtoslicerune", funcTag, 47},
-	{"decoderune", funcTag, 48},
-	{"slicecopy", funcTag, 50},
-	{"slicestringcopy", funcTag, 51},
-	{"convI2I", funcTag, 52},
-	{"convT2E", funcTag, 53},
-	{"convT2E16", funcTag, 53},
-	{"convT2E32", funcTag, 53},
-	{"convT2E64", funcTag, 53},
-	{"convT2Estring", funcTag, 53},
-	{"convT2Eslice", funcTag, 53},
-	{"convT2Enoptr", funcTag, 53},
-	{"convT2I", funcTag, 53},
-	{"convT2I16", funcTag, 53},
-	{"convT2I32", funcTag, 53},
-	{"convT2I64", funcTag, 53},
-	{"convT2Istring", funcTag, 53},
-	{"convT2Islice", funcTag, 53},
-	{"convT2Inoptr", funcTag, 53},
-	{"assertE2I", funcTag, 52},
-	{"assertE2I2", funcTag, 54},
-	{"assertI2I", funcTag, 52},
-	{"assertI2I2", funcTag, 54},
-	{"panicdottypeE", funcTag, 55},
-	{"panicdottypeI", funcTag, 55},
-	{"panicnildottype", funcTag, 56},
-	{"ifaceeq", funcTag, 59},
-	{"efaceeq", funcTag, 59},
-	{"makemap", funcTag, 61},
-	{"mapaccess1", funcTag, 62},
-	{"mapaccess1_fast32", funcTag, 63},
-	{"mapaccess1_fast64", funcTag, 63},
-	{"mapaccess1_faststr", funcTag, 63},
-	{"mapaccess1_fat", funcTag, 64},
-	{"mapaccess2", funcTag, 65},
-	{"mapaccess2_fast32", funcTag, 66},
-	{"mapaccess2_fast64", funcTag, 66},
-	{"mapaccess2_faststr", funcTag, 66},
-	{"mapaccess2_fat", funcTag, 67},
-	{"mapassign", funcTag, 62},
-	{"mapassign_fast32", funcTag, 63},
-	{"mapassign_fast64", funcTag, 63},
-	{"mapassign_faststr", funcTag, 63},
-	{"mapiterinit", funcTag, 68},
-	{"mapdelete", funcTag, 68},
-	{"mapdelete_fast32", funcTag, 69},
-	{"mapdelete_fast64", funcTag, 69},
-	{"mapdelete_faststr", funcTag, 69},
-	{"mapiternext", funcTag, 70},
-	{"makechan", funcTag, 72},
-	{"chanrecv1", funcTag, 74},
-	{"chanrecv2", funcTag, 75},
-	{"chansend1", funcTag, 77},
+	{"intstring", funcTag, 36},
+	{"slicebytetostring", funcTag, 38},
+	{"slicebytetostringtmp", funcTag, 39},
+	{"slicerunetostring", funcTag, 42},
+	{"stringtoslicebyte", funcTag, 43},
+	{"stringtoslicerune", funcTag, 46},
+	{"decoderune", funcTag, 47},
+	{"slicecopy", funcTag, 49},
+	{"slicestringcopy", funcTag, 50},
+	{"convI2I", funcTag, 51},
+	{"convT2E", funcTag, 52},
+	{"convT2E16", funcTag, 52},
+	{"convT2E32", funcTag, 52},
+	{"convT2E64", funcTag, 52},
+	{"convT2Estring", funcTag, 52},
+	{"convT2Eslice", funcTag, 52},
+	{"convT2Enoptr", funcTag, 52},
+	{"convT2I", funcTag, 52},
+	{"convT2I16", funcTag, 52},
+	{"convT2I32", funcTag, 52},
+	{"convT2I64", funcTag, 52},
+	{"convT2Istring", funcTag, 52},
+	{"convT2Islice", funcTag, 52},
+	{"convT2Inoptr", funcTag, 52},
+	{"assertE2I", funcTag, 51},
+	{"assertE2I2", funcTag, 53},
+	{"assertI2I", funcTag, 51},
+	{"assertI2I2", funcTag, 53},
+	{"panicdottypeE", funcTag, 54},
+	{"panicdottypeI", funcTag, 54},
+	{"panicnildottype", funcTag, 55},
+	{"ifaceeq", funcTag, 58},
+	{"efaceeq", funcTag, 58},
+	{"fastrand", funcTag, 60},
+	{"makemap64", funcTag, 62},
+	{"makemap", funcTag, 63},
+	{"makemap_small", funcTag, 64},
+	{"mapaccess1", funcTag, 65},
+	{"mapaccess1_fast32", funcTag, 66},
+	{"mapaccess1_fast64", funcTag, 66},
+	{"mapaccess1_faststr", funcTag, 66},
+	{"mapaccess1_fat", funcTag, 67},
+	{"mapaccess2", funcTag, 68},
+	{"mapaccess2_fast32", funcTag, 69},
+	{"mapaccess2_fast64", funcTag, 69},
+	{"mapaccess2_faststr", funcTag, 69},
+	{"mapaccess2_fat", funcTag, 70},
+	{"mapassign", funcTag, 65},
+	{"mapassign_fast32", funcTag, 66},
+	{"mapassign_fast32ptr", funcTag, 66},
+	{"mapassign_fast64", funcTag, 66},
+	{"mapassign_fast64ptr", funcTag, 66},
+	{"mapassign_faststr", funcTag, 66},
+	{"mapiterinit", funcTag, 71},
+	{"mapdelete", funcTag, 71},
+	{"mapdelete_fast32", funcTag, 72},
+	{"mapdelete_fast64", funcTag, 72},
+	{"mapdelete_faststr", funcTag, 72},
+	{"mapiternext", funcTag, 73},
+	{"makechan64", funcTag, 75},
+	{"makechan", funcTag, 76},
+	{"chanrecv1", funcTag, 78},
+	{"chanrecv2", funcTag, 79},
+	{"chansend1", funcTag, 81},
 	{"closechan", funcTag, 23},
-	{"writeBarrier", varTag, 79},
-	{"writebarrierptr", funcTag, 80},
-	{"typedmemmove", funcTag, 81},
-	{"typedmemclr", funcTag, 82},
-	{"typedslicecopy", funcTag, 83},
-	{"selectnbsend", funcTag, 84},
-	{"selectnbrecv", funcTag, 85},
-	{"selectnbrecv2", funcTag, 87},
-	{"newselect", funcTag, 88},
-	{"selectsend", funcTag, 89},
-	{"selectrecv", funcTag, 90},
-	{"selectdefault", funcTag, 56},
-	{"selectgo", funcTag, 91},
+	{"writeBarrier", varTag, 83},
+	{"writebarrierptr", funcTag, 84},
+	{"typedmemmove", funcTag, 85},
+	{"typedmemclr", funcTag, 86},
+	{"typedslicecopy", funcTag, 87},
+	{"selectnbsend", funcTag, 88},
+	{"selectnbrecv", funcTag, 89},
+	{"selectnbrecv2", funcTag, 91},
+	{"newselect", funcTag, 92},
+	{"selectsend", funcTag, 93},
+	{"selectrecv", funcTag, 94},
+	{"selectdefault", funcTag, 55},
+	{"selectgo", funcTag, 95},
 	{"block", funcTag, 5},
-	{"makeslice", funcTag, 93},
-	{"makeslice64", funcTag, 94},
-	{"growslice", funcTag, 95},
-	{"memmove", funcTag, 96},
-	{"memclrNoHeapPointers", funcTag, 97},
-	{"memclrHasPointers", funcTag, 97},
-	{"memequal", funcTag, 98},
-	{"memequal8", funcTag, 99},
-	{"memequal16", funcTag, 99},
-	{"memequal32", funcTag, 99},
-	{"memequal64", funcTag, 99},
-	{"memequal128", funcTag, 99},
-	{"int64div", funcTag, 100},
-	{"uint64div", funcTag, 101},
-	{"int64mod", funcTag, 100},
-	{"uint64mod", funcTag, 101},
-	{"float64toint64", funcTag, 102},
-	{"float64touint64", funcTag, 103},
-	{"float64touint32", funcTag, 105},
-	{"int64tofloat64", funcTag, 106},
-	{"uint64tofloat64", funcTag, 107},
-	{"uint32tofloat64", funcTag, 108},
-	{"complex128div", funcTag, 109},
-	{"racefuncenter", funcTag, 110},
+	{"makeslice", funcTag, 97},
+	{"makeslice64", funcTag, 98},
+	{"growslice", funcTag, 99},
+	{"memmove", funcTag, 100},
+	{"memclrNoHeapPointers", funcTag, 101},
+	{"memclrHasPointers", funcTag, 101},
+	{"memequal", funcTag, 102},
+	{"memequal8", funcTag, 103},
+	{"memequal16", funcTag, 103},
+	{"memequal32", funcTag, 103},
+	{"memequal64", funcTag, 103},
+	{"memequal128", funcTag, 103},
+	{"int64div", funcTag, 104},
+	{"uint64div", funcTag, 105},
+	{"int64mod", funcTag, 104},
+	{"uint64mod", funcTag, 105},
+	{"float64toint64", funcTag, 106},
+	{"float64touint64", funcTag, 107},
+	{"float64touint32", funcTag, 108},
+	{"int64tofloat64", funcTag, 109},
+	{"uint64tofloat64", funcTag, 110},
+	{"uint32tofloat64", funcTag, 111},
+	{"complex128div", funcTag, 112},
+	{"racefuncenter", funcTag, 113},
 	{"racefuncexit", funcTag, 5},
-	{"raceread", funcTag, 110},
-	{"racewrite", funcTag, 110},
-	{"racereadrange", funcTag, 111},
-	{"racewriterange", funcTag, 111},
-	{"msanread", funcTag, 111},
-	{"msanwrite", funcTag, 111},
+	{"raceread", funcTag, 113},
+	{"racewrite", funcTag, 113},
+	{"racereadrange", funcTag, 114},
+	{"racewriterange", funcTag, 114},
+	{"msanread", funcTag, 114},
+	{"msanwrite", funcTag, 114},
 	{"support_popcnt", varTag, 11},
+	{"support_sse41", varTag, 11},
 }
 
 func runtimeTypes() []*types.Type {
-	var typs [112]*types.Type
+	var typs [115]*types.Type
 	typs[0] = types.Bytetype
 	typs[1] = types.NewPtr(typs[0])
 	typs[2] = types.Types[TANY]
@@ -183,83 +189,86 @@
 	typs[31] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[30])}, []*Node{anonfield(typs[21])})
 	typs[32] = types.Types[TINT]
 	typs[33] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[32])})
-	typs[34] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[11])})
-	typs[35] = types.NewArray(typs[0], 4)
-	typs[36] = types.NewPtr(typs[35])
-	typs[37] = functype(nil, []*Node{anonfield(typs[36]), anonfield(typs[15])}, []*Node{anonfield(typs[21])})
-	typs[38] = types.NewSlice(typs[0])
-	typs[39] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[38])}, []*Node{anonfield(typs[21])})
-	typs[40] = functype(nil, []*Node{anonfield(typs[38])}, []*Node{anonfield(typs[21])})
-	typs[41] = types.Runetype
-	typs[42] = types.NewSlice(typs[41])
-	typs[43] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[42])}, []*Node{anonfield(typs[21])})
-	typs[44] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21])}, []*Node{anonfield(typs[38])})
-	typs[45] = types.NewArray(typs[41], 32)
-	typs[46] = types.NewPtr(typs[45])
-	typs[47] = functype(nil, []*Node{anonfield(typs[46]), anonfield(typs[21])}, []*Node{anonfield(typs[42])})
-	typs[48] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[32])}, []*Node{anonfield(typs[41]), anonfield(typs[32])})
-	typs[49] = types.Types[TUINTPTR]
-	typs[50] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[49])}, []*Node{anonfield(typs[32])})
-	typs[51] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
-	typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
-	typs[53] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
-	typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[11])})
-	typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
-	typs[56] = functype(nil, []*Node{anonfield(typs[1])}, nil)
-	typs[57] = types.NewPtr(typs[49])
-	typs[58] = types.Types[TUNSAFEPTR]
-	typs[59] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[58]), anonfield(typs[58])}, []*Node{anonfield(typs[11])})
-	typs[60] = types.NewMap(typs[2], typs[2])
-	typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[60])})
-	typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
-	typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
-	typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-	typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-	typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-	typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-	typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, nil)
-	typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, nil)
-	typs[70] = functype(nil, []*Node{anonfield(typs[3])}, nil)
-	typs[71] = types.NewChan(typs[2], types.Cboth)
-	typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[71])})
-	typs[73] = types.NewChan(typs[2], types.Crecv)
-	typs[74] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, nil)
-	typs[75] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-	typs[76] = types.NewChan(typs[2], types.Csend)
-	typs[77] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, nil)
-	typs[78] = types.NewArray(typs[0], 3)
-	typs[79] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[78]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
-	typs[80] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
-	typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
-	typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
-	typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
-	typs[84] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-	typs[85] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[73])}, []*Node{anonfield(typs[11])})
-	typs[86] = types.NewPtr(typs[11])
-	typs[87] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[86]), anonfield(typs[73])}, []*Node{anonfield(typs[11])})
-	typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil)
-	typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[76]), anonfield(typs[3])}, nil)
-	typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3]), anonfield(typs[86])}, nil)
-	typs[91] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
-	typs[92] = types.NewSlice(typs[2])
-	typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[92])})
-	typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[92])})
-	typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[92]), anonfield(typs[32])}, []*Node{anonfield(typs[92])})
-	typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, nil)
-	typs[97] = functype(nil, []*Node{anonfield(typs[58]), anonfield(typs[49])}, nil)
-	typs[98] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, []*Node{anonfield(typs[11])})
-	typs[99] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-	typs[100] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
-	typs[101] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
-	typs[102] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
-	typs[103] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
-	typs[104] = types.Types[TUINT32]
-	typs[105] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[104])})
-	typs[106] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
-	typs[107] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
-	typs[108] = functype(nil, []*Node{anonfield(typs[104])}, []*Node{anonfield(typs[13])})
-	typs[109] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
-	typs[110] = functype(nil, []*Node{anonfield(typs[49])}, nil)
-	typs[111] = functype(nil, []*Node{anonfield(typs[49]), anonfield(typs[49])}, nil)
+	typs[34] = types.NewArray(typs[0], 4)
+	typs[35] = types.NewPtr(typs[34])
+	typs[36] = functype(nil, []*Node{anonfield(typs[35]), anonfield(typs[15])}, []*Node{anonfield(typs[21])})
+	typs[37] = types.NewSlice(typs[0])
+	typs[38] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[37])}, []*Node{anonfield(typs[21])})
+	typs[39] = functype(nil, []*Node{anonfield(typs[37])}, []*Node{anonfield(typs[21])})
+	typs[40] = types.Runetype
+	typs[41] = types.NewSlice(typs[40])
+	typs[42] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[41])}, []*Node{anonfield(typs[21])})
+	typs[43] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21])}, []*Node{anonfield(typs[37])})
+	typs[44] = types.NewArray(typs[40], 32)
+	typs[45] = types.NewPtr(typs[44])
+	typs[46] = functype(nil, []*Node{anonfield(typs[45]), anonfield(typs[21])}, []*Node{anonfield(typs[41])})
+	typs[47] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[32])}, []*Node{anonfield(typs[40]), anonfield(typs[32])})
+	typs[48] = types.Types[TUINTPTR]
+	typs[49] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[48])}, []*Node{anonfield(typs[32])})
+	typs[50] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
+	typs[51] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
+	typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
+	typs[53] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[11])})
+	typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+	typs[55] = functype(nil, []*Node{anonfield(typs[1])}, nil)
+	typs[56] = types.NewPtr(typs[48])
+	typs[57] = types.Types[TUNSAFEPTR]
+	typs[58] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[57]), anonfield(typs[57])}, []*Node{anonfield(typs[11])})
+	typs[59] = types.Types[TUINT32]
+	typs[60] = functype(nil, nil, []*Node{anonfield(typs[59])})
+	typs[61] = types.NewMap(typs[2], typs[2])
+	typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[61])})
+	typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[3])}, []*Node{anonfield(typs[61])})
+	typs[64] = functype(nil, nil, []*Node{anonfield(typs[61])})
+	typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
+	typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
+	typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
+	typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+	typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+	typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+	typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, nil)
+	typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[2])}, nil)
+	typs[73] = functype(nil, []*Node{anonfield(typs[3])}, nil)
+	typs[74] = types.NewChan(typs[2], types.Cboth)
+	typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[74])})
+	typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[74])})
+	typs[77] = types.NewChan(typs[2], types.Crecv)
+	typs[78] = functype(nil, []*Node{anonfield(typs[77]), anonfield(typs[3])}, nil)
+	typs[79] = functype(nil, []*Node{anonfield(typs[77]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+	typs[80] = types.NewChan(typs[2], types.Csend)
+	typs[81] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, nil)
+	typs[82] = types.NewArray(typs[0], 3)
+	typs[83] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[82]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
+	typs[84] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
+	typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+	typs[86] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
+	typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
+	typs[88] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+	typs[89] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[77])}, []*Node{anonfield(typs[11])})
+	typs[90] = types.NewPtr(typs[11])
+	typs[91] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[90]), anonfield(typs[77])}, []*Node{anonfield(typs[11])})
+	typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil)
+	typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[80]), anonfield(typs[3])}, nil)
+	typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[77]), anonfield(typs[3]), anonfield(typs[90])}, nil)
+	typs[95] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
+	typs[96] = types.NewSlice(typs[2])
+	typs[97] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[96])})
+	typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[96])})
+	typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[96]), anonfield(typs[32])}, []*Node{anonfield(typs[96])})
+	typs[100] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, nil)
+	typs[101] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[48])}, nil)
+	typs[102] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, []*Node{anonfield(typs[11])})
+	typs[103] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+	typs[104] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
+	typs[105] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
+	typs[106] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
+	typs[107] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
+	typs[108] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[59])})
+	typs[109] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
+	typs[110] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
+	typs[111] = functype(nil, []*Node{anonfield(typs[59])}, []*Node{anonfield(typs[13])})
+	typs[112] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
+	typs[113] = functype(nil, []*Node{anonfield(typs[48])}, nil)
+	typs[114] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[48])}, nil)
 	return typs[:]
 }
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index 7f4846d..de17d51 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -48,7 +48,6 @@
 func concatstrings(*[32]byte, []string) string
 
 func cmpstring(string, string) int
-func eqstring(string, string) bool
 func intstring(*[4]byte, int64) string
 func slicebytetostring(*[32]byte, []byte) string
 func slicebytetostringtmp([]byte) string
@@ -78,7 +77,7 @@
 func convT2Islice(tab *byte, elem *any) (ret any)
 func convT2Inoptr(tab *byte, elem *any) (ret any)
 
-// interface type assertions  x.(T)
+// interface type assertions x.(T)
 func assertE2I(typ *byte, iface any) (ret any)
 func assertE2I2(typ *byte, iface any) (ret any, b bool)
 func assertI2I(typ *byte, iface any) (ret any)
@@ -92,8 +91,12 @@
 func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
 func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
 
+func fastrand() uint32
+
 // *byte is really *runtime.Type
-func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
+func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
+func makemap_small() (hmap map[any]any)
 func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
 func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
 func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
@@ -106,7 +109,9 @@
 func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
 func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
 func mapassign_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
+func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key any) (val *any)
 func mapassign_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
+func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key any) (val *any)
 func mapassign_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
 func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
 func mapdelete(mapType *byte, hmap map[any]any, key *any)
@@ -116,7 +121,8 @@
 func mapiternext(hiter *any)
 
 // *byte is really *runtime.Type
-func makechan(chanType *byte, hint int64) (hchan chan any)
+func makechan64(chanType *byte, size int64) (hchan chan any)
+func makechan(chanType *byte, size int) (hchan chan any)
 func chanrecv1(hchan <-chan any, elem *any)
 func chanrecv2(hchan <-chan any, elem *any) bool
 func chansend1(hchan chan<- any, elem *any)
@@ -190,3 +196,4 @@
 
 // architecture variants
 var support_popcnt bool
+var support_sse41 bool
diff --git a/src/cmd/compile/internal/gc/bv.go b/src/cmd/compile/internal/gc/bv.go
index 72f29e8..03c4b9d 100644
--- a/src/cmd/compile/internal/gc/bv.go
+++ b/src/cmd/compile/internal/gc/bv.go
@@ -5,9 +5,9 @@
 package gc
 
 const (
-	WORDBITS  = 32
-	WORDMASK  = WORDBITS - 1
-	WORDSHIFT = 5
+	wordBits  = 32
+	wordMask  = wordBits - 1
+	wordShift = 5
 )
 
 // A bvec is a bit vector.
@@ -17,7 +17,7 @@
 }
 
 func bvalloc(n int32) bvec {
-	nword := (n + WORDBITS - 1) / WORDBITS
+	nword := (n + wordBits - 1) / wordBits
 	return bvec{n, make([]uint32, nword)}
 }
 
@@ -28,7 +28,7 @@
 }
 
 func bvbulkalloc(nbit int32, count int32) bulkBvec {
-	nword := (nbit + WORDBITS - 1) / WORDBITS
+	nword := (nbit + wordBits - 1) / wordBits
 	size := int64(nword) * int64(count)
 	if int64(int32(size*4)) != size*4 {
 		Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
@@ -66,24 +66,24 @@
 	if i < 0 || i >= bv.n {
 		Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
 	}
-	mask := uint32(1 << uint(i%WORDBITS))
-	return bv.b[i>>WORDSHIFT]&mask != 0
+	mask := uint32(1 << uint(i%wordBits))
+	return bv.b[i>>wordShift]&mask != 0
 }
 
 func (bv bvec) Set(i int32) {
 	if i < 0 || i >= bv.n {
 		Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
 	}
-	mask := uint32(1 << uint(i%WORDBITS))
-	bv.b[i/WORDBITS] |= mask
+	mask := uint32(1 << uint(i%wordBits))
+	bv.b[i/wordBits] |= mask
 }
 
 func (bv bvec) Unset(i int32) {
 	if i < 0 || i >= bv.n {
 		Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n)
 	}
-	mask := uint32(1 << uint(i%WORDBITS))
-	bv.b[i/WORDBITS] &^= mask
+	mask := uint32(1 << uint(i%wordBits))
+	bv.b[i/wordBits] &^= mask
 }
 
 // bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
@@ -94,11 +94,11 @@
 	}
 
 	// Jump i ahead to next word with bits.
-	if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
-		i &^= WORDMASK
-		i += WORDBITS
-		for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
-			i += WORDBITS
+	if bv.b[i>>wordShift]>>uint(i&wordMask) == 0 {
+		i &^= wordMask
+		i += wordBits
+		for i < bv.n && bv.b[i>>wordShift] == 0 {
+			i += wordBits
 		}
 	}
 
@@ -107,7 +107,7 @@
 	}
 
 	// Find 1 bit.
-	w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
+	w := bv.b[i>>wordShift] >> uint(i&wordMask)
 
 	for w&1 == 0 {
 		w >>= 1
@@ -118,8 +118,8 @@
 }
 
 func (bv bvec) IsEmpty() bool {
-	for i := int32(0); i < bv.n; i += WORDBITS {
-		if bv.b[i>>WORDSHIFT] != 0 {
+	for i := int32(0); i < bv.n; i += wordBits {
+		if bv.b[i>>wordShift] != 0 {
 			return false
 		}
 	}
@@ -129,7 +129,7 @@
 func (bv bvec) Not() {
 	i := int32(0)
 	w := int32(0)
-	for ; i < bv.n; i, w = i+WORDBITS, w+1 {
+	for ; i < bv.n; i, w = i+wordBits, w+1 {
 		bv.b[w] = ^bv.b[w]
 	}
 }
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 143e196..d3af16e 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -19,7 +19,7 @@
 	n.Func.Depth = funcdepth
 	n.Func.Outerfunc = Curfn
 
-	old := p.funchdr(n, expr.Pos())
+	old := p.funchdr(n)
 
 	// steal ntype's argument names and
 	// leave a fresh copy in their place.
@@ -60,7 +60,7 @@
 
 	n.Nbody.Set(body)
 	n.Func.Endlineno = lineno
-	p.funcbody(n, expr.Body.Rbrace, old)
+	p.funcbody(old)
 
 	// closure-specific variables are hanging off the
 	// ordinary ones in the symbol table; see oldname.
@@ -463,9 +463,8 @@
 			Warnl(func_.Pos, "closure converted to global")
 		}
 		return func_.Func.Closure.Func.Nname
-	} else {
-		closuredebugruntimecheck(func_)
 	}
+	closuredebugruntimecheck(func_)
 
 	// Create closure in the form of a composite literal.
 	// supposing the closure captures an int i and a string s
@@ -481,28 +480,29 @@
 	// the struct is unnamed so that closures in multiple packages with the
 	// same struct type can share the descriptor.
 
-	typ := nod(OTSTRUCT, nil, nil)
-
-	typ.List.Set1(namedfield(".F", types.Types[TUINTPTR]))
+	fields := []*Node{
+		namedfield(".F", types.Types[TUINTPTR]),
+	}
 	for _, v := range func_.Func.Cvars.Slice() {
 		if v.Op == OXXX {
 			continue
 		}
-		typ1 := typenod(v.Type)
+		typ := v.Type
 		if !v.Name.Byval() {
-			typ1 = nod(OIND, typ1, nil)
+			typ = types.NewPtr(typ)
 		}
-		typ.List.Append(nod(ODCLFIELD, newname(v.Sym), typ1))
+		fields = append(fields, symfield(v.Sym, typ))
 	}
+	typ := tostruct(fields)
+	typ.SetNoalg(true)
 
-	clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil))
+	clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil))
 	clos.Esc = func_.Esc
 	clos.Right.SetImplicit(true)
 	clos.List.Set(append([]*Node{nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)}, func_.Func.Enter.Slice()...))
 
 	// Force type conversion from *struct to the func type.
 	clos = nod(OCONVNOP, clos, nil)
-
 	clos.Type = func_.Type
 
 	clos = typecheck(clos, Erv)
@@ -646,7 +646,7 @@
 	call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
 	call.List.Set(callargs)
 	call.SetIsddd(ddd)
-	if t0.Results().NumFields() == 0 {
+	if t0.NumResults() == 0 {
 		body = append(body, call)
 	} else {
 		n := nod(OAS2, nil, nil)
@@ -683,11 +683,13 @@
 		checknil(n.Left, init)
 	}
 
-	typ := nod(OTSTRUCT, nil, nil)
-	typ.List.Set1(namedfield("F", types.Types[TUINTPTR]))
-	typ.List.Append(namedfield("R", n.Left.Type))
+	typ := tostruct([]*Node{
+		namedfield("F", types.Types[TUINTPTR]),
+		namedfield("R", n.Left.Type),
+	})
+	typ.SetNoalg(true)
 
-	clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil))
+	clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil))
 	clos.Esc = n.Esc
 	clos.Right.SetImplicit(true)
 	clos.List.Set1(nod(OCFUNC, n.Func.Nname, nil))
@@ -695,7 +697,6 @@
 
 	// Force type conversion from *struct to the func type.
 	clos = nod(OCONVNOP, clos, nil)
-
 	clos.Type = n.Type
 
 	clos = typecheck(clos, Erv)
diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go
index a465d4a..dcc16b6 100644
--- a/src/cmd/compile/internal/gc/const.go
+++ b/src/cmd/compile/internal/gc/const.go
@@ -12,7 +12,7 @@
 )
 
 // Ctype describes the constant kind of an "ideal" (untyped) constant.
-type Ctype int8
+type Ctype uint8
 
 const (
 	CTxxx Ctype = iota
@@ -247,7 +247,7 @@
 
 		return n
 
-		// target is invalid type for a constant?  leave alone.
+		// target is invalid type for a constant? leave alone.
 	case OLITERAL:
 		if !okforconst[t.Etype] && n.Type.Etype != TNIL {
 			return defaultlitreuse(n, nil, reuse)
@@ -297,7 +297,7 @@
 
 	ct := consttype(n)
 	var et types.EType
-	if ct < 0 {
+	if ct == 0 {
 		goto bad
 	}
 
@@ -408,7 +408,7 @@
 bad:
 	if !n.Diag() {
 		if !t.Broke() {
-			yyerror("cannot convert %v to type %v", n, t)
+			yyerror("cannot convert %L to type %v", n, t)
 		}
 		n.SetDiag(true)
 	}
@@ -591,7 +591,7 @@
 
 func consttype(n *Node) Ctype {
 	if n == nil || n.Op != OLITERAL {
-		return -1
+		return 0
 	}
 	return n.Val().Ctype()
 }
@@ -693,7 +693,7 @@
 	if nl == nil || nl.Type == nil {
 		return
 	}
-	if consttype(nl) < 0 {
+	if consttype(nl) == 0 {
 		return
 	}
 	wl := nl.Type.Etype
@@ -840,7 +840,7 @@
 	if nr.Type == nil {
 		return
 	}
-	if consttype(nr) < 0 {
+	if consttype(nr) == 0 {
 		return
 	}
 	wr = nr.Type.Etype
@@ -1195,8 +1195,6 @@
 		goto setfalse
 	}
 
-	goto ret
-
 ret:
 	norig = saveorig(n)
 	*n = *nl
@@ -1375,7 +1373,8 @@
 			return convlit(n, t)
 		}
 
-		if n.Val().Ctype() == CTNIL {
+		switch n.Val().Ctype() {
+		case CTNIL:
 			lineno = lno
 			if !n.Diag() {
 				yyerror("use of untyped nil")
@@ -1383,17 +1382,13 @@
 			}
 
 			n.Type = nil
-			break
-		}
-
-		if n.Val().Ctype() == CTSTR {
+		case CTSTR:
 			t1 := types.Types[TSTRING]
 			n = convlit1(n, t1, false, reuse)
-			break
+		default:
+			yyerror("defaultlit: unknown literal: %v", n)
 		}
 
-		yyerror("defaultlit: unknown literal: %v", n)
-
 	case CTxxx:
 		Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
 
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
index b8a5a90..2756707 100644
--- a/src/cmd/compile/internal/gc/dcl.go
+++ b/src/cmd/compile/internal/gc/dcl.go
@@ -5,7 +5,9 @@
 package gc
 
 import (
+	"bytes"
 	"cmd/compile/internal/types"
+	"cmd/internal/obj"
 	"cmd/internal/src"
 	"fmt"
 	"strings"
@@ -83,12 +85,14 @@
 		yyerror("cannot declare name %v", s)
 	}
 
-	if ctxt == PEXTERN && s.Name == "init" {
-		yyerror("cannot declare init - must be func")
-	}
-
 	gen := 0
 	if ctxt == PEXTERN {
+		if s.Name == "init" {
+			yyerror("cannot declare init - must be func")
+		}
+		if s.Name == "main" && localpkg.Name == "main" {
+			yyerror("cannot declare main - must be func")
+		}
 		externdcl = append(externdcl, n)
 	} else {
 		if Curfn == nil && ctxt == PAUTO {
@@ -212,7 +216,13 @@
 // newfuncname generates a new name node for a function or method.
 // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
 func newfuncname(s *types.Sym) *Node {
-	n := newname(s)
+	return newfuncnamel(lineno, s)
+}
+
+// newfuncnamel generates a new name node for a function or method.
+// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
+func newfuncnamel(pos src.XPos, s *types.Sym) *Node {
+	n := newnamel(pos, s)
 	n.Func = new(Func)
 	n.Func.SetIsHiddenClosure(Curfn != nil)
 	return n
@@ -227,11 +237,15 @@
 }
 
 func typenod(t *types.Type) *Node {
+	return typenodl(src.NoXPos, t)
+}
+
+func typenodl(pos src.XPos, t *types.Type) *Node {
 	// if we copied another type with *t = *u
 	// then t->nod might be out of date, so
 	// check t->nod->type too
 	if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
-		t.Nod = asTypesNode(nod(OTYPE, nil, nil))
+		t.Nod = asTypesNode(nodl(pos, OTYPE, nil, nil))
 		asNode(t.Nod).Type = t
 		asNode(t.Nod).Sym = t.Sym
 	}
@@ -244,7 +258,11 @@
 }
 
 func namedfield(s string, typ *types.Type) *Node {
-	return nod(ODCLFIELD, newname(lookup(s)), typenod(typ))
+	return symfield(lookup(s), typ)
+}
+
+func symfield(s *types.Sym, typ *types.Type) *Node {
+	return nod(ODCLFIELD, newname(s), typenod(typ))
 }
 
 // oldname returns the Node that declares symbol s in the current scope.
@@ -519,7 +537,7 @@
 // finish the body.
 // called in auto-declaration context.
 // returns in extern-declaration context.
-func funcbody(n *Node) {
+func funcbody() {
 	// change the declaration context from auto to extern
 	if dclcontext != PAUTO {
 		Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
@@ -742,7 +760,7 @@
 	return t
 }
 
-func tointerface0(t *types.Type, l []*Node) *types.Type {
+func tointerface0(t *types.Type, l []*Node) {
 	if t == nil || !t.IsInterface() {
 		Fatalf("interface expected")
 	}
@@ -756,35 +774,6 @@
 		fields = append(fields, f)
 	}
 	t.SetInterface(fields)
-
-	return t
-}
-
-func embedded(s *types.Sym, pkg *types.Pkg) *Node {
-	const (
-		CenterDot = 0xB7
-	)
-	// Names sometimes have disambiguation junk
-	// appended after a center dot. Discard it when
-	// making the name for the embedded struct field.
-	name := s.Name
-
-	if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
-		name = s.Name[:i]
-	}
-
-	var n *Node
-	if exportname(name) {
-		n = newname(lookup(name))
-	} else if s.Pkg == builtinpkg {
-		// The name of embedded builtins belongs to pkg.
-		n = newname(pkg.Lookup(name))
-	} else {
-		n = newname(s.Pkg.Lookup(name))
-	}
-	n = nod(ODCLFIELD, n, oldname(s))
-	n.SetEmbedded(true)
-	return n
 }
 
 func fakeRecv() *Node {
@@ -949,7 +938,8 @@
 // Add a method, declared as a function.
 // - msym is the method symbol
 // - t is function type (with receiver)
-func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) {
+// Returns a pointer to the existing or added Field.
+func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
 	if msym == nil {
 		Fatalf("no method symbol")
 	}
@@ -958,7 +948,7 @@
 	rf := t.Recv() // ptr to this structure
 	if rf == nil {
 		yyerror("missing receiver")
-		return
+		return nil
 	}
 
 	mt := methtype(rf.Type)
@@ -968,7 +958,7 @@
 		if t != nil && t.IsPtr() {
 			if t.Sym != nil {
 				yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
-				return
+				return nil
 			}
 			t = t.Elem()
 		}
@@ -987,23 +977,23 @@
 			// but just in case, fall back to generic error.
 			yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
 		}
-		return
+		return nil
 	}
 
-	if local && !mt.Local() {
+	if local && mt.Sym.Pkg != localpkg {
 		yyerror("cannot define new methods on non-local type %v", mt)
-		return
+		return nil
 	}
 
 	if msym.IsBlank() {
-		return
+		return nil
 	}
 
 	if mt.IsStruct() {
 		for _, f := range mt.Fields().Slice() {
 			if f.Sym == msym {
 				yyerror("type %v has both field and method named %v", mt, msym)
-				return
+				return nil
 			}
 		}
 	}
@@ -1017,7 +1007,7 @@
 		if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
 			yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
 		}
-		return
+		return f
 	}
 
 	f := types.NewField()
@@ -1027,6 +1017,7 @@
 	f.SetNointerface(nointerface)
 
 	mt.Methods().Append(f)
+	return f
 }
 
 func funccompile(n *Node) {
@@ -1096,9 +1087,10 @@
 	if s.IsBlank() {
 		return
 	}
-	if compiling_runtime && s.Name == "getg" {
-		// runtime.getg() is not a real function and so does
-		// not get a funcsym.
+	if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
+		// runtime.getg(), getclosureptr(), getcallerpc(), and
+		// getcallersp() are not real functions and so do not
+		// get funcsyms.
 		return
 	}
 	if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
@@ -1122,123 +1114,175 @@
 }
 
 type nowritebarrierrecChecker struct {
-	curfn  *Node
-	stable bool
+	// extraCalls contains extra function calls that may not be
+	// visible during later analysis. It maps from the ODCLFUNC of
+	// the caller to a list of callees.
+	extraCalls map[*Node][]nowritebarrierrecCall
 
-	// best maps from the ODCLFUNC of each visited function that
-	// recursively invokes a write barrier to the called function
-	// on the shortest path to a write barrier.
-	best map[*Node]nowritebarrierrecCall
+	// curfn is the current function during AST walks.
+	curfn *Node
 }
 
 type nowritebarrierrecCall struct {
-	target *Node
-	depth  int
-	lineno src.XPos
+	target *Node    // ODCLFUNC of caller or callee
+	lineno src.XPos // line of call
 }
 
-func checknowritebarrierrec() {
-	c := nowritebarrierrecChecker{
-		best: make(map[*Node]nowritebarrierrecCall),
+type nowritebarrierrecCallSym struct {
+	target *obj.LSym // LSym of callee
+	lineno src.XPos  // line of call
+}
+
+// newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
+// must be called before transformclosure and walk.
+func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
+	c := &nowritebarrierrecChecker{
+		extraCalls: make(map[*Node][]nowritebarrierrecCall),
 	}
-	visitBottomUp(xtop, func(list []*Node, recursive bool) {
-		// Functions with write barriers have depth 0.
-		for _, n := range list {
-			if n.Func.WBPos.IsKnown() && n.Func.Pragma&Nowritebarrier != 0 {
-				yyerrorl(n.Func.WBPos, "write barrier prohibited")
-			}
-			if n.Func.WBPos.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 {
-				c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBPos}
-			}
+
+	// Find all systemstack calls and record their targets. In
+	// general, flow analysis can't see into systemstack, but it's
+	// important to handle it for this check, so we model it
+	// directly. This has to happen before transformclosure since
+	// it's a lot harder to work out the argument after.
+	for _, n := range xtop {
+		if n.Op != ODCLFUNC {
+			continue
 		}
-
-		// Propagate write barrier depth up from callees. In
-		// the recursive case, we have to update this at most
-		// len(list) times and can stop when we an iteration
-		// that doesn't change anything.
-		for _ = range list {
-			c.stable = false
-			for _, n := range list {
-				if n.Func.Pragma&Yeswritebarrierrec != 0 {
-					// Don't propagate write
-					// barrier up to a
-					// yeswritebarrierrec function.
-					continue
-				}
-				if !n.Func.WBPos.IsKnown() {
-					c.curfn = n
-					c.visitcodelist(n.Nbody)
-				}
-			}
-			if c.stable {
-				break
-			}
-		}
-
-		// Check nowritebarrierrec functions.
-		for _, n := range list {
-			if n.Func.Pragma&Nowritebarrierrec == 0 {
-				continue
-			}
-			call, hasWB := c.best[n]
-			if !hasWB {
-				continue
-			}
-
-			// Build the error message in reverse.
-			err := ""
-			for call.target != nil {
-				err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err)
-				n = call.target
-				call = c.best[n]
-			}
-			err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err)
-			yyerrorl(n.Func.WBPos, err)
-		}
-	})
+		c.curfn = n
+		inspect(n, c.findExtraCalls)
+	}
+	c.curfn = nil
+	return c
 }
 
-func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) {
-	for _, n := range l.Slice() {
-		c.visitcode(n)
+func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
+	if n.Op != OCALLFUNC {
+		return true
 	}
-}
-
-func (c *nowritebarrierrecChecker) visitcode(n *Node) {
-	if n == nil {
-		return
-	}
-
-	if n.Op == OCALLFUNC || n.Op == OCALLMETH {
-		c.visitcall(n)
-	}
-
-	c.visitcodelist(n.Ninit)
-	c.visitcode(n.Left)
-	c.visitcode(n.Right)
-	c.visitcodelist(n.List)
-	c.visitcodelist(n.Nbody)
-	c.visitcodelist(n.Rlist)
-}
-
-func (c *nowritebarrierrecChecker) visitcall(n *Node) {
 	fn := n.Left
-	if n.Op == OCALLMETH {
-		fn = asNode(n.Left.Sym.Def)
-	}
 	if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
-		return
+		return true
 	}
-	defn := fn.Name.Defn
+	if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
+		return true
+	}
 
-	fnbest, ok := c.best[defn]
-	if !ok {
-		return
+	var callee *Node
+	arg := n.List.First()
+	switch arg.Op {
+	case ONAME:
+		callee = arg.Name.Defn
+	case OCLOSURE:
+		callee = arg.Func.Closure
+	default:
+		Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
 	}
-	best, ok := c.best[c.curfn]
-	if ok && fnbest.depth+1 >= best.depth {
-		return
+	if callee.Op != ODCLFUNC {
+		Fatalf("expected ODCLFUNC node, got %+v", callee)
 	}
-	c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Pos}
-	c.stable = false
+	c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
+	return true
+}
+
+// recordCall records a call from ODCLFUNC node "from", to function
+// symbol "to" at position pos.
+//
+// This should be done as late as possible during compilation to
+// capture precise call graphs. The target of the call is an LSym
+// because that's all we know after we start SSA.
+//
+// This can be called concurrently for different from Nodes.
+func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
+	if from.Op != ODCLFUNC {
+		Fatalf("expected ODCLFUNC, got %v", from)
+	}
+	// We record this information on the *Func so this is
+	// concurrent-safe.
+	fn := from.Func
+	if fn.nwbrCalls == nil {
+		fn.nwbrCalls = new([]nowritebarrierrecCallSym)
+	}
+	*fn.nwbrCalls = append(*fn.nwbrCalls, nowritebarrierrecCallSym{to, pos})
+}
+
+func (c *nowritebarrierrecChecker) check() {
+	// We walk the call graph as late as possible so we can
+	// capture all calls created by lowering, but this means we
+	// only get to see the obj.LSyms of calls. symToFunc lets us
+	// get back to the ODCLFUNCs.
+	symToFunc := make(map[*obj.LSym]*Node)
+	// funcs records the back-edges of the BFS call graph walk. It
+	// maps from the ODCLFUNC of each function that must not have
+	// write barriers to the call that inhibits them. Functions
+	// that are directly marked go:nowritebarrierrec are in this
+	// map with a zero-valued nowritebarrierrecCall. This also
+	// acts as the set of marks for the BFS of the call graph.
+	funcs := make(map[*Node]nowritebarrierrecCall)
+	// q is the queue of ODCLFUNC Nodes to visit in BFS order.
+	var q nodeQueue
+
+	for _, n := range xtop {
+		if n.Op != ODCLFUNC {
+			continue
+		}
+
+		symToFunc[n.Func.lsym] = n
+
+		// Make nowritebarrierrec functions BFS roots.
+		if n.Func.Pragma&Nowritebarrierrec != 0 {
+			funcs[n] = nowritebarrierrecCall{}
+			q.pushRight(n)
+		}
+		// Check go:nowritebarrier functions.
+		if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
+			yyerrorl(n.Func.WBPos, "write barrier prohibited")
+		}
+	}
+
+	// Perform a BFS of the call graph from all
+	// go:nowritebarrierrec functions.
+	enqueue := func(src, target *Node, pos src.XPos) {
+		if target.Func.Pragma&Yeswritebarrierrec != 0 {
+			// Don't flow into this function.
+			return
+		}
+		if _, ok := funcs[target]; ok {
+			// Already found a path to target.
+			return
+		}
+
+		// Record the path.
+		funcs[target] = nowritebarrierrecCall{target: src, lineno: pos}
+		q.pushRight(target)
+	}
+	for !q.empty() {
+		fn := q.popLeft()
+
+		// Check fn.
+		if fn.Func.WBPos.IsKnown() {
+			var err bytes.Buffer
+			call := funcs[fn]
+			for call.target != nil {
+				fmt.Fprintf(&err, "\n\t%v: called by %v", linestr(call.lineno), call.target.Func.Nname)
+				call = funcs[call.target]
+			}
+			yyerrorl(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String())
+			continue
+		}
+
+		// Enqueue fn's calls.
+		for _, callee := range c.extraCalls[fn] {
+			enqueue(fn, callee.target, callee.lineno)
+		}
+		if fn.Func.nwbrCalls == nil {
+			continue
+		}
+		for _, callee := range *fn.Func.nwbrCalls {
+			target := symToFunc[callee.target]
+			if target != nil {
+				enqueue(fn, target, callee.lineno)
+			}
+		}
+	}
 }
diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go
new file mode 100644
index 0000000..e4eae3e
--- /dev/null
+++ b/src/cmd/compile/internal/gc/dwinl.go
@@ -0,0 +1,384 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gc
+
+import (
+	"cmd/internal/dwarf"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+	"sort"
+	"strings"
+)
+
+// To identify variables by original source position.
+type varPos struct {
+	DeclName string
+	DeclFile string
+	DeclLine uint
+	DeclCol  uint
+}
+
+// This is the main entry point for collection of raw material to
+// drive generation of DWARF "inlined subroutine" DIEs. See proposal
+// 22080 for more details and background info.
+func assembleInlines(fnsym *obj.LSym, fn *Node, dwVars []*dwarf.Var) dwarf.InlCalls {
+	var inlcalls dwarf.InlCalls
+
+	if Debug_gendwarfinl != 0 {
+		Ctxt.Logf("assembling DWARF inlined routine info for %v\n", fnsym.Name)
+	}
+
+	// This maps inline index (from Ctxt.InlTree) to index in inlcalls.Calls
+	imap := make(map[int]int)
+
+	// Walk progs to build up the InlCalls data structure
+	var prevpos src.XPos
+	for p := fnsym.Func.Text; p != nil; p = p.Link {
+		if p.Pos == prevpos {
+			continue
+		}
+		ii := posInlIndex(p.Pos)
+		if ii >= 0 {
+			insertInlCall(&inlcalls, ii, imap)
+		}
+		prevpos = p.Pos
+	}
+
+	// This is used to partition DWARF vars by inline index. Vars not
+	// produced by the inliner will wind up in the vmap[0] entry.
+	vmap := make(map[int32][]*dwarf.Var)
+
+	// Now walk the dwarf vars and partition them based on whether they
+	// were produced by the inliner (dwv.InlIndex > 0) or were original
+	// vars/params from the function (dwv.InlIndex == 0).
+	for _, dwv := range dwVars {
+
+		vmap[dwv.InlIndex] = append(vmap[dwv.InlIndex], dwv)
+
+		// Zero index => var was not produced by an inline
+		if dwv.InlIndex == 0 {
+			continue
+		}
+
+		// Look up index in our map, then tack the var in question
+		// onto the vars list for the correct inlined call.
+		ii := int(dwv.InlIndex) - 1
+		idx, ok := imap[ii]
+		if !ok {
+			// We can occasionally encounter a var produced by the
+			// inliner for which there is no remaining prog; add a new
+			// entry to the call list in this scenario.
+			idx = insertInlCall(&inlcalls, ii, imap)
+		}
+		inlcalls.Calls[idx].InlVars =
+			append(inlcalls.Calls[idx].InlVars, dwv)
+	}
+
+	// Post process the map above to assign child indices to vars.
+	//
+	// A given variable is treated differently depending on whether it
+	// is part of the top-level function (ii == 0) or if it was
+	// produced as a result of an inline (ii != 0).
+	//
+	// If a variable was not produced by an inline and its containing
+	// function was not inlined, then we just assign an ordering of
+	// based on variable name.
+	//
+	// If a variable was not produced by an inline and its containing
+	// function was inlined, then we need to assign a child index
+	// based on the order of vars in the abstract function (in
+	// addition, those vars that don't appear in the abstract
+	// function, such as "~r1", are flagged as such).
+	//
+	// If a variable was produced by an inline, then we locate it in
+	// the pre-inlining decls for the target function and assign child
+	// index accordingly.
+	for ii, sl := range vmap {
+		sort.Sort(byClassThenName(sl))
+		var m map[varPos]int
+		if ii == 0 {
+			if !fnsym.WasInlined() {
+				for j := 0; j < len(sl); j++ {
+					sl[j].ChildIndex = int32(j)
+				}
+				continue
+			}
+			m = makePreinlineDclMap(fnsym)
+		} else {
+			ifnlsym := Ctxt.InlTree.InlinedFunction(int(ii - 1))
+			m = makePreinlineDclMap(ifnlsym)
+		}
+
+		// Here we assign child indices to variables based on
+		// pre-inlined decls, and set the "IsInAbstract" flag
+		// appropriately. In addition: parameter and local variable
+		// names are given "middle dot" version numbers as part of the
+		// writing them out to export data (see issue 4326). If DWARF
+		// inlined routine generation is turned on, we want to undo
+		// this versioning, since DWARF variables in question will be
+		// parented by the inlined routine and not the top-level
+		// caller.
+		synthCount := len(m)
+		for j := 0; j < len(sl); j++ {
+			canonName := unversion(sl[j].Name)
+			vp := varPos{
+				DeclName: canonName,
+				DeclFile: sl[j].DeclFile,
+				DeclLine: sl[j].DeclLine,
+				DeclCol:  sl[j].DeclCol,
+			}
+			synthesized := strings.HasPrefix(sl[j].Name, "~r") || canonName == "_"
+			if idx, found := m[vp]; found {
+				sl[j].ChildIndex = int32(idx)
+				sl[j].IsInAbstract = !synthesized
+				sl[j].Name = canonName
+			} else {
+				// Variable can't be found in the pre-inline dcl list.
+				// In the top-level case (ii=0) this can happen
+				// because a composite variable was split into pieces,
+				// and we're looking at a piece. We can also see
+				// return temps (~r%d) that were created during
+				// lowering, or unnamed params ("_").
+				sl[j].ChildIndex = int32(synthCount)
+				synthCount += 1
+			}
+		}
+	}
+
+	// Make a second pass through the progs to compute PC ranges for
+	// the various inlined calls.
+	curii := -1
+	var crange *dwarf.Range
+	var prevp *obj.Prog
+	for p := fnsym.Func.Text; p != nil; prevp, p = p, p.Link {
+		if prevp != nil && p.Pos == prevp.Pos {
+			continue
+		}
+		ii := posInlIndex(p.Pos)
+		if ii == curii {
+			continue
+		} else {
+			// Close out the current range
+			endRange(crange, prevp)
+
+			// Begin new range
+			crange = beginRange(inlcalls.Calls, p, ii, imap)
+			curii = ii
+		}
+	}
+	if prevp != nil {
+		endRange(crange, prevp)
+	}
+
+	// Debugging
+	if Debug_gendwarfinl != 0 {
+		dumpInlCalls(inlcalls)
+		dumpInlVars(dwVars)
+	}
+
+	return inlcalls
+}
+
+// Secondary hook for DWARF inlined subroutine generation. This is called
+// late in the compilation when it is determined that we need an
+// abstract function DIE for an inlined routine imported from a
+// previously compiled package.
+func genAbstractFunc(fn *obj.LSym) {
+	ifn := Ctxt.DwFixups.GetPrecursorFunc(fn)
+	if ifn == nil {
+		Ctxt.Diag("failed to locate precursor fn for %v", fn)
+		return
+	}
+	if Debug_gendwarfinl != 0 {
+		Ctxt.Logf("DwarfAbstractFunc(%v)\n", fn.Name)
+	}
+	Ctxt.DwarfAbstractFunc(ifn, fn, myimportpath)
+}
+
+// Undo any versioning performed when a name was written
+// out as part of export data.
+func unversion(name string) string {
+	if i := strings.Index(name, "·"); i > 0 {
+		name = name[:i]
+	}
+	return name
+}
+
+// Given a function that was inlined as part of the compilation, dig
+// up the pre-inlining DCL list for the function and create a map that
+// supports lookup of pre-inline dcl index, based on variable
+// position/name.
+func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
+	dcl := preInliningDcls(fnsym)
+	m := make(map[varPos]int)
+	for i := 0; i < len(dcl); i++ {
+		n := dcl[i]
+		pos := Ctxt.InnermostPos(n.Pos)
+		vp := varPos{
+			DeclName: unversion(n.Sym.Name),
+			DeclFile: pos.Base().SymFilename(),
+			DeclLine: pos.Line(),
+			DeclCol:  pos.Col(),
+		}
+		if _, found := m[vp]; found {
+			Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name)
+		}
+		m[vp] = i
+	}
+	return m
+}
+
+func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
+	callIdx, found := imap[inlIdx]
+	if found {
+		return callIdx
+	}
+
+	// Haven't seen this inline yet. Visit parent of inline if there
+	// is one. We do this first so that parents appear before their
+	// children in the resulting table.
+	parCallIdx := -1
+	parInlIdx := Ctxt.InlTree.Parent(inlIdx)
+	if parInlIdx >= 0 {
+		parCallIdx = insertInlCall(dwcalls, parInlIdx, imap)
+	}
+
+	// Create new entry for this inline
+	inlinedFn := Ctxt.InlTree.InlinedFunction(int(inlIdx))
+	callXPos := Ctxt.InlTree.CallPos(int(inlIdx))
+	absFnSym := Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
+	pb := Ctxt.PosTable.Pos(callXPos).Base()
+	callFileSym := Ctxt.Lookup(pb.SymFilename())
+	ic := dwarf.InlCall{
+		InlIndex:  inlIdx,
+		CallFile:  callFileSym,
+		CallLine:  uint32(callXPos.Line()),
+		AbsFunSym: absFnSym,
+		Root:      parCallIdx == -1,
+	}
+	dwcalls.Calls = append(dwcalls.Calls, ic)
+	callIdx = len(dwcalls.Calls) - 1
+	imap[inlIdx] = callIdx
+
+	if parCallIdx != -1 {
+		// Add this inline to parent's child list
+		dwcalls.Calls[parCallIdx].Children = append(dwcalls.Calls[parCallIdx].Children, callIdx)
+	}
+
+	return callIdx
+}
+
+// Given a src.XPos, return its associated inlining index if it
+// corresponds to something created as a result of an inline, or -1 if
+// there is no inline info. Note that the index returned will refer to
+// the deepest call in the inlined stack, e.g. if you have "A calls B
+// calls C calls D" and all three callees are inlined (B, C, and D),
+// the index for a node from the inlined body of D will refer to the
+// call to D from C. Whew.
+func posInlIndex(xpos src.XPos) int {
+	pos := Ctxt.PosTable.Pos(xpos)
+	if b := pos.Base(); b != nil {
+		ii := b.InliningIndex()
+		if ii >= 0 {
+			return ii
+		}
+	}
+	return -1
+}
+
+func endRange(crange *dwarf.Range, p *obj.Prog) {
+	if crange == nil {
+		return
+	}
+	crange.End = p.Pc
+}
+
+func beginRange(calls []dwarf.InlCall, p *obj.Prog, ii int, imap map[int]int) *dwarf.Range {
+	if ii == -1 {
+		return nil
+	}
+	callIdx, found := imap[ii]
+	if !found {
+		Fatalf("internal error: can't find inlIndex %d in imap for prog at %d\n", ii, p.Pc)
+	}
+	call := &calls[callIdx]
+
+	// Set up range and append to correct inlined call
+	call.Ranges = append(call.Ranges, dwarf.Range{Start: p.Pc, End: -1})
+	return &call.Ranges[len(call.Ranges)-1]
+}
+
+func cmpDwarfVar(a, b *dwarf.Var) bool {
+	// named before artificial
+	aart := 0
+	if strings.HasPrefix(a.Name, "~r") {
+		aart = 1
+	}
+	bart := 0
+	if strings.HasPrefix(b.Name, "~r") {
+		bart = 1
+	}
+	if aart != bart {
+		return aart < bart
+	}
+
+	// otherwise sort by name
+	return a.Name < b.Name
+}
+
+// byClassThenName implements sort.Interface for []*dwarf.Var using cmpDwarfVar.
+type byClassThenName []*dwarf.Var
+
+func (s byClassThenName) Len() int           { return len(s) }
+func (s byClassThenName) Less(i, j int) bool { return cmpDwarfVar(s[i], s[j]) }
+func (s byClassThenName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
+	for i := 0; i < ilevel; i += 1 {
+		Ctxt.Logf("  ")
+	}
+	ic := inlcalls.Calls[idx]
+	callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex)
+	Ctxt.Logf("  %d: II:%d (%s) V: (", idx, ic.InlIndex, callee.Name)
+	for _, f := range ic.InlVars {
+		Ctxt.Logf(" %v", f.Name)
+	}
+	Ctxt.Logf(" ) C: (")
+	for _, k := range ic.Children {
+		Ctxt.Logf(" %v", k)
+	}
+	Ctxt.Logf(" ) R:")
+	for _, r := range ic.Ranges {
+		Ctxt.Logf(" [%d,%d)", r.Start, r.End)
+	}
+	Ctxt.Logf("\n")
+	for _, k := range ic.Children {
+		dumpInlCall(inlcalls, k, ilevel+1)
+	}
+
+}
+
+func dumpInlCalls(inlcalls dwarf.InlCalls) {
+	n := len(inlcalls.Calls)
+	for k := 0; k < n; k += 1 {
+		if inlcalls.Calls[k].Root {
+			dumpInlCall(inlcalls, k, 0)
+		}
+	}
+}
+
+func dumpInlVars(dwvars []*dwarf.Var) {
+	for i, dwv := range dwvars {
+		typ := "local"
+		if dwv.Abbrev == dwarf.DW_ABRV_PARAM_LOCLIST || dwv.Abbrev == dwarf.DW_ABRV_PARAM {
+			typ = "param"
+		}
+		ia := 0
+		if dwv.IsInAbstract {
+			ia = 1
+		}
+		Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ)
+	}
+}
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index 87a5b7f..03c0ada 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -129,20 +129,17 @@
 	min = v.visitcodelist(n.Nbody, min)
 	min = v.visitcodelist(n.Rlist, min)
 
-	if n.Op == OCALLFUNC || n.Op == OCALLMETH {
-		fn := n.Left
-		if n.Op == OCALLMETH {
-			fn = asNode(n.Left.Sym.Def)
-		}
+	switch n.Op {
+	case OCALLFUNC, OCALLMETH:
+		fn := asNode(n.Left.Type.Nname())
 		if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil {
 			m := v.visit(fn.Name.Defn)
 			if m < min {
 				min = m
 			}
 		}
-	}
 
-	if n.Op == OCLOSURE {
+	case OCLOSURE:
 		m := v.visit(n.Func.Closure)
 		if m < min {
 			min = m
@@ -176,12 +173,6 @@
 // then the value can stay on the stack. If the value new(T) does
 // not escape, then new(T) can be rewritten into a stack allocation.
 // The same is true of slice literals.
-//
-// If optimizations are disabled (-N), this code is not used.
-// Instead, the compiler assumes that any value whose address
-// is taken without being immediately dereferenced
-// needs to be moved to the heap, and new(T) and slice
-// literals are always real allocations.
 
 func escapes(all []*Node) {
 	visitBottomUp(all, escAnalyze)
@@ -205,9 +196,7 @@
 // allowed level when a loop is encountered. Using -2 suffices to
 // 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.
-const (
-	MinLevel = -2
-)
+const MinLevel = -2
 
 // A Level encodes the reference state and context applied to
 // (stack, heap) allocated memory.
@@ -679,7 +668,7 @@
 	// Big stuff escapes unconditionally
 	// "Big" conditions that were scattered around in walk have been gathered here
 	if n.Esc != EscHeap && n.Type != nil &&
-		(n.Type.Width > MaxStackVarSize ||
+		(n.Type.Width > maxStackVarSize ||
 			(n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= 1<<16 ||
 			n.Op == OMAKESLICE && !isSmallMakeSlice(n)) {
 		if Debug['m'] > 2 {
@@ -691,7 +680,18 @@
 	}
 
 	e.esc(n.Left, n)
+
+	if n.Op == ORANGE {
+		// ORANGE node's Right is evaluated before the loop
+		e.loopdepth--
+	}
+
 	e.esc(n.Right, n)
+
+	if n.Op == ORANGE {
+		e.loopdepth++
+	}
+
 	e.esclist(n.Nbody, n)
 	e.esclist(n.List, n)
 	e.esclist(n.Rlist, n)
@@ -848,7 +848,7 @@
 
 	case ORETURN:
 		retList := n.List
-		if retList.Len() == 1 && Curfn.Type.Results().NumFields() > 1 {
+		if retList.Len() == 1 && Curfn.Type.NumResults() > 1 {
 			// OAS2FUNC in disguise
 			// esccall already done on n.List.First()
 			// tie e.nodeEscState(n.List.First()).Retval to Curfn.Func.Dcl PPARAMOUT's
@@ -1279,16 +1279,14 @@
 // to the second output (and if there are more than two outputs, there is no flow to those.)
 func describeEscape(em uint16) string {
 	var s string
-	if em&EscMask == EscUnknown {
+	switch em & EscMask {
+	case EscUnknown:
 		s = "EscUnknown"
-	}
-	if em&EscMask == EscNone {
+	case EscNone:
 		s = "EscNone"
-	}
-	if em&EscMask == EscHeap {
+	case EscHeap:
 		s = "EscHeap"
-	}
-	if em&EscMask == EscReturn {
+	case EscReturn:
 		s = "EscReturn"
 	}
 	if em&EscContentEscapes != 0 {
@@ -1554,20 +1552,20 @@
 					call.Right = arg
 				}
 				e.escassignWhyWhere(n, arg, "arg to recursive call", call) // TODO this message needs help.
-				if arg != args[0] {
-					// "..." arguments are untracked
-					for _, a := range args {
-						if Debug['m'] > 3 {
-							fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
-						}
-						e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call)
-					}
-					// No more PPARAM processing, but keep
-					// going for PPARAMOUT.
-					args = nil
+				if arg == args[0] {
+					args = args[1:]
 					continue
 				}
-				args = args[1:]
+				// "..." arguments are untracked
+				for _, a := range args {
+					if Debug['m'] > 3 {
+						fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
+					}
+					e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call)
+				}
+				// No more PPARAM processing, but keep
+				// going for PPARAMOUT.
+				args = nil
 
 			case PPARAMOUT:
 				cE.Retval.Append(n)
diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go
index a92a41c..c5d5c52 100644
--- a/src/cmd/compile/internal/gc/export.go
+++ b/src/cmd/compile/internal/gc/export.go
@@ -9,6 +9,7 @@
 	"bytes"
 	"cmd/compile/internal/types"
 	"cmd/internal/bio"
+	"cmd/internal/src"
 	"fmt"
 	"unicode"
 	"unicode/utf8"
@@ -18,7 +19,7 @@
 	Debug_export int // if set, print debugging information about export data
 )
 
-func exportf(format string, args ...interface{}) {
+func exportf(bout *bio.Writer, format string, args ...interface{}) {
 	fmt.Fprintf(bout, format, args...)
 	if Debug_export != 0 {
 		fmt.Printf(format, args...)
@@ -82,7 +83,7 @@
 	if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN {
 		return
 	}
-	if n.Type != nil && n.Type.IsKind(TFUNC) && n.Type.Recv() != nil { // method
+	if n.Type != nil && n.Type.IsKind(TFUNC) && n.IsMethod() {
 		return
 	}
 
@@ -111,10 +112,10 @@
 	switch n.Op {
 	case ONAME:
 		switch n.Class() {
-		// methods will be printed along with their type
-		// nodes for T.Method expressions
 		case PFUNC:
-			if n.Left != nil && n.Left.Op == OTYPE {
+			// methods will be printed along with their type
+			// nodes for T.Method expressions
+			if n.isMethodExpression() {
 				break
 			}
 
@@ -221,14 +222,14 @@
 func (x methodbyname) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
 func (x methodbyname) Less(i, j int) bool { return x[i].Sym.Name < x[j].Sym.Name }
 
-func dumpexport() {
+func dumpexport(bout *bio.Writer) {
 	if buildid != "" {
-		exportf("build id %q\n", buildid)
+		exportf(bout, "build id %q\n", buildid)
 	}
 
 	size := 0 // size of export section without enclosing markers
 	// The linker also looks for the $$ marker - use char after $$ to distinguish format.
-	exportf("\n$$B\n") // indicate binary export format
+	exportf(bout, "\n$$B\n") // indicate binary export format
 	if debugFormat {
 		// save a copy of the export data
 		var copy bytes.Buffer
@@ -252,7 +253,7 @@
 	} else {
 		size = export(bout.Writer, Debug_export != 0)
 	}
-	exportf("\n$$\n")
+	exportf(bout, "\n$$\n")
 
 	if Debug_export != 0 {
 		fmt.Printf("export data size = %d bytes\n", size)
@@ -280,12 +281,12 @@
 // pkgtype returns the named type declared by symbol s.
 // If no such type has been declared yet, a forward declaration is returned.
 // pkg is the package being imported
-func pkgtype(pkg *types.Pkg, s *types.Sym) *types.Type {
+func pkgtype(pos src.XPos, pkg *types.Pkg, s *types.Sym) *types.Type {
 	importsym(pkg, s, OTYPE)
 	if asNode(s.Def) == nil || asNode(s.Def).Op != OTYPE {
 		t := types.New(TFORW)
 		t.Sym = s
-		s.Def = asTypesNode(typenod(t))
+		s.Def = asTypesNode(typenodl(pos, t))
 		asNode(s.Def).Name = new(Name)
 	}
 
@@ -326,7 +327,7 @@
 
 // importvar declares symbol s as an imported variable with type t.
 // pkg is the package being imported
-func importvar(pkg *types.Pkg, s *types.Sym, t *types.Type) {
+func importvar(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
 	importsym(pkg, s, ONAME)
 	if asNode(s.Def) != nil && asNode(s.Def).Op == ONAME {
 		if eqtype(t, asNode(s.Def).Type) {
@@ -335,7 +336,7 @@
 		yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path)
 	}
 
-	n := newname(s)
+	n := newnamel(pos, s)
 	s.Importdef = pkg
 	n.Type = t
 	declare(n, PEXTERN)
@@ -347,7 +348,7 @@
 
 // importalias declares symbol s as an imported type alias with type t.
 // pkg is the package being imported
-func importalias(pkg *types.Pkg, s *types.Sym, t *types.Type) {
+func importalias(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
 	importsym(pkg, s, OTYPE)
 	if asNode(s.Def) != nil && asNode(s.Def).Op == OTYPE {
 		if eqtype(t, asNode(s.Def).Type) {
@@ -356,7 +357,7 @@
 		yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path)
 	}
 
-	n := newname(s)
+	n := newnamel(pos, s)
 	n.Op = OTYPE
 	s.Importdef = pkg
 	n.Type = t
@@ -386,10 +387,10 @@
 			if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
 				break
 			}
-			fmt.Fprintf(b, "#define %s__size %d\n", t.Sym.Name, int(t.Width))
-			for _, t := range t.Fields().Slice() {
-				if !t.Sym.IsBlank() {
-					fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, t.Sym.Name, int(t.Offset))
+			fmt.Fprintf(b, "#define %s__size %d\n", n.Sym.Name, int(t.Width))
+			for _, f := range t.Fields().Slice() {
+				if !f.Sym.IsBlank() {
+					fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, f.Sym.Name, int(f.Offset))
 				}
 			}
 		}
diff --git a/src/cmd/compile/internal/gc/float_test.go b/src/cmd/compile/internal/gc/float_test.go
index f906f3a..4cb9532 100644
--- a/src/cmd/compile/internal/gc/float_test.go
+++ b/src/cmd/compile/internal/gc/float_test.go
@@ -4,7 +4,10 @@
 
 package gc
 
-import "testing"
+import (
+	"math"
+	"testing"
+)
 
 // For GO386=387, make sure fucomi* opcodes are not used
 // for comparison operations.
@@ -31,6 +34,107 @@
 	}
 }
 
+func TestFloatCompareFolded(t *testing.T) {
+	// float64 comparisons
+	d1, d3, d5, d9 := float64(1), float64(3), float64(5), float64(9)
+	if d3 == d5 {
+		t.Errorf("d3 == d5 returned true")
+	}
+	if d3 != d3 {
+		t.Errorf("d3 != d3 returned true")
+	}
+	if d3 > d5 {
+		t.Errorf("d3 > d5 returned true")
+	}
+	if d3 >= d9 {
+		t.Errorf("d3 >= d9 returned true")
+	}
+	if d5 < d1 {
+		t.Errorf("d5 < d1 returned true")
+	}
+	if d9 <= d1 {
+		t.Errorf("d9 <= d1 returned true")
+	}
+	if math.NaN() == math.NaN() {
+		t.Errorf("math.NaN() == math.NaN() returned true")
+	}
+	if math.NaN() >= math.NaN() {
+		t.Errorf("math.NaN() >= math.NaN() returned true")
+	}
+	if math.NaN() <= math.NaN() {
+		t.Errorf("math.NaN() <= math.NaN() returned true")
+	}
+	if math.Copysign(math.NaN(), -1) < math.NaN() {
+		t.Errorf("math.Copysign(math.NaN(), -1) < math.NaN() returned true")
+	}
+	if math.Inf(1) != math.Inf(1) {
+		t.Errorf("math.Inf(1) != math.Inf(1) returned true")
+	}
+	if math.Inf(-1) != math.Inf(-1) {
+		t.Errorf("math.Inf(-1) != math.Inf(-1) returned true")
+	}
+	if math.Copysign(0, -1) != 0 {
+		t.Errorf("math.Copysign(0, -1) != 0 returned true")
+	}
+	if math.Copysign(0, -1) < 0 {
+		t.Errorf("math.Copysign(0, -1) < 0 returned true")
+	}
+	if 0 > math.Copysign(0, -1) {
+		t.Errorf("0 > math.Copysign(0, -1) returned true")
+	}
+
+	// float32 comparisons
+	s1, s3, s5, s9 := float32(1), float32(3), float32(5), float32(9)
+	if s3 == s5 {
+		t.Errorf("s3 == s5 returned true")
+	}
+	if s3 != s3 {
+		t.Errorf("s3 != s3 returned true")
+	}
+	if s3 > s5 {
+		t.Errorf("s3 > s5 returned true")
+	}
+	if s3 >= s9 {
+		t.Errorf("s3 >= s9 returned true")
+	}
+	if s5 < s1 {
+		t.Errorf("s5 < s1 returned true")
+	}
+	if s9 <= s1 {
+		t.Errorf("s9 <= s1 returned true")
+	}
+	sPosNaN, sNegNaN := float32(math.NaN()), float32(math.Copysign(math.NaN(), -1))
+	if sPosNaN == sPosNaN {
+		t.Errorf("sPosNaN == sPosNaN returned true")
+	}
+	if sPosNaN >= sPosNaN {
+		t.Errorf("sPosNaN >= sPosNaN returned true")
+	}
+	if sPosNaN <= sPosNaN {
+		t.Errorf("sPosNaN <= sPosNaN returned true")
+	}
+	if sNegNaN < sPosNaN {
+		t.Errorf("sNegNaN < sPosNaN returned true")
+	}
+	sPosInf, sNegInf := float32(math.Inf(1)), float32(math.Inf(-1))
+	if sPosInf != sPosInf {
+		t.Errorf("sPosInf != sPosInf returned true")
+	}
+	if sNegInf != sNegInf {
+		t.Errorf("sNegInf != sNegInf returned true")
+	}
+	sNegZero := float32(math.Copysign(0, -1))
+	if sNegZero != 0 {
+		t.Errorf("sNegZero != 0 returned true")
+	}
+	if sNegZero < 0 {
+		t.Errorf("sNegZero < 0 returned true")
+	}
+	if 0 > sNegZero {
+		t.Errorf("0 > sNegZero returned true")
+	}
+}
+
 // For GO386=387, make sure fucomi* opcodes are not used
 // for float->int conversions.
 
@@ -95,6 +199,16 @@
 	return uint(a)
 }
 
+//go:noinline
+func f2i64p(v float64) *int64 {
+	return ip64(int64(v / 0.1))
+}
+
+//go:noinline
+func ip64(v int64) *int64 {
+	return &v
+}
+
 func TestFloatConvert(t *testing.T) {
 	if got := cvt1(3.5); got != 3 {
 		t.Errorf("cvt1 got %d, wanted 3", got)
@@ -132,6 +246,120 @@
 	if got := cvt12(3.5); got != 3 {
 		t.Errorf("cvt12 got %d, wanted 3", got)
 	}
+	if got := *f2i64p(10); got != 100 {
+		t.Errorf("f2i64p got %d, wanted 100", got)
+	}
+}
+
+func TestFloatConvertFolded(t *testing.T) {
+	// Assign constants to variables so that they are (hopefully) constant folded
+	// by the SSA backend rather than the frontend.
+	u64, u32, u16, u8 := uint64(1<<63), uint32(1<<31), uint16(1<<15), uint8(1<<7)
+	i64, i32, i16, i8 := int64(-1<<63), int32(-1<<31), int16(-1<<15), int8(-1<<7)
+	du64, du32, du16, du8 := float64(1<<63), float64(1<<31), float64(1<<15), float64(1<<7)
+	di64, di32, di16, di8 := float64(-1<<63), float64(-1<<31), float64(-1<<15), float64(-1<<7)
+	su64, su32, su16, su8 := float32(1<<63), float32(1<<31), float32(1<<15), float32(1<<7)
+	si64, si32, si16, si8 := float32(-1<<63), float32(-1<<31), float32(-1<<15), float32(-1<<7)
+
+	// integer to float
+	if float64(u64) != du64 {
+		t.Errorf("float64(u64) != du64")
+	}
+	if float64(u32) != du32 {
+		t.Errorf("float64(u32) != du32")
+	}
+	if float64(u16) != du16 {
+		t.Errorf("float64(u16) != du16")
+	}
+	if float64(u8) != du8 {
+		t.Errorf("float64(u8) != du8")
+	}
+	if float64(i64) != di64 {
+		t.Errorf("float64(i64) != di64")
+	}
+	if float64(i32) != di32 {
+		t.Errorf("float64(i32) != di32")
+	}
+	if float64(i16) != di16 {
+		t.Errorf("float64(i16) != di16")
+	}
+	if float64(i8) != di8 {
+		t.Errorf("float64(i8) != di8")
+	}
+	if float32(u64) != su64 {
+		t.Errorf("float32(u64) != su64")
+	}
+	if float32(u32) != su32 {
+		t.Errorf("float32(u32) != su32")
+	}
+	if float32(u16) != su16 {
+		t.Errorf("float32(u16) != su16")
+	}
+	if float32(u8) != su8 {
+		t.Errorf("float32(u8) != su8")
+	}
+	if float32(i64) != si64 {
+		t.Errorf("float32(i64) != si64")
+	}
+	if float32(i32) != si32 {
+		t.Errorf("float32(i32) != si32")
+	}
+	if float32(i16) != si16 {
+		t.Errorf("float32(i16) != si16")
+	}
+	if float32(i8) != si8 {
+		t.Errorf("float32(i8) != si8")
+	}
+
+	// float to integer
+	if uint64(du64) != u64 {
+		t.Errorf("uint64(du64) != u64")
+	}
+	if uint32(du32) != u32 {
+		t.Errorf("uint32(du32) != u32")
+	}
+	if uint16(du16) != u16 {
+		t.Errorf("uint16(du16) != u16")
+	}
+	if uint8(du8) != u8 {
+		t.Errorf("uint8(du8) != u8")
+	}
+	if int64(di64) != i64 {
+		t.Errorf("int64(di64) != i64")
+	}
+	if int32(di32) != i32 {
+		t.Errorf("int32(di32) != i32")
+	}
+	if int16(di16) != i16 {
+		t.Errorf("int16(di16) != i16")
+	}
+	if int8(di8) != i8 {
+		t.Errorf("int8(di8) != i8")
+	}
+	if uint64(su64) != u64 {
+		t.Errorf("uint64(su64) != u64")
+	}
+	if uint32(su32) != u32 {
+		t.Errorf("uint32(su32) != u32")
+	}
+	if uint16(su16) != u16 {
+		t.Errorf("uint16(su16) != u16")
+	}
+	if uint8(su8) != u8 {
+		t.Errorf("uint8(su8) != u8")
+	}
+	if int64(si64) != i64 {
+		t.Errorf("int64(si64) != i64")
+	}
+	if int32(si32) != i32 {
+		t.Errorf("int32(si32) != i32")
+	}
+	if int16(si16) != i16 {
+		t.Errorf("int16(si16) != i16")
+	}
+	if int8(si8) != i8 {
+		t.Errorf("int8(si8) != i8")
+	}
 }
 
 var sinkFloat float64
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index 2f56d8a..4b2fdb0 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -204,11 +204,6 @@
 	OSUB:      "-",
 	OSWITCH:   "switch",
 	OXOR:      "^",
-	OXFALL:    "fallthrough",
-}
-
-func (o Op) String() string {
-	return fmt.Sprint(o)
 }
 
 func (o Op) GoString() string {
@@ -227,28 +222,14 @@
 
 func (o Op) oconv(s fmt.State, flag FmtFlag, mode fmtMode) {
 	if flag&FmtSharp != 0 || mode != FDbg {
-		if o >= 0 && int(o) < len(goopnames) && goopnames[o] != "" {
+		if int(o) < len(goopnames) && goopnames[o] != "" {
 			fmt.Fprint(s, goopnames[o])
 			return
 		}
 	}
 
-	if o >= 0 && int(o) < len(opnames) && opnames[o] != "" {
-		fmt.Fprint(s, opnames[o])
-		return
-	}
-
-	fmt.Fprintf(s, "O-%d", int(o))
-}
-
-var classnames = []string{
-	"Pxxx",
-	"PEXTERN",
-	"PAUTO",
-	"PAUTOHEAP",
-	"PPARAM",
-	"PPARAMOUT",
-	"PFUNC",
+	// 'o.String()' instead of just 'o' to avoid infinite recursion
+	fmt.Fprint(s, o.String())
 }
 
 type (
@@ -448,11 +429,7 @@
 	}
 
 	if n.Class() != 0 {
-		if int(n.Class()) < len(classnames) {
-			fmt.Fprintf(s, " class(%s)", classnames[n.Class()])
-		} else {
-			fmt.Fprintf(s, " class(%d?)", n.Class())
-		}
+		fmt.Fprintf(s, " class(%v)", n.Class())
 	}
 
 	if n.Colas() {
@@ -814,7 +791,7 @@
 		}
 		buf = append(buf, tmodeString(t.Params(), mode, depth)...)
 
-		switch t.Results().NumFields() {
+		switch t.NumResults() {
 		case 0:
 			// nothing to do
 
@@ -1080,11 +1057,7 @@
 		}
 		mode.Fprintf(s, ": %v", n.Nbody)
 
-	case OBREAK,
-		OCONTINUE,
-		OGOTO,
-		OFALL,
-		OXFALL:
+	case OBREAK, OCONTINUE, OGOTO, OFALL:
 		if n.Left != nil {
 			mode.Fprintf(s, "%#v %v", n.Op, n.Left)
 		} else {
@@ -1219,7 +1192,6 @@
 	OSELECT:     -1,
 	OSWITCH:     -1,
 	OXCASE:      -1,
-	OXFALL:      -1,
 
 	OEND: 0,
 }
@@ -1543,13 +1515,11 @@
 		n.Right.exprfmt(s, nprec+1, mode)
 
 	case OADDSTR:
-		i := 0
-		for _, n1 := range n.List.Slice() {
+		for i, n1 := range n.List.Slice() {
 			if i != 0 {
 				fmt.Fprint(s, " + ")
 			}
 			n1.exprfmt(s, nprec, mode)
-			i++
 		}
 
 	case OCMPSTR, OCMPIFACE:
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
index 626d282..f9b4584 100644
--- a/src/cmd/compile/internal/gc/gen.go
+++ b/src/cmd/compile/internal/gc/gen.go
@@ -11,7 +11,7 @@
 	"strconv"
 )
 
-func Sysfunc(name string) *obj.LSym {
+func sysfunc(name string) *obj.LSym {
 	return Runtimepkg.Lookup(name).Linksym()
 }
 
@@ -39,7 +39,7 @@
 }
 
 // make a new Node off the books
-func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *types.Type) {
+func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
 	if curfn == nil {
 		Fatalf("no curfn for tempname")
 	}
@@ -61,23 +61,15 @@
 	n.SetClass(PAUTO)
 	n.Esc = EscNever
 	n.Name.Curfn = curfn
+	n.Name.SetUsed(true)
 	n.Name.SetAutoTemp(true)
 	curfn.Func.Dcl = append(curfn.Func.Dcl, n)
 
 	dowidth(t)
-	*nn = *n
+
+	return n.Orig
 }
 
 func temp(t *types.Type) *Node {
-	var n Node
-	tempnamel(lineno, Curfn, &n, t)
-	asNode(n.Sym.Def).Name.SetUsed(true)
-	return n.Orig
-}
-
-func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
-	var n Node
-	tempnamel(pos, curfn, &n, t)
-	asNode(n.Sym.Def).Name.SetUsed(true)
-	return n.Orig
+	return tempAt(lineno, Curfn, t)
 }
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index b1ead93..dc94cf4 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -7,7 +7,6 @@
 import (
 	"cmd/compile/internal/ssa"
 	"cmd/compile/internal/types"
-	"cmd/internal/bio"
 	"cmd/internal/obj"
 	"cmd/internal/src"
 	"sync"
@@ -15,7 +14,7 @@
 
 const (
 	BADWIDTH        = types.BADWIDTH
-	MaxStackVarSize = 10 * 1024 * 1024
+	maxStackVarSize = 10 * 1024 * 1024
 )
 
 // isRuntimePkg reports whether p is package runtime.
@@ -85,8 +84,6 @@
 var linkobj string
 var dolinkobj bool
 
-var bout *bio.Writer
-
 // nerrors is the number of compiler errors reported
 // since the last call to saveerrors.
 var nerrors int
@@ -201,7 +198,7 @@
 // Compiling the standard library
 var compiling_std bool
 
-var compiling_wrappers int
+var compiling_wrappers bool
 
 var use_writebarrier bool
 
@@ -222,6 +219,11 @@
 // Whether we are tracking lexical scopes for DWARF.
 var trackScopes bool
 
+// Controls generation of DWARF inlined instance records. Zero
+// disables, 1 emits inlined routines but suppresses var info,
+// and 2 emits inlined routines with tracking of formals/locals.
+var genDwarfInline int
+
 var debuglive int
 
 var Ctxt *obj.Link
@@ -241,9 +243,10 @@
 type Arch struct {
 	LinkArch *obj.LinkArch
 
-	REGSP    int
-	MAXWIDTH int64
-	Use387   bool // should 386 backend use 387 FP instructions instead of sse2.
+	REGSP     int
+	MAXWIDTH  int64
+	Use387    bool // should 386 backend use 387 FP instructions instead of sse2.
+	SoftFloat bool
 
 	PadFrame  func(int64) int64
 	ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
@@ -290,6 +293,7 @@
 	goschedguarded,
 	writeBarrier,
 	writebarrierptr,
+	gcWriteBarrier,
 	typedmemmove,
 	typedmemclr,
 	Udiv *obj.LSym
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index b25709b..d074900 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -37,7 +37,7 @@
 	"cmd/internal/src"
 )
 
-var sharedProgArray *[10000]obj.Prog = new([10000]obj.Prog) // *T instead of T to work around issue 19839
+var sharedProgArray = new([10000]obj.Prog) // *T instead of T to work around issue 19839
 
 // Progs accumulates Progs for a function and converts them into machine code.
 type Progs struct {
@@ -70,13 +70,13 @@
 }
 
 func (pp *Progs) NewProg() *obj.Prog {
+	var p *obj.Prog
 	if pp.cacheidx < len(pp.progcache) {
-		p := &pp.progcache[pp.cacheidx]
-		p.Ctxt = Ctxt
+		p = &pp.progcache[pp.cacheidx]
 		pp.cacheidx++
-		return p
+	} else {
+		p = new(obj.Prog)
 	}
-	p := new(obj.Prog)
 	p.Ctxt = Ctxt
 	return p
 }
@@ -84,7 +84,7 @@
 // Flush converts from pp to machine code.
 func (pp *Progs) Flush() {
 	plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.curfn}
-	obj.Flushplist(Ctxt, plist, pp.NewProg)
+	obj.Flushplist(Ctxt, plist, pp.NewProg, myimportpath)
 }
 
 // Free clears pp and any associated resources.
diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go
index 93ae241..180cbcf 100644
--- a/src/cmd/compile/internal/gc/init.go
+++ b/src/cmd/compile/internal/gc/init.go
@@ -198,7 +198,7 @@
 	exportsym(fn.Func.Nname)
 
 	fn.Nbody.Set(r)
-	funcbody(fn)
+	funcbody()
 
 	Curfn = fn
 	fn = typecheck(fn, Etop)
@@ -208,8 +208,7 @@
 }
 
 func (n *Node) checkInitFuncSignature() {
-	ft := n.Type.FuncType()
-	if ft.Receiver.Fields().Len()+ft.Params.Fields().Len()+ft.Results.Fields().Len() > 0 {
+	if n.Type.NumRecvs()+n.Type.NumParams()+n.Type.NumResults() > 0 {
 		Fatalf("init function cannot have receiver, params, or results: %v (%v)", n, n.Type)
 	}
 }
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
index dfa13e3..c829697 100644
--- a/src/cmd/compile/internal/gc/inl.go
+++ b/src/cmd/compile/internal/gc/inl.go
@@ -8,29 +8,33 @@
 // expand calls to inlinable functions.
 //
 // The debug['l'] flag controls the aggressiveness. Note that main() swaps level 0 and 1,
-// making 1 the default and -l disable.  -ll and more is useful to flush out bugs.
-// These additional levels (beyond -l) may be buggy and are not supported.
+// making 1 the default and -l disable. Additional levels (beyond -l) may be buggy and
+// are not supported.
 //      0: disabled
 //      1: 80-nodes leaf functions, oneliners, lazy typechecking (default)
-//      2: early typechecking of all imported bodies
+//      2: (unassigned)
 //      3: allow variadic functions
-//      4: allow non-leaf functions , (breaks runtime.Caller)
+//      4: allow non-leaf functions
 //
-//  At some point this may get another default and become switch-offable with -N.
+// At some point this may get another default and become switch-offable with -N.
 //
-//  The debug['m'] flag enables diagnostic output.  a single -m is useful for verifying
-//  which calls get inlined or not, more is for debugging, and may go away at any point.
+// The -d typcheckinl flag enables early typechecking of all imported bodies,
+// which is useful to flush out bugs.
+//
+// The debug['m'] flag enables diagnostic output.  a single -m is useful for verifying
+// which calls get inlined or not, more is for debugging, and may go away at any point.
 //
 // TODO:
 //   - inline functions with ... args
-//   - handle T.meth(f()) with func f() (t T, arg, arg, )
 
 package gc
 
 import (
 	"cmd/compile/internal/types"
+	"cmd/internal/obj"
 	"cmd/internal/src"
 	"fmt"
+	"strings"
 )
 
 // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
@@ -118,6 +122,15 @@
 		return
 	}
 
+	// The nowritebarrierrec checker currently works at function
+	// granularity, so inlining yeswritebarrierrec functions can
+	// confuse it (#22342). As a workaround, disallow inlining
+	// them for now.
+	if fn.Func.Pragma&Yeswritebarrierrec != 0 {
+		reason = "marked go:yeswritebarrierrec"
+		return
+	}
+
 	// If fn has no body (is defined outside of Go), cannot inline it.
 	if fn.Nbody.Len() == 0 {
 		reason = "no function body"
@@ -150,6 +163,12 @@
 		return
 	}
 
+	n := fn.Func.Nname
+	if n.Func.InlinabilityChecked() {
+		return
+	}
+	defer n.Func.SetInlinabilityChecked(true)
+
 	const maxBudget = 80
 	visitor := hairyVisitor{budget: maxBudget}
 	if visitor.visitList(fn.Nbody) {
@@ -157,15 +176,13 @@
 		return
 	}
 	if visitor.budget < 0 {
-		reason = "function too complex"
+		reason = fmt.Sprintf("function too complex: cost %d exceeds budget %d", maxBudget-visitor.budget, maxBudget)
 		return
 	}
 
 	savefn := Curfn
 	Curfn = fn
 
-	n := fn.Func.Nname
-
 	n.Func.Inl.Set(fn.Nbody.Slice())
 	fn.Nbody.Set(inlcopylist(n.Func.Inl.Slice()))
 	inldcl := inlcopylist(n.Name.Defn.Func.Dcl)
@@ -185,6 +202,43 @@
 	Curfn = savefn
 }
 
+// inlFlood marks n's inline body for export and recursively ensures
+// all called functions are marked too.
+func inlFlood(n *Node) {
+	if n == nil {
+		return
+	}
+	if n.Op != ONAME || n.Class() != PFUNC {
+		Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op, n.Class())
+	}
+	if n.Func == nil {
+		// TODO(mdempsky): Should init have a Func too?
+		if n.Sym.Name == "init" {
+			return
+		}
+		Fatalf("inlFlood: missing Func on %v", n)
+	}
+	if n.Func.Inl.Len() == 0 {
+		return
+	}
+
+	if n.Func.ExportInline() {
+		return
+	}
+	n.Func.SetExportInline(true)
+
+	typecheckinl(n)
+
+	// Recursively flood any functions called by this one.
+	inspectList(n.Func.Inl, func(n *Node) bool {
+		switch n.Op {
+		case OCALLFUNC, OCALLMETH:
+			inlFlood(asNode(n.Left.Type.Nname()))
+		}
+		return true
+	})
+}
+
 // hairyVisitor visits a function body to determine its inlining
 // hairiness and whether or not it can be inlined.
 type hairyVisitor struct {
@@ -228,13 +282,14 @@
 			v.budget -= fn.InlCost
 			break
 		}
-
-		if n.isMethodCalledAsFunction() {
+		if n.Left.isMethodExpression() {
 			if d := asNode(n.Left.Sym.Def); d != nil && d.Func.Inl.Len() != 0 {
 				v.budget -= d.Func.InlCost
 				break
 			}
 		}
+		// TODO(mdempsky): Budget for OCLOSURE calls if we
+		// ever allow that. See #15561 and #23093.
 		if Debug['l'] < 4 {
 			v.reason = "non-leaf function"
 			return true
@@ -259,12 +314,18 @@
 		}
 
 	// Things that are too hairy, irrespective of the budget
-	case OCALL, OCALLINTER, OPANIC, ORECOVER:
+	case OCALL, OCALLINTER, OPANIC:
 		if Debug['l'] < 4 {
 			v.reason = "non-leaf op " + n.Op.String()
 			return true
 		}
 
+	case ORECOVER:
+		// recover matches the argument frame pointer to find
+		// the right panic value, so it needs an argument frame.
+		v.reason = "call to recover"
+		return true
+
 	case OCLOSURE,
 		OCALLPART,
 		ORANGE,
@@ -279,6 +340,10 @@
 		ORETJMP:
 		v.reason = "unhandled op " + n.Op.String()
 		return true
+
+	case ODCLCONST, OEMPTY, OFALL, OLABEL:
+		// These nodes don't produce code; omit from inlining budget.
+		return false
 	}
 
 	v.budget--
@@ -293,8 +358,8 @@
 		v.budget -= 2
 	}
 
-	if v.budget < 0 {
-		v.reason = "function too complex"
+	// When debugging, don't stop early, to get full cost of inlining this function
+	if v.budget < 0 && Debug['m'] < 2 {
 		return true
 	}
 
@@ -517,8 +582,39 @@
 		}
 		if n.Left.Func != nil && n.Left.Func.Inl.Len() != 0 && !isIntrinsicCall(n) { // normal case
 			n = mkinlcall(n, n.Left, n.Isddd())
-		} else if n.isMethodCalledAsFunction() && asNode(n.Left.Sym.Def) != nil {
+		} else if n.Left.isMethodExpression() && asNode(n.Left.Sym.Def) != nil {
 			n = mkinlcall(n, asNode(n.Left.Sym.Def), n.Isddd())
+		} else if n.Left.Op == OCLOSURE {
+			if f := inlinableClosure(n.Left); f != nil {
+				n = mkinlcall(n, f, n.Isddd())
+			}
+		} else if n.Left.Op == ONAME && n.Left.Name != nil && n.Left.Name.Defn != nil {
+			if d := n.Left.Name.Defn; d.Op == OAS && d.Right.Op == OCLOSURE {
+				if f := inlinableClosure(d.Right); f != nil {
+					// NB: this check is necessary to prevent indirect re-assignment of the variable
+					// having the address taken after the invocation or only used for reads is actually fine
+					// but we have no easy way to distinguish the safe cases
+					if d.Left.Addrtaken() {
+						if Debug['m'] > 1 {
+							fmt.Printf("%v: cannot inline escaping closure variable %v\n", n.Line(), n.Left)
+						}
+						break
+					}
+
+					// ensure the variable is never re-assigned
+					if unsafe, a := reassigned(n.Left); unsafe {
+						if Debug['m'] > 1 {
+							if a != nil {
+								fmt.Printf("%v: cannot inline re-assigned closure variable at %v: %v\n", n.Line(), a.Line(), a)
+							} else {
+								fmt.Printf("%v: cannot inline global closure variable %v\n", n.Line(), n.Left)
+							}
+						}
+						break
+					}
+					n = mkinlcall(n, f, n.Isddd())
+				}
+			}
 		}
 
 	case OCALLMETH:
@@ -542,6 +638,98 @@
 	return n
 }
 
+// inlinableClosure takes an OCLOSURE node and follows linkage to the matching ONAME with
+// the inlinable body. Returns nil if the function is not inlinable.
+func inlinableClosure(n *Node) *Node {
+	c := n.Func.Closure
+	caninl(c)
+	f := c.Func.Nname
+	if f == nil || f.Func.Inl.Len() == 0 {
+		return nil
+	}
+	return f
+}
+
+// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
+// indicating whether the name has any assignments other than its declaration.
+// The second return value is the first such assignment encountered in the walk, if any. It is mostly
+// useful for -m output documenting the reason for inhibited optimizations.
+// NB: global variables are always considered to be re-assigned.
+// TODO: handle initial declaration not including an assignment and followed by a single assignment?
+func reassigned(n *Node) (bool, *Node) {
+	if n.Op != ONAME {
+		Fatalf("reassigned %v", n)
+	}
+	// no way to reliably check for no-reassignment of globals, assume it can be
+	if n.Name.Curfn == nil {
+		return true, nil
+	}
+	f := n.Name.Curfn
+	// There just might be a good reason for this although this can be pretty surprising:
+	// local variables inside a closure have Curfn pointing to the OCLOSURE node instead
+	// of the corresponding ODCLFUNC.
+	// We need to walk the function body to check for reassignments so we follow the
+	// linkage to the ODCLFUNC node as that is where body is held.
+	if f.Op == OCLOSURE {
+		f = f.Func.Closure
+	}
+	v := reassignVisitor{name: n}
+	a := v.visitList(f.Nbody)
+	return a != nil, a
+}
+
+type reassignVisitor struct {
+	name *Node
+}
+
+func (v *reassignVisitor) visit(n *Node) *Node {
+	if n == nil {
+		return nil
+	}
+	switch n.Op {
+	case OAS:
+		if n.Left == v.name && n != v.name.Name.Defn {
+			return n
+		}
+		return nil
+	case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE:
+		for _, p := range n.List.Slice() {
+			if p == v.name && n != v.name.Name.Defn {
+				return n
+			}
+		}
+		return nil
+	}
+	if a := v.visit(n.Left); a != nil {
+		return a
+	}
+	if a := v.visit(n.Right); a != nil {
+		return a
+	}
+	if a := v.visitList(n.List); a != nil {
+		return a
+	}
+	if a := v.visitList(n.Rlist); a != nil {
+		return a
+	}
+	if a := v.visitList(n.Ninit); a != nil {
+		return a
+	}
+	if a := v.visitList(n.Nbody); a != nil {
+		return a
+	}
+	return nil
+}
+
+func (v *reassignVisitor) visitList(l Nodes) *Node {
+	for _, n := range l.Slice() {
+		if a := v.visit(n); a != nil {
+			return a
+		}
+	}
+	return nil
+}
+
 // The result of mkinlcall MUST be assigned back to n, e.g.
 // 	n.Left = mkinlcall(n.Left, fn, isddd)
 func mkinlcall(n *Node, fn *Node, isddd bool) *Node {
@@ -580,7 +768,7 @@
 // parameters.
 // The result of mkinlcall1 MUST be assigned back to n, e.g.
 // 	n.Left = mkinlcall1(n.Left, fn, isddd)
-func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
+func mkinlcall1(n, fn *Node, isddd bool) *Node {
 	if fn.Func.Inl.Len() == 0 {
 		// No inlinable body.
 		return n
@@ -591,7 +779,7 @@
 		return n
 	}
 
-	if Debug['l'] < 2 {
+	if Debug_typecheckinl == 0 {
 		typecheckinl(fn)
 	}
 
@@ -607,16 +795,56 @@
 
 	ninit := n.Ninit
 
+	// Make temp names to use instead of the originals.
+	inlvars := make(map[*Node]*Node)
+
+	// record formals/locals for later post-processing
+	var inlfvars []*Node
+
 	// Find declarations corresponding to inlineable body.
 	var dcl []*Node
 	if fn.Name.Defn != nil {
 		dcl = fn.Func.Inldcl.Slice() // local function
+
+		// handle captured variables when inlining closures
+		if c := fn.Name.Defn.Func.Closure; c != nil {
+			for _, v := range c.Func.Cvars.Slice() {
+				if v.Op == OXXX {
+					continue
+				}
+
+				o := v.Name.Param.Outer
+				// make sure the outer param matches the inlining location
+				// NB: if we enabled inlining of functions containing OCLOSURE or refined
+				// the reassigned check via some sort of copy propagation this would most
+				// likely need to be changed to a loop to walk up to the correct Param
+				if o == nil || (o.Name.Curfn != Curfn && o.Name.Curfn.Func.Closure != Curfn) {
+					Fatalf("%v: unresolvable capture %v %v\n", n.Line(), fn, v)
+				}
+
+				if v.Name.Byval() {
+					iv := typecheck(inlvar(v), Erv)
+					ninit.Append(nod(ODCL, iv, nil))
+					ninit.Append(typecheck(nod(OAS, iv, o), Etop))
+					inlvars[v] = iv
+				} else {
+					addr := newname(lookup("&" + v.Sym.Name))
+					addr.Type = types.NewPtr(v.Type)
+					ia := typecheck(inlvar(addr), Erv)
+					ninit.Append(nod(ODCL, ia, nil))
+					ninit.Append(typecheck(nod(OAS, ia, nod(OADDR, o, nil)), Etop))
+					inlvars[addr] = ia
+
+					// When capturing by reference, all occurrence of the captured var
+					// must be substituted with dereference of the temporary address
+					inlvars[v] = typecheck(nod(OIND, ia, nil), Erv)
+				}
+			}
+		}
 	} else {
 		dcl = fn.Func.Dcl // imported function
 	}
 
-	// Make temp names to use instead of the originals.
-	inlvars := make(map[*Node]*Node)
 	for _, ln := range dcl {
 		if ln.Op != ONAME {
 			continue
@@ -631,13 +859,25 @@
 		if ln.Class() == PPARAM || ln.Name.Param.Stackcopy != nil && ln.Name.Param.Stackcopy.Class() == PPARAM {
 			ninit.Append(nod(ODCL, inlvars[ln], nil))
 		}
+		if genDwarfInline > 0 {
+			inlf := inlvars[ln]
+			if ln.Class() == PPARAM {
+				inlf.SetInlFormal(true)
+			} else {
+				inlf.SetInlLocal(true)
+			}
+			inlf.Pos = ln.Pos
+			inlfvars = append(inlfvars, inlf)
+		}
 	}
 
 	// temporaries for return values.
 	var retvars []*Node
 	for i, t := range fn.Type.Results().Fields().Slice() {
 		var m *Node
+		var mpos src.XPos
 		if t != nil && asNode(t.Nname) != nil && !isblank(asNode(t.Nname)) {
+			mpos = asNode(t.Nname).Pos
 			m = inlvar(asNode(t.Nname))
 			m = typecheck(m, Erv)
 			inlvars[asNode(t.Nname)] = m
@@ -646,6 +886,17 @@
 			m = retvar(t, i)
 		}
 
+		if genDwarfInline > 0 {
+			// Don't update the src.Pos on a return variable if it
+			// was manufactured by the inliner (e.g. "~R2"); such vars
+			// were not part of the original callee.
+			if !strings.HasPrefix(m.Sym.Name, "~R") {
+				m.SetInlFormal(true)
+				m.Pos = mpos
+				inlfvars = append(inlfvars, m)
+			}
+		}
+
 		ninit.Append(nod(ODCL, m, nil))
 		retvars = append(retvars, m)
 	}
@@ -736,10 +987,25 @@
 
 	inlgen++
 
+	parent := -1
+	if b := Ctxt.PosTable.Pos(n.Pos).Base(); b != nil {
+		parent = b.InliningIndex()
+	}
+	newIndex := Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym())
+
+	if genDwarfInline > 0 {
+		if !fn.Sym.Linksym().WasInlined() {
+			Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn)
+			fn.Sym.Linksym().Set(obj.AttrWasInlined, true)
+		}
+	}
+
 	subst := inlsubst{
-		retlabel: retlabel,
-		retvars:  retvars,
-		inlvars:  inlvars,
+		retlabel:    retlabel,
+		retvars:     retvars,
+		inlvars:     inlvars,
+		bases:       make(map[*src.PosBase]*src.PosBase),
+		newInlIndex: newIndex,
 	}
 
 	body := subst.list(fn.Func.Inl)
@@ -749,6 +1015,12 @@
 
 	typecheckslice(body, Etop)
 
+	if genDwarfInline > 0 {
+		for _, v := range inlfvars {
+			v.Pos = subst.updatedPos(v.Pos)
+		}
+	}
+
 	//dumplist("ninit post", ninit);
 
 	call := nod(OINLCALL, nil, nil)
@@ -758,51 +1030,24 @@
 	call.Type = n.Type
 	call.SetTypecheck(1)
 
-	// Hide the args from setPos -- the parameters to the inlined
-	// call already have good line numbers that should be preserved.
-	args := as.Rlist
-	as.Rlist.Set(nil)
-
-	// Rewrite the line information for the inlined AST.
-	parent := -1
-	callBase := Ctxt.PosTable.Pos(n.Pos).Base()
-	if callBase != nil {
-		parent = callBase.InliningIndex()
-	}
-	newIndex := Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym())
-	setpos := &setPos{
-		bases:       make(map[*src.PosBase]*src.PosBase),
-		newInlIndex: newIndex,
-	}
-	setpos.node(call)
-
-	as.Rlist.Set(args.Slice())
-
-	//dumplist("call body", body);
-
-	n = call
-
 	// transitive inlining
 	// might be nice to do this before exporting the body,
 	// but can't emit the body with inlining expanded.
 	// instead we emit the things that the body needs
 	// and each use must redo the inlining.
 	// luckily these are small.
-	body = fn.Func.Inl.Slice()
-	fn.Func.Inl.Set(nil) // prevent infinite recursion (shouldn't happen anyway)
 	inlnodelist(call.Nbody)
 	for _, n := range call.Nbody.Slice() {
 		if n.Op == OINLCALL {
 			inlconv2stmt(n)
 		}
 	}
-	fn.Func.Inl.Set(body)
 
 	if Debug['m'] > 2 {
-		fmt.Printf("%v: After inlining %+v\n\n", n.Line(), n)
+		fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call)
 	}
 
-	return n
+	return call
 }
 
 // Every time we expand a function we generate a new set of tmpnames,
@@ -826,7 +1071,7 @@
 
 // Synthesize a variable to store the inlined function's results in.
 func retvar(t *types.Field, i int) *Node {
-	n := newname(lookupN("~r", i))
+	n := newname(lookupN("~R", i))
 	n.Type = t.Type
 	n.SetClass(PAUTO)
 	n.Name.SetUsed(true)
@@ -857,6 +1102,14 @@
 	retvars []*Node
 
 	inlvars map[*Node]*Node
+
+	// bases maps from original PosBase to PosBase with an extra
+	// inlined call frame.
+	bases map[*src.PosBase]*src.PosBase
+
+	// newInlIndex is the index of the inlined call frame to
+	// insert for inlined nodes.
+	newInlIndex int
 }
 
 // list inlines a list of nodes.
@@ -904,7 +1157,6 @@
 	//		dump("Return before substitution", n);
 	case ORETURN:
 		m := nod(OGOTO, subst.retlabel, nil)
-
 		m.Ninit.Set(subst.list(n.Ninit))
 
 		if len(subst.retvars) != 0 && n.List.Len() != 0 {
@@ -930,6 +1182,7 @@
 	case OGOTO, OLABEL:
 		m := nod(OXXX, nil, nil)
 		*m = *n
+		m.Pos = subst.updatedPos(m.Pos)
 		m.Ninit.Set(nil)
 		p := fmt.Sprintf("%s·%d", n.Left.Sym.Name, inlgen)
 		m.Left = newname(lookup(p))
@@ -939,6 +1192,7 @@
 
 	m := nod(OXXX, nil, nil)
 	*m = *n
+	m.Pos = subst.updatedPos(m.Pos)
 	m.Ninit.Set(nil)
 
 	if n.Op == OCLOSURE {
@@ -955,55 +1209,14 @@
 	return m
 }
 
-// setPos is a visitor to update position info with a new inlining index.
-type setPos struct {
-	bases       map[*src.PosBase]*src.PosBase
-	newInlIndex int
-}
-
-func (s *setPos) nodelist(ll Nodes) {
-	for _, n := range ll.Slice() {
-		s.node(n)
-	}
-}
-
-func (s *setPos) node(n *Node) {
-	if n == nil {
-		return
-	}
-	if n.Op == OLITERAL || n.Op == OTYPE {
-		if n.Sym != nil {
-			// This node is not a copy, so don't clobber position.
-			return
-		}
-	}
-
-	// don't clobber names, unless they're freshly synthesized
-	if n.Op != ONAME || !n.Pos.IsKnown() {
-		n.Pos = s.updatedPos(n)
-	}
-
-	s.node(n.Left)
-	s.node(n.Right)
-	s.nodelist(n.List)
-	s.nodelist(n.Rlist)
-	s.nodelist(n.Ninit)
-	s.nodelist(n.Nbody)
-}
-
-func (s *setPos) updatedPos(n *Node) src.XPos {
-	pos := Ctxt.PosTable.Pos(n.Pos)
+func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
+	pos := Ctxt.PosTable.Pos(xpos)
 	oldbase := pos.Base() // can be nil
-	newbase := s.bases[oldbase]
+	newbase := subst.bases[oldbase]
 	if newbase == nil {
-		newbase = src.NewInliningBase(oldbase, s.newInlIndex)
-		pos.SetBase(newbase)
-		s.bases[oldbase] = newbase
+		newbase = src.NewInliningBase(oldbase, subst.newInlIndex)
+		subst.bases[oldbase] = newbase
 	}
 	pos.SetBase(newbase)
 	return Ctxt.PosTable.XPos(pos)
 }
-
-func (n *Node) isMethodCalledAsFunction() bool {
-	return n.Left.Op == ONAME && n.Left.Left != nil && n.Left.Left.Op == OTYPE && n.Left.Right != nil && n.Left.Right.Op == ONAME
-}
diff --git a/src/cmd/compile/internal/gc/inl_test.go b/src/cmd/compile/internal/gc/inl_test.go
new file mode 100644
index 0000000..3e6da2e
--- /dev/null
+++ b/src/cmd/compile/internal/gc/inl_test.go
@@ -0,0 +1,215 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gc
+
+import (
+	"bufio"
+	"internal/testenv"
+	"io"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// TestIntendedInlining tests that specific runtime functions are inlined.
+// This allows refactoring for code clarity and re-use without fear that
+// changes to the compiler will cause silent performance regressions.
+func TestIntendedInlining(t *testing.T) {
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skip("skipping in short mode")
+	}
+	testenv.MustHaveGoRun(t)
+	t.Parallel()
+
+	// want is the list of function names (by package) that should
+	// be inlined.
+	want := map[string][]string{
+		"runtime": {
+			// TODO(mvdan): enable these once mid-stack
+			// inlining is available
+			// "adjustctxt",
+
+			"add",
+			"acquirem",
+			"add1",
+			"addb",
+			"adjustpanics",
+			"adjustpointer",
+			"bucketMask",
+			"bucketShift",
+			"chanbuf",
+			"deferArgs",
+			"deferclass",
+			"evacuated",
+			"fastlog2",
+			"fastrand",
+			"float64bits",
+			"funcPC",
+			"getm",
+			"isDirectIface",
+			"itabHashFunc",
+			"maxSliceCap",
+			"noescape",
+			"readUnaligned32",
+			"readUnaligned64",
+			"releasem",
+			"round",
+			"roundupsize",
+			"selectsize",
+			"stringStructOf",
+			"subtract1",
+			"subtractb",
+			"tophash",
+			"totaldefersize",
+			"(*bmap).keys",
+			"(*bmap).overflow",
+			"(*waitq).enqueue",
+
+			// GC-related ones
+			"cgoInRange",
+			"gclinkptr.ptr",
+			"guintptr.ptr",
+			"heapBits.bits",
+			"heapBits.isPointer",
+			"heapBits.morePointers",
+			"heapBits.next",
+			"heapBitsForAddr",
+			"inheap",
+			"markBits.isMarked",
+			"muintptr.ptr",
+			"puintptr.ptr",
+			"spanOfUnchecked",
+			"(*gcWork).putFast",
+			"(*gcWork).tryGetFast",
+			"(*guintptr).set",
+			"(*markBits).advance",
+			"(*mspan).allocBitsForIndex",
+			"(*mspan).base",
+			"(*mspan).markBitsForBase",
+			"(*mspan).markBitsForIndex",
+			"(*muintptr).set",
+			"(*puintptr).set",
+		},
+		"runtime/internal/sys": {},
+		"bytes": {
+			"(*Buffer).Bytes",
+			"(*Buffer).Cap",
+			"(*Buffer).Len",
+			"(*Buffer).Next",
+			"(*Buffer).Read",
+			"(*Buffer).ReadByte",
+			"(*Buffer).Reset",
+			"(*Buffer).String",
+			"(*Buffer).UnreadByte",
+			"(*Buffer).tryGrowByReslice",
+		},
+		"unicode/utf8": {
+			"FullRune",
+			"FullRuneInString",
+			"RuneLen",
+			"ValidRune",
+		},
+		"reflect": {
+			"Value.CanAddr",
+			"Value.CanSet",
+			"Value.IsValid",
+			"add",
+			"align",
+			"flag.kind",
+			"flag.ro",
+
+			// TODO: these use panic, need mid-stack
+			// inlining
+			// "Value.CanInterface",
+			// "Value.pointer",
+			// "flag.mustBe",
+			// "flag.mustBeAssignable",
+			// "flag.mustBeExported",
+		},
+		"regexp": {
+			"(*bitState).push",
+		},
+	}
+
+	if runtime.GOARCH != "386" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" {
+		// nextFreeFast calls sys.Ctz64, which on 386 is implemented in asm and is not inlinable.
+		// We currently don't have midstack inlining so nextFreeFast is also not inlinable on 386.
+		// On MIPS64x, Ctz64 is not intrinsified and causes nextFreeFast too expensive to inline
+		// (Issue 22239).
+		want["runtime"] = append(want["runtime"], "nextFreeFast")
+	}
+	if runtime.GOARCH != "386" {
+		// As explained above, Ctz64 and Ctz32 are not Go code on 386.
+		// The same applies to Bswap32.
+		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz64")
+		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz32")
+		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Bswap32")
+	}
+	switch runtime.GOARCH {
+	case "amd64", "amd64p32", "arm64", "mips64", "mips64le", "ppc64", "ppc64le", "s390x":
+		// rotl_31 is only defined on 64-bit architectures
+		want["runtime"] = append(want["runtime"], "rotl_31")
+	}
+
+	notInlinedReason := make(map[string]string)
+	pkgs := make([]string, 0, len(want))
+	for pname, fnames := range want {
+		pkgs = append(pkgs, pname)
+		for _, fname := range fnames {
+			fullName := pname + "." + fname
+			if _, ok := notInlinedReason[fullName]; ok {
+				t.Errorf("duplicate func: %s", fullName)
+			}
+			notInlinedReason[fullName] = "unknown reason"
+		}
+	}
+
+	args := append([]string{"build", "-a", "-gcflags=all=-m -m"}, pkgs...)
+	cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), args...))
+	pr, pw := io.Pipe()
+	cmd.Stdout = pw
+	cmd.Stderr = pw
+	cmdErr := make(chan error, 1)
+	go func() {
+		cmdErr <- cmd.Run()
+		pw.Close()
+	}()
+	scanner := bufio.NewScanner(pr)
+	curPkg := ""
+	canInline := regexp.MustCompile(`: can inline ([^ ]*)`)
+	cannotInline := regexp.MustCompile(`: cannot inline ([^ ]*): (.*)`)
+	for scanner.Scan() {
+		line := scanner.Text()
+		if strings.HasPrefix(line, "# ") {
+			curPkg = line[2:]
+			continue
+		}
+		if m := canInline.FindStringSubmatch(line); m != nil {
+			fname := m[1]
+			delete(notInlinedReason, curPkg+"."+fname)
+			continue
+		}
+		if m := cannotInline.FindStringSubmatch(line); m != nil {
+			fname, reason := m[1], m[2]
+			fullName := curPkg + "." + fname
+			if _, ok := notInlinedReason[fullName]; ok {
+				// cmd/compile gave us a reason why
+				notInlinedReason[fullName] = reason
+			}
+			continue
+		}
+	}
+	if err := <-cmdErr; err != nil {
+		t.Fatal(err)
+	}
+	if err := scanner.Err(); err != nil {
+		t.Fatal(err)
+	}
+	for fullName, reason := range notInlinedReason {
+		t.Errorf("%s was not inlined: %s", fullName, reason)
+	}
+}
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 2b61564..b651c9a 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -11,6 +11,7 @@
 	"bytes"
 	"cmd/compile/internal/ssa"
 	"cmd/compile/internal/types"
+	"cmd/internal/dwarf"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/src"
@@ -43,7 +44,12 @@
 	Debug_slice        int
 	Debug_vlog         bool
 	Debug_wb           int
+	Debug_eagerwb      int
 	Debug_pctab        string
+	Debug_locationlist int
+	Debug_typecheckinl int
+	Debug_gendwarfinl  int
+	Debug_softfloat    int
 )
 
 // Debug arguments.
@@ -67,8 +73,13 @@
 	{"slice", "print information about slice compilation", &Debug_slice},
 	{"typeassert", "print information about type assertion inlining", &Debug_typeassert},
 	{"wb", "print information about write barriers", &Debug_wb},
+	{"eagerwb", "use unbuffered write barrier", &Debug_eagerwb},
 	{"export", "print export data", &Debug_export},
 	{"pctab", "print named pc-value table", &Debug_pctab},
+	{"locationlists", "print information about DWARF location list creation", &Debug_locationlist},
+	{"typecheckinl", "eager typechecking of inline function bodies", &Debug_typecheckinl},
+	{"dwarfinl", "print information about DWARF inlined function creation", &Debug_gendwarfinl},
+	{"softfloat", "force compiler to emit soft-float code", &Debug_softfloat},
 }
 
 const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]
@@ -102,19 +113,6 @@
 	}
 }
 
-func doversion() {
-	p := objabi.Expstring()
-	if p == objabi.DefaultExpstring() {
-		p = ""
-	}
-	sep := ""
-	if p != "" {
-		sep = " "
-	}
-	fmt.Printf("compile version %s%s%s\n", objabi.Version, sep, p)
-	os.Exit(0)
-}
-
 // supportsDynlink reports whether or not the code generator for the given
 // architecture supports the -shared and -dynlink flags.
 func supportsDynlink(arch *sys.Arch) bool {
@@ -125,6 +123,8 @@
 var timings Timings
 var benchfile string
 
+var nowritebarrierrecCheck *nowritebarrierrecChecker
+
 // Main parses flags and Go source files specified in the command-line
 // arguments, type-checks the parsed Go package, compiles functions to machine
 // code, and finally writes the compiled package definition to disk.
@@ -137,6 +137,7 @@
 
 	Ctxt = obj.Linknew(thearch.LinkArch)
 	Ctxt.DiagFunc = yyerror
+	Ctxt.DiagFlush = flusherrors
 	Ctxt.Bso = bufio.NewWriter(os.Stdout)
 
 	localpkg = types.NewPkg("", "")
@@ -182,9 +183,10 @@
 	objabi.Flagcount("E", "debug symbol export", &Debug['E'])
 	objabi.Flagfn1("I", "add `directory` to import search path", addidir)
 	objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
+	objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
 	objabi.Flagcount("N", "disable optimizations", &Debug['N'])
 	flag.BoolVar(&Debug_asm, "S", false, "print assembly listing")
-	objabi.Flagfn0("V", "print compiler version", doversion)
+	objabi.AddVersionFlag() // -V
 	objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
 	flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`")
 	flag.StringVar(&buildid, "buildid", "", "record `id` as the build id in the export metadata")
@@ -192,6 +194,8 @@
 	flag.BoolVar(&pure_go, "complete", false, "compiling complete package (no C or assembly)")
 	flag.StringVar(&debugstr, "d", "", "print debug information about items in `list`; try -d help")
 	flag.BoolVar(&flagDWARF, "dwarf", true, "generate DWARF symbols")
+	flag.BoolVar(&Ctxt.Flag_locationlists, "dwarflocationlists", false, "add location lists to DWARF in optimized mode")
+	flag.IntVar(&genDwarfInline, "gendwarfinl", 2, "generate DWARF inline info records")
 	objabi.Flagcount("e", "no limit on number of errors reported", &Debug['e'])
 	objabi.Flagcount("f", "debug stack frames", &Debug['f'])
 	objabi.Flagcount("h", "halt on error", &Debug['h'])
@@ -235,6 +239,11 @@
 	flag.StringVar(&benchfile, "bench", "", "append benchmark times to `file`")
 	objabi.Flagparse(usage)
 
+	// Record flags that affect the build result. (And don't
+	// record flags that don't, since that would cause spurious
+	// changes in the binary.)
+	recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists")
+
 	Ctxt.Flag_shared = flag_dynlink || flag_shared
 	Ctxt.Flag_dynlink = flag_dynlink
 	Ctxt.Flag_optimize = Debug['N'] == 0
@@ -243,6 +252,11 @@
 	Ctxt.Debugvlog = Debug_vlog
 	if flagDWARF {
 		Ctxt.DebugInfo = debuginfo
+		Ctxt.GenAbstractFunc = genAbstractFunc
+		Ctxt.DwFixups = obj.NewDwarfFixupTable(Ctxt)
+	} else {
+		// turn off inline generation if no dwarf at all
+		genDwarfInline = 0
 	}
 
 	if flag.NArg() < 1 && debugstr != "help" && debugstr != "ssa/help" {
@@ -298,6 +312,9 @@
 	if nBackendWorkers > 1 && !concurrentBackendAllowed() {
 		log.Fatalf("cannot use concurrent backend compilation with provided flags; invoked as %v", os.Args)
 	}
+	if Ctxt.Flag_locationlists && len(Ctxt.Arch.DWARFRegisters) == 0 {
+		log.Fatalf("location lists requested but register mapping not available on %v", Ctxt.Arch.Name)
+	}
 
 	// parse -d argument
 	if debugstr != "" {
@@ -374,16 +391,29 @@
 
 	// set via a -d flag
 	Ctxt.Debugpcln = Debug_pctab
+	if flagDWARF {
+		dwarf.EnableLogging(Debug_gendwarfinl != 0)
+	}
+
+	if Debug_softfloat != 0 {
+		thearch.SoftFloat = true
+	}
 
 	// enable inlining.  for now:
 	//	default: inlining on.  (debug['l'] == 1)
 	//	-l: inlining off  (debug['l'] == 0)
-	//	-ll, -lll: inlining on again, with extra debugging (debug['l'] > 1)
+	//	-l=2, -l=3: inlining on again, with extra debugging (debug['l'] > 1)
 	if Debug['l'] <= 1 {
 		Debug['l'] = 1 - Debug['l']
 	}
 
-	trackScopes = flagDWARF && Debug['l'] == 0 && Debug['N'] != 0
+	// The buffered write barrier is only implemented on amd64
+	// right now.
+	if objabi.GOARCH != "amd64" {
+		Debug_eagerwb = 1
+	}
+
+	trackScopes = flagDWARF && ((Debug['l'] == 0 && Debug['N'] != 0) || Ctxt.Flag_locationlists)
 
 	Widthptr = thearch.LinkArch.PtrSize
 	Widthreg = thearch.LinkArch.RegSize
@@ -488,6 +518,8 @@
 			fcount++
 		}
 	}
+	// With all types ckecked, it's now safe to verify map keys.
+	checkMapKeys()
 	timings.AddEvent(fcount, "funcs")
 
 	// Phase 4: Decide how to capture closed variables.
@@ -510,7 +542,7 @@
 
 	// Phase 5: Inlining
 	timings.Start("fe", "inlining")
-	if Debug['l'] > 1 {
+	if Debug_typecheckinl != 0 {
 		// Typecheck imported function bodies if debug['l'] > 1,
 		// otherwise lazily when used or re-exported.
 		for _, n := range importlist {
@@ -553,6 +585,14 @@
 	escapes(xtop)
 
 	if dolinkobj {
+		// Collect information for go:nowritebarrierrec
+		// checking. This must happen before transformclosure.
+		// We'll do the final check after write barriers are
+		// inserted.
+		if compiling_runtime {
+			nowritebarrierrecCheck = newNowritebarrierrecChecker()
+		}
+
 		// Phase 7: Transform closure bodies to properly reference captured variables.
 		// This needs to happen before walk, because closures must be transformed
 		// before walk reaches a call of a closure.
@@ -601,8 +641,20 @@
 		// at least until this convoluted structure has been unwound.
 		nBackendWorkers = 1
 
-		if compiling_runtime {
-			checknowritebarrierrec()
+		if nowritebarrierrecCheck != nil {
+			// Write barriers are now known. Check the
+			// call graph.
+			nowritebarrierrecCheck.check()
+			nowritebarrierrecCheck = nil
+		}
+
+		// Finalize DWARF inline routine DIEs, then explicitly turn off
+		// DWARF inlining gen so as to avoid problems with generated
+		// method wrappers.
+		if Ctxt.DwFixups != nil {
+			Ctxt.DwFixups.Finalize(myimportpath, Debug_gendwarfinl != 0)
+			Ctxt.DwFixups = nil
+			genDwarfInline = 0
 		}
 
 		// Check whether any of the functions we have compiled have gigantic stack frames.
@@ -610,7 +662,7 @@
 			return largeStackFrames[i].Before(largeStackFrames[j])
 		})
 		for _, largePos := range largeStackFrames {
-			yyerrorl(largePos, "stack frame too large (>2GB)")
+			yyerrorl(largePos, "stack frame too large (>1GB)")
 		}
 	}
 
@@ -763,7 +815,7 @@
 	return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
 }
 
-// is this path a local name?  begins with ./ or ../ or /
+// is this path a local name? begins with ./ or ../ or /
 func islocalname(name string) bool {
 	return strings.HasPrefix(name, "/") ||
 		runtime.GOOS == "windows" && len(name) >= 3 && isDriveLetter(name[0]) && name[1] == ':' && name[2] == '/' ||
@@ -868,7 +920,7 @@
 			n.Type = typ
 			declare(n, PFUNC)
 		case varTag:
-			importvar(Runtimepkg, sym, typ)
+			importvar(lineno, Runtimepkg, sym, typ)
 		default:
 			Fatalf("unhandled declaration tag %v", d.tag)
 		}
@@ -1178,8 +1230,8 @@
 	if Debug_vlog || debugstr != "" || debuglive > 0 {
 		return false
 	}
-	// TODO: test and add builders for GOEXPERIMENT values, and enable
-	if os.Getenv("GOEXPERIMENT") != "" {
+	// TODO: Test and delete these conditions.
+	if objabi.Fieldtrack_enabled != 0 || objabi.Preemptibleloops_enabled != 0 || objabi.Clobberdead_enabled != 0 {
 		return false
 	}
 	// TODO: fix races and enable the following flags
@@ -1188,3 +1240,58 @@
 	}
 	return true
 }
+
+// recordFlags records the specified command-line flags to be placed
+// in the DWARF info.
+func recordFlags(flags ...string) {
+	if myimportpath == "" {
+		// We can't record the flags if we don't know what the
+		// package name is.
+		return
+	}
+
+	type BoolFlag interface {
+		IsBoolFlag() bool
+	}
+	type CountFlag interface {
+		IsCountFlag() bool
+	}
+	var cmd bytes.Buffer
+	for _, name := range flags {
+		f := flag.Lookup(name)
+		if f == nil {
+			continue
+		}
+		getter := f.Value.(flag.Getter)
+		if getter.String() == f.DefValue {
+			// Flag has default value, so omit it.
+			continue
+		}
+		if bf, ok := f.Value.(BoolFlag); ok && bf.IsBoolFlag() {
+			val, ok := getter.Get().(bool)
+			if ok && val {
+				fmt.Fprintf(&cmd, " -%s", f.Name)
+				continue
+			}
+		}
+		if cf, ok := f.Value.(CountFlag); ok && cf.IsCountFlag() {
+			val, ok := getter.Get().(int)
+			if ok && val == 1 {
+				fmt.Fprintf(&cmd, " -%s", f.Name)
+				continue
+			}
+		}
+		fmt.Fprintf(&cmd, " -%s=%v", f.Name, getter.Get())
+	}
+
+	if cmd.Len() == 0 {
+		return
+	}
+	s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + myimportpath)
+	s.Type = objabi.SDWARFINFO
+	// Sometimes (for example when building tests) we can link
+	// together two package main archives. So allow dups.
+	s.Set(obj.AttrDuplicateOK, true)
+	Ctxt.Data = append(Ctxt.Data, s)
+	s.P = cmd.Bytes()[1:]
+}
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index 3977be1..6f32e52 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -7,6 +7,8 @@
 import (
 	"fmt"
 	"os"
+	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 	"unicode/utf8"
@@ -18,14 +20,17 @@
 )
 
 func parseFiles(filenames []string) uint {
-	var lines uint
 	var noders []*noder
+	// Limit the number of simultaneously open files.
+	sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)
 
 	for _, filename := range filenames {
 		p := &noder{err: make(chan syntax.Error)}
 		noders = append(noders, p)
 
 		go func(filename string) {
+			sem <- struct{}{}
+			defer func() { <-sem }()
 			defer close(p.err)
 			base := src.NewFileBase(filename, absFilename(filename))
 
@@ -36,10 +41,11 @@
 			}
 			defer f.Close()
 
-			p.file, _ = syntax.Parse(base, f, p.error, p.pragma, syntax.CheckBranches) // errors are tracked via p.error
+			p.file, _ = syntax.Parse(base, f, p.error, p.pragma, fileh, syntax.CheckBranches) // errors are tracked via p.error
 		}(filename)
 	}
 
+	var lines uint
 	for _, p := range noders {
 		for e := range p.err {
 			yyerrorpos(e.Pos, "%s", e.Msg)
@@ -65,6 +71,10 @@
 
 var pathPrefix string
 
+func fileh(name string) string {
+	return objabi.AbsFile("", name, pathPrefix)
+}
+
 func absFilename(name string) string {
 	return objabi.AbsFile(Ctxt.Pathname, name, pathPrefix)
 }
@@ -78,15 +88,15 @@
 	scope      ScopeID
 }
 
-func (p *noder) funchdr(n *Node, pos src.Pos) ScopeID {
+func (p *noder) funchdr(n *Node) ScopeID {
 	old := p.scope
 	p.scope = 0
 	funchdr(n)
 	return old
 }
 
-func (p *noder) funcbody(n *Node, pos src.Pos, old ScopeID) {
-	funcbody(n)
+func (p *noder) funcbody(old ScopeID) {
+	funcbody()
 	p.scope = old
 }
 
@@ -215,15 +225,14 @@
 	pack.Sym = my
 	pack.Name.Pkg = ipkg
 
-	if my.Name == "." {
+	switch my.Name {
+	case ".":
 		importdot(ipkg, pack)
 		return
-	}
-	if my.Name == "init" {
+	case "init":
 		yyerrorl(pack.Pos, "cannot import package as init - init must be a func")
 		return
-	}
-	if my.Name == "_" {
+	case "_":
 		return
 	}
 	if my.Def != nil {
@@ -313,7 +322,6 @@
 	n := p.declName(decl.Name)
 	n.Op = OTYPE
 	declare(n, dclcontext)
-	n.SetLocal(true)
 
 	// decl.Type may be nil but in that case we got a syntax error during parsing
 	typ := p.typeExprOrNil(decl.Type)
@@ -382,9 +390,8 @@
 		declare(f.Func.Nname, PFUNC)
 	}
 
-	oldScope := p.funchdr(f, fun.Pos())
+	oldScope := p.funchdr(f)
 
-	endPos := fun.Pos()
 	if fun.Body != nil {
 		if f.Noescape() {
 			yyerrorl(f.Pos, "can only use //go:noescape with external func implementations")
@@ -396,16 +403,15 @@
 		}
 		f.Nbody.Set(body)
 
-		endPos = fun.Body.Rbrace
 		lineno = Ctxt.PosTable.XPos(fun.Body.Rbrace)
 		f.Func.Endlineno = lineno
 	} else {
 		if pure_go || strings.HasPrefix(f.funcname(), "init.") {
-			yyerrorl(f.Pos, "missing function body for %q", f.funcname())
+			yyerrorl(f.Pos, "missing function body")
 		}
 	}
 
-	p.funcbody(f, endPos, oldScope)
+	p.funcbody(oldScope)
 	return f
 }
 
@@ -532,6 +538,9 @@
 		// ntype? Shrug, doesn't matter here.
 		return p.nod(expr, ODOTTYPE, p.expr(expr.X), p.expr(expr.Type))
 	case *syntax.Operation:
+		if expr.Op == syntax.Add && expr.Y != nil {
+			return p.sum(expr)
+		}
 		x := p.expr(expr.X)
 		if expr.Y == nil {
 			if expr.Op == syntax.And {
@@ -592,6 +601,82 @@
 	panic("unhandled Expr")
 }
 
+// sum efficiently handles very large summation expressions (such as
+// in issue #16394). In particular, it avoids left recursion and
+// collapses string literals.
+func (p *noder) sum(x syntax.Expr) *Node {
+	// While we need to handle long sums with asymptotic
+	// efficiency, the vast majority of sums are very small: ~95%
+	// have only 2 or 3 operands, and ~99% of string literals are
+	// never concatenated.
+
+	adds := make([]*syntax.Operation, 0, 2)
+	for {
+		add, ok := x.(*syntax.Operation)
+		if !ok || add.Op != syntax.Add || add.Y == nil {
+			break
+		}
+		adds = append(adds, add)
+		x = add.X
+	}
+
+	// nstr is the current rightmost string literal in the
+	// summation (if any), and chunks holds its accumulated
+	// substrings.
+	//
+	// Consider the expression x + "a" + "b" + "c" + y. When we
+	// reach the string literal "a", we assign nstr to point to
+	// its corresponding Node and initialize chunks to {"a"}.
+	// Visiting the subsequent string literals "b" and "c", we
+	// simply append their values to chunks. Finally, when we
+	// reach the non-constant operand y, we'll join chunks to form
+	// "abc" and reassign the "a" string literal's value.
+	//
+	// N.B., we need to be careful about named string constants
+	// (indicated by Sym != nil) because 1) we can't modify their
+	// value, as doing so would affect other uses of the string
+	// constant, and 2) they may have types, which we need to
+	// handle correctly. For now, we avoid these problems by
+	// treating named string constants the same as non-constant
+	// operands.
+	var nstr *Node
+	chunks := make([]string, 0, 1)
+
+	n := p.expr(x)
+	if Isconst(n, CTSTR) && n.Sym == nil {
+		nstr = n
+		chunks = append(chunks, nstr.Val().U.(string))
+	}
+
+	for i := len(adds) - 1; i >= 0; i-- {
+		add := adds[i]
+
+		r := p.expr(add.Y)
+		if Isconst(r, CTSTR) && r.Sym == nil {
+			if nstr != nil {
+				// Collapse r into nstr instead of adding to n.
+				chunks = append(chunks, r.Val().U.(string))
+				continue
+			}
+
+			nstr = r
+			chunks = append(chunks, nstr.Val().U.(string))
+		} else {
+			if len(chunks) > 1 {
+				nstr.SetVal(Val{U: strings.Join(chunks, "")})
+			}
+			nstr = nil
+			chunks = chunks[:0]
+		}
+		n = p.nod(add, OADD, n, r)
+	}
+	if len(chunks) > 1 {
+		nstr.SetVal(Val{U: strings.Join(chunks, "")})
+	}
+
+	return n
+}
+
 func (p *noder) typeExpr(typ syntax.Expr) *Node {
 	// TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
 	return p.expr(typ)
@@ -691,7 +776,11 @@
 		}
 		typ = op.X
 	}
-	n := embedded(p.packname(typ), localpkg)
+
+	sym := p.packname(typ)
+	n := nod(ODCLFIELD, newname(lookup(sym.Name)), oldname(sym))
+	n.SetEmbedded(true)
+
 	if isStar {
 		n.Right = p.nod(op, OIND, n.Right, nil)
 	}
@@ -699,9 +788,13 @@
 }
 
 func (p *noder) stmts(stmts []syntax.Stmt) []*Node {
+	return p.stmtsFall(stmts, false)
+}
+
+func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*Node {
 	var nodes []*Node
-	for _, stmt := range stmts {
-		s := p.stmt(stmt)
+	for i, stmt := range stmts {
+		s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
 		if s == nil {
 		} else if s.Op == OBLOCK && s.Ninit.Len() == 0 {
 			nodes = append(nodes, s.List.Slice()...)
@@ -713,12 +806,16 @@
 }
 
 func (p *noder) stmt(stmt syntax.Stmt) *Node {
+	return p.stmtFall(stmt, false)
+}
+
+func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
 	p.lineno(stmt)
 	switch stmt := stmt.(type) {
 	case *syntax.EmptyStmt:
 		return nil
 	case *syntax.LabeledStmt:
-		return p.labeledStmt(stmt)
+		return p.labeledStmt(stmt, fallOK)
 	case *syntax.BlockStmt:
 		l := p.blockStmt(stmt)
 		if len(l) == 0 {
@@ -740,15 +837,10 @@
 			return n
 		}
 
-		lhs := p.exprList(stmt.Lhs)
-		rhs := p.exprList(stmt.Rhs)
-
 		n := p.nod(stmt, OAS, nil, nil) // assume common case
 
-		if stmt.Op == syntax.Def {
-			n.SetColas(true)
-			colasdefn(lhs, n) // modifies lhs, call before using lhs[0] in common case
-		}
+		rhs := p.exprList(stmt.Rhs)
+		lhs := p.assignList(stmt.Lhs, n, stmt.Op == syntax.Def)
 
 		if len(lhs) == 1 && len(rhs) == 1 {
 			// common case
@@ -769,7 +861,10 @@
 		case syntax.Continue:
 			op = OCONTINUE
 		case syntax.Fallthrough:
-			op = OXFALL
+			if !fallOK {
+				yyerror("fallthrough statement out of place")
+			}
+			op = OFALL
 		case syntax.Goto:
 			op = OGOTO
 		default:
@@ -779,9 +874,6 @@
 		if stmt.Label != nil {
 			n.Left = p.newname(stmt.Label)
 		}
-		if op == OXFALL {
-			n.Xoffset = int64(types.Block)
-		}
 		return n
 	case *syntax.CallStmt:
 		var op Op
@@ -827,6 +919,66 @@
 	panic("unhandled Stmt")
 }
 
+func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
+	if !colas {
+		return p.exprList(expr)
+	}
+
+	defn.SetColas(true)
+
+	var exprs []syntax.Expr
+	if list, ok := expr.(*syntax.ListExpr); ok {
+		exprs = list.ElemList
+	} else {
+		exprs = []syntax.Expr{expr}
+	}
+
+	res := make([]*Node, len(exprs))
+	seen := make(map[*types.Sym]bool, len(exprs))
+
+	newOrErr := false
+	for i, expr := range exprs {
+		p.lineno(expr)
+		res[i] = nblank
+
+		name, ok := expr.(*syntax.Name)
+		if !ok {
+			yyerrorpos(expr.Pos(), "non-name %v on left side of :=", p.expr(expr))
+			newOrErr = true
+			continue
+		}
+
+		sym := p.name(name)
+		if sym.IsBlank() {
+			continue
+		}
+
+		if seen[sym] {
+			yyerrorpos(expr.Pos(), "%v repeated on left side of :=", sym)
+			newOrErr = true
+			continue
+		}
+		seen[sym] = true
+
+		if sym.Block == types.Block {
+			res[i] = oldname(sym)
+			continue
+		}
+
+		newOrErr = true
+		n := newname(sym)
+		declare(n, dclcontext)
+		n.Name.Defn = defn
+		defn.Ninit.Append(nod(ODCL, n, nil))
+		res[i] = n
+	}
+
+	if !newOrErr {
+		yyerrorl(defn.Pos, "no new variables on left side of :=")
+	}
+	return res
+}
+
 func (p *noder) blockStmt(stmt *syntax.BlockStmt) []*Node {
 	p.openScope(stmt.Pos())
 	nodes := p.stmts(stmt.List)
@@ -866,12 +1018,7 @@
 
 		n = p.nod(r, ORANGE, nil, p.expr(r.X))
 		if r.Lhs != nil {
-			lhs := p.exprList(r.Lhs)
-			n.List.Set(lhs)
-			if r.Def {
-				n.SetColas(true)
-				colasdefn(lhs, n)
-			}
+			n.List.Set(p.assignList(r.Lhs, n, r.Def))
 		}
 	} else {
 		n = p.nod(stmt, OFOR, nil, nil)
@@ -901,7 +1048,7 @@
 	}
 
 	tswitch := n.Left
-	if tswitch != nil && (tswitch.Op != OTYPESW || tswitch.Left == nil) {
+	if tswitch != nil && tswitch.Op != OTYPESW {
 		tswitch = nil
 	}
 	n.List.Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace))
@@ -923,15 +1070,35 @@
 		if clause.Cases != nil {
 			n.List.Set(p.exprList(clause.Cases))
 		}
-		if tswitch != nil {
+		if tswitch != nil && tswitch.Left != nil {
 			nn := newname(tswitch.Left.Sym)
 			declare(nn, dclcontext)
 			n.Rlist.Set1(nn)
 			// keep track of the instances for reporting unused
 			nn.Name.Defn = tswitch
 		}
-		n.Xoffset = int64(types.Block)
-		n.Nbody.Set(p.stmts(clause.Body))
+
+		// Trim trailing empty statements. We omit them from
+		// the Node AST anyway, and it's easier to identify
+		// out-of-place fallthrough statements without them.
+		body := clause.Body
+		for len(body) > 0 {
+			if _, ok := body[len(body)-1].(*syntax.EmptyStmt); !ok {
+				break
+			}
+			body = body[:len(body)-1]
+		}
+
+		n.Nbody.Set(p.stmtsFall(body, true))
+		if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == OFALL {
+			if tswitch != nil {
+				yyerror("cannot fallthrough in type switch")
+			}
+			if i+1 == len(clauses) {
+				yyerror("cannot fallthrough final case in switch")
+			}
+		}
+
 		nodes = append(nodes, n)
 	}
 	if len(clauses) > 0 {
@@ -959,7 +1126,6 @@
 		if clause.Comm != nil {
 			n.List.Set1(p.stmt(clause.Comm))
 		}
-		n.Xoffset = int64(types.Block)
 		n.Nbody.Set(p.stmts(clause.Body))
 		nodes = append(nodes, n)
 	}
@@ -969,12 +1135,12 @@
 	return nodes
 }
 
-func (p *noder) labeledStmt(label *syntax.LabeledStmt) *Node {
+func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
 	lhs := p.nod(label, OLABEL, p.newname(label.Label), nil)
 
 	var ls *Node
 	if label.Stmt != nil { // TODO(mdempsky): Should always be present.
-		ls = p.stmt(label.Stmt)
+		ls = p.stmtFall(label.Stmt, fallOK)
 	}
 
 	lhs.Name.Defn = ls
@@ -1180,7 +1346,26 @@
 		}
 		p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
 
+	case strings.HasPrefix(text, "go:cgo_import_dynamic "):
+		// This is permitted for general use because Solaris
+		// code relies on it in golang.org/x/sys/unix and others.
+		fields := pragmaFields(text)
+		if len(fields) >= 4 {
+			lib := strings.Trim(fields[3], `"`)
+			if lib != "" && !safeArg(lib) && !isCgoGeneratedFile(pos) {
+				p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("invalid library name %q in cgo_import_dynamic directive", lib)})
+			}
+			p.pragcgobuf += p.pragcgo(pos, text)
+			return pragmaValue("go:cgo_import_dynamic")
+		}
+		fallthrough
 	case strings.HasPrefix(text, "go:cgo_"):
+		// For security, we disallow //go:cgo_* directives other
+		// than cgo_import_dynamic outside cgo-generated files.
+		// Exception: they are allowed in the standard library, for runtime and syscall.
+		if !isCgoGeneratedFile(pos) && !compiling_std {
+			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
+		}
 		p.pragcgobuf += p.pragcgo(pos, text)
 		fallthrough // because of //go:cgo_unsafe_args
 	default:
@@ -1202,6 +1387,28 @@
 	return 0
 }
 
+// isCgoGeneratedFile reports whether pos is in a file
+// generated by cgo, which is to say a file with name
+// beginning with "_cgo_". Such files are allowed to
+// contain cgo directives, and for security reasons
+// (primarily misuse of linker flags), other files are not.
+// See golang.org/issue/23672.
+func isCgoGeneratedFile(pos src.Pos) bool {
+	return strings.HasPrefix(filepath.Base(filepath.Clean(pos.AbsFilename())), "_cgo_")
+}
+
+// safeArg reports whether arg is a "safe" command-line argument,
+// meaning that when it appears in a command-line, it probably
+// doesn't have some special meaning other than its own name.
+// This is copied from SafeArg in cmd/go/internal/load/pkg.go.
+func safeArg(name string) bool {
+	if name == "" {
+		return false
+	}
+	c := name[0]
+	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
+}
+
 func mkname(sym *types.Sym) *Node {
 	n := oldname(sym)
 	if n.Name != nil && n.Name.Pack != nil {
diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go
index 83e64e7..874c59c 100644
--- a/src/cmd/compile/internal/gc/obj.go
+++ b/src/cmd/compile/internal/gc/obj.go
@@ -9,6 +9,7 @@
 	"cmd/internal/bio"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
+	"cmd/internal/src"
 	"crypto/sha256"
 	"fmt"
 	"io"
@@ -16,9 +17,7 @@
 )
 
 // architecture-independent object file output
-const (
-	ArhdrSize = 60
-)
+const ArhdrSize = 60
 
 func formathdr(arhdr []byte, name string, size int64) {
 	copy(arhdr[:], fmt.Sprintf("%-16s%-12d%-6d%-6d%-8o%-10d`\n", name, 0, 0, 0, 0644, size))
@@ -56,13 +55,13 @@
 }
 
 func dumpobj1(outfile string, mode int) {
-	var err error
-	bout, err = bio.Create(outfile)
+	bout, err := bio.Create(outfile)
 	if err != nil {
 		flusherrors()
 		fmt.Printf("can't create %s: %v\n", outfile, err)
 		errorexit()
 	}
+	defer bout.Close()
 
 	startobj := int64(0)
 	var arhdr [ArhdrSize]byte
@@ -92,7 +91,7 @@
 	printheader()
 
 	if mode&modeCompilerObj != 0 {
-		dumpexport()
+		dumpexport(bout)
 	}
 
 	if writearchive {
@@ -109,7 +108,6 @@
 	}
 
 	if mode&modeLinkerObj == 0 {
-		bout.Close()
 		return
 	}
 
@@ -171,8 +169,6 @@
 		formathdr(arhdr[:], "_go_.o", size)
 		bout.Write(arhdr[:])
 	}
-
-	bout.Close()
 }
 
 func addptabs() {
@@ -204,24 +200,68 @@
 	}
 }
 
+func dumpGlobal(n *Node) {
+	if n.Type == nil {
+		Fatalf("external %v nil type\n", n)
+	}
+	if n.Class() == PFUNC {
+		return
+	}
+	if n.Sym.Pkg != localpkg {
+		return
+	}
+	dowidth(n.Type)
+	ggloblnod(n)
+}
+
+func dumpGlobalConst(n *Node) {
+	// only export typed constants
+	t := n.Type
+	if t == nil {
+		return
+	}
+	if n.Sym.Pkg != localpkg {
+		return
+	}
+	// only export integer constants for now
+	switch t.Etype {
+	case TINT8:
+	case TINT16:
+	case TINT32:
+	case TINT64:
+	case TINT:
+	case TUINT8:
+	case TUINT16:
+	case TUINT32:
+	case TUINT64:
+	case TUINT:
+	case TUINTPTR:
+		// ok
+	case TIDEAL:
+		if !Isconst(n, CTINT) {
+			return
+		}
+		x := n.Val().U.(*Mpint)
+		if x.Cmp(minintval[TINT]) < 0 || x.Cmp(maxintval[TINT]) > 0 {
+			return
+		}
+		// Ideal integers we export as int (if they fit).
+		t = types.Types[TINT]
+	default:
+		return
+	}
+	Ctxt.DwarfIntConst(myimportpath, n.Sym.Name, typesymname(t), n.Int64())
+}
+
 func dumpglobls() {
 	// add globals
 	for _, n := range externdcl {
-		if n.Op != ONAME {
-			continue
+		switch n.Op {
+		case ONAME:
+			dumpGlobal(n)
+		case OLITERAL:
+			dumpGlobalConst(n)
 		}
-
-		if n.Type == nil {
-			Fatalf("external %v nil type\n", n)
-		}
-		if n.Class() == PFUNC {
-			continue
-		}
-		if n.Sym.Pkg != localpkg {
-			continue
-		}
-		dowidth(n.Type)
-		ggloblnod(n)
 	}
 
 	obj.SortSlice(funcsyms, func(i, j int) bool {
@@ -291,7 +331,7 @@
 	return off
 }
 
-func stringsym(s string) (data *obj.LSym) {
+func stringsym(pos src.XPos, s string) (data *obj.LSym) {
 	var symname string
 	if len(s) > 100 {
 		// Huge strings are hashed to avoid long names in object files.
@@ -312,7 +352,7 @@
 
 	if !symdata.SeenGlobl() {
 		// string data
-		off := dsname(symdata, 0, s)
+		off := dsname(symdata, 0, s, pos, "string")
 		ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
 	}
 
@@ -328,7 +368,7 @@
 	sym.Def = asTypesNode(newname(sym))
 
 	lsym := sym.Linksym()
-	off := dsname(lsym, 0, s)
+	off := dsname(lsym, 0, s, nam.Pos, "slice")
 	ggloblsym(lsym, int32(off), obj.NOPTR|obj.LOCAL)
 
 	if nam.Op != ONAME {
@@ -341,7 +381,15 @@
 	duintptr(nsym, off, uint64(len))
 }
 
-func dsname(s *obj.LSym, off int, t string) int {
+func dsname(s *obj.LSym, off int, t string, pos src.XPos, what string) int {
+	// Objects that are too large will cause the data section to overflow right away,
+	// causing a cryptic error message by the linker. Check for oversize objects here
+	// and provide a useful error message instead.
+	if int64(len(t)) > 2e9 {
+		yyerrorl(pos, "%v with length %v is too big", what, len(t))
+		return 0
+	}
+
 	s.WriteString(Ctxt, int64(off), len(t), t)
 	return off + len(t)
 }
@@ -406,7 +454,7 @@
 			}
 
 		case string:
-			symdata := stringsym(u)
+			symdata := stringsym(nam.Pos, u)
 			s.WriteAddr(Ctxt, nam.Xoffset, Widthptr, symdata, 0)
 			s.WriteInt(Ctxt, nam.Xoffset+int64(Widthptr), Widthptr, int64(len(u)))
 
diff --git a/src/cmd/compile/internal/gc/op_string.go b/src/cmd/compile/internal/gc/op_string.go
new file mode 100644
index 0000000..2d47727
--- /dev/null
+++ b/src/cmd/compile/internal/gc/op_string.go
@@ -0,0 +1,16 @@
+// Code generated by "stringer -type=Op -trimprefix=O"; DO NOT EDIT.
+
+package gc
+
+import "fmt"
+
+const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDARRAYBYTESTRARRAYBYTESTRTMPARRAYRUNESTRSTRARRAYBYTESTRARRAYBYTETMPSTRARRAYRUNEASAS2AS2FUNCAS2RECVAS2MAPRAS2DOTTYPEASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECMPIFACECMPSTRCOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTINDINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNOTCOMPLUSMINUSORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASEXCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELPROCRANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDDDDARGINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARKILLVARLIVEINDREGSPRETJMPGETGEND"
+
+var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 73, 88, 100, 112, 127, 139, 141, 144, 151, 158, 165, 175, 179, 183, 191, 199, 208, 216, 219, 224, 231, 239, 245, 252, 258, 267, 275, 283, 289, 293, 302, 309, 313, 316, 323, 331, 339, 346, 352, 355, 361, 368, 376, 380, 387, 395, 397, 399, 401, 403, 405, 407, 410, 415, 423, 426, 435, 438, 442, 450, 457, 466, 469, 472, 475, 478, 481, 484, 490, 493, 496, 499, 503, 508, 512, 517, 522, 528, 533, 537, 542, 550, 558, 564, 573, 580, 584, 591, 598, 606, 610, 614, 618, 625, 632, 640, 646, 651, 656, 660, 665, 673, 678, 683, 687, 690, 698, 702, 704, 709, 713, 718, 724, 730, 736, 742, 747, 751, 758, 764, 769, 775, 778, 784, 791, 796, 800, 805, 809, 819, 824, 832, 839, 846, 854, 860, 864, 867}
+
+func (i Op) String() string {
+	if i >= Op(len(_Op_index)-1) {
+		return fmt.Sprintf("Op(%d)", i)
+	}
+	return _Op_name[_Op_index[i]:_Op_index[i+1]]
+}
diff --git a/src/cmd/compile/internal/gc/opnames.go b/src/cmd/compile/internal/gc/opnames.go
deleted file mode 100644
index 09442b5..0000000
--- a/src/cmd/compile/internal/gc/opnames.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.
-
-package gc
-
-// auto generated by go tool dist
-var opnames = []string{
-	OXXX:             "XXX",
-	ONAME:            "NAME",
-	ONONAME:          "NONAME",
-	OTYPE:            "TYPE",
-	OPACK:            "PACK",
-	OLITERAL:         "LITERAL",
-	OADD:             "ADD",
-	OSUB:             "SUB",
-	OOR:              "OR",
-	OXOR:             "XOR",
-	OADDSTR:          "ADDSTR",
-	OADDR:            "ADDR",
-	OANDAND:          "ANDAND",
-	OAPPEND:          "APPEND",
-	OARRAYBYTESTR:    "ARRAYBYTESTR",
-	OARRAYBYTESTRTMP: "ARRAYBYTESTRTMP",
-	OARRAYRUNESTR:    "ARRAYRUNESTR",
-	OSTRARRAYBYTE:    "STRARRAYBYTE",
-	OSTRARRAYBYTETMP: "STRARRAYBYTETMP",
-	OSTRARRAYRUNE:    "STRARRAYRUNE",
-	OAS:              "AS",
-	OAS2:             "AS2",
-	OAS2FUNC:         "AS2FUNC",
-	OAS2RECV:         "AS2RECV",
-	OAS2MAPR:         "AS2MAPR",
-	OAS2DOTTYPE:      "AS2DOTTYPE",
-	OASOP:            "ASOP",
-	OCALL:            "CALL",
-	OCALLFUNC:        "CALLFUNC",
-	OCALLMETH:        "CALLMETH",
-	OCALLINTER:       "CALLINTER",
-	OCALLPART:        "CALLPART",
-	OCAP:             "CAP",
-	OCLOSE:           "CLOSE",
-	OCLOSURE:         "CLOSURE",
-	OCMPIFACE:        "CMPIFACE",
-	OCMPSTR:          "CMPSTR",
-	OCOMPLIT:         "COMPLIT",
-	OMAPLIT:          "MAPLIT",
-	OSTRUCTLIT:       "STRUCTLIT",
-	OARRAYLIT:        "ARRAYLIT",
-	OSLICELIT:        "SLICELIT",
-	OPTRLIT:          "PTRLIT",
-	OCONV:            "CONV",
-	OCONVIFACE:       "CONVIFACE",
-	OCONVNOP:         "CONVNOP",
-	OCOPY:            "COPY",
-	ODCL:             "DCL",
-	ODCLFUNC:         "DCLFUNC",
-	ODCLFIELD:        "DCLFIELD",
-	ODCLCONST:        "DCLCONST",
-	ODCLTYPE:         "DCLTYPE",
-	ODELETE:          "DELETE",
-	ODOT:             "DOT",
-	ODOTPTR:          "DOTPTR",
-	ODOTMETH:         "DOTMETH",
-	ODOTINTER:        "DOTINTER",
-	OXDOT:            "XDOT",
-	ODOTTYPE:         "DOTTYPE",
-	ODOTTYPE2:        "DOTTYPE2",
-	OEQ:              "EQ",
-	ONE:              "NE",
-	OLT:              "LT",
-	OLE:              "LE",
-	OGE:              "GE",
-	OGT:              "GT",
-	OIND:             "IND",
-	OINDEX:           "INDEX",
-	OINDEXMAP:        "INDEXMAP",
-	OKEY:             "KEY",
-	OSTRUCTKEY:       "STRUCTKEY",
-	OLEN:             "LEN",
-	OMAKE:            "MAKE",
-	OMAKECHAN:        "MAKECHAN",
-	OMAKEMAP:         "MAKEMAP",
-	OMAKESLICE:       "MAKESLICE",
-	OMUL:             "MUL",
-	ODIV:             "DIV",
-	OMOD:             "MOD",
-	OLSH:             "LSH",
-	ORSH:             "RSH",
-	OAND:             "AND",
-	OANDNOT:          "ANDNOT",
-	ONEW:             "NEW",
-	ONOT:             "NOT",
-	OCOM:             "COM",
-	OPLUS:            "PLUS",
-	OMINUS:           "MINUS",
-	OOROR:            "OROR",
-	OPANIC:           "PANIC",
-	OPRINT:           "PRINT",
-	OPRINTN:          "PRINTN",
-	OPAREN:           "PAREN",
-	OSEND:            "SEND",
-	OSLICE:           "SLICE",
-	OSLICEARR:        "SLICEARR",
-	OSLICESTR:        "SLICESTR",
-	OSLICE3:          "SLICE3",
-	OSLICE3ARR:       "SLICE3ARR",
-	ORECOVER:         "RECOVER",
-	ORECV:            "RECV",
-	ORUNESTR:         "RUNESTR",
-	OSELRECV:         "SELRECV",
-	OSELRECV2:        "SELRECV2",
-	OIOTA:            "IOTA",
-	OREAL:            "REAL",
-	OIMAG:            "IMAG",
-	OCOMPLEX:         "COMPLEX",
-	OBLOCK:           "BLOCK",
-	OBREAK:           "BREAK",
-	OCASE:            "CASE",
-	OXCASE:           "XCASE",
-	OCONTINUE:        "CONTINUE",
-	ODEFER:           "DEFER",
-	OEMPTY:           "EMPTY",
-	OFALL:            "FALL",
-	OXFALL:           "XFALL",
-	OFOR:             "FOR",
-	OFORUNTIL:        "FORUNTIL",
-	OGOTO:            "GOTO",
-	OIF:              "IF",
-	OLABEL:           "LABEL",
-	OPROC:            "PROC",
-	ORANGE:           "RANGE",
-	ORETURN:          "RETURN",
-	OSELECT:          "SELECT",
-	OSWITCH:          "SWITCH",
-	OTYPESW:          "TYPESW",
-	OTCHAN:           "TCHAN",
-	OTMAP:            "TMAP",
-	OTSTRUCT:         "TSTRUCT",
-	OTINTER:          "TINTER",
-	OTFUNC:           "TFUNC",
-	OTARRAY:          "TARRAY",
-	ODDD:             "DDD",
-	ODDDARG:          "DDDARG",
-	OINLCALL:         "INLCALL",
-	OEFACE:           "EFACE",
-	OITAB:            "ITAB",
-	OIDATA:           "IDATA",
-	OSPTR:            "SPTR",
-	OCLOSUREVAR:      "CLOSUREVAR",
-	OCFUNC:           "CFUNC",
-	OCHECKNIL:        "CHECKNIL",
-	OVARKILL:         "VARKILL",
-	OVARLIVE:         "VARLIVE",
-	OINDREGSP:        "INDREGSP",
-	ORETJMP:          "RETJMP",
-	OGETG:            "GETG",
-	OEND:             "END",
-}
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index cdda2f3..4b24be8 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -187,7 +187,7 @@
 // The result of orderaddrtemp MUST be assigned back to n, e.g.
 // 	n.Left = orderaddrtemp(n.Left, order)
 func orderaddrtemp(n *Node, order *Order) *Node {
-	if consttype(n) >= 0 {
+	if consttype(n) > 0 {
 		// TODO: expand this to all static composite literal nodes?
 		n = defaultlit(n, nil)
 		dowidth(n.Type)
@@ -235,18 +235,16 @@
 // above the mark on the temporary stack, but it does not pop them
 // from the stack.
 func cleantempnopop(mark ordermarker, order *Order, out *[]*Node) {
-	var kill *Node
-
 	for i := len(order.temp) - 1; i >= int(mark); i-- {
 		n := order.temp[i]
 		if n.Name.Keepalive() {
 			n.Name.SetKeepalive(false)
 			n.SetAddrtaken(true) // ensure SSA keeps the n variable
-			kill = nod(OVARLIVE, n, nil)
+			kill := nod(OVARLIVE, n, nil)
 			kill = typecheck(kill, Etop)
 			*out = append(*out, kill)
 		}
-		kill = nod(OVARKILL, n, nil)
+		kill := nod(OVARKILL, n, nil)
 		kill = typecheck(kill, Etop)
 		*out = append(*out, kill)
 	}
@@ -346,14 +344,14 @@
 	}
 
 	// call must return multiple values
-	return n.Left.Type.Results().NumFields() > 1
+	return n.Left.Type.NumResults() > 1
 }
 
 // Copyret emits t1, t2, ... = n, where n is a function call,
 // and then returns the list t1, t2, ....
 func copyret(n *Node, order *Order) []*Node {
 	if !n.Type.IsFuncArgStruct() {
-		Fatalf("copyret %v %d", n.Type, n.Left.Type.Results().NumFields())
+		Fatalf("copyret %v %d", n.Type, n.Left.Type.NumResults())
 	}
 
 	var l1 []*Node
@@ -397,11 +395,11 @@
 			// by copying it into a temp and marking that temp
 			// still alive when we pop the temp stack.
 			xp := n.List.Addr(i)
-			for (*xp).Op == OCONVNOP && !(*xp).Type.IsPtr() {
+			for (*xp).Op == OCONVNOP && !(*xp).Type.IsUnsafePtr() {
 				xp = &(*xp).Left
 			}
 			x := *xp
-			if x.Type.IsPtr() {
+			if x.Type.IsUnsafePtr() {
 				x = ordercopyexpr(x, x.Type, order, 0)
 				x.Name.SetKeepalive(true)
 				*xp = x
@@ -429,10 +427,10 @@
 // to make sure that all map assignments have the form m[k] = x.
 // (Note: orderexpr has already been called on n, so we know k is addressable.)
 //
-// If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is
+// If n is the multiple assignment form ..., m[k], ... = ..., x, ..., the rewrite is
 //	t1 = m
 //	t2 = k
-//	...., t3, ... = x
+//	...., t3, ... = ..., x, ...
 //	t1[t2] = t3
 //
 // The temporaries t1, t2 are needed in case the ... being assigned
@@ -446,30 +444,29 @@
 		Fatalf("ordermapassign %v", n.Op)
 
 	case OAS:
+		if n.Left.Op == OINDEXMAP {
+			// Make sure we evaluate the RHS before starting the map insert.
+			// We need to make sure the RHS won't panic.  See issue 22881.
+			n.Right = ordercheapexpr(n.Right, order)
+		}
 		order.out = append(order.out, n)
 
 	case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
 		var post []*Node
-		var m *Node
-		var a *Node
-		for i1, n1 := range n.List.Slice() {
-			if n1.Op == OINDEXMAP {
-				m = n1
+		for i, m := range n.List.Slice() {
+			switch {
+			case m.Op == OINDEXMAP:
 				if !m.Left.IsAutoTmp() {
 					m.Left = ordercopyexpr(m.Left, m.Left.Type, order, 0)
 				}
 				if !m.Right.IsAutoTmp() {
 					m.Right = ordercopyexpr(m.Right, m.Right.Type, order, 0)
 				}
-				n.List.SetIndex(i1, ordertemp(m.Type, order, false))
-				a = nod(OAS, m, n.List.Index(i1))
-				a = typecheck(a, Etop)
-				post = append(post, a)
-			} else if instrumenting && n.Op == OAS2FUNC && !isblank(n.List.Index(i1)) {
-				m = n.List.Index(i1)
+				fallthrough
+			case instrumenting && n.Op == OAS2FUNC && !isblank(m):
 				t := ordertemp(m.Type, order, false)
-				n.List.SetIndex(i1, t)
-				a = nod(OAS, m, t)
+				n.List.SetIndex(i, t)
+				a := nod(OAS, m, t)
 				a = typecheck(a, Etop)
 				post = append(post, a)
 			}
@@ -533,8 +530,9 @@
 		// out map read from map write when l is
 		// a map index expression.
 		t := marktemp(order)
-
 		n.Left = orderexpr(n.Left, order, nil)
+		n.Right = orderexpr(n.Right, order, nil)
+
 		n.Left = ordersafeexpr(n.Left, order)
 		tmp1 := treecopy(n.Left, src.NoXPos)
 		if tmp1.Op == OINDEXMAP {
@@ -619,7 +617,6 @@
 		ODCLCONST,
 		ODCLTYPE,
 		OFALL,
-		OXFALL,
 		OGOTO,
 		OLABEL,
 		ORETJMP:
@@ -761,11 +758,12 @@
 			r := n.Right
 			n.Right = ordercopyexpr(r, r.Type, order, 0)
 
-			// n->alloc is the temp for the iterator.
-			prealloc[n] = ordertemp(types.Types[TUINT8], order, true)
+			// prealloc[n] is the temp for the iterator.
+			// hiter contains pointers and needs to be zeroed.
+			prealloc[n] = ordertemp(hiter(n.Type), order, true)
 		}
-		for i := range n.List.Slice() {
-			n.List.SetIndex(i, orderexprinplace(n.List.Index(i), order))
+		for i, n1 := range n.List.Slice() {
+			n.List.SetIndex(i, orderexprinplace(n1, order))
 		}
 		orderblockNodes(&n.Nbody)
 		order.out = append(order.out, n)
@@ -787,14 +785,11 @@
 	case OSELECT:
 		t := marktemp(order)
 
-		var tmp1 *Node
-		var tmp2 *Node
-		var r *Node
 		for _, n2 := range n.List.Slice() {
 			if n2.Op != OXCASE {
 				Fatalf("order select case %v", n2.Op)
 			}
-			r = n2.Left
+			r := n2.Left
 			setlineno(n2)
 
 			// Append any new body prologue to ninit.
@@ -855,16 +850,16 @@
 						// use channel element type for temporary to avoid conversions,
 						// such as in case interfacevalue = <-intchan.
 						// the conversion happens in the OAS instead.
-						tmp1 = r.Left
+						tmp1 := r.Left
 
 						if r.Colas() {
-							tmp2 = nod(ODCL, tmp1, nil)
+							tmp2 := nod(ODCL, tmp1, nil)
 							tmp2 = typecheck(tmp2, Etop)
 							n2.Ninit.Append(tmp2)
 						}
 
 						r.Left = ordertemp(r.Right.Left.Type.Elem(), order, types.Haspointers(r.Right.Left.Type.Elem()))
-						tmp2 = nod(OAS, tmp1, r.Left)
+						tmp2 := nod(OAS, tmp1, r.Left)
 						tmp2 = typecheck(tmp2, Etop)
 						n2.Ninit.Append(tmp2)
 					}
@@ -873,15 +868,15 @@
 						r.List.Set(nil)
 					}
 					if r.List.Len() != 0 {
-						tmp1 = r.List.First()
+						tmp1 := r.List.First()
 						if r.Colas() {
-							tmp2 = nod(ODCL, tmp1, nil)
+							tmp2 := nod(ODCL, tmp1, nil)
 							tmp2 = typecheck(tmp2, Etop)
 							n2.Ninit.Append(tmp2)
 						}
 
 						r.List.Set1(ordertemp(types.Types[TBOOL], order, false))
-						tmp2 = okas(tmp1, r.List.First())
+						tmp2 := okas(tmp1, r.List.First())
 						tmp2 = typecheck(tmp2, Etop)
 						n2.Ninit.Append(tmp2)
 					}
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index 66e4a10..6fa3016 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -13,8 +13,10 @@
 	"cmd/internal/src"
 	"cmd/internal/sys"
 	"fmt"
+	"math"
 	"math/rand"
 	"sort"
+	"strings"
 	"sync"
 	"time"
 )
@@ -36,26 +38,22 @@
 	nptr := int(Curfn.Type.ArgWidth() / int64(Widthptr))
 	bv := bvalloc(int32(nptr) * 2)
 	nbitmap := 1
-	if Curfn.Type.Results().NumFields() > 0 {
+	if Curfn.Type.NumResults() > 0 {
 		nbitmap = 2
 	}
 	off := duint32(lsym, 0, uint32(nbitmap))
 	off = duint32(lsym, off, uint32(bv.n))
-	var xoffset int64
+
 	if Curfn.IsMethod() {
-		xoffset = 0
-		onebitwalktype1(Curfn.Type.Recvs(), &xoffset, bv)
+		onebitwalktype1(Curfn.Type.Recvs(), 0, bv)
 	}
-
-	if Curfn.Type.Params().NumFields() > 0 {
-		xoffset = 0
-		onebitwalktype1(Curfn.Type.Params(), &xoffset, bv)
+	if Curfn.Type.NumParams() > 0 {
+		onebitwalktype1(Curfn.Type.Params(), 0, bv)
 	}
-
 	off = dbvec(lsym, off, bv)
-	if Curfn.Type.Results().NumFields() > 0 {
-		xoffset = 0
-		onebitwalktype1(Curfn.Type.Results(), &xoffset, bv)
+
+	if Curfn.Type.NumResults() > 0 {
+		onebitwalktype1(Curfn.Type.Results(), 0, bv)
 		off = dbvec(lsym, off, bv)
 	}
 
@@ -132,20 +130,21 @@
 	scratchUsed := false
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
-			switch a := v.Aux.(type) {
-			case *ssa.ArgSymbol:
-				n := a.Node.(*Node)
-				// Don't modify nodfp; it is a global.
-				if n != nodfp {
+			if n, ok := v.Aux.(*Node); ok {
+				switch n.Class() {
+				case PPARAM, PPARAMOUT:
+					// Don't modify nodfp; it is a global.
+					if n != nodfp {
+						n.Name.SetUsed(true)
+					}
+				case PAUTO:
 					n.Name.SetUsed(true)
 				}
-			case *ssa.AutoSymbol:
-				a.Node.(*Node).Name.SetUsed(true)
 			}
-
 			if !scratchUsed {
 				scratchUsed = v.Op.UsesScratch()
 			}
+
 		}
 	}
 
@@ -230,23 +229,23 @@
 	return nBackendWorkers == 1 && Debug_compilelater == 0
 }
 
-const maxStackSize = 1 << 31
+const maxStackSize = 1 << 30
 
 // compileSSA builds an SSA backend function,
 // uses it to generate a plist,
 // and flushes that plist to machine code.
 // worker indicates which of the backend workers is doing the processing.
 func compileSSA(fn *Node, worker int) {
-	ssafn := buildssa(fn, worker)
-	pp := newProgs(fn, worker)
-	genssa(ssafn, pp)
-	if pp.Text.To.Offset < maxStackSize {
-		pp.Flush()
-	} else {
+	f := buildssa(fn, worker)
+	if f.Frontend().(*ssafn).stksize >= maxStackSize {
 		largeStackFramesMu.Lock()
 		largeStackFrames = append(largeStackFrames, fn.Pos)
 		largeStackFramesMu.Unlock()
+		return
 	}
+	pp := newProgs(fn, worker)
+	genssa(f, pp)
+	pp.Flush()
 	// fieldtrack must be called after pp.Flush. See issue 20014.
 	fieldtrack(pp.Text.From.Sym, fn.Func.FieldTrack)
 	pp.Free()
@@ -281,6 +280,7 @@
 			})
 		}
 		var wg sync.WaitGroup
+		Ctxt.InParallel = true
 		c := make(chan *Node, nBackendWorkers)
 		for i := 0; i < nBackendWorkers; i++ {
 			wg.Add(1)
@@ -297,35 +297,101 @@
 		close(c)
 		compilequeue = nil
 		wg.Wait()
+		Ctxt.InParallel = false
 		sizeCalculationDisabled = false
 	}
 }
 
-func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope {
+func debuginfo(fnsym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
 	fn := curfn.(*Node)
-	if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
-		Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
+	debugInfo := fn.Func.DebugInfo
+	fn.Func.DebugInfo = nil
+	if fn.Func.Nname != nil {
+		if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
+			Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
+		}
 	}
 
-	var dwarfVars []*dwarf.Var
-	var varScopes []ScopeID
-
+	var automDecls []*Node
+	// Populate Automs for fn.
 	for _, n := range fn.Func.Dcl {
 		if n.Op != ONAME { // might be OTYPE or OLITERAL
 			continue
 		}
-
 		var name obj.AddrName
+		switch n.Class() {
+		case PAUTO:
+			if !n.Name.Used() {
+				// Text == nil -> generating abstract function
+				if fnsym.Func.Text != nil {
+					Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
+				}
+				continue
+			}
+			name = obj.NAME_AUTO
+		case PPARAM, PPARAMOUT:
+			name = obj.NAME_PARAM
+		default:
+			continue
+		}
+		automDecls = append(automDecls, n)
+		gotype := ngotype(n).Linksym()
+		fnsym.Func.Autom = append(fnsym.Func.Autom, &obj.Auto{
+			Asym:    Ctxt.Lookup(n.Sym.Name),
+			Aoffset: int32(n.Xoffset),
+			Name:    name,
+			Gotype:  gotype,
+		})
+	}
+
+	decls, dwarfVars := createDwarfVars(fnsym, debugInfo, automDecls)
+
+	var varScopes []ScopeID
+	for _, decl := range decls {
+		pos := decl.Pos
+		if decl.Name.Defn != nil && (decl.Name.Captured() || decl.Name.Byval()) {
+			// It's not clear which position is correct for captured variables here:
+			// * decl.Pos is the wrong position for captured variables, in the inner
+			//   function, but it is the right position in the outer function.
+			// * decl.Name.Defn is nil for captured variables that were arguments
+			//   on the outer function, however the decl.Pos for those seems to be
+			//   correct.
+			// * decl.Name.Defn is the "wrong" thing for variables declared in the
+			//   header of a type switch, it's their position in the header, rather
+			//   than the position of the case statement. In principle this is the
+			//   right thing, but here we prefer the latter because it makes each
+			//   instance of the header variable local to the lexical block of its
+			//   case statement.
+			// This code is probably wrong for type switch variables that are also
+			// captured.
+			pos = decl.Name.Defn.Pos
+		}
+		varScopes = append(varScopes, findScope(fn.Func.Marks, pos))
+	}
+
+	scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
+	var inlcalls dwarf.InlCalls
+	if genDwarfInline > 0 {
+		inlcalls = assembleInlines(fnsym, fn, dwarfVars)
+	}
+	return scopes, inlcalls
+}
+
+// createSimpleVars creates a DWARF entry for every variable declared in the
+// function, claiming that they are permanently on the stack.
+func createSimpleVars(automDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+	var vars []*dwarf.Var
+	var decls []*Node
+	selected := make(map[*Node]bool)
+	for _, n := range automDecls {
+		if n.IsAutoTmp() {
+			continue
+		}
 		var abbrev int
 		offs := n.Xoffset
 
 		switch n.Class() {
 		case PAUTO:
-			if !n.Name.Used() {
-				Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
-			}
-			name = obj.NAME_AUTO
-
 			abbrev = dwarf.DW_ABRV_AUTO
 			if Ctxt.FixedFrameSize() == 0 {
 				offs -= int64(Widthptr)
@@ -335,48 +401,510 @@
 			}
 
 		case PPARAM, PPARAMOUT:
-			name = obj.NAME_PARAM
-
 			abbrev = dwarf.DW_ABRV_PARAM
 			offs += Ctxt.FixedFrameSize()
-
 		default:
-			continue
+			Fatalf("createSimpleVars unexpected type %v for node %v", n.Class(), n)
 		}
 
+		selected[n] = true
+		typename := dwarf.InfoPrefix + typesymname(n.Type)
+		decls = append(decls, n)
+		inlIndex := 0
+		if genDwarfInline > 1 {
+			if n.InlFormal() || n.InlLocal() {
+				inlIndex = posInlIndex(n.Pos) + 1
+				if n.InlFormal() {
+					abbrev = dwarf.DW_ABRV_PARAM
+				}
+			}
+		}
+		declpos := Ctxt.InnermostPos(n.Pos)
+		vars = append(vars, &dwarf.Var{
+			Name:          n.Sym.Name,
+			IsReturnValue: n.Class() == PPARAMOUT,
+			IsInlFormal:   n.InlFormal(),
+			Abbrev:        abbrev,
+			StackOffset:   int32(offs),
+			Type:          Ctxt.Lookup(typename),
+			DeclFile:      declpos.Base().SymFilename(),
+			DeclLine:      declpos.Line(),
+			DeclCol:       declpos.Col(),
+			InlIndex:      int32(inlIndex),
+			ChildIndex:    -1,
+		})
+	}
+	return decls, vars, selected
+}
+
+type varPart struct {
+	varOffset int64
+	slot      ssa.SlotID
+}
+
+func createComplexVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug, automDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+	for _, blockDebug := range debugInfo.Blocks {
+		for _, locList := range blockDebug.Variables {
+			for _, loc := range locList.Locations {
+				if loc.StartProg != nil {
+					loc.StartPC = loc.StartProg.Pc
+				}
+				if loc.EndProg != nil {
+					loc.EndPC = loc.EndProg.Pc
+				} else {
+					loc.EndPC = fnsym.Size
+				}
+				if Debug_locationlist == 0 {
+					loc.EndProg = nil
+					loc.StartProg = nil
+				}
+			}
+		}
+	}
+
+	// Group SSA variables by the user variable they were decomposed from.
+	varParts := map[*Node][]varPart{}
+	ssaVars := make(map[*Node]bool)
+	for slotID, slot := range debugInfo.VarSlots {
+		for slot.SplitOf != nil {
+			slot = slot.SplitOf
+		}
+		n := slot.N.(*Node)
+		ssaVars[n] = true
+		varParts[n] = append(varParts[n], varPart{varOffset(slot), ssa.SlotID(slotID)})
+	}
+
+	// Produce a DWARF variable entry for each user variable.
+	// Don't iterate over the map -- that's nondeterministic, and
+	// createComplexVar has side effects. Instead, go by slot.
+	var decls []*Node
+	var vars []*dwarf.Var
+	for _, slot := range debugInfo.VarSlots {
+		for slot.SplitOf != nil {
+			slot = slot.SplitOf
+		}
+		n := slot.N.(*Node)
+		parts := varParts[n]
+		if parts == nil {
+			continue
+		}
+		// Don't work on this variable again, no matter how many slots it has.
+		delete(varParts, n)
+
+		// Get the order the parts need to be in to represent the memory
+		// of the decomposed user variable.
+		sort.Sort(partsByVarOffset(parts))
+
+		if dvar := createComplexVar(debugInfo, n, parts); dvar != nil {
+			decls = append(decls, n)
+			vars = append(vars, dvar)
+		}
+	}
+
+	return decls, vars, ssaVars
+}
+
+func createDwarfVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug, automDecls []*Node) ([]*Node, []*dwarf.Var) {
+	// Collect a raw list of DWARF vars.
+	var vars []*dwarf.Var
+	var decls []*Node
+	var selected map[*Node]bool
+	if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && debugInfo != nil {
+		decls, vars, selected = createComplexVars(fnsym, debugInfo, automDecls)
+	} else {
+		decls, vars, selected = createSimpleVars(automDecls)
+	}
+
+	var dcl []*Node
+	if fnsym.WasInlined() {
+		dcl = preInliningDcls(fnsym)
+	} else {
+		dcl = automDecls
+	}
+
+	// If optimization is enabled, the list above will typically be
+	// missing some of the original pre-optimization variables in the
+	// function (they may have been promoted to registers, folded into
+	// constants, dead-coded away, etc). Here we add back in entries
+	// for selected missing vars. Note that the recipe below creates a
+	// conservative location. The idea here is that we want to
+	// communicate to the user that "yes, there is a variable named X
+	// in this function, but no, I don't have enough information to
+	// reliably report its contents."
+	for _, n := range dcl {
+		if _, found := selected[n]; found {
+			continue
+		}
+		c := n.Sym.Name[0]
+		if c == '.' || n.Type.IsUntyped() {
+			continue
+		}
+		typename := dwarf.InfoPrefix + typesymname(n.Type)
+		decls = append(decls, n)
+		abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
+		if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+			abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+		}
+		inlIndex := 0
+		if genDwarfInline > 1 {
+			if n.InlFormal() || n.InlLocal() {
+				inlIndex = posInlIndex(n.Pos) + 1
+				if n.InlFormal() {
+					abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+				}
+			}
+		}
+		declpos := Ctxt.InnermostPos(n.Pos)
+		vars = append(vars, &dwarf.Var{
+			Name:          n.Sym.Name,
+			IsReturnValue: n.Class() == PPARAMOUT,
+			Abbrev:        abbrev,
+			StackOffset:   int32(n.Xoffset),
+			Type:          Ctxt.Lookup(typename),
+			DeclFile:      declpos.Base().SymFilename(),
+			DeclLine:      declpos.Line(),
+			DeclCol:       declpos.Col(),
+			InlIndex:      int32(inlIndex),
+			ChildIndex:    -1,
+		})
+		// Append a "deleted auto" entry to the autom list so as to
+		// insure that the type in question is picked up by the linker.
+		// See issue 22941.
 		gotype := ngotype(n).Linksym()
 		fnsym.Func.Autom = append(fnsym.Func.Autom, &obj.Auto{
 			Asym:    Ctxt.Lookup(n.Sym.Name),
-			Aoffset: int32(n.Xoffset),
-			Name:    name,
+			Aoffset: int32(-1),
+			Name:    obj.NAME_DELETED_AUTO,
 			Gotype:  gotype,
 		})
 
-		if n.IsAutoTmp() {
-			continue
-		}
-
-		typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
-		dwarfVars = append(dwarfVars, &dwarf.Var{
-			Name:   n.Sym.Name,
-			Abbrev: abbrev,
-			Offset: int32(offs),
-			Type:   Ctxt.Lookup(typename),
-		})
-
-		var scope ScopeID
-		if !n.Name.Captured() && !n.Name.Byval() {
-			// n.Pos of captured variables is their first
-			// use in the closure but they should always
-			// be assigned to scope 0 instead.
-			// TODO(mdempsky): Verify this.
-			scope = findScope(fn.Func.Marks, n.Pos)
-		}
-
-		varScopes = append(varScopes, scope)
 	}
 
-	return assembleScopes(fnsym, fn, dwarfVars, varScopes)
+	return decls, vars
+}
+
+// Given a function that was inlined at some point during the
+// compilation, return a sorted list of nodes corresponding to the
+// autos/locals in that function prior to inlining. If this is a
+// function that is not local to the package being compiled, then the
+// names of the variables may have been "versioned" to avoid conflicts
+// with local vars; disregard this versioning when sorting.
+func preInliningDcls(fnsym *obj.LSym) []*Node {
+	fn := Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*Node)
+	var dcl, rdcl []*Node
+	if fn.Name.Defn != nil {
+		dcl = fn.Func.Inldcl.Slice() // local function
+	} else {
+		dcl = fn.Func.Dcl // imported function
+	}
+	for _, n := range dcl {
+		c := n.Sym.Name[0]
+		// Avoid reporting "_" parameters, since if there are more than
+		// one, it can result in a collision later on, as in #23179.
+		if unversion(n.Sym.Name) == "_" || c == '.' || n.Type.IsUntyped() {
+			continue
+		}
+		rdcl = append(rdcl, n)
+	}
+	sort.Sort(byNodeName(rdcl))
+	return rdcl
+}
+
+func cmpNodeName(a, b *Node) bool {
+	aart := 0
+	if strings.HasPrefix(a.Sym.Name, "~") {
+		aart = 1
+	}
+	bart := 0
+	if strings.HasPrefix(b.Sym.Name, "~") {
+		bart = 1
+	}
+	if aart != bart {
+		return aart < bart
+	}
+
+	aname := unversion(a.Sym.Name)
+	bname := unversion(b.Sym.Name)
+	return aname < bname
+}
+
+// byNodeName implements sort.Interface for []*Node using cmpNodeName.
+type byNodeName []*Node
+
+func (s byNodeName) Len() int           { return len(s) }
+func (s byNodeName) Less(i, j int) bool { return cmpNodeName(s[i], s[j]) }
+func (s byNodeName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// varOffset returns the offset of slot within the user variable it was
+// decomposed from. This has nothing to do with its stack offset.
+func varOffset(slot *ssa.LocalSlot) int64 {
+	offset := slot.Off
+	for ; slot.SplitOf != nil; slot = slot.SplitOf {
+		offset += slot.SplitOffset
+	}
+	return offset
+}
+
+type partsByVarOffset []varPart
+
+func (a partsByVarOffset) Len() int           { return len(a) }
+func (a partsByVarOffset) Less(i, j int) bool { return a[i].varOffset < a[j].varOffset }
+func (a partsByVarOffset) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+// stackOffset returns the stack location of a LocalSlot relative to the
+// stack pointer, suitable for use in a DWARF location entry. This has nothing
+// to do with its offset in the user variable.
+func stackOffset(slot *ssa.LocalSlot) int32 {
+	n := slot.N.(*Node)
+	var base int64
+	switch n.Class() {
+	case PAUTO:
+		if Ctxt.FixedFrameSize() == 0 {
+			base -= int64(Widthptr)
+		}
+		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+			base -= int64(Widthptr)
+		}
+	case PPARAM, PPARAMOUT:
+		base += Ctxt.FixedFrameSize()
+	}
+	return int32(base + n.Xoffset + slot.Off)
+}
+
+// createComplexVar builds a DWARF variable entry and location list representing n.
+func createComplexVar(debugInfo *ssa.FuncDebug, n *Node, parts []varPart) *dwarf.Var {
+	slots := debugInfo.Slots
+	var offs int64 // base stack offset for this kind of variable
+	var abbrev int
+	switch n.Class() {
+	case PAUTO:
+		abbrev = dwarf.DW_ABRV_AUTO_LOCLIST
+		if Ctxt.FixedFrameSize() == 0 {
+			offs -= int64(Widthptr)
+		}
+		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+			offs -= int64(Widthptr)
+		}
+
+	case PPARAM, PPARAMOUT:
+		abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+		offs += Ctxt.FixedFrameSize()
+	default:
+		return nil
+	}
+
+	gotype := ngotype(n).Linksym()
+	typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
+	inlIndex := 0
+	if genDwarfInline > 1 {
+		if n.InlFormal() || n.InlLocal() {
+			inlIndex = posInlIndex(n.Pos) + 1
+			if n.InlFormal() {
+				abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+			}
+		}
+	}
+	declpos := Ctxt.InnermostPos(n.Pos)
+	dvar := &dwarf.Var{
+		Name:          n.Sym.Name,
+		IsReturnValue: n.Class() == PPARAMOUT,
+		IsInlFormal:   n.InlFormal(),
+		Abbrev:        abbrev,
+		Type:          Ctxt.Lookup(typename),
+		// The stack offset is used as a sorting key, so for decomposed
+		// variables just give it the lowest one. It's not used otherwise.
+		// This won't work well if the first slot hasn't been assigned a stack
+		// location, but it's not obvious how to do better.
+		StackOffset: int32(stackOffset(slots[parts[0].slot])),
+		DeclFile:    declpos.Base().SymFilename(),
+		DeclLine:    declpos.Line(),
+		DeclCol:     declpos.Col(),
+		InlIndex:    int32(inlIndex),
+		ChildIndex:  -1,
+	}
+
+	if Debug_locationlist != 0 {
+		Ctxt.Logf("Building location list for %+v. Parts:\n", n)
+		for _, part := range parts {
+			Ctxt.Logf("\t%v => %v\n", debugInfo.Slots[part.slot], debugInfo.SlotLocsString(part.slot))
+		}
+	}
+
+	// Given a variable that's been decomposed into multiple parts,
+	// its location list may need a new entry after the beginning or
+	// end of every location entry for each of its parts. For example:
+	//
+	// [variable]    [pc range]
+	// string.ptr    |----|-----|    |----|
+	// string.len    |------------|  |--|
+	// ... needs a location list like:
+	// string        |----|-----|-|  |--|-|
+	//
+	// Note that location entries may or may not line up with each other,
+	// and some of the result will only have one or the other part.
+	//
+	// To build the resulting list:
+	// - keep a "current" pointer for each part
+	// - find the next transition point
+	// - advance the current pointer for each part up to that transition point
+	// - build the piece for the range between that transition point and the next
+	// - repeat
+
+	type locID struct {
+		block int
+		loc   int
+	}
+	findLoc := func(part varPart, id locID) *ssa.VarLoc {
+		if id.block >= len(debugInfo.Blocks) {
+			return nil
+		}
+		return debugInfo.Blocks[id.block].Variables[part.slot].Locations[id.loc]
+	}
+	nextLoc := func(part varPart, id locID) (locID, *ssa.VarLoc) {
+		// Check if there's another loc in this block
+		id.loc++
+		if b := debugInfo.Blocks[id.block]; b != nil && id.loc < len(b.Variables[part.slot].Locations) {
+			return id, findLoc(part, id)
+		}
+		// Find the next block that has a loc for this part.
+		id.loc = 0
+		id.block++
+		for ; id.block < len(debugInfo.Blocks); id.block++ {
+			if b := debugInfo.Blocks[id.block]; b != nil && len(b.Variables[part.slot].Locations) != 0 {
+				return id, findLoc(part, id)
+			}
+		}
+		return id, nil
+	}
+	curLoc := make([]locID, len(slots))
+	// Position each pointer at the first entry for its slot.
+	for _, part := range parts {
+		if b := debugInfo.Blocks[0]; b != nil && len(b.Variables[part.slot].Locations) != 0 {
+			// Block 0 has an entry; no need to advance.
+			continue
+		}
+		curLoc[part.slot], _ = nextLoc(part, curLoc[part.slot])
+	}
+
+	// findBoundaryAfter finds the next beginning or end of a piece after currentPC.
+	findBoundaryAfter := func(currentPC int64) int64 {
+		min := int64(math.MaxInt64)
+		for _, part := range parts {
+			// For each part, find the first PC greater than current. Doesn't
+			// matter if it's a start or an end, since we're looking for any boundary.
+			// If it's the new winner, save it.
+		onePart:
+			for i, loc := curLoc[part.slot], findLoc(part, curLoc[part.slot]); loc != nil; i, loc = nextLoc(part, i) {
+				for _, pc := range [2]int64{loc.StartPC, loc.EndPC} {
+					if pc > currentPC {
+						if pc < min {
+							min = pc
+						}
+						break onePart
+					}
+				}
+			}
+		}
+		return min
+	}
+	var start int64
+	end := findBoundaryAfter(0)
+	for {
+		// Advance to the next chunk.
+		start = end
+		end = findBoundaryAfter(start)
+		if end == math.MaxInt64 {
+			break
+		}
+
+		dloc := dwarf.Location{StartPC: start, EndPC: end}
+		if Debug_locationlist != 0 {
+			Ctxt.Logf("Processing range %x -> %x\n", start, end)
+		}
+
+		// Advance curLoc to the last location that starts before/at start.
+		// After this loop, if there's a location that covers [start, end), it will be current.
+		// Otherwise the current piece will be too early.
+		for _, part := range parts {
+			choice := locID{-1, -1}
+			for i, loc := curLoc[part.slot], findLoc(part, curLoc[part.slot]); loc != nil; i, loc = nextLoc(part, i) {
+				if loc.StartPC > start {
+					break //overshot
+				}
+				choice = i // best yet
+			}
+			if choice.block != -1 {
+				curLoc[part.slot] = choice
+			}
+			if Debug_locationlist != 0 {
+				Ctxt.Logf("\t %v => %v", slots[part.slot], curLoc[part.slot])
+			}
+		}
+		if Debug_locationlist != 0 {
+			Ctxt.Logf("\n")
+		}
+		// Assemble the location list entry for this chunk.
+		present := 0
+		for _, part := range parts {
+			dpiece := dwarf.Piece{
+				Length: slots[part.slot].Type.Size(),
+			}
+			loc := findLoc(part, curLoc[part.slot])
+			if loc == nil || start >= loc.EndPC || end <= loc.StartPC {
+				if Debug_locationlist != 0 {
+					Ctxt.Logf("\t%v: missing", slots[part.slot])
+				}
+				dpiece.Missing = true
+				dloc.Pieces = append(dloc.Pieces, dpiece)
+				continue
+			}
+			present++
+			if Debug_locationlist != 0 {
+				Ctxt.Logf("\t%v: %v", slots[part.slot], debugInfo.Blocks[curLoc[part.slot].block].LocString(loc))
+			}
+			if loc.OnStack {
+				dpiece.OnStack = true
+				dpiece.StackOffset = stackOffset(slots[loc.StackLocation])
+			} else {
+				for reg := 0; reg < len(debugInfo.Registers); reg++ {
+					if loc.Registers&(1<<uint8(reg)) != 0 {
+						dpiece.RegNum = Ctxt.Arch.DWARFRegisters[debugInfo.Registers[reg].ObjNum()]
+					}
+				}
+			}
+			dloc.Pieces = append(dloc.Pieces, dpiece)
+		}
+		if present == 0 {
+			if Debug_locationlist != 0 {
+				Ctxt.Logf(" -> totally missing\n")
+			}
+			continue
+		}
+		// Extend the previous entry if possible.
+		if len(dvar.LocationList) > 0 {
+			prev := &dvar.LocationList[len(dvar.LocationList)-1]
+			if prev.EndPC == dloc.StartPC && len(prev.Pieces) == len(dloc.Pieces) {
+				equal := true
+				for i := range prev.Pieces {
+					if prev.Pieces[i] != dloc.Pieces[i] {
+						equal = false
+					}
+				}
+				if equal {
+					prev.EndPC = end
+					if Debug_locationlist != 0 {
+						Ctxt.Logf("-> merged with previous, now %#v\n", prev)
+					}
+					continue
+				}
+			}
+		}
+		dvar.LocationList = append(dvar.LocationList, dloc)
+		if Debug_locationlist != 0 {
+			Ctxt.Logf("-> added: %#v\n", dloc)
+		}
+	}
+	return dvar
 }
 
 // fieldtrack adds R_USEFIELD relocations to fnsym to record any
diff --git a/src/cmd/compile/internal/gc/phi.go b/src/cmd/compile/internal/gc/phi.go
index 0ce7a4b..b549f0e 100644
--- a/src/cmd/compile/internal/gc/phi.go
+++ b/src/cmd/compile/internal/gc/phi.go
@@ -233,24 +233,25 @@
 					// a D-edge, or an edge whose target is in currentRoot's subtree.
 					continue
 				}
-				if !hasPhi.contains(c.ID) {
-					// Add a phi to block c for variable n.
-					hasPhi.add(c.ID)
-					v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right?
-					// Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building.
-					s.s.addNamedValue(var_, v)
-					for i := 0; i < len(c.Preds); i++ {
-						v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs.
-					}
-					if debugPhi {
-						fmt.Printf("new phi for var%d in %s: %s\n", n, c, v)
-					}
-					if !hasDef.contains(c.ID) {
-						// There's now a new definition of this variable in block c.
-						// Add it to the priority queue to explore.
-						heap.Push(priq, c)
-						hasDef.add(c.ID)
-					}
+				if hasPhi.contains(c.ID) {
+					continue
+				}
+				// Add a phi to block c for variable n.
+				hasPhi.add(c.ID)
+				v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right?
+				// Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building.
+				s.s.addNamedValue(var_, v)
+				for i := 0; i < len(c.Preds); i++ {
+					v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs.
+				}
+				if debugPhi {
+					fmt.Printf("new phi for var%d in %s: %s\n", n, c, v)
+				}
+				if !hasDef.contains(c.ID) {
+					// There's now a new definition of this variable in block c.
+					// Add it to the priority queue to explore.
+					heap.Push(priq, c)
+					hasDef.add(c.ID)
 				}
 			}
 
diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go
index ca449b7..49d0229 100644
--- a/src/cmd/compile/internal/gc/plive.go
+++ b/src/cmd/compile/internal/gc/plive.go
@@ -306,12 +306,10 @@
 
 	var n *Node
 	switch a := v.Aux.(type) {
-	case nil, *ssa.ExternSymbol:
+	case nil, *obj.LSym:
 		// ok, but no node
-	case *ssa.ArgSymbol:
-		n = a.Node.(*Node)
-	case *ssa.AutoSymbol:
-		n = a.Node.(*Node)
+	case *Node:
+		n = a
 	default:
 		Fatalf("weird aux: %s", v.LongString())
 	}
@@ -353,110 +351,85 @@
 	return &lv.be[b.ID]
 }
 
-// NOTE: The bitmap for a specific type t should be cached in t after the first run
-// 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, onebitwalktype1
-// accounts for 40% of the 6g execution time.
-func onebitwalktype1(t *types.Type, xoffset *int64, bv bvec) {
-	if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 {
+// NOTE: The bitmap for a specific type t could be cached in t after
+// the first run and then simply copied into bv at the correct offset
+// on future calls with the same type t.
+func onebitwalktype1(t *types.Type, off int64, bv bvec) {
+	if t.Align > 0 && off&int64(t.Align-1) != 0 {
 		Fatalf("onebitwalktype1: invalid initial alignment, %v", t)
 	}
 
 	switch t.Etype {
-	case TINT8,
-		TUINT8,
-		TINT16,
-		TUINT16,
-		TINT32,
-		TUINT32,
-		TINT64,
-		TUINT64,
-		TINT,
-		TUINT,
-		TUINTPTR,
-		TBOOL,
-		TFLOAT32,
-		TFLOAT64,
-		TCOMPLEX64,
-		TCOMPLEX128:
-		*xoffset += t.Width
+	case TINT8, TUINT8, TINT16, TUINT16,
+		TINT32, TUINT32, TINT64, TUINT64,
+		TINT, TUINT, TUINTPTR, TBOOL,
+		TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
 
-	case TPTR32,
-		TPTR64,
-		TUNSAFEPTR,
-		TFUNC,
-		TCHAN,
-		TMAP:
-		if *xoffset&int64(Widthptr-1) != 0 {
+	case TPTR32, TPTR64, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
+		if off&int64(Widthptr-1) != 0 {
 			Fatalf("onebitwalktype1: invalid alignment, %v", t)
 		}
-		bv.Set(int32(*xoffset / int64(Widthptr))) // pointer
-		*xoffset += t.Width
+		bv.Set(int32(off / int64(Widthptr))) // pointer
 
 	case TSTRING:
 		// struct { byte *str; intgo len; }
-		if *xoffset&int64(Widthptr-1) != 0 {
+		if off&int64(Widthptr-1) != 0 {
 			Fatalf("onebitwalktype1: invalid alignment, %v", t)
 		}
-		bv.Set(int32(*xoffset / int64(Widthptr))) //pointer in first slot
-		*xoffset += t.Width
+		bv.Set(int32(off / int64(Widthptr))) //pointer in first slot
 
 	case TINTER:
 		// struct { Itab *tab;	void *data; }
 		// or, when isnilinter(t)==true:
 		// struct { Type *type; void *data; }
-		if *xoffset&int64(Widthptr-1) != 0 {
+		if off&int64(Widthptr-1) != 0 {
 			Fatalf("onebitwalktype1: invalid alignment, %v", t)
 		}
-		bv.Set(int32(*xoffset / int64(Widthptr)))   // pointer in first slot
-		bv.Set(int32(*xoffset/int64(Widthptr) + 1)) // pointer in second slot
-		*xoffset += t.Width
+		bv.Set(int32(off / int64(Widthptr)))   // pointer in first slot
+		bv.Set(int32(off/int64(Widthptr) + 1)) // pointer in second slot
 
 	case TSLICE:
 		// struct { byte *array; uintgo len; uintgo cap; }
-		if *xoffset&int64(Widthptr-1) != 0 {
+		if off&int64(Widthptr-1) != 0 {
 			Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
 		}
-		bv.Set(int32(*xoffset / int64(Widthptr))) // pointer in first slot (BitsPointer)
-		*xoffset += t.Width
+		bv.Set(int32(off / int64(Widthptr))) // pointer in first slot (BitsPointer)
 
 	case TARRAY:
+		elt := t.Elem()
+		if elt.Width == 0 {
+			// Short-circuit for #20739.
+			break
+		}
 		for i := int64(0); i < t.NumElem(); i++ {
-			onebitwalktype1(t.Elem(), xoffset, bv)
+			onebitwalktype1(elt, off, bv)
+			off += elt.Width
 		}
 
 	case TSTRUCT:
-		var o int64
-		for _, t1 := range t.Fields().Slice() {
-			fieldoffset := t1.Offset
-			*xoffset += fieldoffset - o
-			onebitwalktype1(t1.Type, xoffset, bv)
-			o = fieldoffset + t1.Type.Width
+		for _, f := range t.Fields().Slice() {
+			onebitwalktype1(f.Type, off+f.Offset, bv)
 		}
 
-		*xoffset += t.Width - o
-
 	default:
 		Fatalf("onebitwalktype1: unexpected type, %v", t)
 	}
 }
 
-// Returns the number of words of local variables.
-func localswords(lv *Liveness) int32 {
+// localWords returns the number of words of local variables.
+func (lv *Liveness) localWords() int32 {
 	return int32(lv.stkptrsize / int64(Widthptr))
 }
 
-// Returns the number of words of in and out arguments.
-func argswords(lv *Liveness) int32 {
+// argWords returns the number of words of in and out arguments.
+func (lv *Liveness) argWords() int32 {
 	return int32(lv.fn.Type.ArgWidth() / int64(Widthptr))
 }
 
 // Generates live pointer value maps for arguments and local variables. The
 // this argument and the in arguments are always assumed live. The vars
 // argument is a slice of *Nodes.
-func onebitlivepointermap(lv *Liveness, liveout bvec, vars []*Node, args bvec, locals bvec) {
-	var xoffset int64
-
+func (lv *Liveness) pointerMap(liveout bvec, vars []*Node, args, locals bvec) {
 	for i := int32(0); ; i++ {
 		i = liveout.Next(i)
 		if i < 0 {
@@ -465,12 +438,10 @@
 		node := vars[i]
 		switch node.Class() {
 		case PAUTO:
-			xoffset = node.Xoffset + lv.stkptrsize
-			onebitwalktype1(node.Type, &xoffset, locals)
+			onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals)
 
 		case PPARAM, PPARAMOUT:
-			xoffset = node.Xoffset
-			onebitwalktype1(node.Type, &xoffset, args)
+			onebitwalktype1(node.Type, node.Xoffset, args)
 		}
 	}
 }
@@ -484,7 +455,7 @@
 // Initializes the sets for solving the live variables. Visits all the
 // instructions in each basic block to summarizes the information at each basic
 // block
-func livenessprologue(lv *Liveness) {
+func (lv *Liveness) prologue() {
 	lv.initcache()
 
 	for _, b := range lv.f.Blocks {
@@ -518,7 +489,7 @@
 }
 
 // Solve the liveness dataflow equations.
-func livenesssolve(lv *Liveness) {
+func (lv *Liveness) solve() {
 	// These temporary bitvectors exist to avoid successive allocations and
 	// frees within the loop.
 	newlivein := bvalloc(int32(len(lv.vars)))
@@ -618,7 +589,7 @@
 
 // Visits all instructions in a basic block and computes a bit vector of live
 // variables at each safe point locations.
-func livenessepilogue(lv *Liveness) {
+func (lv *Liveness) epilogue() {
 	nvars := int32(len(lv.vars))
 	liveout := bvalloc(nvars)
 	any := bvalloc(nvars)
@@ -721,7 +692,7 @@
 	for _, b := range lv.f.Blocks {
 		be := lv.blockEffects(b)
 
-		// walk backward, emit pcdata and populate the maps
+		// walk backward, construct maps at each safe point
 		index := int32(be.lastbitmapindex)
 		if index < 0 {
 			// the first block we encounter should have the ATEXT so
@@ -924,13 +895,7 @@
 // clobberPtr generates a clobber of the pointer at offset offset in v.
 // The clobber instruction is added at the end of b.
 func clobberPtr(b *ssa.Block, v *Node, offset int64) {
-	var aux interface{}
-	if v.Class() == PAUTO {
-		aux = &ssa.AutoSymbol{Node: v}
-	} else {
-		aux = &ssa.ArgSymbol{Node: v}
-	}
-	b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, aux)
+	b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, v)
 }
 
 func (lv *Liveness) avarinitanyall(b *ssa.Block, any, all bvec) {
@@ -988,7 +953,7 @@
 // is actually a net loss: we save about 50k of argument bitmaps but the new
 // PCDATA tables cost about 100k. So for now we keep using a single index for
 // both bitmap lists.
-func livenesscompact(lv *Liveness) {
+func (lv *Liveness) compact() {
 	// Linear probing hash table of bitmaps seen so far.
 	// The hash table has 4n entries to keep the linear
 	// scan short. An entry of -1 indicates an empty slot.
@@ -1047,7 +1012,8 @@
 	}
 	lv.livevars = lv.livevars[:uniq]
 
-	// Rewrite PCDATA instructions to use new numbering.
+	// Record compacted stack map indexes for each value.
+	// These will later become PCDATA instructions.
 	lv.showlive(nil, lv.livevars[0])
 	pos := 1
 	lv.stackMapIndex = make(map[*ssa.Value]int)
@@ -1138,7 +1104,7 @@
 // Prints the computed liveness information and inputs, for debugging.
 // This format synthesizes the information used during the multiple passes
 // into a single presentation.
-func livenessprintdebug(lv *Liveness) {
+func (lv *Liveness) printDebug() {
 	fmt.Printf("liveness: %s\n", lv.fn.funcname())
 
 	pcdata := 0
@@ -1250,12 +1216,12 @@
 // first word dumped is the total number of bitmaps. The second word is the
 // length of the bitmaps. All bitmaps are assumed to be of equal length. The
 // remaining bytes are the raw bitmaps.
-func livenessemit(lv *Liveness, argssym, livesym *obj.LSym) {
-	args := bvalloc(argswords(lv))
+func (lv *Liveness) emit(argssym, livesym *obj.LSym) {
+	args := bvalloc(lv.argWords())
 	aoff := duint32(argssym, 0, uint32(len(lv.livevars))) // number of bitmaps
 	aoff = duint32(argssym, aoff, uint32(args.n))         // number of bits in each bitmap
 
-	locals := bvalloc(localswords(lv))
+	locals := bvalloc(lv.localWords())
 	loff := duint32(livesym, 0, uint32(len(lv.livevars))) // number of bitmaps
 	loff = duint32(livesym, loff, uint32(locals.n))       // number of bits in each bitmap
 
@@ -1263,7 +1229,7 @@
 		args.Clear()
 		locals.Clear()
 
-		onebitlivepointermap(lv, live, lv.vars, args, locals)
+		lv.pointerMap(live, lv.vars, args, locals)
 
 		aoff = dbvec(argssym, aoff, args)
 		loff = dbvec(livesym, loff, locals)
@@ -1288,18 +1254,18 @@
 	lv := newliveness(e.curfn, f, vars, idx, e.stkptrsize)
 
 	// Run the dataflow framework.
-	livenessprologue(lv)
-	livenesssolve(lv)
-	livenessepilogue(lv)
-	livenesscompact(lv)
+	lv.prologue()
+	lv.solve()
+	lv.epilogue()
+	lv.compact()
 	lv.clobber()
 	if debuglive >= 2 {
-		livenessprintdebug(lv)
+		lv.printDebug()
 	}
 
 	// Emit the live pointer map data structures
 	if ls := e.curfn.Func.lsym; ls != nil {
-		livenessemit(lv, &ls.Func.GCArgs, &ls.Func.GCLocals)
+		lv.emit(&ls.Func.GCArgs, &ls.Func.GCLocals)
 	}
 	return lv.stackMapIndex
 }
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go
index cfb8031..4b92ce9 100644
--- a/src/cmd/compile/internal/gc/racewalk.go
+++ b/src/cmd/compile/internal/gc/racewalk.go
@@ -70,11 +70,15 @@
 		nodpc := *nodfp
 		nodpc.Type = types.Types[TUINTPTR]
 		nodpc.Xoffset = int64(-Widthptr)
+		savedLineno := lineno
+		lineno = src.NoXPos
 		nd := mkcall("racefuncenter", nil, nil, &nodpc)
+
 		fn.Func.Enter.Prepend(nd)
 		nd = mkcall("racefuncexit", nil, nil)
 		fn.Func.Exit.Append(nd)
 		fn.Func.Dcl = append(fn.Func.Dcl, &nodpc)
+		lineno = savedLineno
 	}
 
 	if Debug['W'] != 0 {
@@ -140,11 +144,9 @@
 	case OAS, OAS2FUNC:
 		instrumentnode(&n.Left, init, 1, 0)
 		instrumentnode(&n.Right, init, 0, 0)
-		goto ret
 
 		// can't matter
 	case OCFUNC, OVARKILL, OVARLIVE:
-		goto ret
 
 	case OBLOCK:
 		ls := n.List.Slice()
@@ -162,26 +164,25 @@
 			instrumentnode(&ls[i], &ls[i].Ninit, 0, 0)
 			afterCall = (op == OCALLFUNC || op == OCALLMETH || op == OCALLINTER)
 		}
-		goto ret
 
 	case ODEFER:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case OPROC:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case OCALLINTER:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
-	// Instrument dst argument of runtime.writebarrier* calls
-	// as we do not instrument runtime code.
-	// typedslicecopy is instrumented in runtime.
 	case OCALLFUNC:
+		// Note that runtime.typedslicecopy is the only
+		// assignment-like function call in the AST at this
+		// point (between walk and SSA); since we don't
+		// instrument it here, typedslicecopy is manually
+		// instrumented in runtime. Calls to the write barrier
+		// and typedmemmove are created later by SSA, so those
+		// still appear as OAS nodes at this point.
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case ONOT,
 		OMINUS,
@@ -190,28 +191,23 @@
 		OIMAG,
 		OCOM:
 		instrumentnode(&n.Left, init, wr, 0)
-		goto ret
 
 	case ODOTINTER:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case ODOT:
 		instrumentnode(&n.Left, init, 0, 1)
 		callinstr(&n, init, wr, skip)
-		goto ret
 
 	case ODOTPTR: // dst = (*x).f with implicit *; otherwise it's ODOT+OIND
 		instrumentnode(&n.Left, init, 0, 0)
 
 		callinstr(&n, init, wr, skip)
-		goto ret
 
 	case OIND: // *p
 		instrumentnode(&n.Left, init, 0, 0)
 
 		callinstr(&n, init, wr, skip)
-		goto ret
 
 	case OSPTR, OLEN, OCAP:
 		instrumentnode(&n.Left, init, 0, 0)
@@ -223,8 +219,6 @@
 			callinstr(&n1, init, 0, skip)
 		}
 
-		goto ret
-
 	case OLSH,
 		ORSH,
 		OAND,
@@ -243,7 +237,6 @@
 		OCOMPLEX:
 		instrumentnode(&n.Left, init, wr, 0)
 		instrumentnode(&n.Right, init, wr, 0)
-		goto ret
 
 	case OANDAND, OOROR:
 		instrumentnode(&n.Left, init, wr, 0)
@@ -254,24 +247,18 @@
 		// so instrumentation goes to n->right->ninit, not init.
 		instrumentnode(&n.Right, &n.Right.Ninit, wr, 0)
 
-		goto ret
-
 	case ONAME:
 		callinstr(&n, init, wr, skip)
-		goto ret
 
 	case OCONV:
 		instrumentnode(&n.Left, init, wr, 0)
-		goto ret
 
 	case OCONVNOP:
 		instrumentnode(&n.Left, init, wr, 0)
-		goto ret
 
 	case ODIV, OMOD:
 		instrumentnode(&n.Left, init, wr, 0)
 		instrumentnode(&n.Right, init, wr, 0)
-		goto ret
 
 	case OINDEX:
 		if !n.Left.Type.IsArray() {
@@ -281,14 +268,13 @@
 			instrumentnode(&n.Left, init, wr, 0)
 
 			instrumentnode(&n.Right, init, 0, 0)
-			goto ret
+			break
 		}
 
 		instrumentnode(&n.Right, init, 0, 0)
 		if !n.Left.Type.IsString() {
 			callinstr(&n, init, wr, skip)
 		}
-		goto ret
 
 	case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
 		instrumentnode(&n.Left, init, 0, 0)
@@ -297,34 +283,26 @@
 		instrumentnode(&high, init, 0, 0)
 		instrumentnode(&max, init, 0, 0)
 		n.SetSliceBounds(low, high, max)
-		goto ret
 
 	case OADDR:
 		instrumentnode(&n.Left, init, 0, 1)
-		goto ret
 
 		// n->left is Type* which is not interesting.
 	case OEFACE:
 		instrumentnode(&n.Right, init, 0, 0)
 
-		goto ret
-
 	case OITAB, OIDATA:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case OSTRARRAYBYTETMP:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 	case OAS2DOTTYPE:
 		instrumentnode(&n.Left, init, 1, 0)
 		instrumentnode(&n.Right, init, 0, 0)
-		goto ret
 
 	case ODOTTYPE, ODOTTYPE2:
 		instrumentnode(&n.Left, init, 0, 0)
-		goto ret
 
 		// should not appear in AST by now
 	case OSEND,
@@ -332,7 +310,6 @@
 		OCLOSE,
 		ONEW,
 		OXCASE,
-		OXFALL,
 		OCASE,
 		OPANIC,
 		ORECOVER,
@@ -377,13 +354,11 @@
 		if n.Right != nil {
 			instrumentnode(&n.Right, &n.Right.Ninit, 0, 0)
 		}
-		goto ret
 
 	case OIF, OSWITCH:
 		if n.Left != nil {
 			instrumentnode(&n.Left, &n.Left.Ninit, 0, 0)
 		}
-		goto ret
 
 		// just do generic traversal
 	case OCALLMETH,
@@ -396,7 +371,6 @@
 		OFALL,
 		OGOTO,
 		OLABEL:
-		goto ret
 
 		// does not require instrumentation
 	case OPRINT, // don't bother instrumenting it
@@ -412,10 +386,8 @@
 		ONONAME,
 		OLITERAL,
 		OTYPESW: // ignored by code generation, do not instrument.
-		goto ret
 	}
 
-ret:
 	if n.Op != OBLOCK { // OBLOCK is handled above in a special way.
 		instrumentlist(n.List, init)
 	}
@@ -462,6 +434,15 @@
 		return false
 	}
 	t := n.Type
+	// dowidth may not have been called for PEXTERN.
+	dowidth(t)
+	w := t.Width
+	if w == BADWIDTH {
+		Fatalf("instrument: %v badwidth", t)
+	}
+	if w == 0 {
+		return false // can't race on zero-sized things
+	}
 	if isartificial(n) {
 		return false
 	}
@@ -479,9 +460,15 @@
 	// that has got a pointer inside. Whether it points to
 	// the heap or not is impossible to know at compile time
 	if class == PAUTOHEAP || class == PEXTERN || b.Op == OINDEX || b.Op == ODOTPTR || b.Op == OIND {
-		hascalls := 0
-		foreach(n, hascallspred, &hascalls)
-		if hascalls != 0 {
+		hasCalls := false
+		inspect(n, func(n *Node) bool {
+			switch n.Op {
+			case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
+				hasCalls = true
+			}
+			return !hasCalls
+		})
+		if hasCalls {
 			n = detachexpr(n, init)
 			*np = n
 		}
@@ -494,26 +481,19 @@
 			if wr != 0 {
 				name = "msanwrite"
 			}
-			// dowidth may not have been called for PEXTERN.
-			dowidth(t)
-			w := t.Width
-			if w == BADWIDTH {
-				Fatalf("instrument: %v badwidth", t)
-			}
 			f = mkcall(name, nil, init, uintptraddr(n), nodintconst(w))
-		} else if flag_race && (t.IsStruct() || t.IsArray()) {
+		} else if flag_race && t.NumComponents() > 1 {
+			// for composite objects we have to write every address
+			// because a write might happen to any subobject.
+			// composites with only one element don't have subobjects, though.
 			name := "racereadrange"
 			if wr != 0 {
 				name = "racewriterange"
 			}
-			// dowidth may not have been called for PEXTERN.
-			dowidth(t)
-			w := t.Width
-			if w == BADWIDTH {
-				Fatalf("instrument: %v badwidth", t)
-			}
 			f = mkcall(name, nil, init, uintptraddr(n), nodintconst(w))
 		} else if flag_race {
+			// for non-composite objects we can write just the start
+			// address, as any write must write the first byte.
 			name := "raceread"
 			if wr != 0 {
 				name = "racewrite"
@@ -552,10 +532,6 @@
 		makeaddable(n.Left)
 
 		// nothing to do
-	case ODOTPTR:
-		fallthrough
-	default:
-		break
 	}
 }
 
@@ -580,34 +556,6 @@
 	return ind
 }
 
-func foreachnode(n *Node, f func(*Node, interface{}), c interface{}) {
-	if n != nil {
-		f(n, c)
-	}
-}
-
-func foreachlist(l Nodes, f func(*Node, interface{}), c interface{}) {
-	for _, n := range l.Slice() {
-		foreachnode(n, f, c)
-	}
-}
-
-func foreach(n *Node, f func(*Node, interface{}), c interface{}) {
-	foreachlist(n.Ninit, f, c)
-	foreachnode(n.Left, f, c)
-	foreachnode(n.Right, f, c)
-	foreachlist(n.List, f, c)
-	foreachlist(n.Nbody, f, c)
-	foreachlist(n.Rlist, f, c)
-}
-
-func hascallspred(n *Node, c interface{}) {
-	switch n.Op {
-	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
-		(*c.(*int))++
-	}
-}
-
 // appendinit is like addinit in subr.go
 // but appends rather than prepends.
 func appendinit(np **Node, init Nodes) {
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index 032601c..db852e8 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -7,19 +7,12 @@
 import (
 	"cmd/compile/internal/types"
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"unicode/utf8"
 )
 
 // range
 func typecheckrange(n *Node) {
-	var toomany int
-	var why string
-	var t1 *types.Type
-	var t2 *types.Type
-	var v1 *Node
-	var v2 *Node
-	var ls []*Node
-
 	// Typechecking order is important here:
 	// 0. first typecheck range expression (slice/map/chan),
 	//	it is evaluated only once and so logically it is not part of the loop.
@@ -29,15 +22,31 @@
 	// 2. decldepth++ to denote loop body.
 	// 3. typecheck body.
 	// 4. decldepth--.
+	typecheckrangeExpr(n)
 
+	// second half of dance, the first half being typecheckrangeExpr
+	n.SetTypecheck(1)
+	ls := n.List.Slice()
+	for i1, n1 := range ls {
+		if n1.Typecheck() == 0 {
+			ls[i1] = typecheck(ls[i1], Erv|Easgn)
+		}
+	}
+
+	decldepth++
+	typecheckslice(n.Nbody.Slice(), Etop)
+	decldepth--
+}
+
+func typecheckrangeExpr(n *Node) {
 	n.Right = typecheck(n.Right, Erv)
 
 	t := n.Right.Type
 	if t == nil {
-		goto out
+		return
 	}
 	// delicate little dance.  see typecheckas2
-	ls = n.List.Slice()
+	ls := n.List.Slice()
 	for i1, n1 := range ls {
 		if n1.Name == nil || n1.Name.Defn != n {
 			ls[i1] = typecheck(ls[i1], Erv|Easgn)
@@ -49,11 +58,12 @@
 	}
 	n.Type = t
 
-	toomany = 0
+	var t1, t2 *types.Type
+	toomany := false
 	switch t.Etype {
 	default:
-		yyerror("cannot range over %L", n.Right)
-		goto out
+		yyerrorl(n.Pos, "cannot range over %L", n.Right)
+		return
 
 	case TARRAY, TSLICE:
 		t1 = types.Types[TINT]
@@ -65,14 +75,14 @@
 
 	case TCHAN:
 		if !t.ChanDir().CanRecv() {
-			yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
-			goto out
+			yyerrorl(n.Pos, "invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
+			return
 		}
 
 		t1 = t.Elem()
 		t2 = nil
 		if n.List.Len() == 2 {
-			toomany = 1
+			toomany = true
 		}
 
 	case TSTRING:
@@ -80,15 +90,14 @@
 		t2 = types.Runetype
 	}
 
-	if n.List.Len() > 2 || toomany != 0 {
-		yyerror("too many variables in range")
+	if n.List.Len() > 2 || toomany {
+		yyerrorl(n.Pos, "too many variables in range")
 	}
 
-	v1 = nil
+	var v1, v2 *Node
 	if n.List.Len() != 0 {
 		v1 = n.List.First()
 	}
-	v2 = nil
 	if n.List.Len() > 1 {
 		v2 = n.List.Second()
 	}
@@ -104,11 +113,12 @@
 		v2 = nil
 	}
 
+	var why string
 	if v1 != nil {
 		if v1.Name != nil && v1.Name.Defn == n {
 			v1.Type = t1
 		} else if v1.Type != nil && assignop(t1, v1.Type, &why) == 0 {
-			yyerror("cannot assign type %v to %L in range%s", t1, v1, why)
+			yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why)
 		}
 		checkassign(n, v1)
 	}
@@ -117,24 +127,26 @@
 		if v2.Name != nil && v2.Name.Defn == n {
 			v2.Type = t2
 		} else if v2.Type != nil && assignop(t2, v2.Type, &why) == 0 {
-			yyerror("cannot assign type %v to %L in range%s", t2, v2, why)
+			yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why)
 		}
 		checkassign(n, v2)
 	}
+}
 
-	// second half of dance
-out:
-	n.SetTypecheck(1)
-	ls = n.List.Slice()
-	for i1, n1 := range ls {
-		if n1.Typecheck() == 0 {
-			ls[i1] = typecheck(ls[i1], Erv|Easgn)
+func cheapComputableIndex(width int64) bool {
+	switch thearch.LinkArch.Family {
+	// MIPS does not have R+R addressing
+	// Arm64 may lack ability to generate this code in our assembler,
+	// but the architecture supports it.
+	case sys.PPC64, sys.S390X:
+		return width == 1
+	case sys.AMD64, sys.I386, sys.ARM64, sys.ARM:
+		switch width {
+		case 1, 2, 4, 8:
+			return true
 		}
 	}
-
-	decldepth++
-	typecheckslice(n.Nbody.Slice(), Etop)
-	decldepth--
+	return false
 }
 
 // walkrange transforms various forms of ORANGE into
@@ -155,27 +167,36 @@
 	lno := setlineno(a)
 	n.Right = nil
 
-	var v1 *Node
-	if n.List.Len() != 0 {
+	var v1, v2 *Node
+	l := n.List.Len()
+	if l > 0 {
 		v1 = n.List.First()
 	}
-	var v2 *Node
-	if n.List.Len() > 1 && !isblank(n.List.Second()) {
+
+	if l > 1 {
 		v2 = n.List.Second()
 	}
 
+	if isblank(v2) {
+		v2 = nil
+	}
+
+	if isblank(v1) && v2 == nil {
+		v1 = nil
+	}
+
 	if v1 == nil && v2 != nil {
 		Fatalf("walkrange: v2 != nil while v1 == nil")
 	}
 
-	var ifGuard *Node
-
-	translatedLoopOp := OFOR
-
 	// n.List has no meaning anymore, clear it
 	// to avoid erroneous processing by racewalk.
 	n.List.Set(nil)
 
+	var ifGuard *Node
+
+	translatedLoopOp := OFOR
+
 	var body []*Node
 	var init []*Node
 	switch t.Etype {
@@ -193,65 +214,83 @@
 
 		hv1 := temp(types.Types[TINT])
 		hn := temp(types.Types[TINT])
-		var hp *Node
 
 		init = append(init, nod(OAS, hv1, nil))
 		init = append(init, nod(OAS, hn, nod(OLEN, ha, nil)))
 
-		if v2 != nil {
-			hp = temp(types.NewPtr(n.Type.Elem()))
-			tmp := nod(OINDEX, ha, nodintconst(0))
-			tmp.SetBounded(true)
-			init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil)))
-		}
-
 		n.Left = nod(OLT, hv1, hn)
 		n.Right = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)))
-		if v1 == nil {
-			body = nil
-		} else if v2 == nil {
-			body = []*Node{nod(OAS, v1, hv1)}
-		} else { // for i,a := range thing { body }
-			if objabi.Preemptibleloops_enabled != 0 {
-				// Doing this transformation makes a bounds check removal less trivial; see #20711
-				// TODO enhance the preemption check insertion so that this transformation is not necessary.
-				ifGuard = nod(OIF, nil, nil)
-				ifGuard.Left = nod(OLT, hv1, hn)
-				translatedLoopOp = OFORUNTIL
-			}
 
+		// for range ha { body }
+		if v1 == nil {
+			break
+		}
+
+		// for v1 := range ha { body }
+		if v2 == nil {
+			body = []*Node{nod(OAS, v1, hv1)}
+			break
+		}
+
+		// for v1, v2 := range ha { body }
+		if cheapComputableIndex(n.Type.Elem().Width) {
+			// v1, v2 = hv1, ha[hv1]
+			tmp := nod(OINDEX, ha, hv1)
+			tmp.SetBounded(true)
+			// Use OAS2 to correctly handle assignments
+			// of the form "v1, a[v1] := range".
 			a := nod(OAS2, nil, nil)
 			a.List.Set2(v1, v2)
-			a.Rlist.Set2(hv1, nod(OIND, hp, nil))
+			a.Rlist.Set2(hv1, tmp)
 			body = []*Node{a}
-
-			// Advance pointer as part of increment.
-			// We used to advance the pointer before executing the loop body,
-			// but doing so would make the pointer point past the end of the
-			// array during the final iteration, possibly causing another unrelated
-			// piece of memory not to be garbage collected until the loop finished.
-			// Advancing during the increment ensures that the pointer p only points
-			// pass the end of the array during the final "p++; i++; if(i >= len(x)) break;",
-			// after which p is dead, so it cannot confuse the collector.
-			tmp := nod(OADD, hp, nodintconst(t.Elem().Width))
-
-			tmp.Type = hp.Type
-			tmp.SetTypecheck(1)
-			tmp.Right.Type = types.Types[types.Tptr]
-			tmp.Right.SetTypecheck(1)
-			a = nod(OAS, hp, tmp)
-			a = typecheck(a, Etop)
-			n.Right.Ninit.Set1(a)
+			break
 		}
 
+		if objabi.Preemptibleloops_enabled != 0 {
+			// Doing this transformation makes a bounds check removal less trivial; see #20711
+			// TODO enhance the preemption check insertion so that this transformation is not necessary.
+			ifGuard = nod(OIF, nil, nil)
+			ifGuard.Left = nod(OLT, hv1, hn)
+			translatedLoopOp = OFORUNTIL
+		}
+
+		hp := temp(types.NewPtr(n.Type.Elem()))
+		tmp := nod(OINDEX, ha, nodintconst(0))
+		tmp.SetBounded(true)
+		init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil)))
+
+		// Use OAS2 to correctly handle assignments
+		// of the form "v1, a[v1] := range".
+		a := nod(OAS2, nil, nil)
+		a.List.Set2(v1, v2)
+		a.Rlist.Set2(hv1, nod(OIND, hp, nil))
+		body = append(body, a)
+
+		// Advance pointer as part of increment.
+		// We used to advance the pointer before executing the loop body,
+		// but doing so would make the pointer point past the end of the
+		// array during the final iteration, possibly causing another unrelated
+		// piece of memory not to be garbage collected until the loop finished.
+		// Advancing during the increment ensures that the pointer p only points
+		// pass the end of the array during the final "p++; i++; if(i >= len(x)) break;",
+		// after which p is dead, so it cannot confuse the collector.
+		tmp = nod(OADD, hp, nodintconst(t.Elem().Width))
+
+		tmp.Type = hp.Type
+		tmp.SetTypecheck(1)
+		tmp.Right.Type = types.Types[types.Tptr]
+		tmp.Right.SetTypecheck(1)
+		a = nod(OAS, hp, tmp)
+		a = typecheck(a, Etop)
+		n.Right.Ninit.Set1(a)
+
 	case TMAP:
 		// orderstmt allocated the iterator for us.
 		// we only use a once, so no copy needed.
 		ha := a
 
-		th := hiter(t)
 		hit := prealloc[n]
-		hit.Type = th
+		th := hit.Type
 		n.Left = nil
 		keysym := th.Field(0).Sym // depends on layout of iterator struct.  See reflect.go:hiter
 		valsym := th.Field(1).Sym // ditto
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 91e6f46..66b1a8e 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -81,6 +81,7 @@
 
 func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{})
 func imethodSize() int     { return 4 + 4 }        // Sizeof(runtime.imethod{})
+
 func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{})
 	if t.Sym == nil && len(methods(t)) == 0 {
 		return 0
@@ -95,7 +96,8 @@
 	return f
 }
 
-func mapbucket(t *types.Type) *types.Type {
+// bmap makes the map bucket type given the type of the map.
+func bmap(t *types.Type) *types.Type {
 	if t.MapType().Bucket != nil {
 		return t.MapType().Bucket
 	}
@@ -120,11 +122,13 @@
 
 	arr = types.NewArray(keytype, BUCKETSIZE)
 	arr.SetNoalg(true)
-	field = append(field, makefield("keys", arr))
+	keys := makefield("keys", arr)
+	field = append(field, keys)
 
 	arr = types.NewArray(valtype, BUCKETSIZE)
 	arr.SetNoalg(true)
-	field = append(field, makefield("values", arr))
+	values := makefield("values", arr)
+	field = append(field, values)
 
 	// Make sure the overflow pointer is the last memory in the struct,
 	// because the runtime assumes it can use size-ptrSize as the
@@ -143,7 +147,7 @@
 	// so if the struct needs 64-bit padding (because a key or value does)
 	// then it would end with an extra 32-bit padding field.
 	// Preempt that by emitting the padding here.
-	if int(t.Val().Align) > Widthptr || int(t.Key().Align) > Widthptr {
+	if int(valtype.Align) > Widthptr || int(keytype.Align) > Widthptr {
 		field = append(field, makefield("pad", types.Types[TUINTPTR]))
 	}
 
@@ -154,22 +158,65 @@
 	// the type of the overflow field to uintptr in this case.
 	// See comment on hmap.overflow in ../../../../runtime/hashmap.go.
 	otyp := types.NewPtr(bucket)
-	if !types.Haspointers(t.Val()) && !types.Haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE {
+	if !types.Haspointers(valtype) && !types.Haspointers(keytype) {
 		otyp = types.Types[TUINTPTR]
 	}
-	ovf := makefield("overflow", otyp)
-	field = append(field, ovf)
+	overflow := makefield("overflow", otyp)
+	field = append(field, overflow)
 
 	// link up fields
 	bucket.SetNoalg(true)
-	bucket.SetLocal(t.Local())
 	bucket.SetFields(field[:])
 	dowidth(bucket)
 
+	// Check invariants that map code depends on.
+	if !IsComparable(t.Key()) {
+		Fatalf("unsupported map key type for %v", t)
+	}
+	if BUCKETSIZE < 8 {
+		Fatalf("bucket size too small for proper alignment")
+	}
+	if keytype.Align > BUCKETSIZE {
+		Fatalf("key align too big for %v", t)
+	}
+	if valtype.Align > BUCKETSIZE {
+		Fatalf("value align too big for %v", t)
+	}
+	if keytype.Width > MAXKEYSIZE {
+		Fatalf("key size to large for %v", t)
+	}
+	if valtype.Width > MAXVALSIZE {
+		Fatalf("value size to large for %v", t)
+	}
+	if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
+		Fatalf("key indirect incorrect for %v", t)
+	}
+	if t.Val().Width > MAXVALSIZE && !valtype.IsPtr() {
+		Fatalf("value indirect incorrect for %v", t)
+	}
+	if keytype.Width%int64(keytype.Align) != 0 {
+		Fatalf("key size not a multiple of key align for %v", t)
+	}
+	if valtype.Width%int64(valtype.Align) != 0 {
+		Fatalf("value size not a multiple of value align for %v", t)
+	}
+	if bucket.Align%keytype.Align != 0 {
+		Fatalf("bucket align not multiple of key align %v", t)
+	}
+	if bucket.Align%valtype.Align != 0 {
+		Fatalf("bucket align not multiple of value align %v", t)
+	}
+	if keys.Offset%int64(keytype.Align) != 0 {
+		Fatalf("bad alignment of keys in bmap for %v", t)
+	}
+	if values.Offset%int64(valtype.Align) != 0 {
+		Fatalf("bad alignment of values in bmap for %v", t)
+	}
+
 	// Double-check that overflow field is final memory in struct,
 	// with no padding at end. See comment above.
-	if ovf.Offset != bucket.Width-int64(Widthptr) {
-		Fatalf("bad math in mapbucket for %v", t)
+	if overflow.Offset != bucket.Width-int64(Widthptr) {
+		Fatalf("bad offset of overflow in bmap for %v", t)
 	}
 
 	t.MapType().Bucket = bucket
@@ -178,82 +225,114 @@
 	return bucket
 }
 
-// Builds a type representing a Hmap structure for the given map type.
-// Make sure this stays in sync with ../../../../runtime/hashmap.go!
+// hmap builds a type representing a Hmap structure for the given map type.
+// Make sure this stays in sync with ../../../../runtime/hashmap.go.
 func hmap(t *types.Type) *types.Type {
 	if t.MapType().Hmap != nil {
 		return t.MapType().Hmap
 	}
 
-	bucket := mapbucket(t)
+	bmap := bmap(t)
+
+	// build a struct:
+	// type hmap struct {
+	//    count      int
+	//    flags      uint8
+	//    B          uint8
+	//    noverflow  uint16
+	//    hash0      uint32
+	//    buckets    *bmap
+	//    oldbuckets *bmap
+	//    nevacuate  uintptr
+	//    extra      unsafe.Pointer // *mapextra
+	// }
+	// must match ../../../../runtime/hashmap.go:hmap.
 	fields := []*types.Field{
 		makefield("count", types.Types[TINT]),
 		makefield("flags", types.Types[TUINT8]),
 		makefield("B", types.Types[TUINT8]),
 		makefield("noverflow", types.Types[TUINT16]),
-		makefield("hash0", types.Types[TUINT32]),
-		makefield("buckets", types.NewPtr(bucket)),
-		makefield("oldbuckets", types.NewPtr(bucket)),
+		makefield("hash0", types.Types[TUINT32]), // Used in walk.go for OMAKEMAP.
+		makefield("buckets", types.NewPtr(bmap)), // Used in walk.go for OMAKEMAP.
+		makefield("oldbuckets", types.NewPtr(bmap)),
 		makefield("nevacuate", types.Types[TUINTPTR]),
-		makefield("overflow", types.Types[TUNSAFEPTR]),
+		makefield("extra", types.Types[TUNSAFEPTR]),
 	}
 
-	h := types.New(TSTRUCT)
-	h.SetNoalg(true)
-	h.SetLocal(t.Local())
-	h.SetFields(fields)
-	dowidth(h)
-	t.MapType().Hmap = h
-	h.StructType().Map = t
-	return h
+	hmap := types.New(TSTRUCT)
+	hmap.SetNoalg(true)
+	hmap.SetFields(fields)
+	dowidth(hmap)
+
+	// The size of hmap should be 48 bytes on 64 bit
+	// and 28 bytes on 32 bit platforms.
+	if size := int64(8 + 5*Widthptr); hmap.Width != size {
+		Fatalf("hmap size not correct: got %d, want %d", hmap.Width, size)
+	}
+
+	t.MapType().Hmap = hmap
+	hmap.StructType().Map = t
+	return hmap
 }
 
+// hiter builds a type representing an Hiter structure for the given map type.
+// Make sure this stays in sync with ../../../../runtime/hashmap.go.
 func hiter(t *types.Type) *types.Type {
 	if t.MapType().Hiter != nil {
 		return t.MapType().Hiter
 	}
 
+	hmap := hmap(t)
+	bmap := bmap(t)
+
 	// build a struct:
-	// hiter {
-	//    key *Key
-	//    val *Value
-	//    t *MapType
-	//    h *Hmap
-	//    buckets *Bucket
-	//    bptr *Bucket
-	//    overflow0 unsafe.Pointer
-	//    overflow1 unsafe.Pointer
+	// type hiter struct {
+	//    key         *Key
+	//    val         *Value
+	//    t           unsafe.Pointer // *MapType
+	//    h           *hmap
+	//    buckets     *bmap
+	//    bptr        *bmap
+	//    overflow    unsafe.Pointer // *[]*bmap
+	//    oldoverflow unsafe.Pointer // *[]*bmap
 	//    startBucket uintptr
-	//    stuff uintptr
-	//    bucket uintptr
+	//    offset      uint8
+	//    wrapped     bool
+	//    B           uint8
+	//    i           uint8
+	//    bucket      uintptr
 	//    checkBucket uintptr
 	// }
 	// must match ../../../../runtime/hashmap.go:hiter.
-	var field [12]*types.Field
-	field[0] = makefield("key", types.NewPtr(t.Key()))
-	field[1] = makefield("val", types.NewPtr(t.Val()))
-	field[2] = makefield("t", types.NewPtr(types.Types[TUINT8]))
-	field[3] = makefield("h", types.NewPtr(hmap(t)))
-	field[4] = makefield("buckets", types.NewPtr(mapbucket(t)))
-	field[5] = makefield("bptr", types.NewPtr(mapbucket(t)))
-	field[6] = makefield("overflow0", types.Types[TUNSAFEPTR])
-	field[7] = makefield("overflow1", types.Types[TUNSAFEPTR])
-	field[8] = makefield("startBucket", types.Types[TUINTPTR])
-	field[9] = makefield("stuff", types.Types[TUINTPTR]) // offset+wrapped+B+I
-	field[10] = makefield("bucket", types.Types[TUINTPTR])
-	field[11] = makefield("checkBucket", types.Types[TUINTPTR])
+	fields := []*types.Field{
+		makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
+		makefield("val", types.NewPtr(t.Val())), // Used in range.go for TMAP.
+		makefield("t", types.Types[TUNSAFEPTR]),
+		makefield("h", types.NewPtr(hmap)),
+		makefield("buckets", types.NewPtr(bmap)),
+		makefield("bptr", types.NewPtr(bmap)),
+		makefield("overflow", types.Types[TUNSAFEPTR]),
+		makefield("oldoverflow", types.Types[TUNSAFEPTR]),
+		makefield("startBucket", types.Types[TUINTPTR]),
+		makefield("offset", types.Types[TUINT8]),
+		makefield("wrapped", types.Types[TBOOL]),
+		makefield("B", types.Types[TUINT8]),
+		makefield("i", types.Types[TUINT8]),
+		makefield("bucket", types.Types[TUINTPTR]),
+		makefield("checkBucket", types.Types[TUINTPTR]),
+	}
 
 	// build iterator struct holding the above fields
-	i := types.New(TSTRUCT)
-	i.SetNoalg(true)
-	i.SetFields(field[:])
-	dowidth(i)
-	if i.Width != int64(12*Widthptr) {
-		Fatalf("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
+	hiter := types.New(TSTRUCT)
+	hiter.SetNoalg(true)
+	hiter.SetFields(fields)
+	dowidth(hiter)
+	if hiter.Width != int64(12*Widthptr) {
+		Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
 	}
-	t.MapType().Hiter = i
-	i.StructType().Map = t
-	return i
+	t.MapType().Hiter = hiter
+	hiter.StructType().Map = t
+	return hiter
 }
 
 // f is method type, with receiver.
@@ -359,18 +438,18 @@
 		if !sig.isym.Siggen() {
 			sig.isym.SetSiggen(true)
 			if !eqtype(this, it) || this.Width < int64(Widthptr) {
-				compiling_wrappers = 1
-				genwrapper(it, f, sig.isym, 1)
-				compiling_wrappers = 0
+				compiling_wrappers = true
+				genwrapper(it, f, sig.isym, true)
+				compiling_wrappers = false
 			}
 		}
 
 		if !sig.tsym.Siggen() {
 			sig.tsym.SetSiggen(true)
 			if !eqtype(this, t) {
-				compiling_wrappers = 1
-				genwrapper(t, f, sig.tsym, 0)
-				compiling_wrappers = 0
+				compiling_wrappers = true
+				genwrapper(t, f, sig.tsym, false)
+				compiling_wrappers = false
 			}
 		}
 	}
@@ -421,7 +500,7 @@
 		isym := methodsym(method, t, false)
 		if !isym.Siggen() {
 			isym.SetSiggen(true)
-			genwrapper(t, f, isym, 0)
+			genwrapper(t, f, isym, false)
 		}
 	}
 
@@ -492,32 +571,12 @@
 	return dsymptrOff(s, ot, pkg.Pathsym, 0)
 }
 
-// isExportedField reports whether a struct field is exported.
-// It also returns the package to use for PkgPath for an unexported field.
-func isExportedField(ft *types.Field) (bool, *types.Pkg) {
-	if ft.Sym != nil && ft.Embedded == 0 {
-		return exportname(ft.Sym.Name), ft.Sym.Pkg
-	} else {
-		if ft.Type.Sym != nil &&
-			(ft.Type.Sym.Pkg == builtinpkg || !exportname(ft.Type.Sym.Name)) {
-			return false, ft.Type.Sym.Pkg
-		} else {
-			return true, nil
-		}
-	}
-}
-
 // dnameField dumps a reflect.name for a struct field.
 func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
-	var name string
-	if ft.Sym != nil {
-		name = ft.Sym.Name
+	if !exportname(ft.Sym.Name) && ft.Sym.Pkg != spkg {
+		Fatalf("package mismatch for %v", ft.Sym)
 	}
-	isExported, fpkg := isExportedField(ft)
-	if isExported || fpkg == spkg {
-		fpkg = nil
-	}
-	nsym := dname(name, ft.Note, fpkg, isExported)
+	nsym := dname(ft.Sym.Name, ft.Note, nil, exportname(ft.Sym.Name))
 	return dsymptr(lsym, ot, nsym, 0)
 }
 
@@ -665,7 +724,7 @@
 		nsym := dname(a.name, "", pkg, exported)
 
 		ot = dsymptrOff(lsym, ot, nsym, 0)
-		ot = dmethodptrOff(lsym, ot, dtypesym(a.mtype).Linksym())
+		ot = dmethodptrOff(lsym, ot, dtypesym(a.mtype))
 		ot = dmethodptrOff(lsym, ot, a.isym.Linksym())
 		ot = dmethodptrOff(lsym, ot, a.tsym.Linksym())
 	}
@@ -788,7 +847,7 @@
 
 	sizeofAlg := 2 * Widthptr
 	if algarray == nil {
-		algarray = Sysfunc("algarray")
+		algarray = sysfunc("algarray")
 	}
 	dowidth(t)
 	alg := algtype(t)
@@ -804,7 +863,7 @@
 		if t.Sym != nil || methods(tptr) != nil {
 			sptrWeak = false
 		}
-		sptr = dtypesym(tptr).Linksym()
+		sptr = dtypesym(tptr)
 	}
 
 	gcsym, useGCProg, ptrdata := dgcsym(t)
@@ -901,10 +960,17 @@
 	return ot
 }
 
+// typeHasNoAlg returns whether t does not have any associated hash/eq
+// algorithms because t, or some component of t, is marked Noalg.
+func typeHasNoAlg(t *types.Type) bool {
+	a, bad := algtype1(t)
+	return a == ANOEQ && bad.Noalg()
+}
+
 func typesymname(t *types.Type) string {
 	name := t.ShortString()
 	// Use a separate symbol name for Noalg types for #17752.
-	if a, bad := algtype1(t); a == ANOEQ && bad.Noalg() {
+	if typeHasNoAlg(t) {
 		name = "noalg." + name
 	}
 	return name
@@ -1079,15 +1145,16 @@
 	return t
 }
 
-func dtypesym(t *types.Type) *types.Sym {
+func dtypesym(t *types.Type) *obj.LSym {
 	t = formalType(t)
 	if t.IsUntyped() {
 		Fatalf("dtypesym %v", t)
 	}
 
 	s := typesym(t)
+	lsym := s.Linksym()
 	if s.Siggen() {
-		return s
+		return lsym
 	}
 	s.SetSiggen(true)
 
@@ -1104,21 +1171,18 @@
 		dupok = obj.DUPOK
 	}
 
-	if myimportpath == "runtime" && (tbase == types.Types[tbase.Etype] || tbase == types.Bytetype || tbase == types.Runetype || tbase == types.Errortype) { // int, float, etc
-		goto ok
+	if myimportpath != "runtime" || (tbase != types.Types[tbase.Etype] && tbase != types.Bytetype && tbase != types.Runetype && tbase != types.Errortype) { // int, float, etc
+		// named types from other files are defined only by those files
+		if tbase.Sym != nil && tbase.Sym.Pkg != localpkg {
+			return lsym
+		}
+		// TODO(mdempsky): Investigate whether this can happen.
+		if isforw[tbase.Etype] {
+			return lsym
+		}
 	}
 
-	// named types from other files are defined only by those files
-	if tbase.Sym != nil && !tbase.Local() {
-		return s
-	}
-	if isforw[tbase.Etype] {
-		return s
-	}
-
-ok:
 	ot := 0
-	lsym := s.Linksym()
 	switch t.Etype {
 	default:
 		ot = dcommontype(lsym, ot, t)
@@ -1130,8 +1194,8 @@
 		t2 := types.NewSlice(t.Elem())
 		s2 := dtypesym(t2)
 		ot = dcommontype(lsym, ot, t)
-		ot = dsymptr(lsym, ot, s1.Linksym(), 0)
-		ot = dsymptr(lsym, ot, s2.Linksym(), 0)
+		ot = dsymptr(lsym, ot, s1, 0)
+		ot = dsymptr(lsym, ot, s2, 0)
 		ot = duintptr(lsym, ot, uint64(t.NumElem()))
 		ot = dextratype(lsym, ot, t, 0)
 
@@ -1139,14 +1203,14 @@
 		// ../../../../runtime/type.go:/sliceType
 		s1 := dtypesym(t.Elem())
 		ot = dcommontype(lsym, ot, t)
-		ot = dsymptr(lsym, ot, s1.Linksym(), 0)
+		ot = dsymptr(lsym, ot, s1, 0)
 		ot = dextratype(lsym, ot, t, 0)
 
 	case TCHAN:
 		// ../../../../runtime/type.go:/chanType
 		s1 := dtypesym(t.Elem())
 		ot = dcommontype(lsym, ot, t)
-		ot = dsymptr(lsym, ot, s1.Linksym(), 0)
+		ot = dsymptr(lsym, ot, s1, 0)
 		ot = duintptr(lsym, ot, uint64(t.ChanDir()))
 		ot = dextratype(lsym, ot, t, 0)
 
@@ -1164,8 +1228,8 @@
 		}
 
 		ot = dcommontype(lsym, ot, t)
-		inCount := t.Recvs().NumFields() + t.Params().NumFields()
-		outCount := t.Results().NumFields()
+		inCount := t.NumRecvs() + t.NumParams()
+		outCount := t.NumResults()
 		if isddd {
 			outCount |= 1 << 15
 		}
@@ -1175,18 +1239,18 @@
 			ot += 4 // align for *rtype
 		}
 
-		dataAdd := (inCount + t.Results().NumFields()) * Widthptr
+		dataAdd := (inCount + t.NumResults()) * Widthptr
 		ot = dextratype(lsym, ot, t, dataAdd)
 
 		// Array of rtype pointers follows funcType.
 		for _, t1 := range t.Recvs().Fields().Slice() {
-			ot = dsymptr(lsym, ot, dtypesym(t1.Type).Linksym(), 0)
+			ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
 		}
 		for _, t1 := range t.Params().Fields().Slice() {
-			ot = dsymptr(lsym, ot, dtypesym(t1.Type).Linksym(), 0)
+			ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
 		}
 		for _, t1 := range t.Results().Fields().Slice() {
-			ot = dsymptr(lsym, ot, dtypesym(t1.Type).Linksym(), 0)
+			ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
 		}
 
 	case TINTER:
@@ -1221,20 +1285,20 @@
 			nsym := dname(a.name, "", pkg, exported)
 
 			ot = dsymptrOff(lsym, ot, nsym, 0)
-			ot = dsymptrOff(lsym, ot, dtypesym(a.type_).Linksym(), 0)
+			ot = dsymptrOff(lsym, ot, dtypesym(a.type_), 0)
 		}
 
 	// ../../../../runtime/type.go:/mapType
 	case TMAP:
 		s1 := dtypesym(t.Key())
 		s2 := dtypesym(t.Val())
-		s3 := dtypesym(mapbucket(t))
+		s3 := dtypesym(bmap(t))
 		s4 := dtypesym(hmap(t))
 		ot = dcommontype(lsym, ot, t)
-		ot = dsymptr(lsym, ot, s1.Linksym(), 0)
-		ot = dsymptr(lsym, ot, s2.Linksym(), 0)
-		ot = dsymptr(lsym, ot, s3.Linksym(), 0)
-		ot = dsymptr(lsym, ot, s4.Linksym(), 0)
+		ot = dsymptr(lsym, ot, s1, 0)
+		ot = dsymptr(lsym, ot, s2, 0)
+		ot = dsymptr(lsym, ot, s3, 0)
+		ot = dsymptr(lsym, ot, s4, 0)
 		if t.Key().Width > MAXKEYSIZE {
 			ot = duint8(lsym, ot, uint8(Widthptr))
 			ot = duint8(lsym, ot, 1) // indirect
@@ -1251,7 +1315,7 @@
 			ot = duint8(lsym, ot, 0) // not indirect
 		}
 
-		ot = duint16(lsym, ot, uint16(mapbucket(t).Width))
+		ot = duint16(lsym, ot, uint16(bmap(t).Width))
 		ot = duint8(lsym, ot, uint8(obj.Bool2int(isreflexive(t.Key()))))
 		ot = duint8(lsym, ot, uint8(obj.Bool2int(needkeyupdate(t.Key()))))
 		ot = dextratype(lsym, ot, t, 0)
@@ -1269,45 +1333,43 @@
 		s1 := dtypesym(t.Elem())
 
 		ot = dcommontype(lsym, ot, t)
-		ot = dsymptr(lsym, ot, s1.Linksym(), 0)
+		ot = dsymptr(lsym, ot, s1, 0)
 		ot = dextratype(lsym, ot, t, 0)
 
 	// ../../../../runtime/type.go:/structType
 	// for security, only the exported fields.
 	case TSTRUCT:
-		n := 0
-
-		for _, t1 := range t.Fields().Slice() {
+		fields := t.Fields().Slice()
+		for _, t1 := range fields {
 			dtypesym(t1.Type)
-			n++
 		}
 
-		ot = dcommontype(lsym, ot, t)
-		pkg := localpkg
-		if t.Sym != nil {
-			pkg = t.Sym.Pkg
-		} else {
-			// Unnamed type. Grab the package from the first field, if any.
-			for _, f := range t.Fields().Slice() {
-				if f.Embedded != 0 {
-					continue
-				}
-				pkg = f.Sym.Pkg
+		// All non-exported struct field names within a struct
+		// type must originate from a single package. By
+		// identifying and recording that package within the
+		// struct type descriptor, we can omit that
+		// information from the field descriptors.
+		var spkg *types.Pkg
+		for _, f := range fields {
+			if !exportname(f.Sym.Name) {
+				spkg = f.Sym.Pkg
 				break
 			}
 		}
-		ot = dgopkgpath(lsym, ot, pkg)
-		ot = dsymptr(lsym, ot, lsym, ot+3*Widthptr+uncommonSize(t))
-		ot = duintptr(lsym, ot, uint64(n))
-		ot = duintptr(lsym, ot, uint64(n))
 
-		dataAdd := n * structfieldSize()
+		ot = dcommontype(lsym, ot, t)
+		ot = dgopkgpath(lsym, ot, spkg)
+		ot = dsymptr(lsym, ot, lsym, ot+3*Widthptr+uncommonSize(t))
+		ot = duintptr(lsym, ot, uint64(len(fields)))
+		ot = duintptr(lsym, ot, uint64(len(fields)))
+
+		dataAdd := len(fields) * structfieldSize()
 		ot = dextratype(lsym, ot, t, dataAdd)
 
-		for _, f := range t.Fields().Slice() {
+		for _, f := range fields {
 			// ../../../../runtime/type.go:/structField
-			ot = dnameField(lsym, ot, pkg, f)
-			ot = dsymptr(lsym, ot, dtypesym(f.Type).Linksym(), 0)
+			ot = dnameField(lsym, ot, spkg, f)
+			ot = dsymptr(lsym, ot, dtypesym(f.Type), 0)
 			offsetAnon := uint64(f.Offset) << 1
 			if offsetAnon>>1 != uint64(f.Offset) {
 				Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
@@ -1339,9 +1401,13 @@
 			keep = true
 		}
 	}
+	// Do not put Noalg types in typelinks.  See issue #22605.
+	if typeHasNoAlg(t) {
+		keep = false
+	}
 	lsym.Set(obj.AttrMakeTypelink, keep)
 
-	return s
+	return lsym
 }
 
 // for each itabEntry, gather the methods on
@@ -1408,7 +1474,7 @@
 	}
 
 	// keep this arithmetic in sync with *itab layout
-	methodnum := int((offset - 3*int64(Widthptr) - 8) / int64(Widthptr))
+	methodnum := int((offset - 2*int64(Widthptr) - 8) / int64(Widthptr))
 	if methodnum >= len(syms) {
 		return nil
 	}
@@ -1457,23 +1523,19 @@
 		// type itab struct {
 		//   inter  *interfacetype
 		//   _type  *_type
-		//   link   *itab
 		//   hash   uint32
-		//   bad    bool
-		//   inhash bool
-		//   unused [2]byte
+		//   _      [4]byte
 		//   fun    [1]uintptr // variable sized
 		// }
-		o := dsymptr(i.lsym, 0, dtypesym(i.itype).Linksym(), 0)
-		o = dsymptr(i.lsym, o, dtypesym(i.t).Linksym(), 0)
-		o += Widthptr                          // skip link field
-		o = duint32(i.lsym, o, typehash(i.t))  // copy of type hash
-		o += 4                                 // skip bad/inhash/unused fields
-		o += len(imethods(i.itype)) * Widthptr // skip fun method pointers
-		// at runtime the itab will contain pointers to types, other itabs and
-		// method functions. None are allocated on heap, so we can use obj.NOPTR.
-		ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.NOPTR))
-
+		o := dsymptr(i.lsym, 0, dtypesym(i.itype), 0)
+		o = dsymptr(i.lsym, o, dtypesym(i.t), 0)
+		o = duint32(i.lsym, o, typehash(i.t)) // copy of type hash
+		o += 4                                // skip unused field
+		for _, fn := range genfun(i.t, i.itype) {
+			o = dsymptr(i.lsym, o, fn, 0) // method pointer for each method
+		}
+		// Nothing writes static itabs, so they are read only.
+		ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
 		ilink := itablinkpkg.Lookup(i.t.ShortString() + "," + i.itype.ShortString()).Linksym()
 		dsymptr(ilink, 0, i.lsym, 0)
 		ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
@@ -1492,7 +1554,7 @@
 			// }
 			nsym := dname(p.s.Name, "", nil, true)
 			ot = dsymptrOff(s, ot, nsym, 0)
-			ot = dsymptrOff(s, ot, dtypesym(p.t).Linksym(), 0)
+			ot = dsymptrOff(s, ot, dtypesym(p.t), 0)
 		}
 		ggloblsym(s, int32(ot), int16(obj.RODATA))
 
@@ -1586,8 +1648,8 @@
 		s.SetAlgGen(true)
 
 		if memhashvarlen == nil {
-			memhashvarlen = Sysfunc("memhash_varlen")
-			memequalvarlen = Sysfunc("memequal_varlen")
+			memhashvarlen = sysfunc("memhash_varlen")
+			memequalvarlen = sysfunc("memequal_varlen")
 		}
 
 		// make hash closure
@@ -1717,8 +1779,7 @@
 	}
 
 	vec := bvalloc(8 * int32(len(ptrmask)))
-	xoffset := int64(0)
-	onebitwalktype1(t, &xoffset, vec)
+	onebitwalktype1(t, 0, vec)
 
 	nptr := typeptrdata(t) / int64(Widthptr)
 	for i := int64(0); i < nptr; i++ {
diff --git a/src/cmd/compile/internal/gc/scope.go b/src/cmd/compile/internal/gc/scope.go
index b0bc7f6..ebdaa19 100644
--- a/src/cmd/compile/internal/gc/scope.go
+++ b/src/cmd/compile/internal/gc/scope.go
@@ -168,7 +168,7 @@
 	if v.scopes[i] != v.scopes[j] {
 		return v.scopes[i] < v.scopes[j]
 	}
-	return v.vars[i].Offset < v.vars[j].Offset
+	return v.vars[i].StackOffset < v.vars[j].StackOffset
 }
 
 func (v varsByScopeAndOffset) Swap(i, j int) {
diff --git a/src/cmd/compile/internal/gc/scope_test.go b/src/cmd/compile/internal/gc/scope_test.go
index 9113afe..5d44b7a 100644
--- a/src/cmd/compile/internal/gc/scope_test.go
+++ b/src/cmd/compile/internal/gc/scope_test.go
@@ -173,6 +173,18 @@
 	{line: "		fi(p)", scopes: []int{1}},
 	{line: "	}"},
 	{line: "}"},
+	{line: "func TestCaptureVar(flag bool) func() int {"},
+	{line: "	a := 1", vars: []string{"arg flag bool", "arg ~r1 func() int", "var a int"}},
+	{line: "	if flag {"},
+	{line: "		b := 2", scopes: []int{1}, vars: []string{"var b int", "var f func() int"}},
+	{line: "		f := func() int {", scopes: []int{1, 0}},
+	{line: "			return b + 1"},
+	{line: "		}"},
+	{line: "		return f", scopes: []int{1}},
+	{line: "	}"},
+	{line: "	f1(a)"},
+	{line: "	return nil"},
+	{line: "}"},
 	{line: "func main() {"},
 	{line: "	TestNestedFor()"},
 	{line: "	TestOas2()"},
@@ -184,6 +196,7 @@
 	{line: "	TestDiscontiguousRanges()"},
 	{line: "	TestClosureScope()"},
 	{line: "	TestEscape()"},
+	{line: "	TestCaptureVar(true)"},
 	{line: "}"},
 }
 
diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go
index 320cd9a..38eaacc 100644
--- a/src/cmd/compile/internal/gc/select.go
+++ b/src/cmd/compile/internal/gc/select.go
@@ -8,39 +8,32 @@
 
 // select
 func typecheckselect(sel *Node) {
-	var ncase *Node
-	var n *Node
-
 	var def *Node
 	lno := setlineno(sel)
-	count := 0
 	typecheckslice(sel.Ninit.Slice(), Etop)
-	for _, n1 := range sel.List.Slice() {
-		count++
-		ncase = n1
-		setlineno(ncase)
+	for _, ncase := range sel.List.Slice() {
 		if ncase.Op != OXCASE {
+			setlineno(ncase)
 			Fatalf("typecheckselect %v", ncase.Op)
 		}
 
 		if ncase.List.Len() == 0 {
 			// default
 			if def != nil {
-				yyerror("multiple defaults in select (first at %v)", def.Line())
+				yyerrorl(ncase.Pos, "multiple defaults in select (first at %v)", def.Line())
 			} else {
 				def = ncase
 			}
 		} else if ncase.List.Len() > 1 {
-			yyerror("select cases cannot be lists")
+			yyerrorl(ncase.Pos, "select cases cannot be lists")
 		} else {
 			ncase.List.SetFirst(typecheck(ncase.List.First(), Etop))
-			n = ncase.List.First()
+			n := ncase.List.First()
 			ncase.Left = n
 			ncase.List.Set(nil)
-			setlineno(n)
 			switch n.Op {
 			default:
-				yyerror("select case must be receive, send or assign recv")
+				yyerrorl(n.Pos, "select case must be receive, send or assign recv")
 
 			// convert x = <-c into OSELRECV(x, <-c).
 			// remove implicit conversions; the eventual assignment
@@ -51,7 +44,7 @@
 				}
 
 				if n.Right.Op != ORECV {
-					yyerror("select assignment must have receive on right hand side")
+					yyerrorl(n.Pos, "select assignment must have receive on right hand side")
 					break
 				}
 
@@ -60,7 +53,7 @@
 				// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
 			case OAS2RECV:
 				if n.Rlist.First().Op != ORECV {
-					yyerror("select assignment must have receive on right hand side")
+					yyerrorl(n.Pos, "select assignment must have receive on right hand side")
 					break
 				}
 
@@ -72,7 +65,7 @@
 
 				// convert <-c into OSELRECV(N, <-c)
 			case ORECV:
-				n = nod(OSELRECV, nil, n)
+				n = nodl(n.Pos, OSELRECV, nil, n)
 
 				n.SetTypecheck(1)
 				ncase.Left = n
@@ -85,35 +78,41 @@
 		typecheckslice(ncase.Nbody.Slice(), Etop)
 	}
 
-	sel.Xoffset = int64(count)
 	lineno = lno
 }
 
 func walkselect(sel *Node) {
-	if sel.List.Len() == 0 && sel.Xoffset != 0 {
-		Fatalf("double walkselect") // already rewrote
+	lno := setlineno(sel)
+	if sel.Nbody.Len() != 0 {
+		Fatalf("double walkselect")
 	}
 
-	lno := setlineno(sel)
-	i := sel.List.Len()
+	init := sel.Ninit.Slice()
+	sel.Ninit.Set(nil)
+
+	init = append(init, walkselectcases(&sel.List)...)
+	sel.List.Set(nil)
+
+	sel.Nbody.Set(init)
+	walkstmtlist(sel.Nbody.Slice())
+
+	lineno = lno
+}
+
+func walkselectcases(cases *Nodes) []*Node {
+	n := cases.Len()
+	sellineno := lineno
 
 	// optimization: zero-case select
-	var init []*Node
-	var r *Node
-	var n *Node
-	var var_ *Node
-	var selv *Node
-	var chosen *Node
-	if i == 0 {
-		sel.Nbody.Set1(mkcall("block", nil, nil))
-		goto out
+	if n == 0 {
+		return []*Node{mkcall("block", nil, nil)}
 	}
 
 	// optimization: one-case select: single op.
 	// TODO(rsc): Reenable optimization once order.go can handle it.
 	// golang.org/issue/7672.
-	if i == 1 {
-		cas := sel.List.First()
+	if n == 1 {
+		cas := cases.First()
 		setlineno(cas)
 		l := cas.Ninit.Slice()
 		if cas.Left != nil { // not default:
@@ -163,21 +162,19 @@
 			a.Nbody.Set1(mkcall("block", nil, &ln))
 			l = ln.Slice()
 			a = typecheck(a, Etop)
-			l = append(l, a)
-			l = append(l, n)
+			l = append(l, a, n)
 		}
 
 		l = append(l, cas.Nbody.Slice()...)
 		l = append(l, nod(OBREAK, nil, nil))
-		sel.Nbody.Set(l)
-		goto out
+		return l
 	}
 
 	// convert case value arguments to addresses.
 	// this rewrite is used by both the general code and the next optimization.
-	for _, cas := range sel.List.Slice() {
+	for _, cas := range cases.Slice() {
 		setlineno(cas)
-		n = cas.Left
+		n := cas.Left
 		if n == nil {
 			continue
 		}
@@ -205,15 +202,15 @@
 	}
 
 	// optimization: two-case select but one is default: single non-blocking op.
-	if i == 2 && (sel.List.First().Left == nil || sel.List.Second().Left == nil) {
+	if n == 2 && (cases.First().Left == nil || cases.Second().Left == nil) {
 		var cas *Node
 		var dflt *Node
-		if sel.List.First().Left == nil {
-			cas = sel.List.Second()
-			dflt = sel.List.First()
+		if cases.First().Left == nil {
+			cas = cases.Second()
+			dflt = cases.First()
 		} else {
-			dflt = sel.List.Second()
-			cas = sel.List.First()
+			dflt = cases.Second()
+			cas = cases.First()
 		}
 
 		n := cas.Left
@@ -247,26 +244,24 @@
 		r.Left = typecheck(r.Left, Erv)
 		r.Nbody.Set(cas.Nbody.Slice())
 		r.Rlist.Set(append(dflt.Ninit.Slice(), dflt.Nbody.Slice()...))
-		sel.Nbody.Set2(r, nod(OBREAK, nil, nil))
-		goto out
+		return []*Node{r, nod(OBREAK, nil, nil)}
 	}
 
-	init = sel.Ninit.Slice()
-	sel.Ninit.Set(nil)
+	var init []*Node
 
 	// generate sel-struct
-	setlineno(sel)
-	selv = temp(selecttype(sel.Xoffset))
-	r = nod(OAS, selv, nil)
+	lineno = sellineno
+	selv := temp(selecttype(int64(n)))
+	r := nod(OAS, selv, nil)
 	r = typecheck(r, Etop)
 	init = append(init, r)
-	var_ = conv(conv(nod(OADDR, selv, nil), types.Types[TUNSAFEPTR]), types.NewPtr(types.Types[TUINT8]))
-	r = mkcall("newselect", nil, nil, var_, nodintconst(selv.Type.Width), nodintconst(sel.Xoffset))
+	var_ := conv(conv(nod(OADDR, selv, nil), types.Types[TUNSAFEPTR]), types.NewPtr(types.Types[TUINT8]))
+	r = mkcall("newselect", nil, nil, var_, nodintconst(selv.Type.Width), nodintconst(int64(n)))
 	r = typecheck(r, Etop)
 	init = append(init, r)
 
 	// register cases
-	for _, cas := range sel.List.Slice() {
+	for _, cas := range cases.Slice() {
 		setlineno(cas)
 
 		init = append(init, cas.Ninit.Slice()...)
@@ -298,8 +293,8 @@
 	}
 
 	// run the select
-	setlineno(sel)
-	chosen = temp(types.Types[TINT])
+	lineno = sellineno
+	chosen := temp(types.Types[TINT])
 	r = nod(OAS, chosen, mkcall("selectgo", types.Types[TINT], nil, var_))
 	r = typecheck(r, Etop)
 	init = append(init, r)
@@ -308,7 +303,7 @@
 	init = append(init, nod(OVARKILL, selv, nil))
 
 	// dispatch cases
-	for i, cas := range sel.List.Slice() {
+	for i, cas := range cases.Slice() {
 		setlineno(cas)
 
 		cond := nod(OEQ, chosen, nodintconst(int64(i)))
@@ -320,12 +315,7 @@
 		init = append(init, r)
 	}
 
-	sel.Nbody.Set(init)
-
-out:
-	sel.List.Set(nil)
-	walkstmtlist(sel.Nbody.Slice())
-	lineno = lno
+	return init
 }
 
 // Keep in sync with src/runtime/select.go.
@@ -342,7 +332,6 @@
 		namedfield("releasetime", types.Types[TUINT64]),
 	})
 	scase.SetNoalg(true)
-	scase.SetLocal(true)
 
 	sel := tostruct([]*Node{
 		namedfield("tcase", types.Types[TUINT16]),
@@ -354,7 +343,6 @@
 		namedfield("pollorderarr", types.NewArray(types.Types[TUINT16], size)),
 	})
 	sel.SetNoalg(true)
-	sel.SetLocal(true)
 
 	return sel
 }
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index 613cdf6..3af2460 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -44,7 +44,7 @@
 		init1(n1, out)
 	}
 
-	if n.Left != nil && n.Type != nil && n.Left.Op == OTYPE && n.Class() == PFUNC {
+	if n.isMethodExpression() {
 		// Methods called as Type.Method(receiver, ...).
 		// Definitions for method expressions are stored in type->nname.
 		init1(asNode(n.Type.FuncType().Nname), out)
@@ -157,7 +157,6 @@
 	initlist = initlist[:last]
 
 	n.SetInitorder(InitDone)
-	return
 }
 
 // foundinitloop prints an init loop error and exits.
@@ -214,10 +213,10 @@
 	init2list(n.Rlist, out)
 	init2list(n.Nbody, out)
 
-	if n.Op == OCLOSURE {
+	switch n.Op {
+	case OCLOSURE:
 		init2list(n.Func.Closure.Nbody, out)
-	}
-	if n.Op == ODOTMETH || n.Op == OCALLPART {
+	case ODOTMETH, OCALLPART:
 		init2(asNode(n.Type.FuncType().Nname), out)
 	}
 }
@@ -229,8 +228,7 @@
 }
 
 func initreorder(l []*Node, out *[]*Node) {
-	var n *Node
-	for _, n = range l {
+	for _, n := range l {
 		switch n.Op {
 		case ODCLFUNC, ODCLCONST, ODCLTYPE:
 			continue
@@ -480,9 +478,8 @@
 			n := *l
 			gdata(&n, r.Func.Closure.Func.Nname, Widthptr)
 			return true
-		} else {
-			closuredebugruntimecheck(r)
 		}
+		closuredebugruntimecheck(r)
 
 	case OCONVIFACE:
 		// This logic is mirrored in isStaticCompositeLiteral.
@@ -885,11 +882,10 @@
 
 	// put dynamics into array (5)
 	var index int64
-	for _, r := range n.List.Slice() {
-		value := r
-		if r.Op == OKEY {
-			index = nonnegintconst(r.Left)
-			value = r.Right
+	for _, value := range n.List.Slice() {
+		if value.Op == OKEY {
+			index = nonnegintconst(value.Left)
+			value = value.Right
 		}
 		a := nod(OINDEX, vauto, nodintconst(index))
 		a.SetBounded(true)
@@ -932,6 +928,7 @@
 func maplit(n *Node, m *Node, init *Nodes) {
 	// make the map var
 	a := nod(OMAKE, nil, nil)
+	a.Esc = n.Esc
 	a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
 	litas(m, a, init)
 
@@ -941,7 +938,7 @@
 		if r.Op != OKEY {
 			Fatalf("maplit: rhs not OKEY: %v", r)
 		}
-		if isliteral(r.Left) && isliteral(r.Right) {
+		if isStaticCompositeLiteral(r.Left) && isStaticCompositeLiteral(r.Right) {
 			stat = append(stat, r)
 		} else {
 			dyn = append(dyn, r)
@@ -966,24 +963,14 @@
 		vstatv := staticname(tv)
 		vstatv.Name.SetReadonly(true)
 
-		for i, r := range stat {
-			index := r.Left
-			value := r.Right
-
-			// build vstatk[b] = index
-			setlineno(index)
-			lhs := nod(OINDEX, vstatk, nodintconst(int64(i)))
-			as := nod(OAS, lhs, index)
-			as = typecheck(as, Etop)
-			genAsStatic(as)
-
-			// build vstatv[b] = value
-			setlineno(value)
-			lhs = nod(OINDEX, vstatv, nodintconst(int64(i)))
-			as = nod(OAS, lhs, value)
-			as = typecheck(as, Etop)
-			genAsStatic(as)
+		datak := nod(OARRAYLIT, nil, nil)
+		datav := nod(OARRAYLIT, nil, nil)
+		for _, r := range stat {
+			datak.List.Append(r.Left)
+			datav.List.Append(r.Right)
 		}
+		fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
+		fixedlit(inInitFunction, initKindStatic, datav, vstatv, init)
 
 		// loop adding structure elements to map
 		// for i = 0; i < len(vstatk); i++ {
diff --git a/src/cmd/compile/internal/gc/sizeof_test.go b/src/cmd/compile/internal/gc/sizeof_test.go
index 1ca0a61..48d357a 100644
--- a/src/cmd/compile/internal/gc/sizeof_test.go
+++ b/src/cmd/compile/internal/gc/sizeof_test.go
@@ -22,7 +22,7 @@
 		_32bit uintptr     // size on 32bit platforms
 		_64bit uintptr     // size on 64bit platforms
 	}{
-		{Func{}, 124, 216},
+		{Func{}, 132, 232},
 		{Name{}, 36, 56},
 		{Param{}, 28, 56},
 		{Node{}, 76, 128},
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 9c1b3ca..fe062da 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -37,6 +37,7 @@
 		Float32:    types.Types[TFLOAT32],
 		Float64:    types.Types[TFLOAT64],
 		Int:        types.Types[TINT],
+		UInt:       types.Types[TUINT],
 		Uintptr:    types.Types[TUINTPTR],
 		String:     types.Types[TSTRING],
 		BytePtr:    types.NewPtr(types.Types[TUINT8]),
@@ -48,6 +49,11 @@
 		Float64Ptr: types.NewPtr(types.Types[TFLOAT64]),
 		BytePtrPtr: types.NewPtr(types.NewPtr(types.Types[TUINT8])),
 	}
+
+	if thearch.SoftFloat {
+		softfloatInit()
+	}
+
 	// Generate a few pointer types that are uncommon in the frontend but common in the backend.
 	// Caching is disabled in the backend, so generating these here avoids allocations.
 	_ = types.NewPtr(types.Types[TINTER])                             // *interface{}
@@ -67,35 +73,37 @@
 	if thearch.LinkArch.Name == "386" {
 		ssaConfig.Set387(thearch.Use387)
 	}
+	ssaConfig.SoftFloat = thearch.SoftFloat
 	ssaCaches = make([]ssa.Cache, nBackendWorkers)
 
 	// Set up some runtime functions we'll need to call.
-	Newproc = Sysfunc("newproc")
-	Deferproc = Sysfunc("deferproc")
-	Deferreturn = Sysfunc("deferreturn")
-	Duffcopy = Sysfunc("duffcopy")
-	Duffzero = Sysfunc("duffzero")
-	panicindex = Sysfunc("panicindex")
-	panicslice = Sysfunc("panicslice")
-	panicdivide = Sysfunc("panicdivide")
-	growslice = Sysfunc("growslice")
-	panicdottypeE = Sysfunc("panicdottypeE")
-	panicdottypeI = Sysfunc("panicdottypeI")
-	panicnildottype = Sysfunc("panicnildottype")
-	assertE2I = Sysfunc("assertE2I")
-	assertE2I2 = Sysfunc("assertE2I2")
-	assertI2I = Sysfunc("assertI2I")
-	assertI2I2 = Sysfunc("assertI2I2")
-	goschedguarded = Sysfunc("goschedguarded")
-	writeBarrier = Sysfunc("writeBarrier")
-	writebarrierptr = Sysfunc("writebarrierptr")
-	typedmemmove = Sysfunc("typedmemmove")
-	typedmemclr = Sysfunc("typedmemclr")
-	Udiv = Sysfunc("udiv")
+	Newproc = sysfunc("newproc")
+	Deferproc = sysfunc("deferproc")
+	Deferreturn = sysfunc("deferreturn")
+	Duffcopy = sysfunc("duffcopy")
+	Duffzero = sysfunc("duffzero")
+	panicindex = sysfunc("panicindex")
+	panicslice = sysfunc("panicslice")
+	panicdivide = sysfunc("panicdivide")
+	growslice = sysfunc("growslice")
+	panicdottypeE = sysfunc("panicdottypeE")
+	panicdottypeI = sysfunc("panicdottypeI")
+	panicnildottype = sysfunc("panicnildottype")
+	assertE2I = sysfunc("assertE2I")
+	assertE2I2 = sysfunc("assertE2I2")
+	assertI2I = sysfunc("assertI2I")
+	assertI2I2 = sysfunc("assertI2I2")
+	goschedguarded = sysfunc("goschedguarded")
+	writeBarrier = sysfunc("writeBarrier")
+	writebarrierptr = sysfunc("writebarrierptr")
+	gcWriteBarrier = sysfunc("gcWriteBarrier")
+	typedmemmove = sysfunc("typedmemmove")
+	typedmemclr = sysfunc("typedmemclr")
+	Udiv = sysfunc("udiv")
 
 	// GO386=387 runtime functions
-	ControlWord64trunc = Sysfunc("controlWord64trunc")
-	ControlWord32 = Sysfunc("controlWord32")
+	ControlWord64trunc = sysfunc("controlWord64trunc")
+	ControlWord32 = sysfunc("controlWord32")
 }
 
 // buildssa builds an SSA function for fn.
@@ -135,13 +143,9 @@
 	if fn.Func.Pragma&Nosplit != 0 {
 		s.f.NoSplit = true
 	}
-	defer func() {
-		if s.f.WBPos.IsKnown() {
-			fn.Func.WBPos = s.f.WBPos
-		}
-	}()
 	s.exitCode = fn.Func.Exit
 	s.panics = map[funcLine]*ssa.Block{}
+	s.softFloat = s.config.SoftFloat
 
 	if name == os.Getenv("GOSSAFUNC") {
 		s.f.HTMLWriter = ssa.NewHTMLWriter("ssa.html", s.f.Frontend(), name)
@@ -162,15 +166,12 @@
 	s.startBlock(s.f.Entry)
 	s.vars[&memVar] = s.startmem
 
-	s.varsyms = map[*Node]interface{}{}
-
 	// Generate addresses of local declarations
 	s.decladdrs = map[*Node]*ssa.Value{}
 	for _, n := range fn.Func.Dcl {
 		switch n.Class() {
 		case PPARAM, PPARAMOUT:
-			aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-			s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sp)
+			s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), n, s.sp)
 			if n.Class() == PPARAMOUT && s.canSSA(n) {
 				// Save ssa-able PPARAMOUT variables so we can
 				// store them back to the stack at the end of
@@ -185,7 +186,7 @@
 		case PFUNC:
 			// local function - already handled by frontend
 		default:
-			s.Fatalf("local variable with class %s unimplemented", classnames[n.Class()])
+			s.Fatalf("local variable with class %v unimplemented", n.Class())
 		}
 	}
 
@@ -207,6 +208,12 @@
 		s.popLine()
 	}
 
+	for _, b := range s.f.Blocks {
+		if b.Pos != src.NoXPos {
+			s.updateUnsetPredPos(b)
+		}
+	}
+
 	s.insertPhis()
 
 	// Don't carry reference this around longer than necessary
@@ -217,6 +224,39 @@
 	return s.f
 }
 
+// updateUnsetPredPos propagates the earliest-value position information for b
+// towards all of b's predecessors that need a position, and recurs on that
+// predecessor if its position is updated. B should have a non-empty position.
+func (s *state) updateUnsetPredPos(b *ssa.Block) {
+	if b.Pos == src.NoXPos {
+		s.Fatalf("Block %s should have a position", b)
+	}
+	bestPos := src.NoXPos
+	for _, e := range b.Preds {
+		p := e.Block()
+		if !p.LackingPos() {
+			continue
+		}
+		if bestPos == src.NoXPos {
+			bestPos = b.Pos
+			for _, v := range b.Values {
+				if v.LackingPos() {
+					continue
+				}
+				if v.Pos != src.NoXPos {
+					// Assume values are still in roughly textual order;
+					// TODO: could also seek minimum position?
+					bestPos = v.Pos
+					break
+				}
+			}
+		}
+		p.Pos = bestPos
+		s.updateUnsetPredPos(p) // We do not expect long chains of these, thus recursion is okay.
+	}
+	return
+}
+
 type state struct {
 	// configuration (arch) information
 	config *ssa.Config
@@ -258,9 +298,6 @@
 	// addresses of PPARAM and PPARAMOUT variables.
 	decladdrs map[*Node]*ssa.Value
 
-	// symbols for PEXTERN, PAUTO and PPARAMOUT variables so they can be reused.
-	varsyms map[*Node]interface{}
-
 	// starting values. Memory, stack pointer, and globals pointer
 	startmem *ssa.Value
 	sp       *ssa.Value
@@ -268,6 +305,8 @@
 
 	// line number stack. The current line number is top of stack
 	line []src.XPos
+	// the last line number processed; it may have been popped
+	lastPos src.XPos
 
 	// list of panic calls by function name and line number.
 	// Used to deduplicate panic calls.
@@ -278,11 +317,12 @@
 
 	cgoUnsafeArgs bool
 	hasdefer      bool // whether the function contains a defer statement
+	softFloat     bool
 }
 
 type funcLine struct {
 	f    *obj.LSym
-	file string
+	base *src.PosBase
 	line uint
 }
 
@@ -349,7 +389,14 @@
 	s.defvars[b.ID] = s.vars
 	s.curBlock = nil
 	s.vars = nil
-	b.Pos = s.peekPos()
+	if b.LackingPos() {
+		// Empty plain blocks get the line of their successor (handled after all blocks created),
+		// except for increment blocks in For statements (handled in ssa conversion of OFOR),
+		// and for blocks ending in GOTO/BREAK/CONTINUE.
+		b.Pos = src.NoXPos
+	} else {
+		b.Pos = s.lastPos
+	}
 	return b
 }
 
@@ -362,7 +409,10 @@
 		if Debug['K'] != 0 {
 			Warn("buildssa: unknown position (line 0)")
 		}
+	} else {
+		s.lastPos = line
 	}
+
 	s.line = append(s.line, line)
 }
 
@@ -443,27 +493,27 @@
 
 // entryNewValue0A adds a new value with no arguments and an aux value to the entry block.
 func (s *state) entryNewValue0A(op ssa.Op, t *types.Type, aux interface{}) *ssa.Value {
-	return s.f.Entry.NewValue0A(s.peekPos(), op, t, aux)
+	return s.f.Entry.NewValue0A(src.NoXPos, op, t, aux)
 }
 
 // entryNewValue1 adds a new value with one argument to the entry block.
 func (s *state) entryNewValue1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value {
-	return s.f.Entry.NewValue1(s.peekPos(), op, t, arg)
+	return s.f.Entry.NewValue1(src.NoXPos, op, t, arg)
 }
 
 // entryNewValue1 adds a new value with one argument and an auxint value to the entry block.
 func (s *state) entryNewValue1I(op ssa.Op, t *types.Type, auxint int64, arg *ssa.Value) *ssa.Value {
-	return s.f.Entry.NewValue1I(s.peekPos(), op, t, auxint, arg)
+	return s.f.Entry.NewValue1I(src.NoXPos, op, t, auxint, arg)
 }
 
 // entryNewValue1A adds a new value with one argument and an aux value to the entry block.
 func (s *state) entryNewValue1A(op ssa.Op, t *types.Type, aux interface{}, arg *ssa.Value) *ssa.Value {
-	return s.f.Entry.NewValue1A(s.peekPos(), op, t, aux, arg)
+	return s.f.Entry.NewValue1A(src.NoXPos, op, t, aux, arg)
 }
 
 // entryNewValue2 adds a new value with two arguments to the entry block.
 func (s *state) entryNewValue2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Value) *ssa.Value {
-	return s.f.Entry.NewValue2(s.peekPos(), op, t, arg0, arg1)
+	return s.f.Entry.NewValue2(src.NoXPos, op, t, arg0, arg1)
 }
 
 // const* routines add a new const value to the entry block.
@@ -511,6 +561,25 @@
 	return s.f.ConstOffPtrSP(s.peekPos(), t, c, s.sp)
 }
 
+// newValueOrSfCall* are wrappers around newValue*, which may create a call to a
+// soft-float runtime function instead (when emitting soft-float code).
+func (s *state) newValueOrSfCall1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value {
+	if s.softFloat {
+		if c, ok := s.sfcall(op, arg); ok {
+			return c
+		}
+	}
+	return s.newValue1(op, t, arg)
+}
+func (s *state) newValueOrSfCall2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Value) *ssa.Value {
+	if s.softFloat {
+		if c, ok := s.sfcall(op, arg0, arg1); ok {
+			return c
+		}
+	}
+	return s.newValue2(op, t, arg0, arg1)
+}
+
 // stmtList converts the statement list n to SSA and adds it to s.
 func (s *state) stmtList(l Nodes) {
 	for _, n := range l.Slice() {
@@ -520,8 +589,11 @@
 
 // stmt converts the statement n to SSA and adds it to s.
 func (s *state) stmt(n *Node) {
-	s.pushLine(n.Pos)
-	defer s.popLine()
+	if !(n.Op == OVARKILL || n.Op == OVARLIVE) {
+		// OVARKILL and OVARLIVE are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
+		s.pushLine(n.Pos)
+		defer s.popLine()
+	}
 
 	// If s.curBlock is nil, and n isn't a label (which might have an associated goto somewhere),
 	// then this code is dead. Stop here.
@@ -634,6 +706,7 @@
 		}
 
 		b := s.endBlock()
+		b.Pos = s.lastPos // Do this even if b is an empty block.
 		b.AddEdgeTo(lab.target)
 
 	case OAS:
@@ -661,24 +734,26 @@
 				}
 				rhs = nil
 			case OAPPEND:
-				// If we're writing the result of an append back to the same slice,
-				// handle it specially to avoid write barriers on the fast (non-growth) path.
+				// Check whether we're writing the result of an append back to the same slice.
+				// If so, we handle it specially to avoid write barriers on the fast
+				// (non-growth) path.
+				if !samesafeexpr(n.Left, rhs.List.First()) || Debug['N'] != 0 {
+					break
+				}
 				// If the slice can be SSA'd, it'll be on the stack,
 				// so there will be no write barriers,
 				// so there's no need to attempt to prevent them.
-				if samesafeexpr(n.Left, rhs.List.First()) {
-					if !s.canSSA(n.Left) {
-						if Debug_append > 0 {
-							Warnl(n.Pos, "append: len-only update")
-						}
-						s.append(rhs, true)
-						return
-					} else {
-						if Debug_append > 0 { // replicating old diagnostic message
-							Warnl(n.Pos, "append: len-only update (in local slice)")
-						}
+				if s.canSSA(n.Left) {
+					if Debug_append > 0 { // replicating old diagnostic message
+						Warnl(n.Pos, "append: len-only update (in local slice)")
 					}
+					break
 				}
+				if Debug_append > 0 {
+					Warnl(n.Pos, "append: len-only update")
+				}
+				s.append(rhs, true)
+				return
 			}
 		}
 
@@ -778,12 +853,14 @@
 
 	case ORETURN:
 		s.stmtList(n.List)
-		s.exit()
+		b := s.exit()
+		b.Pos = s.lastPos
+
 	case ORETJMP:
 		s.stmtList(n.List)
 		b := s.exit()
 		b.Kind = ssa.BlockRetJmp // override BlockRet
-		b.Aux = n.Left.Sym.Linksym()
+		b.Aux = n.Sym.Linksym()
 
 	case OCONTINUE, OBREAK:
 		var to *ssa.Block
@@ -808,6 +885,7 @@
 		}
 
 		b := s.endBlock()
+		b.Pos = s.lastPos // Do this even if b is an empty block.
 		b.AddEdgeTo(to)
 
 	case OFOR, OFORUNTIL:
@@ -873,6 +951,11 @@
 		}
 		if b := s.endBlock(); b != nil {
 			b.AddEdgeTo(bCond)
+			// It can happen that bIncr ends in a block containing only VARKILL,
+			// and that muddles the debugging experience.
+			if n.Op != OFORUNTIL && b.Pos == src.NoXPos {
+				b.Pos = bCond.Pos
+			}
 		}
 
 		if n.Op == OFORUNTIL {
@@ -934,6 +1017,11 @@
 		if !n.Left.Addrtaken() {
 			s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left)
 		}
+		switch n.Left.Class() {
+		case PAUTO, PPARAM, PPARAMOUT:
+		default:
+			s.Fatalf("VARLIVE variable %v must be Auto or Arg", n.Left)
+		}
 		s.vars[&memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, n.Left, s.mem())
 
 	case OCHECKNIL:
@@ -1408,14 +1496,13 @@
 		len := s.newValue1(ssa.OpStringLen, types.Types[TINT], str)
 		return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
 	case OCFUNC:
-		aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: n.Left.Sym.Linksym()})
+		aux := n.Left.Sym.Linksym()
 		return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
 	case ONAME:
 		if n.Class() == PFUNC {
 			// "value" of a function is the address of the function's closure
 			sym := funcsym(n.Sym).Linksym()
-			aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: sym})
-			return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sb)
+			return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb)
 		}
 		if s.canSSA(n) {
 			return s.variable(n, n.Type)
@@ -1525,6 +1612,12 @@
 			return v
 		}
 
+		// map <--> *hmap
+		if to.Etype == TMAP && from.IsPtr() &&
+			to.MapType().Hmap == from.Elem() {
+			return v
+		}
+
 		dowidth(from)
 		dowidth(to)
 		if from.Width != to.Width {
@@ -1623,18 +1716,18 @@
 
 		if ft.IsFloat() || tt.IsFloat() {
 			conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
-			if s.config.RegSize == 4 && thearch.LinkArch.Family != sys.MIPS {
+			if s.config.RegSize == 4 && thearch.LinkArch.Family != sys.MIPS && !s.softFloat {
 				if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
 					conv = conv1
 				}
 			}
-			if thearch.LinkArch.Family == sys.ARM64 {
+			if thearch.LinkArch.Family == sys.ARM64 || s.softFloat {
 				if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
 					conv = conv1
 				}
 			}
 
-			if thearch.LinkArch.Family == sys.MIPS {
+			if thearch.LinkArch.Family == sys.MIPS && !s.softFloat {
 				if ft.Size() == 4 && ft.IsInteger() && !ft.IsSigned() {
 					// tt is float32 or float64, and ft is also unsigned
 					if tt.Size() == 4 {
@@ -1665,12 +1758,12 @@
 					if op2 == ssa.OpCopy {
 						return x
 					}
-					return s.newValue1(op2, n.Type, x)
+					return s.newValueOrSfCall1(op2, n.Type, x)
 				}
 				if op2 == ssa.OpCopy {
-					return s.newValue1(op1, n.Type, x)
+					return s.newValueOrSfCall1(op1, n.Type, x)
 				}
-				return s.newValue1(op2, n.Type, s.newValue1(op1, types.Types[it], x))
+				return s.newValueOrSfCall1(op2, n.Type, s.newValueOrSfCall1(op1, types.Types[it], x))
 			}
 			// Tricky 64-bit unsigned cases.
 			if ft.IsInteger() {
@@ -1715,8 +1808,8 @@
 			ftp := floatForComplex(ft)
 			ttp := floatForComplex(tt)
 			return s.newValue2(ssa.OpComplexMake, tt,
-				s.newValue1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, x)),
-				s.newValue1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
+				s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, x)),
+				s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
 		}
 
 		s.Fatalf("unhandled OCONV %s -> %s", n.Left.Type.Etype, n.Type.Etype)
@@ -1733,8 +1826,8 @@
 		if n.Left.Type.IsComplex() {
 			pt := floatForComplex(n.Left.Type)
 			op := s.ssaOp(OEQ, pt)
-			r := s.newValue2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
-			i := s.newValue2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
+			r := s.newValueOrSfCall2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
+			i := s.newValueOrSfCall2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
 			c := s.newValue2(ssa.OpAndB, types.Types[TBOOL], r, i)
 			switch n.Op {
 			case OEQ:
@@ -1745,6 +1838,9 @@
 				s.Fatalf("ordered complex compare %v", n.Op)
 			}
 		}
+		if n.Left.Type.IsFloat() {
+			return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Left.Type), types.Types[TBOOL], a, b)
+		}
 		return s.newValue2(s.ssaOp(n.Op, n.Left.Type), types.Types[TBOOL], a, b)
 	case OMUL:
 		a := s.expr(n.Left)
@@ -1762,22 +1858,27 @@
 			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
 
 			if pt != wt { // Widen for calculation
-				areal = s.newValue1(ssa.OpCvt32Fto64F, wt, areal)
-				breal = s.newValue1(ssa.OpCvt32Fto64F, wt, breal)
-				aimag = s.newValue1(ssa.OpCvt32Fto64F, wt, aimag)
-				bimag = s.newValue1(ssa.OpCvt32Fto64F, wt, bimag)
+				areal = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, areal)
+				breal = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, breal)
+				aimag = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, aimag)
+				bimag = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, bimag)
 			}
 
-			xreal := s.newValue2(subop, wt, s.newValue2(mulop, wt, areal, breal), s.newValue2(mulop, wt, aimag, bimag))
-			ximag := s.newValue2(addop, wt, s.newValue2(mulop, wt, areal, bimag), s.newValue2(mulop, wt, aimag, breal))
+			xreal := s.newValueOrSfCall2(subop, wt, s.newValueOrSfCall2(mulop, wt, areal, breal), s.newValueOrSfCall2(mulop, wt, aimag, bimag))
+			ximag := s.newValueOrSfCall2(addop, wt, s.newValueOrSfCall2(mulop, wt, areal, bimag), s.newValueOrSfCall2(mulop, wt, aimag, breal))
 
 			if pt != wt { // Narrow to store back
-				xreal = s.newValue1(ssa.OpCvt64Fto32F, pt, xreal)
-				ximag = s.newValue1(ssa.OpCvt64Fto32F, pt, ximag)
+				xreal = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, xreal)
+				ximag = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, ximag)
 			}
 
 			return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag)
 		}
+
+		if n.Type.IsFloat() {
+			return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+		}
+
 		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 
 	case ODIV:
@@ -1800,31 +1901,31 @@
 			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
 
 			if pt != wt { // Widen for calculation
-				areal = s.newValue1(ssa.OpCvt32Fto64F, wt, areal)
-				breal = s.newValue1(ssa.OpCvt32Fto64F, wt, breal)
-				aimag = s.newValue1(ssa.OpCvt32Fto64F, wt, aimag)
-				bimag = s.newValue1(ssa.OpCvt32Fto64F, wt, bimag)
+				areal = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, areal)
+				breal = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, breal)
+				aimag = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, aimag)
+				bimag = s.newValueOrSfCall1(ssa.OpCvt32Fto64F, wt, bimag)
 			}
 
-			denom := s.newValue2(addop, wt, s.newValue2(mulop, wt, breal, breal), s.newValue2(mulop, wt, bimag, bimag))
-			xreal := s.newValue2(addop, wt, s.newValue2(mulop, wt, areal, breal), s.newValue2(mulop, wt, aimag, bimag))
-			ximag := s.newValue2(subop, wt, s.newValue2(mulop, wt, aimag, breal), s.newValue2(mulop, wt, areal, bimag))
+			denom := s.newValueOrSfCall2(addop, wt, s.newValueOrSfCall2(mulop, wt, breal, breal), s.newValueOrSfCall2(mulop, wt, bimag, bimag))
+			xreal := s.newValueOrSfCall2(addop, wt, s.newValueOrSfCall2(mulop, wt, areal, breal), s.newValueOrSfCall2(mulop, wt, aimag, bimag))
+			ximag := s.newValueOrSfCall2(subop, wt, s.newValueOrSfCall2(mulop, wt, aimag, breal), s.newValueOrSfCall2(mulop, wt, areal, bimag))
 
 			// TODO not sure if this is best done in wide precision or narrow
 			// Double-rounding might be an issue.
 			// Note that the pre-SSA implementation does the entire calculation
 			// in wide format, so wide is compatible.
-			xreal = s.newValue2(divop, wt, xreal, denom)
-			ximag = s.newValue2(divop, wt, ximag, denom)
+			xreal = s.newValueOrSfCall2(divop, wt, xreal, denom)
+			ximag = s.newValueOrSfCall2(divop, wt, ximag, denom)
 
 			if pt != wt { // Narrow to store back
-				xreal = s.newValue1(ssa.OpCvt64Fto32F, pt, xreal)
-				ximag = s.newValue1(ssa.OpCvt64Fto32F, pt, ximag)
+				xreal = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, xreal)
+				ximag = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, ximag)
 			}
 			return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag)
 		}
 		if n.Type.IsFloat() {
-			return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+			return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 		}
 		return s.intDivide(n, a, b)
 	case OMOD:
@@ -1838,8 +1939,11 @@
 			pt := floatForComplex(n.Type)
 			op := s.ssaOp(n.Op, pt)
 			return s.newValue2(ssa.OpComplexMake, n.Type,
-				s.newValue2(op, pt, s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)),
-				s.newValue2(op, pt, s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)))
+				s.newValueOrSfCall2(op, pt, s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)),
+				s.newValueOrSfCall2(op, pt, s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)))
+		}
+		if n.Type.IsFloat() {
+			return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 		}
 		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 	case OAND, OOR, OXOR:
@@ -2191,7 +2295,7 @@
 	r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[TINT], types.Types[TINT]}, taddr, p, l, c, nl)
 
 	if inplace {
-		if sn.Op == ONAME {
+		if sn.Op == ONAME && sn.Class() != PEXTERN {
 			// Tell liveness we're about to build a new slice
 			s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, sn, s.mem())
 		}
@@ -2270,7 +2374,8 @@
 // This function is intended to handle && and || better than just calling
 // s.expr(cond) and branching on the result.
 func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
-	if cond.Op == OANDAND {
+	switch cond.Op {
+	case OANDAND:
 		mid := s.f.NewBlock(ssa.BlockPlain)
 		s.stmtList(cond.Ninit)
 		s.condBranch(cond.Left, mid, no, max8(likely, 0))
@@ -2283,8 +2388,7 @@
 		// the likeliness of the first branch.
 		// TODO: have the frontend give us branch prediction hints for
 		// OANDAND and OOROR nodes (if it ever has such info).
-	}
-	if cond.Op == OOROR {
+	case OOROR:
 		mid := s.f.NewBlock(ssa.BlockPlain)
 		s.stmtList(cond.Ninit)
 		s.condBranch(cond.Left, yes, mid, min8(likely, 0))
@@ -2294,8 +2398,7 @@
 		// Note: if likely==-1, then both recursive calls pass -1.
 		// If likely==1, then we don't have enough info to decide
 		// the likelihood of the first branch.
-	}
-	if cond.Op == ONOT {
+	case ONOT:
 		s.stmtList(cond.Ninit)
 		s.condBranch(cond.Left, no, yes, -likely)
 		return
@@ -2398,7 +2501,7 @@
 	}
 	// Left is not ssa-able. Compute its address.
 	addr := s.addr(left, false)
-	if left.Op == ONAME && skip == 0 {
+	if left.Op == ONAME && left.Class() != PEXTERN && skip == 0 {
 		s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, left, s.mem())
 	}
 	if isReflectHeaderDataField(left) {
@@ -2499,6 +2602,79 @@
 	callGo
 )
 
+type sfRtCallDef struct {
+	rtfn  *obj.LSym
+	rtype types.EType
+}
+
+var softFloatOps map[ssa.Op]sfRtCallDef
+
+func softfloatInit() {
+	// Some of these operations get transformed by sfcall.
+	softFloatOps = map[ssa.Op]sfRtCallDef{
+		ssa.OpAdd32F: sfRtCallDef{sysfunc("fadd32"), TFLOAT32},
+		ssa.OpAdd64F: sfRtCallDef{sysfunc("fadd64"), TFLOAT64},
+		ssa.OpSub32F: sfRtCallDef{sysfunc("fadd32"), TFLOAT32},
+		ssa.OpSub64F: sfRtCallDef{sysfunc("fadd64"), TFLOAT64},
+		ssa.OpMul32F: sfRtCallDef{sysfunc("fmul32"), TFLOAT32},
+		ssa.OpMul64F: sfRtCallDef{sysfunc("fmul64"), TFLOAT64},
+		ssa.OpDiv32F: sfRtCallDef{sysfunc("fdiv32"), TFLOAT32},
+		ssa.OpDiv64F: sfRtCallDef{sysfunc("fdiv64"), TFLOAT64},
+
+		ssa.OpEq64F:      sfRtCallDef{sysfunc("feq64"), TBOOL},
+		ssa.OpEq32F:      sfRtCallDef{sysfunc("feq32"), TBOOL},
+		ssa.OpNeq64F:     sfRtCallDef{sysfunc("feq64"), TBOOL},
+		ssa.OpNeq32F:     sfRtCallDef{sysfunc("feq32"), TBOOL},
+		ssa.OpLess64F:    sfRtCallDef{sysfunc("fgt64"), TBOOL},
+		ssa.OpLess32F:    sfRtCallDef{sysfunc("fgt32"), TBOOL},
+		ssa.OpGreater64F: sfRtCallDef{sysfunc("fgt64"), TBOOL},
+		ssa.OpGreater32F: sfRtCallDef{sysfunc("fgt32"), TBOOL},
+		ssa.OpLeq64F:     sfRtCallDef{sysfunc("fge64"), TBOOL},
+		ssa.OpLeq32F:     sfRtCallDef{sysfunc("fge32"), TBOOL},
+		ssa.OpGeq64F:     sfRtCallDef{sysfunc("fge64"), TBOOL},
+		ssa.OpGeq32F:     sfRtCallDef{sysfunc("fge32"), TBOOL},
+
+		ssa.OpCvt32to32F:  sfRtCallDef{sysfunc("fint32to32"), TFLOAT32},
+		ssa.OpCvt32Fto32:  sfRtCallDef{sysfunc("f32toint32"), TINT32},
+		ssa.OpCvt64to32F:  sfRtCallDef{sysfunc("fint64to32"), TFLOAT32},
+		ssa.OpCvt32Fto64:  sfRtCallDef{sysfunc("f32toint64"), TINT64},
+		ssa.OpCvt64Uto32F: sfRtCallDef{sysfunc("fuint64to32"), TFLOAT32},
+		ssa.OpCvt32Fto64U: sfRtCallDef{sysfunc("f32touint64"), TUINT64},
+		ssa.OpCvt32to64F:  sfRtCallDef{sysfunc("fint32to64"), TFLOAT64},
+		ssa.OpCvt64Fto32:  sfRtCallDef{sysfunc("f64toint32"), TINT32},
+		ssa.OpCvt64to64F:  sfRtCallDef{sysfunc("fint64to64"), TFLOAT64},
+		ssa.OpCvt64Fto64:  sfRtCallDef{sysfunc("f64toint64"), TINT64},
+		ssa.OpCvt64Uto64F: sfRtCallDef{sysfunc("fuint64to64"), TFLOAT64},
+		ssa.OpCvt64Fto64U: sfRtCallDef{sysfunc("f64touint64"), TUINT64},
+		ssa.OpCvt32Fto64F: sfRtCallDef{sysfunc("f32to64"), TFLOAT64},
+		ssa.OpCvt64Fto32F: sfRtCallDef{sysfunc("f64to32"), TFLOAT32},
+	}
+}
+
+// TODO: do not emit sfcall if operation can be optimized to constant in later
+// opt phase
+func (s *state) sfcall(op ssa.Op, args ...*ssa.Value) (*ssa.Value, bool) {
+	if callDef, ok := softFloatOps[op]; ok {
+		switch op {
+		case ssa.OpLess32F,
+			ssa.OpLess64F,
+			ssa.OpLeq32F,
+			ssa.OpLeq64F:
+			args[0], args[1] = args[1], args[0]
+		case ssa.OpSub32F,
+			ssa.OpSub64F:
+			args[1] = s.newValue1(s.ssaOp(OMINUS, types.Types[callDef.rtype]), args[1].Type, args[1])
+		}
+
+		result := s.rtcall(callDef.rtfn, true, []*types.Type{types.Types[callDef.rtype]}, args...)[0]
+		if op == ssa.OpNeq32F || op == ssa.OpNeq64F {
+			result = s.newValue1(ssa.OpNot, result.Type, result)
+		}
+		return result, true
+	}
+	return nil, false
+}
+
 var intrinsics map[intrinsicKey]intrinsicBuilder
 
 // An intrinsicBuilder converts a call node n into an ssa value that
@@ -2577,18 +2753,34 @@
 			return nil
 		},
 		all...)
+	add("runtime", "getclosureptr",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue0(ssa.OpGetClosurePtr, s.f.Config.Types.Uintptr)
+		},
+		all...)
+
+	addF("runtime", "getcallerpc",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
+		}, sys.AMD64, sys.I386)
+
+	add("runtime", "getcallersp",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue0(ssa.OpGetCallerSP, s.f.Config.Types.Uintptr)
+		},
+		all...)
 
 	/******** runtime/internal/sys ********/
 	addF("runtime/internal/sys", "Ctz32",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			return s.newValue1(ssa.OpCtz32, types.Types[TINT], args[0])
 		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS)
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
 	addF("runtime/internal/sys", "Ctz64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			return s.newValue1(ssa.OpCtz64, types.Types[TINT], args[0])
 		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS)
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
 	addF("runtime/internal/sys", "Bswap32",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			return s.newValue1(ssa.OpBswap32, types.Types[TUINT32], args[0])
@@ -2607,41 +2799,40 @@
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
-
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Load64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], s.mem())
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Loadp",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			v := s.newValue2(ssa.OpAtomicLoadPtr, types.NewTuple(s.f.Config.Types.BytePtr, types.TypeMem), args[0], s.mem())
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, s.f.Config.Types.BytePtr, v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 
 	addF("runtime/internal/atomic", "Store",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStore32, types.TypeMem, args[0], args[1], s.mem())
 			return nil
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Store64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStore64, types.TypeMem, args[0], args[1], s.mem())
 			return nil
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "StorepNoWB",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStorePtrNoWB, types.TypeMem, args[0], args[1], s.mem())
 			return nil
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64)
 
 	addF("runtime/internal/atomic", "Xchg",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
@@ -2649,14 +2840,14 @@
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Xchg64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem())
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
 
 	addF("runtime/internal/atomic", "Xadd",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
@@ -2664,14 +2855,14 @@
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Xadd64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem())
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
 
 	addF("runtime/internal/atomic", "Cas",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
@@ -2679,14 +2870,14 @@
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
 	addF("runtime/internal/atomic", "Cas64",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 			v := s.newValue4(ssa.OpAtomicCompareAndSwap64, types.NewTuple(types.Types[TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
 			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
 			return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v)
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
 
 	addF("runtime/internal/atomic", "And8",
 		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
@@ -2724,6 +2915,85 @@
 			return s.newValue1(ssa.OpSqrt, types.Types[TFLOAT64], args[0])
 		},
 		sys.AMD64, sys.ARM, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X)
+	addF("math", "Trunc",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpTrunc, types.Types[TFLOAT64], args[0])
+		},
+		sys.PPC64, sys.S390X)
+	addF("math", "Ceil",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCeil, types.Types[TFLOAT64], args[0])
+		},
+		sys.PPC64, sys.S390X)
+	addF("math", "Floor",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpFloor, types.Types[TFLOAT64], args[0])
+		},
+		sys.PPC64, sys.S390X)
+	addF("math", "Round",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
+		},
+		sys.S390X)
+	addF("math", "RoundToEven",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0])
+		},
+		sys.S390X)
+	addF("math", "Abs",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpAbs, types.Types[TFLOAT64], args[0])
+		},
+		sys.PPC64)
+	addF("math", "Copysign",
+		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpCopysign, types.Types[TFLOAT64], args[0], args[1])
+		},
+		sys.PPC64)
+
+	makeRoundAMD64 := func(op ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+		return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+			aux := syslook("support_sse41").Sym.Linksym()
+			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), aux, s.sb)
+			v := s.newValue2(ssa.OpLoad, types.Types[TBOOL], addr, s.mem())
+			b := s.endBlock()
+			b.Kind = ssa.BlockIf
+			b.SetControl(v)
+			bTrue := s.f.NewBlock(ssa.BlockPlain)
+			bFalse := s.f.NewBlock(ssa.BlockPlain)
+			bEnd := s.f.NewBlock(ssa.BlockPlain)
+			b.AddEdgeTo(bTrue)
+			b.AddEdgeTo(bFalse)
+			b.Likely = ssa.BranchLikely // most machines have sse4.1 nowadays
+
+			// We have the intrinsic - use it directly.
+			s.startBlock(bTrue)
+			s.vars[n] = s.newValue1(op, types.Types[TFLOAT64], args[0])
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Call the pure Go version.
+			s.startBlock(bFalse)
+			a := s.call(n, callNormal)
+			s.vars[n] = s.newValue2(ssa.OpLoad, types.Types[TFLOAT64], a, s.mem())
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			return s.variable(n, types.Types[TFLOAT64])
+		}
+	}
+	addF("math", "RoundToEven",
+		makeRoundAMD64(ssa.OpRoundToEven),
+		sys.AMD64)
+	addF("math", "Floor",
+		makeRoundAMD64(ssa.OpFloor),
+		sys.AMD64)
+	addF("math", "Ceil",
+		makeRoundAMD64(ssa.OpCeil),
+		sys.AMD64)
+	addF("math", "Trunc",
+		makeRoundAMD64(ssa.OpTrunc),
+		sys.AMD64)
 
 	/******** math/bits ********/
 	addF("math/bits", "TrailingZeros64",
@@ -2847,7 +3117,7 @@
 		sys.ARM64)
 	makeOnesCountAMD64 := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
 		return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: syslook("support_popcnt").Sym.Linksym()})
+			aux := syslook("support_popcnt").Sym.Linksym()
 			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), aux, s.sb)
 			v := s.newValue2(ssa.OpLoad, types.Types[TBOOL], addr, s.mem())
 			b := s.endBlock()
@@ -2975,6 +3245,12 @@
 		// We can't intrinsify them.
 		return nil
 	}
+	// Skip intrinsifying math functions (which may contain hard-float
+	// instructions) when soft-float
+	if thearch.SoftFloat && pkg == "math" {
+		return nil
+	}
+
 	fn := sym.Name
 	return intrinsics[intrinsicKey{thearch.LinkArch.Arch, pkg, fn}]
 }
@@ -3026,7 +3302,7 @@
 	temps := map[*Node]*ssa.Value{}
 	for _, a := range n.List.Slice() {
 		if a.Op != OAS {
-			s.Fatalf("non-assignment as a function argument %s", opnames[a.Op])
+			s.Fatalf("non-assignment as a function argument %v", a.Op)
 		}
 		l, r := a.Left, a.Right
 		switch l.Op {
@@ -3046,7 +3322,7 @@
 			}
 			args = append(args, callArg{l.Xoffset, v})
 		default:
-			s.Fatalf("function argument assignment target not allowed: %s", opnames[l.Op])
+			s.Fatalf("function argument assignment target not allowed: %v", l.Op)
 		}
 	}
 	sort.Sort(byOffset(args))
@@ -3099,10 +3375,8 @@
 		}
 		i := s.expr(fn.Left)
 		itab := s.newValue1(ssa.OpITab, types.Types[TUINTPTR], i)
-		if k != callNormal {
-			s.nilCheck(itab)
-		}
-		itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab
+		s.nilCheck(itab)
+		itabidx := fn.Xoffset + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab
 		itab = s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab)
 		if k == callNormal {
 			codeptr = s.newValue2(ssa.OpLoad, types.Types[TUINTPTR], itab, s.mem())
@@ -3199,24 +3473,6 @@
 	return 0
 }
 
-// lookupSymbol is used to retrieve the symbol (Extern, Arg or Auto) used for a particular node.
-// This improves the effectiveness of cse by using the same Aux values for the
-// same symbols.
-func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
-	switch sym.(type) {
-	default:
-		s.Fatalf("sym %v is of unknown type %T", sym, sym)
-	case *ssa.ExternSymbol, *ssa.ArgSymbol, *ssa.AutoSymbol:
-		// these are the only valid types
-	}
-
-	if lsym, ok := s.varsyms[n]; ok {
-		return lsym
-	}
-	s.varsyms[n] = sym
-	return sym
-}
-
 // addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
 // The value that the returned Value represents is guaranteed to be non-nil.
 // If bounded is true then this address does not require a nil check for its operand
@@ -3228,8 +3484,7 @@
 		switch n.Class() {
 		case PEXTERN:
 			// global variable
-			aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: n.Sym.Linksym()})
-			v := s.entryNewValue1A(ssa.OpAddr, t, aux, s.sb)
+			v := s.entryNewValue1A(ssa.OpAddr, t, n.Sym.Linksym(), s.sb)
 			// TODO: Make OpAddr use AuxInt as well as Aux.
 			if n.Xoffset != 0 {
 				v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Xoffset, v)
@@ -3243,21 +3498,18 @@
 			}
 			if n == nodfp {
 				// Special arg that points to the frame pointer (Used by ORECOVER).
-				aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-				return s.entryNewValue1A(ssa.OpAddr, t, aux, s.sp)
+				return s.entryNewValue1A(ssa.OpAddr, t, n, s.sp)
 			}
 			s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
 			return nil
 		case PAUTO:
-			aux := s.lookupSymbol(n, &ssa.AutoSymbol{Node: n})
-			return s.newValue1A(ssa.OpAddr, t, aux, s.sp)
+			return s.newValue1A(ssa.OpAddr, t, n, s.sp)
 		case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
 			// ensure that we reuse symbols for out parameters so
 			// that cse works on their addresses
-			aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-			return s.newValue1A(ssa.OpAddr, t, aux, s.sp)
+			return s.newValue1A(ssa.OpAddr, t, n, s.sp)
 		default:
-			s.Fatalf("variable address class %v not implemented", classnames[n.Class()])
+			s.Fatalf("variable address class %v not implemented", n.Class())
 			return nil
 		}
 	case OINDREGSP:
@@ -3342,7 +3594,7 @@
 		return false
 	case PPARAMOUT:
 		if s.hasdefer {
-			// TODO: handle this case?  Named return values must be
+			// TODO: handle this case? Named return values must be
 			// in memory so that the deferred function can see them.
 			// Maybe do: if !strings.HasPrefix(n.String(), "~") { return false }
 			// Or maybe not, see issue 18860.  Even unnamed return values
@@ -3456,7 +3708,7 @@
 	bNext := s.f.NewBlock(ssa.BlockPlain)
 	line := s.peekPos()
 	pos := Ctxt.PosTable.Pos(line)
-	fl := funcLine{f: fn, file: pos.Filename(), line: pos.Line()}
+	fl := funcLine{f: fn, base: pos.Base(), line: pos.Line()}
 	bPanic := s.panics[fl]
 	if bPanic == nil {
 		bPanic = s.f.NewBlock(ssa.BlockPlain)
@@ -3610,8 +3862,9 @@
 		ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right)
 		s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
 	case t.IsSlice():
-		ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, right)
-		s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
+		elType := types.NewPtr(t.Elem())
+		ptr := s.newValue1(ssa.OpSlicePtr, elType, right)
+		s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, elType, left, ptr, s.mem())
 	case t.IsInterface():
 		// itab field is treated as a scalar.
 		idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
@@ -3743,7 +3996,7 @@
 	one                           func(*state, *types.Type, int64) *ssa.Value
 }
 
-var u64_f64 u642fcvtTab = u642fcvtTab{
+var u64_f64 = u642fcvtTab{
 	geq:   ssa.OpGeq64,
 	cvt2F: ssa.OpCvt64to64F,
 	and:   ssa.OpAnd64,
@@ -3753,7 +4006,7 @@
 	one:   (*state).constInt64,
 }
 
-var u64_f32 u642fcvtTab = u642fcvtTab{
+var u64_f32 = u642fcvtTab{
 	geq:   ssa.OpGeq64,
 	cvt2F: ssa.OpCvt64to32F,
 	and:   ssa.OpAnd64,
@@ -3834,12 +4087,12 @@
 	cvtI2F, cvtF2F ssa.Op
 }
 
-var u32_f64 u322fcvtTab = u322fcvtTab{
+var u32_f64 = u322fcvtTab{
 	cvtI2F: ssa.OpCvt32to64F,
 	cvtF2F: ssa.OpCopy,
 }
 
-var u32_f32 u322fcvtTab = u322fcvtTab{
+var u32_f32 = u322fcvtTab{
 	cvtI2F: ssa.OpCvt32to32F,
 	cvtF2F: ssa.OpCvt64Fto32F,
 }
@@ -3924,14 +4177,15 @@
 
 	b.AddEdgeTo(bElse)
 	s.startBlock(bElse)
-	if n.Op == OLEN {
+	switch n.Op {
+	case OLEN:
 		// length is stored in the first word for map/chan
 		s.vars[n] = s.newValue2(ssa.OpLoad, lenType, x, s.mem())
-	} else if n.Op == OCAP {
+	case OCAP:
 		// capacity is stored in the second word for chan
 		sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x)
 		s.vars[n] = s.newValue2(ssa.OpLoad, lenType, sw, s.mem())
-	} else {
+	default:
 		s.Fatalf("op must be OLEN or OCAP")
 	}
 	s.endBlock()
@@ -3948,7 +4202,7 @@
 	cutoff               uint64
 }
 
-var f32_u64 f2uCvtTab = f2uCvtTab{
+var f32_u64 = f2uCvtTab{
 	ltf:        ssa.OpLess32F,
 	cvt2U:      ssa.OpCvt32Fto64,
 	subf:       ssa.OpSub32F,
@@ -3958,7 +4212,7 @@
 	cutoff:     9223372036854775808,
 }
 
-var f64_u64 f2uCvtTab = f2uCvtTab{
+var f64_u64 = f2uCvtTab{
 	ltf:        ssa.OpLess64F,
 	cvt2U:      ssa.OpCvt64Fto64,
 	subf:       ssa.OpSub64F,
@@ -3968,7 +4222,7 @@
 	cutoff:     9223372036854775808,
 }
 
-var f32_u32 f2uCvtTab = f2uCvtTab{
+var f32_u32 = f2uCvtTab{
 	ltf:        ssa.OpLess32F,
 	cvt2U:      ssa.OpCvt32Fto32,
 	subf:       ssa.OpSub32F,
@@ -3978,7 +4232,7 @@
 	cutoff:     2147483648,
 }
 
-var f64_u32 f2uCvtTab = f2uCvtTab{
+var f64_u32 = f2uCvtTab{
 	ltf:        ssa.OpLess64F,
 	cvt2U:      ssa.OpCvt64Fto32,
 	subf:       ssa.OpSub64F,
@@ -4377,23 +4631,20 @@
 
 	e := f.Frontend().(*ssafn)
 
-	// Generate GC bitmaps, except if the stack is too large,
-	// in which compilation will fail later anyway (issue 20529).
-	if e.stksize < maxStackSize {
-		s.stackMapIndex = liveness(e, f)
-	}
+	s.stackMapIndex = liveness(e, f)
 
 	// Remember where each block starts.
 	s.bstart = make([]*obj.Prog, f.NumBlocks())
 	s.pp = pp
-	var valueProgs map[*obj.Prog]*ssa.Value
-	var blockProgs map[*obj.Prog]*ssa.Block
+	var progToValue map[*obj.Prog]*ssa.Value
+	var progToBlock map[*obj.Prog]*ssa.Block
+	var valueToProgAfter []*obj.Prog // The first Prog following computation of a value v; v is visible at this point.
 	var logProgs = e.log
 	if logProgs {
-		valueProgs = make(map[*obj.Prog]*ssa.Value, f.NumValues())
-		blockProgs = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
+		progToValue = make(map[*obj.Prog]*ssa.Value, f.NumValues())
+		progToBlock = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
 		f.Logf("genssa %s\n", f.Name)
-		blockProgs[s.pp.next] = f.Blocks[0]
+		progToBlock[s.pp.next] = f.Blocks[0]
 	}
 
 	if thearch.Use387 {
@@ -4402,6 +4653,12 @@
 
 	s.ScratchFpMem = e.scratchFpMem
 
+	logLocationLists := Debug_locationlist != 0
+	if Ctxt.Flag_locationlists {
+		e.curfn.Func.DebugInfo = ssa.BuildFuncDebug(f, logLocationLists)
+		valueToProgAfter = make([]*obj.Prog, f.NumValues())
+	}
+
 	// Emit basic blocks
 	for i, b := range f.Blocks {
 		s.bstart[b.ID] = s.pp.next
@@ -4442,15 +4699,19 @@
 				}
 			case ssa.OpPhi:
 				CheckLoweredPhi(v)
-
+			case ssa.OpRegKill:
+				// nothing to do
 			default:
 				// let the backend handle it
 				thearch.SSAGenValue(&s, v)
 			}
 
+			if Ctxt.Flag_locationlists {
+				valueToProgAfter[v.ID] = s.pp.next
+			}
 			if logProgs {
 				for ; x != s.pp.next; x = x.Link {
-					valueProgs[x] = v
+					progToValue[x] = v
 				}
 			}
 		}
@@ -4468,7 +4729,47 @@
 		thearch.SSAGenBlock(&s, b, next)
 		if logProgs {
 			for ; x != s.pp.next; x = x.Link {
-				blockProgs[x] = b
+				progToBlock[x] = b
+			}
+		}
+	}
+
+	if Ctxt.Flag_locationlists {
+		for i := range f.Blocks {
+			blockDebug := e.curfn.Func.DebugInfo.Blocks[i]
+			for _, locList := range blockDebug.Variables {
+				for _, loc := range locList.Locations {
+					if loc.Start == ssa.BlockStart {
+						loc.StartProg = s.bstart[f.Blocks[i].ID]
+					} else {
+						loc.StartProg = valueToProgAfter[loc.Start.ID]
+					}
+					if loc.End == nil {
+						Fatalf("empty loc %v compiling %v", loc, f.Name)
+					}
+
+					if loc.End == ssa.BlockEnd {
+						// If this variable was live at the end of the block, it should be
+						// live over the control flow instructions. Extend it up to the
+						// beginning of the next block.
+						// If this is the last block, then there's no Prog to use for it, and
+						// EndProg is unset.
+						if i < len(f.Blocks)-1 {
+							loc.EndProg = s.bstart[f.Blocks[i+1].ID]
+						}
+					} else {
+						// Advance the "end" forward by one; the end-of-range doesn't take effect
+						// until the instruction actually executes.
+						loc.EndProg = valueToProgAfter[loc.End.ID].Link
+						if loc.EndProg == nil {
+							Fatalf("nil loc.EndProg compiling %v, loc=%v", f.Name, loc)
+						}
+					}
+					if !logLocationLists {
+						loc.Start = nil
+						loc.End = nil
+					}
+				}
 			}
 		}
 	}
@@ -4479,16 +4780,22 @@
 	}
 
 	if logProgs {
+		filename := ""
 		for p := pp.Text; p != nil; p = p.Link {
+			if p.Pos.IsKnown() && p.InnermostFilename() != filename {
+				filename = p.InnermostFilename()
+				f.Logf("# %s\n", filename)
+			}
+
 			var s string
-			if v, ok := valueProgs[p]; ok {
+			if v, ok := progToValue[p]; ok {
 				s = v.String()
-			} else if b, ok := blockProgs[p]; ok {
+			} else if b, ok := progToBlock[p]; ok {
 				s = b.String()
 			} else {
 				s = "   " // most value and branch strings are 2-3 characters long
 			}
-			f.Logf("%s\t%s\n", s, p)
+			f.Logf(" %-6s\t%.5d (%s)\t%s\n", s, p.Pc, p.InnermostLineNumber(), p.InstructionString())
 		}
 		if f.HTMLWriter != nil {
 			// LineHist is defunct now - this code won't do
@@ -4499,22 +4806,31 @@
 			var buf bytes.Buffer
 			buf.WriteString("<code>")
 			buf.WriteString("<dl class=\"ssa-gen\">")
+			filename := ""
 			for p := pp.Text; p != nil; p = p.Link {
+				// Don't spam every line with the file name, which is often huge.
+				// Only print changes, and "unknown" is not a change.
+				if p.Pos.IsKnown() && p.InnermostFilename() != filename {
+					filename = p.InnermostFilename()
+					buf.WriteString("<dt class=\"ssa-prog-src\"></dt><dd class=\"ssa-prog\">")
+					buf.WriteString(html.EscapeString("# " + filename))
+					buf.WriteString("</dd>")
+				}
+
 				buf.WriteString("<dt class=\"ssa-prog-src\">")
-				if v, ok := valueProgs[p]; ok {
+				if v, ok := progToValue[p]; ok {
 					buf.WriteString(v.HTML())
-				} else if b, ok := blockProgs[p]; ok {
-					buf.WriteString(b.HTML())
+				} else if b, ok := progToBlock[p]; ok {
+					buf.WriteString("<b>" + b.HTML() + "</b>")
 				}
 				buf.WriteString("</dt>")
 				buf.WriteString("<dd class=\"ssa-prog\">")
-				buf.WriteString(html.EscapeString(p.String()))
+				buf.WriteString(fmt.Sprintf("%.5d <span class=\"line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), html.EscapeString(p.InstructionString())))
 				buf.WriteString("</dd>")
-				buf.WriteString("</li>")
 			}
 			buf.WriteString("</dl>")
 			buf.WriteString("</code>")
-			f.HTMLWriter.WriteColumn("genssa", buf.String())
+			f.HTMLWriter.WriteColumn("genssa", "ssa-prog", buf.String())
 			// pp.Text.Ctxt.LineHist.PrintFilenameOnly = saved
 		}
 	}
@@ -4589,6 +4905,7 @@
 func (s *SSAGenState) oneFPJump(b *ssa.Block, jumps *FloatingEQNEJump) {
 	p := s.Prog(jumps.Jump)
 	p.To.Type = obj.TYPE_BRANCH
+	p.Pos = b.Pos
 	to := jumps.Index
 	s.Branches = append(s.Branches, Branch{p, b.Succs[to].Block()})
 }
@@ -4605,6 +4922,7 @@
 		s.oneFPJump(b, &jumps[1][0])
 		s.oneFPJump(b, &jumps[1][1])
 		q := s.Prog(obj.AJMP)
+		q.Pos = b.Pos
 		q.To.Type = obj.TYPE_BRANCH
 		s.Branches = append(s.Branches, Branch{q, b.Succs[1].Block()})
 	}
@@ -4614,10 +4932,11 @@
 	if v.Aux == nil {
 		return 0
 	}
-	switch sym := v.Aux.(type) {
-
-	case *ssa.AutoSymbol:
-		n := sym.Node.(*Node)
+	n, ok := v.Aux.(*Node)
+	if !ok {
+		v.Fatalf("bad aux type in %s\n", v.LongString())
+	}
+	if n.Class() == PAUTO {
 		return n.Xoffset
 	}
 	return 0
@@ -4639,17 +4958,17 @@
 		return
 	}
 	// Add symbol's offset from its base register.
-	switch sym := v.Aux.(type) {
-	case *ssa.ExternSymbol:
+	switch n := v.Aux.(type) {
+	case *obj.LSym:
 		a.Name = obj.NAME_EXTERN
-		a.Sym = sym.Sym
-	case *ssa.ArgSymbol:
-		n := sym.Node.(*Node)
-		a.Name = obj.NAME_PARAM
-		a.Sym = n.Orig.Sym.Linksym()
-		a.Offset += n.Xoffset
-	case *ssa.AutoSymbol:
-		n := sym.Node.(*Node)
+		a.Sym = n
+	case *Node:
+		if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+			a.Name = obj.NAME_PARAM
+			a.Sym = n.Orig.Sym.Linksym()
+			a.Offset += n.Xoffset
+			break
+		}
 		a.Name = obj.NAME_AUTO
 		a.Sym = n.Sym.Linksym()
 		a.Offset += n.Xoffset
@@ -4725,7 +5044,7 @@
 	loc := f.RegAlloc[v.ID]
 	for _, a := range v.Args {
 		if aloc := f.RegAlloc[a.ID]; aloc != loc { // TODO: .Equal() instead?
-			v.Fatalf("phi arg at different location than phi: %v @ %v, but arg %v @ %v\n%s\n", v, loc, a, aloc, v.Block.Func)
+			v.Fatalf("phi arg at different location than phi: %v @ %s, but arg %v @ %s\n%s\n", v, loc, a, aloc, v.Block.Func)
 		}
 	}
 }
@@ -4800,6 +5119,12 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
 		p.To.Sym = sym
+
+		// Record call graph information for nowritebarrierrec
+		// analysis.
+		if nowritebarrierrecCheck != nil {
+			nowritebarrierrecCheck.recordCall(s.pp.curfn, sym, v.Pos)
+		}
 	} else {
 		// TODO(mdempsky): Can these differences be eliminated?
 		switch thearch.LinkArch.Family {
@@ -4863,10 +5188,9 @@
 	if e.strings == nil {
 		e.strings = make(map[string]interface{})
 	}
-	data := stringsym(s)
-	aux := &ssa.ExternSymbol{Sym: data}
-	e.strings[s] = aux
-	return aux
+	data := stringsym(e.curfn.Pos, s)
+	e.strings[s] = data
+	return data
 }
 
 func (e *ssafn) Auto(pos src.XPos, t *types.Type) ssa.GCNode {
@@ -4880,9 +5204,9 @@
 	lenType := types.Types[TINT]
 	if n.Class() == PAUTO && !n.Addrtaken() {
 		// Split this string up into two separate variables.
-		p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos)
-		l := e.namedAuto(n.Sym.Name+".len", lenType, n.Pos)
-		return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}
+		p := e.splitSlot(&name, ".ptr", 0, ptrType)
+		l := e.splitSlot(&name, ".len", ptrType.Size(), lenType)
+		return p, l
 	}
 	// Return the two parts of the larger variable.
 	return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)}
@@ -4897,9 +5221,9 @@
 		if n.Type.IsEmptyInterface() {
 			f = ".type"
 		}
-		c := e.namedAuto(n.Sym.Name+f, t, n.Pos)
-		d := e.namedAuto(n.Sym.Name+".data", t, n.Pos)
-		return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
+		c := e.splitSlot(&name, f, 0, t)
+		d := e.splitSlot(&name, ".data", t.Size(), t)
+		return c, d
 	}
 	// Return the two parts of the larger variable.
 	return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + int64(Widthptr)}
@@ -4911,10 +5235,10 @@
 	lenType := types.Types[TINT]
 	if n.Class() == PAUTO && !n.Addrtaken() {
 		// Split this slice up into three separate variables.
-		p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos)
-		l := e.namedAuto(n.Sym.Name+".len", lenType, n.Pos)
-		c := e.namedAuto(n.Sym.Name+".cap", lenType, n.Pos)
-		return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}, ssa.LocalSlot{N: c, Type: lenType, Off: 0}
+		p := e.splitSlot(&name, ".ptr", 0, ptrType)
+		l := e.splitSlot(&name, ".len", ptrType.Size(), lenType)
+		c := e.splitSlot(&name, ".cap", ptrType.Size()+lenType.Size(), lenType)
+		return p, l, c
 	}
 	// Return the three parts of the larger variable.
 	return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off},
@@ -4933,9 +5257,9 @@
 	}
 	if n.Class() == PAUTO && !n.Addrtaken() {
 		// Split this complex up into two separate variables.
-		c := e.namedAuto(n.Sym.Name+".real", t, n.Pos)
-		d := e.namedAuto(n.Sym.Name+".imag", t, n.Pos)
-		return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
+		r := e.splitSlot(&name, ".real", 0, t)
+		i := e.splitSlot(&name, ".imag", t.Size(), t)
+		return r, i
 	}
 	// Return the two parts of the larger variable.
 	return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + s}
@@ -4951,9 +5275,10 @@
 	}
 	if n.Class() == PAUTO && !n.Addrtaken() {
 		// Split this int64 up into two separate variables.
-		h := e.namedAuto(n.Sym.Name+".hi", t, n.Pos)
-		l := e.namedAuto(n.Sym.Name+".lo", types.Types[TUINT32], n.Pos)
-		return ssa.LocalSlot{N: h, Type: t, Off: 0}, ssa.LocalSlot{N: l, Type: types.Types[TUINT32], Off: 0}
+		if thearch.LinkArch.ByteOrder == binary.BigEndian {
+			return e.splitSlot(&name, ".hi", 0, t), e.splitSlot(&name, ".lo", t.Size(), types.Types[TUINT32])
+		}
+		return e.splitSlot(&name, ".hi", t.Size(), t), e.splitSlot(&name, ".lo", 0, types.Types[TUINT32])
 	}
 	// Return the two parts of the larger variable.
 	if thearch.LinkArch.ByteOrder == binary.BigEndian {
@@ -4966,12 +5291,15 @@
 	n := name.N.(*Node)
 	st := name.Type
 	ft := st.FieldType(i)
+	var offset int64
+	for f := 0; f < i; f++ {
+		offset += st.FieldType(f).Size()
+	}
 	if n.Class() == PAUTO && !n.Addrtaken() {
 		// Note: the _ field may appear several times.  But
 		// have no fear, identically-named but distinct Autos are
 		// ok, albeit maybe confusing for a debugger.
-		x := e.namedAuto(n.Sym.Name+"."+st.FieldName(i), ft, n.Pos)
-		return ssa.LocalSlot{N: x, Type: ft, Off: 0}
+		return e.splitSlot(&name, "."+st.FieldName(i), offset, ft)
 	}
 	return ssa.LocalSlot{N: n, Type: ft, Off: name.Off + st.FieldOff(i)}
 }
@@ -4984,8 +5312,7 @@
 	}
 	et := at.ElemType()
 	if n.Class() == PAUTO && !n.Addrtaken() {
-		x := e.namedAuto(n.Sym.Name+"[0]", et, n.Pos)
-		return ssa.LocalSlot{N: x, Type: et, Off: 0}
+		return e.splitSlot(&name, "[0]", 0, et)
 	}
 	return ssa.LocalSlot{N: n, Type: et, Off: name.Off}
 }
@@ -4994,16 +5321,15 @@
 	return itabsym(it, offset)
 }
 
-// namedAuto returns a new AUTO variable with the given name and type.
-// These are exposed to the debugger.
-func (e *ssafn) namedAuto(name string, typ *types.Type, pos src.XPos) ssa.GCNode {
-	t := typ
-	s := &types.Sym{Name: name, Pkg: localpkg}
+// splitSlot returns a slot representing the data of parent starting at offset.
+func (e *ssafn) splitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot {
+	s := &types.Sym{Name: parent.N.(*Node).Sym.Name + suffix, Pkg: localpkg}
 
-	n := new(Node)
-	n.Name = new(Name)
-	n.Op = ONAME
-	n.Pos = pos
+	n := &Node{
+		Name: new(Name),
+		Op:   ONAME,
+		Pos:  parent.N.(*Node).Pos,
+	}
 	n.Orig = n
 
 	s.Def = asTypesNode(n)
@@ -5016,7 +5342,7 @@
 	n.Name.Curfn = e.curfn
 	e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n)
 	dowidth(t)
-	return n
+	return ssa.LocalSlot{N: n, Type: t, Off: 0, SplitOf: parent, SplitOffset: offset}
 }
 
 func (e *ssafn) CanSSA(t *types.Type) bool {
@@ -5054,8 +5380,8 @@
 	return Debug_checknil != 0
 }
 
-func (e *ssafn) Debug_wb() bool {
-	return Debug_wb != 0
+func (e *ssafn) Debug_eagerwb() bool {
+	return Debug_eagerwb != 0
 }
 
 func (e *ssafn) UseWriteBarrier() bool {
@@ -5070,6 +5396,8 @@
 		return writeBarrier
 	case "writebarrierptr":
 		return writebarrierptr
+	case "gcWriteBarrier":
+		return gcWriteBarrier
 	case "typedmemmove":
 		return typedmemmove
 	case "typedmemclr":
@@ -5079,6 +5407,23 @@
 	return nil
 }
 
+func (e *ssafn) SetWBPos(pos src.XPos) {
+	e.curfn.Func.setWBPos(pos)
+}
+
 func (n *Node) Typ() *types.Type {
 	return n.Type
 }
+func (n *Node) StorageClass() ssa.StorageClass {
+	switch n.Class() {
+	case PPARAM:
+		return ssa.ClassParam
+	case PPARAMOUT:
+		return ssa.ClassParamOut
+	case PAUTO:
+		return ssa.ClassAuto
+	default:
+		Fatalf("untranslateable storage class for %v: %s", n, n.Class())
+		return 0
+	}
+}
diff --git a/src/cmd/compile/internal/gc/ssa_test.go b/src/cmd/compile/internal/gc/ssa_test.go
index bb315b9..2aa923f 100644
--- a/src/cmd/compile/internal/gc/ssa_test.go
+++ b/src/cmd/compile/internal/gc/ssa_test.go
@@ -7,29 +7,42 @@
 import (
 	"bytes"
 	"internal/testenv"
+	"io/ioutil"
+	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"testing"
 )
 
 // TODO: move all these tests elsewhere?
 // Perhaps teach test/run.go how to run them with a new action verb.
-func runTest(t *testing.T, filename string) {
+func runTest(t *testing.T, filename string, flags ...string) {
 	t.Parallel()
-	doTest(t, filename, "run")
+	doTest(t, filename, "run", flags...)
 }
-func buildTest(t *testing.T, filename string) {
+func buildTest(t *testing.T, filename string, flags ...string) {
 	t.Parallel()
-	doTest(t, filename, "build")
+	doTest(t, filename, "build", flags...)
 }
-func doTest(t *testing.T, filename string, kind string) {
+func doTest(t *testing.T, filename string, kind string, flags ...string) {
 	testenv.MustHaveGoBuild(t)
+	gotool := testenv.GoToolPath(t)
+
 	var stdout, stderr bytes.Buffer
-	cmd := exec.Command(testenv.GoToolPath(t), kind, filepath.Join("testdata", filename))
+	args := []string{kind}
+	if len(flags) == 0 {
+		args = append(args, "-gcflags=-d=ssa/check/on")
+	} else {
+		args = append(args, flags...)
+	}
+	args = append(args, filepath.Join("testdata", filename))
+	cmd := exec.Command(gotool, args...)
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
-	if err := cmd.Run(); err != nil {
+	err := cmd.Run()
+	if err != nil {
 		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
 	}
 	if s := stdout.String(); s != "" {
@@ -40,6 +53,58 @@
 	}
 }
 
+// runGenTest runs a test-generator, then runs the generated test.
+// Generated test can either fail in compilation or execution.
+// The environment variable parameter(s) is passed to the run
+// of the generated test.
+func runGenTest(t *testing.T, filename, tmpname string, ev ...string) {
+	testenv.MustHaveGoRun(t)
+	gotool := testenv.GoToolPath(t)
+	var stdout, stderr bytes.Buffer
+	cmd := exec.Command(gotool, "run", filepath.Join("testdata", filename))
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	if err := cmd.Run(); err != nil {
+		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
+	}
+	// Write stdout into a temporary file
+	tmpdir, ok := ioutil.TempDir("", tmpname)
+	if ok != nil {
+		t.Fatalf("Failed to create temporary directory")
+	}
+	defer os.RemoveAll(tmpdir)
+
+	rungo := filepath.Join(tmpdir, "run.go")
+	ok = ioutil.WriteFile(rungo, stdout.Bytes(), 0600)
+	if ok != nil {
+		t.Fatalf("Failed to create temporary file " + rungo)
+	}
+
+	stdout.Reset()
+	stderr.Reset()
+	cmd = exec.Command(gotool, "run", "-gcflags=-d=ssa/check/on", rungo)
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	cmd.Env = append(cmd.Env, ev...)
+	err := cmd.Run()
+	if err != nil {
+		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
+	}
+	if s := stderr.String(); s != "" {
+		t.Errorf("Stderr = %s\nWant empty", s)
+	}
+	if s := stdout.String(); s != "" {
+		t.Errorf("Stdout = %s\nWant empty", s)
+	}
+}
+
+func TestGenFlowGraph(t *testing.T) {
+	runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp1")
+	if runtime.GOOS != "windows" {
+		runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp2", "GO_SSA_PHI_LOC_CUTOFF=0")
+	}
+}
+
 // TestShortCircuit tests OANDAND and OOROR expressions and short circuiting.
 func TestShortCircuit(t *testing.T) { runTest(t, "short.go") }
 
@@ -55,6 +120,10 @@
 // TestFP tests that both backends have the same result for floating point expressions.
 func TestFP(t *testing.T) { runTest(t, "fp.go") }
 
+func TestFPSoftFloat(t *testing.T) {
+	runTest(t, "fp.go", "-gcflags=-d=softfloat,ssa/check/on")
+}
+
 // TestArithmeticBoundary tests boundary results for arithmetic operations.
 func TestArithmeticBoundary(t *testing.T) { runTest(t, "arithBoundary.go") }
 
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index d79789c..e0925dc 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -93,7 +93,7 @@
 }
 
 func linestr(pos src.XPos) string {
-	return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0)
+	return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1)
 }
 
 // lasterror keeps track of the most recently issued error.
@@ -166,20 +166,22 @@
 func Fatalf(fmt_ string, args ...interface{}) {
 	flusherrors()
 
-	fmt.Printf("%v: internal compiler error: ", linestr(lineno))
-	fmt.Printf(fmt_, args...)
-	fmt.Printf("\n")
-
-	// If this is a released compiler version, ask for a bug report.
-	if strings.HasPrefix(objabi.Version, "release") {
+	if Debug_panic != 0 || nsavederrors+nerrors == 0 {
+		fmt.Printf("%v: internal compiler error: ", linestr(lineno))
+		fmt.Printf(fmt_, args...)
 		fmt.Printf("\n")
-		fmt.Printf("Please file a bug report including a short program that triggers the error.\n")
-		fmt.Printf("https://golang.org/issue/new\n")
-	} else {
-		// Not a release; dump a stack trace, too.
-		fmt.Println()
-		os.Stdout.Write(debug.Stack())
-		fmt.Println()
+
+		// If this is a released compiler version, ask for a bug report.
+		if strings.HasPrefix(objabi.Version, "go") {
+			fmt.Printf("\n")
+			fmt.Printf("Please file a bug report including a short program that triggers the error.\n")
+			fmt.Printf("https://golang.org/issue/new\n")
+		} else {
+			// Not a release; dump a stack trace, too.
+			fmt.Println()
+			os.Stdout.Write(debug.Stack())
+			fmt.Println()
+		}
 	}
 
 	hcrash()
@@ -255,9 +257,6 @@
 // find all the exported symbols in package opkg
 // and make them available in the current package
 func importdot(opkg *types.Pkg, pack *Node) {
-	var s1 *types.Sym
-	var pkgerror string
-
 	n := 0
 	for _, s := range opkg.Syms {
 		if s.Def == nil {
@@ -266,9 +265,9 @@
 		if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
 			continue
 		}
-		s1 = lookup(s.Name)
+		s1 := lookup(s.Name)
 		if s1.Def != nil {
-			pkgerror = fmt.Sprintf("during import %q", opkg.Path)
+			pkgerror := fmt.Sprintf("during import %q", opkg.Path)
 			redeclare(s1, pkgerror)
 			continue
 		}
@@ -448,6 +447,10 @@
 	return c
 }
 
+func nodstr(s string) *Node {
+	return nodlit(Val{s})
+}
+
 // treecopy recursively copies n, with the exception of
 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
 // Copies of iota ONONAME nodes are assigned the current
@@ -924,6 +927,14 @@
 		return OCONVNOP
 	}
 
+	// src is map and dst is a pointer to corresponding hmap.
+	// This rule is needed for the implementation detail that
+	// go gc maps are implemented as a pointer to a hmap struct.
+	if src.Etype == TMAP && dst.IsPtr() &&
+		src.MapType().Hmap == dst.Elem() {
+		return OCONVNOP
+	}
+
 	return 0
 }
 
@@ -1127,53 +1138,57 @@
 	if n == nil {
 		return
 	}
+	n.SetHasCall(calcHasCall(n))
+}
 
-	b := false
+func calcHasCall(n *Node) bool {
 	if n.Ninit.Len() != 0 {
 		// TODO(mdempsky): This seems overly conservative.
-		b = true
-		goto out
+		return true
 	}
 
 	switch n.Op {
 	case OLITERAL, ONAME, OTYPE:
-		if b || n.HasCall() {
+		if n.HasCall() {
 			Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
 		}
-		return
-	case OAS:
-		if needwritebarrier(n.Left) {
-			b = true
-			goto out
-		}
+		return false
 	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
-		b = true
-		goto out
+		return true
 	case OANDAND, OOROR:
 		// hard with instrumented code
 		if instrumenting {
-			b = true
-			goto out
+			return true
 		}
 	case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR,
 		OIND, ODOTPTR, ODOTTYPE, ODIV, OMOD:
 		// These ops might panic, make sure they are done
 		// before we start marshaling args for a call. See issue 16760.
-		b = true
-		goto out
+		return true
+
+	// When using soft-float, these ops might be rewritten to function calls
+	// so we ensure they are evaluated first.
+	case OADD, OSUB, OMINUS:
+		if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) {
+			return true
+		}
+	case OLT, OEQ, ONE, OLE, OGE, OGT:
+		if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) {
+			return true
+		}
+	case OCONV:
+		if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) {
+			return true
+		}
 	}
 
 	if n.Left != nil && n.Left.HasCall() {
-		b = true
-		goto out
+		return true
 	}
 	if n.Right != nil && n.Right.HasCall() {
-		b = true
-		goto out
+		return true
 	}
-
-out:
-	n.SetHasCall(b)
+	return false
 }
 
 func badtype(op Op, tl *types.Type, tr *types.Type) {
@@ -1385,6 +1400,7 @@
 		return
 	}
 	t.SetRecur(true)
+	defer t.SetRecur(false)
 
 	var u *types.Type
 	d--
@@ -1394,7 +1410,7 @@
 		// below for embedded fields.
 		c = lookdot0(s, t, save, ignorecase)
 		if c != 0 {
-			goto out
+			return c, false
 		}
 	}
 
@@ -1403,7 +1419,7 @@
 		u = u.Elem()
 	}
 	if !u.IsStruct() && !u.IsInterface() {
-		goto out
+		return c, false
 	}
 
 	for _, f := range u.Fields().Slice() {
@@ -1412,8 +1428,7 @@
 		}
 		if d < 0 {
 			// Found an embedded field at target depth.
-			more = true
-			goto out
+			return c, true
 		}
 		a, more1 := adddot1(s, f.Type, d, save, ignorecase)
 		if a != 0 && c == 0 {
@@ -1425,8 +1440,6 @@
 		}
 	}
 
-out:
-	t.SetRecur(false)
 	return c, more
 }
 
@@ -1555,21 +1568,18 @@
 		u = u.Elem()
 	}
 
-	if !u.IsStruct() && !u.IsInterface() {
-		goto out
+	if u.IsStruct() || u.IsInterface() {
+		for _, f := range u.Fields().Slice() {
+			if f.Embedded == 0 {
+				continue
+			}
+			if f.Sym == nil {
+				continue
+			}
+			expand1(f.Type, false, followptr)
+		}
 	}
 
-	for _, f := range u.Fields().Slice() {
-		if f.Embedded == 0 {
-			continue
-		}
-		if f.Sym == nil {
-			continue
-		}
-		expand1(f.Type, false, followptr)
-	}
-
-out:
 	t.SetRecur(false)
 }
 
@@ -1667,11 +1677,17 @@
 //	rcvr - U
 //	method - M func (t T)(), a TFIELD type struct
 //	newnam - the eventual mangled name of this function
-func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface int) {
+func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface bool) {
 	if false && Debug['r'] != 0 {
 		fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
 	}
 
+	// Only generate (*T).M wrappers for T.M in T's own package.
+	if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type &&
+		rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != localpkg {
+		return
+	}
+
 	lineno = autogeneratedPos
 
 	dclcontext = PEXTERN
@@ -1684,7 +1700,7 @@
 
 	t := nod(OTFUNC, nil, nil)
 	l := []*Node{this}
-	if iface != 0 && rcvr.Width < int64(Widthptr) {
+	if iface && rcvr.Width < int64(Widthptr) {
 		// Building method for interface table and receiver
 		// is smaller than the single pointer-sized word
 		// that the interface call will pass in.
@@ -1742,9 +1758,7 @@
 		as := nod(OAS, this.Left, nod(OCONVNOP, dot, nil))
 		as.Right.Type = rcvr
 		fn.Nbody.Append(as)
-		n := nod(ORETJMP, nil, nil)
-		n.Left = newname(methodsym(method.Sym, methodrcvr, false))
-		fn.Nbody.Append(n)
+		fn.Nbody.Append(nodSym(ORETJMP, nil, methodsym(method.Sym, methodrcvr, false)))
 		// When tail-calling, we can't use a frame pointer.
 		fn.Func.SetNoFramePointer(true)
 	} else {
@@ -1752,7 +1766,7 @@
 		call := nod(OCALL, dot, nil)
 		call.List.Set(args)
 		call.SetIsddd(isddd)
-		if method.Type.Results().NumFields() > 0 {
+		if method.Type.NumResults() > 0 {
 			n := nod(ORETURN, nil, nil)
 			n.List.Set1(call)
 			call = n
@@ -1765,7 +1779,7 @@
 		dumplist("genwrapper body", fn.Nbody)
 	}
 
-	funcbody(fn)
+	funcbody()
 	Curfn = fn
 	types.Popdcl()
 	if debug_dclstack != 0 {
@@ -1801,35 +1815,32 @@
 	return n
 }
 
-func ifacelookdot(s *types.Sym, t *types.Type, followptr *bool, ignorecase bool) *types.Field {
-	*followptr = false
-
+func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) {
 	if t == nil {
-		return nil
+		return nil, false
 	}
 
-	var m *types.Field
 	path, ambig := dotpath(s, t, &m, ignorecase)
 	if path == nil {
 		if ambig {
 			yyerror("%v.%v is ambiguous", t, s)
 		}
-		return nil
+		return nil, false
 	}
 
 	for _, d := range path {
 		if d.field.Type.IsPtr() {
-			*followptr = true
+			followptr = true
 			break
 		}
 	}
 
 	if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
 		yyerror("%v.%v is a field, not a method", t, s)
-		return nil
+		return nil, followptr
 	}
 
-	return m
+	return m, followptr
 }
 
 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
@@ -1843,11 +1854,12 @@
 	// and then do one loop.
 
 	if t.IsInterface() {
+	Outer:
 		for _, im := range iface.Fields().Slice() {
 			for _, tm := range t.Fields().Slice() {
 				if tm.Sym == im.Sym {
 					if eqtype(tm.Type, im.Type) {
-						goto found
+						continue Outer
 					}
 					*m = im
 					*samename = tm
@@ -1860,7 +1872,6 @@
 			*samename = nil
 			*ptr = 0
 			return false
-		found:
 		}
 
 		return true
@@ -1874,11 +1885,10 @@
 		if im.Broke() {
 			continue
 		}
-		var followptr bool
-		tm := ifacelookdot(im.Sym, t, &followptr, false)
+		tm, followptr := ifacelookdot(im.Sym, t, false)
 		if tm == nil || tm.Nointerface() || !eqtype(tm.Type, im.Type) {
 			if tm == nil {
-				tm = ifacelookdot(im.Sym, t, &followptr, true)
+				tm, followptr = ifacelookdot(im.Sym, t, true)
 			}
 			*m = im
 			*samename = tm
@@ -1964,6 +1974,11 @@
 	return n
 }
 
+// The linker uses the magic symbol prefixes "go." and "type."
+// Avoid potential confusion between import paths and symbols
+// by rejecting these reserved imports for now. Also, people
+// "can do weird things in GOPATH and we'd prefer they didn't
+// do _that_ weird thing" (per rsc). See also #4257.
 var reservedimports = []string{
 	"go",
 	"type",
@@ -2027,6 +2042,10 @@
 // Can this type be stored directly in an interface word?
 // Yes, if the representation is a single pointer.
 func isdirectiface(t *types.Type) bool {
+	if t.Broke() {
+		return false
+	}
+
 	switch t.Etype {
 	case TPTR32,
 		TPTR64,
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index 1b76650..8d42550 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -257,7 +257,7 @@
 	var cas []*Node
 	if s.kind == switchKindTrue || s.kind == switchKindFalse {
 		s.exprname = nodbool(s.kind == switchKindTrue)
-	} else if consttype(cond) >= 0 {
+	} else if consttype(cond) > 0 {
 		// leave constants to enable dead code elimination (issue 9608)
 		s.exprname = cond
 	} else {
@@ -273,21 +273,15 @@
 
 	// handle the cases in order
 	for len(cc) > 0 {
-		// deal with expressions one at a time
-		if !okforcmp[t.Etype] || !cc[0].isconst {
-			a := s.walkCases(cc[:1])
-			cas = append(cas, a)
-			cc = cc[1:]
-			continue
+		run := 1
+		if okforcmp[t.Etype] && cc[0].isconst {
+			// do binary search on runs of constants
+			for ; run < len(cc) && cc[run].isconst; run++ {
+			}
+			// sort and compile constants
+			sort.Sort(caseClauseByConstVal(cc[:run]))
 		}
 
-		// do binary search on runs of constants
-		var run int
-		for run = 1; run < len(cc) && cc[run].isconst; run++ {
-		}
-
-		// sort and compile constants
-		sort.Sort(caseClauseByConstVal(cc[:run]))
 		a := s.walkCases(cc[:run])
 		cas = append(cas, a)
 		cc = cc[run:]
@@ -380,7 +374,7 @@
 	var def *Node    // defaults
 	br := nod(OBREAK, nil, nil)
 
-	for i, n := range sw.List.Slice() {
+	for _, n := range sw.List.Slice() {
 		setlineno(n)
 		if n.Op != OXCASE {
 			Fatalf("casebody %v", n.Op)
@@ -393,7 +387,7 @@
 		case 0:
 			// default
 			if def != nil {
-				yyerror("more than one default case")
+				yyerrorl(n.Pos, "more than one default case")
 			}
 			// reuse original default case
 			n.Right = jmp
@@ -474,21 +468,7 @@
 			fallIndex--
 		}
 		last := stat[fallIndex]
-
-		// botch - shouldn't fall through declaration
-		if last.Xoffset == n.Xoffset && last.Op == OXFALL {
-			if typeswvar != nil {
-				setlineno(last)
-				yyerror("cannot fallthrough in type switch")
-			}
-
-			if i+1 >= sw.List.Len() {
-				setlineno(last)
-				yyerror("cannot fallthrough final case in switch")
-			}
-
-			last.Op = OFALL
-		} else {
+		if last.Op != OFALL {
 			stat = append(stat, br)
 		}
 	}
@@ -588,7 +568,7 @@
 		if !ok {
 			// First entry for this hash.
 			nn = append(nn, c.node)
-			seen[c.hash] = nn[len(nn)-1 : len(nn):len(nn)]
+			seen[c.hash] = nn[len(nn)-1 : len(nn) : len(nn)]
 			continue
 		}
 		for _, n := range prev {
@@ -621,7 +601,7 @@
 				//       case GOARCH == "arm" && GOARM == "5":
 				//       case GOARCH == "arm":
 				//     which would both evaluate to false for non-ARM compiles.
-				if ct := consttype(n); ct < 0 || ct == CTBOOL {
+				if ct := consttype(n); ct == 0 || ct == CTBOOL {
 					continue
 				}
 
@@ -646,7 +626,7 @@
 	seen := make(map[typeVal]*Node)
 	for _, ncase := range clauses {
 		for _, n := range ncase.List.Slice() {
-			if ct := consttype(n); ct < 0 || ct == CTBOOL {
+			if ct := consttype(n); ct == 0 || ct == CTBOOL {
 				continue
 			}
 			tv := typeVal{
@@ -687,14 +667,13 @@
 		return
 	}
 	if cond.Right == nil {
-		setlineno(sw)
-		yyerror("type switch must have an assignment")
+		yyerrorl(sw.Pos, "type switch must have an assignment")
 		return
 	}
 
 	cond.Right = walkexpr(cond.Right, &sw.Ninit)
 	if !cond.Right.Type.IsInterface() {
-		yyerror("type switch must be on an interface")
+		yyerrorl(sw.Pos, "type switch must be on an interface")
 		return
 	}
 
@@ -757,7 +736,7 @@
 	if cond.Right.Type.IsEmptyInterface() {
 		h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
 	} else {
-		h.Xoffset = int64(3 * Widthptr) // offset of hash in runtime.itab
+		h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime.itab
 	}
 	h.SetBounded(true) // guaranteed not to fault
 	a = nod(OAS, s.hashname, h)
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
index 0fd146b..5044ea0 100644
--- a/src/cmd/compile/internal/gc/syntax.go
+++ b/src/cmd/compile/internal/gc/syntax.go
@@ -7,6 +7,7 @@
 package gc
 
 import (
+	"cmd/compile/internal/ssa"
 	"cmd/compile/internal/syntax"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
@@ -44,7 +45,6 @@
 	// - ONAME nodes that refer to local variables use it to identify their stack frame position.
 	// - ODOT, ODOTPTR, and OINDREGSP use it to indicate offset relative to their base address.
 	// - OSTRUCTKEY uses it to store the named field's offset.
-	// - OXCASE and OXFALL use it to validate the use of fallthrough.
 	// - Named OLITERALs use it to to store their ambient iota value.
 	// Possibly still more uses. If you find any, document them.
 	Xoffset int64
@@ -85,19 +85,20 @@
 	_, nodeAssigned  // is the variable ever assigned to
 	_, nodeAddrtaken // address taken, even if not moved to heap
 	_, nodeImplicit
-	_, nodeIsddd    // is the argument variadic
-	_, nodeLocal    // type created in this file (see also Type.Local)
-	_, nodeDiag     // already printed error about this
-	_, nodeColas    // OAS resulting from :=
-	_, nodeNonNil   // guaranteed to be non-nil
-	_, nodeNoescape // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
-	_, nodeBounded  // bounds check unnecessary
-	_, nodeAddable  // addressable
-	_, nodeHasCall  // expression contains a function call
-	_, nodeLikely   // if statement condition likely
-	_, nodeHasVal   // node.E contains a Val
-	_, nodeHasOpt   // node.E contains an Opt
-	_, nodeEmbedded // ODCLFIELD embedded type
+	_, nodeIsddd     // is the argument variadic
+	_, nodeDiag      // already printed error about this
+	_, nodeColas     // OAS resulting from :=
+	_, nodeNonNil    // guaranteed to be non-nil
+	_, nodeNoescape  // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
+	_, nodeBounded   // bounds check unnecessary
+	_, nodeAddable   // addressable
+	_, nodeHasCall   // expression contains a function call
+	_, nodeLikely    // if statement condition likely
+	_, nodeHasVal    // node.E contains a Val
+	_, nodeHasOpt    // node.E contains an Opt
+	_, nodeEmbedded  // ODCLFIELD embedded type
+	_, nodeInlFormal // OPAUTO created by inliner, derived from callee formal
+	_, nodeInlLocal  // OPAUTO created by inliner, derived from callee local
 )
 
 func (n *Node) Class() Class     { return Class(n.flags.get3(nodeClass)) }
@@ -113,7 +114,6 @@
 func (n *Node) Addrtaken() bool             { return n.flags&nodeAddrtaken != 0 }
 func (n *Node) Implicit() bool              { return n.flags&nodeImplicit != 0 }
 func (n *Node) Isddd() bool                 { return n.flags&nodeIsddd != 0 }
-func (n *Node) Local() bool                 { return n.flags&nodeLocal != 0 }
 func (n *Node) Diag() bool                  { return n.flags&nodeDiag != 0 }
 func (n *Node) Colas() bool                 { return n.flags&nodeColas != 0 }
 func (n *Node) NonNil() bool                { return n.flags&nodeNonNil != 0 }
@@ -125,6 +125,8 @@
 func (n *Node) HasVal() bool                { return n.flags&nodeHasVal != 0 }
 func (n *Node) HasOpt() bool                { return n.flags&nodeHasOpt != 0 }
 func (n *Node) Embedded() bool              { return n.flags&nodeEmbedded != 0 }
+func (n *Node) InlFormal() bool             { return n.flags&nodeInlFormal != 0 }
+func (n *Node) InlLocal() bool              { return n.flags&nodeInlLocal != 0 }
 
 func (n *Node) SetClass(b Class)     { n.flags.set3(nodeClass, uint8(b)) }
 func (n *Node) SetWalkdef(b uint8)   { n.flags.set2(nodeWalkdef, b) }
@@ -139,7 +141,6 @@
 func (n *Node) SetAddrtaken(b bool)             { n.flags.set(nodeAddrtaken, b) }
 func (n *Node) SetImplicit(b bool)              { n.flags.set(nodeImplicit, b) }
 func (n *Node) SetIsddd(b bool)                 { n.flags.set(nodeIsddd, b) }
-func (n *Node) SetLocal(b bool)                 { n.flags.set(nodeLocal, b) }
 func (n *Node) SetDiag(b bool)                  { n.flags.set(nodeDiag, b) }
 func (n *Node) SetColas(b bool)                 { n.flags.set(nodeColas, b) }
 func (n *Node) SetNonNil(b bool)                { n.flags.set(nodeNonNil, b) }
@@ -151,6 +152,8 @@
 func (n *Node) SetHasVal(b bool)                { n.flags.set(nodeHasVal, b) }
 func (n *Node) SetHasOpt(b bool)                { n.flags.set(nodeHasOpt, b) }
 func (n *Node) SetEmbedded(b bool)              { n.flags.set(nodeEmbedded, b) }
+func (n *Node) SetInlFormal(b bool)             { n.flags.set(nodeInlFormal, b) }
+func (n *Node) SetInlLocal(b bool)              { n.flags.set(nodeInlLocal, b) }
 
 // Val returns the Val for the node.
 func (n *Node) Val() Val {
@@ -212,6 +215,11 @@
 	return false
 }
 
+// isMethodExpression reports whether n represents a method expression T.M.
+func (n *Node) isMethodExpression() bool {
+	return n.Op == ONAME && n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME
+}
+
 // funcname returns the name of the function n.
 func (n *Node) funcname() string {
 	if n == nil || n.Func == nil || n.Func.Nname == nil {
@@ -349,6 +357,48 @@
 	Alias  bool // node is alias for Ntype (only used when type-checking ODCLTYPE)
 }
 
+// Functions
+//
+// A simple function declaration is represented as an ODCLFUNC node f
+// and an ONAME node n. They're linked to one another through
+// f.Func.Nname == n and n.Name.Defn == f. When functions are
+// referenced by name in an expression, the function's ONAME node is
+// used directly.
+//
+// Function names have n.Class() == PFUNC. This distinguishes them
+// from variables of function type.
+//
+// Confusingly, n.Func and f.Func both exist, but commonly point to
+// different Funcs. (Exception: an OCALLPART's Func does point to its
+// ODCLFUNC's Func.)
+//
+// A method declaration is represented like functions, except n.Sym
+// will be the qualified method name (e.g., "T.m") and
+// f.Func.Shortname is the bare method name (e.g., "m").
+//
+// Method expressions are represented as ONAME/PFUNC nodes like
+// function names, but their Left and Right fields still point to the
+// type and method, respectively. They can be distinguished from
+// normal functions with isMethodExpression. Also, unlike function
+// name nodes, method expression nodes exist for each method
+// expression. The declaration ONAME can be accessed with
+// x.Type.Nname(), where x is the method expression ONAME node.
+//
+// Method values are represented by ODOTMETH/ODOTINTER when called
+// immediately, and OCALLPART otherwise. They are like method
+// expressions, except that for ODOTMETH/ODOTINTER the method name is
+// stored in Sym instead of Right.
+//
+// Closures are represented by OCLOSURE node c. They link back and
+// forth with the ODCLFUNC via Func.Closure; that is, c.Func.Closure
+// == f and f.Func.Closure == c.
+//
+// Function bodies are stored in f.Nbody, and inline function bodies
+// are stored in n.Func.Inl. Pragmas are stored in f.Func.Pragma.
+//
+// Imported functions skip the ODCLFUNC, so n.Name.Defn is nil. They
+// also use Dcl instead of Inldcl.
+
 // Func holds Node fields used only with function-like nodes.
 type Func struct {
 	Shortname *types.Sym
@@ -369,6 +419,7 @@
 	Closgen    int
 	Outerfunc  *Node // outer function (for closure)
 	FieldTrack map[*types.Sym]struct{}
+	DebugInfo  *ssa.FuncDebug
 	Ntype      *Node // signature
 	Top        int   // top context (Ecall, Eproc, etc)
 	Closure    *Node // OCLOSURE <-> ODCLFUNC
@@ -382,11 +433,16 @@
 	Label int32 // largest auto-generated label in this function
 
 	Endlineno src.XPos
-	WBPos     src.XPos // position of first write barrier
+	WBPos     src.XPos // position of first write barrier; see SetWBPos
 
 	Pragma syntax.Pragma // go:xxx function annotations
 
-	flags bitset8
+	flags bitset16
+
+	// nwbrCalls records the LSyms of functions called by this
+	// function for go:nowritebarrierrec analysis. Only filled in
+	// if nowritebarrierrecCheck != nil.
+	nwbrCalls *[]nowritebarrierrecCallSym
 }
 
 // A Mark represents a scope boundary.
@@ -408,34 +464,51 @@
 	funcNeedctxt                  // function uses context register (has closure variables)
 	funcReflectMethod             // function calls reflect.Type.Method or MethodByName
 	funcIsHiddenClosure
-	funcNoFramePointer   // Must not use a frame pointer for this function
-	funcHasDefer         // contains a defer statement
-	funcNilCheckDisabled // disable nil checks when compiling this function
+	funcNoFramePointer      // Must not use a frame pointer for this function
+	funcHasDefer            // contains a defer statement
+	funcNilCheckDisabled    // disable nil checks when compiling this function
+	funcInlinabilityChecked // inliner has already determined whether the function is inlinable
+	funcExportInline        // include inline body in export data
 )
 
-func (f *Func) Dupok() bool            { return f.flags&funcDupok != 0 }
-func (f *Func) Wrapper() bool          { return f.flags&funcWrapper != 0 }
-func (f *Func) Needctxt() bool         { return f.flags&funcNeedctxt != 0 }
-func (f *Func) ReflectMethod() bool    { return f.flags&funcReflectMethod != 0 }
-func (f *Func) IsHiddenClosure() bool  { return f.flags&funcIsHiddenClosure != 0 }
-func (f *Func) NoFramePointer() bool   { return f.flags&funcNoFramePointer != 0 }
-func (f *Func) HasDefer() bool         { return f.flags&funcHasDefer != 0 }
-func (f *Func) NilCheckDisabled() bool { return f.flags&funcNilCheckDisabled != 0 }
+func (f *Func) Dupok() bool               { return f.flags&funcDupok != 0 }
+func (f *Func) Wrapper() bool             { return f.flags&funcWrapper != 0 }
+func (f *Func) Needctxt() bool            { return f.flags&funcNeedctxt != 0 }
+func (f *Func) ReflectMethod() bool       { return f.flags&funcReflectMethod != 0 }
+func (f *Func) IsHiddenClosure() bool     { return f.flags&funcIsHiddenClosure != 0 }
+func (f *Func) NoFramePointer() bool      { return f.flags&funcNoFramePointer != 0 }
+func (f *Func) HasDefer() bool            { return f.flags&funcHasDefer != 0 }
+func (f *Func) NilCheckDisabled() bool    { return f.flags&funcNilCheckDisabled != 0 }
+func (f *Func) InlinabilityChecked() bool { return f.flags&funcInlinabilityChecked != 0 }
+func (f *Func) ExportInline() bool        { return f.flags&funcExportInline != 0 }
 
-func (f *Func) SetDupok(b bool)            { f.flags.set(funcDupok, b) }
-func (f *Func) SetWrapper(b bool)          { f.flags.set(funcWrapper, b) }
-func (f *Func) SetNeedctxt(b bool)         { f.flags.set(funcNeedctxt, b) }
-func (f *Func) SetReflectMethod(b bool)    { f.flags.set(funcReflectMethod, b) }
-func (f *Func) SetIsHiddenClosure(b bool)  { f.flags.set(funcIsHiddenClosure, b) }
-func (f *Func) SetNoFramePointer(b bool)   { f.flags.set(funcNoFramePointer, b) }
-func (f *Func) SetHasDefer(b bool)         { f.flags.set(funcHasDefer, b) }
-func (f *Func) SetNilCheckDisabled(b bool) { f.flags.set(funcNilCheckDisabled, b) }
+func (f *Func) SetDupok(b bool)               { f.flags.set(funcDupok, b) }
+func (f *Func) SetWrapper(b bool)             { f.flags.set(funcWrapper, b) }
+func (f *Func) SetNeedctxt(b bool)            { f.flags.set(funcNeedctxt, b) }
+func (f *Func) SetReflectMethod(b bool)       { f.flags.set(funcReflectMethod, b) }
+func (f *Func) SetIsHiddenClosure(b bool)     { f.flags.set(funcIsHiddenClosure, b) }
+func (f *Func) SetNoFramePointer(b bool)      { f.flags.set(funcNoFramePointer, b) }
+func (f *Func) SetHasDefer(b bool)            { f.flags.set(funcHasDefer, b) }
+func (f *Func) SetNilCheckDisabled(b bool)    { f.flags.set(funcNilCheckDisabled, b) }
+func (f *Func) SetInlinabilityChecked(b bool) { f.flags.set(funcInlinabilityChecked, b) }
+func (f *Func) SetExportInline(b bool)        { f.flags.set(funcExportInline, b) }
+
+func (f *Func) setWBPos(pos src.XPos) {
+	if Debug_wb != 0 {
+		Warnl(pos, "write barrier")
+	}
+	if !f.WBPos.IsKnown() {
+		f.WBPos = pos
+	}
+}
+
+//go:generate stringer -type=Op -trimprefix=O
 
 type Op uint8
 
 // Node ops.
 const (
-	OXXX = Op(iota)
+	OXXX Op = iota
 
 	// names
 	ONAME    // var, const or func name
@@ -562,8 +635,7 @@
 	OCONTINUE // continue
 	ODEFER    // defer Left (Left must be call)
 	OEMPTY    // no-op (empty statement)
-	OFALL     // fallthrough (after processing)
-	OXFALL    // fallthrough (before processing)
+	OFALL     // fallthrough
 	OFOR      // for Ninit; Left; Right { Nbody }
 	OFORUNTIL // for Ninit; Left; Right { Nbody } ; test applied after executing body, not before
 	OGOTO     // goto Left
@@ -574,7 +646,7 @@
 	ORETURN   // return List
 	OSELECT   // select { List } (List is list of OXCASE or OCASE)
 	OSWITCH   // switch Ninit; Left { List } (List is a list of OXCASE or OCASE)
-	OTYPESW   // List = Left.(type) (appears as .Left of OSWITCH)
+	OTYPESW   // Left = Right.(type) (appears as .Left of OSWITCH)
 
 	// types
 	OTCHAN   // chan int
@@ -744,3 +816,69 @@
 	}
 	n2.slice = nil
 }
+
+// inspect invokes f on each node in an AST in depth-first order.
+// If f(n) returns false, inspect skips visiting n's children.
+func inspect(n *Node, f func(*Node) bool) {
+	if n == nil || !f(n) {
+		return
+	}
+	inspectList(n.Ninit, f)
+	inspect(n.Left, f)
+	inspect(n.Right, f)
+	inspectList(n.List, f)
+	inspectList(n.Nbody, f)
+	inspectList(n.Rlist, f)
+}
+
+func inspectList(l Nodes, f func(*Node) bool) {
+	for _, n := range l.Slice() {
+		inspect(n, f)
+	}
+}
+
+// nodeQueue is a FIFO queue of *Node. The zero value of nodeQueue is
+// a ready-to-use empty queue.
+type nodeQueue struct {
+	ring       []*Node
+	head, tail int
+}
+
+// empty returns true if q contains no Nodes.
+func (q *nodeQueue) empty() bool {
+	return q.head == q.tail
+}
+
+// pushRight appends n to the right of the queue.
+func (q *nodeQueue) pushRight(n *Node) {
+	if len(q.ring) == 0 {
+		q.ring = make([]*Node, 16)
+	} else if q.head+len(q.ring) == q.tail {
+		// Grow the ring.
+		nring := make([]*Node, len(q.ring)*2)
+		// Copy the old elements.
+		part := q.ring[q.head%len(q.ring):]
+		if q.tail-q.head <= len(part) {
+			part = part[:q.tail-q.head]
+			copy(nring, part)
+		} else {
+			pos := copy(nring, part)
+			copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
+		}
+		q.ring, q.head, q.tail = nring, 0, q.tail-q.head
+	}
+
+	q.ring[q.tail%len(q.ring)] = n
+	q.tail++
+}
+
+// popLeft pops a node from the left of the queue. It panics if q is
+// empty.
+func (q *nodeQueue) popLeft() *Node {
+	if q.empty() {
+		panic("dequeue empty")
+	}
+	n := q.ring[q.head%len(q.ring)]
+	q.head++
+	return n
+}
diff --git a/src/cmd/compile/internal/gc/testdata/arithConst.go b/src/cmd/compile/internal/gc/testdata/arithConst.go
index ef42359..ef565bf 100644
--- a/src/cmd/compile/internal/gc/testdata/arithConst.go
+++ b/src/cmd/compile/internal/gc/testdata/arithConst.go
@@ -346,6 +346,156 @@
 }
 
 //go:noinline
+func and_uint64_0_ssa(a uint64) uint64 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_uint64_ssa(a uint64) uint64 {
+	return 0 & a
+}
+
+//go:noinline
+func and_uint64_1_ssa(a uint64) uint64 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_uint64_ssa(a uint64) uint64 {
+	return 1 & a
+}
+
+//go:noinline
+func and_uint64_4294967296_ssa(a uint64) uint64 {
+	return a & 4294967296
+}
+
+//go:noinline
+func and_4294967296_uint64_ssa(a uint64) uint64 {
+	return 4294967296 & a
+}
+
+//go:noinline
+func and_uint64_9223372036854775808_ssa(a uint64) uint64 {
+	return a & 9223372036854775808
+}
+
+//go:noinline
+func and_9223372036854775808_uint64_ssa(a uint64) uint64 {
+	return 9223372036854775808 & a
+}
+
+//go:noinline
+func and_uint64_18446744073709551615_ssa(a uint64) uint64 {
+	return a & 18446744073709551615
+}
+
+//go:noinline
+func and_18446744073709551615_uint64_ssa(a uint64) uint64 {
+	return 18446744073709551615 & a
+}
+
+//go:noinline
+func or_uint64_0_ssa(a uint64) uint64 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_uint64_ssa(a uint64) uint64 {
+	return 0 | a
+}
+
+//go:noinline
+func or_uint64_1_ssa(a uint64) uint64 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_uint64_ssa(a uint64) uint64 {
+	return 1 | a
+}
+
+//go:noinline
+func or_uint64_4294967296_ssa(a uint64) uint64 {
+	return a | 4294967296
+}
+
+//go:noinline
+func or_4294967296_uint64_ssa(a uint64) uint64 {
+	return 4294967296 | a
+}
+
+//go:noinline
+func or_uint64_9223372036854775808_ssa(a uint64) uint64 {
+	return a | 9223372036854775808
+}
+
+//go:noinline
+func or_9223372036854775808_uint64_ssa(a uint64) uint64 {
+	return 9223372036854775808 | a
+}
+
+//go:noinline
+func or_uint64_18446744073709551615_ssa(a uint64) uint64 {
+	return a | 18446744073709551615
+}
+
+//go:noinline
+func or_18446744073709551615_uint64_ssa(a uint64) uint64 {
+	return 18446744073709551615 | a
+}
+
+//go:noinline
+func xor_uint64_0_ssa(a uint64) uint64 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_uint64_ssa(a uint64) uint64 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_uint64_1_ssa(a uint64) uint64 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_uint64_ssa(a uint64) uint64 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_uint64_4294967296_ssa(a uint64) uint64 {
+	return a ^ 4294967296
+}
+
+//go:noinline
+func xor_4294967296_uint64_ssa(a uint64) uint64 {
+	return 4294967296 ^ a
+}
+
+//go:noinline
+func xor_uint64_9223372036854775808_ssa(a uint64) uint64 {
+	return a ^ 9223372036854775808
+}
+
+//go:noinline
+func xor_9223372036854775808_uint64_ssa(a uint64) uint64 {
+	return 9223372036854775808 ^ a
+}
+
+//go:noinline
+func xor_uint64_18446744073709551615_ssa(a uint64) uint64 {
+	return a ^ 18446744073709551615
+}
+
+//go:noinline
+func xor_18446744073709551615_uint64_ssa(a uint64) uint64 {
+	return 18446744073709551615 ^ a
+}
+
+//go:noinline
 func add_int64_Neg9223372036854775808_ssa(a int64) int64 {
 	return a + -9223372036854775808
 }
@@ -786,6 +936,276 @@
 }
 
 //go:noinline
+func and_int64_Neg9223372036854775808_ssa(a int64) int64 {
+	return a & -9223372036854775808
+}
+
+//go:noinline
+func and_Neg9223372036854775808_int64_ssa(a int64) int64 {
+	return -9223372036854775808 & a
+}
+
+//go:noinline
+func and_int64_Neg9223372036854775807_ssa(a int64) int64 {
+	return a & -9223372036854775807
+}
+
+//go:noinline
+func and_Neg9223372036854775807_int64_ssa(a int64) int64 {
+	return -9223372036854775807 & a
+}
+
+//go:noinline
+func and_int64_Neg4294967296_ssa(a int64) int64 {
+	return a & -4294967296
+}
+
+//go:noinline
+func and_Neg4294967296_int64_ssa(a int64) int64 {
+	return -4294967296 & a
+}
+
+//go:noinline
+func and_int64_Neg1_ssa(a int64) int64 {
+	return a & -1
+}
+
+//go:noinline
+func and_Neg1_int64_ssa(a int64) int64 {
+	return -1 & a
+}
+
+//go:noinline
+func and_int64_0_ssa(a int64) int64 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_int64_ssa(a int64) int64 {
+	return 0 & a
+}
+
+//go:noinline
+func and_int64_1_ssa(a int64) int64 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_int64_ssa(a int64) int64 {
+	return 1 & a
+}
+
+//go:noinline
+func and_int64_4294967296_ssa(a int64) int64 {
+	return a & 4294967296
+}
+
+//go:noinline
+func and_4294967296_int64_ssa(a int64) int64 {
+	return 4294967296 & a
+}
+
+//go:noinline
+func and_int64_9223372036854775806_ssa(a int64) int64 {
+	return a & 9223372036854775806
+}
+
+//go:noinline
+func and_9223372036854775806_int64_ssa(a int64) int64 {
+	return 9223372036854775806 & a
+}
+
+//go:noinline
+func and_int64_9223372036854775807_ssa(a int64) int64 {
+	return a & 9223372036854775807
+}
+
+//go:noinline
+func and_9223372036854775807_int64_ssa(a int64) int64 {
+	return 9223372036854775807 & a
+}
+
+//go:noinline
+func or_int64_Neg9223372036854775808_ssa(a int64) int64 {
+	return a | -9223372036854775808
+}
+
+//go:noinline
+func or_Neg9223372036854775808_int64_ssa(a int64) int64 {
+	return -9223372036854775808 | a
+}
+
+//go:noinline
+func or_int64_Neg9223372036854775807_ssa(a int64) int64 {
+	return a | -9223372036854775807
+}
+
+//go:noinline
+func or_Neg9223372036854775807_int64_ssa(a int64) int64 {
+	return -9223372036854775807 | a
+}
+
+//go:noinline
+func or_int64_Neg4294967296_ssa(a int64) int64 {
+	return a | -4294967296
+}
+
+//go:noinline
+func or_Neg4294967296_int64_ssa(a int64) int64 {
+	return -4294967296 | a
+}
+
+//go:noinline
+func or_int64_Neg1_ssa(a int64) int64 {
+	return a | -1
+}
+
+//go:noinline
+func or_Neg1_int64_ssa(a int64) int64 {
+	return -1 | a
+}
+
+//go:noinline
+func or_int64_0_ssa(a int64) int64 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_int64_ssa(a int64) int64 {
+	return 0 | a
+}
+
+//go:noinline
+func or_int64_1_ssa(a int64) int64 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_int64_ssa(a int64) int64 {
+	return 1 | a
+}
+
+//go:noinline
+func or_int64_4294967296_ssa(a int64) int64 {
+	return a | 4294967296
+}
+
+//go:noinline
+func or_4294967296_int64_ssa(a int64) int64 {
+	return 4294967296 | a
+}
+
+//go:noinline
+func or_int64_9223372036854775806_ssa(a int64) int64 {
+	return a | 9223372036854775806
+}
+
+//go:noinline
+func or_9223372036854775806_int64_ssa(a int64) int64 {
+	return 9223372036854775806 | a
+}
+
+//go:noinline
+func or_int64_9223372036854775807_ssa(a int64) int64 {
+	return a | 9223372036854775807
+}
+
+//go:noinline
+func or_9223372036854775807_int64_ssa(a int64) int64 {
+	return 9223372036854775807 | a
+}
+
+//go:noinline
+func xor_int64_Neg9223372036854775808_ssa(a int64) int64 {
+	return a ^ -9223372036854775808
+}
+
+//go:noinline
+func xor_Neg9223372036854775808_int64_ssa(a int64) int64 {
+	return -9223372036854775808 ^ a
+}
+
+//go:noinline
+func xor_int64_Neg9223372036854775807_ssa(a int64) int64 {
+	return a ^ -9223372036854775807
+}
+
+//go:noinline
+func xor_Neg9223372036854775807_int64_ssa(a int64) int64 {
+	return -9223372036854775807 ^ a
+}
+
+//go:noinline
+func xor_int64_Neg4294967296_ssa(a int64) int64 {
+	return a ^ -4294967296
+}
+
+//go:noinline
+func xor_Neg4294967296_int64_ssa(a int64) int64 {
+	return -4294967296 ^ a
+}
+
+//go:noinline
+func xor_int64_Neg1_ssa(a int64) int64 {
+	return a ^ -1
+}
+
+//go:noinline
+func xor_Neg1_int64_ssa(a int64) int64 {
+	return -1 ^ a
+}
+
+//go:noinline
+func xor_int64_0_ssa(a int64) int64 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_int64_ssa(a int64) int64 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_int64_1_ssa(a int64) int64 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_int64_ssa(a int64) int64 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_int64_4294967296_ssa(a int64) int64 {
+	return a ^ 4294967296
+}
+
+//go:noinline
+func xor_4294967296_int64_ssa(a int64) int64 {
+	return 4294967296 ^ a
+}
+
+//go:noinline
+func xor_int64_9223372036854775806_ssa(a int64) int64 {
+	return a ^ 9223372036854775806
+}
+
+//go:noinline
+func xor_9223372036854775806_int64_ssa(a int64) int64 {
+	return 9223372036854775806 ^ a
+}
+
+//go:noinline
+func xor_int64_9223372036854775807_ssa(a int64) int64 {
+	return a ^ 9223372036854775807
+}
+
+//go:noinline
+func xor_9223372036854775807_int64_ssa(a int64) int64 {
+	return 9223372036854775807 ^ a
+}
+
+//go:noinline
 func add_uint32_0_ssa(a uint32) uint32 {
 	return a + 0
 }
@@ -986,6 +1406,96 @@
 }
 
 //go:noinline
+func and_uint32_0_ssa(a uint32) uint32 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_uint32_ssa(a uint32) uint32 {
+	return 0 & a
+}
+
+//go:noinline
+func and_uint32_1_ssa(a uint32) uint32 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_uint32_ssa(a uint32) uint32 {
+	return 1 & a
+}
+
+//go:noinline
+func and_uint32_4294967295_ssa(a uint32) uint32 {
+	return a & 4294967295
+}
+
+//go:noinline
+func and_4294967295_uint32_ssa(a uint32) uint32 {
+	return 4294967295 & a
+}
+
+//go:noinline
+func or_uint32_0_ssa(a uint32) uint32 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_uint32_ssa(a uint32) uint32 {
+	return 0 | a
+}
+
+//go:noinline
+func or_uint32_1_ssa(a uint32) uint32 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_uint32_ssa(a uint32) uint32 {
+	return 1 | a
+}
+
+//go:noinline
+func or_uint32_4294967295_ssa(a uint32) uint32 {
+	return a | 4294967295
+}
+
+//go:noinline
+func or_4294967295_uint32_ssa(a uint32) uint32 {
+	return 4294967295 | a
+}
+
+//go:noinline
+func xor_uint32_0_ssa(a uint32) uint32 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_uint32_ssa(a uint32) uint32 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_uint32_1_ssa(a uint32) uint32 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_uint32_ssa(a uint32) uint32 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_uint32_4294967295_ssa(a uint32) uint32 {
+	return a ^ 4294967295
+}
+
+//go:noinline
+func xor_4294967295_uint32_ssa(a uint32) uint32 {
+	return 4294967295 ^ a
+}
+
+//go:noinline
 func add_int32_Neg2147483648_ssa(a int32) int32 {
 	return a + -2147483648
 }
@@ -1276,6 +1786,186 @@
 }
 
 //go:noinline
+func and_int32_Neg2147483648_ssa(a int32) int32 {
+	return a & -2147483648
+}
+
+//go:noinline
+func and_Neg2147483648_int32_ssa(a int32) int32 {
+	return -2147483648 & a
+}
+
+//go:noinline
+func and_int32_Neg2147483647_ssa(a int32) int32 {
+	return a & -2147483647
+}
+
+//go:noinline
+func and_Neg2147483647_int32_ssa(a int32) int32 {
+	return -2147483647 & a
+}
+
+//go:noinline
+func and_int32_Neg1_ssa(a int32) int32 {
+	return a & -1
+}
+
+//go:noinline
+func and_Neg1_int32_ssa(a int32) int32 {
+	return -1 & a
+}
+
+//go:noinline
+func and_int32_0_ssa(a int32) int32 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_int32_ssa(a int32) int32 {
+	return 0 & a
+}
+
+//go:noinline
+func and_int32_1_ssa(a int32) int32 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_int32_ssa(a int32) int32 {
+	return 1 & a
+}
+
+//go:noinline
+func and_int32_2147483647_ssa(a int32) int32 {
+	return a & 2147483647
+}
+
+//go:noinline
+func and_2147483647_int32_ssa(a int32) int32 {
+	return 2147483647 & a
+}
+
+//go:noinline
+func or_int32_Neg2147483648_ssa(a int32) int32 {
+	return a | -2147483648
+}
+
+//go:noinline
+func or_Neg2147483648_int32_ssa(a int32) int32 {
+	return -2147483648 | a
+}
+
+//go:noinline
+func or_int32_Neg2147483647_ssa(a int32) int32 {
+	return a | -2147483647
+}
+
+//go:noinline
+func or_Neg2147483647_int32_ssa(a int32) int32 {
+	return -2147483647 | a
+}
+
+//go:noinline
+func or_int32_Neg1_ssa(a int32) int32 {
+	return a | -1
+}
+
+//go:noinline
+func or_Neg1_int32_ssa(a int32) int32 {
+	return -1 | a
+}
+
+//go:noinline
+func or_int32_0_ssa(a int32) int32 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_int32_ssa(a int32) int32 {
+	return 0 | a
+}
+
+//go:noinline
+func or_int32_1_ssa(a int32) int32 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_int32_ssa(a int32) int32 {
+	return 1 | a
+}
+
+//go:noinline
+func or_int32_2147483647_ssa(a int32) int32 {
+	return a | 2147483647
+}
+
+//go:noinline
+func or_2147483647_int32_ssa(a int32) int32 {
+	return 2147483647 | a
+}
+
+//go:noinline
+func xor_int32_Neg2147483648_ssa(a int32) int32 {
+	return a ^ -2147483648
+}
+
+//go:noinline
+func xor_Neg2147483648_int32_ssa(a int32) int32 {
+	return -2147483648 ^ a
+}
+
+//go:noinline
+func xor_int32_Neg2147483647_ssa(a int32) int32 {
+	return a ^ -2147483647
+}
+
+//go:noinline
+func xor_Neg2147483647_int32_ssa(a int32) int32 {
+	return -2147483647 ^ a
+}
+
+//go:noinline
+func xor_int32_Neg1_ssa(a int32) int32 {
+	return a ^ -1
+}
+
+//go:noinline
+func xor_Neg1_int32_ssa(a int32) int32 {
+	return -1 ^ a
+}
+
+//go:noinline
+func xor_int32_0_ssa(a int32) int32 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_int32_ssa(a int32) int32 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_int32_1_ssa(a int32) int32 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_int32_ssa(a int32) int32 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_int32_2147483647_ssa(a int32) int32 {
+	return a ^ 2147483647
+}
+
+//go:noinline
+func xor_2147483647_int32_ssa(a int32) int32 {
+	return 2147483647 ^ a
+}
+
+//go:noinline
 func add_uint16_0_ssa(a uint16) uint16 {
 	return a + 0
 }
@@ -1476,6 +2166,96 @@
 }
 
 //go:noinline
+func and_uint16_0_ssa(a uint16) uint16 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_uint16_ssa(a uint16) uint16 {
+	return 0 & a
+}
+
+//go:noinline
+func and_uint16_1_ssa(a uint16) uint16 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_uint16_ssa(a uint16) uint16 {
+	return 1 & a
+}
+
+//go:noinline
+func and_uint16_65535_ssa(a uint16) uint16 {
+	return a & 65535
+}
+
+//go:noinline
+func and_65535_uint16_ssa(a uint16) uint16 {
+	return 65535 & a
+}
+
+//go:noinline
+func or_uint16_0_ssa(a uint16) uint16 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_uint16_ssa(a uint16) uint16 {
+	return 0 | a
+}
+
+//go:noinline
+func or_uint16_1_ssa(a uint16) uint16 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_uint16_ssa(a uint16) uint16 {
+	return 1 | a
+}
+
+//go:noinline
+func or_uint16_65535_ssa(a uint16) uint16 {
+	return a | 65535
+}
+
+//go:noinline
+func or_65535_uint16_ssa(a uint16) uint16 {
+	return 65535 | a
+}
+
+//go:noinline
+func xor_uint16_0_ssa(a uint16) uint16 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_uint16_ssa(a uint16) uint16 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_uint16_1_ssa(a uint16) uint16 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_uint16_ssa(a uint16) uint16 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_uint16_65535_ssa(a uint16) uint16 {
+	return a ^ 65535
+}
+
+//go:noinline
+func xor_65535_uint16_ssa(a uint16) uint16 {
+	return 65535 ^ a
+}
+
+//go:noinline
 func add_int16_Neg32768_ssa(a int16) int16 {
 	return a + -32768
 }
@@ -1816,6 +2596,216 @@
 }
 
 //go:noinline
+func and_int16_Neg32768_ssa(a int16) int16 {
+	return a & -32768
+}
+
+//go:noinline
+func and_Neg32768_int16_ssa(a int16) int16 {
+	return -32768 & a
+}
+
+//go:noinline
+func and_int16_Neg32767_ssa(a int16) int16 {
+	return a & -32767
+}
+
+//go:noinline
+func and_Neg32767_int16_ssa(a int16) int16 {
+	return -32767 & a
+}
+
+//go:noinline
+func and_int16_Neg1_ssa(a int16) int16 {
+	return a & -1
+}
+
+//go:noinline
+func and_Neg1_int16_ssa(a int16) int16 {
+	return -1 & a
+}
+
+//go:noinline
+func and_int16_0_ssa(a int16) int16 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_int16_ssa(a int16) int16 {
+	return 0 & a
+}
+
+//go:noinline
+func and_int16_1_ssa(a int16) int16 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_int16_ssa(a int16) int16 {
+	return 1 & a
+}
+
+//go:noinline
+func and_int16_32766_ssa(a int16) int16 {
+	return a & 32766
+}
+
+//go:noinline
+func and_32766_int16_ssa(a int16) int16 {
+	return 32766 & a
+}
+
+//go:noinline
+func and_int16_32767_ssa(a int16) int16 {
+	return a & 32767
+}
+
+//go:noinline
+func and_32767_int16_ssa(a int16) int16 {
+	return 32767 & a
+}
+
+//go:noinline
+func or_int16_Neg32768_ssa(a int16) int16 {
+	return a | -32768
+}
+
+//go:noinline
+func or_Neg32768_int16_ssa(a int16) int16 {
+	return -32768 | a
+}
+
+//go:noinline
+func or_int16_Neg32767_ssa(a int16) int16 {
+	return a | -32767
+}
+
+//go:noinline
+func or_Neg32767_int16_ssa(a int16) int16 {
+	return -32767 | a
+}
+
+//go:noinline
+func or_int16_Neg1_ssa(a int16) int16 {
+	return a | -1
+}
+
+//go:noinline
+func or_Neg1_int16_ssa(a int16) int16 {
+	return -1 | a
+}
+
+//go:noinline
+func or_int16_0_ssa(a int16) int16 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_int16_ssa(a int16) int16 {
+	return 0 | a
+}
+
+//go:noinline
+func or_int16_1_ssa(a int16) int16 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_int16_ssa(a int16) int16 {
+	return 1 | a
+}
+
+//go:noinline
+func or_int16_32766_ssa(a int16) int16 {
+	return a | 32766
+}
+
+//go:noinline
+func or_32766_int16_ssa(a int16) int16 {
+	return 32766 | a
+}
+
+//go:noinline
+func or_int16_32767_ssa(a int16) int16 {
+	return a | 32767
+}
+
+//go:noinline
+func or_32767_int16_ssa(a int16) int16 {
+	return 32767 | a
+}
+
+//go:noinline
+func xor_int16_Neg32768_ssa(a int16) int16 {
+	return a ^ -32768
+}
+
+//go:noinline
+func xor_Neg32768_int16_ssa(a int16) int16 {
+	return -32768 ^ a
+}
+
+//go:noinline
+func xor_int16_Neg32767_ssa(a int16) int16 {
+	return a ^ -32767
+}
+
+//go:noinline
+func xor_Neg32767_int16_ssa(a int16) int16 {
+	return -32767 ^ a
+}
+
+//go:noinline
+func xor_int16_Neg1_ssa(a int16) int16 {
+	return a ^ -1
+}
+
+//go:noinline
+func xor_Neg1_int16_ssa(a int16) int16 {
+	return -1 ^ a
+}
+
+//go:noinline
+func xor_int16_0_ssa(a int16) int16 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_int16_ssa(a int16) int16 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_int16_1_ssa(a int16) int16 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_int16_ssa(a int16) int16 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_int16_32766_ssa(a int16) int16 {
+	return a ^ 32766
+}
+
+//go:noinline
+func xor_32766_int16_ssa(a int16) int16 {
+	return 32766 ^ a
+}
+
+//go:noinline
+func xor_int16_32767_ssa(a int16) int16 {
+	return a ^ 32767
+}
+
+//go:noinline
+func xor_32767_int16_ssa(a int16) int16 {
+	return 32767 ^ a
+}
+
+//go:noinline
 func add_uint8_0_ssa(a uint8) uint8 {
 	return a + 0
 }
@@ -2016,6 +3006,96 @@
 }
 
 //go:noinline
+func and_uint8_0_ssa(a uint8) uint8 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_uint8_ssa(a uint8) uint8 {
+	return 0 & a
+}
+
+//go:noinline
+func and_uint8_1_ssa(a uint8) uint8 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_uint8_ssa(a uint8) uint8 {
+	return 1 & a
+}
+
+//go:noinline
+func and_uint8_255_ssa(a uint8) uint8 {
+	return a & 255
+}
+
+//go:noinline
+func and_255_uint8_ssa(a uint8) uint8 {
+	return 255 & a
+}
+
+//go:noinline
+func or_uint8_0_ssa(a uint8) uint8 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_uint8_ssa(a uint8) uint8 {
+	return 0 | a
+}
+
+//go:noinline
+func or_uint8_1_ssa(a uint8) uint8 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_uint8_ssa(a uint8) uint8 {
+	return 1 | a
+}
+
+//go:noinline
+func or_uint8_255_ssa(a uint8) uint8 {
+	return a | 255
+}
+
+//go:noinline
+func or_255_uint8_ssa(a uint8) uint8 {
+	return 255 | a
+}
+
+//go:noinline
+func xor_uint8_0_ssa(a uint8) uint8 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_uint8_ssa(a uint8) uint8 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_uint8_1_ssa(a uint8) uint8 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_uint8_ssa(a uint8) uint8 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_uint8_255_ssa(a uint8) uint8 {
+	return a ^ 255
+}
+
+//go:noinline
+func xor_255_uint8_ssa(a uint8) uint8 {
+	return 255 ^ a
+}
+
+//go:noinline
 func add_int8_Neg128_ssa(a int8) int8 {
 	return a + -128
 }
@@ -2355,6 +3435,216 @@
 	return 127 % a
 }
 
+//go:noinline
+func and_int8_Neg128_ssa(a int8) int8 {
+	return a & -128
+}
+
+//go:noinline
+func and_Neg128_int8_ssa(a int8) int8 {
+	return -128 & a
+}
+
+//go:noinline
+func and_int8_Neg127_ssa(a int8) int8 {
+	return a & -127
+}
+
+//go:noinline
+func and_Neg127_int8_ssa(a int8) int8 {
+	return -127 & a
+}
+
+//go:noinline
+func and_int8_Neg1_ssa(a int8) int8 {
+	return a & -1
+}
+
+//go:noinline
+func and_Neg1_int8_ssa(a int8) int8 {
+	return -1 & a
+}
+
+//go:noinline
+func and_int8_0_ssa(a int8) int8 {
+	return a & 0
+}
+
+//go:noinline
+func and_0_int8_ssa(a int8) int8 {
+	return 0 & a
+}
+
+//go:noinline
+func and_int8_1_ssa(a int8) int8 {
+	return a & 1
+}
+
+//go:noinline
+func and_1_int8_ssa(a int8) int8 {
+	return 1 & a
+}
+
+//go:noinline
+func and_int8_126_ssa(a int8) int8 {
+	return a & 126
+}
+
+//go:noinline
+func and_126_int8_ssa(a int8) int8 {
+	return 126 & a
+}
+
+//go:noinline
+func and_int8_127_ssa(a int8) int8 {
+	return a & 127
+}
+
+//go:noinline
+func and_127_int8_ssa(a int8) int8 {
+	return 127 & a
+}
+
+//go:noinline
+func or_int8_Neg128_ssa(a int8) int8 {
+	return a | -128
+}
+
+//go:noinline
+func or_Neg128_int8_ssa(a int8) int8 {
+	return -128 | a
+}
+
+//go:noinline
+func or_int8_Neg127_ssa(a int8) int8 {
+	return a | -127
+}
+
+//go:noinline
+func or_Neg127_int8_ssa(a int8) int8 {
+	return -127 | a
+}
+
+//go:noinline
+func or_int8_Neg1_ssa(a int8) int8 {
+	return a | -1
+}
+
+//go:noinline
+func or_Neg1_int8_ssa(a int8) int8 {
+	return -1 | a
+}
+
+//go:noinline
+func or_int8_0_ssa(a int8) int8 {
+	return a | 0
+}
+
+//go:noinline
+func or_0_int8_ssa(a int8) int8 {
+	return 0 | a
+}
+
+//go:noinline
+func or_int8_1_ssa(a int8) int8 {
+	return a | 1
+}
+
+//go:noinline
+func or_1_int8_ssa(a int8) int8 {
+	return 1 | a
+}
+
+//go:noinline
+func or_int8_126_ssa(a int8) int8 {
+	return a | 126
+}
+
+//go:noinline
+func or_126_int8_ssa(a int8) int8 {
+	return 126 | a
+}
+
+//go:noinline
+func or_int8_127_ssa(a int8) int8 {
+	return a | 127
+}
+
+//go:noinline
+func or_127_int8_ssa(a int8) int8 {
+	return 127 | a
+}
+
+//go:noinline
+func xor_int8_Neg128_ssa(a int8) int8 {
+	return a ^ -128
+}
+
+//go:noinline
+func xor_Neg128_int8_ssa(a int8) int8 {
+	return -128 ^ a
+}
+
+//go:noinline
+func xor_int8_Neg127_ssa(a int8) int8 {
+	return a ^ -127
+}
+
+//go:noinline
+func xor_Neg127_int8_ssa(a int8) int8 {
+	return -127 ^ a
+}
+
+//go:noinline
+func xor_int8_Neg1_ssa(a int8) int8 {
+	return a ^ -1
+}
+
+//go:noinline
+func xor_Neg1_int8_ssa(a int8) int8 {
+	return -1 ^ a
+}
+
+//go:noinline
+func xor_int8_0_ssa(a int8) int8 {
+	return a ^ 0
+}
+
+//go:noinline
+func xor_0_int8_ssa(a int8) int8 {
+	return 0 ^ a
+}
+
+//go:noinline
+func xor_int8_1_ssa(a int8) int8 {
+	return a ^ 1
+}
+
+//go:noinline
+func xor_1_int8_ssa(a int8) int8 {
+	return 1 ^ a
+}
+
+//go:noinline
+func xor_int8_126_ssa(a int8) int8 {
+	return a ^ 126
+}
+
+//go:noinline
+func xor_126_int8_ssa(a int8) int8 {
+	return 126 ^ a
+}
+
+//go:noinline
+func xor_int8_127_ssa(a int8) int8 {
+	return a ^ 127
+}
+
+//go:noinline
+func xor_127_int8_ssa(a int8) int8 {
+	return 127 ^ a
+}
+
 var failed bool
 
 func main() {
@@ -4009,6 +5299,756 @@
 		failed = true
 	}
 
+	if got := and_0_uint64_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_0_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint64_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_0_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 0%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_0_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint64_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 0%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_0_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint64_ssa(18446744073709551615); got != 0 {
+		fmt.Printf("and_uint64 0%s18446744073709551615 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_0_ssa(18446744073709551615); got != 0 {
+		fmt.Printf("and_uint64 18446744073709551615%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint64_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_1_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint64_ssa(1); got != 1 {
+		fmt.Printf("and_uint64 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_1_ssa(1); got != 1 {
+		fmt.Printf("and_uint64 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 1%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_1_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint64_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 1%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_1_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint64_ssa(18446744073709551615); got != 1 {
+		fmt.Printf("and_uint64 1%s18446744073709551615 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_1_ssa(18446744073709551615); got != 1 {
+		fmt.Printf("and_uint64 18446744073709551615%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_uint64_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_4294967296_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_uint64_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_4294967296_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 1%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_uint64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_uint64 4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_4294967296_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_uint64 4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_uint64_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_4294967296_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_uint64_ssa(18446744073709551615); got != 4294967296 {
+		fmt.Printf("and_uint64 4294967296%s18446744073709551615 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_4294967296_ssa(18446744073709551615); got != 4294967296 {
+		fmt.Printf("and_uint64 18446744073709551615%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775808_uint64_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_9223372036854775808_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775808_uint64_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_9223372036854775808_ssa(1); got != 0 {
+		fmt.Printf("and_uint64 1%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775808_uint64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_9223372036854775808_ssa(4294967296); got != 0 {
+		fmt.Printf("and_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775808_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_9223372036854775808_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_18446744073709551615_uint64_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 18446744073709551615%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_18446744073709551615_ssa(0); got != 0 {
+		fmt.Printf("and_uint64 0%s18446744073709551615 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_18446744073709551615_uint64_ssa(1); got != 1 {
+		fmt.Printf("and_uint64 18446744073709551615%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_18446744073709551615_ssa(1); got != 1 {
+		fmt.Printf("and_uint64 1%s18446744073709551615 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_18446744073709551615_uint64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_uint64 18446744073709551615%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_18446744073709551615_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_uint64 4294967296%s18446744073709551615 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("and_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_18446744073709551615_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("and_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 18446744073709551615\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint64_18446744073709551615_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("and_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 18446744073709551615\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_0_uint64_ssa(0); got != 0 {
+		fmt.Printf("or_uint64 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_0_ssa(0); got != 0 {
+		fmt.Printf("or_uint64 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint64_ssa(1); got != 1 {
+		fmt.Printf("or_uint64 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_0_ssa(1); got != 1 {
+		fmt.Printf("or_uint64 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_uint64 0%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_0_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_uint64 4294967296%s0 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 0%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_0_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint64_ssa(0); got != 1 {
+		fmt.Printf("or_uint64 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_1_ssa(0); got != 1 {
+		fmt.Printf("or_uint64 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint64_ssa(1); got != 1 {
+		fmt.Printf("or_uint64 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_1_ssa(1); got != 1 {
+		fmt.Printf("or_uint64 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint64_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("or_uint64 1%s4294967296 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_1_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("or_uint64 4294967296%s1 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint64_ssa(9223372036854775808); got != 9223372036854775809 {
+		fmt.Printf("or_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_1_ssa(9223372036854775808); got != 9223372036854775809 {
+		fmt.Printf("or_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 1%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_1_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s1 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_uint64_ssa(0); got != 4294967296 {
+		fmt.Printf("or_uint64 4294967296%s0 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_4294967296_ssa(0); got != 4294967296 {
+		fmt.Printf("or_uint64 0%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_uint64_ssa(1); got != 4294967297 {
+		fmt.Printf("or_uint64 4294967296%s1 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_4294967296_ssa(1); got != 4294967297 {
+		fmt.Printf("or_uint64 1%s4294967296 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_uint64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_uint64 4294967296%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_4294967296_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_uint64 4294967296%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_uint64_ssa(9223372036854775808); got != 9223372041149743104 {
+		fmt.Printf("or_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_4294967296_ssa(9223372036854775808); got != 9223372041149743104 {
+		fmt.Printf("or_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 4294967296%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_4294967296_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s4294967296 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_9223372036854775808_ssa(0); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775808_uint64_ssa(1); got != 9223372036854775809 {
+		fmt.Printf("or_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_9223372036854775808_ssa(1); got != 9223372036854775809 {
+		fmt.Printf("or_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775808_uint64_ssa(4294967296); got != 9223372041149743104 {
+		fmt.Printf("or_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_9223372036854775808_ssa(4294967296); got != 9223372041149743104 {
+		fmt.Printf("or_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775808_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_9223372036854775808_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("or_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775808_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_9223372036854775808_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_18446744073709551615_ssa(0); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 0%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_18446744073709551615_uint64_ssa(1); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s1 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_18446744073709551615_ssa(1); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 1%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_18446744073709551615_uint64_ssa(4294967296); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s4294967296 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_18446744073709551615_ssa(4294967296); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 4294967296%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_18446744073709551615_uint64_ssa(9223372036854775808); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_18446744073709551615_ssa(9223372036854775808); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_18446744073709551615_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint64_18446744073709551615_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("or_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 18446744073709551615\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint64_ssa(0); got != 0 {
+		fmt.Printf("xor_uint64 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_0_ssa(0); got != 0 {
+		fmt.Printf("xor_uint64 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint64_ssa(1); got != 1 {
+		fmt.Printf("xor_uint64 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_0_ssa(1); got != 1 {
+		fmt.Printf("xor_uint64 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("xor_uint64 0%s4294967296 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_0_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("xor_uint64 4294967296%s0 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("xor_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+		fmt.Printf("xor_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("xor_uint64 0%s18446744073709551615 = %d, wanted 18446744073709551615\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_0_ssa(18446744073709551615); got != 18446744073709551615 {
+		fmt.Printf("xor_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint64_ssa(0); got != 1 {
+		fmt.Printf("xor_uint64 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_1_ssa(0); got != 1 {
+		fmt.Printf("xor_uint64 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint64_ssa(1); got != 0 {
+		fmt.Printf("xor_uint64 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_1_ssa(1); got != 0 {
+		fmt.Printf("xor_uint64 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint64_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("xor_uint64 1%s4294967296 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_1_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("xor_uint64 4294967296%s1 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint64_ssa(9223372036854775808); got != 9223372036854775809 {
+		fmt.Printf("xor_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_1_ssa(9223372036854775808); got != 9223372036854775809 {
+		fmt.Printf("xor_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint64_ssa(18446744073709551615); got != 18446744073709551614 {
+		fmt.Printf("xor_uint64 1%s18446744073709551615 = %d, wanted 18446744073709551614\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_1_ssa(18446744073709551615); got != 18446744073709551614 {
+		fmt.Printf("xor_uint64 18446744073709551615%s1 = %d, wanted 18446744073709551614\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_uint64_ssa(0); got != 4294967296 {
+		fmt.Printf("xor_uint64 4294967296%s0 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_4294967296_ssa(0); got != 4294967296 {
+		fmt.Printf("xor_uint64 0%s4294967296 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_uint64_ssa(1); got != 4294967297 {
+		fmt.Printf("xor_uint64 4294967296%s1 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_4294967296_ssa(1); got != 4294967297 {
+		fmt.Printf("xor_uint64 1%s4294967296 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_uint64_ssa(4294967296); got != 0 {
+		fmt.Printf("xor_uint64 4294967296%s4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_4294967296_ssa(4294967296); got != 0 {
+		fmt.Printf("xor_uint64 4294967296%s4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_uint64_ssa(9223372036854775808); got != 9223372041149743104 {
+		fmt.Printf("xor_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_4294967296_ssa(9223372036854775808); got != 9223372041149743104 {
+		fmt.Printf("xor_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_uint64_ssa(18446744073709551615); got != 18446744069414584319 {
+		fmt.Printf("xor_uint64 4294967296%s18446744073709551615 = %d, wanted 18446744069414584319\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_4294967296_ssa(18446744073709551615); got != 18446744069414584319 {
+		fmt.Printf("xor_uint64 18446744073709551615%s4294967296 = %d, wanted 18446744069414584319\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+		fmt.Printf("xor_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_9223372036854775808_ssa(0); got != 9223372036854775808 {
+		fmt.Printf("xor_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775808_uint64_ssa(1); got != 9223372036854775809 {
+		fmt.Printf("xor_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_9223372036854775808_ssa(1); got != 9223372036854775809 {
+		fmt.Printf("xor_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775808_uint64_ssa(4294967296); got != 9223372041149743104 {
+		fmt.Printf("xor_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_9223372036854775808_ssa(4294967296); got != 9223372041149743104 {
+		fmt.Printf("xor_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("xor_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+		fmt.Printf("xor_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775807 {
+		fmt.Printf("xor_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775807 {
+		fmt.Printf("xor_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
+		fmt.Printf("xor_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_18446744073709551615_ssa(0); got != 18446744073709551615 {
+		fmt.Printf("xor_uint64 0%s18446744073709551615 = %d, wanted 18446744073709551615\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_18446744073709551615_uint64_ssa(1); got != 18446744073709551614 {
+		fmt.Printf("xor_uint64 18446744073709551615%s1 = %d, wanted 18446744073709551614\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_18446744073709551615_ssa(1); got != 18446744073709551614 {
+		fmt.Printf("xor_uint64 1%s18446744073709551615 = %d, wanted 18446744073709551614\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_18446744073709551615_uint64_ssa(4294967296); got != 18446744069414584319 {
+		fmt.Printf("xor_uint64 18446744073709551615%s4294967296 = %d, wanted 18446744069414584319\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_18446744073709551615_ssa(4294967296); got != 18446744069414584319 {
+		fmt.Printf("xor_uint64 4294967296%s18446744073709551615 = %d, wanted 18446744069414584319\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775807 {
+		fmt.Printf("xor_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775807 {
+		fmt.Printf("xor_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_18446744073709551615_uint64_ssa(18446744073709551615); got != 0 {
+		fmt.Printf("xor_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint64_18446744073709551615_ssa(18446744073709551615); got != 0 {
+		fmt.Printf("xor_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_Neg9223372036854775808_int64_ssa(-9223372036854775808); got != 0 {
 		fmt.Printf("add_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -7879,6 +9919,2436 @@
 		failed = true
 	}
 
+	if got := and_Neg9223372036854775808_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(-4294967296); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-4294967296 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(-4294967296); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -4294967296%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(-1); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-1 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(-1); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -1%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(1); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(1); got != 0 {
+		fmt.Printf("and_int64 1%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 4294967296%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775808_int64_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775808_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 9223372036854775807%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(-4294967296); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775807%s-4294967296 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(-4294967296); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -4294967296%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(-1); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -9223372036854775807%s-1 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(-1); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -1%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(1); got != 1 {
+		fmt.Printf("and_int64 -9223372036854775807%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(1); got != 1 {
+		fmt.Printf("and_int64 1%s-9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 4294967296%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg9223372036854775807_int64_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 -9223372036854775807%s9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg9223372036854775807_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 9223372036854775807%s-9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -4294967296%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-4294967296 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -4294967296%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775807%s-4294967296 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("and_int64 -4294967296%s-4294967296 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("and_int64 -4294967296%s-4294967296 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(-1); got != -4294967296 {
+		fmt.Printf("and_int64 -4294967296%s-1 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(-1); got != -4294967296 {
+		fmt.Printf("and_int64 -1%s-4294967296 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 -4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s-4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(1); got != 0 {
+		fmt.Printf("and_int64 -4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(1); got != 0 {
+		fmt.Printf("and_int64 1%s-4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 -4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s-4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(9223372036854775806); got != 9223372032559808512 {
+		fmt.Printf("and_int64 -4294967296%s9223372036854775806 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(9223372036854775806); got != 9223372032559808512 {
+		fmt.Printf("and_int64 9223372036854775806%s-4294967296 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg4294967296_int64_ssa(9223372036854775807); got != 9223372032559808512 {
+		fmt.Printf("and_int64 -4294967296%s9223372036854775807 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg4294967296_ssa(9223372036854775807); got != 9223372032559808512 {
+		fmt.Printf("and_int64 9223372036854775807%s-4294967296 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -1%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("and_int64 -9223372036854775808%s-1 = %d, wanted -9223372036854775808\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -1%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("and_int64 -9223372036854775807%s-1 = %d, wanted -9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("and_int64 -1%s-4294967296 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("and_int64 -4294967296%s-1 = %d, wanted -4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(-1); got != -1 {
+		fmt.Printf("and_int64 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("and_int64 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(1); got != 1 {
+		fmt.Printf("and_int64 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(1); got != 1 {
+		fmt.Printf("and_int64 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 -1%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s-1 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 -1%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s-1 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("and_int64 -1%s9223372036854775807 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_Neg1_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("and_int64 9223372036854775807%s-1 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 0%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 0%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(-4294967296); got != 0 {
+		fmt.Printf("and_int64 0%s-4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(-4294967296); got != 0 {
+		fmt.Printf("and_int64 -4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(-1); got != 0 {
+		fmt.Printf("and_int64 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(-1); got != 0 {
+		fmt.Printf("and_int64 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(1); got != 0 {
+		fmt.Printf("and_int64 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(1); got != 0 {
+		fmt.Printf("and_int64 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 0%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 0%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int64_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 0%s9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_0_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 9223372036854775807%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 1%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 1%s-9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 -9223372036854775807%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(-4294967296); got != 0 {
+		fmt.Printf("and_int64 1%s-4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(-4294967296); got != 0 {
+		fmt.Printf("and_int64 -4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(-1); got != 1 {
+		fmt.Printf("and_int64 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(-1); got != 1 {
+		fmt.Printf("and_int64 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(1); got != 1 {
+		fmt.Printf("and_int64 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(1); got != 1 {
+		fmt.Printf("and_int64 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 1%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(4294967296); got != 0 {
+		fmt.Printf("and_int64 4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 1%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int64_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 1%s9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_1_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 9223372036854775807%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 4294967296%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 4294967296%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(-4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s-4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(-4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 -4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(-1); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s-1 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(-1); got != 4294967296 {
+		fmt.Printf("and_int64 -1%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 4294967296%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(1); got != 0 {
+		fmt.Printf("and_int64 4294967296%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(1); got != 0 {
+		fmt.Printf("and_int64 1%s4294967296 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(9223372036854775806); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s9223372036854775806 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(9223372036854775806); got != 4294967296 {
+		fmt.Printf("and_int64 9223372036854775806%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967296_int64_ssa(9223372036854775807); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s9223372036854775807 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_4294967296_ssa(9223372036854775807); got != 4294967296 {
+		fmt.Printf("and_int64 9223372036854775807%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s-9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775807%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("and_int64 9223372036854775806%s-4294967296 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("and_int64 -4294967296%s9223372036854775806 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(-1); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s-1 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(-1); got != 9223372036854775806 {
+		fmt.Printf("and_int64 -1%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(1); got != 0 {
+		fmt.Printf("and_int64 9223372036854775806%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(1); got != 0 {
+		fmt.Printf("and_int64 1%s9223372036854775806 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 9223372036854775806%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s9223372036854775806 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775806_int64_ssa(9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s9223372036854775807 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775806_ssa(9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775807%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 9223372036854775807%s-9223372036854775808 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("and_int64 -9223372036854775808%s9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 9223372036854775807%s-9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("and_int64 -9223372036854775807%s9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("and_int64 9223372036854775807%s-4294967296 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("and_int64 -4294967296%s9223372036854775807 = %d, wanted 9223372032559808512\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(-1); got != 9223372036854775807 {
+		fmt.Printf("and_int64 9223372036854775807%s-1 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(-1); got != 9223372036854775807 {
+		fmt.Printf("and_int64 -1%s9223372036854775807 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(0); got != 0 {
+		fmt.Printf("and_int64 9223372036854775807%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(0); got != 0 {
+		fmt.Printf("and_int64 0%s9223372036854775807 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(1); got != 1 {
+		fmt.Printf("and_int64 9223372036854775807%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(1); got != 1 {
+		fmt.Printf("and_int64 1%s9223372036854775807 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 9223372036854775807%s4294967296 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("and_int64 4294967296%s9223372036854775807 = %d, wanted 4294967296\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775807%s9223372036854775806 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("and_int64 9223372036854775806%s9223372036854775807 = %d, wanted 9223372036854775806\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_9223372036854775807_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("and_int64 9223372036854775807%s9223372036854775807 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int64_9223372036854775807_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("and_int64 9223372036854775807%s9223372036854775807 = %d, wanted 9223372036854775807\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("or_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("or_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -9223372036854775808%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s-9223372036854775808 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775808%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s-9223372036854775808 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(0); got != -9223372036854775808 {
+		fmt.Printf("or_int64 -9223372036854775808%s0 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(0); got != -9223372036854775808 {
+		fmt.Printf("or_int64 0%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775808%s1 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("or_int64 1%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(4294967296); got != -9223372032559808512 {
+		fmt.Printf("or_int64 -9223372036854775808%s4294967296 = %d, wanted -9223372032559808512\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(4294967296); got != -9223372032559808512 {
+		fmt.Printf("or_int64 4294967296%s-9223372036854775808 = %d, wanted -9223372032559808512\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("or_int64 -9223372036854775808%s9223372036854775806 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("or_int64 9223372036854775806%s-9223372036854775808 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775808_int64_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775808%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775808_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-9223372036854775808 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("or_int64 -9223372036854775807%s-4294967296 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("or_int64 -4294967296%s-9223372036854775807 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(0); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s0 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(0); got != -9223372036854775807 {
+		fmt.Printf("or_int64 0%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s1 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("or_int64 1%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(4294967296); got != -9223372032559808511 {
+		fmt.Printf("or_int64 -9223372036854775807%s4294967296 = %d, wanted -9223372032559808511\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(4294967296); got != -9223372032559808511 {
+		fmt.Printf("or_int64 4294967296%s-9223372036854775807 = %d, wanted -9223372032559808511\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s9223372036854775806 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("or_int64 9223372036854775806%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg9223372036854775807_int64_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg9223372036854775807_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(-9223372036854775808); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s-9223372036854775808 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(-9223372036854775808); got != -4294967296 {
+		fmt.Printf("or_int64 -9223372036854775808%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(-9223372036854775807); got != -4294967295 {
+		fmt.Printf("or_int64 -4294967296%s-9223372036854775807 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(-9223372036854775807); got != -4294967295 {
+		fmt.Printf("or_int64 -9223372036854775807%s-4294967296 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -4294967296%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s-4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(0); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s0 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(0); got != -4294967296 {
+		fmt.Printf("or_int64 0%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(1); got != -4294967295 {
+		fmt.Printf("or_int64 -4294967296%s1 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(1); got != -4294967295 {
+		fmt.Printf("or_int64 1%s-4294967296 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 4294967296%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("or_int64 -4294967296%s9223372036854775806 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("or_int64 9223372036854775806%s-4294967296 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg4294967296_int64_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -4294967296%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg4294967296_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("or_int64 -1%s-9223372036854775808 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775808%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -1%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(-4294967296); got != -1 {
+		fmt.Printf("or_int64 -1%s-4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(-4294967296); got != -1 {
+		fmt.Printf("or_int64 -4294967296%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(0); got != -1 {
+		fmt.Printf("or_int64 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(0); got != -1 {
+		fmt.Printf("or_int64 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(1); got != -1 {
+		fmt.Printf("or_int64 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(1); got != -1 {
+		fmt.Printf("or_int64 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(4294967296); got != -1 {
+		fmt.Printf("or_int64 -1%s4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(4294967296); got != -1 {
+		fmt.Printf("or_int64 4294967296%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("or_int64 -1%s9223372036854775806 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("or_int64 9223372036854775806%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int64_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -1%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_Neg1_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("or_int64 0%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("or_int64 -9223372036854775808%s0 = %d, wanted -9223372036854775808\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 0%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s0 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 0%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s0 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(0); got != 0 {
+		fmt.Printf("or_int64 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(0); got != 0 {
+		fmt.Printf("or_int64 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(1); got != 1 {
+		fmt.Printf("or_int64 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(1); got != 1 {
+		fmt.Printf("or_int64 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_int64 0%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_int64 4294967296%s0 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 0%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s0 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 0%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_0_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s0 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("or_int64 1%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775808%s1 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 1%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("or_int64 -9223372036854775807%s1 = %d, wanted -9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("or_int64 1%s-4294967296 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("or_int64 -4294967296%s1 = %d, wanted -4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(0); got != 1 {
+		fmt.Printf("or_int64 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(0); got != 1 {
+		fmt.Printf("or_int64 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(1); got != 1 {
+		fmt.Printf("or_int64 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(1); got != 1 {
+		fmt.Printf("or_int64 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("or_int64 1%s4294967296 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("or_int64 4294967296%s1 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("or_int64 1%s9223372036854775806 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775806%s1 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 1%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_1_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s1 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(-9223372036854775808); got != -9223372032559808512 {
+		fmt.Printf("or_int64 4294967296%s-9223372036854775808 = %d, wanted -9223372032559808512\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(-9223372036854775808); got != -9223372032559808512 {
+		fmt.Printf("or_int64 -9223372036854775808%s4294967296 = %d, wanted -9223372032559808512\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(-9223372036854775807); got != -9223372032559808511 {
+		fmt.Printf("or_int64 4294967296%s-9223372036854775807 = %d, wanted -9223372032559808511\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(-9223372036854775807); got != -9223372032559808511 {
+		fmt.Printf("or_int64 -9223372036854775807%s4294967296 = %d, wanted -9223372032559808511\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 4294967296%s-4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("or_int64 -4294967296%s4294967296 = %d, wanted -4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 4294967296%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(0); got != 4294967296 {
+		fmt.Printf("or_int64 4294967296%s0 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(0); got != 4294967296 {
+		fmt.Printf("or_int64 0%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(1); got != 4294967297 {
+		fmt.Printf("or_int64 4294967296%s1 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(1); got != 4294967297 {
+		fmt.Printf("or_int64 1%s4294967296 = %d, wanted 4294967297\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_int64 4294967296%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("or_int64 4294967296%s4294967296 = %d, wanted 4294967296\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 4294967296%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s4294967296 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967296_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 4294967296%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_4294967296_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s4294967296 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(-9223372036854775808); got != -2 {
+		fmt.Printf("or_int64 9223372036854775806%s-9223372036854775808 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(-9223372036854775808); got != -2 {
+		fmt.Printf("or_int64 -9223372036854775808%s9223372036854775806 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775806%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s9223372036854775806 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(-4294967296); got != -2 {
+		fmt.Printf("or_int64 9223372036854775806%s-4294967296 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(-4294967296); got != -2 {
+		fmt.Printf("or_int64 -4294967296%s9223372036854775806 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 9223372036854775806%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s9223372036854775806 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(0); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s0 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(0); got != 9223372036854775806 {
+		fmt.Printf("or_int64 0%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775806%s1 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("or_int64 1%s9223372036854775806 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(4294967296); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s4294967296 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(4294967296); got != 9223372036854775806 {
+		fmt.Printf("or_int64 4294967296%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("or_int64 9223372036854775806%s9223372036854775806 = %d, wanted 9223372036854775806\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775806_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775806%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775806_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s9223372036854775806 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-9223372036854775808 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775808%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("or_int64 -9223372036854775807%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(-4294967296); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-4294967296 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(-4294967296); got != -1 {
+		fmt.Printf("or_int64 -4294967296%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 9223372036854775807%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(-1); got != -1 {
+		fmt.Printf("or_int64 -1%s9223372036854775807 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(0); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s0 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(0); got != 9223372036854775807 {
+		fmt.Printf("or_int64 0%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s1 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("or_int64 1%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(4294967296); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s4294967296 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(4294967296); got != 9223372036854775807 {
+		fmt.Printf("or_int64 4294967296%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s9223372036854775806 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775806%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_9223372036854775807_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int64_9223372036854775807_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("or_int64 9223372036854775807%s9223372036854775807 = %d, wanted 9223372036854775807\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(-9223372036854775808); got != 0 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-9223372036854775808 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(-9223372036854775807); got != 1 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-4294967296 = %d, wanted 9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(-4294967296); got != 9223372032559808512 {
+		fmt.Printf("xor_int64 -4294967296%s-9223372036854775808 = %d, wanted 9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(-1); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-1 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(-1); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 -1%s-9223372036854775808 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(0); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -9223372036854775808%s0 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(0); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 0%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775808%s1 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(1); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 1%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(4294967296); got != -9223372032559808512 {
+		fmt.Printf("xor_int64 -9223372036854775808%s4294967296 = %d, wanted -9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(4294967296); got != -9223372032559808512 {
+		fmt.Printf("xor_int64 4294967296%s-9223372036854775808 = %d, wanted -9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("xor_int64 -9223372036854775808%s9223372036854775806 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(9223372036854775806); got != -2 {
+		fmt.Printf("xor_int64 9223372036854775806%s-9223372036854775808 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775808_int64_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("xor_int64 -9223372036854775808%s9223372036854775807 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775808_ssa(9223372036854775807); got != -1 {
+		fmt.Printf("xor_int64 9223372036854775807%s-9223372036854775808 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(-9223372036854775808); got != 1 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-9223372036854775808 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(-9223372036854775808); got != 1 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-9223372036854775807 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(-9223372036854775807); got != 0 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-9223372036854775807 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(-4294967296); got != 9223372032559808513 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-4294967296 = %d, wanted 9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(-4294967296); got != 9223372032559808513 {
+		fmt.Printf("xor_int64 -4294967296%s-9223372036854775807 = %d, wanted 9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(-1); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-1 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(-1); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 -1%s-9223372036854775807 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(0); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775807%s0 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(0); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 0%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(1); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -9223372036854775807%s1 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(1); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 1%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(4294967296); got != -9223372032559808511 {
+		fmt.Printf("xor_int64 -9223372036854775807%s4294967296 = %d, wanted -9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(4294967296); got != -9223372032559808511 {
+		fmt.Printf("xor_int64 4294967296%s-9223372036854775807 = %d, wanted -9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("xor_int64 -9223372036854775807%s9223372036854775806 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(9223372036854775806); got != -1 {
+		fmt.Printf("xor_int64 9223372036854775806%s-9223372036854775807 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg9223372036854775807_int64_ssa(9223372036854775807); got != -2 {
+		fmt.Printf("xor_int64 -9223372036854775807%s9223372036854775807 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg9223372036854775807_ssa(9223372036854775807); got != -2 {
+		fmt.Printf("xor_int64 9223372036854775807%s-9223372036854775807 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(-9223372036854775808); got != 9223372032559808512 {
+		fmt.Printf("xor_int64 -4294967296%s-9223372036854775808 = %d, wanted 9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(-9223372036854775808); got != 9223372032559808512 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-4294967296 = %d, wanted 9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(-9223372036854775807); got != 9223372032559808513 {
+		fmt.Printf("xor_int64 -4294967296%s-9223372036854775807 = %d, wanted 9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(-9223372036854775807); got != 9223372032559808513 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-4294967296 = %d, wanted 9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(-4294967296); got != 0 {
+		fmt.Printf("xor_int64 -4294967296%s-4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(-4294967296); got != 0 {
+		fmt.Printf("xor_int64 -4294967296%s-4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(-1); got != 4294967295 {
+		fmt.Printf("xor_int64 -4294967296%s-1 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(-1); got != 4294967295 {
+		fmt.Printf("xor_int64 -1%s-4294967296 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(0); got != -4294967296 {
+		fmt.Printf("xor_int64 -4294967296%s0 = %d, wanted -4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(0); got != -4294967296 {
+		fmt.Printf("xor_int64 0%s-4294967296 = %d, wanted -4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(1); got != -4294967295 {
+		fmt.Printf("xor_int64 -4294967296%s1 = %d, wanted -4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(1); got != -4294967295 {
+		fmt.Printf("xor_int64 1%s-4294967296 = %d, wanted -4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(4294967296); got != -8589934592 {
+		fmt.Printf("xor_int64 -4294967296%s4294967296 = %d, wanted -8589934592\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(4294967296); got != -8589934592 {
+		fmt.Printf("xor_int64 4294967296%s-4294967296 = %d, wanted -8589934592\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(9223372036854775806); got != -9223372032559808514 {
+		fmt.Printf("xor_int64 -4294967296%s9223372036854775806 = %d, wanted -9223372032559808514\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(9223372036854775806); got != -9223372032559808514 {
+		fmt.Printf("xor_int64 9223372036854775806%s-4294967296 = %d, wanted -9223372032559808514\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg4294967296_int64_ssa(9223372036854775807); got != -9223372032559808513 {
+		fmt.Printf("xor_int64 -4294967296%s9223372036854775807 = %d, wanted -9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg4294967296_ssa(9223372036854775807); got != -9223372032559808513 {
+		fmt.Printf("xor_int64 9223372036854775807%s-4294967296 = %d, wanted -9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(-9223372036854775808); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 -1%s-9223372036854775808 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(-9223372036854775808); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775808%s-1 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(-9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 -1%s-9223372036854775807 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(-9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 -9223372036854775807%s-1 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(-4294967296); got != 4294967295 {
+		fmt.Printf("xor_int64 -1%s-4294967296 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(-4294967296); got != 4294967295 {
+		fmt.Printf("xor_int64 -4294967296%s-1 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(-1); got != 0 {
+		fmt.Printf("xor_int64 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(-1); got != 0 {
+		fmt.Printf("xor_int64 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(0); got != -1 {
+		fmt.Printf("xor_int64 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(0); got != -1 {
+		fmt.Printf("xor_int64 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(1); got != -2 {
+		fmt.Printf("xor_int64 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(1); got != -2 {
+		fmt.Printf("xor_int64 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(4294967296); got != -4294967297 {
+		fmt.Printf("xor_int64 -1%s4294967296 = %d, wanted -4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(4294967296); got != -4294967297 {
+		fmt.Printf("xor_int64 4294967296%s-1 = %d, wanted -4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(9223372036854775806); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -1%s9223372036854775806 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(9223372036854775806); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775806%s-1 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int64_ssa(9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -1%s9223372036854775807 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_Neg1_ssa(9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 9223372036854775807%s-1 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 0%s-9223372036854775808 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(-9223372036854775808); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -9223372036854775808%s0 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 0%s-9223372036854775807 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(-9223372036854775807); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775807%s0 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("xor_int64 0%s-4294967296 = %d, wanted -4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(-4294967296); got != -4294967296 {
+		fmt.Printf("xor_int64 -4294967296%s0 = %d, wanted -4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(-1); got != -1 {
+		fmt.Printf("xor_int64 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(-1); got != -1 {
+		fmt.Printf("xor_int64 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(0); got != 0 {
+		fmt.Printf("xor_int64 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(0); got != 0 {
+		fmt.Printf("xor_int64 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(1); got != 1 {
+		fmt.Printf("xor_int64 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(1); got != 1 {
+		fmt.Printf("xor_int64 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("xor_int64 0%s4294967296 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(4294967296); got != 4294967296 {
+		fmt.Printf("xor_int64 4294967296%s0 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 0%s9223372036854775806 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(9223372036854775806); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 9223372036854775806%s0 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int64_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 0%s9223372036854775807 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_0_ssa(9223372036854775807); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775807%s0 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 1%s-9223372036854775808 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(-9223372036854775808); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -9223372036854775808%s1 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 1%s-9223372036854775807 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(-9223372036854775807); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -9223372036854775807%s1 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("xor_int64 1%s-4294967296 = %d, wanted -4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(-4294967296); got != -4294967295 {
+		fmt.Printf("xor_int64 -4294967296%s1 = %d, wanted -4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(-1); got != -2 {
+		fmt.Printf("xor_int64 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(-1); got != -2 {
+		fmt.Printf("xor_int64 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(0); got != 1 {
+		fmt.Printf("xor_int64 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(0); got != 1 {
+		fmt.Printf("xor_int64 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(1); got != 0 {
+		fmt.Printf("xor_int64 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(1); got != 0 {
+		fmt.Printf("xor_int64 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("xor_int64 1%s4294967296 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(4294967296); got != 4294967297 {
+		fmt.Printf("xor_int64 4294967296%s1 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 1%s9223372036854775806 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(9223372036854775806); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775806%s1 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int64_ssa(9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 1%s9223372036854775807 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_1_ssa(9223372036854775807); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 9223372036854775807%s1 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(-9223372036854775808); got != -9223372032559808512 {
+		fmt.Printf("xor_int64 4294967296%s-9223372036854775808 = %d, wanted -9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(-9223372036854775808); got != -9223372032559808512 {
+		fmt.Printf("xor_int64 -9223372036854775808%s4294967296 = %d, wanted -9223372032559808512\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(-9223372036854775807); got != -9223372032559808511 {
+		fmt.Printf("xor_int64 4294967296%s-9223372036854775807 = %d, wanted -9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(-9223372036854775807); got != -9223372032559808511 {
+		fmt.Printf("xor_int64 -9223372036854775807%s4294967296 = %d, wanted -9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(-4294967296); got != -8589934592 {
+		fmt.Printf("xor_int64 4294967296%s-4294967296 = %d, wanted -8589934592\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(-4294967296); got != -8589934592 {
+		fmt.Printf("xor_int64 -4294967296%s4294967296 = %d, wanted -8589934592\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(-1); got != -4294967297 {
+		fmt.Printf("xor_int64 4294967296%s-1 = %d, wanted -4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(-1); got != -4294967297 {
+		fmt.Printf("xor_int64 -1%s4294967296 = %d, wanted -4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(0); got != 4294967296 {
+		fmt.Printf("xor_int64 4294967296%s0 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(0); got != 4294967296 {
+		fmt.Printf("xor_int64 0%s4294967296 = %d, wanted 4294967296\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(1); got != 4294967297 {
+		fmt.Printf("xor_int64 4294967296%s1 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(1); got != 4294967297 {
+		fmt.Printf("xor_int64 1%s4294967296 = %d, wanted 4294967297\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(4294967296); got != 0 {
+		fmt.Printf("xor_int64 4294967296%s4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(4294967296); got != 0 {
+		fmt.Printf("xor_int64 4294967296%s4294967296 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(9223372036854775806); got != 9223372032559808510 {
+		fmt.Printf("xor_int64 4294967296%s9223372036854775806 = %d, wanted 9223372032559808510\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(9223372036854775806); got != 9223372032559808510 {
+		fmt.Printf("xor_int64 9223372036854775806%s4294967296 = %d, wanted 9223372032559808510\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967296_int64_ssa(9223372036854775807); got != 9223372032559808511 {
+		fmt.Printf("xor_int64 4294967296%s9223372036854775807 = %d, wanted 9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_4294967296_ssa(9223372036854775807); got != 9223372032559808511 {
+		fmt.Printf("xor_int64 9223372036854775807%s4294967296 = %d, wanted 9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(-9223372036854775808); got != -2 {
+		fmt.Printf("xor_int64 9223372036854775806%s-9223372036854775808 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(-9223372036854775808); got != -2 {
+		fmt.Printf("xor_int64 -9223372036854775808%s9223372036854775806 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("xor_int64 9223372036854775806%s-9223372036854775807 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(-9223372036854775807); got != -1 {
+		fmt.Printf("xor_int64 -9223372036854775807%s9223372036854775806 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(-4294967296); got != -9223372032559808514 {
+		fmt.Printf("xor_int64 9223372036854775806%s-4294967296 = %d, wanted -9223372032559808514\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(-4294967296); got != -9223372032559808514 {
+		fmt.Printf("xor_int64 -4294967296%s9223372036854775806 = %d, wanted -9223372032559808514\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(-1); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775806%s-1 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(-1); got != -9223372036854775807 {
+		fmt.Printf("xor_int64 -1%s9223372036854775806 = %d, wanted -9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(0); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 9223372036854775806%s0 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(0); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 0%s9223372036854775806 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775806%s1 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(1); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 1%s9223372036854775806 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(4294967296); got != 9223372032559808510 {
+		fmt.Printf("xor_int64 9223372036854775806%s4294967296 = %d, wanted 9223372032559808510\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(4294967296); got != 9223372032559808510 {
+		fmt.Printf("xor_int64 4294967296%s9223372036854775806 = %d, wanted 9223372032559808510\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("xor_int64 9223372036854775806%s9223372036854775806 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(9223372036854775806); got != 0 {
+		fmt.Printf("xor_int64 9223372036854775806%s9223372036854775806 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775806_int64_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("xor_int64 9223372036854775806%s9223372036854775807 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775806_ssa(9223372036854775807); got != 1 {
+		fmt.Printf("xor_int64 9223372036854775807%s9223372036854775806 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("xor_int64 9223372036854775807%s-9223372036854775808 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(-9223372036854775808); got != -1 {
+		fmt.Printf("xor_int64 -9223372036854775808%s9223372036854775807 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(-9223372036854775807); got != -2 {
+		fmt.Printf("xor_int64 9223372036854775807%s-9223372036854775807 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(-9223372036854775807); got != -2 {
+		fmt.Printf("xor_int64 -9223372036854775807%s9223372036854775807 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(-4294967296); got != -9223372032559808513 {
+		fmt.Printf("xor_int64 9223372036854775807%s-4294967296 = %d, wanted -9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(-4294967296); got != -9223372032559808513 {
+		fmt.Printf("xor_int64 -4294967296%s9223372036854775807 = %d, wanted -9223372032559808513\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(-1); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 9223372036854775807%s-1 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(-1); got != -9223372036854775808 {
+		fmt.Printf("xor_int64 -1%s9223372036854775807 = %d, wanted -9223372036854775808\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(0); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 9223372036854775807%s0 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(0); got != 9223372036854775807 {
+		fmt.Printf("xor_int64 0%s9223372036854775807 = %d, wanted 9223372036854775807\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(1); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 9223372036854775807%s1 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(1); got != 9223372036854775806 {
+		fmt.Printf("xor_int64 1%s9223372036854775807 = %d, wanted 9223372036854775806\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(4294967296); got != 9223372032559808511 {
+		fmt.Printf("xor_int64 9223372036854775807%s4294967296 = %d, wanted 9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(4294967296); got != 9223372032559808511 {
+		fmt.Printf("xor_int64 4294967296%s9223372036854775807 = %d, wanted 9223372032559808511\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(9223372036854775806); got != 1 {
+		fmt.Printf("xor_int64 9223372036854775807%s9223372036854775806 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(9223372036854775806); got != 1 {
+		fmt.Printf("xor_int64 9223372036854775806%s9223372036854775807 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_9223372036854775807_int64_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("xor_int64 9223372036854775807%s9223372036854775807 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int64_9223372036854775807_ssa(9223372036854775807); got != 0 {
+		fmt.Printf("xor_int64 9223372036854775807%s9223372036854775807 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_0_uint32_ssa(0); got != 0 {
 		fmt.Printf("add_uint32 0%s0 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -8449,6 +12919,276 @@
 		failed = true
 	}
 
+	if got := and_0_uint32_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_0_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint32_ssa(1); got != 0 {
+		fmt.Printf("and_uint32 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_0_ssa(1); got != 0 {
+		fmt.Printf("and_uint32 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint32_ssa(4294967295); got != 0 {
+		fmt.Printf("and_uint32 0%s4294967295 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_0_ssa(4294967295); got != 0 {
+		fmt.Printf("and_uint32 4294967295%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint32_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_1_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint32_ssa(1); got != 1 {
+		fmt.Printf("and_uint32 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_1_ssa(1); got != 1 {
+		fmt.Printf("and_uint32 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint32_ssa(4294967295); got != 1 {
+		fmt.Printf("and_uint32 1%s4294967295 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_1_ssa(4294967295); got != 1 {
+		fmt.Printf("and_uint32 4294967295%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967295_uint32_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 4294967295%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_4294967295_ssa(0); got != 0 {
+		fmt.Printf("and_uint32 0%s4294967295 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967295_uint32_ssa(1); got != 1 {
+		fmt.Printf("and_uint32 4294967295%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_4294967295_ssa(1); got != 1 {
+		fmt.Printf("and_uint32 1%s4294967295 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_4294967295_uint32_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("and_uint32 4294967295%s4294967295 = %d, wanted 4294967295\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint32_4294967295_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("and_uint32 4294967295%s4294967295 = %d, wanted 4294967295\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_0_uint32_ssa(0); got != 0 {
+		fmt.Printf("or_uint32 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_0_ssa(0); got != 0 {
+		fmt.Printf("or_uint32 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint32_ssa(1); got != 1 {
+		fmt.Printf("or_uint32 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_0_ssa(1); got != 1 {
+		fmt.Printf("or_uint32 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint32_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 0%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_0_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s0 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint32_ssa(0); got != 1 {
+		fmt.Printf("or_uint32 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_1_ssa(0); got != 1 {
+		fmt.Printf("or_uint32 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint32_ssa(1); got != 1 {
+		fmt.Printf("or_uint32 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_1_ssa(1); got != 1 {
+		fmt.Printf("or_uint32 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint32_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 1%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_1_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s1 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967295_uint32_ssa(0); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s0 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_4294967295_ssa(0); got != 4294967295 {
+		fmt.Printf("or_uint32 0%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967295_uint32_ssa(1); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s1 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_4294967295_ssa(1); got != 4294967295 {
+		fmt.Printf("or_uint32 1%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_4294967295_uint32_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint32_4294967295_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("or_uint32 4294967295%s4294967295 = %d, wanted 4294967295\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint32_ssa(0); got != 0 {
+		fmt.Printf("xor_uint32 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_0_ssa(0); got != 0 {
+		fmt.Printf("xor_uint32 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint32_ssa(1); got != 1 {
+		fmt.Printf("xor_uint32 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_0_ssa(1); got != 1 {
+		fmt.Printf("xor_uint32 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint32_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("xor_uint32 0%s4294967295 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_0_ssa(4294967295); got != 4294967295 {
+		fmt.Printf("xor_uint32 4294967295%s0 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint32_ssa(0); got != 1 {
+		fmt.Printf("xor_uint32 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_1_ssa(0); got != 1 {
+		fmt.Printf("xor_uint32 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint32_ssa(1); got != 0 {
+		fmt.Printf("xor_uint32 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_1_ssa(1); got != 0 {
+		fmt.Printf("xor_uint32 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint32_ssa(4294967295); got != 4294967294 {
+		fmt.Printf("xor_uint32 1%s4294967295 = %d, wanted 4294967294\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_1_ssa(4294967295); got != 4294967294 {
+		fmt.Printf("xor_uint32 4294967295%s1 = %d, wanted 4294967294\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967295_uint32_ssa(0); got != 4294967295 {
+		fmt.Printf("xor_uint32 4294967295%s0 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_4294967295_ssa(0); got != 4294967295 {
+		fmt.Printf("xor_uint32 0%s4294967295 = %d, wanted 4294967295\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967295_uint32_ssa(1); got != 4294967294 {
+		fmt.Printf("xor_uint32 4294967295%s1 = %d, wanted 4294967294\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_4294967295_ssa(1); got != 4294967294 {
+		fmt.Printf("xor_uint32 1%s4294967295 = %d, wanted 4294967294\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_4294967295_uint32_ssa(4294967295); got != 0 {
+		fmt.Printf("xor_uint32 4294967295%s4294967295 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint32_4294967295_ssa(4294967295); got != 0 {
+		fmt.Printf("xor_uint32 4294967295%s4294967295 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_Neg2147483648_int32_ssa(-2147483648); got != 0 {
 		fmt.Printf("add_int32 -2147483648%s-2147483648 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -10129,6 +14869,1086 @@
 		failed = true
 	}
 
+	if got := and_Neg2147483648_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483648_int32_ssa(-2147483647); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-2147483647 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(-2147483647); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483647%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483648_int32_ssa(-1); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-1 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(-1); got != -2147483648 {
+		fmt.Printf("and_int32 -1%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483648_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483648_int32_ssa(1); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(1); got != 0 {
+		fmt.Printf("and_int32 1%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483648_int32_ssa(2147483647); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483648_ssa(2147483647); got != 0 {
+		fmt.Printf("and_int32 2147483647%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483647%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-2147483647 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("and_int32 -2147483647%s-2147483647 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("and_int32 -2147483647%s-2147483647 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(-1); got != -2147483647 {
+		fmt.Printf("and_int32 -2147483647%s-1 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(-1); got != -2147483647 {
+		fmt.Printf("and_int32 -1%s-2147483647 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 -2147483647%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s-2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(1); got != 1 {
+		fmt.Printf("and_int32 -2147483647%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(1); got != 1 {
+		fmt.Printf("and_int32 1%s-2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg2147483647_int32_ssa(2147483647); got != 1 {
+		fmt.Printf("and_int32 -2147483647%s2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg2147483647_ssa(2147483647); got != 1 {
+		fmt.Printf("and_int32 2147483647%s-2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -1%s-2147483648 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("and_int32 -2147483648%s-1 = %d, wanted -2147483648\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("and_int32 -1%s-2147483647 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("and_int32 -2147483647%s-1 = %d, wanted -2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(-1); got != -1 {
+		fmt.Printf("and_int32 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("and_int32 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(1); got != 1 {
+		fmt.Printf("and_int32 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(1); got != 1 {
+		fmt.Printf("and_int32 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("and_int32 -1%s2147483647 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_Neg1_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("and_int32 2147483647%s-1 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 0%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(-2147483647); got != 0 {
+		fmt.Printf("and_int32 0%s-2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(-2147483647); got != 0 {
+		fmt.Printf("and_int32 -2147483647%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(-1); got != 0 {
+		fmt.Printf("and_int32 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(-1); got != 0 {
+		fmt.Printf("and_int32 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(1); got != 0 {
+		fmt.Printf("and_int32 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(1); got != 0 {
+		fmt.Printf("and_int32 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int32_ssa(2147483647); got != 0 {
+		fmt.Printf("and_int32 0%s2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_0_ssa(2147483647); got != 0 {
+		fmt.Printf("and_int32 2147483647%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 1%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(-2147483647); got != 1 {
+		fmt.Printf("and_int32 1%s-2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(-2147483647); got != 1 {
+		fmt.Printf("and_int32 -2147483647%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(-1); got != 1 {
+		fmt.Printf("and_int32 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(-1); got != 1 {
+		fmt.Printf("and_int32 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(1); got != 1 {
+		fmt.Printf("and_int32 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(1); got != 1 {
+		fmt.Printf("and_int32 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int32_ssa(2147483647); got != 1 {
+		fmt.Printf("and_int32 1%s2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_1_ssa(2147483647); got != 1 {
+		fmt.Printf("and_int32 2147483647%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 2147483647%s-2147483648 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(-2147483648); got != 0 {
+		fmt.Printf("and_int32 -2147483648%s2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(-2147483647); got != 1 {
+		fmt.Printf("and_int32 2147483647%s-2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(-2147483647); got != 1 {
+		fmt.Printf("and_int32 -2147483647%s2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(-1); got != 2147483647 {
+		fmt.Printf("and_int32 2147483647%s-1 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(-1); got != 2147483647 {
+		fmt.Printf("and_int32 -1%s2147483647 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(0); got != 0 {
+		fmt.Printf("and_int32 2147483647%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(0); got != 0 {
+		fmt.Printf("and_int32 0%s2147483647 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(1); got != 1 {
+		fmt.Printf("and_int32 2147483647%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(1); got != 1 {
+		fmt.Printf("and_int32 1%s2147483647 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_2147483647_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("and_int32 2147483647%s2147483647 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int32_2147483647_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("and_int32 2147483647%s2147483647 = %d, wanted 2147483647\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("or_int32 -2147483648%s-2147483648 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("or_int32 -2147483648%s-2147483648 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483648%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s-2147483648 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -2147483648%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s-2147483648 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(0); got != -2147483648 {
+		fmt.Printf("or_int32 -2147483648%s0 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(0); got != -2147483648 {
+		fmt.Printf("or_int32 0%s-2147483648 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(1); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483648%s1 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(1); got != -2147483647 {
+		fmt.Printf("or_int32 1%s-2147483648 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483648_int32_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 -2147483648%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483648_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-2147483648 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s-2147483648 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483648%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -2147483647%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s-2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(0); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s0 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(0); got != -2147483647 {
+		fmt.Printf("or_int32 0%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(1); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s1 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(1); got != -2147483647 {
+		fmt.Printf("or_int32 1%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg2147483647_int32_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 -2147483647%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg2147483647_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(-2147483648); got != -1 {
+		fmt.Printf("or_int32 -1%s-2147483648 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(-2147483648); got != -1 {
+		fmt.Printf("or_int32 -2147483648%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(-2147483647); got != -1 {
+		fmt.Printf("or_int32 -1%s-2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(-2147483647); got != -1 {
+		fmt.Printf("or_int32 -2147483647%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(0); got != -1 {
+		fmt.Printf("or_int32 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(0); got != -1 {
+		fmt.Printf("or_int32 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(1); got != -1 {
+		fmt.Printf("or_int32 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(1); got != -1 {
+		fmt.Printf("or_int32 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int32_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 -1%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_Neg1_ssa(2147483647); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("or_int32 0%s-2147483648 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("or_int32 -2147483648%s0 = %d, wanted -2147483648\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 0%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s0 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(0); got != 0 {
+		fmt.Printf("or_int32 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(0); got != 0 {
+		fmt.Printf("or_int32 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(1); got != 1 {
+		fmt.Printf("or_int32 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(1); got != 1 {
+		fmt.Printf("or_int32 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 0%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_0_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s0 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("or_int32 1%s-2147483648 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483648%s1 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 1%s-2147483647 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("or_int32 -2147483647%s1 = %d, wanted -2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(0); got != 1 {
+		fmt.Printf("or_int32 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(0); got != 1 {
+		fmt.Printf("or_int32 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(1); got != 1 {
+		fmt.Printf("or_int32 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(1); got != 1 {
+		fmt.Printf("or_int32 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 1%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_1_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s1 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(-2147483648); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-2147483648 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(-2147483648); got != -1 {
+		fmt.Printf("or_int32 -2147483648%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(-2147483647); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(-2147483647); got != -1 {
+		fmt.Printf("or_int32 -2147483647%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 2147483647%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(-1); got != -1 {
+		fmt.Printf("or_int32 -1%s2147483647 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(0); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s0 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(0); got != 2147483647 {
+		fmt.Printf("or_int32 0%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(1); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s1 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(1); got != 2147483647 {
+		fmt.Printf("or_int32 1%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_2147483647_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int32_2147483647_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("or_int32 2147483647%s2147483647 = %d, wanted 2147483647\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(-2147483648); got != 0 {
+		fmt.Printf("xor_int32 -2147483648%s-2147483648 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(-2147483648); got != 0 {
+		fmt.Printf("xor_int32 -2147483648%s-2147483648 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(-2147483647); got != 1 {
+		fmt.Printf("xor_int32 -2147483648%s-2147483647 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(-2147483647); got != 1 {
+		fmt.Printf("xor_int32 -2147483647%s-2147483648 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(-1); got != 2147483647 {
+		fmt.Printf("xor_int32 -2147483648%s-1 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(-1); got != 2147483647 {
+		fmt.Printf("xor_int32 -1%s-2147483648 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(0); got != -2147483648 {
+		fmt.Printf("xor_int32 -2147483648%s0 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(0); got != -2147483648 {
+		fmt.Printf("xor_int32 0%s-2147483648 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(1); got != -2147483647 {
+		fmt.Printf("xor_int32 -2147483648%s1 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(1); got != -2147483647 {
+		fmt.Printf("xor_int32 1%s-2147483648 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483648_int32_ssa(2147483647); got != -1 {
+		fmt.Printf("xor_int32 -2147483648%s2147483647 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483648_ssa(2147483647); got != -1 {
+		fmt.Printf("xor_int32 2147483647%s-2147483648 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(-2147483648); got != 1 {
+		fmt.Printf("xor_int32 -2147483647%s-2147483648 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(-2147483648); got != 1 {
+		fmt.Printf("xor_int32 -2147483648%s-2147483647 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(-2147483647); got != 0 {
+		fmt.Printf("xor_int32 -2147483647%s-2147483647 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(-2147483647); got != 0 {
+		fmt.Printf("xor_int32 -2147483647%s-2147483647 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(-1); got != 2147483646 {
+		fmt.Printf("xor_int32 -2147483647%s-1 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(-1); got != 2147483646 {
+		fmt.Printf("xor_int32 -1%s-2147483647 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(0); got != -2147483647 {
+		fmt.Printf("xor_int32 -2147483647%s0 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(0); got != -2147483647 {
+		fmt.Printf("xor_int32 0%s-2147483647 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(1); got != -2147483648 {
+		fmt.Printf("xor_int32 -2147483647%s1 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(1); got != -2147483648 {
+		fmt.Printf("xor_int32 1%s-2147483647 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg2147483647_int32_ssa(2147483647); got != -2 {
+		fmt.Printf("xor_int32 -2147483647%s2147483647 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg2147483647_ssa(2147483647); got != -2 {
+		fmt.Printf("xor_int32 2147483647%s-2147483647 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(-2147483648); got != 2147483647 {
+		fmt.Printf("xor_int32 -1%s-2147483648 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(-2147483648); got != 2147483647 {
+		fmt.Printf("xor_int32 -2147483648%s-1 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(-2147483647); got != 2147483646 {
+		fmt.Printf("xor_int32 -1%s-2147483647 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(-2147483647); got != 2147483646 {
+		fmt.Printf("xor_int32 -2147483647%s-1 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(-1); got != 0 {
+		fmt.Printf("xor_int32 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(-1); got != 0 {
+		fmt.Printf("xor_int32 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(0); got != -1 {
+		fmt.Printf("xor_int32 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(0); got != -1 {
+		fmt.Printf("xor_int32 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(1); got != -2 {
+		fmt.Printf("xor_int32 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(1); got != -2 {
+		fmt.Printf("xor_int32 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int32_ssa(2147483647); got != -2147483648 {
+		fmt.Printf("xor_int32 -1%s2147483647 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_Neg1_ssa(2147483647); got != -2147483648 {
+		fmt.Printf("xor_int32 2147483647%s-1 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("xor_int32 0%s-2147483648 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(-2147483648); got != -2147483648 {
+		fmt.Printf("xor_int32 -2147483648%s0 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("xor_int32 0%s-2147483647 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(-2147483647); got != -2147483647 {
+		fmt.Printf("xor_int32 -2147483647%s0 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(-1); got != -1 {
+		fmt.Printf("xor_int32 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(-1); got != -1 {
+		fmt.Printf("xor_int32 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(0); got != 0 {
+		fmt.Printf("xor_int32 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(0); got != 0 {
+		fmt.Printf("xor_int32 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(1); got != 1 {
+		fmt.Printf("xor_int32 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(1); got != 1 {
+		fmt.Printf("xor_int32 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int32_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("xor_int32 0%s2147483647 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_0_ssa(2147483647); got != 2147483647 {
+		fmt.Printf("xor_int32 2147483647%s0 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("xor_int32 1%s-2147483648 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(-2147483648); got != -2147483647 {
+		fmt.Printf("xor_int32 -2147483648%s1 = %d, wanted -2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(-2147483647); got != -2147483648 {
+		fmt.Printf("xor_int32 1%s-2147483647 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(-2147483647); got != -2147483648 {
+		fmt.Printf("xor_int32 -2147483647%s1 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(-1); got != -2 {
+		fmt.Printf("xor_int32 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(-1); got != -2 {
+		fmt.Printf("xor_int32 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(0); got != 1 {
+		fmt.Printf("xor_int32 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(0); got != 1 {
+		fmt.Printf("xor_int32 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(1); got != 0 {
+		fmt.Printf("xor_int32 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(1); got != 0 {
+		fmt.Printf("xor_int32 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int32_ssa(2147483647); got != 2147483646 {
+		fmt.Printf("xor_int32 1%s2147483647 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_1_ssa(2147483647); got != 2147483646 {
+		fmt.Printf("xor_int32 2147483647%s1 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(-2147483648); got != -1 {
+		fmt.Printf("xor_int32 2147483647%s-2147483648 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(-2147483648); got != -1 {
+		fmt.Printf("xor_int32 -2147483648%s2147483647 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(-2147483647); got != -2 {
+		fmt.Printf("xor_int32 2147483647%s-2147483647 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(-2147483647); got != -2 {
+		fmt.Printf("xor_int32 -2147483647%s2147483647 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(-1); got != -2147483648 {
+		fmt.Printf("xor_int32 2147483647%s-1 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(-1); got != -2147483648 {
+		fmt.Printf("xor_int32 -1%s2147483647 = %d, wanted -2147483648\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(0); got != 2147483647 {
+		fmt.Printf("xor_int32 2147483647%s0 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(0); got != 2147483647 {
+		fmt.Printf("xor_int32 0%s2147483647 = %d, wanted 2147483647\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(1); got != 2147483646 {
+		fmt.Printf("xor_int32 2147483647%s1 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(1); got != 2147483646 {
+		fmt.Printf("xor_int32 1%s2147483647 = %d, wanted 2147483646\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_2147483647_int32_ssa(2147483647); got != 0 {
+		fmt.Printf("xor_int32 2147483647%s2147483647 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int32_2147483647_ssa(2147483647); got != 0 {
+		fmt.Printf("xor_int32 2147483647%s2147483647 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_0_uint16_ssa(0); got != 0 {
 		fmt.Printf("add_uint16 0%s0 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -10699,6 +16519,276 @@
 		failed = true
 	}
 
+	if got := and_0_uint16_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_0_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint16_ssa(1); got != 0 {
+		fmt.Printf("and_uint16 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_0_ssa(1); got != 0 {
+		fmt.Printf("and_uint16 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint16_ssa(65535); got != 0 {
+		fmt.Printf("and_uint16 0%s65535 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_0_ssa(65535); got != 0 {
+		fmt.Printf("and_uint16 65535%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint16_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_1_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint16_ssa(1); got != 1 {
+		fmt.Printf("and_uint16 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_1_ssa(1); got != 1 {
+		fmt.Printf("and_uint16 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint16_ssa(65535); got != 1 {
+		fmt.Printf("and_uint16 1%s65535 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_1_ssa(65535); got != 1 {
+		fmt.Printf("and_uint16 65535%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_65535_uint16_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 65535%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_65535_ssa(0); got != 0 {
+		fmt.Printf("and_uint16 0%s65535 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_65535_uint16_ssa(1); got != 1 {
+		fmt.Printf("and_uint16 65535%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_65535_ssa(1); got != 1 {
+		fmt.Printf("and_uint16 1%s65535 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_65535_uint16_ssa(65535); got != 65535 {
+		fmt.Printf("and_uint16 65535%s65535 = %d, wanted 65535\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint16_65535_ssa(65535); got != 65535 {
+		fmt.Printf("and_uint16 65535%s65535 = %d, wanted 65535\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_0_uint16_ssa(0); got != 0 {
+		fmt.Printf("or_uint16 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_0_ssa(0); got != 0 {
+		fmt.Printf("or_uint16 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint16_ssa(1); got != 1 {
+		fmt.Printf("or_uint16 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_0_ssa(1); got != 1 {
+		fmt.Printf("or_uint16 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint16_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 0%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_0_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 65535%s0 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint16_ssa(0); got != 1 {
+		fmt.Printf("or_uint16 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_1_ssa(0); got != 1 {
+		fmt.Printf("or_uint16 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint16_ssa(1); got != 1 {
+		fmt.Printf("or_uint16 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_1_ssa(1); got != 1 {
+		fmt.Printf("or_uint16 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint16_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 1%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_1_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 65535%s1 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_65535_uint16_ssa(0); got != 65535 {
+		fmt.Printf("or_uint16 65535%s0 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_65535_ssa(0); got != 65535 {
+		fmt.Printf("or_uint16 0%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_65535_uint16_ssa(1); got != 65535 {
+		fmt.Printf("or_uint16 65535%s1 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_65535_ssa(1); got != 65535 {
+		fmt.Printf("or_uint16 1%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_65535_uint16_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 65535%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint16_65535_ssa(65535); got != 65535 {
+		fmt.Printf("or_uint16 65535%s65535 = %d, wanted 65535\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint16_ssa(0); got != 0 {
+		fmt.Printf("xor_uint16 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_0_ssa(0); got != 0 {
+		fmt.Printf("xor_uint16 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint16_ssa(1); got != 1 {
+		fmt.Printf("xor_uint16 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_0_ssa(1); got != 1 {
+		fmt.Printf("xor_uint16 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint16_ssa(65535); got != 65535 {
+		fmt.Printf("xor_uint16 0%s65535 = %d, wanted 65535\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_0_ssa(65535); got != 65535 {
+		fmt.Printf("xor_uint16 65535%s0 = %d, wanted 65535\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint16_ssa(0); got != 1 {
+		fmt.Printf("xor_uint16 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_1_ssa(0); got != 1 {
+		fmt.Printf("xor_uint16 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint16_ssa(1); got != 0 {
+		fmt.Printf("xor_uint16 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_1_ssa(1); got != 0 {
+		fmt.Printf("xor_uint16 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint16_ssa(65535); got != 65534 {
+		fmt.Printf("xor_uint16 1%s65535 = %d, wanted 65534\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_1_ssa(65535); got != 65534 {
+		fmt.Printf("xor_uint16 65535%s1 = %d, wanted 65534\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_65535_uint16_ssa(0); got != 65535 {
+		fmt.Printf("xor_uint16 65535%s0 = %d, wanted 65535\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_65535_ssa(0); got != 65535 {
+		fmt.Printf("xor_uint16 0%s65535 = %d, wanted 65535\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_65535_uint16_ssa(1); got != 65534 {
+		fmt.Printf("xor_uint16 65535%s1 = %d, wanted 65534\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_65535_ssa(1); got != 65534 {
+		fmt.Printf("xor_uint16 1%s65535 = %d, wanted 65534\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_65535_uint16_ssa(65535); got != 0 {
+		fmt.Printf("xor_uint16 65535%s65535 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint16_65535_ssa(65535); got != 0 {
+		fmt.Printf("xor_uint16 65535%s65535 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_Neg32768_int16_ssa(-32768); got != 0 {
 		fmt.Printf("add_int16 -32768%s-32768 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -13009,6 +19099,1476 @@
 		failed = true
 	}
 
+	if got := and_Neg32768_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(-32767); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-32767 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(-32767); got != -32768 {
+		fmt.Printf("and_int16 -32767%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(-1); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-1 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(-1); got != -32768 {
+		fmt.Printf("and_int16 -1%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 -32768%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(1); got != 0 {
+		fmt.Printf("and_int16 -32768%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(1); got != 0 {
+		fmt.Printf("and_int16 1%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 -32768%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 32766%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32768_int16_ssa(32767); got != 0 {
+		fmt.Printf("and_int16 -32768%s32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32768_ssa(32767); got != 0 {
+		fmt.Printf("and_int16 32767%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -32767%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-32767 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("and_int16 -32767%s-32767 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(-32767); got != -32767 {
+		fmt.Printf("and_int16 -32767%s-32767 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(-1); got != -32767 {
+		fmt.Printf("and_int16 -32767%s-1 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(-1); got != -32767 {
+		fmt.Printf("and_int16 -1%s-32767 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 -32767%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s-32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(1); got != 1 {
+		fmt.Printf("and_int16 -32767%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(1); got != 1 {
+		fmt.Printf("and_int16 1%s-32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 -32767%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 32766%s-32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg32767_int16_ssa(32767); got != 1 {
+		fmt.Printf("and_int16 -32767%s32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg32767_ssa(32767); got != 1 {
+		fmt.Printf("and_int16 32767%s-32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -1%s-32768 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(-32768); got != -32768 {
+		fmt.Printf("and_int16 -32768%s-1 = %d, wanted -32768\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("and_int16 -1%s-32767 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(-32767); got != -32767 {
+		fmt.Printf("and_int16 -32767%s-1 = %d, wanted -32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(-1); got != -1 {
+		fmt.Printf("and_int16 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("and_int16 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(1); got != 1 {
+		fmt.Printf("and_int16 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(1); got != 1 {
+		fmt.Printf("and_int16 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 -1%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 32766%s-1 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int16_ssa(32767); got != 32767 {
+		fmt.Printf("and_int16 -1%s32767 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_Neg1_ssa(32767); got != 32767 {
+		fmt.Printf("and_int16 32767%s-1 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 0%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 -32768%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(-32767); got != 0 {
+		fmt.Printf("and_int16 0%s-32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(-32767); got != 0 {
+		fmt.Printf("and_int16 -32767%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(-1); got != 0 {
+		fmt.Printf("and_int16 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(-1); got != 0 {
+		fmt.Printf("and_int16 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(1); got != 0 {
+		fmt.Printf("and_int16 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(1); got != 0 {
+		fmt.Printf("and_int16 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 0%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 32766%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int16_ssa(32767); got != 0 {
+		fmt.Printf("and_int16 0%s32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_0_ssa(32767); got != 0 {
+		fmt.Printf("and_int16 32767%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 1%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 -32768%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(-32767); got != 1 {
+		fmt.Printf("and_int16 1%s-32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(-32767); got != 1 {
+		fmt.Printf("and_int16 -32767%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(-1); got != 1 {
+		fmt.Printf("and_int16 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(-1); got != 1 {
+		fmt.Printf("and_int16 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(1); got != 1 {
+		fmt.Printf("and_int16 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(1); got != 1 {
+		fmt.Printf("and_int16 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 1%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(32766); got != 0 {
+		fmt.Printf("and_int16 32766%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int16_ssa(32767); got != 1 {
+		fmt.Printf("and_int16 1%s32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_1_ssa(32767); got != 1 {
+		fmt.Printf("and_int16 32767%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 32766%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 -32768%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(-32767); got != 0 {
+		fmt.Printf("and_int16 32766%s-32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(-32767); got != 0 {
+		fmt.Printf("and_int16 -32767%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(-1); got != 32766 {
+		fmt.Printf("and_int16 32766%s-1 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(-1); got != 32766 {
+		fmt.Printf("and_int16 -1%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 32766%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(1); got != 0 {
+		fmt.Printf("and_int16 32766%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(1); got != 0 {
+		fmt.Printf("and_int16 1%s32766 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 32766%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 32766%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32766_int16_ssa(32767); got != 32766 {
+		fmt.Printf("and_int16 32766%s32767 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32766_ssa(32767); got != 32766 {
+		fmt.Printf("and_int16 32767%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 32767%s-32768 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(-32768); got != 0 {
+		fmt.Printf("and_int16 -32768%s32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(-32767); got != 1 {
+		fmt.Printf("and_int16 32767%s-32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(-32767); got != 1 {
+		fmt.Printf("and_int16 -32767%s32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(-1); got != 32767 {
+		fmt.Printf("and_int16 32767%s-1 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(-1); got != 32767 {
+		fmt.Printf("and_int16 -1%s32767 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(0); got != 0 {
+		fmt.Printf("and_int16 32767%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(0); got != 0 {
+		fmt.Printf("and_int16 0%s32767 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(1); got != 1 {
+		fmt.Printf("and_int16 32767%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(1); got != 1 {
+		fmt.Printf("and_int16 1%s32767 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 32767%s32766 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(32766); got != 32766 {
+		fmt.Printf("and_int16 32766%s32767 = %d, wanted 32766\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_32767_int16_ssa(32767); got != 32767 {
+		fmt.Printf("and_int16 32767%s32767 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int16_32767_ssa(32767); got != 32767 {
+		fmt.Printf("and_int16 32767%s32767 = %d, wanted 32767\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("or_int16 -32768%s-32768 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(-32768); got != -32768 {
+		fmt.Printf("or_int16 -32768%s-32768 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32768%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32767%s-32768 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -32768%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s-32768 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(0); got != -32768 {
+		fmt.Printf("or_int16 -32768%s0 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(0); got != -32768 {
+		fmt.Printf("or_int16 0%s-32768 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(1); got != -32767 {
+		fmt.Printf("or_int16 -32768%s1 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(1); got != -32767 {
+		fmt.Printf("or_int16 1%s-32768 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(32766); got != -2 {
+		fmt.Printf("or_int16 -32768%s32766 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(32766); got != -2 {
+		fmt.Printf("or_int16 32766%s-32768 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32768_int16_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 -32768%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32768_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 32767%s-32768 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(-32768); got != -32767 {
+		fmt.Printf("or_int16 -32767%s-32768 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(-32768); got != -32767 {
+		fmt.Printf("or_int16 -32768%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32767%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32767%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -32767%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(0); got != -32767 {
+		fmt.Printf("or_int16 -32767%s0 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(0); got != -32767 {
+		fmt.Printf("or_int16 0%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(1); got != -32767 {
+		fmt.Printf("or_int16 -32767%s1 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(1); got != -32767 {
+		fmt.Printf("or_int16 1%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(32766); got != -1 {
+		fmt.Printf("or_int16 -32767%s32766 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(32766); got != -1 {
+		fmt.Printf("or_int16 32766%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg32767_int16_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 -32767%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg32767_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 32767%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(-32768); got != -1 {
+		fmt.Printf("or_int16 -1%s-32768 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(-32768); got != -1 {
+		fmt.Printf("or_int16 -32768%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 -1%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 -32767%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(0); got != -1 {
+		fmt.Printf("or_int16 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(0); got != -1 {
+		fmt.Printf("or_int16 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(1); got != -1 {
+		fmt.Printf("or_int16 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(1); got != -1 {
+		fmt.Printf("or_int16 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(32766); got != -1 {
+		fmt.Printf("or_int16 -1%s32766 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(32766); got != -1 {
+		fmt.Printf("or_int16 32766%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int16_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 -1%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_Neg1_ssa(32767); got != -1 {
+		fmt.Printf("or_int16 32767%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("or_int16 0%s-32768 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(-32768); got != -32768 {
+		fmt.Printf("or_int16 -32768%s0 = %d, wanted -32768\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 0%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32767%s0 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(0); got != 0 {
+		fmt.Printf("or_int16 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(0); got != 0 {
+		fmt.Printf("or_int16 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(1); got != 1 {
+		fmt.Printf("or_int16 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(1); got != 1 {
+		fmt.Printf("or_int16 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(32766); got != 32766 {
+		fmt.Printf("or_int16 0%s32766 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(32766); got != 32766 {
+		fmt.Printf("or_int16 32766%s0 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int16_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 0%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_0_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32767%s0 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(-32768); got != -32767 {
+		fmt.Printf("or_int16 1%s-32768 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(-32768); got != -32767 {
+		fmt.Printf("or_int16 -32768%s1 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 1%s-32767 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(-32767); got != -32767 {
+		fmt.Printf("or_int16 -32767%s1 = %d, wanted -32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(0); got != 1 {
+		fmt.Printf("or_int16 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(0); got != 1 {
+		fmt.Printf("or_int16 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(1); got != 1 {
+		fmt.Printf("or_int16 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(1); got != 1 {
+		fmt.Printf("or_int16 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(32766); got != 32767 {
+		fmt.Printf("or_int16 1%s32766 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(32766); got != 32767 {
+		fmt.Printf("or_int16 32766%s1 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int16_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 1%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_1_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32767%s1 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(-32768); got != -2 {
+		fmt.Printf("or_int16 32766%s-32768 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(-32768); got != -2 {
+		fmt.Printf("or_int16 -32768%s32766 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 32766%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 -32767%s32766 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 32766%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s32766 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(0); got != 32766 {
+		fmt.Printf("or_int16 32766%s0 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(0); got != 32766 {
+		fmt.Printf("or_int16 0%s32766 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(1); got != 32767 {
+		fmt.Printf("or_int16 32766%s1 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(1); got != 32767 {
+		fmt.Printf("or_int16 1%s32766 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(32766); got != 32766 {
+		fmt.Printf("or_int16 32766%s32766 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(32766); got != 32766 {
+		fmt.Printf("or_int16 32766%s32766 = %d, wanted 32766\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32766_int16_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32766%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32766_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32767%s32766 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(-32768); got != -1 {
+		fmt.Printf("or_int16 32767%s-32768 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(-32768); got != -1 {
+		fmt.Printf("or_int16 -32768%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 32767%s-32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(-32767); got != -1 {
+		fmt.Printf("or_int16 -32767%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 32767%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(-1); got != -1 {
+		fmt.Printf("or_int16 -1%s32767 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(0); got != 32767 {
+		fmt.Printf("or_int16 32767%s0 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(0); got != 32767 {
+		fmt.Printf("or_int16 0%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(1); got != 32767 {
+		fmt.Printf("or_int16 32767%s1 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(1); got != 32767 {
+		fmt.Printf("or_int16 1%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(32766); got != 32767 {
+		fmt.Printf("or_int16 32767%s32766 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(32766); got != 32767 {
+		fmt.Printf("or_int16 32766%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_32767_int16_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32767%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int16_32767_ssa(32767); got != 32767 {
+		fmt.Printf("or_int16 32767%s32767 = %d, wanted 32767\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(-32768); got != 0 {
+		fmt.Printf("xor_int16 -32768%s-32768 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(-32768); got != 0 {
+		fmt.Printf("xor_int16 -32768%s-32768 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(-32767); got != 1 {
+		fmt.Printf("xor_int16 -32768%s-32767 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(-32767); got != 1 {
+		fmt.Printf("xor_int16 -32767%s-32768 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(-1); got != 32767 {
+		fmt.Printf("xor_int16 -32768%s-1 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(-1); got != 32767 {
+		fmt.Printf("xor_int16 -1%s-32768 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(0); got != -32768 {
+		fmt.Printf("xor_int16 -32768%s0 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(0); got != -32768 {
+		fmt.Printf("xor_int16 0%s-32768 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(1); got != -32767 {
+		fmt.Printf("xor_int16 -32768%s1 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(1); got != -32767 {
+		fmt.Printf("xor_int16 1%s-32768 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(32766); got != -2 {
+		fmt.Printf("xor_int16 -32768%s32766 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(32766); got != -2 {
+		fmt.Printf("xor_int16 32766%s-32768 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32768_int16_ssa(32767); got != -1 {
+		fmt.Printf("xor_int16 -32768%s32767 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32768_ssa(32767); got != -1 {
+		fmt.Printf("xor_int16 32767%s-32768 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(-32768); got != 1 {
+		fmt.Printf("xor_int16 -32767%s-32768 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(-32768); got != 1 {
+		fmt.Printf("xor_int16 -32768%s-32767 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(-32767); got != 0 {
+		fmt.Printf("xor_int16 -32767%s-32767 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(-32767); got != 0 {
+		fmt.Printf("xor_int16 -32767%s-32767 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(-1); got != 32766 {
+		fmt.Printf("xor_int16 -32767%s-1 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(-1); got != 32766 {
+		fmt.Printf("xor_int16 -1%s-32767 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(0); got != -32767 {
+		fmt.Printf("xor_int16 -32767%s0 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(0); got != -32767 {
+		fmt.Printf("xor_int16 0%s-32767 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(1); got != -32768 {
+		fmt.Printf("xor_int16 -32767%s1 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(1); got != -32768 {
+		fmt.Printf("xor_int16 1%s-32767 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(32766); got != -1 {
+		fmt.Printf("xor_int16 -32767%s32766 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(32766); got != -1 {
+		fmt.Printf("xor_int16 32766%s-32767 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg32767_int16_ssa(32767); got != -2 {
+		fmt.Printf("xor_int16 -32767%s32767 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg32767_ssa(32767); got != -2 {
+		fmt.Printf("xor_int16 32767%s-32767 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(-32768); got != 32767 {
+		fmt.Printf("xor_int16 -1%s-32768 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(-32768); got != 32767 {
+		fmt.Printf("xor_int16 -32768%s-1 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(-32767); got != 32766 {
+		fmt.Printf("xor_int16 -1%s-32767 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(-32767); got != 32766 {
+		fmt.Printf("xor_int16 -32767%s-1 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(-1); got != 0 {
+		fmt.Printf("xor_int16 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(-1); got != 0 {
+		fmt.Printf("xor_int16 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(0); got != -1 {
+		fmt.Printf("xor_int16 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(0); got != -1 {
+		fmt.Printf("xor_int16 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(1); got != -2 {
+		fmt.Printf("xor_int16 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(1); got != -2 {
+		fmt.Printf("xor_int16 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(32766); got != -32767 {
+		fmt.Printf("xor_int16 -1%s32766 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(32766); got != -32767 {
+		fmt.Printf("xor_int16 32766%s-1 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int16_ssa(32767); got != -32768 {
+		fmt.Printf("xor_int16 -1%s32767 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_Neg1_ssa(32767); got != -32768 {
+		fmt.Printf("xor_int16 32767%s-1 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(-32768); got != -32768 {
+		fmt.Printf("xor_int16 0%s-32768 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(-32768); got != -32768 {
+		fmt.Printf("xor_int16 -32768%s0 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(-32767); got != -32767 {
+		fmt.Printf("xor_int16 0%s-32767 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(-32767); got != -32767 {
+		fmt.Printf("xor_int16 -32767%s0 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(-1); got != -1 {
+		fmt.Printf("xor_int16 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(-1); got != -1 {
+		fmt.Printf("xor_int16 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(0); got != 0 {
+		fmt.Printf("xor_int16 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(0); got != 0 {
+		fmt.Printf("xor_int16 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(1); got != 1 {
+		fmt.Printf("xor_int16 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(1); got != 1 {
+		fmt.Printf("xor_int16 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(32766); got != 32766 {
+		fmt.Printf("xor_int16 0%s32766 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(32766); got != 32766 {
+		fmt.Printf("xor_int16 32766%s0 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int16_ssa(32767); got != 32767 {
+		fmt.Printf("xor_int16 0%s32767 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_0_ssa(32767); got != 32767 {
+		fmt.Printf("xor_int16 32767%s0 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(-32768); got != -32767 {
+		fmt.Printf("xor_int16 1%s-32768 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(-32768); got != -32767 {
+		fmt.Printf("xor_int16 -32768%s1 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(-32767); got != -32768 {
+		fmt.Printf("xor_int16 1%s-32767 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(-32767); got != -32768 {
+		fmt.Printf("xor_int16 -32767%s1 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(-1); got != -2 {
+		fmt.Printf("xor_int16 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(-1); got != -2 {
+		fmt.Printf("xor_int16 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(0); got != 1 {
+		fmt.Printf("xor_int16 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(0); got != 1 {
+		fmt.Printf("xor_int16 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(1); got != 0 {
+		fmt.Printf("xor_int16 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(1); got != 0 {
+		fmt.Printf("xor_int16 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(32766); got != 32767 {
+		fmt.Printf("xor_int16 1%s32766 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(32766); got != 32767 {
+		fmt.Printf("xor_int16 32766%s1 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int16_ssa(32767); got != 32766 {
+		fmt.Printf("xor_int16 1%s32767 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_1_ssa(32767); got != 32766 {
+		fmt.Printf("xor_int16 32767%s1 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(-32768); got != -2 {
+		fmt.Printf("xor_int16 32766%s-32768 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(-32768); got != -2 {
+		fmt.Printf("xor_int16 -32768%s32766 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(-32767); got != -1 {
+		fmt.Printf("xor_int16 32766%s-32767 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(-32767); got != -1 {
+		fmt.Printf("xor_int16 -32767%s32766 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(-1); got != -32767 {
+		fmt.Printf("xor_int16 32766%s-1 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(-1); got != -32767 {
+		fmt.Printf("xor_int16 -1%s32766 = %d, wanted -32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(0); got != 32766 {
+		fmt.Printf("xor_int16 32766%s0 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(0); got != 32766 {
+		fmt.Printf("xor_int16 0%s32766 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(1); got != 32767 {
+		fmt.Printf("xor_int16 32766%s1 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(1); got != 32767 {
+		fmt.Printf("xor_int16 1%s32766 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(32766); got != 0 {
+		fmt.Printf("xor_int16 32766%s32766 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(32766); got != 0 {
+		fmt.Printf("xor_int16 32766%s32766 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32766_int16_ssa(32767); got != 1 {
+		fmt.Printf("xor_int16 32766%s32767 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32766_ssa(32767); got != 1 {
+		fmt.Printf("xor_int16 32767%s32766 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(-32768); got != -1 {
+		fmt.Printf("xor_int16 32767%s-32768 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(-32768); got != -1 {
+		fmt.Printf("xor_int16 -32768%s32767 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(-32767); got != -2 {
+		fmt.Printf("xor_int16 32767%s-32767 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(-32767); got != -2 {
+		fmt.Printf("xor_int16 -32767%s32767 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(-1); got != -32768 {
+		fmt.Printf("xor_int16 32767%s-1 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(-1); got != -32768 {
+		fmt.Printf("xor_int16 -1%s32767 = %d, wanted -32768\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(0); got != 32767 {
+		fmt.Printf("xor_int16 32767%s0 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(0); got != 32767 {
+		fmt.Printf("xor_int16 0%s32767 = %d, wanted 32767\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(1); got != 32766 {
+		fmt.Printf("xor_int16 32767%s1 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(1); got != 32766 {
+		fmt.Printf("xor_int16 1%s32767 = %d, wanted 32766\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(32766); got != 1 {
+		fmt.Printf("xor_int16 32767%s32766 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(32766); got != 1 {
+		fmt.Printf("xor_int16 32766%s32767 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_32767_int16_ssa(32767); got != 0 {
+		fmt.Printf("xor_int16 32767%s32767 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int16_32767_ssa(32767); got != 0 {
+		fmt.Printf("xor_int16 32767%s32767 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_0_uint8_ssa(0); got != 0 {
 		fmt.Printf("add_uint8 0%s0 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -13579,6 +21139,276 @@
 		failed = true
 	}
 
+	if got := and_0_uint8_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_0_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint8_ssa(1); got != 0 {
+		fmt.Printf("and_uint8 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_0_ssa(1); got != 0 {
+		fmt.Printf("and_uint8 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_uint8_ssa(255); got != 0 {
+		fmt.Printf("and_uint8 0%s255 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_0_ssa(255); got != 0 {
+		fmt.Printf("and_uint8 255%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint8_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_1_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint8_ssa(1); got != 1 {
+		fmt.Printf("and_uint8 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_1_ssa(1); got != 1 {
+		fmt.Printf("and_uint8 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_uint8_ssa(255); got != 1 {
+		fmt.Printf("and_uint8 1%s255 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_1_ssa(255); got != 1 {
+		fmt.Printf("and_uint8 255%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_255_uint8_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 255%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_255_ssa(0); got != 0 {
+		fmt.Printf("and_uint8 0%s255 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_255_uint8_ssa(1); got != 1 {
+		fmt.Printf("and_uint8 255%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_255_ssa(1); got != 1 {
+		fmt.Printf("and_uint8 1%s255 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_255_uint8_ssa(255); got != 255 {
+		fmt.Printf("and_uint8 255%s255 = %d, wanted 255\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_uint8_255_ssa(255); got != 255 {
+		fmt.Printf("and_uint8 255%s255 = %d, wanted 255\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_0_uint8_ssa(0); got != 0 {
+		fmt.Printf("or_uint8 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_0_ssa(0); got != 0 {
+		fmt.Printf("or_uint8 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint8_ssa(1); got != 1 {
+		fmt.Printf("or_uint8 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_0_ssa(1); got != 1 {
+		fmt.Printf("or_uint8 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_uint8_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 0%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_0_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 255%s0 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint8_ssa(0); got != 1 {
+		fmt.Printf("or_uint8 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_1_ssa(0); got != 1 {
+		fmt.Printf("or_uint8 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint8_ssa(1); got != 1 {
+		fmt.Printf("or_uint8 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_1_ssa(1); got != 1 {
+		fmt.Printf("or_uint8 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_uint8_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 1%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_1_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 255%s1 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_255_uint8_ssa(0); got != 255 {
+		fmt.Printf("or_uint8 255%s0 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_255_ssa(0); got != 255 {
+		fmt.Printf("or_uint8 0%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_255_uint8_ssa(1); got != 255 {
+		fmt.Printf("or_uint8 255%s1 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_255_ssa(1); got != 255 {
+		fmt.Printf("or_uint8 1%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_255_uint8_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 255%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_uint8_255_ssa(255); got != 255 {
+		fmt.Printf("or_uint8 255%s255 = %d, wanted 255\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint8_ssa(0); got != 0 {
+		fmt.Printf("xor_uint8 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_0_ssa(0); got != 0 {
+		fmt.Printf("xor_uint8 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint8_ssa(1); got != 1 {
+		fmt.Printf("xor_uint8 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_0_ssa(1); got != 1 {
+		fmt.Printf("xor_uint8 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_uint8_ssa(255); got != 255 {
+		fmt.Printf("xor_uint8 0%s255 = %d, wanted 255\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_0_ssa(255); got != 255 {
+		fmt.Printf("xor_uint8 255%s0 = %d, wanted 255\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint8_ssa(0); got != 1 {
+		fmt.Printf("xor_uint8 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_1_ssa(0); got != 1 {
+		fmt.Printf("xor_uint8 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint8_ssa(1); got != 0 {
+		fmt.Printf("xor_uint8 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_1_ssa(1); got != 0 {
+		fmt.Printf("xor_uint8 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_uint8_ssa(255); got != 254 {
+		fmt.Printf("xor_uint8 1%s255 = %d, wanted 254\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_1_ssa(255); got != 254 {
+		fmt.Printf("xor_uint8 255%s1 = %d, wanted 254\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_255_uint8_ssa(0); got != 255 {
+		fmt.Printf("xor_uint8 255%s0 = %d, wanted 255\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_255_ssa(0); got != 255 {
+		fmt.Printf("xor_uint8 0%s255 = %d, wanted 255\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_255_uint8_ssa(1); got != 254 {
+		fmt.Printf("xor_uint8 255%s1 = %d, wanted 254\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_255_ssa(1); got != 254 {
+		fmt.Printf("xor_uint8 1%s255 = %d, wanted 254\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_255_uint8_ssa(255); got != 0 {
+		fmt.Printf("xor_uint8 255%s255 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_uint8_255_ssa(255); got != 0 {
+		fmt.Printf("xor_uint8 255%s255 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
 	if got := add_Neg128_int8_ssa(-128); got != 0 {
 		fmt.Printf("add_int8 -128%s-128 = %d, wanted 0\n", `+`, got)
 		failed = true
@@ -15888,6 +23718,1476 @@
 		fmt.Printf("mod_int8 127%s127 = %d, wanted 0\n", `%`, got)
 		failed = true
 	}
+
+	if got := and_Neg128_int8_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -128%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -128%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(-127); got != -128 {
+		fmt.Printf("and_int8 -128%s-127 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(-127); got != -128 {
+		fmt.Printf("and_int8 -127%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(-1); got != -128 {
+		fmt.Printf("and_int8 -128%s-1 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(-1); got != -128 {
+		fmt.Printf("and_int8 -1%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 -128%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(1); got != 0 {
+		fmt.Printf("and_int8 -128%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(1); got != 0 {
+		fmt.Printf("and_int8 1%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(126); got != 0 {
+		fmt.Printf("and_int8 -128%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(126); got != 0 {
+		fmt.Printf("and_int8 126%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg128_int8_ssa(127); got != 0 {
+		fmt.Printf("and_int8 -128%s127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg128_ssa(127); got != 0 {
+		fmt.Printf("and_int8 127%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -127%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -128%s-127 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(-127); got != -127 {
+		fmt.Printf("and_int8 -127%s-127 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(-127); got != -127 {
+		fmt.Printf("and_int8 -127%s-127 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(-1); got != -127 {
+		fmt.Printf("and_int8 -127%s-1 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(-1); got != -127 {
+		fmt.Printf("and_int8 -1%s-127 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 -127%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s-127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(1); got != 1 {
+		fmt.Printf("and_int8 -127%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(1); got != 1 {
+		fmt.Printf("and_int8 1%s-127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(126); got != 0 {
+		fmt.Printf("and_int8 -127%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(126); got != 0 {
+		fmt.Printf("and_int8 126%s-127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg127_int8_ssa(127); got != 1 {
+		fmt.Printf("and_int8 -127%s127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg127_ssa(127); got != 1 {
+		fmt.Printf("and_int8 127%s-127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -1%s-128 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(-128); got != -128 {
+		fmt.Printf("and_int8 -128%s-1 = %d, wanted -128\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(-127); got != -127 {
+		fmt.Printf("and_int8 -1%s-127 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(-127); got != -127 {
+		fmt.Printf("and_int8 -127%s-1 = %d, wanted -127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(-1); got != -1 {
+		fmt.Printf("and_int8 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("and_int8 -1%s-1 = %d, wanted -1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(1); got != 1 {
+		fmt.Printf("and_int8 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(1); got != 1 {
+		fmt.Printf("and_int8 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(126); got != 126 {
+		fmt.Printf("and_int8 -1%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(126); got != 126 {
+		fmt.Printf("and_int8 126%s-1 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_Neg1_int8_ssa(127); got != 127 {
+		fmt.Printf("and_int8 -1%s127 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_Neg1_ssa(127); got != 127 {
+		fmt.Printf("and_int8 127%s-1 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 0%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 -128%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(-127); got != 0 {
+		fmt.Printf("and_int8 0%s-127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(-127); got != 0 {
+		fmt.Printf("and_int8 -127%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(-1); got != 0 {
+		fmt.Printf("and_int8 0%s-1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(-1); got != 0 {
+		fmt.Printf("and_int8 -1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(1); got != 0 {
+		fmt.Printf("and_int8 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(1); got != 0 {
+		fmt.Printf("and_int8 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(126); got != 0 {
+		fmt.Printf("and_int8 0%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(126); got != 0 {
+		fmt.Printf("and_int8 126%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_0_int8_ssa(127); got != 0 {
+		fmt.Printf("and_int8 0%s127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_0_ssa(127); got != 0 {
+		fmt.Printf("and_int8 127%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 1%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 -128%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(-127); got != 1 {
+		fmt.Printf("and_int8 1%s-127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(-127); got != 1 {
+		fmt.Printf("and_int8 -127%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(-1); got != 1 {
+		fmt.Printf("and_int8 1%s-1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(-1); got != 1 {
+		fmt.Printf("and_int8 -1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 1%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(1); got != 1 {
+		fmt.Printf("and_int8 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(1); got != 1 {
+		fmt.Printf("and_int8 1%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(126); got != 0 {
+		fmt.Printf("and_int8 1%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(126); got != 0 {
+		fmt.Printf("and_int8 126%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_1_int8_ssa(127); got != 1 {
+		fmt.Printf("and_int8 1%s127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_1_ssa(127); got != 1 {
+		fmt.Printf("and_int8 127%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 126%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 -128%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(-127); got != 0 {
+		fmt.Printf("and_int8 126%s-127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(-127); got != 0 {
+		fmt.Printf("and_int8 -127%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(-1); got != 126 {
+		fmt.Printf("and_int8 126%s-1 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(-1); got != 126 {
+		fmt.Printf("and_int8 -1%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 126%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(1); got != 0 {
+		fmt.Printf("and_int8 126%s1 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(1); got != 0 {
+		fmt.Printf("and_int8 1%s126 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(126); got != 126 {
+		fmt.Printf("and_int8 126%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(126); got != 126 {
+		fmt.Printf("and_int8 126%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_126_int8_ssa(127); got != 126 {
+		fmt.Printf("and_int8 126%s127 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_126_ssa(127); got != 126 {
+		fmt.Printf("and_int8 127%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 127%s-128 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(-128); got != 0 {
+		fmt.Printf("and_int8 -128%s127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(-127); got != 1 {
+		fmt.Printf("and_int8 127%s-127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(-127); got != 1 {
+		fmt.Printf("and_int8 -127%s127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(-1); got != 127 {
+		fmt.Printf("and_int8 127%s-1 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(-1); got != 127 {
+		fmt.Printf("and_int8 -1%s127 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(0); got != 0 {
+		fmt.Printf("and_int8 127%s0 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(0); got != 0 {
+		fmt.Printf("and_int8 0%s127 = %d, wanted 0\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(1); got != 1 {
+		fmt.Printf("and_int8 127%s1 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(1); got != 1 {
+		fmt.Printf("and_int8 1%s127 = %d, wanted 1\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(126); got != 126 {
+		fmt.Printf("and_int8 127%s126 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(126); got != 126 {
+		fmt.Printf("and_int8 126%s127 = %d, wanted 126\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_127_int8_ssa(127); got != 127 {
+		fmt.Printf("and_int8 127%s127 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := and_int8_127_ssa(127); got != 127 {
+		fmt.Printf("and_int8 127%s127 = %d, wanted 127\n", `&`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(-128); got != -128 {
+		fmt.Printf("or_int8 -128%s-128 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(-128); got != -128 {
+		fmt.Printf("or_int8 -128%s-128 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -128%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -127%s-128 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -128%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s-128 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(0); got != -128 {
+		fmt.Printf("or_int8 -128%s0 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(0); got != -128 {
+		fmt.Printf("or_int8 0%s-128 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(1); got != -127 {
+		fmt.Printf("or_int8 -128%s1 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(1); got != -127 {
+		fmt.Printf("or_int8 1%s-128 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(126); got != -2 {
+		fmt.Printf("or_int8 -128%s126 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(126); got != -2 {
+		fmt.Printf("or_int8 126%s-128 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg128_int8_ssa(127); got != -1 {
+		fmt.Printf("or_int8 -128%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg128_ssa(127); got != -1 {
+		fmt.Printf("or_int8 127%s-128 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(-128); got != -127 {
+		fmt.Printf("or_int8 -127%s-128 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(-128); got != -127 {
+		fmt.Printf("or_int8 -128%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -127%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -127%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -127%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(0); got != -127 {
+		fmt.Printf("or_int8 -127%s0 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(0); got != -127 {
+		fmt.Printf("or_int8 0%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(1); got != -127 {
+		fmt.Printf("or_int8 -127%s1 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(1); got != -127 {
+		fmt.Printf("or_int8 1%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(126); got != -1 {
+		fmt.Printf("or_int8 -127%s126 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(126); got != -1 {
+		fmt.Printf("or_int8 126%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg127_int8_ssa(127); got != -1 {
+		fmt.Printf("or_int8 -127%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg127_ssa(127); got != -1 {
+		fmt.Printf("or_int8 127%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(-128); got != -1 {
+		fmt.Printf("or_int8 -1%s-128 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(-128); got != -1 {
+		fmt.Printf("or_int8 -128%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 -1%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 -127%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(0); got != -1 {
+		fmt.Printf("or_int8 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(0); got != -1 {
+		fmt.Printf("or_int8 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(1); got != -1 {
+		fmt.Printf("or_int8 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(1); got != -1 {
+		fmt.Printf("or_int8 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(126); got != -1 {
+		fmt.Printf("or_int8 -1%s126 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(126); got != -1 {
+		fmt.Printf("or_int8 126%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_Neg1_int8_ssa(127); got != -1 {
+		fmt.Printf("or_int8 -1%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_Neg1_ssa(127); got != -1 {
+		fmt.Printf("or_int8 127%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(-128); got != -128 {
+		fmt.Printf("or_int8 0%s-128 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(-128); got != -128 {
+		fmt.Printf("or_int8 -128%s0 = %d, wanted -128\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 0%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -127%s0 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 0%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s0 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(0); got != 0 {
+		fmt.Printf("or_int8 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(0); got != 0 {
+		fmt.Printf("or_int8 0%s0 = %d, wanted 0\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(1); got != 1 {
+		fmt.Printf("or_int8 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(1); got != 1 {
+		fmt.Printf("or_int8 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(126); got != 126 {
+		fmt.Printf("or_int8 0%s126 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(126); got != 126 {
+		fmt.Printf("or_int8 126%s0 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_0_int8_ssa(127); got != 127 {
+		fmt.Printf("or_int8 0%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_0_ssa(127); got != 127 {
+		fmt.Printf("or_int8 127%s0 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(-128); got != -127 {
+		fmt.Printf("or_int8 1%s-128 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(-128); got != -127 {
+		fmt.Printf("or_int8 -128%s1 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 1%s-127 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(-127); got != -127 {
+		fmt.Printf("or_int8 -127%s1 = %d, wanted -127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 1%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(0); got != 1 {
+		fmt.Printf("or_int8 1%s0 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(0); got != 1 {
+		fmt.Printf("or_int8 0%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(1); got != 1 {
+		fmt.Printf("or_int8 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(1); got != 1 {
+		fmt.Printf("or_int8 1%s1 = %d, wanted 1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(126); got != 127 {
+		fmt.Printf("or_int8 1%s126 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(126); got != 127 {
+		fmt.Printf("or_int8 126%s1 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_1_int8_ssa(127); got != 127 {
+		fmt.Printf("or_int8 1%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_1_ssa(127); got != 127 {
+		fmt.Printf("or_int8 127%s1 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(-128); got != -2 {
+		fmt.Printf("or_int8 126%s-128 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(-128); got != -2 {
+		fmt.Printf("or_int8 -128%s126 = %d, wanted -2\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 126%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 -127%s126 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 126%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s126 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(0); got != 126 {
+		fmt.Printf("or_int8 126%s0 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(0); got != 126 {
+		fmt.Printf("or_int8 0%s126 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(1); got != 127 {
+		fmt.Printf("or_int8 126%s1 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(1); got != 127 {
+		fmt.Printf("or_int8 1%s126 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(126); got != 126 {
+		fmt.Printf("or_int8 126%s126 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(126); got != 126 {
+		fmt.Printf("or_int8 126%s126 = %d, wanted 126\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_126_int8_ssa(127); got != 127 {
+		fmt.Printf("or_int8 126%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_126_ssa(127); got != 127 {
+		fmt.Printf("or_int8 127%s126 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(-128); got != -1 {
+		fmt.Printf("or_int8 127%s-128 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(-128); got != -1 {
+		fmt.Printf("or_int8 -128%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 127%s-127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(-127); got != -1 {
+		fmt.Printf("or_int8 -127%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 127%s-1 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(-1); got != -1 {
+		fmt.Printf("or_int8 -1%s127 = %d, wanted -1\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(0); got != 127 {
+		fmt.Printf("or_int8 127%s0 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(0); got != 127 {
+		fmt.Printf("or_int8 0%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(1); got != 127 {
+		fmt.Printf("or_int8 127%s1 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(1); got != 127 {
+		fmt.Printf("or_int8 1%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(126); got != 127 {
+		fmt.Printf("or_int8 127%s126 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(126); got != 127 {
+		fmt.Printf("or_int8 126%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_127_int8_ssa(127); got != 127 {
+		fmt.Printf("or_int8 127%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := or_int8_127_ssa(127); got != 127 {
+		fmt.Printf("or_int8 127%s127 = %d, wanted 127\n", `|`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(-128); got != 0 {
+		fmt.Printf("xor_int8 -128%s-128 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(-128); got != 0 {
+		fmt.Printf("xor_int8 -128%s-128 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(-127); got != 1 {
+		fmt.Printf("xor_int8 -128%s-127 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(-127); got != 1 {
+		fmt.Printf("xor_int8 -127%s-128 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(-1); got != 127 {
+		fmt.Printf("xor_int8 -128%s-1 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(-1); got != 127 {
+		fmt.Printf("xor_int8 -1%s-128 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(0); got != -128 {
+		fmt.Printf("xor_int8 -128%s0 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(0); got != -128 {
+		fmt.Printf("xor_int8 0%s-128 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(1); got != -127 {
+		fmt.Printf("xor_int8 -128%s1 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(1); got != -127 {
+		fmt.Printf("xor_int8 1%s-128 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(126); got != -2 {
+		fmt.Printf("xor_int8 -128%s126 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(126); got != -2 {
+		fmt.Printf("xor_int8 126%s-128 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg128_int8_ssa(127); got != -1 {
+		fmt.Printf("xor_int8 -128%s127 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg128_ssa(127); got != -1 {
+		fmt.Printf("xor_int8 127%s-128 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(-128); got != 1 {
+		fmt.Printf("xor_int8 -127%s-128 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(-128); got != 1 {
+		fmt.Printf("xor_int8 -128%s-127 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(-127); got != 0 {
+		fmt.Printf("xor_int8 -127%s-127 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(-127); got != 0 {
+		fmt.Printf("xor_int8 -127%s-127 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(-1); got != 126 {
+		fmt.Printf("xor_int8 -127%s-1 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(-1); got != 126 {
+		fmt.Printf("xor_int8 -1%s-127 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(0); got != -127 {
+		fmt.Printf("xor_int8 -127%s0 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(0); got != -127 {
+		fmt.Printf("xor_int8 0%s-127 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(1); got != -128 {
+		fmt.Printf("xor_int8 -127%s1 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(1); got != -128 {
+		fmt.Printf("xor_int8 1%s-127 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(126); got != -1 {
+		fmt.Printf("xor_int8 -127%s126 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(126); got != -1 {
+		fmt.Printf("xor_int8 126%s-127 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg127_int8_ssa(127); got != -2 {
+		fmt.Printf("xor_int8 -127%s127 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg127_ssa(127); got != -2 {
+		fmt.Printf("xor_int8 127%s-127 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(-128); got != 127 {
+		fmt.Printf("xor_int8 -1%s-128 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(-128); got != 127 {
+		fmt.Printf("xor_int8 -128%s-1 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(-127); got != 126 {
+		fmt.Printf("xor_int8 -1%s-127 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(-127); got != 126 {
+		fmt.Printf("xor_int8 -127%s-1 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(-1); got != 0 {
+		fmt.Printf("xor_int8 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(-1); got != 0 {
+		fmt.Printf("xor_int8 -1%s-1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(0); got != -1 {
+		fmt.Printf("xor_int8 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(0); got != -1 {
+		fmt.Printf("xor_int8 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(1); got != -2 {
+		fmt.Printf("xor_int8 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(1); got != -2 {
+		fmt.Printf("xor_int8 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(126); got != -127 {
+		fmt.Printf("xor_int8 -1%s126 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(126); got != -127 {
+		fmt.Printf("xor_int8 126%s-1 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_Neg1_int8_ssa(127); got != -128 {
+		fmt.Printf("xor_int8 -1%s127 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_Neg1_ssa(127); got != -128 {
+		fmt.Printf("xor_int8 127%s-1 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(-128); got != -128 {
+		fmt.Printf("xor_int8 0%s-128 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(-128); got != -128 {
+		fmt.Printf("xor_int8 -128%s0 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(-127); got != -127 {
+		fmt.Printf("xor_int8 0%s-127 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(-127); got != -127 {
+		fmt.Printf("xor_int8 -127%s0 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(-1); got != -1 {
+		fmt.Printf("xor_int8 0%s-1 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(-1); got != -1 {
+		fmt.Printf("xor_int8 -1%s0 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(0); got != 0 {
+		fmt.Printf("xor_int8 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(0); got != 0 {
+		fmt.Printf("xor_int8 0%s0 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(1); got != 1 {
+		fmt.Printf("xor_int8 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(1); got != 1 {
+		fmt.Printf("xor_int8 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(126); got != 126 {
+		fmt.Printf("xor_int8 0%s126 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(126); got != 126 {
+		fmt.Printf("xor_int8 126%s0 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_0_int8_ssa(127); got != 127 {
+		fmt.Printf("xor_int8 0%s127 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_0_ssa(127); got != 127 {
+		fmt.Printf("xor_int8 127%s0 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(-128); got != -127 {
+		fmt.Printf("xor_int8 1%s-128 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(-128); got != -127 {
+		fmt.Printf("xor_int8 -128%s1 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(-127); got != -128 {
+		fmt.Printf("xor_int8 1%s-127 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(-127); got != -128 {
+		fmt.Printf("xor_int8 -127%s1 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(-1); got != -2 {
+		fmt.Printf("xor_int8 1%s-1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(-1); got != -2 {
+		fmt.Printf("xor_int8 -1%s1 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(0); got != 1 {
+		fmt.Printf("xor_int8 1%s0 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(0); got != 1 {
+		fmt.Printf("xor_int8 0%s1 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(1); got != 0 {
+		fmt.Printf("xor_int8 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(1); got != 0 {
+		fmt.Printf("xor_int8 1%s1 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(126); got != 127 {
+		fmt.Printf("xor_int8 1%s126 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(126); got != 127 {
+		fmt.Printf("xor_int8 126%s1 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_1_int8_ssa(127); got != 126 {
+		fmt.Printf("xor_int8 1%s127 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_1_ssa(127); got != 126 {
+		fmt.Printf("xor_int8 127%s1 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(-128); got != -2 {
+		fmt.Printf("xor_int8 126%s-128 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(-128); got != -2 {
+		fmt.Printf("xor_int8 -128%s126 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(-127); got != -1 {
+		fmt.Printf("xor_int8 126%s-127 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(-127); got != -1 {
+		fmt.Printf("xor_int8 -127%s126 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(-1); got != -127 {
+		fmt.Printf("xor_int8 126%s-1 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(-1); got != -127 {
+		fmt.Printf("xor_int8 -1%s126 = %d, wanted -127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(0); got != 126 {
+		fmt.Printf("xor_int8 126%s0 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(0); got != 126 {
+		fmt.Printf("xor_int8 0%s126 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(1); got != 127 {
+		fmt.Printf("xor_int8 126%s1 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(1); got != 127 {
+		fmt.Printf("xor_int8 1%s126 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(126); got != 0 {
+		fmt.Printf("xor_int8 126%s126 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(126); got != 0 {
+		fmt.Printf("xor_int8 126%s126 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_126_int8_ssa(127); got != 1 {
+		fmt.Printf("xor_int8 126%s127 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_126_ssa(127); got != 1 {
+		fmt.Printf("xor_int8 127%s126 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(-128); got != -1 {
+		fmt.Printf("xor_int8 127%s-128 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(-128); got != -1 {
+		fmt.Printf("xor_int8 -128%s127 = %d, wanted -1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(-127); got != -2 {
+		fmt.Printf("xor_int8 127%s-127 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(-127); got != -2 {
+		fmt.Printf("xor_int8 -127%s127 = %d, wanted -2\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(-1); got != -128 {
+		fmt.Printf("xor_int8 127%s-1 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(-1); got != -128 {
+		fmt.Printf("xor_int8 -1%s127 = %d, wanted -128\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(0); got != 127 {
+		fmt.Printf("xor_int8 127%s0 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(0); got != 127 {
+		fmt.Printf("xor_int8 0%s127 = %d, wanted 127\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(1); got != 126 {
+		fmt.Printf("xor_int8 127%s1 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(1); got != 126 {
+		fmt.Printf("xor_int8 1%s127 = %d, wanted 126\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(126); got != 1 {
+		fmt.Printf("xor_int8 127%s126 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(126); got != 1 {
+		fmt.Printf("xor_int8 126%s127 = %d, wanted 1\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_127_int8_ssa(127); got != 0 {
+		fmt.Printf("xor_int8 127%s127 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
+
+	if got := xor_int8_127_ssa(127); got != 0 {
+		fmt.Printf("xor_int8 127%s127 = %d, wanted 0\n", `^`, got)
+		failed = true
+	}
 	if failed {
 		panic("tests failed")
 	}
diff --git a/src/cmd/compile/internal/gc/testdata/flowgraph_generator1.go b/src/cmd/compile/internal/gc/testdata/flowgraph_generator1.go
new file mode 100644
index 0000000..48b05f7
--- /dev/null
+++ b/src/cmd/compile/internal/gc/testdata/flowgraph_generator1.go
@@ -0,0 +1,315 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"strings"
+)
+
+// make fake flow graph.
+
+// The blocks of the flow graph are designated with letters A
+// through Z, always including A (start block) and Z (exit
+// block) The specification of a flow graph is a comma-
+// separated list of block successor words, for blocks ordered
+// A, B, C etc, where each block except Z has one or two
+// successors, and any block except A can be a target. Within
+// the generated code, each block with two successors includes
+// a conditional testing x & 1 != 0 (x is the input parameter
+// to the generated function) and also unconditionally shifts x
+// right by one, so that different inputs generate different
+// execution paths, including loops. Every block inverts a
+// global binary to ensure it is not empty. For a flow graph
+// with J words (J+1 blocks), a J-1 bit serial number specifies
+// which blocks (not including A and Z) include an increment of
+// the return variable y by increasing powers of 10, and a
+// different version of the test function is created for each
+// of the 2-to-the-(J-1) serial numbers.
+
+// For each generated function a compact summary is also
+// created so that the generated funtion can be simulated
+// with a simple interpreter to sanity check the behavior of
+// the compiled code.
+
+// For example:
+
+// func BC_CD_BE_BZ_CZ101(x int64) int64 {
+// 	y := int64(0)
+// 	var b int64
+// 	_ = b
+// 	b = x & 1
+// 	x = x >> 1
+// 	if b != 0 {
+// 		goto C
+// 	}
+// 	goto B
+// B:
+// 	glob_ = !glob_
+// 	y += 1
+// 	b = x & 1
+// 	x = x >> 1
+// 	if b != 0 {
+// 		goto D
+// 	}
+// 	goto C
+// C:
+// 	glob_ = !glob_
+// 	// no y increment
+// 	b = x & 1
+// 	x = x >> 1
+// 	if b != 0 {
+// 		goto E
+// 	}
+// 	goto B
+// D:
+// 	glob_ = !glob_
+// 	y += 10
+// 	b = x & 1
+// 	x = x >> 1
+// 	if b != 0 {
+// 		goto Z
+// 	}
+// 	goto B
+// E:
+// 	glob_ = !glob_
+// 	// no y increment
+// 	b = x & 1
+// 	x = x >> 1
+// 	if b != 0 {
+// 		goto Z
+// 	}
+// 	goto C
+// Z:
+// 	return y
+// }
+
+// {f:BC_CD_BE_BZ_CZ101,
+//  maxin:32, blocks:[]blo{
+//  	blo{inc:0, cond:true, succs:[2]int64{1, 2}},
+//  	blo{inc:1, cond:true, succs:[2]int64{2, 3}},
+//  	blo{inc:0, cond:true, succs:[2]int64{1, 4}},
+//  	blo{inc:10, cond:true, succs:[2]int64{1, 25}},
+//  	blo{inc:0, cond:true, succs:[2]int64{2, 25}},}},
+
+var labels string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+func blocks(spec string) (blocks []string, fnameBase string) {
+	spec = strings.ToUpper(spec)
+	blocks = strings.Split(spec, ",")
+	fnameBase = strings.Replace(spec, ",", "_", -1)
+	return
+}
+
+func makeFunctionFromFlowGraph(blocks []blo, fname string) string {
+	s := ""
+
+	for j := range blocks {
+		// begin block
+		if j == 0 {
+			// block A, implicit label
+			s += `
+func ` + fname + `(x int64) int64 {
+	y := int64(0)
+	var b int64
+	_ = b`
+		} else {
+			// block B,C, etc, explicit label w/ conditional increment
+			l := labels[j : j+1]
+			yeq := `
+	// no y increment`
+			if blocks[j].inc != 0 {
+				yeq = `
+	y += ` + fmt.Sprintf("%d", blocks[j].inc)
+			}
+
+			s += `
+` + l + `:
+	glob = !glob` + yeq
+		}
+
+		// edges to successors
+		if blocks[j].cond { // conditionally branch to second successor
+			s += `
+	b = x & 1
+	x = x >> 1
+	if b != 0 {` + `
+		goto ` + string(labels[blocks[j].succs[1]]) + `
+	}`
+
+		}
+		// branch to first successor
+		s += `
+	goto ` + string(labels[blocks[j].succs[0]])
+	}
+
+	// end block (Z)
+	s += `
+Z:
+	return y
+}
+`
+	return s
+}
+
+var graphs []string = []string{
+	"Z", "BZ,Z", "B,BZ", "BZ,BZ",
+	"ZB,Z", "B,ZB", "ZB,BZ", "ZB,ZB",
+
+	"BC,C,Z", "BC,BC,Z", "BC,BC,BZ",
+	"BC,Z,Z", "BC,ZC,Z", "BC,ZC,BZ",
+	"BZ,C,Z", "BZ,BC,Z", "BZ,CZ,Z",
+	"BZ,C,BZ", "BZ,BC,BZ", "BZ,CZ,BZ",
+	"BZ,C,CZ", "BZ,BC,CZ", "BZ,CZ,CZ",
+
+	"BC,CD,BE,BZ,CZ",
+	"BC,BD,CE,CZ,BZ",
+	"BC,BD,CE,FZ,GZ,F,G",
+	"BC,BD,CE,FZ,GZ,G,F",
+
+	"BC,DE,BE,FZ,FZ,Z",
+	"BC,DE,BE,FZ,ZF,Z",
+	"BC,DE,BE,ZF,FZ,Z",
+	"BC,DE,EB,FZ,FZ,Z",
+	"BC,ED,BE,FZ,FZ,Z",
+	"CB,DE,BE,FZ,FZ,Z",
+
+	"CB,ED,BE,FZ,FZ,Z",
+	"BC,ED,EB,FZ,ZF,Z",
+	"CB,DE,EB,ZF,FZ,Z",
+	"CB,ED,EB,FZ,FZ,Z",
+
+	"BZ,CD,CD,CE,BZ",
+	"EC,DF,FG,ZC,GB,BE,FD",
+	"BH,CF,DG,HE,BF,CG,DH,BZ",
+}
+
+// blo describes a block in the generated/interpreted code
+type blo struct {
+	inc   int64 // increment amount
+	cond  bool  // block ends in conditional
+	succs [2]int64
+}
+
+// strings2blocks converts a slice of strings specifying
+// successors into a slice of blo encoding the blocks in a
+// common form easy to execute or interpret.
+func strings2blocks(blocks []string, fname string, i int) (bs []blo, cond uint) {
+	bs = make([]blo, len(blocks))
+	edge := int64(1)
+	cond = 0
+	k := uint(0)
+	for j, s := range blocks {
+		if j == 0 {
+		} else {
+			if (i>>k)&1 != 0 {
+				bs[j].inc = edge
+				edge *= 10
+			}
+			k++
+		}
+		if len(s) > 1 {
+			bs[j].succs[1] = int64(blocks[j][1] - 'A')
+			bs[j].cond = true
+			cond++
+		}
+		bs[j].succs[0] = int64(blocks[j][0] - 'A')
+	}
+	return bs, cond
+}
+
+// fmtBlocks writes out the blocks for consumption in the generated test
+func fmtBlocks(bs []blo) string {
+	s := "[]blo{"
+	for _, b := range bs {
+		s += fmt.Sprintf("blo{inc:%d, cond:%v, succs:[2]int64{%d, %d}},", b.inc, b.cond, b.succs[0], b.succs[1])
+	}
+	s += "}"
+	return s
+}
+
+func main() {
+	fmt.Printf(`// This is a machine-generated test file from flowgraph_generator1.go.
+package main
+import "fmt"
+var glob bool
+`)
+	s := "var funs []fun = []fun{"
+	for _, g := range graphs {
+		split, fnameBase := blocks(g)
+		nconfigs := 1 << uint(len(split)-1)
+
+		for i := 0; i < nconfigs; i++ {
+			fname := fnameBase + fmt.Sprintf("%b", i)
+			bs, k := strings2blocks(split, fname, i)
+			fmt.Printf("%s", makeFunctionFromFlowGraph(bs, fname))
+			s += `
+		{f:` + fname + `, maxin:` + fmt.Sprintf("%d", 1<<k) + `, blocks:` + fmtBlocks(bs) + `},`
+		}
+
+	}
+	s += `}
+`
+	// write types for name+array tables.
+	fmt.Printf("%s",
+		`
+type blo struct {
+	inc   int64
+	cond  bool
+	succs [2]int64
+}
+type fun struct {
+	f      func(int64) int64
+	maxin  int64
+	blocks []blo
+}
+`)
+	// write table of function names and blo arrays.
+	fmt.Printf("%s", s)
+
+	// write interpreter and main/test
+	fmt.Printf("%s", `
+func interpret(blocks []blo, x int64) (int64, bool) {
+	y := int64(0)
+	last := int64(25) // 'Z'-'A'
+	j := int64(0)
+	for i := 0; i < 4*len(blocks); i++ {
+		b := blocks[j]
+		y += b.inc
+		next := b.succs[0]
+		if b.cond {
+			c := x&1 != 0
+			x = x>>1
+			if c {
+				next = b.succs[1]
+			}
+		}
+		if next == last {
+			return y, true
+		}
+		j = next
+	}
+	return -1, false
+}
+
+func main() {
+	sum := int64(0)
+	for i, f := range funs {
+		for x := int64(0); x < 16*f.maxin; x++ {
+			y, ok := interpret(f.blocks, x)
+			if ok {
+				yy := f.f(x)
+				if y != yy {
+					fmt.Printf("y(%d) != yy(%d), x=%b, i=%d, blocks=%v\n", y, yy, x, i, f.blocks)
+					return
+				}
+				sum += y
+			}
+		}
+	}
+//	fmt.Printf("Sum of all returns over all terminating inputs is %d\n", sum)
+}
+`)
+}
diff --git a/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go b/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
index ac1c8d9..279c7bc 100644
--- a/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
+++ b/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
@@ -54,6 +54,9 @@
 	{"lsh", "<<"},
 	{"rsh", ">>"},
 	{"mod", "%"},
+	{"and", "&"},
+	{"or", "|"},
+	{"xor", "^"},
 }
 
 // compute the result of i op j, cast as type t.
@@ -78,6 +81,12 @@
 		ans = i << j
 	case ">>":
 		ans = i >> j
+	case "&":
+		ans = i & j
+	case "|":
+		ans = i | j
+	case "^":
+		ans = i ^ j
 	}
 	switch t {
 	case "uint32":
@@ -112,6 +121,12 @@
 		ans = i << uint64(j)
 	case ">>":
 		ans = i >> uint64(j)
+	case "&":
+		ans = i & j
+	case "|":
+		ans = i | j
+	case "^":
+		ans = i ^ j
 	}
 	switch t {
 	case "int32":
diff --git a/src/cmd/compile/internal/gc/testdata/gen/zeroGen.go b/src/cmd/compile/internal/gc/testdata/gen/zeroGen.go
index fa70b16..c764c36 100644
--- a/src/cmd/compile/internal/gc/testdata/gen/zeroGen.go
+++ b/src/cmd/compile/internal/gc/testdata/gen/zeroGen.go
@@ -19,6 +19,7 @@
 // will be written into the parent directory containing the tests.
 
 var sizes = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 23, 24, 25, 31, 32, 33, 63, 64, 65, 1023, 1024, 1025}
+var usizes = [...]int{8, 16, 24, 32, 64, 256}
 
 func main() {
 	w := new(bytes.Buffer)
@@ -61,12 +62,74 @@
 		fmt.Fprintf(w, "}\n")
 	}
 
+	for _, s := range usizes {
+		// type for test
+		fmt.Fprintf(w, "type T%du1 struct {\n", s)
+		fmt.Fprintf(w, "  b   bool\n")
+		fmt.Fprintf(w, "  val [%d]byte\n", s)
+		fmt.Fprintf(w, "}\n")
+
+		fmt.Fprintf(w, "type T%du2 struct {\n", s)
+		fmt.Fprintf(w, "  i   uint16\n")
+		fmt.Fprintf(w, "  val [%d]byte\n", s)
+		fmt.Fprintf(w, "}\n")
+
+		// function being tested
+		fmt.Fprintf(w, "//go:noinline\n")
+		fmt.Fprintf(w, "func zero%du1_ssa(t *T%du1) {\n", s, s)
+		fmt.Fprintf(w, "  t.val = [%d]byte{}\n", s)
+		fmt.Fprintf(w, "}\n")
+
+		// function being tested
+		fmt.Fprintf(w, "//go:noinline\n")
+		fmt.Fprintf(w, "func zero%du2_ssa(t *T%du2) {\n", s, s)
+		fmt.Fprintf(w, "  t.val = [%d]byte{}\n", s)
+		fmt.Fprintf(w, "}\n")
+
+		// testing harness
+		fmt.Fprintf(w, "func testZero%du() {\n", s)
+		fmt.Fprintf(w, "  a := T%du1{false, [%d]byte{", s, s)
+		for i := 0; i < s; i++ {
+			fmt.Fprintf(w, "255,")
+		}
+		fmt.Fprintf(w, "}}\n")
+		fmt.Fprintf(w, "  zero%du1_ssa(&a)\n", s)
+		fmt.Fprintf(w, "  want := T%du1{false, [%d]byte{", s, s)
+		for i := 0; i < s; i++ {
+			fmt.Fprintf(w, "0,")
+		}
+		fmt.Fprintf(w, "}}\n")
+		fmt.Fprintf(w, "  if a != want {\n")
+		fmt.Fprintf(w, "    fmt.Printf(\"zero%du2 got=%%v, want %%v\\n\", a, want)\n", s)
+		fmt.Fprintf(w, "    failed=true\n")
+		fmt.Fprintf(w, "  }\n")
+		fmt.Fprintf(w, "  b := T%du2{15, [%d]byte{", s, s)
+		for i := 0; i < s; i++ {
+			fmt.Fprintf(w, "255,")
+		}
+		fmt.Fprintf(w, "}}\n")
+		fmt.Fprintf(w, "  zero%du2_ssa(&b)\n", s)
+		fmt.Fprintf(w, "  wantb := T%du2{15, [%d]byte{", s, s)
+		for i := 0; i < s; i++ {
+			fmt.Fprintf(w, "0,")
+		}
+		fmt.Fprintf(w, "}}\n")
+		fmt.Fprintf(w, "  if b != wantb {\n")
+		fmt.Fprintf(w, "    fmt.Printf(\"zero%du2 got=%%v, want %%v\\n\", b, wantb)\n", s)
+		fmt.Fprintf(w, "    failed=true\n")
+		fmt.Fprintf(w, "  }\n")
+		fmt.Fprintf(w, "}\n")
+	}
+
 	// boilerplate at end
 	fmt.Fprintf(w, "var failed bool\n")
 	fmt.Fprintf(w, "func main() {\n")
 	for _, s := range sizes {
 		fmt.Fprintf(w, "  testZero%d()\n", s)
 	}
+	for _, s := range usizes {
+		fmt.Fprintf(w, "  testZero%du()\n", s)
+	}
 	fmt.Fprintf(w, "  if failed {\n")
 	fmt.Fprintf(w, "    panic(\"failed\")\n")
 	fmt.Fprintf(w, "  }\n")
diff --git a/src/cmd/compile/internal/gc/testdata/zero.go b/src/cmd/compile/internal/gc/testdata/zero.go
index f635486..9d261aa 100644
--- a/src/cmd/compile/internal/gc/testdata/zero.go
+++ b/src/cmd/compile/internal/gc/testdata/zero.go
@@ -505,6 +505,216 @@
 	}
 }
 
+type T8u1 struct {
+	b   bool
+	val [8]byte
+}
+type T8u2 struct {
+	i   uint16
+	val [8]byte
+}
+
+//go:noinline
+func zero8u1_ssa(t *T8u1) {
+	t.val = [8]byte{}
+}
+
+//go:noinline
+func zero8u2_ssa(t *T8u2) {
+	t.val = [8]byte{}
+}
+func testZero8u() {
+	a := T8u1{false, [8]byte{255, 255, 255, 255, 255, 255, 255, 255}}
+	zero8u1_ssa(&a)
+	want := T8u1{false, [8]byte{0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero8u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T8u2{15, [8]byte{255, 255, 255, 255, 255, 255, 255, 255}}
+	zero8u2_ssa(&b)
+	wantb := T8u2{15, [8]byte{0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero8u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
+type T16u1 struct {
+	b   bool
+	val [16]byte
+}
+type T16u2 struct {
+	i   uint16
+	val [16]byte
+}
+
+//go:noinline
+func zero16u1_ssa(t *T16u1) {
+	t.val = [16]byte{}
+}
+
+//go:noinline
+func zero16u2_ssa(t *T16u2) {
+	t.val = [16]byte{}
+}
+func testZero16u() {
+	a := T16u1{false, [16]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero16u1_ssa(&a)
+	want := T16u1{false, [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero16u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T16u2{15, [16]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero16u2_ssa(&b)
+	wantb := T16u2{15, [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero16u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
+type T24u1 struct {
+	b   bool
+	val [24]byte
+}
+type T24u2 struct {
+	i   uint16
+	val [24]byte
+}
+
+//go:noinline
+func zero24u1_ssa(t *T24u1) {
+	t.val = [24]byte{}
+}
+
+//go:noinline
+func zero24u2_ssa(t *T24u2) {
+	t.val = [24]byte{}
+}
+func testZero24u() {
+	a := T24u1{false, [24]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero24u1_ssa(&a)
+	want := T24u1{false, [24]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero24u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T24u2{15, [24]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero24u2_ssa(&b)
+	wantb := T24u2{15, [24]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero24u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
+type T32u1 struct {
+	b   bool
+	val [32]byte
+}
+type T32u2 struct {
+	i   uint16
+	val [32]byte
+}
+
+//go:noinline
+func zero32u1_ssa(t *T32u1) {
+	t.val = [32]byte{}
+}
+
+//go:noinline
+func zero32u2_ssa(t *T32u2) {
+	t.val = [32]byte{}
+}
+func testZero32u() {
+	a := T32u1{false, [32]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero32u1_ssa(&a)
+	want := T32u1{false, [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero32u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T32u2{15, [32]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero32u2_ssa(&b)
+	wantb := T32u2{15, [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero32u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
+type T64u1 struct {
+	b   bool
+	val [64]byte
+}
+type T64u2 struct {
+	i   uint16
+	val [64]byte
+}
+
+//go:noinline
+func zero64u1_ssa(t *T64u1) {
+	t.val = [64]byte{}
+}
+
+//go:noinline
+func zero64u2_ssa(t *T64u2) {
+	t.val = [64]byte{}
+}
+func testZero64u() {
+	a := T64u1{false, [64]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero64u1_ssa(&a)
+	want := T64u1{false, [64]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero64u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T64u2{15, [64]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero64u2_ssa(&b)
+	wantb := T64u2{15, [64]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero64u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
+type T256u1 struct {
+	b   bool
+	val [256]byte
+}
+type T256u2 struct {
+	i   uint16
+	val [256]byte
+}
+
+//go:noinline
+func zero256u1_ssa(t *T256u1) {
+	t.val = [256]byte{}
+}
+
+//go:noinline
+func zero256u2_ssa(t *T256u2) {
+	t.val = [256]byte{}
+}
+func testZero256u() {
+	a := T256u1{false, [256]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero256u1_ssa(&a)
+	want := T256u1{false, [256]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if a != want {
+		fmt.Printf("zero256u2 got=%v, want %v\n", a, want)
+		failed = true
+	}
+	b := T256u2{15, [256]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}
+	zero256u2_ssa(&b)
+	wantb := T256u2{15, [256]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	if b != wantb {
+		fmt.Printf("zero256u2 got=%v, want %v\n", b, wantb)
+		failed = true
+	}
+}
+
 var failed bool
 
 func main() {
@@ -533,6 +743,12 @@
 	testZero1023()
 	testZero1024()
 	testZero1025()
+	testZero8u()
+	testZero16u()
+	testZero24u()
+	testZero32u()
+	testZero64u()
+	testZero256u()
 	if failed {
 		panic("failed")
 	}
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 795bdcd..5285cb2 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -7,7 +7,6 @@
 import (
 	"cmd/compile/internal/types"
 	"cmd/internal/objabi"
-	"cmd/internal/src"
 	"fmt"
 	"math"
 	"strings"
@@ -244,21 +243,15 @@
 }
 
 // indexlit implements typechecking of untyped values as
-// array/slice indexes. It is equivalent to defaultlit
-// except for constants of numerical kind, which are acceptable
-// whenever they can be represented by a value of type int.
+// array/slice indexes. It is almost equivalent to defaultlit
+// but also accepts untyped numeric values representable as
+// value of type int (see also checkmake for comparison).
 // The result of indexlit MUST be assigned back to n, e.g.
 // 	n.Left = indexlit(n.Left)
 func indexlit(n *Node) *Node {
-	if n == nil || !n.Type.IsUntyped() {
-		return n
+	if n != nil && n.Type != nil && n.Type.Etype == TIDEAL {
+		return defaultlit(n, types.Types[TINT])
 	}
-	switch consttype(n) {
-	case CTINT, CTRUNE, CTFLT, CTCPLX:
-		n = defaultlit(n, types.Types[TINT])
-	}
-
-	n = defaultlit(n, nil)
 	return n
 }
 
@@ -266,7 +259,7 @@
 // 	n.Left = typecheck1(n.Left, top)
 func typecheck1(n *Node, top int) *Node {
 	switch n.Op {
-	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER:
+	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ORETJMP:
 		// n.Sym is a field/method name, not a variable.
 	default:
 		if n.Sym != nil {
@@ -285,7 +278,6 @@
 	}
 
 	ok := 0
-OpSwitch:
 	switch n.Op {
 	// until typecheck is complete, do nothing.
 	default:
@@ -300,11 +292,9 @@
 		if n.Type == nil && n.Val().Ctype() == CTSTR {
 			n.Type = types.Idealstring
 		}
-		break OpSwitch
 
 	case ONONAME:
 		ok |= Erv
-		break OpSwitch
 
 	case ONAME:
 		if n.Name.Decldepth == 0 {
@@ -312,7 +302,7 @@
 		}
 		if n.Etype != 0 {
 			ok |= Ecall
-			break OpSwitch
+			break
 		}
 
 		if top&Easgn == 0 {
@@ -327,7 +317,6 @@
 		}
 
 		ok |= Erv
-		break OpSwitch
 
 	case OPACK:
 		yyerror("use of package %v without selector", n.Sym)
@@ -424,18 +413,7 @@
 		}
 		n.Op = OTYPE
 		n.Type = types.NewMap(l.Type, r.Type)
-
-		// map key validation
-		alg, bad := algtype1(l.Type)
-		if alg == ANOEQ {
-			if bad.Etype == TFORW {
-				// queue check for map until all the types are done settling.
-				mapqueue = append(mapqueue, mapqueueval{l, n.Pos})
-			} else if bad.Etype != TANY {
-				// no need to queue, key is already bad
-				yyerror("invalid map key type %v", l.Type)
-			}
-		}
+		mapqueue = append(mapqueue, n) // check map keys when all types are settled
 		n.Left = nil
 		n.Right = nil
 
@@ -505,7 +483,7 @@
 				checkwidth(l.Type)
 			}
 			n.Left = nil
-			break OpSwitch
+			break
 		}
 
 		if !t.IsPtr() {
@@ -515,12 +493,11 @@
 				return n
 			}
 
-			break OpSwitch
+			break
 		}
 
 		ok |= Erv
 		n.Type = t.Elem()
-		break OpSwitch
 
 	// arithmetic exprs
 	case OASOP,
@@ -597,7 +574,7 @@
 			// the outer context gives the type
 			n.Type = l.Type
 
-			break OpSwitch
+			break
 		}
 
 		// ideal mixed with non-ideal
@@ -617,7 +594,7 @@
 		if et == TIDEAL {
 			et = TINT
 		}
-		var aop Op = OXXX
+		aop := OXXX
 		if iscmp[n.Op] && t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
 			// comparison is okay as long as one side is
 			// assignable to the other.  convert so they have
@@ -626,6 +603,7 @@
 			// the only conversion that isn't a no-op is concrete == interface.
 			// in that case, check comparability of the concrete type.
 			// The conversion allocates, so only do it if the concrete type is huge.
+			converted := false
 			if r.Type.Etype != TBLANK {
 				aop = assignop(l.Type, r.Type, nil)
 				if aop != 0 {
@@ -644,11 +622,11 @@
 					}
 
 					t = r.Type
-					goto converted
+					converted = true
 				}
 			}
 
-			if l.Type.Etype != TBLANK {
+			if !converted && l.Type.Etype != TBLANK {
 				aop = assignop(r.Type, l.Type, nil)
 				if aop != 0 {
 					if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) {
@@ -669,7 +647,6 @@
 				}
 			}
 
-		converted:
 			et = t.Etype
 		}
 
@@ -781,7 +758,6 @@
 		}
 
 		n.Type = t
-		break OpSwitch
 
 	case OCOM, OMINUS, ONOT, OPLUS:
 		ok |= Erv
@@ -799,7 +775,6 @@
 		}
 
 		n.Type = t
-		break OpSwitch
 
 	// exprs
 	case OADDR:
@@ -840,7 +815,6 @@
 			return n
 		}
 		n.Type = types.NewPtr(t)
-		break OpSwitch
 
 	case OCOMPLIT:
 		ok |= Erv
@@ -848,7 +822,6 @@
 		if n.Type == nil {
 			return n
 		}
-		break OpSwitch
 
 	case OXDOT, ODOT:
 		if n.Op == OXDOT {
@@ -899,7 +872,7 @@
 			n.Xoffset = 0
 			n.SetClass(PFUNC)
 			ok = Erv
-			break OpSwitch
+			break
 		}
 
 		if t.IsPtr() && !t.Elem().IsInterface() {
@@ -956,8 +929,6 @@
 			ok |= Erv
 		}
 
-		break OpSwitch
-
 	case ODOTTYPE:
 		ok |= Erv
 		n.Left = typecheck(n.Left, Erv)
@@ -1003,8 +974,6 @@
 			}
 		}
 
-		break OpSwitch
-
 	case OINDEX:
 		ok |= Erv
 		n.Left = typecheck(n.Left, Erv)
@@ -1066,8 +1035,6 @@
 			n.Op = OINDEXMAP
 		}
 
-		break OpSwitch
-
 	case ORECV:
 		ok |= Etop | Erv
 		n.Left = typecheck(n.Left, Erv)
@@ -1091,16 +1058,13 @@
 		}
 
 		n.Type = t.Elem()
-		break OpSwitch
 
 	case OSEND:
 		ok |= Etop
 		n.Left = typecheck(n.Left, Erv)
-		l := n.Left
 		n.Right = typecheck(n.Right, Erv)
 		n.Left = defaultlit(n.Left, nil)
-		l = n.Left
-		t := l.Type
+		t := n.Left.Type
 		if t == nil {
 			n.Type = nil
 			return n
@@ -1123,13 +1087,12 @@
 			n.Type = nil
 			return n
 		}
-		n.Right = assignconv(r, l.Type.Elem(), "send")
+		n.Right = assignconv(r, t.Elem(), "send")
 
 		// TODO: more aggressive
 		n.Etype = 0
 
 		n.Type = nil
-		break OpSwitch
 
 	case OSLICE, OSLICE3:
 		ok |= Erv
@@ -1204,7 +1167,6 @@
 			n.Type = nil
 			return n
 		}
-		break OpSwitch
 
 	// call and call like
 	case OCALL:
@@ -1296,11 +1258,11 @@
 
 		typecheckaste(OCALL, n.Left, n.Isddd(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
 		ok |= Etop
-		if t.Results().NumFields() == 0 {
-			break OpSwitch
+		if t.NumResults() == 0 {
+			break
 		}
 		ok |= Erv
-		if t.Results().NumFields() == 1 {
+		if t.NumResults() == 1 {
 			n.Type = l.Type.Results().Field(0).Type
 
 			if n.Op == OCALLFUNC && n.Left.Op == ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" {
@@ -1313,19 +1275,17 @@
 				n.Op = OGETG
 			}
 
-			break OpSwitch
+			break
 		}
 
 		// multiple return
 		if top&(Efnstruct|Etop) == 0 {
 			yyerror("multiple-value %v() in single-value context", l)
-			break OpSwitch
+			break
 		}
 
 		n.Type = l.Type.Results()
 
-		break OpSwitch
-
 	case OALIGNOF, OOFFSETOF, OSIZEOF:
 		ok |= Erv
 		if !onearg(n, "%v", n.Op) {
@@ -1339,8 +1299,6 @@
 		r.Orig = n
 		n = &r
 
-		break OpSwitch
-
 	case OCAP, OLEN:
 		ok |= Erv
 		if !onearg(n, "%v", n.Op) {
@@ -1391,7 +1349,6 @@
 		}
 
 		n.Type = types.Types[TINT]
-		break OpSwitch
 
 	case OREAL, OIMAG:
 		ok |= Erv
@@ -1459,7 +1416,6 @@
 			Fatalf("unexpected Etype: %v\n", et)
 		}
 		n.Type = types.Types[et]
-		break OpSwitch
 
 	case OCOMPLEX:
 		ok |= Erv
@@ -1478,8 +1434,8 @@
 				// Bail. This error will be reported elsewhere.
 				return n
 			}
-			if t.Results().NumFields() != 2 {
-				yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.Results().NumFields())
+			if t.NumResults() != 2 {
+				yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.NumResults())
 				n.Type = nil
 				return n
 			}
@@ -1541,7 +1497,6 @@
 		}
 
 		n.Type = t
-		break OpSwitch
 
 	case OCLOSE:
 		if !onearg(n, "%v", n.Op) {
@@ -1569,7 +1524,6 @@
 		}
 
 		ok |= Etop
-		break OpSwitch
 
 	case ODELETE:
 		args := n.List
@@ -1602,7 +1556,6 @@
 		}
 
 		args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
-		break OpSwitch
 
 	case OAPPEND:
 		ok |= Erv
@@ -1660,11 +1613,11 @@
 
 			if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
 				args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
-				break OpSwitch
+				break
 			}
 
 			args.SetSecond(assignconv(args.Second(), t.Orig, "append"))
-			break OpSwitch
+			break
 		}
 
 		if funarg != nil {
@@ -1684,8 +1637,6 @@
 			}
 		}
 
-		break OpSwitch
-
 	case OCOPY:
 		ok |= Etop | Erv
 		args := n.List
@@ -1721,7 +1672,7 @@
 		// copy([]byte, string)
 		if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
 			if eqtype(n.Left.Type.Elem(), types.Bytetype) {
-				break OpSwitch
+				break
 			}
 			yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
 			n.Type = nil
@@ -1746,8 +1697,6 @@
 			return n
 		}
 
-		break OpSwitch
-
 	case OCONV:
 		ok |= Erv
 		saveorignode(n)
@@ -1762,7 +1711,7 @@
 		var why string
 		n.Op = convertop(t, n.Type, &why)
 		if n.Op == 0 {
-			if !n.Diag() && !n.Type.Broke() {
+			if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() {
 				yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why)
 				n.SetDiag(true)
 			}
@@ -1799,8 +1748,6 @@
 			}
 		}
 
-		break OpSwitch
-
 	case OMAKE:
 		ok |= Erv
 		args := n.List.Slice()
@@ -1911,7 +1858,6 @@
 		}
 
 		n.Type = t
-		break OpSwitch
 
 	case ONEW:
 		ok |= Erv
@@ -1937,7 +1883,6 @@
 
 		n.Left = l
 		n.Type = types.NewPtr(t)
-		break OpSwitch
 
 	case OPRINT, OPRINTN:
 		ok |= Etop
@@ -1952,8 +1897,6 @@
 			}
 		}
 
-		break OpSwitch
-
 	case OPANIC:
 		ok |= Etop
 		if !onearg(n, "panic") {
@@ -1966,7 +1909,6 @@
 			n.Type = nil
 			return n
 		}
-		break OpSwitch
 
 	case ORECOVER:
 		ok |= Erv | Etop
@@ -1977,7 +1919,6 @@
 		}
 
 		n.Type = types.Types[TINTER]
-		break OpSwitch
 
 	case OCLOSURE:
 		ok |= Erv
@@ -1985,7 +1926,6 @@
 		if n.Type == nil {
 			return n
 		}
-		break OpSwitch
 
 	case OITAB:
 		ok |= Erv
@@ -1999,13 +1939,11 @@
 			Fatalf("OITAB of %v", t)
 		}
 		n.Type = types.NewPtr(types.Types[TUINTPTR])
-		break OpSwitch
 
 	case OIDATA:
 		// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
 		// usually by just having checked the OITAB.
 		Fatalf("cannot typecheck interface data %v", n)
-		break OpSwitch
 
 	case OSPTR:
 		ok |= Erv
@@ -2023,22 +1961,18 @@
 		} else {
 			n.Type = types.NewPtr(t.Elem())
 		}
-		break OpSwitch
 
 	case OCLOSUREVAR:
 		ok |= Erv
-		break OpSwitch
 
 	case OCFUNC:
 		ok |= Erv
 		n.Left = typecheck(n.Left, Erv)
 		n.Type = types.Types[TUINTPTR]
-		break OpSwitch
 
 	case OCONVNOP:
 		ok |= Erv
 		n.Left = typecheck(n.Left, Erv)
-		break OpSwitch
 
 	// statements
 	case OAS:
@@ -2050,23 +1984,20 @@
 		if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
 			n.Left.Name.Defn = n
 		}
-		break OpSwitch
 
 	case OAS2:
 		ok |= Etop
 		typecheckas2(n)
-		break OpSwitch
 
 	case OBREAK,
 		OCONTINUE,
 		ODCL,
 		OEMPTY,
 		OGOTO,
-		OXFALL,
+		OFALL,
 		OVARKILL,
 		OVARLIVE:
 		ok |= Etop
-		break OpSwitch
 
 	case OLABEL:
 		ok |= Etop
@@ -2078,7 +2009,6 @@
 			n.Op = OEMPTY
 			n.Left = nil
 		}
-		break OpSwitch
 
 	case ODEFER:
 		ok |= Etop
@@ -2086,13 +2016,11 @@
 		if !n.Left.Diag() {
 			checkdefergo(n)
 		}
-		break OpSwitch
 
 	case OPROC:
 		ok |= Etop
 		n.Left = typecheck(n.Left, Etop|Erv)
 		checkdefergo(n)
-		break OpSwitch
 
 	case OFOR, OFORUNTIL:
 		ok |= Etop
@@ -2108,7 +2036,6 @@
 		n.Right = typecheck(n.Right, Etop)
 		typecheckslice(n.Nbody.Slice(), Etop)
 		decldepth--
-		break OpSwitch
 
 	case OIF:
 		ok |= Etop
@@ -2122,7 +2049,6 @@
 		}
 		typecheckslice(n.Nbody.Slice(), Etop)
 		typecheckslice(n.Rlist.Slice(), Etop)
-		break OpSwitch
 
 	case ORETURN:
 		ok |= Etop
@@ -2138,29 +2064,24 @@
 		}
 
 		if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
-			break OpSwitch
+			break
 		}
 		typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
-		break OpSwitch
 
 	case ORETJMP:
 		ok |= Etop
-		break OpSwitch
 
 	case OSELECT:
 		ok |= Etop
 		typecheckselect(n)
-		break OpSwitch
 
 	case OSWITCH:
 		ok |= Etop
 		typecheckswitch(n)
-		break OpSwitch
 
 	case ORANGE:
 		ok |= Etop
 		typecheckrange(n)
-		break OpSwitch
 
 	case OTYPESW:
 		yyerror("use of .(type) outside type switch")
@@ -2171,17 +2092,14 @@
 		ok |= Etop
 		typecheckslice(n.List.Slice(), Erv)
 		typecheckslice(n.Nbody.Slice(), Etop)
-		break OpSwitch
 
 	case ODCLFUNC:
 		ok |= Etop
 		typecheckfunc(n)
-		break OpSwitch
 
 	case ODCLCONST:
 		ok |= Etop
 		n.Left = typecheck(n.Left, Erv)
-		break OpSwitch
 
 	case ODCLTYPE:
 		ok |= Etop
@@ -2193,7 +2111,6 @@
 			// could silently propagate go:notinheap).
 			yyerror("type %v must be go:notinheap", n.Left.Type)
 		}
-		break OpSwitch
 	}
 
 	t := n.Type
@@ -2208,7 +2125,7 @@
 		}
 	}
 
-	if safemode && !inimport && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
+	if safemode && !inimport && !compiling_wrappers && t != nil && t.Etype == TUNSAFEPTR {
 		yyerror("cannot use unsafe.Pointer")
 	}
 
@@ -2624,68 +2541,66 @@
 // typecheck assignment: type list = expression list
 func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, desc func() string) {
 	var t *types.Type
-	var n *Node
 	var n1 int
 	var n2 int
 	var i int
 
 	lno := lineno
+	defer func() { lineno = lno }()
 
 	if tstruct.Broke() {
-		goto out
+		return
 	}
 
-	n = nil
+	var n *Node
 	if nl.Len() == 1 {
 		n = nl.First()
-		if n.Type != nil {
-			if n.Type.IsFuncArgStruct() {
-				if !hasddd(tstruct) {
-					n1 := tstruct.NumFields()
-					n2 := n.Type.NumFields()
-					if n2 > n1 {
-						goto toomany
-					}
-					if n2 < n1 {
-						goto notenough
-					}
-				}
-
-				lfs := tstruct.FieldSlice()
-				rfs := n.Type.FieldSlice()
-				var why string
-				for i, tl := range lfs {
-					if tl.Isddd() {
-						for _, tn := range rfs[i:] {
-							if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
-								if call != nil {
-									yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
-								} else {
-									yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why)
-								}
-							}
-						}
-						goto out
-					}
-
-					if i >= len(rfs) {
-						goto notenough
-					}
-					tn := rfs[i]
-					if assignop(tn.Type, tl.Type, &why) == 0 {
-						if call != nil {
-							yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
-						} else {
-							yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
-						}
-					}
-				}
-
-				if len(rfs) > len(lfs) {
+		if n.Type != nil && n.Type.IsFuncArgStruct() {
+			if !hasddd(tstruct) {
+				n1 := tstruct.NumFields()
+				n2 := n.Type.NumFields()
+				if n2 > n1 {
 					goto toomany
 				}
-				goto out
+				if n2 < n1 {
+					goto notenough
+				}
 			}
+
+			lfs := tstruct.FieldSlice()
+			rfs := n.Type.FieldSlice()
+			var why string
+			for i, tl := range lfs {
+				if tl.Isddd() {
+					for _, tn := range rfs[i:] {
+						if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
+							if call != nil {
+								yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
+							} else {
+								yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why)
+							}
+						}
+					}
+					return
+				}
+
+				if i >= len(rfs) {
+					goto notenough
+				}
+				tn := rfs[i]
+				if assignop(tn.Type, tl.Type, &why) == 0 {
+					if call != nil {
+						yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
+					} else {
+						yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
+					}
+				}
+			}
+
+			if len(rfs) > len(lfs) {
+				goto toomany
+			}
+			return
 		}
 	}
 
@@ -2729,7 +2644,7 @@
 				if n.Type != nil {
 					nl.SetIndex(i, assignconvfn(n, t, desc))
 				}
-				goto out
+				return
 			}
 
 			for ; i < nl.Len(); i++ {
@@ -2739,8 +2654,7 @@
 					nl.SetIndex(i, assignconvfn(n, t.Elem(), desc))
 				}
 			}
-
-			goto out
+			return
 		}
 
 		if i >= nl.Len() {
@@ -2764,9 +2678,6 @@
 			yyerror("invalid use of ... in %v", op)
 		}
 	}
-
-out:
-	lineno = lno
 	return
 
 notenough:
@@ -2776,7 +2687,7 @@
 			// call is the expression being called, not the overall call.
 			// Method expressions have the form T.M, and the compiler has
 			// rewritten those to ONAME nodes but left T in Left.
-			if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
+			if call.isMethodExpression() {
 				yyerror("not enough arguments in call to method expression %v%s", call, details)
 			} else {
 				yyerror("not enough arguments in call to %v%s", call, details)
@@ -2788,8 +2699,7 @@
 			n.SetDiag(true)
 		}
 	}
-
-	goto out
+	return
 
 toomany:
 	details := errorDetails(nl, tstruct, isddd)
@@ -2798,7 +2708,6 @@
 	} else {
 		yyerror("too many arguments to %v%s", op, details)
 	}
-	goto out
 }
 
 func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
@@ -3084,7 +2993,7 @@
 		for i3, l := range n.List.Slice() {
 			setlineno(l)
 			if l.Op != OKEY {
-				n.List.SetIndex(i3, typecheck(n.List.Index(i3), Erv))
+				n.List.SetIndex(i3, typecheck(l, Erv))
 				yyerror("missing key in map literal")
 				continue
 			}
@@ -3111,7 +3020,7 @@
 		// Need valid field offsets for Xoffset below.
 		dowidth(t)
 
-		bad := 0
+		errored := false
 		if n.List.Len() != 0 && nokeys(n.List) {
 			// simple list of variables
 			ls := n.List.Slice()
@@ -3120,10 +3029,10 @@
 				n1 = typecheck(n1, Erv)
 				ls[i] = n1
 				if i >= t.NumFields() {
-					if bad == 0 {
+					if !errored {
 						yyerror("too many values in struct initializer")
+						errored = true
 					}
-					bad++
 					continue
 				}
 
@@ -3180,17 +3089,21 @@
 				}
 
 				if l.Op != OSTRUCTKEY {
-					if bad == 0 {
+					if !errored {
 						yyerror("mixture of field:value and value initializers")
+						errored = true
 					}
-					bad++
 					ls[i] = typecheck(ls[i], Erv)
 					continue
 				}
 
 				f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
 				if f == nil {
-					yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
+					if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
+						yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
+					} else {
+						yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
+					}
 					continue
 				}
 				fielddup(f.Sym.Name, hash)
@@ -3493,7 +3406,7 @@
 	}
 
 mismatch:
-	yyerror("cannot assign %d values to %d variables", cr, cl)
+	yyerror("assignment mismatch: %d variables but %d values", cl, cr)
 
 	// second half of dance
 out:
@@ -3563,16 +3476,18 @@
 	return nn
 }
 
-var ntypecheckdeftype int
+var mapqueue []*Node
 
-type mapqueueval struct {
-	n   *Node
-	lno src.XPos
+func checkMapKeys() {
+	for _, n := range mapqueue {
+		k := n.Type.MapType().Key
+		if !k.Broke() && !IsComparable(k) {
+			yyerrorl(n.Pos, "invalid map key type %v", k)
+		}
+	}
+	mapqueue = nil
 }
 
-// tracks the line numbers at which forward types are first used as map keys
-var mapqueue []mapqueueval
-
 func copytype(n *Node, t *types.Type) {
 	if t.Etype == TFORW {
 		// This type isn't computed yet; when it is, update n.
@@ -3591,7 +3506,6 @@
 
 	t = n.Type
 	t.Sym = n.Sym
-	t.SetLocal(n.Local())
 	if n.Name != nil {
 		t.Vargen = n.Name.Vargen
 	}
@@ -3633,7 +3547,6 @@
 }
 
 func typecheckdeftype(n *Node) {
-	ntypecheckdeftype++
 	lno := lineno
 	setlineno(n)
 	n.Type.Sym = n.Sym
@@ -3643,39 +3556,18 @@
 	if t == nil {
 		n.SetDiag(true)
 		n.Type = nil
-		goto ret
-	}
-
-	if n.Type == nil {
+	} else if n.Type == nil {
 		n.SetDiag(true)
-		goto ret
+	} else {
+		// copy new type and clear fields
+		// that don't come along.
+		copytype(n, t)
 	}
 
-	// copy new type and clear fields
-	// that don't come along.
-	copytype(n, t)
-
-ret:
 	lineno = lno
-
-	// if there are no type definitions going on, it's safe to
-	// try to validate the map key types for the interfaces
-	// we just read.
-	if ntypecheckdeftype == 1 {
-		for _, e := range mapqueue {
-			lineno = e.lno
-			if !IsComparable(e.n.Type) {
-				yyerror("invalid map key type %v", e.n.Type)
-			}
-		}
-		mapqueue = nil
-		lineno = lno
-	}
-
-	ntypecheckdeftype--
 }
 
-func typecheckdef(n *Node) *Node {
+func typecheckdef(n *Node) {
 	lno := lineno
 	setlineno(n)
 
@@ -3691,11 +3583,11 @@
 			yyerror("undefined: %v", n.Sym)
 		}
 
-		return n
+		return
 	}
 
 	if n.Walkdef() == 1 {
-		return n
+		return
 	}
 
 	typecheckdefstack = append(typecheckdefstack, n)
@@ -3861,7 +3753,6 @@
 
 	lineno = lno
 	n.SetWalkdef(1)
-	return n
 }
 
 func checkmake(t *types.Type, arg string, n *Node) bool {
@@ -3886,6 +3777,10 @@
 	}
 
 	// defaultlit is necessary for non-constants too: n might be 1.1<<k.
+	// TODO(gri) The length argument requirements for (array/slice) make
+	// are the same as for index expressions. Factor the code better;
+	// for instance, indexlit might be called here and incorporate some
+	// of the bounds checks done for make.
 	n = defaultlit(n, types.Types[TINT])
 
 	return true
@@ -3965,7 +3860,7 @@
 	case OBLOCK:
 		return n.List.isterminating()
 
-	case OGOTO, ORETURN, ORETJMP, OPANIC, OXFALL:
+	case OGOTO, ORETURN, ORETJMP, OPANIC, OFALL:
 		return true
 
 	case OFOR, OFORUNTIL:
@@ -3984,17 +3879,17 @@
 		if n.HasBreak() {
 			return false
 		}
-		def := 0
+		def := false
 		for _, n1 := range n.List.Slice() {
 			if !n1.Nbody.isterminating() {
 				return false
 			}
 			if n1.List.Len() == 0 { // default
-				def = 1
+				def = true
 			}
 		}
 
-		if n.Op != OSELECT && def == 0 {
+		if n.Op != OSELECT && !def {
 			return false
 		}
 		return true
@@ -4005,7 +3900,7 @@
 
 // checkreturn makes sure that fn terminates appropriately.
 func checkreturn(fn *Node) {
-	if fn.Type.Results().NumFields() != 0 && fn.Nbody.Len() != 0 {
+	if fn.Type.NumResults() != 0 && fn.Nbody.Len() != 0 {
 		markbreaklist(fn.Nbody, nil)
 		if !fn.Nbody.isterminating() {
 			yyerrorl(fn.Func.Endlineno, "missing return at end of function")
diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go
index 31a15d2..ea901db 100644
--- a/src/cmd/compile/internal/gc/universe.go
+++ b/src/cmd/compile/internal/gc/universe.go
@@ -385,10 +385,7 @@
 	s := builtinpkg.Lookup("error")
 	types.Errortype = makeErrorInterface()
 	types.Errortype.Sym = s
-	// TODO: If we can prove that it's safe to set errortype.Orig here
-	// than we don't need the special errortype/errorInterface case in
-	// bexport.go. See also issue #15920.
-	// errortype.Orig = makeErrorInterface()
+	types.Errortype.Orig = makeErrorInterface()
 	s.Def = asTypesNode(typenod(types.Errortype))
 
 	// We create separate byte and rune types for better error messages
diff --git a/src/cmd/compile/internal/gc/unsafe.go b/src/cmd/compile/internal/gc/unsafe.go
index 0ae97b4..14ab33b 100644
--- a/src/cmd/compile/internal/gc/unsafe.go
+++ b/src/cmd/compile/internal/gc/unsafe.go
@@ -12,7 +12,6 @@
 		n.Left = defaultlit(n.Left, nil)
 		tr := n.Left.Type
 		if tr == nil {
-			yyerror("invalid expression %v", n)
 			return 0
 		}
 		dowidth(tr)
@@ -35,6 +34,9 @@
 		base := n.Left.Left
 
 		n.Left = typecheck(n.Left, Erv)
+		if n.Left.Type == nil {
+			return 0
+		}
 		switch n.Left.Op {
 		case ODOT, ODOTPTR:
 			break
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 76031d1..f48513d 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -13,9 +13,7 @@
 )
 
 // The constant is known to runtime.
-const (
-	tmpstringbufsize = 32
-)
+const tmpstringbufsize = 32
 
 func walk(fn *Node) {
 	Curfn = fn
@@ -113,15 +111,12 @@
 // adds "adjust" to all the argument locations for the call n.
 // n must be a defer or go node that has already been walked.
 func adjustargs(n *Node, adjust int) {
-	var arg *Node
-	var lhs *Node
-
 	callfunc := n.Left
-	for _, arg = range callfunc.List.Slice() {
+	for _, arg := range callfunc.List.Slice() {
 		if arg.Op != OAS {
 			Fatalf("call arg not assignment")
 		}
-		lhs = arg.Left
+		lhs := arg.Left
 		if lhs.Op == ONAME {
 			// This is a temporary introduced by reorder1.
 			// The real store to the stack appears later in the arg list.
@@ -303,9 +298,8 @@
 			// so that reorder3 can fix up conflicts
 			var rl []*Node
 
-			var cl Class
 			for _, ln := range Curfn.Func.Dcl {
-				cl = ln.Class()
+				cl := ln.Class()
 				if cl == PAUTO || cl == PAUTOHEAP {
 					break
 				}
@@ -352,10 +346,6 @@
 
 	case ORANGE:
 		n = walkrange(n)
-
-	case OXFALL:
-		yyerror("fallthrough statement out of place")
-		n.Op = OFALL
 	}
 
 	if n.Op == ONAME {
@@ -647,7 +637,7 @@
 
 			// Update type of OCALLFUNC node.
 			// Output arguments had not changed, but their offsets could.
-			if n.Left.Type.Results().NumFields() == 1 {
+			if n.Left.Type.NumResults() == 1 {
 				n.Type = n.Left.Type.Results().Field(0).Type
 			} else {
 				n.Type = n.Left.Type.Results()
@@ -762,7 +752,7 @@
 		}
 		init.Append(r)
 
-		ll := ascompatet(n.Op, n.List, r.Type)
+		ll := ascompatet(n.List, r.Type)
 		n = liststmt(ll)
 
 	// x, y = <-c
@@ -998,65 +988,64 @@
 		n = walkexpr(n, init)
 
 	case OCONV, OCONVNOP:
-		if thearch.LinkArch.Family == sys.ARM || thearch.LinkArch.Family == sys.MIPS {
+		if thearch.SoftFloat {
+			// For the soft-float case, ssa.go handles these conversions.
+			goto oconv_walkexpr
+		}
+		switch thearch.LinkArch.Family {
+		case sys.ARM, sys.MIPS:
 			if n.Left.Type.IsFloat() {
-				if n.Type.Etype == TINT64 {
+				switch n.Type.Etype {
+				case TINT64:
 					n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
-					break
-				}
-
-				if n.Type.Etype == TUINT64 {
+					break opswitch
+				case TUINT64:
 					n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
-					break
+					break opswitch
 				}
 			}
 
 			if n.Type.IsFloat() {
-				if n.Left.Type.Etype == TINT64 {
+				switch n.Left.Type.Etype {
+				case TINT64:
 					n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
-					break
-				}
-
-				if n.Left.Type.Etype == TUINT64 {
+					break opswitch
+				case TUINT64:
 					n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
-					break
+					break opswitch
 				}
 			}
-		}
 
-		if thearch.LinkArch.Family == sys.I386 {
+		case sys.I386:
 			if n.Left.Type.IsFloat() {
-				if n.Type.Etype == TINT64 {
+				switch n.Type.Etype {
+				case TINT64:
 					n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
-					break
-				}
-
-				if n.Type.Etype == TUINT64 {
+					break opswitch
+				case TUINT64:
 					n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
-					break
-				}
-				if n.Type.Etype == TUINT32 || n.Type.Etype == TUINT || n.Type.Etype == TUINTPTR {
+					break opswitch
+				case TUINT32, TUINT, TUINTPTR:
 					n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
-					break
+					break opswitch
 				}
 			}
 			if n.Type.IsFloat() {
-				if n.Left.Type.Etype == TINT64 {
+				switch n.Left.Type.Etype {
+				case TINT64:
 					n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
-					break
-				}
-
-				if n.Left.Type.Etype == TUINT64 {
+					break opswitch
+				case TUINT64:
 					n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
-					break
-				}
-				if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINT || n.Left.Type.Etype == TUINTPTR {
+					break opswitch
+				case TUINT32, TUINT, TUINTPTR:
 					n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type)
-					break
+					break opswitch
 				}
 			}
 		}
 
+	oconv_walkexpr:
 		n.Left = walkexpr(n.Left, init)
 
 	case OANDNOT:
@@ -1369,18 +1358,27 @@
 			n.Left = cheapexpr(n.Left, init)
 			n.Right = cheapexpr(n.Right, init)
 
-			r = mkcall("eqstring", types.Types[TBOOL], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
+			lstr := conv(n.Left, types.Types[TSTRING])
+			rstr := conv(n.Right, types.Types[TSTRING])
+			lptr := nod(OSPTR, lstr, nil)
+			rptr := nod(OSPTR, rstr, nil)
+			llen := conv(nod(OLEN, lstr, nil), types.Types[TUINTPTR])
+			rlen := conv(nod(OLEN, rstr, nil), types.Types[TUINTPTR])
 
-			// quick check of len before full compare for == or !=
-			// eqstring assumes that the lengths are equal
+			fn := syslook("memequal")
+			fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
+			r = mkcall1(fn, types.Types[TBOOL], init, lptr, rptr, llen)
+
+			// quick check of len before full compare for == or !=.
+			// memequal then tests equality up to length len.
 			// TODO(marvin): Fix Node.EType type union.
 			if Op(n.Etype) == OEQ {
-				// len(left) == len(right) && eqstring(left, right)
-				r = nod(OANDAND, nod(OEQ, nod(OLEN, n.Left, nil), nod(OLEN, n.Right, nil)), r)
+				// len(left) == len(right) && memequal(left, right, len)
+				r = nod(OANDAND, nod(OEQ, llen, rlen), r)
 			} else {
-				// len(left) != len(right) || !eqstring(left, right)
+				// len(left) != len(right) || !memequal(left, right, len)
 				r = nod(ONOT, r, nil)
-				r = nod(OOROR, nod(ONE, nod(OLEN, n.Left, nil), nod(OLEN, n.Right, nil)), r)
+				r = nod(OOROR, nod(ONE, llen, rlen), r)
 			}
 
 			r = typecheck(r, Erv)
@@ -1417,36 +1415,120 @@
 		n = mkcall1(fn, nil, init, n.Left)
 
 	case OMAKECHAN:
-		n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]))
+		// When size fits into int, use makechan instead of
+		// makechan64, which is faster and shorter on 32 bit platforms.
+		size := n.Left
+		fnname := "makechan64"
+		argtype := types.Types[TINT64]
+
+		// Type checking guarantees that TIDEAL size is positive and fits in an int.
+		// The case of size overflow when converting TUINT or TUINTPTR to TINT
+		// will be handled by the negative range checks in makechan during runtime.
+		if size.Type.IsKind(TIDEAL) || maxintval[size.Type.Etype].Cmp(maxintval[TUINT]) <= 0 {
+			fnname = "makechan"
+			argtype = types.Types[TINT]
+		}
+
+		n = mkcall1(chanfn(fnname, 1, n.Type), n.Type, init, typename(n.Type), conv(size, argtype))
 
 	case OMAKEMAP:
 		t := n.Type
+		hmapType := hmap(t)
+		hint := n.Left
 
-		a := nodnil() // hmap buffer
-		r := nodnil() // bucket buffer
+		// var h *hmap
+		var h *Node
 		if n.Esc == EscNone {
-			// Allocate hmap buffer on stack.
-			var_ := temp(hmap(t))
+			// Allocate hmap on stack.
 
-			a = nod(OAS, var_, nil) // zero temp
-			a = typecheck(a, Etop)
-			init.Append(a)
-			a = nod(OADDR, var_, nil)
+			// var hv hmap
+			hv := temp(hmapType)
+			zero := nod(OAS, hv, nil)
+			zero = typecheck(zero, Etop)
+			init.Append(zero)
+			// h = &hv
+			h = nod(OADDR, hv, nil)
 
-			// Allocate one bucket on stack.
-			// Maximum key/value size is 128 bytes, larger objects
+			// Allocate one bucket pointed to by hmap.buckets on stack if hint
+			// is not larger than BUCKETSIZE. In case hint is larger than
+			// BUCKETSIZE runtime.makemap will allocate the buckets on the heap.
+			// Maximum key and value size is 128 bytes, larger objects
 			// are stored with an indirection. So max bucket size is 2048+eps.
-			var_ = temp(mapbucket(t))
+			if !Isconst(hint, CTINT) ||
+				!(hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) > 0) {
+				// var bv bmap
+				bv := temp(bmap(t))
 
-			r = nod(OAS, var_, nil) // zero temp
-			r = typecheck(r, Etop)
-			init.Append(r)
-			r = nod(OADDR, var_, nil)
+				zero = nod(OAS, bv, nil)
+				zero = typecheck(zero, Etop)
+				init.Append(zero)
+
+				// b = &bv
+				b := nod(OADDR, bv, nil)
+
+				// h.buckets = b
+				bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
+				na := nod(OAS, nodSym(ODOT, h, bsym), b)
+				na = typecheck(na, Etop)
+				init.Append(na)
+			}
 		}
 
-		fn := syslook("makemap")
-		fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
-		n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), a, r)
+		if Isconst(hint, CTINT) && hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
+			// Handling make(map[any]any) and
+			// make(map[any]any, hint) where hint <= BUCKETSIZE
+			// special allows for faster map initialization and
+			// improves binary size by using calls with fewer arguments.
+			// For hint <= BUCKETSIZE overLoadFactor(hint, 0) is false
+			// and no buckets will be allocated by makemap. Therefore,
+			// no buckets need to be allocated in this code path.
+			if n.Esc == EscNone {
+				// Only need to initialize h.hash0 since
+				// hmap h has been allocated on the stack already.
+				// h.hash0 = fastrand()
+				rand := mkcall("fastrand", types.Types[TUINT32], init)
+				hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap
+				a := nod(OAS, nodSym(ODOT, h, hashsym), rand)
+				a = typecheck(a, Etop)
+				a = walkexpr(a, init)
+				init.Append(a)
+				n = nod(OCONVNOP, h, nil)
+				n.Type = t
+				n = typecheck(n, Erv)
+			} else {
+				// Call runtime.makehmap to allocate an
+				// hmap on the heap and initialize hmap's hash0 field.
+				fn := syslook("makemap_small")
+				fn = substArgTypes(fn, t.Key(), t.Val())
+				n = mkcall1(fn, n.Type, init)
+			}
+		} else {
+			if n.Esc != EscNone {
+				h = nodnil()
+			}
+			// Map initialization with a variable or large hint is
+			// more complicated. We therefore generate a call to
+			// runtime.makemap to intialize hmap and allocate the
+			// map buckets.
+
+			// When hint fits into int, use makemap instead of
+			// makemap64, which is faster and shorter on 32 bit platforms.
+			fnname := "makemap64"
+			argtype := types.Types[TINT64]
+
+			// Type checking guarantees that TIDEAL hint is positive and fits in an int.
+			// See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function.
+			// The case of hint overflow when converting TUINT or TUINTPTR to TINT
+			// will be handled by the negative range checks in makemap during runtime.
+			if hint.Type.IsKind(TIDEAL) || maxintval[hint.Type.Etype].Cmp(maxintval[TUINT]) <= 0 {
+				fnname = "makemap"
+				argtype = types.Types[TINT]
+			}
+
+			fn := syslook(fnname)
+			fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
+			n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
+		}
 
 	case OMAKESLICE:
 		l := n.Left
@@ -1487,7 +1569,7 @@
 			fnname := "makeslice64"
 			argtype := types.Types[TINT64]
 
-			// typechecking guarantees that TIDEAL len/cap are positive and fit in an int.
+			// Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
 			// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
 			// will be handled by the negative range checks in makeslice during runtime.
 			if (len.Type.IsKind(TIDEAL) || maxintval[len.Type.Etype].Cmp(maxintval[TUINT]) <= 0) &&
@@ -1667,7 +1749,7 @@
 		// Emit string symbol now to avoid emitting
 		// any concurrently during the backend.
 		if s, ok := n.Val().U.(string); ok {
-			_ = stringsym(s)
+			_ = stringsym(n.Pos, s)
 		}
 	}
 
@@ -1699,7 +1781,7 @@
 	return n
 }
 
-func ascompatee1(op Op, l *Node, r *Node, init *Nodes) *Node {
+func ascompatee1(l *Node, r *Node, init *Nodes) *Node {
 	// convas will turn map assigns into function calls,
 	// making it impossible for reorder3 to work.
 	n := nod(OAS, l, r)
@@ -1713,7 +1795,7 @@
 
 func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
 	// check assign expression list to
-	// a expression list. called in
+	// an expression list. called in
 	//	expr-list = expr-list
 
 	// ensure order of evaluation for function calls
@@ -1734,7 +1816,7 @@
 		if op == ORETURN && samesafeexpr(nl[i], nr[i]) {
 			continue
 		}
-		nn = append(nn, ascompatee1(op, nl[i], nr[i], init))
+		nn = append(nn, ascompatee1(nl[i], nr[i], init))
 	}
 
 	// cannot happen: caller checked that lists had same length
@@ -1755,9 +1837,6 @@
 	if l.HasCall() || l.Op == OINDEXMAP {
 		return true
 	}
-	if needwritebarrier(l) {
-		return true
-	}
 	if eqtype(l.Type, rt) {
 		return false
 	}
@@ -1765,9 +1844,9 @@
 }
 
 // check assign type list to
-// a expression list. called in
+// an expression list. called in
 //	expr-list = func()
-func ascompatet(op Op, nl Nodes, nr *types.Type) []*Node {
+func ascompatet(nl Nodes, nr *types.Type) []*Node {
 	if nl.Len() != nr.NumFields() {
 		Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
 	}
@@ -1949,8 +2028,6 @@
 //	return expr-list
 //	func(expr-list)
 func ascompatte(call *Node, isddd bool, lhs *types.Type, rhs []*Node, fp int, init *Nodes) []*Node {
-	var nn []*Node
-
 	// f(g()) where g has multiple return values
 	if len(rhs) == 1 && rhs[0].Type.IsFuncArgStruct() {
 		// optimization - can do block copy
@@ -1958,8 +2035,9 @@
 			nl := nodarg(lhs, fp)
 			nr := nod(OCONVNOP, rhs[0], nil)
 			nr.Type = nl.Type
-			nn = []*Node{convas(nod(OAS, nl, nr), init)}
-			goto ret
+			n := convas(nod(OAS, nl, nr), init)
+			n.SetTypecheck(1)
+			return []*Node{n}
 		}
 
 		// conversions involved.
@@ -1983,6 +2061,7 @@
 	// If there's a ... parameter (which is only valid as the final
 	// parameter) and this is not a ... call expression,
 	// then assign the remaining arguments as a slice.
+	var nn []*Node
 	for i, nl := range lhs.FieldSlice() {
 		var nr *Node
 		if nl.Isddd() && !isddd {
@@ -1993,41 +2072,53 @@
 
 		a := nod(OAS, nodarg(nl, fp), nr)
 		a = convas(a, init)
+		a.SetTypecheck(1)
 		nn = append(nn, a)
 	}
 
-ret:
-	for _, n := range nn {
-		n.SetTypecheck(1)
-	}
 	return nn
 }
 
 // generate code for print
 func walkprint(nn *Node, init *Nodes) *Node {
-	var r *Node
-	var n *Node
-	var on *Node
-	var t *types.Type
-	var et types.EType
-
-	op := nn.Op
-	all := nn.List
-	var calls []*Node
-	notfirst := false
-
 	// Hoist all the argument evaluation up before the lock.
-	walkexprlistcheap(all.Slice(), init)
+	walkexprlistcheap(nn.List.Slice(), init)
 
-	calls = append(calls, mkcall("printlock", nil, init))
-	for i1, n1 := range all.Slice() {
-		if notfirst {
-			calls = append(calls, mkcall("printsp", nil, init))
+	// For println, add " " between elements and "\n" at the end.
+	if nn.Op == OPRINTN {
+		s := nn.List.Slice()
+		t := make([]*Node, 0, len(s)*2)
+		for i, n := range s {
+			if i != 0 {
+				t = append(t, nodstr(" "))
+			}
+			t = append(t, n)
 		}
+		t = append(t, nodstr("\n"))
+		nn.List.Set(t)
+	}
 
-		notfirst = op == OPRINTN
+	// Collapse runs of constant strings.
+	s := nn.List.Slice()
+	t := make([]*Node, 0, len(s))
+	for i := 0; i < len(s); {
+		var strs []string
+		for i < len(s) && Isconst(s[i], CTSTR) {
+			strs = append(strs, s[i].Val().U.(string))
+			i++
+		}
+		if len(strs) > 0 {
+			t = append(t, nodstr(strings.Join(strs, "")))
+		}
+		if i < len(s) {
+			t = append(t, s[i])
+			i++
+		}
+	}
+	nn.List.Set(t)
 
-		n = n1
+	calls := []*Node{mkcall("printlock", nil, init)}
+	for i, n := range nn.List.Slice() {
 		if n.Op == OLITERAL {
 			switch n.Val().Ctype() {
 			case CTRUNE:
@@ -2045,71 +2136,76 @@
 			n = defaultlit(n, types.Types[TINT64])
 		}
 		n = defaultlit(n, nil)
-		all.SetIndex(i1, n)
+		nn.List.SetIndex(i, n)
 		if n.Type == nil || n.Type.Etype == TFORW {
 			continue
 		}
 
-		t = n.Type
-		et = n.Type.Etype
-		if n.Type.IsInterface() {
+		var on *Node
+		switch n.Type.Etype {
+		case TINTER:
 			if n.Type.IsEmptyInterface() {
 				on = syslook("printeface")
 			} else {
 				on = syslook("printiface")
 			}
 			on = substArgTypes(on, n.Type) // any-1
-		} else if n.Type.IsPtr() || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
+		case TPTR32, TPTR64, TCHAN, TMAP, TFUNC, TUNSAFEPTR:
 			on = syslook("printpointer")
 			on = substArgTypes(on, n.Type) // any-1
-		} else if n.Type.IsSlice() {
+		case TSLICE:
 			on = syslook("printslice")
 			on = substArgTypes(on, n.Type) // any-1
-		} else if isInt[et] {
-			if et == TUINT64 {
-				if isRuntimePkg(t.Sym.Pkg) && t.Sym.Name == "hex" {
-					on = syslook("printhex")
-				} else {
-					on = syslook("printuint")
-				}
+		case TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
+			if isRuntimePkg(n.Type.Sym.Pkg) && n.Type.Sym.Name == "hex" {
+				on = syslook("printhex")
 			} else {
-				on = syslook("printint")
+				on = syslook("printuint")
 			}
-		} else if isFloat[et] {
+		case TINT, TINT8, TINT16, TINT32, TINT64:
+			on = syslook("printint")
+		case TFLOAT32, TFLOAT64:
 			on = syslook("printfloat")
-		} else if isComplex[et] {
+		case TCOMPLEX64, TCOMPLEX128:
 			on = syslook("printcomplex")
-		} else if et == TBOOL {
+		case TBOOL:
 			on = syslook("printbool")
-		} else if et == TSTRING {
-			on = syslook("printstring")
-		} else {
+		case TSTRING:
+			cs := ""
+			if Isconst(n, CTSTR) {
+				cs = n.Val().U.(string)
+			}
+			switch cs {
+			case " ":
+				on = syslook("printsp")
+			case "\n":
+				on = syslook("printnl")
+			default:
+				on = syslook("printstring")
+			}
+		default:
 			badtype(OPRINT, n.Type, nil)
 			continue
 		}
 
-		t = on.Type.Params().Field(0).Type
-
-		if !eqtype(t, n.Type) {
-			n = nod(OCONV, n, nil)
-			n.Type = t
+		r := nod(OCALL, on, nil)
+		if params := on.Type.Params().FieldSlice(); len(params) > 0 {
+			t := params[0].Type
+			if !eqtype(t, n.Type) {
+				n = nod(OCONV, n, nil)
+				n.Type = t
+			}
+			r.List.Append(n)
 		}
-
-		r = nod(OCALL, on, nil)
-		r.List.Append(n)
 		calls = append(calls, r)
 	}
 
-	if op == OPRINTN {
-		calls = append(calls, mkcall("printnl", nil, nil))
-	}
-
 	calls = append(calls, mkcall("printunlock", nil, init))
 
 	typecheckslice(calls, Etop)
 	walkexprlist(calls, init)
 
-	r = nod(OEMPTY, nil, nil)
+	r := nod(OEMPTY, nil, nil)
 	r = typecheck(r, Etop)
 	r = walkexpr(r, init)
 	r.Ninit.Set(calls)
@@ -2129,36 +2225,13 @@
 }
 
 func iscallret(n *Node) bool {
+	if n == nil {
+		return false
+	}
 	n = outervalue(n)
 	return n.Op == OINDREGSP
 }
 
-func isstack(n *Node) bool {
-	n = outervalue(n)
-
-	// If n is *autotmp and autotmp = &foo, replace n with foo.
-	// We introduce such temps when initializing struct literals.
-	if n.Op == OIND && n.Left.Op == ONAME && n.Left.IsAutoTmp() {
-		defn := n.Left.Name.Defn
-		if defn != nil && defn.Op == OAS && defn.Right.Op == OADDR {
-			n = defn.Right.Left
-		}
-	}
-
-	switch n.Op {
-	case OINDREGSP:
-		return true
-
-	case ONAME:
-		switch n.Class() {
-		case PAUTO, PPARAM, PPARAMOUT:
-			return true
-		}
-	}
-
-	return false
-}
-
 // isReflectHeaderDataField reports whether l is an expression p.Data
 // where p has type reflect.SliceHeader or reflect.StringHeader.
 func isReflectHeaderDataField(l *Node) bool {
@@ -2182,74 +2255,27 @@
 	return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
 }
 
-// Do we need a write barrier for assigning to l?
-func needwritebarrier(l *Node) bool {
-	if !use_writebarrier {
-		return false
-	}
-
-	if l == nil || isblank(l) {
-		return false
-	}
-
-	// No write barrier for write to stack.
-	if isstack(l) {
-		return false
-	}
-
-	// Package unsafe's documentation says storing pointers into
-	// reflect.SliceHeader and reflect.StringHeader's Data fields
-	// is valid, even though they have type uintptr (#19168).
-	if isReflectHeaderDataField(l) {
-		return true
-	}
-
-	// No write barrier for write of non-pointers.
-	dowidth(l.Type)
-	if !types.Haspointers(l.Type) {
-		return false
-	}
-
-	// No write barrier if this is a pointer to a go:notinheap
-	// type, since the write barrier's inheap(ptr) check will fail.
-	if l.Type.IsPtr() && l.Type.Elem().NotInHeap() {
-		return false
-	}
-
-	// TODO: We can eliminate write barriers if we know *both* the
-	// current and new content of the slot must already be shaded.
-	// We know a pointer is shaded if it's nil, or points to
-	// static data, a global (variable or function), or the stack.
-	// The nil optimization could be particularly useful for
-	// writes to just-allocated objects. Unfortunately, knowing
-	// the "current" value of the slot requires flow analysis.
-
-	// Otherwise, be conservative and use write barrier.
-	return true
-}
-
 func convas(n *Node, init *Nodes) *Node {
 	if n.Op != OAS {
 		Fatalf("convas: not OAS %v", n.Op)
 	}
+	defer updateHasCall(n)
 
 	n.SetTypecheck(1)
 
-	var lt *types.Type
-	var rt *types.Type
 	if n.Left == nil || n.Right == nil {
-		goto out
+		return n
 	}
 
-	lt = n.Left.Type
-	rt = n.Right.Type
+	lt := n.Left.Type
+	rt := n.Right.Type
 	if lt == nil || rt == nil {
-		goto out
+		return n
 	}
 
 	if isblank(n.Left) {
 		n.Right = defaultlit(n.Right, nil)
-		goto out
+		return n
 	}
 
 	if !eqtype(lt, rt) {
@@ -2258,8 +2284,6 @@
 	}
 	dowidth(n.Right.Type)
 
-out:
-	updateHasCall(n)
 	return n
 }
 
@@ -2270,18 +2294,18 @@
 // then it is done first. otherwise must
 // make temp variables
 func reorder1(all []*Node) []*Node {
-	c := 0 // function calls
-	t := 0 // total parameters
-
-	for _, n := range all {
-		t++
-		updateHasCall(n)
-		if n.HasCall() {
-			c++
-		}
+	if len(all) == 1 {
+		return all
 	}
 
-	if c == 0 || t == 1 {
+	funcCalls := 0
+	for _, n := range all {
+		updateHasCall(n)
+		if n.HasCall() {
+			funcCalls++
+		}
+	}
+	if funcCalls == 0 {
 		return all
 	}
 
@@ -2289,7 +2313,6 @@
 	var f *Node   // last fncall assigned to stack
 	var r []*Node // non fncalls and tempnames assigned to stack
 	d := 0
-	var a *Node
 	for _, n := range all {
 		if !n.HasCall() {
 			r = append(r, n)
@@ -2297,13 +2320,13 @@
 		}
 
 		d++
-		if d == c {
+		if d == funcCalls {
 			f = n
 			continue
 		}
 
 		// make assignment of fncall to tempname
-		a = temp(n.Right.Type)
+		a := temp(n.Right.Type)
 
 		a = nod(OAS, a, n.Right)
 		g = append(g, a)
@@ -2328,8 +2351,6 @@
 //
 // function calls have been removed.
 func reorder3(all []*Node) []*Node {
-	var l *Node
-
 	// If a needed expression may be affected by an
 	// earlier assignment, make an early copy of that
 	// expression and use the copy instead.
@@ -2337,7 +2358,7 @@
 
 	var mapinit Nodes
 	for i, n := range all {
-		l = n.Left
+		l := n.Left
 
 		// Save subexpressions needed on left side.
 		// Drill through non-dereferences.
@@ -2404,23 +2425,21 @@
 // outer value means containing struct or array.
 func outervalue(n *Node) *Node {
 	for {
-		if n.Op == OXDOT {
+		switch n.Op {
+		case OXDOT:
 			Fatalf("OXDOT in walk")
-		}
-		if n.Op == ODOT || n.Op == OPAREN || n.Op == OCONVNOP {
+		case ODOT, OPAREN, OCONVNOP:
 			n = n.Left
 			continue
+		case OINDEX:
+			if n.Left.Type != nil && n.Left.Type.IsArray() {
+				n = n.Left
+				continue
+			}
 		}
 
-		if n.Op == OINDEX && n.Left.Type != nil && n.Left.Type.IsArray() {
-			n = n.Left
-			continue
-		}
-
-		break
+		return n
 	}
-
-	return n
 }
 
 // Is it possible that the computation of n might be
@@ -2441,30 +2460,28 @@
 	// Also record whether there are any writes to main memory.
 	// Also record whether there are any writes to variables
 	// whose addresses have been taken.
-	memwrite := 0
-
-	varwrite := 0
-	var a *Node
+	memwrite := false
+	varwrite := false
 	for _, an := range all[:i] {
-		a = outervalue(an.Left)
+		a := outervalue(an.Left)
 
 		for a.Op == ODOT {
 			a = a.Left
 		}
 
 		if a.Op != ONAME {
-			memwrite = 1
+			memwrite = true
 			continue
 		}
 
 		switch n.Class() {
 		default:
-			varwrite = 1
+			varwrite = true
 			continue
 
 		case PAUTO, PPARAM, PPARAMOUT:
 			if n.Addrtaken() {
-				varwrite = 1
+				varwrite = true
 				continue
 			}
 
@@ -2480,7 +2497,7 @@
 	// that are being written.
 
 	// If no computed addresses are affected by the writes, no aliasing.
-	if memwrite == 0 && varwrite == 0 {
+	if !memwrite && !varwrite {
 		return false
 	}
 
@@ -2703,11 +2720,14 @@
 		Fatalf("mkcall %v %v", fn, fn.Type)
 	}
 
-	n := fn.Type.Params().NumFields()
+	n := fn.Type.NumParams()
+	if n != len(va) {
+		Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
+	}
 
 	r := nod(OCALL, fn, nil)
-	r.List.Set(va[:n])
-	if fn.Type.Results().NumFields() > 0 {
+	r.List.Set(va)
+	if fn.Type.NumResults() > 0 {
 		r = typecheck(r, Erv|Efnstruct)
 	} else {
 		r = typecheck(r, Etop)
@@ -2785,21 +2805,23 @@
 const (
 	mapslow = iota
 	mapfast32
+	mapfast32ptr
 	mapfast64
+	mapfast64ptr
 	mapfaststr
 	nmapfast
 )
 
 type mapnames [nmapfast]string
 
-func mkmapnames(base string) mapnames {
-	return mapnames{base, base + "_fast32", base + "_fast64", base + "_faststr"}
+func mkmapnames(base string, ptr string) mapnames {
+	return mapnames{base, base + "_fast32", base + "_fast32" + ptr, base + "_fast64", base + "_fast64" + ptr, base + "_faststr"}
 }
 
-var mapaccess1 mapnames = mkmapnames("mapaccess1")
-var mapaccess2 mapnames = mkmapnames("mapaccess2")
-var mapassign mapnames = mkmapnames("mapassign")
-var mapdelete mapnames = mkmapnames("mapdelete")
+var mapaccess1 = mkmapnames("mapaccess1", "")
+var mapaccess2 = mkmapnames("mapaccess2", "")
+var mapassign = mkmapnames("mapassign", "ptr")
+var mapdelete = mkmapnames("mapdelete", "")
 
 func mapfast(t *types.Type) int {
 	// Check ../../runtime/hashmap.go:maxValueSize before changing.
@@ -2808,9 +2830,22 @@
 	}
 	switch algtype(t.Key()) {
 	case AMEM32:
-		return mapfast32
+		if !t.Key().HasHeapPointer() {
+			return mapfast32
+		}
+		if Widthptr == 4 {
+			return mapfast32ptr
+		}
+		Fatalf("small pointer %v", t.Key())
 	case AMEM64:
-		return mapfast64
+		if !t.Key().HasHeapPointer() {
+			return mapfast64
+		}
+		if Widthptr == 8 {
+			return mapfast64ptr
+		}
+		// Two-word object, at least one of which is a pointer.
+		// Use the slow path.
 	case ASTRING:
 		return mapfaststr
 	}
@@ -2942,12 +2977,13 @@
 	nt.Etype = 1
 	l = append(l, nod(OAS, s, nt))
 
-	if types.Haspointers(l1.Type.Elem()) {
+	if l1.Type.Elem().HasHeapPointer() {
 		// copy(s[len(l1):], l2)
 		nptr1 := nod(OSLICE, s, nil)
 		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
 		nptr1.Etype = 1
 		nptr2 := l2
+		Curfn.Func.setWBPos(n.Pos)
 		fn := syslook("typedslicecopy")
 		fn = substArgTypes(fn, l1.Type, l2.Type)
 		var ln Nodes
@@ -2961,16 +2997,20 @@
 		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
 		nptr1.Etype = 1
 		nptr2 := l2
-		var fn *Node
-		if l2.Type.IsString() {
-			fn = syslook("slicestringcopy")
-		} else {
-			fn = syslook("slicecopy")
-		}
-		fn = substArgTypes(fn, l1.Type, l2.Type)
+
 		var ln Nodes
 		ln.Set(l)
-		nt := mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
+		var nt *Node
+		if l2.Type.IsString() {
+			fn := syslook("slicestringcopy")
+			fn = substArgTypes(fn, l1.Type, l2.Type)
+			nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2)
+		} else {
+			fn := syslook("slicecopy")
+			fn = substArgTypes(fn, l1.Type, l2.Type)
+			nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
+		}
+
 		l = append(ln.Slice(), nt)
 	} else {
 		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
@@ -3105,18 +3145,20 @@
 // Also works if b is a string.
 //
 func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
-	if types.Haspointers(n.Left.Type.Elem()) {
+	if n.Left.Type.Elem().HasHeapPointer() {
+		Curfn.Func.setWBPos(n.Pos)
 		fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
 		return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), n.Left, n.Right)
 	}
 
 	if runtimecall {
-		var fn *Node
 		if n.Right.Type.IsString() {
-			fn = syslook("slicestringcopy")
-		} else {
-			fn = syslook("slicecopy")
+			fn := syslook("slicestringcopy")
+			fn = substArgTypes(fn, n.Left.Type, n.Right.Type)
+			return mkcall1(fn, n.Type, init, n.Left, n.Right)
 		}
+
+		fn := syslook("slicecopy")
 		fn = substArgTypes(fn, n.Left.Type, n.Right.Type)
 		return mkcall1(fn, n.Type, init, n.Left, n.Right, nodintconst(n.Left.Type.Elem().Width))
 	}
@@ -3159,7 +3201,7 @@
 	return nlen
 }
 
-func eqfor(t *types.Type, needsize *int) *Node {
+func eqfor(t *types.Type) (n *Node, needsize bool) {
 	// Should only arrive here with large memory or
 	// a struct/array containing a non-memory field/element.
 	// Small memory is handled inline, and single non-memory
@@ -3168,8 +3210,7 @@
 	case AMEM:
 		n := syslook("memequal")
 		n = substArgTypes(n, t, t)
-		*needsize = 1
-		return n
+		return n, true
 	case ASPECIAL:
 		sym := typesymprefix(".eq", t)
 		n := newname(sym)
@@ -3180,11 +3221,10 @@
 		ntype.Rlist.Append(anonfield(types.Types[TBOOL]))
 		ntype = typecheck(ntype, Etype)
 		n.Type = ntype.Type
-		*needsize = 0
-		return n
+		return n, false
 	}
 	Fatalf("eqfor %v", t)
-	return nil
+	return nil, false
 }
 
 // The result of walkcompare MUST be assigned back to n, e.g.
@@ -3304,11 +3344,11 @@
 		ar = typecheck(ar, Etop)
 		init.Append(ar)
 
-		var needsize int
-		call := nod(OCALL, eqfor(t, &needsize), nil)
+		fn, needsize := eqfor(t)
+		call := nod(OCALL, fn, nil)
 		call.List.Append(pl)
 		call.List.Append(pr)
-		if needsize != 0 {
+		if needsize {
 			call.List.Append(nodintconst(t.Width))
 		}
 		res := call
@@ -3375,18 +3415,23 @@
 				i++
 				remains -= t.Elem().Width
 			} else {
+				elemType := t.Elem().ToUnsigned()
 				cmplw := nod(OINDEX, cmpl, nodintconst(int64(i)))
-				cmplw = conv(cmplw, convType)
+				cmplw = conv(cmplw, elemType) // convert to unsigned
+				cmplw = conv(cmplw, convType) // widen
 				cmprw := nod(OINDEX, cmpr, nodintconst(int64(i)))
+				cmprw = conv(cmprw, elemType)
 				cmprw = conv(cmprw, convType)
 				// For code like this:  uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
 				// ssa will generate a single large load.
 				for offset := int64(1); offset < step; offset++ {
 					lb := nod(OINDEX, cmpl, nodintconst(int64(i+offset)))
+					lb = conv(lb, elemType)
 					lb = conv(lb, convType)
 					lb = nod(OLSH, lb, nodintconst(int64(8*t.Elem().Width*offset)))
 					cmplw = nod(OOR, cmplw, lb)
 					rb := nod(OINDEX, cmpr, nodintconst(int64(i+offset)))
+					rb = conv(rb, elemType)
 					rb = conv(rb, convType)
 					rb = nod(OLSH, rb, nodintconst(int64(8*t.Elem().Width*offset)))
 					cmprw = nod(OOR, cmprw, rb)
@@ -3623,16 +3668,16 @@
 	//
 	// TODO(crawshaw): improve precision of match by working out
 	//                 how to check the method name.
-	if n := t.Params().NumFields(); n != 1 {
+	if n := t.NumParams(); n != 1 {
 		return
 	}
-	if n := t.Results().NumFields(); n != 1 && n != 2 {
+	if n := t.NumResults(); n != 1 && n != 2 {
 		return
 	}
 	p0 := t.Params().Field(0)
 	res0 := t.Results().Field(0)
 	var res1 *types.Field
-	if t.Results().NumFields() == 2 {
+	if t.NumResults() == 2 {
 		res1 = t.Results().Field(1)
 	}
 
@@ -3827,14 +3872,10 @@
 	}
 
 	t := nod(OTFUNC, nil, nil)
-	num := 0
 	var printargs []*Node
-	var a *Node
-	var buf string
-	for _, n1 := range n.List.Slice() {
-		buf = fmt.Sprintf("a%d", num)
-		num++
-		a = namedfield(buf, n1.Type)
+	for i, n1 := range n.List.Slice() {
+		buf := fmt.Sprintf("a%d", i)
+		a := namedfield(buf, n1.Type)
 		t.List.Append(a)
 		printargs = append(printargs, a.Left)
 	}
@@ -3846,14 +3887,14 @@
 	sym := lookupN("print·%d", walkprintfunc_prgen)
 	fn := dclfunc(sym, t)
 
-	a = nod(n.Op, nil, nil)
+	a := nod(n.Op, nil, nil)
 	a.List.Set(printargs)
 	a = typecheck(a, Etop)
 	a = walkstmt(a)
 
 	fn.Nbody.Set1(a)
 
-	funcbody(fn)
+	funcbody()
 
 	fn = typecheck(fn, Etop)
 	typecheckslice(fn.Nbody.Slice(), Etop)
diff --git a/src/cmd/compile/internal/mips/galign.go b/src/cmd/compile/internal/mips/galign.go
index 77ec78a..f207a17 100644
--- a/src/cmd/compile/internal/mips/galign.go
+++ b/src/cmd/compile/internal/mips/galign.go
@@ -18,6 +18,7 @@
 	}
 	arch.REGSP = mips.REGSP
 	arch.MAXWIDTH = (1 << 31) - 1
+	arch.SoftFloat = (objabi.GOMIPS == "softfloat")
 	arch.ZeroRange = zerorange
 	arch.ZeroAuto = zeroAuto
 	arch.Ginsnop = ginsnop
diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go
index e65515a..ee68afd 100644
--- a/src/cmd/compile/internal/mips/ssa.go
+++ b/src/cmd/compile/internal/mips/ssa.go
@@ -283,10 +283,10 @@
 		switch v.Aux.(type) {
 		default:
 			v.Fatalf("aux is of unknown type %T", v.Aux)
-		case *ssa.ExternSymbol:
+		case *obj.LSym:
 			wantreg = "SB"
 			gc.AddAux(&p.From, v)
-		case *ssa.ArgSymbol, *ssa.AutoSymbol:
+		case *gc.Node:
 			wantreg = "SP"
 			gc.AddAux(&p.From, v)
 		case nil:
@@ -755,6 +755,14 @@
 	case ssa.OpMIPSLoweredGetClosurePtr:
 		// Closure pointer is R22 (mips.REGCTXT).
 		gc.CheckLoweredGetClosurePtr(v)
+	case ssa.OpMIPSLoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(mips.AMOVW)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpClobber:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go
index db163f3..291a162 100644
--- a/src/cmd/compile/internal/mips64/ssa.go
+++ b/src/cmd/compile/internal/mips64/ssa.go
@@ -257,10 +257,10 @@
 		switch v.Aux.(type) {
 		default:
 			v.Fatalf("aux is of unknown type %T", v.Aux)
-		case *ssa.ExternSymbol:
+		case *obj.LSym:
 			wantreg = "SB"
 			gc.AddAux(&p.From, v)
-		case *ssa.ArgSymbol, *ssa.AutoSymbol:
+		case *gc.Node:
 			wantreg = "SP"
 			gc.AddAux(&p.From, v)
 		case nil:
@@ -483,6 +483,211 @@
 		gc.Patch(p6, p2)
 	case ssa.OpMIPS64CALLstatic, ssa.OpMIPS64CALLclosure, ssa.OpMIPS64CALLinter:
 		s.Call(v)
+	case ssa.OpMIPS64LoweredAtomicLoad32, ssa.OpMIPS64LoweredAtomicLoad64:
+		as := mips.AMOVV
+		if v.Op == ssa.OpMIPS64LoweredAtomicLoad32 {
+			as = mips.AMOVW
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(as)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg0()
+		s.Prog(mips.ASYNC)
+	case ssa.OpMIPS64LoweredAtomicStore32, ssa.OpMIPS64LoweredAtomicStore64:
+		as := mips.AMOVV
+		if v.Op == ssa.OpMIPS64LoweredAtomicStore32 {
+			as = mips.AMOVW
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(as)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[1].Reg()
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		s.Prog(mips.ASYNC)
+	case ssa.OpMIPS64LoweredAtomicStorezero32, ssa.OpMIPS64LoweredAtomicStorezero64:
+		as := mips.AMOVV
+		if v.Op == ssa.OpMIPS64LoweredAtomicStorezero32 {
+			as = mips.AMOVW
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(as)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = mips.REGZERO
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		s.Prog(mips.ASYNC)
+	case ssa.OpMIPS64LoweredAtomicExchange32, ssa.OpMIPS64LoweredAtomicExchange64:
+		// SYNC
+		// MOVV	Rarg1, Rtmp
+		// LL	(Rarg0), Rout
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		ll := mips.ALLV
+		sc := mips.ASCV
+		if v.Op == ssa.OpMIPS64LoweredAtomicExchange32 {
+			ll = mips.ALL
+			sc = mips.ASC
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(mips.AMOVV)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[1].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = mips.REGTMP
+		p1 := s.Prog(ll)
+		p1.From.Type = obj.TYPE_MEM
+		p1.From.Reg = v.Args[0].Reg()
+		p1.To.Type = obj.TYPE_REG
+		p1.To.Reg = v.Reg0()
+		p2 := s.Prog(sc)
+		p2.From.Type = obj.TYPE_REG
+		p2.From.Reg = mips.REGTMP
+		p2.To.Type = obj.TYPE_MEM
+		p2.To.Reg = v.Args[0].Reg()
+		p3 := s.Prog(mips.ABEQ)
+		p3.From.Type = obj.TYPE_REG
+		p3.From.Reg = mips.REGTMP
+		p3.To.Type = obj.TYPE_BRANCH
+		gc.Patch(p3, p)
+		s.Prog(mips.ASYNC)
+	case ssa.OpMIPS64LoweredAtomicAdd32, ssa.OpMIPS64LoweredAtomicAdd64:
+		// SYNC
+		// LL	(Rarg0), Rout
+		// ADDV Rarg1, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		// ADDV Rarg1, Rout
+		ll := mips.ALLV
+		sc := mips.ASCV
+		if v.Op == ssa.OpMIPS64LoweredAtomicAdd32 {
+			ll = mips.ALL
+			sc = mips.ASC
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(ll)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg0()
+		p1 := s.Prog(mips.AADDVU)
+		p1.From.Type = obj.TYPE_REG
+		p1.From.Reg = v.Args[1].Reg()
+		p1.Reg = v.Reg0()
+		p1.To.Type = obj.TYPE_REG
+		p1.To.Reg = mips.REGTMP
+		p2 := s.Prog(sc)
+		p2.From.Type = obj.TYPE_REG
+		p2.From.Reg = mips.REGTMP
+		p2.To.Type = obj.TYPE_MEM
+		p2.To.Reg = v.Args[0].Reg()
+		p3 := s.Prog(mips.ABEQ)
+		p3.From.Type = obj.TYPE_REG
+		p3.From.Reg = mips.REGTMP
+		p3.To.Type = obj.TYPE_BRANCH
+		gc.Patch(p3, p)
+		s.Prog(mips.ASYNC)
+		p4 := s.Prog(mips.AADDVU)
+		p4.From.Type = obj.TYPE_REG
+		p4.From.Reg = v.Args[1].Reg()
+		p4.Reg = v.Reg0()
+		p4.To.Type = obj.TYPE_REG
+		p4.To.Reg = v.Reg0()
+	case ssa.OpMIPS64LoweredAtomicAddconst32, ssa.OpMIPS64LoweredAtomicAddconst64:
+		// SYNC
+		// LL	(Rarg0), Rout
+		// ADDV $auxint, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		// ADDV $auxint, Rout
+		ll := mips.ALLV
+		sc := mips.ASCV
+		if v.Op == ssa.OpMIPS64LoweredAtomicAddconst32 {
+			ll = mips.ALL
+			sc = mips.ASC
+		}
+		s.Prog(mips.ASYNC)
+		p := s.Prog(ll)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg0()
+		p1 := s.Prog(mips.AADDVU)
+		p1.From.Type = obj.TYPE_CONST
+		p1.From.Offset = v.AuxInt
+		p1.Reg = v.Reg0()
+		p1.To.Type = obj.TYPE_REG
+		p1.To.Reg = mips.REGTMP
+		p2 := s.Prog(sc)
+		p2.From.Type = obj.TYPE_REG
+		p2.From.Reg = mips.REGTMP
+		p2.To.Type = obj.TYPE_MEM
+		p2.To.Reg = v.Args[0].Reg()
+		p3 := s.Prog(mips.ABEQ)
+		p3.From.Type = obj.TYPE_REG
+		p3.From.Reg = mips.REGTMP
+		p3.To.Type = obj.TYPE_BRANCH
+		gc.Patch(p3, p)
+		s.Prog(mips.ASYNC)
+		p4 := s.Prog(mips.AADDVU)
+		p4.From.Type = obj.TYPE_CONST
+		p4.From.Offset = v.AuxInt
+		p4.Reg = v.Reg0()
+		p4.To.Type = obj.TYPE_REG
+		p4.To.Reg = v.Reg0()
+	case ssa.OpMIPS64LoweredAtomicCas32, ssa.OpMIPS64LoweredAtomicCas64:
+		// MOVV $0, Rout
+		// SYNC
+		// LL	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 4(PC)
+		// MOVV Rarg2, Rout
+		// SC	Rout, (Rarg0)
+		// BEQ	Rout, -4(PC)
+		// SYNC
+		ll := mips.ALLV
+		sc := mips.ASCV
+		if v.Op == ssa.OpMIPS64LoweredAtomicCas32 {
+			ll = mips.ALL
+			sc = mips.ASC
+		}
+		p := s.Prog(mips.AMOVV)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = mips.REGZERO
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg0()
+		s.Prog(mips.ASYNC)
+		p1 := s.Prog(ll)
+		p1.From.Type = obj.TYPE_MEM
+		p1.From.Reg = v.Args[0].Reg()
+		p1.To.Type = obj.TYPE_REG
+		p1.To.Reg = mips.REGTMP
+		p2 := s.Prog(mips.ABNE)
+		p2.From.Type = obj.TYPE_REG
+		p2.From.Reg = v.Args[1].Reg()
+		p2.Reg = mips.REGTMP
+		p2.To.Type = obj.TYPE_BRANCH
+		p3 := s.Prog(mips.AMOVV)
+		p3.From.Type = obj.TYPE_REG
+		p3.From.Reg = v.Args[2].Reg()
+		p3.To.Type = obj.TYPE_REG
+		p3.To.Reg = v.Reg0()
+		p4 := s.Prog(sc)
+		p4.From.Type = obj.TYPE_REG
+		p4.From.Reg = v.Reg0()
+		p4.To.Type = obj.TYPE_MEM
+		p4.To.Reg = v.Args[0].Reg()
+		p5 := s.Prog(mips.ABEQ)
+		p5.From.Type = obj.TYPE_REG
+		p5.From.Reg = v.Reg0()
+		p5.To.Type = obj.TYPE_BRANCH
+		gc.Patch(p5, p1)
+		p6 := s.Prog(mips.ASYNC)
+		gc.Patch(p2, p6)
 	case ssa.OpMIPS64LoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
 		p := s.Prog(mips.AMOVB)
@@ -520,6 +725,14 @@
 	case ssa.OpMIPS64LoweredGetClosurePtr:
 		// Closure pointer is R22 (mips.REGCTXT).
 		gc.CheckLoweredGetClosurePtr(v)
+	case ssa.OpMIPS64LoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(mips.AMOVV)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpClobber:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index 5fe140f..008d965 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -124,7 +124,7 @@
 	p.To.Type = obj.TYPE_REG
 	p.To.Reg = r
 	p.Reg = r1
-	p.From3 = &obj.Addr{Type: obj.TYPE_REG, Reg: r2}
+	p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r2})
 	p.From.Type = obj.TYPE_CONST
 	p.From.Offset = cr
 }
@@ -152,29 +152,6 @@
 			p.To.Reg = y
 		}
 
-	case ssa.OpPPC64Xf2i64:
-		{
-			x := v.Args[0].Reg()
-			y := v.Reg()
-
-			p := s.Prog(ppc64.AMFVSRD)
-			p.From.Type = obj.TYPE_REG
-			p.From.Reg = x
-			p.To.Type = obj.TYPE_REG
-			p.To.Reg = y
-		}
-	case ssa.OpPPC64Xi2f64:
-		{
-			x := v.Args[0].Reg()
-			y := v.Reg()
-
-			p := s.Prog(ppc64.AMTVSRD)
-			p.From.Type = obj.TYPE_REG
-			p.From.Reg = x
-			p.To.Type = obj.TYPE_REG
-			p.To.Reg = y
-		}
-
 	case ssa.OpPPC64LoweredAtomicAnd8,
 		ssa.OpPPC64LoweredAtomicOr8:
 		// SYNC
@@ -445,6 +422,15 @@
 		// Closure pointer is R11 (already)
 		gc.CheckLoweredGetClosurePtr(v)
 
+	case ssa.OpPPC64LoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(ppc64.AMOVD)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+
 	case ssa.OpPPC64LoweredRound32F, ssa.OpPPC64LoweredRound64F:
 		// input is already rounded
 
@@ -542,8 +528,9 @@
 	case ssa.OpPPC64ADD, ssa.OpPPC64FADD, ssa.OpPPC64FADDS, ssa.OpPPC64SUB, ssa.OpPPC64FSUB, ssa.OpPPC64FSUBS,
 		ssa.OpPPC64MULLD, ssa.OpPPC64MULLW, ssa.OpPPC64DIVDU, ssa.OpPPC64DIVWU,
 		ssa.OpPPC64SRAD, ssa.OpPPC64SRAW, ssa.OpPPC64SRD, ssa.OpPPC64SRW, ssa.OpPPC64SLD, ssa.OpPPC64SLW,
+		ssa.OpPPC64ROTL, ssa.OpPPC64ROTLW,
 		ssa.OpPPC64MULHD, ssa.OpPPC64MULHW, ssa.OpPPC64MULHDU, ssa.OpPPC64MULHWU,
-		ssa.OpPPC64FMUL, ssa.OpPPC64FMULS, ssa.OpPPC64FDIV, ssa.OpPPC64FDIVS,
+		ssa.OpPPC64FMUL, ssa.OpPPC64FMULS, ssa.OpPPC64FDIV, ssa.OpPPC64FDIVS, ssa.OpPPC64FCPSGN,
 		ssa.OpPPC64AND, ssa.OpPPC64OR, ssa.OpPPC64ANDN, ssa.OpPPC64ORN, ssa.OpPPC64NOR, ssa.OpPPC64XOR, ssa.OpPPC64EQV:
 		r := v.Reg()
 		r1 := v.Args[0].Reg()
@@ -573,9 +560,7 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r1
 		p.Reg = r3
-		p.From3 = new(obj.Addr)
-		p.From3.Type = obj.TYPE_REG
-		p.From3.Reg = r2
+		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r2})
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
 
@@ -596,7 +581,7 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = ppc64.REGTMP // Ignored; this is for the carry effect.
 
-	case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB:
+	case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FCFIDS, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB, ssa.OpPPC64MFVSRD, ssa.OpPPC64MTVSRD, ssa.OpPPC64FABS, ssa.OpPPC64FNABS:
 		r := v.Reg()
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
@@ -608,15 +593,8 @@
 		ssa.OpPPC64SRADconst, ssa.OpPPC64SRAWconst, ssa.OpPPC64SRDconst, ssa.OpPPC64SRWconst, ssa.OpPPC64SLDconst, ssa.OpPPC64SLWconst:
 		p := s.Prog(v.Op.Asm())
 		p.Reg = v.Args[0].Reg()
-
-		if v.Aux != nil {
-			p.From.Type = obj.TYPE_CONST
-			p.From.Offset = gc.AuxOffset(v)
-		} else {
-			p.From.Type = obj.TYPE_CONST
-			p.From.Offset = v.AuxInt
-		}
-
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
@@ -652,10 +630,10 @@
 		switch v.Aux.(type) {
 		default:
 			v.Fatalf("aux is of unknown type %T", v.Aux)
-		case *ssa.ExternSymbol:
+		case *obj.LSym:
 			wantreg = "SB"
 			gc.AddAux(&p.From, v)
-		case *ssa.ArgSymbol, *ssa.AutoSymbol:
+		case *gc.Node:
 			wantreg = "SP"
 			gc.AddAux(&p.From, v)
 		case nil:
@@ -1088,17 +1066,8 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = ppc64.REG_CTR
 
-		if gc.Ctxt.Flag_shared && p.From.Reg != ppc64.REG_R12 {
-			// Make sure function pointer is in R12 as well when
-			// compiling Go into PIC.
-			// TODO(mwhudson): it would obviously be better to
-			// change the register allocation to put the value in
-			// R12 already, but I don't know how to do that.
-			// TODO: We have the technology now to implement TODO above.
-			q := s.Prog(ppc64.AMOVD)
-			q.From = p.From
-			q.To.Type = obj.TYPE_REG
-			q.To.Reg = ppc64.REG_R12
+		if v.Args[0].Reg() != ppc64.REG_R12 {
+			v.Fatalf("Function address for %v should be in R12 %d but is in %d", v.LongString(), ppc64.REG_R12, p.From.Reg)
 		}
 
 		pp := s.Call(v)
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index 8722345..c9d1f52 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -207,6 +207,16 @@
 		p.Reg = r2
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
+	case ssa.OpS390XFIDBR:
+		switch v.AuxInt {
+		case 0, 1, 3, 4, 5, 6, 7:
+			opregregimm(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg(), v.AuxInt)
+		default:
+			v.Fatalf("invalid FIDBR mask: %v", v.AuxInt)
+		}
+	case ssa.OpS390XCPSDR:
+		p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
+		p.Reg = v.Args[0].Reg()
 	case ssa.OpS390XDIVD, ssa.OpS390XDIVW,
 		ssa.OpS390XDIVDU, ssa.OpS390XDIVWU,
 		ssa.OpS390XMODD, ssa.OpS390XMODW,
@@ -327,12 +337,18 @@
 		opregreg(s, v.Op.Asm(), v.Args[1].Reg(), v.Args[0].Reg())
 	case ssa.OpS390XFCMPS, ssa.OpS390XFCMP:
 		opregreg(s, v.Op.Asm(), v.Args[1].Reg(), v.Args[0].Reg())
-	case ssa.OpS390XCMPconst, ssa.OpS390XCMPWconst, ssa.OpS390XCMPUconst, ssa.OpS390XCMPWUconst:
+	case ssa.OpS390XCMPconst, ssa.OpS390XCMPWconst:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_CONST
 		p.To.Offset = v.AuxInt
+	case ssa.OpS390XCMPUconst, ssa.OpS390XCMPWUconst:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_CONST
+		p.To.Offset = int64(uint32(v.AuxInt))
 	case ssa.OpS390XMOVDconst:
 		x := v.Reg()
 		p := s.Prog(v.Op.Asm())
@@ -374,7 +390,8 @@
 		gc.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpS390XMOVBZloadidx, ssa.OpS390XMOVHZloadidx, ssa.OpS390XMOVWZloadidx, ssa.OpS390XMOVDloadidx,
+	case ssa.OpS390XMOVBZloadidx, ssa.OpS390XMOVHZloadidx, ssa.OpS390XMOVWZloadidx,
+		ssa.OpS390XMOVBloadidx, ssa.OpS390XMOVHloadidx, ssa.OpS390XMOVWloadidx, ssa.OpS390XMOVDloadidx,
 		ssa.OpS390XMOVHBRloadidx, ssa.OpS390XMOVWBRloadidx, ssa.OpS390XMOVDBRloadidx,
 		ssa.OpS390XFMOVSloadidx, ssa.OpS390XFMOVDloadidx:
 		r := v.Args[0].Reg()
@@ -425,10 +442,12 @@
 		gc.AddAux2(&p.To, v, sc.Off())
 	case ssa.OpS390XMOVBreg, ssa.OpS390XMOVHreg, ssa.OpS390XMOVWreg,
 		ssa.OpS390XMOVBZreg, ssa.OpS390XMOVHZreg, ssa.OpS390XMOVWZreg,
+		ssa.OpS390XLDGR, ssa.OpS390XLGDR,
 		ssa.OpS390XCEFBRA, ssa.OpS390XCDFBRA, ssa.OpS390XCEGBRA, ssa.OpS390XCDGBRA,
 		ssa.OpS390XCFEBRA, ssa.OpS390XCFDBRA, ssa.OpS390XCGEBRA, ssa.OpS390XCGDBRA,
 		ssa.OpS390XLDEBR, ssa.OpS390XLEDBR,
-		ssa.OpS390XFNEG, ssa.OpS390XFNEGS:
+		ssa.OpS390XFNEG, ssa.OpS390XFNEGS,
+		ssa.OpS390XLPDFR, ssa.OpS390XLNDFR:
 		opregreg(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg())
 	case ssa.OpS390XCLEAR:
 		p := s.Prog(v.Op.Asm())
@@ -482,6 +501,14 @@
 		p.From.Reg = s390x.REGG
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
+	case ssa.OpS390XLoweredGetCallerSP:
+		// caller's SP is FixedFrameSize below the address of the first arg
+		p := s.Prog(s390x.AMOVD)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpS390XCALLstatic, ssa.OpS390XCALLclosure, ssa.OpS390XCALLinter:
 		s.Call(v)
 	case ssa.OpS390XFLOGR, ssa.OpS390XNEG, ssa.OpS390XNEGW,
@@ -534,10 +561,11 @@
 		p := s.Prog(s390x.AMVC)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = vo.Val()
-		p.From3 = new(obj.Addr)
-		p.From3.Type = obj.TYPE_MEM
-		p.From3.Reg = v.Args[1].Reg()
-		p.From3.Offset = vo.Off()
+		p.SetFrom3(obj.Addr{
+			Type:   obj.TYPE_MEM,
+			Reg:    v.Args[1].Reg(),
+			Offset: vo.Off(),
+		})
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 		p.To.Offset = vo.Off()
@@ -570,9 +598,7 @@
 		mvc := s.Prog(s390x.AMVC)
 		mvc.From.Type = obj.TYPE_CONST
 		mvc.From.Offset = 256
-		mvc.From3 = new(obj.Addr)
-		mvc.From3.Type = obj.TYPE_MEM
-		mvc.From3.Reg = v.Args[1].Reg()
+		mvc.SetFrom3(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
 		mvc.To.Type = obj.TYPE_MEM
 		mvc.To.Reg = v.Args[0].Reg()
 
@@ -599,9 +625,7 @@
 			mvc := s.Prog(s390x.AMVC)
 			mvc.From.Type = obj.TYPE_CONST
 			mvc.From.Offset = v.AuxInt
-			mvc.From3 = new(obj.Addr)
-			mvc.From3.Type = obj.TYPE_MEM
-			mvc.From3.Reg = v.Args[1].Reg()
+			mvc.SetFrom3(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
 			mvc.To.Type = obj.TYPE_MEM
 			mvc.To.Reg = v.Args[0].Reg()
 		}
diff --git a/src/cmd/compile/internal/ssa/block.go b/src/cmd/compile/internal/ssa/block.go
index 10f07ce..273e5f1 100644
--- a/src/cmd/compile/internal/ssa/block.go
+++ b/src/cmd/compile/internal/ssa/block.go
@@ -198,6 +198,29 @@
 	b.Likely *= -1
 }
 
+// LackingPos indicates whether b is a block whose position should be inherited
+// from its successors.  This is true if all the values within it have unreliable positions
+// and if it is "plain", meaning that there is no control flow that is also very likely
+// to correspond to a well-understood source position.
+func (b *Block) LackingPos() bool {
+	// Non-plain predecessors are If or Defer, which both (1) have two successors,
+	// which might have different line numbers and (2) correspond to statements
+	// in the source code that have positions, so this case ought not occur anyway.
+	if b.Kind != BlockPlain {
+		return false
+	}
+	if b.Pos != src.NoXPos {
+		return false
+	}
+	for _, v := range b.Values {
+		if v.LackingPos() {
+			continue
+		}
+		return false
+	}
+	return true
+}
+
 func (b *Block) Logf(msg string, args ...interface{})   { b.Func.Logf(msg, args...) }
 func (b *Block) Log() bool                              { return b.Func.Log() }
 func (b *Block) Fatalf(msg string, args ...interface{}) { b.Func.Fatalf(msg, args...) }
diff --git a/src/cmd/compile/internal/ssa/cache.go b/src/cmd/compile/internal/ssa/cache.go
index f1018da..8434084 100644
--- a/src/cmd/compile/internal/ssa/cache.go
+++ b/src/cmd/compile/internal/ssa/cache.go
@@ -14,6 +14,11 @@
 	blocks [200]Block
 	locs   [2000]Location
 
+	// Storage for DWARF variable locations. Lazily allocated
+	// since location lists are off by default.
+	varLocs   []VarLoc
+	curVarLoc int
+
 	// Reusable stackAllocState.
 	// See stackalloc.go's {new,put}StackAllocState.
 	stackAllocState *stackAllocState
@@ -38,4 +43,21 @@
 	for i := range xl {
 		xl[i] = nil
 	}
+	xvl := c.varLocs[:c.curVarLoc]
+	for i := range xvl {
+		xvl[i] = VarLoc{}
+	}
+	c.curVarLoc = 0
+}
+
+func (c *Cache) NewVarLoc() *VarLoc {
+	if c.varLocs == nil {
+		c.varLocs = make([]VarLoc, 4000)
+	}
+	if c.curVarLoc == len(c.varLocs) {
+		return &VarLoc{}
+	}
+	vl := &c.varLocs[c.curVarLoc]
+	c.curVarLoc++
+	return vl
 }
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index 17f683f..1c2fcd7 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -4,6 +4,10 @@
 
 package ssa
 
+import (
+	"math"
+)
+
 // checkFunc checks invariants of f.
 func checkFunc(f *Func) {
 	blockMark := make([]bool, f.NumBlocks())
@@ -199,6 +203,10 @@
 				}
 			}
 
+			if f.RegAlloc != nil && f.Config.SoftFloat && v.Type.IsFloat() {
+				f.Fatalf("unexpected floating-point type %v", v.LongString())
+			}
+
 			// TODO: check for cycles in values
 			// TODO: check type
 		}
@@ -276,15 +284,17 @@
 	// Check loop construction
 	if f.RegAlloc == nil && f.pass != nil { // non-nil pass allows better-targeted debug printing
 		ln := f.loopnest()
-		po := f.postorder() // use po to avoid unreachable blocks.
-		for _, b := range po {
-			for _, s := range b.Succs {
-				bb := s.Block()
-				if ln.b2l[b.ID] == nil && ln.b2l[bb.ID] != nil && bb != ln.b2l[bb.ID].header {
-					f.Fatalf("block %s not in loop branches to non-header block %s in loop", b.String(), bb.String())
-				}
-				if ln.b2l[b.ID] != nil && ln.b2l[bb.ID] != nil && bb != ln.b2l[bb.ID].header && !ln.b2l[b.ID].isWithinOrEq(ln.b2l[bb.ID]) {
-					f.Fatalf("block %s in loop branches to non-header block %s in non-containing loop", b.String(), bb.String())
+		if !ln.hasIrreducible {
+			po := f.postorder() // use po to avoid unreachable blocks.
+			for _, b := range po {
+				for _, s := range b.Succs {
+					bb := s.Block()
+					if ln.b2l[b.ID] == nil && ln.b2l[bb.ID] != nil && bb != ln.b2l[bb.ID].header {
+						f.Fatalf("block %s not in loop branches to non-header block %s in loop", b.String(), bb.String())
+					}
+					if ln.b2l[b.ID] != nil && ln.b2l[bb.ID] != nil && bb != ln.b2l[bb.ID].header && !ln.b2l[b.ID].isWithinOrEq(ln.b2l[bb.ID]) {
+						f.Fatalf("block %s in loop branches to non-header block %s in non-containing loop", b.String(), bb.String())
+					}
 				}
 			}
 		}
@@ -450,11 +460,16 @@
 		for _, b := range f.Blocks {
 			seenNonPhi := false
 			for _, v := range b.Values {
-				if v.Op == OpPhi {
+				switch v.Op {
+				case OpPhi:
 					if seenNonPhi {
 						f.Fatalf("phi after non-phi @ %s: %s", b, v)
 					}
-				} else {
+				case OpRegKill:
+					if f.RegAlloc == nil {
+						f.Fatalf("RegKill seen before register allocation @ %s: %s", b, v)
+					}
+				default:
 					seenNonPhi = true
 				}
 			}
@@ -471,7 +486,8 @@
 	return sdom.isAncestorEq(x, y)
 }
 
-// isExactFloat32 reoprts whether v has an AuxInt that can be exactly represented as a float32.
+// isExactFloat32 reports whether v has an AuxInt that can be exactly represented as a float32.
 func isExactFloat32(v *Value) bool {
-	return v.AuxFloat() == float64(float32(v.AuxFloat()))
+	x := v.AuxFloat()
+	return math.Float64bits(x) == math.Float64bits(float64(float32(x)))
 }
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 315416b..82b9e2c 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -123,7 +123,7 @@
 // output.
 func (f *Func) dumpFile(phaseName string) {
 	dumpFileSeq++
-	fname := fmt.Sprintf("%s__%s_%d.dump", phaseName, f.Name, dumpFileSeq)
+	fname := fmt.Sprintf("%s_%02d__%s.dump", f.Name, dumpFileSeq, phaseName)
 	fname = strings.Replace(fname, " ", "_", -1)
 	fname = strings.Replace(fname, "/", "_", -1)
 	fname = strings.Replace(fname, ":", "_", -1)
@@ -344,7 +344,7 @@
 	{name: "prove", fn: prove},
 	{name: "loopbce", fn: loopbce},
 	{name: "decompose builtin", fn: decomposeBuiltIn, required: true},
-	{name: "dec", fn: dec, required: true},
+	{name: "softfloat", fn: softfloat, required: true},
 	{name: "late opt", fn: opt, required: true}, // TODO: split required rules and optimizing rules
 	{name: "generic deadcode", fn: deadcode},
 	{name: "check bce", fn: checkbce},
@@ -356,6 +356,7 @@
 	{name: "tighten", fn: tighten}, // move values closer to their uses
 	{name: "lower", fn: lower, required: true},
 	{name: "lowered cse", fn: cse},
+	{name: "elim unread autos", fn: elimUnreadAutos},
 	{name: "lowered deadcode", fn: deadcode, required: true},
 	{name: "checkLower", fn: checkLower, required: true},
 	{name: "late phielim", fn: phielim},
@@ -413,6 +414,8 @@
 	{"generic deadcode", "check bce"},
 	// don't run optimization pass until we've decomposed builtin objects
 	{"decompose builtin", "late opt"},
+	// decompose builtin is the last pass that may introduce new float ops, so run softfloat after it
+	{"decompose builtin", "softfloat"},
 	// don't layout blocks until critical edges have been removed
 	{"critical", "layout"},
 	// regalloc requires the removal of all critical edges
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go
index 6587c40..ae6caee 100644
--- a/src/cmd/compile/internal/ssa/config.go
+++ b/src/cmd/compile/internal/ssa/config.go
@@ -33,8 +33,10 @@
 	ctxt            *obj.Link     // Generic arch information
 	optimize        bool          // Do optimization
 	noDuffDevice    bool          // Don't use Duff's device
+	useSSE          bool          // Use SSE for non-float operations
 	nacl            bool          // GOOS=nacl
 	use387          bool          // GO386=387
+	SoftFloat       bool          //
 	NeedsFpScratch  bool          // No direct move between GP and FP register sets
 	BigEndian       bool          //
 	sparsePhiCutoff uint64        // Sparse phi location algorithm used above this #blocks*#variables score
@@ -58,6 +60,7 @@
 	Int        *types.Type
 	Float32    *types.Type
 	Float64    *types.Type
+	UInt       *types.Type
 	Uintptr    *types.Type
 	String     *types.Type
 	BytePtr    *types.Type // TODO: use unsafe.Pointer instead?
@@ -86,7 +89,7 @@
 
 	// Forwards the Debug flags from gc
 	Debug_checknil() bool
-	Debug_wb() bool
+	Debug_eagerwb() bool
 }
 
 type Frontend interface {
@@ -129,15 +132,28 @@
 
 	// UseWriteBarrier returns whether write barrier is enabled
 	UseWriteBarrier() bool
+
+	// SetWBPos indicates that a write barrier has been inserted
+	// in this function at position pos.
+	SetWBPos(pos src.XPos)
 }
 
-// interface used to hold *gc.Node. We'd use *gc.Node directly but
-// that would lead to an import cycle.
+// interface used to hold a *gc.Node (a stack variable).
+// We'd use *gc.Node directly but that would lead to an import cycle.
 type GCNode interface {
 	Typ() *types.Type
 	String() string
+	StorageClass() StorageClass
 }
 
+type StorageClass uint8
+
+const (
+	ClassAuto     StorageClass = iota // local stack variable
+	ClassParam                        // argument
+	ClassParamOut                     // return value
+)
+
 // NewConfig returns a new configuration object for the given architecture.
 func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
 	c := &Config{arch: arch, Types: types}
@@ -264,11 +280,13 @@
 	c.ctxt = ctxt
 	c.optimize = optimize
 	c.nacl = objabi.GOOS == "nacl"
+	c.useSSE = true
 
-	// Don't use Duff's device on Plan 9 AMD64, because floating
-	// point operations are not allowed in note handler.
+	// Don't use Duff's device nor SSE on Plan 9 AMD64, because
+	// floating point operations are not allowed in note handler.
 	if objabi.GOOS == "plan9" && arch == "amd64" {
 		c.noDuffDevice = true
+		c.useSSE = false
 	}
 
 	if c.nacl {
diff --git a/src/cmd/compile/internal/ssa/copyelim.go b/src/cmd/compile/internal/ssa/copyelim.go
index 5cbb448..44ccfe1 100644
--- a/src/cmd/compile/internal/ssa/copyelim.go
+++ b/src/cmd/compile/internal/ssa/copyelim.go
@@ -45,7 +45,7 @@
 	// but we take some extra care to make sure we
 	// don't get stuck in an infinite loop.
 	// Infinite copy loops may happen in unreachable code.
-	// (TODO: or can they?  Needs a test.)
+	// (TODO: or can they? Needs a test.)
 	slow := w
 	var advance bool
 	for w.Op == OpCopy {
diff --git a/src/cmd/compile/internal/ssa/deadstore.go b/src/cmd/compile/internal/ssa/deadstore.go
index 08a2c6d..bbeb990 100644
--- a/src/cmd/compile/internal/ssa/deadstore.go
+++ b/src/cmd/compile/internal/ssa/deadstore.go
@@ -131,3 +131,58 @@
 		}
 	}
 }
+
+// elimUnreadAutos deletes stores (and associated bookkeeping ops VarDef and VarKill)
+// to autos that are never read from.
+func elimUnreadAutos(f *Func) {
+	// Loop over all ops that affect autos taking note of which
+	// autos we need and also stores that we might be able to
+	// eliminate.
+	seen := make(map[GCNode]bool)
+	var stores []*Value
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			n, ok := v.Aux.(GCNode)
+			if !ok {
+				continue
+			}
+			if n.StorageClass() != ClassAuto {
+				continue
+			}
+
+			effect := v.Op.SymEffect()
+			switch effect {
+			case SymNone, SymWrite:
+				// If we haven't seen the auto yet
+				// then this might be a store we can
+				// eliminate.
+				if !seen[n] {
+					stores = append(stores, v)
+				}
+			default:
+				// Assume the auto is needed (loaded,
+				// has its address taken, etc.).
+				// Note we have to check the uses
+				// because dead loads haven't been
+				// eliminated yet.
+				if v.Uses > 0 {
+					seen[n] = true
+				}
+			}
+		}
+	}
+
+	// Eliminate stores to unread autos.
+	for _, store := range stores {
+		n, _ := store.Aux.(GCNode)
+		if seen[n] {
+			continue
+		}
+
+		// replace store with OpCopy
+		store.SetArgs1(store.MemoryArg())
+		store.Aux = nil
+		store.AuxInt = 0
+		store.Op = OpCopy
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go
new file mode 100644
index 0000000..dcef9f2
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/debug.go
@@ -0,0 +1,574 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package ssa
+
+import (
+	"cmd/internal/obj"
+	"fmt"
+	"strings"
+)
+
+type SlotID int32
+
+// A FuncDebug contains all the debug information for the variables in a
+// function. Variables are identified by their LocalSlot, which may be the
+// result of decomposing a larger variable.
+type FuncDebug struct {
+	// Slots is all the slots used in the debug info, indexed by their SlotID.
+	// Use this when getting a LocalSlot from a SlotID.
+	Slots []*LocalSlot
+	// VarSlots is the slots that represent part of user variables.
+	// Use this when iterating over all the slots to generate debug information.
+	VarSlots []*LocalSlot
+	// The blocks in the function, in program text order.
+	Blocks []*BlockDebug
+	// The registers of the current architecture, indexed by Register.num.
+	Registers []Register
+}
+
+func (f *FuncDebug) BlockString(b *BlockDebug) string {
+	var vars []string
+
+	for slot := range f.VarSlots {
+		if len(b.Variables[slot].Locations) == 0 {
+			continue
+		}
+		vars = append(vars, fmt.Sprintf("%v = %v", f.Slots[slot], b.Variables[slot]))
+	}
+	return fmt.Sprintf("{%v}", strings.Join(vars, ", "))
+}
+
+func (f *FuncDebug) SlotLocsString(id SlotID) string {
+	var locs []string
+	for _, block := range f.Blocks {
+		for _, loc := range block.Variables[id].Locations {
+			locs = append(locs, block.LocString(loc))
+		}
+	}
+	return strings.Join(locs, " ")
+}
+
+type BlockDebug struct {
+	// The SSA block that this tracks. For debug logging only.
+	Block *Block
+	// The variables in this block, indexed by their SlotID.
+	Variables []VarLocList
+}
+
+func (b *BlockDebug) LocString(loc *VarLoc) string {
+	registers := b.Block.Func.Config.registers
+
+	var storage []string
+	if loc.OnStack {
+		storage = append(storage, "stack")
+	}
+
+	for reg := 0; reg < 64; reg++ {
+		if loc.Registers&(1<<uint8(reg)) == 0 {
+			continue
+		}
+		if registers != nil {
+			storage = append(storage, registers[reg].String())
+		} else {
+			storage = append(storage, fmt.Sprintf("reg%d", reg))
+		}
+	}
+	if len(storage) == 0 {
+		storage = append(storage, "!!!no storage!!!")
+	}
+	pos := func(v *Value, p *obj.Prog, pc int64) string {
+		if v == nil {
+			return "?"
+		}
+		vStr := fmt.Sprintf("v%d", v.ID)
+		if v == BlockStart {
+			vStr = fmt.Sprintf("b%dStart", b.Block.ID)
+		}
+		if v == BlockEnd {
+			vStr = fmt.Sprintf("b%dEnd", b.Block.ID)
+		}
+		if p == nil {
+			return vStr
+		}
+		return fmt.Sprintf("%s/%x", vStr, pc)
+	}
+	start := pos(loc.Start, loc.StartProg, loc.StartPC)
+	end := pos(loc.End, loc.EndProg, loc.EndPC)
+	return fmt.Sprintf("%v-%v@%s", start, end, strings.Join(storage, ","))
+
+}
+
+// append adds a location to the location list for slot.
+func (b *BlockDebug) append(slot SlotID, loc *VarLoc) {
+	b.Variables[slot].append(loc)
+}
+
+// lastLoc returns the last VarLoc for slot, or nil if it has none.
+func (b *BlockDebug) lastLoc(slot SlotID) *VarLoc {
+	return b.Variables[slot].last()
+}
+
+// A VarLocList contains the locations for a variable, in program text order.
+// It will often have gaps.
+type VarLocList struct {
+	Locations []*VarLoc
+}
+
+func (l *VarLocList) append(loc *VarLoc) {
+	l.Locations = append(l.Locations, loc)
+}
+
+// last returns the last location in the list.
+func (l *VarLocList) last() *VarLoc {
+	if l == nil || len(l.Locations) == 0 {
+		return nil
+	}
+	return l.Locations[len(l.Locations)-1]
+}
+
+// A VarLoc describes a variable's location in a single contiguous range
+// of program text. It is generated from the SSA representation, but it
+// refers to the generated machine code, so the Values referenced are better
+// understood as PCs than actual Values, and the ranges can cross blocks.
+// The range is defined first by Values, which are then mapped to Progs
+// during genssa and finally to function PCs after assembly.
+// A variable can be on the stack and in any number of registers.
+type VarLoc struct {
+	// Inclusive -- the first SSA value that the range covers. The value
+	// doesn't necessarily have anything to do with the variable; it just
+	// identifies a point in the program text.
+	// The special sentinel value BlockStart indicates that the range begins
+	// at the beginning of the containing block, even if the block doesn't
+	// actually have a Value to use to indicate that.
+	Start *Value
+	// Exclusive -- the first SSA value after start that the range doesn't
+	// cover. A location with start == end is empty.
+	// The special sentinel value BlockEnd indicates that the variable survives
+	// to the end of the of the containing block, after all its Values and any
+	// control flow instructions added later.
+	End *Value
+
+	// The prog/PCs corresponding to Start and End above. These are for the
+	// convenience of later passes, since code generation isn't done when
+	// BuildFuncDebug runs.
+	// Control flow instructions don't correspond to a Value, so EndProg
+	// may point to a Prog in the next block if SurvivedBlock is true. For
+	// the last block, where there's no later Prog, it will be nil to indicate
+	// the end of the function.
+	StartProg, EndProg *obj.Prog
+	StartPC, EndPC     int64
+
+	// The registers this variable is available in. There can be more than
+	// one in various situations, e.g. it's being moved between registers.
+	Registers RegisterSet
+	// OnStack indicates that the variable is on the stack in the LocalSlot
+	// identified by StackLocation.
+	OnStack       bool
+	StackLocation SlotID
+}
+
+var BlockStart = &Value{
+	ID:  -10000,
+	Op:  OpInvalid,
+	Aux: "BlockStart",
+}
+
+var BlockEnd = &Value{
+	ID:  -20000,
+	Op:  OpInvalid,
+	Aux: "BlockEnd",
+}
+
+// RegisterSet is a bitmap of registers, indexed by Register.num.
+type RegisterSet uint64
+
+// unexpected is used to indicate an inconsistency or bug in the debug info
+// generation process. These are not fixable by users. At time of writing,
+// changing this to a Fprintf(os.Stderr) and running make.bash generates
+// thousands of warnings.
+func (s *debugState) unexpected(v *Value, msg string, args ...interface{}) {
+	s.f.Logf("unexpected at "+fmt.Sprint(v.ID)+":"+msg, args...)
+}
+
+func (s *debugState) logf(msg string, args ...interface{}) {
+	s.f.Logf(msg, args...)
+}
+
+type debugState struct {
+	loggingEnabled bool
+	slots          []*LocalSlot
+	varSlots       []*LocalSlot
+	f              *Func
+	cache          *Cache
+	numRegisters   int
+
+	// working storage for BuildFuncDebug, reused between blocks.
+	registerContents [][]SlotID
+}
+
+// getHomeSlot returns the SlotID of the home slot for v, adding to s.slots
+// if necessary.
+func (s *debugState) getHomeSlot(v *Value) SlotID {
+	home := s.f.getHome(v.ID).(LocalSlot)
+	for id, slot := range s.slots {
+		if *slot == home {
+			return SlotID(id)
+		}
+	}
+	// This slot wasn't in the NamedValue table so it needs to be added.
+	s.slots = append(s.slots, &home)
+	return SlotID(len(s.slots) - 1)
+}
+
+func (s *debugState) BlockString(b *BlockDebug) string {
+	f := &FuncDebug{
+		Slots:     s.slots,
+		VarSlots:  s.varSlots,
+		Registers: s.f.Config.registers,
+	}
+	return f.BlockString(b)
+}
+
+// BuildFuncDebug returns debug information for f.
+// f must be fully processed, so that each Value is where it will be when
+// machine code is emitted.
+func BuildFuncDebug(f *Func, loggingEnabled bool) *FuncDebug {
+	if f.RegAlloc == nil {
+		f.Fatalf("BuildFuncDebug on func %v that has not been fully processed", f)
+	}
+	state := &debugState{
+		loggingEnabled:   loggingEnabled,
+		slots:            make([]*LocalSlot, len(f.Names)),
+		cache:            f.Cache,
+		f:                f,
+		numRegisters:     len(f.Config.registers),
+		registerContents: make([][]SlotID, len(f.Config.registers)),
+	}
+	// TODO: consider storing this in Cache and reusing across functions.
+	valueNames := make([][]SlotID, f.NumValues())
+
+	for i, slot := range f.Names {
+		slot := slot
+		state.slots[i] = &slot
+
+		if isSynthetic(&slot) {
+			continue
+		}
+		for _, value := range f.NamedValues[slot] {
+			valueNames[value.ID] = append(valueNames[value.ID], SlotID(i))
+		}
+	}
+	// state.varSlots is never changed, and state.slots is only appended to,
+	// so aliasing is safe.
+	state.varSlots = state.slots
+
+	if state.loggingEnabled {
+		var names []string
+		for i, name := range f.Names {
+			names = append(names, fmt.Sprintf("%d = %s", i, name))
+		}
+		state.logf("Name table: %v\n", strings.Join(names, ", "))
+	}
+
+	// Build up block states, starting with the first block, then
+	// processing blocks once their predecessors have been processed.
+
+	// Location list entries for each block.
+	blockLocs := make([]*BlockDebug, f.NumBlocks())
+
+	// Reverse postorder: visit a block after as many as possible of its
+	// predecessors have been visited.
+	po := f.Postorder()
+	for i := len(po) - 1; i >= 0; i-- {
+		b := po[i]
+
+		// Build the starting state for the block from the final
+		// state of its predecessors.
+		locs := state.mergePredecessors(b, blockLocs)
+		if state.loggingEnabled {
+			state.logf("Processing %v, initial locs %v, regs %v\n", b, state.BlockString(locs), state.registerContents)
+		}
+		// Update locs/registers with the effects of each Value.
+		// The location list generated here needs to be slightly adjusted for use by gdb.
+		// These adjustments are applied in genssa.
+		for _, v := range b.Values {
+			slots := valueNames[v.ID]
+
+			// Loads and stores inherit the names of their sources.
+			var source *Value
+			switch v.Op {
+			case OpStoreReg:
+				source = v.Args[0]
+			case OpLoadReg:
+				switch a := v.Args[0]; a.Op {
+				case OpArg:
+					source = a
+				case OpStoreReg:
+					source = a.Args[0]
+				default:
+					state.unexpected(v, "load with unexpected source op %v", a)
+				}
+			}
+			if source != nil {
+				slots = append(slots, valueNames[source.ID]...)
+				// As of writing, the compiler never uses a load/store as a
+				// source of another load/store, so there's no reason this should
+				// ever be consulted. Update just in case, and so that when
+				// valueNames is cached, we can reuse the memory.
+				valueNames[v.ID] = slots
+			}
+
+			if len(slots) == 0 {
+				continue
+			}
+
+			reg, _ := f.getHome(v.ID).(*Register)
+			state.processValue(locs, v, slots, reg)
+		}
+
+		// The block is done; mark any live locations as ending with the block.
+		for _, locList := range locs.Variables {
+			last := locList.last()
+			if last == nil || last.End != nil {
+				continue
+			}
+			last.End = BlockEnd
+		}
+		if state.loggingEnabled {
+			f.Logf("Block done: locs %v, regs %v\n", state.BlockString(locs), state.registerContents)
+		}
+		blockLocs[b.ID] = locs
+	}
+
+	info := &FuncDebug{
+		Slots:     state.slots,
+		VarSlots:  state.varSlots,
+		Registers: f.Config.registers,
+	}
+	// Consumers want the information in textual order, not by block ID.
+	for _, b := range f.Blocks {
+		info.Blocks = append(info.Blocks, blockLocs[b.ID])
+	}
+
+	if state.loggingEnabled {
+		f.Logf("Final result:\n")
+		for slot := range info.VarSlots {
+			f.Logf("\t%v => %v\n", info.Slots[slot], info.SlotLocsString(SlotID(slot)))
+		}
+	}
+	return info
+}
+
+// isSynthetic reports whether if slot represents a compiler-inserted variable,
+// e.g. an autotmp or an anonymous return value that needed a stack slot.
+func isSynthetic(slot *LocalSlot) bool {
+	c := slot.String()[0]
+	return c == '.' || c == '~'
+}
+
+// mergePredecessors takes the end state of each of b's predecessors and
+// intersects them to form the starting state for b.
+// The registers slice (the second return value) will be reused for each call to mergePredecessors.
+func (state *debugState) mergePredecessors(b *Block, blockLocs []*BlockDebug) *BlockDebug {
+	live := make([]VarLocList, len(state.slots))
+
+	// Filter out back branches.
+	var preds []*Block
+	for _, pred := range b.Preds {
+		if blockLocs[pred.b.ID] != nil {
+			preds = append(preds, pred.b)
+		}
+	}
+
+	if len(preds) > 0 {
+		p := preds[0]
+		for slot, locList := range blockLocs[p.ID].Variables {
+			last := locList.last()
+			if last == nil || last.End != BlockEnd {
+				continue
+			}
+			loc := state.cache.NewVarLoc()
+			loc.Start = BlockStart
+			loc.OnStack = last.OnStack
+			loc.StackLocation = last.StackLocation
+			loc.Registers = last.Registers
+			live[slot].append(loc)
+		}
+	}
+	if state.loggingEnabled && len(b.Preds) > 1 {
+		state.logf("Starting merge with state from %v: %v\n", b.Preds[0].b, state.BlockString(blockLocs[b.Preds[0].b.ID]))
+	}
+	for i := 1; i < len(preds); i++ {
+		p := preds[i]
+		if state.loggingEnabled {
+			state.logf("Merging in state from %v: %v &= %v\n", p, live, state.BlockString(blockLocs[p.ID]))
+		}
+
+		for slot, liveVar := range live {
+			liveLoc := liveVar.last()
+			if liveLoc == nil {
+				continue
+			}
+
+			predLoc := blockLocs[p.ID].Variables[SlotID(slot)].last()
+			// Clear out slots missing/dead in p.
+			if predLoc == nil || predLoc.End != BlockEnd {
+				live[slot].Locations = nil
+				continue
+			}
+
+			// Unify storage locations.
+			if !liveLoc.OnStack || !predLoc.OnStack || liveLoc.StackLocation != predLoc.StackLocation {
+				liveLoc.OnStack = false
+				liveLoc.StackLocation = 0
+			}
+			liveLoc.Registers &= predLoc.Registers
+		}
+	}
+
+	// Create final result.
+	locs := &BlockDebug{Variables: live}
+	if state.loggingEnabled {
+		locs.Block = b
+	}
+	for reg := range state.registerContents {
+		state.registerContents[reg] = state.registerContents[reg][:0]
+	}
+	for slot, locList := range live {
+		loc := locList.last()
+		if loc == nil {
+			continue
+		}
+		for reg := 0; reg < state.numRegisters; reg++ {
+			if loc.Registers&(1<<uint8(reg)) != 0 {
+				state.registerContents[reg] = append(state.registerContents[reg], SlotID(slot))
+			}
+		}
+	}
+	return locs
+}
+
+// processValue updates locs and state.registerContents to reflect v, a value with
+// the names in vSlots and homed in vReg.  "v" becomes visible after execution of
+// the instructions evaluating it.
+func (state *debugState) processValue(locs *BlockDebug, v *Value, vSlots []SlotID, vReg *Register) {
+	switch {
+	case v.Op == OpRegKill:
+		if state.loggingEnabled {
+			existingSlots := make([]bool, len(state.slots))
+			for _, slot := range state.registerContents[vReg.num] {
+				existingSlots[slot] = true
+			}
+			for _, slot := range vSlots {
+				if existingSlots[slot] {
+					existingSlots[slot] = false
+				} else {
+					state.unexpected(v, "regkill of unassociated name %v\n", state.slots[slot])
+				}
+			}
+			for slot, live := range existingSlots {
+				if live {
+					state.unexpected(v, "leftover register name: %v\n", state.slots[slot])
+				}
+			}
+		}
+		state.registerContents[vReg.num] = nil
+
+		for _, slot := range vSlots {
+			last := locs.lastLoc(slot)
+			if last == nil {
+				state.unexpected(v, "regkill of already dead %s, %+v\n", vReg, state.slots[slot])
+				continue
+			}
+			if state.loggingEnabled {
+				state.logf("at %v: %v regkilled out of %s\n", v.ID, state.slots[slot], vReg)
+			}
+			if last.End != nil {
+				state.unexpected(v, "regkill of dead slot, died at %v\n", last.End)
+			}
+			last.End = v
+
+			regs := last.Registers &^ (1 << uint8(vReg.num))
+			if !last.OnStack && regs == 0 {
+				continue
+			}
+			loc := state.cache.NewVarLoc()
+			loc.Start = v
+			loc.OnStack = last.OnStack
+			loc.StackLocation = last.StackLocation
+			loc.Registers = regs
+			locs.append(slot, loc)
+		}
+	case v.Op == OpArg:
+		for _, slot := range vSlots {
+			if last := locs.lastLoc(slot); last != nil {
+				state.unexpected(v, "Arg op on already-live slot %v", state.slots[slot])
+				last.End = v
+			}
+			loc := state.cache.NewVarLoc()
+			loc.Start = v
+			loc.OnStack = true
+			loc.StackLocation = state.getHomeSlot(v)
+			locs.append(slot, loc)
+			if state.loggingEnabled {
+				state.logf("at %v: arg %v now on stack in location %v\n", v.ID, state.slots[slot], state.slots[loc.StackLocation])
+			}
+		}
+
+	case v.Op == OpStoreReg:
+		for _, slot := range vSlots {
+			last := locs.lastLoc(slot)
+			if last == nil {
+				state.unexpected(v, "spill of unnamed register %s\n", vReg)
+				break
+			}
+			last.End = v
+			loc := state.cache.NewVarLoc()
+			loc.Start = v
+			loc.OnStack = true
+			loc.StackLocation = state.getHomeSlot(v)
+			loc.Registers = last.Registers
+			locs.append(slot, loc)
+			if state.loggingEnabled {
+				state.logf("at %v: %v spilled to stack location %v\n", v.ID, state.slots[slot], state.slots[loc.StackLocation])
+			}
+		}
+
+	case vReg != nil:
+		if state.loggingEnabled {
+			newSlots := make([]bool, len(state.slots))
+			for _, slot := range vSlots {
+				newSlots[slot] = true
+			}
+
+			for _, slot := range state.registerContents[vReg.num] {
+				if !newSlots[slot] {
+					state.unexpected(v, "%v clobbered\n", state.slots[slot])
+				}
+			}
+		}
+
+		for _, slot := range vSlots {
+			if state.loggingEnabled {
+				state.logf("at %v: %v now in %s\n", v.ID, state.slots[slot], vReg)
+			}
+			last := locs.lastLoc(slot)
+			if last != nil && last.End == nil {
+				last.End = v
+			}
+			state.registerContents[vReg.num] = append(state.registerContents[vReg.num], slot)
+			loc := state.cache.NewVarLoc()
+			loc.Start = v
+			if last != nil {
+				loc.OnStack = last.OnStack
+				loc.StackLocation = last.StackLocation
+				loc.Registers = last.Registers
+			}
+			loc.Registers |= 1 << uint8(vReg.num)
+			locs.append(slot, loc)
+		}
+	default:
+		state.unexpected(v, "named value with no reg\n")
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/debug_test.go b/src/cmd/compile/internal/ssa/debug_test.go
new file mode 100644
index 0000000..48dbaea
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/debug_test.go
@@ -0,0 +1,929 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa_test
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"internal/testenv"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+var update = flag.Bool("u", false, "update test reference files")
+var verbose = flag.Bool("v", false, "print debugger interactions (very verbose)")
+var dryrun = flag.Bool("n", false, "just print the command line and first debugging bits")
+var useDelve = flag.Bool("d", false, "use Delve (dlv) instead of gdb, use dlv reverence files")
+var force = flag.Bool("f", false, "force run under not linux-amd64; also do not use tempdir")
+
+var repeats = flag.Bool("r", false, "detect repeats in debug steps and don't ignore them")
+var inlines = flag.Bool("i", false, "do inlining for gdb (makes testing flaky till inlining info is correct)")
+
+var hexRe = regexp.MustCompile("0x[a-zA-Z0-9]+")
+var numRe = regexp.MustCompile("-?[0-9]+")
+var stringRe = regexp.MustCompile("\"([^\\\"]|(\\.))*\"")
+var leadingDollarNumberRe = regexp.MustCompile("^[$][0-9]+")
+var optOutGdbRe = regexp.MustCompile("[<]optimized out[>]")
+var numberColonRe = regexp.MustCompile("^ *[0-9]+:")
+
+var gdb = "gdb"      // Might be "ggdb" on Darwin, because gdb no longer part of XCode
+var debugger = "gdb" // For naming files, etc.
+
+var gogcflags = os.Getenv("GO_GCFLAGS")
+
+// optimizedLibs usually means "not running in a noopt test builder".
+var optimizedLibs = (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l"))
+
+// TestNexting go-builds a file, then uses a debugger (default gdb, optionally delve)
+// to next through the generated executable, recording each line landed at, and
+// then compares those lines with reference file(s).
+// Flag -u updates the reference file(s).
+// Flag -d changes the debugger to delve (and uses delve-specific reference files)
+// Flag -v is ever-so-slightly verbose.
+// Flag -n is for dry-run, and prints the shell and first debug commands.
+//
+// Because this test (combined with existing compiler deficiencies) is flaky,
+// for gdb-based testing by default inlining is disabled
+// (otherwise output depends on library internals)
+// and for both gdb and dlv by default repeated lines in the next stream are ignored
+// (because this appears to be timing-dependent in gdb, and the cleanest fix is in code common to gdb and dlv).
+//
+// Also by default, any source code outside of .../testdata/ is not mentioned
+// in the debugging histories.  This deals both with inlined library code once
+// the compiler is generating clean inline records, and also deals with
+// runtime code between return from main and process exit.  This is hidden
+// so that those files (in the runtime/library) can change without affecting
+// this test.
+//
+// These choices can be reversed with -i (inlining on) and -r (repeats detected) which
+// will also cause their own failures against the expected outputs.  Note that if the compiler
+// and debugger were behaving properly, the inlined code and repeated lines would not appear,
+// so the expected output is closer to what we hope to see, though it also encodes all our
+// current bugs.
+//
+// The file being tested may contain comments of the form
+// //DBG-TAG=(v1,v2,v3)
+// where DBG = {gdb,dlv} and TAG={dbg,opt}
+// each variable may optionally be followed by a / and one or more of S,A,N,O
+// to indicate normalization of Strings, (hex) addresses, and numbers.
+// "O" is an explicit indication that we expect it to be optimized out.
+// For example:
+/*
+	if len(os.Args) > 1 { //gdb-dbg=(hist/A,cannedInput/A) //dlv-dbg=(hist/A,cannedInput/A)
+*/
+// TODO: not implemented for Delve yet, but this is the plan
+//
+// After a compiler change that causes a difference in the debug behavior, check
+// to see if it is sensible or not, and if it is, update the reference files with
+// go test debug_test.go -args -u
+// (for Delve)
+// go test debug_test.go -args -u -d
+
+func TestNexting(t *testing.T) {
+	skipReasons := "" // Many possible skip reasons, list all that apply
+	if testing.Short() {
+		skipReasons = "not run in short mode; "
+	}
+	testenv.MustHaveGoBuild(t)
+
+	if !*useDelve && !*force && !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") {
+		// Running gdb on OSX/darwin is very flaky.
+		// Sometimes it is called ggdb, depending on how it is installed.
+		// It also sometimes requires an admin password typed into a dialog box.
+		// Various architectures tend to differ slightly sometimes, and keeping them
+		// all in sync is a pain for people who don't have them all at hand,
+		// so limit testing to amd64 (for now)
+		skipReasons += "not run unless linux-amd64 or -d (delve) or -f (force); "
+	}
+
+	if *useDelve {
+		debugger = "dlv"
+		_, err := exec.LookPath("dlv")
+		if err != nil {
+			skipReasons += "not run because dlv (requested by -d option) not on path; "
+		}
+	} else {
+		_, err := exec.LookPath(gdb)
+		if err != nil {
+			if runtime.GOOS != "darwin" {
+				skipReasons += "not run because gdb not on path; "
+			} else {
+				// On Darwin, MacPorts installs gdb as "ggdb".
+				_, err = exec.LookPath("ggdb")
+				if err != nil {
+					skipReasons += "not run because gdb (and also ggdb) not on path; "
+				} else {
+					gdb = "ggdb"
+				}
+			}
+		}
+	}
+
+	if skipReasons != "" {
+		t.Skip(skipReasons[:len(skipReasons)-2])
+	}
+
+	optFlags := "-dwarflocationlists"
+	if !*useDelve && !*inlines {
+		// For gdb (default), disable inlining so that a compiler test does not depend on library code.
+		// TODO: This may not be necessary with 1.10 and later.
+		optFlags += " -l"
+	}
+
+	subTest(t, debugger+"-dbg", "hist", "-N -l")
+	subTest(t, debugger+"-dbg-race", "i22600", "-N -l", "-race")
+	subTest(t, debugger+"-dbg-22558", "i22558", "-N -l")
+	optSubTest(t, debugger+"-opt", "hist", optFlags)
+}
+
+// subTest creates a subtest that compiles basename.go with the specified gcflags and additional compiler arguments,
+// then runs the debugger on the resulting binary, with any comment-specified actions matching tag triggered.
+func subTest(t *testing.T, tag string, basename string, gcflags string, moreargs ...string) {
+	t.Run(tag, func(t *testing.T) {
+		testNexting(t, basename, tag, gcflags, moreargs...)
+	})
+}
+
+// optSubTest is the same as subTest except that it skips the test if the runtime and libraries
+// were not compiled with optimization turned on.  (The skip may not be necessary with Go 1.10 and later)
+func optSubTest(t *testing.T, tag string, basename string, gcflags string, moreargs ...string) {
+	// If optimized test is run with unoptimized libraries (compiled with -N -l), it is very likely to fail.
+	// This occurs in the noopt builders (for example).
+	t.Run(tag, func(t *testing.T) {
+		if *force || optimizedLibs {
+			testNexting(t, basename, tag, gcflags, moreargs...)
+		} else {
+			t.Skip("skipping for unoptimized stdlib/runtime")
+		}
+	})
+}
+
+func testNexting(t *testing.T, base, tag, gcflags string, moreArgs ...string) {
+	// (1) In testdata, build sample.go into test-sample.<tag>
+	// (2) Run debugger gathering a history
+	// (3) Read expected history from testdata/sample.<tag>.nexts
+	// optionally, write out testdata/sample.<tag>.nexts
+
+	testbase := filepath.Join("testdata", base) + "." + tag
+	tmpbase := filepath.Join("testdata", "test-"+base+"."+tag)
+
+	// Use a temporary directory unless -f is specified
+	if !*force {
+		tmpdir, err := ioutil.TempDir("", "debug_test")
+		if err != nil {
+			panic(fmt.Sprintf("Problem creating TempDir, error %v\n", err))
+		}
+		tmpbase = filepath.Join(tmpdir, "test-"+base+"."+tag)
+		if *verbose {
+			fmt.Printf("Tempdir is %s\n", tmpdir)
+		}
+		defer os.RemoveAll(tmpdir)
+	}
+	exe := tmpbase
+
+	runGoArgs := []string{"build", "-o", exe, "-gcflags=all=" + gcflags}
+	runGoArgs = append(runGoArgs, moreArgs...)
+	runGoArgs = append(runGoArgs, filepath.Join("testdata", base+".go"))
+
+	runGo(t, "", runGoArgs...)
+
+	nextlog := testbase + ".nexts"
+	tmplog := tmpbase + ".nexts"
+	var dbg dbgr
+	if *useDelve {
+		dbg = newDelve(tag, exe)
+	} else {
+		dbg = newGdb(tag, exe)
+	}
+	h1 := runDbgr(dbg, 1000)
+	if *dryrun {
+		fmt.Printf("# Tag for above is %s\n", dbg.tag())
+		return
+	}
+	if *update {
+		h1.write(nextlog)
+	} else {
+		h0 := &nextHist{}
+		h0.read(nextlog)
+		if !h0.equals(h1) {
+			// Be very noisy about exactly what's wrong to simplify debugging.
+			h1.write(tmplog)
+			cmd := exec.Command("diff", "-u", nextlog, tmplog)
+			line := asCommandLine("", cmd)
+			bytes, err := cmd.CombinedOutput()
+			if err != nil && len(bytes) == 0 {
+				t.Fatalf("step/next histories differ, diff command %s failed with error=%v", line, err)
+			}
+			t.Fatalf("step/next histories differ, diff=\n%s", string(bytes))
+		}
+	}
+}
+
+type dbgr interface {
+	start()
+	stepnext(s string) bool // step or next, possible with parameter, gets line etc.  returns true for success, false for unsure response
+	quit()
+	hist() *nextHist
+	tag() string
+}
+
+func runDbgr(dbg dbgr, maxNext int) *nextHist {
+	dbg.start()
+	if *dryrun {
+		return nil
+	}
+	for i := 0; i < maxNext; i++ {
+		if !dbg.stepnext("n") {
+			break
+		}
+	}
+	h := dbg.hist()
+	return h
+}
+
+func runGo(t *testing.T, dir string, args ...string) string {
+	var stdout, stderr bytes.Buffer
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	cmd.Dir = dir
+	if *dryrun {
+		fmt.Printf("%s\n", asCommandLine("", cmd))
+		return ""
+	}
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+
+	if err := cmd.Run(); err != nil {
+		t.Fatalf("error running cmd (%s): %v\nstdout:\n%sstderr:\n%s\n", asCommandLine("", cmd), err, stdout.String(), stderr.String())
+	}
+
+	if s := stderr.String(); s != "" {
+		t.Fatalf("Stderr = %s\nWant empty", s)
+	}
+
+	return stdout.String()
+}
+
+// tstring provides two strings, o (stdout) and e (stderr)
+type tstring struct {
+	o string
+	e string
+}
+
+func (t tstring) String() string {
+	return t.o + t.e
+}
+
+type pos struct {
+	line uint16
+	file uint8 // Artifact of plans to implement differencing instead of calling out to diff.
+}
+
+type nextHist struct {
+	f2i   map[string]uint8
+	fs    []string
+	ps    []pos
+	texts []string
+	vars  [][]string
+}
+
+func (h *nextHist) write(filename string) {
+	file, err := os.Create(filename)
+	if err != nil {
+		panic(fmt.Sprintf("Problem opening %s, error %v\n", filename, err))
+	}
+	defer file.Close()
+	var lastfile uint8
+	for i, x := range h.texts {
+		p := h.ps[i]
+		if lastfile != p.file {
+			fmt.Fprintf(file, "  %s\n", h.fs[p.file-1])
+			lastfile = p.file
+		}
+		fmt.Fprintf(file, "%d:%s\n", p.line, x)
+		// TODO, normalize between gdb and dlv into a common, comparable format.
+		for _, y := range h.vars[i] {
+			y = strings.TrimSpace(y)
+			fmt.Fprintf(file, "%s\n", y)
+		}
+	}
+	file.Close()
+}
+
+func (h *nextHist) read(filename string) {
+	h.f2i = make(map[string]uint8)
+	bytes, err := ioutil.ReadFile(filename)
+	if err != nil {
+		panic(fmt.Sprintf("Problem reading %s, error %v\n", filename, err))
+	}
+	var lastfile string
+	lines := strings.Split(string(bytes), "\n")
+	for i, l := range lines {
+		if len(l) > 0 && l[0] != '#' {
+			if l[0] == ' ' {
+				// file -- first two characters expected to be "  "
+				lastfile = strings.TrimSpace(l)
+			} else if numberColonRe.MatchString(l) {
+				// line number -- <number>:<line>
+				colonPos := strings.Index(l, ":")
+				if colonPos == -1 {
+					panic(fmt.Sprintf("Line %d (%s) in file %s expected to contain '<number>:' but does not.\n", i+1, l, filename))
+				}
+				h.add(lastfile, l[0:colonPos], l[colonPos+1:])
+			} else {
+				h.addVar(l)
+			}
+		}
+	}
+}
+
+// add appends file (name), line (number) and text (string) to the history,
+// provided that the file+line combo does not repeat the previous position,
+// and provided that the file is within the testdata directory.  The return
+// value indicates whether the append occurred.
+func (h *nextHist) add(file, line, text string) bool {
+	// Only record source code in testdata unless the inlines flag is set
+	if !*inlines && !strings.Contains(file, "/testdata/") {
+		return false
+	}
+	fi := h.f2i[file]
+	if fi == 0 {
+		h.fs = append(h.fs, file)
+		fi = uint8(len(h.fs))
+		h.f2i[file] = fi
+	}
+
+	line = strings.TrimSpace(line)
+	var li int
+	var err error
+	if line != "" {
+		li, err = strconv.Atoi(line)
+		if err != nil {
+			panic(fmt.Sprintf("Non-numeric line: %s, error %v\n", line, err))
+		}
+	}
+	l := len(h.ps)
+	p := pos{line: uint16(li), file: fi}
+
+	if l == 0 || *repeats || h.ps[l-1] != p {
+		h.ps = append(h.ps, p)
+		h.texts = append(h.texts, text)
+		h.vars = append(h.vars, []string{})
+		return true
+	}
+	return false
+}
+
+func (h *nextHist) addVar(text string) {
+	l := len(h.texts)
+	h.vars[l-1] = append(h.vars[l-1], text)
+}
+
+func invertMapSU8(hf2i map[string]uint8) map[uint8]string {
+	hi2f := make(map[uint8]string)
+	for hs, i := range hf2i {
+		hi2f[i] = hs
+	}
+	return hi2f
+}
+
+func (h *nextHist) equals(k *nextHist) bool {
+	if len(h.f2i) != len(k.f2i) {
+		return false
+	}
+	if len(h.ps) != len(k.ps) {
+		return false
+	}
+	hi2f := invertMapSU8(h.f2i)
+	ki2f := invertMapSU8(k.f2i)
+
+	for i, hs := range hi2f {
+		if hs != ki2f[i] {
+			return false
+		}
+	}
+
+	for i, x := range h.ps {
+		if k.ps[i] != x {
+			return false
+		}
+	}
+
+	for i, hv := range h.vars {
+		kv := k.vars[i]
+		if len(hv) != len(kv) {
+			return false
+		}
+		for j, hvt := range hv {
+			if hvt != kv[j] {
+				return false
+			}
+		}
+	}
+
+	return true
+}
+
+// canonFileName strips everything before "/src/" from a filename.
+// This makes file names portable across different machines,
+// home directories, and temporary directories.
+func canonFileName(f string) string {
+	i := strings.Index(f, "/src/")
+	if i != -1 {
+		f = f[i+1:]
+	}
+	return f
+}
+
+/* Delve */
+
+type delveState struct {
+	cmd  *exec.Cmd
+	tagg string
+	*ioState
+	atLineRe         *regexp.Regexp // "\n =>"
+	funcFileLinePCre *regexp.Regexp // "^> ([^ ]+) ([^:]+):([0-9]+) .*[(]PC: (0x[a-z0-9]+)"
+	line             string
+	file             string
+	function         string
+}
+
+func newDelve(tag, executable string, args ...string) dbgr {
+	cmd := exec.Command("dlv", "exec", executable)
+	cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
+	if len(args) > 0 {
+		cmd.Args = append(cmd.Args, "--")
+		cmd.Args = append(cmd.Args, args...)
+	}
+	s := &delveState{tagg: tag, cmd: cmd}
+	// HAHA Delve has control characters embedded to change the color of the => and the line number
+	// that would be '(\\x1b\\[[0-9;]+m)?' OR TERM=dumb
+	s.atLineRe = regexp.MustCompile("\n=>[[:space:]]+[0-9]+:(.*)")
+	s.funcFileLinePCre = regexp.MustCompile("> ([^ ]+) ([^:]+):([0-9]+) .*[(]PC: (0x[a-z0-9]+)[)]\n")
+	s.ioState = newIoState(s.cmd)
+	return s
+}
+
+func (s *delveState) tag() string {
+	return s.tagg
+}
+
+func (s *delveState) stepnext(ss string) bool {
+	x := s.ioState.writeReadExpect(ss+"\n", "[(]dlv[)] ")
+	excerpts := s.atLineRe.FindStringSubmatch(x.o)
+	locations := s.funcFileLinePCre.FindStringSubmatch(x.o)
+	excerpt := ""
+	if len(excerpts) > 1 {
+		excerpt = excerpts[1]
+	}
+	if len(locations) > 0 {
+		fn := canonFileName(locations[2])
+		if *verbose {
+			if s.file != fn {
+				fmt.Printf("%s\n", locations[2]) // don't canonocalize verbose logging
+			}
+			fmt.Printf("  %s\n", locations[3])
+		}
+		s.line = locations[3]
+		s.file = fn
+		s.function = locations[1]
+		s.ioState.history.add(s.file, s.line, excerpt)
+		// TODO: here is where variable processing will be added.  See gdbState.stepnext as a guide.
+		// Adding this may require some amount of normalization so that logs are comparable.
+		return true
+	}
+	if *verbose {
+		fmt.Printf("DID NOT MATCH EXPECTED NEXT OUTPUT\nO='%s'\nE='%s'\n", x.o, x.e)
+	}
+	return false
+}
+
+func (s *delveState) start() {
+	if *dryrun {
+		fmt.Printf("%s\n", asCommandLine("", s.cmd))
+		fmt.Printf("b main.test\n")
+		fmt.Printf("c\n")
+		return
+	}
+	err := s.cmd.Start()
+	if err != nil {
+		line := asCommandLine("", s.cmd)
+		panic(fmt.Sprintf("There was an error [start] running '%s', %v\n", line, err))
+	}
+	s.ioState.readExpecting(-1, 5000, "Type 'help' for list of commands.")
+	expect("Breakpoint [0-9]+ set at ", s.ioState.writeReadExpect("b main.test\n", "[(]dlv[)] "))
+	s.stepnext("c")
+}
+
+func (s *delveState) quit() {
+	expect("", s.ioState.writeRead("q\n"))
+}
+
+/* Gdb */
+
+type gdbState struct {
+	cmd  *exec.Cmd
+	tagg string
+	args []string
+	*ioState
+	atLineRe         *regexp.Regexp
+	funcFileLinePCre *regexp.Regexp
+	line             string
+	file             string
+	function         string
+}
+
+func newGdb(tag, executable string, args ...string) dbgr {
+	// Turn off shell, necessary for Darwin apparently
+	cmd := exec.Command(gdb, "-ex", "set startup-with-shell off", executable)
+	cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
+	s := &gdbState{tagg: tag, cmd: cmd, args: args}
+	s.atLineRe = regexp.MustCompile("(^|\n)([0-9]+)(.*)")
+	s.funcFileLinePCre = regexp.MustCompile(
+		"([^ ]+) [(][^)]*[)][ \\t\\n]+at ([^:]+):([0-9]+)")
+	// runtime.main () at /Users/drchase/GoogleDrive/work/go/src/runtime/proc.go:201
+	//                                    function              file    line
+	// Thread 2 hit Breakpoint 1, main.main () at /Users/drchase/GoogleDrive/work/debug/hist.go:18
+	s.ioState = newIoState(s.cmd)
+	return s
+}
+
+func (s *gdbState) tag() string {
+	return s.tagg
+}
+
+func (s *gdbState) start() {
+	run := "run"
+	for _, a := range s.args {
+		run += " " + a // Can't quote args for gdb, it will pass them through including the quotes
+	}
+	if *dryrun {
+		fmt.Printf("%s\n", asCommandLine("", s.cmd))
+		fmt.Printf("tbreak main.test\n")
+		fmt.Printf("%s\n", run)
+		return
+	}
+	err := s.cmd.Start()
+	if err != nil {
+		line := asCommandLine("", s.cmd)
+		panic(fmt.Sprintf("There was an error [start] running '%s', %v\n", line, err))
+	}
+	s.ioState.readExpecting(-1, -1, "[(]gdb[)] ")
+	x := s.ioState.writeReadExpect("b main.test\n", "[(]gdb[)] ")
+	expect("Breakpoint [0-9]+ at", x)
+	s.stepnext(run)
+}
+
+func (s *gdbState) stepnext(ss string) bool {
+	x := s.ioState.writeReadExpect(ss+"\n", "[(]gdb[)] ")
+	excerpts := s.atLineRe.FindStringSubmatch(x.o)
+	locations := s.funcFileLinePCre.FindStringSubmatch(x.o)
+	excerpt := ""
+	addedLine := false
+	if len(excerpts) == 0 && len(locations) == 0 {
+		if *verbose {
+			fmt.Printf("DID NOT MATCH %s", x.o)
+		}
+		return false
+	}
+	if len(excerpts) > 0 {
+		excerpt = excerpts[3]
+	}
+	if len(locations) > 0 {
+		fn := canonFileName(locations[2])
+		if *verbose {
+			if s.file != fn {
+				fmt.Printf("%s\n", locations[2])
+			}
+			fmt.Printf("  %s\n", locations[3])
+		}
+		s.line = locations[3]
+		s.file = fn
+		s.function = locations[1]
+		addedLine = s.ioState.history.add(s.file, s.line, excerpt)
+	}
+	if len(excerpts) > 0 {
+		if *verbose {
+			fmt.Printf("  %s\n", excerpts[2])
+		}
+		s.line = excerpts[2]
+		addedLine = s.ioState.history.add(s.file, s.line, excerpt)
+	}
+
+	if !addedLine {
+		// True if this was a repeat line
+		return true
+	}
+	// Look for //gdb-<tag>=(v1,v2,v3) and print v1, v2, v3
+	vars := varsToPrint(excerpt, "//"+s.tag()+"=(")
+	for _, v := range vars {
+		response := printVariableAndNormalize(v, func(v string) string {
+			return s.ioState.writeReadExpect("p "+v+"\n", "[(]gdb[)] ").String()
+		})
+		s.ioState.history.addVar(response)
+	}
+	return true
+}
+
+// printVariableAndNormalize extracts any slash-indicated normalizing requests from the variable
+// name, then uses printer to get the value of the variable from the debugger, and then
+// normalizes and returns the response.
+func printVariableAndNormalize(v string, printer func(v string) string) string {
+	slashIndex := strings.Index(v, "/")
+	substitutions := ""
+	if slashIndex != -1 {
+		substitutions = v[slashIndex:]
+		v = v[:slashIndex]
+	}
+	response := printer(v)
+	// expect something like "$1 = ..."
+	dollar := strings.Index(response, "$")
+	cr := strings.Index(response, "\n")
+
+	if dollar == -1 { // some not entirely expected response, whine and carry on.
+		if cr == -1 {
+			response = strings.TrimSpace(response) // discards trailing newline
+			response = strings.Replace(response, "\n", "<BR>", -1)
+			return "$ Malformed response " + response
+		}
+		response = strings.TrimSpace(response[:cr])
+		return "$ " + response
+	}
+	if cr == -1 {
+		cr = len(response)
+	}
+	// Convert the leading $<number> into the variable name to enhance readability
+	// and reduce scope of diffs if an earlier print-variable is added.
+	response = strings.TrimSpace(response[dollar:cr])
+	response = leadingDollarNumberRe.ReplaceAllString(response, v)
+
+	// Normalize value as requested.
+	if strings.Contains(substitutions, "A") {
+		response = hexRe.ReplaceAllString(response, "<A>")
+	}
+	if strings.Contains(substitutions, "N") {
+		response = numRe.ReplaceAllString(response, "<N>")
+	}
+	if strings.Contains(substitutions, "S") {
+		response = stringRe.ReplaceAllString(response, "<S>")
+	}
+	if strings.Contains(substitutions, "O") {
+		response = optOutGdbRe.ReplaceAllString(response, "<Optimized out, as expected>")
+	}
+	return response
+}
+
+// varsToPrint takes a source code line, and extracts the comma-separated variable names
+// found between lookfor and the next ")".
+// For example, if line includes "... //gdb-foo=(v1,v2,v3)" and
+// lookfor="//gdb-foo=(", then varsToPrint returns ["v1", "v2", "v3"]
+func varsToPrint(line, lookfor string) []string {
+	var vars []string
+	if strings.Contains(line, lookfor) {
+		x := line[strings.Index(line, lookfor)+len(lookfor):]
+		end := strings.Index(x, ")")
+		if end == -1 {
+			panic(fmt.Sprintf("Saw variable list begin %s in %s but no closing ')'", lookfor, line))
+		}
+		vars = strings.Split(x[:end], ",")
+		for i, y := range vars {
+			vars[i] = strings.TrimSpace(y)
+		}
+	}
+	return vars
+}
+
+func (s *gdbState) quit() {
+	response := s.ioState.writeRead("q\n")
+	if strings.Contains(response.o, "Quit anyway? (y or n)") {
+		s.ioState.writeRead("Y\n")
+	}
+}
+
+type ioState struct {
+	stdout  io.ReadCloser
+	stderr  io.ReadCloser
+	stdin   io.WriteCloser
+	outChan chan string
+	errChan chan string
+	last    tstring // Output of previous step
+	history *nextHist
+}
+
+func newIoState(cmd *exec.Cmd) *ioState {
+	var err error
+	s := &ioState{}
+	s.history = &nextHist{}
+	s.history.f2i = make(map[string]uint8)
+	s.stdout, err = cmd.StdoutPipe()
+	line := asCommandLine("", cmd)
+	if err != nil {
+		panic(fmt.Sprintf("There was an error [stdoutpipe] running '%s', %v\n", line, err))
+	}
+	s.stderr, err = cmd.StderrPipe()
+	if err != nil {
+		panic(fmt.Sprintf("There was an error [stdouterr] running '%s', %v\n", line, err))
+	}
+	s.stdin, err = cmd.StdinPipe()
+	if err != nil {
+		panic(fmt.Sprintf("There was an error [stdinpipe] running '%s', %v\n", line, err))
+	}
+
+	s.outChan = make(chan string, 1)
+	s.errChan = make(chan string, 1)
+	go func() {
+		buffer := make([]byte, 4096)
+		for {
+			n, err := s.stdout.Read(buffer)
+			if n > 0 {
+				s.outChan <- string(buffer[0:n])
+			}
+			if err == io.EOF || n == 0 {
+				break
+			}
+			if err != nil {
+				fmt.Printf("Saw an error forwarding stdout")
+				break
+			}
+		}
+		close(s.outChan)
+		s.stdout.Close()
+	}()
+
+	go func() {
+		buffer := make([]byte, 4096)
+		for {
+			n, err := s.stderr.Read(buffer)
+			if n > 0 {
+				s.errChan <- string(buffer[0:n])
+			}
+			if err == io.EOF || n == 0 {
+				break
+			}
+			if err != nil {
+				fmt.Printf("Saw an error forwarding stderr")
+				break
+			}
+		}
+		close(s.errChan)
+		s.stderr.Close()
+	}()
+	return s
+}
+
+func (s *ioState) hist() *nextHist {
+	return s.history
+}
+
+// writeRead writes ss, then reads stdout and stderr, waiting 500ms to
+// be sure all the output has appeared.
+func (s *ioState) writeRead(ss string) tstring {
+	if *verbose {
+		fmt.Printf("=> %s", ss)
+	}
+	_, err := io.WriteString(s.stdin, ss)
+	if err != nil {
+		panic(fmt.Sprintf("There was an error writing '%s', %v\n", ss, err))
+	}
+	return s.readExpecting(-1, 500, "")
+}
+
+// writeReadExpect writes ss, then reads stdout and stderr until something
+// that matches expectRE appears.  expectRE should not be ""
+func (s *ioState) writeReadExpect(ss, expectRE string) tstring {
+	if *verbose {
+		fmt.Printf("=> %s", ss)
+	}
+	if expectRE == "" {
+		panic("expectRE should not be empty; use .* instead")
+	}
+	_, err := io.WriteString(s.stdin, ss)
+	if err != nil {
+		panic(fmt.Sprintf("There was an error writing '%s', %v\n", ss, err))
+	}
+	return s.readExpecting(-1, -1, expectRE)
+}
+
+func (s *ioState) readExpecting(millis, interlineTimeout int, expectedRE string) tstring {
+	timeout := time.Millisecond * time.Duration(millis)
+	interline := time.Millisecond * time.Duration(interlineTimeout)
+	s.last = tstring{}
+	var re *regexp.Regexp
+	if expectedRE != "" {
+		re = regexp.MustCompile(expectedRE)
+	}
+loop:
+	for {
+		var timer <-chan time.Time
+		if timeout > 0 {
+			timer = time.After(timeout)
+		}
+		select {
+		case x, ok := <-s.outChan:
+			if !ok {
+				s.outChan = nil
+			}
+			s.last.o += x
+		case x, ok := <-s.errChan:
+			if !ok {
+				s.errChan = nil
+			}
+			s.last.e += x
+		case <-timer:
+			break loop
+		}
+		if re != nil {
+			if re.MatchString(s.last.o) {
+				break
+			}
+			if re.MatchString(s.last.e) {
+				break
+			}
+		}
+		timeout = interline
+	}
+	if *verbose {
+		fmt.Printf("<= %s%s", s.last.o, s.last.e)
+	}
+	return s.last
+}
+
+// replaceEnv returns a new environment derived from env
+// by removing any existing definition of ev and adding ev=evv.
+func replaceEnv(env []string, ev string, evv string) []string {
+	evplus := ev + "="
+	var found bool
+	for i, v := range env {
+		if strings.HasPrefix(v, evplus) {
+			found = true
+			env[i] = evplus + evv
+		}
+	}
+	if !found {
+		env = append(env, evplus+evv)
+	}
+	return env
+}
+
+// asCommandLine renders cmd as something that could be copy-and-pasted into a command line
+// If cwd is not empty and different from the command's directory, prepend an approprirate "cd"
+func asCommandLine(cwd string, cmd *exec.Cmd) string {
+	s := "("
+	if cmd.Dir != "" && cmd.Dir != cwd {
+		s += "cd" + escape(cmd.Dir) + ";"
+	}
+	for _, e := range cmd.Env {
+		if !strings.HasPrefix(e, "PATH=") &&
+			!strings.HasPrefix(e, "HOME=") &&
+			!strings.HasPrefix(e, "USER=") &&
+			!strings.HasPrefix(e, "SHELL=") {
+			s += escape(e)
+		}
+	}
+	for _, a := range cmd.Args {
+		s += escape(a)
+	}
+	s += " )"
+	return s
+}
+
+// escape inserts escapes appropriate for use in a shell command line
+func escape(s string) string {
+	s = strings.Replace(s, "\\", "\\\\", -1)
+	s = strings.Replace(s, "'", "\\'", -1)
+	// Conservative guess at characters that will force quoting
+	if strings.ContainsAny(s, "\\ ;#*&$~?!|[]()<>{}`") {
+		s = " '" + s + "'"
+	} else {
+		s = " " + s
+	}
+	return s
+}
+
+func expect(want string, got tstring) {
+	if want != "" {
+		match, err := regexp.MatchString(want, got.o)
+		if err != nil {
+			panic(fmt.Sprintf("Error for regexp %s, %v\n", want, err))
+		}
+		if match {
+			return
+		}
+		match, err = regexp.MatchString(want, got.e)
+		if match {
+			return
+		}
+		fmt.Printf("EXPECTED '%s'\n GOT O='%s'\nAND E='%s'\n", want, got.o, got.e)
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index 2b3f16c..0cabfb6 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -4,12 +4,15 @@
 
 package ssa
 
-import "cmd/compile/internal/types"
+import (
+	"cmd/compile/internal/types"
+)
 
 // decompose converts phi ops on compound builtin types into phi
-// ops on simple types.
-// (The remaining compound ops are decomposed with rewrite rules.)
+// ops on simple types, then invokes rewrite rules to decompose
+// other ops on those types.
 func decomposeBuiltIn(f *Func) {
+	// Decompose phis
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			if v.Op != OpPhi {
@@ -19,87 +22,79 @@
 		}
 	}
 
+	// Decompose other values
+	applyRewrite(f, rewriteBlockdec, rewriteValuedec)
+	if f.Config.RegSize == 4 {
+		applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
+	}
+
 	// Split up named values into their components.
-	// NOTE: the component values we are making are dead at this point.
-	// We must do the opt pass before any deadcode elimination or we will
-	// lose the name->value correspondence.
 	var newNames []LocalSlot
 	for _, name := range f.Names {
 		t := name.Type
 		switch {
 		case t.IsInteger() && t.Size() > f.Config.RegSize:
-			var elemType *types.Type
-			if t.IsSigned() {
-				elemType = f.Config.Types.Int32
-			} else {
-				elemType = f.Config.Types.UInt32
-			}
 			hiName, loName := f.fe.SplitInt64(name)
 			newNames = append(newNames, hiName, loName)
 			for _, v := range f.NamedValues[name] {
-				hi := v.Block.NewValue1(v.Pos, OpInt64Hi, elemType, v)
-				lo := v.Block.NewValue1(v.Pos, OpInt64Lo, f.Config.Types.UInt32, v)
-				f.NamedValues[hiName] = append(f.NamedValues[hiName], hi)
-				f.NamedValues[loName] = append(f.NamedValues[loName], lo)
+				if v.Op != OpInt64Make {
+					continue
+				}
+				f.NamedValues[hiName] = append(f.NamedValues[hiName], v.Args[0])
+				f.NamedValues[loName] = append(f.NamedValues[loName], v.Args[1])
 			}
 			delete(f.NamedValues, name)
 		case t.IsComplex():
-			var elemType *types.Type
-			if t.Size() == 16 {
-				elemType = f.Config.Types.Float64
-			} else {
-				elemType = f.Config.Types.Float32
-			}
 			rName, iName := f.fe.SplitComplex(name)
 			newNames = append(newNames, rName, iName)
 			for _, v := range f.NamedValues[name] {
-				r := v.Block.NewValue1(v.Pos, OpComplexReal, elemType, v)
-				i := v.Block.NewValue1(v.Pos, OpComplexImag, elemType, v)
-				f.NamedValues[rName] = append(f.NamedValues[rName], r)
-				f.NamedValues[iName] = append(f.NamedValues[iName], i)
+				if v.Op != OpComplexMake {
+					continue
+				}
+				f.NamedValues[rName] = append(f.NamedValues[rName], v.Args[0])
+				f.NamedValues[iName] = append(f.NamedValues[iName], v.Args[1])
+
 			}
 			delete(f.NamedValues, name)
 		case t.IsString():
-			ptrType := f.Config.Types.BytePtr
-			lenType := f.Config.Types.Int
 			ptrName, lenName := f.fe.SplitString(name)
 			newNames = append(newNames, ptrName, lenName)
 			for _, v := range f.NamedValues[name] {
-				ptr := v.Block.NewValue1(v.Pos, OpStringPtr, ptrType, v)
-				len := v.Block.NewValue1(v.Pos, OpStringLen, lenType, v)
-				f.NamedValues[ptrName] = append(f.NamedValues[ptrName], ptr)
-				f.NamedValues[lenName] = append(f.NamedValues[lenName], len)
+				if v.Op != OpStringMake {
+					continue
+				}
+				f.NamedValues[ptrName] = append(f.NamedValues[ptrName], v.Args[0])
+				f.NamedValues[lenName] = append(f.NamedValues[lenName], v.Args[1])
 			}
 			delete(f.NamedValues, name)
 		case t.IsSlice():
-			ptrType := f.Config.Types.BytePtr
-			lenType := f.Config.Types.Int
 			ptrName, lenName, capName := f.fe.SplitSlice(name)
 			newNames = append(newNames, ptrName, lenName, capName)
 			for _, v := range f.NamedValues[name] {
-				ptr := v.Block.NewValue1(v.Pos, OpSlicePtr, ptrType, v)
-				len := v.Block.NewValue1(v.Pos, OpSliceLen, lenType, v)
-				cap := v.Block.NewValue1(v.Pos, OpSliceCap, lenType, v)
-				f.NamedValues[ptrName] = append(f.NamedValues[ptrName], ptr)
-				f.NamedValues[lenName] = append(f.NamedValues[lenName], len)
-				f.NamedValues[capName] = append(f.NamedValues[capName], cap)
+				if v.Op != OpSliceMake {
+					continue
+				}
+				f.NamedValues[ptrName] = append(f.NamedValues[ptrName], v.Args[0])
+				f.NamedValues[lenName] = append(f.NamedValues[lenName], v.Args[1])
+				f.NamedValues[capName] = append(f.NamedValues[capName], v.Args[2])
 			}
 			delete(f.NamedValues, name)
 		case t.IsInterface():
-			ptrType := f.Config.Types.BytePtr
 			typeName, dataName := f.fe.SplitInterface(name)
 			newNames = append(newNames, typeName, dataName)
 			for _, v := range f.NamedValues[name] {
-				typ := v.Block.NewValue1(v.Pos, OpITab, ptrType, v)
-				data := v.Block.NewValue1(v.Pos, OpIData, ptrType, v)
-				f.NamedValues[typeName] = append(f.NamedValues[typeName], typ)
-				f.NamedValues[dataName] = append(f.NamedValues[dataName], data)
+				if v.Op != OpIMake {
+					continue
+				}
+				f.NamedValues[typeName] = append(f.NamedValues[typeName], v.Args[0])
+				f.NamedValues[dataName] = append(f.NamedValues[dataName], v.Args[1])
 			}
 			delete(f.NamedValues, name)
 		case t.IsFloat():
 			// floats are never decomposed, even ones bigger than RegSize
+			newNames = append(newNames, name)
 		case t.Size() > f.Config.RegSize:
-			f.Fatalf("undecomposed named type %v %v", name, t)
+			f.Fatalf("undecomposed named type %s %v", name, t)
 		default:
 			newNames = append(newNames, name)
 		}
@@ -228,44 +223,15 @@
 		}
 	}
 	// Split up named values into their components.
-	// NOTE: the component values we are making are dead at this point.
-	// We must do the opt pass before any deadcode elimination or we will
-	// lose the name->value correspondence.
 	i := 0
-	var fnames []LocalSlot
 	var newNames []LocalSlot
 	for _, name := range f.Names {
 		t := name.Type
 		switch {
 		case t.IsStruct():
-			n := t.NumFields()
-			fnames = fnames[:0]
-			for i := 0; i < n; i++ {
-				fnames = append(fnames, f.fe.SplitStruct(name, i))
-			}
-			for _, v := range f.NamedValues[name] {
-				for i := 0; i < n; i++ {
-					x := v.Block.NewValue1I(v.Pos, OpStructSelect, t.FieldType(i), int64(i), v)
-					f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], x)
-				}
-			}
-			delete(f.NamedValues, name)
-			newNames = append(newNames, fnames...)
+			newNames = decomposeUserStructInto(f, name, newNames)
 		case t.IsArray():
-			if t.NumElem() == 0 {
-				// TODO(khr): Not sure what to do here.  Probably nothing.
-				// Names for empty arrays aren't important.
-				break
-			}
-			if t.NumElem() != 1 {
-				f.Fatalf("array not of size 1")
-			}
-			elemName := f.fe.SplitArray(name)
-			for _, v := range f.NamedValues[name] {
-				e := v.Block.NewValue1I(v.Pos, OpArraySelect, t.ElemType(), 0, v)
-				f.NamedValues[elemName] = append(f.NamedValues[elemName], e)
-			}
-
+			newNames = decomposeUserArrayInto(f, name, newNames)
 		default:
 			f.Names[i] = name
 			i++
@@ -275,6 +241,83 @@
 	f.Names = append(f.Names, newNames...)
 }
 
+// decomposeUserArrayInto creates names for the element(s) of arrays referenced
+// by name where possible, and appends those new names to slots, which is then
+// returned.
+func decomposeUserArrayInto(f *Func, name LocalSlot, slots []LocalSlot) []LocalSlot {
+	t := name.Type
+	if t.NumElem() == 0 {
+		// TODO(khr): Not sure what to do here.  Probably nothing.
+		// Names for empty arrays aren't important.
+		return slots
+	}
+	if t.NumElem() != 1 {
+		// shouldn't get here due to CanSSA
+		f.Fatalf("array not of size 1")
+	}
+	elemName := f.fe.SplitArray(name)
+	for _, v := range f.NamedValues[name] {
+		if v.Op != OpArrayMake1 {
+			continue
+		}
+		f.NamedValues[elemName] = append(f.NamedValues[elemName], v.Args[0])
+	}
+	// delete the name for the array as a whole
+	delete(f.NamedValues, name)
+
+	if t.ElemType().IsArray() {
+		return decomposeUserArrayInto(f, elemName, slots)
+	} else if t.ElemType().IsStruct() {
+		return decomposeUserStructInto(f, elemName, slots)
+	}
+
+	return append(slots, elemName)
+}
+
+// decomposeUserStructInto creates names for the fields(s) of structs referenced
+// by name where possible, and appends those new names to slots, which is then
+// returned.
+func decomposeUserStructInto(f *Func, name LocalSlot, slots []LocalSlot) []LocalSlot {
+	fnames := []LocalSlot{} // slots for struct in name
+	t := name.Type
+	n := t.NumFields()
+
+	for i := 0; i < n; i++ {
+		fs := f.fe.SplitStruct(name, i)
+		fnames = append(fnames, fs)
+		// arrays and structs will be decomposed further, so
+		// there's no need to record a name
+		if !fs.Type.IsArray() && !fs.Type.IsStruct() {
+			slots = append(slots, fs)
+		}
+	}
+
+	makeOp := StructMakeOp(n)
+	// create named values for each struct field
+	for _, v := range f.NamedValues[name] {
+		if v.Op != makeOp {
+			continue
+		}
+		for i := 0; i < len(fnames); i++ {
+			f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], v.Args[i])
+		}
+	}
+	// remove the name of the struct as a whole
+	delete(f.NamedValues, name)
+
+	// now that this f.NamedValues contains values for the struct
+	// fields, recurse into nested structs
+	for i := 0; i < n; i++ {
+		if name.Type.FieldType(i).IsStruct() {
+			slots = decomposeUserStructInto(f, fnames[i], slots)
+			delete(f.NamedValues, fnames[i])
+		} else if name.Type.FieldType(i).IsArray() {
+			slots = decomposeUserArrayInto(f, fnames[i], slots)
+			delete(f.NamedValues, fnames[i])
+		}
+	}
+	return slots
+}
 func decomposeUserPhi(v *Value) {
 	switch {
 	case v.Type.IsStruct():
diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go
index 3bb67a9..28ae494 100644
--- a/src/cmd/compile/internal/ssa/export_test.go
+++ b/src/cmd/compile/internal/ssa/export_test.go
@@ -75,6 +75,10 @@
 	return d.s
 }
 
+func (d *DummyAuto) StorageClass() StorageClass {
+	return ClassAuto
+}
+
 func (DummyFrontend) StringData(s string) interface{} {
 	return nil
 }
@@ -82,33 +86,33 @@
 	return &DummyAuto{t: t, s: "aDummyAuto"}
 }
 func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
-	return LocalSlot{s.N, dummyTypes.BytePtr, s.Off}, LocalSlot{s.N, dummyTypes.Int, s.Off + 8}
+	return LocalSlot{N: s.N, Type: dummyTypes.BytePtr, Off: s.Off}, LocalSlot{N: s.N, Type: dummyTypes.Int, Off: s.Off + 8}
 }
 func (d DummyFrontend) SplitInterface(s LocalSlot) (LocalSlot, LocalSlot) {
-	return LocalSlot{s.N, dummyTypes.BytePtr, s.Off}, LocalSlot{s.N, dummyTypes.BytePtr, s.Off + 8}
+	return LocalSlot{N: s.N, Type: dummyTypes.BytePtr, Off: s.Off}, LocalSlot{N: s.N, Type: dummyTypes.BytePtr, Off: s.Off + 8}
 }
 func (d DummyFrontend) SplitSlice(s LocalSlot) (LocalSlot, LocalSlot, LocalSlot) {
-	return LocalSlot{s.N, s.Type.ElemType().PtrTo(), s.Off},
-		LocalSlot{s.N, dummyTypes.Int, s.Off + 8},
-		LocalSlot{s.N, dummyTypes.Int, s.Off + 16}
+	return LocalSlot{N: s.N, Type: s.Type.ElemType().PtrTo(), Off: s.Off},
+		LocalSlot{N: s.N, Type: dummyTypes.Int, Off: s.Off + 8},
+		LocalSlot{N: s.N, Type: dummyTypes.Int, Off: s.Off + 16}
 }
 func (d DummyFrontend) SplitComplex(s LocalSlot) (LocalSlot, LocalSlot) {
 	if s.Type.Size() == 16 {
-		return LocalSlot{s.N, dummyTypes.Float64, s.Off}, LocalSlot{s.N, dummyTypes.Float64, s.Off + 8}
+		return LocalSlot{N: s.N, Type: dummyTypes.Float64, Off: s.Off}, LocalSlot{N: s.N, Type: dummyTypes.Float64, Off: s.Off + 8}
 	}
-	return LocalSlot{s.N, dummyTypes.Float32, s.Off}, LocalSlot{s.N, dummyTypes.Float32, s.Off + 4}
+	return LocalSlot{N: s.N, Type: dummyTypes.Float32, Off: s.Off}, LocalSlot{N: s.N, Type: dummyTypes.Float32, Off: s.Off + 4}
 }
 func (d DummyFrontend) SplitInt64(s LocalSlot) (LocalSlot, LocalSlot) {
 	if s.Type.IsSigned() {
-		return LocalSlot{s.N, dummyTypes.Int32, s.Off + 4}, LocalSlot{s.N, dummyTypes.UInt32, s.Off}
+		return LocalSlot{N: s.N, Type: dummyTypes.Int32, Off: s.Off + 4}, LocalSlot{N: s.N, Type: dummyTypes.UInt32, Off: s.Off}
 	}
-	return LocalSlot{s.N, dummyTypes.UInt32, s.Off + 4}, LocalSlot{s.N, dummyTypes.UInt32, s.Off}
+	return LocalSlot{N: s.N, Type: dummyTypes.UInt32, Off: s.Off + 4}, LocalSlot{N: s.N, Type: dummyTypes.UInt32, Off: s.Off}
 }
 func (d DummyFrontend) SplitStruct(s LocalSlot, i int) LocalSlot {
-	return LocalSlot{s.N, s.Type.FieldType(i), s.Off + s.Type.FieldOff(i)}
+	return LocalSlot{N: s.N, Type: s.Type.FieldType(i), Off: s.Off + s.Type.FieldOff(i)}
 }
 func (d DummyFrontend) SplitArray(s LocalSlot) LocalSlot {
-	return LocalSlot{s.N, s.Type.ElemType(), s.Off}
+	return LocalSlot{N: s.N, Type: s.Type.ElemType(), Off: s.Off}
 }
 func (DummyFrontend) Line(_ src.XPos) string {
 	return "unknown.go:0"
@@ -121,6 +125,8 @@
 func (DummyFrontend) UseWriteBarrier() bool {
 	return true // only writebarrier_test cares
 }
+func (DummyFrontend) SetWBPos(pos src.XPos) {
+}
 
 func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
 func (d DummyFrontend) Log() bool                            { return true }
@@ -128,7 +134,7 @@
 func (d DummyFrontend) Fatalf(_ src.XPos, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
 func (d DummyFrontend) Warnl(_ src.XPos, msg string, args ...interface{})  { d.t.Logf(msg, args...) }
 func (d DummyFrontend) Debug_checknil() bool                               { return false }
-func (d DummyFrontend) Debug_wb() bool                                     { return false }
+func (d DummyFrontend) Debug_eagerwb() bool                                { return false }
 
 var dummyTypes Types
 
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index 7ec5963..62550df 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -44,8 +44,6 @@
 	scheduled bool // Values in Blocks are in final order
 	NoSplit   bool // true if function is marked as nosplit.  Used by schedule check pass.
 
-	WBPos src.XPos // line number of first write barrier
-
 	// when register allocation is done, maps value ids to locations
 	RegAlloc []Location
 
@@ -175,7 +173,7 @@
 	f.Warnl(f.Entry.Pos, "\t%s\t%s%s\t%s", n, key, value, f.Name)
 }
 
-// freeValue frees a value. It must no longer be referenced.
+// freeValue frees a value. It must no longer be referenced or have any args.
 func (f *Func) freeValue(v *Value) {
 	if v.Block == nil {
 		f.Fatalf("trying to free an already freed value")
@@ -183,6 +181,9 @@
 	if v.Uses != 0 {
 		f.Fatalf("value %s still has %d uses", v, v.Uses)
 	}
+	if len(v.Args) != 0 {
+		f.Fatalf("value %s still has %d args", v, len(v.Args))
+	}
 	// Clear everything but ID (which we reuse).
 	id := v.ID
 
@@ -406,6 +407,7 @@
 
 // constVal returns a constant value for c.
 func (f *Func) constVal(pos src.XPos, op Op, t *types.Type, c int64, setAuxInt bool) *Value {
+	// TODO remove unused pos parameter, both here and in *func.ConstXXX callers.
 	if f.constants == nil {
 		f.constants = make(map[int64][]*Value)
 	}
@@ -420,9 +422,9 @@
 	}
 	var v *Value
 	if setAuxInt {
-		v = f.Entry.NewValue0I(pos, op, t, c)
+		v = f.Entry.NewValue0I(src.NoXPos, op, t, c)
 	} else {
-		v = f.Entry.NewValue0(pos, op, t)
+		v = f.Entry.NewValue0(src.NoXPos, op, t)
 	}
 	f.constants[c] = append(vv, v)
 	return v
diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules
index 49fcd36..e012891 100644
--- a/src/cmd/compile/internal/ssa/gen/386.rules
+++ b/src/cmd/compile/internal/ssa/gen/386.rules
@@ -383,6 +383,8 @@
 (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
 (GetG mem) -> (LoweredGetG mem)
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerPC) -> (LoweredGetCallerPC)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Addr {sym} base) -> (LEAL {sym} base)
 
 // block rewrites
@@ -538,7 +540,6 @@
 (MULLconst [41] x) -> (LEAL8 x (LEAL4 <v.Type> x x))
 (MULLconst [73] x) -> (LEAL8 x (LEAL8 <v.Type> x x))
 
-(MULLconst [c] x) && isPowerOfTwo(c) -> (SHLLconst [log2(c)] x)
 (MULLconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
 (MULLconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAL1 (SHLLconst <v.Type> [log2(c-1)] x) x)
 (MULLconst [c] x) && isPowerOfTwo(c-2) && c >= 34 -> (LEAL2 (SHLLconst <v.Type> [log2(c-2)] x) x)
@@ -798,45 +799,45 @@
 (MOVLstoreconstidx1 [c] {sym} ptr (SHLLconst [2] idx) mem) -> (MOVLstoreconstidx4 [c] {sym} ptr idx mem)
 
 // combine ADDL into indexed loads and stores
-(MOVBloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx2 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVWloadidx2 [c+d] {sym} ptr idx mem)
-(MOVLloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
-(MOVLloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVLloadidx4 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSSloadidx4 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx8 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSDloadidx8 [c+d] {sym} ptr idx mem)
+(MOVBloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVBloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVWloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVWloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVWloadidx2 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVWloadidx2 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVLloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVLloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVLloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVLloadidx4 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVSSloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSSloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVSSloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSSloadidx4 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVSDloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSDloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
+(MOVSDloadidx8 [c] {sym} (ADDLconst [d] ptr) idx mem) -> (MOVSDloadidx8 [int64(int32(c+d))] {sym} ptr idx mem)
 
-(MOVBstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx2 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVWstoreidx2 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVLstoreidx4 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVSSstoreidx4 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx8 [c] {sym} (ADDLconst [d] ptr) idx val mem) -> (MOVSDstoreidx8 [c+d] {sym} ptr idx val mem)
+(MOVBstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVBstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVWstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVWstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVWstoreidx2 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVWstoreidx2 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVLstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVLstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVLstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVLstoreidx4 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVSSstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVSSstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVSSstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVSSstoreidx4 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVSDstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVSDstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
+(MOVSDstoreidx8 [c] {sym} (ADDLconst [d] ptr) idx val mem)  -> (MOVSDstoreidx8 [int64(int32(c+d))] {sym} ptr idx val mem)
 
-(MOVBloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx2 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVWloadidx2 [c+2*d] {sym} ptr idx mem)
-(MOVLloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
-(MOVLloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVLloadidx4 [c+4*d] {sym} ptr idx mem)
-(MOVSSloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSSloadidx4 [c+4*d] {sym} ptr idx mem)
-(MOVSDloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx8 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSDloadidx8 [c+8*d] {sym} ptr idx mem)
+(MOVBloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVBloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
+(MOVWloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVWloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
+(MOVWloadidx2 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVWloadidx2  [int64(int32(c+2*d))] {sym} ptr idx mem)
+(MOVLloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVLloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
+(MOVLloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVLloadidx4  [int64(int32(c+4*d))] {sym} ptr idx mem)
+(MOVSSloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSSloadidx1 [int64(int32(c+d))]   {sym} ptr idx mem)
+(MOVSSloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSSloadidx4 [int64(int32(c+4*d))] {sym} ptr idx mem)
+(MOVSDloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSDloadidx1 [int64(int32(c+d))]   {sym} ptr idx mem)
+(MOVSDloadidx8 [c] {sym} ptr (ADDLconst [d] idx) mem) -> (MOVSDloadidx8 [int64(int32(c+8*d))] {sym} ptr idx mem)
 
-(MOVBstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx2 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVWstoreidx2 [c+2*d] {sym} ptr idx val mem)
-(MOVLstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVLstoreidx4 [c+4*d] {sym} ptr idx val mem)
-(MOVSSstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSSstoreidx4 [c+4*d] {sym} ptr idx val mem)
-(MOVSDstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx8 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSDstoreidx8 [c+8*d] {sym} ptr idx val mem)
+(MOVBstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVBstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
+(MOVWstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVWstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
+(MOVWstoreidx2 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVWstoreidx2  [int64(int32(c+2*d))] {sym} ptr idx val mem)
+(MOVLstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVLstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
+(MOVLstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem)  -> (MOVLstoreidx4  [int64(int32(c+4*d))] {sym} ptr idx val mem)
+(MOVSSstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSSstoreidx1 [int64(int32(c+d))]   {sym} ptr idx val mem)
+(MOVSSstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSSstoreidx4 [int64(int32(c+4*d))] {sym} ptr idx val mem)
+(MOVSDstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSDstoreidx1 [int64(int32(c+d))]   {sym} ptr idx val mem)
+(MOVSDstoreidx8 [c] {sym} ptr (ADDLconst [d] idx) val mem) -> (MOVSDstoreidx8 [int64(int32(c+8*d))] {sym} ptr idx val mem)
 
 (MOVBstoreconstidx1 [x] {sym} (ADDLconst [c] ptr) idx mem) ->
 	(MOVBstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go
index 8965d62..f5f46fa 100644
--- a/src/cmd/compile/internal/ssa/gen/386Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/386Ops.go
@@ -440,6 +440,13 @@
 		// and sorts it to the very beginning of the block to prevent other
 		// use of DX (the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
 		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
 
@@ -448,7 +455,7 @@
 		// (particularly stack maps).  It takes a memory arg so it
 		// gets correctly ordered with respect to GC safepoints.
 		// arg0=ptr/int arg1=mem, output=int/ptr
-		{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL"},
+		{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true},
 
 		// Constant flag values. For any comparison, there are 5 possible
 		// outcomes: the three from the signed total order (<,==,>) and the
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 1900f5e..db7c1a4 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -113,6 +113,11 @@
 
 (Sqrt x) -> (SQRTSD x)
 
+(RoundToEven x) -> (ROUNDSD [0] x)
+(Floor x)	-> (ROUNDSD [1] x)
+(Ceil x)  	-> (ROUNDSD [2] x)
+(Trunc x) 	-> (ROUNDSD [3] x)
+
 // Lowering extension
 // Note: we always extend to 64 bits even though some ops don't need that many result bits.
 (SignExt8to16  x) -> (MOVBQSX x)
@@ -319,7 +324,10 @@
 (Move [2] dst src mem) -> (MOVWstore dst (MOVWload src mem) mem)
 (Move [4] dst src mem) -> (MOVLstore dst (MOVLload src mem) mem)
 (Move [8] dst src mem) -> (MOVQstore dst (MOVQload src mem) mem)
-(Move [16] dst src mem) -> (MOVOstore dst (MOVOload src mem) mem)
+(Move [16] dst src mem) && config.useSSE -> (MOVOstore dst (MOVOload src mem) mem)
+(Move [16] dst src mem) && !config.useSSE ->
+	(MOVQstore [8] dst (MOVQload [8] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
 (Move [3] dst src mem) ->
 	(MOVBstore [2] dst (MOVBload [2] src mem)
 		(MOVWstore dst (MOVWload src mem) mem))
@@ -344,11 +352,18 @@
 		(OffPtr <src.Type> src [s%16])
 		(MOVQstore dst (MOVQload src mem) mem))
 (Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 > 8 ->
+	&& s > 16 && s%16 != 0 && s%16 > 8 && config.useSSE ->
 	(Move [s-s%16]
 		(OffPtr <dst.Type> dst [s%16])
 		(OffPtr <src.Type> src [s%16])
 		(MOVOstore dst (MOVOload src mem) mem))
+(Move [s] dst src mem)
+	&& s > 16 && s%16 != 0 && s%16 > 8 && !config.useSSE ->
+	(Move [s-s%16]
+		(OffPtr <dst.Type> dst [s%16])
+		(OffPtr <src.Type> src [s%16])
+		(MOVQstore [8] dst (MOVQload [8] src mem)
+			(MOVQstore dst (MOVQload src mem) mem)))
 
 // Medium copying uses a duff device.
 (Move [s] dst src mem)
@@ -387,36 +402,60 @@
 		(MOVLstoreconst [0] destptr mem))
 
 // Strip off any fractional word zeroing.
-(Zero [s] destptr mem) && s%8 != 0 && s > 8 ->
+(Zero [s] destptr mem) && s%8 != 0 && s > 8 && !config.useSSE ->
 	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
 		(MOVQstoreconst [0] destptr mem))
 
 // Zero small numbers of words directly.
-(Zero [16] destptr mem) ->
+(Zero [16] destptr mem) && !config.useSSE ->
 	(MOVQstoreconst [makeValAndOff(0,8)] destptr
 		(MOVQstoreconst [0] destptr mem))
-(Zero [24] destptr mem) ->
+(Zero [24] destptr mem) && !config.useSSE ->
 	(MOVQstoreconst [makeValAndOff(0,16)] destptr
 		(MOVQstoreconst [makeValAndOff(0,8)] destptr
 			(MOVQstoreconst [0] destptr mem)))
-(Zero [32] destptr mem) ->
+(Zero [32] destptr mem) && !config.useSSE ->
 	(MOVQstoreconst [makeValAndOff(0,24)] destptr
 		(MOVQstoreconst [makeValAndOff(0,16)] destptr
 			(MOVQstoreconst [makeValAndOff(0,8)] destptr
 				(MOVQstoreconst [0] destptr mem))))
 
+(Zero [s] destptr mem) && s > 8 && s < 16 && config.useSSE ->
+	(MOVQstoreconst [makeValAndOff(0,s-8)] destptr
+		(MOVQstoreconst [0] destptr mem))
+
+// Adjust zeros to be a multiple of 16 bytes.
+(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE ->
+	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
+		(MOVOstore destptr (MOVOconst [0]) mem))
+
+(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE ->
+	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
+		(MOVQstoreconst [0] destptr mem))
+
+(Zero [16] destptr mem) && config.useSSE ->
+	(MOVOstore destptr (MOVOconst [0]) mem)
+(Zero [32] destptr mem) && config.useSSE ->
+	(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0])
+		(MOVOstore destptr (MOVOconst [0]) mem))
+(Zero [48] destptr mem) && config.useSSE ->
+	(MOVOstore (OffPtr <destptr.Type> destptr [32]) (MOVOconst [0])
+		(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0])
+			(MOVOstore destptr (MOVOconst [0]) mem)))
+(Zero [64] destptr mem) && config.useSSE ->
+	(MOVOstore (OffPtr <destptr.Type> destptr [48]) (MOVOconst [0])
+		(MOVOstore (OffPtr <destptr.Type> destptr [32]) (MOVOconst [0])
+			(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0])
+				(MOVOstore destptr (MOVOconst [0]) mem))))
+
 // Medium zeroing uses a duff device.
 (Zero [s] destptr mem)
-	&& s <= 1024 && s%8 == 0 && s%16 != 0
-	&& !config.noDuffDevice ->
-	(Zero [s-8] (OffPtr <destptr.Type> [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
-(Zero [s] destptr mem)
-	&& s <= 1024 && s%16 == 0 && !config.noDuffDevice ->
+	&& s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice ->
 	(DUFFZERO [s] destptr (MOVOconst [0]) mem)
 
 // Large zeroing uses REP STOSQ.
 (Zero [s] destptr mem)
-	&& (s > 1024 || (config.noDuffDevice && s > 32))
+	&& (s > 1024 || (config.noDuffDevice && s > 64 || !config.useSSE && s > 32))
 	&& s%8 == 0 ->
 	(REPSTOSQ destptr (MOVQconst [s/8]) (MOVQconst [0]) mem)
 
@@ -448,9 +487,22 @@
 (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
 (GetG mem) -> (LoweredGetG mem)
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerPC) -> (LoweredGetCallerPC)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Addr {sym} base) && config.PtrSize == 8 -> (LEAQ {sym} base)
 (Addr {sym} base) && config.PtrSize == 4 -> (LEAL {sym} base)
 
+(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 -> (SETLmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 -> (SETLEmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETG x) mem) && y.Uses == 1 -> (SETGmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETGE x) mem) && y.Uses == 1 -> (SETGEmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETEQ x) mem) && y.Uses == 1 -> (SETEQmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETNE x) mem) && y.Uses == 1 -> (SETNEmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETB x) mem) && y.Uses == 1 -> (SETBmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETBE x) mem) && y.Uses == 1 -> (SETBEmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETA x) mem) && y.Uses == 1 -> (SETAmem [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETAE x) mem) && y.Uses == 1 -> (SETAEmem [off] {sym} ptr x mem)
+
 // block rewrites
 (If (SETL  cmp) yes no) -> (LT  cmp yes no)
 (If (SETLE cmp) yes no) -> (LE  cmp yes no)
@@ -504,6 +556,9 @@
 (AtomicAnd8 ptr val mem) -> (ANDBlock ptr val mem)
 (AtomicOr8 ptr val mem) -> (ORBlock ptr val mem)
 
+// Write barrier.
+(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
+
 // ***************************
 // Above: lowering rules
 // Below: optimizations
@@ -545,6 +600,17 @@
 (SETEQ (TESTQconst [c] x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAE (BTQconst [log2(c)] x))
 (SETNE (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETB  (BTQconst [log2(c)] x))
 (SETEQ (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAE (BTQconst [log2(c)] x))
+// SET..mem variant
+(SETNEmem [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem) && !config.nacl -> (SETBmem  [off] {sym} ptr (BTL x y) mem)
+(SETEQmem [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem) && !config.nacl -> (SETAEmem [off] {sym} ptr (BTL x y) mem)
+(SETNEmem [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem) && !config.nacl -> (SETBmem  [off] {sym} ptr (BTQ x y) mem)
+(SETEQmem [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem) && !config.nacl -> (SETAEmem [off] {sym} ptr (BTQ x y) mem)
+(SETNEmem [off] {sym} ptr (TESTLconst [c] x) mem) && isPowerOfTwo(c) && log2(c) < 32 && !config.nacl -> (SETBmem  [off] {sym} ptr (BTLconst [log2(c)] x) mem)
+(SETEQmem [off] {sym} ptr (TESTLconst [c] x) mem) && isPowerOfTwo(c) && log2(c) < 32 && !config.nacl -> (SETAEmem [off] {sym} ptr (BTLconst [log2(c)] x) mem)
+(SETNEmem [off] {sym} ptr (TESTQconst [c] x) mem) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETBmem  [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+(SETEQmem [off] {sym} ptr (TESTQconst [c] x) mem) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAEmem [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+(SETNEmem [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETBmem  [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+(SETEQmem [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAEmem [off] {sym} ptr (BTQconst [log2(c)] x) mem)
 
 // Fold boolean negation into SETcc.
 (XORLconst [1] (SETNE x)) -> (SETEQ x)
@@ -874,7 +940,6 @@
 (MULQconst [41] x) -> (LEAQ8 x (LEAQ4 <v.Type> x x))
 (MULQconst [73] x) -> (LEAQ8 x (LEAQ8 <v.Type> x x))
 
-(MULQconst [c] x) && isPowerOfTwo(c) -> (SHLQconst [log2(c)] x)
 (MULQconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
 (MULQconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAQ1 (SHLQconst <v.Type> [log2(c-1)] x) x)
 (MULQconst [c] x) && isPowerOfTwo(c-2) && c >= 34 -> (LEAQ2 (SHLQconst <v.Type> [log2(c-2)] x) x)
@@ -934,6 +999,17 @@
 (SETEQ (InvertFlags x)) -> (SETEQ x)
 (SETNE (InvertFlags x)) -> (SETNE x)
 
+(SETLmem [off] {sym} ptr (InvertFlags x) mem) -> (SETGmem [off] {sym} ptr x mem)
+(SETGmem [off] {sym} ptr (InvertFlags x) mem) -> (SETLmem [off] {sym} ptr x mem)
+(SETBmem [off] {sym} ptr (InvertFlags x) mem) -> (SETAmem [off] {sym} ptr x mem)
+(SETAmem [off] {sym} ptr (InvertFlags x) mem) -> (SETBmem [off] {sym} ptr x mem)
+(SETLEmem [off] {sym} ptr (InvertFlags x) mem) -> (SETGEmem [off] {sym} ptr x mem)
+(SETGEmem [off] {sym} ptr (InvertFlags x) mem) -> (SETLEmem [off] {sym} ptr x mem)
+(SETBEmem [off] {sym} ptr (InvertFlags x) mem) -> (SETAEmem [off] {sym} ptr x mem)
+(SETAEmem [off] {sym} ptr (InvertFlags x) mem) -> (SETBEmem [off] {sym} ptr x mem)
+(SETEQmem [off] {sym} ptr (InvertFlags x) mem) -> (SETEQmem [off] {sym} ptr x mem)
+(SETNEmem [off] {sym} ptr (InvertFlags x) mem) -> (SETNEmem [off] {sym} ptr x mem)
+
 // sign extended loads
 // Note: The combined instruction must end up in the same block
 // as the original load. If not, we end up making a value with
@@ -961,6 +1037,8 @@
 (MOVLQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
 (MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
 
+(MOVLQZX x) && zeroUpper32Bits(x,3) -> x
+
 (MOVBQZX x:(MOVBloadidx1 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx1 <v.Type> [off] {sym} ptr idx mem)
 (MOVWQZX x:(MOVWloadidx1 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem)
 (MOVWQZX x:(MOVWloadidx2 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx2 <v.Type> [off] {sym} ptr idx mem)
@@ -1092,6 +1170,8 @@
 	(MOVLloadidx1 [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVLload [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVLloadidx4 [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVLload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
+	(MOVLloadidx8 [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVQload [off1] {sym1} (LEAQ1 [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVQloadidx1 [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVQload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
@@ -1115,6 +1195,8 @@
 	(MOVLstoreidx1 [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
 (MOVLstore [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVLstoreidx4 [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
+(MOVLstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
+	(MOVLstoreidx8 [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
 (MOVQstore [off1] {sym1} (LEAQ1 [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVQstoreidx1 [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
 (MOVQstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
@@ -1164,11 +1246,13 @@
 // combine SHLQ into indexed loads and stores
 (MOVWloadidx1 [c] {sym} ptr (SHLQconst [1] idx) mem) -> (MOVWloadidx2 [c] {sym} ptr idx mem)
 (MOVLloadidx1 [c] {sym} ptr (SHLQconst [2] idx) mem) -> (MOVLloadidx4 [c] {sym} ptr idx mem)
+(MOVLloadidx1 [c] {sym} ptr (SHLQconst [3] idx) mem) -> (MOVLloadidx8 [c] {sym} ptr idx mem)
 (MOVQloadidx1 [c] {sym} ptr (SHLQconst [3] idx) mem) -> (MOVQloadidx8 [c] {sym} ptr idx mem)
 (MOVSSloadidx1 [c] {sym} ptr (SHLQconst [2] idx) mem) -> (MOVSSloadidx4 [c] {sym} ptr idx mem)
 (MOVSDloadidx1 [c] {sym} ptr (SHLQconst [3] idx) mem) -> (MOVSDloadidx8 [c] {sym} ptr idx mem)
 (MOVWstoreidx1 [c] {sym} ptr (SHLQconst [1] idx) val mem) -> (MOVWstoreidx2 [c] {sym} ptr idx val mem)
 (MOVLstoreidx1 [c] {sym} ptr (SHLQconst [2] idx) val mem) -> (MOVLstoreidx4 [c] {sym} ptr idx val mem)
+(MOVLstoreidx1 [c] {sym} ptr (SHLQconst [3] idx) val mem) -> (MOVLstoreidx8 [c] {sym} ptr idx val mem)
 (MOVQstoreidx1 [c] {sym} ptr (SHLQconst [3] idx) val mem) -> (MOVQstoreidx8 [c] {sym} ptr idx val mem)
 (MOVSSstoreidx1 [c] {sym} ptr (SHLQconst [2] idx) val mem) -> (MOVSSstoreidx4 [c] {sym} ptr idx val mem)
 (MOVSDstoreidx1 [c] {sym} ptr (SHLQconst [3] idx) val mem) -> (MOVSDstoreidx8 [c] {sym} ptr idx val mem)
@@ -1177,82 +1261,86 @@
 (MOVQstoreconstidx1 [c] {sym} ptr (SHLQconst [3] idx) mem) -> (MOVQstoreconstidx8 [c] {sym} ptr idx mem)
 
 // combine ADDQ into indexed loads and stores
-(MOVBloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx2 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVWloadidx2 [c+d] {sym} ptr idx mem)
-(MOVLloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
-(MOVLloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVLloadidx4 [c+d] {sym} ptr idx mem)
-(MOVQloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVQloadidx1 [c+d] {sym} ptr idx mem)
-(MOVQloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVQloadidx8 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVSSloadidx4 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem) -> (MOVSDloadidx8 [c+d] {sym} ptr idx mem)
+(MOVBloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+(MOVWloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+(MOVWloadidx2 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVWloadidx2 [c+d] {sym} ptr idx mem)
+(MOVLloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+(MOVLloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVLloadidx4 [c+d] {sym} ptr idx mem)
+(MOVLloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVLloadidx8 [c+d] {sym} ptr idx mem)
+(MOVQloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVQloadidx1 [c+d] {sym} ptr idx mem)
+(MOVQloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVQloadidx8 [c+d] {sym} ptr idx mem)
+(MOVSSloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
+(MOVSSloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVSSloadidx4 [c+d] {sym} ptr idx mem)
+(MOVSDloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
+(MOVSDloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem) && is32Bit(c+d) -> (MOVSDloadidx8 [c+d] {sym} ptr idx mem)
 
-(MOVBstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx2 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVWstoreidx2 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVLstoreidx4 [c+d] {sym} ptr idx val mem)
-(MOVQstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVQstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVQstoreidx8 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVSSstoreidx4 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem) -> (MOVSDstoreidx8 [c+d] {sym} ptr idx val mem)
+(MOVBstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx2 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVWstoreidx2 [c+d] {sym} ptr idx val mem)
+(MOVLstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVLstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVLstoreidx4 [c+d] {sym} ptr idx val mem)
+(MOVLstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVLstoreidx8 [c+d] {sym} ptr idx val mem)
+(MOVQstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVQstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVQstoreidx8 [c+d] {sym} ptr idx val mem)
+(MOVSSstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVSSstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVSSstoreidx4 [c+d] {sym} ptr idx val mem)
+(MOVSDstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVSDstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem) && is32Bit(c+d) -> (MOVSDstoreidx8 [c+d] {sym} ptr idx val mem)
 
-(MOVBloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
-(MOVWloadidx2 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVWloadidx2 [c+2*d] {sym} ptr idx mem)
-(MOVLloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
-(MOVLloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVLloadidx4 [c+4*d] {sym} ptr idx mem)
-(MOVQloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVQloadidx1 [c+d] {sym} ptr idx mem)
-(MOVQloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVQloadidx8 [c+8*d] {sym} ptr idx mem)
-(MOVSSloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSSloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVSSloadidx4 [c+4*d] {sym} ptr idx mem)
-(MOVSDloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
-(MOVSDloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem) -> (MOVSDloadidx8 [c+8*d] {sym} ptr idx mem)
+(MOVBloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+d)   -> (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+(MOVWloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+d)   -> (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+(MOVWloadidx2 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+2*d) -> (MOVWloadidx2 [c+2*d] {sym} ptr idx mem)
+(MOVLloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+d)   -> (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+(MOVLloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+4*d) -> (MOVLloadidx4 [c+4*d] {sym} ptr idx mem)
+(MOVLloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+8*d) -> (MOVLloadidx8 [c+8*d] {sym} ptr idx mem)
+(MOVQloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+d)   -> (MOVQloadidx1 [c+d] {sym} ptr idx mem)
+(MOVQloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem)  && is32Bit(c+8*d) -> (MOVQloadidx8 [c+8*d] {sym} ptr idx mem)
+(MOVSSloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) && is32Bit(c+d)   -> (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
+(MOVSSloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem) && is32Bit(c+4*d) -> (MOVSSloadidx4 [c+4*d] {sym} ptr idx mem)
+(MOVSDloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem) && is32Bit(c+d)   -> (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
+(MOVSDloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem) && is32Bit(c+8*d) -> (MOVSDloadidx8 [c+8*d] {sym} ptr idx mem)
 
-(MOVBstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx2 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVWstoreidx2 [c+2*d] {sym} ptr idx val mem)
-(MOVLstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVLstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVLstoreidx4 [c+4*d] {sym} ptr idx val mem)
-(MOVQstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVQstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVQstoreidx8 [c+8*d] {sym} ptr idx val mem)
-(MOVSSstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSSstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVSSstoreidx4 [c+4*d] {sym} ptr idx val mem)
-(MOVSDstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
-(MOVSDstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem) -> (MOVSDstoreidx8 [c+8*d] {sym} ptr idx val mem)
+(MOVBstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+d)   -> (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+d)   -> (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx2 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+2*d) -> (MOVWstoreidx2 [c+2*d] {sym} ptr idx val mem)
+(MOVLstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+d)   -> (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVLstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+4*d) -> (MOVLstoreidx4 [c+4*d] {sym} ptr idx val mem)
+(MOVLstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+8*d) -> (MOVLstoreidx8 [c+8*d] {sym} ptr idx val mem)
+(MOVQstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+d)   -> (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVQstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem)  && is32Bit(c+8*d) -> (MOVQstoreidx8 [c+8*d] {sym} ptr idx val mem)
+(MOVSSstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) && is32Bit(c+d)   -> (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVSSstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem) && is32Bit(c+4*d) -> (MOVSSstoreidx4 [c+4*d] {sym} ptr idx val mem)
+(MOVSDstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem) && is32Bit(c+d)   -> (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
+(MOVSDstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem) && is32Bit(c+8*d) -> (MOVSDstoreidx8 [c+8*d] {sym} ptr idx val mem)
 
-(MOVBstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVBstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVBstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVWstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVWstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVWstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVWstoreconstidx2 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVWstoreconstidx2 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVWstoreconstidx2 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVLstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVLstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVLstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVLstoreconstidx4 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVLstoreconstidx4 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVLstoreconstidx4 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVQstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVQstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVQstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVQstoreconstidx8 [x] {sym} (ADDQconst [c] ptr) idx mem) ->
+(MOVQstoreconstidx8 [x] {sym} (ADDQconst [c] ptr) idx mem) && ValAndOff(x).canAdd(c) ->
 	(MOVQstoreconstidx8 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 
-(MOVBstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVBstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(c) ->
 	(MOVBstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVWstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVWstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(c) ->
 	(MOVWstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVWstoreconstidx2 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVWstoreconstidx2 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(2*c) ->
 	(MOVWstoreconstidx2 [ValAndOff(x).add(2*c)] {sym} ptr idx mem)
-(MOVLstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVLstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(c) ->
 	(MOVLstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVLstoreconstidx4 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVLstoreconstidx4 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(4*c) ->
 	(MOVLstoreconstidx4 [ValAndOff(x).add(4*c)] {sym} ptr idx mem)
-(MOVQstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVQstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(c) ->
 	(MOVQstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
-(MOVQstoreconstidx8 [x] {sym} ptr (ADDQconst [c] idx) mem) ->
+(MOVQstoreconstidx8 [x] {sym} ptr (ADDQconst [c] idx) mem) && ValAndOff(x).canAdd(8*c) ->
 	(MOVQstoreconstidx8 [ValAndOff(x).add(8*c)] {sym} ptr idx mem)
 
 // fold LEAQs together
@@ -1465,6 +1553,66 @@
 (SETAE (FlagGT_ULT)) -> (MOVLconst [0])
 (SETAE (FlagGT_UGT)) -> (MOVLconst [1])
 
+(SETEQmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETEQmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETEQmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETEQmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETEQmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+
+(SETNEmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETNEmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETNEmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETNEmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETNEmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+
+(SETLmem  [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETLmem  [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETLmem  [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETLmem  [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETLmem  [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+
+(SETLEmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETLEmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETLEmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETLEmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETLEmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+
+(SETGmem  [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETGmem  [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETGmem  [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETGmem  [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETGmem  [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+
+(SETGEmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETGEmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETGEmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETGEmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETGEmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+
+(SETBmem  [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETBmem  [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETBmem  [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETBmem  [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETBmem  [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+
+(SETBEmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETBEmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETBEmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETBEmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETBEmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+
+(SETAmem  [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETAmem  [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETAmem  [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETAmem  [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETAmem  [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+
+(SETAEmem [off] {sym} ptr x:(FlagEQ)     mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETAEmem [off] {sym} ptr x:(FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETAEmem [off] {sym} ptr x:(FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+(SETAEmem [off] {sym} ptr x:(FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+(SETAEmem [off] {sym} ptr x:(FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+
 // Remove redundant *const ops
 (ADDQconst [0] x) -> x
 (ADDLconst [c] x) && int32(c)==0 -> x
@@ -1499,9 +1647,9 @@
 (SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c])
 (SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x)
 (SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
-(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
-(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
-(SARBconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
+(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int32(d))>>uint64(c)])
+(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int16(d))>>uint64(c)])
+(SARBconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int8(d))>>uint64(c)])
 (NEGQ (MOVQconst [c])) -> (MOVQconst [-c])
 (NEGL (MOVLconst [c])) -> (MOVLconst [int64(int32(-c))])
 (MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d])
@@ -2199,6 +2347,14 @@
   && ValAndOff(a).Off() + 4 == ValAndOff(c).Off()
   && clobber(x)
   -> (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem)
+(MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem))
+  && config.useSSE
+  && x.Uses == 1
+  && ValAndOff(c2).Off() + 8 == ValAndOff(c).Off()
+  && ValAndOff(c).Val() == 0
+  && ValAndOff(c2).Val() == 0
+  && clobber(x)
+  -> (MOVOstore [ValAndOff(c2).Off()] {s} p (MOVOconst [0]) mem)
 
 (MOVBstoreconstidx1 [c] {s} p i x:(MOVBstoreconstidx1 [a] {s} p i mem))
   && x.Uses == 1
@@ -2295,28 +2451,64 @@
   && clobber(x)
   -> (MOVQstoreidx1 [i-4] {s} p (SHLQconst <idx.Type> [2] idx) w0 mem)
 
+(MOVBstore [i] {s} p
+  x1:(MOVBload [j] {s2} p2 mem)
+    mem2:(MOVBstore [i-1] {s} p
+      x2:(MOVBload [j-1] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1)
+  && clobber(x2)
+  && clobber(mem2)
+  -> (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
+
+(MOVWstore [i] {s} p
+  x1:(MOVWload [j] {s2} p2 mem)
+    mem2:(MOVWstore [i-2] {s} p
+      x2:(MOVWload [j-2] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1)
+  && clobber(x2)
+  && clobber(mem2)
+  -> (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem)
+
+(MOVLstore [i] {s} p
+  x1:(MOVLload [j] {s2} p2 mem)
+    mem2:(MOVLstore [i-4] {s} p
+      x2:(MOVLload [j-4] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1)
+  && clobber(x2)
+  && clobber(mem2)
+  -> (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem)
+
 // amd64p32 rules
 // same as the rules above, but with 32 instead of 64 bit pointer arithmetic.
 // LEAQ,ADDQ -> LEAL,ADDL
 (ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(c+d) -> (LEAL [c+d] {s} x)
 (LEAL [c] {s} (ADDLconst [d] x)) && is32Bit(c+d) -> (LEAL [c+d] {s} x)
 
-(MOVQload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+(MOVQload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVQload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVLload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+(MOVLload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVLload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVWload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+(MOVWload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVWload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+(MOVBload  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVBload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
 
-(MOVQstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+(MOVQstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVQstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVLstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+(MOVLstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVLstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVWstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+(MOVWstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVWstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVBstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+(MOVBstore  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) ->
 	(MOVBstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 
 (MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) ->
@@ -2405,15 +2597,68 @@
 (BSFQ (ORQconst <t> [1<<16] (MOVWQZX x))) -> (BSFQ (ORQconst <t> [1<<16] x))
 
 // Redundant sign/zero extensions
-(MOVLQSX x:(MOVLQSX _)) -> x
-(MOVLQSX x:(MOVWQSX _)) -> x
-(MOVLQSX x:(MOVBQSX _)) -> x
-(MOVWQSX x:(MOVWQSX _)) -> x
-(MOVWQSX x:(MOVBQSX _)) -> x
-(MOVBQSX x:(MOVBQSX _)) -> x
-(MOVLQZX x:(MOVLQZX _)) -> x
-(MOVLQZX x:(MOVWQZX _)) -> x
-(MOVLQZX x:(MOVBQZX _)) -> x
-(MOVWQZX x:(MOVWQZX _)) -> x
-(MOVWQZX x:(MOVBQZX _)) -> x
-(MOVBQZX x:(MOVBQZX _)) -> x
+// Note: see issue 21963. We have to make sure we use the right type on
+// the resulting extension (the outer type, not the inner type).
+(MOVLQSX (MOVLQSX x)) -> (MOVLQSX x)
+(MOVLQSX (MOVWQSX x)) -> (MOVWQSX x)
+(MOVLQSX (MOVBQSX x)) -> (MOVBQSX x)
+(MOVWQSX (MOVWQSX x)) -> (MOVWQSX x)
+(MOVWQSX (MOVBQSX x)) -> (MOVBQSX x)
+(MOVBQSX (MOVBQSX x)) -> (MOVBQSX x)
+(MOVLQZX (MOVLQZX x)) -> (MOVLQZX x)
+(MOVLQZX (MOVWQZX x)) -> (MOVWQZX x)
+(MOVLQZX (MOVBQZX x)) -> (MOVBQZX x)
+(MOVWQZX (MOVWQZX x)) -> (MOVWQZX x)
+(MOVWQZX (MOVBQZX x)) -> (MOVBQZX x)
+(MOVBQZX (MOVBQZX x)) -> (MOVBQZX x)
+
+(MOVQstore [off] {sym} ptr a:(ADDQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) ->
+	(ADDQconstmem {sym} [makeValAndOff(c,off)] ptr mem)
+(MOVLstore [off] {sym} ptr a:(ADDLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) ->
+	(ADDLconstmem {sym} [makeValAndOff(c,off)] ptr mem)
+
+// float <-> int register moves, with no conversion.
+// These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}.
+(MOVQload  [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) -> (MOVQf2i val)
+(MOVLload  [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) -> (MOVLf2i val)
+(MOVSDload [off] {sym} ptr (MOVQstore  [off] {sym} ptr val _)) -> (MOVQi2f val)
+(MOVSSload [off] {sym} ptr (MOVLstore  [off] {sym} ptr val _)) -> (MOVLi2f val)
+
+// Other load-like ops.
+(ADDQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (ADDQ x (MOVQf2i y))
+(ADDLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (ADDL x (MOVLf2i y))
+(SUBQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (SUBQ x (MOVQf2i y))
+(SUBLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (SUBL x (MOVLf2i y))
+(ANDQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (ANDQ x (MOVQf2i y))
+(ANDLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (ANDL x (MOVLf2i y))
+( ORQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> ( ORQ x (MOVQf2i y))
+( ORLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> ( ORL x (MOVLf2i y))
+(XORQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (XORQ x (MOVQf2i y))
+(XORLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (XORL x (MOVLf2i y))
+
+(ADDQconstmem [valOff] {sym} ptr (MOVSDstore [ValAndOff(valOff).Off()] {sym} ptr x _)) ->
+  (ADDQconst [ValAndOff(valOff).Val()] (MOVQf2i x))
+(ADDLconstmem [valOff] {sym} ptr (MOVSSstore [ValAndOff(valOff).Off()] {sym} ptr x _)) ->
+  (ADDLconst [ValAndOff(valOff).Val()] (MOVLf2i x))
+
+(ADDSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (ADDSD x (MOVQi2f y))
+(ADDSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (ADDSS x (MOVLi2f y))
+(SUBSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (SUBSD x (MOVQi2f y))
+(SUBSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (SUBSS x (MOVLi2f y))
+(MULSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (MULSD x (MOVQi2f y))
+(MULSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (MULSS x (MOVLi2f y))
+
+// Redirect stores to use the other register set.
+(MOVQstore  [off] {sym} ptr (MOVQf2i val) mem) -> (MOVSDstore [off] {sym} ptr val mem)
+(MOVLstore  [off] {sym} ptr (MOVLf2i val) mem) -> (MOVSSstore [off] {sym} ptr val mem)
+(MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) -> (MOVQstore  [off] {sym} ptr val mem)
+(MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) -> (MOVLstore  [off] {sym} ptr val mem)
+
+// Load args directly into the register class where it will be used.
+// We do this by just modifying the type of the Arg.
+(MOVQf2i <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
+(MOVLf2i <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
+(MOVQi2f <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
+(MOVLi2f <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
index c51cbd2..b7c0ce9 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
@@ -20,6 +20,7 @@
 //  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
 //    filled by sign-extending the used portion.  Users of AuxInt which interpret
 //    AuxInt as unsigned (e.g. shifts) must be careful.
+//  - All SymOff opcodes require their offset to fit in an int32.
 
 // Suffixes encode the bit width of various instructions.
 // Q (quad word) = 64 bit
@@ -179,27 +180,29 @@
 		{name: "MOVSDstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by i store
 		{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by 8i store
 
-		{name: "ADDSDmem", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 		{name: "ADDSSmem", argLength: 3, reg: fp21load, asm: "ADDSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "ADDSDmem", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 		{name: "SUBSSmem", argLength: 3, reg: fp21load, asm: "SUBSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 		{name: "SUBSDmem", argLength: 3, reg: fp21load, asm: "SUBSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 		{name: "MULSSmem", argLength: 3, reg: fp21load, asm: "MULSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 		{name: "MULSDmem", argLength: 3, reg: fp21load, asm: "MULSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
 
 		// binary ops
-		{name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true, clobberFlags: true},                // arg0 + arg1
-		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},                // arg0 + arg1
-		{name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int64", typ: "UInt64", clobberFlags: true}, // arg0 + auxint
-		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", clobberFlags: true},                // arg0 + auxint
+		{name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true, clobberFlags: true},                                                           // arg0 + arg1
+		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},                                                           // arg0 + arg1
+		{name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int32", typ: "UInt64", clobberFlags: true},                                            // arg0 + auxint
+		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", clobberFlags: true},                                                           // arg0 + auxint
+		{name: "ADDQconstmem", argLength: 2, reg: gpstoreconst, asm: "ADDQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "ADDLconstmem", argLength: 2, reg: gpstoreconst, asm: "ADDL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
 
 		{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
 		{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
-		{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
+		{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
 		{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
 
 		{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
 		{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
-		{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 * auxint
+		{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 * auxint
 		{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMULL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 * auxint
 
 		{name: "HMULQ", argLength: 2, reg: gp21hmul, commutative: true, asm: "IMULQ", clobberFlags: true}, // (arg0 * arg1) >> width
@@ -221,24 +224,24 @@
 
 		{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
 		{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
-		{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
+		{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
 		{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
 
 		{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 | arg1
 		{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 | arg1
-		{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
+		{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
 		{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
 
 		{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 ^ arg1
 		{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 ^ arg1
-		{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
+		{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
 		{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
 
 		{name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"},                    // arg0 compare to arg1
 		{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"},                    // arg0 compare to arg1
 		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1
 		{name: "CMPB", argLength: 2, reg: gp2flags, asm: "CMPB", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPQconst", argLength: 1, reg: gp1flags, asm: "CMPQ", typ: "Flags", aux: "Int64"}, // arg0 compare to auxint
+		{name: "CMPQconst", argLength: 1, reg: gp1flags, asm: "CMPQ", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
 		{name: "CMPLconst", argLength: 1, reg: gp1flags, asm: "CMPL", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
 		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int16"}, // arg0 compare to auxint
 		{name: "CMPBconst", argLength: 1, reg: gp1flags, asm: "CMPB", typ: "Flags", aux: "Int8"},  // arg0 compare to auxint
@@ -255,7 +258,7 @@
 		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
 		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
 		{name: "TESTB", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTQconst", argLength: 1, reg: gp1flags, asm: "TESTQ", typ: "Flags", aux: "Int64"}, // (arg0 & auxint) compare to 0
+		{name: "TESTQconst", argLength: 1, reg: gp1flags, asm: "TESTQ", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
 		{name: "TESTLconst", argLength: 1, reg: gp1flags, asm: "TESTL", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
 		{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"}, // (arg0 & auxint) compare to 0
 		{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"},  // (arg0 & auxint) compare to 0
@@ -267,22 +270,22 @@
 		// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
 
 		{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true},              // unsigned arg0 >> arg1, shift amount is mod 64
-		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},              // unsigned arg0 >> arg1, shift amount is mod 32
-		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},              // unsigned arg0 >> arg1, shift amount is mod 32
-		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},              // unsigned arg0 >> arg1, shift amount is mod 32
+		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},              // unsigned uint32(arg0) >> arg1, shift amount is mod 32
+		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},              // unsigned uint16(arg0) >> arg1, shift amount is mod 32
+		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},              // unsigned uint8(arg0) >> arg1, shift amount is mod 32
 		{name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-63
-		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31
-		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-15
-		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-7
+		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
+		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint16(arg0) >> auxint, shift amount 0-15
+		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint8(arg0) >> auxint, shift amount 0-7
 
 		{name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ", resultInArg0: true, clobberFlags: true},              // signed arg0 >> arg1, shift amount is mod 64
-		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},              // signed arg0 >> arg1, shift amount is mod 32
-		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},              // signed arg0 >> arg1, shift amount is mod 32
-		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},              // signed arg0 >> arg1, shift amount is mod 32
+		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},              // signed int32(arg0) >> arg1, shift amount is mod 32
+		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},              // signed int16(arg0) >> arg1, shift amount is mod 32
+		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},              // signed int8(arg0) >> arg1, shift amount is mod 32
 		{name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
-		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31
-		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15
-		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-7
+		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
+		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int16(arg0) >> auxint, shift amount 0-15
+		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int8(arg0) >> auxint, shift amount 0-7
 
 		{name: "ROLQ", argLength: 2, reg: gp21shift, asm: "ROLQ", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
 		{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
@@ -338,6 +341,10 @@
 
 		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
 
+		// ROUNDSD instruction isn't guaranteed to be on the target platform (it is SSE4.1)
+		// Any use must be preceded by a successful check of runtime.support_sse41.
+		{name: "ROUNDSD", argLength: 1, reg: fp11, aux: "Int8", asm: "ROUNDSD"}, // rounds arg0 depending on auxint, 1 means math.Floor, 2 Ceil, 3 Trunc
+
 		{name: "SBBQcarrymask", argLength: 1, reg: flagsgp, asm: "SBBQ"}, // (int64)(-1) if carry is set, 0 if carry is clear.
 		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
 		// Note: SBBW and SBBB are subsumed by SBBL
@@ -352,6 +359,17 @@
 		{name: "SETBE", argLength: 1, reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
 		{name: "SETA", argLength: 1, reg: readflags, asm: "SETHI"},  // extract unsigned > condition from arg0
 		{name: "SETAE", argLength: 1, reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
+		// Variants that store result to memory
+		{name: "SETEQmem", argLength: 3, reg: gpstoreconst, asm: "SETEQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract == condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETNEmem", argLength: 3, reg: gpstoreconst, asm: "SETNE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract != condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETLmem", argLength: 3, reg: gpstoreconst, asm: "SETLT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed < condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETLEmem", argLength: 3, reg: gpstoreconst, asm: "SETLE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed <= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETGmem", argLength: 3, reg: gpstoreconst, asm: "SETGT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed > condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETGEmem", argLength: 3, reg: gpstoreconst, asm: "SETGE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed >= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETBmem", argLength: 3, reg: gpstoreconst, asm: "SETCS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned < condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETBEmem", argLength: 3, reg: gpstoreconst, asm: "SETLS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned <= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETAmem", argLength: 3, reg: gpstoreconst, asm: "SETHI", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned > condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETAEmem", argLength: 3, reg: gpstoreconst, asm: "SETCC", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned >= condition from arg1 to arg0+auxint+aux, arg2=mem
 		// Need different opcodes for floating point conditions because
 		// any comparison involving a NaN is always FALSE and thus
 		// the patterns for inverting conditions cannot be used.
@@ -384,6 +402,13 @@
 		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
 		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
 
+		// Move values between int and float registers, with no conversion.
+		// TODO: should we have generic versions of these?
+		{name: "MOVQi2f", argLength: 1, reg: gpfp, typ: "Float64"}, // move 64 bits from int to float reg
+		{name: "MOVQf2i", argLength: 1, reg: fpgp, typ: "UInt64"},  // move 64 bits from float to int reg
+		{name: "MOVLi2f", argLength: 1, reg: gpfp, typ: "Float32"}, // move 32 bits from int to float reg
+		{name: "MOVLf2i", argLength: 1, reg: fpgp, typ: "UInt32"},  // move 32 bits from float to int reg
+
 		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
 
 		{name: "LEAQ", argLength: 1, reg: gp11sb, asm: "LEAQ", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
@@ -416,6 +441,7 @@
 		{name: "MOVWloadidx2", argLength: 3, reg: gploadidx, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", symEffect: "Read"},                    // load 2 bytes from arg0+2*arg1+auxint+aux. arg2=mem
 		{name: "MOVLloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVL", aux: "SymOff", typ: "UInt32", symEffect: "Read"},    // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem
 		{name: "MOVLloadidx4", argLength: 3, reg: gploadidx, asm: "MOVL", aux: "SymOff", typ: "UInt32", symEffect: "Read"},                       // load 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem
+		{name: "MOVLloadidx8", argLength: 3, reg: gploadidx, asm: "MOVL", aux: "SymOff", typ: "UInt32", symEffect: "Read"},                       // load 4 bytes from arg0+8*arg1+auxint+aux. arg2=mem
 		{name: "MOVQloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVQ", aux: "SymOff", typ: "UInt64", symEffect: "Read"},    // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
 		{name: "MOVQloadidx8", argLength: 3, reg: gploadidx, asm: "MOVQ", aux: "SymOff", typ: "UInt64", symEffect: "Read"},                       // load 8 bytes from arg0+8*arg1+auxint+aux. arg2=mem
 		// TODO: sign-extending indexed loads
@@ -425,6 +451,7 @@
 		{name: "MOVWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVW", aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
 		{name: "MOVLstoreidx1", argLength: 4, reg: gpstoreidx, asm: "MOVL", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
 		{name: "MOVLstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVL", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
+		{name: "MOVLstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVL", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
 		{name: "MOVQstoreidx1", argLength: 4, reg: gpstoreidx, asm: "MOVQ", aux: "SymOff", symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
 		{name: "MOVQstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVQ", aux: "SymOff", symEffect: "Write"}, // store 8 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
 		// TODO: add size-mismatched indexed loads, like MOVBstoreidx4.
@@ -458,7 +485,6 @@
 				inputs:   []regMask{buildReg("DI"), buildReg("X0")},
 				clobbers: buildReg("DI"),
 			},
-			clobberFlags:   true,
 			faultOnNilArg0: true,
 		},
 		{name: "MOVOconst", reg: regInfo{nil, 0, []regMask{fp}}, typ: "Int128", aux: "Int128", rematerializeable: true},
@@ -529,16 +555,27 @@
 		// and sorts it to the very beginning of the block to prevent other
 		// use of DX (the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
 		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
 
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary, but may clobber others.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave ^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
 		// MOVQconvert converts between pointers and integers.
 		// We have a special op for this so as to not confuse GC
 		// (particularly stack maps).  It takes a memory arg so it
 		// gets correctly ordered with respect to GC safepoints.
 		// arg0=ptr/int arg1=mem, output=int/ptr
-		{name: "MOVQconvert", argLength: 2, reg: gp11, asm: "MOVQ"},
-		{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL"}, // amd64p32 equivalent
+		{name: "MOVQconvert", argLength: 2, reg: gp11, asm: "MOVQ", resultInArg0: true},
+		{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true}, // amd64p32 equivalent
 
 		// Constant flag values. For any comparison, there are 5 possible
 		// outcomes: the three from the signed total order (<,==,>) and the
diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
index d66e50f..c3baa51 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
@@ -398,6 +398,7 @@
 
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Convert x mem) -> (MOVWconvert x mem)
 
 // Absorb pseudo-ops into blocks.
@@ -499,6 +500,10 @@
 (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
 (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
 (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
+(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBUreg x)
+(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBreg x)
+(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHUreg x)
+(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHreg x)
 
 // fold constant into arithmatic ops
 (ADD x (MOVWconst [c])) -> (ADDconst [c] x)
@@ -526,6 +531,9 @@
 
 (CMP x (MOVWconst [c])) -> (CMPconst [c] x)
 (CMP (MOVWconst [c]) x) -> (InvertFlags (CMPconst [c] x))
+(CMN x (MOVWconst [c])) -> (CMNconst [c] x)
+(TST x (MOVWconst [c])) -> (TSTconst [c] x)
+(TEQ x (MOVWconst [c])) -> (TEQconst [c] x)
 
 // don't extend after proper load
 // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
@@ -598,6 +606,28 @@
 (MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a)
 (MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
 
+(MULS x (MOVWconst [c]) a) && int32(c) == -1 -> (ADD a x)
+(MULS _ (MOVWconst [0]) a) -> a
+(MULS x (MOVWconst [1]) a) -> (RSB x a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c) -> (RSB (SLLconst <x.Type> [log2(c)] x) a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a)
+(MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a)
+(MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a)
+(MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a)
+(MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
+
+(MULS (MOVWconst [c]) x a) && int32(c) == -1 -> (ADD a x)
+(MULS (MOVWconst [0]) _ a) -> a
+(MULS (MOVWconst [1]) x a) -> (RSB x a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c) -> (RSB (SLLconst <x.Type> [log2(c)] x) a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a)
+(MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a)
+(MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a)
+(MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a)
+(MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
+
 // div by constant
 (Select0 (CALLudiv x (MOVWconst [1]))) -> x
 (Select1 (CALLudiv _ (MOVWconst [1]))) -> (MOVWconst [0])
@@ -610,6 +640,17 @@
 (CMPconst (MOVWconst [x]) [y]) && int32(x)<int32(y) && uint32(x)>uint32(y) -> (FlagLT_UGT)
 (CMPconst (MOVWconst [x]) [y]) && int32(x)>int32(y) && uint32(x)<uint32(y) -> (FlagGT_ULT)
 (CMPconst (MOVWconst [x]) [y]) && int32(x)>int32(y) && uint32(x)>uint32(y) -> (FlagGT_UGT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)==int32(-y) -> (FlagEQ)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)<int32(-y) && uint32(x)<uint32(-y) -> (FlagLT_ULT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)<int32(-y) && uint32(x)>uint32(-y) -> (FlagLT_UGT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)>int32(-y) && uint32(x)<uint32(-y) -> (FlagGT_ULT)
+(CMNconst (MOVWconst [x]) [y]) && int32(x)>int32(-y) && uint32(x)>uint32(-y) -> (FlagGT_UGT)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)==0 -> (FlagEQ)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)<0 -> (FlagLT_UGT)
+(TSTconst (MOVWconst [x]) [y]) && int32(x&y)>0 -> (FlagGT_UGT)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)==0 -> (FlagEQ)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)<0 -> (FlagLT_UGT)
+(TEQconst (MOVWconst [x]) [y]) && int32(x^y)>0 -> (FlagGT_UGT)
 
 // other known comparisons
 (CMPconst (MOVBUreg _) [c]) && 0xff < c -> (FlagLT_ULT)
@@ -799,8 +840,8 @@
 // generic constant folding
 (ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) -> (SUBconst [int64(int32(-c))] x)
 (SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) -> (ADDconst [int64(int32(-c))] x)
-(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (BICconst [int64(^uint32(c))] x)
-(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (ANDconst [int64(^uint32(c))] x)
+(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (BICconst [int64(int32(^uint32(c)))] x)
+(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (ANDconst [int64(int32(^uint32(c)))] x)
 (ADDconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(c+d))])
 (ADDconst [c] (ADDconst [d] x)) -> (ADDconst [int64(int32(c+d))] x)
 (ADDconst [c] (SUBconst [d] x)) -> (ADDconst [int64(int32(c-d))] x)
@@ -824,6 +865,7 @@
 (SRAconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)>>uint64(c))])
 (MUL (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c*d))])
 (MULA (MOVWconst [c]) (MOVWconst [d]) a) -> (ADDconst [int64(int32(c*d))] a)
+(MULS (MOVWconst [c]) (MOVWconst [d]) a) -> (SUBconst [int64(int32(c*d))] a)
 (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)/uint32(d))])
 (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)%uint32(d))])
 (ANDconst [c] (MOVWconst [d])) -> (MOVWconst [c&d])
@@ -840,6 +882,9 @@
 (MOVHreg (MOVWconst [c])) -> (MOVWconst [int64(int16(c))])
 (MOVHUreg (MOVWconst [c])) -> (MOVWconst [int64(uint16(c))])
 (MOVWreg (MOVWconst [c])) -> (MOVWconst [c])
+// BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width)
+(BFX [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
+(BFXU [c] (MOVWconst [d])) -> (MOVWconst [int64(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
 
 // absorb shifts into ops
 (ADD x (SLLconst [c] y)) -> (ADDshiftLL x y [c])
@@ -958,6 +1003,24 @@
 (CMP (SRL y z) x) -> (InvertFlags (CMPshiftRLreg x y z))
 (CMP x (SRA y z)) -> (CMPshiftRAreg x y z)
 (CMP (SRA y z) x) -> (InvertFlags (CMPshiftRAreg x y z))
+(TST x (SLLconst [c] y)) -> (TSTshiftLL x y [c])
+(TST x (SRLconst [c] y)) -> (TSTshiftRL x y [c])
+(TST x (SRAconst [c] y)) -> (TSTshiftRA x y [c])
+(TST x (SLL y z)) -> (TSTshiftLLreg x y z)
+(TST x (SRL y z)) -> (TSTshiftRLreg x y z)
+(TST x (SRA y z)) -> (TSTshiftRAreg x y z)
+(TEQ x (SLLconst [c] y)) -> (TEQshiftLL x y [c])
+(TEQ x (SRLconst [c] y)) -> (TEQshiftRL x y [c])
+(TEQ x (SRAconst [c] y)) -> (TEQshiftRA x y [c])
+(TEQ x (SLL y z)) -> (TEQshiftLLreg x y z)
+(TEQ x (SRL y z)) -> (TEQshiftRLreg x y z)
+(TEQ x (SRA y z)) -> (TEQshiftRAreg x y z)
+(CMN x (SLLconst [c] y)) -> (CMNshiftLL x y [c])
+(CMN x (SRLconst [c] y)) -> (CMNshiftRL x y [c])
+(CMN x (SRAconst [c] y)) -> (CMNshiftRA x y [c])
+(CMN x (SLL y z)) -> (CMNshiftLLreg x y z)
+(CMN x (SRL y z)) -> (CMNshiftRLreg x y z)
+(CMN x (SRA y z)) -> (CMNshiftRAreg x y z)
 
 // prefer *const ops to *shift ops
 (ADDshiftLL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d]))
@@ -1000,6 +1063,15 @@
 (CMPshiftLL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
 (CMPshiftRL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
 (CMPshiftRA (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+(TSTshiftLL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SLLconst <x.Type> x [d]))
+(TSTshiftRL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRLconst <x.Type> x [d]))
+(TSTshiftRA (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRAconst <x.Type> x [d]))
+(TEQshiftLL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SLLconst <x.Type> x [d]))
+(TEQshiftRL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRLconst <x.Type> x [d]))
+(TEQshiftRA (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRAconst <x.Type> x [d]))
+(CMNshiftLL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SLLconst <x.Type> x [d]))
+(CMNshiftRL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRLconst <x.Type> x [d]))
+(CMNshiftRA (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRAconst <x.Type> x [d]))
 
 (ADDshiftLLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SLL <x.Type> x y))
 (ADDshiftRLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRL <x.Type> x y))
@@ -1040,54 +1112,72 @@
 (CMPshiftLLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
 (CMPshiftRLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
 (CMPshiftRAreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
+(TSTshiftLLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SLL <x.Type> x y))
+(TSTshiftRLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRL <x.Type> x y))
+(TSTshiftRAreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRA <x.Type> x y))
+(TEQshiftLLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SLL <x.Type> x y))
+(TEQshiftRLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRL <x.Type> x y))
+(TEQshiftRAreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRA <x.Type> x y))
+(CMNshiftLLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SLL <x.Type> x y))
+(CMNshiftRLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRL <x.Type> x y))
+(CMNshiftRAreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRA <x.Type> x y))
 
 // constant folding in *shift ops
-(ADDshiftLL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(uint32(c)<<uint64(d))])
-(ADDshiftRL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(uint32(c)>>uint64(d))])
+(ADDshiftLL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(uint32(c)<<uint64(d)))])
+(ADDshiftRL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(uint32(c)>>uint64(d)))])
 (ADDshiftRA x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(c)>>uint64(d))])
-(ADCshiftLL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(uint32(c)<<uint64(d))] flags)
-(ADCshiftRL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(uint32(c)>>uint64(d))] flags)
+(ADCshiftLL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
+(ADCshiftRL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 (ADCshiftRA x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(c)>>uint64(d))] flags)
-(ADDSshiftLL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(uint32(c)<<uint64(d))])
-(ADDSshiftRL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(uint32(c)>>uint64(d))])
+(ADDSshiftLL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(uint32(c)<<uint64(d)))])
+(ADDSshiftRL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(uint32(c)>>uint64(d)))])
 (ADDSshiftRA x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(c)>>uint64(d))])
-(SUBshiftLL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(uint32(c)<<uint64(d))])
-(SUBshiftRL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(uint32(c)>>uint64(d))])
+(SUBshiftLL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(uint32(c)<<uint64(d)))])
+(SUBshiftRL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(uint32(c)>>uint64(d)))])
 (SUBshiftRA x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(c)>>uint64(d))])
-(SBCshiftLL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(uint32(c)<<uint64(d))] flags)
-(SBCshiftRL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(uint32(c)>>uint64(d))] flags)
+(SBCshiftLL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
+(SBCshiftRL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 (SBCshiftRA x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(c)>>uint64(d))] flags)
-(SUBSshiftLL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(uint32(c)<<uint64(d))])
-(SUBSshiftRL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(uint32(c)>>uint64(d))])
+(SUBSshiftLL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(uint32(c)<<uint64(d)))])
+(SUBSshiftRL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(uint32(c)>>uint64(d)))])
 (SUBSshiftRA x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(c)>>uint64(d))])
-(RSBshiftLL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(uint32(c)<<uint64(d))])
-(RSBshiftRL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(uint32(c)>>uint64(d))])
+(RSBshiftLL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(uint32(c)<<uint64(d)))])
+(RSBshiftRL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(uint32(c)>>uint64(d)))])
 (RSBshiftRA x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(c)>>uint64(d))])
-(RSCshiftLL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(uint32(c)<<uint64(d))] flags)
-(RSCshiftRL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(uint32(c)>>uint64(d))] flags)
+(RSCshiftLL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
+(RSCshiftRL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 (RSCshiftRA x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(c)>>uint64(d))] flags)
-(RSBSshiftLL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(uint32(c)<<uint64(d))])
-(RSBSshiftRL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(uint32(c)>>uint64(d))])
+(RSBSshiftLL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(uint32(c)<<uint64(d)))])
+(RSBSshiftRL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(uint32(c)>>uint64(d)))])
 (RSBSshiftRA x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(c)>>uint64(d))])
-(ANDshiftLL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(uint32(c)<<uint64(d))])
-(ANDshiftRL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(uint32(c)>>uint64(d))])
+(ANDshiftLL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(uint32(c)<<uint64(d)))])
+(ANDshiftRL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(uint32(c)>>uint64(d)))])
 (ANDshiftRA x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(c)>>uint64(d))])
-(ORshiftLL x (MOVWconst [c]) [d]) -> (ORconst x [int64(uint32(c)<<uint64(d))])
-(ORshiftRL x (MOVWconst [c]) [d]) -> (ORconst x [int64(uint32(c)>>uint64(d))])
+(ORshiftLL x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(uint32(c)<<uint64(d)))])
+(ORshiftRL x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(uint32(c)>>uint64(d)))])
 (ORshiftRA x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(c)>>uint64(d))])
-(XORshiftLL x (MOVWconst [c]) [d]) -> (XORconst x [int64(uint32(c)<<uint64(d))])
-(XORshiftRL x (MOVWconst [c]) [d]) -> (XORconst x [int64(uint32(c)>>uint64(d))])
+(XORshiftLL x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)<<uint64(d)))])
+(XORshiftRL x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)>>uint64(d)))])
 (XORshiftRA x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(c)>>uint64(d))])
-(XORshiftRR x (MOVWconst [c]) [d]) -> (XORconst x [int64(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
-(BICshiftLL x (MOVWconst [c]) [d]) -> (BICconst x [int64(uint32(c)<<uint64(d))])
-(BICshiftRL x (MOVWconst [c]) [d]) -> (BICconst x [int64(uint32(c)>>uint64(d))])
+(XORshiftRR x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d)))])
+(BICshiftLL x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(uint32(c)<<uint64(d)))])
+(BICshiftRL x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(uint32(c)>>uint64(d)))])
 (BICshiftRA x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(c)>>uint64(d))])
 (MVNshiftLL (MOVWconst [c]) [d]) -> (MOVWconst [^int64(uint32(c)<<uint64(d))])
 (MVNshiftRL (MOVWconst [c]) [d]) -> (MOVWconst [^int64(uint32(c)>>uint64(d))])
 (MVNshiftRA (MOVWconst [c]) [d]) -> (MOVWconst [^int64(int32(c)>>uint64(d))])
-(CMPshiftLL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(uint32(c)<<uint64(d))])
-(CMPshiftRL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(uint32(c)>>uint64(d))])
+(CMPshiftLL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(uint32(c)<<uint64(d)))])
+(CMPshiftRL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(uint32(c)>>uint64(d)))])
 (CMPshiftRA x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(c)>>uint64(d))])
+(TSTshiftLL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(uint32(c)<<uint64(d)))])
+(TSTshiftRL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(uint32(c)>>uint64(d)))])
+(TSTshiftRA x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(c)>>uint64(d))])
+(TEQshiftLL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(uint32(c)<<uint64(d)))])
+(TEQshiftRL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(uint32(c)>>uint64(d)))])
+(TEQshiftRA x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(c)>>uint64(d))])
+(CMNshiftLL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(uint32(c)<<uint64(d)))])
+(CMNshiftRL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(uint32(c)>>uint64(d)))])
+(CMNshiftRA x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(c)>>uint64(d))])
 
 (ADDshiftLLreg x y (MOVWconst [c])) -> (ADDshiftLL x y [c])
 (ADDshiftRLreg x y (MOVWconst [c])) -> (ADDshiftRL x y [c])
@@ -1134,6 +1224,15 @@
 (CMPshiftLLreg x y (MOVWconst [c])) -> (CMPshiftLL x y [c])
 (CMPshiftRLreg x y (MOVWconst [c])) -> (CMPshiftRL x y [c])
 (CMPshiftRAreg x y (MOVWconst [c])) -> (CMPshiftRA x y [c])
+(TSTshiftLLreg x y (MOVWconst [c])) -> (TSTshiftLL x y [c])
+(TSTshiftRLreg x y (MOVWconst [c])) -> (TSTshiftRL x y [c])
+(TSTshiftRAreg x y (MOVWconst [c])) -> (TSTshiftRA x y [c])
+(TEQshiftLLreg x y (MOVWconst [c])) -> (TEQshiftLL x y [c])
+(TEQshiftRLreg x y (MOVWconst [c])) -> (TEQshiftRL x y [c])
+(TEQshiftRAreg x y (MOVWconst [c])) -> (TEQshiftRA x y [c])
+(CMNshiftLLreg x y (MOVWconst [c])) -> (CMNshiftLL x y [c])
+(CMNshiftRLreg x y (MOVWconst [c])) -> (CMNshiftRL x y [c])
+(CMNshiftRAreg x y (MOVWconst [c])) -> (CMNshiftRA x y [c])
 
 // Generate rotates
 (ADDshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x)
@@ -1152,13 +1251,31 @@
 (MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftLL ptr idx [c] val mem)
 (MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRL ptr idx [c] val mem)
 (MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRA ptr idx [c] val mem)
+(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBUloadidx ptr idx mem)
+(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBloadidx ptr idx mem)
+(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVBstoreidx ptr idx val mem)
+(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHUloadidx ptr idx mem)
+(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHloadidx ptr idx mem)
+(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVHstoreidx ptr idx val mem)
 
 // constant folding in indexed loads and stores
 (MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem)
 (MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem)
+(MOVBloadidx ptr (MOVWconst [c]) mem) -> (MOVBload [c] ptr mem)
+(MOVBloadidx (MOVWconst [c]) ptr mem) -> (MOVBload [c] ptr mem)
+(MOVBUloadidx ptr (MOVWconst [c]) mem) -> (MOVBUload [c] ptr mem)
+(MOVBUloadidx (MOVWconst [c]) ptr mem) -> (MOVBUload [c] ptr mem)
+(MOVHUloadidx ptr (MOVWconst [c]) mem) -> (MOVHUload [c] ptr mem)
+(MOVHUloadidx (MOVWconst [c]) ptr mem) -> (MOVHUload [c] ptr mem)
+(MOVHloadidx ptr (MOVWconst [c]) mem) -> (MOVHload [c] ptr mem)
+(MOVHloadidx (MOVWconst [c]) ptr mem) -> (MOVHload [c] ptr mem)
 
 (MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem)
 (MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem)
+(MOVBstoreidx ptr (MOVWconst [c]) val mem) -> (MOVBstore [c] ptr val mem)
+(MOVBstoreidx (MOVWconst [c]) ptr val mem) -> (MOVBstore [c] ptr val mem)
+(MOVHstoreidx ptr (MOVWconst [c]) val mem) -> (MOVHstore [c] ptr val mem)
+(MOVHstoreidx (MOVWconst [c]) ptr val mem) -> (MOVHstore [c] ptr val mem)
 
 (MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem)
 (MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem)
@@ -1193,6 +1310,25 @@
 (BIC x x) -> (MOVWconst [0])
 
 (ADD (MUL x y) a) -> (MULA x y a)
+(SUB a (MUL x y)) && objabi.GOARM == 7 -> (MULS x y a)
+(RSB (MUL x y) a) && objabi.GOARM == 7 -> (MULS x y a)
+
+(NEGF (MULF x y)) && objabi.GOARM >= 6 -> (NMULF x y)
+(NEGD (MULD x y)) && objabi.GOARM >= 6 -> (NMULD x y)
+(MULF (NEGF x) y) && objabi.GOARM >= 6 -> (NMULF x y)
+(MULD (NEGD x) y) && objabi.GOARM >= 6 -> (NMULD x y)
+(NMULF (NEGF x) y) -> (MULF x y)
+(NMULD (NEGD x) y) -> (MULD x y)
+
+// the result will overwrite the addend, since they are in the same register
+(ADDF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y)
+(ADDF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y)
+(ADDD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y)
+(ADDD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y)
+(SUBF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y)
+(SUBF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y)
+(SUBD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y)
+(SUBD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y)
 
 (AND x (MVN y)) -> (BIC x y)
 
@@ -1222,3 +1358,75 @@
 // floating point optimizations
 (CMPF x (MOVFconst [0])) -> (CMPF0 x)
 (CMPD x (MOVDconst [0])) -> (CMPD0 x)
+
+// bit extraction
+(SRAconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFX [(d-c)|(32-d)<<8] x)
+(SRLconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFXU [(d-c)|(32-d)<<8] x)
+
+// comparison simplification
+(CMP x (RSBconst [0] y)) -> (CMN x y)
+(CMN x (RSBconst [0] y)) -> (CMP x y)
+(EQ (CMPconst [0] (SUB x y)) yes no) -> (EQ (CMP x y) yes no)
+(EQ (CMPconst [0] (SUBconst [c] x)) yes no) -> (EQ (CMPconst [c] x) yes no)
+(EQ (CMPconst [0] (SUBshiftLL x y [c])) yes no) -> (EQ (CMPshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftRL x y [c])) yes no) -> (EQ (CMPshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftRA x y [c])) yes no) -> (EQ (CMPshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (SUBshiftLLreg x y z)) yes no) -> (EQ (CMPshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (SUBshiftRLreg x y z)) yes no) -> (EQ (CMPshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (SUBshiftRAreg x y z)) yes no) -> (EQ (CMPshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (SUB x y)) yes no) -> (NE (CMP x y) yes no)
+(NE (CMPconst [0] (SUBconst [c] x)) yes no) -> (NE (CMPconst [c] x) yes no)
+(NE (CMPconst [0] (SUBshiftLL x y [c])) yes no) -> (NE (CMPshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftRL x y [c])) yes no) -> (NE (CMPshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftRA x y [c])) yes no) -> (NE (CMPshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (SUBshiftLLreg x y z)) yes no) -> (NE (CMPshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (SUBshiftRLreg x y z)) yes no) -> (NE (CMPshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (SUBshiftRAreg x y z)) yes no) -> (NE (CMPshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (ADD x y)) yes no) -> (EQ (CMN x y) yes no)
+(EQ (CMPconst [0] (ADDconst [c] x)) yes no) -> (EQ (CMNconst [c] x) yes no)
+(EQ (CMPconst [0] (ADDshiftLL x y [c])) yes no) -> (EQ (CMNshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftRL x y [c])) yes no) -> (EQ (CMNshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftRA x y [c])) yes no) -> (EQ (CMNshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (ADDshiftLLreg x y z)) yes no) -> (EQ (CMNshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (ADDshiftRLreg x y z)) yes no) -> (EQ (CMNshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (ADDshiftRAreg x y z)) yes no) -> (EQ (CMNshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (ADD x y)) yes no) -> (NE (CMN x y) yes no)
+(NE (CMPconst [0] (ADDconst [c] x)) yes no) -> (NE (CMNconst [c] x) yes no)
+(NE (CMPconst [0] (ADDshiftLL x y [c])) yes no) -> (NE (CMNshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftRL x y [c])) yes no) -> (NE (CMNshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftRA x y [c])) yes no) -> (NE (CMNshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (ADDshiftLLreg x y z)) yes no) -> (NE (CMNshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (ADDshiftRLreg x y z)) yes no) -> (NE (CMNshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (ADDshiftRAreg x y z)) yes no) -> (NE (CMNshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (AND x y)) yes no) -> (EQ (TST x y) yes no)
+(EQ (CMPconst [0] (ANDconst [c] x)) yes no) -> (EQ (TSTconst [c] x) yes no)
+(EQ (CMPconst [0] (ANDshiftLL x y [c])) yes no) -> (EQ (TSTshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftRL x y [c])) yes no) -> (EQ (TSTshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftRA x y [c])) yes no) -> (EQ (TSTshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (ANDshiftLLreg x y z)) yes no) -> (EQ (TSTshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (ANDshiftRLreg x y z)) yes no) -> (EQ (TSTshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (ANDshiftRAreg x y z)) yes no) -> (EQ (TSTshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (AND x y)) yes no) -> (NE (TST x y) yes no)
+(NE (CMPconst [0] (ANDconst [c] x)) yes no) -> (NE (TSTconst [c] x) yes no)
+(NE (CMPconst [0] (ANDshiftLL x y [c])) yes no) -> (NE (TSTshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftRL x y [c])) yes no) -> (NE (TSTshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftRA x y [c])) yes no) -> (NE (TSTshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (ANDshiftLLreg x y z)) yes no) -> (NE (TSTshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (ANDshiftRLreg x y z)) yes no) -> (NE (TSTshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (ANDshiftRAreg x y z)) yes no) -> (NE (TSTshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] (XOR x y)) yes no) -> (EQ (TEQ x y) yes no)
+(EQ (CMPconst [0] (XORconst [c] x)) yes no) -> (EQ (TEQconst [c] x) yes no)
+(EQ (CMPconst [0] (XORshiftLL x y [c])) yes no) -> (EQ (TEQshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftRL x y [c])) yes no) -> (EQ (TEQshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftRA x y [c])) yes no) -> (EQ (TEQshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] (XORshiftLLreg x y z)) yes no) -> (EQ (TEQshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] (XORshiftRLreg x y z)) yes no) -> (EQ (TEQshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] (XORshiftRAreg x y z)) yes no) -> (EQ (TEQshiftRAreg x y z) yes no)
+(NE (CMPconst [0] (XOR x y)) yes no) -> (NE (TEQ x y) yes no)
+(NE (CMPconst [0] (XORconst [c] x)) yes no) -> (NE (TEQconst [c] x) yes no)
+(NE (CMPconst [0] (XORshiftLL x y [c])) yes no) -> (NE (TEQshiftLL x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftRL x y [c])) yes no) -> (NE (TEQshiftRL x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftRA x y [c])) yes no) -> (NE (TEQshiftRA x y [c]) yes no)
+(NE (CMPconst [0] (XORshiftLLreg x y z)) yes no) -> (NE (TEQshiftLLreg x y z) yes no)
+(NE (CMPconst [0] (XORshiftRLreg x y z)) yes no) -> (NE (TEQshiftRLreg x y z) yes no)
+(NE (CMPconst [0] (XORshiftRAreg x y z)) yes no) -> (NE (TEQshiftRAreg x y z) yes no)
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
index 4831ff2..558e60f 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules
@@ -103,98 +103,68 @@
 (NeqB x y) -> (XOR x y)
 (Not x) -> (XOR (MOVDconst [1]) x)
 
-// constant shifts
-(Lsh64x64  x (MOVDconst [c])) && uint64(c) < 64 -> (SLLconst x [c])
-(Rsh64x64  x (MOVDconst [c])) && uint64(c) < 64 -> (SRAconst x [c])
-(Rsh64Ux64 x (MOVDconst [c])) && uint64(c) < 64 -> (SRLconst x [c])
-(Lsh32x64  x (MOVDconst [c])) && uint64(c) < 32 -> (SLLconst x [c])
-(Rsh32x64  x (MOVDconst [c])) && uint64(c) < 32 -> (SRAconst (SignExt32to64 x) [c])
-(Rsh32Ux64 x (MOVDconst [c])) && uint64(c) < 32 -> (SRLconst (ZeroExt32to64 x) [c])
-(Lsh16x64  x (MOVDconst [c])) && uint64(c) < 16 -> (SLLconst x [c])
-(Rsh16x64  x (MOVDconst [c])) && uint64(c) < 16 -> (SRAconst (SignExt16to64 x) [c])
-(Rsh16Ux64 x (MOVDconst [c])) && uint64(c) < 16 -> (SRLconst (ZeroExt16to64 x) [c])
-(Lsh8x64   x (MOVDconst [c])) && uint64(c) < 8  -> (SLLconst x [c])
-(Rsh8x64   x (MOVDconst [c])) && uint64(c) < 8  -> (SRAconst (SignExt8to64  x) [c])
-(Rsh8Ux64  x (MOVDconst [c])) && uint64(c) < 8  -> (SRLconst (ZeroExt8to64  x) [c])
-
-// large constant shifts
-(Lsh64x64  _ (MOVDconst [c])) && uint64(c) >= 64 -> (MOVDconst [0])
-(Rsh64Ux64 _ (MOVDconst [c])) && uint64(c) >= 64 -> (MOVDconst [0])
-(Lsh32x64  _ (MOVDconst [c])) && uint64(c) >= 32 -> (MOVDconst [0])
-(Rsh32Ux64 _ (MOVDconst [c])) && uint64(c) >= 32 -> (MOVDconst [0])
-(Lsh16x64  _ (MOVDconst [c])) && uint64(c) >= 16 -> (MOVDconst [0])
-(Rsh16Ux64 _ (MOVDconst [c])) && uint64(c) >= 16 -> (MOVDconst [0])
-(Lsh8x64   _ (MOVDconst [c])) && uint64(c) >= 8  -> (MOVDconst [0])
-(Rsh8Ux64  _ (MOVDconst [c])) && uint64(c) >= 8  -> (MOVDconst [0])
-
-// large constant signed right shift, we leave the sign bit
-(Rsh64x64 x (MOVDconst [c])) && uint64(c) >= 64 -> (SRAconst x [63])
-(Rsh32x64 x (MOVDconst [c])) && uint64(c) >= 32 -> (SRAconst (SignExt32to64 x) [63])
-(Rsh16x64 x (MOVDconst [c])) && uint64(c) >= 16 -> (SRAconst (SignExt16to64 x) [63])
-(Rsh8x64  x (MOVDconst [c])) && uint64(c) >= 8  -> (SRAconst (SignExt8to64  x) [63])
-
 // shifts
 // hardware instruction uses only the low 6 bits of the shift
 // we compare to 64 to ensure Go semantics for large shifts
-(Lsh64x64 <t> x y) -> (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh64x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh64x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Lsh64x64 <t> x y) -> (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Lsh64x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh64x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Lsh32x64 <t> x y) -> (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh32x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh32x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Lsh32x64 <t> x y) -> (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Lsh32x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh32x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Lsh16x64 <t> x y) -> (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh16x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh16x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Lsh16x64 <t> x y) -> (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Lsh16x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh16x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Lsh8x64 <t> x y) -> (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh8x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh8x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Lsh8x64 <t> x y) -> (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Lsh8x32 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) -> (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh8x8  <t> x y) -> (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Rsh64Ux64 <t> x y) -> (CSELULT (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh64Ux32 <t> x y) -> (CSELULT (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) -> (CSELULT (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh64Ux8  <t> x y) -> (CSELULT (SRL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Rsh64Ux64 <t> x y) -> (CSELULT (SRL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Rsh64Ux32 <t> x y) -> (CSELULT (SRL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) -> (CSELULT (SRL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh64Ux8  <t> x y) -> (CSELULT (SRL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Rsh32Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh32Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh32Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Rsh32Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Rsh32Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh32Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Rsh16Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh16Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh16Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Rsh16Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Rsh16Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh16Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Rsh8Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh8Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh8Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+(Rsh8Ux64 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
+(Rsh8Ux32 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh8Ux8  <t> x y) -> (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 
-(Rsh64x64 x y) -> (SRA x (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh64x32 x y) -> (SRA x (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh64x16 x y) -> (SRA x (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh64x8  x y) -> (SRA x (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+(Rsh64x64 x y) -> (SRA x (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
+(Rsh64x32 x y) -> (SRA x (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh64x16 x y) -> (SRA x (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh64x8  x y) -> (SRA x (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 
-(Rsh32x64 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh32x32 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh32x16 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh32x8  x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+(Rsh32x64 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
+(Rsh32x32 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh32x16 x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh32x8  x y) -> (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 
-(Rsh16x64 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh16x32 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh16x16 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh16x8  x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+(Rsh16x64 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
+(Rsh16x32 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh16x16 x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh16x8  x y) -> (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 
-(Rsh8x64 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh8x32 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh8x16 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh8x8  x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+(Rsh8x64 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
+(Rsh8x32 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh8x16 x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh8x8  x y) -> (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 
 // constants
 (Const64 [val]) -> (MOVDconst [val])
@@ -365,36 +335,69 @@
 	(MOVBstore [6] ptr (MOVDconst [0])
 		(MOVHstore [4] ptr (MOVDconst [0])
 			(MOVWstore ptr (MOVDconst [0]) mem)))
+(Zero [9] ptr mem) ->
+	(MOVBstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [10] ptr mem) ->
+	(MOVHstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [11] ptr mem) ->
+	(MOVBstore [10] ptr (MOVDconst [0])
+		(MOVHstore [8] ptr (MOVDconst [0])
+			(MOVDstore ptr (MOVDconst [0]) mem)))
 (Zero [12] ptr mem) ->
 	(MOVWstore [8] ptr (MOVDconst [0])
 		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [16] ptr mem) ->
-	(MOVDstore [8] ptr (MOVDconst [0])
-		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [24] ptr mem) ->
-	(MOVDstore [16] ptr (MOVDconst [0])
-		(MOVDstore [8] ptr (MOVDconst [0])
+(Zero [13] ptr mem) ->
+	(MOVBstore [12] ptr (MOVDconst [0])
+		(MOVWstore [8] ptr (MOVDconst [0])
 			(MOVDstore ptr (MOVDconst [0]) mem)))
+(Zero [14] ptr mem) ->
+	(MOVHstore [12] ptr (MOVDconst [0])
+		(MOVWstore [8] ptr (MOVDconst [0])
+			(MOVDstore ptr (MOVDconst [0]) mem)))
+(Zero [15] ptr mem) ->
+	(MOVBstore [14] ptr (MOVDconst [0])
+		(MOVHstore [12] ptr (MOVDconst [0])
+			(MOVWstore [8] ptr (MOVDconst [0])
+				(MOVDstore ptr (MOVDconst [0]) mem))))
+(Zero [16] ptr mem) ->
+	(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)
+
+(Zero [32] ptr mem) ->
+	(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))
+
+(Zero [48] ptr mem) ->
+	(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+			(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)))
+
+(Zero [64] ptr mem) ->
+	(STP [48] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
+			(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+				(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))))
 
 // strip off fractional word zeroing
-(Zero [s] ptr mem) && s%8 != 0 && s > 8 ->
-	(Zero [s%8]
-		(OffPtr <ptr.Type> ptr [s-s%8])
-		(Zero [s-s%8] ptr mem))
+(Zero [s] ptr mem) && s%16 != 0 && s > 16 ->
+	(Zero [s-s%16]
+		(OffPtr <ptr.Type> ptr [s%16])
+		(Zero [s%16] ptr mem))
 
 // medium zeroing uses a duff device
-// 4, 8, and 128 are magic constants, see runtime/mkduff.go
+// 4, 16, and 64 are magic constants, see runtime/mkduff.go
 (Zero [s] ptr mem)
-	&& s%8 == 0 && s > 24 && s <= 8*128
+	&& s%16 == 0 && s > 64 && s <= 16*64
 	&& !config.noDuffDevice ->
-	(DUFFZERO [4 * (128 - int64(s/8))] ptr mem)
+	(DUFFZERO [4 * (64 - int64(s/16))] ptr mem)
 
 // large zeroing uses a loop
 (Zero [s] ptr mem)
-	&& s%8 == 0 && (s > 8*128 || config.noDuffDevice) ->
+	&& s%16 == 0 && (s > 16*64 || config.noDuffDevice) ->
 	(LoweredZero
 		ptr
-		(ADDconst <ptr.Type> [s-8] ptr)
+		(ADDconst <ptr.Type> [s-16] ptr)
 		mem)
 
 // moves
@@ -464,6 +467,7 @@
 
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Convert x mem) -> (MOVDconvert x mem)
 
 // Absorb pseudo-ops into blocks.
@@ -521,6 +525,12 @@
 (EQ (CMPWconst [0] x) yes no) -> (ZW x yes no)
 (NE (CMPWconst [0] x) yes no) -> (NZW x yes no)
 
+// Absorb bit-tests into block
+(Z  (ANDconst [c] x) yes no) && oneBit(c) -> (TBZ  {ntz(c)} x yes no)
+(NZ (ANDconst [c] x) yes no) && oneBit(c) -> (TBNZ {ntz(c)} x yes no)
+(ZW  (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) -> (TBZ  {ntz(int64(uint32(c)))} x yes no)
+(NZW (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) -> (TBNZ {ntz(int64(uint32(c)))} x yes no)
+
 // fold offset into address
 (ADDconst [off1] (MOVDaddr [off2] {sym} ptr)) -> (MOVDaddr [off1+off2] {sym} ptr)
 
@@ -565,6 +575,9 @@
 (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
 	(MOVDstore [off1+off2] {sym} ptr val mem)
+(STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(off1+off2)
+	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
+	(STP [off1+off2] {sym} ptr val1 val2 mem)
 (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
 	(FMOVSstore [off1+off2] {sym} ptr val mem)
@@ -583,6 +596,9 @@
 (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
 	(MOVDstorezero [off1+off2] {sym} ptr mem)
+(MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2)
+	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
+	(MOVQstorezero [off1+off2] {sym} ptr mem)
 
 (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
 	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
@@ -637,6 +653,10 @@
 	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
 	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
+	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
+	(STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
 (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
 	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
@@ -661,12 +681,17 @@
 	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
 	(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(off1+off2)
+	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
+	(MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 
 // store zero
 (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) -> (MOVBstorezero [off] {sym} ptr mem)
 (MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) -> (MOVHstorezero [off] {sym} ptr mem)
 (MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) -> (MOVWstorezero [off] {sym} ptr mem)
 (MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) -> (MOVDstorezero [off] {sym} ptr mem)
+(STP [off] {sym} ptr (MOVDconst [0]) (MOVDconst [0]) mem) -> (MOVQstorezero [off] {sym} ptr mem)
 
 // replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
 // these seem to have bad interaction with other rules, resulting in slower code
@@ -1027,6 +1052,10 @@
 (GreaterEqual (InvertFlags x)) -> (LessEqual x)
 (GreaterEqualU (InvertFlags x)) -> (LessEqualU x)
 
+// Boolean-generating instructions always
+// zero upper bit of the register; no need to zero-extend
+(MOVBUreg x) && x.Type.IsBoolean() -> (MOVDreg x)
+
 // absorb flag constants into conditional instructions
 (CSELULT _ y (FlagEQ)) -> y
 (CSELULT x _ (FlagLT_ULT)) -> x
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
index 832bea2..10a19cb 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
@@ -144,6 +144,7 @@
 		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
 		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
 		gpstore0  = regInfo{inputs: []regMask{gpspsbg}}
+		gpstore2  = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}}
 		gpxchg    = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
 		gpcas     = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
 		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
@@ -275,13 +276,15 @@
 		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
 		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
 		{name: "MOVDstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "STP", argLength: 4, reg: gpstore2, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},         // store 16 bytes of arg1 and arg2 to arg0 + auxInt + aux.  arg3=mem.
 		{name: "FMOVSstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVS", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
 		{name: "FMOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
 
 		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
 		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
 		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  ar12=mem.
+		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVQstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store 16 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
 
 		// conversions
 		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
@@ -347,7 +350,7 @@
 			aux:       "Int64",
 			argLength: 2,
 			reg: regInfo{
-				inputs:   []regMask{gp},
+				inputs:   []regMask{buildReg("R16")},
 				clobbers: buildReg("R16 R30"),
 			},
 			faultOnNilArg0: true,
@@ -355,14 +358,14 @@
 
 		// large zeroing
 		// arg0 = address of memory to zero (in R16 aka arm64.REGRT1, changed as side effect)
-		// arg1 = address of the last element to zero
+		// arg1 = address of the last 16-byte unit to zero
 		// arg2 = mem
 		// returns mem
-		//	MOVD.P	ZR, 8(R16)
+		//	STP.P	(ZR,ZR), 16(R16)
 		//	CMP	Rarg1, R16
 		//	BLE	-2(PC)
 		// Note: the-end-of-the-memory may be not a valid pointer. it's a problem if it is spilled.
-		// the-end-of-the-memory - 8 is with the area to zero, ok to spill.
+		// the-end-of-the-memory - 16 is with the area to zero, ok to spill.
 		{
 			name:      "LoweredZero",
 			argLength: 3,
@@ -422,6 +425,9 @@
 		// use of R26 (arm64.REGCTXT, the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}},
 
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
 		// MOVDconvert converts between pointers and integers.
 		// We have a special op for this so as to not confuse GC
 		// (particularly stack maps).  It takes a memory arg so it
@@ -512,10 +518,12 @@
 		{name: "ULE"},
 		{name: "UGT"},
 		{name: "UGE"},
-		{name: "Z"},   // Control == 0 (take a register instead of flags)
-		{name: "NZ"},  // Control != 0
-		{name: "ZW"},  // Control == 0, 32-bit
-		{name: "NZW"}, // Control != 0, 32-bit
+		{name: "Z"},    // Control == 0 (take a register instead of flags)
+		{name: "NZ"},   // Control != 0
+		{name: "ZW"},   // Control == 0, 32-bit
+		{name: "NZW"},  // Control != 0, 32-bit
+		{name: "TBZ"},  // Control & (1 << Aux.(int64)) == 0
+		{name: "TBNZ"}, // Control & (1 << Aux.(int64)) != 0
 	}
 
 	archs = append(archs, arch{
diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go
index 40be5d6..d16675f 100644
--- a/src/cmd/compile/internal/ssa/gen/ARMOps.go
+++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go
@@ -122,6 +122,7 @@
 		fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}, clobbers: buildReg("F15")} // int-float conversion uses F15 as tmp
 		gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}, clobbers: buildReg("F15")}
 		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp31      = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
 		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
 		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
 		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
@@ -168,15 +169,23 @@
 
 		{name: "MULLU", argLength: 2, reg: gp22, asm: "MULLU", commutative: true}, // arg0 * arg1, high 32 bits in out0, low 32 bits in out1
 		{name: "MULA", argLength: 3, reg: gp31, asm: "MULA"},                      // arg0 * arg1 + arg2
+		{name: "MULS", argLength: 3, reg: gp31, asm: "MULS"},                      // arg2 - arg0 * arg1
 
-		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
-		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
-		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
-		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
-		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
-		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
-		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
-		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
+		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true},   // arg0 + arg1
+		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true},   // arg0 + arg1
+		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                      // arg0 - arg1
+		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                      // arg0 - arg1
+		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true},   // arg0 * arg1
+		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true},   // arg0 * arg1
+		{name: "NMULF", argLength: 2, reg: fp21, asm: "NMULF", commutative: true}, // -(arg0 * arg1)
+		{name: "NMULD", argLength: 2, reg: fp21, asm: "NMULD", commutative: true}, // -(arg0 * arg1)
+		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                      // arg0 / arg1
+		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                      // arg0 / arg1
+
+		{name: "MULAF", argLength: 3, reg: fp31, asm: "MULAF", resultInArg0: true}, // arg0 + (arg1 * arg2)
+		{name: "MULAD", argLength: 3, reg: fp31, asm: "MULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
+		{name: "MULSF", argLength: 3, reg: fp31, asm: "MULSF", resultInArg0: true}, // arg0 - (arg1 * arg2)
+		{name: "MULSD", argLength: 3, reg: fp31, asm: "MULSD", resultInArg0: true}, // arg0 - (arg1 * arg2)
 
 		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
 		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"}, // arg0 & auxInt
@@ -187,6 +196,10 @@
 		{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"},                    // arg0 &^ arg1
 		{name: "BICconst", argLength: 1, reg: gp11, asm: "BIC", aux: "Int32"}, // arg0 &^ auxInt
 
+		// bit extraction, AuxInt = Width<<8 | LSB
+		{name: "BFX", argLength: 1, reg: gp11, asm: "BFX", aux: "Int32"},   // extract W bits from bit L in arg0, then signed extend
+		{name: "BFXU", argLength: 1, reg: gp11, asm: "BFXU", aux: "Int32"}, // extract W bits from bit L in arg0, then unsigned extend
+
 		// unary ops
 		{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
 
@@ -301,7 +314,7 @@
 		// comparisons
 		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                    // arg0 compare to arg1
 		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
-		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags"},                    // arg0 compare to -arg1
+		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1
 		{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
 		{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
 		{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
@@ -313,10 +326,28 @@
 		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1<<auxInt
 		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
 		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
+		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1<<auxInt)
+		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), unsigned shift
+		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), signed shift
+		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1<<auxInt) compare to 0
+		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, unsigned shift
+		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, signed shift
+		{name: "TEQshiftLL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1<<auxInt) compare to 0
+		{name: "TEQshiftRL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, unsigned shift
+		{name: "TEQshiftRA", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, signed shift
 
 		{name: "CMPshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1<<arg2
 		{name: "CMPshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, unsigned shift
 		{name: "CMPshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, signed shift
+		{name: "CMNshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1<<arg2) compare to 0
+		{name: "CMNshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, unsigned shift
+		{name: "CMNshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, signed shift
+		{name: "TSTshiftLLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1<<arg2) compare to 0
+		{name: "TSTshiftRLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, unsigned shift
+		{name: "TSTshiftRAreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, signed shift
+		{name: "TEQshiftLLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1<<arg2) compare to 0
+		{name: "TEQshiftRLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, unsigned shift
+		{name: "TEQshiftRAreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, signed shift
 
 		{name: "CMPF0", argLength: 1, reg: fp1flags, asm: "CMPF", typ: "Flags"}, // arg0 compare to 0, float32
 		{name: "CMPD0", argLength: 1, reg: fp1flags, asm: "CMPD", typ: "Flags"}, // arg0 compare to 0, float64
@@ -346,11 +377,17 @@
 		{name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1<<auxInt. arg2=mem
 		{name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem
 		{name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem
+		{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU"},                 // load from arg0 + arg1. arg2=mem
+		{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB"},                   // load from arg0 + arg1. arg2=mem
+		{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU"},                 // load from arg0 + arg1. arg2=mem
+		{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH"},                   // load from arg0 + arg1. arg2=mem
 
 		{name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW"},                   // store arg2 to arg0 + arg1. arg3=mem
 		{name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem
 		{name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem
 		{name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem
+		{name: "MOVBstoreidx", argLength: 4, reg: gp2store, asm: "MOVB"},                   // store arg2 to arg0 + arg1. arg3=mem
+		{name: "MOVHstoreidx", argLength: 4, reg: gp2store, asm: "MOVH"},                   // store arg2 to arg0 + arg1. arg3=mem
 
 		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"},  // move from arg0, sign-extended from byte
 		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
@@ -479,6 +516,9 @@
 		// use of R7 (arm.REGCTXT, the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}},
 
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
 		// MOVWconvert converts between pointers and integers.
 		// We have a special op for this so as to not confuse GC
 		// (particularly stack maps).  It takes a memory arg so it
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules
index 60a3722..2e7a023 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules
@@ -437,6 +437,7 @@
 
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Convert x mem) -> (MOVWconvert x mem)
 
 (If cond yes no) -> (NE cond yes no)
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
index 2a3a9c2..a95b1fc 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
@@ -71,65 +71,65 @@
 // shifts
 // hardware instruction uses only the low 6 bits of the shift
 // we compare to 64 to ensure Go semantics for large shifts
-(Lsh64x64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh64x32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh64x8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+(Lsh64x64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh64x32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh64x8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 
-(Lsh32x64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh32x32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh32x8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+(Lsh32x64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh32x32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh32x8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 
-(Lsh16x64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh16x32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh16x8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+(Lsh16x64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh16x32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh16x8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 
-(Lsh8x64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh8x32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh8x8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+(Lsh8x64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh8x32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh8x8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 
-(Rsh64Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> x y))
-(Rsh64Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
-(Rsh64Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
+(Rsh64Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
+(Rsh64Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
+(Rsh64Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
 
-(Rsh32Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
-(Rsh32Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
-(Rsh32Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
+(Rsh32Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
+(Rsh32Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
+(Rsh32Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
 
-(Rsh16Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
-(Rsh16Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Rsh16Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
+(Rsh16Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
+(Rsh16Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Rsh16Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
 
-(Rsh8Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
-(Rsh8Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
-(Rsh8Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
+(Rsh8Ux64 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
+(Rsh8Ux32 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
+(Rsh8Ux8  <t> x y) -> (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
 
-(Rsh64x64 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
-(Rsh64x32 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh64x16 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh64x8  <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+(Rsh64x64 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh64x32 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh64x16 <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh64x8  <t> x y) -> (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 
-(Rsh32x64 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
-(Rsh32x32 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh32x16 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh32x8  <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+(Rsh32x64 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh32x32 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh32x16 <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh32x8  <t> x y) -> (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 
-(Rsh16x64 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
-(Rsh16x32 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh16x16 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh16x8  <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+(Rsh16x64 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh16x32 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh16x16 <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh16x8  <t> x y) -> (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 
-(Rsh8x64 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
-(Rsh8x32 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh8x16 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh8x8  <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+(Rsh8x64 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh8x32 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh8x16 <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh8x8  <t> x y) -> (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 
 // unary ops
 (Neg64 x) -> (NEGV x)
@@ -419,6 +419,24 @@
 (ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem)
 (InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
 
+// atomic intrinsics
+(AtomicLoad32  ptr mem) -> (LoweredAtomicLoad32 ptr mem)
+(AtomicLoad64  ptr mem) -> (LoweredAtomicLoad64 ptr mem)
+(AtomicLoadPtr ptr mem) -> (LoweredAtomicLoad64 ptr mem)
+
+(AtomicStore32      ptr val mem) -> (LoweredAtomicStore32 ptr val mem)
+(AtomicStore64      ptr val mem) -> (LoweredAtomicStore64 ptr val mem)
+(AtomicStorePtrNoWB ptr val mem) -> (LoweredAtomicStore64 ptr val mem)
+
+(AtomicExchange32 ptr val mem) -> (LoweredAtomicExchange32 ptr val mem)
+(AtomicExchange64 ptr val mem) -> (LoweredAtomicExchange64 ptr val mem)
+
+(AtomicAdd32 ptr val mem) -> (LoweredAtomicAdd32 ptr val mem)
+(AtomicAdd64 ptr val mem) -> (LoweredAtomicAdd64 ptr val mem)
+
+(AtomicCompareAndSwap32 ptr old new_ mem) -> (LoweredAtomicCas32 ptr old new_ mem)
+(AtomicCompareAndSwap64 ptr old new_ mem) -> (LoweredAtomicCas64 ptr old new_ mem)
+
 // checks
 (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
 (IsNonNil ptr) -> (SGTU ptr (MOVVconst [0]))
@@ -427,6 +445,7 @@
 
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Convert x mem) -> (MOVVconvert x mem)
 
 (If cond yes no) -> (NE cond yes no)
@@ -661,6 +680,10 @@
 (MOVWreg  (MOVVconst [c])) -> (MOVVconst [int64(int32(c))])
 (MOVWUreg (MOVVconst [c])) -> (MOVVconst [int64(uint32(c))])
 (MOVVreg  (MOVVconst [c])) -> (MOVVconst [c])
+(LoweredAtomicStore32 ptr (MOVVconst [0]) mem) -> (LoweredAtomicStorezero32 ptr mem)
+(LoweredAtomicStore64 ptr (MOVVconst [0]) mem) -> (LoweredAtomicStorezero64 ptr mem)
+(LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) -> (LoweredAtomicAddconst32 [c] ptr mem)
+(LoweredAtomicAdd64 ptr (MOVVconst [c]) mem) && is32Bit(c) -> (LoweredAtomicAddconst64 [c] ptr mem)
 
 // constant comparisons
 (SGTconst [c] (MOVVconst [d])) && int64(c)>int64(d) -> (MOVVconst [1])
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
index b0e6564..592a85e 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
@@ -147,6 +147,8 @@
 		gpload   = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
 		gpstore  = regInfo{inputs: []regMask{gpspsbg, gpg}}
 		gpstore0 = regInfo{inputs: []regMask{gpspsbg}}
+		gpxchg   = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gpcas    = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
 		fp01     = regInfo{inputs: nil, outputs: []regMask{fp}}
 		fp11     = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
 		//fp1flags  = regInfo{inputs: []regMask{fp}}
@@ -161,7 +163,7 @@
 	ops := []opData{
 		// binary ops
 		{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},                             // arg0 + arg1
-		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"},                           // arg0 + auxInt
+		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"},                           // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
 		{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                                                // arg0 - arg1
 		{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},                             // arg0 - auxInt
 		{name: "MULV", argLength: 2, reg: gp2hilo, asm: "MULV", commutative: true, typ: "(Int64,Int64)"},     // arg0 * arg1, signed, results hi,lo
@@ -333,6 +335,65 @@
 			faultOnNilArg1: true,
 		},
 
+		// atomic loads.
+		// load from arg0. arg1=mem.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
+
+		// atomic stores.
+		// store arg1 to arg0. arg2=mem. returns memory.
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		// store zero to arg0. arg1=mem. returns memory.
+		{name: "LoweredAtomicStorezero32", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStorezero64", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// MOVV Rarg1, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// ADDV Rarg1, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		// ADDV Rarg1, Rout
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		// *arg0 += auxint. arg1=mem. returns <new content of *arg0, memory>. auxint is 32-bit.
+		{name: "LoweredAtomicAddconst32", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicAddconst64", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int64", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// SYNC
+		// MOVV $0, Rout
+		// LL	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 4(PC)
+		// MOVV Rarg2, Rout
+		// SC	Rout, (Rarg0)
+		// BEQ	Rout, -4(PC)
+		// SYNC
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
 		// pseudo-ops
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
 
@@ -344,6 +405,9 @@
 		// use of R22 (mips.REGCTXT, the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
 
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
 		// MOVDconvert converts between pointers and integers.
 		// We have a special op for this so as to not confuse GC
 		// (particularly stack maps).  It takes a memory arg so it
diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
index b632c6b..155a20b 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
@@ -376,6 +376,9 @@
 		// use of R22 (mips.REGCTXT, the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
 
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
 		// MOVWconvert converts between pointers and integers.
 		// We have a special op for this so as to not confuse GC
 		// (particularly stack maps).  It takes a memory arg so it
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index 81ac3c2..4fd6a5a 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -57,15 +57,15 @@
 (Div64F x y) -> (FDIV x y)
 
 // Lowering float <-> int
-(Cvt32to32F x) -> (FRSP (FCFID (Xi2f64 (SignExt32to64 x))))
-(Cvt32to64F x) -> (FCFID (Xi2f64 (SignExt32to64 x)))
-(Cvt64to32F x) -> (FRSP (FCFID (Xi2f64 x)))
-(Cvt64to64F x) -> (FCFID (Xi2f64 x))
+(Cvt32to32F x) -> (FCFIDS (MTVSRD (SignExt32to64 x)))
+(Cvt32to64F x) -> (FCFID (MTVSRD (SignExt32to64 x)))
+(Cvt64to32F x) -> (FCFIDS (MTVSRD x))
+(Cvt64to64F x) -> (FCFID (MTVSRD x))
 
-(Cvt32Fto32 x) -> (Xf2i64 (FCTIWZ x))
-(Cvt32Fto64 x) -> (Xf2i64 (FCTIDZ x))
-(Cvt64Fto32 x) -> (Xf2i64 (FCTIWZ x))
-(Cvt64Fto64 x) -> (Xf2i64 (FCTIDZ x))
+(Cvt32Fto32 x) -> (MFVSRD (FCTIWZ x))
+(Cvt32Fto64 x) -> (MFVSRD (FCTIDZ x))
+(Cvt64Fto32 x) -> (MFVSRD (FCTIWZ x))
+(Cvt64Fto64 x) -> (MFVSRD (FCTIDZ x))
 
 (Cvt32Fto64F x) -> x // Note x will have the wrong type for patterns dependent on Float32/Float64
 (Cvt64Fto32F x) -> (FRSP x)
@@ -74,6 +74,11 @@
 (Round64F x) -> (LoweredRound64F x)
 
 (Sqrt x) -> (FSQRT x)
+(Floor x) -> (FFLOOR x)
+(Ceil x) -> (FCEIL x)
+(Trunc x) -> (FTRUNC x)
+(Copysign x y) -> (FCPSGN y x)
+(Abs x) -> (FABS x)
 
 // Lowering constants
 (Const8   [val]) -> (MOVDconst [val])
@@ -85,7 +90,14 @@
 (ConstNil) -> (MOVDconst [0])
 (ConstBool [b]) -> (MOVDconst [b])
 
-// Rotate generation
+// Constant folding
+(FABS (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Abs(i2f(x)))])
+(FSQRT (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Sqrt(i2f(x)))])
+(FFLOOR (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Floor(i2f(x)))])
+(FCEIL (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Ceil(i2f(x)))])
+(FTRUNC (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Trunc(i2f(x)))])
+
+// Rotate generation with const shift
 (ADD (SLDconst x [c]) (SRDconst x [d])) && d == 64-c -> (ROTLconst [c] x)
 ( OR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c -> (ROTLconst [c] x)
 (XOR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c -> (ROTLconst [c] x)
@@ -94,6 +106,16 @@
 ( OR (SLWconst x [c]) (SRWconst x [d])) && d == 32-c -> (ROTLWconst [c] x)
 (XOR (SLWconst x [c]) (SRWconst x [d])) && d == 32-c -> (ROTLWconst [c] x)
 
+// Rotate generation with non-const shift
+// these match patterns from math/bits/RotateLeft[32|64], but there could be others
+(ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) -> (ROTL x y)
+( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) -> (ROTL x y)
+(XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) -> (ROTL x y)
+
+(ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) -> (ROTLW x y)
+( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) -> (ROTLW x y)
+(XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) -> (ROTLW x y)
+
 (Lsh64x64  x (Const64 [c])) && uint64(c) < 64 -> (SLDconst x [c])
 (Rsh64x64  x (Const64 [c])) && uint64(c) < 64 -> (SRADconst x [c])
 (Rsh64Ux64 x (Const64 [c])) && uint64(c) < 64 -> (SRDconst x [c])
@@ -163,10 +185,38 @@
 (Rsh8x32   x (MOVDconst [c])) && uint32(c) < 8  -> (SRAWconst (SignExt8to32  x) [c])
 (Rsh8Ux32  x (MOVDconst [c])) && uint32(c) < 8  -> (SRWconst (ZeroExt8to32  x) [c])
 
+// non-constant rotates
+// These are subexpressions found in statements that can become rotates
+// In these cases the shift count is known to be < 64 so the more complicated expressions
+// with Mask & Carry is not needed
+(Lsh64x64 x (AND y (MOVDconst [63]))) -> (SLD x (ANDconst <typ.Int64> [63] y))
+(Lsh64x64 x (ANDconst <typ.Int64> [63] y)) -> (SLD x (ANDconst <typ.Int64> [63] y))
+(Rsh64Ux64 x (AND y (MOVDconst [63]))) -> (SRD x (ANDconst <typ.Int64> [63] y))
+(Rsh64Ux64 x (ANDconst <typ.UInt> [63] y)) -> (SRD x (ANDconst <typ.UInt> [63] y))
+(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) -> (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) -> (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64x64 x (AND y (MOVDconst [63]))) -> (SRAD x (ANDconst <typ.Int64> [63] y))
+(Rsh64x64 x (ANDconst <typ.UInt> [63] y)) -> (SRAD x (ANDconst <typ.UInt> [63] y))
+(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) -> (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) -> (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+
 (Rsh64x64 x y)  -> (SRAD x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
 (Rsh64Ux64 x y) -> (SRD  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
 (Lsh64x64 x y)  -> (SLD  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
 
+(Lsh32x64 x (AND y (MOVDconst [31]))) -> (SLW x (ANDconst <typ.Int32> [31] y))
+(Lsh32x64 x (ANDconst <typ.Int32> [31] y)) -> (SLW x (ANDconst <typ.Int32> [31] y))
+
+(Rsh32Ux64 x (AND y (MOVDconst [31]))) -> (SRW x (ANDconst <typ.Int32> [31] y))
+(Rsh32Ux64 x (ANDconst <typ.UInt> [31] y)) -> (SRW x (ANDconst <typ.UInt> [31] y))
+(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) -> (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) -> (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+
+(Rsh32x64 x (AND y (MOVDconst [31]))) -> (SRAW x (ANDconst <typ.Int32> [31] y))
+(Rsh32x64 x (ANDconst <typ.UInt> [31] y)) -> (SRAW x (ANDconst <typ.UInt> [31] y))
+(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) -> (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) -> (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+
 (Rsh32x64 x y)  -> (SRAW x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
 (Rsh32Ux64 x y) -> (SRW  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
 (Lsh32x64 x y)  -> (SLW  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
@@ -179,7 +229,6 @@
 (Rsh8Ux64 x y) -> (SRW  (ZeroExt8to32 x) (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-8] y))))
 (Lsh8x64 x y)  -> (SLW  x                (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-8] y))))
 
-
 (Rsh64x32 x y)  -> (SRAD x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] (ZeroExt32to64 y)))))
 (Rsh64Ux32 x y) -> (SRD x  (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] (ZeroExt32to64 y)))))
 (Lsh64x32 x y)  -> (SLD x  (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] (ZeroExt32to64 y)))))
@@ -241,7 +290,6 @@
 // (MaskIfNotCarry CarrySet) -> -1
 
 (Addr {sym} base) -> (MOVDaddr {sym} base)
-// (Addr {sym} base) -> (ADDconst {sym} base)
 (OffPtr [off] ptr) -> (ADD (MOVDconst <typ.Int64> [off]) ptr)
 
 (Ctz64 x) -> (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
@@ -526,49 +574,29 @@
 	(MOVBstorezero [6] destptr
 		(MOVHstorezero [4] destptr
 			(MOVWstorezero destptr mem)))
-(Zero [8] destptr mem) ->
-	(MOVDstorezero destptr mem)
 
-// Zero small numbers of words directly.
-(Zero [12] destptr mem) ->
+// MOVD for store with DS must have offsets that are multiple of 4
+(Zero [8] {t} destptr mem) && t.(*types.Type).Alignment()%4 == 0 ->
+        (MOVDstorezero destptr mem)
+(Zero [8] destptr mem) ->
+        (MOVWstorezero [4] destptr
+                (MOVWstorezero [0] destptr mem))
+// Handle these cases only if aligned properly, otherwise use general case below
+(Zero [12] {t} destptr mem) && t.(*types.Type).Alignment()%4 == 0 ->
         (MOVWstorezero [8] destptr
                 (MOVDstorezero [0] destptr mem))
-(Zero [16] destptr mem) ->
-	(MOVDstorezero [8] destptr
+(Zero [16] {t} destptr mem) && t.(*types.Type).Alignment()%4 == 0 ->
+       (MOVDstorezero [8] destptr
                 (MOVDstorezero [0] destptr mem))
-(Zero [24] destptr mem) ->
-	(MOVDstorezero [16] destptr
-		(MOVDstorezero [8] destptr
-			(MOVDstorezero [0] destptr mem)))
-(Zero [32] destptr mem) ->
-	(MOVDstorezero [24] destptr
-		(MOVDstorezero [16] destptr
-			(MOVDstorezero [8] destptr
-				(MOVDstorezero [0] destptr mem))))
-
-(Zero [40] destptr mem) ->
-	(MOVDstorezero [32] destptr
-		(MOVDstorezero [24] destptr
-			(MOVDstorezero [16] destptr
-				(MOVDstorezero [8] destptr
-					(MOVDstorezero [0] destptr mem)))))
-
-(Zero [48] destptr mem) ->
-	(MOVDstorezero [40] destptr
-		(MOVDstorezero [32] destptr
-			(MOVDstorezero [24] destptr
-				(MOVDstorezero [16] destptr
-					(MOVDstorezero [8] destptr
-						(MOVDstorezero [0] destptr mem))))))
-
-(Zero [56] destptr mem) ->
-	(MOVDstorezero [48] destptr
-		(MOVDstorezero [40] destptr
-			(MOVDstorezero [32] destptr
-				(MOVDstorezero [24] destptr
-					(MOVDstorezero [16] destptr
-						(MOVDstorezero [8] destptr
-							(MOVDstorezero [0] destptr mem)))))))
+(Zero [24] {t} destptr mem) && t.(*types.Type).Alignment()%4 == 0 ->
+       (MOVDstorezero [16] destptr
+               (MOVDstorezero [8] destptr
+                       (MOVDstorezero [0] destptr mem)))
+(Zero [32] {t} destptr mem) && t.(*types.Type).Alignment()%4 == 0 ->
+       (MOVDstorezero [24] destptr
+               (MOVDstorezero [16] destptr
+                       (MOVDstorezero [8] destptr
+                               (MOVDstorezero [0] destptr mem))))
 
 // Handle cases not handled above
 (Zero [s] ptr mem) -> (LoweredZero [s] ptr mem)
@@ -617,6 +645,7 @@
 // Miscellaneous
 (Convert <t> x mem) -> (MOVDconvert <t> x mem)
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr))
 (IsInBounds idx len) -> (LessThan (CMPU idx len))
 (IsSliceInBounds idx len) -> (LessEqual (CMPU idx len))
@@ -708,6 +737,20 @@
 
 (ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x)
 
+// Use register moves instead of stores and loads to move int<->float values
+// Common with math Float64bits, Float64frombits
+(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _)) -> (MFVSRD x)
+(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _)) -> (MTVSRD x)
+
+(FMOVDstore [off] {sym} ptr (MTVSRD x) mem) -> (MOVDstore [off] {sym} ptr x mem)
+(MOVDstore [off] {sym} ptr (MFVSRD x) mem) -> (FMOVDstore [off] {sym} ptr x mem)
+
+(MTVSRD (MOVDconst [c])) -> (FMOVDconst [c])
+(MFVSRD (FMOVDconst [c])) -> (MOVDconst [c])
+
+(MTVSRD x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (FMOVDload [off] {sym} ptr mem)
+(MFVSRD x:(FMOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload [off] {sym} ptr mem)
+
 // Fold offsets for stores.
 (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVDstore [off1+off2] {sym} x val mem)
 (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVWstore [off1+off2] {sym} x val mem)
@@ -717,35 +760,54 @@
 (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(off1+off2) -> (FMOVSstore [off1+off2] {sym} ptr val mem)
 (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(off1+off2) -> (FMOVDstore [off1+off2] {sym} ptr val mem)
 
-(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+// Fold address into load/store.
+// The assembler needs to generate several instructions and use
+// temp register for accessing global, and each time it will reload
+// the temp register. So don't fold address of global, unless there
+// is only one use.
+(MOVBstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(MOVHstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(MOVWstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 
-(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(FMOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 
-(MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVBZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVHload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVHZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(FMOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& (ptr.Op != OpSB || p.Uses == 1) ->
         (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 
 // Fold offsets for loads.
@@ -776,13 +838,17 @@
     (MOVBstorezero [off1+off2] {sym} x mem)
 
 // Fold symbols into storezero
-(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+(MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
+	&& (x.Op != OpSB || p.Uses == 1) ->
     (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+(MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
+	&& (x.Op != OpSB || p.Uses == 1) ->
     (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+(MOVHstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
+	&& (x.Op != OpSB || p.Uses == 1) ->
     (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+(MOVBstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
+	&& (x.Op != OpSB || p.Uses == 1) ->
     (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 
 // atomic intrinsics
@@ -870,8 +936,126 @@
 (AND (MOVDconst [c]) x:(MOVBZload _ _)) -> (ANDconst [c&0xFF] x)
 (AND x:(MOVBZload _ _) (MOVDconst [c])) -> (ANDconst [c&0xFF] x)
 
+// floating point negative abs
+(FNEG (FABS x)) -> (FNABS x)
+(FNEG (FNABS x)) -> (FABS x)
+
 // floating-point fused multiply-add/sub
 (FADD (FMUL x y) z) -> (FMADD x y z)
 (FSUB (FMUL x y) z) -> (FMSUB x y z)
 (FADDS (FMULS x y) z) -> (FMADDS x y z)
 (FSUBS (FMULS x y) z) -> (FMSUBS x y z)
+
+
+// The following statements are found in encoding/binary functions UintXX (load) and PutUintXX (store)
+// and convert the statements in these functions from multiple single byte loads or stores to
+// the single largest possible load or store. For now only little endian loads and stores on
+// little endian machines are implemented. Longer rules make use of the match with shorter rules
+// where possible.
+// TODO implement big endian loads and stores for little endian machines (using byte reverse
+// loads and stores).
+// b[0] | b[1]<<8 -> load 16-bit Little endian
+(OR <t> x0:(MOVBZload [i0] {s} p mem)
+	o1:(SLWconst x1:(MOVBZload [i1] {s} p mem) [8]))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& x0.Uses ==1 && x1.Uses == 1
+	&& o1.Uses == 1
+	&& mergePoint(b, x0, x1) != nil
+	&& clobber(x0) && clobber(x1) && clobber(o1)
+	 -> @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 -> load 32-bit Little endian
+(OR <t> s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24])
+	o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16]) x0:(MOVHZload [i0] {s} p mem)))
+	&& !config.BigEndian
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1
+	&& o0.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1
+	&& mergePoint(b, x0, x1, x2) != nil
+	&& clobber(x0) && clobber(x1) && clobber(x2)
+	&& clobber(s0) && clobber(s1)
+	&& clobber(o0)
+	 -> @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4] <<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 -> load 64-bit Little endian
+// Can't build on shorter rules because they use SLW instead of SLD
+// Offset must be multiple of 4 for MOVD
+(OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56])
+	o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])
+	o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])
+	o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])
+	o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])
+	o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])
+	o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))))))
+	&& !config.BigEndian
+	&& i0%4 == 0
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
+	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil
+	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7)
+	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6)
+	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	  -> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+
+// 2 byte store Little endian as in:
+//      b[0] = byte(v)
+//      b[1] = byte(v >> 8)
+(MOVBstore [i1] {s} p (SRWconst (MOVHZreg w) [8])
+	x0:(MOVBstore [i0] {s} p w mem))
+	&& !config.BigEndian
+	&& x0.Uses == 1
+	&& i1 == i0+1
+	&& clobber(x0)
+	  -> (MOVHstore [i0] {s} p w mem)
+
+// 4 byte store Little endian as in:
+//     b[0] = byte(v)
+//     b[1] = byte(v >> 8)
+//     b[2] = byte(v >> 16)
+//     b[3] = byte(v >> 24)
+(MOVBstore [i3] {s} p (SRWconst w [24])
+	x0:(MOVBstore [i2] {s} p (SRWconst w [16])
+	x1:(MOVBstore [i1] {s} p (SRWconst w [8])
+	x2:(MOVBstore [i0] {s} p w mem))))
+	&& !config.BigEndian
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3
+	&& clobber(x0) && clobber(x1) && clobber(x2)
+	  -> (MOVWstore [i0] {s} p w mem)
+
+// 8 byte store Little endian as in:
+//	b[0] = byte(v)
+//	b[1] = byte(v >> 8)
+//	b[2] = byte(v >> 16)
+//	b[3] = byte(v >> 24)
+//	b[4] = byte(v >> 32)
+//	b[5] = byte(v >> 40)
+//	b[6] = byte(v >> 48)
+//	b[7] = byte(v >> 56)
+// Offset must be multiple of 4 for MOVDstore
+// Can't build on previous rules for 2 or 4 bytes because they use SRW not SRD
+(MOVBstore [i7] {s} p (SRDconst w [56])
+	x0:(MOVBstore [i6] {s} p (SRDconst w [48])
+	x1:(MOVBstore [i5] {s} p (SRDconst w [40])
+	x2:(MOVBstore [i4] {s} p (SRDconst w [32])
+	x3:(MOVBstore [i3] {s} p (SRDconst w [24])
+	x4:(MOVBstore [i2] {s} p (SRDconst w [16])
+	x5:(MOVBstore [i1] {s} p (SRDconst w [8])
+	x6:(MOVBstore [i0] {s} p w mem))))))))
+	&& !config.BigEndian
+	&& i0%4 == 0
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1
+	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
+	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6)
+	  -> (MOVDstore [i0] {s} p w mem)
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
index 2e8e239..c6269e0 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
@@ -128,8 +128,9 @@
 		// cr  = buildReg("CR")
 		// ctr = buildReg("CTR")
 		// lr  = buildReg("LR")
-		tmp  = buildReg("R31")
-		ctxt = buildReg("R11")
+		tmp     = buildReg("R31")
+		ctxt    = buildReg("R11")
+		callptr = buildReg("R12")
 		// tls = buildReg("R13")
 		gp01        = regInfo{inputs: nil, outputs: []regMask{gp}}
 		gp11        = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
@@ -154,13 +155,13 @@
 		callerSave  = regMask(gp | fp | gr)
 	)
 	ops := []opData{
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},                     // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11, asm: "ADD", aux: "SymOff", symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym)
-		{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true},                   // arg0+arg1
-		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true},                 // arg0+arg1
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                                        // arg0-arg1
-		{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"},                                      // arg0-arg1
-		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                                    // arg0-arg1
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},     // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11, asm: "ADD", aux: "Int64"},     // arg0 + auxInt
+		{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true},   // arg0+arg1
+		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true}, // arg0+arg1
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                        // arg0-arg1
+		{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"},                      // arg0-arg1
+		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                    // arg0-arg1
 
 		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true}, // arg0*arg1 (signed 64-bit)
 		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true}, // arg0*arg1 (signed 32-bit)
@@ -185,6 +186,9 @@
 		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},   // arg0 << arg1, 64 bits  (0 if arg1 & 64 != 0)
 		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},   // arg0 << arg1, 32 bits  (0 if arg1 & 32 != 0)
 
+		{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"},   // arg0 rotate left by arg1 mod 64
+		{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32
+
 		{name: "ADDconstForCarry", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, aux: "Int16", asm: "ADDC", typ: "Flags"}, // _, carry := arg0 + aux
 		{name: "MaskIfNotCarry", argLength: 1, reg: crgp, asm: "ADDME", typ: "Int64"},                                                                   // carry - 1 (if carry then 0 else -1)
 
@@ -219,6 +223,7 @@
 		{name: "FCTIDZ", argLength: 1, reg: fp11, asm: "FCTIDZ", typ: "Float64"}, // convert float to 64-bit int round towards zero
 		{name: "FCTIWZ", argLength: 1, reg: fp11, asm: "FCTIWZ", typ: "Float64"}, // convert float to 32-bit int round towards zero
 		{name: "FCFID", argLength: 1, reg: fp11, asm: "FCFID", typ: "Float64"},   // convert 64-bit integer to float
+		{name: "FCFIDS", argLength: 1, reg: fp11, asm: "FCFIDS", typ: "Float32"}, // convert 32-bit integer to float
 		{name: "FRSP", argLength: 1, reg: fp11, asm: "FRSP", typ: "Float64"},     // round float to 32-bit value
 
 		// Movement between float and integer registers with no change in bits; accomplished with stores+loads on PPC.
@@ -227,8 +232,8 @@
 		// There are optimizations that should apply -- (Xi2f64 (MOVWload (not-ADD-ptr+offset) ) ) could use
 		// the word-load instructions.  (Xi2f64 (MOVDload ptr )) can be (FMOVDload ptr)
 
-		{name: "Xf2i64", argLength: 1, reg: fpgp, typ: "Int64"},   // move 64 bits of F register into G register
-		{name: "Xi2f64", argLength: 1, reg: gpfp, typ: "Float64"}, // move 64 bits of G register into F register
+		{name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"},   // move 64 bits of F register into G register
+		{name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // move 64 bits of G register into F register
 
 		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},               // arg0&arg1
 		{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"},                                // arg0&^arg1
@@ -241,6 +246,12 @@
 		{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"},                                // -arg0 (floating point)
 		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},                              // sqrt(arg0) (floating point)
 		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                            // sqrt(arg0) (floating point, single precision)
+		{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"},                              // floor(arg0), float64
+		{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"},                               // ceil(arg0), float64
+		{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"},                              // trunc(arg0), float64
+		{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"},                                // abs(arg0), float64
+		{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"},                              // -abs(arg0), float64
+		{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"},                            // copysign arg0 -> arg1, float64
 
 		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                                                                                     // arg0|aux
 		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"},                                                                                   // arg0^aux
@@ -307,6 +318,9 @@
 		// use of the closure pointer.
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}},
 
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
 		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
 		// Round ops to block fused-multiply-add extraction.
@@ -317,8 +331,8 @@
 		{name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
 
 		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"},                   // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gp | sp, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true},                 // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true},            // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
 
 		// large or unaligned zeroing
 		// arg0 = address of memory to zero (in R3, changed as side effect)
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index 8a627e7..366fcc2 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -107,7 +107,13 @@
 (Bswap64 x) -> (MOVDBR x)
 (Bswap32 x) -> (MOVWBR x)
 
-(Sqrt x) -> (FSQRT x)
+// math package intrinsics
+(Sqrt        x) -> (FSQRT x)
+(Floor       x) -> (FIDBR [7] x)
+(Ceil        x) -> (FIDBR [6] x)
+(Trunc       x) -> (FIDBR [5] x)
+(RoundToEven x) -> (FIDBR [4] x)
+(Round       x) -> (FIDBR [1] x)
 
 // Atomic loads.
 (AtomicLoad32 ptr mem) -> (MOVWZatomicload ptr mem)
@@ -422,6 +428,7 @@
 (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
 (GetG mem) -> (LoweredGetG mem)
 (GetClosurePtr) -> (LoweredGetClosurePtr)
+(GetCallerSP) -> (LoweredGetCallerSP)
 (Addr {sym} base) -> (MOVDaddr {sym} base)
 (ITab (Load ptr mem)) -> (MOVDload ptr mem)
 
@@ -474,21 +481,20 @@
 (MOVDnop <t> x:(MOVWload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload  <t> [off] {sym} ptr mem)
 (MOVDnop <t> x:(MOVDload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload  <t> [off] {sym} ptr mem)
 
-// TODO(mundaym): uncomment rules once signed indexed loads are added.
 (MOVDreg <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDreg <t> x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDreg <t> x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDreg <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDreg <t> x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDreg <t> x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDreg <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDreg <t> x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDreg <t> x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDreg <t> x:(MOVDloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx  <t> [off] {sym} ptr idx mem)
 
 (MOVDnop <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDnop <t> x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDnop <t> x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDnop <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDnop <t> x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDnop <t> x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDnop <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
-//(MOVDnop <t> x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
+(MOVDnop <t> x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
 (MOVDnop <t> x:(MOVDloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx  <t> [off] {sym} ptr idx mem)
 
 // Fold sign extensions into conditional moves of constants.
@@ -514,31 +520,31 @@
 
 // Fold constants into instructions.
 (ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x)
-(ADDW x (MOVDconst [c])) -> (ADDWconst [c] x)
+(ADDW x (MOVDconst [c])) -> (ADDWconst [int64(int32(c))] x)
 
 (SUB x (MOVDconst [c])) && is32Bit(c) -> (SUBconst x [c])
 (SUB (MOVDconst [c]) x) && is32Bit(c) -> (NEG (SUBconst <v.Type> x [c]))
-(SUBW x (MOVDconst [c])) -> (SUBWconst x [c])
-(SUBW (MOVDconst [c]) x) -> (NEGW (SUBWconst <v.Type> x [c]))
+(SUBW x (MOVDconst [c])) -> (SUBWconst x [int64(int32(c))])
+(SUBW (MOVDconst [c]) x) -> (NEGW (SUBWconst <v.Type> x [int64(int32(c))]))
 
 (MULLD x (MOVDconst [c])) && is32Bit(c) -> (MULLDconst [c] x)
-(MULLW x (MOVDconst [c])) -> (MULLWconst [c] x)
+(MULLW x (MOVDconst [c])) -> (MULLWconst [int64(int32(c))] x)
 
 // NILF instructions leave the high 32 bits unchanged which is
 // equivalent to the leftmost 32 bits being set.
 // TODO(mundaym): modify the assembler to accept 64-bit values
 // and use isU32Bit(^c).
 (AND x (MOVDconst [c])) && is32Bit(c) && c < 0 -> (ANDconst [c] x)
-(ANDW x (MOVDconst [c])) -> (ANDWconst [c] x)
+(ANDW x (MOVDconst [c])) -> (ANDWconst [int64(int32(c))] x)
 
 (ANDWconst [c] (ANDWconst [d] x)) -> (ANDWconst [c & d] x)
 (ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c & d] x)
 
 (OR x (MOVDconst [c])) && isU32Bit(c) -> (ORconst [c] x)
-(ORW x (MOVDconst [c])) -> (ORWconst [c] x)
+(ORW x (MOVDconst [c])) -> (ORWconst [int64(int32(c))] x)
 
 (XOR x (MOVDconst [c])) && isU32Bit(c) -> (XORconst [c] x)
-(XORW x (MOVDconst [c])) -> (XORWconst [c] x)
+(XORW x (MOVDconst [c])) -> (XORWconst [int64(int32(c))] x)
 
 (SLD x (MOVDconst [c])) -> (SLDconst [c&63] x)
 (SLW x (MOVDconst [c])) -> (SLWconst [c&63] x)
@@ -565,12 +571,12 @@
 
 (CMP x (MOVDconst [c])) && is32Bit(c) -> (CMPconst x [c])
 (CMP (MOVDconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPconst x [c]))
-(CMPW x (MOVDconst [c])) -> (CMPWconst x [c])
-(CMPW (MOVDconst [c]) x) -> (InvertFlags (CMPWconst x [c]))
-(CMPU x (MOVDconst [c])) && isU32Bit(c) -> (CMPUconst x [int64(uint32(c))])
-(CMPU (MOVDconst [c]) x) && isU32Bit(c) -> (InvertFlags (CMPUconst x [int64(uint32(c))]))
-(CMPWU x (MOVDconst [c])) -> (CMPWUconst x [int64(uint32(c))])
-(CMPWU (MOVDconst [c]) x) -> (InvertFlags (CMPWUconst x [int64(uint32(c))]))
+(CMPW x (MOVDconst [c])) -> (CMPWconst x [int64(int32(c))])
+(CMPW (MOVDconst [c]) x) -> (InvertFlags (CMPWconst x [int64(int32(c))]))
+(CMPU x (MOVDconst [c])) && isU32Bit(c) -> (CMPUconst x [int64(int32(c))])
+(CMPU (MOVDconst [c]) x) && isU32Bit(c) -> (InvertFlags (CMPUconst x [int64(int32(c))]))
+(CMPWU x (MOVDconst [c])) -> (CMPWUconst x [int64(int32(c))])
+(CMPWU (MOVDconst [c]) x) -> (InvertFlags (CMPWUconst x [int64(int32(c))]))
 
 // Using MOV{W,H,B}Zreg instead of AND is cheaper.
 (AND x (MOVDconst [0xFF])) -> (MOVBZreg x)
@@ -670,22 +676,82 @@
 // Make sure we don't combine these ops if the load has another use.
 // This prevents a single load from being split into multiple loads
 // which then might return different values.  See test/atomicload.go.
-(MOVBreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBreg  x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload  <v.Type> [off] {sym} ptr mem)
+(MOVBreg  x:(MOVBload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload  <v.Type> [off] {sym} ptr mem)
 (MOVBZreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
-(MOVHreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
+(MOVBZreg x:(MOVBload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
+(MOVHreg  x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload  <v.Type> [off] {sym} ptr mem)
+(MOVHreg  x:(MOVHload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload  <v.Type> [off] {sym} ptr mem)
 (MOVHZreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
-(MOVWreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVHZreg x:(MOVHload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
+(MOVWreg  x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload  <v.Type> [off] {sym} ptr mem)
+(MOVWreg  x:(MOVWload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload  <v.Type> [off] {sym} ptr mem)
 (MOVWZreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
+(MOVWZreg x:(MOVWload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
 
+(MOVBreg  x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <v.Type> [off] {sym} ptr idx mem)
+(MOVBreg  x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx  <v.Type> [off] {sym} ptr idx mem)
 (MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
+(MOVBZreg x:(MOVBloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
+(MOVHreg  x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <v.Type> [off] {sym} ptr idx mem)
+(MOVHreg  x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx  <v.Type> [off] {sym} ptr idx mem)
 (MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
+(MOVHZreg x:(MOVHloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
+(MOVWreg  x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <v.Type> [off] {sym} ptr idx mem)
+(MOVWreg  x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx  <v.Type> [off] {sym} ptr idx mem)
 (MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
+(MOVWZreg x:(MOVWloadidx  [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
 
 // replace load from same location as preceding store with copy
-(MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBZreg x)
-(MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHZreg x)
-(MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWZreg x)
-(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
+(MOVDload  [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVDreg x)
+(MOVWload  [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVWreg x)
+(MOVHload  [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVHreg x)
+(MOVBload  [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVBreg x)
+(MOVWZload [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVWZreg x)
+(MOVHZload [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVHZreg x)
+(MOVBZload [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVBZreg x)
+(MOVDload  [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (LGDR x)
+(FMOVDload [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (LDGR x)
+(FMOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> x
+(FMOVSload [off] {sym} ptr1 (FMOVSstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> x
+
+// prefer FPR <-> GPR moves over combined load ops
+(MULLDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (MULLD x (LGDR <t> y))
+(ADDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (ADD   x (LGDR <t> y))
+(SUBload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (SUB   x (LGDR <t> y))
+(ORload    <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (OR    x (LGDR <t> y))
+(ANDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (AND   x (LGDR <t> y))
+(XORload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) -> (XOR   x (LGDR <t> y))
+
+// detect attempts to set/clear the sign bit
+// may need to be reworked when NIHH/OIHH are added
+(SRDconst [1] (SLDconst [1] (LGDR <t> x))) -> (LGDR <t> (LPDFR <x.Type> x))
+(LDGR <t> (SRDconst [1] (SLDconst [1] x))) -> (LPDFR (LDGR <t> x))
+(OR (MOVDconst [-1<<63]) (LGDR <t> x))     -> (LGDR <t> (LNDFR <x.Type> x))
+(LDGR <t> (OR (MOVDconst [-1<<63]) x))     -> (LNDFR (LDGR <t> x))
+
+// detect attempts to set the sign bit with load
+(LDGR <t> x:(ORload <t1> [off] {sym} (MOVDconst [-1<<63]) ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (LNDFR <t> (LDGR <t> (MOVDload <t1> [off] {sym} ptr mem)))
+
+// detect copysign
+(OR (SLDconst [63] (SRDconst [63] (LGDR x))) (LGDR (LPDFR <t> y))) -> (LGDR (CPSDR <t> y x))
+(OR (SLDconst [63] (SRDconst [63] (LGDR x))) (MOVDconst [c])) && c & -1<<63 == 0 -> (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [c]) x))
+(CPSDR y (FMOVDconst [c])) && c & -1<<63 == 0 -> (LPDFR y)
+(CPSDR y (FMOVDconst [c])) && c & -1<<63 != 0 -> (LNDFR y)
+
+// absorb negations into set/clear sign bit
+(FNEG  (LPDFR x)) -> (LNDFR x)
+(FNEG  (LNDFR x)) -> (LPDFR x)
+(FNEGS (LPDFR x)) -> (LNDFR x)
+(FNEGS (LNDFR x)) -> (LPDFR x)
+
+// no need to convert float32 to float64 to set/clear sign bit
+(LEDBR (LPDFR (LDEBR x))) -> (LPDFR x)
+(LEDBR (LNDFR (LDEBR x))) -> (LNDFR x)
+
+// remove unnecessary FPR <-> GPR moves
+(LDGR (LGDR x)) -> x
+(LGDR (LDGR x)) -> (MOVDreg x)
 
 // Don't extend before storing
 (MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem)
@@ -717,6 +783,20 @@
 (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (FMOVSstore [off1+off2] {sym} ptr val mem)
 (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (FMOVDstore [off1+off2] {sym} ptr val mem)
 
+(ADDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ADDload   [off1+off2] {sym} x ptr mem)
+(ADDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ADDWload  [off1+off2] {sym} x ptr mem)
+(MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (MULLDload [off1+off2] {sym} x ptr mem)
+(MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (MULLWload [off1+off2] {sym} x ptr mem)
+(SUBload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (SUBload   [off1+off2] {sym} x ptr mem)
+(SUBWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (SUBWload  [off1+off2] {sym} x ptr mem)
+
+(ANDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ANDload   [off1+off2] {sym} x ptr mem)
+(ANDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ANDWload  [off1+off2] {sym} x ptr mem)
+(ORload    [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ORload    [off1+off2] {sym} x ptr mem)
+(ORWload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ORWload   [off1+off2] {sym} x ptr mem)
+(XORload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (XORload   [off1+off2] {sym} x ptr mem)
+(XORWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (XORWload  [off1+off2] {sym} x ptr mem)
+
 // Fold constants into stores.
 (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB ->
 	(MOVDstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
@@ -774,6 +854,20 @@
 (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 
+(ADDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ADDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ADDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ADDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(SUBload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (SUBload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(SUBWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (SUBWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+
+(ANDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ANDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ANDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ANDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ORload    [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ORload    [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ORWload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (ORWload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(XORload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (XORload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(XORWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2) -> (XORWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+
 // Cannot store constant to SB directly (no 'move relative long immediate' instructions).
 (MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) ->
 	(MOVDstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
@@ -787,10 +881,16 @@
 // generating indexed loads and stores
 (MOVBZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVBZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVBload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
+	(MOVBloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVHZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVHZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVHload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
+	(MOVHloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVWZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVWZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVWload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
+	(MOVWloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (MOVDload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
 	(MOVDloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
 (FMOVSload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
@@ -812,46 +912,56 @@
 	(FMOVDstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
 
 (MOVBZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVBZloadidx [off] {sym} ptr idx mem)
+(MOVBload  [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVBloadidx  [off] {sym} ptr idx mem)
 (MOVHZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVHZloadidx [off] {sym} ptr idx mem)
+(MOVHload  [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVHloadidx  [off] {sym} ptr idx mem)
 (MOVWZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVWZloadidx [off] {sym} ptr idx mem)
-(MOVDload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVDloadidx [off] {sym} ptr idx mem)
+(MOVWload  [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVWloadidx  [off] {sym} ptr idx mem)
+(MOVDload  [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (MOVDloadidx  [off] {sym} ptr idx mem)
 (FMOVSload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (FMOVSloadidx [off] {sym} ptr idx mem)
 (FMOVDload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB -> (FMOVDloadidx [off] {sym} ptr idx mem)
-(MOVBstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVBstoreidx [off] {sym} ptr idx val mem)
-(MOVHstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVHstoreidx [off] {sym} ptr idx val mem)
-(MOVWstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVWstoreidx [off] {sym} ptr idx val mem)
-(MOVDstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVDstoreidx [off] {sym} ptr idx val mem)
+
+(MOVBstore  [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVBstoreidx  [off] {sym} ptr idx val mem)
+(MOVHstore  [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVHstoreidx  [off] {sym} ptr idx val mem)
+(MOVWstore  [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVWstoreidx  [off] {sym} ptr idx val mem)
+(MOVDstore  [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (MOVDstoreidx  [off] {sym} ptr idx val mem)
 (FMOVSstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (FMOVSstoreidx [off] {sym} ptr idx val mem)
 (FMOVDstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB -> (FMOVDstoreidx [off] {sym} ptr idx val mem)
 
 // combine ADD into indexed loads and stores
-(MOVBZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
-(MOVHZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
-(MOVWZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
-(MOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (MOVDloadidx [c+d] {sym} ptr idx mem)
-(FMOVSloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
-(FMOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
+(MOVBZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
+(MOVBloadidx  [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVBloadidx  [c+d] {sym} ptr idx mem)
+(MOVHZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
+(MOVHloadidx  [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVHloadidx  [c+d] {sym} ptr idx mem)
+(MOVWZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
+(MOVWloadidx  [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVWloadidx  [c+d] {sym} ptr idx mem)
+(MOVDloadidx  [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVDloadidx  [c+d] {sym} ptr idx mem)
+(FMOVSloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
+(FMOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
 
-(MOVBstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (MOVBstoreidx [c+d] {sym} ptr idx val mem)
-(MOVHstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (MOVHstoreidx [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (MOVWstoreidx [c+d] {sym} ptr idx val mem)
-(MOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (MOVDstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVSstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
+(MOVBstoreidx  [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVHstoreidx  [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx  [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVDstoreidx  [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
+(FMOVSstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
+(FMOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
 
-(MOVBZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
-(MOVHZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
-(MOVWZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
-(MOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (MOVDloadidx [c+d] {sym} ptr idx mem)
-(FMOVSloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
-(FMOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
+(MOVBZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
+(MOVBloadidx  [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVBloadidx  [c+d] {sym} ptr idx mem)
+(MOVHZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
+(MOVHloadidx  [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVHloadidx  [c+d] {sym} ptr idx mem)
+(MOVWZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
+(MOVWloadidx  [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVWloadidx  [c+d] {sym} ptr idx mem)
+(MOVDloadidx  [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVDloadidx  [c+d] {sym} ptr idx mem)
+(FMOVSloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
+(FMOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
 
-(MOVBstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (MOVBstoreidx [c+d] {sym} ptr idx val mem)
-(MOVHstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (MOVHstoreidx [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (MOVWstoreidx [c+d] {sym} ptr idx val mem)
-(MOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (MOVDstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVSstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
+(MOVBstoreidx  [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVHstoreidx  [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVWstoreidx  [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
+(MOVDstoreidx  [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
+(FMOVSstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
+(FMOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
 
 // MOVDaddr into MOVDaddridx
 (MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB ->
@@ -978,7 +1088,7 @@
 (SUBconst (MOVDconst [d]) [c]) -> (MOVDconst [d-c])
 (SUBconst (SUBconst x [d]) [c]) && is32Bit(-c-d) -> (ADDconst [-c-d] x)
 (SRADconst [c] (MOVDconst [d])) -> (MOVDconst [d>>uint64(c)])
-(SRAWconst [c] (MOVDconst [d])) -> (MOVDconst [d>>uint64(c)])
+(SRAWconst [c] (MOVDconst [d])) -> (MOVDconst [int64(int32(d))>>uint64(c)])
 (NEG (MOVDconst [c])) -> (MOVDconst [-c])
 (NEGW (MOVDconst [c])) -> (MOVDconst [int64(int32(-c))])
 (MULLDconst [c] (MOVDconst [d])) -> (MOVDconst [c*d])
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
index 2a08a27..d12dfe7 100644
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go
@@ -205,6 +205,20 @@
 		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD", resultInArg0: true},                                               // fp64 arg1 * arg2 + arg0
 		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS", resultInArg0: true},                                             // fp32 arg1 * arg2 - arg0
 		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB", resultInArg0: true},                                               // fp64 arg1 * arg2 - arg0
+		{name: "LPDFR", argLength: 1, reg: fp11, asm: "LPDFR"},                                                                   // fp64/fp32 set sign bit
+		{name: "LNDFR", argLength: 1, reg: fp11, asm: "LNDFR"},                                                                   // fp64/fp32 clear sign bit
+		{name: "CPSDR", argLength: 2, reg: fp21, asm: "CPSDR"},                                                                   // fp64/fp32 copy arg1 sign bit to arg0
+
+		// Round to integer, float64 only.
+		//
+		// aux | rounding mode
+		// ----+-----------------------------------
+		//   1 | round to nearest, ties away from 0
+		//   4 | round to nearest, ties to even
+		//   5 | round toward 0
+		//   6 | round toward +∞
+		//   7 | round toward -∞
+		{name: "FIDBR", argLength: 1, reg: fp11, asm: "FIDBR", aux: "Int8"},
 
 		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
 		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
@@ -221,21 +235,21 @@
 		// binary ops
 		{name: "ADD", argLength: 2, reg: gp21sp, asm: "ADD", commutative: true, clobberFlags: true},                                                                  // arg0 + arg1
 		{name: "ADDW", argLength: 2, reg: gp21sp, asm: "ADDW", commutative: true, clobberFlags: true},                                                                // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int64", typ: "UInt64", clobberFlags: true},                                                   // arg0 + auxint
+		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32", typ: "UInt64", clobberFlags: true},                                                   // arg0 + auxint
 		{name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDW", aux: "Int32", clobberFlags: true},                                                                // arg0 + auxint
 		{name: "ADDload", argLength: 3, reg: gpopload, asm: "ADD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 + *arg1. arg2=mem
 		{name: "ADDWload", argLength: 3, reg: gpopload, asm: "ADDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 + *arg1. arg2=mem
 
 		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB", clobberFlags: true},                                                                                       // arg0 - arg1
 		{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW", clobberFlags: true},                                                                                     // arg0 - arg1
-		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 - auxint
+		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                // arg0 - auxint
 		{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 - auxint
 		{name: "SUBload", argLength: 3, reg: gpopload, asm: "SUB", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 - *arg1. arg2=mem
 		{name: "SUBWload", argLength: 3, reg: gpopload, asm: "SUBW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 - *arg1. arg2=mem
 
 		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
 		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
-		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int64", typ: "Int64", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
+		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
 		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int32", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
 		{name: "MULLDload", argLength: 3, reg: gpopload, asm: "MULLD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
 		{name: "MULLWload", argLength: 3, reg: gpopload, asm: "MULLW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
@@ -281,9 +295,9 @@
 		{name: "CMPU", argLength: 2, reg: gp2flags, asm: "CMPU", typ: "Flags"},   // arg0 compare to arg1
 		{name: "CMPWU", argLength: 2, reg: gp2flags, asm: "CMPWU", typ: "Flags"}, // arg0 compare to arg1
 
-		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", typ: "Flags", aux: "Int64"},     // arg0 compare to auxint
+		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", typ: "Flags", aux: "Int32"},     // arg0 compare to auxint
 		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
-		{name: "CMPUconst", argLength: 1, reg: gp1flags, asm: "CMPU", typ: "Flags", aux: "Int64"},   // arg0 compare to auxint
+		{name: "CMPUconst", argLength: 1, reg: gp1flags, asm: "CMPU", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
 		{name: "CMPWUconst", argLength: 1, reg: gp1flags, asm: "CMPWU", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
 
 		{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "CEBR", typ: "Flags"}, // arg0 compare to arg1, f32
@@ -295,15 +309,15 @@
 		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
 
 		{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"},                   // unsigned arg0 >> arg1, shift amount is mod 64
-		{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"},                   // unsigned arg0 >> arg1, shift amount is mod 32
+		{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"},                   // unsigned uint32(arg0) >> arg1, shift amount is mod 32
 		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-63
-		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-31
+		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
 
 		// Arithmetic shifts clobber flags.
 		{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true},                   // signed arg0 >> arg1, shift amount is mod 64
-		{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true},                   // signed arg0 >> arg1, shift amount is mod 32
+		{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true},                   // signed int32(arg0) >> arg1, shift amount is mod 32
 		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
-		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31
+		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
 
 		{name: "RLLGconst", argLength: 1, reg: gp11, asm: "RLLG", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-63
 		{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"},   // arg0 rotate left auxint, rotate amount 0-31
@@ -346,6 +360,8 @@
 
 		{name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
 
+		{name: "LDGR", argLength: 1, reg: gpfp, asm: "LDGR"},     // move int64 to float64 (no conversion)
+		{name: "LGDR", argLength: 1, reg: fpgp, asm: "LGDR"},     // move float64 to int64 (no conversion)
 		{name: "CFDBRA", argLength: 1, reg: fpgp, asm: "CFDBRA"}, // convert float64 to int32
 		{name: "CGDBRA", argLength: 1, reg: fpgp, asm: "CGDBRA"}, // convert float64 to int64
 		{name: "CFEBRA", argLength: 1, reg: fpgp, asm: "CFEBRA"}, // convert float32 to int32
@@ -357,8 +373,8 @@
 		{name: "LEDBR", argLength: 1, reg: fp11, asm: "LEDBR"},   // convert float64 to float32
 		{name: "LDEBR", argLength: 1, reg: fp11, asm: "LDEBR"},   // convert float32 to float64
 
-		{name: "MOVDaddr", argLength: 1, reg: addr, aux: "SymOff", rematerializeable: true, clobberFlags: true, symEffect: "Read"}, // arg0 + auxint + offset encoded in aux
-		{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", clobberFlags: true, symEffect: "Read"},                    // arg0 + arg1 + auxint + aux
+		{name: "MOVDaddr", argLength: 1, reg: addr, aux: "SymOff", rematerializeable: true, symEffect: "Read"}, // arg0 + auxint + offset encoded in aux
+		{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Read"},                    // arg0 + arg1 + auxint + aux
 
 		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
 		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
@@ -387,10 +403,12 @@
 		{name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size,off
 
 		// indexed loads/stores
-		// TODO(mundaym): add sign-extended indexed loads
-		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", clobberFlags: true, symEffect: "Read"},   // load a byte from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", clobberFlags: true, symEffect: "Read"},  // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", clobberFlags: true, symEffect: "Read"},  // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", clobberFlags: true, symEffect: "Read"},   // load a byte from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", clobberFlags: true, symEffect: "Read"},      // load a byte from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
+		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", clobberFlags: true, symEffect: "Read"},  // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", clobberFlags: true, symEffect: "Read"},     // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
+		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", clobberFlags: true, symEffect: "Read"},  // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", clobberFlags: true, symEffect: "Read"},     // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
 		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", clobberFlags: true, symEffect: "Read"},    // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
 		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", clobberFlags: true, symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
 		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", clobberFlags: true, symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
@@ -428,6 +446,8 @@
 		// use of R12 (the closure pointer)
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}},
 		// arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
 		// Round ops to block fused-multiply-add extraction.
 		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true},
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 944a84d..9b004be 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -38,14 +38,22 @@
 // For now, the generated successors must be a permutation of the matched successors.
 
 // constant folding
-(Trunc16to8  (Const16 [c]))  -> (Const8   [int64(int8(c))])
-(Trunc32to8  (Const32 [c]))  -> (Const8   [int64(int8(c))])
-(Trunc32to16 (Const32 [c]))  -> (Const16  [int64(int16(c))])
-(Trunc64to8  (Const64 [c]))  -> (Const8   [int64(int8(c))])
-(Trunc64to16 (Const64 [c]))  -> (Const16  [int64(int16(c))])
-(Trunc64to32 (Const64 [c]))  -> (Const32  [int64(int32(c))])
+(Trunc16to8  (Const16  [c])) -> (Const8   [int64(int8(c))])
+(Trunc32to8  (Const32  [c])) -> (Const8   [int64(int8(c))])
+(Trunc32to16 (Const32  [c])) -> (Const16  [int64(int16(c))])
+(Trunc64to8  (Const64  [c])) -> (Const8   [int64(int8(c))])
+(Trunc64to16 (Const64  [c])) -> (Const16  [int64(int16(c))])
+(Trunc64to32 (Const64  [c])) -> (Const32  [int64(int32(c))])
 (Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))])
 (Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float
+(Cvt32to32F  (Const32  [c])) -> (Const32F [f2i(float64(float32(int32(c))))])
+(Cvt32to64F  (Const32  [c])) -> (Const64F [f2i(float64(int32(c)))])
+(Cvt64to32F  (Const64  [c])) -> (Const32F [f2i(float64(float32(c)))])
+(Cvt64to64F  (Const64  [c])) -> (Const64F [f2i(float64(c))])
+(Cvt32Fto32  (Const32F [c])) -> (Const32  [int64(int32(i2f(c)))])
+(Cvt32Fto64  (Const32F [c])) -> (Const64  [int64(i2f(c))])
+(Cvt64Fto32  (Const64F [c])) -> (Const32  [int64(int32(i2f(c)))])
+(Cvt64Fto64  (Const64F [c])) -> (Const64  [int64(i2f(c))])
 (Round32F x:(Const32F)) -> x
 (Round64F x:(Const64F)) -> x
 
@@ -208,6 +216,17 @@
 // (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
 (IsInBounds (Mod32u _ y) y) -> (ConstBool [1])
 (IsInBounds (Mod64u _ y) y) -> (ConstBool [1])
+// Right shifting a unsigned number limits its value.
+(IsInBounds (ZeroExt8to64  (Rsh8Ux64  _ (Const64 [c]))) (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
+(IsInBounds (ZeroExt8to32  (Rsh8Ux64  _ (Const64 [c]))) (Const32 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
+(IsInBounds (ZeroExt8to16  (Rsh8Ux64  _ (Const64 [c]))) (Const16 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
+(IsInBounds                (Rsh8Ux64  _ (Const64 [c]))  (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
+(IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
+(IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
+(IsInBounds                (Rsh16Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
+(IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d -> (ConstBool [1])
+(IsInBounds                (Rsh32Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d -> (ConstBool [1])
+(IsInBounds                (Rsh64Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 64 && 1<<uint(64-c)-1 < d -> (ConstBool [1])
 
 (IsSliceInBounds x x) -> (ConstBool [1])
 (IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d -> (ConstBool [1])
@@ -311,6 +330,18 @@
 (Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) ->
   (Add32 (Const32 <t> [int64(int32(c*d))]) (Mul32 <t> (Const32 <t> [c]) x))
 
+// Rewrite x*y + x*z  to  x*(y+z)
+(Add64 <t> (Mul64 x y) (Mul64 x z)) -> (Mul64 x (Add64 <t> y z))
+(Add32 <t> (Mul32 x y) (Mul32 x z)) -> (Mul32 x (Add32 <t> y z))
+(Add16 <t> (Mul16 x y) (Mul16 x z)) -> (Mul16 x (Add16 <t> y z))
+(Add8  <t> (Mul8  x y) (Mul8  x z)) -> (Mul8  x (Add8  <t> y z))
+
+// Rewrite x*y - x*z  to  x*(y-z)
+(Sub64 <t> (Mul64 x y) (Mul64 x z)) -> (Mul64 x (Sub64 <t> y z))
+(Sub32 <t> (Mul32 x y) (Mul32 x z)) -> (Mul32 x (Sub32 <t> y z))
+(Sub16 <t> (Mul16 x y) (Mul16 x z)) -> (Mul16 x (Sub16 <t> y z))
+(Sub8  <t> (Mul8  x y) (Mul8  x z)) -> (Mul8  x (Sub8  <t> y z))
+
 // rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
 // the number of the other rewrite rules for const shifts
 (Lsh64x32  <t> x (Const32 [c])) -> (Lsh64x64  x (Const64 <t> [int64(uint32(c))]))
@@ -538,6 +569,25 @@
 (Leq16U (Const16 [c]) (Const16 [d])) -> (ConstBool [b2i(uint16(c) <= uint16(d))])
 (Leq8U  (Const8  [c]) (Const8  [d])) -> (ConstBool [b2i(uint8(c)  <= uint8(d))])
 
+// constant floating point comparisons
+(Eq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) == i2f(d))])
+(Eq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) == i2f(d))])
+
+(Neq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) != i2f(d))])
+(Neq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) != i2f(d))])
+
+(Greater64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) > i2f(d))])
+(Greater32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) > i2f(d))])
+
+(Geq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) >= i2f(d))])
+(Geq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) >= i2f(d))])
+
+(Less64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) < i2f(d))])
+(Less32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) < i2f(d))])
+
+(Leq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) <= i2f(d))])
+(Leq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) <= i2f(d))])
+
 // simplifications
 (Or64 x x) -> x
 (Or32 x x) -> x
@@ -691,6 +741,12 @@
 // Load of store of same address, with compatibly typed value and same size
 (Load <t1> p1 (Store {t2} p2 x _)) && isSamePtr(p1,p2) && t1.Compare(x.Type) == types.CMPeq && t1.Size() == t2.(*types.Type).Size() -> x
 
+// Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits
+(Load <t1> p1 (Store {t2} p2 (Const64  [x]) _)) && isSamePtr(p1,p2) && t2.(*types.Type).Size() == 8 && is64BitFloat(t1) -> (Const64F [x])
+(Load <t1> p1 (Store {t2} p2 (Const32  [x]) _)) && isSamePtr(p1,p2) && t2.(*types.Type).Size() == 4 && is32BitFloat(t1) -> (Const32F [f2i(float64(math.Float32frombits(uint32(x))))])
+(Load <t1> p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && t2.(*types.Type).Size() == 8 && is64BitInt(t1)   -> (Const64  [x])
+(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && t2.(*types.Type).Size() == 4 && is32BitInt(t1)   -> (Const32  [int64(int32(math.Float32bits(float32(i2f(x)))))])
+
 // Eliminate stores of values that have just been loaded from the same location.
 // We also handle the common case where there are some intermediate stores to non-overlapping struct fields.
 (Store {t1} p1 (Load <t2> p2 mem) mem) &&
@@ -819,8 +875,6 @@
 (Store _ (ArrayMake0) mem) -> mem
 (Store dst (ArrayMake1 e) mem) -> (Store {e.Type} dst e mem)
 
-(ArraySelect [0] (Load ptr mem)) -> (Load ptr mem)
-
 // Putting [1]{*byte} and similar into direct interfaces.
 (IMake typ (ArrayMake1 val)) -> (IMake typ val)
 (ArraySelect [0] x:(IData _)) -> x
@@ -947,6 +1001,13 @@
 (Div64u n (Const64 [c])) && isPowerOfTwo(c)            -> (Rsh64Ux64 n (Const64 <typ.UInt64> [log2(c)]))
 (Div64u n (Const64 [-1<<63]))                          -> (Rsh64Ux64 n (Const64 <typ.UInt64> [63]))
 
+// Signed non-negative divide by power of 2.
+(Div8  n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo(c&0xff)       -> (Rsh8Ux64 n  (Const64 <typ.UInt64> [log2(c&0xff)]))
+(Div16 n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo(c&0xffff)     -> (Rsh16Ux64 n (Const64 <typ.UInt64> [log2(c&0xffff)]))
+(Div32 n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo(c&0xffffffff) -> (Rsh32Ux64 n (Const64 <typ.UInt64> [log2(c&0xffffffff)]))
+(Div64 n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo(c)            -> (Rsh64Ux64 n (Const64 <typ.UInt64> [log2(c)]))
+(Div64 n (Const64 [-1<<63])) && isNonNegative(n)                          -> (Const64 [0])
+
 // Unsigned divide, not a power of 2.  Strength reduce to a multiply.
 // For 8-bit divides, we just do a direct 9-bit by 8-bit multiply.
 (Div8u x (Const8 [c])) && umagicOK(8, c) ->
@@ -1180,6 +1241,13 @@
 (Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c)            -> (And64 n (Const64 <t> [c-1]))
 (Mod64u <t> n (Const64 [-1<<63]))                          -> (And64 n (Const64 <t> [1<<63-1]))
 
+// Signed non-negative mod by power of 2 constant.
+(Mod8  <t> n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo(c&0xff)       -> (And8 n (Const8 <t> [(c&0xff)-1]))
+(Mod16 <t> n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo(c&0xffff)     -> (And16 n (Const16 <t> [(c&0xffff)-1]))
+(Mod32 <t> n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo(c&0xffffffff) -> (And32 n (Const32 <t> [(c&0xffffffff)-1]))
+(Mod64 <t> n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo(c)            -> (And64 n (Const64 <t> [c-1]))
+(Mod64 n (Const64 [-1<<63])) && isNonNegative(n)                              -> n
+
 // Signed mod by negative constant.
 (Mod8  <t> n (Const8  [c])) && c < 0 && c != -1<<7  -> (Mod8  <t> n (Const8  <t> [-c]))
 (Mod16 <t> n (Const16 [c])) && c < 0 && c != -1<<15 -> (Mod16 <t> n (Const16 <t> [-c]))
@@ -1360,15 +1428,13 @@
 	-> mem
 // nil checks just need to rewrite to something useless.
 // they will be deadcode eliminated soon afterwards.
-(NilCheck (Load (OffPtr [c] (SP)) mem) mem)
-	&& mem.Op == OpStaticCall
-	&& isSameSym(mem.Aux, "runtime.newobject")
+(NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _)
+	&& isSameSym(sym, "runtime.newobject")
 	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
 	-> (Invalid)
-(NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem)) mem)
-	&& mem.Op == OpStaticCall
-	&& isSameSym(mem.Aux, "runtime.newobject")
+(NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _)
+	&& isSameSym(sym, "runtime.newobject")
 	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
 	-> (Invalid)
@@ -1377,6 +1443,14 @@
 (EqPtr x x) -> (ConstBool [1])
 (EqPtr (Addr {a} x) (Addr {b} x)) -> (ConstBool [b2i(a == b)])
 
+// Inline small runtime.memmove calls with constant length.
+(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem))))
+     && isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz,config)
+     -> (Move {t.(*types.Type).Elem()} [sz] dst src mem)
+(StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem))))
+     && isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz,config)
+     -> (Move {t.(*types.Type).Elem()} [sz] dst src mem)
+
 // De-virtualize interface calls into static calls.
 // Note that (ITab (IMake)) doesn't get
 // rewritten until after the first opt pass,
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
index d962e4a..5ce11c7 100644
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/gen/genericOps.go
@@ -255,7 +255,28 @@
 	{name: "PopCount32", argLength: 1}, // Count bits in arg[0]
 	{name: "PopCount64", argLength: 1}, // Count bits in arg[0]
 
-	{name: "Sqrt", argLength: 1}, // sqrt(arg0), float64 only
+	// Square root, float64 only.
+	// Special cases:
+	//   +∞  → +∞
+	//   ±0  → ±0 (sign preserved)
+	//   x<0 → NaN
+	//   NaN → NaN
+	{name: "Sqrt", argLength: 1}, // √arg0
+
+	// Round to integer, float64 only.
+	// Special cases:
+	//   ±∞  → ±∞ (sign preserved)
+	//   ±0  → ±0 (sign preserved)
+	//   NaN → NaN
+	{name: "Floor", argLength: 1},       // round arg0 toward -∞
+	{name: "Ceil", argLength: 1},        // round arg0 toward +∞
+	{name: "Trunc", argLength: 1},       // round arg0 toward 0
+	{name: "Round", argLength: 1},       // round arg0 to nearest, ties away from 0
+	{name: "RoundToEven", argLength: 1}, // round arg0 to nearest, ties to even
+
+	// Modify the sign bit
+	{name: "Abs", argLength: 1},      // absolute value arg0
+	{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
 
 	// Data movement, max argument length for Phi is indefinite so just pick
 	// a really large number
@@ -286,12 +307,13 @@
 
 	// Constant-like things
 	{name: "InitMem"},                               // memory input to the function.
-	{name: "Arg", aux: "SymOff", symEffect: "None"}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
+	{name: "Arg", aux: "SymOff", symEffect: "Read"}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
 
-	// The address of a variable.  arg0 is the base pointer (SB or SP, depending
-	// on whether it is a global or stack variable).  The Aux field identifies the
-	// variable. It will be either an *ExternSymbol (with arg0=SB), *ArgSymbol (arg0=SP),
-	// or *AutoSymbol (arg0=SP).
+	// The address of a variable.  arg0 is the base pointer.
+	// If the variable is a global, the base pointer will be SB and
+	// the Aux field will be a *obj.LSym.
+	// If the variable is a local, the base pointer will be SP and
+	// the Aux field will be a *gc.Node.
 	{name: "Addr", argLength: 1, aux: "Sym", symEffect: "Addr"}, // Address of a variable.  Arg0=SP or SB.  Aux identifies the variable.
 
 	{name: "SP"},                 // stack pointer
@@ -299,8 +321,11 @@
 	{name: "Invalid"},            // unused value
 
 	// Memory operations
-	{name: "Load", argLength: 2},                             // Load from arg0.  arg1=memory
-	{name: "Store", argLength: 3, typ: "Mem", aux: "Typ"},    // Store arg1 to arg0.  arg2=memory, aux=type.  Returns memory.
+	{name: "Load", argLength: 2},                          // Load from arg0.  arg1=memory
+	{name: "Store", argLength: 3, typ: "Mem", aux: "Typ"}, // Store arg1 to arg0.  arg2=memory, aux=type.  Returns memory.
+	// The source and destination of Move may overlap in some cases. See e.g.
+	// memmove inlining in generic.rules. When inlineablememmovesize (in ../rewrite.go)
+	// returns true, we must do all loads before all stores, when lowering Move.
 	{name: "Move", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
 	{name: "Zero", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
 
@@ -310,6 +335,12 @@
 	{name: "MoveWB", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
 	{name: "ZeroWB", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
 
+	// WB invokes runtime.gcWriteBarrier. This is not a normal
+	// call: it takes arguments in registers, doesn't clobber
+	// general-purpose registers (the exact clobber set is
+	// arch-dependent), and is not a safe-point.
+	{name: "WB", argLength: 3, typ: "Mem", aux: "Sym", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+
 	// Function calls. Arguments to the call have already been written to the stack.
 	// Return values appear on the stack. The method receiver, if any, is treated
 	// as a phantom first argument.
@@ -361,6 +392,8 @@
 	// Pseudo-ops
 	{name: "GetG", argLength: 1}, // runtime.getg() (read g pointer). arg0=mem
 	{name: "GetClosurePtr"},      // get closure pointer from dedicated register
+	{name: "GetCallerPC"},        // for getcallerpc intrinsic
+	{name: "GetCallerSP"},        // for getcallersp intrinsic
 
 	// Indexing operations
 	{name: "PtrIndex", argLength: 2},             // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
@@ -415,8 +448,9 @@
 
 	{name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None"}, // aux is a *gc.Node of a variable that is about to be initialized.  arg0=mem, returns mem
 	{name: "VarKill", argLength: 1, aux: "Sym", symEffect: "None"},            // aux is a *gc.Node of a variable that is known to be dead.  arg0=mem, returns mem
-	{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "None"},            // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
+	{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read"},            // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
 	{name: "KeepAlive", argLength: 2, typ: "Mem"},                             // arg[0] is a value that must be kept alive until this mark.  arg[1]=mem, returns mem
+	{name: "RegKill"},                                                         // regalloc has determined that the value in this register is dead
 
 	// Ops for breaking 64-bit operations on 32-bit architectures
 	{name: "Int64Make", argLength: 2, typ: "UInt64"}, // arg0=hi, arg1=lo
diff --git a/src/cmd/compile/internal/ssa/gen/main.go b/src/cmd/compile/internal/ssa/gen/main.go
index ea6fa87..0966d4c 100644
--- a/src/cmd/compile/internal/ssa/gen/main.go
+++ b/src/cmd/compile/internal/ssa/gen/main.go
@@ -169,6 +169,9 @@
 				if v.reg.clobbers != 0 {
 					log.Fatalf("%s is rematerializeable and clobbers registers", v.name)
 				}
+				if v.clobberFlags {
+					log.Fatalf("%s is rematerializeable and clobbers flags", v.name)
+				}
 				fmt.Fprintln(w, "rematerializeable: true,")
 			}
 			if v.commutative {
@@ -177,10 +180,10 @@
 			if v.resultInArg0 {
 				fmt.Fprintln(w, "resultInArg0: true,")
 				if v.reg.inputs[0] != v.reg.outputs[0] {
-					log.Fatalf("input[0] and output[0] must use the same registers for %s", v.name)
+					log.Fatalf("%s: input[0] and output[0] must use the same registers for %s", a.name, v.name)
 				}
 				if v.commutative && v.reg.inputs[1] != v.reg.outputs[0] {
-					log.Fatalf("input[1] and output[0] must use the same registers for %s", v.name)
+					log.Fatalf("%s: input[1] and output[0] must use the same registers for %s", a.name, v.name)
 				}
 			}
 			if v.resultNotInArgs {
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index 4306f7e..c23a54d 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -280,29 +280,32 @@
 
 			fmt.Fprintf(w, "for {\n")
 
-			s := split(match[1 : len(match)-1]) // remove parens, then split
+			_, _, _, aux, s := extract(match) // remove parens, then split
 
 			// check match of control value
-			if s[1] != "nil" {
+			if s[0] != "nil" {
 				fmt.Fprintf(w, "v := b.Control\n")
-				if strings.Contains(s[1], "(") {
-					genMatch0(w, arch, s[1], "v", map[string]struct{}{}, false, rule.loc)
+				if strings.Contains(s[0], "(") {
+					genMatch0(w, arch, s[0], "v", map[string]struct{}{}, false, rule.loc)
 				} else {
 					fmt.Fprintf(w, "_ = v\n") // in case we don't use v
-					fmt.Fprintf(w, "%s := b.Control\n", s[1])
+					fmt.Fprintf(w, "%s := b.Control\n", s[0])
 				}
 			}
+			if aux != "" {
+				fmt.Fprintf(w, "%s := b.Aux\n", aux)
+			}
 
 			if cond != "" {
 				fmt.Fprintf(w, "if !(%s) {\nbreak\n}\n", cond)
 			}
 
 			// Rule matches. Generate result.
-			t := split(result[1 : len(result)-1]) // remove parens, then split
-			newsuccs := t[2:]
+			outop, _, _, aux, t := extract(result) // remove parens, then split
+			newsuccs := t[1:]
 
 			// Check if newsuccs is the same set as succs.
-			succs := s[2:]
+			succs := s[1:]
 			m := map[string]bool{}
 			for _, succ := range succs {
 				if m[succ] {
@@ -320,11 +323,16 @@
 				log.Fatalf("unmatched successors %v in %s", m, rule)
 			}
 
-			fmt.Fprintf(w, "b.Kind = %s\n", blockName(t[0], arch))
-			if t[1] == "nil" {
+			fmt.Fprintf(w, "b.Kind = %s\n", blockName(outop, arch))
+			if t[0] == "nil" {
 				fmt.Fprintf(w, "b.SetControl(nil)\n")
 			} else {
-				fmt.Fprintf(w, "b.SetControl(%s)\n", genResult0(w, arch, t[1], new(int), false, false, rule.loc))
+				fmt.Fprintf(w, "b.SetControl(%s)\n", genResult0(w, arch, t[0], new(int), false, false, rule.loc))
+			}
+			if aux != "" {
+				fmt.Fprintf(w, "b.Aux = %s\n", aux)
+			} else {
+				fmt.Fprintln(w, "b.Aux = nil")
 			}
 
 			succChanged := false
@@ -622,11 +630,7 @@
 	return false
 }
 
-// parseValue parses a parenthesized value from a rule.
-// The value can be from the match or the result side.
-// It returns the op and unparsed strings for typ, auxint, and aux restrictions and for all args.
-// oparch is the architecture that op is located in, or "" for generic.
-func parseValue(val string, arch arch, loc string) (op opData, oparch string, typ string, auxint string, aux string, args []string) {
+func extract(val string) (op string, typ string, auxint string, aux string, args []string) {
 	val = val[1 : len(val)-1] // remove ()
 
 	// Split val up into regions.
@@ -634,6 +638,7 @@
 	s := split(val)
 
 	// Extract restrictions and args.
+	op = s[0]
 	for _, a := range s[1:] {
 		switch a[0] {
 		case '<':
@@ -646,8 +651,18 @@
 			args = append(args, a)
 		}
 	}
+	return
+}
+
+// parseValue parses a parenthesized value from a rule.
+// The value can be from the match or the result side.
+// It returns the op and unparsed strings for typ, auxint, and aux restrictions and for all args.
+// oparch is the architecture that op is located in, or "" for generic.
+func parseValue(val string, arch arch, loc string) (op opData, oparch string, typ string, auxint string, aux string, args []string) {
 
 	// Resolve the op.
+	var s string
+	s, typ, auxint, aux, args = extract(val)
 
 	// match reports whether x is a good op to select.
 	// If strict is true, rule generation might succeed.
@@ -656,14 +671,14 @@
 	// Doing strict=true then strict=false allows
 	// precise op matching while retaining good error messages.
 	match := func(x opData, strict bool, archname string) bool {
-		if x.name != s[0] {
+		if x.name != s {
 			return false
 		}
 		if x.argLength != -1 && int(x.argLength) != len(args) {
 			if strict {
 				return false
 			} else {
-				log.Printf("%s: op %s (%s) should have %d args, has %d", loc, s[0], archname, x.argLength, len(args))
+				log.Printf("%s: op %s (%s) should have %d args, has %d", loc, s, archname, x.argLength, len(args))
 			}
 		}
 		return true
diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go
index d554907..47f37f2 100644
--- a/src/cmd/compile/internal/ssa/html.go
+++ b/src/cmd/compile/internal/ssa/html.go
@@ -11,6 +11,7 @@
 	"html"
 	"io"
 	"os"
+	"strings"
 )
 
 type HTMLWriter struct {
@@ -65,6 +66,11 @@
     padding: 5px;
 }
 
+td.ssa-prog {
+    width: 600px;
+    word-wrap: break-word;
+}
+
 li {
     list-style-type: none;
 }
@@ -120,6 +126,11 @@
     font-style: italic;
 }
 
+.line-number {
+    font-style: italic;
+    font-size: 11px;
+}
+
 .highlight-yellow         { background-color: yellow; }
 .highlight-aquamarine     { background-color: aquamarine; }
 .highlight-coral          { background-color: coral; }
@@ -309,17 +320,21 @@
 	if w == nil {
 		return // avoid generating HTML just to discard it
 	}
-	w.WriteColumn(title, f.HTML())
+	w.WriteColumn(title, "", f.HTML())
 	// TODO: Add visual representation of f's CFG.
 }
 
 // WriteColumn writes raw HTML in a column headed by title.
 // It is intended for pre- and post-compilation log output.
-func (w *HTMLWriter) WriteColumn(title string, html string) {
+func (w *HTMLWriter) WriteColumn(title, class, html string) {
 	if w == nil {
 		return
 	}
-	w.WriteString("<td>")
+	if class == "" {
+		w.WriteString("<td>")
+	} else {
+		w.WriteString("<td class=\"" + class + "\">")
+	}
 	w.WriteString("<h2>" + title + "</h2>")
 	w.WriteString(html)
 	w.WriteString("</td>")
@@ -352,7 +367,14 @@
 	// We already have visual noise in the form of punctuation
 	// maybe we could replace some of that with formatting.
 	s := fmt.Sprintf("<span class=\"%s ssa-long-value\">", v.String())
-	s += fmt.Sprintf("%s = %s", v.HTML(), v.Op.String())
+
+	linenumber := "<span class=\"line-number\">(?)</span>"
+	if v.Pos.IsKnown() {
+		linenumber = fmt.Sprintf("<span class=\"line-number\">(%d)</span>", v.Pos.Line())
+	}
+
+	s += fmt.Sprintf("%s %s = %s", v.HTML(), linenumber, v.Op.String())
+
 	s += " &lt;" + html.EscapeString(v.Type.String()) + "&gt;"
 	s += html.EscapeString(v.auxString())
 	for _, a := range v.Args {
@@ -360,8 +382,21 @@
 	}
 	r := v.Block.Func.RegAlloc
 	if int(v.ID) < len(r) && r[v.ID] != nil {
-		s += " : " + html.EscapeString(r[v.ID].Name())
+		s += " : " + html.EscapeString(r[v.ID].String())
 	}
+	var names []string
+	for name, values := range v.Block.Func.NamedValues {
+		for _, value := range values {
+			if value == v {
+				names = append(names, name.String())
+				break // drop duplicates.
+			}
+		}
+	}
+	if len(names) != 0 {
+		s += " (" + strings.Join(names, ", ") + ")"
+	}
+
 	s += "</span>"
 	return s
 }
@@ -396,6 +431,11 @@
 	case BranchLikely:
 		s += " (likely)"
 	}
+	if b.Pos.IsKnown() {
+		// TODO does not begin to deal with the full complexity of line numbers.
+		// Maybe we want a string/slice instead, of outer-inner when inlining.
+		s += fmt.Sprintf(" (line %d)", b.Pos.Line())
+	}
 	return s
 }
 
@@ -469,7 +509,7 @@
 }
 
 func (p htmlFuncPrinter) named(n LocalSlot, vals []*Value) {
-	fmt.Fprintf(p.w, "<li>name %s: ", n.Name())
+	fmt.Fprintf(p.w, "<li>name %s: ", n)
 	for _, val := range vals {
 		fmt.Fprintf(p.w, "%s ", val.HTML())
 	}
diff --git a/src/cmd/compile/internal/ssa/likelyadjust.go b/src/cmd/compile/internal/ssa/likelyadjust.go
index 323de3d..5f4c5d1 100644
--- a/src/cmd/compile/internal/ssa/likelyadjust.go
+++ b/src/cmd/compile/internal/ssa/likelyadjust.go
@@ -12,7 +12,7 @@
 	header *Block // The header node of this (reducible) loop
 	outer  *loop  // loop containing this loop
 
-	// By default, children exits, and depth are not initialized.
+	// By default, children, exits, and depth are not initialized.
 	children []*loop  // loops nested directly within this loop. Initialized by assembleChildren().
 	exits    []*Block // exits records blocks reached by exits from this loop. Initialized by findExits().
 
@@ -23,7 +23,7 @@
 	isInner bool  // True if never discovered to contain a loop
 
 	// register allocation uses this.
-	containsCall bool // if any block in this loop or any loop it contains has a call
+	containsCall bool // if any block in this loop or any loop within it contains has a call
 }
 
 // outerinner records that outer contains inner
@@ -72,11 +72,12 @@
 }
 
 type loopnest struct {
-	f     *Func
-	b2l   []*loop
-	po    []*Block
-	sdom  SparseTree
-	loops []*loop
+	f              *Func
+	b2l            []*loop
+	po             []*Block
+	sdom           SparseTree
+	loops          []*loop
+	hasIrreducible bool // TODO current treatment of irreducible loops is very flaky, if accurate loops are needed, must punt at function level.
 
 	// Record which of the lazily initialized fields have actually been initialized.
 	initializedChildren, initializedDepth, initializedExits bool
@@ -104,7 +105,7 @@
 	blEXIT    = 3
 )
 
-var bllikelies [4]string = [4]string{"default", "call", "ret", "exit"}
+var bllikelies = [4]string{"default", "call", "ret", "exit"}
 
 func describePredictionAgrees(b *Block, prediction BranchPrediction) string {
 	s := ""
@@ -285,6 +286,12 @@
 	sdom := f.sdom()
 	b2l := make([]*loop, f.NumBlocks())
 	loops := make([]*loop, 0)
+	visited := make([]bool, f.NumBlocks())
+	sawIrred := false
+
+	if f.pass.debug > 2 {
+		fmt.Printf("loop finding in %s\n", f.Name)
+	}
 
 	// Reducible-loop-nest-finding.
 	for _, b := range po {
@@ -318,10 +325,17 @@
 					b2l[bb.ID] = l
 					l.checkContainsCall(bb)
 				}
-			} else { // Perhaps a loop header is inherited.
+			} else if !visited[bb.ID] { // Found an irreducible loop
+				sawIrred = true
+				if f.pass != nil && f.pass.debug > 4 {
+					fmt.Printf("loop finding    succ %s of %s is IRRED, in %s\n", bb.String(), b.String(), f.Name)
+				}
+			} else if l != nil {
+				// TODO handle case where l is irreducible.
+				// Perhaps a loop header is inherited.
 				// is there any loop containing our successor whose
 				// header dominates b?
-				if l != nil && !sdom.isAncestorEq(l.header, b) {
+				if !sdom.isAncestorEq(l.header, b) {
 					l = l.nearestOuterLoop(sdom, b)
 				}
 				if f.pass != nil && f.pass.debug > 4 {
@@ -331,6 +345,11 @@
 						fmt.Printf("loop finding    succ %s of %s provides loop with header %s\n", bb.String(), b.String(), l.header.String())
 					}
 				}
+			} else { // No loop
+				if f.pass != nil && f.pass.debug > 4 {
+					fmt.Printf("loop finding    succ %s of %s has no loop\n", bb.String(), b.String())
+				}
+
 			}
 
 			if l == nil || innermost == l {
@@ -355,9 +374,10 @@
 			innermost.checkContainsCall(b)
 			innermost.nBlocks++
 		}
+		visited[b.ID] = true
 	}
 
-	ln := &loopnest{f: f, b2l: b2l, po: po, sdom: sdom, loops: loops}
+	ln := &loopnest{f: f, b2l: b2l, po: po, sdom: sdom, loops: loops, hasIrreducible: sawIrred}
 
 	// Curious about the loopiness? "-d=ssa/likelyadjust/stats"
 	if f.pass != nil && f.pass.stats > 0 && len(loops) > 0 {
diff --git a/src/cmd/compile/internal/ssa/location.go b/src/cmd/compile/internal/ssa/location.go
index 41b4894..a482a60 100644
--- a/src/cmd/compile/internal/ssa/location.go
+++ b/src/cmd/compile/internal/ssa/location.go
@@ -11,30 +11,56 @@
 
 // A place that an ssa variable can reside.
 type Location interface {
-	Name() string // name to use in assembly templates: %rax, 16(%rsp), ...
+	String() string // name to use in assembly templates: AX, 16(SP), ...
 }
 
-// A Register is a machine register, like %rax.
+// A Register is a machine register, like AX.
 // They are numbered densely from 0 (for each architecture).
 type Register struct {
-	num    int32
+	num    int32 // dense numbering
 	objNum int16 // register number from cmd/internal/obj/$ARCH
 	name   string
 }
 
-func (r *Register) Name() string {
+func (r *Register) String() string {
 	return r.name
 }
 
-// A LocalSlot is a location in the stack frame.
-// It is (possibly a subpiece of) a PPARAM, PPARAMOUT, or PAUTO ONAME node.
-type LocalSlot struct {
-	N    GCNode      // an ONAME *gc.Node representing a variable on the stack
-	Type *types.Type // type of slot
-	Off  int64       // offset of slot in N
+// ObjNum returns the register number from cmd/internal/obj/$ARCH that
+// corresponds to this register.
+func (r *Register) ObjNum() int16 {
+	return r.objNum
 }
 
-func (s LocalSlot) Name() string {
+// A LocalSlot is a location in the stack frame, which identifies and stores
+// part or all of a PPARAM, PPARAMOUT, or PAUTO ONAME node.
+// It can represent a whole variable, part of a larger stack slot, or part of a
+// variable that has been decomposed into multiple stack slots.
+// As an example, a string could have the following configurations:
+//
+//           stack layout              LocalSlots
+//
+// Optimizations are disabled. s is on the stack and represented in its entirety.
+// [ ------- s string ---- ] { N: s, Type: string, Off: 0 }
+//
+// s was not decomposed, but the SSA operates on its parts individually, so
+// there is a LocalSlot for each of its fields that points into the single stack slot.
+// [ ------- s string ---- ] { N: s, Type: *uint8, Off: 0 }, {N: s, Type: int, Off: 8}
+//
+// s was decomposed. Each of its fields is in its own stack slot and has its own LocalSLot.
+// [ ptr *uint8 ] [ len int] { N: ptr, Type: *uint8, Off: 0, SplitOf: parent, SplitOffset: 0},
+//                           { N: len, Type: int, Off: 0, SplitOf: parent, SplitOffset: 8}
+//                           parent = &{N: s, Type: string}
+type LocalSlot struct {
+	N    GCNode      // an ONAME *gc.Node representing a stack location.
+	Type *types.Type // type of slot
+	Off  int64       // offset of slot in N
+
+	SplitOf     *LocalSlot // slot is a decomposition of SplitOf
+	SplitOffset int64      // .. at this offset.
+}
+
+func (s LocalSlot) String() string {
 	if s.Off == 0 {
 		return fmt.Sprintf("%v[%v]", s.N, s.Type)
 	}
@@ -43,13 +69,13 @@
 
 type LocPair [2]Location
 
-func (t LocPair) Name() string {
+func (t LocPair) String() string {
 	n0, n1 := "nil", "nil"
 	if t[0] != nil {
-		n0 = t[0].Name()
+		n0 = t[0].String()
 	}
 	if t[1] != nil {
-		n1 = t[1].Name()
+		n1 = t[1].String()
 	}
 	return fmt.Sprintf("<%s,%s>", n0, n1)
 }
diff --git a/src/cmd/compile/internal/ssa/loopreschedchecks.go b/src/cmd/compile/internal/ssa/loopreschedchecks.go
index 4222bf8..c9c04ef 100644
--- a/src/cmd/compile/internal/ssa/loopreschedchecks.go
+++ b/src/cmd/compile/internal/ssa/loopreschedchecks.go
@@ -17,7 +17,7 @@
 	m *Value // phi for memory at dest of e
 }
 
-// a rewriteTarget is a a value-argindex pair indicating
+// a rewriteTarget is a value-argindex pair indicating
 // where a rewrite is applied.  Note that this is for values,
 // not for block controls, because block controls are not targets
 // for the rewrites performed in inserting rescheduling checks.
@@ -267,8 +267,6 @@
 		sdom = newSparseTree(f, f.Idom())
 		fmt.Printf("after %s = %s\n", f.Name, sdom.treestructure(f.Entry))
 	}
-
-	return
 }
 
 // newPhiFor inserts a new Phi function into b,
diff --git a/src/cmd/compile/internal/ssa/looprotate.go b/src/cmd/compile/internal/ssa/looprotate.go
index c5b7682..2e5e421 100644
--- a/src/cmd/compile/internal/ssa/looprotate.go
+++ b/src/cmd/compile/internal/ssa/looprotate.go
@@ -23,6 +23,9 @@
 //    JLT loop
 func loopRotate(f *Func) {
 	loopnest := f.loopnest()
+	if loopnest.hasIrreducible {
+		return
+	}
 	if len(loopnest.loops) == 0 {
 		return
 	}
@@ -62,7 +65,7 @@
 				break
 			}
 			nextb := f.Blocks[nextIdx]
-			if nextb == p { // original loop precedessor is next
+			if nextb == p { // original loop predecessor is next
 				break
 			}
 			if loopnest.b2l[nextb.ID] != loop { // about to leave loop
diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go
index d01edcc..b107f8a 100644
--- a/src/cmd/compile/internal/ssa/nilcheck.go
+++ b/src/cmd/compile/internal/ssa/nilcheck.go
@@ -126,7 +126,7 @@
 							f.Warnl(v.Pos, "removed nil check")
 						}
 						v.reset(OpUnknown)
-						// TODO: f.freeValue(v)
+						f.freeValue(v)
 						i--
 						continue
 					}
@@ -168,6 +168,8 @@
 		// input pointer is nil. Remove nil checks on those pointers, as the
 		// faulting instruction effectively does the nil check for free.
 		unnecessary.clear()
+		// Optimization: keep track of removed nilcheck with smallest index
+		firstToRemove := len(b.Values)
 		for i := len(b.Values) - 1; i >= 0; i-- {
 			v := b.Values[i]
 			if opcodeTable[v.Op].nilCheck && unnecessary.contains(v.Args[0].ID) {
@@ -175,6 +177,7 @@
 					f.Warnl(v.Pos, "removed nil check")
 				}
 				v.reset(OpUnknown)
+				firstToRemove = i
 				continue
 			}
 			if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
@@ -224,8 +227,9 @@
 			}
 		}
 		// Remove values we've clobbered with OpUnknown.
-		i := 0
-		for _, v := range b.Values {
+		i := firstToRemove
+		for j := i; j < len(b.Values); j++ {
+			v := b.Values[j]
 			if v.Op != OpUnknown {
 				b.Values[i] = v
 				i++
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index 37c24ee..92560cd 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -67,7 +67,7 @@
 	auxFloat32              // auxInt is a float32 (encoded with math.Float64bits)
 	auxFloat64              // auxInt is a float64 (encoded with math.Float64bits)
 	auxString               // aux is a string
-	auxSym                  // aux is a symbol
+	auxSym                  // aux is a symbol (a *gc.Node for locals or an *obj.LSym for globals)
 	auxSymOff               // aux is a symbol, auxInt is an offset
 	auxSymValAndOff         // aux is a symbol, auxInt is a ValAndOff
 	auxTyp                  // aux is a type
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index ae2dd5f..0beabb0 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -70,6 +70,8 @@
 	BlockARM64NZ
 	BlockARM64ZW
 	BlockARM64NZW
+	BlockARM64TBZ
+	BlockARM64TBNZ
 
 	BlockMIPSEQ
 	BlockMIPSNE
@@ -162,20 +164,22 @@
 	BlockARMUGT: "UGT",
 	BlockARMUGE: "UGE",
 
-	BlockARM64EQ:  "EQ",
-	BlockARM64NE:  "NE",
-	BlockARM64LT:  "LT",
-	BlockARM64LE:  "LE",
-	BlockARM64GT:  "GT",
-	BlockARM64GE:  "GE",
-	BlockARM64ULT: "ULT",
-	BlockARM64ULE: "ULE",
-	BlockARM64UGT: "UGT",
-	BlockARM64UGE: "UGE",
-	BlockARM64Z:   "Z",
-	BlockARM64NZ:  "NZ",
-	BlockARM64ZW:  "ZW",
-	BlockARM64NZW: "NZW",
+	BlockARM64EQ:   "EQ",
+	BlockARM64NE:   "NE",
+	BlockARM64LT:   "LT",
+	BlockARM64LE:   "LE",
+	BlockARM64GT:   "GT",
+	BlockARM64GE:   "GE",
+	BlockARM64ULT:  "ULT",
+	BlockARM64ULE:  "ULE",
+	BlockARM64UGT:  "UGT",
+	BlockARM64UGE:  "UGE",
+	BlockARM64Z:    "Z",
+	BlockARM64NZ:   "NZ",
+	BlockARM64ZW:   "ZW",
+	BlockARM64NZW:  "NZW",
+	BlockARM64TBZ:  "TBZ",
+	BlockARM64TBNZ: "TBNZ",
 
 	BlockMIPSEQ:  "EQ",
 	BlockMIPSNE:  "NE",
@@ -392,6 +396,8 @@
 	Op386InvertFlags
 	Op386LoweredGetG
 	Op386LoweredGetClosurePtr
+	Op386LoweredGetCallerPC
+	Op386LoweredGetCallerSP
 	Op386LoweredNilCheck
 	Op386MOVLconvert
 	Op386FlagEQ
@@ -427,8 +433,8 @@
 	OpAMD64MOVSSstoreidx4
 	OpAMD64MOVSDstoreidx1
 	OpAMD64MOVSDstoreidx8
-	OpAMD64ADDSDmem
 	OpAMD64ADDSSmem
+	OpAMD64ADDSDmem
 	OpAMD64SUBSSmem
 	OpAMD64SUBSDmem
 	OpAMD64MULSSmem
@@ -437,6 +443,8 @@
 	OpAMD64ADDL
 	OpAMD64ADDQconst
 	OpAMD64ADDLconst
+	OpAMD64ADDQconstmem
+	OpAMD64ADDLconstmem
 	OpAMD64SUBQ
 	OpAMD64SUBL
 	OpAMD64SUBQconst
@@ -549,6 +557,7 @@
 	OpAMD64POPCNTQ
 	OpAMD64POPCNTL
 	OpAMD64SQRTSD
+	OpAMD64ROUNDSD
 	OpAMD64SBBQcarrymask
 	OpAMD64SBBLcarrymask
 	OpAMD64SETEQ
@@ -561,6 +570,16 @@
 	OpAMD64SETBE
 	OpAMD64SETA
 	OpAMD64SETAE
+	OpAMD64SETEQmem
+	OpAMD64SETNEmem
+	OpAMD64SETLmem
+	OpAMD64SETLEmem
+	OpAMD64SETGmem
+	OpAMD64SETGEmem
+	OpAMD64SETBmem
+	OpAMD64SETBEmem
+	OpAMD64SETAmem
+	OpAMD64SETAEmem
 	OpAMD64SETEQF
 	OpAMD64SETNEF
 	OpAMD64SETORD
@@ -585,6 +604,10 @@
 	OpAMD64CVTSQ2SD
 	OpAMD64CVTSD2SS
 	OpAMD64CVTSS2SD
+	OpAMD64MOVQi2f
+	OpAMD64MOVQf2i
+	OpAMD64MOVLi2f
+	OpAMD64MOVLf2i
 	OpAMD64PXOR
 	OpAMD64LEAQ
 	OpAMD64LEAQ1
@@ -610,6 +633,7 @@
 	OpAMD64MOVWloadidx2
 	OpAMD64MOVLloadidx1
 	OpAMD64MOVLloadidx4
+	OpAMD64MOVLloadidx8
 	OpAMD64MOVQloadidx1
 	OpAMD64MOVQloadidx8
 	OpAMD64MOVBstoreidx1
@@ -617,6 +641,7 @@
 	OpAMD64MOVWstoreidx2
 	OpAMD64MOVLstoreidx1
 	OpAMD64MOVLstoreidx4
+	OpAMD64MOVLstoreidx8
 	OpAMD64MOVQstoreidx1
 	OpAMD64MOVQstoreidx8
 	OpAMD64MOVBstoreconst
@@ -641,7 +666,10 @@
 	OpAMD64InvertFlags
 	OpAMD64LoweredGetG
 	OpAMD64LoweredGetClosurePtr
+	OpAMD64LoweredGetCallerPC
+	OpAMD64LoweredGetCallerSP
 	OpAMD64LoweredNilCheck
+	OpAMD64LoweredWB
 	OpAMD64MOVQconvert
 	OpAMD64MOVLconvert
 	OpAMD64FlagEQ
@@ -684,14 +712,21 @@
 	OpARMRSCconst
 	OpARMMULLU
 	OpARMMULA
+	OpARMMULS
 	OpARMADDF
 	OpARMADDD
 	OpARMSUBF
 	OpARMSUBD
 	OpARMMULF
 	OpARMMULD
+	OpARMNMULF
+	OpARMNMULD
 	OpARMDIVF
 	OpARMDIVD
+	OpARMMULAF
+	OpARMMULAD
+	OpARMMULSF
+	OpARMMULSD
 	OpARMAND
 	OpARMANDconst
 	OpARMOR
@@ -700,6 +735,8 @@
 	OpARMXORconst
 	OpARMBIC
 	OpARMBICconst
+	OpARMBFX
+	OpARMBFXU
 	OpARMMVN
 	OpARMNEGF
 	OpARMNEGD
@@ -812,9 +849,27 @@
 	OpARMCMPshiftLL
 	OpARMCMPshiftRL
 	OpARMCMPshiftRA
+	OpARMCMNshiftLL
+	OpARMCMNshiftRL
+	OpARMCMNshiftRA
+	OpARMTSTshiftLL
+	OpARMTSTshiftRL
+	OpARMTSTshiftRA
+	OpARMTEQshiftLL
+	OpARMTEQshiftRL
+	OpARMTEQshiftRA
 	OpARMCMPshiftLLreg
 	OpARMCMPshiftRLreg
 	OpARMCMPshiftRAreg
+	OpARMCMNshiftLLreg
+	OpARMCMNshiftRLreg
+	OpARMCMNshiftRAreg
+	OpARMTSTshiftLLreg
+	OpARMTSTshiftRLreg
+	OpARMTSTshiftRAreg
+	OpARMTEQshiftLLreg
+	OpARMTEQshiftRLreg
+	OpARMTEQshiftRAreg
 	OpARMCMPF0
 	OpARMCMPD0
 	OpARMMOVWconst
@@ -837,10 +892,16 @@
 	OpARMMOVWloadshiftLL
 	OpARMMOVWloadshiftRL
 	OpARMMOVWloadshiftRA
+	OpARMMOVBUloadidx
+	OpARMMOVBloadidx
+	OpARMMOVHUloadidx
+	OpARMMOVHloadidx
 	OpARMMOVWstoreidx
 	OpARMMOVWstoreshiftLL
 	OpARMMOVWstoreshiftRL
 	OpARMMOVWstoreshiftRA
+	OpARMMOVBstoreidx
+	OpARMMOVHstoreidx
 	OpARMMOVBreg
 	OpARMMOVBUreg
 	OpARMMOVHreg
@@ -879,6 +940,7 @@
 	OpARMLoweredZero
 	OpARMLoweredMove
 	OpARMLoweredGetClosurePtr
+	OpARMLoweredGetCallerSP
 	OpARMMOVWconvert
 	OpARMFlagEQ
 	OpARMFlagLT_ULT
@@ -989,12 +1051,14 @@
 	OpARM64MOVHstore
 	OpARM64MOVWstore
 	OpARM64MOVDstore
+	OpARM64STP
 	OpARM64FMOVSstore
 	OpARM64FMOVDstore
 	OpARM64MOVBstorezero
 	OpARM64MOVHstorezero
 	OpARM64MOVWstorezero
 	OpARM64MOVDstorezero
+	OpARM64MOVQstorezero
 	OpARM64MOVBreg
 	OpARM64MOVBUreg
 	OpARM64MOVHreg
@@ -1042,6 +1106,7 @@
 	OpARM64DUFFCOPY
 	OpARM64LoweredMove
 	OpARM64LoweredGetClosurePtr
+	OpARM64LoweredGetCallerSP
 	OpARM64MOVDconvert
 	OpARM64FlagEQ
 	OpARM64FlagLT_ULT
@@ -1161,6 +1226,7 @@
 	OpMIPSFPFlagTrue
 	OpMIPSFPFlagFalse
 	OpMIPSLoweredGetClosurePtr
+	OpMIPSLoweredGetCallerSP
 	OpMIPSMOVWconvert
 
 	OpMIPS64ADDV
@@ -1253,10 +1319,25 @@
 	OpMIPS64DUFFZERO
 	OpMIPS64LoweredZero
 	OpMIPS64LoweredMove
+	OpMIPS64LoweredAtomicLoad32
+	OpMIPS64LoweredAtomicLoad64
+	OpMIPS64LoweredAtomicStore32
+	OpMIPS64LoweredAtomicStore64
+	OpMIPS64LoweredAtomicStorezero32
+	OpMIPS64LoweredAtomicStorezero64
+	OpMIPS64LoweredAtomicExchange32
+	OpMIPS64LoweredAtomicExchange64
+	OpMIPS64LoweredAtomicAdd32
+	OpMIPS64LoweredAtomicAdd64
+	OpMIPS64LoweredAtomicAddconst32
+	OpMIPS64LoweredAtomicAddconst64
+	OpMIPS64LoweredAtomicCas32
+	OpMIPS64LoweredAtomicCas64
 	OpMIPS64LoweredNilCheck
 	OpMIPS64FPFlagTrue
 	OpMIPS64FPFlagFalse
 	OpMIPS64LoweredGetClosurePtr
+	OpMIPS64LoweredGetCallerSP
 	OpMIPS64MOVVconvert
 
 	OpPPC64ADD
@@ -1284,6 +1365,8 @@
 	OpPPC64SRW
 	OpPPC64SLD
 	OpPPC64SLW
+	OpPPC64ROTL
+	OpPPC64ROTLW
 	OpPPC64ADDconstForCarry
 	OpPPC64MaskIfNotCarry
 	OpPPC64SRADconst
@@ -1308,9 +1391,10 @@
 	OpPPC64FCTIDZ
 	OpPPC64FCTIWZ
 	OpPPC64FCFID
+	OpPPC64FCFIDS
 	OpPPC64FRSP
-	OpPPC64Xf2i64
-	OpPPC64Xi2f64
+	OpPPC64MFVSRD
+	OpPPC64MTVSRD
 	OpPPC64AND
 	OpPPC64ANDN
 	OpPPC64OR
@@ -1322,6 +1406,12 @@
 	OpPPC64FNEG
 	OpPPC64FSQRT
 	OpPPC64FSQRTS
+	OpPPC64FFLOOR
+	OpPPC64FCEIL
+	OpPPC64FTRUNC
+	OpPPC64FABS
+	OpPPC64FNABS
+	OpPPC64FCPSGN
 	OpPPC64ORconst
 	OpPPC64XORconst
 	OpPPC64ANDconst
@@ -1374,6 +1464,7 @@
 	OpPPC64GreaterEqual
 	OpPPC64FGreaterEqual
 	OpPPC64LoweredGetClosurePtr
+	OpPPC64LoweredGetCallerSP
 	OpPPC64LoweredNilCheck
 	OpPPC64LoweredRound32F
 	OpPPC64LoweredRound64F
@@ -1415,6 +1506,10 @@
 	OpS390XFMADD
 	OpS390XFMSUBS
 	OpS390XFMSUB
+	OpS390XLPDFR
+	OpS390XLNDFR
+	OpS390XCPSDR
+	OpS390XFIDBR
 	OpS390XFMOVSload
 	OpS390XFMOVDload
 	OpS390XFMOVSconst
@@ -1519,6 +1614,8 @@
 	OpS390XMOVDreg
 	OpS390XMOVDnop
 	OpS390XMOVDconst
+	OpS390XLDGR
+	OpS390XLGDR
 	OpS390XCFDBRA
 	OpS390XCGDBRA
 	OpS390XCFEBRA
@@ -1552,8 +1649,11 @@
 	OpS390XMOVDBRstore
 	OpS390XMVC
 	OpS390XMOVBZloadidx
+	OpS390XMOVBloadidx
 	OpS390XMOVHZloadidx
+	OpS390XMOVHloadidx
 	OpS390XMOVWZloadidx
+	OpS390XMOVWloadidx
 	OpS390XMOVDloadidx
 	OpS390XMOVHBRloadidx
 	OpS390XMOVWBRloadidx
@@ -1576,6 +1676,7 @@
 	OpS390XInvertFlags
 	OpS390XLoweredGetG
 	OpS390XLoweredGetClosurePtr
+	OpS390XLoweredGetCallerSP
 	OpS390XLoweredNilCheck
 	OpS390XLoweredRound32F
 	OpS390XLoweredRound64F
@@ -1800,6 +1901,13 @@
 	OpPopCount32
 	OpPopCount64
 	OpSqrt
+	OpFloor
+	OpCeil
+	OpTrunc
+	OpRound
+	OpRoundToEven
+	OpAbs
+	OpCopysign
 	OpPhi
 	OpCopy
 	OpConvert
@@ -1826,6 +1934,7 @@
 	OpStoreWB
 	OpMoveWB
 	OpZeroWB
+	OpWB
 	OpClosureCall
 	OpStaticCall
 	OpInterCall
@@ -1865,6 +1974,8 @@
 	OpNilCheck
 	OpGetG
 	OpGetClosurePtr
+	OpGetCallerPC
+	OpGetCallerSP
 	OpPtrIndex
 	OpOffPtr
 	OpSliceMake
@@ -1897,6 +2008,7 @@
 	OpVarKill
 	OpVarLive
 	OpKeepAlive
+	OpRegKill
 	OpInt64Make
 	OpInt64Hi
 	OpInt64Lo
@@ -4246,6 +4358,26 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerPC",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+		},
+	},
+	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		clobberFlags:   true,
@@ -4258,9 +4390,10 @@
 		},
 	},
 	{
-		name:   "MOVLconvert",
-		argLen: 2,
-		asm:    x86.AMOVL,
+		name:         "MOVLconvert",
+		argLen:       2,
+		resultInArg0: true,
+		asm:          x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 239}, // AX CX DX BX BP SI DI
@@ -4683,13 +4816,13 @@
 		},
 	},
 	{
-		name:           "ADDSDmem",
+		name:           "ADDSSmem",
 		auxType:        auxSymOff,
 		argLen:         3,
 		resultInArg0:   true,
 		faultOnNilArg1: true,
 		symEffect:      SymRead,
-		asm:            x86.AADDSD,
+		asm:            x86.AADDSS,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
@@ -4701,13 +4834,13 @@
 		},
 	},
 	{
-		name:           "ADDSSmem",
+		name:           "ADDSDmem",
 		auxType:        auxSymOff,
 		argLen:         3,
 		resultInArg0:   true,
 		faultOnNilArg1: true,
 		symEffect:      SymRead,
-		asm:            x86.AADDSS,
+		asm:            x86.AADDSD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
@@ -4824,7 +4957,7 @@
 	},
 	{
 		name:         "ADDQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		clobberFlags: true,
 		asm:          x86.AADDQ,
@@ -4853,6 +4986,34 @@
 		},
 	},
 	{
+		name:           "ADDQconstmem",
+		auxType:        auxSymValAndOff,
+		argLen:         2,
+		clobberFlags:   true,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.AADDQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "ADDLconstmem",
+		auxType:        auxSymValAndOff,
+		argLen:         2,
+		clobberFlags:   true,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.AADDL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
 		name:         "SUBQ",
 		argLen:       2,
 		resultInArg0: true,
@@ -4886,7 +5047,7 @@
 	},
 	{
 		name:         "SUBQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -4952,7 +5113,7 @@
 	},
 	{
 		name:         "MULQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -5232,7 +5393,7 @@
 	},
 	{
 		name:         "ANDQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -5298,7 +5459,7 @@
 	},
 	{
 		name:         "ORQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -5364,7 +5525,7 @@
 	},
 	{
 		name:         "XORQconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -5440,7 +5601,7 @@
 	},
 	{
 		name:    "CMPQconst",
-		auxType: auxInt64,
+		auxType: auxInt32,
 		argLen:  1,
 		asm:     x86.ACMPQ,
 		reg: regInfo{
@@ -5598,7 +5759,7 @@
 	},
 	{
 		name:    "TESTQconst",
-		auxType: auxInt64,
+		auxType: auxInt32,
 		argLen:  1,
 		asm:     x86.ATESTQ,
 		reg: regInfo{
@@ -6560,6 +6721,20 @@
 		},
 	},
 	{
+		name:    "ROUNDSD",
+		auxType: auxInt8,
+		argLen:  1,
+		asm:     x86.AROUNDSD,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+		},
+	},
+	{
 		name:   "SBBQcarrymask",
 		argLen: 1,
 		asm:    x86.ASBBQ,
@@ -6680,6 +6855,136 @@
 		},
 	},
 	{
+		name:           "SETEQmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETNEmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETNE,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETLmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETLT,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETLEmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETLE,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETGmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETGT,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETGEmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETGE,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETBmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETCS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETBEmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETLS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETAmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETHI,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
+		name:           "SETAEmem",
+		auxType:        auxSymOff,
+		argLen:         3,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.ASETCC,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
 		name:         "SETEQF",
 		argLen:       1,
 		clobberFlags: true,
@@ -6976,6 +7281,54 @@
 		},
 	},
 	{
+		name:   "MOVQi2f",
+		argLen: 1,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+		},
+	},
+	{
+		name:   "MOVQf2i",
+		argLen: 1,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+			outputs: []outputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+		},
+	},
+	{
+		name:   "MOVLi2f",
+		argLen: 1,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+		},
+	},
+	{
+		name:   "MOVLf2i",
+		argLen: 1,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			},
+			outputs: []outputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+		},
+	},
+	{
 		name:         "PXOR",
 		argLen:       2,
 		commutative:  true,
@@ -7366,6 +7719,22 @@
 		},
 	},
 	{
+		name:      "MOVLloadidx8",
+		auxType:   auxSymOff,
+		argLen:    3,
+		symEffect: SymRead,
+		asm:       x86.AMOVL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+			outputs: []outputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+		},
+	},
+	{
 		name:        "MOVQloadidx1",
 		auxType:     auxSymOff,
 		argLen:      3,
@@ -7469,6 +7838,20 @@
 		},
 	},
 	{
+		name:      "MOVLstoreidx8",
+		auxType:   auxSymOff,
+		argLen:    4,
+		symEffect: SymWrite,
+		asm:       x86.AMOVL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{2, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+			},
+		},
+	},
+	{
 		name:      "MOVQstoreidx1",
 		auxType:   auxSymOff,
 		argLen:    4,
@@ -7643,7 +8026,6 @@
 		name:           "DUFFZERO",
 		auxType:        auxInt64,
 		argLen:         3,
-		clobberFlags:   true,
 		faultOnNilArg0: true,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -7768,6 +8150,26 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerPC",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+		},
+	},
+	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		clobberFlags:   true,
@@ -7780,9 +8182,24 @@
 		},
 	},
 	{
-		name:   "MOVQconvert",
-		argLen: 2,
-		asm:    x86.AMOVQ,
+		name:         "LoweredWB",
+		auxType:      auxSym,
+		argLen:       3,
+		clobberFlags: true,
+		symEffect:    SymNone,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 128}, // DI
+				{1, 1},   // AX
+			},
+			clobbers: 4294901760, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+		},
+	},
+	{
+		name:         "MOVQconvert",
+		argLen:       2,
+		resultInArg0: true,
+		asm:          x86.AMOVQ,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
@@ -7793,9 +8210,10 @@
 		},
 	},
 	{
-		name:   "MOVLconvert",
-		argLen: 2,
-		asm:    x86.AMOVL,
+		name:         "MOVLconvert",
+		argLen:       2,
+		resultInArg0: true,
+		asm:          x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
@@ -8352,6 +8770,21 @@
 		},
 	},
 	{
+		name:   "MULS",
+		argLen: 3,
+		asm:    arm.AMULS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:        "ADDF",
 		argLen:      2,
 		commutative: true,
@@ -8440,6 +8873,36 @@
 		},
 	},
 	{
+		name:        "NMULF",
+		argLen:      2,
+		commutative: true,
+		asm:         arm.ANMULF,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:        "NMULD",
+		argLen:      2,
+		commutative: true,
+		asm:         arm.ANMULD,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
 		name:   "DIVF",
 		argLen: 2,
 		asm:    arm.ADIVF,
@@ -8468,6 +8931,70 @@
 		},
 	},
 	{
+		name:         "MULAF",
+		argLen:       3,
+		resultInArg0: true,
+		asm:          arm.AMULAF,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:         "MULAD",
+		argLen:       3,
+		resultInArg0: true,
+		asm:          arm.AMULAD,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:         "MULSF",
+		argLen:       3,
+		resultInArg0: true,
+		asm:          arm.AMULSF,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:         "MULSD",
+		argLen:       3,
+		resultInArg0: true,
+		asm:          arm.AMULSD,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
 		name:        "AND",
 		argLen:      2,
 		commutative: true,
@@ -8583,6 +9110,34 @@
 		},
 	},
 	{
+		name:    "BFX",
+		auxType: auxInt32,
+		argLen:  1,
+		asm:     arm.ABFX,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:    "BFXU",
+		auxType: auxInt32,
+		argLen:  1,
+		asm:     arm.ABFXU,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:   "MVN",
 		argLen: 1,
 		asm:    arm.AMVN,
@@ -10080,9 +10635,10 @@
 		},
 	},
 	{
-		name:   "CMN",
-		argLen: 2,
-		asm:    arm.ACMN,
+		name:        "CMN",
+		argLen:      2,
+		commutative: true,
+		asm:         arm.ACMN,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
@@ -10206,6 +10762,114 @@
 		},
 	},
 	{
+		name:    "CMNshiftLL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "CMNshiftRL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "CMNshiftRA",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TSTshiftLL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TSTshiftRL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TSTshiftRA",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TEQshiftLL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TEQshiftRL",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
+		name:    "TEQshiftRA",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{1, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+			},
+		},
+	},
+	{
 		name:   "CMPshiftLLreg",
 		argLen: 3,
 		asm:    arm.ACMP,
@@ -10242,6 +10906,114 @@
 		},
 	},
 	{
+		name:   "CMNshiftLLreg",
+		argLen: 3,
+		asm:    arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "CMNshiftRLreg",
+		argLen: 3,
+		asm:    arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "CMNshiftRAreg",
+		argLen: 3,
+		asm:    arm.ACMN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TSTshiftLLreg",
+		argLen: 3,
+		asm:    arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TSTshiftRLreg",
+		argLen: 3,
+		asm:    arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TSTshiftRAreg",
+		argLen: 3,
+		asm:    arm.ATST,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TEQshiftLLreg",
+		argLen: 3,
+		asm:    arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TEQshiftRLreg",
+		argLen: 3,
+		asm:    arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "TEQshiftRAreg",
+		argLen: 3,
+		asm:    arm.ATEQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{1, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+				{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:   "CMPF0",
 		argLen: 1,
 		asm:    arm.ACMPF,
@@ -10555,6 +11327,62 @@
 		},
 	},
 	{
+		name:   "MOVBUloadidx",
+		argLen: 3,
+		asm:    arm.AMOVBU,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "MOVBloadidx",
+		argLen: 3,
+		asm:    arm.AMOVB,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "MOVHUloadidx",
+		argLen: 3,
+		asm:    arm.AMOVHU,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
+		name:   "MOVHloadidx",
+		argLen: 3,
+		asm:    arm.AMOVH,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:   "MOVWstoreidx",
 		argLen: 4,
 		asm:    arm.AMOVW,
@@ -10606,6 +11434,30 @@
 		},
 	},
 	{
+		name:   "MOVBstoreidx",
+		argLen: 4,
+		asm:    arm.AMOVB,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{2, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+		},
+	},
+	{
+		name:   "MOVHstoreidx",
+		argLen: 4,
+		asm:    arm.AMOVH,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{2, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+				{0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+			},
+		},
+	},
+	{
 		name:   "MOVBreg",
 		argLen: 1,
 		asm:    arm.AMOVBS,
@@ -11072,6 +11924,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:   "MOVWconvert",
 		argLen: 2,
 		asm:    arm.AMOVW,
@@ -12542,6 +13404,21 @@
 		},
 	},
 	{
+		name:           "STP",
+		auxType:        auxSymOff,
+		argLen:         4,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            arm64.ASTP,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 805044223},           // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+				{2, 805044223},           // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+				{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+			},
+		},
+	},
+	{
 		name:           "FMOVSstore",
 		auxType:        auxSymOff,
 		argLen:         3,
@@ -12622,6 +13499,19 @@
 		},
 	},
 	{
+		name:           "MOVQstorezero",
+		auxType:        auxSymOff,
+		argLen:         2,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            arm64.ASTP,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+			},
+		},
+	},
+	{
 		name:   "MOVBreg",
 		argLen: 1,
 		asm:    arm64.AMOVB,
@@ -13132,7 +14022,7 @@
 		faultOnNilArg0: true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+				{0, 65536}, // R16
 			},
 			clobbers: 536936448, // R16 R30
 		},
@@ -13189,6 +14079,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+			},
+		},
+	},
+	{
 		name:   "MOVDconvert",
 		argLen: 2,
 		asm:    arm64.AMOVD,
@@ -14767,6 +15667,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31
+			},
+		},
+	},
+	{
 		name:   "MOVWconvert",
 		argLen: 2,
 		asm:    mips.AMOVW,
@@ -16022,6 +16932,208 @@
 		},
 	},
 	{
+		name:           "LoweredAtomicLoad32",
+		argLen:         2,
+		faultOnNilArg0: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicLoad64",
+		argLen:         2,
+		faultOnNilArg0: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicStore32",
+		argLen:         3,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicStore64",
+		argLen:         3,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicStorezero32",
+		argLen:         2,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicStorezero64",
+		argLen:         2,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicExchange32",
+		argLen:          3,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicExchange64",
+		argLen:          3,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicAdd32",
+		argLen:          3,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicAdd64",
+		argLen:          3,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicAddconst32",
+		auxType:         auxInt32,
+		argLen:          2,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicAddconst64",
+		auxType:         auxInt64,
+		argLen:          2,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicCas32",
+		argLen:          4,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{2, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
+		name:            "LoweredAtomicCas64",
+		argLen:          4,
+		resultNotInArgs: true,
+		faultOnNilArg0:  true,
+		hasSideEffects:  true,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{2, 234881022},           // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+				{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
+			},
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		nilCheck:       true,
@@ -16060,6 +17172,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
+			},
+		},
+	},
+	{
 		name:   "MOVVconvert",
 		argLen: 2,
 		asm:    mips.AMOVV,
@@ -16089,11 +17211,10 @@
 		},
 	},
 	{
-		name:      "ADDconst",
-		auxType:   auxSymOff,
-		argLen:    1,
-		symEffect: SymAddr,
-		asm:       ppc64.AADD,
+		name:    "ADDconst",
+		auxType: auxInt64,
+		argLen:  1,
+		asm:     ppc64.AADD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@@ -16440,6 +17561,34 @@
 		},
 	},
 	{
+		name:   "ROTL",
+		argLen: 2,
+		asm:    ppc64.AROTL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+		},
+	},
+	{
+		name:   "ROTLW",
+		argLen: 2,
+		asm:    ppc64.AROTLW,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+		},
+	},
+	{
 		name:    "ADDconstForCarry",
 		auxType: auxInt16,
 		argLen:  1,
@@ -16764,6 +17913,19 @@
 		},
 	},
 	{
+		name:   "FCFIDS",
+		argLen: 1,
+		asm:    ppc64.AFCFIDS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
 		name:   "FRSP",
 		argLen: 1,
 		asm:    ppc64.AFRSP,
@@ -16777,8 +17939,9 @@
 		},
 	},
 	{
-		name:   "Xf2i64",
+		name:   "MFVSRD",
 		argLen: 1,
+		asm:    ppc64.AMFVSRD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
@@ -16789,8 +17952,9 @@
 		},
 	},
 	{
-		name:   "Xi2f64",
+		name:   "MTVSRD",
 		argLen: 1,
+		asm:    ppc64.AMTVSRD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@@ -16956,6 +18120,85 @@
 		},
 	},
 	{
+		name:   "FFLOOR",
+		argLen: 1,
+		asm:    ppc64.AFRIM,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
+		name:   "FCEIL",
+		argLen: 1,
+		asm:    ppc64.AFRIP,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
+		name:   "FTRUNC",
+		argLen: 1,
+		asm:    ppc64.AFRIZ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
+		name:   "FABS",
+		argLen: 1,
+		asm:    ppc64.AFABS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
+		name:   "FNABS",
+		argLen: 1,
+		asm:    ppc64.AFNABS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
+		name:   "FCPSGN",
+		argLen: 2,
+		asm:    ppc64.AFCPSGN,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+				{1, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+			outputs: []outputInfo{
+				{0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+			},
+		},
+	},
+	{
 		name:    "ORconst",
 		auxType: auxInt64,
 		argLen:  1,
@@ -17602,6 +18845,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		clobberFlags:   true,
@@ -17672,8 +18925,8 @@
 		call:         true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 2048},       // R11
-				{0, 1073733626}, // SP R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+				{0, 4096}, // R12
+				{1, 2048}, // R11
 			},
 			clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
 		},
@@ -17686,7 +18939,7 @@
 		call:         true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+				{0, 4096}, // R12
 			},
 			clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
 		},
@@ -18157,6 +19410,60 @@
 		},
 	},
 	{
+		name:   "LPDFR",
+		argLen: 1,
+		asm:    s390x.ALPDFR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:   "LNDFR",
+		argLen: 1,
+		asm:    s390x.ALNDFR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:   "CPSDR",
+		argLen: 2,
+		asm:    s390x.ACPSDR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+				{1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:    "FIDBR",
+		auxType: auxInt8,
+		argLen:  1,
+		asm:     s390x.AFIDBR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
 		name:           "FMOVSload",
 		auxType:        auxSymOff,
 		argLen:         2,
@@ -18334,7 +19641,7 @@
 	},
 	{
 		name:         "ADDconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		clobberFlags: true,
 		asm:          s390x.AADD,
@@ -18432,7 +19739,7 @@
 	},
 	{
 		name:         "SUBconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -18536,7 +19843,7 @@
 	},
 	{
 		name:         "MULLDconst",
-		auxType:      auxInt64,
+		auxType:      auxInt32,
 		argLen:       1,
 		resultInArg0: true,
 		clobberFlags: true,
@@ -19118,7 +20425,7 @@
 	},
 	{
 		name:    "CMPconst",
-		auxType: auxInt64,
+		auxType: auxInt32,
 		argLen:  1,
 		asm:     s390x.ACMP,
 		reg: regInfo{
@@ -19140,7 +20447,7 @@
 	},
 	{
 		name:    "CMPUconst",
-		auxType: auxInt64,
+		auxType: auxInt32,
 		argLen:  1,
 		asm:     s390x.ACMPU,
 		reg: regInfo{
@@ -19708,6 +21015,32 @@
 		},
 	},
 	{
+		name:   "LDGR",
+		argLen: 1,
+		asm:    s390x.ALDGR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+			outputs: []outputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+		},
+	},
+	{
+		name:   "LGDR",
+		argLen: 1,
+		asm:    s390x.ALGDR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:   "CFDBRA",
 		argLen: 1,
 		asm:    s390x.ACFDBRA,
@@ -19842,7 +21175,6 @@
 		auxType:           auxSymOff,
 		argLen:            1,
 		rematerializeable: true,
-		clobberFlags:      true,
 		symEffect:         SymRead,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -19854,11 +21186,10 @@
 		},
 	},
 	{
-		name:         "MOVDaddridx",
-		auxType:      auxSymOff,
-		argLen:       2,
-		clobberFlags: true,
-		symEffect:    SymRead,
+		name:      "MOVDaddridx",
+		auxType:   auxSymOff,
+		argLen:    2,
+		symEffect: SymRead,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 4295000064}, // SP SB
@@ -20205,6 +21536,24 @@
 		},
 	},
 	{
+		name:         "MOVBloadidx",
+		auxType:      auxSymOff,
+		argLen:       3,
+		commutative:  true,
+		clobberFlags: true,
+		symEffect:    SymRead,
+		asm:          s390x.AMOVB,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 54270},      // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
+				{0, 4295021566}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:         "MOVHZloadidx",
 		auxType:      auxSymOff,
 		argLen:       3,
@@ -20223,6 +21572,24 @@
 		},
 	},
 	{
+		name:         "MOVHloadidx",
+		auxType:      auxSymOff,
+		argLen:       3,
+		commutative:  true,
+		clobberFlags: true,
+		symEffect:    SymRead,
+		asm:          s390x.AMOVH,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 54270},      // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
+				{0, 4295021566}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:         "MOVWZloadidx",
 		auxType:      auxSymOff,
 		argLen:       3,
@@ -20241,6 +21608,24 @@
 		},
 	},
 	{
+		name:         "MOVWloadidx",
+		auxType:      auxSymOff,
+		argLen:       3,
+		commutative:  true,
+		clobberFlags: true,
+		symEffect:    SymRead,
+		asm:          s390x.AMOVW,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 54270},      // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
+				{0, 4295021566}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:         "MOVDloadidx",
 		auxType:      auxSymOff,
 		argLen:       3,
@@ -20552,6 +21937,16 @@
 		},
 	},
 	{
+		name:              "LoweredGetCallerSP",
+		argLen:            0,
+		rematerializeable: true,
+		reg: regInfo{
+			outputs: []outputInfo{
+				{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		clobberFlags:   true,
@@ -21977,6 +23372,41 @@
 		generic: true,
 	},
 	{
+		name:    "Floor",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "Ceil",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "Trunc",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "Round",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "RoundToEven",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "Abs",
+		argLen:  1,
+		generic: true,
+	},
+	{
+		name:    "Copysign",
+		argLen:  2,
+		generic: true,
+	},
+	{
 		name:    "Phi",
 		argLen:  -1,
 		generic: true,
@@ -22063,7 +23493,7 @@
 		name:      "Arg",
 		auxType:   auxSymOff,
 		argLen:    0,
-		symEffect: SymNone,
+		symEffect: SymRead,
 		generic:   true,
 	},
 	{
@@ -22125,6 +23555,13 @@
 		generic: true,
 	},
 	{
+		name:      "WB",
+		auxType:   auxSym,
+		argLen:    3,
+		symEffect: SymNone,
+		generic:   true,
+	},
+	{
 		name:    "ClosureCall",
 		auxType: auxInt64,
 		argLen:  3,
@@ -22327,6 +23764,16 @@
 		generic: true,
 	},
 	{
+		name:    "GetCallerPC",
+		argLen:  0,
+		generic: true,
+	},
+	{
+		name:    "GetCallerSP",
+		argLen:  0,
+		generic: true,
+	},
+	{
 		name:    "PtrIndex",
 		argLen:  2,
 		generic: true,
@@ -22489,7 +23936,7 @@
 		name:      "VarLive",
 		auxType:   auxSym,
 		argLen:    1,
-		symEffect: SymNone,
+		symEffect: SymRead,
 		generic:   true,
 	},
 	{
@@ -22498,6 +23945,11 @@
 		generic: true,
 	},
 	{
+		name:    "RegKill",
+		argLen:  0,
+		generic: true,
+	},
+	{
 		name:    "Int64Make",
 		argLen:  2,
 		generic: true,
diff --git a/src/cmd/compile/internal/ssa/opt.go b/src/cmd/compile/internal/ssa/opt.go
index 670b535..6e91fd7 100644
--- a/src/cmd/compile/internal/ssa/opt.go
+++ b/src/cmd/compile/internal/ssa/opt.go
@@ -8,10 +8,3 @@
 func opt(f *Func) {
 	applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric)
 }
-
-func dec(f *Func) {
-	applyRewrite(f, rewriteBlockdec, rewriteValuedec)
-	if f.Config.RegSize == 4 {
-		applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
-	}
-}
diff --git a/src/cmd/compile/internal/ssa/print.go b/src/cmd/compile/internal/ssa/print.go
index d2a87eb..d66530a 100644
--- a/src/cmd/compile/internal/ssa/print.go
+++ b/src/cmd/compile/internal/ssa/print.go
@@ -78,7 +78,7 @@
 func (p stringFuncPrinter) endDepCycle() {}
 
 func (p stringFuncPrinter) named(n LocalSlot, vals []*Value) {
-	fmt.Fprintf(p.w, "name %s: %v\n", n.Name(), vals)
+	fmt.Fprintf(p.w, "name %s: %v\n", n, vals)
 }
 
 func fprintFunc(p funcPrinter, f *Func) {
diff --git a/src/cmd/compile/internal/ssa/redblack32.go b/src/cmd/compile/internal/ssa/redblack32.go
index ae1ec35..fc9cc71 100644
--- a/src/cmd/compile/internal/ssa/redblack32.go
+++ b/src/cmd/compile/internal/ssa/redblack32.go
@@ -244,7 +244,7 @@
 }
 
 func (t *node32) glb(key int32, allow_eq bool) *node32 {
-	var best *node32 = nil
+	var best *node32
 	for t != nil {
 		if key <= t.key {
 			if key == t.key && allow_eq {
@@ -262,7 +262,7 @@
 }
 
 func (t *node32) lub(key int32, allow_eq bool) *node32 {
-	var best *node32 = nil
+	var best *node32
 	for t != nil {
 		if key >= t.key {
 			if key == t.key && allow_eq {
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index 137e5fc..bc0a972 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -242,6 +242,9 @@
 	// current state of each (preregalloc) Value
 	values []valState
 
+	// names associated with each Value
+	valueNames [][]LocalSlot
+
 	// ID of SP, SB values
 	sp, sb ID
 
@@ -300,6 +303,13 @@
 
 // freeReg frees up register r. Any current user of r is kicked out.
 func (s *regAllocState) freeReg(r register) {
+	s.freeOrResetReg(r, false)
+}
+
+// freeOrResetReg frees up register r. Any current user of r is kicked out.
+// resetting indicates that the operation is only for bookkeeping,
+// e.g. when clearing out state upon entry to a new block.
+func (s *regAllocState) freeOrResetReg(r register, resetting bool) {
 	v := s.regs[r].v
 	if v == nil {
 		s.f.Fatalf("tried to free an already free register %d\n", r)
@@ -307,7 +317,17 @@
 
 	// Mark r as unused.
 	if s.f.pass.debug > regDebug {
-		fmt.Printf("freeReg %s (dump %s/%s)\n", s.registers[r].Name(), v, s.regs[r].c)
+		fmt.Printf("freeReg %s (dump %s/%s)\n", &s.registers[r], v, s.regs[r].c)
+	}
+	if !resetting && s.f.Config.ctxt.Flag_locationlists && len(s.valueNames[v.ID]) != 0 {
+		kill := s.curBlock.NewValue0(src.NoXPos, OpRegKill, types.TypeVoid)
+		for int(kill.ID) >= len(s.orig) {
+			s.orig = append(s.orig, nil)
+		}
+		for _, name := range s.valueNames[v.ID] {
+			s.f.NamedValues[name] = append(s.f.NamedValues[name], kill)
+		}
+		s.f.setHome(kill, &s.registers[r])
 	}
 	s.regs[r] = regState{}
 	s.values[v.ID].regs &^= regMask(1) << r
@@ -337,7 +357,7 @@
 // r must be unused.
 func (s *regAllocState) assignReg(r register, v *Value, c *Value) {
 	if s.f.pass.debug > regDebug {
-		fmt.Printf("assignReg %s %s/%s\n", s.registers[r].Name(), v, c)
+		fmt.Printf("assignReg %s %s/%s\n", &s.registers[r], v, c)
 	}
 	if s.regs[r].v != nil {
 		s.f.Fatalf("tried to assign register %d to %s/%s but it is already used by %s", r, v, c, s.regs[r].v)
@@ -402,7 +422,7 @@
 		c := s.curBlock.NewValue1(v2.Pos, OpCopy, v2.Type, s.regs[r].c)
 		s.copies[c] = false
 		if s.f.pass.debug > regDebug {
-			fmt.Printf("copy %s to %s : %s\n", v2, c, s.registers[r2].Name())
+			fmt.Printf("copy %s to %s : %s\n", v2, c, &s.registers[r2])
 		}
 		s.setOrig(c, v2)
 		s.assignReg(r2, v2, c)
@@ -468,7 +488,7 @@
 		c = s.curBlock.NewValue1(pos, OpCopy, v.Type, s.regs[r2].c)
 	} else if v.rematerializeable() {
 		// Rematerialize instead of loading from the spill location.
-		c = v.copyIntoNoXPos(s.curBlock)
+		c = v.copyIntoWithXPos(s.curBlock, pos)
 	} else {
 		// Load v from its spill location.
 		spill := s.makeSpill(v, s.curBlock)
@@ -511,7 +531,7 @@
 	s.SBReg = noRegister
 	s.GReg = noRegister
 	for r := register(0); r < s.numRegs; r++ {
-		switch s.registers[r].Name() {
+		switch s.registers[r].String() {
 		case "SP":
 			s.SPReg = r
 		case "SB":
@@ -542,12 +562,6 @@
 	if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
 		s.allocatable &^= 1 << uint(s.f.Config.FPReg)
 	}
-	if s.f.Config.ctxt.Flag_shared {
-		switch s.f.Config.arch {
-		case "ppc64le": // R2 already reserved.
-			s.allocatable &^= 1 << 12 // R12
-		}
-	}
 	if s.f.Config.LinkReg != -1 {
 		if isLeaf(f) {
 			// Leaf functions don't save/restore the link register.
@@ -567,7 +581,7 @@
 		case "arm":
 			s.allocatable &^= 1 << 9 // R9
 		case "ppc64le": // R2 already reserved.
-			s.allocatable &^= 1 << 12 // R12
+			// nothing to do
 		case "arm64":
 			// nothing to do?
 		case "386":
@@ -599,6 +613,17 @@
 	s.values = make([]valState, f.NumValues())
 	s.orig = make([]*Value, f.NumValues())
 	s.copies = make(map[*Value]bool)
+	if s.f.Config.ctxt.Flag_locationlists {
+		s.valueNames = make([][]LocalSlot, f.NumValues())
+		for slot, values := range f.NamedValues {
+			if isSynthetic(&slot) {
+				continue
+			}
+			for _, value := range values {
+				s.valueNames[value.ID] = append(s.valueNames[value.ID], slot)
+			}
+		}
+	}
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			if !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() && !v.Type.IsTuple() {
@@ -692,7 +717,9 @@
 
 // Sets the state of the registers to that encoded in regs.
 func (s *regAllocState) setState(regs []endReg) {
-	s.freeRegs(s.used)
+	for s.used != 0 {
+		s.freeOrResetReg(pickReg(s.used), true)
+	}
 	for _, x := range regs {
 		s.assignReg(x.r, x.v, x.c)
 	}
@@ -735,6 +762,9 @@
 	}
 
 	for _, b := range f.Blocks {
+		if s.f.pass.debug > regDebug {
+			fmt.Printf("Begin processing block %v\n", b)
+		}
 		s.curBlock = b
 
 		// Initialize regValLiveSet and uses fields for this block.
@@ -830,9 +860,6 @@
 			// This is the complicated case. We have more than one predecessor,
 			// which means we may have Phi ops.
 
-			// Copy phi ops into new schedule.
-			b.Values = append(b.Values, phis...)
-
 			// Start with the final register state of the primary predecessor
 			idx := s.primary[b.ID]
 			if idx < 0 {
@@ -844,14 +871,14 @@
 			if s.f.pass.debug > regDebug {
 				fmt.Printf("starting merge block %s with end state of %s:\n", b, p)
 				for _, x := range s.endRegs[p.ID] {
-					fmt.Printf("  %s: orig:%s cache:%s\n", s.registers[x.r].Name(), x.v, x.c)
+					fmt.Printf("  %s: orig:%s cache:%s\n", &s.registers[x.r], x.v, x.c)
 				}
 			}
 
 			// Decide on registers for phi ops. Use the registers determined
 			// by the primary predecessor if we can.
 			// TODO: pick best of (already processed) predecessors?
-			// Majority vote?  Deepest nesting level?
+			// Majority vote? Deepest nesting level?
 			phiRegs = phiRegs[:0]
 			var phiUsed regMask
 			for _, v := range phis {
@@ -900,7 +927,7 @@
 						c := p.NewValue1(a.Pos, OpCopy, a.Type, s.regs[r].c)
 						s.copies[c] = false
 						if s.f.pass.debug > regDebug {
-							fmt.Printf("copy %s to %s : %s\n", a, c, s.registers[r2].Name())
+							fmt.Printf("copy %s to %s : %s\n", a, c, &s.registers[r2])
 						}
 						s.setOrig(c, a)
 						s.assignReg(r2, a, c)
@@ -910,6 +937,9 @@
 				}
 			}
 
+			// Copy phi ops into new schedule.
+			b.Values = append(b.Values, phis...)
+
 			// Third pass - pick registers for phis whose inputs
 			// were not in a register.
 			for i, v := range phis {
@@ -976,7 +1006,7 @@
 			if s.f.pass.debug > regDebug {
 				fmt.Printf("after phis\n")
 				for _, x := range s.startRegs[b.ID] {
-					fmt.Printf("  %s: v%d\n", s.registers[x.r].Name(), x.v.ID)
+					fmt.Printf("  %s: v%d\n", &s.registers[x.r], x.v.ID)
 				}
 			}
 		}
@@ -1005,7 +1035,7 @@
 			pidx := e.i
 			for _, v := range succ.Values {
 				if v.Op != OpPhi {
-					break
+					continue
 				}
 				if !s.values[v.ID].needReg {
 					continue
@@ -1103,12 +1133,15 @@
 			if v.Op == OpKeepAlive {
 				// Make sure the argument to v is still live here.
 				s.advanceUses(v)
-				vi := &s.values[v.Args[0].ID]
-				if vi.spill != nil {
+				a := v.Args[0]
+				vi := &s.values[a.ID]
+				if vi.regs == 0 && !vi.rematerializeable {
 					// Use the spill location.
-					v.SetArg(0, vi.spill)
+					// This forces later liveness analysis to make the
+					// value live at this point.
+					v.SetArg(0, s.makeSpill(a, b))
 				} else {
-					// No need to keep unspilled values live.
+					// In-register and rematerializeable values are already live.
 					// These are typically rematerializeable constants like nil,
 					// or values of a variable that were modified since the last call.
 					v.Op = OpCopy
@@ -1141,7 +1174,7 @@
 				fmt.Printf("  out:")
 				for _, r := range dinfo[idx].out {
 					if r != noRegister {
-						fmt.Printf(" %s", s.registers[r].Name())
+						fmt.Printf(" %s", &s.registers[r])
 					}
 				}
 				fmt.Println()
@@ -1149,7 +1182,7 @@
 					fmt.Printf("  in%d:", i)
 					for _, r := range dinfo[idx].in[i] {
 						if r != noRegister {
-							fmt.Printf(" %s", s.registers[r].Name())
+							fmt.Printf(" %s", &s.registers[r])
 						}
 					}
 					fmt.Println()
@@ -1533,7 +1566,7 @@
 				if s.f.pass.debug > regDebug {
 					fmt.Printf("delete copied value %s\n", c.LongString())
 				}
-				c.Args[0].Uses--
+				c.RemoveArg(0)
 				f.freeValue(c)
 				delete(s.copies, c)
 				progress = true
@@ -1565,6 +1598,9 @@
 	for _, b := range f.Blocks {
 		var m regMask
 		for _, v := range b.Values {
+			if v.Op == OpRegKill {
+				continue
+			}
 			if v.Op != OpPhi {
 				break
 			}
@@ -1675,21 +1711,17 @@
 	for _, b := range f.Blocks {
 		nphi := 0
 		for _, v := range b.Values {
-			if v.Op != OpPhi {
+			if v.Op != OpRegKill && v.Op != OpPhi {
 				break
 			}
 			nphi++
 		}
 		oldSched = append(oldSched[:0], b.Values[nphi:]...)
 		b.Values = b.Values[:nphi]
-		for _, v := range start[b.ID] {
-			b.Values = append(b.Values, v)
-		}
+		b.Values = append(b.Values, start[b.ID]...)
 		for _, v := range oldSched {
 			b.Values = append(b.Values, v)
-			for _, w := range after[v.ID] {
-				b.Values = append(b.Values, w)
-			}
+			b.Values = append(b.Values, after[v.ID]...)
 		}
 	}
 }
@@ -1800,6 +1832,9 @@
 	}
 	// Phis need their args to end up in a specific location.
 	for _, v := range e.b.Values {
+		if v.Op == OpRegKill {
+			continue
+		}
 		if v.Op != OpPhi {
 			break
 		}
@@ -1815,11 +1850,11 @@
 		for _, vid := range e.cachedVals {
 			a := e.cache[vid]
 			for _, c := range a {
-				fmt.Printf("src %s: v%d cache=%s\n", e.s.f.getHome(c.ID).Name(), vid, c)
+				fmt.Printf("src %s: v%d cache=%s\n", e.s.f.getHome(c.ID), vid, c)
 			}
 		}
 		for _, d := range e.destinations {
-			fmt.Printf("dst %s: v%d\n", d.loc.Name(), d.vid)
+			fmt.Printf("dst %s: v%d\n", d.loc, d.vid)
 		}
 	}
 }
@@ -1876,8 +1911,9 @@
 		c := e.contents[loc].c
 		r := e.findRegFor(c.Type)
 		if e.s.f.pass.debug > regDebug {
-			fmt.Printf("breaking cycle with v%d in %s:%s\n", vid, loc.Name(), c)
+			fmt.Printf("breaking cycle with v%d in %s:%s\n", vid, loc, c)
 		}
+		e.erase(r)
 		if _, isReg := loc.(*Register); isReg {
 			c = e.p.NewValue1(d.pos, OpCopy, c.Type, c)
 		} else {
@@ -1921,13 +1957,13 @@
 	var c *Value
 	var src Location
 	if e.s.f.pass.debug > regDebug {
-		fmt.Printf("moving v%d to %s\n", vid, loc.Name())
+		fmt.Printf("moving v%d to %s\n", vid, loc)
 		fmt.Printf("sources of v%d:", vid)
 	}
 	for _, w := range e.cache[vid] {
 		h := e.s.f.getHome(w.ID)
 		if e.s.f.pass.debug > regDebug {
-			fmt.Printf(" %s:%s", h.Name(), w)
+			fmt.Printf(" %s:%s", h, w)
 		}
 		_, isreg := h.(*Register)
 		if src == nil || isreg {
@@ -1937,12 +1973,24 @@
 	}
 	if e.s.f.pass.debug > regDebug {
 		if src != nil {
-			fmt.Printf(" [use %s]\n", src.Name())
+			fmt.Printf(" [use %s]\n", src)
 		} else {
 			fmt.Printf(" [no source]\n")
 		}
 	}
 	_, dstReg := loc.(*Register)
+
+	// Pre-clobber destination. This avoids the
+	// following situation:
+	//   - v is currently held in R0 and stacktmp0.
+	//   - We want to copy stacktmp1 to stacktmp0.
+	//   - We choose R0 as the temporary register.
+	// During the copy, both R0 and stacktmp0 are
+	// clobbered, losing both copies of v. Oops!
+	// Erasing the destination early means R0 will not
+	// be chosen as the temp register, as it will then
+	// be the last copy of v.
+	e.erase(loc)
 	var x *Value
 	if c == nil {
 		if !e.s.values[vid].rematerializeable {
@@ -1953,9 +2001,9 @@
 		} else {
 			// Rematerialize into stack slot. Need a free
 			// register to accomplish this.
-			e.erase(loc) // see pre-clobber comment below
 			r := e.findRegFor(v.Type)
-			x = v.copyIntoNoXPos(e.p)
+			e.erase(r)
+			x = v.copyIntoWithXPos(e.p, pos)
 			e.set(r, vid, x, false, pos)
 			// Make sure we spill with the size of the slot, not the
 			// size of x (which might be wider due to our dropping
@@ -1976,20 +2024,8 @@
 				x = e.p.NewValue1(pos, OpLoadReg, c.Type, c)
 			} else {
 				// mem->mem. Use temp register.
-
-				// Pre-clobber destination. This avoids the
-				// following situation:
-				//   - v is currently held in R0 and stacktmp0.
-				//   - We want to copy stacktmp1 to stacktmp0.
-				//   - We choose R0 as the temporary register.
-				// During the copy, both R0 and stacktmp0 are
-				// clobbered, losing both copies of v. Oops!
-				// Erasing the destination early means R0 will not
-				// be chosen as the temp register, as it will then
-				// be the last copy of v.
-				e.erase(loc)
-
 				r := e.findRegFor(c.Type)
+				e.erase(r)
 				t := e.p.NewValue1(pos, OpLoadReg, c.Type, c)
 				e.set(r, vid, t, false, pos)
 				x = e.p.NewValue1(pos, OpStoreReg, loc.(LocalSlot).Type, t)
@@ -2008,7 +2044,6 @@
 // set changes the contents of location loc to hold the given value and its cached representative.
 func (e *edgeState) set(loc Location, vid ID, c *Value, final bool, pos src.XPos) {
 	e.s.f.setHome(c, loc)
-	e.erase(loc)
 	e.contents[loc] = contentRecord{vid, c, final, pos}
 	a := e.cache[vid]
 	if len(a) == 0 {
@@ -2032,7 +2067,7 @@
 	}
 	if e.s.f.pass.debug > regDebug {
 		fmt.Printf("%s\n", c.LongString())
-		fmt.Printf("v%d now available in %s:%s\n", vid, loc.Name(), c)
+		fmt.Printf("v%d now available in %s:%s\n", vid, loc, c)
 	}
 }
 
@@ -2056,9 +2091,19 @@
 	for i, c := range a {
 		if e.s.f.getHome(c.ID) == loc {
 			if e.s.f.pass.debug > regDebug {
-				fmt.Printf("v%d no longer available in %s:%s\n", vid, loc.Name(), c)
+				fmt.Printf("v%d no longer available in %s:%s\n", vid, loc, c)
 			}
 			a[i], a = a[len(a)-1], a[:len(a)-1]
+			if e.s.f.Config.ctxt.Flag_locationlists {
+				if _, isReg := loc.(*Register); isReg && int(c.ID) < len(e.s.valueNames) && len(e.s.valueNames[c.ID]) != 0 {
+					kill := e.p.NewValue0(src.NoXPos, OpRegKill, types.TypeVoid)
+					e.s.f.setHome(kill, loc)
+					for _, name := range e.s.valueNames[c.ID] {
+						e.s.f.NamedValues[name] = append(e.s.f.NamedValues[name], kill)
+					}
+				}
+			}
+
 			break
 		}
 	}
@@ -2118,11 +2163,11 @@
 					// Allocate a temp location to spill a register to.
 					// The type of the slot is immaterial - it will not be live across
 					// any safepoint. Just use a type big enough to hold any register.
-					t := LocalSlot{e.s.f.fe.Auto(c.Pos, types.Int64), types.Int64, 0}
-					// TODO: reuse these slots.
+					t := LocalSlot{N: e.s.f.fe.Auto(c.Pos, types.Int64), Type: types.Int64}
+					// TODO: reuse these slots. They'll need to be erased first.
 					e.set(t, vid, x, false, c.Pos)
 					if e.s.f.pass.debug > regDebug {
-						fmt.Printf("  SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
+						fmt.Printf("  SPILL %s->%s %s\n", r, t, x.LongString())
 					}
 				}
 				// r will now be overwritten by the caller. At some point
@@ -2137,7 +2182,7 @@
 	for _, vid := range e.cachedVals {
 		a := e.cache[vid]
 		for _, c := range a {
-			fmt.Printf("v%d: %s %s\n", vid, c, e.s.f.getHome(c.ID).Name())
+			fmt.Printf("v%d: %s %s\n", vid, c, e.s.f.getHome(c.ID))
 		}
 	}
 	e.s.f.Fatalf("can't find empty register on edge %s->%s", e.p, e.b)
@@ -2165,12 +2210,6 @@
 	pos  src.XPos // source position of next use
 }
 
-// dblock contains information about desired & avoid registers at the end of a block.
-type dblock struct {
-	prefers []desiredStateEntry
-	avoid   regMask
-}
-
 // computeLive computes a map from block ID to a list of value IDs live at the end
 // of that block. Together with the value ID is a count of how many instructions
 // to the next use of that value. The resulting map is stored in s.live.
@@ -2360,7 +2399,7 @@
 						if !first {
 							fmt.Printf(",")
 						}
-						fmt.Print(s.registers[r].Name())
+						fmt.Print(&s.registers[r])
 						first = false
 					}
 					fmt.Printf("]")
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index b42d530..c617841 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -117,10 +117,6 @@
 	return t.IsSigned()
 }
 
-func typeSize(t *types.Type) int64 {
-	return t.Size()
-}
-
 // mergeSym merges two symbolic offsets. There is no real merging of
 // offsets, we just pick the non-nil one.
 func mergeSym(x, y interface{}) interface{} {
@@ -276,18 +272,6 @@
 	return true
 }
 
-// isArg returns whether s is an arg symbol
-func isArg(s interface{}) bool {
-	_, ok := s.(*ArgSymbol)
-	return ok
-}
-
-// isAuto returns whether s is an auto symbol
-func isAuto(s interface{}) bool {
-	_, ok := s.(*AutoSymbol)
-	return ok
-}
-
 // isSameSym returns whether sym is the same as the given named symbol
 func isSameSym(sym interface{}, name string) bool {
 	s, ok := sym.(fmt.Stringer)
@@ -305,6 +289,10 @@
 	return 64 - nlz(^x&(x-1))
 }
 
+func oneBit(x int64) bool {
+	return nlz(x)+ntz(x) == 63
+}
+
 // nlo returns the number of leading ones.
 func nlo(x int64) int64 {
 	return nlz(^x)
@@ -408,11 +396,11 @@
 // 'sym' is the symbol for the itab
 func devirt(v *Value, sym interface{}, offset int64) *obj.LSym {
 	f := v.Block.Func
-	ext, ok := sym.(*ExternSymbol)
+	n, ok := sym.(*obj.LSym)
 	if !ok {
 		return nil
 	}
-	lsym := f.fe.DerefItab(ext.Sym, offset)
+	lsym := f.fe.DerefItab(n, offset)
 	if f.pass.debug > 0 {
 		if lsym != nil {
 			f.Warnl(v.Pos, "de-virtualizing call")
@@ -644,3 +632,54 @@
 	}
 	return false
 }
+
+// check if value zeroes out upper 32-bit of 64-bit register.
+// depth limits recursion depth. In AMD64.rules 3 is used as limit,
+// because it catches same amount of cases as 4.
+func zeroUpper32Bits(x *Value, depth int) bool {
+	switch x.Op {
+	case OpAMD64MOVLconst, OpAMD64MOVLload, OpAMD64MOVLQZX, OpAMD64MOVLloadidx1,
+		OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVBload, OpAMD64MOVBloadidx1,
+		OpAMD64MOVLloadidx4, OpAMD64ADDLmem, OpAMD64SUBLmem, OpAMD64ANDLmem,
+		OpAMD64ORLmem, OpAMD64XORLmem, OpAMD64CVTTSD2SL,
+		OpAMD64ADDL, OpAMD64ADDLconst, OpAMD64SUBL, OpAMD64SUBLconst,
+		OpAMD64ANDL, OpAMD64ANDLconst, OpAMD64ORL, OpAMD64ORLconst,
+		OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL:
+		return true
+	case OpArg:
+		return x.Type.Width == 4
+	case OpSelect0, OpSelect1:
+		// Disabled for now. See issue 23305.
+		// TODO: we could look into the arg of the Select to decide.
+		return false
+	case OpPhi:
+		// Phis can use each-other as an arguments, instead of tracking visited values,
+		// just limit recursion depth.
+		if depth <= 0 {
+			return false
+		}
+		for i := range x.Args {
+			if !zeroUpper32Bits(x.Args[i], depth-1) {
+				return false
+			}
+		}
+		return true
+
+	}
+	return false
+}
+
+// inlineablememmovesize reports whether the given arch performs OpMove of the given size
+// faster than memmove and in a safe way when src and dst overlap.
+// This is used as a check for replacing memmove with OpMove.
+func isInlinableMemmoveSize(sz int64, c *Config) bool {
+	switch c.arch {
+	case "amd64", "amd64p32":
+		return sz <= 16
+	case "386", "ppc64", "s390x", "ppc64le":
+		return sz <= 8
+	case "arm", "mips", "mips64", "mipsle", "mips64le":
+		return sz <= 4
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go
index f9cddd0..32e8608 100644
--- a/src/cmd/compile/internal/ssa/rewrite386.go
+++ b/src/cmd/compile/internal/ssa/rewrite386.go
@@ -329,6 +329,10 @@
 		return rewriteValue386_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValue386_OpGeq8U_0(v)
+	case OpGetCallerPC:
+		return rewriteValue386_OpGetCallerPC_0(v)
+	case OpGetCallerSP:
+		return rewriteValue386_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValue386_OpGetClosurePtr_0(v)
 	case OpGetG:
@@ -3148,7 +3152,7 @@
 func rewriteValue386_Op386MOVBloadidx1_0(v *Value) bool {
 	// match: (MOVBloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVBloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3162,7 +3166,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVBloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3171,7 +3175,7 @@
 	}
 	// match: (MOVBloadidx1 [c] {sym} idx (ADDLconst [d] ptr) mem)
 	// cond:
-	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVBloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3185,7 +3189,7 @@
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVBloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3194,7 +3198,7 @@
 	}
 	// match: (MOVBloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVBloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3208,7 +3212,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVBloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3217,7 +3221,7 @@
 	}
 	// match: (MOVBloadidx1 [c] {sym} (ADDLconst [d] idx) ptr mem)
 	// cond:
-	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVBloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3231,7 +3235,7 @@
 		ptr := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVBloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3747,7 +3751,7 @@
 func rewriteValue386_Op386MOVBstoreidx1_0(v *Value) bool {
 	// match: (MOVBstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVBstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3762,7 +3766,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVBstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3772,7 +3776,7 @@
 	}
 	// match: (MOVBstoreidx1 [c] {sym} idx (ADDLconst [d] ptr) val mem)
 	// cond:
-	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVBstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3787,7 +3791,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVBstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3797,7 +3801,7 @@
 	}
 	// match: (MOVBstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVBstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3812,7 +3816,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVBstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -3822,7 +3826,7 @@
 	}
 	// match: (MOVBstoreidx1 [c] {sym} (ADDLconst [d] idx) ptr val mem)
 	// cond:
-	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVBstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -3837,7 +3841,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVBstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4486,7 +4490,7 @@
 	}
 	// match: (MOVLloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVLloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4500,7 +4504,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4509,7 +4513,7 @@
 	}
 	// match: (MOVLloadidx1 [c] {sym} idx (ADDLconst [d] ptr) mem)
 	// cond:
-	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVLloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4523,7 +4527,7 @@
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4532,7 +4536,7 @@
 	}
 	// match: (MOVLloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVLloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4546,7 +4550,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4555,7 +4559,7 @@
 	}
 	// match: (MOVLloadidx1 [c] {sym} (ADDLconst [d] idx) ptr mem)
 	// cond:
-	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVLloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4569,7 +4573,7 @@
 		ptr := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4581,7 +4585,7 @@
 func rewriteValue386_Op386MOVLloadidx4_0(v *Value) bool {
 	// match: (MOVLloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVLloadidx4 [c+d] {sym} ptr idx mem)
+	// result: (MOVLloadidx4 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4595,7 +4599,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx4)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -4604,7 +4608,7 @@
 	}
 	// match: (MOVLloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVLloadidx4 [c+4*d] {sym} ptr idx mem)
+	// result: (MOVLloadidx4  [int64(int32(c+4*d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -4618,7 +4622,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVLloadidx4)
-		v.AuxInt = c + 4*d
+		v.AuxInt = int64(int32(c + 4*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5114,7 +5118,7 @@
 	}
 	// match: (MOVLstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5129,7 +5133,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5139,7 +5143,7 @@
 	}
 	// match: (MOVLstoreidx1 [c] {sym} idx (ADDLconst [d] ptr) val mem)
 	// cond:
-	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5154,7 +5158,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5164,7 +5168,7 @@
 	}
 	// match: (MOVLstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5179,7 +5183,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5189,7 +5193,7 @@
 	}
 	// match: (MOVLstoreidx1 [c] {sym} (ADDLconst [d] idx) ptr val mem)
 	// cond:
-	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5204,7 +5208,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5217,7 +5221,7 @@
 func rewriteValue386_Op386MOVLstoreidx4_0(v *Value) bool {
 	// match: (MOVLstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVLstoreidx4 [c+d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx4 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5232,7 +5236,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx4)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5242,7 +5246,7 @@
 	}
 	// match: (MOVLstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVLstoreidx4 [c+4*d] {sym} ptr idx val mem)
+	// result: (MOVLstoreidx4  [int64(int32(c+4*d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5257,7 +5261,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVLstoreidx4)
-		v.AuxInt = c + 4*d
+		v.AuxInt = int64(int32(c + 4*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5431,7 +5435,7 @@
 func rewriteValue386_Op386MOVSDloadidx1_0(v *Value) bool {
 	// match: (MOVSDloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVSDloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5445,7 +5449,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVSDloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5454,7 +5458,7 @@
 	}
 	// match: (MOVSDloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVSDloadidx1 [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5468,7 +5472,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVSDloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5480,7 +5484,7 @@
 func rewriteValue386_Op386MOVSDloadidx8_0(v *Value) bool {
 	// match: (MOVSDloadidx8 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVSDloadidx8 [c+d] {sym} ptr idx mem)
+	// result: (MOVSDloadidx8 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5494,7 +5498,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVSDloadidx8)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5503,7 +5507,7 @@
 	}
 	// match: (MOVSDloadidx8 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVSDloadidx8 [c+8*d] {sym} ptr idx mem)
+	// result: (MOVSDloadidx8 [int64(int32(c+8*d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5517,7 +5521,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVSDloadidx8)
-		v.AuxInt = c + 8*d
+		v.AuxInt = int64(int32(c + 8*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5677,7 +5681,7 @@
 func rewriteValue386_Op386MOVSDstoreidx1_0(v *Value) bool {
 	// match: (MOVSDstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSDstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5692,7 +5696,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSDstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5702,7 +5706,7 @@
 	}
 	// match: (MOVSDstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSDstoreidx1 [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5717,7 +5721,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSDstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5730,7 +5734,7 @@
 func rewriteValue386_Op386MOVSDstoreidx8_0(v *Value) bool {
 	// match: (MOVSDstoreidx8 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVSDstoreidx8 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSDstoreidx8 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5745,7 +5749,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSDstoreidx8)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5755,7 +5759,7 @@
 	}
 	// match: (MOVSDstoreidx8 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVSDstoreidx8 [c+8*d] {sym} ptr idx val mem)
+	// result: (MOVSDstoreidx8 [int64(int32(c+8*d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5770,7 +5774,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSDstoreidx8)
-		v.AuxInt = c + 8*d
+		v.AuxInt = int64(int32(c + 8*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5944,7 +5948,7 @@
 func rewriteValue386_Op386MOVSSloadidx1_0(v *Value) bool {
 	// match: (MOVSSloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVSSloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5958,7 +5962,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVSSloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5967,7 +5971,7 @@
 	}
 	// match: (MOVSSloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVSSloadidx1 [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -5981,7 +5985,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVSSloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -5993,7 +5997,7 @@
 func rewriteValue386_Op386MOVSSloadidx4_0(v *Value) bool {
 	// match: (MOVSSloadidx4 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVSSloadidx4 [c+d] {sym} ptr idx mem)
+	// result: (MOVSSloadidx4 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6007,7 +6011,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVSSloadidx4)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6016,7 +6020,7 @@
 	}
 	// match: (MOVSSloadidx4 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVSSloadidx4 [c+4*d] {sym} ptr idx mem)
+	// result: (MOVSSloadidx4 [int64(int32(c+4*d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6030,7 +6034,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVSSloadidx4)
-		v.AuxInt = c + 4*d
+		v.AuxInt = int64(int32(c + 4*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6190,7 +6194,7 @@
 func rewriteValue386_Op386MOVSSstoreidx1_0(v *Value) bool {
 	// match: (MOVSSstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSSstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6205,7 +6209,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSSstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6215,7 +6219,7 @@
 	}
 	// match: (MOVSSstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSSstoreidx1 [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6230,7 +6234,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSSstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6243,7 +6247,7 @@
 func rewriteValue386_Op386MOVSSstoreidx4_0(v *Value) bool {
 	// match: (MOVSSstoreidx4 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVSSstoreidx4 [c+d] {sym} ptr idx val mem)
+	// result: (MOVSSstoreidx4 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6258,7 +6262,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSSstoreidx4)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6268,7 +6272,7 @@
 	}
 	// match: (MOVSSstoreidx4 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVSSstoreidx4 [c+4*d] {sym} ptr idx val mem)
+	// result: (MOVSSstoreidx4 [int64(int32(c+4*d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6283,7 +6287,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVSSstoreidx4)
-		v.AuxInt = c + 4*d
+		v.AuxInt = int64(int32(c + 4*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6715,7 +6719,7 @@
 	}
 	// match: (MOVWloadidx1 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVWloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6729,7 +6733,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6738,7 +6742,7 @@
 	}
 	// match: (MOVWloadidx1 [c] {sym} idx (ADDLconst [d] ptr) mem)
 	// cond:
-	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVWloadidx1 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6752,7 +6756,7 @@
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6761,7 +6765,7 @@
 	}
 	// match: (MOVWloadidx1 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVWloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6775,7 +6779,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6784,7 +6788,7 @@
 	}
 	// match: (MOVWloadidx1 [c] {sym} (ADDLconst [d] idx) ptr mem)
 	// cond:
-	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
+	// result: (MOVWloadidx1  [int64(int32(c+d))]   {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6798,7 +6802,7 @@
 		ptr := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6810,7 +6814,7 @@
 func rewriteValue386_Op386MOVWloadidx2_0(v *Value) bool {
 	// match: (MOVWloadidx2 [c] {sym} (ADDLconst [d] ptr) idx mem)
 	// cond:
-	// result: (MOVWloadidx2 [c+d] {sym} ptr idx mem)
+	// result: (MOVWloadidx2 [int64(int32(c+d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6824,7 +6828,7 @@
 		idx := v.Args[1]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx2)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -6833,7 +6837,7 @@
 	}
 	// match: (MOVWloadidx2 [c] {sym} ptr (ADDLconst [d] idx) mem)
 	// cond:
-	// result: (MOVWloadidx2 [c+2*d] {sym} ptr idx mem)
+	// result: (MOVWloadidx2  [int64(int32(c+2*d))] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -6847,7 +6851,7 @@
 		idx := v_1.Args[0]
 		mem := v.Args[2]
 		v.reset(Op386MOVWloadidx2)
-		v.AuxInt = c + 2*d
+		v.AuxInt = int64(int32(c + 2*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -7590,7 +7594,7 @@
 	}
 	// match: (MOVWstoreidx1 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -7605,7 +7609,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -7615,7 +7619,7 @@
 	}
 	// match: (MOVWstoreidx1 [c] {sym} idx (ADDLconst [d] ptr) val mem)
 	// cond:
-	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx1 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -7630,7 +7634,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -7640,7 +7644,7 @@
 	}
 	// match: (MOVWstoreidx1 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -7655,7 +7659,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -7665,7 +7669,7 @@
 	}
 	// match: (MOVWstoreidx1 [c] {sym} (ADDLconst [d] idx) ptr val mem)
 	// cond:
-	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx1  [int64(int32(c+d))]   {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -7680,7 +7684,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx1)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -8118,7 +8122,7 @@
 	_ = b
 	// match: (MOVWstoreidx2 [c] {sym} (ADDLconst [d] ptr) idx val mem)
 	// cond:
-	// result: (MOVWstoreidx2 [c+d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx2 [int64(int32(c+d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -8133,7 +8137,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx2)
-		v.AuxInt = c + d
+		v.AuxInt = int64(int32(c + d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -8143,7 +8147,7 @@
 	}
 	// match: (MOVWstoreidx2 [c] {sym} ptr (ADDLconst [d] idx) val mem)
 	// cond:
-	// result: (MOVWstoreidx2 [c+2*d] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx2  [int64(int32(c+2*d))] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -8158,7 +8162,7 @@
 		val := v.Args[2]
 		mem := v.Args[3]
 		v.reset(Op386MOVWstoreidx2)
-		v.AuxInt = c + 2*d
+		v.AuxInt = int64(int32(c + 2*d))
 		v.Aux = sym
 		v.AddArg(ptr)
 		v.AddArg(idx)
@@ -8541,20 +8545,6 @@
 		return true
 	}
 	// match: (MULLconst [c] x)
-	// cond: isPowerOfTwo(c)
-	// result: (SHLLconst [log2(c)] x)
-	for {
-		c := v.AuxInt
-		x := v.Args[0]
-		if !(isPowerOfTwo(c)) {
-			break
-		}
-		v.reset(Op386SHLLconst)
-		v.AuxInt = log2(c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (MULLconst [c] x)
 	// cond: isPowerOfTwo(c+1) && c >= 15
 	// result: (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
 	for {
@@ -8622,11 +8612,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValue386_Op386MULLconst_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (MULLconst [c] x)
 	// cond: isPowerOfTwo(c-8) && c >= 136
 	// result: (LEAL8 (SHLLconst <v.Type> [log2(c-8)] x) x)
@@ -8644,6 +8629,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValue386_Op386MULLconst_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (MULLconst [c] x)
 	// cond: c%3 == 0 && isPowerOfTwo(c/3)
 	// result: (SHLLconst [log2(c/3)] (LEAL2 <v.Type> x x))
@@ -15052,6 +15042,24 @@
 		return true
 	}
 }
+func rewriteValue386_OpGetCallerPC_0(v *Value) bool {
+	// match: (GetCallerPC)
+	// cond:
+	// result: (LoweredGetCallerPC)
+	for {
+		v.reset(Op386LoweredGetCallerPC)
+		return true
+	}
+}
+func rewriteValue386_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(Op386LoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValue386_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -18325,6 +18333,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagEQ) yes no)
@@ -18337,6 +18346,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT_ULT) yes no)
@@ -18349,6 +18359,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18362,6 +18373,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18375,6 +18387,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18388,6 +18401,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18403,6 +18417,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagEQ) yes no)
@@ -18415,6 +18430,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT_ULT) yes no)
@@ -18427,6 +18443,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18440,6 +18457,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18453,6 +18471,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagGT_UGT) yes no)
@@ -18465,6 +18484,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case Block386GT:
@@ -18479,6 +18499,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagEQ) yes no)
@@ -18491,6 +18512,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18504,6 +18526,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18517,6 +18540,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18530,6 +18554,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagGT_UGT) yes no)
@@ -18542,6 +18567,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -18556,6 +18582,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETLE cmp) yes no)
@@ -18569,6 +18596,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETG cmp) yes no)
@@ -18582,6 +18610,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGE cmp) yes no)
@@ -18595,6 +18624,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETEQ cmp) yes no)
@@ -18608,6 +18638,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETNE cmp) yes no)
@@ -18621,6 +18652,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETB cmp) yes no)
@@ -18634,6 +18666,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETBE cmp) yes no)
@@ -18647,6 +18680,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETA cmp) yes no)
@@ -18660,6 +18694,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETAE cmp) yes no)
@@ -18673,6 +18708,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGF cmp) yes no)
@@ -18686,6 +18722,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGEF cmp) yes no)
@@ -18699,6 +18736,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETEQF cmp) yes no)
@@ -18712,6 +18750,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETNEF cmp) yes no)
@@ -18725,6 +18764,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -18739,6 +18779,7 @@
 			v0.AddArg(cond)
 			v0.AddArg(cond)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case Block386LE:
@@ -18753,6 +18794,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagEQ) yes no)
@@ -18765,6 +18807,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_ULT) yes no)
@@ -18777,6 +18820,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_UGT) yes no)
@@ -18789,6 +18833,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT_ULT) yes no)
@@ -18801,6 +18846,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18814,6 +18860,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18829,6 +18876,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagEQ) yes no)
@@ -18841,6 +18889,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18854,6 +18903,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagLT_UGT) yes no)
@@ -18866,6 +18916,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT_ULT) yes no)
@@ -18878,6 +18929,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18891,6 +18943,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18918,6 +18971,7 @@
 			}
 			b.Kind = Block386LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETL cmp) (SETL cmp)) yes no)
@@ -18943,6 +18997,7 @@
 			}
 			b.Kind = Block386LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETLE cmp) (SETLE cmp)) yes no)
@@ -18968,6 +19023,7 @@
 			}
 			b.Kind = Block386LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETLE cmp) (SETLE cmp)) yes no)
@@ -18993,6 +19049,7 @@
 			}
 			b.Kind = Block386LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETG cmp) (SETG cmp)) yes no)
@@ -19018,6 +19075,7 @@
 			}
 			b.Kind = Block386GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETG cmp) (SETG cmp)) yes no)
@@ -19043,6 +19101,7 @@
 			}
 			b.Kind = Block386GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGE cmp) (SETGE cmp)) yes no)
@@ -19068,6 +19127,7 @@
 			}
 			b.Kind = Block386GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGE cmp) (SETGE cmp)) yes no)
@@ -19093,6 +19153,7 @@
 			}
 			b.Kind = Block386GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no)
@@ -19118,6 +19179,7 @@
 			}
 			b.Kind = Block386EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no)
@@ -19143,6 +19205,7 @@
 			}
 			b.Kind = Block386EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNE cmp) (SETNE cmp)) yes no)
@@ -19168,6 +19231,7 @@
 			}
 			b.Kind = Block386NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNE cmp) (SETNE cmp)) yes no)
@@ -19193,6 +19257,7 @@
 			}
 			b.Kind = Block386NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETB cmp) (SETB cmp)) yes no)
@@ -19218,6 +19283,7 @@
 			}
 			b.Kind = Block386ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETB cmp) (SETB cmp)) yes no)
@@ -19243,6 +19309,7 @@
 			}
 			b.Kind = Block386ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETBE cmp) (SETBE cmp)) yes no)
@@ -19268,6 +19335,7 @@
 			}
 			b.Kind = Block386ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETBE cmp) (SETBE cmp)) yes no)
@@ -19293,6 +19361,7 @@
 			}
 			b.Kind = Block386ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETA cmp) (SETA cmp)) yes no)
@@ -19318,6 +19387,7 @@
 			}
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETA cmp) (SETA cmp)) yes no)
@@ -19343,6 +19413,7 @@
 			}
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETAE cmp) (SETAE cmp)) yes no)
@@ -19368,6 +19439,7 @@
 			}
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETAE cmp) (SETAE cmp)) yes no)
@@ -19393,6 +19465,7 @@
 			}
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGF cmp) (SETGF cmp)) yes no)
@@ -19418,6 +19491,7 @@
 			}
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGF cmp) (SETGF cmp)) yes no)
@@ -19443,6 +19517,7 @@
 			}
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no)
@@ -19468,6 +19543,7 @@
 			}
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no)
@@ -19493,6 +19569,7 @@
 			}
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no)
@@ -19518,6 +19595,7 @@
 			}
 			b.Kind = Block386EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no)
@@ -19543,6 +19621,7 @@
 			}
 			b.Kind = Block386EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no)
@@ -19568,6 +19647,7 @@
 			}
 			b.Kind = Block386NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no)
@@ -19593,6 +19673,7 @@
 			}
 			b.Kind = Block386NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -19606,6 +19687,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -19618,6 +19700,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19631,6 +19714,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagLT_UGT) yes no)
@@ -19643,6 +19727,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_ULT) yes no)
@@ -19655,6 +19740,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_UGT) yes no)
@@ -19667,6 +19753,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case Block386UGE:
@@ -19681,6 +19768,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagEQ) yes no)
@@ -19693,6 +19781,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagLT_ULT) yes no)
@@ -19705,6 +19794,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19718,6 +19808,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagGT_ULT) yes no)
@@ -19730,6 +19821,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19743,6 +19835,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case Block386UGT:
@@ -19757,6 +19850,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagEQ) yes no)
@@ -19769,6 +19863,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19782,6 +19877,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19795,6 +19891,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagGT_ULT) yes no)
@@ -19807,6 +19904,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19820,6 +19918,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case Block386ULE:
@@ -19834,6 +19933,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagEQ) yes no)
@@ -19846,6 +19946,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_ULT) yes no)
@@ -19858,6 +19959,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_UGT) yes no)
@@ -19870,6 +19972,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19883,6 +19986,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagGT_UGT) yes no)
@@ -19895,6 +19999,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19910,6 +20015,7 @@
 			cmp := v.Args[0]
 			b.Kind = Block386UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagEQ) yes no)
@@ -19922,6 +20028,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19935,6 +20042,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagLT_UGT) yes no)
@@ -19947,6 +20055,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19960,6 +20069,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagGT_UGT) yes no)
@@ -19972,6 +20082,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index f9a94ca..0b2b321 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -19,22 +19,38 @@
 		return rewriteValueAMD64_OpAMD64ADDL_0(v) || rewriteValueAMD64_OpAMD64ADDL_10(v)
 	case OpAMD64ADDLconst:
 		return rewriteValueAMD64_OpAMD64ADDLconst_0(v)
+	case OpAMD64ADDLconstmem:
+		return rewriteValueAMD64_OpAMD64ADDLconstmem_0(v)
+	case OpAMD64ADDLmem:
+		return rewriteValueAMD64_OpAMD64ADDLmem_0(v)
 	case OpAMD64ADDQ:
 		return rewriteValueAMD64_OpAMD64ADDQ_0(v) || rewriteValueAMD64_OpAMD64ADDQ_10(v) || rewriteValueAMD64_OpAMD64ADDQ_20(v)
 	case OpAMD64ADDQconst:
 		return rewriteValueAMD64_OpAMD64ADDQconst_0(v)
+	case OpAMD64ADDQconstmem:
+		return rewriteValueAMD64_OpAMD64ADDQconstmem_0(v)
+	case OpAMD64ADDQmem:
+		return rewriteValueAMD64_OpAMD64ADDQmem_0(v)
 	case OpAMD64ADDSD:
 		return rewriteValueAMD64_OpAMD64ADDSD_0(v)
+	case OpAMD64ADDSDmem:
+		return rewriteValueAMD64_OpAMD64ADDSDmem_0(v)
 	case OpAMD64ADDSS:
 		return rewriteValueAMD64_OpAMD64ADDSS_0(v)
+	case OpAMD64ADDSSmem:
+		return rewriteValueAMD64_OpAMD64ADDSSmem_0(v)
 	case OpAMD64ANDL:
 		return rewriteValueAMD64_OpAMD64ANDL_0(v)
 	case OpAMD64ANDLconst:
 		return rewriteValueAMD64_OpAMD64ANDLconst_0(v)
+	case OpAMD64ANDLmem:
+		return rewriteValueAMD64_OpAMD64ANDLmem_0(v)
 	case OpAMD64ANDQ:
 		return rewriteValueAMD64_OpAMD64ANDQ_0(v)
 	case OpAMD64ANDQconst:
 		return rewriteValueAMD64_OpAMD64ANDQconst_0(v)
+	case OpAMD64ANDQmem:
+		return rewriteValueAMD64_OpAMD64ANDQmem_0(v)
 	case OpAMD64BSFQ:
 		return rewriteValueAMD64_OpAMD64BSFQ_0(v)
 	case OpAMD64BTQconst:
@@ -84,7 +100,7 @@
 	case OpAMD64MOVBloadidx1:
 		return rewriteValueAMD64_OpAMD64MOVBloadidx1_0(v)
 	case OpAMD64MOVBstore:
-		return rewriteValueAMD64_OpAMD64MOVBstore_0(v) || rewriteValueAMD64_OpAMD64MOVBstore_10(v)
+		return rewriteValueAMD64_OpAMD64MOVBstore_0(v) || rewriteValueAMD64_OpAMD64MOVBstore_10(v) || rewriteValueAMD64_OpAMD64MOVBstore_20(v)
 	case OpAMD64MOVBstoreconst:
 		return rewriteValueAMD64_OpAMD64MOVBstoreconst_0(v)
 	case OpAMD64MOVBstoreconstidx1:
@@ -99,12 +115,18 @@
 		return rewriteValueAMD64_OpAMD64MOVLQZX_0(v)
 	case OpAMD64MOVLatomicload:
 		return rewriteValueAMD64_OpAMD64MOVLatomicload_0(v)
+	case OpAMD64MOVLf2i:
+		return rewriteValueAMD64_OpAMD64MOVLf2i_0(v)
+	case OpAMD64MOVLi2f:
+		return rewriteValueAMD64_OpAMD64MOVLi2f_0(v)
 	case OpAMD64MOVLload:
 		return rewriteValueAMD64_OpAMD64MOVLload_0(v)
 	case OpAMD64MOVLloadidx1:
 		return rewriteValueAMD64_OpAMD64MOVLloadidx1_0(v)
 	case OpAMD64MOVLloadidx4:
 		return rewriteValueAMD64_OpAMD64MOVLloadidx4_0(v)
+	case OpAMD64MOVLloadidx8:
+		return rewriteValueAMD64_OpAMD64MOVLloadidx8_0(v)
 	case OpAMD64MOVLstore:
 		return rewriteValueAMD64_OpAMD64MOVLstore_0(v) || rewriteValueAMD64_OpAMD64MOVLstore_10(v)
 	case OpAMD64MOVLstoreconst:
@@ -117,12 +139,18 @@
 		return rewriteValueAMD64_OpAMD64MOVLstoreidx1_0(v)
 	case OpAMD64MOVLstoreidx4:
 		return rewriteValueAMD64_OpAMD64MOVLstoreidx4_0(v)
+	case OpAMD64MOVLstoreidx8:
+		return rewriteValueAMD64_OpAMD64MOVLstoreidx8_0(v)
 	case OpAMD64MOVOload:
 		return rewriteValueAMD64_OpAMD64MOVOload_0(v)
 	case OpAMD64MOVOstore:
 		return rewriteValueAMD64_OpAMD64MOVOstore_0(v)
 	case OpAMD64MOVQatomicload:
 		return rewriteValueAMD64_OpAMD64MOVQatomicload_0(v)
+	case OpAMD64MOVQf2i:
+		return rewriteValueAMD64_OpAMD64MOVQf2i_0(v)
+	case OpAMD64MOVQi2f:
+		return rewriteValueAMD64_OpAMD64MOVQi2f_0(v)
 	case OpAMD64MOVQload:
 		return rewriteValueAMD64_OpAMD64MOVQload_0(v)
 	case OpAMD64MOVQloadidx1:
@@ -199,8 +227,12 @@
 		return rewriteValueAMD64_OpAMD64MULQconst_0(v) || rewriteValueAMD64_OpAMD64MULQconst_10(v) || rewriteValueAMD64_OpAMD64MULQconst_20(v)
 	case OpAMD64MULSD:
 		return rewriteValueAMD64_OpAMD64MULSD_0(v)
+	case OpAMD64MULSDmem:
+		return rewriteValueAMD64_OpAMD64MULSDmem_0(v)
 	case OpAMD64MULSS:
 		return rewriteValueAMD64_OpAMD64MULSS_0(v)
+	case OpAMD64MULSSmem:
+		return rewriteValueAMD64_OpAMD64MULSSmem_0(v)
 	case OpAMD64NEGL:
 		return rewriteValueAMD64_OpAMD64NEGL_0(v)
 	case OpAMD64NEGQ:
@@ -213,10 +245,14 @@
 		return rewriteValueAMD64_OpAMD64ORL_0(v) || rewriteValueAMD64_OpAMD64ORL_10(v) || rewriteValueAMD64_OpAMD64ORL_20(v) || rewriteValueAMD64_OpAMD64ORL_30(v) || rewriteValueAMD64_OpAMD64ORL_40(v) || rewriteValueAMD64_OpAMD64ORL_50(v) || rewriteValueAMD64_OpAMD64ORL_60(v) || rewriteValueAMD64_OpAMD64ORL_70(v) || rewriteValueAMD64_OpAMD64ORL_80(v) || rewriteValueAMD64_OpAMD64ORL_90(v) || rewriteValueAMD64_OpAMD64ORL_100(v) || rewriteValueAMD64_OpAMD64ORL_110(v) || rewriteValueAMD64_OpAMD64ORL_120(v) || rewriteValueAMD64_OpAMD64ORL_130(v)
 	case OpAMD64ORLconst:
 		return rewriteValueAMD64_OpAMD64ORLconst_0(v)
+	case OpAMD64ORLmem:
+		return rewriteValueAMD64_OpAMD64ORLmem_0(v)
 	case OpAMD64ORQ:
 		return rewriteValueAMD64_OpAMD64ORQ_0(v) || rewriteValueAMD64_OpAMD64ORQ_10(v) || rewriteValueAMD64_OpAMD64ORQ_20(v) || rewriteValueAMD64_OpAMD64ORQ_30(v) || rewriteValueAMD64_OpAMD64ORQ_40(v) || rewriteValueAMD64_OpAMD64ORQ_50(v) || rewriteValueAMD64_OpAMD64ORQ_60(v) || rewriteValueAMD64_OpAMD64ORQ_70(v) || rewriteValueAMD64_OpAMD64ORQ_80(v) || rewriteValueAMD64_OpAMD64ORQ_90(v) || rewriteValueAMD64_OpAMD64ORQ_100(v) || rewriteValueAMD64_OpAMD64ORQ_110(v) || rewriteValueAMD64_OpAMD64ORQ_120(v) || rewriteValueAMD64_OpAMD64ORQ_130(v) || rewriteValueAMD64_OpAMD64ORQ_140(v) || rewriteValueAMD64_OpAMD64ORQ_150(v) || rewriteValueAMD64_OpAMD64ORQ_160(v)
 	case OpAMD64ORQconst:
 		return rewriteValueAMD64_OpAMD64ORQconst_0(v)
+	case OpAMD64ORQmem:
+		return rewriteValueAMD64_OpAMD64ORQmem_0(v)
 	case OpAMD64ROLB:
 		return rewriteValueAMD64_OpAMD64ROLB_0(v)
 	case OpAMD64ROLBconst:
@@ -265,22 +301,42 @@
 		return rewriteValueAMD64_OpAMD64SETA_0(v)
 	case OpAMD64SETAE:
 		return rewriteValueAMD64_OpAMD64SETAE_0(v)
+	case OpAMD64SETAEmem:
+		return rewriteValueAMD64_OpAMD64SETAEmem_0(v)
+	case OpAMD64SETAmem:
+		return rewriteValueAMD64_OpAMD64SETAmem_0(v)
 	case OpAMD64SETB:
 		return rewriteValueAMD64_OpAMD64SETB_0(v)
 	case OpAMD64SETBE:
 		return rewriteValueAMD64_OpAMD64SETBE_0(v)
+	case OpAMD64SETBEmem:
+		return rewriteValueAMD64_OpAMD64SETBEmem_0(v)
+	case OpAMD64SETBmem:
+		return rewriteValueAMD64_OpAMD64SETBmem_0(v)
 	case OpAMD64SETEQ:
 		return rewriteValueAMD64_OpAMD64SETEQ_0(v) || rewriteValueAMD64_OpAMD64SETEQ_10(v)
+	case OpAMD64SETEQmem:
+		return rewriteValueAMD64_OpAMD64SETEQmem_0(v) || rewriteValueAMD64_OpAMD64SETEQmem_10(v)
 	case OpAMD64SETG:
 		return rewriteValueAMD64_OpAMD64SETG_0(v)
 	case OpAMD64SETGE:
 		return rewriteValueAMD64_OpAMD64SETGE_0(v)
+	case OpAMD64SETGEmem:
+		return rewriteValueAMD64_OpAMD64SETGEmem_0(v)
+	case OpAMD64SETGmem:
+		return rewriteValueAMD64_OpAMD64SETGmem_0(v)
 	case OpAMD64SETL:
 		return rewriteValueAMD64_OpAMD64SETL_0(v)
 	case OpAMD64SETLE:
 		return rewriteValueAMD64_OpAMD64SETLE_0(v)
+	case OpAMD64SETLEmem:
+		return rewriteValueAMD64_OpAMD64SETLEmem_0(v)
+	case OpAMD64SETLmem:
+		return rewriteValueAMD64_OpAMD64SETLmem_0(v)
 	case OpAMD64SETNE:
 		return rewriteValueAMD64_OpAMD64SETNE_0(v) || rewriteValueAMD64_OpAMD64SETNE_10(v)
+	case OpAMD64SETNEmem:
+		return rewriteValueAMD64_OpAMD64SETNEmem_0(v) || rewriteValueAMD64_OpAMD64SETNEmem_10(v)
 	case OpAMD64SHLL:
 		return rewriteValueAMD64_OpAMD64SHLL_0(v)
 	case OpAMD64SHLLconst:
@@ -309,14 +365,22 @@
 		return rewriteValueAMD64_OpAMD64SUBL_0(v)
 	case OpAMD64SUBLconst:
 		return rewriteValueAMD64_OpAMD64SUBLconst_0(v)
+	case OpAMD64SUBLmem:
+		return rewriteValueAMD64_OpAMD64SUBLmem_0(v)
 	case OpAMD64SUBQ:
 		return rewriteValueAMD64_OpAMD64SUBQ_0(v)
 	case OpAMD64SUBQconst:
 		return rewriteValueAMD64_OpAMD64SUBQconst_0(v)
+	case OpAMD64SUBQmem:
+		return rewriteValueAMD64_OpAMD64SUBQmem_0(v)
 	case OpAMD64SUBSD:
 		return rewriteValueAMD64_OpAMD64SUBSD_0(v)
+	case OpAMD64SUBSDmem:
+		return rewriteValueAMD64_OpAMD64SUBSDmem_0(v)
 	case OpAMD64SUBSS:
 		return rewriteValueAMD64_OpAMD64SUBSS_0(v)
+	case OpAMD64SUBSSmem:
+		return rewriteValueAMD64_OpAMD64SUBSSmem_0(v)
 	case OpAMD64TESTB:
 		return rewriteValueAMD64_OpAMD64TESTB_0(v)
 	case OpAMD64TESTL:
@@ -337,10 +401,14 @@
 		return rewriteValueAMD64_OpAMD64XORL_0(v) || rewriteValueAMD64_OpAMD64XORL_10(v)
 	case OpAMD64XORLconst:
 		return rewriteValueAMD64_OpAMD64XORLconst_0(v) || rewriteValueAMD64_OpAMD64XORLconst_10(v)
+	case OpAMD64XORLmem:
+		return rewriteValueAMD64_OpAMD64XORLmem_0(v)
 	case OpAMD64XORQ:
 		return rewriteValueAMD64_OpAMD64XORQ_0(v)
 	case OpAMD64XORQconst:
 		return rewriteValueAMD64_OpAMD64XORQconst_0(v)
+	case OpAMD64XORQmem:
+		return rewriteValueAMD64_OpAMD64XORQmem_0(v)
 	case OpAdd16:
 		return rewriteValueAMD64_OpAdd16_0(v)
 	case OpAdd32:
@@ -405,6 +473,8 @@
 		return rewriteValueAMD64_OpBswap32_0(v)
 	case OpBswap64:
 		return rewriteValueAMD64_OpBswap64_0(v)
+	case OpCeil:
+		return rewriteValueAMD64_OpCeil_0(v)
 	case OpClosureCall:
 		return rewriteValueAMD64_OpClosureCall_0(v)
 	case OpCom16:
@@ -495,6 +565,8 @@
 		return rewriteValueAMD64_OpEqB_0(v)
 	case OpEqPtr:
 		return rewriteValueAMD64_OpEqPtr_0(v)
+	case OpFloor:
+		return rewriteValueAMD64_OpFloor_0(v)
 	case OpGeq16:
 		return rewriteValueAMD64_OpGeq16_0(v)
 	case OpGeq16U:
@@ -515,6 +587,10 @@
 		return rewriteValueAMD64_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueAMD64_OpGeq8U_0(v)
+	case OpGetCallerPC:
+		return rewriteValueAMD64_OpGetCallerPC_0(v)
+	case OpGetCallerSP:
+		return rewriteValueAMD64_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueAMD64_OpGetClosurePtr_0(v)
 	case OpGetG:
@@ -719,6 +795,8 @@
 		return rewriteValueAMD64_OpRound32F_0(v)
 	case OpRound64F:
 		return rewriteValueAMD64_OpRound64F_0(v)
+	case OpRoundToEven:
+		return rewriteValueAMD64_OpRoundToEven_0(v)
 	case OpRsh16Ux16:
 		return rewriteValueAMD64_OpRsh16Ux16_0(v)
 	case OpRsh16Ux32:
@@ -821,6 +899,8 @@
 		return rewriteValueAMD64_OpSub8_0(v)
 	case OpSubPtr:
 		return rewriteValueAMD64_OpSubPtr_0(v)
+	case OpTrunc:
+		return rewriteValueAMD64_OpTrunc_0(v)
 	case OpTrunc16to8:
 		return rewriteValueAMD64_OpTrunc16to8_0(v)
 	case OpTrunc32to16:
@@ -833,6 +913,8 @@
 		return rewriteValueAMD64_OpTrunc64to32_0(v)
 	case OpTrunc64to8:
 		return rewriteValueAMD64_OpTrunc64to8_0(v)
+	case OpWB:
+		return rewriteValueAMD64_OpWB_0(v)
 	case OpXor16:
 		return rewriteValueAMD64_OpXor16_0(v)
 	case OpXor32:
@@ -842,7 +924,7 @@
 	case OpXor8:
 		return rewriteValueAMD64_OpXor8_0(v)
 	case OpZero:
-		return rewriteValueAMD64_OpZero_0(v) || rewriteValueAMD64_OpZero_10(v)
+		return rewriteValueAMD64_OpZero_0(v) || rewriteValueAMD64_OpZero_10(v) || rewriteValueAMD64_OpZero_20(v)
 	case OpZeroExt16to32:
 		return rewriteValueAMD64_OpZeroExt16to32_0(v)
 	case OpZeroExt16to64:
@@ -1214,6 +1296,81 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ADDLconstmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDLconstmem [valOff] {sym} ptr (MOVSSstore [ValAndOff(valOff).Off()] {sym} ptr x _))
+	// cond:
+	// result: (ADDLconst [ValAndOff(valOff).Val()] (MOVLf2i x))
+	for {
+		valOff := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_1.AuxInt != ValAndOff(valOff).Off() {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		x := v_1.Args[1]
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = ValAndOff(valOff).Val()
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64ADDLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ADDL x (MOVLf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ADDL)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ADDQ_0(v *Value) bool {
 	// match: (ADDQ x (MOVQconst [c]))
 	// cond: is32Bit(c)
@@ -1899,6 +2056,81 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ADDQconstmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDQconstmem [valOff] {sym} ptr (MOVSDstore [ValAndOff(valOff).Off()] {sym} ptr x _))
+	// cond:
+	// result: (ADDQconst [ValAndOff(valOff).Val()] (MOVQf2i x))
+	for {
+		valOff := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_1.AuxInt != ValAndOff(valOff).Off() {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		x := v_1.Args[1]
+		v.reset(OpAMD64ADDQconst)
+		v.AuxInt = ValAndOff(valOff).Val()
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64ADDQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ADDQ x (MOVQf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ADDQ)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ADDSD_0(v *Value) bool {
 	// match: (ADDSD x l:(MOVSDload [off] {sym} ptr mem))
 	// cond: canMergeLoad(v, l, x) && clobber(l)
@@ -1954,6 +2186,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ADDSDmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ADDSD x (MOVQi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVQstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ADDSD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQi2f, typ.Float64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ADDSS_0(v *Value) bool {
 	// match: (ADDSS x l:(MOVSSload [off] {sym} ptr mem))
 	// cond: canMergeLoad(v, l, x) && clobber(l)
@@ -2009,6 +2279,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ADDSSmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ADDSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ADDSS x (MOVLi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVLstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ADDSS)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLi2f, typ.Float32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ANDL_0(v *Value) bool {
 	// match: (ANDL x (MOVLconst [c]))
 	// cond:
@@ -2193,6 +2501,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ANDLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ANDLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ANDL x (MOVLf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ANDL)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ANDQ_0(v *Value) bool {
 	// match: (ANDQ x (MOVQconst [c]))
 	// cond: is32Bit(c)
@@ -2393,6 +2739,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ANDQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ANDQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _))
+	// cond:
+	// result: (ANDQ x (MOVQf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ANDQ)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64BSFQ_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -4319,16 +4703,16 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVBQSX x:(MOVBQSX _))
+	// match: (MOVBQSX (MOVBQSX x))
 	// cond:
-	// result: x
+	// result: (MOVBQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQSX)
 		v.AddArg(x)
 		return true
 	}
@@ -4536,16 +4920,16 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVBQZX x:(MOVBQZX _))
+	// match: (MOVBQZX (MOVBQZX x))
 	// cond:
-	// result: x
+	// result: (MOVBQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQZX)
 		v.AddArg(x)
 		return true
 	}
@@ -4680,7 +5064,7 @@
 		return true
 	}
 	// match: (MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVBload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
 	for {
 		off1 := v.AuxInt
@@ -4694,7 +5078,7 @@
 		sym2 := v_0.Aux
 		base := v_0.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVBload)
@@ -4732,7 +5116,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVBloadidx1_0(v *Value) bool {
 	// match: (MOVBloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -4746,6 +5130,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -4755,7 +5142,7 @@
 		return true
 	}
 	// match: (MOVBloadidx1 [c] {sym} idx (ADDQconst [d] ptr) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -4769,6 +5156,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -4778,7 +5168,7 @@
 		return true
 	}
 	// match: (MOVBloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -4792,6 +5182,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -4801,7 +5194,7 @@
 		return true
 	}
 	// match: (MOVBloadidx1 [c] {sym} (ADDQconst [d] idx) ptr mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -4815,6 +5208,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -4826,6 +5222,259 @@
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVBstore_0(v *Value) bool {
+	// match: (MOVBstore [off] {sym} ptr y:(SETL x) mem)
+	// cond: y.Uses == 1
+	// result: (SETLmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETL {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETLmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETLE x) mem)
+	// cond: y.Uses == 1
+	// result: (SETLEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETLE {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETLEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETG x) mem)
+	// cond: y.Uses == 1
+	// result: (SETGmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETG {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETGmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETGE x) mem)
+	// cond: y.Uses == 1
+	// result: (SETGEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETGE {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETGEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETEQ x) mem)
+	// cond: y.Uses == 1
+	// result: (SETEQmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETEQ {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETEQmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETNE x) mem)
+	// cond: y.Uses == 1
+	// result: (SETNEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETNE {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETNEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETB x) mem)
+	// cond: y.Uses == 1
+	// result: (SETBmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETB {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETBE x) mem)
+	// cond: y.Uses == 1
+	// result: (SETBEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETBE {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETBEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETA x) mem)
+	// cond: y.Uses == 1
+	// result: (SETAmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETA {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETAmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [off] {sym} ptr y:(SETAE x) mem)
+	// cond: y.Uses == 1
+	// result: (SETAEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		y := v.Args[1]
+		if y.Op != OpAMD64SETAE {
+			break
+		}
+		x := y.Args[0]
+		mem := v.Args[2]
+		if !(y.Uses == 1) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64MOVBstore_10(v *Value) bool {
 	b := v.Block
 	_ = b
 	// match: (MOVBstore [off] {sym} ptr (MOVBQSX x) mem)
@@ -5343,7 +5992,11 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64MOVBstore_10(v *Value) bool {
+func rewriteValueAMD64_OpAMD64MOVBstore_20(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (MOVBstore [i] {s} p (SHRQconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
 	// cond: x.Uses == 1   && clobber(x)
 	// result: (MOVWstore [i-1] {s} p w mem)
@@ -5439,8 +6092,75 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) mem2:(MOVBstore [i-1] {s} p x2:(MOVBload [j-1] {s2} p2 mem) mem))
+	// cond: x1.Uses == 1   && x2.Uses == 1   && mem2.Uses == 1   && clobber(x1)   && clobber(x2)   && clobber(mem2)
+	// result: (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
+	for {
+		i := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		x1 := v.Args[1]
+		if x1.Op != OpAMD64MOVBload {
+			break
+		}
+		j := x1.AuxInt
+		s2 := x1.Aux
+		_ = x1.Args[1]
+		p2 := x1.Args[0]
+		mem := x1.Args[1]
+		mem2 := v.Args[2]
+		if mem2.Op != OpAMD64MOVBstore {
+			break
+		}
+		if mem2.AuxInt != i-1 {
+			break
+		}
+		if mem2.Aux != s {
+			break
+		}
+		_ = mem2.Args[2]
+		if p != mem2.Args[0] {
+			break
+		}
+		x2 := mem2.Args[1]
+		if x2.Op != OpAMD64MOVBload {
+			break
+		}
+		if x2.AuxInt != j-1 {
+			break
+		}
+		if x2.Aux != s2 {
+			break
+		}
+		_ = x2.Args[1]
+		if p2 != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if mem != mem2.Args[2] {
+			break
+		}
+		if !(x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1) && clobber(x2) && clobber(mem2)) {
+			break
+		}
+		v.reset(OpAMD64MOVWstore)
+		v.AuxInt = i - 1
+		v.Aux = s
+		v.AddArg(p)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVWload, typ.UInt16)
+		v0.AuxInt = j - 1
+		v0.Aux = s2
+		v0.AddArg(p2)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVBstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 	for {
 		off1 := v.AuxInt
@@ -5455,7 +6175,7 @@
 		base := v_0.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVBstore)
@@ -5679,7 +6399,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVBstoreconstidx1_0(v *Value) bool {
 	// match: (MOVBstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVBstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -5693,6 +6413,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVBstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -5702,7 +6425,7 @@
 		return true
 	}
 	// match: (MOVBstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVBstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -5716,6 +6439,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVBstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -5766,7 +6492,7 @@
 	b := v.Block
 	_ = b
 	// match: (MOVBstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -5781,6 +6507,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -5791,7 +6520,7 @@
 		return true
 	}
 	// match: (MOVBstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVBstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -5806,6 +6535,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVBstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -6368,42 +7100,42 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQSX x:(MOVLQSX _))
+	// match: (MOVLQSX (MOVLQSX x))
 	// cond:
-	// result: x
+	// result: (MOVLQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVLQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVLQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVLQSX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQSX x:(MOVWQSX _))
+	// match: (MOVLQSX (MOVWQSX x))
 	// cond:
-	// result: x
+	// result: (MOVWQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVWQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVWQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVWQSX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQSX x:(MOVBQSX _))
+	// match: (MOVLQSX (MOVBQSX x))
 	// cond:
-	// result: x
+	// result: (MOVBQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQSX)
 		v.AddArg(x)
 		return true
 	}
@@ -6516,6 +7248,19 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVLQZX x)
+	// cond: zeroUpper32Bits(x,3)
+	// result: x
+	for {
+		x := v.Args[0]
+		if !(zeroUpper32Bits(x, 3)) {
+			break
+		}
+		v.reset(OpCopy)
+		v.Type = x.Type
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVLQZX x:(MOVLloadidx1 [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVLloadidx1 <v.Type> [off] {sym} ptr idx mem)
@@ -6587,42 +7332,42 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQZX x:(MOVLQZX _))
+	// match: (MOVLQZX (MOVLQZX x))
 	// cond:
-	// result: x
+	// result: (MOVLQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVLQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVLQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVLQZX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQZX x:(MOVWQZX _))
+	// match: (MOVLQZX (MOVWQZX x))
 	// cond:
-	// result: x
+	// result: (MOVWQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVWQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVWQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVWQZX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVLQZX x:(MOVBQZX _))
+	// match: (MOVLQZX (MOVBQZX x))
 	// cond:
-	// result: x
+	// result: (MOVBQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQZX)
 		v.AddArg(x)
 		return true
 	}
@@ -6680,6 +7425,54 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MOVLf2i_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MOVLf2i <t> (Arg [off] {sym}))
+	// cond:
+	// result: @b.Func.Entry (Arg <t> [off] {sym})
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpArg {
+			break
+		}
+		off := v_0.AuxInt
+		sym := v_0.Aux
+		b = b.Func.Entry
+		v0 := b.NewValue0(v.Pos, OpArg, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64MOVLi2f_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MOVLi2f <t> (Arg [off] {sym}))
+	// cond:
+	// result: @b.Func.Entry (Arg <t> [off] {sym})
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpArg {
+			break
+		}
+		off := v_0.AuxInt
+		sym := v_0.Aux
+		b = b.Func.Entry
+		v0 := b.NewValue0(v.Pos, OpArg, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64MOVLload_0(v *Value) bool {
 	// match: (MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _))
 	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
@@ -6810,6 +7603,34 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVLload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem)
+	// cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
+	// result: (MOVLloadidx8 [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64LEAQ8 {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
+			break
+		}
+		v.reset(OpAMD64MOVLloadidx8)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVLload [off] {sym} (ADDQ ptr idx) mem)
 	// cond: ptr.Op != OpSB
 	// result: (MOVLloadidx1 [off] {sym} ptr idx mem)
@@ -6837,7 +7658,7 @@
 		return true
 	}
 	// match: (MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVLload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
 	for {
 		off1 := v.AuxInt
@@ -6851,7 +7672,7 @@
 		sym2 := v_0.Aux
 		base := v_0.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVLload)
@@ -6885,6 +7706,33 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVLload [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _))
+	// cond:
+	// result: (MOVLf2i val)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		val := v_1.Args[1]
+		v.reset(OpAMD64MOVLf2i)
+		v.AddArg(val)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVLloadidx1_0(v *Value) bool {
@@ -6938,8 +7786,58 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVLloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
+	// match: (MOVLloadidx1 [c] {sym} ptr (SHLQconst [3] idx) mem)
 	// cond:
+	// result: (MOVLloadidx8 [c] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64SHLQconst {
+			break
+		}
+		if v_1.AuxInt != 3 {
+			break
+		}
+		idx := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVLloadidx8)
+		v.AuxInt = c
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLloadidx1 [c] {sym} (SHLQconst [3] idx) ptr mem)
+	// cond:
+	// result: (MOVLloadidx8 [c] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64SHLQconst {
+			break
+		}
+		if v_0.AuxInt != 3 {
+			break
+		}
+		idx := v_0.Args[0]
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVLloadidx8)
+		v.AuxInt = c
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
+	// cond: is32Bit(c+d)
 	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -6953,6 +7851,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -6962,7 +7863,7 @@
 		return true
 	}
 	// match: (MOVLloadidx1 [c] {sym} idx (ADDQconst [d] ptr) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -6976,6 +7877,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -6985,7 +7889,7 @@
 		return true
 	}
 	// match: (MOVLloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -6999,6 +7903,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -7008,7 +7915,7 @@
 		return true
 	}
 	// match: (MOVLloadidx1 [c] {sym} (ADDQconst [d] idx) ptr mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -7022,6 +7929,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -7034,7 +7944,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVLloadidx4_0(v *Value) bool {
 	// match: (MOVLloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLloadidx4 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -7048,6 +7958,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx4)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -7057,7 +7970,7 @@
 		return true
 	}
 	// match: (MOVLloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+4*d)
 	// result: (MOVLloadidx4 [c+4*d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -7071,6 +7984,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + 4*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLloadidx4)
 		v.AuxInt = c + 4*d
 		v.Aux = sym
@@ -7081,6 +7997,61 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MOVLloadidx8_0(v *Value) bool {
+	// match: (MOVLloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem)
+	// cond: is32Bit(c+d)
+	// result: (MOVLloadidx8 [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64ADDQconst {
+			break
+		}
+		d := v_0.AuxInt
+		ptr := v_0.Args[0]
+		idx := v.Args[1]
+		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
+		v.reset(OpAMD64MOVLloadidx8)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem)
+	// cond: is32Bit(c+8*d)
+	// result: (MOVLloadidx8 [c+8*d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64ADDQconst {
+			break
+		}
+		d := v_1.AuxInt
+		idx := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
+		v.reset(OpAMD64MOVLloadidx8)
+		v.AuxInt = c + 8*d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64MOVLstore_0(v *Value) bool {
 	// match: (MOVLstore [off] {sym} ptr (MOVLQSX x) mem)
 	// cond:
@@ -7263,6 +8234,36 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVLstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem)
+	// cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
+	// result: (MOVLstoreidx8 [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64LEAQ8 {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		val := v.Args[1]
+		mem := v.Args[2]
+		if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
+			break
+		}
+		v.reset(OpAMD64MOVLstoreidx8)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVLstore [off] {sym} (ADDQ ptr idx) val mem)
 	// cond: ptr.Op != OpSB
 	// result: (MOVLstoreidx1 [off] {sym} ptr idx val mem)
@@ -7336,6 +8337,13 @@
 		v.AddArg(mem)
 		return true
 	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64MOVLstore_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem))
 	// cond: x.Uses == 1   && clobber(x)
 	// result: (MOVQstore [i-4] {s} p w0 mem)
@@ -7386,11 +8394,75 @@
 		v.AddArg(mem)
 		return true
 	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64MOVLstore_10(v *Value) bool {
+	// match: (MOVLstore [i] {s} p x1:(MOVLload [j] {s2} p2 mem) mem2:(MOVLstore [i-4] {s} p x2:(MOVLload [j-4] {s2} p2 mem) mem))
+	// cond: x1.Uses == 1   && x2.Uses == 1   && mem2.Uses == 1   && clobber(x1)   && clobber(x2)   && clobber(mem2)
+	// result: (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem)
+	for {
+		i := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		x1 := v.Args[1]
+		if x1.Op != OpAMD64MOVLload {
+			break
+		}
+		j := x1.AuxInt
+		s2 := x1.Aux
+		_ = x1.Args[1]
+		p2 := x1.Args[0]
+		mem := x1.Args[1]
+		mem2 := v.Args[2]
+		if mem2.Op != OpAMD64MOVLstore {
+			break
+		}
+		if mem2.AuxInt != i-4 {
+			break
+		}
+		if mem2.Aux != s {
+			break
+		}
+		_ = mem2.Args[2]
+		if p != mem2.Args[0] {
+			break
+		}
+		x2 := mem2.Args[1]
+		if x2.Op != OpAMD64MOVLload {
+			break
+		}
+		if x2.AuxInt != j-4 {
+			break
+		}
+		if x2.Aux != s2 {
+			break
+		}
+		_ = x2.Args[1]
+		if p2 != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if mem != mem2.Args[2] {
+			break
+		}
+		if !(x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1) && clobber(x2) && clobber(mem2)) {
+			break
+		}
+		v.reset(OpAMD64MOVQstore)
+		v.AuxInt = i - 4
+		v.Aux = s
+		v.AddArg(p)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
+		v0.AuxInt = j - 4
+		v0.Aux = s2
+		v0.AddArg(p2)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVLstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 	for {
 		off1 := v.AuxInt
@@ -7405,7 +8477,7 @@
 		base := v_0.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVLstore)
@@ -7442,6 +8514,67 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVLstore [off] {sym} ptr a:(ADDLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off)
+	// result: (ADDLconstmem {sym} [makeValAndOff(c,off)] ptr mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		a := v.Args[1]
+		if a.Op != OpAMD64ADDLconst {
+			break
+		}
+		c := a.AuxInt
+		l := a.Args[0]
+		if l.Op != OpAMD64MOVLload {
+			break
+		}
+		if l.AuxInt != off {
+			break
+		}
+		if l.Aux != sym {
+			break
+		}
+		_ = l.Args[1]
+		ptr2 := l.Args[0]
+		mem := l.Args[1]
+		if mem != v.Args[2] {
+			break
+		}
+		if !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off)) {
+			break
+		}
+		v.reset(OpAMD64ADDLconstmem)
+		v.AuxInt = makeValAndOff(c, off)
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLstore [off] {sym} ptr (MOVLf2i val) mem)
+	// cond:
+	// result: (MOVSSstore [off] {sym} ptr val mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVLf2i {
+			break
+		}
+		val := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVSSstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVLstoreconst_0(v *Value) bool {
@@ -7693,7 +8826,7 @@
 		return true
 	}
 	// match: (MOVLstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVLstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -7707,6 +8840,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -7716,7 +8852,7 @@
 		return true
 	}
 	// match: (MOVLstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVLstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -7730,6 +8866,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -7785,7 +8924,7 @@
 	typ := &b.Func.Config.Types
 	_ = typ
 	// match: (MOVLstoreconstidx4 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVLstoreconstidx4 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -7799,6 +8938,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreconstidx4)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -7808,7 +8950,7 @@
 		return true
 	}
 	// match: (MOVLstoreconstidx4 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(4*c)
 	// result: (MOVLstoreconstidx4 [ValAndOff(x).add(4*c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -7822,6 +8964,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(4 * c)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreconstidx4)
 		v.AuxInt = ValAndOff(x).add(4 * c)
 		v.Aux = sym
@@ -7902,8 +9047,35 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVLstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
+	// match: (MOVLstoreidx1 [c] {sym} ptr (SHLQconst [3] idx) val mem)
 	// cond:
+	// result: (MOVLstoreidx8 [c] {sym} ptr idx val mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64SHLQconst {
+			break
+		}
+		if v_1.AuxInt != 3 {
+			break
+		}
+		idx := v_1.Args[0]
+		val := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpAMD64MOVLstoreidx8)
+		v.AuxInt = c
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
+	// cond: is32Bit(c+d)
 	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -7918,6 +9090,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -7928,7 +9103,7 @@
 		return true
 	}
 	// match: (MOVLstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -7943,6 +9118,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8063,7 +9241,7 @@
 	b := v.Block
 	_ = b
 	// match: (MOVLstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVLstoreidx4 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8078,6 +9256,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreidx4)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8088,7 +9269,7 @@
 		return true
 	}
 	// match: (MOVLstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+4*d)
 	// result: (MOVLstoreidx4 [c+4*d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8103,6 +9284,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + 4*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVLstoreidx4)
 		v.AuxInt = c + 4*d
 		v.Aux = sym
@@ -8225,6 +9409,65 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MOVLstoreidx8_0(v *Value) bool {
+	// match: (MOVLstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem)
+	// cond: is32Bit(c+d)
+	// result: (MOVLstoreidx8 [c+d] {sym} ptr idx val mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[3]
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64ADDQconst {
+			break
+		}
+		d := v_0.AuxInt
+		ptr := v_0.Args[0]
+		idx := v.Args[1]
+		val := v.Args[2]
+		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
+		v.reset(OpAMD64MOVLstoreidx8)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVLstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem)
+	// cond: is32Bit(c+8*d)
+	// result: (MOVLstoreidx8 [c+8*d] {sym} ptr idx val mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64ADDQconst {
+			break
+		}
+		d := v_1.AuxInt
+		idx := v_1.Args[0]
+		val := v.Args[2]
+		mem := v.Args[3]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
+		v.reset(OpAMD64MOVLstoreidx8)
+		v.AuxInt = c + 8*d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64MOVOload_0(v *Value) bool {
 	// match: (MOVOload [off1] {sym} (ADDQconst [off2] ptr) mem)
 	// cond: is32Bit(off1+off2)
@@ -8385,6 +9628,54 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MOVQf2i_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MOVQf2i <t> (Arg [off] {sym}))
+	// cond:
+	// result: @b.Func.Entry (Arg <t> [off] {sym})
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpArg {
+			break
+		}
+		off := v_0.AuxInt
+		sym := v_0.Aux
+		b = b.Func.Entry
+		v0 := b.NewValue0(v.Pos, OpArg, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64MOVQi2f_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MOVQi2f <t> (Arg [off] {sym}))
+	// cond:
+	// result: @b.Func.Entry (Arg <t> [off] {sym})
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpArg {
+			break
+		}
+		off := v_0.AuxInt
+		sym := v_0.Aux
+		b = b.Func.Entry
+		v0 := b.NewValue0(v.Pos, OpArg, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64MOVQload_0(v *Value) bool {
 	// match: (MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _))
 	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
@@ -8543,7 +9834,7 @@
 		return true
 	}
 	// match: (MOVQload [off1] {sym1} (LEAL [off2] {sym2} base) mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVQload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
 	for {
 		off1 := v.AuxInt
@@ -8557,7 +9848,7 @@
 		sym2 := v_0.Aux
 		base := v_0.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVQload)
@@ -8591,6 +9882,33 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVQload [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _))
+	// cond:
+	// result: (MOVQf2i val)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		val := v_1.Args[1]
+		v.reset(OpAMD64MOVQf2i)
+		v.AddArg(val)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVQloadidx1_0(v *Value) bool {
@@ -8645,7 +9963,7 @@
 		return true
 	}
 	// match: (MOVQloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8659,6 +9977,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8668,7 +9989,7 @@
 		return true
 	}
 	// match: (MOVQloadidx1 [c] {sym} idx (ADDQconst [d] ptr) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8682,6 +10003,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8691,7 +10015,7 @@
 		return true
 	}
 	// match: (MOVQloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8705,6 +10029,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8714,7 +10041,7 @@
 		return true
 	}
 	// match: (MOVQloadidx1 [c] {sym} (ADDQconst [d] idx) ptr mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8728,6 +10055,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8740,7 +10070,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVQloadidx8_0(v *Value) bool {
 	// match: (MOVQloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQloadidx8 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8754,6 +10084,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx8)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8763,7 +10096,7 @@
 		return true
 	}
 	// match: (MOVQloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+8*d)
 	// result: (MOVQloadidx8 [c+8*d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8777,6 +10110,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQloadidx8)
 		v.AuxInt = c + 8*d
 		v.Aux = sym
@@ -8954,7 +10290,7 @@
 		return true
 	}
 	// match: (MOVQstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVQstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 	for {
 		off1 := v.AuxInt
@@ -8969,7 +10305,7 @@
 		base := v_0.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
@@ -9006,9 +10342,74 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVQstore [off] {sym} ptr a:(ADDQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off)
+	// result: (ADDQconstmem {sym} [makeValAndOff(c,off)] ptr mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		a := v.Args[1]
+		if a.Op != OpAMD64ADDQconst {
+			break
+		}
+		c := a.AuxInt
+		l := a.Args[0]
+		if l.Op != OpAMD64MOVQload {
+			break
+		}
+		if l.AuxInt != off {
+			break
+		}
+		if l.Aux != sym {
+			break
+		}
+		_ = l.Args[1]
+		ptr2 := l.Args[0]
+		mem := l.Args[1]
+		if mem != v.Args[2] {
+			break
+		}
+		if !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off)) {
+			break
+		}
+		v.reset(OpAMD64ADDQconstmem)
+		v.AuxInt = makeValAndOff(c, off)
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVQstore [off] {sym} ptr (MOVQf2i val) mem)
+	// cond:
+	// result: (MOVSDstore [off] {sym} ptr val mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVQf2i {
+			break
+		}
+		val := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVSDstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVQstoreconst_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVQstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
 	// cond: ValAndOff(sc).canAdd(off)
 	// result: (MOVQstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
@@ -9137,6 +10538,40 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem))
+	// cond: config.useSSE   && x.Uses == 1   && ValAndOff(c2).Off() + 8 == ValAndOff(c).Off()   && ValAndOff(c).Val() == 0   && ValAndOff(c2).Val() == 0   && clobber(x)
+	// result: (MOVOstore [ValAndOff(c2).Off()] {s} p (MOVOconst [0]) mem)
+	for {
+		c := v.AuxInt
+		s := v.Aux
+		_ = v.Args[1]
+		p := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64MOVQstoreconst {
+			break
+		}
+		c2 := x.AuxInt
+		if x.Aux != s {
+			break
+		}
+		_ = x.Args[1]
+		if p != x.Args[0] {
+			break
+		}
+		mem := x.Args[1]
+		if !(config.useSSE && x.Uses == 1 && ValAndOff(c2).Off()+8 == ValAndOff(c).Off() && ValAndOff(c).Val() == 0 && ValAndOff(c2).Val() == 0 && clobber(x)) {
+			break
+		}
+		v.reset(OpAMD64MOVOstore)
+		v.AuxInt = ValAndOff(c2).Off()
+		v.Aux = s
+		v.AddArg(p)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem)
 	// cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)
 	// result: (MOVQstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
@@ -9215,7 +10650,7 @@
 		return true
 	}
 	// match: (MOVQstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVQstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -9229,6 +10664,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -9238,7 +10676,7 @@
 		return true
 	}
 	// match: (MOVQstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVQstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -9252,6 +10690,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -9264,7 +10705,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVQstoreconstidx8_0(v *Value) bool {
 	// match: (MOVQstoreconstidx8 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVQstoreconstidx8 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -9278,6 +10719,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconstidx8)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -9287,7 +10731,7 @@
 		return true
 	}
 	// match: (MOVQstoreconstidx8 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(8*c)
 	// result: (MOVQstoreconstidx8 [ValAndOff(x).add(8*c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -9301,6 +10745,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(8 * c)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconstidx8)
 		v.AuxInt = ValAndOff(x).add(8 * c)
 		v.Aux = sym
@@ -9340,7 +10787,7 @@
 		return true
 	}
 	// match: (MOVQstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9355,6 +10802,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9365,7 +10815,7 @@
 		return true
 	}
 	// match: (MOVQstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9380,6 +10830,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9393,7 +10846,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVQstoreidx8_0(v *Value) bool {
 	// match: (MOVQstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVQstoreidx8 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9408,6 +10861,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreidx8)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9418,7 +10874,7 @@
 		return true
 	}
 	// match: (MOVQstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+8*d)
 	// result: (MOVQstoreidx8 [c+8*d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9433,6 +10889,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreidx8)
 		v.AuxInt = c + 8*d
 		v.Aux = sym
@@ -9576,6 +11035,33 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVSDload [off] {sym} ptr (MOVQstore [off] {sym} ptr val _))
+	// cond:
+	// result: (MOVQi2f val)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVQstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		val := v_1.Args[1]
+		v.reset(OpAMD64MOVQi2f)
+		v.AddArg(val)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVSDloadidx1_0(v *Value) bool {
@@ -9605,7 +11091,7 @@
 		return true
 	}
 	// match: (MOVSDloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -9619,6 +11105,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9628,7 +11117,7 @@
 		return true
 	}
 	// match: (MOVSDloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -9642,6 +11131,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9654,7 +11146,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVSDloadidx8_0(v *Value) bool {
 	// match: (MOVSDloadidx8 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDloadidx8 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -9668,6 +11160,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDloadidx8)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9677,7 +11172,7 @@
 		return true
 	}
 	// match: (MOVSDloadidx8 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+8*d)
 	// result: (MOVSDloadidx8 [c+8*d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -9691,6 +11186,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDloadidx8)
 		v.AuxInt = c + 8*d
 		v.Aux = sym
@@ -9843,6 +11341,28 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVSDstore [off] {sym} ptr (MOVQi2f val) mem)
+	// cond:
+	// result: (MOVQstore  [off] {sym} ptr val mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVQi2f {
+			break
+		}
+		val := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVQstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVSDstoreidx1_0(v *Value) bool {
@@ -9874,7 +11394,7 @@
 		return true
 	}
 	// match: (MOVSDstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9889,6 +11409,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9899,7 +11422,7 @@
 		return true
 	}
 	// match: (MOVSDstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9914,6 +11437,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9927,7 +11453,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVSDstoreidx8_0(v *Value) bool {
 	// match: (MOVSDstoreidx8 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSDstoreidx8 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9942,6 +11468,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDstoreidx8)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9952,7 +11481,7 @@
 		return true
 	}
 	// match: (MOVSDstoreidx8 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+8*d)
 	// result: (MOVSDstoreidx8 [c+8*d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -9967,6 +11496,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + 8*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSDstoreidx8)
 		v.AuxInt = c + 8*d
 		v.Aux = sym
@@ -10110,6 +11642,33 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVSSload [off] {sym} ptr (MOVLstore [off] {sym} ptr val _))
+	// cond:
+	// result: (MOVLi2f val)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVLstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		val := v_1.Args[1]
+		v.reset(OpAMD64MOVLi2f)
+		v.AddArg(val)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVSSloadidx1_0(v *Value) bool {
@@ -10139,7 +11698,7 @@
 		return true
 	}
 	// match: (MOVSSloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -10153,6 +11712,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10162,7 +11724,7 @@
 		return true
 	}
 	// match: (MOVSSloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -10176,6 +11738,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10188,7 +11753,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVSSloadidx4_0(v *Value) bool {
 	// match: (MOVSSloadidx4 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSloadidx4 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -10202,6 +11767,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSloadidx4)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10211,7 +11779,7 @@
 		return true
 	}
 	// match: (MOVSSloadidx4 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+4*d)
 	// result: (MOVSSloadidx4 [c+4*d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -10225,6 +11793,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + 4*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSloadidx4)
 		v.AuxInt = c + 4*d
 		v.Aux = sym
@@ -10377,6 +11948,28 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVSSstore [off] {sym} ptr (MOVLi2f val) mem)
+	// cond:
+	// result: (MOVLstore  [off] {sym} ptr val mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64MOVLi2f {
+			break
+		}
+		val := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVLstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVSSstoreidx1_0(v *Value) bool {
@@ -10408,7 +12001,7 @@
 		return true
 	}
 	// match: (MOVSSstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -10423,6 +12016,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10433,7 +12029,7 @@
 		return true
 	}
 	// match: (MOVSSstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -10448,6 +12044,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10461,7 +12060,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVSSstoreidx4_0(v *Value) bool {
 	// match: (MOVSSstoreidx4 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVSSstoreidx4 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -10476,6 +12075,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSstoreidx4)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10486,7 +12088,7 @@
 		return true
 	}
 	// match: (MOVSSstoreidx4 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+4*d)
 	// result: (MOVSSstoreidx4 [c+4*d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -10501,6 +12103,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + 4*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVSSstoreidx4)
 		v.AuxInt = c + 4*d
 		v.Aux = sym
@@ -10611,29 +12216,29 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVWQSX x:(MOVWQSX _))
+	// match: (MOVWQSX (MOVWQSX x))
 	// cond:
-	// result: x
+	// result: (MOVWQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVWQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVWQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVWQSX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVWQSX x:(MOVBQSX _))
+	// match: (MOVWQSX (MOVBQSX x))
 	// cond:
-	// result: x
+	// result: (MOVBQSX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQSX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQSX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQSX)
 		v.AddArg(x)
 		return true
 	}
@@ -10843,29 +12448,29 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVWQZX x:(MOVWQZX _))
+	// match: (MOVWQZX (MOVWQZX x))
 	// cond:
-	// result: x
+	// result: (MOVWQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVWQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVWQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVWQZX)
 		v.AddArg(x)
 		return true
 	}
-	// match: (MOVWQZX x:(MOVBQZX _))
+	// match: (MOVWQZX (MOVBQZX x))
 	// cond:
-	// result: x
+	// result: (MOVBQZX x)
 	for {
-		x := v.Args[0]
-		if x.Op != OpAMD64MOVBQZX {
+		v_0 := v.Args[0]
+		if v_0.Op != OpAMD64MOVBQZX {
 			break
 		}
-		v.reset(OpCopy)
-		v.Type = x.Type
+		x := v_0.Args[0]
+		v.reset(OpAMD64MOVBQZX)
 		v.AddArg(x)
 		return true
 	}
@@ -11028,7 +12633,7 @@
 		return true
 	}
 	// match: (MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVWload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
 	for {
 		off1 := v.AuxInt
@@ -11042,7 +12647,7 @@
 		sym2 := v_0.Aux
 		base := v_0.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVWload)
@@ -11130,7 +12735,7 @@
 		return true
 	}
 	// match: (MOVWloadidx1 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11144,6 +12749,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -11153,7 +12761,7 @@
 		return true
 	}
 	// match: (MOVWloadidx1 [c] {sym} idx (ADDQconst [d] ptr) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11167,6 +12775,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -11176,7 +12787,7 @@
 		return true
 	}
 	// match: (MOVWloadidx1 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11190,6 +12801,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -11199,7 +12813,7 @@
 		return true
 	}
 	// match: (MOVWloadidx1 [c] {sym} (ADDQconst [d] idx) ptr mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWloadidx1 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11213,6 +12827,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -11225,7 +12842,7 @@
 }
 func rewriteValueAMD64_OpAMD64MOVWloadidx2_0(v *Value) bool {
 	// match: (MOVWloadidx2 [c] {sym} (ADDQconst [d] ptr) idx mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWloadidx2 [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11239,6 +12856,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx2)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -11248,7 +12868,7 @@
 		return true
 	}
 	// match: (MOVWloadidx2 [c] {sym} ptr (ADDQconst [d] idx) mem)
-	// cond:
+	// cond: is32Bit(c+2*d)
 	// result: (MOVWloadidx2 [c+2*d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -11262,6 +12882,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is32Bit(c + 2*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWloadidx2)
 		v.AuxInt = c + 2*d
 		v.Aux = sym
@@ -11580,8 +13203,79 @@
 	return false
 }
 func rewriteValueAMD64_OpAMD64MOVWstore_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (MOVWstore [i] {s} p x1:(MOVWload [j] {s2} p2 mem) mem2:(MOVWstore [i-2] {s} p x2:(MOVWload [j-2] {s2} p2 mem) mem))
+	// cond: x1.Uses == 1   && x2.Uses == 1   && mem2.Uses == 1   && clobber(x1)   && clobber(x2)   && clobber(mem2)
+	// result: (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem)
+	for {
+		i := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		x1 := v.Args[1]
+		if x1.Op != OpAMD64MOVWload {
+			break
+		}
+		j := x1.AuxInt
+		s2 := x1.Aux
+		_ = x1.Args[1]
+		p2 := x1.Args[0]
+		mem := x1.Args[1]
+		mem2 := v.Args[2]
+		if mem2.Op != OpAMD64MOVWstore {
+			break
+		}
+		if mem2.AuxInt != i-2 {
+			break
+		}
+		if mem2.Aux != s {
+			break
+		}
+		_ = mem2.Args[2]
+		if p != mem2.Args[0] {
+			break
+		}
+		x2 := mem2.Args[1]
+		if x2.Op != OpAMD64MOVWload {
+			break
+		}
+		if x2.AuxInt != j-2 {
+			break
+		}
+		if x2.Aux != s2 {
+			break
+		}
+		_ = x2.Args[1]
+		if p2 != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if mem != mem2.Args[2] {
+			break
+		}
+		if !(x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1) && clobber(x2) && clobber(mem2)) {
+			break
+		}
+		v.reset(OpAMD64MOVLstore)
+		v.AuxInt = i - 2
+		v.Aux = s
+		v.AddArg(p)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLload, typ.UInt32)
+		v0.AuxInt = j - 2
+		v0.Aux = s2
+		v0.AddArg(p2)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
-	// cond: canMergeSym(sym1, sym2)
+	// cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2)
 	// result: (MOVWstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 	for {
 		off1 := v.AuxInt
@@ -11596,7 +13290,7 @@
 		base := v_0.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
 			break
 		}
 		v.reset(OpAMD64MOVWstore)
@@ -11873,7 +13567,7 @@
 		return true
 	}
 	// match: (MOVWstoreconstidx1 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVWstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -11887,6 +13581,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -11896,7 +13593,7 @@
 		return true
 	}
 	// match: (MOVWstoreconstidx1 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVWstoreconstidx1 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -11910,6 +13607,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreconstidx1)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -11960,7 +13660,7 @@
 	b := v.Block
 	_ = b
 	// match: (MOVWstoreconstidx2 [x] {sym} (ADDQconst [c] ptr) idx mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(c)
 	// result: (MOVWstoreconstidx2 [ValAndOff(x).add(c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -11974,6 +13674,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(c)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreconstidx2)
 		v.AuxInt = ValAndOff(x).add(c)
 		v.Aux = sym
@@ -11983,7 +13686,7 @@
 		return true
 	}
 	// match: (MOVWstoreconstidx2 [x] {sym} ptr (ADDQconst [c] idx) mem)
-	// cond:
+	// cond: ValAndOff(x).canAdd(2*c)
 	// result: (MOVWstoreconstidx2 [ValAndOff(x).add(2*c)] {sym} ptr idx mem)
 	for {
 		x := v.AuxInt
@@ -11997,6 +13700,9 @@
 		c := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(ValAndOff(x).canAdd(2 * c)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreconstidx2)
 		v.AuxInt = ValAndOff(x).add(2 * c)
 		v.Aux = sym
@@ -12075,7 +13781,7 @@
 		return true
 	}
 	// match: (MOVWstoreidx1 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -12090,6 +13796,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12100,7 +13809,7 @@
 		return true
 	}
 	// match: (MOVWstoreidx1 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWstoreidx1 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -12115,6 +13824,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreidx1)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12235,7 +13947,7 @@
 	b := v.Block
 	_ = b
 	// match: (MOVWstoreidx2 [c] {sym} (ADDQconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is32Bit(c+d)
 	// result: (MOVWstoreidx2 [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -12250,6 +13962,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreidx2)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12260,7 +13975,7 @@
 		return true
 	}
 	// match: (MOVWstoreidx2 [c] {sym} ptr (ADDQconst [d] idx) val mem)
-	// cond:
+	// cond: is32Bit(c+2*d)
 	// result: (MOVWstoreidx2 [c+2*d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -12275,6 +13990,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is32Bit(c + 2*d)) {
+			break
+		}
 		v.reset(OpAMD64MOVWstoreidx2)
 		v.AuxInt = c + 2*d
 		v.Aux = sym
@@ -12736,20 +14454,6 @@
 		return true
 	}
 	// match: (MULQconst [c] x)
-	// cond: isPowerOfTwo(c)
-	// result: (SHLQconst [log2(c)] x)
-	for {
-		c := v.AuxInt
-		x := v.Args[0]
-		if !(isPowerOfTwo(c)) {
-			break
-		}
-		v.reset(OpAMD64SHLQconst)
-		v.AuxInt = log2(c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (MULQconst [c] x)
 	// cond: isPowerOfTwo(c+1) && c >= 15
 	// result: (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
 	for {
@@ -12817,11 +14521,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (MULQconst [c] x)
 	// cond: isPowerOfTwo(c-8) && c >= 136
 	// result: (LEAQ8 (SHLQconst <v.Type> [log2(c-8)] x) x)
@@ -12839,6 +14538,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (MULQconst [c] x)
 	// cond: c%3 == 0 && isPowerOfTwo(c/3)
 	// result: (SHLQconst [log2(c/3)] (LEAQ2 <v.Type> x x))
@@ -12961,6 +14665,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MULSDmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (MULSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _))
+	// cond:
+	// result: (MULSD x (MOVQi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVQstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64MULSD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQi2f, typ.Float64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64MULSS_0(v *Value) bool {
 	// match: (MULSS x l:(MOVSSload [off] {sym} ptr mem))
 	// cond: canMergeLoad(v, l, x) && clobber(l)
@@ -13016,6 +14758,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64MULSSmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (MULSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _))
+	// cond:
+	// result: (MULSS x (MOVLi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVLstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64MULSS)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLi2f, typ.Float32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64NEGL_0(v *Value) bool {
 	// match: (NEGL (MOVLconst [c]))
 	// cond:
@@ -21617,6 +23397,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ORLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ORLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _))
+	// cond:
+	// result: ( ORL x (MOVLf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ORL)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ORQ_0(v *Value) bool {
 	// match: (ORQ x (MOVQconst [c]))
 	// cond: is32Bit(c)
@@ -32321,6 +34139,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64ORQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (ORQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _))
+	// cond:
+	// result: ( ORQ x (MOVQf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64ORQ)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64ROLB_0(v *Value) bool {
 	// match: (ROLB x (NEGQ y))
 	// cond:
@@ -33036,7 +34892,7 @@
 	}
 	// match: (SARBconst [c] (MOVQconst [d]))
 	// cond:
-	// result: (MOVQconst [d>>uint64(c)])
+	// result: (MOVQconst [int64(int8(d))>>uint64(c)])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -33045,7 +34901,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVQconst)
-		v.AuxInt = d >> uint64(c)
+		v.AuxInt = int64(int8(d)) >> uint64(c)
 		return true
 	}
 	return false
@@ -33291,7 +35147,7 @@
 	}
 	// match: (SARLconst [c] (MOVQconst [d]))
 	// cond:
-	// result: (MOVQconst [d>>uint64(c)])
+	// result: (MOVQconst [int64(int32(d))>>uint64(c)])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -33300,7 +35156,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVQconst)
-		v.AuxInt = d >> uint64(c)
+		v.AuxInt = int64(int32(d)) >> uint64(c)
 		return true
 	}
 	return false
@@ -33611,7 +35467,7 @@
 	}
 	// match: (SARWconst [c] (MOVQconst [d]))
 	// cond:
-	// result: (MOVQconst [d>>uint64(c)])
+	// result: (MOVQconst [int64(int16(d))>>uint64(c)])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -33620,7 +35476,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVQconst)
-		v.AuxInt = d >> uint64(c)
+		v.AuxInt = int64(int16(d)) >> uint64(c)
 		return true
 	}
 	return false
@@ -33903,6 +35759,290 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETAEmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETAEmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETBEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETBEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAEmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAEmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAEmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAEmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAEmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETAmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETAmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETBmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETAmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SETB_0(v *Value) bool {
 	// match: (SETB (InvertFlags x))
 	// cond:
@@ -34055,6 +36195,290 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETBEmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETBEmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETAEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBEmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBEmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBEmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBEmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBEmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETBmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETBmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETAmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETAmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETBmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SETEQ_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -34360,6 +36784,449 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETEQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (SETEQmem [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
+	// cond: !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTL x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTL {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64SHLL {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpAMD64MOVLconst {
+			break
+		}
+		if v_1_0_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_0.Args[1]
+		y := v_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTL y (SHLL (MOVLconst [1]) x)) mem)
+	// cond: !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTL x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64SHLL {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpAMD64MOVLconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
+	// cond: !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTQ x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64SHLQ {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		if v_1_0_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_0.Args[1]
+		y := v_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTQ y (SHLQ (MOVQconst [1]) x)) mem)
+	// cond: !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTQ x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64SHLQ {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTLconst [c] x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 32 && !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTLconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTLconst {
+			break
+		}
+		c := v_1.AuxInt
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 32 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTQconst [c] x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQconst {
+			break
+		}
+		c := v_1.AuxInt
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		c := v_1_0.AuxInt
+		x := v_1.Args[1]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (TESTQ x (MOVQconst [c])) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETAEmem [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64MOVQconst {
+			break
+		}
+		c := v_1_1.AuxInt
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETAEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETEQmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETEQmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETEQmem_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETEQmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETEQmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SETG_0(v *Value) bool {
 	// match: (SETG (InvertFlags x))
 	// cond:
@@ -34512,6 +37379,290 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETGEmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETGEmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETLEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETLEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGEmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGEmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGEmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGEmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGEmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETGmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETGmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETLmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETLmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETGmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SETL_0(v *Value) bool {
 	// match: (SETL (InvertFlags x))
 	// cond:
@@ -34664,6 +37815,290 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETLEmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETLEmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETGEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETGEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLEmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLEmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLEmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLEmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLEmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETLmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETGmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETGmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETLmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SETNE_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -34969,6 +38404,449 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SETNEmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (SETNEmem [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
+	// cond: !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTL x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTL {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64SHLL {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpAMD64MOVLconst {
+			break
+		}
+		if v_1_0_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_0.Args[1]
+		y := v_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTL y (SHLL (MOVLconst [1]) x)) mem)
+	// cond: !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTL x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64SHLL {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpAMD64MOVLconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
+	// cond: !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTQ x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64SHLQ {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		if v_1_0_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_0.Args[1]
+		y := v_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTQ y (SHLQ (MOVQconst [1]) x)) mem)
+	// cond: !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTQ x y) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64SHLQ {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 1 {
+			break
+		}
+		x := v_1_1.Args[1]
+		mem := v.Args[2]
+		if !(!config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTLconst [c] x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 32 && !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTLconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTLconst {
+			break
+		}
+		c := v_1.AuxInt
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 32 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTQconst [c] x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQconst {
+			break
+		}
+		c := v_1.AuxInt
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAMD64MOVQconst {
+			break
+		}
+		c := v_1_0.AuxInt
+		x := v_1.Args[1]
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (TESTQ x (MOVQconst [c])) mem)
+	// cond: isPowerOfTwo(c) && log2(c) < 64 && !config.nacl
+	// result: (SETBmem  [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64TESTQ {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpAMD64MOVQconst {
+			break
+		}
+		c := v_1_1.AuxInt
+		mem := v.Args[2]
+		if !(isPowerOfTwo(c) && log2(c) < 64 && !config.nacl) {
+			break
+		}
+		v.reset(OpAMD64SETBmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr (InvertFlags x) mem)
+	// cond:
+	// result: (SETNEmem [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpAMD64InvertFlags {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpAMD64SETNEmem)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr x:(FlagEQ) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [0]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagEQ {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpAMD64SETNEmem_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SETNEmem [off] {sym} ptr x:(FlagLT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr x:(FlagLT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagLT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr x:(FlagGT_ULT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_ULT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SETNEmem [off] {sym} ptr x:(FlagGT_UGT) mem)
+	// cond:
+	// result: (MOVBstore [off] {sym} ptr (MOVLconst <x.Type> [1]) mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		x := v.Args[1]
+		if x.Op != OpAMD64FlagGT_UGT {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpAMD64MOVBstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, x.Type)
+		v0.AuxInt = 1
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SHLL_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -36220,6 +40098,44 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpAMD64SUBLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (SUBLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _))
+	// cond:
+	// result: (SUBL x (MOVLf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64SUBL)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SUBQ_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -36367,6 +40283,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SUBQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (SUBQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _))
+	// cond:
+	// result: (SUBQ x (MOVQf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64SUBQ)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SUBSD_0(v *Value) bool {
 	// match: (SUBSD x l:(MOVSDload [off] {sym} ptr mem))
 	// cond: canMergeLoad(v, l, x) && clobber(l)
@@ -36396,6 +40350,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SUBSDmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (SUBSDmem x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _))
+	// cond:
+	// result: (SUBSD x (MOVQi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVQstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64SUBSD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQi2f, typ.Float64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64SUBSS_0(v *Value) bool {
 	// match: (SUBSS x l:(MOVSSload [off] {sym} ptr mem))
 	// cond: canMergeLoad(v, l, x) && clobber(l)
@@ -36425,6 +40417,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64SUBSSmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (SUBSSmem x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _))
+	// cond:
+	// result: (SUBSS x (MOVLi2f y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVLstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64SUBSS)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLi2f, typ.Float32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64TESTB_0(v *Value) bool {
 	// match: (TESTB (MOVLconst [c]) x)
 	// cond:
@@ -37220,6 +41250,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64XORLmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (XORLmem x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _))
+	// cond:
+	// result: (XORL x (MOVLf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSSstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64XORL)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVLf2i, typ.UInt32)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAMD64XORQ_0(v *Value) bool {
 	// match: (XORQ x (MOVQconst [c]))
 	// cond: is32Bit(c)
@@ -37426,6 +41494,44 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpAMD64XORQmem_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (XORQmem x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _))
+	// cond:
+	// result: (XORQ x (MOVQf2i y))
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpAMD64MOVSDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		if ptr != v_2.Args[0] {
+			break
+		}
+		y := v_2.Args[1]
+		v.reset(OpAMD64XORQ)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQf2i, typ.UInt64)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpAdd16_0(v *Value) bool {
 	// match: (Add16 x y)
 	// cond:
@@ -38038,6 +42144,18 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpCeil_0(v *Value) bool {
+	// match: (Ceil x)
+	// cond:
+	// result: (ROUNDSD [2] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpAMD64ROUNDSD)
+		v.AuxInt = 2
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueAMD64_OpClosureCall_0(v *Value) bool {
 	// match: (ClosureCall [argwid] entry closure mem)
 	// cond:
@@ -38786,6 +42904,18 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpFloor_0(v *Value) bool {
+	// match: (Floor x)
+	// cond:
+	// result: (ROUNDSD [1] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpAMD64ROUNDSD)
+		v.AuxInt = 1
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueAMD64_OpGeq16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -38966,6 +43096,24 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpGetCallerPC_0(v *Value) bool {
+	// match: (GetCallerPC)
+	// cond:
+	// result: (LoweredGetCallerPC)
+	for {
+		v.reset(OpAMD64LoweredGetCallerPC)
+		return true
+	}
+}
+func rewriteValueAMD64_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpAMD64LoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueAMD64_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -40403,6 +44551,8 @@
 func rewriteValueAMD64_OpMove_0(v *Value) bool {
 	b := v.Block
 	_ = b
+	config := b.Func.Config
+	_ = config
 	typ := &b.Func.Config.Types
 	_ = typ
 	// match: (Move [0] _ _ mem)
@@ -40500,7 +44650,7 @@
 		return true
 	}
 	// match: (Move [16] dst src mem)
-	// cond:
+	// cond: config.useSSE
 	// result: (MOVOstore dst (MOVOload src mem) mem)
 	for {
 		if v.AuxInt != 16 {
@@ -40510,6 +44660,9 @@
 		dst := v.Args[0]
 		src := v.Args[1]
 		mem := v.Args[2]
+		if !(config.useSSE) {
+			break
+		}
 		v.reset(OpAMD64MOVOstore)
 		v.AddArg(dst)
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVOload, types.TypeInt128)
@@ -40519,6 +44672,38 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (Move [16] dst src mem)
+	// cond: !config.useSSE
+	// result: (MOVQstore [8] dst (MOVQload [8] src mem) 		(MOVQstore dst (MOVQload src mem) mem))
+	for {
+		if v.AuxInt != 16 {
+			break
+		}
+		_ = v.Args[2]
+		dst := v.Args[0]
+		src := v.Args[1]
+		mem := v.Args[2]
+		if !(!config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVQstore)
+		v.AuxInt = 8
+		v.AddArg(dst)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
+		v0.AuxInt = 8
+		v0.AddArg(src)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstore, types.TypeMem)
+		v1.AddArg(dst)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
+		v2.AddArg(src)
+		v2.AddArg(mem)
+		v1.AddArg(v2)
+		v1.AddArg(mem)
+		v.AddArg(v1)
+		return true
+	}
 	// match: (Move [3] dst src mem)
 	// cond:
 	// result: (MOVBstore [2] dst (MOVBload [2] src mem) 		(MOVWstore dst (MOVWload src mem) mem))
@@ -40606,6 +44791,15 @@
 		v.AddArg(v1)
 		return true
 	}
+	return false
+}
+func rewriteValueAMD64_OpMove_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (Move [7] dst src mem)
 	// cond:
 	// result: (MOVLstore [3] dst (MOVLload [3] src mem) 		(MOVLstore dst (MOVLload src mem) mem))
@@ -40635,15 +44829,6 @@
 		v.AddArg(v1)
 		return true
 	}
-	return false
-}
-func rewriteValueAMD64_OpMove_10(v *Value) bool {
-	b := v.Block
-	_ = b
-	config := b.Func.Config
-	_ = config
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (Move [s] dst src mem)
 	// cond: s > 8 && s < 16
 	// result: (MOVQstore [s-8] dst (MOVQload [s-8] src mem) 		(MOVQstore dst (MOVQload src mem) mem))
@@ -40707,7 +44892,7 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 16 && s%16 != 0 && s%16 > 8
+	// cond: s > 16 && s%16 != 0 && s%16 > 8 && config.useSSE
 	// result: (Move [s-s%16] 		(OffPtr <dst.Type> dst [s%16]) 		(OffPtr <src.Type> src [s%16]) 		(MOVOstore dst (MOVOload src mem) mem))
 	for {
 		s := v.AuxInt
@@ -40715,7 +44900,7 @@
 		dst := v.Args[0]
 		src := v.Args[1]
 		mem := v.Args[2]
-		if !(s > 16 && s%16 != 0 && s%16 > 8) {
+		if !(s > 16 && s%16 != 0 && s%16 > 8 && config.useSSE) {
 			break
 		}
 		v.reset(OpMove)
@@ -40739,6 +44924,47 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
+	// cond: s > 16 && s%16 != 0 && s%16 > 8 && !config.useSSE
+	// result: (Move [s-s%16] 		(OffPtr <dst.Type> dst [s%16]) 		(OffPtr <src.Type> src [s%16]) 		(MOVQstore [8] dst (MOVQload [8] src mem) 			(MOVQstore dst (MOVQload src mem) mem)))
+	for {
+		s := v.AuxInt
+		_ = v.Args[2]
+		dst := v.Args[0]
+		src := v.Args[1]
+		mem := v.Args[2]
+		if !(s > 16 && s%16 != 0 && s%16 > 8 && !config.useSSE) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = s - s%16
+		v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
+		v0.AuxInt = s % 16
+		v0.AddArg(dst)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
+		v1.AuxInt = s % 16
+		v1.AddArg(src)
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVQstore, types.TypeMem)
+		v2.AuxInt = 8
+		v2.AddArg(dst)
+		v3 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
+		v3.AuxInt = 8
+		v3.AddArg(src)
+		v3.AddArg(mem)
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpAMD64MOVQstore, types.TypeMem)
+		v4.AddArg(dst)
+		v5 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
+		v5.AddArg(src)
+		v5.AddArg(mem)
+		v4.AddArg(v5)
+		v4.AddArg(mem)
+		v2.AddArg(v4)
+		v.AddArg(v2)
+		return true
+	}
+	// match: (Move [s] dst src mem)
 	// cond: s >= 32 && s <= 16*64 && s%16 == 0 	&& !config.noDuffDevice
 	// result: (DUFFCOPY [14*(64-s/16)] dst src mem)
 	for {
@@ -41354,6 +45580,18 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpRoundToEven_0(v *Value) bool {
+	// match: (RoundToEven x)
+	// cond:
+	// result: (ROUNDSD [0] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpAMD64ROUNDSD)
+		v.AuxInt = 0
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueAMD64_OpRsh16Ux16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -42617,6 +46855,18 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpTrunc_0(v *Value) bool {
+	// match: (Trunc x)
+	// cond:
+	// result: (ROUNDSD [3] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpAMD64ROUNDSD)
+		v.AuxInt = 3
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueAMD64_OpTrunc16to8_0(v *Value) bool {
 	// match: (Trunc16to8 x)
 	// cond:
@@ -42689,6 +46939,24 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpWB_0(v *Value) bool {
+	// match: (WB {fn} destptr srcptr mem)
+	// cond:
+	// result: (LoweredWB {fn} destptr srcptr mem)
+	for {
+		fn := v.Aux
+		_ = v.Args[2]
+		destptr := v.Args[0]
+		srcptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpAMD64LoweredWB)
+		v.Aux = fn
+		v.AddArg(destptr)
+		v.AddArg(srcptr)
+		v.AddArg(mem)
+		return true
+	}
+}
 func rewriteValueAMD64_OpXor16_0(v *Value) bool {
 	// match: (Xor16 x y)
 	// cond:
@@ -42748,6 +47016,8 @@
 func rewriteValueAMD64_OpZero_0(v *Value) bool {
 	b := v.Block
 	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (Zero [0] _ mem)
 	// cond:
 	// result: mem
@@ -42907,14 +47177,14 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: s%8 != 0 && s > 8
+	// cond: s%8 != 0 && s > 8 && !config.useSSE
 	// result: (Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8]) 		(MOVQstoreconst [0] destptr mem))
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s%8 != 0 && s > 8) {
+		if !(s%8 != 0 && s > 8 && !config.useSSE) {
 			break
 		}
 		v.reset(OpZero)
@@ -42937,10 +47207,8 @@
 	_ = b
 	config := b.Func.Config
 	_ = config
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (Zero [16] destptr mem)
-	// cond:
+	// cond: !config.useSSE
 	// result: (MOVQstoreconst [makeValAndOff(0,8)] destptr 		(MOVQstoreconst [0] destptr mem))
 	for {
 		if v.AuxInt != 16 {
@@ -42949,6 +47217,9 @@
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(!config.useSSE) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconst)
 		v.AuxInt = makeValAndOff(0, 8)
 		v.AddArg(destptr)
@@ -42960,7 +47231,7 @@
 		return true
 	}
 	// match: (Zero [24] destptr mem)
-	// cond:
+	// cond: !config.useSSE
 	// result: (MOVQstoreconst [makeValAndOff(0,16)] destptr 		(MOVQstoreconst [makeValAndOff(0,8)] destptr 			(MOVQstoreconst [0] destptr mem)))
 	for {
 		if v.AuxInt != 24 {
@@ -42969,6 +47240,9 @@
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(!config.useSSE) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconst)
 		v.AuxInt = makeValAndOff(0, 16)
 		v.AddArg(destptr)
@@ -42984,7 +47258,7 @@
 		return true
 	}
 	// match: (Zero [32] destptr mem)
-	// cond:
+	// cond: !config.useSSE
 	// result: (MOVQstoreconst [makeValAndOff(0,24)] destptr 		(MOVQstoreconst [makeValAndOff(0,16)] destptr 			(MOVQstoreconst [makeValAndOff(0,8)] destptr 				(MOVQstoreconst [0] destptr mem))))
 	for {
 		if v.AuxInt != 32 {
@@ -42993,6 +47267,9 @@
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(!config.useSSE) {
+			break
+		}
 		v.reset(OpAMD64MOVQstoreconst)
 		v.AuxInt = makeValAndOff(0, 24)
 		v.AddArg(destptr)
@@ -43012,25 +47289,46 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: s <= 1024 && s%8 == 0 && s%16 != 0 	&& !config.noDuffDevice
-	// result: (Zero [s-8] (OffPtr <destptr.Type> [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
+	// cond: s > 8 && s < 16 && config.useSSE
+	// result: (MOVQstoreconst [makeValAndOff(0,s-8)] destptr 		(MOVQstoreconst [0] destptr mem))
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s <= 1024 && s%8 == 0 && s%16 != 0 && !config.noDuffDevice) {
+		if !(s > 8 && s < 16 && config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVQstoreconst)
+		v.AuxInt = makeValAndOff(0, s-8)
+		v.AddArg(destptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
+		v0.AuxInt = 0
+		v0.AddArg(destptr)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Zero [s] destptr mem)
+	// cond: s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE
+	// result: (Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16]) 		(MOVOstore destptr (MOVOconst [0]) mem))
+	for {
+		s := v.AuxInt
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE) {
 			break
 		}
 		v.reset(OpZero)
-		v.AuxInt = s - 8
+		v.AuxInt = s - s%16
 		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
-		v0.AuxInt = 8
+		v0.AuxInt = s % 16
 		v0.AddArg(destptr)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstore, types.TypeMem)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
 		v1.AddArg(destptr)
-		v2 := b.NewValue0(v.Pos, OpAMD64MOVQconst, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
 		v2.AuxInt = 0
 		v1.AddArg(v2)
 		v1.AddArg(mem)
@@ -43038,14 +47336,185 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: s <= 1024 && s%16 == 0 && !config.noDuffDevice
+	// cond: s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE
+	// result: (Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16]) 		(MOVQstoreconst [0] destptr mem))
+	for {
+		s := v.AuxInt
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE) {
+			break
+		}
+		v.reset(OpZero)
+		v.AuxInt = s - s%16
+		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v0.AuxInt = s % 16
+		v0.AddArg(destptr)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
+		v1.AuxInt = 0
+		v1.AddArg(destptr)
+		v1.AddArg(mem)
+		v.AddArg(v1)
+		return true
+	}
+	// match: (Zero [16] destptr mem)
+	// cond: config.useSSE
+	// result: (MOVOstore destptr (MOVOconst [0]) mem)
+	for {
+		if v.AuxInt != 16 {
+			break
+		}
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVOstore)
+		v.AddArg(destptr)
+		v0 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (Zero [32] destptr mem)
+	// cond: config.useSSE
+	// result: (MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0]) 		(MOVOstore destptr (MOVOconst [0]) mem))
+	for {
+		if v.AuxInt != 32 {
+			break
+		}
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVOstore)
+		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v0.AuxInt = 16
+		v0.AddArg(destptr)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v2.AddArg(destptr)
+		v3 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v3.AuxInt = 0
+		v2.AddArg(v3)
+		v2.AddArg(mem)
+		v.AddArg(v2)
+		return true
+	}
+	// match: (Zero [48] destptr mem)
+	// cond: config.useSSE
+	// result: (MOVOstore (OffPtr <destptr.Type> destptr [32]) (MOVOconst [0]) 		(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0]) 			(MOVOstore destptr (MOVOconst [0]) mem)))
+	for {
+		if v.AuxInt != 48 {
+			break
+		}
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVOstore)
+		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v0.AuxInt = 32
+		v0.AddArg(destptr)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v3 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v3.AuxInt = 16
+		v3.AddArg(destptr)
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v4.AuxInt = 0
+		v2.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v5.AddArg(destptr)
+		v6 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v6.AuxInt = 0
+		v5.AddArg(v6)
+		v5.AddArg(mem)
+		v2.AddArg(v5)
+		v.AddArg(v2)
+		return true
+	}
+	// match: (Zero [64] destptr mem)
+	// cond: config.useSSE
+	// result: (MOVOstore (OffPtr <destptr.Type> destptr [48]) (MOVOconst [0]) 		(MOVOstore (OffPtr <destptr.Type> destptr [32]) (MOVOconst [0]) 			(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0]) 				(MOVOstore destptr (MOVOconst [0]) mem))))
+	for {
+		if v.AuxInt != 64 {
+			break
+		}
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(config.useSSE) {
+			break
+		}
+		v.reset(OpAMD64MOVOstore)
+		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v0.AuxInt = 48
+		v0.AddArg(destptr)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v3 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v3.AuxInt = 32
+		v3.AddArg(destptr)
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v4.AuxInt = 0
+		v2.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v6 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v6.AuxInt = 16
+		v6.AddArg(destptr)
+		v5.AddArg(v6)
+		v7 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v7.AuxInt = 0
+		v5.AddArg(v7)
+		v8 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
+		v8.AddArg(destptr)
+		v9 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
+		v9.AuxInt = 0
+		v8.AddArg(v9)
+		v8.AddArg(mem)
+		v5.AddArg(v8)
+		v2.AddArg(v5)
+		v.AddArg(v2)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64_OpZero_20(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (Zero [s] destptr mem)
+	// cond: s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice
 	// result: (DUFFZERO [s] destptr (MOVOconst [0]) mem)
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s <= 1024 && s%16 == 0 && !config.noDuffDevice) {
+		if !(s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice) {
 			break
 		}
 		v.reset(OpAMD64DUFFZERO)
@@ -43058,14 +47527,14 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: (s > 1024 || (config.noDuffDevice && s > 32)) 	&& s%8 == 0
+	// cond: (s > 1024 || (config.noDuffDevice && s > 64 || !config.useSSE && s > 32)) 	&& s%8 == 0
 	// result: (REPSTOSQ destptr (MOVQconst [s/8]) (MOVQconst [0]) mem)
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
-		if !((s > 1024 || (config.noDuffDevice && s > 32)) && s%8 == 0) {
+		if !((s > 1024 || (config.noDuffDevice && s > 64 || !config.useSSE && s > 32)) && s%8 == 0) {
 			break
 		}
 		v.reset(OpAMD64REPSTOSQ)
@@ -43187,6 +47656,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTL y (SHLL (MOVLconst [1]) x)))
@@ -43220,6 +47690,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTQ (SHLQ (MOVQconst [1]) x) y))
@@ -43253,6 +47724,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTQ y (SHLQ (MOVQconst [1]) x)))
@@ -43286,6 +47758,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTLconst [c] x))
@@ -43306,6 +47779,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTQconst [c] x))
@@ -43326,6 +47800,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTQ (MOVQconst [c]) x))
@@ -43351,6 +47826,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (TESTQ x (MOVQconst [c])))
@@ -43376,6 +47852,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (InvertFlags cmp) yes no)
@@ -43389,6 +47866,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagEQ) yes no)
@@ -43401,6 +47879,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT_ULT) yes no)
@@ -43413,6 +47892,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43426,6 +47906,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43439,6 +47920,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43452,6 +47934,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43467,6 +47950,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagEQ) yes no)
@@ -43479,6 +47963,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT_ULT) yes no)
@@ -43491,6 +47976,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43504,6 +47990,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43517,6 +48004,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagGT_UGT) yes no)
@@ -43529,6 +48017,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockAMD64GT:
@@ -43543,6 +48032,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagEQ) yes no)
@@ -43555,6 +48045,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43568,6 +48059,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43581,6 +48073,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43594,6 +48087,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagGT_UGT) yes no)
@@ -43606,6 +48100,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -43620,6 +48115,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETLE cmp) yes no)
@@ -43633,6 +48129,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETG cmp) yes no)
@@ -43646,6 +48143,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGE cmp) yes no)
@@ -43659,6 +48157,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETEQ cmp) yes no)
@@ -43672,6 +48171,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETNE cmp) yes no)
@@ -43685,6 +48185,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETB cmp) yes no)
@@ -43698,6 +48199,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETBE cmp) yes no)
@@ -43711,6 +48213,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETA cmp) yes no)
@@ -43724,6 +48227,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETAE cmp) yes no)
@@ -43737,6 +48241,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGF cmp) yes no)
@@ -43750,6 +48255,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETGEF cmp) yes no)
@@ -43763,6 +48269,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETEQF cmp) yes no)
@@ -43776,6 +48283,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (SETNEF cmp) yes no)
@@ -43789,6 +48297,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -43803,6 +48312,7 @@
 			v0.AddArg(cond)
 			v0.AddArg(cond)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockAMD64LE:
@@ -43817,6 +48327,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagEQ) yes no)
@@ -43829,6 +48340,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_ULT) yes no)
@@ -43841,6 +48353,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_UGT) yes no)
@@ -43853,6 +48366,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT_ULT) yes no)
@@ -43865,6 +48379,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43878,6 +48393,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43893,6 +48409,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagEQ) yes no)
@@ -43905,6 +48422,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43918,6 +48436,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagLT_UGT) yes no)
@@ -43930,6 +48449,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT_ULT) yes no)
@@ -43942,6 +48462,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43955,6 +48476,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -43982,6 +48504,7 @@
 			}
 			b.Kind = BlockAMD64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETL cmp) (SETL cmp)) yes no)
@@ -44007,6 +48530,7 @@
 			}
 			b.Kind = BlockAMD64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETLE cmp) (SETLE cmp)) yes no)
@@ -44032,6 +48556,7 @@
 			}
 			b.Kind = BlockAMD64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETLE cmp) (SETLE cmp)) yes no)
@@ -44057,6 +48582,7 @@
 			}
 			b.Kind = BlockAMD64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETG cmp) (SETG cmp)) yes no)
@@ -44082,6 +48608,7 @@
 			}
 			b.Kind = BlockAMD64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETG cmp) (SETG cmp)) yes no)
@@ -44107,6 +48634,7 @@
 			}
 			b.Kind = BlockAMD64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGE cmp) (SETGE cmp)) yes no)
@@ -44132,6 +48660,7 @@
 			}
 			b.Kind = BlockAMD64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGE cmp) (SETGE cmp)) yes no)
@@ -44157,6 +48686,7 @@
 			}
 			b.Kind = BlockAMD64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no)
@@ -44182,6 +48712,7 @@
 			}
 			b.Kind = BlockAMD64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no)
@@ -44207,6 +48738,7 @@
 			}
 			b.Kind = BlockAMD64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNE cmp) (SETNE cmp)) yes no)
@@ -44232,6 +48764,7 @@
 			}
 			b.Kind = BlockAMD64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNE cmp) (SETNE cmp)) yes no)
@@ -44257,6 +48790,7 @@
 			}
 			b.Kind = BlockAMD64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETB cmp) (SETB cmp)) yes no)
@@ -44282,6 +48816,7 @@
 			}
 			b.Kind = BlockAMD64ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETB cmp) (SETB cmp)) yes no)
@@ -44307,6 +48842,7 @@
 			}
 			b.Kind = BlockAMD64ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETBE cmp) (SETBE cmp)) yes no)
@@ -44332,6 +48868,7 @@
 			}
 			b.Kind = BlockAMD64ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETBE cmp) (SETBE cmp)) yes no)
@@ -44357,6 +48894,7 @@
 			}
 			b.Kind = BlockAMD64ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETA cmp) (SETA cmp)) yes no)
@@ -44382,6 +48920,7 @@
 			}
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETA cmp) (SETA cmp)) yes no)
@@ -44407,6 +48946,7 @@
 			}
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETAE cmp) (SETAE cmp)) yes no)
@@ -44432,6 +48972,7 @@
 			}
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETAE cmp) (SETAE cmp)) yes no)
@@ -44457,6 +48998,7 @@
 			}
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTL (SHLL (MOVLconst [1]) x) y))
@@ -44490,6 +49032,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTL y (SHLL (MOVLconst [1]) x)))
@@ -44523,6 +49066,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTQ (SHLQ (MOVQconst [1]) x) y))
@@ -44556,6 +49100,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTQ y (SHLQ (MOVQconst [1]) x)))
@@ -44589,6 +49134,7 @@
 			v0.AddArg(x)
 			v0.AddArg(y)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTLconst [c] x))
@@ -44609,6 +49155,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTQconst [c] x))
@@ -44629,6 +49176,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTQ (MOVQconst [c]) x))
@@ -44654,6 +49202,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTQ x (MOVQconst [c])))
@@ -44679,6 +49228,7 @@
 			v0.AuxInt = log2(c)
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGF cmp) (SETGF cmp)) yes no)
@@ -44704,6 +49254,7 @@
 			}
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGF cmp) (SETGF cmp)) yes no)
@@ -44729,6 +49280,7 @@
 			}
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no)
@@ -44754,6 +49306,7 @@
 			}
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no)
@@ -44779,6 +49332,7 @@
 			}
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no)
@@ -44804,6 +49358,7 @@
 			}
 			b.Kind = BlockAMD64EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no)
@@ -44829,6 +49384,7 @@
 			}
 			b.Kind = BlockAMD64EQF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no)
@@ -44854,6 +49410,7 @@
 			}
 			b.Kind = BlockAMD64NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no)
@@ -44879,6 +49436,7 @@
 			}
 			b.Kind = BlockAMD64NEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -44892,6 +49450,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -44904,6 +49463,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -44917,6 +49477,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagLT_UGT) yes no)
@@ -44929,6 +49490,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_ULT) yes no)
@@ -44941,6 +49503,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_UGT) yes no)
@@ -44953,6 +49516,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockAMD64UGE:
@@ -44967,6 +49531,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagEQ) yes no)
@@ -44979,6 +49544,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagLT_ULT) yes no)
@@ -44991,6 +49557,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45004,6 +49571,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagGT_ULT) yes no)
@@ -45016,6 +49584,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45029,6 +49598,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockAMD64UGT:
@@ -45043,6 +49613,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagEQ) yes no)
@@ -45055,6 +49626,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45068,6 +49640,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45081,6 +49654,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagGT_ULT) yes no)
@@ -45093,6 +49667,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45106,6 +49681,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockAMD64ULE:
@@ -45120,6 +49696,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagEQ) yes no)
@@ -45132,6 +49709,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_ULT) yes no)
@@ -45144,6 +49722,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_UGT) yes no)
@@ -45156,6 +49735,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45169,6 +49749,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagGT_UGT) yes no)
@@ -45181,6 +49762,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45196,6 +49778,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockAMD64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagEQ) yes no)
@@ -45208,6 +49791,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45221,6 +49805,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagLT_UGT) yes no)
@@ -45233,6 +49818,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -45246,6 +49832,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagGT_UGT) yes no)
@@ -45258,6 +49845,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index 6bb8da5..058ae72 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -33,6 +33,10 @@
 		return rewriteValueARM_OpARMADCshiftRLreg_0(v)
 	case OpARMADD:
 		return rewriteValueARM_OpARMADD_0(v) || rewriteValueARM_OpARMADD_10(v)
+	case OpARMADDD:
+		return rewriteValueARM_OpARMADDD_0(v)
+	case OpARMADDF:
+		return rewriteValueARM_OpARMADDF_0(v)
 	case OpARMADDS:
 		return rewriteValueARM_OpARMADDS_0(v) || rewriteValueARM_OpARMADDS_10(v)
 	case OpARMADDSshiftLL:
@@ -77,6 +81,10 @@
 		return rewriteValueARM_OpARMANDshiftRL_0(v)
 	case OpARMANDshiftRLreg:
 		return rewriteValueARM_OpARMANDshiftRLreg_0(v)
+	case OpARMBFX:
+		return rewriteValueARM_OpARMBFX_0(v)
+	case OpARMBFXU:
+		return rewriteValueARM_OpARMBFXU_0(v)
 	case OpARMBIC:
 		return rewriteValueARM_OpARMBIC_0(v)
 	case OpARMBICconst:
@@ -93,6 +101,22 @@
 		return rewriteValueARM_OpARMBICshiftRL_0(v)
 	case OpARMBICshiftRLreg:
 		return rewriteValueARM_OpARMBICshiftRLreg_0(v)
+	case OpARMCMN:
+		return rewriteValueARM_OpARMCMN_0(v) || rewriteValueARM_OpARMCMN_10(v)
+	case OpARMCMNconst:
+		return rewriteValueARM_OpARMCMNconst_0(v)
+	case OpARMCMNshiftLL:
+		return rewriteValueARM_OpARMCMNshiftLL_0(v)
+	case OpARMCMNshiftLLreg:
+		return rewriteValueARM_OpARMCMNshiftLLreg_0(v)
+	case OpARMCMNshiftRA:
+		return rewriteValueARM_OpARMCMNshiftRA_0(v)
+	case OpARMCMNshiftRAreg:
+		return rewriteValueARM_OpARMCMNshiftRAreg_0(v)
+	case OpARMCMNshiftRL:
+		return rewriteValueARM_OpARMCMNshiftRL_0(v)
+	case OpARMCMNshiftRLreg:
+		return rewriteValueARM_OpARMCMNshiftRLreg_0(v)
 	case OpARMCMOVWHSconst:
 		return rewriteValueARM_OpARMCMOVWHSconst_0(v)
 	case OpARMCMOVWLSconst:
@@ -137,14 +161,20 @@
 		return rewriteValueARM_OpARMLessThanU_0(v)
 	case OpARMMOVBUload:
 		return rewriteValueARM_OpARMMOVBUload_0(v)
+	case OpARMMOVBUloadidx:
+		return rewriteValueARM_OpARMMOVBUloadidx_0(v)
 	case OpARMMOVBUreg:
 		return rewriteValueARM_OpARMMOVBUreg_0(v)
 	case OpARMMOVBload:
 		return rewriteValueARM_OpARMMOVBload_0(v)
+	case OpARMMOVBloadidx:
+		return rewriteValueARM_OpARMMOVBloadidx_0(v)
 	case OpARMMOVBreg:
 		return rewriteValueARM_OpARMMOVBreg_0(v)
 	case OpARMMOVBstore:
 		return rewriteValueARM_OpARMMOVBstore_0(v)
+	case OpARMMOVBstoreidx:
+		return rewriteValueARM_OpARMMOVBstoreidx_0(v)
 	case OpARMMOVDload:
 		return rewriteValueARM_OpARMMOVDload_0(v)
 	case OpARMMOVDstore:
@@ -155,14 +185,20 @@
 		return rewriteValueARM_OpARMMOVFstore_0(v)
 	case OpARMMOVHUload:
 		return rewriteValueARM_OpARMMOVHUload_0(v)
+	case OpARMMOVHUloadidx:
+		return rewriteValueARM_OpARMMOVHUloadidx_0(v)
 	case OpARMMOVHUreg:
 		return rewriteValueARM_OpARMMOVHUreg_0(v)
 	case OpARMMOVHload:
 		return rewriteValueARM_OpARMMOVHload_0(v)
+	case OpARMMOVHloadidx:
+		return rewriteValueARM_OpARMMOVHloadidx_0(v)
 	case OpARMMOVHreg:
 		return rewriteValueARM_OpARMMOVHreg_0(v)
 	case OpARMMOVHstore:
 		return rewriteValueARM_OpARMMOVHstore_0(v)
+	case OpARMMOVHstoreidx:
+		return rewriteValueARM_OpARMMOVHstoreidx_0(v)
 	case OpARMMOVWload:
 		return rewriteValueARM_OpARMMOVWload_0(v)
 	case OpARMMOVWloadidx:
@@ -189,6 +225,12 @@
 		return rewriteValueARM_OpARMMUL_0(v) || rewriteValueARM_OpARMMUL_10(v) || rewriteValueARM_OpARMMUL_20(v)
 	case OpARMMULA:
 		return rewriteValueARM_OpARMMULA_0(v) || rewriteValueARM_OpARMMULA_10(v) || rewriteValueARM_OpARMMULA_20(v)
+	case OpARMMULD:
+		return rewriteValueARM_OpARMMULD_0(v)
+	case OpARMMULF:
+		return rewriteValueARM_OpARMMULF_0(v)
+	case OpARMMULS:
+		return rewriteValueARM_OpARMMULS_0(v) || rewriteValueARM_OpARMMULS_10(v) || rewriteValueARM_OpARMMULS_20(v)
 	case OpARMMVN:
 		return rewriteValueARM_OpARMMVN_0(v)
 	case OpARMMVNshiftLL:
@@ -203,6 +245,14 @@
 		return rewriteValueARM_OpARMMVNshiftRL_0(v)
 	case OpARMMVNshiftRLreg:
 		return rewriteValueARM_OpARMMVNshiftRLreg_0(v)
+	case OpARMNEGD:
+		return rewriteValueARM_OpARMNEGD_0(v)
+	case OpARMNEGF:
+		return rewriteValueARM_OpARMNEGF_0(v)
+	case OpARMNMULD:
+		return rewriteValueARM_OpARMNMULD_0(v)
+	case OpARMNMULF:
+		return rewriteValueARM_OpARMNMULF_0(v)
 	case OpARMNotEqual:
 		return rewriteValueARM_OpARMNotEqual_0(v)
 	case OpARMOR:
@@ -295,6 +345,10 @@
 		return rewriteValueARM_OpARMSRLconst_0(v)
 	case OpARMSUB:
 		return rewriteValueARM_OpARMSUB_0(v) || rewriteValueARM_OpARMSUB_10(v)
+	case OpARMSUBD:
+		return rewriteValueARM_OpARMSUBD_0(v)
+	case OpARMSUBF:
+		return rewriteValueARM_OpARMSUBF_0(v)
 	case OpARMSUBS:
 		return rewriteValueARM_OpARMSUBS_0(v) || rewriteValueARM_OpARMSUBS_10(v)
 	case OpARMSUBSshiftLL:
@@ -323,6 +377,38 @@
 		return rewriteValueARM_OpARMSUBshiftRL_0(v)
 	case OpARMSUBshiftRLreg:
 		return rewriteValueARM_OpARMSUBshiftRLreg_0(v)
+	case OpARMTEQ:
+		return rewriteValueARM_OpARMTEQ_0(v) || rewriteValueARM_OpARMTEQ_10(v)
+	case OpARMTEQconst:
+		return rewriteValueARM_OpARMTEQconst_0(v)
+	case OpARMTEQshiftLL:
+		return rewriteValueARM_OpARMTEQshiftLL_0(v)
+	case OpARMTEQshiftLLreg:
+		return rewriteValueARM_OpARMTEQshiftLLreg_0(v)
+	case OpARMTEQshiftRA:
+		return rewriteValueARM_OpARMTEQshiftRA_0(v)
+	case OpARMTEQshiftRAreg:
+		return rewriteValueARM_OpARMTEQshiftRAreg_0(v)
+	case OpARMTEQshiftRL:
+		return rewriteValueARM_OpARMTEQshiftRL_0(v)
+	case OpARMTEQshiftRLreg:
+		return rewriteValueARM_OpARMTEQshiftRLreg_0(v)
+	case OpARMTST:
+		return rewriteValueARM_OpARMTST_0(v) || rewriteValueARM_OpARMTST_10(v)
+	case OpARMTSTconst:
+		return rewriteValueARM_OpARMTSTconst_0(v)
+	case OpARMTSTshiftLL:
+		return rewriteValueARM_OpARMTSTshiftLL_0(v)
+	case OpARMTSTshiftLLreg:
+		return rewriteValueARM_OpARMTSTshiftLLreg_0(v)
+	case OpARMTSTshiftRA:
+		return rewriteValueARM_OpARMTSTshiftRA_0(v)
+	case OpARMTSTshiftRAreg:
+		return rewriteValueARM_OpARMTSTshiftRAreg_0(v)
+	case OpARMTSTshiftRL:
+		return rewriteValueARM_OpARMTSTshiftRL_0(v)
+	case OpARMTSTshiftRLreg:
+		return rewriteValueARM_OpARMTSTshiftRLreg_0(v)
 	case OpARMXOR:
 		return rewriteValueARM_OpARMXOR_0(v) || rewriteValueARM_OpARMXOR_10(v)
 	case OpARMXORconst:
@@ -465,6 +551,8 @@
 		return rewriteValueARM_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueARM_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValueARM_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueARM_OpGetClosurePtr_0(v)
 	case OpGreater16:
@@ -1371,7 +1459,7 @@
 	}
 	// match: (ADCshiftLL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (ADCconst x [int64(uint32(c)<<uint64(d))] flags)
+	// result: (ADCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -1383,7 +1471,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMADCconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -1557,7 +1645,7 @@
 	}
 	// match: (ADCshiftRL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (ADCconst x [int64(uint32(c)>>uint64(d))] flags)
+	// result: (ADCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -1569,7 +1657,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMADCconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -2013,6 +2101,188 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMADDD_0(v *Value) bool {
+	// match: (ADDD a (MULD x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAD a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMULD {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDD (MULD x y) a)
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAD a x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMULD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		a := v.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDD a (NMULD x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSD a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNMULD {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDD (NMULD x y) a)
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSD a x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNMULD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		a := v.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMADDF_0(v *Value) bool {
+	// match: (ADDF a (MULF x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAF a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMULF {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDF (MULF x y) a)
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAF a x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMULF {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		a := v.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDF a (NMULF x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSF a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNMULF {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADDF (NMULF x y) a)
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSF a x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNMULF {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		a := v.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMADDS_0(v *Value) bool {
 	// match: (ADDS x (MOVWconst [c]))
 	// cond:
@@ -2298,7 +2568,7 @@
 	}
 	// match: (ADDSshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ADDSconst x [int64(uint32(c)<<uint64(d))])
+	// result: (ADDSconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -2309,7 +2579,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMADDSconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -2468,7 +2738,7 @@
 	}
 	// match: (ADDSshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ADDSconst x [int64(uint32(c)>>uint64(d))])
+	// result: (ADDSconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -2479,7 +2749,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMADDSconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -2663,7 +2933,7 @@
 	}
 	// match: (ADDshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ADDconst x [int64(uint32(c)<<uint64(d))])
+	// result: (ADDconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -2674,7 +2944,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMADDconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -2855,7 +3125,7 @@
 	}
 	// match: (ADDshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ADDconst x [int64(uint32(c)>>uint64(d))])
+	// result: (ADDconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -2866,7 +3136,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMADDconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -3382,7 +3652,7 @@
 	}
 	// match: (ANDconst [c] x)
 	// cond: !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c))
-	// result: (BICconst [int64(^uint32(c))] x)
+	// result: (BICconst [int64(int32(^uint32(c)))] x)
 	for {
 		c := v.AuxInt
 		x := v.Args[0]
@@ -3390,7 +3660,7 @@
 			break
 		}
 		v.reset(OpARMBICconst)
-		v.AuxInt = int64(^uint32(c))
+		v.AuxInt = int64(int32(^uint32(c)))
 		v.AddArg(x)
 		return true
 	}
@@ -3451,7 +3721,7 @@
 	}
 	// match: (ANDshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ANDconst x [int64(uint32(c)<<uint64(d))])
+	// result: (ANDconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -3462,7 +3732,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMANDconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -3667,7 +3937,7 @@
 	}
 	// match: (ANDshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ANDconst x [int64(uint32(c)>>uint64(d))])
+	// result: (ANDconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -3678,7 +3948,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMANDconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -3750,6 +4020,40 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMBFX_0(v *Value) bool {
+	// match: (BFX [c] (MOVWconst [d]))
+	// cond:
+	// result: (MOVWconst [int64(int32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
+	for {
+		c := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		d := v_0.AuxInt
+		v.reset(OpARMMOVWconst)
+		v.AuxInt = int64(int32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8)))
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMBFXU_0(v *Value) bool {
+	// match: (BFXU [c] (MOVWconst [d]))
+	// cond:
+	// result: (MOVWconst [int64(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
+	for {
+		c := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		d := v_0.AuxInt
+		v.reset(OpARMMOVWconst)
+		v.AuxInt = int64(uint32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8)))
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMBIC_0(v *Value) bool {
 	// match: (BIC x (MOVWconst [c]))
 	// cond:
@@ -3921,7 +4225,7 @@
 	}
 	// match: (BICconst [c] x)
 	// cond: !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c))
-	// result: (ANDconst [int64(^uint32(c))] x)
+	// result: (ANDconst [int64(int32(^uint32(c)))] x)
 	for {
 		c := v.AuxInt
 		x := v.Args[0]
@@ -3929,7 +4233,7 @@
 			break
 		}
 		v.reset(OpARMANDconst)
-		v.AuxInt = int64(^uint32(c))
+		v.AuxInt = int64(int32(^uint32(c)))
 		v.AddArg(x)
 		return true
 	}
@@ -3968,7 +4272,7 @@
 func rewriteValueARM_OpARMBICshiftLL_0(v *Value) bool {
 	// match: (BICshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (BICconst x [int64(uint32(c)<<uint64(d))])
+	// result: (BICconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -3979,7 +4283,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMBICconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -4094,7 +4398,7 @@
 func rewriteValueARM_OpARMBICshiftRL_0(v *Value) bool {
 	// match: (BICshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (BICconst x [int64(uint32(c)>>uint64(d))])
+	// result: (BICconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -4105,7 +4409,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMBICconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -4154,6 +4458,642 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMCMN_0(v *Value) bool {
+	// match: (CMN x (MOVWconst [c]))
+	// cond:
+	// result: (CMNconst [c] x)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (CMN (MOVWconst [c]) x)
+	// cond:
+	// result: (CMNconst [c] x)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (CMN x (SLLconst [c] y))
+	// cond:
+	// result: (CMNshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMCMNshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN (SLLconst [c] y) x)
+	// cond:
+	// result: (CMNshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN x (SRLconst [c] y))
+	// cond:
+	// result: (CMNshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMCMNshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN (SRLconst [c] y) x)
+	// cond:
+	// result: (CMNshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN x (SRAconst [c] y))
+	// cond:
+	// result: (CMNshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRAconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMCMNshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN (SRAconst [c] y) x)
+	// cond:
+	// result: (CMNshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRAconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN x (SLL y z))
+	// cond:
+	// result: (CMNshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMCMNshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (CMN (SLL y z) x)
+	// cond:
+	// result: (CMNshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMN_10(v *Value) bool {
+	// match: (CMN x (SRL y z))
+	// cond:
+	// result: (CMNshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMCMNshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (CMN (SRL y z) x)
+	// cond:
+	// result: (CMNshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (CMN x (SRA y z))
+	// cond:
+	// result: (CMNshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRA {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMCMNshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (CMN (SRA y z) x)
+	// cond:
+	// result: (CMNshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRA {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMCMNshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (CMN x (RSBconst [0] y))
+	// cond:
+	// result: (CMP x y)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMRSBconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpARMCMP)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CMN (RSBconst [0] y) x)
+	// cond:
+	// result: (CMP x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMRSBconst {
+			break
+		}
+		if v_0.AuxInt != 0 {
+			break
+		}
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMCMP)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNconst_0(v *Value) bool {
+	// match: (CMNconst (MOVWconst [x]) [y])
+	// cond: int32(x)==int32(-y)
+	// result: (FlagEQ)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x) == int32(-y)) {
+			break
+		}
+		v.reset(OpARMFlagEQ)
+		return true
+	}
+	// match: (CMNconst (MOVWconst [x]) [y])
+	// cond: int32(x)<int32(-y) && uint32(x)<uint32(-y)
+	// result: (FlagLT_ULT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x) < int32(-y) && uint32(x) < uint32(-y)) {
+			break
+		}
+		v.reset(OpARMFlagLT_ULT)
+		return true
+	}
+	// match: (CMNconst (MOVWconst [x]) [y])
+	// cond: int32(x)<int32(-y) && uint32(x)>uint32(-y)
+	// result: (FlagLT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x) < int32(-y) && uint32(x) > uint32(-y)) {
+			break
+		}
+		v.reset(OpARMFlagLT_UGT)
+		return true
+	}
+	// match: (CMNconst (MOVWconst [x]) [y])
+	// cond: int32(x)>int32(-y) && uint32(x)<uint32(-y)
+	// result: (FlagGT_ULT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x) > int32(-y) && uint32(x) < uint32(-y)) {
+			break
+		}
+		v.reset(OpARMFlagGT_ULT)
+		return true
+	}
+	// match: (CMNconst (MOVWconst [x]) [y])
+	// cond: int32(x)>int32(-y) && uint32(x)>uint32(-y)
+	// result: (FlagGT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x) > int32(-y) && uint32(x) > uint32(-y)) {
+			break
+		}
+		v.reset(OpARMFlagGT_UGT)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftLL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftLL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (CMNconst [c] (SLLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftLL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (CMNconst x [int64(int32(uint32(c)<<uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMCMNconst)
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftLLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftLLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (CMNconst [c] (SLL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftLLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (CMNshiftLL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMCMNshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftRA_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftRA (MOVWconst [c]) x [d])
+	// cond:
+	// result: (CMNconst [c] (SRAconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftRA x (MOVWconst [c]) [d])
+	// cond:
+	// result: (CMNconst x [int64(int32(c)>>uint64(d))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMCMNconst)
+		v.AuxInt = int64(int32(c) >> uint64(d))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftRAreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftRAreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (CMNconst [c] (SRA <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftRAreg x y (MOVWconst [c]))
+	// cond:
+	// result: (CMNshiftRA x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMCMNshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftRL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftRL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (CMNconst [c] (SRLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftRL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (CMNconst x [int64(int32(uint32(c)>>uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMCMNconst)
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMCMNshiftRLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (CMNshiftRLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (CMNconst [c] (SRL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMCMNconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (CMNshiftRLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (CMNshiftRL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMCMNshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMCMOVWHSconst_0(v *Value) bool {
 	// match: (CMOVWHSconst _ (FlagEQ) [c])
 	// cond:
@@ -4616,6 +5556,25 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (CMP x (RSBconst [0] y))
+	// cond:
+	// result: (CMN x y)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMRSBconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpARMCMN)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMCMPD_0(v *Value) bool {
@@ -4830,7 +5789,7 @@
 	}
 	// match: (CMPshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (CMPconst x [int64(uint32(c)<<uint64(d))])
+	// result: (CMPconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -4841,7 +5800,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMCMPconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -5008,7 +5967,7 @@
 	}
 	// match: (CMPshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (CMPconst x [int64(uint32(c)>>uint64(d))])
+	// result: (CMPconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -5019,7 +5978,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMCMPconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -5755,6 +6714,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond:
 	// result: (MOVBUload [off1+off2] {sym} ptr mem)
@@ -5846,6 +6809,95 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVBUload [0] {sym} (ADD ptr idx) mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVBUloadidx ptr idx mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVBUloadidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVBUloadidx_0(v *Value) bool {
+	// match: (MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
+	// cond: isSamePtr(ptr, ptr2)
+	// result: (MOVBUreg x)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		idx := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVBstoreidx {
+			break
+		}
+		_ = v_2.Args[3]
+		ptr2 := v_2.Args[0]
+		if idx != v_2.Args[1] {
+			break
+		}
+		x := v_2.Args[2]
+		if !(isSamePtr(ptr, ptr2)) {
+			break
+		}
+		v.reset(OpARMMOVBUreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVBUloadidx ptr (MOVWconst [c]) mem)
+	// cond:
+	// result: (MOVBUload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		v.reset(OpARMMOVBUload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBUloadidx (MOVWconst [c]) ptr mem)
+	// cond:
+	// result: (MOVBUload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpARMMOVBUload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
@@ -5905,6 +6957,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond:
 	// result: (MOVBload [off1+off2] {sym} ptr mem)
@@ -5996,6 +7052,95 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVBload [0] {sym} (ADD ptr idx) mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVBloadidx ptr idx mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVBloadidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVBloadidx_0(v *Value) bool {
+	// match: (MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
+	// cond: isSamePtr(ptr, ptr2)
+	// result: (MOVBreg x)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		idx := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVBstoreidx {
+			break
+		}
+		_ = v_2.Args[3]
+		ptr2 := v_2.Args[0]
+		if idx != v_2.Args[1] {
+			break
+		}
+		x := v_2.Args[2]
+		if !(isSamePtr(ptr, ptr2)) {
+			break
+		}
+		v.reset(OpARMMOVBreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVBloadidx ptr (MOVWconst [c]) mem)
+	// cond:
+	// result: (MOVBload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		v.reset(OpARMMOVBload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBloadidx (MOVWconst [c]) ptr mem)
+	// cond:
+	// result: (MOVBload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpARMMOVBload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
@@ -6058,6 +7203,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
 	// cond:
 	// result: (MOVBstore [off1+off2] {sym} ptr val mem)
@@ -6219,6 +7368,77 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVBstore [0] {sym} (ADD ptr idx) val mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVBstoreidx ptr idx val mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		val := v.Args[1]
+		mem := v.Args[2]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVBstoreidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVBstoreidx_0(v *Value) bool {
+	// match: (MOVBstoreidx ptr (MOVWconst [c]) val mem)
+	// cond:
+	// result: (MOVBstore [c] ptr val mem)
+	for {
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		val := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpARMMOVBstore)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstoreidx (MOVWconst [c]) ptr val mem)
+	// cond:
+	// result: (MOVBstore [c] ptr val mem)
+	for {
+		_ = v.Args[3]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		val := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpARMMOVBstore)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
@@ -6564,6 +7784,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond:
 	// result: (MOVHUload [off1+off2] {sym} ptr mem)
@@ -6655,6 +7879,95 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVHUload [0] {sym} (ADD ptr idx) mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVHUloadidx ptr idx mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVHUloadidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVHUloadidx_0(v *Value) bool {
+	// match: (MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
+	// cond: isSamePtr(ptr, ptr2)
+	// result: (MOVHUreg x)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		idx := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVHstoreidx {
+			break
+		}
+		_ = v_2.Args[3]
+		ptr2 := v_2.Args[0]
+		if idx != v_2.Args[1] {
+			break
+		}
+		x := v_2.Args[2]
+		if !(isSamePtr(ptr, ptr2)) {
+			break
+		}
+		v.reset(OpARMMOVHUreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVHUloadidx ptr (MOVWconst [c]) mem)
+	// cond:
+	// result: (MOVHUload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		v.reset(OpARMMOVHUload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHUloadidx (MOVWconst [c]) ptr mem)
+	// cond:
+	// result: (MOVHUload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpARMMOVHUload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
@@ -6739,6 +8052,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond:
 	// result: (MOVHload [off1+off2] {sym} ptr mem)
@@ -6830,6 +8147,95 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVHload [0] {sym} (ADD ptr idx) mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVHloadidx ptr idx mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVHloadidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
+	// match: (MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
+	// cond: isSamePtr(ptr, ptr2)
+	// result: (MOVHreg x)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		idx := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVHstoreidx {
+			break
+		}
+		_ = v_2.Args[3]
+		ptr2 := v_2.Args[0]
+		if idx != v_2.Args[1] {
+			break
+		}
+		x := v_2.Args[2]
+		if !(isSamePtr(ptr, ptr2)) {
+			break
+		}
+		v.reset(OpARMMOVHreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVHloadidx ptr (MOVWconst [c]) mem)
+	// cond:
+	// result: (MOVHload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		v.reset(OpARMMOVHload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHloadidx (MOVWconst [c]) ptr mem)
+	// cond:
+	// result: (MOVHload [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpARMMOVHload)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
@@ -6942,6 +8348,10 @@
 	return false
 }
 func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
 	// cond:
 	// result: (MOVHstore [off1+off2] {sym} ptr val mem)
@@ -7059,6 +8469,77 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVHstore [0] {sym} (ADD ptr idx) val mem)
+	// cond: sym == nil && !config.nacl
+	// result: (MOVHstoreidx ptr idx val mem)
+	for {
+		if v.AuxInt != 0 {
+			break
+		}
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		val := v.Args[1]
+		mem := v.Args[2]
+		if !(sym == nil && !config.nacl) {
+			break
+		}
+		v.reset(OpARMMOVHstoreidx)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMOVHstoreidx_0(v *Value) bool {
+	// match: (MOVHstoreidx ptr (MOVWconst [c]) val mem)
+	// cond:
+	// result: (MOVHstore [c] ptr val mem)
+	for {
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		val := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpARMMOVHstore)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHstoreidx (MOVWconst [c]) ptr val mem)
+	// cond:
+	// result: (MOVHstore [c] ptr val mem)
+	for {
+		_ = v.Args[3]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		ptr := v.Args[1]
+		val := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpARMMOVHstore)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMMOVWload_0(v *Value) bool {
@@ -9037,6 +10518,594 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMMULD_0(v *Value) bool {
+	// match: (MULD (NEGD x) y)
+	// cond: objabi.GOARM >= 6
+	// result: (NMULD x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNEGD {
+			break
+		}
+		x := v_0.Args[0]
+		y := v.Args[1]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULD)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (MULD y (NEGD x))
+	// cond: objabi.GOARM >= 6
+	// result: (NMULD x y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNEGD {
+			break
+		}
+		x := v_1.Args[0]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULD)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMULF_0(v *Value) bool {
+	// match: (MULF (NEGF x) y)
+	// cond: objabi.GOARM >= 6
+	// result: (NMULF x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNEGF {
+			break
+		}
+		x := v_0.Args[0]
+		y := v.Args[1]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULF)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (MULF y (NEGF x))
+	// cond: objabi.GOARM >= 6
+	// result: (NMULF x y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNEGF {
+			break
+		}
+		x := v_1.Args[0]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULF)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMULS_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: int32(c) == -1
+	// result: (ADD a x)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(int32(c) == -1) {
+			break
+		}
+		v.reset(OpARMADD)
+		v.AddArg(a)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MULS _ (MOVWconst [0]) a)
+	// cond:
+	// result: a
+	for {
+		_ = v.Args[2]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		a := v.Args[2]
+		v.reset(OpCopy)
+		v.Type = a.Type
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [1]) a)
+	// cond:
+	// result: (RSB x a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		if v_1.AuxInt != 1 {
+			break
+		}
+		a := v.Args[2]
+		v.reset(OpARMRSB)
+		v.AddArg(x)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: isPowerOfTwo(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c)] x) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(isPowerOfTwo(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: isPowerOfTwo(c-1) && int32(c) >= 3
+	// result: (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(isPowerOfTwo(c-1) && int32(c) >= 3) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v0.AuxInt = log2(c - 1)
+		v0.AddArg(x)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: isPowerOfTwo(c+1) && int32(c) >= 7
+	// result: (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(isPowerOfTwo(c+1) && int32(c) >= 7) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type)
+		v0.AuxInt = log2(c + 1)
+		v0.AddArg(x)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 3)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 1
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 5)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 2
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 7)
+		v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type)
+		v1.AuxInt = 3
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS x (MOVWconst [c]) a)
+	// cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		a := v.Args[2]
+		if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 9)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 3
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMULS_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: int32(c) == -1
+	// result: (ADD a x)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(int32(c) == -1) {
+			break
+		}
+		v.reset(OpARMADD)
+		v.AddArg(a)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MULS (MOVWconst [0]) _ a)
+	// cond:
+	// result: a
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		if v_0.AuxInt != 0 {
+			break
+		}
+		a := v.Args[2]
+		v.reset(OpCopy)
+		v.Type = a.Type
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [1]) x a)
+	// cond:
+	// result: (RSB x a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		if v_0.AuxInt != 1 {
+			break
+		}
+		x := v.Args[1]
+		a := v.Args[2]
+		v.reset(OpARMRSB)
+		v.AddArg(x)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: isPowerOfTwo(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c)] x) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(isPowerOfTwo(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: isPowerOfTwo(c-1) && int32(c) >= 3
+	// result: (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(isPowerOfTwo(c-1) && int32(c) >= 3) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v0.AuxInt = log2(c - 1)
+		v0.AddArg(x)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: isPowerOfTwo(c+1) && int32(c) >= 7
+	// result: (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(isPowerOfTwo(c+1) && int32(c) >= 7) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type)
+		v0.AuxInt = log2(c + 1)
+		v0.AddArg(x)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 3)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 1
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 5)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 2
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 7)
+		v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type)
+		v1.AuxInt = 3
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	// match: (MULS (MOVWconst [c]) x a)
+	// cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)
+	// result: (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		a := v.Args[2]
+		if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) {
+			break
+		}
+		v.reset(OpARMRSB)
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = log2(c / 9)
+		v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type)
+		v1.AuxInt = 3
+		v1.AddArg(x)
+		v1.AddArg(x)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		v.AddArg(a)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMMULS_20(v *Value) bool {
+	// match: (MULS (MOVWconst [c]) (MOVWconst [d]) a)
+	// cond:
+	// result: (SUBconst [int64(int32(c*d))] a)
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		d := v_1.AuxInt
+		a := v.Args[2]
+		v.reset(OpARMSUBconst)
+		v.AuxInt = int64(int32(c * d))
+		v.AddArg(a)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMMVN_0(v *Value) bool {
 	// match: (MVN (MOVWconst [c]))
 	// cond:
@@ -9254,6 +11323,120 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMNEGD_0(v *Value) bool {
+	// match: (NEGD (MULD x y))
+	// cond: objabi.GOARM >= 6
+	// result: (NMULD x y)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMULD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULD)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMNEGF_0(v *Value) bool {
+	// match: (NEGF (MULF x y))
+	// cond: objabi.GOARM >= 6
+	// result: (NMULF x y)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMULF {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		if !(objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMNMULF)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMNMULD_0(v *Value) bool {
+	// match: (NMULD (NEGD x) y)
+	// cond:
+	// result: (MULD x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNEGD {
+			break
+		}
+		x := v_0.Args[0]
+		y := v.Args[1]
+		v.reset(OpARMMULD)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (NMULD y (NEGD x))
+	// cond:
+	// result: (MULD x y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNEGD {
+			break
+		}
+		x := v_1.Args[0]
+		v.reset(OpARMMULD)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMNMULF_0(v *Value) bool {
+	// match: (NMULF (NEGF x) y)
+	// cond:
+	// result: (MULF x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMNEGF {
+			break
+		}
+		x := v_0.Args[0]
+		y := v.Args[1]
+		v.reset(OpARMMULF)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (NMULF y (NEGF x))
+	// cond:
+	// result: (MULF x y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNEGF {
+			break
+		}
+		x := v_1.Args[0]
+		v.reset(OpARMMULF)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMNotEqual_0(v *Value) bool {
 	// match: (NotEqual (FlagEQ))
 	// cond:
@@ -9687,7 +11870,7 @@
 	}
 	// match: (ORshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ORconst x [int64(uint32(c)<<uint64(d))])
+	// result: (ORconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -9698,7 +11881,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMORconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -9925,7 +12108,7 @@
 	}
 	// match: (ORshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (ORconst x [int64(uint32(c)>>uint64(d))])
+	// result: (ORconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -9936,7 +12119,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMORconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -10301,6 +12484,28 @@
 		v.AuxInt = 0
 		return true
 	}
+	// match: (RSB (MUL x y) a)
+	// cond: objabi.GOARM == 7
+	// result: (MULS x y a)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMUL {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		a := v.Args[1]
+		if !(objabi.GOARM == 7) {
+			break
+		}
+		v.reset(OpARMMULS)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(a)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMRSBSshiftLL_0(v *Value) bool {
@@ -10328,7 +12533,7 @@
 	}
 	// match: (RSBSshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (RSBSconst x [int64(uint32(c)<<uint64(d))])
+	// result: (RSBSconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -10339,7 +12544,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMRSBSconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -10498,7 +12703,7 @@
 	}
 	// match: (RSBSshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (RSBSconst x [int64(uint32(c)>>uint64(d))])
+	// result: (RSBSconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -10509,7 +12714,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMRSBSconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -10648,7 +12853,7 @@
 	}
 	// match: (RSBshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (RSBconst x [int64(uint32(c)<<uint64(d))])
+	// result: (RSBconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -10659,7 +12864,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMRSBconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -10862,7 +13067,7 @@
 	}
 	// match: (RSBshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (RSBconst x [int64(uint32(c)>>uint64(d))])
+	// result: (RSBconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -10873,7 +13078,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMRSBconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -11012,7 +13217,7 @@
 	}
 	// match: (RSCshiftLL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (RSCconst x [int64(uint32(c)<<uint64(d))] flags)
+	// result: (RSCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -11024,7 +13229,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMRSCconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -11198,7 +13403,7 @@
 	}
 	// match: (RSCshiftRL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (RSCconst x [int64(uint32(c)>>uint64(d))] flags)
+	// result: (RSCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -11210,7 +13415,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMRSCconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -11620,7 +13825,7 @@
 	}
 	// match: (SBCshiftLL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (SBCconst x [int64(uint32(c)<<uint64(d))] flags)
+	// result: (SBCconst x [int64(int32(uint32(c)<<uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -11632,7 +13837,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMSBCconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -11806,7 +14011,7 @@
 	}
 	// match: (SBCshiftRL x (MOVWconst [c]) [d] flags)
 	// cond:
-	// result: (SBCconst x [int64(uint32(c)>>uint64(d))] flags)
+	// result: (SBCconst x [int64(int32(uint32(c)>>uint64(d)))] flags)
 	for {
 		d := v.AuxInt
 		_ = v.Args[2]
@@ -11818,7 +14023,7 @@
 		c := v_1.AuxInt
 		flags := v.Args[2]
 		v.reset(OpARMSBCconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		v.AddArg(flags)
 		return true
@@ -12022,6 +14227,25 @@
 		v.AuxInt = int64(int32(d) >> uint64(c))
 		return true
 	}
+	// match: (SRAconst (SLLconst x [c]) [d])
+	// cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+	// result: (BFX [(d-c)|(32-d)<<8] x)
+	for {
+		d := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLLconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v_0.Args[0]
+		if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+			break
+		}
+		v.reset(OpARMBFX)
+		v.AuxInt = (d - c) | (32-d)<<8
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMSRL_0(v *Value) bool {
@@ -12058,6 +14282,25 @@
 		v.AuxInt = int64(uint32(d) >> uint64(c))
 		return true
 	}
+	// match: (SRLconst (SLLconst x [c]) [d])
+	// cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+	// result: (BFXU [(d-c)|(32-d)<<8] x)
+	for {
+		d := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLLconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v_0.Args[0]
+		if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+			break
+		}
+		v.reset(OpARMBFXU)
+		v.AuxInt = (d - c) | (32-d)<<8
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMSUB_0(v *Value) bool {
@@ -12331,6 +14574,122 @@
 		v.AuxInt = 0
 		return true
 	}
+	// match: (SUB a (MUL x y))
+	// cond: objabi.GOARM == 7
+	// result: (MULS x y a)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMUL {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(objabi.GOARM == 7) {
+			break
+		}
+		v.reset(OpARMMULS)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(a)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMSUBD_0(v *Value) bool {
+	// match: (SUBD a (MULD x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSD a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMULD {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (SUBD a (NMULD x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAD a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNMULD {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAD)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMSUBF_0(v *Value) bool {
+	// match: (SUBF a (MULF x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULSF a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMULF {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULSF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (SUBF a (NMULF x y))
+	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// result: (MULAF a x y)
+	for {
+		_ = v.Args[1]
+		a := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMNMULF {
+			break
+		}
+		_ = v_1.Args[1]
+		x := v_1.Args[0]
+		y := v_1.Args[1]
+		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			break
+		}
+		v.reset(OpARMMULAF)
+		v.AddArg(a)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM_OpARMSUBS_0(v *Value) bool {
@@ -12602,7 +14961,7 @@
 	}
 	// match: (SUBSshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (SUBSconst x [int64(uint32(c)<<uint64(d))])
+	// result: (SUBSconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -12613,7 +14972,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMSUBSconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -12772,7 +15131,7 @@
 	}
 	// match: (SUBSshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (SUBSconst x [int64(uint32(c)>>uint64(d))])
+	// result: (SUBSconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -12783,7 +15142,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMSUBSconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -12967,7 +15326,7 @@
 	}
 	// match: (SUBshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (SUBconst x [int64(uint32(c)<<uint64(d))])
+	// result: (SUBconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -12978,7 +15337,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMSUBconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -13181,7 +15540,7 @@
 	}
 	// match: (SUBshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (SUBconst x [int64(uint32(c)>>uint64(d))])
+	// result: (SUBconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -13192,7 +15551,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMSUBconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -13263,6 +15622,1138 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMTEQ_0(v *Value) bool {
+	// match: (TEQ x (MOVWconst [c]))
+	// cond:
+	// result: (TEQconst [c] x)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (TEQ (MOVWconst [c]) x)
+	// cond:
+	// result: (TEQconst [c] x)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (TEQ x (SLLconst [c] y))
+	// cond:
+	// result: (TEQshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTEQshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ (SLLconst [c] y) x)
+	// cond:
+	// result: (TEQshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ x (SRLconst [c] y))
+	// cond:
+	// result: (TEQshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTEQshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ (SRLconst [c] y) x)
+	// cond:
+	// result: (TEQshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ x (SRAconst [c] y))
+	// cond:
+	// result: (TEQshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRAconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTEQshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ (SRAconst [c] y) x)
+	// cond:
+	// result: (TEQshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRAconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TEQ x (SLL y z))
+	// cond:
+	// result: (TEQshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTEQshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TEQ (SLL y z) x)
+	// cond:
+	// result: (TEQshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQ_10(v *Value) bool {
+	// match: (TEQ x (SRL y z))
+	// cond:
+	// result: (TEQshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTEQshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TEQ (SRL y z) x)
+	// cond:
+	// result: (TEQshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TEQ x (SRA y z))
+	// cond:
+	// result: (TEQshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRA {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTEQshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TEQ (SRA y z) x)
+	// cond:
+	// result: (TEQshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRA {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTEQshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQconst_0(v *Value) bool {
+	// match: (TEQconst (MOVWconst [x]) [y])
+	// cond: int32(x^y)==0
+	// result: (FlagEQ)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x^y) == 0) {
+			break
+		}
+		v.reset(OpARMFlagEQ)
+		return true
+	}
+	// match: (TEQconst (MOVWconst [x]) [y])
+	// cond: int32(x^y)<0
+	// result: (FlagLT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x^y) < 0) {
+			break
+		}
+		v.reset(OpARMFlagLT_UGT)
+		return true
+	}
+	// match: (TEQconst (MOVWconst [x]) [y])
+	// cond: int32(x^y)>0
+	// result: (FlagGT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x^y) > 0) {
+			break
+		}
+		v.reset(OpARMFlagGT_UGT)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftLL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftLL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TEQconst [c] (SLLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftLL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TEQconst x [int64(int32(uint32(c)<<uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTEQconst)
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftLLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftLLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TEQconst [c] (SLL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftLLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TEQshiftLL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTEQshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftRA_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftRA (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TEQconst [c] (SRAconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftRA x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TEQconst x [int64(int32(c)>>uint64(d))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTEQconst)
+		v.AuxInt = int64(int32(c) >> uint64(d))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftRAreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftRAreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TEQconst [c] (SRA <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftRAreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TEQshiftRA x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTEQshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftRL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftRL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TEQconst [c] (SRLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftRL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TEQconst x [int64(int32(uint32(c)>>uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTEQconst)
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTEQshiftRLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TEQshiftRLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TEQconst [c] (SRL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTEQconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TEQshiftRLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TEQshiftRL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTEQshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTST_0(v *Value) bool {
+	// match: (TST x (MOVWconst [c]))
+	// cond:
+	// result: (TSTconst [c] x)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (TST (MOVWconst [c]) x)
+	// cond:
+	// result: (TSTconst [c] x)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v.AddArg(x)
+		return true
+	}
+	// match: (TST x (SLLconst [c] y))
+	// cond:
+	// result: (TSTshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTSTshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST (SLLconst [c] y) x)
+	// cond:
+	// result: (TSTshiftLL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST x (SRLconst [c] y))
+	// cond:
+	// result: (TSTshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRLconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTSTshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST (SRLconst [c] y) x)
+	// cond:
+	// result: (TSTshiftRL x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRLconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST x (SRAconst [c] y))
+	// cond:
+	// result: (TSTshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRAconst {
+			break
+		}
+		c := v_1.AuxInt
+		y := v_1.Args[0]
+		v.reset(OpARMTSTshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST (SRAconst [c] y) x)
+	// cond:
+	// result: (TSTshiftRA x y [c])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRAconst {
+			break
+		}
+		c := v_0.AuxInt
+		y := v_0.Args[0]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (TST x (SLL y z))
+	// cond:
+	// result: (TSTshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSLL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTSTshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TST (SLL y z) x)
+	// cond:
+	// result: (TSTshiftLLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSLL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftLLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTST_10(v *Value) bool {
+	// match: (TST x (SRL y z))
+	// cond:
+	// result: (TSTshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRL {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTSTshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TST (SRL y z) x)
+	// cond:
+	// result: (TSTshiftRLreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRL {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftRLreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TST x (SRA y z))
+	// cond:
+	// result: (TSTshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMSRA {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		z := v_1.Args[1]
+		v.reset(OpARMTSTshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	// match: (TST (SRA y z) x)
+	// cond:
+	// result: (TSTshiftRAreg x y z)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMSRA {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		z := v_0.Args[1]
+		x := v.Args[1]
+		v.reset(OpARMTSTshiftRAreg)
+		v.AddArg(x)
+		v.AddArg(y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTconst_0(v *Value) bool {
+	// match: (TSTconst (MOVWconst [x]) [y])
+	// cond: int32(x&y)==0
+	// result: (FlagEQ)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x&y) == 0) {
+			break
+		}
+		v.reset(OpARMFlagEQ)
+		return true
+	}
+	// match: (TSTconst (MOVWconst [x]) [y])
+	// cond: int32(x&y)<0
+	// result: (FlagLT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x&y) < 0) {
+			break
+		}
+		v.reset(OpARMFlagLT_UGT)
+		return true
+	}
+	// match: (TSTconst (MOVWconst [x]) [y])
+	// cond: int32(x&y)>0
+	// result: (FlagGT_UGT)
+	for {
+		y := v.AuxInt
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		x := v_0.AuxInt
+		if !(int32(x&y) > 0) {
+			break
+		}
+		v.reset(OpARMFlagGT_UGT)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftLL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftLL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TSTconst [c] (SLLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftLL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TSTconst x [int64(int32(uint32(c)<<uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTSTconst)
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftLLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftLLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TSTconst [c] (SLL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftLLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TSTshiftLL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTSTshiftLL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftRA_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftRA (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TSTconst [c] (SRAconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftRA x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TSTconst x [int64(int32(c)>>uint64(d))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTSTconst)
+		v.AuxInt = int64(int32(c) >> uint64(d))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftRAreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftRAreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TSTconst [c] (SRA <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftRAreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TSTshiftRA x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTSTshiftRA)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftRL_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftRL (MOVWconst [c]) x [d])
+	// cond:
+	// result: (TSTconst [c] (SRLconst <x.Type> x [d]))
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type)
+		v0.AuxInt = d
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftRL x (MOVWconst [c]) [d])
+	// cond:
+	// result: (TSTconst x [int64(int32(uint32(c)>>uint64(d)))])
+	for {
+		d := v.AuxInt
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpARMTSTconst)
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueARM_OpARMTSTshiftRLreg_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (TSTshiftRLreg (MOVWconst [c]) x y)
+	// cond:
+	// result: (TSTconst [c] (SRL <x.Type> x y))
+	for {
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_0.AuxInt
+		x := v.Args[1]
+		y := v.Args[2]
+		v.reset(OpARMTSTconst)
+		v.AuxInt = c
+		v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type)
+		v0.AddArg(x)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (TSTshiftRLreg x y (MOVWconst [c]))
+	// cond:
+	// result: (TSTshiftRL x y [c])
+	for {
+		_ = v.Args[2]
+		x := v.Args[0]
+		y := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpARMMOVWconst {
+			break
+		}
+		c := v_2.AuxInt
+		v.reset(OpARMTSTshiftRL)
+		v.AuxInt = c
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMXOR_0(v *Value) bool {
 	// match: (XOR x (MOVWconst [c]))
 	// cond:
@@ -13643,7 +17134,7 @@
 	}
 	// match: (XORshiftLL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (XORconst x [int64(uint32(c)<<uint64(d))])
+	// result: (XORconst x [int64(int32(uint32(c)<<uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -13654,7 +17145,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMXORconst)
-		v.AuxInt = int64(uint32(c) << uint64(d))
+		v.AuxInt = int64(int32(uint32(c) << uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -13879,7 +17370,7 @@
 	}
 	// match: (XORshiftRL x (MOVWconst [c]) [d])
 	// cond:
-	// result: (XORconst x [int64(uint32(c)>>uint64(d))])
+	// result: (XORconst x [int64(int32(uint32(c)>>uint64(d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -13890,7 +17381,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMXORconst)
-		v.AuxInt = int64(uint32(c) >> uint64(d))
+		v.AuxInt = int64(int32(uint32(c) >> uint64(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -14008,7 +17499,7 @@
 	}
 	// match: (XORshiftRR x (MOVWconst [c]) [d])
 	// cond:
-	// result: (XORconst x [int64(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
+	// result: (XORconst x [int64(int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d)))])
 	for {
 		d := v.AuxInt
 		_ = v.Args[1]
@@ -14019,7 +17510,7 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpARMXORconst)
-		v.AuxInt = int64(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d))
+		v.AuxInt = int64(int32(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d)))
 		v.AddArg(x)
 		return true
 	}
@@ -15094,6 +18585,15 @@
 		return true
 	}
 }
+func rewriteValueARM_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpARMLoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueARM_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -18583,6 +22083,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT_ULT) yes no)
@@ -18595,6 +22096,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18608,6 +22110,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18621,6 +22124,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18634,6 +22138,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18648,6 +22153,883 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMEQ
 			b.SetControl(cmp)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUB x y)) yes no)
+		// cond:
+		// result: (EQ (CMP x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUB {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBconst [c] x)) yes no)
+		// cond:
+		// result: (EQ (CMPconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftLL x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMPshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftRL x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMPshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftRA x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMPshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMPshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMPshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (SUBshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMPshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADD x y)) yes no)
+		// cond:
+		// result: (EQ (CMN x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADD {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDconst [c] x)) yes no)
+		// cond:
+		// result: (EQ (CMNconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftLL x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMNshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftRL x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMNshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftRA x y [c])) yes no)
+		// cond:
+		// result: (EQ (CMNshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMNshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMNshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ADDshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (EQ (CMNshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (AND x y)) yes no)
+		// cond:
+		// result: (EQ (TST x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMAND {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDconst [c] x)) yes no)
+		// cond:
+		// result: (EQ (TSTconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftLL x y [c])) yes no)
+		// cond:
+		// result: (EQ (TSTshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftRL x y [c])) yes no)
+		// cond:
+		// result: (EQ (TSTshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftRA x y [c])) yes no)
+		// cond:
+		// result: (EQ (TSTshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TSTshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TSTshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (ANDshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TSTshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XOR x y)) yes no)
+		// cond:
+		// result: (EQ (TEQ x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXOR {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORconst [c] x)) yes no)
+		// cond:
+		// result: (EQ (TEQconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftLL x y [c])) yes no)
+		// cond:
+		// result: (EQ (TEQshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftRL x y [c])) yes no)
+		// cond:
+		// result: (EQ (TEQshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftRA x y [c])) yes no)
+		// cond:
+		// result: (EQ (TEQshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TEQshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TEQshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (EQ (CMPconst [0] (XORshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (EQ (TEQshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMEQ
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMGE:
@@ -18661,6 +23043,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT_ULT) yes no)
@@ -18673,6 +23056,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18686,6 +23070,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18699,6 +23084,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagGT_UGT) yes no)
@@ -18711,6 +23097,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (InvertFlags cmp) yes no)
@@ -18724,6 +23111,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMLE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMGT:
@@ -18737,6 +23125,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18750,6 +23139,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18763,6 +23153,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -18776,6 +23167,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagGT_UGT) yes no)
@@ -18788,6 +23180,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (InvertFlags cmp) yes no)
@@ -18801,6 +23194,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMLT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -18815,6 +23209,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMEQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (NotEqual cc) yes no)
@@ -18828,6 +23223,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMNE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessThan cc) yes no)
@@ -18841,6 +23237,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMLT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessThanU cc) yes no)
@@ -18854,6 +23251,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMULT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessEqual cc) yes no)
@@ -18867,6 +23265,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMLE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessEqualU cc) yes no)
@@ -18880,6 +23279,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMULE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterThan cc) yes no)
@@ -18893,6 +23293,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterThanU cc) yes no)
@@ -18906,6 +23307,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMUGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterEqual cc) yes no)
@@ -18919,6 +23321,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterEqualU cc) yes no)
@@ -18932,6 +23335,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARMUGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -18946,6 +23350,7 @@
 			v0.AuxInt = 0
 			v0.AddArg(cond)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMLE:
@@ -18959,6 +23364,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_ULT) yes no)
@@ -18971,6 +23377,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_UGT) yes no)
@@ -18983,6 +23390,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT_ULT) yes no)
@@ -18995,6 +23403,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19008,6 +23417,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19022,6 +23432,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMLT:
@@ -19035,6 +23446,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19048,6 +23460,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagLT_UGT) yes no)
@@ -19060,6 +23473,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT_ULT) yes no)
@@ -19072,6 +23486,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19085,6 +23500,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19099,6 +23515,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMNE:
@@ -19120,6 +23537,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMEQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (NotEqual cc)) yes no)
@@ -19140,6 +23558,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMNE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (LessThan cc)) yes no)
@@ -19160,6 +23579,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMLT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (LessThanU cc)) yes no)
@@ -19180,6 +23600,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMULT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (LessEqual cc)) yes no)
@@ -19200,6 +23621,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMLE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (LessEqualU cc)) yes no)
@@ -19220,6 +23642,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMULE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (GreaterThan cc)) yes no)
@@ -19240,6 +23663,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (GreaterThanU cc)) yes no)
@@ -19260,6 +23684,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMUGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (GreaterEqual cc)) yes no)
@@ -19280,6 +23705,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (GreaterEqualU cc)) yes no)
@@ -19300,6 +23726,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockARMUGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -19312,6 +23739,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19325,6 +23753,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagLT_UGT) yes no)
@@ -19337,6 +23766,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_ULT) yes no)
@@ -19349,6 +23779,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_UGT) yes no)
@@ -19361,6 +23792,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -19374,6 +23806,883 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMNE
 			b.SetControl(cmp)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUB x y)) yes no)
+		// cond:
+		// result: (NE (CMP x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUB {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBconst [c] x)) yes no)
+		// cond:
+		// result: (NE (CMPconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftLL x y [c])) yes no)
+		// cond:
+		// result: (NE (CMPshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftRL x y [c])) yes no)
+		// cond:
+		// result: (NE (CMPshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftRA x y [c])) yes no)
+		// cond:
+		// result: (NE (CMPshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMPshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMPshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (SUBshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMPshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMSUBshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADD x y)) yes no)
+		// cond:
+		// result: (NE (CMN x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADD {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDconst [c] x)) yes no)
+		// cond:
+		// result: (NE (CMNconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftLL x y [c])) yes no)
+		// cond:
+		// result: (NE (CMNshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftRL x y [c])) yes no)
+		// cond:
+		// result: (NE (CMNshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftRA x y [c])) yes no)
+		// cond:
+		// result: (NE (CMNshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMNshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMNshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ADDshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (NE (CMNshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMADDshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (AND x y)) yes no)
+		// cond:
+		// result: (NE (TST x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMAND {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDconst [c] x)) yes no)
+		// cond:
+		// result: (NE (TSTconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftLL x y [c])) yes no)
+		// cond:
+		// result: (NE (TSTshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftRL x y [c])) yes no)
+		// cond:
+		// result: (NE (TSTshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftRA x y [c])) yes no)
+		// cond:
+		// result: (NE (TSTshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (NE (TSTshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (NE (TSTshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (ANDshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (NE (TSTshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMANDshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XOR x y)) yes no)
+		// cond:
+		// result: (NE (TEQ x y) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXOR {
+				break
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORconst [c] x)) yes no)
+		// cond:
+		// result: (NE (TEQconst [c] x) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORconst {
+				break
+			}
+			c := v_0.AuxInt
+			x := v_0.Args[0]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftLL x y [c])) yes no)
+		// cond:
+		// result: (NE (TEQshiftLL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftLL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftRL x y [c])) yes no)
+		// cond:
+		// result: (NE (TEQshiftRL x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRL {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftRA x y [c])) yes no)
+		// cond:
+		// result: (NE (TEQshiftRA x y [c]) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRA {
+				break
+			}
+			c := v_0.AuxInt
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+			v0.AuxInt = c
+			v0.AddArg(x)
+			v0.AddArg(y)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftLLreg x y z)) yes no)
+		// cond:
+		// result: (NE (TEQshiftLLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftLLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftRLreg x y z)) yes no)
+		// cond:
+		// result: (NE (TEQshiftRLreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRLreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
+			return true
+		}
+		// match: (NE (CMPconst [0] (XORshiftRAreg x y z)) yes no)
+		// cond:
+		// result: (NE (TEQshiftRAreg x y z) yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARMCMPconst {
+				break
+			}
+			if v.AuxInt != 0 {
+				break
+			}
+			v_0 := v.Args[0]
+			if v_0.Op != OpARMXORshiftRAreg {
+				break
+			}
+			_ = v_0.Args[2]
+			x := v_0.Args[0]
+			y := v_0.Args[1]
+			z := v_0.Args[2]
+			b.Kind = BlockARMNE
+			v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+			v0.AddArg(x)
+			v0.AddArg(y)
+			v0.AddArg(z)
+			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMUGE:
@@ -19387,6 +24696,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagLT_ULT) yes no)
@@ -19399,6 +24709,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19412,6 +24723,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagGT_ULT) yes no)
@@ -19424,6 +24736,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19437,6 +24750,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (InvertFlags cmp) yes no)
@@ -19450,6 +24764,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMUGT:
@@ -19463,6 +24778,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19476,6 +24792,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19489,6 +24806,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagGT_ULT) yes no)
@@ -19501,6 +24819,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19514,6 +24833,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (InvertFlags cmp) yes no)
@@ -19527,6 +24847,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMULE:
@@ -19540,6 +24861,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_ULT) yes no)
@@ -19552,6 +24874,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_UGT) yes no)
@@ -19564,6 +24887,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19577,6 +24901,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagGT_UGT) yes no)
@@ -19589,6 +24914,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19603,6 +24929,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMUGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARMULT:
@@ -19616,6 +24943,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19629,6 +24957,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagLT_UGT) yes no)
@@ -19641,6 +24970,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19654,6 +24984,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagGT_UGT) yes no)
@@ -19666,6 +24997,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -19680,6 +25012,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARMUGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	}
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index 2be3d11..1cb8de8 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -129,6 +129,8 @@
 		return rewriteValueARM64_OpARM64MOVHstore_0(v)
 	case OpARM64MOVHstorezero:
 		return rewriteValueARM64_OpARM64MOVHstorezero_0(v)
+	case OpARM64MOVQstorezero:
+		return rewriteValueARM64_OpARM64MOVQstorezero_0(v)
 	case OpARM64MOVWUload:
 		return rewriteValueARM64_OpARM64MOVWUload_0(v)
 	case OpARM64MOVWUreg:
@@ -173,6 +175,8 @@
 		return rewriteValueARM64_OpARM64SRL_0(v)
 	case OpARM64SRLconst:
 		return rewriteValueARM64_OpARM64SRLconst_0(v)
+	case OpARM64STP:
+		return rewriteValueARM64_OpARM64STP_0(v)
 	case OpARM64SUB:
 		return rewriteValueARM64_OpARM64SUB_0(v)
 	case OpARM64SUBconst:
@@ -395,6 +399,8 @@
 		return rewriteValueARM64_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueARM64_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValueARM64_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueARM64_OpGetClosurePtr_0(v)
 	case OpGreater16:
@@ -704,7 +710,7 @@
 	case OpXor8:
 		return rewriteValueARM64_OpXor8_0(v)
 	case OpZero:
-		return rewriteValueARM64_OpZero_0(v) || rewriteValueARM64_OpZero_10(v)
+		return rewriteValueARM64_OpZero_0(v) || rewriteValueARM64_OpZero_10(v) || rewriteValueARM64_OpZero_20(v)
 	case OpZeroExt16to32:
 		return rewriteValueARM64_OpZeroExt16to32_0(v)
 	case OpZeroExt16to64:
@@ -3790,6 +3796,18 @@
 		v.AuxInt = int64(uint8(c))
 		return true
 	}
+	// match: (MOVBUreg x)
+	// cond: x.Type.IsBoolean()
+	// result: (MOVDreg x)
+	for {
+		x := v.Args[0]
+		if !(x.Type.IsBoolean()) {
+			break
+		}
+		v.reset(OpARM64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64MOVBload_0(v *Value) bool {
@@ -4971,6 +4989,62 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpARM64MOVQstorezero_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
+	// cond: is32Bit(off1+off2) 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// result: (MOVQstorezero [off1+off2] {sym} ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARM64ADDconst {
+			break
+		}
+		off2 := v_0.AuxInt
+		ptr := v_0.Args[0]
+		mem := v.Args[1]
+		if !(is32Bit(off1+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+			break
+		}
+		v.reset(OpARM64MOVQstorezero)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARM64MOVDaddr {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		ptr := v_0.Args[0]
+		mem := v.Args[1]
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+			break
+		}
+		v.reset(OpARM64MOVQstorezero)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpARM64MOVWUload_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -9162,6 +9236,100 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpARM64STP_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem)
+	// cond: is32Bit(off1+off2) 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// result: (STP [off1+off2] {sym} ptr val1 val2 mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[3]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARM64ADDconst {
+			break
+		}
+		off2 := v_0.AuxInt
+		ptr := v_0.Args[0]
+		val1 := v.Args[1]
+		val2 := v.Args[2]
+		mem := v.Args[3]
+		if !(is32Bit(off1+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+			break
+		}
+		v.reset(OpARM64STP)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(val1)
+		v.AddArg(val2)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// result: (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[3]
+		v_0 := v.Args[0]
+		if v_0.Op != OpARM64MOVDaddr {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		ptr := v_0.Args[0]
+		val1 := v.Args[1]
+		val2 := v.Args[2]
+		mem := v.Args[3]
+		if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+			break
+		}
+		v.reset(OpARM64STP)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(val1)
+		v.AddArg(val2)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (STP [off] {sym} ptr (MOVDconst [0]) (MOVDconst [0]) mem)
+	// cond:
+	// result: (MOVQstorezero [off] {sym} ptr mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpARM64MOVDconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		v_2 := v.Args[2]
+		if v_2.Op != OpARM64MOVDconst {
+			break
+		}
+		if v_2.AuxInt != 0 {
+			break
+		}
+		mem := v.Args[3]
+		v.reset(OpARM64MOVQstorezero)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpARM64SUB_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -11680,6 +11848,15 @@
 		return true
 	}
 }
+func rewriteValueARM64_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpARM64LoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueARM64_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -12609,7 +12786,7 @@
 	_ = typ
 	// match: (Lsh16x16 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12622,7 +12799,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12641,7 +12818,7 @@
 	_ = typ
 	// match: (Lsh16x32 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12654,7 +12831,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12669,45 +12846,9 @@
 func rewriteValueARM64_OpLsh16x64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Lsh16x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 16
-	// result: (SLLconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 16) {
-			break
-		}
-		v.reset(OpARM64SLLconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Lsh16x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 16
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 16) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Lsh16x64 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12718,7 +12859,7 @@
 		v0.AddArg(x)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v1.AuxInt = 0
 		v.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12735,7 +12876,7 @@
 	_ = typ
 	// match: (Lsh16x8 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12748,7 +12889,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12767,7 +12908,7 @@
 	_ = typ
 	// match: (Lsh32x16 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12780,7 +12921,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12799,7 +12940,7 @@
 	_ = typ
 	// match: (Lsh32x32 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12812,7 +12953,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12827,45 +12968,9 @@
 func rewriteValueARM64_OpLsh32x64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Lsh32x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 32
-	// result: (SLLconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 32) {
-			break
-		}
-		v.reset(OpARM64SLLconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Lsh32x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 32
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 32) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Lsh32x64 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12876,7 +12981,7 @@
 		v0.AddArg(x)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v1.AuxInt = 0
 		v.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12893,7 +12998,7 @@
 	_ = typ
 	// match: (Lsh32x8 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12906,7 +13011,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12925,7 +13030,7 @@
 	_ = typ
 	// match: (Lsh64x16 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12938,7 +13043,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12957,7 +13062,7 @@
 	_ = typ
 	// match: (Lsh64x32 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -12970,7 +13075,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -12985,45 +13090,9 @@
 func rewriteValueARM64_OpLsh64x64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Lsh64x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 64
-	// result: (SLLconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 64) {
-			break
-		}
-		v.reset(OpARM64SLLconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Lsh64x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 64
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 64) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Lsh64x64 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13034,7 +13103,7 @@
 		v0.AddArg(x)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v1.AuxInt = 0
 		v.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -13051,7 +13120,7 @@
 	_ = typ
 	// match: (Lsh64x8 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13064,7 +13133,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -13083,7 +13152,7 @@
 	_ = typ
 	// match: (Lsh8x16 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13096,7 +13165,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -13115,7 +13184,7 @@
 	_ = typ
 	// match: (Lsh8x32 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13128,7 +13197,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -13143,45 +13212,9 @@
 func rewriteValueARM64_OpLsh8x64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Lsh8x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 8
-	// result: (SLLconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 8) {
-			break
-		}
-		v.reset(OpARM64SLLconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Lsh8x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 8
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 8) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Lsh8x64 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SLL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13192,7 +13225,7 @@
 		v0.AddArg(x)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v1.AuxInt = 0
 		v.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -13209,7 +13242,7 @@
 	_ = typ
 	// match: (Lsh8x8 <t> x y)
 	// cond:
-	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SLL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -13222,7 +13255,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14242,7 +14275,7 @@
 	_ = typ
 	// match: (Rsh16Ux16 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14257,7 +14290,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14276,7 +14309,7 @@
 	_ = typ
 	// match: (Rsh16Ux32 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14291,7 +14324,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14308,47 +14341,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh16Ux64 x (MOVDconst [c]))
-	// cond: uint64(c) < 16
-	// result: (SRLconst (ZeroExt16to64 x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 16) {
-			break
-		}
-		v.reset(OpARM64SRLconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh16Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 16
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 16) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Rsh16Ux64 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14361,7 +14356,7 @@
 		v0.AddArg(v1)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14378,7 +14373,7 @@
 	_ = typ
 	// match: (Rsh16Ux8 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14393,7 +14388,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14412,7 +14407,7 @@
 	_ = typ
 	// match: (Rsh16x16 x y)
 	// cond:
-	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14425,7 +14420,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14445,7 +14440,7 @@
 	_ = typ
 	// match: (Rsh16x32 x y)
 	// cond:
-	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14458,7 +14453,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14476,51 +14471,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh16x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 16
-	// result: (SRAconst (SignExt16to64 x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 16) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh16x64 x (MOVDconst [c]))
-	// cond: uint64(c) >= 16
-	// result: (SRAconst (SignExt16to64 x) [63])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 16) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = 63
-		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh16x64 x y)
 	// cond:
-	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14531,7 +14484,7 @@
 		v.AddArg(v0)
 		v1 := b.NewValue0(v.Pos, OpARM64CSELULT, y.Type)
 		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14549,7 +14502,7 @@
 	_ = typ
 	// match: (Rsh16x8 x y)
 	// cond:
-	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+	// result: (SRA (SignExt16to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14562,7 +14515,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14582,7 +14535,7 @@
 	_ = typ
 	// match: (Rsh32Ux16 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14597,7 +14550,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14616,7 +14569,7 @@
 	_ = typ
 	// match: (Rsh32Ux32 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14631,7 +14584,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14648,47 +14601,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh32Ux64 x (MOVDconst [c]))
-	// cond: uint64(c) < 32
-	// result: (SRLconst (ZeroExt32to64 x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 32) {
-			break
-		}
-		v.reset(OpARM64SRLconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh32Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 32
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 32) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Rsh32Ux64 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14701,7 +14616,7 @@
 		v0.AddArg(v1)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14718,7 +14633,7 @@
 	_ = typ
 	// match: (Rsh32Ux8 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14733,7 +14648,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14752,7 +14667,7 @@
 	_ = typ
 	// match: (Rsh32x16 x y)
 	// cond:
-	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14765,7 +14680,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14785,7 +14700,7 @@
 	_ = typ
 	// match: (Rsh32x32 x y)
 	// cond:
-	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14798,7 +14713,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14816,51 +14731,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh32x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 32
-	// result: (SRAconst (SignExt32to64 x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 32) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh32x64 x (MOVDconst [c]))
-	// cond: uint64(c) >= 32
-	// result: (SRAconst (SignExt32to64 x) [63])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 32) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = 63
-		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh32x64 x y)
 	// cond:
-	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14871,7 +14744,7 @@
 		v.AddArg(v0)
 		v1 := b.NewValue0(v.Pos, OpARM64CSELULT, y.Type)
 		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14889,7 +14762,7 @@
 	_ = typ
 	// match: (Rsh32x8 x y)
 	// cond:
-	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+	// result: (SRA (SignExt32to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -14902,7 +14775,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14922,7 +14795,7 @@
 	_ = typ
 	// match: (Rsh64Ux16 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SRL <t> x (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14935,7 +14808,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14954,7 +14827,7 @@
 	_ = typ
 	// match: (Rsh64Ux32 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SRL <t> x (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -14967,7 +14840,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -14982,45 +14855,9 @@
 func rewriteValueARM64_OpRsh64Ux64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Rsh64Ux64 x (MOVDconst [c]))
-	// cond: uint64(c) < 64
-	// result: (SRLconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 64) {
-			break
-		}
-		v.reset(OpARM64SRLconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Rsh64Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 64
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 64) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Rsh64Ux64 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SRL <t> x y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15031,7 +14868,7 @@
 		v0.AddArg(x)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v1.AuxInt = 0
 		v.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15048,7 +14885,7 @@
 	_ = typ
 	// match: (Rsh64Ux8 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SRL <t> x (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15061,7 +14898,7 @@
 		v1.AddArg(y)
 		v0.AddArg(v1)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15080,7 +14917,7 @@
 	_ = typ
 	// match: (Rsh64x16 x y)
 	// cond:
-	// result: (SRA x (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// result: (SRA x (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15091,7 +14928,7 @@
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v1.AddArg(y)
 		v0.AddArg(v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v0.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15111,7 +14948,7 @@
 	_ = typ
 	// match: (Rsh64x32 x y)
 	// cond:
-	// result: (SRA x (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// result: (SRA x (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15122,7 +14959,7 @@
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v1.AddArg(y)
 		v0.AddArg(v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v0.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15138,47 +14975,9 @@
 func rewriteValueARM64_OpRsh64x64_0(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Rsh64x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 64
-	// result: (SRAconst x [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 64) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = c
-		v.AddArg(x)
-		return true
-	}
-	// match: (Rsh64x64 x (MOVDconst [c]))
-	// cond: uint64(c) >= 64
-	// result: (SRAconst x [63])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 64) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = 63
-		v.AddArg(x)
-		return true
-	}
 	// match: (Rsh64x64 x y)
 	// cond:
-	// result: (SRA x (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+	// result: (SRA x (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15187,7 +14986,7 @@
 		v.AddArg(x)
 		v0 := b.NewValue0(v.Pos, OpARM64CSELULT, y.Type)
 		v0.AddArg(y)
-		v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v1.AuxInt = 63
 		v0.AddArg(v1)
 		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15205,7 +15004,7 @@
 	_ = typ
 	// match: (Rsh64x8 x y)
 	// cond:
-	// result: (SRA x (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+	// result: (SRA x (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15216,7 +15015,7 @@
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v1.AddArg(y)
 		v0.AddArg(v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v0.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15236,7 +15035,7 @@
 	_ = typ
 	// match: (Rsh8Ux16 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15251,7 +15050,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15270,7 +15069,7 @@
 	_ = typ
 	// match: (Rsh8Ux32 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15285,7 +15084,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15302,47 +15101,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh8Ux64 x (MOVDconst [c]))
-	// cond: uint64(c) < 8
-	// result: (SRLconst (ZeroExt8to64  x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 8) {
-			break
-		}
-		v.reset(OpARM64SRLconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh8Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 8
-	// result: (MOVDconst [0])
-	for {
-		_ = v.Args[1]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 8) {
-			break
-		}
-		v.reset(OpARM64MOVDconst)
-		v.AuxInt = 0
-		return true
-	}
 	// match: (Rsh8Ux64 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) y) (MOVDconst <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15355,7 +15116,7 @@
 		v0.AddArg(v1)
 		v0.AddArg(y)
 		v.AddArg(v0)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v2.AuxInt = 0
 		v.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15372,7 +15133,7 @@
 	_ = typ
 	// match: (Rsh8Ux8 <t> x y)
 	// cond:
-	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+	// result: (CSELULT (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64  y)) (MOVDconst <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -15387,7 +15148,7 @@
 		v2.AddArg(y)
 		v0.AddArg(v2)
 		v.AddArg(v0)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, t)
 		v3.AuxInt = 0
 		v.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15406,7 +15167,7 @@
 	_ = typ
 	// match: (Rsh8x16 x y)
 	// cond:
-	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt16to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15419,7 +15180,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15439,7 +15200,7 @@
 	_ = typ
 	// match: (Rsh8x32 x y)
 	// cond:
-	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt32to64 y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15452,7 +15213,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15470,51 +15231,9 @@
 	_ = b
 	typ := &b.Func.Config.Types
 	_ = typ
-	// match: (Rsh8x64 x (MOVDconst [c]))
-	// cond: uint64(c) < 8
-	// result: (SRAconst (SignExt8to64  x) [c])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) < 8) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = c
-		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Rsh8x64 x (MOVDconst [c]))
-	// cond: uint64(c) >= 8
-	// result: (SRAconst (SignExt8to64  x) [63])
-	for {
-		_ = v.Args[1]
-		x := v.Args[0]
-		v_1 := v.Args[1]
-		if v_1.Op != OpARM64MOVDconst {
-			break
-		}
-		c := v_1.AuxInt
-		if !(uint64(c) >= 8) {
-			break
-		}
-		v.reset(OpARM64SRAconst)
-		v.AuxInt = 63
-		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh8x64 x y)
 	// cond:
-	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> y (MOVDconst <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15525,7 +15244,7 @@
 		v.AddArg(v0)
 		v1 := b.NewValue0(v.Pos, OpARM64CSELULT, y.Type)
 		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v2.AuxInt = 63
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -15543,7 +15262,7 @@
 	_ = typ
 	// match: (Rsh8x8 x y)
 	// cond:
-	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+	// result: (SRA (SignExt8to64 x) (CSELULT <y.Type> (ZeroExt8to64  y) (MOVDconst <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -15556,7 +15275,7 @@
 		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v2.AddArg(y)
 		v1.AddArg(v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, y.Type)
 		v3.AuxInt = 63
 		v1.AddArg(v3)
 		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -16213,6 +15932,95 @@
 		v.AddArg(v1)
 		return true
 	}
+	// match: (Zero [9] ptr mem)
+	// cond:
+	// result: (MOVBstore [8] ptr (MOVDconst [0]) 		(MOVDstore ptr (MOVDconst [0]) mem))
+	for {
+		if v.AuxInt != 9 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64MOVBstore)
+		v.AuxInt = 8
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg(ptr)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v2.AuxInt = 0
+		v1.AddArg(v2)
+		v1.AddArg(mem)
+		v.AddArg(v1)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpZero_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (Zero [10] ptr mem)
+	// cond:
+	// result: (MOVHstore [8] ptr (MOVDconst [0]) 		(MOVDstore ptr (MOVDconst [0]) mem))
+	for {
+		if v.AuxInt != 10 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64MOVHstore)
+		v.AuxInt = 8
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg(ptr)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v2.AuxInt = 0
+		v1.AddArg(v2)
+		v1.AddArg(mem)
+		v.AddArg(v1)
+		return true
+	}
+	// match: (Zero [11] ptr mem)
+	// cond:
+	// result: (MOVBstore [10] ptr (MOVDconst [0]) 		(MOVHstore [8] ptr (MOVDconst [0]) 			(MOVDstore ptr (MOVDconst [0]) mem)))
+	for {
+		if v.AuxInt != 11 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64MOVBstore)
+		v.AuxInt = 10
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
+		v1.AuxInt = 8
+		v1.AddArg(ptr)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v2.AuxInt = 0
+		v1.AddArg(v2)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v3.AddArg(ptr)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v3.AddArg(v4)
+		v3.AddArg(mem)
+		v1.AddArg(v3)
+		v.AddArg(v1)
+		return true
+	}
 	// match: (Zero [12] ptr mem)
 	// cond:
 	// result: (MOVWstore [8] ptr (MOVDconst [0]) 		(MOVDstore ptr (MOVDconst [0]) mem))
@@ -16238,57 +16046,23 @@
 		v.AddArg(v1)
 		return true
 	}
-	return false
-}
-func rewriteValueARM64_OpZero_10(v *Value) bool {
-	b := v.Block
-	_ = b
-	config := b.Func.Config
-	_ = config
-	typ := &b.Func.Config.Types
-	_ = typ
-	// match: (Zero [16] ptr mem)
+	// match: (Zero [13] ptr mem)
 	// cond:
-	// result: (MOVDstore [8] ptr (MOVDconst [0]) 		(MOVDstore ptr (MOVDconst [0]) mem))
+	// result: (MOVBstore [12] ptr (MOVDconst [0]) 		(MOVWstore [8] ptr (MOVDconst [0]) 			(MOVDstore ptr (MOVDconst [0]) mem)))
 	for {
-		if v.AuxInt != 16 {
+		if v.AuxInt != 13 {
 			break
 		}
 		_ = v.Args[1]
 		ptr := v.Args[0]
 		mem := v.Args[1]
-		v.reset(OpARM64MOVDstore)
-		v.AuxInt = 8
+		v.reset(OpARM64MOVBstore)
+		v.AuxInt = 12
 		v.AddArg(ptr)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = 0
 		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v1.AddArg(ptr)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
-		v2.AuxInt = 0
-		v1.AddArg(v2)
-		v1.AddArg(mem)
-		v.AddArg(v1)
-		return true
-	}
-	// match: (Zero [24] ptr mem)
-	// cond:
-	// result: (MOVDstore [16] ptr (MOVDconst [0]) 		(MOVDstore [8] ptr (MOVDconst [0]) 			(MOVDstore ptr (MOVDconst [0]) mem)))
-	for {
-		if v.AuxInt != 24 {
-			break
-		}
-		_ = v.Args[1]
-		ptr := v.Args[0]
-		mem := v.Args[1]
-		v.reset(OpARM64MOVDstore)
-		v.AuxInt = 16
-		v.AddArg(ptr)
-		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
-		v0.AuxInt = 0
-		v.AddArg(v0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
 		v1.AuxInt = 8
 		v1.AddArg(ptr)
 		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
@@ -16304,62 +16078,288 @@
 		v.AddArg(v1)
 		return true
 	}
+	// match: (Zero [14] ptr mem)
+	// cond:
+	// result: (MOVHstore [12] ptr (MOVDconst [0]) 		(MOVWstore [8] ptr (MOVDconst [0]) 			(MOVDstore ptr (MOVDconst [0]) mem)))
+	for {
+		if v.AuxInt != 14 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64MOVHstore)
+		v.AuxInt = 12
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
+		v1.AuxInt = 8
+		v1.AddArg(ptr)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v2.AuxInt = 0
+		v1.AddArg(v2)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v3.AddArg(ptr)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v3.AddArg(v4)
+		v3.AddArg(mem)
+		v1.AddArg(v3)
+		v.AddArg(v1)
+		return true
+	}
+	// match: (Zero [15] ptr mem)
+	// cond:
+	// result: (MOVBstore [14] ptr (MOVDconst [0]) 		(MOVHstore [12] ptr (MOVDconst [0]) 			(MOVWstore [8] ptr (MOVDconst [0]) 				(MOVDstore ptr (MOVDconst [0]) mem))))
+	for {
+		if v.AuxInt != 15 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64MOVBstore)
+		v.AuxInt = 14
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
+		v1.AuxInt = 12
+		v1.AddArg(ptr)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v2.AuxInt = 0
+		v1.AddArg(v2)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
+		v3.AuxInt = 8
+		v3.AddArg(ptr)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v3.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v5.AddArg(ptr)
+		v6 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v6.AuxInt = 0
+		v5.AddArg(v6)
+		v5.AddArg(mem)
+		v3.AddArg(v5)
+		v1.AddArg(v3)
+		v.AddArg(v1)
+		return true
+	}
+	// match: (Zero [16] ptr mem)
+	// cond:
+	// result: (STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)
+	for {
+		if v.AuxInt != 16 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64STP)
+		v.AuxInt = 0
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (Zero [32] ptr mem)
+	// cond:
+	// result: (STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) 		(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))
+	for {
+		if v.AuxInt != 32 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64STP)
+		v.AuxInt = 16
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v2.AuxInt = 0
+		v2.AddArg(ptr)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v3.AuxInt = 0
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v2.AddArg(v4)
+		v2.AddArg(mem)
+		v.AddArg(v2)
+		return true
+	}
+	// match: (Zero [48] ptr mem)
+	// cond:
+	// result: (STP [32] ptr (MOVDconst [0]) (MOVDconst [0]) 		(STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) 			(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)))
+	for {
+		if v.AuxInt != 48 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64STP)
+		v.AuxInt = 32
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v2.AuxInt = 16
+		v2.AddArg(ptr)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v3.AuxInt = 0
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v2.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v5.AuxInt = 0
+		v5.AddArg(ptr)
+		v6 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v6.AuxInt = 0
+		v5.AddArg(v6)
+		v7 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v7.AuxInt = 0
+		v5.AddArg(v7)
+		v5.AddArg(mem)
+		v2.AddArg(v5)
+		v.AddArg(v2)
+		return true
+	}
+	// match: (Zero [64] ptr mem)
+	// cond:
+	// result: (STP [48] ptr (MOVDconst [0]) (MOVDconst [0]) 		(STP [32] ptr (MOVDconst [0]) (MOVDconst [0]) 			(STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) 				(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))))
+	for {
+		if v.AuxInt != 64 {
+			break
+		}
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpARM64STP)
+		v.AuxInt = 48
+		v.AddArg(ptr)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = 0
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v1.AuxInt = 0
+		v.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v2.AuxInt = 32
+		v2.AddArg(ptr)
+		v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v3.AuxInt = 0
+		v2.AddArg(v3)
+		v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v4.AuxInt = 0
+		v2.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v5.AuxInt = 16
+		v5.AddArg(ptr)
+		v6 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v6.AuxInt = 0
+		v5.AddArg(v6)
+		v7 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v7.AuxInt = 0
+		v5.AddArg(v7)
+		v8 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v8.AuxInt = 0
+		v8.AddArg(ptr)
+		v9 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v9.AuxInt = 0
+		v8.AddArg(v9)
+		v10 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v10.AuxInt = 0
+		v8.AddArg(v10)
+		v8.AddArg(mem)
+		v5.AddArg(v8)
+		v2.AddArg(v5)
+		v.AddArg(v2)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpZero_20(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (Zero [s] ptr mem)
-	// cond: s%8 != 0 && s > 8
-	// result: (Zero [s%8] 		(OffPtr <ptr.Type> ptr [s-s%8]) 		(Zero [s-s%8] ptr mem))
+	// cond: s%16 != 0 && s > 16
+	// result: (Zero [s-s%16] 		(OffPtr <ptr.Type> ptr [s%16]) 		(Zero [s%16] ptr mem))
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		ptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s%8 != 0 && s > 8) {
+		if !(s%16 != 0 && s > 16) {
 			break
 		}
 		v.reset(OpZero)
-		v.AuxInt = s % 8
+		v.AuxInt = s - s%16
 		v0 := b.NewValue0(v.Pos, OpOffPtr, ptr.Type)
-		v0.AuxInt = s - s%8
+		v0.AuxInt = s % 16
 		v0.AddArg(ptr)
 		v.AddArg(v0)
 		v1 := b.NewValue0(v.Pos, OpZero, types.TypeMem)
-		v1.AuxInt = s - s%8
+		v1.AuxInt = s % 16
 		v1.AddArg(ptr)
 		v1.AddArg(mem)
 		v.AddArg(v1)
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: s%8 == 0 && s > 24 && s <= 8*128 	&& !config.noDuffDevice
-	// result: (DUFFZERO [4 * (128 - int64(s/8))] ptr mem)
+	// cond: s%16 == 0 && s > 64 && s <= 16*64 	&& !config.noDuffDevice
+	// result: (DUFFZERO [4 * (64 - int64(s/16))] ptr mem)
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		ptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s%8 == 0 && s > 24 && s <= 8*128 && !config.noDuffDevice) {
+		if !(s%16 == 0 && s > 64 && s <= 16*64 && !config.noDuffDevice) {
 			break
 		}
 		v.reset(OpARM64DUFFZERO)
-		v.AuxInt = 4 * (128 - int64(s/8))
+		v.AuxInt = 4 * (64 - int64(s/16))
 		v.AddArg(ptr)
 		v.AddArg(mem)
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: s%8 == 0 && (s > 8*128 || config.noDuffDevice)
-	// result: (LoweredZero 		ptr 		(ADDconst <ptr.Type> [s-8] ptr) 		mem)
+	// cond: s%16 == 0 && (s > 16*64 || config.noDuffDevice)
+	// result: (LoweredZero 		ptr 		(ADDconst <ptr.Type> [s-16] ptr) 		mem)
 	for {
 		s := v.AuxInt
 		_ = v.Args[1]
 		ptr := v.Args[0]
 		mem := v.Args[1]
-		if !(s%8 == 0 && (s > 8*128 || config.noDuffDevice)) {
+		if !(s%16 == 0 && (s > 16*64 || config.noDuffDevice)) {
 			break
 		}
 		v.reset(OpARM64LoweredZero)
 		v.AddArg(ptr)
 		v0 := b.NewValue0(v.Pos, OpARM64ADDconst, ptr.Type)
-		v0.AuxInt = s - 8
+		v0.AuxInt = s - 16
 		v0.AddArg(ptr)
 		v.AddArg(v0)
 		v.AddArg(mem)
@@ -16456,6 +16456,7 @@
 			x := v.Args[0]
 			b.Kind = BlockARM64Z
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (CMPWconst [0] x) yes no)
@@ -16472,6 +16473,7 @@
 			x := v.Args[0]
 			b.Kind = BlockARM64ZW
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagEQ) yes no)
@@ -16484,6 +16486,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT_ULT) yes no)
@@ -16496,6 +16499,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16509,6 +16513,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16522,6 +16527,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16535,6 +16541,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16549,6 +16556,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64GE:
@@ -16562,6 +16570,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT_ULT) yes no)
@@ -16574,6 +16583,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16587,6 +16597,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16600,6 +16611,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagGT_UGT) yes no)
@@ -16612,6 +16624,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (InvertFlags cmp) yes no)
@@ -16625,6 +16638,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64GT:
@@ -16638,6 +16652,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16651,6 +16666,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16664,6 +16680,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16677,6 +16694,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagGT_UGT) yes no)
@@ -16689,6 +16707,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (InvertFlags cmp) yes no)
@@ -16702,6 +16721,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -16716,6 +16736,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64EQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (NotEqual cc) yes no)
@@ -16729,6 +16750,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64NE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessThan cc) yes no)
@@ -16742,6 +16764,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64LT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessThanU cc) yes no)
@@ -16755,6 +16778,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64ULT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessEqual cc) yes no)
@@ -16768,6 +16792,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64LE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessEqualU cc) yes no)
@@ -16781,6 +16806,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64ULE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterThan cc) yes no)
@@ -16794,6 +16820,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64GT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterThanU cc) yes no)
@@ -16807,6 +16834,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64UGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterEqual cc) yes no)
@@ -16820,6 +16848,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64GE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterEqualU cc) yes no)
@@ -16833,6 +16862,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64UGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -16844,6 +16874,7 @@
 			cond := b.Control
 			b.Kind = BlockARM64NZ
 			b.SetControl(cond)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64LE:
@@ -16857,6 +16888,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_ULT) yes no)
@@ -16869,6 +16901,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT_UGT) yes no)
@@ -16881,6 +16914,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT_ULT) yes no)
@@ -16893,6 +16927,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16906,6 +16941,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16920,6 +16956,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64LT:
@@ -16933,6 +16970,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16946,6 +16984,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagLT_UGT) yes no)
@@ -16958,6 +16997,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT_ULT) yes no)
@@ -16970,6 +17010,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16983,6 +17024,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -16997,6 +17039,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64NE:
@@ -17014,6 +17057,7 @@
 			x := v.Args[0]
 			b.Kind = BlockARM64NZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] x) yes no)
@@ -17030,6 +17074,7 @@
 			x := v.Args[0]
 			b.Kind = BlockARM64NZW
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -17042,6 +17087,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17055,6 +17101,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagLT_UGT) yes no)
@@ -17067,6 +17114,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_ULT) yes no)
@@ -17079,6 +17127,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT_UGT) yes no)
@@ -17091,6 +17140,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -17104,6 +17154,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64NZ:
@@ -17118,6 +17169,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64EQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (NotEqual cc) yes no)
@@ -17131,6 +17183,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64NE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (LessThan cc) yes no)
@@ -17144,6 +17197,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64LT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (LessThanU cc) yes no)
@@ -17157,6 +17211,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64ULT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (LessEqual cc) yes no)
@@ -17170,6 +17225,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64LE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (LessEqualU cc) yes no)
@@ -17183,6 +17239,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64ULE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (GreaterThan cc) yes no)
@@ -17196,6 +17253,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64GT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (GreaterThanU cc) yes no)
@@ -17209,6 +17267,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64UGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (GreaterEqual cc) yes no)
@@ -17222,6 +17281,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64GE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NZ (GreaterEqualU cc) yes no)
@@ -17235,6 +17295,25 @@
 			cc := v.Args[0]
 			b.Kind = BlockARM64UGE
 			b.SetControl(cc)
+			b.Aux = nil
+			return true
+		}
+		// match: (NZ (ANDconst [c] x) yes no)
+		// cond: oneBit(c)
+		// result: (TBNZ {ntz(c)} x yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARM64ANDconst {
+				break
+			}
+			c := v.AuxInt
+			x := v.Args[0]
+			if !(oneBit(c)) {
+				break
+			}
+			b.Kind = BlockARM64TBNZ
+			b.SetControl(x)
+			b.Aux = ntz(c)
 			return true
 		}
 		// match: (NZ (MOVDconst [0]) yes no)
@@ -17250,6 +17329,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17267,9 +17347,28 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64NZW:
+		// match: (NZW (ANDconst [c] x) yes no)
+		// cond: oneBit(int64(uint32(c)))
+		// result: (TBNZ {ntz(int64(uint32(c)))} x yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARM64ANDconst {
+				break
+			}
+			c := v.AuxInt
+			x := v.Args[0]
+			if !(oneBit(int64(uint32(c)))) {
+				break
+			}
+			b.Kind = BlockARM64TBNZ
+			b.SetControl(x)
+			b.Aux = ntz(int64(uint32(c)))
+			return true
+		}
 		// match: (NZW (MOVDconst [c]) yes no)
 		// cond: int32(c) == 0
 		// result: (First nil no yes)
@@ -17284,6 +17383,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17301,6 +17401,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64UGE:
@@ -17314,6 +17415,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagLT_ULT) yes no)
@@ -17326,6 +17428,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17339,6 +17442,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (FlagGT_ULT) yes no)
@@ -17351,6 +17455,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17364,6 +17469,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGE (InvertFlags cmp) yes no)
@@ -17377,6 +17483,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64ULE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64UGT:
@@ -17390,6 +17497,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17403,6 +17511,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17416,6 +17525,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (FlagGT_ULT) yes no)
@@ -17428,6 +17538,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17441,6 +17552,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (UGT (InvertFlags cmp) yes no)
@@ -17454,6 +17566,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64ULT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64ULE:
@@ -17467,6 +17580,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_ULT) yes no)
@@ -17479,6 +17593,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagLT_UGT) yes no)
@@ -17491,6 +17606,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17504,6 +17620,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULE (FlagGT_UGT) yes no)
@@ -17516,6 +17633,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17530,6 +17648,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64UGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64ULT:
@@ -17543,6 +17662,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17556,6 +17676,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagLT_UGT) yes no)
@@ -17568,6 +17689,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17581,6 +17703,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ULT (FlagGT_UGT) yes no)
@@ -17593,6 +17716,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -17607,9 +17731,28 @@
 			cmp := v.Args[0]
 			b.Kind = BlockARM64UGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockARM64Z:
+		// match: (Z (ANDconst [c] x) yes no)
+		// cond: oneBit(c)
+		// result: (TBZ  {ntz(c)} x yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARM64ANDconst {
+				break
+			}
+			c := v.AuxInt
+			x := v.Args[0]
+			if !(oneBit(c)) {
+				break
+			}
+			b.Kind = BlockARM64TBZ
+			b.SetControl(x)
+			b.Aux = ntz(c)
+			return true
+		}
 		// match: (Z (MOVDconst [0]) yes no)
 		// cond:
 		// result: (First nil yes no)
@@ -17623,6 +17766,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (Z (MOVDconst [c]) yes no)
@@ -17639,10 +17783,29 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
 	case BlockARM64ZW:
+		// match: (ZW (ANDconst [c] x) yes no)
+		// cond: oneBit(int64(uint32(c)))
+		// result: (TBZ  {ntz(int64(uint32(c)))} x yes no)
+		for {
+			v := b.Control
+			if v.Op != OpARM64ANDconst {
+				break
+			}
+			c := v.AuxInt
+			x := v.Args[0]
+			if !(oneBit(int64(uint32(c)))) {
+				break
+			}
+			b.Kind = BlockARM64TBZ
+			b.SetControl(x)
+			b.Aux = ntz(int64(uint32(c)))
+			return true
+		}
 		// match: (ZW (MOVDconst [c]) yes no)
 		// cond: int32(c) == 0
 		// result: (First nil yes no)
@@ -17657,6 +17820,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (ZW (MOVDconst [c]) yes no)
@@ -17673,6 +17837,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go
index 0874975..d4f4c03 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go
@@ -145,6 +145,8 @@
 		return rewriteValueMIPS_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueMIPS_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValueMIPS_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueMIPS_OpGetClosurePtr_0(v)
 	case OpGreater16:
@@ -1759,6 +1761,15 @@
 		return true
 	}
 }
+func rewriteValueMIPS_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpMIPSLoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueMIPS_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -9608,6 +9619,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPSFPF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FPFlagFalse cmp) yes no)
@@ -9621,6 +9633,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPSFPT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGT _ _)) yes no)
@@ -9641,6 +9654,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTU _ _)) yes no)
@@ -9661,6 +9675,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTconst _)) yes no)
@@ -9680,6 +9695,7 @@
 			}
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTUconst _)) yes no)
@@ -9699,6 +9715,7 @@
 			}
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTzero _)) yes no)
@@ -9718,6 +9735,7 @@
 			}
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTUzero _)) yes no)
@@ -9737,6 +9755,7 @@
 			}
 			b.Kind = BlockMIPSNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTUconst [1] x) yes no)
@@ -9753,6 +9772,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSNE
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTUzero x) yes no)
@@ -9766,6 +9786,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSEQ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTconst [0] x) yes no)
@@ -9782,6 +9803,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSGEZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTzero x) yes no)
@@ -9795,6 +9817,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSLEZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (MOVWconst [0]) yes no)
@@ -9810,6 +9833,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (MOVWconst [c]) yes no)
@@ -9826,6 +9850,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -9844,6 +9869,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GEZ (MOVWconst [c]) yes no)
@@ -9860,6 +9886,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -9878,6 +9905,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GTZ (MOVWconst [c]) yes no)
@@ -9894,6 +9922,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -9907,6 +9936,7 @@
 			cond := b.Control
 			b.Kind = BlockMIPSNE
 			b.SetControl(cond)
+			b.Aux = nil
 			return true
 		}
 	case BlockMIPSLEZ:
@@ -9924,6 +9954,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LEZ (MOVWconst [c]) yes no)
@@ -9940,6 +9971,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -9958,6 +9990,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LTZ (MOVWconst [c]) yes no)
@@ -9974,6 +10007,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -9989,6 +10023,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPSFPT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FPFlagFalse cmp) yes no)
@@ -10002,6 +10037,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPSFPF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGT _ _)) yes no)
@@ -10022,6 +10058,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTU _ _)) yes no)
@@ -10042,6 +10079,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTconst _)) yes no)
@@ -10061,6 +10099,7 @@
 			}
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTUconst _)) yes no)
@@ -10080,6 +10119,7 @@
 			}
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTzero _)) yes no)
@@ -10099,6 +10139,7 @@
 			}
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTUzero _)) yes no)
@@ -10118,6 +10159,7 @@
 			}
 			b.Kind = BlockMIPSEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTUconst [1] x) yes no)
@@ -10134,6 +10176,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSEQ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTUzero x) yes no)
@@ -10147,6 +10190,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSNE
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTconst [0] x) yes no)
@@ -10163,6 +10207,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSLTZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTzero x) yes no)
@@ -10176,6 +10221,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPSGTZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (MOVWconst [0]) yes no)
@@ -10191,6 +10237,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10208,6 +10255,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	}
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
index 82919a1..21265e3 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
@@ -41,6 +41,30 @@
 		return rewriteValueMIPS64_OpAnd8_0(v)
 	case OpAndB:
 		return rewriteValueMIPS64_OpAndB_0(v)
+	case OpAtomicAdd32:
+		return rewriteValueMIPS64_OpAtomicAdd32_0(v)
+	case OpAtomicAdd64:
+		return rewriteValueMIPS64_OpAtomicAdd64_0(v)
+	case OpAtomicCompareAndSwap32:
+		return rewriteValueMIPS64_OpAtomicCompareAndSwap32_0(v)
+	case OpAtomicCompareAndSwap64:
+		return rewriteValueMIPS64_OpAtomicCompareAndSwap64_0(v)
+	case OpAtomicExchange32:
+		return rewriteValueMIPS64_OpAtomicExchange32_0(v)
+	case OpAtomicExchange64:
+		return rewriteValueMIPS64_OpAtomicExchange64_0(v)
+	case OpAtomicLoad32:
+		return rewriteValueMIPS64_OpAtomicLoad32_0(v)
+	case OpAtomicLoad64:
+		return rewriteValueMIPS64_OpAtomicLoad64_0(v)
+	case OpAtomicLoadPtr:
+		return rewriteValueMIPS64_OpAtomicLoadPtr_0(v)
+	case OpAtomicStore32:
+		return rewriteValueMIPS64_OpAtomicStore32_0(v)
+	case OpAtomicStore64:
+		return rewriteValueMIPS64_OpAtomicStore64_0(v)
+	case OpAtomicStorePtrNoWB:
+		return rewriteValueMIPS64_OpAtomicStorePtrNoWB_0(v)
 	case OpAvg64u:
 		return rewriteValueMIPS64_OpAvg64u_0(v)
 	case OpClosureCall:
@@ -147,6 +171,8 @@
 		return rewriteValueMIPS64_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueMIPS64_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValueMIPS64_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueMIPS64_OpGetClosurePtr_0(v)
 	case OpGreater16:
@@ -267,6 +293,14 @@
 		return rewriteValueMIPS64_OpMIPS64AND_0(v)
 	case OpMIPS64ANDconst:
 		return rewriteValueMIPS64_OpMIPS64ANDconst_0(v)
+	case OpMIPS64LoweredAtomicAdd32:
+		return rewriteValueMIPS64_OpMIPS64LoweredAtomicAdd32_0(v)
+	case OpMIPS64LoweredAtomicAdd64:
+		return rewriteValueMIPS64_OpMIPS64LoweredAtomicAdd64_0(v)
+	case OpMIPS64LoweredAtomicStore32:
+		return rewriteValueMIPS64_OpMIPS64LoweredAtomicStore32_0(v)
+	case OpMIPS64LoweredAtomicStore64:
+		return rewriteValueMIPS64_OpMIPS64LoweredAtomicStore64_0(v)
 	case OpMIPS64MOVBUload:
 		return rewriteValueMIPS64_OpMIPS64MOVBUload_0(v)
 	case OpMIPS64MOVBUreg:
@@ -753,6 +787,196 @@
 		return true
 	}
 }
+func rewriteValueMIPS64_OpAtomicAdd32_0(v *Value) bool {
+	// match: (AtomicAdd32 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicAdd32 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicAdd32)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicAdd64_0(v *Value) bool {
+	// match: (AtomicAdd64 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicAdd64 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicAdd64)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicCompareAndSwap32_0(v *Value) bool {
+	// match: (AtomicCompareAndSwap32 ptr old new_ mem)
+	// cond:
+	// result: (LoweredAtomicCas32 ptr old new_ mem)
+	for {
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		old := v.Args[1]
+		new_ := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpMIPS64LoweredAtomicCas32)
+		v.AddArg(ptr)
+		v.AddArg(old)
+		v.AddArg(new_)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicCompareAndSwap64_0(v *Value) bool {
+	// match: (AtomicCompareAndSwap64 ptr old new_ mem)
+	// cond:
+	// result: (LoweredAtomicCas64 ptr old new_ mem)
+	for {
+		_ = v.Args[3]
+		ptr := v.Args[0]
+		old := v.Args[1]
+		new_ := v.Args[2]
+		mem := v.Args[3]
+		v.reset(OpMIPS64LoweredAtomicCas64)
+		v.AddArg(ptr)
+		v.AddArg(old)
+		v.AddArg(new_)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicExchange32_0(v *Value) bool {
+	// match: (AtomicExchange32 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicExchange32 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicExchange32)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicExchange64_0(v *Value) bool {
+	// match: (AtomicExchange64 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicExchange64 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicExchange64)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicLoad32_0(v *Value) bool {
+	// match: (AtomicLoad32 ptr mem)
+	// cond:
+	// result: (LoweredAtomicLoad32 ptr mem)
+	for {
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpMIPS64LoweredAtomicLoad32)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicLoad64_0(v *Value) bool {
+	// match: (AtomicLoad64 ptr mem)
+	// cond:
+	// result: (LoweredAtomicLoad64 ptr mem)
+	for {
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpMIPS64LoweredAtomicLoad64)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicLoadPtr_0(v *Value) bool {
+	// match: (AtomicLoadPtr ptr mem)
+	// cond:
+	// result: (LoweredAtomicLoad64 ptr mem)
+	for {
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		mem := v.Args[1]
+		v.reset(OpMIPS64LoweredAtomicLoad64)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicStore32_0(v *Value) bool {
+	// match: (AtomicStore32 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicStore32 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicStore32)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicStore64_0(v *Value) bool {
+	// match: (AtomicStore64 ptr val mem)
+	// cond:
+	// result: (LoweredAtomicStore64 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicStore64)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
+func rewriteValueMIPS64_OpAtomicStorePtrNoWB_0(v *Value) bool {
+	// match: (AtomicStorePtrNoWB ptr val mem)
+	// cond:
+	// result: (LoweredAtomicStore64 ptr val mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		val := v.Args[1]
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicStore64)
+		v.AddArg(ptr)
+		v.AddArg(val)
+		v.AddArg(mem)
+		return true
+	}
+}
 func rewriteValueMIPS64_OpAvg64u_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -1719,6 +1943,15 @@
 		return true
 	}
 }
+func rewriteValueMIPS64_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpMIPS64LoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueMIPS64_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -2699,7 +2932,7 @@
 	_ = typ
 	// match: (Lsh16x16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2708,7 +2941,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -2732,7 +2965,7 @@
 	_ = typ
 	// match: (Lsh16x32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2741,7 +2974,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -2765,7 +2998,7 @@
 	_ = typ
 	// match: (Lsh16x64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2774,7 +3007,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -2794,7 +3027,7 @@
 	_ = typ
 	// match: (Lsh16x8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2803,7 +3036,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -2827,7 +3060,7 @@
 	_ = typ
 	// match: (Lsh32x16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2836,7 +3069,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -2860,7 +3093,7 @@
 	_ = typ
 	// match: (Lsh32x32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2869,7 +3102,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -2893,7 +3126,7 @@
 	_ = typ
 	// match: (Lsh32x64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2902,7 +3135,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -2922,7 +3155,7 @@
 	_ = typ
 	// match: (Lsh32x8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2931,7 +3164,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -2955,7 +3188,7 @@
 	_ = typ
 	// match: (Lsh64x16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2964,7 +3197,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -2988,7 +3221,7 @@
 	_ = typ
 	// match: (Lsh64x32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -2997,7 +3230,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -3021,7 +3254,7 @@
 	_ = typ
 	// match: (Lsh64x64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3030,7 +3263,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -3050,7 +3283,7 @@
 	_ = typ
 	// match: (Lsh64x8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3059,7 +3292,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -3083,7 +3316,7 @@
 	_ = typ
 	// match: (Lsh8x16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3092,7 +3325,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -3116,7 +3349,7 @@
 	_ = typ
 	// match: (Lsh8x32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3125,7 +3358,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -3149,7 +3382,7 @@
 	_ = typ
 	// match: (Lsh8x64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SLLV <t> x y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3158,7 +3391,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -3178,7 +3411,7 @@
 	_ = typ
 	// match: (Lsh8x8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -3187,7 +3420,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -3475,6 +3708,98 @@
 	}
 	return false
 }
+func rewriteValueMIPS64_OpMIPS64LoweredAtomicAdd32_0(v *Value) bool {
+	// match: (LoweredAtomicAdd32 ptr (MOVVconst [c]) mem)
+	// cond: is32Bit(c)
+	// result: (LoweredAtomicAddconst32 [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMIPS64MOVVconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		if !(is32Bit(c)) {
+			break
+		}
+		v.reset(OpMIPS64LoweredAtomicAddconst32)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueMIPS64_OpMIPS64LoweredAtomicAdd64_0(v *Value) bool {
+	// match: (LoweredAtomicAdd64 ptr (MOVVconst [c]) mem)
+	// cond: is32Bit(c)
+	// result: (LoweredAtomicAddconst64 [c] ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMIPS64MOVVconst {
+			break
+		}
+		c := v_1.AuxInt
+		mem := v.Args[2]
+		if !(is32Bit(c)) {
+			break
+		}
+		v.reset(OpMIPS64LoweredAtomicAddconst64)
+		v.AuxInt = c
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueMIPS64_OpMIPS64LoweredAtomicStore32_0(v *Value) bool {
+	// match: (LoweredAtomicStore32 ptr (MOVVconst [0]) mem)
+	// cond:
+	// result: (LoweredAtomicStorezero32 ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMIPS64MOVVconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicStorezero32)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueMIPS64_OpMIPS64LoweredAtomicStore64_0(v *Value) bool {
+	// match: (LoweredAtomicStore64 ptr (MOVVconst [0]) mem)
+	// cond:
+	// result: (LoweredAtomicStorezero64 ptr mem)
+	for {
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMIPS64MOVVconst {
+			break
+		}
+		if v_1.AuxInt != 0 {
+			break
+		}
+		mem := v.Args[2]
+		v.reset(OpMIPS64LoweredAtomicStorezero64)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueMIPS64_OpMIPS64MOVBUload_0(v *Value) bool {
 	// match: (MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem)
 	// cond: is32Bit(off1+off2)
@@ -7521,7 +7846,7 @@
 	_ = typ
 	// match: (Rsh16Ux16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7530,7 +7855,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -7556,7 +7881,7 @@
 	_ = typ
 	// match: (Rsh16Ux32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7565,7 +7890,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -7591,7 +7916,7 @@
 	_ = typ
 	// match: (Rsh16Ux64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7600,7 +7925,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -7622,7 +7947,7 @@
 	_ = typ
 	// match: (Rsh16Ux8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7631,7 +7956,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -7657,7 +7982,7 @@
 	_ = typ
 	// match: (Rsh16x16 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7673,7 +7998,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -7692,7 +8017,7 @@
 	_ = typ
 	// match: (Rsh16x32 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7708,7 +8033,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -7727,7 +8052,7 @@
 	_ = typ
 	// match: (Rsh16x64 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
+	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7741,7 +8066,7 @@
 		v2 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v3 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
 		v3.AddArg(y)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v3.AddArg(v4)
 		v2.AddArg(v3)
@@ -7758,7 +8083,7 @@
 	_ = typ
 	// match: (Rsh16x8 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+	// result: (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7774,7 +8099,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -7793,7 +8118,7 @@
 	_ = typ
 	// match: (Rsh32Ux16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7802,7 +8127,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -7828,7 +8153,7 @@
 	_ = typ
 	// match: (Rsh32Ux32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7837,7 +8162,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -7863,7 +8188,7 @@
 	_ = typ
 	// match: (Rsh32Ux64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7872,7 +8197,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -7894,7 +8219,7 @@
 	_ = typ
 	// match: (Rsh32Ux8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7903,7 +8228,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -7929,7 +8254,7 @@
 	_ = typ
 	// match: (Rsh32x16 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7945,7 +8270,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -7964,7 +8289,7 @@
 	_ = typ
 	// match: (Rsh32x32 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -7980,7 +8305,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -7999,7 +8324,7 @@
 	_ = typ
 	// match: (Rsh32x64 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
+	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8013,7 +8338,7 @@
 		v2 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v3 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
 		v3.AddArg(y)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v3.AddArg(v4)
 		v2.AddArg(v3)
@@ -8030,7 +8355,7 @@
 	_ = typ
 	// match: (Rsh32x8 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+	// result: (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8046,7 +8371,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -8065,7 +8390,7 @@
 	_ = typ
 	// match: (Rsh64Ux16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8074,7 +8399,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -8098,7 +8423,7 @@
 	_ = typ
 	// match: (Rsh64Ux32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8107,7 +8432,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -8131,7 +8456,7 @@
 	_ = typ
 	// match: (Rsh64Ux64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> x y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8140,7 +8465,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -8160,7 +8485,7 @@
 	_ = typ
 	// match: (Rsh64Ux8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8169,7 +8494,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -8193,7 +8518,7 @@
 	_ = typ
 	// match: (Rsh64x16 <t> x y)
 	// cond:
-	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8207,7 +8532,7 @@
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v3.AddArg(y)
 		v2.AddArg(v3)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v2.AddArg(v4)
 		v1.AddArg(v2)
@@ -8226,7 +8551,7 @@
 	_ = typ
 	// match: (Rsh64x32 <t> x y)
 	// cond:
-	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8240,7 +8565,7 @@
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v3.AddArg(y)
 		v2.AddArg(v3)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v2.AddArg(v4)
 		v1.AddArg(v2)
@@ -8259,7 +8584,7 @@
 	_ = typ
 	// match: (Rsh64x64 <t> x y)
 	// cond:
-	// result: (SRAV x (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
+	// result: (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8271,7 +8596,7 @@
 		v1 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v2 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
 		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v3 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v3.AuxInt = 63
 		v2.AddArg(v3)
 		v1.AddArg(v2)
@@ -8288,7 +8613,7 @@
 	_ = typ
 	// match: (Rsh64x8 <t> x y)
 	// cond:
-	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+	// result: (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8302,7 +8627,7 @@
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v3.AddArg(y)
 		v2.AddArg(v3)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v2.AddArg(v4)
 		v1.AddArg(v2)
@@ -8321,7 +8646,7 @@
 	_ = typ
 	// match: (Rsh8Ux16 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8330,7 +8655,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -8356,7 +8681,7 @@
 	_ = typ
 	// match: (Rsh8Ux32 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8365,7 +8690,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -8391,7 +8716,7 @@
 	_ = typ
 	// match: (Rsh8Ux64 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8400,7 +8725,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v1.AddArg(y)
@@ -8422,7 +8747,7 @@
 	_ = typ
 	// match: (Rsh8Ux8 <t> x y)
 	// cond:
-	// result: (AND (NEGV <t> (SGTU (Const64 <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
+	// result: (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8431,7 +8756,7 @@
 		v.reset(OpMIPS64AND)
 		v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v1 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
-		v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v2 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v2.AuxInt = 64
 		v1.AddArg(v2)
 		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -8457,7 +8782,7 @@
 	_ = typ
 	// match: (Rsh8x16 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8473,7 +8798,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -8492,7 +8817,7 @@
 	_ = typ
 	// match: (Rsh8x32 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (Const64 <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8508,7 +8833,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -8527,7 +8852,7 @@
 	_ = typ
 	// match: (Rsh8x64 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (Const64 <typ.UInt64> [63]))) y))
+	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8541,7 +8866,7 @@
 		v2 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
 		v3 := b.NewValue0(v.Pos, OpMIPS64SGTU, typ.Bool)
 		v3.AddArg(y)
-		v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v4 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v4.AuxInt = 63
 		v3.AddArg(v4)
 		v2.AddArg(v3)
@@ -8558,7 +8883,7 @@
 	_ = typ
 	// match: (Rsh8x8 <t> x y)
 	// cond:
-	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (Const64 <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+	// result: (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
 	for {
 		t := v.Type
 		_ = v.Args[1]
@@ -8574,7 +8899,7 @@
 		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v4.AddArg(y)
 		v3.AddArg(v4)
-		v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
 		v5.AuxInt = 63
 		v3.AddArg(v5)
 		v2.AddArg(v3)
@@ -10187,6 +10512,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPS64FPF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FPFlagFalse cmp) yes no)
@@ -10200,6 +10526,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPS64FPT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGT _ _)) yes no)
@@ -10220,6 +10547,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPS64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTU _ _)) yes no)
@@ -10240,6 +10568,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPS64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTconst _)) yes no)
@@ -10259,6 +10588,7 @@
 			}
 			b.Kind = BlockMIPS64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (XORconst [1] cmp:(SGTUconst _)) yes no)
@@ -10278,6 +10608,7 @@
 			}
 			b.Kind = BlockMIPS64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTUconst [1] x) yes no)
@@ -10294,6 +10625,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPS64NE
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTU x (MOVVconst [0])) yes no)
@@ -10315,6 +10647,7 @@
 			}
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGTconst [0] x) yes no)
@@ -10331,6 +10664,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPS64GEZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (SGT x (MOVVconst [0])) yes no)
@@ -10352,6 +10686,7 @@
 			}
 			b.Kind = BlockMIPS64LEZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (MOVVconst [0]) yes no)
@@ -10367,6 +10702,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (MOVVconst [c]) yes no)
@@ -10383,6 +10719,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10401,6 +10738,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GEZ (MOVVconst [c]) yes no)
@@ -10417,6 +10755,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10435,6 +10774,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GTZ (MOVVconst [c]) yes no)
@@ -10451,6 +10791,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10464,6 +10805,7 @@
 			cond := b.Control
 			b.Kind = BlockMIPS64NE
 			b.SetControl(cond)
+			b.Aux = nil
 			return true
 		}
 	case BlockMIPS64LEZ:
@@ -10481,6 +10823,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LEZ (MOVVconst [c]) yes no)
@@ -10497,6 +10840,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10515,6 +10859,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LTZ (MOVVconst [c]) yes no)
@@ -10531,6 +10876,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10546,6 +10892,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPS64FPT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FPFlagFalse cmp) yes no)
@@ -10559,6 +10906,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockMIPS64FPF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGT _ _)) yes no)
@@ -10579,6 +10927,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTU _ _)) yes no)
@@ -10599,6 +10948,7 @@
 			_ = cmp.Args[1]
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTconst _)) yes no)
@@ -10618,6 +10968,7 @@
 			}
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (XORconst [1] cmp:(SGTUconst _)) yes no)
@@ -10637,6 +10988,7 @@
 			}
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTUconst [1] x) yes no)
@@ -10653,6 +11005,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPS64EQ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTU x (MOVVconst [0])) yes no)
@@ -10674,6 +11027,7 @@
 			}
 			b.Kind = BlockMIPS64NE
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGTconst [0] x) yes no)
@@ -10690,6 +11044,7 @@
 			x := v.Args[0]
 			b.Kind = BlockMIPS64LTZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (SGT x (MOVVconst [0])) yes no)
@@ -10711,6 +11066,7 @@
 			}
 			b.Kind = BlockMIPS64GTZ
 			b.SetControl(x)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (MOVVconst [0]) yes no)
@@ -10726,6 +11082,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -10743,6 +11100,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	}
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 20e354c..6a000f4 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -15,6 +15,8 @@
 
 func rewriteValuePPC64(v *Value) bool {
 	switch v.Op {
+	case OpAbs:
+		return rewriteValuePPC64_OpAbs_0(v)
 	case OpAdd16:
 		return rewriteValuePPC64_OpAdd16_0(v)
 	case OpAdd32:
@@ -73,6 +75,8 @@
 		return rewriteValuePPC64_OpBitLen32_0(v)
 	case OpBitLen64:
 		return rewriteValuePPC64_OpBitLen64_0(v)
+	case OpCeil:
+		return rewriteValuePPC64_OpCeil_0(v)
 	case OpClosureCall:
 		return rewriteValuePPC64_OpClosureCall_0(v)
 	case OpCom16:
@@ -101,6 +105,8 @@
 		return rewriteValuePPC64_OpConstNil_0(v)
 	case OpConvert:
 		return rewriteValuePPC64_OpConvert_0(v)
+	case OpCopysign:
+		return rewriteValuePPC64_OpCopysign_0(v)
 	case OpCtz32:
 		return rewriteValuePPC64_OpCtz32_0(v)
 	case OpCtz64:
@@ -161,6 +167,8 @@
 		return rewriteValuePPC64_OpEqB_0(v)
 	case OpEqPtr:
 		return rewriteValuePPC64_OpEqPtr_0(v)
+	case OpFloor:
+		return rewriteValuePPC64_OpFloor_0(v)
 	case OpGeq16:
 		return rewriteValuePPC64_OpGeq16_0(v)
 	case OpGeq16U:
@@ -181,6 +189,8 @@
 		return rewriteValuePPC64_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValuePPC64_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValuePPC64_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValuePPC64_OpGetClosurePtr_0(v)
 	case OpGreater16:
@@ -393,10 +403,16 @@
 		return rewriteValuePPC64_OpPPC64CMPconst_0(v)
 	case OpPPC64Equal:
 		return rewriteValuePPC64_OpPPC64Equal_0(v)
+	case OpPPC64FABS:
+		return rewriteValuePPC64_OpPPC64FABS_0(v)
 	case OpPPC64FADD:
 		return rewriteValuePPC64_OpPPC64FADD_0(v)
 	case OpPPC64FADDS:
 		return rewriteValuePPC64_OpPPC64FADDS_0(v)
+	case OpPPC64FCEIL:
+		return rewriteValuePPC64_OpPPC64FCEIL_0(v)
+	case OpPPC64FFLOOR:
+		return rewriteValuePPC64_OpPPC64FFLOOR_0(v)
 	case OpPPC64FMOVDload:
 		return rewriteValuePPC64_OpPPC64FMOVDload_0(v)
 	case OpPPC64FMOVDstore:
@@ -405,10 +421,16 @@
 		return rewriteValuePPC64_OpPPC64FMOVSload_0(v)
 	case OpPPC64FMOVSstore:
 		return rewriteValuePPC64_OpPPC64FMOVSstore_0(v)
+	case OpPPC64FNEG:
+		return rewriteValuePPC64_OpPPC64FNEG_0(v)
+	case OpPPC64FSQRT:
+		return rewriteValuePPC64_OpPPC64FSQRT_0(v)
 	case OpPPC64FSUB:
 		return rewriteValuePPC64_OpPPC64FSUB_0(v)
 	case OpPPC64FSUBS:
 		return rewriteValuePPC64_OpPPC64FSUBS_0(v)
+	case OpPPC64FTRUNC:
+		return rewriteValuePPC64_OpPPC64FTRUNC_0(v)
 	case OpPPC64GreaterEqual:
 		return rewriteValuePPC64_OpPPC64GreaterEqual_0(v)
 	case OpPPC64GreaterThan:
@@ -417,6 +439,8 @@
 		return rewriteValuePPC64_OpPPC64LessEqual_0(v)
 	case OpPPC64LessThan:
 		return rewriteValuePPC64_OpPPC64LessThan_0(v)
+	case OpPPC64MFVSRD:
+		return rewriteValuePPC64_OpPPC64MFVSRD_0(v)
 	case OpPPC64MOVBZload:
 		return rewriteValuePPC64_OpPPC64MOVBZload_0(v)
 	case OpPPC64MOVBZreg:
@@ -457,12 +481,14 @@
 		return rewriteValuePPC64_OpPPC64MOVWstore_0(v)
 	case OpPPC64MOVWstorezero:
 		return rewriteValuePPC64_OpPPC64MOVWstorezero_0(v)
+	case OpPPC64MTVSRD:
+		return rewriteValuePPC64_OpPPC64MTVSRD_0(v)
 	case OpPPC64MaskIfNotCarry:
 		return rewriteValuePPC64_OpPPC64MaskIfNotCarry_0(v)
 	case OpPPC64NotEqual:
 		return rewriteValuePPC64_OpPPC64NotEqual_0(v)
 	case OpPPC64OR:
-		return rewriteValuePPC64_OpPPC64OR_0(v)
+		return rewriteValuePPC64_OpPPC64OR_0(v) || rewriteValuePPC64_OpPPC64OR_10(v) || rewriteValuePPC64_OpPPC64OR_20(v) || rewriteValuePPC64_OpPPC64OR_30(v) || rewriteValuePPC64_OpPPC64OR_40(v) || rewriteValuePPC64_OpPPC64OR_50(v) || rewriteValuePPC64_OpPPC64OR_60(v) || rewriteValuePPC64_OpPPC64OR_70(v) || rewriteValuePPC64_OpPPC64OR_80(v) || rewriteValuePPC64_OpPPC64OR_90(v) || rewriteValuePPC64_OpPPC64OR_100(v) || rewriteValuePPC64_OpPPC64OR_110(v) || rewriteValuePPC64_OpPPC64OR_120(v) || rewriteValuePPC64_OpPPC64OR_130(v) || rewriteValuePPC64_OpPPC64OR_140(v)
 	case OpPPC64ORN:
 		return rewriteValuePPC64_OpPPC64ORN_0(v)
 	case OpPPC64ORconst:
@@ -470,7 +496,7 @@
 	case OpPPC64SUB:
 		return rewriteValuePPC64_OpPPC64SUB_0(v)
 	case OpPPC64XOR:
-		return rewriteValuePPC64_OpPPC64XOR_0(v)
+		return rewriteValuePPC64_OpPPC64XOR_0(v) || rewriteValuePPC64_OpPPC64XOR_10(v)
 	case OpPPC64XORconst:
 		return rewriteValuePPC64_OpPPC64XORconst_0(v)
 	case OpPopCount16:
@@ -583,6 +609,8 @@
 		return rewriteValuePPC64_OpSub8_0(v)
 	case OpSubPtr:
 		return rewriteValuePPC64_OpSubPtr_0(v)
+	case OpTrunc:
+		return rewriteValuePPC64_OpTrunc_0(v)
 	case OpTrunc16to8:
 		return rewriteValuePPC64_OpTrunc16to8_0(v)
 	case OpTrunc32to16:
@@ -620,6 +648,17 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpAbs_0(v *Value) bool {
+	// match: (Abs x)
+	// cond:
+	// result: (FABS x)
+	for {
+		x := v.Args[0]
+		v.reset(OpPPC64FABS)
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValuePPC64_OpAdd16_0(v *Value) bool {
 	// match: (Add16 x y)
 	// cond:
@@ -1070,6 +1109,17 @@
 		return true
 	}
 }
+func rewriteValuePPC64_OpCeil_0(v *Value) bool {
+	// match: (Ceil x)
+	// cond:
+	// result: (FCEIL x)
+	for {
+		x := v.Args[0]
+		v.reset(OpPPC64FCEIL)
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValuePPC64_OpClosureCall_0(v *Value) bool {
 	// match: (ClosureCall [argwid] entry closure mem)
 	// cond:
@@ -1239,6 +1289,20 @@
 		return true
 	}
 }
+func rewriteValuePPC64_OpCopysign_0(v *Value) bool {
+	// match: (Copysign x y)
+	// cond:
+	// result: (FCPSGN y x)
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		y := v.Args[1]
+		v.reset(OpPPC64FCPSGN)
+		v.AddArg(y)
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValuePPC64_OpCtz32_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -1290,10 +1354,10 @@
 	_ = typ
 	// match: (Cvt32Fto32 x)
 	// cond:
-	// result: (Xf2i64 (FCTIWZ x))
+	// result: (MFVSRD (FCTIWZ x))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64Xf2i64)
+		v.reset(OpPPC64MFVSRD)
 		v0 := b.NewValue0(v.Pos, OpPPC64FCTIWZ, typ.Float64)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -1307,10 +1371,10 @@
 	_ = typ
 	// match: (Cvt32Fto64 x)
 	// cond:
-	// result: (Xf2i64 (FCTIDZ x))
+	// result: (MFVSRD (FCTIDZ x))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64Xf2i64)
+		v.reset(OpPPC64MFVSRD)
 		v0 := b.NewValue0(v.Pos, OpPPC64FCTIDZ, typ.Float64)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -1336,15 +1400,13 @@
 	_ = typ
 	// match: (Cvt32to32F x)
 	// cond:
-	// result: (FRSP (FCFID (Xi2f64 (SignExt32to64 x))))
+	// result: (FCFIDS (MTVSRD (SignExt32to64 x)))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64FRSP)
-		v0 := b.NewValue0(v.Pos, OpPPC64FCFID, typ.Float64)
-		v1 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
-		v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
-		v2.AddArg(x)
-		v1.AddArg(v2)
+		v.reset(OpPPC64FCFIDS)
+		v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
+		v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v1.AddArg(x)
 		v0.AddArg(v1)
 		v.AddArg(v0)
 		return true
@@ -1357,11 +1419,11 @@
 	_ = typ
 	// match: (Cvt32to64F x)
 	// cond:
-	// result: (FCFID (Xi2f64 (SignExt32to64 x)))
+	// result: (FCFID (MTVSRD (SignExt32to64 x)))
 	for {
 		x := v.Args[0]
 		v.reset(OpPPC64FCFID)
-		v0 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
+		v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
 		v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
 		v1.AddArg(x)
 		v0.AddArg(v1)
@@ -1376,10 +1438,10 @@
 	_ = typ
 	// match: (Cvt64Fto32 x)
 	// cond:
-	// result: (Xf2i64 (FCTIWZ x))
+	// result: (MFVSRD (FCTIWZ x))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64Xf2i64)
+		v.reset(OpPPC64MFVSRD)
 		v0 := b.NewValue0(v.Pos, OpPPC64FCTIWZ, typ.Float64)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -1404,10 +1466,10 @@
 	_ = typ
 	// match: (Cvt64Fto64 x)
 	// cond:
-	// result: (Xf2i64 (FCTIDZ x))
+	// result: (MFVSRD (FCTIDZ x))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64Xf2i64)
+		v.reset(OpPPC64MFVSRD)
 		v0 := b.NewValue0(v.Pos, OpPPC64FCTIDZ, typ.Float64)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -1421,14 +1483,12 @@
 	_ = typ
 	// match: (Cvt64to32F x)
 	// cond:
-	// result: (FRSP (FCFID (Xi2f64 x)))
+	// result: (FCFIDS (MTVSRD x))
 	for {
 		x := v.Args[0]
-		v.reset(OpPPC64FRSP)
-		v0 := b.NewValue0(v.Pos, OpPPC64FCFID, typ.Float64)
-		v1 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
-		v1.AddArg(x)
-		v0.AddArg(v1)
+		v.reset(OpPPC64FCFIDS)
+		v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
+		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
 	}
@@ -1440,11 +1500,11 @@
 	_ = typ
 	// match: (Cvt64to64F x)
 	// cond:
-	// result: (FCFID (Xi2f64 x))
+	// result: (FCFID (MTVSRD x))
 	for {
 		x := v.Args[0]
 		v.reset(OpPPC64FCFID)
-		v0 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
+		v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
 		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
@@ -1823,6 +1883,17 @@
 		return true
 	}
 }
+func rewriteValuePPC64_OpFloor_0(v *Value) bool {
+	// match: (Floor x)
+	// cond:
+	// result: (FFLOOR x)
+	for {
+		x := v.Args[0]
+		v.reset(OpPPC64FFLOOR)
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValuePPC64_OpGeq16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -2027,6 +2098,15 @@
 		return true
 	}
 }
+func rewriteValuePPC64_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpPPC64LoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValuePPC64_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -3298,6 +3378,85 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Lsh32x64 x (AND y (MOVDconst [31])))
+	// cond:
+	// result: (SLW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		v.reset(OpPPC64SLW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Lsh32x64 x (AND (MOVDconst [31]) y))
+	// cond:
+	// result: (SLW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SLW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Lsh32x64 x (ANDconst <typ.Int32> [31] y))
+	// cond:
+	// result: (SLW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.Int32 {
+			break
+		}
+		if v_1.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SLW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Lsh32x64 x y)
 	// cond:
 	// result: (SLW  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
@@ -3501,6 +3660,85 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Lsh64x64 x (AND y (MOVDconst [63])))
+	// cond:
+	// result: (SLD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		v.reset(OpPPC64SLD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Lsh64x64 x (AND (MOVDconst [63]) y))
+	// cond:
+	// result: (SLD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SLD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Lsh64x64 x (ANDconst <typ.Int64> [63] y))
+	// cond:
+	// result: (SLD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.Int64 {
+			break
+		}
+		if v_1.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SLD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Lsh64x64 x y)
 	// cond:
 	// result: (SLD  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
@@ -4678,6 +4916,10 @@
 	}
 }
 func rewriteValuePPC64_OpPPC64ADD_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (ADD (SLDconst x [c]) (SRDconst x [d]))
 	// cond: d == 64-c
 	// result: (ROTLconst [c] x)
@@ -4786,6 +5028,258 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int64 {
+			break
+		}
+		if v_0_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADD (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) (SLD x (ANDconst <typ.Int64> [63] y)))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 64 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int64 {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int32 {
+			break
+		}
+		if v_0_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (ADD (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) (SLW x (ANDconst <typ.Int32> [31] y)))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 32 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int32 {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
 	// match: (ADD x (MOVDconst [c]))
 	// cond: is32Bit(c)
 	// result: (ADDconst [c] x)
@@ -5717,6 +6211,22 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64FABS_0(v *Value) bool {
+	// match: (FABS (FMOVDconst [x]))
+	// cond:
+	// result: (FMOVDconst [f2i(math.Abs(i2f(x)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		x := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = f2i(math.Abs(i2f(x)))
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64FADD_0(v *Value) bool {
 	// match: (FADD (FMUL x y) z)
 	// cond:
@@ -5799,23 +6309,82 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64FCEIL_0(v *Value) bool {
+	// match: (FCEIL (FMOVDconst [x]))
+	// cond:
+	// result: (FMOVDconst [f2i(math.Ceil(i2f(x)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		x := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = f2i(math.Ceil(i2f(x)))
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64FFLOOR_0(v *Value) bool {
+	// match: (FFLOOR (FMOVDconst [x]))
+	// cond:
+	// result: (FMOVDconst [f2i(math.Floor(i2f(x)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		x := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = f2i(math.Floor(i2f(x)))
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64FMOVDload_0(v *Value) bool {
-	// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _))
+	// cond:
+	// result: (MTVSRD x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64MOVDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		x := v_1.Args[1]
+		v.reset(OpPPC64MTVSRD)
+		v.AddArg(x)
+		return true
+	}
+	// match: (FMOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64FMOVDload)
@@ -5852,6 +6421,28 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64FMOVDstore_0(v *Value) bool {
+	// match: (FMOVDstore [off] {sym} ptr (MTVSRD x) mem)
+	// cond:
+	// result: (MOVDstore [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64MTVSRD {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpPPC64MOVDstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
 	// cond: is16Bit(off1+off2)
 	// result: (FMOVDstore [off1+off2] {sym} ptr val mem)
@@ -5878,23 +6469,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (FMOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64FMOVDstore)
@@ -5908,22 +6499,22 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64FMOVSload_0(v *Value) bool {
-	// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64FMOVSload)
@@ -5986,23 +6577,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64FMOVSstore)
@@ -6015,6 +6606,51 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64FNEG_0(v *Value) bool {
+	// match: (FNEG (FABS x))
+	// cond:
+	// result: (FNABS x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FABS {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpPPC64FNABS)
+		v.AddArg(x)
+		return true
+	}
+	// match: (FNEG (FNABS x))
+	// cond:
+	// result: (FABS x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FNABS {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpPPC64FABS)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64FSQRT_0(v *Value) bool {
+	// match: (FSQRT (FMOVDconst [x]))
+	// cond:
+	// result: (FMOVDconst [f2i(math.Sqrt(i2f(x)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		x := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = f2i(math.Sqrt(i2f(x)))
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64FSUB_0(v *Value) bool {
 	// match: (FSUB (FMUL x y) z)
 	// cond:
@@ -6059,6 +6695,22 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64FTRUNC_0(v *Value) bool {
+	// match: (FTRUNC (FMOVDconst [x]))
+	// cond:
+	// result: (FMOVDconst [f2i(math.Trunc(i2f(x)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		x := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = f2i(math.Trunc(i2f(x)))
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64GreaterEqual_0(v *Value) bool {
 	// match: (GreaterEqual (FlagEQ))
 	// cond:
@@ -6267,23 +6919,69 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64MFVSRD_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (MFVSRD (FMOVDconst [c]))
+	// cond:
+	// result: (MOVDconst [c])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64FMOVDconst {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpPPC64MOVDconst)
+		v.AuxInt = c
+		return true
+	}
+	// match: (MFVSRD x:(FMOVDload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVDload [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpPPC64FMOVDload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, typ.Int64)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64MOVBZload_0(v *Value) bool {
-	// match: (MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVBZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVBZload)
@@ -6452,6 +7150,10 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVBstore_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem)
 	// cond: is16Bit(off1+off2)
 	// result: (MOVBstore [off1+off2] {sym} x val mem)
@@ -6478,23 +7180,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVBstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVBstore)
@@ -6573,6 +7275,315 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVBstore [i1] {s} p (SRWconst (MOVHZreg w) [8]) x0:(MOVBstore [i0] {s} p w mem))
+	// cond: !config.BigEndian 	&& x0.Uses == 1 	&& i1 == i0+1 	&& clobber(x0)
+	// result: (MOVHstore [i0] {s} p w mem)
+	for {
+		i1 := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRWconst {
+			break
+		}
+		if v_1.AuxInt != 8 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVHZreg {
+			break
+		}
+		w := v_1_0.Args[0]
+		x0 := v.Args[2]
+		if x0.Op != OpPPC64MOVBstore {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[2]
+		if p != x0.Args[0] {
+			break
+		}
+		if w != x0.Args[1] {
+			break
+		}
+		mem := x0.Args[2]
+		if !(!config.BigEndian && x0.Uses == 1 && i1 == i0+1 && clobber(x0)) {
+			break
+		}
+		v.reset(OpPPC64MOVHstore)
+		v.AuxInt = i0
+		v.Aux = s
+		v.AddArg(p)
+		v.AddArg(w)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [i3] {s} p (SRWconst w [24]) x0:(MOVBstore [i2] {s} p (SRWconst w [16]) x1:(MOVBstore [i1] {s} p (SRWconst w [8]) x2:(MOVBstore [i0] {s} p w mem))))
+	// cond: !config.BigEndian 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3 	&& clobber(x0) && clobber(x1) && clobber(x2)
+	// result: (MOVWstore [i0] {s} p w mem)
+	for {
+		i3 := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRWconst {
+			break
+		}
+		if v_1.AuxInt != 24 {
+			break
+		}
+		w := v_1.Args[0]
+		x0 := v.Args[2]
+		if x0.Op != OpPPC64MOVBstore {
+			break
+		}
+		i2 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[2]
+		if p != x0.Args[0] {
+			break
+		}
+		x0_1 := x0.Args[1]
+		if x0_1.Op != OpPPC64SRWconst {
+			break
+		}
+		if x0_1.AuxInt != 16 {
+			break
+		}
+		if w != x0_1.Args[0] {
+			break
+		}
+		x1 := x0.Args[2]
+		if x1.Op != OpPPC64MOVBstore {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[2]
+		if p != x1.Args[0] {
+			break
+		}
+		x1_1 := x1.Args[1]
+		if x1_1.Op != OpPPC64SRWconst {
+			break
+		}
+		if x1_1.AuxInt != 8 {
+			break
+		}
+		if w != x1_1.Args[0] {
+			break
+		}
+		x2 := x1.Args[2]
+		if x2.Op != OpPPC64MOVBstore {
+			break
+		}
+		i0 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[2]
+		if p != x2.Args[0] {
+			break
+		}
+		if w != x2.Args[1] {
+			break
+		}
+		mem := x2.Args[2]
+		if !(!config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && clobber(x0) && clobber(x1) && clobber(x2)) {
+			break
+		}
+		v.reset(OpPPC64MOVWstore)
+		v.AuxInt = i0
+		v.Aux = s
+		v.AddArg(p)
+		v.AddArg(w)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBstore [i7] {s} p (SRDconst w [56]) x0:(MOVBstore [i6] {s} p (SRDconst w [48]) x1:(MOVBstore [i5] {s} p (SRDconst w [40]) x2:(MOVBstore [i4] {s} p (SRDconst w [32]) x3:(MOVBstore [i3] {s} p (SRDconst w [24]) x4:(MOVBstore [i2] {s} p (SRDconst w [16]) x5:(MOVBstore [i1] {s} p (SRDconst w [8]) x6:(MOVBstore [i0] {s} p w mem))))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6)
+	// result: (MOVDstore [i0] {s} p w mem)
+	for {
+		i7 := v.AuxInt
+		s := v.Aux
+		_ = v.Args[2]
+		p := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if v_1.AuxInt != 56 {
+			break
+		}
+		w := v_1.Args[0]
+		x0 := v.Args[2]
+		if x0.Op != OpPPC64MOVBstore {
+			break
+		}
+		i6 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[2]
+		if p != x0.Args[0] {
+			break
+		}
+		x0_1 := x0.Args[1]
+		if x0_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x0_1.AuxInt != 48 {
+			break
+		}
+		if w != x0_1.Args[0] {
+			break
+		}
+		x1 := x0.Args[2]
+		if x1.Op != OpPPC64MOVBstore {
+			break
+		}
+		i5 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[2]
+		if p != x1.Args[0] {
+			break
+		}
+		x1_1 := x1.Args[1]
+		if x1_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x1_1.AuxInt != 40 {
+			break
+		}
+		if w != x1_1.Args[0] {
+			break
+		}
+		x2 := x1.Args[2]
+		if x2.Op != OpPPC64MOVBstore {
+			break
+		}
+		i4 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[2]
+		if p != x2.Args[0] {
+			break
+		}
+		x2_1 := x2.Args[1]
+		if x2_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x2_1.AuxInt != 32 {
+			break
+		}
+		if w != x2_1.Args[0] {
+			break
+		}
+		x3 := x2.Args[2]
+		if x3.Op != OpPPC64MOVBstore {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[2]
+		if p != x3.Args[0] {
+			break
+		}
+		x3_1 := x3.Args[1]
+		if x3_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x3_1.AuxInt != 24 {
+			break
+		}
+		if w != x3_1.Args[0] {
+			break
+		}
+		x4 := x3.Args[2]
+		if x4.Op != OpPPC64MOVBstore {
+			break
+		}
+		i2 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[2]
+		if p != x4.Args[0] {
+			break
+		}
+		x4_1 := x4.Args[1]
+		if x4_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x4_1.AuxInt != 16 {
+			break
+		}
+		if w != x4_1.Args[0] {
+			break
+		}
+		x5 := x4.Args[2]
+		if x5.Op != OpPPC64MOVBstore {
+			break
+		}
+		i1 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[2]
+		if p != x5.Args[0] {
+			break
+		}
+		x5_1 := x5.Args[1]
+		if x5_1.Op != OpPPC64SRDconst {
+			break
+		}
+		if x5_1.AuxInt != 8 {
+			break
+		}
+		if w != x5_1.Args[0] {
+			break
+		}
+		x6 := x5.Args[2]
+		if x6.Op != OpPPC64MOVBstore {
+			break
+		}
+		i0 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[2]
+		if p != x6.Args[0] {
+			break
+		}
+		if w != x6.Args[1] {
+			break
+		}
+		mem := x6.Args[2]
+		if !(!config.BigEndian && i0%4 == 0 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6)) {
+			break
+		}
+		v.reset(OpPPC64MOVDstore)
+		v.AuxInt = i0
+		v.Aux = s
+		v.AddArg(p)
+		v.AddArg(w)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVBstorezero_0(v *Value) bool {
@@ -6600,22 +7611,22 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVBstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (x.Op != OpSB || p.Uses == 1)
 	// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		x := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		x := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVBstorezero)
@@ -6628,22 +7639,49 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVDload_0(v *Value) bool {
-	// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _))
+	// cond:
+	// result: (MFVSRD x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64FMOVDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		if ptr != v_1.Args[0] {
+			break
+		}
+		x := v_1.Args[1]
+		v.reset(OpPPC64MFVSRD)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDload)
@@ -6680,6 +7718,28 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVDstore_0(v *Value) bool {
+	// match: (MOVDstore [off] {sym} ptr (MFVSRD x) mem)
+	// cond:
+	// result: (FMOVDstore [off] {sym} ptr x mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64MFVSRD {
+			break
+		}
+		x := v_1.Args[0]
+		mem := v.Args[2]
+		v.reset(OpPPC64FMOVDstore)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(x)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
 	// cond: is16Bit(off1+off2)
 	// result: (MOVDstore [off1+off2] {sym} x val mem)
@@ -6706,23 +7766,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstore)
@@ -6784,22 +7844,22 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (x.Op != OpSB || p.Uses == 1)
 	// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		x := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		x := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstorezero)
@@ -6812,22 +7872,22 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVHZload_0(v *Value) bool {
-	// match: (MOVHZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVHZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVHZload)
@@ -6950,22 +8010,22 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVHload_0(v *Value) bool {
-	// match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVHload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVHload)
@@ -7114,23 +8174,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVHstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVHstore)
@@ -7236,22 +8296,22 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVHstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (x.Op != OpSB || p.Uses == 1)
 	// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		x := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		x := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVHstorezero)
@@ -7264,22 +8324,22 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVWZload_0(v *Value) bool {
-	// match: (MOVWZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVWZload)
@@ -7432,22 +8492,22 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64MOVWload_0(v *Value) bool {
-	// match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVWload)
@@ -7626,23 +8686,23 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVWstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[2]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		ptr := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		ptr := p.Args[0]
 		val := v.Args[1]
 		mem := v.Args[2]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVWstore)
@@ -7748,22 +8808,22 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
-	// cond: canMergeSym(sym1,sym2)
+	// match: (MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem)
+	// cond: canMergeSym(sym1,sym2) 	&& (x.Op != OpSB || p.Uses == 1)
 	// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 	for {
 		off1 := v.AuxInt
 		sym1 := v.Aux
 		_ = v.Args[1]
-		v_0 := v.Args[0]
-		if v_0.Op != OpPPC64MOVDaddr {
+		p := v.Args[0]
+		if p.Op != OpPPC64MOVDaddr {
 			break
 		}
-		off2 := v_0.AuxInt
-		sym2 := v_0.Aux
-		x := v_0.Args[0]
+		off2 := p.AuxInt
+		sym2 := p.Aux
+		x := p.Args[0]
 		mem := v.Args[1]
-		if !(canMergeSym(sym1, sym2)) {
+		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVWstorezero)
@@ -7775,6 +8835,52 @@
 	}
 	return false
 }
+func rewriteValuePPC64_OpPPC64MTVSRD_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
+	// match: (MTVSRD (MOVDconst [c]))
+	// cond:
+	// result: (FMOVDconst [c])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpPPC64FMOVDconst)
+		v.AuxInt = c
+		return true
+	}
+	// match: (MTVSRD x:(MOVDload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (FMOVDload [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpPPC64MOVDload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpPPC64FMOVDload, typ.Float64)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValuePPC64_OpPPC64MaskIfNotCarry_0(v *Value) bool {
 	// match: (MaskIfNotCarry (ADDconstForCarry [c] (ANDconst [d] _)))
 	// cond: c < 0 && d > 0 && c + d < 0
@@ -7852,6 +8958,10 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64OR_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR (SLDconst x [c]) (SRDconst x [d]))
 	// cond: d == 64-c
 	// result: (ROTLconst [c] x)
@@ -7960,6 +9070,258 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int64 {
+			break
+		}
+		if v_0_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (OR (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) (SLD x (ANDconst <typ.Int64> [63] y)))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 64 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int64 {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int32 {
+			break
+		}
+		if v_0_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (OR (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) (SLW x (ANDconst <typ.Int32> [31] y)))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 32 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int32 {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
 	// match: (OR (MOVDconst [c]) (MOVDconst [d]))
 	// cond:
 	// result: (MOVDconst [c|d])
@@ -7998,6 +9360,13 @@
 		v.AuxInt = c | d
 		return true
 	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
 	// match: (OR x (MOVDconst [c]))
 	// cond: isU32Bit(c)
 	// result: (ORconst [c] x)
@@ -8036,6 +9405,29957 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (OR <t> x0:(MOVBZload [i0] {s} p mem) o1:(SLWconst x1:(MOVBZload [i1] {s} p mem) [8]))
+	// cond: !config.BigEndian 	&& i1 == i0+1 	&& x0.Uses ==1 && x1.Uses == 1 	&& o1.Uses == 1 	&& mergePoint(b, x0, x1) != nil 	&& clobber(x0) && clobber(x1) && clobber(o1)
+	// result: @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		x0 := v.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		s := x0.Aux
+		_ = x0.Args[1]
+		p := x0.Args[0]
+		mem := x0.Args[1]
+		o1 := v.Args[1]
+		if o1.Op != OpPPC64SLWconst {
+			break
+		}
+		if o1.AuxInt != 8 {
+			break
+		}
+		x1 := o1.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0) && clobber(x1) && clobber(o1)) {
+			break
+		}
+		b = mergePoint(b, x0, x1)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVHZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o1:(SLWconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))
+	// cond: !config.BigEndian 	&& i1 == i0+1 	&& x0.Uses ==1 && x1.Uses == 1 	&& o1.Uses == 1 	&& mergePoint(b, x0, x1) != nil 	&& clobber(x0) && clobber(x1) && clobber(o1)
+	// result: @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o1 := v.Args[0]
+		if o1.Op != OpPPC64SLWconst {
+			break
+		}
+		if o1.AuxInt != 8 {
+			break
+		}
+		x1 := o1.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		s := x1.Aux
+		_ = x1.Args[1]
+		p := x1.Args[0]
+		mem := x1.Args[1]
+		x0 := v.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0) && clobber(x1) && clobber(o1)) {
+			break
+		}
+		b = mergePoint(b, x0, x1)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVHZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24]) o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16]) x0:(MOVHZload [i0] {s} p mem)))
+	// cond: !config.BigEndian 	&& i2 == i0+2 	&& i3 == i0+3 	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 	&& o0.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 	&& mergePoint(b, x0, x1, x2) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) 	&& clobber(s0) && clobber(s1) 	&& clobber(o0)
+	// result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s1 := v.Args[0]
+		if s1.Op != OpPPC64SLWconst {
+			break
+		}
+		if s1.AuxInt != 24 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x2.AuxInt
+		s := x2.Aux
+		_ = x2.Args[1]
+		p := x2.Args[0]
+		mem := x2.Args[1]
+		o0 := v.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLWconst {
+			break
+		}
+		if s0.AuxInt != 16 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVHZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVWZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24]) o0:(OR <t> x0:(MOVHZload [i0] {s} p mem) s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16])))
+	// cond: !config.BigEndian 	&& i2 == i0+2 	&& i3 == i0+3 	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 	&& o0.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 	&& mergePoint(b, x0, x1, x2) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) 	&& clobber(s0) && clobber(s1) 	&& clobber(o0)
+	// result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s1 := v.Args[0]
+		if s1.Op != OpPPC64SLWconst {
+			break
+		}
+		if s1.AuxInt != 24 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x2.AuxInt
+		s := x2.Aux
+		_ = x2.Args[1]
+		p := x2.Args[0]
+		mem := x2.Args[1]
+		o0 := v.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVHZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLWconst {
+			break
+		}
+		if s0.AuxInt != 16 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVWZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o0:(OR <t> s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16]) x0:(MOVHZload [i0] {s} p mem)) s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24]))
+	// cond: !config.BigEndian 	&& i2 == i0+2 	&& i3 == i0+3 	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 	&& o0.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 	&& mergePoint(b, x0, x1, x2) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) 	&& clobber(s0) && clobber(s1) 	&& clobber(o0)
+	// result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o0 := v.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLWconst {
+			break
+		}
+		if s0.AuxInt != 16 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x1.AuxInt
+		s := x1.Aux
+		_ = x1.Args[1]
+		p := x1.Args[0]
+		mem := x1.Args[1]
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVHZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := v.Args[1]
+		if s1.Op != OpPPC64SLWconst {
+			break
+		}
+		if s1.AuxInt != 24 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVWZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o0:(OR <t> x0:(MOVHZload [i0] {s} p mem) s0:(SLWconst x1:(MOVBZload [i2] {s} p mem) [16])) s1:(SLWconst x2:(MOVBZload [i3] {s} p mem) [24]))
+	// cond: !config.BigEndian 	&& i2 == i0+2 	&& i3 == i0+3 	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1 	&& o0.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 	&& mergePoint(b, x0, x1, x2) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) 	&& clobber(s0) && clobber(s1) 	&& clobber(o0)
+	// result: @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o0 := v.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVHZload {
+			break
+		}
+		i0 := x0.AuxInt
+		s := x0.Aux
+		_ = x0.Args[1]
+		p := x0.Args[0]
+		mem := x0.Args[1]
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLWconst {
+			break
+		}
+		if s0.AuxInt != 16 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := v.Args[1]
+		if s1.Op != OpPPC64SLWconst {
+			break
+		}
+		if s1.AuxInt != 24 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && o0.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVWZload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_20(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_30(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_40(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_50(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_60(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_70(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_80(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]) o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		s6 := v.Args[0]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		s := x7.Aux
+		_ = x7.Args[1]
+		p := x7.Args[0]
+		mem := x7.Args[1]
+		o5 := v.Args[1]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_90(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_100(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_110(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48]) o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]))) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		s5 := o5.Args[0]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		s := x6.Aux
+		_ = x6.Args[1]
+		p := x6.Args[0]
+		mem := x6.Args[1]
+		o4 := o5.Args[1]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_120(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40]) o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]))) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		s4 := o4.Args[0]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		s := x5.Aux
+		_ = x5.Args[1]
+		p := x5.Args[0]
+		mem := x5.Args[1]
+		o3 := o4.Args[1]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_130(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32]) o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]))) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		s3 := o3.Args[0]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		s := x4.Aux
+		_ = x4.Args[1]
+		p := x4.Args[0]
+		mem := x4.Args[1]
+		o2 := o3.Args[1]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		s := x3.Aux
+		_ = x3.Args[1]
+		p := x3.Args[0]
+		mem := x3.Args[1]
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		s := x3.Aux
+		_ = x3.Args[1]
+		p := x3.Args[0]
+		mem := x3.Args[1]
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64OR_140(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		s := x3.Aux
+		_ = x3.Args[1]
+		p := x3.Args[0]
+		mem := x3.Args[1]
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24]) o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]))) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		s2 := o2.Args[0]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		s := x3.Aux
+		_ = x3.Args[1]
+		p := x3.Args[0]
+		mem := x3.Args[1]
+		o1 := o2.Args[1]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		s := x2.Aux
+		_ = x2.Args[1]
+		p := x2.Args[0]
+		mem := x2.Args[1]
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16]) o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]))) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		s1 := o1.Args[0]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		s := x2.Aux
+		_ = x2.Args[1]
+		p := x2.Args[0]
+		mem := x2.Args[1]
+		o0 := o1.Args[1]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8]) x0:(MOVBZload [i0] {s} p mem)) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		s0 := o0.Args[0]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		s := x1.Aux
+		_ = x1.Args[1]
+		p := x1.Args[0]
+		mem := x1.Args[1]
+		x0 := o0.Args[1]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		if x0.Aux != s {
+			break
+		}
+		_ = x0.Args[1]
+		if p != x0.Args[0] {
+			break
+		}
+		if mem != x0.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (OR <t> o5:(OR <t> o4:(OR <t> o3:(OR <t> o2:(OR <t> o1:(OR <t> o0:(OR <t> x0:(MOVBZload [i0] {s} p mem) s0:(SLDconst x1:(MOVBZload [i1] {s} p mem) [8])) s1:(SLDconst x2:(MOVBZload [i2] {s} p mem) [16])) s2:(SLDconst x3:(MOVBZload [i3] {s} p mem) [24])) s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])) s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])) s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])) s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56]))
+	// cond: !config.BigEndian 	&& i0%4 == 0 	&& i1 == i0+1 	&& i2 == i0+2 	&& i3 == i0+3 	&& i4 == i0+4 	&& i5 == i0+5 	&& i6 == i0+6 	&& i7 == i0+7 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 	&& mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil 	&& clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) 	&& clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber (s6) 	&& clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)
+	// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		o5 := v.Args[0]
+		if o5.Op != OpPPC64OR {
+			break
+		}
+		if o5.Type != t {
+			break
+		}
+		_ = o5.Args[1]
+		o4 := o5.Args[0]
+		if o4.Op != OpPPC64OR {
+			break
+		}
+		if o4.Type != t {
+			break
+		}
+		_ = o4.Args[1]
+		o3 := o4.Args[0]
+		if o3.Op != OpPPC64OR {
+			break
+		}
+		if o3.Type != t {
+			break
+		}
+		_ = o3.Args[1]
+		o2 := o3.Args[0]
+		if o2.Op != OpPPC64OR {
+			break
+		}
+		if o2.Type != t {
+			break
+		}
+		_ = o2.Args[1]
+		o1 := o2.Args[0]
+		if o1.Op != OpPPC64OR {
+			break
+		}
+		if o1.Type != t {
+			break
+		}
+		_ = o1.Args[1]
+		o0 := o1.Args[0]
+		if o0.Op != OpPPC64OR {
+			break
+		}
+		if o0.Type != t {
+			break
+		}
+		_ = o0.Args[1]
+		x0 := o0.Args[0]
+		if x0.Op != OpPPC64MOVBZload {
+			break
+		}
+		i0 := x0.AuxInt
+		s := x0.Aux
+		_ = x0.Args[1]
+		p := x0.Args[0]
+		mem := x0.Args[1]
+		s0 := o0.Args[1]
+		if s0.Op != OpPPC64SLDconst {
+			break
+		}
+		if s0.AuxInt != 8 {
+			break
+		}
+		x1 := s0.Args[0]
+		if x1.Op != OpPPC64MOVBZload {
+			break
+		}
+		i1 := x1.AuxInt
+		if x1.Aux != s {
+			break
+		}
+		_ = x1.Args[1]
+		if p != x1.Args[0] {
+			break
+		}
+		if mem != x1.Args[1] {
+			break
+		}
+		s1 := o1.Args[1]
+		if s1.Op != OpPPC64SLDconst {
+			break
+		}
+		if s1.AuxInt != 16 {
+			break
+		}
+		x2 := s1.Args[0]
+		if x2.Op != OpPPC64MOVBZload {
+			break
+		}
+		i2 := x2.AuxInt
+		if x2.Aux != s {
+			break
+		}
+		_ = x2.Args[1]
+		if p != x2.Args[0] {
+			break
+		}
+		if mem != x2.Args[1] {
+			break
+		}
+		s2 := o2.Args[1]
+		if s2.Op != OpPPC64SLDconst {
+			break
+		}
+		if s2.AuxInt != 24 {
+			break
+		}
+		x3 := s2.Args[0]
+		if x3.Op != OpPPC64MOVBZload {
+			break
+		}
+		i3 := x3.AuxInt
+		if x3.Aux != s {
+			break
+		}
+		_ = x3.Args[1]
+		if p != x3.Args[0] {
+			break
+		}
+		if mem != x3.Args[1] {
+			break
+		}
+		s3 := o3.Args[1]
+		if s3.Op != OpPPC64SLDconst {
+			break
+		}
+		if s3.AuxInt != 32 {
+			break
+		}
+		x4 := s3.Args[0]
+		if x4.Op != OpPPC64MOVBZload {
+			break
+		}
+		i4 := x4.AuxInt
+		if x4.Aux != s {
+			break
+		}
+		_ = x4.Args[1]
+		if p != x4.Args[0] {
+			break
+		}
+		if mem != x4.Args[1] {
+			break
+		}
+		s4 := o4.Args[1]
+		if s4.Op != OpPPC64SLDconst {
+			break
+		}
+		if s4.AuxInt != 40 {
+			break
+		}
+		x5 := s4.Args[0]
+		if x5.Op != OpPPC64MOVBZload {
+			break
+		}
+		i5 := x5.AuxInt
+		if x5.Aux != s {
+			break
+		}
+		_ = x5.Args[1]
+		if p != x5.Args[0] {
+			break
+		}
+		if mem != x5.Args[1] {
+			break
+		}
+		s5 := o5.Args[1]
+		if s5.Op != OpPPC64SLDconst {
+			break
+		}
+		if s5.AuxInt != 48 {
+			break
+		}
+		x6 := s5.Args[0]
+		if x6.Op != OpPPC64MOVBZload {
+			break
+		}
+		i6 := x6.AuxInt
+		if x6.Aux != s {
+			break
+		}
+		_ = x6.Args[1]
+		if p != x6.Args[0] {
+			break
+		}
+		if mem != x6.Args[1] {
+			break
+		}
+		s6 := v.Args[1]
+		if s6.Op != OpPPC64SLDconst {
+			break
+		}
+		if s6.AuxInt != 56 {
+			break
+		}
+		x7 := s6.Args[0]
+		if x7.Op != OpPPC64MOVBZload {
+			break
+		}
+		i7 := x7.AuxInt
+		if x7.Aux != s {
+			break
+		}
+		_ = x7.Args[1]
+		if p != x7.Args[0] {
+			break
+		}
+		if mem != x7.Args[1] {
+			break
+		}
+		if !(!config.BigEndian && i0%4 == 0 && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(s3) && clobber(s4) && clobber(s5) && clobber(s6) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5)) {
+			break
+		}
+		b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = i0
+		v0.Aux = s
+		v0.AddArg(p)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValuePPC64_OpPPC64ORN_0(v *Value) bool {
@@ -8125,6 +39445,10 @@
 	return false
 }
 func rewriteValuePPC64_OpPPC64XOR_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (XOR (SLDconst x [c]) (SRDconst x [d]))
 	// cond: d == 64-c
 	// result: (ROTLconst [c] x)
@@ -8233,6 +39557,258 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int64 {
+			break
+		}
+		if v_0_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (XOR (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) (SLD x (ANDconst <typ.Int64> [63] y)))
+	// cond:
+	// result: (ROTL x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRD {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 64 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 63 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLD {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int64 {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTL)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1.Type != typ.Int32 {
+			break
+		}
+		if v_0_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
+	// match: (XOR (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) (SLW x (ANDconst <typ.Int32> [31] y)))
+	// cond:
+	// result: (ROTLW x y)
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpPPC64SRW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_0_1.Type != typ.UInt {
+			break
+		}
+		_ = v_0_1.Args[1]
+		v_0_1_0 := v_0_1.Args[0]
+		if v_0_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_0_1_0.AuxInt != 32 {
+			break
+		}
+		v_0_1_1 := v_0_1.Args[1]
+		if v_0_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_0_1_1.Type != typ.UInt {
+			break
+		}
+		if v_0_1_1.AuxInt != 31 {
+			break
+		}
+		y := v_0_1_1.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SLW {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.Int32 {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		if y != v_1_1.Args[0] {
+			break
+		}
+		v.reset(OpPPC64ROTLW)
+		v.AddArg(x)
+		v.AddArg(y)
+		return true
+	}
 	// match: (XOR (MOVDconst [c]) (MOVDconst [d]))
 	// cond:
 	// result: (MOVDconst [c^d])
@@ -8271,6 +39847,9 @@
 		v.AuxInt = c ^ d
 		return true
 	}
+	return false
+}
+func rewriteValuePPC64_OpPPC64XOR_10(v *Value) bool {
 	// match: (XOR x (MOVDconst [c]))
 	// cond: isU32Bit(c)
 	// result: (XORconst [c] x)
@@ -9023,6 +40602,230 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Rsh32Ux64 x (AND y (MOVDconst [31])))
+	// cond:
+	// result: (SRW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32Ux64 x (AND (MOVDconst [31]) y))
+	// cond:
+	// result: (SRW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32Ux64 x (ANDconst <typ.UInt> [31] y))
+	// cond:
+	// result: (SRW x (ANDconst <typ.UInt> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		if v_1.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	// cond:
+	// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		y := v_1_1.Args[0]
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
+	// cond:
+	// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		y := v_1_1.Args[0]
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_1.AuxInt != 31 {
+			break
+		}
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> (MOVDconst [31]) y)))
+	// cond:
+	// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 31 {
+			break
+		}
+		y := v_1_1.Args[1]
+		v.reset(OpPPC64SRW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Rsh32Ux64 x y)
 	// cond:
 	// result: (SRW  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
@@ -9228,6 +41031,230 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Rsh32x64 x (AND y (MOVDconst [31])))
+	// cond:
+	// result: (SRAW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32x64 x (AND (MOVDconst [31]) y))
+	// cond:
+	// result: (SRAW x (ANDconst <typ.Int32> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32x64 x (ANDconst <typ.UInt> [31] y))
+	// cond:
+	// result: (SRAW x (ANDconst <typ.UInt> [31] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		if v_1.AuxInt != 31 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v0.AuxInt = 31
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	// cond:
+	// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1.AuxInt != 31 {
+			break
+		}
+		y := v_1_1.Args[0]
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
+	// cond:
+	// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		y := v_1_1.Args[0]
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_1.AuxInt != 31 {
+			break
+		}
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> (MOVDconst [31]) y)))
+	// cond:
+	// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 32 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 31 {
+			break
+		}
+		y := v_1_1.Args[1]
+		v.reset(OpPPC64SRAW)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 32
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 31
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Rsh32x64 x y)
 	// cond:
 	// result: (SRAW x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-32] y))))
@@ -9431,6 +41458,230 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Rsh64Ux64 x (AND y (MOVDconst [63])))
+	// cond:
+	// result: (SRD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64Ux64 x (AND (MOVDconst [63]) y))
+	// cond:
+	// result: (SRD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64Ux64 x (ANDconst <typ.UInt> [63] y))
+	// cond:
+	// result: (SRD x (ANDconst <typ.UInt> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		if v_1.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	// cond:
+	// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		y := v_1_1.Args[0]
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
+	// cond:
+	// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		y := v_1_1.Args[0]
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_1.AuxInt != 63 {
+			break
+		}
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> (MOVDconst [63]) y)))
+	// cond:
+	// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 63 {
+			break
+		}
+		y := v_1_1.Args[1]
+		v.reset(OpPPC64SRD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Rsh64Ux64 x y)
 	// cond:
 	// result: (SRD  x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
@@ -9636,6 +41887,230 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Rsh64x64 x (AND y (MOVDconst [63])))
+	// cond:
+	// result: (SRAD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64x64 x (AND (MOVDconst [63]) y))
+	// cond:
+	// result: (SRAD x (ANDconst <typ.Int64> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64AND {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64x64 x (ANDconst <typ.UInt> [63] y))
+	// cond:
+	// result: (SRAD x (ANDconst <typ.UInt> [63] y))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		if v_1.AuxInt != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v0.AuxInt = 63
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	// cond:
+	// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64ANDconst {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		if v_1_1.AuxInt != 63 {
+			break
+		}
+		y := v_1_1.Args[0]
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
+	// cond:
+	// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		y := v_1_1.Args[0]
+		v_1_1_1 := v_1_1.Args[1]
+		if v_1_1_1.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_1.AuxInt != 63 {
+			break
+		}
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> (MOVDconst [63]) y)))
+	// cond:
+	// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+	for {
+		_ = v.Args[1]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpPPC64SUB {
+			break
+		}
+		if v_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_0.AuxInt != 64 {
+			break
+		}
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpPPC64AND {
+			break
+		}
+		if v_1_1.Type != typ.UInt {
+			break
+		}
+		_ = v_1_1.Args[1]
+		v_1_1_0 := v_1_1.Args[0]
+		if v_1_1_0.Op != OpPPC64MOVDconst {
+			break
+		}
+		if v_1_1_0.AuxInt != 63 {
+			break
+		}
+		y := v_1_1.Args[1]
+		v.reset(OpPPC64SRAD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
+		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
+		v1.AuxInt = 64
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+		v2.AuxInt = 63
+		v2.AddArg(y)
+		v0.AddArg(v2)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Rsh64x64 x y)
 	// cond:
 	// result: (SRAD x (ORN y <typ.Int64> (MaskIfNotCarry (ADDconstForCarry [-64] y))))
@@ -10463,6 +42938,17 @@
 		return true
 	}
 }
+func rewriteValuePPC64_OpTrunc_0(v *Value) bool {
+	// match: (Trunc x)
+	// cond:
+	// result: (FTRUNC x)
+	for {
+		x := v.Args[0]
+		v.reset(OpPPC64FTRUNC)
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValuePPC64_OpTrunc16to8_0(v *Value) bool {
 	// match: (Trunc16to8 x)
 	// cond:
@@ -10727,9 +43213,28 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (Zero [8] {t} destptr mem)
+	// cond: t.(*types.Type).Alignment()%4 == 0
+	// result: (MOVDstorezero destptr mem)
+	for {
+		if v.AuxInt != 8 {
+			break
+		}
+		t := v.Aux
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(t.(*types.Type).Alignment()%4 == 0) {
+			break
+		}
+		v.reset(OpPPC64MOVDstorezero)
+		v.AddArg(destptr)
+		v.AddArg(mem)
+		return true
+	}
 	// match: (Zero [8] destptr mem)
 	// cond:
-	// result: (MOVDstorezero destptr mem)
+	// result: (MOVWstorezero [4] destptr                 (MOVWstorezero [0] destptr mem))
 	for {
 		if v.AuxInt != 8 {
 			break
@@ -10737,25 +43242,10 @@
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
-		v.reset(OpPPC64MOVDstorezero)
-		v.AddArg(destptr)
-		v.AddArg(mem)
-		return true
-	}
-	// match: (Zero [12] destptr mem)
-	// cond:
-	// result: (MOVWstorezero [8] destptr                 (MOVDstorezero [0] destptr mem))
-	for {
-		if v.AuxInt != 12 {
-			break
-		}
-		_ = v.Args[1]
-		destptr := v.Args[0]
-		mem := v.Args[1]
 		v.reset(OpPPC64MOVWstorezero)
-		v.AuxInt = 8
+		v.AuxInt = 4
 		v.AddArg(destptr)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVWstorezero, types.TypeMem)
 		v0.AuxInt = 0
 		v0.AddArg(destptr)
 		v0.AddArg(mem)
@@ -10767,16 +43257,44 @@
 func rewriteValuePPC64_OpZero_10(v *Value) bool {
 	b := v.Block
 	_ = b
-	// match: (Zero [16] destptr mem)
-	// cond:
+	// match: (Zero [12] {t} destptr mem)
+	// cond: t.(*types.Type).Alignment()%4 == 0
+	// result: (MOVWstorezero [8] destptr                 (MOVDstorezero [0] destptr mem))
+	for {
+		if v.AuxInt != 12 {
+			break
+		}
+		t := v.Aux
+		_ = v.Args[1]
+		destptr := v.Args[0]
+		mem := v.Args[1]
+		if !(t.(*types.Type).Alignment()%4 == 0) {
+			break
+		}
+		v.reset(OpPPC64MOVWstorezero)
+		v.AuxInt = 8
+		v.AddArg(destptr)
+		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
+		v0.AuxInt = 0
+		v0.AddArg(destptr)
+		v0.AddArg(mem)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Zero [16] {t} destptr mem)
+	// cond: t.(*types.Type).Alignment()%4 == 0
 	// result: (MOVDstorezero [8] destptr                 (MOVDstorezero [0] destptr mem))
 	for {
 		if v.AuxInt != 16 {
 			break
 		}
+		t := v.Aux
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(t.(*types.Type).Alignment()%4 == 0) {
+			break
+		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = 8
 		v.AddArg(destptr)
@@ -10787,16 +43305,20 @@
 		v.AddArg(v0)
 		return true
 	}
-	// match: (Zero [24] destptr mem)
-	// cond:
-	// result: (MOVDstorezero [16] destptr 		(MOVDstorezero [8] destptr 			(MOVDstorezero [0] destptr mem)))
+	// match: (Zero [24] {t} destptr mem)
+	// cond: t.(*types.Type).Alignment()%4 == 0
+	// result: (MOVDstorezero [16] destptr                (MOVDstorezero [8] destptr                        (MOVDstorezero [0] destptr mem)))
 	for {
 		if v.AuxInt != 24 {
 			break
 		}
+		t := v.Aux
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(t.(*types.Type).Alignment()%4 == 0) {
+			break
+		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = 16
 		v.AddArg(destptr)
@@ -10811,16 +43333,20 @@
 		v.AddArg(v0)
 		return true
 	}
-	// match: (Zero [32] destptr mem)
-	// cond:
-	// result: (MOVDstorezero [24] destptr 		(MOVDstorezero [16] destptr 			(MOVDstorezero [8] destptr 				(MOVDstorezero [0] destptr mem))))
+	// match: (Zero [32] {t} destptr mem)
+	// cond: t.(*types.Type).Alignment()%4 == 0
+	// result: (MOVDstorezero [24] destptr                (MOVDstorezero [16] destptr                        (MOVDstorezero [8] destptr                                (MOVDstorezero [0] destptr mem))))
 	for {
 		if v.AuxInt != 32 {
 			break
 		}
+		t := v.Aux
 		_ = v.Args[1]
 		destptr := v.Args[0]
 		mem := v.Args[1]
+		if !(t.(*types.Type).Alignment()%4 == 0) {
+			break
+		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = 24
 		v.AddArg(destptr)
@@ -10839,114 +43365,6 @@
 		v.AddArg(v0)
 		return true
 	}
-	// match: (Zero [40] destptr mem)
-	// cond:
-	// result: (MOVDstorezero [32] destptr 		(MOVDstorezero [24] destptr 			(MOVDstorezero [16] destptr 				(MOVDstorezero [8] destptr 					(MOVDstorezero [0] destptr mem)))))
-	for {
-		if v.AuxInt != 40 {
-			break
-		}
-		_ = v.Args[1]
-		destptr := v.Args[0]
-		mem := v.Args[1]
-		v.reset(OpPPC64MOVDstorezero)
-		v.AuxInt = 32
-		v.AddArg(destptr)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v0.AuxInt = 24
-		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v1.AuxInt = 16
-		v1.AddArg(destptr)
-		v2 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v2.AuxInt = 8
-		v2.AddArg(destptr)
-		v3 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v3.AuxInt = 0
-		v3.AddArg(destptr)
-		v3.AddArg(mem)
-		v2.AddArg(v3)
-		v1.AddArg(v2)
-		v0.AddArg(v1)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Zero [48] destptr mem)
-	// cond:
-	// result: (MOVDstorezero [40] destptr 		(MOVDstorezero [32] destptr 			(MOVDstorezero [24] destptr 				(MOVDstorezero [16] destptr 					(MOVDstorezero [8] destptr 						(MOVDstorezero [0] destptr mem))))))
-	for {
-		if v.AuxInt != 48 {
-			break
-		}
-		_ = v.Args[1]
-		destptr := v.Args[0]
-		mem := v.Args[1]
-		v.reset(OpPPC64MOVDstorezero)
-		v.AuxInt = 40
-		v.AddArg(destptr)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v0.AuxInt = 32
-		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v1.AuxInt = 24
-		v1.AddArg(destptr)
-		v2 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v2.AuxInt = 16
-		v2.AddArg(destptr)
-		v3 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v3.AuxInt = 8
-		v3.AddArg(destptr)
-		v4 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v4.AuxInt = 0
-		v4.AddArg(destptr)
-		v4.AddArg(mem)
-		v3.AddArg(v4)
-		v2.AddArg(v3)
-		v1.AddArg(v2)
-		v0.AddArg(v1)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Zero [56] destptr mem)
-	// cond:
-	// result: (MOVDstorezero [48] destptr 		(MOVDstorezero [40] destptr 			(MOVDstorezero [32] destptr 				(MOVDstorezero [24] destptr 					(MOVDstorezero [16] destptr 						(MOVDstorezero [8] destptr 							(MOVDstorezero [0] destptr mem)))))))
-	for {
-		if v.AuxInt != 56 {
-			break
-		}
-		_ = v.Args[1]
-		destptr := v.Args[0]
-		mem := v.Args[1]
-		v.reset(OpPPC64MOVDstorezero)
-		v.AuxInt = 48
-		v.AddArg(destptr)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v0.AuxInt = 40
-		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v1.AuxInt = 32
-		v1.AddArg(destptr)
-		v2 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v2.AuxInt = 24
-		v2.AddArg(destptr)
-		v3 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v3.AuxInt = 16
-		v3.AddArg(destptr)
-		v4 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v4.AuxInt = 8
-		v4.AddArg(destptr)
-		v5 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
-		v5.AuxInt = 0
-		v5.AddArg(destptr)
-		v5.AddArg(mem)
-		v4.AddArg(v5)
-		v3.AddArg(v4)
-		v2.AddArg(v3)
-		v1.AddArg(v2)
-		v0.AddArg(v1)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Zero [s] ptr mem)
 	// cond:
 	// result: (LoweredZero [s] ptr mem)
@@ -11059,6 +43477,7 @@
 			v0.AuxInt = c
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (CMPWconst [0] (ANDconst [c] x)) yes no)
@@ -11083,6 +43502,7 @@
 			v0.AuxInt = c
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagEQ) yes no)
@@ -11095,6 +43515,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT) yes no)
@@ -11107,6 +43528,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11120,6 +43542,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11134,6 +43557,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64EQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockPPC64GE:
@@ -11147,6 +43571,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT) yes no)
@@ -11159,6 +43584,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11172,6 +43598,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (InvertFlags cmp) yes no)
@@ -11185,6 +43612,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64LE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockPPC64GT:
@@ -11198,6 +43626,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11211,6 +43640,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11224,6 +43654,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (InvertFlags cmp) yes no)
@@ -11237,6 +43668,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64LT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -11251,6 +43683,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64EQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (NotEqual cc) yes no)
@@ -11264,6 +43697,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64NE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessThan cc) yes no)
@@ -11277,6 +43711,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64LT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (LessEqual cc) yes no)
@@ -11290,6 +43725,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64LE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterThan cc) yes no)
@@ -11303,6 +43739,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64GT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (GreaterEqual cc) yes no)
@@ -11316,6 +43753,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64GE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (FLessThan cc) yes no)
@@ -11329,6 +43767,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64FLT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (FLessEqual cc) yes no)
@@ -11342,6 +43781,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64FLE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (FGreaterThan cc) yes no)
@@ -11355,6 +43795,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64FGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (FGreaterEqual cc) yes no)
@@ -11368,6 +43809,7 @@
 			cc := v.Args[0]
 			b.Kind = BlockPPC64FGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -11382,6 +43824,7 @@
 			v0.AuxInt = 0
 			v0.AddArg(cond)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockPPC64LE:
@@ -11395,6 +43838,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT) yes no)
@@ -11407,6 +43851,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT) yes no)
@@ -11419,6 +43864,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11433,6 +43879,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64GE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockPPC64LT:
@@ -11446,6 +43893,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11459,6 +43907,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT) yes no)
@@ -11471,6 +43920,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11485,6 +43935,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64GT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	case BlockPPC64NE:
@@ -11506,6 +43957,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64EQ
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (NotEqual cc)) yes no)
@@ -11526,6 +43978,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64NE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (LessThan cc)) yes no)
@@ -11546,6 +43999,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64LT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (LessEqual cc)) yes no)
@@ -11566,6 +44020,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64LE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (GreaterThan cc)) yes no)
@@ -11586,6 +44041,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64GT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (GreaterEqual cc)) yes no)
@@ -11606,6 +44062,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64GE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (FLessThan cc)) yes no)
@@ -11626,6 +44083,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64FLT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (FLessEqual cc)) yes no)
@@ -11646,6 +44104,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64FLE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (FGreaterThan cc)) yes no)
@@ -11666,6 +44125,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64FGT
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (FGreaterEqual cc)) yes no)
@@ -11686,6 +44146,7 @@
 			cc := v_0.Args[0]
 			b.Kind = BlockPPC64FGE
 			b.SetControl(cc)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPconst [0] (ANDconst [c] x)) yes no)
@@ -11710,6 +44171,7 @@
 			v0.AuxInt = c
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (ANDconst [c] x)) yes no)
@@ -11734,6 +44196,7 @@
 			v0.AuxInt = c
 			v0.AddArg(x)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -11746,6 +44209,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -11759,6 +44223,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT) yes no)
@@ -11771,6 +44236,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -11784,6 +44250,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockPPC64NE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 	}
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index e84cb5b..5f25e9d 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -73,6 +73,8 @@
 		return rewriteValueS390X_OpBswap32_0(v)
 	case OpBswap64:
 		return rewriteValueS390X_OpBswap64_0(v)
+	case OpCeil:
+		return rewriteValueS390X_OpCeil_0(v)
 	case OpClosureCall:
 		return rewriteValueS390X_OpClosureCall_0(v)
 	case OpCom16:
@@ -161,6 +163,8 @@
 		return rewriteValueS390X_OpEqB_0(v)
 	case OpEqPtr:
 		return rewriteValueS390X_OpEqPtr_0(v)
+	case OpFloor:
+		return rewriteValueS390X_OpFloor_0(v)
 	case OpGeq16:
 		return rewriteValueS390X_OpGeq16_0(v)
 	case OpGeq16U:
@@ -181,6 +185,8 @@
 		return rewriteValueS390X_OpGeq8_0(v)
 	case OpGeq8U:
 		return rewriteValueS390X_OpGeq8U_0(v)
+	case OpGetCallerSP:
+		return rewriteValueS390X_OpGetCallerSP_0(v)
 	case OpGetClosurePtr:
 		return rewriteValueS390X_OpGetClosurePtr_0(v)
 	case OpGetG:
@@ -371,10 +377,14 @@
 		return rewriteValueS390X_OpOr8_0(v)
 	case OpOrB:
 		return rewriteValueS390X_OpOrB_0(v)
+	case OpRound:
+		return rewriteValueS390X_OpRound_0(v)
 	case OpRound32F:
 		return rewriteValueS390X_OpRound32F_0(v)
 	case OpRound64F:
 		return rewriteValueS390X_OpRound64F_0(v)
+	case OpRoundToEven:
+		return rewriteValueS390X_OpRoundToEven_0(v)
 	case OpRsh16Ux16:
 		return rewriteValueS390X_OpRsh16Ux16_0(v)
 	case OpRsh16Ux32:
@@ -445,16 +455,24 @@
 		return rewriteValueS390X_OpS390XADDW_0(v) || rewriteValueS390X_OpS390XADDW_10(v)
 	case OpS390XADDWconst:
 		return rewriteValueS390X_OpS390XADDWconst_0(v)
+	case OpS390XADDWload:
+		return rewriteValueS390X_OpS390XADDWload_0(v)
 	case OpS390XADDconst:
 		return rewriteValueS390X_OpS390XADDconst_0(v)
+	case OpS390XADDload:
+		return rewriteValueS390X_OpS390XADDload_0(v)
 	case OpS390XAND:
 		return rewriteValueS390X_OpS390XAND_0(v) || rewriteValueS390X_OpS390XAND_10(v)
 	case OpS390XANDW:
 		return rewriteValueS390X_OpS390XANDW_0(v) || rewriteValueS390X_OpS390XANDW_10(v)
 	case OpS390XANDWconst:
 		return rewriteValueS390X_OpS390XANDWconst_0(v)
+	case OpS390XANDWload:
+		return rewriteValueS390X_OpS390XANDWload_0(v)
 	case OpS390XANDconst:
 		return rewriteValueS390X_OpS390XANDconst_0(v)
+	case OpS390XANDload:
+		return rewriteValueS390X_OpS390XANDload_0(v)
 	case OpS390XCMP:
 		return rewriteValueS390X_OpS390XCMP_0(v)
 	case OpS390XCMPU:
@@ -471,6 +489,8 @@
 		return rewriteValueS390X_OpS390XCMPWconst_0(v)
 	case OpS390XCMPconst:
 		return rewriteValueS390X_OpS390XCMPconst_0(v)
+	case OpS390XCPSDR:
+		return rewriteValueS390X_OpS390XCPSDR_0(v)
 	case OpS390XFADD:
 		return rewriteValueS390X_OpS390XFADD_0(v)
 	case OpS390XFADDS:
@@ -491,10 +511,20 @@
 		return rewriteValueS390X_OpS390XFMOVSstore_0(v)
 	case OpS390XFMOVSstoreidx:
 		return rewriteValueS390X_OpS390XFMOVSstoreidx_0(v)
+	case OpS390XFNEG:
+		return rewriteValueS390X_OpS390XFNEG_0(v)
+	case OpS390XFNEGS:
+		return rewriteValueS390X_OpS390XFNEGS_0(v)
 	case OpS390XFSUB:
 		return rewriteValueS390X_OpS390XFSUB_0(v)
 	case OpS390XFSUBS:
 		return rewriteValueS390X_OpS390XFSUBS_0(v)
+	case OpS390XLDGR:
+		return rewriteValueS390X_OpS390XLDGR_0(v)
+	case OpS390XLEDBR:
+		return rewriteValueS390X_OpS390XLEDBR_0(v)
+	case OpS390XLGDR:
+		return rewriteValueS390X_OpS390XLGDR_0(v)
 	case OpS390XLoweredRound32F:
 		return rewriteValueS390X_OpS390XLoweredRound32F_0(v)
 	case OpS390XLoweredRound64F:
@@ -507,6 +537,8 @@
 		return rewriteValueS390X_OpS390XMOVBZreg_0(v) || rewriteValueS390X_OpS390XMOVBZreg_10(v)
 	case OpS390XMOVBload:
 		return rewriteValueS390X_OpS390XMOVBload_0(v)
+	case OpS390XMOVBloadidx:
+		return rewriteValueS390X_OpS390XMOVBloadidx_0(v)
 	case OpS390XMOVBreg:
 		return rewriteValueS390X_OpS390XMOVBreg_0(v)
 	case OpS390XMOVBstore:
@@ -555,8 +587,10 @@
 		return rewriteValueS390X_OpS390XMOVHZreg_0(v)
 	case OpS390XMOVHload:
 		return rewriteValueS390X_OpS390XMOVHload_0(v)
+	case OpS390XMOVHloadidx:
+		return rewriteValueS390X_OpS390XMOVHloadidx_0(v)
 	case OpS390XMOVHreg:
-		return rewriteValueS390X_OpS390XMOVHreg_0(v)
+		return rewriteValueS390X_OpS390XMOVHreg_0(v) || rewriteValueS390X_OpS390XMOVHreg_10(v)
 	case OpS390XMOVHstore:
 		return rewriteValueS390X_OpS390XMOVHstore_0(v) || rewriteValueS390X_OpS390XMOVHstore_10(v)
 	case OpS390XMOVHstoreconst:
@@ -572,9 +606,11 @@
 	case OpS390XMOVWZloadidx:
 		return rewriteValueS390X_OpS390XMOVWZloadidx_0(v)
 	case OpS390XMOVWZreg:
-		return rewriteValueS390X_OpS390XMOVWZreg_0(v)
+		return rewriteValueS390X_OpS390XMOVWZreg_0(v) || rewriteValueS390X_OpS390XMOVWZreg_10(v)
 	case OpS390XMOVWload:
 		return rewriteValueS390X_OpS390XMOVWload_0(v)
+	case OpS390XMOVWloadidx:
+		return rewriteValueS390X_OpS390XMOVWloadidx_0(v)
 	case OpS390XMOVWreg:
 		return rewriteValueS390X_OpS390XMOVWreg_0(v) || rewriteValueS390X_OpS390XMOVWreg_10(v)
 	case OpS390XMOVWstore:
@@ -587,10 +623,14 @@
 		return rewriteValueS390X_OpS390XMULLD_0(v)
 	case OpS390XMULLDconst:
 		return rewriteValueS390X_OpS390XMULLDconst_0(v)
+	case OpS390XMULLDload:
+		return rewriteValueS390X_OpS390XMULLDload_0(v)
 	case OpS390XMULLW:
 		return rewriteValueS390X_OpS390XMULLW_0(v)
 	case OpS390XMULLWconst:
 		return rewriteValueS390X_OpS390XMULLWconst_0(v)
+	case OpS390XMULLWload:
+		return rewriteValueS390X_OpS390XMULLWload_0(v)
 	case OpS390XNEG:
 		return rewriteValueS390X_OpS390XNEG_0(v)
 	case OpS390XNEGW:
@@ -605,8 +645,12 @@
 		return rewriteValueS390X_OpS390XORW_0(v) || rewriteValueS390X_OpS390XORW_10(v) || rewriteValueS390X_OpS390XORW_20(v) || rewriteValueS390X_OpS390XORW_30(v) || rewriteValueS390X_OpS390XORW_40(v) || rewriteValueS390X_OpS390XORW_50(v) || rewriteValueS390X_OpS390XORW_60(v) || rewriteValueS390X_OpS390XORW_70(v) || rewriteValueS390X_OpS390XORW_80(v) || rewriteValueS390X_OpS390XORW_90(v)
 	case OpS390XORWconst:
 		return rewriteValueS390X_OpS390XORWconst_0(v)
+	case OpS390XORWload:
+		return rewriteValueS390X_OpS390XORWload_0(v)
 	case OpS390XORconst:
 		return rewriteValueS390X_OpS390XORconst_0(v)
+	case OpS390XORload:
+		return rewriteValueS390X_OpS390XORload_0(v)
 	case OpS390XSLD:
 		return rewriteValueS390X_OpS390XSLD_0(v)
 	case OpS390XSLW:
@@ -621,6 +665,8 @@
 		return rewriteValueS390X_OpS390XSRAWconst_0(v)
 	case OpS390XSRD:
 		return rewriteValueS390X_OpS390XSRD_0(v)
+	case OpS390XSRDconst:
+		return rewriteValueS390X_OpS390XSRDconst_0(v)
 	case OpS390XSRW:
 		return rewriteValueS390X_OpS390XSRW_0(v)
 	case OpS390XSTM2:
@@ -637,16 +683,24 @@
 		return rewriteValueS390X_OpS390XSUBW_0(v)
 	case OpS390XSUBWconst:
 		return rewriteValueS390X_OpS390XSUBWconst_0(v)
+	case OpS390XSUBWload:
+		return rewriteValueS390X_OpS390XSUBWload_0(v)
 	case OpS390XSUBconst:
 		return rewriteValueS390X_OpS390XSUBconst_0(v)
+	case OpS390XSUBload:
+		return rewriteValueS390X_OpS390XSUBload_0(v)
 	case OpS390XXOR:
 		return rewriteValueS390X_OpS390XXOR_0(v) || rewriteValueS390X_OpS390XXOR_10(v)
 	case OpS390XXORW:
 		return rewriteValueS390X_OpS390XXORW_0(v) || rewriteValueS390X_OpS390XXORW_10(v)
 	case OpS390XXORWconst:
 		return rewriteValueS390X_OpS390XXORWconst_0(v)
+	case OpS390XXORWload:
+		return rewriteValueS390X_OpS390XXORWload_0(v)
 	case OpS390XXORconst:
 		return rewriteValueS390X_OpS390XXORconst_0(v)
+	case OpS390XXORload:
+		return rewriteValueS390X_OpS390XXORload_0(v)
 	case OpSelect0:
 		return rewriteValueS390X_OpSelect0_0(v)
 	case OpSelect1:
@@ -685,6 +739,8 @@
 		return rewriteValueS390X_OpSub8_0(v)
 	case OpSubPtr:
 		return rewriteValueS390X_OpSubPtr_0(v)
+	case OpTrunc:
+		return rewriteValueS390X_OpTrunc_0(v)
 	case OpTrunc16to8:
 		return rewriteValueS390X_OpTrunc16to8_0(v)
 	case OpTrunc32to16:
@@ -1172,6 +1228,18 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpCeil_0(v *Value) bool {
+	// match: (Ceil x)
+	// cond:
+	// result: (FIDBR [6] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpS390XFIDBR)
+		v.AuxInt = 6
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueS390X_OpClosureCall_0(v *Value) bool {
 	// match: (ClosureCall [argwid] entry closure mem)
 	// cond:
@@ -1911,6 +1979,18 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpFloor_0(v *Value) bool {
+	// match: (Floor x)
+	// cond:
+	// result: (FIDBR [7] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpS390XFIDBR)
+		v.AuxInt = 7
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueS390X_OpGeq16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -2187,6 +2267,15 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpGetCallerSP_0(v *Value) bool {
+	// match: (GetCallerSP)
+	// cond:
+	// result: (LoweredGetCallerSP)
+	for {
+		v.reset(OpS390XLoweredGetCallerSP)
+		return true
+	}
+}
 func rewriteValueS390X_OpGetClosurePtr_0(v *Value) bool {
 	// match: (GetClosurePtr)
 	// cond:
@@ -4913,6 +5002,18 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpRound_0(v *Value) bool {
+	// match: (Round x)
+	// cond:
+	// result: (FIDBR [1] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpS390XFIDBR)
+		v.AuxInt = 1
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueS390X_OpRound32F_0(v *Value) bool {
 	// match: (Round32F x)
 	// cond:
@@ -4935,6 +5036,18 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpRoundToEven_0(v *Value) bool {
+	// match: (RoundToEven x)
+	// cond:
+	// result: (FIDBR [4] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpS390XFIDBR)
+		v.AuxInt = 4
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueS390X_OpRsh16Ux16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -6186,7 +6299,7 @@
 func rewriteValueS390X_OpS390XADDW_0(v *Value) bool {
 	// match: (ADDW x (MOVDconst [c]))
 	// cond:
-	// result: (ADDWconst [c] x)
+	// result: (ADDWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -6196,13 +6309,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XADDWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (ADDW (MOVDconst [c]) x)
 	// cond:
-	// result: (ADDWconst [c] x)
+	// result: (ADDWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -6212,7 +6325,7 @@
 		c := v_0.AuxInt
 		x := v.Args[1]
 		v.reset(OpS390XADDWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
@@ -6578,6 +6691,62 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XADDWload_0(v *Value) bool {
+	// match: (ADDWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ADDWload  [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XADDWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ADDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ADDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XADDWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XADDconst_0(v *Value) bool {
 	// match: (ADDconst [c] (MOVDaddr [d] {s} x:(SB)))
 	// cond: ((c+d)&1 == 0) && is32Bit(c+d)
@@ -6696,6 +6865,97 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XADDload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (ADDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (ADD   x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XADD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ADDload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ADDload   [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XADDload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ADDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XADDload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XAND_0(v *Value) bool {
 	// match: (AND x (MOVDconst [c]))
 	// cond: is32Bit(c) && c < 0
@@ -7009,7 +7269,7 @@
 func rewriteValueS390X_OpS390XANDW_0(v *Value) bool {
 	// match: (ANDW x (MOVDconst [c]))
 	// cond:
-	// result: (ANDWconst [c] x)
+	// result: (ANDWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -7019,13 +7279,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XANDWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (ANDW (MOVDconst [c]) x)
 	// cond:
-	// result: (ANDWconst [c] x)
+	// result: (ANDWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -7035,7 +7295,7 @@
 		c := v_0.AuxInt
 		x := v.Args[1]
 		v.reset(OpS390XANDWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
@@ -7365,6 +7625,62 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XANDWload_0(v *Value) bool {
+	// match: (ANDWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ANDWload  [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XANDWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ANDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ANDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XANDWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XANDconst_0(v *Value) bool {
 	// match: (ANDconst [c] (ANDconst [d] x))
 	// cond:
@@ -7422,6 +7738,97 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XANDload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (ANDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (AND   x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XAND)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ANDload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ANDload   [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XANDload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ANDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ANDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XANDload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XCMP_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -7472,7 +7879,7 @@
 	_ = b
 	// match: (CMPU x (MOVDconst [c]))
 	// cond: isU32Bit(c)
-	// result: (CMPUconst x [int64(uint32(c))])
+	// result: (CMPUconst x [int64(int32(c))])
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -7485,13 +7892,13 @@
 			break
 		}
 		v.reset(OpS390XCMPUconst)
-		v.AuxInt = int64(uint32(c))
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (CMPU (MOVDconst [c]) x)
 	// cond: isU32Bit(c)
-	// result: (InvertFlags (CMPUconst x [int64(uint32(c))]))
+	// result: (InvertFlags (CMPUconst x [int64(int32(c))]))
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -7505,7 +7912,7 @@
 		}
 		v.reset(OpS390XInvertFlags)
 		v0 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-		v0.AuxInt = int64(uint32(c))
+		v0.AuxInt = int64(int32(c))
 		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
@@ -7568,7 +7975,7 @@
 	_ = b
 	// match: (CMPW x (MOVDconst [c]))
 	// cond:
-	// result: (CMPWconst x [c])
+	// result: (CMPWconst x [int64(int32(c))])
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -7578,13 +7985,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XCMPWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (CMPW (MOVDconst [c]) x)
 	// cond:
-	// result: (InvertFlags (CMPWconst x [c]))
+	// result: (InvertFlags (CMPWconst x [int64(int32(c))]))
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -7595,7 +8002,7 @@
 		x := v.Args[1]
 		v.reset(OpS390XInvertFlags)
 		v0 := b.NewValue0(v.Pos, OpS390XCMPWconst, types.TypeFlags)
-		v0.AuxInt = c
+		v0.AuxInt = int64(int32(c))
 		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
@@ -7607,7 +8014,7 @@
 	_ = b
 	// match: (CMPWU x (MOVDconst [c]))
 	// cond:
-	// result: (CMPWUconst x [int64(uint32(c))])
+	// result: (CMPWUconst x [int64(int32(c))])
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -7617,13 +8024,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XCMPWUconst)
-		v.AuxInt = int64(uint32(c))
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (CMPWU (MOVDconst [c]) x)
 	// cond:
-	// result: (InvertFlags (CMPWUconst x [int64(uint32(c))]))
+	// result: (InvertFlags (CMPWUconst x [int64(int32(c))]))
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -7634,7 +8041,7 @@
 		x := v.Args[1]
 		v.reset(OpS390XInvertFlags)
 		v0 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-		v0.AuxInt = int64(uint32(c))
+		v0.AuxInt = int64(int32(c))
 		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
@@ -7903,6 +8310,45 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XCPSDR_0(v *Value) bool {
+	// match: (CPSDR y (FMOVDconst [c]))
+	// cond: c & -1<<63 == 0
+	// result: (LPDFR y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XFMOVDconst {
+			break
+		}
+		c := v_1.AuxInt
+		if !(c&-1<<63 == 0) {
+			break
+		}
+		v.reset(OpS390XLPDFR)
+		v.AddArg(y)
+		return true
+	}
+	// match: (CPSDR y (FMOVDconst [c]))
+	// cond: c & -1<<63 != 0
+	// result: (LNDFR y)
+	for {
+		_ = v.Args[1]
+		y := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XFMOVDconst {
+			break
+		}
+		c := v_1.AuxInt
+		if !(c&-1<<63 != 0) {
+			break
+		}
+		v.reset(OpS390XLNDFR)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XFADD_0(v *Value) bool {
 	// match: (FADD (FMUL y z) x)
 	// cond:
@@ -7986,6 +8432,63 @@
 	return false
 }
 func rewriteValueS390X_OpS390XFMOVDload_0(v *Value) bool {
+	// match: (FMOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (LDGR x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XLDGR)
+		v.AddArg(x)
+		return true
+	}
+	// match: (FMOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: x
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpCopy)
+		v.Type = x.Type
+		v.AddArg(x)
+		return true
+	}
 	// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (FMOVDload [off1+off2] {sym} ptr mem)
@@ -8093,7 +8596,7 @@
 }
 func rewriteValueS390X_OpS390XFMOVDloadidx_0(v *Value) bool {
 	// match: (FMOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVDloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8107,6 +8610,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8116,7 +8622,7 @@
 		return true
 	}
 	// match: (FMOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVDloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8130,6 +8636,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8256,7 +8765,7 @@
 }
 func rewriteValueS390X_OpS390XFMOVDstoreidx_0(v *Value) bool {
 	// match: (FMOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8271,6 +8780,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8281,7 +8793,7 @@
 		return true
 	}
 	// match: (FMOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8296,6 +8808,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8308,6 +8823,35 @@
 	return false
 }
 func rewriteValueS390X_OpS390XFMOVSload_0(v *Value) bool {
+	// match: (FMOVSload [off] {sym} ptr1 (FMOVSstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: x
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XFMOVSstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpCopy)
+		v.Type = x.Type
+		v.AddArg(x)
+		return true
+	}
 	// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (FMOVSload [off1+off2] {sym} ptr mem)
@@ -8415,7 +8959,7 @@
 }
 func rewriteValueS390X_OpS390XFMOVSloadidx_0(v *Value) bool {
 	// match: (FMOVSloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVSloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8429,6 +8973,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVSloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8438,7 +8985,7 @@
 		return true
 	}
 	// match: (FMOVSloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVSloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8452,6 +8999,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVSloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8578,7 +9128,7 @@
 }
 func rewriteValueS390X_OpS390XFMOVSstoreidx_0(v *Value) bool {
 	// match: (FMOVSstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8593,6 +9143,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVSstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8603,7 +9156,7 @@
 		return true
 	}
 	// match: (FMOVSstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
@@ -8618,6 +9171,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XFMOVSstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8629,6 +9185,64 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XFNEG_0(v *Value) bool {
+	// match: (FNEG (LPDFR x))
+	// cond:
+	// result: (LNDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLPDFR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpS390XLNDFR)
+		v.AddArg(x)
+		return true
+	}
+	// match: (FNEG (LNDFR x))
+	// cond:
+	// result: (LPDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLNDFR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpS390XLPDFR)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XFNEGS_0(v *Value) bool {
+	// match: (FNEGS (LPDFR x))
+	// cond:
+	// result: (LNDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLPDFR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpS390XLNDFR)
+		v.AddArg(x)
+		return true
+	}
+	// match: (FNEGS (LNDFR x))
+	// cond:
+	// result: (LPDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLNDFR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpS390XLPDFR)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XFSUB_0(v *Value) bool {
 	// match: (FSUB (FMUL y z) x)
 	// cond:
@@ -8673,6 +9287,191 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XLDGR_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (LDGR <t> (SRDconst [1] (SLDconst [1] x)))
+	// cond:
+	// result: (LPDFR (LDGR <t> x))
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XSRDconst {
+			break
+		}
+		if v_0.AuxInt != 1 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XSLDconst {
+			break
+		}
+		if v_0_0.AuxInt != 1 {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpS390XLPDFR)
+		v0 := b.NewValue0(v.Pos, OpS390XLDGR, t)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LDGR <t> (OR (MOVDconst [-1<<63]) x))
+	// cond:
+	// result: (LNDFR (LDGR <t> x))
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XOR {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XMOVDconst {
+			break
+		}
+		if v_0_0.AuxInt != -1<<63 {
+			break
+		}
+		x := v_0.Args[1]
+		v.reset(OpS390XLNDFR)
+		v0 := b.NewValue0(v.Pos, OpS390XLDGR, t)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LDGR <t> (OR x (MOVDconst [-1<<63])))
+	// cond:
+	// result: (LNDFR (LDGR <t> x))
+	for {
+		t := v.Type
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XOR {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpS390XMOVDconst {
+			break
+		}
+		if v_0_1.AuxInt != -1<<63 {
+			break
+		}
+		v.reset(OpS390XLNDFR)
+		v0 := b.NewValue0(v.Pos, OpS390XLDGR, t)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LDGR <t> x:(ORload <t1> [off] {sym} (MOVDconst [-1<<63]) ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (LNDFR <t> (LDGR <t> (MOVDload <t1> [off] {sym} ptr mem)))
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XORload {
+			break
+		}
+		t1 := x.Type
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		x_0 := x.Args[0]
+		if x_0.Op != OpS390XMOVDconst {
+			break
+		}
+		if x_0.AuxInt != -1<<63 {
+			break
+		}
+		ptr := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XLNDFR, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v1 := b.NewValue0(v.Pos, OpS390XLDGR, t)
+		v2 := b.NewValue0(v.Pos, OpS390XMOVDload, t1)
+		v2.AuxInt = off
+		v2.Aux = sym
+		v2.AddArg(ptr)
+		v2.AddArg(mem)
+		v1.AddArg(v2)
+		v0.AddArg(v1)
+		return true
+	}
+	// match: (LDGR (LGDR x))
+	// cond:
+	// result: x
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLGDR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpCopy)
+		v.Type = x.Type
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XLEDBR_0(v *Value) bool {
+	// match: (LEDBR (LPDFR (LDEBR x)))
+	// cond:
+	// result: (LPDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLPDFR {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XLDEBR {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpS390XLPDFR)
+		v.AddArg(x)
+		return true
+	}
+	// match: (LEDBR (LNDFR (LDEBR x)))
+	// cond:
+	// result: (LNDFR x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLNDFR {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XLDEBR {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpS390XLNDFR)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XLGDR_0(v *Value) bool {
+	// match: (LGDR (LDGR x))
+	// cond:
+	// result: (MOVDreg x)
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLDGR {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpS390XMOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XLoweredRound32F_0(v *Value) bool {
 	// match: (LoweredRound32F x:(FMOVSconst))
 	// cond:
@@ -8706,24 +9505,28 @@
 	return false
 }
 func rewriteValueS390X_OpS390XMOVBZload_0(v *Value) bool {
-	// match: (MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
-	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+	// match: (MOVBZload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
 	// result: (MOVBZreg x)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
 		_ = v.Args[1]
-		ptr := v.Args[0]
+		ptr1 := v.Args[0]
 		v_1 := v.Args[1]
 		if v_1.Op != OpS390XMOVBstore {
 			break
 		}
-		off2 := v_1.AuxInt
-		sym2 := v_1.Aux
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
 		_ = v_1.Args[2]
 		ptr2 := v_1.Args[0]
 		x := v_1.Args[1]
-		if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+		if !(isSamePtr(ptr1, ptr2)) {
 			break
 		}
 		v.reset(OpS390XMOVBZreg)
@@ -8837,7 +9640,7 @@
 }
 func rewriteValueS390X_OpS390XMOVBZloadidx_0(v *Value) bool {
 	// match: (MOVBZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8851,6 +9654,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8860,7 +9666,7 @@
 		return true
 	}
 	// match: (MOVBZloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8874,6 +9680,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8883,7 +9692,7 @@
 		return true
 	}
 	// match: (MOVBZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8897,6 +9706,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -8906,7 +9718,7 @@
 		return true
 	}
 	// match: (MOVBZloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -8920,6 +9732,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -9224,6 +10039,32 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVBZreg x:(MOVBload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBZload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
@@ -9252,9 +10093,65 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVBZreg x:(MOVBloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVBload_0(v *Value) bool {
+	// match: (MOVBload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (MOVBreg x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVBstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XMOVBreg)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (MOVBload  [off1+off2] {sym} ptr mem)
@@ -9304,6 +10201,167 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVBload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
+	// cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
+	// result: (MOVBloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XMOVDaddridx {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBload [off] {sym} (ADD ptr idx) mem)
+	// cond: ptr.Op != OpSB
+	// result: (MOVBloadidx  [off] {sym} ptr idx mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(ptr.Op != OpSB) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XMOVBloadidx_0(v *Value) bool {
+	// match: (MOVBloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		ptr := v_0.Args[0]
+		idx := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		idx := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		idx := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVBloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		idx := v_0.Args[0]
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVBloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool {
@@ -9365,7 +10423,7 @@
 	}
 	// match: (MOVBreg x:(MOVBZload [off] {sym} ptr mem))
 	// cond: x.Uses == 1 && clobber(x)
-	// result: @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+	// result: @x.Block (MOVBload  <v.Type> [off] {sym} ptr mem)
 	for {
 		x := v.Args[0]
 		if x.Op != OpS390XMOVBZload {
@@ -9389,6 +10447,88 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVBreg x:(MOVBload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBload  <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBZloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (MOVBreg x:(MOVBloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVBstore_0(v *Value) bool {
@@ -9545,7 +10685,7 @@
 	}
 	// match: (MOVBstore [off] {sym} (ADD ptr idx) val mem)
 	// cond: ptr.Op != OpSB
-	// result: (MOVBstoreidx [off] {sym} ptr idx val mem)
+	// result: (MOVBstoreidx  [off] {sym} ptr idx val mem)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
@@ -10041,8 +11181,8 @@
 }
 func rewriteValueS390X_OpS390XMOVBstoreidx_0(v *Value) bool {
 	// match: (MOVBstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
-	// result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -10056,6 +11196,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10066,8 +11209,8 @@
 		return true
 	}
 	// match: (MOVBstoreidx [c] {sym} idx (ADDconst [d] ptr) val mem)
-	// cond:
-	// result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -10081,6 +11224,9 @@
 		ptr := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10091,8 +11237,8 @@
 		return true
 	}
 	// match: (MOVBstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
-	// result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -10106,6 +11252,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -10116,8 +11265,8 @@
 		return true
 	}
 	// match: (MOVBstoreidx [c] {sym} (ADDconst [d] idx) ptr val mem)
-	// cond:
-	// result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVBstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -10131,6 +11280,9 @@
 		ptr := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVBstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12329,30 +13481,62 @@
 	return false
 }
 func rewriteValueS390X_OpS390XMOVDload_0(v *Value) bool {
-	// match: (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _))
-	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+	// match: (MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
 	// result: (MOVDreg x)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
 		_ = v.Args[1]
-		ptr := v.Args[0]
+		ptr1 := v.Args[0]
 		v_1 := v.Args[1]
 		if v_1.Op != OpS390XMOVDstore {
 			break
 		}
-		off2 := v_1.AuxInt
-		sym2 := v_1.Aux
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
 		_ = v_1.Args[2]
 		ptr2 := v_1.Args[0]
 		x := v_1.Args[1]
-		if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+		if !(isSamePtr(ptr1, ptr2)) {
 			break
 		}
 		v.reset(OpS390XMOVDreg)
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (LGDR x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XLGDR)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (MOVDload  [off1+off2] {sym} ptr mem)
@@ -12433,7 +13617,7 @@
 	}
 	// match: (MOVDload [off] {sym} (ADD ptr idx) mem)
 	// cond: ptr.Op != OpSB
-	// result: (MOVDloadidx [off] {sym} ptr idx mem)
+	// result: (MOVDloadidx  [off] {sym} ptr idx mem)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
@@ -12461,8 +13645,8 @@
 }
 func rewriteValueS390X_OpS390XMOVDloadidx_0(v *Value) bool {
 	// match: (MOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
-	// result: (MOVDloadidx [c+d] {sym} ptr idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDloadidx  [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -12475,6 +13659,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12484,8 +13671,8 @@
 		return true
 	}
 	// match: (MOVDloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
-	// cond:
-	// result: (MOVDloadidx [c+d] {sym} ptr idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDloadidx  [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -12498,6 +13685,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12507,8 +13697,8 @@
 		return true
 	}
 	// match: (MOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
-	// result: (MOVDloadidx [c+d] {sym} ptr idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDloadidx  [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -12521,6 +13711,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12530,8 +13723,8 @@
 		return true
 	}
 	// match: (MOVDloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
-	// cond:
-	// result: (MOVDloadidx [c+d] {sym} ptr idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDloadidx  [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -12544,6 +13737,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -12807,6 +14003,35 @@
 func rewriteValueS390X_OpS390XMOVDnop_10(v *Value) bool {
 	b := v.Block
 	_ = b
+	// match: (MOVDnop <t> x:(MOVBloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDnop <t> x:(MOVHZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
@@ -12836,6 +14061,35 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVDnop <t> x:(MOVHloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDnop <t> x:(MOVWZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
@@ -12865,6 +14119,35 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVDnop <t> x:(MOVWloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDnop <t> x:(MOVDloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVDloadidx  <t> [off] {sym} ptr idx mem)
@@ -13161,6 +14444,35 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVDreg <t> x:(MOVBloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVBloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVBloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDreg <t> x:(MOVHZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
@@ -13190,6 +14502,35 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVDreg <t> x:(MOVHloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDreg <t> x:(MOVWZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
@@ -13219,6 +14560,35 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVDreg <t> x:(MOVWloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWloadidx  <t> [off] {sym} ptr idx mem)
+	for {
+		t := v.Type
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVDreg <t> x:(MOVDloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVDloadidx  <t> [off] {sym} ptr idx mem)
@@ -13361,7 +14731,7 @@
 	}
 	// match: (MOVDstore [off] {sym} (ADD ptr idx) val mem)
 	// cond: ptr.Op != OpSB
-	// result: (MOVDstoreidx [off] {sym} ptr idx val mem)
+	// result: (MOVDstoreidx  [off] {sym} ptr idx val mem)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
@@ -13560,8 +14930,8 @@
 }
 func rewriteValueS390X_OpS390XMOVDstoreidx_0(v *Value) bool {
 	// match: (MOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
-	// result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -13575,6 +14945,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -13585,8 +14958,8 @@
 		return true
 	}
 	// match: (MOVDstoreidx [c] {sym} idx (ADDconst [d] ptr) val mem)
-	// cond:
-	// result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -13600,6 +14973,9 @@
 		ptr := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -13610,8 +14986,8 @@
 		return true
 	}
 	// match: (MOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
-	// result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -13625,6 +15001,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -13635,8 +15014,8 @@
 		return true
 	}
 	// match: (MOVDstoreidx [c] {sym} (ADDconst [d] idx) ptr val mem)
-	// cond:
-	// result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVDstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -13650,6 +15029,9 @@
 		ptr := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVDstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -14701,24 +16083,28 @@
 	return false
 }
 func rewriteValueS390X_OpS390XMOVHZload_0(v *Value) bool {
-	// match: (MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
-	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+	// match: (MOVHZload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
 	// result: (MOVHZreg x)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
 		_ = v.Args[1]
-		ptr := v.Args[0]
+		ptr1 := v.Args[0]
 		v_1 := v.Args[1]
 		if v_1.Op != OpS390XMOVHstore {
 			break
 		}
-		off2 := v_1.AuxInt
-		sym2 := v_1.Aux
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
 		_ = v_1.Args[2]
 		ptr2 := v_1.Args[0]
 		x := v_1.Args[1]
-		if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+		if !(isSamePtr(ptr1, ptr2)) {
 			break
 		}
 		v.reset(OpS390XMOVHZreg)
@@ -14833,7 +16219,7 @@
 }
 func rewriteValueS390X_OpS390XMOVHZloadidx_0(v *Value) bool {
 	// match: (MOVHZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -14847,6 +16233,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -14856,7 +16245,7 @@
 		return true
 	}
 	// match: (MOVHZloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -14870,6 +16259,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -14879,7 +16271,7 @@
 		return true
 	}
 	// match: (MOVHZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -14893,6 +16285,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -14902,7 +16297,7 @@
 		return true
 	}
 	// match: (MOVHZloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -14916,6 +16311,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -15034,6 +16432,32 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVHZreg x:(MOVHload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHZload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
 	// match: (MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
@@ -15062,9 +16486,65 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVHZreg x:(MOVHloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVHload_0(v *Value) bool {
+	// match: (MOVHload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (MOVHreg x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVHstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XMOVHreg)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (MOVHload  [off1+off2] {sym} ptr mem)
@@ -15115,6 +16595,167 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVHload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
+	// cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
+	// result: (MOVHloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XMOVDaddridx {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHload [off] {sym} (ADD ptr idx) mem)
+	// cond: ptr.Op != OpSB
+	// result: (MOVHloadidx  [off] {sym} ptr idx mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(ptr.Op != OpSB) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XMOVHloadidx_0(v *Value) bool {
+	// match: (MOVHloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		ptr := v_0.Args[0]
+		idx := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		idx := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		idx := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVHloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		idx := v_0.Args[0]
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVHloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool {
@@ -15226,7 +16867,7 @@
 	}
 	// match: (MOVHreg x:(MOVHZload [off] {sym} ptr mem))
 	// cond: x.Uses == 1 && clobber(x)
-	// result: @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
+	// result: @x.Block (MOVHload  <v.Type> [off] {sym} ptr mem)
 	for {
 		x := v.Args[0]
 		if x.Op != OpS390XMOVHZload {
@@ -15250,6 +16891,93 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVHreg x:(MOVHload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHload  <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHZloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (MOVHreg x:(MOVHloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVHloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVHloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVHstore_0(v *Value) bool {
@@ -15407,7 +17135,7 @@
 	}
 	// match: (MOVHstore [off] {sym} (ADD ptr idx) val mem)
 	// cond: ptr.Op != OpSB
-	// result: (MOVHstoreidx [off] {sym} ptr idx val mem)
+	// result: (MOVHstoreidx  [off] {sym} ptr idx val mem)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
@@ -15720,8 +17448,8 @@
 }
 func rewriteValueS390X_OpS390XMOVHstoreidx_0(v *Value) bool {
 	// match: (MOVHstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
-	// result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -15735,6 +17463,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -15745,8 +17476,8 @@
 		return true
 	}
 	// match: (MOVHstoreidx [c] {sym} idx (ADDconst [d] ptr) val mem)
-	// cond:
-	// result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -15760,6 +17491,9 @@
 		ptr := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -15770,8 +17504,8 @@
 		return true
 	}
 	// match: (MOVHstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
-	// result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -15785,6 +17519,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -15795,8 +17532,8 @@
 		return true
 	}
 	// match: (MOVHstoreidx [c] {sym} (ADDconst [d] idx) ptr val mem)
-	// cond:
-	// result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVHstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -15810,6 +17547,9 @@
 		ptr := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVHstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -17186,24 +18926,28 @@
 	return false
 }
 func rewriteValueS390X_OpS390XMOVWZload_0(v *Value) bool {
-	// match: (MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _))
-	// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
+	// match: (MOVWZload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
 	// result: (MOVWZreg x)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
 		_ = v.Args[1]
-		ptr := v.Args[0]
+		ptr1 := v.Args[0]
 		v_1 := v.Args[1]
 		if v_1.Op != OpS390XMOVWstore {
 			break
 		}
-		off2 := v_1.AuxInt
-		sym2 := v_1.Aux
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
 		_ = v_1.Args[2]
 		ptr2 := v_1.Args[0]
 		x := v_1.Args[1]
-		if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
+		if !(isSamePtr(ptr1, ptr2)) {
 			break
 		}
 		v.reset(OpS390XMOVWZreg)
@@ -17318,7 +19062,7 @@
 }
 func rewriteValueS390X_OpS390XMOVWZloadidx_0(v *Value) bool {
 	// match: (MOVWZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -17332,6 +19076,9 @@
 		ptr := v_0.Args[0]
 		idx := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -17341,7 +19088,7 @@
 		return true
 	}
 	// match: (MOVWZloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -17355,6 +19102,9 @@
 		d := v_1.AuxInt
 		ptr := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -17364,7 +19114,7 @@
 		return true
 	}
 	// match: (MOVWZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -17378,6 +19128,9 @@
 		d := v_1.AuxInt
 		idx := v_1.Args[0]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -17387,7 +19140,7 @@
 		return true
 	}
 	// match: (MOVWZloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
-	// cond:
+	// cond: is20Bit(c+d)
 	// result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
 	for {
 		c := v.AuxInt
@@ -17401,6 +19154,9 @@
 		idx := v_0.Args[0]
 		ptr := v.Args[1]
 		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWZloadidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -17544,6 +19300,37 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVWZreg x:(MOVWload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWZload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XMOVWZreg_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem))
 	// cond: x.Uses == 1 && clobber(x)
 	// result: @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
@@ -17572,9 +19359,65 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVWZreg x:(MOVWloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVWload_0(v *Value) bool {
+	// match: (MOVWload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (MOVWreg x)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		ptr1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVWstore {
+			break
+		}
+		if v_1.AuxInt != off {
+			break
+		}
+		if v_1.Aux != sym {
+			break
+		}
+		_ = v_1.Args[2]
+		ptr2 := v_1.Args[0]
+		x := v_1.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XMOVWreg)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
 	// cond: is20Bit(off1+off2)
 	// result: (MOVWload  [off1+off2] {sym} ptr mem)
@@ -17625,6 +19468,167 @@
 		v.AddArg(mem)
 		return true
 	}
+	// match: (MOVWload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
+	// cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
+	// result: (MOVWloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
+	for {
+		off1 := v.AuxInt
+		sym1 := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XMOVDaddridx {
+			break
+		}
+		off2 := v_0.AuxInt
+		sym2 := v_0.Aux
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = off1 + off2
+		v.Aux = mergeSym(sym1, sym2)
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVWload [off] {sym} (ADD ptr idx) mem)
+	// cond: ptr.Op != OpSB
+	// result: (MOVWloadidx  [off] {sym} ptr idx mem)
+	for {
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADD {
+			break
+		}
+		_ = v_0.Args[1]
+		ptr := v_0.Args[0]
+		idx := v_0.Args[1]
+		mem := v.Args[1]
+		if !(ptr.Op != OpSB) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = off
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XMOVWloadidx_0(v *Value) bool {
+	// match: (MOVWloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		ptr := v_0.Args[0]
+		idx := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVWloadidx [c] {sym} idx (ADDconst [d] ptr) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		idx := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVWloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		ptr := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		d := v_1.AuxInt
+		idx := v_1.Args[0]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MOVWloadidx [c] {sym} (ADDconst [d] idx) ptr mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWloadidx  [c+d] {sym} ptr idx mem)
+	for {
+		c := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XADDconst {
+			break
+		}
+		d := v_0.AuxInt
+		idx := v_0.Args[0]
+		ptr := v.Args[1]
+		mem := v.Args[2]
+		if !(is20Bit(c + d)) {
+			break
+		}
+		v.reset(OpS390XMOVWloadidx)
+		v.AuxInt = c + d
+		v.Aux = sym
+		v.AddArg(ptr)
+		v.AddArg(idx)
+		v.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVWreg_0(v *Value) bool {
@@ -17789,7 +19793,7 @@
 	}
 	// match: (MOVWreg x:(MOVWZload [off] {sym} ptr mem))
 	// cond: x.Uses == 1 && clobber(x)
-	// result: @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+	// result: @x.Block (MOVWload  <v.Type> [off] {sym} ptr mem)
 	for {
 		x := v.Args[0]
 		if x.Op != OpS390XMOVWZload {
@@ -17813,6 +19817,88 @@
 		v0.AddArg(mem)
 		return true
 	}
+	// match: (MOVWreg x:(MOVWload [off] {sym} ptr mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWload  <v.Type> [off] {sym} ptr mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWload {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[1]
+		ptr := x.Args[0]
+		mem := x.Args[1]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWload, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWZloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
+	// match: (MOVWreg x:(MOVWloadidx [off] {sym} ptr idx mem))
+	// cond: x.Uses == 1 && clobber(x)
+	// result: @x.Block (MOVWloadidx  <v.Type> [off] {sym} ptr idx mem)
+	for {
+		x := v.Args[0]
+		if x.Op != OpS390XMOVWloadidx {
+			break
+		}
+		off := x.AuxInt
+		sym := x.Aux
+		_ = x.Args[2]
+		ptr := x.Args[0]
+		idx := x.Args[1]
+		mem := x.Args[2]
+		if !(x.Uses == 1 && clobber(x)) {
+			break
+		}
+		b = x.Block
+		v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type)
+		v.reset(OpCopy)
+		v.AddArg(v0)
+		v0.AuxInt = off
+		v0.Aux = sym
+		v0.AddArg(ptr)
+		v0.AddArg(idx)
+		v0.AddArg(mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVWstore_0(v *Value) bool {
@@ -17970,7 +20056,7 @@
 	}
 	// match: (MOVWstore [off] {sym} (ADD ptr idx) val mem)
 	// cond: ptr.Op != OpSB
-	// result: (MOVWstoreidx [off] {sym} ptr idx val mem)
+	// result: (MOVWstoreidx  [off] {sym} ptr idx val mem)
 	for {
 		off := v.AuxInt
 		sym := v.Aux
@@ -18305,8 +20391,8 @@
 }
 func rewriteValueS390X_OpS390XMOVWstoreidx_0(v *Value) bool {
 	// match: (MOVWstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
-	// cond:
-	// result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -18320,6 +20406,9 @@
 		idx := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -18330,8 +20419,8 @@
 		return true
 	}
 	// match: (MOVWstoreidx [c] {sym} idx (ADDconst [d] ptr) val mem)
-	// cond:
-	// result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -18345,6 +20434,9 @@
 		ptr := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -18355,8 +20447,8 @@
 		return true
 	}
 	// match: (MOVWstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
-	// cond:
-	// result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -18370,6 +20462,9 @@
 		idx := v_1.Args[0]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -18380,8 +20475,8 @@
 		return true
 	}
 	// match: (MOVWstoreidx [c] {sym} (ADDconst [d] idx) ptr val mem)
-	// cond:
-	// result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
+	// cond: is20Bit(c+d)
+	// result: (MOVWstoreidx  [c+d] {sym} ptr idx val mem)
 	for {
 		c := v.AuxInt
 		sym := v.Aux
@@ -18395,6 +20490,9 @@
 		ptr := v.Args[1]
 		val := v.Args[2]
 		mem := v.Args[3]
+		if !(is20Bit(c + d)) {
+			break
+		}
 		v.reset(OpS390XMOVWstoreidx)
 		v.AuxInt = c + d
 		v.Aux = sym
@@ -19085,10 +21183,101 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XMULLDload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (MULLDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (MULLD x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XMULLD)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (MULLDload [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XMULLDload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XMULLDload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XMULLW_0(v *Value) bool {
 	// match: (MULLW x (MOVDconst [c]))
 	// cond:
-	// result: (MULLWconst [c] x)
+	// result: (MULLWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -19098,13 +21287,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XMULLWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (MULLW (MOVDconst [c]) x)
 	// cond:
-	// result: (MULLWconst [c] x)
+	// result: (MULLWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -19114,7 +21303,7 @@
 		c := v_0.AuxInt
 		x := v.Args[1]
 		v.reset(OpS390XMULLWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
@@ -19447,6 +21636,62 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XMULLWload_0(v *Value) bool {
+	// match: (MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (MULLWload [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XMULLWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XMULLWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XNEG_0(v *Value) bool {
 	// match: (NEG (MOVDconst [c]))
 	// cond:
@@ -19540,6 +21785,8 @@
 	return false
 }
 func rewriteValueS390X_OpS390XOR_0(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (OR x (MOVDconst [c]))
 	// cond: isU32Bit(c)
 	// result: (ORconst [c] x)
@@ -19632,6 +21879,227 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (OR (MOVDconst [-1<<63]) (LGDR <t> x))
+	// cond:
+	// result: (LGDR <t> (LNDFR <x.Type> x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XMOVDconst {
+			break
+		}
+		if v_0.AuxInt != -1<<63 {
+			break
+		}
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XLGDR {
+			break
+		}
+		t := v_1.Type
+		x := v_1.Args[0]
+		v.reset(OpS390XLGDR)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpS390XLNDFR, x.Type)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (OR (LGDR <t> x) (MOVDconst [-1<<63]))
+	// cond:
+	// result: (LGDR <t> (LNDFR <x.Type> x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLGDR {
+			break
+		}
+		t := v_0.Type
+		x := v_0.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDconst {
+			break
+		}
+		if v_1.AuxInt != -1<<63 {
+			break
+		}
+		v.reset(OpS390XLGDR)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpS390XLNDFR, x.Type)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (OR (SLDconst [63] (SRDconst [63] (LGDR x))) (LGDR (LPDFR <t> y)))
+	// cond:
+	// result: (LGDR (CPSDR <t> y x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XSLDconst {
+			break
+		}
+		if v_0.AuxInt != 63 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XSRDconst {
+			break
+		}
+		if v_0_0.AuxInt != 63 {
+			break
+		}
+		v_0_0_0 := v_0_0.Args[0]
+		if v_0_0_0.Op != OpS390XLGDR {
+			break
+		}
+		x := v_0_0_0.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XLGDR {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpS390XLPDFR {
+			break
+		}
+		t := v_1_0.Type
+		y := v_1_0.Args[0]
+		v.reset(OpS390XLGDR)
+		v0 := b.NewValue0(v.Pos, OpS390XCPSDR, t)
+		v0.AddArg(y)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (OR (LGDR (LPDFR <t> y)) (SLDconst [63] (SRDconst [63] (LGDR x))))
+	// cond:
+	// result: (LGDR (CPSDR <t> y x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XLGDR {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XLPDFR {
+			break
+		}
+		t := v_0_0.Type
+		y := v_0_0.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XSLDconst {
+			break
+		}
+		if v_1.AuxInt != 63 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpS390XSRDconst {
+			break
+		}
+		if v_1_0.AuxInt != 63 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpS390XLGDR {
+			break
+		}
+		x := v_1_0_0.Args[0]
+		v.reset(OpS390XLGDR)
+		v0 := b.NewValue0(v.Pos, OpS390XCPSDR, t)
+		v0.AddArg(y)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (OR (SLDconst [63] (SRDconst [63] (LGDR x))) (MOVDconst [c]))
+	// cond: c & -1<<63 == 0
+	// result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [c]) x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XSLDconst {
+			break
+		}
+		if v_0.AuxInt != 63 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XSRDconst {
+			break
+		}
+		if v_0_0.AuxInt != 63 {
+			break
+		}
+		v_0_0_0 := v_0_0.Args[0]
+		if v_0_0_0.Op != OpS390XLGDR {
+			break
+		}
+		x := v_0_0_0.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDconst {
+			break
+		}
+		c := v_1.AuxInt
+		if !(c&-1<<63 == 0) {
+			break
+		}
+		v.reset(OpS390XLGDR)
+		v0 := b.NewValue0(v.Pos, OpS390XCPSDR, x.Type)
+		v1 := b.NewValue0(v.Pos, OpS390XFMOVDconst, x.Type)
+		v1.AuxInt = c
+		v0.AddArg(v1)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (OR (MOVDconst [c]) (SLDconst [63] (SRDconst [63] (LGDR x))))
+	// cond: c & -1<<63 == 0
+	// result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [c]) x))
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XMOVDconst {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XSLDconst {
+			break
+		}
+		if v_1.AuxInt != 63 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpS390XSRDconst {
+			break
+		}
+		if v_1_0.AuxInt != 63 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpS390XLGDR {
+			break
+		}
+		x := v_1_0_0.Args[0]
+		if !(c&-1<<63 == 0) {
+			break
+		}
+		v.reset(OpS390XLGDR)
+		v0 := b.NewValue0(v.Pos, OpS390XCPSDR, x.Type)
+		v1 := b.NewValue0(v.Pos, OpS390XFMOVDconst, x.Type)
+		v1.AuxInt = c
+		v0.AddArg(v1)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR (MOVDconst [c]) (MOVDconst [d]))
 	// cond:
 	// result: (MOVDconst [c|d])
@@ -19768,13 +22236,6 @@
 		v.AddArg(mem)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_10(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR <t> x g:(MOVDload [off] {sym} ptr mem))
 	// cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoad(v, g, x) && clobber(g)
 	// result: (ORload <t> [off] {sym} x ptr mem)
@@ -19950,6 +22411,13 @@
 		v0.AddArg(mem)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_20(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)) x1:(MOVHZload [i1] {s} p mem))
 	// cond: i1 == i0+2   && p.Op != OpSB   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
@@ -20289,13 +22757,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_20(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))) s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem)))
 	// cond: i1 == i0+1   && j1 == j0-8   && j1 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
@@ -20552,6 +23013,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_30(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR y s1:(SLDconst [j1] x1:(MOVHZload [i1] {s} p mem))) s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem)))
 	// cond: i1 == i0+2   && j1 == j0-16   && j1 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
@@ -20886,13 +23354,6 @@
 		v0.AddArg(mem)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_30(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR sh:(SLDconst [8] x0:(MOVBZloadidx [i0] {s} idx p mem)) x1:(MOVBZloadidx [i1] {s} p idx mem))
 	// cond: i1 == i0+1   && p.Op != OpSB   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVHZloadidx [i0] {s} p idx mem)
@@ -21109,6 +23570,13 @@
 		v0.AddArg(mem)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_40(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR x1:(MOVHZloadidx [i1] {s} idx p mem) sh:(SLDconst [16] x0:(MOVHZloadidx [i0] {s} p idx mem)))
 	// cond: i1 == i0+2   && p.Op != OpSB   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
@@ -21433,13 +23901,6 @@
 		v0.AddArg(mem)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_40(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR sh:(SLDconst [16] x0:(MOVHZloadidx [i0] {s} idx p mem)) x1:(MOVHZloadidx [i1] {s} idx p mem))
 	// cond: i1 == i0+2   && p.Op != OpSB   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
@@ -21656,6 +24117,13 @@
 		v0.AddArg(mem)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_50(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR x1:(MOVWZloadidx [i1] {s} idx p mem) sh:(SLDconst [32] x0:(MOVWZloadidx [i0] {s} idx p mem)))
 	// cond: i1 == i0+4   && p.Op != OpSB   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVDloadidx [i0] {s} p idx mem)
@@ -21995,13 +24463,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_50(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} idx p mem)) or:(OR s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)) y))
 	// cond: i1 == i0+1   && j1 == j0-8   && j1 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
@@ -22278,6 +24739,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_60(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} idx p mem)) or:(OR y s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))))
 	// cond: i1 == i0+1   && j1 == j0-8   && j1 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
@@ -22692,13 +25160,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_60(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} idx p mem))) s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)))
 	// cond: i1 == i0+1   && j1 == j0-8   && j1 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
@@ -22975,6 +25436,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_70(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR y s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} idx p mem))) s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} idx p mem)))
 	// cond: i1 == i0+1   && j1 == j0-8   && j1 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
@@ -23389,13 +25857,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_70(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} idx p mem)) or:(OR y s1:(SLDconst [j1] x1:(MOVHZloadidx [i1] {s} p idx mem))))
 	// cond: i1 == i0+2   && j1 == j0-16   && j1 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
@@ -23672,6 +26133,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_80(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR s1:(SLDconst [j1] x1:(MOVHZloadidx [i1] {s} idx p mem)) y) s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} p idx mem)))
 	// cond: i1 == i0+2   && j1 == j0-16   && j1 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
@@ -24086,13 +26554,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_80(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s1:(SLDconst [j1] x1:(MOVHZloadidx [i1] {s} idx p mem))) s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} idx p mem)))
 	// cond: i1 == i0+2   && j1 == j0-16   && j1 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
@@ -24323,6 +26784,13 @@
 		v0.AddArg(v1)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_90(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))) r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)))
 	// cond: i1 == i0+2   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
@@ -24694,13 +27162,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_90(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))) s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem)))
 	// cond: p.Op != OpSB   && i1 == i0+1   && j1 == j0+8   && j0 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
@@ -24989,6 +27450,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_100(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR y s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)))) s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
 	// cond: i1 == i0+2   && j1 == j0+16   && j0 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
@@ -25343,13 +27811,6 @@
 		v0.AddArg(v1)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_100(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR sh:(SLDconst [8] x1:(MOVBZloadidx [i1] {s} idx p mem)) x0:(MOVBZloadidx [i0] {s} p idx mem))
 	// cond: p.Op != OpSB   && i1 == i0+1   && x0.Uses == 1   && x1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))
@@ -25582,6 +28043,13 @@
 		v0.AddArg(v1)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_110(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} idx p mem)) sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
 	// cond: i1 == i0+2   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))
@@ -25966,13 +28434,6 @@
 		v0.AddArg(v1)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_110(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} idx p mem))) r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} idx p mem)))
 	// cond: i1 == i0+2   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))
@@ -26223,6 +28684,13 @@
 		v0.AddArg(mem)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_120(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR r0:(MOVWZreg x0:(MOVWBRloadidx [i0] {s} idx p mem)) sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRloadidx [i1] {s} idx p mem))))
 	// cond: i1 == i0+4   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && sh.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(sh)
 	// result: @mergePoint(b,x0,x1) (MOVDBRloadidx [i0] {s} p idx mem)
@@ -26604,13 +29072,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_120(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} idx p mem)) or:(OR s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)) y))
 	// cond: p.Op != OpSB   && i1 == i0+1   && j1 == j0+8   && j0 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
@@ -26895,6 +29356,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_130(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} idx p mem)) or:(OR y s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))))
 	// cond: p.Op != OpSB   && i1 == i0+1   && j1 == j0+8   && j0 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
@@ -27321,13 +29789,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_130(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} idx p mem))) s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)))
 	// cond: p.Op != OpSB   && i1 == i0+1   && j1 == j0+8   && j0 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
@@ -27612,6 +30073,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_140(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR y s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} idx p mem))) s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} idx p mem)))
 	// cond: p.Op != OpSB   && i1 == i0+1   && j1 == j0+8   && j0 % 16 == 0   && x0.Uses == 1   && x1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
@@ -28078,13 +30546,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_140(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} idx p mem))) or:(OR y s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem)))))
 	// cond: i1 == i0+2   && j1 == j0+16   && j0 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
@@ -28401,6 +30862,13 @@
 		v0.AddArg(y)
 		return true
 	}
+	return false
+}
+func rewriteValueS390X_OpS390XOR_150(v *Value) bool {
+	b := v.Block
+	_ = b
+	typ := &b.Func.Config.Types
+	_ = typ
 	// match: (OR or:(OR s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} idx p mem))) y) s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
 	// cond: i1 == i0+2   && j1 == j0+16   && j0 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
@@ -28875,13 +31343,6 @@
 		v0.AddArg(y)
 		return true
 	}
-	return false
-}
-func rewriteValueS390X_OpS390XOR_150(v *Value) bool {
-	b := v.Block
-	_ = b
-	typ := &b.Func.Config.Types
-	_ = typ
 	// match: (OR or:(OR y s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} idx p mem)))) s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} idx p mem))))
 	// cond: i1 == i0+2   && j1 == j0+16   && j0 % 32 == 0   && x0.Uses == 1   && x1.Uses == 1   && r0.Uses == 1   && r1.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && or.Uses == 1   && mergePoint(b,x0,x1) != nil   && clobber(x0)   && clobber(x1)   && clobber(r0)   && clobber(r1)   && clobber(s0)   && clobber(s1)   && clobber(or)
 	// result: @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
@@ -28966,7 +31427,7 @@
 func rewriteValueS390X_OpS390XORW_0(v *Value) bool {
 	// match: (ORW x (MOVDconst [c]))
 	// cond:
-	// result: (ORWconst [c] x)
+	// result: (ORWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -28976,13 +31437,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XORWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (ORW (MOVDconst [c]) x)
 	// cond:
-	// result: (ORWconst [c] x)
+	// result: (ORWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -28992,7 +31453,7 @@
 		c := v_0.AuxInt
 		x := v.Args[1]
 		v.reset(OpS390XORWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
@@ -34376,6 +36837,62 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XORWload_0(v *Value) bool {
+	// match: (ORWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ORWload   [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XORWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ORWload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XORWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XORconst_0(v *Value) bool {
 	// match: (ORconst [0] x)
 	// cond:
@@ -34417,6 +36934,97 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XORload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (ORload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (OR    x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XOR)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ORload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (ORload    [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XORload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (ORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (ORload    [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XORload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XSLD_0(v *Value) bool {
 	// match: (SLD x (MOVDconst [c]))
 	// cond:
@@ -34589,7 +37197,7 @@
 func rewriteValueS390X_OpS390XSRAWconst_0(v *Value) bool {
 	// match: (SRAWconst [c] (MOVDconst [d]))
 	// cond:
-	// result: (MOVDconst [d>>uint64(c)])
+	// result: (MOVDconst [int64(int32(d))>>uint64(c)])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -34598,7 +37206,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpS390XMOVDconst)
-		v.AuxInt = d >> uint64(c)
+		v.AuxInt = int64(int32(d)) >> uint64(c)
 		return true
 	}
 	return false
@@ -34641,6 +37249,38 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XSRDconst_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SRDconst [1] (SLDconst [1] (LGDR <t> x)))
+	// cond:
+	// result: (LGDR <t> (LPDFR <x.Type> x))
+	for {
+		if v.AuxInt != 1 {
+			break
+		}
+		v_0 := v.Args[0]
+		if v_0.Op != OpS390XSLDconst {
+			break
+		}
+		if v_0.AuxInt != 1 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpS390XLGDR {
+			break
+		}
+		t := v_0_0.Type
+		x := v_0_0.Args[0]
+		v.reset(OpS390XLGDR)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpS390XLPDFR, x.Type)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XSRW_0(v *Value) bool {
 	// match: (SRW x (MOVDconst [c]))
 	// cond:
@@ -34964,7 +37604,7 @@
 	_ = b
 	// match: (SUBW x (MOVDconst [c]))
 	// cond:
-	// result: (SUBWconst x [c])
+	// result: (SUBWconst x [int64(int32(c))])
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -34974,13 +37614,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XSUBWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (SUBW (MOVDconst [c]) x)
 	// cond:
-	// result: (NEGW (SUBWconst <v.Type> x [c]))
+	// result: (NEGW (SUBWconst <v.Type> x [int64(int32(c))]))
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -34991,7 +37631,7 @@
 		x := v.Args[1]
 		v.reset(OpS390XNEGW)
 		v0 := b.NewValue0(v.Pos, OpS390XSUBWconst, v.Type)
-		v0.AuxInt = c
+		v0.AuxInt = int64(int32(c))
 		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
@@ -35094,6 +37734,62 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpS390XSUBWload_0(v *Value) bool {
+	// match: (SUBWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (SUBWload  [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XSUBWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SUBWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (SUBWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XSUBWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XSUBconst_0(v *Value) bool {
 	// match: (SUBconst [0] x)
 	// cond:
@@ -35157,6 +37853,97 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XSUBload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (SUBload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (SUB   x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XSUB)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SUBload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (SUBload   [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XSUBload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (SUBload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (SUBload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XSUBload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XXOR_0(v *Value) bool {
 	// match: (XOR x (MOVDconst [c]))
 	// cond: isU32Bit(c)
@@ -35421,7 +38208,7 @@
 func rewriteValueS390X_OpS390XXORW_0(v *Value) bool {
 	// match: (XORW x (MOVDconst [c]))
 	// cond:
-	// result: (XORWconst [c] x)
+	// result: (XORWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		x := v.Args[0]
@@ -35431,13 +38218,13 @@
 		}
 		c := v_1.AuxInt
 		v.reset(OpS390XXORWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (XORW (MOVDconst [c]) x)
 	// cond:
-	// result: (XORWconst [c] x)
+	// result: (XORWconst [int64(int32(c))] x)
 	for {
 		_ = v.Args[1]
 		v_0 := v.Args[0]
@@ -35447,7 +38234,7 @@
 		c := v_0.AuxInt
 		x := v.Args[1]
 		v.reset(OpS390XXORWconst)
-		v.AuxInt = c
+		v.AuxInt = int64(int32(c))
 		v.AddArg(x)
 		return true
 	}
@@ -35778,6 +38565,62 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XXORWload_0(v *Value) bool {
+	// match: (XORWload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (XORWload  [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XXORWload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (XORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (XORWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XXORWload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpS390XXORconst_0(v *Value) bool {
 	// match: (XORconst [0] x)
 	// cond:
@@ -35808,6 +38651,97 @@
 	}
 	return false
 }
+func rewriteValueS390X_OpS390XXORload_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	// match: (XORload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _))
+	// cond: isSamePtr(ptr1, ptr2)
+	// result: (XOR   x (LGDR <t> y))
+	for {
+		t := v.Type
+		off := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		ptr1 := v.Args[1]
+		v_2 := v.Args[2]
+		if v_2.Op != OpS390XFMOVDstore {
+			break
+		}
+		if v_2.AuxInt != off {
+			break
+		}
+		if v_2.Aux != sym {
+			break
+		}
+		_ = v_2.Args[2]
+		ptr2 := v_2.Args[0]
+		y := v_2.Args[1]
+		if !(isSamePtr(ptr1, ptr2)) {
+			break
+		}
+		v.reset(OpS390XXOR)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpS390XLGDR, t)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (XORload [off1] {sym} x (ADDconst [off2] ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(off1+off2)
+	// result: (XORload   [off1+off2] {sym} x ptr mem)
+	for {
+		off1 := v.AuxInt
+		sym := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XADDconst {
+			break
+		}
+		off2 := v_1.AuxInt
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+			break
+		}
+		v.reset(OpS390XXORload)
+		v.AuxInt = off1 + off2
+		v.Aux = sym
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (XORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
+	// cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
+	// result: (XORload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+	for {
+		o1 := v.AuxInt
+		s1 := v.Aux
+		_ = v.Args[2]
+		x := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpS390XMOVDaddr {
+			break
+		}
+		o2 := v_1.AuxInt
+		s2 := v_1.Aux
+		ptr := v_1.Args[0]
+		mem := v.Args[2]
+		if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+			break
+		}
+		v.reset(OpS390XXORload)
+		v.AuxInt = o1 + o2
+		v.Aux = mergeSym(s1, s2)
+		v.AddArg(x)
+		v.AddArg(ptr)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueS390X_OpSelect0_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -36200,6 +39134,18 @@
 		return true
 	}
 }
+func rewriteValueS390X_OpTrunc_0(v *Value) bool {
+	// match: (Trunc x)
+	// cond:
+	// result: (FIDBR [5] x)
+	for {
+		x := v.Args[0]
+		v.reset(OpS390XFIDBR)
+		v.AuxInt = 5
+		v.AddArg(x)
+		return true
+	}
+}
 func rewriteValueS390X_OpTrunc16to8_0(v *Value) bool {
 	// match: (Trunc16to8 x)
 	// cond:
@@ -36620,6 +39566,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagEQ) yes no)
@@ -36632,6 +39579,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (EQ (FlagLT) yes no)
@@ -36644,6 +39592,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -36657,6 +39606,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -36672,6 +39622,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XLE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagEQ) yes no)
@@ -36684,6 +39635,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (GE (FlagLT) yes no)
@@ -36696,6 +39648,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -36709,6 +39662,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockS390XGT:
@@ -36723,6 +39677,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XLT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (GT (FlagEQ) yes no)
@@ -36735,6 +39690,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -36748,6 +39704,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -36761,6 +39718,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	case BlockIf:
@@ -36790,6 +39748,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XLT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDLE (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36818,6 +39777,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XLE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDGT (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36846,6 +39806,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDGE (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36874,6 +39835,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDEQ (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36902,6 +39864,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDNE (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36930,6 +39893,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDGTnoinv (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36958,6 +39922,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XGTF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (MOVDGEnoinv (MOVDconst [0]) (MOVDconst [1]) cmp) yes no)
@@ -36986,6 +39951,7 @@
 			cmp := v.Args[2]
 			b.Kind = BlockS390XGEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (If cond yes no)
@@ -37002,6 +39968,7 @@
 			v1.AddArg(cond)
 			v0.AddArg(v1)
 			b.SetControl(v0)
+			b.Aux = nil
 			return true
 		}
 	case BlockS390XLE:
@@ -37016,6 +39983,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagEQ) yes no)
@@ -37028,6 +39996,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagLT) yes no)
@@ -37040,6 +40009,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LE (FlagGT) yes no)
@@ -37052,6 +40022,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -37067,6 +40038,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagEQ) yes no)
@@ -37079,6 +40051,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -37092,6 +40065,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (LT (FlagGT) yes no)
@@ -37104,6 +40078,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -37141,6 +40116,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XLT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDLE (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37176,6 +40152,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XLE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDGT (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37211,6 +40188,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XGT
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDGE (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37246,6 +40224,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XGE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDEQ (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37281,6 +40260,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XEQ
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDNE (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37316,6 +40296,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDGTnoinv (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37351,6 +40332,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XGTF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (CMPWconst [0] (MOVDGEnoinv (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no)
@@ -37386,6 +40368,7 @@
 			cmp := v_0.Args[2]
 			b.Kind = BlockS390XGEF
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (InvertFlags cmp) yes no)
@@ -37399,6 +40382,7 @@
 			cmp := v.Args[0]
 			b.Kind = BlockS390XNE
 			b.SetControl(cmp)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagEQ) yes no)
@@ -37411,6 +40395,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -37424,6 +40409,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (NE (FlagGT) yes no)
@@ -37436,6 +40422,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 	}
diff --git a/src/cmd/compile/internal/ssa/rewrite_test.go b/src/cmd/compile/internal/ssa/rewrite_test.go
index c21c64b..8a097b0 100644
--- a/src/cmd/compile/internal/ssa/rewrite_test.go
+++ b/src/cmd/compile/internal/ssa/rewrite_test.go
@@ -103,3 +103,25 @@
 		}
 	}
 }
+
+// We generate memmove for copy(x[1:], x[:]), however we may change it to OpMove,
+// because size is known. Check that OpMove is alias-safe, or we did call memmove.
+func TestMove(t *testing.T) {
+	x := [...]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}
+	copy(x[1:], x[:])
+	for i := 1; i < len(x); i++ {
+		if int(x[i]) != i {
+			t.Errorf("Memmove got converted to OpMove in alias-unsafe way. Got %d insted of %d in position %d", int(x[i]), i, i+1)
+		}
+	}
+}
+
+func TestMoveSmall(t *testing.T) {
+	x := [...]byte{1, 2, 3, 4, 5, 6, 7}
+	copy(x[1:], x[:])
+	for i := 1; i < len(x); i++ {
+		if int(x[i]) != i {
+			t.Errorf("Memmove got converted to OpMove in alias-unsafe way. Got %d instead of %d in position %d", int(x[i]), i, i+1)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index c67e4f9..def2cca 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -16,17 +16,17 @@
 func rewriteValuegeneric(v *Value) bool {
 	switch v.Op {
 	case OpAdd16:
-		return rewriteValuegeneric_OpAdd16_0(v) || rewriteValuegeneric_OpAdd16_10(v) || rewriteValuegeneric_OpAdd16_20(v)
+		return rewriteValuegeneric_OpAdd16_0(v) || rewriteValuegeneric_OpAdd16_10(v) || rewriteValuegeneric_OpAdd16_20(v) || rewriteValuegeneric_OpAdd16_30(v)
 	case OpAdd32:
-		return rewriteValuegeneric_OpAdd32_0(v) || rewriteValuegeneric_OpAdd32_10(v) || rewriteValuegeneric_OpAdd32_20(v)
+		return rewriteValuegeneric_OpAdd32_0(v) || rewriteValuegeneric_OpAdd32_10(v) || rewriteValuegeneric_OpAdd32_20(v) || rewriteValuegeneric_OpAdd32_30(v)
 	case OpAdd32F:
 		return rewriteValuegeneric_OpAdd32F_0(v)
 	case OpAdd64:
-		return rewriteValuegeneric_OpAdd64_0(v) || rewriteValuegeneric_OpAdd64_10(v) || rewriteValuegeneric_OpAdd64_20(v)
+		return rewriteValuegeneric_OpAdd64_0(v) || rewriteValuegeneric_OpAdd64_10(v) || rewriteValuegeneric_OpAdd64_20(v) || rewriteValuegeneric_OpAdd64_30(v)
 	case OpAdd64F:
 		return rewriteValuegeneric_OpAdd64F_0(v)
 	case OpAdd8:
-		return rewriteValuegeneric_OpAdd8_0(v) || rewriteValuegeneric_OpAdd8_10(v) || rewriteValuegeneric_OpAdd8_20(v)
+		return rewriteValuegeneric_OpAdd8_0(v) || rewriteValuegeneric_OpAdd8_10(v) || rewriteValuegeneric_OpAdd8_20(v) || rewriteValuegeneric_OpAdd8_30(v)
 	case OpAddPtr:
 		return rewriteValuegeneric_OpAddPtr_0(v)
 	case OpAnd16:
@@ -57,10 +57,26 @@
 		return rewriteValuegeneric_OpConstString_0(v)
 	case OpConvert:
 		return rewriteValuegeneric_OpConvert_0(v)
+	case OpCvt32Fto32:
+		return rewriteValuegeneric_OpCvt32Fto32_0(v)
+	case OpCvt32Fto64:
+		return rewriteValuegeneric_OpCvt32Fto64_0(v)
 	case OpCvt32Fto64F:
 		return rewriteValuegeneric_OpCvt32Fto64F_0(v)
+	case OpCvt32to32F:
+		return rewriteValuegeneric_OpCvt32to32F_0(v)
+	case OpCvt32to64F:
+		return rewriteValuegeneric_OpCvt32to64F_0(v)
+	case OpCvt64Fto32:
+		return rewriteValuegeneric_OpCvt64Fto32_0(v)
 	case OpCvt64Fto32F:
 		return rewriteValuegeneric_OpCvt64Fto32F_0(v)
+	case OpCvt64Fto64:
+		return rewriteValuegeneric_OpCvt64Fto64_0(v)
+	case OpCvt64to32F:
+		return rewriteValuegeneric_OpCvt64to32F_0(v)
+	case OpCvt64to64F:
+		return rewriteValuegeneric_OpCvt64to64F_0(v)
 	case OpDiv16:
 		return rewriteValuegeneric_OpDiv16_0(v)
 	case OpDiv16u:
@@ -85,8 +101,12 @@
 		return rewriteValuegeneric_OpEq16_0(v)
 	case OpEq32:
 		return rewriteValuegeneric_OpEq32_0(v)
+	case OpEq32F:
+		return rewriteValuegeneric_OpEq32F_0(v)
 	case OpEq64:
 		return rewriteValuegeneric_OpEq64_0(v)
+	case OpEq64F:
+		return rewriteValuegeneric_OpEq64F_0(v)
 	case OpEq8:
 		return rewriteValuegeneric_OpEq8_0(v)
 	case OpEqB:
@@ -103,10 +123,14 @@
 		return rewriteValuegeneric_OpGeq16U_0(v)
 	case OpGeq32:
 		return rewriteValuegeneric_OpGeq32_0(v)
+	case OpGeq32F:
+		return rewriteValuegeneric_OpGeq32F_0(v)
 	case OpGeq32U:
 		return rewriteValuegeneric_OpGeq32U_0(v)
 	case OpGeq64:
 		return rewriteValuegeneric_OpGeq64_0(v)
+	case OpGeq64F:
+		return rewriteValuegeneric_OpGeq64F_0(v)
 	case OpGeq64U:
 		return rewriteValuegeneric_OpGeq64U_0(v)
 	case OpGeq8:
@@ -119,10 +143,14 @@
 		return rewriteValuegeneric_OpGreater16U_0(v)
 	case OpGreater32:
 		return rewriteValuegeneric_OpGreater32_0(v)
+	case OpGreater32F:
+		return rewriteValuegeneric_OpGreater32F_0(v)
 	case OpGreater32U:
 		return rewriteValuegeneric_OpGreater32U_0(v)
 	case OpGreater64:
 		return rewriteValuegeneric_OpGreater64_0(v)
+	case OpGreater64F:
+		return rewriteValuegeneric_OpGreater64F_0(v)
 	case OpGreater64U:
 		return rewriteValuegeneric_OpGreater64U_0(v)
 	case OpGreater8:
@@ -134,7 +162,7 @@
 	case OpInterCall:
 		return rewriteValuegeneric_OpInterCall_0(v)
 	case OpIsInBounds:
-		return rewriteValuegeneric_OpIsInBounds_0(v) || rewriteValuegeneric_OpIsInBounds_10(v) || rewriteValuegeneric_OpIsInBounds_20(v)
+		return rewriteValuegeneric_OpIsInBounds_0(v) || rewriteValuegeneric_OpIsInBounds_10(v) || rewriteValuegeneric_OpIsInBounds_20(v) || rewriteValuegeneric_OpIsInBounds_30(v)
 	case OpIsNonNil:
 		return rewriteValuegeneric_OpIsNonNil_0(v)
 	case OpIsSliceInBounds:
@@ -145,10 +173,14 @@
 		return rewriteValuegeneric_OpLeq16U_0(v)
 	case OpLeq32:
 		return rewriteValuegeneric_OpLeq32_0(v)
+	case OpLeq32F:
+		return rewriteValuegeneric_OpLeq32F_0(v)
 	case OpLeq32U:
 		return rewriteValuegeneric_OpLeq32U_0(v)
 	case OpLeq64:
 		return rewriteValuegeneric_OpLeq64_0(v)
+	case OpLeq64F:
+		return rewriteValuegeneric_OpLeq64F_0(v)
 	case OpLeq64U:
 		return rewriteValuegeneric_OpLeq64U_0(v)
 	case OpLeq8:
@@ -161,10 +193,14 @@
 		return rewriteValuegeneric_OpLess16U_0(v)
 	case OpLess32:
 		return rewriteValuegeneric_OpLess32_0(v)
+	case OpLess32F:
+		return rewriteValuegeneric_OpLess32F_0(v)
 	case OpLess32U:
 		return rewriteValuegeneric_OpLess32U_0(v)
 	case OpLess64:
 		return rewriteValuegeneric_OpLess64_0(v)
+	case OpLess64F:
+		return rewriteValuegeneric_OpLess64F_0(v)
 	case OpLess64U:
 		return rewriteValuegeneric_OpLess64U_0(v)
 	case OpLess8:
@@ -172,7 +208,7 @@
 	case OpLess8U:
 		return rewriteValuegeneric_OpLess8U_0(v)
 	case OpLoad:
-		return rewriteValuegeneric_OpLoad_0(v)
+		return rewriteValuegeneric_OpLoad_0(v) || rewriteValuegeneric_OpLoad_10(v)
 	case OpLsh16x16:
 		return rewriteValuegeneric_OpLsh16x16_0(v)
 	case OpLsh16x32:
@@ -249,8 +285,12 @@
 		return rewriteValuegeneric_OpNeq16_0(v)
 	case OpNeq32:
 		return rewriteValuegeneric_OpNeq32_0(v)
+	case OpNeq32F:
+		return rewriteValuegeneric_OpNeq32F_0(v)
 	case OpNeq64:
 		return rewriteValuegeneric_OpNeq64_0(v)
+	case OpNeq64F:
+		return rewriteValuegeneric_OpNeq64F_0(v)
 	case OpNeq8:
 		return rewriteValuegeneric_OpNeq8_0(v)
 	case OpNeqB:
@@ -369,6 +409,8 @@
 		return rewriteValuegeneric_OpSlicemask_0(v)
 	case OpSqrt:
 		return rewriteValuegeneric_OpSqrt_0(v)
+	case OpStaticCall:
+		return rewriteValuegeneric_OpStaticCall_0(v)
 	case OpStore:
 		return rewriteValuegeneric_OpStore_0(v) || rewriteValuegeneric_OpStore_10(v)
 	case OpStringLen:
@@ -467,6 +509,251 @@
 		v.AuxInt = int64(int16(c + d))
 		return true
 	}
+	// match: (Add16 <t> (Mul16 x y) (Mul16 x z))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 y x) (Mul16 x z))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 x y) (Mul16 z x))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 y x) (Mul16 z x))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 x z) (Mul16 x y))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 z x) (Mul16 x y))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 x z) (Mul16 y x))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add16 <t> (Mul16 z x) (Mul16 y x))
+	// cond:
+	// result: (Mul16 x (Add16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpAdd16_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add16 (Const16 [0]) x)
 	// cond:
 	// result: x
@@ -657,11 +944,6 @@
 		v.AddArg(v0)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd16_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add16 (Sub16 i:(Const16 <t>) z) x)
 	// cond: (z.Op != OpConst16 && x.Op != OpConst16)
 	// result: (Add16 i (Sub16 <t> x z))
@@ -718,6 +1000,11 @@
 		v.AddArg(v0)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd16_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add16 x (Sub16 i:(Const16 <t>) z))
 	// cond: (z.Op != OpConst16 && x.Op != OpConst16)
 	// result: (Add16 i (Sub16 <t> x z))
@@ -950,11 +1237,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd16_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add16 (Add16 (Const16 <t> [d]) x) (Const16 <t> [c]))
 	// cond:
 	// result: (Add16 (Const16 <t> [int64(int16(c+d))]) x)
@@ -1019,6 +1301,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd16_30(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x))
 	// cond:
 	// result: (Sub16 (Const16 <t> [int64(int16(c+d))]) x)
@@ -1190,6 +1477,251 @@
 		v.AuxInt = int64(int32(c + d))
 		return true
 	}
+	// match: (Add32 <t> (Mul32 x y) (Mul32 x z))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 y x) (Mul32 x z))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 x y) (Mul32 z x))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 y x) (Mul32 z x))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 x z) (Mul32 x y))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 z x) (Mul32 x y))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 x z) (Mul32 y x))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add32 <t> (Mul32 z x) (Mul32 y x))
+	// cond:
+	// result: (Mul32 x (Add32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpAdd32_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add32 (Const32 [0]) x)
 	// cond:
 	// result: x
@@ -1380,11 +1912,6 @@
 		v.AddArg(v0)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd32_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add32 (Sub32 i:(Const32 <t>) z) x)
 	// cond: (z.Op != OpConst32 && x.Op != OpConst32)
 	// result: (Add32 i (Sub32 <t> x z))
@@ -1441,6 +1968,11 @@
 		v.AddArg(v0)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd32_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add32 x (Sub32 i:(Const32 <t>) z))
 	// cond: (z.Op != OpConst32 && x.Op != OpConst32)
 	// result: (Add32 i (Sub32 <t> x z))
@@ -1673,11 +2205,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd32_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add32 (Add32 (Const32 <t> [d]) x) (Const32 <t> [c]))
 	// cond:
 	// result: (Add32 (Const32 <t> [int64(int32(c+d))]) x)
@@ -1742,6 +2269,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd32_30(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x))
 	// cond:
 	// result: (Sub32 (Const32 <t> [int64(int32(c+d))]) x)
@@ -1990,6 +2522,251 @@
 		v.AuxInt = c + d
 		return true
 	}
+	// match: (Add64 <t> (Mul64 x y) (Mul64 x z))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 y x) (Mul64 x z))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 x y) (Mul64 z x))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 y x) (Mul64 z x))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 x z) (Mul64 x y))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 z x) (Mul64 x y))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 x z) (Mul64 y x))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add64 <t> (Mul64 z x) (Mul64 y x))
+	// cond:
+	// result: (Mul64 x (Add64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpAdd64_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add64 (Const64 [0]) x)
 	// cond:
 	// result: x
@@ -2180,11 +2957,6 @@
 		v.AddArg(v0)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd64_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add64 (Sub64 i:(Const64 <t>) z) x)
 	// cond: (z.Op != OpConst64 && x.Op != OpConst64)
 	// result: (Add64 i (Sub64 <t> x z))
@@ -2241,6 +3013,11 @@
 		v.AddArg(v0)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd64_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add64 x (Sub64 i:(Const64 <t>) z))
 	// cond: (z.Op != OpConst64 && x.Op != OpConst64)
 	// result: (Add64 i (Sub64 <t> x z))
@@ -2473,11 +3250,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd64_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add64 (Add64 (Const64 <t> [d]) x) (Const64 <t> [c]))
 	// cond:
 	// result: (Add64 (Const64 <t> [c+d]) x)
@@ -2542,6 +3314,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd64_30(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x))
 	// cond:
 	// result: (Sub64 (Const64 <t> [c+d]) x)
@@ -2790,6 +3567,251 @@
 		v.AuxInt = int64(int8(c + d))
 		return true
 	}
+	// match: (Add8 <t> (Mul8 x y) (Mul8 x z))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 y x) (Mul8 x z))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 x y) (Mul8 z x))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 y x) (Mul8 z x))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 x z) (Mul8 x y))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 z x) (Mul8 x y))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		y := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 x z) (Mul8 y x))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Add8 <t> (Mul8 z x) (Mul8 y x))
+	// cond:
+	// result: (Mul8  x (Add8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		z := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		y := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpAdd8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpAdd8_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add8 (Const8 [0]) x)
 	// cond:
 	// result: x
@@ -2980,11 +4002,6 @@
 		v.AddArg(v0)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd8_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add8 (Sub8 i:(Const8 <t>) z) x)
 	// cond: (z.Op != OpConst8  && x.Op != OpConst8)
 	// result: (Add8  i (Sub8  <t> x z))
@@ -3041,6 +4058,11 @@
 		v.AddArg(v0)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd8_20(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add8 x (Sub8 i:(Const8 <t>) z))
 	// cond: (z.Op != OpConst8  && x.Op != OpConst8)
 	// result: (Add8  i (Sub8  <t> x z))
@@ -3273,11 +4295,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpAdd8_20(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Add8 (Add8 (Const8 <t> [d]) x) (Const8 <t> [c]))
 	// cond:
 	// result: (Add8  (Const8  <t> [int64(int8(c+d))]) x)
@@ -3342,6 +4359,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpAdd8_30(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Add8 (Const8 <t> [c]) (Sub8 (Const8 <t> [d]) x))
 	// cond:
 	// result: (Sub8  (Const8  <t> [int64(int8(c+d))]) x)
@@ -5684,25 +6706,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (ArraySelect [0] (Load ptr mem))
-	// cond:
-	// result: (Load ptr mem)
-	for {
-		if v.AuxInt != 0 {
-			break
-		}
-		v_0 := v.Args[0]
-		if v_0.Op != OpLoad {
-			break
-		}
-		_ = v_0.Args[1]
-		ptr := v_0.Args[0]
-		mem := v_0.Args[1]
-		v.reset(OpLoad)
-		v.AddArg(ptr)
-		v.AddArg(mem)
-		return true
-	}
 	// match: (ArraySelect [0] x:(IData _))
 	// cond:
 	// result: x
@@ -6059,6 +7062,38 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpCvt32Fto32_0(v *Value) bool {
+	// match: (Cvt32Fto32 (Const32F [c]))
+	// cond:
+	// result: (Const32  [int64(int32(i2f(c)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst32)
+		v.AuxInt = int64(int32(i2f(c)))
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpCvt32Fto64_0(v *Value) bool {
+	// match: (Cvt32Fto64 (Const32F [c]))
+	// cond:
+	// result: (Const64  [int64(i2f(c))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst64)
+		v.AuxInt = int64(i2f(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpCvt32Fto64F_0(v *Value) bool {
 	// match: (Cvt32Fto64F (Const32F [c]))
 	// cond:
@@ -6075,6 +7110,54 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpCvt32to32F_0(v *Value) bool {
+	// match: (Cvt32to32F (Const32 [c]))
+	// cond:
+	// result: (Const32F [f2i(float64(float32(int32(c))))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32 {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst32F)
+		v.AuxInt = f2i(float64(float32(int32(c))))
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpCvt32to64F_0(v *Value) bool {
+	// match: (Cvt32to64F (Const32 [c]))
+	// cond:
+	// result: (Const64F [f2i(float64(int32(c)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32 {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst64F)
+		v.AuxInt = f2i(float64(int32(c)))
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpCvt64Fto32_0(v *Value) bool {
+	// match: (Cvt64Fto32 (Const64F [c]))
+	// cond:
+	// result: (Const32  [int64(int32(i2f(c)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst32)
+		v.AuxInt = int64(int32(i2f(c)))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpCvt64Fto32F_0(v *Value) bool {
 	// match: (Cvt64Fto32F (Const64F [c]))
 	// cond:
@@ -6091,6 +7174,54 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpCvt64Fto64_0(v *Value) bool {
+	// match: (Cvt64Fto64 (Const64F [c]))
+	// cond:
+	// result: (Const64  [int64(i2f(c))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst64)
+		v.AuxInt = int64(i2f(c))
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpCvt64to32F_0(v *Value) bool {
+	// match: (Cvt64to32F (Const64 [c]))
+	// cond:
+	// result: (Const32F [f2i(float64(float32(c)))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64 {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst32F)
+		v.AuxInt = f2i(float64(float32(c)))
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpCvt64to64F_0(v *Value) bool {
+	// match: (Cvt64to64F (Const64 [c]))
+	// cond:
+	// result: (Const64F [f2i(float64(c))])
+	for {
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64 {
+			break
+		}
+		c := v_0.AuxInt
+		v.reset(OpConst64F)
+		v.AuxInt = f2i(float64(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpDiv16_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -6118,6 +7249,27 @@
 		v.AuxInt = int64(int16(c) / int16(d))
 		return true
 	}
+	// match: (Div16 n (Const16 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xffff)
+	// result: (Rsh16Ux64 n (Const64 <typ.UInt64> [log2(c&0xffff)]))
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst16 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xffff)) {
+			break
+		}
+		v.reset(OpRsh16Ux64)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v0.AuxInt = log2(c & 0xffff)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Div16 <t> n (Const16 [c]))
 	// cond: c < 0 && c != -1<<15
 	// result: (Neg16 (Div16 <t> n (Const16 <t> [-c])))
@@ -6461,6 +7613,27 @@
 		v.AuxInt = int64(int32(c) / int32(d))
 		return true
 	}
+	// match: (Div32 n (Const32 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xffffffff)
+	// result: (Rsh32Ux64 n (Const64 <typ.UInt64> [log2(c&0xffffffff)]))
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xffffffff)) {
+			break
+		}
+		v.reset(OpRsh32Ux64)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v0.AuxInt = log2(c & 0xffffffff)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Div32 <t> n (Const32 [c]))
 	// cond: c < 0 && c != -1<<31
 	// result: (Neg32 (Div32 <t> n (Const32 <t> [-c])))
@@ -6982,6 +8155,47 @@
 		v.AuxInt = c / d
 		return true
 	}
+	// match: (Div64 n (Const64 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c)
+	// result: (Rsh64Ux64 n (Const64 <typ.UInt64> [log2(c)]))
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c)) {
+			break
+		}
+		v.reset(OpRsh64Ux64)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v0.AuxInt = log2(c)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Div64 n (Const64 [-1<<63]))
+	// cond: isNonNegative(n)
+	// result: (Const64 [0])
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		if v_1.AuxInt != -1<<63 {
+			break
+		}
+		if !(isNonNegative(n)) {
+			break
+		}
+		v.reset(OpConst64)
+		v.AuxInt = 0
+		return true
+	}
 	// match: (Div64 <t> n (Const64 [c]))
 	// cond: c < 0 && c != -1<<63
 	// result: (Neg64 (Div64 <t> n (Const64 <t> [-c])))
@@ -7378,6 +8592,27 @@
 		v.AuxInt = int64(int8(c) / int8(d))
 		return true
 	}
+	// match: (Div8 n (Const8 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xff)
+	// result: (Rsh8Ux64 n  (Const64 <typ.UInt64> [log2(c&0xff)]))
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst8 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xff)) {
+			break
+		}
+		v.reset(OpRsh8Ux64)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+		v0.AuxInt = log2(c & 0xff)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Div8 <t> n (Const8 [c]))
 	// cond: c < 0 && c != -1<<7
 	// result: (Neg8  (Div8  <t> n (Const8  <t> [-c])))
@@ -7953,6 +9188,47 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpEq32F_0(v *Value) bool {
+	// match: (Eq32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) == i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) == i2f(d))
+		return true
+	}
+	// match: (Eq32F (Const32F [d]) (Const32F [c]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) == i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		d := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) == i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpEq64_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -8137,6 +9413,47 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpEq64F_0(v *Value) bool {
+	// match: (Eq64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) == i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) == i2f(d))
+		return true
+	}
+	// match: (Eq64F (Const64F [d]) (Const64F [c]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) == i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		d := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) == i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpEq8_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -8640,6 +9957,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpGeq32F_0(v *Value) bool {
+	// match: (Geq32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) >= i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) >= i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpGeq32U_0(v *Value) bool {
 	// match: (Geq32U (Const32 [c]) (Const32 [d]))
 	// cond:
@@ -8684,6 +10023,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpGeq64F_0(v *Value) bool {
+	// match: (Geq64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) >= i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) >= i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpGeq64U_0(v *Value) bool {
 	// match: (Geq64U (Const64 [c]) (Const64 [d]))
 	// cond:
@@ -8816,6 +10177,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpGreater32F_0(v *Value) bool {
+	// match: (Greater32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) > i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) > i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpGreater32U_0(v *Value) bool {
 	// match: (Greater32U (Const32 [c]) (Const32 [d]))
 	// cond:
@@ -8860,6 +10243,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpGreater64F_0(v *Value) bool {
+	// match: (Greater64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) > i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) > i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpGreater64U_0(v *Value) bool {
 	// match: (Greater64U (Const64 [c]) (Const64 [d]))
 	// cond:
@@ -9774,6 +11179,303 @@
 		v.AuxInt = 1
 		return true
 	}
+	// match: (IsInBounds (ZeroExt8to64 (Rsh8Ux64 _ (Const64 [c]))) (Const64 [d]))
+	// cond: 0 < c && c <  8 && 1<<uint( 8-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt8to64 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh8Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	return false
+}
+func rewriteValuegeneric_OpIsInBounds_30(v *Value) bool {
+	// match: (IsInBounds (ZeroExt8to32 (Rsh8Ux64 _ (Const64 [c]))) (Const32 [d]))
+	// cond: 0 < c && c <  8 && 1<<uint( 8-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt8to32 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh8Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (ZeroExt8to16 (Rsh8Ux64 _ (Const64 [c]))) (Const16 [d]))
+	// cond: 0 < c && c <  8 && 1<<uint( 8-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt8to16 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh8Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst16 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (Rsh8Ux64 _ (Const64 [c])) (Const64 [d]))
+	// cond: 0 < c && c <  8 && 1<<uint( 8-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpRsh8Ux64 {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d]))
+	// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt16to64 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh16Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d]))
+	// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt16to32 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh16Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (Rsh16Ux64 _ (Const64 [c])) (Const64 [d]))
+	// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpRsh16Ux64 {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d]))
+	// cond: 0 < c && c < 32 && 1<<uint(32-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpZeroExt32to64 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpRsh32Ux64 {
+			break
+		}
+		_ = v_0_0.Args[1]
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 32 && 1<<uint(32-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (Rsh32Ux64 _ (Const64 [c])) (Const64 [d]))
+	// cond: 0 < c && c < 32 && 1<<uint(32-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpRsh32Ux64 {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 32 && 1<<uint(32-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
+	// match: (IsInBounds (Rsh64Ux64 _ (Const64 [c])) (Const64 [d]))
+	// cond: 0 < c && c < 64 && 1<<uint(64-c)-1 < d
+	// result: (ConstBool [1])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpRsh64Ux64 {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpConst64 {
+			break
+		}
+		c := v_0_1.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		d := v_1.AuxInt
+		if !(0 < c && c < 64 && 1<<uint(64-c)-1 < d) {
+			break
+		}
+		v.reset(OpConstBool)
+		v.AuxInt = 1
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpIsNonNil_0(v *Value) bool {
@@ -10072,6 +11774,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpLeq32F_0(v *Value) bool {
+	// match: (Leq32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) <= i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) <= i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpLeq32U_0(v *Value) bool {
 	// match: (Leq32U (Const32 [c]) (Const32 [d]))
 	// cond:
@@ -10116,6 +11840,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpLeq64F_0(v *Value) bool {
+	// match: (Leq64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) <= i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) <= i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpLeq64U_0(v *Value) bool {
 	// match: (Leq64U (Const64 [c]) (Const64 [d]))
 	// cond:
@@ -10248,6 +11994,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpLess32F_0(v *Value) bool {
+	// match: (Less32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) < i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) < i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpLess32U_0(v *Value) bool {
 	// match: (Less32U (Const32 [c]) (Const32 [d]))
 	// cond:
@@ -10292,6 +12060,28 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpLess64F_0(v *Value) bool {
+	// match: (Less64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) < i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) < i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpLess64U_0(v *Value) bool {
 	// match: (Less64U (Const64 [c]) (Const64 [d]))
 	// cond:
@@ -10386,6 +12176,110 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Load <t1> p1 (Store {t2} p2 (Const64 [x]) _))
+	// cond: isSamePtr(p1,p2) && t2.(*types.Type).Size() == 8 && is64BitFloat(t1)
+	// result: (Const64F [x])
+	for {
+		t1 := v.Type
+		_ = v.Args[1]
+		p1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpStore {
+			break
+		}
+		t2 := v_1.Aux
+		_ = v_1.Args[2]
+		p2 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpConst64 {
+			break
+		}
+		x := v_1_1.AuxInt
+		if !(isSamePtr(p1, p2) && t2.(*types.Type).Size() == 8 && is64BitFloat(t1)) {
+			break
+		}
+		v.reset(OpConst64F)
+		v.AuxInt = x
+		return true
+	}
+	// match: (Load <t1> p1 (Store {t2} p2 (Const32 [x]) _))
+	// cond: isSamePtr(p1,p2) && t2.(*types.Type).Size() == 4 && is32BitFloat(t1)
+	// result: (Const32F [f2i(float64(math.Float32frombits(uint32(x))))])
+	for {
+		t1 := v.Type
+		_ = v.Args[1]
+		p1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpStore {
+			break
+		}
+		t2 := v_1.Aux
+		_ = v_1.Args[2]
+		p2 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpConst32 {
+			break
+		}
+		x := v_1_1.AuxInt
+		if !(isSamePtr(p1, p2) && t2.(*types.Type).Size() == 4 && is32BitFloat(t1)) {
+			break
+		}
+		v.reset(OpConst32F)
+		v.AuxInt = f2i(float64(math.Float32frombits(uint32(x))))
+		return true
+	}
+	// match: (Load <t1> p1 (Store {t2} p2 (Const64F [x]) _))
+	// cond: isSamePtr(p1,p2) && t2.(*types.Type).Size() == 8 && is64BitInt(t1)
+	// result: (Const64  [x])
+	for {
+		t1 := v.Type
+		_ = v.Args[1]
+		p1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpStore {
+			break
+		}
+		t2 := v_1.Aux
+		_ = v_1.Args[2]
+		p2 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpConst64F {
+			break
+		}
+		x := v_1_1.AuxInt
+		if !(isSamePtr(p1, p2) && t2.(*types.Type).Size() == 8 && is64BitInt(t1)) {
+			break
+		}
+		v.reset(OpConst64)
+		v.AuxInt = x
+		return true
+	}
+	// match: (Load <t1> p1 (Store {t2} p2 (Const32F [x]) _))
+	// cond: isSamePtr(p1,p2) && t2.(*types.Type).Size() == 4 && is32BitInt(t1)
+	// result: (Const32  [int64(int32(math.Float32bits(float32(i2f(x)))))])
+	for {
+		t1 := v.Type
+		_ = v.Args[1]
+		p1 := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpStore {
+			break
+		}
+		t2 := v_1.Aux
+		_ = v_1.Args[2]
+		p2 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		if v_1_1.Op != OpConst32F {
+			break
+		}
+		x := v_1_1.AuxInt
+		if !(isSamePtr(p1, p2) && t2.(*types.Type).Size() == 4 && is32BitInt(t1)) {
+			break
+		}
+		v.reset(OpConst32)
+		v.AuxInt = int64(int32(math.Float32bits(float32(i2f(x)))))
+		return true
+	}
 	// match: (Load <t> _ _)
 	// cond: t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t)
 	// result: (StructMake0)
@@ -10524,6 +12418,13 @@
 		v.AddArg(v6)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpLoad_10(v *Value) bool {
+	b := v.Block
+	_ = b
+	fe := b.Func.fe
+	_ = fe
 	// match: (Load <t> _ _)
 	// cond: t.IsArray() && t.NumElem() == 0
 	// result: (ArrayMake0)
@@ -11662,6 +13563,28 @@
 		return true
 	}
 	// match: (Mod16 <t> n (Const16 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xffff)
+	// result: (And16 n (Const16 <t> [(c&0xffff)-1]))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst16 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xffff)) {
+			break
+		}
+		v.reset(OpAnd16)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst16, t)
+		v0.AuxInt = (c & 0xffff) - 1
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Mod16 <t> n (Const16 [c]))
 	// cond: c < 0 && c != -1<<15
 	// result: (Mod16 <t> n (Const16 <t> [-c]))
 	for {
@@ -11821,6 +13744,28 @@
 		return true
 	}
 	// match: (Mod32 <t> n (Const32 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xffffffff)
+	// result: (And32 n (Const32 <t> [(c&0xffffffff)-1]))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xffffffff)) {
+			break
+		}
+		v.reset(OpAnd32)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst32, t)
+		v0.AuxInt = (c & 0xffffffff) - 1
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Mod32 <t> n (Const32 [c]))
 	// cond: c < 0 && c != -1<<31
 	// result: (Mod32 <t> n (Const32 <t> [-c]))
 	for {
@@ -11980,6 +13925,49 @@
 		return true
 	}
 	// match: (Mod64 <t> n (Const64 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c)
+	// result: (And64 n (Const64 <t> [c-1]))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c)) {
+			break
+		}
+		v.reset(OpAnd64)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst64, t)
+		v0.AuxInt = c - 1
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Mod64 n (Const64 [-1<<63]))
+	// cond: isNonNegative(n)
+	// result: n
+	for {
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64 {
+			break
+		}
+		if v_1.AuxInt != -1<<63 {
+			break
+		}
+		if !(isNonNegative(n)) {
+			break
+		}
+		v.reset(OpCopy)
+		v.Type = n.Type
+		v.AddArg(n)
+		return true
+	}
+	// match: (Mod64 <t> n (Const64 [c]))
 	// cond: c < 0 && c != -1<<63
 	// result: (Mod64 <t> n (Const64 <t> [-c]))
 	for {
@@ -12160,6 +14148,28 @@
 		return true
 	}
 	// match: (Mod8 <t> n (Const8 [c]))
+	// cond: isNonNegative(n) && isPowerOfTwo(c&0xff)
+	// result: (And8 n (Const8 <t> [(c&0xff)-1]))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		n := v.Args[0]
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst8 {
+			break
+		}
+		c := v_1.AuxInt
+		if !(isNonNegative(n) && isPowerOfTwo(c&0xff)) {
+			break
+		}
+		v.reset(OpAnd8)
+		v.AddArg(n)
+		v0 := b.NewValue0(v.Pos, OpConst8, t)
+		v0.AuxInt = (c & 0xff) - 1
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Mod8 <t> n (Const8 [c]))
 	// cond: c < 0 && c != -1<<7
 	// result: (Mod8  <t> n (Const8  <t> [-c]))
 	for {
@@ -14937,6 +16947,47 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpNeq32F_0(v *Value) bool {
+	// match: (Neq32F (Const32F [c]) (Const32F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) != i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) != i2f(d))
+		return true
+	}
+	// match: (Neq32F (Const32F [d]) (Const32F [c]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) != i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst32F {
+			break
+		}
+		d := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst32F {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) != i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpNeq64_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -15121,6 +17172,47 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpNeq64F_0(v *Value) bool {
+	// match: (Neq64F (Const64F [c]) (Const64F [d]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) != i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		d := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) != i2f(d))
+		return true
+	}
+	// match: (Neq64F (Const64F [d]) (Const64F [c]))
+	// cond:
+	// result: (ConstBool [b2i(i2f(c) != i2f(d))])
+	for {
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpConst64F {
+			break
+		}
+		d := v_0.AuxInt
+		v_1 := v.Args[1]
+		if v_1.Op != OpConst64F {
+			break
+		}
+		c := v_1.AuxInt
+		v.reset(OpConstBool)
+		v.AuxInt = b2i(i2f(c) != i2f(d))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpNeq8_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -15556,8 +17648,8 @@
 		v.AddArg(mem)
 		return true
 	}
-	// match: (NilCheck (Load (OffPtr [c] (SP)) mem) mem)
-	// cond: mem.Op == OpStaticCall 	&& isSameSym(mem.Aux, "runtime.newobject") 	&& c == config.ctxt.FixedFrameSize() + config.RegSize 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
+	// match: (NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _)
+	// cond: isSameSym(sym, "runtime.newobject") 	&& c == config.ctxt.FixedFrameSize() + config.RegSize 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
 	// result: (Invalid)
 	for {
 		_ = v.Args[1]
@@ -15575,18 +17667,19 @@
 		if v_0_0_0.Op != OpSP {
 			break
 		}
-		mem := v_0.Args[1]
-		if mem != v.Args[1] {
+		v_0_1 := v_0.Args[1]
+		if v_0_1.Op != OpStaticCall {
 			break
 		}
-		if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")) {
+		sym := v_0_1.Aux
+		if !(isSameSym(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")) {
 			break
 		}
 		v.reset(OpInvalid)
 		return true
 	}
-	// match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem)) mem)
-	// cond: mem.Op == OpStaticCall 	&& isSameSym(mem.Aux, "runtime.newobject") 	&& c == config.ctxt.FixedFrameSize() + config.RegSize 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
+	// match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _)
+	// cond: isSameSym(sym, "runtime.newobject") 	&& c == config.ctxt.FixedFrameSize() + config.RegSize 	&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
 	// result: (Invalid)
 	for {
 		_ = v.Args[1]
@@ -15608,11 +17701,12 @@
 		if v_0_0_0_0.Op != OpSP {
 			break
 		}
-		mem := v_0_0.Args[1]
-		if mem != v.Args[1] {
+		v_0_0_1 := v_0_0.Args[1]
+		if v_0_0_1.Op != OpStaticCall {
 			break
 		}
-		if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")) {
+		sym := v_0_0_1.Aux
+		if !(isSameSym(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")) {
 			break
 		}
 		v.reset(OpInvalid)
@@ -21640,6 +23734,93 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
+	b := v.Block
+	_ = b
+	config := b.Func.Config
+	_ = config
+	// match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
+	// cond: isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz,config)
+	// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
+	for {
+		sym := v.Aux
+		s1 := v.Args[0]
+		if s1.Op != OpStore {
+			break
+		}
+		_ = s1.Args[2]
+		s1_1 := s1.Args[1]
+		if s1_1.Op != OpConst64 {
+			break
+		}
+		sz := s1_1.AuxInt
+		s2 := s1.Args[2]
+		if s2.Op != OpStore {
+			break
+		}
+		_ = s2.Args[2]
+		src := s2.Args[1]
+		s3 := s2.Args[2]
+		if s3.Op != OpStore {
+			break
+		}
+		t := s3.Aux
+		_ = s3.Args[2]
+		dst := s3.Args[1]
+		mem := s3.Args[2]
+		if !(isSameSym(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz, config)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = sz
+		v.Aux = t.(*types.Type).Elem()
+		v.AddArg(dst)
+		v.AddArg(src)
+		v.AddArg(mem)
+		return true
+	}
+	// match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
+	// cond: isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz,config)
+	// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
+	for {
+		sym := v.Aux
+		s1 := v.Args[0]
+		if s1.Op != OpStore {
+			break
+		}
+		_ = s1.Args[2]
+		s1_1 := s1.Args[1]
+		if s1_1.Op != OpConst32 {
+			break
+		}
+		sz := s1_1.AuxInt
+		s2 := s1.Args[2]
+		if s2.Op != OpStore {
+			break
+		}
+		_ = s2.Args[2]
+		src := s2.Args[1]
+		s3 := s2.Args[2]
+		if s3.Op != OpStore {
+			break
+		}
+		t := s3.Aux
+		_ = s3.Args[2]
+		dst := s3.Args[1]
+		mem := s3.Args[2]
+		if !(isSameSym(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmoveSize(sz, config)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = sz
+		v.Aux = t.(*types.Type).Elem()
+		v.AddArg(dst)
+		v.AddArg(src)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpStore_0(v *Value) bool {
 	b := v.Block
 	_ = b
@@ -22517,6 +24698,126 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Sub16 <t> (Mul16 x y) (Mul16 x z))
+	// cond:
+	// result: (Mul16 x (Sub16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub16 <t> (Mul16 y x) (Mul16 x z))
+	// cond:
+	// result: (Mul16 x (Sub16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub16 <t> (Mul16 x y) (Mul16 z x))
+	// cond:
+	// result: (Mul16 x (Sub16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub16 <t> (Mul16 y x) (Mul16 z x))
+	// cond:
+	// result: (Mul16 x (Sub16 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul16 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul16 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul16)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub16, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Sub16 x x)
 	// cond:
 	// result: (Const16 [0])
@@ -22590,6 +24891,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpSub16_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Sub16 (Add16 y x) y)
 	// cond:
 	// result: x
@@ -22698,11 +25004,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpSub16_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Sub16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x))
 	// cond:
 	// result: (Add16 (Const16 <t> [int64(int16(c-d))]) x)
@@ -22781,6 +25082,126 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Sub32 <t> (Mul32 x y) (Mul32 x z))
+	// cond:
+	// result: (Mul32 x (Sub32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub32 <t> (Mul32 y x) (Mul32 x z))
+	// cond:
+	// result: (Mul32 x (Sub32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub32 <t> (Mul32 x y) (Mul32 z x))
+	// cond:
+	// result: (Mul32 x (Sub32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub32 <t> (Mul32 y x) (Mul32 z x))
+	// cond:
+	// result: (Mul32 x (Sub32 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul32 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul32 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul32)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub32, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Sub32 x x)
 	// cond:
 	// result: (Const32 [0])
@@ -22854,6 +25275,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpSub32_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Sub32 (Add32 y x) y)
 	// cond:
 	// result: x
@@ -22962,11 +25388,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpSub32_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Sub32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x))
 	// cond:
 	// result: (Add32 (Const32 <t> [int64(int32(c-d))]) x)
@@ -23085,6 +25506,126 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Sub64 <t> (Mul64 x y) (Mul64 x z))
+	// cond:
+	// result: (Mul64 x (Sub64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub64 <t> (Mul64 y x) (Mul64 x z))
+	// cond:
+	// result: (Mul64 x (Sub64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub64 <t> (Mul64 x y) (Mul64 z x))
+	// cond:
+	// result: (Mul64 x (Sub64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub64 <t> (Mul64 y x) (Mul64 z x))
+	// cond:
+	// result: (Mul64 x (Sub64 <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul64 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul64 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul64)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub64, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Sub64 x x)
 	// cond:
 	// result: (Const64 [0])
@@ -23158,6 +25699,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpSub64_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Sub64 (Add64 y x) y)
 	// cond:
 	// result: x
@@ -23266,11 +25812,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpSub64_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Sub64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x))
 	// cond:
 	// result: (Add64 (Const64 <t> [c-d]) x)
@@ -23389,6 +25930,126 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (Sub8 <t> (Mul8 x y) (Mul8 x z))
+	// cond:
+	// result: (Mul8  x (Sub8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub8 <t> (Mul8 y x) (Mul8 x z))
+	// cond:
+	// result: (Mul8  x (Sub8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		if x != v_1.Args[0] {
+			break
+		}
+		z := v_1.Args[1]
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub8 <t> (Mul8 x y) (Mul8 z x))
+	// cond:
+	// result: (Mul8  x (Sub8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Sub8 <t> (Mul8 y x) (Mul8 z x))
+	// cond:
+	// result: (Mul8  x (Sub8  <t> y z))
+	for {
+		t := v.Type
+		_ = v.Args[1]
+		v_0 := v.Args[0]
+		if v_0.Op != OpMul8 {
+			break
+		}
+		_ = v_0.Args[1]
+		y := v_0.Args[0]
+		x := v_0.Args[1]
+		v_1 := v.Args[1]
+		if v_1.Op != OpMul8 {
+			break
+		}
+		_ = v_1.Args[1]
+		z := v_1.Args[0]
+		if x != v_1.Args[1] {
+			break
+		}
+		v.reset(OpMul8)
+		v.AddArg(x)
+		v0 := b.NewValue0(v.Pos, OpSub8, t)
+		v0.AddArg(y)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Sub8 x x)
 	// cond:
 	// result: (Const8  [0])
@@ -23462,6 +26123,11 @@
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValuegeneric_OpSub8_10(v *Value) bool {
+	b := v.Block
+	_ = b
 	// match: (Sub8 (Add8 y x) y)
 	// cond:
 	// result: x
@@ -23570,11 +26236,6 @@
 		v.AddArg(x)
 		return true
 	}
-	return false
-}
-func rewriteValuegeneric_OpSub8_10(v *Value) bool {
-	b := v.Block
-	_ = b
 	// match: (Sub8 (Const8 <t> [c]) (Sub8 (Const8 <t> [d]) x))
 	// cond:
 	// result: (Add8  (Const8  <t> [int64(int8(c-d))]) x)
@@ -26219,6 +28880,7 @@
 			cond := v.Args[0]
 			b.Kind = BlockIf
 			b.SetControl(cond)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
@@ -26236,6 +28898,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			return true
 		}
 		// match: (If (ConstBool [c]) yes no)
@@ -26252,6 +28915,7 @@
 			}
 			b.Kind = BlockFirst
 			b.SetControl(nil)
+			b.Aux = nil
 			b.swapSuccessors()
 			return true
 		}
diff --git a/src/cmd/compile/internal/ssa/sizeof_test.go b/src/cmd/compile/internal/ssa/sizeof_test.go
index 9fab7b6..f8bbed9 100644
--- a/src/cmd/compile/internal/ssa/sizeof_test.go
+++ b/src/cmd/compile/internal/ssa/sizeof_test.go
@@ -24,6 +24,7 @@
 	}{
 		{Value{}, 68, 112},
 		{Block{}, 152, 288},
+		{LocalSlot{}, 32, 48},
 		{valState{}, 28, 40},
 	}
 
diff --git a/src/cmd/compile/internal/ssa/softfloat.go b/src/cmd/compile/internal/ssa/softfloat.go
new file mode 100644
index 0000000..39829b0
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/softfloat.go
@@ -0,0 +1,66 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+import "math"
+
+func softfloat(f *Func) {
+	if !f.Config.SoftFloat {
+		return
+	}
+	newInt64 := false
+
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			if v.Type.IsFloat() {
+				switch v.Op {
+				case OpPhi, OpLoad, OpArg:
+					if v.Type.Size() == 4 {
+						v.Type = f.Config.Types.UInt32
+					} else {
+						v.Type = f.Config.Types.UInt64
+					}
+				case OpConst32F:
+					v.Op = OpConst32
+					v.Type = f.Config.Types.UInt32
+					v.AuxInt = int64(int32(math.Float32bits(i2f32(v.AuxInt))))
+				case OpConst64F:
+					v.Op = OpConst64
+					v.Type = f.Config.Types.UInt64
+				case OpNeg32F:
+					arg0 := v.Args[0]
+					v.reset(OpXor32)
+					v.Type = f.Config.Types.UInt32
+					v.AddArg(arg0)
+					mask := v.Block.NewValue0(v.Pos, OpConst32, v.Type)
+					mask.AuxInt = -0x80000000
+					v.AddArg(mask)
+				case OpNeg64F:
+					arg0 := v.Args[0]
+					v.reset(OpXor64)
+					v.Type = f.Config.Types.UInt64
+					v.AddArg(arg0)
+					mask := v.Block.NewValue0(v.Pos, OpConst64, v.Type)
+					mask.AuxInt = -0x8000000000000000
+					v.AddArg(mask)
+				case OpRound32F:
+					v.Op = OpCopy
+					v.Type = f.Config.Types.UInt32
+				case OpRound64F:
+					v.Op = OpCopy
+					v.Type = f.Config.Types.UInt64
+				}
+				newInt64 = newInt64 || v.Type.Size() == 8
+			}
+		}
+	}
+
+	if newInt64 && f.Config.RegSize == 4 {
+		// On 32bit arch, decompose Uint64 introduced in the switch above.
+		decomposeBuiltIn(f)
+		applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
+	}
+
+}
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go
index 3b44986..aadc6c4 100644
--- a/src/cmd/compile/internal/ssa/stackalloc.go
+++ b/src/cmd/compile/internal/ssa/stackalloc.go
@@ -72,6 +72,7 @@
 	typ      *types.Type
 	spill    *Value
 	needSlot bool
+	isArg    bool
 }
 
 // stackalloc allocates storage in the stack frame for
@@ -110,6 +111,7 @@
 		for _, v := range b.Values {
 			s.values[v.ID].typ = v.Type
 			s.values[v.ID].needSlot = !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() && f.getHome(v.ID) == nil && !v.rematerializeable()
+			s.values[v.ID].isArg = v.Op == OpArg
 			if f.pass.debug > stackDebug && s.values[v.ID].needSlot {
 				fmt.Printf("%s needs a stack slot\n", v)
 			}
@@ -151,9 +153,9 @@
 		if v.Op != OpArg {
 			continue
 		}
-		loc := LocalSlot{v.Aux.(GCNode), v.Type, v.AuxInt}
+		loc := LocalSlot{N: v.Aux.(GCNode), Type: v.Type, Off: v.AuxInt}
 		if f.pass.debug > stackDebug {
-			fmt.Printf("stackalloc %s to %s\n", v, loc.Name())
+			fmt.Printf("stackalloc %s to %s\n", v, loc)
 		}
 		f.setHome(v, loc)
 	}
@@ -216,7 +218,7 @@
 					}
 				}
 				if f.pass.debug > stackDebug {
-					fmt.Printf("stackalloc %s to %s\n", v, name.Name())
+					fmt.Printf("stackalloc %s to %s\n", v, name)
 				}
 				s.nNamedSlot++
 				f.setHome(v, name)
@@ -253,7 +255,7 @@
 			// Use the stack variable at that index for v.
 			loc := locs[i]
 			if f.pass.debug > stackDebug {
-				fmt.Printf("stackalloc %s to %s\n", v, loc.Name())
+				fmt.Printf("stackalloc %s to %s\n", v, loc)
 			}
 			f.setHome(v, loc)
 			slots[v.ID] = i
@@ -377,7 +379,9 @@
 			if s.values[v.ID].needSlot {
 				live.remove(v.ID)
 				for _, id := range live.contents() {
-					if s.values[v.ID].typ.Compare(s.values[id].typ) == types.CMPeq {
+					// Note: args can have different types and still interfere
+					// (with each other or with other values). See issue 23522.
+					if s.values[v.ID].typ.Compare(s.values[id].typ) == types.CMPeq || v.Op == OpArg || s.values[id].isArg {
 						s.interfere[v.ID] = append(s.interfere[v.ID], id)
 						s.interfere[id] = append(s.interfere[id], v.ID)
 					}
diff --git a/src/cmd/compile/internal/ssa/testdata/hist.dlv-dbg.nexts b/src/cmd/compile/internal/ssa/testdata/hist.dlv-dbg.nexts
new file mode 100644
index 0000000..ec79b77
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/hist.dlv-dbg.nexts
@@ -0,0 +1,99 @@
+  ./testdata/hist.go
+55:	func test() {
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+58:		tinycall()                // this forces l etc to stack
+59:		dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)//gdb-opt=(l,dx/O,dy/O)
+60:		dy := l.end.y - l.begin.y //gdb-opt=(dx,dy/O)
+61:		sink = dx + dy            //gdb-opt=(dx,dy)
+63:		hist := make([]int, 7)                                //gdb-opt=(dx/O,dy/O) // TODO sink is missing if this code is in 'test' instead of 'main'
+64:		var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A) // TODO cannedInput/A is missing if this code is in 'test' instead of 'main'
+65:		if len(os.Args) > 1 {
+73:		scanner := bufio.NewScanner(reader)
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+84:		t := 0
+85:		n := 0
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+98:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/hist.dlv-opt.nexts b/src/cmd/compile/internal/ssa/testdata/hist.dlv-opt.nexts
new file mode 100644
index 0000000..b98e3c6
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/hist.dlv-opt.nexts
@@ -0,0 +1,105 @@
+  ./testdata/hist.go
+55:	func test() {
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+58:		tinycall()                // this forces l etc to stack
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+59:		dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)//gdb-opt=(l,dx/O,dy/O)
+60:		dy := l.end.y - l.begin.y //gdb-opt=(dx,dy/O)
+61:		sink = dx + dy            //gdb-opt=(dx,dy)
+63:		hist := make([]int, 7)                                //gdb-opt=(dx/O,dy/O) // TODO sink is missing if this code is in 'test' instead of 'main'
+64:		var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A) // TODO cannedInput/A is missing if this code is in 'test' instead of 'main'
+65:		if len(os.Args) > 1 {
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+87:			if a == 0 { //gdb-opt=(a,n,t)
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+87:			if a == 0 { //gdb-opt=(a,n,t)
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+98:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/hist.gdb-dbg.nexts b/src/cmd/compile/internal/ssa/testdata/hist.gdb-dbg.nexts
new file mode 100644
index 0000000..fe00014
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/hist.gdb-dbg.nexts
@@ -0,0 +1,123 @@
+  src/cmd/compile/internal/ssa/testdata/hist.go
+55:	func test() {
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+58:		tinycall()                // this forces l etc to stack
+59:		dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)//gdb-opt=(l,dx/O,dy/O)
+l.begin.x = 1
+l.end.y = 4
+60:		dy := l.end.y - l.begin.y //gdb-opt=(dx,dy/O)
+61:		sink = dx + dy            //gdb-opt=(dx,dy)
+63:		hist := make([]int, 7)                                //gdb-opt=(dx/O,dy/O) // TODO sink is missing if this code is in 'test' instead of 'main'
+64:		var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A) // TODO cannedInput/A is missing if this code is in 'test' instead of 'main'
+hist =  []int = {0, 0, 0, 0, 0, 0, 0}
+65:		if len(os.Args) > 1 {
+73:		scanner := bufio.NewScanner(reader)
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 4
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 4
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+i = 5
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+84:		t := 0
+85:		n := 0
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+n = 3
+i = 1
+t = 3
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+n = 6
+i = 2
+t = 9
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+n = 8
+i = 4
+t = 17
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+90:			t += i * a
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+n = 9
+i = 5
+t = 22
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+88:				continue
+86:		for i, a := range hist {
+98:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/hist.gdb-opt.nexts b/src/cmd/compile/internal/ssa/testdata/hist.gdb-opt.nexts
new file mode 100644
index 0000000..e4dc280
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/hist.gdb-opt.nexts
@@ -0,0 +1,182 @@
+  src/cmd/compile/internal/ssa/testdata/hist.go
+55:	func test() {
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+58:		tinycall()                // this forces l etc to stack
+57:		l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+59:		dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)//gdb-opt=(l,dx/O,dy/O)
+l = {begin = {x = 1, y = 2}, end = {x = 3, y = 4}}
+dx = <Optimized out, as expected>
+dy = <Optimized out, as expected>
+60:		dy := l.end.y - l.begin.y //gdb-opt=(dx,dy/O)
+dx = 2
+dy = <Optimized out, as expected>
+61:		sink = dx + dy            //gdb-opt=(dx,dy)
+dx = 2
+dy = 2
+63:		hist := make([]int, 7)                                //gdb-opt=(dx/O,dy/O) // TODO sink is missing if this code is in 'test' instead of 'main'
+dx = <Optimized out, as expected>
+dy = <Optimized out, as expected>
+64:		var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A) // TODO cannedInput/A is missing if this code is in 'test' instead of 'main'
+65:		if len(os.Args) > 1 {
+73:		scanner := bufio.NewScanner(reader)
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 0, 0, 0, 0, 0, 0}
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 1, 0, 0, 0, 0, 0}
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 2, 0, 0, 0, 0, 0}
+i = 1
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 0, 0, 0, 0, 0}
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 1, 0, 0, 0, 0}
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 2, 0, 0, 0, 0}
+i = 2
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 3, 0, 0, 0, 0}
+i = 4
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 3, 0, 1, 0, 0}
+i = 4
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+75:			s := scanner.Text()
+76:			i, err := strconv.ParseInt(s, 10, 64)
+77:			if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+err = {tab = 0x0, data = 0x0}
+hist =  []int = {0, 3, 3, 0, 2, 0, 0}
+i = 5
+81:			hist = ensure(int(i), hist)
+82:			hist[int(i)]++
+74:		for scanner.Scan() { //gdb-opt=(scanner/A)
+scanner = (struct bufio.Scanner *) <A>
+86:		for i, a := range hist {
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 0
+n = 0
+t = 0
+88:				continue
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 3
+n = 0
+t = 0
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 3
+n = 3
+t = 3
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 0
+n = 6
+t = 9
+88:				continue
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 2
+n = 6
+t = 9
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 1
+n = 8
+t = 17
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+91:			n += a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+90:			t += i * a
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+86:		for i, a := range hist {
+92:			fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+87:			if a == 0 { //gdb-opt=(a,n,t)
+a = 0
+n = 9
+t = 22
+88:				continue
+98:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/hist.go b/src/cmd/compile/internal/ssa/testdata/hist.go
new file mode 100644
index 0000000..8a0cc27
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/hist.go
@@ -0,0 +1,98 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is the input program for an end-to-end test of the DWARF produced
+// by the compiler. It is compiled with various flags, then the resulting
+// binary is "debugged" under the control of a harness.  Because the compile+debug
+// step is time-consuming, the tests for different bugs are all accumulated here
+// so that their cost is only the time to "n" through the additional code.
+
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+)
+
+type point struct {
+	x, y int
+}
+
+type line struct {
+	begin, end point
+}
+
+var zero int
+var sink int
+
+//go:noinline
+func tinycall() {
+}
+
+func ensure(n int, sl []int) []int {
+	for len(sl) <= n {
+		sl = append(sl, 0)
+	}
+	return sl
+}
+
+var cannedInput string = `1
+1
+1
+2
+2
+2
+4
+4
+5
+`
+
+func test() {
+	// For #19868
+	l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
+	tinycall()                // this forces l etc to stack
+	dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)//gdb-opt=(l,dx/O,dy/O)
+	dy := l.end.y - l.begin.y //gdb-opt=(dx,dy/O)
+	sink = dx + dy            //gdb-opt=(dx,dy)
+	// For #21098
+	hist := make([]int, 7)                                //gdb-opt=(dx/O,dy/O) // TODO sink is missing if this code is in 'test' instead of 'main'
+	var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A) // TODO cannedInput/A is missing if this code is in 'test' instead of 'main'
+	if len(os.Args) > 1 {
+		var err error
+		reader, err = os.Open(os.Args[1])
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "There was an error opening %s: %v\n", os.Args[1], err)
+			return
+		}
+	}
+	scanner := bufio.NewScanner(reader)
+	for scanner.Scan() { //gdb-opt=(scanner/A)
+		s := scanner.Text()
+		i, err := strconv.ParseInt(s, 10, 64)
+		if err != nil { //gdb-dbg=(i) //gdb-opt=(err,hist,i)
+			fmt.Fprintf(os.Stderr, "There was an error: %v\n", err)
+			return
+		}
+		hist = ensure(int(i), hist)
+		hist[int(i)]++
+	}
+	t := 0
+	n := 0
+	for i, a := range hist {
+		if a == 0 { //gdb-opt=(a,n,t)
+			continue
+		}
+		t += i * a
+		n += a
+		fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
+	}
+}
+
+func main() {
+	test()
+}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22558.dlv-dbg-22558.nexts b/src/cmd/compile/internal/ssa/testdata/i22558.dlv-dbg-22558.nexts
new file mode 100644
index 0000000..3c33fe0
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22558.dlv-dbg-22558.nexts
@@ -0,0 +1,11 @@
+  ./testdata/i22558.go
+19:	func test(t *thing, u *thing) {
+20:		if t.next != nil {
+23:		fmt.Fprintf(os.Stderr, "%s\n", t.name)
+24:		u.self = u
+25:		t.self = t
+26:		t.next = u
+27:		for _, p := range t.stuff {
+28:			if isFoo(t, p) {
+29:				return
+43:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22558.gdb-dbg-22558.nexts b/src/cmd/compile/internal/ssa/testdata/i22558.gdb-dbg-22558.nexts
new file mode 100644
index 0000000..b88a227
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22558.gdb-dbg-22558.nexts
@@ -0,0 +1,11 @@
+  src/cmd/compile/internal/ssa/testdata/i22558.go
+19:	func test(t *thing, u *thing) {
+20:		if t.next != nil {
+23:		fmt.Fprintf(os.Stderr, "%s\n", t.name)
+24:		u.self = u
+25:		t.self = t
+26:		t.next = u
+27:		for _, p := range t.stuff {
+28:			if isFoo(t, p) {
+29:				return
+43:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22558.go b/src/cmd/compile/internal/ssa/testdata/i22558.go
new file mode 100644
index 0000000..a62e11e
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22558.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+type big struct {
+	pile [768]int8
+}
+
+type thing struct {
+	name  string
+	next  *thing
+	self  *thing
+	stuff []big
+}
+
+func test(t *thing, u *thing) {
+	if t.next != nil {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "%s\n", t.name)
+	u.self = u
+	t.self = t
+	t.next = u
+	for _, p := range t.stuff {
+		if isFoo(t, p) {
+			return
+		}
+	}
+}
+
+//go:noinline
+func isFoo(t *thing, b big) bool {
+	return true
+}
+
+func main() {
+	t := &thing{name: "t", self: nil, next: nil, stuff: make([]big, 1)}
+	u := thing{name: "u", self: t, next: t, stuff: make([]big, 1)}
+	test(t, &u)
+}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22600.dlv-dbg-race.nexts b/src/cmd/compile/internal/ssa/testdata/i22600.dlv-dbg-race.nexts
new file mode 100644
index 0000000..46aad7c
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22600.dlv-dbg-race.nexts
@@ -0,0 +1,7 @@
+  ./testdata/i22600.go
+8:	func test() {
+9:		pwd, err := os.Getwd()
+10:		if err != nil {
+14:		fmt.Println(pwd)
+15:	}
+19:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22600.gdb-dbg-race.nexts b/src/cmd/compile/internal/ssa/testdata/i22600.gdb-dbg-race.nexts
new file mode 100644
index 0000000..bfffec4
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22600.gdb-dbg-race.nexts
@@ -0,0 +1,7 @@
+  src/cmd/compile/internal/ssa/testdata/i22600.go
+8:	func test() {
+9:		pwd, err := os.Getwd()
+10:		if err != nil {
+14:		fmt.Println(pwd)
+15:	}
+19:	}
diff --git a/src/cmd/compile/internal/ssa/testdata/i22600.go b/src/cmd/compile/internal/ssa/testdata/i22600.go
new file mode 100644
index 0000000..f7a7ade
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/i22600.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+func test() {
+	pwd, err := os.Getwd()
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+	fmt.Println(pwd)
+}
+
+func main() {
+	test()
+}
diff --git a/src/cmd/compile/internal/ssa/trim.go b/src/cmd/compile/internal/ssa/trim.go
index 04b4fd4..d97c6ba 100644
--- a/src/cmd/compile/internal/ssa/trim.go
+++ b/src/cmd/compile/internal/ssa/trim.go
@@ -121,9 +121,8 @@
 }
 
 // mergePhi adjusts the number of `v`s arguments to account for merge
-// of `b`, which was `i`th predecessor of the `v`s block. Returns
-// `v`.
-func mergePhi(v *Value, i int, b *Block) *Value {
+// of `b`, which was `i`th predecessor of the `v`s block.
+func mergePhi(v *Value, i int, b *Block) {
 	u := v.Args[i]
 	if u.Block == b {
 		if u.Op != OpPhi {
@@ -147,5 +146,4 @@
 			v.AddArg(v.Args[i])
 		}
 	}
-	return v
 }
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 7edc71b..832ed8d 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -6,10 +6,11 @@
 
 import (
 	"cmd/compile/internal/types"
-	"cmd/internal/obj"
 	"cmd/internal/src"
 	"fmt"
 	"math"
+	"sort"
+	"strings"
 )
 
 // A Value represents a value in the SSA representation of the program.
@@ -98,7 +99,7 @@
 	return ValAndOff(v.AuxInt)
 }
 
-// long form print.  v# = opcode <type> [aux] args [: reg]
+// long form print.  v# = opcode <type> [aux] args [: reg] (names)
 func (v *Value) LongString() string {
 	s := fmt.Sprintf("v%d = %s", v.ID, v.Op)
 	s += " <" + v.Type.String() + ">"
@@ -108,7 +109,20 @@
 	}
 	r := v.Block.Func.RegAlloc
 	if int(v.ID) < len(r) && r[v.ID] != nil {
-		s += " : " + r[v.ID].Name()
+		s += " : " + r[v.ID].String()
+	}
+	var names []string
+	for name, values := range v.Block.Func.NamedValues {
+		for _, value := range values {
+			if value == v {
+				names = append(names, name.String())
+				break // drop duplicates.
+			}
+		}
+	}
+	if len(names) != 0 {
+		sort.Strings(names) // Otherwise a source of variation in debugging output.
+		s += " (" + strings.Join(names, ", ") + ")"
 	}
 	return s
 }
@@ -228,7 +242,13 @@
 // The copied value receives no source code position to avoid confusing changes
 // in debugger information (the intended user is the register allocator).
 func (v *Value) copyIntoNoXPos(b *Block) *Value {
-	c := b.NewValue0(src.NoXPos, v.Op, v.Type) // Lose the position, this causes line number churn otherwise.
+	return v.copyIntoWithXPos(b, src.NoXPos)
+}
+
+// copyIntoWithXPos makes a new value identical to v and adds it to the end of b.
+// The supplied position is used as the position of the new value.
+func (v *Value) copyIntoWithXPos(b *Block, pos src.XPos) *Value {
+	c := b.NewValue0(pos, v.Op, v.Type)
 	c.Aux = v.Aux
 	c.AuxInt = v.AuxInt
 	c.AddArgs(v.Args...)
@@ -251,38 +271,6 @@
 	return v != nil && (v.Op == OpConst64 || v.Op == OpConst32 || v.Op == OpConst16 || v.Op == OpConst8)
 }
 
-// ExternSymbol is an aux value that encodes a variable's
-// constant offset from the static base pointer.
-type ExternSymbol struct {
-	Sym *obj.LSym
-	// Note: the offset for an external symbol is not
-	// calculated until link time.
-}
-
-// ArgSymbol is an aux value that encodes an argument or result
-// variable's constant offset from FP (FP = SP + framesize).
-type ArgSymbol struct {
-	Node GCNode // A *gc.Node referring to the argument/result variable.
-}
-
-// AutoSymbol is an aux value that encodes a local variable's
-// constant offset from SP.
-type AutoSymbol struct {
-	Node GCNode // A *gc.Node referring to a local (auto) variable.
-}
-
-func (s *ExternSymbol) String() string {
-	return s.Sym.String()
-}
-
-func (s *ArgSymbol) String() string {
-	return s.Node.String()
-}
-
-func (s *AutoSymbol) String() string {
-	return s.Node.String()
-}
-
 // Reg returns the register assigned to v, in cmd/internal/obj/$ARCH numbering.
 func (v *Value) Reg() int16 {
 	reg := v.Block.Func.RegAlloc[v.ID]
@@ -334,3 +322,14 @@
 	}
 	return nil
 }
+
+// LackingPos indicates whether v is a value that is unlikely to have a correct
+// position assigned to it.  Ignoring such values leads to more user-friendly positions
+// assigned to nearby values and the blocks containing them.
+func (v *Value) LackingPos() bool {
+	// The exact definition of LackingPos is somewhat heuristically defined and may change
+	// in the future, for example if some of these operations are generated more carefully
+	// with respect to their source position.
+	return v.Op == OpVarDef || v.Op == OpVarKill || v.Op == OpVarLive || v.Op == OpPhi ||
+		(v.Op == OpFwdRef || v.Op == OpCopy) && v.Type == types.TypeMem
+}
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index cf22724..b711d8d 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -17,7 +17,7 @@
 	if !ok {
 		v.Fatalf("store aux is not a type: %s", v.LongString())
 	}
-	if !t.HasPointer() {
+	if !t.HasHeapPointer() {
 		return false
 	}
 	if IsStackAddr(v.Args[0]) {
@@ -44,7 +44,7 @@
 	}
 
 	var sb, sp, wbaddr, const0 *Value
-	var writebarrierptr, typedmemmove, typedmemclr *obj.LSym
+	var writebarrierptr, typedmemmove, typedmemclr, gcWriteBarrier *obj.LSym
 	var stores, after []*Value
 	var sset *sparseSet
 	var storeNumber []int32
@@ -52,7 +52,7 @@
 	for _, b := range f.Blocks { // range loop is safe since the blocks we added contain no stores to expand
 		// first, identify all the stores that need to insert a write barrier.
 		// mark them with WB ops temporarily. record presence of WB ops.
-		hasStore := false
+		nWBops := 0 // count of temporarily created WB ops remaining to be rewritten in the current block
 		for _, v := range b.Values {
 			switch v.Op {
 			case OpStore, OpMove, OpZero:
@@ -65,11 +65,11 @@
 					case OpZero:
 						v.Op = OpZeroWB
 					}
-					hasStore = true
+					nWBops++
 				}
 			}
 		}
-		if !hasStore {
+		if nWBops == 0 {
 			continue
 		}
 
@@ -94,9 +94,12 @@
 			if sp == nil {
 				sp = f.Entry.NewValue0(initpos, OpSP, f.Config.Types.Uintptr)
 			}
-			wbsym := &ExternSymbol{Sym: f.fe.Syslook("writeBarrier")}
+			wbsym := f.fe.Syslook("writeBarrier")
 			wbaddr = f.Entry.NewValue1A(initpos, OpAddr, f.Config.Types.UInt32Ptr, wbsym, sb)
 			writebarrierptr = f.fe.Syslook("writebarrierptr")
+			if !f.fe.Debug_eagerwb() {
+				gcWriteBarrier = f.fe.Syslook("gcWriteBarrier")
+			}
 			typedmemmove = f.fe.Syslook("typedmemmove")
 			typedmemclr = f.fe.Syslook("typedmemclr")
 			const0 = f.ConstInt32(initpos, f.Config.Types.UInt32, 0)
@@ -170,6 +173,15 @@
 		b.Succs = b.Succs[:0]
 		b.AddEdgeTo(bThen)
 		b.AddEdgeTo(bElse)
+		// TODO: For OpStoreWB and the buffered write barrier,
+		// we could move the write out of the write barrier,
+		// which would lead to fewer branches. We could do
+		// something similar to OpZeroWB, since the runtime
+		// could provide just the barrier half and then we
+		// could unconditionally do an OpZero (which could
+		// also generate better zeroing code). OpMoveWB is
+		// trickier and would require changing how
+		// cgoCheckMemmove works.
 		bThen.AddEdgeTo(bEnd)
 		bElse.AddEdgeTo(bEnd)
 
@@ -182,19 +194,22 @@
 			pos := w.Pos
 
 			var fn *obj.LSym
-			var typ *ExternSymbol
+			var typ *obj.LSym
 			var val *Value
 			switch w.Op {
 			case OpStoreWB:
 				fn = writebarrierptr
 				val = w.Args[1]
+				nWBops--
 			case OpMoveWB:
 				fn = typedmemmove
 				val = w.Args[1]
-				typ = &ExternSymbol{Sym: w.Aux.(*types.Type).Symbol()}
+				typ = w.Aux.(*types.Type).Symbol()
+				nWBops--
 			case OpZeroWB:
 				fn = typedmemclr
-				typ = &ExternSymbol{Sym: w.Aux.(*types.Type).Symbol()}
+				typ = w.Aux.(*types.Type).Symbol()
+				nWBops--
 			case OpVarDef, OpVarLive, OpVarKill:
 			}
 
@@ -202,7 +217,11 @@
 			switch w.Op {
 			case OpStoreWB, OpMoveWB, OpZeroWB:
 				volatile := w.Op == OpMoveWB && isVolatile(val)
-				memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
+				if w.Op == OpStoreWB && !f.fe.Debug_eagerwb() {
+					memThen = bThen.NewValue3A(pos, OpWB, types.TypeMem, gcWriteBarrier, ptr, val, memThen)
+				} else {
+					memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
+				}
 			case OpVarDef, OpVarLive, OpVarKill:
 				memThen = bThen.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, memThen)
 			}
@@ -223,12 +242,7 @@
 
 			if fn != nil {
 				// Note that we set up a writebarrier function call.
-				if !f.WBPos.IsKnown() {
-					f.WBPos = pos
-				}
-				if f.fe.Debug_wb() {
-					f.Warnl(pos, "write barrier")
-				}
+				f.fe.SetWBPos(pos)
 			}
 		}
 
@@ -261,20 +275,15 @@
 		}
 
 		// if we have more stores in this block, do this block again
-		// check from end to beginning, to avoid quadratic behavior; issue 13554
-		// TODO: track the final value to avoid any looping here at all
-		for i := len(b.Values) - 1; i >= 0; i-- {
-			switch b.Values[i].Op {
-			case OpStoreWB, OpMoveWB, OpZeroWB:
-				goto again
-			}
+		if nWBops > 0 {
+			goto again
 		}
 	}
 }
 
 // wbcall emits write barrier runtime call in b, returns memory.
 // if valIsVolatile, it moves val into temp space before making the call.
-func wbcall(pos src.XPos, b *Block, fn *obj.LSym, typ *ExternSymbol, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
+func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
 	config := b.Func.Config
 
 	var tmp GCNode
@@ -284,9 +293,8 @@
 		// value we're trying to move.
 		t := val.Type.ElemType()
 		tmp = b.Func.fe.Auto(val.Pos, t)
-		aux := &AutoSymbol{Node: tmp}
 		mem = b.NewValue1A(pos, OpVarDef, types.TypeMem, tmp, mem)
-		tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), aux, sp)
+		tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), tmp, sp)
 		siz := t.Size()
 		mem = b.NewValue3I(pos, OpMove, types.TypeMem, siz, tmpaddr, val, mem)
 		mem.Aux = t
diff --git a/src/cmd/compile/internal/syntax/branches.go b/src/cmd/compile/internal/syntax/branches.go
index 5fecdd6..2fd97a4 100644
--- a/src/cmd/compile/internal/syntax/branches.go
+++ b/src/cmd/compile/internal/syntax/branches.go
@@ -131,7 +131,7 @@
 // blockBranches processes a block's body starting at start and returns the
 // list of unresolved (forward) gotos. parent is the immediately enclosing
 // block (or nil), ctxt provides information about the enclosing statements,
-// and lstmt is the labeled statement asociated with this block, or nil.
+// and lstmt is the labeled statement associated with this block, or nil.
 func (ls *labelScope) blockBranches(parent *block, ctxt targets, lstmt *LabeledStmt, start src.Pos, body []Stmt) []*BranchStmt {
 	b := &block{parent: parent, start: start, lstmt: lstmt}
 
diff --git a/src/cmd/compile/internal/syntax/nodes_test.go b/src/cmd/compile/internal/syntax/nodes_test.go
index be9d5d8..1bba9ee 100644
--- a/src/cmd/compile/internal/syntax/nodes_test.go
+++ b/src/cmd/compile/internal/syntax/nodes_test.go
@@ -291,7 +291,7 @@
 		}
 
 		// build syntaxt tree
-		file, err := ParseBytes(nil, []byte(src), nil, nil, 0)
+		file, err := ParseBytes(nil, []byte(src), nil, nil, nil, 0)
 		if err != nil {
 			t.Errorf("parse error: %s: %v (%s)", src, err, test.nodetyp)
 			continue
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index bcf56d5..c8dfc96 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -16,12 +16,14 @@
 const trace = false
 
 type parser struct {
-	base *src.PosBase
-	errh ErrorHandler
-	mode Mode
+	base  *src.PosBase
+	errh  ErrorHandler
+	fileh FilenameHandler
+	mode  Mode
 	scanner
 
 	first  error  // first error encountered
+	errcnt int    // number of errors encountered
 	pragma Pragma // pragma flags
 
 	fnest  int    // function nesting level (for error handling)
@@ -29,9 +31,10 @@
 	indent []byte // tracing support
 }
 
-func (p *parser) init(base *src.PosBase, r io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) {
+func (p *parser) init(base *src.PosBase, r io.Reader, errh ErrorHandler, pragh PragmaHandler, fileh FilenameHandler, mode Mode) {
 	p.base = base
 	p.errh = errh
+	p.fileh = fileh
 	p.mode = mode
 	p.scanner.init(
 		r,
@@ -55,6 +58,7 @@
 	)
 
 	p.first = nil
+	p.errcnt = 0
 	p.pragma = 0
 
 	p.fnest = 0
@@ -76,7 +80,12 @@
 		p.error_at(p.pos_at(line, col+uint(i+1)), "invalid line number: "+nstr)
 		return
 	}
-	p.base = src.NewLinePragmaBase(src.MakePos(p.base.Pos().Base(), line, col), text[:i], uint(n))
+	filename := text[:i]
+	absFilename := filename
+	if p.fileh != nil {
+		absFilename = p.fileh(filename)
+	}
+	p.base = src.NewLinePragmaBase(src.MakePos(p.base.Pos().Base(), line, col), filename, absFilename, uint(n))
 }
 
 func (p *parser) got(tok token) bool {
@@ -89,7 +98,7 @@
 
 func (p *parser) want(tok token) {
 	if !p.got(tok) {
-		p.syntax_error("expecting " + tok.String())
+		p.syntax_error("expecting " + tokstring(tok))
 		p.advance()
 	}
 }
@@ -108,6 +117,7 @@
 	if p.first == nil {
 		p.first = err
 	}
+	p.errcnt++
 	if p.errh == nil {
 		panic(p.first)
 	}
@@ -117,7 +127,7 @@
 // syntax_error_at reports a syntax error at the given position.
 func (p *parser) syntax_error_at(pos src.Pos, msg string) {
 	if trace {
-		defer p.trace("syntax_error (" + msg + ")")()
+		p.print("syntax error: " + msg)
 	}
 
 	if p.tok == _EOF && p.first != nil {
@@ -159,6 +169,18 @@
 	p.error_at(pos, "syntax error: unexpected "+tok+msg)
 }
 
+// tokstring returns the English word for selected punctuation tokens
+// for more readable error messages.
+func tokstring(tok token) string {
+	switch tok {
+	case _Comma:
+		return "comma"
+	case _Semi:
+		return "semicolon or newline"
+	}
+	return tok.String()
+}
+
 // Convenience methods using the current token position.
 func (p *parser) pos() src.Pos            { return p.pos_at(p.line, p.col) }
 func (p *parser) error(msg string)        { p.error_at(p.pos(), msg) }
@@ -173,7 +195,6 @@
 	1<<_Defer |
 	1<<_Fallthrough |
 	1<<_For |
-	1<<_Func |
 	1<<_Go |
 	1<<_Goto |
 	1<<_If |
@@ -186,40 +207,42 @@
 // Advance consumes tokens until it finds a token of the stopset or followlist.
 // The stopset is only considered if we are inside a function (p.fnest > 0).
 // The followlist is the list of valid tokens that can follow a production;
-// if it is empty, exactly one token is consumed to ensure progress.
+// if it is empty, exactly one (non-EOF) token is consumed to ensure progress.
 func (p *parser) advance(followlist ...token) {
-	if len(followlist) == 0 {
-		p.next()
-		return
+	if trace {
+		p.print(fmt.Sprintf("advance %s", followlist))
 	}
 
 	// compute follow set
 	// (not speed critical, advance is only called in error situations)
-	var followset uint64 = 1 << _EOF // never skip over EOF
-	for _, tok := range followlist {
-		followset |= 1 << tok
+	var followset uint64 = 1 << _EOF // don't skip over EOF
+	if len(followlist) > 0 {
+		if p.fnest > 0 {
+			followset |= stopset
+		}
+		for _, tok := range followlist {
+			followset |= 1 << tok
+		}
 	}
 
-	for !(contains(followset, p.tok) || p.fnest > 0 && contains(stopset, p.tok)) {
+	for !contains(followset, p.tok) {
+		if trace {
+			p.print("skip " + p.tok.String())
+		}
 		p.next()
+		if len(followlist) == 0 {
+			break
+		}
 	}
-}
 
-func tokstring(tok token) string {
-	switch tok {
-	case _EOF:
-		return "EOF"
-	case _Comma:
-		return "comma"
-	case _Semi:
-		return "semicolon"
+	if trace {
+		p.print("next " + p.tok.String())
 	}
-	return tok.String()
 }
 
 // usage: defer p.trace(msg)()
 func (p *parser) trace(msg string) func() {
-	fmt.Printf("%5d: %s%s (\n", p.line, p.indent, msg)
+	p.print(msg + " (")
 	const tab = ". "
 	p.indent = append(p.indent, tab...)
 	return func() {
@@ -227,10 +250,14 @@
 		if x := recover(); x != nil {
 			panic(x) // skip print_trace
 		}
-		fmt.Printf("%5d: %s)\n", p.line, p.indent)
+		p.print(")")
 	}
 }
 
+func (p *parser) print(msg string) {
+	fmt.Printf("%5d: %s%s\n", p.line, p.indent, msg)
+}
+
 // ----------------------------------------------------------------------------
 // Package files
 //
@@ -325,17 +352,47 @@
 // ----------------------------------------------------------------------------
 // Declarations
 
-// appendGroup(f) = f | "(" { f ";" } ")" .
-func (p *parser) appendGroup(list []Decl, f func(*Group) Decl) []Decl {
-	if p.got(_Lparen) {
-		g := new(Group)
-		for p.tok != _EOF && p.tok != _Rparen {
-			list = append(list, f(g))
-			if !p.osemi(_Rparen) {
-				break
+// list parses a possibly empty, sep-separated list, optionally
+// followed by sep and enclosed by ( and ) or { and }. open is
+// one of _Lparen, or _Lbrace, sep is one of _Comma or _Semi,
+// and close is expected to be the (closing) opposite of open.
+// For each list element, f is called. After f returns true, no
+// more list elements are accepted. list returns the position
+// of the closing token.
+//
+// list = "(" { f sep } ")" |
+//        "{" { f sep } "}" . // sep is optional before ")" or "}"
+//
+func (p *parser) list(open, sep, close token, f func() bool) src.Pos {
+	p.want(open)
+
+	var done bool
+	for p.tok != _EOF && p.tok != close && !done {
+		done = f()
+		// sep is optional before close
+		if !p.got(sep) && p.tok != close {
+			p.syntax_error(fmt.Sprintf("expecting %s or %s", tokstring(sep), tokstring(close)))
+			p.advance(_Rparen, _Rbrack, _Rbrace)
+			if p.tok != close {
+				// position could be better but we had an error so we don't care
+				return p.pos()
 			}
 		}
-		p.want(_Rparen)
+	}
+
+	pos := p.pos()
+	p.want(close)
+	return pos
+}
+
+// appendGroup(f) = f | "(" { f ";" } ")" . // ";" is optional before ")"
+func (p *parser) appendGroup(list []Decl, f func(*Group) Decl) []Decl {
+	if p.tok == _Lparen {
+		g := new(Group)
+		p.list(_Lparen, _Semi, _Rparen, func() bool {
+			list = append(list, f(g))
+			return false
+		})
 	} else {
 		list = append(list, f(nil))
 	}
@@ -478,39 +535,32 @@
 		return nil
 	}
 
-	// TODO(gri) check for regular functions only
-	// if name.Sym.Name == "init" {
-	// 	name = renameinit()
-	// 	if params != nil || result != nil {
-	// 		p.error("func init must have no arguments and no return values")
-	// 	}
-	// }
-
-	// if localpkg.Name == "main" && name.Name == "main" {
-	// 	if params != nil || result != nil {
-	// 		p.error("func main must have no arguments and no return values")
-	// 	}
-	// }
-
 	f.Name = p.name()
 	f.Type = p.funcType()
 	if p.tok == _Lbrace {
-		f.Body = p.blockStmt("")
-		if p.mode&CheckBranches != 0 {
-			checkBranches(f.Body, p.errh)
-		}
+		f.Body = p.funcBody()
 	}
-
 	f.Pragma = p.pragma
 
-	// TODO(gri) deal with function properties
-	// if noescape && body != nil {
-	// 	p.error("can only use //go:noescape with external func implementations")
-	// }
-
 	return f
 }
 
+func (p *parser) funcBody() *BlockStmt {
+	p.fnest++
+	errcnt := p.errcnt
+	body := p.blockStmt("")
+	p.fnest--
+
+	// Don't check branches if there were syntax errors in the function
+	// as it may lead to spurious errors (e.g., see test/switch2.go) or
+	// possibly crashes due to incomplete syntax trees.
+	if p.mode&CheckBranches != 0 && errcnt == p.errcnt {
+		checkBranches(body, p.errh)
+	}
+
+	return body
+}
+
 // ----------------------------------------------------------------------------
 // Expressions
 
@@ -726,10 +776,7 @@
 			f := new(FuncLit)
 			f.pos = pos
 			f.Type = t
-			f.Body = p.blockStmt("")
-			if p.mode&CheckBranches != 0 {
-				checkBranches(f.Body, p.errh)
-			}
+			f.Body = p.funcBody()
 
 			p.xnest--
 			return f
@@ -859,7 +906,11 @@
 			p.xnest--
 
 		case _Lparen:
-			x = p.call(x)
+			t := new(CallExpr)
+			t.pos = pos
+			t.Fun = x
+			t.ArgList, t.HasDots = p.argList()
+			x = t
 
 		case _Lbrace:
 			// operand may have returned a parenthesized complit
@@ -919,10 +970,8 @@
 	x := new(CompositeLit)
 	x.pos = p.pos()
 
-	p.want(_Lbrace)
 	p.xnest++
-
-	for p.tok != _EOF && p.tok != _Rbrace {
+	x.Rbrace = p.list(_Lbrace, _Comma, _Rbrace, func() bool {
 		// value
 		e := p.bare_complitexpr()
 		if p.tok == _Colon {
@@ -936,14 +985,9 @@
 			x.NKeys++
 		}
 		x.ElemList = append(x.ElemList, e)
-		if !p.ocomma(_Rbrace) {
-			break
-		}
-	}
-
-	x.Rbrace = p.pos()
+		return false
+	})
 	p.xnest--
-	p.want(_Rbrace)
 
 	return x
 }
@@ -1129,14 +1173,10 @@
 	typ.pos = p.pos()
 
 	p.want(_Struct)
-	p.want(_Lbrace)
-	for p.tok != _EOF && p.tok != _Rbrace {
+	p.list(_Lbrace, _Semi, _Rbrace, func() bool {
 		p.fieldDecl(typ)
-		if !p.osemi(_Rbrace) {
-			break
-		}
-	}
-	p.want(_Rbrace)
+		return false
+	})
 
 	return typ
 }
@@ -1151,36 +1191,16 @@
 	typ.pos = p.pos()
 
 	p.want(_Interface)
-	p.want(_Lbrace)
-	for p.tok != _EOF && p.tok != _Rbrace {
+	p.list(_Lbrace, _Semi, _Rbrace, func() bool {
 		if m := p.methodDecl(); m != nil {
 			typ.MethodList = append(typ.MethodList, m)
 		}
-		if !p.osemi(_Rbrace) {
-			break
-		}
-	}
-	p.want(_Rbrace)
+		return false
+	})
 
 	return typ
 }
 
-// FunctionBody = Block .
-func (p *parser) funcBody() []Stmt {
-	if trace {
-		defer p.trace("funcBody")()
-	}
-
-	p.fnest++
-	body := p.stmtList()
-	p.fnest--
-
-	if body == nil {
-		body = []Stmt{new(EmptyStmt)}
-	}
-	return body
-}
-
 // Result = Parameters | Type .
 func (p *parser) funcResult() []*Field {
 	if trace {
@@ -1429,10 +1449,9 @@
 	}
 
 	pos := p.pos()
-	p.want(_Lparen)
 
 	var named int // number of parameters that have an explicit name and type
-	for p.tok != _EOF && p.tok != _Rparen {
+	p.list(_Lparen, _Comma, _Rparen, func() bool {
 		if par := p.paramDeclOrNil(); par != nil {
 			if debug && par.Name == nil && par.Type == nil {
 				panic("parameter without name or type")
@@ -1442,10 +1461,8 @@
 			}
 			list = append(list, par)
 		}
-		if !p.ocomma(_Rparen) {
-			break
-		}
-	}
+		return false
+	})
 
 	// distribute parameter types
 	if named == 0 {
@@ -1484,7 +1501,6 @@
 		}
 	}
 
-	p.want(_Rparen)
 	return
 }
 
@@ -1665,6 +1681,7 @@
 	return nil // avoids follow-on errors (see e.g., fixedbugs/bug274.go)
 }
 
+// context must be a non-empty string unless we know that p.tok == _Lbrace.
 func (p *parser) blockStmt(context string) *BlockStmt {
 	if trace {
 		defer p.trace("blockStmt")()
@@ -1673,10 +1690,14 @@
 	s := new(BlockStmt)
 	s.pos = p.pos()
 
+	// people coming from C may forget that braces are mandatory in Go
 	if !p.got(_Lbrace) {
 		p.syntax_error("expecting { after " + context)
 		p.advance(_Name, _Rbrace)
-		// TODO(gri) may be better to return here than to continue (#19663)
+		s.Rbrace = p.pos() // in case we found "}"
+		if p.got(_Rbrace) {
+			return s
+		}
 	}
 
 	s.List = p.stmtList()
@@ -1714,9 +1735,6 @@
 	return s
 }
 
-// TODO(gri) This function is now so heavily influenced by the keyword that
-//           it may not make sense anymore to combine all three cases. It
-//           may be simpler to just split it up for each statement kind.
 func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleStmt) {
 	p.want(keyword)
 
@@ -1749,10 +1767,14 @@
 		pos src.Pos
 		lit string // valid if pos.IsKnown()
 	}
-	if p.tok == _Semi {
-		semi.pos = p.pos()
-		semi.lit = p.lit
-		p.next()
+	if p.tok != _Lbrace {
+		if p.tok == _Semi {
+			semi.pos = p.pos()
+			semi.lit = p.lit
+			p.next()
+		} else {
+			p.want(_Semi)
+		}
 		if keyword == _For {
 			if p.tok != _Semi {
 				if p.tok == _Lbrace {
@@ -2050,46 +2072,31 @@
 			break
 		}
 		l = append(l, s)
-		// customized version of osemi:
-		// ';' is optional before a closing ')' or '}'
-		if p.tok == _Rparen || p.tok == _Rbrace {
-			continue
-		}
-		if !p.got(_Semi) {
+		// ";" is optional before "}"
+		if !p.got(_Semi) && p.tok != _Rbrace {
 			p.syntax_error("at end of statement")
-			p.advance(_Semi, _Rbrace)
+			p.advance(_Semi, _Rbrace, _Case, _Default)
+			p.got(_Semi) // avoid spurious empty statement
 		}
 	}
 	return
 }
 
 // Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
-func (p *parser) call(fun Expr) *CallExpr {
+func (p *parser) argList() (list []Expr, hasDots bool) {
 	if trace {
-		defer p.trace("call")()
+		defer p.trace("argList")()
 	}
 
-	// call or conversion
-	// convtype '(' expr ocomma ')'
-	c := new(CallExpr)
-	c.pos = p.pos()
-	c.Fun = fun
-
-	p.want(_Lparen)
 	p.xnest++
-
-	for p.tok != _EOF && p.tok != _Rparen {
-		c.ArgList = append(c.ArgList, p.expr())
-		c.HasDots = p.got(_DotDotDot)
-		if !p.ocomma(_Rparen) || c.HasDots {
-			break
-		}
-	}
-
+	p.list(_Lparen, _Comma, _Rparen, func() bool {
+		list = append(list, p.expr())
+		hasDots = p.got(_DotDotDot)
+		return hasDots
+	})
 	p.xnest--
-	p.want(_Rparen)
 
-	return c
+	return
 }
 
 // ----------------------------------------------------------------------------
@@ -2176,40 +2183,6 @@
 	return x
 }
 
-// osemi parses an optional semicolon.
-func (p *parser) osemi(follow token) bool {
-	switch p.tok {
-	case _Semi:
-		p.next()
-		return true
-
-	case _Rparen, _Rbrace:
-		// semicolon is optional before ) or }
-		return true
-	}
-
-	p.syntax_error("expecting semicolon, newline, or " + tokstring(follow))
-	p.advance(follow)
-	return false
-}
-
-// ocomma parses an optional comma.
-func (p *parser) ocomma(follow token) bool {
-	switch p.tok {
-	case _Comma:
-		p.next()
-		return true
-
-	case _Rparen, _Rbrace:
-		// comma is optional before ) or }
-		return true
-	}
-
-	p.syntax_error("expecting comma or " + tokstring(follow))
-	p.advance(follow)
-	return false
-}
-
 // unparen removes all parentheses around an expression.
 func unparen(x Expr) Expr {
 	for {
diff --git a/src/cmd/compile/internal/syntax/parser_test.go b/src/cmd/compile/internal/syntax/parser_test.go
index 4c317da..309f133 100644
--- a/src/cmd/compile/internal/syntax/parser_test.go
+++ b/src/cmd/compile/internal/syntax/parser_test.go
@@ -131,7 +131,7 @@
 		panic(err)
 	}
 
-	ast2, err := ParseBytes(src.NewFileBase(filename, filename), buf1.Bytes(), nil, nil, 0)
+	ast2, err := ParseBytes(src.NewFileBase(filename, filename), buf1.Bytes(), nil, nil, nil, 0)
 	if err != nil {
 		panic(err)
 	}
@@ -155,7 +155,7 @@
 }
 
 func TestIssue17697(t *testing.T) {
-	_, err := ParseBytes(nil, nil, nil, nil, 0) // return with parser error, don't panic
+	_, err := ParseBytes(nil, nil, nil, nil, nil, 0) // return with parser error, don't panic
 	if err == nil {
 		t.Errorf("no error reported")
 	}
@@ -199,8 +199,16 @@
 		// test effect of //line directive on (relative) position information
 		{"//line foo:123\n   foo", "syntax error: package statement must be first", "foo", 123 - linebase, 3},
 		{"//line foo:123\n//line bar:345\nfoo", "syntax error: package statement must be first", "bar", 345 - linebase, 0},
+
+		{"//line " + runtime.GOROOT() + "/src/a/a.go:123\n   foo", "syntax error: package statement must be first", "$GOROOT/src/a/a.go", 123 - linebase, 3},
 	} {
-		_, err := ParseBytes(nil, []byte(test.src), nil, nil, 0)
+		fileh := func(name string) string {
+			if strings.HasPrefix(name, runtime.GOROOT()) {
+				return "$GOROOT" + name[len(runtime.GOROOT()):]
+			}
+			return name
+		}
+		_, err := ParseBytes(nil, []byte(test.src), nil, nil, fileh, 0)
 		if err == nil {
 			t.Errorf("%s: no error reported", test.src)
 			continue
@@ -213,7 +221,7 @@
 		if msg := perr.Msg; msg != test.msg {
 			t.Errorf("%s: got msg = %q; want %q", test.src, msg, test.msg)
 		}
-		if filename := perr.Pos.RelFilename(); filename != test.filename {
+		if filename := perr.Pos.AbsFilename(); filename != test.filename {
 			t.Errorf("%s: got filename = %q; want %q", test.src, filename, test.filename)
 		}
 		if line := perr.Pos.RelLine(); line != test.line+linebase {
diff --git a/src/cmd/compile/internal/syntax/printer_test.go b/src/cmd/compile/internal/syntax/printer_test.go
index 14652f4..bbf75a9 100644
--- a/src/cmd/compile/internal/syntax/printer_test.go
+++ b/src/cmd/compile/internal/syntax/printer_test.go
@@ -29,7 +29,7 @@
 		"package p; type _ = int; type T1 = struct{}; type ( _ = *struct{}; T2 = float32 )",
 		// TODO(gri) expand
 	} {
-		ast, err := ParseBytes(nil, []byte(want), nil, nil, 0)
+		ast, err := ParseBytes(nil, []byte(want), nil, nil, nil, 0)
 		if err != nil {
 			t.Error(err)
 			continue
diff --git a/src/cmd/compile/internal/syntax/scanner_test.go b/src/cmd/compile/internal/syntax/scanner_test.go
index e434db9..53995e0 100644
--- a/src/cmd/compile/internal/syntax/scanner_test.go
+++ b/src/cmd/compile/internal/syntax/scanner_test.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"os"
+	"strings"
 	"testing"
 )
 
@@ -367,3 +368,15 @@
 		}
 	}
 }
+
+func TestIssue21938(t *testing.T) {
+	s := "/*" + strings.Repeat(" ", 4089) + "*/ .5"
+
+	var got scanner
+	got.init(strings.NewReader(s), nil, nil)
+	got.next()
+
+	if got.tok != _Literal || got.lit != ".5" {
+		t.Errorf("got %s %q; want %s %q", got.tok, got.lit, _Literal, ".5")
+	}
+}
diff --git a/src/cmd/compile/internal/syntax/source.go b/src/cmd/compile/internal/syntax/source.go
index 9354721..4e35512 100644
--- a/src/cmd/compile/internal/syntax/source.go
+++ b/src/cmd/compile/internal/syntax/source.go
@@ -164,11 +164,12 @@
 			s.lit = append(s.lit, s.buf[s.suf:s.r0]...)
 			s.suf = 1 // == s.r0 after slide below
 		}
-		s.offs += s.r0 - 1
-		r := s.r - s.r0 + 1 // last read char plus one byte
-		s.w = r + copy(s.buf[r:], s.buf[s.r:s.w])
-		s.r = r
-		s.r0 = 1
+		n := s.r0 - 1
+		copy(s.buf[:], s.buf[n:s.w])
+		s.offs += n
+		s.r0 = 1 // eqv: s.r0 -= n
+		s.r -= n
+		s.w -= n
 	}
 
 	// read more data: try a limited number of times
diff --git a/src/cmd/compile/internal/syntax/syntax.go b/src/cmd/compile/internal/syntax/syntax.go
index ed5e254..f58d5ef 100644
--- a/src/cmd/compile/internal/syntax/syntax.go
+++ b/src/cmd/compile/internal/syntax/syntax.go
@@ -39,11 +39,15 @@
 // appropriate.
 type Pragma uint16
 
-// A PragmaHandler is used to process //line and //go: directives as
+// A PragmaHandler is used to process //go: directives as
 // they're scanned. The returned Pragma value will be unioned into the
 // next FuncDecl node.
 type PragmaHandler func(pos src.Pos, text string) Pragma
 
+// A FilenameHandler is used to process each filename encountered
+// in //line directives. The returned value is used as the absolute filename.
+type FilenameHandler func(name string) string
+
 // Parse parses a single Go source file from src and returns the corresponding
 // syntax tree. If there are errors, Parse will return the first error found,
 // and a possibly partially constructed syntax tree, or nil if no correct package
@@ -55,8 +59,11 @@
 //
 // If a PragmaHandler is provided, it is called with each pragma encountered.
 //
+// If a FilenameHandler is provided, it is called to process each filename
+// encountered in //line directives.
+//
 // The Mode argument is currently ignored.
-func Parse(base *src.PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) {
+func Parse(base *src.PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, fileh FilenameHandler, mode Mode) (_ *File, first error) {
 	defer func() {
 		if p := recover(); p != nil {
 			if err, ok := p.(Error); ok {
@@ -68,14 +75,14 @@
 	}()
 
 	var p parser
-	p.init(base, src, errh, pragh, mode)
+	p.init(base, src, errh, pragh, fileh, mode)
 	p.next()
 	return p.fileOrNil(), p.first
 }
 
 // ParseBytes behaves like Parse but it reads the source from the []byte slice provided.
-func ParseBytes(base *src.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
-	return Parse(base, &bytesReader{src}, errh, pragh, mode)
+func ParseBytes(base *src.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, fileh FilenameHandler, mode Mode) (*File, error) {
+	return Parse(base, &bytesReader{src}, errh, pragh, fileh, mode)
 }
 
 type bytesReader struct {
@@ -101,5 +108,5 @@
 		return nil, err
 	}
 	defer f.Close()
-	return Parse(src.NewFileBase(filename, filename), f, errh, pragh, mode)
+	return Parse(src.NewFileBase(filename, filename), f, errh, pragh, nil, mode)
 }
diff --git a/src/cmd/compile/internal/syntax/tokens.go b/src/cmd/compile/internal/syntax/tokens.go
index bd0118a..e49a027 100644
--- a/src/cmd/compile/internal/syntax/tokens.go
+++ b/src/cmd/compile/internal/syntax/tokens.go
@@ -25,7 +25,7 @@
 	_Arrow
 	_Star
 
-	// delimitors
+	// delimiters
 	_Lparen
 	_Lbrack
 	_Lbrace
@@ -97,7 +97,7 @@
 	_Arrow:    "<-",
 	_Star:     "*",
 
-	// delimitors
+	// delimiters
 	_Lparen:    "(",
 	_Lbrack:    "[",
 	_Lbrace:    "{",
diff --git a/src/cmd/compile/internal/types/etype_string.go b/src/cmd/compile/internal/types/etype_string.go
new file mode 100644
index 0000000..acb1011
--- /dev/null
+++ b/src/cmd/compile/internal/types/etype_string.go
@@ -0,0 +1,16 @@
+// Code generated by "stringer -type EType -trimprefix T"; DO NOT EDIT.
+
+package types
+
+import "fmt"
+
+const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTR32PTR64FUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSDDDFIELDSSATUPLENTYPE"
+
+var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 101, 106, 110, 115, 120, 126, 130, 133, 138, 142, 145, 151, 160, 165, 168, 173, 181, 189, 197, 200, 205, 210}
+
+func (i EType) String() string {
+	if i >= EType(len(_EType_index)-1) {
+		return fmt.Sprintf("EType(%d)", i)
+	}
+	return _EType_name[_EType_index[i]:_EType_index[i+1]]
+}
diff --git a/src/cmd/compile/internal/types/scope.go b/src/cmd/compile/internal/types/scope.go
index 072b808..aef3b3b 100644
--- a/src/cmd/compile/internal/types/scope.go
+++ b/src/cmd/compile/internal/types/scope.go
@@ -4,65 +4,74 @@
 
 package types
 
+import "cmd/internal/src"
+
 // Declaration stack & operations
 
 var blockgen int32 = 1 // max block number
 var Block int32        // current block number
 
+// A dsym stores a symbol's shadowed declaration so that it can be
+// restored once the block scope ends.
+type dsym struct {
+	sym        *Sym // sym == nil indicates stack mark
+	def        *Node
+	block      int32
+	lastlineno src.XPos // last declaration for diagnostic
+}
+
 // dclstack maintains a stack of shadowed symbol declarations so that
 // Popdcl can restore their declarations when a block scope ends.
-//
-// The Syms on this stack are not "real" Syms as they don't actually
-// represent object names. Sym is just a convenient type for saving shadowed
-// Sym definitions, and only a subset of its fields are actually used.
-var dclstack []*Sym
-
-func dcopy(a, b *Sym) {
-	a.Pkg = b.Pkg
-	a.Name = b.Name
-	a.Def = b.Def
-	a.Block = b.Block
-	a.Lastlineno = b.Lastlineno
-}
-
-func push() *Sym {
-	d := new(Sym)
-	dclstack = append(dclstack, d)
-	return d
-}
+var dclstack []dsym
 
 // Pushdcl pushes the current declaration for symbol s (if any) so that
 // it can be shadowed by a new declaration within a nested block scope.
 func Pushdcl(s *Sym) {
-	dcopy(push(), s)
+	dclstack = append(dclstack, dsym{
+		sym:        s,
+		def:        s.Def,
+		block:      s.Block,
+		lastlineno: s.Lastlineno,
+	})
 }
 
 // Popdcl pops the innermost block scope and restores all symbol declarations
 // to their previous state.
 func Popdcl() {
 	for i := len(dclstack); i > 0; i-- {
-		d := dclstack[i-1]
-		if d.Name == "" {
+		d := &dclstack[i-1]
+		s := d.sym
+		if s == nil {
 			// pop stack mark
-			Block = d.Block
+			Block = d.block
 			dclstack = dclstack[:i-1]
 			return
 		}
-		dcopy(d.Pkg.Lookup(d.Name), d)
+
+		s.Def = d.def
+		s.Block = d.block
+		s.Lastlineno = d.lastlineno
+
+		// Clear dead pointer fields.
+		d.sym = nil
+		d.def = nil
 	}
 	Fatalf("popdcl: no stack mark")
 }
 
 // Markdcl records the start of a new block scope for declarations.
 func Markdcl() {
-	push().Block = Block // stack mark (Name == "")
+	dclstack = append(dclstack, dsym{
+		sym:   nil, // stack mark
+		block: Block,
+	})
 	blockgen++
 	Block = blockgen
 }
 
 func IsDclstackValid() bool {
 	for _, d := range dclstack {
-		if d.Name == "" {
+		if d.sym == nil {
 			return false
 		}
 	}
diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go
index f79b07b..1b9d01d 100644
--- a/src/cmd/compile/internal/types/sym.go
+++ b/src/cmd/compile/internal/types/sym.go
@@ -21,9 +21,10 @@
 	Importdef *Pkg   // where imported definition was found
 	Linkname  string // link name
 
+	Pkg  *Pkg
+	Name string // object name
+
 	// saved and restored by dcopy
-	Pkg        *Pkg
-	Name       string   // object name
 	Def        *Node    // definition: ONAME OTYPE OPACK or OLITERAL
 	Block      int32    // blocknumber to catch redeclaration
 	Lastlineno src.XPos // last declaration for diagnostic
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 5c44e62..e62d324 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -15,11 +15,13 @@
 // TODO(gri) try to eliminate soon
 type Node struct{ _ int }
 
+//go:generate stringer -type EType -trimprefix T
+
 // EType describes a kind of type.
 type EType uint8
 
 const (
-	Txxx = iota
+	Txxx EType = iota
 
 	TINT8
 	TUINT8
@@ -162,22 +164,19 @@
 }
 
 const (
-	typeLocal     = 1 << iota // created in this file
-	typeNotInHeap             // type cannot be heap allocated
+	typeNotInHeap = 1 << iota // type cannot be heap allocated
 	typeBroke                 // broken type definition
 	typeNoalg                 // suppress hash and eq algorithm generation
 	typeDeferwidth
 	typeRecur
 )
 
-func (t *Type) Local() bool      { return t.flags&typeLocal != 0 }
 func (t *Type) NotInHeap() bool  { return t.flags&typeNotInHeap != 0 }
 func (t *Type) Broke() bool      { return t.flags&typeBroke != 0 }
 func (t *Type) Noalg() bool      { return t.flags&typeNoalg != 0 }
 func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
 func (t *Type) Recur() bool      { return t.flags&typeRecur != 0 }
 
-func (t *Type) SetLocal(b bool)      { t.flags.set(typeLocal, b) }
 func (t *Type) SetNotInHeap(b bool)  { t.flags.set(typeNotInHeap, b) }
 func (t *Type) SetBroke(b bool)      { t.flags.set(typeBroke, b) }
 func (t *Type) SetNoalg(b bool)      { t.flags.set(typeNoalg, b) }
@@ -585,28 +584,28 @@
 	case TPTR32, TPTR64:
 		elem := SubstAny(t.Elem(), types)
 		if elem != t.Elem() {
-			t = t.Copy()
+			t = t.copy()
 			t.Extra = Ptr{Elem: elem}
 		}
 
 	case TARRAY:
 		elem := SubstAny(t.Elem(), types)
 		if elem != t.Elem() {
-			t = t.Copy()
+			t = t.copy()
 			t.Extra.(*Array).Elem = elem
 		}
 
 	case TSLICE:
 		elem := SubstAny(t.Elem(), types)
 		if elem != t.Elem() {
-			t = t.Copy()
+			t = t.copy()
 			t.Extra = Slice{Elem: elem}
 		}
 
 	case TCHAN:
 		elem := SubstAny(t.Elem(), types)
 		if elem != t.Elem() {
-			t = t.Copy()
+			t = t.copy()
 			t.Extra.(*Chan).Elem = elem
 		}
 
@@ -614,7 +613,7 @@
 		key := SubstAny(t.Key(), types)
 		val := SubstAny(t.Val(), types)
 		if key != t.Key() || val != t.Val() {
-			t = t.Copy()
+			t = t.copy()
 			t.Extra.(*Map).Key = key
 			t.Extra.(*Map).Val = val
 		}
@@ -624,7 +623,7 @@
 		params := SubstAny(t.Params(), types)
 		results := SubstAny(t.Results(), types)
 		if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
-			t = t.Copy()
+			t = t.copy()
 			t.FuncType().Receiver = recvs
 			t.FuncType().Results = results
 			t.FuncType().Params = params
@@ -645,7 +644,7 @@
 			nfs[i].Type = nft
 		}
 		if nfs != nil {
-			t = t.Copy()
+			t = t.copy()
 			t.SetFields(nfs)
 		}
 	}
@@ -653,8 +652,8 @@
 	return t
 }
 
-// Copy returns a shallow copy of the Type.
-func (t *Type) Copy() *Type {
+// copy returns a shallow copy of the Type.
+func (t *Type) copy() *Type {
 	if t == nil {
 		return nil
 	}
@@ -707,6 +706,10 @@
 func (t *Type) Params() *Type  { return t.FuncType().Params }
 func (t *Type) Results() *Type { return t.FuncType().Results }
 
+func (t *Type) NumRecvs() int   { return t.FuncType().Receiver.NumFields() }
+func (t *Type) NumParams() int  { return t.FuncType().Params.NumFields() }
+func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
+
 // Recv returns the receiver of function type t, if any.
 func (t *Type) Recv() *Field {
 	s := t.Recvs()
@@ -1317,6 +1320,23 @@
 	at.Bound = n
 }
 
+func (t *Type) NumComponents() int64 {
+	switch t.Etype {
+	case TSTRUCT:
+		if t.IsFuncArgStruct() {
+			Fatalf("NumComponents func arg struct")
+		}
+		var n int64
+		for _, f := range t.FieldSlice() {
+			n += f.Type.NumComponents()
+		}
+		return n
+	case TARRAY:
+		return t.NumElem() * t.Elem().NumComponents()
+	}
+	return 1
+}
+
 // ChanDir returns the direction of a channel type t.
 // The direction will be one of Crecv, Csend, or Cboth.
 func (t *Type) ChanDir() ChanDir {
@@ -1346,7 +1366,14 @@
 	return false
 }
 
+// TODO(austin): We probably only need HasHeapPointer. See
+// golang.org/cl/73412 for discussion.
+
 func Haspointers(t *Type) bool {
+	return Haspointers1(t, false)
+}
+
+func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
 	switch t.Etype {
 	case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
 		TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL:
@@ -1356,28 +1383,28 @@
 		if t.NumElem() == 0 { // empty array has no pointers
 			return false
 		}
-		return Haspointers(t.Elem())
+		return Haspointers1(t.Elem(), ignoreNotInHeap)
 
 	case TSTRUCT:
 		for _, t1 := range t.Fields().Slice() {
-			if Haspointers(t1.Type) {
+			if Haspointers1(t1.Type, ignoreNotInHeap) {
 				return true
 			}
 		}
 		return false
+
+	case TPTR32, TPTR64, TSLICE:
+		return !(ignoreNotInHeap && t.Elem().NotInHeap())
 	}
 
 	return true
 }
 
-// HasPointer returns whether t contains heap pointer.
-// This is used for write barrier insertion, so we ignore
+// HasHeapPointer returns whether t contains a heap pointer.
+// This is used for write barrier insertion, so it ignores
 // pointers to go:notinheap types.
-func (t *Type) HasPointer() bool {
-	if t.IsPtr() && t.Elem().NotInHeap() {
-		return false
-	}
-	return Haspointers(t)
+func (t *Type) HasHeapPointer() bool {
+	return Haspointers1(t, true)
 }
 
 func (t *Type) Symbol() *obj.LSym {
@@ -1408,9 +1435,9 @@
 }
 
 var (
-	TypeInvalid *Type = newSSA("invalid")
-	TypeMem     *Type = newSSA("mem")
-	TypeFlags   *Type = newSSA("flags")
-	TypeVoid    *Type = newSSA("void")
-	TypeInt128  *Type = newSSA("int128")
+	TypeInvalid = newSSA("invalid")
+	TypeMem     = newSSA("mem")
+	TypeFlags   = newSSA("flags")
+	TypeVoid    = newSSA("void")
+	TypeInt128  = newSSA("int128")
 )
diff --git a/src/cmd/compile/internal/types/utils.go b/src/cmd/compile/internal/types/utils.go
index 796cd44..0eac402 100644
--- a/src/cmd/compile/internal/types/utils.go
+++ b/src/cmd/compile/internal/types/utils.go
@@ -76,51 +76,3 @@
 		*(*uint8)(f) &^= mask
 	}
 }
-
-var etnames = []string{
-	Txxx:        "Txxx",
-	TINT:        "INT",
-	TUINT:       "UINT",
-	TINT8:       "INT8",
-	TUINT8:      "UINT8",
-	TINT16:      "INT16",
-	TUINT16:     "UINT16",
-	TINT32:      "INT32",
-	TUINT32:     "UINT32",
-	TINT64:      "INT64",
-	TUINT64:     "UINT64",
-	TUINTPTR:    "UINTPTR",
-	TFLOAT32:    "FLOAT32",
-	TFLOAT64:    "FLOAT64",
-	TCOMPLEX64:  "COMPLEX64",
-	TCOMPLEX128: "COMPLEX128",
-	TBOOL:       "BOOL",
-	TPTR32:      "PTR32",
-	TPTR64:      "PTR64",
-	TFUNC:       "FUNC",
-	TARRAY:      "ARRAY",
-	TSLICE:      "SLICE",
-	TSTRUCT:     "STRUCT",
-	TCHAN:       "CHAN",
-	TMAP:        "MAP",
-	TINTER:      "INTER",
-	TFORW:       "FORW",
-	TSTRING:     "STRING",
-	TUNSAFEPTR:  "TUNSAFEPTR",
-	TANY:        "ANY",
-	TIDEAL:      "TIDEAL",
-	TNIL:        "TNIL",
-	TBLANK:      "TBLANK",
-	TFUNCARGS:   "TFUNCARGS",
-	TCHANARGS:   "TCHANARGS",
-	TDDDFIELD:   "TDDDFIELD",
-	TSSA:        "TSSA",
-	TTUPLE:      "TTUPLE",
-}
-
-func (et EType) String() string {
-	if int(et) < len(etnames) && etnames[et] != "" {
-		return etnames[et]
-	}
-	return fmt.Sprintf("E-%d", et)
-}
diff --git a/src/cmd/compile/internal/x86/387.go b/src/cmd/compile/internal/x86/387.go
index cdac000..7a36224 100644
--- a/src/cmd/compile/internal/x86/387.go
+++ b/src/cmd/compile/internal/x86/387.go
@@ -46,6 +46,9 @@
 		case ssa.Op386MOVSSloadidx1, ssa.Op386MOVSDloadidx1:
 			p.From.Scale = 1
 			p.From.Index = v.Args[1].Reg()
+			if p.From.Index == x86.REG_SP {
+				p.From.Reg, p.From.Index = p.From.Index, p.From.Reg
+			}
 		case ssa.Op386MOVSSloadidx4:
 			p.From.Scale = 4
 			p.From.Index = v.Args[1].Reg()
@@ -95,6 +98,9 @@
 		case ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSDstoreidx1:
 			p.To.Scale = 1
 			p.To.Index = v.Args[1].Reg()
+			if p.To.Index == x86.REG_SP {
+				p.To.Reg, p.To.Index = p.To.Index, p.To.Reg
+			}
 		case ssa.Op386MOVSSstoreidx4:
 			p.To.Scale = 4
 			p.To.Index = v.Args[1].Reg()
diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go
index 54a76bd..69217f2 100644
--- a/src/cmd/compile/internal/x86/ssa.go
+++ b/src/cmd/compile/internal/x86/ssa.go
@@ -426,16 +426,23 @@
 		p.To.Reg = v.Args[0].Reg()
 	case ssa.Op386MOVLconst:
 		x := v.Reg()
+
+		// If flags aren't live (indicated by v.Aux == nil),
+		// then we can rewrite MOV $0, AX into XOR AX, AX.
+		if v.AuxInt == 0 && v.Aux == nil {
+			p := s.Prog(x86.AXORL)
+			p.From.Type = obj.TYPE_REG
+			p.From.Reg = x
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = x
+			break
+		}
+
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = x
-		// If flags are live at this instruction, suppress the
-		// MOV $0,AX -> XOR AX,AX optimization.
-		if v.Aux != nil {
-			p.Mark |= x86.PRESERVEFLAGS
-		}
 	case ssa.Op386MOVSSconst, ssa.Op386MOVSDconst:
 		x := v.Reg()
 		p := s.Prog(v.Op.Asm())
@@ -604,7 +611,11 @@
 		p.To.Sym = gc.Duffcopy
 		p.To.Offset = v.AuxInt
 
-	case ssa.OpCopy, ssa.Op386MOVLconvert: // TODO: use MOVLreg for reg->reg copies instead of OpCopy?
+	case ssa.Op386MOVLconvert:
+		if v.Args[0].Reg() != v.Reg() {
+			v.Fatalf("MOVLconvert should be a no-op")
+		}
+	case ssa.OpCopy: // TODO: use MOVLreg for reg->reg copies instead of OpCopy?
 		if v.Type.IsMemory() {
 			return
 		}
@@ -662,6 +673,24 @@
 			q.To.Type = obj.TYPE_REG
 			q.To.Reg = r
 		}
+
+	case ssa.Op386LoweredGetCallerPC:
+		p := s.Prog(x86.AMOVL)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Offset = -4 // PC is stored 4 bytes below first parameter.
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+
+	case ssa.Op386LoweredGetCallerSP:
+		// caller's SP is the address of the first arg
+		p := s.Prog(x86.AMOVL)
+		p.From.Type = obj.TYPE_ADDR
+		p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on 386, just to be consistent with other architectures
+		p.From.Name = obj.NAME_PARAM
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+
 	case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
 		s.Call(v)
 	case ssa.Op386NEGL,
@@ -724,7 +753,7 @@
 	case ssa.Op386LoweredNilCheck:
 		// Issue a load which will fault if the input is nil.
 		// TODO: We currently use the 2-byte instruction TESTB AX, (reg).
-		// Should we use the 3-byte TESTB $0, (reg) instead?  It is larger
+		// Should we use the 3-byte TESTB $0, (reg) instead? It is larger
 		// but it doesn't have false dependency on AX.
 		// Or maybe allocate an output register and use MOVL (reg),reg2 ?
 		// That trades clobbering flags for clobbering a register.
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index ee14070..500027e 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -10,16 +10,16 @@
 	"fmt"
 	"go/ast"
 	"go/parser"
-	"go/printer"
 	"go/token"
 	"io"
 	"io/ioutil"
 	"log"
 	"os"
-	"path/filepath"
 	"sort"
 	"strconv"
-	"strings"
+
+	"cmd/internal/edit"
+	"cmd/internal/objabi"
 )
 
 const usageMessage = "" +
@@ -59,7 +59,7 @@
 
 var profile string // The profile to read; the value of -html or -func
 
-var counterStmt func(*File, ast.Expr) ast.Stmt
+var counterStmt func(*File, string) string
 
 const (
 	atomicPackagePath = "sync/atomic"
@@ -67,6 +67,7 @@
 )
 
 func main() {
+	objabi.AddVersionFlag()
 	flag.Usage = usage
 	flag.Parse()
 
@@ -151,12 +152,48 @@
 // File is a wrapper for the state of a file used in the parser.
 // The basic parse tree walker is a method of this type.
 type File struct {
-	fset       *token.FileSet
-	name       string // Name of file.
-	astFile    *ast.File
-	blocks     []Block
-	atomicPkg  string                // Package name for "sync/atomic" in this file.
-	directives map[*ast.Comment]bool // Map of compiler directives to whether it's processed in ast.Visitor or not.
+	fset    *token.FileSet
+	name    string // Name of file.
+	astFile *ast.File
+	blocks  []Block
+	content []byte
+	edit    *edit.Buffer
+}
+
+// findText finds text in the original source, starting at pos.
+// It correctly skips over comments and assumes it need not
+// handle quoted strings.
+// It returns a byte offset within f.src.
+func (f *File) findText(pos token.Pos, text string) int {
+	b := []byte(text)
+	start := f.offset(pos)
+	i := start
+	s := f.content
+	for i < len(s) {
+		if bytes.HasPrefix(s[i:], b) {
+			return i
+		}
+		if i+2 <= len(s) && s[i] == '/' && s[i+1] == '/' {
+			for i < len(s) && s[i] != '\n' {
+				i++
+			}
+			continue
+		}
+		if i+2 <= len(s) && s[i] == '/' && s[i+1] == '*' {
+			for i += 2; ; i++ {
+				if i+2 > len(s) {
+					return 0
+				}
+				if s[i] == '*' && s[i+1] == '/' {
+					i += 2
+					break
+				}
+			}
+			continue
+		}
+		i++
+	}
+	return -1
 }
 
 // Visit implements the ast.Visitor interface.
@@ -169,18 +206,18 @@
 			case *ast.CaseClause: // switch
 				for _, n := range n.List {
 					clause := n.(*ast.CaseClause)
-					clause.Body = f.addCounters(clause.Colon+1, clause.End(), clause.Body, false)
+					f.addCounters(clause.Colon+1, clause.Colon+1, clause.End(), clause.Body, false)
 				}
 				return f
 			case *ast.CommClause: // select
 				for _, n := range n.List {
 					clause := n.(*ast.CommClause)
-					clause.Body = f.addCounters(clause.Colon+1, clause.End(), clause.Body, false)
+					f.addCounters(clause.Colon+1, clause.Colon+1, clause.End(), clause.Body, false)
 				}
 				return f
 			}
 		}
-		n.List = f.addCounters(n.Lbrace, n.Rbrace+1, n.List, true) // +1 to step past closing brace.
+		f.addCounters(n.Lbrace, n.Lbrace+1, n.Rbrace+1, n.List, true) // +1 to step past closing brace.
 	case *ast.IfStmt:
 		if n.Init != nil {
 			ast.Walk(f, n.Init)
@@ -201,6 +238,13 @@
 		//		if y {
 		//		}
 		//	}
+		f.edit.Insert(f.offset(n.Body.End()), "else{")
+		elseOffset := f.findText(n.Body.End(), "else")
+		if elseOffset < 0 {
+			panic("lost else")
+		}
+		f.edit.Delete(elseOffset, elseOffset+4)
+		f.edit.Insert(f.offset(n.Else.End()), "}")
 		switch stmt := n.Else.(type) {
 		case *ast.IfStmt:
 			block := &ast.BlockStmt{
@@ -241,21 +285,6 @@
 			ast.Walk(f, n.Assign)
 			return nil
 		}
-	case *ast.CommentGroup:
-		var list []*ast.Comment
-		// Drop all but the //go: comments, some of which are semantically important.
-		// We drop all others because they can appear in places that cause our counters
-		// to appear in syntactically incorrect places. //go: appears at the beginning of
-		// the line and is syntactically safe.
-		for _, c := range n.List {
-			if f.isDirective(c) {
-				list = append(list, c)
-
-				// Mark compiler directive as handled.
-				f.directives[c] = true
-			}
-		}
-		n.List = list
 	}
 	return f
 }
@@ -269,91 +298,8 @@
 	return t
 }
 
-// addImport adds an import for the specified path, if one does not already exist, and returns
-// the local package name.
-func (f *File) addImport(path string) string {
-	// Does the package already import it?
-	for _, s := range f.astFile.Imports {
-		if unquote(s.Path.Value) == path {
-			if s.Name != nil {
-				return s.Name.Name
-			}
-			return filepath.Base(path)
-		}
-	}
-	newImport := &ast.ImportSpec{
-		Name: ast.NewIdent(atomicPackageName),
-		Path: &ast.BasicLit{
-			Kind:  token.STRING,
-			Value: fmt.Sprintf("%q", path),
-		},
-	}
-	impDecl := &ast.GenDecl{
-		Tok: token.IMPORT,
-		Specs: []ast.Spec{
-			newImport,
-		},
-	}
-	// Make the new import the first Decl in the file.
-	astFile := f.astFile
-	astFile.Decls = append(astFile.Decls, nil)
-	copy(astFile.Decls[1:], astFile.Decls[0:])
-	astFile.Decls[0] = impDecl
-	astFile.Imports = append(astFile.Imports, newImport)
-
-	// Now refer to the package, just in case it ends up unused.
-	// That is, append to the end of the file the declaration
-	//	var _ = _cover_atomic_.AddUint32
-	reference := &ast.GenDecl{
-		Tok: token.VAR,
-		Specs: []ast.Spec{
-			&ast.ValueSpec{
-				Names: []*ast.Ident{
-					ast.NewIdent("_"),
-				},
-				Values: []ast.Expr{
-					&ast.SelectorExpr{
-						X:   ast.NewIdent(atomicPackageName),
-						Sel: ast.NewIdent("AddUint32"),
-					},
-				},
-			},
-		},
-	}
-	astFile.Decls = append(astFile.Decls, reference)
-	return atomicPackageName
-}
-
 var slashslash = []byte("//")
 
-// initialComments returns the prefix of content containing only
-// whitespace and line comments. Any +build directives must appear
-// within this region. This approach is more reliable than using
-// go/printer to print a modified AST containing comments.
-//
-func initialComments(content []byte) []byte {
-	// Derived from go/build.Context.shouldBuild.
-	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
-		}
-	}
-	return content[:end]
-}
-
 func annotate(name string) {
 	fset := token.NewFileSet()
 	content, err := ioutil.ReadFile(name)
@@ -366,26 +312,25 @@
 	}
 
 	file := &File{
-		fset:       fset,
-		name:       name,
-		astFile:    parsedFile,
-		directives: map[*ast.Comment]bool{},
+		fset:    fset,
+		name:    name,
+		content: content,
+		edit:    edit.NewBuffer(content),
+		astFile: parsedFile,
 	}
 	if *mode == "atomic" {
-		file.atomicPkg = file.addImport(atomicPackagePath)
+		// Add import of sync/atomic immediately after package clause.
+		// We do this even if there is an existing import, because the
+		// existing import may be shadowed at any given place we want
+		// to refer to it, and our name (_cover_atomic_) is less likely to
+		// be shadowed.
+		file.edit.Insert(file.offset(file.astFile.Name.End()),
+			fmt.Sprintf("; import %s %q", atomicPackageName, atomicPackagePath))
 	}
 
-	for _, cg := range parsedFile.Comments {
-		for _, c := range cg.List {
-			if file.isDirective(c) {
-				file.directives[c] = false
-			}
-		}
-	}
-	// Remove comments. Or else they interfere with new AST.
-	parsedFile.Comments = nil
-
 	ast.Walk(file, file.astFile)
+	newContent := file.edit.Bytes()
+
 	fd := os.Stdout
 	if *output != "" {
 		var err error
@@ -394,92 +339,33 @@
 			log.Fatalf("cover: %s", err)
 		}
 	}
-	fd.Write(initialComments(content)) // Retain '// +build' directives.
 
-	// Retain compiler directives that are not processed in ast.Visitor.
-	// Some compiler directives like "go:linkname" and "go:cgo_"
-	// can be not attached to anything in the tree and hence will not be printed by printer.
-	// So, we have to explicitly print them here.
-	for cd, handled := range file.directives {
-		if !handled {
-			fmt.Fprintln(fd, cd.Text)
-		}
-	}
+	fmt.Fprintf(fd, "//line %s:1\n", name)
+	fd.Write(newContent)
 
-	file.print(fd)
 	// After printing the source tree, add some declarations for the counters etc.
 	// We could do this by adding to the tree, but it's easier just to print the text.
 	file.addVariables(fd)
 }
 
-func (f *File) print(w io.Writer) {
-	printer.Fprint(w, f.fset, f.astFile)
-}
-
-// isDirective reports whether a comment is a compiler directive.
-func (f *File) isDirective(c *ast.Comment) bool {
-	return strings.HasPrefix(c.Text, "//go:") && f.fset.Position(c.Slash).Column == 1
-}
-
-// intLiteral returns an ast.BasicLit representing the integer value.
-func (f *File) intLiteral(i int) *ast.BasicLit {
-	node := &ast.BasicLit{
-		Kind:  token.INT,
-		Value: fmt.Sprint(i),
-	}
-	return node
-}
-
-// index returns an ast.BasicLit representing the number of counters present.
-func (f *File) index() *ast.BasicLit {
-	return f.intLiteral(len(f.blocks))
-}
-
 // setCounterStmt returns the expression: __count[23] = 1.
-func setCounterStmt(f *File, counter ast.Expr) ast.Stmt {
-	return &ast.AssignStmt{
-		Lhs: []ast.Expr{counter},
-		Tok: token.ASSIGN,
-		Rhs: []ast.Expr{f.intLiteral(1)},
-	}
+func setCounterStmt(f *File, counter string) string {
+	return fmt.Sprintf("%s = 1", counter)
 }
 
 // incCounterStmt returns the expression: __count[23]++.
-func incCounterStmt(f *File, counter ast.Expr) ast.Stmt {
-	return &ast.IncDecStmt{
-		X:   counter,
-		Tok: token.INC,
-	}
+func incCounterStmt(f *File, counter string) string {
+	return fmt.Sprintf("%s++", counter)
 }
 
 // atomicCounterStmt returns the expression: atomic.AddUint32(&__count[23], 1)
-func atomicCounterStmt(f *File, counter ast.Expr) ast.Stmt {
-	return &ast.ExprStmt{
-		X: &ast.CallExpr{
-			Fun: &ast.SelectorExpr{
-				X:   ast.NewIdent(f.atomicPkg),
-				Sel: ast.NewIdent("AddUint32"),
-			},
-			Args: []ast.Expr{&ast.UnaryExpr{
-				Op: token.AND,
-				X:  counter,
-			},
-				f.intLiteral(1),
-			},
-		},
-	}
+func atomicCounterStmt(f *File, counter string) string {
+	return fmt.Sprintf("%s.AddUint32(&%s, 1)", atomicPackageName, counter)
 }
 
 // newCounter creates a new counter expression of the appropriate form.
-func (f *File) newCounter(start, end token.Pos, numStmt int) ast.Stmt {
-	counter := &ast.IndexExpr{
-		X: &ast.SelectorExpr{
-			X:   ast.NewIdent(*varVar),
-			Sel: ast.NewIdent("Count"),
-		},
-		Index: f.index(),
-	}
-	stmt := counterStmt(f, counter)
+func (f *File) newCounter(start, end token.Pos, numStmt int) string {
+	stmt := counterStmt(f, fmt.Sprintf("%s.Count[%d]", *varVar, len(f.blocks)))
 	f.blocks = append(f.blocks, Block{start, end, numStmt})
 	return stmt
 }
@@ -496,15 +382,15 @@
 // counters will be added before S1 and before S3. The block containing S2
 // will be visited in a separate call.
 // TODO: Nested simple blocks get unnecessary (but correct) counters
-func (f *File) addCounters(pos, blockEnd token.Pos, list []ast.Stmt, extendToClosingBrace bool) []ast.Stmt {
+func (f *File) addCounters(pos, insertPos, blockEnd token.Pos, list []ast.Stmt, extendToClosingBrace bool) {
 	// Special case: make sure we add a counter to an empty block. Can't do this below
 	// or we will add a counter to an empty statement list after, say, a return statement.
 	if len(list) == 0 {
-		return []ast.Stmt{f.newCounter(pos, blockEnd, 0)}
+		f.edit.Insert(f.offset(insertPos), f.newCounter(insertPos, blockEnd, 0)+";")
+		return
 	}
 	// We have a block (statement list), but it may have several basic blocks due to the
 	// appearance of statements that affect the flow of control.
-	var newList []ast.Stmt
 	for {
 		// Find first statement that affects flow of control (break, continue, if, etc.).
 		// It will be the last statement of this basic block.
@@ -547,16 +433,15 @@
 			end = blockEnd
 		}
 		if pos != end { // Can have no source to cover if e.g. blocks abut.
-			newList = append(newList, f.newCounter(pos, end, last))
+			f.edit.Insert(f.offset(insertPos), f.newCounter(pos, end, last)+";")
 		}
-		newList = append(newList, list[0:last]...)
 		list = list[last:]
 		if len(list) == 0 {
 			break
 		}
 		pos = list[0].Pos()
+		insertPos = pos
 	}
-	return newList
 }
 
 // hasFuncLiteral reports the existence and position of the first func literal
@@ -791,4 +676,10 @@
 
 	// Close the struct initialization.
 	fmt.Fprintf(w, "}\n")
+
+	// Emit a reference to the atomic package to avoid
+	// import and not used error when there's no code in a file.
+	if *mode == "atomic" {
+		fmt.Fprintf(w, "var _ = %s.LoadUint32\n", atomicPackageName)
+	}
 }
diff --git a/src/cmd/cover/cover_test.go b/src/cmd/cover/cover_test.go
index 1584a73..79ddf4f 100644
--- a/src/cmd/cover/cover_test.go
+++ b/src/cmd/cover/cover_test.go
@@ -6,13 +6,18 @@
 
 import (
 	"bytes"
+	"flag"
 	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
 	"internal/testenv"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"regexp"
+	"strings"
 	"testing"
 )
 
@@ -33,7 +38,7 @@
 	coverProfile = filepath.Join(testdata, "profile.cov")
 )
 
-var debug = false // Keeps the rewritten files around if set.
+var debug = flag.Bool("debug", false, "keep rewritten files for debugging")
 
 // Run this shell script, but do it in Go so it can be run by "go test".
 //
@@ -59,7 +64,7 @@
 	}
 
 	// defer removal of test_line.go
-	if !debug {
+	if !*debug {
 		defer os.Remove(coverInput)
 	}
 
@@ -75,7 +80,7 @@
 	run(cmd, t)
 
 	// defer removal of ./testdata/test_cover.go
-	if !debug {
+	if !*debug {
 		defer os.Remove(coverOutput)
 	}
 
@@ -89,20 +94,138 @@
 	}
 	// compiler directive must appear right next to function declaration.
 	if got, err := regexp.MatchString(".*\n//go:nosplit\nfunc someFunction().*", string(file)); err != nil || !got {
-		t.Errorf("misplaced compiler directive: got=(%v, %v); want=(true; nil)", got, err)
+		t.Error("misplaced compiler directive")
 	}
 	// "go:linkname" compiler directive should be present.
 	if got, err := regexp.MatchString(`.*go\:linkname some\_name some\_name.*`, string(file)); err != nil || !got {
-		t.Errorf("'go:linkname' compiler directive not found: got=(%v, %v); want=(true; nil)", got, err)
+		t.Error("'go:linkname' compiler directive not found")
 	}
 
-	// No other comments should be present in generated code.
-	c := ".*// This comment shouldn't appear in generated go code.*"
-	if got, err := regexp.MatchString(c, string(file)); err != nil || got {
-		t.Errorf("non compiler directive comment %q found. got=(%v, %v); want=(false; nil)", c, got, err)
+	// Other comments should be preserved too.
+	c := ".*// This comment didn't appear in generated go code.*"
+	if got, err := regexp.MatchString(c, string(file)); err != nil || !got {
+		t.Errorf("non compiler directive comment %q not found", c)
 	}
 }
 
+// TestDirectives checks that compiler directives are preserved and positioned
+// correctly. Directives that occur before top-level declarations should remain
+// above those declarations, even if they are not part of the block of
+// documentation comments.
+func TestDirectives(t *testing.T) {
+	// Read the source file and find all the directives. We'll keep
+	// track of whether each one has been seen in the output.
+	testDirectives := filepath.Join(testdata, "directives.go")
+	source, err := ioutil.ReadFile(testDirectives)
+	if err != nil {
+		t.Fatal(err)
+	}
+	sourceDirectives := findDirectives(source)
+
+	// go tool cover -mode=atomic ./testdata/directives.go
+	cmd := exec.Command(testenv.GoToolPath(t), "tool", "cover", "-mode=atomic", testDirectives)
+	cmd.Stderr = os.Stderr
+	output, err := cmd.Output()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Check that all directives are present in the output.
+	outputDirectives := findDirectives(output)
+	foundDirective := make(map[string]bool)
+	for _, p := range sourceDirectives {
+		foundDirective[p.name] = false
+	}
+	for _, p := range outputDirectives {
+		if found, ok := foundDirective[p.name]; !ok {
+			t.Errorf("unexpected directive in output: %s", p.text)
+		} else if found {
+			t.Errorf("directive found multiple times in output: %s", p.text)
+		}
+		foundDirective[p.name] = true
+	}
+	for name, found := range foundDirective {
+		if !found {
+			t.Errorf("missing directive: %s", name)
+		}
+	}
+
+	// Check that directives that start with the name of top-level declarations
+	// come before the beginning of the named declaration and after the end
+	// of the previous declaration.
+	fset := token.NewFileSet()
+	astFile, err := parser.ParseFile(fset, testDirectives, output, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	prevEnd := 0
+	for _, decl := range astFile.Decls {
+		var name string
+		switch d := decl.(type) {
+		case *ast.FuncDecl:
+			name = d.Name.Name
+		case *ast.GenDecl:
+			if len(d.Specs) == 0 {
+				// An empty group declaration. We still want to check that
+				// directives can be associated with it, so we make up a name
+				// to match directives in the test data.
+				name = "_empty"
+			} else if spec, ok := d.Specs[0].(*ast.TypeSpec); ok {
+				name = spec.Name.Name
+			}
+		}
+		pos := fset.Position(decl.Pos()).Offset
+		end := fset.Position(decl.End()).Offset
+		if name == "" {
+			prevEnd = end
+			continue
+		}
+		for _, p := range outputDirectives {
+			if !strings.HasPrefix(p.name, name) {
+				continue
+			}
+			if p.offset < prevEnd || pos < p.offset {
+				t.Errorf("directive %s does not appear before definition %s", p.text, name)
+			}
+		}
+		prevEnd = end
+	}
+}
+
+type directiveInfo struct {
+	text   string // full text of the comment, not including newline
+	name   string // text after //go:
+	offset int    // byte offset of first slash in comment
+}
+
+func findDirectives(source []byte) []directiveInfo {
+	var directives []directiveInfo
+	directivePrefix := []byte("\n//go:")
+	offset := 0
+	for {
+		i := bytes.Index(source[offset:], directivePrefix)
+		if i < 0 {
+			break
+		}
+		i++ // skip newline
+		p := source[offset+i:]
+		j := bytes.IndexByte(p, '\n')
+		if j < 0 {
+			// reached EOF
+			j = len(p)
+		}
+		directive := directiveInfo{
+			text:   string(p[:j]),
+			name:   string(p[len(directivePrefix)-1 : j]),
+			offset: offset + i,
+		}
+		directives = append(directives, directive)
+		offset += i + j
+	}
+	return directives
+}
+
 // Makes sure that `cover -func=profile.cov` reports accurate coverage.
 // Issue #20515.
 func TestCoverFunc(t *testing.T) {
diff --git a/src/cmd/cover/doc.go b/src/cmd/cover/doc.go
index 636d7e0..e2c8494 100644
--- a/src/cmd/cover/doc.go
+++ b/src/cmd/cover/doc.go
@@ -14,6 +14,10 @@
 For instance, it does not probe inside && and || expressions, and can
 be mildly confused by single statements with multiple function literals.
 
+When computing coverage of a package that uses cgo, the cover tool
+must be applied to the output of cgo preprocessing, not the input,
+because cover deletes comments that are significant to cgo.
+
 For usage information, please see:
 	go help testflag
 	go tool cover -help
diff --git a/src/cmd/cover/func.go b/src/cmd/cover/func.go
index 05c7c12..1673fbf 100644
--- a/src/cmd/cover/func.go
+++ b/src/cmd/cover/func.go
@@ -113,6 +113,10 @@
 func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor {
 	switch n := node.(type) {
 	case *ast.FuncDecl:
+		if n.Body == nil {
+			// Do not count declarations of assembly functions.
+			break
+		}
 		start := v.fset.Position(n.Pos())
 		end := v.fset.Position(n.End())
 		fe := &FuncExtent{
diff --git a/src/cmd/cover/testdata/directives.go b/src/cmd/cover/testdata/directives.go
new file mode 100644
index 0000000..dfb7b8e
--- /dev/null
+++ b/src/cmd/cover/testdata/directives.go
@@ -0,0 +1,40 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is processed by the cover command, then a test verifies that
+// all compiler directives are preserved and positioned appropriately.
+
+//go:a
+
+//go:b
+package main
+
+//go:c1
+
+//go:c2
+//doc
+func c() {
+}
+
+//go:d1
+
+//doc
+//go:d2
+type d int
+
+//go:e1
+
+//doc
+//go:e2
+type (
+	e int
+	f int
+)
+
+//go:_empty1
+//doc
+//go:_empty2
+type ()
+
+//go:f
diff --git a/src/cmd/cover/testdata/test.go b/src/cmd/cover/testdata/test.go
index 5effa2d..0b03ef9 100644
--- a/src/cmd/cover/testdata/test.go
+++ b/src/cmd/cover/testdata/test.go
@@ -282,7 +282,7 @@
 	}
 }
 
-// This comment shouldn't appear in generated go code.
+// This comment didn't appear in generated go code.
 func haha() {
 	// Needed for cover to add counter increment here.
 	_ = 42
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 76e42a4..49ed800 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -9,43 +9,46 @@
 	"encoding/json"
 	"flag"
 	"fmt"
+	"log"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"sort"
 	"strings"
 	"sync"
+	"time"
 )
 
 // Initialization for any invocation.
 
 // The usual variables.
 var (
-	goarch                 string
-	gobin                  string
-	gohostarch             string
-	gohostos               string
-	goos                   string
-	goarm                  string
-	go386                  string
-	goroot                 string
-	goroot_final           string
-	goextlinkenabled       string
-	gogcflags              string // For running built compiler
-	workdir                string
-	tooldir                string
-	oldgoos                string
-	oldgoarch              string
-	slash                  string
-	exe                    string
-	defaultcc              string
-	defaultcflags          string
-	defaultldflags         string
-	defaultcxxtarget       string
-	defaultcctarget        string
-	defaultpkgconfigtarget string
-	rebuildall             bool
-	defaultclang           bool
+	goarch           string
+	gobin            string
+	gohostarch       string
+	gohostos         string
+	goos             string
+	goarm            string
+	go386            string
+	gomips           string
+	goroot           string
+	goroot_final     string
+	goextlinkenabled string
+	gogcflags        string // For running built compiler
+	goldflags        string
+	workdir          string
+	tooldir          string
+	oldgoos          string
+	oldgoarch        string
+	exe              string
+	defaultcc        map[string]string
+	defaultcxx       map[string]string
+	defaultcflags    string
+	defaultldflags   string
+	defaultpkgconfig string
+
+	rebuildall   bool
+	defaultclang bool
 
 	vflag int // verbosity
 )
@@ -93,23 +96,21 @@
 
 // xinit handles initialization of the various global state, like goroot and goarch.
 func xinit() {
-	goroot = os.Getenv("GOROOT")
-	if slash == "/" && len(goroot) > 1 || slash == `\` && len(goroot) > 3 {
-		// if not "/" or "c:\", then strip trailing path separator
-		goroot = strings.TrimSuffix(goroot, slash)
-	}
-	if goroot == "" {
-		fatal("$GOROOT must be set")
-	}
-
-	goroot_final = os.Getenv("GOROOT_FINAL")
-	if goroot_final == "" {
-		goroot_final = goroot
-	}
-
-	b := os.Getenv("GOBIN")
+	b := os.Getenv("GOROOT")
 	if b == "" {
-		b = goroot + slash + "bin"
+		fatalf("$GOROOT must be set")
+	}
+	goroot = filepath.Clean(b)
+
+	b = os.Getenv("GOROOT_FINAL")
+	if b == "" {
+		b = goroot
+	}
+	goroot_final = b
+
+	b = os.Getenv("GOBIN")
+	if b == "" {
+		b = pathf("%s/bin", goroot)
 	}
 	gobin = b
 
@@ -119,7 +120,7 @@
 	}
 	goos = b
 	if find(goos, okgoos) < 0 {
-		fatal("unknown $GOOS %s", goos)
+		fatalf("unknown $GOOS %s", goos)
 	}
 
 	b = os.Getenv("GOARM")
@@ -138,9 +139,14 @@
 	}
 	go386 = b
 
-	p := pathf("%s/src/all.bash", goroot)
-	if !isfile(p) {
-		fatal("$GOROOT is not set correctly or not exported\n"+
+	b = os.Getenv("GOMIPS")
+	if b == "" {
+		b = "hardfloat"
+	}
+	gomips = b
+
+	if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
+		fatalf("$GOROOT is not set correctly or not exported\n"+
 			"\tGOROOT=%s\n"+
 			"\t%s does not exist", goroot, p)
 	}
@@ -149,9 +155,8 @@
 	if b != "" {
 		gohostarch = b
 	}
-
 	if find(gohostarch, okgoarch) < 0 {
-		fatal("unknown $GOHOSTARCH %s", gohostarch)
+		fatalf("unknown $GOHOSTARCH %s", gohostarch)
 	}
 
 	b = os.Getenv("GOARCH")
@@ -160,62 +165,34 @@
 	}
 	goarch = b
 	if find(goarch, okgoarch) < 0 {
-		fatal("unknown $GOARCH %s", goarch)
+		fatalf("unknown $GOARCH %s", goarch)
 	}
 
 	b = os.Getenv("GO_EXTLINK_ENABLED")
 	if b != "" {
 		if b != "0" && b != "1" {
-			fatal("unknown $GO_EXTLINK_ENABLED %s", b)
+			fatalf("unknown $GO_EXTLINK_ENABLED %s", b)
 		}
 		goextlinkenabled = b
 	}
 
 	gogcflags = os.Getenv("BOOT_GO_GCFLAGS")
 
-	b = os.Getenv("CC")
-	if b == "" {
-		// Use clang on OS X, because gcc is deprecated there.
-		// Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
-		// actually runs clang. We prepare different command
-		// lines for the two binaries, so it matters what we call it.
-		// See golang.org/issue/5822.
-		if defaultclang {
-			b = "clang"
-		} else {
-			b = "gcc"
-		}
+	cc, cxx := "gcc", "g++"
+	if defaultclang {
+		cc, cxx = "clang", "clang++"
 	}
-	defaultcc = b
+	defaultcc = compilerEnv("CC", cc)
+	defaultcxx = compilerEnv("CXX", cxx)
 
 	defaultcflags = os.Getenv("CFLAGS")
-
 	defaultldflags = os.Getenv("LDFLAGS")
 
-	b = os.Getenv("CC_FOR_TARGET")
-	if b == "" {
-		b = defaultcc
-	}
-	defaultcctarget = b
-
-	b = os.Getenv("CXX_FOR_TARGET")
-	if b == "" {
-		b = os.Getenv("CXX")
-		if b == "" {
-			if defaultclang {
-				b = "clang++"
-			} else {
-				b = "g++"
-			}
-		}
-	}
-	defaultcxxtarget = b
-
 	b = os.Getenv("PKG_CONFIG")
 	if b == "" {
 		b = "pkg-config"
 	}
-	defaultpkgconfigtarget = b
+	defaultpkgconfig = b
 
 	// For tools being invoked but also for os.ExpandEnv.
 	os.Setenv("GO386", go386)
@@ -224,9 +201,18 @@
 	os.Setenv("GOHOSTARCH", gohostarch)
 	os.Setenv("GOHOSTOS", gohostos)
 	os.Setenv("GOOS", goos)
+	os.Setenv("GOMIPS", gomips)
 	os.Setenv("GOROOT", goroot)
 	os.Setenv("GOROOT_FINAL", goroot_final)
 
+	// Use a build cache separate from the default user one.
+	// Also one that will be wiped out during startup, so that
+	// make.bash really does start from a clean slate.
+	// But if the user has specified no caching, don't cache.
+	if os.Getenv("GOCACHE") != "off" {
+		os.Setenv("GOCACHE", pathf("%s/pkg/obj/go-build", goroot))
+	}
+
 	// Make the environment more predictable.
 	os.Setenv("LANG", "C")
 	os.Setenv("LANGUAGE", "en_US.UTF8")
@@ -237,6 +223,55 @@
 	tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
 }
 
+// compilerEnv returns a map from "goos/goarch" to the
+// compiler setting to use for that platform.
+// The entry for key "" covers any goos/goarch not explicitly set in the map.
+// For example, compilerEnv("CC", "gcc") returns the C compiler settings
+// read from $CC, defaulting to gcc.
+//
+// The result is a map because additional environment variables
+// can be set to change the compiler based on goos/goarch settings.
+// The following applies to all envNames but CC is assumed to simplify
+// the presentation.
+//
+// If no environment variables are set, we use def for all goos/goarch.
+// $CC, if set, applies to all goos/goarch but is overridden by the following.
+// $CC_FOR_TARGET, if set, applies to all goos/goarch except gohostos/gohostarch,
+// but is overridden by the following.
+// If gohostos=goos and gohostarch=goarch, then $CC_FOR_TARGET applies even for gohostos/gohostarch.
+// $CC_FOR_goos_goarch, if set, applies only to goos/goarch.
+func compilerEnv(envName, def string) map[string]string {
+	m := map[string]string{"": def}
+
+	if env := os.Getenv(envName); env != "" {
+		m[""] = env
+	}
+	if env := os.Getenv(envName + "_FOR_TARGET"); env != "" {
+		if gohostos != goos || gohostarch != goarch {
+			m[gohostos+"/"+gohostarch] = m[""]
+		}
+		m[""] = env
+	}
+
+	for _, goos := range okgoos {
+		for _, goarch := range okgoarch {
+			if env := os.Getenv(envName + "_FOR_" + goos + "_" + goarch); env != "" {
+				m[goos+"/"+goarch] = env
+			}
+		}
+	}
+
+	return m
+}
+
+// compilerEnvLookup returns the compiler settings for goos/goarch in map m.
+func compilerEnvLookup(m map[string]string, goos, goarch string) string {
+	if cc := m[goos+"/"+goarch]; cc != "" {
+		return cc
+	}
+	return m[""]
+}
+
 // rmworkdir deletes the work directory.
 func rmworkdir() {
 	if vflag > 1 {
@@ -251,27 +286,26 @@
 }
 
 func branchtag(branch string) (tag string, precise bool) {
-	b := run(goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", "master.."+branch)
+	log := run(goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", "master.."+branch)
 	tag = branch
-	for _, line := range splitlines(b) {
+	for row, line := range strings.Split(log, "\n") {
 		// Each line is either blank, or looks like
 		//	  (tag: refs/tags/go1.4rc2, refs/remotes/origin/release-branch.go1.4, refs/heads/release-branch.go1.4)
 		// We need to find an element starting with refs/tags/.
-		i := strings.Index(line, " refs/tags/")
+		const s = " refs/tags/"
+		i := strings.Index(line, s)
 		if i < 0 {
 			continue
 		}
-		i += len(" refs/tags/")
-		// The tag name ends at a comma or paren (prefer the first).
-		j := strings.Index(line[i:], ",")
-		if j < 0 {
-			j = strings.Index(line[i:], ")")
-		}
+		// Trim off known prefix.
+		line = line[i+len(s):]
+		// The tag name ends at a comma or paren.
+		j := strings.IndexAny(line, ",)")
 		if j < 0 {
 			continue // malformed line; ignore it
 		}
-		tag = line[i : i+j]
-		if i == 0 {
+		tag = line[:j]
+		if row == 0 {
 			precise = true // tag denotes HEAD
 		}
 		break
@@ -292,6 +326,26 @@
 		// its content if available, which is empty at this point.
 		// Only use the VERSION file if it is non-empty.
 		if b != "" {
+			// Some builders cross-compile the toolchain on linux-amd64
+			// and then copy the toolchain to the target builder (say, linux-arm)
+			// for use there. But on non-release (devel) branches, the compiler
+			// used on linux-amd64 will be an amd64 binary, and the compiler
+			// shipped to linux-arm will be an arm binary, so they will have different
+			// content IDs (they are binaries for different architectures) and so the
+			// packages compiled by the running-on-amd64 compiler will appear
+			// stale relative to the running-on-arm compiler. Avoid this by setting
+			// the version string to something that doesn't begin with devel.
+			// Then the version string will be used in place of the content ID,
+			// and the packages will look up-to-date.
+			// TODO(rsc): Really the builders could be writing out a better VERSION file instead,
+			// but it is easier to change cmd/dist than to try to make changes to
+			// the builder while Brad is away.
+			if strings.HasPrefix(b, "devel") {
+				if hostType := os.Getenv("META_BUILDLET_HOST_TYPE"); strings.Contains(hostType, "-cross") {
+					fmt.Fprintf(os.Stderr, "warning: changing VERSION from %q to %q\n", b, "builder "+hostType)
+					b = "builder " + hostType
+				}
+			}
 			return b
 		}
 	}
@@ -306,7 +360,7 @@
 
 	// Show a nicer error message if this isn't a Git repo.
 	if !isGitRepo() {
-		fatal("FAILED: not a Git repo; must put a VERSION file in $GOROOT")
+		fatalf("FAILED: not a Git repo; must put a VERSION file in $GOROOT")
 	}
 
 	// Otherwise, use Git.
@@ -343,8 +397,7 @@
 	if !filepath.IsAbs(gitDir) {
 		gitDir = filepath.Join(goroot, gitDir)
 	}
-	fi, err := os.Stat(gitDir)
-	return err == nil && fi.IsDir()
+	return isdir(gitDir)
 }
 
 /*
@@ -411,14 +464,10 @@
 	}
 
 	// Create object directory.
-	// We keep it in pkg/ so that all the generated binaries
-	// are in one tree. If pkg/obj/libgc.a exists, it is a dreg from
-	// before we used subdirectories of obj. Delete all of obj
-	// to clean up.
-	if p := pathf("%s/pkg/obj/libgc.a", goroot); isfile(p) {
-		xremoveall(pathf("%s/pkg/obj", goroot))
-	}
-	p = pathf("%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch)
+	// We used to use it for C objects.
+	// Now we use it for the build cache, to separate dist's cache
+	// from any other cache the user might have.
+	p = pathf("%s/pkg/obj/go-build", goroot)
 	if rebuildall {
 		xremoveall(p)
 	}
@@ -441,7 +490,7 @@
 
 	// If $GOBIN is set and has a Go compiler, it must be cleaned.
 	for _, char := range "56789" {
-		if isfile(pathf("%s%s%c%s", gobin, slash, char, "g")) {
+		if isfile(pathf("%s/%c%s", gobin, char, "g")) {
 			for _, old := range oldtool {
 				xremove(pathf("%s/%s", gobin, old))
 			}
@@ -454,7 +503,7 @@
 	if strings.HasPrefix(goversion, "release.") || (strings.HasPrefix(goversion, "go") && !strings.Contains(goversion, "beta")) {
 		for _, dir := range unreleased {
 			if p := pathf("%s/%s", goroot, dir); isdir(p) {
-				fatal("%s should not exist in release build", p)
+				fatalf("%s should not exist in release build", p)
 			}
 		}
 	}
@@ -467,6 +516,8 @@
 // deptab lists changes to the default dependencies for a given prefix.
 // deps ending in /* read the whole directory; deps beginning with -
 // exclude files with that prefix.
+// Note that this table applies only to the build of cmd/go,
+// after the main compiler bootstrap.
 var deptab = []struct {
 	prefix string   // prefix of target
 	dep    []string // dependency tweaks for targets with that prefix
@@ -510,15 +561,35 @@
 // installed maps from a dir name (as given to install) to a chan
 // closed when the dir's package is installed.
 var installed = make(map[string]chan struct{})
+var installedMu sync.Mutex
 
-// install installs the library, package, or binary associated with dir,
-// which is relative to $GOROOT/src.
 func install(dir string) {
-	if ch, ok := installed[dir]; ok {
-		defer close(ch)
+	<-startInstall(dir)
+}
+
+func startInstall(dir string) chan struct{} {
+	installedMu.Lock()
+	ch := installed[dir]
+	if ch == nil {
+		ch = make(chan struct{})
+		installed[dir] = ch
+		go runInstall(dir, ch)
 	}
-	for _, dep := range builddeps[dir] {
-		<-installed[dep]
+	installedMu.Unlock()
+	return ch
+}
+
+// runInstall installs the library, package, or binary associated with dir,
+// which is relative to $GOROOT/src.
+func runInstall(dir string, ch chan struct{}) {
+	if dir == "net" || dir == "os/user" || dir == "crypto/x509" {
+		fatalf("go_bootstrap cannot depend on cgo package %s", dir)
+	}
+
+	defer close(ch)
+
+	if dir == "unsafe" {
+		return
 	}
 
 	if vflag > 0 {
@@ -595,7 +666,7 @@
 
 	// Convert to absolute paths.
 	for i, p := range files {
-		if !isabs(p) {
+		if !filepath.IsAbs(p) {
 			files[i] = pathf("%s/%s", path, p)
 		}
 	}
@@ -637,7 +708,7 @@
 	}
 
 	// For package runtime, copy some files into the work space.
-	if dir == "runtime" || strings.HasPrefix(dir, "runtime/internal/") {
+	if dir == "runtime" {
 		xmkdirall(pathf("%s/pkg/include", goroot))
 		// For use by assembly and C files.
 		copyfile(pathf("%s/pkg/include/textflag.h", goroot),
@@ -672,11 +743,23 @@
 		}
 		// Did not rebuild p.
 		if find(p, missing) >= 0 {
-			fatal("missing file %s", p)
+			fatalf("missing file %s", p)
 		}
 	built:
 	}
 
+	// Make sure dependencies are installed.
+	var deps []string
+	for _, p := range gofiles {
+		deps = append(deps, readimports(p)...)
+	}
+	for _, dir1 := range deps {
+		startInstall(dir1)
+	}
+	for _, dir1 := range deps {
+		install(dir1)
+	}
+
 	if goos != gohostos || goarch != gohostarch {
 		// We've generated the right files; the go command can do the build.
 		if vflag > 1 {
@@ -691,7 +774,7 @@
 	// For package runtime, this writes go_asm.h, which
 	// the assembly files will need.
 	pkg := dir
-	if strings.HasPrefix(dir, "cmd/") {
+	if strings.HasPrefix(dir, "cmd/") && strings.Count(dir, "/") == 1 {
 		pkg = "main"
 	}
 	b := pathf("%s/_go_.a", workdir)
@@ -701,7 +784,7 @@
 	} else {
 		archive = b
 	}
-	compile := []string{pathf("%s/compile", tooldir), "-pack", "-o", b, "-p", pkg}
+	compile := []string{pathf("%s/compile", tooldir), "-std", "-pack", "-o", b, "-p", pkg}
 	if gogcflags != "" {
 		compile = append(compile, strings.Fields(gogcflags)...)
 	}
@@ -729,6 +812,11 @@
 			"-D", "GOOS_GOARCH_" + goos + "_" + goarch,
 		}
 
+		if goarch == "mips" || goarch == "mipsle" {
+			// Define GOMIPS_value from gomips.
+			compile = append(compile, "-D", "GOMIPS_"+gomips)
+		}
+
 		doclean := true
 		b := pathf("%s/%s", workdir, filepath.Base(p))
 
@@ -815,7 +903,7 @@
 	}
 
 	// Check file contents for // +build lines.
-	for _, p := range splitlines(readfile(file)) {
+	for _, p := range strings.Split(readfile(file), "\n") {
 		p = strings.TrimSpace(p)
 		if p == "" {
 			continue
@@ -837,7 +925,7 @@
 		if !strings.Contains(p, "+build") {
 			continue
 		}
-		fields := splitfields(p[2:])
+		fields := strings.Fields(p[2:])
 		if len(fields) < 1 || fields[0] != "+build" {
 			continue
 		}
@@ -883,28 +971,21 @@
 	writefile(bdst.String(), dst, 0)
 }
 
-// builddeps records the build dependencies for the 'go bootstrap' command.
-// It is a map[string][]string and generated by mkdeps.bash into deps.go.
-
-// buildlist is the list of directories being built, sorted by name.
-var buildlist = makeBuildlist()
-
-func makeBuildlist() []string {
-	var all []string
-	for dir := range builddeps {
-		all = append(all, dir)
-	}
-	sort.Strings(all)
-	return all
-}
-
 var runtimegen = []string{
 	"zaexperiment.h",
 	"zversion.go",
 }
 
+// cleanlist is a list of packages with generated files and commands.
+var cleanlist = []string{
+	"runtime/internal/sys",
+	"cmd/cgo",
+	"cmd/go/internal/cfg",
+	"go/build",
+}
+
 func clean() {
-	for _, name := range buildlist {
+	for _, name := range cleanlist {
 		path := pathf("%s/src/%s", goroot, name)
 		// Remove generated files.
 		for _, elem := range xreaddir(path) {
@@ -946,24 +1027,6 @@
  * command implementations
  */
 
-func usage() {
-	xprintf("usage: go tool dist [command]\n" +
-		"Commands are:\n" +
-		"\n" +
-		"banner         print installation banner\n" +
-		"bootstrap      rebuild everything\n" +
-		"clean          deletes all built files\n" +
-		"env [-p]       print environment (-p: include $PATH)\n" +
-		"install [dir]  install individual directory\n" +
-		"list [-json]   list all supported platforms\n" +
-		"test [-h]      run Go test(s)\n" +
-		"version        print Go version\n" +
-		"\n" +
-		"All commands take -v flags to emit extra information.\n",
-	)
-	xexit(2)
-}
-
 // The env command prints the default environment.
 func cmdenv() {
 	path := flag.Bool("p", false, "emit updated PATH")
@@ -979,8 +1042,6 @@
 		format = "set %s=%s\r\n"
 	}
 
-	xprintf(format, "CC", defaultcc)
-	xprintf(format, "CC_FOR_TARGET", defaultcctarget)
 	xprintf(format, "GOROOT", goroot)
 	xprintf(format, "GOBIN", gobin)
 	xprintf(format, "GOARCH", goarch)
@@ -994,6 +1055,9 @@
 	if goarch == "386" {
 		xprintf(format, "GO386", go386)
 	}
+	if goarch == "mips" || goarch == "mipsle" {
+		xprintf(format, "GOMIPS", gomips)
+	}
 
 	if *path {
 		sep := ":"
@@ -1004,14 +1068,79 @@
 	}
 }
 
+var (
+	timeLogEnabled = os.Getenv("GOBUILDTIMELOGFILE") != ""
+	timeLogMu      sync.Mutex
+	timeLogFile    *os.File
+	timeLogStart   time.Time
+)
+
+func timelog(op, name string) {
+	if !timeLogEnabled {
+		return
+	}
+	timeLogMu.Lock()
+	defer timeLogMu.Unlock()
+	if timeLogFile == nil {
+		f, err := os.OpenFile(os.Getenv("GOBUILDTIMELOGFILE"), os.O_RDWR|os.O_APPEND, 0666)
+		if err != nil {
+			log.Fatal(err)
+		}
+		buf := make([]byte, 100)
+		n, _ := f.Read(buf)
+		s := string(buf[:n])
+		if i := strings.Index(s, "\n"); i >= 0 {
+			s = s[:i]
+		}
+		i := strings.Index(s, " start")
+		if i < 0 {
+			log.Fatalf("time log %s does not begin with start line", os.Getenv("GOBULDTIMELOGFILE"))
+		}
+		t, err := time.Parse(time.UnixDate, s[:i])
+		if err != nil {
+			log.Fatalf("cannot parse time log line %q: %v", s, err)
+		}
+		timeLogStart = t
+		timeLogFile = f
+	}
+	t := time.Now()
+	fmt.Fprintf(timeLogFile, "%s %+.1fs %s %s\n", t.Format(time.UnixDate), t.Sub(timeLogStart).Seconds(), op, name)
+}
+
+var toolchain = []string{"cmd/asm", "cmd/cgo", "cmd/compile", "cmd/link"}
+
 // The bootstrap command runs a build from scratch,
 // stopping at having installed the go_bootstrap command.
+//
+// WARNING: This command runs after cmd/dist is built with Go 1.4.
+// It rebuilds and installs cmd/dist with the new toolchain, so other
+// commands (like "go tool dist test" in run.bash) can rely on bug fixes
+// made since Go 1.4, but this function cannot. In particular, the uses
+// of os/exec in this function cannot assume that
+//	cmd.Env = append(os.Environ(), "X=Y")
+// sets $X to Y in the command's environment. That guarantee was
+// added after Go 1.4, and in fact in Go 1.4 it was typically the opposite:
+// if $X was already present in os.Environ(), most systems preferred
+// that setting, not the new one.
 func cmdbootstrap() {
+	timelog("start", "dist bootstrap")
+	defer timelog("end", "dist bootstrap")
+
+	var noBanner bool
+	var debug bool
 	flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
+	flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process")
+	flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner")
+
 	xflagparse(0)
 
+	if debug {
+		// cmd/buildid is used in debug mode.
+		toolchain = append(toolchain, "cmd/buildid")
+	}
+
 	if isdir(pathf("%s/src/pkg", goroot)) {
-		fatal("\n\n"+
+		fatalf("\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"+
@@ -1026,9 +1155,13 @@
 
 	setup()
 
+	timelog("build", "toolchain1")
 	checkCC()
 	bootstrapBuildTools()
 
+	// Remember old content of $GOROOT/bin for comparison below.
+	oldBinFiles, _ := filepath.Glob(pathf("%s/bin/*", goroot))
+
 	// For the main bootstrap, building for host os/arch.
 	oldgoos = goos
 	oldgoarch = goarch
@@ -1039,48 +1172,175 @@
 	os.Setenv("GOARCH", goarch)
 	os.Setenv("GOOS", goos)
 
-	// TODO(rsc): Enable when appropriate.
-	// This step is only needed if we believe that the Go compiler built from Go 1.4
-	// will produce different object files than the Go compiler built from itself.
-	// In the absence of bugs, that should not happen.
-	// And if there are bugs, they're more likely in the current development tree
-	// than in a standard release like Go 1.4, so don't do this rebuild by default.
-	if false {
-		xprintf("##### Building Go toolchain using itself.\n")
-		for _, dir := range buildlist {
-			installed[dir] = make(chan struct{})
-		}
-		var wg sync.WaitGroup
-		for _, dir := range builddeps["cmd/go"] {
-			wg.Add(1)
-			dir := dir
-			go func() {
-				defer wg.Done()
-				install(dir)
-			}()
-		}
-		wg.Wait()
+	timelog("build", "go_bootstrap")
+	xprintf("Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.\n")
+	install("runtime") // dependency not visible in sources; also sets up textflag.h
+	install("cmd/go")
+	if vflag > 0 {
 		xprintf("\n")
 	}
 
-	xprintf("##### Building go_bootstrap for host, %s/%s.\n", gohostos, gohostarch)
-	for _, dir := range buildlist {
-		installed[dir] = make(chan struct{})
+	gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
+	goldflags = os.Getenv("GO_LDFLAGS")
+	goBootstrap := pathf("%s/go_bootstrap", tooldir)
+	cmdGo := pathf("%s/go", gobin)
+	if debug {
+		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
+		copyfile(pathf("%s/compile1", tooldir), pathf("%s/compile", tooldir), writeExec)
 	}
-	for _, dir := range buildlist {
-		go install(dir)
+
+	// To recap, so far we have built the new toolchain
+	// (cmd/asm, cmd/cgo, cmd/compile, cmd/link)
+	// using Go 1.4's toolchain and go command.
+	// Then we built the new go command (as go_bootstrap)
+	// using the new toolchain and our own build logic (above).
+	//
+	//	toolchain1 = mk(new toolchain, go1.4 toolchain, go1.4 cmd/go)
+	//	go_bootstrap = mk(new cmd/go, toolchain1, cmd/dist)
+	//
+	// The toolchain1 we built earlier is built from the new sources,
+	// but because it was built using cmd/go it has no build IDs.
+	// The eventually installed toolchain needs build IDs, so we need
+	// to do another round:
+	//
+	//	toolchain2 = mk(new toolchain, toolchain1, go_bootstrap)
+	//
+	timelog("build", "toolchain2")
+	if vflag > 0 {
+		xprintf("\n")
 	}
-	<-installed["cmd/go"]
+	xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n")
+	os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
+	goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
+	if debug {
+		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
+		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
+		copyfile(pathf("%s/compile2", tooldir), pathf("%s/compile", tooldir), writeExec)
+	}
 
-	goos = oldgoos
-	goarch = oldgoarch
-	os.Setenv("GOARCH", goarch)
-	os.Setenv("GOOS", goos)
+	// Toolchain2 should be semantically equivalent to toolchain1,
+	// but it was built using the new compilers instead of the Go 1.4 compilers,
+	// so it should at the least run faster. Also, toolchain1 had no build IDs
+	// in the binaries, while toolchain2 does. In non-release builds, the
+	// toolchain's build IDs feed into constructing the build IDs of built targets,
+	// so in non-release builds, everything now looks out-of-date due to
+	// toolchain2 having build IDs - that is, due to the go command seeing
+	// that there are new compilers. In release builds, the toolchain's reported
+	// version is used in place of the build ID, and the go command does not
+	// see that change from toolchain1 to toolchain2, so in release builds,
+	// nothing looks out of date.
+	// To keep the behavior the same in both non-release and release builds,
+	// we force-install everything here.
+	//
+	//	toolchain3 = mk(new toolchain, toolchain2, go_bootstrap)
+	//
+	timelog("build", "toolchain3")
+	if vflag > 0 {
+		xprintf("\n")
+	}
+	xprintf("Building Go toolchain3 using go_bootstrap and Go toolchain2.\n")
+	goInstall(goBootstrap, append([]string{"-a", "-i"}, toolchain...)...)
+	if debug {
+		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
+		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
+		copyfile(pathf("%s/compile3", tooldir), pathf("%s/compile", tooldir), writeExec)
+	}
+	checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
 
-	// Build runtime for actual goos/goarch too.
-	if goos != gohostos || goarch != gohostarch {
-		installed["runtime"] = make(chan struct{})
-		install("runtime")
+	if goos == oldgoos && goarch == oldgoarch {
+		// Common case - not setting up for cross-compilation.
+		timelog("build", "toolchain")
+		if vflag > 0 {
+			xprintf("\n")
+		}
+		xprintf("Building packages and commands for %s/%s.\n", goos, goarch)
+	} else {
+		// GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH.
+		// Finish GOHOSTOS/GOHOSTARCH installation and then
+		// run GOOS/GOARCH installation.
+		timelog("build", "host toolchain")
+		if vflag > 0 {
+			xprintf("\n")
+		}
+		xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch)
+		goInstall(goBootstrap, "std", "cmd")
+		checkNotStale(goBootstrap, "std", "cmd")
+		checkNotStale(cmdGo, "std", "cmd")
+
+		timelog("build", "target toolchain")
+		if vflag > 0 {
+			xprintf("\n")
+		}
+		goos = oldgoos
+		goarch = oldgoarch
+		os.Setenv("GOOS", goos)
+		os.Setenv("GOARCH", goarch)
+		os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
+		xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
+	}
+	goInstall(goBootstrap, "std", "cmd")
+	checkNotStale(goBootstrap, "std", "cmd")
+	checkNotStale(cmdGo, "std", "cmd")
+	if debug {
+		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
+		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
+		checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
+		copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
+	}
+
+	// Check that there are no new files in $GOROOT/bin other than
+	// go and gofmt and $GOOS_$GOARCH (target bin when cross-compiling).
+	binFiles, _ := filepath.Glob(pathf("%s/bin/*", goroot))
+	ok := map[string]bool{}
+	for _, f := range oldBinFiles {
+		ok[f] = true
+	}
+	for _, f := range binFiles {
+		elem := strings.TrimSuffix(filepath.Base(f), ".exe")
+		if !ok[f] && elem != "go" && elem != "gofmt" && elem != goos+"_"+goarch {
+			fatalf("unexpected new file in $GOROOT/bin: %s", elem)
+		}
+	}
+
+	// Remove go_bootstrap now that we're done.
+	xremove(pathf("%s/go_bootstrap", tooldir))
+
+	// Print trailing banner unless instructed otherwise.
+	if !noBanner {
+		banner()
+	}
+}
+
+func goInstall(goBinary string, args ...string) {
+	installCmd := []string{goBinary, "install", "-gcflags=all=" + gogcflags, "-ldflags=all=" + goldflags}
+	if vflag > 0 {
+		installCmd = append(installCmd, "-v")
+	}
+
+	// Force only one process at a time on vx32 emulation.
+	if gohostos == "plan9" && os.Getenv("sysname") == "vx32" {
+		installCmd = append(installCmd, "-p=1")
+	}
+
+	run(goroot, ShowOutput|CheckExit, append(installCmd, args...)...)
+}
+
+func checkNotStale(goBinary string, targets ...string) {
+	out := run(goroot, CheckExit,
+		append([]string{
+			goBinary,
+			"list", "-gcflags=all=" + gogcflags, "-ldflags=all=" + goldflags,
+			"-f={{if .Stale}}\tSTALE {{.ImportPath}}: {{.StaleReason}}{{end}}",
+		}, targets...)...)
+	if strings.Contains(out, "\tSTALE ") {
+		os.Setenv("GODEBUG", "gocachehash=1")
+		for _, target := range []string{"runtime/internal/sys", "cmd/dist", "cmd/link"} {
+			if strings.Contains(out, "STALE "+target) {
+				run(goroot, ShowOutput|CheckExit, goBinary, "list", "-f={{.ImportPath}} {{.Stale}}", target)
+				break
+			}
+		}
+		fatalf("unexpected stale targets reported by %s list -gcflags=\"%s\" -ldflags=\"%s\" for %v:\n%s", goBinary, gogcflags, goldflags, targets, out)
 	}
 }
 
@@ -1146,12 +1406,12 @@
 	if !needCC() {
 		return
 	}
-	if output, err := exec.Command(defaultcc, "--help").CombinedOutput(); err != nil {
+	if output, err := exec.Command(defaultcc[""], "--help").CombinedOutput(); err != nil {
 		outputHdr := ""
 		if len(output) > 0 {
 			outputHdr = "\nCommand output:\n\n"
 		}
-		fatal("cannot invoke C compiler %q: %v\n\n"+
+		fatalf("cannot invoke C compiler %q: %v\n\n"+
 			"Go needs a system C compiler for use with cgo.\n"+
 			"To set a C compiler, set CC=the-compiler.\n"+
 			"To disable cgo, set CGO_ENABLED=0.\n%s%s", defaultcc, err, outputHdr, output)
@@ -1167,7 +1427,7 @@
 	src := pathf("%s/src/", goroot)
 	real_src := xrealwd(src)
 	if !strings.HasPrefix(pwd, real_src) {
-		fatal("current directory %s is not under %s", pwd, real_src)
+		fatalf("current directory %s is not under %s", pwd, real_src)
 	}
 	pwd = pwd[len(real_src):]
 	// guard against xrealwd returning the directory without the trailing /
@@ -1198,8 +1458,13 @@
 // Banner prints the 'now you've installed Go' banner.
 func cmdbanner() {
 	xflagparse(0)
+	banner()
+}
 
-	xprintf("\n")
+func banner() {
+	if vflag > 0 {
+		xprintf("\n")
+	}
 	xprintf("---\n")
 	xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot)
 	xprintf("Installed commands in %s\n", gobin)
@@ -1271,9 +1536,9 @@
 	}
 	out, err := json.MarshalIndent(results, "", "\t")
 	if err != nil {
-		fatal("json marshal error: %v", err)
+		fatalf("json marshal error: %v", err)
 	}
 	if _, err := os.Stdout.Write(out); err != nil {
-		fatal("write failed: %v", err)
+		fatalf("write failed: %v", err)
 	}
 }
diff --git a/src/cmd/dist/buildgo.go b/src/cmd/dist/buildgo.go
index 1de2c4e..caafc13 100644
--- a/src/cmd/dist/buildgo.go
+++ b/src/cmd/dist/buildgo.go
@@ -8,7 +8,9 @@
 	"bytes"
 	"fmt"
 	"os"
+	"path/filepath"
 	"sort"
+	"strings"
 )
 
 /*
@@ -22,35 +24,53 @@
 //	const defaultCXX = <defaultcxx>
 //	const defaultPkgConfig = <defaultpkgconfig>
 //
-// It is invoked to write cmd/go/zdefaultcc.go
+// It is invoked to write cmd/go/internal/cfg/zdefaultcc.go
 // but we also write cmd/cgo/zdefaultcc.go
 func mkzdefaultcc(dir, file string) {
-	outGo := fmt.Sprintf(
-		"// auto generated by go tool dist\n"+
-			"\n"+
-			"package cfg\n"+
-			"\n"+
-			"const DefaultCC = `%s`\n"+
-			"const DefaultCXX = `%s`\n"+
-			"const DefaultPkgConfig = `%s`\n",
-		defaultcctarget, defaultcxxtarget, defaultpkgconfigtarget)
+	if strings.Contains(file, filepath.FromSlash("go/internal/cfg")) {
+		var buf bytes.Buffer
+		fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
+		fmt.Fprintln(&buf)
+		fmt.Fprintf(&buf, "package cfg\n")
+		fmt.Fprintln(&buf)
+		fmt.Fprintf(&buf, "const DefaultPkgConfig = `%s`\n", defaultpkgconfig)
+		buf.WriteString(defaultCCFunc("DefaultCC", defaultcc))
+		buf.WriteString(defaultCCFunc("DefaultCXX", defaultcxx))
+		writefile(buf.String(), file, writeSkipSame)
+		return
+	}
 
-	writefile(outGo, file, writeSkipSame)
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "package main\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "const defaultPkgConfig = `%s`\n", defaultpkgconfig)
+	buf.WriteString(defaultCCFunc("defaultCC", defaultcc))
+	buf.WriteString(defaultCCFunc("defaultCXX", defaultcxx))
+	writefile(buf.String(), file, writeSkipSame)
+}
 
-	// Convert file name to replace: turn go/internal/cfg into cgo.
-	outCgo := fmt.Sprintf(
-		"// auto generated by go tool dist\n"+
-			"\n"+
-			"package main\n"+
-			"\n"+
-			"const defaultCC = `%s`\n"+
-			"const defaultCXX = `%s`\n"+
-			"const defaultPkgConfig = `%s`\n",
-		defaultcctarget, defaultcxxtarget, defaultpkgconfigtarget)
+func defaultCCFunc(name string, defaultcc map[string]string) string {
+	var buf bytes.Buffer
 
-	i := len(file) - len("go/internal/cfg/zdefaultcc.go")
-	file = file[:i] + "cgo/zdefaultcc.go"
-	writefile(outCgo, file, writeSkipSame)
+	fmt.Fprintf(&buf, "func %s(goos, goarch string) string {\n", name)
+	fmt.Fprintf(&buf, "\tswitch goos+`/`+goarch {\n")
+	var keys []string
+	for k := range defaultcc {
+		if k != "" {
+			keys = append(keys, k)
+		}
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		fmt.Fprintf(&buf, "\tcase %q:\n\t\treturn %q\n", k, defaultcc[k])
+	}
+	fmt.Fprintf(&buf, "\t}\n")
+	fmt.Fprintf(&buf, "\treturn %q\n", defaultcc[""])
+	fmt.Fprintf(&buf, "}\n")
+
+	return buf.String()
 }
 
 // mkzcgo writes zosarch.go for cmd/go.
@@ -63,13 +83,14 @@
 	sort.Strings(list)
 
 	var buf bytes.Buffer
-	buf.WriteString("// auto generated by go tool dist\n\n")
-	buf.WriteString("package cfg\n\n")
+	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n\n")
+	fmt.Fprintf(&buf, "package cfg\n\n")
 	fmt.Fprintf(&buf, "var OSArchSupportsCgo = map[string]bool{\n")
 	for _, plat := range list {
 		fmt.Fprintf(&buf, "\t%q: %v,\n", plat, cgoEnabled[plat])
 	}
 	fmt.Fprintf(&buf, "}\n")
+
 	writefile(buf.String(), file, writeSkipSame)
 }
 
@@ -90,18 +111,17 @@
 	sort.Strings(list)
 
 	var buf bytes.Buffer
-
-	fmt.Fprintf(&buf,
-		"// auto generated by go tool dist\n"+
-			"\n"+
-			"package build\n"+
-			"\n"+
-			"const defaultCGO_ENABLED = %q\n\n"+
-			"var cgoEnabled = map[string]bool{\n", os.Getenv("CGO_ENABLED"))
+	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "package build\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %q\n", os.Getenv("CGO_ENABLED"))
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "var cgoEnabled = map[string]bool{\n")
 	for _, plat := range list {
 		fmt.Fprintf(&buf, "\t%q: true,\n", plat)
 	}
-	fmt.Fprintf(&buf, "}")
+	fmt.Fprintf(&buf, "}\n")
 
 	writefile(buf.String(), file, writeSkipSame)
 }
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index 1467c59..5cbcd81 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -5,6 +5,7 @@
 package main
 
 import (
+	"bytes"
 	"fmt"
 	"os"
 	"strings"
@@ -17,23 +18,22 @@
 // mkzversion writes zversion.go:
 //
 //	package sys
-//	const DefaultGoroot = <goroot>
+//
 //	const TheVersion = <version>
 //	const Goexperiment = <goexperiment>
 //	const StackGuardMultiplier = <multiplier value>
 //
 func mkzversion(dir, file string) {
-	out := fmt.Sprintf(
-		"// auto generated by go tool dist\n"+
-			"\n"+
-			"package sys\n"+
-			"\n"+
-			"const DefaultGoroot = `%s`\n"+
-			"const TheVersion = `%s`\n"+
-			"const Goexperiment = `%s`\n"+
-			"const StackGuardMultiplier = %d\n\n", goroot_final, findgoversion(), os.Getenv("GOEXPERIMENT"), stackGuardMultiplier())
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "package sys\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "const TheVersion = `%s`\n", findgoversion())
+	fmt.Fprintf(&buf, "const Goexperiment = `%s`\n", os.Getenv("GOEXPERIMENT"))
+	fmt.Fprintf(&buf, "const StackGuardMultiplier = %d\n", stackGuardMultiplier())
 
-	writefile(out, file, writeSkipSame)
+	writefile(buf.String(), file, writeSkipSame)
 }
 
 // mkzbootstrap writes cmd/internal/objabi/zbootstrap.go:
@@ -43,6 +43,7 @@
 //	const defaultGOROOT = <goroot>
 //	const defaultGO386 = <go386>
 //	const defaultGOARM = <goarm>
+//	const defaultGOMIPS = <gomips>
 //	const defaultGOOS = runtime.GOOS
 //	const defaultGOARCH = runtime.GOARCH
 //	const defaultGO_EXTLINK_ENABLED = <goextlinkenabled>
@@ -60,25 +61,24 @@
 // This is more useful than having it default to generating objects for the
 // original target (in this example, a Mac).
 func mkzbootstrap(file string) {
-	out := fmt.Sprintf(
-		"// auto generated by go tool dist\n"+
-			"\n"+
-			"package objabi\n"+
-			"\n"+
-			"import \"runtime\"\n"+
-			"\n"+
-			"const defaultGOROOT = `%s`\n"+
-			"const defaultGO386 = `%s`\n"+
-			"const defaultGOARM = `%s`\n"+
-			"const defaultGOOS = runtime.GOOS\n"+
-			"const defaultGOARCH = runtime.GOARCH\n"+
-			"const defaultGO_EXTLINK_ENABLED = `%s`\n"+
-			"const version = `%s`\n"+
-			"const stackGuardMultiplier = %d\n"+
-			"const goexperiment = `%s`\n",
-		goroot_final, go386, goarm, goextlinkenabled, findgoversion(), stackGuardMultiplier(), os.Getenv("GOEXPERIMENT"))
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "package objabi\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "import \"runtime\"\n")
+	fmt.Fprintln(&buf)
+	fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
+	fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
+	fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
+	fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
+	fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
+	fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
+	fmt.Fprintf(&buf, "const version = `%s`\n", findgoversion())
+	fmt.Fprintf(&buf, "const stackGuardMultiplier = %d\n", stackGuardMultiplier())
+	fmt.Fprintf(&buf, "const goexperiment = `%s`\n", os.Getenv("GOEXPERIMENT"))
 
-	writefile(out, file, writeSkipSame)
+	writefile(buf.String(), file, writeSkipSame)
 }
 
 // stackGuardMultiplier returns a multiplier to apply to the default
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index 8a3db32..24d2e1e 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -35,6 +35,7 @@
 	"cmd/asm/internal/asm",
 	"cmd/asm/internal/flags",
 	"cmd/asm/internal/lex",
+	"cmd/cgo",
 	"cmd/compile",
 	"cmd/compile/internal/amd64",
 	"cmd/compile/internal/arm",
@@ -51,6 +52,7 @@
 	"cmd/internal/bio",
 	"cmd/internal/gcprog",
 	"cmd/internal/dwarf",
+	"cmd/internal/edit",
 	"cmd/internal/objabi",
 	"cmd/internal/obj",
 	"cmd/internal/obj/arm",
@@ -66,14 +68,24 @@
 	"cmd/link/internal/arm",
 	"cmd/link/internal/arm64",
 	"cmd/link/internal/ld",
+	"cmd/link/internal/loadelf",
+	"cmd/link/internal/loadmacho",
+	"cmd/link/internal/loadpe",
 	"cmd/link/internal/mips",
 	"cmd/link/internal/mips64",
+	"cmd/link/internal/objfile",
 	"cmd/link/internal/ppc64",
 	"cmd/link/internal/s390x",
+	"cmd/link/internal/sym",
 	"cmd/link/internal/x86",
+	"container/heap",
+	"debug/dwarf",
+	"debug/elf",
+	"debug/macho",
 	"debug/pe",
 	"math/big",
 	"math/bits",
+	"sort",
 }
 
 // File prefixes that are ignored by go/build anyway, and cause
@@ -95,7 +107,7 @@
 	if goroot_bootstrap == "" {
 		goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
 	}
-	xprintf("##### Building Go toolchain using %s.\n", goroot_bootstrap)
+	xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)
 
 	mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
 
@@ -114,6 +126,11 @@
 		src := pathf("%s/src/%s", goroot, dir)
 		dst := pathf("%s/%s", base, dir)
 		xmkdirall(dst)
+		if dir == "cmd/cgo" {
+			// Write to src because we need the file both for bootstrap
+			// and for later in the main build.
+			mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
+		}
 	Dir:
 		for _, name := range xreaddirfiles(src) {
 			for _, pre := range ignorePrefixes {
@@ -128,8 +145,7 @@
 			}
 			srcFile := pathf("%s/%s", src, name)
 			dstFile := pathf("%s/%s", dst, name)
-			text := readfile(srcFile)
-			text = bootstrapRewriteFile(text, srcFile)
+			text := bootstrapRewriteFile(srcFile)
 			writefile(text, dstFile, 0)
 		}
 	}
@@ -163,12 +179,17 @@
 	// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
 	// Use the math_big_pure_go build tag to disable the assembly in math/big
 	// which may contain unsupported instructions.
+	// Note that if we are using Go 1.10 or later as bootstrap, the -gcflags=-l
+	// only applies to the final cmd/go binary, but that's OK: if this is Go 1.10
+	// or later we don't need to disable inlining to work around bugs in the Go 1.4 compiler.
 	cmd := []string{
 		pathf("%s/bin/go", goroot_bootstrap),
 		"install",
 		"-gcflags=-l",
-		"-tags=math_big_pure_go",
-		"-v",
+		"-tags=math_big_pure_go compiler_bootstrap",
+	}
+	if vflag > 0 {
+		cmd = append(cmd, "-v")
 	}
 	if tool := os.Getenv("GOBOOTSTRAP_TOOLEXEC"); tool != "" {
 		cmd = append(cmd, "-toolexec="+tool)
@@ -187,10 +208,12 @@
 		}
 	}
 
-	xprintf("\n")
+	if vflag > 0 {
+		xprintf("\n")
+	}
 }
 
-var ssaRewriteFileSubstring = filepath.ToSlash("src/cmd/compile/internal/ssa/rewrite")
+var ssaRewriteFileSubstring = filepath.FromSlash("src/cmd/compile/internal/ssa/rewrite")
 
 // isUnneededSSARewriteFile reports whether srcFile is a
 // src/cmd/compile/internal/ssa/rewriteARCHNAME.go file for an
@@ -221,24 +244,26 @@
 	return archCaps, true
 }
 
-func bootstrapRewriteFile(text, srcFile string) string {
+func bootstrapRewriteFile(srcFile string) string {
 	// During bootstrap, generate dummy rewrite files for
 	// irrelevant architectures. We only need to build a bootstrap
 	// binary that works for the current runtime.GOARCH.
 	// This saves 6+ seconds of bootstrap.
 	if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
-		return fmt.Sprintf(`package ssa
+		return fmt.Sprintf(`// Code generated by go tool dist; DO NOT EDIT.
+
+package ssa
 
 func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
 func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
 `, archCaps, archCaps)
 	}
 
-	return bootstrapFixImports(text, srcFile)
+	return bootstrapFixImports(srcFile)
 }
 
-func bootstrapFixImports(text, srcFile string) string {
-	lines := strings.SplitAfter(text, "\n")
+func bootstrapFixImports(srcFile string) string {
+	lines := strings.SplitAfter(readfile(srcFile), "\n")
 	inBlock := false
 	for i, line := range lines {
 		if strings.HasPrefix(line, "import (") {
@@ -262,7 +287,7 @@
 		}
 	}
 
-	lines[0] = "// Do not edit. Bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
+	lines[0] = "// Code generated by go tool dist; DO NOT EDIT.\n// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
 
 	return strings.Join(lines, "")
 }
diff --git a/src/cmd/dist/deps.go b/src/cmd/dist/deps.go
deleted file mode 100644
index 6e2169d..0000000
--- a/src/cmd/dist/deps.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// generated by mkdeps.bash
-
-package main
-
-var builddeps = map[string][]string{
-	"bufio":                             {"bytes", "errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"bytes":                             {"errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"cmd/go/internal/base":              {"bufio", "bytes", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/bug":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/envcmd", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/web", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding", "encoding/base64", "encoding/binary", "encoding/json", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/buildid":           {"bufio", "bytes", "cmd/go/internal/cfg", "cmd/internal/objabi", "compress/flate", "compress/zlib", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/cfg":               {"bufio", "bytes", "cmd/internal/objabi", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/clean":             {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/cmdflag":           {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/doc":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/envcmd":            {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding", "encoding/base64", "encoding/binary", "encoding/json", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/fix":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/internal/objabi", "compress/flate", "compress/zlib", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/fmtcmd":            {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/internal/objabi", "compress/flate", "compress/zlib", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/generate":          {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/get":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/web", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding", "encoding/base64", "encoding/binary", "encoding/json", "encoding/xml", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/singleflight", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/help":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/list":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding", "encoding/base64", "encoding/binary", "encoding/json", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/load":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "compress/flate", "compress/zlib", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/run":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/str":               {"bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/test":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/cmdflag", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/tool":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/version":           {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/cfg", "cmd/go/internal/str", "cmd/internal/objabi", "context", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/vet":               {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/cmdflag", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/go/internal/web":               {"errors", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
-	"cmd/go/internal/work":              {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/load", "cmd/go/internal/str", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding/binary", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"cmd/internal/objabi":               {"errors", "flag", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "log", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"compress/flate":                    {"bufio", "bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "math/bits", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"compress/zlib":                     {"bufio", "bytes", "compress/flate", "errors", "fmt", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "math/bits", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"container/heap":                    {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"context":                           {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"crypto":                            {"errors", "hash", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
-	"crypto/sha1":                       {"crypto", "errors", "hash", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
-	"debug/dwarf":                       {"encoding/binary", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"debug/elf":                         {"bufio", "bytes", "compress/flate", "compress/zlib", "debug/dwarf", "encoding/binary", "errors", "fmt", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "math/bits", "os", "path", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"debug/macho":                       {"bytes", "debug/dwarf", "encoding/binary", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"encoding":                          {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"encoding/base64":                   {"errors", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
-	"encoding/binary":                   {"errors", "internal/cpu", "internal/race", "io", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"encoding/json":                     {"bytes", "encoding", "encoding/base64", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"encoding/xml":                      {"bufio", "bytes", "encoding", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"errors":                            {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"flag":                              {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"fmt":                               {"errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/ast":                            {"bytes", "errors", "fmt", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/build":                          {"bufio", "bytes", "errors", "fmt", "go/ast", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/doc":                            {"bytes", "errors", "fmt", "go/ast", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "math", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/parser":                         {"bytes", "errors", "fmt", "go/ast", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/scanner":                        {"bytes", "errors", "fmt", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"go/token":                          {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"hash":                              {"errors", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
-	"hash/adler32":                      {"errors", "hash", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
-	"internal/cpu":                      {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"internal/poll":                     {"errors", "internal/race", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
-	"internal/race":                     {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"internal/singleflight":             {"internal/race", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
-	"internal/syscall/windows":          {"errors", "internal/race", "internal/syscall/windows/sysdll", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "unicode/utf16"},
-	"internal/syscall/windows/registry": {"errors", "internal/race", "internal/syscall/windows/sysdll", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "unicode/utf16"},
-	"internal/syscall/windows/sysdll":   {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"io":                      {"errors", "internal/race", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
-	"io/ioutil":               {"bytes", "errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"log":                     {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"math":                    {"internal/cpu", "runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"math/bits":               {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"net/url":                 {"bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"os":                      {"errors", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
-	"os/exec":                 {"bytes", "context", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"os/signal":               {"errors", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "os", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
-	"path":                    {"errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"path/filepath":           {"errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"reflect":                 {"errors", "internal/cpu", "internal/race", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"regexp":                  {"bytes", "errors", "internal/cpu", "internal/race", "io", "math", "reflect", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"regexp/syntax":           {"bytes", "errors", "internal/cpu", "internal/race", "io", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"runtime":                 {"runtime/internal/atomic", "runtime/internal/sys"},
-	"runtime/internal/atomic": {"runtime/internal/sys"},
-	"runtime/internal/sys":    {},
-	"sort":                    {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"strconv":                 {"errors", "internal/cpu", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "unicode/utf8"},
-	"strings":                 {"errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "unicode", "unicode/utf8"},
-	"sync":                    {"internal/race", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync/atomic"},
-	"sync/atomic":             {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"syscall":                 {"errors", "internal/race", "internal/syscall/windows/sysdll", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "unicode/utf16"},
-	"text/template":           {"bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "math", "net/url", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"text/template/parse":     {"bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-	"time":                    {"errors", "internal/race", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "unicode/utf16"},
-	"unicode":                 {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"unicode/utf16":           {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"unicode/utf8":            {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
-	"cmd/go":                  {"bufio", "bytes", "cmd/go/internal/base", "cmd/go/internal/bug", "cmd/go/internal/buildid", "cmd/go/internal/cfg", "cmd/go/internal/clean", "cmd/go/internal/cmdflag", "cmd/go/internal/doc", "cmd/go/internal/envcmd", "cmd/go/internal/fix", "cmd/go/internal/fmtcmd", "cmd/go/internal/generate", "cmd/go/internal/get", "cmd/go/internal/help", "cmd/go/internal/list", "cmd/go/internal/load", "cmd/go/internal/run", "cmd/go/internal/str", "cmd/go/internal/test", "cmd/go/internal/tool", "cmd/go/internal/version", "cmd/go/internal/vet", "cmd/go/internal/web", "cmd/go/internal/work", "cmd/internal/objabi", "compress/flate", "compress/zlib", "container/heap", "context", "crypto", "crypto/sha1", "debug/dwarf", "debug/elf", "debug/macho", "encoding", "encoding/base64", "encoding/binary", "encoding/json", "encoding/xml", "errors", "flag", "fmt", "go/ast", "go/build", "go/doc", "go/parser", "go/scanner", "go/token", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/singleflight", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "math/bits", "net/url", "os", "os/exec", "os/signal", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
-}
diff --git a/src/cmd/dist/doc.go b/src/cmd/dist/doc.go
new file mode 100644
index 0000000..a4e6aa5
--- /dev/null
+++ b/src/cmd/dist/doc.go
@@ -0,0 +1,19 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Dist helps bootstrap, build, and test the Go distribution.
+//
+// Usage:
+//   go tool dist [command]
+//
+// The commands are:
+//   banner         print installation banner
+//   bootstrap      rebuild everything
+//   clean          deletes all built files
+//   env [-p]       print environment (-p: include $PATH)
+//   install [dir]  install individual directory
+//   list [-json]   list all supported platforms
+//   test [-h]      run Go test(s)
+//   version        print Go version
+package main
diff --git a/src/cmd/dist/imports.go b/src/cmd/dist/imports.go
new file mode 100644
index 0000000..bf64d66
--- /dev/null
+++ b/src/cmd/dist/imports.go
@@ -0,0 +1,245 @@
+// 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 is forked from go/build/read.go.
+// (cmd/dist must not import go/build because we do not want it to be
+// sensitive to the specific version of go/build present in $GOROOT_BOOTSTRAP.)
+
+package main
+
+import (
+	"bufio"
+	"errors"
+	"io"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+)
+
+type importReader struct {
+	b    *bufio.Reader
+	buf  []byte
+	peek byte
+	err  error
+	eof  bool
+	nerr int
+}
+
+func isIdent(c byte) bool {
+	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
+}
+
+var (
+	errSyntax = errors.New("syntax error")
+	errNUL    = errors.New("unexpected NUL in input")
+)
+
+// syntaxError records a syntax error, but only if an I/O error has not already been recorded.
+func (r *importReader) syntaxError() {
+	if r.err == nil {
+		r.err = errSyntax
+	}
+}
+
+// readByte reads the next byte from the input, saves it in buf, and returns it.
+// If an error occurs, readByte records the error in r.err and returns 0.
+func (r *importReader) readByte() byte {
+	c, err := r.b.ReadByte()
+	if err == nil {
+		r.buf = append(r.buf, c)
+		if c == 0 {
+			err = errNUL
+		}
+	}
+	if err != nil {
+		if err == io.EOF {
+			r.eof = true
+		} else if r.err == nil {
+			r.err = err
+		}
+		c = 0
+	}
+	return c
+}
+
+// peekByte returns the next byte from the input reader but does not advance beyond it.
+// If skipSpace is set, peekByte skips leading spaces and comments.
+func (r *importReader) peekByte(skipSpace bool) byte {
+	if r.err != nil {
+		if r.nerr++; r.nerr > 10000 {
+			panic("go/build: import reader looping")
+		}
+		return 0
+	}
+
+	// Use r.peek as first input byte.
+	// Don't just return r.peek here: it might have been left by peekByte(false)
+	// and this might be peekByte(true).
+	c := r.peek
+	if c == 0 {
+		c = r.readByte()
+	}
+	for r.err == nil && !r.eof {
+		if skipSpace {
+			// For the purposes of this reader, semicolons are never necessary to
+			// understand the input and are treated as spaces.
+			switch c {
+			case ' ', '\f', '\t', '\r', '\n', ';':
+				c = r.readByte()
+				continue
+
+			case '/':
+				c = r.readByte()
+				if c == '/' {
+					for c != '\n' && r.err == nil && !r.eof {
+						c = r.readByte()
+					}
+				} else if c == '*' {
+					var c1 byte
+					for (c != '*' || c1 != '/') && r.err == nil {
+						if r.eof {
+							r.syntaxError()
+						}
+						c, c1 = c1, r.readByte()
+					}
+				} else {
+					r.syntaxError()
+				}
+				c = r.readByte()
+				continue
+			}
+		}
+		break
+	}
+	r.peek = c
+	return r.peek
+}
+
+// nextByte is like peekByte but advances beyond the returned byte.
+func (r *importReader) nextByte(skipSpace bool) byte {
+	c := r.peekByte(skipSpace)
+	r.peek = 0
+	return c
+}
+
+// readKeyword reads the given keyword from the input.
+// If the keyword is not present, readKeyword records a syntax error.
+func (r *importReader) readKeyword(kw string) {
+	r.peekByte(true)
+	for i := 0; i < len(kw); i++ {
+		if r.nextByte(false) != kw[i] {
+			r.syntaxError()
+			return
+		}
+	}
+	if isIdent(r.peekByte(false)) {
+		r.syntaxError()
+	}
+}
+
+// readIdent reads an identifier from the input.
+// If an identifier is not present, readIdent records a syntax error.
+func (r *importReader) readIdent() {
+	c := r.peekByte(true)
+	if !isIdent(c) {
+		r.syntaxError()
+		return
+	}
+	for isIdent(r.peekByte(false)) {
+		r.peek = 0
+	}
+}
+
+// readString reads a quoted string literal from the input.
+// If an identifier is not present, readString records a syntax error.
+func (r *importReader) readString(save *[]string) {
+	switch r.nextByte(true) {
+	case '`':
+		start := len(r.buf) - 1
+		for r.err == nil {
+			if r.nextByte(false) == '`' {
+				if save != nil {
+					*save = append(*save, string(r.buf[start:]))
+				}
+				break
+			}
+			if r.eof {
+				r.syntaxError()
+			}
+		}
+	case '"':
+		start := len(r.buf) - 1
+		for r.err == nil {
+			c := r.nextByte(false)
+			if c == '"' {
+				if save != nil {
+					*save = append(*save, string(r.buf[start:]))
+				}
+				break
+			}
+			if r.eof || c == '\n' {
+				r.syntaxError()
+			}
+			if c == '\\' {
+				r.nextByte(false)
+			}
+		}
+	default:
+		r.syntaxError()
+	}
+}
+
+// readImport reads an import clause - optional identifier followed by quoted string -
+// from the input.
+func (r *importReader) readImport(imports *[]string) {
+	c := r.peekByte(true)
+	if c == '.' {
+		r.peek = 0
+	} else if isIdent(c) {
+		r.readIdent()
+	}
+	r.readString(imports)
+}
+
+// readComments is like ioutil.ReadAll, except that it only reads the leading
+// block of comments in the file.
+func readComments(f io.Reader) ([]byte, error) {
+	r := &importReader{b: bufio.NewReader(f)}
+	r.peekByte(true)
+	if r.err == nil && !r.eof {
+		// Didn't reach EOF, so must have found a non-space byte. Remove it.
+		r.buf = r.buf[:len(r.buf)-1]
+	}
+	return r.buf, r.err
+}
+
+// readimports returns the imports found in the named file.
+func readimports(file string) []string {
+	var imports []string
+	r := &importReader{b: bufio.NewReader(strings.NewReader(readfile(file)))}
+	r.readKeyword("package")
+	r.readIdent()
+	for r.peekByte(true) == 'i' {
+		r.readKeyword("import")
+		if r.peekByte(true) == '(' {
+			r.nextByte(false)
+			for r.peekByte(true) != ')' && r.err == nil {
+				r.readImport(&imports)
+			}
+			r.nextByte(false)
+		} else {
+			r.readImport(&imports)
+		}
+	}
+
+	for i := range imports {
+		unquoted, err := strconv.Unquote(imports[i])
+		if err != nil {
+			fatalf("reading imports from %s: %v", file, err)
+		}
+		imports[i] = unquoted
+	}
+
+	return imports
+}
diff --git a/src/cmd/dist/main.go b/src/cmd/dist/main.go
index b0471bd..a72a260 100644
--- a/src/cmd/dist/main.go
+++ b/src/cmd/dist/main.go
@@ -8,22 +8,158 @@
 	"flag"
 	"fmt"
 	"os"
+	"runtime"
 	"strconv"
+	"strings"
 )
 
-// cmdtab records the available commands.
-var cmdtab = []struct {
-	name string
-	f    func()
-}{
-	{"banner", cmdbanner},
-	{"bootstrap", cmdbootstrap},
-	{"clean", cmdclean},
-	{"env", cmdenv},
-	{"install", cmdinstall},
-	{"list", cmdlist},
-	{"test", cmdtest},
-	{"version", cmdversion},
+func usage() {
+	xprintf(`usage: go tool dist [command]
+Commands are:
+
+banner         print installation banner
+bootstrap      rebuild everything
+clean          deletes all built files
+env [-p]       print environment (-p: include $PATH)
+install [dir]  install individual directory
+list [-json]   list all supported platforms
+test [-h]      run Go test(s)
+version        print Go version
+
+All commands take -v flags to emit extra information.
+`)
+	xexit(2)
+}
+
+// commands records the available commands.
+var commands = map[string]func(){
+	"banner":    cmdbanner,
+	"bootstrap": cmdbootstrap,
+	"clean":     cmdclean,
+	"env":       cmdenv,
+	"install":   cmdinstall,
+	"list":      cmdlist,
+	"test":      cmdtest,
+	"version":   cmdversion,
+}
+
+// main takes care of OS-specific startup and dispatches to xmain.
+func main() {
+	os.Setenv("TERM", "dumb") // disable escape codes in clang errors
+
+	// provide -check-armv6k first, before checking for $GOROOT so that
+	// it is possible to run this check without having $GOROOT available.
+	if len(os.Args) > 1 && os.Args[1] == "-check-armv6k" {
+		useARMv6K() // might fail with SIGILL
+		println("ARMv6K supported.")
+		os.Exit(0)
+	}
+
+	gohostos = runtime.GOOS
+	switch gohostos {
+	case "darwin":
+		// Even on 64-bit platform, darwin uname -m prints i386.
+		// We don't support any of the OS X versions that run on 32-bit-only hardware anymore.
+		gohostarch = "amd64"
+	case "freebsd":
+		// Since FreeBSD 10 gcc is no longer part of the base system.
+		defaultclang = true
+	case "solaris":
+		// Even on 64-bit platform, solaris uname -m prints i86pc.
+		out := run("", CheckExit, "isainfo", "-n")
+		if strings.Contains(out, "amd64") {
+			gohostarch = "amd64"
+		}
+		if strings.Contains(out, "i386") {
+			gohostarch = "386"
+		}
+	case "plan9":
+		gohostarch = os.Getenv("objtype")
+		if gohostarch == "" {
+			fatalf("$objtype is unset")
+		}
+	case "windows":
+		exe = ".exe"
+	}
+
+	sysinit()
+
+	if gohostarch == "" {
+		// Default Unix system.
+		out := run("", CheckExit, "uname", "-m")
+		switch {
+		case strings.Contains(out, "x86_64"), strings.Contains(out, "amd64"):
+			gohostarch = "amd64"
+		case strings.Contains(out, "86"):
+			gohostarch = "386"
+		case strings.Contains(out, "arm"):
+			gohostarch = "arm"
+		case strings.Contains(out, "aarch64"):
+			gohostarch = "arm64"
+		case strings.Contains(out, "ppc64le"):
+			gohostarch = "ppc64le"
+		case strings.Contains(out, "ppc64"):
+			gohostarch = "ppc64"
+		case strings.Contains(out, "mips64"):
+			gohostarch = "mips64"
+			if elfIsLittleEndian(os.Args[0]) {
+				gohostarch = "mips64le"
+			}
+		case strings.Contains(out, "mips"):
+			gohostarch = "mips"
+			if elfIsLittleEndian(os.Args[0]) {
+				gohostarch = "mipsle"
+			}
+		case strings.Contains(out, "s390x"):
+			gohostarch = "s390x"
+		case gohostos == "darwin":
+			if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM_") {
+				gohostarch = "arm"
+			}
+		default:
+			fatalf("unknown architecture: %s", out)
+		}
+	}
+
+	if gohostarch == "arm" || gohostarch == "mips64" || gohostarch == "mips64le" {
+		maxbg = min(maxbg, runtime.NumCPU())
+	}
+	bginit()
+
+	// The OS X 10.6 linker does not support external linking mode.
+	// See golang.org/issue/5130.
+	//
+	// OS X 10.6 does not work with clang either, but OS X 10.9 requires it.
+	// It seems to work with OS X 10.8, so we default to clang for 10.8 and later.
+	// See golang.org/issue/5822.
+	//
+	// 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 gohostos == "darwin" {
+		rel := run("", CheckExit, "uname", "-r")
+		if i := strings.Index(rel, "."); i >= 0 {
+			rel = rel[:i]
+		}
+		osx, _ := strconv.Atoi(rel)
+		if osx <= 6+4 {
+			goextlinkenabled = "0"
+		}
+		if osx >= 8+4 {
+			defaultclang = true
+		}
+	}
+
+	if len(os.Args) > 1 && os.Args[1] == "-check-goarm" {
+		useVFPv1() // might fail with SIGILL
+		println("VFPv1 OK.")
+		useVFPv3() // might fail with SIGILL
+		println("VFPv3 OK.")
+		os.Exit(0)
+	}
+
+	xinit()
+	xmain()
+	xexit(0)
 }
 
 // The OS-specific main calls into the portable code here.
@@ -33,55 +169,15 @@
 	}
 	cmd := os.Args[1]
 	os.Args = os.Args[1:] // for flag parsing during cmd
-	for _, ct := range cmdtab {
-		if ct.name == cmd {
-			flag.Usage = func() {
-				fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd)
-				flag.PrintDefaults()
-				os.Exit(2)
-			}
-			ct.f()
-			return
-		}
+	flag.Usage = func() {
+		fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd)
+		flag.PrintDefaults()
+		os.Exit(2)
 	}
-
-	xprintf("unknown command %s\n", cmd)
-	usage()
-}
-
-func xflagparse(maxargs int) {
-	flag.Var((*count)(&vflag), "v", "verbosity")
-	flag.Parse()
-	if maxargs >= 0 && flag.NArg() > maxargs {
-		flag.Usage()
+	if f, ok := commands[cmd]; ok {
+		f()
+	} else {
+		xprintf("unknown command %s\n", cmd)
+		usage()
 	}
 }
-
-// count is a flag.Value that is like a flag.Bool and a flag.Int.
-// If used as -name, it increments the count, but -name=x sets the count.
-// Used for verbose flag -v.
-type count int
-
-func (c *count) String() string {
-	return fmt.Sprint(int(*c))
-}
-
-func (c *count) Set(s string) error {
-	switch s {
-	case "true":
-		*c++
-	case "false":
-		*c = 0
-	default:
-		n, err := strconv.Atoi(s)
-		if err != nil {
-			return fmt.Errorf("invalid count %q", s)
-		}
-		*c = count(n)
-	}
-	return nil
-}
-
-func (c *count) IsBoolFlag() bool {
-	return true
-}
diff --git a/src/cmd/dist/mkdeps.bash b/src/cmd/dist/mkdeps.bash
deleted file mode 100755
index 71d3c37..0000000
--- a/src/cmd/dist/mkdeps.bash
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-# Copyright 2015 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-set -e
-
-# We need to test enough GOOS/GOARCH combinations to pick up all the
-# package dependencies.
-gooslist="windows linux darwin solaris"
-goarchlist="386 amd64 arm arm64 ppc64"
-
-echo NOTE: errors about loading internal/syscall/windows are ok
-
-deps_of() {
-	for goos in $gooslist
-	do
-		for goarch in $goarchlist
-		do
-			GOOS=$goos GOARCH=$goarch go list -tags cmd_go_bootstrap -f '{{range .Deps}}{{$.ImportPath}} {{.}}
-{{end}}' $*
-		done
-	done | sort -u | grep . | grep -v ' unsafe$'
-}
-
-all="$(deps_of cmd/go | awk '{print $2}') cmd/go"
-deps_of $all >tmp.all.deps
-
-(
-	echo '// generated by mkdeps.bash'
-	echo
-	echo 'package main'
-	echo
-	echo 'var builddeps = map[string][]string{'
-	for pkg in $all
-	do
-		echo -n "\"$pkg\": {"
-		for dep in $(awk -v pkg=$pkg '$1==pkg {print $2}' tmp.all.deps)
-		do
-			echo -n "\"$dep\","
-		done
-		echo '},'
-	done
-	echo '}'
-) |gofmt >deps.go
-
-rm -f tmp.all.deps
diff --git a/src/cmd/dist/sys_windows.go b/src/cmd/dist/sys_windows.go
index 05cb3e2..6d1f82e 100644
--- a/src/cmd/dist/sys_windows.go
+++ b/src/cmd/dist/sys_windows.go
@@ -44,6 +44,6 @@
 	case PROCESSOR_ARCHITECTURE_INTEL:
 		gohostarch = "386"
 	default:
-		fatal("unknown processor architecture")
+		fatalf("unknown processor architecture")
 	}
 }
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 73432d3..bc1f733 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -14,6 +14,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"reflect"
 	"regexp"
 	"runtime"
 	"strconv"
@@ -23,6 +24,8 @@
 )
 
 func cmdtest() {
+	gogcflags = os.Getenv("GO_GCFLAGS")
+
 	var t tester
 	var noRebuild bool
 	flag.BoolVar(&t.listMode, "list", false, "list available tests")
@@ -57,11 +60,6 @@
 	banner      string   // prefix, or "" for none
 	lastHeading string   // last dir heading printed
 
-	goroot     string
-	goarch     string
-	gohostarch string
-	goos       string
-	gohostos   string
 	cgoEnabled bool
 	partial    bool
 	haveTime   bool // the 'time' binary is available
@@ -89,20 +87,17 @@
 	fn      func(*distTest) error
 }
 
-func mustEnv(k string) string {
-	v := os.Getenv(k)
-	if v == "" {
-		log.Fatalf("Unset environment variable %v", k)
-	}
-	return v
-}
-
 func (t *tester) run() {
-	t.goroot = mustEnv("GOROOT")
-	t.goos = mustEnv("GOOS")
-	t.gohostos = mustEnv("GOHOSTOS")
-	t.goarch = mustEnv("GOARCH")
-	t.gohostarch = mustEnv("GOHOSTARCH")
+	timelog("start", "dist test")
+
+	var exeSuffix string
+	if goos == "windows" {
+		exeSuffix = ".exe"
+	}
+	if _, err := os.Stat(filepath.Join(gobin, "go"+exeSuffix)); err == nil {
+		os.Setenv("PATH", fmt.Sprintf("%s%c%s", gobin, os.PathListSeparator, os.Getenv("PATH")))
+	}
+
 	slurp, err := exec.Command("go", "env", "CGO_ENABLED").Output()
 	if err != nil {
 		log.Fatalf("Error running go env CGO_ENABLED: %v", err)
@@ -111,6 +106,7 @@
 	if flag.NArg() > 0 && t.runRxStr != "" {
 		log.Fatalf("the -run regular expression flag is mutually exclusive with test name arguments")
 	}
+
 	t.runNames = flag.Args()
 
 	if t.hasBash() {
@@ -121,39 +117,31 @@
 
 	if t.rebuild {
 		t.out("Building packages and commands.")
-		cmd := exec.Command("go", "install", "-a", "-v", "std", "cmd")
-		cmd.Stdout = os.Stdout
-		cmd.Stderr = os.Stderr
-		if err := cmd.Run(); err != nil {
-			log.Fatalf("building packages and commands: %v", err)
-		}
+		// Force rebuild the whole toolchain.
+		goInstall("go", append([]string{"-a", "-i"}, toolchain...)...)
 	}
 
-	if t.iOS() {
-		// Install the Mach exception handler used to intercept
-		// EXC_BAD_ACCESS and convert it into a Go panic. This is
-		// necessary for a Go program running under lldb (the way
-		// we run tests). It is disabled by default because iOS
-		// apps are not allowed to access the exc_server symbol.
-		cmd := exec.Command("go", "install", "-a", "-tags", "lldb", "runtime/cgo")
-		cmd.Stdout = os.Stdout
-		cmd.Stderr = os.Stderr
-		if err := cmd.Run(); err != nil {
-			log.Fatalf("building mach exception handler: %v", err)
-		}
-
-		defer func() {
-			cmd := exec.Command("go", "install", "-a", "runtime/cgo")
-			cmd.Stdout = os.Stdout
-			cmd.Stderr = os.Stderr
-			if err := cmd.Run(); err != nil {
-				log.Fatalf("reverting mach exception handler: %v", err)
-			}
-		}()
+	// Complete rebuild bootstrap, even with -no-rebuild.
+	// If everything is up-to-date, this is a no-op.
+	// If everything is not up-to-date, the first checkNotStale
+	// during the test process will kill the tests, so we might
+	// as well install the world.
+	// Now that for example "go install cmd/compile" does not
+	// also install runtime (you need "go install -i cmd/compile"
+	// for that), it's easy for previous workflows like
+	// "rebuild the compiler and then run run.bash"
+	// to break if we don't automatically refresh things here.
+	// Rebuilding is a shortened bootstrap.
+	// See cmdbootstrap for a description of the overall process.
+	if !t.listMode {
+		goInstall("go", append([]string{"-i"}, toolchain...)...)
+		goInstall("go", append([]string{"-i"}, toolchain...)...)
+		goInstall("go", "std", "cmd")
+		checkNotStale("go", "std", "cmd")
 	}
 
 	t.timeoutScale = 1
-	switch t.goarch {
+	switch goarch {
 	case "arm":
 		t.timeoutScale = 2
 	case "mips", "mipsle", "mips64", "mips64le":
@@ -184,9 +172,13 @@
 		return
 	}
 
-	// we must unset GOROOT_FINAL before tests, because runtime/debug requires
+	// We must unset GOROOT_FINAL before tests, because runtime/debug requires
 	// correct access to source code, so if we have GOROOT_FINAL in effect,
 	// at least runtime/debug test will fail.
+	// If GOROOT_FINAL was set before, then now all the commands will appear stale.
+	// Nothing we can do about that other than not checking them below.
+	// (We call checkNotStale but only with "std" not "cmd".)
+	os.Setenv("GOROOT_FINAL_OLD", os.Getenv("GOROOT_FINAL")) // for cmd/link test
 	os.Unsetenv("GOROOT_FINAL")
 
 	for _, name := range t.runNames {
@@ -212,6 +204,7 @@
 		}
 	}
 	t.runPending(nil)
+	timelog("end", "dist test")
 	if t.failed {
 		fmt.Println("\nFAILED")
 		os.Exit(1)
@@ -237,6 +230,15 @@
 	return false
 }
 
+// goTest returns the beginning of the go test command line.
+// Callers should use goTest and then pass flags overriding these
+// defaults as later arguments in the command line.
+func (t *tester) goTest() []string {
+	return []string{
+		"go", "test", "-short", "-count=1", t.tags(), t.runFlag(""),
+	}
+}
+
 func (t *tester) tags() string {
 	if t.iOS() {
 		return "-tags=lldb"
@@ -267,6 +269,10 @@
 	if t.runRx == nil || t.runRx.MatchString(testName) == t.runRxWant {
 		stdMatches = append(stdMatches, pkg)
 	}
+	timeoutSec := 180
+	if pkg == "cmd/go" {
+		timeoutSec *= 2
+	}
 	t.tests = append(t.tests, distTest{
 		name:    testName,
 		heading: "Testing packages.",
@@ -275,13 +281,15 @@
 				return nil
 			}
 			t.runPending(dt)
+			timelog("start", dt.name)
+			defer timelog("end", dt.name)
 			ranGoTest = true
 			args := []string{
 				"test",
 				"-short",
 				t.tags(),
-				t.timeout(180),
-				"-gcflags=" + os.Getenv("GO_GCFLAGS"),
+				t.timeout(timeoutSec),
+				"-gcflags=all=" + gogcflags,
 			}
 			if t.race {
 				args = append(args, "-race")
@@ -311,6 +319,8 @@
 				return nil
 			}
 			t.runPending(dt)
+			timelog("start", dt.name)
+			defer timelog("end", dt.name)
 			ranGoBench = true
 			args := []string{
 				"test",
@@ -343,7 +353,7 @@
 			osarch := k
 			t.tests = append(t.tests, distTest{
 				name:    "vet/" + osarch,
-				heading: "go vet std cmd",
+				heading: "cmd/vet/all",
 				fn: func(dt *distTest) error {
 					t.addCmd(dt, "src/cmd/vet/all", "go", "run", "main.go", "-p="+osarch)
 					return nil
@@ -353,27 +363,6 @@
 		return
 	}
 
-	// This test needs its stdout/stderr to be terminals, so we don't run it from cmd/go's tests.
-	// See issue 18153.
-	if t.goos == "linux" {
-		t.tests = append(t.tests, distTest{
-			name:    "cmd_go_test_terminal",
-			heading: "cmd/go terminal test",
-			fn: func(dt *distTest) error {
-				t.runPending(dt)
-				if !stdOutErrAreTerminals() {
-					fmt.Println("skipping terminal test; stdout/stderr not terminals")
-					return nil
-				}
-				cmd := exec.Command("go", "test")
-				cmd.Dir = filepath.Join(os.Getenv("GOROOT"), "src/cmd/go/testdata/testterminal18153")
-				cmd.Stdout = os.Stdout
-				cmd.Stderr = os.Stderr
-				return cmd.Run()
-			},
-		})
-	}
-
 	// Fast path to avoid the ~1 second of `go list std cmd` when
 	// the caller lists specific tests to run. (as the continuous
 	// build coordinator does).
@@ -391,7 +380,7 @@
 		const format = "{{if (or .TestGoFiles .XTestGoFiles)}}{{.ImportPath}}{{end}}"
 		cmd := exec.Command("go", "list", "-f", format)
 		if t.race {
-			cmd.Args = append(cmd.Args, "-tags", "race")
+			cmd.Args = append(cmd.Args, "-tags=race")
 		}
 		cmd.Args = append(cmd.Args, "std")
 		if !t.race {
@@ -423,9 +412,9 @@
 		testName := "runtime:cpu124"
 		t.tests = append(t.tests, distTest{
 			name:    testName,
-			heading: "GOMAXPROCS=2 runtime -cpu=1,2,4",
+			heading: "GOMAXPROCS=2 runtime -cpu=1,2,4 -quick",
 			fn: func(dt *distTest) error {
-				cmd := t.addCmd(dt, "src", "go", "test", "-short", t.timeout(300), t.tags(), "runtime", "-cpu=1,2,4")
+				cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(300), "runtime", "-cpu=1,2,4", "-quick")
 				// We set GOMAXPROCS=2 in addition to -cpu=1,2,4 in order to test runtime bootstrap code,
 				// creation of first goroutines and first garbage collections in the parallel setting.
 				cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
@@ -434,20 +423,45 @@
 		})
 	}
 
+	// This test needs its stdout/stderr to be terminals, so we don't run it from cmd/go's tests.
+	// See issue 18153.
+	if goos == "linux" {
+		t.tests = append(t.tests, distTest{
+			name:    "cmd_go_test_terminal",
+			heading: "cmd/go terminal test",
+			fn: func(dt *distTest) error {
+				t.runPending(dt)
+				timelog("start", dt.name)
+				defer timelog("end", dt.name)
+				if !stdOutErrAreTerminals() {
+					fmt.Println("skipping terminal test; stdout/stderr not terminals")
+					return nil
+				}
+				cmd := exec.Command("go", "test")
+				cmd.Dir = filepath.Join(os.Getenv("GOROOT"), "src/cmd/go/testdata/testterminal18153")
+				cmd.Stdout = os.Stdout
+				cmd.Stderr = os.Stderr
+				return cmd.Run()
+			},
+		})
+	}
+
 	// On the builders only, test that a moved GOROOT still works.
 	// Fails on iOS because CC_FOR_TARGET refers to clangwrap.sh
 	// in the unmoved GOROOT.
 	// Fails on Android with an exec format error.
 	// Fails on plan9 with "cannot find GOROOT" (issue #21016).
-	if os.Getenv("GO_BUILDER_NAME") != "" && t.goos != "android" && !t.iOS() && t.goos != "plan9" {
+	if os.Getenv("GO_BUILDER_NAME") != "" && goos != "android" && !t.iOS() && goos != "plan9" {
 		t.tests = append(t.tests, distTest{
 			name:    "moved_goroot",
 			heading: "moved GOROOT",
 			fn: func(dt *distTest) error {
 				t.runPending(dt)
-				moved := t.goroot + "-moved"
-				if err := os.Rename(t.goroot, moved); err != nil {
-					if t.goos == "windows" {
+				timelog("start", dt.name)
+				defer timelog("end", dt.name)
+				moved := goroot + "-moved"
+				if err := os.Rename(goroot, moved); err != nil {
+					if goos == "windows" {
 						// Fails on Windows (with "Access is denied") if a process
 						// or binary is in this directory. For instance, using all.bat
 						// when run from c:\workdir\go\src fails here
@@ -462,18 +476,20 @@
 				}
 
 				// Run `go test fmt` in the moved GOROOT.
+				// Disable GOCACHE because it points back at the old GOROOT.
 				cmd := exec.Command(filepath.Join(moved, "bin", "go"), "test", "fmt")
 				cmd.Stdout = os.Stdout
 				cmd.Stderr = os.Stderr
 				// Don't set GOROOT in the environment.
 				for _, e := range os.Environ() {
-					if !strings.HasPrefix(e, "GOROOT=") {
+					if !strings.HasPrefix(e, "GOROOT=") && !strings.HasPrefix(e, "GOCACHE=") {
 						cmd.Env = append(cmd.Env, e)
 					}
 				}
+				cmd.Env = append(cmd.Env, "GOCACHE=off")
 				err := cmd.Run()
 
-				if rerr := os.Rename(moved, t.goroot); rerr != nil {
+				if rerr := os.Rename(moved, goroot); rerr != nil {
 					log.Fatalf("failed to restore GOROOT: %v", rerr)
 				}
 				return err
@@ -491,7 +507,7 @@
 		}
 
 		// ARM libgcc may be Thumb, which internal linking does not support.
-		if t.goarch == "arm" {
+		if goarch == "arm" {
 			break
 		}
 
@@ -504,14 +520,14 @@
 			name:    "nolibgcc:" + pkg,
 			heading: "Testing without libgcc.",
 			fn: func(dt *distTest) error {
-				t.addCmd(dt, "src", "go", "test", "-short", "-ldflags=-linkmode=internal -libgcc=none", t.tags(), pkg, t.runFlag(run))
+				t.addCmd(dt, "src", t.goTest(), "-ldflags=-linkmode=internal -libgcc=none", pkg, t.runFlag(run))
 				return nil
 			},
 		})
 	}
 
 	// Test internal linking of PIE binaries where it is supported.
-	if t.goos == "linux" && t.goarch == "amd64" && !isAlpineLinux() {
+	if goos == "linux" && goarch == "amd64" && !isAlpineLinux() {
 		// Issue 18243: We don't have a way to set the default
 		// dynamic linker used in internal linking mode. So
 		// this test is skipped on Alpine.
@@ -519,7 +535,7 @@
 			name:    "pie_internal",
 			heading: "internal linking of -buildmode=pie",
 			fn: func(dt *distTest) error {
-				t.addCmd(dt, "src", "go", "test", "reflect", "-short", "-buildmode=pie", "-ldflags=-linkmode=internal", t.timeout(60), t.tags(), t.runFlag(""))
+				t.addCmd(dt, "src", t.goTest(), "reflect", "-buildmode=pie", "-ldflags=-linkmode=internal", t.timeout(60))
 				return nil
 			},
 		})
@@ -530,11 +546,19 @@
 		name:    "sync_cpu",
 		heading: "sync -cpu=10",
 		fn: func(dt *distTest) error {
-			t.addCmd(dt, "src", "go", "test", "sync", "-short", t.timeout(120), t.tags(), "-cpu=10", t.runFlag(""))
+			t.addCmd(dt, "src", t.goTest(), "sync", t.timeout(120), "-cpu=10", t.runFlag(""))
 			return nil
 		},
 	})
 
+	if t.raceDetectorSupported() {
+		t.tests = append(t.tests, distTest{
+			name:    "race",
+			heading: "Testing race detector",
+			fn:      t.raceTest,
+		})
+	}
+
 	if t.cgoEnabled && !t.iOS() {
 		// Disabled on iOS. golang.org/issue/15919
 		t.tests = append(t.tests, distTest{
@@ -567,6 +591,26 @@
 				},
 			})
 		}
+		if t.hasSwig() && goos != "android" {
+			t.tests = append(t.tests, distTest{
+				name:    "swig_stdio",
+				heading: "../misc/swig/stdio",
+				fn: func(dt *distTest) error {
+					t.addCmd(dt, "misc/swig/stdio", t.goTest())
+					return nil
+				},
+			})
+			if cxx, _ := exec.LookPath(compilerEnvLookup(defaultcxx, goos, goarch)); cxx != "" {
+				t.tests = append(t.tests, distTest{
+					name:    "swig_callback",
+					heading: "../misc/swig/callback",
+					fn: func(dt *distTest) error {
+						t.addCmd(dt, "misc/swig/callback", t.goTest())
+						return nil
+					},
+				})
+			}
+		}
 	}
 	if t.cgoEnabled {
 		t.tests = append(t.tests, distTest{
@@ -576,18 +620,15 @@
 		})
 	}
 
-	if t.raceDetectorSupported() {
-		t.tests = append(t.tests, distTest{
-			name:    "race",
-			heading: "Testing race detector",
-			fn:      t.raceTest,
-		})
-	}
-
-	if t.hasBash() && t.cgoEnabled && t.goos != "android" && t.goos != "darwin" {
+	if t.hasBash() && t.cgoEnabled && goos != "android" && goos != "darwin" {
 		t.registerTest("testgodefs", "../misc/cgo/testgodefs", "./test.bash")
 	}
-	if t.cgoEnabled {
+
+	// Don't run these tests with $GO_GCFLAGS because most of them
+	// assume that they can run "go install" with no -gcflags and not
+	// recompile the entire standard library. If make.bash ran with
+	// special -gcflags, that's not true.
+	if t.cgoEnabled && gogcflags == "" {
 		if t.cgoTestSOSupported() {
 			t.tests = append(t.tests, distTest{
 				name:    "testso",
@@ -608,40 +649,40 @@
 			t.registerHostTest("testcarchive", "../misc/cgo/testcarchive", "misc/cgo/testcarchive", "carchive_test.go")
 		}
 		if t.supportedBuildmode("c-shared") {
-			t.registerTest("testcshared", "../misc/cgo/testcshared", "./test.bash")
+			t.registerHostTest("testcshared", "../misc/cgo/testcshared", "misc/cgo/testcshared", "cshared_test.go")
 		}
 		if t.supportedBuildmode("shared") {
-			t.registerTest("testshared", "../misc/cgo/testshared", "go", "test")
+			t.registerTest("testshared", "../misc/cgo/testshared", t.goTest(), t.timeout(600))
 		}
 		if t.supportedBuildmode("plugin") {
 			t.registerTest("testplugin", "../misc/cgo/testplugin", "./test.bash")
 		}
-		if t.gohostos == "linux" && t.goarch == "amd64" {
+		if gohostos == "linux" && goarch == "amd64" {
 			t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", "main.go")
 		}
-		if t.goos == "linux" && t.goarch == "amd64" {
-			t.registerTest("testsanitizers", "../misc/cgo/testsanitizers", "./test.bash")
+		if goos == "linux" && goarch == "amd64" {
+			t.registerHostTest("testsanitizers/msan", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".")
 		}
-		if t.hasBash() && t.goos != "android" && !t.iOS() && t.gohostos != "windows" {
-			t.registerTest("cgo_errors", "../misc/cgo/errors", "./test.bash")
+		if t.hasBash() && goos != "android" && !t.iOS() && gohostos != "windows" {
+			t.registerHostTest("cgo_errors", "../misc/cgo/errors", "misc/cgo/errors", ".")
 		}
-		if t.gohostos == "linux" && t.extLink() {
+		if gohostos == "linux" && t.extLink() {
 			t.registerTest("testsigfwd", "../misc/cgo/testsigfwd", "go", "run", "main.go")
 		}
 	}
 
 	// Doc tests only run on builders.
 	// They find problems approximately never.
-	if t.hasBash() && t.goos != "nacl" && t.goos != "android" && !t.iOS() && os.Getenv("GO_BUILDER_NAME") != "" {
+	if t.hasBash() && goos != "nacl" && goos != "android" && !t.iOS() && os.Getenv("GO_BUILDER_NAME") != "" {
 		t.registerTest("doc_progs", "../doc/progs", "time", "go", "run", "run.go")
 		t.registerTest("wiki", "../doc/articles/wiki", "./test.bash")
 		t.registerTest("codewalk", "../doc/codewalk", "time", "./run")
 	}
 
-	if t.goos != "android" && !t.iOS() {
-		t.registerTest("bench_go1", "../test/bench/go1", "go", "test", t.timeout(600), t.runFlag(""))
+	if goos != "android" && !t.iOS() {
+		t.registerTest("bench_go1", "../test/bench/go1", t.goTest(), t.timeout(600))
 	}
-	if t.goos != "android" && !t.iOS() {
+	if goos != "android" && !t.iOS() {
 		// Only start multiple test dir shards on builders,
 		// where they get distributed to multiple machines.
 		// See issue 20141.
@@ -658,16 +699,16 @@
 			})
 		}
 	}
-	if t.goos != "nacl" && t.goos != "android" && !t.iOS() {
+	if goos != "nacl" && goos != "android" && !t.iOS() {
 		t.tests = append(t.tests, distTest{
 			name:    "api",
 			heading: "API check",
 			fn: func(dt *distTest) error {
 				if t.compileOnly {
-					t.addCmd(dt, "src", "go", "build", filepath.Join(t.goroot, "src/cmd/api/run.go"))
+					t.addCmd(dt, "src", "go", "build", filepath.Join(goroot, "src/cmd/api/run.go"))
 					return nil
 				}
-				t.addCmd(dt, "src", "go", "run", filepath.Join(t.goroot, "src/cmd/api/run.go"))
+				t.addCmd(dt, "src", "go", "run", filepath.Join(goroot, "src/cmd/api/run.go"))
 				return nil
 			},
 		})
@@ -685,7 +726,8 @@
 	return false
 }
 
-func (t *tester) registerTest1(seq bool, name, dirBanner, bin string, args ...string) {
+func (t *tester) registerTest1(seq bool, name, dirBanner string, cmdline ...interface{}) {
+	bin, args := flattenCmdline(cmdline)
 	if bin == "time" && !t.haveTime {
 		bin, args = args[0], args[1:]
 	}
@@ -698,20 +740,22 @@
 		fn: func(dt *distTest) error {
 			if seq {
 				t.runPending(dt)
-				return t.dirCmd(filepath.Join(t.goroot, "src", dirBanner), bin, args...).Run()
+				timelog("start", name)
+				defer timelog("end", name)
+				return t.dirCmd(filepath.Join(goroot, "src", dirBanner), bin, args).Run()
 			}
-			t.addCmd(dt, filepath.Join(t.goroot, "src", dirBanner), bin, args...)
+			t.addCmd(dt, filepath.Join(goroot, "src", dirBanner), bin, args)
 			return nil
 		},
 	})
 }
 
-func (t *tester) registerTest(name, dirBanner, bin string, args ...string) {
-	t.registerTest1(false, name, dirBanner, bin, args...)
+func (t *tester) registerTest(name, dirBanner string, cmdline ...interface{}) {
+	t.registerTest1(false, name, dirBanner, cmdline...)
 }
 
-func (t *tester) registerSeqTest(name, dirBanner, bin string, args ...string) {
-	t.registerTest1(true, name, dirBanner, bin, args...)
+func (t *tester) registerSeqTest(name, dirBanner string, cmdline ...interface{}) {
+	t.registerTest1(true, name, dirBanner, cmdline...)
 }
 
 func (t *tester) bgDirCmd(dir, bin string, args ...string) *exec.Cmd {
@@ -719,12 +763,13 @@
 	if filepath.IsAbs(dir) {
 		cmd.Dir = dir
 	} else {
-		cmd.Dir = filepath.Join(t.goroot, dir)
+		cmd.Dir = filepath.Join(goroot, dir)
 	}
 	return cmd
 }
 
-func (t *tester) dirCmd(dir, bin string, args ...string) *exec.Cmd {
+func (t *tester) dirCmd(dir string, cmdline ...interface{}) *exec.Cmd {
+	bin, args := flattenCmdline(cmdline)
 	cmd := t.bgDirCmd(dir, bin, args...)
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
@@ -734,7 +779,52 @@
 	return cmd
 }
 
-func (t *tester) addCmd(dt *distTest, dir, bin string, args ...string) *exec.Cmd {
+// flattenCmdline flattens a mixture of string and []string as single list
+// and then interprets it as a command line: first element is binary, then args.
+func flattenCmdline(cmdline []interface{}) (bin string, args []string) {
+	var list []string
+	for _, x := range cmdline {
+		switch x := x.(type) {
+		case string:
+			list = append(list, x)
+		case []string:
+			list = append(list, x...)
+		default:
+			panic("invalid addCmd argument type: " + reflect.TypeOf(x).String())
+		}
+	}
+
+	// The go command is too picky about duplicated flags.
+	// Drop all but the last of the allowed duplicated flags.
+	drop := make([]bool, len(list))
+	have := map[string]int{}
+	for i := 1; i < len(list); i++ {
+		j := strings.Index(list[i], "=")
+		if j < 0 {
+			continue
+		}
+		flag := list[i][:j]
+		switch flag {
+		case "-run", "-tags":
+			if have[flag] != 0 {
+				drop[have[flag]] = true
+			}
+			have[flag] = i
+		}
+	}
+	out := list[:0]
+	for i, x := range list {
+		if !drop[i] {
+			out = append(out, x)
+		}
+	}
+	list = out
+
+	return list[0], list[1:]
+}
+
+func (t *tester) addCmd(dt *distTest, dir string, cmdline ...interface{}) *exec.Cmd {
+	bin, args := flattenCmdline(cmdline)
 	w := &work{
 		dt:  dt,
 		cmd: t.bgDirCmd(dir, bin, args...),
@@ -744,7 +834,7 @@
 }
 
 func (t *tester) iOS() bool {
-	return t.goos == "darwin" && (t.goarch == "arm" || t.goarch == "arm64")
+	return goos == "darwin" && (goarch == "arm" || goarch == "arm64")
 }
 
 func (t *tester) out(v string) {
@@ -755,11 +845,11 @@
 }
 
 func (t *tester) extLink() bool {
-	pair := t.gohostos + "-" + t.goarch
+	pair := gohostos + "-" + goarch
 	switch pair {
 	case "android-arm",
 		"darwin-arm", "darwin-arm64",
-		"dragonfly-386", "dragonfly-amd64",
+		"dragonfly-amd64",
 		"freebsd-386", "freebsd-amd64", "freebsd-arm",
 		"linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-mips64", "linux-mips64le", "linux-mips", "linux-mipsle", "linux-s390x",
 		"netbsd-386", "netbsd-amd64",
@@ -780,25 +870,25 @@
 }
 
 func (t *tester) internalLink() bool {
-	if t.gohostos == "dragonfly" {
+	if gohostos == "dragonfly" {
 		// linkmode=internal fails on dragonfly since errno is a TLS relocation.
 		return false
 	}
-	if t.gohostarch == "ppc64le" {
+	if gohostarch == "ppc64le" {
 		// linkmode=internal fails on ppc64le because cmd/link doesn't
 		// handle the TOC correctly (issue 15409).
 		return false
 	}
-	if t.goos == "android" {
+	if goos == "android" {
 		return false
 	}
-	if t.goos == "darwin" && (t.goarch == "arm" || t.goarch == "arm64") {
+	if goos == "darwin" && (goarch == "arm" || goarch == "arm64") {
 		return false
 	}
 	// Internally linking cgo is incomplete on some architectures.
 	// https://golang.org/issue/10373
 	// https://golang.org/issue/14449
-	if t.goarch == "arm64" || t.goarch == "mips64" || t.goarch == "mips64le" || t.goarch == "mips" || t.goarch == "mipsle" {
+	if goarch == "arm64" || goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" {
 		return false
 	}
 	if isAlpineLinux() {
@@ -809,7 +899,7 @@
 }
 
 func (t *tester) supportedBuildmode(mode string) bool {
-	pair := t.goos + "-" + t.goarch
+	pair := goos + "-" + goarch
 	switch mode {
 	case "c-archive":
 		if !t.extLink() {
@@ -817,16 +907,17 @@
 		}
 		switch pair {
 		case "darwin-386", "darwin-amd64", "darwin-arm", "darwin-arm64",
-			"linux-amd64", "linux-386", "linux-ppc64le",
+			"linux-amd64", "linux-386", "linux-ppc64le", "linux-s390x",
 			"windows-amd64", "windows-386":
 			return true
 		}
 		return false
 	case "c-shared":
 		switch pair {
-		case "linux-386", "linux-amd64", "linux-arm", "linux-arm64",
+		case "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-s390x",
 			"darwin-amd64", "darwin-386",
-			"android-arm", "android-arm64", "android-386":
+			"android-arm", "android-arm64", "android-386",
+			"windows-amd64", "windows-386":
 			return true
 		}
 		return false
@@ -837,21 +928,25 @@
 		}
 		return false
 	case "plugin":
-		if os.Getenv("GO_BUILDER_NAME") == "linux-amd64-noopt" {
-			// Skip the plugin tests on noopt. They're
-			// causing build failures potentially
-			// obscuring other issues. This is hopefully a
-			// temporary workaround. See golang.org/issue/17937.
-			return false
-		}
-
 		// linux-arm64 is missing because it causes the external linker
 		// to crash, see https://golang.org/issue/17138
 		switch pair {
-		case "linux-386", "linux-amd64", "linux-arm", "linux-s390x":
+		case "linux-386", "linux-amd64", "linux-arm", "linux-s390x", "linux-ppc64le":
+			return true
+		case "darwin-amd64":
 			return true
 		}
 		return false
+	case "pie":
+		switch pair {
+		case "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-s390x",
+			"android-amd64", "android-arm", "android-arm64", "android-386":
+			return true
+		case "darwin-amd64":
+			return true
+		}
+		return false
+
 	default:
 		log.Fatalf("internal error: unknown buildmode %s", mode)
 		return false
@@ -864,15 +959,17 @@
 		heading: heading,
 		fn: func(dt *distTest) error {
 			t.runPending(dt)
+			timelog("start", name)
+			defer timelog("end", name)
 			return t.runHostTest(dir, pkg)
 		},
 	})
 }
 
 func (t *tester) runHostTest(dir, pkg string) error {
-	defer os.Remove(filepath.Join(t.goroot, dir, "test.test"))
-	cmd := t.dirCmd(dir, "go", "test", t.tags(), "-c", "-o", "test.test", pkg)
-	cmd.Env = append(os.Environ(), "GOARCH="+t.gohostarch, "GOOS="+t.gohostos)
+	defer os.Remove(filepath.Join(goroot, dir, "test.test"))
+	cmd := t.dirCmd(dir, t.goTest(), "-c", "-o", "test.test", pkg)
+	cmd.Env = append(os.Environ(), "GOARCH="+gohostarch, "GOOS="+gohostos)
 	if err := cmd.Run(); err != nil {
 		return err
 	}
@@ -880,17 +977,13 @@
 }
 
 func (t *tester) cgoTest(dt *distTest) error {
-	env := append(os.Environ(), "GOTRACEBACK=2")
-
-	cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", t.tags(), "-ldflags", "-linkmode=auto", t.runFlag(""))
-	cmd.Env = env
+	t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=auto")
 
 	if t.internalLink() {
-		cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", "-ldflags", "-linkmode=internal", t.runFlag(""))
-		cmd.Env = env
+		t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=internal", "-ldflags", "-linkmode=internal")
 	}
 
-	pair := t.gohostos + "-" + t.goarch
+	pair := gohostos + "-" + goarch
 	switch pair {
 	case "darwin-386", "darwin-amd64",
 		"openbsd-386", "openbsd-amd64",
@@ -899,24 +992,17 @@
 		if !t.extLink() {
 			break
 		}
-		cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", "-ldflags", "-linkmode=external")
-		cmd.Env = env
-		cmd = t.addCmd(dt, "misc/cgo/test", "go", "test", "-ldflags", "-linkmode=external -s")
-		cmd.Env = env
+		t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external")
+		t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external -s")
 	case "android-arm",
-		"dragonfly-386", "dragonfly-amd64",
+		"dragonfly-amd64",
 		"freebsd-386", "freebsd-amd64", "freebsd-arm",
 		"linux-386", "linux-amd64", "linux-arm", "linux-ppc64le", "linux-s390x",
 		"netbsd-386", "netbsd-amd64":
 
-		cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", "-ldflags", "-linkmode=external")
-		cmd.Env = env
-
-		cmd = t.addCmd(dt, "misc/cgo/testtls", "go", "test", "-ldflags", "-linkmode=auto")
-		cmd.Env = env
-
-		cmd = t.addCmd(dt, "misc/cgo/testtls", "go", "test", "-ldflags", "-linkmode=external")
-		cmd.Env = env
+		t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external")
+		t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=auto")
+		t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=external")
 
 		switch pair {
 		case "netbsd-386", "netbsd-amd64":
@@ -928,49 +1014,26 @@
 			// static linking on FreeBSD/ARM with clang. (cgo depends on
 			// -fPIC fundamentally.)
 		default:
-			cc := mustEnv("CC")
 			cmd := t.dirCmd("misc/cgo/test",
-				cc, "-xc", "-o", "/dev/null", "-static", "-")
-			cmd.Env = env
+				compilerEnvLookup(defaultcc, goos, goarch), "-xc", "-o", "/dev/null", "-static", "-")
 			cmd.Stdin = strings.NewReader("int main() {}")
 			if err := cmd.Run(); err != nil {
 				fmt.Println("No support for static linking found (lacks libc.a?), skip cgo static linking test.")
 			} else {
-				if t.goos != "android" {
-					cmd = t.addCmd(dt, "misc/cgo/testtls", "go", "test", "-ldflags", `-linkmode=external -extldflags "-static -pthread"`)
-					cmd.Env = env
+				if goos != "android" {
+					t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", `-linkmode=external -extldflags "-static -pthread"`)
 				}
-
-				cmd = t.addCmd(dt, "misc/cgo/nocgo", "go", "test")
-				cmd.Env = env
-
-				cmd = t.addCmd(dt, "misc/cgo/nocgo", "go", "test", "-ldflags", `-linkmode=external`)
-				cmd.Env = env
-
-				if t.goos != "android" {
-					cmd = t.addCmd(dt, "misc/cgo/nocgo", "go", "test", "-ldflags", `-linkmode=external -extldflags "-static -pthread"`)
-					cmd.Env = env
+				t.addCmd(dt, "misc/cgo/nocgo", t.goTest())
+				t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-ldflags", `-linkmode=external`)
+				if goos != "android" {
+					t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-ldflags", `-linkmode=external -extldflags "-static -pthread"`)
 				}
 			}
 
-			if pair != "freebsd-amd64" { // clang -pie fails to link misc/cgo/test
-				cmd := t.dirCmd("misc/cgo/test",
-					cc, "-xc", "-o", "/dev/null", "-pie", "-")
-				cmd.Env = env
-				cmd.Stdin = strings.NewReader("int main() {}")
-				if err := cmd.Run(); err != nil {
-					fmt.Println("No support for -pie found, skip cgo PIE test.")
-				} else {
-					cmd = t.addCmd(dt, "misc/cgo/test", "go", "test", "-ldflags", `-linkmode=external -extldflags "-pie"`)
-					cmd.Env = env
-
-					cmd = t.addCmd(dt, "misc/cgo/testtls", "go", "test", "-ldflags", `-linkmode=external -extldflags "-pie"`)
-					cmd.Env = env
-
-					cmd = t.addCmd(dt, "misc/cgo/nocgo", "go", "test", "-ldflags", `-linkmode=external -extldflags "-pie"`)
-					cmd.Env = env
-
-				}
+			if t.supportedBuildmode("pie") {
+				t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie")
+				t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-buildmode=pie")
+				t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-buildmode=pie")
 			}
 		}
 	}
@@ -985,6 +1048,7 @@
 // running in parallel with earlier tests, or if it has some other reason
 // for needing the earlier tests to be done.
 func (t *tester) runPending(nextTest *distTest) {
+	checkNotStale("go", "std")
 	worklist := t.worklist
 	t.worklist = nil
 	for _, w := range worklist {
@@ -992,10 +1056,13 @@
 		w.end = make(chan bool)
 		go func(w *work) {
 			if !<-w.start {
+				timelog("skip", w.dt.name)
 				w.out = []byte(fmt.Sprintf("skipped due to earlier error\n"))
 			} else {
+				timelog("start", w.dt.name)
 				w.out, w.err = w.cmd.CombinedOutput()
 			}
+			timelog("end", w.dt.name)
 			w.end <- true
 		}(w)
 	}
@@ -1034,6 +1101,7 @@
 			log.Printf("Failed: %v", w.err)
 			t.failed = true
 		}
+		checkNotStale("go", "std")
 	}
 	if t.failed && !t.keepGoing {
 		log.Fatal("FAILED")
@@ -1051,15 +1119,15 @@
 }
 
 func (t *tester) cgoTestSOSupported() bool {
-	if t.goos == "android" || t.iOS() {
+	if goos == "android" || t.iOS() {
 		// No exec facility on Android or iOS.
 		return false
 	}
-	if t.goarch == "ppc64" {
+	if goarch == "ppc64" {
 		// External linking not implemented on ppc64 (issue #8912).
 		return false
 	}
-	if t.goarch == "mips64le" || t.goarch == "mips64" {
+	if goarch == "mips64le" || goarch == "mips64" {
 		// External linking not implemented on mips64.
 		return false
 	}
@@ -1069,7 +1137,10 @@
 func (t *tester) cgoTestSO(dt *distTest, testpath string) error {
 	t.runPending(dt)
 
-	dir := filepath.Join(t.goroot, testpath)
+	timelog("start", dt.name)
+	defer timelog("end", dt.name)
+
+	dir := filepath.Join(goroot, testpath)
 
 	// build shared object
 	output, err := exec.Command("go", "env", "CC").Output()
@@ -1088,7 +1159,7 @@
 
 	ext := "so"
 	args := append(gogccflags, "-shared")
-	switch t.goos {
+	switch goos {
 	case "darwin":
 		ext = "dylib"
 		args = append(args, "-undefined", "suppress", "-flat_namespace")
@@ -1099,7 +1170,7 @@
 	sofname := "libcgosotest." + ext
 	args = append(args, "-o", sofname, "cgoso_c.c")
 
-	if err := t.dirCmd(dir, cc, args...).Run(); err != nil {
+	if err := t.dirCmd(dir, cc, args).Run(); err != nil {
 		return err
 	}
 	defer os.Remove(filepath.Join(dir, sofname))
@@ -1110,16 +1181,16 @@
 	defer os.Remove(filepath.Join(dir, "main.exe"))
 
 	cmd := t.dirCmd(dir, "./main.exe")
-	if t.goos != "windows" {
+	if goos != "windows" {
 		s := "LD_LIBRARY_PATH"
-		if t.goos == "darwin" {
+		if goos == "darwin" {
 			s = "DYLD_LIBRARY_PATH"
 		}
 		cmd.Env = append(os.Environ(), s+"=.")
 
 		// On FreeBSD 64-bit architectures, the 32-bit linker looks for
 		// different environment variables.
-		if t.goos == "freebsd" && t.gohostarch == "386" {
+		if goos == "freebsd" && gohostarch == "386" {
 			cmd.Env = append(cmd.Env, "LD_32_LIBRARY_PATH=.")
 		}
 	}
@@ -1127,19 +1198,93 @@
 }
 
 func (t *tester) hasBash() bool {
-	switch t.gohostos {
+	switch gohostos {
 	case "windows", "plan9":
 		return false
 	}
 	return true
 }
 
+func (t *tester) hasSwig() bool {
+	swig, err := exec.LookPath("swig")
+	if err != nil {
+		return false
+	}
+
+	// Check that swig was installed with Go support by checking
+	// that a go directory exists inside the swiglib directory.
+	// See https://golang.org/issue/23469.
+	output, err := exec.Command(swig, "-go", "-swiglib").Output()
+	if err != nil {
+		return false
+	}
+	swigDir := strings.TrimSpace(string(output))
+
+	_, err = os.Stat(filepath.Join(swigDir, "go"))
+	if err != nil {
+		return false
+	}
+
+	// Check that swig has a new enough version.
+	// See https://golang.org/issue/22858.
+	out, err := exec.Command(swig, "-version").CombinedOutput()
+	if err != nil {
+		return false
+	}
+
+	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
+	matches := re.FindSubmatch(out)
+	if matches == nil {
+		// Can't find version number; hope for the best.
+		return true
+	}
+
+	major, err := strconv.Atoi(string(matches[1]))
+	if err != nil {
+		// Can't find version number; hope for the best.
+		return true
+	}
+	if major < 3 {
+		return false
+	}
+	if major > 3 {
+		// 4.0 or later
+		return true
+	}
+
+	// We have SWIG version 3.x.
+	if len(matches[2]) > 0 {
+		minor, err := strconv.Atoi(string(matches[2][1:]))
+		if err != nil {
+			return true
+		}
+		if minor > 0 {
+			// 3.1 or later
+			return true
+		}
+	}
+
+	// We have SWIG version 3.0.x.
+	if len(matches[3]) > 0 {
+		patch, err := strconv.Atoi(string(matches[3][1:]))
+		if err != nil {
+			return true
+		}
+		if patch < 6 {
+			// Before 3.0.6.
+			return false
+		}
+	}
+
+	return true
+}
+
 func (t *tester) raceDetectorSupported() bool {
-	switch t.gohostos {
+	switch gohostos {
 	case "linux", "darwin", "freebsd", "windows":
 		// The race detector doesn't work on Alpine Linux:
 		// golang.org/issue/14481
-		return t.cgoEnabled && t.goarch == "amd64" && t.gohostos == t.goos && !isAlpineLinux()
+		return t.cgoEnabled && goarch == "amd64" && gohostos == goos && !isAlpineLinux()
 	}
 	return false
 }
@@ -1160,21 +1305,21 @@
 }
 
 func (t *tester) raceTest(dt *distTest) error {
-	t.addCmd(dt, "src", "go", "test", "-race", "-i", "runtime/race", "flag", "os", "os/exec")
-	t.addCmd(dt, "src", "go", "test", "-race", t.runFlag("Output"), "runtime/race")
-	t.addCmd(dt, "src", "go", "test", "-race", "-short", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace"), "flag", "os", "os/exec")
+	t.addCmd(dt, "src", t.goTest(), "-race", "-i", "runtime/race", "flag", "os", "os/exec")
+	t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("Output"), "runtime/race")
+	t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace"), "flag", "os", "os/exec", "encoding/gob")
 	// We don't want the following line, because it
 	// slows down all.bash (by 10 seconds on my laptop).
 	// The race builder should catch any error here, but doesn't.
 	// TODO(iant): Figure out how to catch this.
-	// t.addCmd(dt, "src", "go", "test", "-race", "-run=TestParallelTest", "cmd/go")
+	// t.addCmd(dt, "src", t.goTest(),  "-race", "-run=TestParallelTest", "cmd/go")
 	if t.cgoEnabled {
-		cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", "-race", "-short", t.runFlag(""))
+		cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-race")
 		cmd.Env = append(os.Environ(), "GOTRACEBACK=2")
 	}
 	if t.extLink() {
 		// Test with external linking; see issue 9133.
-		t.addCmd(dt, "src", "go", "test", "-race", "-short", "-ldflags=-linkmode=external", t.runFlag("TestParse|TestEcho|TestStdinCloseRace"), "flag", "os/exec")
+		t.addCmd(dt, "src", t.goTest(), "-race", "-ldflags=-linkmode=external", t.runFlag("TestParse|TestEcho|TestStdinCloseRace"), "flag", "os/exec")
 	}
 	return nil
 }
@@ -1189,7 +1334,7 @@
 	runtest.Do(func() {
 		const exe = "runtest.exe" // named exe for Windows, but harmless elsewhere
 		cmd := t.dirCmd("test", "go", "build", "-o", exe, "run.go")
-		cmd.Env = append(os.Environ(), "GOOS="+t.gohostos, "GOARCH="+t.gohostarch)
+		cmd.Env = append(os.Environ(), "GOOS="+gohostos, "GOARCH="+gohostarch)
 		runtest.exe = filepath.Join(cmd.Dir, exe)
 		if err := cmd.Run(); err != nil {
 			runtest.err = err
@@ -1229,7 +1374,7 @@
 // second or two per package, and this function returns false for
 // about 100 packages.
 func (t *tester) packageHasBenchmarks(pkg string) bool {
-	pkgDir := filepath.Join(t.goroot, "src", pkg)
+	pkgDir := filepath.Join(goroot, "src", pkg)
 	d, err := os.Open(pkgDir)
 	if err != nil {
 		return true // conservatively
diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go
index 511978f..7e27bbb 100644
--- a/src/cmd/dist/util.go
+++ b/src/cmd/dist/util.go
@@ -6,13 +6,13 @@
 
 import (
 	"bytes"
+	"flag"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
-	"runtime"
 	"sort"
 	"strconv"
 	"strings"
@@ -51,18 +51,6 @@
 	return keep
 }
 
-// splitlines returns a slice with the result of splitting
-// the input p after each \n.
-func splitlines(p string) []string {
-	return strings.SplitAfter(p, "\n")
-}
-
-// splitfields replaces the vector v with the result of splitting
-// the input p into non-empty fields containing no spaces.
-func splitfields(p string) []string {
-	return strings.Fields(p)
-}
-
 const (
 	CheckExit = 1 << iota
 	ShowOutput
@@ -74,7 +62,7 @@
 // run runs the command line cmd in dir.
 // If mode has ShowOutput set and Background unset, run passes cmd's output to
 // stdout/stderr directly. Otherwise, run returns cmd's output as a string.
-// If mode has CheckExit set and the command fails, run calls fatal.
+// If mode has CheckExit set and the command fails, run calls fatalf.
 // If mode has Background set, this command is being run as a
 // Background job. Only bgrun should use the Background mode,
 // not other callers.
@@ -109,11 +97,11 @@
 		}
 		outputLock.Unlock()
 		if mode&Background != 0 {
-			// Prevent fatal from waiting on our own goroutine's
+			// Prevent fatalf from waiting on our own goroutine's
 			// bghelper to exit:
 			bghelpers.Done()
 		}
-		fatal("FAILED: %v: %v", strings.Join(cmd, " "), err)
+		fatalf("FAILED: %v: %v", strings.Join(cmd, " "), err)
 	}
 	if mode&ShowOutput != 0 {
 		outputLock.Lock()
@@ -191,7 +179,7 @@
 func xgetwd() string {
 	wd, err := os.Getwd()
 	if err != nil {
-		fatal("%s", err)
+		fatalf("%s", err)
 	}
 	return wd
 }
@@ -201,11 +189,11 @@
 func xrealwd(path string) string {
 	old := xgetwd()
 	if err := os.Chdir(path); err != nil {
-		fatal("chdir %s: %v", path, err)
+		fatalf("chdir %s: %v", path, err)
 	}
 	real := xgetwd()
 	if err := os.Chdir(old); err != nil {
-		fatal("chdir %s: %v", old, err)
+		fatalf("chdir %s: %v", old, err)
 	}
 	return real
 }
@@ -231,16 +219,11 @@
 	return fi.ModTime()
 }
 
-// isabs reports whether p is an absolute path.
-func isabs(p string) bool {
-	return filepath.IsAbs(p)
-}
-
 // readfile returns the content of the named file.
 func readfile(file string) string {
 	data, err := ioutil.ReadFile(file)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 	return string(data)
 }
@@ -250,12 +233,12 @@
 	writeSkipSame
 )
 
-// writefile writes b to the named file, creating it if needed.
+// writefile writes text to the named file, creating it if needed.
 // if exec is non-zero, marks the file as executable.
 // If the file already exists and has the expected content,
 // it is not rewritten, to avoid changing the time stamp.
-func writefile(b, file string, flag int) {
-	new := []byte(b)
+func writefile(text, file string, flag int) {
+	new := []byte(text)
 	if flag&writeSkipSame != 0 {
 		old, err := ioutil.ReadFile(file)
 		if err == nil && bytes.Equal(old, new) {
@@ -268,7 +251,7 @@
 	}
 	err := ioutil.WriteFile(file, new, mode)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 }
 
@@ -276,7 +259,7 @@
 func xmkdir(p string) {
 	err := os.Mkdir(p, 0777)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 }
 
@@ -284,7 +267,7 @@
 func xmkdirall(p string) {
 	err := os.MkdirAll(p, 0777)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 }
 
@@ -309,12 +292,12 @@
 func xreaddir(dir string) []string {
 	f, err := os.Open(dir)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 	defer f.Close()
 	names, err := f.Readdirnames(-1)
 	if err != nil {
-		fatal("reading %s: %v", dir, err)
+		fatalf("reading %s: %v", dir, err)
 	}
 	return names
 }
@@ -324,12 +307,12 @@
 func xreaddirfiles(dir string) []string {
 	f, err := os.Open(dir)
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 	defer f.Close()
 	infos, err := f.Readdir(-1)
 	if err != nil {
-		fatal("reading %s: %v", dir, err)
+		fatalf("reading %s: %v", dir, err)
 	}
 	var names []string
 	for _, fi := range infos {
@@ -343,15 +326,15 @@
 // xworkdir creates a new temporary directory to hold object files
 // and returns the name of that directory.
 func xworkdir() string {
-	name, err := ioutil.TempDir("", "go-tool-dist-")
+	name, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-tool-dist-")
 	if err != nil {
-		fatal("%v", err)
+		fatalf("%v", err)
 	}
 	return name
 }
 
-// fatal prints an error message to standard error and exits.
-func fatal(format string, args ...interface{}) {
+// fatalf prints an error message to standard error and exits.
+func fatalf(format string, args ...interface{}) {
 	fmt.Fprintf(os.Stderr, "go tool dist: %s\n", fmt.Sprintf(format, args...))
 
 	dieOnce.Do(func() { close(dying) })
@@ -389,127 +372,6 @@
 	fmt.Fprintf(os.Stderr, format, args...)
 }
 
-// main takes care of OS-specific startup and dispatches to xmain.
-func main() {
-	os.Setenv("TERM", "dumb") // disable escape codes in clang errors
-
-	// provide -check-armv6k first, before checking for $GOROOT so that
-	// it is possible to run this check without having $GOROOT available.
-	if len(os.Args) > 1 && os.Args[1] == "-check-armv6k" {
-		useARMv6K() // might fail with SIGILL
-		println("ARMv6K supported.")
-		os.Exit(0)
-	}
-
-	slash = string(filepath.Separator)
-
-	gohostos = runtime.GOOS
-	switch gohostos {
-	case "darwin":
-		// Even on 64-bit platform, darwin uname -m prints i386.
-		// We don't support any of the OS X versions that run on 32-bit-only hardware anymore.
-		gohostarch = "amd64"
-	case "freebsd":
-		// Since FreeBSD 10 gcc is no longer part of the base system.
-		defaultclang = true
-	case "solaris":
-		// Even on 64-bit platform, solaris uname -m prints i86pc.
-		out := run("", CheckExit, "isainfo", "-n")
-		if strings.Contains(out, "amd64") {
-			gohostarch = "amd64"
-		}
-		if strings.Contains(out, "i386") {
-			gohostarch = "386"
-		}
-	case "plan9":
-		gohostarch = os.Getenv("objtype")
-		if gohostarch == "" {
-			fatal("$objtype is unset")
-		}
-	case "windows":
-		exe = ".exe"
-	}
-
-	sysinit()
-
-	if gohostarch == "" {
-		// Default Unix system.
-		out := run("", CheckExit, "uname", "-m")
-		switch {
-		case strings.Contains(out, "x86_64"), strings.Contains(out, "amd64"):
-			gohostarch = "amd64"
-		case strings.Contains(out, "86"):
-			gohostarch = "386"
-		case strings.Contains(out, "arm"):
-			gohostarch = "arm"
-		case strings.Contains(out, "aarch64"):
-			gohostarch = "arm64"
-		case strings.Contains(out, "ppc64le"):
-			gohostarch = "ppc64le"
-		case strings.Contains(out, "ppc64"):
-			gohostarch = "ppc64"
-		case strings.Contains(out, "mips64"):
-			gohostarch = "mips64"
-			if elfIsLittleEndian(os.Args[0]) {
-				gohostarch = "mips64le"
-			}
-		case strings.Contains(out, "mips"):
-			gohostarch = "mips"
-			if elfIsLittleEndian(os.Args[0]) {
-				gohostarch = "mipsle"
-			}
-		case strings.Contains(out, "s390x"):
-			gohostarch = "s390x"
-		case gohostos == "darwin":
-			if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM_") {
-				gohostarch = "arm"
-			}
-		default:
-			fatal("unknown architecture: %s", out)
-		}
-	}
-
-	if gohostarch == "arm" || gohostarch == "mips64" || gohostarch == "mips64le" {
-		maxbg = min(maxbg, runtime.NumCPU())
-	}
-	bginit()
-
-	// The OS X 10.6 linker does not support external linking mode.
-	// See golang.org/issue/5130.
-	//
-	// OS X 10.6 does not work with clang either, but OS X 10.9 requires it.
-	// It seems to work with OS X 10.8, so we default to clang for 10.8 and later.
-	// See golang.org/issue/5822.
-	//
-	// 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 gohostos == "darwin" {
-		rel := run("", CheckExit, "uname", "-r")
-		if i := strings.Index(rel, "."); i >= 0 {
-			rel = rel[:i]
-		}
-		osx, _ := strconv.Atoi(rel)
-		if osx <= 6+4 {
-			goextlinkenabled = "0"
-		}
-		if osx >= 8+4 {
-			defaultclang = true
-		}
-	}
-
-	if len(os.Args) > 1 && os.Args[1] == "-check-goarm" {
-		useVFPv1() // might fail with SIGILL
-		println("VFPv1 OK.")
-		useVFPv3() // might fail with SIGILL
-		println("VFPv3 OK.")
-		os.Exit(0)
-	}
-
-	xinit()
-	xmain()
-	xexit(0)
-}
-
 // xsamefile reports whether f1 and f2 are the same file (or dir)
 func xsamefile(f1, f2 string) bool {
 	fi1, err1 := os.Stat(f1)
@@ -570,17 +432,17 @@
 	// debug/elf package.
 	file, err := os.Open(fn)
 	if err != nil {
-		fatal("failed to open file to determine endianness: %v", err)
+		fatalf("failed to open file to determine endianness: %v", err)
 	}
 	defer file.Close()
 	var hdr [16]byte
 	if _, err := io.ReadFull(file, hdr[:]); err != nil {
-		fatal("failed to read ELF header to determine endianness: %v", err)
+		fatalf("failed to read ELF header to determine endianness: %v", err)
 	}
 	// hdr[5] is EI_DATA byte, 1 is ELFDATA2LSB and 2 is ELFDATA2MSB
 	switch hdr[5] {
 	default:
-		fatal("unknown ELF endianness of %s: EI_DATA = %d", fn, hdr[5])
+		fatalf("unknown ELF endianness of %s: EI_DATA = %d", fn, hdr[5])
 	case 1:
 		return true
 	case 2:
@@ -588,3 +450,40 @@
 	}
 	panic("unreachable")
 }
+
+// count is a flag.Value that is like a flag.Bool and a flag.Int.
+// If used as -name, it increments the count, but -name=x sets the count.
+// Used for verbose flag -v.
+type count int
+
+func (c *count) String() string {
+	return fmt.Sprint(int(*c))
+}
+
+func (c *count) Set(s string) error {
+	switch s {
+	case "true":
+		*c++
+	case "false":
+		*c = 0
+	default:
+		n, err := strconv.Atoi(s)
+		if err != nil {
+			return fmt.Errorf("invalid count %q", s)
+		}
+		*c = count(n)
+	}
+	return nil
+}
+
+func (c *count) IsBoolFlag() bool {
+	return true
+}
+
+func xflagparse(maxargs int) {
+	flag.Var((*count)(&vflag), "v", "verbosity")
+	flag.Parse()
+	if maxargs >= 0 && flag.NArg() > maxargs {
+		flag.Usage()
+	}
+}
diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go
index 8928252..07e59a2 100644
--- a/src/cmd/doc/doc_test.go
+++ b/src/cmd/doc/doc_test.go
@@ -292,6 +292,7 @@
 			`unexportedField.*int.*Comment on line with unexported field.`,
 			`ExportedEmbeddedType.*Comment on line with exported embedded field.`,
 			`\*ExportedEmbeddedType.*Comment on line with exported embedded \*field.`,
+			`\*qualified.ExportedEmbeddedType.*Comment on line with exported embedded \*selector.field.`,
 			`unexportedType.*Comment on line with unexported embedded field.`,
 			`\*unexportedType.*Comment on line with unexported embedded \*field.`,
 			`io.Reader.*Comment on line with embedded Reader.`,
@@ -445,6 +446,19 @@
 			`CaseMatch`,
 		},
 	},
+
+	// No dups with -u. Issue 21797.
+	{
+		"case matching on, no dups",
+		[]string{"-u", p, `duplicate`},
+		[]string{
+			`Duplicate`,
+			`duplicate`,
+		},
+		[]string{
+			"\\)\n+const", // This will appear if the const decl appears twice.
+		},
+	},
 }
 
 func TestDoc(t *testing.T) {
@@ -541,6 +555,54 @@
 	}
 }
 
+// Test the code to look up packages when given two args. First test case is
+//	go doc binary BigEndian
+// This needs to find encoding/binary.BigEndian, which means
+// finding the package encoding/binary given only "binary".
+// Second case is
+//	go doc rand Float64
+// which again needs to find math/rand and not give up after crypto/rand,
+// which has no such function.
+func TestTwoArgLookup(t *testing.T) {
+	if testing.Short() {
+		t.Skip("scanning file system takes too long")
+	}
+	maybeSkip(t)
+	var b bytes.Buffer // We don't care about the output.
+	{
+		var flagSet flag.FlagSet
+		err := do(&b, &flagSet, []string{"binary", "BigEndian"})
+		if err != nil {
+			t.Errorf("unexpected error %q from binary BigEndian", err)
+		}
+	}
+	{
+		var flagSet flag.FlagSet
+		err := do(&b, &flagSet, []string{"rand", "Float64"})
+		if err != nil {
+			t.Errorf("unexpected error %q from rand Float64", err)
+		}
+	}
+	{
+		var flagSet flag.FlagSet
+		err := do(&b, &flagSet, []string{"bytes", "Foo"})
+		if err == nil {
+			t.Errorf("expected error from bytes Foo")
+		} else if !strings.Contains(err.Error(), "no symbol Foo") {
+			t.Errorf("unexpected error %q from bytes Foo", err)
+		}
+	}
+	{
+		var flagSet flag.FlagSet
+		err := do(&b, &flagSet, []string{"nosuchpackage", "Foo"})
+		if err == nil {
+			// actually present in the user's filesystem
+		} else if !strings.Contains(err.Error(), "no such package") {
+			t.Errorf("unexpected error %q from nosuchpackage Foo", err)
+		}
+	}
+}
+
 type trimTest struct {
 	path   string
 	prefix string
diff --git a/src/cmd/doc/main.go b/src/cmd/doc/main.go
index 76c7dba..809a719 100644
--- a/src/cmd/doc/main.go
+++ b/src/cmd/doc/main.go
@@ -93,6 +93,9 @@
 		if i > 0 && !more { // Ignore the "more" bit on the first iteration.
 			return failMessage(paths, symbol, method)
 		}
+		if buildPackage == nil {
+			return fmt.Errorf("no such package: %s", userPath)
+		}
 		symbol, method = parseSymbol(sym)
 		pkg := parsePackage(writer, buildPackage, userPath)
 		paths = append(paths, pkg.prettyPath())
@@ -176,12 +179,12 @@
 	case 1:
 		// Done below.
 	case 2:
-		// Package must be importable.
-		pkg, err := build.Import(args[0], "", build.ImportComment)
-		if err != nil {
-			log.Fatalf("%s", err)
+		// Package must be findable and importable.
+		packagePath, ok := findPackage(args[0])
+		if !ok {
+			return nil, args[0], args[1], false
 		}
-		return pkg, args[0], args[1], false
+		return importDir(packagePath), args[0], args[1], true
 	}
 	// Usual case: one argument.
 	arg := args[0]
@@ -230,7 +233,6 @@
 		}
 		// See if we have the basename or tail of a package, as in json for encoding/json
 		// or ivy/value for robpike.io/ivy/value.
-		// Launch findPackage as a goroutine so it can return multiple paths if required.
 		path, ok := findPackage(arg[0:period])
 		if ok {
 			return importDir(path), arg[0:period], symbol, true
diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go
index 5a14d6e..11011de 100644
--- a/src/cmd/doc/pkg.go
+++ b/src/cmd/doc/pkg.go
@@ -594,6 +594,11 @@
 	// Constants and variables behave the same.
 	values := pkg.findValues(symbol, pkg.doc.Consts)
 	values = append(values, pkg.findValues(symbol, pkg.doc.Vars)...)
+	// A declaration like
+	//	const ( c = 1; C = 2 )
+	// could be printed twice if the -u flag is set, as it matches twice.
+	// So we remember which declarations we've printed to avoid duplication.
+	printed := make(map[*ast.GenDecl]bool)
 	for _, value := range values {
 		// Print each spec only if there is at least one exported symbol in it.
 		// (See issue 11008.)
@@ -628,7 +633,7 @@
 				}
 			}
 		}
-		if len(specs) == 0 {
+		if len(specs) == 0 || printed[value.Decl] {
 			continue
 		}
 		value.Decl.Specs = specs
@@ -636,6 +641,7 @@
 			pkg.packageClause(true)
 		}
 		pkg.emit(value.Doc, value.Decl)
+		printed[value.Decl] = true
 		found = true
 	}
 	// Types.
@@ -696,9 +702,16 @@
 	for _, field := range fields.List {
 		names := field.Names
 		if len(names) == 0 {
-			// Embedded type. Use the name of the type. It must be of type ident or *ident.
+			// Embedded type. Use the name of the type. It must be of the form ident or
+			// pkg.ident (for structs and interfaces), or *ident or *pkg.ident (structs only).
 			// Nothing else is allowed.
-			switch ident := field.Type.(type) {
+			ty := field.Type
+			if se, ok := field.Type.(*ast.StarExpr); !isInterface && ok {
+				// The form *ident or *pkg.ident is only valid on
+				// embedded types in structs.
+				ty = se.X
+			}
+			switch ident := ty.(type) {
 			case *ast.Ident:
 				if isInterface && ident.Name == "error" && ident.Obj == nil {
 					// For documentation purposes, we consider the builtin error
@@ -708,12 +721,6 @@
 					continue
 				}
 				names = []*ast.Ident{ident}
-			case *ast.StarExpr:
-				// Must have the form *identifier.
-				// This is only valid on embedded types in structs.
-				if ident, ok := ident.X.(*ast.Ident); ok && !isInterface {
-					names = []*ast.Ident{ident}
-				}
 			case *ast.SelectorExpr:
 				// An embedded type may refer to a type in another package.
 				names = []*ast.Ident{ident.Sel}
diff --git a/src/cmd/doc/testdata/pkg.go b/src/cmd/doc/testdata/pkg.go
index 99755b1..bc06993 100644
--- a/src/cmd/doc/testdata/pkg.go
+++ b/src/cmd/doc/testdata/pkg.go
@@ -60,14 +60,15 @@
 // Comment about exported type.
 type ExportedType struct {
 	// Comment before exported field.
-	ExportedField         int // Comment on line with exported field.
-	unexportedField       int // Comment on line with unexported field.
-	ExportedEmbeddedType      // Comment on line with exported embedded field.
-	*ExportedEmbeddedType     // Comment on line with exported embedded *field.
-	unexportedType            // Comment on line with unexported embedded field.
-	*unexportedType           // Comment on line with unexported embedded *field.
-	io.Reader                 // Comment on line with embedded Reader.
-	error                     // Comment on line with embedded error.
+	ExportedField                   int // Comment on line with exported field.
+	unexportedField                 int // Comment on line with unexported field.
+	ExportedEmbeddedType                // Comment on line with exported embedded field.
+	*ExportedEmbeddedType               // Comment on line with exported embedded *field.
+	*qualified.ExportedEmbeddedType     // Comment on line with exported embedded *selector.field.
+	unexportedType                      // Comment on line with unexported embedded field.
+	*unexportedType                     // Comment on line with unexported embedded *field.
+	io.Reader                           // Comment on line with embedded Reader.
+	error                               // Comment on line with embedded error.
 }
 
 // Comment about exported method.
@@ -193,3 +194,8 @@
 type T2 int
 
 type T1 = T2
+
+const (
+	Duplicate = iota
+	duplicate
+)
diff --git a/src/cmd/fix/cftype.go b/src/cmd/fix/cftype.go
new file mode 100644
index 0000000..b47b066
--- /dev/null
+++ b/src/cmd/fix/cftype.go
@@ -0,0 +1,143 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"go/ast"
+	"go/token"
+	"reflect"
+	"strings"
+)
+
+func init() {
+	register(cftypeFix)
+}
+
+var cftypeFix = fix{
+	name:     "cftype",
+	date:     "2017-09-27",
+	f:        cftypefix,
+	desc:     `Fixes initializers and casts of C.*Ref and JNI types`,
+	disabled: false,
+}
+
+// Old state:
+//   type CFTypeRef unsafe.Pointer
+// New state:
+//   type CFTypeRef uintptr
+// and similar for other *Ref types.
+// This fix finds nils initializing these types and replaces the nils with 0s.
+func cftypefix(f *ast.File) bool {
+	return typefix(f, func(s string) bool {
+		return strings.HasPrefix(s, "C.") && strings.HasSuffix(s, "Ref") && s != "C.CFAllocatorRef"
+	})
+}
+
+// typefix replaces nil with 0 for all nils whose type, when passed to badType, returns true.
+func typefix(f *ast.File, badType func(string) bool) bool {
+	if !imports(f, "C") {
+		return false
+	}
+	typeof, _ := typecheck(&TypeConfig{}, f)
+	changed := false
+
+	// step 1: Find all the nils with the offending types.
+	// Compute their replacement.
+	badNils := map[interface{}]ast.Expr{}
+	walk(f, func(n interface{}) {
+		if i, ok := n.(*ast.Ident); ok && i.Name == "nil" && badType(typeof[n]) {
+			badNils[n] = &ast.BasicLit{ValuePos: i.NamePos, Kind: token.INT, Value: "0"}
+		}
+	})
+
+	// step 2: find all uses of the bad nils, replace them with 0.
+	// There's no easy way to map from an ast.Expr to all the places that use them, so
+	// we use reflect to find all such references.
+	if len(badNils) > 0 {
+		exprType := reflect.TypeOf((*ast.Expr)(nil)).Elem()
+		exprSliceType := reflect.TypeOf(([]ast.Expr)(nil))
+		walk(f, func(n interface{}) {
+			if n == nil {
+				return
+			}
+			v := reflect.ValueOf(n)
+			if v.Type().Kind() != reflect.Ptr {
+				return
+			}
+			if v.IsNil() {
+				return
+			}
+			v = v.Elem()
+			if v.Type().Kind() != reflect.Struct {
+				return
+			}
+			for i := 0; i < v.NumField(); i++ {
+				f := v.Field(i)
+				if f.Type() == exprType {
+					if r := badNils[f.Interface()]; r != nil {
+						f.Set(reflect.ValueOf(r))
+						changed = true
+					}
+				}
+				if f.Type() == exprSliceType {
+					for j := 0; j < f.Len(); j++ {
+						e := f.Index(j)
+						if r := badNils[e.Interface()]; r != nil {
+							e.Set(reflect.ValueOf(r))
+							changed = true
+						}
+					}
+				}
+			}
+		})
+	}
+
+	// step 3: fix up invalid casts.
+	// It used to be ok to cast between *unsafe.Pointer and *C.CFTypeRef in a single step.
+	// Now we need unsafe.Pointer as an intermediate cast.
+	// (*unsafe.Pointer)(x) where x is type *bad -> (*unsafe.Pointer)(unsafe.Pointer(x))
+	// (*bad.type)(x) where x is type *unsafe.Pointer -> (*bad.type)(unsafe.Pointer(x))
+	walk(f, func(n interface{}) {
+		if n == nil {
+			return
+		}
+		// Find pattern like (*a.b)(x)
+		c, ok := n.(*ast.CallExpr)
+		if !ok {
+			return
+		}
+		if len(c.Args) != 1 {
+			return
+		}
+		p, ok := c.Fun.(*ast.ParenExpr)
+		if !ok {
+			return
+		}
+		s, ok := p.X.(*ast.StarExpr)
+		if !ok {
+			return
+		}
+		t, ok := s.X.(*ast.SelectorExpr)
+		if !ok {
+			return
+		}
+		pkg, ok := t.X.(*ast.Ident)
+		if !ok {
+			return
+		}
+		dst := pkg.Name + "." + t.Sel.Name
+		src := typeof[c.Args[0]]
+		if badType(dst) && src == "*unsafe.Pointer" ||
+			dst == "unsafe.Pointer" && strings.HasPrefix(src, "*") && badType(src[1:]) {
+			c.Args[0] = &ast.CallExpr{
+				Fun:  &ast.SelectorExpr{X: &ast.Ident{Name: "unsafe"}, Sel: &ast.Ident{Name: "Pointer"}},
+				Args: []ast.Expr{c.Args[0]},
+			}
+			changed = true
+		}
+	})
+
+	return changed
+}
diff --git a/src/cmd/fix/cftype_test.go b/src/cmd/fix/cftype_test.go
new file mode 100644
index 0000000..a18eb25
--- /dev/null
+++ b/src/cmd/fix/cftype_test.go
@@ -0,0 +1,219 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func init() {
+	addTestCases(cftypeTests, cftypefix)
+}
+
+var cftypeTests = []testCase{
+	{
+		Name: "cftype.localVariable",
+		In: `package main
+
+import "C"
+
+func f() {
+	var x C.CFTypeRef = nil
+	x = nil
+	x, x = nil, nil
+}
+`,
+		Out: `package main
+
+import "C"
+
+func f() {
+	var x C.CFTypeRef = 0
+	x = 0
+	x, x = 0, 0
+}
+`,
+	},
+	{
+		Name: "cftype.globalVariable",
+		In: `package main
+
+import "C"
+
+var x C.CFTypeRef = nil
+
+func f() {
+	x = nil
+}
+`,
+		Out: `package main
+
+import "C"
+
+var x C.CFTypeRef = 0
+
+func f() {
+	x = 0
+}
+`,
+	},
+	{
+		Name: "cftype.EqualArgument",
+		In: `package main
+
+import "C"
+
+var x C.CFTypeRef
+var y = x == nil
+var z = x != nil
+`,
+		Out: `package main
+
+import "C"
+
+var x C.CFTypeRef
+var y = x == 0
+var z = x != 0
+`,
+	},
+	{
+		Name: "cftype.StructField",
+		In: `package main
+
+import "C"
+
+type T struct {
+	x C.CFTypeRef
+}
+
+var t = T{x: nil}
+`,
+		Out: `package main
+
+import "C"
+
+type T struct {
+	x C.CFTypeRef
+}
+
+var t = T{x: 0}
+`,
+	},
+	{
+		Name: "cftype.FunctionArgument",
+		In: `package main
+
+import "C"
+
+func f(x C.CFTypeRef) {
+}
+
+func g() {
+	f(nil)
+}
+`,
+		Out: `package main
+
+import "C"
+
+func f(x C.CFTypeRef) {
+}
+
+func g() {
+	f(0)
+}
+`,
+	},
+	{
+		Name: "cftype.ArrayElement",
+		In: `package main
+
+import "C"
+
+var x = [3]C.CFTypeRef{nil, nil, nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = [3]C.CFTypeRef{0, 0, 0}
+`,
+	},
+	{
+		Name: "cftype.SliceElement",
+		In: `package main
+
+import "C"
+
+var x = []C.CFTypeRef{nil, nil, nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = []C.CFTypeRef{0, 0, 0}
+`,
+	},
+	{
+		Name: "cftype.MapKey",
+		In: `package main
+
+import "C"
+
+var x = map[C.CFTypeRef]int{nil: 0}
+`,
+		Out: `package main
+
+import "C"
+
+var x = map[C.CFTypeRef]int{0: 0}
+`,
+	},
+	{
+		Name: "cftype.MapValue",
+		In: `package main
+
+import "C"
+
+var x = map[int]C.CFTypeRef{0: nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = map[int]C.CFTypeRef{0: 0}
+`,
+	},
+	{
+		Name: "cftype.Conversion1",
+		In: `package main
+
+import "C"
+
+var x C.CFTypeRef
+var y = (*unsafe.Pointer)(&x)
+`,
+		Out: `package main
+
+import "C"
+
+var x C.CFTypeRef
+var y = (*unsafe.Pointer)(unsafe.Pointer(&x))
+`,
+	},
+	{
+		Name: "cftype.Conversion2",
+		In: `package main
+
+import "C"
+
+var x unsafe.Pointer
+var y = (*C.CFTypeRef)(&x)
+`,
+		Out: `package main
+
+import "C"
+
+var x unsafe.Pointer
+var y = (*C.CFTypeRef)(unsafe.Pointer(&x))
+`,
+	},
+}
diff --git a/src/cmd/fix/context.go b/src/cmd/fix/context.go
index 926a06c..1107f4d 100644
--- a/src/cmd/fix/context.go
+++ b/src/cmd/fix/context.go
@@ -17,7 +17,7 @@
 	date:     "2016-09-09",
 	f:        ctxfix,
 	desc:     `Change imports of golang.org/x/net/context to context`,
-	disabled: true,
+	disabled: false,
 }
 
 func ctxfix(f *ast.File) bool {
diff --git a/src/cmd/fix/jnitype.go b/src/cmd/fix/jnitype.go
new file mode 100644
index 0000000..29abe0f
--- /dev/null
+++ b/src/cmd/fix/jnitype.go
@@ -0,0 +1,65 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"go/ast"
+)
+
+func init() {
+	register(jniFix)
+}
+
+var jniFix = fix{
+	name:     "jni",
+	date:     "2017-12-04",
+	f:        jnifix,
+	desc:     `Fixes initializers of JNI's jobject and subtypes`,
+	disabled: false,
+}
+
+// Old state:
+//   type jobject *_jobject
+// New state:
+//   type jobject uintptr
+// and similar for subtypes of jobject.
+// This fix finds nils initializing these types and replaces the nils with 0s.
+func jnifix(f *ast.File) bool {
+	return typefix(f, func(s string) bool {
+		switch s {
+		case "C.jobject":
+			return true
+		case "C.jclass":
+			return true
+		case "C.jthrowable":
+			return true
+		case "C.jstring":
+			return true
+		case "C.jarray":
+			return true
+		case "C.jbooleanArray":
+			return true
+		case "C.jbyteArray":
+			return true
+		case "C.jcharArray":
+			return true
+		case "C.jshortArray":
+			return true
+		case "C.jintArray":
+			return true
+		case "C.jlongArray":
+			return true
+		case "C.jfloatArray":
+			return true
+		case "C.jdoubleArray":
+			return true
+		case "C.jobjectArray":
+			return true
+		case "C.jweak":
+			return true
+		}
+		return false
+	})
+}
diff --git a/src/cmd/fix/jnitype_test.go b/src/cmd/fix/jnitype_test.go
new file mode 100644
index 0000000..a6420f7
--- /dev/null
+++ b/src/cmd/fix/jnitype_test.go
@@ -0,0 +1,185 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func init() {
+	addTestCases(jniTests, jnifix)
+}
+
+var jniTests = []testCase{
+	{
+		Name: "jni.localVariable",
+		In: `package main
+
+import "C"
+
+func f() {
+	var x C.jobject = nil
+	x = nil
+	x, x = nil, nil
+}
+`,
+		Out: `package main
+
+import "C"
+
+func f() {
+	var x C.jobject = 0
+	x = 0
+	x, x = 0, 0
+}
+`,
+	},
+	{
+		Name: "jni.globalVariable",
+		In: `package main
+
+import "C"
+
+var x C.jobject = nil
+
+func f() {
+	x = nil
+}
+`,
+		Out: `package main
+
+import "C"
+
+var x C.jobject = 0
+
+func f() {
+	x = 0
+}
+`,
+	},
+	{
+		Name: "jni.EqualArgument",
+		In: `package main
+
+import "C"
+
+var x C.jobject
+var y = x == nil
+var z = x != nil
+`,
+		Out: `package main
+
+import "C"
+
+var x C.jobject
+var y = x == 0
+var z = x != 0
+`,
+	},
+	{
+		Name: "jni.StructField",
+		In: `package main
+
+import "C"
+
+type T struct {
+	x C.jobject
+}
+
+var t = T{x: nil}
+`,
+		Out: `package main
+
+import "C"
+
+type T struct {
+	x C.jobject
+}
+
+var t = T{x: 0}
+`,
+	},
+	{
+		Name: "jni.FunctionArgument",
+		In: `package main
+
+import "C"
+
+func f(x C.jobject) {
+}
+
+func g() {
+	f(nil)
+}
+`,
+		Out: `package main
+
+import "C"
+
+func f(x C.jobject) {
+}
+
+func g() {
+	f(0)
+}
+`,
+	},
+	{
+		Name: "jni.ArrayElement",
+		In: `package main
+
+import "C"
+
+var x = [3]C.jobject{nil, nil, nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = [3]C.jobject{0, 0, 0}
+`,
+	},
+	{
+		Name: "jni.SliceElement",
+		In: `package main
+
+import "C"
+
+var x = []C.jobject{nil, nil, nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = []C.jobject{0, 0, 0}
+`,
+	},
+	{
+		Name: "jni.MapKey",
+		In: `package main
+
+import "C"
+
+var x = map[C.jobject]int{nil: 0}
+`,
+		Out: `package main
+
+import "C"
+
+var x = map[C.jobject]int{0: 0}
+`,
+	},
+	{
+		Name: "jni.MapValue",
+		In: `package main
+
+import "C"
+
+var x = map[int]C.jobject{0: nil}
+`,
+		Out: `package main
+
+import "C"
+
+var x = map[int]C.jobject{0: 0}
+`,
+	},
+}
diff --git a/src/cmd/fix/typecheck.go b/src/cmd/fix/typecheck.go
index 0352c49..eafb626 100644
--- a/src/cmd/fix/typecheck.go
+++ b/src/cmd/fix/typecheck.go
@@ -7,9 +7,14 @@
 import (
 	"fmt"
 	"go/ast"
+	"go/parser"
 	"go/token"
+	"io/ioutil"
 	"os"
+	"os/exec"
+	"path/filepath"
 	"reflect"
+	"runtime"
 	"strings"
 )
 
@@ -74,6 +79,11 @@
 	Type map[string]*Type
 	Var  map[string]string
 	Func map[string]string
+
+	// External maps from a name to its type.
+	// It provides additional typings not present in the Go source itself.
+	// For now, the only additional typings are those generated by cgo.
+	External map[string]string
 }
 
 // typeof returns the type of the given name, which may be of
@@ -140,6 +150,67 @@
 	*cfg1 = *cfg // make copy so we can add locally
 	copied := false
 
+	// If we import "C", add types of cgo objects.
+	cfg.External = map[string]string{}
+	cfg1.External = cfg.External
+	if imports(f, "C") {
+		// Run cgo on gofmtFile(f)
+		// Parse, extract decls from _cgo_gotypes.go
+		// Map _Ctype_* types to C.* types.
+		err := func() error {
+			txt, err := gofmtFile(f)
+			if err != nil {
+				return err
+			}
+			dir, err := ioutil.TempDir(os.TempDir(), "fix_cgo_typecheck")
+			if err != nil {
+				return err
+			}
+			defer os.RemoveAll(dir)
+			err = ioutil.WriteFile(filepath.Join(dir, "in.go"), txt, 0600)
+			if err != nil {
+				return err
+			}
+			cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "tool", "cgo", "-objdir", dir, "-srcdir", dir, "in.go")
+			err = cmd.Run()
+			if err != nil {
+				return err
+			}
+			out, err := ioutil.ReadFile(filepath.Join(dir, "_cgo_gotypes.go"))
+			if err != nil {
+				return err
+			}
+			cgo, err := parser.ParseFile(token.NewFileSet(), "cgo.go", out, 0)
+			if err != nil {
+				return err
+			}
+			for _, decl := range cgo.Decls {
+				fn, ok := decl.(*ast.FuncDecl)
+				if !ok {
+					continue
+				}
+				if strings.HasPrefix(fn.Name.Name, "_Cfunc_") {
+					var params, results []string
+					for _, p := range fn.Type.Params.List {
+						t := gofmt(p.Type)
+						t = strings.Replace(t, "_Ctype_", "C.", -1)
+						params = append(params, t)
+					}
+					for _, r := range fn.Type.Results.List {
+						t := gofmt(r.Type)
+						t = strings.Replace(t, "_Ctype_", "C.", -1)
+						results = append(results, t)
+					}
+					cfg.External["C."+fn.Name.Name[7:]] = joinFunc(params, results)
+				}
+			}
+			return nil
+		}()
+		if err != nil {
+			fmt.Printf("warning: no cgo types: %s\n", err)
+		}
+	}
+
 	// gather function declarations
 	for _, decl := range f.Decls {
 		fn, ok := decl.(*ast.FuncDecl)
@@ -434,6 +505,9 @@
 			}
 			// Otherwise, use type of function to determine arguments.
 			t := typeof[n.Fun]
+			if t == "" {
+				t = cfg.External[gofmt(n.Fun)]
+			}
 			in, out := splitFunc(t)
 			if in == nil && out == nil {
 				return
@@ -498,6 +572,50 @@
 			// T{...} has type T.
 			typeof[n] = gofmt(n.Type)
 
+			// Propagate types down to values used in the composite literal.
+			t := expand(typeof[n])
+			if strings.HasPrefix(t, "[") { // array or slice
+				// Lazy: assume there are no nested [] in the array length.
+				if i := strings.Index(t, "]"); i >= 0 {
+					et := t[i+1:]
+					for _, e := range n.Elts {
+						if kv, ok := e.(*ast.KeyValueExpr); ok {
+							e = kv.Value
+						}
+						if typeof[e] == "" {
+							typeof[e] = et
+						}
+					}
+				}
+			}
+			if strings.HasPrefix(t, "map[") { // map
+				// Lazy: assume there are no nested [] in the map key type.
+				if i := strings.Index(t, "]"); i >= 0 {
+					kt, vt := t[4:i], t[i+1:]
+					for _, e := range n.Elts {
+						if kv, ok := e.(*ast.KeyValueExpr); ok {
+							if typeof[kv.Key] == "" {
+								typeof[kv.Key] = kt
+							}
+							if typeof[kv.Value] == "" {
+								typeof[kv.Value] = vt
+							}
+						}
+					}
+				}
+			}
+			if typ := cfg.Type[t]; typ != nil && len(typ.Field) > 0 { // struct
+				for _, e := range n.Elts {
+					if kv, ok := e.(*ast.KeyValueExpr); ok {
+						if ft := typ.Field[fmt.Sprintf("%s", kv.Key)]; ft != "" {
+							if typeof[kv.Value] == "" {
+								typeof[kv.Value] = ft
+							}
+						}
+					}
+				}
+			}
+
 		case *ast.ParenExpr:
 			// (x) has type of x.
 			typeof[n] = typeof[n.X]
@@ -579,6 +697,18 @@
 					set(res[i], t[i], false)
 				}
 			}
+
+		case *ast.BinaryExpr:
+			// Propagate types across binary ops that require two args of the same type.
+			switch n.Op {
+			case token.EQL, token.NEQ: // TODO: more cases. This is enough for the cftype fix.
+				if typeof[n.X] != "" && typeof[n.Y] == "" {
+					typeof[n.Y] = typeof[n.X]
+				}
+				if typeof[n.X] == "" && typeof[n.Y] != "" {
+					typeof[n.X] = typeof[n.Y]
+				}
+			}
 		}
 	}
 	walkBeforeAfter(f, before, after)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 7dd7ba9..7557647 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -14,12 +14,12 @@
 // The commands are:
 //
 // 	build       compile packages and dependencies
-// 	clean       remove object files
+// 	clean       remove object files and cached files
 // 	doc         show documentation for package or symbol
 // 	env         print Go environment information
 // 	bug         start a bug report
-// 	fix         run go tool fix on packages
-// 	fmt         run gofmt on package sources
+// 	fix         update packages to use new APIs
+// 	fmt         gofmt (reformat) package sources
 // 	generate    generate Go files by processing source
 // 	get         download and install packages and dependencies
 // 	install     compile and install packages and dependencies
@@ -28,21 +28,22 @@
 // 	test        test packages
 // 	tool        run specified go tool
 // 	version     print Go version
-// 	vet         run go tool vet on packages
+// 	vet         report likely mistakes in packages
 //
 // Use "go help [command]" for more information about a command.
 //
 // Additional help topics:
 //
 // 	c           calling between Go and C
-// 	buildmode   description of build modes
+// 	buildmode   build modes
+// 	cache       build and test caching
 // 	filetype    file types
 // 	gopath      GOPATH environment variable
 // 	environment environment variables
 // 	importpath  import path syntax
-// 	packages    description of package lists
-// 	testflag    description of testing flags
-// 	testfunc    description of testing functions
+// 	packages    package lists
+// 	testflag    testing flags
+// 	testfunc    testing functions
 //
 // Use "go help [topic]" for more information about that topic.
 //
@@ -104,15 +105,15 @@
 // 	-x
 // 		print the commands.
 //
-// 	-asmflags 'flag list'
+// 	-asmflags '[pattern=]arg list'
 // 		arguments to pass on each go tool asm invocation.
 // 	-buildmode mode
 // 		build mode to use. See 'go help buildmode' for more.
 // 	-compiler name
 // 		name of compiler to use, as in runtime.Compiler (gccgo or gc).
-// 	-gccgoflags 'arg list'
+// 	-gccgoflags '[pattern=]arg list'
 // 		arguments to pass on each gccgo compiler/linker invocation.
-// 	-gcflags 'arg list'
+// 	-gcflags '[pattern=]arg list'
 // 		arguments to pass on each go tool compile invocation.
 // 	-installsuffix suffix
 // 		a suffix to use in the name of the package installation directory,
@@ -121,7 +122,7 @@
 // 		or, if set explicitly, has _race appended to it. Likewise for the -msan
 // 		flag. Using a -buildmode option that requires non-default compile flags
 // 		has a similar effect.
-// 	-ldflags 'flag list'
+// 	-ldflags '[pattern=]arg list'
 // 		arguments to pass on each go tool link invocation.
 // 	-linkshared
 // 		link against shared libraries previously created with
@@ -139,9 +140,21 @@
 // 		For example, instead of running asm, the go command will run
 // 		'cmd args /path/to/asm <arguments for asm>'.
 //
-// All the flags that take a list of arguments accept a space-separated
-// list of strings. To embed spaces in an element in the list, surround
-// it with either single or double quotes.
+// The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
+// space-separated list of arguments to pass to an underlying tool
+// during the build. To embed spaces in an element in the list, surround
+// it with either single or double quotes. The argument list may be
+// preceded by a package pattern and an equal sign, which restricts
+// the use of that argument list to the building of packages matching
+// that pattern (see 'go help packages' for a description of package
+// patterns). Without a pattern, the argument list applies only to the
+// packages named on the command line. The flags may be repeated
+// with different patterns in order to specify different arguments for
+// different sets of packages. If a package matches patterns given in
+// multiple flags, the latest match on the command line wins.
+// For example, 'go build -gcflags=-S fmt' prints the disassembly
+// only for package fmt, while 'go build -gcflags=all=-S fmt'
+// prints the disassembly for fmt and all its dependencies.
 //
 // For more about specifying packages, see 'go help packages'.
 // For more about where packages and binaries are installed,
@@ -158,11 +171,11 @@
 // See also: go install, go get, go clean.
 //
 //
-// Remove object files
+// Remove object files and cached files
 //
 // Usage:
 //
-// 	go clean [-i] [-r] [-n] [-x] [build flags] [packages]
+// 	go clean [-i] [-r] [-n] [-x] [-cache] [-testcache] [build flags] [packages]
 //
 // Clean removes object files from package source directories.
 // The go command builds most objects in a temporary directory,
@@ -200,6 +213,11 @@
 //
 // The -x flag causes clean to print remove commands as it executes them.
 //
+// The -cache flag causes clean to remove the entire go build cache.
+//
+// The -testcache flag causes clean to expire all test results in the
+// go build cache.
+//
 // For more about build flags, see 'go help build'.
 //
 // For more about specifying packages, see 'go help packages'.
@@ -328,6 +346,8 @@
 // The -json flag prints the environment in JSON format
 // instead of as a shell script.
 //
+// For more about environment variables, see 'go help environment'.
+//
 //
 // Start a bug report
 //
@@ -339,7 +359,7 @@
 // The report includes useful system information.
 //
 //
-// Run go tool fix on packages
+// Update packages to use new APIs
 //
 // Usage:
 //
@@ -355,7 +375,7 @@
 // See also: go fmt, go vet.
 //
 //
-// Run gofmt on package sources
+// Gofmt (reformat) package sources
 //
 // Usage:
 //
@@ -486,7 +506,7 @@
 //
 // Usage:
 //
-// 	go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
+// 	go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [-v] [build flags] [packages]
 //
 // Get downloads the packages named by the import paths, along with their
 // dependencies. It then installs the named packages, like 'go install'.
@@ -543,10 +563,11 @@
 //
 // Usage:
 //
-// 	go install [build flags] [packages]
+// 	go install [-i] [build flags] [packages]
 //
-// Install compiles and installs the packages named by the import paths,
-// along with their dependencies.
+// Install compiles and installs the packages named by the import paths.
+//
+// The -i flag installs the dependencies of the named packages as well.
 //
 // For more about the build flags, see 'go help build'.
 // For more about specifying packages, see 'go help packages'.
@@ -719,10 +740,10 @@
 //
 // 'Go test' recompiles each package along with any files with names matching
 // 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.
 // Each listed package causes the execution of a separate test binary.
+// Files whose names begin with "_" (including "_test.go") or "." are ignored.
 //
 // Test files that declare a package with the suffix "_test" will be compiled as a
 // separate package, and then linked and run with the main test binary.
@@ -730,11 +751,58 @@
 // The go tool will ignore a directory named "testdata", making it available
 // to hold ancillary data needed by the tests.
 //
-// By default, go test needs no arguments. It compiles and tests the package
-// with source in the current directory, including tests, and runs the tests.
+// As part of building a test binary, go test runs go vet on the package
+// and its test source files to identify significant problems. If go vet
+// finds any problems, go test reports those and does not run the test binary.
+// Only a high-confidence subset of the default go vet checks are used.
+// To disable the running of go vet, use the -vet=off flag.
 //
-// The package is built in a temporary directory so it does not interfere with the
-// non-test installation.
+// All test output and summary lines are printed to the go command's
+// standard output, even if the test printed them to its own standard
+// error. (The go command's standard error is reserved for printing
+// errors building the tests.)
+//
+// Go test runs in two different modes:
+//
+// The first, called local directory mode, occurs when go test is
+// invoked with no package arguments (for example, 'go test' or 'go
+// test -v'). In this mode, go test compiles the package sources and
+// tests found in the current directory and then runs the resulting
+// test binary. In this mode, caching (discussed below) is disabled.
+// After the package test finishes, go test prints a summary line
+// showing the test status ('ok' or 'FAIL'), package name, and elapsed
+// time.
+//
+// The second, called package list mode, occurs when go test is invoked
+// with explicit package arguments (for example 'go test math', 'go
+// test ./...', and even 'go test .'). In this mode, go test compiles
+// and tests each of the packages listed on the command line. If a
+// package test passes, go test prints only the final 'ok' summary
+// line. If a package test fails, go test prints the full test output.
+// If invoked with the -bench or -v flag, go test prints the full
+// output even for passing package tests, in order to display the
+// requested benchmark results or verbose logging.
+//
+// In package list mode only, go test caches successful package test
+// results to avoid unnecessary repeated running of tests. When the
+// result of a test can be recovered from the cache, go test will
+// redisplay the previous output instead of running the test binary
+// again. When this happens, go test prints '(cached)' in place of the
+// elapsed time in the summary line.
+//
+// The rule for a match in the cache is that the run involves the same
+// test binary and the flags on the command line come entirely from a
+// restricted set of 'cacheable' test flags, defined as -cpu, -list,
+// -parallel, -run, -short, and -v. If a run of go test has any test
+// or non-test flags outside this set, the result is not cached. To
+// disable test caching, use any test flag or argument other than the
+// cacheable flags. The idiomatic way to disable test caching explicitly
+// is to use -count=1. Tests that open files within the package's source
+// root (usually $GOPATH) or that consult environment variables only
+// match future runs in which the files and environment variables are unchanged.
+// A cached test result is treated as executing in no time at all,
+// so a successful package test result will be cached and reused
+// regardless of -timeout setting.
 //
 // In addition to the build flags, the flags handled by 'go test' itself are:
 //
@@ -757,6 +825,10 @@
 // 	    Install packages that are dependencies of the test.
 // 	    Do not run the test.
 //
+// 	-json
+// 	    Convert test output to JSON suitable for automated processing.
+// 	    See 'go doc test2json' for the encoding details.
+//
 // 	-o file
 // 	    Compile the test binary to the named file.
 // 	    The test still runs (unless -c or -i is specified).
@@ -782,7 +854,7 @@
 // The -n flag causes tool to print the command that would be
 // executed but not execute it.
 //
-// For more about each tool command, see 'go tool command -h'.
+// For more about each tool command, see 'go doc cmd/<command>'.
 //
 //
 // Print Go version
@@ -794,7 +866,7 @@
 // Version prints the Go version, as reported by runtime.Version.
 //
 //
-// Run go tool vet on packages
+// Report likely mistakes in packages
 //
 // Usage:
 //
@@ -808,7 +880,9 @@
 // The -n flag prints commands that would be executed.
 // The -x flag prints commands as they are executed.
 //
-// For more about build flags, see 'go help build'.
+// The build flags supported by go vet are those that control package resolution
+// and execution, such as -n, -x, -v, -tags, and -toolexec.
+// For more about these flags, see 'go help build'.
 //
 // See also: go fmt, go fix.
 //
@@ -832,7 +906,7 @@
 // the C or C++ compiler, respectively, to use.
 //
 //
-// Description of build modes
+// Build modes
 //
 // The 'go build' and 'go install' commands take a -buildmode argument which
 // indicates which kind of object file is to be built. Currently supported values
@@ -878,6 +952,45 @@
 // 		import, into a Go plugin. Packages not named main are ignored.
 //
 //
+// Build and test caching
+//
+// The go command caches build outputs for reuse in future builds.
+// The default location for cache data is a subdirectory named go-build
+// in the standard user cache directory for the current operating system.
+// Setting the GOCACHE environment variable overrides this default,
+// and running 'go env GOCACHE' prints the current cache directory.
+//
+// The go command periodically deletes cached data that has not been
+// used recently. Running 'go clean -cache' deletes all cached data.
+//
+// The build cache correctly accounts for changes to Go source files,
+// compilers, compiler options, and so on: cleaning the cache explicitly
+// should not be necessary in typical use. However, the build cache
+// does not detect changes to C libraries imported with cgo.
+// If you have made changes to the C libraries on your system, you
+// will need to clean the cache explicitly or else use the -a build flag
+// (see 'go help build') to force rebuilding of packages that
+// depend on the updated C libraries.
+//
+// The go command also caches successful package test results.
+// See 'go help test' for details. Running 'go clean -testcache' removes
+// all cached test results (but not cached build results).
+//
+// The GODEBUG environment variable can enable printing of debugging
+// information about the state of the cache:
+//
+// GODEBUG=gocacheverify=1 causes the go command to bypass the
+// use of any cache entries and instead rebuild everything and check
+// that the results match existing cache entries.
+//
+// GODEBUG=gocachehash=1 causes the go command to print the inputs
+// for all of the content hashes it uses to construct cache lookup keys.
+// The output is voluminous but can be useful for debugging the cache.
+//
+// GODEBUG=gocachetest=1 causes the go command to print details of its
+// decisions about whether to reuse a cached test result.
+//
+//
 // File types
 //
 // The go command examines the contents of a restricted set of files
@@ -917,8 +1030,10 @@
 // comment, indicating that the package sources are included
 // for documentation only and must not be used to build the
 // package binary. This enables distribution of Go packages in
-// their compiled form alone. See the go/build package documentation
-// for more details.
+// their compiled form alone. Even binary-only packages require
+// accurate import blocks listing required dependencies, so that
+// those dependencies can be supplied when linking the resulting
+// command.
 //
 //
 // GOPATH environment variable
@@ -1096,6 +1211,12 @@
 // 		See https://golang.org/doc/articles/race_detector.html.
 // 	GOROOT
 // 		The root of the go tree.
+// 	GOTMPDIR
+// 		The directory where the go command will write
+// 		temporary source files, packages, and binaries.
+// 	GOCACHE
+// 		The directory where the go command will store
+// 		cached information for reuse in future builds.
 //
 // Environment variables for use with cgo:
 //
@@ -1106,17 +1227,26 @@
 // 	CGO_CFLAGS
 // 		Flags that cgo will pass to the compiler when compiling
 // 		C code.
-// 	CGO_CPPFLAGS
-// 		Flags that cgo will pass to the compiler when compiling
-// 		C or C++ code.
-// 	CGO_CXXFLAGS
-// 		Flags that cgo will pass to the compiler when compiling
-// 		C++ code.
-// 	CGO_FFLAGS
-// 		Flags that cgo will pass to the compiler when compiling
-// 		Fortran code.
-// 	CGO_LDFLAGS
-// 		Flags that cgo will pass to the compiler when linking.
+// 	CGO_CFLAGS_ALLOW
+// 		A regular expression specifying additional flags to allow
+// 		to appear in #cgo CFLAGS source code directives.
+// 		Does not apply to the CGO_CFLAGS environment variable.
+// 	CGO_CFLAGS_DISALLOW
+// 		A regular expression specifying flags that must be disallowed
+// 		from appearing in #cgo CFLAGS source code directives.
+// 		Does not apply to the CGO_CFLAGS environment variable.
+// 	CGO_CPPFLAGS, CGO_CPPFLAGS_ALLOW, CGO_CPPFLAGS_DISALLOW
+// 		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+// 		but for the C preprocessor.
+// 	CGO_CXXFLAGS, CGO_CXXFLAGS_ALLOW, CGO_CXXFLAGS_DISALLOW
+// 		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+// 		but for the C++ compiler.
+// 	CGO_FFLAGS, CGO_FFLAGS_ALLOW, CGO_FFLAGS_DISALLOW
+// 		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+// 		but for the Fortran compiler.
+// 	CGO_LDFLAGS, CGO_LDFLAGS_ALLOW, CGO_LDFLAGS_DISALLOW
+// 		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+// 		but for the linker.
 // 	CXX
 // 		The command to use to compile C++ code.
 // 	PKG_CONFIG
@@ -1130,6 +1260,9 @@
 // 	GO386
 // 		For GOARCH=386, the floating point instruction set.
 // 		Valid values are 387, sse2.
+// 	GOMIPS
+// 		For GOARCH=mips{,le}, whether to use floating point instructions.
+// 		Valid values are hardfloat (default), softfloat.
 //
 // Special-purpose environment variables:
 //
@@ -1321,7 +1454,7 @@
 // See https://golang.org/s/go14customimport for details.
 //
 //
-// Description of package lists
+// Package lists
 //
 // Many commands apply to a set of packages:
 //
@@ -1403,7 +1536,7 @@
 // by the go tool, as are directories named "testdata".
 //
 //
-// Description of testing flags
+// Testing flags
 //
 // The 'go test' command takes both flags that apply to 'go test' itself
 // and flags that apply to the resulting test binary.
@@ -1457,10 +1590,10 @@
 // 			significantly more expensive.
 // 	    Sets -cover.
 //
-// 	-coverpkg pkg1,pkg2,pkg3
-// 	    Apply coverage analysis in each test to the given list of packages.
+// 	-coverpkg pattern1,pattern2,pattern3
+// 	    Apply coverage analysis in each test to packages matching the patterns.
 // 	    The default is for each test to analyze only the package being tested.
-// 	    Packages are specified as import paths.
+// 	    See 'go help packages' for a description of package patterns.
 // 	    Sets -cover.
 //
 // 	-cpu 1,2,4
@@ -1468,6 +1601,9 @@
 // 	    benchmarks should be executed. The default is the current value
 // 	    of GOMAXPROCS.
 //
+// 	-failfast
+// 	    Do not start new tests after the first test failure.
+//
 // 	-list regexp
 // 	    List tests, benchmarks, or examples matching the regular expression.
 // 	    No tests, benchmarks or examples will be run. This will only
@@ -1500,12 +1636,20 @@
 //
 // 	-timeout d
 // 	    If a test binary runs longer than duration d, panic.
+// 	    If d is 0, the timeout is disabled.
 // 	    The default is 10 minutes (10m).
 //
 // 	-v
 // 	    Verbose output: log all tests as they are run. Also print all
 // 	    text from Log and Logf calls even if the test succeeds.
 //
+// 	-vet list
+// 	    Configure the invocation of "go vet" during "go test"
+// 	    to use the comma-separated list of vet checks.
+// 	    If list is empty, "go test" runs "go vet" with a curated list of
+// 	    checks believed to be always worth addressing.
+// 	    If list is "off", "go test" does not run "go vet" at all.
+//
 // The following flags are also recognized by 'go test' and can be used to
 // profile the tests during execution:
 //
@@ -1619,19 +1763,19 @@
 // binary, instead of being interpreted as the package list.
 //
 //
-// Description of testing functions
+// Testing functions
 //
 // The 'go test' command expects to find test, benchmark, and example functions
 // in the "*_test.go" files corresponding to the package under test.
 //
-// A test function is one named TestXXX (where XXX is any alphanumeric string
-// not starting with a lower case letter) and should have the signature,
+// A test function is one named TestXxx (where Xxx does not start with a
+// lower case letter) and should have the signature,
 //
-// 	func TestXXX(t *testing.T) { ... }
+// 	func TestXxx(t *testing.T) { ... }
 //
-// A benchmark function is one named BenchmarkXXX and should have the signature,
+// A benchmark function is one named BenchmarkXxx and should have the signature,
 //
-// 	func BenchmarkXXX(b *testing.B) { ... }
+// 	func BenchmarkXxx(b *testing.B) { ... }
 //
 // An example function is similar to a test function but, instead of using
 // *testing.T to report success or failure, prints output to os.Stdout.
@@ -1642,8 +1786,8 @@
 // comment is compiled but not executed. An example with no text after
 // "Output:" is compiled, executed, and expected to produce no output.
 //
-// Godoc displays the body of ExampleXXX to demonstrate the use
-// of the function, constant, or variable XXX. An example of a method M with
+// Godoc displays the body of ExampleXxx to demonstrate the use
+// of the function, constant, or variable Xxx. An example of a method M with
 // receiver type T or *T is named ExampleT_M. There may be multiple examples
 // for a given function, constant, or variable, distinguished by a trailing _xxx,
 // where xxx is a suffix not beginning with an upper case letter.
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 7d80d96..3972d79 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -6,6 +6,8 @@
 
 import (
 	"bytes"
+	"debug/elf"
+	"debug/macho"
 	"fmt"
 	"go/format"
 	"internal/race"
@@ -27,12 +29,23 @@
 	canRun  = true  // whether we can run go or ./testgo
 	canRace = false // whether we can run the race detector
 	canCgo  = false // whether we can use cgo
+	canMSan = false // whether we can run the memory sanitizer
 
 	exeSuffix string // ".exe" on Windows
 
 	skipExternal = false // skip external tests
 )
 
+func tooSlow(t *testing.T) {
+	if testing.Short() {
+		// In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
+		if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
+			return
+		}
+		t.Skip("skipping test in -short mode")
+	}
+}
+
 func init() {
 	switch runtime.GOOS {
 	case "android", "nacl":
@@ -68,6 +81,13 @@
 			skipExternal = true
 			canRun = false
 		}
+	case "plan9":
+		switch runtime.GOARCH {
+		case "arm":
+			// many plan9/arm machines are too slow to run
+			// the full set of external tests.
+			skipExternal = true
+		}
 	case "windows":
 		exeSuffix = ".exe"
 	}
@@ -83,25 +103,62 @@
 // The TestMain function creates a go command for testing purposes and
 // deletes it after the tests have been run.
 func TestMain(m *testing.M) {
+	if os.Getenv("GO_GCFLAGS") != "" {
+		fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
+		fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
+		fmt.Printf("SKIP\n")
+		return
+	}
+	os.Unsetenv("GOROOT_FINAL")
+
 	if canRun {
 		args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
 		if race.Enabled {
 			args = append(args, "-race")
 		}
-		out, err := exec.Command("go", args...).CombinedOutput()
+		gotool, err := testenv.GoTool()
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			os.Exit(2)
+		}
+
+		goEnv := func(name string) string {
+			out, err := exec.Command(gotool, "env", name).CombinedOutput()
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
+				os.Exit(2)
+			}
+			return strings.TrimSpace(string(out))
+		}
+		testGOROOT = goEnv("GOROOT")
+
+		// The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
+		// toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
+		// The testgo.exe we are about to create will be built for GOOS/GOARCH,
+		// which means it will use the GOOS/GOARCH toolchain
+		// (installed in GOROOT/pkg/tool/GOOS_GOARCH).
+		// If these are not the same toolchain, then the entire standard library
+		// will look out of date (the compilers in those two different tool directories
+		// are built for different architectures and have different buid IDs),
+		// which will cause many tests to do unnecessary rebuilds and some
+		// tests to attempt to overwrite the installed standard library.
+		// Bail out entirely in this case.
+		hostGOOS := goEnv("GOHOSTOS")
+		hostGOARCH := goEnv("GOHOSTARCH")
+		if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
+			fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
+			fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
+			fmt.Printf("SKIP\n")
+			return
+		}
+
+		out, err := exec.Command(gotool, args...).CombinedOutput()
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
 			os.Exit(2)
 		}
 
-		out, err = exec.Command("go", "env", "GOROOT").CombinedOutput()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "could not find testing GOROOT: %v\n%s", err, out)
-			os.Exit(2)
-		}
-		testGOROOT = strings.TrimSpace(string(out))
-
-		out, err = exec.Command("go", "env", "CC").CombinedOutput()
+		out, err = exec.Command(gotool, "env", "CC").CombinedOutput()
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
 			os.Exit(2)
@@ -118,6 +175,10 @@
 			}
 		}
 
+		// As of Sept 2017, MSan is only supported on linux/amd64.
+		// https://github.com/google/sanitizers/wiki/MemorySanitizer#getting-memorysanitizer
+		canMSan = canCgo && runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
+
 		switch runtime.GOOS {
 		case "linux", "darwin", "freebsd", "windows":
 			// The race detector doesn't work on Alpine Linux:
@@ -125,7 +186,6 @@
 			canRace = canCgo && runtime.GOARCH == "amd64" && !isAlpineLinux()
 		}
 	}
-
 	// Don't let these environment variables confuse the test.
 	os.Unsetenv("GOBIN")
 	os.Unsetenv("GOPATH")
@@ -137,6 +197,9 @@
 		os.Setenv("CCACHE_DIR", filepath.Join(home, ".ccache"))
 	}
 	os.Setenv("HOME", "/test-go-home-does-not-exist")
+	if os.Getenv("GOCACHE") == "" {
+		os.Setenv("GOCACHE", "off") // because $HOME is gone
+	}
 
 	r := m.Run()
 
@@ -175,10 +238,11 @@
 
 // testgo sets up for a test that runs testgo.
 func testgo(t *testing.T) *testgoData {
+	t.Helper()
 	testenv.MustHaveGoBuild(t)
 
 	if skipExternal {
-		t.Skip("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
+		t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
 
 	return &testgoData{t: t}
@@ -186,6 +250,7 @@
 
 // must gives a fatal error if err is not nil.
 func (tg *testgoData) must(err error) {
+	tg.t.Helper()
 	if err != nil {
 		tg.t.Fatal(err)
 	}
@@ -193,6 +258,7 @@
 
 // check gives a test non-fatal error if err is not nil.
 func (tg *testgoData) check(err error) {
+	tg.t.Helper()
 	if err != nil {
 		tg.t.Error(err)
 	}
@@ -200,6 +266,7 @@
 
 // parallel runs the test in parallel by calling t.Parallel.
 func (tg *testgoData) parallel() {
+	tg.t.Helper()
 	if tg.ran {
 		tg.t.Fatal("internal testsuite error: call to parallel after run")
 	}
@@ -220,6 +287,7 @@
 
 // pwd returns the current directory.
 func (tg *testgoData) pwd() string {
+	tg.t.Helper()
 	wd, err := os.Getwd()
 	if err != nil {
 		tg.t.Fatalf("could not get working directory: %v", err)
@@ -231,6 +299,7 @@
 // using this means that the test must not be run in parallel with any
 // other tests.
 func (tg *testgoData) cd(dir string) {
+	tg.t.Helper()
 	if tg.inParallel {
 		tg.t.Fatal("internal testsuite error: changing directory when running in parallel")
 	}
@@ -254,6 +323,7 @@
 // setenv sets an environment variable to use when running the test go
 // command.
 func (tg *testgoData) setenv(name, val string) {
+	tg.t.Helper()
 	if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
 		tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
 	}
@@ -284,6 +354,7 @@
 // doRun runs the test go command, recording stdout and stderr and
 // returning exit status.
 func (tg *testgoData) doRun(args []string) error {
+	tg.t.Helper()
 	if !canRun {
 		panic("testgoData.doRun called but canRun false")
 	}
@@ -329,6 +400,7 @@
 
 // run runs the test go command, and expects it to succeed.
 func (tg *testgoData) run(args ...string) {
+	tg.t.Helper()
 	if status := tg.doRun(args); status != nil {
 		tg.t.Logf("go %v failed unexpectedly: %v", args, status)
 		tg.t.FailNow()
@@ -337,6 +409,7 @@
 
 // runFail runs the test go command, and expects it to fail.
 func (tg *testgoData) runFail(args ...string) {
+	tg.t.Helper()
 	if status := tg.doRun(args); status == nil {
 		tg.t.Fatal("testgo succeeded unexpectedly")
 	} else {
@@ -346,6 +419,7 @@
 
 // runGit runs a git command, and expects it to succeed.
 func (tg *testgoData) runGit(dir string, args ...string) {
+	tg.t.Helper()
 	cmd := exec.Command("git", args...)
 	tg.stdout.Reset()
 	tg.stderr.Reset()
@@ -370,6 +444,7 @@
 
 // getStdout returns standard output of the testgo run as a string.
 func (tg *testgoData) getStdout() string {
+	tg.t.Helper()
 	if !tg.ran {
 		tg.t.Fatal("internal testsuite error: stdout called before run")
 	}
@@ -378,6 +453,7 @@
 
 // getStderr returns standard error of the testgo run as a string.
 func (tg *testgoData) getStderr() string {
+	tg.t.Helper()
 	if !tg.ran {
 		tg.t.Fatal("internal testsuite error: stdout called before run")
 	}
@@ -388,6 +464,7 @@
 // whether it is found. The regular expression is matched against
 // each line separately, as with the grep command.
 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
+	tg.t.Helper()
 	if !tg.ran {
 		tg.t.Fatal("internal testsuite error: grep called before run")
 	}
@@ -405,6 +482,7 @@
 // searching, "output" or "error". The msg argument is logged on
 // failure.
 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
+	tg.t.Helper()
 	if !tg.doGrepMatch(match, b) {
 		tg.t.Log(msg)
 		tg.t.Logf("pattern %v not found in standard %s", match, name)
@@ -415,18 +493,21 @@
 // grepStdout looks for a regular expression in the test run's
 // standard output and fails, logging msg, if it is not found.
 func (tg *testgoData) grepStdout(match, msg string) {
+	tg.t.Helper()
 	tg.doGrep(match, &tg.stdout, "output", msg)
 }
 
 // grepStderr looks for a regular expression in the test run's
 // standard error and fails, logging msg, if it is not found.
 func (tg *testgoData) grepStderr(match, msg string) {
+	tg.t.Helper()
 	tg.doGrep(match, &tg.stderr, "error", msg)
 }
 
 // grepBoth looks for a regular expression in the test run's standard
 // output or stand error and fails, logging msg, if it is not found.
 func (tg *testgoData) grepBoth(match, msg string) {
+	tg.t.Helper()
 	if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
 		tg.t.Log(msg)
 		tg.t.Logf("pattern %v not found in standard output or standard error", match)
@@ -437,6 +518,7 @@
 // doGrepNot looks for a regular expression in a buffer and fails if
 // it is found. The name and msg arguments are as for doGrep.
 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
+	tg.t.Helper()
 	if tg.doGrepMatch(match, b) {
 		tg.t.Log(msg)
 		tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
@@ -447,12 +529,14 @@
 // grepStdoutNot looks for a regular expression in the test run's
 // standard output and fails, logging msg, if it is found.
 func (tg *testgoData) grepStdoutNot(match, msg string) {
+	tg.t.Helper()
 	tg.doGrepNot(match, &tg.stdout, "output", msg)
 }
 
 // grepStderrNot looks for a regular expression in the test run's
 // standard error and fails, logging msg, if it is found.
 func (tg *testgoData) grepStderrNot(match, msg string) {
+	tg.t.Helper()
 	tg.doGrepNot(match, &tg.stderr, "error", msg)
 }
 
@@ -460,6 +544,7 @@
 // standard output or stand error and fails, logging msg, if it is
 // found.
 func (tg *testgoData) grepBothNot(match, msg string) {
+	tg.t.Helper()
 	if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
 		tg.t.Log(msg)
 		tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
@@ -468,6 +553,7 @@
 
 // doGrepCount counts the number of times a regexp is seen in a buffer.
 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
+	tg.t.Helper()
 	if !tg.ran {
 		tg.t.Fatal("internal testsuite error: doGrepCount called before run")
 	}
@@ -484,6 +570,7 @@
 // grepCountBoth returns the number of times a regexp is seen in both
 // standard output and standard error.
 func (tg *testgoData) grepCountBoth(match string) int {
+	tg.t.Helper()
 	return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
 }
 
@@ -492,6 +579,7 @@
 // removed. When the test completes, the file or directory will be
 // removed if it exists.
 func (tg *testgoData) creatingTemp(path string) {
+	tg.t.Helper()
 	if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
 		tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
 	}
@@ -508,6 +596,7 @@
 // makeTempdir makes a temporary directory for a run of testgo. If
 // the temporary directory was already created, this does nothing.
 func (tg *testgoData) makeTempdir() {
+	tg.t.Helper()
 	if tg.tempdir == "" {
 		var err error
 		tg.tempdir, err = ioutil.TempDir("", "gotest")
@@ -517,6 +606,7 @@
 
 // tempFile adds a temporary file for a run of testgo.
 func (tg *testgoData) tempFile(path, contents string) {
+	tg.t.Helper()
 	tg.makeTempdir()
 	tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
 	bytes := []byte(contents)
@@ -531,6 +621,7 @@
 
 // tempDir adds a temporary directory for a run of testgo.
 func (tg *testgoData) tempDir(path string) {
+	tg.t.Helper()
 	tg.makeTempdir()
 	if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
 		tg.t.Fatal(err)
@@ -540,6 +631,7 @@
 // path returns the absolute pathname to file with the temporary
 // directory.
 func (tg *testgoData) path(name string) string {
+	tg.t.Helper()
 	if tg.tempdir == "" {
 		tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
 	}
@@ -551,6 +643,7 @@
 
 // mustExist fails if path does not exist.
 func (tg *testgoData) mustExist(path string) {
+	tg.t.Helper()
 	if _, err := os.Stat(path); err != nil {
 		if os.IsNotExist(err) {
 			tg.t.Fatalf("%s does not exist but should", path)
@@ -561,13 +654,28 @@
 
 // mustNotExist fails if path exists.
 func (tg *testgoData) mustNotExist(path string) {
+	tg.t.Helper()
 	if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
 		tg.t.Fatalf("%s exists but should not (%v)", path, err)
 	}
 }
 
+// mustHaveContent succeeds if filePath is a path to a file,
+// and that file is readable and not empty.
+func (tg *testgoData) mustHaveContent(filePath string) {
+	tg.mustExist(filePath)
+	f, err := os.Stat(filePath)
+	if err != nil {
+		tg.t.Fatal(err)
+	}
+	if f.Size() == 0 {
+		tg.t.Fatalf("expected %s to have data, but is empty", filePath)
+	}
+}
+
 // wantExecutable fails with msg if path is not executable.
 func (tg *testgoData) wantExecutable(path, msg string) {
+	tg.t.Helper()
 	if st, err := os.Stat(path); err != nil {
 		if !os.IsNotExist(err) {
 			tg.t.Log(err)
@@ -582,6 +690,7 @@
 
 // wantArchive fails if path is not an archive.
 func (tg *testgoData) wantArchive(path string) {
+	tg.t.Helper()
 	f, err := os.Open(path)
 	if err != nil {
 		tg.t.Fatal(err)
@@ -596,6 +705,7 @@
 
 // isStale reports whether pkg is stale, and why
 func (tg *testgoData) isStale(pkg string) (bool, string) {
+	tg.t.Helper()
 	tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
 	v := strings.TrimSpace(tg.getStdout())
 	f := strings.SplitN(v, ":", 2)
@@ -613,6 +723,7 @@
 
 // wantStale fails with msg if pkg is not stale.
 func (tg *testgoData) wantStale(pkg, reason, msg string) {
+	tg.t.Helper()
 	stale, why := tg.isStale(pkg)
 	if !stale {
 		tg.t.Fatal(msg)
@@ -624,6 +735,7 @@
 
 // wantNotStale fails with msg if pkg is stale.
 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
+	tg.t.Helper()
 	stale, why := tg.isStale(pkg)
 	if stale {
 		tg.t.Fatal(msg)
@@ -635,6 +747,7 @@
 
 // cleanup cleans up a test that runs testgo.
 func (tg *testgoData) cleanup() {
+	tg.t.Helper()
 	if tg.wd != "" {
 		if err := os.Chdir(tg.wd); err != nil {
 			// We are unlikely to be able to continue.
@@ -653,6 +766,7 @@
 // failSSH puts an ssh executable in the PATH that always fails.
 // This is to stub out uses of ssh by go get.
 func (tg *testgoData) failSSH() {
+	tg.t.Helper()
 	wd, err := os.Getwd()
 	if err != nil {
 		tg.t.Fatal(err)
@@ -661,6 +775,20 @@
 	tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
 }
 
+func TestBuildComplex(t *testing.T) {
+	// Simple smoke test for build configuration.
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("build", "-x", "-o", os.DevNull, "complex")
+
+	if _, err := exec.LookPath("gccgo"); err == nil {
+		t.Skip("golang.org/issue/22472")
+		tg.run("build", "-x", "-o", os.DevNull, "-compiler=gccgo", "complex")
+	}
+}
+
 func TestFileLineInErrorMessages(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -759,40 +887,36 @@
 		}
 	}
 
-	tg.setenv("TESTGO_IS_GO_RELEASE", "1")
-
 	tg.tempFile("d1/src/p1/p1.go", `package p1`)
 	tg.setenv("GOPATH", tg.path("d1"))
 	tg.run("install", "-a", "p1")
-	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly")
-	tg.sleep()
+	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
 
-	// Changing mtime and content of runtime/internal/sys/sys.go
-	// should have no effect: we're in a release, which doesn't rebuild
-	// for general mtime or content changes.
+	// Changing mtime of runtime/internal/sys/sys.go
+	// should have no effect: only the content matters.
+	// In fact this should be true even outside a release branch.
 	sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go"
+	tg.sleep()
 	restore := addNL(sys)
-	defer restore()
-	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating runtime/internal/sys/sys.go")
 	restore()
-	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after restoring runtime/internal/sys/sys.go")
+	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
 
-	// But changing runtime/internal/sys/zversion.go should have an effect:
-	// that's how we tell when we flip from one release to another.
-	zversion := runtime.GOROOT() + "/src/runtime/internal/sys/zversion.go"
-	restore = addNL(zversion)
+	// But changing content of any file should have an effect.
+	// Previously zversion.go was the only one that mattered;
+	// now they all matter, so keep using sys.go.
+	restore = addNL(sys)
 	defer restore()
-	tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing to new release")
+	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
 	restore()
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
-	addNL(zversion)
-	tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing again to new release")
+	addNL(sys)
+	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
 	tg.run("install", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
 
 	// Restore to "old" release.
 	restore()
-	tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing to old release after new build")
+	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
 	tg.run("install", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
 
@@ -801,6 +925,7 @@
 }
 
 func TestGoListStandard(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -826,6 +951,7 @@
 }
 
 func TestGoInstallCleansUpAfterGoBuild(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -868,6 +994,7 @@
 }
 
 func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -878,7 +1005,7 @@
 		func F() {}`)
 	sep := string(filepath.ListSeparator)
 	tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
-	tg.run("install", "p1")
+	tg.run("install", "-i", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly")
 	tg.wantNotStale("p2", "", "./testgo list claims p2 is stale, incorrectly")
 	tg.sleep()
@@ -889,10 +1016,10 @@
 	} else {
 		tg.must(f.Close())
 	}
-	tg.wantStale("p2", "newer source file", "./testgo list claims p2 is NOT stale, incorrectly")
-	tg.wantStale("p1", "stale dependency", "./testgo list claims p1 is NOT stale, incorrectly")
+	tg.wantStale("p2", "build ID mismatch", "./testgo list claims p2 is NOT stale, incorrectly")
+	tg.wantStale("p1", "stale dependency: p2", "./testgo list claims p1 is NOT stale, incorrectly")
 
-	tg.run("install", "p1")
+	tg.run("install", "-i", "p1")
 	tg.wantNotStale("p2", "", "./testgo list claims p2 is stale after reinstall, incorrectly")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after reinstall, incorrectly")
 }
@@ -967,6 +1094,7 @@
 }
 
 func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -988,6 +1116,7 @@
 }
 
 func testLocalRun(tg *testgoData, exepath, local, match string) {
+	tg.t.Helper()
 	out, err := exec.Command(exepath).Output()
 	if err != nil {
 		tg.t.Fatalf("error running %v: %v", exepath, err)
@@ -999,6 +1128,7 @@
 }
 
 func testLocalEasy(tg *testgoData, local string) {
+	tg.t.Helper()
 	exepath := "./easy" + exeSuffix
 	tg.creatingTemp(exepath)
 	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go"))
@@ -1006,6 +1136,7 @@
 }
 
 func testLocalEasySub(tg *testgoData, local string) {
+	tg.t.Helper()
 	exepath := "./easysub" + exeSuffix
 	tg.creatingTemp(exepath)
 	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go"))
@@ -1013,6 +1144,7 @@
 }
 
 func testLocalHard(tg *testgoData, local string) {
+	tg.t.Helper()
 	exepath := "./hard" + exeSuffix
 	tg.creatingTemp(exepath)
 	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go"))
@@ -1020,6 +1152,7 @@
 }
 
 func testLocalInstall(tg *testgoData, local string) {
+	tg.t.Helper()
 	tg.runFail("install", filepath.Join("testdata", local, "easy.go"))
 }
 
@@ -1050,6 +1183,7 @@
 const badDirName = `#$%:, &()*;<=>?\^{}`
 
 func copyBad(tg *testgoData) {
+	tg.t.Helper()
 	if runtime.GOOS == "windows" {
 		tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName)
 	}
@@ -1164,7 +1298,7 @@
 	tg.runFail("get", "-d", "-u", url)
 	tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason")
 	tg.runFail("get", "-d", "-f", "-u", url)
-	tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason")
+	tg.grepStderr("validating server certificate|[nN]ot [fF]ound", "go get -d -f -u "+url+" failed for wrong reason")
 }
 
 func TestInternalPackageErrorsAreHandled(t *testing.T) {
@@ -1185,10 +1319,9 @@
 	testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config")
 }
 
-// TODO(rsc): Set up a test case on bitbucket for hg.
-// func TestMoveHG(t *testing.T) {
-// 	testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc")
-// }
+func TestMoveHG(t *testing.T) {
+	testMove(t, "hg", "vcs-test.golang.org/go/custom-hg-hello", "custom-hg-hello", "vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc")
+}
 
 // TODO(rsc): Set up a test case on SourceForge (?) for svn.
 // func testMoveSVN(t *testing.T) {
@@ -1317,6 +1450,25 @@
 	tg.grepStdout(`\* another-branch`, "not on correct default branch")
 }
 
+func TestAccidentalGitCheckout(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+	if _, err := exec.LookPath("git"); err != nil {
+		t.Skip("skipping because git binary not found")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", tg.path("."))
+
+	tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
+	tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
+
+	tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
+	tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
+}
+
 func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1343,6 +1495,10 @@
 func TestRelativeImportsGoTestDashI(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
+
+	// don't let test -i overwrite runtime
+	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
+
 	tg.run("test", "-i", "./testdata/testimport")
 }
 
@@ -1389,6 +1545,28 @@
 	tg.grepStderr("build constraints exclude all Go files", "go install cgotest did not report 'build constraints exclude all Go files'")
 }
 
+// Issue 21895
+func TestMSanAndRaceRequireCgo(t *testing.T) {
+	if !canMSan && !canRace {
+		t.Skip("skipping because both msan and the race detector are not supported")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("triv.go", `package main; func main() {}`)
+	tg.setenv("CGO_ENABLED", "0")
+	if canRace {
+		tg.runFail("install", "-race", "triv.go")
+		tg.grepStderr("-race requires cgo", "did not correctly report that -race requires cgo")
+		tg.grepStderrNot("-msan", "reported that -msan instead of -race requires cgo")
+	}
+	if canMSan {
+		tg.runFail("install", "-msan", "triv.go")
+		tg.grepStderr("-msan requires cgo", "did not correctly report that -msan requires cgo")
+		tg.grepStderrNot("-race", "reported that -race instead of -msan requires cgo")
+	}
+}
+
 func TestRelativeGOBINFail(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1418,6 +1596,7 @@
 }
 
 func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1433,6 +1612,19 @@
 	tg.run("test", "main_test")
 }
 
+func TestPackageMainTestCompilerFlags(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.tempFile("src/p1/p1.go", "package main\n")
+	tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
+	tg.run("test", "-c", "-n", "p1")
+	tg.grepBothNot(`[\\/]compile.* -p main.*p1\.go`, "should not have run compile -p main p1.go")
+	tg.grepStderr(`[\\/]compile.* -p p1.*p1\.go`, "should have run compile -p p1 p1.go")
+}
+
 // 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
@@ -1445,19 +1637,16 @@
 	defer tg.cleanup()
 
 	// Make sure the packages below are not stale.
-	tg.run("install", "runtime", "os", "io")
+	tg.wantNotStale("runtime", "", "must be non-stale before test runs")
+	tg.wantNotStale("os", "", "must be non-stale before test runs")
+	tg.wantNotStale("io", "", "must be non-stale before test runs")
 
 	goroot := runtime.GOROOT()
 	tg.setenv("GOROOT", goroot+"/")
 
-	want := ""
-	if isGoRelease {
-		want = "standard package in Go release distribution"
-	}
-
-	tg.wantNotStale("runtime", want, "with trailing slash in GOROOT, runtime listed as stale")
-	tg.wantNotStale("os", want, "with trailing slash in GOROOT, os listed as stale")
-	tg.wantNotStale("io", want, "with trailing slash in GOROOT, io listed as stale")
+	tg.wantNotStale("runtime", "", "with trailing slash in GOROOT, runtime listed as stale")
+	tg.wantNotStale("os", "", "with trailing slash in GOROOT, os listed as stale")
+	tg.wantNotStale("io", "", "with trailing slash in GOROOT, io listed as stale")
 }
 
 // With $GOBIN set, binaries get installed to $GOBIN.
@@ -1599,8 +1788,30 @@
 	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
 }
 
+// Issue 21928.
+func TestRejectBlankPathsInGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", " "+sep+filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("build", "go-cmd-test")
+	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
+}
+
+// Issue 21928.
+func TestIgnoreEmptyPathsInGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix)
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", ""+sep+filepath.Join(tg.pwd(), "testdata"))
+	tg.run("install", "go-cmd-test")
+	tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test")
+}
+
 // Issue 4104.
 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1611,6 +1822,7 @@
 }
 
 func TestGoListHasAConsistentOrder(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1623,6 +1835,7 @@
 }
 
 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1631,6 +1844,7 @@
 }
 
 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1657,6 +1871,20 @@
 	}
 }
 
+func TestGoListDeps(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src/p1/p2/p3/p4")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
+	tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
+	tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
+	tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
+	tg.run("list", "-f", "{{.Deps}}", "p1")
+	tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
+}
+
 // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
 	tg := testgo(t)
@@ -1835,6 +2063,7 @@
 }
 
 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1848,6 +2077,7 @@
 }
 
 func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -1858,6 +2088,7 @@
 }
 
 func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -1868,6 +2099,7 @@
 }
 
 func TestGoTestMutexprofileLeavesBinaryBehind(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -1878,6 +2110,7 @@
 }
 
 func TestGoTestMutexprofileDashOControlsBinaryLocation(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
@@ -1887,7 +2120,18 @@
 	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -mutexprofile -o myerrors.test did not create myerrors.test")
 }
 
+func TestGoBuildNonMain(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	// TODO: tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("build", "-buildmode=exe", "-o", "not_main"+exeSuffix, "not_main")
+	tg.grepStderr("-buildmode=exe requires exactly one main package", "go build with -o and -buildmode=exe should on a non-main package should throw an error")
+	tg.mustNotExist("not_main" + exeSuffix)
+}
+
 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1897,6 +2141,7 @@
 }
 
 func TestGoTestDashOWritesBinary(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -1906,10 +2151,15 @@
 }
 
 func TestGoTestDashIDashOWritesBinary(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
 	tg.makeTempdir()
+
+	// don't let test -i overwrite runtime
+	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
+
 	tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
 	tg.grepBothNot("PASS|FAIL", "test should not have run")
 	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
@@ -1999,6 +2249,7 @@
 
 // Issue 4515.
 func TestInstallWithTags(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -2082,7 +2333,7 @@
 	tg.tempDir("yy/zz")
 	tg.tempFile("yy/zz/zz.go", "package zz\n")
 	if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
-		t.Skip("symlink failed: %v", err)
+		t.Skipf("symlink failed: %v", err)
 	}
 	tg.run("list", "example/xx/z...")
 	tg.grepStdoutNot(".", "list should not have matched anything")
@@ -2176,16 +2427,14 @@
 // Check that coverage analysis works at all.
 // Don't worry about the exact numbers but require not 0.0%.
 func checkCoverage(tg *testgoData, data string) {
+	tg.t.Helper()
 	if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) {
 		tg.t.Error("some coverage results are 0.0%")
 	}
-	tg.t.Log(data)
 }
 
 func TestCoverageRuns(t *testing.T) {
-	if testing.Short() {
-		t.Skip("don't build libraries for coverage in short mode")
-	}
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp")
@@ -2195,15 +2444,24 @@
 	checkCoverage(tg, data)
 }
 
+func TestCoverageDotImport(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("test", "-coverpkg=coverdot1,coverdot2", "coverdot2")
+	data := tg.getStdout() + tg.getStderr()
+	checkCoverage(tg, data)
+}
+
 // Check that coverage analysis uses set mode.
+// Also check that coverage profiles merge correctly.
 func TestCoverageUsesSetMode(t *testing.T) {
-	if testing.Short() {
-		t.Skip("don't build libraries for coverage in short mode")
-	}
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.creatingTemp("testdata/cover.out")
-	tg.run("test", "-short", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
+	tg.run("test", "-short", "-cover", "encoding/binary", "errors", "-coverprofile=testdata/cover.out")
 	data := tg.getStdout() + tg.getStderr()
 	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
 		t.Error(err)
@@ -2211,14 +2469,21 @@
 		if !bytes.Contains(out, []byte("mode: set")) {
 			t.Error("missing mode: set")
 		}
+		if !bytes.Contains(out, []byte("errors.go")) {
+			t.Error("missing errors.go")
+		}
+		if !bytes.Contains(out, []byte("binary.go")) {
+			t.Error("missing binary.go")
+		}
+		if bytes.Count(out, []byte("mode: set")) != 1 {
+			t.Error("too many mode: set")
+		}
 	}
 	checkCoverage(tg, data)
 }
 
 func TestCoverageUsesAtomicModeForRace(t *testing.T) {
-	if testing.Short() {
-		t.Skip("don't build libraries for coverage in short mode")
-	}
+	tooSlow(t)
 	if !canRace {
 		t.Skip("skipping because race detector not supported")
 	}
@@ -2238,6 +2503,27 @@
 	checkCoverage(tg, data)
 }
 
+func TestCoverageSyncAtomicImport(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("test", "-short", "-cover", "-covermode=atomic", "-coverpkg=coverdep/p1", "coverdep")
+}
+
+func TestCoverageDepLoop(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	// coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1.
+	// Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2.
+	tg.run("test", "-short", "-cover", "coverdep2/p1")
+	tg.grepStdout("coverage: 100.0% of statements", "expected 100.0% coverage")
+}
+
 func TestCoverageImportMainLoop(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -2248,6 +2534,78 @@
 	tg.grepStderr("not an importable package", "did not detect import main")
 }
 
+func TestCoveragePattern(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+	// If coverpkg=sleepy... expands by package loading
+	// (as opposed to pattern matching on deps)
+	// then it will try to load sleepybad, which does not compile,
+	// and the test command will fail.
+	tg.run("test", "-coverprofile="+tg.path("cover.out"), "-coverpkg=sleepy...", "-run=^$", "sleepy1")
+}
+
+func TestCoverageErrorLine(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GOTMPDIR", tg.tempdir)
+
+	tg.runFail("test", "coverbad")
+	tg.grepStderr(`coverbad[\\/]p\.go:4`, "did not find coverbad/p.go:4")
+	if canCgo {
+		tg.grepStderr(`coverbad[\\/]p1\.go:6`, "did not find coverbad/p1.go:6")
+	}
+	tg.grepStderrNot(regexp.QuoteMeta(tg.tempdir), "found temporary directory in error")
+	stderr := tg.getStderr()
+
+	tg.runFail("test", "-cover", "coverbad")
+	stderr2 := tg.getStderr()
+
+	// It's OK that stderr2 drops the character position in the error,
+	// because of the //line directive (see golang.org/issue/22662).
+	stderr = strings.Replace(stderr, "p.go:4:2:", "p.go:4:", -1)
+	if stderr != stderr2 {
+		t.Logf("test -cover changed error messages:\nbefore:\n%s\n\nafter:\n%s", stderr, stderr2)
+		t.Skip("golang.org/issue/22660")
+		t.FailNow()
+	}
+}
+
+func TestTestBuildFailureOutput(t *testing.T) {
+	tooSlow(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+	// Doesn't build, -x output should not claim to run test.
+	tg.runFail("test", "-x", "coverbad")
+	tg.grepStderrNot(`[\\/]coverbad\.test( |$)`, "claimed to run test")
+}
+
+func TestCoverageFunc(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+	tg.run("test", "-outputdir="+tg.tempdir, "-coverprofile=cover.out", "coverasm")
+	tg.run("tool", "cover", "-func="+tg.path("cover.out"))
+	tg.grepStdout(`\tg\t*100.0%`, "did not find g 100% covered")
+	tg.grepStdoutNot(`\tf\t*[0-9]`, "reported coverage for assembly function f")
+}
+
 func TestPluginNonMain(t *testing.T) {
 	wd, err := os.Getwd()
 	if err != nil {
@@ -2310,9 +2668,7 @@
 	if !canRace {
 		t.Skip("no race detector")
 	}
-	if testing.Short() && testenv.Builder() == "" {
-		t.Skip("don't rebuild the standard library in short mode")
-	}
+	tooSlow(t)
 
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -2349,6 +2705,7 @@
 }
 
 func TestCoverageWithCgo(t *testing.T) {
+	tooSlow(t)
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
 	}
@@ -2423,6 +2780,7 @@
 }
 
 func TestCgoHandlesWlORIGIN(t *testing.T) {
+	tooSlow(t)
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
 	}
@@ -2431,7 +2789,7 @@
 	defer tg.cleanup()
 	tg.parallel()
 	tg.tempFile("src/origin/origin.go", `package origin
-		// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
+		// #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN
 		// void f(void) {}
 		import "C"
 		func f() { C.f() }`)
@@ -2440,6 +2798,7 @@
 }
 
 func TestCgoPkgConfig(t *testing.T) {
+	tooSlow(t)
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
 	}
@@ -2485,14 +2844,64 @@
 	tg.run("run", tg.path("foo.go"))
 }
 
-// "go test -c -test.bench=XXX errors" should not hang
+// "go test -c -test.bench=XXX errors" should not hang.
+// "go test -c" should also produce reproducible binaries.
+// "go test -c" should also appear to write a new binary every time,
+// even if it's really just updating the mtime on an existing up-to-date binary.
 func TestIssue6480(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	// TODO: tg.parallel()
 	tg.makeTempdir()
 	tg.cd(tg.path("."))
 	tg.run("test", "-c", "-test.bench=XXX", "errors")
+	tg.run("test", "-c", "-o", "errors2.test", "errors")
+
+	data1, err := ioutil.ReadFile("errors.test" + exeSuffix)
+	tg.must(err)
+	data2, err := ioutil.ReadFile("errors2.test") // no exeSuffix because -o above doesn't have it
+	tg.must(err)
+	if !bytes.Equal(data1, data2) {
+		t.Fatalf("go test -c errors produced different binaries when run twice")
+	}
+
+	start := time.Now()
+	tg.run("test", "-x", "-c", "-test.bench=XXX", "errors")
+	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
+	info, err := os.Stat("errors.test" + exeSuffix)
+	if err != nil {
+		t.Fatal(err)
+	}
+	start = truncateLike(start, info.ModTime())
+	if info.ModTime().Before(start) {
+		t.Fatalf("mtime of errors.test predates test -c command (%v < %v)", info.ModTime(), start)
+	}
+
+	start = time.Now()
+	tg.run("test", "-x", "-c", "-o", "errors2.test", "errors")
+	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
+	info, err = os.Stat("errors2.test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	start = truncateLike(start, info.ModTime())
+	if info.ModTime().Before(start) {
+		t.Fatalf("mtime of errors2.test predates test -c command (%v < %v)", info.ModTime(), start)
+	}
+}
+
+// truncateLike returns the result of truncating t to the apparent precision of p.
+func truncateLike(t, p time.Time) time.Time {
+	nano := p.UnixNano()
+	d := 1 * time.Nanosecond
+	for nano%int64(d) == 0 && d < 1*time.Second {
+		d *= 10
+	}
+	for nano%int64(d) == 0 && d < 2*time.Second {
+		d *= 2
+	}
+	return t.Truncate(d)
 }
 
 // cmd/cgo: undefined reference when linking a C-library using gccgo
@@ -2503,6 +2912,7 @@
 	if _, err := exec.LookPath("gccgo"); err != nil {
 		t.Skip("skipping because no gccgo compiler found")
 	}
+	t.Skip("golang.org/issue/22472")
 
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -2575,6 +2985,8 @@
 }
 
 func TestBuildDashIInstallsDependencies(t *testing.T) {
+	tooSlow(t)
+
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -2585,17 +2997,21 @@
 		func F() { foo.F() }`)
 	tg.setenv("GOPATH", tg.path("."))
 
+	// don't let build -i overwrite runtime
+	tg.wantNotStale("runtime", "", "must be non-stale before build -i")
+
 	checkbar := func(desc string) {
-		tg.sleep()
-		tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now()))
-		tg.sleep()
 		tg.run("build", "-v", "-i", "x/y/bar")
 		tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo")
 		tg.run("build", "-v", "-i", "x/y/bar")
 		tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo")
 	}
 	checkbar("pkg")
+
 	tg.creatingTemp("bar" + exeSuffix)
+	tg.sleep()
+	tg.tempFile("src/x/y/foo/foo.go", `package foo
+		func F() { F() }`)
 	tg.tempFile("src/x/y/bar/bar.go", `package main
 		import "x/y/foo"
 		func main() { foo.F() }`)
@@ -2626,7 +3042,35 @@
 	tg.run("test", "testdata/standalone_test.go")
 }
 
+// Issue 22388
+func TestGoTestMainWithWrongSignature(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("test", "testdata/standalone_main_wrong_test.go")
+	tg.grepStderr(`wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)`, "detected wrong error message")
+}
+
+func TestGoTestMainAsNormalTest(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "testdata/standalone_main_normal_test.go")
+	tg.grepBoth(okPattern, "go test did not say ok")
+}
+
+func TestGoTestMainTwice(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", tg.tempdir)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("test", "-v", "multimain")
+	if strings.Count(tg.getStdout(), "notwithstanding") != 2 {
+		t.Fatal("tests did not run twice")
+	}
+}
+
 func TestGoTestFlagsAfterPackage(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags.
@@ -2748,41 +3192,47 @@
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.makeTempdir()
-	tg.run("install", "cmd/vet")
 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
 	tg.runFail("vet", "vetpkg")
-	tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf")
+	tg.grepBoth("Printf", "go vet vetpkg did not find missing argument for Printf")
 }
 
 func TestGoVetWithTags(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.makeTempdir()
-	tg.run("install", "cmd/vet")
 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
 	tg.runFail("vet", "-tags", "tagtest", "vetpkg")
-	tg.grepBoth(`c\.go.*wrong number of args for format`, "go vet vetpkg did not run scan tagged file")
+	tg.grepBoth(`c\.go.*Printf`, "go vet vetpkg did not run scan tagged file")
 }
 
 func TestGoVetWithFlagsOn(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.makeTempdir()
-	tg.run("install", "cmd/vet")
 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
 	tg.runFail("vet", "-printf", "vetpkg")
-	tg.grepBoth("missing argument for Printf", "go vet -printf vetpkg did not find missing argument for Printf")
+	tg.grepBoth("Printf", "go vet -printf vetpkg did not find missing argument for Printf")
 }
 
 func TestGoVetWithFlagsOff(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.makeTempdir()
-	tg.run("install", "cmd/vet")
 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
 	tg.run("vet", "-printf=false", "vetpkg")
 }
 
+// Issue 23395.
+func TestGoVetWithOnlyTestFiles(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/p/p_test.go", "package p; import \"testing\"; func TestMe(*testing.T) {}")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("vet", "p")
+}
+
 // Issue 9767, 19769.
 func TestGoGetDotSlashDownload(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
@@ -2814,6 +3264,8 @@
 // Test that you cannot import a main package.
 // See golang.org/issue/4210 and golang.org/issue/17475.
 func TestImportMain(t *testing.T) {
+	tooSlow(t)
+
 	tg := testgo(t)
 	tg.parallel()
 	defer tg.cleanup()
@@ -2829,7 +3281,7 @@
 		func TestFoo(t *testing.T) {}
 	`)
 	tg.setenv("GOPATH", tg.path("."))
-	tg.creatingTemp("x")
+	tg.creatingTemp("x" + exeSuffix)
 	tg.run("build", "x")
 	tg.run("test", "x")
 
@@ -2902,6 +3354,8 @@
 // accessed by a non-local import (found in a GOPATH/GOROOT).
 // See golang.org/issue/17475.
 func TestImportLocal(t *testing.T) {
+	tooSlow(t)
+
 	tg := testgo(t)
 	tg.parallel()
 	defer tg.cleanup()
@@ -3119,16 +3573,19 @@
 }
 
 func TestGoInstallPkgdir(t *testing.T) {
+	tooSlow(t)
+
 	tg := testgo(t)
 	tg.parallel()
 	defer tg.cleanup()
 	tg.makeTempdir()
 	pkg := tg.path(".")
-	tg.run("install", "-pkgdir", pkg, "errors")
-	_, err := os.Stat(filepath.Join(pkg, "errors.a"))
-	tg.must(err)
-	_, err = os.Stat(filepath.Join(pkg, "runtime.a"))
-	tg.must(err)
+	tg.run("install", "-pkgdir", pkg, "sync")
+	tg.mustExist(filepath.Join(pkg, "sync.a"))
+	tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
+	tg.run("install", "-i", "-pkgdir", pkg, "sync")
+	tg.mustExist(filepath.Join(pkg, "sync.a"))
+	tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
 }
 
 func TestGoTestRaceInstallCgo(t *testing.T) {
@@ -3153,6 +3610,8 @@
 }
 
 func TestGoTestRaceFailures(t *testing.T) {
+	tooSlow(t)
+
 	if !canRace {
 		t.Skip("skipping because race detector not supported")
 	}
@@ -3361,6 +3820,7 @@
 }
 
 func TestGoBuildOutput(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 
@@ -3439,17 +3899,9 @@
 	tg.grepStderrNot("unable to find math.a", "did not build math.a correctly")
 }
 
-func TestIssue13655(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	for _, pkg := range []string{"runtime", "runtime/internal/atomic"} {
-		tg.run("list", "-f", "{{.Deps}}", pkg)
-		tg.grepStdout("runtime/internal/sys", "did not find required dependency of "+pkg+" on runtime/internal/sys")
-	}
-}
-
 // For issue 14337.
 func TestParallelTest(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	tg.parallel()
 	defer tg.cleanup()
@@ -3469,6 +3921,7 @@
 }
 
 func TestCgoConsistentResults(t *testing.T) {
+	tooSlow(t)
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
 	}
@@ -3535,6 +3988,8 @@
 }
 
 func TestBinaryOnlyPackages(t *testing.T) {
+	tooSlow(t)
+
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
@@ -3545,9 +4000,9 @@
 
 		package p1
 	`)
-	tg.wantStale("p1", "cannot access install target", "p1 is binary-only but has no binary, should be stale")
+	tg.wantStale("p1", "missing or invalid binary-only package", "p1 is binary-only but has no binary, should be stale")
 	tg.runFail("install", "p1")
-	tg.grepStderr("missing or invalid package binary", "did not report attempt to compile binary-only package")
+	tg.grepStderr("missing or invalid binary-only package", "did not report attempt to compile binary-only package")
 
 	tg.tempFile("src/p1/p1.go", `
 		package p1
@@ -3570,11 +4025,12 @@
 	tg.tempFile("src/p1/missing.go", `//go:binary-only-package
 
 		package p1
+		import _ "fmt"
 		func G()
 	`)
-	tg.wantNotStale("p1", "no source code", "should NOT want to rebuild p1 (first)")
+	tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
 	tg.run("install", "-x", "p1") // no-op, up to date
-	tg.grepBothNot("/compile", "should not have run compiler")
+	tg.grepBothNot(`[\\/]compile`, "should not have run compiler")
 	tg.run("install", "p2") // does not rebuild p1 (or else p2 will fail)
 	tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
 
@@ -3584,7 +4040,7 @@
 		package p1
 		func H()
 	`)
-	tg.wantNotStale("p1", "no source code", "should NOT want to rebuild p1 (second)")
+	tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (second)")
 	tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
 
 	tg.tempFile("src/p3/p3.go", `
@@ -3604,9 +4060,11 @@
 	tg.grepStdout("hello from p1", "did not see message from p1")
 
 	tg.tempFile("src/p4/p4.go", `package main`)
+	// The odd string split below avoids vet complaining about
+	// a // +build line appearing too late in this source file.
 	tg.tempFile("src/p4/p4not.go", `//go:binary-only-package
 
-		// +build asdf
+		/`+`/ +build asdf
 
 		package main
 	`)
@@ -3692,6 +4150,7 @@
 	tg := testgo(t)
 	tg.parallel()
 	defer tg.cleanup()
+	tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
 	tg.setenv("GOARCH", "arm")
 	tg.run("env", "GOARCH")
 	tg.grepStdout("^arm$", "GOARCH not honored")
@@ -3841,11 +4300,31 @@
 
 // Issue 18845
 func TestBenchTimeout(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
 }
 
+// Issue 19394
+func TestWriteProfilesOnTimeout(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("profiling")
+	tg.tempFile("profiling/timeouttest_test.go", `package timeouttest_test
+import "testing"
+import "time"
+func TestSleep(t *testing.T) { time.Sleep(time.Second) }`)
+	tg.cd(tg.path("profiling"))
+	tg.runFail(
+		"test",
+		"-cpuprofile", tg.path("profiling/cpu.pprof"), "-memprofile", tg.path("profiling/mem.pprof"),
+		"-timeout", "1ms")
+	tg.mustHaveContent(tg.path("profiling/cpu.pprof"))
+	tg.mustHaveContent(tg.path("profiling/mem.pprof"))
+}
+
 func TestLinkXImportPathEscape(t *testing.T) {
 	// golang.org/issue/16710
 	tg := testgo(t)
@@ -3942,6 +4421,7 @@
 // Issue 19198.
 // This is really a cmd/link issue but this is a convenient place to test it.
 func TestDuplicateGlobalAsmSymbols(t *testing.T) {
+	tooSlow(t)
 	if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
 		t.Skipf("skipping test on %s", runtime.GOARCH)
 	}
@@ -3978,7 +4458,7 @@
 }
 `)
 	tg.setenv("GOPATH", tg.path("go"))
-	exe := filepath.Join(tg.tempdir, "p.exe")
+	exe := tg.path("p.exe")
 	tg.creatingTemp(exe)
 	tg.run("build", "-o", exe, "p")
 }
@@ -3988,9 +4468,7 @@
 	defer tg.cleanup()
 	tg.makeTempdir()
 	tg.setenv("GOPATH", tg.path("go"))
-	tg.run("install", "-tags", "tag1 tag2", "math")
-	tg.runFail("install", "-tags", "tag1,tag2", "math")
-	tg.grepBoth("space-separated list contains comma", "-tags with a comma-separated list didn't error")
+	tg.run("build", "-tags", "tag1 tag2", "math")
 	tg.runFail("build", "-tags", "tag1,tag2", "math")
 	tg.grepBoth("space-separated list contains comma", "-tags with a comma-separated list didn't error")
 }
@@ -4061,19 +4539,9 @@
 	newRoot := tg.path("new")
 
 	t.Run("RelocatedExe", func(t *testing.T) {
-		t.Skip("TODO: skipping known broken test; see golang.org/issue/20284")
-
-		// Should fall back to default location in binary.
-		// No way to dig out other than look at source code.
-		data, err := ioutil.ReadFile("../../runtime/internal/sys/zversion.go")
-		if err != nil {
-			t.Fatal(err)
-		}
-		m := regexp.MustCompile("const DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
-		if m == nil {
-			t.Fatal("cannot find DefaultGoroot in ../../runtime/internal/sys/zversion.go")
-		}
-		check(t, newGoTool, m[1])
+		// Should fall back to default location in binary,
+		// which is the GOROOT we used when building testgo.exe.
+		check(t, newGoTool, testGOROOT)
 	})
 
 	// If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
@@ -4094,6 +4562,41 @@
 		}
 		check(t, symGoTool, newRoot)
 	})
+
+	tg.must(os.RemoveAll(tg.path("new/pkg")))
+
+	// Binaries built in the new tree should report the
+	// new tree when they call runtime.GOROOT.
+	t.Run("RuntimeGoroot", func(t *testing.T) {
+		// Build a working GOROOT the easy way, with symlinks.
+		testenv.MustHaveSymlink(t)
+		if err := os.Symlink(filepath.Join(testGOROOT, "src"), tg.path("new/src")); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Symlink(filepath.Join(testGOROOT, "pkg"), tg.path("new/pkg")); err != nil {
+			t.Fatal(err)
+		}
+
+		cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go")
+		cmd.Env = env
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out)
+		}
+		goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
+		if err != nil {
+			t.Fatal(err)
+		}
+		want, err := filepath.EvalSymlinks(tg.path("new"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !strings.EqualFold(goroot, want) {
+			t.Errorf("go run testdata/print_goroot.go:\nhave %s\nwant %s", goroot, want)
+		} else {
+			t.Logf("go run testdata/print_goroot.go: %s", goroot)
+		}
+	})
 }
 
 func TestNeedVersion(t *testing.T) {
@@ -4120,7 +4623,8 @@
 
 	tg := testgo(t)
 	defer tg.cleanup()
-	tg.parallel()
+	// Don't call tg.parallel, as creating override.h and override.a may
+	// confuse other tests.
 	tg.tempFile("override.go", `package main
 
 import "C"
@@ -4131,77 +4635,36 @@
 func main() {}`)
 	tg.creatingTemp("override.a")
 	tg.creatingTemp("override.h")
-	tg.run("build", "-x", "-buildmode=c-archive", "-gcflags=-shared=false", tg.path("override.go"))
+	tg.run("build", "-x", "-buildmode=c-archive", "-gcflags=all=-shared=false", tg.path("override.go"))
 	tg.grepStderr("compile .*-shared .*-shared=false", "user can not override code generation flag")
 }
 
 func TestCgoFlagContainsSpace(t *testing.T) {
+	tooSlow(t)
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
 	}
-
 	tg := testgo(t)
 	defer tg.cleanup()
 
-	ccName := filepath.Base(testCC)
-
-	tg.tempFile(fmt.Sprintf("src/%s/main.go", ccName), fmt.Sprintf(`package main
-		import (
-			"os"
-			"os/exec"
-			"strings"
-		)
-
-		func main() {
-			cmd := exec.Command(%q, os.Args[1:]...)
-			cmd.Stdin = os.Stdin
-			cmd.Stdout = os.Stdout
-			cmd.Stderr = os.Stderr
-			err := cmd.Run()
-			if err != nil {
-				panic(err)
-			}
-
-			if os.Args[len(os.Args)-1] == "trivial.c" {
-				return
-			}
-
-			var success bool
-			for _, arg := range os.Args {
-				switch {
-				case strings.Contains(arg, "c flags"):
-					if success {
-						panic("duplicate CFLAGS")
-					}
-					success = true
-				case strings.Contains(arg, "ld flags"):
-					if success {
-						panic("duplicate LDFLAGS")
-					}
-					success = true
-				}
-			}
-			if !success {
-				panic("args should contains '-Ic flags' or '-Lld flags'")
-			}
-		}
-	`, testCC))
-	tg.cd(tg.path(fmt.Sprintf("src/%s", ccName)))
-	tg.run("build")
-	tg.setenv("CC", tg.path(fmt.Sprintf("src/%s/%s", ccName, ccName)))
-
-	tg.tempFile("src/cgo/main.go", `package main
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+	tg.tempFile("main.go", `package main
 		// #cgo CFLAGS: -I"c flags"
 		// #cgo LDFLAGS: -L"ld flags"
 		import "C"
 		func main() {}
 	`)
-	tg.cd(tg.path("src/cgo"))
-	tg.run("run", "main.go")
+	tg.run("run", "-x", "main.go")
+	tg.grepStderr(`"-I[^"]+c flags"`, "did not find quoted c flags")
+	tg.grepStderrNot(`"-I[^"]+c flags".*"-I[^"]+c flags"`, "found too many quoted c flags")
+	tg.grepStderr(`"-L[^"]+ld flags"`, "did not find quoted ld flags")
+	tg.grepStderrNot(`"-L[^"]+c flags".*"-L[^"]+c flags"`, "found too many quoted ld flags")
 }
 
 // Issue #20435.
 func TestGoTestRaceCoverModeFailures(t *testing.T) {
+	tooSlow(t)
 	if !canRace {
 		t.Skip("skipping because race detector not supported")
 	}
@@ -4238,7 +4701,7 @@
 			before()
 			tg.run("install", "mycmd")
 			after()
-			tg.wantStale("mycmd", "build ID mismatch", "should be stale after environment variable change")
+			tg.wantStale("mycmd", "stale dependency: runtime/internal/sys", "should be stale after environment variable change")
 		}
 	}
 
@@ -4316,6 +4779,7 @@
 }
 
 func TestListTests(t *testing.T) {
+	tooSlow(t)
 	var tg *testgoData
 	testWith := func(listName, expected string) func(*testing.T) {
 		return func(t *testing.T) {
@@ -4331,3 +4795,1096 @@
 	t.Run("Example1", testWith("Example", "ExampleSimple"))
 	t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
 }
+
+func TestBuildmodePIE(t *testing.T) {
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skipf("skipping in -short mode on non-builder")
+	}
+	if runtime.Compiler == "gccgo" {
+		t.Skipf("skipping test because buildmode=pie is not supported on gccgo")
+	}
+
+	platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
+	switch platform {
+	case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
+		"android/amd64", "android/arm", "android/arm64", "android/386":
+	case "darwin/amd64":
+	default:
+		t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.tempFile("main.go", `package main; func main() { print("hello") }`)
+	src := tg.path("main.go")
+	obj := tg.path("main")
+	tg.run("build", "-buildmode=pie", "-o", obj, src)
+
+	switch runtime.GOOS {
+	case "linux", "android":
+		f, err := elf.Open(obj)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer f.Close()
+		if f.Type != elf.ET_DYN {
+			t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
+		}
+	case "darwin":
+		f, err := macho.Open(obj)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer f.Close()
+		if f.Flags&macho.FlagDyldLink == 0 {
+			t.Error("PIE must have DyldLink flag, but not")
+		}
+		if f.Flags&macho.FlagPIE == 0 {
+			t.Error("PIE must have PIE flag, but not")
+		}
+	default:
+		panic("unreachable")
+	}
+
+	out, err := exec.Command(obj).CombinedOutput()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if string(out) != "hello" {
+		t.Errorf("got %q; want %q", out, "hello")
+	}
+}
+
+func TestExecBuildX(t *testing.T) {
+	tooSlow(t)
+	if !canCgo {
+		t.Skip("skipping because cgo not enabled")
+	}
+
+	if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
+		t.Skipf("skipping because unix shell is not supported on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.setenv("GOCACHE", "off")
+
+	tg.tempFile("main.go", `package main; import "C"; func main() { print("hello") }`)
+	src := tg.path("main.go")
+	obj := tg.path("main")
+	tg.run("build", "-x", "-o", obj, src)
+	sh := tg.path("test.sh")
+	err := ioutil.WriteFile(sh, []byte("set -e\n"+tg.getStderr()), 0666)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	out, err := exec.Command(obj).CombinedOutput()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(out) != "hello" {
+		t.Fatalf("got %q; want %q", out, "hello")
+	}
+
+	err = os.Remove(obj)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	out, err = exec.Command("/usr/bin/env", "bash", "-x", sh).CombinedOutput()
+	if err != nil {
+		t.Fatalf("/bin/sh %s: %v\n%s", sh, err, out)
+	}
+	t.Logf("shell output:\n%s", out)
+
+	out, err = exec.Command(obj).CombinedOutput()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(out) != "hello" {
+		t.Fatalf("got %q; want %q", out, "hello")
+	}
+}
+
+func TestParallelNumber(t *testing.T) {
+	tooSlow(t)
+	for _, n := range [...]string{"-1", "0"} {
+		t.Run(n, func(t *testing.T) {
+			tg := testgo(t)
+			defer tg.cleanup()
+			tg.runFail("test", "-parallel", n, "testdata/standalone_parallel_sub_test.go")
+			tg.grepBoth("-parallel can only be given", "go test -parallel with N<1 did not error")
+		})
+	}
+}
+
+func TestWrongGOOSErrorBeforeLoadError(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GOOS", "windwos")
+	tg.runFail("build", "exclude")
+	tg.grepStderr("unsupported GOOS/GOARCH pair", "GOOS=windwos go build exclude did not report 'unsupported GOOS/GOARCH pair'")
+}
+
+func TestUpxCompression(t *testing.T) {
+	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+		t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+
+	out, err := exec.Command("upx", "--version").CombinedOutput()
+	if err != nil {
+		t.Skip("skipping because upx is not available")
+	}
+
+	// upx --version prints `upx <version>` in the first line of output:
+	//   upx 3.94
+	//   [...]
+	re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
+	upxVersion := re.FindStringSubmatch(string(out))
+	if len(upxVersion) != 3 {
+		t.Errorf("bad upx version string: %s", upxVersion)
+	}
+
+	major, err1 := strconv.Atoi(upxVersion[1])
+	minor, err2 := strconv.Atoi(upxVersion[2])
+	if err1 != nil || err2 != nil {
+		t.Errorf("bad upx version string: %s", upxVersion[0])
+	}
+
+	// Anything below 3.94 is known not to work with go binaries
+	if (major < 3) || (major == 3 && minor < 94) {
+		t.Skipf("skipping because upx version %v.%v is too old", major, minor)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
+	src := tg.path("main.go")
+	obj := tg.path("main")
+	tg.run("build", "-o", obj, src)
+
+	out, err = exec.Command("upx", obj).CombinedOutput()
+	if err != nil {
+		t.Logf("executing upx\n%s\n", out)
+		t.Fatalf("upx failed with %v", err)
+	}
+
+	out, err = exec.Command(obj).CombinedOutput()
+	if err != nil {
+		t.Logf("%s", out)
+		t.Fatalf("running compressed go binary failed with error %s", err)
+	}
+	if string(out) != "hello upx" {
+		t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
+	}
+}
+
+func TestGOTMPDIR(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.makeTempdir()
+	tg.setenv("GOTMPDIR", tg.tempdir)
+	tg.setenv("GOCACHE", "off")
+
+	// complex/x is a trivial non-main package.
+	tg.run("build", "-work", "-x", "complex/w")
+	tg.grepStderr("WORK="+regexp.QuoteMeta(tg.tempdir), "did not work in $GOTMPDIR")
+}
+
+func TestBuildCache(t *testing.T) {
+	tooSlow(t)
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", tg.tempdir)
+
+	// complex/w is a trivial non-main package.
+	// It imports nothing, so there should be no Deps.
+	tg.run("list", "-f={{join .Deps \" \"}}", "complex/w")
+	tg.grepStdoutNot(".+", "complex/w depends on unexpected packages")
+
+	tg.run("build", "-x", "complex/w")
+	tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler")
+
+	tg.run("build", "-x", "complex/w")
+	tg.grepStderrNot(`[\\/]compile|gccgo`, "ran compiler incorrectly")
+
+	tg.run("build", "-a", "-x", "complex/w")
+	tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler with -a")
+
+	// complex is a non-trivial main package.
+	// the link step should not be cached.
+	tg.run("build", "-o", os.DevNull, "-x", "complex")
+	tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
+
+	tg.run("build", "-o", os.DevNull, "-x", "complex")
+	tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
+}
+
+func TestCacheOutput(t *testing.T) {
+	// Test that command output is cached and replayed too.
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", tg.tempdir)
+
+	tg.run("build", "-gcflags=-m", "errors")
+	stdout1 := tg.getStdout()
+	stderr1 := tg.getStderr()
+
+	tg.run("build", "-gcflags=-m", "errors")
+	stdout2 := tg.getStdout()
+	stderr2 := tg.getStderr()
+
+	if stdout2 != stdout1 || stderr2 != stderr1 {
+		t.Errorf("cache did not reproduce output:\n\nstdout1:\n%s\n\nstdout2:\n%s\n\nstderr1:\n%s\n\nstderr2:\n%s",
+			stdout1, stdout2, stderr1, stderr2)
+	}
+}
+
+func TestCacheCoverage(t *testing.T) {
+	tooSlow(t)
+
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.makeTempdir()
+
+	tg.setenv("GOCACHE", tg.path("c1"))
+	tg.run("test", "-cover", "-short", "strings")
+	tg.run("test", "-cover", "-short", "math", "strings")
+}
+
+func TestIssue22588(t *testing.T) {
+	// Don't get confused by stderr coming from tools.
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+
+	if _, err := os.Stat("/usr/bin/time"); err != nil {
+		t.Skip(err)
+	}
+
+	tg.run("list", "-f={{.Stale}}", "runtime")
+	tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
+	tg.grepStdout("false", "incorrectly reported runtime as stale")
+}
+
+func TestIssue22531(t *testing.T) {
+	tooSlow(t)
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.tempdir)
+	tg.setenv("GOCACHE", tg.path("cache"))
+	tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
+	tg.run("install", "-x", "m")
+	tg.run("list", "-f", "{{.Stale}}", "m")
+	tg.grepStdout("false", "reported m as stale after install")
+	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
+
+	// The link action ID did not include the full main build ID,
+	// even though the full main build ID is written into the
+	// eventual binary. That caused the following install to
+	// be a no-op, thinking the gofmt binary was up-to-date,
+	// even though .Stale could see it was not.
+	tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
+	tg.run("install", "-x", "m")
+	tg.run("list", "-f", "{{.Stale}}", "m")
+	tg.grepStdout("false", "reported m as stale after reinstall")
+	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
+}
+
+func TestIssue22596(t *testing.T) {
+	tooSlow(t)
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", tg.path("cache"))
+	tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
+	tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
+
+	tg.setenv("GOPATH", tg.path("gopath1"))
+	tg.run("list", "-f={{.Target}}", "p")
+	target1 := strings.TrimSpace(tg.getStdout())
+	tg.run("install", "p")
+	tg.wantNotStale("p", "", "p stale after install")
+
+	tg.setenv("GOPATH", tg.path("gopath2"))
+	tg.run("list", "-f={{.Target}}", "p")
+	target2 := strings.TrimSpace(tg.getStdout())
+	tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
+	tg.must(copyFile(target1, target2, 0666))
+	tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
+	tg.run("install", "p")
+	tg.wantNotStale("p", "", "p stale after install2")
+}
+
+func TestTestCache(t *testing.T) {
+	tooSlow(t)
+
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.tempdir)
+	tg.setenv("GOCACHE", tg.path("cache"))
+
+	// timeout here should not affect result being cached
+	// or being retrieved later.
+	tg.run("test", "-x", "-timeout=10s", "errors")
+	tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler")
+	tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
+	tg.grepStderr(`errors\.test`, "did not run test")
+
+	tg.run("test", "-x", "errors")
+	tg.grepStdout(`ok  \terrors\t\(cached\)`, "did not report cached result")
+	tg.grepStderrNot(`[\\/]compile|gccgo`, "incorrectly ran compiler")
+	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly ran linker")
+	tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
+	tg.grepStderrNot("DO NOT USE", "poisoned action status leaked")
+
+	// Even very low timeouts do not disqualify cached entries.
+	tg.run("test", "-timeout=1ns", "-x", "errors")
+	tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
+
+	tg.run("clean", "-testcache")
+	tg.run("test", "-x", "errors")
+	tg.grepStderr(`errors\.test`, "did not run test")
+
+	// The -p=1 in the commands below just makes the -x output easier to read.
+
+	t.Log("\n\nINITIAL\n\n")
+
+	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
+	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
+	tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
+	tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
+	tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
+	tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
+	tg.run("test", "-x", "-v", "-short", "t/...")
+
+	t.Log("\n\nREPEAT\n\n")
+
+	tg.run("test", "-x", "-v", "-short", "t/...")
+	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
+	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
+	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
+	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
+	tg.grepStderrNot(`[\\/]compile|gccgo`, "incorrectly ran compiler")
+	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly ran linker")
+	tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
+
+	t.Log("\n\nCOMMENT\n\n")
+
+	// Changing the program text without affecting the compiled package
+	// should result in the package being rebuilt but nothing more.
+	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
+	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
+	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
+	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
+	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
+	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
+	tg.grepStderrNot(`([\\/]compile|gccgo).*t[0-9]_test\.go`, "incorrectly ran compiler")
+	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly ran linker")
+	tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
+
+	t.Log("\n\nCHANGE\n\n")
+
+	// Changing the actual package should have limited effects.
+	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
+	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
+
+	// p2 should have been rebuilt.
+	tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
+
+	// t1 does not import anything, should not have been rebuilt.
+	tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
+	tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
+	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t/t1")
+
+	// t2 imports p1 and must be rebuilt and relinked,
+	// but the change should not have any effect on the test binary,
+	// so the test should not have been rerun.
+	tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
+	tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
+	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t/t2")
+
+	// t3 imports p1, and changing X changes t3's test binary.
+	tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
+	tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
+	tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
+	tg.grepStdoutNot(`ok  \tt/t3\t\(cached\)`, "reported cached t3_test result")
+
+	// t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
+	// and not rerun.
+	tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
+	tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
+	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t/t4")
+}
+
+func TestTestCacheInputs(t *testing.T) {
+	tooSlow(t)
+
+	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+		t.Skip("GODEBUG gocacheverify")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GOCACHE", tg.path("cache"))
+
+	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
+	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"))
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("x"), 0644))
+	old := time.Now().Add(-1 * time.Minute)
+	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
+	info, err := os.Stat(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("file.txt: old=%v, info.ModTime=%v", old, info.ModTime()) // help debug when Chtimes lies about succeeding
+	tg.setenv("TESTKEY", "x")
+
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), []byte("#!/bin/sh\nexit 0\n"), 0755))
+	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old, old))
+
+	tg.run("test", "testcache")
+	tg.run("test", "testcache")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.setenv("TESTKEY", "y")
+	tg.run("test", "testcache")
+	tg.grepStdoutNot(`\(cached\)`, "did not notice env var change")
+	tg.run("test", "testcache")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.run("test", "testcache", "-run=FileSize")
+	tg.run("test", "testcache", "-run=FileSize")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxx"), 0644))
+	tg.run("test", "testcache", "-run=FileSize")
+	tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
+	tg.run("test", "testcache", "-run=FileSize")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.run("test", "testcache", "-run=Chdir")
+	tg.run("test", "testcache", "-run=Chdir")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxxxx"), 0644))
+	tg.run("test", "testcache", "-run=Chdir")
+	tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
+	tg.run("test", "testcache", "-run=Chdir")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
+	tg.run("test", "testcache", "-run=FileContent")
+	tg.run("test", "testcache", "-run=FileContent")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("yyy"), 0644))
+	old2 := old.Add(10 * time.Second)
+	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old2, old2))
+	tg.run("test", "testcache", "-run=FileContent")
+	tg.grepStdoutNot(`\(cached\)`, "did not notice file content change")
+	tg.run("test", "testcache", "-run=FileContent")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.run("test", "testcache", "-run=DirList")
+	tg.run("test", "testcache", "-run=DirList")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+	tg.must(os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt")))
+	tg.run("test", "testcache", "-run=DirList")
+	tg.grepStdoutNot(`\(cached\)`, "did not notice directory change")
+	tg.run("test", "testcache", "-run=DirList")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	tg.tempFile("file.txt", "")
+	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"), []byte(`package testcache
+
+		import (
+			"os"
+			"testing"
+		)
+
+		func TestExternalFile(t *testing.T) {
+			os.Open(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
+			_, err := os.Stat(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
+			if err != nil {
+				t.Fatal(err)
+			}
+		}
+	`), 0666))
+	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"))
+	tg.run("test", "testcache", "-run=ExternalFile")
+	tg.run("test", "testcache", "-run=ExternalFile")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+	tg.must(os.Remove(filepath.Join(tg.tempdir, "file.txt")))
+	tg.run("test", "testcache", "-run=ExternalFile")
+	tg.grepStdout(`\(cached\)`, "did not cache")
+
+	switch runtime.GOOS {
+	case "nacl", "plan9", "windows":
+		// no shell scripts
+	default:
+		tg.run("test", "testcache", "-run=Exec")
+		tg.run("test", "testcache", "-run=Exec")
+		tg.grepStdout(`\(cached\)`, "did not cache")
+		tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old2, old2))
+		tg.run("test", "testcache", "-run=Exec")
+		tg.grepStdoutNot(`\(cached\)`, "did not notice script change")
+		tg.run("test", "testcache", "-run=Exec")
+		tg.grepStdout(`\(cached\)`, "did not cache")
+	}
+}
+
+func TestNoCache(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows":
+		t.Skipf("no unwritable directories on %s", runtime.GOOS)
+	}
+	if os.Getuid() == 0 {
+		t.Skip("skipping test because running as root")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("triv.go", `package main; func main() {}`)
+	tg.must(os.MkdirAll(tg.path("unwritable"), 0555))
+	home := "HOME"
+	if runtime.GOOS == "plan9" {
+		home = "home"
+	}
+	tg.setenv(home, tg.path(filepath.Join("unwritable", "home")))
+	tg.unsetenv("GOCACHE")
+	tg.run("build", "-o", tg.path("triv"), tg.path("triv.go"))
+	tg.grepStderr("disabling cache", "did not disable cache")
+}
+
+func TestTestVet(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+
+	tg.tempFile("p1_test.go", `
+		package p
+		import "testing"
+		func Test(t *testing.T) {
+			t.Logf("%d") // oops
+		}
+	`)
+
+	tg.runFail("test", tg.path("p1_test.go"))
+	tg.grepStderr(`Logf format %d`, "did not diagnose bad Logf")
+	tg.run("test", "-vet=off", tg.path("p1_test.go"))
+	tg.grepStdout(`^ok`, "did not print test summary")
+
+	tg.tempFile("p1.go", `
+		package p
+		import "fmt"
+		func F() {
+			fmt.Printf("%d") // oops
+		}
+	`)
+	tg.runFail("test", tg.path("p1.go"))
+	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
+	tg.run("test", "-x", "-vet=shift", tg.path("p1.go"))
+	tg.grepStderr(`[\\/]vet.*-shift`, "did not run vet with -shift")
+	tg.grepStdout(`\[no test files\]`, "did not print test summary")
+	tg.run("test", "-vet=off", tg.path("p1.go"))
+	tg.grepStdout(`\[no test files\]`, "did not print test summary")
+
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("test", "vetcycle") // must not fail; #22890
+
+	tg.runFail("test", "vetfail/...")
+	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
+	tg.grepStdout(`ok\s+vetfail/p2`, "did not run vetfail/p2")
+}
+
+func TestTestRebuild(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+
+	// golang.org/issue/23701.
+	// b_test imports b with augmented method from export_test.go.
+	// b_test also imports a, which imports b.
+	// Must not accidentally see un-augmented b propagate through a to b_test.
+	tg.tempFile("src/a/a.go", `package a
+		import "b"
+		type Type struct{}
+		func (*Type) M() b.T {return 0}
+	`)
+	tg.tempFile("src/b/b.go", `package b
+		type T int
+		type I interface {M() T}
+	`)
+	tg.tempFile("src/b/export_test.go", `package b
+		func (*T) Method() *T { return nil }
+	`)
+	tg.tempFile("src/b/b_test.go", `package b_test
+		import (
+			"testing"
+			"a"
+			. "b"
+		)
+		func TestBroken(t *testing.T) {
+			x := new(T)
+			x.Method()
+			_ = new(a.Type)
+		}
+	`)
+
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("test", "b")
+}
+
+func TestInstallDeps(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.tempdir)
+
+	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
+	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
+	tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
+
+	tg.run("list", "-f={{.Target}}", "p1")
+	p1 := strings.TrimSpace(tg.getStdout())
+	tg.run("list", "-f={{.Target}}", "p2")
+	p2 := strings.TrimSpace(tg.getStdout())
+	tg.run("list", "-f={{.Target}}", "main1")
+	main1 := strings.TrimSpace(tg.getStdout())
+
+	tg.run("install", "main1")
+
+	tg.mustExist(main1)
+	tg.mustNotExist(p2)
+	tg.mustNotExist(p1)
+
+	tg.run("install", "p2")
+	tg.mustExist(p2)
+	tg.mustNotExist(p1)
+
+	// don't let install -i overwrite runtime
+	tg.wantNotStale("runtime", "", "must be non-stale before install -i")
+
+	tg.run("install", "-i", "main1")
+	tg.mustExist(p1)
+	tg.must(os.Remove(p1))
+
+	tg.run("install", "-i", "p2")
+	tg.mustExist(p1)
+}
+
+func TestFmtLoadErrors(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("fmt", "does-not-exist")
+	tg.run("fmt", "-n", "exclude")
+}
+
+func TestRelativePkgdir(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", "off")
+	tg.cd(tg.tempdir)
+
+	tg.run("build", "-i", "-pkgdir=.", "runtime")
+}
+
+func TestGcflagsPatterns(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", "")
+	tg.setenv("GOCACHE", "off")
+
+	tg.run("build", "-n", "-v", "-gcflags= \t\r\n -e", "fmt")
+	tg.grepStderr("^# fmt", "did not rebuild fmt")
+	tg.grepStderrNot("^# reflect", "incorrectly rebuilt reflect")
+
+	tg.run("build", "-n", "-v", "-gcflags=-e", "fmt", "reflect")
+	tg.grepStderr("^# fmt", "did not rebuild fmt")
+	tg.grepStderr("^# reflect", "did not rebuild reflect")
+	tg.grepStderrNot("^# runtime", "incorrectly rebuilt runtime")
+
+	tg.run("build", "-n", "-x", "-v", "-gcflags= \t\r\n reflect \t\r\n = \t\r\n -N", "fmt")
+	tg.grepStderr("^# fmt", "did not rebuild fmt")
+	tg.grepStderr("^# reflect", "did not rebuild reflect")
+	tg.grepStderr("compile.* -N .*-p reflect", "did not build reflect with -N flag")
+	tg.grepStderrNot("compile.* -N .*-p fmt", "incorrectly built fmt with -N flag")
+
+	tg.run("test", "-c", "-n", "-gcflags=-N", "-ldflags=-X=x.y=z", "strings")
+	tg.grepStderr("compile.* -N .*compare_test.go", "did not compile strings_test package with -N flag")
+	tg.grepStderr("link.* -X=x.y=z", "did not link strings.test binary with -X flag")
+
+	tg.run("test", "-c", "-n", "-gcflags=strings=-N", "-ldflags=strings=-X=x.y=z", "strings")
+	tg.grepStderr("compile.* -N .*compare_test.go", "did not compile strings_test package with -N flag")
+	tg.grepStderr("link.* -X=x.y=z", "did not link strings.test binary with -X flag")
+}
+
+func TestGoTestMinusN(t *testing.T) {
+	// Intent here is to verify that 'go test -n' works without crashing.
+	// This reuses flag_test.go, but really any test would do.
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "testdata/flag_test.go", "-n", "-args", "-v=7")
+}
+
+func TestGoTestJSON(t *testing.T) {
+	tooSlow(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOCACHE", tg.tempdir)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+	// It would be nice to test that the output is interlaced
+	// but it seems to be impossible to do that in a short test
+	// that isn't also flaky. Just check that we get JSON output.
+	tg.run("test", "-json", "-short", "-v", "errors", "empty/pkg", "skipper")
+	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
+	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
+
+	tg.grepStdout(`"Action":"output","Package":"empty/pkg","Output":".*no test files`, "did not see no test files print")
+	tg.grepStdout(`"Action":"skip","Package":"empty/pkg"`, "did not see skip")
+
+	tg.grepStdout(`"Action":"output","Package":"skipper","Test":"Test","Output":"--- SKIP:`, "did not see SKIP output")
+	tg.grepStdout(`"Action":"skip","Package":"skipper","Test":"Test"`, "did not see skip result for Test")
+
+	tg.run("test", "-json", "-short", "-v", "errors")
+	tg.grepStdout(`"Action":"output","Package":"errors","Output":".*\(cached\)`, "did not see no cached output")
+
+	tg.run("test", "-json", "-bench=NONE", "-short", "-v", "errors")
+	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
+	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
+
+	tg.run("test", "-o", tg.path("errors.test.exe"), "-c", "errors")
+	tg.run("tool", "test2json", "-p", "errors", tg.path("errors.test.exe"), "-test.v", "-test.short")
+	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
+	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
+	tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass")
+}
+
+func TestFailFast(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tests := []struct {
+		run      string
+		failfast bool
+		nfail    int
+	}{
+		{"TestFailingA", true, 1},
+		{"TestFailing[AB]", true, 1},
+		{"TestFailing[AB]", false, 2},
+		// mix with non-failing tests:
+		{"TestA|TestFailing[AB]", true, 1},
+		{"TestA|TestFailing[AB]", false, 2},
+		// mix with parallel tests:
+		{"TestFailingB|TestParallelFailingA", true, 2},
+		{"TestFailingB|TestParallelFailingA", false, 2},
+		{"TestFailingB|TestParallelFailing[AB]", true, 3},
+		{"TestFailingB|TestParallelFailing[AB]", false, 3},
+		// mix with parallel sub-tests
+		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", true, 3},
+		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", false, 5},
+		{"TestParallelFailingSubtestsA", true, 1},
+		// only parallels:
+		{"TestParallelFailing[AB]", false, 2},
+		// non-parallel subtests:
+		{"TestFailingSubtestsA", true, 1},
+		{"TestFailingSubtestsA", false, 2},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.run, func(t *testing.T) {
+			tg.runFail("test", "./testdata/src/failfast_test.go", "-run="+tt.run, "-failfast="+strconv.FormatBool(tt.failfast))
+
+			nfail := strings.Count(tg.getStdout(), "FAIL - ")
+
+			if nfail != tt.nfail {
+				t.Errorf("go test -run=%s -failfast=%t printed %d FAILs, want %d", tt.run, tt.failfast, nfail, tt.nfail)
+			}
+		})
+	}
+}
+
+// Issue 22986.
+func TestImportPath(t *testing.T) {
+	tooSlow(t)
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+
+	tg.tempFile("src/a/a.go", `
+package main
+
+import (
+	"log"
+	p "a/p-1.0"
+)
+
+func main() {
+	if !p.V {
+		log.Fatal("false")
+	}
+}`)
+
+	tg.tempFile("src/a/a_test.go", `
+package main_test
+
+import (
+	p "a/p-1.0"
+	"testing"
+)
+
+func TestV(t *testing.T) {
+	if !p.V {
+		t.Fatal("false")
+	}
+}`)
+
+	tg.tempFile("src/a/p-1.0/p.go", `
+package p
+
+var V = true
+
+func init() {}
+`)
+
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("build", "-o", tg.path("a.exe"), "a")
+	tg.run("test", "a")
+}
+
+// Issue 23150.
+func TestCpuprofileTwice(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("prof/src/x/x_test.go", `
+		package x_test
+		import (
+			"testing"
+			"time"
+		)
+		func TestSleep(t *testing.T) { time.Sleep(10 * time.Millisecond) }`)
+	tg.setenv("GOPATH", tg.path("prof"))
+	bin := tg.path("x.test")
+	out := tg.path("cpu.out")
+	tg.run("test", "-o="+bin, "-cpuprofile="+out, "x")
+	tg.must(os.Remove(out))
+	tg.run("test", "-o="+bin, "-cpuprofile="+out, "x")
+	tg.mustExist(out)
+}
+
+// Issue 23694.
+func TestAtomicCoverpkgAll(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+
+	tg.tempFile("src/x/x.go", `package x; import _ "sync/atomic"; func F() {}`)
+	tg.tempFile("src/x/x_test.go", `package x; import "testing"; func TestF(t *testing.T) { F() }`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("test", "-coverpkg=all", "-covermode=atomic", "x")
+	if canRace {
+		tg.run("test", "-coverpkg=all", "-race", "x")
+	}
+}
+
+func TestBadCommandLines(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.tempFile("src/x/x.go", "package x\n")
+	tg.setenv("GOPATH", tg.path("."))
+
+	tg.run("build", "x")
+
+	tg.tempFile("src/x/@y.go", "package x\n")
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
+	tg.must(os.Remove(tg.path("src/x/@y.go")))
+
+	tg.tempFile("src/x/-y.go", "package x\n")
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
+	tg.must(os.Remove(tg.path("src/x/-y.go")))
+
+	tg.runFail("build", "-gcflags=all=@x", "x")
+	tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
+
+	tg.tempFile("src/@x/x.go", "package x\n")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "@x")
+	tg.grepStderr("invalid input directory name \"@x\"", "did not reject @x directory")
+
+	tg.tempFile("src/@x/y/y.go", "package y\n")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "@x/y")
+	tg.grepStderr("invalid import path \"@x/y\"", "did not reject @x/y import path")
+
+	tg.tempFile("src/-x/x.go", "package x\n")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "--", "-x")
+	tg.grepStderr("invalid input directory name \"-x\"", "did not reject -x directory")
+
+	tg.tempFile("src/-x/y/y.go", "package y\n")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "--", "-x/y")
+	tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
+}
+
+func TestBadCgoDirectives(t *testing.T) {
+	if !canCgo {
+		t.Skip("no cgo")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.tempFile("src/x/x.go", "package x\n")
+	tg.setenv("GOPATH", tg.path("."))
+
+	tg.tempFile("src/x/x.go", `package x
+
+		//go:cgo_ldflag "-fplugin=foo.so"
+
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("//go:cgo_ldflag .* only allowed in cgo-generated code", "did not reject //go:cgo_ldflag directive")
+
+	tg.must(os.Remove(tg.path("src/x/x.go")))
+	tg.runFail("build", "x")
+	tg.grepStderr("no Go files", "did not report missing source code")
+	tg.tempFile("src/x/_cgo_yy.go", `package x
+
+		//go:cgo_ldflag "-fplugin=foo.so"
+
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("no Go files", "did not report missing source code") // _* files are ignored...
+
+	tg.runFail("build", tg.path("src/x/_cgo_yy.go")) // ... but if forced, the comment is rejected
+	// Actually, today there is a separate issue that _ files named
+	// on the command-line are ignored. Once that is fixed,
+	// we want to see the cgo_ldflag error.
+	tg.grepStderr("//go:cgo_ldflag only allowed in cgo-generated code|no Go files", "did not reject //go:cgo_ldflag directive")
+	tg.must(os.Remove(tg.path("src/x/_cgo_yy.go")))
+
+	tg.tempFile("src/x/x.go", "package x\n")
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: -fplugin=foo.so
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: -Ibar -fplugin=foo.so
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo pkg-config: -foo
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid pkg-config package name: -foo", "did not reject pkg-config: -foo")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo pkg-config: @foo
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid pkg-config package name: @foo", "did not reject pkg-config: -foo")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: @foo
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: @foo", "did not reject @foo flag")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: -D
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: -D without argument", "did not reject trailing -I flag")
+
+	// Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo
+	// before the check is applied. There's no such rewrite for -D.
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: -D @foo
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: -D @foo", "did not reject -D @foo flag")
+
+	tg.tempFile("src/x/y.go", `package x
+		// #cgo CFLAGS: -D@foo
+		import "C"
+	`)
+	tg.runFail("build", "x")
+	tg.grepStderr("invalid flag in #cgo CFLAGS: -D@foo", "did not reject -D@foo flag")
+
+	tg.setenv("CGO_CFLAGS", "-D@foo")
+	tg.tempFile("src/x/y.go", `package x
+		import "C"
+	`)
+	tg.run("build", "-n", "x")
+	tg.grepStderr("-D@foo", "did not find -D@foo in commands")
+}
diff --git a/src/cmd/go/go_windows_test.go b/src/cmd/go/go_windows_test.go
index d8d04aa..aa68a19 100644
--- a/src/cmd/go/go_windows_test.go
+++ b/src/cmd/go/go_windows_test.go
@@ -5,12 +5,14 @@
 package main
 
 import (
+	"fmt"
 	"internal/testenv"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"strings"
+	"syscall"
 	"testing"
 )
 
@@ -54,3 +56,82 @@
 		t.Fatalf("wrong output found: %v %v", err, string(output))
 	}
 }
+
+func isWindowsXP(t *testing.T) bool {
+	v, err := syscall.GetVersion()
+	if err != nil {
+		t.Fatalf("GetVersion failed: %v", err)
+	}
+	major := byte(v)
+	return major < 6
+}
+
+func runIcacls(t *testing.T, args ...string) string {
+	t.Helper()
+	out, err := exec.Command("icacls", args...).CombinedOutput()
+	if err != nil {
+		t.Fatalf("icacls failed: %v\n%v", err, string(out))
+	}
+	return string(out)
+}
+
+func runGetACL(t *testing.T, path string) string {
+	t.Helper()
+	cmd := fmt.Sprintf(`Get-Acl "%s" | Select -expand AccessToString`, path)
+	out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("Get-Acl failed: %v\n%v", err, string(out))
+	}
+	return string(out)
+}
+
+// For issue 22343: verify that executable file created by "go build" command
+// has discretionary access control list (DACL) set as if the file
+// was created in the destination directory.
+func TestACL(t *testing.T) {
+	if isWindowsXP(t) {
+		t.Skip("Windows XP does not have powershell command")
+	}
+
+	tmpdir, err := ioutil.TempDir("", "TestACL")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	newtmpdir := filepath.Join(tmpdir, "tmp")
+	err = os.Mkdir(newtmpdir, 0777)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// When TestACL/tmp directory is created, it will have
+	// the same security attributes as TestACL.
+	// Add Guest account full access to TestACL/tmp - this
+	// will make all files created in TestACL/tmp have different
+	// security attributes to the files created in TestACL.
+	runIcacls(t, newtmpdir,
+		"/grant", "guest:(oi)(ci)f", // add Guest user to have full access
+	)
+
+	src := filepath.Join(tmpdir, "main.go")
+	err = ioutil.WriteFile(src, []byte("package main; func main() { }\n"), 0644)
+	if err != nil {
+		t.Fatal(err)
+	}
+	exe := filepath.Join(tmpdir, "main.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src)
+	cmd.Env = append(os.Environ(),
+		"TMP="+newtmpdir,
+		"TEMP="+newtmpdir,
+	)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("go command failed: %v\n%v", err, string(out))
+	}
+
+	// exe file is expected to have the same security attributes as the src.
+	if got, expected := runGetACL(t, exe), runGetACL(t, src); got != expected {
+		t.Fatalf("expected Get-Acl output of \n%v\n, got \n%v\n", expected, got)
+	}
+}
diff --git a/src/cmd/go/internal/base/base.go b/src/cmd/go/internal/base/base.go
index aff33f7..286efbc 100644
--- a/src/cmd/go/internal/base/base.go
+++ b/src/cmd/go/internal/base/base.go
@@ -62,8 +62,8 @@
 }
 
 func (c *Command) Usage() {
-	fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
-	fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
+	fmt.Fprintf(os.Stderr, "usage: %s\n", c.UsageLine)
+	fmt.Fprintf(os.Stderr, "Run 'go help %s' for details.\n", c.Name())
 	os.Exit(2)
 }
 
diff --git a/src/cmd/go/internal/base/path.go b/src/cmd/go/internal/base/path.go
index 4f12fa8..7a51181 100644
--- a/src/cmd/go/internal/base/path.go
+++ b/src/cmd/go/internal/base/path.go
@@ -44,28 +44,6 @@
 	return out
 }
 
-// FilterDotUnderscoreFiles returns a slice containing all elements
-// of path whose base name doesn't begin with "." or "_".
-func FilterDotUnderscoreFiles(path []string) []string {
-	var out []string // lazily initialized
-	for i, p := range path {
-		base := filepath.Base(p)
-		if strings.HasPrefix(base, ".") || strings.HasPrefix(base, "_") {
-			if out == nil {
-				out = append(make([]string, 0, len(path)), path[:i]...)
-			}
-			continue
-		}
-		if out != nil {
-			out = append(out, p)
-		}
-	}
-	if out == nil {
-		return path
-	}
-	return out
-}
-
 // IsTestFile reports whether the source file is a set of tests and should therefore
 // be excluded from coverage analysis.
 func IsTestFile(file string) bool {
diff --git a/src/cmd/go/internal/base/tool.go b/src/cmd/go/internal/base/tool.go
index c907772..d0da65e 100644
--- a/src/cmd/go/internal/base/tool.go
+++ b/src/cmd/go/internal/base/tool.go
@@ -36,18 +36,9 @@
 	}
 	// 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 golang.org/x/tools/cmd/%s\n", toolName, toolName)
-		} else {
-			fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
-		}
+		fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
 		SetExitStatus(2)
 		Exit()
 	}
 	return toolPath
 }
-
-// TODO: Delete.
-func isInGoToolsRepo(toolName string) bool {
-	return false
-}
diff --git a/src/cmd/go/internal/buildid/buildid.go b/src/cmd/go/internal/buildid/buildid.go
deleted file mode 100644
index 091c909..0000000
--- a/src/cmd/go/internal/buildid/buildid.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package buildid
-
-import (
-	"bytes"
-	"cmd/go/internal/cfg"
-	"fmt"
-	"io"
-	"os"
-	"strconv"
-	"strings"
-)
-
-var (
-	errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain")
-	errBuildIDMalformed = fmt.Errorf("malformed object file")
-	errBuildIDUnknown   = fmt.Errorf("lost build ID")
-)
-
-var (
-	bangArch = []byte("!<arch>")
-	pkgdef   = []byte("__.PKGDEF")
-	goobject = []byte("go object ")
-	buildid  = []byte("build id ")
-)
-
-// ReadBuildID reads the build ID from an archive or binary.
-// It only supports the gc toolchain.
-// Other toolchain maintainers should adjust this function.
-func ReadBuildID(name, target string) (id string, err error) {
-	if cfg.BuildToolchainName != "gc" {
-		return "", errBuildIDToolchain
-	}
-
-	// For commands, read build ID directly from binary.
-	if name == "main" {
-		return ReadBuildIDFromBinary(target)
-	}
-
-	// Otherwise, we expect to have an archive (.a) file,
-	// and we can read the build ID from the Go export data.
-	if !strings.HasSuffix(target, ".a") {
-		return "", &os.PathError{Op: "parse", Path: target, Err: errBuildIDUnknown}
-	}
-
-	// Read just enough of the target to fetch the build ID.
-	// The archive is expected to look like:
-	//
-	//	!<arch>
-	//	__.PKGDEF       0           0     0     644     7955      `
-	//	go object darwin amd64 devel X:none
-	//	build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224"
-	//
-	// The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none).
-	// Reading the first 1024 bytes should be plenty.
-	f, err := os.Open(target)
-	if err != nil {
-		return "", err
-	}
-	data := make([]byte, 1024)
-	n, err := io.ReadFull(f, data)
-	f.Close()
-
-	if err != nil && n == 0 {
-		return "", err
-	}
-
-	bad := func() (string, error) {
-		return "", &os.PathError{Op: "parse", Path: target, Err: errBuildIDMalformed}
-	}
-
-	// Archive header.
-	for i := 0; ; i++ { // returns during i==3
-		j := bytes.IndexByte(data, '\n')
-		if j < 0 {
-			return bad()
-		}
-		line := data[:j]
-		data = data[j+1:]
-		switch i {
-		case 0:
-			if !bytes.Equal(line, bangArch) {
-				return bad()
-			}
-		case 1:
-			if !bytes.HasPrefix(line, pkgdef) {
-				return bad()
-			}
-		case 2:
-			if !bytes.HasPrefix(line, goobject) {
-				return bad()
-			}
-		case 3:
-			if !bytes.HasPrefix(line, buildid) {
-				// Found the object header, just doesn't have a build id line.
-				// Treat as successful, with empty build id.
-				return "", nil
-			}
-			id, err := strconv.Unquote(string(line[len(buildid):]))
-			if err != nil {
-				return bad()
-			}
-			return id, nil
-		}
-	}
-}
-
-var (
-	goBuildPrefix = []byte("\xff Go build ID: \"")
-	goBuildEnd    = []byte("\"\n \xff")
-
-	elfPrefix = []byte("\x7fELF")
-
-	machoPrefixes = [][]byte{
-		{0xfe, 0xed, 0xfa, 0xce},
-		{0xfe, 0xed, 0xfa, 0xcf},
-		{0xce, 0xfa, 0xed, 0xfe},
-		{0xcf, 0xfa, 0xed, 0xfe},
-	}
-)
-
-var BuildIDReadSize = 32 * 1024 // changed for testing
-
-// ReadBuildIDFromBinary reads the build ID from a binary.
-//
-// ELF binaries store the build ID in a proper PT_NOTE section.
-//
-// Other binary formats are not so flexible. For those, the linker
-// stores the build ID as non-instruction bytes at the very beginning
-// of the text segment, which should appear near the beginning
-// of the file. This is clumsy but fairly portable. Custom locations
-// can be added for other binary types as needed, like we did for ELF.
-func ReadBuildIDFromBinary(filename string) (id string, err error) {
-	if filename == "" {
-		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDUnknown}
-	}
-
-	// Read the first 32 kB of the binary file.
-	// That should be enough to find the build ID.
-	// In ELF files, the build ID is in the leading headers,
-	// which are typically less than 4 kB, not to mention 32 kB.
-	// In Mach-O files, there's no limit, so we have to parse the file.
-	// On other systems, we're trying to read enough that
-	// we get the beginning of the text segment in the read.
-	// The offset where the text segment begins in a hello
-	// world compiled for each different object format today:
-	//
-	//	Plan 9: 0x20
-	//	Windows: 0x600
-	//
-	f, err := os.Open(filename)
-	if err != nil {
-		return "", err
-	}
-	defer f.Close()
-
-	data := make([]byte, BuildIDReadSize)
-	_, err = io.ReadFull(f, data)
-	if err == io.ErrUnexpectedEOF {
-		err = nil
-	}
-	if err != nil {
-		return "", err
-	}
-
-	if bytes.HasPrefix(data, elfPrefix) {
-		return readELFGoBuildID(filename, f, data)
-	}
-	for _, m := range machoPrefixes {
-		if bytes.HasPrefix(data, m) {
-			return readMachoGoBuildID(filename, f, data)
-		}
-	}
-
-	return readRawGoBuildID(filename, data)
-}
-
-// readRawGoBuildID finds the raw build ID stored in text segment data.
-func readRawGoBuildID(filename string, data []byte) (id string, err error) {
-	i := bytes.Index(data, goBuildPrefix)
-	if i < 0 {
-		// Missing. Treat as successful but build ID empty.
-		return "", nil
-	}
-
-	j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd)
-	if j < 0 {
-		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed}
-	}
-
-	quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1]
-	id, err = strconv.Unquote(string(quoted))
-	if err != nil {
-		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed}
-	}
-
-	return id, nil
-}
diff --git a/src/cmd/go/internal/buildid/note.go b/src/cmd/go/internal/buildid/note.go
deleted file mode 100644
index 68c91e2..0000000
--- a/src/cmd/go/internal/buildid/note.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package buildid
-
-import (
-	"bytes"
-	"debug/elf"
-	"debug/macho"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-)
-
-func readAligned4(r io.Reader, sz int32) ([]byte, error) {
-	full := (sz + 3) &^ 3
-	data := make([]byte, full)
-	_, err := io.ReadFull(r, data)
-	if err != nil {
-		return nil, err
-	}
-	data = data[:sz]
-	return data, nil
-}
-
-func ReadELFNote(filename, name string, typ int32) ([]byte, error) {
-	f, err := elf.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	for _, sect := range f.Sections {
-		if sect.Type != elf.SHT_NOTE {
-			continue
-		}
-		r := sect.Open()
-		for {
-			var namesize, descsize, noteType int32
-			err = binary.Read(r, f.ByteOrder, &namesize)
-			if err != nil {
-				if err == io.EOF {
-					break
-				}
-				return nil, fmt.Errorf("read namesize failed: %v", err)
-			}
-			err = binary.Read(r, f.ByteOrder, &descsize)
-			if err != nil {
-				return nil, fmt.Errorf("read descsize failed: %v", err)
-			}
-			err = binary.Read(r, f.ByteOrder, &noteType)
-			if err != nil {
-				return nil, fmt.Errorf("read type failed: %v", err)
-			}
-			noteName, err := readAligned4(r, namesize)
-			if err != nil {
-				return nil, fmt.Errorf("read name failed: %v", err)
-			}
-			desc, err := readAligned4(r, descsize)
-			if err != nil {
-				return nil, fmt.Errorf("read desc failed: %v", err)
-			}
-			if name == string(noteName) && typ == noteType {
-				return desc, nil
-			}
-		}
-	}
-	return nil, nil
-}
-
-var elfGoNote = []byte("Go\x00\x00")
-
-// The Go build ID is stored in a note described by an ELF PT_NOTE prog
-// header. The caller has already opened filename, to get f, and read
-// at least 4 kB out, in data.
-func readELFGoBuildID(filename string, f *os.File, data []byte) (buildid string, err error) {
-	// Assume the note content is in the data, already read.
-	// Rewrite the ELF header to set shnum to 0, so that we can pass
-	// the data to elf.NewFile and it will decode the Prog list but not
-	// try to read the section headers and the string table from disk.
-	// That's a waste of I/O when all we care about is the Prog list
-	// and the one ELF note.
-	switch elf.Class(data[elf.EI_CLASS]) {
-	case elf.ELFCLASS32:
-		data[48] = 0
-		data[49] = 0
-	case elf.ELFCLASS64:
-		data[60] = 0
-		data[61] = 0
-	}
-
-	const elfGoBuildIDTag = 4
-
-	ef, err := elf.NewFile(bytes.NewReader(data))
-	if err != nil {
-		return "", &os.PathError{Path: filename, Op: "parse", Err: err}
-	}
-	for _, p := range ef.Progs {
-		if p.Type != elf.PT_NOTE || p.Filesz < 16 {
-			continue
-		}
-
-		var note []byte
-		if p.Off+p.Filesz < uint64(len(data)) {
-			note = data[p.Off : p.Off+p.Filesz]
-		} else {
-			// For some linkers, such as the Solaris linker,
-			// the buildid may not be found in data (which
-			// likely contains the first 16kB of the file)
-			// or even the first few megabytes of the file
-			// due to differences in note segment placement;
-			// in that case, extract the note data manually.
-			_, err = f.Seek(int64(p.Off), io.SeekStart)
-			if err != nil {
-				return "", err
-			}
-
-			note = make([]byte, p.Filesz)
-			_, err = io.ReadFull(f, note)
-			if err != nil {
-				return "", err
-			}
-		}
-
-		filesz := p.Filesz
-		for filesz >= 16 {
-			nameSize := ef.ByteOrder.Uint32(note)
-			valSize := ef.ByteOrder.Uint32(note[4:])
-			tag := ef.ByteOrder.Uint32(note[8:])
-			name := note[12:16]
-			if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == elfGoBuildIDTag && bytes.Equal(name, elfGoNote) {
-				return string(note[16 : 16+valSize]), nil
-			}
-
-			nameSize = (nameSize + 3) &^ 3
-			valSize = (valSize + 3) &^ 3
-			notesz := uint64(12 + nameSize + valSize)
-			if filesz <= notesz {
-				break
-			}
-			filesz -= notesz
-			note = note[notesz:]
-		}
-	}
-
-	// No note. Treat as successful but build ID empty.
-	return "", nil
-}
-
-// The Go build ID is stored at the beginning of the Mach-O __text segment.
-// The caller has already opened filename, to get f, and read a few kB out, in data.
-// Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount
-// of other junk placed in the file ahead of the main text.
-func readMachoGoBuildID(filename string, f *os.File, data []byte) (buildid string, err error) {
-	// If the data we want has already been read, don't worry about Mach-O parsing.
-	// This is both an optimization and a hedge against the Mach-O parsing failing
-	// in the future due to, for example, the name of the __text section changing.
-	if b, err := readRawGoBuildID(filename, data); b != "" && err == nil {
-		return b, err
-	}
-
-	mf, err := macho.NewFile(f)
-	if err != nil {
-		return "", &os.PathError{Path: filename, Op: "parse", Err: err}
-	}
-
-	sect := mf.Section("__text")
-	if sect == nil {
-		// Every binary has a __text section. Something is wrong.
-		return "", &os.PathError{Path: filename, Op: "parse", Err: fmt.Errorf("cannot find __text section")}
-	}
-
-	// It should be in the first few bytes, but read a lot just in case,
-	// especially given our past problems on OS X with the build ID moving.
-	// There shouldn't be much difference between reading 4kB and 32kB:
-	// the hard part is getting to the data, not transferring it.
-	n := sect.Size
-	if n > uint64(BuildIDReadSize) {
-		n = uint64(BuildIDReadSize)
-	}
-	buf := make([]byte, n)
-	if _, err := f.ReadAt(buf, int64(sect.Offset)); err != nil {
-		return "", err
-	}
-
-	return readRawGoBuildID(filename, buf)
-}
diff --git a/src/cmd/go/internal/cache/cache.go b/src/cmd/go/internal/cache/cache.go
new file mode 100644
index 0000000..edb5882
--- /dev/null
+++ b/src/cmd/go/internal/cache/cache.go
@@ -0,0 +1,459 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cache implements a build artifact cache.
+package cache
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// An ActionID is a cache action key, the hash of a complete description of a
+// repeatable computation (command line, environment variables,
+// input file contents, executable contents).
+type ActionID [HashSize]byte
+
+// An OutputID is a cache output key, the hash of an output of a computation.
+type OutputID [HashSize]byte
+
+// A Cache is a package cache, backed by a file system directory tree.
+type Cache struct {
+	dir string
+	log *os.File
+	now func() time.Time
+}
+
+// Open opens and returns the cache in the given directory.
+//
+// It is safe for multiple processes on a single machine to use the
+// same cache directory in a local file system simultaneously.
+// They will coordinate using operating system file locks and may
+// duplicate effort but will not corrupt the cache.
+//
+// However, it is NOT safe for multiple processes on different machines
+// to share a cache directory (for example, if the directory were stored
+// in a network file system). File locking is notoriously unreliable in
+// network file systems and may not suffice to protect the cache.
+//
+func Open(dir string) (*Cache, error) {
+	info, err := os.Stat(dir)
+	if err != nil {
+		return nil, err
+	}
+	if !info.IsDir() {
+		return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")}
+	}
+	for i := 0; i < 256; i++ {
+		name := filepath.Join(dir, fmt.Sprintf("%02x", i))
+		if err := os.MkdirAll(name, 0777); err != nil {
+			return nil, err
+		}
+	}
+	f, err := os.OpenFile(filepath.Join(dir, "log.txt"), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
+	if err != nil {
+		return nil, err
+	}
+	c := &Cache{
+		dir: dir,
+		log: f,
+		now: time.Now,
+	}
+	return c, nil
+}
+
+// fileName returns the name of the file corresponding to the given id.
+func (c *Cache) fileName(id [HashSize]byte, key string) string {
+	return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key)
+}
+
+var errMissing = errors.New("cache entry not found")
+
+const (
+	// action entry file is "v1 <hex id> <hex out> <decimal size space-padded to 20 bytes> <unixnano space-padded to 20 bytes>\n"
+	hexSize   = HashSize * 2
+	entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1
+)
+
+// verify controls whether to run the cache in verify mode.
+// In verify mode, the cache always returns errMissing from Get
+// but then double-checks in Put that the data being written
+// exactly matches any existing entry. This provides an easy
+// way to detect program behavior that would have been different
+// had the cache entry been returned from Get.
+//
+// verify is enabled by setting the environment variable
+// GODEBUG=gocacheverify=1.
+var verify = false
+
+// DebugTest is set when GODEBUG=gocachetest=1 is in the environment.
+var DebugTest = false
+
+func init() { initEnv() }
+
+func initEnv() {
+	verify = false
+	debugHash = false
+	debug := strings.Split(os.Getenv("GODEBUG"), ",")
+	for _, f := range debug {
+		if f == "gocacheverify=1" {
+			verify = true
+		}
+		if f == "gocachehash=1" {
+			debugHash = true
+		}
+		if f == "gocachetest=1" {
+			DebugTest = true
+		}
+	}
+}
+
+// Get looks up the action ID in the cache,
+// returning the corresponding output ID and file size, if any.
+// Note that finding an output ID does not guarantee that the
+// saved file for that output ID is still available.
+func (c *Cache) Get(id ActionID) (Entry, error) {
+	if verify {
+		return Entry{}, errMissing
+	}
+	return c.get(id)
+}
+
+type Entry struct {
+	OutputID OutputID
+	Size     int64
+	Time     time.Time
+}
+
+// get is Get but does not respect verify mode, so that Put can use it.
+func (c *Cache) get(id ActionID) (Entry, error) {
+	missing := func() (Entry, error) {
+		fmt.Fprintf(c.log, "%d miss %x\n", c.now().Unix(), id)
+		return Entry{}, errMissing
+	}
+	f, err := os.Open(c.fileName(id, "a"))
+	if err != nil {
+		return missing()
+	}
+	defer f.Close()
+	entry := make([]byte, entrySize+1) // +1 to detect whether f is too long
+	if n, err := io.ReadFull(f, entry); n != entrySize || err != io.ErrUnexpectedEOF {
+		return missing()
+	}
+	if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' {
+		return missing()
+	}
+	eid, entry := entry[3:3+hexSize], entry[3+hexSize:]
+	eout, entry := entry[1:1+hexSize], entry[1+hexSize:]
+	esize, entry := entry[1:1+20], entry[1+20:]
+	etime, entry := entry[1:1+20], entry[1+20:]
+	var buf [HashSize]byte
+	if _, err := hex.Decode(buf[:], eid); err != nil || buf != id {
+		return missing()
+	}
+	if _, err := hex.Decode(buf[:], eout); err != nil {
+		return missing()
+	}
+	i := 0
+	for i < len(esize) && esize[i] == ' ' {
+		i++
+	}
+	size, err := strconv.ParseInt(string(esize[i:]), 10, 64)
+	if err != nil || size < 0 {
+		return missing()
+	}
+	i = 0
+	for i < len(etime) && etime[i] == ' ' {
+		i++
+	}
+	tm, err := strconv.ParseInt(string(etime[i:]), 10, 64)
+	if err != nil || size < 0 {
+		return missing()
+	}
+
+	fmt.Fprintf(c.log, "%d get %x\n", c.now().Unix(), id)
+
+	c.used(c.fileName(id, "a"))
+
+	return Entry{buf, size, time.Unix(0, tm)}, nil
+}
+
+// GetBytes looks up the action ID in the cache and returns
+// the corresponding output bytes.
+// GetBytes should only be used for data that can be expected to fit in memory.
+func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
+	entry, err := c.Get(id)
+	if err != nil {
+		return nil, entry, err
+	}
+	data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID))
+	if sha256.Sum256(data) != entry.OutputID {
+		return nil, entry, errMissing
+	}
+	return data, entry, nil
+}
+
+// OutputFile returns the name of the cache file storing output with the given OutputID.
+func (c *Cache) OutputFile(out OutputID) string {
+	file := c.fileName(out, "d")
+	c.used(file)
+	return file
+}
+
+// Time constants for cache expiration.
+//
+// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour),
+// to avoid causing many unnecessary inode updates. The mtimes therefore
+// roughly reflect "time of last use" but may in fact be older by at most an hour.
+//
+// We scan the cache for entries to delete at most once per trimInterval (1 day).
+//
+// When we do scan the cache, we delete entries that have not been used for
+// at least trimLimit (5 days). Statistics gathered from a month of usage by
+// Go developers found that essentially all reuse of cached entries happened
+// within 5 days of the previous reuse. See golang.org/issue/22990.
+const (
+	mtimeInterval = 1 * time.Hour
+	trimInterval  = 24 * time.Hour
+	trimLimit     = 5 * 24 * time.Hour
+)
+
+// used makes a best-effort attempt to update mtime on file,
+// so that mtime reflects cache access time.
+//
+// Because the reflection only needs to be approximate,
+// and to reduce the amount of disk activity caused by using
+// cache entries, used only updates the mtime if the current
+// mtime is more than an hour old. This heuristic eliminates
+// nearly all of the mtime updates that would otherwise happen,
+// while still keeping the mtimes useful for cache trimming.
+func (c *Cache) used(file string) {
+	info, err := os.Stat(file)
+	if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval {
+		return
+	}
+	os.Chtimes(file, c.now(), c.now())
+}
+
+// Trim removes old cache entries that are likely not to be reused.
+func (c *Cache) Trim() {
+	now := c.now()
+
+	// We maintain in dir/trim.txt the time of the last completed cache trim.
+	// If the cache has been trimmed recently enough, do nothing.
+	// This is the common case.
+	data, _ := ioutil.ReadFile(filepath.Join(c.dir, "trim.txt"))
+	t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
+	if err == nil && now.Sub(time.Unix(t, 0)) < trimInterval {
+		return
+	}
+
+	// Trim each of the 256 subdirectories.
+	// We subtract an additional mtimeInterval
+	// to account for the imprecision of our "last used" mtimes.
+	cutoff := now.Add(-trimLimit - mtimeInterval)
+	for i := 0; i < 256; i++ {
+		subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i))
+		c.trimSubdir(subdir, cutoff)
+	}
+
+	ioutil.WriteFile(filepath.Join(c.dir, "trim.txt"), []byte(fmt.Sprintf("%d", now.Unix())), 0666)
+}
+
+// trimSubdir trims a single cache subdirectory.
+func (c *Cache) trimSubdir(subdir string, cutoff time.Time) {
+	// Read all directory entries from subdir before removing
+	// any files, in case removing files invalidates the file offset
+	// in the directory scan. Also, ignore error from f.Readdirnames,
+	// because we don't care about reporting the error and we still
+	// want to process any entries found before the error.
+	f, err := os.Open(subdir)
+	if err != nil {
+		return
+	}
+	names, _ := f.Readdirnames(-1)
+	f.Close()
+
+	for _, name := range names {
+		// Remove only cache entries (xxxx-a and xxxx-d).
+		if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") {
+			continue
+		}
+		entry := filepath.Join(subdir, name)
+		info, err := os.Stat(entry)
+		if err == nil && info.ModTime().Before(cutoff) {
+			os.Remove(entry)
+		}
+	}
+}
+
+// putIndexEntry adds an entry to the cache recording that executing the action
+// with the given id produces an output with the given output id (hash) and size.
+func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error {
+	// Note: We expect that for one reason or another it may happen
+	// that repeating an action produces a different output hash
+	// (for example, if the output contains a time stamp or temp dir name).
+	// While not ideal, this is also not a correctness problem, so we
+	// don't make a big deal about it. In particular, we leave the action
+	// cache entries writable specifically so that they can be overwritten.
+	//
+	// Setting GODEBUG=gocacheverify=1 does make a big deal:
+	// in verify mode we are double-checking that the cache entries
+	// are entirely reproducible. As just noted, this may be unrealistic
+	// in some cases but the check is also useful for shaking out real bugs.
+	entry := []byte(fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()))
+	if verify && allowVerify {
+		old, err := c.get(id)
+		if err == nil && (old.OutputID != out || old.Size != size) {
+			// panic to show stack trace, so we can see what code is generating this cache entry.
+			msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size)
+			panic(msg)
+		}
+	}
+	file := c.fileName(id, "a")
+	if err := ioutil.WriteFile(file, entry, 0666); err != nil {
+		os.Remove(file)
+		return err
+	}
+	os.Chtimes(file, c.now(), c.now()) // mainly for tests
+
+	fmt.Fprintf(c.log, "%d put %x %x %d\n", c.now().Unix(), id, out, size)
+	return nil
+}
+
+// Put stores the given output in the cache as the output for the action ID.
+// It may read file twice. The content of file must not change between the two passes.
+func (c *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
+	return c.put(id, file, true)
+}
+
+// PutNoVerify is like Put but disables the verify check
+// when GODEBUG=goverifycache=1 is set.
+// It is meant for data that is OK to cache but that we expect to vary slightly from run to run,
+// like test output containing times and the like.
+func (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
+	return c.put(id, file, false)
+}
+
+func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
+	// Compute output ID.
+	h := sha256.New()
+	if _, err := file.Seek(0, 0); err != nil {
+		return OutputID{}, 0, err
+	}
+	size, err := io.Copy(h, file)
+	if err != nil {
+		return OutputID{}, 0, err
+	}
+	var out OutputID
+	h.Sum(out[:0])
+
+	// Copy to cached output file (if not already present).
+	if err := c.copyFile(file, out, size); err != nil {
+		return out, size, err
+	}
+
+	// Add to cache index.
+	return out, size, c.putIndexEntry(id, out, size, allowVerify)
+}
+
+// PutBytes stores the given bytes in the cache as the output for the action ID.
+func (c *Cache) PutBytes(id ActionID, data []byte) error {
+	_, _, err := c.Put(id, bytes.NewReader(data))
+	return err
+}
+
+// copyFile copies file into the cache, expecting it to have the given
+// output ID and size, if that file is not present already.
+func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
+	name := c.fileName(out, "d")
+	info, err := os.Stat(name)
+	if err == nil && info.Size() == size {
+		// Check hash.
+		if f, err := os.Open(name); err == nil {
+			h := sha256.New()
+			io.Copy(h, f)
+			f.Close()
+			var out2 OutputID
+			h.Sum(out2[:0])
+			if out == out2 {
+				return nil
+			}
+		}
+		// Hash did not match. Fall through and rewrite file.
+	}
+
+	// Copy file to cache directory.
+	mode := os.O_RDWR | os.O_CREATE
+	if err == nil && info.Size() > size { // shouldn't happen but fix in case
+		mode |= os.O_TRUNC
+	}
+	f, err := os.OpenFile(name, mode, 0666)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	if size == 0 {
+		// File now exists with correct size.
+		// Only one possible zero-length file, so contents are OK too.
+		// Early return here makes sure there's a "last byte" for code below.
+		return nil
+	}
+
+	// From here on, if any of the I/O writing the file fails,
+	// we make a best-effort attempt to truncate the file f
+	// before returning, to avoid leaving bad bytes in the file.
+
+	// Copy file to f, but also into h to double-check hash.
+	if _, err := file.Seek(0, 0); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	h := sha256.New()
+	w := io.MultiWriter(f, h)
+	if _, err := io.CopyN(w, file, size-1); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	// Check last byte before writing it; writing it will make the size match
+	// what other processes expect to find and might cause them to start
+	// using the file.
+	buf := make([]byte, 1)
+	if _, err := file.Read(buf); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	h.Write(buf)
+	sum := h.Sum(nil)
+	if !bytes.Equal(sum, out[:]) {
+		f.Truncate(0)
+		return fmt.Errorf("file content changed underfoot")
+	}
+
+	// Commit cache file entry.
+	if _, err := f.Write(buf); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	if err := f.Close(); err != nil {
+		// Data might not have been written,
+		// but file may look like it is the right size.
+		// To be extra careful, remove cached file.
+		os.Remove(name)
+		return err
+	}
+	os.Chtimes(name, c.now(), c.now()) // mainly for tests
+
+	return nil
+}
diff --git a/src/cmd/go/internal/cache/cache_test.go b/src/cmd/go/internal/cache/cache_test.go
new file mode 100644
index 0000000..d3dafcc
--- /dev/null
+++ b/src/cmd/go/internal/cache/cache_test.go
@@ -0,0 +1,319 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+)
+
+func init() {
+	verify = false // even if GODEBUG is set
+}
+
+func TestBasic(t *testing.T) {
+	dir, err := ioutil.TempDir("", "cachetest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+	_, err = Open(filepath.Join(dir, "notexist"))
+	if err == nil {
+		t.Fatal(`Open("tmp/notexist") succeeded, want failure`)
+	}
+
+	cdir := filepath.Join(dir, "c1")
+	if err := os.Mkdir(cdir, 0777); err != nil {
+		t.Fatal(err)
+	}
+
+	c1, err := Open(cdir)
+	if err != nil {
+		t.Fatalf("Open(c1) (create): %v", err)
+	}
+	if err := c1.putIndexEntry(dummyID(1), dummyID(12), 13, true); err != nil {
+		t.Fatalf("addIndexEntry: %v", err)
+	}
+	if err := c1.putIndexEntry(dummyID(1), dummyID(2), 3, true); err != nil { // overwrite entry
+		t.Fatalf("addIndexEntry: %v", err)
+	}
+	if entry, err := c1.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
+		t.Fatalf("c1.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
+	}
+
+	c2, err := Open(cdir)
+	if err != nil {
+		t.Fatalf("Open(c2) (reuse): %v", err)
+	}
+	if entry, err := c2.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
+		t.Fatalf("c2.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
+	}
+	if err := c2.putIndexEntry(dummyID(2), dummyID(3), 4, true); err != nil {
+		t.Fatalf("addIndexEntry: %v", err)
+	}
+	if entry, err := c1.Get(dummyID(2)); err != nil || entry.OutputID != dummyID(3) || entry.Size != 4 {
+		t.Fatalf("c1.Get(2) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(3), 4)
+	}
+}
+
+func TestGrowth(t *testing.T) {
+	dir, err := ioutil.TempDir("", "cachetest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	c, err := Open(dir)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+
+	n := 10000
+	if testing.Short() {
+		n = 1000
+	}
+
+	for i := 0; i < n; i++ {
+		if err := c.putIndexEntry(dummyID(i), dummyID(i*99), int64(i)*101, true); err != nil {
+			t.Fatalf("addIndexEntry: %v", err)
+		}
+		id := ActionID(dummyID(i))
+		entry, err := c.Get(id)
+		if err != nil {
+			t.Fatalf("Get(%x): %v", id, err)
+		}
+		if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
+			t.Errorf("Get(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
+		}
+	}
+	for i := 0; i < n; i++ {
+		id := ActionID(dummyID(i))
+		entry, err := c.Get(id)
+		if err != nil {
+			t.Fatalf("Get2(%x): %v", id, err)
+		}
+		if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
+			t.Errorf("Get2(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
+		}
+	}
+}
+
+func TestVerifyPanic(t *testing.T) {
+	os.Setenv("GODEBUG", "gocacheverify=1")
+	initEnv()
+	defer func() {
+		os.Unsetenv("GODEBUG")
+		verify = false
+	}()
+
+	if !verify {
+		t.Fatal("initEnv did not set verify")
+	}
+
+	dir, err := ioutil.TempDir("", "cachetest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	c, err := Open(dir)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+
+	id := ActionID(dummyID(1))
+	if err := c.PutBytes(id, []byte("abc")); err != nil {
+		t.Fatal(err)
+	}
+
+	defer func() {
+		if err := recover(); err != nil {
+			t.Log(err)
+			return
+		}
+	}()
+	c.PutBytes(id, []byte("def"))
+	t.Fatal("mismatched Put did not panic in verify mode")
+}
+
+func TestCacheLog(t *testing.T) {
+	dir, err := ioutil.TempDir("", "cachetest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	c, err := Open(dir)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+	c.now = func() time.Time { return time.Unix(1e9, 0) }
+
+	id := ActionID(dummyID(1))
+	c.Get(id)
+	c.PutBytes(id, []byte("abc"))
+	c.Get(id)
+
+	c, err = Open(dir)
+	if err != nil {
+		t.Fatalf("Open #2: %v", err)
+	}
+	c.now = func() time.Time { return time.Unix(1e9+1, 0) }
+	c.Get(id)
+
+	id2 := ActionID(dummyID(2))
+	c.Get(id2)
+	c.PutBytes(id2, []byte("abc"))
+	c.Get(id2)
+	c.Get(id)
+
+	data, err := ioutil.ReadFile(filepath.Join(dir, "log.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := `1000000000 miss 0100000000000000000000000000000000000000000000000000000000000000
+1000000000 put 0100000000000000000000000000000000000000000000000000000000000000 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad 3
+1000000000 get 0100000000000000000000000000000000000000000000000000000000000000
+1000000001 get 0100000000000000000000000000000000000000000000000000000000000000
+1000000001 miss 0200000000000000000000000000000000000000000000000000000000000000
+1000000001 put 0200000000000000000000000000000000000000000000000000000000000000 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad 3
+1000000001 get 0200000000000000000000000000000000000000000000000000000000000000
+1000000001 get 0100000000000000000000000000000000000000000000000000000000000000
+`
+	if string(data) != want {
+		t.Fatalf("log:\n%s\nwant:\n%s", string(data), want)
+	}
+}
+
+func dummyID(x int) [HashSize]byte {
+	var out [HashSize]byte
+	binary.LittleEndian.PutUint64(out[:], uint64(x))
+	return out
+}
+
+func TestCacheTrim(t *testing.T) {
+	dir, err := ioutil.TempDir("", "cachetest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	c, err := Open(dir)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+	const start = 1000000000
+	now := int64(start)
+	c.now = func() time.Time { return time.Unix(now, 0) }
+
+	checkTime := func(name string, mtime int64) {
+		t.Helper()
+		file := filepath.Join(c.dir, name[:2], name)
+		info, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if info.ModTime().Unix() != mtime {
+			t.Fatalf("%s mtime = %d, want %d", name, info.ModTime().Unix(), mtime)
+		}
+	}
+
+	id := ActionID(dummyID(1))
+	c.PutBytes(id, []byte("abc"))
+	entry, _ := c.Get(id)
+	c.PutBytes(ActionID(dummyID(2)), []byte("def"))
+	mtime := now
+	checkTime(fmt.Sprintf("%x-a", id), mtime)
+	checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
+
+	// Get should not change recent mtimes.
+	now = start + 10
+	c.Get(id)
+	checkTime(fmt.Sprintf("%x-a", id), mtime)
+	checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
+
+	// Get should change distant mtimes.
+	now = start + 5000
+	mtime2 := now
+	if _, err := c.Get(id); err != nil {
+		t.Fatal(err)
+	}
+	c.OutputFile(entry.OutputID)
+	checkTime(fmt.Sprintf("%x-a", id), mtime2)
+	checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime2)
+
+	// Trim should leave everything alone: it's all too new.
+	c.Trim()
+	if _, err := c.Get(id); err != nil {
+		t.Fatal(err)
+	}
+	c.OutputFile(entry.OutputID)
+	data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
+
+	// Trim less than a day later should not do any work at all.
+	now = start + 80000
+	c.Trim()
+	if _, err := c.Get(id); err != nil {
+		t.Fatal(err)
+	}
+	c.OutputFile(entry.OutputID)
+	data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(data, data2) {
+		t.Fatalf("second trim did work: %q -> %q", data, data2)
+	}
+
+	// Fast forward and do another trim just before the 5 day cutoff.
+	// Note that because of usedQuantum the cutoff is actually 5 days + 1 hour.
+	// We used c.Get(id) just now, so 5 days later it should still be kept.
+	// On the other hand almost a full day has gone by since we wrote dummyID(2)
+	// and we haven't looked at it since, so 5 days later it should be gone.
+	now += 5 * 86400
+	checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
+	c.Trim()
+	if _, err := c.Get(id); err != nil {
+		t.Fatal(err)
+	}
+	c.OutputFile(entry.OutputID)
+	mtime3 := now
+	if _, err := c.Get(dummyID(2)); err == nil { // haven't done a Get for this since original write above
+		t.Fatalf("Trim did not remove dummyID(2)")
+	}
+
+	// The c.Get(id) refreshed id's mtime again.
+	// Check that another 5 days later it is still not gone,
+	// but check by using checkTime, which doesn't bring mtime forward.
+	now += 5 * 86400
+	c.Trim()
+	checkTime(fmt.Sprintf("%x-a", id), mtime3)
+	checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
+
+	// Half a day later Trim should still be a no-op, because there was a Trim recently.
+	// Even though the entry for id is now old enough to be trimmed,
+	// it gets a reprieve until the time comes for a new Trim scan.
+	now += 86400 / 2
+	c.Trim()
+	checkTime(fmt.Sprintf("%x-a", id), mtime3)
+	checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
+
+	// Another half a day later, Trim should actually run, and it should remove id.
+	now += 86400/2 + 1
+	c.Trim()
+	if _, err := c.Get(dummyID(1)); err == nil {
+		t.Fatal("Trim did not remove dummyID(1)")
+	}
+}
diff --git a/src/cmd/go/internal/cache/default.go b/src/cmd/go/internal/cache/default.go
new file mode 100644
index 0000000..9728376
--- /dev/null
+++ b/src/cmd/go/internal/cache/default.go
@@ -0,0 +1,110 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"runtime"
+	"sync"
+)
+
+// Default returns the default cache to use, or nil if no cache should be used.
+func Default() *Cache {
+	defaultOnce.Do(initDefaultCache)
+	return defaultCache
+}
+
+var (
+	defaultOnce  sync.Once
+	defaultCache *Cache
+)
+
+// cacheREADME is a message stored in a README in the cache directory.
+// Because the cache lives outside the normal Go trees, we leave the
+// README as a courtesy to explain where it came from.
+const cacheREADME = `This directory holds cached build artifacts from the Go build system.
+Run "go clean -cache" if the directory is getting too large.
+See golang.org to learn more about Go.
+`
+
+// initDefaultCache does the work of finding the default cache
+// the first time Default is called.
+func initDefaultCache() {
+	dir := DefaultDir()
+	if dir == "off" {
+		return
+	}
+	if err := os.MkdirAll(dir, 0777); err != nil {
+		fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+		return
+	}
+	if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
+		// Best effort.
+		ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
+	}
+
+	c, err := Open(dir)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+		return
+	}
+	defaultCache = c
+}
+
+// DefaultDir returns the effective GOCACHE setting.
+// It returns "off" if the cache is disabled.
+func DefaultDir() string {
+	dir := os.Getenv("GOCACHE")
+	if dir != "" {
+		return dir
+	}
+
+	// Compute default location.
+	// TODO(rsc): This code belongs somewhere else,
+	// like maybe ioutil.CacheDir or os.CacheDir.
+	switch runtime.GOOS {
+	case "windows":
+		dir = os.Getenv("LocalAppData")
+		if dir == "" {
+			// Fall back to %AppData%, the old name of
+			// %LocalAppData% on Windows XP.
+			dir = os.Getenv("AppData")
+		}
+		if dir == "" {
+			return "off"
+		}
+
+	case "darwin":
+		dir = os.Getenv("HOME")
+		if dir == "" {
+			return "off"
+		}
+		dir += "/Library/Caches"
+
+	case "plan9":
+		dir = os.Getenv("home")
+		if dir == "" {
+			return "off"
+		}
+		// Plan 9 has no established per-user cache directory,
+		// but $home/lib/xyz is the usual equivalent of $HOME/.xyz on Unix.
+		dir += "/lib/cache"
+
+	default: // Unix
+		// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+		dir = os.Getenv("XDG_CACHE_HOME")
+		if dir == "" {
+			dir = os.Getenv("HOME")
+			if dir == "" {
+				return "off"
+			}
+			dir += "/.cache"
+		}
+	}
+	return filepath.Join(dir, "go-build")
+}
diff --git a/src/cmd/go/internal/cache/hash.go b/src/cmd/go/internal/cache/hash.go
new file mode 100644
index 0000000..0e45e7d
--- /dev/null
+++ b/src/cmd/go/internal/cache/hash.go
@@ -0,0 +1,174 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"fmt"
+	"hash"
+	"io"
+	"os"
+	"runtime"
+	"sync"
+)
+
+var debugHash = false // set when GODEBUG=gocachehash=1
+
+// HashSize is the number of bytes in a hash.
+const HashSize = 32
+
+// A Hash provides access to the canonical hash function used to index the cache.
+// The current implementation uses salted SHA256, but clients must not assume this.
+type Hash struct {
+	h    hash.Hash
+	name string        // for debugging
+	buf  *bytes.Buffer // for verify
+}
+
+// hashSalt is a salt string added to the beginning of every hash
+// created by NewHash. Using the Go version makes sure that different
+// versions of the go command (or even different Git commits during
+// work on the development branch) do not address the same cache
+// entries, so that a bug in one version does not affect the execution
+// of other versions. This salt will result in additional ActionID files
+// in the cache, but not additional copies of the large output files,
+// which are still addressed by unsalted SHA256.
+var hashSalt = []byte(runtime.Version())
+
+// Subkey returns an action ID corresponding to mixing a parent
+// action ID with a string description of the subkey.
+func Subkey(parent ActionID, desc string) ActionID {
+	h := sha256.New()
+	h.Write([]byte("subkey:"))
+	h.Write(parent[:])
+	h.Write([]byte(desc))
+	var out ActionID
+	h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out)
+	}
+	if verify {
+		hashDebug.Lock()
+		hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc)
+		hashDebug.Unlock()
+	}
+	return out
+}
+
+// NewHash returns a new Hash.
+// The caller is expected to Write data to it and then call Sum.
+func NewHash(name string) *Hash {
+	h := &Hash{h: sha256.New(), name: name}
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name)
+	}
+	h.Write(hashSalt)
+	if verify {
+		h.buf = new(bytes.Buffer)
+	}
+	return h
+}
+
+// Write writes data to the running hash.
+func (h *Hash) Write(b []byte) (int, error) {
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b)
+	}
+	if h.buf != nil {
+		h.buf.Write(b)
+	}
+	return h.h.Write(b)
+}
+
+// Sum returns the hash of the data written previously.
+func (h *Hash) Sum() [HashSize]byte {
+	var out [HashSize]byte
+	h.h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out)
+	}
+	if h.buf != nil {
+		hashDebug.Lock()
+		if hashDebug.m == nil {
+			hashDebug.m = make(map[[HashSize]byte]string)
+		}
+		hashDebug.m[out] = h.buf.String()
+		hashDebug.Unlock()
+	}
+	return out
+}
+
+// In GODEBUG=gocacheverify=1 mode,
+// hashDebug holds the input to every computed hash ID,
+// so that we can work backward from the ID involved in a
+// cache entry mismatch to a description of what should be there.
+var hashDebug struct {
+	sync.Mutex
+	m map[[HashSize]byte]string
+}
+
+// reverseHash returns the input used to compute the hash id.
+func reverseHash(id [HashSize]byte) string {
+	hashDebug.Lock()
+	s := hashDebug.m[id]
+	hashDebug.Unlock()
+	return s
+}
+
+var hashFileCache struct {
+	sync.Mutex
+	m map[string][HashSize]byte
+}
+
+// HashFile returns the hash of the named file.
+// It caches repeated lookups for a given file,
+// and the cache entry for a file can be initialized
+// using SetFileHash.
+// The hash used by FileHash is not the same as
+// the hash used by NewHash.
+func FileHash(file string) ([HashSize]byte, error) {
+	hashFileCache.Lock()
+	out, ok := hashFileCache.m[file]
+	hashFileCache.Unlock()
+
+	if ok {
+		return out, nil
+	}
+
+	h := sha256.New()
+	f, err := os.Open(file)
+	if err != nil {
+		if debugHash {
+			fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
+		}
+		return [HashSize]byte{}, err
+	}
+	_, err = io.Copy(h, f)
+	f.Close()
+	if err != nil {
+		if debugHash {
+			fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
+		}
+		return [HashSize]byte{}, err
+	}
+	h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out)
+	}
+
+	SetFileHash(file, out)
+	return out, nil
+}
+
+// SetFileHash sets the hash returned by FileHash for file.
+func SetFileHash(file string, sum [HashSize]byte) {
+	hashFileCache.Lock()
+	if hashFileCache.m == nil {
+		hashFileCache.m = make(map[string][HashSize]byte)
+	}
+	hashFileCache.m[file] = sum
+	hashFileCache.Unlock()
+}
diff --git a/src/cmd/go/internal/cache/hash_test.go b/src/cmd/go/internal/cache/hash_test.go
new file mode 100644
index 0000000..3bf7143
--- /dev/null
+++ b/src/cmd/go/internal/cache/hash_test.go
@@ -0,0 +1,52 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"testing"
+)
+
+func TestHash(t *testing.T) {
+	oldSalt := hashSalt
+	hashSalt = nil
+	defer func() {
+		hashSalt = oldSalt
+	}()
+
+	h := NewHash("alice")
+	h.Write([]byte("hello world"))
+	sum := fmt.Sprintf("%x", h.Sum())
+	want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
+	if sum != want {
+		t.Errorf("hash(hello world) = %v, want %v", sum, want)
+	}
+}
+
+func TestHashFile(t *testing.T) {
+	f, err := ioutil.TempFile("", "cmd-go-test-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	name := f.Name()
+	fmt.Fprintf(f, "hello world")
+	defer os.Remove(name)
+	if err := f.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	var h ActionID // make sure hash result is assignable to ActionID
+	h, err = FileHash(name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	sum := fmt.Sprintf("%x", h)
+	want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
+	if sum != want {
+		t.Errorf("hash(hello world) = %v, want %v", sum, want)
+	}
+}
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index b3ad1ce..1de4f0d 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -22,7 +22,6 @@
 	BuildBuildmode         string // -buildmode flag
 	BuildContext           = build.Default
 	BuildI                 bool               // -i flag
-	BuildLdflags           []string           // -ldflags flag
 	BuildLinkshared        bool               // -linkshared flag
 	BuildMSan              bool               // -msan flag
 	BuildN                 bool               // -n flag
@@ -37,6 +36,10 @@
 	BuildV                 bool // -v flag
 	BuildWork              bool // -work flag
 	BuildX                 bool // -x flag
+
+	CmdName string // "build", "install", "list", etc.
+
+	DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable)
 )
 
 func init() {
@@ -73,15 +76,17 @@
 }
 
 var (
-	GOROOT    = findGOROOT()
-	GOBIN     = os.Getenv("GOBIN")
-	GOROOTbin = filepath.Join(GOROOT, "bin")
-	GOROOTpkg = filepath.Join(GOROOT, "pkg")
-	GOROOTsrc = filepath.Join(GOROOT, "src")
+	GOROOT       = findGOROOT()
+	GOBIN        = os.Getenv("GOBIN")
+	GOROOTbin    = filepath.Join(GOROOT, "bin")
+	GOROOTpkg    = filepath.Join(GOROOT, "pkg")
+	GOROOTsrc    = filepath.Join(GOROOT, "src")
+	GOROOT_FINAL = findGOROOT_FINAL()
 
 	// Used in envcmd.MkEnv and build ID computations.
-	GOARM = fmt.Sprint(objabi.GOARM)
-	GO386 = objabi.GO386
+	GOARM  = fmt.Sprint(objabi.GOARM)
+	GO386  = objabi.GO386
+	GOMIPS = objabi.GOMIPS
 )
 
 // Update build context to use our computed GOROOT.
@@ -98,22 +103,49 @@
 	if env := os.Getenv("GOROOT"); env != "" {
 		return filepath.Clean(env)
 	}
+	def := filepath.Clean(runtime.GOROOT())
 	exe, err := os.Executable()
 	if err == nil {
 		exe, err = filepath.Abs(exe)
 		if err == nil {
 			if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
+				// If def (runtime.GOROOT()) and dir are the same
+				// directory, prefer the spelling used in def.
+				if isSameDir(def, dir) {
+					return def
+				}
 				return dir
 			}
 			exe, err = filepath.EvalSymlinks(exe)
 			if err == nil {
 				if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
+					if isSameDir(def, dir) {
+						return def
+					}
 					return dir
 				}
 			}
 		}
 	}
-	return filepath.Clean(runtime.GOROOT())
+	return def
+}
+
+func findGOROOT_FINAL() string {
+	def := GOROOT
+	if env := os.Getenv("GOROOT_FINAL"); env != "" {
+		def = filepath.Clean(env)
+	}
+	return def
+}
+
+// isSameDir reports whether dir1 and dir2 are the same directory.
+func isSameDir(dir1, dir2 string) bool {
+	if dir1 == dir2 {
+		return true
+	}
+	info1, err1 := os.Stat(dir1)
+	info2, err2 := os.Stat(dir2)
+	return err1 == nil && err2 == nil && os.SameFile(info1, info2)
 }
 
 // isGOROOT reports whether path looks like a GOROOT.
diff --git a/src/cmd/go/internal/cfg/zdefaultcc.go b/src/cmd/go/internal/cfg/zdefaultcc.go
index b03042c..28761b7 100644
--- a/src/cmd/go/internal/cfg/zdefaultcc.go
+++ b/src/cmd/go/internal/cfg/zdefaultcc.go
@@ -1,7 +1,15 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package cfg
 
-const DefaultCC = `clang`
-const DefaultCXX = `clang++`
 const DefaultPkgConfig = `pkg-config`
+func DefaultCC(goos, goarch string) string {
+	switch goos+`/`+goarch {
+	}
+	return "clang"
+}
+func DefaultCXX(goos, goarch string) string {
+	switch goos+`/`+goarch {
+	}
+	return "clang++"
+}
diff --git a/src/cmd/go/internal/cfg/zosarch.go b/src/cmd/go/internal/cfg/zosarch.go
index 57231fb..b7cfc7b 100644
--- a/src/cmd/go/internal/cfg/zosarch.go
+++ b/src/cmd/go/internal/cfg/zosarch.go
@@ -1,4 +1,4 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package cfg
 
diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go
index 454cac1..fa5af94 100644
--- a/src/cmd/go/internal/clean/clean.go
+++ b/src/cmd/go/internal/clean/clean.go
@@ -11,16 +11,18 @@
 	"os"
 	"path/filepath"
 	"strings"
+	"time"
 
 	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
 	"cmd/go/internal/work"
 )
 
 var CmdClean = &base.Command{
-	UsageLine: "clean [-i] [-r] [-n] [-x] [build flags] [packages]",
-	Short:     "remove object files",
+	UsageLine: "clean [-i] [-r] [-n] [-x] [-cache] [-testcache] [build flags] [packages]",
+	Short:     "remove object files and cached files",
 	Long: `
 Clean removes object files from package source directories.
 The go command builds most objects in a temporary directory,
@@ -58,14 +60,23 @@
 
 The -x flag causes clean to print remove commands as it executes them.
 
+The -cache flag causes clean to remove the entire go build cache.
+
+The -testcache flag causes clean to expire all test results in the
+go build cache.
+
 For more about build flags, see 'go help build'.
 
 For more about specifying packages, see 'go help packages'.
 	`,
 }
 
-var cleanI bool // clean -i flag
-var cleanR bool // clean -r flag
+var (
+	cleanI         bool // clean -i flag
+	cleanR         bool // clean -r flag
+	cleanCache     bool // clean -cache flag
+	cleanTestcache bool // clean -testcache flag
+)
 
 func init() {
 	// break init cycle
@@ -73,6 +84,9 @@
 
 	CmdClean.Flag.BoolVar(&cleanI, "i", false, "")
 	CmdClean.Flag.BoolVar(&cleanR, "r", false, "")
+	CmdClean.Flag.BoolVar(&cleanCache, "cache", false, "")
+	CmdClean.Flag.BoolVar(&cleanTestcache, "testcache", false, "")
+
 	// -n and -x are important enough to be
 	// mentioned explicitly in the docs but they
 	// are part of the build flags.
@@ -84,6 +98,46 @@
 	for _, pkg := range load.PackagesAndErrors(args) {
 		clean(pkg)
 	}
+
+	if cleanCache {
+		var b work.Builder
+		b.Print = fmt.Print
+		dir := cache.DefaultDir()
+		if dir != "off" {
+			// Remove the cache subdirectories but not the top cache directory.
+			// The top cache directory may have been created with special permissions
+			// and not something that we want to remove. Also, we'd like to preserve
+			// the access log for future analysis, even if the cache is cleared.
+			subdirs, _ := filepath.Glob(filepath.Join(dir, "[0-9a-f][0-9a-f]"))
+			if len(subdirs) > 0 {
+				if cfg.BuildN || cfg.BuildX {
+					b.Showcmd("", "rm -r %s", strings.Join(subdirs, " "))
+				}
+				printedErrors := false
+				for _, d := range subdirs {
+					// Only print the first error - there may be many.
+					// This also mimics what os.RemoveAll(dir) would do.
+					if err := os.RemoveAll(d); err != nil && !printedErrors {
+						printedErrors = true
+						base.Errorf("go clean -cache: %v", err)
+					}
+				}
+			}
+		}
+	}
+
+	if cleanTestcache && !cleanCache {
+		// Instead of walking through the entire cache looking for test results,
+		// we write a file to the cache indicating that all test results from before
+		// right now are to be ignored.
+		dir := cache.DefaultDir()
+		if dir != "off" {
+			err := ioutil.WriteFile(filepath.Join(dir, "testexpire.txt"), []byte(fmt.Sprintf("%d\n", time.Now().UnixNano())), 0666)
+			if err != nil {
+				base.Errorf("go clean -testcache: %v", err)
+			}
+		}
+	}
 }
 
 var cleaned = map[*load.Package]bool{}
@@ -213,12 +267,12 @@
 		}
 	}
 
-	if cleanI && p.Internal.Target != "" {
+	if cleanI && p.Target != "" {
 		if cfg.BuildN || cfg.BuildX {
-			b.Showcmd("", "rm -f %s", p.Internal.Target)
+			b.Showcmd("", "rm -f %s", p.Target)
 		}
 		if !cfg.BuildN {
-			removeFile(p.Internal.Target)
+			removeFile(p.Target)
 		}
 	}
 
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index 43d4334..603f7b5 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -13,6 +13,7 @@
 	"strings"
 
 	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
 	"cmd/go/internal/work"
@@ -31,6 +32,8 @@
 
 The -json flag prints the environment in JSON format
 instead of as a shell script.
+
+For more about environment variables, see 'go help environment'.
 	`,
 }
 
@@ -47,6 +50,7 @@
 	env := []cfg.EnvVar{
 		{Name: "GOARCH", Value: cfg.Goarch},
 		{Name: "GOBIN", Value: cfg.GOBIN},
+		{Name: "GOCACHE", Value: cache.DefaultDir()},
 		{Name: "GOEXE", Value: cfg.ExeSuffix},
 		{Name: "GOHOSTARCH", Value: runtime.GOARCH},
 		{Name: "GOHOSTOS", Value: runtime.GOOS},
@@ -54,6 +58,7 @@
 		{Name: "GOPATH", Value: cfg.BuildContext.GOPATH},
 		{Name: "GORACE", Value: os.Getenv("GORACE")},
 		{Name: "GOROOT", Value: cfg.GOROOT},
+		{Name: "GOTMPDIR", Value: os.Getenv("GOTMPDIR")},
 		{Name: "GOTOOLDIR", Value: base.ToolDir},
 
 		// disable escape codes in clang errors
@@ -71,13 +76,20 @@
 		env = append(env, cfg.EnvVar{Name: "GOARM", Value: cfg.GOARM})
 	case "386":
 		env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386})
+	case "mips", "mipsle":
+		env = append(env, cfg.EnvVar{Name: "GOMIPS", Value: cfg.GOMIPS})
 	}
 
-	cmd := b.GccCmd(".")
-	env = append(env, cfg.EnvVar{Name: "CC", Value: cmd[0]})
-	env = append(env, cfg.EnvVar{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")})
-	cmd = b.GxxCmd(".")
-	env = append(env, cfg.EnvVar{Name: "CXX", Value: cmd[0]})
+	cc := cfg.DefaultCC(cfg.Goos, cfg.Goarch)
+	if env := strings.Fields(os.Getenv("CC")); len(env) > 0 {
+		cc = env[0]
+	}
+	cxx := cfg.DefaultCXX(cfg.Goos, cfg.Goarch)
+	if env := strings.Fields(os.Getenv("CXX")); len(env) > 0 {
+		cxx = env[0]
+	}
+	env = append(env, cfg.EnvVar{Name: "CC", Value: cc})
+	env = append(env, cfg.EnvVar{Name: "CXX", Value: cxx})
 
 	if cfg.BuildContext.CgoEnabled {
 		env = append(env, cfg.EnvVar{Name: "CGO_ENABLED", Value: "1"})
@@ -101,20 +113,51 @@
 func ExtraEnvVars() []cfg.EnvVar {
 	var b work.Builder
 	b.Init()
-	cppflags, cflags, cxxflags, fflags, ldflags := b.CFlags(&load.Package{})
+	cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{})
+	if err != nil {
+		// Should not happen - b.CFlags was given an empty package.
+		fmt.Fprintf(os.Stderr, "go: invalid cflags: %v\n", err)
+		return nil
+	}
+	cmd := b.GccCmd(".", "")
 	return []cfg.EnvVar{
+		// Note: Update the switch in runEnv below when adding to this list.
 		{Name: "CGO_CFLAGS", Value: strings.Join(cflags, " ")},
 		{Name: "CGO_CPPFLAGS", Value: strings.Join(cppflags, " ")},
 		{Name: "CGO_CXXFLAGS", Value: strings.Join(cxxflags, " ")},
 		{Name: "CGO_FFLAGS", Value: strings.Join(fflags, " ")},
 		{Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")},
 		{Name: "PKG_CONFIG", Value: b.PkgconfigCmd()},
+		{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")},
 	}
 }
 
 func runEnv(cmd *base.Command, args []string) {
 	env := cfg.CmdEnv
-	env = append(env, ExtraEnvVars()...)
+
+	// Do we need to call ExtraEnvVars, which is a bit expensive?
+	// Only if we're listing all environment variables ("go env")
+	// or the variables being requested are in the extra list.
+	needExtra := true
+	if len(args) > 0 {
+		needExtra = false
+		for _, arg := range args {
+			switch arg {
+			case "CGO_CFLAGS",
+				"CGO_CPPFLAGS",
+				"CGO_CXXFLAGS",
+				"CGO_FFLAGS",
+				"CGO_LDFLAGS",
+				"PKG_CONFIG",
+				"GOGCCFLAGS":
+				needExtra = true
+			}
+		}
+	}
+	if needExtra {
+		env = append(env, ExtraEnvVars()...)
+	}
+
 	if len(args) > 0 {
 		if *envJson {
 			var es []cfg.EnvVar
diff --git a/src/cmd/go/internal/fix/fix.go b/src/cmd/go/internal/fix/fix.go
index 788d49b..99c7ca5 100644
--- a/src/cmd/go/internal/fix/fix.go
+++ b/src/cmd/go/internal/fix/fix.go
@@ -15,7 +15,7 @@
 var CmdFix = &base.Command{
 	Run:       runFix,
 	UsageLine: "fix [packages]",
-	Short:     "run go tool fix on packages",
+	Short:     "update packages to use new APIs",
 	Long: `
 Fix runs the Go fix command on the packages named by the import paths.
 
@@ -33,7 +33,7 @@
 		// Use pkg.gofiles instead of pkg.Dir so that
 		// the command only applies to this package,
 		// not to packages in subdirectories.
-		files := base.FilterDotUnderscoreFiles(base.RelPaths(pkg.Internal.AllGoFiles))
+		files := base.RelPaths(pkg.InternalAllGoFiles())
 		base.Run(str.StringList(cfg.BuildToolexec, base.Tool("fix"), files))
 	}
 }
diff --git a/src/cmd/go/internal/fmtcmd/fmt.go b/src/cmd/go/internal/fmtcmd/fmt.go
index 0563a04..eb96823 100644
--- a/src/cmd/go/internal/fmtcmd/fmt.go
+++ b/src/cmd/go/internal/fmtcmd/fmt.go
@@ -8,6 +8,9 @@
 import (
 	"os"
 	"path/filepath"
+	"runtime"
+	"strings"
+	"sync"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
@@ -22,7 +25,7 @@
 var CmdFmt = &base.Command{
 	Run:       runFmt,
 	UsageLine: "fmt [-n] [-x] [packages]",
-	Short:     "run gofmt on package sources",
+	Short:     "gofmt (reformat) package sources",
 	Long: `
 Fmt runs the command 'gofmt -l -w' on the packages named
 by the import paths. It prints the names of the files that are modified.
@@ -41,13 +44,38 @@
 
 func runFmt(cmd *base.Command, args []string) {
 	gofmt := gofmtPath()
-	for _, pkg := range load.Packages(args) {
+	procs := runtime.GOMAXPROCS(0)
+	var wg sync.WaitGroup
+	wg.Add(procs)
+	fileC := make(chan string, 2*procs)
+	for i := 0; i < procs; i++ {
+		go func() {
+			defer wg.Done()
+			for file := range fileC {
+				base.Run(str.StringList(gofmt, "-l", "-w", file))
+			}
+		}()
+	}
+	for _, pkg := range load.PackagesAndErrors(args) {
+		if pkg.Error != nil {
+			if strings.HasPrefix(pkg.Error.Err, "build constraints exclude all Go files") {
+				// Skip this error, as we will format
+				// all files regardless.
+			} else {
+				base.Errorf("can't load package: %s", pkg.Error)
+				continue
+			}
+		}
 		// Use pkg.gofiles instead of pkg.Dir so that
 		// the command only applies to this package,
 		// not to packages in subdirectories.
-		files := base.FilterDotUnderscoreFiles(base.RelPaths(pkg.Internal.AllGoFiles))
-		base.Run(str.StringList(gofmt, "-l", "-w", files))
+		files := base.RelPaths(pkg.InternalAllGoFiles())
+		for _, file := range files {
+			fileC <- file
+		}
 	}
+	close(fileC)
+	wg.Wait()
 }
 
 func gofmtPath() string {
diff --git a/src/cmd/go/internal/generate/generate.go b/src/cmd/go/internal/generate/generate.go
index d47c9b7..75c0d3b 100644
--- a/src/cmd/go/internal/generate/generate.go
+++ b/src/cmd/go/internal/generate/generate.go
@@ -153,7 +153,7 @@
 	}
 	// Even if the arguments are .go files, this loop suffices.
 	for _, pkg := range load.Packages(args) {
-		for _, file := range pkg.Internal.GoFiles {
+		for _, file := range pkg.InternalGoFiles() {
 			if !generate(pkg.Name, file) {
 				break
 			}
@@ -385,7 +385,7 @@
 	}
 	command := words[1]
 	if g.commands[command] != nil {
-		g.errorf("command %q defined multiply defined", command)
+		g.errorf("command %q multiply defined", command)
 	}
 	g.commands[command] = words[2:len(words):len(words)] // force later append to make copy
 }
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
index 5503211..733116e 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -22,7 +22,7 @@
 )
 
 var CmdGet = &base.Command{
-	UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
+	UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [-v] [build flags] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads the packages named by the import paths, along with their
@@ -90,8 +90,7 @@
 }
 
 func runGet(cmd *base.Command, args []string) {
-	work.InstrumentInit()
-	work.BuildModeInit()
+	work.BuildInit()
 
 	if *getF && !*getU {
 		base.Fatalf("go get: cannot use -f flag without -u")
@@ -301,7 +300,7 @@
 	// due to wildcard expansion.
 	for _, p := range pkgs {
 		if *getFix {
-			files := base.FilterDotUnderscoreFiles(base.RelPaths(p.Internal.AllGoFiles))
+			files := base.RelPaths(p.InternalAllGoFiles())
 			base.Run(cfg.BuildToolexec, str.StringList(base.Tool("fix"), files))
 
 			// The imports might have changed, so reload again.
@@ -439,6 +438,11 @@
 		p.Internal.Build.PkgRoot = filepath.Join(list[0], "pkg")
 	}
 	root := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath))
+
+	if err := checkNestedVCS(vcs, root, p.Internal.Build.SrcRoot); err != nil {
+		return err
+	}
+
 	// If we've considered this repository already, don't do it again.
 	if downloadRootCache[root] {
 		return nil
@@ -452,12 +456,8 @@
 	// Check that this is an appropriate place for the repo to be checked out.
 	// The target directory must either not exist or have a repo checked out already.
 	meta := filepath.Join(root, "."+vcs.cmd)
-	st, err := os.Stat(meta)
-	if err == nil && !st.IsDir() {
-		return fmt.Errorf("%s exists but is not a directory", meta)
-	}
-	if err != nil {
-		// Metadata directory does not exist. Prepare to checkout new copy.
+	if _, err := os.Stat(meta); err != nil {
+		// Metadata file or directory does not exist. Prepare to checkout new copy.
 		// Some version control tools require the target directory not to exist.
 		// We require that too, just to avoid stepping on existing work.
 		if _, err := os.Stat(root); err == nil {
diff --git a/src/cmd/go/internal/get/vcs.go b/src/cmd/go/internal/get/vcs.go
index 71d0b51..26693b1 100644
--- a/src/cmd/go/internal/get/vcs.go
+++ b/src/cmd/go/internal/get/vcs.go
@@ -93,6 +93,7 @@
 	vcsGit,
 	vcsSvn,
 	vcsBzr,
+	vcsFossil,
 }
 
 // vcsByCmd returns the version control system for the given
@@ -324,6 +325,34 @@
 	return strings.TrimSpace(out), nil
 }
 
+// fossilRepoName is the name go get associates with a fossil repository. In the
+// real world the file can be named anything.
+const fossilRepoName = ".fossil"
+
+// vcsFossil describes how to use Fossil (fossil-scm.org)
+var vcsFossil = &vcsCmd{
+	name: "Fossil",
+	cmd:  "fossil",
+
+	createCmd:   []string{"-go-internal-mkdir {dir} clone {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"},
+	downloadCmd: []string{"up"},
+
+	tagCmd:         []tagCmd{{"tag ls", `(.*)`}},
+	tagSyncCmd:     []string{"up tag:{tag}"},
+	tagSyncDefault: []string{"up trunk"},
+
+	scheme:     []string{"https", "http"},
+	remoteRepo: fossilRemoteRepo,
+}
+
+func fossilRemoteRepo(vcsFossil *vcsCmd, rootDir string) (remoteRepo string, err error) {
+	out, err := vcsFossil.runOutput(rootDir, "remote-url")
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(string(out)), nil
+}
+
 func (v *vcsCmd) String() string {
 	return v.name
 }
@@ -362,6 +391,19 @@
 		args[i] = expand(m, arg)
 	}
 
+	if len(args) >= 2 && args[0] == "-go-internal-mkdir" {
+		var err error
+		if filepath.IsAbs(args[1]) {
+			err = os.Mkdir(args[1], os.ModePerm)
+		} else {
+			err = os.Mkdir(filepath.Join(dir, args[1]), os.ModePerm)
+		}
+		if err != nil {
+			return nil, err
+		}
+		args = args[2:]
+	}
+
 	if len(args) >= 2 && args[0] == "-go-internal-cd" {
 		if filepath.IsAbs(args[1]) {
 			dir = args[1]
@@ -506,11 +548,28 @@
 		return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
 	}
 
+	var vcsRet *vcsCmd
+	var rootRet string
+
 	origDir := dir
 	for len(dir) > len(srcRoot) {
 		for _, vcs := range vcsList {
 			if _, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil {
-				return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil
+				root := filepath.ToSlash(dir[len(srcRoot)+1:])
+				// Record first VCS we find, but keep looking,
+				// to detect mistakes like one kind of VCS inside another.
+				if vcsRet == nil {
+					vcsRet = vcs
+					rootRet = root
+					continue
+				}
+				// Allow .git inside .git, which can arise due to submodules.
+				if vcsRet == vcs && vcs.cmd == "git" {
+					continue
+				}
+				// Otherwise, we have one VCS inside a different VCS.
+				return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s",
+					filepath.Join(srcRoot, rootRet), vcsRet.cmd, filepath.Join(srcRoot, root), vcs.cmd)
 			}
 		}
 
@@ -523,9 +582,48 @@
 		dir = ndir
 	}
 
+	if vcsRet != nil {
+		return vcsRet, rootRet, nil
+	}
+
 	return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
 }
 
+// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS
+// situation for dir, checking parents up until srcRoot.
+func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error {
+	if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
+		return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
+	}
+
+	otherDir := dir
+	for len(otherDir) > len(srcRoot) {
+		for _, otherVCS := range vcsList {
+			if _, err := os.Stat(filepath.Join(otherDir, "."+otherVCS.cmd)); err == nil {
+				// Allow expected vcs in original dir.
+				if otherDir == dir && otherVCS == vcs {
+					continue
+				}
+				// Allow .git inside .git, which can arise due to submodules.
+				if otherVCS == vcs && vcs.cmd == "git" {
+					continue
+				}
+				// Otherwise, we have one VCS inside a different VCS.
+				return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.cmd, otherDir, otherVCS.cmd)
+			}
+		}
+		// Move to parent.
+		newDir := filepath.Dir(otherDir)
+		if len(newDir) >= len(otherDir) {
+			// Shouldn't happen, but just in case, stop.
+			break
+		}
+		otherDir = newDir
+	}
+
+	return nil
+}
+
 // repoRoot represents a version control system, a repo, and a root of
 // where to put it on disk.
 type repoRoot struct {
@@ -872,7 +970,7 @@
 
 	// IBM DevOps Services (JazzHub)
 	{
-		prefix: "hub.jazz.net/git",
+		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}",
@@ -881,7 +979,7 @@
 
 	// Git at Apache
 	{
-		prefix: "git.apache.org",
+		prefix: "git.apache.org/",
 		re:     `^(?P<root>git.apache.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`,
 		vcs:    "git",
 		repo:   "https://{root}",
@@ -889,16 +987,24 @@
 
 	// Git at OpenStack
 	{
-		prefix: "git.openstack.org",
+		prefix: "git.openstack.org/",
 		re:     `^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`,
 		vcs:    "git",
 		repo:   "https://{root}",
 	},
 
+	// chiselapp.com for fossil
+	{
+		prefix: "chiselapp.com/",
+		re:     `^(?P<root>chiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`,
+		vcs:    "fossil",
+		repo:   "https://{root}",
+	},
+
 	// General syntax for any server.
 	// Must be last.
 	{
-		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_.\-]+)*$`,
+		re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?P<vcs>bzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`,
 		ping: true,
 	},
 }
diff --git a/src/cmd/go/internal/get/vcs_test.go b/src/cmd/go/internal/get/vcs_test.go
index 62d352a..e29338a 100644
--- a/src/cmd/go/internal/get/vcs_test.go
+++ b/src/cmd/go/internal/get/vcs_test.go
@@ -154,6 +154,22 @@
 				repo: "https://git.apache.org/package-name_2.x.git",
 			},
 		},
+		{
+			"chiselapp.com/user/kyle/repository/fossilgg",
+			&repoRoot{
+				vcs:  vcsFossil,
+				repo: "https://chiselapp.com/user/kyle/repository/fossilgg",
+			},
+		},
+		{
+			// must have a user/$name/repository/$repo path
+			"chiselapp.com/kyle/repository/fossilgg",
+			nil,
+		},
+		{
+			"chiselapp.com/user/kyle/fossilgg",
+			nil,
+		},
 	}
 
 	for _, test := range tests {
@@ -241,6 +257,8 @@
 		{vcsGit, "example.com:path/to/repo.git", false},
 		{vcsGit, "path/that/contains/a:colon/repo.git", false},
 		{vcsHg, "ssh://user@example.com/path/to/repo.hg", true},
+		{vcsFossil, "http://example.com/foo", false},
+		{vcsFossil, "https://example.com/foo", true},
 	}
 
 	for _, test := range tests {
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index b9349ee..c39af79 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -30,7 +30,7 @@
 
 var HelpPackages = &base.Command{
 	UsageLine: "packages",
-	Short:     "description of package lists",
+	Short:     "package lists",
 	Long: `
 Many commands apply to a set of packages:
 
@@ -471,6 +471,12 @@
 		See https://golang.org/doc/articles/race_detector.html.
 	GOROOT
 		The root of the go tree.
+	GOTMPDIR
+		The directory where the go command will write
+		temporary source files, packages, and binaries.
+	GOCACHE
+		The directory where the go command will store
+		cached information for reuse in future builds.
 
 Environment variables for use with cgo:
 
@@ -481,17 +487,26 @@
 	CGO_CFLAGS
 		Flags that cgo will pass to the compiler when compiling
 		C code.
-	CGO_CPPFLAGS
-		Flags that cgo will pass to the compiler when compiling
-		C or C++ code.
-	CGO_CXXFLAGS
-		Flags that cgo will pass to the compiler when compiling
-		C++ code.
-	CGO_FFLAGS
-		Flags that cgo will pass to the compiler when compiling
-		Fortran code.
-	CGO_LDFLAGS
-		Flags that cgo will pass to the compiler when linking.
+	CGO_CFLAGS_ALLOW
+		A regular expression specifying additional flags to allow
+		to appear in #cgo CFLAGS source code directives.
+		Does not apply to the CGO_CFLAGS environment variable.
+	CGO_CFLAGS_DISALLOW
+		A regular expression specifying flags that must be disallowed
+		from appearing in #cgo CFLAGS source code directives.
+		Does not apply to the CGO_CFLAGS environment variable.
+	CGO_CPPFLAGS, CGO_CPPFLAGS_ALLOW, CGO_CPPFLAGS_DISALLOW
+		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+		but for the C preprocessor.
+	CGO_CXXFLAGS, CGO_CXXFLAGS_ALLOW, CGO_CXXFLAGS_DISALLOW
+		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+		but for the C++ compiler.
+	CGO_FFLAGS, CGO_FFLAGS_ALLOW, CGO_FFLAGS_DISALLOW
+		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+		but for the Fortran compiler.
+	CGO_LDFLAGS, CGO_LDFLAGS_ALLOW, CGO_LDFLAGS_DISALLOW
+		Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW,
+		but for the linker.
 	CXX
 		The command to use to compile C++ code.
 	PKG_CONFIG
@@ -505,6 +520,9 @@
 	GO386
 		For GOARCH=386, the floating point instruction set.
 		Valid values are 387, sse2.
+	GOMIPS
+		For GOARCH=mips{,le}, whether to use floating point instructions.
+		Valid values are hardfloat (default), softfloat.
 
 Special-purpose environment variables:
 
@@ -565,14 +583,16 @@
 comment, indicating that the package sources are included
 for documentation only and must not be used to build the
 package binary. This enables distribution of Go packages in
-their compiled form alone. See the go/build package documentation
-for more details.
+their compiled form alone. Even binary-only packages require
+accurate import blocks listing required dependencies, so that
+those dependencies can be supplied when linking the resulting
+command.
 	`,
 }
 
 var HelpBuildmode = &base.Command{
 	UsageLine: "buildmode",
-	Short:     "description of build modes",
+	Short:     "build modes",
 	Long: `
 The 'go build' and 'go install' commands take a -buildmode argument which
 indicates which kind of object file is to be built. Currently supported values
@@ -618,3 +638,45 @@
 		import, into a Go plugin. Packages not named main are ignored.
 `,
 }
+
+var HelpCache = &base.Command{
+	UsageLine: "cache",
+	Short:     "build and test caching",
+	Long: `
+The go command caches build outputs for reuse in future builds.
+The default location for cache data is a subdirectory named go-build
+in the standard user cache directory for the current operating system.
+Setting the GOCACHE environment variable overrides this default,
+and running 'go env GOCACHE' prints the current cache directory.
+
+The go command periodically deletes cached data that has not been
+used recently. Running 'go clean -cache' deletes all cached data.
+
+The build cache correctly accounts for changes to Go source files,
+compilers, compiler options, and so on: cleaning the cache explicitly
+should not be necessary in typical use. However, the build cache
+does not detect changes to C libraries imported with cgo.
+If you have made changes to the C libraries on your system, you
+will need to clean the cache explicitly or else use the -a build flag
+(see 'go help build') to force rebuilding of packages that
+depend on the updated C libraries.
+
+The go command also caches successful package test results.
+See 'go help test' for details. Running 'go clean -testcache' removes
+all cached test results (but not cached build results).
+
+The GODEBUG environment variable can enable printing of debugging
+information about the state of the cache:
+
+GODEBUG=gocacheverify=1 causes the go command to bypass the
+use of any cache entries and instead rebuild everything and check
+that the results match existing cache entries.
+
+GODEBUG=gocachehash=1 causes the go command to print the inputs
+for all of the content hashes it uses to construct cache lookup keys.
+The output is voluminous but can be useful for debugging the cache.
+
+GODEBUG=gocachetest=1 causes the go command to print details of its
+decisions about whether to reuse a cached test result.
+`,
+}
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 241d089..7435273 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -152,7 +152,7 @@
 var nl = []byte{'\n'}
 
 func runList(cmd *base.Command, args []string) {
-	work.BuildModeInit()
+	work.BuildInit()
 	out := newTrackingWriter(os.Stdout)
 	defer out.w.Flush()
 
@@ -194,12 +194,29 @@
 		}
 	}
 
-	loadpkgs := load.Packages
+	var pkgs []*load.Package
 	if *listE {
-		loadpkgs = load.PackagesAndErrors
+		pkgs = load.PackagesAndErrors(args)
+	} else {
+		pkgs = load.Packages(args)
 	}
 
-	for _, pkg := range loadpkgs(args) {
+	// Estimate whether staleness information is needed,
+	// since it's a little bit of work to compute.
+	needStale := *listJson || strings.Contains(*listFmt, ".Stale")
+	if needStale {
+		var b work.Builder
+		b.Init()
+		b.ComputeStaleOnly = true
+		a := &work.Action{}
+		// TODO: Use pkgsFilter?
+		for _, p := range pkgs {
+			a.Deps = append(a.Deps, b.AutoAction(work.ModeInstall, work.ModeInstall, p))
+		}
+		b.Do(a)
+	}
+
+	for _, pkg := range pkgs {
 		// Show vendor-expanded paths in listing
 		pkg.TestImports = pkg.Vendored(pkg.TestImports)
 		pkg.XTestImports = pkg.Vendored(pkg.XTestImports)
diff --git a/src/cmd/go/internal/load/flag.go b/src/cmd/go/internal/load/flag.go
new file mode 100644
index 0000000..7ad4208
--- /dev/null
+++ b/src/cmd/go/internal/load/flag.go
@@ -0,0 +1,121 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package load
+
+import (
+	"cmd/go/internal/base"
+	"cmd/go/internal/str"
+	"fmt"
+	"strings"
+)
+
+var (
+	BuildAsmflags   PerPackageFlag // -asmflags
+	BuildGcflags    PerPackageFlag // -gcflags
+	BuildLdflags    PerPackageFlag // -ldflags
+	BuildGccgoflags PerPackageFlag // -gccgoflags
+)
+
+// A PerPackageFlag is a command-line flag implementation (a flag.Value)
+// that allows specifying different effective flags for different packages.
+// See 'go help build' for more details about per-package flags.
+type PerPackageFlag struct {
+	present bool
+	values  []ppfValue
+}
+
+// A ppfValue is a single <pattern>=<flags> per-package flag value.
+type ppfValue struct {
+	match func(*Package) bool // compiled pattern
+	flags []string
+}
+
+// Set is called each time the flag is encountered on the command line.
+func (f *PerPackageFlag) Set(v string) error {
+	return f.set(v, base.Cwd)
+}
+
+// set is the implementation of Set, taking a cwd (current working directory) for easier testing.
+func (f *PerPackageFlag) set(v, cwd string) error {
+	f.present = true
+	match := func(p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern
+	// For backwards compatibility with earlier flag splitting, ignore spaces around flags.
+	v = strings.TrimSpace(v)
+	if v == "" {
+		// Special case: -gcflags="" means no flags for command-line arguments
+		// (overrides previous -gcflags="-whatever").
+		f.values = append(f.values, ppfValue{match, []string{}})
+		return nil
+	}
+	if !strings.HasPrefix(v, "-") {
+		i := strings.Index(v, "=")
+		if i < 0 {
+			return fmt.Errorf("missing =<value> in <pattern>=<value>")
+		}
+		if i == 0 {
+			return fmt.Errorf("missing <pattern> in <pattern>=<value>")
+		}
+		pattern := strings.TrimSpace(v[:i])
+		match = MatchPackage(pattern, cwd)
+		v = v[i+1:]
+	}
+	flags, err := str.SplitQuotedFields(v)
+	if err != nil {
+		return err
+	}
+	if flags == nil {
+		flags = []string{}
+	}
+	f.values = append(f.values, ppfValue{match, flags})
+	return nil
+}
+
+// String is required to implement flag.Value.
+// It is not used, because cmd/go never calls flag.PrintDefaults.
+func (f *PerPackageFlag) String() string { return "<PerPackageFlag>" }
+
+// Present reports whether the flag appeared on the command line.
+func (f *PerPackageFlag) Present() bool {
+	return f.present
+}
+
+// For returns the flags to use for the given package.
+func (f *PerPackageFlag) For(p *Package) []string {
+	flags := []string{}
+	for _, v := range f.values {
+		if v.match(p) {
+			flags = v.flags
+		}
+	}
+	return flags
+}
+
+var cmdlineMatchers []func(*Package) bool
+
+// SetCmdlinePatterns records the set of patterns given on the command line,
+// for use by the PerPackageFlags.
+func SetCmdlinePatterns(args []string) {
+	setCmdlinePatterns(args, base.Cwd)
+}
+
+func setCmdlinePatterns(args []string, cwd string) {
+	if len(args) == 0 {
+		args = []string{"."}
+	}
+	cmdlineMatchers = nil // allow reset for testing
+	for _, arg := range args {
+		cmdlineMatchers = append(cmdlineMatchers, MatchPackage(arg, cwd))
+	}
+}
+
+// isCmdlinePkg reports whether p is a package listed on the command line.
+func isCmdlinePkg(p *Package) bool {
+	for _, m := range cmdlineMatchers {
+		if m(p) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/cmd/go/internal/load/flag_test.go b/src/cmd/go/internal/load/flag_test.go
new file mode 100644
index 0000000..d3223e1
--- /dev/null
+++ b/src/cmd/go/internal/load/flag_test.go
@@ -0,0 +1,135 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package load
+
+import (
+	"fmt"
+	"path/filepath"
+	"reflect"
+	"testing"
+)
+
+type ppfTestPackage struct {
+	path    string
+	dir     string
+	cmdline bool
+	flags   []string
+}
+
+type ppfTest struct {
+	args []string
+	pkgs []ppfTestPackage
+}
+
+var ppfTests = []ppfTest{
+	// -gcflags=-S applies only to packages on command line.
+	{
+		args: []string{"-S"},
+		pkgs: []ppfTestPackage{
+			{cmdline: true, flags: []string{"-S"}},
+			{cmdline: false, flags: []string{}},
+		},
+	},
+
+	// -gcflags=-S -gcflags= overrides the earlier -S.
+	{
+		args: []string{"-S", ""},
+		pkgs: []ppfTestPackage{
+			{cmdline: true, flags: []string{}},
+		},
+	},
+
+	// -gcflags=net=-S applies only to package net
+	{
+		args: []string{"net=-S"},
+		pkgs: []ppfTestPackage{
+			{path: "math", cmdline: true, flags: []string{}},
+			{path: "net", flags: []string{"-S"}},
+		},
+	},
+
+	// -gcflags=net=-S -gcflags=net= also overrides the earlier -S
+	{
+		args: []string{"net=-S", "net="},
+		pkgs: []ppfTestPackage{
+			{path: "net", flags: []string{}},
+		},
+	},
+
+	// -gcflags=net/...=-S net math
+	// applies -S to net and net/http but not math
+	{
+		args: []string{"net/...=-S"},
+		pkgs: []ppfTestPackage{
+			{path: "net", flags: []string{"-S"}},
+			{path: "net/http", flags: []string{"-S"}},
+			{path: "math", flags: []string{}},
+		},
+	},
+
+	// -gcflags=net/...=-S -gcflags=-m net math
+	// applies -m to net and math and -S to other packages matching net/...
+	// (net matches too, but it was grabbed by the later -gcflags).
+	{
+		args: []string{"net/...=-S", "-m"},
+		pkgs: []ppfTestPackage{
+			{path: "net", cmdline: true, flags: []string{"-m"}},
+			{path: "math", cmdline: true, flags: []string{"-m"}},
+			{path: "net", cmdline: false, flags: []string{"-S"}},
+			{path: "net/http", flags: []string{"-S"}},
+			{path: "math", flags: []string{}},
+		},
+	},
+
+	// relative path patterns
+	// ppfDirTest(pattern, n, dirs...) says the first n dirs should match and the others should not.
+	ppfDirTest(".", 1, "/my/test/dir", "/my/test", "/my/test/other", "/my/test/dir/sub"),
+	ppfDirTest("..", 1, "/my/test", "/my/test/dir", "/my/test/other", "/my/test/dir/sub"),
+	ppfDirTest("./sub", 1, "/my/test/dir/sub", "/my/test", "/my/test/dir", "/my/test/other", "/my/test/dir/sub/sub"),
+	ppfDirTest("../other", 1, "/my/test/other", "/my/test", "/my/test/dir", "/my/test/other/sub", "/my/test/dir/other", "/my/test/dir/sub"),
+	ppfDirTest("./...", 3, "/my/test/dir", "/my/test/dir/sub", "/my/test/dir/sub/sub", "/my/test/other", "/my/test/other/sub"),
+	ppfDirTest("../...", 4, "/my/test/dir", "/my/test/other", "/my/test/dir/sub", "/my/test/other/sub", "/my/other/test"),
+	ppfDirTest("../...sub...", 3, "/my/test/dir/sub", "/my/test/othersub", "/my/test/yellowsubmarine", "/my/other/test"),
+}
+
+func ppfDirTest(pattern string, nmatch int, dirs ...string) ppfTest {
+	var pkgs []ppfTestPackage
+	for i, d := range dirs {
+		flags := []string{}
+		if i < nmatch {
+			flags = []string{"-S"}
+		}
+		pkgs = append(pkgs, ppfTestPackage{path: "p", dir: d, flags: flags})
+	}
+	return ppfTest{args: []string{pattern + "=-S"}, pkgs: pkgs}
+}
+
+func TestPerPackageFlag(t *testing.T) {
+	nativeDir := func(d string) string {
+		if filepath.Separator == '\\' {
+			return `C:` + filepath.FromSlash(d)
+		}
+		return d
+	}
+
+	for i, tt := range ppfTests {
+		t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
+			ppFlags := new(PerPackageFlag)
+			for _, arg := range tt.args {
+				t.Logf("set(%s)", arg)
+				if err := ppFlags.set(arg, nativeDir("/my/test/dir")); err != nil {
+					t.Fatal(err)
+				}
+			}
+			for _, p := range tt.pkgs {
+				dir := nativeDir(p.dir)
+				flags := ppFlags.For(&Package{PackagePublic: PackagePublic{ImportPath: p.path, Dir: dir}, Internal: PackageInternal{CmdlinePkg: p.cmdline}})
+				if !reflect.DeepEqual(flags, p.flags) {
+					t.Errorf("For(%v, %v, %v) = %v, want %v", p.path, dir, p.cmdline, flags, p.flags)
+				}
+			}
+		})
+	}
+}
diff --git a/src/cmd/go/internal/load/icfg.go b/src/cmd/go/internal/load/icfg.go
new file mode 100644
index 0000000..d8dd664
--- /dev/null
+++ b/src/cmd/go/internal/load/icfg.go
@@ -0,0 +1,78 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package load
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"io/ioutil"
+)
+
+// DebugDeprecatedImportcfg is installed as the undocumented -debug-deprecated-importcfg build flag.
+// It is useful for debugging subtle problems in the go command logic but not something
+// we want users to depend on. The hope is that the "deprecated" will make that clear.
+// We intend to remove this flag in Go 1.11.
+var DebugDeprecatedImportcfg debugDeprecatedImportcfgFlag
+
+type debugDeprecatedImportcfgFlag struct {
+	enabled bool
+	Import  map[string]string
+	Pkg     map[string]*debugDeprecatedImportcfgPkg
+}
+
+type debugDeprecatedImportcfgPkg struct {
+	Dir    string
+	Import map[string]string
+}
+
+var (
+	debugDeprecatedImportcfgMagic = []byte("# debug-deprecated-importcfg\n")
+	errImportcfgSyntax            = errors.New("malformed syntax")
+)
+
+func (f *debugDeprecatedImportcfgFlag) String() string { return "" }
+
+func (f *debugDeprecatedImportcfgFlag) Set(x string) error {
+	if x == "" {
+		*f = debugDeprecatedImportcfgFlag{}
+		return nil
+	}
+	data, err := ioutil.ReadFile(x)
+	if err != nil {
+		return err
+	}
+
+	if !bytes.HasPrefix(data, debugDeprecatedImportcfgMagic) {
+		return errImportcfgSyntax
+	}
+	data = data[len(debugDeprecatedImportcfgMagic):]
+
+	f.Import = nil
+	f.Pkg = nil
+	if err := json.Unmarshal(data, &f); err != nil {
+		return errImportcfgSyntax
+	}
+	f.enabled = true
+	return nil
+}
+
+func (f *debugDeprecatedImportcfgFlag) lookup(parent *Package, path string) (dir, newPath string) {
+	newPath = path
+	if p := f.Import[path]; p != "" {
+		newPath = p
+	}
+	if parent != nil {
+		if p1 := f.Pkg[parent.ImportPath]; p1 != nil {
+			if p := p1.Import[path]; p != "" {
+				newPath = p
+			}
+		}
+	}
+	if p2 := f.Pkg[newPath]; p2 != nil {
+		return p2.Dir, newPath
+	}
+	return "", ""
+}
diff --git a/src/cmd/go/internal/load/path.go b/src/cmd/go/internal/load/path.go
index 9cc85dd..45a9e7b 100644
--- a/src/cmd/go/internal/load/path.go
+++ b/src/cmd/go/internal/load/path.go
@@ -56,25 +56,3 @@
 	}
 	return p
 }
-
-// hasFilePathPrefix reports whether the filesystem path s begins with the
-// elements in prefix.
-func hasFilePathPrefix(s, prefix string) bool {
-	sv := strings.ToUpper(filepath.VolumeName(s))
-	pv := strings.ToUpper(filepath.VolumeName(prefix))
-	s = s[len(sv):]
-	prefix = prefix[len(pv):]
-	switch {
-	default:
-		return false
-	case sv != pv:
-		return false
-	case len(s) == len(prefix):
-		return s == prefix
-	case len(s) > len(prefix):
-		if prefix != "" && prefix[len(prefix)-1] == filepath.Separator {
-			return strings.HasPrefix(s, prefix)
-		}
-		return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix
-	}
-}
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 60de666..b006d41 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -6,7 +6,6 @@
 package load
 
 import (
-	"crypto/sha1"
 	"fmt"
 	"go/build"
 	"go/token"
@@ -14,13 +13,12 @@
 	"os"
 	pathpkg "path"
 	"path/filepath"
-	"runtime"
 	"sort"
 	"strings"
 	"unicode"
+	"unicode/utf8"
 
 	"cmd/go/internal/base"
-	"cmd/go/internal/buildid"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/str"
 )
@@ -42,17 +40,23 @@
 	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
+	Target        string `json:",omitempty"` // installed target for this package (may be executable)
 	Shlib         string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
 	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?
-	StaleReason   string `json:",omitempty"` // why is Stale true?
 	Root          string `json:",omitempty"` // Go root or Go path dir containing this package
 	ConflictDir   string `json:",omitempty"` // Dir is hidden by this other directory
 	BinaryOnly    bool   `json:",omitempty"` // package cannot be recompiled
 
+	// Stale and StaleReason remain here *only* for the list command.
+	// They are only initialized in preparation for list execution.
+	// The regular build determines staleness on the fly during action execution.
+	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
+	StaleReason string `json:",omitempty"` // why is Stale true?
+
 	// Source files
+	// If you add to this list you MUST add to p.AllFiles (below) too.
+	// Otherwise file name security lists will not apply to any new additions.
 	GoFiles        []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
 	CgoFiles       []string `json:",omitempty"` // .go sources files that import "C"
 	IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
@@ -84,34 +88,58 @@
 	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
 
 	// Test information
+	// If you add to this list you MUST add to p.AllFiles (below) too.
+	// Otherwise file name security lists will not apply to any new additions.
 	TestGoFiles  []string `json:",omitempty"` // _test.go files in package
 	TestImports  []string `json:",omitempty"` // imports from TestGoFiles
 	XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
 	XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
 }
 
+// AllFiles returns the names of all the files considered for the package.
+// This is used for sanity and security checks, so we include all files,
+// even IgnoredGoFiles, because some subcommands consider them.
+// The go/build package filtered others out (like foo_wrongGOARCH.s)
+// and that's OK.
+func (p *Package) AllFiles() []string {
+	return str.StringList(
+		p.GoFiles,
+		p.CgoFiles,
+		p.IgnoredGoFiles,
+		p.CFiles,
+		p.CXXFiles,
+		p.MFiles,
+		p.HFiles,
+		p.FFiles,
+		p.SFiles,
+		p.SwigFiles,
+		p.SwigCXXFiles,
+		p.SysoFiles,
+		p.TestGoFiles,
+		p.XTestGoFiles,
+	)
+}
+
 type PackageInternal struct {
 	// Unexported fields are not part of the public API.
 	Build        *build.Package
-	Pkgdir       string // overrides build.PkgDir
-	Imports      []*Package
-	Deps         []*Package
-	GoFiles      []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
-	SFiles       []string
-	AllGoFiles   []string             // gofiles + IgnoredGoFiles, absolute paths
-	Target       string               // installed file for this package (may be executable)
-	Fake         bool                 // synthesized package
-	External     bool                 // synthesized external test package
+	Imports      []*Package           // this package's direct imports
+	RawImports   []string             // this package's original imports as they appear in the text of the program
 	ForceLibrary bool                 // this package is a library (even if named "main")
-	Cmdline      bool                 // defined by files listed on command line
+	CmdlineFiles bool                 // package built from files listed on command line
+	CmdlinePkg   bool                 // package listed on command line
 	Local        bool                 // imported via local path (./ or ../)
 	LocalPrefix  string               // interpret ./ and ../ imports relative to this prefix
 	ExeName      string               // desired name for temporary executable
 	CoverMode    string               // preprocess Go source files with the coverage tool in this mode
 	CoverVars    map[string]*CoverVar // variables created by coverage analysis
 	OmitDebug    bool                 // tell linker not to write debug information
-	BuildID      string               // expected build ID for generated package
 	GobinSubdir  bool                 // install target would be subdir of GOBIN
+
+	Asmflags   []string // -asmflags for this package
+	Gcflags    []string // -gcflags for this package
+	Ldflags    []string // -ldflags for this package
+	Gccgoflags []string // -gccgoflags for this package
 }
 
 type NoGoError struct {
@@ -216,6 +244,7 @@
 	// We modify p.Imports in place, so make copy now.
 	p.Imports = make([]string, len(pp.Imports))
 	copy(p.Imports, pp.Imports)
+	p.Internal.RawImports = pp.Imports
 	p.TestGoFiles = pp.TestGoFiles
 	p.TestImports = pp.TestImports
 	p.XTestGoFiles = pp.XTestGoFiles
@@ -351,7 +380,7 @@
 
 // Mode flags for loadImport and download (in get.go).
 const (
-	// useVendor means that loadImport should do vendor expansion
+	// UseVendor means that loadImport should do vendor expansion
 	// (provided the vendoring experiment is enabled).
 	// That is, useVendor means that the import path came from
 	// a source file and has not been vendor-expanded yet.
@@ -362,12 +391,12 @@
 	// disallowVendor will reject direct use of paths containing /vendor/.
 	UseVendor = 1 << iota
 
-	// getTestDeps is for download (part of "go get") and indicates
+	// GetTestDeps is for download (part of "go get") and indicates
 	// that test dependencies should be fetched too.
 	GetTestDeps
 )
 
-// loadImport scans the directory named by path, which must be an import path,
+// LoadImport scans the directory named by path, which must be an import path,
 // but possibly a local import path (an absolute file system path or one beginning
 // with ./ or ../). A local relative path is interpreted relative to srcDir.
 // It returns a *Package describing the package found in that directory.
@@ -383,8 +412,14 @@
 	importPath := path
 	origPath := path
 	isLocal := build.IsLocalImport(path)
+	var debugDeprecatedImportcfgDir string
 	if isLocal {
 		importPath = dirToImportPath(filepath.Join(srcDir, path))
+	} else if DebugDeprecatedImportcfg.enabled {
+		if d, i := DebugDeprecatedImportcfg.lookup(parent, path); d != "" {
+			debugDeprecatedImportcfgDir = d
+			importPath = i
+		}
 	} else if mode&UseVendor != 0 {
 		// We do our own vendor resolution, because we want to
 		// find out the key to use in packageCache without the
@@ -406,20 +441,26 @@
 		// Load package.
 		// Import always returns bp != nil, even if an error occurs,
 		// in order to return partial information.
-		//
-		// TODO: After Go 1, decide when to pass build.AllowBinary here.
-		// See issue 3268 for mistakes to avoid.
-		buildMode := build.ImportComment
-		if mode&UseVendor == 0 || path != origPath {
-			// Not vendoring, or we already found the vendored path.
-			buildMode |= build.IgnoreVendor
+		var bp *build.Package
+		var err error
+		if debugDeprecatedImportcfgDir != "" {
+			bp, err = cfg.BuildContext.ImportDir(debugDeprecatedImportcfgDir, 0)
+		} else if DebugDeprecatedImportcfg.enabled {
+			bp = new(build.Package)
+			err = fmt.Errorf("unknown import path %q: not in import cfg", importPath)
+		} else {
+			buildMode := build.ImportComment
+			if mode&UseVendor == 0 || path != origPath {
+				// Not vendoring, or we already found the vendored path.
+				buildMode |= build.IgnoreVendor
+			}
+			bp, err = cfg.BuildContext.Import(path, srcDir, buildMode)
 		}
-		bp, err := cfg.BuildContext.Import(path, srcDir, buildMode)
 		bp.ImportPath = importPath
 		if cfg.GOBIN != "" {
 			bp.BinDir = cfg.GOBIN
 		}
-		if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
+		if debugDeprecatedImportcfgDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
 			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
 			err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
 		}
@@ -428,7 +469,7 @@
 			p = setErrorPos(p, importPos)
 		}
 
-		if origPath != cleanImport(origPath) {
+		if debugDeprecatedImportcfgDir == "" && origPath != cleanImport(origPath) {
 			p.Error = &PackageError{
 				ImportStack: stk.Copy(),
 				Err:         fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)),
@@ -505,19 +546,26 @@
 // x/vendor/path, vendor/path, or else stay path if none of those exist.
 // VendoredImportPath returns the expanded path or, if no expansion is found, the original.
 func VendoredImportPath(parent *Package, path string) (found string) {
+	if DebugDeprecatedImportcfg.enabled {
+		if d, i := DebugDeprecatedImportcfg.lookup(parent, path); d != "" {
+			return i
+		}
+		return path
+	}
+
 	if parent == nil || parent.Root == "" {
 		return path
 	}
 
 	dir := filepath.Clean(parent.Dir)
 	root := filepath.Join(parent.Root, "src")
-	if !hasFilePathPrefix(dir, root) || parent.ImportPath != "command-line-arguments" && filepath.Join(root, parent.ImportPath) != dir {
+	if !str.HasFilePathPrefix(dir, root) || parent.ImportPath != "command-line-arguments" && filepath.Join(root, parent.ImportPath) != dir {
 		// Look for symlinks before reporting error.
 		dir = expandPath(dir)
 		root = expandPath(root)
 	}
 
-	if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || parent.ImportPath != "command-line-arguments" && !parent.Internal.Local && filepath.Join(root, parent.ImportPath) != dir {
+	if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || parent.ImportPath != "command-line-arguments" && !parent.Internal.Local && filepath.Join(root, parent.ImportPath) != dir {
 		base.Fatalf("unexpected directory layout:\n"+
 			"	import path: %s\n"+
 			"	root: %s\n"+
@@ -661,14 +709,14 @@
 		i-- // rewind over slash in ".../internal"
 	}
 	parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
-	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
 		return p
 	}
 
 	// Look for symlinks before reporting error.
 	srcDir = expandPath(srcDir)
 	parent = expandPath(parent)
-	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
 		return p
 	}
 
@@ -761,14 +809,14 @@
 		return p
 	}
 	parent := p.Dir[:truncateTo]
-	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
 		return p
 	}
 
 	// Look for symlinks before reporting error.
 	srcDir = expandPath(srcDir)
 	parent = expandPath(parent)
-	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
 		return p
 	}
 
@@ -803,45 +851,27 @@
 	return 0, false
 }
 
-type targetDir int
+type TargetDir int
 
 const (
-	ToRoot    targetDir = iota // to bin dir inside package root (default)
-	ToTool                     // GOROOT/pkg/tool
-	StalePath                  // the old import path; fail to build
+	ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
+	ToBin                      // to bin dir inside package root (default for non-cmd/*)
+	StalePath                  // an old import path; fail to build
 )
 
-// goTools is a map of Go program import path to install target directory.
-var GoTools = map[string]targetDir{
-	"cmd/addr2line": ToTool,
-	"cmd/api":       ToTool,
-	"cmd/asm":       ToTool,
-	"cmd/compile":   ToTool,
-	"cmd/cgo":       ToTool,
-	"cmd/cover":     ToTool,
-	"cmd/dist":      ToTool,
-	"cmd/doc":       ToTool,
-	"cmd/fix":       ToTool,
-	"cmd/link":      ToTool,
-	"cmd/newlink":   ToTool,
-	"cmd/nm":        ToTool,
-	"cmd/objdump":   ToTool,
-	"cmd/pack":      ToTool,
-	"cmd/pprof":     ToTool,
-	"cmd/trace":     ToTool,
-	"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,
-}
-
-var raceExclude = map[string]bool{
-	"runtime/race": true,
-	"runtime/msan": true,
-	"runtime/cgo":  true,
-	"cmd/cgo":      true,
-	"syscall":      true,
-	"errors":       true,
+// InstallTargetDir reports the target directory for installing the command p.
+func InstallTargetDir(p *Package) TargetDir {
+	if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
+		return StalePath
+	}
+	if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
+		switch p.ImportPath {
+		case "cmd/go", "cmd/gofmt":
+			return ToBin
+		}
+		return ToTool
+	}
+	return ToBin
 }
 
 var cgoExclude = map[string]bool{
@@ -858,12 +888,34 @@
 
 // load populates p using information from bp, err, which should
 // be the result of calling build.Context.Import.
-func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package {
+func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
 	p.copyBuild(bp)
 
+	// Decide whether p was listed on the command line.
+	// Given that load is called while processing the command line,
+	// you might think we could simply pass a flag down into load
+	// saying whether we are loading something named on the command
+	// line or something to satisfy an import. But the first load of a
+	// package named on the command line may be as a dependency
+	// of an earlier package named on the command line, not when we
+	// get to that package during command line processing.
+	// For example "go test fmt reflect" will load reflect as a dependency
+	// of fmt before it attempts to load as a command-line argument.
+	// Because loads are cached, the later load will be a no-op,
+	// so it is important that the first load can fill in CmdlinePkg correctly.
+	// Hence the call to an explicit matching check here.
+	p.Internal.CmdlinePkg = isCmdlinePkg(p)
+
+	p.Internal.Asmflags = BuildAsmflags.For(p)
+	p.Internal.Gcflags = BuildGcflags.For(p)
+	p.Internal.Ldflags = BuildLdflags.For(p)
+	p.Internal.Gccgoflags = BuildGccgoflags.For(p)
+
 	// The localPrefix is the path we interpret ./ imports relative to.
 	// Synthesized main packages sometimes override this.
-	p.Internal.LocalPrefix = dirToImportPath(p.Dir)
+	if p.Internal.Local {
+		p.Internal.LocalPrefix = dirToImportPath(p.Dir)
+	}
 
 	if err != nil {
 		if _, ok := err.(*build.NoGoError); ok {
@@ -875,7 +927,7 @@
 			ImportStack: stk.Copy(),
 			Err:         err.Error(),
 		}
-		return p
+		return
 	}
 
 	useBindir := p.Name == "main"
@@ -888,11 +940,11 @@
 
 	if useBindir {
 		// Report an error when the old code.google.com/p/go.tools paths are used.
-		if GoTools[p.ImportPath] == StalePath {
+		if InstallTargetDir(p) == 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
+			return
 		}
 		_, elem := filepath.Split(p.Dir)
 		full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
@@ -902,167 +954,130 @@
 		}
 		if p.Internal.Build.BinDir != "" {
 			// Install to GOBIN or bin of GOPATH entry.
-			p.Internal.Target = filepath.Join(p.Internal.Build.BinDir, elem)
+			p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
 			if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
 				// Do not create $GOBIN/goos_goarch/elem.
-				p.Internal.Target = ""
+				p.Target = ""
 				p.Internal.GobinSubdir = true
 			}
 		}
-		if GoTools[p.ImportPath] == ToTool {
+		if InstallTargetDir(p) == ToTool {
 			// This is for 'go tool'.
 			// Override all the usual logic and force it into the tool directory.
-			p.Internal.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
+			p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
 		}
-		if p.Internal.Target != "" && cfg.BuildContext.GOOS == "windows" {
-			p.Internal.Target += ".exe"
+		if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
+			p.Target += ".exe"
 		}
 	} else if p.Internal.Local {
 		// Local import turned into absolute path.
 		// No permanent install target.
-		p.Internal.Target = ""
+		p.Target = ""
 	} else {
-		p.Internal.Target = p.Internal.Build.PkgObj
+		p.Target = p.Internal.Build.PkgObj
 		if cfg.BuildLinkshared {
-			shlibnamefile := p.Internal.Target[:len(p.Internal.Target)-2] + ".shlibname"
+			shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
 			shlib, err := ioutil.ReadFile(shlibnamefile)
+			if err != nil && !os.IsNotExist(err) {
+				base.Fatalf("reading shlibname: %v", err)
+			}
 			if err == nil {
 				libname := strings.TrimSpace(string(shlib))
 				if cfg.BuildContext.Compiler == "gccgo" {
 					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
 				} else {
 					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
-
 				}
-			} else if !os.IsNotExist(err) {
-				base.Fatalf("unexpected error reading %s: %v", shlibnamefile, err)
 			}
 		}
 	}
 
-	ImportPaths := p.Imports
-	// Packages that use cgo import runtime/cgo implicitly.
-	// Packages that use cgo also import syscall implicitly,
-	// to wrap errno.
-	// Exclude certain packages to avoid circular dependencies.
-	if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) {
-		ImportPaths = append(ImportPaths, "runtime/cgo")
-	}
-	if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
-		ImportPaths = append(ImportPaths, "syscall")
-	}
-
-	if cfg.BuildContext.CgoEnabled && p.Name == "main" && !p.Goroot {
-		// Currently build modes c-shared, pie (on systems that do not
-		// support PIE with internal linking mode), plugin, and
-		// -linkshared force external linking mode, as of course does
-		// -ldflags=-linkmode=external. External linking mode forces
-		// an import of runtime/cgo.
-		pieCgo := cfg.BuildBuildmode == "pie" && (cfg.BuildContext.GOOS != "linux" || cfg.BuildContext.GOARCH != "amd64")
-		linkmodeExternal := false
-		for i, a := range cfg.BuildLdflags {
-			if a == "-linkmode=external" {
-				linkmodeExternal = true
-			}
-			if a == "-linkmode" && i+1 < len(cfg.BuildLdflags) && cfg.BuildLdflags[i+1] == "external" {
-				linkmodeExternal = true
+	// Build augmented import list to add implicit dependencies.
+	// Be careful not to add imports twice, just to avoid confusion.
+	importPaths := p.Imports
+	addImport := func(path string) {
+		for _, p := range importPaths {
+			if path == p {
+				return
 			}
 		}
-		if cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal {
-			ImportPaths = append(ImportPaths, "runtime/cgo")
+		importPaths = append(importPaths, path)
+	}
+
+	// Cgo translation adds imports of "runtime/cgo" and "syscall",
+	// except for certain packages, to avoid circular dependencies.
+	if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) {
+		addImport("runtime/cgo")
+	}
+	if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
+		addImport("syscall")
+	}
+
+	// SWIG adds imports of some standard packages.
+	if p.UsesSwig() {
+		addImport("runtime/cgo")
+		addImport("syscall")
+		addImport("sync")
+
+		// TODO: The .swig and .swigcxx files can use
+		// %go_import directives to import other packages.
+	}
+
+	// The linker loads implicit dependencies.
+	if p.Name == "main" && !p.Internal.ForceLibrary {
+		for _, dep := range LinkerDeps(p) {
+			addImport(dep)
 		}
 	}
 
-	// Everything depends on runtime, except runtime, its internal
-	// subpackages, and unsafe.
-	if !p.Standard || (p.ImportPath != "runtime" && !strings.HasPrefix(p.ImportPath, "runtime/internal/") && p.ImportPath != "unsafe") {
-		ImportPaths = append(ImportPaths, "runtime")
-		// When race detection enabled everything depends on runtime/race.
-		// Exclude certain packages to avoid circular dependencies.
-		if cfg.BuildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
-			ImportPaths = append(ImportPaths, "runtime/race")
-		}
-		// MSan uses runtime/msan.
-		if cfg.BuildMSan && (!p.Standard || !raceExclude[p.ImportPath]) {
-			ImportPaths = append(ImportPaths, "runtime/msan")
-		}
-		// On ARM with GOARM=5, everything depends on math for the link.
-		if p.Name == "main" && cfg.Goarch == "arm" {
-			ImportPaths = append(ImportPaths, "math")
-		}
-	}
-
-	// Runtime and its internal packages depend on runtime/internal/sys,
-	// so that they pick up the generated zversion.go file.
-	// This can be an issue particularly for runtime/internal/atomic;
-	// see issue 13655.
-	if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal/")) && p.ImportPath != "runtime/internal/sys" {
-		ImportPaths = append(ImportPaths, "runtime/internal/sys")
-	}
-
-	// Build list of full paths to all Go files in the package,
-	// for use by commands like go fmt.
-	p.Internal.GoFiles = str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)
-	for i := range p.Internal.GoFiles {
-		p.Internal.GoFiles[i] = filepath.Join(p.Dir, p.Internal.GoFiles[i])
-	}
-	sort.Strings(p.Internal.GoFiles)
-
-	p.Internal.SFiles = str.StringList(p.SFiles)
-	for i := range p.Internal.SFiles {
-		p.Internal.SFiles[i] = filepath.Join(p.Dir, p.Internal.SFiles[i])
-	}
-	sort.Strings(p.Internal.SFiles)
-
-	p.Internal.AllGoFiles = str.StringList(p.IgnoredGoFiles)
-	for i := range p.Internal.AllGoFiles {
-		p.Internal.AllGoFiles[i] = filepath.Join(p.Dir, p.Internal.AllGoFiles[i])
-	}
-	p.Internal.AllGoFiles = append(p.Internal.AllGoFiles, p.Internal.GoFiles...)
-	sort.Strings(p.Internal.AllGoFiles)
-
 	// Check for case-insensitive collision of input files.
 	// To avoid problems on case-insensitive files, we reject any package
 	// where two different input files have equal names under a case-insensitive
 	// comparison.
-	f1, f2 := str.FoldDup(str.StringList(
-		p.GoFiles,
-		p.CgoFiles,
-		p.IgnoredGoFiles,
-		p.CFiles,
-		p.CXXFiles,
-		p.MFiles,
-		p.HFiles,
-		p.FFiles,
-		p.SFiles,
-		p.SysoFiles,
-		p.SwigFiles,
-		p.SwigCXXFiles,
-		p.TestGoFiles,
-		p.XTestGoFiles,
-	))
+	inputs := p.AllFiles()
+	f1, f2 := str.FoldDup(inputs)
 	if f1 != "" {
 		p.Error = &PackageError{
 			ImportStack: stk.Copy(),
 			Err:         fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2),
 		}
-		return p
+		return
+	}
+
+	// If first letter of input file is ASCII, it must be alphanumeric.
+	// This avoids files turning into flags when invoking commands,
+	// and other problems we haven't thought of yet.
+	// Also, _cgo_ files must be generated by us, not supplied.
+	// They are allowed to have //go:cgo_ldflag directives.
+	// The directory scan ignores files beginning with _,
+	// so we shouldn't see any _cgo_ files anyway, but just be safe.
+	for _, file := range inputs {
+		if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
+			p.Error = &PackageError{
+				ImportStack: stk.Copy(),
+				Err:         fmt.Sprintf("invalid input file name %q", file),
+			}
+			return
+		}
+	}
+	if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
+		p.Error = &PackageError{
+			ImportStack: stk.Copy(),
+			Err:         fmt.Sprintf("invalid input directory name %q", name),
+		}
+		return
+	}
+	if !SafeArg(p.ImportPath) {
+		p.Error = &PackageError{
+			ImportStack: stk.Copy(),
+			Err:         fmt.Sprintf("invalid import path %q", p.ImportPath),
+		}
+		return
 	}
 
 	// Build list of imported packages and full dependency list.
 	imports := make([]*Package, 0, len(p.Imports))
-	deps := make(map[string]*Package)
-	save := func(path string, p1 *Package) {
-		// The same import path could produce an error or not,
-		// depending on what tries to import it.
-		// Prefer to record entries with errors, so we can report them.
-		p0 := deps[path]
-		if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
-			deps[path] = p1
-		}
-	}
-
-	for i, path := range ImportPaths {
+	for i, path := range importPaths {
 		if path == "C" {
 			continue
 		}
@@ -1079,22 +1094,38 @@
 		}
 
 		path = p1.ImportPath
-		ImportPaths[i] = path
+		importPaths[i] = path
 		if i < len(p.Imports) {
 			p.Imports[i] = path
 		}
 
-		save(path, p1)
 		imports = append(imports, p1)
-		for _, dep := range p1.Internal.Deps {
-			save(dep.ImportPath, dep)
-		}
 		if p1.Incomplete {
 			p.Incomplete = true
 		}
 	}
 	p.Internal.Imports = imports
 
+	deps := make(map[string]*Package)
+	var q []*Package
+	q = append(q, imports...)
+	for i := 0; i < len(q); i++ {
+		p1 := q[i]
+		path := p1.ImportPath
+		// The same import path could produce an error or not,
+		// depending on what tries to import it.
+		// Prefer to record entries with errors, so we can report them.
+		p0 := deps[path]
+		if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
+			deps[path] = p1
+			for _, p2 := range p1.Internal.Imports {
+				if deps[p2.ImportPath] != p2 {
+					q = append(q, p2)
+				}
+			}
+		}
+	}
+
 	p.Deps = make([]string, 0, len(deps))
 	for dep := range deps {
 		p.Deps = append(p.Deps, dep)
@@ -1105,7 +1136,6 @@
 		if p1 == nil {
 			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
 		}
-		p.Internal.Deps = append(p.Internal.Deps, p1)
 		if p1.Error != nil {
 			p.DepsErrors = append(p.DepsErrors, p1.Error)
 		}
@@ -1113,9 +1143,8 @@
 
 	// unsafe is a fake package.
 	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
-		p.Internal.Target = ""
+		p.Target = ""
 	}
-	p.Target = p.Internal.Target
 
 	// If cgo is not enabled, ignore cgo supporting sources
 	// just as we ignore go files containing import "C".
@@ -1131,13 +1160,32 @@
 		// code; see issue #16050).
 	}
 
-	// The gc toolchain only permits C source files with cgo.
-	if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
+	setError := func(msg string) {
 		p.Error = &PackageError{
 			ImportStack: stk.Copy(),
-			Err:         fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")),
+			Err:         msg,
 		}
-		return p
+	}
+
+	// The gc toolchain only permits C source files with cgo or SWIG.
+	if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
+		setError(fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
+		return
+	}
+
+	// C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
+	// regardless of toolchain.
+	if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
+		setError(fmt.Sprintf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
+		return
+	}
+	if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
+		setError(fmt.Sprintf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
+		return
+	}
+	if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
+		setError(fmt.Sprintf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
+		return
 	}
 
 	// Check for case-insensitive collisions of import paths.
@@ -1145,23 +1193,121 @@
 	if other := foldPath[fold]; other == "" {
 		foldPath[fold] = p.ImportPath
 	} else if other != p.ImportPath {
-		p.Error = &PackageError{
-			ImportStack: stk.Copy(),
-			Err:         fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other),
-		}
-		return p
+		setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other))
+		return
+	}
+}
+
+// SafeArg reports whether arg is a "safe" command-line argument,
+// meaning that when it appears in a command-line, it probably
+// doesn't have some special meaning other than its own name.
+// Obviously args beginning with - are not safe (they look like flags).
+// Less obviously, args beginning with @ are not safe (they look like
+// GNU binutils flagfile specifiers, sometimes called "response files").
+// To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
+// We accept leading . _ and / as likely in file system paths.
+// There is a copy of this function in cmd/compile/internal/gc/noder.go.
+func SafeArg(name string) bool {
+	if name == "" {
+		return false
+	}
+	c := name[0]
+	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
+}
+
+// LinkerDeps returns the list of linker-induced dependencies for main package p.
+func LinkerDeps(p *Package) []string {
+	// Everything links runtime.
+	deps := []string{"runtime"}
+
+	// External linking mode forces an import of runtime/cgo.
+	if externalLinkingForced(p) {
+		deps = append(deps, "runtime/cgo")
+	}
+	// On ARM with GOARM=5, it forces an import of math, for soft floating point.
+	if cfg.Goarch == "arm" {
+		deps = append(deps, "math")
+	}
+	// Using the race detector forces an import of runtime/race.
+	if cfg.BuildRace {
+		deps = append(deps, "runtime/race")
+	}
+	// Using memory sanitizer forces an import of runtime/msan.
+	if cfg.BuildMSan {
+		deps = append(deps, "runtime/msan")
 	}
 
-	if p.BinaryOnly {
-		// For binary-only package, use build ID from supplied package binary.
-		buildID, err := buildid.ReadBuildID(p.Name, p.Target)
-		if err == nil {
-			p.Internal.BuildID = buildID
+	return deps
+}
+
+// externalLinkingForced reports whether external linking is being
+// forced even for programs that do not use cgo.
+func externalLinkingForced(p *Package) bool {
+	// Some targets must use external linking even inside GOROOT.
+	switch cfg.BuildContext.GOOS {
+	case "android":
+		return true
+	case "darwin":
+		switch cfg.BuildContext.GOARCH {
+		case "arm", "arm64":
+			return true
 		}
-	} else {
-		computeBuildID(p)
 	}
-	return p
+
+	if !cfg.BuildContext.CgoEnabled {
+		return false
+	}
+	// Currently build modes c-shared, pie (on systems that do not
+	// support PIE with internal linking mode (currently all
+	// systems: issue #18968)), plugin, and -linkshared force
+	// external linking mode, as of course does
+	// -ldflags=-linkmode=external. External linking mode forces
+	// an import of runtime/cgo.
+	pieCgo := cfg.BuildBuildmode == "pie"
+	linkmodeExternal := false
+	if p != nil {
+		ldflags := BuildLdflags.For(p)
+		for i, a := range ldflags {
+			if a == "-linkmode=external" {
+				linkmodeExternal = true
+			}
+			if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
+				linkmodeExternal = true
+			}
+		}
+	}
+
+	return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
+}
+
+// mkAbs rewrites list, which must be paths relative to p.Dir,
+// into a sorted list of absolute paths. It edits list in place but for
+// convenience also returns list back to its caller.
+func (p *Package) mkAbs(list []string) []string {
+	for i, f := range list {
+		list[i] = filepath.Join(p.Dir, f)
+	}
+	sort.Strings(list)
+	return list
+}
+
+// InternalGoFiles returns the list of Go files being built for the package,
+// using absolute paths.
+func (p *Package) InternalGoFiles() []string {
+	return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
+}
+
+// InternalGoFiles returns the list of all Go files possibly relevant for the package,
+// using absolute paths. "Possibly relevant" means that files are not excluded
+// due to build tags, but files with names beginning with . or _ are still excluded.
+func (p *Package) InternalAllGoFiles() []string {
+	var extra []string
+	for _, f := range p.IgnoredGoFiles {
+		if f != "" && f[0] != '.' || f[0] != '_' {
+			extra = append(extra, f)
+		}
+	}
+	return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
 }
 
 // usesSwig reports whether the package needs to run SWIG.
@@ -1196,517 +1342,6 @@
 	return all
 }
 
-// computeStale computes the Stale flag in the package dag that starts
-// at the named pkgs (command-line arguments).
-func ComputeStale(pkgs ...*Package) {
-	for _, p := range PackageList(pkgs) {
-		p.Stale, p.StaleReason = isStale(p)
-	}
-}
-
-// 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 and computeBuildID
-//
-// Theory of Operation
-//
-// There is an installed copy of the package (or binary).
-// Can we reuse the installed copy, or do we need to build a new one?
-//
-// We can use the installed copy if it matches what we'd get
-// by building a new one. The hard part is predicting that without
-// actually running a build.
-//
-// To start, we must know the set of inputs to the build process that can
-// affect the generated output. At a minimum, that includes the source
-// files for the package and also any compiled packages imported by those
-// source files. The *Package has these, and we use them. One might also
-// argue for including in the input set: the build tags, whether the race
-// detector is in use, the target operating system and architecture, the
-// compiler and linker binaries being used, the additional flags being
-// passed to those, the cgo binary being used, the additional flags cgo
-// passes to the host C compiler, the host C compiler being used, the set
-// of host C include files and installed C libraries, and so on.
-// We include some but not all of this information.
-//
-// Once we have decided on a set of inputs, we must next decide how to
-// tell whether the content of that set has changed since the last build
-// of p. If there have been no changes, then we assume a new build would
-// produce the same result and reuse the installed package or binary.
-// But if there have been changes, then we assume a new build might not
-// produce the same result, so we rebuild.
-//
-// There are two common ways to decide whether the content of the set has
-// changed: modification times and content hashes. We use a mixture of both.
-//
-// The use of modification times (mtimes) was pioneered by make:
-// assuming that a file's mtime is an accurate record of when that file was last written,
-// and assuming that the modification time of an installed package or
-// binary is the time that it was built, if the mtimes of the inputs
-// predate the mtime of the installed object, then the build of that
-// object saw those versions of the files, and therefore a rebuild using
-// those same versions would produce the same object. In contrast, if any
-// mtime of an input is newer than the mtime of the installed object, a
-// change has occurred since the build, and the build should be redone.
-//
-// Modification times are attractive because the logic is easy to
-// understand and the file system maintains the mtimes automatically
-// (less work for us). Unfortunately, there are a variety of ways in
-// which the mtime approach fails to detect a change and reuses a stale
-// object file incorrectly. (Making the opposite mistake, rebuilding
-// unnecessarily, is only a performance problem and not a correctness
-// problem, so we ignore that one.)
-//
-// As a warmup, one problem is that to be perfectly precise, we need to
-// compare the input mtimes against the time at the beginning of the
-// build, but the object file time is the time at the end of the build.
-// If an input file changes after being read but before the object is
-// written, the next build will see an object newer than the input and
-// will incorrectly decide that the object is up to date. We make no
-// attempt to detect or solve this problem.
-//
-// Another problem is that due to file system imprecision, an input and
-// output that are actually ordered in time have the same mtime.
-// This typically happens on file systems with 1-second (or, worse,
-// 2-second) mtime granularity and with automated scripts that write an
-// input and then immediately run a build, or vice versa. If an input and
-// an output have the same mtime, the conservative behavior is to treat
-// the output as out-of-date and rebuild. This can cause one or more
-// spurious rebuilds, but only for 1 second, until the object finally has
-// an mtime later than the input.
-//
-// Another problem is that binary distributions often set the mtime on
-// all files to the same time. If the distribution includes both inputs
-// and cached build outputs, the conservative solution to the previous
-// problem will cause unnecessary rebuilds. Worse, in such a binary
-// distribution, those rebuilds might not even have permission to update
-// the cached build output. To avoid these write errors, if an input and
-// output have the same mtime, we assume the output is up-to-date.
-// This is the opposite of what the previous problem would have us do,
-// but binary distributions are more common than instances of the
-// previous problem.
-//
-// A variant of the last problem is that some binary distributions do not
-// set the mtime on all files to the same time. Instead they let the file
-// system record mtimes as the distribution is unpacked. If the outputs
-// are unpacked before the inputs, they'll be older and a build will try
-// to rebuild them. That rebuild might hit the same write errors as in
-// the last scenario. We don't make any attempt to solve this, and we
-// haven't had many reports of it. Perhaps the only time this happens is
-// when people manually unpack the distribution, and most of the time
-// that's done as the same user who will be using it, so an initial
-// rebuild on first use succeeds quietly.
-//
-// More generally, people and programs change mtimes on files. The last
-// few problems were specific examples of this, but it's a general problem.
-// For example, instead of a binary distribution, copying a home
-// directory from one directory or machine to another might copy files
-// but not preserve mtimes. If the inputs are new than the outputs on the
-// first machine but copied first, they end up older than the outputs on
-// the second machine.
-//
-// Because many other build systems have the same sensitivity to mtimes,
-// most programs manipulating source code take pains not to break the
-// mtime assumptions. For example, Git does not set the mtime of files
-// during a checkout operation, even when checking out an old version of
-// the code. This decision was made specifically to work well with
-// mtime-based build systems.
-//
-// The killer problem, though, for mtime-based build systems is that the
-// build only has access to the mtimes of the inputs that still exist.
-// If it is possible to remove an input without changing any other inputs,
-// a later build will think the object is up-to-date when it is not.
-// This happens for Go because a package is made up of all source
-// files in a directory. If a source file is removed, there is no newer
-// mtime available recording that fact. The mtime on the directory could
-// be used, but it also changes when unrelated files are added to or
-// removed from the directory, so including the directory mtime would
-// cause unnecessary rebuilds, possibly many. It would also exacerbate
-// the problems mentioned earlier, since even programs that are careful
-// to maintain mtimes on files rarely maintain mtimes on directories.
-//
-// A variant of the last problem is when the inputs change for other
-// reasons. For example, Go 1.4 and Go 1.5 both install $GOPATH/src/mypkg
-// into the same target, $GOPATH/pkg/$GOOS_$GOARCH/mypkg.a.
-// If Go 1.4 has built mypkg into mypkg.a, a build using Go 1.5 must
-// rebuild mypkg.a, but from mtimes alone mypkg.a looks up-to-date.
-// If Go 1.5 has just been installed, perhaps the compiler will have a
-// newer mtime; since the compiler is considered an input, that would
-// trigger a rebuild. But only once, and only the last Go 1.4 build of
-// mypkg.a happened before Go 1.5 was installed. If a user has the two
-// versions installed in different locations and flips back and forth,
-// mtimes alone cannot tell what to do. Changing the toolchain is
-// changing the set of inputs, without affecting any mtimes.
-//
-// To detect the set of inputs changing, we turn away from mtimes and to
-// an explicit data comparison. Specifically, we build a list of the
-// inputs to the build, compute its SHA1 hash, and record that as the
-// ``build ID'' in the generated object. At the next build, we can
-// recompute the build ID and compare it to the one in the generated
-// object. If they differ, the list of inputs has changed, so the object
-// is out of date and must be rebuilt.
-//
-// Because this build ID is computed before the build begins, the
-// comparison does not have the race that mtime comparison does.
-//
-// Making the build sensitive to changes in other state is
-// straightforward: include the state in the build ID hash, and if it
-// changes, so does the build ID, triggering a rebuild.
-//
-// To detect changes in toolchain, we include the toolchain version in
-// the build ID hash for package runtime, and then we include the build
-// IDs of all imported packages in the build ID for p.
-//
-// It is natural to think about including build tags in the build ID, but
-// the naive approach of just dumping the tags into the hash would cause
-// spurious rebuilds. For example, 'go install' and 'go install -tags neverusedtag'
-// produce the same binaries (assuming neverusedtag is never used).
-// A more precise approach would be to include only tags that have an
-// effect on the build. But the effect of a tag on the build is to
-// include or exclude a file from the compilation, and that file list is
-// already in the build ID hash. So the build ID is already tag-sensitive
-// in a perfectly precise way. So we do NOT explicitly add build tags to
-// the build ID hash.
-//
-// We do not include as part of the build ID the operating system,
-// architecture, or whether the race detector is enabled, even though all
-// three have an effect on the output, because that information is used
-// to decide the install location. Binaries for linux and binaries for
-// darwin are written to different directory trees; including that
-// information in the build ID is unnecessary (although it would be
-// harmless).
-//
-// TODO(rsc): Investigate the cost of putting source file content into
-// the build ID hash as a replacement for the use of mtimes. Using the
-// file content would avoid all the mtime problems, but it does require
-// reading all the source files, something we avoid today (we read the
-// beginning to find the build tags and the imports, but we stop as soon
-// as we see the import block is over). If the package is stale, the compiler
-// is going to read the files anyway. But if the package is up-to-date, the
-// read is overhead.
-//
-// TODO(rsc): Investigate the complexity of making the build more
-// precise about when individual results are needed. To be fully precise,
-// there are two results of a compilation: the entire .a file used by the link
-// and the subpiece used by later compilations (__.PKGDEF only).
-// If a rebuild is needed but produces the previous __.PKGDEF, then
-// no more recompilation due to the rebuilt package is needed, only
-// relinking. To date, there is nothing in the Go command to express this.
-//
-// Special Cases
-//
-// When the go command makes the wrong build decision and does not
-// rebuild something it should, users fall back to adding the -a flag.
-// Any common use of the -a flag should be considered prima facie evidence
-// that isStale is returning an incorrect false result in some important case.
-// Bugs reported in the behavior of -a itself should prompt the question
-// ``Why is -a being used at all? What bug does that indicate?''
-//
-// There is a long history of changes to isStale to try to make -a into a
-// suitable workaround for bugs in the mtime-based decisions.
-// It is worth recording that history to inform (and, as much as possible, deter) future changes.
-//
-// (1) Before the build IDs were introduced, building with alternate tags
-// would happily reuse installed objects built without those tags.
-// For example, "go build -tags netgo myprog.go" would use the installed
-// copy of package net, even if that copy had been built without netgo.
-// (The netgo tag controls whether package net uses cgo or pure Go for
-// functionality such as name resolution.)
-// Using the installed non-netgo package defeats the purpose.
-//
-// Users worked around this with "go build -tags netgo -a myprog.go".
-//
-// Build IDs have made that workaround unnecessary:
-// "go build -tags netgo myprog.go"
-// cannot use a non-netgo copy of package net.
-//
-// (2) Before the build IDs were introduced, building with different toolchains,
-// especially changing between toolchains, tried to reuse objects stored in
-// $GOPATH/pkg, resulting in link-time errors about object file mismatches.
-//
-// Users worked around this with "go install -a ./...".
-//
-// Build IDs have made that workaround unnecessary:
-// "go install ./..." will rebuild any objects it finds that were built against
-// a different toolchain.
-//
-// (3) The common use of "go install -a ./..." led to reports of problems
-// when the -a forced the rebuild of the standard library, which for some
-// users was not writable. Because we didn't understand that the real
-// problem was the bug -a was working around, we changed -a not to
-// apply to the standard library.
-//
-// (4) The common use of "go build -tags netgo -a myprog.go" broke
-// when we changed -a not to apply to the standard library, because
-// if go build doesn't rebuild package net, it uses the non-netgo version.
-//
-// Users worked around this with "go build -tags netgo -installsuffix barf myprog.go".
-// The -installsuffix here is making the go command look for packages
-// in pkg/$GOOS_$GOARCH_barf instead of pkg/$GOOS_$GOARCH.
-// Since the former presumably doesn't exist, go build decides to rebuild
-// everything, including the standard library. Since go build doesn't
-// install anything it builds, nothing is ever written to pkg/$GOOS_$GOARCH_barf,
-// so repeated invocations continue to work.
-//
-// If the use of -a wasn't a red flag, the use of -installsuffix to point to
-// a non-existent directory in a command that installs nothing should
-// have been.
-//
-// (5) Now that (1) and (2) no longer need -a, we have removed the kludge
-// introduced in (3): once again, -a means ``rebuild everything,'' not
-// ``rebuild everything except the standard library.'' Only Go 1.4 had
-// the restricted meaning.
-//
-// In addition to these cases trying to trigger rebuilds, there are
-// special cases trying NOT to trigger rebuilds. The main one is that for
-// a variety of reasons (see above), the install process for a Go release
-// cannot be relied upon to set the mtimes such that the go command will
-// think the standard library is up to date. So the mtime evidence is
-// ignored for the standard library if we find ourselves in a release
-// version of Go. Build ID-based staleness checks still apply to the
-// standard library, even in release versions. This makes
-// 'go build -tags netgo' work, among other things.
-
-// isStale reports whether package p needs to be rebuilt,
-// along with the reason why.
-func isStale(p *Package) (bool, string) {
-	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
-		// fake, builtin package
-		return false, "builtin package"
-	}
-	if p.Error != nil {
-		return true, "errors loading package"
-	}
-	if p.Stale {
-		return true, p.StaleReason
-	}
-
-	// If this is a package with no source code, it cannot be rebuilt.
-	// If the binary is missing, we mark the package stale so that
-	// if a rebuild is needed, that rebuild attempt will produce a useful error.
-	// (Some commands, such as 'go list', do not attempt to rebuild.)
-	if p.BinaryOnly {
-		if p.Internal.Target == "" {
-			// Fail if a build is attempted.
-			return true, "no source code for package, but no install target"
-		}
-		if _, err := os.Stat(p.Internal.Target); err != nil {
-			// Fail if a build is attempted.
-			return true, "no source code for package, but cannot access install target: " + err.Error()
-		}
-		return false, "no source code for package"
-	}
-
-	// If the -a flag is given, rebuild everything.
-	if cfg.BuildA {
-		return true, "build -a flag in use"
-	}
-
-	// If there's no install target, we have to rebuild.
-	if p.Internal.Target == "" {
-		return true, "no install target"
-	}
-
-	// Package is stale if completely unbuilt.
-	fi, err := os.Stat(p.Internal.Target)
-	if err != nil {
-		return true, "cannot stat install target"
-	}
-
-	// Package is stale if the expected build ID differs from the
-	// recorded build ID. This catches changes like a source file
-	// being removed from a package directory. See issue 3895.
-	// It also catches changes in build tags that affect the set of
-	// files being compiled. See issue 9369.
-	// It also catches changes in toolchain, like when flipping between
-	// two versions of Go compiling a single GOPATH.
-	// See issue 8290 and issue 10702.
-	targetBuildID, err := buildid.ReadBuildID(p.Name, p.Target)
-	if err == nil && targetBuildID != p.Internal.BuildID {
-		return true, "build ID mismatch"
-	}
-
-	// Package is stale if a dependency is.
-	for _, p1 := range p.Internal.Deps {
-		if p1.Stale {
-			return true, "stale dependency"
-		}
-	}
-
-	// The checks above are content-based staleness.
-	// We assume they are always accurate.
-	//
-	// The checks below are mtime-based staleness.
-	// We hope they are accurate, but we know that they fail in the case of
-	// prebuilt Go installations that don't preserve the build mtimes
-	// (for example, if the pkg/ mtimes are before the src/ mtimes).
-	// See the large comment above isStale for details.
-
-	// If we are running a release copy of Go and didn't find a content-based
-	// reason to rebuild the standard packages, do not rebuild them.
-	// They may not be writable anyway, but they are certainly not changing.
-	// This makes 'go build' skip the standard packages when
-	// using an official release, even when the mtimes have been changed.
-	// See issue 3036, issue 3149, issue 4106, issue 8290.
-	// (If a change to a release tree must be made by hand, the way to force the
-	// install is to run make.bash, which will remove the old package archives
-	// before rebuilding.)
-	if p.Standard && isGoRelease {
-		return false, "standard package in Go release distribution"
-	}
-
-	// Time-based staleness.
-
-	built := fi.ModTime()
-
-	olderThan := func(file string) bool {
-		fi, err := os.Stat(file)
-		return err != nil || fi.ModTime().After(built)
-	}
-
-	// Package is stale if a dependency is, or if a dependency is newer.
-	for _, p1 := range p.Internal.Deps {
-		if p1.Internal.Target != "" && olderThan(p1.Internal.Target) {
-			return true, "newer dependency"
-		}
-	}
-
-	// As a courtesy to developers installing new versions of the compiler
-	// frequently, define that packages are stale if they are
-	// older than the compiler, and commands if they are older than
-	// the linker. This heuristic will not work if the binaries are
-	// back-dated, as some binary distributions may do, but it does handle
-	// a very common case.
-	// See issue 3036.
-	// Exclude $GOROOT, under the assumption that people working on
-	// the compiler may want to control when everything gets rebuilt,
-	// and people updating the Go repository will run make.bash or all.bash
-	// and get a full rebuild anyway.
-	// Excluding $GOROOT used to also fix issue 4106, but that's now
-	// taken care of above (at least when the installed Go is a released version).
-	if p.Root != cfg.GOROOT {
-		if olderThan(cfg.BuildToolchainCompiler()) {
-			return true, "newer compiler"
-		}
-		if p.Internal.Build.IsCommand() && olderThan(cfg.BuildToolchainLinker()) {
-			return true, "newer linker"
-		}
-	}
-
-	// Note: Until Go 1.5, we had an additional shortcut here.
-	// We built a list of the workspace roots ($GOROOT, each $GOPATH)
-	// containing targets directly named on the command line,
-	// and if p were not in any of those, it would be treated as up-to-date
-	// as long as it is built. The goal was to avoid rebuilding a system-installed
-	// $GOROOT, unless something from $GOROOT were explicitly named
-	// on the command line (like go install math).
-	// That's now handled by the isGoRelease clause above.
-	// The other effect of the shortcut was to isolate different entries in
-	// $GOPATH from each other. This had the unfortunate effect that
-	// if you had (say), GOPATH listing two entries, one for commands
-	// and one for libraries, and you did a 'git pull' in the library one
-	// and then tried 'go install commands/...', it would build the new libraries
-	// during the first build (because they wouldn't have been installed at all)
-	// but then subsequent builds would not rebuild the libraries, even if the
-	// mtimes indicate they are stale, because the different GOPATH entries
-	// were treated differently. This behavior was confusing when using
-	// non-trivial GOPATHs, which were particularly common with some
-	// code management conventions, like the original godep.
-	// Since the $GOROOT case (the original motivation) is handled separately,
-	// we no longer put a barrier between the different $GOPATH entries.
-	//
-	// One implication of this is that if there is a system directory for
-	// non-standard Go packages that is included in $GOPATH, the mtimes
-	// on those compiled packages must be no earlier than the mtimes
-	// on the source files. Since most distributions use the same mtime
-	// for all files in a tree, they will be unaffected. People using plain
-	// tar x to extract system-installed packages will need to adjust mtimes,
-	// but it's better to force them to get the mtimes right than to ignore
-	// the mtimes and thereby do the wrong thing in common use cases.
-	//
-	// So there is no GOPATH vs GOPATH shortcut here anymore.
-	//
-	// If something needs to come back here, we could try writing a dummy
-	// file with a random name to the $GOPATH/pkg directory (and removing it)
-	// to test for write access, and then skip GOPATH roots we don't have write
-	// access to. But hopefully we can just use the mtimes always.
-
-	srcs := str.StringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
-	for _, src := range srcs {
-		if olderThan(filepath.Join(p.Dir, src)) {
-			return true, "newer source file"
-		}
-	}
-
-	return false, ""
-}
-
-// computeBuildID computes the build ID for p, leaving it in p.Internal.BuildID.
-// Build ID is a hash of the information we want to detect changes in.
-// See the long comment in isStale for details.
-func computeBuildID(p *Package) {
-	h := sha1.New()
-
-	// Include the list of files compiled as part of the package.
-	// This lets us detect removed files. See issue 3895.
-	inputFiles := str.StringList(
-		p.GoFiles,
-		p.CgoFiles,
-		p.CFiles,
-		p.CXXFiles,
-		p.FFiles,
-		p.MFiles,
-		p.HFiles,
-		p.SFiles,
-		p.SysoFiles,
-		p.SwigFiles,
-		p.SwigCXXFiles,
-	)
-	for _, file := range inputFiles {
-		fmt.Fprintf(h, "file %s\n", file)
-	}
-
-	// Include the content of runtime/internal/sys/zversion.go in the hash
-	// for package runtime. This will give package runtime a
-	// different build ID in each Go release.
-	if p.Standard && p.ImportPath == "runtime/internal/sys" && cfg.BuildContext.Compiler != "gccgo" {
-		data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
-		if os.IsNotExist(err) {
-			p.Stale = true
-			p.StaleReason = fmt.Sprintf("missing zversion.go")
-		} else if err != nil {
-			base.Fatalf("go: %s", err)
-		}
-		fmt.Fprintf(h, "zversion %q\n", string(data))
-
-		// Add environment variables that affect code generation.
-		switch cfg.BuildContext.GOARCH {
-		case "arm":
-			fmt.Fprintf(h, "GOARM=%s\n", cfg.GOARM)
-		case "386":
-			fmt.Fprintf(h, "GO386=%s\n", cfg.GO386)
-		}
-	}
-
-	// Include the build IDs of any dependencies in the hash.
-	// This, combined with the runtime/zversion content,
-	// will cause packages to have different build IDs when
-	// compiled with different Go releases.
-	// This helps the go command know to recompile when
-	// people use the same GOPATH but switch between
-	// different Go releases. See issue 10702.
-	// This is also a better fix for issue 8290.
-	for _, p1 := range p.Internal.Deps {
-		fmt.Fprintf(h, "dep %s %s\n", p1.ImportPath, p1.Internal.BuildID)
-	}
-
-	p.Internal.BuildID = fmt.Sprintf("%x", h.Sum(nil))
-}
-
 var cmdCache = map[string]*Package{}
 
 func ClearCmdCache() {
@@ -1825,7 +1460,6 @@
 		seenPkg[pkg] = true
 		pkgs = append(pkgs, pkg)
 	}
-	ComputeStale(pkgs...)
 
 	return pkgs
 }
@@ -1926,13 +1560,13 @@
 	bp, err := ctxt.ImportDir(dir, 0)
 	pkg := new(Package)
 	pkg.Internal.Local = true
-	pkg.Internal.Cmdline = true
+	pkg.Internal.CmdlineFiles = true
 	stk.Push("main")
 	pkg.load(&stk, bp, err)
 	stk.Pop()
 	pkg.Internal.LocalPrefix = dirToImportPath(dir)
 	pkg.ImportPath = "command-line-arguments"
-	pkg.Internal.Target = ""
+	pkg.Target = ""
 
 	if pkg.Name == "main" {
 		_, elem := filepath.Split(gofiles[0])
@@ -1941,14 +1575,153 @@
 			cfg.BuildO = exe
 		}
 		if cfg.GOBIN != "" {
-			pkg.Internal.Target = filepath.Join(cfg.GOBIN, exe)
+			pkg.Target = filepath.Join(cfg.GOBIN, exe)
 		}
 	}
 
-	pkg.Target = pkg.Internal.Target
-	pkg.Stale = true
-	pkg.StaleReason = "files named on command line"
-
-	ComputeStale(pkg)
 	return pkg
 }
+
+// TestPackagesFor returns package structs ptest, the package p plus
+// its test files, and pxtest, the external tests of package p.
+// pxtest may be nil. If there are no test files, forceTest decides
+// whether this returns a new package struct or just returns p.
+func TestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err error) {
+	var imports, ximports []*Package
+	var stk ImportStack
+	stk.Push(p.ImportPath + " (test)")
+	rawTestImports := str.StringList(p.TestImports)
+	for i, path := range p.TestImports {
+		p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], UseVendor)
+		if p1.Error != nil {
+			return nil, nil, p1.Error
+		}
+		if len(p1.DepsErrors) > 0 {
+			err := p1.DepsErrors[0]
+			err.Pos = "" // show full import stack
+			return nil, nil, err
+		}
+		if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
+			// Same error that loadPackage returns (via reusePackage) in pkg.go.
+			// Can't change that code, because that code is only for loading the
+			// non-test copy of a package.
+			err := &PackageError{
+				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
+				Err:           "import cycle not allowed in test",
+				IsImportCycle: true,
+			}
+			return nil, nil, err
+		}
+		p.TestImports[i] = p1.ImportPath
+		imports = append(imports, p1)
+	}
+	stk.Pop()
+	stk.Push(p.ImportPath + "_test")
+	pxtestNeedsPtest := false
+	rawXTestImports := str.StringList(p.XTestImports)
+	for i, path := range p.XTestImports {
+		p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], UseVendor)
+		if p1.Error != nil {
+			return nil, nil, p1.Error
+		}
+		if len(p1.DepsErrors) > 0 {
+			err := p1.DepsErrors[0]
+			err.Pos = "" // show full import stack
+			return nil, nil, err
+		}
+		if p1.ImportPath == p.ImportPath {
+			pxtestNeedsPtest = true
+		} else {
+			ximports = append(ximports, p1)
+		}
+		p.XTestImports[i] = p1.ImportPath
+	}
+	stk.Pop()
+
+	// Test package.
+	if len(p.TestGoFiles) > 0 || forceTest {
+		ptest = new(Package)
+		*ptest = *p
+		ptest.GoFiles = nil
+		ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
+		ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
+		ptest.Target = ""
+		// Note: The preparation of the vet config requires that common
+		// indexes in ptest.Imports, ptest.Internal.Imports, and ptest.Internal.RawImports
+		// all line up (but RawImports can be shorter than the others).
+		// That is, for 0 ≤ i < len(RawImports),
+		// RawImports[i] is the import string in the program text,
+		// Imports[i] is the expanded import string (vendoring applied or relative path expanded away),
+		// and Internal.Imports[i] is the corresponding *Package.
+		// Any implicitly added imports appear in Imports and Internal.Imports
+		// but not RawImports (because they were not in the source code).
+		// We insert TestImports, imports, and rawTestImports at the start of
+		// these lists to preserve the alignment.
+		ptest.Imports = str.StringList(p.TestImports, p.Imports)
+		ptest.Internal.Imports = append(imports, p.Internal.Imports...)
+		ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
+		ptest.Internal.ForceLibrary = true
+		ptest.Internal.Build = new(build.Package)
+		*ptest.Internal.Build = *p.Internal.Build
+		m := map[string][]token.Position{}
+		for k, v := range p.Internal.Build.ImportPos {
+			m[k] = append(m[k], v...)
+		}
+		for k, v := range p.Internal.Build.TestImportPos {
+			m[k] = append(m[k], v...)
+		}
+		ptest.Internal.Build.ImportPos = m
+	} else {
+		ptest = p
+	}
+
+	// External test package.
+	if len(p.XTestGoFiles) > 0 {
+		pxtest = &Package{
+			PackagePublic: PackagePublic{
+				Name:       p.Name + "_test",
+				ImportPath: p.ImportPath + "_test",
+				Root:       p.Root,
+				Dir:        p.Dir,
+				GoFiles:    p.XTestGoFiles,
+				Imports:    p.XTestImports,
+			},
+			Internal: PackageInternal{
+				LocalPrefix: p.Internal.LocalPrefix,
+				Build: &build.Package{
+					ImportPos: p.Internal.Build.XTestImportPos,
+				},
+				Imports:    ximports,
+				RawImports: rawXTestImports,
+
+				Asmflags:   p.Internal.Asmflags,
+				Gcflags:    p.Internal.Gcflags,
+				Ldflags:    p.Internal.Ldflags,
+				Gccgoflags: p.Internal.Gccgoflags,
+			},
+		}
+		if pxtestNeedsPtest {
+			pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
+		}
+	}
+
+	return ptest, pxtest, nil
+}
+
+func testImportStack(top string, p *Package, target string) []string {
+	stk := []string{top, p.ImportPath}
+Search:
+	for p.ImportPath != target {
+		for _, p1 := range p.Internal.Imports {
+			if p1.ImportPath == target || str.Contains(p1.Deps, target) {
+				stk = append(stk, p1.ImportPath)
+				p = p1
+				continue Search
+			}
+		}
+		// Can't happen, but in case it does...
+		stk = append(stk, "<lost path to cycle>")
+		break
+	}
+	return stk
+}
diff --git a/src/cmd/go/internal/load/search.go b/src/cmd/go/internal/load/search.go
index 0c7d9ce..595de07 100644
--- a/src/cmd/go/internal/load/search.go
+++ b/src/cmd/go/internal/load/search.go
@@ -266,6 +266,50 @@
 	}
 }
 
+// MatchPackage(pattern, cwd)(p) reports whether package p matches pattern in the working directory cwd.
+func MatchPackage(pattern, cwd string) func(*Package) bool {
+	switch {
+	case strings.HasPrefix(pattern, "./") || strings.HasPrefix(pattern, "../") || pattern == "." || pattern == "..":
+		// Split pattern into leading pattern-free directory path
+		// (including all . and .. elements) and the final pattern.
+		var dir string
+		i := strings.Index(pattern, "...")
+		if i < 0 {
+			dir, pattern = pattern, ""
+		} else {
+			j := strings.LastIndex(pattern[:i], "/")
+			dir, pattern = pattern[:j], pattern[j+1:]
+		}
+		dir = filepath.Join(cwd, dir)
+		if pattern == "" {
+			return func(p *Package) bool { return p.Dir == dir }
+		}
+		matchPath := matchPattern(pattern)
+		return func(p *Package) bool {
+			// Compute relative path to dir and see if it matches the pattern.
+			rel, err := filepath.Rel(dir, p.Dir)
+			if err != nil {
+				// Cannot make relative - e.g. different drive letters on Windows.
+				return false
+			}
+			rel = filepath.ToSlash(rel)
+			if rel == ".." || strings.HasPrefix(rel, "../") {
+				return false
+			}
+			return matchPath(rel)
+		}
+	case pattern == "all":
+		return func(p *Package) bool { return true }
+	case pattern == "std":
+		return func(p *Package) bool { return p.Standard }
+	case pattern == "cmd":
+		return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
+	default:
+		matchPath := matchPattern(pattern)
+		return func(p *Package) bool { return matchPath(p.ImportPath) }
+	}
+}
+
 // replaceVendor returns the result of replacing
 // non-trailing vendor path elements in x with repl.
 func replaceVendor(x, repl string) string {
@@ -302,6 +346,9 @@
 // ImportPathsNoDotExpansion returns the import paths to use for the given
 // command line, but it does no ... expansion.
 func ImportPathsNoDotExpansion(args []string) []string {
+	if cmdlineMatchers == nil {
+		SetCmdlinePatterns(args)
+	}
 	if len(args) == 0 {
 		return []string{"."}
 	}
@@ -332,7 +379,7 @@
 	return out
 }
 
-// isMetaPackage checks if name is a reserved package name that expands to multiple packages.
+// IsMetaPackage checks if name is a reserved package name that expands to multiple packages.
 func IsMetaPackage(name string) bool {
 	return name == "std" || name == "cmd" || name == "all"
 }
diff --git a/src/cmd/go/internal/load/testgo.go b/src/cmd/go/internal/load/testgo.go
deleted file mode 100644
index 7734048..0000000
--- a/src/cmd/go/internal/load/testgo.go
+++ /dev/null
@@ -1,21 +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 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 load
-
-import "os"
-
-func init() {
-	if v := os.Getenv("TESTGO_IS_GO_RELEASE"); v != "" {
-		isGoRelease = v == "1"
-	}
-}
diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go
index 6e276c2..ce24748 100644
--- a/src/cmd/go/internal/run/run.go
+++ b/src/cmd/go/internal/run/run.go
@@ -52,8 +52,7 @@
 }
 
 func runRun(cmd *base.Command, args []string) {
-	work.InstrumentInit()
-	work.BuildModeInit()
+	work.BuildInit()
 	var b work.Builder
 	b.Init()
 	b.Print = printStderr
@@ -94,7 +93,7 @@
 	if p.Name != "main" {
 		base.Fatalf("go run: cannot run non-main package")
 	}
-	p.Internal.Target = "" // must build - not up to date
+	p.Target = "" // must build - not up to date
 	var src string
 	if len(p.GoFiles) > 0 {
 		src = p.GoFiles[0]
@@ -110,8 +109,8 @@
 		base.Fatalf("go run: no suitable source files%s", hint)
 	}
 	p.Internal.ExeName = src[:len(src)-len(".go")] // name temporary executable for first go file
-	a1 := b.Action(work.ModeBuild, work.ModeBuild, p)
-	a := &work.Action{Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
+	a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
+	a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
 	b.Do(a)
 }
 
diff --git a/src/cmd/go/internal/str/path.go b/src/cmd/go/internal/str/path.go
new file mode 100644
index 0000000..84ca9d5
--- /dev/null
+++ b/src/cmd/go/internal/str/path.go
@@ -0,0 +1,32 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package str
+
+import (
+	"path/filepath"
+	"strings"
+)
+
+// HasFilePathPrefix reports whether the filesystem path s begins with the
+// elements in prefix.
+func HasFilePathPrefix(s, prefix string) bool {
+	sv := strings.ToUpper(filepath.VolumeName(s))
+	pv := strings.ToUpper(filepath.VolumeName(prefix))
+	s = s[len(sv):]
+	prefix = prefix[len(pv):]
+	switch {
+	default:
+		return false
+	case sv != pv:
+		return false
+	case len(s) == len(prefix):
+		return s == prefix
+	case len(s) > len(prefix):
+		if prefix != "" && prefix[len(prefix)-1] == filepath.Separator {
+			return strings.HasPrefix(s, prefix)
+		}
+		return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix
+	}
+}
diff --git a/src/cmd/go/internal/test/cover.go b/src/cmd/go/internal/test/cover.go
new file mode 100644
index 0000000..12538b4
--- /dev/null
+++ b/src/cmd/go/internal/test/cover.go
@@ -0,0 +1,84 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"cmd/go/internal/base"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+var coverMerge struct {
+	f          *os.File
+	sync.Mutex // for f.Write
+}
+
+// initCoverProfile initializes the test coverage profile.
+// It must be run before any calls to mergeCoverProfile or closeCoverProfile.
+// Using this function clears the profile in case it existed from a previous run,
+// or in case it doesn't exist and the test is going to fail to create it (or not run).
+func initCoverProfile() {
+	if testCoverProfile == "" {
+		return
+	}
+	if !filepath.IsAbs(testCoverProfile) && testOutputDir != "" {
+		testCoverProfile = filepath.Join(testOutputDir, testCoverProfile)
+	}
+
+	// No mutex - caller's responsibility to call with no racing goroutines.
+	f, err := os.Create(testCoverProfile)
+	if err != nil {
+		base.Fatalf("%v", err)
+	}
+	_, err = fmt.Fprintf(f, "mode: %s\n", testCoverMode)
+	if err != nil {
+		base.Fatalf("%v", err)
+	}
+	coverMerge.f = f
+}
+
+// mergeCoverProfile merges file into the profile stored in testCoverProfile.
+// It prints any errors it encounters to ew.
+func mergeCoverProfile(ew io.Writer, file string) {
+	if coverMerge.f == nil {
+		return
+	}
+	coverMerge.Lock()
+	defer coverMerge.Unlock()
+
+	expect := fmt.Sprintf("mode: %s\n", testCoverMode)
+	buf := make([]byte, len(expect))
+	r, err := os.Open(file)
+	if err != nil {
+		// Test did not create profile, which is OK.
+		return
+	}
+	defer r.Close()
+
+	n, err := io.ReadFull(r, buf)
+	if n == 0 {
+		return
+	}
+	if err != nil || string(buf) != expect {
+		fmt.Fprintf(ew, "error: test wrote malformed coverage profile.\n")
+		return
+	}
+	_, err = io.Copy(coverMerge.f, r)
+	if err != nil {
+		fmt.Fprintf(ew, "error: saving coverage profile: %v\n", err)
+	}
+}
+
+func closeCoverProfile() {
+	if coverMerge.f == nil {
+		return
+	}
+	if err := coverMerge.f.Close(); err != nil {
+		base.Errorf("closing coverage profile: %v", err)
+	}
+}
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index ebebffd..a99c6a5 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"crypto/sha256"
 	"errors"
 	"fmt"
 	"go/ast"
@@ -13,24 +14,29 @@
 	"go/doc"
 	"go/parser"
 	"go/token"
+	"io"
+	"io/ioutil"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
 	"regexp"
-	"runtime"
 	"sort"
+	"strconv"
 	"strings"
+	"sync"
 	"text/template"
 	"time"
 	"unicode"
 	"unicode/utf8"
 
 	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
 	"cmd/go/internal/str"
 	"cmd/go/internal/work"
+	"cmd/internal/test2json"
 )
 
 // Break init loop.
@@ -57,10 +63,10 @@
 
 'Go test' recompiles each package along with any files with names matching
 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.
 Each listed package causes the execution of a separate test binary.
+Files whose names begin with "_" (including "_test.go") or "." are ignored.
 
 Test files that declare a package with the suffix "_test" will be compiled as a
 separate package, and then linked and run with the main test binary.
@@ -68,11 +74,58 @@
 The go tool will ignore a directory named "testdata", making it available
 to hold ancillary data needed by the tests.
 
-By default, go test needs no arguments. It compiles and tests the package
-with source in the current directory, including tests, and runs the tests.
+As part of building a test binary, go test runs go vet on the package
+and its test source files to identify significant problems. If go vet
+finds any problems, go test reports those and does not run the test binary.
+Only a high-confidence subset of the default go vet checks are used.
+To disable the running of go vet, use the -vet=off flag.
 
-The package is built in a temporary directory so it does not interfere with the
-non-test installation.
+All test output and summary lines are printed to the go command's
+standard output, even if the test printed them to its own standard
+error. (The go command's standard error is reserved for printing
+errors building the tests.)
+
+Go test runs in two different modes:
+
+The first, called local directory mode, occurs when go test is
+invoked with no package arguments (for example, 'go test' or 'go
+test -v'). In this mode, go test compiles the package sources and
+tests found in the current directory and then runs the resulting
+test binary. In this mode, caching (discussed below) is disabled.
+After the package test finishes, go test prints a summary line
+showing the test status ('ok' or 'FAIL'), package name, and elapsed
+time.
+
+The second, called package list mode, occurs when go test is invoked
+with explicit package arguments (for example 'go test math', 'go
+test ./...', and even 'go test .'). In this mode, go test compiles
+and tests each of the packages listed on the command line. If a
+package test passes, go test prints only the final 'ok' summary
+line. If a package test fails, go test prints the full test output.
+If invoked with the -bench or -v flag, go test prints the full
+output even for passing package tests, in order to display the
+requested benchmark results or verbose logging.
+
+In package list mode only, go test caches successful package test
+results to avoid unnecessary repeated running of tests. When the
+result of a test can be recovered from the cache, go test will
+redisplay the previous output instead of running the test binary
+again. When this happens, go test prints '(cached)' in place of the
+elapsed time in the summary line.
+
+The rule for a match in the cache is that the run involves the same
+test binary and the flags on the command line come entirely from a
+restricted set of 'cacheable' test flags, defined as -cpu, -list,
+-parallel, -run, -short, and -v. If a run of go test has any test
+or non-test flags outside this set, the result is not cached. To
+disable test caching, use any test flag or argument other than the
+cacheable flags. The idiomatic way to disable test caching explicitly
+is to use -count=1. Tests that open files within the package's source
+root (usually $GOPATH) or that consult environment variables only
+match future runs in which the files and environment variables are unchanged.
+A cached test result is treated as executing in no time at all,
+so a successful package test result will be cached and reused
+regardless of -timeout setting.
 
 ` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
 
@@ -105,6 +158,10 @@
 	    Install packages that are dependencies of the test.
 	    Do not run the test.
 
+	-json
+	    Convert test output to JSON suitable for automated processing.
+	    See 'go doc test2json' for the encoding details.
+
 	-o file
 	    Compile the test binary to the named file.
 	    The test still runs (unless -c or -i is specified).
@@ -123,7 +180,7 @@
 
 var HelpTestflag = &base.Command{
 	UsageLine: "testflag",
-	Short:     "description of testing flags",
+	Short:     "testing flags",
 	Long: `
 The 'go test' command takes both flags that apply to 'go test' itself
 and flags that apply to the resulting test binary.
@@ -143,7 +200,7 @@
 const testFlag2 = `
 	-bench regexp
 	    Run only those benchmarks matching a regular expression.
-	    By default, no benchmarks are run. 
+	    By default, no benchmarks are run.
 	    To run all benchmarks, use '-bench .' or '-bench=.'.
 	    The regular expression is split by unbracketed slash (/)
 	    characters into a sequence of regular expressions, and each
@@ -182,10 +239,10 @@
 			significantly more expensive.
 	    Sets -cover.
 
-	-coverpkg pkg1,pkg2,pkg3
-	    Apply coverage analysis in each test to the given list of packages.
+	-coverpkg pattern1,pattern2,pattern3
+	    Apply coverage analysis in each test to packages matching the patterns.
 	    The default is for each test to analyze only the package being tested.
-	    Packages are specified as import paths.
+	    See 'go help packages' for a description of package patterns.
 	    Sets -cover.
 
 	-cpu 1,2,4
@@ -193,6 +250,9 @@
 	    benchmarks should be executed. The default is the current value
 	    of GOMAXPROCS.
 
+	-failfast
+	    Do not start new tests after the first test failure.
+
 	-list regexp
 	    List tests, benchmarks, or examples matching the regular expression.
 	    No tests, benchmarks or examples will be run. This will only
@@ -225,12 +285,20 @@
 
 	-timeout d
 	    If a test binary runs longer than duration d, panic.
+	    If d is 0, the timeout is disabled.
 	    The default is 10 minutes (10m).
 
 	-v
 	    Verbose output: log all tests as they are run. Also print all
 	    text from Log and Logf calls even if the test succeeds.
 
+	-vet list
+	    Configure the invocation of "go vet" during "go test"
+	    to use the comma-separated list of vet checks.
+	    If list is empty, "go test" runs "go vet" with a curated list of
+	    checks believed to be always worth addressing.
+	    If list is "off", "go test" does not run "go vet" at all.
+
 The following flags are also recognized by 'go test' and can be used to
 profile the tests during execution:
 
@@ -346,19 +414,19 @@
 
 var HelpTestfunc = &base.Command{
 	UsageLine: "testfunc",
-	Short:     "description of testing functions",
+	Short:     "testing functions",
 	Long: `
 The 'go test' command expects to find test, benchmark, and example functions
 in the "*_test.go" files corresponding to the package under test.
 
-A test function is one named TestXXX (where XXX is any alphanumeric string
-not starting with a lower case letter) and should have the signature,
+A test function is one named TestXxx (where Xxx does not start with a
+lower case letter) and should have the signature,
 
-	func TestXXX(t *testing.T) { ... }
+	func TestXxx(t *testing.T) { ... }
 
-A benchmark function is one named BenchmarkXXX and should have the signature,
+A benchmark function is one named BenchmarkXxx and should have the signature,
 
-	func BenchmarkXXX(b *testing.B) { ... }
+	func BenchmarkXxx(b *testing.B) { ... }
 
 An example function is similar to a test function but, instead of using
 *testing.T to report success or failure, prints output to os.Stdout.
@@ -369,8 +437,8 @@
 comment is compiled but not executed. An example with no text after
 "Output:" is compiled, executed, and expected to produce no output.
 
-Godoc displays the body of ExampleXXX to demonstrate the use
-of the function, constant, or variable XXX. An example of a method M with
+Godoc displays the body of ExampleXxx to demonstrate the use
+of the function, constant, or variable Xxx. An example of a method M with
 receiver type T or *T is named ExampleT_M. There may be multiple examples
 for a given function, constant, or variable, distinguished by a trailing _xxx,
 where xxx is a suffix not beginning with an upper case letter.
@@ -411,36 +479,68 @@
 	testCoverMode    string          // -covermode flag
 	testCoverPaths   []string        // -coverpkg flag
 	testCoverPkgs    []*load.Package // -coverpkg flag
+	testCoverProfile string          // -coverprofile flag
+	testOutputDir    string          // -outputdir flag
 	testO            string          // -o flag
-	testProfile      bool            // some profiling flag
+	testProfile      string          // profiling flag that limits test to one package
 	testNeedBinary   bool            // profile needs to keep binary around
+	testJSON         bool            // -json flag
 	testV            bool            // -v flag
 	testTimeout      string          // -timeout flag
 	testArgs         []string
 	testBench        bool
 	testList         bool
-	testStreamOutput bool // show output as it is generated
-	testShowPass     bool // show passing output
+	testShowPass     bool   // show passing output
+	testVetList      string // -vet flag
+	pkgArgs          []string
+	pkgs             []*load.Package
 
 	testKillTimeout = 10 * time.Minute
+	testCacheExpire time.Time // ignore cached test results before this time
 )
 
-var testMainDeps = map[string]bool{
+var testMainDeps = []string{
 	// Dependencies for testmain.
-	"testing":                   true,
-	"testing/internal/testdeps": true,
-	"os": true,
+	"os",
+	"testing",
+	"testing/internal/testdeps",
+}
+
+// testVetFlags is the list of flags to pass to vet when invoked automatically during go test.
+var testVetFlags = []string{
+	// TODO(rsc): Decide which tests are enabled by default.
+	// See golang.org/issue/18085.
+	// "-asmdecl",
+	// "-assign",
+	"-atomic",
+	"-bool",
+	"-buildtags",
+	// "-cgocall",
+	// "-composites",
+	// "-copylocks",
+	// "-httpresponse",
+	// "-lostcancel",
+	// "-methods",
+	"-nilfunc",
+	"-printf",
+	// "-rangeloops",
+	// "-shift",
+	// "-structtags",
+	// "-tests",
+	// "-unreachable",
+	// "-unsafeptr",
+	// "-unusedresult",
 }
 
 func runTest(cmd *base.Command, args []string) {
-	var pkgArgs []string
 	pkgArgs, testArgs = testFlags(args)
 
 	work.FindExecCmd() // initialize cached result
 
-	work.InstrumentInit()
-	work.BuildModeInit()
-	pkgs := load.PackagesForBuild(pkgArgs)
+	work.BuildInit()
+	work.VetFlags = testVetFlags
+
+	pkgs = load.PackagesForBuild(pkgArgs)
 	if len(pkgs) == 0 {
 		base.Fatalf("no packages to test")
 	}
@@ -451,9 +551,11 @@
 	if testO != "" && len(pkgs) != 1 {
 		base.Fatalf("cannot use -o flag with multiple packages")
 	}
-	if testProfile && len(pkgs) != 1 {
-		base.Fatalf("cannot use test profile flag with multiple packages")
+	if testProfile != "" && len(pkgs) != 1 {
+		base.Fatalf("cannot use %s flag with multiple packages", testProfile)
 	}
+	initCoverProfile()
+	defer closeCoverProfile()
 
 	// If a test timeout was given and is parseable, set our kill timeout
 	// to that timeout plus one minute. This is a backup alarm in case
@@ -461,6 +563,10 @@
 	// timer does not get a chance to fire.
 	if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 {
 		testKillTimeout = dt + 1*time.Minute
+	} else if err == nil && dt == 0 {
+		// An explicit zero disables the test timeout.
+		// Let it have one century (almost) before we kill it.
+		testKillTimeout = 100 * 365 * 24 * time.Hour
 	}
 
 	// show passing test output (after buffering) with -v flag.
@@ -468,21 +574,22 @@
 	// otherwise the output will get mixed.
 	testShowPass = testV || testList
 
-	// stream test output (no buffering) when no package has
-	// been given on the command line (implicit current directory)
-	// or when benchmarking.
-	// Also stream if we're showing output anyway with a
-	// single package under test or if parallelism is set to 1.
-	// In these cases, streaming the output produces the same result
-	// as not streaming, just more immediately.
-	testStreamOutput = len(pkgArgs) == 0 || testBench ||
-		(testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1))
-
 	// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
 	if cfg.BuildI && testO != "" {
 		testC = true
 	}
 
+	// Read testcache expiration time, if present.
+	// (We implement go clean -testcache by writing an expiration date
+	// instead of searching out and deleting test result cache entries.)
+	if dir := cache.DefaultDir(); dir != "off" {
+		if data, _ := ioutil.ReadFile(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
+			if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil {
+				testCacheExpire = time.Unix(0, t)
+			}
+		}
+	}
+
 	var b work.Builder
 	b.Init()
 
@@ -490,7 +597,7 @@
 		cfg.BuildV = testV
 
 		deps := make(map[string]bool)
-		for dep := range testMainDeps {
+		for _, dep := range testMainDeps {
 			deps[dep] = true
 		}
 
@@ -511,9 +618,6 @@
 		if deps["C"] {
 			delete(deps, "C")
 			deps["runtime/cgo"] = true
-			if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan {
-				deps["cmd/cgo"] = true
-			}
 		}
 		// Ignore pseudo-packages.
 		delete(deps, "unsafe")
@@ -526,9 +630,9 @@
 		}
 		sort.Strings(all)
 
-		a := &work.Action{}
+		a := &work.Action{Mode: "go test -i"}
 		for _, p := range load.PackagesForBuild(all) {
-			a.Deps = append(a.Deps, b.Action(work.ModeInstall, work.ModeInstall, p))
+			a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
 		}
 		b.Do(a)
 		if !testC || a.Failed {
@@ -540,21 +644,39 @@
 	var builds, runs, prints []*work.Action
 
 	if testCoverPaths != nil {
-		// Load packages that were asked about for coverage.
-		// packagesForBuild exits if the packages cannot be loaded.
-		testCoverPkgs = load.PackagesForBuild(testCoverPaths)
+		match := make([]func(*load.Package) bool, len(testCoverPaths))
+		matched := make([]bool, len(testCoverPaths))
+		for i := range testCoverPaths {
+			match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd)
+		}
 
-		// Warn about -coverpkg arguments that are not actually used.
-		used := make(map[string]bool)
-		for _, p := range pkgs {
-			used[p.ImportPath] = true
-			for _, dep := range p.Deps {
-				used[dep] = true
+		// Select for coverage all dependencies matching the testCoverPaths patterns.
+		for _, p := range load.PackageList(pkgs) {
+			haveMatch := false
+			for i := range testCoverPaths {
+				if match[i](p) {
+					matched[i] = true
+					haveMatch = true
+				}
+			}
+
+			// Silently ignore attempts to run coverage on
+			// sync/atomic when using atomic coverage mode.
+			// Atomic coverage mode uses sync/atomic, so
+			// we can't also do coverage on it.
+			if testCoverMode == "atomic" && p.Standard && p.ImportPath == "sync/atomic" {
+				continue
+			}
+
+			if haveMatch {
+				testCoverPkgs = append(testCoverPkgs, p)
 			}
 		}
-		for _, p := range testCoverPkgs {
-			if !used[p.ImportPath] {
-				fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on %s\n", p.ImportPath)
+
+		// Warn about -coverpkg arguments that are not actually used.
+		for i := range testCoverPaths {
+			if !matched[i] {
+				fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on matches for pattern %s\n", testCoverPaths[i])
 			}
 		}
 
@@ -564,15 +686,15 @@
 			if p.ImportPath == "unsafe" {
 				continue
 			}
-			p.Stale = true // rebuild
-			p.StaleReason = "rebuild for coverage"
-			p.Internal.Fake = true // do not warn about rebuild
 			p.Internal.CoverMode = testCoverMode
 			var coverFiles []string
 			coverFiles = append(coverFiles, p.GoFiles...)
 			coverFiles = append(coverFiles, p.CgoFiles...)
 			coverFiles = append(coverFiles, p.TestGoFiles...)
 			p.Internal.CoverVars = declareCoverVars(p.ImportPath, coverFiles...)
+			if testCover && testCoverMode == "atomic" {
+				ensureImport(p, "sync/atomic")
+			}
 		}
 	}
 
@@ -604,7 +726,7 @@
 	}
 
 	// Ultimately the goal is to print the output.
-	root := &work.Action{Deps: prints}
+	root := &work.Action{Mode: "go test", Deps: prints}
 
 	// Force the printing of results to happen in order,
 	// one at a time.
@@ -627,68 +749,23 @@
 		}
 	}
 
-	// If we are building any out-of-date packages other
-	// than those under test, warn.
-	okBuild := map[*load.Package]bool{}
-	for _, p := range pkgs {
-		okBuild[p] = true
-	}
-	warned := false
-	for _, a := range work.ActionList(root) {
-		if a.Package == nil || okBuild[a.Package] {
-			continue
-		}
-		okBuild[a.Package] = true // warn at most once
-
-		// Don't warn about packages being rebuilt because of
-		// things like coverage analysis.
-		for _, p1 := range a.Package.Internal.Imports {
-			if p1.Internal.Fake {
-				a.Package.Internal.Fake = true
-			}
-		}
-
-		if a.Func != nil && !okBuild[a.Package] && !a.Package.Internal.Fake && !a.Package.Internal.Local {
-			if !warned {
-				fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
-				warned = true
-			}
-			fmt.Fprintf(os.Stderr, "\t%s\n", a.Package.ImportPath)
-		}
-	}
-	if warned {
-		args := strings.Join(pkgArgs, " ")
-		if args != "" {
-			args = " " + args
-		}
-		extraOpts := ""
-		if cfg.BuildRace {
-			extraOpts = "-race "
-		}
-		if cfg.BuildMSan {
-			extraOpts = "-msan "
-		}
-		fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args)
-	}
-
 	b.Do(root)
 }
 
 // ensures that package p imports the named package
 func ensureImport(p *load.Package, pkg string) {
-	for _, d := range p.Internal.Deps {
+	for _, d := range p.Internal.Imports {
 		if d.Name == pkg {
 			return
 		}
 	}
 
-	a := load.LoadPackage(pkg, &load.ImportStack{})
-	if a.Error != nil {
-		base.Fatalf("load %s: %v", pkg, a.Error)
+	p1 := load.LoadPackage(pkg, &load.ImportStack{})
+	if p1.Error != nil {
+		base.Fatalf("load %s: %v", pkg, p1.Error)
 	}
-	load.ComputeStale(a)
 
-	p.Internal.Imports = append(p.Internal.Imports, a)
+	p.Internal.Imports = append(p.Internal.Imports, p1)
 }
 
 var windowsBadWords = []string{
@@ -700,9 +777,10 @@
 
 func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
 	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
-		build := b.Action(work.ModeBuild, work.ModeBuild, p)
-		run := &work.Action{Package: p, Deps: []*work.Action{build}}
-		print := &work.Action{Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
+		build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
+		run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
+		addTestVet(b, p, run, nil)
+		print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
 		return build, run, print, nil
 	}
 
@@ -712,54 +790,12 @@
 	//	pmain - pkg.test binary
 	var ptest, pxtest, pmain *load.Package
 
-	var imports, ximports []*load.Package
-	var stk load.ImportStack
-	stk.Push(p.ImportPath + " (test)")
-	for i, path := range p.TestImports {
-		p1 := load.LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], load.UseVendor)
-		if p1.Error != nil {
-			return nil, nil, nil, p1.Error
-		}
-		if len(p1.DepsErrors) > 0 {
-			err := p1.DepsErrors[0]
-			err.Pos = "" // show full import stack
-			return nil, nil, nil, err
-		}
-		if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
-			// Same error that loadPackage returns (via reusePackage) in pkg.go.
-			// Can't change that code, because that code is only for loading the
-			// non-test copy of a package.
-			err := &load.PackageError{
-				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
-				Err:           "import cycle not allowed in test",
-				IsImportCycle: true,
-			}
-			return nil, nil, nil, err
-		}
-		p.TestImports[i] = p1.ImportPath
-		imports = append(imports, p1)
+	localCover := testCover && testCoverPaths == nil
+
+	ptest, pxtest, err = load.TestPackagesFor(p, localCover || p.Name == "main")
+	if err != nil {
+		return nil, nil, nil, err
 	}
-	stk.Pop()
-	stk.Push(p.ImportPath + "_test")
-	pxtestNeedsPtest := false
-	for i, path := range p.XTestImports {
-		p1 := load.LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], load.UseVendor)
-		if p1.Error != nil {
-			return nil, nil, nil, p1.Error
-		}
-		if len(p1.DepsErrors) > 0 {
-			err := p1.DepsErrors[0]
-			err.Pos = "" // show full import stack
-			return nil, nil, nil, err
-		}
-		if p1.ImportPath == p.ImportPath {
-			pxtestNeedsPtest = true
-		} else {
-			ximports = append(ximports, p1)
-		}
-		p.XTestImports[i] = p1.ImportPath
-	}
-	stk.Pop()
 
 	// Use last element of import path, not package name.
 	// They differ when package name is "main".
@@ -773,98 +809,21 @@
 	}
 	testBinary := elem + ".test"
 
-	// The ptest package needs to be importable under the
-	// same import path that p has, but we cannot put it in
-	// the usual place in the temporary tree, because then
-	// other tests will see it as the real package.
-	// Instead we make a _test directory under the import path
-	// and then repeat the import path there. We tell the
-	// compiler and linker to look in that _test directory first.
-	//
-	// That is, if the package under test is unicode/utf8,
-	// then the normal place to write the package archive is
-	// $WORK/unicode/utf8.a, but we write the test package archive to
-	// $WORK/unicode/utf8/_test/unicode/utf8.a.
-	// We write the external test package archive to
-	// $WORK/unicode/utf8/_test/unicode/utf8_test.a.
-	testDir := filepath.Join(b.WorkDir, filepath.FromSlash(p.ImportPath+"/_test"))
-	ptestObj := work.BuildToolchain.Pkgpath(testDir, p)
-
-	// Create the directory for the .a files.
-	ptestDir, _ := filepath.Split(ptestObj)
-	if err := b.Mkdir(ptestDir); err != nil {
-		return nil, nil, nil, err
-	}
-
 	// Should we apply coverage analysis locally,
 	// only for this package and only for this test?
 	// Yes, if -cover is on but -coverpkg has not specified
 	// a list of packages for global coverage.
-	localCover := testCover && testCoverPaths == nil
-
-	// Test package.
-	if len(p.TestGoFiles) > 0 || localCover || p.Name == "main" {
-		ptest = new(load.Package)
-		*ptest = *p
-		ptest.GoFiles = nil
-		ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
-		ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
-		ptest.Internal.Target = ""
-		ptest.Imports = str.StringList(p.Imports, p.TestImports)
-		ptest.Internal.Imports = append(append([]*load.Package{}, p.Internal.Imports...), imports...)
-		ptest.Internal.Pkgdir = testDir
-		ptest.Internal.Fake = true
-		ptest.Internal.ForceLibrary = true
-		ptest.Stale = true
-		ptest.StaleReason = "rebuild for test"
-		ptest.Internal.Build = new(build.Package)
-		*ptest.Internal.Build = *p.Internal.Build
-		m := map[string][]token.Position{}
-		for k, v := range p.Internal.Build.ImportPos {
-			m[k] = append(m[k], v...)
-		}
-		for k, v := range p.Internal.Build.TestImportPos {
-			m[k] = append(m[k], v...)
-		}
-		ptest.Internal.Build.ImportPos = m
-
-		if localCover {
-			ptest.Internal.CoverMode = testCoverMode
-			var coverFiles []string
-			coverFiles = append(coverFiles, ptest.GoFiles...)
-			coverFiles = append(coverFiles, ptest.CgoFiles...)
-			ptest.Internal.CoverVars = declareCoverVars(ptest.ImportPath, coverFiles...)
-		}
-	} else {
-		ptest = p
+	if localCover {
+		ptest.Internal.CoverMode = testCoverMode
+		var coverFiles []string
+		coverFiles = append(coverFiles, ptest.GoFiles...)
+		coverFiles = append(coverFiles, ptest.CgoFiles...)
+		ptest.Internal.CoverVars = declareCoverVars(ptest.ImportPath, coverFiles...)
 	}
 
-	// External test package.
-	if len(p.XTestGoFiles) > 0 {
-		pxtest = &load.Package{
-			PackagePublic: load.PackagePublic{
-				Name:       p.Name + "_test",
-				ImportPath: p.ImportPath + "_test",
-				Root:       p.Root,
-				Dir:        p.Dir,
-				GoFiles:    p.XTestGoFiles,
-				Imports:    p.XTestImports,
-				Stale:      true,
-			},
-			Internal: load.PackageInternal{
-				LocalPrefix: p.Internal.LocalPrefix,
-				Build: &build.Package{
-					ImportPos: p.Internal.Build.XTestImportPos,
-				},
-				Imports:  ximports,
-				Pkgdir:   testDir,
-				Fake:     true,
-				External: true,
-			},
-		}
-		if pxtestNeedsPtest {
-			pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
-		}
+	testDir := b.NewObjdir()
+	if err := b.Mkdir(testDir); err != nil {
+		return nil, nil, nil, err
 	}
 
 	// Action for building pkg.test.
@@ -873,21 +832,29 @@
 			Name:       "main",
 			Dir:        testDir,
 			GoFiles:    []string{"_testmain.go"},
-			ImportPath: "testmain",
+			ImportPath: p.ImportPath + " (testmain)",
 			Root:       p.Root,
-			Stale:      true,
 		},
 		Internal: load.PackageInternal{
 			Build:     &build.Package{Name: "main"},
-			Pkgdir:    testDir,
-			Fake:      true,
 			OmitDebug: !testC && !testNeedBinary,
+
+			Asmflags:   p.Internal.Asmflags,
+			Gcflags:    p.Internal.Gcflags,
+			Ldflags:    p.Internal.Ldflags,
+			Gccgoflags: p.Internal.Gccgoflags,
 		},
 	}
 
 	// The generated main also imports testing, regexp, and os.
+	// Also the linker introduces implicit dependencies reported by LinkerDeps.
+	var stk load.ImportStack
 	stk.Push("testmain")
-	for dep := range testMainDeps {
+	deps := testMainDeps // cap==len, so safe for append
+	for _, d := range load.LinkerDeps(p) {
+		deps = append(deps, d)
+	}
+	for _, dep := range deps {
 		if dep == ptest.ImportPath {
 			pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
 		} else {
@@ -930,26 +897,16 @@
 		t.ImportXtest = true
 	}
 
-	if ptest != p && localCover {
+	if ptest != p {
 		// We have made modifications to the package p being tested
-		// and are rebuilding p (as ptest), writing it to the testDir tree.
-		// Arrange to rebuild, writing to that same tree, all packages q
-		// such that the test depends on q, and q depends on p.
+		// and are rebuilding p (as ptest).
+		// Arrange to rebuild all packages q such that
+		// the test depends on q and q depends on p.
 		// This makes sure that q sees the modifications to p.
 		// Strictly speaking, the rebuild is only necessary if the
 		// modifications to p change its export metadata, but
 		// determining that is a bit tricky, so we rebuild always.
-		//
-		// This will cause extra compilation, so for now we only do it
-		// when testCover is set. The conditions are more general, though,
-		// and we may find that we need to do it always in the future.
-		recompileForTest(pmain, p, ptest, testDir)
-	}
-
-	if cfg.BuildContext.GOOS == "darwin" {
-		if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" {
-			t.NeedCgo = true
-		}
+		recompileForTest(pmain, p, ptest, pxtest)
 	}
 
 	for _, cp := range pmain.Internal.Imports {
@@ -959,34 +916,19 @@
 	}
 
 	if !cfg.BuildN {
-		// writeTestmain writes _testmain.go. This must happen after recompileForTest,
-		// because recompileForTest modifies XXX.
-		if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil {
+		// writeTestmain writes _testmain.go,
+		// using the test description gathered in t.
+		if err := writeTestmain(testDir+"_testmain.go", t); err != nil {
 			return nil, nil, nil, err
 		}
 	}
 
-	load.ComputeStale(pmain)
+	// Set compile objdir to testDir we've already created,
+	// so that the default file path stripping applies to _testmain.go.
+	b.CompileAction(work.ModeBuild, work.ModeBuild, pmain).Objdir = testDir
 
-	if ptest != p {
-		a := b.Action(work.ModeBuild, work.ModeBuild, ptest)
-		a.Objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
-		a.Objpkg = ptestObj
-		a.Target = ptestObj
-		a.Link = false
-	}
-
-	if pxtest != nil {
-		a := b.Action(work.ModeBuild, work.ModeBuild, pxtest)
-		a.Objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
-		a.Objpkg = work.BuildToolchain.Pkgpath(testDir, pxtest)
-		a.Target = a.Objpkg
-	}
-
-	a := b.Action(work.ModeBuild, work.ModeBuild, pmain)
-	a.Objdir = testDir + string(filepath.Separator)
-	a.Objpkg = filepath.Join(testDir, "main.a")
-	a.Target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
+	a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain)
+	a.Target = testDir + testBinary + cfg.ExeSuffix
 	if cfg.Goos == "windows" {
 		// There are many reserved words on Windows that,
 		// if used in the name of an executable, cause Windows
@@ -1012,13 +954,13 @@
 		// we could just do this always on Windows.
 		for _, bad := range windowsBadWords {
 			if strings.Contains(testBinary, bad) {
-				a.Target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
+				a.Target = testDir + "test.test" + cfg.ExeSuffix
 				break
 			}
 		}
 	}
 	buildAction = a
-
+	var installAction, cleanAction *work.Action
 	if testC || testNeedBinary {
 		// -c or profiling flag: create action to copy binary to ./test.out.
 		target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix)
@@ -1028,92 +970,109 @@
 				target = filepath.Join(base.Cwd, target)
 			}
 		}
-		buildAction = &work.Action{
+		pmain.Target = target
+		installAction = &work.Action{
+			Mode:    "test build",
 			Func:    work.BuildInstallFunc,
 			Deps:    []*work.Action{buildAction},
 			Package: pmain,
 			Target:  target,
 		}
-		runAction = buildAction // make sure runAction != nil even if not running test
+		runAction = installAction // make sure runAction != nil even if not running test
 	}
 	if testC {
-		printAction = &work.Action{Package: p, Deps: []*work.Action{runAction}} // nop
+		printAction = &work.Action{Mode: "test print (nop)", Package: p, Deps: []*work.Action{runAction}} // nop
 	} else {
 		// run test
+		c := new(runCache)
 		runAction = &work.Action{
-			Func:       builderRunTest,
+			Mode:       "test run",
+			Func:       c.builderRunTest,
 			Deps:       []*work.Action{buildAction},
 			Package:    p,
-			IgnoreFail: true,
+			IgnoreFail: true, // run (prepare output) even if build failed
+			TryCache:   c.tryCache,
+			Objdir:     testDir,
 		}
-		cleanAction := &work.Action{
-			Func:    builderCleanTest,
-			Deps:    []*work.Action{runAction},
-			Package: p,
+		if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
+			addTestVet(b, ptest, runAction, installAction)
+		}
+		if pxtest != nil {
+			addTestVet(b, pxtest, runAction, installAction)
+		}
+		cleanAction = &work.Action{
+			Mode:       "test clean",
+			Func:       builderCleanTest,
+			Deps:       []*work.Action{runAction},
+			Package:    p,
+			IgnoreFail: true, // clean even if test failed
+			Objdir:     testDir,
 		}
 		printAction = &work.Action{
-			Func:    builderPrintTest,
-			Deps:    []*work.Action{cleanAction},
-			Package: p,
+			Mode:       "test print",
+			Func:       builderPrintTest,
+			Deps:       []*work.Action{cleanAction},
+			Package:    p,
+			IgnoreFail: true, // print even if test failed
+		}
+	}
+	if installAction != nil {
+		if runAction != installAction {
+			installAction.Deps = append(installAction.Deps, runAction)
+		}
+		if cleanAction != nil {
+			cleanAction.Deps = append(cleanAction.Deps, installAction)
 		}
 	}
 
 	return buildAction, runAction, printAction, nil
 }
 
-func testImportStack(top string, p *load.Package, target string) []string {
-	stk := []string{top, p.ImportPath}
-Search:
-	for p.ImportPath != target {
-		for _, p1 := range p.Internal.Imports {
-			if p1.ImportPath == target || str.Contains(p1.Deps, target) {
-				stk = append(stk, p1.ImportPath)
-				p = p1
-				continue Search
-			}
-		}
-		// Can't happen, but in case it does...
-		stk = append(stk, "<lost path to cycle>")
-		break
+func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) {
+	if testVetList == "off" {
+		return
 	}
-	return stk
+
+	vet := b.VetAction(work.ModeBuild, work.ModeBuild, p)
+	runAction.Deps = append(runAction.Deps, vet)
+	// Install will clean the build directory.
+	// Make sure vet runs first.
+	// The install ordering in b.VetAction does not apply here
+	// because we are using a custom installAction (created above).
+	if installAction != nil {
+		installAction.Deps = append(installAction.Deps, vet)
+	}
 }
 
-func recompileForTest(pmain, preal, ptest *load.Package, testDir string) {
+func recompileForTest(pmain, preal, ptest, pxtest *load.Package) {
 	// The "test copy" of preal is ptest.
 	// For each package that depends on preal, make a "test copy"
 	// that depends on ptest. And so on, up the dependency tree.
 	testCopy := map[*load.Package]*load.Package{preal: ptest}
 	for _, p := range load.PackageList([]*load.Package{pmain}) {
+		if p == preal {
+			continue
+		}
 		// Copy on write.
-		didSplit := false
+		didSplit := p == pmain || p == pxtest
 		split := func() {
 			if didSplit {
 				return
 			}
 			didSplit = true
-			if p.Internal.Pkgdir != testDir {
-				p1 := new(load.Package)
-				testCopy[p] = p1
-				*p1 = *p
-				p1.Internal.Imports = make([]*load.Package, len(p.Internal.Imports))
-				copy(p1.Internal.Imports, p.Internal.Imports)
-				p = p1
-				p.Internal.Pkgdir = testDir
-				p.Internal.Target = ""
-				p.Internal.Fake = true
-				p.Stale = true
-				p.StaleReason = "depends on package being tested"
+			if testCopy[p] != nil {
+				panic("recompileForTest loop")
 			}
+			p1 := new(load.Package)
+			testCopy[p] = p1
+			*p1 = *p
+			p1.Internal.Imports = make([]*load.Package, len(p.Internal.Imports))
+			copy(p1.Internal.Imports, p.Internal.Imports)
+			p = p1
+			p.Target = ""
 		}
 
-		// Update p.Deps and p.Internal.Imports to use at test copies.
-		for i, dep := range p.Internal.Deps {
-			if p1 := testCopy[dep]; p1 != nil && p1 != dep {
-				split()
-				p.Internal.Deps[i] = p1
-			}
-		}
+		// Update p.Internal.Imports to use test copies.
 		for i, imp := range p.Internal.Imports {
 			if p1 := testCopy[imp]; p1 != nil && p1 != imp {
 				split()
@@ -1123,8 +1082,6 @@
 	}
 }
 
-var coverIndex = 0
-
 // isTestFile reports whether the source file is a set of tests and should therefore
 // be excluded from coverage analysis.
 func isTestFile(file string) bool {
@@ -1136,13 +1093,22 @@
 // to the files, to be used when annotating the files.
 func declareCoverVars(importPath string, files ...string) map[string]*load.CoverVar {
 	coverVars := make(map[string]*load.CoverVar)
+	coverIndex := 0
+	// We create the cover counters as new top-level variables in the package.
+	// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
+	// and more importantly with dot imports of other covered packages,
+	// so we append 12 hex digits from the SHA-256 of the import path.
+	// The point is only to avoid accidents, not to defeat users determined to
+	// break things.
+	sum := sha256.Sum256([]byte(importPath))
+	h := fmt.Sprintf("%x", sum[:6])
 	for _, file := range files {
 		if isTestFile(file) {
 			continue
 		}
 		coverVars[file] = &load.CoverVar{
 			File: filepath.Join(importPath, file),
-			Var:  fmt.Sprintf("GoCover_%d", coverIndex),
+			Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
 		}
 		coverIndex++
 	}
@@ -1151,10 +1117,113 @@
 
 var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
 
+type runCache struct {
+	disableCache bool // cache should be disabled for this run
+
+	buf *bytes.Buffer
+	id1 cache.ActionID
+	id2 cache.ActionID
+}
+
+// stdoutMu and lockedStdout provide a locked standard output
+// that guarantees never to interlace writes from multiple
+// goroutines, so that we can have multiple JSON streams writing
+// to a lockedStdout simultaneously and know that events will
+// still be intelligible.
+var stdoutMu sync.Mutex
+
+type lockedStdout struct{}
+
+func (lockedStdout) Write(b []byte) (int, error) {
+	stdoutMu.Lock()
+	defer stdoutMu.Unlock()
+	return os.Stdout.Write(b)
+}
+
 // builderRunTest is the action for running a test binary.
-func builderRunTest(b *work.Builder, a *work.Action) error {
-	args := str.StringList(work.FindExecCmd(), a.Deps[0].Target, testArgs)
-	a.TestOutput = new(bytes.Buffer)
+func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error {
+	if a.Failed {
+		// We were unable to build the binary.
+		a.Failed = false
+		a.TestOutput = new(bytes.Buffer)
+		fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
+		base.SetExitStatus(1)
+		return nil
+	}
+
+	var stdout io.Writer = os.Stdout
+	if testJSON {
+		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
+		defer json.Close()
+		stdout = json
+	}
+
+	var buf bytes.Buffer
+	if len(pkgArgs) == 0 || testBench {
+		// Stream test output (no buffering) when no package has
+		// been given on the command line (implicit current directory)
+		// or when benchmarking.
+		// No change to stdout.
+	} else {
+		// If we're only running a single package under test or if parallelism is
+		// set to 1, and if we're displaying all output (testShowPass), we can
+		// hurry the output along, echoing it as soon as it comes in.
+		// We still have to copy to &buf for caching the result. This special
+		// case was introduced in Go 1.5 and is intentionally undocumented:
+		// the exact details of output buffering are up to the go command and
+		// subject to change. It would be nice to remove this special case
+		// entirely, but it is surely very helpful to see progress being made
+		// when tests are run on slow single-CPU ARM systems.
+		//
+		// If we're showing JSON output, then display output as soon as
+		// possible even when multiple tests are being run: the JSON output
+		// events are attributed to specific package tests, so interlacing them
+		// is OK.
+		if testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
+			// Write both to stdout and buf, for possible saving
+			// to cache, and for looking for the "no tests to run" message.
+			stdout = io.MultiWriter(stdout, &buf)
+		} else {
+			stdout = &buf
+		}
+	}
+
+	if c.buf == nil {
+		// We did not find a cached result using the link step action ID,
+		// so we ran the link step. Try again now with the link output
+		// content ID. The attempt using the action ID makes sure that
+		// if the link inputs don't change, we reuse the cached test
+		// result without even rerunning the linker. The attempt using
+		// the link output (test binary) content ID makes sure that if
+		// we have different link inputs but the same final binary,
+		// we still reuse the cached test result.
+		// c.saveOutput will store the result under both IDs.
+		c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
+	}
+	if c.buf != nil {
+		if stdout != &buf {
+			stdout.Write(c.buf.Bytes())
+			c.buf.Reset()
+		}
+		a.TestOutput = c.buf
+		return nil
+	}
+
+	execCmd := work.FindExecCmd()
+	testlogArg := []string{}
+	if !c.disableCache && len(execCmd) == 0 {
+		testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
+	}
+	args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, testArgs)
+
+	if testCoverProfile != "" {
+		// Write coverage to temporary profile, for merging later.
+		for i, arg := range args {
+			if strings.HasPrefix(arg, "-test.coverprofile=") {
+				args[i] = "-test.coverprofile=" + a.Objdir + "_cover_.out"
+			}
+		}
+	}
 
 	if cfg.BuildN || cfg.BuildX {
 		b.Showcmd("", "%s", strings.Join(args, " "))
@@ -1163,25 +1232,11 @@
 		}
 	}
 
-	if a.Failed {
-		// We were unable to build the binary.
-		a.Failed = false
-		fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
-		base.SetExitStatus(1)
-		return nil
-	}
-
 	cmd := exec.Command(args[0], args[1:]...)
 	cmd.Dir = a.Package.Dir
 	cmd.Env = base.EnvForDir(cmd.Dir, cfg.OrigEnv)
-	var buf bytes.Buffer
-	if testStreamOutput {
-		cmd.Stdout = os.Stdout
-		cmd.Stderr = os.Stderr
-	} else {
-		cmd.Stdout = &buf
-		cmd.Stderr = &buf
-	}
+	cmd.Stdout = stdout
+	cmd.Stderr = stdout
 
 	// If there are any local SWIG dependencies, we want to load
 	// the shared library from the build directory.
@@ -1227,43 +1282,404 @@
 				cmd.Process.Signal(base.SignalTrace)
 				select {
 				case err = <-done:
-					fmt.Fprintf(&buf, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
+					fmt.Fprintf(cmd.Stdout, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
 					break Outer
 				case <-time.After(5 * time.Second):
 				}
 			}
 			cmd.Process.Kill()
 			err = <-done
-			fmt.Fprintf(&buf, "*** Test killed: ran too long (%v).\n", testKillTimeout)
+			fmt.Fprintf(cmd.Stdout, "*** Test killed: ran too long (%v).\n", testKillTimeout)
 		}
 		tick.Stop()
 	}
 	out := buf.Bytes()
+	a.TestOutput = &buf
 	t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds())
+
+	mergeCoverProfile(cmd.Stdout, a.Objdir+"_cover_.out")
+
 	if err == nil {
 		norun := ""
-		if testShowPass {
-			a.TestOutput.Write(out)
+		if !testShowPass && !testJSON {
+			buf.Reset()
 		}
 		if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
 			norun = " [no tests to run]"
 		}
-		fmt.Fprintf(a.TestOutput, "ok  \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
-		return nil
-	}
-
-	base.SetExitStatus(1)
-	if len(out) > 0 {
-		a.TestOutput.Write(out)
-		// assume printing the test binary's exit status is superfluous
+		fmt.Fprintf(cmd.Stdout, "ok  \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
+		c.saveOutput(a)
 	} else {
-		fmt.Fprintf(a.TestOutput, "%s\n", err)
+		base.SetExitStatus(1)
+		// If there was test output, assume we don't need to print the exit status.
+		// Buf there's no test output, do print the exit status.
+		if len(out) == 0 {
+			fmt.Fprintf(cmd.Stdout, "%s\n", err)
+		}
+		fmt.Fprintf(cmd.Stdout, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
 	}
-	fmt.Fprintf(a.TestOutput, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
 
+	if cmd.Stdout != &buf {
+		buf.Reset() // cmd.Stdout was going to os.Stdout already
+	}
 	return nil
 }
 
+// tryCache is called just before the link attempt,
+// to see if the test result is cached and therefore the link is unneeded.
+// It reports whether the result can be satisfied from cache.
+func (c *runCache) tryCache(b *work.Builder, a *work.Action) bool {
+	return c.tryCacheWithID(b, a, a.Deps[0].BuildActionID())
+}
+
+func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool {
+	if len(pkgArgs) == 0 {
+		// Caching does not apply to "go test",
+		// only to "go test foo" (including "go test .").
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n")
+		}
+		c.disableCache = true
+		return false
+	}
+
+	var cacheArgs []string
+	for _, arg := range testArgs {
+		i := strings.Index(arg, "=")
+		if i < 0 || !strings.HasPrefix(arg, "-test.") {
+			if cache.DebugTest {
+				fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
+			}
+			c.disableCache = true
+			return false
+		}
+		switch arg[:i] {
+		case "-test.cpu",
+			"-test.list",
+			"-test.parallel",
+			"-test.run",
+			"-test.short",
+			"-test.v":
+			// These are cacheable.
+			// Note that this list is documented above,
+			// so if you add to this list, update the docs too.
+			cacheArgs = append(cacheArgs, arg)
+
+		case "-test.timeout":
+			// Special case: this is cacheable but ignored during the hash.
+			// Do not add to cacheArgs.
+
+		default:
+			// nothing else is cacheable
+			if cache.DebugTest {
+				fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
+			}
+			c.disableCache = true
+			return false
+		}
+	}
+
+	if cache.Default() == nil {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: GOCACHE=off\n")
+		}
+		c.disableCache = true
+		return false
+	}
+
+	// The test cache result fetch is a two-level lookup.
+	//
+	// First, we use the content hash of the test binary
+	// and its command-line arguments to find the
+	// list of environment variables and files consulted
+	// the last time the test was run with those arguments.
+	// (To avoid unnecessary links, we store this entry
+	// under two hashes: id1 uses the linker inputs as a
+	// proxy for the test binary, and id2 uses the actual
+	// test binary. If the linker inputs are unchanged,
+	// this way we avoid the link step, even though we
+	// do not cache link outputs.)
+	//
+	// Second, we compute a hash of the values of the
+	// environment variables and the content of the files
+	// listed in the log from the previous run.
+	// Then we look up test output using a combination of
+	// the hash from the first part (testID) and the hash of the
+	// test inputs (testInputsID).
+	//
+	// In order to store a new test result, we must redo the
+	// testInputsID computation using the log from the run
+	// we want to cache, and then we store that new log and
+	// the new outputs.
+
+	h := cache.NewHash("testResult")
+	fmt.Fprintf(h, "test binary %s args %q execcmd %q", id, cacheArgs, work.ExecCmd)
+	testID := h.Sum()
+	if c.id1 == (cache.ActionID{}) {
+		c.id1 = testID
+	} else {
+		c.id2 = testID
+	}
+	if cache.DebugTest {
+		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => %x\n", a.Package.ImportPath, id, testID)
+	}
+
+	// Load list of referenced environment variables and files
+	// from last run of testID, and compute hash of that content.
+	data, entry, err := cache.Default().GetBytes(testID)
+	if !bytes.HasPrefix(data, testlogMagic) || data[len(data)-1] != '\n' {
+		if cache.DebugTest {
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "testcache: %s: input list not found: %v\n", a.Package.ImportPath, err)
+			} else {
+				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed\n", a.Package.ImportPath)
+			}
+		}
+		return false
+	}
+	testInputsID, err := computeTestInputsID(a, data)
+	if err != nil {
+		return false
+	}
+	if cache.DebugTest {
+		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => input ID %x => %x\n", a.Package.ImportPath, testID, testInputsID, testAndInputKey(testID, testInputsID))
+	}
+
+	// Parse cached result in preparation for changing run time to "(cached)".
+	// If we can't parse the cached result, don't use it.
+	data, entry, err = cache.Default().GetBytes(testAndInputKey(testID, testInputsID))
+	if len(data) == 0 || data[len(data)-1] != '\n' {
+		if cache.DebugTest {
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "testcache: %s: test output not found: %v\n", a.Package.ImportPath, err)
+			} else {
+				fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
+			}
+		}
+		return false
+	}
+	if entry.Time.Before(testCacheExpire) {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: %s: test output expired due to go clean -testcache\n", a.Package.ImportPath)
+		}
+		return false
+	}
+	i := bytes.LastIndexByte(data[:len(data)-1], '\n') + 1
+	if !bytes.HasPrefix(data[i:], []byte("ok  \t")) {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
+		}
+		return false
+	}
+	j := bytes.IndexByte(data[i+len("ok  \t"):], '\t')
+	if j < 0 {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
+		}
+		return false
+	}
+	j += i + len("ok  \t") + 1
+
+	// Committed to printing.
+	c.buf = new(bytes.Buffer)
+	c.buf.Write(data[:j])
+	c.buf.WriteString("(cached)")
+	for j < len(data) && ('0' <= data[j] && data[j] <= '9' || data[j] == '.' || data[j] == 's') {
+		j++
+	}
+	c.buf.Write(data[j:])
+	return true
+}
+
+var errBadTestInputs = errors.New("error parsing test inputs")
+var testlogMagic = []byte("# test log\n") // known to testing/internal/testdeps/deps.go
+
+// computeTestInputsID computes the "test inputs ID"
+// (see comment in tryCacheWithID above) for the
+// test log.
+func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) {
+	testlog = bytes.TrimPrefix(testlog, testlogMagic)
+	h := cache.NewHash("testInputs")
+	pwd := a.Package.Dir
+	for _, line := range bytes.Split(testlog, []byte("\n")) {
+		if len(line) == 0 {
+			continue
+		}
+		s := string(line)
+		i := strings.Index(s, " ")
+		if i < 0 {
+			if cache.DebugTest {
+				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
+			}
+			return cache.ActionID{}, errBadTestInputs
+		}
+		op := s[:i]
+		name := s[i+1:]
+		switch op {
+		default:
+			if cache.DebugTest {
+				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
+			}
+			return cache.ActionID{}, errBadTestInputs
+		case "getenv":
+			fmt.Fprintf(h, "env %s %x\n", name, hashGetenv(name))
+		case "chdir":
+			pwd = name // always absolute
+			fmt.Fprintf(h, "cbdir %s %x\n", name, hashStat(name))
+		case "stat":
+			if !filepath.IsAbs(name) {
+				name = filepath.Join(pwd, name)
+			}
+			if !inDir(name, a.Package.Root) {
+				// Do not recheck files outside the GOPATH or GOROOT root.
+				break
+			}
+			fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name))
+		case "open":
+			if !filepath.IsAbs(name) {
+				name = filepath.Join(pwd, name)
+			}
+			if !inDir(name, a.Package.Root) {
+				// Do not recheck files outside the GOPATH or GOROOT root.
+				break
+			}
+			fh, err := hashOpen(name)
+			if err != nil {
+				if cache.DebugTest {
+					fmt.Fprintf(os.Stderr, "testcache: %s: input file %s: %s\n", a.Package.ImportPath, name, err)
+				}
+				return cache.ActionID{}, err
+			}
+			fmt.Fprintf(h, "open %s %x\n", name, fh)
+		}
+	}
+	sum := h.Sum()
+	return sum, nil
+}
+
+func inDir(path, dir string) bool {
+	if str.HasFilePathPrefix(path, dir) {
+		return true
+	}
+	xpath, err1 := filepath.EvalSymlinks(path)
+	xdir, err2 := filepath.EvalSymlinks(dir)
+	if err1 == nil && err2 == nil && str.HasFilePathPrefix(xpath, xdir) {
+		return true
+	}
+	return false
+}
+
+func hashGetenv(name string) cache.ActionID {
+	h := cache.NewHash("getenv")
+	v, ok := os.LookupEnv(name)
+	if !ok {
+		h.Write([]byte{0})
+	} else {
+		h.Write([]byte{1})
+		h.Write([]byte(v))
+	}
+	return h.Sum()
+}
+
+const modTimeCutoff = 2 * time.Second
+
+var errFileTooNew = errors.New("file used as input is too new")
+
+func hashOpen(name string) (cache.ActionID, error) {
+	h := cache.NewHash("open")
+	info, err := os.Stat(name)
+	if err != nil {
+		fmt.Fprintf(h, "err %v\n", err)
+		return h.Sum(), nil
+	}
+	hashWriteStat(h, info)
+	if info.IsDir() {
+		names, err := ioutil.ReadDir(name)
+		if err != nil {
+			fmt.Fprintf(h, "err %v\n", err)
+		}
+		for _, f := range names {
+			fmt.Fprintf(h, "file %s ", f.Name())
+			hashWriteStat(h, f)
+		}
+	} else if info.Mode().IsRegular() {
+		// Because files might be very large, do not attempt
+		// to hash the entirety of their content. Instead assume
+		// the mtime and size recorded in hashWriteStat above
+		// are good enough.
+		//
+		// To avoid problems for very recent files where a new
+		// write might not change the mtime due to file system
+		// mtime precision, reject caching if a file was read that
+		// is less than modTimeCutoff old.
+		if time.Since(info.ModTime()) < modTimeCutoff {
+			return cache.ActionID{}, errFileTooNew
+		}
+	}
+	return h.Sum(), nil
+}
+
+func hashStat(name string) cache.ActionID {
+	h := cache.NewHash("stat")
+	if info, err := os.Stat(name); err != nil {
+		fmt.Fprintf(h, "err %v\n", err)
+	} else {
+		hashWriteStat(h, info)
+	}
+	if info, err := os.Lstat(name); err != nil {
+		fmt.Fprintf(h, "err %v\n", err)
+	} else {
+		hashWriteStat(h, info)
+	}
+	return h.Sum()
+}
+
+func hashWriteStat(h io.Writer, info os.FileInfo) {
+	fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir())
+}
+
+// testAndInputKey returns the actual cache key for the pair (testID, testInputsID).
+func testAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID {
+	return cache.Subkey(testID, fmt.Sprintf("inputs:%x", testInputsID))
+}
+
+func (c *runCache) saveOutput(a *work.Action) {
+	if c.id1 == (cache.ActionID{}) && c.id2 == (cache.ActionID{}) {
+		return
+	}
+
+	// See comment about two-level lookup in tryCacheWithID above.
+	testlog, err := ioutil.ReadFile(a.Objdir + "testlog.txt")
+	if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
+		if cache.DebugTest {
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: %v\n", a.Package.ImportPath, err)
+			} else {
+				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: malformed\n", a.Package.ImportPath)
+			}
+		}
+		return
+	}
+	testInputsID, err := computeTestInputsID(a, testlog)
+	if err != nil {
+		return
+	}
+	if c.id1 != (cache.ActionID{}) {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id1, testInputsID, testAndInputKey(c.id1, testInputsID))
+		}
+		cache.Default().PutNoVerify(c.id1, bytes.NewReader(testlog))
+		cache.Default().PutNoVerify(testAndInputKey(c.id1, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
+	}
+	if c.id2 != (cache.ActionID{}) {
+		if cache.DebugTest {
+			fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id2, testInputsID, testAndInputKey(c.id2, testInputsID))
+		}
+		cache.Default().PutNoVerify(c.id2, bytes.NewReader(testlog))
+		cache.Default().PutNoVerify(testAndInputKey(c.id2, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
+	}
+}
+
 // coveragePercentage returns the coverage results (if enabled) for the
 // test. It uncovers the data by scanning the output from the test run.
 func coveragePercentage(out []byte) string {
@@ -1288,9 +1704,10 @@
 	if cfg.BuildWork {
 		return nil
 	}
-	run := a.Deps[0]
-	testDir := filepath.Join(b.WorkDir, filepath.FromSlash(run.Package.ImportPath+"/_test"))
-	os.RemoveAll(testDir)
+	if cfg.BuildX {
+		b.Showcmd("", "rm -r %s", a.Objdir)
+	}
+	os.RemoveAll(a.Objdir)
 	return nil
 }
 
@@ -1298,14 +1715,22 @@
 func builderPrintTest(b *work.Builder, a *work.Action) error {
 	clean := a.Deps[0]
 	run := clean.Deps[0]
-	os.Stdout.Write(run.TestOutput.Bytes())
-	run.TestOutput = nil
+	if run.TestOutput != nil {
+		os.Stdout.Write(run.TestOutput.Bytes())
+		run.TestOutput = nil
+	}
 	return nil
 }
 
 // builderNoTest is the action for testing a package with no test files.
 func builderNoTest(b *work.Builder, a *work.Action) error {
-	fmt.Printf("?   \t%s\t[no test files]\n", a.Package.ImportPath)
+	var stdout io.Writer = os.Stdout
+	if testJSON {
+		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
+		defer json.Close()
+		stdout = json
+	}
+	fmt.Fprintf(stdout, "?   \t%s\t[no test files]\n", a.Package.ImportPath)
 	return nil
 }
 
@@ -1397,7 +1822,6 @@
 	NeedTest    bool
 	ImportXtest bool
 	NeedXtest   bool
-	NeedCgo     bool
 	Cover       []coverInfo
 }
 
@@ -1462,7 +1886,16 @@
 		}
 		name := n.Name.String()
 		switch {
-		case name == "TestMain" && isTestFunc(n, "M"):
+		case name == "TestMain":
+			if isTestFunc(n, "T") {
+				t.Tests = append(t.Tests, testFunc{pkg, name, "", false})
+				*doImport, *seen = true, true
+				continue
+			}
+			err := checkTestFunc(n, "M")
+			if err != nil {
+				return err
+			}
 			if t.TestMain != nil {
 				return errors.New("multiple definitions of TestMain")
 			}
@@ -1526,10 +1959,6 @@
 {{range $i, $p := .Cover}}
 	_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
 {{end}}
-
-{{if .NeedCgo}}
-	_ "runtime/cgo"
-{{end}}
 )
 
 var tests = []testing.InternalTest{
diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go
index bff8656..8a686b7 100644
--- a/src/cmd/go/internal/test/testflag.go
+++ b/src/cmd/go/internal/test/testflag.go
@@ -33,20 +33,23 @@
 	{Name: "covermode"},
 	{Name: "coverpkg"},
 	{Name: "exec"},
+	{Name: "json", BoolVar: &testJSON},
+	{Name: "vet"},
 
 	// Passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
 	{Name: "bench", PassToTest: true},
 	{Name: "benchmem", BoolVar: new(bool), PassToTest: true},
 	{Name: "benchtime", PassToTest: true},
+	{Name: "blockprofile", PassToTest: true},
+	{Name: "blockprofilerate", PassToTest: true},
 	{Name: "count", PassToTest: true},
 	{Name: "coverprofile", PassToTest: true},
 	{Name: "cpu", PassToTest: true},
 	{Name: "cpuprofile", PassToTest: true},
+	{Name: "failfast", BoolVar: new(bool), PassToTest: true},
 	{Name: "list", PassToTest: true},
 	{Name: "memprofile", PassToTest: true},
 	{Name: "memprofilerate", PassToTest: true},
-	{Name: "blockprofile", PassToTest: true},
-	{Name: "blockprofilerate", PassToTest: true},
 	{Name: "mutexprofile", PassToTest: true},
 	{Name: "mutexprofilefraction", PassToTest: true},
 	{Name: "outputdir", PassToTest: true},
@@ -85,7 +88,6 @@
 //	go test -x math
 func testFlags(args []string) (packageNames, passToTest []string) {
 	inPkg := false
-	outputDir := ""
 	var explicitArgs []string
 	for i := 0; i < len(args); i++ {
 		if !strings.HasPrefix(args[i], "-") {
@@ -132,8 +134,11 @@
 			// Arguably should be handled by f.Value, but aren't.
 			switch f.Name {
 			// bool flags.
-			case "c", "i", "v", "cover":
+			case "c", "i", "v", "cover", "json":
 				cmdflag.SetBool(cmd, f.BoolVar, value)
+				if f.Name == "json" && testJSON {
+					passToTest = append(passToTest, "-test.v=true")
+				}
 			case "o":
 				testO = value
 				testNeedBinary = true
@@ -151,10 +156,10 @@
 			case "timeout":
 				testTimeout = value
 			case "blockprofile", "cpuprofile", "memprofile", "mutexprofile":
-				testProfile = true
+				testProfile = "-" + f.Name
 				testNeedBinary = true
 			case "trace":
-				testProfile = true
+				testProfile = "-trace"
 			case "coverpkg":
 				testCover = true
 				if value == "" {
@@ -164,7 +169,7 @@
 				}
 			case "coverprofile":
 				testCover = true
-				testProfile = true
+				testCoverProfile = value
 			case "covermode":
 				switch value {
 				case "set", "count", "atomic":
@@ -174,7 +179,9 @@
 				}
 				testCover = true
 			case "outputdir":
-				outputDir = value
+				testOutputDir = value
+			case "vet":
+				testVetList = value
 			}
 		}
 		if extraWord {
@@ -193,12 +200,26 @@
 		}
 	}
 
+	if testVetList != "" && testVetList != "off" {
+		if strings.Contains(testVetList, "=") {
+			base.Fatalf("-vet argument cannot contain equal signs")
+		}
+		if strings.Contains(testVetList, " ") {
+			base.Fatalf("-vet argument is comma-separated list, cannot contain spaces")
+		}
+		list := strings.Split(testVetList, ",")
+		for i, arg := range list {
+			list[i] = "-" + arg
+		}
+		testVetFlags = list
+	}
+
 	if cfg.BuildRace && testCoverMode != "atomic" {
 		base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, testCoverMode)
 	}
 
 	// Tell the test what directory we're running in, so it can write the profiles there.
-	if testProfile && outputDir == "" {
+	if testProfile != "" && testOutputDir == "" {
 		dir, err := os.Getwd()
 		if err != nil {
 			base.Fatalf("error from os.Getwd: %s", err)
diff --git a/src/cmd/go/internal/tool/tool.go b/src/cmd/go/internal/tool/tool.go
index 5167526..db92884 100644
--- a/src/cmd/go/internal/tool/tool.go
+++ b/src/cmd/go/internal/tool/tool.go
@@ -27,7 +27,7 @@
 The -n flag causes tool to print the command that would be
 executed but not execute it.
 
-For more about each tool command, see 'go tool command -h'.
+For more about each tool command, see 'go doc cmd/<command>'.
 `,
 }
 
diff --git a/src/cmd/go/internal/vet/vet.go b/src/cmd/go/internal/vet/vet.go
index ddacd08..3d095d4 100644
--- a/src/cmd/go/internal/vet/vet.go
+++ b/src/cmd/go/internal/vet/vet.go
@@ -6,19 +6,17 @@
 package vet
 
 import (
-	"path/filepath"
-
 	"cmd/go/internal/base"
-	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
-	"cmd/go/internal/str"
+	"cmd/go/internal/work"
+	"path/filepath"
 )
 
 var CmdVet = &base.Command{
 	Run:         runVet,
 	CustomFlags: true,
 	UsageLine:   "vet [-n] [-x] [build flags] [vet flags] [packages]",
-	Short:       "run go tool vet on packages",
+	Short:       "report likely mistakes in packages",
 	Long: `
 Vet runs the Go vet command on the packages named by the import paths.
 
@@ -28,29 +26,52 @@
 The -n flag prints commands that would be executed.
 The -x flag prints commands as they are executed.
 
-For more about build flags, see 'go help build'.
+The build flags supported by go vet are those that control package resolution
+and execution, such as -n, -x, -v, -tags, and -toolexec.
+For more about these flags, see 'go help build'.
 
 See also: go fmt, go fix.
 	`,
 }
 
 func runVet(cmd *base.Command, args []string) {
-	vetFlags, packages := vetFlags(args)
-	for _, p := range load.Packages(packages) {
-		// 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, vetFlags, str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.SFiles))
-		}
-		if len(p.XTestGoFiles) > 0 {
-			runVetFiles(p, vetFlags, str.StringList(p.XTestGoFiles))
-		}
-	}
-}
+	vetFlags, pkgArgs := vetFlags(args)
 
-func runVetFiles(p *load.Package, flags, files []string) {
-	for i := range files {
-		files[i] = filepath.Join(p.Dir, files[i])
+	work.BuildInit()
+	work.VetFlags = vetFlags
+	if vetTool != "" {
+		var err error
+		work.VetTool, err = filepath.Abs(vetTool)
+		if err != nil {
+			base.Fatalf("%v", err)
+		}
 	}
-	base.Run(cfg.BuildToolexec, base.Tool("vet"), flags, base.RelPaths(files))
+
+	pkgs := load.PackagesForBuild(pkgArgs)
+	if len(pkgs) == 0 {
+		base.Fatalf("no packages to vet")
+	}
+
+	var b work.Builder
+	b.Init()
+
+	root := &work.Action{Mode: "go vet"}
+	for _, p := range pkgs {
+		ptest, pxtest, err := load.TestPackagesFor(p, false)
+		if err != nil {
+			base.Errorf("%v", err)
+			continue
+		}
+		if len(ptest.GoFiles) == 0 && pxtest == nil {
+			base.Errorf("go vet %s: no Go files in %s", p.ImportPath, p.Dir)
+			continue
+		}
+		if len(ptest.GoFiles) > 0 {
+			root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, ptest))
+		}
+		if pxtest != nil {
+			root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, pxtest))
+		}
+	}
+	b.Do(root)
 }
diff --git a/src/cmd/go/internal/vet/vetflag.go b/src/cmd/go/internal/vet/vetflag.go
index 8cd21bb..d4664cc 100644
--- a/src/cmd/go/internal/vet/vetflag.go
+++ b/src/cmd/go/internal/vet/vetflag.go
@@ -44,6 +44,7 @@
 	{Name: "rangeloops", BoolVar: new(bool)},
 	{Name: "shadow", BoolVar: new(bool)},
 	{Name: "shadowstrict", BoolVar: new(bool)},
+	{Name: "shift", BoolVar: new(bool)},
 	{Name: "source", BoolVar: new(bool)},
 	{Name: "structtags", BoolVar: new(bool)},
 	{Name: "tests", BoolVar: new(bool)},
@@ -54,10 +55,13 @@
 	{Name: "unusedstringmethods"},
 }
 
+var vetTool string
+
 // add build flags to vetFlagDefn.
 func init() {
 	var cmd base.Command
 	work.AddBuildFlags(&cmd)
+	cmd.Flag.StringVar(&vetTool, "vettool", "", "path to vet tool binary") // for cmd/vet tests; undocumented for now
 	cmd.Flag.VisitAll(func(f *flag.Flag) {
 		vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{
 			Name:  f.Name,
@@ -86,8 +90,13 @@
 			}
 			switch f.Name {
 			// Flags known to the build but not to vet, so must be dropped.
-			case "x", "n":
-				args = append(args[:i], args[i+1:]...)
+			case "x", "n", "vettool":
+				if extraWord {
+					args = append(args[:i], args[i+2:]...)
+					extraWord = false
+				} else {
+					args = append(args[:i], args[i+1:]...)
+				}
 				i--
 			}
 		}
diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go
new file mode 100644
index 0000000..9f1f8f8
--- /dev/null
+++ b/src/cmd/go/internal/work/action.go
@@ -0,0 +1,749 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Action graph creation (planning).
+
+package work
+
+import (
+	"bufio"
+	"bytes"
+	"container/heap"
+	"debug/elf"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/internal/buildid"
+)
+
+// A Builder holds global state about a build.
+// It does not hold per-package state, because we
+// build packages in parallel, and the builder is shared.
+type Builder struct {
+	WorkDir     string               // the temporary work directory (ends in filepath.Separator)
+	actionCache map[cacheKey]*Action // a cache of already-constructed actions
+	mkdirCache  map[string]bool      // a cache of created directories
+	flagCache   map[[2]string]bool   // a cache of supported compiler flags
+	Print       func(args ...interface{}) (int, error)
+
+	ComputeStaleOnly bool // compute staleness for go list; no actual build
+
+	objdirSeq int // counter for NewObjdir
+	pkgSeq    int
+
+	output    sync.Mutex
+	scriptDir string // current directory in printed script
+
+	exec      sync.Mutex
+	readySema chan bool
+	ready     actionQueue
+
+	id           sync.Mutex
+	toolIDCache  map[string]string // tool name -> tool ID
+	buildIDCache map[string]string // file name -> build ID
+}
+
+// NOTE: Much of Action would not need to be exported if not for test.
+// Maybe test functionality should move into this package too?
+
+// An Action represents a single action in the action graph.
+type Action struct {
+	Mode       string                        // description of action operation
+	Package    *load.Package                 // the package this action works on
+	Deps       []*Action                     // actions that must happen before this one
+	Func       func(*Builder, *Action) error // the action itself (nil = no-op)
+	IgnoreFail bool                          // whether to run f even if dependencies fail
+	TestOutput *bytes.Buffer                 // test output buffer
+	Args       []string                      // additional args for runProgram
+
+	triggers []*Action // inverse of deps
+
+	buggyInstall bool // is this a buggy install (see -linkshared)?
+
+	TryCache func(*Builder, *Action) bool // callback for cache bypass
+
+	// Generated files, directories.
+	Objdir   string         // directory for intermediate objects
+	Target   string         // goal of the action: the created package or executable
+	built    string         // the actual created package or executable
+	actionID cache.ActionID // cache ID of action input
+	buildID  string         // build ID of action output
+
+	needVet bool       // Mode=="build": need to fill in vet config
+	vetCfg  *vetConfig // vet config
+	output  []byte     // output redirect buffer (nil means use b.Print)
+
+	// Execution state.
+	pending  int  // number of deps yet to complete
+	priority int  // relative execution priority
+	Failed   bool // whether the action failed
+}
+
+// BuildActionID returns the action ID section of a's build ID.
+func (a *Action) BuildActionID() string { return actionID(a.buildID) }
+
+// BuildContentID returns the content ID section of a's build ID.
+func (a *Action) BuildContentID() string { return contentID(a.buildID) }
+
+// BuildID returns a's build ID.
+func (a *Action) BuildID() string { return a.buildID }
+
+// BuiltTarget returns the actual file that was built. This differs
+// from Target when the result was cached.
+func (a *Action) BuiltTarget() string { return a.built }
+
+// An actionQueue is a priority queue of actions.
+type actionQueue []*Action
+
+// Implement heap.Interface
+func (q *actionQueue) Len() int           { return len(*q) }
+func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
+func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
+func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*Action)) }
+func (q *actionQueue) Pop() interface{} {
+	n := len(*q) - 1
+	x := (*q)[n]
+	*q = (*q)[:n]
+	return x
+}
+
+func (q *actionQueue) push(a *Action) {
+	heap.Push(q, a)
+}
+
+func (q *actionQueue) pop() *Action {
+	return heap.Pop(q).(*Action)
+}
+
+type actionJSON struct {
+	ID         int
+	Mode       string
+	Package    string
+	Deps       []int    `json:",omitempty"`
+	IgnoreFail bool     `json:",omitempty"`
+	Args       []string `json:",omitempty"`
+	Link       bool     `json:",omitempty"`
+	Objdir     string   `json:",omitempty"`
+	Target     string   `json:",omitempty"`
+	Priority   int      `json:",omitempty"`
+	Failed     bool     `json:",omitempty"`
+	Built      string   `json:",omitempty"`
+}
+
+// cacheKey is the key for the action cache.
+type cacheKey struct {
+	mode string
+	p    *load.Package
+}
+
+func actionGraphJSON(a *Action) string {
+	var workq []*Action
+	var inWorkq = make(map[*Action]int)
+
+	add := func(a *Action) {
+		if _, ok := inWorkq[a]; ok {
+			return
+		}
+		inWorkq[a] = len(workq)
+		workq = append(workq, a)
+	}
+	add(a)
+
+	for i := 0; i < len(workq); i++ {
+		for _, dep := range workq[i].Deps {
+			add(dep)
+		}
+	}
+
+	var list []*actionJSON
+	for id, a := range workq {
+		aj := &actionJSON{
+			Mode:       a.Mode,
+			ID:         id,
+			IgnoreFail: a.IgnoreFail,
+			Args:       a.Args,
+			Objdir:     a.Objdir,
+			Target:     a.Target,
+			Failed:     a.Failed,
+			Priority:   a.priority,
+			Built:      a.built,
+		}
+		if a.Package != nil {
+			// TODO(rsc): Make this a unique key for a.Package somehow.
+			aj.Package = a.Package.ImportPath
+		}
+		for _, a1 := range a.Deps {
+			aj.Deps = append(aj.Deps, inWorkq[a1])
+		}
+		list = append(list, aj)
+	}
+
+	js, err := json.MarshalIndent(list, "", "\t")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "go: writing debug action graph: %v\n", err)
+		return ""
+	}
+	return string(js)
+}
+
+// BuildMode specifies the build mode:
+// are we just building things or also installing the results?
+type BuildMode int
+
+const (
+	ModeBuild BuildMode = iota
+	ModeInstall
+	ModeBuggyInstall
+)
+
+func (b *Builder) Init() {
+	var err error
+	b.Print = func(a ...interface{}) (int, error) {
+		return fmt.Fprint(os.Stderr, a...)
+	}
+	b.actionCache = make(map[cacheKey]*Action)
+	b.mkdirCache = make(map[string]bool)
+	b.toolIDCache = make(map[string]string)
+	b.buildIDCache = make(map[string]string)
+
+	if cfg.BuildN {
+		b.WorkDir = "$WORK"
+	} else {
+		b.WorkDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-build")
+		if err != nil {
+			base.Fatalf("%s", err)
+		}
+		if cfg.BuildX || cfg.BuildWork {
+			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir)
+		}
+		if !cfg.BuildWork {
+			workdir := b.WorkDir
+			base.AtExit(func() { os.RemoveAll(workdir) })
+		}
+	}
+
+	if _, ok := cfg.OSArchSupportsCgo[cfg.Goos+"/"+cfg.Goarch]; !ok && cfg.BuildContext.Compiler == "gc" {
+		fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", cfg.Goos, cfg.Goarch)
+		os.Exit(2)
+	}
+	for _, tag := range cfg.BuildContext.BuildTags {
+		if strings.Contains(tag, ",") {
+			fmt.Fprintf(os.Stderr, "cmd/go: -tags space-separated list contains comma\n")
+			os.Exit(2)
+		}
+	}
+}
+
+// NewObjdir returns the name of a fresh object directory under b.WorkDir.
+// It is up to the caller to call b.Mkdir on the result at an appropriate time.
+// The result ends in a slash, so that file names in that directory
+// can be constructed with direct string addition.
+//
+// NewObjdir must be called only from a single goroutine at a time,
+// so it is safe to call during action graph construction, but it must not
+// be called during action graph execution.
+func (b *Builder) NewObjdir() string {
+	b.objdirSeq++
+	return filepath.Join(b.WorkDir, fmt.Sprintf("b%03d", b.objdirSeq)) + string(filepath.Separator)
+}
+
+// readpkglist returns the list of packages that were built into the shared library
+// at shlibpath. For the native toolchain this list is stored, newline separated, in
+// an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
+// .go_export section.
+func readpkglist(shlibpath string) (pkgs []*load.Package) {
+	var stk load.ImportStack
+	if cfg.BuildToolchainName == "gccgo" {
+		f, _ := elf.Open(shlibpath)
+		sect := f.Section(".go_export")
+		data, _ := sect.Data()
+		scanner := bufio.NewScanner(bytes.NewBuffer(data))
+		for scanner.Scan() {
+			t := scanner.Text()
+			if strings.HasPrefix(t, "pkgpath ") {
+				t = strings.TrimPrefix(t, "pkgpath ")
+				t = strings.TrimSuffix(t, ";")
+				pkgs = append(pkgs, load.LoadPackage(t, &stk))
+			}
+		}
+	} else {
+		pkglistbytes, err := buildid.ReadELFNote(shlibpath, "Go\x00\x00", 1)
+		if err != nil {
+			base.Fatalf("readELFNote failed: %v", err)
+		}
+		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
+		for scanner.Scan() {
+			t := scanner.Text()
+			pkgs = append(pkgs, load.LoadPackage(t, &stk))
+		}
+	}
+	return
+}
+
+// cacheAction looks up {mode, p} in the cache and returns the resulting action.
+// If the cache has no such action, f() is recorded and returned.
+// TODO(rsc): Change the second key from *load.Package to interface{},
+// to make the caching in linkShared less awkward?
+func (b *Builder) cacheAction(mode string, p *load.Package, f func() *Action) *Action {
+	a := b.actionCache[cacheKey{mode, p}]
+	if a == nil {
+		a = f()
+		b.actionCache[cacheKey{mode, p}] = a
+	}
+	return a
+}
+
+// AutoAction returns the "right" action for go build or go install of p.
+func (b *Builder) AutoAction(mode, depMode BuildMode, p *load.Package) *Action {
+	if p.Name == "main" {
+		return b.LinkAction(mode, depMode, p)
+	}
+	return b.CompileAction(mode, depMode, p)
+}
+
+// CompileAction returns the action for compiling and possibly installing
+// (according to mode) the given package. The resulting action is only
+// for building packages (archives), never for linking executables.
+// depMode is the action (build or install) to use when building dependencies.
+// To turn package main into an executable, call b.Link instead.
+func (b *Builder) CompileAction(mode, depMode BuildMode, p *load.Package) *Action {
+	if mode != ModeBuild && p.Internal.Local && p.Target == "" {
+		// Imported via local path. No permanent target.
+		mode = ModeBuild
+	}
+	if mode != ModeBuild && p.Name == "main" {
+		// We never install the .a file for a main package.
+		mode = ModeBuild
+	}
+
+	// Construct package build action.
+	a := b.cacheAction("build", p, func() *Action {
+		a := &Action{
+			Mode:    "build",
+			Package: p,
+			Func:    (*Builder).build,
+			Objdir:  b.NewObjdir(),
+		}
+
+		for _, p1 := range p.Internal.Imports {
+			a.Deps = append(a.Deps, b.CompileAction(depMode, depMode, p1))
+		}
+
+		if p.Standard {
+			switch p.ImportPath {
+			case "builtin", "unsafe":
+				// Fake packages - nothing to build.
+				a.Mode = "built-in package"
+				a.Func = nil
+				return a
+			}
+
+			// gccgo standard library is "fake" too.
+			if cfg.BuildToolchainName == "gccgo" {
+				// the target name is needed for cgo.
+				a.Mode = "gccgo stdlib"
+				a.Target = p.Target
+				a.Func = nil
+				return a
+			}
+		}
+
+		return a
+	})
+
+	// Construct install action.
+	if mode == ModeInstall || mode == ModeBuggyInstall {
+		a = b.installAction(a, mode)
+	}
+
+	return a
+}
+
+// VetAction returns the action for running go vet on package p.
+// It depends on the action for compiling p.
+// If the caller may be causing p to be installed, it is up to the caller
+// to make sure that the install depends on (runs after) vet.
+func (b *Builder) VetAction(mode, depMode BuildMode, p *load.Package) *Action {
+	// Construct vet action.
+	a := b.cacheAction("vet", p, func() *Action {
+		a1 := b.CompileAction(mode, depMode, p)
+
+		// vet expects to be able to import "fmt".
+		var stk load.ImportStack
+		stk.Push("vet")
+		p1 := load.LoadPackage("fmt", &stk)
+		stk.Pop()
+		aFmt := b.CompileAction(ModeBuild, depMode, p1)
+
+		a := &Action{
+			Mode:    "vet",
+			Package: p,
+			Deps:    []*Action{a1, aFmt},
+			Objdir:  a1.Objdir,
+		}
+		if a1.Func == nil {
+			// Built-in packages like unsafe.
+			return a
+		}
+		a1.needVet = true
+		a.Func = (*Builder).vet
+
+		return a
+	})
+	return a
+}
+
+// LinkAction returns the action for linking p into an executable
+// and possibly installing the result (according to mode).
+// depMode is the action (build or install) to use when compiling dependencies.
+func (b *Builder) LinkAction(mode, depMode BuildMode, p *load.Package) *Action {
+	// Construct link action.
+	a := b.cacheAction("link", p, func() *Action {
+		a := &Action{
+			Mode:    "link",
+			Package: p,
+		}
+
+		a1 := b.CompileAction(ModeBuild, depMode, p)
+		a.Func = (*Builder).link
+		a.Deps = []*Action{a1}
+		a.Objdir = a1.Objdir
+
+		// An executable file. (This is the name of a temporary file.)
+		// Because we run the temporary file in 'go run' and 'go test',
+		// the name will show up in ps listings. If the caller has specified
+		// a name, use that instead of a.out. The binary is generated
+		// in an otherwise empty subdirectory named exe to avoid
+		// naming conflicts. The only possible conflict is if we were
+		// to create a top-level package named exe.
+		name := "a.out"
+		if p.Internal.ExeName != "" {
+			name = p.Internal.ExeName
+		} else if (cfg.Goos == "darwin" || cfg.Goos == "windows") && cfg.BuildBuildmode == "c-shared" && p.Target != "" {
+			// On OS X, the linker output name gets recorded in the
+			// shared library's LC_ID_DYLIB load command.
+			// The code invoking the linker knows to pass only the final
+			// path element. Arrange that the path element matches what
+			// we'll install it as; otherwise the library is only loadable as "a.out".
+			// On Windows, DLL file name is recorded in PE file
+			// export section, so do like on OS X.
+			_, name = filepath.Split(p.Target)
+		}
+		a.Target = a.Objdir + filepath.Join("exe", name) + cfg.ExeSuffix
+		a.built = a.Target
+		b.addTransitiveLinkDeps(a, a1, "")
+
+		// Sequence the build of the main package (a1) strictly after the build
+		// of all other dependencies that go into the link. It is likely to be after
+		// them anyway, but just make sure. This is required by the build ID-based
+		// shortcut in (*Builder).useCache(a1), which will call b.linkActionID(a).
+		// In order for that linkActionID call to compute the right action ID, all the
+		// dependencies of a (except a1) must have completed building and have
+		// recorded their build IDs.
+		a1.Deps = append(a1.Deps, &Action{Mode: "nop", Deps: a.Deps[1:]})
+		return a
+	})
+
+	if mode == ModeInstall || mode == ModeBuggyInstall {
+		a = b.installAction(a, mode)
+	}
+
+	return a
+}
+
+// installAction returns the action for installing the result of a1.
+func (b *Builder) installAction(a1 *Action, mode BuildMode) *Action {
+	// Because we overwrite the build action with the install action below,
+	// a1 may already be an install action fetched from the "build" cache key,
+	// and the caller just doesn't realize.
+	if strings.HasSuffix(a1.Mode, "-install") {
+		if a1.buggyInstall && mode == ModeInstall {
+			//  Congratulations! The buggy install is now a proper install.
+			a1.buggyInstall = false
+		}
+		return a1
+	}
+
+	// If there's no actual action to build a1,
+	// there's nothing to install either.
+	// This happens if a1 corresponds to reusing an already-built object.
+	if a1.Func == nil {
+		return a1
+	}
+
+	p := a1.Package
+	return b.cacheAction(a1.Mode+"-install", p, func() *Action {
+		// The install deletes the temporary build result,
+		// so we need all other actions, both past and future,
+		// that attempt to depend on the build to depend instead
+		// on the install.
+
+		// Make a private copy of a1 (the build action),
+		// no longer accessible to any other rules.
+		buildAction := new(Action)
+		*buildAction = *a1
+
+		// Overwrite a1 with the install action.
+		// This takes care of updating past actions that
+		// point at a1 for the build action; now they will
+		// point at a1 and get the install action.
+		// We also leave a1 in the action cache as the result
+		// for "build", so that actions not yet created that
+		// try to depend on the build will instead depend
+		// on the install.
+		*a1 = Action{
+			Mode:    buildAction.Mode + "-install",
+			Func:    BuildInstallFunc,
+			Package: p,
+			Objdir:  buildAction.Objdir,
+			Deps:    []*Action{buildAction},
+			Target:  p.Target,
+			built:   p.Target,
+
+			buggyInstall: mode == ModeBuggyInstall,
+		}
+
+		b.addInstallHeaderAction(a1)
+		return a1
+	})
+}
+
+// addTransitiveLinkDeps adds to the link action a all packages
+// that are transitive dependencies of a1.Deps.
+// That is, if a is a link of package main, a1 is the compile of package main
+// and a1.Deps is the actions for building packages directly imported by
+// package main (what the compiler needs). The linker needs all packages
+// transitively imported by the whole program; addTransitiveLinkDeps
+// makes sure those are present in a.Deps.
+// If shlib is non-empty, then a corresponds to the build and installation of shlib,
+// so any rebuild of shlib should not be added as a dependency.
+func (b *Builder) addTransitiveLinkDeps(a, a1 *Action, shlib string) {
+	// Expand Deps to include all built packages, for the linker.
+	// Use breadth-first search to find rebuilt-for-test packages
+	// before the standard ones.
+	// TODO(rsc): Eliminate the standard ones from the action graph,
+	// which will require doing a little bit more rebuilding.
+	workq := []*Action{a1}
+	haveDep := map[string]bool{}
+	if a1.Package != nil {
+		haveDep[a1.Package.ImportPath] = true
+	}
+	for i := 0; i < len(workq); i++ {
+		a1 := workq[i]
+		for _, a2 := range a1.Deps {
+			// TODO(rsc): Find a better discriminator than the Mode strings, once the dust settles.
+			if a2.Package == nil || (a2.Mode != "build-install" && a2.Mode != "build") || haveDep[a2.Package.ImportPath] {
+				continue
+			}
+			haveDep[a2.Package.ImportPath] = true
+			a.Deps = append(a.Deps, a2)
+			if a2.Mode == "build-install" {
+				a2 = a2.Deps[0] // walk children of "build" action
+			}
+			workq = append(workq, a2)
+		}
+	}
+
+	// If this is go build -linkshared, then the link depends on the shared libraries
+	// in addition to the packages themselves. (The compile steps do not.)
+	if cfg.BuildLinkshared {
+		haveShlib := map[string]bool{shlib: true}
+		for _, a1 := range a.Deps {
+			p1 := a1.Package
+			if p1 == nil || p1.Shlib == "" || haveShlib[filepath.Base(p1.Shlib)] {
+				continue
+			}
+			haveShlib[filepath.Base(p1.Shlib)] = true
+			// TODO(rsc): The use of ModeInstall here is suspect, but if we only do ModeBuild,
+			// we'll end up building an overall library or executable that depends at runtime
+			// on other libraries that are out-of-date, which is clearly not good either.
+			// We call it ModeBuggyInstall to make clear that this is not right.
+			a.Deps = append(a.Deps, b.linkSharedAction(ModeBuggyInstall, ModeBuggyInstall, p1.Shlib, nil))
+		}
+	}
+}
+
+// addInstallHeaderAction adds an install header action to a, if needed.
+// The action a should be an install action as generated by either
+// b.CompileAction or b.LinkAction with mode=ModeInstall,
+// and so a.Deps[0] is the corresponding build action.
+func (b *Builder) addInstallHeaderAction(a *Action) {
+	// Install header for cgo in c-archive and c-shared modes.
+	p := a.Package
+	if p.UsesCgo() && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
+		hdrTarget := a.Target[:len(a.Target)-len(filepath.Ext(a.Target))] + ".h"
+		if cfg.BuildContext.Compiler == "gccgo" {
+			// For the header file, remove the "lib"
+			// added by go/build, so we generate pkg.h
+			// rather than libpkg.h.
+			dir, file := filepath.Split(hdrTarget)
+			file = strings.TrimPrefix(file, "lib")
+			hdrTarget = filepath.Join(dir, file)
+		}
+		ah := &Action{
+			Mode:    "install header",
+			Package: a.Package,
+			Deps:    []*Action{a.Deps[0]},
+			Func:    (*Builder).installHeader,
+			Objdir:  a.Deps[0].Objdir,
+			Target:  hdrTarget,
+		}
+		a.Deps = append(a.Deps, ah)
+	}
+}
+
+// buildmodeShared takes the "go build" action a1 into the building of a shared library of a1.Deps.
+// That is, the input a1 represents "go build pkgs" and the result represents "go build -buidmode=shared pkgs".
+func (b *Builder) buildmodeShared(mode, depMode BuildMode, args []string, pkgs []*load.Package, a1 *Action) *Action {
+	name, err := libname(args, pkgs)
+	if err != nil {
+		base.Fatalf("%v", err)
+	}
+	return b.linkSharedAction(mode, depMode, name, a1)
+}
+
+// linkSharedAction takes a grouping action a1 corresponding to a list of built packages
+// and returns an action that links them together into a shared library with the name shlib.
+// If a1 is nil, shlib should be an absolute path to an existing shared library,
+// and then linkSharedAction reads that library to find out the package list.
+func (b *Builder) linkSharedAction(mode, depMode BuildMode, shlib string, a1 *Action) *Action {
+	fullShlib := shlib
+	shlib = filepath.Base(shlib)
+	a := b.cacheAction("build-shlib "+shlib, nil, func() *Action {
+		if a1 == nil {
+			// TODO(rsc): Need to find some other place to store config,
+			// not in pkg directory. See golang.org/issue/22196.
+			pkgs := readpkglist(fullShlib)
+			a1 = &Action{
+				Mode: "shlib packages",
+			}
+			for _, p := range pkgs {
+				a1.Deps = append(a1.Deps, b.CompileAction(mode, depMode, p))
+			}
+		}
+
+		// Fake package to hold ldflags.
+		// As usual shared libraries are a kludgy, abstraction-violating special case:
+		// we let them use the flags specified for the command-line arguments.
+		p := &load.Package{}
+		p.Internal.CmdlinePkg = true
+		p.Internal.Ldflags = load.BuildLdflags.For(p)
+		p.Internal.Gccgoflags = load.BuildGccgoflags.For(p)
+
+		// Add implicit dependencies to pkgs list.
+		// Currently buildmode=shared forces external linking mode, and
+		// external linking mode forces an import of runtime/cgo (and
+		// math on arm). So if it was not passed on the command line and
+		// it is not present in another shared library, add it here.
+		// TODO(rsc): Maybe this should only happen if "runtime" is in the original package set.
+		// TODO(rsc): This should probably be changed to use load.LinkerDeps(p).
+		// TODO(rsc): We don't add standard library imports for gccgo
+		// because they are all always linked in anyhow.
+		// Maybe load.LinkerDeps should be used and updated.
+		a := &Action{
+			Mode:    "go build -buildmode=shared",
+			Package: p,
+			Objdir:  b.NewObjdir(),
+			Func:    (*Builder).linkShared,
+			Deps:    []*Action{a1},
+		}
+		a.Target = filepath.Join(a.Objdir, shlib)
+		if cfg.BuildToolchainName != "gccgo" {
+			add := func(a1 *Action, pkg string, force bool) {
+				for _, a2 := range a1.Deps {
+					if a2.Package != nil && a2.Package.ImportPath == pkg {
+						return
+					}
+				}
+				var stk load.ImportStack
+				p := load.LoadPackage(pkg, &stk)
+				if p.Error != nil {
+					base.Fatalf("load %s: %v", pkg, p.Error)
+				}
+				// Assume that if pkg (runtime/cgo or math)
+				// is already accounted for in a different shared library,
+				// then that shared library also contains runtime,
+				// so that anything we do will depend on that library,
+				// so we don't need to include pkg in our shared library.
+				if force || p.Shlib == "" || filepath.Base(p.Shlib) == pkg {
+					a1.Deps = append(a1.Deps, b.CompileAction(depMode, depMode, p))
+				}
+			}
+			add(a1, "runtime/cgo", false)
+			if cfg.Goarch == "arm" {
+				add(a1, "math", false)
+			}
+
+			// The linker step still needs all the usual linker deps.
+			// (For example, the linker always opens runtime.a.)
+			for _, dep := range load.LinkerDeps(nil) {
+				add(a, dep, true)
+			}
+		}
+		b.addTransitiveLinkDeps(a, a1, shlib)
+		return a
+	})
+
+	// Install result.
+	if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Func != nil {
+		buildAction := a
+
+		a = b.cacheAction("install-shlib "+shlib, nil, func() *Action {
+			// Determine the eventual install target.
+			// The install target is root/pkg/shlib, where root is the source root
+			// in which all the packages lie.
+			// TODO(rsc): Perhaps this cross-root check should apply to the full
+			// transitive package dependency list, not just the ones named
+			// on the command line?
+			pkgDir := a1.Deps[0].Package.Internal.Build.PkgTargetRoot
+			for _, a2 := range a1.Deps {
+				if dir := a2.Package.Internal.Build.PkgTargetRoot; dir != pkgDir {
+					base.Fatalf("installing shared library: cannot use packages %s and %s from different roots %s and %s",
+						a1.Deps[0].Package.ImportPath,
+						a2.Package.ImportPath,
+						pkgDir,
+						dir)
+				}
+			}
+			// TODO(rsc): Find out and explain here why gccgo is different.
+			if cfg.BuildToolchainName == "gccgo" {
+				pkgDir = filepath.Join(pkgDir, "shlibs")
+			}
+			target := filepath.Join(pkgDir, shlib)
+
+			a := &Action{
+				Mode:   "go install -buildmode=shared",
+				Objdir: buildAction.Objdir,
+				Func:   BuildInstallFunc,
+				Deps:   []*Action{buildAction},
+				Target: target,
+			}
+			for _, a2 := range buildAction.Deps[0].Deps {
+				p := a2.Package
+				if p.Target == "" {
+					continue
+				}
+				a.Deps = append(a.Deps, &Action{
+					Mode:    "shlibname",
+					Package: p,
+					Func:    (*Builder).installShlibname,
+					Target:  strings.TrimSuffix(p.Target, ".a") + ".shlibname",
+					Deps:    []*Action{a.Deps[0]},
+				})
+			}
+			return a
+		})
+	}
+
+	return a
+}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 7d667ff..57b7b00 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -5,33 +5,19 @@
 package work
 
 import (
-	"bufio"
-	"bytes"
-	"container/heap"
-	"debug/elf"
 	"errors"
-	"flag"
 	"fmt"
 	"go/build"
-	"io"
-	"io/ioutil"
-	"log"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
-	"regexp"
 	"runtime"
-	"strconv"
 	"strings"
-	"sync"
-	"time"
 
 	"cmd/go/internal/base"
-	"cmd/go/internal/buildid"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
-	"cmd/go/internal/str"
 )
 
 var CmdBuild = &base.Command{
@@ -89,15 +75,15 @@
 	-x
 		print the commands.
 
-	-asmflags 'flag list'
+	-asmflags '[pattern=]arg list'
 		arguments to pass on each go tool asm invocation.
 	-buildmode mode
 		build mode to use. See 'go help buildmode' for more.
 	-compiler name
 		name of compiler to use, as in runtime.Compiler (gccgo or gc).
-	-gccgoflags 'arg list'
+	-gccgoflags '[pattern=]arg list'
 		arguments to pass on each gccgo compiler/linker invocation.
-	-gcflags 'arg list'
+	-gcflags '[pattern=]arg list'
 		arguments to pass on each go tool compile invocation.
 	-installsuffix suffix
 		a suffix to use in the name of the package installation directory,
@@ -106,7 +92,7 @@
 		or, if set explicitly, has _race appended to it. Likewise for the -msan
 		flag. Using a -buildmode option that requires non-default compile flags
 		has a similar effect.
-	-ldflags 'flag list'
+	-ldflags '[pattern=]arg list'
 		arguments to pass on each go tool link invocation.
 	-linkshared
 		link against shared libraries previously created with
@@ -124,9 +110,21 @@
 		For example, instead of running asm, the go command will run
 		'cmd args /path/to/asm <arguments for asm>'.
 
-All the flags that take a list of arguments accept a space-separated
-list of strings. To embed spaces in an element in the list, surround
-it with either single or double quotes.
+The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
+space-separated list of arguments to pass to an underlying tool
+during the build. To embed spaces in an element in the list, surround
+it with either single or double quotes. The argument list may be
+preceded by a package pattern and an equal sign, which restricts
+the use of that argument list to the building of packages matching
+that pattern (see 'go help packages' for a description of package
+patterns). Without a pattern, the argument list applies only to the
+packages named on the command line. The flags may be repeated
+with different patterns in order to specify different arguments for
+different sets of packages. If a package matches patterns given in
+multiple flags, the latest match on the command line wins.
+For example, 'go build -gcflags=-S fmt' prints the disassembly
+only for package fmt, while 'go build -gcflags=all=-S fmt'
+prints the disassembly for fmt and all its dependencies.
 
 For more about specifying packages, see 'go help packages'.
 For more about where packages and binaries are installed,
@@ -154,6 +152,8 @@
 	CmdBuild.Flag.BoolVar(&cfg.BuildI, "i", false, "")
 	CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file")
 
+	CmdInstall.Flag.BoolVar(&cfg.BuildI, "i", false, "")
+
 	AddBuildFlags(CmdBuild)
 	AddBuildFlags(CmdInstall)
 }
@@ -161,9 +161,12 @@
 // Note that flags consulted by other parts of the code
 // (for example, buildV) are in cmd/go/internal/cfg.
 
-var buildAsmflags []string   // -asmflags flag
-var buildGcflags []string    // -gcflags flag
-var buildGccgoflags []string // -gccgoflags flag
+var (
+	forcedAsmflags   []string // internally-forced flags for cmd/asm
+	forcedGcflags    []string // internally-forced flags for cmd/compile
+	forcedLdflags    []string // internally-forced flags for cmd/link
+	forcedGccgoflags []string // internally-forced flags for gccgo
+)
 
 var BuildToolchain toolchain = noToolchain{}
 var ldBuildmode string
@@ -209,13 +212,13 @@
 	cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
 	cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
 
-	cmd.Flag.Var((*base.StringsFlag)(&buildAsmflags), "asmflags", "")
+	cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "")
 	cmd.Flag.Var(buildCompiler{}, "compiler", "")
 	cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
-	cmd.Flag.Var((*base.StringsFlag)(&buildGcflags), "gcflags", "")
-	cmd.Flag.Var((*base.StringsFlag)(&buildGccgoflags), "gccgoflags", "")
+	cmd.Flag.Var(&load.BuildGcflags, "gcflags", "")
+	cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "")
 	cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
-	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildLdflags), "ldflags", "")
+	cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
 	cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
 	cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
 	cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
@@ -223,6 +226,10 @@
 	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
 	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
 	cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
+
+	// Undocumented, unstable debugging flags.
+	cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
+	cmd.Flag.Var(&load.DebugDeprecatedImportcfg, "debug-deprecated-importcfg", "")
 }
 
 // fileExtSplit expects a filename and returns the name
@@ -264,148 +271,10 @@
 
 var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
 
-func BuildModeInit() {
-	gccgo := cfg.BuildToolchainName == "gccgo"
-	var codegenArg string
-	platform := cfg.Goos + "/" + cfg.Goarch
-	switch cfg.BuildBuildmode {
-	case "archive":
-		pkgsFilter = pkgsNotMain
-	case "c-archive":
-		pkgsFilter = oneMainPkg
-		switch platform {
-		case "darwin/arm", "darwin/arm64":
-			codegenArg = "-shared"
-		default:
-			switch cfg.Goos {
-			case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
-				// Use -shared so that the result is
-				// suitable for inclusion in a PIE or
-				// shared library.
-				codegenArg = "-shared"
-			}
-		}
-		cfg.ExeSuffix = ".a"
-		ldBuildmode = "c-archive"
-	case "c-shared":
-		pkgsFilter = oneMainPkg
-		if gccgo {
-			codegenArg = "-fPIC"
-		} else {
-			switch platform {
-			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386",
-				"android/amd64", "android/arm", "android/arm64", "android/386":
-				codegenArg = "-shared"
-			case "darwin/amd64", "darwin/386":
-			default:
-				base.Fatalf("-buildmode=c-shared not supported on %s\n", platform)
-			}
-		}
-		ldBuildmode = "c-shared"
-	case "default":
-		switch platform {
-		case "android/arm", "android/arm64", "android/amd64", "android/386":
-			codegenArg = "-shared"
-			ldBuildmode = "pie"
-		case "darwin/arm", "darwin/arm64":
-			codegenArg = "-shared"
-			fallthrough
-		default:
-			ldBuildmode = "exe"
-		}
-	case "exe":
-		pkgsFilter = pkgsMain
-		ldBuildmode = "exe"
-	case "pie":
-		if cfg.BuildRace {
-			base.Fatalf("-buildmode=pie not supported when -race is enabled")
-		}
-		if gccgo {
-			base.Fatalf("-buildmode=pie not supported by gccgo")
-		} else {
-			switch platform {
-			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
-				"android/amd64", "android/arm", "android/arm64", "android/386":
-				codegenArg = "-shared"
-			default:
-				base.Fatalf("-buildmode=pie not supported on %s\n", platform)
-			}
-		}
-		ldBuildmode = "pie"
-	case "shared":
-		pkgsFilter = pkgsNotMain
-		if gccgo {
-			codegenArg = "-fPIC"
-		} else {
-			switch platform {
-			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
-			default:
-				base.Fatalf("-buildmode=shared not supported on %s\n", platform)
-			}
-			codegenArg = "-dynlink"
-		}
-		if cfg.BuildO != "" {
-			base.Fatalf("-buildmode=shared and -o not supported together")
-		}
-		ldBuildmode = "shared"
-	case "plugin":
-		pkgsFilter = oneMainPkg
-		if gccgo {
-			codegenArg = "-fPIC"
-		} else {
-			switch platform {
-			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x",
-				"android/amd64", "android/arm", "android/arm64", "android/386":
-			default:
-				base.Fatalf("-buildmode=plugin not supported on %s\n", platform)
-			}
-			codegenArg = "-dynlink"
-		}
-		cfg.ExeSuffix = ".so"
-		ldBuildmode = "plugin"
-	default:
-		base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
-	}
-	if cfg.BuildLinkshared {
-		if gccgo {
-			codegenArg = "-fPIC"
-		} else {
-			switch platform {
-			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
-				buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
-			default:
-				base.Fatalf("-linkshared not supported on %s\n", platform)
-			}
-			codegenArg = "-dynlink"
-			// TODO(mwhudson): remove -w when that gets fixed in linker.
-			cfg.BuildLdflags = append(cfg.BuildLdflags, "-linkshared", "-w")
-		}
-	}
-	if codegenArg != "" {
-		if gccgo {
-			buildGccgoflags = append([]string{codegenArg}, buildGccgoflags...)
-		} else {
-			buildAsmflags = append([]string{codegenArg}, buildAsmflags...)
-			buildGcflags = append([]string{codegenArg}, buildGcflags...)
-		}
-		// Don't alter InstallSuffix when modifying default codegen args.
-		if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
-			if cfg.BuildContext.InstallSuffix != "" {
-				cfg.BuildContext.InstallSuffix += "_"
-			}
-			cfg.BuildContext.InstallSuffix += codegenArg[1:]
-		}
-	}
-	if strings.HasPrefix(runtimeVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") {
-		buildGcflags = append(buildGcflags, "-goversion", runtimeVersion)
-	}
-}
-
 var runtimeVersion = runtime.Version()
 
 func runBuild(cmd *base.Command, args []string) {
-	InstrumentInit()
-	BuildModeInit()
+	BuildInit()
 	var b Builder
 	b.Init()
 
@@ -424,14 +293,14 @@
 	// sanity check some often mis-used options
 	switch cfg.BuildContext.Compiler {
 	case "gccgo":
-		if len(buildGcflags) != 0 {
+		if load.BuildGcflags.Present() {
 			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
 		}
-		if len(cfg.BuildLdflags) != 0 {
+		if load.BuildLdflags.Present() {
 			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
 		}
 	case "gc":
-		if len(buildGccgoflags) != 0 {
+		if load.BuildGccgoflags.Present() {
 			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
 		}
 	}
@@ -441,6 +310,8 @@
 		depMode = ModeInstall
 	}
 
+	pkgs = pkgsFilter(load.Packages(args))
+
 	if cfg.BuildO != "" {
 		if len(pkgs) > 1 {
 			base.Fatalf("go build: cannot use -o with multiple packages")
@@ -448,38 +319,31 @@
 			base.Fatalf("no packages to build")
 		}
 		p := pkgs[0]
-		p.Internal.Target = cfg.BuildO
+		p.Target = cfg.BuildO
 		p.Stale = true // must build - not up to date
 		p.StaleReason = "build -o flag in use"
-		a := b.Action(ModeInstall, depMode, p)
+		a := b.AutoAction(ModeInstall, depMode, p)
 		b.Do(a)
 		return
 	}
 
-	pkgs = pkgsFilter(load.Packages(args))
-
-	var a *Action
+	a := &Action{Mode: "go build"}
+	for _, p := range pkgs {
+		a.Deps = append(a.Deps, b.AutoAction(ModeBuild, depMode, p))
+	}
 	if cfg.BuildBuildmode == "shared" {
-		if libName, err := libname(args, pkgs); err != nil {
-			base.Fatalf("%s", err.Error())
-		} else {
-			a = b.libaction(libName, pkgs, ModeBuild, depMode)
-		}
-	} else {
-		a = &Action{}
-		for _, p := range pkgs {
-			a.Deps = append(a.Deps, b.Action(ModeBuild, depMode, p))
-		}
+		a = b.buildmodeShared(ModeBuild, depMode, args, pkgs, a)
 	}
 	b.Do(a)
 }
 
 var CmdInstall = &base.Command{
-	UsageLine: "install [build flags] [packages]",
+	UsageLine: "install [-i] [build flags] [packages]",
 	Short:     "compile and install packages and dependencies",
 	Long: `
-Install compiles and installs the packages named by the import paths,
-along with their dependencies.
+Install compiles and installs the packages named by the import paths.
+
+The -i flag installs the dependencies of the named packages as well.
 
 For more about the build flags, see 'go help build'.
 For more about specifying packages, see 'go help packages'.
@@ -545,8 +409,7 @@
 }
 
 func runInstall(cmd *base.Command, args []string) {
-	InstrumentInit()
-	BuildModeInit()
+	BuildInit()
 	InstallPackages(args, false)
 }
 
@@ -561,14 +424,14 @@
 		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
 			switch {
 			case p.Internal.GobinSubdir:
-				base.Errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
-			case p.Internal.Cmdline:
-				base.Errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
+				base.Errorf("go %s: cannot install cross-compiled binaries when GOBIN is set", cfg.CmdName)
+			case p.Internal.CmdlineFiles:
+				base.Errorf("go %s: no install location for .go files listed on command line (GOBIN not set)", cfg.CmdName)
 			case p.ConflictDir != "":
-				base.Errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
+				base.Errorf("go %s: no install location for %s: hidden by %s", cfg.CmdName, p.Dir, p.ConflictDir)
 			default:
-				base.Errorf("go install: no install location for directory %s outside GOPATH\n"+
-					"\tFor more details see: 'go help gopath'", p.Dir)
+				base.Errorf("go %s: no install location for directory %s outside GOPATH\n"+
+					"\tFor more details see: 'go help gopath'", cfg.CmdName, p.Dir)
 			}
 		}
 	}
@@ -576,42 +439,46 @@
 
 	var b Builder
 	b.Init()
-	var a *Action
-	if cfg.BuildBuildmode == "shared" {
-		if libName, err := libname(args, pkgs); err != nil {
-			base.Fatalf("%s", err.Error())
-		} else {
-			a = b.libaction(libName, pkgs, ModeInstall, ModeInstall)
+	depMode := ModeBuild
+	if cfg.BuildI {
+		depMode = ModeInstall
+	}
+	a := &Action{Mode: "go install"}
+	var tools []*Action
+	for _, p := range pkgs {
+		// During 'go get', don't attempt (and fail) to install packages with only tests.
+		// TODO(rsc): It's not clear why 'go get' should be different from 'go install' here. See #20760.
+		if forGet && len(p.GoFiles)+len(p.CgoFiles) == 0 && len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
+			continue
 		}
-	} else {
-		a = &Action{}
-		var tools []*Action
-		for _, p := range pkgs {
-			// During 'go get', don't attempt (and fail) to install packages with only tests.
-			// TODO(rsc): It's not clear why 'go get' should be different from 'go install' here. See #20760.
-			if forGet && len(p.GoFiles)+len(p.CgoFiles) == 0 && len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
-				continue
-			}
-			// If p is a tool, delay the installation until the end of the build.
-			// This avoids installing assemblers/compilers that are being executed
-			// by other steps in the build.
-			// cmd/cgo is handled specially in b.Action, so that we can
-			// both build and use it in the same 'go install'.
-			Action := b.Action(ModeInstall, ModeInstall, p)
-			if load.GoTools[p.ImportPath] == load.ToTool && p.ImportPath != "cmd/cgo" {
-				a.Deps = append(a.Deps, Action.Deps...)
-				Action.Deps = append(Action.Deps, a)
-				tools = append(tools, Action)
-				continue
-			}
-			a.Deps = append(a.Deps, Action)
+		// If p is a tool, delay the installation until the end of the build.
+		// This avoids installing assemblers/compilers that are being executed
+		// by other steps in the build.
+		a1 := b.AutoAction(ModeInstall, depMode, p)
+		if load.InstallTargetDir(p) == load.ToTool {
+			a.Deps = append(a.Deps, a1.Deps...)
+			a1.Deps = append(a1.Deps, a)
+			tools = append(tools, a1)
+			continue
 		}
-		if len(tools) > 0 {
-			a = &Action{
-				Deps: tools,
-			}
+		a.Deps = append(a.Deps, a1)
+	}
+	if len(tools) > 0 {
+		a = &Action{
+			Mode: "go install (tools)",
+			Deps: tools,
 		}
 	}
+
+	if cfg.BuildBuildmode == "shared" {
+		// Note: If buildmode=shared then only non-main packages
+		// are present in the pkgs list, so all the special case code about
+		// tools above did not apply, and a is just a simple Action
+		// with a list of Deps, one per package named in pkgs,
+		// the same as in runBuild.
+		a = b.buildmodeShared(ModeInstall, ModeInstall, args, pkgs, a)
+	}
+
 	b.Do(a)
 	base.ExitIfErrors()
 
@@ -643,3208 +510,6 @@
 	}
 }
 
-// A Builder holds global state about a build.
-// It does not hold per-package state, because we
-// build packages in parallel, and the builder is shared.
-type Builder struct {
-	WorkDir     string               // the temporary work directory (ends in filepath.Separator)
-	actionCache map[cacheKey]*Action // a cache of already-constructed actions
-	mkdirCache  map[string]bool      // a cache of created directories
-	flagCache   map[string]bool      // a cache of supported compiler flags
-	Print       func(args ...interface{}) (int, error)
-
-	output    sync.Mutex
-	scriptDir string // current directory in printed script
-
-	exec      sync.Mutex
-	readySema chan bool
-	ready     actionQueue
-}
-
-// NOTE: Much of Action would not need to be exported if not for test.
-// Maybe test functionality should move into this package too?
-
-// An Action represents a single action in the action graph.
-type Action struct {
-	Package    *load.Package                 // the package this action works on
-	Deps       []*Action                     // actions that must happen before this one
-	Func       func(*Builder, *Action) error // the action itself (nil = no-op)
-	IgnoreFail bool                          // whether to run f even if dependencies fail
-	TestOutput *bytes.Buffer                 // test output buffer
-	Args       []string                      // additional args for runProgram
-
-	triggers []*Action // inverse of deps
-	cgo      *Action   // action for cgo binary if needed
-
-	// Generated files, directories.
-	Link   bool   // target is executable, not just package
-	Pkgdir string // the -I or -L argument to use when importing this package
-	Objdir string // directory for intermediate objects
-	Objpkg string // the intermediate package .a file created during the action
-	Target string // goal of the action: the created package or executable
-
-	// Execution state.
-	pending  int  // number of deps yet to complete
-	priority int  // relative execution priority
-	Failed   bool // whether the action failed
-}
-
-// cacheKey is the key for the action cache.
-type cacheKey struct {
-	mode  BuildMode
-	p     *load.Package
-	shlib string
-}
-
-// BuildMode specifies the build mode:
-// are we just building things or also installing the results?
-type BuildMode int
-
-const (
-	ModeBuild BuildMode = iota
-	ModeInstall
-)
-
-func (b *Builder) Init() {
-	var err error
-	b.Print = func(a ...interface{}) (int, error) {
-		return fmt.Fprint(os.Stderr, a...)
-	}
-	b.actionCache = make(map[cacheKey]*Action)
-	b.mkdirCache = make(map[string]bool)
-
-	if cfg.BuildN {
-		b.WorkDir = "$WORK"
-	} else {
-		b.WorkDir, err = ioutil.TempDir("", "go-build")
-		if err != nil {
-			base.Fatalf("%s", err)
-		}
-		if cfg.BuildX || cfg.BuildWork {
-			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir)
-		}
-		if !cfg.BuildWork {
-			workdir := b.WorkDir
-			base.AtExit(func() { os.RemoveAll(workdir) })
-		}
-	}
-}
-
-// readpkglist returns the list of packages that were built into the shared library
-// at shlibpath. For the native toolchain this list is stored, newline separated, in
-// an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
-// .go_export section.
-func readpkglist(shlibpath string) (pkgs []*load.Package) {
-	var stk load.ImportStack
-	if cfg.BuildToolchainName == "gccgo" {
-		f, _ := elf.Open(shlibpath)
-		sect := f.Section(".go_export")
-		data, _ := sect.Data()
-		scanner := bufio.NewScanner(bytes.NewBuffer(data))
-		for scanner.Scan() {
-			t := scanner.Text()
-			if strings.HasPrefix(t, "pkgpath ") {
-				t = strings.TrimPrefix(t, "pkgpath ")
-				t = strings.TrimSuffix(t, ";")
-				pkgs = append(pkgs, load.LoadPackage(t, &stk))
-			}
-		}
-	} else {
-		pkglistbytes, err := buildid.ReadELFNote(shlibpath, "Go\x00\x00", 1)
-		if err != nil {
-			base.Fatalf("readELFNote failed: %v", err)
-		}
-		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
-		for scanner.Scan() {
-			t := scanner.Text()
-			pkgs = append(pkgs, load.LoadPackage(t, &stk))
-		}
-	}
-	return
-}
-
-// Action returns the action for applying the given operation (mode) to the package.
-// depMode is the action to use when building dependencies.
-// action never looks for p in a shared library, but may find p's dependencies in a
-// shared library if buildLinkshared is true.
-func (b *Builder) Action(mode BuildMode, depMode BuildMode, p *load.Package) *Action {
-	return b.action1(mode, depMode, p, false, "")
-}
-
-// action1 returns the action for applying the given operation (mode) to the package.
-// depMode is the action to use when building dependencies.
-// action1 will look for p in a shared library if lookshared is true.
-// forShlib is the shared library that p will become part of, if any.
-func (b *Builder) action1(mode BuildMode, depMode BuildMode, p *load.Package, lookshared bool, forShlib string) *Action {
-	shlib := ""
-	if lookshared {
-		shlib = p.Shlib
-	}
-	key := cacheKey{mode, p, shlib}
-
-	a := b.actionCache[key]
-	if a != nil {
-		return a
-	}
-	if shlib != "" {
-		key2 := cacheKey{ModeInstall, nil, shlib}
-		a = b.actionCache[key2]
-		if a != nil {
-			b.actionCache[key] = a
-			return a
-		}
-		pkgs := readpkglist(shlib)
-		a = b.libaction(filepath.Base(shlib), pkgs, ModeInstall, depMode)
-		b.actionCache[key2] = a
-		b.actionCache[key] = a
-		return a
-	}
-
-	a = &Action{Package: p, Pkgdir: p.Internal.Build.PkgRoot}
-	if p.Internal.Pkgdir != "" { // overrides p.t
-		a.Pkgdir = p.Internal.Pkgdir
-	}
-	b.actionCache[key] = a
-
-	for _, p1 := range p.Internal.Imports {
-		if forShlib != "" {
-			// p is part of a shared library.
-			if p1.Shlib != "" && p1.Shlib != forShlib {
-				// p1 is explicitly part of a different shared library.
-				// Put the action for that shared library into a.Deps.
-				a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, true, p1.Shlib))
-			} else {
-				// p1 is (implicitly or not) part of this shared library.
-				// Put the action for p1 into a.Deps.
-				a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, false, forShlib))
-			}
-		} else {
-			// p is not part of a shared library.
-			// If p1 is in a shared library, put the action for that into
-			// a.Deps, otherwise put the action for p1 into a.Deps.
-			a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, cfg.BuildLinkshared, p1.Shlib))
-		}
-	}
-
-	// If we are not doing a cross-build, then record the binary we'll
-	// generate for cgo as a dependency of the build of any package
-	// using cgo, to make sure we do not overwrite the binary while
-	// a package is using it. If this is a cross-build, then the cgo we
-	// are writing is not the cgo we need to use.
-	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan {
-		if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !cfg.BuildLinkshared && cfg.BuildBuildmode != "shared" {
-			var stk load.ImportStack
-			p1 := load.LoadPackage("cmd/cgo", &stk)
-			if p1.Error != nil {
-				base.Fatalf("load cmd/cgo: %v", p1.Error)
-			}
-			a.cgo = b.Action(depMode, depMode, p1)
-			a.Deps = append(a.Deps, a.cgo)
-		}
-	}
-
-	if p.Standard {
-		switch p.ImportPath {
-		case "builtin", "unsafe":
-			// Fake packages - nothing to build.
-			return a
-		}
-		// gccgo standard library is "fake" too.
-		if cfg.BuildToolchainName == "gccgo" {
-			// the target name is needed for cgo.
-			a.Target = p.Internal.Target
-			return a
-		}
-	}
-
-	if !p.Stale && p.Internal.Target != "" {
-		// p.Stale==false implies that p.Internal.Target is up-to-date.
-		// Record target name for use by actions depending on this one.
-		a.Target = p.Internal.Target
-		return a
-	}
-
-	if p.Internal.Local && p.Internal.Target == "" {
-		// Imported via local path. No permanent target.
-		mode = ModeBuild
-	}
-	work := p.Internal.Pkgdir
-	if work == "" {
-		work = b.WorkDir
-	}
-	a.Objdir = filepath.Join(work, a.Package.ImportPath, "_obj") + string(filepath.Separator)
-	a.Objpkg = BuildToolchain.Pkgpath(work, a.Package)
-	a.Link = p.Name == "main"
-
-	switch mode {
-	case ModeInstall:
-		a.Func = BuildInstallFunc
-		a.Deps = []*Action{b.action1(ModeBuild, depMode, p, lookshared, forShlib)}
-		a.Target = a.Package.Internal.Target
-
-		// Install header for cgo in c-archive and c-shared modes.
-		if p.UsesCgo() && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
-			hdrTarget := a.Target[:len(a.Target)-len(filepath.Ext(a.Target))] + ".h"
-			if cfg.BuildContext.Compiler == "gccgo" {
-				// For the header file, remove the "lib"
-				// added by go/build, so we generate pkg.h
-				// rather than libpkg.h.
-				dir, file := filepath.Split(hdrTarget)
-				file = strings.TrimPrefix(file, "lib")
-				hdrTarget = filepath.Join(dir, file)
-			}
-			ah := &Action{
-				Package: a.Package,
-				Deps:    []*Action{a.Deps[0]},
-				Func:    (*Builder).installHeader,
-				Pkgdir:  a.Pkgdir,
-				Objdir:  a.Objdir,
-				Target:  hdrTarget,
-			}
-			a.Deps = append(a.Deps, ah)
-		}
-
-	case ModeBuild:
-		a.Func = (*Builder).build
-		a.Target = a.Objpkg
-		if a.Link {
-			// An executable file. (This is the name of a temporary file.)
-			// Because we run the temporary file in 'go run' and 'go test',
-			// the name will show up in ps listings. If the caller has specified
-			// a name, use that instead of a.out. The binary is generated
-			// in an otherwise empty subdirectory named exe to avoid
-			// naming conflicts. The only possible conflict is if we were
-			// to create a top-level package named exe.
-			name := "a.out"
-			if p.Internal.ExeName != "" {
-				name = p.Internal.ExeName
-			} else if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" && p.Internal.Target != "" {
-				// On OS X, the linker output name gets recorded in the
-				// shared library's LC_ID_DYLIB load command.
-				// The code invoking the linker knows to pass only the final
-				// path element. Arrange that the path element matches what
-				// we'll install it as; otherwise the library is only loadable as "a.out".
-				_, name = filepath.Split(p.Internal.Target)
-			}
-			a.Target = a.Objdir + filepath.Join("exe", name) + cfg.ExeSuffix
-		}
-	}
-
-	return a
-}
-
-func (b *Builder) libaction(libname string, pkgs []*load.Package, mode, depMode BuildMode) *Action {
-	a := &Action{}
-	switch mode {
-	default:
-		base.Fatalf("unrecognized mode %v", mode)
-
-	case ModeBuild:
-		a.Func = (*Builder).linkShared
-		a.Target = filepath.Join(b.WorkDir, libname)
-		for _, p := range pkgs {
-			if p.Internal.Target == "" {
-				continue
-			}
-			a.Deps = append(a.Deps, b.Action(depMode, depMode, p))
-		}
-
-	case ModeInstall:
-		// Currently build mode shared forces external linking mode, and
-		// external linking mode forces an import of runtime/cgo (and
-		// math on arm). So if it was not passed on the command line and
-		// it is not present in another shared library, add it here.
-		gccgo := cfg.BuildToolchainName == "gccgo"
-		if !gccgo {
-			seencgo := false
-			for _, p := range pkgs {
-				seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
-			}
-			if !seencgo {
-				var stk load.ImportStack
-				p := load.LoadPackage("runtime/cgo", &stk)
-				if p.Error != nil {
-					base.Fatalf("load runtime/cgo: %v", p.Error)
-				}
-				load.ComputeStale(p)
-				// If runtime/cgo is in another shared library, then that's
-				// also the shared library that contains runtime, so
-				// something will depend on it and so runtime/cgo's staleness
-				// will be checked when processing that library.
-				if p.Shlib == "" || p.Shlib == libname {
-					pkgs = append([]*load.Package{}, pkgs...)
-					pkgs = append(pkgs, p)
-				}
-			}
-			if cfg.Goarch == "arm" {
-				seenmath := false
-				for _, p := range pkgs {
-					seenmath = seenmath || (p.Standard && p.ImportPath == "math")
-				}
-				if !seenmath {
-					var stk load.ImportStack
-					p := load.LoadPackage("math", &stk)
-					if p.Error != nil {
-						base.Fatalf("load math: %v", p.Error)
-					}
-					load.ComputeStale(p)
-					// If math is in another shared library, then that's
-					// also the shared library that contains runtime, so
-					// something will depend on it and so math's staleness
-					// will be checked when processing that library.
-					if p.Shlib == "" || p.Shlib == libname {
-						pkgs = append([]*load.Package{}, pkgs...)
-						pkgs = append(pkgs, p)
-					}
-				}
-			}
-		}
-
-		// Figure out where the library will go.
-		var libdir string
-		for _, p := range pkgs {
-			plibdir := p.Internal.Build.PkgTargetRoot
-			if gccgo {
-				plibdir = filepath.Join(plibdir, "shlibs")
-			}
-			if libdir == "" {
-				libdir = plibdir
-			} else if libdir != plibdir {
-				base.Fatalf("multiple roots %s & %s", libdir, plibdir)
-			}
-		}
-		a.Target = filepath.Join(libdir, libname)
-
-		// Now we can check whether we need to rebuild it.
-		stale := false
-		var built time.Time
-		if fi, err := os.Stat(a.Target); err == nil {
-			built = fi.ModTime()
-		}
-		for _, p := range pkgs {
-			if p.Internal.Target == "" {
-				continue
-			}
-			stale = stale || p.Stale
-			lstat, err := os.Stat(p.Internal.Target)
-			if err != nil || lstat.ModTime().After(built) {
-				stale = true
-			}
-			a.Deps = append(a.Deps, b.action1(depMode, depMode, p, false, a.Target))
-		}
-
-		if stale {
-			a.Func = BuildInstallFunc
-			buildAction := b.libaction(libname, pkgs, ModeBuild, depMode)
-			a.Deps = []*Action{buildAction}
-			for _, p := range pkgs {
-				if p.Internal.Target == "" {
-					continue
-				}
-				shlibnameaction := &Action{}
-				shlibnameaction.Func = (*Builder).installShlibname
-				shlibnameaction.Target = p.Internal.Target[:len(p.Internal.Target)-2] + ".shlibname"
-				a.Deps = append(a.Deps, shlibnameaction)
-				shlibnameaction.Deps = append(shlibnameaction.Deps, buildAction)
-			}
-		}
-	}
-	return a
-}
-
-// ActionList returns the list of actions in the dag rooted at root
-// as visited in a depth-first post-order traversal.
-func ActionList(root *Action) []*Action {
-	seen := map[*Action]bool{}
-	all := []*Action{}
-	var walk func(*Action)
-	walk = func(a *Action) {
-		if seen[a] {
-			return
-		}
-		seen[a] = true
-		for _, a1 := range a.Deps {
-			walk(a1)
-		}
-		all = append(all, a)
-	}
-	walk(root)
-	return all
-}
-
-// allArchiveActions returns a list of the archive dependencies of root.
-// This is needed because if package p depends on package q that is in libr.so, the
-// action graph looks like p->libr.so->q and so just scanning through p's
-// dependencies does not find the import dir for q.
-func allArchiveActions(root *Action) []*Action {
-	seen := map[*Action]bool{}
-	r := []*Action{}
-	var walk func(*Action)
-	walk = func(a *Action) {
-		if seen[a] {
-			return
-		}
-		seen[a] = true
-		if strings.HasSuffix(a.Target, ".so") || a == root {
-			for _, a1 := range a.Deps {
-				walk(a1)
-			}
-		} else if strings.HasSuffix(a.Target, ".a") {
-			r = append(r, a)
-		}
-	}
-	walk(root)
-	return r
-}
-
-// do runs the action graph rooted at root.
-func (b *Builder) Do(root *Action) {
-	if _, ok := cfg.OSArchSupportsCgo[cfg.Goos+"/"+cfg.Goarch]; !ok && cfg.BuildContext.Compiler == "gc" {
-		fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", cfg.Goos, cfg.Goarch)
-		os.Exit(2)
-	}
-	for _, tag := range cfg.BuildContext.BuildTags {
-		if strings.Contains(tag, ",") {
-			fmt.Fprintf(os.Stderr, "cmd/go: -tags space-separated list contains comma\n")
-			os.Exit(2)
-		}
-	}
-
-	// Build list of all actions, assigning depth-first post-order priority.
-	// The original implementation here was a true queue
-	// (using a channel) but it had the effect of getting
-	// distracted by low-level leaf actions to the detriment
-	// of completing higher-level actions. The order of
-	// work does not matter much to overall execution time,
-	// but when running "go test std" it is nice to see each test
-	// results as soon as possible. The priorities assigned
-	// ensure that, all else being equal, the execution prefers
-	// to do what it would have done first in a simple depth-first
-	// dependency order traversal.
-	all := ActionList(root)
-	for i, a := range all {
-		a.priority = i
-	}
-
-	b.readySema = make(chan bool, len(all))
-
-	// Initialize per-action execution state.
-	for _, a := range all {
-		for _, a1 := range a.Deps {
-			a1.triggers = append(a1.triggers, a)
-		}
-		a.pending = len(a.Deps)
-		if a.pending == 0 {
-			b.ready.push(a)
-			b.readySema <- true
-		}
-	}
-
-	// Handle runs a single action and takes care of triggering
-	// any actions that are runnable as a result.
-	handle := func(a *Action) {
-		var err error
-		if a.Func != nil && (!a.Failed || a.IgnoreFail) {
-			err = a.Func(b, a)
-		}
-
-		// The actions run in parallel but all the updates to the
-		// shared work state are serialized through b.exec.
-		b.exec.Lock()
-		defer b.exec.Unlock()
-
-		if err != nil {
-			if err == errPrintedOutput {
-				base.SetExitStatus(2)
-			} else {
-				base.Errorf("%s", err)
-			}
-			a.Failed = true
-		}
-
-		for _, a0 := range a.triggers {
-			if a.Failed {
-				a0.Failed = true
-			}
-			if a0.pending--; a0.pending == 0 {
-				b.ready.push(a0)
-				b.readySema <- true
-			}
-		}
-
-		if a == root {
-			close(b.readySema)
-		}
-	}
-
-	var wg sync.WaitGroup
-
-	// Kick off goroutines according to parallelism.
-	// If we are using the -n flag (just printing commands)
-	// drop the parallelism to 1, both to make the output
-	// deterministic and because there is no real work anyway.
-	par := cfg.BuildP
-	if cfg.BuildN {
-		par = 1
-	}
-	for i := 0; i < par; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			for {
-				select {
-				case _, ok := <-b.readySema:
-					if !ok {
-						return
-					}
-					// Receiving a value from b.readySema entitles
-					// us to take from the ready queue.
-					b.exec.Lock()
-					a := b.ready.pop()
-					b.exec.Unlock()
-					handle(a)
-				case <-base.Interrupted:
-					base.SetExitStatus(1)
-					return
-				}
-			}
-		}()
-	}
-
-	wg.Wait()
-}
-
-// build is the action for building a single package or command.
-func (b *Builder) build(a *Action) (err error) {
-	// Return an error for binary-only package.
-	// We only reach this if isStale believes the binary form is
-	// either not present or not usable.
-	if a.Package.BinaryOnly {
-		return fmt.Errorf("missing or invalid package binary for binary-only package %s", a.Package.ImportPath)
-	}
-
-	// Return an error if the package has CXX files but it's not using
-	// cgo nor SWIG, since the CXX files can only be processed by cgo
-	// and SWIG.
-	if len(a.Package.CXXFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
-		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
-			a.Package.ImportPath, strings.Join(a.Package.CXXFiles, ","))
-	}
-	// Same as above for Objective-C files
-	if len(a.Package.MFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
-		return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
-			a.Package.ImportPath, strings.Join(a.Package.MFiles, ","))
-	}
-	// Same as above for Fortran files
-	if len(a.Package.FFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
-		return fmt.Errorf("can't build package %s because it contains Fortran files (%s) but it's not using cgo nor SWIG",
-			a.Package.ImportPath, strings.Join(a.Package.FFiles, ","))
-	}
-
-	defer func() {
-		if err != nil && err != errPrintedOutput {
-			err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
-		}
-	}()
-	if cfg.BuildN {
-		// In -n mode, print a banner between packages.
-		// The banner is five lines so that when changes to
-		// different sections of the bootstrap script have to
-		// be merged, the banners give patch something
-		// to use to find its context.
-		b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
-	}
-
-	if cfg.BuildV {
-		b.Print(a.Package.ImportPath + "\n")
-	}
-
-	// Make build directory.
-	obj := a.Objdir
-	if err := b.Mkdir(obj); err != nil {
-		return err
-	}
-
-	// make target directory
-	dir, _ := filepath.Split(a.Target)
-	if dir != "" {
-		if err := b.Mkdir(dir); err != nil {
-			return err
-		}
-	}
-
-	var gofiles, cgofiles, objdirCgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
-
-	gofiles = append(gofiles, a.Package.GoFiles...)
-	cgofiles = append(cgofiles, a.Package.CgoFiles...)
-	cfiles = append(cfiles, a.Package.CFiles...)
-	sfiles = append(sfiles, a.Package.SFiles...)
-	cxxfiles = append(cxxfiles, a.Package.CXXFiles...)
-
-	if a.Package.UsesCgo() || a.Package.UsesSwig() {
-		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
-			return
-		}
-	}
-
-	// Run SWIG on each .swig and .swigcxx file.
-	// Each run will generate two files, a .go file and a .c or .cxx file.
-	// The .go file will use import "C" and is to be processed by cgo.
-	if a.Package.UsesSwig() {
-		outGo, outC, outCXX, err := b.swig(a.Package, obj, pcCFLAGS)
-		if err != nil {
-			return err
-		}
-		objdirCgofiles = append(objdirCgofiles, outGo...)
-		cfiles = append(cfiles, outC...)
-		cxxfiles = append(cxxfiles, outCXX...)
-	}
-
-	// Run cgo.
-	if a.Package.UsesCgo() || a.Package.UsesSwig() {
-		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
-		// There is one exception: runtime/cgo's job is to bridge the
-		// cgo and non-cgo worlds, so it necessarily has files in both.
-		// In that case gcc only gets the gcc_* files.
-		var gccfiles []string
-		gccfiles = append(gccfiles, cfiles...)
-		cfiles = nil
-		if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
-			filter := func(files, nongcc, gcc []string) ([]string, []string) {
-				for _, f := range files {
-					if strings.HasPrefix(f, "gcc_") {
-						gcc = append(gcc, f)
-					} else {
-						nongcc = append(nongcc, f)
-					}
-				}
-				return nongcc, gcc
-			}
-			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
-		} else {
-			for _, sfile := range sfiles {
-				data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
-				if err == nil {
-					if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
-						bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
-						bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) {
-						return fmt.Errorf("package using cgo has Go assembly file %s", sfile)
-					}
-				}
-			}
-			gccfiles = append(gccfiles, sfiles...)
-			sfiles = nil
-		}
-
-		var cgoExe string
-		if a.cgo != nil && a.cgo.Target != "" {
-			cgoExe = a.cgo.Target
-		} else {
-			cgoExe = base.Tool("cgo")
-		}
-		outGo, outObj, err := b.cgo(a, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
-		if err != nil {
-			return err
-		}
-		if cfg.BuildToolchainName == "gccgo" {
-			cgoObjects = append(cgoObjects, filepath.Join(a.Objdir, "_cgo_flags"))
-		}
-		cgoObjects = append(cgoObjects, outObj...)
-		gofiles = append(gofiles, outGo...)
-	}
-
-	if len(gofiles) == 0 {
-		return &load.NoGoError{Package: a.Package}
-	}
-
-	// If we're doing coverage, preprocess the .go files and put them in the work directory
-	if a.Package.Internal.CoverMode != "" {
-		for i, file := range gofiles {
-			var sourceFile string
-			var coverFile string
-			var key string
-			if strings.HasSuffix(file, ".cgo1.go") {
-				// cgo files have absolute paths
-				base := filepath.Base(file)
-				sourceFile = file
-				coverFile = filepath.Join(obj, base)
-				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
-			} else {
-				sourceFile = filepath.Join(a.Package.Dir, file)
-				coverFile = filepath.Join(obj, file)
-				key = file
-			}
-			cover := a.Package.Internal.CoverVars[key]
-			if cover == nil || base.IsTestFile(file) {
-				// Not covering this file.
-				continue
-			}
-			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
-				return err
-			}
-			gofiles[i] = coverFile
-		}
-	}
-
-	// Prepare Go import path list.
-	inc := b.includeArgs("-I", allArchiveActions(a))
-
-	// Compile Go.
-	ofile, out, err := BuildToolchain.gc(b, a.Package, a.Objpkg, obj, len(sfiles) > 0, inc, gofiles)
-	if len(out) > 0 {
-		b.showOutput(a.Package.Dir, a.Package.ImportPath, b.processOutput(out))
-		if err != nil {
-			return errPrintedOutput
-		}
-	}
-	if err != nil {
-		return err
-	}
-	if ofile != a.Objpkg {
-		objects = append(objects, ofile)
-	}
-
-	// Copy .h files named for goos or goarch or goos_goarch
-	// to names using GOOS and GOARCH.
-	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
-	_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
-	_goos := "_" + cfg.Goos
-	_goarch := "_" + cfg.Goarch
-	for _, file := range a.Package.HFiles {
-		name, ext := fileExtSplit(file)
-		switch {
-		case strings.HasSuffix(name, _goos_goarch):
-			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
-				return err
-			}
-		case strings.HasSuffix(name, _goarch):
-			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
-				return err
-			}
-		case strings.HasSuffix(name, _goos):
-			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
-				return err
-			}
-		}
-	}
-
-	for _, file := range cfiles {
-		out := file[:len(file)-len(".c")] + ".o"
-		if err := BuildToolchain.cc(b, a.Package, obj, obj+out, file); err != nil {
-			return err
-		}
-		objects = append(objects, out)
-	}
-
-	// Assemble .s files.
-	if len(sfiles) > 0 {
-		ofiles, err := BuildToolchain.asm(b, a.Package, obj, sfiles)
-		if err != nil {
-			return err
-		}
-		objects = append(objects, ofiles...)
-	}
-
-	// NOTE(rsc): On Windows, it is critically important that the
-	// gcc-compiled objects (cgoObjects) be listed after the ordinary
-	// objects in the archive. I do not know why this is.
-	// https://golang.org/issue/2601
-	objects = append(objects, cgoObjects...)
-
-	// Add system object files.
-	for _, syso := range a.Package.SysoFiles {
-		objects = append(objects, filepath.Join(a.Package.Dir, syso))
-	}
-
-	// Pack into archive in obj directory.
-	// If the Go compiler wrote an archive, we only need to add the
-	// object files for non-Go sources to the archive.
-	// If the Go compiler wrote an archive and the package is entirely
-	// Go sources, there is no pack to execute at all.
-	if len(objects) > 0 {
-		if err := BuildToolchain.pack(b, a.Package, obj, a.Objpkg, objects); err != nil {
-			return err
-		}
-	}
-
-	// Link if needed.
-	if a.Link {
-		// The compiler only cares about direct imports, but the
-		// linker needs the whole dependency tree.
-		all := ActionList(a)
-		all = all[:len(all)-1] // drop a
-		if err := BuildToolchain.ld(b, a, a.Target, all, a.Objpkg, objects); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// PkgconfigCmd returns a pkg-config binary name
-// defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
-func (b *Builder) PkgconfigCmd() string {
-	return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0]
-}
-
-// splitPkgConfigOutput parses the pkg-config output into a slice of
-// flags. pkg-config always uses \ to escape special characters.
-func splitPkgConfigOutput(out []byte) []string {
-	if len(out) == 0 {
-		return nil
-	}
-	var flags []string
-	flag := make([]byte, len(out))
-	r, w := 0, 0
-	for r < len(out) {
-		switch out[r] {
-		case ' ', '\t', '\r', '\n':
-			if w > 0 {
-				flags = append(flags, string(flag[:w]))
-			}
-			w = 0
-		case '\\':
-			r++
-			fallthrough
-		default:
-			if r < len(out) {
-				flag[w] = out[r]
-				w++
-			}
-		}
-		r++
-	}
-	if w > 0 {
-		flags = append(flags, string(flag[:w]))
-	}
-	return flags
-}
-
-// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
-func (b *Builder) getPkgConfigFlags(p *load.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, b.PkgconfigCmd(), "--cflags", pkgs)
-		if err != nil {
-			b.showOutput(p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out))
-			b.Print(err.Error() + "\n")
-			err = errPrintedOutput
-			return
-		}
-		if len(out) > 0 {
-			cflags = splitPkgConfigOutput(out)
-		}
-		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pkgs)
-		if err != nil {
-			b.showOutput(p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out))
-			b.Print(err.Error() + "\n")
-			err = errPrintedOutput
-			return
-		}
-		if len(out) > 0 {
-			ldflags = strings.Fields(string(out))
-		}
-	}
-	return
-}
-
-func (b *Builder) installShlibname(a *Action) error {
-	a1 := a.Deps[0]
-	err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
-	if err != nil {
-		return err
-	}
-	if cfg.BuildX {
-		b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target)
-	}
-	return nil
-}
-
-func (b *Builder) linkShared(a *Action) (err error) {
-	allactions := ActionList(a)
-	allactions = allactions[:len(allactions)-1]
-	return BuildToolchain.ldShared(b, a.Deps, a.Target, allactions)
-}
-
-// BuildInstallFunc is the action for installing a single package or executable.
-func BuildInstallFunc(b *Builder, a *Action) (err error) {
-	defer func() {
-		if err != nil && err != errPrintedOutput {
-			err = fmt.Errorf("go install %s: %v", a.Package.ImportPath, err)
-		}
-	}()
-	a1 := a.Deps[0]
-	perm := os.FileMode(0666)
-	if a1.Link {
-		switch cfg.BuildBuildmode {
-		case "c-archive", "c-shared", "plugin":
-		default:
-			perm = 0777
-		}
-	}
-
-	// make target directory
-	dir, _ := filepath.Split(a.Target)
-	if dir != "" {
-		if err := b.Mkdir(dir); err != nil {
-			return err
-		}
-	}
-
-	// remove object dir to keep the amount of
-	// garbage down in a large build. On an operating system
-	// with aggressive buffering, cleaning incrementally like
-	// this keeps the intermediate objects from hitting the disk.
-	if !cfg.BuildWork {
-		defer os.RemoveAll(a1.Objdir)
-		defer os.Remove(a1.Target)
-	}
-
-	return b.moveOrCopyFile(a, a.Target, a1.Target, perm, false)
-}
-
-// includeArgs returns the -I or -L directory list for access
-// to the results of the list of actions.
-func (b *Builder) includeArgs(flag string, all []*Action) []string {
-	inc := []string{}
-	incMap := map[string]bool{
-		b.WorkDir:     true, // handled later
-		cfg.GOROOTpkg: true,
-		"":            true, // ignore empty strings
-	}
-
-	// Look in the temporary space for results of test-specific actions.
-	// This is the $WORK/my/package/_test directory for the
-	// package being built, so there are few of these.
-	for _, a1 := range all {
-		if a1.Package == nil {
-			continue
-		}
-		if dir := a1.Pkgdir; dir != a1.Package.Internal.Build.PkgRoot && !incMap[dir] {
-			incMap[dir] = true
-			inc = append(inc, flag, dir)
-		}
-	}
-
-	// Also look in $WORK for any non-test packages that have
-	// been built but not installed.
-	inc = append(inc, flag, b.WorkDir)
-
-	// Finally, look in the installed package directories for each action.
-	// First add the package dirs corresponding to GOPATH entries
-	// in the original GOPATH order.
-	need := map[string]*build.Package{}
-	for _, a1 := range all {
-		if a1.Package != nil && a1.Pkgdir == a1.Package.Internal.Build.PkgRoot {
-			need[a1.Package.Internal.Build.Root] = a1.Package.Internal.Build
-		}
-	}
-	for _, root := range cfg.Gopath {
-		if p := need[root]; p != nil && !incMap[p.PkgRoot] {
-			incMap[p.PkgRoot] = true
-			inc = append(inc, flag, p.PkgTargetRoot)
-		}
-	}
-
-	// Then add anything that's left.
-	for _, a1 := range all {
-		if a1.Package == nil {
-			continue
-		}
-		if dir := a1.Pkgdir; dir == a1.Package.Internal.Build.PkgRoot && !incMap[dir] {
-			incMap[dir] = true
-			inc = append(inc, flag, a1.Package.Internal.Build.PkgTargetRoot)
-		}
-	}
-
-	return inc
-}
-
-// moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
-func (b *Builder) moveOrCopyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
-	if cfg.BuildN {
-		b.Showcmd("", "mv %s %s", src, dst)
-		return nil
-	}
-
-	// If we can update the mode and rename to the dst, do it.
-	// Otherwise fall back to standard copy.
-
-	// If the destination directory has the group sticky bit set,
-	// we have to copy the file to retain the correct permissions.
-	// https://golang.org/issue/18878
-	if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
-		if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
-			return b.copyFile(a, dst, src, perm, force)
-		}
-	}
-
-	// The perm argument is meant to be adjusted according to umask,
-	// but we don't know what the umask is.
-	// Create a dummy file to find out.
-	// This avoids build tags and works even on systems like Plan 9
-	// where the file mask computation incorporates other information.
-	mode := perm
-	f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
-	if err == nil {
-		fi, err := f.Stat()
-		if err == nil {
-			mode = fi.Mode() & 0777
-		}
-		name := f.Name()
-		f.Close()
-		os.Remove(name)
-	}
-
-	if err := os.Chmod(src, mode); err == nil {
-		if err := os.Rename(src, dst); err == nil {
-			if cfg.BuildX {
-				b.Showcmd("", "mv %s %s", src, dst)
-			}
-			return nil
-		}
-	}
-
-	return b.copyFile(a, dst, src, perm, force)
-}
-
-// copyFile is like 'cp src dst'.
-func (b *Builder) copyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
-	if cfg.BuildN || cfg.BuildX {
-		b.Showcmd("", "cp %s %s", src, dst)
-		if cfg.BuildN {
-			return nil
-		}
-	}
-
-	sf, err := os.Open(src)
-	if err != nil {
-		return err
-	}
-	defer sf.Close()
-
-	// Be careful about removing/overwriting dst.
-	// Do not remove/overwrite if dst exists and is a directory
-	// or a non-object file.
-	if fi, err := os.Stat(dst); err == nil {
-		if fi.IsDir() {
-			return fmt.Errorf("build output %q already exists and is a directory", dst)
-		}
-		if !force && fi.Mode().IsRegular() && !isObject(dst) {
-			return fmt.Errorf("build output %q already exists and is not an object file", dst)
-		}
-	}
-
-	// On Windows, remove lingering ~ file from last attempt.
-	if base.ToolIsWindows {
-		if _, err := os.Stat(dst + "~"); err == nil {
-			os.Remove(dst + "~")
-		}
-	}
-
-	mayberemovefile(dst)
-	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
-	if err != nil && base.ToolIsWindows {
-		// Windows does not allow deletion of a binary file
-		// while it is executing. Try to move it out of the way.
-		// If the move fails, which is likely, we'll try again the
-		// next time we do an install of this binary.
-		if err := os.Rename(dst, dst+"~"); err == nil {
-			os.Remove(dst + "~")
-		}
-		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
-	}
-	if err != nil {
-		return err
-	}
-
-	_, err = io.Copy(df, sf)
-	df.Close()
-	if err != nil {
-		mayberemovefile(dst)
-		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
-	}
-	return nil
-}
-
-// Install the cgo export header file, if there is one.
-func (b *Builder) installHeader(a *Action) error {
-	src := a.Objdir + "_cgo_install.h"
-	if _, err := os.Stat(src); os.IsNotExist(err) {
-		// If the file does not exist, there are no exported
-		// functions, and we do not install anything.
-		return nil
-	}
-
-	dir, _ := filepath.Split(a.Target)
-	if dir != "" {
-		if err := b.Mkdir(dir); err != nil {
-			return err
-		}
-	}
-
-	return b.moveOrCopyFile(a, a.Target, src, 0666, true)
-}
-
-// cover runs, in effect,
-//	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
-func (b *Builder) cover(a *Action, dst, src string, perm os.FileMode, varName string) error {
-	return b.run(a.Objdir, "cover "+a.Package.ImportPath, nil,
-		cfg.BuildToolexec,
-		base.Tool("cover"),
-		"-mode", a.Package.Internal.CoverMode,
-		"-var", varName,
-		"-o", dst,
-		src)
-}
-
-var objectMagic = [][]byte{
-	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
-	{'\x7F', 'E', 'L', 'F'},                   // ELF
-	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
-	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
-	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
-	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
-	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
-	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
-	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
-	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
-}
-
-func isObject(s string) bool {
-	f, err := os.Open(s)
-	if err != nil {
-		return false
-	}
-	defer f.Close()
-	buf := make([]byte, 64)
-	io.ReadFull(f, buf)
-	for _, magic := range objectMagic {
-		if bytes.HasPrefix(buf, magic) {
-			return true
-		}
-	}
-	return false
-}
-
-// mayberemovefile removes a file only if it is a regular file
-// When running as a user with sufficient privileges, we may delete
-// even device files, for example, which is not intended.
-func mayberemovefile(s string) {
-	if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
-		return
-	}
-	os.Remove(s)
-}
-
-// fmtcmd formats a command in the manner of fmt.Sprintf but also:
-//
-//	If dir is non-empty and the script is not in dir right now,
-//	fmtcmd inserts "cd dir\n" before the command.
-//
-//	fmtcmd replaces the value of b.WorkDir with $WORK.
-//	fmtcmd replaces the value of goroot with $GOROOT.
-//	fmtcmd replaces the value of b.gobin with $GOBIN.
-//
-//	fmtcmd replaces the name of the current directory with dot (.)
-//	but only when it is at the beginning of a space-separated token.
-//
-func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string {
-	cmd := fmt.Sprintf(format, args...)
-	if dir != "" && dir != "/" {
-		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
-		if b.scriptDir != dir {
-			b.scriptDir = dir
-			cmd = "cd " + dir + "\n" + cmd
-		}
-	}
-	if b.WorkDir != "" {
-		cmd = strings.Replace(cmd, b.WorkDir, "$WORK", -1)
-	}
-	return cmd
-}
-
-// showcmd prints the given command to standard output
-// for the implementation of -n or -x.
-func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
-	b.output.Lock()
-	defer b.output.Unlock()
-	b.Print(b.fmtcmd(dir, format, args...) + "\n")
-}
-
-// showOutput prints "# desc" followed by the given output.
-// The output is expected to contain references to 'dir', usually
-// the source directory for the package that has failed to build.
-// 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/html,
-// the output is
-//
-//	$ go build
-//	# fmt
-//	../fmt/print.go:1090: undefined: asdf
-//	$
-//
-// instead of
-//
-//	$ go build
-//	# fmt
-//	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
-//	$
-//
-// showOutput also replaces references to the work directory with $WORK.
-//
-func (b *Builder) showOutput(dir, desc, out string) {
-	prefix := "# " + desc
-	suffix := "\n" + out
-	if reldir := base.ShortPath(dir); reldir != dir {
-		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
-		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
-	}
-	suffix = strings.Replace(suffix, " "+b.WorkDir, " $WORK", -1)
-
-	b.output.Lock()
-	defer b.output.Unlock()
-	b.Print(prefix, suffix)
-}
-
-// errPrintedOutput is a special error indicating that a command failed
-// but that it generated output as well, and that output has already
-// been printed, so there's no point showing 'exit status 1' or whatever
-// the wait status was. The main executor, builder.do, knows not to
-// print this error.
-var errPrintedOutput = errors.New("already printed output - no need to show error")
-
-var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+(:[0-9]+)?\]`)
-var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
-
-// run runs the command given by cmdline in the directory dir.
-// If the command fails, run prints information about the failure
-// and returns a non-nil error.
-func (b *Builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
-	out, err := b.runOut(dir, desc, env, cmdargs...)
-	if len(out) > 0 {
-		if desc == "" {
-			desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
-		}
-		b.showOutput(dir, desc, b.processOutput(out))
-		if err != nil {
-			err = errPrintedOutput
-		}
-	}
-	return err
-}
-
-// processOutput prepares the output of runOut to be output to the console.
-func (b *Builder) processOutput(out []byte) string {
-	if out[len(out)-1] != '\n' {
-		out = append(out, '\n')
-	}
-	messages := string(out)
-	// Fix up output referring to cgo-generated code to be more readable.
-	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
-	// Replace *[100]_Ctype_foo with *[100]C.foo.
-	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
-	if !cfg.BuildX && cgoLine.MatchString(messages) {
-		messages = cgoLine.ReplaceAllString(messages, "")
-		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
-	}
-	return messages
-}
-
-// runOut runs the command given by cmdline in the directory dir.
-// It returns the command output and any errors that occurred.
-func (b *Builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
-	cmdline := str.StringList(cmdargs...)
-	if cfg.BuildN || cfg.BuildX {
-		var envcmdline string
-		for i := range env {
-			envcmdline += env[i]
-			envcmdline += " "
-		}
-		envcmdline += joinUnambiguously(cmdline)
-		b.Showcmd(dir, "%s", envcmdline)
-		if cfg.BuildN {
-			return nil, nil
-		}
-	}
-
-	nbusy := 0
-	for {
-		var buf bytes.Buffer
-		cmd := exec.Command(cmdline[0], cmdline[1:]...)
-		cmd.Stdout = &buf
-		cmd.Stderr = &buf
-		cmd.Dir = dir
-		cmd.Env = base.MergeEnvLists(env, base.EnvForDir(cmd.Dir, os.Environ()))
-		err := cmd.Run()
-
-		// cmd.Run will fail on Unix if some other process has the binary
-		// we want to run open for writing. This can happen here because
-		// we build and install the cgo command and then run it.
-		// If another command was kicked off while we were writing the
-		// cgo binary, the child process for that command may be holding
-		// a reference to the fd, keeping us from running exec.
-		//
-		// But, you might reasonably wonder, how can this happen?
-		// The cgo fd, like all our fds, is close-on-exec, so that we need
-		// not worry about other processes inheriting the fd accidentally.
-		// The answer is that running a command is fork and exec.
-		// A child forked while the cgo fd is open inherits that fd.
-		// Until the child has called exec, it holds the fd open and the
-		// kernel will not let us run cgo. Even if the child were to close
-		// the fd explicitly, it would still be open from the time of the fork
-		// until the time of the explicit close, and the race would remain.
-		//
-		// On Unix systems, this results in ETXTBSY, which formats
-		// as "text file busy". Rather than hard-code specific error cases,
-		// we just look for that string. If this happens, sleep a little
-		// and try again. We let this happen three times, with increasing
-		// sleep lengths: 100+200+400 ms = 0.7 seconds.
-		//
-		// An alternate solution might be to split the cmd.Run into
-		// separate cmd.Start and cmd.Wait, and then use an RWLock
-		// to make sure that copyFile only executes when no cmd.Start
-		// call is in progress. However, cmd.Start (really syscall.forkExec)
-		// only guarantees that when it returns, the exec is committed to
-		// happen and succeed. It uses a close-on-exec file descriptor
-		// itself to determine this, so we know that when cmd.Start returns,
-		// at least one close-on-exec file descriptor has been closed.
-		// However, we cannot be sure that all of them have been closed,
-		// so the program might still encounter ETXTBSY even with such
-		// an RWLock. The race window would be smaller, perhaps, but not
-		// guaranteed to be gone.
-		//
-		// Sleeping when we observe the race seems to be the most reliable
-		// option we have.
-		//
-		// https://golang.org/issue/3001
-		//
-		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
-			time.Sleep(100 * time.Millisecond << uint(nbusy))
-			nbusy++
-			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
-	}
-}
-
-// joinUnambiguously prints the slice, quoting where necessary to make the
-// output unambiguous.
-// TODO: See issue 5279. The printing of commands needs a complete redo.
-func joinUnambiguously(a []string) string {
-	var buf bytes.Buffer
-	for i, s := range a {
-		if i > 0 {
-			buf.WriteByte(' ')
-		}
-		q := strconv.Quote(s)
-		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
-			buf.WriteString(q)
-		} else {
-			buf.WriteString(s)
-		}
-	}
-	return buf.String()
-}
-
-// mkdir makes the named directory.
-func (b *Builder) Mkdir(dir string) error {
-	b.exec.Lock()
-	defer b.exec.Unlock()
-	// We can be a little aggressive about being
-	// sure directories exist. Skip repeated calls.
-	if b.mkdirCache[dir] {
-		return nil
-	}
-	b.mkdirCache[dir] = true
-
-	if cfg.BuildN || cfg.BuildX {
-		b.Showcmd("", "mkdir -p %s", dir)
-		if cfg.BuildN {
-			return nil
-		}
-	}
-
-	if err := os.MkdirAll(dir, 0777); err != nil {
-		return err
-	}
-	return nil
-}
-
-// mkAbs returns an absolute path corresponding to
-// evaluating f in the directory dir.
-// We always pass absolute paths of source files so that
-// the error messages will include the full path to a file
-// in need of attention.
-func mkAbs(dir, f string) string {
-	// Leave absolute paths alone.
-	// Also, during -n mode we use the pseudo-directory $WORK
-	// instead of creating an actual work directory that won't be used.
-	// Leave paths beginning with $WORK alone too.
-	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
-		return f
-	}
-	return filepath.Join(dir, f)
-}
-
-type toolchain interface {
-	// gc runs the compiler in a specific directory on a set of files
-	// and returns the name of the generated output file.
-	gc(b *Builder, p *load.Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
-	// cc runs the toolchain's C compiler in a directory on a C file
-	// to produce an output file.
-	cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error
-	// asm runs the assembler in a specific directory on specific files
-	// and returns a list of named output files.
-	asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error)
-	// pkgpath builds an appropriate path for a temporary package file.
-	Pkgpath(basedir string, p *load.Package) string
-	// pack runs the archive packer in a specific directory to create
-	// an archive from a set of object files.
-	// typically it is run in the object directory.
-	pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error
-	// ld runs the linker to create an executable starting at mainpkg.
-	ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error
-	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
-	ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error
-
-	compiler() string
-	linker() string
-}
-
-type noToolchain struct{}
-
-func noCompiler() error {
-	log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
-	return nil
-}
-
-func (noToolchain) compiler() string {
-	noCompiler()
-	return ""
-}
-
-func (noToolchain) linker() string {
-	noCompiler()
-	return ""
-}
-
-func (noToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
-	return "", nil, noCompiler()
-}
-
-func (noToolchain) asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error) {
-	return nil, noCompiler()
-}
-
-func (noToolchain) Pkgpath(basedir string, p *load.Package) string {
-	noCompiler()
-	return ""
-}
-
-func (noToolchain) pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error {
-	return noCompiler()
-}
-
-func (noToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
-	return noCompiler()
-}
-
-func (noToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
-	return noCompiler()
-}
-
-func (noToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
-	return noCompiler()
-}
-
-// The Go toolchain.
-type gcToolchain struct{}
-
-func (gcToolchain) compiler() string {
-	return base.Tool("compile")
-}
-
-func (gcToolchain) linker() string {
-	return base.Tool("link")
-}
-
-func (gcToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
-	if archive != "" {
-		ofile = archive
-	} else {
-		out := "_go_.o"
-		ofile = obj + out
-	}
-
-	gcargs := []string{"-p", p.ImportPath}
-	if p.Name == "main" {
-		gcargs[1] = "main"
-	}
-	if p.Standard {
-		gcargs = append(gcargs, "-std")
-	}
-	compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal"))
-	if compilingRuntime {
-		// runtime compiles with a special gc flag to emit
-		// additional reflect type data.
-		gcargs = append(gcargs, "-+")
-	}
-
-	// If we're giving the compiler the entire package (no C etc files), tell it that,
-	// so that it can give good error messages about forward declarations.
-	// Exceptions: a few standard packages have forward declarations for
-	// pieces supplied behind-the-scenes by package runtime.
-	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
-	if p.Standard {
-		switch p.ImportPath {
-		case "bytes", "internal/poll", "net", "os", "runtime/pprof", "sync", "syscall", "time":
-			extFiles++
-		}
-	}
-	if extFiles == 0 {
-		gcargs = append(gcargs, "-complete")
-	}
-	if cfg.BuildContext.InstallSuffix != "" {
-		gcargs = append(gcargs, "-installsuffix", cfg.BuildContext.InstallSuffix)
-	}
-	if p.Internal.BuildID != "" {
-		gcargs = append(gcargs, "-buildid", p.Internal.BuildID)
-	}
-	platform := cfg.Goos + "/" + cfg.Goarch
-	if p.Internal.OmitDebug || platform == "nacl/amd64p32" || platform == "darwin/arm" || platform == "darwin/arm64" || cfg.Goos == "plan9" {
-		gcargs = append(gcargs, "-dwarf=false")
-	}
-
-	for _, path := range p.Imports {
-		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
-			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
-		} else if strings.HasPrefix(path, "vendor/") {
-			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
-		}
-	}
-
-	gcflags := buildGcflags
-	if compilingRuntime {
-		// Remove -N, if present.
-		// It is not possible to build the runtime with no optimizations,
-		// because the compiler cannot eliminate enough write barriers.
-		gcflags = make([]string, len(buildGcflags))
-		copy(gcflags, buildGcflags)
-		for i := 0; i < len(gcflags); i++ {
-			if gcflags[i] == "-N" {
-				copy(gcflags[i:], gcflags[i+1:])
-				gcflags = gcflags[:len(gcflags)-1]
-				i--
-			}
-		}
-	}
-	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", b.WorkDir, gcflags, gcargs, "-D", p.Internal.LocalPrefix, importArgs}
-	if ofile == archive {
-		args = append(args, "-pack")
-	}
-	if asmhdr {
-		args = append(args, "-asmhdr", obj+"go_asm.h")
-	}
-
-	// Add -c=N to use concurrent backend compilation, if possible.
-	if c := gcBackendConcurrency(gcflags); c > 1 {
-		args = append(args, fmt.Sprintf("-c=%d", c))
-	}
-
-	for _, f := range gofiles {
-		args = append(args, mkAbs(p.Dir, f))
-	}
-
-	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
-	return ofile, output, err
-}
-
-// gcBackendConcurrency returns the backend compiler concurrency level for a package compilation.
-func gcBackendConcurrency(gcflags []string) int {
-	// First, check whether we can use -c at all for this compilation.
-	canDashC := concurrentGCBackendCompilationEnabledByDefault
-
-	switch e := os.Getenv("GO19CONCURRENTCOMPILATION"); e {
-	case "0":
-		canDashC = false
-	case "1":
-		canDashC = true
-	case "":
-		// Not set. Use default.
-	default:
-		log.Fatalf("GO19CONCURRENTCOMPILATION must be 0, 1, or unset, got %q", e)
-	}
-
-	if os.Getenv("GOEXPERIMENT") != "" {
-		// Concurrent compilation is presumed incompatible with GOEXPERIMENTs.
-		canDashC = false
-	}
-
-CheckFlags:
-	for _, flag := range gcflags {
-		// Concurrent compilation is presumed incompatible with any gcflags,
-		// except for a small whitelist of commonly used flags.
-		// If the user knows better, they can manually add their own -c to the gcflags.
-		switch flag {
-		case "-N", "-l", "-S", "-B", "-C", "-I":
-			// OK
-		default:
-			canDashC = false
-			break CheckFlags
-		}
-	}
-
-	if !canDashC {
-		return 1
-	}
-
-	// Decide how many concurrent backend compilations to allow.
-	//
-	// If we allow too many, in theory we might end up with p concurrent processes,
-	// each with c concurrent backend compiles, all fighting over the same resources.
-	// However, in practice, that seems not to happen too much.
-	// Most build graphs are surprisingly serial, so p==1 for much of the build.
-	// Furthermore, concurrent backend compilation is only enabled for a part
-	// of the overall compiler execution, so c==1 for much of the build.
-	// So don't worry too much about that interaction for now.
-	//
-	// However, in practice, setting c above 4 tends not to help very much.
-	// See the analysis in CL 41192.
-	//
-	// TODO(josharian): attempt to detect whether this particular compilation
-	// is likely to be a bottleneck, e.g. when:
-	//   - it has no successor packages to compile (usually package main)
-	//   - all paths through the build graph pass through it
-	//   - critical path scheduling says it is high priority
-	// and in such a case, set c to runtime.NumCPU.
-	// We do this now when p==1.
-	if cfg.BuildP == 1 {
-		// No process parallelism. Max out c.
-		return runtime.NumCPU()
-	}
-	// Some process parallelism. Set c to min(4, numcpu).
-	c := 4
-	if ncpu := runtime.NumCPU(); ncpu < c {
-		c = ncpu
-	}
-	return c
-}
-
-func (gcToolchain) asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error) {
-	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
-	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
-	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", b.WorkDir, "-I", obj, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
-	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
-		for _, arg := range buildAsmflags {
-			if arg == "-dynlink" {
-				args = append(args, "-D=GOBUILDMODE_shared=1")
-			}
-		}
-	}
-	var ofiles []string
-	for _, sfile := range sfiles {
-		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
-		ofiles = append(ofiles, ofile)
-		a := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
-		if err := b.run(p.Dir, p.ImportPath, nil, a...); err != nil {
-			return nil, err
-		}
-	}
-	return ofiles, nil
-}
-
-// toolVerify checks that the command line args writes the same output file
-// if run using newTool instead.
-// Unused now but kept around for future use.
-func toolVerify(b *Builder, p *load.Package, newTool string, ofile string, args []interface{}) error {
-	newArgs := make([]interface{}, len(args))
-	copy(newArgs, args)
-	newArgs[1] = base.Tool(newTool)
-	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
-	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
-		return err
-	}
-	data1, err := ioutil.ReadFile(ofile)
-	if err != nil {
-		return err
-	}
-	data2, err := ioutil.ReadFile(ofile + ".new")
-	if err != nil {
-		return err
-	}
-	if !bytes.Equal(data1, data2) {
-		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(str.StringList(args...), " "), strings.Join(str.StringList(newArgs...), " "))
-	}
-	os.Remove(ofile + ".new")
-	return nil
-}
-
-func (gcToolchain) Pkgpath(basedir string, p *load.Package) string {
-	end := filepath.FromSlash(p.ImportPath + ".a")
-	return filepath.Join(basedir, end)
-}
-
-func (gcToolchain) pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error {
-	var absOfiles []string
-	for _, f := range ofiles {
-		absOfiles = append(absOfiles, mkAbs(objDir, f))
-	}
-	absAfile := mkAbs(objDir, afile)
-
-	// The archive file should have been created by the compiler.
-	// Since it used to not work that way, verify.
-	if !cfg.BuildN {
-		if _, err := os.Stat(absAfile); err != nil {
-			base.Fatalf("os.Stat of archive file failed: %v", err)
-		}
-	}
-
-	if cfg.BuildN || cfg.BuildX {
-		cmdline := str.StringList("pack", "r", absAfile, absOfiles)
-		b.Showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
-	}
-	if cfg.BuildN {
-		return nil
-	}
-	if err := packInternal(b, absAfile, absOfiles); err != nil {
-		b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
-		return errPrintedOutput
-	}
-	return nil
-}
-
-func packInternal(b *Builder, afile string, ofiles []string) error {
-	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
-	if err != nil {
-		return err
-	}
-	defer dst.Close() // only for error returns or panics
-	w := bufio.NewWriter(dst)
-
-	for _, ofile := range ofiles {
-		src, err := os.Open(ofile)
-		if err != nil {
-			return err
-		}
-		fi, err := src.Stat()
-		if err != nil {
-			src.Close()
-			return err
-		}
-		// Note: Not using %-16.16s format because we care
-		// about bytes, not runes.
-		name := fi.Name()
-		if len(name) > 16 {
-			name = name[:16]
-		} else {
-			name += strings.Repeat(" ", 16-len(name))
-		}
-		size := fi.Size()
-		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
-			name, 0, 0, 0, 0644, size)
-		n, err := io.Copy(w, src)
-		src.Close()
-		if err == nil && n < size {
-			err = io.ErrUnexpectedEOF
-		} else if err == nil && n > size {
-			err = fmt.Errorf("file larger than size reported by stat")
-		}
-		if err != nil {
-			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
-		}
-		if size&1 != 0 {
-			w.WriteByte(0)
-		}
-	}
-
-	if err := w.Flush(); err != nil {
-		return err
-	}
-	return dst.Close()
-}
-
-// setextld sets the appropriate linker flags for the specified compiler.
-func setextld(ldflags []string, compiler []string) []string {
-	for _, f := range ldflags {
-		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
-			// don't override -extld if supplied
-			return ldflags
-		}
-	}
-	ldflags = append(ldflags, "-extld="+compiler[0])
-	if len(compiler) > 1 {
-		extldflags := false
-		add := strings.Join(compiler[1:], " ")
-		for i, f := range ldflags {
-			if f == "-extldflags" && i+1 < len(ldflags) {
-				ldflags[i+1] = add + " " + ldflags[i+1]
-				extldflags = true
-				break
-			} else if strings.HasPrefix(f, "-extldflags=") {
-				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
-				extldflags = true
-				break
-			}
-		}
-		if !extldflags {
-			ldflags = append(ldflags, "-extldflags="+add)
-		}
-	}
-	return ldflags
-}
-
-func (gcToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
-	importArgs := b.includeArgs("-L", allactions)
-	cxx := len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
-	for _, a := range allactions {
-		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
-			cxx = true
-		}
-	}
-	var ldflags []string
-	if cfg.BuildContext.InstallSuffix != "" {
-		ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
-	}
-	if root.Package.Internal.OmitDebug {
-		ldflags = append(ldflags, "-s", "-w")
-	}
-	if cfg.BuildBuildmode == "plugin" {
-		pluginpath := root.Package.ImportPath
-		if pluginpath == "command-line-arguments" {
-			pluginpath = "plugin/unnamed-" + root.Package.Internal.BuildID
-		}
-		ldflags = append(ldflags, "-pluginpath", pluginpath)
-	}
-
-	// If the user has not specified the -extld option, then specify the
-	// appropriate linker. In case of C++ code, use the compiler named
-	// by the CXX environment variable or defaultCXX if CXX is not set.
-	// Else, use the CC environment variable and defaultCC as fallback.
-	var compiler []string
-	if cxx {
-		compiler = envList("CXX", cfg.DefaultCXX)
-	} else {
-		compiler = envList("CC", cfg.DefaultCC)
-	}
-	ldflags = setextld(ldflags, compiler)
-	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
-	if root.Package.Internal.BuildID != "" {
-		ldflags = append(ldflags, "-buildid="+root.Package.Internal.BuildID)
-	}
-	ldflags = append(ldflags, cfg.BuildLdflags...)
-
-	// On OS X when using external linking to build a shared library,
-	// the argument passed here to -o ends up recorded in the final
-	// shared library in the LC_ID_DYLIB load command.
-	// To avoid putting the temporary output directory name there
-	// (and making the resulting shared library useless),
-	// run the link in the output directory so that -o can name
-	// just the final path element.
-	dir := "."
-	if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" {
-		dir, out = filepath.Split(out)
-	}
-
-	return b.run(dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags, mainpkg)
-}
-
-func (gcToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
-	importArgs := b.includeArgs("-L", allactions)
-	ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
-	ldflags = append(ldflags, "-buildmode=shared")
-	ldflags = append(ldflags, cfg.BuildLdflags...)
-	cxx := false
-	for _, a := range allactions {
-		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
-			cxx = true
-		}
-	}
-	// If the user has not specified the -extld option, then specify the
-	// appropriate linker. In case of C++ code, use the compiler named
-	// by the CXX environment variable or defaultCXX if CXX is not set.
-	// Else, use the CC environment variable and defaultCC as fallback.
-	var compiler []string
-	if cxx {
-		compiler = envList("CXX", cfg.DefaultCXX)
-	} else {
-		compiler = envList("CC", cfg.DefaultCC)
-	}
-	ldflags = setextld(ldflags, compiler)
-	for _, d := range toplevelactions {
-		if !strings.HasSuffix(d.Target, ".a") { // omit unsafe etc and actions for other shared libraries
-			continue
-		}
-		ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target)
-	}
-	return b.run(".", out, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags)
-}
-
-func (gcToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
-	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
-}
-
-// The Gccgo toolchain.
-type gccgoToolchain struct{}
-
-var GccgoName, GccgoBin string
-var gccgoErr error
-
-func init() {
-	GccgoName = os.Getenv("GCCGO")
-	if GccgoName == "" {
-		GccgoName = "gccgo"
-	}
-	GccgoBin, gccgoErr = exec.LookPath(GccgoName)
-}
-
-func (gccgoToolchain) compiler() string {
-	checkGccgoBin()
-	return GccgoBin
-}
-
-func (gccgoToolchain) linker() string {
-	checkGccgoBin()
-	return GccgoBin
-}
-
-func checkGccgoBin() {
-	if gccgoErr == nil {
-		return
-	}
-	fmt.Fprintf(os.Stderr, "cmd/go: gccgo: %s\n", gccgoErr)
-	os.Exit(2)
-}
-
-func (tools gccgoToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
-	out := "_go_.o"
-	ofile = obj + out
-	gcargs := []string{"-g"}
-	gcargs = append(gcargs, b.gccArchArgs()...)
-	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
-		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
-	}
-	if p.Internal.LocalPrefix != "" {
-		gcargs = append(gcargs, "-fgo-relative-import-path="+p.Internal.LocalPrefix)
-	}
-
-	// Handle vendor directories
-	savedirs := []string{}
-	for _, incdir := range importArgs {
-		if incdir != "-I" {
-			savedirs = append(savedirs, incdir)
-		}
-	}
-
-	for _, path := range p.Imports {
-		// If this is a new vendor path, add it to the list of importArgs
-		if i := strings.LastIndex(path, "/vendor"); i >= 0 {
-			for _, dir := range savedirs {
-				// Check if the vendor path is already included in dir
-				if strings.HasSuffix(dir, path[:i+len("/vendor")]) {
-					continue
-				}
-				// Make sure this vendor path is not already in the list for importArgs
-				vendorPath := dir + "/" + path[:i+len("/vendor")]
-				for _, imp := range importArgs {
-					if imp == "-I" {
-						continue
-					}
-					// This vendorPath is already in the list
-					if imp == vendorPath {
-						goto nextSuffixPath
-					}
-				}
-				// New vendorPath not yet in the importArgs list, so add it
-				importArgs = append(importArgs, "-I", vendorPath)
-			nextSuffixPath:
-			}
-		} else if strings.HasPrefix(path, "vendor/") {
-			for _, dir := range savedirs {
-				// Make sure this vendor path is not already in the list for importArgs
-				vendorPath := dir + "/" + path[len("/vendor"):]
-				for _, imp := range importArgs {
-					if imp == "-I" {
-						continue
-					}
-					if imp == vendorPath {
-						goto nextPrefixPath
-					}
-				}
-				// This vendor path is needed and not already in the list, so add it
-				importArgs = append(importArgs, "-I", vendorPath)
-			nextPrefixPath:
-			}
-		}
-	}
-
-	args := str.StringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
-	for _, f := range gofiles {
-		args = append(args, mkAbs(p.Dir, f))
-	}
-
-	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
-	return ofile, output, err
-}
-
-func (tools gccgoToolchain) asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error) {
-	var ofiles []string
-	for _, sfile := range sfiles {
-		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
-		ofiles = append(ofiles, ofile)
-		sfile = mkAbs(p.Dir, sfile)
-		defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
-		if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
-			defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
-		}
-		defs = tools.maybePIC(defs)
-		defs = append(defs, b.gccArchArgs()...)
-		err := b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return ofiles, nil
-}
-
-func (gccgoToolchain) Pkgpath(basedir string, p *load.Package) string {
-	end := filepath.FromSlash(p.ImportPath + ".a")
-	afile := filepath.Join(basedir, end)
-	// add "lib" to the final element
-	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
-}
-
-func (gccgoToolchain) pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error {
-	var absOfiles []string
-	for _, f := range ofiles {
-		absOfiles = append(absOfiles, mkAbs(objDir, f))
-	}
-	return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles)
-}
-
-func (tools gccgoToolchain) link(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string, buildmode, desc string) error {
-	// gccgo needs explicit linking with all package dependencies,
-	// and all LDFLAGS from cgo dependencies.
-	apackagePathsSeen := make(map[string]bool)
-	afiles := []string{}
-	shlibs := []string{}
-	ldflags := b.gccArchArgs()
-	cgoldflags := []string{}
-	usesCgo := false
-	cxx := false
-	objc := false
-	fortran := false
-	if root.Package != nil {
-		cxx = len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
-		objc = len(root.Package.MFiles) > 0
-		fortran = len(root.Package.FFiles) > 0
-	}
-
-	readCgoFlags := func(flagsFile string) error {
-		flags, err := ioutil.ReadFile(flagsFile)
-		if err != nil {
-			return err
-		}
-		const ldflagsPrefix = "_CGO_LDFLAGS="
-		for _, line := range strings.Split(string(flags), "\n") {
-			if strings.HasPrefix(line, ldflagsPrefix) {
-				newFlags := strings.Fields(line[len(ldflagsPrefix):])
-				for _, flag := range newFlags {
-					// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
-					// but they don't mean anything to the linker so filter
-					// them out.
-					if flag != "-g" && !strings.HasPrefix(flag, "-O") {
-						cgoldflags = append(cgoldflags, flag)
-					}
-				}
-			}
-		}
-		return nil
-	}
-
-	readAndRemoveCgoFlags := func(archive string) (string, error) {
-		newa, err := ioutil.TempFile(b.WorkDir, filepath.Base(archive))
-		if err != nil {
-			return "", err
-		}
-		olda, err := os.Open(archive)
-		if err != nil {
-			return "", err
-		}
-		_, err = io.Copy(newa, olda)
-		if err != nil {
-			return "", err
-		}
-		err = olda.Close()
-		if err != nil {
-			return "", err
-		}
-		err = newa.Close()
-		if err != nil {
-			return "", err
-		}
-
-		newarchive := newa.Name()
-		err = b.run(b.WorkDir, desc, nil, "ar", "x", newarchive, "_cgo_flags")
-		if err != nil {
-			return "", err
-		}
-		err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags")
-		if err != nil {
-			return "", err
-		}
-		err = readCgoFlags(filepath.Join(b.WorkDir, "_cgo_flags"))
-		if err != nil {
-			return "", err
-		}
-		return newarchive, nil
-	}
-
-	actionsSeen := make(map[*Action]bool)
-	// Make a pre-order depth-first traversal of the action graph, taking note of
-	// whether a shared library action has been seen on the way to an action (the
-	// construction of the graph means that if any path to a node passes through
-	// a shared library action, they all do).
-	var walk func(a *Action, seenShlib bool)
-	var err error
-	walk = func(a *Action, seenShlib bool) {
-		if actionsSeen[a] {
-			return
-		}
-		actionsSeen[a] = true
-		if a.Package != nil && !seenShlib {
-			if a.Package.Standard {
-				return
-			}
-			// We record the target of the first time we see a .a file
-			// for a package to make sure that we prefer the 'install'
-			// rather than the 'build' location (which may not exist any
-			// more). We still need to traverse the dependencies of the
-			// build action though so saying
-			// if apackagePathsSeen[a.Package.ImportPath] { return }
-			// doesn't work.
-			if !apackagePathsSeen[a.Package.ImportPath] {
-				apackagePathsSeen[a.Package.ImportPath] = true
-				target := a.Target
-				if len(a.Package.CgoFiles) > 0 || a.Package.UsesSwig() {
-					target, err = readAndRemoveCgoFlags(target)
-					if err != nil {
-						return
-					}
-				}
-				afiles = append(afiles, target)
-			}
-		}
-		if strings.HasSuffix(a.Target, ".so") {
-			shlibs = append(shlibs, a.Target)
-			seenShlib = true
-		}
-		for _, a1 := range a.Deps {
-			walk(a1, seenShlib)
-			if err != nil {
-				return
-			}
-		}
-	}
-	for _, a1 := range root.Deps {
-		walk(a1, false)
-		if err != nil {
-			return err
-		}
-	}
-
-	for _, a := range allactions {
-		// Gather CgoLDFLAGS, but not from standard packages.
-		// The go tool can dig up runtime/cgo from GOROOT and
-		// think that it should use its CgoLDFLAGS, but gccgo
-		// doesn't use runtime/cgo.
-		if a.Package == nil {
-			continue
-		}
-		if !a.Package.Standard {
-			cgoldflags = append(cgoldflags, a.Package.CgoLDFLAGS...)
-		}
-		if len(a.Package.CgoFiles) > 0 {
-			usesCgo = true
-		}
-		if a.Package.UsesSwig() {
-			usesCgo = true
-		}
-		if len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0 {
-			cxx = true
-		}
-		if len(a.Package.MFiles) > 0 {
-			objc = true
-		}
-		if len(a.Package.FFiles) > 0 {
-			fortran = true
-		}
-	}
-
-	for i, o := range ofiles {
-		if filepath.Base(o) == "_cgo_flags" {
-			readCgoFlags(o)
-			ofiles = append(ofiles[:i], ofiles[i+1:]...)
-			break
-		}
-	}
-
-	ldflags = append(ldflags, "-Wl,--whole-archive")
-	ldflags = append(ldflags, afiles...)
-	ldflags = append(ldflags, "-Wl,--no-whole-archive")
-
-	ldflags = append(ldflags, cgoldflags...)
-	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
-	if root.Package != nil {
-		ldflags = append(ldflags, root.Package.CgoLDFLAGS...)
-	}
-
-	ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
-
-	for _, shlib := range shlibs {
-		ldflags = append(
-			ldflags,
-			"-L"+filepath.Dir(shlib),
-			"-Wl,-rpath="+filepath.Dir(shlib),
-			"-l"+strings.TrimSuffix(
-				strings.TrimPrefix(filepath.Base(shlib), "lib"),
-				".so"))
-	}
-
-	var realOut string
-	switch buildmode {
-	case "exe":
-		if usesCgo && cfg.Goos == "linux" {
-			ldflags = append(ldflags, "-Wl,-E")
-		}
-
-	case "c-archive":
-		// Link the Go files into a single .o, and also link
-		// in -lgolibbegin.
-		//
-		// We need to use --whole-archive with -lgolibbegin
-		// because it doesn't define any symbols that will
-		// cause the contents to be pulled in; it's just
-		// initialization code.
-		//
-		// The user remains responsible for linking against
-		// -lgo -lpthread -lm in the final link. We can't use
-		// -r to pick them up because we can't combine
-		// split-stack and non-split-stack code in a single -r
-		// link, and libgo picks up non-split-stack code from
-		// libffi.
-		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
-
-		if nopie := b.gccNoPie(); nopie != "" {
-			ldflags = append(ldflags, nopie)
-		}
-
-		// We are creating an object file, so we don't want a build ID.
-		ldflags = b.disableBuildID(ldflags)
-
-		realOut = out
-		out = out + ".o"
-
-	case "c-shared":
-		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
-	case "shared":
-		ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
-
-	default:
-		base.Fatalf("-buildmode=%s not supported for gccgo", buildmode)
-	}
-
-	switch buildmode {
-	case "exe", "c-shared":
-		if cxx {
-			ldflags = append(ldflags, "-lstdc++")
-		}
-		if objc {
-			ldflags = append(ldflags, "-lobjc")
-		}
-		if fortran {
-			fc := os.Getenv("FC")
-			if fc == "" {
-				fc = "gfortran"
-			}
-			// support gfortran out of the box and let others pass the correct link options
-			// via CGO_LDFLAGS
-			if strings.Contains(fc, "gfortran") {
-				ldflags = append(ldflags, "-lgfortran")
-			}
-		}
-	}
-
-	if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
-		return err
-	}
-
-	switch buildmode {
-	case "c-archive":
-		if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (tools gccgoToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
-	return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.Package.ImportPath)
-}
-
-func (tools gccgoToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
-	fakeRoot := &Action{}
-	fakeRoot.Deps = toplevelactions
-	return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out)
-}
-
-func (tools gccgoToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
-	cfile = mkAbs(p.Dir, cfile)
-	defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
-	defs = append(defs, b.gccArchArgs()...)
-	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
-		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
-	}
-	switch cfg.Goarch {
-	case "386", "amd64":
-		defs = append(defs, "-fsplit-stack")
-	}
-	defs = tools.maybePIC(defs)
-	return b.run(p.Dir, p.ImportPath, nil, envList("CC", cfg.DefaultCC), "-Wall", "-g",
-		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
-}
-
-// maybePIC adds -fPIC to the list of arguments if needed.
-func (tools gccgoToolchain) maybePIC(args []string) []string {
-	switch cfg.BuildBuildmode {
-	case "c-shared", "shared", "plugin":
-		args = append(args, "-fPIC")
-	}
-	return args
-}
-
-func gccgoPkgpath(p *load.Package) string {
-	if p.Internal.Build.IsCommand() && !p.Internal.ForceLibrary {
-		return ""
-	}
-	return p.ImportPath
-}
-
-func gccgoCleanPkgpath(p *load.Package) string {
-	clean := func(r rune) rune {
-		switch {
-		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
-			'0' <= r && r <= '9':
-			return r
-		}
-		return '_'
-	}
-	return strings.Map(clean, gccgoPkgpath(p))
-}
-
-// gcc runs the gcc C compiler to create an object from a single C file.
-func (b *Builder) gcc(p *load.Package, out string, flags []string, cfile string) error {
-	return b.ccompile(p, out, flags, cfile, b.GccCmd(p.Dir))
-}
-
-// gxx runs the g++ C++ compiler to create an object from a single C++ file.
-func (b *Builder) gxx(p *load.Package, out string, flags []string, cxxfile string) error {
-	return b.ccompile(p, out, flags, cxxfile, b.GxxCmd(p.Dir))
-}
-
-// gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
-func (b *Builder) gfortran(p *load.Package, out string, flags []string, ffile string) error {
-	return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
-}
-
-// ccompile runs the given C or C++ compiler and creates an object from a single source file.
-func (b *Builder) ccompile(p *load.Package, outfile string, flags []string, file string, compiler []string) error {
-	file = mkAbs(p.Dir, file)
-	desc := p.ImportPath
-	if !filepath.IsAbs(outfile) {
-		outfile = filepath.Join(p.Dir, outfile)
-	}
-	output, err := b.runOut(filepath.Dir(file), desc, nil, compiler, flags, "-o", outfile, "-c", filepath.Base(file))
-	if len(output) > 0 {
-		// On FreeBSD 11, when we pass -g to clang 3.8 it
-		// invokes its internal assembler with -dwarf-version=2.
-		// When it sees .section .note.GNU-stack, it warns
-		// "DWARF2 only supports one section per compilation unit".
-		// This warning makes no sense, since the section is empty,
-		// but it confuses people.
-		// We work around the problem by detecting the warning
-		// and dropping -g and trying again.
-		if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
-			newFlags := make([]string, 0, len(flags))
-			for _, f := range flags {
-				if !strings.HasPrefix(f, "-g") {
-					newFlags = append(newFlags, f)
-				}
-			}
-			if len(newFlags) < len(flags) {
-				return b.ccompile(p, outfile, newFlags, file, compiler)
-			}
-		}
-
-		b.showOutput(p.Dir, desc, b.processOutput(output))
-		if err != nil {
-			err = errPrintedOutput
-		} else if os.Getenv("GO_BUILDER_NAME") != "" {
-			return errors.New("C compiler warning promoted to error on Go builders")
-		}
-	}
-	return err
-}
-
-// gccld runs the gcc linker to create an executable from a set of object files.
-func (b *Builder) gccld(p *load.Package, out string, flags []string, obj []string) error {
-	var cmd []string
-	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
-		cmd = b.GxxCmd(p.Dir)
-	} else {
-		cmd = b.GccCmd(p.Dir)
-	}
-	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
-}
-
-// gccCmd returns a gcc command line prefix
-// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
-func (b *Builder) GccCmd(objdir string) []string {
-	return b.ccompilerCmd("CC", cfg.DefaultCC, objdir)
-}
-
-// gxxCmd returns a g++ command line prefix
-// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
-func (b *Builder) GxxCmd(objdir string) []string {
-	return b.ccompilerCmd("CXX", cfg.DefaultCXX, objdir)
-}
-
-// gfortranCmd returns a gfortran command line prefix.
-func (b *Builder) gfortranCmd(objdir string) []string {
-	return b.ccompilerCmd("FC", "gfortran", objdir)
-}
-
-// ccompilerCmd returns a command line prefix for the given environment
-// variable and using the default command when the variable is empty.
-func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
-	// NOTE: env.go's mkEnv knows that the first three
-	// strings returned are "gcc", "-I", objdir (and cuts them off).
-
-	compiler := envList(envvar, defcmd)
-	a := []string{compiler[0], "-I", objdir}
-	a = append(a, compiler[1:]...)
-
-	// Definitely want -fPIC but on Windows gcc complains
-	// "-fPIC ignored for target (all code is position independent)"
-	if cfg.Goos != "windows" {
-		a = append(a, "-fPIC")
-	}
-	a = append(a, b.gccArchArgs()...)
-	// gcc-4.5 and beyond require explicit "-pthread" flag
-	// for multithreading with pthread library.
-	if cfg.BuildContext.CgoEnabled {
-		switch cfg.Goos {
-		case "windows":
-			a = append(a, "-mthreads")
-		default:
-			a = append(a, "-pthread")
-		}
-	}
-
-	if strings.Contains(a[0], "clang") {
-		// disable ASCII art in clang errors, if possible
-		a = append(a, "-fno-caret-diagnostics")
-		// clang is too smart about command-line arguments
-		a = append(a, "-Qunused-arguments")
-	}
-
-	// disable word wrapping in error messages
-	a = append(a, "-fmessage-length=0")
-
-	// Tell gcc not to include the work directory in object files.
-	if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
-		a = append(a, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
-	}
-
-	// Tell gcc not to include flags in object files, which defeats the
-	// point of -fdebug-prefix-map above.
-	if b.gccSupportsFlag("-gno-record-gcc-switches") {
-		a = append(a, "-gno-record-gcc-switches")
-	}
-
-	// On OS X, some of the compilers behave as if -fno-common
-	// is always set, and the Mach-O linker in 6l/8l assumes this.
-	// See https://golang.org/issue/3253.
-	if cfg.Goos == "darwin" {
-		a = append(a, "-fno-common")
-	}
-
-	return a
-}
-
-// gccNoPie returns the flag to use to request non-PIE. On systems
-// with PIE (position independent executables) enabled by default,
-// -no-pie must be passed when doing a partial link with -Wl,-r.
-// But -no-pie is not supported by all compilers, and clang spells it -nopie.
-func (b *Builder) gccNoPie() string {
-	if b.gccSupportsFlag("-no-pie") {
-		return "-no-pie"
-	}
-	if b.gccSupportsFlag("-nopie") {
-		return "-nopie"
-	}
-	return ""
-}
-
-// gccSupportsFlag checks to see if the compiler supports a flag.
-func (b *Builder) gccSupportsFlag(flag string) bool {
-	b.exec.Lock()
-	defer b.exec.Unlock()
-	if b, ok := b.flagCache[flag]; ok {
-		return b
-	}
-	if b.flagCache == nil {
-		src := filepath.Join(b.WorkDir, "trivial.c")
-		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
-			return false
-		}
-		b.flagCache = make(map[string]bool)
-	}
-	cmdArgs := append(envList("CC", cfg.DefaultCC), flag, "-c", "trivial.c")
-	if cfg.BuildN || cfg.BuildX {
-		b.Showcmd(b.WorkDir, "%s", joinUnambiguously(cmdArgs))
-		if cfg.BuildN {
-			return false
-		}
-	}
-	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
-	cmd.Dir = b.WorkDir
-	cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
-	out, err := cmd.CombinedOutput()
-	supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
-	b.flagCache[flag] = supported
-	return supported
-}
-
-// gccArchArgs returns arguments to pass to gcc based on the architecture.
-func (b *Builder) gccArchArgs() []string {
-	switch cfg.Goarch {
-	case "386":
-		return []string{"-m32"}
-	case "amd64", "amd64p32":
-		return []string{"-m64"}
-	case "arm":
-		return []string{"-marm"} // not thumb
-	case "s390x":
-		return []string{"-m64", "-march=z196"}
-	case "mips64", "mips64le":
-		return []string{"-mabi=64"}
-	case "mips", "mipsle":
-		return []string{"-mabi=32", "-march=mips32"}
-	}
-	return nil
-}
-
-// envList returns the value of the given environment variable broken
-// into fields, using the default value when the variable is empty.
-func envList(key, def string) []string {
-	v := os.Getenv(key)
-	if v == "" {
-		v = def
-	}
-	return strings.Fields(v)
-}
-
-// CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
-func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
-	defaults := "-g -O2"
-
-	cppflags = str.StringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
-	cflags = str.StringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
-	cxxflags = str.StringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
-	fflags = str.StringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
-	ldflags = str.StringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
-	return
-}
-
-var cgoRe = regexp.MustCompile(`[/\\:]`)
-
-func (b *Builder) cgo(a *Action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
-	p := a.Package
-	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.CFlags(p)
-	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")
-	}
-
-	// Likewise for Fortran, except there are many Fortran compilers.
-	// Support gfortran out of the box and let others pass the correct link options
-	// via CGO_LDFLAGS
-	if len(ffiles) > 0 {
-		fc := os.Getenv("FC")
-		if fc == "" {
-			fc = "gfortran"
-		}
-		if strings.Contains(fc, "gfortran") {
-			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
-		}
-	}
-
-	if cfg.BuildMSan {
-		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
-		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
-	}
-
-	// Allows including _cgo_export.h from .[ch] files in the package.
-	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
-
-	// If we have cgo files in the object directory, then copy any
-	// other cgo files into the object directory, and pass a
-	// -srcdir option to cgo.
-	var srcdirarg []string
-	if len(objdirCgofiles) > 0 {
-		for _, fn := range cgofiles {
-			if err := b.copyFile(a, obj+filepath.Base(fn), filepath.Join(p.Dir, fn), 0666, false); err != nil {
-				return nil, nil, err
-			}
-		}
-		cgofiles = append(cgofiles, objdirCgofiles...)
-		srcdirarg = []string{"-srcdir", obj}
-	}
-
-	// cgo
-	// TODO: CGO_FLAGS?
-	gofiles := []string{obj + "_cgo_gotypes.go"}
-	cfiles := []string{"_cgo_export.c"}
-	for _, fn := range cgofiles {
-		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
-		gofiles = append(gofiles, obj+f+"cgo1.go")
-		cfiles = append(cfiles, f+"cgo2.c")
-	}
-
-	// TODO: make cgo not depend on $GOARCH?
-
-	cgoflags := []string{}
-	if p.Standard && p.ImportPath == "runtime/cgo" {
-		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
-	}
-	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
-		cgoflags = append(cgoflags, "-import_syscall=false")
-	}
-
-	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
-	var cgoenv []string
-	if len(cgoLDFLAGS) > 0 {
-		flags := make([]string, len(cgoLDFLAGS))
-		for i, f := range cgoLDFLAGS {
-			flags[i] = strconv.Quote(f)
-		}
-		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
-	}
-
-	if cfg.BuildToolchainName == "gccgo" {
-		switch cfg.Goarch {
-		case "386", "amd64":
-			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
-		}
-		cgoflags = append(cgoflags, "-gccgo")
-		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
-			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
-		}
-	}
-
-	switch cfg.BuildBuildmode {
-	case "c-archive", "c-shared":
-		// Tell cgo that if there are any exported functions
-		// it should generate a header file that C code can
-		// #include.
-		cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
-	}
-
-	if err := b.run(p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
-		return nil, nil, err
-	}
-	outGo = append(outGo, gofiles...)
-
-	// gcc
-	cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
-	for _, cfile := range cfiles {
-		ofile := obj + cfile[:len(cfile)-1] + "o"
-		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	for _, file := range gccfiles {
-		base := filepath.Base(file)
-		ofile := obj + cgoRe.ReplaceAllString(base[:len(base)-1], "_") + "o"
-		if err := b.gcc(p, ofile, cflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
-	for _, file := range gxxfiles {
-		// Append .o to the file, just in case the pkg has file.c and file.cpp
-		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
-		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	for _, file := range mfiles {
-		// Append .o to the file, just in case the pkg has file.c and file.m
-		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
-		if err := b.gcc(p, ofile, cflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
-	for _, file := range ffiles {
-		// Append .o to the file, just in case the pkg has file.c and file.f
-		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
-		if err := b.gfortran(p, ofile, fflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	switch cfg.BuildToolchainName {
-	case "gc":
-		importGo := obj + "_cgo_import.go"
-		if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
-			return nil, nil, err
-		}
-		outGo = append(outGo, importGo)
-
-		ofile := obj + "_all.o"
-		if err := b.collect(p, obj, ofile, cgoLDFLAGS, outObj); err != nil {
-			return nil, nil, err
-		}
-		outObj = []string{ofile}
-
-	case "gccgo":
-		defunC := obj + "_cgo_defun.c"
-		defunObj := obj + "_cgo_defun.o"
-		if err := BuildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, defunObj)
-
-	default:
-		noCompiler()
-	}
-
-	return outGo, outObj, nil
-}
-
-// dynimport creates a Go source file named importGo containing
-// //go:cgo_import_dynamic directives for each symbol or library
-// dynamically imported by the object files outObj.
-func (b *Builder) dynimport(p *load.Package, obj, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
-	cfile := obj + "_cgo_main.c"
-	ofile := obj + "_cgo_main.o"
-	if err := b.gcc(p, ofile, cflags, cfile); err != nil {
-		return err
-	}
-
-	linkobj := str.StringList(ofile, outObj, p.SysoFiles)
-	dynobj := obj + "_cgo_.o"
-
-	// we need to use -pie for Linux/ARM to get accurate imported sym
-	ldflags := cgoLDFLAGS
-	if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
-		ldflags = append(ldflags, "-pie")
-	}
-	if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
-		return err
-	}
-
-	// cgo -dynimport
-	var cgoflags []string
-	if p.Standard && p.ImportPath == "runtime/cgo" {
-		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
-	}
-	return b.run(p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
-}
-
-// collect partially links the object files outObj into a single
-// relocatable object file named ofile.
-func (b *Builder) collect(p *load.Package, obj, ofile string, cgoLDFLAGS, outObj []string) error {
-	// When linking relocatable objects, various flags need to be
-	// filtered out as they are inapplicable and can cause some linkers
-	// to fail.
-	var ldflags []string
-	for i := 0; i < len(cgoLDFLAGS); i++ {
-		f := cgoLDFLAGS[i]
-		switch {
-		// skip "-lc" or "-l somelib"
-		case strings.HasPrefix(f, "-l"):
-			if f == "-l" {
-				i++
-			}
-		// skip "-framework X" on Darwin
-		case cfg.Goos == "darwin" && f == "-framework":
-			i++
-		// skip "*.{dylib,so,dll,o,a}"
-		case strings.HasSuffix(f, ".dylib"),
-			strings.HasSuffix(f, ".so"),
-			strings.HasSuffix(f, ".dll"),
-			strings.HasSuffix(f, ".o"),
-			strings.HasSuffix(f, ".a"):
-		// 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
-		// runpath flags not applicable unless building a shared
-		// object or executable; see issue 12115 for details. This
-		// is necessary as Go currently does not offer a way to
-		// specify the set of LDFLAGS that only apply to shared
-		// objects.
-		case strings.HasPrefix(f, "-Wl,-rpath"):
-			if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
-				// Skip following argument to -rpath* too.
-				i++
-			}
-		default:
-			ldflags = append(ldflags, f)
-		}
-	}
-
-	ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
-
-	if flag := b.gccNoPie(); flag != "" {
-		ldflags = append(ldflags, flag)
-	}
-
-	// We are creating an object file, so we don't want a build ID.
-	ldflags = b.disableBuildID(ldflags)
-
-	return b.gccld(p, ofile, ldflags, outObj)
-}
-
-// 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 *load.Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
-	if err := b.swigVersionCheck(); err != nil {
-		return nil, nil, nil, err
-	}
-
-	intgosize, err := b.swigIntSize(obj)
-	if err != nil {
-		return nil, nil, nil, err
-	}
-
-	for _, f := range p.SwigFiles {
-		goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
-		if err != nil {
-			return nil, nil, nil, err
-		}
-		if goFile != "" {
-			outGo = append(outGo, goFile)
-		}
-		if cFile != "" {
-			outC = append(outC, cFile)
-		}
-	}
-	for _, f := range p.SwigCXXFiles {
-		goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
-		if err != nil {
-			return nil, nil, nil, err
-		}
-		if goFile != "" {
-			outGo = append(outGo, goFile)
-		}
-		if cxxFile != "" {
-			outCXX = append(outCXX, cxxFile)
-		}
-	}
-	return outGo, outC, outCXX, nil
-}
-
-// Make sure SWIG is new enough.
-var (
-	swigCheckOnce sync.Once
-	swigCheck     error
-)
-
-func (b *Builder) swigDoVersionCheck() error {
-	out, err := b.runOut("", "", nil, "swig", "-version")
-	if err != nil {
-		return err
-	}
-	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
-	matches := re.FindSubmatch(out)
-	if matches == nil {
-		// Can't find version number; hope for the best.
-		return nil
-	}
-
-	major, err := strconv.Atoi(string(matches[1]))
-	if err != nil {
-		// Can't find version number; hope for the best.
-		return nil
-	}
-	const errmsg = "must have SWIG version >= 3.0.6"
-	if major < 3 {
-		return errors.New(errmsg)
-	}
-	if major > 3 {
-		// 4.0 or later
-		return nil
-	}
-
-	// We have SWIG version 3.x.
-	if len(matches[2]) > 0 {
-		minor, err := strconv.Atoi(string(matches[2][1:]))
-		if err != nil {
-			return nil
-		}
-		if minor > 0 {
-			// 3.1 or later
-			return nil
-		}
-	}
-
-	// We have SWIG version 3.0.x.
-	if len(matches[3]) > 0 {
-		patch, err := strconv.Atoi(string(matches[3][1:]))
-		if err != nil {
-			return nil
-		}
-		if patch < 6 {
-			// Before 3.0.6.
-			return errors.New(errmsg)
-		}
-	}
-
-	return nil
-}
-
-func (b *Builder) swigVersionCheck() error {
-	swigCheckOnce.Do(func() {
-		swigCheck = b.swigDoVersionCheck()
-	})
-	return swigCheck
-}
-
-// Find the value to pass for the -intgosize option to swig.
-var (
-	swigIntSizeOnce  sync.Once
-	swigIntSize      string
-	swigIntSizeError error
-)
-
-// This code fails to build if sizeof(int) <= 32
-const swigIntSizeCode = `
-package main
-const i int = 1 << 32
-`
-
-// Determine the size of int on the target system for the -intgosize option
-// of swig >= 2.0.9. Run only once.
-func (b *Builder) swigDoIntSize(obj string) (intsize string, err error) {
-	if cfg.BuildN {
-		return "$INTBITS", nil
-	}
-	src := filepath.Join(b.WorkDir, "swig_intsize.go")
-	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
-		return
-	}
-	srcs := []string{src}
-
-	p := load.GoFilesPackage(srcs)
-
-	if _, _, e := BuildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
-		return "32", nil
-	}
-	return "64", nil
-}
-
-// Determine the size of int on the target system for the -intgosize option
-// of swig >= 2.0.9.
-func (b *Builder) swigIntSize(obj string) (intsize string, err error) {
-	swigIntSizeOnce.Do(func() {
-		swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
-	})
-	return swigIntSize, swigIntSizeError
-}
-
-// Run SWIG on one SWIG input file.
-func (b *Builder) swigOne(p *load.Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
-	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.CFlags(p)
-	var cflags []string
-	if cxx {
-		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
-	} else {
-		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
-	}
-
-	n := 5 // length of ".swig"
-	if cxx {
-		n = 8 // length of ".swigcxx"
-	}
-	base := file[:len(file)-n]
-	goFile := base + ".go"
-	gccBase := base + "_wrap."
-	gccExt := "c"
-	if cxx {
-		gccExt = "cxx"
-	}
-
-	gccgo := cfg.BuildToolchainName == "gccgo"
-
-	// swig
-	args := []string{
-		"-go",
-		"-cgo",
-		"-intgosize", intgosize,
-		"-module", base,
-		"-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 != "" {
-			args = append(args, "-go-pkgpath", pkgpath)
-		}
-	}
-	if cxx {
-		args = append(args, "-c++")
-	}
-
-	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
-	if err != nil {
-		if len(out) > 0 {
-			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
-				return "", "", errors.New("must have SWIG version >= 3.0.6")
-			}
-			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
-			return "", "", errPrintedOutput
-		}
-		return "", "", err
-	}
-	if len(out) > 0 {
-		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
-	}
-
-	return goFile, obj + gccBase + gccExt, nil
-}
-
-// disableBuildID adjusts a linker command line to avoid creating a
-// build ID when creating an object file rather than an executable or
-// shared library. Some systems, such as Ubuntu, always add
-// --build-id to every link, but we don't want a build ID when 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.
-func (b *Builder) disableBuildID(ldflags []string) []string {
-	switch cfg.Goos {
-	case "android", "dragonfly", "linux", "netbsd":
-		ldflags = append(ldflags, "-Wl,--build-id=none")
-	}
-	return ldflags
-}
-
-// An actionQueue is a priority queue of actions.
-type actionQueue []*Action
-
-// Implement heap.Interface
-func (q *actionQueue) Len() int           { return len(*q) }
-func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
-func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
-func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*Action)) }
-func (q *actionQueue) Pop() interface{} {
-	n := len(*q) - 1
-	x := (*q)[n]
-	*q = (*q)[:n]
-	return x
-}
-
-func (q *actionQueue) push(a *Action) {
-	heap.Push(q, a)
-}
-
-func (q *actionQueue) pop() *Action {
-	return heap.Pop(q).(*Action)
-}
-
-func InstrumentInit() {
-	if !cfg.BuildRace && !cfg.BuildMSan {
-		return
-	}
-	if cfg.BuildRace && cfg.BuildMSan {
-		fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
-		os.Exit(2)
-	}
-	if cfg.BuildMSan && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
-		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
-		os.Exit(2)
-	}
-	if cfg.Goarch != "amd64" || cfg.Goos != "linux" && cfg.Goos != "freebsd" && cfg.Goos != "darwin" && cfg.Goos != "windows" {
-		fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
-		os.Exit(2)
-	}
-	if !cfg.BuildContext.CgoEnabled {
-		fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
-		os.Exit(2)
-	}
-	if cfg.BuildRace {
-		buildGcflags = append(buildGcflags, "-race")
-		cfg.BuildLdflags = append(cfg.BuildLdflags, "-race")
-	} else {
-		buildGcflags = append(buildGcflags, "-msan")
-		cfg.BuildLdflags = append(cfg.BuildLdflags, "-msan")
-	}
-	if cfg.BuildContext.InstallSuffix != "" {
-		cfg.BuildContext.InstallSuffix += "_"
-	}
-
-	if cfg.BuildRace {
-		cfg.BuildContext.InstallSuffix += "race"
-		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "race")
-	} else {
-		cfg.BuildContext.InstallSuffix += "msan"
-		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "msan")
-	}
-}
-
 // ExecCmd is the command to use to run user binaries.
 // Normally it is empty, meaning run the binaries directly.
 // If cross-compiling and running on a remote system or
diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go
index 294b83c..3f5ba37 100644
--- a/src/cmd/go/internal/work/build_test.go
+++ b/src/cmd/go/internal/work/build_test.go
@@ -175,8 +175,13 @@
 // directory.
 // See https://golang.org/issue/18878.
 func TestRespectSetgidDir(t *testing.T) {
-	if runtime.GOOS == "nacl" {
+	switch runtime.GOOS {
+	case "nacl":
 		t.Skip("can't set SetGID bit with chmod on nacl")
+	case "darwin":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			t.Skip("can't set SetGID bit with chmod on iOS")
+		}
 	}
 
 	var b Builder
diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go
new file mode 100644
index 0000000..39ca20e
--- /dev/null
+++ b/src/cmd/go/internal/work/buildid.go
@@ -0,0 +1,616 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package work
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"strings"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/go/internal/str"
+	"cmd/internal/buildid"
+)
+
+// Build IDs
+//
+// Go packages and binaries are stamped with build IDs that record both
+// the action ID, which is a hash of the inputs to the action that produced
+// the packages or binary, and the content ID, which is a hash of the action
+// output, namely the archive or binary itself. The hash is the same one
+// used by the build artifact cache (see cmd/go/internal/cache), but
+// truncated when stored in packages and binaries, as the full length is not
+// needed and is a bit unwieldy. The precise form is
+//
+//	actionID/[.../]contentID
+//
+// where the actionID and contentID are prepared by hashToString below.
+// and are found by looking for the first or last slash.
+// Usually the buildID is simply actionID/contentID, but see below for an
+// exception.
+//
+// The build ID serves two primary purposes.
+//
+// 1. The action ID half allows installed packages and binaries to serve as
+// one-element cache entries. If we intend to build math.a with a given
+// set of inputs summarized in the action ID, and the installed math.a already
+// has that action ID, we can reuse the installed math.a instead of rebuilding it.
+//
+// 2. The content ID half allows the easy preparation of action IDs for steps
+// that consume a particular package or binary. The content hash of every
+// input file for a given action must be included in the action ID hash.
+// Storing the content ID in the build ID lets us read it from the file with
+// minimal I/O, instead of reading and hashing the entire file.
+// This is especially effective since packages and binaries are typically
+// the largest inputs to an action.
+//
+// Separating action ID from content ID is important for reproducible builds.
+// The compiler is compiled with itself. If an output were represented by its
+// own action ID (instead of content ID) when computing the action ID of
+// the next step in the build process, then the compiler could never have its
+// own input action ID as its output action ID (short of a miraculous hash collision).
+// Instead we use the content IDs to compute the next action ID, and because
+// the content IDs converge, so too do the action IDs and therefore the
+// build IDs and the overall compiler binary. See cmd/dist's cmdbootstrap
+// for the actual convergence sequence.
+//
+// The “one-element cache” purpose is a bit more complex for installed
+// binaries. For a binary, like cmd/gofmt, there are two steps: compile
+// cmd/gofmt/*.go into main.a, and then link main.a into the gofmt binary.
+// We do not install gofmt's main.a, only the gofmt binary. Being able to
+// decide that the gofmt binary is up-to-date means computing the action ID
+// for the final link of the gofmt binary and comparing it against the
+// already-installed gofmt binary. But computing the action ID for the link
+// means knowing the content ID of main.a, which we did not keep.
+// To sidestep this problem, each binary actually stores an expanded build ID:
+//
+//	actionID(binary)/actionID(main.a)/contentID(main.a)/contentID(binary)
+//
+// (Note that this can be viewed equivalently as:
+//
+//	actionID(binary)/buildID(main.a)/contentID(binary)
+//
+// Storing the buildID(main.a) in the middle lets the computations that care
+// about the prefix or suffix halves ignore the middle and preserves the
+// original build ID as a contiguous string.)
+//
+// During the build, when it's time to build main.a, the gofmt binary has the
+// information needed to decide whether the eventual link would produce
+// the same binary: if the action ID for main.a's inputs matches and then
+// the action ID for the link step matches when assuming the given main.a
+// content ID, then the binary as a whole is up-to-date and need not be rebuilt.
+//
+// This is all a bit complex and may be simplified once we can rely on the
+// main cache, but at least at the start we will be using the content-based
+// staleness determination without a cache beyond the usual installed
+// package and binary locations.
+
+const buildIDSeparator = "/"
+
+// actionID returns the action ID half of a build ID.
+func actionID(buildID string) string {
+	i := strings.Index(buildID, buildIDSeparator)
+	if i < 0 {
+		return buildID
+	}
+	return buildID[:i]
+}
+
+// contentID returns the content ID half of a build ID.
+func contentID(buildID string) string {
+	return buildID[strings.LastIndex(buildID, buildIDSeparator)+1:]
+}
+
+// hashToString converts the hash h to a string to be recorded
+// in package archives and binaries as part of the build ID.
+// We use the first 96 bits of the hash and encode it in base64,
+// resulting in a 16-byte string. Because this is only used for
+// detecting the need to rebuild installed files (not for lookups
+// in the object file cache), 96 bits are sufficient to drive the
+// probability of a false "do not need to rebuild" decision to effectively zero.
+// We embed two different hashes in archives and four in binaries,
+// so cutting to 16 bytes is a significant savings when build IDs are displayed.
+// (16*4+3 = 67 bytes compared to 64*4+3 = 259 bytes for the
+// more straightforward option of printing the entire h in hex).
+func hashToString(h [cache.HashSize]byte) string {
+	const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+	const chunks = 5
+	var dst [chunks * 4]byte
+	for i := 0; i < chunks; i++ {
+		v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
+		dst[4*i+0] = b64[(v>>18)&0x3F]
+		dst[4*i+1] = b64[(v>>12)&0x3F]
+		dst[4*i+2] = b64[(v>>6)&0x3F]
+		dst[4*i+3] = b64[v&0x3F]
+	}
+	return string(dst[:])
+}
+
+// toolID returns the unique ID to use for the current copy of the
+// named tool (asm, compile, cover, link).
+//
+// It is important that if the tool changes (for example a compiler bug is fixed
+// and the compiler reinstalled), toolID returns a different string, so that old
+// package archives look stale and are rebuilt (with the fixed compiler).
+// This suggests using a content hash of the tool binary, as stored in the build ID.
+//
+// Unfortunately, we can't just open the tool binary, because the tool might be
+// invoked via a wrapper program specified by -toolexec and we don't know
+// what the wrapper program does. In particular, we want "-toolexec toolstash"
+// to continue working: it does no good if "-toolexec toolstash" is executing a
+// stashed copy of the compiler but the go command is acting as if it will run
+// the standard copy of the compiler. The solution is to ask the tool binary to tell
+// us its own build ID using the "-V=full" flag now supported by all tools.
+// Then we know we're getting the build ID of the compiler that will actually run
+// during the build. (How does the compiler binary know its own content hash?
+// We store it there using updateBuildID after the standard link step.)
+//
+// A final twist is that we'd prefer to have reproducible builds for release toolchains.
+// It should be possible to cross-compile for Windows from either Linux or Mac
+// or Windows itself and produce the same binaries, bit for bit. If the tool ID,
+// which influences the action ID half of the build ID, is based on the content ID,
+// then the Linux compiler binary and Mac compiler binary will have different tool IDs
+// and therefore produce executables with different action IDs.
+// To avoids this problem, for releases we use the release version string instead
+// of the compiler binary's content hash. This assumes that all compilers built
+// on all different systems are semantically equivalent, which is of course only true
+// modulo bugs. (Producing the exact same executables also requires that the different
+// build setups agree on details like $GOROOT and file name paths, but at least the
+// tool IDs do not make it impossible.)
+func (b *Builder) toolID(name string) string {
+	b.id.Lock()
+	id := b.toolIDCache[name]
+	b.id.Unlock()
+
+	if id != "" {
+		return id
+	}
+
+	cmdline := str.StringList(cfg.BuildToolexec, base.Tool(name), "-V=full")
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	var stdout, stderr bytes.Buffer
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	if err := cmd.Run(); err != nil {
+		base.Fatalf("go tool %s: %v\n%s%s", name, err, stdout.Bytes(), stderr.Bytes())
+	}
+
+	line := stdout.String()
+	f := strings.Fields(line)
+	if len(f) < 3 || f[0] != name || f[1] != "version" || f[2] == "devel" && !strings.HasPrefix(f[len(f)-1], "buildID=") {
+		base.Fatalf("go tool %s -V=full: unexpected output:\n\t%s", name, line)
+	}
+	if f[2] == "devel" {
+		// On the development branch, use the content ID part of the build ID.
+		id = contentID(f[len(f)-1])
+	} else {
+		// For a release, the output is like: "compile version go1.9.1". Use the whole line.
+		id = f[2]
+	}
+
+	b.id.Lock()
+	b.toolIDCache[name] = id
+	b.id.Unlock()
+
+	return id
+}
+
+// gccToolID returns the unique ID to use for a tool that is invoked
+// by the GCC driver. This is in particular gccgo, but this can also
+// be used for gcc, g++, gfortran, etc.; those tools all use the GCC
+// driver under different names. The approach used here should also
+// work for sufficiently new versions of clang. Unlike toolID, the
+// name argument is the program to run. The language argument is the
+// type of input file as passed to the GCC driver's -x option.
+//
+// For these tools we have no -V=full option to dump the build ID,
+// but we can run the tool with -v -### to reliably get the compiler proper
+// and hash that. That will work in the presence of -toolexec.
+//
+// In order to get reproducible builds for released compilers, we
+// detect a released compiler by the absence of "experimental" in the
+// --version output, and in that case we just use the version string.
+func (b *Builder) gccgoToolID(name, language string) (string, error) {
+	key := name + "." + language
+	b.id.Lock()
+	id := b.toolIDCache[key]
+	b.id.Unlock()
+
+	if id != "" {
+		return id, nil
+	}
+
+	// Invoke the driver with -### to see the subcommands and the
+	// version strings. Use -x to set the language. Pretend to
+	// compile an empty file on standard input.
+	cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-")
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return "", fmt.Errorf("%s: %v; output: %q", name, err, out)
+	}
+
+	version := ""
+	lines := strings.Split(string(out), "\n")
+	for _, line := range lines {
+		if fields := strings.Fields(line); len(fields) > 1 && fields[1] == "version" {
+			version = line
+			break
+		}
+	}
+	if version == "" {
+		return "", fmt.Errorf("%s: can not find version number in %q", name, out)
+	}
+
+	if !strings.Contains(version, "experimental") {
+		// This is a release. Use this line as the tool ID.
+		id = version
+	} else {
+		// This is a development version. The first line with
+		// a leading space is the compiler proper.
+		compiler := ""
+		for _, line := range lines {
+			if len(line) > 1 && line[0] == ' ' {
+				compiler = line
+				break
+			}
+		}
+		if compiler == "" {
+			return "", fmt.Errorf("%s: can not find compilation command in %q", name, out)
+		}
+
+		fields := strings.Fields(compiler)
+		if len(fields) == 0 {
+			return "", fmt.Errorf("%s: compilation command confusion %q", name, out)
+		}
+		exe := fields[0]
+		if !strings.ContainsAny(exe, `/\`) {
+			if lp, err := exec.LookPath(exe); err == nil {
+				exe = lp
+			}
+		}
+		if _, err := os.Stat(exe); err != nil {
+			return "", fmt.Errorf("%s: can not find compiler %q: %v; output %q", name, exe, err, out)
+		}
+		id = b.fileHash(exe)
+	}
+
+	b.id.Lock()
+	b.toolIDCache[name] = id
+	b.id.Unlock()
+
+	return id, nil
+}
+
+// gccgoBuildIDELFFile creates an assembler file that records the
+// action's build ID in an SHF_EXCLUDE section.
+func (b *Builder) gccgoBuildIDELFFile(a *Action) (string, error) {
+	sfile := a.Objdir + "_buildid.s"
+
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n")
+	fmt.Fprintf(&buf, "\t.byte ")
+	for i := 0; i < len(a.buildID); i++ {
+		if i > 0 {
+			if i%8 == 0 {
+				fmt.Fprintf(&buf, "\n\t.byte ")
+			} else {
+				fmt.Fprintf(&buf, ",")
+			}
+		}
+		fmt.Fprintf(&buf, "%#02x", a.buildID[i])
+	}
+	fmt.Fprintf(&buf, "\n")
+	fmt.Fprintf(&buf, "\t"+`.section .note.GNU-stack,"",@progbits`+"\n")
+	fmt.Fprintf(&buf, "\t"+`.section .note.GNU-split-stack,"",@progbits`+"\n")
+
+	if cfg.BuildN || cfg.BuildX {
+		for _, line := range bytes.Split(buf.Bytes(), []byte("\n")) {
+			b.Showcmd("", "echo '%s' >> %s", line, sfile)
+		}
+		if cfg.BuildN {
+			return sfile, nil
+		}
+	}
+
+	if err := ioutil.WriteFile(sfile, buf.Bytes(), 0666); err != nil {
+		return "", err
+	}
+
+	return sfile, nil
+}
+
+// buildID returns the build ID found in the given file.
+// If no build ID is found, buildID returns the content hash of the file.
+func (b *Builder) buildID(file string) string {
+	b.id.Lock()
+	id := b.buildIDCache[file]
+	b.id.Unlock()
+
+	if id != "" {
+		return id
+	}
+
+	id, err := buildid.ReadFile(file)
+	if err != nil {
+		id = b.fileHash(file)
+	}
+
+	b.id.Lock()
+	b.buildIDCache[file] = id
+	b.id.Unlock()
+
+	return id
+}
+
+// fileHash returns the content hash of the named file.
+func (b *Builder) fileHash(file string) string {
+	sum, err := cache.FileHash(file)
+	if err != nil {
+		return ""
+	}
+	return hashToString(sum)
+}
+
+// useCache tries to satisfy the action a, which has action ID actionHash,
+// by using a cached result from an earlier build. At the moment, the only
+// cached result is the installed package or binary at target.
+// If useCache decides that the cache can be used, it sets a.buildID
+// and a.built for use by parent actions and then returns true.
+// Otherwise it sets a.buildID to a temporary build ID for use in the build
+// and returns false. When useCache returns false the expectation is that
+// the caller will build the target and then call updateBuildID to finish the
+// build ID computation.
+// When useCache returns false, it may have initiated buffering of output
+// during a's work. The caller should defer b.flushOutput(a), to make sure
+// that flushOutput is eventually called regardless of whether the action
+// succeeds. The flushOutput call must happen after updateBuildID.
+func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID, target string) bool {
+	// The second half of the build ID here is a placeholder for the content hash.
+	// It's important that the overall buildID be unlikely verging on impossible
+	// to appear in the output by chance, but that should be taken care of by
+	// the actionID half; if it also appeared in the input that would be like an
+	// engineered 96-bit partial SHA256 collision.
+	a.actionID = actionHash
+	actionID := hashToString(actionHash)
+	contentID := actionID // temporary placeholder, likely unique
+	a.buildID = actionID + buildIDSeparator + contentID
+
+	// Executable binaries also record the main build ID in the middle.
+	// See "Build IDs" comment above.
+	if a.Mode == "link" {
+		mainpkg := a.Deps[0]
+		a.buildID = actionID + buildIDSeparator + mainpkg.buildID + buildIDSeparator + contentID
+	}
+
+	// Check to see if target exists and matches the expected action ID.
+	// If so, it's up to date and we can reuse it instead of rebuilding it.
+	var buildID string
+	if target != "" && !cfg.BuildA {
+		var err error
+		buildID, err = buildid.ReadFile(target)
+		if err != nil && b.ComputeStaleOnly {
+			if p != nil && !p.Stale {
+				p.Stale = true
+				p.StaleReason = "target missing"
+			}
+			return true
+		}
+		if strings.HasPrefix(buildID, actionID+buildIDSeparator) {
+			a.buildID = buildID
+			a.built = target
+			// Poison a.Target to catch uses later in the build.
+			a.Target = "DO NOT USE - " + a.Mode
+			return true
+		}
+	}
+
+	// Special case for building a main package: if the only thing we
+	// want the package for is to link a binary, and the binary is
+	// already up-to-date, then to avoid a rebuild, report the package
+	// as up-to-date as well. See "Build IDs" comment above.
+	// TODO(rsc): Rewrite this code to use a TryCache func on the link action.
+	if target != "" && !cfg.BuildA && a.Mode == "build" && len(a.triggers) == 1 && a.triggers[0].Mode == "link" {
+		buildID, err := buildid.ReadFile(target)
+		if err == nil {
+			id := strings.Split(buildID, buildIDSeparator)
+			if len(id) == 4 && id[1] == actionID {
+				// Temporarily assume a.buildID is the package build ID
+				// stored in the installed binary, and see if that makes
+				// the upcoming link action ID a match. If so, report that
+				// we built the package, safe in the knowledge that the
+				// link step will not ask us for the actual package file.
+				// Note that (*Builder).LinkAction arranged that all of
+				// a.triggers[0]'s dependencies other than a are also
+				// dependencies of a, so that we can be sure that,
+				// other than a.buildID, b.linkActionID is only accessing
+				// build IDs of completed actions.
+				oldBuildID := a.buildID
+				a.buildID = id[1] + buildIDSeparator + id[2]
+				linkID := hashToString(b.linkActionID(a.triggers[0]))
+				if id[0] == linkID {
+					// Poison a.Target to catch uses later in the build.
+					a.Target = "DO NOT USE - main build pseudo-cache Target"
+					a.built = "DO NOT USE - main build pseudo-cache built"
+					return true
+				}
+				// Otherwise restore old build ID for main build.
+				a.buildID = oldBuildID
+			}
+		}
+	}
+
+	// Special case for linking a test binary: if the only thing we
+	// want the binary for is to run the test, and the test result is cached,
+	// then to avoid the link step, report the link as up-to-date.
+	// We avoid the nested build ID problem in the previous special case
+	// by recording the test results in the cache under the action ID half.
+	if !cfg.BuildA && len(a.triggers) == 1 && a.triggers[0].TryCache != nil && a.triggers[0].TryCache(b, a.triggers[0]) {
+		a.Target = "DO NOT USE -  pseudo-cache Target"
+		a.built = "DO NOT USE - pseudo-cache built"
+		return true
+	}
+
+	if b.ComputeStaleOnly {
+		// Invoked during go list only to compute and record staleness.
+		if p := a.Package; p != nil && !p.Stale {
+			p.Stale = true
+			if cfg.BuildA {
+				p.StaleReason = "build -a flag in use"
+			} else {
+				p.StaleReason = "build ID mismatch"
+				for _, p1 := range p.Internal.Imports {
+					if p1.Stale && p1.StaleReason != "" {
+						if strings.HasPrefix(p1.StaleReason, "stale dependency: ") {
+							p.StaleReason = p1.StaleReason
+							break
+						}
+						if strings.HasPrefix(p.StaleReason, "build ID mismatch") {
+							p.StaleReason = "stale dependency: " + p1.ImportPath
+						}
+					}
+				}
+			}
+		}
+		return true
+	}
+
+	// Check the build artifact cache.
+	// We treat hits in this cache as being "stale" for the purposes of go list
+	// (in effect, "stale" means whether p.Target is up-to-date),
+	// but we're still happy to use results from the build artifact cache.
+	if c := cache.Default(); c != nil {
+		if !cfg.BuildA {
+			entry, err := c.Get(actionHash)
+			if err == nil {
+				file := c.OutputFile(entry.OutputID)
+				info, err1 := os.Stat(file)
+				buildID, err2 := buildid.ReadFile(file)
+				if err1 == nil && err2 == nil && info.Size() == entry.Size {
+					stdout, stdoutEntry, err := c.GetBytes(cache.Subkey(a.actionID, "stdout"))
+					if err == nil {
+						if len(stdout) > 0 {
+							if cfg.BuildX || cfg.BuildN {
+								b.Showcmd("", "%s  # internal", joinUnambiguously(str.StringList("cat", c.OutputFile(stdoutEntry.OutputID))))
+							}
+							if !cfg.BuildN {
+								b.Print(string(stdout))
+							}
+						}
+						a.built = file
+						a.Target = "DO NOT USE - using cache"
+						a.buildID = buildID
+						return true
+					}
+				}
+			}
+		}
+
+		// Begin saving output for later writing to cache.
+		a.output = []byte{}
+	}
+
+	return false
+}
+
+// flushOutput flushes the output being queued in a.
+func (b *Builder) flushOutput(a *Action) {
+	b.Print(string(a.output))
+	a.output = nil
+}
+
+// updateBuildID updates the build ID in the target written by action a.
+// It requires that useCache was called for action a and returned false,
+// and that the build was then carried out and given the temporary
+// a.buildID to record as the build ID in the resulting package or binary.
+// updateBuildID computes the final content ID and updates the build IDs
+// in the binary.
+//
+// Keep in sync with src/cmd/buildid/buildid.go
+func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error {
+	if cfg.BuildX || cfg.BuildN {
+		if rewrite {
+			b.Showcmd("", "%s # internal", joinUnambiguously(str.StringList(base.Tool("buildid"), "-w", target)))
+		}
+		if cfg.BuildN {
+			return nil
+		}
+	}
+
+	// Find occurrences of old ID and compute new content-based ID.
+	r, err := os.Open(target)
+	if err != nil {
+		return err
+	}
+	matches, hash, err := buildid.FindAndHash(r, a.buildID, 0)
+	r.Close()
+	if err != nil {
+		return err
+	}
+	newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + hashToString(hash)
+	if len(newID) != len(a.buildID) {
+		return fmt.Errorf("internal error: build ID length mismatch %q vs %q", a.buildID, newID)
+	}
+
+	// Replace with new content-based ID.
+	a.buildID = newID
+	if len(matches) == 0 {
+		// Assume the user specified -buildid= to override what we were going to choose.
+		return nil
+	}
+
+	if rewrite {
+		w, err := os.OpenFile(target, os.O_WRONLY, 0)
+		if err != nil {
+			return err
+		}
+		err = buildid.Rewrite(w, matches, newID)
+		if err != nil {
+			w.Close()
+			return err
+		}
+		if err := w.Close(); err != nil {
+			return err
+		}
+	}
+
+	// Cache package builds, but not binaries (link steps).
+	// The expectation is that binaries are not reused
+	// nearly as often as individual packages, and they're
+	// much larger, so the cache-footprint-to-utility ratio
+	// of binaries is much lower for binaries.
+	// Not caching the link step also makes sure that repeated "go run" at least
+	// always rerun the linker, so that they don't get too fast.
+	// (We don't want people thinking go is a scripting language.)
+	// Note also that if we start caching binaries, then we will
+	// copy the binaries out of the cache to run them, and then
+	// that will mean the go process is itself writing a binary
+	// and then executing it, so we will need to defend against
+	// ETXTBSY problems as discussed in exec.go and golang.org/issue/22220.
+	if c := cache.Default(); c != nil && a.Mode == "build" {
+		r, err := os.Open(target)
+		if err == nil {
+			if a.output == nil {
+				panic("internal error: a.output not set")
+			}
+			outputID, _, err := c.Put(a.actionID, r)
+			if err == nil && cfg.BuildX {
+				b.Showcmd("", "%s # internal", joinUnambiguously(str.StringList("cp", target, c.OutputFile(outputID))))
+			}
+			c.PutBytes(cache.Subkey(a.actionID, "stdout"), a.output)
+			r.Close()
+		}
+	}
+
+	return nil
+}
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
new file mode 100644
index 0000000..c4c1500
--- /dev/null
+++ b/src/cmd/go/internal/work/exec.go
@@ -0,0 +1,2422 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Action graph execution.
+
+package work
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/go/internal/str"
+)
+
+// actionList returns the list of actions in the dag rooted at root
+// as visited in a depth-first post-order traversal.
+func actionList(root *Action) []*Action {
+	seen := map[*Action]bool{}
+	all := []*Action{}
+	var walk func(*Action)
+	walk = func(a *Action) {
+		if seen[a] {
+			return
+		}
+		seen[a] = true
+		for _, a1 := range a.Deps {
+			walk(a1)
+		}
+		all = append(all, a)
+	}
+	walk(root)
+	return all
+}
+
+// do runs the action graph rooted at root.
+func (b *Builder) Do(root *Action) {
+	if c := cache.Default(); c != nil && !b.ComputeStaleOnly {
+		// If we're doing real work, take time at the end to trim the cache.
+		defer c.Trim()
+	}
+
+	// Build list of all actions, assigning depth-first post-order priority.
+	// The original implementation here was a true queue
+	// (using a channel) but it had the effect of getting
+	// distracted by low-level leaf actions to the detriment
+	// of completing higher-level actions. The order of
+	// work does not matter much to overall execution time,
+	// but when running "go test std" it is nice to see each test
+	// results as soon as possible. The priorities assigned
+	// ensure that, all else being equal, the execution prefers
+	// to do what it would have done first in a simple depth-first
+	// dependency order traversal.
+	all := actionList(root)
+	for i, a := range all {
+		a.priority = i
+	}
+
+	if cfg.DebugActiongraph != "" {
+		js := actionGraphJSON(root)
+		if err := ioutil.WriteFile(cfg.DebugActiongraph, []byte(js), 0666); err != nil {
+			fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err)
+			base.SetExitStatus(1)
+		}
+	}
+
+	b.readySema = make(chan bool, len(all))
+
+	// Initialize per-action execution state.
+	for _, a := range all {
+		for _, a1 := range a.Deps {
+			a1.triggers = append(a1.triggers, a)
+		}
+		a.pending = len(a.Deps)
+		if a.pending == 0 {
+			b.ready.push(a)
+			b.readySema <- true
+		}
+	}
+
+	// Handle runs a single action and takes care of triggering
+	// any actions that are runnable as a result.
+	handle := func(a *Action) {
+		var err error
+
+		if a.Func != nil && (!a.Failed || a.IgnoreFail) {
+			if err == nil {
+				err = a.Func(b, a)
+			}
+		}
+
+		// The actions run in parallel but all the updates to the
+		// shared work state are serialized through b.exec.
+		b.exec.Lock()
+		defer b.exec.Unlock()
+
+		if err != nil {
+			if err == errPrintedOutput {
+				base.SetExitStatus(2)
+			} else {
+				base.Errorf("%s", err)
+			}
+			a.Failed = true
+		}
+
+		for _, a0 := range a.triggers {
+			if a.Failed {
+				a0.Failed = true
+			}
+			if a0.pending--; a0.pending == 0 {
+				b.ready.push(a0)
+				b.readySema <- true
+			}
+		}
+
+		if a == root {
+			close(b.readySema)
+		}
+	}
+
+	var wg sync.WaitGroup
+
+	// Kick off goroutines according to parallelism.
+	// If we are using the -n flag (just printing commands)
+	// drop the parallelism to 1, both to make the output
+	// deterministic and because there is no real work anyway.
+	par := cfg.BuildP
+	if cfg.BuildN {
+		par = 1
+	}
+	for i := 0; i < par; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			for {
+				select {
+				case _, ok := <-b.readySema:
+					if !ok {
+						return
+					}
+					// Receiving a value from b.readySema entitles
+					// us to take from the ready queue.
+					b.exec.Lock()
+					a := b.ready.pop()
+					b.exec.Unlock()
+					handle(a)
+				case <-base.Interrupted:
+					base.SetExitStatus(1)
+					return
+				}
+			}
+		}()
+	}
+
+	wg.Wait()
+}
+
+// buildActionID computes the action ID for a build action.
+func (b *Builder) buildActionID(a *Action) cache.ActionID {
+	p := a.Package
+	h := cache.NewHash("build " + p.ImportPath)
+
+	// Configuration independent of compiler toolchain.
+	// Note: buildmode has already been accounted for in buildGcflags
+	// and should not be inserted explicitly. Most buildmodes use the
+	// same compiler settings and can reuse each other's results.
+	// If not, the reason is already recorded in buildGcflags.
+	fmt.Fprintf(h, "compile\n")
+	// The compiler hides the exact value of $GOROOT
+	// when building things in GOROOT,
+	// but it does not hide the exact value of $GOPATH.
+	// Include the full dir in that case.
+	// Assume b.WorkDir is being trimmed properly.
+	if !p.Goroot && !strings.HasPrefix(p.Dir, b.WorkDir) {
+		fmt.Fprintf(h, "dir %s\n", p.Dir)
+	}
+	fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
+	fmt.Fprintf(h, "import %q\n", p.ImportPath)
+	fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
+	if len(p.CgoFiles)+len(p.SwigFiles) > 0 {
+		fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo"))
+		cppflags, cflags, cxxflags, fflags, _, _ := b.CFlags(p)
+		fmt.Fprintf(h, "CC=%q %q %q\n", b.ccExe(), cppflags, cflags)
+		if len(p.CXXFiles)+len(p.SwigFiles) > 0 {
+			fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags)
+		}
+		if len(p.FFiles) > 0 {
+			fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags)
+		}
+		// TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
+	}
+	if p.Internal.CoverMode != "" {
+		fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
+	}
+
+	// Configuration specific to compiler toolchain.
+	switch cfg.BuildToolchainName {
+	default:
+		base.Fatalf("buildActionID: unknown build toolchain %q", cfg.BuildToolchainName)
+	case "gc":
+		fmt.Fprintf(h, "compile %s %q %q\n", b.toolID("compile"), forcedGcflags, p.Internal.Gcflags)
+		if len(p.SFiles) > 0 {
+			fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags)
+		}
+		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
+
+		// TODO(rsc): Convince compiler team not to add more magic environment variables,
+		// or perhaps restrict the environment variables passed to subprocesses.
+		magic := []string{
+			"GOCLOBBERDEADHASH",
+			"GOSSAFUNC",
+			"GO_SSA_PHI_LOC_CUTOFF",
+			"GOSSAHASH",
+		}
+		for _, env := range magic {
+			if x := os.Getenv(env); x != "" {
+				fmt.Fprintf(h, "magic %s=%s\n", env, x)
+			}
+		}
+		if os.Getenv("GOSSAHASH") != "" {
+			for i := 0; ; i++ {
+				env := fmt.Sprintf("GOSSAHASH%d", i)
+				x := os.Getenv(env)
+				if x == "" {
+					break
+				}
+				fmt.Fprintf(h, "magic %s=%s\n", env, x)
+			}
+		}
+		if os.Getenv("GSHS_LOGFILE") != "" {
+			// Clumsy hack. Compiler writes to this log file,
+			// so do not allow use of cache at all.
+			// We will still write to the cache but it will be
+			// essentially unfindable.
+			fmt.Fprintf(h, "nocache %d\n", time.Now().UnixNano())
+		}
+
+	case "gccgo":
+		id, err := b.gccgoToolID(BuildToolchain.compiler(), "go")
+		if err != nil {
+			base.Fatalf("%v", err)
+		}
+		fmt.Fprintf(h, "compile %s %q %q\n", id, forcedGccgoflags, p.Internal.Gccgoflags)
+		fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p))
+		if len(p.SFiles) > 0 {
+			id, err = b.gccgoToolID(BuildToolchain.compiler(), "assembler-with-cpp")
+			// Ignore error; different assembler versions
+			// are unlikely to make any difference anyhow.
+			fmt.Fprintf(h, "asm %q\n", id)
+		}
+	}
+
+	// Input files.
+	inputFiles := str.StringList(
+		p.GoFiles,
+		p.CgoFiles,
+		p.CFiles,
+		p.CXXFiles,
+		p.FFiles,
+		p.MFiles,
+		p.HFiles,
+		p.SFiles,
+		p.SysoFiles,
+		p.SwigFiles,
+		p.SwigCXXFiles,
+	)
+	for _, file := range inputFiles {
+		fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file)))
+	}
+	for _, a1 := range a.Deps {
+		p1 := a1.Package
+		if p1 != nil {
+			fmt.Fprintf(h, "import %s %s\n", p1.ImportPath, contentID(a1.buildID))
+		}
+	}
+
+	return h.Sum()
+}
+
+// build is the action for building a single package.
+// Note that any new influence on this logic must be reported in b.buildActionID above as well.
+func (b *Builder) build(a *Action) (err error) {
+	p := a.Package
+	cached := false
+	if !p.BinaryOnly {
+		if b.useCache(a, p, b.buildActionID(a), p.Target) {
+			// If this build triggers a header install, run cgo to get the header.
+			// TODO(rsc): Once we can cache multiple file outputs from an action,
+			// the header should be cached, and then this awful test can be deleted.
+			// Need to look for install header actions depending on this action,
+			// or depending on a link that depends on this action.
+			needHeader := false
+			if (a.Package.UsesCgo() || a.Package.UsesSwig()) && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
+				for _, t1 := range a.triggers {
+					if t1.Mode == "install header" {
+						needHeader = true
+						goto CheckedHeader
+					}
+				}
+				for _, t1 := range a.triggers {
+					for _, t2 := range t1.triggers {
+						if t2.Mode == "install header" {
+							needHeader = true
+							goto CheckedHeader
+						}
+					}
+				}
+			}
+		CheckedHeader:
+			if b.ComputeStaleOnly || !a.needVet && !needHeader {
+				return nil
+			}
+			cached = true
+		}
+		defer b.flushOutput(a)
+	}
+
+	defer func() {
+		if err != nil && err != errPrintedOutput {
+			err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
+		}
+	}()
+	if cfg.BuildN {
+		// In -n mode, print a banner between packages.
+		// The banner is five lines so that when changes to
+		// different sections of the bootstrap script have to
+		// be merged, the banners give patch something
+		// to use to find its context.
+		b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
+	}
+
+	if cfg.BuildV {
+		b.Print(a.Package.ImportPath + "\n")
+	}
+
+	if a.Package.BinaryOnly {
+		_, err := os.Stat(a.Package.Target)
+		if err == nil {
+			a.built = a.Package.Target
+			a.Target = a.Package.Target
+			a.buildID = b.fileHash(a.Package.Target)
+			a.Package.Stale = false
+			a.Package.StaleReason = "binary-only package"
+			return nil
+		}
+		if b.ComputeStaleOnly {
+			a.Package.Stale = true
+			a.Package.StaleReason = "missing or invalid binary-only package"
+			return nil
+		}
+		return fmt.Errorf("missing or invalid binary-only package")
+	}
+
+	if err := b.Mkdir(a.Objdir); err != nil {
+		return err
+	}
+	objdir := a.Objdir
+
+	// make target directory
+	dir, _ := filepath.Split(a.Target)
+	if dir != "" {
+		if err := b.Mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
+
+	gofiles = append(gofiles, a.Package.GoFiles...)
+	cgofiles = append(cgofiles, a.Package.CgoFiles...)
+	cfiles = append(cfiles, a.Package.CFiles...)
+	sfiles = append(sfiles, a.Package.SFiles...)
+	cxxfiles = append(cxxfiles, a.Package.CXXFiles...)
+
+	if a.Package.UsesCgo() || a.Package.UsesSwig() {
+		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
+			return
+		}
+	}
+
+	// Run SWIG on each .swig and .swigcxx file.
+	// Each run will generate two files, a .go file and a .c or .cxx file.
+	// The .go file will use import "C" and is to be processed by cgo.
+	if a.Package.UsesSwig() {
+		outGo, outC, outCXX, err := b.swig(a, a.Package, objdir, pcCFLAGS)
+		if err != nil {
+			return err
+		}
+		cgofiles = append(cgofiles, outGo...)
+		cfiles = append(cfiles, outC...)
+		cxxfiles = append(cxxfiles, outCXX...)
+	}
+
+	// If we're doing coverage, preprocess the .go files and put them in the work directory
+	if a.Package.Internal.CoverMode != "" {
+		for i, file := range str.StringList(gofiles, cgofiles) {
+			var sourceFile string
+			var coverFile string
+			var key string
+			if strings.HasSuffix(file, ".cgo1.go") {
+				// cgo files have absolute paths
+				base := filepath.Base(file)
+				sourceFile = file
+				coverFile = objdir + base
+				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
+			} else {
+				sourceFile = filepath.Join(a.Package.Dir, file)
+				coverFile = objdir + file
+				key = file
+			}
+			coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go"
+			cover := a.Package.Internal.CoverVars[key]
+			if cover == nil || base.IsTestFile(file) {
+				// Not covering this file.
+				continue
+			}
+			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
+				return err
+			}
+			if i < len(gofiles) {
+				gofiles[i] = coverFile
+			} else {
+				cgofiles[i-len(gofiles)] = coverFile
+			}
+		}
+	}
+
+	// Run cgo.
+	if a.Package.UsesCgo() || a.Package.UsesSwig() {
+		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
+		// There is one exception: runtime/cgo's job is to bridge the
+		// cgo and non-cgo worlds, so it necessarily has files in both.
+		// In that case gcc only gets the gcc_* files.
+		var gccfiles []string
+		gccfiles = append(gccfiles, cfiles...)
+		cfiles = nil
+		if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
+			filter := func(files, nongcc, gcc []string) ([]string, []string) {
+				for _, f := range files {
+					if strings.HasPrefix(f, "gcc_") {
+						gcc = append(gcc, f)
+					} else {
+						nongcc = append(nongcc, f)
+					}
+				}
+				return nongcc, gcc
+			}
+			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
+		} else {
+			for _, sfile := range sfiles {
+				data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
+				if err == nil {
+					if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
+						bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
+						bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) {
+						return fmt.Errorf("package using cgo has Go assembly file %s", sfile)
+					}
+				}
+			}
+			gccfiles = append(gccfiles, sfiles...)
+			sfiles = nil
+		}
+
+		outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
+		if err != nil {
+			return err
+		}
+		if cfg.BuildToolchainName == "gccgo" {
+			cgoObjects = append(cgoObjects, a.Objdir+"_cgo_flags")
+		}
+		cgoObjects = append(cgoObjects, outObj...)
+		gofiles = append(gofiles, outGo...)
+	}
+	if cached && !a.needVet {
+		return nil
+	}
+
+	// Sanity check only, since Package.load already checked as well.
+	if len(gofiles) == 0 {
+		return &load.NoGoError{Package: a.Package}
+	}
+
+	// Prepare Go vet config if needed.
+	var vcfg *vetConfig
+	if a.needVet {
+		// Pass list of absolute paths to vet,
+		// so that vet's error messages will use absolute paths,
+		// so that we can reformat them relative to the directory
+		// in which the go command is invoked.
+		vcfg = &vetConfig{
+			Compiler:    cfg.BuildToolchainName,
+			Dir:         a.Package.Dir,
+			GoFiles:     mkAbsFiles(a.Package.Dir, gofiles),
+			ImportPath:  a.Package.ImportPath,
+			ImportMap:   make(map[string]string),
+			PackageFile: make(map[string]string),
+		}
+		a.vetCfg = vcfg
+		for i, raw := range a.Package.Internal.RawImports {
+			final := a.Package.Imports[i]
+			vcfg.ImportMap[raw] = final
+		}
+	}
+
+	// Prepare Go import config.
+	// We start it off with a comment so it can't be empty, so icfg.Bytes() below is never nil.
+	// It should never be empty anyway, but there have been bugs in the past that resulted
+	// in empty configs, which then unfortunately turn into "no config passed to compiler",
+	// and the compiler falls back to looking in pkg itself, which mostly works,
+	// except when it doesn't.
+	var icfg bytes.Buffer
+	fmt.Fprintf(&icfg, "# import config\n")
+
+	for i, raw := range a.Package.Internal.RawImports {
+		final := a.Package.Imports[i]
+		if final != raw {
+			fmt.Fprintf(&icfg, "importmap %s=%s\n", raw, final)
+		}
+	}
+
+	// Compute the list of mapped imports in the vet config
+	// so that we can add any missing mappings below.
+	var vcfgMapped map[string]bool
+	if vcfg != nil {
+		vcfgMapped = make(map[string]bool)
+		for _, p := range vcfg.ImportMap {
+			vcfgMapped[p] = true
+		}
+	}
+
+	for _, a1 := range a.Deps {
+		p1 := a1.Package
+		if p1 == nil || p1.ImportPath == "" || a1.built == "" {
+			continue
+		}
+		fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
+		if vcfg != nil {
+			// Add import mapping if needed
+			// (for imports like "runtime/cgo" that appear only in generated code).
+			if !vcfgMapped[p1.ImportPath] {
+				vcfg.ImportMap[p1.ImportPath] = p1.ImportPath
+			}
+			vcfg.PackageFile[p1.ImportPath] = a1.built
+		}
+	}
+
+	if cached {
+		// The cached package file is OK, so we don't need to run the compile.
+		// We've only going through the motions to prepare the vet configuration,
+		// which is now complete.
+		return nil
+	}
+
+	// Compile Go.
+	objpkg := objdir + "_pkg_.a"
+	ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), len(sfiles) > 0, gofiles)
+	if len(out) > 0 {
+		b.showOutput(a, a.Package.Dir, a.Package.ImportPath, b.processOutput(out))
+		if err != nil {
+			return errPrintedOutput
+		}
+	}
+	if err != nil {
+		return err
+	}
+	if ofile != objpkg {
+		objects = append(objects, ofile)
+	}
+
+	// Copy .h files named for goos or goarch or goos_goarch
+	// to names using GOOS and GOARCH.
+	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
+	_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
+	_goos := "_" + cfg.Goos
+	_goarch := "_" + cfg.Goarch
+	for _, file := range a.Package.HFiles {
+		name, ext := fileExtSplit(file)
+		switch {
+		case strings.HasSuffix(name, _goos_goarch):
+			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
+			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+				return err
+			}
+		case strings.HasSuffix(name, _goarch):
+			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
+			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+				return err
+			}
+		case strings.HasSuffix(name, _goos):
+			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
+			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+				return err
+			}
+		}
+	}
+
+	for _, file := range cfiles {
+		out := file[:len(file)-len(".c")] + ".o"
+		if err := BuildToolchain.cc(b, a, objdir+out, file); err != nil {
+			return err
+		}
+		objects = append(objects, out)
+	}
+
+	// Assemble .s files.
+	if len(sfiles) > 0 {
+		ofiles, err := BuildToolchain.asm(b, a, sfiles)
+		if err != nil {
+			return err
+		}
+		objects = append(objects, ofiles...)
+	}
+
+	// For gccgo on ELF systems, we write the build ID as an assembler file.
+	// This lets us set the the SHF_EXCLUDE flag.
+	// This is read by readGccgoArchive in cmd/internal/buildid/buildid.go.
+	if a.buildID != "" && cfg.BuildToolchainName == "gccgo" {
+		switch cfg.Goos {
+		case "android", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
+			asmfile, err := b.gccgoBuildIDELFFile(a)
+			if err != nil {
+				return err
+			}
+			ofiles, err := BuildToolchain.asm(b, a, []string{asmfile})
+			if err != nil {
+				return err
+			}
+			objects = append(objects, ofiles...)
+		}
+	}
+
+	// NOTE(rsc): On Windows, it is critically important that the
+	// gcc-compiled objects (cgoObjects) be listed after the ordinary
+	// objects in the archive. I do not know why this is.
+	// https://golang.org/issue/2601
+	objects = append(objects, cgoObjects...)
+
+	// Add system object files.
+	for _, syso := range a.Package.SysoFiles {
+		objects = append(objects, filepath.Join(a.Package.Dir, syso))
+	}
+
+	// Pack into archive in objdir directory.
+	// If the Go compiler wrote an archive, we only need to add the
+	// object files for non-Go sources to the archive.
+	// If the Go compiler wrote an archive and the package is entirely
+	// Go sources, there is no pack to execute at all.
+	if len(objects) > 0 {
+		if err := BuildToolchain.pack(b, a, objpkg, objects); err != nil {
+			return err
+		}
+	}
+
+	if err := b.updateBuildID(a, objpkg, true); err != nil {
+		return err
+	}
+
+	a.built = objpkg
+	return nil
+}
+
+type vetConfig struct {
+	Compiler    string
+	Dir         string
+	GoFiles     []string
+	ImportMap   map[string]string
+	PackageFile map[string]string
+	ImportPath  string
+
+	SucceedOnTypecheckFailure bool
+}
+
+// VetTool is the path to an alternate vet tool binary.
+// The caller is expected to set it (if needed) before executing any vet actions.
+var VetTool string
+
+// VetFlags are the flags to pass to vet.
+// The caller is expected to set them before executing any vet actions.
+var VetFlags []string
+
+func (b *Builder) vet(a *Action) error {
+	// a.Deps[0] is the build of the package being vetted.
+	// a.Deps[1] is the build of the "fmt" package.
+
+	vcfg := a.Deps[0].vetCfg
+	if vcfg == nil {
+		// Vet config should only be missing if the build failed.
+		if !a.Deps[0].Failed {
+			return fmt.Errorf("vet config not found")
+		}
+		return nil
+	}
+
+	if vcfg.ImportMap["fmt"] == "" {
+		a1 := a.Deps[1]
+		vcfg.ImportMap["fmt"] = "fmt"
+		vcfg.PackageFile["fmt"] = a1.built
+	}
+
+	// During go test, ignore type-checking failures during vet.
+	// We only run vet if the compilation has succeeded,
+	// so at least for now assume the bug is in vet.
+	// We know of at least #18395.
+	// TODO(rsc,gri): Try to remove this for Go 1.11.
+	vcfg.SucceedOnTypecheckFailure = cfg.CmdName == "test"
+
+	js, err := json.MarshalIndent(vcfg, "", "\t")
+	if err != nil {
+		return fmt.Errorf("internal error marshaling vet config: %v", err)
+	}
+	js = append(js, '\n')
+	if err := b.writeFile(a.Objdir+"vet.cfg", js); err != nil {
+		return err
+	}
+
+	var env []string
+	if cfg.BuildToolchainName == "gccgo" {
+		env = append(env, "GCCGO="+BuildToolchain.compiler())
+	}
+
+	p := a.Package
+	tool := VetTool
+	if tool == "" {
+		tool = base.Tool("vet")
+	}
+	return b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, VetFlags, a.Objdir+"vet.cfg")
+}
+
+// linkActionID computes the action ID for a link action.
+func (b *Builder) linkActionID(a *Action) cache.ActionID {
+	p := a.Package
+	h := cache.NewHash("link " + p.ImportPath)
+
+	// Toolchain-independent configuration.
+	fmt.Fprintf(h, "link\n")
+	fmt.Fprintf(h, "buildmode %s goos %s goarch %s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
+	fmt.Fprintf(h, "import %q\n", p.ImportPath)
+	fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
+
+	// Toolchain-dependent configuration, shared with b.linkSharedActionID.
+	b.printLinkerConfig(h, p)
+
+	// Input files.
+	for _, a1 := range a.Deps {
+		p1 := a1.Package
+		if p1 != nil {
+			if a1.built != "" || a1.buildID != "" {
+				buildID := a1.buildID
+				if buildID == "" {
+					buildID = b.buildID(a1.built)
+				}
+				fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(buildID))
+			}
+			// Because we put package main's full action ID into the binary's build ID,
+			// we must also put the full action ID into the binary's action ID hash.
+			if p1.Name == "main" {
+				fmt.Fprintf(h, "packagemain %s\n", a1.buildID)
+			}
+			if p1.Shlib != "" {
+				fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
+			}
+		}
+	}
+
+	return h.Sum()
+}
+
+// printLinkerConfig prints the linker config into the hash h,
+// as part of the computation of a linker-related action ID.
+func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) {
+	switch cfg.BuildToolchainName {
+	default:
+		base.Fatalf("linkActionID: unknown toolchain %q", cfg.BuildToolchainName)
+
+	case "gc":
+		fmt.Fprintf(h, "link %s %q %s\n", b.toolID("link"), forcedLdflags, ldBuildmode)
+		if p != nil {
+			fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags)
+		}
+		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
+
+		// The linker writes source file paths that say GOROOT_FINAL.
+		fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL)
+
+		// TODO(rsc): Convince linker team not to add more magic environment variables,
+		// or perhaps restrict the environment variables passed to subprocesses.
+		magic := []string{
+			"GO_EXTLINK_ENABLED",
+		}
+		for _, env := range magic {
+			if x := os.Getenv(env); x != "" {
+				fmt.Fprintf(h, "magic %s=%s\n", env, x)
+			}
+		}
+
+		// TODO(rsc): Do cgo settings and flags need to be included?
+		// Or external linker settings and flags?
+
+	case "gccgo":
+		id, err := b.gccgoToolID(BuildToolchain.linker(), "go")
+		if err != nil {
+			base.Fatalf("%v", err)
+		}
+		fmt.Fprintf(h, "link %s %s\n", id, ldBuildmode)
+		// TODO(iant): Should probably include cgo flags here.
+	}
+}
+
+// link is the action for linking a single command.
+// Note that any new influence on this logic must be reported in b.linkActionID above as well.
+func (b *Builder) link(a *Action) (err error) {
+	if b.useCache(a, a.Package, b.linkActionID(a), a.Package.Target) {
+		return nil
+	}
+	defer b.flushOutput(a)
+
+	if err := b.Mkdir(a.Objdir); err != nil {
+		return err
+	}
+
+	importcfg := a.Objdir + "importcfg.link"
+	if err := b.writeLinkImportcfg(a, importcfg); err != nil {
+		return err
+	}
+
+	// make target directory
+	dir, _ := filepath.Split(a.Target)
+	if dir != "" {
+		if err := b.Mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	if err := BuildToolchain.ld(b, a, a.Target, importcfg, a.Deps[0].built); err != nil {
+		return err
+	}
+
+	// Update the binary with the final build ID.
+	// But if OmitDebug is set, don't rewrite the binary, because we set OmitDebug
+	// on binaries that we are going to run and then delete.
+	// There's no point in doing work on such a binary.
+	// Worse, opening the binary for write here makes it
+	// essentially impossible to safely fork+exec due to a fundamental
+	// incompatibility between ETXTBSY and threads on modern Unix systems.
+	// See golang.org/issue/22220.
+	// We still call updateBuildID to update a.buildID, which is important
+	// for test result caching, but passing rewrite=false (final arg)
+	// means we don't actually rewrite the binary, nor store the
+	// result into the cache.
+	// Not calling updateBuildID means we also don't insert these
+	// binaries into the build object cache. That's probably a net win:
+	// less cache space wasted on large binaries we are not likely to
+	// need again. (On the other hand it does make repeated go test slower.)
+	if err := b.updateBuildID(a, a.Target, !a.Package.Internal.OmitDebug); err != nil {
+		return err
+	}
+
+	a.built = a.Target
+	return nil
+}
+
+func (b *Builder) writeLinkImportcfg(a *Action, file string) error {
+	// Prepare Go import cfg.
+	var icfg bytes.Buffer
+	for _, a1 := range a.Deps {
+		p1 := a1.Package
+		if p1 == nil {
+			continue
+		}
+		fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
+		if p1.Shlib != "" {
+			fmt.Fprintf(&icfg, "packageshlib %s=%s\n", p1.ImportPath, p1.Shlib)
+		}
+	}
+	return b.writeFile(file, icfg.Bytes())
+}
+
+// PkgconfigCmd returns a pkg-config binary name
+// defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
+func (b *Builder) PkgconfigCmd() string {
+	return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0]
+}
+
+// splitPkgConfigOutput parses the pkg-config output into a slice of
+// flags. pkg-config always uses \ to escape special characters.
+func splitPkgConfigOutput(out []byte) []string {
+	if len(out) == 0 {
+		return nil
+	}
+	var flags []string
+	flag := make([]byte, len(out))
+	r, w := 0, 0
+	for r < len(out) {
+		switch out[r] {
+		case ' ', '\t', '\r', '\n':
+			if w > 0 {
+				flags = append(flags, string(flag[:w]))
+			}
+			w = 0
+		case '\\':
+			r++
+			fallthrough
+		default:
+			if r < len(out) {
+				flag[w] = out[r]
+				w++
+			}
+		}
+		r++
+	}
+	if w > 0 {
+		flags = append(flags, string(flag[:w]))
+	}
+	return flags
+}
+
+// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
+func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) {
+	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
+		var pcflags []string
+		for len(pkgs) > 0 && strings.HasPrefix(pkgs[0], "--") {
+			pcflags = append(pcflags, pkgs[0])
+			pkgs = pkgs[1:]
+		}
+		for _, pkg := range pkgs {
+			if !load.SafeArg(pkg) {
+				return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg)
+			}
+		}
+		var out []byte
+		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs)
+		if err != nil {
+			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
+			b.Print(err.Error() + "\n")
+			return nil, nil, errPrintedOutput
+		}
+		if len(out) > 0 {
+			cflags = splitPkgConfigOutput(out)
+			if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil {
+				return nil, nil, err
+			}
+		}
+		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs)
+		if err != nil {
+			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
+			b.Print(err.Error() + "\n")
+			return nil, nil, errPrintedOutput
+		}
+		if len(out) > 0 {
+			ldflags = strings.Fields(string(out))
+			if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil {
+				return nil, nil, err
+			}
+		}
+	}
+
+	return
+}
+
+func (b *Builder) installShlibname(a *Action) error {
+	// TODO: BuildN
+	a1 := a.Deps[0]
+	err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
+	if err != nil {
+		return err
+	}
+	if cfg.BuildX {
+		b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target)
+	}
+	return nil
+}
+
+func (b *Builder) linkSharedActionID(a *Action) cache.ActionID {
+	h := cache.NewHash("linkShared")
+
+	// Toolchain-independent configuration.
+	fmt.Fprintf(h, "linkShared\n")
+	fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
+
+	// Toolchain-dependent configuration, shared with b.linkActionID.
+	b.printLinkerConfig(h, nil)
+
+	// Input files.
+	for _, a1 := range a.Deps {
+		p1 := a1.Package
+		if a1.built == "" {
+			continue
+		}
+		if p1 != nil {
+			fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
+			if p1.Shlib != "" {
+				fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
+			}
+		}
+	}
+	// Files named on command line are special.
+	for _, a1 := range a.Deps[0].Deps {
+		p1 := a1.Package
+		fmt.Fprintf(h, "top %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
+	}
+
+	return h.Sum()
+}
+
+func (b *Builder) linkShared(a *Action) (err error) {
+	if b.useCache(a, nil, b.linkSharedActionID(a), a.Target) {
+		return nil
+	}
+	defer b.flushOutput(a)
+
+	if err := b.Mkdir(a.Objdir); err != nil {
+		return err
+	}
+
+	importcfg := a.Objdir + "importcfg.link"
+	if err := b.writeLinkImportcfg(a, importcfg); err != nil {
+		return err
+	}
+
+	// TODO(rsc): There is a missing updateBuildID here,
+	// but we have to decide where to store the build ID in these files.
+	a.built = a.Target
+	return BuildToolchain.ldShared(b, a, a.Deps[0].Deps, a.Target, importcfg, a.Deps)
+}
+
+// BuildInstallFunc is the action for installing a single package or executable.
+func BuildInstallFunc(b *Builder, a *Action) (err error) {
+	defer func() {
+		if err != nil && err != errPrintedOutput {
+			// a.Package == nil is possible for the go install -buildmode=shared
+			// action that installs libmangledname.so, which corresponds to
+			// a list of packages, not just one.
+			sep, path := "", ""
+			if a.Package != nil {
+				sep, path = " ", a.Package.ImportPath
+			}
+			err = fmt.Errorf("go %s%s%s: %v", cfg.CmdName, sep, path, err)
+		}
+	}()
+
+	a1 := a.Deps[0]
+	a.buildID = a1.buildID
+
+	// If we are using the eventual install target as an up-to-date
+	// cached copy of the thing we built, then there's no need to
+	// copy it into itself (and that would probably fail anyway).
+	// In this case a1.built == a.Target because a1.built == p.Target,
+	// so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes.
+	if a1.built == a.Target {
+		a.built = a.Target
+		b.cleanup(a1)
+		// Whether we're smart enough to avoid a complete rebuild
+		// depends on exactly what the staleness and rebuild algorithms
+		// are, as well as potentially the state of the Go build cache.
+		// We don't really want users to be able to infer (or worse start depending on)
+		// those details from whether the modification time changes during
+		// "go install", so do a best-effort update of the file times to make it
+		// look like we rewrote a.Target even if we did not. Updating the mtime
+		// may also help other mtime-based systems that depend on our
+		// previous mtime updates that happened more often.
+		// This is still not perfect - we ignore the error result, and if the file was
+		// unwritable for some reason then pretending to have written it is also
+		// confusing - but it's probably better than not doing the mtime update.
+		//
+		// But don't do that for the special case where building an executable
+		// with -linkshared implicitly installs all its dependent libraries.
+		// We want to hide that awful detail as much as possible, so don't
+		// advertise it by touching the mtimes (usually the libraries are up
+		// to date).
+		if !a.buggyInstall {
+			now := time.Now()
+			os.Chtimes(a.Target, now, now)
+		}
+		return nil
+	}
+	if b.ComputeStaleOnly {
+		return nil
+	}
+
+	if err := b.Mkdir(a.Objdir); err != nil {
+		return err
+	}
+
+	perm := os.FileMode(0666)
+	if a1.Mode == "link" {
+		switch cfg.BuildBuildmode {
+		case "c-archive", "c-shared", "plugin":
+		default:
+			perm = 0777
+		}
+	}
+
+	// make target directory
+	dir, _ := filepath.Split(a.Target)
+	if dir != "" {
+		if err := b.Mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	defer b.cleanup(a1)
+
+	return b.moveOrCopyFile(a, a.Target, a1.built, perm, false)
+}
+
+// cleanup removes a's object dir to keep the amount of
+// on-disk garbage down in a large build. On an operating system
+// with aggressive buffering, cleaning incrementally like
+// this keeps the intermediate objects from hitting the disk.
+func (b *Builder) cleanup(a *Action) {
+	if !cfg.BuildWork {
+		if cfg.BuildX {
+			b.Showcmd("", "rm -r %s", a.Objdir)
+		}
+		os.RemoveAll(a.Objdir)
+	}
+}
+
+// moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
+func (b *Builder) moveOrCopyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
+	if cfg.BuildN {
+		b.Showcmd("", "mv %s %s", src, dst)
+		return nil
+	}
+
+	// If we can update the mode and rename to the dst, do it.
+	// Otherwise fall back to standard copy.
+
+	// If the source is in the build cache, we need to copy it.
+	if strings.HasPrefix(src, cache.DefaultDir()) {
+		return b.copyFile(a, dst, src, perm, force)
+	}
+
+	// On Windows, always copy the file, so that we respect the NTFS
+	// permissions of the parent folder. https://golang.org/issue/22343.
+	// What matters here is not cfg.Goos (the system we are building
+	// for) but runtime.GOOS (the system we are building on).
+	if runtime.GOOS == "windows" {
+		return b.copyFile(a, dst, src, perm, force)
+	}
+
+	// If the destination directory has the group sticky bit set,
+	// we have to copy the file to retain the correct permissions.
+	// https://golang.org/issue/18878
+	if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
+		if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
+			return b.copyFile(a, dst, src, perm, force)
+		}
+	}
+
+	// The perm argument is meant to be adjusted according to umask,
+	// but we don't know what the umask is.
+	// Create a dummy file to find out.
+	// This avoids build tags and works even on systems like Plan 9
+	// where the file mask computation incorporates other information.
+	mode := perm
+	f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
+	if err == nil {
+		fi, err := f.Stat()
+		if err == nil {
+			mode = fi.Mode() & 0777
+		}
+		name := f.Name()
+		f.Close()
+		os.Remove(name)
+	}
+
+	if err := os.Chmod(src, mode); err == nil {
+		if err := os.Rename(src, dst); err == nil {
+			if cfg.BuildX {
+				b.Showcmd("", "mv %s %s", src, dst)
+			}
+			return nil
+		}
+	}
+
+	return b.copyFile(a, dst, src, perm, force)
+}
+
+// copyFile is like 'cp src dst'.
+func (b *Builder) copyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
+	if cfg.BuildN || cfg.BuildX {
+		b.Showcmd("", "cp %s %s", src, dst)
+		if cfg.BuildN {
+			return nil
+		}
+	}
+
+	sf, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer sf.Close()
+
+	// Be careful about removing/overwriting dst.
+	// Do not remove/overwrite if dst exists and is a directory
+	// or a non-object file.
+	if fi, err := os.Stat(dst); err == nil {
+		if fi.IsDir() {
+			return fmt.Errorf("build output %q already exists and is a directory", dst)
+		}
+		if !force && fi.Mode().IsRegular() && !isObject(dst) {
+			return fmt.Errorf("build output %q already exists and is not an object file", dst)
+		}
+	}
+
+	// On Windows, remove lingering ~ file from last attempt.
+	if base.ToolIsWindows {
+		if _, err := os.Stat(dst + "~"); err == nil {
+			os.Remove(dst + "~")
+		}
+	}
+
+	mayberemovefile(dst)
+	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+	if err != nil && base.ToolIsWindows {
+		// Windows does not allow deletion of a binary file
+		// while it is executing. Try to move it out of the way.
+		// If the move fails, which is likely, we'll try again the
+		// next time we do an install of this binary.
+		if err := os.Rename(dst, dst+"~"); err == nil {
+			os.Remove(dst + "~")
+		}
+		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+	}
+	if err != nil {
+		return err
+	}
+
+	_, err = io.Copy(df, sf)
+	df.Close()
+	if err != nil {
+		mayberemovefile(dst)
+		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
+	}
+	return nil
+}
+
+// writeFile writes the text to file.
+func (b *Builder) writeFile(file string, text []byte) error {
+	if cfg.BuildN || cfg.BuildX {
+		b.Showcmd("", "cat >%s << 'EOF' # internal\n%sEOF", file, text)
+	}
+	if cfg.BuildN {
+		return nil
+	}
+	return ioutil.WriteFile(file, text, 0666)
+}
+
+// Install the cgo export header file, if there is one.
+func (b *Builder) installHeader(a *Action) error {
+	src := a.Objdir + "_cgo_install.h"
+	if _, err := os.Stat(src); os.IsNotExist(err) {
+		// If the file does not exist, there are no exported
+		// functions, and we do not install anything.
+		// TODO(rsc): Once we know that caching is rebuilding
+		// at the right times (not missing rebuilds), here we should
+		// probably delete the installed header, if any.
+		if cfg.BuildX {
+			b.Showcmd("", "# %s not created", src)
+		}
+		return nil
+	}
+
+	dir, _ := filepath.Split(a.Target)
+	if dir != "" {
+		if err := b.Mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	return b.moveOrCopyFile(a, a.Target, src, 0666, true)
+}
+
+// cover runs, in effect,
+//	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
+func (b *Builder) cover(a *Action, dst, src string, perm os.FileMode, varName string) error {
+	return b.run(a, a.Objdir, "cover "+a.Package.ImportPath, nil,
+		cfg.BuildToolexec,
+		base.Tool("cover"),
+		"-mode", a.Package.Internal.CoverMode,
+		"-var", varName,
+		"-o", dst,
+		src)
+}
+
+var objectMagic = [][]byte{
+	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
+	{'\x7F', 'E', 'L', 'F'},                   // ELF
+	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
+	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
+	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
+	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
+	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
+	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
+	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
+	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
+}
+
+func isObject(s string) bool {
+	f, err := os.Open(s)
+	if err != nil {
+		return false
+	}
+	defer f.Close()
+	buf := make([]byte, 64)
+	io.ReadFull(f, buf)
+	for _, magic := range objectMagic {
+		if bytes.HasPrefix(buf, magic) {
+			return true
+		}
+	}
+	return false
+}
+
+// mayberemovefile removes a file only if it is a regular file
+// When running as a user with sufficient privileges, we may delete
+// even device files, for example, which is not intended.
+func mayberemovefile(s string) {
+	if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
+		return
+	}
+	os.Remove(s)
+}
+
+// fmtcmd formats a command in the manner of fmt.Sprintf but also:
+//
+//	If dir is non-empty and the script is not in dir right now,
+//	fmtcmd inserts "cd dir\n" before the command.
+//
+//	fmtcmd replaces the value of b.WorkDir with $WORK.
+//	fmtcmd replaces the value of goroot with $GOROOT.
+//	fmtcmd replaces the value of b.gobin with $GOBIN.
+//
+//	fmtcmd replaces the name of the current directory with dot (.)
+//	but only when it is at the beginning of a space-separated token.
+//
+func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string {
+	cmd := fmt.Sprintf(format, args...)
+	if dir != "" && dir != "/" {
+		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
+		if b.scriptDir != dir {
+			b.scriptDir = dir
+			cmd = "cd " + dir + "\n" + cmd
+		}
+	}
+	if b.WorkDir != "" {
+		cmd = strings.Replace(cmd, b.WorkDir, "$WORK", -1)
+	}
+	return cmd
+}
+
+// showcmd prints the given command to standard output
+// for the implementation of -n or -x.
+func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
+	b.output.Lock()
+	defer b.output.Unlock()
+	b.Print(b.fmtcmd(dir, format, args...) + "\n")
+}
+
+// showOutput prints "# desc" followed by the given output.
+// The output is expected to contain references to 'dir', usually
+// the source directory for the package that has failed to build.
+// 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/html,
+// the output is
+//
+//	$ go build
+//	# fmt
+//	../fmt/print.go:1090: undefined: asdf
+//	$
+//
+// instead of
+//
+//	$ go build
+//	# fmt
+//	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
+//	$
+//
+// showOutput also replaces references to the work directory with $WORK.
+//
+// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
+// printing to b.Print.
+//
+func (b *Builder) showOutput(a *Action, dir, desc, out string) {
+	prefix := "# " + desc
+	suffix := "\n" + out
+	if reldir := base.ShortPath(dir); reldir != dir {
+		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
+		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
+	}
+	suffix = strings.Replace(suffix, " "+b.WorkDir, " $WORK", -1)
+
+	if a != nil && a.output != nil {
+		a.output = append(a.output, prefix...)
+		a.output = append(a.output, suffix...)
+		return
+	}
+
+	b.output.Lock()
+	defer b.output.Unlock()
+	b.Print(prefix, suffix)
+}
+
+// errPrintedOutput is a special error indicating that a command failed
+// but that it generated output as well, and that output has already
+// been printed, so there's no point showing 'exit status 1' or whatever
+// the wait status was. The main executor, builder.do, knows not to
+// print this error.
+var errPrintedOutput = errors.New("already printed output - no need to show error")
+
+var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
+var cgoTypeSigRe = regexp.MustCompile(`\b_C2?(type|func|var|macro)_\B`)
+
+// run runs the command given by cmdline in the directory dir.
+// If the command fails, run prints information about the failure
+// and returns a non-nil error.
+func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs ...interface{}) error {
+	out, err := b.runOut(dir, desc, env, cmdargs...)
+	if len(out) > 0 {
+		if desc == "" {
+			desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
+		}
+		b.showOutput(a, dir, desc, b.processOutput(out))
+		if err != nil {
+			err = errPrintedOutput
+		}
+	}
+	return err
+}
+
+// processOutput prepares the output of runOut to be output to the console.
+func (b *Builder) processOutput(out []byte) string {
+	if out[len(out)-1] != '\n' {
+		out = append(out, '\n')
+	}
+	messages := string(out)
+	// Fix up output referring to cgo-generated code to be more readable.
+	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
+	// Replace *[100]_Ctype_foo with *[100]C.foo.
+	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
+	if !cfg.BuildX && cgoLine.MatchString(messages) {
+		messages = cgoLine.ReplaceAllString(messages, "")
+		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
+	}
+	return messages
+}
+
+// runOut runs the command given by cmdline in the directory dir.
+// It returns the command output and any errors that occurred.
+func (b *Builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
+	cmdline := str.StringList(cmdargs...)
+
+	for _, arg := range cmdline {
+		// GNU binutils commands, including gcc and gccgo, interpret an argument
+		// @foo anywhere in the command line (even following --) as meaning
+		// "read and insert arguments from the file named foo."
+		// Don't say anything that might be misinterpreted that way.
+		if strings.HasPrefix(arg, "@") {
+			return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline))
+		}
+	}
+
+	if cfg.BuildN || cfg.BuildX {
+		var envcmdline string
+		for _, e := range env {
+			if j := strings.IndexByte(e, '='); j != -1 {
+				if strings.ContainsRune(e[j+1:], '\'') {
+					envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:])
+				} else {
+					envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:])
+				}
+				envcmdline += " "
+			}
+		}
+		envcmdline += joinUnambiguously(cmdline)
+		b.Showcmd(dir, "%s", envcmdline)
+		if cfg.BuildN {
+			return nil, nil
+		}
+	}
+
+	var buf bytes.Buffer
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Stdout = &buf
+	cmd.Stderr = &buf
+	cmd.Dir = dir
+	cmd.Env = base.MergeEnvLists(env, base.EnvForDir(cmd.Dir, os.Environ()))
+	err := cmd.Run()
+
+	// 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
+}
+
+// joinUnambiguously prints the slice, quoting where necessary to make the
+// output unambiguous.
+// TODO: See issue 5279. The printing of commands needs a complete redo.
+func joinUnambiguously(a []string) string {
+	var buf bytes.Buffer
+	for i, s := range a {
+		if i > 0 {
+			buf.WriteByte(' ')
+		}
+		q := strconv.Quote(s)
+		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
+			buf.WriteString(q)
+		} else {
+			buf.WriteString(s)
+		}
+	}
+	return buf.String()
+}
+
+// mkdir makes the named directory.
+func (b *Builder) Mkdir(dir string) error {
+	// Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
+	if dir == "" {
+		return nil
+	}
+
+	b.exec.Lock()
+	defer b.exec.Unlock()
+	// We can be a little aggressive about being
+	// sure directories exist. Skip repeated calls.
+	if b.mkdirCache[dir] {
+		return nil
+	}
+	b.mkdirCache[dir] = true
+
+	if cfg.BuildN || cfg.BuildX {
+		b.Showcmd("", "mkdir -p %s", dir)
+		if cfg.BuildN {
+			return nil
+		}
+	}
+
+	if err := os.MkdirAll(dir, 0777); err != nil {
+		return err
+	}
+	return nil
+}
+
+// symlink creates a symlink newname -> oldname.
+func (b *Builder) Symlink(oldname, newname string) error {
+	if cfg.BuildN || cfg.BuildX {
+		b.Showcmd("", "ln -s %s %s", oldname, newname)
+		if cfg.BuildN {
+			return nil
+		}
+	}
+	return os.Symlink(oldname, newname)
+}
+
+// mkAbs returns an absolute path corresponding to
+// evaluating f in the directory dir.
+// We always pass absolute paths of source files so that
+// the error messages will include the full path to a file
+// in need of attention.
+func mkAbs(dir, f string) string {
+	// Leave absolute paths alone.
+	// Also, during -n mode we use the pseudo-directory $WORK
+	// instead of creating an actual work directory that won't be used.
+	// Leave paths beginning with $WORK alone too.
+	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
+		return f
+	}
+	return filepath.Join(dir, f)
+}
+
+type toolchain interface {
+	// gc runs the compiler in a specific directory on a set of files
+	// and returns the name of the generated output file.
+	gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, out []byte, err error)
+	// cc runs the toolchain's C compiler in a directory on a C file
+	// to produce an output file.
+	cc(b *Builder, a *Action, ofile, cfile string) error
+	// asm runs the assembler in a specific directory on specific files
+	// and returns a list of named output files.
+	asm(b *Builder, a *Action, sfiles []string) ([]string, error)
+	// pack runs the archive packer in a specific directory to create
+	// an archive from a set of object files.
+	// typically it is run in the object directory.
+	pack(b *Builder, a *Action, afile string, ofiles []string) error
+	// ld runs the linker to create an executable starting at mainpkg.
+	ld(b *Builder, root *Action, out, importcfg, mainpkg string) error
+	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
+	ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error
+
+	compiler() string
+	linker() string
+}
+
+type noToolchain struct{}
+
+func noCompiler() error {
+	log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
+	return nil
+}
+
+func (noToolchain) compiler() string {
+	noCompiler()
+	return ""
+}
+
+func (noToolchain) linker() string {
+	noCompiler()
+	return ""
+}
+
+func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) {
+	return "", nil, noCompiler()
+}
+
+func (noToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
+	return nil, noCompiler()
+}
+
+func (noToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
+	return noCompiler()
+}
+
+func (noToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error {
+	return noCompiler()
+}
+
+func (noToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
+	return noCompiler()
+}
+
+func (noToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
+	return noCompiler()
+}
+
+// gcc runs the gcc C compiler to create an object from a single C file.
+func (b *Builder) gcc(a *Action, p *load.Package, workdir, out string, flags []string, cfile string) error {
+	return b.ccompile(a, p, out, flags, cfile, b.GccCmd(p.Dir, workdir))
+}
+
+// gxx runs the g++ C++ compiler to create an object from a single C++ file.
+func (b *Builder) gxx(a *Action, p *load.Package, workdir, out string, flags []string, cxxfile string) error {
+	return b.ccompile(a, p, out, flags, cxxfile, b.GxxCmd(p.Dir, workdir))
+}
+
+// gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
+func (b *Builder) gfortran(a *Action, p *load.Package, workdir, out string, flags []string, ffile string) error {
+	return b.ccompile(a, p, out, flags, ffile, b.gfortranCmd(p.Dir, workdir))
+}
+
+// ccompile runs the given C or C++ compiler and creates an object from a single source file.
+func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error {
+	file = mkAbs(p.Dir, file)
+	desc := p.ImportPath
+	if !filepath.IsAbs(outfile) {
+		outfile = filepath.Join(p.Dir, outfile)
+	}
+	output, err := b.runOut(filepath.Dir(file), desc, nil, compiler, flags, "-o", outfile, "-c", filepath.Base(file))
+	if len(output) > 0 {
+		// On FreeBSD 11, when we pass -g to clang 3.8 it
+		// invokes its internal assembler with -dwarf-version=2.
+		// When it sees .section .note.GNU-stack, it warns
+		// "DWARF2 only supports one section per compilation unit".
+		// This warning makes no sense, since the section is empty,
+		// but it confuses people.
+		// We work around the problem by detecting the warning
+		// and dropping -g and trying again.
+		if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
+			newFlags := make([]string, 0, len(flags))
+			for _, f := range flags {
+				if !strings.HasPrefix(f, "-g") {
+					newFlags = append(newFlags, f)
+				}
+			}
+			if len(newFlags) < len(flags) {
+				return b.ccompile(a, p, outfile, newFlags, file, compiler)
+			}
+		}
+
+		b.showOutput(a, p.Dir, desc, b.processOutput(output))
+		if err != nil {
+			err = errPrintedOutput
+		} else if os.Getenv("GO_BUILDER_NAME") != "" {
+			return errors.New("C compiler warning promoted to error on Go builders")
+		}
+	}
+	return err
+}
+
+// gccld runs the gcc linker to create an executable from a set of object files.
+func (b *Builder) gccld(p *load.Package, objdir, out string, flags []string, objs []string) error {
+	var cmd []string
+	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
+		cmd = b.GxxCmd(p.Dir, objdir)
+	} else {
+		cmd = b.GccCmd(p.Dir, objdir)
+	}
+	return b.run(nil, p.Dir, p.ImportPath, nil, cmd, "-o", out, objs, flags)
+}
+
+// Grab these before main helpfully overwrites them.
+var (
+	origCC  = os.Getenv("CC")
+	origCXX = os.Getenv("CXX")
+)
+
+// gccCmd returns a gcc command line prefix
+// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
+func (b *Builder) GccCmd(incdir, workdir string) []string {
+	return b.compilerCmd(b.ccExe(), incdir, workdir)
+}
+
+// gxxCmd returns a g++ command line prefix
+// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
+func (b *Builder) GxxCmd(incdir, workdir string) []string {
+	return b.compilerCmd(b.cxxExe(), incdir, workdir)
+}
+
+// gfortranCmd returns a gfortran command line prefix.
+func (b *Builder) gfortranCmd(incdir, workdir string) []string {
+	return b.compilerCmd(b.fcExe(), incdir, workdir)
+}
+
+// ccExe returns the CC compiler setting without all the extra flags we add implicitly.
+func (b *Builder) ccExe() []string {
+	return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch))
+}
+
+// cxxExe returns the CXX compiler setting without all the extra flags we add implicitly.
+func (b *Builder) cxxExe() []string {
+	return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
+}
+
+// fcExe returns the FC compiler setting without all the extra flags we add implicitly.
+func (b *Builder) fcExe() []string {
+	return b.compilerExe(os.Getenv("FC"), "gfortran")
+}
+
+// compilerExe returns the compiler to use given an
+// environment variable setting (the value not the name)
+// and a default. The resulting slice is usually just the name
+// of the compiler but can have additional arguments if they
+// were present in the environment value.
+// For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"].
+func (b *Builder) compilerExe(envValue string, def string) []string {
+	compiler := strings.Fields(envValue)
+	if len(compiler) == 0 {
+		compiler = []string{def}
+	}
+	return compiler
+}
+
+// compilerCmd returns a command line prefix for the given environment
+// variable and using the default command when the variable is empty.
+func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []string {
+	// NOTE: env.go's mkEnv knows that the first three
+	// strings returned are "gcc", "-I", incdir (and cuts them off).
+	a := []string{compiler[0], "-I", incdir}
+	a = append(a, compiler[1:]...)
+
+	// Definitely want -fPIC but on Windows gcc complains
+	// "-fPIC ignored for target (all code is position independent)"
+	if cfg.Goos != "windows" {
+		a = append(a, "-fPIC")
+	}
+	a = append(a, b.gccArchArgs()...)
+	// gcc-4.5 and beyond require explicit "-pthread" flag
+	// for multithreading with pthread library.
+	if cfg.BuildContext.CgoEnabled {
+		switch cfg.Goos {
+		case "windows":
+			a = append(a, "-mthreads")
+		default:
+			a = append(a, "-pthread")
+		}
+	}
+
+	// disable ASCII art in clang errors, if possible
+	if b.gccSupportsFlag(compiler, "-fno-caret-diagnostics") {
+		a = append(a, "-fno-caret-diagnostics")
+	}
+	// clang is too smart about command-line arguments
+	if b.gccSupportsFlag(compiler, "-Qunused-arguments") {
+		a = append(a, "-Qunused-arguments")
+	}
+
+	// disable word wrapping in error messages
+	a = append(a, "-fmessage-length=0")
+
+	// Tell gcc not to include the work directory in object files.
+	if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
+		if workdir == "" {
+			workdir = b.WorkDir
+		}
+		workdir = strings.TrimSuffix(workdir, string(filepath.Separator))
+		a = append(a, "-fdebug-prefix-map="+workdir+"=/tmp/go-build")
+	}
+
+	// Tell gcc not to include flags in object files, which defeats the
+	// point of -fdebug-prefix-map above.
+	if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") {
+		a = append(a, "-gno-record-gcc-switches")
+	}
+
+	// On OS X, some of the compilers behave as if -fno-common
+	// is always set, and the Mach-O linker in 6l/8l assumes this.
+	// See https://golang.org/issue/3253.
+	if cfg.Goos == "darwin" {
+		a = append(a, "-fno-common")
+	}
+
+	return a
+}
+
+// gccNoPie returns the flag to use to request non-PIE. On systems
+// with PIE (position independent executables) enabled by default,
+// -no-pie must be passed when doing a partial link with -Wl,-r.
+// But -no-pie is not supported by all compilers, and clang spells it -nopie.
+func (b *Builder) gccNoPie(linker []string) string {
+	if b.gccSupportsFlag(linker, "-no-pie") {
+		return "-no-pie"
+	}
+	if b.gccSupportsFlag(linker, "-nopie") {
+		return "-nopie"
+	}
+	return ""
+}
+
+// gccSupportsFlag checks to see if the compiler supports a flag.
+func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
+	key := [2]string{compiler[0], flag}
+
+	b.exec.Lock()
+	defer b.exec.Unlock()
+	if b, ok := b.flagCache[key]; ok {
+		return b
+	}
+	if b.flagCache == nil {
+		b.flagCache = make(map[[2]string]bool)
+	}
+	// We used to write an empty C file, but that gets complicated with
+	// go build -n. We tried using a file that does not exist, but that
+	// fails on systems with GCC version 4.2.1; that is the last GPLv2
+	// version of GCC, so some systems have frozen on it.
+	// Now we pass an empty file on stdin, which should work at least for
+	// GCC and clang.
+	cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-")
+	if cfg.BuildN || cfg.BuildX {
+		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
+		if cfg.BuildN {
+			return false
+		}
+	}
+	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
+	cmd.Dir = b.WorkDir
+	cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
+	out, _ := cmd.CombinedOutput()
+	// GCC says "unrecognized command line option".
+	// clang says "unknown argument".
+	// Older versions of GCC say "unrecognised debug output level".
+	// For -fsplit-stack GCC says "'-fsplit-stack' is not supported".
+	supported := !bytes.Contains(out, []byte("unrecognized")) &&
+		!bytes.Contains(out, []byte("unknown")) &&
+		!bytes.Contains(out, []byte("unrecognised")) &&
+		!bytes.Contains(out, []byte("is not supported"))
+	b.flagCache[key] = supported
+	return supported
+}
+
+// gccArchArgs returns arguments to pass to gcc based on the architecture.
+func (b *Builder) gccArchArgs() []string {
+	switch cfg.Goarch {
+	case "386":
+		return []string{"-m32"}
+	case "amd64", "amd64p32":
+		return []string{"-m64"}
+	case "arm":
+		return []string{"-marm"} // not thumb
+	case "s390x":
+		return []string{"-m64", "-march=z196"}
+	case "mips64", "mips64le":
+		return []string{"-mabi=64"}
+	case "mips", "mipsle":
+		return []string{"-mabi=32", "-march=mips32"}
+	}
+	return nil
+}
+
+// envList returns the value of the given environment variable broken
+// into fields, using the default value when the variable is empty.
+func envList(key, def string) []string {
+	v := os.Getenv(key)
+	if v == "" {
+		v = def
+	}
+	return strings.Fields(v)
+}
+
+// CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
+func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
+	defaults := "-g -O2"
+
+	if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil {
+		return
+	}
+	if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil {
+		return
+	}
+	if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil {
+		return
+	}
+	if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil {
+		return
+	}
+	if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
+		return
+	}
+
+	return
+}
+
+func buildFlags(name, defaults string, fromPackage []string, check func(string, string, []string) error) ([]string, error) {
+	if err := check(name, "#cgo "+name, fromPackage); err != nil {
+		return nil, err
+	}
+	return str.StringList(envList("CGO_"+name, defaults), fromPackage), nil
+}
+
+var cgoRe = regexp.MustCompile(`[/\\:]`)
+
+func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
+	p := a.Package
+	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	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")
+	}
+
+	// Likewise for Fortran, except there are many Fortran compilers.
+	// Support gfortran out of the box and let others pass the correct link options
+	// via CGO_LDFLAGS
+	if len(ffiles) > 0 {
+		fc := os.Getenv("FC")
+		if fc == "" {
+			fc = "gfortran"
+		}
+		if strings.Contains(fc, "gfortran") {
+			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
+		}
+	}
+
+	if cfg.BuildMSan {
+		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
+		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
+	}
+
+	// Allows including _cgo_export.h from .[ch] files in the package.
+	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir)
+
+	// cgo
+	// TODO: CGO_FLAGS?
+	gofiles := []string{objdir + "_cgo_gotypes.go"}
+	cfiles := []string{"_cgo_export.c"}
+	for _, fn := range cgofiles {
+		f := strings.TrimSuffix(filepath.Base(fn), ".go")
+		gofiles = append(gofiles, objdir+f+".cgo1.go")
+		cfiles = append(cfiles, f+".cgo2.c")
+	}
+
+	// TODO: make cgo not depend on $GOARCH?
+
+	cgoflags := []string{}
+	if p.Standard && p.ImportPath == "runtime/cgo" {
+		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
+	}
+	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
+		cgoflags = append(cgoflags, "-import_syscall=false")
+	}
+
+	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
+	// These flags are recorded in the generated _cgo_gotypes.go file
+	// using //go:cgo_ldflag directives, the compiler records them in the
+	// object file for the package, and then the Go linker passes them
+	// along to the host linker. At this point in the code, cgoLDFLAGS
+	// consists of the original $CGO_LDFLAGS (unchecked) and all the
+	// flags put together from source code (checked).
+	var cgoenv []string
+	if len(cgoLDFLAGS) > 0 {
+		flags := make([]string, len(cgoLDFLAGS))
+		for i, f := range cgoLDFLAGS {
+			flags[i] = strconv.Quote(f)
+		}
+		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
+	}
+
+	if cfg.BuildToolchainName == "gccgo" {
+		switch cfg.Goarch {
+		case "386", "amd64":
+			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
+		}
+		cgoflags = append(cgoflags, "-gccgo")
+		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
+		}
+	}
+
+	switch cfg.BuildBuildmode {
+	case "c-archive", "c-shared":
+		// Tell cgo that if there are any exported functions
+		// it should generate a header file that C code can
+		// #include.
+		cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h")
+	}
+
+	if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
+		return nil, nil, err
+	}
+	outGo = append(outGo, gofiles...)
+
+	// Use sequential object file names to keep them distinct
+	// and short enough to fit in the .a header file name slots.
+	// We no longer collect them all into _all.o, and we'd like
+	// tools to see both the .o suffix and unique names, so
+	// we need to make them short enough not to be truncated
+	// in the final archive.
+	oseq := 0
+	nextOfile := func() string {
+		oseq++
+		return objdir + fmt.Sprintf("_x%03d.o", oseq)
+	}
+
+	// gcc
+	cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
+	for _, cfile := range cfiles {
+		ofile := nextOfile()
+		if err := b.gcc(a, p, a.Objdir, ofile, cflags, objdir+cfile); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	for _, file := range gccfiles {
+		ofile := nextOfile()
+		if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
+	for _, file := range gxxfiles {
+		ofile := nextOfile()
+		if err := b.gxx(a, p, a.Objdir, ofile, cxxflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	for _, file := range mfiles {
+		ofile := nextOfile()
+		if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
+	for _, file := range ffiles {
+		ofile := nextOfile()
+		if err := b.gfortran(a, p, a.Objdir, ofile, fflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	switch cfg.BuildToolchainName {
+	case "gc":
+		importGo := objdir + "_cgo_import.go"
+		if err := b.dynimport(a, p, objdir, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
+			return nil, nil, err
+		}
+		outGo = append(outGo, importGo)
+
+	case "gccgo":
+		defunC := objdir + "_cgo_defun.c"
+		defunObj := objdir + "_cgo_defun.o"
+		if err := BuildToolchain.cc(b, a, defunObj, defunC); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, defunObj)
+
+	default:
+		noCompiler()
+	}
+
+	return outGo, outObj, nil
+}
+
+// dynimport creates a Go source file named importGo containing
+// //go:cgo_import_dynamic directives for each symbol or library
+// dynamically imported by the object files outObj.
+func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
+	cfile := objdir + "_cgo_main.c"
+	ofile := objdir + "_cgo_main.o"
+	if err := b.gcc(a, p, objdir, ofile, cflags, cfile); err != nil {
+		return err
+	}
+
+	linkobj := str.StringList(ofile, outObj, p.SysoFiles)
+	dynobj := objdir + "_cgo_.o"
+
+	// we need to use -pie for Linux/ARM to get accurate imported sym
+	ldflags := cgoLDFLAGS
+	if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
+		ldflags = append(ldflags, "-pie")
+	}
+	if err := b.gccld(p, objdir, dynobj, ldflags, linkobj); err != nil {
+		return err
+	}
+
+	// cgo -dynimport
+	var cgoflags []string
+	if p.Standard && p.ImportPath == "runtime/cgo" {
+		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
+	}
+	return b.run(a, p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
+}
+
+// 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(a *Action, p *load.Package, objdir string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
+	if err := b.swigVersionCheck(); err != nil {
+		return nil, nil, nil, err
+	}
+
+	intgosize, err := b.swigIntSize(objdir)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	for _, f := range p.SwigFiles {
+		goFile, cFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, false, intgosize)
+		if err != nil {
+			return nil, nil, nil, err
+		}
+		if goFile != "" {
+			outGo = append(outGo, goFile)
+		}
+		if cFile != "" {
+			outC = append(outC, cFile)
+		}
+	}
+	for _, f := range p.SwigCXXFiles {
+		goFile, cxxFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, true, intgosize)
+		if err != nil {
+			return nil, nil, nil, err
+		}
+		if goFile != "" {
+			outGo = append(outGo, goFile)
+		}
+		if cxxFile != "" {
+			outCXX = append(outCXX, cxxFile)
+		}
+	}
+	return outGo, outC, outCXX, nil
+}
+
+// Make sure SWIG is new enough.
+var (
+	swigCheckOnce sync.Once
+	swigCheck     error
+)
+
+func (b *Builder) swigDoVersionCheck() error {
+	out, err := b.runOut("", "", nil, "swig", "-version")
+	if err != nil {
+		return err
+	}
+	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
+	matches := re.FindSubmatch(out)
+	if matches == nil {
+		// Can't find version number; hope for the best.
+		return nil
+	}
+
+	major, err := strconv.Atoi(string(matches[1]))
+	if err != nil {
+		// Can't find version number; hope for the best.
+		return nil
+	}
+	const errmsg = "must have SWIG version >= 3.0.6"
+	if major < 3 {
+		return errors.New(errmsg)
+	}
+	if major > 3 {
+		// 4.0 or later
+		return nil
+	}
+
+	// We have SWIG version 3.x.
+	if len(matches[2]) > 0 {
+		minor, err := strconv.Atoi(string(matches[2][1:]))
+		if err != nil {
+			return nil
+		}
+		if minor > 0 {
+			// 3.1 or later
+			return nil
+		}
+	}
+
+	// We have SWIG version 3.0.x.
+	if len(matches[3]) > 0 {
+		patch, err := strconv.Atoi(string(matches[3][1:]))
+		if err != nil {
+			return nil
+		}
+		if patch < 6 {
+			// Before 3.0.6.
+			return errors.New(errmsg)
+		}
+	}
+
+	return nil
+}
+
+func (b *Builder) swigVersionCheck() error {
+	swigCheckOnce.Do(func() {
+		swigCheck = b.swigDoVersionCheck()
+	})
+	return swigCheck
+}
+
+// Find the value to pass for the -intgosize option to swig.
+var (
+	swigIntSizeOnce  sync.Once
+	swigIntSize      string
+	swigIntSizeError error
+)
+
+// This code fails to build if sizeof(int) <= 32
+const swigIntSizeCode = `
+package main
+const i int = 1 << 32
+`
+
+// Determine the size of int on the target system for the -intgosize option
+// of swig >= 2.0.9. Run only once.
+func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) {
+	if cfg.BuildN {
+		return "$INTBITS", nil
+	}
+	src := filepath.Join(b.WorkDir, "swig_intsize.go")
+	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
+		return
+	}
+	srcs := []string{src}
+
+	p := load.GoFilesPackage(srcs)
+
+	if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, false, srcs); e != nil {
+		return "32", nil
+	}
+	return "64", nil
+}
+
+// Determine the size of int on the target system for the -intgosize option
+// of swig >= 2.0.9.
+func (b *Builder) swigIntSize(objdir string) (intsize string, err error) {
+	swigIntSizeOnce.Do(func() {
+		swigIntSize, swigIntSizeError = b.swigDoIntSize(objdir)
+	})
+	return swigIntSize, swigIntSizeError
+}
+
+// Run SWIG on one SWIG input file.
+func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
+	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p)
+	if err != nil {
+		return "", "", err
+	}
+
+	var cflags []string
+	if cxx {
+		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
+	} else {
+		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
+	}
+
+	n := 5 // length of ".swig"
+	if cxx {
+		n = 8 // length of ".swigcxx"
+	}
+	base := file[:len(file)-n]
+	goFile := base + ".go"
+	gccBase := base + "_wrap."
+	gccExt := "c"
+	if cxx {
+		gccExt = "cxx"
+	}
+
+	gccgo := cfg.BuildToolchainName == "gccgo"
+
+	// swig
+	args := []string{
+		"-go",
+		"-cgo",
+		"-intgosize", intgosize,
+		"-module", base,
+		"-o", objdir + gccBase + gccExt,
+		"-outdir", objdir,
+	}
+
+	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 != "" {
+			args = append(args, "-go-pkgpath", pkgpath)
+		}
+	}
+	if cxx {
+		args = append(args, "-c++")
+	}
+
+	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
+	if err != nil {
+		if len(out) > 0 {
+			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
+				return "", "", errors.New("must have SWIG version >= 3.0.6")
+			}
+			b.showOutput(a, p.Dir, p.ImportPath, b.processOutput(out)) // swig error
+			return "", "", errPrintedOutput
+		}
+		return "", "", err
+	}
+	if len(out) > 0 {
+		b.showOutput(a, p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
+	}
+
+	// If the input was x.swig, the output is x.go in the objdir.
+	// But there might be an x.go in the original dir too, and if it
+	// uses cgo as well, cgo will be processing both and will
+	// translate both into x.cgo1.go in the objdir, overwriting one.
+	// Rename x.go to _x_swig.go to avoid this problem.
+	// We ignore files in the original dir that begin with underscore
+	// so _x_swig.go cannot conflict with an original file we were
+	// going to compile.
+	goFile = objdir + goFile
+	newGoFile := objdir + "_" + base + "_swig.go"
+	if err := os.Rename(goFile, newGoFile); err != nil {
+		return "", "", err
+	}
+	return newGoFile, objdir + gccBase + gccExt, nil
+}
+
+// disableBuildID adjusts a linker command line to avoid creating a
+// build ID when creating an object file rather than an executable or
+// shared library. Some systems, such as Ubuntu, always add
+// --build-id to every link, but we don't want a build ID when 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.
+func (b *Builder) disableBuildID(ldflags []string) []string {
+	switch cfg.Goos {
+	case "android", "dragonfly", "linux", "netbsd":
+		ldflags = append(ldflags, "-Wl,--build-id=none")
+	}
+	return ldflags
+}
+
+// mkAbsFiles converts files into a list of absolute files,
+// assuming they were originally relative to dir,
+// and returns that new list.
+func mkAbsFiles(dir string, files []string) []string {
+	abs := make([]string, len(files))
+	for i, f := range files {
+		if !filepath.IsAbs(f) {
+			f = filepath.Join(dir, f)
+		}
+		abs[i] = f
+	}
+	return abs
+}
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
new file mode 100644
index 0000000..71b5337
--- /dev/null
+++ b/src/cmd/go/internal/work/gc.go
@@ -0,0 +1,495 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package work
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/go/internal/str"
+	"cmd/internal/objabi"
+	"crypto/sha1"
+)
+
+// The Go toolchain.
+
+type gcToolchain struct{}
+
+func (gcToolchain) compiler() string {
+	return base.Tool("compile")
+}
+
+func (gcToolchain) linker() string {
+	return base.Tool("link")
+}
+
+func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) {
+	p := a.Package
+	objdir := a.Objdir
+	if archive != "" {
+		ofile = archive
+	} else {
+		out := "_go_.o"
+		ofile = objdir + out
+	}
+
+	pkgpath := p.ImportPath
+	if cfg.BuildBuildmode == "plugin" {
+		pkgpath = pluginPath(a)
+	} else if p.Name == "main" && !p.Internal.ForceLibrary {
+		pkgpath = "main"
+	}
+	gcargs := []string{"-p", pkgpath}
+	if p.Standard {
+		gcargs = append(gcargs, "-std")
+	}
+	compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal"))
+	if compilingRuntime {
+		// runtime compiles with a special gc flag to emit
+		// additional reflect type data.
+		gcargs = append(gcargs, "-+")
+	}
+
+	// If we're giving the compiler the entire package (no C etc files), tell it that,
+	// so that it can give good error messages about forward declarations.
+	// Exceptions: a few standard packages have forward declarations for
+	// pieces supplied behind-the-scenes by package runtime.
+	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
+	if p.Standard {
+		switch p.ImportPath {
+		case "bytes", "internal/poll", "net", "os", "runtime/pprof", "sync", "syscall", "time":
+			extFiles++
+		}
+	}
+	if extFiles == 0 {
+		gcargs = append(gcargs, "-complete")
+	}
+	if cfg.BuildContext.InstallSuffix != "" {
+		gcargs = append(gcargs, "-installsuffix", cfg.BuildContext.InstallSuffix)
+	}
+	if a.buildID != "" {
+		gcargs = append(gcargs, "-buildid", a.buildID)
+	}
+	platform := cfg.Goos + "/" + cfg.Goarch
+	if p.Internal.OmitDebug || platform == "nacl/amd64p32" || platform == "darwin/arm" || platform == "darwin/arm64" || cfg.Goos == "plan9" {
+		gcargs = append(gcargs, "-dwarf=false")
+	}
+	if strings.HasPrefix(runtimeVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") {
+		gcargs = append(gcargs, "-goversion", runtimeVersion)
+	}
+
+	gcflags := str.StringList(forcedGcflags, p.Internal.Gcflags)
+	if compilingRuntime {
+		// Remove -N, if present.
+		// It is not possible to build the runtime with no optimizations,
+		// because the compiler cannot eliminate enough write barriers.
+		for i := 0; i < len(gcflags); i++ {
+			if gcflags[i] == "-N" {
+				copy(gcflags[i:], gcflags[i+1:])
+				gcflags = gcflags[:len(gcflags)-1]
+				i--
+			}
+		}
+	}
+
+	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", trimDir(a.Objdir), gcflags, gcargs, "-D", p.Internal.LocalPrefix}
+	if importcfg != nil {
+		if err := b.writeFile(objdir+"importcfg", importcfg); err != nil {
+			return "", nil, err
+		}
+		args = append(args, "-importcfg", objdir+"importcfg")
+	}
+	if ofile == archive {
+		args = append(args, "-pack")
+	}
+	if asmhdr {
+		args = append(args, "-asmhdr", objdir+"go_asm.h")
+	}
+
+	// Add -c=N to use concurrent backend compilation, if possible.
+	if c := gcBackendConcurrency(gcflags); c > 1 {
+		args = append(args, fmt.Sprintf("-c=%d", c))
+	}
+
+	for _, f := range gofiles {
+		args = append(args, mkAbs(p.Dir, f))
+	}
+
+	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
+	return ofile, output, err
+}
+
+// gcBackendConcurrency returns the backend compiler concurrency level for a package compilation.
+func gcBackendConcurrency(gcflags []string) int {
+	// First, check whether we can use -c at all for this compilation.
+	canDashC := concurrentGCBackendCompilationEnabledByDefault
+
+	switch e := os.Getenv("GO19CONCURRENTCOMPILATION"); e {
+	case "0":
+		canDashC = false
+	case "1":
+		canDashC = true
+	case "":
+		// Not set. Use default.
+	default:
+		log.Fatalf("GO19CONCURRENTCOMPILATION must be 0, 1, or unset, got %q", e)
+	}
+
+CheckFlags:
+	for _, flag := range gcflags {
+		// Concurrent compilation is presumed incompatible with any gcflags,
+		// except for a small whitelist of commonly used flags.
+		// If the user knows better, they can manually add their own -c to the gcflags.
+		switch flag {
+		case "-N", "-l", "-S", "-B", "-C", "-I":
+			// OK
+		default:
+			canDashC = false
+			break CheckFlags
+		}
+	}
+
+	// TODO: Test and delete these conditions.
+	if objabi.Fieldtrack_enabled != 0 || objabi.Preemptibleloops_enabled != 0 || objabi.Clobberdead_enabled != 0 {
+		canDashC = false
+	}
+
+	if !canDashC {
+		return 1
+	}
+
+	// Decide how many concurrent backend compilations to allow.
+	//
+	// If we allow too many, in theory we might end up with p concurrent processes,
+	// each with c concurrent backend compiles, all fighting over the same resources.
+	// However, in practice, that seems not to happen too much.
+	// Most build graphs are surprisingly serial, so p==1 for much of the build.
+	// Furthermore, concurrent backend compilation is only enabled for a part
+	// of the overall compiler execution, so c==1 for much of the build.
+	// So don't worry too much about that interaction for now.
+	//
+	// However, in practice, setting c above 4 tends not to help very much.
+	// See the analysis in CL 41192.
+	//
+	// TODO(josharian): attempt to detect whether this particular compilation
+	// is likely to be a bottleneck, e.g. when:
+	//   - it has no successor packages to compile (usually package main)
+	//   - all paths through the build graph pass through it
+	//   - critical path scheduling says it is high priority
+	// and in such a case, set c to runtime.NumCPU.
+	// We do this now when p==1.
+	if cfg.BuildP == 1 {
+		// No process parallelism. Max out c.
+		return runtime.NumCPU()
+	}
+	// Some process parallelism. Set c to min(4, numcpu).
+	c := 4
+	if ncpu := runtime.NumCPU(); ncpu < c {
+		c = ncpu
+	}
+	return c
+}
+
+func trimDir(dir string) string {
+	if len(dir) > 1 && dir[len(dir)-1] == filepath.Separator {
+		dir = dir[:len(dir)-1]
+	}
+	return dir
+}
+
+func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
+	p := a.Package
+	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
+	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
+	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", trimDir(a.Objdir), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
+	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
+		for _, arg := range forcedAsmflags {
+			if arg == "-dynlink" {
+				args = append(args, "-D=GOBUILDMODE_shared=1")
+			}
+		}
+	}
+
+	if cfg.Goarch == "mips" || cfg.Goarch == "mipsle" {
+		// Define GOMIPS_value from cfg.GOMIPS.
+		args = append(args, "-D", "GOMIPS_"+cfg.GOMIPS)
+	}
+
+	var ofiles []string
+	for _, sfile := range sfiles {
+		ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o"
+		ofiles = append(ofiles, ofile)
+		args1 := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
+		if err := b.run(a, p.Dir, p.ImportPath, nil, args1...); err != nil {
+			return nil, err
+		}
+	}
+	return ofiles, nil
+}
+
+// toolVerify checks that the command line args writes the same output file
+// if run using newTool instead.
+// Unused now but kept around for future use.
+func toolVerify(a *Action, b *Builder, p *load.Package, newTool string, ofile string, args []interface{}) error {
+	newArgs := make([]interface{}, len(args))
+	copy(newArgs, args)
+	newArgs[1] = base.Tool(newTool)
+	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
+	if err := b.run(a, p.Dir, p.ImportPath, nil, newArgs...); err != nil {
+		return err
+	}
+	data1, err := ioutil.ReadFile(ofile)
+	if err != nil {
+		return err
+	}
+	data2, err := ioutil.ReadFile(ofile + ".new")
+	if err != nil {
+		return err
+	}
+	if !bytes.Equal(data1, data2) {
+		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(str.StringList(args...), " "), strings.Join(str.StringList(newArgs...), " "))
+	}
+	os.Remove(ofile + ".new")
+	return nil
+}
+
+func (gcToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
+	var absOfiles []string
+	for _, f := range ofiles {
+		absOfiles = append(absOfiles, mkAbs(a.Objdir, f))
+	}
+	absAfile := mkAbs(a.Objdir, afile)
+
+	// The archive file should have been created by the compiler.
+	// Since it used to not work that way, verify.
+	if !cfg.BuildN {
+		if _, err := os.Stat(absAfile); err != nil {
+			base.Fatalf("os.Stat of archive file failed: %v", err)
+		}
+	}
+
+	p := a.Package
+	if cfg.BuildN || cfg.BuildX {
+		cmdline := str.StringList(base.Tool("pack"), "r", absAfile, absOfiles)
+		b.Showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
+	}
+	if cfg.BuildN {
+		return nil
+	}
+	if err := packInternal(b, absAfile, absOfiles); err != nil {
+		b.showOutput(a, p.Dir, p.ImportPath, err.Error()+"\n")
+		return errPrintedOutput
+	}
+	return nil
+}
+
+func packInternal(b *Builder, afile string, ofiles []string) error {
+	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
+	if err != nil {
+		return err
+	}
+	defer dst.Close() // only for error returns or panics
+	w := bufio.NewWriter(dst)
+
+	for _, ofile := range ofiles {
+		src, err := os.Open(ofile)
+		if err != nil {
+			return err
+		}
+		fi, err := src.Stat()
+		if err != nil {
+			src.Close()
+			return err
+		}
+		// Note: Not using %-16.16s format because we care
+		// about bytes, not runes.
+		name := fi.Name()
+		if len(name) > 16 {
+			name = name[:16]
+		} else {
+			name += strings.Repeat(" ", 16-len(name))
+		}
+		size := fi.Size()
+		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
+			name, 0, 0, 0, 0644, size)
+		n, err := io.Copy(w, src)
+		src.Close()
+		if err == nil && n < size {
+			err = io.ErrUnexpectedEOF
+		} else if err == nil && n > size {
+			err = fmt.Errorf("file larger than size reported by stat")
+		}
+		if err != nil {
+			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
+		}
+		if size&1 != 0 {
+			w.WriteByte(0)
+		}
+	}
+
+	if err := w.Flush(); err != nil {
+		return err
+	}
+	return dst.Close()
+}
+
+// setextld sets the appropriate linker flags for the specified compiler.
+func setextld(ldflags []string, compiler []string) []string {
+	for _, f := range ldflags {
+		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+			// don't override -extld if supplied
+			return ldflags
+		}
+	}
+	ldflags = append(ldflags, "-extld="+compiler[0])
+	if len(compiler) > 1 {
+		extldflags := false
+		add := strings.Join(compiler[1:], " ")
+		for i, f := range ldflags {
+			if f == "-extldflags" && i+1 < len(ldflags) {
+				ldflags[i+1] = add + " " + ldflags[i+1]
+				extldflags = true
+				break
+			} else if strings.HasPrefix(f, "-extldflags=") {
+				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+				extldflags = true
+				break
+			}
+		}
+		if !extldflags {
+			ldflags = append(ldflags, "-extldflags="+add)
+		}
+	}
+	return ldflags
+}
+
+// pluginPath computes the package path for a plugin main package.
+//
+// This is typically the import path of the main package p, unless the
+// plugin is being built directly from source files. In that case we
+// combine the package build ID with the contents of the main package
+// source files. This allows us to identify two different plugins
+// built from two source files with the same name.
+func pluginPath(a *Action) string {
+	p := a.Package
+	if p.ImportPath != "command-line-arguments" {
+		return p.ImportPath
+	}
+	h := sha1.New()
+	fmt.Fprintf(h, "build ID: %s\n", a.buildID)
+	for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) {
+		data, err := ioutil.ReadFile(filepath.Join(p.Dir, file))
+		if err != nil {
+			base.Fatalf("go: %s", err)
+		}
+		h.Write(data)
+	}
+	return fmt.Sprintf("plugin/unnamed-%x", h.Sum(nil))
+}
+
+func (gcToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error {
+	cxx := len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
+	for _, a := range root.Deps {
+		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
+			cxx = true
+		}
+	}
+	var ldflags []string
+	if cfg.BuildContext.InstallSuffix != "" {
+		ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
+	}
+	if root.Package.Internal.OmitDebug {
+		ldflags = append(ldflags, "-s", "-w")
+	}
+	if cfg.BuildBuildmode == "plugin" {
+		ldflags = append(ldflags, "-pluginpath", pluginPath(root))
+	}
+
+	// Store BuildID inside toolchain binaries as a unique identifier of the
+	// tool being run, for use by content-based staleness determination.
+	if root.Package.Goroot && strings.HasPrefix(root.Package.ImportPath, "cmd/") {
+		ldflags = append(ldflags, "-X=cmd/internal/objabi.buildID="+root.buildID)
+	}
+
+	// If the user has not specified the -extld option, then specify the
+	// appropriate linker. In case of C++ code, use the compiler named
+	// by the CXX environment variable or defaultCXX if CXX is not set.
+	// Else, use the CC environment variable and defaultCC as fallback.
+	var compiler []string
+	if cxx {
+		compiler = envList("CXX", cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
+	} else {
+		compiler = envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch))
+	}
+	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
+	if root.buildID != "" {
+		ldflags = append(ldflags, "-buildid="+root.buildID)
+	}
+	ldflags = append(ldflags, forcedLdflags...)
+	ldflags = append(ldflags, root.Package.Internal.Ldflags...)
+	ldflags = setextld(ldflags, compiler)
+
+	// On OS X when using external linking to build a shared library,
+	// the argument passed here to -o ends up recorded in the final
+	// shared library in the LC_ID_DYLIB load command.
+	// To avoid putting the temporary output directory name there
+	// (and making the resulting shared library useless),
+	// run the link in the output directory so that -o can name
+	// just the final path element.
+	// On Windows, DLL file name is recorded in PE file
+	// export section, so do like on OS X.
+	dir := "."
+	if (cfg.Goos == "darwin" || cfg.Goos == "windows") && cfg.BuildBuildmode == "c-shared" {
+		dir, out = filepath.Split(out)
+	}
+
+	return b.run(root, dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg)
+}
+
+func (gcToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
+	ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
+	ldflags = append(ldflags, "-buildmode=shared")
+	ldflags = append(ldflags, forcedLdflags...)
+	ldflags = append(ldflags, root.Package.Internal.Ldflags...)
+	cxx := false
+	for _, a := range allactions {
+		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
+			cxx = true
+		}
+	}
+	// If the user has not specified the -extld option, then specify the
+	// appropriate linker. In case of C++ code, use the compiler named
+	// by the CXX environment variable or defaultCXX if CXX is not set.
+	// Else, use the CC environment variable and defaultCC as fallback.
+	var compiler []string
+	if cxx {
+		compiler = envList("CXX", cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
+	} else {
+		compiler = envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch))
+	}
+	ldflags = setextld(ldflags, compiler)
+	for _, d := range toplevelactions {
+		if !strings.HasSuffix(d.Target, ".a") { // omit unsafe etc and actions for other shared libraries
+			continue
+		}
+		ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target)
+	}
+	return b.run(root, ".", out, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags)
+}
+
+func (gcToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
+	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(a.Package.Dir, cfile))
+}
diff --git a/src/cmd/go/internal/work/gccgo.go b/src/cmd/go/internal/work/gccgo.go
new file mode 100644
index 0000000..2512ffe
--- /dev/null
+++ b/src/cmd/go/internal/work/gccgo.go
@@ -0,0 +1,507 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package work
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/go/internal/str"
+)
+
+// The Gccgo toolchain.
+
+type gccgoToolchain struct{}
+
+var GccgoName, GccgoBin string
+var gccgoErr error
+
+func init() {
+	GccgoName = os.Getenv("GCCGO")
+	if GccgoName == "" {
+		GccgoName = "gccgo"
+	}
+	GccgoBin, gccgoErr = exec.LookPath(GccgoName)
+}
+
+func (gccgoToolchain) compiler() string {
+	checkGccgoBin()
+	return GccgoBin
+}
+
+func (gccgoToolchain) linker() string {
+	checkGccgoBin()
+	return GccgoBin
+}
+
+func checkGccgoBin() {
+	if gccgoErr == nil {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "cmd/go: gccgo: %s\n", gccgoErr)
+	os.Exit(2)
+}
+
+func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) {
+	p := a.Package
+	objdir := a.Objdir
+	out := "_go_.o"
+	ofile = objdir + out
+	gcargs := []string{"-g"}
+	gcargs = append(gcargs, b.gccArchArgs()...)
+	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
+	}
+	if p.Internal.LocalPrefix != "" {
+		gcargs = append(gcargs, "-fgo-relative-import-path="+p.Internal.LocalPrefix)
+	}
+
+	args := str.StringList(tools.compiler(), "-c", gcargs, "-o", ofile, forcedGccgoflags)
+	if importcfg != nil {
+		if b.gccSupportsFlag(args[:1], "-fgo-importcfg=/dev/null") {
+			if err := b.writeFile(objdir+"importcfg", importcfg); err != nil {
+				return "", nil, err
+			}
+			args = append(args, "-fgo-importcfg="+objdir+"importcfg")
+		} else {
+			root := objdir + "_importcfgroot_"
+			if err := buildImportcfgSymlinks(b, root, importcfg); err != nil {
+				return "", nil, err
+			}
+			args = append(args, "-I", root)
+		}
+	}
+	args = append(args, a.Package.Internal.Gccgoflags...)
+	for _, f := range gofiles {
+		args = append(args, mkAbs(p.Dir, f))
+	}
+
+	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
+	return ofile, output, err
+}
+
+// buildImportcfgSymlinks builds in root a tree of symlinks
+// implementing the directives from importcfg.
+// This serves as a temporary transition mechanism until
+// we can depend on gccgo reading an importcfg directly.
+// (The Go 1.9 and later gc compilers already do.)
+func buildImportcfgSymlinks(b *Builder, root string, importcfg []byte) error {
+	for lineNum, line := range strings.Split(string(importcfg), "\n") {
+		lineNum++ // 1-based
+		line = strings.TrimSpace(line)
+		if line == "" {
+			continue
+		}
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		var verb, args string
+		if i := strings.Index(line, " "); i < 0 {
+			verb = line
+		} else {
+			verb, args = line[:i], strings.TrimSpace(line[i+1:])
+		}
+		var before, after string
+		if i := strings.Index(args, "="); i >= 0 {
+			before, after = args[:i], args[i+1:]
+		}
+		switch verb {
+		default:
+			base.Fatalf("importcfg:%d: unknown directive %q", lineNum, verb)
+		case "packagefile":
+			if before == "" || after == "" {
+				return fmt.Errorf(`importcfg:%d: invalid packagefile: syntax is "packagefile path=filename": %s`, lineNum, line)
+			}
+			archive := gccgoArchive(root, before)
+			if err := b.Mkdir(filepath.Dir(archive)); err != nil {
+				return err
+			}
+			if err := b.Symlink(after, archive); err != nil {
+				return err
+			}
+		case "importmap":
+			if before == "" || after == "" {
+				return fmt.Errorf(`importcfg:%d: invalid importmap: syntax is "importmap old=new": %s`, lineNum, line)
+			}
+			beforeA := gccgoArchive(root, before)
+			afterA := gccgoArchive(root, after)
+			if err := b.Mkdir(filepath.Dir(beforeA)); err != nil {
+				return err
+			}
+			if err := b.Mkdir(filepath.Dir(afterA)); err != nil {
+				return err
+			}
+			if err := b.Symlink(afterA, beforeA); err != nil {
+				return err
+			}
+		case "packageshlib":
+			return fmt.Errorf("gccgo -importcfg does not support shared libraries")
+		}
+	}
+	return nil
+}
+
+func (tools gccgoToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
+	p := a.Package
+	var ofiles []string
+	for _, sfile := range sfiles {
+		base := filepath.Base(sfile)
+		ofile := a.Objdir + base[:len(base)-len(".s")] + ".o"
+		ofiles = append(ofiles, ofile)
+		sfile = mkAbs(p.Dir, sfile)
+		defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
+		if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+			defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
+		}
+		defs = tools.maybePIC(defs)
+		defs = append(defs, b.gccArchArgs()...)
+		err := b.run(a, p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", a.Objdir, "-c", "-o", ofile, defs, sfile)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return ofiles, nil
+}
+
+func gccgoArchive(basedir, imp string) string {
+	end := filepath.FromSlash(imp + ".a")
+	afile := filepath.Join(basedir, end)
+	// add "lib" to the final element
+	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
+}
+
+func (gccgoToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
+	p := a.Package
+	objdir := a.Objdir
+	var absOfiles []string
+	for _, f := range ofiles {
+		absOfiles = append(absOfiles, mkAbs(objdir, f))
+	}
+	return b.run(a, p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objdir, afile), absOfiles)
+}
+
+func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string, allactions []*Action, buildmode, desc string) error {
+	// gccgo needs explicit linking with all package dependencies,
+	// and all LDFLAGS from cgo dependencies.
+	afiles := []string{}
+	shlibs := []string{}
+	ldflags := b.gccArchArgs()
+	cgoldflags := []string{}
+	usesCgo := false
+	cxx := false
+	objc := false
+	fortran := false
+	if root.Package != nil {
+		cxx = len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
+		objc = len(root.Package.MFiles) > 0
+		fortran = len(root.Package.FFiles) > 0
+	}
+
+	readCgoFlags := func(flagsFile string) error {
+		flags, err := ioutil.ReadFile(flagsFile)
+		if err != nil {
+			return err
+		}
+		const ldflagsPrefix = "_CGO_LDFLAGS="
+		for _, line := range strings.Split(string(flags), "\n") {
+			if strings.HasPrefix(line, ldflagsPrefix) {
+				newFlags := strings.Fields(line[len(ldflagsPrefix):])
+				for _, flag := range newFlags {
+					// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
+					// but they don't mean anything to the linker so filter
+					// them out.
+					if flag != "-g" && !strings.HasPrefix(flag, "-O") {
+						cgoldflags = append(cgoldflags, flag)
+					}
+				}
+			}
+		}
+		return nil
+	}
+
+	newID := 0
+	readAndRemoveCgoFlags := func(archive string) (string, error) {
+		newID++
+		newArchive := root.Objdir + fmt.Sprintf("_pkg%d_.a", newID)
+		if err := b.copyFile(root, newArchive, archive, 0666, false); err != nil {
+			return "", err
+		}
+		if cfg.BuildN || cfg.BuildX {
+			b.Showcmd("", "ar d %s _cgo_flags", newArchive)
+			if cfg.BuildN {
+				// TODO(rsc): We could do better about showing the right _cgo_flags even in -n mode.
+				// Either the archive is already built and we can read them out,
+				// or we're printing commands to build the archive and can
+				// forward the _cgo_flags directly to this step.
+				return "", nil
+			}
+		}
+		err := b.run(root, root.Objdir, desc, nil, "ar", "x", newArchive, "_cgo_flags")
+		if err != nil {
+			return "", err
+		}
+		err = b.run(root, ".", desc, nil, "ar", "d", newArchive, "_cgo_flags")
+		if err != nil {
+			return "", err
+		}
+		err = readCgoFlags(filepath.Join(root.Objdir, "_cgo_flags"))
+		if err != nil {
+			return "", err
+		}
+		return newArchive, nil
+	}
+
+	// If using -linkshared, find the shared library deps.
+	haveShlib := make(map[string]bool)
+	targetBase := filepath.Base(root.Target)
+	if cfg.BuildLinkshared {
+		for _, a := range root.Deps {
+			p := a.Package
+			if p == nil || p.Shlib == "" {
+				continue
+			}
+
+			// The .a we are linking into this .so
+			// will have its Shlib set to this .so.
+			// Don't start thinking we want to link
+			// this .so into itself.
+			base := filepath.Base(p.Shlib)
+			if base != targetBase {
+				haveShlib[base] = true
+			}
+		}
+	}
+
+	// Arrange the deps into afiles and shlibs.
+	addedShlib := make(map[string]bool)
+	for _, a := range root.Deps {
+		p := a.Package
+		if p != nil && p.Shlib != "" && haveShlib[filepath.Base(p.Shlib)] {
+			// This is a package linked into a shared
+			// library that we will put into shlibs.
+			continue
+		}
+
+		if haveShlib[filepath.Base(a.Target)] {
+			// This is a shared library we want to link againt.
+			if !addedShlib[a.Target] {
+				shlibs = append(shlibs, a.Target)
+				addedShlib[a.Target] = true
+			}
+			continue
+		}
+
+		if p != nil {
+			target := a.built
+			if p.UsesCgo() || p.UsesSwig() {
+				var err error
+				target, err = readAndRemoveCgoFlags(target)
+				if err != nil {
+					continue
+				}
+			}
+
+			afiles = append(afiles, target)
+		}
+	}
+
+	for _, a := range allactions {
+		// Gather CgoLDFLAGS, but not from standard packages.
+		// The go tool can dig up runtime/cgo from GOROOT and
+		// think that it should use its CgoLDFLAGS, but gccgo
+		// doesn't use runtime/cgo.
+		if a.Package == nil {
+			continue
+		}
+		if !a.Package.Standard {
+			cgoldflags = append(cgoldflags, a.Package.CgoLDFLAGS...)
+		}
+		if len(a.Package.CgoFiles) > 0 {
+			usesCgo = true
+		}
+		if a.Package.UsesSwig() {
+			usesCgo = true
+		}
+		if len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0 {
+			cxx = true
+		}
+		if len(a.Package.MFiles) > 0 {
+			objc = true
+		}
+		if len(a.Package.FFiles) > 0 {
+			fortran = true
+		}
+	}
+
+	ldflags = append(ldflags, "-Wl,--whole-archive")
+	ldflags = append(ldflags, afiles...)
+	ldflags = append(ldflags, "-Wl,--no-whole-archive")
+
+	ldflags = append(ldflags, cgoldflags...)
+	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
+	if root.Package != nil {
+		ldflags = append(ldflags, root.Package.CgoLDFLAGS...)
+	}
+
+	ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
+
+	if root.buildID != "" {
+		// On systems that normally use gold or the GNU linker,
+		// use the --build-id option to write a GNU build ID note.
+		switch cfg.Goos {
+		case "android", "dragonfly", "linux", "netbsd":
+			ldflags = append(ldflags, fmt.Sprintf("-Wl,--build-id=0x%x", root.buildID))
+		}
+	}
+
+	for _, shlib := range shlibs {
+		ldflags = append(
+			ldflags,
+			"-L"+filepath.Dir(shlib),
+			"-Wl,-rpath="+filepath.Dir(shlib),
+			"-l"+strings.TrimSuffix(
+				strings.TrimPrefix(filepath.Base(shlib), "lib"),
+				".so"))
+	}
+
+	var realOut string
+	switch buildmode {
+	case "exe":
+		if usesCgo && cfg.Goos == "linux" {
+			ldflags = append(ldflags, "-Wl,-E")
+		}
+
+	case "c-archive":
+		// Link the Go files into a single .o, and also link
+		// in -lgolibbegin.
+		//
+		// We need to use --whole-archive with -lgolibbegin
+		// because it doesn't define any symbols that will
+		// cause the contents to be pulled in; it's just
+		// initialization code.
+		//
+		// The user remains responsible for linking against
+		// -lgo -lpthread -lm in the final link. We can't use
+		// -r to pick them up because we can't combine
+		// split-stack and non-split-stack code in a single -r
+		// link, and libgo picks up non-split-stack code from
+		// libffi.
+		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
+
+		if nopie := b.gccNoPie([]string{tools.linker()}); nopie != "" {
+			ldflags = append(ldflags, nopie)
+		}
+
+		// We are creating an object file, so we don't want a build ID.
+		if root.buildID == "" {
+			ldflags = b.disableBuildID(ldflags)
+		}
+
+		realOut = out
+		out = out + ".o"
+
+	case "c-shared":
+		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
+	case "shared":
+		ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
+
+	default:
+		base.Fatalf("-buildmode=%s not supported for gccgo", buildmode)
+	}
+
+	switch buildmode {
+	case "exe", "c-shared":
+		if cxx {
+			ldflags = append(ldflags, "-lstdc++")
+		}
+		if objc {
+			ldflags = append(ldflags, "-lobjc")
+		}
+		if fortran {
+			fc := os.Getenv("FC")
+			if fc == "" {
+				fc = "gfortran"
+			}
+			// support gfortran out of the box and let others pass the correct link options
+			// via CGO_LDFLAGS
+			if strings.Contains(fc, "gfortran") {
+				ldflags = append(ldflags, "-lgfortran")
+			}
+		}
+	}
+
+	if err := b.run(root, ".", desc, nil, tools.linker(), "-o", out, ldflags, forcedGccgoflags, root.Package.Internal.Gccgoflags); err != nil {
+		return err
+	}
+
+	switch buildmode {
+	case "c-archive":
+		if err := b.run(root, ".", desc, nil, "ar", "rc", realOut, out); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (tools gccgoToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error {
+	return tools.link(b, root, out, importcfg, root.Deps, ldBuildmode, root.Package.ImportPath)
+}
+
+func (tools gccgoToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
+	return tools.link(b, root, out, importcfg, allactions, "shared", out)
+}
+
+func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
+	p := a.Package
+	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
+	cfile = mkAbs(p.Dir, cfile)
+	defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
+	defs = append(defs, b.gccArchArgs()...)
+	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
+	}
+	switch cfg.Goarch {
+	case "386", "amd64":
+		defs = append(defs, "-fsplit-stack")
+	}
+	defs = tools.maybePIC(defs)
+	return b.run(a, p.Dir, p.ImportPath, nil, envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch)), "-Wall", "-g",
+		"-I", a.Objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
+}
+
+// maybePIC adds -fPIC to the list of arguments if needed.
+func (tools gccgoToolchain) maybePIC(args []string) []string {
+	switch cfg.BuildBuildmode {
+	case "c-shared", "shared", "plugin":
+		args = append(args, "-fPIC")
+	}
+	return args
+}
+
+func gccgoPkgpath(p *load.Package) string {
+	if p.Internal.Build.IsCommand() && !p.Internal.ForceLibrary {
+		return ""
+	}
+	return p.ImportPath
+}
+
+func gccgoCleanPkgpath(p *load.Package) string {
+	clean := func(r rune) rune {
+		switch {
+		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
+			'0' <= r && r <= '9':
+			return r
+		}
+		return '_'
+	}
+	return strings.Map(clean, gccgoPkgpath(p))
+}
diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go
new file mode 100644
index 0000000..7f894f5
--- /dev/null
+++ b/src/cmd/go/internal/work/init.go
@@ -0,0 +1,217 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Build initialization (after flag parsing).
+
+package work
+
+import (
+	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
+	"flag"
+	"fmt"
+	"os"
+	"path/filepath"
+)
+
+func BuildInit() {
+	instrumentInit()
+	buildModeInit()
+
+	// Make sure -pkgdir is absolute, because we run commands
+	// in different directories.
+	if cfg.BuildPkgdir != "" && !filepath.IsAbs(cfg.BuildPkgdir) {
+		p, err := filepath.Abs(cfg.BuildPkgdir)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "go %s: evaluating -pkgdir: %v\n", flag.Args()[0], err)
+			os.Exit(2)
+		}
+		cfg.BuildPkgdir = p
+	}
+}
+
+func instrumentInit() {
+	if !cfg.BuildRace && !cfg.BuildMSan {
+		return
+	}
+	if cfg.BuildRace && cfg.BuildMSan {
+		fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
+		os.Exit(2)
+	}
+	if cfg.BuildMSan && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
+		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
+		os.Exit(2)
+	}
+	if cfg.Goarch != "amd64" || cfg.Goos != "linux" && cfg.Goos != "freebsd" && cfg.Goos != "darwin" && cfg.Goos != "windows" {
+		fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
+		os.Exit(2)
+	}
+
+	mode := "race"
+	if cfg.BuildMSan {
+		mode = "msan"
+	}
+	modeFlag := "-" + mode
+
+	if !cfg.BuildContext.CgoEnabled {
+		fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
+		os.Exit(2)
+	}
+	forcedGcflags = append(forcedGcflags, modeFlag)
+	forcedLdflags = append(forcedLdflags, modeFlag)
+
+	if cfg.BuildContext.InstallSuffix != "" {
+		cfg.BuildContext.InstallSuffix += "_"
+	}
+	cfg.BuildContext.InstallSuffix += mode
+	cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode)
+}
+
+func buildModeInit() {
+	gccgo := cfg.BuildToolchainName == "gccgo"
+	var codegenArg string
+	platform := cfg.Goos + "/" + cfg.Goarch
+	switch cfg.BuildBuildmode {
+	case "archive":
+		pkgsFilter = pkgsNotMain
+	case "c-archive":
+		pkgsFilter = oneMainPkg
+		switch platform {
+		case "darwin/arm", "darwin/arm64":
+			codegenArg = "-shared"
+		default:
+			switch cfg.Goos {
+			case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
+				// Use -shared so that the result is
+				// suitable for inclusion in a PIE or
+				// shared library.
+				codegenArg = "-shared"
+			}
+		}
+		cfg.ExeSuffix = ".a"
+		ldBuildmode = "c-archive"
+	case "c-shared":
+		pkgsFilter = oneMainPkg
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x",
+				"android/amd64", "android/arm", "android/arm64", "android/386":
+				codegenArg = "-shared"
+			case "darwin/amd64", "darwin/386":
+			case "windows/amd64", "windows/386":
+				// Do not add usual .exe suffix to the .dll file.
+				cfg.ExeSuffix = ""
+			default:
+				base.Fatalf("-buildmode=c-shared not supported on %s\n", platform)
+			}
+		}
+		ldBuildmode = "c-shared"
+	case "default":
+		switch platform {
+		case "android/arm", "android/arm64", "android/amd64", "android/386":
+			codegenArg = "-shared"
+			ldBuildmode = "pie"
+		case "darwin/arm", "darwin/arm64":
+			codegenArg = "-shared"
+			fallthrough
+		default:
+			ldBuildmode = "exe"
+		}
+	case "exe":
+		pkgsFilter = pkgsMain
+		ldBuildmode = "exe"
+		// Set the pkgsFilter to oneMainPkg if the user passed a specific binary output
+		// and is using buildmode=exe for a better error message.
+		// See issue #20017.
+		if cfg.BuildO != "" {
+			pkgsFilter = oneMainPkg
+		}
+	case "pie":
+		if cfg.BuildRace {
+			base.Fatalf("-buildmode=pie not supported when -race is enabled")
+		}
+		if gccgo {
+			base.Fatalf("-buildmode=pie not supported by gccgo")
+		} else {
+			switch platform {
+			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
+				"android/amd64", "android/arm", "android/arm64", "android/386":
+				codegenArg = "-shared"
+			case "darwin/amd64":
+				codegenArg = "-shared"
+			default:
+				base.Fatalf("-buildmode=pie not supported on %s\n", platform)
+			}
+		}
+		ldBuildmode = "pie"
+	case "shared":
+		pkgsFilter = pkgsNotMain
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
+			default:
+				base.Fatalf("-buildmode=shared not supported on %s\n", platform)
+			}
+			codegenArg = "-dynlink"
+		}
+		if cfg.BuildO != "" {
+			base.Fatalf("-buildmode=shared and -o not supported together")
+		}
+		ldBuildmode = "shared"
+	case "plugin":
+		pkgsFilter = oneMainPkg
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le",
+				"android/amd64", "android/arm", "android/arm64", "android/386":
+			case "darwin/amd64":
+				// Skip DWARF generation due to #21647
+				forcedLdflags = append(forcedLdflags, "-w")
+			default:
+				base.Fatalf("-buildmode=plugin not supported on %s\n", platform)
+			}
+			codegenArg = "-dynlink"
+		}
+		cfg.ExeSuffix = ".so"
+		ldBuildmode = "plugin"
+	default:
+		base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
+	}
+	if cfg.BuildLinkshared {
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
+				forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1")
+			default:
+				base.Fatalf("-linkshared not supported on %s\n", platform)
+			}
+			codegenArg = "-dynlink"
+			// TODO(mwhudson): remove -w when that gets fixed in linker.
+			forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
+		}
+	}
+	if codegenArg != "" {
+		if gccgo {
+			forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...)
+		} else {
+			forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...)
+			forcedGcflags = append([]string{codegenArg}, forcedGcflags...)
+		}
+		// Don't alter InstallSuffix when modifying default codegen args.
+		if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
+			if cfg.BuildContext.InstallSuffix != "" {
+				cfg.BuildContext.InstallSuffix += "_"
+			}
+			cfg.BuildContext.InstallSuffix += codegenArg[1:]
+		}
+	}
+}
diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
new file mode 100644
index 0000000..54fd6b9
--- /dev/null
+++ b/src/cmd/go/internal/work/security.go
@@ -0,0 +1,202 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Checking of compiler and linker flags.
+// We must avoid flags like -fplugin=, which can allow
+// arbitrary code execution during the build.
+// Do not make changes here without carefully
+// considering the implications.
+// (That's why the code is isolated in a file named security.go.)
+//
+// Note that -Wl,foo means split foo on commas and pass to
+// the linker, so that -Wl,-foo,bar means pass -foo bar to
+// the linker. Similarly -Wa,foo for the assembler and so on.
+// If any of these are permitted, the wildcard portion must
+// disallow commas.
+//
+// Note also that GNU binutils accept any argument @foo
+// as meaning "read more flags from the file foo", so we must
+// guard against any command-line argument beginning with @,
+// even things like "-I @foo".
+// We use load.SafeArg (which is even more conservative)
+// to reject these.
+//
+// Even worse, gcc -I@foo (one arg) turns into cc1 -I @foo (two args),
+// so although gcc doesn't expand the @foo, cc1 will.
+// So out of paranoia, we reject @ at the beginning of every
+// flag argument that might be split into its own argument.
+
+package work
+
+import (
+	"cmd/go/internal/load"
+	"fmt"
+	"os"
+	"regexp"
+	"strings"
+)
+
+var re = regexp.MustCompile
+
+var validCompilerFlags = []*regexp.Regexp{
+	re(`-D([A-Za-z_].*)`),
+	re(`-I([^@\-].*)`),
+	re(`-O`),
+	re(`-O([^@\-].*)`),
+	re(`-W`),
+	re(`-W([^@,]+)`), // -Wall but not -Wa,-foo.
+	re(`-f(no-)?blocks`),
+	re(`-f(no-)?common`),
+	re(`-f(no-)?constant-cfstrings`),
+	re(`-f(no-)?exceptions`),
+	re(`-finput-charset=([^@\-].*)`),
+	re(`-f(no-)?lto`),
+	re(`-f(no-)?modules`),
+	re(`-f(no-)?objc-arc`),
+	re(`-f(no-)?omit-frame-pointer`),
+	re(`-f(no-)?openmp(-simd)?`),
+	re(`-f(no-)?permissive`),
+	re(`-f(no-)?(pic|PIC|pie|PIE)`),
+	re(`-f(no-)?rtti`),
+	re(`-f(no-)?split-stack`),
+	re(`-f(no-)?stack-(.+)`),
+	re(`-f(no-)?strict-aliasing`),
+	re(`-fsanitize=(.+)`),
+	re(`-g([^@\-].*)?`),
+	re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-m(no-)?avx[0-9a-z.]*`),
+	re(`-m(no-)?ms-bitfields`),
+	re(`-m(no-)?stack-(.+)`),
+	re(`-mmacosx-(.+)`),
+	re(`-mnop-fun-dllimport`),
+	re(`-m(no-)?sse[0-9.]*`),
+	re(`-pedantic(-errors)?`),
+	re(`-pipe`),
+	re(`-pthread`),
+	re(`-?-std=([^@\-].*)`),
+	re(`-x([^@\-].*)`),
+}
+
+var validCompilerFlagsWithNextArg = []string{
+	"-D",
+	"-I",
+	"-isystem",
+	"-framework",
+	"-x",
+}
+
+var validLinkerFlags = []*regexp.Regexp{
+	re(`-F([^@\-].*)`),
+	re(`-l([^@\-].*)`),
+	re(`-L([^@\-].*)`),
+	re(`-f(no-)?(pic|PIC|pie|PIE)`),
+	re(`-fsanitize=([^@\-].*)`),
+	re(`-g([^@\-].*)?`),
+	re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-(pic|PIC|pie|PIE)`),
+	re(`-pthread`),
+	re(`-?-static([-a-z0-9+]*)`),
+
+	// Note that any wildcards in -Wl need to exclude comma,
+	// since -Wl splits its argument at commas and passes
+	// them all to the linker uninterpreted. Allowing comma
+	// in a wildcard would allow tunnelling arbitrary additional
+	// linker arguments through one of these.
+	re(`-Wl,--(no-)?as-needed`),
+	re(`-Wl,-Bdynamic`),
+	re(`-Wl,-Bstatic`),
+	re(`-Wl,--disable-new-dtags`),
+	re(`-Wl,--enable-new-dtags`),
+	re(`-Wl,--end-group`),
+	re(`-Wl,-framework,[^,@\-][^,]+`),
+	re(`-Wl,-headerpad_max_install_names`),
+	re(`-Wl,--no-undefined`),
+	re(`-Wl,-rpath,([^,@\-][^,]+)`),
+	re(`-Wl,-search_paths_first`),
+	re(`-Wl,--start-group`),
+	re(`-Wl,-?-unresolved-symbols=[^,]+`),
+	re(`-Wl,--(no-)?warn-([^,]+)`),
+
+	re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)
+}
+
+var validLinkerFlagsWithNextArg = []string{
+	"-F",
+	"-l",
+	"-L",
+	"-framework",
+	"-Wl,-framework",
+}
+
+func checkCompilerFlags(name, source string, list []string) error {
+	return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg)
+}
+
+func checkLinkerFlags(name, source string, list []string) error {
+	return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg)
+}
+
+func checkFlags(name, source string, list []string, valid []*regexp.Regexp, validNext []string) error {
+	// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
+	var (
+		allow    *regexp.Regexp
+		disallow *regexp.Regexp
+	)
+	if env := os.Getenv("CGO_" + name + "_ALLOW"); env != "" {
+		r, err := regexp.Compile(env)
+		if err != nil {
+			return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
+		}
+		allow = r
+	}
+	if env := os.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
+		r, err := regexp.Compile(env)
+		if err != nil {
+			return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
+		}
+		disallow = r
+	}
+
+Args:
+	for i := 0; i < len(list); i++ {
+		arg := list[i]
+		if disallow != nil && disallow.FindString(arg) == arg {
+			goto Bad
+		}
+		if allow != nil && allow.FindString(arg) == arg {
+			continue Args
+		}
+		for _, re := range valid {
+			if re.FindString(arg) == arg { // must be complete match
+				continue Args
+			}
+		}
+		for _, x := range validNext {
+			if arg == x {
+				if i+1 < len(list) && load.SafeArg(list[i+1]) {
+					i++
+					continue Args
+				}
+
+				// Permit -Wl,-framework -Wl,name.
+				if i+1 < len(list) &&
+					strings.HasPrefix(arg, "-Wl,") &&
+					strings.HasPrefix(list[i+1], "-Wl,") &&
+					load.SafeArg(list[i+1][4:]) &&
+					!strings.Contains(list[i+1][4:], ",") {
+					i++
+					continue Args
+				}
+
+				if i+1 < len(list) {
+					return fmt.Errorf("invalid flag in %s: %s %s (see https://golang.org/s/invalidflag)", source, arg, list[i+1])
+				}
+				return fmt.Errorf("invalid flag in %s: %s without argument (see https://golang.org/s/invalidflag)", source, arg)
+			}
+		}
+	Bad:
+		return fmt.Errorf("invalid flag in %s: %s", source, arg)
+	}
+	return nil
+}
diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go
new file mode 100644
index 0000000..976501b
--- /dev/null
+++ b/src/cmd/go/internal/work/security_test.go
@@ -0,0 +1,247 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package work
+
+import (
+	"os"
+	"testing"
+)
+
+var goodCompilerFlags = [][]string{
+	{"-DFOO"},
+	{"-Dfoo=bar"},
+	{"-I/"},
+	{"-I/etc/passwd"},
+	{"-I."},
+	{"-O"},
+	{"-O2"},
+	{"-Osmall"},
+	{"-W"},
+	{"-Wall"},
+	{"-fobjc-arc"},
+	{"-fno-objc-arc"},
+	{"-fomit-frame-pointer"},
+	{"-fno-omit-frame-pointer"},
+	{"-fpic"},
+	{"-fno-pic"},
+	{"-fPIC"},
+	{"-fno-PIC"},
+	{"-fpie"},
+	{"-fno-pie"},
+	{"-fPIE"},
+	{"-fno-PIE"},
+	{"-fsplit-stack"},
+	{"-fno-split-stack"},
+	{"-fstack-xxx"},
+	{"-fno-stack-xxx"},
+	{"-fsanitize=hands"},
+	{"-g"},
+	{"-ggdb"},
+	{"-march=souza"},
+	{"-mcpu=123"},
+	{"-mfpu=123"},
+	{"-mtune=happybirthday"},
+	{"-mstack-overflow"},
+	{"-mno-stack-overflow"},
+	{"-mmacosx-version"},
+	{"-mnop-fun-dllimport"},
+	{"-pthread"},
+	{"-std=c99"},
+	{"-xc"},
+	{"-D", "FOO"},
+	{"-D", "foo=bar"},
+	{"-I", "."},
+	{"-I", "/etc/passwd"},
+	{"-I", "世界"},
+	{"-framework", "Chocolate"},
+	{"-x", "c"},
+}
+
+var badCompilerFlags = [][]string{
+	{"-D@X"},
+	{"-D-X"},
+	{"-I@dir"},
+	{"-I-dir"},
+	{"-O@1"},
+	{"-Wa,-foo"},
+	{"-W@foo"},
+	{"-g@gdb"},
+	{"-g-gdb"},
+	{"-march=@dawn"},
+	{"-march=-dawn"},
+	{"-std=@c99"},
+	{"-std=-c99"},
+	{"-x@c"},
+	{"-x-c"},
+	{"-D", "@foo"},
+	{"-D", "-foo"},
+	{"-I", "@foo"},
+	{"-I", "-foo"},
+	{"-framework", "-Caffeine"},
+	{"-framework", "@Home"},
+	{"-x", "--c"},
+	{"-x", "@obj"},
+}
+
+func TestCheckCompilerFlags(t *testing.T) {
+	for _, f := range goodCompilerFlags {
+		if err := checkCompilerFlags("test", "test", f); err != nil {
+			t.Errorf("unexpected error for %q: %v", f, err)
+		}
+	}
+	for _, f := range badCompilerFlags {
+		if err := checkCompilerFlags("test", "test", f); err == nil {
+			t.Errorf("missing error for %q", f)
+		}
+	}
+}
+
+var goodLinkerFlags = [][]string{
+	{"-Fbar"},
+	{"-lbar"},
+	{"-Lbar"},
+	{"-fpic"},
+	{"-fno-pic"},
+	{"-fPIC"},
+	{"-fno-PIC"},
+	{"-fpie"},
+	{"-fno-pie"},
+	{"-fPIE"},
+	{"-fno-PIE"},
+	{"-fsanitize=hands"},
+	{"-g"},
+	{"-ggdb"},
+	{"-march=souza"},
+	{"-mcpu=123"},
+	{"-mfpu=123"},
+	{"-mtune=happybirthday"},
+	{"-pic"},
+	{"-pthread"},
+	{"-Wl,-rpath,foo"},
+	{"-Wl,-rpath,$ORIGIN/foo"},
+	{"-Wl,--warn-error"},
+	{"-Wl,--no-warn-error"},
+	{"foo.so"},
+	{"_世界.dll"},
+	{"libcgosotest.dylib"},
+	{"-F", "framework"},
+	{"-l", "."},
+	{"-l", "/etc/passwd"},
+	{"-l", "世界"},
+	{"-L", "framework"},
+	{"-framework", "Chocolate"},
+	{"-Wl,-framework", "-Wl,Chocolate"},
+	{"-Wl,-framework,Chocolate"},
+	{"-Wl,-unresolved-symbols=ignore-all"},
+}
+
+var badLinkerFlags = [][]string{
+	{"-DFOO"},
+	{"-Dfoo=bar"},
+	{"-O"},
+	{"-O2"},
+	{"-Osmall"},
+	{"-W"},
+	{"-Wall"},
+	{"-fobjc-arc"},
+	{"-fno-objc-arc"},
+	{"-fomit-frame-pointer"},
+	{"-fno-omit-frame-pointer"},
+	{"-fsplit-stack"},
+	{"-fno-split-stack"},
+	{"-fstack-xxx"},
+	{"-fno-stack-xxx"},
+	{"-mstack-overflow"},
+	{"-mno-stack-overflow"},
+	{"-mmacosx-version"},
+	{"-mnop-fun-dllimport"},
+	{"-std=c99"},
+	{"-xc"},
+	{"-D", "FOO"},
+	{"-D", "foo=bar"},
+	{"-I", "FOO"},
+	{"-L", "@foo"},
+	{"-L", "-foo"},
+	{"-x", "c"},
+	{"-D@X"},
+	{"-D-X"},
+	{"-I@dir"},
+	{"-I-dir"},
+	{"-O@1"},
+	{"-Wa,-foo"},
+	{"-W@foo"},
+	{"-g@gdb"},
+	{"-g-gdb"},
+	{"-march=@dawn"},
+	{"-march=-dawn"},
+	{"-std=@c99"},
+	{"-std=-c99"},
+	{"-x@c"},
+	{"-x-c"},
+	{"-D", "@foo"},
+	{"-D", "-foo"},
+	{"-I", "@foo"},
+	{"-I", "-foo"},
+	{"-l", "@foo"},
+	{"-l", "-foo"},
+	{"-framework", "-Caffeine"},
+	{"-framework", "@Home"},
+	{"-Wl,-framework,-Caffeine"},
+	{"-Wl,-framework", "-Wl,@Home"},
+	{"-Wl,-framework", "@Home"},
+	{"-Wl,-framework,Chocolate,@Home"},
+	{"-x", "--c"},
+	{"-x", "@obj"},
+	{"-Wl,-rpath,@foo"},
+}
+
+func TestCheckLinkerFlags(t *testing.T) {
+	for _, f := range goodLinkerFlags {
+		if err := checkLinkerFlags("test", "test", f); err != nil {
+			t.Errorf("unexpected error for %q: %v", f, err)
+		}
+	}
+	for _, f := range badLinkerFlags {
+		if err := checkLinkerFlags("test", "test", f); err == nil {
+			t.Errorf("missing error for %q", f)
+		}
+	}
+}
+
+func TestCheckFlagAllowDisallow(t *testing.T) {
+	if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil {
+		t.Fatalf("missing error for -disallow")
+	}
+	os.Setenv("CGO_TEST_ALLOW", "-disallo")
+	if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil {
+		t.Fatalf("missing error for -disallow with CGO_TEST_ALLOW=-disallo")
+	}
+	os.Setenv("CGO_TEST_ALLOW", "-disallow")
+	if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err != nil {
+		t.Fatalf("unexpected error for -disallow with CGO_TEST_ALLOW=-disallow: %v", err)
+	}
+	os.Unsetenv("CGO_TEST_ALLOW")
+
+	if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err != nil {
+		t.Fatalf("unexpected error for -Wall: %v", err)
+	}
+	os.Setenv("CGO_TEST_DISALLOW", "-Wall")
+	if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil {
+		t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall")
+	}
+	os.Setenv("CGO_TEST_ALLOW", "-Wall") // disallow wins
+	if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil {
+		t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall and CGO_TEST_ALLOW=-Wall")
+	}
+
+	os.Setenv("CGO_TEST_ALLOW", "-fplugin.*")
+	os.Setenv("CGO_TEST_DISALLOW", "-fplugin=lint.so")
+	if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=faster.so"}); err != nil {
+		t.Fatalf("unexpected error for -fplugin=faster.so: %v", err)
+	}
+	if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=lint.so"}); err == nil {
+		t.Fatalf("missing error for -fplugin=lint.so: %v", err)
+	}
+}
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 75a46db..497970b 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -56,6 +56,7 @@
 
 		help.HelpC,
 		help.HelpBuildmode,
+		help.HelpCache,
 		help.HelpFileType,
 		help.HelpGopath,
 		help.HelpEnvironment,
@@ -77,6 +78,7 @@
 		base.Usage()
 	}
 
+	cfg.CmdName = args[0] // for error messages
 	if args[0] == "help" {
 		help.Help(args[1:])
 		return
@@ -89,6 +91,11 @@
 		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
 	} else {
 		for _, p := range filepath.SplitList(gopath) {
+			// Some GOPATHs have empty directory elements - ignore them.
+			// See issue 21928 for details.
+			if p == "" {
+				continue
+			}
 			// Note: using HasPrefix instead of Contains because a ~ can appear
 			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
 			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
diff --git a/src/cmd/go/note_test.go b/src/cmd/go/note_test.go
index 289af99..66c5d39 100644
--- a/src/cmd/go/note_test.go
+++ b/src/cmd/go/note_test.go
@@ -9,33 +9,19 @@
 	"runtime"
 	"testing"
 
-	"cmd/go/internal/buildid"
+	"cmd/internal/buildid"
 )
 
 func TestNoteReading(t *testing.T) {
-	testNoteReading(t)
-}
-
-func TestNoteReading2K(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skipf("2kB is not enough on %s", runtime.GOOS)
-	}
-	// Set BuildIDReadSize to 2kB to exercise Mach-O parsing more strictly.
-	defer func(old int) {
-		buildid.BuildIDReadSize = old
-	}(buildid.BuildIDReadSize)
-	buildid.BuildIDReadSize = 2 * 1024
-
-	testNoteReading(t)
-}
-
-func testNoteReading(t *testing.T) {
+	// cmd/internal/buildid already has tests that the basic reading works.
+	// This test is essentially checking that -ldflags=-buildid=XXX works,
+	// both in internal and external linking mode.
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.tempFile("hello.go", `package main; func main() { print("hello, world\n") }`)
 	const buildID = "TestNoteReading-Build-ID"
 	tg.run("build", "-ldflags", "-buildid="+buildID, "-o", tg.path("hello.exe"), tg.path("hello.go"))
-	id, err := buildid.ReadBuildIDFromBinary(tg.path("hello.exe"))
+	id, err := buildid.ReadFile(tg.path("hello.exe"))
 	if err != nil {
 		t.Fatalf("reading build ID from hello binary: %v", err)
 	}
@@ -46,20 +32,41 @@
 	switch {
 	case !build.Default.CgoEnabled:
 		t.Skipf("skipping - no cgo, so assuming external linking not available")
-	case runtime.GOOS == "linux" && (runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64"):
-		t.Skipf("skipping - external linking not supported, golang.org/issue/11184")
 	case runtime.GOOS == "openbsd" && runtime.GOARCH == "arm":
 		t.Skipf("skipping - external linking not supported, golang.org/issue/10619")
 	case runtime.GOOS == "plan9":
 		t.Skipf("skipping - external linking not supported")
 	}
 
-	tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello.exe"), tg.path("hello.go"))
-	id, err = buildid.ReadBuildIDFromBinary(tg.path("hello.exe"))
+	tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello2.exe"), tg.path("hello.go"))
+	id, err = buildid.ReadFile(tg.path("hello2.exe"))
 	if err != nil {
 		t.Fatalf("reading build ID from hello binary (linkmode=external): %v", err)
 	}
 	if id != buildID {
 		t.Fatalf("buildID in hello binary = %q, want %q (linkmode=external)", id, buildID)
 	}
+
+	switch runtime.GOOS {
+	case "dragonfly", "freebsd", "linux", "netbsd", "openbsd":
+		// Test while forcing use of the gold linker, since in the past
+		// we've had trouble reading the notes generated by gold.
+		err := tg.doRun([]string{"build", "-ldflags", "-buildid=" + buildID + " -linkmode=external -extldflags=-fuse-ld=gold", "-o", tg.path("hello3.exe"), tg.path("hello.go")})
+		if err != nil {
+			if tg.grepCountBoth("(invalid linker|gold|cannot find 'ld')") > 0 {
+				// It's not an error if gold isn't there. gcc claims it "cannot find 'ld'" if
+				// ld.gold is missing, see issue #22340.
+				t.Log("skipping gold test")
+				break
+			}
+			t.Fatalf("building hello binary: %v", err)
+		}
+		id, err = buildid.ReadFile(tg.path("hello3.exe"))
+		if err != nil {
+			t.Fatalf("reading build ID from hello binary (linkmode=external -extldflags=-fuse-ld=gold): %v", err)
+		}
+		if id != buildID {
+			t.Fatalf("buildID in hello binary = %q, want %q (linkmode=external -extldflags=-fuse-ld=gold)", id, buildID)
+		}
+	}
 }
diff --git a/src/cmd/go/testdata/print_goroot.go b/src/cmd/go/testdata/print_goroot.go
new file mode 100644
index 0000000..5477291
--- /dev/null
+++ b/src/cmd/go/testdata/print_goroot.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime"
+
+func main() {
+	println(runtime.GOROOT())
+}
diff --git a/src/cmd/go/testdata/src/complex/main.go b/src/cmd/go/testdata/src/complex/main.go
new file mode 100644
index 0000000..c38df01
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/main.go
@@ -0,0 +1,12 @@
+package main
+
+import (
+	_ "complex/nest/sub/test12"
+	_ "complex/nest/sub/test23"
+	"complex/w"
+	"v"
+)
+
+func main() {
+	println(v.Hello + " " + w.World)
+}
diff --git a/src/cmd/go/testdata/src/complex/nest/sub/test12/p.go b/src/cmd/go/testdata/src/complex/nest/sub/test12/p.go
new file mode 100644
index 0000000..94943ec
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/sub/test12/p.go
@@ -0,0 +1,11 @@
+package test12
+
+// Check that vendor/v1 is used but vendor/v2 is NOT used (sub/vendor/v2 wins).
+
+import (
+	"v1"
+	"v2"
+)
+
+const x = v1.ComplexNestVendorV1
+const y = v2.ComplexNestSubVendorV2
diff --git a/src/cmd/go/testdata/src/complex/nest/sub/test23/p.go b/src/cmd/go/testdata/src/complex/nest/sub/test23/p.go
new file mode 100644
index 0000000..8801a48
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/sub/test23/p.go
@@ -0,0 +1,11 @@
+package test23
+
+// Check that vendor/v3 is used but vendor/v2 is NOT used (sub/vendor/v2 wins).
+
+import (
+	"v2"
+	"v3"
+)
+
+const x = v3.ComplexNestVendorV3
+const y = v2.ComplexNestSubVendorV2
diff --git a/src/cmd/go/testdata/src/complex/nest/sub/vendor/v2/v2.go b/src/cmd/go/testdata/src/complex/nest/sub/vendor/v2/v2.go
new file mode 100644
index 0000000..2991871
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/sub/vendor/v2/v2.go
@@ -0,0 +1,3 @@
+package v2
+
+const ComplexNestSubVendorV2 = true
diff --git a/src/cmd/go/testdata/src/complex/nest/vendor/v1/v1.go b/src/cmd/go/testdata/src/complex/nest/vendor/v1/v1.go
new file mode 100644
index 0000000..a55f529
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/vendor/v1/v1.go
@@ -0,0 +1,3 @@
+package v1
+
+const ComplexNestVendorV1 = true
diff --git a/src/cmd/go/testdata/src/complex/nest/vendor/v2/v2.go b/src/cmd/go/testdata/src/complex/nest/vendor/v2/v2.go
new file mode 100644
index 0000000..ac94def
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/vendor/v2/v2.go
@@ -0,0 +1,3 @@
+package v2
+
+const ComplexNestVendorV2 = true
diff --git a/src/cmd/go/testdata/src/complex/nest/vendor/v3/v3.go b/src/cmd/go/testdata/src/complex/nest/vendor/v3/v3.go
new file mode 100644
index 0000000..abf99b9
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/nest/vendor/v3/v3.go
@@ -0,0 +1,3 @@
+package v3
+
+const ComplexNestVendorV3 = true
diff --git a/src/cmd/go/testdata/src/complex/vendor/v/v.go b/src/cmd/go/testdata/src/complex/vendor/v/v.go
new file mode 100644
index 0000000..bb20d86
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/vendor/v/v.go
@@ -0,0 +1,3 @@
+package v
+
+const Hello = "hello"
diff --git a/src/cmd/go/testdata/src/complex/w/w.go b/src/cmd/go/testdata/src/complex/w/w.go
new file mode 100644
index 0000000..a9c7fbb
--- /dev/null
+++ b/src/cmd/go/testdata/src/complex/w/w.go
@@ -0,0 +1,3 @@
+package w
+
+const World = "world"
diff --git a/src/cmd/go/testdata/src/coverasm/p.go b/src/cmd/go/testdata/src/coverasm/p.go
new file mode 100644
index 0000000..ab0c300
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverasm/p.go
@@ -0,0 +1,7 @@
+package p
+
+func f()
+
+func g() {
+	println("g")
+}
diff --git a/src/cmd/go/testdata/src/coverasm/p.s b/src/cmd/go/testdata/src/coverasm/p.s
new file mode 100644
index 0000000..5e728f9
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverasm/p.s
@@ -0,0 +1,2 @@
+// empty asm file,
+// so go test doesn't complain about declaration of f in p.go.
diff --git a/src/cmd/go/testdata/src/coverasm/p_test.go b/src/cmd/go/testdata/src/coverasm/p_test.go
new file mode 100644
index 0000000..3cb3bd5
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverasm/p_test.go
@@ -0,0 +1,7 @@
+package p
+
+import "testing"
+
+func Test(t *testing.T) {
+	g()
+}
diff --git a/src/cmd/go/testdata/src/coverbad/p.go b/src/cmd/go/testdata/src/coverbad/p.go
new file mode 100644
index 0000000..16504a4
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverbad/p.go
@@ -0,0 +1,5 @@
+package p
+
+func f() {
+	g()
+}
diff --git a/src/cmd/go/testdata/src/coverbad/p1.go b/src/cmd/go/testdata/src/coverbad/p1.go
new file mode 100644
index 0000000..2d25c8e
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverbad/p1.go
@@ -0,0 +1,7 @@
+package p
+
+import "C"
+
+func h() {
+	j()
+}
diff --git a/src/cmd/go/testdata/src/coverbad/p_test.go b/src/cmd/go/testdata/src/coverbad/p_test.go
new file mode 100644
index 0000000..3a876d6
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverbad/p_test.go
@@ -0,0 +1,5 @@
+package p
+
+import "testing"
+
+func Test(t *testing.T) {}
diff --git a/src/cmd/go/testdata/src/coverdep/p.go b/src/cmd/go/testdata/src/coverdep/p.go
new file mode 100644
index 0000000..6baf6d5
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep/p.go
@@ -0,0 +1,6 @@
+package p
+
+import _ "coverdep/p1"
+
+func F() {
+}
diff --git a/src/cmd/go/testdata/src/coverdep/p1/p1.go b/src/cmd/go/testdata/src/coverdep/p1/p1.go
new file mode 100644
index 0000000..8ae793d
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep/p1/p1.go
@@ -0,0 +1,3 @@
+package p1
+
+import _ "errors"
diff --git a/src/cmd/go/testdata/src/coverdep/p_test.go b/src/cmd/go/testdata/src/coverdep/p_test.go
new file mode 100644
index 0000000..11a1434
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep/p_test.go
@@ -0,0 +1,7 @@
+package p
+
+import "testing"
+
+func Test(t *testing.T) {
+	F()
+}
diff --git a/src/cmd/go/testdata/src/coverdep2/p1/p.go b/src/cmd/go/testdata/src/coverdep2/p1/p.go
new file mode 100644
index 0000000..fd31527
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep2/p1/p.go
@@ -0,0 +1,3 @@
+package p1
+
+func F() int { return 1 }
diff --git a/src/cmd/go/testdata/src/coverdep2/p1/p_test.go b/src/cmd/go/testdata/src/coverdep2/p1/p_test.go
new file mode 100644
index 0000000..c402568
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep2/p1/p_test.go
@@ -0,0 +1,10 @@
+package p1_test
+
+import (
+	"coverdep2/p2"
+	"testing"
+)
+
+func Test(t *testing.T) {
+	p2.F()
+}
diff --git a/src/cmd/go/testdata/src/coverdep2/p2/p2.go b/src/cmd/go/testdata/src/coverdep2/p2/p2.go
new file mode 100644
index 0000000..33561bb
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdep2/p2/p2.go
@@ -0,0 +1,7 @@
+package p2
+
+import "coverdep2/p1"
+
+func F() {
+	p1.F()
+}
diff --git a/src/cmd/go/testdata/src/coverdot1/p.go b/src/cmd/go/testdata/src/coverdot1/p.go
new file mode 100644
index 0000000..cda364f
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdot1/p.go
@@ -0,0 +1,3 @@
+package coverdot1
+
+func F() {}
diff --git a/src/cmd/go/testdata/src/coverdot2/p.go b/src/cmd/go/testdata/src/coverdot2/p.go
new file mode 100644
index 0000000..80f79ae
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdot2/p.go
@@ -0,0 +1,5 @@
+package coverdot2
+
+import . "coverdot1"
+
+func G() { F() }
diff --git a/src/cmd/go/testdata/src/coverdot2/p_test.go b/src/cmd/go/testdata/src/coverdot2/p_test.go
new file mode 100644
index 0000000..da66e3e
--- /dev/null
+++ b/src/cmd/go/testdata/src/coverdot2/p_test.go
@@ -0,0 +1,7 @@
+package coverdot2
+
+import "testing"
+
+func TestG(t *testing.T) {
+	G()
+}
diff --git a/src/cmd/go/testdata/src/failfast_test.go b/src/cmd/go/testdata/src/failfast_test.go
new file mode 100644
index 0000000..fef4d2a
--- /dev/null
+++ b/src/cmd/go/testdata/src/failfast_test.go
@@ -0,0 +1,54 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package failfast
+
+import "testing"
+
+func TestA(t *testing.T) {
+	// Edge-case testing, mixing unparallel tests too
+	t.Logf("LOG: %s", t.Name())
+}
+
+func TestFailingA(t *testing.T) {
+	t.Errorf("FAIL - %s", t.Name())
+}
+
+func TestB(t *testing.T) {
+	// Edge-case testing, mixing unparallel tests too
+	t.Logf("LOG: %s", t.Name())
+}
+
+func TestParallelFailingA(t *testing.T) {
+	t.Parallel()
+	t.Errorf("FAIL - %s", t.Name())
+}
+
+func TestParallelFailingB(t *testing.T) {
+	t.Parallel()
+	t.Errorf("FAIL - %s", t.Name())
+}
+
+func TestParallelFailingSubtestsA(t *testing.T) {
+	t.Parallel()
+	t.Run("TestFailingSubtestsA1", func(t *testing.T) {
+		t.Errorf("FAIL - %s", t.Name())
+	})
+	t.Run("TestFailingSubtestsA2", func(t *testing.T) {
+		t.Errorf("FAIL - %s", t.Name())
+	})
+}
+
+func TestFailingSubtestsA(t *testing.T) {
+	t.Run("TestFailingSubtestsA1", func(t *testing.T) {
+		t.Errorf("FAIL - %s", t.Name())
+	})
+	t.Run("TestFailingSubtestsA2", func(t *testing.T) {
+		t.Errorf("FAIL - %s", t.Name())
+	})
+}
+
+func TestFailingB(t *testing.T) {
+	t.Errorf("FAIL - %s", t.Name())
+}
diff --git a/src/cmd/go/testdata/src/multimain/multimain_test.go b/src/cmd/go/testdata/src/multimain/multimain_test.go
new file mode 100644
index 0000000..007a86a
--- /dev/null
+++ b/src/cmd/go/testdata/src/multimain/multimain_test.go
@@ -0,0 +1,16 @@
+package multimain_test
+
+import "testing"
+
+func TestMain(m *testing.M) {
+	// Some users run m.Run multiple times, changing
+	// some kind of global state between runs.
+	// This used to work so I guess now it has to keep working.
+	// See golang.org/issue/23129.
+	m.Run()
+	m.Run()
+}
+
+func Test(t *testing.T) {
+	t.Log("notwithstanding")
+}
diff --git a/src/cmd/go/testdata/src/not_main/not_main.go b/src/cmd/go/testdata/src/not_main/not_main.go
new file mode 100644
index 0000000..75a397c
--- /dev/null
+++ b/src/cmd/go/testdata/src/not_main/not_main.go
@@ -0,0 +1,3 @@
+package not_main
+
+func F() {}
diff --git a/src/cmd/go/testdata/src/skipper/skip_test.go b/src/cmd/go/testdata/src/skipper/skip_test.go
new file mode 100644
index 0000000..58e6dc5
--- /dev/null
+++ b/src/cmd/go/testdata/src/skipper/skip_test.go
@@ -0,0 +1,7 @@
+package skipper
+
+import "testing"
+
+func Test(t *testing.T) {
+	t.Skip("skipping")
+}
diff --git a/src/cmd/go/testdata/src/sleepy1/p_test.go b/src/cmd/go/testdata/src/sleepy1/p_test.go
new file mode 100644
index 0000000..333be7d
--- /dev/null
+++ b/src/cmd/go/testdata/src/sleepy1/p_test.go
@@ -0,0 +1,10 @@
+package p
+
+import (
+	"testing"
+	"time"
+)
+
+func Test1(t *testing.T) {
+	time.Sleep(200 * time.Millisecond)
+}
diff --git a/src/cmd/go/testdata/src/sleepy2/p_test.go b/src/cmd/go/testdata/src/sleepy2/p_test.go
new file mode 100644
index 0000000..333be7d
--- /dev/null
+++ b/src/cmd/go/testdata/src/sleepy2/p_test.go
@@ -0,0 +1,10 @@
+package p
+
+import (
+	"testing"
+	"time"
+)
+
+func Test1(t *testing.T) {
+	time.Sleep(200 * time.Millisecond)
+}
diff --git a/src/cmd/go/testdata/src/sleepybad/p.go b/src/cmd/go/testdata/src/sleepybad/p.go
new file mode 100644
index 0000000..e05b403
--- /dev/null
+++ b/src/cmd/go/testdata/src/sleepybad/p.go
@@ -0,0 +1,5 @@
+package p
+
+// missing import
+
+var _ = io.DoesNotExist
diff --git a/src/cmd/go/testdata/src/testcache/testcache_test.go b/src/cmd/go/testdata/src/testcache/testcache_test.go
new file mode 100644
index 0000000..9b2d1ea
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcache/testcache_test.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testcache
+
+import (
+	"io/ioutil"
+	"os"
+	"runtime"
+	"testing"
+)
+
+func TestChdir(t *testing.T) {
+	os.Chdir("..")
+	defer os.Chdir("testcache")
+	info, err := os.Stat("testcache/file.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if info.Size()%2 != 1 {
+		t.Fatal("even file")
+	}
+}
+
+func TestOddFileContent(t *testing.T) {
+	f, err := os.Open("file.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	data, err := ioutil.ReadAll(f)
+	f.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(data)%2 != 1 {
+		t.Fatal("even file")
+	}
+}
+
+func TestOddFileSize(t *testing.T) {
+	info, err := os.Stat("file.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if info.Size()%2 != 1 {
+		t.Fatal("even file")
+	}
+}
+
+func TestOddGetenv(t *testing.T) {
+	val := os.Getenv("TESTKEY")
+	if len(val)%2 != 1 {
+		t.Fatal("even env value")
+	}
+}
+
+func TestLookupEnv(t *testing.T) {
+	_, ok := os.LookupEnv("TESTKEY")
+	if !ok {
+		t.Fatal("env missing")
+	}
+}
+
+func TestDirList(t *testing.T) {
+	f, err := os.Open(".")
+	if err != nil {
+		t.Fatal(err)
+	}
+	f.Readdirnames(-1)
+	f.Close()
+}
+
+func TestExec(t *testing.T) {
+	if runtime.GOOS == "plan9" || runtime.GOOS == "windows" || runtime.GOOS == "nacl" {
+		t.Skip("non-unix")
+	}
+
+	// Note: not using os/exec to make sure there is no unexpected stat.
+	p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr))
+	if err != nil {
+		t.Fatal(err)
+	}
+	ps, err := p.Wait()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !ps.Success() {
+		t.Fatalf("script failed: %v", err)
+	}
+}
diff --git a/src/cmd/go/testdata/src/testrace/race_test.go b/src/cmd/go/testdata/src/testrace/race_test.go
index 264dcf0..7ec0c6d 100644
--- a/src/cmd/go/testdata/src/testrace/race_test.go
+++ b/src/cmd/go/testdata/src/testrace/race_test.go
@@ -12,6 +12,7 @@
 		}()
 		x = 3
 		<-c
+		_ = x
 	}
 }
 
@@ -25,5 +26,6 @@
 		}()
 		x = 3
 		<-c
+		_ = x
 	}
 }
diff --git a/src/cmd/go/testdata/src/vetcycle/p.go b/src/cmd/go/testdata/src/vetcycle/p.go
new file mode 100644
index 0000000..857c3a6
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetcycle/p.go
@@ -0,0 +1,12 @@
+package p
+
+
+type (
+	_ interface{ m(B1) }
+	A1 interface{ a(D1) }
+	B1 interface{ A1 }
+	C1 interface{ B1 /* ERROR issue #18395 */ }
+	D1 interface{ C1 }
+)
+
+var _ A1 = C1 /* ERROR cannot use C1 */ (nil)
diff --git a/src/cmd/go/testdata/src/vetfail/p1/p1.go b/src/cmd/go/testdata/src/vetfail/p1/p1.go
new file mode 100644
index 0000000..248317b
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetfail/p1/p1.go
@@ -0,0 +1,7 @@
+package p1
+
+import "fmt"
+
+func F() {
+	fmt.Printf("%d", "hello") // causes vet error
+}
diff --git a/src/cmd/go/testdata/src/vetfail/p2/p2.go b/src/cmd/go/testdata/src/vetfail/p2/p2.go
new file mode 100644
index 0000000..88b1cc2
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetfail/p2/p2.go
@@ -0,0 +1,6 @@
+package p2
+
+import _ "vetfail/p1"
+
+func F() {
+}
diff --git a/src/cmd/go/testdata/src/vetfail/p2/p2_test.go b/src/cmd/go/testdata/src/vetfail/p2/p2_test.go
new file mode 100644
index 0000000..fde0d1a
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetfail/p2/p2_test.go
@@ -0,0 +1,7 @@
+package p2
+
+import "testing"
+
+func TestF(t *testing.T) {
+	F()
+}
diff --git a/src/cmd/go/testdata/standalone_main_normal_test.go b/src/cmd/go/testdata/standalone_main_normal_test.go
new file mode 100644
index 0000000..018ce75
--- /dev/null
+++ b/src/cmd/go/testdata/standalone_main_normal_test.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package standalone_main_normal_test
+
+import "testing"
+
+func TestMain(t *testing.T) {
+}
diff --git a/src/cmd/go/testdata/standalone_main_wrong_test.go b/src/cmd/go/testdata/standalone_main_wrong_test.go
new file mode 100644
index 0000000..5999887
--- /dev/null
+++ b/src/cmd/go/testdata/standalone_main_wrong_test.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package standalone_main_wrong_test
+
+import "testing"
+
+func TestMain(m *testing.Main) {
+}
diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
index 739ce5a..4f21a51 100644
--- a/src/cmd/go/vendor_test.go
+++ b/src/cmd/go/vendor_test.go
@@ -148,6 +148,7 @@
 }
 
 func TestVendorGet(t *testing.T) {
+	tooSlow(t)
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.tempFile("src/v/m.go", `
@@ -173,8 +174,8 @@
 	tg.grepStdout("v/vendor/vendor.org/p", "import not in vendor directory")
 	tg.run("list", "-f", "{{.TestImports}}")
 	tg.grepStdout("v/vendor/vendor.org/p", "test import not in vendor directory")
-	tg.run("get")
-	tg.run("get", "-t")
+	tg.run("get", "-d")
+	tg.run("get", "-t", "-d")
 }
 
 func TestVendorGetUpdate(t *testing.T) {
diff --git a/src/cmd/internal/buildid/buildid.go b/src/cmd/internal/buildid/buildid.go
new file mode 100644
index 0000000..fa3d7f3
--- /dev/null
+++ b/src/cmd/internal/buildid/buildid.go
@@ -0,0 +1,238 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"debug/elf"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+)
+
+var (
+	errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain")
+	errBuildIDMalformed = fmt.Errorf("malformed object file")
+	errBuildIDUnknown   = fmt.Errorf("lost build ID")
+)
+
+var (
+	bangArch = []byte("!<arch>")
+	pkgdef   = []byte("__.PKGDEF")
+	goobject = []byte("go object ")
+	buildid  = []byte("build id ")
+)
+
+// ReadFile reads the build ID from an archive or executable file.
+func ReadFile(name string) (id string, err error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+
+	buf := make([]byte, 8)
+	if _, err := f.ReadAt(buf, 0); err != nil {
+		return "", err
+	}
+	if string(buf) != "!<arch>\n" {
+		return readBinary(name, f)
+	}
+
+	// Read just enough of the target to fetch the build ID.
+	// The archive is expected to look like:
+	//
+	//	!<arch>
+	//	__.PKGDEF       0           0     0     644     7955      `
+	//	go object darwin amd64 devel X:none
+	//	build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224"
+	//
+	// The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none).
+	// Reading the first 1024 bytes should be plenty.
+	data := make([]byte, 1024)
+	n, err := io.ReadFull(f, data)
+	if err != nil && n == 0 {
+		return "", err
+	}
+
+	tryGccgo := func() (string, error) {
+		return readGccgoArchive(name, f)
+	}
+
+	// Archive header.
+	for i := 0; ; i++ { // returns during i==3
+		j := bytes.IndexByte(data, '\n')
+		if j < 0 {
+			return tryGccgo()
+		}
+		line := data[:j]
+		data = data[j+1:]
+		switch i {
+		case 0:
+			if !bytes.Equal(line, bangArch) {
+				return tryGccgo()
+			}
+		case 1:
+			if !bytes.HasPrefix(line, pkgdef) {
+				return tryGccgo()
+			}
+		case 2:
+			if !bytes.HasPrefix(line, goobject) {
+				return tryGccgo()
+			}
+		case 3:
+			if !bytes.HasPrefix(line, buildid) {
+				// Found the object header, just doesn't have a build id line.
+				// Treat as successful, with empty build id.
+				return "", nil
+			}
+			id, err := strconv.Unquote(string(line[len(buildid):]))
+			if err != nil {
+				return tryGccgo()
+			}
+			return id, nil
+		}
+	}
+}
+
+// readGccgoArchive tries to parse the archive as a standard Unix
+// archive file, and fetch the build ID from the _buildid.o entry.
+// The _buildid.o entry is written by (*Builder).gccgoBuildIDELFFile
+// in cmd/go/internal/work/exec.go.
+func readGccgoArchive(name string, f *os.File) (string, error) {
+	bad := func() (string, error) {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+
+	off := int64(8)
+	for {
+		if _, err := f.Seek(off, io.SeekStart); err != nil {
+			return "", err
+		}
+
+		// TODO(iant): Make a debug/ar package, and use it
+		// here and in cmd/link.
+		var hdr [60]byte
+		if _, err := io.ReadFull(f, hdr[:]); err != nil {
+			if err == io.EOF {
+				// No more entries, no build ID.
+				return "", nil
+			}
+			return "", err
+		}
+		off += 60
+
+		sizeStr := strings.TrimSpace(string(hdr[48:58]))
+		size, err := strconv.ParseInt(sizeStr, 0, 64)
+		if err != nil {
+			return bad()
+		}
+
+		name := strings.TrimSpace(string(hdr[:16]))
+		if name == "_buildid.o/" {
+			sr := io.NewSectionReader(f, off, size)
+			e, err := elf.NewFile(sr)
+			if err != nil {
+				return bad()
+			}
+			s := e.Section(".go.buildid")
+			if s == nil {
+				return bad()
+			}
+			data, err := s.Data()
+			if err != nil {
+				return bad()
+			}
+			return string(data), nil
+		}
+
+		off += size
+		if off&1 != 0 {
+			off++
+		}
+	}
+}
+
+var (
+	goBuildPrefix = []byte("\xff Go build ID: \"")
+	goBuildEnd    = []byte("\"\n \xff")
+
+	elfPrefix = []byte("\x7fELF")
+
+	machoPrefixes = [][]byte{
+		{0xfe, 0xed, 0xfa, 0xce},
+		{0xfe, 0xed, 0xfa, 0xcf},
+		{0xce, 0xfa, 0xed, 0xfe},
+		{0xcf, 0xfa, 0xed, 0xfe},
+	}
+)
+
+var readSize = 32 * 1024 // changed for testing
+
+// readBinary reads the build ID from a binary.
+//
+// ELF binaries store the build ID in a proper PT_NOTE section.
+//
+// Other binary formats are not so flexible. For those, the linker
+// stores the build ID as non-instruction bytes at the very beginning
+// of the text segment, which should appear near the beginning
+// of the file. This is clumsy but fairly portable. Custom locations
+// can be added for other binary types as needed, like we did for ELF.
+func readBinary(name string, f *os.File) (id string, err error) {
+	// Read the first 32 kB of the binary file.
+	// That should be enough to find the build ID.
+	// In ELF files, the build ID is in the leading headers,
+	// which are typically less than 4 kB, not to mention 32 kB.
+	// In Mach-O files, there's no limit, so we have to parse the file.
+	// On other systems, we're trying to read enough that
+	// we get the beginning of the text segment in the read.
+	// The offset where the text segment begins in a hello
+	// world compiled for each different object format today:
+	//
+	//	Plan 9: 0x20
+	//	Windows: 0x600
+	//
+	data := make([]byte, readSize)
+	_, err = io.ReadFull(f, data)
+	if err == io.ErrUnexpectedEOF {
+		err = nil
+	}
+	if err != nil {
+		return "", err
+	}
+
+	if bytes.HasPrefix(data, elfPrefix) {
+		return readELF(name, f, data)
+	}
+	for _, m := range machoPrefixes {
+		if bytes.HasPrefix(data, m) {
+			return readMacho(name, f, data)
+		}
+	}
+	return readRaw(name, data)
+}
+
+// readRaw finds the raw build ID stored in text segment data.
+func readRaw(name string, data []byte) (id string, err error) {
+	i := bytes.Index(data, goBuildPrefix)
+	if i < 0 {
+		// Missing. Treat as successful but build ID empty.
+		return "", nil
+	}
+
+	j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd)
+	if j < 0 {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+
+	quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1]
+	id, err = strconv.Unquote(string(quoted))
+	if err != nil {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+	return id, nil
+}
diff --git a/src/cmd/internal/buildid/buildid_test.go b/src/cmd/internal/buildid/buildid_test.go
new file mode 100644
index 0000000..15481dd
--- /dev/null
+++ b/src/cmd/internal/buildid/buildid_test.go
@@ -0,0 +1,137 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"testing"
+)
+
+const (
+	expectedID = "abcdefghijklmnopqrstuvwxyz.1234567890123456789012345678901234567890123456789012345678901234"
+	newID      = "bcdefghijklmnopqrstuvwxyza.2345678901234567890123456789012345678901234567890123456789012341"
+)
+
+func TestReadFile(t *testing.T) {
+	var files = []string{
+		"p.a",
+		"a.elf",
+		"a.macho",
+		"a.pe",
+	}
+
+	f, err := ioutil.TempFile("", "buildid-test-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	tmp := f.Name()
+	defer os.Remove(tmp)
+	f.Close()
+
+	for _, f := range files {
+		id, err := ReadFile("testdata/" + f)
+		if id != expectedID || err != nil {
+			t.Errorf("ReadFile(testdata/%s) = %q, %v, want %q, nil", f, id, err, expectedID)
+		}
+		old := readSize
+		readSize = 2048
+		id, err = ReadFile("testdata/" + f)
+		readSize = old
+		if id != expectedID || err != nil {
+			t.Errorf("ReadFile(testdata/%s) [readSize=2k] = %q, %v, want %q, nil", f, id, err, expectedID)
+		}
+
+		data, err := ioutil.ReadFile("testdata/" + f)
+		if err != nil {
+			t.Fatal(err)
+		}
+		m, _, err := FindAndHash(bytes.NewReader(data), expectedID, 1024)
+		if err != nil {
+			t.Errorf("FindAndHash(testdata/%s): %v", f, err)
+			continue
+		}
+		if err := ioutil.WriteFile(tmp, data, 0666); err != nil {
+			t.Error(err)
+			continue
+		}
+		tf, err := os.OpenFile(tmp, os.O_WRONLY, 0)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		err = Rewrite(tf, m, newID)
+		err2 := tf.Close()
+		if err != nil {
+			t.Errorf("Rewrite(testdata/%s): %v", f, err)
+			continue
+		}
+		if err2 != nil {
+			t.Fatal(err2)
+		}
+
+		id, err = ReadFile(tmp)
+		if id != newID || err != nil {
+			t.Errorf("ReadFile(testdata/%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID)
+		}
+	}
+}
+
+func TestFindAndHash(t *testing.T) {
+	buf := make([]byte, 64)
+	buf2 := make([]byte, 64)
+	id := make([]byte, 8)
+	zero := make([]byte, 8)
+	for i := range id {
+		id[i] = byte(i)
+	}
+	numError := 0
+	errorf := func(msg string, args ...interface{}) {
+		t.Errorf(msg, args...)
+		if numError++; numError > 20 {
+			t.Logf("stopping after too many errors")
+			t.FailNow()
+		}
+	}
+	for bufSize := len(id); bufSize <= len(buf); bufSize++ {
+		for j := range buf {
+			for k := 0; k < 2*len(id) && j+k < len(buf); k++ {
+				for i := range buf {
+					buf[i] = 1
+				}
+				copy(buf[j:], id)
+				copy(buf[j+k:], id)
+				var m []int64
+				if j+len(id) <= j+k {
+					m = append(m, int64(j))
+				}
+				if j+k+len(id) <= len(buf) {
+					m = append(m, int64(j+k))
+				}
+				copy(buf2, buf)
+				for _, p := range m {
+					copy(buf2[p:], zero)
+				}
+				h := sha256.Sum256(buf2)
+
+				matches, hash, err := FindAndHash(bytes.NewReader(buf), string(id), bufSize)
+				if err != nil {
+					errorf("bufSize=%d j=%d k=%d: findAndHash: %v", bufSize, j, k, err)
+					continue
+				}
+				if !reflect.DeepEqual(matches, m) {
+					errorf("bufSize=%d j=%d k=%d: findAndHash: matches=%v, want %v", bufSize, j, k, matches, m)
+					continue
+				}
+				if hash != h {
+					errorf("bufSize=%d j=%d k=%d: findAndHash: matches correct, but hash=%x, want %x", bufSize, j, k, hash, h)
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/internal/buildid/note.go b/src/cmd/internal/buildid/note.go
new file mode 100644
index 0000000..f0439fb
--- /dev/null
+++ b/src/cmd/internal/buildid/note.go
@@ -0,0 +1,206 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"os"
+)
+
+func readAligned4(r io.Reader, sz int32) ([]byte, error) {
+	full := (sz + 3) &^ 3
+	data := make([]byte, full)
+	_, err := io.ReadFull(r, data)
+	if err != nil {
+		return nil, err
+	}
+	data = data[:sz]
+	return data, nil
+}
+
+func ReadELFNote(filename, name string, typ int32) ([]byte, error) {
+	f, err := elf.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	for _, sect := range f.Sections {
+		if sect.Type != elf.SHT_NOTE {
+			continue
+		}
+		r := sect.Open()
+		for {
+			var namesize, descsize, noteType int32
+			err = binary.Read(r, f.ByteOrder, &namesize)
+			if err != nil {
+				if err == io.EOF {
+					break
+				}
+				return nil, fmt.Errorf("read namesize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, &descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read descsize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, &noteType)
+			if err != nil {
+				return nil, fmt.Errorf("read type failed: %v", err)
+			}
+			noteName, err := readAligned4(r, namesize)
+			if err != nil {
+				return nil, fmt.Errorf("read name failed: %v", err)
+			}
+			desc, err := readAligned4(r, descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read desc failed: %v", err)
+			}
+			if name == string(noteName) && typ == noteType {
+				return desc, nil
+			}
+		}
+	}
+	return nil, nil
+}
+
+var elfGoNote = []byte("Go\x00\x00")
+var elfGNUNote = []byte("GNU\x00")
+
+// The Go build ID is stored in a note described by an ELF PT_NOTE prog
+// header. The caller has already opened filename, to get f, and read
+// at least 4 kB out, in data.
+func readELF(name string, f *os.File, data []byte) (buildid string, err error) {
+	// Assume the note content is in the data, already read.
+	// Rewrite the ELF header to set shnum to 0, so that we can pass
+	// the data to elf.NewFile and it will decode the Prog list but not
+	// try to read the section headers and the string table from disk.
+	// That's a waste of I/O when all we care about is the Prog list
+	// and the one ELF note.
+	switch elf.Class(data[elf.EI_CLASS]) {
+	case elf.ELFCLASS32:
+		data[48] = 0
+		data[49] = 0
+	case elf.ELFCLASS64:
+		data[60] = 0
+		data[61] = 0
+	}
+
+	const elfGoBuildIDTag = 4
+	const gnuBuildIDTag = 3
+
+	ef, err := elf.NewFile(bytes.NewReader(data))
+	if err != nil {
+		return "", &os.PathError{Path: name, Op: "parse", Err: err}
+	}
+	var gnu string
+	for _, p := range ef.Progs {
+		if p.Type != elf.PT_NOTE || p.Filesz < 16 {
+			continue
+		}
+
+		var note []byte
+		if p.Off+p.Filesz < uint64(len(data)) {
+			note = data[p.Off : p.Off+p.Filesz]
+		} else {
+			// For some linkers, such as the Solaris linker,
+			// the buildid may not be found in data (which
+			// likely contains the first 16kB of the file)
+			// or even the first few megabytes of the file
+			// due to differences in note segment placement;
+			// in that case, extract the note data manually.
+			_, err = f.Seek(int64(p.Off), io.SeekStart)
+			if err != nil {
+				return "", err
+			}
+
+			note = make([]byte, p.Filesz)
+			_, err = io.ReadFull(f, note)
+			if err != nil {
+				return "", err
+			}
+		}
+
+		filesz := p.Filesz
+		off := p.Off
+		for filesz >= 16 {
+			nameSize := ef.ByteOrder.Uint32(note)
+			valSize := ef.ByteOrder.Uint32(note[4:])
+			tag := ef.ByteOrder.Uint32(note[8:])
+			nname := note[12:16]
+			if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == elfGoBuildIDTag && bytes.Equal(nname, elfGoNote) {
+				return string(note[16 : 16+valSize]), nil
+			}
+
+			if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == gnuBuildIDTag && bytes.Equal(nname, elfGNUNote) {
+				gnu = string(note[16 : 16+valSize])
+			}
+
+			nameSize = (nameSize + 3) &^ 3
+			valSize = (valSize + 3) &^ 3
+			notesz := uint64(12 + nameSize + valSize)
+			if filesz <= notesz {
+				break
+			}
+			off += notesz
+			align := uint64(p.Align)
+			alignedOff := (off + align - 1) &^ (align - 1)
+			notesz += alignedOff - off
+			off = alignedOff
+			filesz -= notesz
+			note = note[notesz:]
+		}
+	}
+
+	// If we didn't find a Go note, use a GNU note if available.
+	// This is what gccgo uses.
+	if gnu != "" {
+		return gnu, nil
+	}
+
+	// No note. Treat as successful but build ID empty.
+	return "", nil
+}
+
+// The Go build ID is stored at the beginning of the Mach-O __text segment.
+// The caller has already opened filename, to get f, and read a few kB out, in data.
+// Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount
+// of other junk placed in the file ahead of the main text.
+func readMacho(name string, f *os.File, data []byte) (buildid string, err error) {
+	// If the data we want has already been read, don't worry about Mach-O parsing.
+	// This is both an optimization and a hedge against the Mach-O parsing failing
+	// in the future due to, for example, the name of the __text section changing.
+	if b, err := readRaw(name, data); b != "" && err == nil {
+		return b, err
+	}
+
+	mf, err := macho.NewFile(f)
+	if err != nil {
+		return "", &os.PathError{Path: name, Op: "parse", Err: err}
+	}
+
+	sect := mf.Section("__text")
+	if sect == nil {
+		// Every binary has a __text section. Something is wrong.
+		return "", &os.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")}
+	}
+
+	// It should be in the first few bytes, but read a lot just in case,
+	// especially given our past problems on OS X with the build ID moving.
+	// There shouldn't be much difference between reading 4kB and 32kB:
+	// the hard part is getting to the data, not transferring it.
+	n := sect.Size
+	if n > uint64(readSize) {
+		n = uint64(readSize)
+	}
+	buf := make([]byte, n)
+	if _, err := f.ReadAt(buf, int64(sect.Offset)); err != nil {
+		return "", err
+	}
+
+	return readRaw(name, buf)
+}
diff --git a/src/cmd/internal/buildid/rewrite.go b/src/cmd/internal/buildid/rewrite.go
new file mode 100644
index 0000000..5be5455
--- /dev/null
+++ b/src/cmd/internal/buildid/rewrite.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"fmt"
+	"io"
+)
+
+// FindAndHash reads all of r and returns the offsets of occurrences of id.
+// While reading, findAndHash also computes and returns
+// a hash of the content of r, but with occurrences of id replaced by zeros.
+// FindAndHash reads bufSize bytes from r at a time.
+// If bufSize == 0, FindAndHash uses a reasonable default.
+func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32]byte, err error) {
+	if bufSize == 0 {
+		bufSize = 31 * 1024 // bufSize+little will likely fit in 32 kB
+	}
+	if len(id) > bufSize {
+		return nil, [32]byte{}, fmt.Errorf("buildid.FindAndHash: buffer too small")
+	}
+	zeros := make([]byte, len(id))
+	idBytes := []byte(id)
+
+	// The strategy is to read the file through buf, looking for id,
+	// but we need to worry about what happens if id is broken up
+	// and returned in parts by two different reads.
+	// We allocate a tiny buffer (at least len(id)) and a big buffer (bufSize bytes)
+	// next to each other in memory and then copy the tail of
+	// one read into the tiny buffer before reading new data into the big buffer.
+	// The search for id is over the entire tiny+big buffer.
+	tiny := (len(id) + 127) &^ 127 // round up to 128-aligned
+	buf := make([]byte, tiny+bufSize)
+	h := sha256.New()
+	start := tiny
+	for offset := int64(0); ; {
+		// The file offset maintained by the loop corresponds to &buf[tiny].
+		// buf[start:tiny] is left over from previous iteration.
+		// After reading n bytes into buf[tiny:], we process buf[start:tiny+n].
+		n, err := io.ReadFull(r, buf[tiny:])
+		if err != io.ErrUnexpectedEOF && err != io.EOF && err != nil {
+			return nil, [32]byte{}, err
+		}
+
+		// Process any matches.
+		for {
+			i := bytes.Index(buf[start:tiny+n], idBytes)
+			if i < 0 {
+				break
+			}
+			matches = append(matches, offset+int64(start+i-tiny))
+			h.Write(buf[start : start+i])
+			h.Write(zeros)
+			start += i + len(id)
+		}
+		if n < bufSize {
+			// Did not fill buffer, must be at end of file.
+			h.Write(buf[start : tiny+n])
+			break
+		}
+
+		// Process all but final tiny bytes of buf (bufSize = len(buf)-tiny).
+		// Note that start > len(buf)-tiny is possible, if the search above
+		// found an id ending in the final tiny fringe. That's OK.
+		if start < len(buf)-tiny {
+			h.Write(buf[start : len(buf)-tiny])
+			start = len(buf) - tiny
+		}
+
+		// Slide ending tiny-sized fringe to beginning of buffer.
+		copy(buf[0:], buf[bufSize:])
+		start -= bufSize
+		offset += int64(bufSize)
+	}
+	h.Sum(hash[:0])
+	return matches, hash, nil
+}
+
+func Rewrite(w io.WriterAt, pos []int64, id string) error {
+	b := []byte(id)
+	for _, p := range pos {
+		if _, err := w.WriteAt(b, p); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/src/cmd/internal/buildid/testdata/a.elf b/src/cmd/internal/buildid/testdata/a.elf
new file mode 100755
index 0000000..f631289
--- /dev/null
+++ b/src/cmd/internal/buildid/testdata/a.elf
Binary files differ
diff --git a/src/cmd/internal/buildid/testdata/a.macho b/src/cmd/internal/buildid/testdata/a.macho
new file mode 100755
index 0000000..fbbd57c
--- /dev/null
+++ b/src/cmd/internal/buildid/testdata/a.macho
Binary files differ
diff --git a/src/cmd/internal/buildid/testdata/a.pe b/src/cmd/internal/buildid/testdata/a.pe
new file mode 100755
index 0000000..9120272
--- /dev/null
+++ b/src/cmd/internal/buildid/testdata/a.pe
Binary files differ
diff --git a/src/cmd/internal/buildid/testdata/p.a b/src/cmd/internal/buildid/testdata/p.a
new file mode 100644
index 0000000..dcc3e76
--- /dev/null
+++ b/src/cmd/internal/buildid/testdata/p.a
Binary files differ
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index a617c38..0d6b197 100644
--- a/src/cmd/internal/dwarf/dwarf.go
+++ b/src/cmd/internal/dwarf/dwarf.go
@@ -10,26 +10,73 @@
 import (
 	"errors"
 	"fmt"
+	"sort"
+	"strings"
 )
 
 // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
 const InfoPrefix = "go.info."
 
+// RangePrefix is the prefix for all the symbols containing DWARF location lists.
+const LocPrefix = "go.loc."
+
 // RangePrefix is the prefix for all the symbols containing DWARF range lists.
 const RangePrefix = "go.range."
 
+// ConstInfoPrefix is the prefix for all symbols containing DWARF info
+// entries that contain constants.
+const ConstInfoPrefix = "go.constinfo."
+
+// CUInfoPrefix is the prefix for symbols containing information to
+// populate the DWARF compilation unit info entries.
+const CUInfoPrefix = "go.cuinfo."
+
+// Used to form the symbol name assigned to the DWARF 'abstract subprogram"
+// info entry for a function
+const AbstractFuncSuffix = "$abstract"
+
+// Controls logging/debugging for selected aspects of DWARF subprogram
+// generation (functions, scopes).
+var logDwarf bool
+
 // Sym represents a symbol.
 type Sym interface {
 	Len() int64
 }
 
+// A Location represents a variable's location at a particular PC range.
+// It becomes a location list entry in the DWARF.
+type Location struct {
+	StartPC, EndPC int64
+	Pieces         []Piece
+}
+
+// A Piece represents the location of a particular part of a variable.
+// It becomes part of a location list entry (a DW_OP_piece) in the DWARF.
+type Piece struct {
+	Length      int64
+	StackOffset int32
+	RegNum      int16
+	Missing     bool
+	OnStack     bool // if true, RegNum is unset.
+}
+
 // A Var represents a local variable or a function parameter.
 type Var struct {
-	Name   string
-	Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM
-	Offset int32
-	Scope  int32
-	Type   Sym
+	Name          string
+	Abbrev        int // Either DW_ABRV_AUTO[_LOCLIST] or DW_ABRV_PARAM[_LOCLIST]
+	IsReturnValue bool
+	IsInlFormal   bool
+	StackOffset   int32
+	LocationList  []Location
+	Scope         int32
+	Type          Sym
+	DeclFile      string
+	DeclLine      uint
+	DeclCol       uint
+	InlIndex      int32 // subtract 1 to form real index into InlTree
+	ChildIndex    int32 // child DIE index in abstract function
+	IsInAbstract  bool  // variable exists in abstract function
 }
 
 // A Scope represents a lexical scope. All variables declared within a
@@ -49,6 +96,27 @@
 	Start, End int64
 }
 
+// This container is used by the PutFunc* variants below when
+// creating the DWARF subprogram DIE(s) for a function.
+type FnState struct {
+	Name       string
+	Importpath string
+	Info       Sym
+	Filesym    Sym
+	Loc        Sym
+	Ranges     Sym
+	Absfn      Sym
+	StartPC    Sym
+	Size       int64
+	External   bool
+	Scopes     []Scope
+	InlCalls   InlCalls
+}
+
+func EnableLogging(doit bool) {
+	logDwarf = doit
+}
+
 // UnifyRanges merges the list of ranges of c into the list of ranges of s
 func (s *Scope) UnifyRanges(c *Scope) {
 	out := make([]Range, 0, len(s.Ranges)+len(c.Ranges))
@@ -84,15 +152,51 @@
 	s.Ranges = out
 }
 
+type InlCalls struct {
+	Calls []InlCall
+}
+
+type InlCall struct {
+	// index into ctx.InlTree describing the call inlined here
+	InlIndex int
+
+	// Symbol of file containing inlined call site (really *obj.LSym).
+	CallFile Sym
+
+	// Line number of inlined call site.
+	CallLine uint32
+
+	// Dwarf abstract subroutine symbol (really *obj.LSym).
+	AbsFunSym Sym
+
+	// Indices of child inlines within Calls array above.
+	Children []int
+
+	// entries in this list are PAUTO's created by the inliner to
+	// capture the promoted formals and locals of the inlined callee.
+	InlVars []*Var
+
+	// PC ranges for this inlined call.
+	Ranges []Range
+
+	// Root call (not a child of some other call).
+	Root bool
+}
+
 // A Context specifies how to add data to a Sym.
 type Context interface {
 	PtrSize() int
 	AddInt(s Sym, size int, i int64)
 	AddBytes(s Sym, b []byte)
 	AddAddress(s Sym, t interface{}, ofs int64)
+	AddCURelativeAddress(s Sym, t interface{}, ofs int64)
 	AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
+	CurrentOffset(s Sym) int64
+	RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
+	RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
 	AddString(s Sym, v string)
-	SymValue(s Sym) int64
+	AddFileRef(s Sym, f interface{})
+	Logf(format string, args ...interface{})
 }
 
 // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
@@ -205,15 +309,28 @@
 )
 
 // Index into the abbrevs table below.
-// Keep in sync with ispubname() and ispubtype() below.
+// Keep in sync with ispubname() and ispubtype() in ld/dwarf.go.
 // ispubtype considers >= NULLTYPE public
 const (
 	DW_ABRV_NULL = iota
 	DW_ABRV_COMPUNIT
 	DW_ABRV_FUNCTION
+	DW_ABRV_FUNCTION_ABSTRACT
+	DW_ABRV_FUNCTION_CONCRETE
+	DW_ABRV_INLINED_SUBROUTINE
+	DW_ABRV_INLINED_SUBROUTINE_RANGES
 	DW_ABRV_VARIABLE
+	DW_ABRV_INT_CONSTANT
 	DW_ABRV_AUTO
+	DW_ABRV_AUTO_LOCLIST
+	DW_ABRV_AUTO_ABSTRACT
+	DW_ABRV_AUTO_CONCRETE
+	DW_ABRV_AUTO_CONCRETE_LOCLIST
 	DW_ABRV_PARAM
+	DW_ABRV_PARAM_LOCLIST
+	DW_ABRV_PARAM_ABSTRACT
+	DW_ABRV_PARAM_CONCRETE
+	DW_ABRV_PARAM_CONCRETE_LOCLIST
 	DW_ABRV_LEXICAL_BLOCK_RANGES
 	DW_ABRV_LEXICAL_BLOCK_SIMPLE
 	DW_ABRV_STRUCTFIELD
@@ -253,9 +370,9 @@
 		[]dwAttrForm{
 			{DW_AT_name, DW_FORM_string},
 			{DW_AT_language, DW_FORM_data1},
-			{DW_AT_low_pc, DW_FORM_addr},
-			{DW_AT_high_pc, DW_FORM_addr},
 			{DW_AT_stmt_list, DW_FORM_sec_offset},
+			{DW_AT_low_pc, DW_FORM_addr},
+			{DW_AT_ranges, DW_FORM_sec_offset},
 			{DW_AT_comp_dir, DW_FORM_string},
 			{DW_AT_producer, DW_FORM_string},
 		},
@@ -270,10 +387,59 @@
 			{DW_AT_low_pc, DW_FORM_addr},
 			{DW_AT_high_pc, DW_FORM_addr},
 			{DW_AT_frame_base, DW_FORM_block1},
+			{DW_AT_decl_file, DW_FORM_data4},
 			{DW_AT_external, DW_FORM_flag},
 		},
 	},
 
+	/* FUNCTION_ABSTRACT */
+	{
+		DW_TAG_subprogram,
+		DW_CHILDREN_yes,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_inline, DW_FORM_data1},
+			{DW_AT_external, DW_FORM_flag},
+		},
+	},
+
+	/* FUNCTION_CONCRETE */
+	{
+		DW_TAG_subprogram,
+		DW_CHILDREN_yes,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_low_pc, DW_FORM_addr},
+			{DW_AT_high_pc, DW_FORM_addr},
+			{DW_AT_frame_base, DW_FORM_block1},
+		},
+	},
+
+	/* INLINED_SUBROUTINE */
+	{
+		DW_TAG_inlined_subroutine,
+		DW_CHILDREN_yes,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_low_pc, DW_FORM_addr},
+			{DW_AT_high_pc, DW_FORM_addr},
+			{DW_AT_call_file, DW_FORM_data4},
+			{DW_AT_call_line, DW_FORM_udata},
+		},
+	},
+
+	/* INLINED_SUBROUTINE_RANGES */
+	{
+		DW_TAG_inlined_subroutine,
+		DW_CHILDREN_yes,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_ranges, DW_FORM_sec_offset},
+			{DW_AT_call_file, DW_FORM_data4},
+			{DW_AT_call_line, DW_FORM_udata},
+		},
+	},
+
 	/* VARIABLE */
 	{
 		DW_TAG_variable,
@@ -286,14 +452,69 @@
 		},
 	},
 
+	/* INT CONSTANT */
+	{
+		DW_TAG_constant,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_type, DW_FORM_ref_addr},
+			{DW_AT_const_value, DW_FORM_sdata},
+		},
+	},
+
 	/* AUTO */
 	{
 		DW_TAG_variable,
 		DW_CHILDREN_no,
 		[]dwAttrForm{
 			{DW_AT_name, DW_FORM_string},
-			{DW_AT_location, DW_FORM_block1},
+			{DW_AT_decl_line, DW_FORM_udata},
 			{DW_AT_type, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_block1},
+		},
+	},
+
+	/* AUTO_LOCLIST */
+	{
+		DW_TAG_variable,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_decl_line, DW_FORM_udata},
+			{DW_AT_type, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_sec_offset},
+		},
+	},
+
+	/* AUTO_ABSTRACT */
+	{
+		DW_TAG_variable,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_decl_line, DW_FORM_udata},
+			{DW_AT_type, DW_FORM_ref_addr},
+		},
+	},
+
+	/* AUTO_CONCRETE */
+	{
+		DW_TAG_variable,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_block1},
+		},
+	},
+
+	/* AUTO_CONCRETE_LOCLIST */
+	{
+		DW_TAG_variable,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_sec_offset},
 		},
 	},
 
@@ -303,10 +524,57 @@
 		DW_CHILDREN_no,
 		[]dwAttrForm{
 			{DW_AT_name, DW_FORM_string},
+			{DW_AT_variable_parameter, DW_FORM_flag},
+			{DW_AT_decl_line, DW_FORM_udata},
+			{DW_AT_type, DW_FORM_ref_addr},
 			{DW_AT_location, DW_FORM_block1},
+		},
+	},
+
+	/* PARAM_LOCLIST */
+	{
+		DW_TAG_formal_parameter,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_variable_parameter, DW_FORM_flag},
+			{DW_AT_decl_line, DW_FORM_udata},
+			{DW_AT_type, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_sec_offset},
+		},
+	},
+
+	/* PARAM_ABSTRACT */
+	{
+		DW_TAG_formal_parameter,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_name, DW_FORM_string},
+			{DW_AT_variable_parameter, DW_FORM_flag},
 			{DW_AT_type, DW_FORM_ref_addr},
 		},
 	},
+
+	/* PARAM_CONCRETE */
+	{
+		DW_TAG_formal_parameter,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_block1},
+		},
+	},
+
+	/* PARAM_CONCRETE_LOCLIST */
+	{
+		DW_TAG_formal_parameter,
+		DW_CHILDREN_no,
+		[]dwAttrForm{
+			{DW_AT_abstract_origin, DW_FORM_ref_addr},
+			{DW_AT_location, DW_FORM_sec_offset},
+		},
+	},
+
 	/* LEXICAL_BLOCK_RANGES */
 	{
 		DW_TAG_lexical_block,
@@ -332,7 +600,7 @@
 		DW_CHILDREN_no,
 		[]dwAttrForm{
 			{DW_AT_name, DW_FORM_string},
-			{DW_AT_data_member_location, DW_FORM_block1},
+			{DW_AT_data_member_location, DW_FORM_udata},
 			{DW_AT_type, DW_FORM_ref_addr},
 			{DW_AT_go_embedded_field, DW_FORM_flag},
 		},
@@ -421,6 +689,7 @@
 		DW_CHILDREN_yes,
 		[]dwAttrForm{
 			{DW_AT_name, DW_FORM_string},
+			{DW_AT_byte_size, DW_FORM_udata},
 			// {DW_AT_type,	DW_FORM_ref_addr},
 			{DW_AT_go_kind, DW_FORM_data1},
 		},
@@ -682,33 +951,365 @@
 	return abbrevs[die.Abbrev].children != 0
 }
 
-// PutFunc writes a DIE for a function to s.
-// It also writes child DIEs for each variable in vars.
-func PutFunc(ctxt Context, s, ranges Sym, name string, external bool, startPC Sym, size int64, scopes []Scope) error {
-	Uleb128put(ctxt, s, DW_ABRV_FUNCTION)
-	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
-	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC)
-	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size, startPC)
-	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
-	var ev int64
-	if external {
-		ev = 1
-	}
-	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
-	if len(scopes) > 0 {
-		var encbuf [20]byte
-		if putscope(ctxt, s, ranges, startPC, 0, scopes, encbuf[:0]) < int32(len(scopes)) {
-			return errors.New("multiple toplevel scopes")
+// PutIntConst writes a DIE for an integer constant
+func PutIntConst(ctxt Context, info, typ Sym, name string, val int64) {
+	Uleb128put(ctxt, info, DW_ABRV_INT_CONSTANT)
+	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
+	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
+	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_sdata, DW_CLS_CONSTANT, val, nil)
+}
+
+// PutRanges writes a range table to sym. All addresses in ranges are
+// relative to some base address. If base is not nil, then they're
+// relative to the start of base. If base is nil, then the caller must
+// arrange a base address some other way (such as a DW_AT_low_pc
+// attribute).
+func PutRanges(ctxt Context, sym Sym, base Sym, ranges []Range) {
+	ps := ctxt.PtrSize()
+	// Write ranges.
+	// We do not emit base address entries here, even though they would reduce
+	// the number of relocations, because dsymutil (which is used on macOS when
+	// linking externally) does not support them.
+	for _, r := range ranges {
+		if base == nil {
+			ctxt.AddInt(sym, ps, r.Start)
+			ctxt.AddInt(sym, ps, r.End)
+		} else {
+			ctxt.AddCURelativeAddress(sym, base, r.Start)
+			ctxt.AddCURelativeAddress(sym, base, r.End)
 		}
 	}
+	// Write trailer.
+	ctxt.AddInt(sym, ps, 0)
+	ctxt.AddInt(sym, ps, 0)
+}
 
-	Uleb128put(ctxt, s, 0)
+// Return TRUE if the inlined call in the specified slot is empty,
+// meaning it has a zero-length range (no instructions), and all
+// of its children are empty.
+func isEmptyInlinedCall(slot int, calls *InlCalls) bool {
+	ic := &calls.Calls[slot]
+	if ic.InlIndex == -2 {
+		return true
+	}
+	live := false
+	for _, k := range ic.Children {
+		if !isEmptyInlinedCall(k, calls) {
+			live = true
+		}
+	}
+	if len(ic.Ranges) > 0 {
+		live = true
+	}
+	if !live {
+		ic.InlIndex = -2
+	}
+	return !live
+}
+
+// Slot -1:    return top-level inlines
+// Slot >= 0:  return children of that slot
+func inlChildren(slot int, calls *InlCalls) []int {
+	var kids []int
+	if slot != -1 {
+		for _, k := range calls.Calls[slot].Children {
+			if !isEmptyInlinedCall(k, calls) {
+				kids = append(kids, k)
+			}
+		}
+	} else {
+		for k := 0; k < len(calls.Calls); k += 1 {
+			if calls.Calls[k].Root && !isEmptyInlinedCall(k, calls) {
+				kids = append(kids, k)
+			}
+		}
+	}
+	return kids
+}
+
+func inlinedVarTable(inlcalls *InlCalls) map[*Var]bool {
+	vars := make(map[*Var]bool)
+	for _, ic := range inlcalls.Calls {
+		for _, v := range ic.InlVars {
+			vars[v] = true
+		}
+	}
+	return vars
+}
+
+// The s.Scopes slice contains variables were originally part of the
+// function being emitted, as well as variables that were imported
+// from various callee functions during the inlining process. This
+// function prunes out any variables from the latter category (since
+// they will be emitted as part of DWARF inlined_subroutine DIEs) and
+// then generates scopes for vars in the former category.
+func putPrunedScopes(ctxt Context, s *FnState, fnabbrev int) error {
+	if len(s.Scopes) == 0 {
+		return nil
+	}
+	scopes := make([]Scope, len(s.Scopes), len(s.Scopes))
+	pvars := inlinedVarTable(&s.InlCalls)
+	for k, s := range s.Scopes {
+		var pruned Scope = Scope{Parent: s.Parent, Ranges: s.Ranges}
+		for i := 0; i < len(s.Vars); i++ {
+			_, found := pvars[s.Vars[i]]
+			if !found {
+				pruned.Vars = append(pruned.Vars, s.Vars[i])
+			}
+		}
+		sort.Sort(byChildIndex(pruned.Vars))
+		scopes[k] = pruned
+	}
+	var encbuf [20]byte
+	if putscope(ctxt, s, scopes, 0, fnabbrev, encbuf[:0]) < int32(len(scopes)) {
+		return errors.New("multiple toplevel scopes")
+	}
 	return nil
 }
 
-func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes []Scope, encbuf []byte) int32 {
+// Emit DWARF attributes and child DIEs for an 'abstract' subprogram.
+// The abstract subprogram DIE for a function contains its
+// location-independent attributes (name, type, etc). Other instances
+// of the function (any inlined copy of it, or the single out-of-line
+// 'concrete' instance) will contain a pointer back to this abstract
+// DIE (as a space-saving measure, so that name/type etc doesn't have
+// to be repeated for each inlined copy).
+func PutAbstractFunc(ctxt Context, s *FnState) error {
+
+	if logDwarf {
+		ctxt.Logf("PutAbstractFunc(%v)\n", s.Absfn)
+	}
+
+	abbrev := DW_ABRV_FUNCTION_ABSTRACT
+	Uleb128put(ctxt, s.Absfn, int64(abbrev))
+
+	fullname := s.Name
+	if strings.HasPrefix(s.Name, "\"\".") {
+		// Generate a fully qualified name for the function in the
+		// abstract case. This is so as to avoid the need for the
+		// linker to process the DIE with patchDWARFName(); we can't
+		// allow the name attribute of an abstract subprogram DIE to
+		// be rewritten, since it would change the offsets of the
+		// child DIEs (which we're relying on in order for abstract
+		// origin references to work).
+		fullname = s.Importpath + "." + s.Name[3:]
+	}
+	putattr(ctxt, s.Absfn, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(fullname)), fullname)
+
+	// DW_AT_inlined value
+	putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
+
+	var ev int64
+	if s.External {
+		ev = 1
+	}
+	putattr(ctxt, s.Absfn, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
+
+	// Child variables (may be empty)
+	var flattened []*Var
+
+	// This slice will hold the offset in bytes for each child var DIE
+	// with respect to the start of the parent subprogram DIE.
+	var offsets []int32
+
+	// Scopes/vars
+	if len(s.Scopes) > 0 {
+		// For abstract subprogram DIEs we want to flatten out scope info:
+		// lexical scope DIEs contain range and/or hi/lo PC attributes,
+		// which we explicitly don't want for the abstract subprogram DIE.
+		pvars := inlinedVarTable(&s.InlCalls)
+		for _, scope := range s.Scopes {
+			for i := 0; i < len(scope.Vars); i++ {
+				_, found := pvars[scope.Vars[i]]
+				if found || !scope.Vars[i].IsInAbstract {
+					continue
+				}
+				flattened = append(flattened, scope.Vars[i])
+			}
+		}
+		if len(flattened) > 0 {
+			sort.Sort(byChildIndex(flattened))
+
+			if logDwarf {
+				ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
+				for i, v := range flattened {
+					ctxt.Logf(" %d:%s", i, v.Name)
+				}
+				ctxt.Logf("\n")
+			}
+
+			// This slice will hold the offset in bytes for each child
+			// variable DIE with respect to the start of the parent
+			// subprogram DIE.
+			for _, v := range flattened {
+				offsets = append(offsets, int32(ctxt.CurrentOffset(s.Absfn)))
+				putAbstractVar(ctxt, s.Absfn, v)
+			}
+		}
+	}
+	ctxt.RecordChildDieOffsets(s.Absfn, flattened, offsets)
+
+	Uleb128put(ctxt, s.Absfn, 0)
+	return nil
+}
+
+// Emit DWARF attributes and child DIEs for an inlined subroutine. The
+// first attribute of an inlined subroutine DIE is a reference back to
+// its corresponding 'abstract' DIE (containing location-independent
+// attributes such as name, type, etc). Inlined subroutine DIEs can
+// have other inlined subroutine DIEs as children.
+func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error {
+	ic := s.InlCalls.Calls[callIdx]
+	callee := ic.AbsFunSym
+
+	abbrev := DW_ABRV_INLINED_SUBROUTINE_RANGES
+	if len(ic.Ranges) == 1 {
+		abbrev = DW_ABRV_INLINED_SUBROUTINE
+	}
+	Uleb128put(ctxt, s.Info, int64(abbrev))
+
+	if logDwarf {
+		ctxt.Logf("PutInlinedFunc(caller=%v,callee=%v,abbrev=%d)\n", callersym, callee, abbrev)
+	}
+
+	// Abstract origin.
+	putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, callee)
+
+	if abbrev == DW_ABRV_INLINED_SUBROUTINE_RANGES {
+		putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, s.Ranges.Len(), s.Ranges)
+		PutRanges(ctxt, s.Ranges, s.StartPC, ic.Ranges)
+	} else {
+		st := ic.Ranges[0].Start
+		en := ic.Ranges[0].End
+		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, st, s.StartPC)
+		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, en, s.StartPC)
+	}
+
+	// Emit call file, line attrs.
+	ctxt.AddFileRef(s.Info, ic.CallFile)
+	putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(ic.CallLine), nil)
+
+	// Variables associated with this inlined routine instance.
+	vars := ic.InlVars
+	sort.Sort(byChildIndex(vars))
+	inlIndex := ic.InlIndex
+	var encbuf [20]byte
+	for _, v := range vars {
+		if !v.IsInAbstract {
+			continue
+		}
+		putvar(ctxt, s, v, callee, abbrev, inlIndex, encbuf[:0])
+	}
+
+	// Children of this inline.
+	for _, sib := range inlChildren(callIdx, &s.InlCalls) {
+		absfn := s.InlCalls.Calls[sib].AbsFunSym
+		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		if err != nil {
+			return err
+		}
+	}
+
+	Uleb128put(ctxt, s.Info, 0)
+	return nil
+}
+
+// Emit DWARF attributes and child DIEs for a 'concrete' subprogram,
+// meaning the out-of-line copy of a function that was inlined at some
+// point during the compilation of its containing package. The first
+// attribute for a concrete DIE is a reference to the 'abstract' DIE
+// for the function (which holds location-independent attributes such
+// as name, type), then the remainder of the attributes are specific
+// to this instance (location, frame base, etc).
+func PutConcreteFunc(ctxt Context, s *FnState) error {
+	if logDwarf {
+		ctxt.Logf("PutConcreteFunc(%v)\n", s.Info)
+	}
+	abbrev := DW_ABRV_FUNCTION_CONCRETE
+	Uleb128put(ctxt, s.Info, int64(abbrev))
+
+	// Abstract origin.
+	putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, s.Absfn)
+
+	// Start/end PC.
+	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
+	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
+
+	// cfa / frame base
+	putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
+
+	// Scopes
+	if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
+		return err
+	}
+
+	// Inlined subroutines.
+	for _, sib := range inlChildren(-1, &s.InlCalls) {
+		absfn := s.InlCalls.Calls[sib].AbsFunSym
+		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		if err != nil {
+			return err
+		}
+	}
+
+	Uleb128put(ctxt, s.Info, 0)
+	return nil
+}
+
+// Emit DWARF attributes and child DIEs for a subprogram. Here
+// 'default' implies that the function in question was not inlined
+// when its containing package was compiled (hence there is no need to
+// emit an abstract version for it to use as a base for inlined
+// routine records).
+func PutDefaultFunc(ctxt Context, s *FnState) error {
+	if logDwarf {
+		ctxt.Logf("PutDefaultFunc(%v)\n", s.Info)
+	}
+	abbrev := DW_ABRV_FUNCTION
+	Uleb128put(ctxt, s.Info, int64(abbrev))
+
+	putattr(ctxt, s.Info, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(s.Name)), s.Name)
+	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
+	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
+	putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
+	ctxt.AddFileRef(s.Info, s.Filesym)
+
+	var ev int64
+	if s.External {
+		ev = 1
+	}
+	putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
+
+	// Scopes
+	if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
+		return err
+	}
+
+	// Inlined subroutines.
+	for _, sib := range inlChildren(-1, &s.InlCalls) {
+		absfn := s.InlCalls.Calls[sib].AbsFunSym
+		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		if err != nil {
+			return err
+		}
+	}
+
+	Uleb128put(ctxt, s.Info, 0)
+	return nil
+}
+
+func putscope(ctxt Context, s *FnState, scopes []Scope, curscope int32, fnabbrev int, encbuf []byte) int32 {
+
+	if logDwarf {
+		ctxt.Logf("putscope(%v,%d): vars:", s.Info, curscope)
+		for i, v := range scopes[curscope].Vars {
+			ctxt.Logf(" %d:%d:%s", i, v.ChildIndex, v.Name)
+		}
+		ctxt.Logf("\n")
+	}
+
 	for _, v := range scopes[curscope].Vars {
-		putvar(ctxt, s, v, encbuf)
+		putvar(ctxt, s, v, s.Absfn, fnabbrev, -1, encbuf)
 	}
 	this := curscope
 	curscope++
@@ -719,49 +1320,224 @@
 		}
 
 		if len(scope.Ranges) == 1 {
-			Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
-			putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, startPC)
-			putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, startPC)
+			Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
+			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, s.StartPC)
+			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, s.StartPC)
 		} else {
-			Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES)
-			putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, ranges.Len(), ranges)
+			Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES)
+			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, s.Ranges.Len(), s.Ranges)
 
-			ctxt.AddAddress(ranges, nil, -1)
-			ctxt.AddAddress(ranges, startPC, 0)
-			for _, r := range scope.Ranges {
-				ctxt.AddAddress(ranges, nil, r.Start)
-				ctxt.AddAddress(ranges, nil, r.End)
-			}
-			ctxt.AddAddress(ranges, nil, 0)
-			ctxt.AddAddress(ranges, nil, 0)
+			PutRanges(ctxt, s.Ranges, s.StartPC, scope.Ranges)
 		}
 
-		curscope = putscope(ctxt, s, ranges, startPC, curscope, scopes, encbuf)
-
-		Uleb128put(ctxt, s, 0)
+		curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
+		Uleb128put(ctxt, s.Info, 0)
 	}
 	return curscope
 }
 
-func putvar(ctxt Context, s Sym, v *Var, encbuf []byte) {
-	n := v.Name
-
-	Uleb128put(ctxt, s, int64(v.Abbrev))
-	putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
-	loc := append(encbuf[:0], DW_OP_call_frame_cfa)
-	if v.Offset != 0 {
-		loc = append(loc, DW_OP_consts)
-		loc = AppendSleb128(loc, int64(v.Offset))
-		loc = append(loc, DW_OP_plus)
+// Given a default var abbrev code, select corresponding concrete code.
+func concreteVarAbbrev(varAbbrev int) int {
+	switch varAbbrev {
+	case DW_ABRV_AUTO:
+		return DW_ABRV_AUTO_CONCRETE
+	case DW_ABRV_PARAM:
+		return DW_ABRV_PARAM_CONCRETE
+	case DW_ABRV_AUTO_LOCLIST:
+		return DW_ABRV_AUTO_CONCRETE_LOCLIST
+	case DW_ABRV_PARAM_LOCLIST:
+		return DW_ABRV_PARAM_CONCRETE_LOCLIST
+	default:
+		panic("should never happen")
 	}
-	putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
-	putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
+}
+
+// Pick the correct abbrev code for variable or parameter DIE.
+func determineVarAbbrev(v *Var, fnabbrev int) (int, bool, bool) {
+	abbrev := v.Abbrev
+
+	// If the variable was entirely optimized out, don't emit a location list;
+	// convert to an inline abbreviation and emit an empty location.
+	missing := false
+	switch {
+	case abbrev == DW_ABRV_AUTO_LOCLIST && len(v.LocationList) == 0:
+		missing = true
+		abbrev = DW_ABRV_AUTO
+	case abbrev == DW_ABRV_PARAM_LOCLIST && len(v.LocationList) == 0:
+		missing = true
+		abbrev = DW_ABRV_PARAM
+	}
+
+	// Determine whether to use a concrete variable or regular variable DIE.
+	concrete := true
+	switch fnabbrev {
+	case DW_ABRV_FUNCTION:
+		concrete = false
+		break
+	case DW_ABRV_FUNCTION_CONCRETE:
+		// If we're emitting a concrete subprogram DIE and the variable
+		// in question is not part of the corresponding abstract function DIE,
+		// then use the default (non-concrete) abbrev for this param.
+		if !v.IsInAbstract {
+			concrete = false
+		}
+	case DW_ABRV_INLINED_SUBROUTINE, DW_ABRV_INLINED_SUBROUTINE_RANGES:
+	default:
+		panic("should never happen")
+	}
+
+	// Select proper abbrev based on concrete/non-concrete
+	if concrete {
+		abbrev = concreteVarAbbrev(abbrev)
+	}
+
+	return abbrev, missing, concrete
+}
+
+func abbrevUsesLoclist(abbrev int) bool {
+	switch abbrev {
+	case DW_ABRV_AUTO_LOCLIST, DW_ABRV_AUTO_CONCRETE_LOCLIST,
+		DW_ABRV_PARAM_LOCLIST, DW_ABRV_PARAM_CONCRETE_LOCLIST:
+		return true
+	default:
+		return false
+	}
+}
+
+// Emit DWARF attributes for a variable belonging to an 'abstract' subprogram.
+func putAbstractVar(ctxt Context, info Sym, v *Var) {
+	// Remap abbrev
+	abbrev := v.Abbrev
+	switch abbrev {
+	case DW_ABRV_AUTO, DW_ABRV_AUTO_LOCLIST:
+		abbrev = DW_ABRV_AUTO_ABSTRACT
+	case DW_ABRV_PARAM, DW_ABRV_PARAM_LOCLIST:
+		abbrev = DW_ABRV_PARAM_ABSTRACT
+	}
+
+	Uleb128put(ctxt, info, int64(abbrev))
+	putattr(ctxt, info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(v.Name)), v.Name)
+
+	// Isreturn attribute if this is a param
+	if abbrev == DW_ABRV_PARAM_ABSTRACT {
+		var isReturn int64
+		if v.IsReturnValue {
+			isReturn = 1
+		}
+		putattr(ctxt, info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
+	}
+
+	// Line
+	if abbrev != DW_ABRV_PARAM_ABSTRACT {
+		// See issue 23374 for more on why decl line is skipped for abs params.
+		putattr(ctxt, info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
+	}
+
+	// Type
+	putattr(ctxt, info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
+
+	// Var has no children => no terminator
+}
+
+func putvar(ctxt Context, s *FnState, v *Var, absfn Sym, fnabbrev, inlIndex int, encbuf []byte) {
+	// Remap abbrev according to parent DIE abbrev
+	abbrev, missing, concrete := determineVarAbbrev(v, fnabbrev)
+
+	Uleb128put(ctxt, s.Info, int64(abbrev))
+
+	// Abstract origin for concrete / inlined case
+	if concrete {
+		// Here we are making a reference to a child DIE of an abstract
+		// function subprogram DIE. The child DIE has no LSym, so instead
+		// after the call to 'putattr' below we make a call to register
+		// the child DIE reference.
+		putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, absfn)
+		ctxt.RecordDclReference(s.Info, absfn, int(v.ChildIndex), inlIndex)
+	} else {
+		// Var name, line for abstract and default cases
+		n := v.Name
+		putattr(ctxt, s.Info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
+		if abbrev == DW_ABRV_PARAM || abbrev == DW_ABRV_PARAM_LOCLIST || abbrev == DW_ABRV_PARAM_ABSTRACT {
+			var isReturn int64
+			if v.IsReturnValue {
+				isReturn = 1
+			}
+			putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
+		}
+		putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
+		putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
+	}
+
+	if abbrevUsesLoclist(abbrev) {
+		putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, int64(s.Loc.Len()), s.Loc)
+		addLocList(ctxt, s.Loc, s.StartPC, v, encbuf)
+	} else {
+		loc := encbuf[:0]
+		switch {
+		case missing:
+			break // no location
+		case v.StackOffset == 0:
+			loc = append(loc, DW_OP_call_frame_cfa)
+		default:
+			loc = append(loc, DW_OP_fbreg)
+			loc = AppendSleb128(loc, int64(v.StackOffset))
+		}
+		putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
+	}
+
+	// Var has no children => no terminator
+}
+
+func addLocList(ctxt Context, listSym, startPC Sym, v *Var, encbuf []byte) {
+	// Base address entry: max ptr followed by the base address.
+	ctxt.AddInt(listSym, ctxt.PtrSize(), ^0)
+	ctxt.AddAddress(listSym, startPC, 0)
+	for _, entry := range v.LocationList {
+		ctxt.AddInt(listSym, ctxt.PtrSize(), entry.StartPC)
+		ctxt.AddInt(listSym, ctxt.PtrSize(), entry.EndPC)
+		locBuf := encbuf[:0]
+		for _, piece := range entry.Pieces {
+			if !piece.Missing {
+				if piece.OnStack {
+					if piece.StackOffset == 0 {
+						locBuf = append(locBuf, DW_OP_call_frame_cfa)
+					} else {
+						locBuf = append(locBuf, DW_OP_fbreg)
+						locBuf = AppendSleb128(locBuf, int64(piece.StackOffset))
+					}
+				} else {
+					if piece.RegNum < 32 {
+						locBuf = append(locBuf, DW_OP_reg0+byte(piece.RegNum))
+					} else {
+						locBuf = append(locBuf, DW_OP_regx)
+						locBuf = AppendUleb128(locBuf, uint64(piece.RegNum))
+					}
+				}
+			}
+			if len(entry.Pieces) > 1 {
+				locBuf = append(locBuf, DW_OP_piece)
+				locBuf = AppendUleb128(locBuf, uint64(piece.Length))
+			}
+		}
+		ctxt.AddInt(listSym, 2, int64(len(locBuf)))
+		ctxt.AddBytes(listSym, locBuf)
+	}
+	// End list
+	ctxt.AddInt(listSym, ctxt.PtrSize(), 0)
+	ctxt.AddInt(listSym, ctxt.PtrSize(), 0)
 }
 
 // VarsByOffset attaches the methods of sort.Interface to []*Var,
-// sorting in increasing Offset.
+// sorting in increasing StackOffset.
 type VarsByOffset []*Var
 
 func (s VarsByOffset) Len() int           { return len(s) }
-func (s VarsByOffset) Less(i, j int) bool { return s[i].Offset < s[j].Offset }
+func (s VarsByOffset) Less(i, j int) bool { return s[i].StackOffset < s[j].StackOffset }
 func (s VarsByOffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// byChildIndex implements sort.Interface for []*dwarf.Var by child index.
+type byChildIndex []*Var
+
+func (s byChildIndex) Len() int           { return len(s) }
+func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
+func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
diff --git a/src/cmd/internal/edit/edit.go b/src/cmd/internal/edit/edit.go
new file mode 100644
index 0000000..2d470f4
--- /dev/null
+++ b/src/cmd/internal/edit/edit.go
@@ -0,0 +1,93 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package edit implements buffered position-based editing of byte slices.
+package edit
+
+import (
+	"fmt"
+	"sort"
+)
+
+// A Buffer is a queue of edits to apply to a given byte slice.
+type Buffer struct {
+	old []byte
+	q   edits
+}
+
+// An edit records a single text modification: change the bytes in [start,end) to new.
+type edit struct {
+	start int
+	end   int
+	new   string
+}
+
+// An edits is a list of edits that is sortable by start offset, breaking ties by end offset.
+type edits []edit
+
+func (x edits) Len() int      { return len(x) }
+func (x edits) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x edits) Less(i, j int) bool {
+	if x[i].start != x[j].start {
+		return x[i].start < x[j].start
+	}
+	return x[i].end < x[j].end
+}
+
+// NewBuffer returns a new buffer to accumulate changes to an initial data slice.
+// The returned buffer maintains a reference to the data, so the caller must ensure
+// the data is not modified until after the Buffer is done being used.
+func NewBuffer(data []byte) *Buffer {
+	return &Buffer{old: data}
+}
+
+func (b *Buffer) Insert(pos int, new string) {
+	if pos < 0 || pos > len(b.old) {
+		panic("invalid edit position")
+	}
+	b.q = append(b.q, edit{pos, pos, new})
+}
+
+func (b *Buffer) Delete(start, end int) {
+	if end < start || start < 0 || end > len(b.old) {
+		panic("invalid edit position")
+	}
+	b.q = append(b.q, edit{start, end, ""})
+}
+
+func (b *Buffer) Replace(start, end int, new string) {
+	if end < start || start < 0 || end > len(b.old) {
+		panic("invalid edit position")
+	}
+	b.q = append(b.q, edit{start, end, new})
+}
+
+// Bytes returns a new byte slice containing the original data
+// with the queued edits applied.
+func (b *Buffer) Bytes() []byte {
+	// Sort edits by starting position and then by ending position.
+	// Breaking ties by ending position allows insertions at point x
+	// to be applied before a replacement of the text at [x, y).
+	sort.Stable(b.q)
+
+	var new []byte
+	offset := 0
+	for i, e := range b.q {
+		if e.start < offset {
+			e0 := b.q[i-1]
+			panic(fmt.Sprintf("overlapping edits: [%d,%d)->%q, [%d,%d)->%q", e0.start, e0.end, e0.new, e.start, e.end, e.new))
+		}
+		new = append(new, b.old[offset:e.start]...)
+		offset = e.end
+		new = append(new, e.new...)
+	}
+	new = append(new, b.old[offset:]...)
+	return new
+}
+
+// String returns a string containing the original data
+// with the queued edits applied.
+func (b *Buffer) String() string {
+	return string(b.Bytes())
+}
diff --git a/src/cmd/internal/edit/edit_test.go b/src/cmd/internal/edit/edit_test.go
new file mode 100644
index 0000000..0e0c564
--- /dev/null
+++ b/src/cmd/internal/edit/edit_test.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edit
+
+import "testing"
+
+func TestEdit(t *testing.T) {
+	b := NewBuffer([]byte("0123456789"))
+	b.Insert(8, ",7½,")
+	b.Replace(9, 10, "the-end")
+	b.Insert(10, "!")
+	b.Insert(4, "3.14,")
+	b.Insert(4, "π,")
+	b.Insert(4, "3.15,")
+	b.Replace(3, 4, "three,")
+	want := "012three,3.14,π,3.15,4567,7½,8the-end!"
+
+	s := b.String()
+	if s != want {
+		t.Errorf("b.String() = %q, want %q", s, want)
+	}
+	sb := b.Bytes()
+	if string(sb) != want {
+		t.Errorf("b.Bytes() = %q, want %q", sb, want)
+	}
+}
diff --git a/src/cmd/internal/goobj/goobj_test.go b/src/cmd/internal/goobj/goobj_test.go
new file mode 100644
index 0000000..3b41589
--- /dev/null
+++ b/src/cmd/internal/goobj/goobj_test.go
@@ -0,0 +1,318 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goobj
+
+import (
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"fmt"
+	"internal/testenv"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+var (
+	buildDir   string
+	go1obj     string
+	go2obj     string
+	goarchive  string
+	cgoarchive string
+)
+
+func TestMain(m *testing.M) {
+	if !testenv.HasGoBuild() {
+		return
+	}
+
+	if err := buildGoobj(); err != nil {
+		fmt.Println(err)
+		os.RemoveAll(buildDir)
+		os.Exit(1)
+	}
+
+	exit := m.Run()
+
+	os.RemoveAll(buildDir)
+	os.Exit(exit)
+}
+
+func copyDir(dst, src string) error {
+	err := os.MkdirAll(dst, 0777)
+	if err != nil {
+		return err
+	}
+	fis, err := ioutil.ReadDir(src)
+	if err != nil {
+		return err
+	}
+	for _, fi := range fis {
+		err = copyFile(filepath.Join(dst, fi.Name()), filepath.Join(src, fi.Name()))
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func copyFile(dst, src string) (err error) {
+	var s, d *os.File
+	s, err = os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer s.Close()
+	d, err = os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		e := d.Close()
+		if err == nil {
+			err = e
+		}
+	}()
+	_, err = io.Copy(d, s)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func buildGoobj() error {
+	var err error
+
+	buildDir, err = ioutil.TempDir("", "TestGoobj")
+	if err != nil {
+		return err
+	}
+
+	go1obj = filepath.Join(buildDir, "go1.o")
+	go2obj = filepath.Join(buildDir, "go2.o")
+	goarchive = filepath.Join(buildDir, "go.a")
+
+	gotool, err := testenv.GoTool()
+	if err != nil {
+		return err
+	}
+
+	go1src := filepath.Join("testdata", "go1.go")
+	go2src := filepath.Join("testdata", "go2.go")
+
+	out, err := exec.Command(gotool, "tool", "compile", "-o", go1obj, go1src).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
+	}
+	out, err = exec.Command(gotool, "tool", "compile", "-o", go2obj, go2src).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
+	}
+	out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
+	}
+
+	if testenv.HasCGO() {
+		gopath := filepath.Join(buildDir, "gopath")
+		err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
+		if err != nil {
+			return err
+		}
+		cmd := exec.Command(gotool, "install", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
+		cmd.Env = append(os.Environ(), "GOPATH="+gopath)
+		out, err = cmd.CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("go install mycgo: %v\n%s", err, out)
+		}
+		pat := filepath.Join(gopath, "pkg", "*", "mycgo.a")
+		ms, err := filepath.Glob(pat)
+		if err != nil {
+			return err
+		}
+		if len(ms) == 0 {
+			return fmt.Errorf("cannot found paths for pattern %s", pat)
+		}
+		cgoarchive = ms[0]
+	}
+
+	return nil
+}
+
+func TestParseGoobj(t *testing.T) {
+	path := go1obj
+
+	f, err := os.Open(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	p, err := Parse(f, "mypkg")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.Arch != runtime.GOARCH {
+		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
+	}
+	var found bool
+	for _, s := range p.Syms {
+		if s.Name == "mypkg.go1" {
+			found = true
+			break
+		}
+	}
+	if !found {
+		t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
+	}
+}
+
+func TestParseArchive(t *testing.T) {
+	path := goarchive
+
+	f, err := os.Open(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	p, err := Parse(f, "mypkg")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.Arch != runtime.GOARCH {
+		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
+	}
+	var found1 bool
+	var found2 bool
+	for _, s := range p.Syms {
+		if s.Name == "mypkg.go1" {
+			found1 = true
+		}
+		if s.Name == "mypkg.go2" {
+			found2 = true
+		}
+	}
+	if !found1 {
+		t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
+	}
+	if !found2 {
+		t.Errorf(`%s: symbol "mypkg.go2" not found`, path)
+	}
+}
+
+func TestParseCGOArchive(t *testing.T) {
+	testenv.MustHaveCGO(t)
+
+	path := cgoarchive
+
+	f, err := os.Open(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	p, err := Parse(f, "mycgo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.Arch != runtime.GOARCH {
+		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
+	}
+	var found1 bool
+	var found2 bool
+	for _, s := range p.Syms {
+		if s.Name == "mycgo.go1" {
+			found1 = true
+		}
+		if s.Name == "mycgo.go2" {
+			found2 = true
+		}
+	}
+	if !found1 {
+		t.Errorf(`%s: symbol "mycgo.go1" not found`, path)
+	}
+	if !found2 {
+		t.Errorf(`%s: symbol "mycgo.go2" not found`, path)
+	}
+
+	c1 := "c1"
+	c2 := "c2"
+
+	found1 = false
+	found2 = false
+
+	switch runtime.GOOS {
+	case "darwin":
+		c1 = "_" + c1
+		c2 = "_" + c2
+		for _, obj := range p.Native {
+			mf, err := macho.NewFile(obj)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if mf.Symtab == nil {
+				continue
+			}
+			for _, s := range mf.Symtab.Syms {
+				switch s.Name {
+				case c1:
+					found1 = true
+				case c2:
+					found2 = true
+				}
+			}
+		}
+	case "windows":
+		if runtime.GOARCH == "386" {
+			c1 = "_" + c1
+			c2 = "_" + c2
+		}
+		for _, obj := range p.Native {
+			pf, err := pe.NewFile(obj)
+			if err != nil {
+				t.Fatal(err)
+			}
+			for _, s := range pf.Symbols {
+				switch s.Name {
+				case c1:
+					found1 = true
+				case c2:
+					found2 = true
+				}
+			}
+		}
+	default:
+		for _, obj := range p.Native {
+			ef, err := elf.NewFile(obj)
+			if err != nil {
+				t.Fatal(err)
+			}
+			syms, err := ef.Symbols()
+			if err != nil {
+				t.Fatal(err)
+			}
+			for _, s := range syms {
+				switch s.Name {
+				case c1:
+					found1 = true
+				case c2:
+					found2 = true
+				}
+			}
+		}
+	}
+
+	if !found1 {
+		t.Errorf(`%s: symbol %q not found`, path, c1)
+	}
+	if !found2 {
+		t.Errorf(`%s: symbol %q not found`, path, c2)
+	}
+}
diff --git a/src/cmd/internal/goobj/read.go b/src/cmd/internal/goobj/read.go
index b6c90d3..ebdc375 100644
--- a/src/cmd/internal/goobj/read.go
+++ b/src/cmd/internal/goobj/read.go
@@ -6,7 +6,6 @@
 //
 // 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 (
@@ -16,6 +15,7 @@
 	"errors"
 	"fmt"
 	"io"
+	"os"
 	"strconv"
 	"strings"
 )
@@ -25,7 +25,7 @@
 	SymID                // symbol identifier (name and version)
 	Kind  objabi.SymKind // kind of symbol
 	DupOK bool           // are duplicate definitions okay?
-	Size  int            // size of corresponding data
+	Size  int64          // size of corresponding data
 	Type  SymID          // symbol for Go type information
 	Data  Data           // memory image of symbol
 	Reloc []Reloc        // relocations to apply to Data
@@ -43,7 +43,7 @@
 	// 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
+	Version int64
 }
 
 func (s SymID) String() string {
@@ -67,10 +67,10 @@
 	// The bytes at [Offset, Offset+Size) within the containing Sym
 	// should be updated to refer to the address Add bytes after the start
 	// of the symbol Sym.
-	Offset int
-	Size   int
+	Offset int64
+	Size   int64
 	Sym    SymID
-	Add    int
+	Add    int64
 
 	// The Type records the form of address expected in the bytes
 	// described by the previous fields: absolute, PC-relative, and so on.
@@ -85,16 +85,16 @@
 	// 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.
+	Kind   int64  // TODO(rsc): Define meaning.
+	Offset int64  // 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
+	Args     int64      // size in bytes of argument frame: inputs and outputs
+	Frame    int64      // 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
@@ -119,20 +119,26 @@
 // An InlinedCall is a node in an InlTree.
 // See cmd/internal/obj.InlTree for details.
 type InlinedCall struct {
-	Parent int
+	Parent int64
 	File   string
-	Line   int
+	Line   int64
 	Func   SymID
 }
 
 // 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
-	SymRefs    []SymID  // list of symbol names and versions referred to by this pack
-	Syms       []*Sym   // symbols defined by this package
-	MaxVersion int      // maximum Version in any SymID in Syms
-	Arch       string   // architecture
+	ImportPath string          // import path denoting this package
+	Imports    []string        // packages imported by this package
+	SymRefs    []SymID         // list of symbol names and versions referred to by this pack
+	Syms       []*Sym          // symbols defined by this package
+	MaxVersion int64           // maximum Version in any SymID in Syms
+	Arch       string          // architecture
+	Native     []*NativeReader // native object data (e.g. ELF)
+}
+
+type NativeReader struct {
+	Name string
+	io.ReaderAt
 }
 
 var (
@@ -150,7 +156,7 @@
 type objReader struct {
 	p          *Package
 	b          *bufio.Reader
-	f          io.ReadSeeker
+	f          *os.File
 	err        error
 	offset     int64
 	dataOffset int64
@@ -160,7 +166,7 @@
 }
 
 // init initializes r to read package p from f.
-func (r *objReader) init(f io.ReadSeeker, p *Package) {
+func (r *objReader) init(f *os.File, p *Package) {
 	r.f = f
 	r.p = p
 	r.offset, _ = f.Seek(0, io.SeekCurrent)
@@ -185,6 +191,24 @@
 	return r.err
 }
 
+// peek returns the next n bytes without advancing the reader.
+func (r *objReader) peek(n int) ([]byte, error) {
+	if r.err != nil {
+		return nil, r.err
+	}
+	if r.offset >= r.limit {
+		r.error(io.ErrUnexpectedEOF)
+		return nil, r.err
+	}
+	b, err := r.b.Peek(n)
+	if err != nil {
+		if err != bufio.ErrBufferFull {
+			r.error(err)
+		}
+	}
+	return b, 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
@@ -231,7 +255,7 @@
 }
 
 // readInt reads a zigzag varint from the input file.
-func (r *objReader) readInt() int {
+func (r *objReader) readInt() int64 {
 	var u uint64
 
 	for shift := uint(0); ; shift += 7 {
@@ -246,12 +270,7 @@
 		}
 	}
 
-	v := int64(u>>1) ^ (int64(u) << 63 >> 63)
-	if int64(int(v)) != v {
-		r.error(errCorruptObject) // TODO
-		return 0
-	}
-	return int(v)
+	return int64(u>>1) ^ (int64(u) << 63 >> 63)
 }
 
 // readString reads a length-delimited string from the input file.
@@ -289,8 +308,8 @@
 // readData reads a data reference from the input file.
 func (r *objReader) readData() Data {
 	n := r.readInt()
-	d := Data{Offset: r.dataOffset, Size: int64(n)}
-	r.dataOffset += int64(n)
+	d := Data{Offset: r.dataOffset, Size: n}
+	r.dataOffset += n
 	return d
 }
 
@@ -322,9 +341,9 @@
 	}
 }
 
-// Parse parses an object file or archive from r,
+// Parse parses an object file or archive from f,
 // assuming that its import path is pkgpath.
-func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) {
+func Parse(f *os.File, pkgpath string) (*Package, error) {
 	if pkgpath == "" {
 		pkgpath = `""`
 	}
@@ -332,7 +351,7 @@
 	p.ImportPath = pkgpath
 
 	var rd objReader
-	rd.init(r, p)
+	rd.init(f, p)
 	err := rd.readFull(rd.tmp[:8])
 	if err != nil {
 		if err == io.EOF {
@@ -365,9 +384,6 @@
 }
 
 // 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 {
@@ -413,9 +429,22 @@
 		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)
+
+			p, err := r.peek(8)
+			if err != nil {
+				return err
 			}
+			if bytes.Equal(p, goobjHeader) {
+				if err := r.parseObject(nil); err != nil {
+					return fmt.Errorf("parsing archive member %q: %v", name, err)
+				}
+			} else {
+				r.p.Native = append(r.p.Native, &NativeReader{
+					Name:     name,
+					ReaderAt: io.NewSectionReader(r.f, r.offset, size),
+				})
+			}
+
 			r.skip(r.limit - r.offset)
 			r.limit = oldLimit
 		}
@@ -496,7 +525,7 @@
 	r.readInt() // n files - ignore
 
 	r.dataOffset = r.offset
-	r.skip(int64(dataLength))
+	r.skip(dataLength)
 
 	// Symbols.
 	for {
@@ -581,7 +610,7 @@
 }
 
 func (r *Reloc) String(insnOffset uint64) string {
-	delta := r.Offset - int(insnOffset)
+	delta := r.Offset - int64(insnOffset)
 	s := fmt.Sprintf("[%d:%d]%s", delta, delta+r.Size, r.Type)
 	if r.Sym.Name != "" {
 		if r.Add != 0 {
diff --git a/src/cmd/internal/goobj/testdata/go1.go b/src/cmd/internal/goobj/testdata/go1.go
new file mode 100644
index 0000000..37d1ec1
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/go1.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mypkg
+
+import "fmt"
+
+func go1() {
+	fmt.Println("go1")
+}
diff --git a/src/cmd/internal/goobj/testdata/go2.go b/src/cmd/internal/goobj/testdata/go2.go
new file mode 100644
index 0000000..0e9c0d7
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/go2.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mypkg
+
+import "fmt"
+
+func go2() {
+	fmt.Println("go2")
+}
diff --git a/src/cmd/internal/goobj/testdata/mycgo/c1.c b/src/cmd/internal/goobj/testdata/mycgo/c1.c
new file mode 100644
index 0000000..869a324
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/mycgo/c1.c
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <stdio.h>
+
+void c1(void) {
+	puts("c1");
+}
diff --git a/src/cmd/internal/goobj/testdata/mycgo/c2.c b/src/cmd/internal/goobj/testdata/mycgo/c2.c
new file mode 100644
index 0000000..1cf904f
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/mycgo/c2.c
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <stdio.h>
+
+void c2(void) {
+	puts("c2");
+}
diff --git a/src/cmd/internal/goobj/testdata/mycgo/go.go b/src/cmd/internal/goobj/testdata/mycgo/go.go
new file mode 100644
index 0000000..7b74f91
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/mycgo/go.go
@@ -0,0 +1,5 @@
+package mycgo
+
+// void c1(void);
+// void c2(void);
+import "C"
diff --git a/src/cmd/internal/goobj/testdata/mycgo/go1.go b/src/cmd/internal/goobj/testdata/mycgo/go1.go
new file mode 100644
index 0000000..eb3924c
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/mycgo/go1.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mycgo
+
+import "fmt"
+
+func go1() {
+	fmt.Println("go1")
+}
diff --git a/src/cmd/internal/goobj/testdata/mycgo/go2.go b/src/cmd/internal/goobj/testdata/mycgo/go2.go
new file mode 100644
index 0000000..ea3e26f
--- /dev/null
+++ b/src/cmd/internal/goobj/testdata/mycgo/go2.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mycgo
+
+import "fmt"
+
+func go2() {
+	fmt.Println("go2")
+}
diff --git a/src/cmd/internal/obj/arm/a.out.go b/src/cmd/internal/obj/arm/a.out.go
index 6ea7d4b..d4d9510 100644
--- a/src/cmd/internal/obj/arm/a.out.go
+++ b/src/cmd/internal/obj/arm/a.out.go
@@ -116,7 +116,8 @@
 	C_REGREG
 	C_REGREG2
 	C_REGLIST
-	C_SHIFT
+	C_SHIFT     /* register shift R>>x */
+	C_SHIFTADDR /* memory address with shifted offset R>>x(R) */
 	C_FREG
 	C_PSR
 	C_FCR
@@ -230,6 +231,24 @@
 	ASUBD
 	AMULF
 	AMULD
+	ANMULF
+	ANMULD
+	AMULAF
+	AMULAD
+	ANMULAF
+	ANMULAD
+	AMULSF
+	AMULSD
+	ANMULSF
+	ANMULSD
+	AFMULAF
+	AFMULAD
+	AFNMULAF
+	AFNMULAD
+	AFMULSF
+	AFMULSD
+	AFNMULSF
+	AFNMULSD
 	ADIVF
 	ADIVD
 	ASQRTF
@@ -294,6 +313,16 @@
 	AREVSH
 	ARBIT
 
+	AXTAB
+	AXTAH
+	AXTABU
+	AXTAHU
+
+	ABFX
+	ABFXU
+	ABFC
+	ABFI
+
 	AMULWT
 	AMULWB
 	AMULBB
diff --git a/src/cmd/internal/obj/arm/anames.go b/src/cmd/internal/obj/arm/anames.go
index 63cc5da..cb60eba 100644
--- a/src/cmd/internal/obj/arm/anames.go
+++ b/src/cmd/internal/obj/arm/anames.go
@@ -53,6 +53,24 @@
 	"SUBD",
 	"MULF",
 	"MULD",
+	"NMULF",
+	"NMULD",
+	"MULAF",
+	"MULAD",
+	"NMULAF",
+	"NMULAD",
+	"MULSF",
+	"MULSD",
+	"NMULSF",
+	"NMULSD",
+	"FMULAF",
+	"FMULAD",
+	"FNMULAF",
+	"FNMULAD",
+	"FMULSF",
+	"FMULSD",
+	"FNMULSF",
+	"FNMULSD",
 	"DIVF",
 	"DIVD",
 	"SQRTF",
@@ -107,6 +125,14 @@
 	"REV16",
 	"REVSH",
 	"RBIT",
+	"XTAB",
+	"XTAH",
+	"XTABU",
+	"XTAHU",
+	"BFX",
+	"BFXU",
+	"BFC",
+	"BFI",
 	"MULWT",
 	"MULWB",
 	"MULBB",
diff --git a/src/cmd/internal/obj/arm/anames5.go b/src/cmd/internal/obj/arm/anames5.go
index bb98d3b..f2743b9 100644
--- a/src/cmd/internal/obj/arm/anames5.go
+++ b/src/cmd/internal/obj/arm/anames5.go
@@ -11,6 +11,7 @@
 	"REGREG2",
 	"REGLIST",
 	"SHIFT",
+	"SHIFTADDR",
 	"FREG",
 	"PSR",
 	"FCR",
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index 8abf732..04c91fa 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -69,6 +69,7 @@
 	param    int16
 	flag     int8
 	pcrelsiz uint8
+	scond    uint8 // optional flags accepted by the instruction
 }
 
 type Opcross [32][2][32]uint8
@@ -82,236 +83,252 @@
 
 var optab = []Optab{
 	/* struct Optab:
-	OPCODE,	from, prog->reg, to,		 type,size,param,flag */
-	{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
-	{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
-	{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
-	{AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AORR, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
-	{AORR, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AMVN, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0},
-	{AADD, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0},
-	{AADD, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0},
-	{AAND, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0},
-	{AAND, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0},
-	{AORR, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0},
-	{AORR, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0},
-	{AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0},
-	{AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0},
-	{ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0, 0, 0},
-	{AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
-	{AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
-	{AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AORR, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
-	{AORR, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0},
-	{AMOVW, C_RACON, C_NONE, C_REG, 4, 4, REGSP, 0, 0},
-	{AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL, 0},
-	{ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
-	{ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0, 0, 0},
-	{ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
-	{ABEQ, C_RCON, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // prediction hinted form, hint ignored
-
-	{AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL, 0},
-	{ABL, C_NONE, C_NONE, C_ROREG, 7, 4, 0, 0, 0},
-	{ABL, C_REG, C_NONE, C_ROREG, 7, 4, 0, 0, 0},
-	{ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0, 0, 0},
-	{ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0, 0, 0},
-	{ASLL, C_RCON, C_REG, C_REG, 8, 4, 0, 0, 0},
-	{ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0, 0, 0},
-	{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
-	{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
-	{ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
-	{ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0, 0, 0},
-	{AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0, 0, 0},
-	{AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0, 0, 0},
-	{AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0, 0, 0},
-	{AWORD, C_NONE, C_NONE, C_TLS_LE, 103, 4, 0, 0, 0},
-	{AWORD, C_NONE, C_NONE, C_TLS_IE, 104, 4, 0, 0, 0},
-	{AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0},
-	{AMOVW, C_SCON, C_NONE, C_REG, 12, 4, 0, 0, 0},
-	{AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
-	{AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4},
-	{AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AAND, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AAND, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AORR, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AORR, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AMVN, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0},
-	{AADD, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AADD, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AAND, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AAND, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AORR, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0},
-	{AORR, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{AMVN, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
-	{ACMP, C_SCON, C_REG, C_NONE, 13, 8, 0, 0, 0},
-	{AADD, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0},
-	{AADD, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0},
-	{AORR, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0},
-	{AORR, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0},
-	{AADD, C_RCON2S, C_REG, C_REG, 107, 8, 0, 0, 0},
-	{AADD, C_RCON2S, C_NONE, C_REG, 107, 8, 0, 0, 0},
-	{AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0},
-	{AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0},
-	{AAND, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0},
-	{AAND, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0},
-	{AORR, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0},
-	{AORR, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0},
-	{AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0},
-	{ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0},
-	{AMOVB, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0},
-	{AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0},
-	{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
-	{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
-	{ADIV, C_REG, C_REG, C_REG, 16, 4, 0, 0, 0},
-	{ADIV, C_REG, C_NONE, C_REG, 16, 4, 0, 0, 0},
-	{ADIVHW, C_REG, C_REG, C_REG, 105, 4, 0, 0, 0},
-	{ADIVHW, C_REG, C_NONE, C_REG, 105, 4, 0, 0, 0},
-	{AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0},
-	{AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0},
-	{AMOVW, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVW, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVBU, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVBU, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4},
-	{AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4},
-	{AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4},
-	{AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4},
-	{AMOVW, C_TLS_LE, C_NONE, C_REG, 101, 4, 0, LFROM, 0},
-	{AMOVW, C_TLS_IE, C_NONE, C_REG, 102, 8, 0, LFROM, 0},
-	{AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4},
-	{AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4},
-	{AMOVW, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0},
-	{AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0, 0, 0},
-	{AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0, 0, 0},
-	{AMOVM, C_REGLIST, C_NONE, C_SOREG, 38, 4, 0, 0, 0},
-	{AMOVM, C_SOREG, C_NONE, C_REGLIST, 39, 4, 0, 0, 0},
-	{ASWPW, C_SOREG, C_REG, C_REG, 40, 4, 0, 0, 0},
-	{ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
-	{AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP, 0, 0},
-	{AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0, 0, 0},
-	{AMOVF, C_FAUTO, C_NONE, C_FREG, 51, 4, REGSP, 0, 0},
-	{AMOVF, C_FOREG, C_NONE, C_FREG, 51, 4, 0, 0, 0},
-	{AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO, 0},
-	{AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO, 0},
-	{AMOVF, C_LAUTO, C_NONE, C_FREG, 53, 12, REGSP, LFROM, 0},
-	{AMOVF, C_LOREG, C_NONE, C_FREG, 53, 12, 0, LFROM, 0},
-	{AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4},
-	{AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4},
-	{AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
-	{AADDF, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0},
-	{AMOVF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0},
-	{ANEGF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0},
-	{AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0},
-	{AMOVW, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0},
-	{AMOVBU, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0},
-	{AMOVB, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
-	{AMOVBS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
-	{AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0},
-	{AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0},
-	{AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0},
-	{AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0},
-	{AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0},
-	{AMOVB, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0},
-	{AMOVB, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0},
-	{AMOVBS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0},
-	{AMOVBS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0},
-	{AMOVH, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0},
-	{AMOVH, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0},
-	{AMOVHS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0},
-	{AMOVHS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0},
-	{AMOVHU, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0},
-	{AMOVHU, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0},
-	{AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0},
-	{AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4},
-	{AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0},
-	{AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0},
-	{AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4},
-	{AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0},
-	{AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0},
-	{AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4},
-	{AMOVB, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0},
-	{AMOVB, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0},
-	{AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4},
-	{AMOVBS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0},
-	{AMOVBS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0},
-	{AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4},
-	{AMOVH, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0},
-	{AMOVH, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0},
-	{AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4},
-	{AMOVHS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0},
-	{AMOVHS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0},
-	{AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4},
-	{AMOVHU, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0},
-	{AMOVHU, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0},
-	{AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4},
-	{ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0},
-	{ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0},
-	{AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0},
-	{AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0},
-	{ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0},
-	{ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0},
-	{AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0},
-	{AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0},
-	{AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0, 0, 0},
-	{AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0},
-	{AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0},
-	{ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0},
-	{ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0},
-	{APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0},
-	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0},
-	{ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0},
-	{AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0},
-	{AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0},
-	{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0},
-	{obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
-	{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
-	{obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL
-	{obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL
-
-	{ADATABUNDLE, C_NONE, C_NONE, C_NONE, 100, 4, 0, 0, 0},
-	{ADATABUNDLEEND, C_NONE, C_NONE, C_NONE, 100, 0, 0, 0, 0},
-	{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0},
+	OPCODE, from, prog->reg, to, type, size, param, flag, extra data size, optional suffix */
+	{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0, 0},
+	{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{AMVN, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
+	{ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0, 0},
+	{AADD, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AADD, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
+	{AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, 0},
+	{AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, 0},
+	{ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0, 0, 0, 0},
+	{AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AORR, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
+	{ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0, 0},
+	{AMOVW, C_RACON, C_NONE, C_REG, 4, 4, REGSP, 0, 0, C_SBIT},
+	{AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL, 0, 0},
+	{ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0},
+	{ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0, 0, 0, 0},
+	{ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0},
+	{ABEQ, C_RCON, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, // prediction hinted form, hint ignored
+	{AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL, 0, 0},
+	{ABL, C_NONE, C_NONE, C_ROREG, 7, 4, 0, 0, 0, 0},
+	{ABL, C_REG, C_NONE, C_ROREG, 7, 4, 0, 0, 0, 0},
+	{ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0, 0, 0, 0},
+	{ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0, 0, 0, 0},
+	{ASLL, C_RCON, C_REG, C_REG, 8, 4, 0, 0, 0, C_SBIT},
+	{ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0, 0, 0, C_SBIT},
+	{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0, C_SBIT},
+	{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0, C_SBIT},
+	{ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0, 0},
+	{ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0, 0, 0, 0},
+	{AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0, 0, 0, 0},
+	{AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0, 0, 0, 0},
+	{AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0, 0, 0, 0},
+	{AWORD, C_NONE, C_NONE, C_TLS_LE, 103, 4, 0, 0, 0, 0},
+	{AWORD, C_NONE, C_NONE, C_TLS_IE, 104, 4, 0, 0, 0, 0},
+	{AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
+	{AMOVW, C_SCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
+	{AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0, 0},
+	{AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4, 0},
+	{AMVN, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
+	{AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AAND, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AAND, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AORR, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AORR, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0, 0},
+	{AADD, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AADD, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AAND, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AAND, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AORR, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AORR, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
+	{AMVN, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, 0},
+	{ACMP, C_SCON, C_REG, C_NONE, 13, 8, 0, 0, 0, 0},
+	{AADD, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0, 0},
+	{AADD, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0, 0},
+	{AORR, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0, 0},
+	{AORR, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0, 0},
+	{AADD, C_RCON2S, C_REG, C_REG, 107, 8, 0, 0, 0, 0},
+	{AADD, C_RCON2S, C_NONE, C_REG, 107, 8, 0, 0, 0, 0},
+	{AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AAND, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AAND, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AORR, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AORR, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
+	{AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, 0},
+	{ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0, 0},
+	{AMOVB, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, 0},
+	{AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
+	{AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0, 0, 0, 0},
+	{AMOVH, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, 0},
+	{AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
+	{AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
+	{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0, C_SBIT},
+	{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0, C_SBIT},
+	{ADIV, C_REG, C_REG, C_REG, 16, 4, 0, 0, 0, 0},
+	{ADIV, C_REG, C_NONE, C_REG, 16, 4, 0, 0, 0, 0},
+	{ADIVHW, C_REG, C_REG, C_REG, 105, 4, 0, 0, 0, 0},
+	{ADIVHW, C_REG, C_NONE, C_REG, 105, 4, 0, 0, 0, 0},
+	{AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0, 0, 0, C_SBIT},
+	{ABFX, C_LCON, C_REG, C_REG, 18, 4, 0, 0, 0, 0},  // width in From, LSB in From3
+	{ABFX, C_LCON, C_NONE, C_REG, 18, 4, 0, 0, 0, 0}, // width in From, LSB in From3
+	{AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AXTAB, C_SHIFT, C_REG, C_REG, 22, 4, 0, 0, 0, 0},
+	{AXTAB, C_SHIFT, C_NONE, C_REG, 22, 4, 0, 0, 0, 0},
+	{AMOVW, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, C_SBIT},
+	{AMOVB, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVBS, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVBU, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVH, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVHS, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVHU, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
+	{AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_TLS_LE, C_NONE, C_REG, 101, 4, 0, LFROM, 0, 0},
+	{AMOVW, C_TLS_IE, C_NONE, C_REG, 102, 8, 0, LFROM, 0, 0},
+	{AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0, C_SBIT},
+	{AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0, 0, 0, 0},
+	{AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0, 0, 0, 0},
+	{AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0, 0, 0, 0},
+	{AMOVM, C_REGLIST, C_NONE, C_SOREG, 38, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVM, C_SOREG, C_NONE, C_REGLIST, 39, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{ASWPW, C_SOREG, C_REG, C_REG, 40, 4, 0, 0, 0, 0},
+	{ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0, 0},
+	{AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FAUTO, C_NONE, C_FREG, 51, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FOREG, C_NONE, C_FREG, 51, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_LAUTO, C_NONE, C_FREG, 53, 12, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_LOREG, C_NONE, C_FREG, 53, 12, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0, 0},
+	{AADDF, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0, 0},
+	{AMOVF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0, 0},
+	{ANEGF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0, 0},
+	{AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0, 0},
+	{AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0, 0},
+	{AMOVW, C_SHIFTADDR, C_NONE, C_REG, 59, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_SHIFTADDR, C_NONE, C_REG, 59, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVW, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBU, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
+	{AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
+	{ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0, 0},
+	{ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0, 0},
+	{AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0, 0},
+	{AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0, 0},
+	{ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0, 0},
+	{ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0, 0},
+	{AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0, C_UBIT},
+	{AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0, C_UBIT},
+	{AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0, 0, 0, C_UBIT},
+	{AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0, 0, 0, C_UBIT},
+	{AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0, 0},
+	{AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0, 0},
+	{ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0, 0},
+	{ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0, 0},
+	{APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0, 0},
+	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0, 0},
+	{ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0, 0},
+	{AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0, 0},
+	{AMULA, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0, C_SBIT},
+	{AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0, 0},
+	{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0, 0},
+	{obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0, 0},
+	{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0, 0},
+	{obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, // same as ABL
+	{obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, // same as ABL
+	{ADATABUNDLE, C_NONE, C_NONE, C_NONE, 100, 4, 0, 0, 0, 0},
+	{ADATABUNDLEEND, C_NONE, C_NONE, C_NONE, 100, 0, 0, 0, 0, 0},
+	{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0, 0},
 }
 
 var oprange [ALAST & obj.AMask][]Optab
@@ -601,61 +618,18 @@
 	return size
 }
 
-const (
-	T_SBIT = 1 << 0
-	T_PBIT = 1 << 1
-	T_WBIT = 1 << 2
-)
-
-var mayHaveSuffix = map[obj.As]uint8{
-	// bit logic
-	AAND: T_SBIT,
-	AEOR: T_SBIT,
-	AORR: T_SBIT,
-	ABIC: T_SBIT,
-	// arithmatic
-	ASUB: T_SBIT,
-	AADD: T_SBIT,
-	ASBC: T_SBIT,
-	AADC: T_SBIT,
-	ARSB: T_SBIT,
-	ARSC: T_SBIT,
-	// mov
-	AMVN:   T_SBIT,
-	AMOVW:  T_SBIT | T_PBIT | T_WBIT,
-	AMOVB:  T_SBIT | T_PBIT | T_WBIT,
-	AMOVBS: T_SBIT | T_PBIT | T_WBIT,
-	AMOVBU: T_SBIT | T_PBIT | T_WBIT,
-	AMOVH:  T_SBIT | T_PBIT | T_WBIT,
-	AMOVHS: T_SBIT | T_PBIT | T_WBIT,
-	AMOVHU: T_SBIT | T_PBIT | T_WBIT,
-	AMOVM:  T_PBIT | T_WBIT,
-	// shift
-	ASRL: T_SBIT,
-	ASRA: T_SBIT,
-	ASLL: T_SBIT,
-	// mul
-	AMUL:   T_SBIT,
-	AMULU:  T_SBIT,
-	AMULL:  T_SBIT,
-	AMULLU: T_SBIT,
-	// mula
-	AMULA:   T_SBIT,
-	AMULAL:  T_SBIT,
-	AMULALU: T_SBIT,
-	// MRC/MCR
-	AMRC: T_SBIT,
-}
-
-func checkBits(ctxt *obj.Link, p *obj.Prog) {
-	if p.Scond&C_SBIT != 0 && mayHaveSuffix[p.As]&T_SBIT == 0 {
-		ctxt.Diag("invalid .S suffix: %v", p)
+func checkSuffix(c *ctxt5, p *obj.Prog, o *Optab) {
+	if p.Scond&C_SBIT != 0 && o.scond&C_SBIT == 0 {
+		c.ctxt.Diag("invalid .S suffix: %v", p)
 	}
-	if p.Scond&C_PBIT != 0 && mayHaveSuffix[p.As]&T_PBIT == 0 {
-		ctxt.Diag("invalid .P suffix: %v", p)
+	if p.Scond&C_PBIT != 0 && o.scond&C_PBIT == 0 {
+		c.ctxt.Diag("invalid .P suffix: %v", p)
 	}
-	if p.Scond&C_WBIT != 0 && mayHaveSuffix[p.As]&T_WBIT == 0 {
-		ctxt.Diag("invalid .W suffix: %v", p)
+	if p.Scond&C_WBIT != 0 && o.scond&C_WBIT == 0 {
+		c.ctxt.Diag("invalid .W suffix: %v", p)
+	}
+	if p.Scond&C_UBIT != 0 && o.scond&C_UBIT == 0 {
+		c.ctxt.Diag("invalid .U suffix: %v", p)
 	}
 }
 
@@ -738,8 +712,6 @@
 			c.flushpool(p, 0, 0)
 		}
 
-		checkBits(ctxt, p)
-
 		pc += int32(m)
 	}
 
@@ -1143,7 +1115,13 @@
 		return C_REGLIST
 
 	case obj.TYPE_SHIFT:
-		return C_SHIFT
+		if a.Reg == 0 {
+			// register shift R>>i
+			return C_SHIFT
+		} else {
+			// memory address with shifted offset R>>i(R)
+			return C_SHIFTADDR
+		}
 
 	case obj.TYPE_MEM:
 		switch a.Name {
@@ -1365,19 +1343,14 @@
 
 	// check illegal base register
 	switch a1 {
-	case C_SHIFT:
-		if p.From.Reg == 0 { // no base register
-			break
-		}
-		fallthrough
-	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG:
+	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG, C_SHIFTADDR:
 		if p.From.Reg < REG_R0 || REG_R15 < p.From.Reg {
 			c.ctxt.Diag("illegal base register: %v", p)
 		}
 	default:
 	}
 	switch a3 {
-	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG, C_SHIFT:
+	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG, C_SHIFTADDR:
 		if p.To.Reg < REG_R0 || REG_R15 < p.To.Reg {
 			c.ctxt.Diag("illegal base register: %v", p)
 		}
@@ -1405,6 +1378,7 @@
 		op := &ops[i]
 		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] {
 			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
+			checkSuffix(c, p, op)
 			return op
 		}
 	}
@@ -1559,6 +1533,7 @@
 		switch r {
 		default:
 			ctxt.Diag("unknown op in build: %v", r)
+			ctxt.DiagFlush()
 			log.Fatalf("bad code")
 
 		case AADD:
@@ -1643,6 +1618,24 @@
 			opset(ASUBD, r0)
 			opset(AMULF, r0)
 			opset(AMULD, r0)
+			opset(ANMULF, r0)
+			opset(ANMULD, r0)
+			opset(AMULAF, r0)
+			opset(AMULAD, r0)
+			opset(AMULSF, r0)
+			opset(AMULSD, r0)
+			opset(ANMULAF, r0)
+			opset(ANMULAD, r0)
+			opset(ANMULSF, r0)
+			opset(ANMULSD, r0)
+			opset(AFMULAF, r0)
+			opset(AFMULAD, r0)
+			opset(AFMULSF, r0)
+			opset(AFMULSD, r0)
+			opset(AFNMULAF, r0)
+			opset(AFNMULAD, r0)
+			opset(AFNMULSF, r0)
+			opset(AFNMULSD, r0)
 			opset(ADIVF, r0)
 			opset(ADIVD, r0)
 
@@ -1680,23 +1673,33 @@
 		case AMULAWT:
 			opset(AMULAWB, r0)
 			opset(AMULABB, r0)
-			opset(AMULA, r0)
 			opset(AMULS, r0)
 			opset(AMMULA, r0)
 			opset(AMMULS, r0)
 
+		case ABFX:
+			opset(ABFXU, r0)
+			opset(ABFC, r0)
+			opset(ABFI, r0)
+
 		case ACLZ:
 			opset(AREV, r0)
 			opset(AREV16, r0)
 			opset(AREVSH, r0)
 			opset(ARBIT, r0)
 
+		case AXTAB:
+			opset(AXTAH, r0)
+			opset(AXTABU, r0)
+			opset(AXTAHU, r0)
+
 		case ALDREX,
 			ASTREX,
 			ALDREXD,
 			ASTREXD,
 			APLD,
 			AAND,
+			AMULA,
 			obj.AUNDEF,
 			obj.AFUNCDATA,
 			obj.APCDATA,
@@ -1944,6 +1947,8 @@
 	case 12: /* movw $lcon, reg */
 		if o.a1 == C_SCON {
 			o1 = c.omvs(p, &p.From, int(p.To.Reg))
+		} else if p.As == AMVN {
+			o1 = c.omvr(p, &p.From, int(p.To.Reg))
 		} else {
 			o1 = c.omvl(p, &p.From, int(p.To.Reg))
 		}
@@ -2030,6 +2035,33 @@
 		r := int(p.Reg)
 		o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12
 
+	case 18: /* BFX/BFXU/BFC/BFI */
+		o1 = c.oprrr(p, p.As, int(p.Scond))
+		rt := int(p.To.Reg)
+		r := int(p.Reg)
+		if r == 0 {
+			r = rt
+		} else if p.As == ABFC { // only "BFC $width, $lsb, Reg" is accepted, p.Reg must be 0
+			c.ctxt.Diag("illegal combination: %v", p)
+		}
+		if p.GetFrom3() == nil || p.GetFrom3().Type != obj.TYPE_CONST {
+			c.ctxt.Diag("%v: missing or wrong LSB", p)
+			break
+		}
+		lsb := p.GetFrom3().Offset
+		width := p.From.Offset
+		if lsb < 0 || lsb > 31 || width <= 0 || (lsb+width) > 32 {
+			c.ctxt.Diag("%v: wrong width or LSB", p)
+		}
+		switch p.As {
+		case ABFX, ABFXU: // (width-1) is encoded
+			o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(width-1)<<16
+		case ABFC, ABFI: // MSB is encoded
+			o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(lsb+width-1)<<16
+		default:
+			c.ctxt.Diag("illegal combination: %v", p)
+		}
+
 	case 20: /* mov/movb/movbu R,O(R) */
 		c.aclass(&p.To)
 
@@ -2051,6 +2083,32 @@
 			o1 |= 1 << 22
 		}
 
+	case 22: /* XTAB R@>i, [R], R */
+		o1 = c.oprrr(p, p.As, int(p.Scond))
+		switch p.From.Offset &^ 0xf {
+		// only 0/8/16/24 bits rotation is accepted
+		case SHIFT_RR, SHIFT_RR | 8<<7, SHIFT_RR | 16<<7, SHIFT_RR | 24<<7:
+			o1 |= uint32(p.From.Offset) & 0xc0f
+		default:
+			c.ctxt.Diag("illegal shift: %v", p)
+		}
+		rt := p.To.Reg
+		r := p.Reg
+		if r == 0 {
+			r = rt
+		}
+		o1 |= (uint32(rt)&15)<<12 | (uint32(r)&15)<<16
+
+	case 23: /* MOVW/MOVB/MOVH R@>i, R */
+		switch p.As {
+		case AMOVW:
+			o1 = c.mov(p)
+		case AMOVBU, AMOVBS, AMOVB, AMOVHU, AMOVHS, AMOVH:
+			o1 = c.movxt(p)
+		default:
+			c.ctxt.Diag("illegal combination: %v", p)
+		}
+
 	case 30: /* mov/movb/movbu R,L(R) */
 		o1 = c.omvl(p, &p.To, REGTMP)
 
@@ -2228,7 +2286,13 @@
 		rt := int(p.To.Reg)
 		r := int(p.Reg)
 		if r == 0 {
-			r = rt
+			switch p.As {
+			case AMULAD, AMULAF, AMULSF, AMULSD, ANMULAF, ANMULAD, ANMULSF, ANMULSD,
+				AFMULAD, AFMULAF, AFMULSF, AFMULSD, AFNMULAF, AFNMULAD, AFNMULSF, AFNMULSD:
+				c.ctxt.Diag("illegal combination: %v", p)
+			default:
+				r = rt
+			}
 		}
 
 		o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
@@ -2267,15 +2331,12 @@
 
 	case 59: /* movw/bu R<<I(R),R -> ldr indexed */
 		if p.From.Reg == 0 {
-			if p.As != AMOVW {
-				c.ctxt.Diag("byte MOV from shifter operand")
-			}
-			o1 = c.mov(p)
+			c.ctxt.Diag("source operand is not a memory address: %v", p)
 			break
 		}
-
 		if p.From.Offset&(1<<4) != 0 {
 			c.ctxt.Diag("bad shift in LDR")
+			break
 		}
 		o1 = c.olrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond))
 		if p.As == AMOVBU {
@@ -2284,16 +2345,21 @@
 
 	case 60: /* movb R(R),R -> ldrsb indexed */
 		if p.From.Reg == 0 {
-			c.ctxt.Diag("byte MOV from shifter operand")
-			o1 = c.mov(p)
+			c.ctxt.Diag("source operand is not a memory address: %v", p)
 			break
 		}
-
 		if p.From.Offset&(^0xf) != 0 {
 			c.ctxt.Diag("bad shift: %v", p)
+			break
 		}
 		o1 = c.olhrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond))
-		o1 ^= 1<<5 | 1<<6
+		switch p.As {
+		case AMOVB, AMOVBS:
+			o1 ^= 1<<5 | 1<<6
+		case AMOVH, AMOVHS:
+			o1 ^= 1 << 6
+		default:
+		}
 		if p.Scond&C_UBIT != 0 {
 			o1 &^= 1 << 23
 		}
@@ -2307,6 +2373,19 @@
 			o1 |= 1 << 22
 		}
 
+	case 62: /* MOVH/MOVHS/MOVHU Reg, Reg<<0(Reg) -> strh */
+		if p.To.Reg == 0 {
+			c.ctxt.Diag("MOV to shifter operand")
+		}
+		if p.To.Offset&(^0xf) != 0 {
+			c.ctxt.Diag("bad shift: %v", p)
+		}
+		o1 = c.olhrr(int(p.To.Offset), int(p.To.Reg), int(p.From.Reg), int(p.Scond))
+		o1 ^= 1 << 20
+		if p.Scond&C_UBIT != 0 {
+			o1 &^= 1 << 23
+		}
+
 		/* reloc ops */
 	case 64: /* mov/movb/movbu R,addr */
 		o1 = c.omvl(p, &p.To, REGTMP)
@@ -2336,15 +2415,9 @@
 		}
 
 	case 101: /* movw tlsvar,R, local exec*/
-		if p.Scond&C_SCOND != C_SCOND_NONE {
-			c.ctxt.Diag("conditional tls")
-		}
 		o1 = c.omvl(p, &p.From, int(p.To.Reg))
 
 	case 102: /* movw tlsvar,R, initial exec*/
-		if p.Scond&C_SCOND != C_SCOND_NONE {
-			c.ctxt.Diag("conditional tls")
-		}
 		o1 = c.omvl(p, &p.From, int(p.To.Reg))
 		o2 = c.olrr(int(p.To.Reg)&15, (REGPC & 15), int(p.To.Reg), int(p.Scond))
 
@@ -2499,6 +2572,9 @@
 		if c.instoffset != 0 {
 			c.ctxt.Diag("offset must be zero in STREX")
 		}
+		if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg {
+			c.ctxt.Diag("cannot use same register as both source and destination: %v", p)
+		}
 		o1 = 0x18<<20 | 0xf90
 		o1 |= (uint32(p.From.Reg) & 15) << 16
 		o1 |= (uint32(p.Reg) & 15) << 0
@@ -2613,6 +2689,12 @@
 		if c.instoffset != 0 {
 			c.ctxt.Diag("offset must be zero in STREX")
 		}
+		if p.Reg&1 != 0 {
+			c.ctxt.Diag("source register must be even in STREXD: %v", p)
+		}
+		if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg || p.To.Reg == p.Reg+1 {
+			c.ctxt.Diag("cannot use same register as both source and destination: %v", p)
+		}
 		o1 = 0x1a<<20 | 0xf90
 		o1 |= (uint32(p.From.Reg) & 15) << 16
 		o1 |= (uint32(p.Reg) & 15) << 0
@@ -2715,6 +2797,31 @@
 	return
 }
 
+func (c *ctxt5) movxt(p *obj.Prog) uint32 {
+	o1 := ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
+	switch p.As {
+	case AMOVB, AMOVBS:
+		o1 |= 0x6af<<16 | 0x7<<4
+	case AMOVH, AMOVHS:
+		o1 |= 0x6bf<<16 | 0x7<<4
+	case AMOVBU:
+		o1 |= 0x6ef<<16 | 0x7<<4
+	case AMOVHU:
+		o1 |= 0x6ff<<16 | 0x7<<4
+	default:
+		c.ctxt.Diag("illegal combination: %v", p)
+	}
+	switch p.From.Offset &^ 0xf {
+	// only 0/8/16/24 bits rotation is accepted
+	case SHIFT_RR, SHIFT_RR | 8<<7, SHIFT_RR | 16<<7, SHIFT_RR | 24<<7:
+		o1 |= uint32(p.From.Offset) & 0xc0f
+	default:
+		c.ctxt.Diag("illegal shift: %v", p)
+	}
+	o1 |= (uint32(p.To.Reg) & 15) << 12
+	return o1
+}
+
 func (c *ctxt5) mov(p *obj.Prog) uint32 {
 	c.aclass(&p.From)
 	o1 := c.oprrr(p, p.As, int(p.Scond))
@@ -2820,6 +2927,42 @@
 		return o | 0xe<<24 | 0x2<<20 | 0xb<<8 | 0<<4
 	case AMULF:
 		return o | 0xe<<24 | 0x2<<20 | 0xa<<8 | 0<<4
+	case ANMULD:
+		return o | 0xe<<24 | 0x2<<20 | 0xb<<8 | 0x4<<4
+	case ANMULF:
+		return o | 0xe<<24 | 0x2<<20 | 0xa<<8 | 0x4<<4
+	case AMULAD:
+		return o | 0xe<<24 | 0xb<<8
+	case AMULAF:
+		return o | 0xe<<24 | 0xa<<8
+	case AMULSD:
+		return o | 0xe<<24 | 0xb<<8 | 0x4<<4
+	case AMULSF:
+		return o | 0xe<<24 | 0xa<<8 | 0x4<<4
+	case ANMULAD:
+		return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 0x4<<4
+	case ANMULAF:
+		return o | 0xe<<24 | 0x1<<20 | 0xa<<8 | 0x4<<4
+	case ANMULSD:
+		return o | 0xe<<24 | 0x1<<20 | 0xb<<8
+	case ANMULSF:
+		return o | 0xe<<24 | 0x1<<20 | 0xa<<8
+	case AFMULAD:
+		return o | 0xe<<24 | 0xa<<20 | 0xb<<8
+	case AFMULAF:
+		return o | 0xe<<24 | 0xa<<20 | 0xa<<8
+	case AFMULSD:
+		return o | 0xe<<24 | 0xa<<20 | 0xb<<8 | 0x4<<4
+	case AFMULSF:
+		return o | 0xe<<24 | 0xa<<20 | 0xa<<8 | 0x4<<4
+	case AFNMULAD:
+		return o | 0xe<<24 | 0x9<<20 | 0xb<<8 | 0x4<<4
+	case AFNMULAF:
+		return o | 0xe<<24 | 0x9<<20 | 0xa<<8 | 0x4<<4
+	case AFNMULSD:
+		return o | 0xe<<24 | 0x9<<20 | 0xb<<8
+	case AFNMULSF:
+		return o | 0xe<<24 | 0x9<<20 | 0xa<<8
 	case ADIVD:
 		return o | 0xe<<24 | 0x8<<20 | 0xb<<8 | 0<<4
 	case ADIVF:
@@ -2884,6 +3027,30 @@
 	case -ACMP: // cmp imm
 		return o | 0x3<<24 | 0x5<<20
 
+	case ABFX:
+		return o | 0x3d<<21 | 0x5<<4
+
+	case ABFXU:
+		return o | 0x3f<<21 | 0x5<<4
+
+	case ABFC:
+		return o | 0x3e<<21 | 0x1f
+
+	case ABFI:
+		return o | 0x3e<<21 | 0x1<<4
+
+	case AXTAB:
+		return o | 0x6a<<20 | 0x7<<4
+
+	case AXTAH:
+		return o | 0x6b<<20 | 0x7<<4
+
+	case AXTABU:
+		return o | 0x6e<<20 | 0x7<<4
+
+	case AXTAHU:
+		return o | 0x6f<<20 | 0x7<<4
+
 		// CLZ doesn't support .nil
 	case ACLZ:
 		return o&(0xf<<28) | 0x16f<<16 | 0xf1<<4
@@ -2977,9 +3144,6 @@
 }
 
 func (c *ctxt5) olr(v int32, b int, r int, sc int) uint32 {
-	if sc&C_SBIT != 0 {
-		c.ctxt.Diag(".nil on LDR/STR instruction")
-	}
 	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
 	if sc&C_PBIT == 0 {
 		o |= 1 << 24
@@ -3009,9 +3173,6 @@
 }
 
 func (c *ctxt5) olhr(v int32, b int, r int, sc int) uint32 {
-	if sc&C_SBIT != 0 {
-		c.ctxt.Diag(".nil on LDRH/STRH instruction")
-	}
 	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
 	if sc&C_PBIT == 0 {
 		o |= 1 << 24
@@ -3113,6 +3274,19 @@
 	return o1
 }
 
+// MVN $C_NCON, Reg -> MOVW $C_RCON, Reg
+func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
+	o1 := c.oprrr(p, AMOVW, int(p.Scond))
+	o1 |= (uint32(dr) & 15) << 12
+	v := immrot(^uint32(a.Offset))
+	if v == 0 {
+		c.ctxt.Diag("%v: missing literal", p)
+		return 0
+	}
+	o1 |= uint32(v)
+	return o1
+}
+
 func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
 	var o1 uint32
 	if p.Pcond == nil {
@@ -3136,7 +3310,7 @@
 
 func (c *ctxt5) chipzero5(e float64) int {
 	// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
-	if objabi.GOARM < 7 || e != 0 {
+	if objabi.GOARM < 7 || math.Float64bits(e) != 0 {
 		return -1
 	}
 	return 0
@@ -3181,8 +3355,8 @@
 func nocache(p *obj.Prog) {
 	p.Optab = 0
 	p.From.Class = 0
-	if p.From3 != nil {
-		p.From3.Class = 0
+	if p.GetFrom3() != nil {
+		p.GetFrom3().Class = 0
 	}
 	p.To.Class = 0
 }
diff --git a/src/cmd/internal/obj/arm/list5.go b/src/cmd/internal/obj/arm/list5.go
index 169a7f5..6522f9a 100644
--- a/src/cmd/internal/obj/arm/list5.go
+++ b/src/cmd/internal/obj/arm/list5.go
@@ -38,6 +38,7 @@
 func init() {
 	obj.RegisterRegister(obj.RBaseARM, MAXREG, rconv)
 	obj.RegisterOpcode(obj.ABaseARM, Anames)
+	obj.RegisterRegisterList(obj.RegListARMLo, obj.RegListARMHi, rlconv)
 }
 
 func rconv(r int) string {
@@ -81,3 +82,25 @@
 	fp += s
 	return fp
 }
+
+func rlconv(list int64) string {
+	str := ""
+	for i := 0; i < 16; i++ {
+		if list&(1<<uint(i)) != 0 {
+			if str == "" {
+				str += "["
+			} else {
+				str += ","
+			}
+			// This is ARM-specific; R10 is g.
+			if i == REGG-REG_R0 {
+				str += "g"
+			} else {
+				str += fmt.Sprintf("R%d", i)
+			}
+		}
+	}
+
+	str += "]"
+	return str
+}
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index 32c4643..59f044e 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -186,7 +186,7 @@
 			p.From.Offset = 0
 		}
 	}
-	if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
+	if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
 		c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
 	}
 	var source *obj.Addr
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go
index 3a3fed5..6087b74 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -166,6 +166,14 @@
 	REG_RSP = REG_V31 + 32 // to differentiate ZR/SP, REG_RSP&0x1f = 31
 )
 
+// bits 0-4 indicates register: Vn
+// bits 5-8 indicates arrangement: <T>
+const (
+	REG_ARNG = obj.RBaseARM64 + 1<<10 + iota<<9 // Vn.<T>
+	REG_ELEM                                    // Vn.<T>[index]
+	REG_ELEM_END
+)
+
 // Not registers, but flags that can be combined with regular register
 // constants to indicate extended register conversion. When checking,
 // you should subtract obj.RBaseARM64 first. From this difference, bit 11
@@ -264,9 +272,12 @@
 	C_VREG   // V0..V31
 	C_PAIR   // (Rn, Rm)
 	C_SHIFT  // Rn<<2
-	C_EXTREG // Rn.UXTB<<3
+	C_EXTREG // Rn.UXTB[<<3]
 	C_SPR    // REG_NZCV
 	C_COND   // EQ, NE, etc
+	C_ARNG   // Vn.<T>
+	C_ELEM   // Vn.<T>[index]
+	C_LIST   // [V1, V2, V3]
 
 	C_ZCON     // $0 or ZR
 	C_ABCON0   // could be C_ADDCON0 or C_BITCON
@@ -291,6 +302,7 @@
 
 	C_NPAUTO     // -512 <= x < 0, 0 mod 8
 	C_NSAUTO     // -256 <= x < 0
+	C_PSAUTO_8   // 0 to 255, 0 mod 8
 	C_PSAUTO     // 0 to 255
 	C_PPAUTO     // 0 to 504, 0 mod 8
 	C_UAUTO4K_8  // 0 to 4095, 0 mod 8
@@ -315,6 +327,7 @@
 	C_ZOREG  // 0(R)
 	C_NPOREG // must mirror NPAUTO, etc
 	C_NSOREG
+	C_PSOREG_8
 	C_PSOREG
 	C_PPOREG
 	C_UOREG4K_8
@@ -718,6 +731,22 @@
 	ASHA256H2
 	ASHA256SU0
 	ASHA256SU1
+	AVADD
+	AVADDP
+	AVAND
+	AVCMEQ
+	AVEOR
+	AVMOV
+	AVLD1
+	AVORR
+	AVREV32
+	AVST1
+	AVDUP
+	AVMOVS
+	AVADDV
+	AVMOVI
+	AVUADDLV
+	AVSUB
 	ALAST
 	AB  = obj.AJMP
 	ABL = obj.ACALL
@@ -729,3 +758,20 @@
 	SHIFT_LR = 1 << 22
 	SHIFT_AR = 2 << 22
 )
+
+// Arrangement for ARM64 SIMD instructions
+const (
+	// arrangement types
+	ARNG_8B = iota
+	ARNG_16B
+	ARNG_1D
+	ARNG_4H
+	ARNG_8H
+	ARNG_2S
+	ARNG_4S
+	ARNG_2D
+	ARNG_B
+	ARNG_H
+	ARNG_S
+	ARNG_D
+)
diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go
index 4ee4043..4070a43 100644
--- a/src/cmd/internal/obj/arm64/anames.go
+++ b/src/cmd/internal/obj/arm64/anames.go
@@ -366,5 +366,21 @@
 	"SHA256H2",
 	"SHA256SU0",
 	"SHA256SU1",
+	"VADD",
+	"VADDP",
+	"VAND",
+	"VCMEQ",
+	"VEOR",
+	"VMOV",
+	"VLD1",
+	"VORR",
+	"VREV32",
+	"VST1",
+	"VDUP",
+	"VMOVS",
+	"VADDV",
+	"VMOVI",
+	"VUADDLV",
+	"VSUB",
 	"LAST",
 }
diff --git a/src/cmd/internal/obj/arm64/anames7.go b/src/cmd/internal/obj/arm64/anames7.go
index 24911f6..cb4b139 100644
--- a/src/cmd/internal/obj/arm64/anames7.go
+++ b/src/cmd/internal/obj/arm64/anames7.go
@@ -16,6 +16,9 @@
 	"EXTREG",
 	"SPR",
 	"COND",
+	"ARNG",
+	"ELEM",
+	"LIST",
 	"ZCON",
 	"ABCON0",
 	"ADDCON0",
@@ -35,6 +38,7 @@
 	"LBRA",
 	"NPAUTO",
 	"NSAUTO",
+	"PSAUTO_8",
 	"PSAUTO",
 	"PPAUTO",
 	"UAUTO4K_8",
@@ -57,6 +61,7 @@
 	"ZOREG",
 	"NPOREG",
 	"NSOREG",
+	"PSOREG_8",
 	"PSOREG",
 	"PPOREG",
 	"UOREG4K_8",
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 4419909..ca81238 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -271,7 +271,7 @@
 	{ALSL, C_VCON, C_NONE, C_REG, 8, 4, 0, 0, 0},
 	{ALSL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
 	{ALSL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
-	{ASVC, C_NONE, C_NONE, C_VCON, 10, 4, 0, 0, 0},
+	{ASVC, C_VCON, C_NONE, C_NONE, 10, 4, 0, 0, 0},
 	{ASVC, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
 	{ADWORD, C_NONE, C_NONE, C_VCON, 11, 8, 0, 0, 0},
 	{ADWORD, C_NONE, C_NONE, C_LEXT, 11, 8, 0, 0, 0},
@@ -320,6 +320,10 @@
 	{AMOVW, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
 	{AMOVW, C_REG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
 
+	{AVMOVS, C_VREG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
+	{AVMOVS, C_VREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
+	{AVMOVS, C_VREG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
+
 	/* unscaled 9-bit signed displacement store */
 	{AMOVB, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
 	{AMOVB, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
@@ -368,6 +372,10 @@
 	{AMOVD, C_UOREG32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
 	{AMOVD, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
 
+	{AVMOVS, C_UAUTO16K, C_NONE, C_VREG, 21, 4, REGSP, 0, 0},
+	{AVMOVS, C_ZOREG, C_NONE, C_VREG, 21, 4, 0, 0, 0},
+	{AVMOVS, C_UOREG16K, C_NONE, C_VREG, 21, 4, 0, 0, 0},
+
 	/* long displacement store */
 	{AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
 	{AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
@@ -403,6 +411,7 @@
 	{AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
 	{AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
 	{AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
+	{AVMOVS, C_LOREG, C_NONE, C_VREG, 22, 4, 0, 0, C_XPOST},
 	{AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
 	{AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
 	{AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
@@ -410,6 +419,7 @@
 	{AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
 	{AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
 	{AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
+	{AVMOVS, C_LOREG, C_NONE, C_VREG, 22, 4, 0, 0, C_XPRE},
 
 	/* pre/post-indexed store (unscaled, signed 9-bit offset) */
 	{AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
@@ -419,6 +429,7 @@
 	{AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
+	{AVMOVS, C_VREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
@@ -426,13 +437,61 @@
 	{AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
+	{AVMOVS, C_VREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 
-	/* pre/post-indexed load/store register pair
-	   (unscaled, signed 10-bit quad-aligned offset) */
-	{ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
-	{ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
-	{ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPOST},
+	/* pre/post-indexed/signed-offset load/store register pair
+	   (unscaled, signed 10-bit quad-aligned and long offset) */
+	{ALDP, C_NPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
+	{ALDP, C_NPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
+	{ALDP, C_NPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
+	{ALDP, C_PPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
+	{ALDP, C_PPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
+	{ALDP, C_PPAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
+	{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
+	{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
+	{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
+	{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
+	{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPRE},
+	{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPOST},
+	{ALDP, C_NPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
+	{ALDP, C_NPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
+	{ALDP, C_NPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
+	{ALDP, C_PPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
+	{ALDP, C_PPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
+	{ALDP, C_PPOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
+	{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
+	{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
+	{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
+	{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
+	{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPRE},
+	{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPOST},
+	{ALDP, C_ADDR, C_NONE, C_PAIR, 88, 12, 0, 0, 0},
+
+	{ASTP, C_PAIR, C_NONE, C_NPAUTO, 67, 4, REGSP, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_NPAUTO, 67, 4, REGSP, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_NPAUTO, 67, 4, REGSP, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
+	{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_NPOREG, 67, 4, 0, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_PPOREG, 67, 4, 0, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
+	{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
+	{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPRE},
+	{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
 
 	/* special */
 	{AMOVD, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0},
@@ -491,7 +550,7 @@
 	{AFCMPS, C_FREG, C_FREG, C_NONE, 56, 4, 0, 0, 0},
 	{AFCMPS, C_FCON, C_FREG, C_NONE, 56, 4, 0, 0, 0},
 	{AFCCMPS, C_COND, C_FREG, C_VCON, 57, 4, 0, 0, 0},
-	{AFCSELD, C_COND, C_REG, C_FREG, 18, 4, 0, 0, 0},
+	{AFCSELD, C_COND, C_FREG, C_FREG, 18, 4, 0, 0, 0},
 	{AFCVTSD, C_FREG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
 	{ACLREX, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0},
 	{ACLREX, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
@@ -512,8 +571,32 @@
 
 	//	{ ASTXP,		C_REG, C_NONE,	C_ZOREG,		59, 4, 0 , 0}, // TODO(aram):
 
-	{AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0},
+	{AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0}, // for compatibility with old code
+	{AAESD, C_ARNG, C_NONE, C_ARNG, 29, 4, 0, 0, 0}, // recommend using the new one for better readability
 	{ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0},
+	{ASHA1C, C_ARNG, C_VREG, C_VREG, 1, 4, 0, 0, 0},
+	{ASHA1H, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0},
+	{ASHA1SU0, C_ARNG, C_ARNG, C_ARNG, 1, 4, 0, 0, 0},
+	{ASHA256H, C_ARNG, C_VREG, C_VREG, 1, 4, 0, 0, 0},
+	{AVADDP, C_ARNG, C_ARNG, C_ARNG, 72, 4, 0, 0, 0},
+	{AVADD, C_ARNG, C_ARNG, C_ARNG, 72, 4, 0, 0, 0},
+	{AVADD, C_VREG, C_VREG, C_VREG, 89, 4, 0, 0, 0},
+	{AVADD, C_VREG, C_NONE, C_VREG, 89, 4, 0, 0, 0},
+	{AVLD1, C_ZOREG, C_NONE, C_LIST, 81, 4, 0, 0, 0},
+	{AVLD1, C_LOREG, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST},
+	{AVLD1, C_ROFF, C_NONE, C_LIST, 81, 4, 0, 0, C_XPOST},
+	{AVMOV, C_ELEM, C_NONE, C_REG, 73, 4, 0, 0, 0},
+	{AVMOV, C_REG, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
+	{AVMOV, C_ARNG, C_NONE, C_ARNG, 83, 4, 0, 0, 0},
+	{AVMOV, C_REG, C_NONE, C_ELEM, 78, 4, 0, 0, 0},
+	{AVMOV, C_ELEM, C_NONE, C_VREG, 80, 4, 0, 0, 0},
+	{AVREV32, C_ARNG, C_NONE, C_ARNG, 83, 4, 0, 0, 0},
+	{AVST1, C_LIST, C_NONE, C_ZOREG, 84, 4, 0, 0, 0},
+	{AVST1, C_LIST, C_NONE, C_LOREG, 84, 4, 0, 0, C_XPOST},
+	{AVST1, C_LIST, C_NONE, C_ROFF, 84, 4, 0, 0, C_XPOST},
+	{AVDUP, C_ELEM, C_NONE, C_ARNG, 79, 4, 0, 0, 0},
+	{AVADDV, C_ARNG, C_NONE, C_VREG, 85, 4, 0, 0, 0},
+	{AVMOVI, C_ADDCON, C_NONE, C_ARNG, 86, 4, 0, 0, 0},
 
 	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
 	{obj.APCDATA, C_VCON, C_NONE, C_VCON, 0, 0, 0, 0, 0},
@@ -529,14 +612,22 @@
  * valid pstate field values, and value to use in instruction
  */
 var pstatefield = []struct {
-	a uint32
-	b uint32
+	reg int16
+	enc uint32
 }{
 	{REG_SPSel, 0<<16 | 4<<12 | 5<<5},
 	{REG_DAIFSet, 3<<16 | 4<<12 | 6<<5},
 	{REG_DAIFClr, 3<<16 | 4<<12 | 7<<5},
 }
 
+// the System register values, and value to use in instruction
+var systemreg = []struct {
+	reg int16
+	enc uint32
+}{
+	{REG_ELR_EL1, 8<<16 | 4<<12 | 1<<5},
+}
+
 func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 	p := cursym.Func.Text
 	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
@@ -761,6 +852,7 @@
 		fallthrough
 
 	case C_PSAUTO,
+		C_PSAUTO_8,
 		C_PPAUTO,
 		C_UAUTO4K_8,
 		C_UAUTO4K_4,
@@ -777,6 +869,7 @@
 		C_LAUTO,
 		C_PPOREG,
 		C_PSOREG,
+		C_PSOREG_8,
 		C_UOREG4K_8,
 		C_UOREG4K_4,
 		C_UOREG4K_2,
@@ -997,9 +1090,12 @@
 	}
 
 	if l <= 255 {
+		if (l & 7) == 0 {
+			return C_PSAUTO_8
+		}
 		return C_PSAUTO
 	}
-	if l <= 504 && (l&7) == 0 {
+	if l <= 504 && l&7 == 0 {
 		return C_PPAUTO
 	}
 	if l <= 4095 {
@@ -1104,7 +1200,11 @@
 		return C_COND
 	case r == REGSP:
 		return C_RSP
-	case r&REG_EXT != 0:
+	case r >= REG_ARNG && r < REG_ELEM:
+		return C_ARNG
+	case r >= REG_ELEM && r < REG_ELEM_END:
+		return C_ELEM
+	case r >= REG_UXTB && r < REG_SPECIAL:
 		return C_EXTREG
 	case r >= REG_SPECIAL:
 		return C_SPR
@@ -1126,6 +1226,9 @@
 	case obj.TYPE_SHIFT:
 		return C_SHIFT
 
+	case obj.TYPE_REGLIST:
+		return C_LIST
+
 	case obj.TYPE_MEM:
 		switch a.Name {
 		case obj.NAME_EXTERN, obj.NAME_STATIC:
@@ -1167,6 +1270,12 @@
 			return autoclass(c.instoffset)
 
 		case obj.NAME_NONE:
+			if a.Index != 0 {
+				if a.Offset != 0 {
+					return C_GOK
+				}
+				return C_ROFF
+			}
 			c.instoffset = a.Offset
 			return oregclass(c.instoffset)
 		}
@@ -1316,7 +1425,7 @@
 		}
 	}
 
-	c.ctxt.Diag("illegal combination %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type)
+	c.ctxt.Diag("illegal combination: %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type)
 	if ops == nil {
 		ops = optab
 	}
@@ -1396,32 +1505,37 @@
 			return true
 		}
 
+	case C_PSAUTO:
+		if b == C_PSAUTO_8 {
+			return true
+		}
+
 	case C_PPAUTO:
-		if b == C_PSAUTO {
+		if b == C_PSAUTO_8 {
 			return true
 		}
 
 	case C_UAUTO4K:
 		switch b {
-		case C_PSAUTO, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8:
+		case C_PSAUTO, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8:
 			return true
 		}
 
 	case C_UAUTO8K:
 		switch b {
-		case C_PSAUTO, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8:
+		case C_PSAUTO, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8:
 			return true
 		}
 
 	case C_UAUTO16K:
 		switch b {
-		case C_PSAUTO, C_PPAUTO, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO16K_8:
+		case C_PSAUTO, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO16K_8:
 			return true
 		}
 
 	case C_UAUTO32K:
 		switch b {
-		case C_PSAUTO, C_PPAUTO, C_UAUTO4K_8, C_UAUTO8K_8, C_UAUTO16K_8:
+		case C_PSAUTO, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_8, C_UAUTO8K_8, C_UAUTO16K_8:
 			return true
 		}
 
@@ -1430,7 +1544,7 @@
 
 	case C_LAUTO:
 		switch b {
-		case C_PSAUTO, C_PPAUTO,
+		case C_PSAUTO, C_PSAUTO_8, C_PPAUTO,
 			C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8,
 			C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8,
 			C_UAUTO16K, C_UAUTO16K_8,
@@ -1440,36 +1554,37 @@
 		return cmp(C_NPAUTO, b)
 
 	case C_PSOREG:
-		if b == C_ZOREG {
+		if b == C_ZOREG || b == C_PSOREG_8 {
 			return true
 		}
 
 	case C_PPOREG:
-		if b == C_ZOREG || b == C_PSOREG {
+		switch b {
+		case C_ZOREG, C_PSOREG_8:
 			return true
 		}
 
 	case C_UOREG4K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8:
+		case C_ZOREG, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8:
 			return true
 		}
 
 	case C_UOREG8K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8:
+		case C_ZOREG, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8:
 			return true
 		}
 
 	case C_UOREG16K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PPOREG, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8, C_UOREG16K_8:
+		case C_ZOREG, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8, C_UOREG16K_8:
 			return true
 		}
 
 	case C_UOREG32K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PPOREG, C_UOREG4K_8, C_UOREG8K_8, C_UOREG16K_8:
+		case C_ZOREG, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_8, C_UOREG8K_8, C_UOREG16K_8:
 			return true
 		}
 
@@ -1478,7 +1593,7 @@
 
 	case C_LOREG:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PPOREG,
+		case C_ZOREG, C_PSOREG_8, C_PSOREG, C_PPOREG,
 			C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8,
 			C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8,
 			C_UOREG16K, C_UOREG16K_8,
@@ -1562,6 +1677,7 @@
 		switch r {
 		default:
 			ctxt.Diag("unknown op in build: %v", r)
+			ctxt.DiagFlush()
 			log.Fatalf("bad code")
 
 		case AADD:
@@ -1817,8 +1933,8 @@
 			break
 
 		case ASVC:
-			oprangeset(AHLT, t)
 			oprangeset(AHVC, t)
+			oprangeset(AHLT, t)
 			oprangeset(ASMC, t)
 			oprangeset(ABRK, t)
 			oprangeset(ADCPS1, t)
@@ -1954,22 +2070,45 @@
 		case ASTXP:
 			oprangeset(ASTXPW, t)
 
+		case AVADDP:
+			oprangeset(AVAND, t)
+			oprangeset(AVCMEQ, t)
+			oprangeset(AVORR, t)
+			oprangeset(AVEOR, t)
+
+		case AVADD:
+			oprangeset(AVSUB, t)
+
 		case AAESD:
 			oprangeset(AAESE, t)
 			oprangeset(AAESMC, t)
 			oprangeset(AAESIMC, t)
-			oprangeset(ASHA1H, t)
 			oprangeset(ASHA1SU1, t)
 			oprangeset(ASHA256SU0, t)
 
 		case ASHA1C:
 			oprangeset(ASHA1P, t)
 			oprangeset(ASHA1M, t)
-			oprangeset(ASHA1SU0, t)
-			oprangeset(ASHA256H, t)
+
+		case ASHA256H:
 			oprangeset(ASHA256H2, t)
+
+		case ASHA1SU0:
 			oprangeset(ASHA256SU1, t)
 
+		case AVADDV:
+			oprangeset(AVUADDLV, t)
+
+		case ASHA1H,
+			AVMOV,
+			AVLD1,
+			AVREV32,
+			AVST1,
+			AVDUP,
+			AVMOVS,
+			AVMOVI:
+			break
+
 		case obj.ANOP,
 			obj.AUNDEF,
 			obj.AFUNCDATA,
@@ -2185,8 +2324,8 @@
 	case 10: /* brk/hvc/.../svc [$con] */
 		o1 = c.opimm(p, p.As)
 
-		if p.To.Type != obj.TYPE_NONE {
-			o1 |= uint32((p.To.Offset & 0xffff) << 5)
+		if p.From.Type != obj.TYPE_NONE {
+			o1 |= uint32((p.From.Offset & 0xffff) << 5)
 		}
 
 	case 11: /* dword */
@@ -2223,7 +2362,7 @@
 			r = rt
 		}
 		if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
-			o2 = c.opxrrr(p, p.As)
+			o2 = c.opxrrr(p, p.As, false)
 			o2 |= REGTMP & 31 << 16
 			o2 |= LSL0_64
 		} else {
@@ -2260,7 +2399,7 @@
 		var r int
 		var ra int
 		if p.From3Type() == obj.TYPE_REG {
-			r = int(p.From3.Reg)
+			r = int(p.GetFrom3().Reg)
 			ra = int(p.Reg)
 			if ra == 0 {
 				ra = REGZERO
@@ -2322,7 +2461,7 @@
 
 				cond ^= 1
 			} else {
-				rf = int(p.From3.Reg) /* CSEL */
+				rf = int(p.GetFrom3().Reg) /* CSEL */
 			}
 		} else {
 			/* CSET */
@@ -2347,12 +2486,12 @@
 			cond -= COND_EQ
 		}
 		var rf int
-		if p.From3.Type == obj.TYPE_REG {
+		if p.GetFrom3().Type == obj.TYPE_REG {
 			o1 = c.oprrr(p, p.As)
-			rf = int(p.From3.Reg) /* Rm */
+			rf = int(p.GetFrom3().Reg) /* Rm */
 		} else {
 			o1 = c.opirr(p, p.As)
-			rf = int(p.From3.Offset & 0x1F)
+			rf = int(p.GetFrom3().Offset & 0x1F)
 		}
 
 		o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
@@ -2392,7 +2531,7 @@
 		v := int32(p.From.Offset)
 
 		if v < -256 || v > 255 {
-			c.ctxt.Diag("offset out of range\n%v", p)
+			c.ctxt.Diag("offset out of range [-255,254]: %v", p)
 		}
 		o1 = c.opldrpp(p, p.As)
 		if o.scond == C_XPOST {
@@ -2406,7 +2545,7 @@
 		v := int32(p.To.Offset)
 
 		if v < -256 || v > 255 {
-			c.ctxt.Diag("offset out of range\n%v", p)
+			c.ctxt.Diag("offset out of range [-255,254]: %v", p)
 		}
 		o1 = LD2STR(c.opldrpp(p, p.As))
 		if o.scond == C_XPOST {
@@ -2452,12 +2591,16 @@
 		o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
 
 	case 27: /* op Rm<<n[,Rn],Rd (extended register) */
-		o1 = c.opxrrr(p, p.As)
 
 		if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 {
-			c.ctxt.Diag("extended register not implemented\n%v", p)
-			// o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
+			amount := (p.From.Reg >> 5) & 7
+			if amount > 4 {
+				c.ctxt.Diag("shift amount out of range 0 to 4: %v", p)
+			}
+			o1 = c.opxrrr(p, p.As, true)
+			o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
 		} else {
+			o1 = c.opxrrr(p, p.As, false)
 			o1 |= uint32(p.From.Reg&31) << 16
 		}
 		rt := int(p.To.Reg)
@@ -2597,22 +2740,19 @@
 		o1 = c.opirr(p, p.As)
 
 		d := p.From.Offset
-		if (d >> 16) != 0 {
+		s := movcon(d)
+		if s < 0 || s >= 4 {
+			c.ctxt.Diag("bad constant for MOVK: %#x\n%v", uint64(d), p)
+		}
+		if (o1&S64) == 0 && s >= 2 {
+			c.ctxt.Diag("illegal bit position\n%v", p)
+		}
+		if ((d >> uint(s*16)) >> 16) != 0 {
 			c.ctxt.Diag("requires uimm16\n%v", p)
 		}
-		s := 0
-		if p.From3Type() != obj.TYPE_NONE {
-			if p.From3.Type != obj.TYPE_CONST {
-				c.ctxt.Diag("missing bit position\n%v", p)
-			}
-			s = int(p.From3.Offset / 16)
-			if (s*16&0xF) != 0 || s >= 4 || (o1&S64) == 0 && s >= 2 {
-				c.ctxt.Diag("illegal bit position\n%v", p)
-			}
-		}
-
 		rt := int(p.To.Reg)
-		o1 |= uint32(((d & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
+
+		o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
 
 	case 34: /* mov $lacon,R */
 		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
@@ -2620,7 +2760,7 @@
 		if !(o1 != 0) {
 			break
 		}
-		o2 = c.opxrrr(p, AADD)
+		o2 = c.opxrrr(p, AADD, false)
 		o2 |= REGTMP & 31 << 16
 		o2 |= LSL0_64
 		r := int(p.From.Reg)
@@ -2633,21 +2773,41 @@
 	case 35: /* mov SPR,R -> mrs */
 		o1 = c.oprrr(p, AMRS)
 
-		v := int32(p.From.Offset)
+		v := uint32(0)
+		for i := 0; i < len(systemreg); i++ {
+			if systemreg[i].reg == p.From.Reg {
+				v = systemreg[i].enc
+				break
+			}
+		}
+		if v == 0 {
+			c.ctxt.Diag("illegal system register:\n%v", p)
+		}
 		if (o1 & uint32(v&^(3<<19))) != 0 {
 			c.ctxt.Diag("MRS register value overlap\n%v", p)
 		}
-		o1 |= uint32(v)
+
+		o1 |= v
 		o1 |= uint32(p.To.Reg & 31)
 
 	case 36: /* mov R,SPR */
 		o1 = c.oprrr(p, AMSR)
 
-		v := int32(p.To.Offset)
+		v := uint32(0)
+		for i := 0; i < len(systemreg); i++ {
+			if systemreg[i].reg == p.To.Reg {
+				v = systemreg[i].enc
+				break
+			}
+		}
+		if v == 0 {
+			c.ctxt.Diag("illegal system register:\n%v", p)
+		}
 		if (o1 & uint32(v&^(3<<19))) != 0 {
 			c.ctxt.Diag("MSR register value overlap\n%v", p)
 		}
-		o1 |= uint32(v)
+
+		o1 |= v
 		o1 |= uint32(p.From.Reg & 31)
 
 	case 37: /* mov $con,PSTATEfield -> MSR [immediate] */
@@ -2656,10 +2816,10 @@
 		}
 		o1 = c.opirr(p, AMSR)
 		o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
-		v := int32(0)
+		v := uint32(0)
 		for i := 0; i < len(pstatefield); i++ {
-			if int64(pstatefield[i].a) == p.To.Offset {
-				v = int32(pstatefield[i].b)
+			if pstatefield[i].reg == p.To.Reg {
+				v = pstatefield[i].enc
 				break
 			}
 		}
@@ -2667,7 +2827,7 @@
 		if v == 0 {
 			c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
 		}
-		o1 |= uint32(v)
+		o1 |= v
 
 	case 38: /* clrex [$imm] */
 		o1 = c.opimm(p, p.As)
@@ -2699,12 +2859,12 @@
 		o1 = c.op0(p, p.As)
 
 	case 42: /* bfm R,r,s,R */
-		o1 = c.opbfm(p, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg))
+		o1 = c.opbfm(p, p.As, int(p.From.Offset), int(p.GetFrom3().Offset), int(p.Reg), int(p.To.Reg))
 
 	case 43: /* bfm aliases */
 		r := int(p.From.Offset)
 
-		s := int(p.From3.Offset)
+		s := int(p.GetFrom3().Offset)
 		rf := int(p.Reg)
 		rt := int(p.To.Reg)
 		if rf == 0 {
@@ -2753,7 +2913,7 @@
 		}
 
 	case 44: /* extr $b, Rn, Rm, Rd */
-		o1 = c.opextr(p, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg))
+		o1 = c.opextr(p, p.As, int32(p.From.Offset), int(p.GetFrom3().Reg), int(p.Reg), int(p.To.Reg))
 
 	case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */
 		rf := int(p.From.Reg)
@@ -2885,7 +3045,7 @@
 		o1 = c.oprrr(p, p.As)
 
 		var rf int
-		if p.From.Type == obj.TYPE_CONST {
+		if p.From.Type == obj.TYPE_FCONST {
 			o1 |= 8 /* zero */
 			rf = 0
 		} else {
@@ -2909,11 +3069,11 @@
 			c.ctxt.Diag("implausible condition\n%v", p)
 		}
 		rf := int(p.Reg)
-		if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
+		if p.GetFrom3() == nil || p.GetFrom3().Reg < REG_F0 || p.GetFrom3().Reg > REG_F31 {
 			c.ctxt.Diag("illegal FCCMP\n%v", p)
 			break
 		}
-		rt := int(p.From3.Reg)
+		rt := int(p.GetFrom3().Reg)
 		o1 |= uint32(rf&31)<<16 | uint32(cond&15)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
 
 	case 58: /* ldar/ldxr/ldaxr */
@@ -2967,7 +3127,7 @@
 			r = rt
 		}
 		if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
-			o2 = c.opxrrr(p, p.As)
+			o2 = c.opxrrr(p, p.As, false)
 			o2 |= REGTMP & 31 << 16
 			o2 |= LSL0_64
 		} else {
@@ -3001,31 +3161,50 @@
 		o3 = c.olsr12u(p, int32(c.opldr12(p, p.As)), 0, REGTMP, int(p.To.Reg))
 
 	case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
-		v := int32(p.From.Offset)
+		v := int32(c.regoff(&p.From))
+		r := int(p.From.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
+		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid ldp source: %v\n", p)
+		}
 
-		if v < -512 || v > 504 {
-			c.ctxt.Diag("offset out of range\n%v", p)
+		if v < -512 || v > 504 || v%8 != 0 {
+			c.ctxt.Diag("invalid offset %v\n", p)
 		}
 		if o.scond == C_XPOST {
 			o1 |= 1 << 23
-		} else {
+		} else if o.scond == C_XPRE {
 			o1 |= 3 << 23
+		} else {
+			o1 |= 2 << 23
 		}
 		o1 |= 1 << 22
-		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.To.Offset<<10 | int64(uint32(p.From.Reg&31)<<5) | int64(p.To.Reg&31))
+		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | (p.To.Offset&31)<<10 | int64(uint32(r&31)<<5) | int64(p.To.Reg&31))
 
 	case 67: /* stp (r1, r2), O(R)!; stp (r1, r2), (R)O! */
-		v := int32(p.To.Offset)
-
-		if v < -512 || v > 504 {
-			c.ctxt.Diag("offset out of range\n%v", p)
+		r := int(p.To.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
 		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid stp destination: %v\n", p)
+		}
+
+		v := int32(c.regoff(&p.To))
+		if v < -512 || v > 504 || v%8 != 0 {
+			c.ctxt.Diag("invalid offset %v\n", p)
+		}
+
 		if o.scond == C_XPOST {
 			o1 |= 1 << 23
-		} else {
+		} else if o.scond == C_XPRE {
 			o1 |= 3 << 23
+		} else {
+			o1 |= 2 << 23
 		}
-		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.From.Offset<<10 | int64(uint32(p.To.Reg&31)<<5) | int64(p.From.Reg&31))
+		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | (p.From.Offset&31)<<10 | int64(uint32(r&31)<<5) | int64(p.From.Reg&31))
 
 	case 68: /* movT $vconaddr(SB), reg -> adrp + add + reloc */
 		if p.As == AMOVW {
@@ -3075,6 +3254,474 @@
 		rel.Add = 0
 		rel.Type = objabi.R_ARM64_GOTPCREL
 
+	case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor Vm.<T>, Vn.<T>, Vd.<T> */
+		af := int((p.From.Reg >> 5) & 15)
+		af3 := int((p.Reg >> 5) & 15)
+		at := int((p.To.Reg >> 5) & 15)
+		if af != af3 || af != at {
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+		o1 = c.oprrr(p, p.As)
+		rf := int((p.From.Reg) & 31)
+		rt := int((p.To.Reg) & 31)
+		r := int((p.Reg) & 31)
+
+		Q := 0
+		size := 0
+		switch af {
+		case ARNG_16B:
+			Q = 1
+			size = 0
+		case ARNG_2D:
+			Q = 1
+			size = 3
+		case ARNG_2S:
+			Q = 0
+			size = 2
+		case ARNG_4H:
+			Q = 0
+			size = 1
+		case ARNG_4S:
+			Q = 1
+			size = 2
+		case ARNG_8B:
+			Q = 0
+			size = 0
+		case ARNG_8H:
+			Q = 1
+			size = 1
+		default:
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+
+		if (p.As == AVORR || p.As == AVAND || p.As == AVEOR) &&
+			(af != ARNG_16B && af != ARNG_8B) {
+			c.ctxt.Diag("invalid arrangement on op %v", p.As)
+		} else if p.As == AVORR {
+			size = 2
+		} else if p.As == AVAND || p.As == AVEOR {
+			size = 0
+		}
+
+		o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
+
+	case 73: /* vmov V.<T>[index], R */
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		imm5 := 0
+		o1 = 7<<25 | 0xf<<10
+		switch (p.From.Reg >> 5) & 15 {
+		case ARNG_B:
+			imm5 |= 1
+			imm5 |= int(p.From.Index) << 1
+		case ARNG_H:
+			imm5 |= 2
+			imm5 |= int(p.From.Index) << 2
+		case ARNG_S:
+			imm5 |= 4
+			imm5 |= int(p.From.Index) << 3
+		case ARNG_D:
+			imm5 |= 8
+			imm5 |= int(p.From.Index) << 4
+			o1 |= 1 << 30
+		default:
+			c.ctxt.Diag("invalid arrangement on op V.<T>[index], R: %v\n", p)
+		}
+		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 74:
+		//	add $O, R, Rtmp
+		//	ldp (Rtmp), (R1, R2)
+		r := int(p.From.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
+		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid ldp source: %v\n", p)
+		}
+
+		v := int32(c.regoff(&p.From))
+		if v < 0 || v > 4095 {
+			c.ctxt.Diag("offset out of range%v\n", p)
+		}
+
+		if o.scond == C_XPOST {
+			o2 |= 1 << 23
+		} else if o.scond == C_XPRE {
+			o2 |= 3 << 23
+		} else {
+			o2 |= 2 << 23
+		}
+
+		o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
+		o2 |= 1 << 22
+		o2 |= uint32(int64(2<<30|5<<27) | (p.To.Offset&31)<<10 | int64(uint32(REGTMP&31)<<5) | int64(p.To.Reg&31))
+
+	case 75:
+		//	mov $L, Rtmp (from constant pool)
+		//	add Rtmp, R, Rtmp
+		//	ldp (Rtmp), (R1, R2)
+		r := int(p.From.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
+		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid ldp source: %v\n", p)
+		}
+
+		if o.scond == C_XPOST {
+			o3 |= 1 << 23
+		} else if o.scond == C_XPRE {
+			o3 |= 3 << 23
+		} else {
+			o3 |= 2 << 23
+		}
+
+		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
+		o2 = c.opxrrr(p, AADD, false)
+		o2 |= (REGTMP & 31) << 16
+		o2 |= uint32(r&31) << 5
+		o2 |= uint32(REGTMP & 31)
+		o3 |= 1 << 22
+		o3 |= uint32(int64(2<<30|5<<27) | (p.To.Offset&31)<<10 | int64(uint32(REGTMP&31)<<5) | int64(p.To.Reg&31))
+
+	case 76:
+		//	add $O, R, Rtmp
+		//	stp (R1, R2), (Rtmp)
+		r := int(p.To.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
+		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid stp destination: %v\n", p)
+		}
+
+		v := int32(c.regoff(&p.To))
+		if v < 0 || v > 4095 {
+			c.ctxt.Diag("offset out of range%v\n", p)
+		}
+		if o.scond == C_XPOST {
+			o2 |= 1 << 23
+		} else if o.scond == C_XPRE {
+			o2 |= 3 << 23
+		} else {
+			o2 |= 2 << 23
+		}
+
+		o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
+		o2 |= uint32(int64(2<<30|5<<27) | (p.From.Offset&31)<<10 | int64(uint32(REGTMP&31)<<5) | int64(p.From.Reg&31))
+
+	case 77:
+		//	mov $L, Rtmp (from constant pool)
+		//	add Rtmp, R, Rtmp
+		//	stp (R1, R2), (Rtmp)
+		r := int(p.To.Reg)
+		if r == obj.REG_NONE {
+			r = int(o.param)
+		}
+		if r == obj.REG_NONE {
+			c.ctxt.Diag("invalid stp destination: %v\n", p)
+		}
+
+		if o.scond == C_XPOST {
+			o3 |= 1 << 23
+		} else if o.scond == C_XPRE {
+			o3 |= 3 << 23
+		} else {
+			o3 |= 2 << 23
+		}
+		o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
+		o2 = c.opxrrr(p, AADD, false)
+		o2 |= REGTMP & 31 << 16
+		o2 |= uint32(r&31) << 5
+		o2 |= uint32(REGTMP & 31)
+		o3 |= uint32(int64(2<<30|5<<27) | (p.From.Offset&31)<<10 | int64(uint32(REGTMP&31)<<5) | int64(p.From.Reg&31))
+
+	case 78: /* vmov R, V.<T>[index] */
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		imm5 := 0
+		o1 = 1<<30 | 7<<25 | 7<<10
+		switch (p.To.Reg >> 5) & 15 {
+		case ARNG_B:
+			imm5 |= 1
+			imm5 |= int(p.From.Index) << 1
+		case ARNG_H:
+			imm5 |= 2
+			imm5 |= int(p.From.Index) << 2
+		case ARNG_S:
+			imm5 |= 4
+			imm5 |= int(p.From.Index) << 3
+		case ARNG_D:
+			imm5 |= 8
+			imm5 |= int(p.From.Index) << 4
+		default:
+			c.ctxt.Diag("invalid arrangement on op R, V.<T>[index]: %v\n", p)
+		}
+		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 79: /* vdup Vn.<T>[index], Vd.<T> */
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		o1 = 7<<25 | 1<<10
+		var imm5, Q uint32
+		switch (p.To.Reg >> 5) & 15 {
+		case ARNG_16B:
+			Q = 1
+			imm5 = 1
+			imm5 |= uint32(p.From.Index) << 1
+		case ARNG_2D:
+			Q = 1
+			imm5 = 8
+			imm5 |= uint32(p.From.Index) << 4
+		case ARNG_2S:
+			Q = 0
+			imm5 = 4
+			imm5 |= uint32(p.From.Index) << 3
+		case ARNG_4H:
+			Q = 0
+			imm5 = 2
+			imm5 |= uint32(p.From.Index) << 2
+		case ARNG_4S:
+			Q = 1
+			imm5 = 4
+			imm5 |= uint32(p.From.Index) << 3
+		case ARNG_8B:
+			Q = 0
+			imm5 = 1
+			imm5 |= uint32(p.From.Index) << 1
+		case ARNG_8H:
+			Q = 1
+			imm5 = 2
+			imm5 |= uint32(p.From.Index) << 2
+		default:
+			c.ctxt.Diag("invalid arrangement on VDUP Vn.<T>[index], Vd.<T>: %v\n", p)
+		}
+		o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16)
+		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 80: /* vmov V.<T>[index], Vn */
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		imm5 := 0
+		switch p.As {
+		case AVMOV:
+			o1 = 1<<30 | 15<<25 | 1<<10
+			switch (p.From.Reg >> 5) & 15 {
+			case ARNG_B:
+				imm5 |= 1
+				imm5 |= int(p.From.Index) << 1
+			case ARNG_H:
+				imm5 |= 2
+				imm5 |= int(p.From.Index) << 2
+			case ARNG_S:
+				imm5 |= 4
+				imm5 |= int(p.From.Index) << 3
+			case ARNG_D:
+				imm5 |= 8
+				imm5 |= int(p.From.Index) << 4
+			default:
+				c.ctxt.Diag("invalid arrangement on op V.<T>[index], Vn: %v\n", p)
+			}
+		default:
+			c.ctxt.Diag("unsupported op %v", p.As)
+		}
+		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 81: /* vld1 (Rn), [Vt1.<T>, Vt2.<T>, ...] */
+		r := int(p.From.Reg)
+		o1 = 3<<26 | 1<<22
+		if o.scond == C_XPOST {
+			o1 |= 1 << 23
+			if p.From.Index == 0 {
+				// immediate offset variant
+				o1 |= 0x1f << 16
+			} else {
+				// register offset variant
+				o1 |= uint32(p.From.Index&31) << 16
+			}
+		}
+		o1 |= uint32(p.To.Offset)
+		o1 |= uint32(r&31) << 5
+
+	case 82: /* vmov Rn, Vd.<T> */
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		o1 = 7<<25 | 3<<10
+		var imm5, Q uint32
+		switch (p.To.Reg >> 5) & 15 {
+		case ARNG_16B:
+			Q = 1
+			imm5 = 1
+		case ARNG_2D:
+			Q = 1
+			imm5 = 8
+		case ARNG_2S:
+			Q = 0
+			imm5 = 4
+		case ARNG_4H:
+			Q = 0
+			imm5 = 2
+		case ARNG_4S:
+			Q = 1
+			imm5 = 4
+		case ARNG_8B:
+			Q = 0
+			imm5 = 1
+		case ARNG_8H:
+			Q = 1
+			imm5 = 2
+		default:
+			c.ctxt.Diag("invalid arrangement on VMOV Rn, Vd.<T>: %v\n", p)
+		}
+		o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16)
+		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 83: /* vmov Vn.<T>, Vd.<T> */
+		af := int((p.From.Reg >> 5) & 15)
+		at := int((p.To.Reg >> 5) & 15)
+		if af != at {
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+		o1 = c.oprrr(p, p.As)
+		rf := int((p.From.Reg) & 31)
+		rt := int((p.To.Reg) & 31)
+
+		Q := 0
+		size := 0
+		switch af {
+		case ARNG_8B:
+			Q = 0
+			size = 0
+		case ARNG_16B:
+			Q = 1
+			size = 0
+		case ARNG_4H:
+			Q = 0
+			size = 1
+		case ARNG_8H:
+			Q = 1
+			size = 1
+		default:
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+
+		if (p.As == AVMOV) && (af != ARNG_16B && af != ARNG_8B) {
+			c.ctxt.Diag("invalid arrangement on op %v", p.As)
+		}
+
+		if p.As == AVMOV {
+			o1 |= uint32(rf&31) << 16
+		}
+
+		o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 84: /* vst1 [Vt1.<T>, Vt2.<T>, ...], (Rn) */
+		r := int(p.To.Reg)
+		o1 = 3 << 26
+		if o.scond == C_XPOST {
+			o1 |= 1 << 23
+			if p.To.Index == 0 {
+				// immediate offset variant
+				o1 |= 0x1f << 16
+			} else {
+				// register offset variant
+				o1 |= uint32(p.To.Index&31) << 16
+			}
+		}
+		o1 |= uint32(p.From.Offset)
+		o1 |= uint32(r&31) << 5
+
+	case 85: /* vaddv/vuaddlv Vn.<T>, Vd*/
+		af := int((p.From.Reg >> 5) & 15)
+		o1 = c.oprrr(p, p.As)
+		rf := int((p.From.Reg) & 31)
+		rt := int((p.To.Reg) & 31)
+		Q := 0
+		size := 0
+		switch af {
+		case ARNG_8B:
+			Q = 0
+			size = 0
+		case ARNG_16B:
+			Q = 1
+			size = 0
+		case ARNG_4H:
+			Q = 0
+			size = 1
+		case ARNG_8H:
+			Q = 1
+			size = 1
+		case ARNG_4S:
+			Q = 1
+			size = 2
+		default:
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+		o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 5) | uint32(rt&31)
+
+	case 86: /* vmovi $imm8, Vd.<T>*/
+		at := int((p.To.Reg >> 5) & 15)
+		r := int(p.From.Offset)
+		if r > 255 || r < 0 {
+			c.ctxt.Diag("immediate constant out of range: %v\n", p)
+		}
+		rt := int((p.To.Reg) & 31)
+		Q := 0
+		switch at {
+		case ARNG_8B:
+			Q = 0
+		case ARNG_16B:
+			Q = 1
+		default:
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
+		}
+		o1 = 0xf<<24 | 0xe<<12 | 1<<10
+		o1 |= (uint32(Q&1) << 30) | (uint32((r>>5)&7) << 16) | (uint32(r&0x1f) << 5) | uint32(rt&31)
+
+	case 87: /* stp (r,r), addr(SB) -> adrp + add + stp */
+		o1 = ADR(1, 0, REGTMP)
+		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
+		rel := obj.Addrel(c.cursym)
+		rel.Off = int32(c.pc)
+		rel.Siz = 8
+		rel.Sym = p.To.Sym
+		rel.Add = p.To.Offset
+		rel.Type = objabi.R_ADDRARM64
+		o3 |= 2<<30 | 5<<27 | 2<<23 | uint32(p.From.Offset&31)<<10 | (REGTMP&31)<<5 | uint32(p.From.Reg&31)
+
+	case 88: /* ldp addr(SB), (r,r) -> adrp + add + ldp */
+		o1 = ADR(1, 0, REGTMP)
+		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
+		rel := obj.Addrel(c.cursym)
+		rel.Off = int32(c.pc)
+		rel.Siz = 8
+		rel.Sym = p.From.Sym
+		rel.Add = p.From.Offset
+		rel.Type = objabi.R_ADDRARM64
+		o3 |= 2<<30 | 5<<27 | 2<<23 | 1<<22 | uint32(p.To.Offset&31)<<10 | (REGTMP&31)<<5 | uint32(p.To.Reg&31)
+
+	case 89: /* vadd/vsub Vm, Vn, Vd */
+		switch p.As {
+		case AVADD:
+			o1 = 5<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
+
+		case AVSUB:
+			o1 = 7<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
+
+		default:
+			c.ctxt.Diag("bad opcode: %v\n", p)
+			break
+		}
+
+		rf := int(p.From.Reg)
+		rt := int(p.To.Reg)
+		r := int(p.Reg)
+		if r == 0 {
+			r = rt
+		}
+		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
+
 	// This is supposed to be something that stops execution.
 	// It's not supposed to be reached, ever, but if it is, we'd
 	// like to be able to tell how we got there. Assemble as
@@ -3098,6 +3745,7 @@
  * basic Rm op Rn -> Rd (using shifted register with 0)
  * also op Rn -> Rt
  * also Rm*Rn op Ra -> Rd
+ * also Vm op Vn -> Vd
  */
 func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 {
 	switch a {
@@ -3611,6 +4259,36 @@
 
 	case AFCVTHD:
 		return FPOP1S(0, 0, 3, 5)
+
+	case AVADD:
+		return 7<<25 | 1<<21 | 1<<15 | 1<<10
+
+	case AVADDP:
+		return 7<<25 | 1<<21 | 1<<15 | 15<<10
+
+	case AVAND:
+		return 7<<25 | 1<<21 | 7<<10
+
+	case AVCMEQ:
+		return 1<<29 | 0x71<<21 | 0x23<<10
+
+	case AVEOR:
+		return 1<<29 | 0x71<<21 | 7<<10
+
+	case AVORR:
+		return 7<<25 | 5<<21 | 7<<10
+
+	case AVREV32:
+		return 11<<26 | 2<<24 | 1<<21 | 1<<11
+
+	case AVMOV:
+		return 7<<25 | 5<<21 | 7<<10
+
+	case AVADDV:
+		return 7<<25 | 3<<20 | 3<<15 | 7<<11
+
+	case AVUADDLV:
+		return 1<<29 | 7<<25 | 3<<20 | 7<<11
 	}
 
 	c.ctxt.Diag("%v: bad rrr %d %v", p, a, a)
@@ -3845,33 +4523,44 @@
 }
 
 /*
- * add/subtract extended register
+ * add/subtract sign or zero-extended register
  */
-func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As) uint32 {
+func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 {
+	extension := uint32(0)
+	if !extend {
+		switch a {
+		case AADD, ACMN, AADDS, ASUB, ACMP, ASUBS:
+			extension = LSL0_64
+
+		case AADDW, ACMNW, AADDSW, ASUBW, ACMPW, ASUBSW:
+			extension = LSL0_32
+		}
+	}
+
 	switch a {
 	case AADD:
-		return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
+		return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case AADDW:
-		return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
+		return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ACMN, AADDS:
-		return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
+		return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ACMNW, AADDSW:
-		return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
+		return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ASUB:
-		return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
+		return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ASUBW:
-		return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
+		return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ACMP, ASUBS:
-		return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
+		return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 
 	case ACMPW, ASUBSW:
-		return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
+		return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
 	}
 
 	c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
@@ -4215,6 +4904,9 @@
 
 	case AFMOVD:
 		return LDSTR12U(3, 1, 1)
+
+	case AVMOVS:
+		return LDSTR12U(2, 1, 1)
 	}
 
 	c.ctxt.Diag("bad opldr12 %v\n%v", a, p)
@@ -4298,6 +4990,9 @@
 
 	case AMOVBU:
 		return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
+
+	case AVMOVS:
+		return 2<<30 | 7<<27 | 1<<26 | 0<<24 | 1<<22
 	}
 
 	c.ctxt.Diag("bad opldr %v\n%v", a, p)
@@ -4517,7 +5212,7 @@
 	case AMOVD:
 		return 3
 
-	case AMOVW, AMOVWU:
+	case AMOVW, AMOVWU, AVMOVS:
 		return 2
 
 	case AMOVH, AMOVHU:
diff --git a/src/cmd/internal/obj/arm64/doc.go b/src/cmd/internal/obj/arm64/doc.go
new file mode 100644
index 0000000..f75f49f
--- /dev/null
+++ b/src/cmd/internal/obj/arm64/doc.go
@@ -0,0 +1,157 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64
+
+/*
+
+Go Assembly for ARM64 Reference Manual
+
+1. Alphabetical list of basic instructions
+    // TODO
+
+2. Alphabetical list of float-point instructions
+    // TODO
+
+3. Alphabetical list of SIMD instructions
+    VADD: Add (scalar)
+      VADD	<Vm>, <Vn>, <Vd>
+        Add corresponding low 64-bit elements in <Vm> and <Vn>,
+        place the result into low 64-bit element of <Vd>.
+
+    VADD: Add (vector).
+      VADD	<Vm>.T, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        8B, 16B, H4, H8, S2, S4, D2
+
+    VADDP: Add Pairwise (vector)
+      VADDP	<Vm>.<T>, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8, S2, S4, D2
+
+    VADDV: Add across Vector.
+      VADDV	<Vn>.<T>, Vd
+        <T> Is an arrangement specifier and can have the following values:
+        8B, 16B, H4, H8, S4
+
+    VAND: Bitwise AND (vector)
+      VAND	<Vm>.<T>, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16
+
+    VCMEQ: Compare bitwise Equal (vector)
+      VCMEQ	<Vm>.<T>, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8, S2, S4, D2
+
+    VDUP: Duplicate vector element to vector or scalar.
+      VDUP	<Vn>.<Ts>[index], <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        8B, 16B, H4, H8, S2, S4, D2
+        <Ts> Is an element size specifier and can have the following values:
+        B, H, S, D
+
+    VEOR: Bitwise exclusive OR (vector, register)
+      VEOR	<Vm>.<T>, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16
+
+    VLD1: Load multiple single-element structures
+      VLD1	(Rn), [<Vt>.<T>, <Vt2>.<T> ...]     // no offset
+      VLD1.P	imm(Rn), [<Vt>.<T>, <Vt2>.<T> ...]  // immediate offset variant
+      VLD1.P	(Rn)(Rm), [<Vt>.<T>, <Vt2>.<T> ...] // register offset variant
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8, S2, S4, D1, D2
+
+    VMOV: move
+      VMOV	<Vn>.<T>[index], Rd // Move vector element to general-purpose register.
+        <T> Is a source width specifier and can have the following values:
+        B, H, S (Wd)
+        D (Xd)
+
+      VMOV	Rn, <Vd>.<T> // Duplicate general-purpose register to vector.
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8, S2, S4 (Wn)
+        D2 (Xn)
+
+      VMOV	<Vn>.<T>, <Vd>.<T> // Move vector.
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16
+
+      VMOV	Rn, <Vd>.<T>[index] // Move general-purpose register to a vector element.
+        <T> Is a source width specifier and can have the following values:
+        B, H, S (Wd)
+        D (Xd)
+
+      VMOV	<Vn>.<T>[index], Vn  // Move vector element to scalar.
+        <T> Is an element size specifier and can have the following values:
+        B, H, S, D
+
+    VMOVI: Move Immediate (vector).
+      VMOVI	$imm8, <Vd>.<T>
+        <T> is an arrangement specifier and can have the following values:
+        8B, 16B
+
+    VMOVS: Load SIMD&FP Register (immediate offset). ARMv8: LDR (immediate, SIMD&FP)
+      Store SIMD&FP register (immediate offset). ARMv8: STR (immediate, SIMD&FP)
+      VMOVS	(Rn), Vn
+      VMOVS.W	imm(Rn), Vn
+      VMOVS.P	imm(Rn), Vn
+      VMOVS	Vn, (Rn)
+      VMOVS.W	Vn, imm(Rn)
+      VMOVS.P	Vn, imm(Rn)
+
+    VORR: Bitwise inclusive OR (vector, register)
+      VORR	<Vm>.<T>, <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16
+
+    VREV32: Reverse elements in 32-bit words (vector).
+      REV32 <Vn>.<T>, <Vd>.<T>
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8
+
+    VST1: Store multiple single-element structures
+      VST1	[<Vt>.<T>, <Vt2>.<T> ...], (Rn)         // no offset
+      VST1.P	[<Vt>.<T>, <Vt2>.<T> ...], imm(Rn)      // immediate offset variant
+      VST1.P	[<Vt>.<T>, <Vt2>.<T> ...], (Rn)(Rm)     // register offset variant
+        <T> Is an arrangement specifier and can have the following values:
+        B8, B16, H4, H8, S2, S4, D1, D2
+
+    VSUB: Sub (scalar)
+      VSUB	<Vm>, <Vn>, <Vd>
+        Subtract low 64-bit element in <Vm> from the correponding element in <Vn>,
+        place the result into low 64-bit element of <Vd>.
+
+    VUADDLV: Unsigned sum Long across Vector.
+      VUADDLV	<Vn>.<T>, Vd
+        <T> Is an arrangement specifier and can have the following values:
+        8B, 16B, H4, H8, S4
+
+4. Alphabetical list of cryptographic extension instructions
+
+    SHA1C, SHA1M, SHA1P: SHA1 hash update.
+      SHA1C	<Vm>.S4, Vn, Vd
+      SHA1M	<Vm>.S4, Vn, Vd
+      SHA1P	<Vm>.S4, Vn, Vd
+
+    SHA1H: SHA1 fixed rotate.
+      SHA1H	Vn, Vd
+
+    SHA1SU0:   SHA1 schedule update 0.
+    SHA256SU1: SHA256 schedule update 1.
+      SHA1SU0	<Vm>.S4, <Vn>.S4, <Vd>.S4
+      SHA256SU1	<Vm>.S4, <Vn>.S4, <Vd>.S4
+
+    SHA1SU1:   SHA1 schedule update 1.
+    SHA256SU0: SHA256 schedule update 0.
+      SHA1SU1	<Vn>.S4, <Vd>.S4
+      SHA256SU0	<Vn>.S4, <Vd>.S4
+
+    SHA256H, SHA256H2: SHA256 hash update.
+      SHA256H	<Vm>.S4, Vn, Vd
+      SHA256H2	<Vm>.S4, Vn, Vd
+
+
+*/
diff --git a/src/cmd/internal/obj/arm64/list7.go b/src/cmd/internal/obj/arm64/list7.go
index 65be486..9a9f4b4 100644
--- a/src/cmd/internal/obj/arm64/list7.go
+++ b/src/cmd/internal/obj/arm64/list7.go
@@ -57,6 +57,38 @@
 func init() {
 	obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, rconv)
 	obj.RegisterOpcode(obj.ABaseARM64, Anames)
+	obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
+}
+
+func arrange(a int) string {
+	switch a {
+	case ARNG_8B:
+		return "B8"
+	case ARNG_16B:
+		return "B16"
+	case ARNG_4H:
+		return "H4"
+	case ARNG_8H:
+		return "H8"
+	case ARNG_2S:
+		return "S2"
+	case ARNG_4S:
+		return "S4"
+	case ARNG_1D:
+		return "D1"
+	case ARNG_2D:
+		return "D2"
+	case ARNG_B:
+		return "B"
+	case ARNG_H:
+		return "H"
+	case ARNG_S:
+		return "S"
+	case ARNG_D:
+		return "D"
+	default:
+		return ""
+	}
 }
 
 func rconv(r int) string {
@@ -102,6 +134,58 @@
 		return "DAIFSet"
 	case r == REG_DAIFClr:
 		return "DAIFClr"
+	case REG_UXTB <= r && r < REG_UXTH:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.UXTB<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.UXTB", r&31)
+		}
+	case REG_UXTH <= r && r < REG_UXTW:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.UXTH<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.UXTH", r&31)
+		}
+	case REG_UXTW <= r && r < REG_UXTX:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.UXTW<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.UXTW", r&31)
+		}
+	case REG_UXTX <= r && r < REG_SXTB:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.UXTX<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.UXTX", r&31)
+		}
+	case REG_SXTB <= r && r < REG_SXTH:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.SXTB<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.SXTB", r&31)
+		}
+	case REG_SXTH <= r && r < REG_SXTW:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.SXTH<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.SXTH", r&31)
+		}
+	case REG_SXTW <= r && r < REG_SXTX:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.SXTW<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.SXTW", r&31)
+		}
+	case REG_SXTX <= r && r < REG_SPECIAL:
+		if (r>>5)&7 != 0 {
+			return fmt.Sprintf("R%d.SXTX<<%d", r&31, (r>>5)&7)
+		} else {
+			return fmt.Sprintf("R%d.SXTX", r&31)
+		}
+	case REG_ARNG <= r && r < REG_ELEM:
+		return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
+	case REG_ELEM <= r && r < REG_ELEM_END:
+		return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
 	}
 	return fmt.Sprintf("badreg(%d)", r)
 }
@@ -112,3 +196,60 @@
 	}
 	return "C_??"
 }
+
+func rlconv(list int64) string {
+	str := ""
+
+	// ARM64 register list follows ARM64 instruction decode schema
+	// | 31 | 30 | ... | 15 - 12 | 11 - 10 | ... |
+	// +----+----+-----+---------+---------+-----+
+	// |    | Q  | ... | opcode  |   size  | ... |
+
+	firstReg := int(list & 31)
+	opcode := (list >> 12) & 15
+	var regCnt int
+	var t string
+	switch opcode {
+	case 0x7:
+		regCnt = 1
+	case 0xa:
+		regCnt = 2
+	case 0x6:
+		regCnt = 3
+	case 0x2:
+		regCnt = 4
+	default:
+		regCnt = -1
+	}
+	// Q:size
+	arng := ((list>>30)&1)<<2 | (list>>10)&3
+	switch arng {
+	case 0:
+		t = "B8"
+	case 4:
+		t = "B16"
+	case 1:
+		t = "H4"
+	case 5:
+		t = "H8"
+	case 2:
+		t = "S2"
+	case 6:
+		t = "S4"
+	case 3:
+		t = "D1"
+	case 7:
+		t = "D2"
+	}
+	for i := 0; i < regCnt; i++ {
+		if str == "" {
+			str += "["
+		} else {
+			str += ","
+		}
+		str += fmt.Sprintf("V%d.", (firstReg+i)&31)
+		str += t
+	}
+	str += "]"
+	return str
+}
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 7aa0c8d..7092232 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -382,7 +382,7 @@
 			p.From.Offset = 0
 		}
 	}
-	if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
+	if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
 		c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
 	}
 	var source *obj.Addr
@@ -515,7 +515,6 @@
 		q = p
 	}
 
-	var q2 *obj.Prog
 	var retjmp *obj.LSym
 	for p := c.cursym.Func.Text; p != nil; p = p.Link {
 		o := p.As
@@ -618,22 +617,25 @@
 			if c.cursym.Func.Text.From.Sym.Wrapper() {
 				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
 				//
-				//	MOV g_panic(g), R1
-				//	CMP ZR, R1
-				//	BEQ end
-				//	MOV panic_argp(R1), R2
-				//	ADD $(autosize+8), RSP, R3
-				//	CMP R2, R3
-				//	BNE end
-				//	ADD $8, RSP, R4
-				//	MOVD R4, panic_argp(R1)
+				//	MOV  g_panic(g), R1
+				//	CBNZ checkargp
 				// end:
 				//	NOP
+				// ... function body ...
+				// checkargp:
+				//	MOV  panic_argp(R1), R2
+				//	ADD  $(autosize+8), RSP, R3
+				//	CMP  R2, R3
+				//	BNE  end
+				//	ADD  $8, RSP, R4
+				//	MOVD R4, panic_argp(R1)
+				//	B    end
 				//
 				// The NOP is needed to give the jumps somewhere to land.
-				// It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
+				// It is a liblink NOP, not an ARM64 NOP: it encodes to 0 instruction bytes.
 				q = q1
 
+				// MOV g_panic(g), R1
 				q = obj.Appendp(q, c.newprog)
 				q.As = AMOVD
 				q.From.Type = obj.TYPE_MEM
@@ -642,26 +644,36 @@
 				q.To.Type = obj.TYPE_REG
 				q.To.Reg = REG_R1
 
-				q = obj.Appendp(q, c.newprog)
-				q.As = ACMP
-				q.From.Type = obj.TYPE_REG
-				q.From.Reg = REGZERO
-				q.Reg = REG_R1
+				// CBNZ R1, checkargp
+				cbnz := obj.Appendp(q, c.newprog)
+				cbnz.As = ACBNZ
+				cbnz.From.Type = obj.TYPE_REG
+				cbnz.From.Reg = REG_R1
+				cbnz.To.Type = obj.TYPE_BRANCH
 
-				q = obj.Appendp(q, c.newprog)
-				q.As = ABEQ
-				q.To.Type = obj.TYPE_BRANCH
-				q1 = q
+				// Empty branch target at the top of the function body
+				end := obj.Appendp(cbnz, c.newprog)
+				end.As = obj.ANOP
 
-				q = obj.Appendp(q, c.newprog)
-				q.As = AMOVD
-				q.From.Type = obj.TYPE_MEM
-				q.From.Reg = REG_R1
-				q.From.Offset = 0 // Panic.argp
-				q.To.Type = obj.TYPE_REG
-				q.To.Reg = REG_R2
+				// find the end of the function
+				var last *obj.Prog
+				for last = end; last.Link != nil; last = last.Link {
+				}
 
-				q = obj.Appendp(q, c.newprog)
+				// MOV panic_argp(R1), R2
+				mov := obj.Appendp(last, c.newprog)
+				mov.As = AMOVD
+				mov.From.Type = obj.TYPE_MEM
+				mov.From.Reg = REG_R1
+				mov.From.Offset = 0 // Panic.argp
+				mov.To.Type = obj.TYPE_REG
+				mov.To.Reg = REG_R2
+
+				// CBNZ branches to the MOV above
+				cbnz.Pcond = mov
+
+				// ADD $(autosize+8), SP, R3
+				q = obj.Appendp(mov, c.newprog)
 				q.As = AADD
 				q.From.Type = obj.TYPE_CONST
 				q.From.Offset = int64(c.autosize) + 8
@@ -669,17 +681,20 @@
 				q.To.Type = obj.TYPE_REG
 				q.To.Reg = REG_R3
 
+				// CMP R2, R3
 				q = obj.Appendp(q, c.newprog)
 				q.As = ACMP
 				q.From.Type = obj.TYPE_REG
 				q.From.Reg = REG_R2
 				q.Reg = REG_R3
 
+				// BNE end
 				q = obj.Appendp(q, c.newprog)
 				q.As = ABNE
 				q.To.Type = obj.TYPE_BRANCH
-				q2 = q
+				q.Pcond = end
 
+				// ADD $8, SP, R4
 				q = obj.Appendp(q, c.newprog)
 				q.As = AADD
 				q.From.Type = obj.TYPE_CONST
@@ -688,6 +703,7 @@
 				q.To.Type = obj.TYPE_REG
 				q.To.Reg = REG_R4
 
+				// MOV R4, panic_argp(R1)
 				q = obj.Appendp(q, c.newprog)
 				q.As = AMOVD
 				q.From.Type = obj.TYPE_REG
@@ -696,11 +712,11 @@
 				q.To.Reg = REG_R1
 				q.To.Offset = 0 // Panic.argp
 
+				// B end
 				q = obj.Appendp(q, c.newprog)
-
-				q.As = obj.ANOP
-				q1.Pcond = q
-				q2.Pcond = q
+				q.As = AB
+				q.To.Type = obj.TYPE_BRANCH
+				q.Pcond = end
 			}
 
 		case obj.ARET:
@@ -797,7 +813,7 @@
 	ADWORD: true,
 	ABL:    true,
 	AB:     true,
-	ASVC:   true,
+	ACLREX: true,
 }
 
 var Linkarm64 = obj.LinkArch{
diff --git a/src/cmd/internal/obj/data.go b/src/cmd/internal/obj/data.go
index 23d1809..ce0dd09 100644
--- a/src/cmd/internal/obj/data.go
+++ b/src/cmd/internal/obj/data.go
@@ -117,9 +117,7 @@
 	}
 }
 
-// WriteAddr writes an address of size siz into s at offset off.
-// rsym and roff specify the relocation for the address.
-func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
+func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, rtype objabi.RelocType) {
 	// Allow 4-byte addresses for DWARF.
 	if siz != ctxt.Arch.PtrSize && siz != 4 {
 		ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
@@ -132,10 +130,24 @@
 	}
 	r.Siz = uint8(siz)
 	r.Sym = rsym
-	r.Type = objabi.R_ADDR
+	r.Type = rtype
 	r.Add = roff
 }
 
+// WriteAddr writes an address of size siz into s at offset off.
+// rsym and roff specify the relocation for the address.
+func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
+	s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR)
+}
+
+// WriteCURelativeAddr writes a pointer-sized address into s at offset off.
+// rsym and roff specify the relocation for the address which will be
+// resolved by the linker to an offset from the DW_AT_low_pc attribute of
+// the DWARF Compile Unit of rsym.
+func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64) {
+	s.writeAddr(ctxt, off, ctxt.Arch.PtrSize, rsym, roff, objabi.R_ADDRCUOFF)
+}
+
 // WriteOff writes a 4 byte offset to rsym+roff into s at offset off.
 // After linking the 4 bytes stored at s+off will be
 // rsym+roff-(start of section that s is in).
diff --git a/src/cmd/internal/obj/go.go b/src/cmd/internal/obj/go.go
index f0b2c46..dbe9b40 100644
--- a/src/cmd/internal/obj/go.go
+++ b/src/cmd/internal/obj/go.go
@@ -10,7 +10,7 @@
 	p.As = ANOP
 	p.Scond = 0
 	p.From = Addr{}
-	p.From3 = nil
+	p.RestArgs = nil
 	p.Reg = 0
 	p.To = Addr{}
 }
diff --git a/src/cmd/internal/obj/inl.go b/src/cmd/internal/obj/inl.go
index 1169219..6712394 100644
--- a/src/cmd/internal/obj/inl.go
+++ b/src/cmd/internal/obj/inl.go
@@ -6,7 +6,7 @@
 
 import "cmd/internal/src"
 
-// InlTree s a collection of inlined calls. The Parent field of an
+// InlTree is a collection of inlined calls. The Parent field of an
 // InlinedCall is the index of another InlinedCall in InlTree.
 //
 // The compiler maintains a global inlining tree and adds a node to it
@@ -23,6 +23,9 @@
 //  8     h()
 //  9     h()
 // 10 }
+// 11 func h() {
+// 12     println("H")
+// 13 }
 //
 // Assuming the global tree starts empty, inlining will produce the
 // following tree:
@@ -61,12 +64,24 @@
 	return r
 }
 
+func (tree *InlTree) Parent(inlIndex int) int {
+	return tree.nodes[inlIndex].Parent
+}
+
+func (tree *InlTree) InlinedFunction(inlIndex int) *LSym {
+	return tree.nodes[inlIndex].Func
+}
+
+func (tree *InlTree) CallPos(inlIndex int) src.XPos {
+	return tree.nodes[inlIndex].Pos
+}
+
 // OutermostPos returns the outermost position corresponding to xpos,
 // which is where xpos was ultimately inlined to. In the example for
 // InlTree, main() contains inlined AST nodes from h(), but the
 // outermost position for those nodes is line 2.
 func (ctxt *Link) OutermostPos(xpos src.XPos) src.Pos {
-	pos := ctxt.PosTable.Pos(xpos)
+	pos := ctxt.InnermostPos(xpos)
 
 	outerxpos := xpos
 	for ix := pos.Base().InliningIndex(); ix >= 0; {
@@ -77,6 +92,17 @@
 	return ctxt.PosTable.Pos(outerxpos)
 }
 
+// InnermostPos returns the innermost position corresponding to xpos,
+// that is, the code that is inlined and that inlines nothing else.
+// In the example for InlTree above, the code for println within h
+// would have an innermost position with line number 12, whether
+// h was not inlined, inlined into g, g-then-f, or g-then-f-then-main.
+// This corresponds to what someone debugging main, f, g, or h might
+// expect to see while single-stepping.
+func (ctxt *Link) InnermostPos(xpos src.XPos) src.Pos {
+	return ctxt.PosTable.Pos(xpos)
+}
+
 func dumpInlTree(ctxt *Link, tree InlTree) {
 	for i, call := range tree.nodes {
 		pos := ctxt.PosTable.Pos(call.Pos)
diff --git a/src/cmd/internal/obj/line_test.go b/src/cmd/internal/obj/line_test.go
index 6b21abe..f159a65 100644
--- a/src/cmd/internal/obj/line_test.go
+++ b/src/cmd/internal/obj/line_test.go
@@ -17,7 +17,7 @@
 
 	afile := src.NewFileBase("a.go", "a.go")
 	bfile := src.NewFileBase("b.go", "/foo/bar/b.go")
-	lfile := src.NewLinePragmaBase(src.MakePos(afile, 7, 0), "linedir", 100)
+	lfile := src.NewLinePragmaBase(src.MakePos(afile, 7, 0), "linedir", "linedir", 100)
 
 	var tests = []struct {
 		pos  src.Pos
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index d49bc8c..27c74f6 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -138,10 +138,13 @@
 //			offset = second register
 //
 //	[reg, reg, reg-reg]
-//		Register list for ARM.
+//		Register list for ARM and ARM64.
 //		Encoding:
 //			type = TYPE_REGLIST
+//		On ARM:
 //			offset = bit mask of registers in list; R0 is low bit.
+//		On ARM64:
+//			offset = register count (Q:size) | arrangement (opcode) | first register
 //
 //	reg, reg
 //		Register pair for ARM.
@@ -155,6 +158,27 @@
 //			index = second register
 //			scale = 1
 //
+//	reg.[US]XT[BHWX]
+//		Register extension for ARM64
+//		Encoding:
+//			type = TYPE_REG
+//			reg = REG_[US]XT[BHWX] + register + shift amount
+//			offset = ((reg&31) << 16) | (exttype << 13) | (amount<<10)
+//
+//	reg.<T>
+//		Register arrangement for ARM64 SIMD register
+//		e.g.: V1.S4, V2.S2, V7.D2, V2.H4, V6.B16
+//		Encoding:
+//			type = TYPE_REG
+//			reg = REG_ARNG + register + arrangement
+//
+//	reg.<T>[index]
+//		Register element for ARM64
+//		Encoding:
+//			type = TYPE_REG
+//			reg = REG_ELEM + register + arrangement
+//			index = element index
+
 type Addr struct {
 	Reg    int16
 	Index  int16
@@ -184,6 +208,9 @@
 	// A reference to name@GOT(SB) is a reference to the entry in the global offset
 	// table for 'name'.
 	NAME_GOTREF
+	// Indicates auto that was optimized away, but whose type
+	// we want to preserve in the DWARF debug info.
+	NAME_DELETED_AUTO
 )
 
 type AddrType uint8
@@ -209,14 +236,19 @@
 //
 // The general instruction form is:
 //
-//	As.Scond From, Reg, From3, To, RegTo2
+//	(1) As.Scond From [, ...RestArgs], To
+//	(2) As.Scond From, Reg [, ...RestArgs], To, RegTo2
 //
 // where As is an opcode and the others are arguments:
-// From, Reg, From3 are sources, and To, RegTo2 are destinations.
+// From, Reg are sources, and To, RegTo2 are destinations.
+// RestArgs can hold additional sources and destinations.
 // Usually, not all arguments are present.
 // For example, MOVL R1, R2 encodes using only As=MOVL, From=R1, To=R2.
 // The Scond field holds additional condition bits for systems (like arm)
 // that have generalized conditional execution.
+// (2) form is present for compatibility with older code,
+// to avoid too much changes in a single swing.
+// (1) scheme is enough to express any kind of operand combination.
 //
 // Jump instructions use the Pcond field to point to the target instruction,
 // which must be in the same linked list as the jump instruction.
@@ -232,35 +264,62 @@
 // The other fields not yet mentioned are for use by the back ends and should
 // be left zeroed by creators of Prog lists.
 type Prog struct {
-	Ctxt   *Link    // linker context
-	Link   *Prog    // next Prog in linked list
-	From   Addr     // first source operand
-	From3  *Addr    // third source operand (second is Reg below)
-	To     Addr     // destination operand (second is RegTo2 below)
-	Pcond  *Prog    // target of conditional jump
-	Forwd  *Prog    // for x86 back end
-	Rel    *Prog    // for x86, arm back ends
-	Pc     int64    // for back ends or assembler: virtual or actual program counter, depending on phase
-	Pos    src.XPos // source position of this instruction
-	Spadj  int32    // effect of instruction on stack pointer (increment or decrement amount)
-	As     As       // assembler opcode
-	Reg    int16    // 2nd source operand
-	RegTo2 int16    // 2nd destination operand
-	Mark   uint16   // bitmask of arch-specific items
-	Optab  uint16   // arch-specific opcode index
-	Scond  uint8    // condition bits for conditional instruction (e.g., on ARM)
-	Back   uint8    // for x86 back end: backwards branch state
-	Ft     uint8    // for x86 back end: type index of Prog.From
-	Tt     uint8    // for x86 back end: type index of Prog.To
-	Isize  uint8    // for x86 back end: size of the instruction in bytes
+	Ctxt     *Link    // linker context
+	Link     *Prog    // next Prog in linked list
+	From     Addr     // first source operand
+	RestArgs []Addr   // can pack any operands that not fit into {Prog.From, Prog.To}
+	To       Addr     // destination operand (second is RegTo2 below)
+	Pcond    *Prog    // target of conditional jump
+	Forwd    *Prog    // for x86 back end
+	Rel      *Prog    // for x86, arm back ends
+	Pc       int64    // for back ends or assembler: virtual or actual program counter, depending on phase
+	Pos      src.XPos // source position of this instruction
+	Spadj    int32    // effect of instruction on stack pointer (increment or decrement amount)
+	As       As       // assembler opcode
+	Reg      int16    // 2nd source operand
+	RegTo2   int16    // 2nd destination operand
+	Mark     uint16   // bitmask of arch-specific items
+	Optab    uint16   // arch-specific opcode index
+	Scond    uint8    // condition bits for conditional instruction (e.g., on ARM)
+	Back     uint8    // for x86 back end: backwards branch state
+	Ft       uint8    // for x86 back end: type index of Prog.From
+	Tt       uint8    // for x86 back end: type index of Prog.To
+	Isize    uint8    // for x86 back end: size of the instruction in bytes
 }
 
-// From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
+// From3Type returns p.GetFrom3().Type, or TYPE_NONE when
+// p.GetFrom3() returns nil.
+//
+// Deprecated: for the same reasons as Prog.GetFrom3.
 func (p *Prog) From3Type() AddrType {
-	if p.From3 == nil {
+	if p.RestArgs == nil {
 		return TYPE_NONE
 	}
-	return p.From3.Type
+	return p.RestArgs[0].Type
+}
+
+// GetFrom3 returns second source operand (the first is Prog.From).
+// In combination with Prog.From and Prog.To it makes common 3 operand
+// case easier to use.
+//
+// Should be used only when RestArgs is set with SetFrom3.
+//
+// Deprecated: better use RestArgs directly or define backend-specific getters.
+// Introduced to simplify transition to []Addr.
+// Usage of this is discouraged due to fragility and lack of guarantees.
+func (p *Prog) GetFrom3() *Addr {
+	if p.RestArgs == nil {
+		return nil
+	}
+	return &p.RestArgs[0]
+}
+
+// SetFrom3 assigns []Addr{a} to p.RestArgs.
+// In pair with Prog.GetFrom3 it can help in emulation of Prog.From3.
+//
+// Deprecated: for the same reasons as Prog.GetFrom3.
+func (p *Prog) SetFrom3(a Addr) {
+	p.RestArgs = []Addr{a}
 }
 
 // An As denotes an assembler opcode.
@@ -295,7 +354,7 @@
 // Subspaces are aligned to a power of two so opcodes can be masked
 // with AMask and used as compact array indices.
 const (
-	ABase386 = (1 + iota) << 10
+	ABase386 = (1 + iota) << 11
 	ABaseARM
 	ABaseAMD64
 	ABasePPC64
@@ -303,7 +362,7 @@
 	ABaseMIPS
 	ABaseS390X
 
-	AllowedOpCodes = 1 << 10            // The number of opcodes available for any given architecture.
+	AllowedOpCodes = 1 << 11            // The number of opcodes available for any given architecture.
 	AMask          = AllowedOpCodes - 1 // AND with this to use the opcode as an array index.
 )
 
@@ -330,8 +389,10 @@
 	Autom  []*Auto
 	Pcln   Pcln
 
-	dwarfSym       *LSym
+	dwarfInfoSym   *LSym
+	dwarfLocSym    *LSym
 	dwarfRangesSym *LSym
+	dwarfAbsFnSym  *LSym
 
 	GCArgs   LSym
 	GCLocals LSym
@@ -370,6 +431,10 @@
 	// definition. (When not compiling to support Go shared libraries, all symbols are
 	// local in this sense unless there is a cgo_export_* directive).
 	AttrLocal
+
+	// For function symbols; indicates that the specified function was the
+	// target of an inline during compilation
+	AttrWasInlined
 )
 
 func (a Attribute) DuplicateOK() bool   { return a&AttrDuplicateOK != 0 }
@@ -385,6 +450,7 @@
 func (a Attribute) NeedCtxt() bool      { return a&AttrNeedCtxt != 0 }
 func (a Attribute) NoFrame() bool       { return a&AttrNoFrame != 0 }
 func (a Attribute) Static() bool        { return a&AttrStatic != 0 }
+func (a Attribute) WasInlined() bool    { return a&AttrWasInlined != 0 }
 
 func (a *Attribute) Set(flag Attribute, value bool) {
 	if value {
@@ -411,6 +477,7 @@
 	{bit: AttrNeedCtxt, s: "NEEDCTXT"},
 	{bit: AttrNoFrame, s: "NOFRAME"},
 	{bit: AttrStatic, s: "STATIC"},
+	{bit: AttrWasInlined, s: ""},
 }
 
 // TextAttrString formats a for printing in as part of a TEXT prog.
@@ -476,26 +543,31 @@
 // Link holds the context for writing object code from a compiler
 // to be linker input or for reading that input into the linker.
 type Link struct {
-	Headtype      objabi.HeadType
-	Arch          *LinkArch
-	Debugasm      bool
-	Debugvlog     bool
-	Debugpcln     string
-	Flag_shared   bool
-	Flag_dynlink  bool
-	Flag_optimize bool
-	Bso           *bufio.Writer
-	Pathname      string
-	hashmu        sync.Mutex       // protects hash
-	hash          map[string]*LSym // name -> sym mapping
-	statichash    map[string]*LSym // name -> sym mapping for static syms
-	PosTable      src.PosTable
-	InlTree       InlTree // global inlining tree used by gc/inl.go
-	Imports       []string
-	DiagFunc      func(string, ...interface{})
-	DebugInfo     func(fn *LSym, curfn interface{}) []dwarf.Scope // if non-nil, curfn is a *gc.Node
-	Errors        int
+	Headtype           objabi.HeadType
+	Arch               *LinkArch
+	Debugasm           bool
+	Debugvlog          bool
+	Debugpcln          string
+	Flag_shared        bool
+	Flag_dynlink       bool
+	Flag_optimize      bool
+	Flag_locationlists bool
+	Bso                *bufio.Writer
+	Pathname           string
+	hashmu             sync.Mutex       // protects hash
+	hash               map[string]*LSym // name -> sym mapping
+	statichash         map[string]*LSym // name -> sym mapping for static syms
+	PosTable           src.PosTable
+	InlTree            InlTree // global inlining tree used by gc/inl.go
+	DwFixups           *DwarfFixupTable
+	Imports            []string
+	DiagFunc           func(string, ...interface{})
+	DiagFlush          func()
+	DebugInfo          func(fn *LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) // if non-nil, curfn is a *gc.Node
+	GenAbstractFunc    func(fn *LSym)
+	Errors             int
 
+	InParallel           bool // parallel backend phase in effect
 	Framepointer_enabled bool
 
 	// state for writing objects
@@ -533,9 +605,10 @@
 // LinkArch is the definition of a single architecture.
 type LinkArch struct {
 	*sys.Arch
-	Init       func(*Link)
-	Preprocess func(*Link, *LSym, ProgAlloc)
-	Assemble   func(*Link, *LSym, ProgAlloc)
-	Progedit   func(*Link, *Prog, ProgAlloc)
-	UnaryDst   map[As]bool // Instruction takes one operand, a destination.
+	Init           func(*Link)
+	Preprocess     func(*Link, *LSym, ProgAlloc)
+	Assemble       func(*Link, *LSym, ProgAlloc)
+	Progedit       func(*Link, *Prog, ProgAlloc)
+	UnaryDst       map[As]bool // Instruction takes one operand, a destination.
+	DWARFRegisters map[int16]int16
 }
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index 6257e5b..2dcfa97 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -893,6 +893,7 @@
 		switch r {
 		default:
 			ctxt.Diag("unknown op in build: %v", r)
+			ctxt.DiagFlush()
 			log.Fatalf("bad code")
 
 		case AABSF:
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index e309c5f..2501bba 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -15,6 +15,7 @@
 	"log"
 	"path/filepath"
 	"sort"
+	"sync"
 )
 
 // objWriter writes Go object files.
@@ -350,6 +351,8 @@
 			w.writeInt(objabi.A_AUTO)
 		} else if a.Name == NAME_PARAM {
 			w.writeInt(objabi.A_PARAM)
+		} else if a.Name == NAME_DELETED_AUTO {
+			w.writeInt(objabi.A_DELETED_AUTO)
 		} else {
 			log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
 		}
@@ -443,9 +446,6 @@
 	ls.WriteString(c.Link, ls.Size, len(v), v)
 	ls.WriteInt(c.Link, ls.Size, 1, 0)
 }
-func (c dwCtxt) SymValue(s dwarf.Sym) int64 {
-	return 0
-}
 func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
 	ls := s.(*LSym)
 	size := c.PtrSize()
@@ -456,43 +456,422 @@
 		ls.WriteInt(c.Link, ls.Size, size, value)
 	}
 }
+func (c dwCtxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
+	ls := s.(*LSym)
+	rsym := data.(*LSym)
+	ls.WriteCURelativeAddr(c.Link, ls.Size, rsym, value)
+}
 func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
 	ls := s.(*LSym)
 	rsym := t.(*LSym)
 	ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs)
 	r := &ls.R[len(ls.R)-1]
-	r.Type = objabi.R_DWARFREF
+	r.Type = objabi.R_DWARFSECREF
+}
+func (c dwCtxt) AddFileRef(s dwarf.Sym, f interface{}) {
+	ls := s.(*LSym)
+	rsym := f.(*LSym)
+	ls.WriteAddr(c.Link, ls.Size, 4, rsym, 0)
+	r := &ls.R[len(ls.R)-1]
+	r.Type = objabi.R_DWARFFILEREF
 }
 
-// dwarfSym returns the DWARF symbols for TEXT symbol.
-func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfRangesSym *LSym) {
+func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
+	ls := s.(*LSym)
+	return ls.Size
+}
+
+// Here "from" is a symbol corresponding to an inlined or concrete
+// function, "to" is the symbol for the corresponding abstract
+// function, and "dclIdx" is the index of the symbol of interest with
+// respect to the Dcl slice of the original pre-optimization version
+// of the inlined function.
+func (c dwCtxt) RecordDclReference(from dwarf.Sym, to dwarf.Sym, dclIdx int, inlIndex int) {
+	ls := from.(*LSym)
+	tls := to.(*LSym)
+	ridx := len(ls.R) - 1
+	c.Link.DwFixups.ReferenceChildDIE(ls, ridx, tls, dclIdx, inlIndex)
+}
+
+func (c dwCtxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
+	ls := s.(*LSym)
+	c.Link.DwFixups.RegisterChildDIEOffsets(ls, vars, offsets)
+}
+
+func (c dwCtxt) Logf(format string, args ...interface{}) {
+	c.Link.Logf(format, args...)
+}
+
+func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym, dwarfAbsFnSym *LSym) {
 	if s.Type != objabi.STEXT {
 		ctxt.Diag("dwarfSym of non-TEXT %v", s)
 	}
-	if s.Func.dwarfSym == nil {
-		s.Func.dwarfSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
+	if s.Func.dwarfInfoSym == nil {
+		s.Func.dwarfInfoSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
+		if ctxt.Flag_locationlists {
+			s.Func.dwarfLocSym = ctxt.LookupDerived(s, dwarf.LocPrefix+s.Name)
+		}
 		s.Func.dwarfRangesSym = ctxt.LookupDerived(s, dwarf.RangePrefix+s.Name)
+		if s.WasInlined() {
+			s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s)
+		}
+
 	}
-	return s.Func.dwarfSym, s.Func.dwarfRangesSym
+	return s.Func.dwarfInfoSym, s.Func.dwarfLocSym, s.Func.dwarfRangesSym, s.Func.dwarfAbsFnSym
 }
 
 func (s *LSym) Len() int64 {
 	return s.Size
 }
 
-// populateDWARF fills in the DWARF Debugging Information Entries for TEXT symbol s.
-// The DWARFs symbol must already have been initialized in InitTextSym.
-func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym) {
-	dsym, drsym := ctxt.dwarfSym(s)
-	if dsym.Size != 0 {
+// fileSymbol returns a symbol corresponding to the source file of the
+// first instruction (prog) of the specified function. This will
+// presumably be the file in which the function is defined.
+func (ctxt *Link) fileSymbol(fn *LSym) *LSym {
+	p := fn.Func.Text
+	if p != nil {
+		f, _ := linkgetlineFromPos(ctxt, p.Pos)
+		fsym := ctxt.Lookup(f)
+		return fsym
+	}
+	return nil
+}
+
+// populateDWARF fills in the DWARF Debugging Information Entries for
+// TEXT symbol 's'. The various DWARF symbols must already have been
+// initialized in InitTextSym.
+func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym, myimportpath string) {
+	info, loc, ranges, absfunc := ctxt.dwarfSym(s)
+	if info.Size != 0 {
 		ctxt.Diag("makeFuncDebugEntry double process %v", s)
 	}
 	var scopes []dwarf.Scope
+	var inlcalls dwarf.InlCalls
 	if ctxt.DebugInfo != nil {
-		scopes = ctxt.DebugInfo(s, curfn)
+		scopes, inlcalls = ctxt.DebugInfo(s, curfn)
 	}
-	err := dwarf.PutFunc(dwCtxt{ctxt}, dsym, drsym, s.Name, !s.Static(), s, s.Size, scopes)
+	var err error
+	dwctxt := dwCtxt{ctxt}
+	filesym := ctxt.fileSymbol(s)
+	fnstate := &dwarf.FnState{
+		Name:       s.Name,
+		Importpath: myimportpath,
+		Info:       info,
+		Filesym:    filesym,
+		Loc:        loc,
+		Ranges:     ranges,
+		Absfn:      absfunc,
+		StartPC:    s,
+		Size:       s.Size,
+		External:   !s.Static(),
+		Scopes:     scopes,
+		InlCalls:   inlcalls,
+	}
+	if absfunc != nil {
+		err = dwarf.PutAbstractFunc(dwctxt, fnstate)
+		if err != nil {
+			ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
+		}
+		err = dwarf.PutConcreteFunc(dwctxt, fnstate)
+	} else {
+		err = dwarf.PutDefaultFunc(dwctxt, fnstate)
+	}
 	if err != nil {
 		ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
 	}
 }
+
+// DwarfIntConst creates a link symbol for an integer constant with the
+// given name, type and value.
+func (ctxt *Link) DwarfIntConst(myimportpath, name, typename string, val int64) {
+	if myimportpath == "" {
+		return
+	}
+	s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
+		s.Type = objabi.SDWARFINFO
+		ctxt.Data = append(ctxt.Data, s)
+	})
+	dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
+}
+
+func (ctxt *Link) DwarfAbstractFunc(curfn interface{}, s *LSym, myimportpath string) {
+	absfn := ctxt.DwFixups.AbsFuncDwarfSym(s)
+	if absfn.Size != 0 {
+		ctxt.Diag("internal error: DwarfAbstractFunc double process %v", s)
+	}
+	if s.Func == nil {
+		s.Func = new(FuncInfo)
+	}
+	scopes, _ := ctxt.DebugInfo(s, curfn)
+	dwctxt := dwCtxt{ctxt}
+	filesym := ctxt.fileSymbol(s)
+	fnstate := dwarf.FnState{
+		Name:       s.Name,
+		Importpath: myimportpath,
+		Info:       absfn,
+		Filesym:    filesym,
+		Absfn:      absfn,
+		External:   !s.Static(),
+		Scopes:     scopes,
+	}
+	if err := dwarf.PutAbstractFunc(dwctxt, &fnstate); err != nil {
+		ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
+	}
+}
+
+// This table is designed to aid in the creation of references betweeen
+// DWARF subprogram DIEs.
+//
+// In most cases when one DWARF DIE has to refer to another DWARF DIE,
+// the target of the reference has an LSym, which makes it easy to use
+// the existing relocation mechanism. For DWARF inlined routine DIEs,
+// however, the subprogram DIE has to refer to a child
+// parameter/variable DIE of the abstract subprogram. This child DIE
+// doesn't have an LSym, and also of interest is the fact that when
+// DWARF generation is happening for inlined function F within caller
+// G, it's possible that DWARF generation hasn't happened yet for F,
+// so there is no way to know the offset of a child DIE within F's
+// abstract function. Making matters more complex, each inlined
+// instance of F may refer to a subset of the original F's variables
+// (depending on what happens with optimization, some vars may be
+// eliminated).
+//
+// The fixup table below helps overcome this hurdle. At the point
+// where a parameter/variable reference is made (via a call to
+// "ReferenceChildDIE"), a fixup record is generate that records
+// the relocation that is targeting that child variable. At a later
+// point when the abstract function DIE is emitted, there will be
+// a call to "RegisterChildDIEOffsets", at which point the offsets
+// needed to apply fixups are captured. Finally, once the parallel
+// portion of the compilation is done, fixups can actually be applied
+// during the "Finalize" method (this can't be done during the
+// parallel portion of the compile due to the possibility of data
+// races).
+//
+// This table is also used to record the "precursor" function node for
+// each function that is the target of an inline -- child DIE references
+// have to be made with respect to the original pre-optimization
+// version of the function (to allow for the fact that each inlined
+// body may be optimized differently).
+type DwarfFixupTable struct {
+	ctxt      *Link
+	mu        sync.Mutex
+	symtab    map[*LSym]int // maps abstract fn LSYM to index in svec
+	svec      []symFixups
+	precursor map[*LSym]fnState // maps fn Lsym to precursor Node, absfn sym
+}
+
+type symFixups struct {
+	fixups   []relFixup
+	doffsets []declOffset
+	inlIndex int32
+	defseen  bool
+}
+
+type declOffset struct {
+	// Index of variable within DCL list of pre-optimization function
+	dclIdx int32
+	// Offset of var's child DIE with respect to containing subprogram DIE
+	offset int32
+}
+
+type relFixup struct {
+	refsym *LSym
+	relidx int32
+	dclidx int32
+}
+
+type fnState struct {
+	// precursor function (really *gc.Node)
+	precursor interface{}
+	// abstract function symbol
+	absfn *LSym
+}
+
+func NewDwarfFixupTable(ctxt *Link) *DwarfFixupTable {
+	return &DwarfFixupTable{
+		ctxt:      ctxt,
+		symtab:    make(map[*LSym]int),
+		precursor: make(map[*LSym]fnState),
+	}
+}
+
+func (ft *DwarfFixupTable) GetPrecursorFunc(s *LSym) interface{} {
+	if fnstate, found := ft.precursor[s]; found {
+		return fnstate.precursor
+	}
+	return nil
+}
+
+func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) {
+	if _, found := ft.precursor[s]; found {
+		ft.ctxt.Diag("internal error: DwarfFixupTable.SetPrecursorFunc double call on %v", s)
+	}
+
+	// initialize abstract function symbol now. This is done here so
+	// as to avoid data races later on during the parallel portion of
+	// the back end.
+	absfn := ft.ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name+dwarf.AbstractFuncSuffix)
+	absfn.Set(AttrDuplicateOK, true)
+	absfn.Type = objabi.SDWARFINFO
+	ft.ctxt.Data = append(ft.ctxt.Data, absfn)
+
+	ft.precursor[s] = fnState{precursor: fn, absfn: absfn}
+}
+
+// Make a note of a child DIE reference: relocation 'ridx' within symbol 's'
+// is targeting child 'c' of DIE with symbol 'tgt'.
+func (ft *DwarfFixupTable) ReferenceChildDIE(s *LSym, ridx int, tgt *LSym, dclidx int, inlIndex int) {
+	// Protect against concurrent access if multiple backend workers
+	ft.mu.Lock()
+	defer ft.mu.Unlock()
+
+	// Create entry for symbol if not already present.
+	idx, found := ft.symtab[tgt]
+	if !found {
+		ft.svec = append(ft.svec, symFixups{inlIndex: int32(inlIndex)})
+		idx = len(ft.svec) - 1
+		ft.symtab[tgt] = idx
+	}
+
+	// Do we have child DIE offsets available? If so, then apply them,
+	// otherwise create a fixup record.
+	sf := &ft.svec[idx]
+	if len(sf.doffsets) > 0 {
+		found := false
+		for _, do := range sf.doffsets {
+			if do.dclIdx == int32(dclidx) {
+				off := do.offset
+				s.R[ridx].Add += int64(off)
+				found = true
+				break
+			}
+		}
+		if !found {
+			ft.ctxt.Diag("internal error: DwarfFixupTable.ReferenceChildDIE unable to locate child DIE offset for dclIdx=%d src=%v tgt=%v", dclidx, s, tgt)
+		}
+	} else {
+		sf.fixups = append(sf.fixups, relFixup{s, int32(ridx), int32(dclidx)})
+	}
+}
+
+// Called once DWARF generation is complete for a given abstract function,
+// whose children might have been referenced via a call above. Stores
+// the offsets for any child DIEs (vars, params) so that they can be
+// consumed later in on DwarfFixupTable.Finalize, which applies any
+// outstanding fixups.
+func (ft *DwarfFixupTable) RegisterChildDIEOffsets(s *LSym, vars []*dwarf.Var, coffsets []int32) {
+	// Length of these two slices should agree
+	if len(vars) != len(coffsets) {
+		ft.ctxt.Diag("internal error: RegisterChildDIEOffsets vars/offsets length mismatch")
+		return
+	}
+
+	// Generate the slice of declOffset's based in vars/coffsets
+	doffsets := make([]declOffset, len(coffsets))
+	for i := 0; i < len(coffsets); i++ {
+		doffsets[i].dclIdx = vars[i].ChildIndex
+		doffsets[i].offset = coffsets[i]
+	}
+
+	ft.mu.Lock()
+	defer ft.mu.Unlock()
+
+	// Store offsets for this symbol.
+	idx, found := ft.symtab[s]
+	if !found {
+		sf := symFixups{inlIndex: -1, defseen: true, doffsets: doffsets}
+		ft.svec = append(ft.svec, sf)
+		ft.symtab[s] = len(ft.svec) - 1
+	} else {
+		sf := &ft.svec[idx]
+		sf.doffsets = doffsets
+		sf.defseen = true
+	}
+}
+
+func (ft *DwarfFixupTable) processFixups(slot int, s *LSym) {
+	sf := &ft.svec[slot]
+	for _, f := range sf.fixups {
+		dfound := false
+		for i := 0; i < len(sf.doffsets); i++ {
+			if sf.doffsets[i].dclIdx == f.dclidx {
+				f.refsym.R[f.relidx].Add += int64(sf.doffsets[i].offset)
+				dfound = true
+				break
+			}
+		}
+		if !dfound {
+			ft.ctxt.Diag("internal error: DwarfFixupTable has orphaned fixup on %v targeting %v relidx=%d dclidx=%d", f.refsym, s, f.relidx, f.dclidx)
+		}
+	}
+}
+
+// return the LSym corresponding to the 'abstract subprogram' DWARF
+// info entry for a function.
+func (ft *DwarfFixupTable) AbsFuncDwarfSym(fnsym *LSym) *LSym {
+	// Protect against concurrent access if multiple backend workers
+	ft.mu.Lock()
+	defer ft.mu.Unlock()
+
+	if fnstate, found := ft.precursor[fnsym]; found {
+		return fnstate.absfn
+	}
+	ft.ctxt.Diag("internal error: AbsFuncDwarfSym requested for %v, not seen during inlining", fnsym)
+	return nil
+}
+
+// Called after all functions have been compiled; the main job of this
+// function is to identify cases where there are outstanding fixups.
+// This scenario crops up when we have references to variables of an
+// inlined routine, but that routine is defined in some other package.
+// This helper walks through and locate these fixups, then invokes a
+// helper to create an abstract subprogram DIE for each one.
+func (ft *DwarfFixupTable) Finalize(myimportpath string, trace bool) {
+	if trace {
+		ft.ctxt.Logf("DwarfFixupTable.Finalize invoked for %s\n", myimportpath)
+	}
+
+	// Collect up the keys from the precursor map, then sort the
+	// resulting list (don't want to rely on map ordering here).
+	fns := make([]*LSym, len(ft.precursor))
+	idx := 0
+	for fn, _ := range ft.precursor {
+		fns[idx] = fn
+		idx++
+	}
+	sort.Sort(bySymName(fns))
+
+	// Should not be called during parallel portion of compilation.
+	if ft.ctxt.InParallel {
+		ft.ctxt.Diag("internal error: DwarfFixupTable.Finalize call during parallel backend")
+	}
+
+	// Generate any missing abstract functions.
+	for i := 0; i < len(fns); i++ {
+		s := fns[i]
+		absfn := ft.AbsFuncDwarfSym(s)
+		slot, found := ft.symtab[absfn]
+		if !found || !ft.svec[slot].defseen {
+			ft.ctxt.GenAbstractFunc(s)
+		}
+	}
+
+	// Apply fixups.
+	for i := 0; i < len(fns); i++ {
+		s := fns[i]
+		absfn := ft.AbsFuncDwarfSym(s)
+		slot, found := ft.symtab[absfn]
+		if !found {
+			ft.ctxt.Diag("internal error: DwarfFixupTable.Finalize orphan abstract function for %v", s)
+		} else {
+			ft.processFixups(slot, s)
+		}
+	}
+}
+
+type bySymName []*LSym
+
+func (s bySymName) Len() int           { return len(s) }
+func (s bySymName) Less(i, j int) bool { return s[i].Name < s[j].Name }
+func (s bySymName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
diff --git a/src/cmd/internal/obj/pass.go b/src/cmd/internal/obj/pass.go
index 7cc187d..edfc3ac 100644
--- a/src/cmd/internal/obj/pass.go
+++ b/src/cmd/internal/obj/pass.go
@@ -124,8 +124,8 @@
 
 	for p := sym.Func.Text; p != nil; p = p.Link {
 		checkaddr(ctxt, p, &p.From)
-		if p.From3 != nil {
-			checkaddr(ctxt, p, p.From3)
+		if p.GetFrom3() != nil {
+			checkaddr(ctxt, p, p.GetFrom3())
 		}
 		checkaddr(ctxt, p, &p.To)
 
diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go
index b85bb8a..d1d36cf 100644
--- a/src/cmd/internal/obj/pcln.go
+++ b/src/cmd/internal/obj/pcln.go
@@ -223,6 +223,7 @@
 	}
 	if oldval+p.Spadj < -10000 || oldval+p.Spadj > 1100000000 {
 		ctxt.Diag("overflow in spadj: %d + %d = %d", oldval, p.Spadj, oldval+p.Spadj)
+		ctxt.DiagFlush()
 		log.Fatalf("bad code")
 	}
 
@@ -240,6 +241,7 @@
 	}
 	if int64(int32(p.To.Offset)) != p.To.Offset {
 		ctxt.Diag("overflow in PCDATA instruction: %v", p)
+		ctxt.DiagFlush()
 		log.Fatalf("bad code")
 	}
 
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index 861da88..e2609da 100644
--- a/src/cmd/internal/obj/plist.go
+++ b/src/cmd/internal/obj/plist.go
@@ -19,7 +19,7 @@
 // It is used to provide access to cached/bulk-allocated Progs to the assemblers.
 type ProgAlloc func() *Prog
 
-func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc) {
+func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string) {
 	// Build list of symbols, and assign instructions to lists.
 	var curtext *LSym
 	var etext *Prog
@@ -106,7 +106,7 @@
 		ctxt.Arch.Preprocess(ctxt, s, newprog)
 		ctxt.Arch.Assemble(ctxt, s, newprog)
 		linkpcln(ctxt, s)
-		ctxt.populateDWARF(plist.Curfn, s)
+		ctxt.populateDWARF(plist.Curfn, s, myimportpath)
 	}
 }
 
@@ -136,13 +136,17 @@
 	ctxt.Text = append(ctxt.Text, s)
 
 	// Set up DWARF entries for s.
-	dsym, drsym := ctxt.dwarfSym(s)
-	dsym.Type = objabi.SDWARFINFO
-	dsym.Set(AttrDuplicateOK, s.DuplicateOK())
-	drsym.Type = objabi.SDWARFRANGE
-	drsym.Set(AttrDuplicateOK, s.DuplicateOK())
-	ctxt.Data = append(ctxt.Data, dsym)
-	ctxt.Data = append(ctxt.Data, drsym)
+	info, loc, ranges, _ := ctxt.dwarfSym(s)
+	info.Type = objabi.SDWARFINFO
+	info.Set(AttrDuplicateOK, s.DuplicateOK())
+	if loc != nil {
+		loc.Type = objabi.SDWARFLOC
+		loc.Set(AttrDuplicateOK, s.DuplicateOK())
+		ctxt.Data = append(ctxt.Data, loc)
+	}
+	ranges.Type = objabi.SDWARFRANGE
+	ranges.Set(AttrDuplicateOK, s.DuplicateOK())
+	ctxt.Data = append(ctxt.Data, info, ranges)
 
 	// Set up the function's gcargs and gclocals.
 	// They will be filled in later if needed.
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go
index 90a2047..e684281 100644
--- a/src/cmd/internal/obj/ppc64/a.out.go
+++ b/src/cmd/internal/obj/ppc64/a.out.go
@@ -396,6 +396,7 @@
 	AADDZECC
 	AADDZEVCC
 	AADDZEV
+	AADDEX
 	AAND
 	AANDCC
 	AANDN
@@ -412,6 +413,7 @@
 	ABVS // Unordered-set
 	ACMP
 	ACMPU
+	ACMPEQB
 	ACNTLZW
 	ACNTLZWCC
 	ACRAND
@@ -602,6 +604,8 @@
 
 	ARFCI
 
+	AFCPSGN
+	AFCPSGNCC
 	/* optional on 32-bit */
 	AFRES
 	AFRESCC
@@ -648,6 +652,8 @@
 	AFCFIDCC
 	AFCFIDU
 	AFCFIDUCC
+	AFCFIDS
+	AFCFIDSCC
 	AFCTID
 	AFCTIDCC
 	AFCTIDZ
@@ -712,6 +718,13 @@
 	APOPCNTD
 	APOPCNTW
 	APOPCNTB
+	ACOPY
+	APASTECC
+	ADARN
+	ALDMX
+	AMADDHD
+	AMADDHDU
+	AMADDLD
 
 	/* Vector */
 	ALV
@@ -781,6 +794,7 @@
 	AVPMSUMH
 	AVPMSUMW
 	AVPMSUMD
+	AVMSUMUDM
 	AVR
 	AVRLB
 	AVRLH
@@ -842,7 +856,11 @@
 	AVCMPGTSWCC
 	AVCMPGTSD
 	AVCMPGTSDCC
+	AVCMPNEZB
+	AVCMPNEZBCC
 	AVPERM
+	AVBPERMQ
+	AVBPERMD
 	AVSEL
 	AVSPLT
 	AVSPLTB
@@ -885,12 +903,15 @@
 	AMFFPRD
 	AMFVRD
 	AMFVSRWZ
+	AMFVSRLD
 	AMTVSR
 	AMTVSRD
 	AMTFPRD
 	AMTVRD
 	AMTVSRWA
 	AMTVSRWZ
+	AMTVSRDD
+	AMTVSRWS
 	AXXLAND
 	AXXLANDQ
 	AXXLANDC
diff --git a/src/cmd/internal/obj/ppc64/anames.go b/src/cmd/internal/obj/ppc64/anames.go
index 5ca2945..b7ca133 100644
--- a/src/cmd/internal/obj/ppc64/anames.go
+++ b/src/cmd/internal/obj/ppc64/anames.go
@@ -26,6 +26,7 @@
 	"ADDZECC",
 	"ADDZEVCC",
 	"ADDZEV",
+	"ADDEX",
 	"AND",
 	"ANDCC",
 	"ANDN",
@@ -42,6 +43,7 @@
 	"BVS",
 	"CMP",
 	"CMPU",
+	"CMPEQB",
 	"CNTLZW",
 	"CNTLZWCC",
 	"CRAND",
@@ -228,6 +230,8 @@
 	"SYSCALL",
 	"WORD",
 	"RFCI",
+	"FCPSGN",
+	"FCPSGNCC",
 	"FRES",
 	"FRESCC",
 	"FRIM",
@@ -269,6 +273,8 @@
 	"FCFIDCC",
 	"FCFIDU",
 	"FCFIDUCC",
+	"FCFIDS",
+	"FCFIDSCC",
 	"FCTID",
 	"FCTIDCC",
 	"FCTIDZ",
@@ -329,6 +335,13 @@
 	"POPCNTD",
 	"POPCNTW",
 	"POPCNTB",
+	"COPY",
+	"PASTECC",
+	"DARN",
+	"LDMX",
+	"MADDHD",
+	"MADDHDU",
+	"MADDLD",
 	"LV",
 	"LVEBX",
 	"LVEHX",
@@ -396,6 +409,7 @@
 	"VPMSUMH",
 	"VPMSUMW",
 	"VPMSUMD",
+	"VMSUMUDM",
 	"VR",
 	"VRLB",
 	"VRLH",
@@ -457,7 +471,11 @@
 	"VCMPGTSWCC",
 	"VCMPGTSD",
 	"VCMPGTSDCC",
+	"VCMPNEZB",
+	"VCMPNEZBCC",
 	"VPERM",
+	"VBPERMQ",
+	"VBPERMD",
 	"VSEL",
 	"VSPLT",
 	"VSPLTB",
@@ -498,12 +516,15 @@
 	"MFFPRD",
 	"MFVRD",
 	"MFVSRWZ",
+	"MFVSRLD",
 	"MTVSR",
 	"MTVSRD",
 	"MTFPRD",
 	"MTVRD",
 	"MTVSRWA",
 	"MTVSRWZ",
+	"MTVSRDD",
+	"MTVSRWS",
 	"XXLAND",
 	"XXLANDQ",
 	"XXLANDC",
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index 4d787b1..3938ceb 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -362,8 +362,14 @@
 	/* Other ISA 2.05+ instructions */
 	{APOPCNTD, C_REG, C_NONE, C_NONE, C_REG, 93, 4, 0},  /* population count, x-form */
 	{ACMPB, C_REG, C_REG, C_NONE, C_REG, 92, 4, 0},      /* compare byte, x-form */
+	{ACMPEQB, C_REG, C_REG, C_NONE, C_CREG, 92, 4, 0},   /* compare equal byte, x-form */
 	{AFTDIV, C_FREG, C_FREG, C_NONE, C_SCON, 92, 4, 0},  /* floating test for sw divide, x-form */
 	{AFTSQRT, C_FREG, C_NONE, C_NONE, C_SCON, 93, 4, 0}, /* floating test for sw square root, x-form */
+	{ACOPY, C_REG, C_NONE, C_NONE, C_REG, 92, 4, 0},     /* copy/paste facility, x-form */
+	{ADARN, C_SCON, C_NONE, C_NONE, C_REG, 92, 4, 0},    /* deliver random number, x-form */
+	{ALDMX, C_SOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},   /* load doubleword monitored, x-form */
+	{AMADDHD, C_REG, C_REG, C_REG, C_REG, 83, 4, 0},     /* multiply-add high/low doubleword, va-form */
+	{AADDEX, C_REG, C_REG, C_SCON, C_REG, 94, 4, 0},     /* add extended using alternate carry, z23-form */
 
 	/* Vector instructions */
 
@@ -392,7 +398,8 @@
 	{AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0},  /* vector subtract extended, va-form */
 
 	/* Vector multiply */
-	{AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector polynomial multiply & sum, vx-form */
+	{AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},   /* vector polynomial multiply & sum, vx-form */
+	{AVMSUMUDM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector multiply-sum, va-form */
 
 	/* Vector rotate */
 	{AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */
@@ -407,12 +414,16 @@
 	{AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */
 
 	/* Vector compare */
-	{AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */
-	{AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */
+	{AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},   /* vector compare equal, vc-form */
+	{AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},   /* vector compare greater than, vc-form */
+	{AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */
 
 	/* Vector permute */
 	{AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */
 
+	/* Vector bit permute */
+	{AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */
+
 	/* Vector select */
 	{AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */
 
@@ -455,6 +466,7 @@
 
 	/* VSX move to VSR */
 	{AMTVSR, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */
+	{AMTVSR, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},
 	{AMTVSR, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},
 	{AMTVSR, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},
 
@@ -537,7 +549,9 @@
 	{ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
 	{ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
 	{ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
-	{ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0},
+	{ADCBF, C_SOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
+	{ADCBF, C_ZOREG, C_REG, C_NONE, C_SCON, 43, 4, 0},
+	{ADCBF, C_SOREG, C_NONE, C_NONE, C_SCON, 43, 4, 0},
 	{AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
 	{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
 	{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
@@ -758,11 +772,6 @@
 			return C_GOTADDR
 
 		case obj.NAME_AUTO:
-			if a.Reg == REGSP {
-				// unset base register for better printing, since
-				// a.Offset is still relative to pseudo-SP.
-				a.Reg = obj.REG_NONE
-			}
 			c.instoffset = int64(c.autosize) + a.Offset
 			if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SAUTO
@@ -770,11 +779,6 @@
 			return C_LAUTO
 
 		case obj.NAME_PARAM:
-			if a.Reg == REGSP {
-				// unset base register for better printing, since
-				// a.Offset is still relative to pseudo-FP.
-				a.Reg = obj.REG_NONE
-			}
 			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
 			if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SAUTO
@@ -827,11 +831,6 @@
 			return C_LCON
 
 		case obj.NAME_AUTO:
-			if a.Reg == REGSP {
-				// unset base register for better printing, since
-				// a.Offset is still relative to pseudo-SP.
-				a.Reg = obj.REG_NONE
-			}
 			c.instoffset = int64(c.autosize) + a.Offset
 			if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SACON
@@ -839,11 +838,6 @@
 			return C_LACON
 
 		case obj.NAME_PARAM:
-			if a.Reg == REGSP {
-				// unset base register for better printing, since
-				// a.Offset is still relative to pseudo-FP.
-				a.Reg = obj.REG_NONE
-			}
 			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
 			if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SACON
@@ -911,11 +905,11 @@
 
 	a1--
 	a3 := C_NONE + 1
-	if p.From3 != nil {
-		a3 = int(p.From3.Class)
+	if p.GetFrom3() != nil {
+		a3 = int(p.GetFrom3().Class)
 		if a3 == 0 {
-			a3 = c.aclass(p.From3) + 1
-			p.From3.Class = int8(a3)
+			a3 = c.aclass(p.GetFrom3()) + 1
+			p.GetFrom3().Class = int8(a3)
 		}
 	}
 
@@ -1208,9 +1202,15 @@
 			opset(APOPCNTW, r0)
 			opset(APOPCNTB, r0)
 
+		case ACOPY: /* copy, paste. */
+			opset(APASTECC, r0)
+
+		case AMADDHD: /* maddhd, maddhdu, maddld */
+			opset(AMADDHDU, r0)
+			opset(AMADDLD, r0)
+
 		case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
 			opset(AMOVH, r0)
-
 			opset(AMOVHZ, r0)
 
 		case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
@@ -1375,9 +1375,15 @@
 			opset(AVCMPGTSD, r0)
 			opset(AVCMPGTSDCC, r0)
 
+		case AVCMPNEZB: /* vcmpnezb[.] */
+			opset(AVCMPNEZBCC, r0)
+
 		case AVPERM: /* vperm */
 			opset(AVPERM, r0)
 
+		case AVBPERMQ: /* vbpermq, vbpermd */
+			opset(AVBPERMD, r0)
+
 		case AVSEL: /* vsel */
 			opset(AVSEL, r0)
 
@@ -1428,18 +1434,21 @@
 		case ASTXSI: /* stxsiwx */
 			opset(ASTXSIWX, r0)
 
-		case AMFVSR: /* mfvsrd, mfvsrwz (and extended mnemonics) */
+		case AMFVSR: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
 			opset(AMFVSRD, r0)
 			opset(AMFFPRD, r0)
 			opset(AMFVRD, r0)
 			opset(AMFVSRWZ, r0)
+			opset(AMFVSRLD, r0)
 
-		case AMTVSR: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics) */
+		case AMTVSR: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
 			opset(AMTVSRD, r0)
 			opset(AMTFPRD, r0)
 			opset(AMTVRD, r0)
 			opset(AMTVSRWA, r0)
 			opset(AMTVSRWZ, r0)
+			opset(AMTVSRDD, r0)
+			opset(AMTVSRWS, r0)
 
 		case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
 			opset(AXXLANDQ, r0)
@@ -1595,6 +1604,8 @@
 			opset(AFCFIDCC, r0)
 			opset(AFCFIDU, r0)
 			opset(AFCFIDUCC, r0)
+			opset(AFCFIDS, r0)
+			opset(AFCFIDSCC, r0)
 			opset(AFRES, r0)
 			opset(AFRESCC, r0)
 			opset(AFRIM, r0)
@@ -1614,6 +1625,8 @@
 			opset(AFADDS, r0)
 			opset(AFADDCC, r0)
 			opset(AFADDSCC, r0)
+			opset(AFCPSGN, r0)
+			opset(AFCPSGNCC, r0)
 			opset(AFDIV, r0)
 			opset(AFDIVS, r0)
 			opset(AFDIVCC, r0)
@@ -1797,6 +1810,11 @@
 			ASLBMTE,
 			AWORD,
 			ADWORD,
+			ADARN,
+			ALDMX,
+			AVMSUMUDM,
+			AADDEX,
+			ACMPEQB,
 			obj.ANOP,
 			obj.ATEXT,
 			obj.AUNDEF,
@@ -1924,6 +1942,11 @@
 	return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xc&31)<<6 | (xc&32)>>2 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
 }
 
+/* Z23-form, 3-register operands + CY field */
+func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
+	return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
+}
+
 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
 	return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
 }
@@ -2448,7 +2471,7 @@
 		if r == 0 {
 			r = int(p.To.Reg)
 		}
-		d := c.vregoff(p.From3)
+		d := c.vregoff(p.GetFrom3())
 		var a int
 		switch p.As {
 
@@ -2701,7 +2724,7 @@
 		o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
 
 	case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
-		v := c.regoff(p.From3)
+		v := c.regoff(p.GetFrom3())
 
 		r := int(p.From.Reg)
 		o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
@@ -2710,7 +2733,7 @@
 		if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
 			c.ctxt.Diag("can't synthesize large constant\n%v", p)
 		}
-		v := c.regoff(p.From3)
+		v := c.regoff(p.GetFrom3())
 		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
 		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
 		o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
@@ -2723,7 +2746,7 @@
 	case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
 		v := c.regoff(&p.From)
 
-		d := c.vregoff(p.From3)
+		d := c.vregoff(p.GetFrom3())
 		var mask [2]uint8
 		c.maskgen64(p, mask[:], uint64(d))
 		var a int
@@ -2763,7 +2786,7 @@
 	case 30: /* rldimi $sh,s,$mask,a */
 		v := c.regoff(&p.From)
 
-		d := c.vregoff(p.From3)
+		d := c.vregoff(p.GetFrom3())
 
 		// Original opcodes had mask operands which had to be converted to a shift count as expected by
 		// the ppc64 asm.
@@ -2834,7 +2857,7 @@
 		o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
 
 	case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
-		o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
+		o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
 
 	case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
 		v := c.regoff(&p.To)
@@ -2876,13 +2899,28 @@
 		o1 = uint32(c.regoff(&p.From))
 
 	case 41: /* stswi */
-		o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.From3))&0x7F)<<11
+		o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
 
 	case 42: /* lswi */
-		o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.From3))&0x7F)<<11
+		o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
 
-	case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
-		o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
+	case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
+		/* TH field for dcbt/dcbtst: */
+		/* 0 = Block access - program will soon access EA. */
+		/* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
+		/* 16 = Block access - program will soon make a transient access to EA. */
+		/* 17 = Block access - program will not access EA for a long time. */
+
+		/* L field for dcbf: */
+		/* 0 = invalidates the block containing EA in all processors. */
+		/* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
+		/* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
+		if p.To.Type == obj.TYPE_NONE {
+			o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
+		} else {
+			th := c.regoff(&p.To)
+			o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
+		}
 
 	case 44: /* indexed store */
 		o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
@@ -3049,13 +3087,13 @@
 		v := c.regoff(&p.From)
 
 		var mask [2]uint8
-		c.maskgen(p, mask[:], uint32(c.regoff(p.From3)))
+		c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
 		o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
 		o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
 
 	case 63: /* rlwmi b,s,$mask,a */
 		var mask [2]uint8
-		c.maskgen(p, mask[:], uint32(c.regoff(p.From3)))
+		c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
 
 		o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
 		o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
@@ -3063,7 +3101,7 @@
 	case 64: /* mtfsf fr[, $m] {,fpcsr} */
 		var v int32
 		if p.From3Type() != obj.TYPE_NONE {
-			v = c.regoff(p.From3) & 255
+			v = c.regoff(p.GetFrom3()) & 255
 		} else {
 			v = 255
 		}
@@ -3118,7 +3156,7 @@
 			if p.To.Reg != 0 {
 				c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
 			}
-			v = c.regoff(p.From3) & 0xff
+			v = c.regoff(p.GetFrom3()) & 0xff
 		} else {
 			if p.To.Reg == 0 {
 				v = 0xff /* CR */
@@ -3257,7 +3295,7 @@
 			/* imm imm reg reg */
 			/* operand order: SIX, VRA, ST, VRT */
 			six := int(c.regoff(&p.From))
-			st := int(c.regoff(p.From3))
+			st := int(c.regoff(p.GetFrom3()))
 			o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
 		} else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
 			/* imm reg reg */
@@ -3275,19 +3313,19 @@
 		if p.From.Type == obj.TYPE_REG {
 			/* reg reg reg reg */
 			/* 4-register operand order: VRA, VRB, VRC, VRT */
-			o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.From3.Reg))
+			o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
 		} else if p.From.Type == obj.TYPE_CONST {
 			/* imm reg reg reg */
 			/* operand order: SHB, VRA, VRB, VRT */
 			shb := int(c.regoff(&p.From))
-			o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), uint32(shb))
+			o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
 		}
 
 	case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
 		bc := c.vregoff(&p.From)
 
 		// rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
-		o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), uint32(bc))
+		o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
 
 	case 85: /* vector instructions, VX-form */
 		/* reg none reg */
@@ -3335,7 +3373,7 @@
 	case 89: /* VSX instructions, XX2-form */
 		/* reg none reg OR reg imm reg */
 		/* 2-register operand order: XB, XT or XB, UIM, XT*/
-		uim := int(c.regoff(p.From3))
+		uim := int(c.regoff(p.GetFrom3()))
 		o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
 
 	case 90: /* VSX instructions, XX3-form */
@@ -3346,25 +3384,55 @@
 		} else if p.From3Type() == obj.TYPE_CONST {
 			/* reg reg reg imm */
 			/* operand order: XA, XB, DM, XT */
-			dm := int(c.regoff(p.From3))
+			dm := int(c.regoff(p.GetFrom3()))
 			o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
 		}
 
 	case 91: /* VSX instructions, XX4-form */
 		/* reg reg reg reg */
 		/* 3-register operand order: XA, XB, XC, XT */
-		o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.From3.Reg))
+		o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
 
 	case 92: /* X-form instructions, 3-operands */
 		if p.To.Type == obj.TYPE_CONST {
 			/* imm reg reg */
-			/* operand order: FRA, FRB, BF */
-			bf := int(c.regoff(&p.To)) << 2
-			o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
+			xf := int32(p.From.Reg)
+			if REG_F0 <= xf && xf <= REG_F31 {
+				/* operand order: FRA, FRB, BF */
+				bf := int(c.regoff(&p.To)) << 2
+				o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
+			} else {
+				/* operand order: RA, RB, L */
+				l := int(c.regoff(&p.To))
+				o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
+			}
+		} else if p.From3Type() == obj.TYPE_CONST {
+			/* reg reg imm */
+			/* operand order: RB, L, RA */
+			l := int(c.regoff(p.GetFrom3()))
+			o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
 		} else if p.To.Type == obj.TYPE_REG {
-			/* reg reg reg */
-			/* operand order: RS, RB, RA */
-			o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
+			cr := int32(p.To.Reg)
+			if REG_CR0 <= cr && cr <= REG_CR7 {
+				/* cr reg reg */
+				/* operand order: RA, RB, BF */
+				bf := (int(p.To.Reg) & 7) << 2
+				o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
+			} else if p.From.Type == obj.TYPE_CONST {
+				/* reg imm */
+				/* operand order: L, RT */
+				l := int(c.regoff(&p.From))
+				o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
+			} else {
+				switch p.As {
+				case ACOPY, APASTECC:
+					o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
+				default:
+					/* reg reg reg */
+					/* operand order: RS, RB, RA */
+					o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
+				}
+			}
 		}
 
 	case 93: /* X-form instructions, 2-operands */
@@ -3379,6 +3447,11 @@
 			o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
 		}
 
+	case 94: /* Z23-form instructions, 4-operands */
+		/* reg reg reg imm */
+		/* operand order: RA, RB, CY, RT */
+		cy := int(c.regoff(p.GetFrom3()))
+		o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
 	}
 
 	out[0] = o1
@@ -3443,6 +3516,8 @@
 		return OPVCC(31, 202, 1, 0)
 	case AADDZEVCC:
 		return OPVCC(31, 202, 1, 1)
+	case AADDEX:
+		return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
 
 	case AAND:
 		return OPVCC(31, 28, 0, 0)
@@ -3608,6 +3683,10 @@
 		return OPVCC(63, 974, 0, 0)
 	case AFCFIDUCC:
 		return OPVCC(63, 974, 0, 1)
+	case AFCFIDS:
+		return OPVCC(59, 846, 0, 0)
+	case AFCFIDSCC:
+		return OPVCC(59, 846, 0, 1)
 	case AFCTIW:
 		return OPVCC(63, 14, 0, 0)
 	case AFCTIWCC:
@@ -3685,6 +3764,10 @@
 		return OPVCC(59, 30, 0, 0)
 	case AFNMSUBSCC:
 		return OPVCC(59, 30, 0, 1)
+	case AFCPSGN:
+		return OPVCC(63, 8, 0, 0)
+	case AFCPSGNCC:
+		return OPVCC(63, 8, 0, 1)
 	case AFRES:
 		return OPVCC(59, 24, 0, 0)
 	case AFRESCC:
@@ -4008,6 +4091,9 @@
 	case AVPMSUMD:
 		return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
 
+	case AVMSUMUDM:
+		return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
+
 	case AVSUBUBM:
 		return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
 	case AVSUBUHM:
@@ -4086,6 +4172,11 @@
 	case AVSRAD:
 		return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
 
+	case AVBPERMQ:
+		return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
+	case AVBPERMD:
+		return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
+
 	case AVCLZB:
 		return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
 	case AVCLZH:
@@ -4154,6 +4245,11 @@
 	case AVCMPGTSDCC:
 		return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
 
+	case AVCMPNEZB:
+		return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
+	case AVCMPNEZBCC:
+		return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
+
 	case AVPERM:
 		return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
 
@@ -4178,6 +4274,8 @@
 		return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
 	case AMFVSRWZ:
 		return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
+	case AMFVSRLD:
+		return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
 
 	case AMTVSRD, AMTFPRD, AMTVRD:
 		return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
@@ -4185,6 +4283,10 @@
 		return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
 	case AMTVSRWZ:
 		return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
+	case AMTVSRDD:
+		return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
+	case AMTVSRWS:
+		return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
 
 	case AXXLANDQ:
 		return OPVXX3(60, 130, 0) /* xxland - v2.06 */
@@ -4288,6 +4390,13 @@
 		return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
 	/* End of VSX instructions */
 
+	case AMADDHD:
+		return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
+	case AMADDHDU:
+		return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
+	case AMADDLD:
+		return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
+
 	case AXOR:
 		return OPVCC(31, 316, 0, 0)
 	case AXORCC:
@@ -4379,9 +4488,19 @@
 		return OPVCC(11, 0, 0, 0) /* L=0 */
 	case ACMPWU:
 		return OPVCC(10, 0, 0, 0)
+	case ACMPEQB:
+		return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
+
 	case ALSW:
 		return OPVCC(31, 597, 0, 0)
 
+	case ACOPY:
+		return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
+	case APASTECC:
+		return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
+	case ADARN:
+		return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
+
 	case AMULLW:
 		return OPVCC(7, 0, 0, 0)
 
@@ -4579,6 +4698,8 @@
 		return OPVCC(31, 21, 0, 0) /* ldx */
 	case AMOVDU:
 		return OPVCC(31, 53, 0, 0) /* ldux */
+	case ALDMX:
+		return OPVCC(31, 309, 0, 0) /* ldmx */
 
 	/* Vector (VMX/Altivec) instructions */
 	/* ISA 2.03 enables these for PPC970. For POWERx processors, these */
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index b1509e3..c50cd3b 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -176,7 +176,7 @@
 			p.From.Offset = 0
 		}
 	}
-	if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
+	if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
 		c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
 	}
 	var source *obj.Addr
diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go
index 9d5b34a..54c1edb 100644
--- a/src/cmd/internal/obj/s390x/a.out.go
+++ b/src/cmd/internal/obj/s390x/a.out.go
@@ -283,12 +283,15 @@
 	AFNEGS
 	ALEDBR
 	ALDEBR
+	ALPDFR
+	ALNDFR
 	AFSUB
 	AFSUBS
 	AFSQRT
 	AFSQRTS
 	AFIEBR
 	AFIDBR
+	ACPSDR
 
 	// move from GPR to FPR and vice versa
 	ALDGR
@@ -324,6 +327,12 @@
 	ACMPW
 	ACMPWU
 
+	// test under mask
+	ATMHH
+	ATMHL
+	ATMLH
+	ATMLL
+
 	// compare and swap
 	ACS
 	ACSG
diff --git a/src/cmd/internal/obj/s390x/anames.go b/src/cmd/internal/obj/s390x/anames.go
index 42a0222..8488ccc 100644
--- a/src/cmd/internal/obj/s390x/anames.go
+++ b/src/cmd/internal/obj/s390x/anames.go
@@ -81,12 +81,15 @@
 	"FNEGS",
 	"LEDBR",
 	"LDEBR",
+	"LPDFR",
+	"LNDFR",
 	"FSUB",
 	"FSUBS",
 	"FSQRT",
 	"FSQRTS",
 	"FIEBR",
 	"FIDBR",
+	"CPSDR",
 	"LDGR",
 	"LGDR",
 	"CEFBRA",
@@ -109,6 +112,10 @@
 	"CMPU",
 	"CMPW",
 	"CMPWU",
+	"TMHH",
+	"TMHL",
+	"TMLH",
+	"TMLL",
 	"CS",
 	"CSG",
 	"SYNC",
diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
index 6d2b870..7304ab3 100644
--- a/src/cmd/internal/obj/s390x/asmz.go
+++ b/src/cmd/internal/obj/s390x/asmz.go
@@ -212,6 +212,7 @@
 	Optab{ACEFBRA, C_REG, C_NONE, C_NONE, C_FREG, 82, 0},
 	Optab{ACFEBRA, C_FREG, C_NONE, C_NONE, C_REG, 83, 0},
 	Optab{AFIEBR, C_SCON, C_FREG, C_NONE, C_FREG, 48, 0},
+	Optab{ACPSDR, C_FREG, C_FREG, C_NONE, C_FREG, 49, 0},
 
 	// load symbol address (plus offset)
 	Optab{AMOVD, C_SYMADDR, C_NONE, C_NONE, C_REG, 19, 0},
@@ -251,6 +252,9 @@
 	Optab{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 0},
 	Optab{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 0},
 
+	// test under mask
+	Optab{ATMHH, C_REG, C_NONE, C_NONE, C_ANDCON, 91, 0},
+
 	// 32-bit access registers
 	Optab{AMOVW, C_AREG, C_NONE, C_NONE, C_REG, 68, 0},
 	Optab{AMOVWZ, C_AREG, C_NONE, C_NONE, C_REG, 68, 0},
@@ -654,11 +658,11 @@
 
 	a1--
 	a3 := C_NONE + 1
-	if p.From3 != nil {
-		a3 = int(p.From3.Class)
+	if p.GetFrom3() != nil {
+		a3 = int(p.GetFrom3().Class)
 		if a3 == 0 {
-			a3 = c.aclass(p.From3) + 1
-			p.From3.Class = int8(a3)
+			a3 = c.aclass(p.GetFrom3()) + 1
+			p.GetFrom3().Class = int8(a3)
 		}
 	}
 
@@ -897,6 +901,8 @@
 			opset(ABCL, r)
 		case AFABS:
 			opset(AFNABS, r)
+			opset(ALPDFR, r)
+			opset(ALNDFR, r)
 			opset(AFNEG, r)
 			opset(AFNEGS, r)
 			opset(ALEDBR, r)
@@ -948,6 +954,10 @@
 			opset(ACMPW, r)
 		case ACMPU:
 			opset(ACMPWU, r)
+		case ATMHH:
+			opset(ATMHL, r)
+			opset(ATMLH, r)
+			opset(ATMLL, r)
 		case ACEFBRA:
 			opset(ACDFBRA, r)
 			opset(ACEGBRA, r)
@@ -3182,6 +3192,10 @@
 			opcode = op_LPDBR
 		case AFNABS:
 			opcode = op_LNDBR
+		case ALPDFR:
+			opcode = op_LPDFR
+		case ALNDFR:
+			opcode = op_LNDFR
 		case AFNEG:
 			opcode = op_LCDFR
 		case AFNEGS:
@@ -3281,6 +3295,9 @@
 		}
 		zRRF(opcode, uint32(m3), 0, uint32(p.To.Reg), uint32(p.Reg), asm)
 
+	case 49: // copysign
+		zRRF(op_CPSDR, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(p.Reg), asm)
+
 	case 67: // fmov $0 freg
 		var opcode uint32
 		switch p.As {
@@ -3534,11 +3551,11 @@
 		if l < 1 || l > 256 {
 			c.ctxt.Diag("number of bytes (%v) not in range [1,256]", l)
 		}
-		if p.From3.Index != 0 || p.To.Index != 0 {
+		if p.GetFrom3().Index != 0 || p.To.Index != 0 {
 			c.ctxt.Diag("cannot use index reg")
 		}
 		b1 := p.To.Reg
-		b2 := p.From3.Reg
+		b2 := p.GetFrom3().Reg
 		if b1 == 0 {
 			b1 = o.param
 		}
@@ -3546,7 +3563,7 @@
 			b2 = o.param
 		}
 		d1 := c.regoff(&p.To)
-		d2 := c.regoff(p.From3)
+		d2 := c.regoff(p.GetFrom3())
 		if d1 < 0 || d1 >= DISP12 {
 			if b2 == REGTMP {
 				c.ctxt.Diag("REGTMP conflict")
@@ -3688,12 +3705,26 @@
 		}
 		mask := c.branchMask(p)
 		if int32(int16(v)) != v {
-			zRIL(_a, opcode2, uint32(p.From.Reg), uint32(c.regoff(p.From3)), asm)
+			zRIL(_a, opcode2, uint32(p.From.Reg), uint32(c.regoff(p.GetFrom3())), asm)
 			zRIL(_c, op_BRCL, mask, uint32(v-sizeRIL/2), asm)
 		} else {
-			zRIE(_c, opcode, uint32(p.From.Reg), mask, uint32(v), 0, 0, 0, uint32(c.regoff(p.From3)), asm)
+			zRIE(_c, opcode, uint32(p.From.Reg), mask, uint32(v), 0, 0, 0, uint32(c.regoff(p.GetFrom3())), asm)
 		}
 
+	case 91: // test under mask (immediate)
+		var opcode uint32
+		switch p.As {
+		case ATMHH:
+			opcode = op_TMHH
+		case ATMHL:
+			opcode = op_TMHL
+		case ATMLH:
+			opcode = op_TMLH
+		case ATMLL:
+			opcode = op_TMLL
+		}
+		zRI(opcode, uint32(p.From.Reg), uint32(c.vregoff(&p.To)), asm)
+
 	case 93: // GOT lookup
 		v := c.vregoff(&p.To)
 		if v != 0 {
@@ -3893,9 +3924,9 @@
 	case 101: // VRX LOAD
 		op, m3, _ := vop(p.As)
 		src := &p.From
-		if p.From3 != nil {
+		if p.GetFrom3() != nil {
 			m3 = uint32(c.vregoff(&p.From))
-			src = p.From3
+			src = p.GetFrom3()
 		}
 		b2 := src.Reg
 		if b2 == 0 {
@@ -3917,12 +3948,12 @@
 	case 103: // VRV GATHER
 		op, _, _ := vop(p.As)
 		m3 := uint32(c.vregoff(&p.From))
-		b2 := p.From3.Reg
+		b2 := p.GetFrom3().Reg
 		if b2 == 0 {
 			b2 = o.param
 		}
-		d2 := uint32(c.vregoff(p.From3))
-		zVRV(op, uint32(p.To.Reg), uint32(p.From3.Index), uint32(b2), d2, m3, asm)
+		d2 := uint32(c.vregoff(p.GetFrom3()))
+		zVRV(op, uint32(p.To.Reg), uint32(p.GetFrom3().Index), uint32(b2), d2, m3, asm)
 
 	case 104: // VRS SHIFT/ROTATE and LOAD GR FROM VR ELEMENT
 		op, m4, _ := vop(p.As)
@@ -3962,8 +3993,8 @@
 
 	case 108: // VRS LOAD WITH LENGTH
 		op, _, _ := vop(p.As)
-		offset := uint32(c.vregoff(p.From3))
-		reg := p.From3.Reg
+		offset := uint32(c.vregoff(p.GetFrom3()))
+		reg := p.GetFrom3().Reg
 		if reg == 0 {
 			reg = o.param
 		}
@@ -3972,9 +4003,9 @@
 	case 109: // VRI-a
 		op, m3, _ := vop(p.As)
 		i2 := uint32(c.vregoff(&p.From))
-		if p.From3 != nil {
+		if p.GetFrom3() != nil {
 			m3 = uint32(c.vregoff(&p.From))
-			i2 = uint32(c.vregoff(p.From3))
+			i2 = uint32(c.vregoff(p.GetFrom3()))
 		}
 		switch p.As {
 		case AVZERO:
@@ -3987,7 +4018,7 @@
 	case 110:
 		op, m4, _ := vop(p.As)
 		i2 := uint32(c.vregoff(&p.From))
-		i3 := uint32(c.vregoff(p.From3))
+		i3 := uint32(c.vregoff(p.GetFrom3()))
 		zVRIb(op, uint32(p.To.Reg), i2, i3, m4, asm)
 
 	case 111:
@@ -3998,7 +4029,7 @@
 	case 112:
 		op, m5, _ := vop(p.As)
 		i4 := uint32(c.vregoff(&p.From))
-		zVRId(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), i4, m5, asm)
+		zVRId(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), i4, m5, asm)
 
 	case 113:
 		op, m4, _ := vop(p.As)
@@ -4044,7 +4075,7 @@
 		v1 := uint32(p.To.Reg)
 		v2 := uint32(p.From.Reg)
 		v3 := uint32(p.Reg)
-		v4 := uint32(p.From3.Reg)
+		v4 := uint32(p.GetFrom3().Reg)
 		zVRRd(op, v1, v2, v3, m6, m5, v4, asm)
 
 	case 121: // VRR-e
@@ -4053,7 +4084,7 @@
 		v1 := uint32(p.To.Reg)
 		v2 := uint32(p.From.Reg)
 		v3 := uint32(p.Reg)
-		v4 := uint32(p.From3.Reg)
+		v4 := uint32(p.GetFrom3().Reg)
 		zVRRe(op, v1, v2, v3, m6, m5, v4, asm)
 
 	case 122: // VRR-f LOAD VRS FROM GRS DISJOINT
@@ -4063,7 +4094,7 @@
 	case 123: // VPDI $m4, V2, V3, V1
 		op, _, _ := vop(p.As)
 		m4 := c.regoff(&p.From)
-		zVRRc(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), 0, 0, uint32(m4), asm)
+		zVRRc(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), 0, 0, uint32(m4), asm)
 	}
 }
 
diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go
index 3d3571a..45ce68b 100644
--- a/src/cmd/internal/obj/s390x/objz.go
+++ b/src/cmd/internal/obj/s390x/objz.go
@@ -122,9 +122,11 @@
 	// We only care about global data: NAME_EXTERN means a global
 	// symbol in the Go sense, and p.Sym.Local is true for a few
 	// internally defined symbols.
+	// Rewrites must not clobber flags and therefore cannot use the
+	// ADD instruction.
 	if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
 		// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
-		// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
+		// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx or REGTMP2; MOVD $<off>(Rx or REGTMP2), Rx
 		if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
 			c.ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
 		}
@@ -132,20 +134,28 @@
 		p.From.Name = obj.NAME_GOTREF
 		q := p
 		if p.From.Offset != 0 {
-			q = obj.Appendp(p, c.newprog)
-			q.As = AADD
-			q.From.Type = obj.TYPE_CONST
+			target := p.To.Reg
+			if target == REG_R0 {
+				// Cannot use R0 as input to address calculation.
+				// REGTMP might be used by the assembler.
+				p.To.Reg = REGTMP2
+			}
+			q = obj.Appendp(q, c.newprog)
+			q.As = AMOVD
+			q.From.Type = obj.TYPE_ADDR
 			q.From.Offset = p.From.Offset
-			q.To = p.To
+			q.From.Reg = p.To.Reg
+			q.To.Type = obj.TYPE_REG
+			q.To.Reg = target
 			p.From.Offset = 0
 		}
 	}
-	if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
+	if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
 		c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
 	}
 	var source *obj.Addr
-	// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
-	// MOVD Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP)
+	// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP2; MOVD (REGTMP2), Ry
+	// MOVD Ry, sym becomes MOVD sym@GOT, REGTMP2; MOVD Ry, (REGTMP2)
 	// An addition may be inserted between the two MOVs if there is an offset.
 	if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
 		if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
@@ -174,17 +184,17 @@
 	p1.From.Sym = source.Sym
 	p1.From.Name = obj.NAME_GOTREF
 	p1.To.Type = obj.TYPE_REG
-	p1.To.Reg = REGTMP
+	p1.To.Reg = REGTMP2
 
 	p2.As = p.As
 	p2.From = p.From
 	p2.To = p.To
 	if p.From.Name == obj.NAME_EXTERN {
-		p2.From.Reg = REGTMP
+		p2.From.Reg = REGTMP2
 		p2.From.Name = obj.NAME_NONE
 		p2.From.Sym = nil
 	} else if p.To.Name == obj.NAME_EXTERN {
-		p2.To.Reg = REGTMP
+		p2.To.Reg = REGTMP2
 		p2.To.Name = obj.NAME_NONE
 		p2.To.Sym = nil
 	} else {
diff --git a/src/cmd/internal/obj/sizeof_test.go b/src/cmd/internal/obj/sizeof_test.go
index 601e9e2..e70d174 100644
--- a/src/cmd/internal/obj/sizeof_test.go
+++ b/src/cmd/internal/obj/sizeof_test.go
@@ -24,7 +24,7 @@
 	}{
 		{Addr{}, 32, 48},
 		{LSym{}, 56, 104},
-		{Prog{}, 124, 184},
+		{Prog{}, 132, 200},
 	}
 
 	for _, tt := range tests {
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 3fb2df1..3fc17fa 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -45,8 +45,7 @@
 	ctxt.Arch = arch
 	ctxt.Pathname = objabi.WorkingDir()
 
-	ctxt.Headtype.Set(objabi.GOOS)
-	if ctxt.Headtype < 0 {
+	if err := ctxt.Headtype.Set(objabi.GOOS); err != nil {
 		log.Fatalf("unknown goos %s", objabi.GOOS)
 	}
 
diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go
index 9bcdbbd..245e9e9 100644
--- a/src/cmd/internal/obj/util.go
+++ b/src/cmd/internal/obj/util.go
@@ -13,8 +13,31 @@
 
 const REG_NONE = 0
 
+// Line returns a string containing the filename and line number for p
 func (p *Prog) Line() string {
-	return p.Ctxt.OutermostPos(p.Pos).Format(false)
+	return p.Ctxt.OutermostPos(p.Pos).Format(false, true)
+}
+
+// InnermostLineNumber returns a string containing the line number for the
+// innermost inlined function (if any inlining) at p's position
+func (p *Prog) InnermostLineNumber() string {
+	pos := p.Ctxt.InnermostPos(p.Pos)
+	if !pos.IsKnown() {
+		return "?"
+	}
+	return fmt.Sprintf("%d", pos.Line())
+}
+
+// InnermostFilename returns a string containing the innermost
+// (in inlining) filename at p's position
+func (p *Prog) InnermostFilename() string {
+	// TODO For now, this is only used for debugging output, and if we need more/better information, it might change.
+	// An example of what we might want to see is the full stack of positions for inlined code, so we get some visibility into what is recorded there.
+	pos := p.Ctxt.InnermostPos(p.Pos)
+	if !pos.IsKnown() {
+		return "<unknown file name>"
+	}
+	return pos.Filename()
 }
 
 var armCondCode = []string{
@@ -72,6 +95,18 @@
 	if p == nil {
 		return "<nil Prog>"
 	}
+	if p.Ctxt == nil {
+		return "<Prog without ctxt>"
+	}
+	return fmt.Sprintf("%.5d (%v)\t%s", p.Pc, p.Line(), p.InstructionString())
+}
+
+// InstructionString returns a string representation of the instruction without preceding
+// program counter or file and line number.
+func (p *Prog) InstructionString() string {
+	if p == nil {
+		return "<nil Prog>"
+	}
 
 	if p.Ctxt == nil {
 		return "<Prog without ctxt>"
@@ -81,13 +116,9 @@
 
 	var buf bytes.Buffer
 
-	fmt.Fprintf(&buf, "%.5d (%v)\t%v%s", p.Pc, p.Line(), p.As, sc)
+	fmt.Fprintf(&buf, "%v%s", p.As, sc)
 	sep := "\t"
-	quadOpAmd64 := p.RegTo2 == -1
-	if quadOpAmd64 {
-		fmt.Fprintf(&buf, "%s$%d", sep, p.From3.Offset)
-		sep = ", "
-	}
+
 	if p.From.Type != TYPE_NONE {
 		fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.From))
 		sep = ", "
@@ -97,14 +128,11 @@
 		fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.Reg)))
 		sep = ", "
 	}
-	if p.From3Type() != TYPE_NONE {
-		if quadOpAmd64 {
-			fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg)))
-		} else {
-			fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3))
-		}
+	for i := range p.RestArgs {
+		fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.RestArgs[i]))
 		sep = ", "
 	}
+
 	if p.As == ATEXT {
 		// If there are attributes, print them. Otherwise, skip the comma.
 		// In short, print one of these two:
@@ -119,7 +147,7 @@
 	if p.To.Type != TYPE_NONE {
 		fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
 	}
-	if p.RegTo2 != REG_NONE && !quadOpAmd64 {
+	if p.RegTo2 != REG_NONE {
 		fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.RegTo2)))
 	}
 	return buf.String()
@@ -157,7 +185,7 @@
 		//	PINSRQ	CX,$1,X6
 		// where the $1 is included in the p->to Addr.
 		// Move into a new field.
-		if a.Offset != 0 {
+		if a.Offset != 0 && (a.Reg < RBaseARM64 || a.Reg >= RBaseMIPS) {
 			str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
 			break
 		}
@@ -166,6 +194,10 @@
 		if a.Name != NAME_NONE || a.Sym != nil {
 			str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
 		}
+		if (RBaseARM64+1<<10+1<<9) /* arm64.REG_ELEM */ <= a.Reg &&
+			a.Reg < (RBaseARM64+1<<11) /* arm64.REG_ELEM_END */ {
+			str += fmt.Sprintf("[%d]", a.Index)
+		}
 
 	case TYPE_BRANCH:
 		if a.Sym != nil {
@@ -243,7 +275,7 @@
 		str = fmt.Sprintf("%v, %v", Rconv(int(a.Offset)), Rconv(int(a.Reg)))
 
 	case TYPE_REGLIST:
-		str = regListConv(int(a.Offset))
+		str = RLconv(a.Offset)
 	}
 
 	return str
@@ -380,27 +412,40 @@
 	return fmt.Sprintf("R???%d", reg)
 }
 
-func regListConv(list int) string {
-	str := ""
+type regListSet struct {
+	lo     int64
+	hi     int64
+	RLconv func(int64) string
+}
 
-	for i := 0; i < 16; i++ { // TODO: 16 is ARM-specific.
-		if list&(1<<uint(i)) != 0 {
-			if str == "" {
-				str += "["
-			} else {
-				str += ","
-			}
-			// This is ARM-specific; R10 is g.
-			if i == 10 {
-				str += "g"
-			} else {
-				str += fmt.Sprintf("R%d", i)
-			}
+var regListSpace []regListSet
+
+// Each architecture is allotted a distinct subspace: [Lo, Hi) for declaring its
+// arch-specific register list numbers.
+const (
+	RegListARMLo = 0
+	RegListARMHi = 1 << 16
+
+	// arm64 uses the 60th bit to differentiate from other archs
+	RegListARM64Lo = 1 << 60
+	RegListARM64Hi = 1<<61 - 1
+)
+
+// RegisterRegisterList binds a pretty-printer (RLconv) for register list
+// numbers to a given register list number range. Lo is inclusive,
+// hi exclusive (valid register list are lo through hi-1).
+func RegisterRegisterList(lo, hi int64, rlconv func(int64) string) {
+	regListSpace = append(regListSpace, regListSet{lo, hi, rlconv})
+}
+
+func RLconv(list int64) string {
+	for i := range regListSpace {
+		rls := &regListSpace[i]
+		if rls.lo <= list && list < rls.hi {
+			return rls.RLconv(list)
 		}
 	}
-
-	str += "]"
-	return str
+	return fmt.Sprintf("RL???%d", list)
 }
 
 type opSet struct {
diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
index 04f9ef6..3799789 100644
--- a/src/cmd/internal/obj/x86/a.out.go
+++ b/src/cmd/internal/obj/x86/a.out.go
@@ -32,809 +32,9 @@
 
 import "cmd/internal/obj"
 
-//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p x86
-
 const (
 	/* mark flags */
-	DONE          = 1 << iota
-	PRESERVEFLAGS // not allowed to clobber flags
-)
-
-/*
- *	amd64
- */
-const (
-	AAAA = obj.ABaseAMD64 + obj.A_ARCHSPECIFIC + iota
-	AAAD
-	AAAM
-	AAAS
-	AADCB
-	AADCL
-	AADCW
-	AADDB
-	AADDL
-	AADDW
-	AADJSP
-	AANDB
-	AANDL
-	AANDW
-	AARPL
-	ABOUNDL
-	ABOUNDW
-	ABSFL
-	ABSFW
-	ABSRL
-	ABSRW
-	ABTL
-	ABTW
-	ABTCL
-	ABTCW
-	ABTRL
-	ABTRW
-	ABTSL
-	ABTSW
-	ABYTE
-	ACLC
-	ACLD
-	ACLI
-	ACLTS
-	ACMC
-	ACMPB
-	ACMPL
-	ACMPW
-	ACMPSB
-	ACMPSL
-	ACMPSW
-	ADAA
-	ADAS
-	ADECB
-	ADECL
-	ADECQ
-	ADECW
-	ADIVB
-	ADIVL
-	ADIVW
-	AENTER
-	AHADDPD
-	AHADDPS
-	AHLT
-	AHSUBPD
-	AHSUBPS
-	AIDIVB
-	AIDIVL
-	AIDIVW
-	AIMULB
-	AIMULL
-	AIMULW
-	AINB
-	AINL
-	AINW
-	AINCB
-	AINCL
-	AINCQ
-	AINCW
-	AINSB
-	AINSL
-	AINSW
-	AINT
-	AINTO
-	AIRETL
-	AIRETW
-	AJCC // >= unsigned
-	AJCS // < unsigned
-	AJCXZL
-	AJEQ // == (zero)
-	AJGE // >= signed
-	AJGT // > signed
-	AJHI // > unsigned
-	AJLE // <= signed
-	AJLS // <= unsigned
-	AJLT // < signed
-	AJMI // sign bit set (negative)
-	AJNE // != (nonzero)
-	AJOC // overflow clear
-	AJOS // overflow set
-	AJPC // parity clear
-	AJPL // sign bit clear (positive)
-	AJPS // parity set
-	ALAHF
-	ALARL
-	ALARW
-	ALEAL
-	ALEAW
-	ALEAVEL
-	ALEAVEW
-	ALOCK
-	ALODSB
-	ALODSL
-	ALODSW
-	ALONG
-	ALOOP
-	ALOOPEQ
-	ALOOPNE
-	ALSLL
-	ALSLW
-	AMOVB
-	AMOVL
-	AMOVW
-	AMOVBLSX
-	AMOVBLZX
-	AMOVBQSX
-	AMOVBQZX
-	AMOVBWSX
-	AMOVBWZX
-	AMOVWLSX
-	AMOVWLZX
-	AMOVWQSX
-	AMOVWQZX
-	AMOVSB
-	AMOVSL
-	AMOVSW
-	AMULB
-	AMULL
-	AMULW
-	ANEGB
-	ANEGL
-	ANEGW
-	ANOTB
-	ANOTL
-	ANOTW
-	AORB
-	AORL
-	AORW
-	AOUTB
-	AOUTL
-	AOUTW
-	AOUTSB
-	AOUTSL
-	AOUTSW
-	APAUSE
-	APOPAL
-	APOPAW
-	APOPCNTW
-	APOPCNTL
-	APOPCNTQ
-	APOPFL
-	APOPFW
-	APOPL
-	APOPW
-	APUSHAL
-	APUSHAW
-	APUSHFL
-	APUSHFW
-	APUSHL
-	APUSHW
-	ARCLB
-	ARCLL
-	ARCLW
-	ARCRB
-	ARCRL
-	ARCRW
-	AREP
-	AREPN
-	AROLB
-	AROLL
-	AROLW
-	ARORB
-	ARORL
-	ARORW
-	ASAHF
-	ASALB
-	ASALL
-	ASALW
-	ASARB
-	ASARL
-	ASARW
-	ASBBB
-	ASBBL
-	ASBBW
-	ASCASB
-	ASCASL
-	ASCASW
-	ASETCC
-	ASETCS
-	ASETEQ
-	ASETGE
-	ASETGT
-	ASETHI
-	ASETLE
-	ASETLS
-	ASETLT
-	ASETMI
-	ASETNE
-	ASETOC
-	ASETOS
-	ASETPC
-	ASETPL
-	ASETPS
-	ACDQ
-	ACWD
-	ASHLB
-	ASHLL
-	ASHLW
-	ASHRB
-	ASHRL
-	ASHRW
-	ASTC
-	ASTD
-	ASTI
-	ASTOSB
-	ASTOSL
-	ASTOSW
-	ASUBB
-	ASUBL
-	ASUBW
-	ASYSCALL
-	ATESTB
-	ATESTL
-	ATESTW
-	AVERR
-	AVERW
-	AWAIT
-	AWORD
-	AXCHGB
-	AXCHGL
-	AXCHGW
-	AXLAT
-	AXORB
-	AXORL
-	AXORW
-
-	AFMOVB
-	AFMOVBP
-	AFMOVD
-	AFMOVDP
-	AFMOVF
-	AFMOVFP
-	AFMOVL
-	AFMOVLP
-	AFMOVV
-	AFMOVVP
-	AFMOVW
-	AFMOVWP
-	AFMOVX
-	AFMOVXP
-
-	AFCOMD
-	AFCOMDP
-	AFCOMDPP
-	AFCOMF
-	AFCOMFP
-	AFCOML
-	AFCOMLP
-	AFCOMW
-	AFCOMWP
-	AFUCOM
-	AFUCOMP
-	AFUCOMPP
-
-	AFADDDP
-	AFADDW
-	AFADDL
-	AFADDF
-	AFADDD
-
-	AFMULDP
-	AFMULW
-	AFMULL
-	AFMULF
-	AFMULD
-
-	AFSUBDP
-	AFSUBW
-	AFSUBL
-	AFSUBF
-	AFSUBD
-
-	AFSUBRDP
-	AFSUBRW
-	AFSUBRL
-	AFSUBRF
-	AFSUBRD
-
-	AFDIVDP
-	AFDIVW
-	AFDIVL
-	AFDIVF
-	AFDIVD
-
-	AFDIVRDP
-	AFDIVRW
-	AFDIVRL
-	AFDIVRF
-	AFDIVRD
-
-	AFXCHD
-	AFFREE
-
-	AFLDCW
-	AFLDENV
-	AFRSTOR
-	AFSAVE
-	AFSTCW
-	AFSTENV
-	AFSTSW
-
-	AF2XM1
-	AFABS
-	AFCHS
-	AFCLEX
-	AFCOS
-	AFDECSTP
-	AFINCSTP
-	AFINIT
-	AFLD1
-	AFLDL2E
-	AFLDL2T
-	AFLDLG2
-	AFLDLN2
-	AFLDPI
-	AFLDZ
-	AFNOP
-	AFPATAN
-	AFPREM
-	AFPREM1
-	AFPTAN
-	AFRNDINT
-	AFSCALE
-	AFSIN
-	AFSINCOS
-	AFSQRT
-	AFTST
-	AFXAM
-	AFXTRACT
-	AFYL2X
-	AFYL2XP1
-
-	// extra 32-bit operations
-	ACMPXCHGB
-	ACMPXCHGL
-	ACMPXCHGW
-	ACMPXCHG8B
-	ACPUID
-	AINVD
-	AINVLPG
-	ALFENCE
-	AMFENCE
-	AMOVNTIL
-	ARDMSR
-	ARDPMC
-	ARDTSC
-	ARSM
-	ASFENCE
-	ASYSRET
-	AWBINVD
-	AWRMSR
-	AXADDB
-	AXADDL
-	AXADDW
-
-	// conditional move
-	ACMOVLCC
-	ACMOVLCS
-	ACMOVLEQ
-	ACMOVLGE
-	ACMOVLGT
-	ACMOVLHI
-	ACMOVLLE
-	ACMOVLLS
-	ACMOVLLT
-	ACMOVLMI
-	ACMOVLNE
-	ACMOVLOC
-	ACMOVLOS
-	ACMOVLPC
-	ACMOVLPL
-	ACMOVLPS
-	ACMOVQCC
-	ACMOVQCS
-	ACMOVQEQ
-	ACMOVQGE
-	ACMOVQGT
-	ACMOVQHI
-	ACMOVQLE
-	ACMOVQLS
-	ACMOVQLT
-	ACMOVQMI
-	ACMOVQNE
-	ACMOVQOC
-	ACMOVQOS
-	ACMOVQPC
-	ACMOVQPL
-	ACMOVQPS
-	ACMOVWCC
-	ACMOVWCS
-	ACMOVWEQ
-	ACMOVWGE
-	ACMOVWGT
-	ACMOVWHI
-	ACMOVWLE
-	ACMOVWLS
-	ACMOVWLT
-	ACMOVWMI
-	ACMOVWNE
-	ACMOVWOC
-	ACMOVWOS
-	ACMOVWPC
-	ACMOVWPL
-	ACMOVWPS
-
-	// 64-bit
-	AADCQ
-	AADDQ
-	AANDQ
-	ABSFQ
-	ABSRQ
-	ABTCQ
-	ABTQ
-	ABTRQ
-	ABTSQ
-	ACMPQ
-	ACMPSQ
-	ACMPXCHGQ
-	ACQO
-	ADIVQ
-	AIDIVQ
-	AIMULQ
-	AIRETQ
-	AJCXZQ
-	ALEAQ
-	ALEAVEQ
-	ALODSQ
-	AMOVQ
-	AMOVLQSX
-	AMOVLQZX
-	AMOVNTIQ
-	AMOVSQ
-	AMULQ
-	ANEGQ
-	ANOTQ
-	AORQ
-	APOPFQ
-	APOPQ
-	APUSHFQ
-	APUSHQ
-	ARCLQ
-	ARCRQ
-	AROLQ
-	ARORQ
-	AQUAD
-	ASALQ
-	ASARQ
-	ASBBQ
-	ASCASQ
-	ASHLQ
-	ASHRQ
-	ASTOSQ
-	ASUBQ
-	ATESTQ
-	AXADDQ
-	AXCHGQ
-	AXORQ
-	AXGETBV
-
-	// media
-	AADDPD
-	AADDPS
-	AADDSD
-	AADDSS
-	AANDNL
-	AANDNQ
-	AANDNPD
-	AANDNPS
-	AANDPD
-	AANDPS
-	ABEXTRL
-	ABEXTRQ
-	ABLSIL
-	ABLSIQ
-	ABLSMSKL
-	ABLSMSKQ
-	ABLSRL
-	ABLSRQ
-	ABZHIL
-	ABZHIQ
-	ACMPPD
-	ACMPPS
-	ACMPSD
-	ACMPSS
-	ACOMISD
-	ACOMISS
-	ACVTPD2PL
-	ACVTPD2PS
-	ACVTPL2PD
-	ACVTPL2PS
-	ACVTPS2PD
-	ACVTPS2PL
-	ACVTSD2SL
-	ACVTSD2SQ
-	ACVTSD2SS
-	ACVTSL2SD
-	ACVTSL2SS
-	ACVTSQ2SD
-	ACVTSQ2SS
-	ACVTSS2SD
-	ACVTSS2SL
-	ACVTSS2SQ
-	ACVTTPD2PL
-	ACVTTPS2PL
-	ACVTTSD2SL
-	ACVTTSD2SQ
-	ACVTTSS2SL
-	ACVTTSS2SQ
-	ADIVPD
-	ADIVPS
-	ADIVSD
-	ADIVSS
-	AEMMS
-	AFXRSTOR
-	AFXRSTOR64
-	AFXSAVE
-	AFXSAVE64
-	ALDDQU
-	ALDMXCSR
-	AMASKMOVOU
-	AMASKMOVQ
-	AMAXPD
-	AMAXPS
-	AMAXSD
-	AMAXSS
-	AMINPD
-	AMINPS
-	AMINSD
-	AMINSS
-	AMOVAPD
-	AMOVAPS
-	AMOVOU
-	AMOVHLPS
-	AMOVHPD
-	AMOVHPS
-	AMOVLHPS
-	AMOVLPD
-	AMOVLPS
-	AMOVMSKPD
-	AMOVMSKPS
-	AMOVNTO
-	AMOVNTPD
-	AMOVNTPS
-	AMOVNTQ
-	AMOVO
-	AMOVQOZX
-	AMOVSD
-	AMOVSS
-	AMOVUPD
-	AMOVUPS
-	AMULPD
-	AMULPS
-	AMULSD
-	AMULSS
-	AMULXL
-	AMULXQ
-	AORPD
-	AORPS
-	APACKSSLW
-	APACKSSWB
-	APACKUSWB
-	APADDB
-	APADDL
-	APADDQ
-	APADDSB
-	APADDSW
-	APADDUSB
-	APADDUSW
-	APADDW
-	APAND
-	APANDN
-	APAVGB
-	APAVGW
-	APCMPEQB
-	APCMPEQL
-	APCMPEQW
-	APCMPGTB
-	APCMPGTL
-	APCMPGTW
-	APDEPL
-	APDEPQ
-	APEXTL
-	APEXTQ
-	APEXTRB
-	APEXTRD
-	APEXTRQ
-	APEXTRW
-	APHADDD
-	APHADDSW
-	APHADDW
-	APHMINPOSUW
-	APHSUBD
-	APHSUBSW
-	APHSUBW
-	APINSRB
-	APINSRD
-	APINSRQ
-	APINSRW
-	APMADDWL
-	APMAXSW
-	APMAXUB
-	APMINSW
-	APMINUB
-	APMOVMSKB
-	APMOVSXBD
-	APMOVSXBQ
-	APMOVSXBW
-	APMOVSXDQ
-	APMOVSXWD
-	APMOVSXWQ
-	APMOVZXBD
-	APMOVZXBQ
-	APMOVZXBW
-	APMOVZXDQ
-	APMOVZXWD
-	APMOVZXWQ
-	APMULDQ
-	APMULHUW
-	APMULHW
-	APMULLD
-	APMULLW
-	APMULULQ
-	APOR
-	APSADBW
-	APSHUFB
-	APSHUFHW
-	APSHUFL
-	APSHUFLW
-	APSHUFW
-	APSLLL
-	APSLLO
-	APSLLQ
-	APSLLW
-	APSRAL
-	APSRAW
-	APSRLL
-	APSRLO
-	APSRLQ
-	APSRLW
-	APSUBB
-	APSUBL
-	APSUBQ
-	APSUBSB
-	APSUBSW
-	APSUBUSB
-	APSUBUSW
-	APSUBW
-	APUNPCKHBW
-	APUNPCKHLQ
-	APUNPCKHQDQ
-	APUNPCKHWL
-	APUNPCKLBW
-	APUNPCKLLQ
-	APUNPCKLQDQ
-	APUNPCKLWL
-	APXOR
-	ARCPPS
-	ARCPSS
-	ARSQRTPS
-	ARSQRTSS
-	ASARXL
-	ASARXQ
-	ASHLXL
-	ASHLXQ
-	ASHRXL
-	ASHRXQ
-	ASHUFPD
-	ASHUFPS
-	ASQRTPD
-	ASQRTPS
-	ASQRTSD
-	ASQRTSS
-	ASTMXCSR
-	ASUBPD
-	ASUBPS
-	ASUBSD
-	ASUBSS
-	AUCOMISD
-	AUCOMISS
-	AUNPCKHPD
-	AUNPCKHPS
-	AUNPCKLPD
-	AUNPCKLPS
-	AXORPD
-	AXORPS
-	APCMPESTRI
-
-	ARETFW
-	ARETFL
-	ARETFQ
-	ASWAPGS
-
-	ACRC32B
-	ACRC32Q
-	AIMUL3Q
-
-	APREFETCHT0
-	APREFETCHT1
-	APREFETCHT2
-	APREFETCHNTA
-
-	AMOVQL
-	ABSWAPL
-	ABSWAPQ
-
-	AAESENC
-	AAESENCLAST
-	AAESDEC
-	AAESDECLAST
-	AAESIMC
-	AAESKEYGENASSIST
-
-	AROUNDPS
-	AROUNDSS
-	AROUNDPD
-	AROUNDSD
-	AMOVDDUP
-	AMOVSHDUP
-	AMOVSLDUP
-
-	APSHUFD
-	APCLMULQDQ
-
-	AVZEROUPPER
-	AVMOVDQU
-	AVMOVNTDQ
-	AVMOVDQA
-	AVPCMPEQB
-	AVPXOR
-	AVPMOVMSKB
-	AVPAND
-	AVPTEST
-	AVPBROADCASTB
-	AVPSHUFB
-	AVPSHUFD
-	AVPERM2F128
-	AVPALIGNR
-	AVPADDQ
-	AVPADDD
-	AVPSRLDQ
-	AVPSLLDQ
-	AVPSRLQ
-	AVPSLLQ
-	AVPSRLD
-	AVPSLLD
-	AVPOR
-	AVPBLENDD
-	AVINSERTI128
-	AVPERM2I128
-	ARORXL
-	ARORXQ
-	AVBROADCASTSS
-	AVBROADCASTSD
-	AVMOVDDUP
-	AVMOVSHDUP
-	AVMOVSLDUP
-
-	// from 386
-	AJCXZW
-	AFCMOVCC
-	AFCMOVCS
-	AFCMOVEQ
-	AFCMOVHI
-	AFCMOVLS
-	AFCMOVNE
-	AFCMOVNU
-	AFCMOVUN
-	AFCOMI
-	AFCOMIP
-	AFUCOMI
-	AFUCOMIP
-
-	// TSX
-	AXACQUIRE
-	AXRELEASE
-	AXBEGIN
-	AXEND
-	AXABORT
-	AXTEST
-
-	ALAST
+	DONE = 1 << iota
 )
 
 const (
@@ -1006,3 +206,120 @@
 	T_64     = 1 << 6
 	T_GOTYPE = 1 << 7
 )
+
+// https://www.uclibc.org/docs/psABI-x86_64.pdf, figure 3.36
+var AMD64DWARFRegisters = map[int16]int16{
+	REG_AX:  0,
+	REG_DX:  1,
+	REG_CX:  2,
+	REG_BX:  3,
+	REG_SI:  4,
+	REG_DI:  5,
+	REG_BP:  6,
+	REG_SP:  7,
+	REG_R8:  8,
+	REG_R9:  9,
+	REG_R10: 10,
+	REG_R11: 11,
+	REG_R12: 12,
+	REG_R13: 13,
+	REG_R14: 14,
+	REG_R15: 15,
+	// 16 is "Return Address RA", whatever that is.
+	// XMM registers. %xmmN => XN.
+	REG_X0:  17,
+	REG_X1:  18,
+	REG_X2:  19,
+	REG_X3:  20,
+	REG_X4:  21,
+	REG_X5:  22,
+	REG_X6:  23,
+	REG_X7:  24,
+	REG_X8:  25,
+	REG_X9:  26,
+	REG_X10: 27,
+	REG_X11: 28,
+	REG_X12: 29,
+	REG_X13: 30,
+	REG_X14: 31,
+	REG_X15: 32,
+	// ST registers. %stN => FN.
+	REG_F0: 33,
+	REG_F1: 34,
+	REG_F2: 35,
+	REG_F3: 36,
+	REG_F4: 37,
+	REG_F5: 38,
+	REG_F6: 39,
+	REG_F7: 40,
+	// MMX registers. %mmN => MN.
+	REG_M0: 41,
+	REG_M1: 42,
+	REG_M2: 43,
+	REG_M3: 44,
+	REG_M4: 45,
+	REG_M5: 46,
+	REG_M6: 47,
+	REG_M7: 48,
+	// 48 is flags, which doesn't have a name.
+	REG_ES: 50,
+	REG_CS: 51,
+	REG_SS: 52,
+	REG_DS: 53,
+	REG_FS: 54,
+	REG_GS: 55,
+	// 58 and 59 are {fs,gs}base, which don't have names.
+	REG_TR:   62,
+	REG_LDTR: 63,
+	// 64-66 are mxcsr, fcw, fsw, which don't have names.
+}
+
+// https://www.uclibc.org/docs/psABI-i386.pdf, table 2.14
+var X86DWARFRegisters = map[int16]int16{
+	REG_AX: 0,
+	REG_CX: 1,
+	REG_DX: 2,
+	REG_BX: 3,
+	REG_SP: 4,
+	REG_BP: 5,
+	REG_SI: 6,
+	REG_DI: 7,
+	// 8 is "Return Address RA", whatever that is.
+	// 9 is flags, which doesn't have a name.
+	// ST registers. %stN => FN.
+	REG_F0: 11,
+	REG_F1: 12,
+	REG_F2: 13,
+	REG_F3: 14,
+	REG_F4: 15,
+	REG_F5: 16,
+	REG_F6: 17,
+	REG_F7: 18,
+	// XMM registers. %xmmN => XN.
+	REG_X0: 21,
+	REG_X1: 22,
+	REG_X2: 23,
+	REG_X3: 24,
+	REG_X4: 25,
+	REG_X5: 26,
+	REG_X6: 27,
+	REG_X7: 28,
+	// MMX registers. %mmN => MN.
+	REG_M0: 29,
+	REG_M1: 30,
+	REG_M2: 31,
+	REG_M3: 32,
+	REG_M4: 33,
+	REG_M5: 34,
+	REG_M6: 35,
+	REG_M7: 36,
+	// 39 is mxcsr, which doesn't have a name.
+	REG_ES:   40,
+	REG_CS:   41,
+	REG_SS:   42,
+	REG_DS:   43,
+	REG_FS:   44,
+	REG_GS:   45,
+	REG_TR:   48,
+	REG_LDTR: 49,
+}
diff --git a/src/cmd/internal/obj/x86/aenum.go b/src/cmd/internal/obj/x86/aenum.go
new file mode 100644
index 0000000..013d9e0
--- /dev/null
+++ b/src/cmd/internal/obj/x86/aenum.go
@@ -0,0 +1,1136 @@
+// Code generated by x86avxgen. DO NOT EDIT.
+
+package x86
+
+import "cmd/internal/obj"
+
+//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p x86
+
+const (
+	AAAA = obj.ABaseAMD64 + obj.A_ARCHSPECIFIC + iota
+	AAAD
+	AAAM
+	AAAS
+	AADCB
+	AADCL
+	AADCQ
+	AADCW
+	AADCXL
+	AADCXQ
+	AADDB
+	AADDL
+	AADDPD
+	AADDPS
+	AADDQ
+	AADDSD
+	AADDSS
+	AADDSUBPD
+	AADDSUBPS
+	AADDW
+	AADJSP
+	AADOXL
+	AADOXQ
+	AAESDEC
+	AAESDECLAST
+	AAESENC
+	AAESENCLAST
+	AAESIMC
+	AAESKEYGENASSIST
+	AANDB
+	AANDL
+	AANDNL
+	AANDNPD
+	AANDNPS
+	AANDNQ
+	AANDPD
+	AANDPS
+	AANDQ
+	AANDW
+	AARPL
+	ABEXTRL
+	ABEXTRQ
+	ABLENDPD
+	ABLENDPS
+	ABLSIL
+	ABLSIQ
+	ABLSMSKL
+	ABLSMSKQ
+	ABLSRL
+	ABLSRQ
+	ABOUNDL
+	ABOUNDW
+	ABSFL
+	ABSFQ
+	ABSFW
+	ABSRL
+	ABSRQ
+	ABSRW
+	ABSWAPL
+	ABSWAPQ
+	ABTCL
+	ABTCQ
+	ABTCW
+	ABTL
+	ABTQ
+	ABTRL
+	ABTRQ
+	ABTRW
+	ABTSL
+	ABTSQ
+	ABTSW
+	ABTW
+	ABYTE
+	ABZHIL
+	ABZHIQ
+	ACDQ
+	ACLC
+	ACLD
+	ACLFLUSH
+	ACLI
+	ACLTS
+	ACMC
+	ACMOVLCC
+	ACMOVLCS
+	ACMOVLEQ
+	ACMOVLGE
+	ACMOVLGT
+	ACMOVLHI
+	ACMOVLLE
+	ACMOVLLS
+	ACMOVLLT
+	ACMOVLMI
+	ACMOVLNE
+	ACMOVLOC
+	ACMOVLOS
+	ACMOVLPC
+	ACMOVLPL
+	ACMOVLPS
+	ACMOVQCC
+	ACMOVQCS
+	ACMOVQEQ
+	ACMOVQGE
+	ACMOVQGT
+	ACMOVQHI
+	ACMOVQLE
+	ACMOVQLS
+	ACMOVQLT
+	ACMOVQMI
+	ACMOVQNE
+	ACMOVQOC
+	ACMOVQOS
+	ACMOVQPC
+	ACMOVQPL
+	ACMOVQPS
+	ACMOVWCC
+	ACMOVWCS
+	ACMOVWEQ
+	ACMOVWGE
+	ACMOVWGT
+	ACMOVWHI
+	ACMOVWLE
+	ACMOVWLS
+	ACMOVWLT
+	ACMOVWMI
+	ACMOVWNE
+	ACMOVWOC
+	ACMOVWOS
+	ACMOVWPC
+	ACMOVWPL
+	ACMOVWPS
+	ACMPB
+	ACMPL
+	ACMPPD
+	ACMPPS
+	ACMPQ
+	ACMPSB
+	ACMPSD
+	ACMPSL
+	ACMPSQ
+	ACMPSS
+	ACMPSW
+	ACMPW
+	ACMPXCHG8B
+	ACMPXCHGB
+	ACMPXCHGL
+	ACMPXCHGQ
+	ACMPXCHGW
+	ACOMISD
+	ACOMISS
+	ACPUID
+	ACQO
+	ACRC32B
+	ACRC32Q
+	ACVTPD2PL
+	ACVTPD2PS
+	ACVTPL2PD
+	ACVTPL2PS
+	ACVTPS2PD
+	ACVTPS2PL
+	ACVTSD2SL
+	ACVTSD2SQ
+	ACVTSD2SS
+	ACVTSL2SD
+	ACVTSL2SS
+	ACVTSQ2SD
+	ACVTSQ2SS
+	ACVTSS2SD
+	ACVTSS2SL
+	ACVTSS2SQ
+	ACVTTPD2PL
+	ACVTTPS2PL
+	ACVTTSD2SL
+	ACVTTSD2SQ
+	ACVTTSS2SL
+	ACVTTSS2SQ
+	ACWD
+	ADAA
+	ADAS
+	ADECB
+	ADECL
+	ADECQ
+	ADECW
+	ADIVB
+	ADIVL
+	ADIVPD
+	ADIVPS
+	ADIVQ
+	ADIVSD
+	ADIVSS
+	ADIVW
+	ADPPD
+	ADPPS
+	AEMMS
+	AENTER
+	AEXTRACTPS
+	AF2XM1
+	AFABS
+	AFADDD
+	AFADDDP
+	AFADDF
+	AFADDL
+	AFADDW
+	AFCHS
+	AFCLEX
+	AFCMOVCC
+	AFCMOVCS
+	AFCMOVEQ
+	AFCMOVHI
+	AFCMOVLS
+	AFCMOVNE
+	AFCMOVNU
+	AFCMOVUN
+	AFCOMD
+	AFCOMDP
+	AFCOMDPP
+	AFCOMF
+	AFCOMFP
+	AFCOMI
+	AFCOMIP
+	AFCOML
+	AFCOMLP
+	AFCOMW
+	AFCOMWP
+	AFCOS
+	AFDECSTP
+	AFDIVD
+	AFDIVDP
+	AFDIVF
+	AFDIVL
+	AFDIVRD
+	AFDIVRDP
+	AFDIVRF
+	AFDIVRL
+	AFDIVRW
+	AFDIVW
+	AFFREE
+	AFINCSTP
+	AFINIT
+	AFLD1
+	AFLDCW
+	AFLDENV
+	AFLDL2E
+	AFLDL2T
+	AFLDLG2
+	AFLDLN2
+	AFLDPI
+	AFLDZ
+	AFMOVB
+	AFMOVBP
+	AFMOVD
+	AFMOVDP
+	AFMOVF
+	AFMOVFP
+	AFMOVL
+	AFMOVLP
+	AFMOVV
+	AFMOVVP
+	AFMOVW
+	AFMOVWP
+	AFMOVX
+	AFMOVXP
+	AFMULD
+	AFMULDP
+	AFMULF
+	AFMULL
+	AFMULW
+	AFNOP
+	AFPATAN
+	AFPREM
+	AFPREM1
+	AFPTAN
+	AFRNDINT
+	AFRSTOR
+	AFSAVE
+	AFSCALE
+	AFSIN
+	AFSINCOS
+	AFSQRT
+	AFSTCW
+	AFSTENV
+	AFSTSW
+	AFSUBD
+	AFSUBDP
+	AFSUBF
+	AFSUBL
+	AFSUBRD
+	AFSUBRDP
+	AFSUBRF
+	AFSUBRL
+	AFSUBRW
+	AFSUBW
+	AFTST
+	AFUCOM
+	AFUCOMI
+	AFUCOMIP
+	AFUCOMP
+	AFUCOMPP
+	AFXAM
+	AFXCHD
+	AFXRSTOR
+	AFXRSTOR64
+	AFXSAVE
+	AFXSAVE64
+	AFXTRACT
+	AFYL2X
+	AFYL2XP1
+	AHADDPD
+	AHADDPS
+	AHLT
+	AHSUBPD
+	AHSUBPS
+	AIDIVB
+	AIDIVL
+	AIDIVQ
+	AIDIVW
+	AIMUL3Q
+	AIMULB
+	AIMULL
+	AIMULQ
+	AIMULW
+	AINB
+	AINCB
+	AINCL
+	AINCQ
+	AINCW
+	AINL
+	AINSB
+	AINSERTPS
+	AINSL
+	AINSW
+	AINT
+	AINTO
+	AINVD
+	AINVLPG
+	AINW
+	AIRETL
+	AIRETQ
+	AIRETW
+	AJCC // >= unsigned
+	AJCS // < unsigned
+	AJCXZL
+	AJCXZQ
+	AJCXZW
+	AJEQ // == (zero)
+	AJGE // >= signed
+	AJGT // > signed
+	AJHI // > unsigned
+	AJLE // <= signed
+	AJLS // <= unsigned
+	AJLT // < signed
+	AJMI // sign bit set (negative)
+	AJNE // != (nonzero)
+	AJOC // overflow clear
+	AJOS // overflow set
+	AJPC // parity clear
+	AJPL // sign bit clear (positive)
+	AJPS // parity set
+	ALAHF
+	ALARL
+	ALARW
+	ALDDQU
+	ALDMXCSR
+	ALEAL
+	ALEAQ
+	ALEAVEL
+	ALEAVEQ
+	ALEAVEW
+	ALEAW
+	ALFENCE
+	ALOCK
+	ALODSB
+	ALODSL
+	ALODSQ
+	ALODSW
+	ALONG
+	ALOOP
+	ALOOPEQ
+	ALOOPNE
+	ALSLL
+	ALSLW
+	AMASKMOVOU
+	AMASKMOVQ
+	AMAXPD
+	AMAXPS
+	AMAXSD
+	AMAXSS
+	AMFENCE
+	AMINPD
+	AMINPS
+	AMINSD
+	AMINSS
+	AMOVAPD
+	AMOVAPS
+	AMOVB
+	AMOVBLSX
+	AMOVBLZX
+	AMOVBQSX
+	AMOVBQZX
+	AMOVBWSX
+	AMOVBWZX
+	AMOVDDUP
+	AMOVHLPS
+	AMOVHPD
+	AMOVHPS
+	AMOVL
+	AMOVLHPS
+	AMOVLPD
+	AMOVLPS
+	AMOVLQSX
+	AMOVLQZX
+	AMOVMSKPD
+	AMOVMSKPS
+	AMOVNTDQA
+	AMOVNTIL
+	AMOVNTIQ
+	AMOVNTO
+	AMOVNTPD
+	AMOVNTPS
+	AMOVNTQ
+	AMOVO
+	AMOVOU
+	AMOVQ
+	AMOVQL
+	AMOVQOZX
+	AMOVSB
+	AMOVSD
+	AMOVSHDUP
+	AMOVSL
+	AMOVSLDUP
+	AMOVSQ
+	AMOVSS
+	AMOVSW
+	AMOVUPD
+	AMOVUPS
+	AMOVW
+	AMOVWLSX
+	AMOVWLZX
+	AMOVWQSX
+	AMOVWQZX
+	AMPSADBW
+	AMULB
+	AMULL
+	AMULPD
+	AMULPS
+	AMULQ
+	AMULSD
+	AMULSS
+	AMULW
+	AMULXL
+	AMULXQ
+	ANEGB
+	ANEGL
+	ANEGQ
+	ANEGW
+	ANOTB
+	ANOTL
+	ANOTQ
+	ANOTW
+	AORB
+	AORL
+	AORPD
+	AORPS
+	AORQ
+	AORW
+	AOUTB
+	AOUTL
+	AOUTSB
+	AOUTSL
+	AOUTSW
+	AOUTW
+	APABSB
+	APABSD
+	APABSW
+	APACKSSLW
+	APACKSSWB
+	APACKUSDW
+	APACKUSWB
+	APADDB
+	APADDL
+	APADDQ
+	APADDSB
+	APADDSW
+	APADDUSB
+	APADDUSW
+	APADDW
+	APALIGNR
+	APAND
+	APANDN
+	APAUSE
+	APAVGB
+	APAVGW
+	APBLENDW
+	APCLMULQDQ
+	APCMPEQB
+	APCMPEQL
+	APCMPEQQ
+	APCMPEQW
+	APCMPESTRI
+	APCMPESTRM
+	APCMPGTB
+	APCMPGTL
+	APCMPGTQ
+	APCMPGTW
+	APCMPISTRI
+	APCMPISTRM
+	APDEPL
+	APDEPQ
+	APEXTL
+	APEXTQ
+	APEXTRB
+	APEXTRD
+	APEXTRQ
+	APEXTRW
+	APHADDD
+	APHADDSW
+	APHADDW
+	APHMINPOSUW
+	APHSUBD
+	APHSUBSW
+	APHSUBW
+	APINSRB
+	APINSRD
+	APINSRQ
+	APINSRW
+	APMADDUBSW
+	APMADDWL
+	APMAXSB
+	APMAXSD
+	APMAXSW
+	APMAXUB
+	APMAXUD
+	APMAXUW
+	APMINSB
+	APMINSD
+	APMINSW
+	APMINUB
+	APMINUD
+	APMINUW
+	APMOVMSKB
+	APMOVSXBD
+	APMOVSXBQ
+	APMOVSXBW
+	APMOVSXDQ
+	APMOVSXWD
+	APMOVSXWQ
+	APMOVZXBD
+	APMOVZXBQ
+	APMOVZXBW
+	APMOVZXDQ
+	APMOVZXWD
+	APMOVZXWQ
+	APMULDQ
+	APMULHRSW
+	APMULHUW
+	APMULHW
+	APMULLD
+	APMULLW
+	APMULULQ
+	APOPAL
+	APOPAW
+	APOPCNTL
+	APOPCNTQ
+	APOPCNTW
+	APOPFL
+	APOPFQ
+	APOPFW
+	APOPL
+	APOPQ
+	APOPW
+	APOR
+	APREFETCHNTA
+	APREFETCHT0
+	APREFETCHT1
+	APREFETCHT2
+	APSADBW
+	APSHUFB
+	APSHUFD
+	APSHUFHW
+	APSHUFL
+	APSHUFLW
+	APSHUFW
+	APSIGNB
+	APSIGND
+	APSIGNW
+	APSLLL
+	APSLLO
+	APSLLQ
+	APSLLW
+	APSRAL
+	APSRAW
+	APSRLL
+	APSRLO
+	APSRLQ
+	APSRLW
+	APSUBB
+	APSUBL
+	APSUBQ
+	APSUBSB
+	APSUBSW
+	APSUBUSB
+	APSUBUSW
+	APSUBW
+	APTEST
+	APUNPCKHBW
+	APUNPCKHLQ
+	APUNPCKHQDQ
+	APUNPCKHWL
+	APUNPCKLBW
+	APUNPCKLLQ
+	APUNPCKLQDQ
+	APUNPCKLWL
+	APUSHAL
+	APUSHAW
+	APUSHFL
+	APUSHFQ
+	APUSHFW
+	APUSHL
+	APUSHQ
+	APUSHW
+	APXOR
+	AQUAD
+	ARCLB
+	ARCLL
+	ARCLQ
+	ARCLW
+	ARCPPS
+	ARCPSS
+	ARCRB
+	ARCRL
+	ARCRQ
+	ARCRW
+	ARDMSR
+	ARDPMC
+	ARDTSC
+	AREP
+	AREPN
+	ARETFL
+	ARETFQ
+	ARETFW
+	AROLB
+	AROLL
+	AROLQ
+	AROLW
+	ARORB
+	ARORL
+	ARORQ
+	ARORW
+	ARORXL
+	ARORXQ
+	AROUNDPD
+	AROUNDPS
+	AROUNDSD
+	AROUNDSS
+	ARSM
+	ARSQRTPS
+	ARSQRTSS
+	ASAHF
+	ASALB
+	ASALL
+	ASALQ
+	ASALW
+	ASARB
+	ASARL
+	ASARQ
+	ASARW
+	ASARXL
+	ASARXQ
+	ASBBB
+	ASBBL
+	ASBBQ
+	ASBBW
+	ASCASB
+	ASCASL
+	ASCASQ
+	ASCASW
+	ASETCC
+	ASETCS
+	ASETEQ
+	ASETGE
+	ASETGT
+	ASETHI
+	ASETLE
+	ASETLS
+	ASETLT
+	ASETMI
+	ASETNE
+	ASETOC
+	ASETOS
+	ASETPC
+	ASETPL
+	ASETPS
+	ASFENCE
+	ASHLB
+	ASHLL
+	ASHLQ
+	ASHLW
+	ASHLXL
+	ASHLXQ
+	ASHRB
+	ASHRL
+	ASHRQ
+	ASHRW
+	ASHRXL
+	ASHRXQ
+	ASHUFPD
+	ASHUFPS
+	ASQRTPD
+	ASQRTPS
+	ASQRTSD
+	ASQRTSS
+	ASTC
+	ASTD
+	ASTI
+	ASTMXCSR
+	ASTOSB
+	ASTOSL
+	ASTOSQ
+	ASTOSW
+	ASUBB
+	ASUBL
+	ASUBPD
+	ASUBPS
+	ASUBQ
+	ASUBSD
+	ASUBSS
+	ASUBW
+	ASWAPGS
+	ASYSCALL
+	ASYSRET
+	ATESTB
+	ATESTL
+	ATESTQ
+	ATESTW
+	AUCOMISD
+	AUCOMISS
+	AUNPCKHPD
+	AUNPCKHPS
+	AUNPCKLPD
+	AUNPCKLPS
+	AVADDPD
+	AVADDPS
+	AVADDSD
+	AVADDSS
+	AVADDSUBPD
+	AVADDSUBPS
+	AVAESDEC
+	AVAESDECLAST
+	AVAESENC
+	AVAESENCLAST
+	AVAESIMC
+	AVAESKEYGENASSIST
+	AVANDNPD
+	AVANDNPS
+	AVANDPD
+	AVANDPS
+	AVBLENDPD
+	AVBLENDPS
+	AVBLENDVPD
+	AVBLENDVPS
+	AVBROADCASTF128
+	AVBROADCASTI128
+	AVBROADCASTSD
+	AVBROADCASTSS
+	AVCMPPD
+	AVCMPPS
+	AVCMPSD
+	AVCMPSS
+	AVCOMISD
+	AVCOMISS
+	AVCVTDQ2PD
+	AVCVTDQ2PS
+	AVCVTPD2DQX
+	AVCVTPD2DQY
+	AVCVTPD2PSX
+	AVCVTPD2PSY
+	AVCVTPH2PS
+	AVCVTPS2DQ
+	AVCVTPS2PD
+	AVCVTPS2PH
+	AVCVTSD2SI
+	AVCVTSD2SIQ
+	AVCVTSD2SS
+	AVCVTSI2SDL
+	AVCVTSI2SDQ
+	AVCVTSI2SSL
+	AVCVTSI2SSQ
+	AVCVTSS2SD
+	AVCVTSS2SI
+	AVCVTSS2SIQ
+	AVCVTTPD2DQX
+	AVCVTTPD2DQY
+	AVCVTTPS2DQ
+	AVCVTTSD2SI
+	AVCVTTSD2SIQ
+	AVCVTTSS2SI
+	AVCVTTSS2SIQ
+	AVDIVPD
+	AVDIVPS
+	AVDIVSD
+	AVDIVSS
+	AVDPPD
+	AVDPPS
+	AVERR
+	AVERW
+	AVEXTRACTF128
+	AVEXTRACTI128
+	AVEXTRACTPS
+	AVFMADD132PD
+	AVFMADD132PS
+	AVFMADD132SD
+	AVFMADD132SS
+	AVFMADD213PD
+	AVFMADD213PS
+	AVFMADD213SD
+	AVFMADD213SS
+	AVFMADD231PD
+	AVFMADD231PS
+	AVFMADD231SD
+	AVFMADD231SS
+	AVFMADDSUB132PD
+	AVFMADDSUB132PS
+	AVFMADDSUB213PD
+	AVFMADDSUB213PS
+	AVFMADDSUB231PD
+	AVFMADDSUB231PS
+	AVFMSUB132PD
+	AVFMSUB132PS
+	AVFMSUB132SD
+	AVFMSUB132SS
+	AVFMSUB213PD
+	AVFMSUB213PS
+	AVFMSUB213SD
+	AVFMSUB213SS
+	AVFMSUB231PD
+	AVFMSUB231PS
+	AVFMSUB231SD
+	AVFMSUB231SS
+	AVFMSUBADD132PD
+	AVFMSUBADD132PS
+	AVFMSUBADD213PD
+	AVFMSUBADD213PS
+	AVFMSUBADD231PD
+	AVFMSUBADD231PS
+	AVFNMADD132PD
+	AVFNMADD132PS
+	AVFNMADD132SD
+	AVFNMADD132SS
+	AVFNMADD213PD
+	AVFNMADD213PS
+	AVFNMADD213SD
+	AVFNMADD213SS
+	AVFNMADD231PD
+	AVFNMADD231PS
+	AVFNMADD231SD
+	AVFNMADD231SS
+	AVFNMSUB132PD
+	AVFNMSUB132PS
+	AVFNMSUB132SD
+	AVFNMSUB132SS
+	AVFNMSUB213PD
+	AVFNMSUB213PS
+	AVFNMSUB213SD
+	AVFNMSUB213SS
+	AVFNMSUB231PD
+	AVFNMSUB231PS
+	AVFNMSUB231SD
+	AVFNMSUB231SS
+	AVGATHERDPD
+	AVGATHERDPS
+	AVGATHERQPD
+	AVGATHERQPS
+	AVHADDPD
+	AVHADDPS
+	AVHSUBPD
+	AVHSUBPS
+	AVINSERTF128
+	AVINSERTI128
+	AVINSERTPS
+	AVLDDQU
+	AVLDMXCSR
+	AVMASKMOVDQU
+	AVMASKMOVPD
+	AVMASKMOVPS
+	AVMAXPD
+	AVMAXPS
+	AVMAXSD
+	AVMAXSS
+	AVMINPD
+	AVMINPS
+	AVMINSD
+	AVMINSS
+	AVMOVAPD
+	AVMOVAPS
+	AVMOVD
+	AVMOVDDUP
+	AVMOVDQA
+	AVMOVDQU
+	AVMOVHLPS
+	AVMOVHPD
+	AVMOVHPS
+	AVMOVLHPS
+	AVMOVLPD
+	AVMOVLPS
+	AVMOVMSKPD
+	AVMOVMSKPS
+	AVMOVNTDQ
+	AVMOVNTDQA
+	AVMOVNTPD
+	AVMOVNTPS
+	AVMOVQ
+	AVMOVSD
+	AVMOVSHDUP
+	AVMOVSLDUP
+	AVMOVSS
+	AVMOVUPD
+	AVMOVUPS
+	AVMPSADBW
+	AVMULPD
+	AVMULPS
+	AVMULSD
+	AVMULSS
+	AVORPD
+	AVORPS
+	AVPABSB
+	AVPABSD
+	AVPABSW
+	AVPACKSSDW
+	AVPACKSSWB
+	AVPACKUSDW
+	AVPACKUSWB
+	AVPADDB
+	AVPADDD
+	AVPADDQ
+	AVPADDSB
+	AVPADDSW
+	AVPADDUSB
+	AVPADDUSW
+	AVPADDW
+	AVPALIGNR
+	AVPAND
+	AVPANDN
+	AVPAVGB
+	AVPAVGW
+	AVPBLENDD
+	AVPBLENDVB
+	AVPBLENDW
+	AVPBROADCASTB
+	AVPBROADCASTD
+	AVPBROADCASTQ
+	AVPBROADCASTW
+	AVPCLMULQDQ
+	AVPCMPEQB
+	AVPCMPEQD
+	AVPCMPEQQ
+	AVPCMPEQW
+	AVPCMPESTRI
+	AVPCMPESTRM
+	AVPCMPGTB
+	AVPCMPGTD
+	AVPCMPGTQ
+	AVPCMPGTW
+	AVPCMPISTRI
+	AVPCMPISTRM
+	AVPERM2F128
+	AVPERM2I128
+	AVPERMD
+	AVPERMILPD
+	AVPERMILPS
+	AVPERMPD
+	AVPERMPS
+	AVPERMQ
+	AVPEXTRB
+	AVPEXTRD
+	AVPEXTRQ
+	AVPEXTRW
+	AVPGATHERDD
+	AVPGATHERDQ
+	AVPGATHERQD
+	AVPGATHERQQ
+	AVPHADDD
+	AVPHADDSW
+	AVPHADDW
+	AVPHMINPOSUW
+	AVPHSUBD
+	AVPHSUBSW
+	AVPHSUBW
+	AVPINSRB
+	AVPINSRD
+	AVPINSRQ
+	AVPINSRW
+	AVPMADDUBSW
+	AVPMADDWD
+	AVPMASKMOVD
+	AVPMASKMOVQ
+	AVPMAXSB
+	AVPMAXSD
+	AVPMAXSW
+	AVPMAXUB
+	AVPMAXUD
+	AVPMAXUW
+	AVPMINSB
+	AVPMINSD
+	AVPMINSW
+	AVPMINUB
+	AVPMINUD
+	AVPMINUW
+	AVPMOVMSKB
+	AVPMOVSXBD
+	AVPMOVSXBQ
+	AVPMOVSXBW
+	AVPMOVSXDQ
+	AVPMOVSXWD
+	AVPMOVSXWQ
+	AVPMOVZXBD
+	AVPMOVZXBQ
+	AVPMOVZXBW
+	AVPMOVZXDQ
+	AVPMOVZXWD
+	AVPMOVZXWQ
+	AVPMULDQ
+	AVPMULHRSW
+	AVPMULHUW
+	AVPMULHW
+	AVPMULLD
+	AVPMULLW
+	AVPMULUDQ
+	AVPOR
+	AVPSADBW
+	AVPSHUFB
+	AVPSHUFD
+	AVPSHUFHW
+	AVPSHUFLW
+	AVPSIGNB
+	AVPSIGND
+	AVPSIGNW
+	AVPSLLD
+	AVPSLLDQ
+	AVPSLLQ
+	AVPSLLVD
+	AVPSLLVQ
+	AVPSLLW
+	AVPSRAD
+	AVPSRAVD
+	AVPSRAW
+	AVPSRLD
+	AVPSRLDQ
+	AVPSRLQ
+	AVPSRLVD
+	AVPSRLVQ
+	AVPSRLW
+	AVPSUBB
+	AVPSUBD
+	AVPSUBQ
+	AVPSUBSB
+	AVPSUBSW
+	AVPSUBUSB
+	AVPSUBUSW
+	AVPSUBW
+	AVPTEST
+	AVPUNPCKHBW
+	AVPUNPCKHDQ
+	AVPUNPCKHQDQ
+	AVPUNPCKHWD
+	AVPUNPCKLBW
+	AVPUNPCKLDQ
+	AVPUNPCKLQDQ
+	AVPUNPCKLWD
+	AVPXOR
+	AVRCPPS
+	AVRCPSS
+	AVROUNDPD
+	AVROUNDPS
+	AVROUNDSD
+	AVROUNDSS
+	AVRSQRTPS
+	AVRSQRTSS
+	AVSHUFPD
+	AVSHUFPS
+	AVSQRTPD
+	AVSQRTPS
+	AVSQRTSD
+	AVSQRTSS
+	AVSTMXCSR
+	AVSUBPD
+	AVSUBPS
+	AVSUBSD
+	AVSUBSS
+	AVTESTPD
+	AVTESTPS
+	AVUCOMISD
+	AVUCOMISS
+	AVUNPCKHPD
+	AVUNPCKHPS
+	AVUNPCKLPD
+	AVUNPCKLPS
+	AVXORPD
+	AVXORPS
+	AVZEROALL
+	AVZEROUPPER
+	AWAIT
+	AWBINVD
+	AWORD
+	AWRMSR
+	AXABORT
+	AXACQUIRE
+	AXADDB
+	AXADDL
+	AXADDQ
+	AXADDW
+	AXBEGIN
+	AXCHGB
+	AXCHGL
+	AXCHGQ
+	AXCHGW
+	AXEND
+	AXGETBV
+	AXLAT
+	AXORB
+	AXORL
+	AXORPD
+	AXORPS
+	AXORQ
+	AXORW
+	AXRELEASE
+	AXTEST
+	ALAST
+)
diff --git a/src/cmd/internal/obj/x86/anames.go b/src/cmd/internal/obj/x86/anames.go
index 38cc03d..ec7bea1 100644
--- a/src/cmd/internal/obj/x86/anames.go
+++ b/src/cmd/internal/obj/x86/anames.go
@@ -1,4 +1,4 @@
-// Generated by stringer -i a.out.go -o anames.go -p x86
+// Generated by stringer -i aenum.go -o anames.go -p x86
 // Do not edit.
 
 package x86
@@ -12,351 +12,82 @@
 	"AAS",
 	"ADCB",
 	"ADCL",
+	"ADCQ",
 	"ADCW",
+	"ADCXL",
+	"ADCXQ",
 	"ADDB",
 	"ADDL",
+	"ADDPD",
+	"ADDPS",
+	"ADDQ",
+	"ADDSD",
+	"ADDSS",
+	"ADDSUBPD",
+	"ADDSUBPS",
 	"ADDW",
 	"ADJSP",
+	"ADOXL",
+	"ADOXQ",
+	"AESDEC",
+	"AESDECLAST",
+	"AESENC",
+	"AESENCLAST",
+	"AESIMC",
+	"AESKEYGENASSIST",
 	"ANDB",
 	"ANDL",
+	"ANDNL",
+	"ANDNPD",
+	"ANDNPS",
+	"ANDNQ",
+	"ANDPD",
+	"ANDPS",
+	"ANDQ",
 	"ANDW",
 	"ARPL",
+	"BEXTRL",
+	"BEXTRQ",
+	"BLENDPD",
+	"BLENDPS",
+	"BLSIL",
+	"BLSIQ",
+	"BLSMSKL",
+	"BLSMSKQ",
+	"BLSRL",
+	"BLSRQ",
 	"BOUNDL",
 	"BOUNDW",
 	"BSFL",
+	"BSFQ",
 	"BSFW",
 	"BSRL",
+	"BSRQ",
 	"BSRW",
-	"BTL",
-	"BTW",
+	"BSWAPL",
+	"BSWAPQ",
 	"BTCL",
+	"BTCQ",
 	"BTCW",
+	"BTL",
+	"BTQ",
 	"BTRL",
+	"BTRQ",
 	"BTRW",
 	"BTSL",
+	"BTSQ",
 	"BTSW",
+	"BTW",
 	"BYTE",
+	"BZHIL",
+	"BZHIQ",
+	"CDQ",
 	"CLC",
 	"CLD",
+	"CLFLUSH",
 	"CLI",
 	"CLTS",
 	"CMC",
-	"CMPB",
-	"CMPL",
-	"CMPW",
-	"CMPSB",
-	"CMPSL",
-	"CMPSW",
-	"DAA",
-	"DAS",
-	"DECB",
-	"DECL",
-	"DECQ",
-	"DECW",
-	"DIVB",
-	"DIVL",
-	"DIVW",
-	"ENTER",
-	"HADDPD",
-	"HADDPS",
-	"HLT",
-	"HSUBPD",
-	"HSUBPS",
-	"IDIVB",
-	"IDIVL",
-	"IDIVW",
-	"IMULB",
-	"IMULL",
-	"IMULW",
-	"INB",
-	"INL",
-	"INW",
-	"INCB",
-	"INCL",
-	"INCQ",
-	"INCW",
-	"INSB",
-	"INSL",
-	"INSW",
-	"INT",
-	"INTO",
-	"IRETL",
-	"IRETW",
-	"JCC",
-	"JCS",
-	"JCXZL",
-	"JEQ",
-	"JGE",
-	"JGT",
-	"JHI",
-	"JLE",
-	"JLS",
-	"JLT",
-	"JMI",
-	"JNE",
-	"JOC",
-	"JOS",
-	"JPC",
-	"JPL",
-	"JPS",
-	"LAHF",
-	"LARL",
-	"LARW",
-	"LEAL",
-	"LEAW",
-	"LEAVEL",
-	"LEAVEW",
-	"LOCK",
-	"LODSB",
-	"LODSL",
-	"LODSW",
-	"LONG",
-	"LOOP",
-	"LOOPEQ",
-	"LOOPNE",
-	"LSLL",
-	"LSLW",
-	"MOVB",
-	"MOVL",
-	"MOVW",
-	"MOVBLSX",
-	"MOVBLZX",
-	"MOVBQSX",
-	"MOVBQZX",
-	"MOVBWSX",
-	"MOVBWZX",
-	"MOVWLSX",
-	"MOVWLZX",
-	"MOVWQSX",
-	"MOVWQZX",
-	"MOVSB",
-	"MOVSL",
-	"MOVSW",
-	"MULB",
-	"MULL",
-	"MULW",
-	"NEGB",
-	"NEGL",
-	"NEGW",
-	"NOTB",
-	"NOTL",
-	"NOTW",
-	"ORB",
-	"ORL",
-	"ORW",
-	"OUTB",
-	"OUTL",
-	"OUTW",
-	"OUTSB",
-	"OUTSL",
-	"OUTSW",
-	"PAUSE",
-	"POPAL",
-	"POPAW",
-	"POPCNTW",
-	"POPCNTL",
-	"POPCNTQ",
-	"POPFL",
-	"POPFW",
-	"POPL",
-	"POPW",
-	"PUSHAL",
-	"PUSHAW",
-	"PUSHFL",
-	"PUSHFW",
-	"PUSHL",
-	"PUSHW",
-	"RCLB",
-	"RCLL",
-	"RCLW",
-	"RCRB",
-	"RCRL",
-	"RCRW",
-	"REP",
-	"REPN",
-	"ROLB",
-	"ROLL",
-	"ROLW",
-	"RORB",
-	"RORL",
-	"RORW",
-	"SAHF",
-	"SALB",
-	"SALL",
-	"SALW",
-	"SARB",
-	"SARL",
-	"SARW",
-	"SBBB",
-	"SBBL",
-	"SBBW",
-	"SCASB",
-	"SCASL",
-	"SCASW",
-	"SETCC",
-	"SETCS",
-	"SETEQ",
-	"SETGE",
-	"SETGT",
-	"SETHI",
-	"SETLE",
-	"SETLS",
-	"SETLT",
-	"SETMI",
-	"SETNE",
-	"SETOC",
-	"SETOS",
-	"SETPC",
-	"SETPL",
-	"SETPS",
-	"CDQ",
-	"CWD",
-	"SHLB",
-	"SHLL",
-	"SHLW",
-	"SHRB",
-	"SHRL",
-	"SHRW",
-	"STC",
-	"STD",
-	"STI",
-	"STOSB",
-	"STOSL",
-	"STOSW",
-	"SUBB",
-	"SUBL",
-	"SUBW",
-	"SYSCALL",
-	"TESTB",
-	"TESTL",
-	"TESTW",
-	"VERR",
-	"VERW",
-	"WAIT",
-	"WORD",
-	"XCHGB",
-	"XCHGL",
-	"XCHGW",
-	"XLAT",
-	"XORB",
-	"XORL",
-	"XORW",
-	"FMOVB",
-	"FMOVBP",
-	"FMOVD",
-	"FMOVDP",
-	"FMOVF",
-	"FMOVFP",
-	"FMOVL",
-	"FMOVLP",
-	"FMOVV",
-	"FMOVVP",
-	"FMOVW",
-	"FMOVWP",
-	"FMOVX",
-	"FMOVXP",
-	"FCOMD",
-	"FCOMDP",
-	"FCOMDPP",
-	"FCOMF",
-	"FCOMFP",
-	"FCOML",
-	"FCOMLP",
-	"FCOMW",
-	"FCOMWP",
-	"FUCOM",
-	"FUCOMP",
-	"FUCOMPP",
-	"FADDDP",
-	"FADDW",
-	"FADDL",
-	"FADDF",
-	"FADDD",
-	"FMULDP",
-	"FMULW",
-	"FMULL",
-	"FMULF",
-	"FMULD",
-	"FSUBDP",
-	"FSUBW",
-	"FSUBL",
-	"FSUBF",
-	"FSUBD",
-	"FSUBRDP",
-	"FSUBRW",
-	"FSUBRL",
-	"FSUBRF",
-	"FSUBRD",
-	"FDIVDP",
-	"FDIVW",
-	"FDIVL",
-	"FDIVF",
-	"FDIVD",
-	"FDIVRDP",
-	"FDIVRW",
-	"FDIVRL",
-	"FDIVRF",
-	"FDIVRD",
-	"FXCHD",
-	"FFREE",
-	"FLDCW",
-	"FLDENV",
-	"FRSTOR",
-	"FSAVE",
-	"FSTCW",
-	"FSTENV",
-	"FSTSW",
-	"F2XM1",
-	"FABS",
-	"FCHS",
-	"FCLEX",
-	"FCOS",
-	"FDECSTP",
-	"FINCSTP",
-	"FINIT",
-	"FLD1",
-	"FLDL2E",
-	"FLDL2T",
-	"FLDLG2",
-	"FLDLN2",
-	"FLDPI",
-	"FLDZ",
-	"FNOP",
-	"FPATAN",
-	"FPREM",
-	"FPREM1",
-	"FPTAN",
-	"FRNDINT",
-	"FSCALE",
-	"FSIN",
-	"FSINCOS",
-	"FSQRT",
-	"FTST",
-	"FXAM",
-	"FXTRACT",
-	"FYL2X",
-	"FYL2XP1",
-	"CMPXCHGB",
-	"CMPXCHGL",
-	"CMPXCHGW",
-	"CMPXCHG8B",
-	"CPUID",
-	"INVD",
-	"INVLPG",
-	"LFENCE",
-	"MFENCE",
-	"MOVNTIL",
-	"RDMSR",
-	"RDPMC",
-	"RDTSC",
-	"RSM",
-	"SFENCE",
-	"SYSRET",
-	"WBINVD",
-	"WRMSR",
-	"XADDB",
-	"XADDL",
-	"XADDW",
 	"CMOVLCC",
 	"CMOVLCS",
 	"CMOVLEQ",
@@ -405,84 +136,29 @@
 	"CMOVWPC",
 	"CMOVWPL",
 	"CMOVWPS",
-	"ADCQ",
-	"ADDQ",
-	"ANDQ",
-	"BSFQ",
-	"BSRQ",
-	"BTCQ",
-	"BTQ",
-	"BTRQ",
-	"BTSQ",
-	"CMPQ",
-	"CMPSQ",
-	"CMPXCHGQ",
-	"CQO",
-	"DIVQ",
-	"IDIVQ",
-	"IMULQ",
-	"IRETQ",
-	"JCXZQ",
-	"LEAQ",
-	"LEAVEQ",
-	"LODSQ",
-	"MOVQ",
-	"MOVLQSX",
-	"MOVLQZX",
-	"MOVNTIQ",
-	"MOVSQ",
-	"MULQ",
-	"NEGQ",
-	"NOTQ",
-	"ORQ",
-	"POPFQ",
-	"POPQ",
-	"PUSHFQ",
-	"PUSHQ",
-	"RCLQ",
-	"RCRQ",
-	"ROLQ",
-	"RORQ",
-	"QUAD",
-	"SALQ",
-	"SARQ",
-	"SBBQ",
-	"SCASQ",
-	"SHLQ",
-	"SHRQ",
-	"STOSQ",
-	"SUBQ",
-	"TESTQ",
-	"XADDQ",
-	"XCHGQ",
-	"XORQ",
-	"XGETBV",
-	"ADDPD",
-	"ADDPS",
-	"ADDSD",
-	"ADDSS",
-	"ANDNL",
-	"ANDNQ",
-	"ANDNPD",
-	"ANDNPS",
-	"ANDPD",
-	"ANDPS",
-	"BEXTRL",
-	"BEXTRQ",
-	"BLSIL",
-	"BLSIQ",
-	"BLSMSKL",
-	"BLSMSKQ",
-	"BLSRL",
-	"BLSRQ",
-	"BZHIL",
-	"BZHIQ",
+	"CMPB",
+	"CMPL",
 	"CMPPD",
 	"CMPPS",
+	"CMPQ",
+	"CMPSB",
 	"CMPSD",
+	"CMPSL",
+	"CMPSQ",
 	"CMPSS",
+	"CMPSW",
+	"CMPW",
+	"CMPXCHG8B",
+	"CMPXCHGB",
+	"CMPXCHGL",
+	"CMPXCHGQ",
+	"CMPXCHGW",
 	"COMISD",
 	"COMISS",
+	"CPUID",
+	"CQO",
+	"CRC32B",
+	"CRC32Q",
 	"CVTPD2PL",
 	"CVTPD2PS",
 	"CVTPL2PD",
@@ -505,58 +181,307 @@
 	"CVTTSD2SQ",
 	"CVTTSS2SL",
 	"CVTTSS2SQ",
+	"CWD",
+	"DAA",
+	"DAS",
+	"DECB",
+	"DECL",
+	"DECQ",
+	"DECW",
+	"DIVB",
+	"DIVL",
 	"DIVPD",
 	"DIVPS",
+	"DIVQ",
 	"DIVSD",
 	"DIVSS",
+	"DIVW",
+	"DPPD",
+	"DPPS",
 	"EMMS",
+	"ENTER",
+	"EXTRACTPS",
+	"F2XM1",
+	"FABS",
+	"FADDD",
+	"FADDDP",
+	"FADDF",
+	"FADDL",
+	"FADDW",
+	"FCHS",
+	"FCLEX",
+	"FCMOVCC",
+	"FCMOVCS",
+	"FCMOVEQ",
+	"FCMOVHI",
+	"FCMOVLS",
+	"FCMOVNE",
+	"FCMOVNU",
+	"FCMOVUN",
+	"FCOMD",
+	"FCOMDP",
+	"FCOMDPP",
+	"FCOMF",
+	"FCOMFP",
+	"FCOMI",
+	"FCOMIP",
+	"FCOML",
+	"FCOMLP",
+	"FCOMW",
+	"FCOMWP",
+	"FCOS",
+	"FDECSTP",
+	"FDIVD",
+	"FDIVDP",
+	"FDIVF",
+	"FDIVL",
+	"FDIVRD",
+	"FDIVRDP",
+	"FDIVRF",
+	"FDIVRL",
+	"FDIVRW",
+	"FDIVW",
+	"FFREE",
+	"FINCSTP",
+	"FINIT",
+	"FLD1",
+	"FLDCW",
+	"FLDENV",
+	"FLDL2E",
+	"FLDL2T",
+	"FLDLG2",
+	"FLDLN2",
+	"FLDPI",
+	"FLDZ",
+	"FMOVB",
+	"FMOVBP",
+	"FMOVD",
+	"FMOVDP",
+	"FMOVF",
+	"FMOVFP",
+	"FMOVL",
+	"FMOVLP",
+	"FMOVV",
+	"FMOVVP",
+	"FMOVW",
+	"FMOVWP",
+	"FMOVX",
+	"FMOVXP",
+	"FMULD",
+	"FMULDP",
+	"FMULF",
+	"FMULL",
+	"FMULW",
+	"FNOP",
+	"FPATAN",
+	"FPREM",
+	"FPREM1",
+	"FPTAN",
+	"FRNDINT",
+	"FRSTOR",
+	"FSAVE",
+	"FSCALE",
+	"FSIN",
+	"FSINCOS",
+	"FSQRT",
+	"FSTCW",
+	"FSTENV",
+	"FSTSW",
+	"FSUBD",
+	"FSUBDP",
+	"FSUBF",
+	"FSUBL",
+	"FSUBRD",
+	"FSUBRDP",
+	"FSUBRF",
+	"FSUBRL",
+	"FSUBRW",
+	"FSUBW",
+	"FTST",
+	"FUCOM",
+	"FUCOMI",
+	"FUCOMIP",
+	"FUCOMP",
+	"FUCOMPP",
+	"FXAM",
+	"FXCHD",
 	"FXRSTOR",
 	"FXRSTOR64",
 	"FXSAVE",
 	"FXSAVE64",
+	"FXTRACT",
+	"FYL2X",
+	"FYL2XP1",
+	"HADDPD",
+	"HADDPS",
+	"HLT",
+	"HSUBPD",
+	"HSUBPS",
+	"IDIVB",
+	"IDIVL",
+	"IDIVQ",
+	"IDIVW",
+	"IMUL3Q",
+	"IMULB",
+	"IMULL",
+	"IMULQ",
+	"IMULW",
+	"INB",
+	"INCB",
+	"INCL",
+	"INCQ",
+	"INCW",
+	"INL",
+	"INSB",
+	"INSERTPS",
+	"INSL",
+	"INSW",
+	"INT",
+	"INTO",
+	"INVD",
+	"INVLPG",
+	"INW",
+	"IRETL",
+	"IRETQ",
+	"IRETW",
+	"JCC",
+	"JCS",
+	"JCXZL",
+	"JCXZQ",
+	"JCXZW",
+	"JEQ",
+	"JGE",
+	"JGT",
+	"JHI",
+	"JLE",
+	"JLS",
+	"JLT",
+	"JMI",
+	"JNE",
+	"JOC",
+	"JOS",
+	"JPC",
+	"JPL",
+	"JPS",
+	"LAHF",
+	"LARL",
+	"LARW",
 	"LDDQU",
 	"LDMXCSR",
+	"LEAL",
+	"LEAQ",
+	"LEAVEL",
+	"LEAVEQ",
+	"LEAVEW",
+	"LEAW",
+	"LFENCE",
+	"LOCK",
+	"LODSB",
+	"LODSL",
+	"LODSQ",
+	"LODSW",
+	"LONG",
+	"LOOP",
+	"LOOPEQ",
+	"LOOPNE",
+	"LSLL",
+	"LSLW",
 	"MASKMOVOU",
 	"MASKMOVQ",
 	"MAXPD",
 	"MAXPS",
 	"MAXSD",
 	"MAXSS",
+	"MFENCE",
 	"MINPD",
 	"MINPS",
 	"MINSD",
 	"MINSS",
 	"MOVAPD",
 	"MOVAPS",
-	"MOVOU",
+	"MOVB",
+	"MOVBLSX",
+	"MOVBLZX",
+	"MOVBQSX",
+	"MOVBQZX",
+	"MOVBWSX",
+	"MOVBWZX",
+	"MOVDDUP",
 	"MOVHLPS",
 	"MOVHPD",
 	"MOVHPS",
+	"MOVL",
 	"MOVLHPS",
 	"MOVLPD",
 	"MOVLPS",
+	"MOVLQSX",
+	"MOVLQZX",
 	"MOVMSKPD",
 	"MOVMSKPS",
+	"MOVNTDQA",
+	"MOVNTIL",
+	"MOVNTIQ",
 	"MOVNTO",
 	"MOVNTPD",
 	"MOVNTPS",
 	"MOVNTQ",
 	"MOVO",
+	"MOVOU",
+	"MOVQ",
+	"MOVQL",
 	"MOVQOZX",
+	"MOVSB",
 	"MOVSD",
+	"MOVSHDUP",
+	"MOVSL",
+	"MOVSLDUP",
+	"MOVSQ",
 	"MOVSS",
+	"MOVSW",
 	"MOVUPD",
 	"MOVUPS",
+	"MOVW",
+	"MOVWLSX",
+	"MOVWLZX",
+	"MOVWQSX",
+	"MOVWQZX",
+	"MPSADBW",
+	"MULB",
+	"MULL",
 	"MULPD",
 	"MULPS",
+	"MULQ",
 	"MULSD",
 	"MULSS",
+	"MULW",
 	"MULXL",
 	"MULXQ",
+	"NEGB",
+	"NEGL",
+	"NEGQ",
+	"NEGW",
+	"NOTB",
+	"NOTL",
+	"NOTQ",
+	"NOTW",
+	"ORB",
+	"ORL",
 	"ORPD",
 	"ORPS",
+	"ORQ",
+	"ORW",
+	"OUTB",
+	"OUTL",
+	"OUTSB",
+	"OUTSL",
+	"OUTSW",
+	"OUTW",
+	"PABSB",
+	"PABSD",
+	"PABSW",
 	"PACKSSLW",
 	"PACKSSWB",
+	"PACKUSDW",
 	"PACKUSWB",
 	"PADDB",
 	"PADDL",
@@ -566,16 +491,26 @@
 	"PADDUSB",
 	"PADDUSW",
 	"PADDW",
+	"PALIGNR",
 	"PAND",
 	"PANDN",
+	"PAUSE",
 	"PAVGB",
 	"PAVGW",
+	"PBLENDW",
+	"PCLMULQDQ",
 	"PCMPEQB",
 	"PCMPEQL",
+	"PCMPEQQ",
 	"PCMPEQW",
+	"PCMPESTRI",
+	"PCMPESTRM",
 	"PCMPGTB",
 	"PCMPGTL",
+	"PCMPGTQ",
 	"PCMPGTW",
+	"PCMPISTRI",
+	"PCMPISTRM",
 	"PDEPL",
 	"PDEPQ",
 	"PEXTL",
@@ -595,11 +530,20 @@
 	"PINSRD",
 	"PINSRQ",
 	"PINSRW",
+	"PMADDUBSW",
 	"PMADDWL",
+	"PMAXSB",
+	"PMAXSD",
 	"PMAXSW",
 	"PMAXUB",
+	"PMAXUD",
+	"PMAXUW",
+	"PMINSB",
+	"PMINSD",
 	"PMINSW",
 	"PMINUB",
+	"PMINUD",
+	"PMINUW",
 	"PMOVMSKB",
 	"PMOVSXBD",
 	"PMOVSXBQ",
@@ -614,18 +558,38 @@
 	"PMOVZXWD",
 	"PMOVZXWQ",
 	"PMULDQ",
+	"PMULHRSW",
 	"PMULHUW",
 	"PMULHW",
 	"PMULLD",
 	"PMULLW",
 	"PMULULQ",
+	"POPAL",
+	"POPAW",
+	"POPCNTL",
+	"POPCNTQ",
+	"POPCNTW",
+	"POPFL",
+	"POPFQ",
+	"POPFW",
+	"POPL",
+	"POPQ",
+	"POPW",
 	"POR",
+	"PREFETCHNTA",
+	"PREFETCHT0",
+	"PREFETCHT1",
+	"PREFETCHT2",
 	"PSADBW",
 	"PSHUFB",
+	"PSHUFD",
 	"PSHUFHW",
 	"PSHUFL",
 	"PSHUFLW",
 	"PSHUFW",
+	"PSIGNB",
+	"PSIGND",
+	"PSIGNW",
 	"PSLLL",
 	"PSLLO",
 	"PSLLQ",
@@ -644,6 +608,7 @@
 	"PSUBUSB",
 	"PSUBUSW",
 	"PSUBW",
+	"PTEST",
 	"PUNPCKHBW",
 	"PUNPCKHLQ",
 	"PUNPCKHQDQ",
@@ -652,15 +617,97 @@
 	"PUNPCKLLQ",
 	"PUNPCKLQDQ",
 	"PUNPCKLWL",
+	"PUSHAL",
+	"PUSHAW",
+	"PUSHFL",
+	"PUSHFQ",
+	"PUSHFW",
+	"PUSHL",
+	"PUSHQ",
+	"PUSHW",
 	"PXOR",
+	"QUAD",
+	"RCLB",
+	"RCLL",
+	"RCLQ",
+	"RCLW",
 	"RCPPS",
 	"RCPSS",
+	"RCRB",
+	"RCRL",
+	"RCRQ",
+	"RCRW",
+	"RDMSR",
+	"RDPMC",
+	"RDTSC",
+	"REP",
+	"REPN",
+	"RETFL",
+	"RETFQ",
+	"RETFW",
+	"ROLB",
+	"ROLL",
+	"ROLQ",
+	"ROLW",
+	"RORB",
+	"RORL",
+	"RORQ",
+	"RORW",
+	"RORXL",
+	"RORXQ",
+	"ROUNDPD",
+	"ROUNDPS",
+	"ROUNDSD",
+	"ROUNDSS",
+	"RSM",
 	"RSQRTPS",
 	"RSQRTSS",
+	"SAHF",
+	"SALB",
+	"SALL",
+	"SALQ",
+	"SALW",
+	"SARB",
+	"SARL",
+	"SARQ",
+	"SARW",
 	"SARXL",
 	"SARXQ",
+	"SBBB",
+	"SBBL",
+	"SBBQ",
+	"SBBW",
+	"SCASB",
+	"SCASL",
+	"SCASQ",
+	"SCASW",
+	"SETCC",
+	"SETCS",
+	"SETEQ",
+	"SETGE",
+	"SETGT",
+	"SETHI",
+	"SETLE",
+	"SETLS",
+	"SETLT",
+	"SETMI",
+	"SETNE",
+	"SETOC",
+	"SETOS",
+	"SETPC",
+	"SETPL",
+	"SETPS",
+	"SFENCE",
+	"SHLB",
+	"SHLL",
+	"SHLQ",
+	"SHLW",
 	"SHLXL",
 	"SHLXQ",
+	"SHRB",
+	"SHRL",
+	"SHRQ",
+	"SHRW",
 	"SHRXL",
 	"SHRXQ",
 	"SHUFPD",
@@ -669,100 +716,420 @@
 	"SQRTPS",
 	"SQRTSD",
 	"SQRTSS",
+	"STC",
+	"STD",
+	"STI",
 	"STMXCSR",
+	"STOSB",
+	"STOSL",
+	"STOSQ",
+	"STOSW",
+	"SUBB",
+	"SUBL",
 	"SUBPD",
 	"SUBPS",
+	"SUBQ",
 	"SUBSD",
 	"SUBSS",
+	"SUBW",
+	"SWAPGS",
+	"SYSCALL",
+	"SYSRET",
+	"TESTB",
+	"TESTL",
+	"TESTQ",
+	"TESTW",
 	"UCOMISD",
 	"UCOMISS",
 	"UNPCKHPD",
 	"UNPCKHPS",
 	"UNPCKLPD",
 	"UNPCKLPS",
-	"XORPD",
-	"XORPS",
-	"PCMPESTRI",
-	"RETFW",
-	"RETFL",
-	"RETFQ",
-	"SWAPGS",
-	"CRC32B",
-	"CRC32Q",
-	"IMUL3Q",
-	"PREFETCHT0",
-	"PREFETCHT1",
-	"PREFETCHT2",
-	"PREFETCHNTA",
-	"MOVQL",
-	"BSWAPL",
-	"BSWAPQ",
-	"AESENC",
-	"AESENCLAST",
-	"AESDEC",
-	"AESDECLAST",
-	"AESIMC",
-	"AESKEYGENASSIST",
-	"ROUNDPS",
-	"ROUNDSS",
-	"ROUNDPD",
-	"ROUNDSD",
-	"MOVDDUP",
-	"MOVSHDUP",
-	"MOVSLDUP",
-	"PSHUFD",
-	"PCLMULQDQ",
-	"VZEROUPPER",
-	"VMOVDQU",
-	"VMOVNTDQ",
-	"VMOVDQA",
-	"VPCMPEQB",
-	"VPXOR",
-	"VPMOVMSKB",
-	"VPAND",
-	"VPTEST",
-	"VPBROADCASTB",
-	"VPSHUFB",
-	"VPSHUFD",
-	"VPERM2F128",
-	"VPALIGNR",
-	"VPADDQ",
-	"VPADDD",
-	"VPSRLDQ",
-	"VPSLLDQ",
-	"VPSRLQ",
-	"VPSLLQ",
-	"VPSRLD",
-	"VPSLLD",
-	"VPOR",
-	"VPBLENDD",
-	"VINSERTI128",
-	"VPERM2I128",
-	"RORXL",
-	"RORXQ",
-	"VBROADCASTSS",
+	"VADDPD",
+	"VADDPS",
+	"VADDSD",
+	"VADDSS",
+	"VADDSUBPD",
+	"VADDSUBPS",
+	"VAESDEC",
+	"VAESDECLAST",
+	"VAESENC",
+	"VAESENCLAST",
+	"VAESIMC",
+	"VAESKEYGENASSIST",
+	"VANDNPD",
+	"VANDNPS",
+	"VANDPD",
+	"VANDPS",
+	"VBLENDPD",
+	"VBLENDPS",
+	"VBLENDVPD",
+	"VBLENDVPS",
+	"VBROADCASTF128",
+	"VBROADCASTI128",
 	"VBROADCASTSD",
+	"VBROADCASTSS",
+	"VCMPPD",
+	"VCMPPS",
+	"VCMPSD",
+	"VCMPSS",
+	"VCOMISD",
+	"VCOMISS",
+	"VCVTDQ2PD",
+	"VCVTDQ2PS",
+	"VCVTPD2DQX",
+	"VCVTPD2DQY",
+	"VCVTPD2PSX",
+	"VCVTPD2PSY",
+	"VCVTPH2PS",
+	"VCVTPS2DQ",
+	"VCVTPS2PD",
+	"VCVTPS2PH",
+	"VCVTSD2SI",
+	"VCVTSD2SIQ",
+	"VCVTSD2SS",
+	"VCVTSI2SDL",
+	"VCVTSI2SDQ",
+	"VCVTSI2SSL",
+	"VCVTSI2SSQ",
+	"VCVTSS2SD",
+	"VCVTSS2SI",
+	"VCVTSS2SIQ",
+	"VCVTTPD2DQX",
+	"VCVTTPD2DQY",
+	"VCVTTPS2DQ",
+	"VCVTTSD2SI",
+	"VCVTTSD2SIQ",
+	"VCVTTSS2SI",
+	"VCVTTSS2SIQ",
+	"VDIVPD",
+	"VDIVPS",
+	"VDIVSD",
+	"VDIVSS",
+	"VDPPD",
+	"VDPPS",
+	"VERR",
+	"VERW",
+	"VEXTRACTF128",
+	"VEXTRACTI128",
+	"VEXTRACTPS",
+	"VFMADD132PD",
+	"VFMADD132PS",
+	"VFMADD132SD",
+	"VFMADD132SS",
+	"VFMADD213PD",
+	"VFMADD213PS",
+	"VFMADD213SD",
+	"VFMADD213SS",
+	"VFMADD231PD",
+	"VFMADD231PS",
+	"VFMADD231SD",
+	"VFMADD231SS",
+	"VFMADDSUB132PD",
+	"VFMADDSUB132PS",
+	"VFMADDSUB213PD",
+	"VFMADDSUB213PS",
+	"VFMADDSUB231PD",
+	"VFMADDSUB231PS",
+	"VFMSUB132PD",
+	"VFMSUB132PS",
+	"VFMSUB132SD",
+	"VFMSUB132SS",
+	"VFMSUB213PD",
+	"VFMSUB213PS",
+	"VFMSUB213SD",
+	"VFMSUB213SS",
+	"VFMSUB231PD",
+	"VFMSUB231PS",
+	"VFMSUB231SD",
+	"VFMSUB231SS",
+	"VFMSUBADD132PD",
+	"VFMSUBADD132PS",
+	"VFMSUBADD213PD",
+	"VFMSUBADD213PS",
+	"VFMSUBADD231PD",
+	"VFMSUBADD231PS",
+	"VFNMADD132PD",
+	"VFNMADD132PS",
+	"VFNMADD132SD",
+	"VFNMADD132SS",
+	"VFNMADD213PD",
+	"VFNMADD213PS",
+	"VFNMADD213SD",
+	"VFNMADD213SS",
+	"VFNMADD231PD",
+	"VFNMADD231PS",
+	"VFNMADD231SD",
+	"VFNMADD231SS",
+	"VFNMSUB132PD",
+	"VFNMSUB132PS",
+	"VFNMSUB132SD",
+	"VFNMSUB132SS",
+	"VFNMSUB213PD",
+	"VFNMSUB213PS",
+	"VFNMSUB213SD",
+	"VFNMSUB213SS",
+	"VFNMSUB231PD",
+	"VFNMSUB231PS",
+	"VFNMSUB231SD",
+	"VFNMSUB231SS",
+	"VGATHERDPD",
+	"VGATHERDPS",
+	"VGATHERQPD",
+	"VGATHERQPS",
+	"VHADDPD",
+	"VHADDPS",
+	"VHSUBPD",
+	"VHSUBPS",
+	"VINSERTF128",
+	"VINSERTI128",
+	"VINSERTPS",
+	"VLDDQU",
+	"VLDMXCSR",
+	"VMASKMOVDQU",
+	"VMASKMOVPD",
+	"VMASKMOVPS",
+	"VMAXPD",
+	"VMAXPS",
+	"VMAXSD",
+	"VMAXSS",
+	"VMINPD",
+	"VMINPS",
+	"VMINSD",
+	"VMINSS",
+	"VMOVAPD",
+	"VMOVAPS",
+	"VMOVD",
 	"VMOVDDUP",
+	"VMOVDQA",
+	"VMOVDQU",
+	"VMOVHLPS",
+	"VMOVHPD",
+	"VMOVHPS",
+	"VMOVLHPS",
+	"VMOVLPD",
+	"VMOVLPS",
+	"VMOVMSKPD",
+	"VMOVMSKPS",
+	"VMOVNTDQ",
+	"VMOVNTDQA",
+	"VMOVNTPD",
+	"VMOVNTPS",
+	"VMOVQ",
+	"VMOVSD",
 	"VMOVSHDUP",
 	"VMOVSLDUP",
-	"JCXZW",
-	"FCMOVCC",
-	"FCMOVCS",
-	"FCMOVEQ",
-	"FCMOVHI",
-	"FCMOVLS",
-	"FCMOVNE",
-	"FCMOVNU",
-	"FCMOVUN",
-	"FCOMI",
-	"FCOMIP",
-	"FUCOMI",
-	"FUCOMIP",
-	"XACQUIRE",
-	"XRELEASE",
-	"XBEGIN",
-	"XEND",
+	"VMOVSS",
+	"VMOVUPD",
+	"VMOVUPS",
+	"VMPSADBW",
+	"VMULPD",
+	"VMULPS",
+	"VMULSD",
+	"VMULSS",
+	"VORPD",
+	"VORPS",
+	"VPABSB",
+	"VPABSD",
+	"VPABSW",
+	"VPACKSSDW",
+	"VPACKSSWB",
+	"VPACKUSDW",
+	"VPACKUSWB",
+	"VPADDB",
+	"VPADDD",
+	"VPADDQ",
+	"VPADDSB",
+	"VPADDSW",
+	"VPADDUSB",
+	"VPADDUSW",
+	"VPADDW",
+	"VPALIGNR",
+	"VPAND",
+	"VPANDN",
+	"VPAVGB",
+	"VPAVGW",
+	"VPBLENDD",
+	"VPBLENDVB",
+	"VPBLENDW",
+	"VPBROADCASTB",
+	"VPBROADCASTD",
+	"VPBROADCASTQ",
+	"VPBROADCASTW",
+	"VPCLMULQDQ",
+	"VPCMPEQB",
+	"VPCMPEQD",
+	"VPCMPEQQ",
+	"VPCMPEQW",
+	"VPCMPESTRI",
+	"VPCMPESTRM",
+	"VPCMPGTB",
+	"VPCMPGTD",
+	"VPCMPGTQ",
+	"VPCMPGTW",
+	"VPCMPISTRI",
+	"VPCMPISTRM",
+	"VPERM2F128",
+	"VPERM2I128",
+	"VPERMD",
+	"VPERMILPD",
+	"VPERMILPS",
+	"VPERMPD",
+	"VPERMPS",
+	"VPERMQ",
+	"VPEXTRB",
+	"VPEXTRD",
+	"VPEXTRQ",
+	"VPEXTRW",
+	"VPGATHERDD",
+	"VPGATHERDQ",
+	"VPGATHERQD",
+	"VPGATHERQQ",
+	"VPHADDD",
+	"VPHADDSW",
+	"VPHADDW",
+	"VPHMINPOSUW",
+	"VPHSUBD",
+	"VPHSUBSW",
+	"VPHSUBW",
+	"VPINSRB",
+	"VPINSRD",
+	"VPINSRQ",
+	"VPINSRW",
+	"VPMADDUBSW",
+	"VPMADDWD",
+	"VPMASKMOVD",
+	"VPMASKMOVQ",
+	"VPMAXSB",
+	"VPMAXSD",
+	"VPMAXSW",
+	"VPMAXUB",
+	"VPMAXUD",
+	"VPMAXUW",
+	"VPMINSB",
+	"VPMINSD",
+	"VPMINSW",
+	"VPMINUB",
+	"VPMINUD",
+	"VPMINUW",
+	"VPMOVMSKB",
+	"VPMOVSXBD",
+	"VPMOVSXBQ",
+	"VPMOVSXBW",
+	"VPMOVSXDQ",
+	"VPMOVSXWD",
+	"VPMOVSXWQ",
+	"VPMOVZXBD",
+	"VPMOVZXBQ",
+	"VPMOVZXBW",
+	"VPMOVZXDQ",
+	"VPMOVZXWD",
+	"VPMOVZXWQ",
+	"VPMULDQ",
+	"VPMULHRSW",
+	"VPMULHUW",
+	"VPMULHW",
+	"VPMULLD",
+	"VPMULLW",
+	"VPMULUDQ",
+	"VPOR",
+	"VPSADBW",
+	"VPSHUFB",
+	"VPSHUFD",
+	"VPSHUFHW",
+	"VPSHUFLW",
+	"VPSIGNB",
+	"VPSIGND",
+	"VPSIGNW",
+	"VPSLLD",
+	"VPSLLDQ",
+	"VPSLLQ",
+	"VPSLLVD",
+	"VPSLLVQ",
+	"VPSLLW",
+	"VPSRAD",
+	"VPSRAVD",
+	"VPSRAW",
+	"VPSRLD",
+	"VPSRLDQ",
+	"VPSRLQ",
+	"VPSRLVD",
+	"VPSRLVQ",
+	"VPSRLW",
+	"VPSUBB",
+	"VPSUBD",
+	"VPSUBQ",
+	"VPSUBSB",
+	"VPSUBSW",
+	"VPSUBUSB",
+	"VPSUBUSW",
+	"VPSUBW",
+	"VPTEST",
+	"VPUNPCKHBW",
+	"VPUNPCKHDQ",
+	"VPUNPCKHQDQ",
+	"VPUNPCKHWD",
+	"VPUNPCKLBW",
+	"VPUNPCKLDQ",
+	"VPUNPCKLQDQ",
+	"VPUNPCKLWD",
+	"VPXOR",
+	"VRCPPS",
+	"VRCPSS",
+	"VROUNDPD",
+	"VROUNDPS",
+	"VROUNDSD",
+	"VROUNDSS",
+	"VRSQRTPS",
+	"VRSQRTSS",
+	"VSHUFPD",
+	"VSHUFPS",
+	"VSQRTPD",
+	"VSQRTPS",
+	"VSQRTSD",
+	"VSQRTSS",
+	"VSTMXCSR",
+	"VSUBPD",
+	"VSUBPS",
+	"VSUBSD",
+	"VSUBSS",
+	"VTESTPD",
+	"VTESTPS",
+	"VUCOMISD",
+	"VUCOMISS",
+	"VUNPCKHPD",
+	"VUNPCKHPS",
+	"VUNPCKLPD",
+	"VUNPCKLPS",
+	"VXORPD",
+	"VXORPS",
+	"VZEROALL",
+	"VZEROUPPER",
+	"WAIT",
+	"WBINVD",
+	"WORD",
+	"WRMSR",
 	"XABORT",
+	"XACQUIRE",
+	"XADDB",
+	"XADDL",
+	"XADDQ",
+	"XADDW",
+	"XBEGIN",
+	"XCHGB",
+	"XCHGL",
+	"XCHGQ",
+	"XCHGW",
+	"XEND",
+	"XGETBV",
+	"XLAT",
+	"XORB",
+	"XORL",
+	"XORPD",
+	"XORPS",
+	"XORQ",
+	"XORW",
+	"XRELEASE",
 	"XTEST",
 	"LAST",
 }
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index bcf9318..7b80892 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -72,14 +72,6 @@
 	op     [23]uint8
 }
 
-type ytab struct {
-	from    uint8
-	from3   uint8
-	to      uint8
-	zcase   uint8
-	zoffset uint8
-}
-
 type Movtab struct {
 	as   obj.As
 	ft   uint8
@@ -94,6 +86,7 @@
 	Ynone
 	Yi0 // $0
 	Yi1 // $1
+	Yu2 // $x, x fits in uint2
 	Yi8 // $x, x fits in int8
 	Yu8 // $x, x fits in uint8
 	Yu7 // $x, x in 0..127 (fits in both int8 and uint8)
@@ -155,8 +148,10 @@
 	Ymm
 	Yxr
 	Yxm
+	Yxvm // VSIB vector array; vm32x/vm64x
 	Yyr
 	Yym
+	Yyvm // VSIB vector array; vm32y/vm64y
 	Ytls
 	Ytextsize
 	Yindir
@@ -209,14 +204,19 @@
 	Zm_ilo
 	Zib_rr
 	Zil_rr
-	Zclr
 	Zbyte
 	Zvex_rm_v_r
+	Zvex_rm_v_ro
 	Zvex_r_v_rm
 	Zvex_v_rm_r
 	Zvex_i_rm_r
 	Zvex_i_r_v
 	Zvex_i_rm_v_r
+	Zvex
+	Zvex_rm_r_vo
+	Zvex_i_r_rm
+	Zvex_hr_rm_v_r
+
 	Zmax
 )
 
@@ -233,6 +233,9 @@
 	Pef3 = 0xf5 /* xmm escape 2 with 16-bit prefix: 66 f3 0f */
 	Pq3  = 0x67 /* xmm escape 3: 66 48 0f */
 	Pq4  = 0x68 /* xmm escape 4: 66 0F 38 */
+	Pq4w = 0x69 /* Pq4 with Rex.w 66 0F 38 */
+	Pq5  = 0x6a /* xmm escape 5: F3 0F 38 */
+	Pq5w = 0x6b /* Pq5 with Rex.w F3 0F 38 */
 	Pfw  = 0xf4 /* Pf3 with Rex.w: f3 48 0f */
 	Pw   = 0x48 /* Rex.w */
 	Pw8  = 0x90 // symbolic; exact value doesn't matter
@@ -252,6 +255,11 @@
 	// The P, L, and W fields are chosen to match
 	// their eventual locations in the VEX prefix bytes.
 
+	// V field - 4 bits; ignored by encoder
+	vexNOVSR = 0 // No VEX-SPECIFIED-REGISTER
+	vexNDS   = 0
+	vexNDD   = 0
+	vexDDS   = 0
 	// P field - 2 bits
 	vex66 = 1 << 0
 	vexF3 = 2 << 0
@@ -271,49 +279,38 @@
 	vex0F3A = 3 << 3
 
 	// Combinations used in the manual.
-	VEX_128_0F_WIG      = vex128 | vex0F | vexWIG
-	VEX_128_66_0F_W0    = vex128 | vex66 | vex0F | vexW0
-	VEX_128_66_0F_W1    = vex128 | vex66 | vex0F | vexW1
-	VEX_128_66_0F_WIG   = vex128 | vex66 | vex0F | vexWIG
-	VEX_128_66_0F38_W0  = vex128 | vex66 | vex0F38 | vexW0
-	VEX_128_66_0F38_W1  = vex128 | vex66 | vex0F38 | vexW1
-	VEX_128_66_0F38_WIG = vex128 | vex66 | vex0F38 | vexWIG
-	VEX_128_66_0F3A_W0  = vex128 | vex66 | vex0F3A | vexW0
-	VEX_128_66_0F3A_W1  = vex128 | vex66 | vex0F3A | vexW1
-	VEX_128_66_0F3A_WIG = vex128 | vex66 | vex0F3A | vexWIG
-	VEX_128_F2_0F_WIG   = vex128 | vexF2 | vex0F | vexWIG
-	VEX_128_F3_0F_WIG   = vex128 | vexF3 | vex0F | vexWIG
-	VEX_256_66_0F_WIG   = vex256 | vex66 | vex0F | vexWIG
-	VEX_256_66_0F38_W0  = vex256 | vex66 | vex0F38 | vexW0
-	VEX_256_66_0F38_W1  = vex256 | vex66 | vex0F38 | vexW1
-	VEX_256_66_0F38_WIG = vex256 | vex66 | vex0F38 | vexWIG
-	VEX_256_66_0F3A_W0  = vex256 | vex66 | vex0F3A | vexW0
-	VEX_256_66_0F3A_W1  = vex256 | vex66 | vex0F3A | vexW1
-	VEX_256_66_0F3A_WIG = vex256 | vex66 | vex0F3A | vexWIG
-	VEX_256_F2_0F_WIG   = vex256 | vexF2 | vex0F | vexWIG
-	VEX_256_F3_0F_WIG   = vex256 | vexF3 | vex0F | vexWIG
-	VEX_LIG_0F_WIG      = vexLIG | vex0F | vexWIG
-	VEX_LIG_66_0F_WIG   = vexLIG | vex66 | vex0F | vexWIG
-	VEX_LIG_66_0F38_W0  = vexLIG | vex66 | vex0F38 | vexW0
-	VEX_LIG_66_0F38_W1  = vexLIG | vex66 | vex0F38 | vexW1
-	VEX_LIG_66_0F3A_WIG = vexLIG | vex66 | vex0F3A | vexWIG
-	VEX_LIG_F2_0F_W0    = vexLIG | vexF2 | vex0F | vexW0
-	VEX_LIG_F2_0F_W1    = vexLIG | vexF2 | vex0F | vexW1
-	VEX_LIG_F2_0F_WIG   = vexLIG | vexF2 | vex0F | vexWIG
-	VEX_LIG_F3_0F_W0    = vexLIG | vexF3 | vex0F | vexW0
-	VEX_LIG_F3_0F_W1    = vexLIG | vexF3 | vex0F | vexW1
-	VEX_LIG_F3_0F_WIG   = vexLIG | vexF3 | vex0F | vexWIG
-	VEX_LZ_0F_WIG       = vexLZ | vex0F | vexWIG
-	VEX_LZ_0F38_W0      = vexLZ | vex0F38 | vexW0
-	VEX_LZ_0F38_W1      = vexLZ | vex0F38 | vexW1
-	VEX_LZ_66_0F38_W0   = vexLZ | vex66 | vex0F38 | vexW0
-	VEX_LZ_66_0F38_W1   = vexLZ | vex66 | vex0F38 | vexW1
-	VEX_LZ_F2_0F38_W0   = vexLZ | vexF2 | vex0F38 | vexW0
-	VEX_LZ_F2_0F38_W1   = vexLZ | vexF2 | vex0F38 | vexW1
-	VEX_LZ_F2_0F3A_W0   = vexLZ | vexF2 | vex0F3A | vexW0
-	VEX_LZ_F2_0F3A_W1   = vexLZ | vexF2 | vex0F3A | vexW1
-	VEX_LZ_F3_0F38_W0   = vexLZ | vexF3 | vex0F38 | vexW0
-	VEX_LZ_F3_0F38_W1   = vexLZ | vexF3 | vex0F38 | vexW1
+	VEX_DDS_LIG_66_0F38_W1    = vexDDS | vexLIG | vex66 | vex0F38 | vexW1
+	VEX_NDD_128_66_0F_WIG     = vexNDD | vex128 | vex66 | vex0F | vexWIG
+	VEX_NDD_256_66_0F_WIG     = vexNDD | vex256 | vex66 | vex0F | vexWIG
+	VEX_NDD_LZ_F2_0F38_W0     = vexNDD | vexLZ | vexF2 | vex0F38 | vexW0
+	VEX_NDD_LZ_F2_0F38_W1     = vexNDD | vexLZ | vexF2 | vex0F38 | vexW1
+	VEX_NDS_128_66_0F_WIG     = vexNDS | vex128 | vex66 | vex0F | vexWIG
+	VEX_NDS_128_66_0F38_WIG   = vexNDS | vex128 | vex66 | vex0F38 | vexWIG
+	VEX_NDS_128_F2_0F_WIG     = vexNDS | vex128 | vexF2 | vex0F | vexWIG
+	VEX_NDS_256_66_0F_WIG     = vexNDS | vex256 | vex66 | vex0F | vexWIG
+	VEX_NDS_256_66_0F38_WIG   = vexNDS | vex256 | vex66 | vex0F38 | vexWIG
+	VEX_NDS_256_66_0F3A_W0    = vexNDS | vex256 | vex66 | vex0F3A | vexW0
+	VEX_NDS_256_66_0F3A_WIG   = vexNDS | vex256 | vex66 | vex0F3A | vexWIG
+	VEX_NDS_LZ_0F38_W0        = vexNDS | vexLZ | vex0F38 | vexW0
+	VEX_NDS_LZ_0F38_W1        = vexNDS | vexLZ | vex0F38 | vexW1
+	VEX_NDS_LZ_66_0F38_W0     = vexNDS | vexLZ | vex66 | vex0F38 | vexW0
+	VEX_NDS_LZ_66_0F38_W1     = vexNDS | vexLZ | vex66 | vex0F38 | vexW1
+	VEX_NDS_LZ_F2_0F38_W0     = vexNDS | vexLZ | vexF2 | vex0F38 | vexW0
+	VEX_NDS_LZ_F2_0F38_W1     = vexNDS | vexLZ | vexF2 | vex0F38 | vexW1
+	VEX_NDS_LZ_F3_0F38_W0     = vexNDS | vexLZ | vexF3 | vex0F38 | vexW0
+	VEX_NDS_LZ_F3_0F38_W1     = vexNDS | vexLZ | vexF3 | vex0F38 | vexW1
+	VEX_NOVSR_128_66_0F_WIG   = vexNOVSR | vex128 | vex66 | vex0F | vexWIG
+	VEX_NOVSR_128_66_0F38_W0  = vexNOVSR | vex128 | vex66 | vex0F38 | vexW0
+	VEX_NOVSR_128_66_0F38_WIG = vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG
+	VEX_NOVSR_128_F2_0F_WIG   = vexNOVSR | vex128 | vexF2 | vex0F | vexWIG
+	VEX_NOVSR_128_F3_0F_WIG   = vexNOVSR | vex128 | vexF3 | vex0F | vexWIG
+	VEX_NOVSR_256_66_0F_WIG   = vexNOVSR | vex256 | vex66 | vex0F | vexWIG
+	VEX_NOVSR_256_66_0F38_W0  = vexNOVSR | vex256 | vex66 | vex0F38 | vexW0
+	VEX_NOVSR_256_66_0F38_WIG = vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG
+	VEX_NOVSR_256_F2_0F_WIG   = vexNOVSR | vex256 | vexF2 | vex0F | vexWIG
+	VEX_NOVSR_256_F3_0F_WIG   = vexNOVSR | vex256 | vexF3 | vex0F | vexWIG
+	VEX_NOVSR_LZ_F2_0F3A_W0   = vexNOVSR | vexLZ | vexF2 | vex0F3A | vexW0
+	VEX_NOVSR_LZ_F2_0F3A_W1   = vexNOVSR | vexLZ | vexF2 | vex0F3A | vexW1
 )
 
 var ycover [Ymax * Ymax]uint8
@@ -323,463 +320,477 @@
 var regrex [MAXREG + 1]int
 
 var ynone = []ytab{
-	{Ynone, Ynone, Ynone, Zlit, 1},
+	{Zlit, 1, argList{}},
 }
 
 var ytext = []ytab{
-	{Ymb, Ynone, Ytextsize, Zpseudo, 0},
-	{Ymb, Yi32, Ytextsize, Zpseudo, 1},
+	{Zpseudo, 0, argList{Ymb, Ytextsize}},
+	{Zpseudo, 1, argList{Ymb, Yi32, Ytextsize}},
 }
 
 var ynop = []ytab{
-	{Ynone, Ynone, Ynone, Zpseudo, 0},
-	{Ynone, Ynone, Yiauto, Zpseudo, 0},
-	{Ynone, Ynone, Yml, Zpseudo, 0},
-	{Ynone, Ynone, Yrf, Zpseudo, 0},
-	{Ynone, Ynone, Yxr, Zpseudo, 0},
-	{Yiauto, Ynone, Ynone, Zpseudo, 0},
-	{Yml, Ynone, Ynone, Zpseudo, 0},
-	{Yrf, Ynone, Ynone, Zpseudo, 0},
-	{Yxr, Ynone, Ynone, Zpseudo, 1},
+	{Zpseudo, 0, argList{}},
+	{Zpseudo, 0, argList{Yiauto}},
+	{Zpseudo, 0, argList{Yml}},
+	{Zpseudo, 0, argList{Yrf}},
+	{Zpseudo, 0, argList{Yxr}},
+	{Zpseudo, 0, argList{Yiauto}},
+	{Zpseudo, 0, argList{Yml}},
+	{Zpseudo, 0, argList{Yrf}},
+	{Zpseudo, 1, argList{Yxr}},
 }
 
 var yfuncdata = []ytab{
-	{Yi32, Ynone, Ym, Zpseudo, 0},
+	{Zpseudo, 0, argList{Yi32, Ym}},
 }
 
 var ypcdata = []ytab{
-	{Yi32, Ynone, Yi32, Zpseudo, 0},
+	{Zpseudo, 0, argList{Yi32, Yi32}},
 }
 
 var yxorb = []ytab{
-	{Yi32, Ynone, Yal, Zib_, 1},
-	{Yi32, Ynone, Ymb, Zibo_m, 2},
-	{Yrb, Ynone, Ymb, Zr_m, 1},
-	{Ymb, Ynone, Yrb, Zm_r, 1},
+	{Zib_, 1, argList{Yi32, Yal}},
+	{Zibo_m, 2, argList{Yi32, Ymb}},
+	{Zr_m, 1, argList{Yrb, Ymb}},
+	{Zm_r, 1, argList{Ymb, Yrb}},
 }
 
 var yaddl = []ytab{
-	{Yi8, Ynone, Yml, Zibo_m, 2},
-	{Yi32, Ynone, Yax, Zil_, 1},
-	{Yi32, Ynone, Yml, Zilo_m, 2},
-	{Yrl, Ynone, Yml, Zr_m, 1},
-	{Yml, Ynone, Yrl, Zm_r, 1},
+	{Zibo_m, 2, argList{Yi8, Yml}},
+	{Zil_, 1, argList{Yi32, Yax}},
+	{Zilo_m, 2, argList{Yi32, Yml}},
+	{Zr_m, 1, argList{Yrl, Yml}},
+	{Zm_r, 1, argList{Yml, Yrl}},
 }
 
 var yincl = []ytab{
-	{Ynone, Ynone, Yrl, Z_rp, 1},
-	{Ynone, Ynone, Yml, Zo_m, 2},
+	{Z_rp, 1, argList{Yrl}},
+	{Zo_m, 2, argList{Yml}},
 }
 
 var yincq = []ytab{
-	{Ynone, Ynone, Yml, Zo_m, 2},
+	{Zo_m, 2, argList{Yml}},
 }
 
 var ycmpb = []ytab{
-	{Yal, Ynone, Yi32, Z_ib, 1},
-	{Ymb, Ynone, Yi32, Zm_ibo, 2},
-	{Ymb, Ynone, Yrb, Zm_r, 1},
-	{Yrb, Ynone, Ymb, Zr_m, 1},
+	{Z_ib, 1, argList{Yal, Yi32}},
+	{Zm_ibo, 2, argList{Ymb, Yi32}},
+	{Zm_r, 1, argList{Ymb, Yrb}},
+	{Zr_m, 1, argList{Yrb, Ymb}},
 }
 
 var ycmpl = []ytab{
-	{Yml, Ynone, Yi8, Zm_ibo, 2},
-	{Yax, Ynone, Yi32, Z_il, 1},
-	{Yml, Ynone, Yi32, Zm_ilo, 2},
-	{Yml, Ynone, Yrl, Zm_r, 1},
-	{Yrl, Ynone, Yml, Zr_m, 1},
+	{Zm_ibo, 2, argList{Yml, Yi8}},
+	{Z_il, 1, argList{Yax, Yi32}},
+	{Zm_ilo, 2, argList{Yml, Yi32}},
+	{Zm_r, 1, argList{Yml, Yrl}},
+	{Zr_m, 1, argList{Yrl, Yml}},
 }
 
 var yshb = []ytab{
-	{Yi1, Ynone, Ymb, Zo_m, 2},
-	{Yi32, Ynone, Ymb, Zibo_m, 2},
-	{Ycx, Ynone, Ymb, Zo_m, 2},
+	{Zo_m, 2, argList{Yi1, Ymb}},
+	{Zibo_m, 2, argList{Yu8, Ymb}},
+	{Zo_m, 2, argList{Ycx, Ymb}},
 }
 
 var yshl = []ytab{
-	{Yi1, Ynone, Yml, Zo_m, 2},
-	{Yi32, Ynone, Yml, Zibo_m, 2},
-	{Ycl, Ynone, Yml, Zo_m, 2},
-	{Ycx, Ynone, Yml, Zo_m, 2},
+	{Zo_m, 2, argList{Yi1, Yml}},
+	{Zibo_m, 2, argList{Yu8, Yml}},
+	{Zo_m, 2, argList{Ycl, Yml}},
+	{Zo_m, 2, argList{Ycx, Yml}},
 }
 
 var ytestl = []ytab{
-	{Yi32, Ynone, Yax, Zil_, 1},
-	{Yi32, Ynone, Yml, Zilo_m, 2},
-	{Yrl, Ynone, Yml, Zr_m, 1},
-	{Yml, Ynone, Yrl, Zm_r, 1},
+	{Zil_, 1, argList{Yi32, Yax}},
+	{Zilo_m, 2, argList{Yi32, Yml}},
+	{Zr_m, 1, argList{Yrl, Yml}},
+	{Zm_r, 1, argList{Yml, Yrl}},
 }
 
 var ymovb = []ytab{
-	{Yrb, Ynone, Ymb, Zr_m, 1},
-	{Ymb, Ynone, Yrb, Zm_r, 1},
-	{Yi32, Ynone, Yrb, Zib_rp, 1},
-	{Yi32, Ynone, Ymb, Zibo_m, 2},
+	{Zr_m, 1, argList{Yrb, Ymb}},
+	{Zm_r, 1, argList{Ymb, Yrb}},
+	{Zib_rp, 1, argList{Yi32, Yrb}},
+	{Zibo_m, 2, argList{Yi32, Ymb}},
 }
 
 var ybtl = []ytab{
-	{Yi8, Ynone, Yml, Zibo_m, 2},
-	{Yrl, Ynone, Yml, Zr_m, 1},
+	{Zibo_m, 2, argList{Yi8, Yml}},
+	{Zr_m, 1, argList{Yrl, Yml}},
 }
 
 var ymovw = []ytab{
-	{Yrl, Ynone, Yml, Zr_m, 1},
-	{Yml, Ynone, Yrl, Zm_r, 1},
-	{Yi0, Ynone, Yrl, Zclr, 1},
-	{Yi32, Ynone, Yrl, Zil_rp, 1},
-	{Yi32, Ynone, Yml, Zilo_m, 2},
-	{Yiauto, Ynone, Yrl, Zaut_r, 2},
+	{Zr_m, 1, argList{Yrl, Yml}},
+	{Zm_r, 1, argList{Yml, Yrl}},
+	{Zil_rp, 1, argList{Yi32, Yrl}},
+	{Zilo_m, 2, argList{Yi32, Yml}},
+	{Zaut_r, 2, argList{Yiauto, Yrl}},
 }
 
 var ymovl = []ytab{
-	{Yrl, Ynone, Yml, Zr_m, 1},
-	{Yml, Ynone, Yrl, Zm_r, 1},
-	{Yi0, Ynone, Yrl, Zclr, 1},
-	{Yi32, Ynone, Yrl, Zil_rp, 1},
-	{Yi32, Ynone, Yml, Zilo_m, 2},
-	{Yml, Ynone, Ymr, Zm_r_xm, 1}, // MMX MOVD
-	{Ymr, Ynone, Yml, Zr_m_xm, 1}, // MMX MOVD
-	{Yml, Ynone, Yxr, Zm_r_xm, 2}, // XMM MOVD (32 bit)
-	{Yxr, Ynone, Yml, Zr_m_xm, 2}, // XMM MOVD (32 bit)
-	{Yiauto, Ynone, Yrl, Zaut_r, 2},
+	{Zr_m, 1, argList{Yrl, Yml}},
+	{Zm_r, 1, argList{Yml, Yrl}},
+	{Zil_rp, 1, argList{Yi32, Yrl}},
+	{Zilo_m, 2, argList{Yi32, Yml}},
+	{Zm_r_xm, 1, argList{Yml, Ymr}}, // MMX MOVD
+	{Zr_m_xm, 1, argList{Ymr, Yml}}, // MMX MOVD
+	{Zm_r_xm, 2, argList{Yml, Yxr}}, // XMM MOVD (32 bit)
+	{Zr_m_xm, 2, argList{Yxr, Yml}}, // XMM MOVD (32 bit)
+	{Zaut_r, 2, argList{Yiauto, Yrl}},
 }
 
 var yret = []ytab{
-	{Ynone, Ynone, Ynone, Zo_iw, 1},
-	{Yi32, Ynone, Ynone, Zo_iw, 1},
+	{Zo_iw, 1, argList{}},
+	{Zo_iw, 1, argList{Yi32}},
 }
 
 var ymovq = []ytab{
 	// valid in 32-bit mode
-	{Ym, Ynone, Ymr, Zm_r_xm_nr, 1},  // 0x6f MMX MOVQ (shorter encoding)
-	{Ymr, Ynone, Ym, Zr_m_xm_nr, 1},  // 0x7f MMX MOVQ
-	{Yxr, Ynone, Ymr, Zm_r_xm_nr, 2}, // Pf2, 0xd6 MOVDQ2Q
-	{Yxm, Ynone, Yxr, Zm_r_xm_nr, 2}, // Pf3, 0x7e MOVQ xmm1/m64 -> xmm2
-	{Yxr, Ynone, Yxm, Zr_m_xm_nr, 2}, // Pe, 0xd6 MOVQ xmm1 -> xmm2/m64
+	{Zm_r_xm_nr, 1, argList{Ym, Ymr}},  // 0x6f MMX MOVQ (shorter encoding)
+	{Zr_m_xm_nr, 1, argList{Ymr, Ym}},  // 0x7f MMX MOVQ
+	{Zm_r_xm_nr, 2, argList{Yxr, Ymr}}, // Pf2, 0xd6 MOVDQ2Q
+	{Zm_r_xm_nr, 2, argList{Yxm, Yxr}}, // Pf3, 0x7e MOVQ xmm1/m64 -> xmm2
+	{Zr_m_xm_nr, 2, argList{Yxr, Yxm}}, // Pe, 0xd6 MOVQ xmm1 -> xmm2/m64
 
 	// valid only in 64-bit mode, usually with 64-bit prefix
-	{Yrl, Ynone, Yml, Zr_m, 1},      // 0x89
-	{Yml, Ynone, Yrl, Zm_r, 1},      // 0x8b
-	{Yi0, Ynone, Yrl, Zclr, 1},      // 0x31
-	{Ys32, Ynone, Yrl, Zilo_m, 2},   // 32 bit signed 0xc7,(0)
-	{Yi64, Ynone, Yrl, Ziq_rp, 1},   // 0xb8 -- 32/64 bit immediate
-	{Yi32, Ynone, Yml, Zilo_m, 2},   // 0xc7,(0)
-	{Ymm, Ynone, Ymr, Zm_r_xm, 1},   // 0x6e MMX MOVD
-	{Ymr, Ynone, Ymm, Zr_m_xm, 1},   // 0x7e MMX MOVD
-	{Yml, Ynone, Yxr, Zm_r_xm, 2},   // Pe, 0x6e MOVD xmm load
-	{Yxr, Ynone, Yml, Zr_m_xm, 2},   // Pe, 0x7e MOVD xmm store
-	{Yiauto, Ynone, Yrl, Zaut_r, 1}, // 0 built-in LEAQ
+	{Zr_m, 1, argList{Yrl, Yml}},      // 0x89
+	{Zm_r, 1, argList{Yml, Yrl}},      // 0x8b
+	{Zilo_m, 2, argList{Ys32, Yrl}},   // 32 bit signed 0xc7,(0)
+	{Ziq_rp, 1, argList{Yi64, Yrl}},   // 0xb8 -- 32/64 bit immediate
+	{Zilo_m, 2, argList{Yi32, Yml}},   // 0xc7,(0)
+	{Zm_r_xm, 1, argList{Ymm, Ymr}},   // 0x6e MMX MOVD
+	{Zr_m_xm, 1, argList{Ymr, Ymm}},   // 0x7e MMX MOVD
+	{Zm_r_xm, 2, argList{Yml, Yxr}},   // Pe, 0x6e MOVD xmm load
+	{Zr_m_xm, 2, argList{Yxr, Yml}},   // Pe, 0x7e MOVD xmm store
+	{Zaut_r, 1, argList{Yiauto, Yrl}}, // 0 built-in LEAQ
 }
 
 var ym_rl = []ytab{
-	{Ym, Ynone, Yrl, Zm_r, 1},
+	{Zm_r, 1, argList{Ym, Yrl}},
 }
 
 var yrl_m = []ytab{
-	{Yrl, Ynone, Ym, Zr_m, 1},
+	{Zr_m, 1, argList{Yrl, Ym}},
 }
 
 var ymb_rl = []ytab{
-	{Ymb, Ynone, Yrl, Zmb_r, 1},
+	{Zmb_r, 1, argList{Ymb, Yrl}},
 }
 
 var yml_rl = []ytab{
-	{Yml, Ynone, Yrl, Zm_r, 1},
+	{Zm_r, 1, argList{Yml, Yrl}},
 }
 
 var yrl_ml = []ytab{
-	{Yrl, Ynone, Yml, Zr_m, 1},
+	{Zr_m, 1, argList{Yrl, Yml}},
 }
 
 var yml_mb = []ytab{
-	{Yrb, Ynone, Ymb, Zr_m, 1},
-	{Ymb, Ynone, Yrb, Zm_r, 1},
+	{Zr_m, 1, argList{Yrb, Ymb}},
+	{Zm_r, 1, argList{Ymb, Yrb}},
 }
 
 var yrb_mb = []ytab{
-	{Yrb, Ynone, Ymb, Zr_m, 1},
+	{Zr_m, 1, argList{Yrb, Ymb}},
 }
 
 var yxchg = []ytab{
-	{Yax, Ynone, Yrl, Z_rp, 1},
-	{Yrl, Ynone, Yax, Zrp_, 1},
-	{Yrl, Ynone, Yml, Zr_m, 1},
-	{Yml, Ynone, Yrl, Zm_r, 1},
+	{Z_rp, 1, argList{Yax, Yrl}},
+	{Zrp_, 1, argList{Yrl, Yax}},
+	{Zr_m, 1, argList{Yrl, Yml}},
+	{Zm_r, 1, argList{Yml, Yrl}},
 }
 
 var ydivl = []ytab{
-	{Yml, Ynone, Ynone, Zm_o, 2},
+	{Zm_o, 2, argList{Yml}},
 }
 
 var ydivb = []ytab{
-	{Ymb, Ynone, Ynone, Zm_o, 2},
+	{Zm_o, 2, argList{Ymb}},
 }
 
 var yimul = []ytab{
-	{Yml, Ynone, Ynone, Zm_o, 2},
-	{Yi8, Ynone, Yrl, Zib_rr, 1},
-	{Yi32, Ynone, Yrl, Zil_rr, 1},
-	{Yml, Ynone, Yrl, Zm_r, 2},
+	{Zm_o, 2, argList{Yml}},
+	{Zib_rr, 1, argList{Yi8, Yrl}},
+	{Zil_rr, 1, argList{Yi32, Yrl}},
+	{Zm_r, 2, argList{Yml, Yrl}},
 }
 
 var yimul3 = []ytab{
-	{Yi8, Yml, Yrl, Zibm_r, 2},
+	{Zibm_r, 2, argList{Yi8, Yml, Yrl}},
 }
 
 var ybyte = []ytab{
-	{Yi64, Ynone, Ynone, Zbyte, 1},
+	{Zbyte, 1, argList{Yi64}},
 }
 
 var yin = []ytab{
-	{Yi32, Ynone, Ynone, Zib_, 1},
-	{Ynone, Ynone, Ynone, Zlit, 1},
+	{Zib_, 1, argList{Yi32}},
+	{Zlit, 1, argList{}},
 }
 
 var yint = []ytab{
-	{Yi32, Ynone, Ynone, Zib_, 1},
+	{Zib_, 1, argList{Yi32}},
 }
 
 var ypushl = []ytab{
-	{Yrl, Ynone, Ynone, Zrp_, 1},
-	{Ym, Ynone, Ynone, Zm_o, 2},
-	{Yi8, Ynone, Ynone, Zib_, 1},
-	{Yi32, Ynone, Ynone, Zil_, 1},
+	{Zrp_, 1, argList{Yrl}},
+	{Zm_o, 2, argList{Ym}},
+	{Zib_, 1, argList{Yi8}},
+	{Zil_, 1, argList{Yi32}},
 }
 
 var ypopl = []ytab{
-	{Ynone, Ynone, Yrl, Z_rp, 1},
-	{Ynone, Ynone, Ym, Zo_m, 2},
+	{Z_rp, 1, argList{Yrl}},
+	{Zo_m, 2, argList{Ym}},
+}
+
+var yclflush = []ytab{
+	{Zo_m, 2, argList{Ym}},
 }
 
 var ybswap = []ytab{
-	{Ynone, Ynone, Yrl, Z_rp, 2},
+	{Z_rp, 2, argList{Yrl}},
 }
 
 var yscond = []ytab{
-	{Ynone, Ynone, Ymb, Zo_m, 2},
+	{Zo_m, 2, argList{Ymb}},
 }
 
 var yjcond = []ytab{
-	{Ynone, Ynone, Ybr, Zbr, 0},
-	{Yi0, Ynone, Ybr, Zbr, 0},
-	{Yi1, Ynone, Ybr, Zbr, 1},
+	{Zbr, 0, argList{Ybr}},
+	{Zbr, 0, argList{Yi0, Ybr}},
+	{Zbr, 1, argList{Yi1, Ybr}},
 }
 
 var yloop = []ytab{
-	{Ynone, Ynone, Ybr, Zloop, 1},
+	{Zloop, 1, argList{Ybr}},
 }
 
 var ycall = []ytab{
-	{Ynone, Ynone, Yml, Zcallindreg, 0},
-	{Yrx, Ynone, Yrx, Zcallindreg, 2},
-	{Ynone, Ynone, Yindir, Zcallind, 2},
-	{Ynone, Ynone, Ybr, Zcall, 0},
-	{Ynone, Ynone, Yi32, Zcallcon, 1},
+	{Zcallindreg, 0, argList{Yml}},
+	{Zcallindreg, 2, argList{Yrx, Yrx}},
+	{Zcallind, 2, argList{Yindir}},
+	{Zcall, 0, argList{Ybr}},
+	{Zcallcon, 1, argList{Yi32}},
 }
 
 var yduff = []ytab{
-	{Ynone, Ynone, Yi32, Zcallduff, 1},
+	{Zcallduff, 1, argList{Yi32}},
 }
 
 var yjmp = []ytab{
-	{Ynone, Ynone, Yml, Zo_m64, 2},
-	{Ynone, Ynone, Ybr, Zjmp, 0},
-	{Ynone, Ynone, Yi32, Zjmpcon, 1},
+	{Zo_m64, 2, argList{Yml}},
+	{Zjmp, 0, argList{Ybr}},
+	{Zjmpcon, 1, argList{Yi32}},
 }
 
 var yfmvd = []ytab{
-	{Ym, Ynone, Yf0, Zm_o, 2},
-	{Yf0, Ynone, Ym, Zo_m, 2},
-	{Yrf, Ynone, Yf0, Zm_o, 2},
-	{Yf0, Ynone, Yrf, Zo_m, 2},
+	{Zm_o, 2, argList{Ym, Yf0}},
+	{Zo_m, 2, argList{Yf0, Ym}},
+	{Zm_o, 2, argList{Yrf, Yf0}},
+	{Zo_m, 2, argList{Yf0, Yrf}},
 }
 
 var yfmvdp = []ytab{
-	{Yf0, Ynone, Ym, Zo_m, 2},
-	{Yf0, Ynone, Yrf, Zo_m, 2},
+	{Zo_m, 2, argList{Yf0, Ym}},
+	{Zo_m, 2, argList{Yf0, Yrf}},
 }
 
 var yfmvf = []ytab{
-	{Ym, Ynone, Yf0, Zm_o, 2},
-	{Yf0, Ynone, Ym, Zo_m, 2},
+	{Zm_o, 2, argList{Ym, Yf0}},
+	{Zo_m, 2, argList{Yf0, Ym}},
 }
 
 var yfmvx = []ytab{
-	{Ym, Ynone, Yf0, Zm_o, 2},
+	{Zm_o, 2, argList{Ym, Yf0}},
 }
 
 var yfmvp = []ytab{
-	{Yf0, Ynone, Ym, Zo_m, 2},
+	{Zo_m, 2, argList{Yf0, Ym}},
 }
 
 var yfcmv = []ytab{
-	{Yrf, Ynone, Yf0, Zm_o, 2},
+	{Zm_o, 2, argList{Yrf, Yf0}},
 }
 
 var yfadd = []ytab{
-	{Ym, Ynone, Yf0, Zm_o, 2},
-	{Yrf, Ynone, Yf0, Zm_o, 2},
-	{Yf0, Ynone, Yrf, Zo_m, 2},
+	{Zm_o, 2, argList{Ym, Yf0}},
+	{Zm_o, 2, argList{Yrf, Yf0}},
+	{Zo_m, 2, argList{Yf0, Yrf}},
 }
 
 var yfxch = []ytab{
-	{Yf0, Ynone, Yrf, Zo_m, 2},
-	{Yrf, Ynone, Yf0, Zm_o, 2},
+	{Zo_m, 2, argList{Yf0, Yrf}},
+	{Zm_o, 2, argList{Yrf, Yf0}},
 }
 
 var ycompp = []ytab{
-	{Yf0, Ynone, Yrf, Zo_m, 2}, /* botch is really f0,f1 */
+	{Zo_m, 2, argList{Yf0, Yrf}}, /* botch is really f0,f1 */
 }
 
 var ystsw = []ytab{
-	{Ynone, Ynone, Ym, Zo_m, 2},
-	{Ynone, Ynone, Yax, Zlit, 1},
+	{Zo_m, 2, argList{Ym}},
+	{Zlit, 1, argList{Yax}},
 }
 
-var ysvrs = []ytab{
-	{Ynone, Ynone, Ym, Zo_m, 2},
-	{Ym, Ynone, Ynone, Zm_o, 2},
+var ysvrs_mo = []ytab{
+	{Zm_o, 2, argList{Ym}},
+}
+
+// unaryDst version of "ysvrs_mo".
+var ysvrs_om = []ytab{
+	{Zo_m, 2, argList{Ym}},
 }
 
 var ymm = []ytab{
-	{Ymm, Ynone, Ymr, Zm_r_xm, 1},
-	{Yxm, Ynone, Yxr, Zm_r_xm, 2},
+	{Zm_r_xm, 1, argList{Ymm, Ymr}},
+	{Zm_r_xm, 2, argList{Yxm, Yxr}},
 }
 
 var yxm = []ytab{
-	{Yxm, Ynone, Yxr, Zm_r_xm, 1},
+	{Zm_r_xm, 1, argList{Yxm, Yxr}},
 }
 
 var yxm_q4 = []ytab{
-	{Yxm, Ynone, Yxr, Zm_r, 1},
+	{Zm_r, 1, argList{Yxm, Yxr}},
 }
 
 var yxcvm1 = []ytab{
-	{Yxm, Ynone, Yxr, Zm_r_xm, 2},
-	{Yxm, Ynone, Ymr, Zm_r_xm, 2},
+	{Zm_r_xm, 2, argList{Yxm, Yxr}},
+	{Zm_r_xm, 2, argList{Yxm, Ymr}},
 }
 
 var yxcvm2 = []ytab{
-	{Yxm, Ynone, Yxr, Zm_r_xm, 2},
-	{Ymm, Ynone, Yxr, Zm_r_xm, 2},
+	{Zm_r_xm, 2, argList{Yxm, Yxr}},
+	{Zm_r_xm, 2, argList{Ymm, Yxr}},
 }
 
 var yxr = []ytab{
-	{Yxr, Ynone, Yxr, Zm_r_xm, 1},
+	{Zm_r_xm, 1, argList{Yxr, Yxr}},
 }
 
 var yxr_ml = []ytab{
-	{Yxr, Ynone, Yml, Zr_m_xm, 1},
+	{Zr_m_xm, 1, argList{Yxr, Yml}},
 }
 
 var ymr = []ytab{
-	{Ymr, Ynone, Ymr, Zm_r, 1},
+	{Zm_r, 1, argList{Ymr, Ymr}},
 }
 
 var ymr_ml = []ytab{
-	{Ymr, Ynone, Yml, Zr_m_xm, 1},
+	{Zr_m_xm, 1, argList{Ymr, Yml}},
 }
 
 var yxcmpi = []ytab{
-	{Yxm, Yxr, Yi8, Zm_r_i_xm, 2},
+	{Zm_r_i_xm, 2, argList{Yxm, Yxr, Yi8}},
 }
 
 var yxmov = []ytab{
-	{Yxm, Ynone, Yxr, Zm_r_xm, 1},
-	{Yxr, Ynone, Yxm, Zr_m_xm, 1},
+	{Zm_r_xm, 1, argList{Yxm, Yxr}},
+	{Zr_m_xm, 1, argList{Yxr, Yxm}},
 }
 
 var yxcvfl = []ytab{
-	{Yxm, Ynone, Yrl, Zm_r_xm, 1},
+	{Zm_r_xm, 1, argList{Yxm, Yrl}},
 }
 
 var yxcvlf = []ytab{
-	{Yml, Ynone, Yxr, Zm_r_xm, 1},
+	{Zm_r_xm, 1, argList{Yml, Yxr}},
 }
 
 var yxcvfq = []ytab{
-	{Yxm, Ynone, Yrl, Zm_r_xm, 2},
+	{Zm_r_xm, 2, argList{Yxm, Yrl}},
 }
 
 var yxcvqf = []ytab{
-	{Yml, Ynone, Yxr, Zm_r_xm, 2},
+	{Zm_r_xm, 2, argList{Yml, Yxr}},
 }
 
 var yps = []ytab{
-	{Ymm, Ynone, Ymr, Zm_r_xm, 1},
-	{Yi8, Ynone, Ymr, Zibo_m_xm, 2},
-	{Yxm, Ynone, Yxr, Zm_r_xm, 2},
-	{Yi8, Ynone, Yxr, Zibo_m_xm, 3},
+	{Zm_r_xm, 1, argList{Ymm, Ymr}},
+	{Zibo_m_xm, 2, argList{Yi8, Ymr}},
+	{Zm_r_xm, 2, argList{Yxm, Yxr}},
+	{Zibo_m_xm, 3, argList{Yi8, Yxr}},
 }
 
 var yxrrl = []ytab{
-	{Yxr, Ynone, Yrl, Zm_r, 1},
+	{Zm_r, 1, argList{Yxr, Yrl}},
 }
 
 var ymrxr = []ytab{
-	{Ymr, Ynone, Yxr, Zm_r, 1},
-	{Yxm, Ynone, Yxr, Zm_r_xm, 1},
+	{Zm_r, 1, argList{Ymr, Yxr}},
+	{Zm_r_xm, 1, argList{Yxm, Yxr}},
 }
 
 var ymshuf = []ytab{
-	{Yi8, Ymm, Ymr, Zibm_r, 2},
+	{Zibm_r, 2, argList{Yi8, Ymm, Ymr}},
 }
 
 var ymshufb = []ytab{
-	{Yxm, Ynone, Yxr, Zm2_r, 2},
+	{Zm2_r, 2, argList{Yxm, Yxr}},
 }
 
+// It should never have more than 1 entry,
+// because some optab entries you opcode secuences that
+// are longer than 2 bytes (zoffset=2 here),
+// ROUNDPD and ROUNDPS and recently added BLENDPD,
+// to name a few.
 var yxshuf = []ytab{
-	{Yu8, Yxm, Yxr, Zibm_r, 2},
+	{Zibm_r, 2, argList{Yu8, Yxm, Yxr}},
 }
 
 var yextrw = []ytab{
-	{Yu8, Yxr, Yrl, Zibm_r, 2},
+	{Zibm_r, 2, argList{Yu8, Yxr, Yrl}},
 }
 
 var yextr = []ytab{
-	{Yu8, Yxr, Ymm, Zibr_m, 3},
+	{Zibr_m, 3, argList{Yu8, Yxr, Ymm}},
 }
 
 var yinsrw = []ytab{
-	{Yu8, Yml, Yxr, Zibm_r, 2},
+	{Zibm_r, 2, argList{Yu8, Yml, Yxr}},
 }
 
 var yinsr = []ytab{
-	{Yu8, Ymm, Yxr, Zibm_r, 3},
+	{Zibm_r, 3, argList{Yu8, Ymm, Yxr}},
 }
 
 var ypsdq = []ytab{
-	{Yi8, Ynone, Yxr, Zibo_m, 2},
+	{Zibo_m, 2, argList{Yi8, Yxr}},
 }
 
 var ymskb = []ytab{
-	{Yxr, Ynone, Yrl, Zm_r_xm, 2},
-	{Ymr, Ynone, Yrl, Zm_r_xm, 1},
+	{Zm_r_xm, 2, argList{Yxr, Yrl}},
+	{Zm_r_xm, 1, argList{Ymr, Yrl}},
 }
 
 var ycrc32l = []ytab{
-	{Yml, Ynone, Yrl, Zlitm_r, 0},
+	{Zlitm_r, 0, argList{Yml, Yrl}},
 }
 
 var yprefetch = []ytab{
-	{Ym, Ynone, Ynone, Zm_o, 2},
+	{Zm_o, 2, argList{Ym}},
 }
 
 var yaes = []ytab{
-	{Yxm, Ynone, Yxr, Zlitm_r, 2},
+	{Zlitm_r, 2, argList{Yxm, Yxr}},
 }
 
 var yxbegin = []ytab{
-	{Ynone, Ynone, Ybr, Zjmp, 1},
+	{Zjmp, 1, argList{Ybr}},
 }
 
 var yxabort = []ytab{
-	{Yu8, Ynone, Ynone, Zib_, 1},
+	{Zib_, 1, argList{Yu8}},
 }
 
 var ylddqu = []ytab{
-	{Ym, Ynone, Yxr, Zm_r, 1},
+	{Zm_r, 1, argList{Ym, Yxr}},
+}
+
+var ypalignr = []ytab{
+	{Zibm_r, 2, argList{Yu8, Yxm, Yxr}},
 }
 
 // VEX instructions that come in two forms:
@@ -796,89 +807,257 @@
 //	VPXOR ymm2/m256, ymmV, ymm1
 //	VEX.NDS.256.66.0F.WIG EF /r
 //
-// The NDS/NDD/DDS part can be dropped, producing this
-// Optab entry:
+// Produce this Optab entry:
 //
-//	{AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}}
+//	{AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_NDS_128_66_0F_WIG, 0xEF, VEX_NDS_256_66_0F_WIG, 0xEF}}
 //
 var yvex_xy3 = []ytab{
-	{Yxm, Yxr, Yxr, Zvex_rm_v_r, 2},
-	{Yym, Yyr, Yyr, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yym, Yyr, Yyr}},
+}
+
+var yvex_x3 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr, Yxr}},
 }
 
 var yvex_ri3 = []ytab{
-	{Yi8, Ymb, Yrl, Zvex_i_rm_r, 2},
+	{Zvex_i_rm_r, 2, argList{Yi8, Ymb, Yrl}},
 }
 
 var yvex_xyi3 = []ytab{
-	{Yu8, Yxm, Yxr, Zvex_i_rm_r, 2},
-	{Yu8, Yym, Yyr, Zvex_i_rm_r, 2},
-	{Yi8, Yxm, Yxr, Zvex_i_rm_r, 2},
-	{Yi8, Yym, Yyr, Zvex_i_rm_r, 2},
+	{Zvex_i_rm_r, 2, argList{Yu8, Yxm, Yxr}},
+	{Zvex_i_rm_r, 2, argList{Yu8, Yym, Yyr}},
+	{Zvex_i_rm_r, 2, argList{Yi8, Yxm, Yxr}},
+	{Zvex_i_rm_r, 2, argList{Yi8, Yym, Yyr}},
 }
 
-var yvex_yyi4 = []ytab{ //TODO don't hide 4 op, some version have xmm version
-	{Yym, Yyr, Yyr, Zvex_i_rm_v_r, 2},
+var yvex_yyi4 = []ytab{
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yym, Yyr, Yyr}},
 }
 
 var yvex_xyi4 = []ytab{
-	{Yxm, Yyr, Yyr, Zvex_i_rm_v_r, 2},
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yxm, Yyr, Yyr}},
 }
 
 var yvex_shift = []ytab{
-	{Yi8, Yxr, Yxr, Zvex_i_r_v, 3},
-	{Yi8, Yyr, Yyr, Zvex_i_r_v, 3},
-	{Yxm, Yxr, Yxr, Zvex_rm_v_r, 2},
-	{Yxm, Yyr, Yyr, Zvex_rm_v_r, 2},
+	{Zvex_i_r_v, 3, argList{Yi8, Yxr, Yxr}},
+	{Zvex_i_r_v, 3, argList{Yi8, Yyr, Yyr}},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yyr, Yyr}},
 }
 
 var yvex_shift_dq = []ytab{
-	{Yi8, Yxr, Yxr, Zvex_i_r_v, 3},
-	{Yi8, Yyr, Yyr, Zvex_i_r_v, 3},
+	{Zvex_i_r_v, 3, argList{Yi8, Yxr, Yxr}},
+	{Zvex_i_r_v, 3, argList{Yi8, Yyr, Yyr}},
 }
 
 var yvex_r3 = []ytab{
-	{Yml, Yrl, Yrl, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yml, Yrl, Yrl}},
 }
 
 var yvex_vmr3 = []ytab{
-	{Yrl, Yml, Yrl, Zvex_v_rm_r, 2},
+	{Zvex_v_rm_r, 2, argList{Yrl, Yml, Yrl}},
 }
 
 var yvex_xy2 = []ytab{
-	{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
-	{Yym, Ynone, Yyr, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yym, Yyr}},
 }
 
 var yvex_xyr2 = []ytab{
-	{Yxr, Ynone, Yrl, Zvex_rm_v_r, 2},
-	{Yyr, Ynone, Yrl, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yrl}},
+	{Zvex_rm_v_r, 2, argList{Yyr, Yrl}},
 }
 
 var yvex_vmovdqa = []ytab{
-	{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
-	{Yxr, Ynone, Yxm, Zvex_r_v_rm, 2},
-	{Yym, Ynone, Yyr, Zvex_rm_v_r, 2},
-	{Yyr, Ynone, Yym, Zvex_r_v_rm, 2},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr}},
+	{Zvex_r_v_rm, 2, argList{Yxr, Yxm}},
+	{Zvex_rm_v_r, 2, argList{Yym, Yyr}},
+	{Zvex_r_v_rm, 2, argList{Yyr, Yym}},
 }
 
 var yvex_vmovntdq = []ytab{
-	{Yxr, Ynone, Ym, Zvex_r_v_rm, 2},
-	{Yyr, Ynone, Ym, Zvex_r_v_rm, 2},
+	{Zvex_r_v_rm, 2, argList{Yxr, Ym}},
+	{Zvex_r_v_rm, 2, argList{Yyr, Ym}},
 }
 
 var yvex_vpbroadcast = []ytab{
-	{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
-	{Yxm, Ynone, Yyr, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yyr}},
 }
 
 var yvex_vpbroadcast_sd = []ytab{
-	{Yxm, Ynone, Yyr, Zvex_rm_v_r, 2},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yyr}},
+}
+
+var yvex_vpextrw = []ytab{
+	{Zvex_i_rm_r, 2, argList{Yi8, Yxr, Yrl}},
+	{Zvex_i_r_rm, 2, argList{Yi8, Yxr, Yml}},
+}
+
+var yvex_m = []ytab{
+	{Zvex_rm_v_ro, 3, argList{Ym}},
+}
+
+var yvex_xx3 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr, Yxr}},
+}
+
+var yvex_yi3 = []ytab{
+	{Zvex_i_r_rm, 2, argList{Yi8, Yyr, Yxm}},
+}
+
+var yvex_mxy = []ytab{
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yyr}},
+}
+
+var yvex_yy3 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yym, Yyr, Yyr}},
+}
+
+var yvex_xi3 = []ytab{
+	{Zvex_i_rm_r, 2, argList{Yi8, Yxm, Yxr}},
+}
+
+var yvex_vpermpd = []ytab{
+	{Zvex_i_rm_r, 2, argList{Yi8, Yym, Yyr}},
+}
+
+var yvex_vpermilp = []ytab{
+	{Zvex_i_rm_r, 2, argList{Yi8, Yxm, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr, Yxr}},
+	{Zvex_i_rm_r, 2, argList{Yi8, Yym, Yyr}},
+	{Zvex_rm_v_r, 2, argList{Yym, Yyr, Yyr}},
+}
+
+var yvex_vcvtps2ph = []ytab{
+	{Zvex_i_r_rm, 2, argList{Yi8, Yyr, Yxm}},
+	{Zvex_i_r_rm, 2, argList{Yi8, Yxr, Yxm}},
+}
+
+var yvex_vbroadcastf = []ytab{
+	{Zvex_rm_v_r, 2, argList{Ym, Yyr}},
+}
+
+var yvex_vmovd = []ytab{
+	{Zvex_r_v_rm, 2, argList{Yxr, Yml}},
+	{Zvex_rm_v_r, 2, argList{Yml, Yxr}},
+}
+
+var yvex_x2 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr}},
+}
+
+var yvex_y2 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yym, Yxr}},
+}
+
+var yvex = []ytab{
+	{Zvex, 2, argList{}},
+}
+
+var yvex_xx2 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr}},
+}
+
+var yvex_vpalignr = []ytab{
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yxm, Yxr, Yxr}},
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yym, Yyr, Yyr}},
+}
+
+var yvex_rxi4 = []ytab{
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yml, Yxr, Yxr}},
+}
+
+var yvex_xxi4 = []ytab{
+	{Zvex_i_rm_v_r, 2, argList{Yu8, Yxm, Yxr, Yxr}},
+}
+
+var yvex_xy4 = []ytab{
+	{Zvex_hr_rm_v_r, 2, argList{Yxr, Yxm, Yxr, Yxr}},
+	{Zvex_hr_rm_v_r, 2, argList{Yyr, Yym, Yyr, Yyr}},
+}
+
+var yvex_vpbroadcast_ss = []ytab{
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yyr}},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yyr}},
+}
+
+var yvex_vblendvpd = []ytab{
+	{Zvex_r_v_rm, 2, argList{Yxr, Yxr, Yml}},
+	{Zvex_r_v_rm, 2, argList{Yyr, Yyr, Yml}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yyr, Yyr}},
+}
+
+var yvex_vmov = []ytab{
+	{Zvex_r_v_rm, 2, argList{Yxr, Ym}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr, Yxr}},
+}
+
+var yvex_vps = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxm, Yxr, Yxr}},
+	{Zvex_i_r_v, 3, argList{Yi8, Yxr, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxm, Yyr, Yyr}},
+	{Zvex_i_r_v, 3, argList{Yi8, Yyr, Yyr}},
+}
+
+var yvex_r2 = []ytab{
+	{Zvex_rm_r_vo, 3, argList{Yml, Yrl}},
+}
+
+var yvex_vpextr = []ytab{
+	{Zvex_i_r_rm, 2, argList{Yi8, Yxr, Yml}},
+}
+
+var yvex_rx3 = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yml, Yxr, Yxr}},
+}
+
+var yvex_vcvtsd2si = []ytab{
+	{Zvex_rm_v_r, 2, argList{Yxm, Yrl}},
+}
+
+var yvex_vmovhpd = []ytab{
+	{Zvex_r_v_rm, 2, argList{Yxr, Ym}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr, Yxr}},
+}
+
+var yvex_vmovq = []ytab{
+	{Zvex_r_v_rm, 2, argList{Yxr, Yml}},
+	{Zvex_rm_v_r, 2, argList{Ym, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yml, Yxr}},
+	{Zvex_rm_v_r, 2, argList{Yxr, Yxr}},
+	{Zvex_r_v_rm, 2, argList{Yxr, Yxm}},
+}
+
+var yvpgatherdq = []ytab{
+	{Zvex_v_rm_r, 2, argList{Yxr, Yxvm, Yxr}},
+	{Zvex_v_rm_r, 2, argList{Yyr, Yxvm, Yyr}},
+}
+
+var yvpgatherqq = []ytab{
+	{Zvex_v_rm_r, 2, argList{Yxr, Yxvm, Yxr}},
+	{Zvex_v_rm_r, 2, argList{Yyr, Yyvm, Yyr}},
+}
+
+var yvgatherqps = []ytab{
+	{Zvex_v_rm_r, 2, argList{Yxr, Yxvm, Yxr}},
+	{Zvex_v_rm_r, 2, argList{Yxr, Yyvm, Yxr}},
 }
 
 var ymmxmm0f38 = []ytab{
-	{Ymm, Ynone, Ymr, Zlitm_r, 3},
-	{Yxm, Ynone, Yxr, Zlitm_r, 5},
+	{Zlitm_r, 3, argList{Ymm, Ymr}},
+	{Zlitm_r, 5, argList{Yxm, Yxr}},
+}
+
+var yextractps = []ytab{
+	{Zibr_m, 2, argList{Yu2, Yxr, Yml}},
 }
 
 /*
@@ -949,6 +1128,8 @@
 	{AADCL, yaddl, Px, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
 	{AADCQ, yaddl, Pw, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
 	{AADCW, yaddl, Pe, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
+	{AADCXL, yml_rl, Pq4, [23]uint8{0xf6}},
+	{AADCXQ, yml_rl, Pq4w, [23]uint8{0xf6}},
 	{AADDB, yxorb, Pb, [23]uint8{0x04, 0x80, 00, 0x00, 0x02}},
 	{AADDL, yaddl, Px, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
 	{AADDPD, yxm, Pq, [23]uint8{0x58}},
@@ -956,7 +1137,11 @@
 	{AADDQ, yaddl, Pw, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
 	{AADDSD, yxm, Pf2, [23]uint8{0x58}},
 	{AADDSS, yxm, Pf3, [23]uint8{0x58}},
+	{AADDSUBPD, yxm, Pq, [23]uint8{0xd0}},
+	{AADDSUBPS, yxm, Pf2, [23]uint8{0xd0}},
 	{AADDW, yaddl, Pe, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
+	{AADOXL, yml_rl, Pq5, [23]uint8{0xf6}},
+	{AADOXQ, yml_rl, Pq5w, [23]uint8{0xf6}},
 	{AADJSP, nil, 0, [23]uint8{}},
 	{AANDB, yxorb, Pb, [23]uint8{0x24, 0x80, 04, 0x20, 0x22}},
 	{AANDL, yaddl, Px, [23]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}},
@@ -994,6 +1179,7 @@
 	{ACDQ, ynone, Px, [23]uint8{0x99}},
 	{ACLC, ynone, Px, [23]uint8{0xf8}},
 	{ACLD, ynone, Px, [23]uint8{0xfc}},
+	{ACLFLUSH, yclflush, Pm, [23]uint8{0xae, 07}},
 	{ACLI, ynone, Px, [23]uint8{0xfa}},
 	{ACLTS, ynone, Pm, [23]uint8{0x06}},
 	{ACMC, ynone, Px, [23]uint8{0xf5}},
@@ -1098,12 +1284,15 @@
 	{ADIVSD, yxm, Pf2, [23]uint8{0x5e}},
 	{ADIVSS, yxm, Pf3, [23]uint8{0x5e}},
 	{ADIVW, ydivl, Pe, [23]uint8{0xf7, 06}},
+	{ADPPD, yxshuf, Pq, [23]uint8{0x3a, 0x41, 0}},
+	{ADPPS, yxshuf, Pq, [23]uint8{0x3a, 0x40, 0}},
 	{AEMMS, ynone, Pm, [23]uint8{0x77}},
+	{AEXTRACTPS, yextractps, Pq, [23]uint8{0x3a, 0x17, 0}},
 	{AENTER, nil, 0, [23]uint8{}}, /* botch */
-	{AFXRSTOR, ysvrs, Pm, [23]uint8{0xae, 01, 0xae, 01}},
-	{AFXSAVE, ysvrs, Pm, [23]uint8{0xae, 00, 0xae, 00}},
-	{AFXRSTOR64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 01, 0x0f, 0xae, 01}},
-	{AFXSAVE64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 00, 0x0f, 0xae, 00}},
+	{AFXRSTOR, ysvrs_mo, Pm, [23]uint8{0xae, 01, 0xae, 01}},
+	{AFXSAVE, ysvrs_om, Pm, [23]uint8{0xae, 00, 0xae, 00}},
+	{AFXRSTOR64, ysvrs_mo, Pw, [23]uint8{0x0f, 0xae, 01, 0x0f, 0xae, 01}},
+	{AFXSAVE64, ysvrs_om, Pw, [23]uint8{0x0f, 0xae, 00, 0x0f, 0xae, 00}},
 	{AHLT, ynone, Px, [23]uint8{0xf4}},
 	{AIDIVB, ydivb, Pb, [23]uint8{0xf6, 07}},
 	{AIDIVL, ydivl, Px, [23]uint8{0xf7, 07}},
@@ -1122,6 +1311,7 @@
 	{AINL, yin, Px, [23]uint8{0xe5, 0xed}},
 	{AINSB, ynone, Pb, [23]uint8{0x6c}},
 	{AINSL, ynone, Px, [23]uint8{0x6d}},
+	{AINSERTPS, yxshuf, Pq, [23]uint8{0x3a, 0x21, 0}},
 	{AINSW, ynone, Pe, [23]uint8{0x6d}},
 	{AINT, yint, Px, [23]uint8{0xcd}},
 	{AINTO, ynone, P32, [23]uint8{0xce}},
@@ -1157,7 +1347,7 @@
 	{ALARL, yml_rl, Pm, [23]uint8{0x02}},
 	{ALARW, yml_rl, Pq, [23]uint8{0x02}},
 	{ALDDQU, ylddqu, Pf2, [23]uint8{0xf0}},
-	{ALDMXCSR, ysvrs, Pm, [23]uint8{0xae, 02, 0xae, 02}},
+	{ALDMXCSR, ysvrs_mo, Pm, [23]uint8{0xae, 02, 0xae, 02}},
 	{ALEAL, ym_rl, Px, [23]uint8{0x8d}},
 	{ALEAQ, ym_rl, Pw, [23]uint8{0x8d}},
 	{ALEAVEL, ynone, P32, [23]uint8{0xc9}},
@@ -1199,7 +1389,7 @@
 	{AMOVHLPS, yxr, Pm, [23]uint8{0x12}},
 	{AMOVHPD, yxmov, Pe, [23]uint8{0x16, 0x17}},
 	{AMOVHPS, yxmov, Pm, [23]uint8{0x16, 0x17}},
-	{AMOVL, ymovl, Px, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
+	{AMOVL, ymovl, Px, [23]uint8{0x89, 0x8b, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
 	{AMOVLHPS, yxr, Pm, [23]uint8{0x16}},
 	{AMOVLPD, yxmov, Pe, [23]uint8{0x12, 0x13}},
 	{AMOVLPS, yxmov, Pm, [23]uint8{0x12, 0x13}},
@@ -1208,10 +1398,11 @@
 	{AMOVMSKPD, yxrrl, Pq, [23]uint8{0x50}},
 	{AMOVMSKPS, yxrrl, Pm, [23]uint8{0x50}},
 	{AMOVNTO, yxr_ml, Pe, [23]uint8{0xe7}},
+	{AMOVNTDQA, ylddqu, Pq4, [23]uint8{0x2a}},
 	{AMOVNTPD, yxr_ml, Pe, [23]uint8{0x2b}},
 	{AMOVNTPS, yxr_ml, Pm, [23]uint8{0x2b}},
 	{AMOVNTQ, ymr_ml, Pm, [23]uint8{0xe7}},
-	{AMOVQ, ymovq, Pw8, [23]uint8{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0x31, 0xc7, 00, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
+	{AMOVQ, ymovq, Pw8, [23]uint8{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0xc7, 00, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
 	{AMOVQOZX, ymrxr, Pf3, [23]uint8{0xd6, 0x7e}},
 	{AMOVSB, ynone, Pb, [23]uint8{0xa4}},
 	{AMOVSD, yxmov, Pf2, [23]uint8{0x10, 0x11}},
@@ -1221,11 +1412,12 @@
 	{AMOVSW, ynone, Pe, [23]uint8{0xa5}},
 	{AMOVUPD, yxmov, Pe, [23]uint8{0x10, 0x11}},
 	{AMOVUPS, yxmov, Pm, [23]uint8{0x10, 0x11}},
-	{AMOVW, ymovw, Pe, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0}},
+	{AMOVW, ymovw, Pe, [23]uint8{0x89, 0x8b, 0xb8, 0xc7, 00, 0}},
 	{AMOVWLSX, yml_rl, Pm, [23]uint8{0xbf}},
 	{AMOVWLZX, yml_rl, Pm, [23]uint8{0xb7}},
 	{AMOVWQSX, yml_rl, Pw, [23]uint8{0x0f, 0xbf}},
 	{AMOVWQZX, yml_rl, Pw, [23]uint8{0x0f, 0xb7}},
+	{AMPSADBW, yxshuf, Pq, [23]uint8{0x3a, 0x42, 0}},
 	{AMULB, ydivb, Pb, [23]uint8{0xf6, 04}},
 	{AMULL, ydivl, Px, [23]uint8{0xf7, 04}},
 	{AMULPD, yxm, Pe, [23]uint8{0x59}},
@@ -1255,8 +1447,12 @@
 	{AOUTSL, ynone, Px, [23]uint8{0x6f}},
 	{AOUTSW, ynone, Pe, [23]uint8{0x6f}},
 	{AOUTW, yin, Pe, [23]uint8{0xe7, 0xef}},
+	{APABSB, yxm_q4, Pq4, [23]uint8{0x1c}},
+	{APABSD, yxm_q4, Pq4, [23]uint8{0x1e}},
+	{APABSW, yxm_q4, Pq4, [23]uint8{0x1d}},
 	{APACKSSLW, ymm, Py1, [23]uint8{0x6b, Pe, 0x6b}},
 	{APACKSSWB, ymm, Py1, [23]uint8{0x63, Pe, 0x63}},
+	{APACKUSDW, yxm_q4, Pq4, [23]uint8{0x2b}},
 	{APACKUSWB, ymm, Py1, [23]uint8{0x67, Pe, 0x67}},
 	{APADDB, ymm, Py1, [23]uint8{0xfc, Pe, 0xfc}},
 	{APADDL, ymm, Py1, [23]uint8{0xfe, Pe, 0xfe}},
@@ -1266,17 +1462,23 @@
 	{APADDUSB, ymm, Py1, [23]uint8{0xdc, Pe, 0xdc}},
 	{APADDUSW, ymm, Py1, [23]uint8{0xdd, Pe, 0xdd}},
 	{APADDW, ymm, Py1, [23]uint8{0xfd, Pe, 0xfd}},
+	{APALIGNR, ypalignr, Pq, [23]uint8{0x3a, 0x0f}},
 	{APAND, ymm, Py1, [23]uint8{0xdb, Pe, 0xdb}},
 	{APANDN, ymm, Py1, [23]uint8{0xdf, Pe, 0xdf}},
 	{APAUSE, ynone, Px, [23]uint8{0xf3, 0x90}},
 	{APAVGB, ymm, Py1, [23]uint8{0xe0, Pe, 0xe0}},
 	{APAVGW, ymm, Py1, [23]uint8{0xe3, Pe, 0xe3}},
+	{APBLENDW, yxshuf, Pq, [23]uint8{0x3a, 0x0e, 0}},
 	{APCMPEQB, ymm, Py1, [23]uint8{0x74, Pe, 0x74}},
 	{APCMPEQL, ymm, Py1, [23]uint8{0x76, Pe, 0x76}},
+	{APCMPEQQ, yxm_q4, Pq4, [23]uint8{0x29}},
 	{APCMPEQW, ymm, Py1, [23]uint8{0x75, Pe, 0x75}},
 	{APCMPGTB, ymm, Py1, [23]uint8{0x64, Pe, 0x64}},
 	{APCMPGTL, ymm, Py1, [23]uint8{0x66, Pe, 0x66}},
+	{APCMPGTQ, yxm_q4, Pq4, [23]uint8{0x37}},
 	{APCMPGTW, ymm, Py1, [23]uint8{0x65, Pe, 0x65}},
+	{APCMPISTRI, yxshuf, Pq, [23]uint8{0x3a, 0x63, 0}},
+	{APCMPISTRM, yxshuf, Pq, [23]uint8{0x3a, 0x62, 0}},
 	{APEXTRW, yextrw, Pq, [23]uint8{0xc5, 00}},
 	{APEXTRB, yextr, Pq, [23]uint8{0x3a, 0x14, 00}},
 	{APEXTRD, yextr, Pq, [23]uint8{0x3a, 0x16, 00}},
@@ -1292,11 +1494,20 @@
 	{APINSRB, yinsr, Pq, [23]uint8{0x3a, 0x20, 00}},
 	{APINSRD, yinsr, Pq, [23]uint8{0x3a, 0x22, 00}},
 	{APINSRQ, yinsr, Pq3, [23]uint8{0x3a, 0x22, 00}},
+	{APMADDUBSW, yxm_q4, Pq4, [23]uint8{0x04}},
 	{APMADDWL, ymm, Py1, [23]uint8{0xf5, Pe, 0xf5}},
+	{APMAXSB, yxm_q4, Pq4, [23]uint8{0x3c}},
+	{APMAXSD, yxm_q4, Pq4, [23]uint8{0x3d}},
 	{APMAXSW, yxm, Pe, [23]uint8{0xee}},
 	{APMAXUB, yxm, Pe, [23]uint8{0xde}},
+	{APMAXUD, yxm_q4, Pq4, [23]uint8{0x3f}},
+	{APMAXUW, yxm_q4, Pq4, [23]uint8{0x3e}},
+	{APMINSB, yxm_q4, Pq4, [23]uint8{0x38}},
+	{APMINSD, yxm_q4, Pq4, [23]uint8{0x39}},
 	{APMINSW, yxm, Pe, [23]uint8{0xea}},
 	{APMINUB, yxm, Pe, [23]uint8{0xda}},
+	{APMINUD, yxm_q4, Pq4, [23]uint8{0x3b}},
+	{APMINUW, yxm_q4, Pq4, [23]uint8{0x3a}},
 	{APMOVMSKB, ymskb, Px, [23]uint8{Pe, 0xd7, 0xd7}},
 	{APMOVSXBD, yxm_q4, Pq4, [23]uint8{0x21}},
 	{APMOVSXBQ, yxm_q4, Pq4, [23]uint8{0x22}},
@@ -1311,6 +1522,7 @@
 	{APMOVZXWD, yxm_q4, Pq4, [23]uint8{0x33}},
 	{APMOVZXWQ, yxm_q4, Pq4, [23]uint8{0x34}},
 	{APMULDQ, yxm_q4, Pq4, [23]uint8{0x28}},
+	{APMULHRSW, yxm_q4, Pq4, [23]uint8{0x0b}},
 	{APMULHUW, ymm, Py1, [23]uint8{0xe4, Pe, 0xe4}},
 	{APMULHW, ymm, Py1, [23]uint8{0xe5, Pe, 0xe5}},
 	{APMULLD, yxm_q4, Pq4, [23]uint8{0x40}},
@@ -1334,6 +1546,9 @@
 	{APSHUFLW, yxshuf, Pf2, [23]uint8{0x70, 00}},
 	{APSHUFW, ymshuf, Pm, [23]uint8{0x70, 00}},
 	{APSHUFB, ymshufb, Pq, [23]uint8{0x38, 0x00}},
+	{APSIGNB, yxm_q4, Pq4, [23]uint8{0x08}},
+	{APSIGND, yxm_q4, Pq4, [23]uint8{0x0a}},
+	{APSIGNW, yxm_q4, Pq4, [23]uint8{0x09}},
 	{APSLLO, ypsdq, Pq, [23]uint8{0x73, 07}},
 	{APSLLL, yps, Py3, [23]uint8{0xf2, 0x72, 06, Pe, 0xf2, Pe, 0x72, 06}},
 	{APSLLQ, yps, Py3, [23]uint8{0xf3, 0x73, 06, Pe, 0xf3, Pe, 0x73, 06}},
@@ -1352,6 +1567,7 @@
 	{APSUBUSB, yxm, Pe, [23]uint8{0xd8}},
 	{APSUBUSW, yxm, Pe, [23]uint8{0xd9}},
 	{APSUBW, yxm, Pe, [23]uint8{0xf9}},
+	{APTEST, yxm_q4, Pq4, [23]uint8{0x17}},
 	{APUNPCKHBW, ymm, Py1, [23]uint8{0x68, Pe, 0x68}},
 	{APUNPCKHLQ, ymm, Py1, [23]uint8{0x6a, Pe, 0x6a}},
 	{APUNPCKHQDQ, yxm, Pe, [23]uint8{0x6d}},
@@ -1446,7 +1662,7 @@
 	{ASTC, ynone, Px, [23]uint8{0xf9}},
 	{ASTD, ynone, Px, [23]uint8{0xfd}},
 	{ASTI, ynone, Px, [23]uint8{0xfb}},
-	{ASTMXCSR, ysvrs, Pm, [23]uint8{0xae, 03, 0xae, 03}},
+	{ASTMXCSR, ysvrs_om, Pm, [23]uint8{0xae, 03, 0xae, 03}},
 	{ASTOSB, ynone, Pb, [23]uint8{0xaa}},
 	{ASTOSL, ynone, Px, [23]uint8{0xab}},
 	{ASTOSQ, ynone, Pw, [23]uint8{0xab}},
@@ -1557,12 +1773,12 @@
 	{AFDIVRD, yfadd, Px, [23]uint8{0xdc, 07, 0xd8, 07, 0xdc, 06}},
 	{AFXCHD, yfxch, Px, [23]uint8{0xd9, 01, 0xd9, 01}},
 	{AFFREE, nil, 0, [23]uint8{}},
-	{AFLDCW, ysvrs, Px, [23]uint8{0xd9, 05, 0xd9, 05}},
-	{AFLDENV, ysvrs, Px, [23]uint8{0xd9, 04, 0xd9, 04}},
-	{AFRSTOR, ysvrs, Px, [23]uint8{0xdd, 04, 0xdd, 04}},
-	{AFSAVE, ysvrs, Px, [23]uint8{0xdd, 06, 0xdd, 06}},
-	{AFSTCW, ysvrs, Px, [23]uint8{0xd9, 07, 0xd9, 07}},
-	{AFSTENV, ysvrs, Px, [23]uint8{0xd9, 06, 0xd9, 06}},
+	{AFLDCW, ysvrs_mo, Px, [23]uint8{0xd9, 05, 0xd9, 05}},
+	{AFLDENV, ysvrs_mo, Px, [23]uint8{0xd9, 04, 0xd9, 04}},
+	{AFRSTOR, ysvrs_mo, Px, [23]uint8{0xdd, 04, 0xdd, 04}},
+	{AFSAVE, ysvrs_om, Px, [23]uint8{0xdd, 06, 0xdd, 06}},
+	{AFSTCW, ysvrs_om, Px, [23]uint8{0xd9, 07, 0xd9, 07}},
+	{AFSTENV, ysvrs_om, Px, [23]uint8{0xd9, 06, 0xd9, 06}},
 	{AFSTSW, ystsw, Px, [23]uint8{0xdd, 07, 0xdf, 0xe0}},
 	{AF2XM1, ynone, Px, [23]uint8{0xd9, 0xf0}},
 	{AFABS, ynone, Px, [23]uint8{0xd9, 0xe1}},
@@ -1638,63 +1854,13 @@
 	{APSHUFD, yxshuf, Pq, [23]uint8{0x70, 0}},
 	{APCLMULQDQ, yxshuf, Pq, [23]uint8{0x3a, 0x44, 0}},
 	{APCMPESTRI, yxshuf, Pq, [23]uint8{0x3a, 0x61, 0}},
+	{APCMPESTRM, yxshuf, Pq, [23]uint8{0x3a, 0x60, 0}},
 	{AMOVDDUP, yxm, Pf2, [23]uint8{0x12}},
 	{AMOVSHDUP, yxm, Pf3, [23]uint8{0x16}},
 	{AMOVSLDUP, yxm, Pf3, [23]uint8{0x12}},
 
-	{AANDNL, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF2}},
-	{AANDNQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF2}},
-	{ABEXTRL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF7}},
-	{ABEXTRQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF7}},
-	{ABZHIL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF5}},
-	{ABZHIQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF5}},
-	{AMULXL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF6}},
-	{AMULXQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF6}},
-	{APDEPL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF5}},
-	{APDEPQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF5}},
-	{APEXTL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF5}},
-	{APEXTQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF5}},
-	{ASARXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF7}},
-	{ASARXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF7}},
-	{ASHLXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W0, 0xF7}},
-	{ASHLXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W1, 0xF7}},
-	{ASHRXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF7}},
-	{ASHRXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF7}},
-
-	{AVZEROUPPER, ynone, Px, [23]uint8{0xc5, 0xf8, 0x77}},
-	{AVMOVDQU, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x6F, VEX_128_F3_0F_WIG, 0x7F, VEX_256_F3_0F_WIG, 0x6F, VEX_256_F3_0F_WIG, 0x7F}},
-	{AVMOVDQA, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x6F, VEX_128_66_0F_WIG, 0x7F, VEX_256_66_0F_WIG, 0x6F, VEX_256_66_0F_WIG, 0x7F}},
-	{AVMOVNTDQ, yvex_vmovntdq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xE7, VEX_256_66_0F_WIG, 0xE7}},
-	{AVPCMPEQB, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x74, VEX_256_66_0F_WIG, 0x74}},
-	{AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}},
-	{AVPMOVMSKB, yvex_xyr2, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xD7, VEX_256_66_0F_WIG, 0xD7}},
-	{AVPAND, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xDB, VEX_256_66_0F_WIG, 0xDB}},
-	{AVPBROADCASTB, yvex_vpbroadcast, Pvex, [23]uint8{VEX_128_66_0F38_W0, 0x78, VEX_256_66_0F38_W0, 0x78}},
-	{AVPTEST, yvex_xy2, Pvex, [23]uint8{VEX_128_66_0F38_WIG, 0x17, VEX_256_66_0F38_WIG, 0x17}},
-	{AVPSHUFB, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F38_WIG, 0x00, VEX_256_66_0F38_WIG, 0x00}},
-	{AVPSHUFD, yvex_xyi3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x70, VEX_256_66_0F_WIG, 0x70, VEX_128_66_0F_WIG, 0x70, VEX_256_66_0F_WIG, 0x70}},
-	{AVPOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xeb, VEX_256_66_0F_WIG, 0xeb}},
-	{AVPADDQ, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xd4, VEX_256_66_0F_WIG, 0xd4}},
-	{AVPADDD, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xfe, VEX_256_66_0F_WIG, 0xfe}},
-	{AVPSLLD, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x72, 0xf0, VEX_256_66_0F_WIG, 0x72, 0xf0, VEX_128_66_0F_WIG, 0xf2, VEX_256_66_0F_WIG, 0xf2}},
-	{AVPSLLQ, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xf0, VEX_256_66_0F_WIG, 0x73, 0xf0, VEX_128_66_0F_WIG, 0xf3, VEX_256_66_0F_WIG, 0xf3}},
-	{AVPSRLD, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x72, 0xd0, VEX_256_66_0F_WIG, 0x72, 0xd0, VEX_128_66_0F_WIG, 0xd2, VEX_256_66_0F_WIG, 0xd2}},
-	{AVPSRLQ, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xd0, VEX_256_66_0F_WIG, 0x73, 0xd0, VEX_128_66_0F_WIG, 0xd3, VEX_256_66_0F_WIG, 0xd3}},
-	{AVPSRLDQ, yvex_shift_dq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xd8, VEX_256_66_0F_WIG, 0x73, 0xd8}},
-	{AVPSLLDQ, yvex_shift_dq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xf8, VEX_256_66_0F_WIG, 0x73, 0xf8}},
-	{AVPERM2F128, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_W0, 0x06}},
-	{AVPALIGNR, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x0f}},
-	{AVPBLENDD, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x02}},
-	{AVINSERTI128, yvex_xyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x38}},
-	{AVPERM2I128, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x46}},
-	{ARORXL, yvex_ri3, Pvex, [23]uint8{VEX_LZ_F2_0F3A_W0, 0xf0}},
-	{ARORXQ, yvex_ri3, Pvex, [23]uint8{VEX_LZ_F2_0F3A_W1, 0xf0}},
-	{AVBROADCASTSD, yvex_vpbroadcast_sd, Pvex, [23]uint8{VEX_256_66_0F38_W0, 0x19}},
-	{AVBROADCASTSS, yvex_vpbroadcast, Pvex, [23]uint8{VEX_128_66_0F38_W0, 0x18, VEX_256_66_0F38_W0, 0x18}},
-	{AVMOVDDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F2_0F_WIG, 0x12, VEX_256_F2_0F_WIG, 0x12}},
-	{AVMOVSHDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x16, VEX_256_F3_0F_WIG, 0x16}},
-	{AVMOVSLDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x12, VEX_256_F3_0F_WIG, 0x12}},
-
+	{ABLENDPD, yxshuf, Pq, [23]uint8{0x3a, 0x0d, 0}},
+	{ABLENDPS, yxshuf, Pq, [23]uint8{0x3a, 0x0c, 0}},
 	{AXACQUIRE, ynone, Px, [23]uint8{0xf2}},
 	{AXRELEASE, ynone, Px, [23]uint8{0xf3}},
 	{AXBEGIN, yxbegin, Px, [23]uint8{0xc7, 0xf8}},
@@ -1706,20 +1872,61 @@
 	{obj.APCDATA, ypcdata, Px, [23]uint8{0, 0}},
 	{obj.ADUFFCOPY, yduff, Px, [23]uint8{0xe8}},
 	{obj.ADUFFZERO, yduff, Px, [23]uint8{0xe8}},
+
+	// AVX2 gather instructions.
+	// Added as a part of VSIB support implementation,
+	// when x86avxgen will output these, they will be moved to
+	// vex_optabs.go where they belong.
+	{AVGATHERDPD, yvpgatherdq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x92,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x92,
+	}},
+	{AVGATHERQPD, yvpgatherqq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x93,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x93,
+	}},
+	{AVGATHERDPS, yvpgatherqq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x92,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x92,
+	}},
+	{AVGATHERQPS, yvgatherqps, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x93,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x93,
+	}},
+	{AVPGATHERDD, yvpgatherqq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x90,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x90,
+	}},
+	{AVPGATHERQD, yvgatherqps, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x91,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x91,
+	}},
+	{AVPGATHERDQ, yvpgatherdq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x90,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x90,
+	}},
+	{AVPGATHERQQ, yvpgatherqq, Pvex, [23]uint8{
+		vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x91,
+		vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x91,
+	}},
+
 	{obj.AEND, nil, 0, [23]uint8{}},
 	{0, nil, 0, [23]uint8{}},
 }
 
 var opindex [(ALAST + 1) & obj.AMask]*Optab
 
-// isextern reports whether s describes an external symbol that must avoid pc-relative addressing.
+// useAbs reports whether s describes a 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.
-func isextern(s *obj.LSym) bool {
-	// All the Solaris dynamic imports from libc.so begin with "libc_".
-	return strings.HasPrefix(s.Name, "libc_")
+func useAbs(ctxt *obj.Link, s *obj.LSym) bool {
+	if ctxt.Headtype == objabi.Hsolaris {
+		// All the Solaris dynamic imports from libc.so begin with "libc_".
+		return strings.HasPrefix(s.Name, "libc_")
+	}
+	return ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared
 }
 
 // single-instruction no-ops of various lengths.
@@ -1980,6 +2187,13 @@
 		deferreturn = ctxt.Lookup("runtime.deferreturn")
 	}
 
+	for i := range vexOptab {
+		c := vexOptab[i].as
+		if opindex[c&obj.AMask] != nil {
+			ctxt.Diag("phase error in vexOptab: %d (%v)", i, c)
+		}
+		opindex[c&obj.AMask] = &vexOptab[i]
+	}
 	for i := 1; optab[i].as != 0; i++ {
 		c := optab[i].as
 		if opindex[c&obj.AMask] != nil {
@@ -1992,25 +2206,33 @@
 		ycover[i*Ymax+i] = 1
 	}
 
+	ycover[Yi0*Ymax+Yu2] = 1
+	ycover[Yi1*Ymax+Yu2] = 1
+
 	ycover[Yi0*Ymax+Yi8] = 1
 	ycover[Yi1*Ymax+Yi8] = 1
+	ycover[Yu2*Ymax+Yi8] = 1
 	ycover[Yu7*Ymax+Yi8] = 1
 
 	ycover[Yi0*Ymax+Yu7] = 1
 	ycover[Yi1*Ymax+Yu7] = 1
+	ycover[Yu2*Ymax+Yu7] = 1
 
 	ycover[Yi0*Ymax+Yu8] = 1
 	ycover[Yi1*Ymax+Yu8] = 1
+	ycover[Yu2*Ymax+Yu8] = 1
 	ycover[Yu7*Ymax+Yu8] = 1
 
 	ycover[Yi0*Ymax+Ys32] = 1
 	ycover[Yi1*Ymax+Ys32] = 1
+	ycover[Yu2*Ymax+Ys32] = 1
 	ycover[Yu7*Ymax+Ys32] = 1
 	ycover[Yu8*Ymax+Ys32] = 1
 	ycover[Yi8*Ymax+Ys32] = 1
 
 	ycover[Yi0*Ymax+Yi32] = 1
 	ycover[Yi1*Ymax+Yi32] = 1
+	ycover[Yu2*Ymax+Yi32] = 1
 	ycover[Yu7*Ymax+Yi32] = 1
 	ycover[Yu8*Ymax+Yi32] = 1
 	ycover[Yi8*Ymax+Yi32] = 1
@@ -2019,6 +2241,7 @@
 	ycover[Yi0*Ymax+Yi64] = 1
 	ycover[Yi1*Ymax+Yi64] = 1
 	ycover[Yu7*Ymax+Yi64] = 1
+	ycover[Yu2*Ymax+Yi64] = 1
 	ycover[Yu8*Ymax+Yi64] = 1
 	ycover[Yi8*Ymax+Yi64] = 1
 	ycover[Ys32*Ymax+Yi64] = 1
@@ -2225,7 +2448,7 @@
 		return 0x26
 
 	case REG_TLS:
-		if ctxt.Flag_shared {
+		if ctxt.Flag_shared && ctxt.Headtype != objabi.Hwindows {
 			// When building for inclusion into a shared library, an instruction of the form
 			//     MOV 0(CX)(TLS*1), AX
 			// becomes
@@ -2268,7 +2491,26 @@
 			// Can't use SP as the index register
 			return Yxxx
 		}
+		if a.Index >= REG_X0 && a.Index <= REG_X15 {
+			if ctxt.Arch.Family == sys.I386 && a.Index > REG_X7 {
+				return Yxxx
+			}
+			return Yxvm
+		}
+		if a.Index >= REG_Y0 && a.Index <= REG_Y15 {
+			if ctxt.Arch.Family == sys.I386 && a.Index > REG_Y7 {
+				return Yxxx
+			}
+			return Yyvm
+		}
 		if ctxt.Arch.Family == sys.AMD64 {
+			// Offset must fit in a 32-bit signed field (or fit in a 32-bit unsigned field
+			// where the sign extension doesn't matter).
+			// Note: The latter happens only in assembly, for example crypto/sha1/sha1block_amd64.s.
+			if !(a.Offset == int64(int32(a.Offset)) ||
+				a.Offset == int64(uint32(a.Offset)) && p.As == ALEAL) {
+				return Yxxx
+			}
 			switch a.Name {
 			case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
 				// Global variables can't use index registers and their
@@ -2299,7 +2541,7 @@
 
 		case obj.NAME_EXTERN,
 			obj.NAME_STATIC:
-			if a.Sym != nil && isextern(a.Sym) || (ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared) {
+			if a.Sym != nil && useAbs(ctxt, a.Sym) {
 				return Yi32
 			}
 			return Yiauto // use pc-relative addressing
@@ -2333,15 +2575,14 @@
 			v = int64(int32(v))
 		}
 		if v == 0 {
-			if p.Mark&PRESERVEFLAGS != 0 {
-				// If PRESERVEFLAGS is set, avoid MOV $0, AX turning into XOR AX, AX.
-				return Yu7
-			}
 			return Yi0
 		}
 		if v == 1 {
 			return Yi1
 		}
+		if v >= 0 && v <= 3 {
+			return Yu2
+		}
 		if v >= 0 && v <= 127 {
 			return Yu7
 		}
@@ -2674,9 +2915,11 @@
 // At returns the byte at offset i.
 func (a *AsmBuf) At(i int) byte { return a.buf[i] }
 
+// asmidx emits SIB byte.
 func (asmbuf *AsmBuf) asmidx(ctxt *obj.Link, scale int, index int, base int) {
 	var i int
 
+	// X/Y index register is used in VSIB.
 	switch index {
 	default:
 		goto bad
@@ -2692,7 +2935,23 @@
 		REG_R12,
 		REG_R13,
 		REG_R14,
-		REG_R15:
+		REG_R15,
+		REG_X8,
+		REG_X9,
+		REG_X10,
+		REG_X11,
+		REG_X12,
+		REG_X13,
+		REG_X14,
+		REG_X15,
+		REG_Y8,
+		REG_Y9,
+		REG_Y10,
+		REG_Y11,
+		REG_Y12,
+		REG_Y13,
+		REG_Y14,
+		REG_Y15:
 		if ctxt.Arch.Family == sys.I386 {
 			goto bad
 		}
@@ -2704,7 +2963,23 @@
 		REG_BX,
 		REG_BP,
 		REG_SI,
-		REG_DI:
+		REG_DI,
+		REG_X0,
+		REG_X1,
+		REG_X2,
+		REG_X3,
+		REG_X4,
+		REG_X5,
+		REG_X6,
+		REG_X7,
+		REG_Y0,
+		REG_Y1,
+		REG_Y2,
+		REG_Y3,
+		REG_Y4,
+		REG_Y5,
+		REG_Y6,
+		REG_Y7:
 		i = reg[index] << 3
 	}
 
@@ -2800,7 +3075,7 @@
 		if a.Name == obj.NAME_GOTREF {
 			r.Siz = 4
 			r.Type = objabi.R_GOTPCREL
-		} else if isextern(s) || (ctxt.Arch.Family != sys.AMD64 && !ctxt.Flag_shared) {
+		} else if useAbs(ctxt, s) {
 			r.Siz = 4
 			r.Type = objabi.R_ADDR
 		} else {
@@ -2883,7 +3158,7 @@
 		case obj.NAME_EXTERN,
 			obj.NAME_GOTREF,
 			obj.NAME_STATIC:
-			if !isextern(a.Sym) && ctxt.Arch.Family == sys.AMD64 {
+			if !useAbs(ctxt, a.Sym) && ctxt.Arch.Family == sys.AMD64 {
 				goto bad
 			}
 			if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
@@ -2953,7 +3228,7 @@
 
 	asmbuf.rexflag |= regrex[base]&Rxb | rex
 	if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS {
-		if (a.Sym == nil || !isextern(a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || ctxt.Arch.Family != sys.AMD64 {
+		if (a.Sym == nil || !useAbs(ctxt, a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || ctxt.Arch.Family != sys.AMD64 {
 			if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) {
 				ctxt.Diag("%v has offset against gotref", p)
 			}
@@ -3315,6 +3590,35 @@
 	asmbuf.Put1(opcode)
 }
 
+// regIndex returns register index that fits in 4 bits.
+//
+// Examples:
+//   REG_X15 => 15
+//   REG_R9  => 9
+//   REG_AX  => 0
+//
+func regIndex(r int16) int {
+	lower3bits := reg[r]
+	high4bit := regrex[r] & Rxr << 1
+	return lower3bits | high4bit
+}
+
+// avx2gatherValid returns true if p satisfies AVX2 gather constraints.
+// Reports errors via ctxt.
+func avx2gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
+	// If any pair of the index, mask, or destination registers
+	// are the same, this instruction results a #UD fault.
+	index := regIndex(p.GetFrom3().Index)
+	mask := regIndex(p.From.Reg)
+	dest := regIndex(p.To.Reg)
+	if dest == mask || dest == index || mask == index {
+		ctxt.Diag("mask, index, and destination registers should be distinct: %v", p)
+		return false
+	}
+
+	return true
+}
+
 func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
 	o := opindex[p.As&obj.AMask]
 
@@ -3337,9 +3641,10 @@
 	// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
 	// Change encoding generated by assemblers and compilers and remove.
 	if (p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_REG) && p.From.Index != REG_NONE && p.From.Scale == 0 {
-		p.From3 = new(obj.Addr)
-		p.From3.Type = obj.TYPE_REG
-		p.From3.Reg = p.From.Index
+		p.SetFrom3(obj.Addr{
+			Type: obj.TYPE_REG,
+			Reg:  p.From.Index,
+		})
 		p.From.Index = 0
 	}
 
@@ -3348,8 +3653,7 @@
 	switch p.As {
 	case AIMUL3Q, APEXTRW, APINSRW, APINSRD, APINSRQ, APSHUFHW, APSHUFL, APSHUFW, ASHUFPD, ASHUFPS, AAESKEYGENASSIST, APSHUFD, APCLMULQDQ:
 		if p.From3Type() == obj.TYPE_NONE {
-			p.From3 = new(obj.Addr)
-			*p.From3 = p.From
+			p.SetFrom3(p.From)
 			p.From = obj.Addr{}
 			p.From.Type = obj.TYPE_CONST
 			p.From.Offset = p.To.Offset
@@ -3357,12 +3661,23 @@
 		}
 	case ACMPSD, ACMPSS, ACMPPS, ACMPPD:
 		if p.From3Type() == obj.TYPE_NONE {
-			p.From3 = new(obj.Addr)
-			*p.From3 = p.To
+			p.SetFrom3(p.To)
 			p.To = obj.Addr{}
 			p.To.Type = obj.TYPE_CONST
-			p.To.Offset = p.From3.Offset
-			p.From3.Offset = 0
+			p.To.Offset = p.GetFrom3().Offset
+			p.GetFrom3().Offset = 0
+		}
+
+	case AVGATHERDPD,
+		AVGATHERQPD,
+		AVGATHERDPS,
+		AVGATHERQPS,
+		AVPGATHERDD,
+		AVPGATHERQD,
+		AVPGATHERDQ,
+		AVPGATHERQQ:
+		if !avx2gatherValid(ctxt, p) {
+			return
 		}
 	}
 
@@ -3374,10 +3689,7 @@
 	}
 
 	ft := int(p.Ft) * Ymax
-	f3t := Ynone * Ymax
-	if p.From3 != nil {
-		f3t = oclass(ctxt, p, p.From3) * Ymax
-	}
+	var f3t int
 	tt := int(p.Tt) * Ymax
 
 	xo := obj.Bool2int(o.op[0] == 0x0f)
@@ -3389,9 +3701,22 @@
 	var r *obj.Reloc
 	var rel obj.Reloc
 	var v int64
-	for i := range o.ytab {
-		yt := &o.ytab[i]
-		if ycover[ft+int(yt.from)] != 0 && ycover[f3t+int(yt.from3)] != 0 && ycover[tt+int(yt.to)] != 0 {
+
+	args := make([]int, 0, 6)
+	if ft != Ynone*Ymax {
+		args = append(args, ft)
+	}
+	for i := range p.RestArgs {
+		args = append(args, oclass(ctxt, p, &p.RestArgs[i])*Ymax)
+	}
+	if tt != Ynone*Ymax {
+		args = append(args, tt)
+	}
+
+	for _, yt := range o.ytab {
+		if !yt.match(args) {
+			z += int(yt.zoffset) + xo
+		} else {
 			switch o.prefix {
 			case Px1: /* first option valid only in 32-bit mode */
 				if ctxt.Arch.Family == sys.AMD64 && z == 0 {
@@ -3408,6 +3733,17 @@
 			case Pq4: /*  66 0F 38 */
 				asmbuf.Put3(0x66, 0x0F, 0x38)
 
+			case Pq4w: /*  66 0F 38 + REX.W */
+				asmbuf.rexflag |= Pw
+				asmbuf.Put3(0x66, 0x0F, 0x38)
+
+			case Pq5: /*  F3 0F 38 */
+				asmbuf.Put3(0xF3, 0x0F, 0x38)
+
+			case Pq5w: /*  F3 0F 38 + REX.W */
+				asmbuf.rexflag |= Pw
+				asmbuf.Put3(0xF3, 0x0F, 0x38)
+
 			case Pf2, /* xmm opcode escape */
 				Pf3:
 				asmbuf.Put2(o.prefix, Pm)
@@ -3538,7 +3874,7 @@
 
 			case Zm_r_i_xm:
 				asmbuf.mediaop(ctxt, o, op, int(yt.zoffset), z)
-				asmbuf.asmand(ctxt, cursym, p, &p.From, p.From3)
+				asmbuf.asmand(ctxt, cursym, p, &p.From, p.GetFrom3())
 				asmbuf.Put1(byte(p.To.Offset))
 
 			case Zibm_r, Zibr_m:
@@ -3552,9 +3888,9 @@
 					asmbuf.Put1(byte(op))
 				}
 				if yt.zcase == Zibr_m {
-					asmbuf.asmand(ctxt, cursym, p, &p.To, p.From3)
+					asmbuf.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
 				} else {
-					asmbuf.asmand(ctxt, cursym, p, p.From3, &p.To)
+					asmbuf.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
 				}
 				asmbuf.Put1(byte(p.From.Offset))
 
@@ -3575,39 +3911,62 @@
 				asmbuf.Put1(byte(op))
 				asmbuf.asmand(ctxt, cursym, p, &p.To, &p.From)
 
+			case Zvex:
+				asmbuf.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
+
 			case Zvex_rm_v_r:
-				asmbuf.asmvex(ctxt, &p.From, p.From3, &p.To, o.op[z], o.op[z+1])
+				asmbuf.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
 				asmbuf.asmand(ctxt, cursym, p, &p.From, &p.To)
 
+			case Zvex_rm_v_ro:
+				asmbuf.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
+				asmbuf.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
+
 			case Zvex_i_r_v:
-				asmbuf.asmvex(ctxt, p.From3, &p.To, nil, o.op[z], o.op[z+1])
+				asmbuf.asmvex(ctxt, p.GetFrom3(), &p.To, nil, o.op[z], o.op[z+1])
 				regnum := byte(0x7)
-				if p.From3.Reg >= REG_X0 && p.From3.Reg <= REG_X15 {
-					regnum &= byte(p.From3.Reg - REG_X0)
+				if p.GetFrom3().Reg >= REG_X0 && p.GetFrom3().Reg <= REG_X15 {
+					regnum &= byte(p.GetFrom3().Reg - REG_X0)
 				} else {
-					regnum &= byte(p.From3.Reg - REG_Y0)
+					regnum &= byte(p.GetFrom3().Reg - REG_Y0)
 				}
 				asmbuf.Put1(byte(o.op[z+2]) | regnum)
 				asmbuf.Put1(byte(p.From.Offset))
 
 			case Zvex_i_rm_v_r:
-				asmbuf.asmvex(ctxt, &p.From, p.From3, &p.To, o.op[z], o.op[z+1])
-				asmbuf.asmand(ctxt, cursym, p, &p.From, &p.To)
-				asmbuf.Put1(byte(p.From3.Offset))
+				imm, from, from3, to := unpackOps4(p)
+				asmbuf.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
+				asmbuf.asmand(ctxt, cursym, p, from, to)
+				asmbuf.Put1(byte(imm.Offset))
 
 			case Zvex_i_rm_r:
-				asmbuf.asmvex(ctxt, p.From3, nil, &p.To, o.op[z], o.op[z+1])
-				asmbuf.asmand(ctxt, cursym, p, p.From3, &p.To)
+				asmbuf.asmvex(ctxt, p.GetFrom3(), nil, &p.To, o.op[z], o.op[z+1])
+				asmbuf.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
 				asmbuf.Put1(byte(p.From.Offset))
 
 			case Zvex_v_rm_r:
-				asmbuf.asmvex(ctxt, p.From3, &p.From, &p.To, o.op[z], o.op[z+1])
-				asmbuf.asmand(ctxt, cursym, p, p.From3, &p.To)
+				asmbuf.asmvex(ctxt, p.GetFrom3(), &p.From, &p.To, o.op[z], o.op[z+1])
+				asmbuf.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
 
 			case Zvex_r_v_rm:
-				asmbuf.asmvex(ctxt, &p.To, p.From3, &p.From, o.op[z], o.op[z+1])
+				asmbuf.asmvex(ctxt, &p.To, p.GetFrom3(), &p.From, o.op[z], o.op[z+1])
 				asmbuf.asmand(ctxt, cursym, p, &p.To, &p.From)
 
+			case Zvex_rm_r_vo:
+				asmbuf.asmvex(ctxt, &p.From, &p.To, p.GetFrom3(), o.op[z], o.op[z+1])
+				asmbuf.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
+
+			case Zvex_i_r_rm:
+				asmbuf.asmvex(ctxt, &p.To, nil, p.GetFrom3(), o.op[z], o.op[z+1])
+				asmbuf.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
+				asmbuf.Put1(byte(p.From.Offset))
+
+			case Zvex_hr_rm_v_r:
+				hr, from, from3, to := unpackOps4(p)
+				asmbuf.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
+				asmbuf.asmand(ctxt, cursym, p, from, to)
+				asmbuf.Put1(byte(regIndex(hr.Reg) << 4))
+
 			case Zr_m_xm:
 				asmbuf.mediaop(ctxt, o, op, int(yt.zoffset), z)
 				asmbuf.asmand(ctxt, cursym, p, &p.To, &p.From)
@@ -3772,11 +4131,6 @@
 				asmbuf.rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
 				asmbuf.Put1(byte(op + reg[p.From.Reg]))
 
-			case Zclr:
-				asmbuf.rexflag &^= Pw
-				asmbuf.Put1(byte(op))
-				asmbuf.asmand(ctxt, cursym, p, &p.To, &p.To)
-
 			case Zcallcon, Zjmpcon:
 				if yt.zcase == Zcallcon {
 					asmbuf.Put1(byte(op))
@@ -3807,6 +4161,7 @@
 			case Zcall, Zcallduff:
 				if p.To.Sym == nil {
 					ctxt.Diag("call without target")
+					ctxt.DiagFlush()
 					log.Fatalf("bad code")
 				}
 
@@ -3847,6 +4202,7 @@
 				if p.To.Sym != nil {
 					if yt.zcase != Zjmp {
 						ctxt.Diag("branch to ATEXT")
+						ctxt.DiagFlush()
 						log.Fatalf("bad code")
 					}
 
@@ -3868,6 +4224,7 @@
 
 				if q == nil {
 					ctxt.Diag("jmp/branch/loop without target")
+					ctxt.DiagFlush()
 					log.Fatalf("bad code")
 				}
 
@@ -3960,7 +4317,10 @@
 
 			return
 		}
-		z += int(yt.zoffset) + xo
+	}
+	f3t = Ynone * Ymax
+	if p.GetFrom3() != nil {
+		f3t = oclass(ctxt, p, p.GetFrom3()) * Ymax
 	}
 	for mo := ymovtab; mo[0].as != 0; mo = mo[1:] {
 		var pp obj.Prog
@@ -4039,7 +4399,7 @@
 
 					case obj.TYPE_CONST:
 						asmbuf.Put2(0x0f, t[0])
-						asmbuf.asmandsz(ctxt, cursym, p, &p.To, reg[p.From3.Reg], regrex[p.From3.Reg], 0)
+						asmbuf.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
 						asmbuf.Put1(byte(p.From.Offset))
 
 					case obj.TYPE_REG:
@@ -4049,7 +4409,7 @@
 
 						case REG_CL, REG_CX:
 							asmbuf.Put2(0x0f, t[1])
-							asmbuf.asmandsz(ctxt, cursym, p, &p.To, reg[p.From3.Reg], regrex[p.From3.Reg], 0)
+							asmbuf.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
 						}
 					}
 
@@ -4362,6 +4722,7 @@
 		return REG_DX
 	default:
 		ctxt.Diag("impossible byte register")
+		ctxt.DiagFlush()
 		log.Fatalf("bad code")
 		return 0
 	}
@@ -4600,3 +4961,8 @@
 		}
 	}
 }
+
+// Extract 4 operands from p.
+func unpackOps4(p *obj.Prog) (*obj.Addr, *obj.Addr, *obj.Addr, *obj.Addr) {
+	return &p.From, &p.RestArgs[0], &p.RestArgs[1], &p.To
+}
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index d34f0ae..7b5e476 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -201,8 +201,8 @@
 	}
 
 	if ctxt.Headtype == objabi.Hnacl && ctxt.Arch.Family == sys.AMD64 {
-		if p.From3 != nil {
-			nacladdr(ctxt, p, p.From3)
+		if p.GetFrom3() != nil {
+			nacladdr(ctxt, p, p.GetFrom3())
 		}
 		nacladdr(ctxt, p, &p.From)
 		nacladdr(ctxt, p, &p.To)
@@ -322,7 +322,7 @@
 		//     $LEA $offset($reg), $reg
 		//     CALL $reg
 		// (we use LEAx rather than ADDx because ADDx clobbers
-		// flags and duffzero on 386 does not otherwise do so)
+		// flags and duffzero on 386 does not otherwise do so).
 		var sym *obj.LSym
 		if p.As == obj.ADUFFZERO {
 			sym = ctxt.Lookup("runtime.duffzero")
@@ -398,7 +398,7 @@
 			q.From.Reg = reg
 		}
 	}
-	if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
+	if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
 		ctxt.Diag("don't know how to handle %v with -dynlink", p)
 	}
 	var source *obj.Addr
@@ -436,7 +436,9 @@
 		p2.As = p.As
 		p2.Scond = p.Scond
 		p2.From = p.From
-		p2.From3 = p.From3
+		if p.RestArgs != nil {
+			p2.RestArgs = append(p2.RestArgs, p.RestArgs...)
+		}
 		p2.Reg = p.Reg
 		p2.To = p.To
 		// p.To.Type was set to TYPE_BRANCH above, but that makes checkaddr
@@ -522,13 +524,13 @@
 		}
 	}
 
-	if !isName(&p.From) && !isName(&p.To) && (p.From3 == nil || !isName(p.From3)) {
+	if !isName(&p.From) && !isName(&p.To) && (p.GetFrom3() == nil || !isName(p.GetFrom3())) {
 		return
 	}
 	var dst int16 = REG_CX
 	if (p.As == ALEAL || p.As == AMOVL) && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
 		dst = p.To.Reg
-		// Why?  See the comment near the top of rewriteToUseGot above.
+		// Why? See the comment near the top of rewriteToUseGot above.
 		// AMOVLs might be introduced by the GOT rewrites.
 	}
 	q := obj.Appendp(p, newprog)
@@ -543,7 +545,7 @@
 	r.As = p.As
 	r.Scond = p.Scond
 	r.From = p.From
-	r.From3 = p.From3
+	r.RestArgs = p.RestArgs
 	r.Reg = p.Reg
 	r.To = p.To
 	if isName(&p.From) {
@@ -552,8 +554,8 @@
 	if isName(&p.To) {
 		r.To.Reg = dst
 	}
-	if p.From3 != nil && isName(p.From3) {
-		r.From3.Reg = dst
+	if p.GetFrom3() != nil && isName(p.GetFrom3()) {
+		r.GetFrom3().Reg = dst
 	}
 	obj.Nopout(p)
 }
@@ -857,12 +859,12 @@
 		case obj.NAME_PARAM:
 			p.From.Offset += int64(deltasp) + int64(pcsize)
 		}
-		if p.From3 != nil {
-			switch p.From3.Name {
+		if p.GetFrom3() != nil {
+			switch p.GetFrom3().Name {
 			case obj.NAME_AUTO:
-				p.From3.Offset += int64(deltasp) - int64(bpsize)
+				p.GetFrom3().Offset += int64(deltasp) - int64(bpsize)
 			case obj.NAME_PARAM:
-				p.From3.Offset += int64(deltasp) + int64(pcsize)
+				p.GetFrom3().Offset += int64(deltasp) + int64(pcsize)
 			}
 		}
 		switch p.To.Name {
@@ -1183,6 +1185,7 @@
 var unaryDst = map[obj.As]bool{
 	ABSWAPL:    true,
 	ABSWAPQ:    true,
+	ACLFLUSH:   true,
 	ACMPXCHG8B: true,
 	ADECB:      true,
 	ADECL:      true,
@@ -1231,28 +1234,31 @@
 }
 
 var Linkamd64 = obj.LinkArch{
-	Arch:       sys.ArchAMD64,
-	Init:       instinit,
-	Preprocess: preprocess,
-	Assemble:   span6,
-	Progedit:   progedit,
-	UnaryDst:   unaryDst,
+	Arch:           sys.ArchAMD64,
+	Init:           instinit,
+	Preprocess:     preprocess,
+	Assemble:       span6,
+	Progedit:       progedit,
+	UnaryDst:       unaryDst,
+	DWARFRegisters: AMD64DWARFRegisters,
 }
 
 var Linkamd64p32 = obj.LinkArch{
-	Arch:       sys.ArchAMD64P32,
-	Init:       instinit,
-	Preprocess: preprocess,
-	Assemble:   span6,
-	Progedit:   progedit,
-	UnaryDst:   unaryDst,
+	Arch:           sys.ArchAMD64P32,
+	Init:           instinit,
+	Preprocess:     preprocess,
+	Assemble:       span6,
+	Progedit:       progedit,
+	UnaryDst:       unaryDst,
+	DWARFRegisters: AMD64DWARFRegisters,
 }
 
 var Link386 = obj.LinkArch{
-	Arch:       sys.Arch386,
-	Init:       instinit,
-	Preprocess: preprocess,
-	Assemble:   span6,
-	Progedit:   progedit,
-	UnaryDst:   unaryDst,
+	Arch:           sys.Arch386,
+	Init:           instinit,
+	Preprocess:     preprocess,
+	Assemble:       span6,
+	Progedit:       progedit,
+	UnaryDst:       unaryDst,
+	DWARFRegisters: X86DWARFRegisters,
 }
diff --git a/src/cmd/internal/obj/x86/vex_optabs.go b/src/cmd/internal/obj/x86/vex_optabs.go
new file mode 100644
index 0000000..b0b54fe
--- /dev/null
+++ b/src/cmd/internal/obj/x86/vex_optabs.go
@@ -0,0 +1,382 @@
+// Code generated by x86avxgen. DO NOT EDIT.
+
+package x86
+
+var vexOptab = []Optab{
+	{AANDNL, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW0, 0xF2}},
+	{AANDNQ, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW1, 0xF2}},
+	{ABEXTRL, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW0, 0xF7}},
+	{ABEXTRQ, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW1, 0xF7}},
+	{ABLSIL, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW0, 0xF3, 03}},
+	{ABLSIQ, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW1, 0xF3, 03}},
+	{ABLSMSKL, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW0, 0xF3, 02}},
+	{ABLSMSKQ, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW1, 0xF3, 02}},
+	{ABLSRL, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW0, 0xF3, 01}},
+	{ABLSRQ, yvex_r2, Pvex, [23]uint8{vexNDD | vexLZ | vex0F38 | vexW1, 0xF3, 01}},
+	{ABZHIL, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW0, 0xF5}},
+	{ABZHIQ, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex0F38 | vexW1, 0xF5}},
+	{AMULXL, yvex_r3, Pvex, [23]uint8{vexNDD | vexLZ | vexF2 | vex0F38 | vexW0, 0xF6}},
+	{AMULXQ, yvex_r3, Pvex, [23]uint8{vexNDD | vexLZ | vexF2 | vex0F38 | vexW1, 0xF6}},
+	{APDEPL, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vexF2 | vex0F38 | vexW0, 0xF5}},
+	{APDEPQ, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vexF2 | vex0F38 | vexW1, 0xF5}},
+	{APEXTL, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vexF3 | vex0F38 | vexW0, 0xF5}},
+	{APEXTQ, yvex_r3, Pvex, [23]uint8{vexNDS | vexLZ | vexF3 | vex0F38 | vexW1, 0xF5}},
+	{ARORXL, yvex_ri3, Pvex, [23]uint8{vexNOVSR | vexLZ | vexF2 | vex0F3A | vexW0, 0xF0}},
+	{ARORXQ, yvex_ri3, Pvex, [23]uint8{vexNOVSR | vexLZ | vexF2 | vex0F3A | vexW1, 0xF0}},
+	{ASARXL, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vexF3 | vex0F38 | vexW0, 0xF7}},
+	{ASARXQ, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vexF3 | vex0F38 | vexW1, 0xF7}},
+	{ASHLXL, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex66 | vex0F38 | vexW0, 0xF7}},
+	{ASHLXQ, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vex66 | vex0F38 | vexW1, 0xF7}},
+	{ASHRXL, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vexF2 | vex0F38 | vexW0, 0xF7}},
+	{ASHRXQ, yvex_vmr3, Pvex, [23]uint8{vexNDS | vexLZ | vexF2 | vex0F38 | vexW1, 0xF7}},
+	{AVADDPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x58, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x58}},
+	{AVADDPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x58, vexNDS | vex256 | vex0F | vexWIG, 0x58}},
+	{AVADDSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x58}},
+	{AVADDSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x58}},
+	{AVADDSUBPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD0}},
+	{AVADDSUBPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vexF2 | vex0F | vexWIG, 0xD0, vexNDS | vex256 | vexF2 | vex0F | vexWIG, 0xD0}},
+	{AVAESDEC, yvex_x3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0xDE}},
+	{AVAESDECLAST, yvex_x3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0xDF}},
+	{AVAESENC, yvex_x3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0xDC}},
+	{AVAESENCLAST, yvex_x3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0xDD}},
+	{AVAESIMC, yvex_x2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0xDB}},
+	{AVAESKEYGENASSIST, yvex_xi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0xDF}},
+	{AVANDNPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x55, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x55}},
+	{AVANDNPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x55, vexNDS | vex256 | vex0F | vexWIG, 0x55}},
+	{AVANDPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x54, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x54}},
+	{AVANDPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x54, vexNDS | vex256 | vex0F | vexWIG, 0x54}},
+	{AVBLENDPD, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x0D, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x0D}},
+	{AVBLENDPS, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x0C, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x0C}},
+	{AVBLENDVPD, yvex_xy4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x4B, vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x4B}},
+	{AVBLENDVPS, yvex_xy4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x4A, vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x4A}},
+	{AVBROADCASTF128, yvex_vbroadcastf, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x1A}},
+	{AVBROADCASTI128, yvex_vbroadcastf, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x5A}},
+	{AVBROADCASTSD, yvex_vpbroadcast_sd, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x19, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x19}},
+	{AVBROADCASTSS, yvex_vpbroadcast_ss, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x18, vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x18, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x18, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x18}},
+	{AVCMPPD, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xC2, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xC2}},
+	{AVCMPPS, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0xC2, vexNDS | vex256 | vex0F | vexWIG, 0xC2}},
+	{AVCMPSD, yvex_xxi4, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0xC2}},
+	{AVCMPSS, yvex_xxi4, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0xC2}},
+	{AVCOMISD, yvex_x2, Pvex, [23]uint8{vexNOVSR | vexLIG | vex66 | vex0F | vexWIG, 0x2F}},
+	{AVCOMISS, yvex_x2, Pvex, [23]uint8{vexNOVSR | vexLIG | vex0F | vexWIG, 0x2F}},
+	{AVCVTDQ2PD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0xE6, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0xE6}},
+	{AVCVTDQ2PS, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x5B, vexNOVSR | vex256 | vex0F | vexWIG, 0x5B}},
+	{AVCVTPD2DQX, yvex_x2, Pvex, [23]uint8{vexNOVSR | vex128 | vexF2 | vex0F | vexWIG, 0xE6}},
+	{AVCVTPD2DQY, yvex_y2, Pvex, [23]uint8{vexNOVSR | vex256 | vexF2 | vex0F | vexWIG, 0xE6}},
+	{AVCVTPD2PSX, yvex_x2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x5A}},
+	{AVCVTPD2PSY, yvex_y2, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x5A}},
+	{AVCVTPH2PS, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x13, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x13}},
+	{AVCVTPS2DQ, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x5B, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x5B}},
+	{AVCVTPS2PD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x5A, vexNOVSR | vex256 | vex0F | vexWIG, 0x5A}},
+	{AVCVTPS2PH, yvex_vcvtps2ph, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F3A | vexW0, 0x1D, vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x1D}},
+	{AVCVTSD2SI, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF2 | vex0F | vexW0, 0x2D}},
+	{AVCVTSD2SIQ, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF2 | vex0F | vexW1, 0x2D}},
+	{AVCVTSD2SS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x5A}},
+	{AVCVTSI2SDL, yvex_rx3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexW0, 0x2A}},
+	{AVCVTSI2SDQ, yvex_rx3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexW1, 0x2A}},
+	{AVCVTSI2SSL, yvex_rx3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexW0, 0x2A}},
+	{AVCVTSI2SSQ, yvex_rx3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexW1, 0x2A}},
+	{AVCVTSS2SD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x5A}},
+	{AVCVTSS2SI, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF3 | vex0F | vexW0, 0x2D}},
+	{AVCVTSS2SIQ, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF3 | vex0F | vexW1, 0x2D}},
+	{AVCVTTPD2DQX, yvex_x2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0xE6}},
+	{AVCVTTPD2DQY, yvex_y2, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0xE6}},
+	{AVCVTTPS2DQ, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x5B, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x5B}},
+	{AVCVTTSD2SI, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF2 | vex0F | vexW0, 0x2C}},
+	{AVCVTTSD2SIQ, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF2 | vex0F | vexW1, 0x2C}},
+	{AVCVTTSS2SI, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF3 | vex0F | vexW0, 0x2C}},
+	{AVCVTTSS2SIQ, yvex_vcvtsd2si, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF3 | vex0F | vexW1, 0x2C}},
+	{AVDIVPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x5E, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x5E}},
+	{AVDIVPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x5E, vexNDS | vex256 | vex0F | vexWIG, 0x5E}},
+	{AVDIVSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x5E}},
+	{AVDIVSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x5E}},
+	{AVDPPD, yvex_xxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x41}},
+	{AVDPPS, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x40, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x40}},
+	{AVEXTRACTF128, yvex_yi3, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F3A | vexW0, 0x19}},
+	{AVEXTRACTI128, yvex_yi3, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F3A | vexW0, 0x39}},
+	{AVEXTRACTPS, yvex_vpextr, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x17}},
+	{AVFMADD132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x98, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x98}},
+	{AVFMADD132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x98, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x98}},
+	{AVFMADD132SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0x99}},
+	{AVFMADD132SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0x99}},
+	{AVFMADD213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xA8, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xA8}},
+	{AVFMADD213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xA8, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xA8}},
+	{AVFMADD213SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xA9}},
+	{AVFMADD213SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xA9}},
+	{AVFMADD231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xB8, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xB8}},
+	{AVFMADD231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xB8, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xB8}},
+	{AVFMADD231SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xB9}},
+	{AVFMADD231SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xB9}},
+	{AVFMADDSUB132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x96, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x96}},
+	{AVFMADDSUB132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x96, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x96}},
+	{AVFMADDSUB213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xA6, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xA6}},
+	{AVFMADDSUB213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xA6, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xA6}},
+	{AVFMADDSUB231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xB6, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xB6}},
+	{AVFMADDSUB231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xB6, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xB6}},
+	{AVFMSUB132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x9A, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x9A}},
+	{AVFMSUB132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x9A, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x9A}},
+	{AVFMSUB132SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0x9B}},
+	{AVFMSUB132SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0x9B}},
+	{AVFMSUB213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xAA, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xAA}},
+	{AVFMSUB213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xAA, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xAA}},
+	{AVFMSUB213SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xAB}},
+	{AVFMSUB213SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xAB}},
+	{AVFMSUB231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xBA, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xBA}},
+	{AVFMSUB231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xBA, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xBA}},
+	{AVFMSUB231SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xBB}},
+	{AVFMSUB231SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xBB}},
+	{AVFMSUBADD132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x97, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x97}},
+	{AVFMSUBADD132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x97, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x97}},
+	{AVFMSUBADD213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xA7, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xA7}},
+	{AVFMSUBADD213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xA7, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xA7}},
+	{AVFMSUBADD231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xB7, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xB7}},
+	{AVFMSUBADD231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xB7, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xB7}},
+	{AVFNMADD132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x9C, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x9C}},
+	{AVFNMADD132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x9C, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x9C}},
+	{AVFNMADD132SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0x9D}},
+	{AVFNMADD132SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0x9D}},
+	{AVFNMADD213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xAC, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xAC}},
+	{AVFNMADD213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xAC, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xAC}},
+	{AVFNMADD213SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xAD}},
+	{AVFNMADD213SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xAD}},
+	{AVFNMADD231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xBC, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xBC}},
+	{AVFNMADD231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xBC, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xBC}},
+	{AVFNMADD231SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xBD}},
+	{AVFNMADD231SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xBD}},
+	{AVFNMSUB132PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0x9E, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0x9E}},
+	{AVFNMSUB132PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0x9E, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0x9E}},
+	{AVFNMSUB132SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0x9F}},
+	{AVFNMSUB132SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0x9F}},
+	{AVFNMSUB213PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xAE, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xAE}},
+	{AVFNMSUB213PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xAE, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xAE}},
+	{AVFNMSUB213SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xAF}},
+	{AVFNMSUB213SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xAF}},
+	{AVFNMSUB231PD, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW1, 0xBE, vexDDS | vex256 | vex66 | vex0F38 | vexW1, 0xBE}},
+	{AVFNMSUB231PS, yvex_xy3, Pvex, [23]uint8{vexDDS | vex128 | vex66 | vex0F38 | vexW0, 0xBE, vexDDS | vex256 | vex66 | vex0F38 | vexW0, 0xBE}},
+	{AVFNMSUB231SD, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW1, 0xBF}},
+	{AVFNMSUB231SS, yvex_x3, Pvex, [23]uint8{vexDDS | vexLIG | vex66 | vex0F38 | vexW0, 0xBF}},
+	{AVHADDPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x7C, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x7C}},
+	{AVHADDPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vexF2 | vex0F | vexWIG, 0x7C, vexNDS | vex256 | vexF2 | vex0F | vexWIG, 0x7C}},
+	{AVHSUBPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x7D, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x7D}},
+	{AVHSUBPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vexF2 | vex0F | vexWIG, 0x7D, vexNDS | vex256 | vexF2 | vex0F | vexWIG, 0x7D}},
+	{AVINSERTF128, yvex_xyi4, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x18}},
+	{AVINSERTI128, yvex_xyi4, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x38}},
+	{AVINSERTPS, yvex_xxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x21}},
+	{AVLDDQU, yvex_mxy, Pvex, [23]uint8{vexNOVSR | vex128 | vexF2 | vex0F | vexWIG, 0xF0, vexNOVSR | vex256 | vexF2 | vex0F | vexWIG, 0xF0}},
+	{AVLDMXCSR, yvex_m, Pvex, [23]uint8{vexNOVSR | vexLZ | vex0F | vexWIG, 0xAE, 02}},
+	{AVMASKMOVDQU, yvex_xx2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0xF7}},
+	{AVMASKMOVPD, yvex_vblendvpd, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x2F, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x2F, vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x2D, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x2D}},
+	{AVMASKMOVPS, yvex_vblendvpd, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x2E, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x2E, vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x2C, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x2C}},
+	{AVMAXPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x5F, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x5F}},
+	{AVMAXPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x5F, vexNDS | vex256 | vex0F | vexWIG, 0x5F}},
+	{AVMAXSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x5F}},
+	{AVMAXSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x5F}},
+	{AVMINPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x5D, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x5D}},
+	{AVMINPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x5D, vexNDS | vex256 | vex0F | vexWIG, 0x5D}},
+	{AVMINSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x5D}},
+	{AVMINSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x5D}},
+	{AVMOVAPD, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x28, vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x29, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x28, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x29}},
+	{AVMOVAPS, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x28, vexNOVSR | vex128 | vex0F | vexWIG, 0x29, vexNOVSR | vex256 | vex0F | vexWIG, 0x28, vexNOVSR | vex256 | vex0F | vexWIG, 0x29}},
+	{AVMOVD, yvex_vmovd, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexW0, 0x7E, vexNOVSR | vex128 | vex66 | vex0F | vexW0, 0x6E}},
+	{AVMOVDDUP, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vexF2 | vex0F | vexWIG, 0x12, vexNOVSR | vex256 | vexF2 | vex0F | vexWIG, 0x12}},
+	{AVMOVDQA, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x6F, vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x7F, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x6F, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x7F}},
+	{AVMOVDQU, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x6F, vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x7F, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x6F, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x7F}},
+	{AVMOVHLPS, yvex_xx3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x12}},
+	{AVMOVHPD, yvex_vmovhpd, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x17, vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x16}},
+	{AVMOVHPS, yvex_vmovhpd, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x17, vexNDS | vex128 | vex0F | vexWIG, 0x16}},
+	{AVMOVLHPS, yvex_xx3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x16}},
+	{AVMOVLPD, yvex_vmovhpd, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x13, vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x12}},
+	{AVMOVLPS, yvex_vmovhpd, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x13, vexNDS | vex128 | vex0F | vexWIG, 0x12}},
+	{AVMOVMSKPD, yvex_xyr2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x50, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x50}},
+	{AVMOVMSKPS, yvex_xyr2, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x50, vexNOVSR | vex256 | vex0F | vexWIG, 0x50}},
+	{AVMOVNTDQ, yvex_vmovntdq, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0xE7, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0xE7}},
+	{AVMOVNTDQA, yvex_mxy, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x2A, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x2A}},
+	{AVMOVNTPD, yvex_vmovntdq, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x2B, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x2B}},
+	{AVMOVNTPS, yvex_vmovntdq, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x2B, vexNOVSR | vex256 | vex0F | vexWIG, 0x2B}},
+	{AVMOVQ, yvex_vmovq, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexW1, 0x7E, vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x7E, vexNOVSR | vex128 | vex66 | vex0F | vexW1, 0x6E, vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x7E, vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0xD6}},
+	{AVMOVSD, yvex_vmov, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF2 | vex0F | vexWIG, 0x11, vexNOVSR | vexLIG | vexF2 | vex0F | vexWIG, 0x10, vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x10, vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x11}},
+	{AVMOVSHDUP, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x16, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x16}},
+	{AVMOVSLDUP, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x12, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x12}},
+	{AVMOVSS, yvex_vmov, Pvex, [23]uint8{vexNOVSR | vexLIG | vexF3 | vex0F | vexWIG, 0x11, vexNOVSR | vexLIG | vexF3 | vex0F | vexWIG, 0x10, vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x10, vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x11}},
+	{AVMOVUPD, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x10, vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x11, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x10, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x11}},
+	{AVMOVUPS, yvex_vmovdqa, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x10, vexNOVSR | vex128 | vex0F | vexWIG, 0x11, vexNOVSR | vex256 | vex0F | vexWIG, 0x10, vexNOVSR | vex256 | vex0F | vexWIG, 0x11}},
+	{AVMPSADBW, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x42, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x42}},
+	{AVMULPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x59, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x59}},
+	{AVMULPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x59, vexNDS | vex256 | vex0F | vexWIG, 0x59}},
+	{AVMULSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x59}},
+	{AVMULSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x59}},
+	{AVORPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x56, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x56}},
+	{AVORPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x56, vexNDS | vex256 | vex0F | vexWIG, 0x56}},
+	{AVPABSB, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x1C, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x1C}},
+	{AVPABSD, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x1E, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x1E}},
+	{AVPABSW, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x1D, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x1D}},
+	{AVPACKSSDW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x6B, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x6B}},
+	{AVPACKSSWB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x63, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x63}},
+	{AVPACKUSDW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x2B, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x2B}},
+	{AVPACKUSWB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x67, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x67}},
+	{AVPADDB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xFC, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xFC}},
+	{AVPADDD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xFE, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xFE}},
+	{AVPADDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD4, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD4}},
+	{AVPADDSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xEC, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xEC}},
+	{AVPADDSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xED, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xED}},
+	{AVPADDUSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDC, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDC}},
+	{AVPADDUSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDD, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDD}},
+	{AVPADDW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xFD, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xFD}},
+	{AVPALIGNR, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x0F, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x0F}},
+	{AVPAND, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDB, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDB}},
+	{AVPANDN, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDF, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDF}},
+	{AVPAVGB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE0}},
+	{AVPAVGW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE3, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE3}},
+	{AVPBLENDD, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x02, vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x02}},
+	{AVPBLENDVB, yvex_xy4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x4C, vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x4C}},
+	{AVPBLENDW, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x0E, vexNDS | vex256 | vex66 | vex0F3A | vexWIG, 0x0E}},
+	{AVPBROADCASTB, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x78, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x78}},
+	{AVPBROADCASTD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x58, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x58}},
+	{AVPBROADCASTQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x59, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x59}},
+	{AVPBROADCASTW, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x79, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x79}},
+	{AVPCLMULQDQ, yvex_xxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexWIG, 0x44}},
+	{AVPCMPEQB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x74, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x74}},
+	{AVPCMPEQD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x76, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x76}},
+	{AVPCMPEQQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x29, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x29}},
+	{AVPCMPEQW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x75, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x75}},
+	{AVPCMPESTRI, yvex_xi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x61}},
+	{AVPCMPESTRM, yvex_xi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x60}},
+	{AVPCMPGTB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x64, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x64}},
+	{AVPCMPGTD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x66, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x66}},
+	{AVPCMPGTQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x37, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x37}},
+	{AVPCMPGTW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x65, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x65}},
+	{AVPCMPISTRI, yvex_xi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x63}},
+	{AVPCMPISTRM, yvex_xi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x62}},
+	{AVPERM2F128, yvex_yyi4, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x06}},
+	{AVPERM2I128, yvex_yyi4, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F3A | vexW0, 0x46}},
+	{AVPERMD, yvex_yy3, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x36}},
+	{AVPERMILPD, yvex_vpermilp, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x05, vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x0D, vexNOVSR | vex256 | vex66 | vex0F3A | vexW0, 0x05, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x0D}},
+	{AVPERMILPS, yvex_vpermilp, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x04, vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x0C, vexNOVSR | vex256 | vex66 | vex0F3A | vexW0, 0x04, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x0C}},
+	{AVPERMPD, yvex_vpermpd, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F3A | vexW1, 0x01}},
+	{AVPERMPS, yvex_yy3, Pvex, [23]uint8{vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x16}},
+	{AVPERMQ, yvex_vpermpd, Pvex, [23]uint8{vexNOVSR | vex256 | vex66 | vex0F3A | vexW1, 0x00}},
+	{AVPEXTRB, yvex_vpextr, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x14}},
+	{AVPEXTRD, yvex_vpextr, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x16}},
+	{AVPEXTRQ, yvex_vpextr, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexW1, 0x16}},
+	{AVPEXTRW, yvex_vpextrw, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexW0, 0xC5, vexNOVSR | vex128 | vex66 | vex0F3A | vexW0, 0x15}},
+	{AVPHADDD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x02, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x02}},
+	{AVPHADDSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x03, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x03}},
+	{AVPHADDW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x01, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x01}},
+	{AVPHMINPOSUW, yvex_x2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x41}},
+	{AVPHSUBD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x06, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x06}},
+	{AVPHSUBSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x07, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x07}},
+	{AVPHSUBW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x05, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x05}},
+	{AVPINSRB, yvex_rxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x20}},
+	{AVPINSRD, yvex_rxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW0, 0x22}},
+	{AVPINSRQ, yvex_rxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F3A | vexW1, 0x22}},
+	{AVPINSRW, yvex_rxi4, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexW0, 0xC4}},
+	{AVPMADDUBSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x04, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x04}},
+	{AVPMADDWD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF5, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF5}},
+	{AVPMASKMOVD, yvex_vblendvpd, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x8E, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x8E, vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x8C, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x8C}},
+	{AVPMASKMOVQ, yvex_vblendvpd, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW1, 0x8E, vexNDS | vex256 | vex66 | vex0F38 | vexW1, 0x8E, vexNDS | vex128 | vex66 | vex0F38 | vexW1, 0x8C, vexNDS | vex256 | vex66 | vex0F38 | vexW1, 0x8C}},
+	{AVPMAXSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3C, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3C}},
+	{AVPMAXSD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3D, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3D}},
+	{AVPMAXSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xEE, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xEE}},
+	{AVPMAXUB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDE, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDE}},
+	{AVPMAXUD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3F, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3F}},
+	{AVPMAXUW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3E, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3E}},
+	{AVPMINSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x38, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x38}},
+	{AVPMINSD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x39, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x39}},
+	{AVPMINSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xEA, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xEA}},
+	{AVPMINUB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xDA, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xDA}},
+	{AVPMINUD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3B, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3B}},
+	{AVPMINUW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x3A, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x3A}},
+	{AVPMOVMSKB, yvex_xyr2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0xD7, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0xD7}},
+	{AVPMOVSXBD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x21, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x21}},
+	{AVPMOVSXBQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x22, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x22}},
+	{AVPMOVSXBW, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x20, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x20}},
+	{AVPMOVSXDQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x25, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x25}},
+	{AVPMOVSXWD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x23, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x23}},
+	{AVPMOVSXWQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x24, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x24}},
+	{AVPMOVZXBD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x31, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x31}},
+	{AVPMOVZXBQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x32, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x32}},
+	{AVPMOVZXBW, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x30, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x30}},
+	{AVPMOVZXDQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x35, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x35}},
+	{AVPMOVZXWD, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x33, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x33}},
+	{AVPMOVZXWQ, yvex_vpbroadcast, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x34, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x34}},
+	{AVPMULDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x28, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x28}},
+	{AVPMULHRSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x0B, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x0B}},
+	{AVPMULHUW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE4, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE4}},
+	{AVPMULHW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE5, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE5}},
+	{AVPMULLD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x40, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x40}},
+	{AVPMULLW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD5, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD5}},
+	{AVPMULUDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF4, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF4}},
+	{AVPOR, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xEB, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xEB}},
+	{AVPSADBW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF6, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF6}},
+	{AVPSHUFB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x00, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x00}},
+	{AVPSHUFD, yvex_xyi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x70, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x70, vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x70, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x70}},
+	{AVPSHUFHW, yvex_xyi3, Pvex, [23]uint8{vexNOVSR | vex128 | vexF3 | vex0F | vexWIG, 0x70, vexNOVSR | vex256 | vexF3 | vex0F | vexWIG, 0x70}},
+	{AVPSHUFLW, yvex_xyi3, Pvex, [23]uint8{vexNOVSR | vex128 | vexF2 | vex0F | vexWIG, 0x70, vexNOVSR | vex256 | vexF2 | vex0F | vexWIG, 0x70}},
+	{AVPSIGNB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x08, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x08}},
+	{AVPSIGND, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x0A, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x0A}},
+	{AVPSIGNW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexWIG, 0x09, vexNDS | vex256 | vex66 | vex0F38 | vexWIG, 0x09}},
+	{AVPSLLD, yvex_shift, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x72, 0xF0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x72, 0xF0, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0xF2, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0xF2}},
+	{AVPSLLDQ, yvex_shift_dq, Pvex, [23]uint8{vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x73, 0xF8, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x73, 0xF8}},
+	{AVPSLLQ, yvex_shift, Pvex, [23]uint8{vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x73, 0xF0, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x73, 0xF0, vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF3, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF3}},
+	{AVPSLLVD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x47, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x47}},
+	{AVPSLLVQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW1, 0x47, vexNDS | vex256 | vex66 | vex0F38 | vexW1, 0x47}},
+	{AVPSLLW, yvex_vps, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF1, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x71, 0xF0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF1, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x71, 0xF0}},
+	{AVPSRAD, yvex_vps, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE2, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x72, 0xE0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE2, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x72, 0xE0}},
+	{AVPSRAVD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x46, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x46}},
+	{AVPSRAW, yvex_vps, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE1, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x71, 0xE0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE1, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x71, 0xE0}},
+	{AVPSRLD, yvex_shift, Pvex, [23]uint8{vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x72, 0xD0, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x72, 0xD0, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0xD2, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0xD2}},
+	{AVPSRLDQ, yvex_shift_dq, Pvex, [23]uint8{vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x73, 0xD8, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x73, 0xD8}},
+	{AVPSRLQ, yvex_shift, Pvex, [23]uint8{vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x73, 0xD0, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x73, 0xD0, vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD3, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD3}},
+	{AVPSRLVD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW0, 0x45, vexNDS | vex256 | vex66 | vex0F38 | vexW0, 0x45}},
+	{AVPSRLVQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F38 | vexW1, 0x45, vexNDS | vex256 | vex66 | vex0F38 | vexW1, 0x45}},
+	{AVPSRLW, yvex_vps, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD1, vexNDD | vex128 | vex66 | vex0F | vexWIG, 0x71, 0xD0, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD1, vexNDD | vex256 | vex66 | vex0F | vexWIG, 0x71, 0xD0}},
+	{AVPSUBB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF8, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF8}},
+	{AVPSUBD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xFA, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xFA}},
+	{AVPSUBQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xFB, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xFB}},
+	{AVPSUBSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE8, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE8}},
+	{AVPSUBSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xE9, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xE9}},
+	{AVPSUBUSB, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD8, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD8}},
+	{AVPSUBUSW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xD9, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xD9}},
+	{AVPSUBW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xF9, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xF9}},
+	{AVPTEST, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexWIG, 0x17, vexNOVSR | vex256 | vex66 | vex0F38 | vexWIG, 0x17}},
+	{AVPUNPCKHBW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x68, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x68}},
+	{AVPUNPCKHDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x6A, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x6A}},
+	{AVPUNPCKHQDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x6D, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x6D}},
+	{AVPUNPCKHWD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x69, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x69}},
+	{AVPUNPCKLBW, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x60, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x60}},
+	{AVPUNPCKLDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x62, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x62}},
+	{AVPUNPCKLQDQ, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x6C, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x6C}},
+	{AVPUNPCKLWD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x61, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x61}},
+	{AVPXOR, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xEF, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xEF}},
+	{AVRCPPS, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x53, vexNOVSR | vex256 | vex0F | vexWIG, 0x53}},
+	{AVRCPSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x53}},
+	{AVROUNDPD, yvex_xyi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x09, vexNOVSR | vex256 | vex66 | vex0F3A | vexWIG, 0x09}},
+	{AVROUNDPS, yvex_xyi3, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F3A | vexWIG, 0x08, vexNOVSR | vex256 | vex66 | vex0F3A | vexWIG, 0x08}},
+	{AVROUNDSD, yvex_xxi4, Pvex, [23]uint8{vexNDS | vexLIG | vex66 | vex0F3A | vexWIG, 0x0B}},
+	{AVROUNDSS, yvex_xxi4, Pvex, [23]uint8{vexNDS | vexLIG | vex66 | vex0F3A | vexWIG, 0x0A}},
+	{AVRSQRTPS, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x52, vexNOVSR | vex256 | vex0F | vexWIG, 0x52}},
+	{AVRSQRTSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x52}},
+	{AVSHUFPD, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0xC6, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0xC6}},
+	{AVSHUFPS, yvex_vpalignr, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0xC6, vexNDS | vex256 | vex0F | vexWIG, 0xC6}},
+	{AVSQRTPD, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F | vexWIG, 0x51, vexNOVSR | vex256 | vex66 | vex0F | vexWIG, 0x51}},
+	{AVSQRTPS, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x51, vexNOVSR | vex256 | vex0F | vexWIG, 0x51}},
+	{AVSQRTSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x51}},
+	{AVSQRTSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x51}},
+	{AVSTMXCSR, yvex_m, Pvex, [23]uint8{vexNOVSR | vexLZ | vex0F | vexWIG, 0xAE, 03}},
+	{AVSUBPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x5C, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x5C}},
+	{AVSUBPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x5C, vexNDS | vex256 | vex0F | vexWIG, 0x5C}},
+	{AVSUBSD, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF2 | vex0F | vexWIG, 0x5C}},
+	{AVSUBSS, yvex_x3, Pvex, [23]uint8{vexNDS | vexLIG | vexF3 | vex0F | vexWIG, 0x5C}},
+	{AVTESTPD, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x0F, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x0F}},
+	{AVTESTPS, yvex_xy2, Pvex, [23]uint8{vexNOVSR | vex128 | vex66 | vex0F38 | vexW0, 0x0E, vexNOVSR | vex256 | vex66 | vex0F38 | vexW0, 0x0E}},
+	{AVUCOMISD, yvex_x2, Pvex, [23]uint8{vexNOVSR | vexLIG | vex66 | vex0F | vexWIG, 0x2E}},
+	{AVUCOMISS, yvex_x2, Pvex, [23]uint8{vexNOVSR | vexLIG | vex0F | vexWIG, 0x2E}},
+	{AVUNPCKHPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x15, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x15}},
+	{AVUNPCKHPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x15, vexNDS | vex256 | vex0F | vexWIG, 0x15}},
+	{AVUNPCKLPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x14, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x14}},
+	{AVUNPCKLPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x14, vexNDS | vex256 | vex0F | vexWIG, 0x14}},
+	{AVXORPD, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex66 | vex0F | vexWIG, 0x57, vexNDS | vex256 | vex66 | vex0F | vexWIG, 0x57}},
+	{AVXORPS, yvex_xy3, Pvex, [23]uint8{vexNDS | vex128 | vex0F | vexWIG, 0x57, vexNDS | vex256 | vex0F | vexWIG, 0x57}},
+	{AVZEROALL, yvex, Pvex, [23]uint8{vexNOVSR | vex256 | vex0F | vexWIG, 0x77}},
+	{AVZEROUPPER, yvex, Pvex, [23]uint8{vexNOVSR | vex128 | vex0F | vexWIG, 0x77}},
+}
diff --git a/src/cmd/internal/obj/x86/ytab.go b/src/cmd/internal/obj/x86/ytab.go
new file mode 100644
index 0000000..dbbef47
--- /dev/null
+++ b/src/cmd/internal/obj/x86/ytab.go
@@ -0,0 +1,40 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x86
+
+type argList [6]uint8
+
+type ytab struct {
+	zcase   uint8
+	zoffset uint8
+
+	// Last arg is usually destination.
+	// For unary instructions unaryDst is used to determine
+	// if single argument is a source or destination.
+	args argList
+}
+
+// Returns true if yt is compatible with args.
+//
+// Elements from args and yt.args are used to
+// to index ycover table like `ycover[args[i]+yt.args[i]]`.
+// This means that args should contain values that already
+// multiplied by Ymax.
+func (yt *ytab) match(args []int) bool {
+	// Trailing Yxxx check is required to avoid a case
+	// where shorter arg list is matched.
+	// If we had exact yt.args length, it could be `yt.argc != len(args)`.
+	if len(args) < len(yt.args) && yt.args[len(args)] != Yxxx {
+		return false
+	}
+
+	for i := range args {
+		if ycover[args[i]+int(yt.args[i])] == 0 {
+			return false
+		}
+	}
+
+	return true
+}
diff --git a/src/cmd/internal/objabi/autotype.go b/src/cmd/internal/objabi/autotype.go
index 17c4293..1b46b0f 100644
--- a/src/cmd/internal/objabi/autotype.go
+++ b/src/cmd/internal/objabi/autotype.go
@@ -34,4 +34,5 @@
 const (
 	A_AUTO = 1 + iota
 	A_PARAM
+	A_DELETED_AUTO
 )
diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go
index e349b41..1bd4bc9 100644
--- a/src/cmd/internal/objabi/flag.go
+++ b/src/cmd/internal/objabi/flag.go
@@ -9,30 +9,13 @@
 	"fmt"
 	"os"
 	"strconv"
+	"strings"
 )
 
-func Flagfn2(string, string, func(string, string)) { panic("flag") }
-
 func Flagcount(name, usage string, val *int) {
 	flag.Var((*count)(val), name, usage)
 }
 
-func Flagint32(name, usage string, val *int32) {
-	flag.Var((*int32Value)(val), name, usage)
-}
-
-func Flagint64(name, usage string, val *int64) {
-	flag.Int64Var(val, name, *val, usage)
-}
-
-func Flagstr(name, usage string, val *string) {
-	flag.StringVar(val, name, *val, usage)
-}
-
-func Flagfn0(name, usage string, f func()) {
-	flag.Var(fn0(f), name, usage)
-}
-
 func Flagfn1(name, usage string, f func(string)) {
 	flag.Var(fn1(f), name, usage)
 }
@@ -49,6 +32,44 @@
 	flag.Parse()
 }
 
+func AddVersionFlag() {
+	flag.Var(versionFlag{}, "V", "print version and exit")
+}
+
+var buildID string // filled in by linker
+
+type versionFlag struct{}
+
+func (versionFlag) IsBoolFlag() bool { return true }
+func (versionFlag) Get() interface{} { return nil }
+func (versionFlag) String() string   { return "" }
+func (versionFlag) Set(s string) error {
+	name := os.Args[0]
+	name = name[strings.LastIndex(name, `/`)+1:]
+	name = name[strings.LastIndex(name, `\`)+1:]
+	name = strings.TrimSuffix(name, ".exe")
+	p := Expstring()
+	if p == DefaultExpstring() {
+		p = ""
+	}
+	sep := ""
+	if p != "" {
+		sep = " "
+	}
+
+	// The go command invokes -V=full to get a unique identifier
+	// for this tool. It is assumed that the release version is sufficient
+	// for releases, but during development we include the full
+	// build ID of the binary, so that if the compiler is changed and
+	// rebuilt, we notice and rebuild all packages.
+	if s == "full" && strings.HasPrefix(Version, "devel") {
+		p += " buildID=" + buildID
+	}
+	fmt.Printf("%s version %s%s%s\n", name, Version, sep, p)
+	os.Exit(0)
+	return nil
+}
+
 // count is a flag.Value that is like a flag.Bool and a flag.Int.
 // If used as -name, it increments the count, but -name=x sets the count.
 // Used for verbose flag -v.
@@ -74,22 +95,18 @@
 	return nil
 }
 
+func (c *count) Get() interface{} {
+	return int(*c)
+}
+
 func (c *count) IsBoolFlag() bool {
 	return true
 }
 
-type int32Value int32
-
-func (i *int32Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 64)
-	*i = int32Value(v)
-	return err
+func (c *count) IsCountFlag() bool {
+	return true
 }
 
-func (i *int32Value) Get() interface{} { return int32(*i) }
-
-func (i *int32Value) String() string { return fmt.Sprint(*i) }
-
 type fn0 func()
 
 func (f fn0) Set(s string) error {
diff --git a/src/cmd/internal/objabi/line.go b/src/cmd/internal/objabi/line.go
index ed509b7..1c671b2 100644
--- a/src/cmd/internal/objabi/line.go
+++ b/src/cmd/internal/objabi/line.go
@@ -44,7 +44,7 @@
 		abs = "??"
 	}
 
-	return filepath.Clean(abs)
+	return abs
 }
 
 // Does s have t as a path prefix?
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index 179f049..2e0b916 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -99,8 +99,15 @@
 	// of a JMP instruction, by encoding the address into the instruction.
 	// The stack nosplit check ignores this since it is not a function call.
 	R_JMPMIPS
-	// R_DWARFREF resolves to the offset of the symbol from its section.
-	R_DWARFREF
+
+	// R_DWARFSECREF resolves to the offset of the symbol from its section.
+	// Target of relocation must be size 4 (in current implementation).
+	R_DWARFSECREF
+
+	// R_DWARFFILEREF resolves to an index into the DWARF .debug_line
+	// file table for the specified file symbol. Must be applied to an
+	// attribute of form DW_FORM_data4.
+	R_DWARFFILEREF
 
 	// Platform dependent relocations. Architectures with fixed width instructions
 	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
@@ -183,6 +190,9 @@
 	// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
 	// address (offset from thread pointer), by encoding it into the instruction.
 	R_ADDRMIPSTLS
+	// R_ADDRCUOFF resolves to a pointer-sized offset from the start of the
+	// symbol's DWARF compile unit.
+	R_ADDRCUOFF
 )
 
 // IsDirectJump returns whether r is a relocation for a direct jump.
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index 182d03f..a6efe9c 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -4,9 +4,9 @@
 
 import "fmt"
 
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLS"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFF"
 
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 129, 136, 144, 152, 160, 166, 172, 178, 188, 197, 208, 219, 229, 238, 248, 262, 276, 292, 306, 320, 331, 345, 360, 377, 395, 416, 426, 437, 450}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 129, 136, 144, 152, 160, 166, 172, 178, 188, 197, 208, 219, 229, 238, 251, 265, 279, 293, 309, 323, 337, 348, 362, 377, 394, 412, 433, 443, 454, 467, 478}
 
 func (i RelocType) String() string {
 	i -= 1
diff --git a/src/cmd/internal/objabi/symkind.go b/src/cmd/internal/objabi/symkind.go
index b037e9e..ea180d0 100644
--- a/src/cmd/internal/objabi/symkind.go
+++ b/src/cmd/internal/objabi/symkind.go
@@ -52,9 +52,10 @@
 	SBSS
 	// Statically data that is initially all 0s and does not contain pointers
 	SNOPTRBSS
-	// Thread-local data that is initally all 0s
+	// Thread-local data that is initially all 0s
 	STLSBSS
 	// Debugging data
 	SDWARFINFO
 	SDWARFRANGE
+	SDWARFLOC
 )
diff --git a/src/cmd/internal/objabi/symkind_string.go b/src/cmd/internal/objabi/symkind_string.go
index 5123dc7..3064c8e 100644
--- a/src/cmd/internal/objabi/symkind_string.go
+++ b/src/cmd/internal/objabi/symkind_string.go
@@ -4,9 +4,9 @@
 
 import "fmt"
 
-const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGE"
+const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOC"
 
-var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72}
+var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81}
 
 func (i SymKind) String() string {
 	if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index 1da0502..eafef6b 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -19,11 +19,14 @@
 }
 
 var (
+	defaultGOROOT string // set by linker
+
 	GOROOT  = envOr("GOROOT", defaultGOROOT)
 	GOARCH  = envOr("GOARCH", defaultGOARCH)
 	GOOS    = envOr("GOOS", defaultGOOS)
 	GO386   = envOr("GO386", defaultGO386)
 	GOARM   = goarm()
+	GOMIPS  = gomips()
 	Version = version
 )
 
@@ -41,6 +44,15 @@
 	panic("unreachable")
 }
 
+func gomips() string {
+	switch v := envOr("GOMIPS", defaultGOMIPS); v {
+	case "hardfloat", "softfloat":
+		return v
+	}
+	log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.")
+	panic("unreachable")
+}
+
 func Getgoextlinkenabled() string {
 	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
 }
diff --git a/src/cmd/internal/objabi/zbootstrap.go b/src/cmd/internal/objabi/zbootstrap.go
index d377d15..796794d 100644
--- a/src/cmd/internal/objabi/zbootstrap.go
+++ b/src/cmd/internal/objabi/zbootstrap.go
@@ -1,15 +1,15 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package objabi
 
 import "runtime"
 
-const defaultGOROOT = `./prebuilts/go/darwin-x86`
 const defaultGO386 = `sse2`
 const defaultGOARM = `7`
+const defaultGOMIPS = `hardfloat`
 const defaultGOOS = runtime.GOOS
 const defaultGOARCH = runtime.GOARCH
 const defaultGO_EXTLINK_ENABLED = ``
-const version = `go1.9`
+const version = `go1.10`
 const stackGuardMultiplier = 1
 const goexperiment = ``
diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go
index d61cb27..6ddf8d6 100644
--- a/src/cmd/internal/objfile/disasm.go
+++ b/src/cmd/internal/objfile/disasm.go
@@ -22,6 +22,7 @@
 	"text/tabwriter"
 
 	"golang.org/x/arch/arm/armasm"
+	"golang.org/x/arch/arm64/arm64asm"
 	"golang.org/x/arch/ppc64/ppc64asm"
 	"golang.org/x/arch/x86/x86asm"
 )
@@ -39,23 +40,23 @@
 }
 
 // Disasm returns a disassembler for the file f.
-func (f *File) Disasm() (*Disasm, error) {
-	syms, err := f.Symbols()
+func (e *Entry) Disasm() (*Disasm, error) {
+	syms, err := e.Symbols()
 	if err != nil {
 		return nil, err
 	}
 
-	pcln, err := f.PCLineTable()
+	pcln, err := e.PCLineTable()
 	if err != nil {
 		return nil, err
 	}
 
-	textStart, textBytes, err := f.Text()
+	textStart, textBytes, err := e.Text()
 	if err != nil {
 		return nil, err
 	}
 
-	goarch := f.GOARCH()
+	goarch := e.GOARCH()
 	disasm := disasms[goarch]
 	byteOrder := byteOrders[goarch]
 	if disasm == nil || byteOrder == nil {
@@ -242,7 +243,7 @@
 				fmt.Fprintf(tw, "  %s:%d\t%#x\t", base(file), line, pc)
 			}
 
-			if size%4 != 0 || d.goarch == "386" || d.goarch == "amd64" {
+			if size%4 != 0 || d.goarch == "386" || d.goarch == "amd64" || d.goarch == "amd64p32" {
 				// Print instruction as bytes.
 				fmt.Fprintf(tw, "%x", code[i:i+size])
 			} else {
@@ -291,7 +292,7 @@
 	}
 }
 
-type lookupFunc func(addr uint64) (sym string, base uint64)
+type lookupFunc = func(addr uint64) (sym string, base uint64)
 type disasmFunc func(code []byte, pc uint64, lookup lookupFunc, ord binary.ByteOrder) (text string, size int)
 
 func disasm_386(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) {
@@ -303,7 +304,7 @@
 }
 
 func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) {
-	inst, err := x86asm.Decode(code, 64)
+	inst, err := x86asm.Decode(code, arch)
 	var text string
 	size := inst.Len
 	if err != nil || size == 0 || inst.Op == 0 {
@@ -348,6 +349,17 @@
 	return text, size
 }
 
+func disasm_arm64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder) (string, int) {
+	inst, err := arm64asm.Decode(code)
+	var text string
+	if err != nil || inst.Op == 0 {
+		text = "?"
+	} else {
+		text = arm64asm.GoSyntax(inst, pc, lookup, textReader{code, pc})
+	}
+	return text, 4
+}
+
 func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder) (string, int) {
 	inst, err := ppc64asm.Decode(code, byteOrder)
 	var text string
@@ -362,20 +374,24 @@
 }
 
 var disasms = map[string]disasmFunc{
-	"386":     disasm_386,
-	"amd64":   disasm_amd64,
-	"arm":     disasm_arm,
-	"ppc64":   disasm_ppc64,
-	"ppc64le": disasm_ppc64,
+	"386":      disasm_386,
+	"amd64":    disasm_amd64,
+	"amd64p32": disasm_amd64,
+	"arm":      disasm_arm,
+	"arm64":    disasm_arm64,
+	"ppc64":    disasm_ppc64,
+	"ppc64le":  disasm_ppc64,
 }
 
 var byteOrders = map[string]binary.ByteOrder{
-	"386":     binary.LittleEndian,
-	"amd64":   binary.LittleEndian,
-	"arm":     binary.LittleEndian,
-	"ppc64":   binary.BigEndian,
-	"ppc64le": binary.LittleEndian,
-	"s390x":   binary.BigEndian,
+	"386":      binary.LittleEndian,
+	"amd64":    binary.LittleEndian,
+	"amd64p32": binary.LittleEndian,
+	"arm":      binary.LittleEndian,
+	"arm64":    binary.LittleEndian,
+	"ppc64":    binary.BigEndian,
+	"ppc64le":  binary.LittleEndian,
+	"s390x":    binary.BigEndian,
 }
 
 type Liner interface {
diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go
index 4ab7e6d..7d5162a 100644
--- a/src/cmd/internal/objfile/elf.go
+++ b/src/cmd/internal/objfile/elf.go
@@ -11,14 +11,14 @@
 	"debug/elf"
 	"encoding/binary"
 	"fmt"
-	"os"
+	"io"
 )
 
 type elfFile struct {
 	elf *elf.File
 }
 
-func openElf(r *os.File) (rawFile, error) {
+func openElf(r io.ReaderAt) (rawFile, error) {
 	f, err := elf.NewFile(r)
 	if err != nil {
 		return nil, err
@@ -99,6 +99,8 @@
 		return "amd64"
 	case elf.EM_ARM:
 		return "arm"
+	case elf.EM_AARCH64:
+		return "arm64"
 	case elf.EM_PPC64:
 		if f.elf.ByteOrder == binary.LittleEndian {
 			return "ppc64le"
diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go
index e075604..51fa6e8 100644
--- a/src/cmd/internal/objfile/goobj.go
+++ b/src/cmd/internal/objfile/goobj.go
@@ -22,12 +22,33 @@
 	f     *os.File // the underlying .o or .a file
 }
 
-func openGoobj(r *os.File) (rawFile, error) {
+func openGoFile(r *os.File) (*File, error) {
 	f, err := goobj.Parse(r, `""`)
 	if err != nil {
 		return nil, err
 	}
-	return &goobjFile{goobj: f, f: r}, nil
+	rf := &goobjFile{goobj: f, f: r}
+	if len(f.Native) == 0 {
+		return &File{r, []*Entry{&Entry{raw: rf}}}, nil
+	}
+	entries := make([]*Entry, len(f.Native)+1)
+	entries[0] = &Entry{
+		raw: rf,
+	}
+L:
+	for i, nr := range f.Native {
+		for _, try := range openers {
+			if raw, err := try(nr); err == nil {
+				entries[i+1] = &Entry{
+					name: nr.Name,
+					raw:  raw,
+				}
+				continue L
+			}
+		}
+		return nil, fmt.Errorf("open %s: unrecognized archive member %s", r.Name(), nr.Name)
+	}
+	return &File{r, entries}, nil
 }
 
 func goobjName(id goobj.SymID) string {
@@ -81,7 +102,7 @@
 }
 
 func (f *goobjFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
-	// Should never be called.  We implement Liner below, callers
+	// Should never be called. We implement Liner below, callers
 	// should use that instead.
 	return 0, nil, nil, fmt.Errorf("pcln not available in go object file")
 }
@@ -90,7 +111,7 @@
 // Returns "",0,nil if unknown.
 // This function implements the Liner interface in preference to pcln() above.
 func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
-	// TODO: this is really inefficient.  Binary search?  Memoize last result?
+	// TODO: this is really inefficient. Binary search? Memoize last result?
 	var arch *sys.Arch
 	for _, a := range sys.Archs {
 		if a.Name == f.goobj.Arch {
diff --git a/src/cmd/internal/objfile/macho.go b/src/cmd/internal/objfile/macho.go
index 1d22a09..7a8999e 100644
--- a/src/cmd/internal/objfile/macho.go
+++ b/src/cmd/internal/objfile/macho.go
@@ -10,7 +10,7 @@
 	"debug/dwarf"
 	"debug/macho"
 	"fmt"
-	"os"
+	"io"
 	"sort"
 )
 
@@ -20,7 +20,7 @@
 	macho *macho.File
 }
 
-func openMacho(r *os.File) (rawFile, error) {
+func openMacho(r io.ReaderAt) (rawFile, error) {
 	f, err := macho.NewFile(r)
 	if err != nil {
 		return nil, err
@@ -30,7 +30,7 @@
 
 func (f *machoFile) symbols() ([]Sym, error) {
 	if f.macho.Symtab == nil {
-		return nil, fmt.Errorf("missing symbol table")
+		return nil, nil
 	}
 
 	// Build sorted list of addresses of all symbols.
diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go
index 2bf6363..10307be 100644
--- a/src/cmd/internal/objfile/objfile.go
+++ b/src/cmd/internal/objfile/objfile.go
@@ -9,6 +9,7 @@
 	"debug/dwarf"
 	"debug/gosym"
 	"fmt"
+	"io"
 	"os"
 	"sort"
 )
@@ -24,8 +25,13 @@
 
 // A File is an opened executable file.
 type File struct {
-	r   *os.File
-	raw rawFile
+	r       *os.File
+	entries []*Entry
+}
+
+type Entry struct {
+	name string
+	raw  rawFile
 }
 
 // A Sym is a symbol defined in an executable file.
@@ -50,9 +56,8 @@
 	String(insnOffset uint64) string
 }
 
-var openers = []func(*os.File) (rawFile, error){
+var openers = []func(io.ReaderAt) (rawFile, error){
 	openElf,
-	openGoobj,
 	openMacho,
 	openPE,
 	openPlan9,
@@ -65,9 +70,12 @@
 	if err != nil {
 		return nil, err
 	}
+	if f, err := openGoFile(r); err == nil {
+		return f, nil
+	}
 	for _, try := range openers {
 		if raw, err := try(r); err == nil {
-			return &File{r, raw}, nil
+			return &File{r, []*Entry{&Entry{raw: raw}}}, nil
 		}
 	}
 	r.Close()
@@ -78,8 +86,44 @@
 	return f.r.Close()
 }
 
+func (f *File) Entries() []*Entry {
+	return f.entries
+}
+
 func (f *File) Symbols() ([]Sym, error) {
-	syms, err := f.raw.symbols()
+	return f.entries[0].Symbols()
+}
+
+func (f *File) PCLineTable() (Liner, error) {
+	return f.entries[0].PCLineTable()
+}
+
+func (f *File) Text() (uint64, []byte, error) {
+	return f.entries[0].Text()
+}
+
+func (f *File) GOARCH() string {
+	return f.entries[0].GOARCH()
+}
+
+func (f *File) LoadAddress() (uint64, error) {
+	return f.entries[0].LoadAddress()
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+	return f.entries[0].DWARF()
+}
+
+func (f *File) Disasm() (*Disasm, error) {
+	return f.entries[0].Disasm()
+}
+
+func (e *Entry) Name() string {
+	return e.name
+}
+
+func (e *Entry) Symbols() ([]Sym, error) {
+	syms, err := e.raw.symbols()
 	if err != nil {
 		return nil, err
 	}
@@ -93,37 +137,37 @@
 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() (Liner, error) {
+func (e *Entry) PCLineTable() (Liner, error) {
 	// If the raw file implements Liner directly, use that.
 	// Currently, only Go intermediate objects and archives (goobj) use this path.
-	if pcln, ok := f.raw.(Liner); ok {
+	if pcln, ok := e.raw.(Liner); ok {
 		return pcln, nil
 	}
 	// Otherwise, read the pcln tables and build a Liner out of that.
-	textStart, symtab, pclntab, err := f.raw.pcln()
+	textStart, symtab, pclntab, err := e.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 (e *Entry) Text() (uint64, []byte, error) {
+	return e.raw.text()
 }
 
-func (f *File) GOARCH() string {
-	return f.raw.goarch()
+func (e *Entry) GOARCH() string {
+	return e.raw.goarch()
 }
 
 // LoadAddress returns the expected load address of the file.
 // This differs from the actual load address for a position-independent
 // executable.
-func (f *File) LoadAddress() (uint64, error) {
-	return f.raw.loadAddress()
+func (e *Entry) LoadAddress() (uint64, error) {
+	return e.raw.loadAddress()
 }
 
 // DWARF returns DWARF debug data for the file, if any.
 // This is for cmd/pprof to locate cgo functions.
-func (f *File) DWARF() (*dwarf.Data, error) {
-	return f.raw.dwarf()
+func (e *Entry) DWARF() (*dwarf.Data, error) {
+	return e.raw.dwarf()
 }
diff --git a/src/cmd/internal/objfile/pe.go b/src/cmd/internal/objfile/pe.go
index 46b2317..80db6f0 100644
--- a/src/cmd/internal/objfile/pe.go
+++ b/src/cmd/internal/objfile/pe.go
@@ -10,7 +10,7 @@
 	"debug/dwarf"
 	"debug/pe"
 	"fmt"
-	"os"
+	"io"
 	"sort"
 )
 
@@ -18,17 +18,11 @@
 	pe *pe.File
 }
 
-func openPE(r *os.File) (rawFile, error) {
+func openPE(r io.ReaderAt) (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
 }
 
diff --git a/src/cmd/internal/objfile/plan9obj.go b/src/cmd/internal/objfile/plan9obj.go
index 3e34f65..da0b345 100644
--- a/src/cmd/internal/objfile/plan9obj.go
+++ b/src/cmd/internal/objfile/plan9obj.go
@@ -11,7 +11,7 @@
 	"debug/plan9obj"
 	"errors"
 	"fmt"
-	"os"
+	"io"
 	"sort"
 )
 
@@ -28,7 +28,7 @@
 	plan9 *plan9obj.File
 }
 
-func openPlan9(r *os.File) (rawFile, error) {
+func openPlan9(r io.ReaderAt) (rawFile, error) {
 	f, err := plan9obj.NewFile(r)
 	if err != nil {
 		return nil, err
diff --git a/src/cmd/internal/src/pos.go b/src/cmd/internal/src/pos.go
index a1ea3fc..10fa924 100644
--- a/src/cmd/internal/src/pos.go
+++ b/src/cmd/internal/src/pos.go
@@ -79,15 +79,15 @@
 func (p Pos) SymFilename() string { return p.base.SymFilename() }
 
 func (p Pos) String() string {
-	return p.Format(true)
+	return p.Format(true, true)
 }
 
 // Format formats a position as "filename:line" or "filename:line:column",
-// controlled by the showCol flag.
-// If the position is relative to a line directive, the original position
-// is appended in square brackets without column (since the column doesn't
-// change).
-func (p Pos) Format(showCol bool) string {
+// controlled by the showCol flag. A position relative to a line directive
+// is always formatted without column information. In that case, if showOrig
+// is set, the original position (again controlled by showCol) is appended
+// in square brackets: "filename:line[origfile:origline:origcolumn]".
+func (p Pos) Format(showCol, showOrig bool) string {
 	if !p.IsKnown() {
 		return "<unknown line number>"
 	}
@@ -105,8 +105,11 @@
 	// that's provided via a line directive).
 	// TODO(gri) This may not be true if we have an inlining base.
 	// We may want to differentiate at some point.
-	return format(p.RelFilename(), p.RelLine(), 0, false) +
-		"[" + format(p.Filename(), p.Line(), p.Col(), showCol) + "]"
+	s := format(p.RelFilename(), p.RelLine(), 0, false)
+	if showOrig {
+		s += "[" + format(p.Filename(), p.Line(), p.Col(), showCol) + "]"
+	}
+	return s
 }
 
 // format formats a (filename, line, col) tuple as "filename:line" (showCol
@@ -155,8 +158,8 @@
 // NewLinePragmaBase returns a new *PosBase for a line pragma of the form
 //      //line filename:line
 // at position pos.
-func NewLinePragmaBase(pos Pos, filename string, line uint) *PosBase {
-	return &PosBase{pos, filename, filename, FileSymPrefix + filename, line - 1, -1}
+func NewLinePragmaBase(pos Pos, filename, absFilename string, line uint) *PosBase {
+	return &PosBase{pos, filename, absFilename, FileSymPrefix + absFilename, line - 1, -1}
 }
 
 // NewInliningBase returns a copy of the old PosBase with the given inlining
diff --git a/src/cmd/internal/src/pos_test.go b/src/cmd/internal/src/pos_test.go
index a101bc1..b06d382 100644
--- a/src/cmd/internal/src/pos_test.go
+++ b/src/cmd/internal/src/pos_test.go
@@ -12,16 +12,16 @@
 func TestPos(t *testing.T) {
 	f0 := NewFileBase("", "")
 	f1 := NewFileBase("f1", "f1")
-	f2 := NewLinePragmaBase(Pos{}, "f2", 10)
-	f3 := NewLinePragmaBase(MakePos(f1, 10, 1), "f3", 100)
-	f4 := NewLinePragmaBase(MakePos(f3, 10, 1), "f4", 100)
+	f2 := NewLinePragmaBase(Pos{}, "f2", "f2", 10)
+	f3 := NewLinePragmaBase(MakePos(f1, 10, 1), "f3", "f3", 100)
+	f4 := NewLinePragmaBase(MakePos(f3, 10, 1), "f4", "f4", 100)
 
 	// line directives from issue #19392
 	fp := NewFileBase("p.go", "p.go")
-	fc := NewLinePragmaBase(MakePos(fp, 3, 0), "c.go", 10)
-	ft := NewLinePragmaBase(MakePos(fp, 6, 0), "t.go", 20)
-	fv := NewLinePragmaBase(MakePos(fp, 9, 0), "v.go", 30)
-	ff := NewLinePragmaBase(MakePos(fp, 12, 0), "f.go", 40)
+	fc := NewLinePragmaBase(MakePos(fp, 3, 0), "c.go", "c.go", 10)
+	ft := NewLinePragmaBase(MakePos(fp, 6, 0), "t.go", "t.go", 20)
+	fv := NewLinePragmaBase(MakePos(fp, 9, 0), "v.go", "v.go", 30)
+	ff := NewLinePragmaBase(MakePos(fp, 12, 0), "f.go", "f.go", 40)
 
 	for _, test := range []struct {
 		pos    Pos
diff --git a/src/cmd/internal/src/xpos_test.go b/src/cmd/internal/src/xpos_test.go
index 4cfeedc..8ac9c9d 100644
--- a/src/cmd/internal/src/xpos_test.go
+++ b/src/cmd/internal/src/xpos_test.go
@@ -19,7 +19,7 @@
 func TestConversion(t *testing.T) {
 	b1 := NewFileBase("b1", "b1")
 	b2 := NewFileBase("b2", "b2")
-	b3 := NewLinePragmaBase(MakePos(b1, 10, 0), "b3", 123)
+	b3 := NewLinePragmaBase(MakePos(b1, 10, 0), "b3", "b3", 123)
 
 	var tab PosTable
 	for _, want := range []Pos{
diff --git a/src/cmd/internal/test2json/test2json.go b/src/cmd/internal/test2json/test2json.go
new file mode 100644
index 0000000..483fb1d
--- /dev/null
+++ b/src/cmd/internal/test2json/test2json.go
@@ -0,0 +1,445 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package test2json implements conversion of test binary output to JSON.
+// It is used by cmd/test2json and cmd/go.
+//
+// See the cmd/test2json documentation for details of the JSON encoding.
+package test2json
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+	"time"
+	"unicode"
+	"unicode/utf8"
+)
+
+// Mode controls details of the conversion.
+type Mode int
+
+const (
+	Timestamp Mode = 1 << iota // include Time in events
+)
+
+// event is the JSON struct we emit.
+type event struct {
+	Time    *time.Time `json:",omitempty"`
+	Action  string
+	Package string     `json:",omitempty"`
+	Test    string     `json:",omitempty"`
+	Elapsed *float64   `json:",omitempty"`
+	Output  *textBytes `json:",omitempty"`
+}
+
+// textBytes is a hack to get JSON to emit a []byte as a string
+// without actually copying it to a string.
+// It implements encoding.TextMarshaler, which returns its text form as a []byte,
+// and then json encodes that text form as a string (which was our goal).
+type textBytes []byte
+
+func (b textBytes) MarshalText() ([]byte, error) { return b, nil }
+
+// A converter holds the state of a test-to-JSON conversion.
+// It implements io.WriteCloser; the caller writes test output in,
+// and the converter writes JSON output to w.
+type converter struct {
+	w        io.Writer  // JSON output stream
+	pkg      string     // package to name in events
+	mode     Mode       // mode bits
+	start    time.Time  // time converter started
+	testName string     // name of current test, for output attribution
+	report   []*event   // pending test result reports (nested for subtests)
+	result   string     // overall test result if seen
+	input    lineBuffer // input buffer
+	output   lineBuffer // output buffer
+}
+
+// inBuffer and outBuffer are the input and output buffer sizes.
+// They're variables so that they can be reduced during testing.
+//
+// The input buffer needs to be able to hold any single test
+// directive line we want to recognize, like:
+//
+//     <many spaces> --- PASS: very/nested/s/u/b/t/e/s/t
+//
+// If anyone reports a test directive line > 4k not working, it will
+// be defensible to suggest they restructure their test or test names.
+//
+// The output buffer must be >= utf8.UTFMax, so that it can
+// accumulate any single UTF8 sequence. Lines that fit entirely
+// within the output buffer are emitted in single output events.
+// Otherwise they are split into multiple events.
+// The output buffer size therefore limits the size of the encoding
+// of a single JSON output event. 1k seems like a reasonable balance
+// between wanting to avoid splitting an output line and not wanting to
+// generate enormous output events.
+var (
+	inBuffer  = 4096
+	outBuffer = 1024
+)
+
+// NewConverter returns a "test to json" converter.
+// Writes on the returned writer are written as JSON to w,
+// with minimal delay.
+//
+// The writes to w are whole JSON events ending in \n,
+// so that it is safe to run multiple tests writing to multiple converters
+// writing to a single underlying output stream w.
+// As long as the underlying output w can handle concurrent writes
+// from multiple goroutines, the result will be a JSON stream
+// describing the relative ordering of execution in all the concurrent tests.
+//
+// The mode flag adjusts the behavior of the converter.
+// Passing ModeTime includes event timestamps and elapsed times.
+//
+// The pkg string, if present, specifies the import path to
+// report in the JSON stream.
+func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser {
+	c := new(converter)
+	*c = converter{
+		w:     w,
+		pkg:   pkg,
+		mode:  mode,
+		start: time.Now(),
+		input: lineBuffer{
+			b:    make([]byte, 0, inBuffer),
+			line: c.handleInputLine,
+			part: c.output.write,
+		},
+		output: lineBuffer{
+			b:    make([]byte, 0, outBuffer),
+			line: c.writeOutputEvent,
+			part: c.writeOutputEvent,
+		},
+	}
+	return c
+}
+
+// Write writes the test input to the converter.
+func (c *converter) Write(b []byte) (int, error) {
+	c.input.write(b)
+	return len(b), nil
+}
+
+var (
+	bigPass = []byte("PASS\n")
+	bigFail = []byte("FAIL\n")
+
+	updates = [][]byte{
+		[]byte("=== RUN   "),
+		[]byte("=== PAUSE "),
+		[]byte("=== CONT  "),
+	}
+
+	reports = [][]byte{
+		[]byte("--- PASS: "),
+		[]byte("--- FAIL: "),
+		[]byte("--- SKIP: "),
+		[]byte("--- BENCH: "),
+	}
+
+	fourSpace = []byte("    ")
+
+	skipLinePrefix = []byte("?   \t")
+	skipLineSuffix = []byte("\t[no test files]\n")
+)
+
+// handleInputLine handles a single whole test output line.
+// It must write the line to c.output but may choose to do so
+// before or after emitting other events.
+func (c *converter) handleInputLine(line []byte) {
+	// Final PASS or FAIL.
+	if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) {
+		c.flushReport(0)
+		c.output.write(line)
+		if bytes.Equal(line, bigPass) {
+			c.result = "pass"
+		} else {
+			c.result = "fail"
+		}
+		return
+	}
+
+	// Special case for entirely skipped test binary: "?   \tpkgname\t[no test files]\n" is only line.
+	// Report it as plain output but remember to say skip in the final summary.
+	if bytes.HasPrefix(line, skipLinePrefix) && bytes.HasSuffix(line, skipLineSuffix) && len(c.report) == 0 {
+		c.result = "skip"
+	}
+
+	// "=== RUN   "
+	// "=== PAUSE "
+	// "=== CONT  "
+	origLine := line
+	ok := false
+	indent := 0
+	for _, magic := range updates {
+		if bytes.HasPrefix(line, magic) {
+			ok = true
+			break
+		}
+	}
+	if !ok {
+		// "--- PASS: "
+		// "--- FAIL: "
+		// "--- SKIP: "
+		// "--- BENCH: "
+		// but possibly indented.
+		for bytes.HasPrefix(line, fourSpace) {
+			line = line[4:]
+			indent++
+		}
+		for _, magic := range reports {
+			if bytes.HasPrefix(line, magic) {
+				ok = true
+				break
+			}
+		}
+	}
+
+	if !ok {
+		// Not a special test output line.
+		c.output.write(origLine)
+		return
+	}
+
+	// Parse out action and test name.
+	i := bytes.IndexByte(line, ':') + 1
+	if i == 0 {
+		i = len(updates[0])
+	}
+	action := strings.ToLower(strings.TrimSuffix(strings.TrimSpace(string(line[4:i])), ":"))
+	name := strings.TrimSpace(string(line[i:]))
+
+	e := &event{Action: action}
+	if line[0] == '-' { // PASS or FAIL report
+		// Parse out elapsed time.
+		if i := strings.Index(name, " ("); i >= 0 {
+			if strings.HasSuffix(name, "s)") {
+				t, err := strconv.ParseFloat(name[i+2:len(name)-2], 64)
+				if err == nil {
+					if c.mode&Timestamp != 0 {
+						e.Elapsed = &t
+					}
+				}
+			}
+			name = name[:i]
+		}
+		if len(c.report) < indent {
+			// Nested deeper than expected.
+			// Treat this line as plain output.
+			c.output.write(origLine)
+			return
+		}
+		// Flush reports at this indentation level or deeper.
+		c.flushReport(indent)
+		e.Test = name
+		c.testName = name
+		c.report = append(c.report, e)
+		c.output.write(origLine)
+		return
+	}
+	// === update.
+	// Finish any pending PASS/FAIL reports.
+	c.flushReport(0)
+	c.testName = name
+
+	if action == "pause" {
+		// For a pause, we want to write the pause notification before
+		// delivering the pause event, just so it doesn't look like the test
+		// is generating output immediately after being paused.
+		c.output.write(origLine)
+	}
+	c.writeEvent(e)
+	if action != "pause" {
+		c.output.write(origLine)
+	}
+
+	return
+}
+
+// flushReport flushes all pending PASS/FAIL reports at levels >= depth.
+func (c *converter) flushReport(depth int) {
+	c.testName = ""
+	for len(c.report) > depth {
+		e := c.report[len(c.report)-1]
+		c.report = c.report[:len(c.report)-1]
+		c.writeEvent(e)
+	}
+}
+
+// Close marks the end of the go test output.
+// It flushes any pending input and then output (only partial lines at this point)
+// and then emits the final overall package-level pass/fail event.
+func (c *converter) Close() error {
+	c.input.flush()
+	c.output.flush()
+	e := &event{Action: "fail"}
+	if c.result != "" {
+		e.Action = c.result
+	}
+	if c.mode&Timestamp != 0 {
+		dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds()
+		e.Elapsed = &dt
+	}
+	c.writeEvent(e)
+	return nil
+}
+
+// writeOutputEvent writes a single output event with the given bytes.
+func (c *converter) writeOutputEvent(out []byte) {
+	c.writeEvent(&event{
+		Action: "output",
+		Output: (*textBytes)(&out),
+	})
+}
+
+// writeEvent writes a single event.
+// It adds the package, time (if requested), and test name (if needed).
+func (c *converter) writeEvent(e *event) {
+	e.Package = c.pkg
+	if c.mode&Timestamp != 0 {
+		t := time.Now()
+		e.Time = &t
+	}
+	if e.Test == "" {
+		e.Test = c.testName
+	}
+	js, err := json.Marshal(e)
+	if err != nil {
+		// Should not happen - event is valid for json.Marshal.
+		c.w.Write([]byte(fmt.Sprintf("testjson internal error: %v\n", err)))
+		return
+	}
+	js = append(js, '\n')
+	c.w.Write(js)
+}
+
+// A lineBuffer is an I/O buffer that reacts to writes by invoking
+// input-processing callbacks on whole lines or (for long lines that
+// have been split) line fragments.
+//
+// It should be initialized with b set to a buffer of length 0 but non-zero capacity,
+// and line and part set to the desired input processors.
+// The lineBuffer will call line(x) for any whole line x (including the final newline)
+// that fits entirely in cap(b). It will handle input lines longer than cap(b) by
+// calling part(x) for sections of the line. The line will be split at UTF8 boundaries,
+// and the final call to part for a long line includes the final newline.
+type lineBuffer struct {
+	b    []byte       // buffer
+	mid  bool         // whether we're in the middle of a long line
+	line func([]byte) // line callback
+	part func([]byte) // partial line callback
+}
+
+// write writes b to the buffer.
+func (l *lineBuffer) write(b []byte) {
+	for len(b) > 0 {
+		// Copy what we can into b.
+		m := copy(l.b[len(l.b):cap(l.b)], b)
+		l.b = l.b[:len(l.b)+m]
+		b = b[m:]
+
+		// Process lines in b.
+		i := 0
+		for i < len(l.b) {
+			j := bytes.IndexByte(l.b[i:], '\n')
+			if j < 0 {
+				if !l.mid {
+					if j := bytes.IndexByte(l.b[i:], '\t'); j >= 0 {
+						if isBenchmarkName(bytes.TrimRight(l.b[i:i+j], " ")) {
+							l.part(l.b[i : i+j+1])
+							l.mid = true
+							i += j + 1
+						}
+					}
+				}
+				break
+			}
+			e := i + j + 1
+			if l.mid {
+				// Found the end of a partial line.
+				l.part(l.b[i:e])
+				l.mid = false
+			} else {
+				// Found a whole line.
+				l.line(l.b[i:e])
+			}
+			i = e
+		}
+
+		// Whatever's left in l.b is a line fragment.
+		if i == 0 && len(l.b) == cap(l.b) {
+			// The whole buffer is a fragment.
+			// Emit it as the beginning (or continuation) of a partial line.
+			t := trimUTF8(l.b)
+			l.part(l.b[:t])
+			l.b = l.b[:copy(l.b, l.b[t:])]
+			l.mid = true
+		}
+
+		// There's room for more input.
+		// Slide it down in hope of completing the line.
+		if i > 0 {
+			l.b = l.b[:copy(l.b, l.b[i:])]
+		}
+	}
+}
+
+// flush flushes the line buffer.
+func (l *lineBuffer) flush() {
+	if len(l.b) > 0 {
+		// Must be a line without a \n, so a partial line.
+		l.part(l.b)
+		l.b = l.b[:0]
+	}
+}
+
+var benchmark = []byte("Benchmark")
+
+// isBenchmarkName reports whether b is a valid benchmark name
+// that might appear as the first field in a benchmark result line.
+func isBenchmarkName(b []byte) bool {
+	if !bytes.HasPrefix(b, benchmark) {
+		return false
+	}
+	if len(b) == len(benchmark) { // just "Benchmark"
+		return true
+	}
+	r, _ := utf8.DecodeRune(b[len(benchmark):])
+	return !unicode.IsLower(r)
+}
+
+// trimUTF8 returns a length t as close to len(b) as possible such that b[:t]
+// does not end in the middle of a possibly-valid UTF-8 sequence.
+//
+// If a large text buffer must be split before position i at the latest,
+// splitting at position trimUTF(b[:i]) avoids splitting a UTF-8 sequence.
+func trimUTF8(b []byte) int {
+	// Scan backward to find non-continuation byte.
+	for i := 1; i < utf8.UTFMax && i <= len(b); i++ {
+		if c := b[len(b)-i]; c&0xc0 != 0x80 {
+			switch {
+			case c&0xe0 == 0xc0:
+				if i < 2 {
+					return len(b) - i
+				}
+			case c&0xf0 == 0xe0:
+				if i < 3 {
+					return len(b) - i
+				}
+			case c&0xf8 == 0xf0:
+				if i < 4 {
+					return len(b) - i
+				}
+			}
+			break
+		}
+	}
+	return len(b)
+}
diff --git a/src/cmd/internal/test2json/test2json_test.go b/src/cmd/internal/test2json/test2json_test.go
new file mode 100644
index 0000000..4683907
--- /dev/null
+++ b/src/cmd/internal/test2json/test2json_test.go
@@ -0,0 +1,277 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test2json
+
+import (
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"path/filepath"
+	"reflect"
+	"strings"
+	"testing"
+	"unicode/utf8"
+)
+
+var update = flag.Bool("update", false, "rewrite testdata/*.json files")
+
+func TestGolden(t *testing.T) {
+	files, err := filepath.Glob("testdata/*.test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, file := range files {
+		name := strings.TrimSuffix(filepath.Base(file), ".test")
+		t.Run(name, func(t *testing.T) {
+			orig, err := ioutil.ReadFile(file)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// Test one line written to c at a time.
+			// Assume that's the most likely to be handled correctly.
+			var buf bytes.Buffer
+			c := NewConverter(&buf, "", 0)
+			in := append([]byte{}, orig...)
+			for _, line := range bytes.SplitAfter(in, []byte("\n")) {
+				writeAndKill(c, line)
+			}
+			c.Close()
+
+			if *update {
+				js := strings.TrimSuffix(file, ".test") + ".json"
+				t.Logf("rewriting %s", js)
+				if err := ioutil.WriteFile(js, buf.Bytes(), 0666); err != nil {
+					t.Fatal(err)
+				}
+				return
+			}
+
+			want, err := ioutil.ReadFile(strings.TrimSuffix(file, ".test") + ".json")
+			if err != nil {
+				t.Fatal(err)
+			}
+			diffJSON(t, buf.Bytes(), want)
+			if t.Failed() {
+				// If the line-at-a-time conversion fails, no point testing boundary conditions.
+				return
+			}
+
+			// Write entire input in bulk.
+			t.Run("bulk", func(t *testing.T) {
+				buf.Reset()
+				c = NewConverter(&buf, "", 0)
+				in = append([]byte{}, orig...)
+				writeAndKill(c, in)
+				c.Close()
+				diffJSON(t, buf.Bytes(), want)
+			})
+
+			// Write 2 bytes at a time on even boundaries.
+			t.Run("even2", func(t *testing.T) {
+				buf.Reset()
+				c = NewConverter(&buf, "", 0)
+				in = append([]byte{}, orig...)
+				for i := 0; i < len(in); i += 2 {
+					if i+2 <= len(in) {
+						writeAndKill(c, in[i:i+2])
+					} else {
+						writeAndKill(c, in[i:])
+					}
+				}
+				c.Close()
+				diffJSON(t, buf.Bytes(), want)
+			})
+
+			// Write 2 bytes at a time on odd boundaries.
+			t.Run("odd2", func(t *testing.T) {
+				buf.Reset()
+				c = NewConverter(&buf, "", 0)
+				in = append([]byte{}, orig...)
+				if len(in) > 0 {
+					writeAndKill(c, in[:1])
+				}
+				for i := 1; i < len(in); i += 2 {
+					if i+2 <= len(in) {
+						writeAndKill(c, in[i:i+2])
+					} else {
+						writeAndKill(c, in[i:])
+					}
+				}
+				c.Close()
+				diffJSON(t, buf.Bytes(), want)
+			})
+
+			// Test with very small output buffers, to check that
+			// UTF8 sequences are not broken up.
+			for b := 5; b <= 8; b++ {
+				t.Run(fmt.Sprintf("tiny%d", b), func(t *testing.T) {
+					oldIn := inBuffer
+					oldOut := outBuffer
+					defer func() {
+						inBuffer = oldIn
+						outBuffer = oldOut
+					}()
+					inBuffer = 64
+					outBuffer = b
+					buf.Reset()
+					c = NewConverter(&buf, "", 0)
+					in = append([]byte{}, orig...)
+					writeAndKill(c, in)
+					c.Close()
+					diffJSON(t, buf.Bytes(), want)
+				})
+			}
+		})
+	}
+}
+
+// writeAndKill writes b to w and then fills b with Zs.
+// The filling makes sure that if w is holding onto b for
+// future use, that future use will have obviously wrong data.
+func writeAndKill(w io.Writer, b []byte) {
+	w.Write(b)
+	for i := range b {
+		b[i] = 'Z'
+	}
+}
+
+// diffJSON diffs the stream we have against the stream we want
+// and fails the test with a useful message if they don't match.
+func diffJSON(t *testing.T, have, want []byte) {
+	t.Helper()
+	type event map[string]interface{}
+
+	// Parse into events, one per line.
+	parseEvents := func(b []byte) ([]event, []string) {
+		t.Helper()
+		var events []event
+		var lines []string
+		for _, line := range bytes.SplitAfter(b, []byte("\n")) {
+			if len(line) > 0 {
+				line = bytes.TrimSpace(line)
+				var e event
+				err := json.Unmarshal(line, &e)
+				if err != nil {
+					t.Errorf("unmarshal %s: %v", b, err)
+					continue
+				}
+				events = append(events, e)
+				lines = append(lines, string(line))
+			}
+		}
+		return events, lines
+	}
+	haveEvents, haveLines := parseEvents(have)
+	wantEvents, wantLines := parseEvents(want)
+	if t.Failed() {
+		return
+	}
+
+	// Make sure the events we have match the events we want.
+	// At each step we're matching haveEvents[i] against wantEvents[j].
+	// i and j can move independently due to choices about exactly
+	// how to break up text in "output" events.
+	i := 0
+	j := 0
+
+	// Fail reports a failure at the current i,j and stops the test.
+	// It shows the events around the current positions,
+	// with the current positions marked.
+	fail := func() {
+		var buf bytes.Buffer
+		show := func(i int, lines []string) {
+			for k := -2; k < 5; k++ {
+				marker := ""
+				if k == 0 {
+					marker = "» "
+				}
+				if 0 <= i+k && i+k < len(lines) {
+					fmt.Fprintf(&buf, "\t%s%s\n", marker, lines[i+k])
+				}
+			}
+			if i >= len(lines) {
+				// show marker after end of input
+				fmt.Fprintf(&buf, "\t» \n")
+			}
+		}
+		fmt.Fprintf(&buf, "have:\n")
+		show(i, haveLines)
+		fmt.Fprintf(&buf, "want:\n")
+		show(j, wantLines)
+		t.Fatal(buf.String())
+	}
+
+	var outputTest string             // current "Test" key in "output" events
+	var wantOutput, haveOutput string // collected "Output" of those events
+
+	// getTest returns the "Test" setting, or "" if it is missing.
+	getTest := func(e event) string {
+		s, _ := e["Test"].(string)
+		return s
+	}
+
+	// checkOutput collects output from the haveEvents for the current outputTest
+	// and then checks that the collected output matches the wanted output.
+	checkOutput := func() {
+		for i < len(haveEvents) && haveEvents[i]["Action"] == "output" && getTest(haveEvents[i]) == outputTest {
+			haveOutput += haveEvents[i]["Output"].(string)
+			i++
+		}
+		if haveOutput != wantOutput {
+			t.Errorf("output mismatch for Test=%q:\nhave %q\nwant %q", outputTest, haveOutput, wantOutput)
+			fail()
+		}
+		haveOutput = ""
+		wantOutput = ""
+	}
+
+	// Walk through wantEvents matching against haveEvents.
+	for j = range wantEvents {
+		e := wantEvents[j]
+		if e["Action"] == "output" && getTest(e) == outputTest {
+			wantOutput += e["Output"].(string)
+			continue
+		}
+		checkOutput()
+		if e["Action"] == "output" {
+			outputTest = getTest(e)
+			wantOutput += e["Output"].(string)
+			continue
+		}
+		if i >= len(haveEvents) {
+			t.Errorf("early end of event stream: missing event")
+			fail()
+		}
+		if !reflect.DeepEqual(haveEvents[i], e) {
+			t.Errorf("events out of sync")
+			fail()
+		}
+		i++
+	}
+	checkOutput()
+	if i < len(haveEvents) {
+		t.Errorf("extra events in stream")
+		fail()
+	}
+}
+
+func TestTrimUTF8(t *testing.T) {
+	s := "hello α ☺ 😂 world" // α is 2-byte, ☺ is 3-byte, 😂 is 4-byte
+	b := []byte(s)
+	for i := 0; i < len(s); i++ {
+		j := trimUTF8(b[:i])
+		u := string([]rune(s[:j])) + string([]rune(s[j:]))
+		if u != s {
+			t.Errorf("trimUTF8(%q) = %d (-%d), not at boundary (split: %q %q)", s[:i], j, i-j, s[:j], s[j:])
+		}
+		if utf8.FullRune(b[j:i]) {
+			t.Errorf("trimUTF8(%q) = %d (-%d), too early (missed: %q)", s[:j], j, i-j, s[j:i])
+		}
+	}
+}
diff --git a/src/cmd/internal/test2json/testdata/ascii.json b/src/cmd/internal/test2json/testdata/ascii.json
new file mode 100644
index 0000000..67fccfc
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/ascii.json
@@ -0,0 +1,10 @@
+{"Action":"run","Test":"TestAscii"}
+{"Action":"output","Test":"TestAscii","Output":"=== RUN   TestAscii\n"}
+{"Action":"output","Test":"TestAscii","Output":"I can eat glass, and it doesn't hurt me. I can eat glass, and it doesn't hurt me.\n"}
+{"Action":"output","Test":"TestAscii","Output":"I CAN EAT GLASS, AND IT DOESN'T HURT ME. I CAN EAT GLASS, AND IT DOESN'T HURT ME.\n"}
+{"Action":"output","Test":"TestAscii","Output":"--- PASS: TestAscii\n"}
+{"Action":"output","Test":"TestAscii","Output":"    i can eat glass, and it doesn't hurt me. i can eat glass, and it doesn't hurt me.\n"}
+{"Action":"output","Test":"TestAscii","Output":"    V PNA RNG TYNFF, NAQ VG QBRFA'G UHEG ZR. V PNA RNG TYNFF, NAQ VG QBRFA'G UHEG ZR.\n"}
+{"Action":"pass","Test":"TestAscii"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/ascii.test b/src/cmd/internal/test2json/testdata/ascii.test
new file mode 100644
index 0000000..4ff7453
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/ascii.test
@@ -0,0 +1,7 @@
+=== RUN   TestAscii
+I can eat glass, and it doesn't hurt me. I can eat glass, and it doesn't hurt me.
+I CAN EAT GLASS, AND IT DOESN'T HURT ME. I CAN EAT GLASS, AND IT DOESN'T HURT ME.
+--- PASS: TestAscii
+    i can eat glass, and it doesn't hurt me. i can eat glass, and it doesn't hurt me.
+    V PNA RNG TYNFF, NAQ VG QBRFA'G UHEG ZR. V PNA RNG TYNFF, NAQ VG QBRFA'G UHEG ZR.
+PASS
diff --git a/src/cmd/internal/test2json/testdata/bench.json b/src/cmd/internal/test2json/testdata/bench.json
new file mode 100644
index 0000000..69e417e
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/bench.json
@@ -0,0 +1,14 @@
+{"Action":"output","Output":"goos: darwin\n"}
+{"Action":"output","Output":"goarch: 386\n"}
+{"Action":"output","Output":"BenchmarkFoo-8   \t2000000000\t         0.00 ns/op\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"--- BENCH: BenchmarkFoo-8\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"output","Test":"BenchmarkFoo-8","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"bench","Test":"BenchmarkFoo-8"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"output","Output":"ok  \tcommand-line-arguments\t0.009s\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/bench.test b/src/cmd/internal/test2json/testdata/bench.test
new file mode 100644
index 0000000..453bd59
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/bench.test
@@ -0,0 +1,12 @@
+goos: darwin
+goarch: 386
+BenchmarkFoo-8   	2000000000	         0.00 ns/op
+--- BENCH: BenchmarkFoo-8
+	x_test.go:8: My benchmark
+	x_test.go:8: My benchmark
+	x_test.go:8: My benchmark
+	x_test.go:8: My benchmark
+	x_test.go:8: My benchmark
+	x_test.go:8: My benchmark
+PASS
+ok  	command-line-arguments	0.009s
diff --git a/src/cmd/internal/test2json/testdata/benchfail.json b/src/cmd/internal/test2json/testdata/benchfail.json
new file mode 100644
index 0000000..ad3ac9e
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/benchfail.json
@@ -0,0 +1,6 @@
+{"Action":"output","Test":"BenchmarkFoo","Output":"--- FAIL: BenchmarkFoo\n"}
+{"Action":"output","Test":"BenchmarkFoo","Output":"\tx_test.go:8: My benchmark\n"}
+{"Action":"fail","Test":"BenchmarkFoo"}
+{"Action":"output","Output":"FAIL\n"}
+{"Action":"output","Output":"FAIL\tcommand-line-arguments\t0.008s\n"}
+{"Action":"fail"}
diff --git a/src/cmd/internal/test2json/testdata/benchfail.test b/src/cmd/internal/test2json/testdata/benchfail.test
new file mode 100644
index 0000000..538d957
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/benchfail.test
@@ -0,0 +1,4 @@
+--- FAIL: BenchmarkFoo
+	x_test.go:8: My benchmark
+FAIL
+FAIL	command-line-arguments	0.008s
diff --git a/src/cmd/internal/test2json/testdata/benchshort.json b/src/cmd/internal/test2json/testdata/benchshort.json
new file mode 100644
index 0000000..8c61d95
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/benchshort.json
@@ -0,0 +1,7 @@
+{"Action":"output","Output":"# This file ends in an early EOF to trigger the Benchmark prefix test,\n"}
+{"Action":"output","Output":"# which only happens when a benchmark prefix is seen ahead of the \\n.\n"}
+{"Action":"output","Output":"# Normally that's due to the benchmark running and the \\n coming later,\n"}
+{"Action":"output","Output":"# but to avoid questions of timing, we just use a file with no \\n at all.\n"}
+{"Action":"output","Output":"BenchmarkFoo   \t"}
+{"Action":"output","Output":"10000 early EOF"}
+{"Action":"fail"}
diff --git a/src/cmd/internal/test2json/testdata/benchshort.test b/src/cmd/internal/test2json/testdata/benchshort.test
new file mode 100644
index 0000000..0b173ab
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/benchshort.test
@@ -0,0 +1,5 @@
+# This file ends in an early EOF to trigger the Benchmark prefix test,
+# which only happens when a benchmark prefix is seen ahead of the \n.
+# Normally that's due to the benchmark running and the \n coming later,
+# but to avoid questions of timing, we just use a file with no \n at all.
+BenchmarkFoo   	10000 early EOF
\ No newline at end of file
diff --git a/src/cmd/internal/test2json/testdata/issue23036.json b/src/cmd/internal/test2json/testdata/issue23036.json
new file mode 100644
index 0000000..935c0c5
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/issue23036.json
@@ -0,0 +1,12 @@
+{"Action":"run","Test":"TestActualCase"}
+{"Action":"output","Test":"TestActualCase","Output":"=== RUN   TestActualCase\n"}
+{"Action":"output","Test":"TestActualCase","Output":"--- FAIL: TestActualCase (0.00s)\n"}
+{"Action":"output","Test":"TestActualCase","Output":"        foo_test.go:14: Differed.\n"}
+{"Action":"output","Test":"TestActualCase","Output":"                Expected: MyTest:\n"}
+{"Action":"output","Test":"TestActualCase","Output":"                --- FAIL: Test output from other tool\n"}
+{"Action":"output","Test":"TestActualCase","Output":"                Actual: not expected\n"}
+{"Action":"fail","Test":"TestActualCase"}
+{"Action":"output","Output":"FAIL\n"}
+{"Action":"output","Output":"exit status 1\n"}
+{"Action":"output","Output":"FAIL    github.com/org/project/badtest     0.049s\n"}
+{"Action":"fail"}
diff --git a/src/cmd/internal/test2json/testdata/issue23036.test b/src/cmd/internal/test2json/testdata/issue23036.test
new file mode 100644
index 0000000..fd4774f
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/issue23036.test
@@ -0,0 +1,9 @@
+=== RUN   TestActualCase
+--- FAIL: TestActualCase (0.00s)
+        foo_test.go:14: Differed.
+                Expected: MyTest:
+                --- FAIL: Test output from other tool
+                Actual: not expected
+FAIL
+exit status 1
+FAIL    github.com/org/project/badtest     0.049s
diff --git a/src/cmd/internal/test2json/testdata/smiley.json b/src/cmd/internal/test2json/testdata/smiley.json
new file mode 100644
index 0000000..afa990d
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/smiley.json
@@ -0,0 +1,182 @@
+{"Action":"run","Test":"Test☺☹"}
+{"Action":"output","Test":"Test☺☹","Output":"=== RUN   Test☺☹\n"}
+{"Action":"output","Test":"Test☺☹","Output":"=== PAUSE Test☺☹\n"}
+{"Action":"pause","Test":"Test☺☹"}
+{"Action":"run","Test":"Test☺☹Asm"}
+{"Action":"output","Test":"Test☺☹Asm","Output":"=== RUN   Test☺☹Asm\n"}
+{"Action":"output","Test":"Test☺☹Asm","Output":"=== PAUSE Test☺☹Asm\n"}
+{"Action":"pause","Test":"Test☺☹Asm"}
+{"Action":"run","Test":"Test☺☹Dirs"}
+{"Action":"output","Test":"Test☺☹Dirs","Output":"=== RUN   Test☺☹Dirs\n"}
+{"Action":"output","Test":"Test☺☹Dirs","Output":"=== PAUSE Test☺☹Dirs\n"}
+{"Action":"pause","Test":"Test☺☹Dirs"}
+{"Action":"run","Test":"TestTags"}
+{"Action":"output","Test":"TestTags","Output":"=== RUN   TestTags\n"}
+{"Action":"output","Test":"TestTags","Output":"=== PAUSE TestTags\n"}
+{"Action":"pause","Test":"TestTags"}
+{"Action":"run","Test":"Test☺☹Verbose"}
+{"Action":"output","Test":"Test☺☹Verbose","Output":"=== RUN   Test☺☹Verbose\n"}
+{"Action":"output","Test":"Test☺☹Verbose","Output":"=== PAUSE Test☺☹Verbose\n"}
+{"Action":"pause","Test":"Test☺☹Verbose"}
+{"Action":"cont","Test":"Test☺☹"}
+{"Action":"output","Test":"Test☺☹","Output":"=== CONT  Test☺☹\n"}
+{"Action":"cont","Test":"TestTags"}
+{"Action":"output","Test":"TestTags","Output":"=== CONT  TestTags\n"}
+{"Action":"cont","Test":"Test☺☹Verbose"}
+{"Action":"output","Test":"Test☺☹Verbose","Output":"=== CONT  Test☺☹Verbose\n"}
+{"Action":"run","Test":"TestTags/testtag"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== RUN   TestTags/testtag\n"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== PAUSE TestTags/testtag\n"}
+{"Action":"pause","Test":"TestTags/testtag"}
+{"Action":"cont","Test":"Test☺☹Dirs"}
+{"Action":"output","Test":"Test☺☹Dirs","Output":"=== CONT  Test☺☹Dirs\n"}
+{"Action":"cont","Test":"Test☺☹Asm"}
+{"Action":"output","Test":"Test☺☹Asm","Output":"=== CONT  Test☺☹Asm\n"}
+{"Action":"run","Test":"Test☺☹/0"}
+{"Action":"output","Test":"Test☺☹/0","Output":"=== RUN   Test☺☹/0\n"}
+{"Action":"output","Test":"Test☺☹/0","Output":"=== PAUSE Test☺☹/0\n"}
+{"Action":"pause","Test":"Test☺☹/0"}
+{"Action":"run","Test":"Test☺☹/1"}
+{"Action":"output","Test":"Test☺☹/1","Output":"=== RUN   Test☺☹/1\n"}
+{"Action":"output","Test":"Test☺☹/1","Output":"=== PAUSE Test☺☹/1\n"}
+{"Action":"pause","Test":"Test☺☹/1"}
+{"Action":"run","Test":"Test☺☹/2"}
+{"Action":"output","Test":"Test☺☹/2","Output":"=== RUN   Test☺☹/2\n"}
+{"Action":"output","Test":"Test☺☹/2","Output":"=== PAUSE Test☺☹/2\n"}
+{"Action":"pause","Test":"Test☺☹/2"}
+{"Action":"run","Test":"Test☺☹/3"}
+{"Action":"output","Test":"Test☺☹/3","Output":"=== RUN   Test☺☹/3\n"}
+{"Action":"output","Test":"Test☺☹/3","Output":"=== PAUSE Test☺☹/3\n"}
+{"Action":"pause","Test":"Test☺☹/3"}
+{"Action":"run","Test":"Test☺☹/4"}
+{"Action":"output","Test":"Test☺☹/4","Output":"=== RUN   Test☺☹/4\n"}
+{"Action":"run","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== RUN   TestTags/x_testtag_y\n"}
+{"Action":"output","Test":"Test☺☹/4","Output":"=== PAUSE Test☺☹/4\n"}
+{"Action":"pause","Test":"Test☺☹/4"}
+{"Action":"run","Test":"Test☺☹/5"}
+{"Action":"output","Test":"Test☺☹/5","Output":"=== RUN   Test☺☹/5\n"}
+{"Action":"output","Test":"Test☺☹/5","Output":"=== PAUSE Test☺☹/5\n"}
+{"Action":"pause","Test":"Test☺☹/5"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== PAUSE TestTags/x_testtag_y\n"}
+{"Action":"pause","Test":"TestTags/x_testtag_y"}
+{"Action":"run","Test":"Test☺☹/6"}
+{"Action":"output","Test":"Test☺☹/6","Output":"=== RUN   Test☺☹/6\n"}
+{"Action":"run","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== RUN   TestTags/x,testtag,y\n"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== PAUSE TestTags/x,testtag,y\n"}
+{"Action":"pause","Test":"TestTags/x,testtag,y"}
+{"Action":"run","Test":"Test☺☹Dirs/testingpkg"}
+{"Action":"output","Test":"Test☺☹Dirs/testingpkg","Output":"=== RUN   Test☺☹Dirs/testingpkg\n"}
+{"Action":"output","Test":"Test☺☹/6","Output":"=== PAUSE Test☺☹/6\n"}
+{"Action":"pause","Test":"Test☺☹/6"}
+{"Action":"cont","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== CONT  TestTags/x,testtag,y\n"}
+{"Action":"output","Test":"Test☺☹Dirs/testingpkg","Output":"=== PAUSE Test☺☹Dirs/testingpkg\n"}
+{"Action":"pause","Test":"Test☺☹Dirs/testingpkg"}
+{"Action":"run","Test":"Test☺☹Dirs/divergent"}
+{"Action":"output","Test":"Test☺☹Dirs/divergent","Output":"=== RUN   Test☺☹Dirs/divergent\n"}
+{"Action":"run","Test":"Test☺☹/7"}
+{"Action":"output","Test":"Test☺☹/7","Output":"=== RUN   Test☺☹/7\n"}
+{"Action":"output","Test":"Test☺☹/7","Output":"=== PAUSE Test☺☹/7\n"}
+{"Action":"pause","Test":"Test☺☹/7"}
+{"Action":"output","Test":"Test☺☹Dirs/divergent","Output":"=== PAUSE Test☺☹Dirs/divergent\n"}
+{"Action":"pause","Test":"Test☺☹Dirs/divergent"}
+{"Action":"cont","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== CONT  TestTags/x_testtag_y\n"}
+{"Action":"cont","Test":"TestTags/testtag"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== CONT  TestTags/testtag\n"}
+{"Action":"run","Test":"Test☺☹Dirs/buildtag"}
+{"Action":"output","Test":"Test☺☹Dirs/buildtag","Output":"=== RUN   Test☺☹Dirs/buildtag\n"}
+{"Action":"output","Test":"Test☺☹Dirs/buildtag","Output":"=== PAUSE Test☺☹Dirs/buildtag\n"}
+{"Action":"pause","Test":"Test☺☹Dirs/buildtag"}
+{"Action":"cont","Test":"Test☺☹/0"}
+{"Action":"output","Test":"Test☺☹/0","Output":"=== CONT  Test☺☹/0\n"}
+{"Action":"cont","Test":"Test☺☹/4"}
+{"Action":"output","Test":"Test☺☹/4","Output":"=== CONT  Test☺☹/4\n"}
+{"Action":"run","Test":"Test☺☹Dirs/incomplete"}
+{"Action":"output","Test":"Test☺☹Dirs/incomplete","Output":"=== RUN   Test☺☹Dirs/incomplete\n"}
+{"Action":"output","Test":"Test☺☹Dirs/incomplete","Output":"=== PAUSE Test☺☹Dirs/incomplete\n"}
+{"Action":"pause","Test":"Test☺☹Dirs/incomplete"}
+{"Action":"run","Test":"Test☺☹Dirs/cgo"}
+{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== RUN   Test☺☹Dirs/cgo\n"}
+{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== PAUSE Test☺☹Dirs/cgo\n"}
+{"Action":"pause","Test":"Test☺☹Dirs/cgo"}
+{"Action":"cont","Test":"Test☺☹/7"}
+{"Action":"output","Test":"Test☺☹/7","Output":"=== CONT  Test☺☹/7\n"}
+{"Action":"cont","Test":"Test☺☹/6"}
+{"Action":"output","Test":"Test☺☹/6","Output":"=== CONT  Test☺☹/6\n"}
+{"Action":"output","Test":"Test☺☹Verbose","Output":"--- PASS: Test☺☹Verbose (0.04s)\n"}
+{"Action":"pass","Test":"Test☺☹Verbose"}
+{"Action":"cont","Test":"Test☺☹/5"}
+{"Action":"output","Test":"Test☺☹/5","Output":"=== CONT  Test☺☹/5\n"}
+{"Action":"cont","Test":"Test☺☹/3"}
+{"Action":"output","Test":"Test☺☹/3","Output":"=== CONT  Test☺☹/3\n"}
+{"Action":"cont","Test":"Test☺☹/2"}
+{"Action":"output","Test":"Test☺☹/2","Output":"=== CONT  Test☺☹/2\n"}
+{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"    --- PASS: TestTags/x_testtag_y (0.04s)\n"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"    \tvet_test.go:187: -tags=x testtag y\n"}
+{"Action":"pass","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"    --- PASS: TestTags/x,testtag,y (0.04s)\n"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"    \tvet_test.go:187: -tags=x,testtag,y\n"}
+{"Action":"pass","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/testtag","Output":"    --- PASS: TestTags/testtag (0.04s)\n"}
+{"Action":"output","Test":"TestTags/testtag","Output":"    \tvet_test.go:187: -tags=testtag\n"}
+{"Action":"pass","Test":"TestTags/testtag"}
+{"Action":"pass","Test":"TestTags"}
+{"Action":"cont","Test":"Test☺☹/1"}
+{"Action":"output","Test":"Test☺☹/1","Output":"=== CONT  Test☺☹/1\n"}
+{"Action":"cont","Test":"Test☺☹Dirs/testingpkg"}
+{"Action":"output","Test":"Test☺☹Dirs/testingpkg","Output":"=== CONT  Test☺☹Dirs/testingpkg\n"}
+{"Action":"cont","Test":"Test☺☹Dirs/buildtag"}
+{"Action":"output","Test":"Test☺☹Dirs/buildtag","Output":"=== CONT  Test☺☹Dirs/buildtag\n"}
+{"Action":"cont","Test":"Test☺☹Dirs/divergent"}
+{"Action":"output","Test":"Test☺☹Dirs/divergent","Output":"=== CONT  Test☺☹Dirs/divergent\n"}
+{"Action":"cont","Test":"Test☺☹Dirs/incomplete"}
+{"Action":"output","Test":"Test☺☹Dirs/incomplete","Output":"=== CONT  Test☺☹Dirs/incomplete\n"}
+{"Action":"cont","Test":"Test☺☹Dirs/cgo"}
+{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== CONT  Test☺☹Dirs/cgo\n"}
+{"Action":"output","Test":"Test☺☹","Output":"--- PASS: Test☺☹ (0.39s)\n"}
+{"Action":"output","Test":"Test☺☹/5","Output":"    --- PASS: Test☺☹/5 (0.07s)\n"}
+{"Action":"output","Test":"Test☺☹/5","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/5"}
+{"Action":"output","Test":"Test☺☹/3","Output":"    --- PASS: Test☺☹/3 (0.07s)\n"}
+{"Action":"output","Test":"Test☺☹/3","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/3"}
+{"Action":"output","Test":"Test☺☹/6","Output":"    --- PASS: Test☺☹/6 (0.07s)\n"}
+{"Action":"output","Test":"Test☺☹/6","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/6"}
+{"Action":"output","Test":"Test☺☹/2","Output":"    --- PASS: Test☺☹/2 (0.07s)\n"}
+{"Action":"output","Test":"Test☺☹/2","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/2"}
+{"Action":"output","Test":"Test☺☹/0","Output":"    --- PASS: Test☺☹/0 (0.13s)\n"}
+{"Action":"output","Test":"Test☺☹/0","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/0"}
+{"Action":"output","Test":"Test☺☹/4","Output":"    --- PASS: Test☺☹/4 (0.16s)\n"}
+{"Action":"output","Test":"Test☺☹/4","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/4"}
+{"Action":"output","Test":"Test☺☹/1","Output":"    --- PASS: Test☺☹/1 (0.07s)\n"}
+{"Action":"output","Test":"Test☺☹/1","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/1"}
+{"Action":"output","Test":"Test☺☹/7","Output":"    --- PASS: Test☺☹/7 (0.19s)\n"}
+{"Action":"output","Test":"Test☺☹/7","Output":"    \tvet_test.go:114: φιλεσ: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
+{"Action":"pass","Test":"Test☺☹/7"}
+{"Action":"pass","Test":"Test☺☹"}
+{"Action":"output","Test":"Test☺☹Dirs","Output":"--- PASS: Test☺☹Dirs (0.01s)\n"}
+{"Action":"output","Test":"Test☺☹Dirs/testingpkg","Output":"    --- PASS: Test☺☹Dirs/testingpkg (0.06s)\n"}
+{"Action":"pass","Test":"Test☺☹Dirs/testingpkg"}
+{"Action":"output","Test":"Test☺☹Dirs/divergent","Output":"    --- PASS: Test☺☹Dirs/divergent (0.05s)\n"}
+{"Action":"pass","Test":"Test☺☹Dirs/divergent"}
+{"Action":"output","Test":"Test☺☹Dirs/buildtag","Output":"    --- PASS: Test☺☹Dirs/buildtag (0.06s)\n"}
+{"Action":"pass","Test":"Test☺☹Dirs/buildtag"}
+{"Action":"output","Test":"Test☺☹Dirs/incomplete","Output":"    --- PASS: Test☺☹Dirs/incomplete (0.05s)\n"}
+{"Action":"pass","Test":"Test☺☹Dirs/incomplete"}
+{"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"    --- PASS: Test☺☹Dirs/cgo (0.04s)\n"}
+{"Action":"pass","Test":"Test☺☹Dirs/cgo"}
+{"Action":"pass","Test":"Test☺☹Dirs"}
+{"Action":"output","Test":"Test☺☹Asm","Output":"--- PASS: Test☺☹Asm (0.75s)\n"}
+{"Action":"pass","Test":"Test☺☹Asm"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"output","Output":"ok  \tcmd/vet\t(cached)\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/smiley.test b/src/cmd/internal/test2json/testdata/smiley.test
new file mode 100644
index 0000000..05edf5a
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/smiley.test
@@ -0,0 +1,97 @@
+=== RUN   Test☺☹
+=== PAUSE Test☺☹
+=== RUN   Test☺☹Asm
+=== PAUSE Test☺☹Asm
+=== RUN   Test☺☹Dirs
+=== PAUSE Test☺☹Dirs
+=== RUN   TestTags
+=== PAUSE TestTags
+=== RUN   Test☺☹Verbose
+=== PAUSE Test☺☹Verbose
+=== CONT  Test☺☹
+=== CONT  TestTags
+=== CONT  Test☺☹Verbose
+=== RUN   TestTags/testtag
+=== PAUSE TestTags/testtag
+=== CONT  Test☺☹Dirs
+=== CONT  Test☺☹Asm
+=== RUN   Test☺☹/0
+=== PAUSE Test☺☹/0
+=== RUN   Test☺☹/1
+=== PAUSE Test☺☹/1
+=== RUN   Test☺☹/2
+=== PAUSE Test☺☹/2
+=== RUN   Test☺☹/3
+=== PAUSE Test☺☹/3
+=== RUN   Test☺☹/4
+=== RUN   TestTags/x_testtag_y
+=== PAUSE Test☺☹/4
+=== RUN   Test☺☹/5
+=== PAUSE Test☺☹/5
+=== PAUSE TestTags/x_testtag_y
+=== RUN   Test☺☹/6
+=== RUN   TestTags/x,testtag,y
+=== PAUSE TestTags/x,testtag,y
+=== RUN   Test☺☹Dirs/testingpkg
+=== PAUSE Test☺☹/6
+=== CONT  TestTags/x,testtag,y
+=== PAUSE Test☺☹Dirs/testingpkg
+=== RUN   Test☺☹Dirs/divergent
+=== RUN   Test☺☹/7
+=== PAUSE Test☺☹/7
+=== PAUSE Test☺☹Dirs/divergent
+=== CONT  TestTags/x_testtag_y
+=== CONT  TestTags/testtag
+=== RUN   Test☺☹Dirs/buildtag
+=== PAUSE Test☺☹Dirs/buildtag
+=== CONT  Test☺☹/0
+=== CONT  Test☺☹/4
+=== RUN   Test☺☹Dirs/incomplete
+=== PAUSE Test☺☹Dirs/incomplete
+=== RUN   Test☺☹Dirs/cgo
+=== PAUSE Test☺☹Dirs/cgo
+=== CONT  Test☺☹/7
+=== CONT  Test☺☹/6
+--- PASS: Test☺☹Verbose (0.04s)
+=== CONT  Test☺☹/5
+=== CONT  Test☺☹/3
+=== CONT  Test☺☹/2
+--- PASS: TestTags (0.00s)
+    --- PASS: TestTags/x_testtag_y (0.04s)
+    	vet_test.go:187: -tags=x testtag y
+    --- PASS: TestTags/x,testtag,y (0.04s)
+    	vet_test.go:187: -tags=x,testtag,y
+    --- PASS: TestTags/testtag (0.04s)
+    	vet_test.go:187: -tags=testtag
+=== CONT  Test☺☹/1
+=== CONT  Test☺☹Dirs/testingpkg
+=== CONT  Test☺☹Dirs/buildtag
+=== CONT  Test☺☹Dirs/divergent
+=== CONT  Test☺☹Dirs/incomplete
+=== CONT  Test☺☹Dirs/cgo
+--- PASS: Test☺☹ (0.39s)
+    --- PASS: Test☺☹/5 (0.07s)
+    	vet_test.go:114: φιλεσ: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
+    --- PASS: Test☺☹/3 (0.07s)
+    	vet_test.go:114: φιλεσ: ["testdata/composite.go" "testdata/nilfunc.go"]
+    --- PASS: Test☺☹/6 (0.07s)
+    	vet_test.go:114: φιλεσ: ["testdata/copylock_range.go" "testdata/shadow.go"]
+    --- PASS: Test☺☹/2 (0.07s)
+    	vet_test.go:114: φιλεσ: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
+    --- PASS: Test☺☹/0 (0.13s)
+    	vet_test.go:114: φιλεσ: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
+    --- PASS: Test☺☹/4 (0.16s)
+    	vet_test.go:114: φιλεσ: ["testdata/copylock.go" "testdata/print.go"]
+    --- PASS: Test☺☹/1 (0.07s)
+    	vet_test.go:114: φιλεσ: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
+    --- PASS: Test☺☹/7 (0.19s)
+    	vet_test.go:114: φιλεσ: ["testdata/deadcode.go" "testdata/shift.go"]
+--- PASS: Test☺☹Dirs (0.01s)
+    --- PASS: Test☺☹Dirs/testingpkg (0.06s)
+    --- PASS: Test☺☹Dirs/divergent (0.05s)
+    --- PASS: Test☺☹Dirs/buildtag (0.06s)
+    --- PASS: Test☺☹Dirs/incomplete (0.05s)
+    --- PASS: Test☺☹Dirs/cgo (0.04s)
+--- PASS: Test☺☹Asm (0.75s)
+PASS
+ok  	cmd/vet	(cached)
diff --git a/src/cmd/internal/test2json/testdata/unicode.json b/src/cmd/internal/test2json/testdata/unicode.json
new file mode 100644
index 0000000..9cfb5f2
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/unicode.json
@@ -0,0 +1,10 @@
+{"Action":"run","Test":"TestUnicode"}
+{"Action":"output","Test":"TestUnicode","Output":"=== RUN   TestUnicode\n"}
+{"Action":"output","Test":"TestUnicode","Output":"Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα. Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.\n"}
+{"Action":"output","Test":"TestUnicode","Output":"私はガラスを食べられます。それは私を傷つけません。私はガラスを食べられます。それは私を傷つけません。\n"}
+{"Action":"output","Test":"TestUnicode","Output":"--- PASS: TestUnicode\n"}
+{"Action":"output","Test":"TestUnicode","Output":"    ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ\n"}
+{"Action":"output","Test":"TestUnicode","Output":"    אני יכול לאכול זכוכית וזה לא מזיק לי. אני יכול לאכול זכוכית וזה לא מזיק לי.\n"}
+{"Action":"pass","Test":"TestUnicode"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/unicode.test b/src/cmd/internal/test2json/testdata/unicode.test
new file mode 100644
index 0000000..58c620d
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/unicode.test
@@ -0,0 +1,7 @@
+=== RUN   TestUnicode
+Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα. Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.
+私はガラスを食べられます。それは私を傷つけません。私はガラスを食べられます。それは私を傷つけません。
+--- PASS: TestUnicode
+    ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ
+    אני יכול לאכול זכוכית וזה לא מזיק לי. אני יכול לאכול זכוכית וזה לא מזיק לי.
+PASS
diff --git a/src/cmd/internal/test2json/testdata/vet.json b/src/cmd/internal/test2json/testdata/vet.json
new file mode 100644
index 0000000..8c5921d
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/vet.json
@@ -0,0 +1,182 @@
+{"Action":"run","Test":"TestVet"}
+{"Action":"output","Test":"TestVet","Output":"=== RUN   TestVet\n"}
+{"Action":"output","Test":"TestVet","Output":"=== PAUSE TestVet\n"}
+{"Action":"pause","Test":"TestVet"}
+{"Action":"run","Test":"TestVetAsm"}
+{"Action":"output","Test":"TestVetAsm","Output":"=== RUN   TestVetAsm\n"}
+{"Action":"output","Test":"TestVetAsm","Output":"=== PAUSE TestVetAsm\n"}
+{"Action":"pause","Test":"TestVetAsm"}
+{"Action":"run","Test":"TestVetDirs"}
+{"Action":"output","Test":"TestVetDirs","Output":"=== RUN   TestVetDirs\n"}
+{"Action":"output","Test":"TestVetDirs","Output":"=== PAUSE TestVetDirs\n"}
+{"Action":"pause","Test":"TestVetDirs"}
+{"Action":"run","Test":"TestTags"}
+{"Action":"output","Test":"TestTags","Output":"=== RUN   TestTags\n"}
+{"Action":"output","Test":"TestTags","Output":"=== PAUSE TestTags\n"}
+{"Action":"pause","Test":"TestTags"}
+{"Action":"run","Test":"TestVetVerbose"}
+{"Action":"output","Test":"TestVetVerbose","Output":"=== RUN   TestVetVerbose\n"}
+{"Action":"output","Test":"TestVetVerbose","Output":"=== PAUSE TestVetVerbose\n"}
+{"Action":"pause","Test":"TestVetVerbose"}
+{"Action":"cont","Test":"TestVet"}
+{"Action":"output","Test":"TestVet","Output":"=== CONT  TestVet\n"}
+{"Action":"cont","Test":"TestTags"}
+{"Action":"output","Test":"TestTags","Output":"=== CONT  TestTags\n"}
+{"Action":"cont","Test":"TestVetVerbose"}
+{"Action":"output","Test":"TestVetVerbose","Output":"=== CONT  TestVetVerbose\n"}
+{"Action":"run","Test":"TestTags/testtag"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== RUN   TestTags/testtag\n"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== PAUSE TestTags/testtag\n"}
+{"Action":"pause","Test":"TestTags/testtag"}
+{"Action":"cont","Test":"TestVetDirs"}
+{"Action":"output","Test":"TestVetDirs","Output":"=== CONT  TestVetDirs\n"}
+{"Action":"cont","Test":"TestVetAsm"}
+{"Action":"output","Test":"TestVetAsm","Output":"=== CONT  TestVetAsm\n"}
+{"Action":"run","Test":"TestVet/0"}
+{"Action":"output","Test":"TestVet/0","Output":"=== RUN   TestVet/0\n"}
+{"Action":"output","Test":"TestVet/0","Output":"=== PAUSE TestVet/0\n"}
+{"Action":"pause","Test":"TestVet/0"}
+{"Action":"run","Test":"TestVet/1"}
+{"Action":"output","Test":"TestVet/1","Output":"=== RUN   TestVet/1\n"}
+{"Action":"output","Test":"TestVet/1","Output":"=== PAUSE TestVet/1\n"}
+{"Action":"pause","Test":"TestVet/1"}
+{"Action":"run","Test":"TestVet/2"}
+{"Action":"output","Test":"TestVet/2","Output":"=== RUN   TestVet/2\n"}
+{"Action":"output","Test":"TestVet/2","Output":"=== PAUSE TestVet/2\n"}
+{"Action":"pause","Test":"TestVet/2"}
+{"Action":"run","Test":"TestVet/3"}
+{"Action":"output","Test":"TestVet/3","Output":"=== RUN   TestVet/3\n"}
+{"Action":"output","Test":"TestVet/3","Output":"=== PAUSE TestVet/3\n"}
+{"Action":"pause","Test":"TestVet/3"}
+{"Action":"run","Test":"TestVet/4"}
+{"Action":"output","Test":"TestVet/4","Output":"=== RUN   TestVet/4\n"}
+{"Action":"run","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== RUN   TestTags/x_testtag_y\n"}
+{"Action":"output","Test":"TestVet/4","Output":"=== PAUSE TestVet/4\n"}
+{"Action":"pause","Test":"TestVet/4"}
+{"Action":"run","Test":"TestVet/5"}
+{"Action":"output","Test":"TestVet/5","Output":"=== RUN   TestVet/5\n"}
+{"Action":"output","Test":"TestVet/5","Output":"=== PAUSE TestVet/5\n"}
+{"Action":"pause","Test":"TestVet/5"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== PAUSE TestTags/x_testtag_y\n"}
+{"Action":"pause","Test":"TestTags/x_testtag_y"}
+{"Action":"run","Test":"TestVet/6"}
+{"Action":"output","Test":"TestVet/6","Output":"=== RUN   TestVet/6\n"}
+{"Action":"run","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== RUN   TestTags/x,testtag,y\n"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== PAUSE TestTags/x,testtag,y\n"}
+{"Action":"pause","Test":"TestTags/x,testtag,y"}
+{"Action":"run","Test":"TestVetDirs/testingpkg"}
+{"Action":"output","Test":"TestVetDirs/testingpkg","Output":"=== RUN   TestVetDirs/testingpkg\n"}
+{"Action":"output","Test":"TestVet/6","Output":"=== PAUSE TestVet/6\n"}
+{"Action":"pause","Test":"TestVet/6"}
+{"Action":"cont","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"=== CONT  TestTags/x,testtag,y\n"}
+{"Action":"output","Test":"TestVetDirs/testingpkg","Output":"=== PAUSE TestVetDirs/testingpkg\n"}
+{"Action":"pause","Test":"TestVetDirs/testingpkg"}
+{"Action":"run","Test":"TestVetDirs/divergent"}
+{"Action":"output","Test":"TestVetDirs/divergent","Output":"=== RUN   TestVetDirs/divergent\n"}
+{"Action":"run","Test":"TestVet/7"}
+{"Action":"output","Test":"TestVet/7","Output":"=== RUN   TestVet/7\n"}
+{"Action":"output","Test":"TestVet/7","Output":"=== PAUSE TestVet/7\n"}
+{"Action":"pause","Test":"TestVet/7"}
+{"Action":"output","Test":"TestVetDirs/divergent","Output":"=== PAUSE TestVetDirs/divergent\n"}
+{"Action":"pause","Test":"TestVetDirs/divergent"}
+{"Action":"cont","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"=== CONT  TestTags/x_testtag_y\n"}
+{"Action":"cont","Test":"TestTags/testtag"}
+{"Action":"output","Test":"TestTags/testtag","Output":"=== CONT  TestTags/testtag\n"}
+{"Action":"run","Test":"TestVetDirs/buildtag"}
+{"Action":"output","Test":"TestVetDirs/buildtag","Output":"=== RUN   TestVetDirs/buildtag\n"}
+{"Action":"output","Test":"TestVetDirs/buildtag","Output":"=== PAUSE TestVetDirs/buildtag\n"}
+{"Action":"pause","Test":"TestVetDirs/buildtag"}
+{"Action":"cont","Test":"TestVet/0"}
+{"Action":"output","Test":"TestVet/0","Output":"=== CONT  TestVet/0\n"}
+{"Action":"cont","Test":"TestVet/4"}
+{"Action":"output","Test":"TestVet/4","Output":"=== CONT  TestVet/4\n"}
+{"Action":"run","Test":"TestVetDirs/incomplete"}
+{"Action":"output","Test":"TestVetDirs/incomplete","Output":"=== RUN   TestVetDirs/incomplete\n"}
+{"Action":"output","Test":"TestVetDirs/incomplete","Output":"=== PAUSE TestVetDirs/incomplete\n"}
+{"Action":"pause","Test":"TestVetDirs/incomplete"}
+{"Action":"run","Test":"TestVetDirs/cgo"}
+{"Action":"output","Test":"TestVetDirs/cgo","Output":"=== RUN   TestVetDirs/cgo\n"}
+{"Action":"output","Test":"TestVetDirs/cgo","Output":"=== PAUSE TestVetDirs/cgo\n"}
+{"Action":"pause","Test":"TestVetDirs/cgo"}
+{"Action":"cont","Test":"TestVet/7"}
+{"Action":"output","Test":"TestVet/7","Output":"=== CONT  TestVet/7\n"}
+{"Action":"cont","Test":"TestVet/6"}
+{"Action":"output","Test":"TestVet/6","Output":"=== CONT  TestVet/6\n"}
+{"Action":"output","Test":"TestVetVerbose","Output":"--- PASS: TestVetVerbose (0.04s)\n"}
+{"Action":"pass","Test":"TestVetVerbose"}
+{"Action":"cont","Test":"TestVet/5"}
+{"Action":"output","Test":"TestVet/5","Output":"=== CONT  TestVet/5\n"}
+{"Action":"cont","Test":"TestVet/3"}
+{"Action":"output","Test":"TestVet/3","Output":"=== CONT  TestVet/3\n"}
+{"Action":"cont","Test":"TestVet/2"}
+{"Action":"output","Test":"TestVet/2","Output":"=== CONT  TestVet/2\n"}
+{"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"    --- PASS: TestTags/x_testtag_y (0.04s)\n"}
+{"Action":"output","Test":"TestTags/x_testtag_y","Output":"    \tvet_test.go:187: -tags=x testtag y\n"}
+{"Action":"pass","Test":"TestTags/x_testtag_y"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"    --- PASS: TestTags/x,testtag,y (0.04s)\n"}
+{"Action":"output","Test":"TestTags/x,testtag,y","Output":"    \tvet_test.go:187: -tags=x,testtag,y\n"}
+{"Action":"pass","Test":"TestTags/x,testtag,y"}
+{"Action":"output","Test":"TestTags/testtag","Output":"    --- PASS: TestTags/testtag (0.04s)\n"}
+{"Action":"output","Test":"TestTags/testtag","Output":"    \tvet_test.go:187: -tags=testtag\n"}
+{"Action":"pass","Test":"TestTags/testtag"}
+{"Action":"pass","Test":"TestTags"}
+{"Action":"cont","Test":"TestVet/1"}
+{"Action":"output","Test":"TestVet/1","Output":"=== CONT  TestVet/1\n"}
+{"Action":"cont","Test":"TestVetDirs/testingpkg"}
+{"Action":"output","Test":"TestVetDirs/testingpkg","Output":"=== CONT  TestVetDirs/testingpkg\n"}
+{"Action":"cont","Test":"TestVetDirs/buildtag"}
+{"Action":"output","Test":"TestVetDirs/buildtag","Output":"=== CONT  TestVetDirs/buildtag\n"}
+{"Action":"cont","Test":"TestVetDirs/divergent"}
+{"Action":"output","Test":"TestVetDirs/divergent","Output":"=== CONT  TestVetDirs/divergent\n"}
+{"Action":"cont","Test":"TestVetDirs/incomplete"}
+{"Action":"output","Test":"TestVetDirs/incomplete","Output":"=== CONT  TestVetDirs/incomplete\n"}
+{"Action":"cont","Test":"TestVetDirs/cgo"}
+{"Action":"output","Test":"TestVetDirs/cgo","Output":"=== CONT  TestVetDirs/cgo\n"}
+{"Action":"output","Test":"TestVet","Output":"--- PASS: TestVet (0.39s)\n"}
+{"Action":"output","Test":"TestVet/5","Output":"    --- PASS: TestVet/5 (0.07s)\n"}
+{"Action":"output","Test":"TestVet/5","Output":"    \tvet_test.go:114: files: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"}
+{"Action":"pass","Test":"TestVet/5"}
+{"Action":"output","Test":"TestVet/3","Output":"    --- PASS: TestVet/3 (0.07s)\n"}
+{"Action":"output","Test":"TestVet/3","Output":"    \tvet_test.go:114: files: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"}
+{"Action":"pass","Test":"TestVet/3"}
+{"Action":"output","Test":"TestVet/6","Output":"    --- PASS: TestVet/6 (0.07s)\n"}
+{"Action":"output","Test":"TestVet/6","Output":"    \tvet_test.go:114: files: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"}
+{"Action":"pass","Test":"TestVet/6"}
+{"Action":"output","Test":"TestVet/2","Output":"    --- PASS: TestVet/2 (0.07s)\n"}
+{"Action":"output","Test":"TestVet/2","Output":"    \tvet_test.go:114: files: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"}
+{"Action":"pass","Test":"TestVet/2"}
+{"Action":"output","Test":"TestVet/0","Output":"    --- PASS: TestVet/0 (0.13s)\n"}
+{"Action":"output","Test":"TestVet/0","Output":"    \tvet_test.go:114: files: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"}
+{"Action":"pass","Test":"TestVet/0"}
+{"Action":"output","Test":"TestVet/4","Output":"    --- PASS: TestVet/4 (0.16s)\n"}
+{"Action":"output","Test":"TestVet/4","Output":"    \tvet_test.go:114: files: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"}
+{"Action":"pass","Test":"TestVet/4"}
+{"Action":"output","Test":"TestVet/1","Output":"    --- PASS: TestVet/1 (0.07s)\n"}
+{"Action":"output","Test":"TestVet/1","Output":"    \tvet_test.go:114: files: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"}
+{"Action":"pass","Test":"TestVet/1"}
+{"Action":"output","Test":"TestVet/7","Output":"    --- PASS: TestVet/7 (0.19s)\n"}
+{"Action":"output","Test":"TestVet/7","Output":"    \tvet_test.go:114: files: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"}
+{"Action":"pass","Test":"TestVet/7"}
+{"Action":"pass","Test":"TestVet"}
+{"Action":"output","Test":"TestVetDirs","Output":"--- PASS: TestVetDirs (0.01s)\n"}
+{"Action":"output","Test":"TestVetDirs/testingpkg","Output":"    --- PASS: TestVetDirs/testingpkg (0.06s)\n"}
+{"Action":"pass","Test":"TestVetDirs/testingpkg"}
+{"Action":"output","Test":"TestVetDirs/divergent","Output":"    --- PASS: TestVetDirs/divergent (0.05s)\n"}
+{"Action":"pass","Test":"TestVetDirs/divergent"}
+{"Action":"output","Test":"TestVetDirs/buildtag","Output":"    --- PASS: TestVetDirs/buildtag (0.06s)\n"}
+{"Action":"pass","Test":"TestVetDirs/buildtag"}
+{"Action":"output","Test":"TestVetDirs/incomplete","Output":"    --- PASS: TestVetDirs/incomplete (0.05s)\n"}
+{"Action":"pass","Test":"TestVetDirs/incomplete"}
+{"Action":"output","Test":"TestVetDirs/cgo","Output":"    --- PASS: TestVetDirs/cgo (0.04s)\n"}
+{"Action":"pass","Test":"TestVetDirs/cgo"}
+{"Action":"pass","Test":"TestVetDirs"}
+{"Action":"output","Test":"TestVetAsm","Output":"--- PASS: TestVetAsm (0.75s)\n"}
+{"Action":"pass","Test":"TestVetAsm"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"output","Output":"ok  \tcmd/vet\t(cached)\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/vet.test b/src/cmd/internal/test2json/testdata/vet.test
new file mode 100644
index 0000000..3389559
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/vet.test
@@ -0,0 +1,97 @@
+=== RUN   TestVet
+=== PAUSE TestVet
+=== RUN   TestVetAsm
+=== PAUSE TestVetAsm
+=== RUN   TestVetDirs
+=== PAUSE TestVetDirs
+=== RUN   TestTags
+=== PAUSE TestTags
+=== RUN   TestVetVerbose
+=== PAUSE TestVetVerbose
+=== CONT  TestVet
+=== CONT  TestTags
+=== CONT  TestVetVerbose
+=== RUN   TestTags/testtag
+=== PAUSE TestTags/testtag
+=== CONT  TestVetDirs
+=== CONT  TestVetAsm
+=== RUN   TestVet/0
+=== PAUSE TestVet/0
+=== RUN   TestVet/1
+=== PAUSE TestVet/1
+=== RUN   TestVet/2
+=== PAUSE TestVet/2
+=== RUN   TestVet/3
+=== PAUSE TestVet/3
+=== RUN   TestVet/4
+=== RUN   TestTags/x_testtag_y
+=== PAUSE TestVet/4
+=== RUN   TestVet/5
+=== PAUSE TestVet/5
+=== PAUSE TestTags/x_testtag_y
+=== RUN   TestVet/6
+=== RUN   TestTags/x,testtag,y
+=== PAUSE TestTags/x,testtag,y
+=== RUN   TestVetDirs/testingpkg
+=== PAUSE TestVet/6
+=== CONT  TestTags/x,testtag,y
+=== PAUSE TestVetDirs/testingpkg
+=== RUN   TestVetDirs/divergent
+=== RUN   TestVet/7
+=== PAUSE TestVet/7
+=== PAUSE TestVetDirs/divergent
+=== CONT  TestTags/x_testtag_y
+=== CONT  TestTags/testtag
+=== RUN   TestVetDirs/buildtag
+=== PAUSE TestVetDirs/buildtag
+=== CONT  TestVet/0
+=== CONT  TestVet/4
+=== RUN   TestVetDirs/incomplete
+=== PAUSE TestVetDirs/incomplete
+=== RUN   TestVetDirs/cgo
+=== PAUSE TestVetDirs/cgo
+=== CONT  TestVet/7
+=== CONT  TestVet/6
+--- PASS: TestVetVerbose (0.04s)
+=== CONT  TestVet/5
+=== CONT  TestVet/3
+=== CONT  TestVet/2
+--- PASS: TestTags (0.00s)
+    --- PASS: TestTags/x_testtag_y (0.04s)
+    	vet_test.go:187: -tags=x testtag y
+    --- PASS: TestTags/x,testtag,y (0.04s)
+    	vet_test.go:187: -tags=x,testtag,y
+    --- PASS: TestTags/testtag (0.04s)
+    	vet_test.go:187: -tags=testtag
+=== CONT  TestVet/1
+=== CONT  TestVetDirs/testingpkg
+=== CONT  TestVetDirs/buildtag
+=== CONT  TestVetDirs/divergent
+=== CONT  TestVetDirs/incomplete
+=== CONT  TestVetDirs/cgo
+--- PASS: TestVet (0.39s)
+    --- PASS: TestVet/5 (0.07s)
+    	vet_test.go:114: files: ["testdata/copylock_func.go" "testdata/rangeloop.go"]
+    --- PASS: TestVet/3 (0.07s)
+    	vet_test.go:114: files: ["testdata/composite.go" "testdata/nilfunc.go"]
+    --- PASS: TestVet/6 (0.07s)
+    	vet_test.go:114: files: ["testdata/copylock_range.go" "testdata/shadow.go"]
+    --- PASS: TestVet/2 (0.07s)
+    	vet_test.go:114: files: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"]
+    --- PASS: TestVet/0 (0.13s)
+    	vet_test.go:114: files: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"]
+    --- PASS: TestVet/4 (0.16s)
+    	vet_test.go:114: files: ["testdata/copylock.go" "testdata/print.go"]
+    --- PASS: TestVet/1 (0.07s)
+    	vet_test.go:114: files: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"]
+    --- PASS: TestVet/7 (0.19s)
+    	vet_test.go:114: files: ["testdata/deadcode.go" "testdata/shift.go"]
+--- PASS: TestVetDirs (0.01s)
+    --- PASS: TestVetDirs/testingpkg (0.06s)
+    --- PASS: TestVetDirs/divergent (0.05s)
+    --- PASS: TestVetDirs/buildtag (0.06s)
+    --- PASS: TestVetDirs/incomplete (0.05s)
+    --- PASS: TestVetDirs/cgo (0.04s)
+--- PASS: TestVetAsm (0.75s)
+PASS
+ok  	cmd/vet	(cached)
diff --git a/src/cmd/link/doc.go b/src/cmd/link/doc.go
index 16fddf2..d61b66a 100644
--- a/src/cmd/link/doc.go
+++ b/src/cmd/link/doc.go
@@ -36,7 +36,7 @@
 	-T address
 		Set text segment address.
 	-V
-		Print the linker version and exit.
+		Print linker version and exit.
 	-X importpath.name=value
 		Set the value of the string variable in importpath named name to value.
 		Note that before Go 1.5 this option took two separate arguments.
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index f88aecc..2b3771e 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -32,6 +32,9 @@
 		t.Fatalf("go list: %v\n%s", err, out)
 	}
 	if string(out) != "false\n" {
+		if os.Getenv("GOROOT_FINAL_OLD") != "" {
+			t.Skip("cmd/link is stale, but $GOROOT_FINAL_OLD is set")
+		}
 		t.Fatalf("cmd/link is stale - run go install cmd/link")
 	}
 
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index d2f63d3..aad3c53 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -32,7 +32,9 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
 	"debug/elf"
 	"log"
 )
@@ -41,12 +43,12 @@
 	return x &^ 0x80000000
 }
 
-func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
-	s.Attr |= ld.AttrReachable
+func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
+	s.Attr |= sym.AttrReachable
 	i := s.Size
 	s.Size += 4
-	ld.Symgrow(s, s.Size)
-	r := ld.Addrel(s)
+	s.Grow(s.Size)
+	r := s.AddRel()
 	r.Sym = t
 	r.Off = int32(i)
 	r.Type = objabi.R_CALL
@@ -59,69 +61,82 @@
 		return
 	}
 	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
 		// we're linking a module containing the runtime -> no need for
 		// an init function
 		return
 	}
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 	o := func(op ...uint8) {
 		for _, op1 := range op {
-			ld.Adduint8(ctxt, initfunc, op1)
+			initfunc.AddUint8(op1)
 		}
 	}
 	// 0000000000000000 <local.dso_init>:
 	//    0:	48 8d 3d 00 00 00 00 	lea    0x0(%rip),%rdi        # 7 <local.dso_init+0x7>
 	// 			3: R_X86_64_PC32	runtime.firstmoduledata-0x4
 	o(0x48, 0x8d, 0x3d)
-	ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 0)
+	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 0)
 	//    7:	e8 00 00 00 00       	callq  c <local.dso_init+0xc>
 	// 			8: R_X86_64_PLT32	runtime.addmoduledata-0x4
 	o(0xe8)
 	Addcall(ctxt, initfunc, addmoduledata)
 	//    c:	c3                   	retq
 	o(0xc3)
-	if ld.Buildmode == ld.BuildmodePlugin {
+	if ctxt.BuildMode == ld.BuildModePlugin {
 		ctxt.Textp = append(ctxt.Textp, addmoduledata)
 	}
 	ctxt.Textp = append(ctxt.Textp, initfunc)
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
 	switch r.Type {
 	default:
 		if r.Type >= 256 {
-			ld.Errorf(s, "unexpected relocation type %d", r.Type)
+			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			return false
 		}
 
 		// Handle relocations found in ELF object files.
-	case 256 + ld.R_X86_64_PC32:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_X86_64_PC32):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
 		}
-		if targ.Type == 0 || targ.Type == ld.SXREF {
+		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
+		// sense and should be removed when someone has thought about it properly.
+		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
 			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
 		}
 		r.Type = objabi.R_PCREL
 		r.Add += 4
 		return true
 
-	case 256 + ld.R_X86_64_PLT32:
+	case 256 + objabi.RelocType(elf.R_X86_64_PC64):
+		if targ.Type == sym.SDYNIMPORT {
+			ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name)
+		}
+		if targ.Type == 0 || targ.Type == sym.SXREF {
+			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
+		}
+		r.Type = objabi.R_PCREL
+		r.Add += 8
+		return true
+
+	case 256 + objabi.RelocType(elf.R_X86_64_PLT32):
 		r.Type = objabi.R_PCREL
 		r.Add += 4
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add += int64(targ.Plt)
@@ -129,8 +144,8 @@
 
 		return true
 
-	case 256 + ld.R_X86_64_GOTPCREL, 256 + ld.R_X86_64_GOTPCRELX, 256 + ld.R_X86_64_REX_GOTPCRELX:
-		if targ.Type != ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_X86_64_GOTPCREL), 256 + objabi.RelocType(elf.R_X86_64_GOTPCRELX), 256 + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
+		if targ.Type != sym.SDYNIMPORT {
 			// have symbol
 			if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
 				// turn MOVQ of GOT entry into LEAQ of symbol itself
@@ -152,8 +167,8 @@
 		r.Add += int64(targ.Got)
 		return true
 
-	case 256 + ld.R_X86_64_64:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_X86_64_64):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
 		}
 		r.Type = objabi.R_ADDR
@@ -166,13 +181,13 @@
 		// TODO: What is the difference between all these?
 		r.Type = objabi.R_ADDR
 
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
 		}
 		return true
 
 	case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add = int64(targ.Plt)
@@ -189,13 +204,13 @@
 		512 + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
 		r.Type = objabi.R_PCREL
 
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
 		}
 		return true
 
 	case 512 + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
-		if targ.Type != ld.SDYNIMPORT {
+		if targ.Type != sym.SDYNIMPORT {
 			// have symbol
 			// turn MOVQ of GOT entry into LEAQ of symbol itself
 			if r.Off < 2 || s.P[r.Off-2] != 0x8b {
@@ -211,7 +226,7 @@
 
 		// fall through
 	case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
-		if targ.Type != ld.SDYNIMPORT {
+		if targ.Type != sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
 		}
 		addgotsym(ctxt, targ)
@@ -224,24 +239,19 @@
 	switch r.Type {
 	case objabi.R_CALL,
 		objabi.R_PCREL:
-		if targ.Type != ld.SDYNIMPORT {
+		if targ.Type != sym.SDYNIMPORT {
 			// nothing to do, the relocation will be laid out in reloc
 			return true
 		}
-		if ld.Headtype == objabi.Hwindows {
-			// nothing to do, the relocation will be laid out in pereloc1
-			return true
-		} else {
-			// for both ELF and Mach-O
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(targ.Plt)
-			return true
-		}
+		// for both ELF and Mach-O
+		addpltsym(ctxt, targ)
+		r.Sym = ctxt.Syms.Lookup(".plt", 0)
+		r.Add = int64(targ.Plt)
+		return true
 
 	case objabi.R_ADDR:
-		if s.Type == ld.STEXT && ld.Iself {
-			if ld.Headtype == objabi.Hsolaris {
+		if s.Type == sym.STEXT && ctxt.IsELF {
+			if ctxt.HeadType == objabi.Hsolaris {
 				addpltsym(ctxt, targ)
 				r.Sym = ctxt.Syms.Lookup(".plt", 0)
 				r.Add += int64(targ.Plt)
@@ -258,7 +268,7 @@
 		}
 
 		// Process dynamic relocations for the data sections.
-		if ld.Buildmode == ld.BuildmodePIE && ld.Linkmode == ld.LinkInternal {
+		if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
 			// When internally linking, generate dynamic relocations
 			// for all typical R_ADDR relocations. The exception
 			// are those R_ADDR that are created as part of generating
@@ -301,30 +311,30 @@
 			// linking, in which case the relocation will be
 			// prepared in the 'reloc' phase and passed to the
 			// external linker in the 'asmb' phase.
-			if s.Type != ld.SDATA && s.Type != ld.SRODATA {
+			if s.Type != sym.SDATA && s.Type != sym.SRODATA {
 				break
 			}
 		}
 
-		if ld.Iself {
+		if ctxt.IsELF {
 			// TODO: We generate a R_X86_64_64 relocation for every R_ADDR, even
 			// though it would be more efficient (for the dynamic linker) if we
 			// generated R_X86_RELATIVE instead.
 			ld.Adddynsym(ctxt, targ)
 			rela := ctxt.Syms.Lookup(".rela", 0)
-			ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
+			rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
 			if r.Siz == 8 {
-				ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
+				rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_64)))
 			} else {
 				// TODO: never happens, remove.
-				ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32))
+				rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_32)))
 			}
-			ld.Adduint64(ctxt, rela, uint64(r.Add))
+			rela.AddUint64(ctxt.Arch, uint64(r.Add))
 			r.Type = 256 // ignore during relocsym
 			return true
 		}
 
-		if ld.Headtype == objabi.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
+		if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
 			// Mach-O relocations are a royal pain to lay out.
 			// They use a compact stateful bytecode representation
 			// that is too much bother to deal with.
@@ -338,104 +348,94 @@
 			ld.Adddynsym(ctxt, targ)
 
 			got := ctxt.Syms.Lookup(".got", 0)
-			s.Type = got.Type | ld.SSUB
+			s.Type = got.Type
+			s.Attr |= sym.AttrSubSymbol
 			s.Outer = got
 			s.Sub = got.Sub
 			got.Sub = s
 			s.Value = got.Size
-			ld.Adduint64(ctxt, got, 0)
-			ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
+			got.AddUint64(ctxt.Arch, 0)
+			ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
 			r.Type = 256 // ignore during relocsym
 			return true
 		}
-
-		if ld.Headtype == objabi.Hwindows {
-			// nothing to do, the relocation will be laid out in pereloc1
-			return true
-		}
 	}
 
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Vput(uint64(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		if r.Siz == 4 {
-			ld.Thearch.Vput(ld.R_X86_64_32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_X86_64_32) | uint64(elfsym)<<32)
 		} else if r.Siz == 8 {
-			ld.Thearch.Vput(ld.R_X86_64_64 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_X86_64_64) | uint64(elfsym)<<32)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_TLS_LE:
 		if r.Siz == 4 {
-			ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_X86_64_TPOFF32) | uint64(elfsym)<<32)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_TLS_IE:
 		if r.Siz == 4 {
-			ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_X86_64_GOTTPOFF) | uint64(elfsym)<<32)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_CALL:
 		if r.Siz == 4 {
-			if r.Xsym.Type == ld.SDYNIMPORT {
+			if r.Xsym.Type == sym.SDYNIMPORT {
 				if ctxt.DynlinkingGo() {
-					ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
+					ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
 				} else {
-					ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
+					ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
 				}
 			} else {
-				ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
+				ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
 			}
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_PCREL:
 		if r.Siz == 4 {
-			if r.Xsym.Type == ld.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
-				ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
+			if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
+				ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
 			} else {
-				ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
+				ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
 			}
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_GOTPCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
 		} else {
-			return -1
+			return false
 		}
 	}
 
-	ld.Thearch.Vput(uint64(r.Xadd))
-	return 0
+	ctxt.Out.Write64(uint64(r.Xadd))
+	return true
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
 
-	if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL {
+	if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL {
 		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+			return false
 		}
 
 		v = uint32(rs.Dynid)
@@ -443,14 +443,14 @@
 	} else {
 		v = uint32(rs.Sect.Extnum)
 		if v == 0 {
-			ld.Errorf(s, "reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+			return false
 		}
 	}
 
 	switch r.Type {
 	default:
-		return -1
+		return false
 
 	case objabi.R_ADDR:
 		v |= ld.MACHO_X86_64_RELOC_UNSIGNED << 28
@@ -470,7 +470,7 @@
 
 	switch r.Siz {
 	default:
-		return -1
+		return false
 
 	case 1:
 		v |= 0 << 25
@@ -485,29 +485,29 @@
 		v |= 3 << 25
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(v)
-	return 0
+	out.Write32(uint32(sectoff))
+	out.Write32(v)
+	return true
 }
 
-func pereloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
 
 	if rs.Dynid < 0 {
-		ld.Errorf(s, "reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
+		ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
 		return false
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(uint32(rs.Dynid))
+	out.Write32(uint32(sectoff))
+	out.Write32(uint32(rs.Dynid))
 
 	switch r.Type {
 	default:
 		return false
 
-	case objabi.R_DWARFREF:
+	case objabi.R_DWARFSECREF:
 		v = ld.IMAGE_REL_AMD64_SECREL
 
 	case objabi.R_ADDR:
@@ -522,16 +522,16 @@
 		v = ld.IMAGE_REL_AMD64_REL32
 	}
 
-	ld.Thearch.Wput(uint16(v))
+	out.Write16(uint16(v))
 
 	return true
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	return -1
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return t
 }
@@ -541,36 +541,36 @@
 	got := ctxt.Syms.Lookup(".got.plt", 0)
 	if plt.Size == 0 {
 		// pushq got+8(IP)
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x35)
-		ld.Addpcrelplus(ctxt, plt, got, 8)
+		plt.AddUint8(0x35)
+		plt.AddPCRelPlus(ctxt.Arch, got, 8)
 
 		// jmpq got+16(IP)
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addpcrelplus(ctxt, plt, got, 16)
+		plt.AddUint8(0x25)
+		plt.AddPCRelPlus(ctxt.Arch, got, 16)
 
 		// nopl 0(AX)
-		ld.Adduint32(ctxt, plt, 0x00401f0f)
+		plt.AddUint32(ctxt.Arch, 0x00401f0f)
 
 		// assume got->size == 0 too
-		ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
+		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
 
-		ld.Adduint64(ctxt, got, 0)
-		ld.Adduint64(ctxt, got, 0)
+		got.AddUint64(ctxt.Arch, 0)
+		got.AddUint64(ctxt.Arch, 0)
 	}
 }
 
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Plt >= 0 {
 		return
 	}
 
 	ld.Adddynsym(ctxt, s)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		plt := ctxt.Syms.Lookup(".plt", 0)
 		got := ctxt.Syms.Lookup(".got.plt", 0)
 		rela := ctxt.Syms.Lookup(".rela.plt", 0)
@@ -579,32 +579,32 @@
 		}
 
 		// jmpq *got+size(IP)
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addpcrelplus(ctxt, plt, got, got.Size)
+		plt.AddUint8(0x25)
+		plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
 
 		// add to got: pointer to current pos in plt
-		ld.Addaddrplus(ctxt, got, plt, plt.Size)
+		got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
 
 		// pushq $x
-		ld.Adduint8(ctxt, plt, 0x68)
+		plt.AddUint8(0x68)
 
-		ld.Adduint32(ctxt, plt, uint32((got.Size-24-8)/8))
+		plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8))
 
 		// jmpq .plt
-		ld.Adduint8(ctxt, plt, 0xe9)
+		plt.AddUint8(0xe9)
 
-		ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
+		plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
 
 		// rela
-		ld.Addaddrplus(ctxt, rela, got, got.Size-8)
+		rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
 
-		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT))
-		ld.Adduint64(ctxt, rela, 0)
+		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
+		rela.AddUint64(ctxt.Arch, 0)
 
 		s.Plt = int32(plt.Size - 16)
-	} else if ld.Headtype == objabi.Hdarwin {
+	} else if ctxt.HeadType == objabi.Hdarwin {
 		// To do lazy symbol lookup right, we're supposed
 		// to tell the dynamic loader which library each
 		// symbol comes from and format the link info
@@ -618,20 +618,20 @@
 		addgotsym(ctxt, s)
 		plt := ctxt.Syms.Lookup(".plt", 0)
 
-		ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.plt", 0), uint32(s.Dynid))
+		ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
 
 		// jmpq *got+size(IP)
 		s.Plt = int32(plt.Size)
 
-		ld.Adduint8(ctxt, plt, 0xff)
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addpcrelplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
+		plt.AddUint8(0xff)
+		plt.AddUint8(0x25)
+		plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
 	} else {
 		ld.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
 
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Got >= 0 {
 		return
 	}
@@ -639,15 +639,15 @@
 	ld.Adddynsym(ctxt, s)
 	got := ctxt.Syms.Lookup(".got", 0)
 	s.Got = int32(got.Size)
-	ld.Adduint64(ctxt, got, 0)
+	got.AddUint64(ctxt.Arch, 0)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		rela := ctxt.Syms.Lookup(".rela", 0)
-		ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
-		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
-		ld.Adduint64(ctxt, rela, 0)
-	} else if ld.Headtype == objabi.Hdarwin {
-		ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(s.Dynid))
+		rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
+		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
+		rela.AddUint64(ctxt.Arch, 0)
+	} else if ctxt.HeadType == objabi.Hdarwin {
+		ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
 	} else {
 		ld.Errorf(s, "addgotsym: unsupported binary format")
 	}
@@ -662,16 +662,16 @@
 		ctxt.Logf("%5.2f codeblk\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	// 0xCC is INT $3 - breakpoint instruction
 	ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -679,14 +679,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -694,20 +694,20 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	machlink := int64(0)
-	if ld.Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		machlink = ld.Domacholink(ctxt)
 	}
 
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Errorf(nil, "unknown header type %v", ld.Headtype)
+		ld.Errorf(nil, "unknown header type %v", ctxt.HeadType)
 		fallthrough
 
 	case objabi.Hplan9:
@@ -737,7 +737,7 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
 		case objabi.Hplan9:
 			*ld.FlagS = true
@@ -761,36 +761,33 @@
 			symo = ld.Rnd(symo, ld.PEFILEALIGN)
 		}
 
-		ld.Cseek(symo)
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(symo)
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
-				ld.Cseek(symo)
+			if ctxt.IsELF {
+				ctxt.Out.SeekSet(symo)
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
 				}
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 
 		case objabi.Hwindows:
@@ -799,7 +796,7 @@
 			}
 
 		case objabi.Hdarwin:
-			if ld.Linkmode == ld.LinkExternal {
+			if ctxt.LinkMode == ld.LinkExternal {
 				ld.Machoemitreloc(ctxt)
 			}
 		}
@@ -808,23 +805,23 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f headr\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan9 */
 		magic := int32(4*26*26 + 7)
 
-		magic |= 0x00008000                  /* fat header */
-		ld.Lputb(uint32(magic))              /* magic */
-		ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Lputb(uint32(ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Symsize)) /* nsyms */
+		magic |= 0x00008000                           /* fat header */
+		ctxt.Out.Write32b(uint32(magic))              /* magic */
+		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Symsize)) /* nsyms */
 		vl := ld.Entryvalue(ctxt)
-		ld.Lputb(PADDR(uint32(vl))) /* va of entry */
-		ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
-		ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
-		ld.Vputb(uint64(vl))        /* va of entry */
+		ctxt.Out.Write32b(PADDR(uint32(vl))) /* va of entry */
+		ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
+		ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
+		ctxt.Out.Write64b(uint64(vl))        /* va of entry */
 
 	case objabi.Hdarwin:
 		ld.Asmbmacho(ctxt)
@@ -842,10 +839,10 @@
 		ld.Asmbpe(ctxt)
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 }
 
-func tlsIEtoLE(s *ld.Symbol, off, size int) {
+func tlsIEtoLE(s *sym.Symbol, off, size int) {
 	// Transform the PC-relative instruction into a constant load.
 	// That is,
 	//
diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go
index ef69c26..87e8091 100644
--- a/src/cmd/link/internal/amd64/obj.go
+++ b/src/cmd/link/internal/amd64/obj.go
@@ -37,48 +37,46 @@
 	"fmt"
 )
 
-func Init() {
-	ld.SysArch = sys.ArchAMD64
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchAMD64
 	if objabi.GOARCH == "amd64p32" {
-		ld.SysArch = sys.ArchAMD64P32
+		arch = sys.ArchAMD64P32
 	}
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	ld.Thearch.PEreloc1 = pereloc1
-	ld.Thearch.Lput = ld.Lputl
-	ld.Thearch.Wput = ld.Wputl
-	ld.Thearch.Vput = ld.Vputl
-	ld.Thearch.Append16 = ld.Append16l
-	ld.Thearch.Append32 = ld.Append32l
-	ld.Thearch.Append64 = ld.Append64l
-	ld.Thearch.TLSIEtoLE = tlsIEtoLE
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
+		PEreloc1:         pereloc1,
+		TLSIEtoLE:        tlsIEtoLE,
 
-	ld.Thearch.Linuxdynld = "/lib64/ld-linux-x86-64.so.2"
-	ld.Thearch.Freebsddynld = "/libexec/ld-elf.so.1"
-	ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
-	ld.Thearch.Netbsddynld = "/libexec/ld.elf_so"
-	ld.Thearch.Dragonflydynld = "/usr/libexec/ld-elf.so.2"
-	ld.Thearch.Solarisdynld = "/lib/amd64/ld.so.1"
+		Linuxdynld:     "/lib64/ld-linux-x86-64.so.2",
+		Freebsddynld:   "/libexec/ld-elf.so.1",
+		Openbsddynld:   "/usr/libexec/ld.so",
+		Netbsddynld:    "/libexec/ld.elf_so",
+		Dragonflydynld: "/usr/libexec/ld-elf.so.2",
+		Solarisdynld:   "/lib/amd64/ld.so.1",
+	}
+
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32 + 8
@@ -94,8 +92,6 @@
 		}
 
 	case objabi.Hdarwin: /* apple MACH */
-		ld.Machoinit()
-
 		ld.HEADR = ld.INITIAL_MACHO_HEADR
 		if *ld.FlagRound == -1 {
 			*ld.FlagRound = 4096
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
index 0f281c1..93c2a85 100644
--- a/src/cmd/link/internal/arm/asm.go
+++ b/src/cmd/link/internal/arm/asm.go
@@ -32,7 +32,10 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"fmt"
 	"log"
 )
@@ -63,24 +66,24 @@
 		return
 	}
 	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
 		// we're linking a module containing the runtime -> no need for
 		// an init function
 		return
 	}
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 	o := func(op uint32) {
-		ld.Adduint32(ctxt, initfunc, op)
+		initfunc.AddUint32(ctxt.Arch, op)
 	}
 	o(0xe59f0004)
 	o(0xe08f0000)
 
 	o(0xeafffffe)
-	rel := ld.Addrel(initfunc)
+	rel := initfunc.AddRel()
 	rel.Off = 8
 	rel.Siz = 4
 	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
@@ -88,22 +91,22 @@
 	rel.Add = 0xeafffffe // vomit
 
 	o(0x00000000)
-	rel = ld.Addrel(initfunc)
+	rel = initfunc.AddRel()
 	rel.Off = 12
 	rel.Siz = 4
 	rel.Sym = ctxt.Moduledata
 	rel.Type = objabi.R_PCREL
 	rel.Add = 4
 
-	if ld.Buildmode == ld.BuildmodePlugin {
+	if ctxt.BuildMode == ld.BuildModePlugin {
 		ctxt.Textp = append(ctxt.Textp, addmoduledata)
 	}
 	ctxt.Textp = append(ctxt.Textp, initfunc)
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
 // Preserve highest 8 bits of a, and do addition to lower 24-bit
@@ -112,21 +115,21 @@
 	return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
 	switch r.Type {
 	default:
 		if r.Type >= 256 {
-			ld.Errorf(s, "unexpected relocation type %d", r.Type)
+			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			return false
 		}
 
 		// Handle relocations found in ELF object files.
-	case 256 + ld.R_ARM_PLT32:
+	case 256 + objabi.RelocType(elf.R_ARM_PLT32):
 		r.Type = objabi.R_CALLARM
 
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
@@ -134,12 +137,12 @@
 
 		return true
 
-	case 256 + ld.R_ARM_THM_PC22: // R_ARM_THM_CALL
+	case 256 + objabi.RelocType(elf.R_ARM_THM_PC22): // R_ARM_THM_CALL
 		ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
 		return false
 
-	case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
-		if targ.Type != ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
+		if targ.Type != sym.SDYNIMPORT {
 			addgotsyminternal(ctxt, targ)
 		} else {
 			addgotsym(ctxt, targ)
@@ -150,8 +153,8 @@
 		r.Add += int64(targ.Got)
 		return true
 
-	case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
-		if targ.Type != ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
+		if targ.Type != sym.SDYNIMPORT {
 			addgotsyminternal(ctxt, targ)
 		} else {
 			addgotsym(ctxt, targ)
@@ -162,21 +165,21 @@
 		r.Add += int64(targ.Got) + 4
 		return true
 
-	case 256 + ld.R_ARM_GOTOFF: // R_ARM_GOTOFF32
+	case 256 + objabi.RelocType(elf.R_ARM_GOTOFF): // R_ARM_GOTOFF32
 		r.Type = objabi.R_GOTOFF
 
 		return true
 
-	case 256 + ld.R_ARM_GOTPC: // R_ARM_BASE_PREL
+	case 256 + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
 		r.Type = objabi.R_PCREL
 
 		r.Sym = ctxt.Syms.Lookup(".got", 0)
 		r.Add += 4
 		return true
 
-	case 256 + ld.R_ARM_CALL:
+	case 256 + objabi.RelocType(elf.R_ARM_CALL):
 		r.Type = objabi.R_CALLARM
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
@@ -184,21 +187,21 @@
 
 		return true
 
-	case 256 + ld.R_ARM_REL32: // R_ARM_REL32
+	case 256 + objabi.RelocType(elf.R_ARM_REL32): // R_ARM_REL32
 		r.Type = objabi.R_PCREL
 
 		r.Add += 4
 		return true
 
-	case 256 + ld.R_ARM_ABS32:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_ARM_ABS32):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
 		}
 		r.Type = objabi.R_ADDR
 		return true
 
 		// we can just ignore this, because we are targeting ARM V5+ anyway
-	case 256 + ld.R_ARM_V4BX:
+	case 256 + objabi.RelocType(elf.R_ARM_V4BX):
 		if r.Sym != nil {
 			// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
 			r.Sym.Type = 0
@@ -207,10 +210,10 @@
 		r.Sym = nil
 		return true
 
-	case 256 + ld.R_ARM_PC24,
-		256 + ld.R_ARM_JUMP24:
+	case 256 + objabi.RelocType(elf.R_ARM_PC24),
+		256 + objabi.RelocType(elf.R_ARM_JUMP24):
 		r.Type = objabi.R_CALLARM
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
@@ -220,7 +223,7 @@
 	}
 
 	// Handle references to ELF symbols from our own object files.
-	if targ.Type != ld.SDYNIMPORT {
+	if targ.Type != sym.SDYNIMPORT {
 		return true
 	}
 
@@ -232,15 +235,15 @@
 		return true
 
 	case objabi.R_ADDR:
-		if s.Type != ld.SDATA {
+		if s.Type != sym.SDATA {
 			break
 		}
-		if ld.Iself {
+		if ctxt.IsELF {
 			ld.Adddynsym(ctxt, targ)
 			rel := ctxt.Syms.Lookup(".rel", 0)
-			ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
-			ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynamic reloc
-			r.Type = objabi.R_CONST                                                         // write r->add during relocsym
+			rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
+			rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
+			r.Type = objabi.R_CONST                                                                   // write r->add during relocsym
 			r.Sym = nil
 			return true
 		}
@@ -249,54 +252,48 @@
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Lput(uint32(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_ARM_ABS32 | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_PCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_ARM_REL32 | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_CALLARM:
 		if r.Siz == 4 {
 			if r.Add&0xff000000 == 0xeb000000 { // BL
-				ld.Thearch.Lput(ld.R_ARM_CALL | uint32(elfsym)<<8)
+				ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
 			} else {
-				ld.Thearch.Lput(ld.R_ARM_JUMP24 | uint32(elfsym)<<8)
+				ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8)
 			}
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_TLS_LE:
-		ld.Thearch.Lput(ld.R_ARM_TLS_LE32 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
 	case objabi.R_TLS_IE:
-		ld.Thearch.Lput(ld.R_ARM_TLS_IE32 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
 	case objabi.R_GOTPCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_ARM_GOT_PREL | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
 	}
 
-	return 0
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
@@ -304,40 +301,40 @@
 	got := ctxt.Syms.Lookup(".got.plt", 0)
 	if plt.Size == 0 {
 		// str lr, [sp, #-4]!
-		ld.Adduint32(ctxt, plt, 0xe52de004)
+		plt.AddUint32(ctxt.Arch, 0xe52de004)
 
 		// ldr lr, [pc, #4]
-		ld.Adduint32(ctxt, plt, 0xe59fe004)
+		plt.AddUint32(ctxt.Arch, 0xe59fe004)
 
 		// add lr, pc, lr
-		ld.Adduint32(ctxt, plt, 0xe08fe00e)
+		plt.AddUint32(ctxt.Arch, 0xe08fe00e)
 
 		// ldr pc, [lr, #8]!
-		ld.Adduint32(ctxt, plt, 0xe5bef008)
+		plt.AddUint32(ctxt.Arch, 0xe5bef008)
 
 		// .word &GLOBAL_OFFSET_TABLE[0] - .
-		ld.Addpcrelplus(ctxt, plt, got, 4)
+		plt.AddPCRelPlus(ctxt.Arch, got, 4)
 
 		// the first .plt entry requires 3 .plt.got entries
-		ld.Adduint32(ctxt, got, 0)
+		got.AddUint32(ctxt.Arch, 0)
 
-		ld.Adduint32(ctxt, got, 0)
-		ld.Adduint32(ctxt, got, 0)
+		got.AddUint32(ctxt.Arch, 0)
+		got.AddUint32(ctxt.Arch, 0)
 	}
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
 
 	if r.Type == objabi.R_PCREL {
-		if rs.Type == ld.SHOSTOBJ {
+		if rs.Type == sym.SHOSTOBJ {
 			ld.Errorf(s, "pc-relative relocation of external symbol is not supported")
-			return -1
+			return false
 		}
 		if r.Siz != 4 {
-			return -1
+			return false
 		}
 
 		// emit a pair of "scattered" relocations that
@@ -354,17 +351,17 @@
 		o2 |= ld.MACHO_ARM_RELOC_PAIR << 24
 		o2 |= 2 << 28 // size = 4
 
-		ld.Thearch.Lput(o1)
-		ld.Thearch.Lput(uint32(ld.Symaddr(rs)))
-		ld.Thearch.Lput(o2)
-		ld.Thearch.Lput(uint32(s.Value + int64(r.Off)))
-		return 0
+		out.Write32(o1)
+		out.Write32(uint32(ld.Symaddr(rs)))
+		out.Write32(o2)
+		out.Write32(uint32(s.Value + int64(r.Off)))
+		return true
 	}
 
-	if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM {
+	if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM {
 		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+			return false
 		}
 
 		v = uint32(rs.Dynid)
@@ -372,14 +369,14 @@
 	} else {
 		v = uint32(rs.Sect.Extnum)
 		if v == 0 {
-			ld.Errorf(s, "reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+			return false
 		}
 	}
 
 	switch r.Type {
 	default:
-		return -1
+		return false
 
 	case objabi.R_ADDR:
 		v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
@@ -391,8 +388,7 @@
 
 	switch r.Siz {
 	default:
-		return -1
-
+		return false
 	case 1:
 		v |= 0 << 25
 
@@ -406,9 +402,9 @@
 		v |= 3 << 25
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(v)
-	return 0
+	out.Write32(uint32(sectoff))
+	out.Write32(v)
+	return true
 }
 
 // sign extend a 24-bit integer
@@ -428,7 +424,7 @@
 }
 
 // Convert the direct jump relocation r to refer to a trampoline if the target is too far
-func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
+func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
 	switch r.Type {
 	case objabi.R_CALLARM:
 		// r.Add is the instruction
@@ -439,11 +435,11 @@
 			// look up existing trampolines first. if we found one within the range
 			// of direct call, we can reuse it. otherwise create a new one.
 			offset := (signext24(r.Add&0xffffff) + 2) * 4
-			var tramp *ld.Symbol
+			var tramp *sym.Symbol
 			for i := 0; ; i++ {
 				name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
 				tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
-				if tramp.Type == ld.SDYNIMPORT {
+				if tramp.Type == sym.SDYNIMPORT {
 					// don't reuse trampoline defined in other module
 					continue
 				}
@@ -468,37 +464,37 @@
 					if immrot(uint32(offset)) == 0 {
 						ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
 					}
-					gentrampdyn(tramp, r.Sym, int64(offset))
-				} else if ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE {
-					gentramppic(tramp, r.Sym, int64(offset))
+					gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
+				} else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
+					gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
 				} else {
-					gentramp(tramp, r.Sym, int64(offset))
+					gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(offset))
 				}
 			}
 			// modify reloc to point to tramp, which will be resolved later
 			r.Sym = tramp
 			r.Add = r.Add&0xff000000 | 0xfffffe // clear the offset embedded in the instruction
-			r.Done = 0
+			r.Done = false
 		}
 	default:
-		ld.Errorf(s, "trampoline called with non-jump reloc: %v", r.Type)
+		ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 	}
 }
 
 // generate a trampoline to target+offset
-func gentramp(tramp, target *ld.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
 	tramp.Size = 12 // 3 instructions
 	tramp.P = make([]byte, tramp.Size)
 	t := ld.Symaddr(target) + int64(offset)
 	o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
 	o2 := uint32(0xe12fff10 | 11)              // JMP  (R11)
 	o3 := uint32(t)                            // WORD $target
-	ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
+	arch.ByteOrder.PutUint32(tramp.P, o1)
+	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
+	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
 
-	if ld.Linkmode == ld.LinkExternal {
-		r := ld.Addrel(tramp)
+	if linkmode == ld.LinkExternal {
+		r := tramp.AddRel()
 		r.Off = 8
 		r.Type = objabi.R_ADDR
 		r.Siz = 4
@@ -508,19 +504,19 @@
 }
 
 // generate a trampoline to target+offset in position independent code
-func gentramppic(tramp, target *ld.Symbol, offset int64) {
+func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
 	tramp.Size = 16 // 4 instructions
 	tramp.P = make([]byte, tramp.Size)
 	o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4)  // MOVW 4(R15), R11 // R15 is actual pc + 8
 	o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
 	o3 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
 	o4 := uint32(0)                                 // WORD $(target-pc) // filled in with relocation
-	ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
+	arch.ByteOrder.PutUint32(tramp.P, o1)
+	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
+	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
+	arch.ByteOrder.PutUint32(tramp.P[12:], o4)
 
-	r := ld.Addrel(tramp)
+	r := tramp.AddRel()
 	r.Off = 12
 	r.Type = objabi.R_PCREL
 	r.Siz = 4
@@ -529,7 +525,7 @@
 }
 
 // generate a trampoline to target+offset in dynlink mode (using GOT)
-func gentrampdyn(tramp, target *ld.Symbol, offset int64) {
+func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
 	tramp.Size = 20                                 // 5 instructions
 	o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8)  // MOVW 8(R15), R11 // R15 is actual pc + 8
 	o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
@@ -546,16 +542,16 @@
 		o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12)                     // MOVW 12(R15), R11
 	}
 	tramp.P = make([]byte, tramp.Size)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[16:], o5)
+	arch.ByteOrder.PutUint32(tramp.P, o1)
+	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
+	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
+	arch.ByteOrder.PutUint32(tramp.P[12:], o4)
+	arch.ByteOrder.PutUint32(tramp.P[16:], o5)
 	if offset != 0 {
-		ld.SysArch.ByteOrder.PutUint32(tramp.P[20:], o6)
+		arch.ByteOrder.PutUint32(tramp.P[20:], o6)
 	}
 
-	r := ld.Addrel(tramp)
+	r := tramp.AddRel()
 	r.Off = 16
 	r.Type = objabi.R_GOTPCREL
 	r.Siz = 4
@@ -568,11 +564,11 @@
 	}
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
 		switch r.Type {
 		case objabi.R_CALLARM:
-			r.Done = 0
+			r.Done = false
 
 			// set up addend for eventual relocation via outer symbol.
 			rs := r.Sym
@@ -584,7 +580,7 @@
 				rs = rs.Outer
 			}
 
-			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 				ld.Errorf(s, "missing section for %s", rs.Name)
 			}
 			r.Xsym = rs
@@ -594,7 +590,7 @@
 			// the section load address.
 			// we need to compensate that by removing the instruction's address
 			// from addend.
-			if ld.Headtype == objabi.Hdarwin {
+			if ctxt.HeadType == objabi.Hdarwin {
 				r.Xadd -= ld.Symaddr(s) + int64(r.Off)
 			}
 
@@ -603,20 +599,19 @@
 			}
 
 			*val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4))))
-			return 0
+			return true
 		}
 
-		return -1
+		return false
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
+		return true
 
 	// The following three arch specific relocations are only for generation of
 	// Linux/ARM ELF's PLT entry (3 assembler instruction)
@@ -625,18 +620,15 @@
 			ld.Errorf(s, ".got.plt should be placed after .plt section.")
 		}
 		*val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20))
-		return 0
-
+		return true
 	case objabi.R_PLT1: // add ip, ip, #0xYY000
 		*val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12))
 
-		return 0
-
+		return true
 	case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
 		*val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8)))
 
-		return 0
-
+		return true
 	case objabi.R_CALLARM: // bl XXXXXX or b YYYYYY
 		// r.Add is the instruction
 		// low 24-bit encodes the target address
@@ -646,40 +638,40 @@
 		}
 		*val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t)))
 
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return t
 }
 
-func addpltreloc(ctxt *ld.Link, plt *ld.Symbol, got *ld.Symbol, sym *ld.Symbol, typ objabi.RelocType) *ld.Reloc {
-	r := ld.Addrel(plt)
+func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) *sym.Reloc {
+	r := plt.AddRel()
 	r.Sym = got
 	r.Off = int32(plt.Size)
 	r.Siz = 4
 	r.Type = typ
-	r.Add = int64(sym.Got) - 8
+	r.Add = int64(s.Got) - 8
 
-	plt.Attr |= ld.AttrReachable
+	plt.Attr |= sym.AttrReachable
 	plt.Size += 4
-	ld.Symgrow(plt, plt.Size)
+	plt.Grow(plt.Size)
 
 	return r
 }
 
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Plt >= 0 {
 		return
 	}
 
 	ld.Adddynsym(ctxt, s)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		plt := ctxt.Syms.Lookup(".plt", 0)
 		got := ctxt.Syms.Lookup(".got.plt", 0)
 		rel := ctxt.Syms.Lookup(".rel.plt", 0)
@@ -693,7 +685,7 @@
 		// In theory, all GOT should point to the first PLT entry,
 		// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
 		// dynamic linker won't, so we'd better do it ourselves.
-		ld.Addaddrplus(ctxt, got, plt, 0)
+		got.AddAddrPlus(ctxt.Arch, plt, 0)
 
 		// .plt entry, this depends on the .got entry
 		s.Plt = int32(plt.Size)
@@ -703,15 +695,15 @@
 		addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
 
 		// rel
-		ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
+		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
 
-		ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT))
+		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
 	} else {
 		ld.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
 
-func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Got >= 0 {
 		return
 	}
@@ -719,15 +711,15 @@
 	got := ctxt.Syms.Lookup(".got", 0)
 	s.Got = int32(got.Size)
 
-	ld.Addaddrplus(ctxt, got, s, 0)
+	got.AddAddrPlus(ctxt.Arch, s, 0)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 	} else {
 		ld.Errorf(s, "addgotsyminternal: unsupported binary format")
 	}
 }
 
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Got >= 0 {
 		return
 	}
@@ -735,12 +727,12 @@
 	ld.Adddynsym(ctxt, s)
 	got := ctxt.Syms.Lookup(".got", 0)
 	s.Got = int32(got.Size)
-	ld.Adduint32(ctxt, got, 0)
+	got.AddUint32(ctxt.Arch, 0)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		rel := ctxt.Syms.Lookup(".rel", 0)
-		ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
-		ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
+		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
+		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
 	} else {
 		ld.Errorf(s, "addgotsym: unsupported binary format")
 	}
@@ -751,15 +743,15 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -767,14 +759,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -782,14 +774,14 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	machlink := uint32(0)
-	if ld.Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		machlink = uint32(ld.Domacholink(ctxt))
 	}
 
@@ -803,9 +795,9 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 			}
@@ -817,38 +809,35 @@
 			symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
 		}
 
-		ld.Cseek(int64(symo))
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(int64(symo))
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 				}
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 
 		case objabi.Hdarwin:
-			if ld.Linkmode == ld.LinkExternal {
+			if ctxt.LinkMode == ld.LinkExternal {
 				ld.Machoemitreloc(ctxt)
 			}
 		}
@@ -857,18 +846,18 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan 9 */
-		ld.Lputb(0x647)                      /* magic */
-		ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Lputb(uint32(ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Symsize))          /* nsyms */
-		ld.Lputb(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ld.Lputb(0)
-		ld.Lputb(uint32(ld.Lcsize))
+		ctxt.Out.Write32b(0x647)                      /* magic */
+		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
+		ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+		ctxt.Out.Write32b(0)
+		ctxt.Out.Write32b(uint32(ld.Lcsize))
 
 	case objabi.Hlinux,
 		objabi.Hfreebsd,
@@ -881,7 +870,7 @@
 		ld.Asmbmacho(ctxt)
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go
index 2975e5d..da16f92 100644
--- a/src/cmd/link/internal/arm/obj.go
+++ b/src/cmd/link/internal/arm/obj.go
@@ -37,44 +37,42 @@
 	"fmt"
 )
 
-func Init() {
-	ld.SysArch = sys.ArchARM
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchARM
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Trampoline = trampoline
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	ld.Thearch.Lput = ld.Lputl
-	ld.Thearch.Wput = ld.Wputl
-	ld.Thearch.Vput = ld.Vputl
-	ld.Thearch.Append16 = ld.Append16l
-	ld.Thearch.Append32 = ld.Append32l
-	ld.Thearch.Append64 = ld.Append64l
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Trampoline:       trampoline,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
 
-	ld.Thearch.Linuxdynld = "/lib/ld-linux.so.3" // 2 for OABI, 3 for EABI
-	ld.Thearch.Freebsddynld = "/usr/libexec/ld-elf.so.1"
-	ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
-	ld.Thearch.Netbsddynld = "/libexec/ld.elf_so"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+		Linuxdynld:     "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
+		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
+		Openbsddynld:   "/usr/libexec/ld.so",
+		Netbsddynld:    "/libexec/ld.elf_so",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
+	}
+
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32
@@ -123,7 +121,6 @@
 
 	case objabi.Hdarwin: /* apple MACH */
 		*ld.FlagW = true // disable DWARF generation
-		ld.Machoinit()
 		ld.HEADR = ld.INITIAL_MACHO_HEADR
 		if *ld.FlagTextAddr == -1 {
 			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 92a87f9..d824559 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -32,7 +32,10 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"encoding/binary"
 	"fmt"
 	"log"
@@ -43,18 +46,18 @@
 		return
 	}
 	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT {
+	if addmoduledata.Type == sym.STEXT {
 		// we're linking a module containing the runtime -> no need for
 		// an init function
 		return
 	}
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 	o := func(op uint32) {
-		ld.Adduint32(ctxt, initfunc, op)
+		initfunc.AddUint32(ctxt.Arch, op)
 	}
 	// 0000000000000000 <local.dso_init>:
 	// 0:	90000000 	adrp	x0, 0 <runtime.firstmoduledata>
@@ -63,7 +66,7 @@
 	// 	4: R_AARCH64_ADD_ABS_LO12_NC	local.moduledata
 	o(0x90000000)
 	o(0x91000000)
-	rel := ld.Addrel(initfunc)
+	rel := initfunc.AddRel()
 	rel.Off = 0
 	rel.Siz = 8
 	rel.Sym = ctxt.Moduledata
@@ -72,7 +75,7 @@
 	// 8:	14000000 	bl	0 <runtime.addmoduledata>
 	// 	8: R_AARCH64_CALL26	runtime.addmoduledata
 	o(0x14000000)
-	rel = ld.Addrel(initfunc)
+	rel = initfunc.AddRel()
 	rel.Off = 8
 	rel.Siz = 4
 	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
@@ -80,67 +83,61 @@
 
 	ctxt.Textp = append(ctxt.Textp, initfunc)
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	log.Fatalf("adddynrel not implemented")
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Vput(uint64(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		switch r.Siz {
 		case 4:
-			ld.Thearch.Vput(ld.R_AARCH64_ABS32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
 		case 8:
-			ld.Thearch.Vput(ld.R_AARCH64_ABS64 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS64) | uint64(elfsym)<<32)
 		default:
-			return -1
+			return false
 		}
-
 	case objabi.R_ADDRARM64:
 		// two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC
-		ld.Thearch.Vput(ld.R_AARCH64_ADR_PREL_PG_HI21 | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_AARCH64_ADD_ABS_LO12_NC | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_PREL_PG_HI21) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADD_ABS_LO12_NC) | uint64(elfsym)<<32)
 	case objabi.R_ARM64_TLS_LE:
-		ld.Thearch.Vput(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSLE_MOVW_TPREL_G0) | uint64(elfsym)<<32)
 	case objabi.R_ARM64_TLS_IE:
-		ld.Thearch.Vput(ld.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) | uint64(elfsym)<<32)
 	case objabi.R_ARM64_GOTPCREL:
-		ld.Thearch.Vput(ld.R_AARCH64_ADR_GOT_PAGE | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_AARCH64_LD64_GOT_LO12_NC | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_GOT_PAGE) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_LD64_GOT_LO12_NC) | uint64(elfsym)<<32)
 	case objabi.R_CALLARM64:
 		if r.Siz != 4 {
-			return -1
+			return false
 		}
-		ld.Thearch.Vput(ld.R_AARCH64_CALL26 | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32)
 
 	}
-	ld.Thearch.Vput(uint64(r.Xadd))
+	ctxt.Out.Write64(uint64(r.Xadd))
 
-	return 0
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
@@ -148,7 +145,7 @@
 	return
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
@@ -156,10 +153,10 @@
 	// ld64 has a bug handling MACHO_ARM64_RELOC_UNSIGNED with !extern relocation.
 	// see cmd/internal/ld/data.go for details. The workaround is that don't use !extern
 	// UNSIGNED relocation at all.
-	if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
+	if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
 		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+			return false
 		}
 
 		v = uint32(rs.Dynid)
@@ -167,18 +164,16 @@
 	} else {
 		v = uint32(rs.Sect.Extnum)
 		if v == 0 {
-			ld.Errorf(s, "reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+			return false
 		}
 	}
 
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
-
 	case objabi.R_CALLARM64:
 		if r.Xadd != 0 {
 			ld.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
@@ -186,20 +181,19 @@
 
 		v |= 1 << 24 // pc-relative bit
 		v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28
-
 	case objabi.R_ADDRARM64:
 		r.Siz = 4
 		// Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21
 		// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
 		if r.Xadd != 0 {
-			ld.Thearch.Lput(uint32(sectoff + 4))
-			ld.Thearch.Lput((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+			out.Write32(uint32(sectoff + 4))
+			out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
 		}
-		ld.Thearch.Lput(uint32(sectoff + 4))
-		ld.Thearch.Lput(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
+		out.Write32(uint32(sectoff + 4))
+		out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
 		if r.Xadd != 0 {
-			ld.Thearch.Lput(uint32(sectoff))
-			ld.Thearch.Lput((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+			out.Write32(uint32(sectoff))
+			out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
 		}
 		v |= 1 << 24 // pc-relative bit
 		v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
@@ -207,32 +201,27 @@
 
 	switch r.Siz {
 	default:
-		return -1
-
+		return false
 	case 1:
 		v |= 0 << 25
-
 	case 2:
 		v |= 1 << 25
-
 	case 4:
 		v |= 2 << 25
-
 	case 8:
 		v |= 3 << 25
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(v)
-	return 0
+	out.Write32(uint32(sectoff))
+	out.Write32(v)
+	return true
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
 		switch r.Type {
 		default:
-			return -1
-
+			return false
 		case objabi.R_ARM64_GOTPCREL:
 			var o1, o2 uint32
 			if ctxt.Arch.ByteOrder == binary.BigEndian {
@@ -250,7 +239,7 @@
 			// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
 			// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
 			// add + R_ADDRARM64.
-			if !(r.Sym.Version != 0 || (r.Sym.Type&ld.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == ld.STEXT && ctxt.DynlinkingGo() {
+			if !(r.Sym.Version != 0 || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
 				if o2&0xffc00000 != 0xf9400000 {
 					ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
 				}
@@ -263,9 +252,8 @@
 				*val = int64(o2)<<32 | int64(o1)
 			}
 			fallthrough
-
 		case objabi.R_ADDRARM64:
-			r.Done = 0
+			r.Done = false
 
 			// set up addend for eventual relocation via outer symbol.
 			rs := r.Sym
@@ -275,7 +263,7 @@
 				rs = rs.Outer
 			}
 
-			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 				ld.Errorf(s, "missing section for %s", rs.Name)
 			}
 			r.Xsym = rs
@@ -285,7 +273,7 @@
 			// the BR26 relocation should be fully resolved at link time.
 			// That is the reason why the next if block is disabled. When the bug in ld64
 			// is fixed, we can enable this block and also enable duff's device in cmd/7g.
-			if false && ld.Headtype == objabi.Hdarwin {
+			if false && ctxt.HeadType == objabi.Hdarwin {
 				var o0, o1 uint32
 
 				if ctxt.Arch.ByteOrder == binary.BigEndian {
@@ -312,27 +300,24 @@
 				}
 			}
 
-			return 0
-
+			return true
 		case objabi.R_CALLARM64,
 			objabi.R_ARM64_TLS_LE,
 			objabi.R_ARM64_TLS_IE:
-			r.Done = 0
+			r.Done = false
 			r.Xsym = r.Sym
 			r.Xadd = r.Add
-			return 0
+			return true
 		}
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
-
+		return true
 	case objabi.R_ADDRARM64:
 		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
 		if t >= 1<<32 || t < -1<<32 {
@@ -358,35 +343,33 @@
 		} else {
 			*val = int64(o1)<<32 | int64(o0)
 		}
-		return 0
-
+		return true
 	case objabi.R_ARM64_TLS_LE:
-		r.Done = 0
-		if ld.Headtype != objabi.Hlinux {
-			ld.Errorf(s, "TLS reloc on unsupported OS %v", ld.Headtype)
+		r.Done = false
+		if ctxt.HeadType != objabi.Hlinux {
+			ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
 		}
 		// The TCB is two pointers. This is not documented anywhere, but is
 		// de facto part of the ABI.
-		v := r.Sym.Value + int64(2*ld.SysArch.PtrSize)
+		v := r.Sym.Value + int64(2*ctxt.Arch.PtrSize)
 		if v < 0 || v >= 32678 {
 			ld.Errorf(s, "TLS offset out of range %d", v)
 		}
 		*val |= v << 5
-		return 0
-
+		return true
 	case objabi.R_CALLARM64:
 		t := (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
 		if t >= 1<<27 || t < -1<<27 {
 			ld.Errorf(s, "program too large, call relocation distance = %d", t)
 		}
 		*val |= (t >> 2) & 0x03ffffff
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
@@ -396,15 +379,15 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -412,14 +395,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -427,14 +410,14 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	machlink := uint32(0)
-	if ld.Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		machlink = uint32(ld.Domacholink(ctxt))
 	}
 
@@ -448,9 +431,9 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 			}
@@ -462,38 +445,35 @@
 			symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
 		}
 
-		ld.Cseek(int64(symo))
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(int64(symo))
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 				}
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 
 		case objabi.Hdarwin:
-			if ld.Linkmode == ld.LinkExternal {
+			if ctxt.LinkMode == ld.LinkExternal {
 				ld.Machoemitreloc(ctxt)
 			}
 		}
@@ -502,18 +482,18 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan 9 */
-		ld.Thearch.Lput(0x647)                      /* magic */
-		ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Symsize))          /* nsyms */
-		ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ld.Thearch.Lput(0)
-		ld.Thearch.Lput(uint32(ld.Lcsize))
+		ctxt.Out.Write32(0x647)                      /* magic */
+		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
+		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+		ctxt.Out.Write32(0)
+		ctxt.Out.Write32(uint32(ld.Lcsize))
 
 	case objabi.Hlinux,
 		objabi.Hfreebsd,
@@ -526,7 +506,7 @@
 		ld.Asmbmacho(ctxt)
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index dce9beb..6b386ad 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -37,44 +37,42 @@
 	"fmt"
 )
 
-func Init() {
-	ld.SysArch = sys.ArchARM64
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchARM64
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	ld.Thearch.Lput = ld.Lputl
-	ld.Thearch.Wput = ld.Wputl
-	ld.Thearch.Vput = ld.Vputl
-	ld.Thearch.Append16 = ld.Append16l
-	ld.Thearch.Append32 = ld.Append32l
-	ld.Thearch.Append64 = ld.Append64l
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
 
-	ld.Thearch.Linuxdynld = "/lib/ld-linux-aarch64.so.1"
+		Linuxdynld: "/lib/ld-linux-aarch64.so.1",
 
-	ld.Thearch.Freebsddynld = "XXX"
-	ld.Thearch.Openbsddynld = "XXX"
-	ld.Thearch.Netbsddynld = "XXX"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+		Freebsddynld:   "XXX",
+		Openbsddynld:   "XXX",
+		Netbsddynld:    "XXX",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
+	}
+
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32
@@ -104,7 +102,6 @@
 
 	case objabi.Hdarwin: /* apple MACH */
 		*ld.FlagW = true // disable DWARF generation
-		ld.Machoinit()
 		ld.HEADR = ld.INITIAL_MACHO_HEADR
 		if *ld.FlagTextAddr == -1 {
 			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go
index 8827b76..4b51304 100644
--- a/src/cmd/link/internal/ld/ar.go
+++ b/src/cmd/link/internal/ld/ar.go
@@ -33,6 +33,7 @@
 import (
 	"cmd/internal/bio"
 	"cmd/internal/objabi"
+	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
 	"io"
@@ -82,6 +83,10 @@
 		Exitf("file %s too short", name)
 	}
 
+	if string(magbuf[:]) != ARMAG {
+		Exitf("%s is not an archive file", name)
+	}
+
 	var arhdr ArHdr
 	l := nextar(f, f.Offset(), &arhdr)
 	if l <= 0 {
@@ -101,7 +106,7 @@
 		var load []uint64
 		for _, s := range ctxt.Syms.Allsym {
 			for _, r := range s.R {
-				if r.Sym != nil && r.Sym.Type&SMASK == SXREF {
+				if r.Sym != nil && r.Sym.Type == sym.SXREF {
 					if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
 						load = append(load, off)
 						loaded[off] = true
@@ -118,7 +123,7 @@
 			pname := fmt.Sprintf("%s(%s)", name, arhdr.name)
 			l = atolwhex(arhdr.size)
 
-			libgcc := Library{Pkg: "libgcc"}
+			libgcc := sym.Library{Pkg: "libgcc"}
 			h := ldobj(ctxt, f, &libgcc, l, pname, name, ArchiveObj)
 			f.Seek(h.off, 0)
 			h.ld(ctxt, f, h.pkg, h.length, h.pn)
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index 342351b..cc95392 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -11,11 +11,6 @@
 	"log"
 )
 
-var (
-	Linkmode  LinkMode
-	Buildmode BuildMode
-)
-
 // A BuildMode indicates the sort of object we are building.
 //
 // Possible build modes are the same as those for the -buildmode flag
@@ -23,13 +18,13 @@
 type BuildMode uint8
 
 const (
-	BuildmodeUnset BuildMode = iota
-	BuildmodeExe
-	BuildmodePIE
-	BuildmodeCArchive
-	BuildmodeCShared
-	BuildmodeShared
-	BuildmodePlugin
+	BuildModeUnset BuildMode = iota
+	BuildModeExe
+	BuildModePIE
+	BuildModeCArchive
+	BuildModeCShared
+	BuildModeShared
+	BuildModePlugin
 )
 
 func (mode *BuildMode) Set(s string) error {
@@ -40,14 +35,20 @@
 	default:
 		return fmt.Errorf("invalid buildmode: %q", s)
 	case "exe":
-		*mode = BuildmodeExe
+		*mode = BuildModeExe
 	case "pie":
 		switch objabi.GOOS {
 		case "android", "linux":
+		case "darwin":
+			switch objabi.GOARCH {
+			case "amd64":
+			default:
+				return badmode()
+			}
 		default:
 			return badmode()
 		}
-		*mode = BuildmodePIE
+		*mode = BuildModePIE
 	case "c-archive":
 		switch objabi.GOOS {
 		case "darwin", "linux":
@@ -60,14 +61,14 @@
 		default:
 			return badmode()
 		}
-		*mode = BuildmodeCArchive
+		*mode = BuildModeCArchive
 	case "c-shared":
 		switch objabi.GOARCH {
-		case "386", "amd64", "arm", "arm64":
+		case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
 		default:
 			return badmode()
 		}
-		*mode = BuildmodeCShared
+		*mode = BuildModeCShared
 	case "shared":
 		switch objabi.GOOS {
 		case "linux":
@@ -79,12 +80,12 @@
 		default:
 			return badmode()
 		}
-		*mode = BuildmodeShared
+		*mode = BuildModeShared
 	case "plugin":
 		switch objabi.GOOS {
 		case "linux":
 			switch objabi.GOARCH {
-			case "386", "amd64", "arm", "arm64", "s390x":
+			case "386", "amd64", "arm", "arm64", "s390x", "ppc64le":
 			default:
 				return badmode()
 			}
@@ -97,26 +98,26 @@
 		default:
 			return badmode()
 		}
-		*mode = BuildmodePlugin
+		*mode = BuildModePlugin
 	}
 	return nil
 }
 
 func (mode *BuildMode) String() string {
 	switch *mode {
-	case BuildmodeUnset:
+	case BuildModeUnset:
 		return "" // avoid showing a default in usage message
-	case BuildmodeExe:
+	case BuildModeExe:
 		return "exe"
-	case BuildmodePIE:
+	case BuildModePIE:
 		return "pie"
-	case BuildmodeCArchive:
+	case BuildModeCArchive:
 		return "c-archive"
-	case BuildmodeCShared:
+	case BuildModeCShared:
 		return "c-shared"
-	case BuildmodeShared:
+	case BuildModeShared:
 		return "shared"
-	case BuildmodePlugin:
+	case BuildModePlugin:
 		return "plugin"
 	}
 	return fmt.Sprintf("BuildMode(%d)", uint8(*mode))
@@ -172,7 +173,7 @@
 	case "android":
 		return true, "android"
 	case "darwin":
-		if SysArch.InFamily(sys.ARM, sys.ARM64) {
+		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
 			return true, "iOS"
 		}
 	}
@@ -184,42 +185,43 @@
 	// Internally linking cgo is incomplete on some architectures.
 	// https://golang.org/issue/10373
 	// https://golang.org/issue/14449
-	if iscgo && SysArch.InFamily(sys.ARM64, sys.MIPS64, sys.MIPS) {
+	// https://golang.org/issue/21961
+	if iscgo && ctxt.Arch.InFamily(sys.ARM64, sys.MIPS64, sys.MIPS, sys.PPC64) {
 		return true, objabi.GOARCH + " does not support internal cgo"
 	}
 
 	// Some build modes require work the internal linker cannot do (yet).
-	switch Buildmode {
-	case BuildmodeCArchive:
+	switch ctxt.BuildMode {
+	case BuildModeCArchive:
 		return true, "buildmode=c-archive"
-	case BuildmodeCShared:
+	case BuildModeCShared:
 		return true, "buildmode=c-shared"
-	case BuildmodePIE:
+	case BuildModePIE:
 		switch objabi.GOOS + "/" + objabi.GOARCH {
 		case "linux/amd64":
 		default:
 			// Internal linking does not support TLS_IE.
 			return true, "buildmode=pie"
 		}
-	case BuildmodePlugin:
+	case BuildModePlugin:
 		return true, "buildmode=plugin"
-	case BuildmodeShared:
+	case BuildModeShared:
 		return true, "buildmode=shared"
 	}
-	if *FlagLinkshared {
+	if ctxt.linkShared {
 		return true, "dynamically linking with a shared library"
 	}
 
 	return false, ""
 }
 
-// determineLinkMode sets Linkmode.
+// determineLinkMode sets ctxt.LinkMode.
 //
 // It is called after flags are processed and inputs are processed,
-// so the Linkmode variable has an initial value from the -linkmode
+// so the ctxt.LinkMode variable has an initial value from the -linkmode
 // flag and the iscgo externalobj variables are set.
 func determineLinkMode(ctxt *Link) {
-	switch Linkmode {
+	switch ctxt.LinkMode {
 	case LinkAuto:
 		// The environment variable GO_EXTLINK_ENABLED controls the
 		// default value of -linkmode. If it is not set when the
@@ -230,18 +232,18 @@
 			if needed, reason := mustLinkExternal(ctxt); needed {
 				Exitf("internal linking requested via GO_EXTLINK_ENABLED, but external linking required: %s", reason)
 			}
-			Linkmode = LinkInternal
+			ctxt.LinkMode = LinkInternal
 		case "1":
-			Linkmode = LinkExternal
+			ctxt.LinkMode = LinkExternal
 		default:
 			if needed, _ := mustLinkExternal(ctxt); needed {
-				Linkmode = LinkExternal
+				ctxt.LinkMode = LinkExternal
 			} else if iscgo && externalobj {
-				Linkmode = LinkExternal
-			} else if Buildmode == BuildmodePIE {
-				Linkmode = LinkExternal // https://golang.org/issue/18968
+				ctxt.LinkMode = LinkExternal
+			} else if ctxt.BuildMode == BuildModePIE {
+				ctxt.LinkMode = LinkExternal // https://golang.org/issue/18968
 			} else {
-				Linkmode = LinkInternal
+				ctxt.LinkMode = LinkInternal
 			}
 		}
 	case LinkInternal:
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 4523323..7450dea 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -35,6 +35,7 @@
 	"cmd/internal/gcprog"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"fmt"
 	"log"
 	"os"
@@ -44,280 +45,6 @@
 	"sync"
 )
 
-func Symgrow(s *Symbol, siz int64) {
-	if int64(int(siz)) != siz {
-		log.Fatalf("symgrow size %d too long", siz)
-	}
-	if int64(len(s.P)) >= siz {
-		return
-	}
-	if cap(s.P) < int(siz) {
-		p := make([]byte, 2*(siz+1))
-		s.P = append(p[:0], s.P...)
-	}
-	s.P = s.P[:siz]
-}
-
-func Addrel(s *Symbol) *Reloc {
-	s.R = append(s.R, Reloc{})
-	return &s.R[len(s.R)-1]
-}
-
-func setuintxx(ctxt *Link, s *Symbol, off int64, v uint64, wid int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	if s.Size < off+wid {
-		s.Size = off + wid
-		Symgrow(s, s.Size)
-	}
-
-	switch wid {
-	case 1:
-		s.P[off] = uint8(v)
-	case 2:
-		ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
-	case 4:
-		ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
-	case 8:
-		ctxt.Arch.ByteOrder.PutUint64(s.P[off:], v)
-	}
-
-	return off + wid
-}
-
-func Addbytes(s *Symbol, bytes []byte) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	s.P = append(s.P, bytes...)
-	s.Size = int64(len(s.P))
-
-	return s.Size
-}
-
-func adduintxx(ctxt *Link, s *Symbol, v uint64, wid int) int64 {
-	off := s.Size
-	setuintxx(ctxt, s, off, v, int64(wid))
-	return off
-}
-
-func Adduint8(ctxt *Link, s *Symbol, v uint8) int64 {
-	off := s.Size
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	s.Size++
-	s.P = append(s.P, v)
-
-	return off
-}
-
-func Adduint16(ctxt *Link, s *Symbol, v uint16) int64 {
-	return adduintxx(ctxt, s, uint64(v), 2)
-}
-
-func Adduint32(ctxt *Link, s *Symbol, v uint32) int64 {
-	return adduintxx(ctxt, s, uint64(v), 4)
-}
-
-func Adduint64(ctxt *Link, s *Symbol, v uint64) int64 {
-	return adduintxx(ctxt, s, v, 8)
-}
-
-func adduint(ctxt *Link, s *Symbol, v uint64) int64 {
-	return adduintxx(ctxt, s, v, SysArch.PtrSize)
-}
-
-func setuint8(ctxt *Link, s *Symbol, r int64, v uint8) int64 {
-	return setuintxx(ctxt, s, r, uint64(v), 1)
-}
-
-func setuint32(ctxt *Link, s *Symbol, r int64, v uint32) int64 {
-	return setuintxx(ctxt, s, r, uint64(v), 4)
-}
-
-func setuint(ctxt *Link, s *Symbol, r int64, v uint64) int64 {
-	return setuintxx(ctxt, s, r, v, int64(SysArch.PtrSize))
-}
-
-func Addaddrplus(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += int64(ctxt.Arch.PtrSize)
-	Symgrow(s, s.Size)
-	r := Addrel(s)
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = uint8(ctxt.Arch.PtrSize)
-	r.Type = objabi.R_ADDR
-	r.Add = add
-	return i + int64(r.Siz)
-}
-
-func Addpcrelplus(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += 4
-	Symgrow(s, s.Size)
-	r := Addrel(s)
-	r.Sym = t
-	r.Off = int32(i)
-	r.Add = add
-	r.Type = objabi.R_PCREL
-	r.Siz = 4
-	if SysArch.Family == sys.S390X {
-		r.Variant = RV_390_DBL
-	}
-	return i + int64(r.Siz)
-}
-
-func Addaddr(ctxt *Link, s *Symbol, t *Symbol) int64 {
-	return Addaddrplus(ctxt, s, t, 0)
-}
-
-func setaddrplus(ctxt *Link, s *Symbol, off int64, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	if off+int64(ctxt.Arch.PtrSize) > s.Size {
-		s.Size = off + int64(ctxt.Arch.PtrSize)
-		Symgrow(s, s.Size)
-	}
-
-	r := Addrel(s)
-	r.Sym = t
-	r.Off = int32(off)
-	r.Siz = uint8(ctxt.Arch.PtrSize)
-	r.Type = objabi.R_ADDR
-	r.Add = add
-	return off + int64(r.Siz)
-}
-
-func setaddr(ctxt *Link, s *Symbol, off int64, t *Symbol) int64 {
-	return setaddrplus(ctxt, s, off, t, 0)
-}
-
-func addsize(ctxt *Link, s *Symbol, t *Symbol) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += int64(ctxt.Arch.PtrSize)
-	Symgrow(s, s.Size)
-	r := Addrel(s)
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = uint8(ctxt.Arch.PtrSize)
-	r.Type = objabi.R_SIZE
-	return i + int64(r.Siz)
-}
-
-func addaddrplus4(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += 4
-	Symgrow(s, s.Size)
-	r := Addrel(s)
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = 4
-	r.Type = objabi.R_ADDR
-	r.Add = add
-	return i + int64(r.Siz)
-}
-
-/*
- * divide-and-conquer list-link (by Sub) sort of Symbol* by Value.
- * Used for sub-symbols when loading host objects (see e.g. ldelf.go).
- */
-
-func listsort(l *Symbol) *Symbol {
-	if l == nil || l.Sub == nil {
-		return l
-	}
-
-	l1 := l
-	l2 := l
-	for {
-		l2 = l2.Sub
-		if l2 == nil {
-			break
-		}
-		l2 = l2.Sub
-		if l2 == nil {
-			break
-		}
-		l1 = l1.Sub
-	}
-
-	l2 = l1.Sub
-	l1.Sub = nil
-	l1 = listsort(l)
-	l2 = listsort(l2)
-
-	/* set up lead element */
-	if l1.Value < l2.Value {
-		l = l1
-		l1 = l1.Sub
-	} else {
-		l = l2
-		l2 = l2.Sub
-	}
-
-	le := l
-
-	for {
-		if l1 == nil {
-			for l2 != nil {
-				le.Sub = l2
-				le = l2
-				l2 = l2.Sub
-			}
-
-			le.Sub = nil
-			break
-		}
-
-		if l2 == nil {
-			for l1 != nil {
-				le.Sub = l1
-				le = l1
-				l1 = l1.Sub
-			}
-
-			break
-		}
-
-		if l1.Value < l2.Value {
-			le.Sub = l1
-			le = l1
-			l1 = l1.Sub
-		} else {
-			le.Sub = l2
-			le = l2
-			l2 = l2.Sub
-		}
-	}
-
-	le.Sub = nil
-	return l
-}
-
 // isRuntimeDepPkg returns whether pkg is the runtime package or its dependency
 func isRuntimeDepPkg(pkg string) bool {
 	switch pkg {
@@ -331,7 +58,7 @@
 // Estimate the max size needed to hold any new trampolines created for this function. This
 // is used to determine when the section can be split if it becomes too large, to ensure that
 // the trampolines are in the same section as the function that uses them.
-func maxSizeTrampolinesPPC64(s *Symbol, isTramp bool) uint64 {
+func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 {
 	// If Thearch.Trampoline is nil, then trampoline support is not available on this arch.
 	// A trampoline does not need any dependent trampolines.
 	if Thearch.Trampoline == nil || isTramp {
@@ -353,7 +80,7 @@
 // ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking
 // On PPC64 & PPC64LE the text sections might be split but will still insert trampolines
 // where necessary.
-func trampoline(ctxt *Link, s *Symbol) {
+func trampoline(ctxt *Link, s *sym.Symbol) {
 	if Thearch.Trampoline == nil {
 		return // no need or no support of trampolines on this arch
 	}
@@ -363,7 +90,7 @@
 		if !r.Type.IsDirectJump() {
 			continue
 		}
-		if Symaddr(r.Sym) == 0 && r.Sym.Type != SDYNIMPORT {
+		if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT {
 			if r.Sym.File != s.File {
 				if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
 					Errorf(s, "unresolved inter-package jump to %s(%s)", r.Sym, r.Sym.File)
@@ -380,21 +107,16 @@
 }
 
 // resolve relocations in s.
-func relocsym(ctxt *Link, s *Symbol) {
-	var r *Reloc
-	var rs *Symbol
-	var i16 int16
-	var off int32
-	var siz int32
-	var fl int32
-	var o int64
-
+func relocsym(ctxt *Link, s *sym.Symbol) {
 	for ri := int32(0); ri < int32(len(s.R)); ri++ {
-		r = &s.R[ri]
-
-		r.Done = 1
-		off = r.Off
-		siz = int32(r.Siz)
+		r := &s.R[ri]
+		if r.Done {
+			// Relocation already processed by an earlier phase.
+			continue
+		}
+		r.Done = true
+		off := r.Off
+		siz := int32(r.Siz)
 		if off < 0 || off+siz > int32(len(s.P)) {
 			rname := ""
 			if r.Sym != nil {
@@ -404,12 +126,12 @@
 			continue
 		}
 
-		if r.Sym != nil && (r.Sym.Type&(SMASK|SHIDDEN) == 0 || r.Sym.Type&SMASK == SXREF) {
+		if r.Sym != nil && ((r.Sym.Type == 0 && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) {
 			// When putting the runtime but not main into a shared library
 			// these symbols are undefined and that's OK.
-			if Buildmode == BuildmodeShared {
+			if ctxt.BuildMode == BuildModeShared {
 				if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" {
-					r.Sym.Type = SDYNIMPORT
+					r.Sym.Type = sym.SDYNIMPORT
 				} else if strings.HasPrefix(r.Sym.Name, "go.info.") {
 					// Skip go.info symbols. They are only needed to communicate
 					// DWARF info between the compiler and linker.
@@ -427,29 +149,36 @@
 		if r.Siz == 0 { // informational relocation - no work to do
 			continue
 		}
+		if r.Type == objabi.R_DWARFFILEREF {
+			// These should have been processed previously during
+			// line table writing.
+			Errorf(s, "orphan R_DWARFFILEREF reloc to %v", r.Sym.Name)
+			continue
+		}
 
 		// We need to be able to reference dynimport symbols when linking against
 		// shared libraries, and Solaris needs it always
-		if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == SDYNIMPORT && !ctxt.DynlinkingGo() {
-			if !(SysArch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
-				Errorf(s, "unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type)
+		if ctxt.HeadType != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() && !r.Sym.Attr.SubSymbol() {
+			if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") {
+				Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			}
 		}
-		if r.Sym != nil && r.Sym.Type != STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
+		if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
 			Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name)
 		}
 
 		// TODO(mundaym): remove this special case - see issue 14218.
-		if SysArch.Family == sys.S390X {
+		if ctxt.Arch.Family == sys.S390X {
 			switch r.Type {
 			case objabi.R_PCRELDBL:
 				r.Type = objabi.R_PCREL
-				r.Variant = RV_390_DBL
+				r.Variant = sym.RV_390_DBL
 			case objabi.R_CALL:
-				r.Variant = RV_390_DBL
+				r.Variant = sym.RV_390_DBL
 			}
 		}
 
+		var o int64
 		switch r.Type {
 		default:
 			switch siz {
@@ -464,28 +193,27 @@
 			case 8:
 				o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
 			}
-			if Thearch.Archreloc(ctxt, r, s, &o) < 0 {
-				Errorf(s, "unknown reloc to %v: %v", r.Sym.Name, r.Type)
+			if !Thearch.Archreloc(ctxt, r, s, &o) {
+				Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			}
-
 		case objabi.R_TLS_LE:
-			isAndroidX86 := objabi.GOOS == "android" && (SysArch.InFamily(sys.AMD64, sys.I386))
+			isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386))
 
-			if Linkmode == LinkExternal && Iself && !isAndroidX86 {
-				r.Done = 0
+			if ctxt.LinkMode == LinkExternal && ctxt.IsELF && !isAndroidX86 {
+				r.Done = false
 				if r.Sym == nil {
 					r.Sym = ctxt.Tlsg
 				}
 				r.Xsym = r.Sym
 				r.Xadd = r.Add
 				o = 0
-				if SysArch.Family != sys.AMD64 {
+				if ctxt.Arch.Family != sys.AMD64 {
 					o = r.Add
 				}
 				break
 			}
 
-			if Iself && SysArch.Family == sys.ARM {
+			if ctxt.IsELF && ctxt.Arch.Family == sys.ARM {
 				// On ELF ARM, the thread pointer is 8 bytes before
 				// the start of the thread-local data block, so add 8
 				// to the actual TLS offset (r->sym->value).
@@ -494,51 +222,49 @@
 				// related to the fact that our own TLS storage happens
 				// to take up 8 bytes.
 				o = 8 + r.Sym.Value
-			} else if Iself || Headtype == objabi.Hplan9 || Headtype == objabi.Hdarwin || isAndroidX86 {
+			} else if ctxt.IsELF || ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hdarwin || isAndroidX86 {
 				o = int64(ctxt.Tlsoffset) + r.Add
-			} else if Headtype == objabi.Hwindows {
+			} else if ctxt.HeadType == objabi.Hwindows {
 				o = r.Add
 			} else {
-				log.Fatalf("unexpected R_TLS_LE relocation for %v", Headtype)
+				log.Fatalf("unexpected R_TLS_LE relocation for %v", ctxt.HeadType)
 			}
-
 		case objabi.R_TLS_IE:
-			isAndroidX86 := objabi.GOOS == "android" && (SysArch.InFamily(sys.AMD64, sys.I386))
+			isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386))
 
-			if Linkmode == LinkExternal && Iself && !isAndroidX86 {
-				r.Done = 0
+			if ctxt.LinkMode == LinkExternal && ctxt.IsELF && !isAndroidX86 {
+				r.Done = false
 				if r.Sym == nil {
 					r.Sym = ctxt.Tlsg
 				}
 				r.Xsym = r.Sym
 				r.Xadd = r.Add
 				o = 0
-				if SysArch.Family != sys.AMD64 {
+				if ctxt.Arch.Family != sys.AMD64 {
 					o = r.Add
 				}
 				break
 			}
-			if Buildmode == BuildmodePIE && Iself {
+			if ctxt.BuildMode == BuildModePIE && ctxt.IsELF {
 				// We are linking the final executable, so we
 				// can optimize any TLS IE relocation to LE.
 				if Thearch.TLSIEtoLE == nil {
-					log.Fatalf("internal linking of TLS IE not supported on %v", SysArch.Family)
+					log.Fatalf("internal linking of TLS IE not supported on %v", ctxt.Arch.Family)
 				}
 				Thearch.TLSIEtoLE(s, int(off), int(r.Siz))
 				o = int64(ctxt.Tlsoffset)
-				// TODO: o += r.Add when SysArch.Family != sys.AMD64?
+				// TODO: o += r.Add when ctxt.Arch.Family != sys.AMD64?
 				// Why do we treat r.Add differently on AMD64?
 				// Is the external linker using Xadd at all?
 			} else {
 				log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
 			}
-
 		case objabi.R_ADDR:
-			if Linkmode == LinkExternal && r.Sym.Type != SCONST {
-				r.Done = 0
+			if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST {
+				r.Done = false
 
 				// set up addend for eventual relocation via outer symbol.
-				rs = r.Sym
+				rs := r.Sym
 
 				r.Xadd = r.Add
 				for rs.Outer != nil {
@@ -546,34 +272,34 @@
 					rs = rs.Outer
 				}
 
-				if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil {
+				if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 					Errorf(s, "missing section for relocation target %s", rs.Name)
 				}
 				r.Xsym = rs
 
 				o = r.Xadd
-				if Iself {
-					if SysArch.Family == sys.AMD64 {
+				if ctxt.IsELF {
+					if ctxt.Arch.Family == sys.AMD64 {
 						o = 0
 					}
-				} else if Headtype == objabi.Hdarwin {
+				} else if ctxt.HeadType == objabi.Hdarwin {
 					// ld64 for arm64 has a bug where if the address pointed to by o exists in the
 					// symbol table (dynid >= 0), or is inside a symbol that exists in the symbol
 					// table, then it will add o twice into the relocated value.
 					// The workaround is that on arm64 don't ever add symaddr to o and always use
 					// extern relocation by requiring rs->dynid >= 0.
-					if rs.Type != SHOSTOBJ {
-						if SysArch.Family == sys.ARM64 && rs.Dynid < 0 {
+					if rs.Type != sym.SHOSTOBJ {
+						if ctxt.Arch.Family == sys.ARM64 && rs.Dynid < 0 {
 							Errorf(s, "R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o)
 						}
-						if SysArch.Family != sys.ARM64 {
+						if ctxt.Arch.Family != sys.ARM64 {
 							o += Symaddr(rs)
 						}
 					}
-				} else if Headtype == objabi.Hwindows {
+				} else if ctxt.HeadType == objabi.Hwindows {
 					// nothing to do
 				} else {
-					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, Headtype)
+					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
 				}
 
 				break
@@ -586,47 +312,46 @@
 			// fail at runtime. See https://golang.org/issue/7980.
 			// Instead of special casing only amd64, we treat this as an error on all
 			// 64-bit architectures so as to be future-proof.
-			if int32(o) < 0 && SysArch.PtrSize > 4 && siz == 4 {
+			if int32(o) < 0 && ctxt.Arch.PtrSize > 4 && siz == 4 {
 				Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", r.Sym.Name, uint64(o), Symaddr(r.Sym), r.Add)
 				errorexit()
 			}
-
-		case objabi.R_DWARFREF:
-			var sectName string
-			var vaddr int64
-			switch {
-			case r.Sym.Sect != nil:
-				sectName = r.Sym.Sect.Name
-				vaddr = int64(r.Sym.Sect.Vaddr)
-			case r.Sym.Type == SDWARFRANGE:
-				sectName = ".debug_ranges"
-			default:
+		case objabi.R_DWARFSECREF:
+			if r.Sym.Sect == nil {
 				Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
 			}
 
-			if Linkmode == LinkExternal {
-				r.Done = 0
+			if ctxt.LinkMode == LinkExternal {
+				r.Done = false
+
+				// On most platforms, the external linker needs to adjust DWARF references
+				// as it combines DWARF sections. However, on Darwin, dsymutil does the
+				// DWARF linking, and it understands how to follow section offsets.
+				// Leaving in the relocation records confuses it (see
+				// https://golang.org/issue/22068) so drop them for Darwin.
+				if ctxt.HeadType == objabi.Hdarwin {
+					r.Done = true
+				}
+
 				// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
-				// for R_DWARFREF relocations, while R_ADDR is replaced with
+				// for R_DWARFSECREF relocations, while R_ADDR is replaced with
 				// IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32.
-				// Do not replace R_DWARFREF with R_ADDR for windows -
+				// Do not replace R_DWARFSECREF with R_ADDR for windows -
 				// let PE code emit correct relocations.
-				if Headtype != objabi.Hwindows {
+				if ctxt.HeadType != objabi.Hwindows {
 					r.Type = objabi.R_ADDR
 				}
 
-				r.Xsym = ctxt.Syms.ROLookup(sectName, 0)
-				r.Xadd = r.Add + Symaddr(r.Sym) - vaddr
+				r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0)
+				r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
 
 				o = r.Xadd
-				rs = r.Xsym
-				if Iself && SysArch.Family == sys.AMD64 {
+				if ctxt.IsELF && ctxt.Arch.Family == sys.AMD64 {
 					o = 0
 				}
 				break
 			}
-			o = Symaddr(r.Sym) + r.Add - vaddr
-
+			o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
 		case objabi.R_WEAKADDROFF:
 			if !r.Sym.Attr.Reachable() {
 				continue
@@ -642,10 +367,15 @@
 				o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
 			}
 
+		case objabi.R_ADDRCUOFF:
+			// debug_range and debug_loc elements use this relocation type to get an
+			// offset from the start of the compile unit.
+			o = Symaddr(r.Sym) + r.Add - Symaddr(r.Sym.Lib.Textp[0])
+
 			// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
 		case objabi.R_GOTPCREL:
-			if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != SCONST {
-				r.Done = 0
+			if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST {
+				r.Done = false
 				r.Xadd = r.Add
 				r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
 				r.Xsym = r.Sym
@@ -656,11 +386,11 @@
 			}
 			fallthrough
 		case objabi.R_CALL, objabi.R_PCREL:
-			if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
-				r.Done = 0
+			if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
+				r.Done = false
 
 				// set up addend for eventual relocation via outer symbol.
-				rs = r.Sym
+				rs := r.Sym
 
 				r.Xadd = r.Add
 				for rs.Outer != nil {
@@ -669,34 +399,34 @@
 				}
 
 				r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
-				if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil {
+				if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 					Errorf(s, "missing section for relocation target %s", rs.Name)
 				}
 				r.Xsym = rs
 
 				o = r.Xadd
-				if Iself {
-					if SysArch.Family == sys.AMD64 {
+				if ctxt.IsELF {
+					if ctxt.Arch.Family == sys.AMD64 {
 						o = 0
 					}
-				} else if Headtype == objabi.Hdarwin {
+				} else if ctxt.HeadType == objabi.Hdarwin {
 					if r.Type == objabi.R_CALL {
-						if rs.Type != SHOSTOBJ {
+						if rs.Type != sym.SHOSTOBJ {
 							o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
 						}
 						o -= int64(r.Off) // relative to section offset, not symbol
-					} else if SysArch.Family == sys.ARM {
+					} else if ctxt.Arch.Family == sys.ARM {
 						// see ../arm/asm.go:/machoreloc1
 						o += Symaddr(rs) - int64(s.Value) - int64(r.Off)
 					} else {
 						o += int64(r.Siz)
 					}
-				} else if Headtype == objabi.Hwindows && SysArch.Family == sys.AMD64 { // only amd64 needs PCREL
+				} else if ctxt.HeadType == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 { // only amd64 needs PCREL
 					// PE/COFF's PC32 relocation uses the address after the relocated
 					// bytes as the base. Compensate by skewing the addend.
 					o += int64(r.Siz)
 				} else {
-					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, Headtype)
+					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
 				}
 
 				break
@@ -708,12 +438,11 @@
 			}
 
 			o += r.Add - (s.Value + int64(r.Off) + int64(r.Siz))
-
 		case objabi.R_SIZE:
 			o = r.Sym.Size + r.Add
 		}
 
-		if r.Variant != RV_NONE {
+		if r.Variant != sym.RV_NONE {
 			o = Thearch.Archrelocvariant(ctxt, r, s, o)
 		}
 
@@ -722,7 +451,7 @@
 			if r.Sym != nil {
 				nam = r.Sym.Name
 			}
-			fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, r.Variant, o)
+			fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o)
 		}
 		switch siz {
 		default:
@@ -732,14 +461,12 @@
 			// TODO(rsc): Remove.
 		case 1:
 			s.P[off] = byte(int8(o))
-
 		case 2:
 			if o != int64(int16(o)) {
 				Errorf(s, "relocation address for %s is too big: %#x", r.Sym.Name, o)
 			}
-			i16 = int16(o)
+			i16 := int16(o)
 			ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
-
 		case 4:
 			if r.Type == objabi.R_PCREL || r.Type == objabi.R_CALL {
 				if o != int64(int32(o)) {
@@ -751,9 +478,8 @@
 				}
 			}
 
-			fl = int32(o)
+			fl := int32(o)
 			ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
-
 		case 8:
 			ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
 		}
@@ -768,99 +494,104 @@
 	for _, s := range ctxt.Textp {
 		relocsym(ctxt, s)
 	}
-	for _, sym := range datap {
-		relocsym(ctxt, sym)
+	for _, s := range datap {
+		relocsym(ctxt, s)
 	}
 	for _, s := range dwarfp {
 		relocsym(ctxt, s)
 	}
 }
 
-func dynrelocsym(ctxt *Link, s *Symbol) {
-	if Headtype == objabi.Hwindows && Linkmode != LinkExternal {
-		rel := ctxt.Syms.Lookup(".rel", 0)
-		if s == rel {
-			return
+func windynrelocsym(ctxt *Link, s *sym.Symbol) {
+	rel := ctxt.Syms.Lookup(".rel", 0)
+	if s == rel {
+		return
+	}
+	for ri := 0; ri < len(s.R); ri++ {
+		r := &s.R[ri]
+		targ := r.Sym
+		if targ == nil {
+			continue
 		}
-		for ri := 0; ri < len(s.R); ri++ {
-			r := &s.R[ri]
-			targ := r.Sym
-			if targ == nil {
+		if !targ.Attr.Reachable() {
+			if r.Type == objabi.R_WEAKADDROFF {
 				continue
 			}
-			if !targ.Attr.Reachable() {
-				if r.Type == objabi.R_WEAKADDROFF {
-					continue
-				}
-				Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name)
-			}
-			if r.Sym.Plt == -2 && r.Sym.Got != -2 { // make dynimport JMP table for PE object files.
-				targ.Plt = int32(rel.Size)
-				r.Sym = rel
-				r.Add = int64(targ.Plt)
-
-				// jmp *addr
-				if SysArch.Family == sys.I386 {
-					Adduint8(ctxt, rel, 0xff)
-					Adduint8(ctxt, rel, 0x25)
-					Addaddr(ctxt, rel, targ)
-					Adduint8(ctxt, rel, 0x90)
-					Adduint8(ctxt, rel, 0x90)
-				} else {
-					Adduint8(ctxt, rel, 0xff)
-					Adduint8(ctxt, rel, 0x24)
-					Adduint8(ctxt, rel, 0x25)
-					addaddrplus4(ctxt, rel, targ, 0)
-					Adduint8(ctxt, rel, 0x90)
-				}
-			} else if r.Sym.Plt >= 0 {
-				r.Sym = rel
-				r.Add = int64(targ.Plt)
-			}
+			Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name)
 		}
+		if r.Sym.Plt == -2 && r.Sym.Got != -2 { // make dynimport JMP table for PE object files.
+			targ.Plt = int32(rel.Size)
+			r.Sym = rel
+			r.Add = int64(targ.Plt)
 
+			// jmp *addr
+			if ctxt.Arch.Family == sys.I386 {
+				rel.AddUint8(0xff)
+				rel.AddUint8(0x25)
+				rel.AddAddr(ctxt.Arch, targ)
+				rel.AddUint8(0x90)
+				rel.AddUint8(0x90)
+			} else {
+				rel.AddUint8(0xff)
+				rel.AddUint8(0x24)
+				rel.AddUint8(0x25)
+				rel.AddAddrPlus4(targ, 0)
+				rel.AddUint8(0x90)
+			}
+		} else if r.Sym.Plt >= 0 {
+			r.Sym = rel
+			r.Add = int64(targ.Plt)
+		}
+	}
+}
+
+func dynrelocsym(ctxt *Link, s *sym.Symbol) {
+	if ctxt.HeadType == objabi.Hwindows {
+		if ctxt.LinkMode == LinkInternal {
+			windynrelocsym(ctxt, s)
+		}
 		return
 	}
 
 	for ri := 0; ri < len(s.R); ri++ {
 		r := &s.R[ri]
-		if Buildmode == BuildmodePIE && Linkmode == LinkInternal {
+		if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
 			// It's expected that some relocations will be done
 			// later by relocsym (R_TLS_LE, R_ADDROFF), so
 			// don't worry if Adddynrel returns false.
 			Thearch.Adddynrel(ctxt, s, r)
 			continue
 		}
-		if r.Sym != nil && r.Sym.Type == SDYNIMPORT || r.Type >= 256 {
+		if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= 256 {
 			if r.Sym != nil && !r.Sym.Attr.Reachable() {
 				Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name)
 			}
 			if !Thearch.Adddynrel(ctxt, s, r) {
-				Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d stype=%d)", r.Sym.Name, r.Type, r.Sym.Type)
+				Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type)
 			}
 		}
 	}
 }
 
-func dynreloc(ctxt *Link, data *[SXREF][]*Symbol) {
+func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) {
 	// -d suppresses dynamic loader format, so we may as well not
 	// compute these sections or mark their symbols as reachable.
-	if *FlagD && Headtype != objabi.Hwindows {
+	if *FlagD && ctxt.HeadType != objabi.Hwindows {
 		return
 	}
 	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%5.2f reloc\n", Cputime())
+		ctxt.Logf("%5.2f dynreloc\n", Cputime())
 	}
 
 	for _, s := range ctxt.Textp {
 		dynrelocsym(ctxt, s)
 	}
 	for _, syms := range data {
-		for _, sym := range syms {
-			dynrelocsym(ctxt, sym)
+		for _, s := range syms {
+			dynrelocsym(ctxt, s)
 		}
 	}
-	if Iself {
+	if ctxt.IsELF {
 		elfdynhash(ctxt)
 	}
 }
@@ -870,7 +601,7 @@
 }
 func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) {
 	if *flagA {
-		ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+		ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
 	}
 
 	blk(ctxt, ctxt.Textp, addr, size, pad)
@@ -881,11 +612,11 @@
 	}
 
 	syms := ctxt.Textp
-	for i, sym := range syms {
-		if !sym.Attr.Reachable() {
+	for i, s := range syms {
+		if !s.Attr.Reachable() {
 			continue
 		}
-		if sym.Value >= addr {
+		if s.Value >= addr {
 			syms = syms[i:]
 			break
 		}
@@ -893,24 +624,24 @@
 
 	eaddr := addr + size
 	var q []byte
-	for _, sym := range syms {
-		if !sym.Attr.Reachable() {
+	for _, s := range syms {
+		if !s.Attr.Reachable() {
 			continue
 		}
-		if sym.Value >= eaddr {
+		if s.Value >= eaddr {
 			break
 		}
 
-		if addr < sym.Value {
+		if addr < s.Value {
 			ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
-			for ; addr < sym.Value; addr++ {
+			for ; addr < s.Value; addr++ {
 				ctxt.Logf(" %.2x", 0)
 			}
 			ctxt.Logf("\n")
 		}
 
-		ctxt.Logf("%.6x\t%-20s\n", uint64(addr), sym.Name)
-		q = sym.P
+		ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name)
+		q = s.P
 
 		for len(q) >= 16 {
 			ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16])
@@ -932,9 +663,9 @@
 	}
 }
 
-func blk(ctxt *Link, syms []*Symbol, addr, size int64, pad []byte) {
+func blk(ctxt *Link, syms []*sym.Symbol, addr, size int64, pad []byte) {
 	for i, s := range syms {
-		if s.Type&SSUB == 0 && s.Value >= addr {
+		if !s.Attr.SubSymbol() && s.Value >= addr {
 			syms = syms[i:]
 			break
 		}
@@ -942,7 +673,7 @@
 
 	eaddr := addr + size
 	for _, s := range syms {
-		if s.Type&SSUB != 0 {
+		if s.Attr.SubSymbol() {
 			continue
 		}
 		if s.Value >= eaddr {
@@ -953,13 +684,13 @@
 			errorexit()
 		}
 		if addr < s.Value {
-			strnputPad("", int(s.Value-addr), pad)
+			ctxt.Out.WriteStringPad("", int(s.Value-addr), pad)
 			addr = s.Value
 		}
-		Cwrite(s.P)
+		ctxt.Out.Write(s.P)
 		addr += int64(len(s.P))
 		if addr < s.Value+s.Size {
-			strnputPad("", int(s.Value+s.Size-addr), pad)
+			ctxt.Out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
 			addr = s.Value + s.Size
 		}
 		if addr != s.Value+s.Size {
@@ -972,14 +703,14 @@
 	}
 
 	if addr < eaddr {
-		strnputPad("", int(eaddr-addr), pad)
+		ctxt.Out.WriteStringPad("", int(eaddr-addr), pad)
 	}
-	Cflush()
+	ctxt.Out.Flush()
 }
 
 func Datblk(ctxt *Link, addr int64, size int64) {
 	if *flagA {
-		ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+		ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
 	}
 
 	blk(ctxt, datap, addr, size, zeros[:])
@@ -1021,7 +752,7 @@
 		}
 		ctxt.Logf("\n")
 
-		if Linkmode != LinkExternal {
+		if ctxt.LinkMode != LinkExternal {
 			continue
 		}
 		for _, r := range sym.R {
@@ -1050,7 +781,7 @@
 
 func Dwarfblk(ctxt *Link, addr int64, size int64) {
 	if *flagA {
-		ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+		ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
 	}
 
 	blk(ctxt, dwarfp, addr, size, zeros[:])
@@ -1058,32 +789,10 @@
 
 var zeros [512]byte
 
-// strnput writes the first n bytes of s.
-// If n is larger than len(s),
-// it is padded with NUL bytes.
-func strnput(s string, n int) {
-	strnputPad(s, n, zeros[:])
-}
-
-// strnput writes the first n bytes of s.
-// If n is larger than len(s),
-// it is padded with the bytes in pad (repeated as needed).
-func strnputPad(s string, n int, pad []byte) {
-	if len(s) >= n {
-		Cwritestring(s[:n])
-	} else {
-		Cwritestring(s)
-		n -= len(s)
-		for n > len(pad) {
-			Cwrite(pad)
-			n -= len(pad)
-
-		}
-		Cwrite(pad[:n])
-	}
-}
-
-var strdata []*Symbol
+var (
+	strdata  = make(map[string]string)
+	strnames []string
+)
 
 func addstrdata1(ctxt *Link, arg string) {
 	eq := strings.Index(arg, "=")
@@ -1091,48 +800,65 @@
 	if eq < 0 || dot < 0 {
 		Exitf("-X flag requires argument of the form importpath.name=value")
 	}
-	addstrdata(ctxt, objabi.PathToPrefix(arg[:dot])+arg[dot:eq], arg[eq+1:])
+	pkg := arg[:dot]
+	if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
+		pkg = *flagPluginPath
+	}
+	pkg = objabi.PathToPrefix(pkg)
+	name := pkg + arg[dot:eq]
+	value := arg[eq+1:]
+	if _, ok := strdata[name]; !ok {
+		strnames = append(strnames, name)
+	}
+	strdata[name] = value
 }
 
-func addstrdata(ctxt *Link, name string, value string) {
-	p := fmt.Sprintf("%s.str", name)
+func addstrdata(ctxt *Link, name, value string) {
+	s := ctxt.Syms.ROLookup(name, 0)
+	if s == nil || s.Gotype == nil {
+		// Not defined in the loaded packages.
+		return
+	}
+	if s.Gotype.Name != "type.string" {
+		Errorf(s, "cannot set with -X: not a var of type string (%s)", s.Gotype.Name)
+		return
+	}
+	if s.Type == sym.SBSS {
+		s.Type = sym.SDATA
+	}
+
+	p := fmt.Sprintf("%s.str", s.Name)
 	sp := ctxt.Syms.Lookup(p, 0)
 
 	Addstring(sp, value)
-	sp.Type = SRODATA
+	sp.Type = sym.SRODATA
 
-	s := ctxt.Syms.Lookup(name, 0)
 	s.Size = 0
-	s.Attr |= AttrDuplicateOK
+	s.P = s.P[:0]
+	s.R = s.R[:0]
 	reachable := s.Attr.Reachable()
-	Addaddr(ctxt, s, sp)
-	adduintxx(ctxt, s, uint64(len(value)), SysArch.PtrSize)
+	s.AddAddr(ctxt.Arch, sp)
+	s.AddUint(ctxt.Arch, uint64(len(value)))
 
 	// 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.Attr.Set(AttrReachable, reachable)
+	s.Attr.Set(sym.AttrReachable, reachable)
 
-	strdata = append(strdata, s)
-
-	sp.Attr.Set(AttrReachable, reachable)
+	sp.Attr.Set(sym.AttrReachable, reachable)
 }
 
-func (ctxt *Link) checkstrdata() {
-	for _, s := range strdata {
-		if s.Type == STEXT {
-			Errorf(s, "cannot use -X with text symbol")
-		} else if s.Gotype != nil && s.Gotype.Name != "type.string" {
-			Errorf(s, "cannot use -X with non-string symbol")
-		}
+func (ctxt *Link) dostrdata() {
+	for _, name := range strnames {
+		addstrdata(ctxt, name, strdata[name])
 	}
 }
 
-func Addstring(s *Symbol, str string) int64 {
+func Addstring(s *sym.Symbol, str string) int64 {
 	if s.Type == 0 {
-		s.Type = SNOPTRDATA
+		s.Type = sym.SNOPTRDATA
 	}
-	s.Attr |= AttrReachable
+	s.Attr |= sym.AttrReachable
 	r := s.Size
 	if s.Name == ".shstrtab" {
 		elfsetstring(s, str, int(r))
@@ -1145,47 +871,44 @@
 
 // addgostring adds str, as a Go string value, to s. symname is the name of the
 // symbol used to define the string data and must be unique per linked object.
-func addgostring(ctxt *Link, s *Symbol, symname, str string) {
-	sym := ctxt.Syms.Lookup(symname, 0)
-	if sym.Type != Sxxx {
+func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) {
+	sdata := ctxt.Syms.Lookup(symname, 0)
+	if sdata.Type != sym.Sxxx {
 		Errorf(s, "duplicate symname in addgostring: %s", symname)
 	}
-	sym.Attr |= AttrReachable
-	sym.Attr |= AttrLocal
-	sym.Type = SRODATA
-	sym.Size = int64(len(str))
-	sym.P = []byte(str)
-	Addaddr(ctxt, s, sym)
-	adduint(ctxt, s, uint64(len(str)))
+	sdata.Attr |= sym.AttrReachable
+	sdata.Attr |= sym.AttrLocal
+	sdata.Type = sym.SRODATA
+	sdata.Size = int64(len(str))
+	sdata.P = []byte(str)
+	s.AddAddr(ctxt.Arch, sdata)
+	s.AddUint(ctxt.Arch, uint64(len(str)))
 }
 
-func addinitarrdata(ctxt *Link, s *Symbol) {
+func addinitarrdata(ctxt *Link, s *sym.Symbol) {
 	p := s.Name + ".ptr"
 	sp := ctxt.Syms.Lookup(p, 0)
-	sp.Type = SINITARR
+	sp.Type = sym.SINITARR
 	sp.Size = 0
-	sp.Attr |= AttrDuplicateOK
-	Addaddr(ctxt, sp, s)
+	sp.Attr |= sym.AttrDuplicateOK
+	sp.AddAddr(ctxt.Arch, s)
 }
 
 func dosymtype(ctxt *Link) {
-	switch Buildmode {
-	case BuildmodeCArchive, BuildmodeCShared:
+	switch ctxt.BuildMode {
+	case BuildModeCArchive, BuildModeCShared:
 		for _, s := range ctxt.Syms.Allsym {
 			// Create a new entry in the .init_array section that points to the
 			// library initializer function.
-			switch Buildmode {
-			case BuildmodeCArchive, BuildmodeCShared:
-				if s.Name == *flagEntrySymbol {
-					addinitarrdata(ctxt, s)
-				}
+			if s.Name == *flagEntrySymbol {
+				addinitarrdata(ctxt, s)
 			}
 		}
 	}
 }
 
 // symalign returns the required alignment for the given symbol s.
-func symalign(s *Symbol) int32 {
+func symalign(s *sym.Symbol) int32 {
 	min := int32(Thearch.Minalign)
 	if s.Align >= min {
 		return s.Align
@@ -1204,7 +927,7 @@
 	return align
 }
 
-func aligndatsize(datsize int64, s *Symbol) int64 {
+func aligndatsize(datsize int64, s *sym.Symbol) int64 {
 	return Rnd(datsize, int64(symalign(s)))
 }
 
@@ -1212,7 +935,7 @@
 
 type GCProg struct {
 	ctxt *Link
-	sym  *Symbol
+	sym  *sym.Symbol
 	w    gcprog.Writer
 }
 
@@ -1228,21 +951,21 @@
 
 func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
 	return func(x byte) {
-		Adduint8(ctxt, p.sym, x)
+		p.sym.AddUint8(x)
 	}
 }
 
 func (p *GCProg) End(size int64) {
-	p.w.ZeroUntil(size / int64(SysArch.PtrSize))
+	p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
 	p.w.End()
 	if debugGCProg {
 		fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
 	}
 }
 
-func (p *GCProg) AddSym(s *Symbol) {
+func (p *GCProg) AddSym(s *sym.Symbol) {
 	typ := s.Gotype
-	// Things without pointers should be in SNOPTRDATA or SNOPTRBSS;
+	// Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS;
 	// everything we see should have pointers and should therefore have a type.
 	if typ == nil {
 		switch s.Name {
@@ -1256,14 +979,14 @@
 		return
 	}
 
-	ptrsize := int64(SysArch.PtrSize)
+	ptrsize := int64(p.ctxt.Arch.PtrSize)
 	nptr := decodetypePtrdata(p.ctxt.Arch, typ) / ptrsize
 
 	if debugGCProg {
 		fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", s.Name, s.Value, s.Value/ptrsize, nptr)
 	}
 
-	if decodetypeUsegcprog(typ) == 0 {
+	if decodetypeUsegcprog(p.ctxt.Arch, typ) == 0 {
 		// Copy pointers from mask into program.
 		mask := decodetypeGcmask(p.ctxt, typ)
 		for i := int64(0); i < nptr; i++ {
@@ -1280,12 +1003,12 @@
 	p.w.Append(prog[4:], nptr)
 }
 
-// dataSortKey is used to sort a slice of data symbol *Symbol pointers.
+// dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers.
 // The sort keys are kept inline to improve cache behavior while sorting.
 type dataSortKey struct {
 	size int64
 	name string
-	sym  *Symbol
+	sym  *sym.Symbol
 }
 
 type bySizeAndName []dataSortKey
@@ -1300,24 +1023,26 @@
 	return s1.name < s2.name
 }
 
-const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31)
+// cutoff is the maximum data section size permitted by the linker
+// (see issue #9862).
+const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31)
 
-func checkdatsize(ctxt *Link, datsize int64, symn SymKind) {
+func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) {
 	if datsize > cutoff {
-		Errorf(nil, "too much data in section %v (over %d bytes)", symn, cutoff)
+		Errorf(nil, "too much data in section %v (over %v bytes)", symn, cutoff)
 	}
 }
 
 // datap is a collection of reachable data symbols in address order.
 // Generated by dodata.
-var datap []*Symbol
+var datap []*sym.Symbol
 
 func (ctxt *Link) dodata() {
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f dodata\n", Cputime())
 	}
 
-	if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin {
+	if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin {
 		// The values in moduledata are filled out by relocations
 		// pointing to the addresses of these special symbols.
 		// Typically these symbols have no size and are not laid
@@ -1337,33 +1062,33 @@
 		// as normal symbols, and give them a little size.
 		bss := ctxt.Syms.Lookup("runtime.bss", 0)
 		bss.Size = 8
-		bss.Attr.Set(AttrSpecial, false)
+		bss.Attr.Set(sym.AttrSpecial, false)
 
-		ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(AttrSpecial, false)
+		ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
 
 		data := ctxt.Syms.Lookup("runtime.data", 0)
 		data.Size = 8
-		data.Attr.Set(AttrSpecial, false)
+		data.Attr.Set(sym.AttrSpecial, false)
 
-		ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(AttrSpecial, false)
+		ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(sym.AttrSpecial, false)
 
 		types := ctxt.Syms.Lookup("runtime.types", 0)
-		types.Type = STYPE
+		types.Type = sym.STYPE
 		types.Size = 8
-		types.Attr.Set(AttrSpecial, false)
+		types.Attr.Set(sym.AttrSpecial, false)
 
 		etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
-		etypes.Type = SFUNCTAB
-		etypes.Attr.Set(AttrSpecial, false)
+		etypes.Type = sym.SFUNCTAB
+		etypes.Attr.Set(sym.AttrSpecial, false)
 	}
 
 	// Collect data symbols by type into data.
-	var data [SXREF][]*Symbol
+	var data [sym.SXREF][]*sym.Symbol
 	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || s.Attr.Special() {
+		if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() {
 			continue
 		}
-		if s.Type <= STEXT || s.Type >= SXREF {
+		if s.Type <= sym.STEXT || s.Type >= sym.SXREF {
 			continue
 		}
 		data[s.Type] = append(data[s.Type], s)
@@ -1375,25 +1100,25 @@
 	// symbol, which is itself data.
 	//
 	// On darwin, we need the symbol table numbers for dynreloc.
-	if Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		machosymorder(ctxt)
 	}
 	dynreloc(ctxt, &data)
 
-	if UseRelro() {
+	if ctxt.UseRelro() {
 		// "read only" data with relocations needs to go in its own section
 		// when building a shared library. We do this by boosting objects of
 		// type SXXX with relocations to type SXXXRELRO.
-		for _, symnro := range readOnly {
-			symnrelro := relROMap[symnro]
+		for _, symnro := range sym.ReadOnly {
+			symnrelro := sym.RelROMap[symnro]
 
-			ro := []*Symbol{}
+			ro := []*sym.Symbol{}
 			relro := data[symnrelro]
 
 			for _, s := range data[symnro] {
 				isRelro := len(s.R) > 0
 				switch s.Type {
-				case STYPE, STYPERELRO, SGOFUNCRELRO:
+				case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
 					// Symbols are not sorted yet, so it is possible
 					// that an Outer symbol has been changed to a
 					// relro Type before it reaches here.
@@ -1427,10 +1152,10 @@
 	}
 
 	// Sort symbols.
-	var dataMaxAlign [SXREF]int32
+	var dataMaxAlign [sym.SXREF]int32
 	var wg sync.WaitGroup
 	for symn := range data {
-		symn := SymKind(symn)
+		symn := sym.SymKind(symn)
 		wg.Add(1)
 		go func() {
 			data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn])
@@ -1446,20 +1171,20 @@
 	datsize := int64(0)
 
 	// Writable data sections that do not need any specialized handling.
-	writable := []SymKind{
-		SELFSECT,
-		SMACHO,
-		SMACHOGOT,
-		SWINDOWS,
+	writable := []sym.SymKind{
+		sym.SELFSECT,
+		sym.SMACHO,
+		sym.SMACHOGOT,
+		sym.SWINDOWS,
 	}
 	for _, symn := range writable {
 		for _, s := range data[symn] {
-			sect := addsection(&Segdata, s.Name, 06)
+			sect := addsection(ctxt.Arch, &Segdata, s.Name, 06)
 			sect.Align = symalign(s)
 			datsize = Rnd(datsize, int64(sect.Align))
 			sect.Vaddr = uint64(datsize)
 			s.Sect = sect
-			s.Type = SDATA
+			s.Type = sym.SDATA
 			s.Value = int64(uint64(datsize) - sect.Vaddr)
 			datsize += s.Size
 			sect.Length = uint64(datsize) - sect.Vaddr
@@ -1468,16 +1193,16 @@
 	}
 
 	// .got (and .toc on ppc64)
-	if len(data[SELFGOT]) > 0 {
-		sect := addsection(&Segdata, ".got", 06)
-		sect.Align = dataMaxAlign[SELFGOT]
+	if len(data[sym.SELFGOT]) > 0 {
+		sect := addsection(ctxt.Arch, &Segdata, ".got", 06)
+		sect.Align = dataMaxAlign[sym.SELFGOT]
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
-		var toc *Symbol
-		for _, s := range data[SELFGOT] {
+		var toc *sym.Symbol
+		for _, s := range data[sym.SELFGOT] {
 			datsize = aligndatsize(datsize, s)
 			s.Sect = sect
-			s.Type = SDATA
+			s.Type = sym.SDATA
 			s.Value = int64(uint64(datsize) - sect.Vaddr)
 
 			// Resolve .TOC. symbol for this object file (ppc64)
@@ -1493,98 +1218,98 @@
 
 			datsize += s.Size
 		}
-		checkdatsize(ctxt, datsize, SELFGOT)
+		checkdatsize(ctxt, datsize, sym.SELFGOT)
 		sect.Length = uint64(datsize) - sect.Vaddr
 	}
 
 	/* pointer-free data */
-	sect := addsection(&Segdata, ".noptrdata", 06)
-	sect.Align = dataMaxAlign[SNOPTRDATA]
+	sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06)
+	sect.Align = dataMaxAlign[sym.SNOPTRDATA]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect
-	for _, s := range data[SNOPTRDATA] {
+	for _, s := range data[sym.SNOPTRDATA] {
 		datsize = aligndatsize(datsize, s)
 		s.Sect = sect
-		s.Type = SDATA
+		s.Type = sym.SDATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SNOPTRDATA)
+	checkdatsize(ctxt, datsize, sym.SNOPTRDATA)
 	sect.Length = uint64(datsize) - sect.Vaddr
 
-	hasinitarr := *FlagLinkshared
+	hasinitarr := ctxt.linkShared
 
 	/* shared library initializer */
-	switch Buildmode {
-	case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
+	switch ctxt.BuildMode {
+	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
 		hasinitarr = true
 	}
 	if hasinitarr {
-		sect := addsection(&Segdata, ".init_array", 06)
-		sect.Align = dataMaxAlign[SINITARR]
+		sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06)
+		sect.Align = dataMaxAlign[sym.SINITARR]
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
-		for _, s := range data[SINITARR] {
+		for _, s := range data[sym.SINITARR] {
 			datsize = aligndatsize(datsize, s)
 			s.Sect = sect
 			s.Value = int64(uint64(datsize) - sect.Vaddr)
 			datsize += s.Size
 		}
 		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, SINITARR)
+		checkdatsize(ctxt, datsize, sym.SINITARR)
 	}
 
 	/* data */
-	sect = addsection(&Segdata, ".data", 06)
-	sect.Align = dataMaxAlign[SDATA]
+	sect = addsection(ctxt.Arch, &Segdata, ".data", 06)
+	sect.Align = dataMaxAlign[sym.SDATA]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.data", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect
 	var gc GCProg
 	gc.Init(ctxt, "runtime.gcdata")
-	for _, s := range data[SDATA] {
+	for _, s := range data[sym.SDATA] {
 		s.Sect = sect
-		s.Type = SDATA
+		s.Type = sym.SDATA
 		datsize = aligndatsize(datsize, s)
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		gc.AddSym(s)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SDATA)
+	checkdatsize(ctxt, datsize, sym.SDATA)
 	sect.Length = uint64(datsize) - sect.Vaddr
 	gc.End(int64(sect.Length))
 
 	/* bss */
-	sect = addsection(&Segdata, ".bss", 06)
-	sect.Align = dataMaxAlign[SBSS]
+	sect = addsection(ctxt.Arch, &Segdata, ".bss", 06)
+	sect.Align = dataMaxAlign[sym.SBSS]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect
 	gc = GCProg{}
 	gc.Init(ctxt, "runtime.gcbss")
-	for _, s := range data[SBSS] {
+	for _, s := range data[sym.SBSS] {
 		s.Sect = sect
 		datsize = aligndatsize(datsize, s)
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		gc.AddSym(s)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SBSS)
+	checkdatsize(ctxt, datsize, sym.SBSS)
 	sect.Length = uint64(datsize) - sect.Vaddr
 	gc.End(int64(sect.Length))
 
 	/* pointer-free bss */
-	sect = addsection(&Segdata, ".noptrbss", 06)
-	sect.Align = dataMaxAlign[SNOPTRBSS]
+	sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06)
+	sect.Align = dataMaxAlign[sym.SNOPTRBSS]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect
-	for _, s := range data[SNOPTRBSS] {
+	for _, s := range data[sym.SNOPTRBSS] {
 		datsize = aligndatsize(datsize, s)
 		s.Sect = sect
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
@@ -1593,24 +1318,24 @@
 
 	sect.Length = uint64(datsize) - sect.Vaddr
 	ctxt.Syms.Lookup("runtime.end", 0).Sect = sect
-	checkdatsize(ctxt, datsize, SNOPTRBSS)
+	checkdatsize(ctxt, datsize, sym.SNOPTRBSS)
 
-	if len(data[STLSBSS]) > 0 {
-		var sect *Section
-		if Iself && (Linkmode == LinkExternal || !*FlagD) {
-			sect = addsection(&Segdata, ".tbss", 06)
-			sect.Align = int32(SysArch.PtrSize)
+	if len(data[sym.STLSBSS]) > 0 {
+		var sect *sym.Section
+		if ctxt.IsELF && (ctxt.LinkMode == LinkExternal || !*FlagD) {
+			sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
+			sect.Align = int32(ctxt.Arch.PtrSize)
 			sect.Vaddr = 0
 		}
 		datsize = 0
 
-		for _, s := range data[STLSBSS] {
+		for _, s := range data[sym.STLSBSS] {
 			datsize = aligndatsize(datsize, s)
 			s.Sect = sect
 			s.Value = datsize
 			datsize += s.Size
 		}
-		checkdatsize(ctxt, datsize, STLSBSS)
+		checkdatsize(ctxt, datsize, sym.STLSBSS)
 
 		if sect != nil {
 			sect.Length = uint64(datsize)
@@ -1627,8 +1352,8 @@
 	 * since it's not our decision; that code expects the sections in
 	 * segtext.
 	 */
-	var segro *Segment
-	if Iself && Linkmode == LinkInternal {
+	var segro *sym.Segment
+	if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
 		segro = &Segrodata
 	} else {
 		segro = &Segtext
@@ -1637,44 +1362,44 @@
 	datsize = 0
 
 	/* read-only executable ELF, Mach-O sections */
-	if len(data[STEXT]) != 0 {
-		Errorf(nil, "dodata found an STEXT symbol: %s", data[STEXT][0].Name)
+	if len(data[sym.STEXT]) != 0 {
+		Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name)
 	}
-	for _, s := range data[SELFRXSECT] {
-		sect := addsection(&Segtext, s.Name, 04)
+	for _, s := range data[sym.SELFRXSECT] {
+		sect := addsection(ctxt.Arch, &Segtext, s.Name, 04)
 		sect.Align = symalign(s)
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, SELFRXSECT)
+		checkdatsize(ctxt, datsize, sym.SELFRXSECT)
 	}
 
 	/* read-only data */
-	sect = addsection(segro, ".rodata", 04)
+	sect = addsection(ctxt.Arch, segro, ".rodata", 04)
 
 	sect.Vaddr = 0
 	ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.erodata", 0).Sect = sect
-	if !UseRelro() {
+	if !ctxt.UseRelro() {
 		ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
 		ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
 	}
-	for _, symn := range readOnly {
+	for _, symn := range sym.ReadOnly {
 		align := dataMaxAlign[symn]
 		if sect.Align < align {
 			sect.Align = align
 		}
 	}
 	datsize = Rnd(datsize, int64(sect.Align))
-	for _, symn := range readOnly {
+	for _, symn := range sym.ReadOnly {
 		for _, s := range data[symn] {
 			datsize = aligndatsize(datsize, s)
 			s.Sect = sect
-			s.Type = SRODATA
+			s.Type = sym.SRODATA
 			s.Value = int64(uint64(datsize) - sect.Vaddr)
 			datsize += s.Size
 		}
@@ -1683,31 +1408,31 @@
 	sect.Length = uint64(datsize) - sect.Vaddr
 
 	/* read-only ELF, Mach-O sections */
-	for _, s := range data[SELFROSECT] {
-		sect = addsection(segro, s.Name, 04)
+	for _, s := range data[sym.SELFROSECT] {
+		sect = addsection(ctxt.Arch, segro, s.Name, 04)
 		sect.Align = symalign(s)
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 		sect.Length = uint64(datsize) - sect.Vaddr
 	}
-	checkdatsize(ctxt, datsize, SELFROSECT)
+	checkdatsize(ctxt, datsize, sym.SELFROSECT)
 
-	for _, s := range data[SMACHOPLT] {
-		sect = addsection(segro, s.Name, 04)
+	for _, s := range data[sym.SMACHOPLT] {
+		sect = addsection(ctxt.Arch, segro, s.Name, 04)
 		sect.Align = symalign(s)
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 		sect.Length = uint64(datsize) - sect.Vaddr
 	}
-	checkdatsize(ctxt, datsize, SMACHOPLT)
+	checkdatsize(ctxt, datsize, sym.SMACHOPLT)
 
 	// There is some data that are conceptually read-only but are written to by
 	// relocations. On GNU systems, we can arrange for the dynamic linker to
@@ -1719,14 +1444,14 @@
 	// situation.
 	// TODO(mwhudson): It would make sense to do this more widely, but it makes
 	// the system linker segfault on darwin.
-	addrelrosection := func(suffix string) *Section {
-		return addsection(segro, suffix, 04)
+	addrelrosection := func(suffix string) *sym.Section {
+		return addsection(ctxt.Arch, segro, suffix, 04)
 	}
 
-	if UseRelro() {
-		addrelrosection = func(suffix string) *Section {
+	if ctxt.UseRelro() {
+		addrelrosection = func(suffix string) *sym.Section {
 			seg := &Segrelrodata
-			if Linkmode == LinkExternal {
+			if ctxt.LinkMode == LinkExternal {
 				// Using a separate segment with an external
 				// linker results in some programs moving
 				// their data sections unexpectedly, which
@@ -1735,7 +1460,7 @@
 				// sort out a rel.ro segment.
 				seg = &Segrodata
 			}
-			return addsection(seg, ".data.rel.ro"+suffix, 06)
+			return addsection(ctxt.Arch, seg, ".data.rel.ro"+suffix, 06)
 		}
 		/* data only written by relocations */
 		sect = addrelrosection("")
@@ -1743,23 +1468,23 @@
 		sect.Vaddr = 0
 		ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
 		ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
-		for _, symnro := range readOnly {
-			symn := relROMap[symnro]
+		for _, symnro := range sym.ReadOnly {
+			symn := sym.RelROMap[symnro]
 			align := dataMaxAlign[symn]
 			if sect.Align < align {
 				sect.Align = align
 			}
 		}
 		datsize = Rnd(datsize, int64(sect.Align))
-		for _, symnro := range readOnly {
-			symn := relROMap[symnro]
+		for _, symnro := range sym.ReadOnly {
+			symn := sym.RelROMap[symnro]
 			for _, s := range data[symn] {
 				datsize = aligndatsize(datsize, s)
 				if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
 					Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name)
 				}
 				s.Sect = sect
-				s.Type = SRODATA
+				s.Type = sym.SRODATA
 				s.Value = int64(uint64(datsize) - sect.Vaddr)
 				datsize += s.Size
 			}
@@ -1771,65 +1496,65 @@
 
 	/* typelink */
 	sect = addrelrosection(".typelink")
-	sect.Align = dataMaxAlign[STYPELINK]
+	sect.Align = dataMaxAlign[sym.STYPELINK]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	typelink := ctxt.Syms.Lookup("runtime.typelink", 0)
 	typelink.Sect = sect
-	typelink.Type = SRODATA
+	typelink.Type = sym.SRODATA
 	datsize += typelink.Size
-	checkdatsize(ctxt, datsize, STYPELINK)
+	checkdatsize(ctxt, datsize, sym.STYPELINK)
 	sect.Length = uint64(datsize) - sect.Vaddr
 
 	/* itablink */
 	sect = addrelrosection(".itablink")
-	sect.Align = dataMaxAlign[SITABLINK]
+	sect.Align = dataMaxAlign[sym.SITABLINK]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect
-	for _, s := range data[SITABLINK] {
+	for _, s := range data[sym.SITABLINK] {
 		datsize = aligndatsize(datsize, s)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SITABLINK)
+	checkdatsize(ctxt, datsize, sym.SITABLINK)
 	sect.Length = uint64(datsize) - sect.Vaddr
 
 	/* gosymtab */
 	sect = addrelrosection(".gosymtab")
-	sect.Align = dataMaxAlign[SSYMTAB]
+	sect.Align = dataMaxAlign[sym.SSYMTAB]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect
-	for _, s := range data[SSYMTAB] {
+	for _, s := range data[sym.SSYMTAB] {
 		datsize = aligndatsize(datsize, s)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SSYMTAB)
+	checkdatsize(ctxt, datsize, sym.SSYMTAB)
 	sect.Length = uint64(datsize) - sect.Vaddr
 
 	/* gopclntab */
 	sect = addrelrosection(".gopclntab")
-	sect.Align = dataMaxAlign[SPCLNTAB]
+	sect.Align = dataMaxAlign[sym.SPCLNTAB]
 	datsize = Rnd(datsize, int64(sect.Align))
 	sect.Vaddr = uint64(datsize)
 	ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect
 	ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect
-	for _, s := range data[SPCLNTAB] {
+	for _, s := range data[sym.SPCLNTAB] {
 		datsize = aligndatsize(datsize, s)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 	}
-	checkdatsize(ctxt, datsize, SRODATA)
+	checkdatsize(ctxt, datsize, sym.SRODATA)
 	sect.Length = uint64(datsize) - sect.Vaddr
 
 	// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
@@ -1837,48 +1562,61 @@
 		Errorf(nil, "read-only data segment too large: %d", datsize)
 	}
 
-	for symn := SELFRXSECT; symn < SXREF; symn++ {
+	for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
 		datap = append(datap, data[symn]...)
 	}
 
 	dwarfgeneratedebugsyms(ctxt)
 
-	var s *Symbol
 	var i int
-	for i, s = range dwarfp {
-		if s.Type != SDWARFSECT {
+	for ; i < len(dwarfp); i++ {
+		s := dwarfp[i]
+		if s.Type != sym.SDWARFSECT {
 			break
 		}
 
-		sect = addsection(&Segdwarf, s.Name, 04)
+		sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04)
 		sect.Align = 1
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
 		s.Sect = sect
-		s.Type = SRODATA
+		s.Type = sym.SRODATA
 		s.Value = int64(uint64(datsize) - sect.Vaddr)
 		datsize += s.Size
 		sect.Length = uint64(datsize) - sect.Vaddr
 	}
-	checkdatsize(ctxt, datsize, SDWARFSECT)
+	checkdatsize(ctxt, datsize, sym.SDWARFSECT)
 
-	if i < len(dwarfp) {
-		sect = addsection(&Segdwarf, ".debug_info", 04)
+	for i < len(dwarfp) {
+		curType := dwarfp[i].Type
+		var sect *sym.Section
+		switch curType {
+		case sym.SDWARFINFO:
+			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04)
+		case sym.SDWARFRANGE:
+			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04)
+		case sym.SDWARFLOC:
+			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04)
+		default:
+			Errorf(dwarfp[i], "unknown DWARF section %v", curType)
+		}
+
 		sect.Align = 1
 		datsize = Rnd(datsize, int64(sect.Align))
 		sect.Vaddr = uint64(datsize)
-		for _, s := range dwarfp[i:] {
-			if s.Type != SDWARFINFO {
+		for ; i < len(dwarfp); i++ {
+			s := dwarfp[i]
+			if s.Type != curType {
 				break
 			}
 			s.Sect = sect
-			s.Type = SRODATA
+			s.Type = sym.SRODATA
 			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			s.Attr |= AttrLocal
+			s.Attr |= sym.AttrLocal
 			datsize += s.Size
 		}
 		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, SDWARFINFO)
+		checkdatsize(ctxt, datsize, curType)
 	}
 
 	/* number the sections */
@@ -1906,11 +1644,11 @@
 	}
 }
 
-func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, maxAlign int32) {
-	if Headtype == objabi.Hdarwin {
+func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) {
+	if ctxt.HeadType == objabi.Hdarwin {
 		// Some symbols may no longer belong in syms
 		// due to movement in machosymorder.
-		newSyms := make([]*Symbol, 0, len(syms))
+		newSyms := make([]*sym.Symbol, 0, len(syms))
 		for _, s := range syms {
 			if s.Type == symn {
 				newSyms = append(newSyms, s)
@@ -1919,13 +1657,13 @@
 		syms = newSyms
 	}
 
-	var head, tail *Symbol
+	var head, tail *sym.Symbol
 	symsSort := make([]dataSortKey, 0, len(syms))
 	for _, s := range syms {
 		if s.Attr.OnList() {
 			log.Fatalf("symbol %s listed multiple times", s.Name)
 		}
-		s.Attr |= AttrOnList
+		s.Attr |= sym.AttrOnList
 		switch {
 		case s.Size < int64(len(s.P)):
 			Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P))
@@ -1938,7 +1676,7 @@
 		// If the usually-special section-marker symbols are being laid
 		// out as regular symbols, put them either at the beginning or
 		// end of their section.
-		if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin {
+		if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin {
 			switch s.Name {
 			case "runtime.text", "runtime.bss", "runtime.data", "runtime.types":
 				head = s
@@ -1956,9 +1694,9 @@
 		}
 
 		switch s.Type {
-		case SELFGOT:
+		case sym.SELFGOT:
 			// For ppc64, we want to interleave the .got and .toc sections
-			// from input files. Both are type SELFGOT, so in that case
+			// from input files. Both are type sym.SELFGOT, so in that case
 			// we skip size comparison and fall through to the name
 			// comparison (conveniently, .got sorts before .toc).
 			key.size = 0
@@ -1985,7 +1723,7 @@
 		syms[len(syms)-1] = tail
 	}
 
-	if Iself && symn == SELFROSECT {
+	if ctxt.IsELF && symn == sym.SELFROSECT {
 		// Make .rela and .rela.plt contiguous, the ELF ABI requires this
 		// and Solaris actually cares.
 		reli, plti := -1, -1
@@ -2013,8 +1751,8 @@
 			// Setting the alignment explicitly prevents
 			// symalign from basing it on the size and
 			// getting it wrong.
-			rel.Align = int32(SysArch.RegSize)
-			plt.Align = int32(SysArch.RegSize)
+			rel.Align = int32(ctxt.Arch.RegSize)
+			plt.Align = int32(ctxt.Arch.RegSize)
 		}
 	}
 
@@ -2027,27 +1765,27 @@
 // at the very beginning of the text segment.
 // This ``header'' is read by cmd/go.
 func (ctxt *Link) textbuildid() {
-	if Iself || Buildmode == BuildmodePlugin || *flagBuildid == "" {
+	if ctxt.IsELF || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" {
 		return
 	}
 
-	sym := ctxt.Syms.Lookup("go.buildid", 0)
-	sym.Attr |= AttrReachable
+	s := ctxt.Syms.Lookup("go.buildid", 0)
+	s.Attr |= sym.AttrReachable
 	// The \xff is invalid UTF-8, meant to make it less likely
 	// to find one of these accidentally.
 	data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
-	sym.Type = STEXT
-	sym.P = []byte(data)
-	sym.Size = int64(len(sym.P))
+	s.Type = sym.STEXT
+	s.P = []byte(data)
+	s.Size = int64(len(s.P))
 
 	ctxt.Textp = append(ctxt.Textp, nil)
 	copy(ctxt.Textp[1:], ctxt.Textp)
-	ctxt.Textp[0] = sym
+	ctxt.Textp[0] = s
 }
 
 // assign addresses to text
 func (ctxt *Link) textaddress() {
-	addsection(&Segtext, ".text", 05)
+	addsection(ctxt.Arch, &Segtext, ".text", 05)
 
 	// Assign PCs in text segment.
 	// Could parallelize, by assigning to text
@@ -2059,7 +1797,7 @@
 	text := ctxt.Syms.Lookup("runtime.text", 0)
 	text.Sect = sect
 
-	if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin {
+	if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin {
 		etext := ctxt.Syms.Lookup("runtime.etext", 0)
 		etext.Sect = sect
 
@@ -2072,10 +1810,10 @@
 	n := 1
 	sect.Vaddr = va
 	ntramps := 0
-	for _, sym := range ctxt.Textp {
-		sect, n, va = assignAddress(ctxt, sect, n, sym, va, false)
+	for _, s := range ctxt.Textp {
+		sect, n, va = assignAddress(ctxt, sect, n, s, va, false)
 
-		trampoline(ctxt, sym) // resolve jumps, may add trampolines if jump too far
+		trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
 
 		// lay down trampolines after each function
 		for ; ntramps < len(ctxt.tramps); ntramps++ {
@@ -2089,13 +1827,13 @@
 
 	// merge tramps into Textp, keeping Textp in address order
 	if ntramps != 0 {
-		newtextp := make([]*Symbol, 0, len(ctxt.Textp)+ntramps)
+		newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps)
 		i := 0
-		for _, sym := range ctxt.Textp {
-			for ; i < ntramps && ctxt.tramps[i].Value < sym.Value; i++ {
+		for _, s := range ctxt.Textp {
+			for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ {
 				newtextp = append(newtextp, ctxt.tramps[i])
 			}
-			newtextp = append(newtextp, sym)
+			newtextp = append(newtextp, s)
 		}
 		newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
 
@@ -2106,24 +1844,24 @@
 // assigns address for a text symbol, returns (possibly new) section, its number, and the address
 // Note: once we have trampoline insertion support for external linking, this function
 // will not need to create new text sections, and so no need to return sect and n.
-func assignAddress(ctxt *Link, sect *Section, n int, sym *Symbol, va uint64, isTramp bool) (*Section, int, uint64) {
-	sym.Sect = sect
-	if sym.Type&SSUB != 0 {
+func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
+	s.Sect = sect
+	if s.Attr.SubSymbol() {
 		return sect, n, va
 	}
-	if sym.Align != 0 {
-		va = uint64(Rnd(int64(va), int64(sym.Align)))
+	if s.Align != 0 {
+		va = uint64(Rnd(int64(va), int64(s.Align)))
 	} else {
 		va = uint64(Rnd(int64(va), int64(Funcalign)))
 	}
-	sym.Value = 0
-	for sub := sym; sub != nil; sub = sub.Sub {
+	s.Value = 0
+	for sub := s; sub != nil; sub = sub.Sub {
 		sub.Value += int64(va)
 	}
 
 	funcsize := uint64(MINFUNC) // spacing required for findfunctab
-	if sym.Size > MINFUNC {
-		funcsize = uint64(sym.Size)
+	if s.Size > MINFUNC {
+		funcsize = uint64(s.Size)
 	}
 
 	// On ppc64x a text section should not be larger than 2^26 bytes due to the size of
@@ -2135,15 +1873,15 @@
 
 	// Only break at outermost syms.
 
-	if SysArch.InFamily(sys.PPC64) && sym.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(sym, isTramp) > 0x1c00000 {
+	if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && ctxt.IsELF && ctxt.LinkMode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
 
 		// Set the length for the previous text section
 		sect.Length = va - sect.Vaddr
 
 		// Create new section, set the starting Vaddr
-		sect = addsection(&Segtext, ".text", 05)
+		sect = addsection(ctxt.Arch, &Segtext, ".text", 05)
 		sect.Vaddr = va
-		sym.Sect = sect
+		s.Sect = sect
 
 		// Create a symbol for the start of the secondary text sections
 		ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
@@ -2168,7 +1906,7 @@
 
 	Segtext.Length = va - uint64(*FlagTextAddr)
 	Segtext.Filelen = Segtext.Length
-	if Headtype == objabi.Hnacl {
+	if ctxt.HeadType == objabi.Hnacl {
 		va += 32 // room for the "halt sled"
 	}
 
@@ -2225,23 +1963,22 @@
 	Segdata.Vaddr = va
 	Segdata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff
 	Segdata.Filelen = 0
-	if Headtype == objabi.Hwindows {
+	if ctxt.HeadType == objabi.Hwindows {
 		Segdata.Fileoff = Segtext.Fileoff + uint64(Rnd(int64(Segtext.Length), PEFILEALIGN))
 	}
-	if Headtype == objabi.Hplan9 {
+	if ctxt.HeadType == objabi.Hplan9 {
 		Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen
 	}
-	var data *Section
-	var noptr *Section
-	var bss *Section
-	var noptrbss *Section
-	var vlen int64
+	var data *sym.Section
+	var noptr *sym.Section
+	var bss *sym.Section
+	var noptrbss *sym.Section
 	for i, s := range Segdata.Sections {
-		if Iself && s.Name == ".tbss" {
+		if ctxt.IsELF && s.Name == ".tbss" {
 			continue
 		}
-		vlen = int64(s.Length)
-		if i+1 < len(Segdata.Sections) && !(Iself && Segdata.Sections[i+1].Name == ".tbss") {
+		vlen := int64(s.Length)
+		if i+1 < len(Segdata.Sections) && !(ctxt.IsELF && Segdata.Sections[i+1].Name == ".tbss") {
 			vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
 		}
 		s.Vaddr = va
@@ -2268,17 +2005,17 @@
 	Segdwarf.Vaddr = va
 	Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(*FlagRound)))
 	Segdwarf.Filelen = 0
-	if Headtype == objabi.Hwindows {
+	if ctxt.HeadType == objabi.Hwindows {
 		Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(PEFILEALIGN)))
 	}
 	for i, s := range Segdwarf.Sections {
-		vlen = int64(s.Length)
+		vlen := int64(s.Length)
 		if i+1 < len(Segdwarf.Sections) {
 			vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
 		}
 		s.Vaddr = va
 		va += uint64(vlen)
-		if Headtype == objabi.Hwindows {
+		if ctxt.HeadType == objabi.Hwindows {
 			va = uint64(Rnd(int64(va), PEFILEALIGN))
 		}
 		Segdwarf.Length = va - Segdwarf.Vaddr
@@ -2311,75 +2048,74 @@
 		}
 	}
 
-	for _, sym := range dwarfp {
-		if sym.Sect != nil {
-			sym.Value += int64(sym.Sect.Vaddr)
+	for _, s := range dwarfp {
+		if s.Sect != nil {
+			s.Value += int64(s.Sect.Vaddr)
 		}
-		for sub := sym.Sub; sub != nil; sub = sub.Sub {
-			sub.Value += sym.Value
+		for sub := s.Sub; sub != nil; sub = sub.Sub {
+			sub.Value += s.Value
 		}
 	}
 
-	if Buildmode == BuildmodeShared {
+	if ctxt.BuildMode == BuildModeShared {
 		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
 		sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0)
 		s.Sect = sectSym.Sect
 		s.Value = int64(sectSym.Sect.Vaddr + 16)
 	}
 
-	ctxt.xdefine("runtime.text", STEXT, int64(text.Vaddr))
-	ctxt.xdefine("runtime.etext", STEXT, int64(lasttext.Vaddr+lasttext.Length))
+	ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr))
+	ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length))
 
 	// If there are multiple text sections, create runtime.text.n for
 	// their section Vaddr, using n for index
 	n := 1
 	for _, sect := range Segtext.Sections[1:] {
-		if sect.Name == ".text" {
-			symname := fmt.Sprintf("runtime.text.%d", n)
-			ctxt.xdefine(symname, STEXT, int64(sect.Vaddr))
-			n++
-		} else {
+		if sect.Name != ".text" {
 			break
 		}
+		symname := fmt.Sprintf("runtime.text.%d", n)
+		ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
+		n++
 	}
 
-	ctxt.xdefine("runtime.rodata", SRODATA, int64(rodata.Vaddr))
-	ctxt.xdefine("runtime.erodata", SRODATA, int64(rodata.Vaddr+rodata.Length))
-	ctxt.xdefine("runtime.types", SRODATA, int64(types.Vaddr))
-	ctxt.xdefine("runtime.etypes", SRODATA, int64(types.Vaddr+types.Length))
-	ctxt.xdefine("runtime.itablink", SRODATA, int64(itablink.Vaddr))
-	ctxt.xdefine("runtime.eitablink", SRODATA, int64(itablink.Vaddr+itablink.Length))
+	ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
+	ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
+	ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
+	ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
+	ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
+	ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
 
-	sym := ctxt.Syms.Lookup("runtime.gcdata", 0)
-	sym.Attr |= AttrLocal
-	ctxt.xdefine("runtime.egcdata", SRODATA, Symaddr(sym)+sym.Size)
-	ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = sym.Sect
+	s := ctxt.Syms.Lookup("runtime.gcdata", 0)
+	s.Attr |= sym.AttrLocal
+	ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size)
+	ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect
 
-	sym = ctxt.Syms.Lookup("runtime.gcbss", 0)
-	sym.Attr |= AttrLocal
-	ctxt.xdefine("runtime.egcbss", SRODATA, Symaddr(sym)+sym.Size)
-	ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = sym.Sect
+	s = ctxt.Syms.Lookup("runtime.gcbss", 0)
+	s.Attr |= sym.AttrLocal
+	ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size)
+	ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect
 
-	ctxt.xdefine("runtime.symtab", SRODATA, int64(symtab.Vaddr))
-	ctxt.xdefine("runtime.esymtab", SRODATA, int64(symtab.Vaddr+symtab.Length))
-	ctxt.xdefine("runtime.pclntab", SRODATA, int64(pclntab.Vaddr))
-	ctxt.xdefine("runtime.epclntab", SRODATA, int64(pclntab.Vaddr+pclntab.Length))
-	ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, int64(noptr.Vaddr))
-	ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
-	ctxt.xdefine("runtime.bss", SBSS, int64(bss.Vaddr))
-	ctxt.xdefine("runtime.ebss", SBSS, int64(bss.Vaddr+bss.Length))
-	ctxt.xdefine("runtime.data", SDATA, int64(data.Vaddr))
-	ctxt.xdefine("runtime.edata", SDATA, int64(data.Vaddr+data.Length))
-	ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, int64(noptrbss.Vaddr))
-	ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
-	ctxt.xdefine("runtime.end", SBSS, int64(Segdata.Vaddr+Segdata.Length))
+	ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
+	ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
+	ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
+	ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
+	ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
+	ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
+	ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
+	ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
+	ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
+	ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
+	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
+	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
+	ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
 }
 
 // add a trampoline with symbol s (to be laid down after the current function)
-func (ctxt *Link) AddTramp(s *Symbol) {
-	s.Type = STEXT
-	s.Attr |= AttrReachable
-	s.Attr |= AttrOnList
+func (ctxt *Link) AddTramp(s *sym.Symbol) {
+	s.Type = sym.STEXT
+	s.Attr |= sym.AttrReachable
+	s.Attr |= sym.AttrOnList
 	ctxt.tramps = append(ctxt.tramps, s)
 	if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
 		ctxt.Logf("trampoline %s inserted\n", s)
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index dbb96fb..c5c48e5 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -7,6 +7,7 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"fmt"
 	"strings"
 	"unicode"
@@ -107,20 +108,27 @@
 		}
 	}
 
-	if Buildmode != BuildmodeShared {
+	if ctxt.BuildMode != BuildModeShared {
 		// Keep a itablink if the symbol it points at is being kept.
-		// (When BuildmodeShared, always keep itablinks.)
+		// (When BuildModeShared, always keep itablinks.)
 		for _, s := range ctxt.Syms.Allsym {
 			if strings.HasPrefix(s.Name, "go.itablink.") {
-				s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
+				s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
 			}
 		}
 	}
 
+	for _, lib := range ctxt.Library {
+		lib.Textp = lib.Textp[:0]
+	}
+
 	// Remove dead text but keep file information (z symbols).
-	textp := make([]*Symbol, 0, len(ctxt.Textp))
+	textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
 	for _, s := range ctxt.Textp {
 		if s.Attr.Reachable() {
+			if s.Lib != nil {
+				s.Lib.Textp = append(s.Lib.Textp, s)
+			}
 			textp = append(textp, s)
 		}
 	}
@@ -132,11 +140,11 @@
 // the reflect.method struct: mtyp, ifn, and tfn.
 type methodref struct {
 	m   methodsig
-	src *Symbol   // receiver type symbol
-	r   [3]*Reloc // R_METHODOFF relocations to fields of runtime.method
+	src *sym.Symbol   // receiver type symbol
+	r   [3]*sym.Reloc // R_METHODOFF relocations to fields of runtime.method
 }
 
-func (m methodref) ifn() *Symbol { return m.r[1].Sym }
+func (m methodref) ifn() *sym.Symbol { return m.r[1].Sym }
 
 func (m methodref) isExported() bool {
 	for _, r := range m.m {
@@ -148,13 +156,13 @@
 // deadcodepass holds state for the deadcode flood fill.
 type deadcodepass struct {
 	ctxt            *Link
-	markQueue       []*Symbol          // symbols to flood fill in next pass
+	markQueue       []*sym.Symbol      // symbols to flood fill in next pass
 	ifaceMethod     map[methodsig]bool // methods declared in reached interfaces
 	markableMethods []methodref        // methods of reached types
 	reflectMethod   bool
 }
 
-func (d *deadcodepass) cleanupReloc(r *Reloc) {
+func (d *deadcodepass) cleanupReloc(r *sym.Reloc) {
 	if r.Sym.Attr.Reachable() {
 		r.Type = objabi.R_ADDROFF
 	} else {
@@ -167,7 +175,7 @@
 }
 
 // mark appends a symbol to the mark queue for flood filling.
-func (d *deadcodepass) mark(s, parent *Symbol) {
+func (d *deadcodepass) mark(s, parent *sym.Symbol) {
 	if s == nil || s.Attr.Reachable() {
 		return
 	}
@@ -181,7 +189,7 @@
 		}
 		fmt.Printf("%s -> %s\n", p, s.Name)
 	}
-	s.Attr |= AttrReachable
+	s.Attr |= sym.AttrReachable
 	s.Reachparent = parent
 	d.markQueue = append(d.markQueue, s)
 }
@@ -199,34 +207,45 @@
 func (d *deadcodepass) init() {
 	var names []string
 
-	if SysArch.Family == sys.ARM {
+	if d.ctxt.Arch.Family == sys.ARM {
 		// mark some functions that are only referenced after linker code editing
 		names = append(names, "runtime.read_tls_fallback")
 	}
 
-	if Buildmode == BuildmodeShared {
+	if d.ctxt.BuildMode == BuildModeShared {
 		// Mark all symbols defined in this library as reachable when
 		// building a shared library.
 		for _, s := range d.ctxt.Syms.Allsym {
-			if s.Type != 0 && s.Type != SDYNIMPORT {
+			if s.Type != 0 && s.Type != sym.SDYNIMPORT {
 				d.mark(s, nil)
 			}
 		}
 	} else {
 		// In a normal binary, start at main.main and the init
 		// functions and mark what is reachable from there.
-		names = append(names, *flagEntrySymbol)
-		if *FlagLinkshared && (Buildmode == BuildmodeExe || Buildmode == BuildmodePIE) {
-			names = append(names, "main.main", "main.init")
-		} else if Buildmode == BuildmodePlugin {
-			names = append(names, *flagPluginPath+".init", *flagPluginPath+".main", "go.plugin.tabs")
 
-			// We don't keep the go.plugin.exports symbol,
-			// but we do keep the symbols it refers to.
-			exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
-			if exports != nil {
-				for _, r := range exports.R {
-					d.mark(r.Sym, nil)
+		if d.ctxt.linkShared && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
+			names = append(names, "main.main", "main.init")
+		} else {
+			// The external linker refers main symbol directly.
+			if d.ctxt.LinkMode == LinkExternal && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
+				if d.ctxt.HeadType == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
+					*flagEntrySymbol = "_main"
+				} else {
+					*flagEntrySymbol = "main"
+				}
+			}
+			names = append(names, *flagEntrySymbol)
+			if d.ctxt.BuildMode == BuildModePlugin {
+				names = append(names, objabi.PathToPrefix(*flagPluginPath)+".init", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
+
+				// We don't keep the go.plugin.exports symbol,
+				// but we do keep the symbols it refers to.
+				exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
+				if exports != nil {
+					for _, r := range exports.R {
+						d.mark(r.Sym, nil)
+					}
 				}
 			}
 		}
@@ -240,13 +259,13 @@
 	}
 }
 
-// flood flood fills symbols reachable from the markQueue symbols.
+// flood fills symbols reachable from the markQueue symbols.
 // As it goes, it collects methodref and interface method declarations.
 func (d *deadcodepass) flood() {
 	for len(d.markQueue) > 0 {
 		s := d.markQueue[0]
 		d.markQueue = d.markQueue[1:]
-		if s.Type == STEXT {
+		if s.Type == sym.STEXT {
 			if d.ctxt.Debugvlog > 1 {
 				d.ctxt.Logf("marktext %s\n", s.Name)
 			}
@@ -264,7 +283,7 @@
 				// later will give a better error than deadcode.
 				continue
 			}
-			if decodetypeKind(s)&kindMask == kindInterface {
+			if decodetypeKind(d.ctxt.Arch, s)&kindMask == kindInterface {
 				for _, sig := range decodeIfaceMethods(d.ctxt.Arch, s) {
 					if d.ctxt.Debugvlog > 1 {
 						d.ctxt.Logf("reached iface method: %s\n", sig)
diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go
index eba8ee3..3afb389 100644
--- a/src/cmd/link/internal/ld/decodesym.go
+++ b/src/cmd/link/internal/ld/decodesym.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"debug/elf"
 	"fmt"
 )
@@ -28,7 +29,7 @@
 	tflagExtraStar = 1 << 1
 )
 
-func decodeReloc(s *Symbol, off int32) *Reloc {
+func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc {
 	for i := range s.R {
 		if s.R[i].Off == off {
 			return &s.R[i]
@@ -37,7 +38,7 @@
 	return nil
 }
 
-func decodeRelocSym(s *Symbol, off int32) *Symbol {
+func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol {
 	r := decodeReloc(s, off)
 	if r == nil {
 		return nil
@@ -59,33 +60,33 @@
 	}
 }
 
-func commonsize() int      { return 4*SysArch.PtrSize + 8 + 8 } // runtime._type
-func structfieldSize() int { return 3 * SysArch.PtrSize }       // runtime.structfield
-func uncommonSize() int    { return 4 + 2 + 2 + 4 + 4 }         // runtime.uncommontype
+func commonsize(arch *sys.Arch) int      { return 4*arch.PtrSize + 8 + 8 } // runtime._type
+func structfieldSize(arch *sys.Arch) int { return 3 * arch.PtrSize }       // runtime.structfield
+func uncommonSize() int                  { return 4 + 2 + 2 + 4 + 4 }      // runtime.uncommontype
 
 // Type.commonType.kind
-func decodetypeKind(s *Symbol) uint8 {
-	return s.P[2*SysArch.PtrSize+7] & objabi.KindMask //  0x13 / 0x1f
+func decodetypeKind(arch *sys.Arch, s *sym.Symbol) uint8 {
+	return s.P[2*arch.PtrSize+7] & objabi.KindMask //  0x13 / 0x1f
 }
 
 // Type.commonType.kind
-func decodetypeUsegcprog(s *Symbol) uint8 {
-	return s.P[2*SysArch.PtrSize+7] & objabi.KindGCProg //  0x13 / 0x1f
+func decodetypeUsegcprog(arch *sys.Arch, s *sym.Symbol) uint8 {
+	return s.P[2*arch.PtrSize+7] & objabi.KindGCProg //  0x13 / 0x1f
 }
 
 // Type.commonType.size
-func decodetypeSize(arch *sys.Arch, s *Symbol) int64 {
-	return int64(decodeInuxi(arch, s.P, SysArch.PtrSize)) // 0x8 / 0x10
+func decodetypeSize(arch *sys.Arch, s *sym.Symbol) int64 {
+	return int64(decodeInuxi(arch, s.P, arch.PtrSize)) // 0x8 / 0x10
 }
 
 // Type.commonType.ptrdata
-func decodetypePtrdata(arch *sys.Arch, s *Symbol) int64 {
-	return int64(decodeInuxi(arch, s.P[SysArch.PtrSize:], SysArch.PtrSize)) // 0x8 / 0x10
+func decodetypePtrdata(arch *sys.Arch, s *sym.Symbol) int64 {
+	return int64(decodeInuxi(arch, s.P[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10
 }
 
 // Type.commonType.tflag
-func decodetypeHasUncommon(s *Symbol) bool {
-	return s.P[2*SysArch.PtrSize+4]&tflagUncommon != 0
+func decodetypeHasUncommon(arch *sys.Arch, s *sym.Symbol) bool {
+	return s.P[2*arch.PtrSize+4]&tflagUncommon != 0
 }
 
 // Find the elf.Section of a given shared library that contains a given address.
@@ -103,8 +104,8 @@
 }
 
 // Type.commonType.gc
-func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
-	if s.Type == SDYNIMPORT {
+func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
+	if s.Type == sym.SDYNIMPORT {
 		addr := decodetypeGcprogShlib(ctxt, s)
 		sect := findShlibSection(ctxt, s.File, addr)
 		if sect != nil {
@@ -119,11 +120,11 @@
 		Exitf("cannot find gcprog for %s", s.Name)
 		return nil
 	}
-	return decodeRelocSym(s, 2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize)).P
+	return decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize)).P
 }
 
-func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 {
-	if SysArch.Family == sys.ARM64 {
+func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
+	if ctxt.Arch.Family == sys.ARM64 {
 		for _, shlib := range ctxt.Shlibs {
 			if shlib.Path == s.File {
 				return shlib.gcdataAddresses[s]
@@ -131,108 +132,108 @@
 		}
 		return 0
 	}
-	return decodeInuxi(ctxt.Arch, s.P[2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize):], SysArch.PtrSize)
+	return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
 }
 
-func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
-	if s.Type == SDYNIMPORT {
+func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
+	if s.Type == sym.SDYNIMPORT {
 		addr := decodetypeGcprogShlib(ctxt, s)
 		ptrdata := decodetypePtrdata(ctxt.Arch, s)
 		sect := findShlibSection(ctxt, s.File, addr)
 		if sect != nil {
-			r := make([]byte, ptrdata/int64(SysArch.PtrSize))
+			r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
 			sect.ReadAt(r, int64(addr-sect.Addr))
 			return r
 		}
 		Exitf("cannot find gcmask for %s", s.Name)
 		return nil
 	}
-	mask := decodeRelocSym(s, 2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize))
+	mask := decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
 	return mask.P
 }
 
 // Type.ArrayType.elem and Type.SliceType.Elem
-func decodetypeArrayElem(s *Symbol) *Symbol {
-	return decodeRelocSym(s, int32(commonsize())) // 0x1c / 0x30
+func decodetypeArrayElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
+	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
-func decodetypeArrayLen(arch *sys.Arch, s *Symbol) int64 {
-	return int64(decodeInuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
+func decodetypeArrayLen(arch *sys.Arch, s *sym.Symbol) int64 {
+	return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
 }
 
 // Type.PtrType.elem
-func decodetypePtrElem(s *Symbol) *Symbol {
-	return decodeRelocSym(s, int32(commonsize())) // 0x1c / 0x30
+func decodetypePtrElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
+	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 // Type.MapType.key, elem
-func decodetypeMapKey(s *Symbol) *Symbol {
-	return decodeRelocSym(s, int32(commonsize())) // 0x1c / 0x30
+func decodetypeMapKey(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
+	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
-func decodetypeMapValue(s *Symbol) *Symbol {
-	return decodeRelocSym(s, int32(commonsize())+int32(SysArch.PtrSize)) // 0x20 / 0x38
+func decodetypeMapValue(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
+	return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
 }
 
 // Type.ChanType.elem
-func decodetypeChanElem(s *Symbol) *Symbol {
-	return decodeRelocSym(s, int32(commonsize())) // 0x1c / 0x30
+func decodetypeChanElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
+	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 // Type.FuncType.dotdotdot
-func decodetypeFuncDotdotdot(arch *sys.Arch, s *Symbol) bool {
-	return uint16(decodeInuxi(arch, s.P[commonsize()+2:], 2))&(1<<15) != 0
+func decodetypeFuncDotdotdot(arch *sys.Arch, s *sym.Symbol) bool {
+	return uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2))&(1<<15) != 0
 }
 
 // Type.FuncType.inCount
-func decodetypeFuncInCount(arch *sys.Arch, s *Symbol) int {
-	return int(decodeInuxi(arch, s.P[commonsize():], 2))
+func decodetypeFuncInCount(arch *sys.Arch, s *sym.Symbol) int {
+	return int(decodeInuxi(arch, s.P[commonsize(arch):], 2))
 }
 
-func decodetypeFuncOutCount(arch *sys.Arch, s *Symbol) int {
-	return int(uint16(decodeInuxi(arch, s.P[commonsize()+2:], 2)) & (1<<15 - 1))
+func decodetypeFuncOutCount(arch *sys.Arch, s *sym.Symbol) int {
+	return int(uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2)) & (1<<15 - 1))
 }
 
-func decodetypeFuncInType(s *Symbol, i int) *Symbol {
-	uadd := commonsize() + 4
-	if SysArch.PtrSize == 8 {
+func decodetypeFuncInType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
+	uadd := commonsize(arch) + 4
+	if arch.PtrSize == 8 {
 		uadd += 4
 	}
-	if decodetypeHasUncommon(s) {
+	if decodetypeHasUncommon(arch, s) {
 		uadd += uncommonSize()
 	}
-	return decodeRelocSym(s, int32(uadd+i*SysArch.PtrSize))
+	return decodeRelocSym(s, int32(uadd+i*arch.PtrSize))
 }
 
-func decodetypeFuncOutType(arch *sys.Arch, s *Symbol, i int) *Symbol {
-	return decodetypeFuncInType(s, i+decodetypeFuncInCount(arch, s))
+func decodetypeFuncOutType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
+	return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s))
 }
 
 // Type.StructType.fields.Slice::length
-func decodetypeStructFieldCount(arch *sys.Arch, s *Symbol) int {
-	return int(decodeInuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
+func decodetypeStructFieldCount(arch *sys.Arch, s *sym.Symbol) int {
+	return int(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
 }
 
-func decodetypeStructFieldArrayOff(s *Symbol, i int) int {
-	off := commonsize() + 4*SysArch.PtrSize
-	if decodetypeHasUncommon(s) {
+func decodetypeStructFieldArrayOff(arch *sys.Arch, s *sym.Symbol, i int) int {
+	off := commonsize(arch) + 4*arch.PtrSize
+	if decodetypeHasUncommon(arch, s) {
 		off += uncommonSize()
 	}
-	off += i * structfieldSize()
+	off += i * structfieldSize(arch)
 	return off
 }
 
 // decodetypeStr returns the contents of an rtype's str field (a nameOff).
-func decodetypeStr(s *Symbol) string {
-	str := decodetypeName(s, 4*SysArch.PtrSize+8)
-	if s.P[2*SysArch.PtrSize+4]&tflagExtraStar != 0 {
+func decodetypeStr(arch *sys.Arch, s *sym.Symbol) string {
+	str := decodetypeName(s, 4*arch.PtrSize+8)
+	if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
 		return str[1:]
 	}
 	return str
 }
 
 // decodetypeName decodes the name from a reflect.name.
-func decodetypeName(s *Symbol, off int) string {
+func decodetypeName(s *sym.Symbol, off int) string {
 	r := decodeReloc(s, int32(off))
 	if r == nil {
 		return ""
@@ -243,28 +244,28 @@
 	return string(data[3 : 3+namelen])
 }
 
-func decodetypeStructFieldName(s *Symbol, i int) string {
-	off := decodetypeStructFieldArrayOff(s, i)
+func decodetypeStructFieldName(arch *sys.Arch, s *sym.Symbol, i int) string {
+	off := decodetypeStructFieldArrayOff(arch, s, i)
 	return decodetypeName(s, off)
 }
 
-func decodetypeStructFieldType(s *Symbol, i int) *Symbol {
-	off := decodetypeStructFieldArrayOff(s, i)
-	return decodeRelocSym(s, int32(off+SysArch.PtrSize))
+func decodetypeStructFieldType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
+	off := decodetypeStructFieldArrayOff(arch, s, i)
+	return decodeRelocSym(s, int32(off+arch.PtrSize))
 }
 
-func decodetypeStructFieldOffs(arch *sys.Arch, s *Symbol, i int) int64 {
+func decodetypeStructFieldOffs(arch *sys.Arch, s *sym.Symbol, i int) int64 {
 	return decodetypeStructFieldOffsAnon(arch, s, i) >> 1
 }
 
-func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *Symbol, i int) int64 {
-	off := decodetypeStructFieldArrayOff(s, i)
-	return int64(decodeInuxi(arch, s.P[off+2*SysArch.PtrSize:], SysArch.PtrSize))
+func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *sym.Symbol, i int) int64 {
+	off := decodetypeStructFieldArrayOff(arch, s, i)
+	return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
 }
 
 // InterfaceType.methods.length
-func decodetypeIfaceMethodCount(arch *sys.Arch, s *Symbol) int64 {
-	return int64(decodeInuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
+func decodetypeIfaceMethodCount(arch *sys.Arch, s *sym.Symbol) int64 {
+	return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
 }
 
 // methodsig is a fully qualified typed method signature, like
@@ -290,7 +291,7 @@
 // the function type.
 //
 // Conveniently this is the layout of both runtime.method and runtime.imethod.
-func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsig {
+func decodeMethodSig(arch *sys.Arch, s *sym.Symbol, off, size, count int) []methodsig {
 	var buf bytes.Buffer
 	var methods []methodsig
 	for i := 0; i < count; i++ {
@@ -303,7 +304,7 @@
 			if i > 0 {
 				buf.WriteString(", ")
 			}
-			buf.WriteString(decodetypeFuncInType(mtypSym, i).Name)
+			buf.WriteString(decodetypeFuncInType(arch, mtypSym, i).Name)
 		}
 		buf.WriteString(") (")
 		outCount := decodetypeFuncOutCount(arch, mtypSym)
@@ -322,11 +323,11 @@
 	return methods
 }
 
-func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig {
-	if decodetypeKind(s)&kindMask != kindInterface {
+func decodeIfaceMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
+	if decodetypeKind(arch, s)&kindMask != kindInterface {
 		panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
 	}
-	r := decodeReloc(s, int32(commonsize()+SysArch.PtrSize))
+	r := decodeReloc(s, int32(commonsize(arch)+arch.PtrSize))
 	if r == nil {
 		return nil
 	}
@@ -339,28 +340,28 @@
 	return decodeMethodSig(arch, s, off, sizeofIMethod, numMethods)
 }
 
-func decodetypeMethods(arch *sys.Arch, s *Symbol) []methodsig {
-	if !decodetypeHasUncommon(s) {
+func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
+	if !decodetypeHasUncommon(arch, s) {
 		panic(fmt.Sprintf("no methods on %q", s.Name))
 	}
-	off := commonsize() // reflect.rtype
-	switch decodetypeKind(s) & kindMask {
+	off := commonsize(arch) // reflect.rtype
+	switch decodetypeKind(arch, s) & kindMask {
 	case kindStruct: // reflect.structType
-		off += 4 * SysArch.PtrSize
+		off += 4 * arch.PtrSize
 	case kindPtr: // reflect.ptrType
-		off += SysArch.PtrSize
+		off += arch.PtrSize
 	case kindFunc: // reflect.funcType
-		off += SysArch.PtrSize // 4 bytes, pointer aligned
+		off += arch.PtrSize // 4 bytes, pointer aligned
 	case kindSlice: // reflect.sliceType
-		off += SysArch.PtrSize
+		off += arch.PtrSize
 	case kindArray: // reflect.arrayType
-		off += 3 * SysArch.PtrSize
+		off += 3 * arch.PtrSize
 	case kindChan: // reflect.chanType
-		off += 2 * SysArch.PtrSize
+		off += 2 * arch.PtrSize
 	case kindMap: // reflect.mapType
-		off += 4*SysArch.PtrSize + 8
+		off += 4*arch.PtrSize + 8
 	case kindInterface: // reflect.interfaceType
-		off += 3 * SysArch.PtrSize
+		off += 3 * arch.PtrSize
 	default:
 		// just Sizeof(rtype)
 	}
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index ba8ace5..4642bdb 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -16,9 +16,10 @@
 import (
 	"cmd/internal/dwarf"
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"fmt"
 	"log"
-	"os"
 	"strings"
 )
 
@@ -27,66 +28,81 @@
 }
 
 func (c dwctxt) PtrSize() int {
-	return SysArch.PtrSize
+	return c.linkctxt.Arch.PtrSize
 }
 func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
-	ls := s.(*Symbol)
-	adduintxx(c.linkctxt, ls, uint64(i), size)
+	ls := s.(*sym.Symbol)
+	ls.AddUintXX(c.linkctxt.Arch, uint64(i), size)
 }
 func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
-	ls := s.(*Symbol)
-	Addbytes(ls, b)
+	ls := s.(*sym.Symbol)
+	ls.AddBytes(b)
 }
 func (c dwctxt) AddString(s dwarf.Sym, v string) {
-	Addstring(s.(*Symbol), v)
-}
-func (c dwctxt) SymValue(s dwarf.Sym) int64 {
-	return s.(*Symbol).Value
+	Addstring(s.(*sym.Symbol), v)
 }
 
 func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
 	if value != 0 {
-		value -= (data.(*Symbol)).Value
+		value -= (data.(*sym.Symbol)).Value
 	}
-	Addaddrplus(c.linkctxt, s.(*Symbol), data.(*Symbol), value)
+	s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
+}
+
+func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
+	if value != 0 {
+		value -= (data.(*sym.Symbol)).Value
+	}
+	s.(*sym.Symbol).AddCURelativeAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
 }
 
 func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
-	ls := s.(*Symbol)
+	ls := s.(*sym.Symbol)
 	switch size {
 	default:
 		Errorf(ls, "invalid size %d in adddwarfref\n", size)
 		fallthrough
-	case SysArch.PtrSize:
-		Addaddr(c.linkctxt, ls, t.(*Symbol))
+	case c.linkctxt.Arch.PtrSize:
+		ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol))
 	case 4:
-		addaddrplus4(c.linkctxt, ls, t.(*Symbol), 0)
+		ls.AddAddrPlus4(t.(*sym.Symbol), 0)
 	}
 	r := &ls.R[len(ls.R)-1]
-	r.Type = objabi.R_DWARFREF
+	r.Type = objabi.R_DWARFSECREF
 	r.Add = ofs
 }
 
-/*
- * Offsets and sizes of the debug_* sections in the cout file.
- */
-var abbrevsym *Symbol
-var arangessec *Symbol
-var framesec *Symbol
-var infosec *Symbol
-var linesec *Symbol
-var rangesec *Symbol
+func (c dwctxt) Logf(format string, args ...interface{}) {
+	c.linkctxt.Logf(format, args...)
+}
+
+// At the moment these interfaces are only used in the compiler.
+
+func (c dwctxt) AddFileRef(s dwarf.Sym, f interface{}) {
+	panic("should be used only in the compiler")
+}
+
+func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
+	panic("should be used only in the compiler")
+}
+
+func (c dwctxt) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
+	panic("should be used only in the compiler")
+}
+
+func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
+	panic("should be used only in the compiler")
+}
 
 var gdbscript string
 
-var dwarfp []*Symbol
+var dwarfp []*sym.Symbol
 
-func writeabbrev(ctxt *Link, syms []*Symbol) []*Symbol {
+func writeabbrev(ctxt *Link) *sym.Symbol {
 	s := ctxt.Syms.Lookup(".debug_abbrev", 0)
-	s.Type = SDWARFSECT
-	abbrevsym = s
-	Addbytes(s, dwarf.GetAbbrev())
-	return append(syms, s)
+	s.Type = sym.SDWARFSECT
+	s.AddBytes(dwarf.GetAbbrev())
+	return s
 }
 
 /*
@@ -134,8 +150,10 @@
 	return nil
 }
 
-// Every DIE has at least a AT_name attribute (but it will only be
-// written out if it is listed in the abbrev).
+// Every DIE manufactured by the linker has at least an AT_name
+// attribute (but it will only be written out if it is listed in the abbrev).
+// The compiler does create nameless DWARF DIEs (ex: concrete subprogram
+// instance).
 func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
 	die := new(dwarf.DWDie)
 	die.Abbrev = abbrev
@@ -146,10 +164,14 @@
 
 	if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) {
 		if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
-			sym := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
-			sym.Attr |= AttrNotInSymbolTable
-			sym.Type = SDWARFINFO
-			die.Sym = sym
+			if abbrev == dwarf.DW_ABRV_COMPUNIT {
+				// Avoid collisions with "real" symbol names.
+				name = ".pkg." + name
+			}
+			s := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
+			s.Attr |= sym.AttrNotInSymbolTable
+			s.Type = sym.SDWARFINFO
+			die.Sym = s
 		}
 	}
 
@@ -172,7 +194,7 @@
 	return die
 }
 
-func walksymtypedef(ctxt *Link, s *Symbol) *Symbol {
+func walksymtypedef(ctxt *Link, s *sym.Symbol) *sym.Symbol {
 	if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil {
 		return t
 	}
@@ -197,18 +219,18 @@
 // Used to avoid string allocation when looking up dwarf symbols
 var prefixBuf = []byte(dwarf.InfoPrefix)
 
-func find(ctxt *Link, name string) *Symbol {
+func find(ctxt *Link, name string) *sym.Symbol {
 	n := append(prefixBuf, name...)
 	// The string allocation below is optimized away because it is only used in a map lookup.
 	s := ctxt.Syms.ROLookup(string(n), 0)
 	prefixBuf = n[:len(dwarf.InfoPrefix)]
-	if s != nil && s.Type == SDWARFINFO {
+	if s != nil && s.Type == sym.SDWARFINFO {
 		return s
 	}
 	return nil
 }
 
-func mustFind(ctxt *Link, name string) *Symbol {
+func mustFind(ctxt *Link, name string) *sym.Symbol {
 	r := find(ctxt, name)
 	if r == nil {
 		Exitf("dwarf find: cannot find %s", name)
@@ -216,46 +238,46 @@
 	return r
 }
 
-func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 {
+func adddwarfref(ctxt *Link, s *sym.Symbol, t *sym.Symbol, size int) int64 {
 	var result int64
 	switch size {
 	default:
 		Errorf(s, "invalid size %d in adddwarfref\n", size)
 		fallthrough
-	case SysArch.PtrSize:
-		result = Addaddr(ctxt, s, t)
+	case ctxt.Arch.PtrSize:
+		result = s.AddAddr(ctxt.Arch, t)
 	case 4:
-		result = addaddrplus4(ctxt, s, t, 0)
+		result = s.AddAddrPlus4(t, 0)
 	}
 	r := &s.R[len(s.R)-1]
-	r.Type = objabi.R_DWARFREF
+	r.Type = objabi.R_DWARFSECREF
 	return result
 }
 
-func newrefattr(die *dwarf.DWDie, attr uint16, ref *Symbol) *dwarf.DWAttr {
+func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
 	if ref == nil {
 		return nil
 	}
 	return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
 }
 
-func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
 	for ; die != nil; die = die.Link {
 		syms = putdie(linkctxt, ctxt, syms, die)
 	}
-	Adduint8(linkctxt, syms[len(syms)-1], 0)
+	syms[len(syms)-1].AddUint8(0)
 
 	return syms
 }
 
-func dtolsym(s dwarf.Sym) *Symbol {
+func dtolsym(s dwarf.Sym) *sym.Symbol {
 	if s == nil {
 		return nil
 	}
-	return s.(*Symbol)
+	return s.(*sym.Symbol)
 }
 
-func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
 	s := dtolsym(die.Sym)
 	if s == nil {
 		s = syms[len(syms)-1]
@@ -263,7 +285,7 @@
 		if s.Attr.OnList() {
 			log.Fatalf("symbol %s listed multiple times", s.Name)
 		}
-		s.Attr |= AttrOnList
+		s.Attr |= sym.AttrOnList
 		syms = append(syms, s)
 	}
 	dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
@@ -278,7 +300,7 @@
 	curr := *list
 	var prev *dwarf.DWDie
 	for curr != nil {
-		var next *dwarf.DWDie = curr.Link
+		next := curr.Link
 		curr.Link = prev
 		prev = curr
 		curr = next
@@ -297,21 +319,18 @@
 }
 
 func newmemberoffsetattr(die *dwarf.DWDie, offs int32) {
-	var block [20]byte
-	b := append(block[:0], dwarf.DW_OP_plus_uconst)
-	b = dwarf.AppendUleb128(b, uint64(offs))
-	newattr(die, dwarf.DW_AT_data_member_location, dwarf.DW_CLS_BLOCK, int64(len(b)), b)
+	newattr(die, dwarf.DW_AT_data_member_location, dwarf.DW_CLS_CONSTANT, int64(offs), nil)
 }
 
 // GDB doesn't like FORM_addr for AT_location, so emit a
 // location expression that evals to a const.
-func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *Symbol) {
+func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *sym.Symbol) {
 	newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym)
 	// below
 }
 
 // Lookup predefined types
-func lookupOrDiag(ctxt *Link, n string) *Symbol {
+func lookupOrDiag(ctxt *Link, n string) *sym.Symbol {
 	s := ctxt.Syms.ROLookup(n, 0)
 	if s == nil || s.Size == 0 {
 		Exitf("dwarf: missing type: %s", n)
@@ -338,10 +357,10 @@
 		Errorf(nil, "dwarf: bad def in dotypedef")
 	}
 
-	sym := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
-	sym.Attr |= AttrNotInSymbolTable
-	sym.Type = SDWARFINFO
-	def.Sym = sym
+	s := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
+	s.Attr |= sym.AttrNotInSymbolTable
+	s.Type = sym.SDWARFINFO
+	def.Sym = s
 
 	// The typedef entry must be created after the def,
 	// so that future lookups will find the typedef instead
@@ -349,11 +368,11 @@
 	// circular definition loops, so that gdb can understand them.
 	die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
 
-	newrefattr(die, dwarf.DW_AT_type, sym)
+	newrefattr(die, dwarf.DW_AT_type, s)
 }
 
 // Define gotype, for composite ones recurse into constituents.
-func defgotype(ctxt *Link, gotype *Symbol) *Symbol {
+func defgotype(ctxt *Link, gotype *sym.Symbol) *sym.Symbol {
 	if gotype == nil {
 		return mustFind(ctxt, "<unspecified>")
 	}
@@ -371,12 +390,12 @@
 		return sdie
 	}
 
-	return newtype(ctxt, gotype).Sym.(*Symbol)
+	return newtype(ctxt, gotype).Sym.(*sym.Symbol)
 }
 
-func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
+func newtype(ctxt *Link, gotype *sym.Symbol) *dwarf.DWDie {
 	name := gotype.Name[5:] // could also decode from Type.string
-	kind := decodetypeKind(gotype)
+	kind := decodetypeKind(ctxt.Arch, gotype)
 	bytesize := decodetypeSize(ctxt.Arch, gotype)
 
 	var die *dwarf.DWDie
@@ -421,7 +440,7 @@
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0)
 		dotypedef(ctxt, &dwtypes, name, die)
 		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		s := decodetypeArrayElem(gotype)
+		s := decodetypeArrayElem(ctxt.Arch, gotype)
 		newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
 		fld := newdie(ctxt, die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0)
 
@@ -433,7 +452,7 @@
 	case objabi.KindChan:
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0)
 		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		s := decodetypeChanElem(gotype)
+		s := decodetypeChanElem(ctxt.Arch, gotype)
 		newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
 		// Save elem type for synthesizechantypes. We could synthesize here
 		// but that would change the order of DIEs we output.
@@ -441,13 +460,14 @@
 
 	case objabi.KindFunc:
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_FUNCTYPE, name, 0)
+		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
 		dotypedef(ctxt, &dwtypes, name, die)
 		newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void"))
 		nfields := decodetypeFuncInCount(ctxt.Arch, gotype)
 		var fld *dwarf.DWDie
-		var s *Symbol
+		var s *sym.Symbol
 		for i := 0; i < nfields; i++ {
-			s = decodetypeFuncInType(gotype, i)
+			s = decodetypeFuncInType(ctxt.Arch, gotype, i)
 			fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
 			newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s))
 		}
@@ -467,7 +487,7 @@
 		dotypedef(ctxt, &dwtypes, name, die)
 		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
 		nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype))
-		var s *Symbol
+		var s *sym.Symbol
 		if nfields == 0 {
 			s = lookupOrDiag(ctxt, "type.runtime.eface")
 		} else {
@@ -477,9 +497,9 @@
 
 	case objabi.KindMap:
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0)
-		s := decodetypeMapKey(gotype)
+		s := decodetypeMapKey(ctxt.Arch, gotype)
 		newrefattr(die, dwarf.DW_AT_go_key, defgotype(ctxt, s))
-		s = decodetypeMapValue(gotype)
+		s = decodetypeMapValue(ctxt.Arch, gotype)
 		newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
 		// Save gotype for use in synthesizemaptypes. We could synthesize here,
 		// but that would change the order of the DIEs.
@@ -488,14 +508,14 @@
 	case objabi.KindPtr:
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0)
 		dotypedef(ctxt, &dwtypes, name, die)
-		s := decodetypePtrElem(gotype)
+		s := decodetypePtrElem(ctxt.Arch, gotype)
 		newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
 
 	case objabi.KindSlice:
 		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0)
 		dotypedef(ctxt, &dwtypes, name, die)
 		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		s := decodetypeArrayElem(gotype)
+		s := decodetypeArrayElem(ctxt.Arch, gotype)
 		elem := defgotype(ctxt, s)
 		newrefattr(die, dwarf.DW_AT_go_elem, elem)
 
@@ -509,8 +529,8 @@
 		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
 		nfields := decodetypeStructFieldCount(ctxt.Arch, gotype)
 		for i := 0; i < nfields; i++ {
-			f := decodetypeStructFieldName(gotype, i)
-			s := decodetypeStructFieldType(gotype, i)
+			f := decodetypeStructFieldName(ctxt.Arch, gotype, i)
+			s := decodetypeStructFieldType(ctxt.Arch, gotype, i)
 			if f == "" {
 				f = s.Name[5:] // skip "type."
 			}
@@ -541,12 +561,12 @@
 	return die
 }
 
-func nameFromDIESym(dwtype *Symbol) string {
+func nameFromDIESym(dwtype *sym.Symbol) string {
 	return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def")
 }
 
 // Find or construct *T given T.
-func defptrto(ctxt *Link, dwtype *Symbol) *Symbol {
+func defptrto(ctxt *Link, dwtype *sym.Symbol) *sym.Symbol {
 	ptrname := "*" + nameFromDIESym(dwtype)
 	die := find(ctxt, ptrname)
 	if die == nil {
@@ -582,7 +602,7 @@
 
 // Search children (assumed to have TAG_member) for the one named
 // field and set its AT_type to dwtype
-func substitutetype(structdie *dwarf.DWDie, field string, dwtype *Symbol) {
+func substitutetype(structdie *dwarf.DWDie, field string, dwtype *sym.Symbol) {
 	child := findchild(structdie, field)
 	if child == nil {
 		Exitf("dwarf substitutetype: %s does not have member %s",
@@ -632,7 +652,7 @@
 			continue
 		}
 		copychildren(ctxt, die, prototype)
-		elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*Symbol)
+		elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*sym.Symbol)
 		substitutetype(die, "array", defptrto(ctxt, elem))
 	}
 }
@@ -656,11 +676,11 @@
 	BucketSize = 8
 )
 
-func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *Symbol {
+func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *sym.Symbol {
 	name := mkinternaltypename(typename, keyname, valname)
 	symname := dwarf.InfoPrefix + name
 	s := ctxt.Syms.ROLookup(symname, 0)
-	if s != nil && s.Type == SDWARFINFO {
+	if s != nil && s.Type == sym.SDWARFINFO {
 		return s
 	}
 	die := newdie(ctxt, &dwtypes, abbrev, name, 0)
@@ -680,20 +700,20 @@
 		if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
 			continue
 		}
-		gotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
-		keytype := decodetypeMapKey(gotype)
-		valtype := decodetypeMapValue(gotype)
+		gotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
+		keytype := decodetypeMapKey(ctxt.Arch, gotype)
+		valtype := decodetypeMapValue(ctxt.Arch, gotype)
 		keysize, valsize := decodetypeSize(ctxt.Arch, keytype), decodetypeSize(ctxt.Arch, valtype)
 		keytype, valtype = walksymtypedef(ctxt, defgotype(ctxt, keytype)), walksymtypedef(ctxt, defgotype(ctxt, valtype))
 
 		// compute size info like hashmap.c does.
 		indirectKey, indirectVal := false, false
 		if keysize > MaxKeySize {
-			keysize = int64(SysArch.PtrSize)
+			keysize = int64(ctxt.Arch.PtrSize)
 			indirectKey = true
 		}
 		if valsize > MaxValSize {
-			valsize = int64(SysArch.PtrSize)
+			valsize = int64(ctxt.Arch.PtrSize)
 			indirectVal = true
 		}
 
@@ -740,13 +760,13 @@
 			fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
 			newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, dtolsym(dwhb.Sym)))
 			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
-			if SysArch.RegSize > SysArch.PtrSize {
+			if ctxt.Arch.RegSize > ctxt.Arch.PtrSize {
 				fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
 				newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
-				newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize))
+				newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(ctxt.Arch.PtrSize))
 			}
 
-			newattr(dwhb, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(SysArch.RegSize), 0)
+			newattr(dwhb, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(ctxt.Arch.RegSize), 0)
 		})
 
 		// Construct hash<K,V>
@@ -776,21 +796,15 @@
 		if die.Abbrev != dwarf.DW_ABRV_CHANTYPE {
 			continue
 		}
-		elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
-		elemsize := decodetypeSize(ctxt.Arch, elemgotype)
+		elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
 		elemname := elemgotype.Name[5:]
 		elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
 
 		// sudog<T>
 		dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
 			copychildren(ctxt, dws, sudog)
-			substitutetype(dws, "elem", elemtype)
-			if elemsize > 8 {
-				elemsize -= 8
-			} else {
-				elemsize = 0
-			}
-			newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize)+elemsize, nil)
+			substitutetype(dws, "elem", defptrto(ctxt, elemtype))
+			newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil)
 		})
 
 		// waitq<T>
@@ -815,35 +829,35 @@
 }
 
 // For use with pass.c::genasmsym
-func defdwsymb(ctxt *Link, sym *Symbol, s string, t SymbolType, v int64, gotype *Symbol) {
-	if strings.HasPrefix(s, "go.string.") {
+func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, gotype *sym.Symbol) {
+	if strings.HasPrefix(str, "go.string.") {
 		return
 	}
-	if strings.HasPrefix(s, "runtime.gcbits.") {
+	if strings.HasPrefix(str, "runtime.gcbits.") {
 		return
 	}
 
-	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
-		defgotype(ctxt, sym)
+	if strings.HasPrefix(str, "type.") && str != "type.*" && !strings.HasPrefix(str, "type..") {
+		defgotype(ctxt, s)
 		return
 	}
 
 	var dv *dwarf.DWDie
 
-	var dt *Symbol
+	var dt *sym.Symbol
 	switch t {
 	default:
 		return
 
 	case DataSym, BSSSym:
-		dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, int(sym.Version))
-		newabslocexprattr(dv, v, sym)
-		if sym.Version == 0 {
+		dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, str, int(s.Version))
+		newabslocexprattr(dv, v, s)
+		if s.Version == 0 {
 			newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
 		}
 		fallthrough
 
-	case AutoSym, ParamSym:
+	case AutoSym, ParamSym, DeletedAutoSym:
 		dt = defgotype(ctxt, gotype)
 	}
 
@@ -852,6 +866,53 @@
 	}
 }
 
+// compilationUnit is per-compilation unit (equivalently, per-package)
+// debug-related data.
+type compilationUnit struct {
+	lib       *sym.Library
+	consts    *sym.Symbol   // Package constants DIEs
+	pcs       []dwarf.Range // PC ranges, relative to textp[0]
+	dwinfo    *dwarf.DWDie  // CU root DIE
+	funcDIEs  []*sym.Symbol // Function DIE subtrees
+	absFnDIEs []*sym.Symbol // Abstract function DIE subtrees
+}
+
+// getCompilationUnits divides the symbols in ctxt.Textp by package.
+func getCompilationUnits(ctxt *Link) []*compilationUnit {
+	units := []*compilationUnit{}
+	index := make(map[*sym.Library]*compilationUnit)
+	var prevUnit *compilationUnit
+	for _, s := range ctxt.Textp {
+		if s.FuncInfo == nil {
+			continue
+		}
+		unit := index[s.Lib]
+		if unit == nil {
+			unit = &compilationUnit{lib: s.Lib}
+			if s := ctxt.Syms.ROLookup(dwarf.ConstInfoPrefix+s.Lib.Pkg, 0); s != nil {
+				importInfoSymbol(ctxt, s)
+				unit.consts = s
+			}
+			units = append(units, unit)
+			index[s.Lib] = unit
+		}
+
+		// Update PC ranges.
+		//
+		// We don't simply compare the end of the previous
+		// symbol with the start of the next because there's
+		// often a little padding between them. Instead, we
+		// only create boundaries between symbols from
+		// different units.
+		if prevUnit != unit {
+			unit.pcs = append(unit.pcs, dwarf.Range{Start: s.Value - unit.lib.Textp[0].Value})
+			prevUnit = unit
+		}
+		unit.pcs[len(unit.pcs)-1].End = s.Value - unit.lib.Textp[0].Value + s.Size
+	}
+	return units
+}
+
 func movetomodule(parent *dwarf.DWDie) {
 	die := dwroot.Child.Child
 	if die == nil {
@@ -864,15 +925,18 @@
 	die.Link = parent.Child
 }
 
-// If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
-func finddebugruntimepath(s *Symbol) {
+// If the pcln table contains runtime/proc.go, use that to set gdbscript path.
+func finddebugruntimepath(s *sym.Symbol) {
 	if gdbscript != "" {
 		return
 	}
 
 	for i := range s.FuncInfo.File {
 		f := s.FuncInfo.File[i]
-		if i := strings.Index(f.Name, "runtime/debug.go"); i >= 0 {
+		// We can't use something that may be dead-code
+		// eliminated from a binary here. proc.go contains
+		// main and the scheduler, so it's not going anywhere.
+		if i := strings.Index(f.Name, "runtime/proc.go"); i >= 0 {
 			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
 			break
 		}
@@ -890,7 +954,7 @@
 	OPCODE_BASE = 10
 )
 
-func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, deltaPC uint64, deltaLC int64) {
+func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *sym.Symbol, deltaPC uint64, deltaLC int64) {
 	// Choose a special opcode that minimizes the number of bytes needed to
 	// encode the remaining PC delta and LC delta.
 	var opcode int64
@@ -960,24 +1024,24 @@
 			if opcode < OPCODE_BASE {
 				panic(fmt.Sprintf("produced invalid special opcode %d", opcode))
 			}
-			Adduint8(linkctxt, s, dwarf.DW_LNS_const_add_pc)
+			s.AddUint8(dwarf.DW_LNS_const_add_pc)
 		} else if (1<<14) <= deltaPC && deltaPC < (1<<16) {
-			Adduint8(linkctxt, s, dwarf.DW_LNS_fixed_advance_pc)
-			Adduint16(linkctxt, s, uint16(deltaPC))
+			s.AddUint8(dwarf.DW_LNS_fixed_advance_pc)
+			s.AddUint16(linkctxt.Arch, uint16(deltaPC))
 		} else {
-			Adduint8(linkctxt, s, dwarf.DW_LNS_advance_pc)
+			s.AddUint8(dwarf.DW_LNS_advance_pc)
 			dwarf.Uleb128put(ctxt, s, int64(deltaPC))
 		}
 	}
 
 	// Encode deltaLC.
 	if deltaLC != 0 {
-		Adduint8(linkctxt, s, dwarf.DW_LNS_advance_line)
+		s.AddUint8(dwarf.DW_LNS_advance_line)
 		dwarf.Sleb128put(ctxt, s, deltaLC)
 	}
 
 	// Output the special opcode.
-	Adduint8(linkctxt, s, uint8(opcode))
+	s.AddUint8(uint8(opcode))
 }
 
 /*
@@ -985,127 +1049,198 @@
  */
 
 func getCompilationDir() string {
-	if dir, err := os.Getwd(); err == nil {
-		return dir
-	}
-	return "/"
+	// OSX requires this be set to something, but it's not easy to choose
+	// a value. Linking takes place in a temporary directory, so there's
+	// no point including it here. Paths in the file table are usually
+	// absolute, in which case debuggers will ignore this value. -trimpath
+	// produces relative paths, but we don't know where they start, so
+	// all we can do here is try not to make things worse.
+	return "."
 }
 
-func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
-	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-	if linesec == nil {
-		linesec = ctxt.Syms.Lookup(".debug_line", 0)
+func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
+	dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
+	dsym.Type = sym.SDWARFINFO
+	for _, r := range dsym.R {
+		if r.Type == objabi.R_DWARFSECREF && r.Sym.Size == 0 {
+			if ctxt.BuildMode == BuildModeShared {
+				// These type symbols may not be present in BuildModeShared. Skip.
+				continue
+			}
+			n := nameFromDIESym(r.Sym)
+			defgotype(ctxt, ctxt.Syms.Lookup("type."+n, 0))
+		}
 	}
-	linesec.Type = SDWARFSECT
-	linesec.R = linesec.R[:0]
+}
 
-	ls := linesec
-	syms = append(syms, ls)
-	var funcs []*Symbol
+// For the specified function, collect symbols corresponding to any
+// "abstract" subprogram DIEs referenced. The first case of interest
+// is a concrete subprogram DIE, which will refer to its corresponding
+// abstract subprogram DIE, and then there can be references from a
+// non-abstract subprogram DIE to the abstract subprogram DIEs for any
+// functions inlined into this one.
+//
+// A given abstract subprogram DIE can be referenced in numerous
+// places (even within the same DIE), so it is important to make sure
+// it gets imported and added to the absfuncs lists only once.
+
+func collectAbstractFunctions(ctxt *Link, fn *sym.Symbol, dsym *sym.Symbol, absfuncs []*sym.Symbol) []*sym.Symbol {
+
+	var newabsfns []*sym.Symbol
+
+	// Walk the relocations on the primary subprogram DIE and look for
+	// references to abstract funcs.
+	for _, reloc := range dsym.R {
+		candsym := reloc.Sym
+		if reloc.Type != objabi.R_DWARFSECREF {
+			continue
+		}
+		if !strings.HasPrefix(candsym.Name, dwarf.InfoPrefix) {
+			continue
+		}
+		if !strings.HasSuffix(candsym.Name, dwarf.AbstractFuncSuffix) {
+			continue
+		}
+		if candsym.Attr.OnList() {
+			continue
+		}
+		candsym.Attr |= sym.AttrOnList
+		newabsfns = append(newabsfns, candsym)
+	}
+
+	// Import any new symbols that have turned up.
+	for _, absdsym := range newabsfns {
+		importInfoSymbol(ctxt, absdsym)
+		absfuncs = append(absfuncs, absdsym)
+	}
+
+	return absfuncs
+}
+
+func writelines(ctxt *Link, lib *sym.Library, textp []*sym.Symbol, ls *sym.Symbol) (dwinfo *dwarf.DWDie, funcs []*sym.Symbol, absfuncs []*sym.Symbol) {
+
+	var dwarfctxt dwarf.Context = dwctxt{ctxt}
 
 	unitstart := int64(-1)
 	headerstart := int64(-1)
 	headerend := int64(-1)
-	epc := int64(0)
-	var epcs *Symbol
-	var dwinfo *dwarf.DWDie
 
 	lang := dwarf.DW_LANG_Go
 
-	s := ctxt.Textp[0]
-	if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin {
-		s = ctxt.Textp[1] // skip runtime.text
-	}
-
-	dwinfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, "go", 0)
+	dwinfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, lib.Pkg, 0)
 	newattr(dwinfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(lang), 0)
-	newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, linesec)
-	newattr(dwinfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, s.Value, s)
+	newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, ls.Size, ls)
 	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
 	compDir := getCompilationDir()
+	// TODO: Make this be the actual compilation directory, not
+	// the linker directory. If we move CU construction into the
+	// compiler, this should happen naturally.
 	newattr(dwinfo, dwarf.DW_AT_comp_dir, dwarf.DW_CLS_STRING, int64(len(compDir)), compDir)
+	producerExtra := ctxt.Syms.Lookup(dwarf.CUInfoPrefix+"producer."+lib.Pkg, 0)
 	producer := "Go cmd/compile " + objabi.Version
+	if len(producerExtra.P) > 0 {
+		// We put a semicolon before the flags to clearly
+		// separate them from the version, which can be long
+		// and have lots of weird things in it in development
+		// versions. We promise not to put a semicolon in the
+		// version, so it should be safe for readers to scan
+		// forward to the semicolon.
+		producer += "; " + string(producerExtra.P)
+	}
 	newattr(dwinfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer)
 
 	// Write .debug_line Line Number Program Header (sec 6.2.4)
 	// Fields marked with (*) must be changed for 64-bit dwarf
 	unitLengthOffset := ls.Size
-	Adduint32(ctxt, ls, 0) // unit_length (*), filled in at end.
+	ls.AddUint32(ctxt.Arch, 0) // unit_length (*), filled in at end.
 	unitstart = ls.Size
-	Adduint16(ctxt, ls, 2) // dwarf version (appendix F)
+	ls.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
 	headerLengthOffset := ls.Size
-	Adduint32(ctxt, ls, 0) // header_length (*), filled in at end.
+	ls.AddUint32(ctxt.Arch, 0) // header_length (*), filled in at end.
 	headerstart = ls.Size
 
 	// cpos == unitstart + 4 + 2 + 4
-	Adduint8(ctxt, ls, 1)              // minimum_instruction_length
-	Adduint8(ctxt, ls, 1)              // default_is_stmt
-	Adduint8(ctxt, ls, LINE_BASE&0xFF) // line_base
-	Adduint8(ctxt, ls, LINE_RANGE)     // line_range
-	Adduint8(ctxt, ls, OPCODE_BASE)    // opcode_base
-	Adduint8(ctxt, ls, 0)              // standard_opcode_lengths[1]
-	Adduint8(ctxt, ls, 1)              // standard_opcode_lengths[2]
-	Adduint8(ctxt, ls, 1)              // standard_opcode_lengths[3]
-	Adduint8(ctxt, ls, 1)              // standard_opcode_lengths[4]
-	Adduint8(ctxt, ls, 1)              // standard_opcode_lengths[5]
-	Adduint8(ctxt, ls, 0)              // standard_opcode_lengths[6]
-	Adduint8(ctxt, ls, 0)              // standard_opcode_lengths[7]
-	Adduint8(ctxt, ls, 0)              // standard_opcode_lengths[8]
-	Adduint8(ctxt, ls, 1)              // standard_opcode_lengths[9]
-	Adduint8(ctxt, ls, 0)              // include_directories  (empty)
+	ls.AddUint8(1)                // minimum_instruction_length
+	ls.AddUint8(1)                // default_is_stmt
+	ls.AddUint8(LINE_BASE & 0xFF) // line_base
+	ls.AddUint8(LINE_RANGE)       // line_range
+	ls.AddUint8(OPCODE_BASE)      // opcode_base
+	ls.AddUint8(0)                // standard_opcode_lengths[1]
+	ls.AddUint8(1)                // standard_opcode_lengths[2]
+	ls.AddUint8(1)                // standard_opcode_lengths[3]
+	ls.AddUint8(1)                // standard_opcode_lengths[4]
+	ls.AddUint8(1)                // standard_opcode_lengths[5]
+	ls.AddUint8(0)                // standard_opcode_lengths[6]
+	ls.AddUint8(0)                // standard_opcode_lengths[7]
+	ls.AddUint8(0)                // standard_opcode_lengths[8]
+	ls.AddUint8(1)                // standard_opcode_lengths[9]
+	ls.AddUint8(0)                // include_directories  (empty)
 
-	for _, f := range ctxt.Filesyms {
-		Addstring(ls, f.Name)
-		Adduint8(ctxt, ls, 0)
-		Adduint8(ctxt, ls, 0)
-		Adduint8(ctxt, ls, 0)
+	// Create the file table. fileNums maps from global file
+	// indexes (created by numberfile) to CU-local indexes.
+	fileNums := make(map[int]int)
+	for _, s := range textp {
+		for _, f := range s.FuncInfo.File {
+			if _, ok := fileNums[int(f.Value)]; ok {
+				continue
+			}
+			// File indexes are 1-based.
+			fileNums[int(f.Value)] = len(fileNums) + 1
+			Addstring(ls, f.Name)
+			ls.AddUint8(0)
+			ls.AddUint8(0)
+			ls.AddUint8(0)
+		}
+
+		// Look up the .debug_info sym for the function. We do this
+		// now so that we can walk the sym's relocations to discover
+		// files that aren't mentioned in S.FuncInfo.File (for
+		// example, files mentioned only in an inlined subroutine).
+		dsym := ctxt.Syms.Lookup(dwarf.InfoPrefix+s.Name, int(s.Version))
+		importInfoSymbol(ctxt, dsym)
+		for ri := 0; ri < len(dsym.R); ri++ {
+			r := &dsym.R[ri]
+			if r.Type != objabi.R_DWARFFILEREF {
+				continue
+			}
+			_, ok := fileNums[int(r.Sym.Value)]
+			if !ok {
+				fileNums[int(r.Sym.Value)] = len(fileNums) + 1
+				Addstring(ls, r.Sym.Name)
+				ls.AddUint8(0)
+				ls.AddUint8(0)
+				ls.AddUint8(0)
+			}
+		}
 	}
 
 	// 4 zeros: the string termination + 3 fields.
-	Adduint8(ctxt, ls, 0)
+	ls.AddUint8(0)
 	// terminate file_names.
 	headerend = ls.Size
 
-	Adduint8(ctxt, ls, 0) // start extended opcode
-	dwarf.Uleb128put(dwarfctxt, ls, 1+int64(SysArch.PtrSize))
-	Adduint8(ctxt, ls, dwarf.DW_LNE_set_address)
+	ls.AddUint8(0) // start extended opcode
+	dwarf.Uleb128put(dwarfctxt, ls, 1+int64(ctxt.Arch.PtrSize))
+	ls.AddUint8(dwarf.DW_LNE_set_address)
 
+	s := textp[0]
 	pc := s.Value
 	line := 1
 	file := 1
-	Addaddr(ctxt, ls, s)
+	ls.AddAddr(ctxt.Arch, s)
 
 	var pcfile Pciter
 	var pcline Pciter
-	for _, s := range ctxt.Textp {
-
-		epc = s.Value + s.Size
-		epcs = s
-
+	for _, s := range textp {
 		dsym := ctxt.Syms.Lookup(dwarf.InfoPrefix+s.Name, int(s.Version))
-		dsym.Attr |= AttrNotInSymbolTable | AttrReachable
-		dsym.Type = SDWARFINFO
-		for _, r := range dsym.R {
-			if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
-				if Buildmode == BuildmodeShared {
-					// These type symbols may not be present in BuildmodeShared. Skip.
-					continue
-				}
-				n := nameFromDIESym(r.Sym)
-				defgotype(ctxt, ctxt.Syms.Lookup("type."+n, 0))
-			}
-		}
 		funcs = append(funcs, dsym)
-
-		if s.FuncInfo == nil {
-			continue
-		}
+		absfuncs = collectAbstractFunctions(ctxt, s, dsym, absfuncs)
 
 		finddebugruntimepath(s)
 
 		pciterinit(ctxt, &pcfile, &s.FuncInfo.Pcfile)
 		pciterinit(ctxt, &pcline, &s.FuncInfo.Pcline)
-		epc = pc
+		epc := pc
 		for pcfile.done == 0 && pcline.done == 0 {
 			if epc-s.Value >= int64(pcfile.nextpc) {
 				pciternext(&pcfile)
@@ -1118,8 +1253,12 @@
 			}
 
 			if int32(file) != pcfile.value {
-				Adduint8(ctxt, ls, dwarf.DW_LNS_set_file)
-				dwarf.Uleb128put(dwarfctxt, ls, int64(pcfile.value))
+				ls.AddUint8(dwarf.DW_LNS_set_file)
+				idx, ok := fileNums[int(pcfile.value)]
+				if !ok {
+					Exitf("pcln table file missing from DWARF line table")
+				}
+				dwarf.Uleb128put(dwarfctxt, ls, int64(idx))
 				file = int(pcfile.value)
 			}
 
@@ -1136,16 +1275,63 @@
 		}
 	}
 
-	Adduint8(ctxt, ls, 0) // start extended opcode
+	ls.AddUint8(0) // start extended opcode
 	dwarf.Uleb128put(dwarfctxt, ls, 1)
-	Adduint8(ctxt, ls, dwarf.DW_LNE_end_sequence)
+	ls.AddUint8(dwarf.DW_LNE_end_sequence)
 
-	newattr(dwinfo, dwarf.DW_AT_high_pc, dwarf.DW_CLS_ADDRESS, epc+1, epcs)
+	ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
+	ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
 
-	setuint32(ctxt, ls, unitLengthOffset, uint32(ls.Size-unitstart))
-	setuint32(ctxt, ls, headerLengthOffset, uint32(headerend-headerstart))
+	// Apply any R_DWARFFILEREF relocations, since we now know the
+	// line table file indices for this compilation unit. Note that
+	// this loop visits only subprogram DIEs: if the compiler is
+	// changed to generate DW_AT_decl_file attributes for other
+	// DIE flavors (ex: variables) then those DIEs would need to
+	// be included below.
+	missing := make(map[int]interface{})
+	for fidx := 0; fidx < len(funcs); fidx++ {
+		f := funcs[fidx]
+		for ri := 0; ri < len(f.R); ri++ {
+			r := &f.R[ri]
+			if r.Type != objabi.R_DWARFFILEREF {
+				continue
+			}
+			// Mark relocation as applied (signal to relocsym)
+			r.Done = true
+			idx, ok := fileNums[int(r.Sym.Value)]
+			if ok {
+				if int(int32(idx)) != idx {
+					Errorf(f, "bad R_DWARFFILEREF relocation: file index overflow")
+				}
+				if r.Siz != 4 {
+					Errorf(f, "bad R_DWARFFILEREF relocation: has size %d, expected 4", r.Siz)
+				}
+				if r.Off < 0 || r.Off+4 > int32(len(f.P)) {
+					Errorf(f, "bad R_DWARFFILEREF relocation offset %d + 4 would write past length %d", r.Off, len(s.P))
+					continue
+				}
+				ctxt.Arch.ByteOrder.PutUint32(f.P[r.Off:r.Off+4], uint32(idx))
+			} else {
+				_, found := missing[int(r.Sym.Value)]
+				if !found {
+					Errorf(f, "R_DWARFFILEREF relocation file missing: %v idx %d", r.Sym, r.Sym.Value)
+					missing[int(r.Sym.Value)] = nil
+				}
+			}
+		}
+	}
 
-	return syms, funcs
+	return dwinfo, funcs, absfuncs
+}
+
+// writepcranges generates the DW_AT_ranges table for compilation unit cu.
+func writepcranges(ctxt *Link, cu *dwarf.DWDie, base *sym.Symbol, pcs []dwarf.Range, ranges *sym.Symbol) {
+	var dwarfctxt dwarf.Context = dwctxt{ctxt}
+
+	// Create PC ranges for this CU.
+	newattr(cu, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, ranges.Size, ranges)
+	newattr(cu, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, base.Value, base)
+	dwarf.PutRanges(dwarfctxt, ranges, nil, pcs)
 }
 
 /*
@@ -1156,7 +1342,7 @@
 )
 
 // appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice.
-func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte {
+func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
 	b = append(b, dwarf.DW_CFA_def_cfa_offset_sf)
 	b = dwarf.AppendSleb128(b, cfa/dataAlignmentFactor)
 
@@ -1167,23 +1353,19 @@
 		b = append(b, dwarf.DW_CFA_advance_loc1)
 		b = append(b, uint8(deltapc))
 	case deltapc < 0x10000:
-		b = append(b, dwarf.DW_CFA_advance_loc2)
-		b = Thearch.Append16(b, uint16(deltapc))
+		b = append(b, dwarf.DW_CFA_advance_loc2, 0, 0)
+		arch.ByteOrder.PutUint16(b[len(b)-2:], uint16(deltapc))
 	default:
-		b = append(b, dwarf.DW_CFA_advance_loc4)
-		b = Thearch.Append32(b, uint32(deltapc))
+		b = append(b, dwarf.DW_CFA_advance_loc4, 0, 0, 0, 0)
+		arch.ByteOrder.PutUint32(b[len(b)-4:], uint32(deltapc))
 	}
 	return b
 }
 
-func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
+func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
 	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-	if framesec == nil {
-		framesec = ctxt.Syms.Lookup(".debug_frame", 0)
-	}
-	framesec.Type = SDWARFSECT
-	framesec.R = framesec.R[:0]
-	fs := framesec
+	fs := ctxt.Syms.Lookup(".debug_frame", 0)
+	fs.Type = sym.SDWARFSECT
 	syms = append(syms, fs)
 
 	// Emit the CIE, Section 6.4.1
@@ -1191,31 +1373,31 @@
 	if haslinkregister(ctxt) {
 		cieReserve = 32
 	}
-	Adduint32(ctxt, fs, cieReserve)                            // initial length, must be multiple of thearch.ptrsize
-	Adduint32(ctxt, fs, 0xffffffff)                            // cid.
-	Adduint8(ctxt, fs, 3)                                      // dwarf version (appendix F)
-	Adduint8(ctxt, fs, 0)                                      // augmentation ""
+	fs.AddUint32(ctxt.Arch, cieReserve)                        // initial length, must be multiple of thearch.ptrsize
+	fs.AddUint32(ctxt.Arch, 0xffffffff)                        // cid.
+	fs.AddUint8(3)                                             // dwarf version (appendix F)
+	fs.AddUint8(0)                                             // augmentation ""
 	dwarf.Uleb128put(dwarfctxt, fs, 1)                         // code_alignment_factor
 	dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor)       // all CFI offset calculations include multiplication with this factor
 	dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // return_address_register
 
-	Adduint8(ctxt, fs, dwarf.DW_CFA_def_cfa)                   // Set the current frame address..
+	fs.AddUint8(dwarf.DW_CFA_def_cfa)                          // Set the current frame address..
 	dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
 	if haslinkregister(ctxt) {
 		dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
 
-		Adduint8(ctxt, fs, dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
+		fs.AddUint8(dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
 		dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr))
 
-		Adduint8(ctxt, fs, dwarf.DW_CFA_val_offset)                // The previous value...
+		fs.AddUint8(dwarf.DW_CFA_val_offset)                       // The previous value...
 		dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register...
 		dwarf.Uleb128put(dwarfctxt, fs, int64(0))                  // ...is CFA+0.
 	} else {
-		dwarf.Uleb128put(dwarfctxt, fs, int64(SysArch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
+		dwarf.Uleb128put(dwarfctxt, fs, int64(ctxt.Arch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
 
-		Adduint8(ctxt, fs, dwarf.DW_CFA_offset_extended)                             // The previous value...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr))                   // ...of the return address...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(-SysArch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
+		fs.AddUint8(dwarf.DW_CFA_offset_extended)                                      // The previous value...
+		dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr))                     // ...of the return address...
+		dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
 	}
 
 	// 4 is to exclude the length field.
@@ -1225,7 +1407,7 @@
 		Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
 	}
 
-	Addbytes(fs, zeros[:pad])
+	fs.AddBytes(zeros[:pad])
 
 	var deltaBuf []byte
 	var pcsp Pciter
@@ -1265,12 +1447,12 @@
 					deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value)
 					deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr))
 				}
-				deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
+				deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
 			} else {
-				deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(SysArch.PtrSize)+int64(pcsp.value))
+				deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(ctxt.Arch.PtrSize)+int64(pcsp.value))
 			}
 		}
-		pad := int(Rnd(int64(len(deltaBuf)), int64(SysArch.PtrSize))) - len(deltaBuf)
+		pad := int(Rnd(int64(len(deltaBuf)), int64(ctxt.Arch.PtrSize))) - len(deltaBuf)
 		deltaBuf = append(deltaBuf, zeros[:pad]...)
 
 		// Emit the FDE header, Section 6.4.1.
@@ -1278,42 +1460,28 @@
 		//	4 bytes: Pointer to the CIE above, at offset 0
 		//	ptrsize: initial location
 		//	ptrsize: address range
-		Adduint32(ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself)
-		if Linkmode == LinkExternal {
-			adddwarfref(ctxt, fs, framesec, 4)
+		fs.AddUint32(ctxt.Arch, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself)
+		if ctxt.LinkMode == LinkExternal {
+			adddwarfref(ctxt, fs, fs, 4)
 		} else {
-			Adduint32(ctxt, fs, 0) // CIE offset
+			fs.AddUint32(ctxt.Arch, 0) // CIE offset
 		}
-		Addaddr(ctxt, fs, s)
-		adduintxx(ctxt, fs, uint64(s.Size), SysArch.PtrSize) // address range
-		Addbytes(fs, deltaBuf)
+		fs.AddAddr(ctxt.Arch, s)
+		fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
+		fs.AddBytes(deltaBuf)
 	}
 	return syms
 }
 
-func writeranges(ctxt *Link, syms []*Symbol) []*Symbol {
-	if rangesec == nil {
-		rangesec = ctxt.Syms.Lookup(".debug_ranges", 0)
-	}
-	rangesec.Type = SDWARFSECT
-	rangesec.Attr |= AttrReachable
-	rangesec.R = rangesec.R[:0]
-
+func writeranges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
 	for _, s := range ctxt.Textp {
-		rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
-		rangeSym.Attr |= AttrReachable
-		rangeSym.Type = SDWARFRANGE
-		rangeSym.Value = rangesec.Size
-		rangesec.P = append(rangesec.P, rangeSym.P...)
-		for _, r := range rangeSym.R {
-			r.Off += int32(rangesec.Size)
-			rangesec.R = append(rangesec.R, r)
+		rangeSym := ctxt.Syms.ROLookup(dwarf.RangePrefix+s.Name, int(s.Version))
+		if rangeSym == nil || rangeSym.Size == 0 {
+			continue
 		}
-		rangesec.Size += rangeSym.Size
-	}
-	if rangesec.Size > 0 {
-		// PE does not like empty sections
-		syms = append(syms, rangesec)
+		rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
+		rangeSym.Type = sym.SDWARFRANGE
+		syms = append(syms, rangeSym)
 	}
 	return syms
 }
@@ -1325,43 +1493,43 @@
 	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
 )
 
-func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
-	if infosec == nil {
-		infosec = ctxt.Syms.Lookup(".debug_info", 0)
-	}
-	infosec.R = infosec.R[:0]
-	infosec.Type = SDWARFINFO
-	infosec.Attr |= AttrReachable
+func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevsym *sym.Symbol) []*sym.Symbol {
+	infosec := ctxt.Syms.Lookup(".debug_info", 0)
+	infosec.Type = sym.SDWARFINFO
+	infosec.Attr |= sym.AttrReachable
 	syms = append(syms, infosec)
 
-	if arangessec == nil {
-		arangessec = ctxt.Syms.Lookup(".dwarfaranges", 0)
-	}
-	arangessec.R = arangessec.R[:0]
-
 	var dwarfctxt dwarf.Context = dwctxt{ctxt}
 
+	// Re-index per-package information by its CU die.
+	unitByDIE := make(map[*dwarf.DWDie]*compilationUnit)
+	for _, u := range units {
+		unitByDIE[u.dwinfo] = u
+	}
+
 	for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
 		s := dtolsym(compunit.Sym)
+		u := unitByDIE[compunit]
 
 		// Write .debug_info Compilation Unit Header (sec 7.5.1)
 		// Fields marked with (*) must be changed for 64-bit dwarf
 		// This must match COMPUNITHEADERSIZE above.
-		Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
-		Adduint16(ctxt, s, 4) // dwarf version (appendix F)
+		s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
+		s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
 
 		// debug_abbrev_offset (*)
 		adddwarfref(ctxt, s, abbrevsym, 4)
 
-		Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size
+		s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
 
 		dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
 		dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
 
-		cu := []*Symbol{s}
-		if funcs != nil {
-			cu = append(cu, funcs...)
-			funcs = nil
+		cu := []*sym.Symbol{s}
+		cu = append(cu, u.absFnDIEs...)
+		cu = append(cu, u.funcDIEs...)
+		if u.consts != nil {
+			cu = append(cu, u.consts)
 		}
 		cu = putdies(ctxt, dwarfctxt, cu, compunit.Child)
 		var cusize int64
@@ -1369,7 +1537,9 @@
 			cusize += child.Size
 		}
 		cusize -= 4 // exclude the length field.
-		setuint32(ctxt, s, 0, uint32(cusize))
+		s.SetUint32(ctxt.Arch, 0, uint32(cusize))
+		// Leave a breadcrumb for writepub. This does not
+		// appear in the DWARF output.
 		newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
 		syms = append(syms, cu...)
 	}
@@ -1394,9 +1564,9 @@
 	return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
 }
 
-func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol {
+func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*sym.Symbol) []*sym.Symbol {
 	s := ctxt.Syms.Lookup(sname, 0)
-	s.Type = SDWARFSECT
+	s.Type = sym.SDWARFSECT
 	syms = append(syms, s)
 
 	for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
@@ -1404,10 +1574,10 @@
 		culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
 
 		// Write .debug_pubnames/types	Header (sec 6.1.1)
-		Adduint32(ctxt, s, 0)                          // unit_length (*), will be filled in later.
-		Adduint16(ctxt, s, 2)                          // dwarf version (appendix F)
+		s.AddUint32(ctxt.Arch, 0)                      // unit_length (*), will be filled in later.
+		s.AddUint16(ctxt.Arch, 2)                      // dwarf version (appendix F)
 		adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
-		Adduint32(ctxt, s, culength)                   // debug_info_length
+		s.AddUint32(ctxt.Arch, culength)               // debug_info_length
 
 		for die := compunit.Child; die != nil; die = die.Link {
 			if !ispub(die) {
@@ -1422,62 +1592,16 @@
 			Addstring(s, name)
 		}
 
-		Adduint32(ctxt, s, 0)
+		s.AddUint32(ctxt.Arch, 0)
 
-		setuint32(ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
+		s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
 	}
 
 	return syms
 }
 
-/*
- *  emit .debug_aranges.  _info must have been written before,
- *  because we need die->offs of dwarf.DW_globals.
- */
-func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
-	s := ctxt.Syms.Lookup(".debug_aranges", 0)
-	s.Type = SDWARFSECT
-	// The first tuple is aligned to a multiple of the size of a single tuple
-	// (twice the size of an address)
-	headersize := int(Rnd(4+2+4+1+1, int64(SysArch.PtrSize*2))) // don't count unit_length field itself
-
-	for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
-		b := getattr(compunit, dwarf.DW_AT_low_pc)
-		if b == nil {
-			continue
-		}
-		e := getattr(compunit, dwarf.DW_AT_high_pc)
-		if e == nil {
-			continue
-		}
-
-		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
-		unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4
-		Adduint32(ctxt, s, unitlength) // unit_length (*)
-		Adduint16(ctxt, s, 2)          // dwarf version (appendix F)
-
-		adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4)
-
-		Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size
-		Adduint8(ctxt, s, 0)                      // segment_size
-		padding := headersize - (4 + 2 + 4 + 1 + 1)
-		for i := 0; i < padding; i++ {
-			Adduint8(ctxt, s, 0)
-		}
-
-		Addaddrplus(ctxt, s, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
-		adduintxx(ctxt, s, uint64(e.Value-b.Value), SysArch.PtrSize)
-		adduintxx(ctxt, s, 0, SysArch.PtrSize)
-		adduintxx(ctxt, s, 0, SysArch.PtrSize)
-	}
-	if s.Size > 0 {
-		syms = append(syms, s)
-	}
-	return syms
-}
-
-func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol {
-	if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive {
+func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
+	if ctxt.LinkMode == LinkExternal && ctxt.HeadType == objabi.Hwindows && ctxt.BuildMode == BuildModeCArchive {
 		// gcc on Windows places .debug_gdb_scripts in the wrong location, which
 		// causes the program not to run. See https://golang.org/issue/20183
 		// Non c-archives can avoid this issue via a linker script
@@ -1489,9 +1613,9 @@
 
 	if gdbscript != "" {
 		s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
-		s.Type = SDWARFSECT
+		s.Type = sym.SDWARFSECT
 		syms = append(syms, s)
-		Adduint8(ctxt, s, 1) // magic 1 byte?
+		s.AddUint8(1) // magic 1 byte?
 		Addstring(s, gdbscript)
 	}
 
@@ -1513,18 +1637,18 @@
 	if *FlagW { // disable dwarf
 		return
 	}
-	if *FlagS && Headtype != objabi.Hdarwin {
+	if *FlagS && ctxt.HeadType != objabi.Hdarwin {
 		return
 	}
-	if Headtype == objabi.Hplan9 {
+	if ctxt.HeadType == objabi.Hplan9 {
 		return
 	}
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		switch {
-		case Iself:
-		case Headtype == objabi.Hdarwin:
-		case Headtype == objabi.Hwindows:
+		case ctxt.IsELF:
+		case ctxt.HeadType == objabi.Hdarwin:
+		case ctxt.HeadType == objabi.Hwindows:
 		default:
 			return
 		}
@@ -1545,7 +1669,7 @@
 
 	die := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
 	newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
-	newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0)
+	newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(ctxt.Arch.PtrSize), 0)
 	newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, objabi.KindUintptr, 0)
 
 	// Prototypes needed for type synthesis.
@@ -1577,16 +1701,31 @@
 
 	genasmsym(ctxt, defdwsymb)
 
-	syms := writeabbrev(ctxt, nil)
-	syms, funcs := writelines(ctxt, syms)
-	syms = writeframes(ctxt, syms)
-	syms = writeranges(ctxt, syms)
+	abbrev := writeabbrev(ctxt)
+	syms := []*sym.Symbol{abbrev}
+
+	units := getCompilationUnits(ctxt)
+
+	// Write per-package line and range tables and start their CU DIEs.
+	debugLine := ctxt.Syms.Lookup(".debug_line", 0)
+	debugLine.Type = sym.SDWARFSECT
+	debugRanges := ctxt.Syms.Lookup(".debug_ranges", 0)
+	debugRanges.Type = sym.SDWARFRANGE
+	debugRanges.Attr |= sym.AttrReachable
+	syms = append(syms, debugLine)
+	for _, u := range units {
+		u.dwinfo, u.funcDIEs, u.absFnDIEs = writelines(ctxt, u.lib, u.lib.Textp, debugLine)
+		writepcranges(ctxt, u.dwinfo, u.lib.Textp[0], u.pcs, debugRanges)
+	}
 
 	synthesizestringtypes(ctxt, dwtypes.Child)
 	synthesizeslicetypes(ctxt, dwtypes.Child)
 	synthesizemaptypes(ctxt, dwtypes.Child)
 	synthesizechantypes(ctxt, dwtypes.Child)
 
+	// newdie adds DIEs to the *beginning* of the parent's DIE list.
+	// Now that we're done creating DIEs, reverse the trees so DIEs
+	// appear in the order they were created.
 	reversetree(&dwroot.Child)
 	reversetree(&dwtypes.Child)
 	reversetree(&dwglobals.Child)
@@ -1594,38 +1733,68 @@
 	movetomodule(&dwtypes)
 	movetomodule(&dwglobals)
 
-	// Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
+	// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
 	// (but we need to generate dies before writepub)
-	infosyms := writeinfo(ctxt, nil, funcs)
+	infosyms := writeinfo(ctxt, nil, units, abbrev)
 
+	syms = writeframes(ctxt, syms)
 	syms = writepub(ctxt, ".debug_pubnames", ispubname, syms)
 	syms = writepub(ctxt, ".debug_pubtypes", ispubtype, syms)
-	syms = writearanges(ctxt, syms)
 	syms = writegdbscript(ctxt, syms)
+	// Now we're done writing SDWARFSECT symbols, so we can write
+	// other SDWARF* symbols.
 	syms = append(syms, infosyms...)
+	syms = collectlocs(ctxt, syms, units)
+	syms = append(syms, debugRanges)
+	syms = writeranges(ctxt, syms)
 	dwarfp = syms
 }
 
+func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit) []*sym.Symbol {
+	empty := true
+	for _, u := range units {
+		for _, fn := range u.funcDIEs {
+			for _, reloc := range fn.R {
+				if reloc.Type == objabi.R_DWARFSECREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
+					reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
+					syms = append(syms, reloc.Sym)
+					empty = false
+					// One location list entry per function, but many relocations to it. Don't duplicate.
+					break
+				}
+			}
+		}
+	}
+	// Don't emit .debug_loc if it's empty -- it makes the ARM linker mad.
+	if !empty {
+		locsym := ctxt.Syms.Lookup(".debug_loc", 0)
+		locsym.Type = sym.SDWARFLOC
+		locsym.Attr |= sym.AttrReachable
+		syms = append(syms, locsym)
+	}
+	return syms
+}
+
 /*
  *  Elf.
  */
-func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
+func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
 	if *FlagW { // disable dwarf
 		return
 	}
 
 	Addstring(shstrtab, ".debug_abbrev")
-	Addstring(shstrtab, ".debug_aranges")
 	Addstring(shstrtab, ".debug_frame")
 	Addstring(shstrtab, ".debug_info")
+	Addstring(shstrtab, ".debug_loc")
 	Addstring(shstrtab, ".debug_line")
 	Addstring(shstrtab, ".debug_pubnames")
 	Addstring(shstrtab, ".debug_pubtypes")
 	Addstring(shstrtab, ".debug_gdb_scripts")
 	Addstring(shstrtab, ".debug_ranges")
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		Addstring(shstrtab, elfRelType+".debug_info")
-		Addstring(shstrtab, elfRelType+".debug_aranges")
+		Addstring(shstrtab, elfRelType+".debug_loc")
 		Addstring(shstrtab, elfRelType+".debug_line")
 		Addstring(shstrtab, elfRelType+".debug_frame")
 		Addstring(shstrtab, elfRelType+".debug_pubnames")
@@ -1640,35 +1809,23 @@
 	if *FlagW { // disable dwarf
 		return
 	}
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		return
 	}
-	sym := ctxt.Syms.Lookup(".debug_info", 0)
-	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
-	sym = ctxt.Syms.Lookup(".debug_abbrev", 0)
-	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
-	sym = ctxt.Syms.Lookup(".debug_line", 0)
-	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
-	sym = ctxt.Syms.Lookup(".debug_frame", 0)
-	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
-	sym = ctxt.Syms.Lookup(".debug_ranges", 0)
-	if sym.Sect != nil {
-		putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+	s := ctxt.Syms.Lookup(".debug_info", 0)
+	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+	s = ctxt.Syms.Lookup(".debug_abbrev", 0)
+	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+	s = ctxt.Syms.Lookup(".debug_line", 0)
+	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+	s = ctxt.Syms.Lookup(".debug_frame", 0)
+	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+	s = ctxt.Syms.Lookup(".debug_loc", 0)
+	if s.Sect != nil {
+		putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
 	}
-}
-
-/*
- * Windows PE
- */
-func dwarfaddpeheaders(ctxt *Link) {
-	if *FlagW { // disable dwarf
-		return
-	}
-	for _, sect := range Segdwarf.Sections {
-		h := newPEDWARFSection(ctxt, sect.Name, int64(sect.Length))
-		fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
-		if uint64(h.PointerToRawData) != fileoff {
-			Exitf("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff)
-		}
+	s = ctxt.Syms.Lookup(".debug_ranges", 0)
+	if s.Sect != nil {
+		putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
 	}
 }
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index 4e7413f..391601a 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -7,6 +7,8 @@
 import (
 	objfilepkg "cmd/internal/objfile" // renamed to avoid conflict with objfile function
 	"debug/dwarf"
+	"errors"
+	"fmt"
 	"internal/testenv"
 	"io/ioutil"
 	"os"
@@ -17,6 +19,13 @@
 	"testing"
 )
 
+const (
+	NoOpt        = "-gcflags=-l -N"
+	Opt          = ""
+	OptInl4      = "-gcflags=all=-l=4"
+	OptInl4DwLoc = "-gcflags=all=-l=4 -dwarflocationlists"
+)
+
 func TestRuntimeTypeDIEs(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
@@ -30,7 +39,7 @@
 	}
 	defer os.RemoveAll(dir)
 
-	f := gobuild(t, dir, `package main; func main() { }`)
+	f := gobuild(t, dir, `package main; func main() { }`, NoOpt)
 	defer f.Close()
 
 	dwarf, err := f.DWARF()
@@ -75,7 +84,7 @@
 	return
 }
 
-func gobuild(t *testing.T, dir string, testfile string) *objfilepkg.File {
+func gobuild(t *testing.T, dir string, testfile string, gcflags string) *objfilepkg.File {
 	src := filepath.Join(dir, "test.go")
 	dst := filepath.Join(dir, "out")
 
@@ -83,7 +92,7 @@
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
+	cmd := exec.Command(testenv.GoToolPath(t), "build", gcflags, "-o", dst, src)
 	if b, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("build: %s\n", b)
 		t.Fatalf("build error: %v", err)
@@ -136,7 +145,7 @@
 	}
 	defer os.RemoveAll(dir)
 
-	f := gobuild(t, dir, prog)
+	f := gobuild(t, dir, prog, NoOpt)
 
 	defer f.Close()
 
@@ -192,3 +201,575 @@
 	}
 	return memberEmbedded, nil
 }
+
+func TestSizes(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	// DWARF sizes should never be -1.
+	// See issue #21097
+	const prog = `
+package main
+var x func()
+var y [4]func()
+func main() {
+	x = nil
+	y[0] = nil
+}
+`
+	dir, err := ioutil.TempDir("", "TestSizes")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+	f := gobuild(t, dir, prog, NoOpt)
+	defer f.Close()
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+	rdr := d.Reader()
+	for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
+		if err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+		switch entry.Tag {
+		case dwarf.TagArrayType, dwarf.TagPointerType, dwarf.TagStructType, dwarf.TagBaseType, dwarf.TagSubroutineType, dwarf.TagTypedef:
+		default:
+			continue
+		}
+		typ, err := d.Type(entry.Offset)
+		if err != nil {
+			t.Fatalf("can't read type: %v", err)
+		}
+		if typ.Size() < 0 {
+			t.Errorf("subzero size %s %s %T", typ, entry.Tag, typ)
+		}
+	}
+}
+
+func TestFieldOverlap(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	// This test grew out of issue 21094, where specific sudog<T> DWARF types
+	// had elem fields set to values instead of pointers.
+	const prog = `
+package main
+
+var c chan string
+
+func main() {
+	c <- "foo"
+}
+`
+	dir, err := ioutil.TempDir("", "TestFieldOverlap")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	f := gobuild(t, dir, prog, NoOpt)
+	defer f.Close()
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	rdr := d.Reader()
+	for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
+		if err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+		if entry.Tag != dwarf.TagStructType {
+			continue
+		}
+		typ, err := d.Type(entry.Offset)
+		if err != nil {
+			t.Fatalf("can't read type: %v", err)
+		}
+		s := typ.(*dwarf.StructType)
+		for i := 0; i < len(s.Field); i++ {
+			end := s.Field[i].ByteOffset + s.Field[i].Type.Size()
+			var limit int64
+			if i == len(s.Field)-1 {
+				limit = s.Size()
+			} else {
+				limit = s.Field[i+1].ByteOffset
+			}
+			if end > limit {
+				name := entry.Val(dwarf.AttrName).(string)
+				t.Fatalf("field %s.%s overlaps next field", name, s.Field[i].Name)
+			}
+		}
+	}
+}
+
+func TestVarDeclCoordsAndSubrogramDeclFile(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	const prog = `
+package main
+
+func main() {
+	var i int
+	i = i
+}
+`
+	dir, err := ioutil.TempDir("", "TestVarDeclCoords")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	f := gobuild(t, dir, prog, NoOpt)
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	rdr := d.Reader()
+	ex := examiner{}
+	if err := ex.populate(rdr); err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	// Locate the main.main DIE
+	mains := ex.Named("main.main")
+	if len(mains) == 0 {
+		t.Fatalf("unable to locate DIE for main.main")
+	}
+	if len(mains) != 1 {
+		t.Fatalf("more than one main.main DIE")
+	}
+	maindie := mains[0]
+
+	// Vet the main.main DIE
+	if maindie.Tag != dwarf.TagSubprogram {
+		t.Fatalf("unexpected tag %v on main.main DIE", maindie.Tag)
+	}
+
+	// Walk main's children and select variable "i".
+	mainIdx := ex.idxFromOffset(maindie.Offset)
+	childDies := ex.Children(mainIdx)
+	var iEntry *dwarf.Entry
+	for _, child := range childDies {
+		if child.Tag == dwarf.TagVariable && child.Val(dwarf.AttrName).(string) == "i" {
+			iEntry = child
+			break
+		}
+	}
+	if iEntry == nil {
+		t.Fatalf("didn't find DW_TAG_variable for i in main.main")
+	}
+
+	// Verify line/file attributes.
+	line := iEntry.Val(dwarf.AttrDeclLine)
+	if line == nil || line.(int64) != 5 {
+		t.Errorf("DW_AT_decl_line for i is %v, want 5", line)
+	}
+
+	file := maindie.Val(dwarf.AttrDeclFile)
+	if file == nil || file.(int64) != 1 {
+		t.Errorf("DW_AT_decl_file for main is %v, want 1", file)
+	}
+}
+
+// Helper class for supporting queries on DIEs within a DWARF .debug_info
+// section. Invoke the populate() method below passing in a dwarf.Reader,
+// which will read in all DIEs and keep track of parent/child
+// relationships. Queries can then be made to ask for DIEs by name or
+// by offset. This will hopefully reduce boilerplate for future test
+// writing.
+
+type examiner struct {
+	dies        []*dwarf.Entry
+	idxByOffset map[dwarf.Offset]int
+	kids        map[int][]int
+	parent      map[int]int
+	byname      map[string][]int
+}
+
+// Populate the examiner using the DIEs read from rdr.
+func (ex *examiner) populate(rdr *dwarf.Reader) error {
+	ex.idxByOffset = make(map[dwarf.Offset]int)
+	ex.kids = make(map[int][]int)
+	ex.parent = make(map[int]int)
+	ex.byname = make(map[string][]int)
+	var nesting []int
+	for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
+		if err != nil {
+			return err
+		}
+		if entry.Tag == 0 {
+			// terminator
+			if len(nesting) == 0 {
+				return errors.New("nesting stack underflow")
+			}
+			nesting = nesting[:len(nesting)-1]
+			continue
+		}
+		idx := len(ex.dies)
+		ex.dies = append(ex.dies, entry)
+		if _, found := ex.idxByOffset[entry.Offset]; found {
+			return errors.New("DIE clash on offset")
+		}
+		ex.idxByOffset[entry.Offset] = idx
+		if name, ok := entry.Val(dwarf.AttrName).(string); ok {
+			ex.byname[name] = append(ex.byname[name], idx)
+		}
+		if len(nesting) > 0 {
+			parent := nesting[len(nesting)-1]
+			ex.kids[parent] = append(ex.kids[parent], idx)
+			ex.parent[idx] = parent
+		}
+		if entry.Children {
+			nesting = append(nesting, idx)
+		}
+	}
+	if len(nesting) > 0 {
+		return errors.New("unterminated child sequence")
+	}
+	return nil
+}
+
+func indent(ilevel int) {
+	for i := 0; i < ilevel; i++ {
+		fmt.Printf("  ")
+	}
+}
+
+// For debugging new tests
+func (ex *examiner) dumpEntry(idx int, dumpKids bool, ilevel int) error {
+	if idx >= len(ex.dies) {
+		msg := fmt.Sprintf("bad DIE %d: index out of range\n", idx)
+		return errors.New(msg)
+	}
+	entry := ex.dies[idx]
+	indent(ilevel)
+	fmt.Printf("0x%x: %v\n", idx, entry.Tag)
+	for _, f := range entry.Field {
+		indent(ilevel)
+		fmt.Printf("at=%v val=0x%x\n", f.Attr, f.Val)
+	}
+	if dumpKids {
+		ksl := ex.kids[idx]
+		for _, k := range ksl {
+			ex.dumpEntry(k, true, ilevel+2)
+		}
+	}
+	return nil
+}
+
+// Given a DIE offset, return the previously read dwarf.Entry, or nil
+func (ex *examiner) entryFromOffset(off dwarf.Offset) *dwarf.Entry {
+	if idx, found := ex.idxByOffset[off]; found && idx != -1 {
+		return ex.entryFromIdx(idx)
+	}
+	return nil
+}
+
+// Return the ID that that examiner uses to refer to the DIE at offset off
+func (ex *examiner) idxFromOffset(off dwarf.Offset) int {
+	if idx, found := ex.idxByOffset[off]; found {
+		return idx
+	}
+	return -1
+}
+
+// Return the dwarf.Entry pointer for the DIE with id 'idx'
+func (ex *examiner) entryFromIdx(idx int) *dwarf.Entry {
+	if idx >= len(ex.dies) || idx < 0 {
+		return nil
+	}
+	return ex.dies[idx]
+}
+
+// Returns a list of child entries for a die with ID 'idx'
+func (ex *examiner) Children(idx int) []*dwarf.Entry {
+	sl := ex.kids[idx]
+	ret := make([]*dwarf.Entry, len(sl))
+	for i, k := range sl {
+		ret[i] = ex.entryFromIdx(k)
+	}
+	return ret
+}
+
+// Returns parent DIE for DIE 'idx', or nil if the DIE is top level
+func (ex *examiner) Parent(idx int) *dwarf.Entry {
+	p, found := ex.parent[idx]
+	if !found {
+		return nil
+	}
+	return ex.entryFromIdx(p)
+}
+
+// Return a list of all DIEs with name 'name'. When searching for DIEs
+// by name, keep in mind that the returned results will include child
+// DIEs such as params/variables. For example, asking for all DIEs named
+// "p" for even a small program will give you 400-500 entries.
+func (ex *examiner) Named(name string) []*dwarf.Entry {
+	sl := ex.byname[name]
+	ret := make([]*dwarf.Entry, len(sl))
+	for i, k := range sl {
+		ret[i] = ex.entryFromIdx(k)
+	}
+	return ret
+}
+
+func TestInlinedRoutineRecords(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+	if runtime.GOOS == "solaris" {
+		t.Skip("skipping on solaris, pending resolution of issue #23168")
+	}
+
+	const prog = `
+package main
+
+var G int
+
+func noinline(x int) int {
+	defer func() { G += x }()
+	return x
+}
+
+func cand(x, y int) int {
+	return noinline(x+y) ^ (y - x)
+}
+
+func main() {
+    x := cand(G*G,G|7%G)
+    G = x
+}
+`
+	dir, err := ioutil.TempDir("", "TestInlinedRoutineRecords")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	// Note: this is a build with "-l=4", as opposed to "-l -N". The
+	// test is intended to verify DWARF that is only generated when
+	// the inliner is active.
+	f := gobuild(t, dir, prog, OptInl4)
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	// The inlined subroutines we expect to visit
+	expectedInl := []string{"main.cand"}
+
+	rdr := d.Reader()
+	ex := examiner{}
+	if err := ex.populate(rdr); err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	// Locate the main.main DIE
+	mains := ex.Named("main.main")
+	if len(mains) == 0 {
+		t.Fatalf("unable to locate DIE for main.main")
+	}
+	if len(mains) != 1 {
+		t.Fatalf("more than one main.main DIE")
+	}
+	maindie := mains[0]
+
+	// Vet the main.main DIE
+	if maindie.Tag != dwarf.TagSubprogram {
+		t.Fatalf("unexpected tag %v on main.main DIE", maindie.Tag)
+	}
+
+	// Walk main's children and pick out the inlined subroutines
+	mainIdx := ex.idxFromOffset(maindie.Offset)
+	childDies := ex.Children(mainIdx)
+	exCount := 0
+	for _, child := range childDies {
+		if child.Tag == dwarf.TagInlinedSubroutine {
+			// Found an inlined subroutine, locate abstract origin.
+			ooff, originOK := child.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
+			if !originOK {
+				t.Fatalf("no abstract origin attr for inlined subroutine at offset %v", child.Offset)
+			}
+			originDIE := ex.entryFromOffset(ooff)
+			if originDIE == nil {
+				t.Fatalf("can't locate origin DIE at off %v", ooff)
+			}
+
+			if exCount >= len(expectedInl) {
+				t.Fatalf("too many inlined subroutines found in main.main")
+			}
+
+			// Name should check out.
+			expected := expectedInl[exCount]
+			if name, ok := originDIE.Val(dwarf.AttrName).(string); ok {
+				if name != expected {
+					t.Fatalf("expected inlined routine %s got %s", name, expected)
+				}
+			}
+			exCount++
+
+			omap := make(map[dwarf.Offset]bool)
+
+			// Walk the child variables of the inlined routine. Each
+			// of them should have a distinct abstract origin-- if two
+			// vars point to the same origin things are definitely broken.
+			inlIdx := ex.idxFromOffset(child.Offset)
+			inlChildDies := ex.Children(inlIdx)
+			for _, k := range inlChildDies {
+				ooff, originOK := k.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
+				if !originOK {
+					t.Fatalf("no abstract origin attr for child of inlined subroutine at offset %v", k.Offset)
+				}
+				if _, found := omap[ooff]; found {
+					t.Fatalf("duplicate abstract origin at child of inlined subroutine at offset %v", k.Offset)
+				}
+				omap[ooff] = true
+			}
+		}
+	}
+	if exCount != len(expectedInl) {
+		t.Fatalf("not enough inlined subroutines found in main.main")
+	}
+}
+
+func abstractOriginSanity(t *testing.T, flags string) {
+
+	// Nothing special about net/http here, this is just a convenient
+	// way to pull in a lot of code.
+	const prog = `
+package main
+
+import (
+	"net/http"
+	"net/http/httptest"
+)
+
+type statusHandler int
+
+func (h *statusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	w.WriteHeader(int(*h))
+}
+
+func main() {
+	status := statusHandler(http.StatusNotFound)
+	s := httptest.NewServer(&status)
+	defer s.Close()
+}
+`
+	dir, err := ioutil.TempDir("", "TestAbstractOriginSanity")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	// Build with inlining, to exercise DWARF inlining support.
+	f := gobuild(t, dir, prog, flags)
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+	rdr := d.Reader()
+	ex := examiner{}
+	if err := ex.populate(rdr); err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	// Make a pass through all DIEs looking for abstract origin
+	// references.
+	abscount := 0
+	for i, die := range ex.dies {
+
+		// Does it have an abstract origin?
+		ooff, originOK := die.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
+		if !originOK {
+			continue
+		}
+
+		// All abstract origin references should be resolvable.
+		abscount += 1
+		originDIE := ex.entryFromOffset(ooff)
+		if originDIE == nil {
+			ex.dumpEntry(i, false, 0)
+			t.Fatalf("unresolved abstract origin ref in DIE at offset 0x%x\n", die.Offset)
+		}
+
+		// Suppose that DIE X has parameter/variable children {K1,
+		// K2, ... KN}. If X has an abstract origin of A, then for
+		// each KJ, the abstract origin of KJ should be a child of A.
+		// Note that this same rule doesn't hold for non-variable DIEs.
+		pidx := ex.idxFromOffset(die.Offset)
+		if pidx < 0 {
+			t.Fatalf("can't locate DIE id")
+		}
+		kids := ex.Children(pidx)
+		for _, kid := range kids {
+			if kid.Tag != dwarf.TagVariable &&
+				kid.Tag != dwarf.TagFormalParameter {
+				continue
+			}
+			kooff, originOK := kid.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
+			if !originOK {
+				continue
+			}
+			childOriginDIE := ex.entryFromOffset(kooff)
+			if childOriginDIE == nil {
+				ex.dumpEntry(i, false, 0)
+				t.Fatalf("unresolved abstract origin ref in DIE at offset %x", kid.Offset)
+			}
+			coidx := ex.idxFromOffset(childOriginDIE.Offset)
+			childOriginParent := ex.Parent(coidx)
+			if childOriginParent != originDIE {
+				ex.dumpEntry(i, false, 0)
+				t.Fatalf("unexpected parent of abstract origin DIE at offset %v", childOriginDIE.Offset)
+			}
+		}
+	}
+	if abscount == 0 {
+		t.Fatalf("no abstract origin refs found, something is wrong")
+	}
+}
+
+func TestAbstractOriginSanity(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+	if runtime.GOOS == "solaris" {
+		t.Skip("skipping on solaris, pending resolution of issue #23168")
+	}
+
+	abstractOriginSanity(t, OptInl4)
+}
+
+func TestAbstractOriginSanityWithLocationLists(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+	if runtime.GOOS == "solaris" {
+		t.Skip("skipping on solaris, pending resolution of issue #23168")
+	}
+	if runtime.GOARCH != "amd64" && runtime.GOARCH != "x86" {
+		t.Skip("skipping on not-amd64 not-x86; location lists not supported")
+	}
+
+	abstractOriginSanity(t, OptInl4DwLoc)
+}
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 0fc947f..d56a235 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -7,6 +7,7 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"crypto/sha1"
 	"encoding/binary"
 	"encoding/hex"
@@ -329,438 +330,6 @@
  * Relocation types.
  */
 const (
-	R_X86_64_NONE           = 0
-	R_X86_64_64             = 1
-	R_X86_64_PC32           = 2
-	R_X86_64_GOT32          = 3
-	R_X86_64_PLT32          = 4
-	R_X86_64_COPY           = 5
-	R_X86_64_GLOB_DAT       = 6
-	R_X86_64_JMP_SLOT       = 7
-	R_X86_64_RELATIVE       = 8
-	R_X86_64_GOTPCREL       = 9
-	R_X86_64_32             = 10
-	R_X86_64_32S            = 11
-	R_X86_64_16             = 12
-	R_X86_64_PC16           = 13
-	R_X86_64_8              = 14
-	R_X86_64_PC8            = 15
-	R_X86_64_DTPMOD64       = 16
-	R_X86_64_DTPOFF64       = 17
-	R_X86_64_TPOFF64        = 18
-	R_X86_64_TLSGD          = 19
-	R_X86_64_TLSLD          = 20
-	R_X86_64_DTPOFF32       = 21
-	R_X86_64_GOTTPOFF       = 22
-	R_X86_64_TPOFF32        = 23
-	R_X86_64_PC64           = 24
-	R_X86_64_GOTOFF64       = 25
-	R_X86_64_GOTPC32        = 26
-	R_X86_64_GOT64          = 27
-	R_X86_64_GOTPCREL64     = 28
-	R_X86_64_GOTPC64        = 29
-	R_X86_64_GOTPLT64       = 30
-	R_X86_64_PLTOFF64       = 31
-	R_X86_64_SIZE32         = 32
-	R_X86_64_SIZE64         = 33
-	R_X86_64_GOTPC32_TLSDEC = 34
-	R_X86_64_TLSDESC_CALL   = 35
-	R_X86_64_TLSDESC        = 36
-	R_X86_64_IRELATIVE      = 37
-	R_X86_64_PC32_BND       = 40
-	R_X86_64_GOTPCRELX      = 41
-	R_X86_64_REX_GOTPCRELX  = 42
-
-	R_AARCH64_ABS64                       = 257
-	R_AARCH64_ABS32                       = 258
-	R_AARCH64_CALL26                      = 283
-	R_AARCH64_ADR_PREL_PG_HI21            = 275
-	R_AARCH64_ADD_ABS_LO12_NC             = 277
-	R_AARCH64_LDST8_ABS_LO12_NC           = 278
-	R_AARCH64_LDST16_ABS_LO12_NC          = 284
-	R_AARCH64_LDST32_ABS_LO12_NC          = 285
-	R_AARCH64_LDST64_ABS_LO12_NC          = 286
-	R_AARCH64_ADR_GOT_PAGE                = 311
-	R_AARCH64_LD64_GOT_LO12_NC            = 312
-	R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21   = 541
-	R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
-	R_AARCH64_TLSLE_MOVW_TPREL_G0         = 547
-
-	R_ALPHA_NONE           = 0
-	R_ALPHA_REFLONG        = 1
-	R_ALPHA_REFQUAD        = 2
-	R_ALPHA_GPREL32        = 3
-	R_ALPHA_LITERAL        = 4
-	R_ALPHA_LITUSE         = 5
-	R_ALPHA_GPDISP         = 6
-	R_ALPHA_BRADDR         = 7
-	R_ALPHA_HINT           = 8
-	R_ALPHA_SREL16         = 9
-	R_ALPHA_SREL32         = 10
-	R_ALPHA_SREL64         = 11
-	R_ALPHA_OP_PUSH        = 12
-	R_ALPHA_OP_STORE       = 13
-	R_ALPHA_OP_PSUB        = 14
-	R_ALPHA_OP_PRSHIFT     = 15
-	R_ALPHA_GPVALUE        = 16
-	R_ALPHA_GPRELHIGH      = 17
-	R_ALPHA_GPRELLOW       = 18
-	R_ALPHA_IMMED_GP_16    = 19
-	R_ALPHA_IMMED_GP_HI32  = 20
-	R_ALPHA_IMMED_SCN_HI32 = 21
-	R_ALPHA_IMMED_BR_HI32  = 22
-	R_ALPHA_IMMED_LO32     = 23
-	R_ALPHA_COPY           = 24
-	R_ALPHA_GLOB_DAT       = 25
-	R_ALPHA_JMP_SLOT       = 26
-	R_ALPHA_RELATIVE       = 27
-
-	R_ARM_NONE          = 0
-	R_ARM_PC24          = 1
-	R_ARM_ABS32         = 2
-	R_ARM_REL32         = 3
-	R_ARM_PC13          = 4
-	R_ARM_ABS16         = 5
-	R_ARM_ABS12         = 6
-	R_ARM_THM_ABS5      = 7
-	R_ARM_ABS8          = 8
-	R_ARM_SBREL32       = 9
-	R_ARM_THM_PC22      = 10
-	R_ARM_THM_PC8       = 11
-	R_ARM_AMP_VCALL9    = 12
-	R_ARM_SWI24         = 13
-	R_ARM_THM_SWI8      = 14
-	R_ARM_XPC25         = 15
-	R_ARM_THM_XPC22     = 16
-	R_ARM_COPY          = 20
-	R_ARM_GLOB_DAT      = 21
-	R_ARM_JUMP_SLOT     = 22
-	R_ARM_RELATIVE      = 23
-	R_ARM_GOTOFF        = 24
-	R_ARM_GOTPC         = 25
-	R_ARM_GOT32         = 26
-	R_ARM_PLT32         = 27
-	R_ARM_CALL          = 28
-	R_ARM_JUMP24        = 29
-	R_ARM_V4BX          = 40
-	R_ARM_GOT_PREL      = 96
-	R_ARM_GNU_VTENTRY   = 100
-	R_ARM_GNU_VTINHERIT = 101
-	R_ARM_TLS_IE32      = 107
-	R_ARM_TLS_LE32      = 108
-	R_ARM_RSBREL32      = 250
-	R_ARM_THM_RPC22     = 251
-	R_ARM_RREL32        = 252
-	R_ARM_RABS32        = 253
-	R_ARM_RPC24         = 254
-	R_ARM_RBASE         = 255
-
-	R_386_NONE          = 0
-	R_386_32            = 1
-	R_386_PC32          = 2
-	R_386_GOT32         = 3
-	R_386_PLT32         = 4
-	R_386_COPY          = 5
-	R_386_GLOB_DAT      = 6
-	R_386_JMP_SLOT      = 7
-	R_386_RELATIVE      = 8
-	R_386_GOTOFF        = 9
-	R_386_GOTPC         = 10
-	R_386_TLS_TPOFF     = 14
-	R_386_TLS_IE        = 15
-	R_386_TLS_GOTIE     = 16
-	R_386_TLS_LE        = 17
-	R_386_TLS_GD        = 18
-	R_386_TLS_LDM       = 19
-	R_386_TLS_GD_32     = 24
-	R_386_TLS_GD_PUSH   = 25
-	R_386_TLS_GD_CALL   = 26
-	R_386_TLS_GD_POP    = 27
-	R_386_TLS_LDM_32    = 28
-	R_386_TLS_LDM_PUSH  = 29
-	R_386_TLS_LDM_CALL  = 30
-	R_386_TLS_LDM_POP   = 31
-	R_386_TLS_LDO_32    = 32
-	R_386_TLS_IE_32     = 33
-	R_386_TLS_LE_32     = 34
-	R_386_TLS_DTPMOD32  = 35
-	R_386_TLS_DTPOFF32  = 36
-	R_386_TLS_TPOFF32   = 37
-	R_386_TLS_GOTDESC   = 39
-	R_386_TLS_DESC_CALL = 40
-	R_386_TLS_DESC      = 41
-	R_386_IRELATIVE     = 42
-	R_386_GOT32X        = 43
-
-	R_MIPS_NONE            = 0
-	R_MIPS_16              = 1
-	R_MIPS_32              = 2
-	R_MIPS_REL32           = 3
-	R_MIPS_26              = 4
-	R_MIPS_HI16            = 5
-	R_MIPS_LO16            = 6
-	R_MIPS_GPREL16         = 7
-	R_MIPS_LITERAL         = 8
-	R_MIPS_GOT16           = 9
-	R_MIPS_PC16            = 10
-	R_MIPS_CALL16          = 11
-	R_MIPS_GPREL32         = 12
-	R_MIPS_SHIFT5          = 16
-	R_MIPS_SHIFT6          = 17
-	R_MIPS_64              = 18
-	R_MIPS_GOT_DISP        = 19
-	R_MIPS_GOT_PAGE        = 20
-	R_MIPS_GOT_OFST        = 21
-	R_MIPS_GOT_HI16        = 22
-	R_MIPS_GOT_LO16        = 23
-	R_MIPS_SUB             = 24
-	R_MIPS_INSERT_A        = 25
-	R_MIPS_INSERT_B        = 26
-	R_MIPS_DELETE          = 27
-	R_MIPS_HIGHER          = 28
-	R_MIPS_HIGHEST         = 29
-	R_MIPS_CALL_HI16       = 30
-	R_MIPS_CALL_LO16       = 31
-	R_MIPS_SCN_DISP        = 32
-	R_MIPS_REL16           = 33
-	R_MIPS_ADD_IMMEDIATE   = 34
-	R_MIPS_PJUMP           = 35
-	R_MIPS_RELGOT          = 36
-	R_MIPS_JALR            = 37
-	R_MIPS_TLS_DTPMOD32    = 38
-	R_MIPS_TLS_DTPREL32    = 39
-	R_MIPS_TLS_DTPMOD64    = 40
-	R_MIPS_TLS_DTPREL64    = 41
-	R_MIPS_TLS_GD          = 42
-	R_MIPS_TLS_LDM         = 43
-	R_MIPS_TLS_DTPREL_HI16 = 44
-	R_MIPS_TLS_DTPREL_LO16 = 45
-	R_MIPS_TLS_GOTTPREL    = 46
-	R_MIPS_TLS_TPREL32     = 47
-	R_MIPS_TLS_TPREL64     = 48
-	R_MIPS_TLS_TPREL_HI16  = 49
-	R_MIPS_TLS_TPREL_LO16  = 50
-
-	R_PPC_NONE            = 0
-	R_PPC_ADDR32          = 1
-	R_PPC_ADDR24          = 2
-	R_PPC_ADDR16          = 3
-	R_PPC_ADDR16_LO       = 4
-	R_PPC_ADDR16_HI       = 5
-	R_PPC_ADDR16_HA       = 6
-	R_PPC_ADDR14          = 7
-	R_PPC_ADDR14_BRTAKEN  = 8
-	R_PPC_ADDR14_BRNTAKEN = 9
-	R_PPC_REL24           = 10
-	R_PPC_REL14           = 11
-	R_PPC_REL14_BRTAKEN   = 12
-	R_PPC_REL14_BRNTAKEN  = 13
-	R_PPC_GOT16           = 14
-	R_PPC_GOT16_LO        = 15
-	R_PPC_GOT16_HI        = 16
-	R_PPC_GOT16_HA        = 17
-	R_PPC_PLTREL24        = 18
-	R_PPC_COPY            = 19
-	R_PPC_GLOB_DAT        = 20
-	R_PPC_JMP_SLOT        = 21
-	R_PPC_RELATIVE        = 22
-	R_PPC_LOCAL24PC       = 23
-	R_PPC_UADDR32         = 24
-	R_PPC_UADDR16         = 25
-	R_PPC_REL32           = 26
-	R_PPC_PLT32           = 27
-	R_PPC_PLTREL32        = 28
-	R_PPC_PLT16_LO        = 29
-	R_PPC_PLT16_HI        = 30
-	R_PPC_PLT16_HA        = 31
-	R_PPC_SDAREL16        = 32
-	R_PPC_SECTOFF         = 33
-	R_PPC_SECTOFF_LO      = 34
-	R_PPC_SECTOFF_HI      = 35
-	R_PPC_SECTOFF_HA      = 36
-	R_PPC_TLS             = 67
-	R_PPC_DTPMOD32        = 68
-	R_PPC_TPREL16         = 69
-	R_PPC_TPREL16_LO      = 70
-	R_PPC_TPREL16_HI      = 71
-	R_PPC_TPREL16_HA      = 72
-	R_PPC_TPREL32         = 73
-	R_PPC_DTPREL16        = 74
-	R_PPC_DTPREL16_LO     = 75
-	R_PPC_DTPREL16_HI     = 76
-	R_PPC_DTPREL16_HA     = 77
-	R_PPC_DTPREL32        = 78
-	R_PPC_GOT_TLSGD16     = 79
-	R_PPC_GOT_TLSGD16_LO  = 80
-	R_PPC_GOT_TLSGD16_HI  = 81
-	R_PPC_GOT_TLSGD16_HA  = 82
-	R_PPC_GOT_TLSLD16     = 83
-	R_PPC_GOT_TLSLD16_LO  = 84
-	R_PPC_GOT_TLSLD16_HI  = 85
-	R_PPC_GOT_TLSLD16_HA  = 86
-	R_PPC_GOT_TPREL16     = 87
-	R_PPC_GOT_TPREL16_LO  = 88
-	R_PPC_GOT_TPREL16_HI  = 89
-	R_PPC_GOT_TPREL16_HA  = 90
-	R_PPC_EMB_NADDR32     = 101
-	R_PPC_EMB_NADDR16     = 102
-	R_PPC_EMB_NADDR16_LO  = 103
-	R_PPC_EMB_NADDR16_HI  = 104
-	R_PPC_EMB_NADDR16_HA  = 105
-	R_PPC_EMB_SDAI16      = 106
-	R_PPC_EMB_SDA2I16     = 107
-	R_PPC_EMB_SDA2REL     = 108
-	R_PPC_EMB_SDA21       = 109
-	R_PPC_EMB_MRKREF      = 110
-	R_PPC_EMB_RELSEC16    = 111
-	R_PPC_EMB_RELST_LO    = 112
-	R_PPC_EMB_RELST_HI    = 113
-	R_PPC_EMB_RELST_HA    = 114
-	R_PPC_EMB_BIT_FLD     = 115
-	R_PPC_EMB_RELSDA      = 116
-
-	R_PPC64_ADDR32            = R_PPC_ADDR32
-	R_PPC64_ADDR16_LO         = R_PPC_ADDR16_LO
-	R_PPC64_ADDR16_HA         = R_PPC_ADDR16_HA
-	R_PPC64_REL24             = R_PPC_REL24
-	R_PPC64_GOT16_HA          = R_PPC_GOT16_HA
-	R_PPC64_JMP_SLOT          = R_PPC_JMP_SLOT
-	R_PPC64_TPREL16           = R_PPC_TPREL16
-	R_PPC64_ADDR64            = 38
-	R_PPC64_TOC16             = 47
-	R_PPC64_TOC16_LO          = 48
-	R_PPC64_TOC16_HI          = 49
-	R_PPC64_TOC16_HA          = 50
-	R_PPC64_ADDR16_LO_DS      = 57
-	R_PPC64_GOT16_LO_DS       = 59
-	R_PPC64_TOC16_DS          = 63
-	R_PPC64_TOC16_LO_DS       = 64
-	R_PPC64_TLS               = 67
-	R_PPC64_GOT_TPREL16_LO_DS = 88
-	R_PPC64_GOT_TPREL16_HA    = 90
-	R_PPC64_REL16_LO          = 250
-	R_PPC64_REL16_HI          = 251
-	R_PPC64_REL16_HA          = 252
-
-	R_SPARC_NONE     = 0
-	R_SPARC_8        = 1
-	R_SPARC_16       = 2
-	R_SPARC_32       = 3
-	R_SPARC_DISP8    = 4
-	R_SPARC_DISP16   = 5
-	R_SPARC_DISP32   = 6
-	R_SPARC_WDISP30  = 7
-	R_SPARC_WDISP22  = 8
-	R_SPARC_HI22     = 9
-	R_SPARC_22       = 10
-	R_SPARC_13       = 11
-	R_SPARC_LO10     = 12
-	R_SPARC_GOT10    = 13
-	R_SPARC_GOT13    = 14
-	R_SPARC_GOT22    = 15
-	R_SPARC_PC10     = 16
-	R_SPARC_PC22     = 17
-	R_SPARC_WPLT30   = 18
-	R_SPARC_COPY     = 19
-	R_SPARC_GLOB_DAT = 20
-	R_SPARC_JMP_SLOT = 21
-	R_SPARC_RELATIVE = 22
-	R_SPARC_UA32     = 23
-	R_SPARC_PLT32    = 24
-	R_SPARC_HIPLT22  = 25
-	R_SPARC_LOPLT10  = 26
-	R_SPARC_PCPLT32  = 27
-	R_SPARC_PCPLT22  = 28
-	R_SPARC_PCPLT10  = 29
-	R_SPARC_10       = 30
-	R_SPARC_11       = 31
-	R_SPARC_64       = 32
-	R_SPARC_OLO10    = 33
-	R_SPARC_HH22     = 34
-	R_SPARC_HM10     = 35
-	R_SPARC_LM22     = 36
-	R_SPARC_PC_HH22  = 37
-	R_SPARC_PC_HM10  = 38
-	R_SPARC_PC_LM22  = 39
-	R_SPARC_WDISP16  = 40
-	R_SPARC_WDISP19  = 41
-	R_SPARC_GLOB_JMP = 42
-	R_SPARC_7        = 43
-	R_SPARC_5        = 44
-	R_SPARC_6        = 45
-	R_SPARC_DISP64   = 46
-	R_SPARC_PLT64    = 47
-	R_SPARC_HIX22    = 48
-	R_SPARC_LOX10    = 49
-	R_SPARC_H44      = 50
-	R_SPARC_M44      = 51
-	R_SPARC_L44      = 52
-	R_SPARC_REGISTER = 53
-	R_SPARC_UA64     = 54
-	R_SPARC_UA16     = 55
-
-	R_390_NONE        = 0
-	R_390_8           = 1
-	R_390_12          = 2
-	R_390_16          = 3
-	R_390_32          = 4
-	R_390_PC32        = 5
-	R_390_GOT12       = 6
-	R_390_GOT32       = 7
-	R_390_PLT32       = 8
-	R_390_COPY        = 9
-	R_390_GLOB_DAT    = 10
-	R_390_JMP_SLOT    = 11
-	R_390_RELATIVE    = 12
-	R_390_GOTOFF      = 13
-	R_390_GOTPC       = 14
-	R_390_GOT16       = 15
-	R_390_PC16        = 16
-	R_390_PC16DBL     = 17
-	R_390_PLT16DBL    = 18
-	R_390_PC32DBL     = 19
-	R_390_PLT32DBL    = 20
-	R_390_GOTPCDBL    = 21
-	R_390_64          = 22
-	R_390_PC64        = 23
-	R_390_GOT64       = 24
-	R_390_PLT64       = 25
-	R_390_GOTENT      = 26
-	R_390_GOTOFF16    = 27
-	R_390_GOTOFF64    = 28
-	R_390_GOTPLT12    = 29
-	R_390_GOTPLT16    = 30
-	R_390_GOTPLT32    = 31
-	R_390_GOTPLT64    = 32
-	R_390_GOTPLTENT   = 33
-	R_390_GOTPLTOFF16 = 34
-	R_390_GOTPLTOFF32 = 35
-	R_390_GOTPLTOFF64 = 36
-	R_390_TLS_LOAD    = 37
-	R_390_TLS_GDCALL  = 38
-	R_390_TLS_LDCALL  = 39
-	R_390_TLS_GD32    = 40
-	R_390_TLS_GD64    = 41
-	R_390_TLS_GOTIE12 = 42
-	R_390_TLS_GOTIE32 = 43
-	R_390_TLS_GOTIE64 = 44
-	R_390_TLS_LDM32   = 45
-	R_390_TLS_LDM64   = 46
-	R_390_TLS_IE32    = 47
-	R_390_TLS_IE64    = 48
-	R_390_TLS_IEENT   = 49
-	R_390_TLS_LE32    = 50
-	R_390_TLS_LE64    = 51
-	R_390_TLS_LDO32   = 52
-	R_390_TLS_LDO64   = 53
-	R_390_TLS_DTPMOD  = 54
-	R_390_TLS_DTPOFF  = 55
-	R_390_TLS_TPOFF   = 56
-	R_390_20          = 57
-	R_390_GOT20       = 58
-	R_390_GOTPLT20    = 59
-	R_390_TLS_GOTIE20 = 60
-
 	ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
 )
 
@@ -809,7 +378,6 @@
 	addralign uint64
 	entsize   uint64
 	shnum     int
-	secsym    *Symbol
 }
 
 /*
@@ -885,9 +453,7 @@
 )
 
 var (
-	Iself bool
-
-	Nelfsym int = 1
+	Nelfsym = 1
 
 	elf64 bool
 	// Either ".rel" or ".rela" depending on which type of relocation the
@@ -917,15 +483,15 @@
  we write section and prog headers.
 */
 func Elfinit(ctxt *Link) {
-	Iself = true
+	ctxt.IsELF = true
 
-	if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
+	if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
 		elfRelType = ".rela"
 	} else {
 		elfRelType = ".rel"
 	}
 
-	switch SysArch.Family {
+	switch ctxt.Arch.Family {
 	// 64-bit architectures
 	case sys.PPC64, sys.S390X:
 		if ctxt.Arch.ByteOrder == binary.BigEndian {
@@ -935,7 +501,7 @@
 		}
 		fallthrough
 	case sys.AMD64, sys.ARM64, sys.MIPS64:
-		if SysArch.Family == sys.MIPS64 {
+		if ctxt.Arch.Family == sys.MIPS64 {
 			ehdr.flags = 0x20000004 /* MIPS 3 CPIC */
 		}
 		elf64 = true
@@ -948,9 +514,9 @@
 
 	// 32-bit architectures
 	case sys.ARM, sys.MIPS:
-		if SysArch.Family == sys.ARM {
+		if ctxt.Arch.Family == sys.ARM {
 			// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
-			if Headtype == objabi.Hlinux || Headtype == objabi.Hfreebsd || Headtype == objabi.Hnetbsd {
+			if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd {
 				// We set a value here that makes no indication of which
 				// float ABI the object uses, because this is information
 				// used by the dynamic linker to compare executables and
@@ -961,7 +527,7 @@
 				// appropriate.
 				ehdr.flags = 0x5000002 // has entry point, Version5 EABI
 			}
-		} else if SysArch.Family == sys.MIPS {
+		} else if ctxt.Arch.Family == sys.MIPS {
 			ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
 		}
 		fallthrough
@@ -990,77 +556,77 @@
 	e.memsz += uint64(frag)
 }
 
-func elf64phdr(e *ElfPhdr) {
+func elf64phdr(out *OutBuf, e *ElfPhdr) {
 	if e.type_ == PT_LOAD {
 		fixElfPhdr(e)
 	}
 
-	Thearch.Lput(e.type_)
-	Thearch.Lput(e.flags)
-	Thearch.Vput(e.off)
-	Thearch.Vput(e.vaddr)
-	Thearch.Vput(e.paddr)
-	Thearch.Vput(e.filesz)
-	Thearch.Vput(e.memsz)
-	Thearch.Vput(e.align)
+	out.Write32(e.type_)
+	out.Write32(e.flags)
+	out.Write64(e.off)
+	out.Write64(e.vaddr)
+	out.Write64(e.paddr)
+	out.Write64(e.filesz)
+	out.Write64(e.memsz)
+	out.Write64(e.align)
 }
 
-func elf32phdr(e *ElfPhdr) {
+func elf32phdr(out *OutBuf, e *ElfPhdr) {
 	if e.type_ == PT_LOAD {
 		fixElfPhdr(e)
 	}
 
-	Thearch.Lput(e.type_)
-	Thearch.Lput(uint32(e.off))
-	Thearch.Lput(uint32(e.vaddr))
-	Thearch.Lput(uint32(e.paddr))
-	Thearch.Lput(uint32(e.filesz))
-	Thearch.Lput(uint32(e.memsz))
-	Thearch.Lput(e.flags)
-	Thearch.Lput(uint32(e.align))
+	out.Write32(e.type_)
+	out.Write32(uint32(e.off))
+	out.Write32(uint32(e.vaddr))
+	out.Write32(uint32(e.paddr))
+	out.Write32(uint32(e.filesz))
+	out.Write32(uint32(e.memsz))
+	out.Write32(e.flags)
+	out.Write32(uint32(e.align))
 }
 
-func elf64shdr(e *ElfShdr) {
-	Thearch.Lput(e.name)
-	Thearch.Lput(e.type_)
-	Thearch.Vput(e.flags)
-	Thearch.Vput(e.addr)
-	Thearch.Vput(e.off)
-	Thearch.Vput(e.size)
-	Thearch.Lput(e.link)
-	Thearch.Lput(e.info)
-	Thearch.Vput(e.addralign)
-	Thearch.Vput(e.entsize)
+func elf64shdr(out *OutBuf, e *ElfShdr) {
+	out.Write32(e.name)
+	out.Write32(e.type_)
+	out.Write64(e.flags)
+	out.Write64(e.addr)
+	out.Write64(e.off)
+	out.Write64(e.size)
+	out.Write32(e.link)
+	out.Write32(e.info)
+	out.Write64(e.addralign)
+	out.Write64(e.entsize)
 }
 
-func elf32shdr(e *ElfShdr) {
-	Thearch.Lput(e.name)
-	Thearch.Lput(e.type_)
-	Thearch.Lput(uint32(e.flags))
-	Thearch.Lput(uint32(e.addr))
-	Thearch.Lput(uint32(e.off))
-	Thearch.Lput(uint32(e.size))
-	Thearch.Lput(e.link)
-	Thearch.Lput(e.info)
-	Thearch.Lput(uint32(e.addralign))
-	Thearch.Lput(uint32(e.entsize))
+func elf32shdr(out *OutBuf, e *ElfShdr) {
+	out.Write32(e.name)
+	out.Write32(e.type_)
+	out.Write32(uint32(e.flags))
+	out.Write32(uint32(e.addr))
+	out.Write32(uint32(e.off))
+	out.Write32(uint32(e.size))
+	out.Write32(e.link)
+	out.Write32(e.info)
+	out.Write32(uint32(e.addralign))
+	out.Write32(uint32(e.entsize))
 }
 
-func elfwriteshdrs() uint32 {
+func elfwriteshdrs(out *OutBuf) uint32 {
 	if elf64 {
 		for i := 0; i < int(ehdr.shnum); i++ {
-			elf64shdr(shdr[i])
+			elf64shdr(out, shdr[i])
 		}
 		return uint32(ehdr.shnum) * ELF64SHDRSIZE
 	}
 
 	for i := 0; i < int(ehdr.shnum); i++ {
-		elf32shdr(shdr[i])
+		elf32shdr(out, shdr[i])
 	}
 	return uint32(ehdr.shnum) * ELF32SHDRSIZE
 }
 
-func elfsetstring(s *Symbol, str string, off int) {
+func elfsetstring(s *sym.Symbol, str string, off int) {
 	if nelfstr >= len(elfstr) {
 		Errorf(s, "too many elf strings")
 		errorexit()
@@ -1071,16 +637,16 @@
 	nelfstr++
 }
 
-func elfwritephdrs() uint32 {
+func elfwritephdrs(out *OutBuf) uint32 {
 	if elf64 {
 		for i := 0; i < int(ehdr.phnum); i++ {
-			elf64phdr(phdr[i])
+			elf64phdr(out, phdr[i])
 		}
 		return uint32(ehdr.phnum) * ELF64PHDRSIZE
 	}
 
 	for i := 0; i < int(ehdr.phnum); i++ {
-		elf32phdr(phdr[i])
+		elf32phdr(out, phdr[i])
 	}
 	return uint32(ehdr.phnum) * ELF32PHDRSIZE
 }
@@ -1119,51 +685,47 @@
 	return &ehdr
 }
 
-func elf64writehdr() uint32 {
-	for i := 0; i < EI_NIDENT; i++ {
-		Cput(ehdr.ident[i])
-	}
-	Thearch.Wput(ehdr.type_)
-	Thearch.Wput(ehdr.machine)
-	Thearch.Lput(ehdr.version)
-	Thearch.Vput(ehdr.entry)
-	Thearch.Vput(ehdr.phoff)
-	Thearch.Vput(ehdr.shoff)
-	Thearch.Lput(ehdr.flags)
-	Thearch.Wput(ehdr.ehsize)
-	Thearch.Wput(ehdr.phentsize)
-	Thearch.Wput(ehdr.phnum)
-	Thearch.Wput(ehdr.shentsize)
-	Thearch.Wput(ehdr.shnum)
-	Thearch.Wput(ehdr.shstrndx)
+func elf64writehdr(out *OutBuf) uint32 {
+	out.Write(ehdr.ident[:])
+	out.Write16(ehdr.type_)
+	out.Write16(ehdr.machine)
+	out.Write32(ehdr.version)
+	out.Write64(ehdr.entry)
+	out.Write64(ehdr.phoff)
+	out.Write64(ehdr.shoff)
+	out.Write32(ehdr.flags)
+	out.Write16(ehdr.ehsize)
+	out.Write16(ehdr.phentsize)
+	out.Write16(ehdr.phnum)
+	out.Write16(ehdr.shentsize)
+	out.Write16(ehdr.shnum)
+	out.Write16(ehdr.shstrndx)
 	return ELF64HDRSIZE
 }
 
-func elf32writehdr() uint32 {
-	for i := 0; i < EI_NIDENT; i++ {
-		Cput(ehdr.ident[i])
-	}
-	Thearch.Wput(ehdr.type_)
-	Thearch.Wput(ehdr.machine)
-	Thearch.Lput(ehdr.version)
-	Thearch.Lput(uint32(ehdr.entry))
-	Thearch.Lput(uint32(ehdr.phoff))
-	Thearch.Lput(uint32(ehdr.shoff))
-	Thearch.Lput(ehdr.flags)
-	Thearch.Wput(ehdr.ehsize)
-	Thearch.Wput(ehdr.phentsize)
-	Thearch.Wput(ehdr.phnum)
-	Thearch.Wput(ehdr.shentsize)
-	Thearch.Wput(ehdr.shnum)
-	Thearch.Wput(ehdr.shstrndx)
+func elf32writehdr(out *OutBuf) uint32 {
+	out.Write(ehdr.ident[:])
+	out.Write16(ehdr.type_)
+	out.Write16(ehdr.machine)
+	out.Write32(ehdr.version)
+	out.Write32(uint32(ehdr.entry))
+	out.Write32(uint32(ehdr.phoff))
+	out.Write32(uint32(ehdr.shoff))
+	out.Write32(ehdr.flags)
+	out.Write16(ehdr.ehsize)
+	out.Write16(ehdr.phentsize)
+	out.Write16(ehdr.phnum)
+	out.Write16(ehdr.shentsize)
+	out.Write16(ehdr.shnum)
+	out.Write16(ehdr.shstrndx)
 	return ELF32HDRSIZE
 }
 
-func elfwritehdr() uint32 {
+func elfwritehdr(out *OutBuf) uint32 {
 	if elf64 {
-		return elf64writehdr()
+		return elf64writehdr(out)
 	}
-	return elf32writehdr()
+	return elf32writehdr(out)
 }
 
 /* Taken directly from the definition document for ELF64 */
@@ -1179,36 +741,36 @@
 	return h
 }
 
-func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
+func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) {
 	if elf64 {
-		Adduint64(ctxt, s, uint64(tag))
-		Adduint64(ctxt, s, val)
+		s.AddUint64(ctxt.Arch, uint64(tag))
+		s.AddUint64(ctxt.Arch, val)
 	} else {
-		Adduint32(ctxt, s, uint32(tag))
-		Adduint32(ctxt, s, uint32(val))
+		s.AddUint32(ctxt.Arch, uint32(tag))
+		s.AddUint32(ctxt.Arch, uint32(val))
 	}
 }
 
-func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
+func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
 	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
 }
 
-func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
+func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
 	if elf64 {
-		Adduint64(ctxt, s, uint64(tag))
+		s.AddUint64(ctxt.Arch, uint64(tag))
 	} else {
-		Adduint32(ctxt, s, uint32(tag))
+		s.AddUint32(ctxt.Arch, uint32(tag))
 	}
-	Addaddrplus(ctxt, s, t, add)
+	s.AddAddrPlus(ctxt.Arch, t, add)
 }
 
-func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
+func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
 	if elf64 {
-		Adduint64(ctxt, s, uint64(tag))
+		s.AddUint64(ctxt.Arch, uint64(tag))
 	} else {
-		Adduint32(ctxt, s, uint32(tag))
+		s.AddUint32(ctxt.Arch, uint32(tag))
 	}
-	addsize(ctxt, s, t)
+	s.AddSize(ctxt.Arch, t)
 }
 
 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
@@ -1221,11 +783,11 @@
 	return n
 }
 
-func elfwriteinterp() int {
+func elfwriteinterp(out *OutBuf) int {
 	sh := elfshname(".interp")
-	Cseek(int64(sh.off))
-	coutbuf.WriteString(interp)
-	Cput(0)
+	out.SeekSet(int64(sh.off))
+	out.WriteString(interp)
+	out.Write8(0)
 	return int(sh.size)
 }
 
@@ -1244,15 +806,15 @@
 	return int(n)
 }
 
-func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
+func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
 	sh := elfshname(str)
 
 	// Write Elf_Note header.
-	Cseek(int64(sh.off))
+	out.SeekSet(int64(sh.off))
 
-	Thearch.Lput(namesz)
-	Thearch.Lput(descsz)
-	Thearch.Lput(tag)
+	out.Write32(namesz)
+	out.Write32(descsz)
+	out.Write32(tag)
 
 	return sh
 }
@@ -1272,19 +834,18 @@
 	return elfnote(sh, startva, resoff, n, true)
 }
 
-func elfwritenetbsdsig() int {
+func elfwritenetbsdsig(out *OutBuf) int {
 	// Write Elf_Note header.
-	sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
+	sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
 
 	if sh == nil {
 		return 0
 	}
 
 	// Followed by NetBSD string and version.
-	Cwrite(ELF_NOTE_NETBSD_NAME)
-	Cput(0)
-
-	Thearch.Lput(ELF_NOTE_NETBSD_VERSION)
+	out.Write(ELF_NOTE_NETBSD_NAME)
+	out.Write8(0)
+	out.Write32(ELF_NOTE_NETBSD_VERSION)
 
 	return int(sh.size)
 }
@@ -1304,18 +865,18 @@
 	return elfnote(sh, startva, resoff, n, true)
 }
 
-func elfwriteopenbsdsig() int {
+func elfwriteopenbsdsig(out *OutBuf) int {
 	// Write Elf_Note header.
-	sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
+	sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
 
 	if sh == nil {
 		return 0
 	}
 
 	// Followed by OpenBSD string and version.
-	Cwrite(ELF_NOTE_OPENBSD_NAME)
+	out.Write(ELF_NOTE_OPENBSD_NAME)
 
-	Thearch.Lput(ELF_NOTE_OPENBSD_VERSION)
+	out.Write32(ELF_NOTE_OPENBSD_VERSION)
 
 	return int(sh.size)
 }
@@ -1365,30 +926,30 @@
 	return elfnote(sh, startva, resoff, n, true)
 }
 
-func elfwritebuildinfo() int {
-	sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
+func elfwritebuildinfo(out *OutBuf) int {
+	sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
 	if sh == nil {
 		return 0
 	}
 
-	Cwrite(ELF_NOTE_BUILDINFO_NAME)
-	Cwrite(buildinfo)
+	out.Write(ELF_NOTE_BUILDINFO_NAME)
+	out.Write(buildinfo)
 	var zero = make([]byte, 4)
-	Cwrite(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
+	out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
 
 	return int(sh.size)
 }
 
-func elfwritegobuildid() int {
-	sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
+func elfwritegobuildid(out *OutBuf) int {
+	sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
 	if sh == nil {
 		return 0
 	}
 
-	Cwrite(ELF_NOTE_GO_NAME)
-	Cwrite([]byte(*flagBuildid))
+	out.Write(ELF_NOTE_GO_NAME)
+	out.Write([]byte(*flagBuildid))
 	var zero = make([]byte, 4)
-	Cwrite(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
+	out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
 
 	return int(sh.size)
 }
@@ -1445,14 +1006,14 @@
 }
 
 func elfdynhash(ctxt *Link) {
-	if !Iself {
+	if !ctxt.IsELF {
 		return
 	}
 
 	nsym := Nelfsym
 	s := ctxt.Syms.Lookup(".hash", 0)
-	s.Type = SELFROSECT
-	s.Attr |= AttrReachable
+	s.Type = sym.SELFROSECT
+	s.Attr |= sym.AttrReachable
 
 	i := nsym
 	nbucket := 1
@@ -1466,7 +1027,6 @@
 	chain := make([]uint32, nsym)
 	buckets := make([]uint32, nbucket)
 
-	var b int
 	for _, sy := range ctxt.Syms.Allsym {
 		if sy.Dynid <= 0 {
 			continue
@@ -1479,29 +1039,29 @@
 		name := sy.Extname
 		hc := elfhash(name)
 
-		b = int(hc % uint32(nbucket))
+		b := hc % uint32(nbucket)
 		chain[sy.Dynid] = buckets[b]
 		buckets[b] = uint32(sy.Dynid)
 	}
 
 	// s390x (ELF64) hash table entries are 8 bytes
-	if SysArch.Family == sys.S390X {
-		Adduint64(ctxt, s, uint64(nbucket))
-		Adduint64(ctxt, s, uint64(nsym))
+	if ctxt.Arch.Family == sys.S390X {
+		s.AddUint64(ctxt.Arch, uint64(nbucket))
+		s.AddUint64(ctxt.Arch, uint64(nsym))
 		for i := 0; i < nbucket; i++ {
-			Adduint64(ctxt, s, uint64(buckets[i]))
+			s.AddUint64(ctxt.Arch, uint64(buckets[i]))
 		}
 		for i := 0; i < nsym; i++ {
-			Adduint64(ctxt, s, uint64(chain[i]))
+			s.AddUint64(ctxt.Arch, uint64(chain[i]))
 		}
 	} else {
-		Adduint32(ctxt, s, uint32(nbucket))
-		Adduint32(ctxt, s, uint32(nsym))
+		s.AddUint32(ctxt.Arch, uint32(nbucket))
+		s.AddUint32(ctxt.Arch, uint32(nsym))
 		for i := 0; i < nbucket; i++ {
-			Adduint32(ctxt, s, buckets[i])
+			s.AddUint32(ctxt.Arch, buckets[i])
 		}
 		for i := 0; i < nsym; i++ {
-			Adduint32(ctxt, s, chain[i])
+			s.AddUint32(ctxt.Arch, chain[i])
 		}
 	}
 
@@ -1511,39 +1071,37 @@
 	s = ctxt.Syms.Lookup(".gnu.version_r", 0)
 	i = 2
 	nfile := 0
-	var j int
-	var x *Elfaux
 	for l := needlib; l != nil; l = l.next {
 		nfile++
 
 		// header
-		Adduint16(ctxt, s, 1) // table version
-		j = 0
-		for x = l.aux; x != nil; x = x.next {
+		s.AddUint16(ctxt.Arch, 1) // table version
+		j := 0
+		for x := l.aux; x != nil; x = x.next {
 			j++
 		}
-		Adduint16(ctxt, s, uint16(j))                         // aux count
-		Adduint32(ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
-		Adduint32(ctxt, s, 16)                                // offset from header to first aux
+		s.AddUint16(ctxt.Arch, uint16(j))                         // aux count
+		s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
+		s.AddUint32(ctxt.Arch, 16)                                // offset from header to first aux
 		if l.next != nil {
-			Adduint32(ctxt, s, 16+uint32(j)*16) // offset from this header to next
+			s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
 		} else {
-			Adduint32(ctxt, s, 0)
+			s.AddUint32(ctxt.Arch, 0)
 		}
 
-		for x = l.aux; x != nil; x = x.next {
+		for x := l.aux; x != nil; x = x.next {
 			x.num = i
 			i++
 
 			// aux struct
-			Adduint32(ctxt, s, elfhash(x.vers))                   // hash
-			Adduint16(ctxt, s, 0)                                 // flags
-			Adduint16(ctxt, s, uint16(x.num))                     // other - index we refer to this by
-			Adduint32(ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
+			s.AddUint32(ctxt.Arch, elfhash(x.vers))                   // hash
+			s.AddUint16(ctxt.Arch, 0)                                 // flags
+			s.AddUint16(ctxt.Arch, uint16(x.num))                     // other - index we refer to this by
+			s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
 			if x.next != nil {
-				Adduint32(ctxt, s, 16) // offset from this aux to next
+				s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
 			} else {
-				Adduint32(ctxt, s, 0)
+				s.AddUint32(ctxt.Arch, 0)
 			}
 		}
 	}
@@ -1553,11 +1111,11 @@
 
 	for i := 0; i < nsym; i++ {
 		if i == 0 {
-			Adduint16(ctxt, s, 0) // first entry - no symbol
+			s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
 		} else if need[i] == nil {
-			Adduint16(ctxt, s, 1) // global
+			s.AddUint16(ctxt.Arch, 1) // global
 		} else {
-			Adduint16(ctxt, s, uint16(need[i].num))
+			s.AddUint16(ctxt.Arch, uint16(need[i].num))
 		}
 	}
 
@@ -1583,7 +1141,7 @@
 	Elfwritedynent(ctxt, s, DT_NULL, 0)
 }
 
-func elfphload(seg *Segment) *ElfPhdr {
+func elfphload(seg *sym.Segment) *ElfPhdr {
 	ph := newElfPhdr()
 	ph.type_ = PT_LOAD
 	if seg.Rwx&4 != 0 {
@@ -1605,7 +1163,7 @@
 	return ph
 }
 
-func elfphrelro(seg *Segment) {
+func elfphrelro(seg *sym.Segment) {
 	ph := newElfPhdr()
 	ph.type_ = PT_GNU_RELRO
 	ph.vaddr = seg.Vaddr
@@ -1617,24 +1175,19 @@
 }
 
 func elfshname(name string) *ElfShdr {
-	var off int
-	var sh *ElfShdr
-
 	for i := 0; i < nelfstr; i++ {
-		if name == elfstr[i].s {
-			off = elfstr[i].off
-			for i = 0; i < int(ehdr.shnum); i++ {
-				sh = shdr[i]
-				if sh.name == uint32(off) {
-					return sh
-				}
-			}
-
-			sh = newElfShdr(int64(off))
-			return sh
+		if name != elfstr[i].s {
+			continue
 		}
+		off := elfstr[i].off
+		for i = 0; i < int(ehdr.shnum); i++ {
+			sh := shdr[i]
+			if sh.name == uint32(off) {
+				return sh
+			}
+		}
+		return newElfShdr(int64(off))
 	}
-
 	Exitf("cannot find elf name %s", name)
 	return nil
 }
@@ -1642,14 +1195,10 @@
 // Create an ElfShdr for the section with name.
 // Create a duplicate if one already exists with that name
 func elfshnamedup(name string) *ElfShdr {
-	var off int
-	var sh *ElfShdr
-
 	for i := 0; i < nelfstr; i++ {
 		if name == elfstr[i].s {
-			off = elfstr[i].off
-			sh = newElfShdr(int64(off))
-			return sh
+			off := elfstr[i].off
+			return newElfShdr(int64(off))
 		}
 	}
 
@@ -1658,20 +1207,20 @@
 	return nil
 }
 
-func elfshalloc(sect *Section) *ElfShdr {
+func elfshalloc(sect *sym.Section) *ElfShdr {
 	sh := elfshname(sect.Name)
 	sect.Elfsect = sh
 	return sh
 }
 
-func elfshbits(sect *Section) *ElfShdr {
+func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
 	var sh *ElfShdr
 
 	if sect.Name == ".text" {
 		if sect.Elfsect == nil {
 			sect.Elfsect = elfshnamedup(sect.Name)
 		}
-		sh = sect.Elfsect
+		sh = sect.Elfsect.(*ElfShdr)
 	} else {
 		sh = elfshalloc(sect)
 	}
@@ -1679,7 +1228,7 @@
 	// If this section has already been set up as a note, we assume type_ and
 	// flags are already correct, but the other fields still need filling in.
 	if sh.type_ == SHT_NOTE {
-		if Linkmode != LinkExternal {
+		if linkmode != LinkExternal {
 			// TODO(mwhudson): the approach here will work OK when
 			// linking internally for notes that we want to be included
 			// in a loadable segment (e.g. the abihash note) but not for
@@ -1718,7 +1267,7 @@
 		sh.flags = 0
 	}
 
-	if Linkmode != LinkExternal {
+	if linkmode != LinkExternal {
 		sh.addr = sect.Vaddr
 	}
 	sh.addralign = uint64(sect.Align)
@@ -1730,7 +1279,7 @@
 	return sh
 }
 
-func elfshreloc(sect *Section) *ElfShdr {
+func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
 	// If main section is SHT_NOBITS, nothing to relocate.
 	// Also nothing to relocate in .shstrtab or notes.
 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
@@ -1739,7 +1288,7 @@
 	if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
 		return nil
 	}
-	if sect.Elfsect.type_ == SHT_NOTE {
+	if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
 		return nil
 	}
 
@@ -1755,25 +1304,25 @@
 	// its own .rela.text.
 
 	if sect.Name == ".text" {
-		if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
+		if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
 			sh = elfshnamedup(elfRelType + sect.Name)
 		}
 	}
 
 	sh.type_ = uint32(typ)
-	sh.entsize = uint64(SysArch.RegSize) * 2
+	sh.entsize = uint64(arch.RegSize) * 2
 	if typ == SHT_RELA {
-		sh.entsize += uint64(SysArch.RegSize)
+		sh.entsize += uint64(arch.RegSize)
 	}
 	sh.link = uint32(elfshname(".symtab").shnum)
-	sh.info = uint32(sect.Elfsect.shnum)
+	sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
 	sh.off = sect.Reloff
 	sh.size = sect.Rellen
-	sh.addralign = uint64(SysArch.RegSize)
+	sh.addralign = uint64(arch.RegSize)
 	return sh
 }
 
-func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
+func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
 	// If main section is SHT_NOBITS, nothing to relocate.
 	// Also nothing to relocate in .shstrtab.
 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
@@ -1783,7 +1332,7 @@
 		return
 	}
 
-	sect.Reloff = uint64(coutbuf.Offset())
+	sect.Reloff = uint64(ctxt.Out.Offset())
 	for i, s := range syms {
 		if !s.Attr.Reachable() {
 			continue
@@ -1795,40 +1344,40 @@
 	}
 
 	eaddr := int32(sect.Vaddr + sect.Length)
-	for _, sym := range syms {
-		if !sym.Attr.Reachable() {
+	for _, s := range syms {
+		if !s.Attr.Reachable() {
 			continue
 		}
-		if sym.Value >= int64(eaddr) {
+		if s.Value >= int64(eaddr) {
 			break
 		}
-		for ri := 0; ri < len(sym.R); ri++ {
-			r := &sym.R[ri]
-			if r.Done != 0 {
+		for ri := 0; ri < len(s.R); ri++ {
+			r := &s.R[ri]
+			if r.Done {
 				continue
 			}
 			if r.Xsym == nil {
-				Errorf(sym, "missing xsym in relocation")
+				Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s)
 				continue
 			}
 			if r.Xsym.ElfsymForReloc() == 0 {
-				Errorf(sym, "reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
+				Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
 			}
 			if !r.Xsym.Attr.Reachable() {
-				Errorf(sym, "unreachable reloc %v target %v", r.Type, r.Xsym.Name)
+				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
 			}
-			if Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
-				Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
+			if !Thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
+				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
 			}
 		}
 	}
 
-	sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
+	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
 }
 
 func Elfemitreloc(ctxt *Link) {
-	for coutbuf.Offset()&7 != 0 {
-		Cput(0)
+	for ctxt.Out.Offset()&7 != 0 {
+		ctxt.Out.Write8(0)
 	}
 
 	for _, sect := range Segtext.Sections {
@@ -1855,14 +1404,14 @@
 
 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
 	s := ctxt.Syms.Lookup(sectionName, 0)
-	s.Attr |= AttrReachable
-	s.Type = SELFROSECT
+	s.Attr |= sym.AttrReachable
+	s.Type = sym.SELFROSECT
 	// namesz
-	Adduint32(ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
+	s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
 	// descsz
-	Adduint32(ctxt, s, uint32(len(desc)))
+	s.AddUint32(ctxt.Arch, uint32(len(desc)))
 	// tag
-	Adduint32(ctxt, s, tag)
+	s.AddUint32(ctxt.Arch, tag)
 	// name + padding
 	s.P = append(s.P, ELF_NOTE_GO_NAME...)
 	for len(s.P)%4 != 0 {
@@ -1874,18 +1423,19 @@
 		s.P = append(s.P, 0)
 	}
 	s.Size = int64(len(s.P))
+	s.Align = 4
 }
 
 func (ctxt *Link) doelf() {
-	if !Iself {
+	if !ctxt.IsELF {
 		return
 	}
 
 	/* predefine strings we need for section headers */
 	shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
 
-	shstrtab.Type = SELFROSECT
-	shstrtab.Attr |= AttrReachable
+	shstrtab.Type = sym.SELFROSECT
+	shstrtab.Attr |= sym.AttrReachable
 
 	Addstring(shstrtab, "")
 	Addstring(shstrtab, ".text")
@@ -1897,13 +1447,13 @@
 	// generate .tbss section for dynamic internal linker or external
 	// linking, so that various binutils could correctly calculate
 	// PT_TLS size. See https://golang.org/issue/5200.
-	if !*FlagD || Linkmode == LinkExternal {
+	if !*FlagD || ctxt.LinkMode == LinkExternal {
 		Addstring(shstrtab, ".tbss")
 	}
-	if Headtype == objabi.Hnetbsd {
+	if ctxt.HeadType == objabi.Hnetbsd {
 		Addstring(shstrtab, ".note.netbsd.ident")
 	}
-	if Headtype == objabi.Hopenbsd {
+	if ctxt.HeadType == objabi.Hopenbsd {
 		Addstring(shstrtab, ".note.openbsd.ident")
 	}
 	if len(buildinfo) > 0 {
@@ -1916,7 +1466,7 @@
 	Addstring(shstrtab, ".rodata")
 	// See the comment about data.rel.ro.FOO section names in data.go.
 	relro_prefix := ""
-	if UseRelro() {
+	if ctxt.UseRelro() {
 		Addstring(shstrtab, ".data.rel.ro")
 		relro_prefix = ".data.rel.ro"
 	}
@@ -1925,7 +1475,7 @@
 	Addstring(shstrtab, relro_prefix+".gosymtab")
 	Addstring(shstrtab, relro_prefix+".gopclntab")
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		*FlagD = true
 
 		Addstring(shstrtab, elfRelType+".text")
@@ -1936,25 +1486,25 @@
 		Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
 		Addstring(shstrtab, elfRelType+".noptrdata")
 		Addstring(shstrtab, elfRelType+".data")
-		if UseRelro() {
+		if ctxt.UseRelro() {
 			Addstring(shstrtab, elfRelType+".data.rel.ro")
 		}
 
 		// add a .note.GNU-stack section to mark the stack as non-executable
 		Addstring(shstrtab, ".note.GNU-stack")
 
-		if Buildmode == BuildmodeShared {
+		if ctxt.BuildMode == BuildModeShared {
 			Addstring(shstrtab, ".note.go.abihash")
 			Addstring(shstrtab, ".note.go.pkg-list")
 			Addstring(shstrtab, ".note.go.deps")
 		}
 	}
 
-	hasinitarr := *FlagLinkshared
+	hasinitarr := ctxt.linkShared
 
 	/* shared library initializer */
-	switch Buildmode {
-	case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
+	switch ctxt.BuildMode {
+	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
 		hasinitarr = true
 	}
 
@@ -1975,7 +1525,7 @@
 		Addstring(shstrtab, ".interp")
 		Addstring(shstrtab, ".hash")
 		Addstring(shstrtab, ".got")
-		if SysArch.Family == sys.PPC64 {
+		if ctxt.Arch.Family == sys.PPC64 {
 			Addstring(shstrtab, ".glink")
 		}
 		Addstring(shstrtab, ".got.plt")
@@ -1992,8 +1542,8 @@
 		/* dynamic symbol table - first entry all zeros */
 		s := ctxt.Syms.Lookup(".dynsym", 0)
 
-		s.Type = SELFROSECT
-		s.Attr |= AttrReachable
+		s.Type = sym.SELFROSECT
+		s.Attr |= sym.AttrReachable
 		if elf64 {
 			s.Size += ELF64SYMSIZE
 		} else {
@@ -2003,8 +1553,8 @@
 		/* dynamic string table */
 		s = ctxt.Syms.Lookup(".dynstr", 0)
 
-		s.Type = SELFROSECT
-		s.Attr |= AttrReachable
+		s.Type = sym.SELFROSECT
+		s.Attr |= sym.AttrReachable
 		if s.Size == 0 {
 			Addstring(s, "")
 		}
@@ -2012,62 +1562,62 @@
 
 		/* relocation table */
 		s = ctxt.Syms.Lookup(elfRelType, 0)
-		s.Attr |= AttrReachable
-		s.Type = SELFROSECT
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFROSECT
 
 		/* global offset table */
 		s = ctxt.Syms.Lookup(".got", 0)
 
-		s.Attr |= AttrReachable
-		s.Type = SELFGOT // writable
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFGOT // writable
 
 		/* ppc64 glink resolver */
-		if SysArch.Family == sys.PPC64 {
+		if ctxt.Arch.Family == sys.PPC64 {
 			s := ctxt.Syms.Lookup(".glink", 0)
-			s.Attr |= AttrReachable
-			s.Type = SELFRXSECT
+			s.Attr |= sym.AttrReachable
+			s.Type = sym.SELFRXSECT
 		}
 
 		/* hash */
 		s = ctxt.Syms.Lookup(".hash", 0)
 
-		s.Attr |= AttrReachable
-		s.Type = SELFROSECT
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFROSECT
 
 		s = ctxt.Syms.Lookup(".got.plt", 0)
-		s.Attr |= AttrReachable
-		s.Type = SELFSECT // writable
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFSECT // writable
 
 		s = ctxt.Syms.Lookup(".plt", 0)
 
-		s.Attr |= AttrReachable
-		if SysArch.Family == sys.PPC64 {
+		s.Attr |= sym.AttrReachable
+		if ctxt.Arch.Family == sys.PPC64 {
 			// In the ppc64 ABI, .plt is a data section
 			// written by the dynamic linker.
-			s.Type = SELFSECT
+			s.Type = sym.SELFSECT
 		} else {
-			s.Type = SELFRXSECT
+			s.Type = sym.SELFRXSECT
 		}
 
 		Thearch.Elfsetupplt(ctxt)
 
 		s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
-		s.Attr |= AttrReachable
-		s.Type = SELFROSECT
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFROSECT
 
 		s = ctxt.Syms.Lookup(".gnu.version", 0)
-		s.Attr |= AttrReachable
-		s.Type = SELFROSECT
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFROSECT
 
 		s = ctxt.Syms.Lookup(".gnu.version_r", 0)
-		s.Attr |= AttrReachable
-		s.Type = SELFROSECT
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFROSECT
 
 		/* define dynamic elf table */
 		s = ctxt.Syms.Lookup(".dynamic", 0)
 
-		s.Attr |= AttrReachable
-		s.Type = SELFSECT // writable
+		s.Attr |= sym.AttrReachable
+		s.Type = sym.SELFSECT // writable
 
 		/*
 		 * .dynamic table
@@ -2096,15 +1646,15 @@
 			Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
 		}
 
-		if SysArch.Family == sys.PPC64 {
+		if ctxt.Arch.Family == sys.PPC64 {
 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
-		} else if SysArch.Family == sys.S390X {
+		} else if ctxt.Arch.Family == sys.S390X {
 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
 		} else {
 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
 		}
 
-		if SysArch.Family == sys.PPC64 {
+		if ctxt.Arch.Family == sys.PPC64 {
 			Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
 		}
 
@@ -2115,20 +1665,20 @@
 		Elfwritedynent(ctxt, s, DT_DEBUG, 0)
 	}
 
-	if Buildmode == BuildmodeShared {
+	if ctxt.BuildMode == BuildModeShared {
 		// The go.link.abihashbytes symbol will be pointed at the appropriate
 		// part of the .note.go.abihash section in data.go:func address().
 		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-		s.Attr |= AttrLocal
-		s.Type = SRODATA
-		s.Attr |= AttrSpecial
-		s.Attr |= AttrReachable
+		s.Attr |= sym.AttrLocal
+		s.Type = sym.SRODATA
+		s.Attr |= sym.AttrSpecial
+		s.Attr |= sym.AttrReachable
 		s.Size = int64(sha1.Size)
 
 		sort.Sort(byPkg(ctxt.Library))
 		h := sha1.New()
 		for _, l := range ctxt.Library {
-			io.WriteString(h, l.hash)
+			io.WriteString(h, l.Hash)
 		}
 		addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
 		addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
@@ -2139,13 +1689,13 @@
 		addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
 	}
 
-	if Linkmode == LinkExternal && *flagBuildid != "" {
+	if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
 		addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
 	}
 }
 
 // Do not write DT_NULL.  elfdynhash will finish it.
-func shsym(sh *ElfShdr, s *Symbol) {
+func shsym(sh *ElfShdr, s *sym.Symbol) {
 	addr := Symaddr(s)
 	if sh.flags&SHF_ALLOC != 0 {
 		sh.addr = uint64(addr)
@@ -2194,9 +1744,9 @@
 
 func Asmbelf(ctxt *Link, symo int64) {
 	eh := getElfEhdr()
-	switch SysArch.Family {
+	switch ctxt.Arch.Family {
 	default:
-		Exitf("unknown architecture in asmbelf: %v", SysArch.Family)
+		Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
 	case sys.MIPS, sys.MIPS64:
 		eh.machine = EM_MIPS
 	case sys.ARM:
@@ -2236,13 +1786,13 @@
 
 	var pph *ElfPhdr
 	var pnote *ElfPhdr
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		/* skip program headers */
 		eh.phoff = 0
 
 		eh.phentsize = 0
 
-		if Buildmode == BuildmodeShared {
+		if ctxt.BuildMode == BuildModeShared {
 			sh := elfshname(".note.go.pkg-list")
 			sh.type_ = SHT_NOTE
 			sh = elfshname(".note.go.abihash")
@@ -2276,7 +1826,7 @@
 	 * segment boundaries downwards to include it.
 	 * Except on NaCl where it must not be loaded.
 	 */
-	if Headtype != objabi.Hnacl {
+	if ctxt.HeadType != objabi.Hnacl {
 		o := int64(Segtext.Vaddr - pph.vaddr)
 		Segtext.Vaddr -= uint64(o)
 		Segtext.Length += uint64(o)
@@ -2293,7 +1843,7 @@
 		sh.flags = SHF_ALLOC
 		sh.addralign = 1
 		if interpreter == "" {
-			switch Headtype {
+			switch ctxt.HeadType {
 			case objabi.Hlinux:
 				interpreter = Thearch.Linuxdynld
 
@@ -2323,9 +1873,9 @@
 	}
 
 	pnote = nil
-	if Headtype == objabi.Hnetbsd || Headtype == objabi.Hopenbsd {
+	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
 		var sh *ElfShdr
-		switch Headtype {
+		switch ctxt.HeadType {
 		case objabi.Hnetbsd:
 			sh = elfshname(".note.netbsd.ident")
 			resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
@@ -2386,7 +1936,7 @@
 		} else {
 			sh.entsize = ELF32SYMSIZE
 		}
-		sh.addralign = uint64(SysArch.RegSize)
+		sh.addralign = uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".dynstr").shnum)
 
 		// sh->info = index of first non-local symbol (number of local symbols)
@@ -2410,7 +1960,7 @@
 			sh = elfshname(".gnu.version_r")
 			sh.type_ = SHT_GNU_VERNEED
 			sh.flags = SHF_ALLOC
-			sh.addralign = uint64(SysArch.RegSize)
+			sh.addralign = uint64(ctxt.Arch.RegSize)
 			sh.info = uint32(elfverneed)
 			sh.link = uint32(elfshname(".dynstr").shnum)
 			shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
@@ -2421,7 +1971,7 @@
 			sh.type_ = SHT_RELA
 			sh.flags = SHF_ALLOC
 			sh.entsize = ELF64RELASIZE
-			sh.addralign = uint64(SysArch.RegSize)
+			sh.addralign = uint64(ctxt.Arch.RegSize)
 			sh.link = uint32(elfshname(".dynsym").shnum)
 			sh.info = uint32(elfshname(".plt").shnum)
 			shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
@@ -2485,15 +2035,15 @@
 			sh := elfshname(".got")
 			sh.type_ = SHT_PROGBITS
 			sh.flags = SHF_ALLOC + SHF_WRITE
-			sh.entsize = uint64(SysArch.RegSize)
-			sh.addralign = uint64(SysArch.RegSize)
+			sh.entsize = uint64(ctxt.Arch.RegSize)
+			sh.addralign = uint64(ctxt.Arch.RegSize)
 			shsym(sh, ctxt.Syms.Lookup(".got", 0))
 
 			sh = elfshname(".got.plt")
 			sh.type_ = SHT_PROGBITS
 			sh.flags = SHF_ALLOC + SHF_WRITE
-			sh.entsize = uint64(SysArch.RegSize)
-			sh.addralign = uint64(SysArch.RegSize)
+			sh.entsize = uint64(ctxt.Arch.RegSize)
+			sh.addralign = uint64(ctxt.Arch.RegSize)
 			shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
 		}
 
@@ -2501,7 +2051,7 @@
 		sh.type_ = SHT_HASH
 		sh.flags = SHF_ALLOC
 		sh.entsize = 4
-		sh.addralign = uint64(SysArch.RegSize)
+		sh.addralign = uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".dynsym").shnum)
 		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
 
@@ -2510,8 +2060,8 @@
 
 		sh.type_ = SHT_DYNAMIC
 		sh.flags = SHF_ALLOC + SHF_WRITE
-		sh.entsize = 2 * uint64(SysArch.RegSize)
-		sh.addralign = uint64(SysArch.RegSize)
+		sh.entsize = 2 * uint64(ctxt.Arch.RegSize)
+		sh.addralign = uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".dynstr").shnum)
 		shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
 		ph := newElfPhdr()
@@ -2533,21 +2083,21 @@
 			ph.type_ = PT_TLS
 			ph.flags = PF_R
 			ph.memsz = tlssize
-			ph.align = uint64(SysArch.RegSize)
+			ph.align = uint64(ctxt.Arch.RegSize)
 		}
 	}
 
-	if Headtype == objabi.Hlinux {
+	if ctxt.HeadType == objabi.Hlinux {
 		ph := newElfPhdr()
 		ph.type_ = PT_GNU_STACK
 		ph.flags = PF_W + PF_R
-		ph.align = uint64(SysArch.RegSize)
+		ph.align = uint64(ctxt.Arch.RegSize)
 
 		ph = newElfPhdr()
 		ph.type_ = PT_PAX_FLAGS
 		ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
-		ph.align = uint64(SysArch.RegSize)
-	} else if Headtype == objabi.Hsolaris {
+		ph.align = uint64(ctxt.Arch.RegSize)
+	} else if ctxt.HeadType == objabi.Hsolaris {
 		ph := newElfPhdr()
 		ph.type_ = PT_SUNWSTACK
 		ph.flags = PF_W + PF_R
@@ -2567,40 +2117,37 @@
 	}
 
 	for _, sect := range Segtext.Sections {
-		elfshbits(sect)
+		elfshbits(ctxt.LinkMode, sect)
 	}
 	for _, sect := range Segrodata.Sections {
-		elfshbits(sect)
+		elfshbits(ctxt.LinkMode, sect)
 	}
 	for _, sect := range Segrelrodata.Sections {
-		elfshbits(sect)
+		elfshbits(ctxt.LinkMode, sect)
 	}
 	for _, sect := range Segdata.Sections {
-		elfshbits(sect)
+		elfshbits(ctxt.LinkMode, sect)
 	}
 	for _, sect := range Segdwarf.Sections {
-		elfshbits(sect)
+		elfshbits(ctxt.LinkMode, sect)
 	}
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		for _, sect := range Segtext.Sections {
-			elfshreloc(sect)
+			elfshreloc(ctxt.Arch, sect)
 		}
 		for _, sect := range Segrodata.Sections {
-			elfshreloc(sect)
+			elfshreloc(ctxt.Arch, sect)
 		}
 		for _, sect := range Segrelrodata.Sections {
-			elfshreloc(sect)
+			elfshreloc(ctxt.Arch, sect)
 		}
 		for _, sect := range Segdata.Sections {
-			elfshreloc(sect)
+			elfshreloc(ctxt.Arch, sect)
 		}
 		for _, s := range dwarfp {
-			if len(s.R) > 0 || s.Type == SDWARFINFO {
-				elfshreloc(s.Sect)
-			}
-			if s.Type == SDWARFINFO {
-				break
+			if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC {
+				elfshreloc(ctxt.Arch, s.Sect)
 			}
 		}
 		// add a .note.GNU-stack section to mark the stack as non-executable
@@ -2616,8 +2163,8 @@
 		sh.type_ = SHT_SYMTAB
 		sh.off = uint64(symo)
 		sh.size = uint64(Symsize)
-		sh.addralign = uint64(SysArch.RegSize)
-		sh.entsize = 8 + 2*uint64(SysArch.RegSize)
+		sh.addralign = uint64(ctxt.Arch.RegSize)
+		sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".strtab").shnum)
 		sh.info = uint32(elfglobalsymndx)
 
@@ -2634,13 +2181,13 @@
 	eh.ident[EI_MAG1] = 'E'
 	eh.ident[EI_MAG2] = 'L'
 	eh.ident[EI_MAG3] = 'F'
-	if Headtype == objabi.Hfreebsd {
+	if ctxt.HeadType == objabi.Hfreebsd {
 		eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
-	} else if Headtype == objabi.Hnetbsd {
+	} else if ctxt.HeadType == objabi.Hnetbsd {
 		eh.ident[EI_OSABI] = ELFOSABI_NETBSD
-	} else if Headtype == objabi.Hopenbsd {
+	} else if ctxt.HeadType == objabi.Hopenbsd {
 		eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
-	} else if Headtype == objabi.Hdragonfly {
+	} else if ctxt.HeadType == objabi.Hdragonfly {
 		eh.ident[EI_OSABI] = ELFOSABI_NONE
 	}
 	if elf64 {
@@ -2655,15 +2202,15 @@
 	}
 	eh.ident[EI_VERSION] = EV_CURRENT
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		eh.type_ = ET_REL
-	} else if Buildmode == BuildmodePIE {
+	} else if ctxt.BuildMode == BuildModePIE {
 		eh.type_ = ET_DYN
 	} else {
 		eh.type_ = ET_EXEC
 	}
 
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		eh.entry = uint64(Entryvalue(ctxt))
 	}
 
@@ -2674,26 +2221,26 @@
 		pph.memsz = pph.filesz
 	}
 
-	Cseek(0)
+	ctxt.Out.SeekSet(0)
 	a := int64(0)
-	a += int64(elfwritehdr())
-	a += int64(elfwritephdrs())
-	a += int64(elfwriteshdrs())
+	a += int64(elfwritehdr(ctxt.Out))
+	a += int64(elfwritephdrs(ctxt.Out))
+	a += int64(elfwriteshdrs(ctxt.Out))
 	if !*FlagD {
-		a += int64(elfwriteinterp())
+		a += int64(elfwriteinterp(ctxt.Out))
 	}
-	if Linkmode != LinkExternal {
-		if Headtype == objabi.Hnetbsd {
-			a += int64(elfwritenetbsdsig())
+	if ctxt.LinkMode != LinkExternal {
+		if ctxt.HeadType == objabi.Hnetbsd {
+			a += int64(elfwritenetbsdsig(ctxt.Out))
 		}
-		if Headtype == objabi.Hopenbsd {
-			a += int64(elfwriteopenbsdsig())
+		if ctxt.HeadType == objabi.Hopenbsd {
+			a += int64(elfwriteopenbsdsig(ctxt.Out))
 		}
 		if len(buildinfo) > 0 {
-			a += int64(elfwritebuildinfo())
+			a += int64(elfwritebuildinfo(ctxt.Out))
 		}
 		if *flagBuildid != "" {
-			a += int64(elfwritegobuildid())
+			a += int64(elfwritegobuildid(ctxt.Out))
 		}
 	}
 
@@ -2702,7 +2249,7 @@
 	}
 }
 
-func Elfadddynsym(ctxt *Link, s *Symbol) {
+func elfadddynsym(ctxt *Link, s *sym.Symbol) {
 	if elf64 {
 		s.Dynid = int32(Nelfsym)
 		Nelfsym++
@@ -2710,39 +2257,39 @@
 		d := ctxt.Syms.Lookup(".dynsym", 0)
 
 		name := s.Extname
-		Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
+		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
 
 		/* type */
 		t := STB_GLOBAL << 4
 
-		if s.Attr.CgoExport() && s.Type&SMASK == STEXT {
+		if s.Attr.CgoExport() && s.Type == sym.STEXT {
 			t |= STT_FUNC
 		} else {
 			t |= STT_OBJECT
 		}
-		Adduint8(ctxt, d, uint8(t))
+		d.AddUint8(uint8(t))
 
 		/* reserved */
-		Adduint8(ctxt, d, 0)
+		d.AddUint8(0)
 
 		/* section where symbol is defined */
-		if s.Type == SDYNIMPORT {
-			Adduint16(ctxt, d, SHN_UNDEF)
+		if s.Type == sym.SDYNIMPORT {
+			d.AddUint16(ctxt.Arch, SHN_UNDEF)
 		} else {
-			Adduint16(ctxt, d, 1)
+			d.AddUint16(ctxt.Arch, 1)
 		}
 
 		/* value */
-		if s.Type == SDYNIMPORT {
-			Adduint64(ctxt, d, 0)
+		if s.Type == sym.SDYNIMPORT {
+			d.AddUint64(ctxt.Arch, 0)
 		} else {
-			Addaddr(ctxt, d, s)
+			d.AddAddr(ctxt.Arch, s)
 		}
 
 		/* size of object */
-		Adduint64(ctxt, d, uint64(s.Size))
+		d.AddUint64(ctxt.Arch, uint64(s.Size))
 
-		if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
+		if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
 			Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
 		}
 	} else {
@@ -2754,37 +2301,37 @@
 		/* name */
 		name := s.Extname
 
-		Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
+		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
 
 		/* value */
-		if s.Type == SDYNIMPORT {
-			Adduint32(ctxt, d, 0)
+		if s.Type == sym.SDYNIMPORT {
+			d.AddUint32(ctxt.Arch, 0)
 		} else {
-			Addaddr(ctxt, d, s)
+			d.AddAddr(ctxt.Arch, s)
 		}
 
 		/* size of object */
-		Adduint32(ctxt, d, uint32(s.Size))
+		d.AddUint32(ctxt.Arch, uint32(s.Size))
 
 		/* type */
 		t := STB_GLOBAL << 4
 
 		// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
-		if SysArch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&SMASK == STEXT {
+		if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT {
 			t |= STT_FUNC
-		} else if SysArch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&SMASK == STEXT {
+		} else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT {
 			t |= STT_FUNC
 		} else {
 			t |= STT_OBJECT
 		}
-		Adduint8(ctxt, d, uint8(t))
-		Adduint8(ctxt, d, 0)
+		d.AddUint8(uint8(t))
+		d.AddUint8(0)
 
 		/* shndx */
-		if s.Type == SDYNIMPORT {
-			Adduint16(ctxt, d, SHN_UNDEF)
+		if s.Type == sym.SDYNIMPORT {
+			d.AddUint16(ctxt.Arch, SHN_UNDEF)
 		} else {
-			Adduint16(ctxt, d, 1)
+			d.AddUint16(ctxt.Arch, 1)
 		}
 	}
 }
diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go
index 2930a6b..7210ebb 100644
--- a/src/cmd/link/internal/ld/go.go
+++ b/src/cmd/link/internal/ld/go.go
@@ -10,6 +10,7 @@
 	"bytes"
 	"cmd/internal/bio"
 	"cmd/internal/objabi"
+	"cmd/link/internal/sym"
 	"fmt"
 	"io"
 	"os"
@@ -29,8 +30,6 @@
 //		libmach, so that other linkers and ar can share.
 
 func ldpkg(ctxt *Link, f *bio.Reader, pkg string, length int64, filename string, whence int) {
-	var p0, p1 int
-
 	if *flagG {
 		return
 	}
@@ -95,7 +94,8 @@
 	}
 
 	// look for cgo section
-	p0 = strings.Index(data, "\n$$  // cgo")
+	p0 := strings.Index(data, "\n$$  // cgo")
+	var p1 int
 	if p0 >= 0 {
 		p0 += p1
 		i := strings.IndexByte(data[p0+1:], '\n')
@@ -128,11 +128,8 @@
 func loadcgo(ctxt *Link, file string, pkg string, p string) {
 	var next string
 	var q string
-	var f []string
-	var local string
-	var remote string
 	var lib string
-	var s *Symbol
+	var s *sym.Symbol
 
 	p0 := ""
 	for ; p != ""; p = next {
@@ -143,7 +140,7 @@
 		}
 
 		p0 = p // save for error message
-		f = tokenize(p)
+		f := tokenize(p)
 		if len(f) == 0 {
 			continue
 		}
@@ -153,8 +150,8 @@
 				goto err
 			}
 
-			local = f[1]
-			remote = local
+			local := f[1]
+			remote := local
 			if len(f) > 2 {
 				remote = f[2]
 			}
@@ -174,8 +171,8 @@
 				// to force a link of foo.so.
 				havedynamic = 1
 
-				if Headtype == objabi.Hdarwin {
-					Machoadddynlib(lib)
+				if ctxt.HeadType == objabi.Hdarwin {
+					machoadddynlib(lib, ctxt.LinkMode)
 				} else {
 					dynlib = append(dynlib, lib)
 				}
@@ -188,14 +185,12 @@
 				remote, q = remote[:i], remote[i+1:]
 			}
 			s = ctxt.Syms.Lookup(local, 0)
-			if local != f[1] {
-			}
-			if s.Type == 0 || s.Type == SXREF || s.Type == SHOSTOBJ {
+			if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
 				s.Dynimplib = lib
 				s.Extname = remote
 				s.Dynimpvers = q
-				if s.Type != SHOSTOBJ {
-					s.Type = SDYNIMPORT
+				if s.Type != sym.SHOSTOBJ {
+					s.Type = sym.SDYNIMPORT
 				}
 				havedynamic = 1
 			}
@@ -207,9 +202,9 @@
 			if len(f) != 2 {
 				goto err
 			}
-			local = f[1]
+			local := f[1]
 			s = ctxt.Syms.Lookup(local, 0)
-			s.Type = SHOSTOBJ
+			s.Type = sym.SHOSTOBJ
 			s.Size = 0
 			continue
 		}
@@ -218,7 +213,8 @@
 			if len(f) < 2 || len(f) > 3 {
 				goto err
 			}
-			local = f[1]
+			local := f[1]
+			var remote string
 			if len(f) > 2 {
 				remote = f[2]
 			} else {
@@ -227,8 +223,8 @@
 			local = expandpkg(local, pkg)
 			s = ctxt.Syms.Lookup(local, 0)
 
-			switch Buildmode {
-			case BuildmodeCShared, BuildmodeCArchive, BuildmodePlugin:
+			switch ctxt.BuildMode {
+			case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
 				if s == ctxt.Syms.Lookup("main", 0) {
 					continue
 				}
@@ -253,11 +249,9 @@
 			}
 
 			if f[0] == "cgo_export_static" {
-				s.Attr |= AttrCgoExportStatic
+				s.Attr |= sym.AttrCgoExportStatic
 			} else {
-				s.Attr |= AttrCgoExportDynamic
-			}
-			if local != f[1] {
+				s.Attr |= sym.AttrCgoExportDynamic
 			}
 			continue
 		}
@@ -299,12 +293,12 @@
 var seenlib = make(map[string]bool)
 
 func adddynlib(ctxt *Link, lib string) {
-	if seenlib[lib] || Linkmode == LinkExternal {
+	if seenlib[lib] || ctxt.LinkMode == LinkExternal {
 		return
 	}
 	seenlib[lib] = true
 
-	if Iself {
+	if ctxt.IsELF {
 		s := ctxt.Syms.Lookup(".dynstr", 0)
 		if s.Size == 0 {
 			Addstring(s, "")
@@ -315,16 +309,16 @@
 	}
 }
 
-func Adddynsym(ctxt *Link, s *Symbol) {
-	if s.Dynid >= 0 || Linkmode == LinkExternal {
+func Adddynsym(ctxt *Link, s *sym.Symbol) {
+	if s.Dynid >= 0 || ctxt.LinkMode == LinkExternal {
 		return
 	}
 
-	if Iself {
-		Elfadddynsym(ctxt, s)
-	} else if Headtype == objabi.Hdarwin {
+	if ctxt.IsELF {
+		elfadddynsym(ctxt, s)
+	} else if ctxt.HeadType == objabi.Hdarwin {
 		Errorf(s, "adddynsym: missed symbol (Extname=%s)", s.Extname)
-	} else if Headtype == objabi.Hwindows {
+	} else if ctxt.HeadType == objabi.Hwindows {
 		// already taken care of
 	} else {
 		Errorf(s, "adddynsym: unsupported binary format")
@@ -336,8 +330,8 @@
 	var buf bytes.Buffer
 	for _, s := range ctxt.Syms.Allsym {
 		if strings.HasPrefix(s.Name, "go.track.") {
-			s.Attr |= AttrSpecial // do not lay out in data segment
-			s.Attr |= AttrNotInSymbolTable
+			s.Attr |= sym.AttrSpecial // do not lay out in data segment
+			s.Attr |= sym.AttrNotInSymbolTable
 			if s.Attr.Reachable() {
 				buf.WriteString(s.Name[9:])
 				for p := s.Reachparent; p != nil; p = p.Reachparent {
@@ -347,7 +341,7 @@
 				buf.WriteString("\n")
 			}
 
-			s.Type = SCONST
+			s.Type = sym.SCONST
 			s.Value = 0
 		}
 	}
@@ -355,16 +349,16 @@
 	if *flagFieldTrack == "" {
 		return
 	}
-	s := ctxt.Syms.Lookup(*flagFieldTrack, 0)
-	if !s.Attr.Reachable() {
+	s := ctxt.Syms.ROLookup(*flagFieldTrack, 0)
+	if s == nil || !s.Attr.Reachable() {
 		return
 	}
+	s.Type = sym.SDATA
 	addstrdata(ctxt, *flagFieldTrack, buf.String())
-	s.Type = SDATA
 }
 
 func (ctxt *Link) addexport() {
-	if Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		return
 	}
 
diff --git a/src/cmd/link/internal/ld/ld.go b/src/cmd/link/internal/ld/ld.go
index fc41372..896e1c8 100644
--- a/src/cmd/link/internal/ld/ld.go
+++ b/src/cmd/link/internal/ld/ld.go
@@ -32,6 +32,7 @@
 package ld
 
 import (
+	"cmd/link/internal/sym"
 	"io/ioutil"
 	"log"
 	"os"
@@ -86,39 +87,55 @@
 	}
 }
 
-func addlib(ctxt *Link, src string, obj string, pathname string) *Library {
-	name := path.Clean(pathname)
+func pkgname(ctxt *Link, lib string) string {
+	name := path.Clean(lib)
+
+	// When using importcfg, we have the final package name.
+	if ctxt.PackageFile != nil {
+		return name
+	}
 
 	// runtime.a -> runtime, runtime.6 -> runtime
 	pkg := name
 	if len(pkg) >= 2 && pkg[len(pkg)-2] == '.' {
 		pkg = pkg[:len(pkg)-2]
 	}
+	return pkg
+}
 
-	// already loaded?
-	if l := ctxt.LibraryByPkg[pkg]; l != nil {
-		return l
-	}
+func findlib(ctxt *Link, lib string) (string, bool) {
+	name := path.Clean(lib)
 
 	var pname string
 	isshlib := false
 
-	if *FlagLinkshared && ctxt.PackageShlib[name] != "" {
+	if ctxt.linkShared && ctxt.PackageShlib[name] != "" {
 		pname = ctxt.PackageShlib[name]
 		isshlib = true
 	} else if ctxt.PackageFile != nil {
 		pname = ctxt.PackageFile[name]
 		if pname == "" {
 			ctxt.Logf("cannot find package %s (using -importcfg)\n", name)
-			return nil
+			return "", false
 		}
 	} else {
 		if filepath.IsAbs(name) {
 			pname = name
 		} else {
+			pkg := pkgname(ctxt, lib)
+			// Add .a if needed; the new -importcfg modes
+			// do not put .a into the package name anymore.
+			// This only matters when people try to mix
+			// compiles using -importcfg with links not using -importcfg,
+			// such as when running quick things like
+			// 'go tool compile x.go && go tool link x.o'
+			// by hand against a standard library built using -importcfg.
+			if !strings.HasSuffix(name, ".a") && !strings.HasSuffix(name, ".o") {
+				name += ".a"
+			}
 			// try dot, -L "libdir", and then goroot.
 			for _, dir := range ctxt.Libdir {
-				if *FlagLinkshared {
+				if ctxt.linkShared {
 					pname = dir + "/" + pkg + ".shlibname"
 					if _, err := os.Stat(pname); err == nil {
 						isshlib = true
@@ -134,6 +151,19 @@
 		pname = path.Clean(pname)
 	}
 
+	return pname, isshlib
+}
+
+func addlib(ctxt *Link, src string, obj string, lib string) *sym.Library {
+	pkg := pkgname(ctxt, lib)
+
+	// already loaded?
+	if l := ctxt.LibraryByPkg[pkg]; l != nil {
+		return l
+	}
+
+	pname, isshlib := findlib(ctxt, lib)
+
 	if ctxt.Debugvlog > 1 {
 		ctxt.Logf("%5.2f addlib: %s %s pulls in %s isshlib %v\n", elapsed(), obj, src, pname, isshlib)
 	}
@@ -150,29 +180,33 @@
  *	objref: object file referring to package
  *	file: object file, e.g., /home/rsc/go/pkg/container/vector.a
  *	pkg: package import path, e.g. container/vector
+ *	shlib: path to shared library, or .shlibname file holding path
  */
-func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlibnamefile string) *Library {
+func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlib string) *sym.Library {
 	if l := ctxt.LibraryByPkg[pkg]; l != nil {
 		return l
 	}
 
 	if ctxt.Debugvlog > 1 {
-		ctxt.Logf("%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s shlibnamefile: %s\n", Cputime(), srcref, objref, file, pkg, shlibnamefile)
+		ctxt.Logf("%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s shlib: %s\n", Cputime(), srcref, objref, file, pkg, shlib)
 	}
 
-	l := &Library{}
+	l := &sym.Library{}
 	ctxt.LibraryByPkg[pkg] = l
 	ctxt.Library = append(ctxt.Library, l)
 	l.Objref = objref
 	l.Srcref = srcref
 	l.File = file
 	l.Pkg = pkg
-	if shlibnamefile != "" {
-		shlibbytes, err := ioutil.ReadFile(shlibnamefile)
-		if err != nil {
-			Errorf(nil, "cannot read %s: %v", shlibnamefile, err)
+	if shlib != "" {
+		if strings.HasSuffix(shlib, ".shlibname") {
+			data, err := ioutil.ReadFile(shlib)
+			if err != nil {
+				Errorf(nil, "cannot read %s: %v", shlib, err)
+			}
+			shlib = strings.TrimSpace(string(data))
 		}
-		l.Shlib = strings.TrimSpace(string(shlibbytes))
+		l.Shlib = shlib
 	}
 	return l
 }
diff --git a/src/cmd/link/internal/ld/ldelf.go b/src/cmd/link/internal/ld/ldelf.go
deleted file mode 100644
index d4f9fc4..0000000
--- a/src/cmd/link/internal/ld/ldelf.go
+++ /dev/null
@@ -1,1224 +0,0 @@
-package ld
-
-import (
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"log"
-	"sort"
-	"strings"
-)
-
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-	Copyright © 2004 Russ Cox.
-	Portions Copyright © 2008-2010 Google Inc.
-	Portions Copyright © 2010 The Go Authors.
-
-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.
-*/
-const (
-	ElfClassNone = 0
-	ElfClass32   = 1
-	ElfClass64   = 2
-)
-
-const (
-	ElfDataNone = 0
-	ElfDataLsb  = 1
-	ElfDataMsb  = 2
-)
-
-const (
-	ElfTypeNone         = 0
-	ElfTypeRelocatable  = 1
-	ElfTypeExecutable   = 2
-	ElfTypeSharedObject = 3
-	ElfTypeCore         = 4
-)
-
-const (
-	ElfMachNone        = 0
-	ElfMach32100       = 1
-	ElfMachSparc       = 2
-	ElfMach386         = 3
-	ElfMach68000       = 4
-	ElfMach88000       = 5
-	ElfMach486         = 6
-	ElfMach860         = 7
-	ElfMachMips        = 8
-	ElfMachS370        = 9
-	ElfMachMipsLe      = 10
-	ElfMachParisc      = 15
-	ElfMachVpp500      = 17
-	ElfMachSparc32Plus = 18
-	ElfMach960         = 19
-	ElfMachPower       = 20
-	ElfMachPower64     = 21
-	ElfMachS390        = 22
-	ElfMachV800        = 36
-	ElfMachFr20        = 37
-	ElfMachRh32        = 38
-	ElfMachRce         = 39
-	ElfMachArm         = 40
-	ElfMachAlpha       = 41
-	ElfMachSH          = 42
-	ElfMachSparc9      = 43
-	ElfMachAmd64       = 62
-	ElfMachArm64       = 183
-)
-
-const (
-	ElfAbiNone     = 0
-	ElfAbiSystemV  = 0
-	ElfAbiHPUX     = 1
-	ElfAbiNetBSD   = 2
-	ElfAbiLinux    = 3
-	ElfAbiSolaris  = 6
-	ElfAbiAix      = 7
-	ElfAbiIrix     = 8
-	ElfAbiFreeBSD  = 9
-	ElfAbiTru64    = 10
-	ElfAbiModesto  = 11
-	ElfAbiOpenBSD  = 12
-	ElfAbiARM      = 97
-	ElfAbiEmbedded = 255
-)
-
-const (
-	ElfSectNone      = 0
-	ElfSectProgbits  = 1
-	ElfSectSymtab    = 2
-	ElfSectStrtab    = 3
-	ElfSectRela      = 4
-	ElfSectHash      = 5
-	ElfSectDynamic   = 6
-	ElfSectNote      = 7
-	ElfSectNobits    = 8
-	ElfSectRel       = 9
-	ElfSectShlib     = 10
-	ElfSectDynsym    = 11
-	ElfSectFlagWrite = 0x1
-	ElfSectFlagAlloc = 0x2
-	ElfSectFlagExec  = 0x4
-)
-
-const (
-	ElfSymBindLocal  = 0
-	ElfSymBindGlobal = 1
-	ElfSymBindWeak   = 2
-)
-
-const (
-	ElfSymTypeNone    = 0
-	ElfSymTypeObject  = 1
-	ElfSymTypeFunc    = 2
-	ElfSymTypeSection = 3
-	ElfSymTypeFile    = 4
-	ElfSymTypeCommon  = 5
-	ElfSymTypeTLS     = 6
-)
-
-const (
-	ElfSymShnNone   = 0
-	ElfSymShnAbs    = 0xFFF1
-	ElfSymShnCommon = 0xFFF2
-)
-
-const (
-	ElfProgNone      = 0
-	ElfProgLoad      = 1
-	ElfProgDynamic   = 2
-	ElfProgInterp    = 3
-	ElfProgNote      = 4
-	ElfProgShlib     = 5
-	ElfProgPhdr      = 6
-	ElfProgFlagExec  = 0x1
-	ElfProgFlagWrite = 0x2
-	ElfProgFlagRead  = 0x4
-)
-
-const (
-	ElfNotePrStatus     = 1
-	ElfNotePrFpreg      = 2
-	ElfNotePrPsinfo     = 3
-	ElfNotePrTaskstruct = 4
-	ElfNotePrAuxv       = 6
-	ElfNotePrXfpreg     = 0x46e62b7f
-)
-
-type ElfHdrBytes struct {
-	Ident     [16]uint8
-	Type      [2]uint8
-	Machine   [2]uint8
-	Version   [4]uint8
-	Entry     [4]uint8
-	Phoff     [4]uint8
-	Shoff     [4]uint8
-	Flags     [4]uint8
-	Ehsize    [2]uint8
-	Phentsize [2]uint8
-	Phnum     [2]uint8
-	Shentsize [2]uint8
-	Shnum     [2]uint8
-	Shstrndx  [2]uint8
-}
-
-type ElfSectBytes struct {
-	Name    [4]uint8
-	Type    [4]uint8
-	Flags   [4]uint8
-	Addr    [4]uint8
-	Off     [4]uint8
-	Size    [4]uint8
-	Link    [4]uint8
-	Info    [4]uint8
-	Align   [4]uint8
-	Entsize [4]uint8
-}
-
-type ElfProgBytes struct {
-}
-
-type ElfSymBytes struct {
-	Name  [4]uint8
-	Value [4]uint8
-	Size  [4]uint8
-	Info  uint8
-	Other uint8
-	Shndx [2]uint8
-}
-
-type ElfHdrBytes64 struct {
-	Ident     [16]uint8
-	Type      [2]uint8
-	Machine   [2]uint8
-	Version   [4]uint8
-	Entry     [8]uint8
-	Phoff     [8]uint8
-	Shoff     [8]uint8
-	Flags     [4]uint8
-	Ehsize    [2]uint8
-	Phentsize [2]uint8
-	Phnum     [2]uint8
-	Shentsize [2]uint8
-	Shnum     [2]uint8
-	Shstrndx  [2]uint8
-}
-
-type ElfSectBytes64 struct {
-	Name    [4]uint8
-	Type    [4]uint8
-	Flags   [8]uint8
-	Addr    [8]uint8
-	Off     [8]uint8
-	Size    [8]uint8
-	Link    [4]uint8
-	Info    [4]uint8
-	Align   [8]uint8
-	Entsize [8]uint8
-}
-
-type ElfProgBytes64 struct {
-}
-
-type ElfSymBytes64 struct {
-	Name  [4]uint8
-	Info  uint8
-	Other uint8
-	Shndx [2]uint8
-	Value [8]uint8
-	Size  [8]uint8
-}
-
-type ElfSect struct {
-	name    string
-	nameoff uint32
-	type_   uint32
-	flags   uint64
-	addr    uint64
-	off     uint64
-	size    uint64
-	link    uint32
-	info    uint32
-	align   uint64
-	entsize uint64
-	base    []byte
-	sym     *Symbol
-}
-
-type ElfObj struct {
-	f         *bio.Reader
-	base      int64 // offset in f where ELF begins
-	length    int64 // length of ELF
-	is64      int
-	name      string
-	e         binary.ByteOrder
-	sect      []ElfSect
-	nsect     uint
-	shstrtab  string
-	nsymtab   int
-	symtab    *ElfSect
-	symstr    *ElfSect
-	type_     uint32
-	machine   uint32
-	version   uint32
-	entry     uint64
-	phoff     uint64
-	shoff     uint64
-	flags     uint32
-	ehsize    uint32
-	phentsize uint32
-	phnum     uint32
-	shentsize uint32
-	shnum     uint32
-	shstrndx  uint32
-}
-
-type ElfSym struct {
-	name  string
-	value uint64
-	size  uint64
-	bind  uint8
-	type_ uint8
-	other uint8
-	shndx uint16
-	sym   *Symbol
-}
-
-var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
-
-const (
-	TagFile               = 1
-	TagCPUName            = 4
-	TagCPURawName         = 5
-	TagCompatibility      = 32
-	TagNoDefaults         = 64
-	TagAlsoCompatibleWith = 65
-	TagABIVFPArgs         = 28
-)
-
-type elfAttribute struct {
-	tag  uint64
-	sval string
-	ival uint64
-}
-
-type elfAttributeList struct {
-	data []byte
-	err  error
-}
-
-func (a *elfAttributeList) string() string {
-	if a.err != nil {
-		return ""
-	}
-	nul := bytes.IndexByte(a.data, 0)
-	if nul < 0 {
-		a.err = io.EOF
-		return ""
-	}
-	s := string(a.data[:nul])
-	a.data = a.data[nul+1:]
-	return s
-}
-
-func (a *elfAttributeList) uleb128() uint64 {
-	if a.err != nil {
-		return 0
-	}
-	v, size := binary.Uvarint(a.data)
-	a.data = a.data[size:]
-	return v
-}
-
-// Read an elfAttribute from the list following the rules used on ARM systems.
-func (a *elfAttributeList) armAttr() elfAttribute {
-	attr := elfAttribute{tag: a.uleb128()}
-	switch {
-	case attr.tag == TagCompatibility:
-		attr.ival = a.uleb128()
-		attr.sval = a.string()
-
-	case attr.tag == 64: // Tag_nodefaults has no argument
-
-	case attr.tag == 65: // Tag_also_compatible_with
-		// Not really, but we don't actually care about this tag.
-		attr.sval = a.string()
-
-	// Tag with string argument
-	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
-		attr.sval = a.string()
-
-	default: // Tag with integer argument
-		attr.ival = a.uleb128()
-	}
-	return attr
-}
-
-func (a *elfAttributeList) done() bool {
-	if a.err != nil || len(a.data) == 0 {
-		return true
-	}
-	return false
-}
-
-// Look for the attribute that indicates the object uses the hard-float ABI (a
-// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
-// format used means that we have to parse all of the file-level attributes to
-// find the one we are looking for. This format is slightly documented in "ELF
-// for the ARM Architecture" but mostly this is derived from reading the source
-// to gold and readelf.
-func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) {
-	// We assume the soft-float ABI unless we see a tag indicating otherwise.
-	if ehdr.flags == 0x5000002 {
-		ehdr.flags = 0x5000202
-	}
-	if data[0] != 'A' {
-		// TODO(dfc) should this be ctxt.Diag ?
-		ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0])
-		return
-	}
-	data = data[1:]
-	for len(data) != 0 {
-		sectionlength := e.Uint32(data)
-		sectiondata := data[4:sectionlength]
-		data = data[sectionlength:]
-
-		nulIndex := bytes.IndexByte(sectiondata, 0)
-		if nulIndex < 0 {
-			// TODO(dfc) should this be ctxt.Diag ?
-			ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
-			return
-		}
-		name := string(sectiondata[:nulIndex])
-		sectiondata = sectiondata[nulIndex+1:]
-
-		if name != "aeabi" {
-			continue
-		}
-		for len(sectiondata) != 0 {
-			subsectiontag, sz := binary.Uvarint(sectiondata)
-			subsectionsize := e.Uint32(sectiondata[sz:])
-			subsectiondata := sectiondata[sz+4 : subsectionsize]
-			sectiondata = sectiondata[subsectionsize:]
-
-			if subsectiontag == TagFile {
-				attrList := elfAttributeList{data: subsectiondata}
-				for !attrList.done() {
-					attr := attrList.armAttr()
-					if attr.tag == TagABIVFPArgs && attr.ival == 1 {
-						ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
-					}
-				}
-				if attrList.err != nil {
-					// TODO(dfc) should this be ctxt.Diag ?
-					ctxt.Logf("could not parse .ARM.attributes\n")
-				}
-			}
-		}
-	}
-}
-
-func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%5.2f ldelf %s\n", Cputime(), pn)
-	}
-
-	localSymVersion := ctxt.Syms.IncVersion()
-	base := f.Offset()
-
-	var add uint64
-	var e binary.ByteOrder
-	var elfobj *ElfObj
-	var flag int
-	var hdr *ElfHdrBytes
-	var hdrbuf [64]uint8
-	var info uint64
-	var is64 int
-	var j int
-	var n int
-	var name string
-	var p []byte
-	var r []Reloc
-	var rela int
-	var rp *Reloc
-	var rsect *ElfSect
-	var s *Symbol
-	var sect *ElfSect
-	var sym ElfSym
-	var symbols []*Symbol
-	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
-		Errorf(nil, "%s: malformed elf file: %v", pn, err)
-		return
-	}
-	hdr = new(ElfHdrBytes)
-	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
-	if string(hdr.Ident[:4]) != "\x7FELF" {
-		Errorf(nil, "%s: malformed elf file", pn)
-		return
-	}
-	switch hdr.Ident[5] {
-	case ElfDataLsb:
-		e = binary.LittleEndian
-
-	case ElfDataMsb:
-		e = binary.BigEndian
-
-	default:
-		Errorf(nil, "%s: malformed elf file", pn)
-		return
-	}
-
-	// read header
-	elfobj = new(ElfObj)
-
-	elfobj.e = e
-	elfobj.f = f
-	elfobj.base = base
-	elfobj.length = length
-	elfobj.name = pn
-
-	is64 = 0
-	if hdr.Ident[4] == ElfClass64 {
-		is64 = 1
-		hdr := new(ElfHdrBytes64)
-		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
-		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
-		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
-		elfobj.version = e.Uint32(hdr.Version[:])
-		elfobj.phoff = e.Uint64(hdr.Phoff[:])
-		elfobj.shoff = e.Uint64(hdr.Shoff[:])
-		elfobj.flags = e.Uint32(hdr.Flags[:])
-		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
-		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
-		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
-		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
-		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
-		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
-	} else {
-		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
-		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
-		elfobj.version = e.Uint32(hdr.Version[:])
-		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
-		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
-		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
-		elfobj.flags = e.Uint32(hdr.Flags[:])
-		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
-		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
-		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
-		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
-		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
-		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
-	}
-
-	elfobj.is64 = is64
-
-	if v := uint32(hdr.Ident[6]); v != elfobj.version {
-		Errorf(nil, "%s: malformed elf version: got %d, want %d", pn, v, elfobj.version)
-		return
-	}
-
-	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
-		Errorf(nil, "%s: elf but not elf relocatable object", pn)
-		return
-	}
-
-	switch SysArch.Family {
-	default:
-		Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
-		return
-
-	case sys.MIPS:
-		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
-			Errorf(nil, "%s: elf object but not mips", pn)
-			return
-		}
-
-	case sys.MIPS64:
-		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
-			Errorf(nil, "%s: elf object but not mips64", pn)
-			return
-		}
-
-	case sys.ARM:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
-			Errorf(nil, "%s: elf object but not arm", pn)
-			return
-		}
-
-	case sys.AMD64:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
-			Errorf(nil, "%s: elf object but not amd64", pn)
-			return
-		}
-
-	case sys.ARM64:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
-			Errorf(nil, "%s: elf object but not arm64", pn)
-			return
-		}
-
-	case sys.I386:
-		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
-			Errorf(nil, "%s: elf object but not 386", pn)
-			return
-		}
-
-	case sys.PPC64:
-		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
-			Errorf(nil, "%s: elf object but not ppc64", pn)
-			return
-		}
-
-	case sys.S390X:
-		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
-			Errorf(nil, "%s: elf object but not s390x", pn)
-			return
-		}
-	}
-
-	// load section list into memory.
-	elfobj.sect = make([]ElfSect, elfobj.shnum)
-
-	elfobj.nsect = uint(elfobj.shnum)
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
-			Errorf(nil, "%s: malformed elf file", pn)
-			return
-		}
-		sect = &elfobj.sect[i]
-		if is64 != 0 {
-			var b ElfSectBytes64
-
-			if err := binary.Read(f, e, &b); err != nil {
-				Errorf(nil, "%s: malformed elf file: %v", pn, err)
-				return
-			}
-
-			sect.nameoff = e.Uint32(b.Name[:])
-			sect.type_ = e.Uint32(b.Type[:])
-			sect.flags = e.Uint64(b.Flags[:])
-			sect.addr = e.Uint64(b.Addr[:])
-			sect.off = e.Uint64(b.Off[:])
-			sect.size = e.Uint64(b.Size[:])
-			sect.link = e.Uint32(b.Link[:])
-			sect.info = e.Uint32(b.Info[:])
-			sect.align = e.Uint64(b.Align[:])
-			sect.entsize = e.Uint64(b.Entsize[:])
-		} else {
-			var b ElfSectBytes
-
-			if err := binary.Read(f, e, &b); err != nil {
-				Errorf(nil, "%s: malformed elf file: %v", pn, err)
-				return
-			}
-
-			sect.nameoff = e.Uint32(b.Name[:])
-			sect.type_ = e.Uint32(b.Type[:])
-			sect.flags = uint64(e.Uint32(b.Flags[:]))
-			sect.addr = uint64(e.Uint32(b.Addr[:]))
-			sect.off = uint64(e.Uint32(b.Off[:]))
-			sect.size = uint64(e.Uint32(b.Size[:]))
-			sect.link = e.Uint32(b.Link[:])
-			sect.info = e.Uint32(b.Info[:])
-			sect.align = uint64(e.Uint32(b.Align[:]))
-			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
-		}
-	}
-
-	// read section string table and translate names
-	if elfobj.shstrndx >= uint32(elfobj.nsect) {
-		Errorf(nil, "%s: malformed elf file: shstrndx out of range %d >= %d", pn, elfobj.shstrndx, elfobj.nsect)
-		return
-	}
-
-	sect = &elfobj.sect[elfobj.shstrndx]
-	if err := elfmap(elfobj, sect); err != nil {
-		Errorf(nil, "%s: malformed elf file: %v", pn, err)
-		return
-	}
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		if elfobj.sect[i].nameoff != 0 {
-			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
-		}
-	}
-
-	// load string table for symbols into memory.
-	elfobj.symtab = section(elfobj, ".symtab")
-
-	if elfobj.symtab == nil {
-		// our work is done here - no symbols means nothing can refer to this file
-		return
-	}
-
-	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
-		Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn)
-		return
-	}
-
-	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
-	if is64 != 0 {
-		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
-	} else {
-		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
-	}
-
-	if err := elfmap(elfobj, elfobj.symtab); err != nil {
-		Errorf(nil, "%s: malformed elf file: %v", pn, err)
-		return
-	}
-	if err := elfmap(elfobj, elfobj.symstr); err != nil {
-		Errorf(nil, "%s: malformed elf file: %v", pn, err)
-		return
-	}
-
-	// load text and data segments into memory.
-	// they are not as small as the section lists, but we'll need
-	// the memory anyway for the symbol images, so we might
-	// as well use one large chunk.
-
-	// create symbols for elfmapped sections
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		sect = &elfobj.sect[i]
-		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
-			if err := elfmap(elfobj, sect); err != nil {
-				Errorf(nil, "%s: malformed elf file: %v", pn, err)
-				return
-			}
-			parseArmAttributes(ctxt, e, sect.base[:sect.size])
-		}
-		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
-			continue
-		}
-		if sect.type_ != ElfSectNobits {
-			if err := elfmap(elfobj, sect); err != nil {
-				Errorf(nil, "%s: malformed elf file: %v", pn, err)
-				return
-			}
-		}
-
-		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
-		s = ctxt.Syms.Lookup(name, localSymVersion)
-
-		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
-		default:
-			Errorf(nil, "%s: unexpected flags for ELF section %s", pn, sect.name)
-			return
-
-		case ElfSectFlagAlloc:
-			s.Type = SRODATA
-
-		case ElfSectFlagAlloc + ElfSectFlagWrite:
-			if sect.type_ == ElfSectNobits {
-				s.Type = SNOPTRBSS
-			} else {
-				s.Type = SNOPTRDATA
-			}
-
-		case ElfSectFlagAlloc + ElfSectFlagExec:
-			s.Type = STEXT
-		}
-
-		if sect.name == ".got" || sect.name == ".toc" {
-			s.Type = SELFGOT
-		}
-		if sect.type_ == ElfSectProgbits {
-			s.P = sect.base
-			s.P = s.P[:sect.size]
-		}
-
-		s.Size = int64(sect.size)
-		s.Align = int32(sect.align)
-		sect.sym = s
-	}
-
-	// enter sub-symbols into symbol table.
-	// symbol 0 is the null symbol.
-	symbols = make([]*Symbol, elfobj.nsymtab)
-
-	for i := 1; i < elfobj.nsymtab; i++ {
-		if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
-			Errorf(nil, "%s: malformed elf file: %v", pn, err)
-			return
-		}
-		symbols[i] = sym.sym
-		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
-			continue
-		}
-		if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
-			s = sym.sym
-			if uint64(s.Size) < sym.size {
-				s.Size = int64(sym.size)
-			}
-			if s.Type == 0 || s.Type == SXREF {
-				s.Type = SNOPTRBSS
-			}
-			continue
-		}
-
-		if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
-			continue
-		}
-
-		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
-		if sym.sym == nil {
-			continue
-		}
-		sect = &elfobj.sect[sym.shndx]
-		if sect.sym == nil {
-			if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
-				continue
-			}
-
-			if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
-				// This reportedly happens with clang 3.7 on ARM.
-				// See issue 13139.
-				continue
-			}
-
-			if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
-				continue
-			}
-			Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_)
-			continue
-		}
-
-		s = sym.sym
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
-		}
-
-		s.Sub = sect.sym.Sub
-		sect.sym.Sub = s
-		s.Type = sect.sym.Type | s.Type&^SMASK | SSUB
-		if !s.Attr.CgoExportDynamic() {
-			s.Dynimplib = "" // satisfy dynimport
-		}
-		s.Value = int64(sym.value)
-		s.Size = int64(sym.size)
-		s.Outer = sect.sym
-		if sect.sym.Type == STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				Errorf(s, "%s: duplicate symbol definition", pn)
-			}
-			s.Attr |= AttrExternal
-		}
-
-		if elfobj.machine == ElfMachPower64 {
-			flag = int(sym.other) >> 5
-			if 2 <= flag && flag <= 6 {
-				s.Localentry = 1 << uint(flag-2)
-			} else if flag == 7 {
-				Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other)
-			}
-		}
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		s = elfobj.sect[i].sym
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = listsort(s.Sub)
-		}
-		if s.Type == STEXT {
-			if s.Attr.OnList() {
-				log.Fatalf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= AttrOnList
-			ctxt.Textp = append(ctxt.Textp, s)
-			for s = s.Sub; s != nil; s = s.Sub {
-				if s.Attr.OnList() {
-					log.Fatalf("symbol %s listed multiple times", s.Name)
-				}
-				s.Attr |= AttrOnList
-				ctxt.Textp = append(ctxt.Textp, s)
-			}
-		}
-	}
-
-	// load relocations
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		rsect = &elfobj.sect[i]
-		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
-			continue
-		}
-		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
-			continue
-		}
-		sect = &elfobj.sect[rsect.info]
-		if err := elfmap(elfobj, rsect); err != nil {
-			Errorf(nil, "%s: malformed elf file: %v", pn, err)
-			return
-		}
-		rela = 0
-		if rsect.type_ == ElfSectRela {
-			rela = 1
-		}
-		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
-		r = make([]Reloc, n)
-		p = rsect.base
-		for j = 0; j < n; j++ {
-			add = 0
-			rp = &r[j]
-			if is64 != 0 {
-				// 64-bit rel/rela
-				rp.Off = int32(e.Uint64(p))
-
-				p = p[8:]
-				info = e.Uint64(p)
-				p = p[8:]
-				if rela != 0 {
-					add = e.Uint64(p)
-					p = p[8:]
-				}
-			} else {
-				// 32-bit rel/rela
-				rp.Off = int32(e.Uint32(p))
-
-				p = p[4:]
-				info = uint64(e.Uint32(p))
-				info = info>>8<<32 | info&0xff // convert to 64-bit info
-				p = p[4:]
-				if rela != 0 {
-					add = uint64(e.Uint32(p))
-					p = p[4:]
-				}
-			}
-
-			if info&0xffffffff == 0 { // skip R_*_NONE relocation
-				j--
-				n--
-				continue
-			}
-
-			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
-				rp.Sym = nil
-			} else {
-				if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
-					Errorf(nil, "%s: malformed elf file: %v", pn, err)
-					return
-				}
-				sym.sym = symbols[info>>32]
-				if sym.sym == nil {
-					Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
-					return
-				}
-
-				rp.Sym = sym.sym
-			}
-
-			rp.Type = 256 + objabi.RelocType(info)
-			rp.Siz = relSize(ctxt, pn, uint32(info))
-			if rela != 0 {
-				rp.Add = int64(add)
-			} else {
-				// load addend from image
-				if rp.Siz == 4 {
-					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
-				} else if rp.Siz == 8 {
-					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
-				} else {
-					Errorf(nil, "invalid rela size %d", rp.Siz)
-				}
-			}
-
-			if rp.Siz == 2 {
-				rp.Add = int64(int16(rp.Add))
-			}
-			if rp.Siz == 4 {
-				rp.Add = int64(int32(rp.Add))
-			}
-		}
-
-		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
-		sort.Sort(rbyoff(r[:n]))
-		// just in case
-
-		s = sect.sym
-		s.R = r
-		s.R = s.R[:n]
-	}
-}
-
-func section(elfobj *ElfObj, name string) *ElfSect {
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
-			return &elfobj.sect[i]
-		}
-	}
-	return nil
-}
-
-func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
-	if sect.base != nil {
-		return nil
-	}
-
-	if sect.off+sect.size > uint64(elfobj.length) {
-		err = fmt.Errorf("elf section past end of file")
-		return err
-	}
-
-	sect.base = make([]byte, sect.size)
-	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
-		return fmt.Errorf("short read: seek not successful")
-	}
-	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
-		return fmt.Errorf("short read: %v", err)
-	}
-
-	return nil
-}
-
-func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
-	if i >= elfobj.nsymtab || i < 0 {
-		err = fmt.Errorf("invalid elf symbol index")
-		return err
-	}
-
-	if i == 0 {
-		Errorf(nil, "readym: read null symbol!")
-	}
-
-	if elfobj.is64 != 0 {
-		b := new(ElfSymBytes64)
-		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
-		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
-		sym.value = elfobj.e.Uint64(b.Value[:])
-		sym.size = elfobj.e.Uint64(b.Size[:])
-		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
-		sym.bind = b.Info >> 4
-		sym.type_ = b.Info & 0xf
-		sym.other = b.Other
-	} else {
-		b := new(ElfSymBytes)
-		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
-		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
-		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
-		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
-		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
-		sym.bind = b.Info >> 4
-		sym.type_ = b.Info & 0xf
-		sym.other = b.Other
-	}
-
-	var s *Symbol
-	if sym.name == "_GLOBAL_OFFSET_TABLE_" {
-		sym.name = ".got"
-	}
-	if sym.name == ".TOC." {
-		// Magic symbol on ppc64.  Will be set to this object
-		// file's .got+0x8000.
-		sym.bind = ElfSymBindLocal
-	}
-
-	switch sym.type_ {
-	case ElfSymTypeSection:
-		s = elfobj.sect[sym.shndx].sym
-
-	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
-		switch sym.bind {
-		case ElfSymBindGlobal:
-			if needSym != 0 {
-				s = ctxt.Syms.Lookup(sym.name, 0)
-
-				// for global scoped hidden symbols we should insert it into
-				// symbol hash table, but mark them as hidden.
-				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
-				// workaround that we set dupok.
-				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
-				// set dupok generally. See http://codereview.appspot.com/5823055/
-				// comment #5 for details.
-				if s != nil && sym.other == 2 {
-					s.Type |= SHIDDEN
-					s.Attr |= AttrDuplicateOK
-				}
-			}
-
-		case ElfSymBindLocal:
-			if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
-				// binutils for arm generate these mapping
-				// symbols, ignore these
-				break
-			}
-
-			if sym.name == ".TOC." {
-				// We need to be able to look this up,
-				// so put it in the hash table.
-				if needSym != 0 {
-					s = ctxt.Syms.Lookup(sym.name, localSymVersion)
-					s.Type |= SHIDDEN
-				}
-
-				break
-			}
-
-			if needSym != 0 {
-				// local names and hidden global names are unique
-				// and should only be referenced by their index, not name, so we
-				// don't bother to add them into the hash table
-				s = ctxt.Syms.newsym(sym.name, localSymVersion)
-
-				s.Type |= SHIDDEN
-			}
-
-		case ElfSymBindWeak:
-			if needSym != 0 {
-				s = ctxt.Syms.Lookup(sym.name, 0)
-				if sym.other == 2 {
-					s.Type |= SHIDDEN
-				}
-			}
-
-		default:
-			err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
-			return err
-		}
-	}
-
-	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
-		s.Type = SXREF
-	}
-	sym.sym = s
-
-	return nil
-}
-
-type rbyoff []Reloc
-
-func (x rbyoff) Len() int {
-	return len(x)
-}
-
-func (x rbyoff) Swap(i, j int) {
-	x[i], x[j] = x[j], x[i]
-}
-
-func (x rbyoff) Less(i, j int) bool {
-	a := &x[i]
-	b := &x[j]
-	if a.Off < b.Off {
-		return true
-	}
-	if a.Off > b.Off {
-		return false
-	}
-	return false
-}
-
-func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
-	// TODO(mdempsky): Replace this with a struct-valued switch statement
-	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
-	// performance.
-
-	const (
-		AMD64 = uint32(sys.AMD64)
-		ARM   = uint32(sys.ARM)
-		I386  = uint32(sys.I386)
-		PPC64 = uint32(sys.PPC64)
-		S390X = uint32(sys.S390X)
-	)
-
-	switch uint32(SysArch.Family) | elftype<<24 {
-	default:
-		Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
-		fallthrough
-
-	case S390X | R_390_8<<24:
-		return 1
-
-	case PPC64 | R_PPC64_TOC16<<24,
-		PPC64 | R_PPC64_TOC16_LO<<24,
-		PPC64 | R_PPC64_TOC16_HI<<24,
-		PPC64 | R_PPC64_TOC16_HA<<24,
-		PPC64 | R_PPC64_TOC16_DS<<24,
-		PPC64 | R_PPC64_TOC16_LO_DS<<24,
-		PPC64 | R_PPC64_REL16_LO<<24,
-		PPC64 | R_PPC64_REL16_HI<<24,
-		PPC64 | R_PPC64_REL16_HA<<24,
-		S390X | R_390_16<<24,
-		S390X | R_390_GOT16<<24,
-		S390X | R_390_PC16<<24,
-		S390X | R_390_PC16DBL<<24,
-		S390X | R_390_PLT16DBL<<24:
-		return 2
-
-	case ARM | R_ARM_ABS32<<24,
-		ARM | R_ARM_GOT32<<24,
-		ARM | R_ARM_PLT32<<24,
-		ARM | R_ARM_GOTOFF<<24,
-		ARM | R_ARM_GOTPC<<24,
-		ARM | R_ARM_THM_PC22<<24,
-		ARM | R_ARM_REL32<<24,
-		ARM | R_ARM_CALL<<24,
-		ARM | R_ARM_V4BX<<24,
-		ARM | R_ARM_GOT_PREL<<24,
-		ARM | R_ARM_PC24<<24,
-		ARM | R_ARM_JUMP24<<24,
-		AMD64 | R_X86_64_PC32<<24,
-		AMD64 | R_X86_64_PLT32<<24,
-		AMD64 | R_X86_64_GOTPCREL<<24,
-		AMD64 | R_X86_64_GOTPCRELX<<24,
-		AMD64 | R_X86_64_REX_GOTPCRELX<<24,
-		I386 | R_386_32<<24,
-		I386 | R_386_PC32<<24,
-		I386 | R_386_GOT32<<24,
-		I386 | R_386_PLT32<<24,
-		I386 | R_386_GOTOFF<<24,
-		I386 | R_386_GOTPC<<24,
-		I386 | R_386_GOT32X<<24,
-		PPC64 | R_PPC64_REL24<<24,
-		PPC64 | R_PPC_REL32<<24,
-		S390X | R_390_32<<24,
-		S390X | R_390_PC32<<24,
-		S390X | R_390_GOT32<<24,
-		S390X | R_390_PLT32<<24,
-		S390X | R_390_PC32DBL<<24,
-		S390X | R_390_PLT32DBL<<24,
-		S390X | R_390_GOTPCDBL<<24,
-		S390X | R_390_GOTENT<<24:
-		return 4
-
-	case AMD64 | R_X86_64_64<<24,
-		PPC64 | R_PPC64_ADDR64<<24,
-		S390X | R_390_GLOB_DAT<<24,
-		S390X | R_390_RELATIVE<<24,
-		S390X | R_390_GOTOFF<<24,
-		S390X | R_390_GOTPC<<24,
-		S390X | R_390_64<<24,
-		S390X | R_390_PC64<<24,
-		S390X | R_390_GOT64<<24,
-		S390X | R_390_PLT64<<24:
-		return 8
-	}
-}
diff --git a/src/cmd/link/internal/ld/ldmacho.go b/src/cmd/link/internal/ld/ldmacho.go
deleted file mode 100644
index 7bfa67d..0000000
--- a/src/cmd/link/internal/ld/ldmacho.go
+++ /dev/null
@@ -1,904 +0,0 @@
-package ld
-
-import (
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"log"
-	"sort"
-)
-
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-	Copyright © 2004 Russ Cox.
-	Portions Copyright © 2008-2010 Google Inc.
-	Portions Copyright © 2010 The Go Authors.
-
-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.
-*/
-const (
-	N_EXT  = 0x01
-	N_TYPE = 0x1e
-	N_STAB = 0xe0
-)
-
-type ldMachoObj struct {
-	f          *bio.Reader
-	base       int64 // off in f where Mach-O begins
-	length     int64 // length of Mach-O
-	is64       bool
-	name       string
-	e          binary.ByteOrder
-	cputype    uint
-	subcputype uint
-	filetype   uint32
-	flags      uint32
-	cmd        []ldMachoCmd
-	ncmd       uint
-}
-
-type ldMachoCmd struct {
-	type_ int
-	off   uint32
-	size  uint32
-	seg   ldMachoSeg
-	sym   ldMachoSymtab
-	dsym  ldMachoDysymtab
-}
-
-type ldMachoSeg struct {
-	name     string
-	vmaddr   uint64
-	vmsize   uint64
-	fileoff  uint32
-	filesz   uint32
-	maxprot  uint32
-	initprot uint32
-	nsect    uint32
-	flags    uint32
-	sect     []ldMachoSect
-}
-
-type ldMachoSect struct {
-	name    string
-	segname string
-	addr    uint64
-	size    uint64
-	off     uint32
-	align   uint32
-	reloff  uint32
-	nreloc  uint32
-	flags   uint32
-	res1    uint32
-	res2    uint32
-	sym     *Symbol
-	rel     []ldMachoRel
-}
-
-type ldMachoRel struct {
-	addr      uint32
-	symnum    uint32
-	pcrel     uint8
-	length    uint8
-	extrn     uint8
-	type_     uint8
-	scattered uint8
-	value     uint32
-}
-
-type ldMachoSymtab struct {
-	symoff  uint32
-	nsym    uint32
-	stroff  uint32
-	strsize uint32
-	str     []byte
-	sym     []ldMachoSym
-}
-
-type ldMachoSym struct {
-	name    string
-	type_   uint8
-	sectnum uint8
-	desc    uint16
-	kind    int8
-	value   uint64
-	sym     *Symbol
-}
-
-type ldMachoDysymtab struct {
-	ilocalsym      uint32
-	nlocalsym      uint32
-	iextdefsym     uint32
-	nextdefsym     uint32
-	iundefsym      uint32
-	nundefsym      uint32
-	tocoff         uint32
-	ntoc           uint32
-	modtaboff      uint32
-	nmodtab        uint32
-	extrefsymoff   uint32
-	nextrefsyms    uint32
-	indirectsymoff uint32
-	nindirectsyms  uint32
-	extreloff      uint32
-	nextrel        uint32
-	locreloff      uint32
-	nlocrel        uint32
-	indir          []uint32
-}
-
-const (
-	LdMachoCpuVax         = 1
-	LdMachoCpu68000       = 6
-	LdMachoCpu386         = 7
-	LdMachoCpuAmd64       = 0x1000007
-	LdMachoCpuMips        = 8
-	LdMachoCpu98000       = 10
-	LdMachoCpuHppa        = 11
-	LdMachoCpuArm         = 12
-	LdMachoCpu88000       = 13
-	LdMachoCpuSparc       = 14
-	LdMachoCpu860         = 15
-	LdMachoCpuAlpha       = 16
-	LdMachoCpuPower       = 18
-	LdMachoCmdSegment     = 1
-	LdMachoCmdSymtab      = 2
-	LdMachoCmdSymseg      = 3
-	LdMachoCmdThread      = 4
-	LdMachoCmdDysymtab    = 11
-	LdMachoCmdSegment64   = 25
-	LdMachoFileObject     = 1
-	LdMachoFileExecutable = 2
-	LdMachoFileFvmlib     = 3
-	LdMachoFileCore       = 4
-	LdMachoFilePreload    = 5
-)
-
-func unpackcmd(p []byte, m *ldMachoObj, c *ldMachoCmd, type_ uint, sz uint) int {
-	e4 := m.e.Uint32
-	e8 := m.e.Uint64
-
-	c.type_ = int(type_)
-	c.size = uint32(sz)
-	switch type_ {
-	default:
-		return -1
-
-	case LdMachoCmdSegment:
-		if sz < 56 {
-			return -1
-		}
-		c.seg.name = cstring(p[8:24])
-		c.seg.vmaddr = uint64(e4(p[24:]))
-		c.seg.vmsize = uint64(e4(p[28:]))
-		c.seg.fileoff = e4(p[32:])
-		c.seg.filesz = e4(p[36:])
-		c.seg.maxprot = e4(p[40:])
-		c.seg.initprot = e4(p[44:])
-		c.seg.nsect = e4(p[48:])
-		c.seg.flags = e4(p[52:])
-		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
-		if uint32(sz) < 56+c.seg.nsect*68 {
-			return -1
-		}
-		p = p[56:]
-		var s *ldMachoSect
-		for i := 0; uint32(i) < c.seg.nsect; i++ {
-			s = &c.seg.sect[i]
-			s.name = cstring(p[0:16])
-			s.segname = cstring(p[16:32])
-			s.addr = uint64(e4(p[32:]))
-			s.size = uint64(e4(p[36:]))
-			s.off = e4(p[40:])
-			s.align = e4(p[44:])
-			s.reloff = e4(p[48:])
-			s.nreloc = e4(p[52:])
-			s.flags = e4(p[56:])
-			s.res1 = e4(p[60:])
-			s.res2 = e4(p[64:])
-			p = p[68:]
-		}
-
-	case LdMachoCmdSegment64:
-		if sz < 72 {
-			return -1
-		}
-		c.seg.name = cstring(p[8:24])
-		c.seg.vmaddr = e8(p[24:])
-		c.seg.vmsize = e8(p[32:])
-		c.seg.fileoff = uint32(e8(p[40:]))
-		c.seg.filesz = uint32(e8(p[48:]))
-		c.seg.maxprot = e4(p[56:])
-		c.seg.initprot = e4(p[60:])
-		c.seg.nsect = e4(p[64:])
-		c.seg.flags = e4(p[68:])
-		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
-		if uint32(sz) < 72+c.seg.nsect*80 {
-			return -1
-		}
-		p = p[72:]
-		var s *ldMachoSect
-		for i := 0; uint32(i) < c.seg.nsect; i++ {
-			s = &c.seg.sect[i]
-			s.name = cstring(p[0:16])
-			s.segname = cstring(p[16:32])
-			s.addr = e8(p[32:])
-			s.size = e8(p[40:])
-			s.off = e4(p[48:])
-			s.align = e4(p[52:])
-			s.reloff = e4(p[56:])
-			s.nreloc = e4(p[60:])
-			s.flags = e4(p[64:])
-			s.res1 = e4(p[68:])
-			s.res2 = e4(p[72:])
-
-			// p+76 is reserved
-			p = p[80:]
-		}
-
-	case LdMachoCmdSymtab:
-		if sz < 24 {
-			return -1
-		}
-		c.sym.symoff = e4(p[8:])
-		c.sym.nsym = e4(p[12:])
-		c.sym.stroff = e4(p[16:])
-		c.sym.strsize = e4(p[20:])
-
-	case LdMachoCmdDysymtab:
-		if sz < 80 {
-			return -1
-		}
-		c.dsym.ilocalsym = e4(p[8:])
-		c.dsym.nlocalsym = e4(p[12:])
-		c.dsym.iextdefsym = e4(p[16:])
-		c.dsym.nextdefsym = e4(p[20:])
-		c.dsym.iundefsym = e4(p[24:])
-		c.dsym.nundefsym = e4(p[28:])
-		c.dsym.tocoff = e4(p[32:])
-		c.dsym.ntoc = e4(p[36:])
-		c.dsym.modtaboff = e4(p[40:])
-		c.dsym.nmodtab = e4(p[44:])
-		c.dsym.extrefsymoff = e4(p[48:])
-		c.dsym.nextrefsyms = e4(p[52:])
-		c.dsym.indirectsymoff = e4(p[56:])
-		c.dsym.nindirectsyms = e4(p[60:])
-		c.dsym.extreloff = e4(p[64:])
-		c.dsym.nextrel = e4(p[68:])
-		c.dsym.locreloff = e4(p[72:])
-		c.dsym.nlocrel = e4(p[76:])
-	}
-
-	return 0
-}
-
-func macholoadrel(m *ldMachoObj, sect *ldMachoSect) int {
-	if sect.rel != nil || sect.nreloc == 0 {
-		return 0
-	}
-	rel := make([]ldMachoRel, sect.nreloc)
-	n := int(sect.nreloc * 8)
-	buf := make([]byte, n)
-	if m.f.Seek(m.base+int64(sect.reloff), 0) < 0 {
-		return -1
-	}
-	if _, err := io.ReadFull(m.f, buf); err != nil {
-		return -1
-	}
-	var p []byte
-	var r *ldMachoRel
-	var v uint32
-	for i := 0; uint32(i) < sect.nreloc; i++ {
-		r = &rel[i]
-		p = buf[i*8:]
-		r.addr = m.e.Uint32(p)
-
-		// TODO(rsc): Wrong interpretation for big-endian bitfields?
-		if r.addr&0x80000000 != 0 {
-			// scatterbrained relocation
-			r.scattered = 1
-
-			v = r.addr >> 24
-			r.addr &= 0xFFFFFF
-			r.type_ = uint8(v & 0xF)
-			v >>= 4
-			r.length = 1 << (v & 3)
-			v >>= 2
-			r.pcrel = uint8(v & 1)
-			r.value = m.e.Uint32(p[4:])
-		} else {
-			v = m.e.Uint32(p[4:])
-			r.symnum = v & 0xFFFFFF
-			v >>= 24
-			r.pcrel = uint8(v & 1)
-			v >>= 1
-			r.length = 1 << (v & 3)
-			v >>= 2
-			r.extrn = uint8(v & 1)
-			v >>= 1
-			r.type_ = uint8(v)
-		}
-	}
-
-	sect.rel = rel
-	return 0
-}
-
-func macholoaddsym(m *ldMachoObj, d *ldMachoDysymtab) int {
-	n := int(d.nindirectsyms)
-
-	p := make([]byte, n*4)
-	if m.f.Seek(m.base+int64(d.indirectsymoff), 0) < 0 {
-		return -1
-	}
-	if _, err := io.ReadFull(m.f, p); err != nil {
-		return -1
-	}
-
-	d.indir = make([]uint32, n)
-	for i := 0; i < n; i++ {
-		d.indir[i] = m.e.Uint32(p[4*i:])
-	}
-	return 0
-}
-
-func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
-	if symtab.sym != nil {
-		return 0
-	}
-
-	strbuf := make([]byte, symtab.strsize)
-	if m.f.Seek(m.base+int64(symtab.stroff), 0) < 0 {
-		return -1
-	}
-	if _, err := io.ReadFull(m.f, strbuf); err != nil {
-		return -1
-	}
-
-	symsize := 12
-	if m.is64 {
-		symsize = 16
-	}
-	n := int(symtab.nsym * uint32(symsize))
-	symbuf := make([]byte, n)
-	if m.f.Seek(m.base+int64(symtab.symoff), 0) < 0 {
-		return -1
-	}
-	if _, err := io.ReadFull(m.f, symbuf); err != nil {
-		return -1
-	}
-	sym := make([]ldMachoSym, symtab.nsym)
-	p := symbuf
-	var s *ldMachoSym
-	var v uint32
-	for i := 0; uint32(i) < symtab.nsym; i++ {
-		s = &sym[i]
-		v = m.e.Uint32(p)
-		if v >= symtab.strsize {
-			return -1
-		}
-		s.name = cstring(strbuf[v:])
-		s.type_ = p[4]
-		s.sectnum = p[5]
-		s.desc = m.e.Uint16(p[6:])
-		if m.is64 {
-			s.value = m.e.Uint64(p[8:])
-		} else {
-			s.value = uint64(m.e.Uint32(p[8:]))
-		}
-		p = p[symsize:]
-	}
-
-	symtab.str = strbuf
-	symtab.sym = sym
-	return 0
-}
-
-func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-	var err error
-	var j int
-	var is64 bool
-	var secaddr uint64
-	var hdr [7 * 4]uint8
-	var cmdp []byte
-	var dat []byte
-	var ncmd uint32
-	var cmdsz uint32
-	var ty uint32
-	var sz uint32
-	var off uint32
-	var m *ldMachoObj
-	var e binary.ByteOrder
-	var sect *ldMachoSect
-	var rel *ldMachoRel
-	var rpi int
-	var s *Symbol
-	var s1 *Symbol
-	var outer *Symbol
-	var c *ldMachoCmd
-	var symtab *ldMachoSymtab
-	var dsymtab *ldMachoDysymtab
-	var sym *ldMachoSym
-	var r []Reloc
-	var rp *Reloc
-	var name string
-
-	localSymVersion := ctxt.Syms.IncVersion()
-	base := f.Offset()
-	if _, err := io.ReadFull(f, hdr[:]); err != nil {
-		goto bad
-	}
-
-	if binary.BigEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
-		e = binary.BigEndian
-	} else if binary.LittleEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
-		e = binary.LittleEndian
-	} else {
-		err = fmt.Errorf("bad magic - not mach-o file")
-		goto bad
-	}
-
-	is64 = e.Uint32(hdr[:]) == 0xFEEDFACF
-	ncmd = e.Uint32(hdr[4*4:])
-	cmdsz = e.Uint32(hdr[5*4:])
-	if ncmd > 0x10000 || cmdsz >= 0x01000000 {
-		err = fmt.Errorf("implausible mach-o header ncmd=%d cmdsz=%d", ncmd, cmdsz)
-		goto bad
-	}
-
-	if is64 {
-		f.Seek(4, 1) // skip reserved word in header
-	}
-
-	m = new(ldMachoObj)
-
-	m.f = f
-	m.e = e
-	m.cputype = uint(e.Uint32(hdr[1*4:]))
-	m.subcputype = uint(e.Uint32(hdr[2*4:]))
-	m.filetype = e.Uint32(hdr[3*4:])
-	m.ncmd = uint(ncmd)
-	m.flags = e.Uint32(hdr[6*4:])
-	m.is64 = is64
-	m.base = base
-	m.length = length
-	m.name = pn
-
-	switch SysArch.Family {
-	default:
-		Errorf(nil, "%s: mach-o %s unimplemented", pn, SysArch.Name)
-		return
-
-	case sys.AMD64:
-		if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 {
-			Errorf(nil, "%s: mach-o object but not amd64", pn)
-			return
-		}
-
-	case sys.I386:
-		if e != binary.LittleEndian || m.cputype != LdMachoCpu386 {
-			Errorf(nil, "%s: mach-o object but not 386", pn)
-			return
-		}
-	}
-
-	m.cmd = make([]ldMachoCmd, ncmd)
-	off = uint32(len(hdr))
-	cmdp = make([]byte, cmdsz)
-	if _, err2 := io.ReadFull(f, cmdp); err2 != nil {
-		err = fmt.Errorf("reading cmds: %v", err)
-		goto bad
-	}
-
-	// read and parse load commands
-	c = nil
-
-	symtab = nil
-	dsymtab = nil
-
-	for i := 0; uint32(i) < ncmd; i++ {
-		ty = e.Uint32(cmdp)
-		sz = e.Uint32(cmdp[4:])
-		m.cmd[i].off = off
-		unpackcmd(cmdp, m, &m.cmd[i], uint(ty), uint(sz))
-		cmdp = cmdp[sz:]
-		off += sz
-		if ty == LdMachoCmdSymtab {
-			if symtab != nil {
-				err = fmt.Errorf("multiple symbol tables")
-				goto bad
-			}
-
-			symtab = &m.cmd[i].sym
-			macholoadsym(m, symtab)
-		}
-
-		if ty == LdMachoCmdDysymtab {
-			dsymtab = &m.cmd[i].dsym
-			macholoaddsym(m, dsymtab)
-		}
-
-		if (is64 && ty == LdMachoCmdSegment64) || (!is64 && ty == LdMachoCmdSegment) {
-			if c != nil {
-				err = fmt.Errorf("multiple load commands")
-				goto bad
-			}
-
-			c = &m.cmd[i]
-		}
-	}
-
-	// load text and data segments into memory.
-	// they are not as small as the load commands, but we'll need
-	// the memory anyway for the symbol images, so we might
-	// as well use one large chunk.
-	if c == nil {
-		err = fmt.Errorf("no load command")
-		goto bad
-	}
-
-	if symtab == nil {
-		// our work is done here - no symbols means nothing can refer to this file
-		return
-	}
-
-	if int64(c.seg.fileoff+c.seg.filesz) >= length {
-		err = fmt.Errorf("load segment out of range")
-		goto bad
-	}
-
-	dat = make([]byte, c.seg.filesz)
-	if f.Seek(m.base+int64(c.seg.fileoff), 0) < 0 {
-		err = fmt.Errorf("cannot load object data: %v", err)
-		goto bad
-	}
-	if _, err2 := io.ReadFull(f, dat); err2 != nil {
-		err = fmt.Errorf("cannot load object data: %v", err)
-		goto bad
-	}
-
-	for i := 0; uint32(i) < c.seg.nsect; i++ {
-		sect = &c.seg.sect[i]
-		if sect.segname != "__TEXT" && sect.segname != "__DATA" {
-			continue
-		}
-		if sect.name == "__eh_frame" {
-			continue
-		}
-		name = fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
-		s = ctxt.Syms.Lookup(name, localSymVersion)
-		if s.Type != 0 {
-			err = fmt.Errorf("duplicate %s/%s", sect.segname, sect.name)
-			goto bad
-		}
-
-		if sect.flags&0xff == 1 { // S_ZEROFILL
-			s.P = make([]byte, sect.size)
-		} else {
-			s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
-		}
-		s.Size = int64(len(s.P))
-
-		if sect.segname == "__TEXT" {
-			if sect.name == "__text" {
-				s.Type = STEXT
-			} else {
-				s.Type = SRODATA
-			}
-		} else {
-			if sect.name == "__bss" {
-				s.Type = SNOPTRBSS
-				s.P = s.P[:0]
-			} else {
-				s.Type = SNOPTRDATA
-			}
-		}
-
-		sect.sym = s
-	}
-
-	// enter sub-symbols into symbol table.
-	// have to guess sizes from next symbol.
-	for i := 0; uint32(i) < symtab.nsym; i++ {
-		sym = &symtab.sym[i]
-		if sym.type_&N_STAB != 0 {
-			continue
-		}
-
-		// TODO: check sym->type against outer->type.
-		name = sym.name
-
-		if name[0] == '_' && name[1] != '\x00' {
-			name = name[1:]
-		}
-		v := 0
-		if sym.type_&N_EXT == 0 {
-			v = localSymVersion
-		}
-		s = ctxt.Syms.Lookup(name, v)
-		if sym.type_&N_EXT == 0 {
-			s.Attr |= AttrDuplicateOK
-		}
-		sym.sym = s
-		if sym.sectnum == 0 { // undefined
-			continue
-		}
-		if uint32(sym.sectnum) > c.seg.nsect {
-			err = fmt.Errorf("reference to invalid section %d", sym.sectnum)
-			goto bad
-		}
-
-		sect = &c.seg.sect[sym.sectnum-1]
-		outer = sect.sym
-		if outer == nil {
-			err = fmt.Errorf("reference to invalid section %s/%s", sect.segname, sect.name)
-			continue
-		}
-
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
-		}
-
-		s.Type = outer.Type | SSUB
-		s.Sub = outer.Sub
-		outer.Sub = s
-		s.Outer = outer
-		s.Value = int64(sym.value - sect.addr)
-		if !s.Attr.CgoExportDynamic() {
-			s.Dynimplib = "" // satisfy dynimport
-		}
-		if outer.Type == STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				Errorf(s, "%s: duplicate symbol definition", pn)
-			}
-			s.Attr |= AttrExternal
-		}
-
-		sym.sym = s
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for i := 0; uint32(i) < c.seg.nsect; i++ {
-		sect = &c.seg.sect[i]
-		s = sect.sym
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = listsort(s.Sub)
-
-			// assign sizes, now that we know symbols in sorted order.
-			for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
-				if s1.Sub != nil {
-					s1.Size = s1.Sub.Value - s1.Value
-				} else {
-					s1.Size = s.Value + s.Size - s1.Value
-				}
-			}
-		}
-
-		if s.Type == STEXT {
-			if s.Attr.OnList() {
-				log.Fatalf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= AttrOnList
-			ctxt.Textp = append(ctxt.Textp, s)
-			for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
-				if s1.Attr.OnList() {
-					log.Fatalf("symbol %s listed multiple times", s1.Name)
-				}
-				s1.Attr |= AttrOnList
-				ctxt.Textp = append(ctxt.Textp, s1)
-			}
-		}
-	}
-
-	// load relocations
-	for i := 0; uint32(i) < c.seg.nsect; i++ {
-		sect = &c.seg.sect[i]
-		s = sect.sym
-		if s == nil {
-			continue
-		}
-		macholoadrel(m, sect)
-		if sect.rel == nil {
-			continue
-		}
-		r = make([]Reloc, sect.nreloc)
-		rpi = 0
-	Reloc:
-		for j = 0; uint32(j) < sect.nreloc; j++ {
-			rp = &r[rpi]
-			rel = &sect.rel[j]
-			if rel.scattered != 0 {
-				if SysArch.Family != sys.I386 {
-					// mach-o only uses scattered relocation on 32-bit platforms
-					Errorf(s, "unexpected scattered relocation")
-					continue
-				}
-
-				// on 386, rewrite scattered 4/1 relocation and some
-				// scattered 2/1 relocation into the pseudo-pc-relative
-				// reference that it is.
-				// assume that the second in the pair is in this section
-				// and use that as the pc-relative base.
-				if uint32(j+1) >= sect.nreloc {
-					err = fmt.Errorf("unsupported scattered relocation %d", int(rel.type_))
-					goto bad
-				}
-
-				if sect.rel[j+1].scattered == 0 || sect.rel[j+1].type_ != 1 || (rel.type_ != 4 && rel.type_ != 2) || uint64(sect.rel[j+1].value) < sect.addr || uint64(sect.rel[j+1].value) >= sect.addr+sect.size {
-					err = fmt.Errorf("unsupported scattered relocation %d/%d", int(rel.type_), int(sect.rel[j+1].type_))
-					goto bad
-				}
-
-				rp.Siz = rel.length
-				rp.Off = int32(rel.addr)
-
-				// NOTE(rsc): I haven't worked out why (really when)
-				// we should ignore the addend on a
-				// scattered relocation, but it seems that the
-				// common case is we ignore it.
-				// It's likely that this is not strictly correct
-				// and that the math should look something
-				// like the non-scattered case below.
-				rp.Add = 0
-
-				// want to make it pc-relative aka relative to rp->off+4
-				// but the scatter asks for relative to off = sect->rel[j+1].value - sect->addr.
-				// adjust rp->add accordingly.
-				rp.Type = objabi.R_PCREL
-
-				rp.Add += int64(uint64(int64(rp.Off)+4) - (uint64(sect.rel[j+1].value) - sect.addr))
-
-				// now consider the desired symbol.
-				// find the section where it lives.
-				var ks *ldMachoSect
-				for k := 0; uint32(k) < c.seg.nsect; k++ {
-					ks = &c.seg.sect[k]
-					if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
-						if ks.sym != nil {
-							rp.Sym = ks.sym
-							rp.Add += int64(uint64(rel.value) - ks.addr)
-						} else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
-							// handle reference to __IMPORT/__pointers.
-							// how much worse can this get?
-							// why are we supporting 386 on the mac anyway?
-							rp.Type = 512 + MACHO_FAKE_GOTPCREL
-
-							// figure out which pointer this is a reference to.
-							k = int(uint64(ks.res1) + (uint64(rel.value)-ks.addr)/4)
-
-							// load indirect table for __pointers
-							// fetch symbol number
-							if dsymtab == nil || k < 0 || uint32(k) >= dsymtab.nindirectsyms || dsymtab.indir == nil {
-								err = fmt.Errorf("invalid scattered relocation: indirect symbol reference out of range")
-								goto bad
-							}
-
-							k = int(dsymtab.indir[k])
-							if k < 0 || uint32(k) >= symtab.nsym {
-								err = fmt.Errorf("invalid scattered relocation: symbol reference out of range")
-								goto bad
-							}
-
-							rp.Sym = symtab.sym[k].sym
-						} else {
-							err = fmt.Errorf("unsupported scattered relocation: reference to %s/%s", ks.segname, ks.name)
-							goto bad
-						}
-
-						rpi++
-
-						// skip #1 of 2 rel; continue skips #2 of 2.
-						j++
-
-						continue Reloc
-					}
-				}
-
-				err = fmt.Errorf("unsupported scattered relocation: invalid address %#x", rel.addr)
-				goto bad
-
-			}
-
-			rp.Siz = rel.length
-			rp.Type = 512 + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel)
-			rp.Off = int32(rel.addr)
-
-			// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
-			if SysArch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == 1 {
-				// Calculate the addend as the offset into the section.
-				//
-				// The rip-relative offset stored in the object file is encoded
-				// as follows:
-				//
-				//    movsd	0x00000360(%rip),%xmm0
-				//
-				// To get the absolute address of the value this rip-relative address is pointing
-				// to, we must add the address of the next instruction to it. This is done by
-				// taking the address of the relocation and adding 4 to it (since the rip-relative
-				// offset can at most be 32 bits long).  To calculate the offset into the section the
-				// relocation is referencing, we subtract the vaddr of the start of the referenced
-				// section found in the original object file.
-				//
-				// [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
-				secaddr = c.seg.sect[rel.symnum-1].addr
-
-				rp.Add = int64(uint64(int64(int32(e.Uint32(s.P[rp.Off:])))+int64(rp.Off)+4) - secaddr)
-			} else {
-				rp.Add = int64(int32(e.Uint32(s.P[rp.Off:])))
-			}
-
-			// For i386 Mach-O PC-relative, the addend is written such that
-			// it *is* the PC being subtracted. Use that to make
-			// it match our version of PC-relative.
-			if rel.pcrel != 0 && SysArch.Family == sys.I386 {
-				rp.Add += int64(rp.Off) + int64(rp.Siz)
-			}
-			if rel.extrn == 0 {
-				if rel.symnum < 1 || rel.symnum > c.seg.nsect {
-					err = fmt.Errorf("invalid relocation: section reference out of range %d vs %d", rel.symnum, c.seg.nsect)
-					goto bad
-				}
-
-				rp.Sym = c.seg.sect[rel.symnum-1].sym
-				if rp.Sym == nil {
-					err = fmt.Errorf("invalid relocation: %s", c.seg.sect[rel.symnum-1].name)
-					goto bad
-				}
-
-				// References to symbols in other sections
-				// include that information in the addend.
-				// We only care about the delta from the
-				// section base.
-				if SysArch.Family == sys.I386 {
-					rp.Add -= int64(c.seg.sect[rel.symnum-1].addr)
-				}
-			} else {
-				if rel.symnum >= symtab.nsym {
-					err = fmt.Errorf("invalid relocation: symbol reference out of range")
-					goto bad
-				}
-
-				rp.Sym = symtab.sym[rel.symnum].sym
-			}
-
-			rpi++
-		}
-
-		sort.Sort(rbyoff(r[:rpi]))
-		s.R = r
-		s.R = s.R[:rpi]
-	}
-
-	return
-
-bad:
-	Errorf(nil, "%s: malformed mach-o file: %v", pn, err)
-}
diff --git a/src/cmd/link/internal/ld/ldpe.go b/src/cmd/link/internal/ld/ldpe.go
deleted file mode 100644
index 14f56d4..0000000
--- a/src/cmd/link/internal/ld/ldpe.go
+++ /dev/null
@@ -1,444 +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 ld
-
-import (
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"debug/pe"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"sort"
-	"strings"
-)
-
-const (
-	// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 (same with IMAGE_SYM_DTYPE_POINTER and IMAGE_SYM_DTYPE_FUNCTION)
-	IMAGE_SYM_UNDEFINED              = 0
-	IMAGE_SYM_ABSOLUTE               = -1
-	IMAGE_SYM_DEBUG                  = -2
-	IMAGE_SYM_TYPE_NULL              = 0
-	IMAGE_SYM_TYPE_VOID              = 1
-	IMAGE_SYM_TYPE_CHAR              = 2
-	IMAGE_SYM_TYPE_SHORT             = 3
-	IMAGE_SYM_TYPE_INT               = 4
-	IMAGE_SYM_TYPE_LONG              = 5
-	IMAGE_SYM_TYPE_FLOAT             = 6
-	IMAGE_SYM_TYPE_DOUBLE            = 7
-	IMAGE_SYM_TYPE_STRUCT            = 8
-	IMAGE_SYM_TYPE_UNION             = 9
-	IMAGE_SYM_TYPE_ENUM              = 10
-	IMAGE_SYM_TYPE_MOE               = 11
-	IMAGE_SYM_TYPE_BYTE              = 12
-	IMAGE_SYM_TYPE_WORD              = 13
-	IMAGE_SYM_TYPE_UINT              = 14
-	IMAGE_SYM_TYPE_DWORD             = 15
-	IMAGE_SYM_TYPE_PCODE             = 32768
-	IMAGE_SYM_DTYPE_NULL             = 0
-	IMAGE_SYM_DTYPE_POINTER          = 0x10
-	IMAGE_SYM_DTYPE_FUNCTION         = 0x20
-	IMAGE_SYM_DTYPE_ARRAY            = 0x30
-	IMAGE_SYM_CLASS_END_OF_FUNCTION  = -1
-	IMAGE_SYM_CLASS_NULL             = 0
-	IMAGE_SYM_CLASS_AUTOMATIC        = 1
-	IMAGE_SYM_CLASS_EXTERNAL         = 2
-	IMAGE_SYM_CLASS_STATIC           = 3
-	IMAGE_SYM_CLASS_REGISTER         = 4
-	IMAGE_SYM_CLASS_EXTERNAL_DEF     = 5
-	IMAGE_SYM_CLASS_LABEL            = 6
-	IMAGE_SYM_CLASS_UNDEFINED_LABEL  = 7
-	IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
-	IMAGE_SYM_CLASS_ARGUMENT         = 9
-	IMAGE_SYM_CLASS_STRUCT_TAG       = 10
-	IMAGE_SYM_CLASS_MEMBER_OF_UNION  = 11
-	IMAGE_SYM_CLASS_UNION_TAG        = 12
-	IMAGE_SYM_CLASS_TYPE_DEFINITION  = 13
-	IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
-	IMAGE_SYM_CLASS_ENUM_TAG         = 15
-	IMAGE_SYM_CLASS_MEMBER_OF_ENUM   = 16
-	IMAGE_SYM_CLASS_REGISTER_PARAM   = 17
-	IMAGE_SYM_CLASS_BIT_FIELD        = 18
-	IMAGE_SYM_CLASS_FAR_EXTERNAL     = 68 /* Not in PECOFF v8 spec */
-	IMAGE_SYM_CLASS_BLOCK            = 100
-	IMAGE_SYM_CLASS_FUNCTION         = 101
-	IMAGE_SYM_CLASS_END_OF_STRUCT    = 102
-	IMAGE_SYM_CLASS_FILE             = 103
-	IMAGE_SYM_CLASS_SECTION          = 104
-	IMAGE_SYM_CLASS_WEAK_EXTERNAL    = 105
-	IMAGE_SYM_CLASS_CLR_TOKEN        = 107
-	IMAGE_REL_I386_ABSOLUTE          = 0x0000
-	IMAGE_REL_I386_DIR16             = 0x0001
-	IMAGE_REL_I386_REL16             = 0x0002
-	IMAGE_REL_I386_DIR32             = 0x0006
-	IMAGE_REL_I386_DIR32NB           = 0x0007
-	IMAGE_REL_I386_SEG12             = 0x0009
-	IMAGE_REL_I386_SECTION           = 0x000A
-	IMAGE_REL_I386_SECREL            = 0x000B
-	IMAGE_REL_I386_TOKEN             = 0x000C
-	IMAGE_REL_I386_SECREL7           = 0x000D
-	IMAGE_REL_I386_REL32             = 0x0014
-	IMAGE_REL_AMD64_ABSOLUTE         = 0x0000
-	IMAGE_REL_AMD64_ADDR64           = 0x0001
-	IMAGE_REL_AMD64_ADDR32           = 0x0002
-	IMAGE_REL_AMD64_ADDR32NB         = 0x0003
-	IMAGE_REL_AMD64_REL32            = 0x0004
-	IMAGE_REL_AMD64_REL32_1          = 0x0005
-	IMAGE_REL_AMD64_REL32_2          = 0x0006
-	IMAGE_REL_AMD64_REL32_3          = 0x0007
-	IMAGE_REL_AMD64_REL32_4          = 0x0008
-	IMAGE_REL_AMD64_REL32_5          = 0x0009
-	IMAGE_REL_AMD64_SECTION          = 0x000A
-	IMAGE_REL_AMD64_SECREL           = 0x000B
-	IMAGE_REL_AMD64_SECREL7          = 0x000C
-	IMAGE_REL_AMD64_TOKEN            = 0x000D
-	IMAGE_REL_AMD64_SREL32           = 0x000E
-	IMAGE_REL_AMD64_PAIR             = 0x000F
-	IMAGE_REL_AMD64_SSPAN32          = 0x0010
-)
-
-// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf
-
-// peBiobuf makes bio.Reader look like io.ReaderAt.
-type peBiobuf bio.Reader
-
-func (f *peBiobuf) ReadAt(p []byte, off int64) (int, error) {
-	ret := ((*bio.Reader)(f)).Seek(off, 0)
-	if ret < 0 {
-		return 0, errors.New("fail to seek")
-	}
-	n, err := f.Read(p)
-	if err != nil {
-		return 0, err
-	}
-	return n, nil
-}
-
-func ldpe(ctxt *Link, input *bio.Reader, pkg string, length int64, pn string) {
-	err := ldpeError(ctxt, input, pkg, length, pn)
-	if err != nil {
-		Errorf(nil, "%s: malformed pe file: %v", pn, err)
-	}
-}
-
-func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn string) error {
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%5.2f ldpe %s\n", Cputime(), pn)
-	}
-
-	localSymVersion := ctxt.Syms.IncVersion()
-
-	sectsyms := make(map[*pe.Section]*Symbol)
-	sectdata := make(map[*pe.Section][]byte)
-
-	// Some input files are archives containing multiple of
-	// object files, and pe.NewFile seeks to the start of
-	// input file and get confused. Create section reader
-	// to stop pe.NewFile looking before current position.
-	sr := io.NewSectionReader((*peBiobuf)(input), input.Offset(), 1<<63-1)
-
-	// TODO: replace pe.NewFile with pe.Load (grep for "add Load function" in debug/pe for details)
-	f, err := pe.NewFile(sr)
-	if err != nil {
-		return err
-	}
-	defer f.Close()
-
-	// TODO return error if found .cormeta
-
-	// create symbols for mapped sections
-	for _, sect := range f.Sections {
-		if sect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
-			continue
-		}
-
-		if sect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
-			// This has been seen for .idata sections, which we
-			// want to ignore. See issues 5106 and 5273.
-			continue
-		}
-
-		name := fmt.Sprintf("%s(%s)", pkg, sect.Name)
-		s := ctxt.Syms.Lookup(name, localSymVersion)
-
-		switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
-		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
-			s.Type = SRODATA
-
-		case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
-			s.Type = SNOPTRBSS
-
-		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
-			s.Type = SNOPTRDATA
-
-		case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
-			s.Type = STEXT
-
-		default:
-			return fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
-		}
-
-		if s.Type != SNOPTRBSS {
-			data, err := sect.Data()
-			if err != nil {
-				return err
-			}
-			sectdata[sect] = data
-			s.P = data
-		}
-		s.Size = int64(sect.Size)
-		sectsyms[sect] = s
-		if sect.Name == ".rsrc" {
-			setpersrc(ctxt, s)
-		}
-	}
-
-	// load relocations
-	for _, rsect := range f.Sections {
-		if _, found := sectsyms[rsect]; !found {
-			continue
-		}
-		if rsect.NumberOfRelocations == 0 {
-			continue
-		}
-		if rsect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
-			continue
-		}
-		if rsect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
-			// This has been seen for .idata sections, which we
-			// want to ignore. See issues 5106 and 5273.
-			continue
-		}
-
-		rs := make([]Reloc, rsect.NumberOfRelocations)
-		for j, r := range rsect.Relocs {
-			rp := &rs[j]
-			if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
-				return fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
-			}
-			pesym := &f.COFFSymbols[r.SymbolTableIndex]
-			gosym, err := readpesym(ctxt, f, pesym, sectsyms, localSymVersion)
-			if err != nil {
-				return err
-			}
-			if gosym == nil {
-				name, err := pesym.FullName(f.StringTable)
-				if err != nil {
-					name = string(pesym.Name[:])
-				}
-				return fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
-			}
-
-			rp.Sym = gosym
-			rp.Siz = 4
-			rp.Off = int32(r.VirtualAddress)
-			switch r.Type {
-			default:
-				Errorf(sectsyms[rsect], "%s: unknown relocation type %d;", pn, r.Type)
-				fallthrough
-
-			case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
-				IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
-				IMAGE_REL_AMD64_ADDR32NB:
-				rp.Type = objabi.R_PCREL
-
-				rp.Add = int64(int32(Le32(sectdata[rsect][rp.Off:])))
-
-			case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
-				rp.Type = objabi.R_ADDR
-
-				// load addend from image
-				rp.Add = int64(int32(Le32(sectdata[rsect][rp.Off:])))
-
-			case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
-				rp.Siz = 8
-
-				rp.Type = objabi.R_ADDR
-
-				// load addend from image
-				rp.Add = int64(Le64(sectdata[rsect][rp.Off:]))
-			}
-
-			// ld -r could generate multiple section symbols for the
-			// same section but with different values, we have to take
-			// that into account
-			if issect(pesym) {
-				rp.Add += int64(pesym.Value)
-			}
-		}
-
-		sort.Sort(rbyoff(rs[:rsect.NumberOfRelocations]))
-
-		s := sectsyms[rsect]
-		s.R = rs
-		s.R = s.R[:rsect.NumberOfRelocations]
-	}
-
-	// enter sub-symbols into symbol table.
-	for i, numaux := 0, 0; i < len(f.COFFSymbols); i += numaux + 1 {
-		pesym := &f.COFFSymbols[i]
-
-		numaux = int(pesym.NumberOfAuxSymbols)
-
-		name, err := pesym.FullName(f.StringTable)
-		if err != nil {
-			return err
-		}
-		if name == "" {
-			continue
-		}
-		if issect(pesym) {
-			continue
-		}
-		if int(pesym.SectionNumber) > len(f.Sections) {
-			continue
-		}
-		if pesym.SectionNumber == IMAGE_SYM_DEBUG {
-			continue
-		}
-		var sect *pe.Section
-		if pesym.SectionNumber > 0 {
-			sect = f.Sections[pesym.SectionNumber-1]
-			if _, found := sectsyms[sect]; !found {
-				continue
-			}
-		}
-
-		s, err := readpesym(ctxt, f, pesym, sectsyms, localSymVersion)
-		if err != nil {
-			return err
-		}
-
-		if pesym.SectionNumber == 0 { // extern
-			if s.Type == SDYNIMPORT {
-				s.Plt = -2 // flag for dynimport in PE object files.
-			}
-			if s.Type == SXREF && pesym.Value > 0 { // global data
-				s.Type = SNOPTRDATA
-				s.Size = int64(pesym.Value)
-			}
-
-			continue
-		} else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {
-			sect = f.Sections[pesym.SectionNumber-1]
-			if _, found := sectsyms[sect]; !found {
-				Errorf(s, "%s: missing sect.sym", pn)
-			}
-		} else {
-			Errorf(s, "%s: sectnum < 0!", pn)
-		}
-
-		if sect == nil {
-			return nil
-		}
-
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sectsyms[sect].Name)
-		}
-
-		sectsym := sectsyms[sect]
-		s.Sub = sectsym.Sub
-		sectsym.Sub = s
-		s.Type = sectsym.Type | SSUB
-		s.Value = int64(pesym.Value)
-		s.Size = 4
-		s.Outer = sectsym
-		if sectsym.Type == STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				Errorf(s, "%s: duplicate symbol definition", pn)
-			}
-			s.Attr |= AttrExternal
-		}
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for _, sect := range f.Sections {
-		s := sectsyms[sect]
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = listsort(s.Sub)
-		}
-		if s.Type == STEXT {
-			if s.Attr.OnList() {
-				log.Fatalf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= AttrOnList
-			ctxt.Textp = append(ctxt.Textp, s)
-			for s = s.Sub; s != nil; s = s.Sub {
-				if s.Attr.OnList() {
-					log.Fatalf("symbol %s listed multiple times", s.Name)
-				}
-				s.Attr |= AttrOnList
-				ctxt.Textp = append(ctxt.Textp, s)
-			}
-		}
-	}
-
-	return nil
-}
-
-func issect(s *pe.COFFSymbol) bool {
-	return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
-}
-
-func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Section]*Symbol, localSymVersion int) (*Symbol, error) {
-	symname, err := sym.FullName(f.StringTable)
-	if err != nil {
-		return nil, err
-	}
-	var name string
-	if issect(sym) {
-		name = sectsyms[f.Sections[sym.SectionNumber-1]].Name
-	} else {
-		name = symname
-		if strings.HasPrefix(name, "__imp_") {
-			name = name[6:] // __imp_Name => Name
-		}
-		if SysArch.Family == sys.I386 && name[0] == '_' {
-			name = name[1:] // _Name => Name
-		}
-	}
-
-	// remove last @XXX
-	if i := strings.LastIndex(name, "@"); i >= 0 {
-		name = name[:i]
-	}
-
-	var s *Symbol
-	switch sym.Type {
-	default:
-		return nil, fmt.Errorf("%s: invalid symbol type %d", symname, sym.Type)
-
-	case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
-		switch sym.StorageClass {
-		case IMAGE_SYM_CLASS_EXTERNAL: //global
-			s = ctxt.Syms.Lookup(name, 0)
-
-		case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
-			s = ctxt.Syms.Lookup(name, localSymVersion)
-			s.Attr |= AttrDuplicateOK
-
-		default:
-			return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, sym.StorageClass)
-		}
-	}
-
-	if s != nil && s.Type == 0 && (sym.StorageClass != IMAGE_SYM_CLASS_STATIC || sym.Value != 0) {
-		s.Type = SXREF
-	}
-	if strings.HasPrefix(symname, "__imp_") {
-		s.Got = -2 // flag for __imp_
-	}
-
-	return s, nil
-}
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 0234105..6dcaf64 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -36,8 +36,14 @@
 	"cmd/internal/bio"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/loadelf"
+	"cmd/link/internal/loadmacho"
+	"cmd/link/internal/loadpe"
+	"cmd/link/internal/objfile"
+	"cmd/link/internal/sym"
 	"crypto/sha1"
 	"debug/elf"
+	"encoding/base64"
 	"encoding/binary"
 	"encoding/hex"
 	"fmt"
@@ -96,23 +102,17 @@
 	Openbsddynld     string
 	Dragonflydynld   string
 	Solarisdynld     string
-	Adddynrel        func(*Link, *Symbol, *Reloc) bool
+	Adddynrel        func(*Link, *sym.Symbol, *sym.Reloc) bool
 	Archinit         func(*Link)
-	Archreloc        func(*Link, *Reloc, *Symbol, *int64) int
-	Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64
-	Trampoline       func(*Link, *Reloc, *Symbol)
+	Archreloc        func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
+	Archrelocvariant func(*Link, *sym.Reloc, *sym.Symbol, int64) int64
+	Trampoline       func(*Link, *sym.Reloc, *sym.Symbol)
 	Asmb             func(*Link)
-	Elfreloc1        func(*Link, *Reloc, int64) int
+	Elfreloc1        func(*Link, *sym.Reloc, int64) bool
 	Elfsetupplt      func(*Link)
 	Gentext          func(*Link)
-	Machoreloc1      func(*Symbol, *Reloc, int64) int
-	PEreloc1         func(*Symbol, *Reloc, int64) bool
-	Wput             func(uint16)
-	Lput             func(uint32)
-	Vput             func(uint64)
-	Append16         func(b []byte, v uint16) []byte
-	Append32         func(b []byte, v uint32) []byte
-	Append64         func(b []byte, v uint64) []byte
+	Machoreloc1      func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
+	PEreloc1         func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
 
 	// TLSIEtoLE converts a TLS Initial Executable relocation to
 	// a TLS Local Executable relocation.
@@ -120,7 +120,7 @@
 	// This is possible when a TLS IE relocation refers to a local
 	// symbol in an executable, which is typical when internally
 	// linking PIE binaries.
-	TLSIEtoLE func(s *Symbol, off, size int)
+	TLSIEtoLE func(s *sym.Symbol, off, size int)
 }
 
 var (
@@ -131,61 +131,37 @@
 	Symsize int32
 )
 
-// Terrible but standard terminology.
-// A segment describes a block of file to load into memory.
-// A section further describes the pieces of that block for
-// use in debuggers and such.
-
 const (
 	MINFUNC = 16 // minimum size for a function
 )
 
-type Segment struct {
-	Rwx      uint8  // permission as usual unix bits (5 = r-x etc)
-	Vaddr    uint64 // virtual address
-	Length   uint64 // length in memory
-	Fileoff  uint64 // file offset
-	Filelen  uint64 // length on disk
-	Sections []*Section
-}
-
-type Section struct {
-	Rwx     uint8
-	Extnum  int16
-	Align   int32
-	Name    string
-	Vaddr   uint64
-	Length  uint64
-	Seg     *Segment
-	Elfsect *ElfShdr
-	Reloff  uint64
-	Rellen  uint64
-}
-
 // DynlinkingGo returns whether we are producing Go code that can live
 // in separate shared libraries linked together at runtime.
 func (ctxt *Link) DynlinkingGo() bool {
 	if !ctxt.Loaded {
 		panic("DynlinkingGo called before all symbols loaded")
 	}
-	canUsePlugins := ctxt.Syms.ROLookup("plugin.Open", 0) != nil
-	return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || canUsePlugins
+	return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins()
+}
+
+// CanUsePlugins returns whether a plugins can be used
+func (ctxt *Link) CanUsePlugins() bool {
+	return ctxt.Syms.ROLookup("plugin.Open", 0) != nil
 }
 
 // UseRelro returns whether to make use of "read only relocations" aka
 // relro.
-func UseRelro() bool {
-	switch Buildmode {
-	case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePIE, BuildmodePlugin:
-		return Iself
+func (ctxt *Link) UseRelro() bool {
+	switch ctxt.BuildMode {
+	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
+		return ctxt.IsELF
 	default:
-		return *FlagLinkshared
+		return ctxt.linkShared
 	}
 }
 
 var (
-	SysArch         *sys.Arch
-	dynexp          []*Symbol
+	dynexp          []*sym.Symbol
 	dynlib          []string
 	ldflag          []string
 	havedynamic     int
@@ -194,20 +170,19 @@
 	elfglobalsymndx int
 	interpreter     string
 
-	debug_s  bool // backup old value of debug['s']
-	HEADR    int32
-	Headtype objabi.HeadType
+	debug_s bool // backup old value of debug['s']
+	HEADR   int32
 
 	nerrors  int
 	liveness int64
 )
 
 var (
-	Segtext      Segment
-	Segrodata    Segment
-	Segrelrodata Segment
-	Segdata      Segment
-	Segdwarf     Segment
+	Segtext      sym.Segment
+	Segrodata    sym.Segment
+	Segrelrodata sym.Segment
+	Segdata      sym.Segment
+	Segdwarf     sym.Segment
 )
 
 /* whence for ldpkg */
@@ -217,32 +192,7 @@
 	Pkgdef
 )
 
-// TODO(dfc) outBuf duplicates bio.Writer
-type outBuf struct {
-	w   *bufio.Writer
-	f   *os.File
-	off int64
-}
-
-func (w *outBuf) Write(p []byte) (n int, err error) {
-	n, err = w.w.Write(p)
-	w.off += int64(n)
-	return n, err
-}
-
-func (w *outBuf) WriteString(s string) (n int, err error) {
-	n, err = coutbuf.w.WriteString(s)
-	w.off += int64(n)
-	return n, err
-}
-
-func (w *outBuf) Offset() int64 {
-	return w.off
-}
-
-var coutbuf outBuf
-
-const pkgname = "__.PKGDEF"
+const pkgdef = "__.PKGDEF"
 
 var (
 	// Set if we see an object compiled by the host compiler that is not
@@ -294,48 +244,34 @@
 		Exitf("cannot create %s: %v", *flagOutfile, err)
 	}
 
-	coutbuf.w = bufio.NewWriter(f)
-	coutbuf.f = f
+	ctxt.Out.w = bufio.NewWriter(f)
+	ctxt.Out.f = f
 
 	if *flagEntrySymbol == "" {
-		switch Buildmode {
-		case BuildmodeCShared, BuildmodeCArchive:
+		switch ctxt.BuildMode {
+		case BuildModeCShared, BuildModeCArchive:
 			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
-		case BuildmodeExe, BuildmodePIE:
+		case BuildModeExe, BuildModePIE:
 			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
-		case BuildmodeShared, BuildmodePlugin:
+		case BuildModeShared, BuildModePlugin:
 			// No *flagEntrySymbol for -buildmode=shared and plugin
 		default:
-			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", Buildmode)
+			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
 		}
 	}
 }
 
 func errorexit() {
-	if coutbuf.f != nil {
-		if nerrors != 0 {
-			Cflush()
-		}
-		// For rmtemp run at atexit time on Windows.
-		if err := coutbuf.f.Close(); err != nil {
-			Exitf("close: %v", err)
-		}
-	}
-
 	if nerrors != 0 {
-		if coutbuf.f != nil {
-			mayberemoveoutfile()
-		}
 		Exit(2)
 	}
-
 	Exit(0)
 }
 
-func loadinternal(ctxt *Link, name string) *Library {
-	if *FlagLinkshared && ctxt.PackageShlib != nil {
-		if shlibname := ctxt.PackageShlib[name]; shlibname != "" {
-			return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
+func loadinternal(ctxt *Link, name string) *sym.Library {
+	if ctxt.linkShared && ctxt.PackageShlib != nil {
+		if shlib := ctxt.PackageShlib[name]; shlib != "" {
+			return addlibpath(ctxt, "internal", "internal", "", name, shlib)
 		}
 	}
 	if ctxt.PackageFile != nil {
@@ -347,7 +283,7 @@
 	}
 
 	for i := 0; i < len(ctxt.Libdir); i++ {
-		if *FlagLinkshared {
+		if ctxt.linkShared {
 			shlibname := filepath.Join(ctxt.Libdir[i], name+".shlibname")
 			if ctxt.Debugvlog != 0 {
 				ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
@@ -375,7 +311,7 @@
 	if *flagExtld == "" {
 		*flagExtld = "gcc"
 	}
-	args := hostlinkArchArgs()
+	args := hostlinkArchArgs(ctxt.Arch)
 	args = append(args, cmd)
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%s %v\n", *flagExtld, args)
@@ -397,19 +333,19 @@
 }
 
 func (ctxt *Link) loadlib() {
-	switch Buildmode {
-	case BuildmodeCShared, BuildmodePlugin:
+	switch ctxt.BuildMode {
+	case BuildModeCShared, BuildModePlugin:
 		s := ctxt.Syms.Lookup("runtime.islibrary", 0)
-		s.Attr |= AttrDuplicateOK
-		Adduint8(ctxt, s, 1)
-	case BuildmodeCArchive:
+		s.Attr |= sym.AttrDuplicateOK
+		s.AddUint8(1)
+	case BuildModeCArchive:
 		s := ctxt.Syms.Lookup("runtime.isarchive", 0)
-		s.Attr |= AttrDuplicateOK
-		Adduint8(ctxt, s, 1)
+		s.Attr |= sym.AttrDuplicateOK
+		s.AddUint8(1)
 	}
 
 	loadinternal(ctxt, "runtime")
-	if SysArch.Family == sys.ARM {
+	if ctxt.Arch.Family == sys.ARM {
 		loadinternal(ctxt, "math")
 	}
 	if *flagRace {
@@ -419,73 +355,73 @@
 		loadinternal(ctxt, "runtime/msan")
 	}
 
-	var i int
-	for i = 0; i < len(ctxt.Library); i++ {
-		iscgo = iscgo || ctxt.Library[i].Pkg == "runtime/cgo"
-		if ctxt.Library[i].Shlib == "" {
+	// ctxt.Library grows during the loop, so not a range loop.
+	for i := 0; i < len(ctxt.Library); i++ {
+		lib := ctxt.Library[i]
+		if lib.Shlib == "" {
 			if ctxt.Debugvlog > 1 {
-				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].File, ctxt.Library[i].Objref)
+				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), lib.File, lib.Objref)
 			}
-			objfile(ctxt, ctxt.Library[i])
+			loadobjfile(ctxt, lib)
 		}
 	}
 
-	for i = 0; i < len(ctxt.Library); i++ {
-		if ctxt.Library[i].Shlib != "" {
+	for _, lib := range ctxt.Library {
+		if lib.Shlib != "" {
 			if ctxt.Debugvlog > 1 {
-				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].Shlib, ctxt.Library[i].Objref)
+				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), lib.Shlib, lib.Objref)
 			}
-			ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
+			ldshlibsyms(ctxt, lib.Shlib)
 		}
 	}
 
+	iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
+
 	// We now have enough information to determine the link mode.
 	determineLinkMode(ctxt)
 
-	// Recalculate pe parameters now that we have Linkmode set.
-	if Headtype == objabi.Hwindows {
+	// Recalculate pe parameters now that we have ctxt.LinkMode set.
+	if ctxt.HeadType == objabi.Hwindows {
 		Peinit(ctxt)
 	}
 
-	if Headtype == objabi.Hdarwin && Linkmode == LinkExternal {
+	if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
 		*FlagTextAddr = 0
 	}
 
-	if Linkmode == LinkExternal && SysArch.Family == sys.PPC64 {
+	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
 		toc := ctxt.Syms.Lookup(".TOC.", 0)
-		toc.Type = SDYNIMPORT
+		toc.Type = sym.SDYNIMPORT
 	}
 
-	if Linkmode == LinkExternal && !iscgo {
+	if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
 		// This indicates a user requested -linkmode=external.
 		// The startup code uses an import of runtime/cgo to decide
 		// whether to initialize the TLS.  So give it one. This could
 		// be handled differently but it's an unusual case.
-		loadinternal(ctxt, "runtime/cgo")
-
-		if i < len(ctxt.Library) {
-			if ctxt.Library[i].Shlib != "" {
-				ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
+		if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil {
+			if lib.Shlib != "" {
+				ldshlibsyms(ctxt, lib.Shlib)
 			} else {
-				if Buildmode == BuildmodeShared || *FlagLinkshared {
+				if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
 					Exitf("cannot implicitly include runtime/cgo in a shared library")
 				}
-				objfile(ctxt, ctxt.Library[i])
+				loadobjfile(ctxt, lib)
 			}
 		}
 	}
 
-	if Linkmode == LinkInternal {
+	if ctxt.LinkMode == LinkInternal {
 		// Drop all the cgo_import_static declarations.
 		// Turns out we won't be needing them.
 		for _, s := range ctxt.Syms.Allsym {
-			if s.Type == SHOSTOBJ {
+			if s.Type == sym.SHOSTOBJ {
 				// If a symbol was marked both
 				// cgo_import_static and cgo_import_dynamic,
 				// then we want to make it cgo_import_dynamic
 				// now.
 				if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
-					s.Type = SDYNIMPORT
+					s.Type = sym.SDYNIMPORT
 				} else {
 					s.Type = 0
 				}
@@ -498,22 +434,22 @@
 	// runtime.tlsg is used for external linking on platforms that do not define
 	// a variable to hold g in assembly (currently only intel).
 	if tlsg.Type == 0 {
-		tlsg.Type = STLSBSS
-		tlsg.Size = int64(SysArch.PtrSize)
-	} else if tlsg.Type != SDYNIMPORT {
+		tlsg.Type = sym.STLSBSS
+		tlsg.Size = int64(ctxt.Arch.PtrSize)
+	} else if tlsg.Type != sym.SDYNIMPORT {
 		Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
 	}
-	tlsg.Attr |= AttrReachable
+	tlsg.Attr |= sym.AttrReachable
 	ctxt.Tlsg = tlsg
 
-	var moduledata *Symbol
-	if Buildmode == BuildmodePlugin {
+	var moduledata *sym.Symbol
+	if ctxt.BuildMode == BuildModePlugin {
 		moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
-		moduledata.Attr |= AttrLocal
+		moduledata.Attr |= sym.AttrLocal
 	} else {
 		moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
 	}
-	if moduledata.Type != 0 && moduledata.Type != SDYNIMPORT {
+	if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT {
 		// If the module (toolchain-speak for "executable or shared
 		// library") we are linking contains the runtime package, it
 		// will define the runtime.firstmoduledata symbol and we
@@ -523,36 +459,36 @@
 
 		// In addition, on ARM, the runtime depends on the linker
 		// recording the value of GOARM.
-		if SysArch.Family == sys.ARM {
+		if ctxt.Arch.Family == sys.ARM {
 			s := ctxt.Syms.Lookup("runtime.goarm", 0)
-			s.Type = SRODATA
+			s.Type = sym.SRODATA
 			s.Size = 0
-			Adduint8(ctxt, s, uint8(objabi.GOARM))
+			s.AddUint8(uint8(objabi.GOARM))
 		}
 
 		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
 			s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
-			s.Type = SRODATA
+			s.Type = sym.SRODATA
 			s.Size = 0
-			Adduint8(ctxt, s, 1)
+			s.AddUint8(1)
 		}
 	} else {
 		// If OTOH the module does not contain the runtime package,
 		// create a local symbol for the moduledata.
 		moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
-		moduledata.Attr |= AttrLocal
+		moduledata.Attr |= sym.AttrLocal
 	}
 	// In all cases way we mark the moduledata as noptrdata to hide it from
 	// the GC.
-	moduledata.Type = SNOPTRDATA
-	moduledata.Attr |= AttrReachable
+	moduledata.Type = sym.SNOPTRDATA
+	moduledata.Attr |= sym.AttrReachable
 	ctxt.Moduledata = moduledata
 
 	// Now that we know the link mode, trim the dynexp list.
-	x := AttrCgoExportDynamic
+	x := sym.AttrCgoExportDynamic
 
-	if Linkmode == LinkExternal {
-		x = AttrCgoExportStatic
+	if ctxt.LinkMode == LinkExternal {
+		x = sym.AttrCgoExportStatic
 	}
 	w := 0
 	for i := 0; i < len(dynexp); i++ {
@@ -564,7 +500,7 @@
 	dynexp = dynexp[:w]
 
 	// In internal link mode, read the host object files.
-	if Linkmode == LinkInternal {
+	if ctxt.LinkMode == LinkInternal {
 		hostobjs(ctxt)
 
 		// If we have any undefined symbols in external
@@ -572,7 +508,7 @@
 		any := false
 		for _, s := range ctxt.Syms.Allsym {
 			for _, r := range s.R {
-				if r.Sym != nil && r.Sym.Type&SMASK == SXREF && r.Sym.Name != ".got" {
+				if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
 					any = true
 					break
 				}
@@ -585,7 +521,7 @@
 			if *flagLibGCC != "none" {
 				hostArchive(ctxt, *flagLibGCC)
 			}
-			if Headtype == objabi.Hwindows {
+			if ctxt.HeadType == objabi.Hwindows {
 				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
 					hostArchive(ctxt, p)
 				}
@@ -603,7 +539,7 @@
 			}
 		}
 	} else {
-		hostlinksetup()
+		hostlinksetup(ctxt)
 	}
 
 	// We've loaded all the code now.
@@ -619,27 +555,48 @@
 	// binaries, so leave it enabled on OS X (Mach-O) binaries.
 	// Also leave it enabled on Solaris which doesn't support
 	// statically linked binaries.
-	if Buildmode == BuildmodeExe {
-		if havedynamic == 0 && Headtype != objabi.Hdarwin && Headtype != objabi.Hsolaris {
+	if ctxt.BuildMode == BuildModeExe {
+		if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
 			*FlagD = true
 		}
 	}
 
+	// If type. symbols are visible in the symbol table, rename them
+	// using a SHA-1 prefix. This reduces binary size (the full
+	// string of a type symbol can be multiple kilobytes) and removes
+	// characters that upset external linkers.
+	//
+	// Keep the type.. prefix, which parts of the linker (like the
+	// DWARF generator) know means the symbol is not decodable.
+	//
+	// Leave type.runtime. symbols alone, because other parts of
+	// the linker manipulates them, and also symbols whose names
+	// would not be shortened by this process.
+	if typeSymbolMangling(ctxt) {
+		*FlagW = true // disable DWARF generation
+		for _, s := range ctxt.Syms.Allsym {
+			newName := typeSymbolMangle(s.Name)
+			if newName != s.Name {
+				ctxt.Syms.Rename(s.Name, newName, int(s.Version))
+			}
+		}
+	}
+
 	// If package versioning is required, generate a hash of the
 	// the packages used in the link.
-	if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
-		for i = 0; i < len(ctxt.Library); i++ {
-			if ctxt.Library[i].Shlib == "" {
-				genhash(ctxt, ctxt.Library[i])
+	if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
+		for _, lib := range ctxt.Library {
+			if lib.Shlib == "" {
+				genhash(ctxt, lib)
 			}
 		}
 	}
 
-	if SysArch == sys.Arch386 {
-		if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
+	if ctxt.Arch == sys.Arch386 {
+		if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || (ctxt.BuildMode == BuildModeCShared && ctxt.HeadType != objabi.Hwindows) || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
 			got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
-			got.Type = SDYNIMPORT
-			got.Attr |= AttrReachable
+			got.Type = sym.SDYNIMPORT
+			got.Attr |= sym.AttrReachable
 		}
 	}
 
@@ -654,11 +611,11 @@
 			if isRuntimeDepPkg(lib.Pkg) != doInternal {
 				continue
 			}
-			ctxt.Textp = append(ctxt.Textp, lib.textp...)
-			for _, s := range lib.dupTextSyms {
+			ctxt.Textp = append(ctxt.Textp, lib.Textp...)
+			for _, s := range lib.DupTextSyms {
 				if !s.Attr.OnList() {
 					ctxt.Textp = append(ctxt.Textp, s)
-					s.Attr |= AttrOnList
+					s.Attr |= sym.AttrOnList
 					// dupok symbols may be defined in multiple packages. its
 					// associated package is chosen sort of arbitrarily (the
 					// first containing package that the linker loads). canonicalize
@@ -674,9 +631,9 @@
 		// We might have overwritten some functions above (this tends to happen for the
 		// autogenerated type equality/hashing functions) and we don't want to generated
 		// pcln table entries for these any more so remove them from Textp.
-		textp := make([]*Symbol, 0, len(ctxt.Textp))
+		textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
 		for _, s := range ctxt.Textp {
-			if s.Type != SDYNIMPORT {
+			if s.Type != sym.SDYNIMPORT {
 				textp = append(textp, s)
 			}
 		}
@@ -684,6 +641,41 @@
 	}
 }
 
+// typeSymbolMangling reports whether the linker should shorten the
+// names of symbols that represent Go types.
+//
+// As the names of these symbols are derived from the string of
+// the type, they can run to many kilobytes long. So we shorten
+// them using a SHA-1 when the name appears in the final binary.
+//
+// These are the symbols that begin with the prefix 'type.' and
+// contain run-time type information used by the runtime and reflect
+// packages. All Go binaries contain these symbols, but only only
+// those programs loaded dynamically in multiple parts need these
+// symbols to have entries in the symbol table.
+func typeSymbolMangling(ctxt *Link) bool {
+	return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil
+}
+
+// typeSymbolMangle mangles the given symbol name into something shorter.
+func typeSymbolMangle(name string) string {
+	if !strings.HasPrefix(name, "type.") {
+		return name
+	}
+	if strings.HasPrefix(name, "type.runtime.") {
+		return name
+	}
+	if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
+		return name
+	}
+	hash := sha1.Sum([]byte(name))
+	prefix := "type."
+	if name[5] == '.' {
+		prefix = "type.."
+	}
+	return prefix + base64.StdEncoding.EncodeToString(hash[:6])
+}
+
 /*
  * look for the next file in an archive.
  * adapted from libmach.
@@ -716,7 +708,7 @@
 	return arsize + SAR_HDR
 }
 
-func genhash(ctxt *Link, lib *Library) {
+func genhash(ctxt *Link, lib *sym.Library) {
 	f, err := bio.Open(lib.File)
 	if err != nil {
 		Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
@@ -724,8 +716,17 @@
 	}
 	defer f.Close()
 
+	var magbuf [len(ARMAG)]byte
+	if _, err := io.ReadFull(f, magbuf[:]); err != nil {
+		Exitf("file %s too short", lib.File)
+	}
+
+	if string(magbuf[:]) != ARMAG {
+		Exitf("%s is not an archive file", lib.File)
+	}
+
 	var arhdr ArHdr
-	l := nextar(f, int64(len(ARMAG)), &arhdr)
+	l := nextar(f, f.Offset(), &arhdr)
 	if l <= 0 {
 		Errorf(nil, "%s: short read on archive file symbol header", lib.File)
 		return
@@ -736,7 +737,7 @@
 	// To compute the hash of a package, we hash the first line of
 	// __.PKGDEF (which contains the toolchain version and any
 	// GOEXPERIMENT flags) and the export data (which is between
-	// the first two occurences of "\n$$").
+	// the first two occurrences of "\n$$").
 
 	pkgDefBytes := make([]byte, atolwhex(arhdr.size))
 	_, err = io.ReadFull(f, pkgDefBytes)
@@ -744,7 +745,7 @@
 		Errorf(nil, "%s: error reading package data: %v", lib.File, err)
 		return
 	}
-	firstEOL := bytes.Index(pkgDefBytes, []byte("\n"))
+	firstEOL := bytes.IndexByte(pkgDefBytes, '\n')
 	if firstEOL < 0 {
 		Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
 		return
@@ -761,10 +762,10 @@
 	}
 	h.Write(pkgDefBytes[0:firstEOL])
 	h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
-	lib.hash = hex.EncodeToString(h.Sum(nil))
+	lib.Hash = hex.EncodeToString(h.Sum(nil))
 }
 
-func objfile(ctxt *Link, lib *Library) {
+func loadobjfile(ctxt *Link, lib *sym.Library) {
 	pkg := objabi.PathToPrefix(lib.Pkg)
 
 	if ctxt.Debugvlog > 1 {
@@ -801,7 +802,7 @@
 		goto out
 	}
 
-	if !strings.HasPrefix(arhdr.name, pkgname) {
+	if !strings.HasPrefix(arhdr.name, pkgdef) {
 		Errorf(nil, "%s: cannot find package header", lib.File)
 		goto out
 	}
@@ -864,7 +865,7 @@
 	"runtime/msan",
 }
 
-func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
+func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
 	isinternal := false
 	for i := 0; i < len(internalpkg); i++ {
 		if pkg == internalpkg[i] {
@@ -879,7 +880,7 @@
 	// force external linking for any libraries that link in code that
 	// uses errno. This can be removed if the Go linker ever supports
 	// these relocation types.
-	if Headtype == objabi.Hdragonfly {
+	if headType == objabi.Hdragonfly {
 		if pkg == "net" || pkg == "os/user" {
 			isinternal = false
 		}
@@ -922,8 +923,8 @@
 	os.RemoveAll(*flagTmpdir)
 }
 
-func hostlinksetup() {
-	if Linkmode != LinkExternal {
+func hostlinksetup(ctxt *Link) {
+	if ctxt.LinkMode != LinkExternal {
 		return
 	}
 
@@ -944,7 +945,7 @@
 	}
 
 	// change our output to temporary object file
-	coutbuf.f.Close()
+	ctxt.Out.f.Close()
 	mayberemoveoutfile()
 
 	p := filepath.Join(*flagTmpdir, "go.o")
@@ -954,8 +955,9 @@
 		Exitf("cannot create %s: %v", p, err)
 	}
 
-	coutbuf.w = bufio.NewWriter(f)
-	coutbuf.f = f
+	ctxt.Out.w = bufio.NewWriter(f)
+	ctxt.Out.f = f
+	ctxt.Out.off = 0
 }
 
 // hostobjCopy creates a copy of the object files in hostobj in a
@@ -1024,7 +1026,7 @@
 
 // archive builds a .a archive from the hostobj object files.
 func (ctxt *Link) archive() {
-	if Buildmode != BuildmodeCArchive {
+	if ctxt.BuildMode != BuildModeCArchive {
 		return
 	}
 
@@ -1036,11 +1038,11 @@
 
 	// Force the buffer to flush here so that external
 	// tools will see a complete file.
-	Cflush()
-	if err := coutbuf.f.Close(); err != nil {
+	ctxt.Out.Flush()
+	if err := ctxt.Out.f.Close(); err != nil {
 		Exitf("close: %v", err)
 	}
-	coutbuf.f = nil
+	ctxt.Out.f = nil
 
 	argv := []string{*flagExtar, "-q", "-c", "-s", *flagOutfile}
 	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
@@ -1055,11 +1057,11 @@
 	}
 }
 
-func (l *Link) hostlink() {
-	if Linkmode != LinkExternal || nerrors > 0 {
+func (ctxt *Link) hostlink() {
+	if ctxt.LinkMode != LinkExternal || nerrors > 0 {
 		return
 	}
-	if Buildmode == BuildmodeCArchive {
+	if ctxt.BuildMode == BuildModeCArchive {
 		return
 	}
 
@@ -1069,24 +1071,25 @@
 
 	var argv []string
 	argv = append(argv, *flagExtld)
-	argv = append(argv, hostlinkArchArgs()...)
+	argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
 
-	if !*FlagS && !debug_s {
-		argv = append(argv, "-gdwarf-2")
-	} else if Headtype == objabi.Hdarwin {
-		// Recent versions of macOS print
-		//	ld: warning: option -s is obsolete and being ignored
-		// so do not pass any arguments.
-	} else {
-		argv = append(argv, "-s")
+	if *FlagS || debug_s {
+		if ctxt.HeadType == objabi.Hdarwin {
+			// Recent versions of macOS print
+			//	ld: warning: option -s is obsolete and being ignored
+			// so do not pass any arguments.
+		} else {
+			argv = append(argv, "-s")
+		}
 	}
 
-	switch Headtype {
+	switch ctxt.HeadType {
 	case objabi.Hdarwin:
 		argv = append(argv, "-Wl,-headerpad,1144")
-		if l.DynlinkingGo() {
+		if ctxt.DynlinkingGo() {
 			argv = append(argv, "-Wl,-flat_namespace")
-		} else if !SysArch.InFamily(sys.ARM64) {
+		}
+		if ctxt.BuildMode == BuildModeExe && !ctxt.Arch.InFamily(sys.ARM64) {
 			argv = append(argv, "-Wl,-no_pie")
 		}
 	case objabi.Hopenbsd:
@@ -1099,49 +1102,61 @@
 		}
 	}
 
-	switch Buildmode {
-	case BuildmodeExe:
-		if Headtype == objabi.Hdarwin {
-			argv = append(argv, "-Wl,-pagezero_size,4000000")
+	switch ctxt.BuildMode {
+	case BuildModeExe:
+		if ctxt.HeadType == objabi.Hdarwin {
+			if ctxt.Arch.Family == sys.ARM64 {
+				// __PAGEZERO segment size determined empirically.
+				// XCode 9.0.1 successfully uploads an iOS app with this value.
+				argv = append(argv, "-Wl,-pagezero_size,100000000")
+			} else {
+				argv = append(argv, "-Wl,-pagezero_size,4000000")
+			}
 		}
-	case BuildmodePIE:
-		if UseRelro() {
-			argv = append(argv, "-Wl,-z,relro")
+	case BuildModePIE:
+		// ELF.
+		if ctxt.HeadType != objabi.Hdarwin {
+			if ctxt.UseRelro() {
+				argv = append(argv, "-Wl,-z,relro")
+			}
+			argv = append(argv, "-pie")
 		}
-		argv = append(argv, "-pie")
-	case BuildmodeCShared:
-		if Headtype == objabi.Hdarwin {
+	case BuildModeCShared:
+		if ctxt.HeadType == objabi.Hdarwin {
 			argv = append(argv, "-dynamiclib")
-			if SysArch.Family != sys.AMD64 {
+			if ctxt.Arch.Family != sys.AMD64 {
 				argv = append(argv, "-Wl,-read_only_relocs,suppress")
 			}
 		} else {
 			// ELF.
 			argv = append(argv, "-Wl,-Bsymbolic")
-			if UseRelro() {
+			if ctxt.UseRelro() {
 				argv = append(argv, "-Wl,-z,relro")
 			}
-			// Pass -z nodelete to mark the shared library as
-			// non-closeable: a dlclose will do nothing.
-			argv = append(argv, "-shared", "-Wl,-z,nodelete")
+			argv = append(argv, "-shared")
+			if ctxt.HeadType != objabi.Hwindows {
+				// Pass -z nodelete to mark the shared library as
+				// non-closeable: a dlclose will do nothing.
+				argv = append(argv, "-Wl,-z,nodelete")
+			}
 		}
-	case BuildmodeShared:
-		if UseRelro() {
+	case BuildModeShared:
+		if ctxt.UseRelro() {
 			argv = append(argv, "-Wl,-z,relro")
 		}
 		argv = append(argv, "-shared")
-	case BuildmodePlugin:
-		if Headtype == objabi.Hdarwin {
+	case BuildModePlugin:
+		if ctxt.HeadType == objabi.Hdarwin {
 			argv = append(argv, "-dynamiclib")
 		} else {
-			if UseRelro() {
+			if ctxt.UseRelro() {
 				argv = append(argv, "-Wl,-z,relro")
 			}
 			argv = append(argv, "-shared")
 		}
 	}
 
-	if Iself && l.DynlinkingGo() {
+	if ctxt.IsELF && ctxt.DynlinkingGo() {
 		// We force all symbol resolution to be done at program startup
 		// because lazy PLT resolution can use large amounts of stack at
 		// times we cannot allow it to do so.
@@ -1149,10 +1164,10 @@
 
 		// Do not let the host linker generate COPY relocations. These
 		// can move symbols out of sections that rely on stable offsets
-		// from the beginning of the section (like STYPE).
+		// from the beginning of the section (like sym.STYPE).
 		argv = append(argv, "-Wl,-znocopyreloc")
 
-		if SysArch.InFamily(sys.ARM, sys.ARM64) {
+		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
 			// On ARM, the GNU linker will generate COPY relocations
 			// even with -znocopyreloc set.
 			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
@@ -1175,7 +1190,7 @@
 		}
 	}
 
-	if Iself && len(buildinfo) > 0 {
+	if ctxt.IsELF && len(buildinfo) > 0 {
 		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
 	}
 
@@ -1197,7 +1212,7 @@
 	}
 
 	// Force global symbols to be exported for dlopen, etc.
-	if Iself {
+	if ctxt.IsELF {
 		argv = append(argv, "-rdynamic")
 	}
 
@@ -1208,7 +1223,7 @@
 	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
 	argv = append(argv, hostobjCopy()...)
 
-	if *FlagLinkshared {
+	if ctxt.linkShared {
 		seenDirs := make(map[string]bool)
 		seenLibs := make(map[string]bool)
 		addshlib := func(path string) {
@@ -1227,13 +1242,13 @@
 				seenLibs[base] = true
 			}
 		}
-		for _, shlib := range l.Shlibs {
+		for _, shlib := range ctxt.Shlibs {
 			addshlib(shlib.Path)
 			for _, dep := range shlib.Deps {
 				if dep == "" {
 					continue
 				}
-				libpath := findshlib(l, dep)
+				libpath := findshlib(ctxt, dep)
 				if libpath != "" {
 					addshlib(libpath)
 				}
@@ -1250,7 +1265,7 @@
 	// does not work, the resulting programs will not run. See
 	// issue #17847. To avoid this problem pass -no-pie to the
 	// toolchain if it is supported.
-	if Buildmode == BuildmodeExe {
+	if ctxt.BuildMode == BuildModeExe {
 		src := filepath.Join(*flagTmpdir, "trivial.c")
 		if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
 			Errorf(nil, "WriteFile trivial.c failed: %v", err)
@@ -1281,7 +1296,7 @@
 		// we added it. We do it in this order, rather than
 		// only adding -rdynamic later, so that -*extldflags
 		// can override -rdynamic without using -static.
-		if Iself && p == "-static" {
+		if ctxt.IsELF && p == "-static" {
 			for i := range argv {
 				if argv[i] == "-rdynamic" {
 					argv[i] = "-static"
@@ -1289,7 +1304,7 @@
 			}
 		}
 	}
-	if Headtype == objabi.Hwindows {
+	if ctxt.HeadType == objabi.Hwindows {
 		// use gcc linker script to work around gcc bug
 		// (see https://golang.org/issue/20183 for details).
 		p := writeGDBLinkerScript()
@@ -1300,12 +1315,12 @@
 		argv = append(argv, peimporteddlls()...)
 	}
 
-	if l.Debugvlog != 0 {
-		l.Logf("%5.2f host link:", Cputime())
+	if ctxt.Debugvlog != 0 {
+		ctxt.Logf("%5.2f host link:", Cputime())
 		for _, v := range argv {
-			l.Logf(" %q", v)
+			ctxt.Logf(" %q", v)
 		}
-		l.Logf("\n")
+		ctxt.Logf("\n")
 	}
 
 	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
@@ -1313,12 +1328,12 @@
 	} else if len(out) > 0 {
 		// always print external output even if the command is successful, so that we don't
 		// swallow linker warnings (see https://golang.org/issue/17935).
-		l.Logf("%s", out)
+		ctxt.Logf("%s", out)
 	}
 
-	if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin {
+	if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
 		// Skip combining dwarf on arm.
-		if !SysArch.InFamily(sys.ARM, sys.ARM64) {
+		if !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
 			dsym := filepath.Join(*flagTmpdir, "go.dwarf")
 			if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
 				Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
@@ -1329,7 +1344,7 @@
 			}
 			// For os.Rename to work reliably, must be in same directory as outfile.
 			combinedOutput := *flagOutfile + "~"
-			if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil {
+			if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput, ctxt.BuildMode); err != nil {
 				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
 			}
 			os.Remove(*flagOutfile)
@@ -1342,8 +1357,8 @@
 
 // hostlinkArchArgs returns arguments to pass to the external linker
 // based on the architecture.
-func hostlinkArchArgs() []string {
-	switch SysArch.Family {
+func hostlinkArchArgs(arch *sys.Arch) []string {
+	switch arch.Family {
 	case sys.I386:
 		return []string{"-m32"}
 	case sys.AMD64, sys.PPC64, sys.S390X:
@@ -1363,7 +1378,7 @@
 // ldobj loads an input object. If it is a host object (an object
 // compiled by a non-Go compiler) it returns the Hostobj pointer. If
 // it is a Go object, it returns nil.
-func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj {
+func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string, whence int) *Hostobj {
 	pkg := objabi.PathToPrefix(lib.Pkg)
 
 	eof := f.Offset() + length
@@ -1376,15 +1391,43 @@
 
 	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
 	if magic == 0x7f454c46 { // \x7F E L F
-		return ldhostobj(ldelf, f, pkg, length, pn, file)
+		ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
+			textp, flags, err := loadelf.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
+			if err != nil {
+				Errorf(nil, "%v", err)
+				return
+			}
+			ehdr.flags = flags
+			ctxt.Textp = append(ctxt.Textp, textp...)
+		}
+		return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
 	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
-		return ldhostobj(ldmacho, f, pkg, length, pn, file)
+		ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
+			textp, err := loadmacho.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
+			if err != nil {
+				Errorf(nil, "%v", err)
+				return
+			}
+			ctxt.Textp = append(ctxt.Textp, textp...)
+		}
+		return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
 	if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
-		return ldhostobj(ldpe, f, pkg, length, pn, file)
+		ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
+			textp, rsrc, err := loadpe.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
+			if err != nil {
+				Errorf(nil, "%v", err)
+				return
+			}
+			if rsrc != nil {
+				setpersrc(ctxt, rsrc)
+			}
+			ctxt.Textp = append(ctxt.Textp, textp...)
+		}
+		return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
 	/* check the header */
@@ -1400,7 +1443,7 @@
 			return nil
 		}
 
-		if line == SysArch.Name {
+		if line == ctxt.Arch.Name {
 			// old header format: just $GOOS
 			Errorf(nil, "%s: stale object file", pn)
 			return nil
@@ -1431,13 +1474,29 @@
 		}
 	}
 
-	/* skip over exports and other info -- ends with \n!\n */
+	// Skip over exports and other info -- ends with \n!\n.
+	//
+	// Note: It's possible for "\n!\n" to appear within the binary
+	// package export data format. To avoid truncating the package
+	// definition prematurely (issue 21703), we keep keep track of
+	// how many "$$" delimiters we've seen.
+
 	import0 := f.Offset()
 
 	c1 = '\n' // the last line ended in \n
 	c2 = bgetc(f)
 	c3 = bgetc(f)
-	for c1 != '\n' || c2 != '!' || c3 != '\n' {
+	markers := 0
+	for {
+		if c1 == '\n' {
+			if markers%2 == 0 && c2 == '!' && c3 == '\n' {
+				break
+			}
+			if c2 == '$' && c3 == '$' {
+				markers++
+			}
+		}
+
 		c1 = c2
 		c2 = c3
 		c3 = bgetc(f)
@@ -1453,7 +1512,8 @@
 	ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n
 	f.Seek(import1, 0)
 
-	LoadObjFile(ctxt, f, lib, eof-f.Offset(), pn)
+	objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, eof-f.Offset(), pn)
+	addImports(ctxt, lib, pn)
 	return nil
 }
 
@@ -1520,6 +1580,9 @@
 }
 
 func findshlib(ctxt *Link, shlib string) string {
+	if filepath.IsAbs(shlib) {
+		return shlib
+	}
 	for _, libdir := range ctxt.Libdir {
 		libpath := filepath.Join(libdir, shlib)
 		if _, err := os.Stat(libpath); err == nil {
@@ -1531,9 +1594,15 @@
 }
 
 func ldshlibsyms(ctxt *Link, shlib string) {
-	libpath := findshlib(ctxt, shlib)
-	if libpath == "" {
-		return
+	var libpath string
+	if filepath.IsAbs(shlib) {
+		libpath = shlib
+		shlib = filepath.Base(shlib)
+	} else {
+		libpath = findshlib(ctxt, shlib)
+		if libpath == "" {
+			return
+		}
 	}
 	for _, processedlib := range ctxt.Shlibs {
 		if processedlib.Path == libpath {
@@ -1549,6 +1618,7 @@
 		Errorf(nil, "cannot open shared library: %s", libpath)
 		return
 	}
+	defer f.Close()
 
 	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
 	if err != nil {
@@ -1561,14 +1631,29 @@
 		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
 		return
 	}
-	deps := strings.Split(string(depsbytes), "\n")
+	var deps []string
+	for _, dep := range strings.Split(string(depsbytes), "\n") {
+		if dep == "" {
+			continue
+		}
+		if !filepath.IsAbs(dep) {
+			// If the dep can be interpreted as a path relative to the shlib
+			// in which it was found, do that. Otherwise, we will leave it
+			// to be resolved by libdir lookup.
+			abs := filepath.Join(filepath.Dir(libpath), dep)
+			if _, err := os.Stat(abs); err == nil {
+				dep = abs
+			}
+		}
+		deps = append(deps, dep)
+	}
 
 	syms, err := f.DynamicSymbols()
 	if err != nil {
 		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
 		return
 	}
-	gcdataLocations := make(map[uint64]*Symbol)
+	gcdataLocations := make(map[uint64]*sym.Symbol)
 	for _, elfsym := range syms {
 		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
 			continue
@@ -1578,10 +1663,10 @@
 		// libraries, any non-dynimport symbols we find that duplicate symbols
 		// already loaded should be ignored (the symbols from the .a files
 		// "win").
-		if lsym.Type != 0 && lsym.Type != SDYNIMPORT {
+		if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
 			continue
 		}
-		lsym.Type = SDYNIMPORT
+		lsym.Type = sym.SDYNIMPORT
 		lsym.ElfType = elf.ST_TYPE(elfsym.Info)
 		lsym.Size = int64(elfsym.Size)
 		if elfsym.Section != elf.SHN_UNDEF {
@@ -1591,12 +1676,12 @@
 			// the type data.
 			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
 				lsym.P = readelfsymboldata(ctxt, f, &elfsym)
-				gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
+				gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
 			}
 		}
 	}
-	gcdataAddresses := make(map[*Symbol]uint64)
-	if SysArch.Family == sys.ARM64 {
+	gcdataAddresses := make(map[*sym.Symbol]uint64)
+	if ctxt.Arch.Family == sys.ARM64 {
 		for _, sect := range f.Sections {
 			if sect.Type == elf.SHT_RELA {
 				var rela elf.Rela64
@@ -1624,12 +1709,12 @@
 	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
 }
 
-func addsection(seg *Segment, name string, rwx int) *Section {
-	sect := new(Section)
+func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
+	sect := new(sym.Section)
 	sect.Rwx = uint8(rwx)
 	sect.Name = name
 	sect.Seg = seg
-	sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
+	sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
 	seg.Sections = append(seg.Sections, sect)
 	return sect
 }
@@ -1655,12 +1740,12 @@
 }
 
 type chain struct {
-	sym   *Symbol
+	sym   *sym.Symbol
 	up    *chain
 	limit int // limit on entry to sym
 }
 
-var morestack *Symbol
+var morestack *sym.Symbol
 
 // TODO: Record enough information in new object files to
 // allow stack checks here.
@@ -1673,7 +1758,7 @@
 	if haslinkregister(ctxt) {
 		return 0
 	}
-	return SysArch.RegSize
+	return ctxt.Arch.RegSize
 }
 
 func (ctxt *Link) dostkcheck() {
@@ -1727,7 +1812,7 @@
 		if s.Attr.StackCheck() {
 			return 0
 		}
-		s.Attr |= AttrStackCheck
+		s.Attr |= sym.AttrStackCheck
 	}
 
 	if depth > 100 {
@@ -1741,8 +1826,8 @@
 		// should never be called directly.
 		// onlyctxt.Diagnose the direct caller.
 		// TODO(mwhudson): actually think about this.
-		if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() &&
-			Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
+		if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
+			ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
 
 			Errorf(s, "call to external function")
 		}
@@ -1787,7 +1872,7 @@
 	endr := len(s.R)
 	var ch1 chain
 	var pcsp Pciter
-	var r *Reloc
+	var r *sym.Reloc
 	for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
 		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
 
@@ -1866,36 +1951,6 @@
 	}
 }
 
-func Cflush() {
-	if err := coutbuf.w.Flush(); err != nil {
-		Exitf("flushing %s: %v", coutbuf.f.Name(), err)
-	}
-}
-
-func Cseek(p int64) {
-	if p == coutbuf.off {
-		return
-	}
-	Cflush()
-	if _, err := coutbuf.f.Seek(p, 0); err != nil {
-		Exitf("seeking in output [0, 1]: %v", err)
-	}
-	coutbuf.off = p
-}
-
-func Cwritestring(s string) {
-	coutbuf.WriteString(s)
-}
-
-func Cwrite(p []byte) {
-	coutbuf.Write(p)
-}
-
-func Cput(c uint8) {
-	coutbuf.w.WriteByte(c)
-	coutbuf.off++
-}
-
 func usage() {
 	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
 	objabi.Flagprint(2)
@@ -1909,23 +1964,31 @@
 type SymbolType int8
 
 const (
+	// see also http://9p.io/magic/man2html/1/nm
 	TextSym      SymbolType = 'T'
 	DataSym                 = 'D'
 	BSSSym                  = 'B'
 	UndefinedSym            = 'U'
 	TLSSym                  = 't'
-	FileSym                 = 'f'
 	FrameSym                = 'm'
 	ParamSym                = 'p'
 	AutoSym                 = 'a'
+
+	// Deleted auto (not a real sym, just placeholder for type)
+	DeletedAutoSym = 'x'
 )
 
-func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) {
+func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
 	// These symbols won't show up in the first loop below because we
-	// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
+	// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
 	s := ctxt.Syms.Lookup("runtime.text", 0)
-	if s.Type == STEXT {
-		put(ctxt, s, s.Name, TextSym, s.Value, nil)
+	if s.Type == sym.STEXT {
+		// We've already included this symbol in ctxt.Textp
+		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin.
+		// See data.go:/textaddress
+		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) {
+			put(ctxt, s, s.Name, TextSym, s.Value, nil)
+		}
 	}
 
 	n := 0
@@ -1943,15 +2006,20 @@
 		if s == nil {
 			break
 		}
-		if s.Type == STEXT {
+		if s.Type == sym.STEXT {
 			put(ctxt, s, s.Name, TextSym, s.Value, nil)
 		}
 		n++
 	}
 
 	s = ctxt.Syms.Lookup("runtime.etext", 0)
-	if s.Type == STEXT {
-		put(ctxt, s, s.Name, TextSym, s.Value, nil)
+	if s.Type == sym.STEXT {
+		// We've already included this symbol in ctxt.Textp
+		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin.
+		// See data.go:/textaddress
+		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) {
+			put(ctxt, s, s.Name, TextSym, s.Value, nil)
+		}
 	}
 
 	for _, s := range ctxt.Syms.Allsym {
@@ -1961,36 +2029,36 @@
 		if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
 			continue
 		}
-		switch s.Type & SMASK {
-		case SCONST,
-			SRODATA,
-			SSYMTAB,
-			SPCLNTAB,
-			SINITARR,
-			SDATA,
-			SNOPTRDATA,
-			SELFROSECT,
-			SMACHOGOT,
-			STYPE,
-			SSTRING,
-			SGOSTRING,
-			SGOFUNC,
-			SGCBITS,
-			STYPERELRO,
-			SSTRINGRELRO,
-			SGOSTRINGRELRO,
-			SGOFUNCRELRO,
-			SGCBITSRELRO,
-			SRODATARELRO,
-			STYPELINK,
-			SITABLINK,
-			SWINDOWS:
+		switch s.Type {
+		case sym.SCONST,
+			sym.SRODATA,
+			sym.SSYMTAB,
+			sym.SPCLNTAB,
+			sym.SINITARR,
+			sym.SDATA,
+			sym.SNOPTRDATA,
+			sym.SELFROSECT,
+			sym.SMACHOGOT,
+			sym.STYPE,
+			sym.SSTRING,
+			sym.SGOSTRING,
+			sym.SGOFUNC,
+			sym.SGCBITS,
+			sym.STYPERELRO,
+			sym.SSTRINGRELRO,
+			sym.SGOSTRINGRELRO,
+			sym.SGOFUNCRELRO,
+			sym.SGCBITSRELRO,
+			sym.SRODATARELRO,
+			sym.STYPELINK,
+			sym.SITABLINK,
+			sym.SWINDOWS:
 			if !s.Attr.Reachable() {
 				continue
 			}
 			put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
 
-		case SBSS, SNOPTRBSS:
+		case sym.SBSS, sym.SNOPTRBSS:
 			if !s.Attr.Reachable() {
 				continue
 			}
@@ -1999,22 +2067,19 @@
 			}
 			put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
 
-		case SFILE:
-			put(ctxt, nil, s.Name, FileSym, s.Value, nil)
-
-		case SHOSTOBJ:
-			if Headtype == objabi.Hwindows || Iself {
+		case sym.SHOSTOBJ:
+			if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
 				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
 			}
 
-		case SDYNIMPORT:
+		case sym.SDYNIMPORT:
 			if !s.Attr.Reachable() {
 				continue
 			}
 			put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
 
-		case STLSBSS:
-			if Linkmode == LinkExternal {
+		case sym.STLSBSS:
+			if ctxt.LinkMode == LinkExternal {
 				put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
 			}
 		}
@@ -2029,12 +2094,17 @@
 			locals = s.FuncInfo.Locals
 		}
 		// NOTE(ality): acid can't produce a stack trace without .frame symbols
-		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil)
+		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
 
 		if s.FuncInfo == nil {
 			continue
 		}
 		for _, a := range s.FuncInfo.Autom {
+			if a.Name == objabi.A_DELETED_AUTO {
+				put(ctxt, nil, "", DeletedAutoSym, 0, a.Gotype)
+				continue
+			}
+
 			// Emit a or p according to actual offset, even if label is wrong.
 			// This avoids negative offsets, which cannot be encoded.
 			if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM {
@@ -2045,7 +2115,7 @@
 			if a.Name == objabi.A_PARAM {
 				off = a.Aoffset
 			} else {
-				off = a.Aoffset - int32(SysArch.PtrSize)
+				off = a.Aoffset - int32(ctxt.Arch.PtrSize)
 			}
 
 			// FP
@@ -2055,8 +2125,8 @@
 			}
 
 			// SP
-			if off <= int32(-SysArch.PtrSize) {
-				put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype)
+			if off <= int32(-ctxt.Arch.PtrSize) {
+				put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(ctxt.Arch.PtrSize)), a.Gotype)
 				continue
 			}
 			// Otherwise, off is addressing the saved program counter.
@@ -2069,23 +2139,23 @@
 	}
 }
 
-func Symaddr(s *Symbol) int64 {
+func Symaddr(s *sym.Symbol) int64 {
 	if !s.Attr.Reachable() {
 		Errorf(s, "unreachable symbol in symaddr")
 	}
 	return s.Value
 }
 
-func (ctxt *Link) xdefine(p string, t SymKind, v int64) {
+func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
 	s := ctxt.Syms.Lookup(p, 0)
 	s.Type = t
 	s.Value = v
-	s.Attr |= AttrReachable
-	s.Attr |= AttrSpecial
-	s.Attr |= AttrLocal
+	s.Attr |= sym.AttrReachable
+	s.Attr |= sym.AttrSpecial
+	s.Attr |= sym.AttrLocal
 }
 
-func datoff(s *Symbol, addr int64) int64 {
+func datoff(s *sym.Symbol, addr int64) int64 {
 	if uint64(addr) >= Segdata.Vaddr {
 		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
 	}
@@ -2105,21 +2175,23 @@
 	if s.Type == 0 {
 		return *FlagTextAddr
 	}
-	if s.Type != STEXT {
+	if s.Type != sym.STEXT {
 		Errorf(s, "entry not text")
 	}
 	return s.Value
 }
 
-func undefsym(ctxt *Link, s *Symbol) {
-	var r *Reloc
+func undefsym(ctxt *Link, s *sym.Symbol) {
+	var r *sym.Reloc
 
 	for i := 0; i < len(s.R); i++ {
 		r = &s.R[i]
 		if r.Sym == nil { // happens for some external ARM relocs
 			continue
 		}
-		if r.Sym.Type == Sxxx || r.Sym.Type == SXREF {
+		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
+		// sense and should be removed when someone has thought about it properly.
+		if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
 			Errorf(s, "undefined: %q", r.Sym.Name)
 		}
 		if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
@@ -2146,14 +2218,14 @@
 	}
 
 	var i int
-	var r *Reloc
+	var r *sym.Reloc
 	for _, s := range ctxt.Textp {
 		for i = 0; i < len(s.R); i++ {
 			r = &s.R[i]
 			if r.Sym == nil {
 				continue
 			}
-			if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == STEXT {
+			if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == sym.STEXT {
 				ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
 			}
 		}
@@ -2191,16 +2263,16 @@
 	visited
 )
 
-func postorder(libs []*Library) []*Library {
-	order := make([]*Library, 0, len(libs)) // hold the result
-	mark := make(map[*Library]markKind, len(libs))
+func postorder(libs []*sym.Library) []*sym.Library {
+	order := make([]*sym.Library, 0, len(libs)) // hold the result
+	mark := make(map[*sym.Library]markKind, len(libs))
 	for _, lib := range libs {
 		dfs(lib, mark, &order)
 	}
 	return order
 }
 
-func dfs(lib *Library, mark map[*Library]markKind, order *[]*Library) {
+func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
 	if mark[lib] == visited {
 		return
 	}
@@ -2208,7 +2280,7 @@
 		panic("found import cycle while visiting " + lib.Pkg)
 	}
 	mark[lib] = visiting
-	for _, i := range lib.imports {
+	for _, i := range lib.Imports {
 		dfs(i, mark, order)
 	}
 	mark[lib] = visited
diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go
index 302364c..a413353 100644
--- a/src/cmd/link/internal/ld/link.go
+++ b/src/cmd/link/internal/ld/link.go
@@ -34,185 +34,25 @@
 	"bufio"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"debug/elf"
 	"fmt"
 )
 
-// Symbol is an entry in the symbol table.
-type Symbol struct {
-	Name        string
-	Extname     string
-	Type        SymKind
-	Version     int16
-	Attr        Attribute
-	Localentry  uint8
-	Dynid       int32
-	Plt         int32
-	Got         int32
-	Align       int32
-	Elfsym      int32
-	LocalElfsym int32
-	Value       int64
-	Size        int64
-	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
-	// is not set for symbols defined by the packages being linked or by symbols
-	// read by ldelf (and so is left as elf.STT_NOTYPE).
-	ElfType     elf.SymType
-	Sub         *Symbol
-	Outer       *Symbol
-	Gotype      *Symbol
-	Reachparent *Symbol
-	File        string
-	Dynimplib   string
-	Dynimpvers  string
-	Sect        *Section
-	FuncInfo    *FuncInfo
-	// P contains the raw symbol data.
-	P []byte
-	R []Reloc
-}
-
-func (s *Symbol) String() string {
-	if s.Version == 0 {
-		return s.Name
-	}
-	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
-}
-
-func (s *Symbol) ElfsymForReloc() int32 {
-	// If putelfsym created a local version of this symbol, use that in all
-	// relocations.
-	if s.LocalElfsym != 0 {
-		return s.LocalElfsym
-	} else {
-		return s.Elfsym
-	}
-}
-
-func (s *Symbol) Len() int64 {
-	return s.Size
-}
-
-// Attribute is a set of common symbol attributes.
-type Attribute int16
-
-const (
-	// AttrDuplicateOK marks a symbol that can be present in multiple object
-	// files.
-	AttrDuplicateOK Attribute = 1 << iota
-	// AttrExternal marks function symbols loaded from host object files.
-	AttrExternal
-	// AttrNoSplit marks functions that cannot split the stack; the linker
-	// cares because it checks that there are no call chains of nosplit
-	// functions that require more than StackLimit bytes (see
-	// lib.go:dostkcheck)
-	AttrNoSplit
-	// AttrReachable marks symbols that are transitively referenced from the
-	// entry points. Unreachable symbols are not written to the output.
-	AttrReachable
-	// AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
-	// by directives written by cgo (in response to //export directives in
-	// the source).
-	AttrCgoExportDynamic
-	AttrCgoExportStatic
-	// AttrSpecial marks symbols that do not have their address (i.e. Value)
-	// computed by the usual mechanism of data.go:dodata() &
-	// data.go:address().
-	AttrSpecial
-	// AttrStackCheck is used by dostkcheck to only check each NoSplit
-	// function's stack usage once.
-	AttrStackCheck
-	// AttrNotInSymbolTable marks symbols that are not written to the symbol table.
-	AttrNotInSymbolTable
-	// AttrOnList marks symbols that are on some list (such as the list of
-	// all text symbols, or one of the lists of data symbols) and is
-	// consulted to avoid bugs where a symbol is put on a list twice.
-	AttrOnList
-	// AttrLocal marks symbols that are only visible within the module
-	// (exectuable or shared library) being linked. Only relevant when
-	// dynamically linking Go code.
-	AttrLocal
-	// AttrReflectMethod marks certain methods from the reflect package that
-	// can be used to call arbitrary methods. If no symbol with this bit set
-	// is marked as reachable, more dead code elimination can be done.
-	AttrReflectMethod
-	// AttrMakeTypelink Amarks types that should be added to the typelink
-	// table. See typelinks.go:typelinks().
-	AttrMakeTypelink
-	// AttrShared marks symbols compiled with the -shared option.
-	AttrShared
-	// 14 attributes defined so far.
-)
-
-func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
-func (a Attribute) External() bool         { return a&AttrExternal != 0 }
-func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
-func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
-func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
-func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
-func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
-func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
-func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
-func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
-func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
-func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
-func (a Attribute) MakeTypelink() bool     { return a&AttrMakeTypelink != 0 }
-func (a Attribute) Shared() bool           { return a&AttrShared != 0 }
-
-func (a Attribute) CgoExport() bool {
-	return a.CgoExportDynamic() || a.CgoExportStatic()
-}
-
-func (a *Attribute) Set(flag Attribute, value bool) {
-	if value {
-		*a |= flag
-	} else {
-		*a &^= flag
-	}
-}
-
-// Reloc is a relocation.
-//
-// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
-// A Reloc is stored in a slice on the Symbol it rewrites.
-//
-// Relocations are generated by the compiler as the type
-// cmd/internal/obj.Reloc, which is encoded into the object file wire
-// format and decoded by the linker into this type. A separate type is
-// used to hold linker-specific state about the relocation.
-//
-// Some relocations are created by cmd/link.
-type Reloc struct {
-	Off     int32            // offset to rewrite
-	Siz     uint8            // number of bytes to rewrite, 1, 2, or 4
-	Done    uint8            // set to 1 when relocation is complete
-	Variant RelocVariant     // variation on Type
-	Type    objabi.RelocType // the relocation type
-	Add     int64            // addend
-	Xadd    int64            // addend passed to external linker
-	Sym     *Symbol          // symbol the relocation addresses
-	Xsym    *Symbol          // symbol passed to external linker
-}
-
-type Auto struct {
-	Asym    *Symbol
-	Gotype  *Symbol
-	Aoffset int32
-	Name    int16
-}
-
 type Shlib struct {
 	Path            string
 	Hash            []byte
 	Deps            []string
 	File            *elf.File
-	gcdataAddresses map[*Symbol]uint64
+	gcdataAddresses map[*sym.Symbol]uint64
 }
 
 // Link holds the context for writing object code from a compiler
 // or for reading that input into the linker.
 type Link struct {
-	Syms *Symbols
+	Out *OutBuf
+
+	Syms *sym.Symbols
 
 	Arch      *sys.Arch
 	Debugvlog int
@@ -220,20 +60,27 @@
 
 	Loaded bool // set after all inputs have been loaded as symbols
 
-	Tlsg         *Symbol
+	IsELF    bool
+	HeadType objabi.HeadType
+
+	linkShared bool // link against installed Go shared libraries
+	LinkMode   LinkMode
+	BuildMode  BuildMode
+
+	Tlsg         *sym.Symbol
 	Libdir       []string
-	Library      []*Library
-	LibraryByPkg map[string]*Library
+	Library      []*sym.Library
+	LibraryByPkg map[string]*sym.Library
 	Shlibs       []Shlib
 	Tlsoffset    int
-	Textp        []*Symbol
-	Filesyms     []*Symbol
-	Moduledata   *Symbol
+	Textp        []*sym.Symbol
+	Filesyms     []*sym.Symbol
+	Moduledata   *sym.Symbol
 
 	PackageFile  map[string]string
 	PackageShlib map[string]string
 
-	tramps []*Symbol // trampolines
+	tramps []*sym.Symbol // trampolines
 }
 
 // The smallest possible offset from the hardware stack pointer to a local
@@ -253,56 +100,24 @@
 	}
 }
 
-func (l *Link) Logf(format string, args ...interface{}) {
-	fmt.Fprintf(l.Bso, format, args...)
-	l.Bso.Flush()
+func (ctxt *Link) Logf(format string, args ...interface{}) {
+	fmt.Fprintf(ctxt.Bso, format, args...)
+	ctxt.Bso.Flush()
 }
 
-type Library struct {
-	Objref      string
-	Srcref      string
-	File        string
-	Pkg         string
-	Shlib       string
-	hash        string
-	imports     []*Library
-	textp       []*Symbol // text symbols defined in this library
-	dupTextSyms []*Symbol // dupok text symbols defined in this library
-}
-
-func (l Library) String() string {
-	return l.Pkg
-}
-
-type FuncInfo struct {
-	Args        int32
-	Locals      int32
-	Autom       []Auto
-	Pcsp        Pcdata
-	Pcfile      Pcdata
-	Pcline      Pcdata
-	Pcinline    Pcdata
-	Pcdata      []Pcdata
-	Funcdata    []*Symbol
-	Funcdataoff []int64
-	File        []*Symbol
-	InlTree     []InlinedCall
-}
-
-// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
-type InlinedCall struct {
-	Parent int32   // index of parent in InlTree
-	File   *Symbol // file of the inlined call
-	Line   int32   // line number of the inlined call
-	Func   *Symbol // function that was inlined
-}
-
-type Pcdata struct {
-	P []byte
+func addImports(ctxt *Link, l *sym.Library, pn string) {
+	pkg := objabi.PathToPrefix(l.Pkg)
+	for _, importStr := range l.ImportStrings {
+		lib := addlib(ctxt, pkg, pn, importStr)
+		if lib != nil {
+			l.Imports = append(l.Imports, lib)
+		}
+	}
+	l.ImportStrings = nil
 }
 
 type Pciter struct {
-	d       Pcdata
+	d       sym.Pcdata
 	p       []byte
 	pc      uint32
 	nextpc  uint32
@@ -311,22 +126,3 @@
 	start   int
 	done    int
 }
-
-// RelocVariant is a linker-internal variation on a relocation.
-type RelocVariant uint8
-
-const (
-	RV_NONE RelocVariant = iota
-	RV_POWER_LO
-	RV_POWER_HI
-	RV_POWER_HA
-	RV_POWER_DS
-
-	// RV_390_DBL is a s390x-specific relocation variant that indicates that
-	// the value to be placed into the relocatable field should first be
-	// divided by 2.
-	RV_390_DBL
-
-	RV_CHECK_OVERFLOW RelocVariant = 1 << 7
-	RV_TYPE_MASK      RelocVariant = RV_CHECK_OVERFLOW - 1
-)
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 59c81a6..2b38ec0 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -5,7 +5,9 @@
 package ld
 
 import (
+	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"sort"
 	"strings"
 )
@@ -90,6 +92,56 @@
 	MACHO_FAKE_GOTPCREL           = 100
 )
 
+const (
+	MH_MAGIC    = 0xfeedface
+	MH_MAGIC_64 = 0xfeedfacf
+
+	MH_OBJECT  = 0x1
+	MH_EXECUTE = 0x2
+
+	MH_NOUNDEFS = 0x1
+)
+
+const (
+	LC_SEGMENT              = 0x1
+	LC_SYMTAB               = 0x2
+	LC_UNIXTHREAD           = 0x5
+	LC_DYSYMTAB             = 0xb
+	LC_LOAD_DYLIB           = 0xc
+	LC_ID_DYLIB             = 0xd
+	LC_LOAD_DYLINKER        = 0xe
+	LC_PREBOUND_DYLIB       = 0x10
+	LC_LOAD_WEAK_DYLIB      = 0x18
+	LC_SEGMENT_64           = 0x19
+	LC_UUID                 = 0x1b
+	LC_RPATH                = 0x8000001c
+	LC_CODE_SIGNATURE       = 0x1d
+	LC_SEGMENT_SPLIT_INFO   = 0x1e
+	LC_REEXPORT_DYLIB       = 0x8000001f
+	LC_ENCRYPTION_INFO      = 0x21
+	LC_DYLD_INFO            = 0x22
+	LC_DYLD_INFO_ONLY       = 0x80000022
+	LC_VERSION_MIN_MACOSX   = 0x24
+	LC_VERSION_MIN_IPHONEOS = 0x25
+	LC_FUNCTION_STARTS      = 0x26
+	LC_MAIN                 = 0x80000028
+	LC_DATA_IN_CODE         = 0x29
+	LC_SOURCE_VERSION       = 0x2A
+	LC_DYLIB_CODE_SIGN_DRS  = 0x2B
+	LC_ENCRYPTION_INFO_64   = 0x2C
+)
+
+const (
+	S_REGULAR                  = 0x0
+	S_ZEROFILL                 = 0x1
+	S_NON_LAZY_SYMBOL_POINTERS = 0x6
+	S_SYMBOL_STUBS             = 0x8
+	S_MOD_INIT_FUNC_POINTERS   = 0x9
+	S_ATTR_PURE_INSTRUCTIONS   = 0x80000000
+	S_ATTR_DEBUG               = 0x02000000
+	S_ATTR_SOME_INSTRUCTIONS   = 0x00000400
+)
+
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -97,8 +149,6 @@
 // Mach-O file writing
 // http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
 
-var macho64 bool
-
 var machohdr MachoHdr
 
 var load []MachoLoad
@@ -120,7 +170,7 @@
 
 var nkind [NumSymKind]int
 
-var sortsym []*Symbol
+var sortsym []*sym.Symbol
 
 var nsortsym int
 
@@ -130,18 +180,14 @@
 // "big enough" header size. The initial header is
 // one page, the non-dynamic library stuff takes
 // up about 1300 bytes; we overestimate that as 2k.
-var loadBudget int = INITIAL_MACHO_HEADR - 2*1024
-
-func Machoinit() {
-	macho64 = SysArch.RegSize == 8
-}
+var loadBudget = INITIAL_MACHO_HEADR - 2*1024
 
 func getMachoHdr() *MachoHdr {
 	return &machohdr
 }
 
-func newMachoLoad(type_ uint32, ndata uint32) *MachoLoad {
-	if macho64 && (ndata&1 != 0) {
+func newMachoLoad(arch *sys.Arch, type_ uint32, ndata uint32) *MachoLoad {
+	if arch.PtrSize == 8 && (ndata&1 != 0) {
 		ndata++
 	}
 
@@ -184,14 +230,14 @@
 
 var linkoff int64
 
-func machowrite() int {
-	o1 := coutbuf.Offset()
+func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int {
+	o1 := out.Offset()
 
 	loadsize := 4 * 4 * ndebug
 	for i := 0; i < len(load); i++ {
 		loadsize += 4 * (len(load[i].data) + 2)
 	}
-	if macho64 {
+	if arch.PtrSize == 8 {
 		loadsize += 18 * 4 * nseg
 		loadsize += 20 * 4 * nsect
 	} else {
@@ -199,98 +245,98 @@
 		loadsize += 17 * 4 * nsect
 	}
 
-	if macho64 {
-		Thearch.Lput(0xfeedfacf)
+	if arch.PtrSize == 8 {
+		out.Write32(MH_MAGIC_64)
 	} else {
-		Thearch.Lput(0xfeedface)
+		out.Write32(MH_MAGIC)
 	}
-	Thearch.Lput(machohdr.cpu)
-	Thearch.Lput(machohdr.subcpu)
-	if Linkmode == LinkExternal {
-		Thearch.Lput(1) /* file type - mach object */
+	out.Write32(machohdr.cpu)
+	out.Write32(machohdr.subcpu)
+	if linkmode == LinkExternal {
+		out.Write32(MH_OBJECT) /* file type - mach object */
 	} else {
-		Thearch.Lput(2) /* file type - mach executable */
+		out.Write32(MH_EXECUTE) /* file type - mach executable */
 	}
-	Thearch.Lput(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
-	Thearch.Lput(uint32(loadsize))
-	Thearch.Lput(1) /* flags - no undefines */
-	if macho64 {
-		Thearch.Lput(0) /* reserved */
+	out.Write32(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
+	out.Write32(uint32(loadsize))
+	if nkind[SymKindUndef] == 0 {
+		out.Write32(MH_NOUNDEFS) /* flags - no undefines */
+	} else {
+		out.Write32(0) /* flags */
+	}
+	if arch.PtrSize == 8 {
+		out.Write32(0) /* reserved */
 	}
 
-	var j int
-	var s *MachoSeg
-	var t *MachoSect
 	for i := 0; i < nseg; i++ {
-		s = &seg[i]
-		if macho64 {
-			Thearch.Lput(25) /* segment 64 */
-			Thearch.Lput(72 + 80*s.nsect)
-			strnput(s.name, 16)
-			Thearch.Vput(s.vaddr)
-			Thearch.Vput(s.vsize)
-			Thearch.Vput(s.fileoffset)
-			Thearch.Vput(s.filesize)
-			Thearch.Lput(s.prot1)
-			Thearch.Lput(s.prot2)
-			Thearch.Lput(s.nsect)
-			Thearch.Lput(s.flag)
+		s := &seg[i]
+		if arch.PtrSize == 8 {
+			out.Write32(LC_SEGMENT_64)
+			out.Write32(72 + 80*s.nsect)
+			out.WriteStringN(s.name, 16)
+			out.Write64(s.vaddr)
+			out.Write64(s.vsize)
+			out.Write64(s.fileoffset)
+			out.Write64(s.filesize)
+			out.Write32(s.prot1)
+			out.Write32(s.prot2)
+			out.Write32(s.nsect)
+			out.Write32(s.flag)
 		} else {
-			Thearch.Lput(1) /* segment 32 */
-			Thearch.Lput(56 + 68*s.nsect)
-			strnput(s.name, 16)
-			Thearch.Lput(uint32(s.vaddr))
-			Thearch.Lput(uint32(s.vsize))
-			Thearch.Lput(uint32(s.fileoffset))
-			Thearch.Lput(uint32(s.filesize))
-			Thearch.Lput(s.prot1)
-			Thearch.Lput(s.prot2)
-			Thearch.Lput(s.nsect)
-			Thearch.Lput(s.flag)
+			out.Write32(LC_SEGMENT)
+			out.Write32(56 + 68*s.nsect)
+			out.WriteStringN(s.name, 16)
+			out.Write32(uint32(s.vaddr))
+			out.Write32(uint32(s.vsize))
+			out.Write32(uint32(s.fileoffset))
+			out.Write32(uint32(s.filesize))
+			out.Write32(s.prot1)
+			out.Write32(s.prot2)
+			out.Write32(s.nsect)
+			out.Write32(s.flag)
 		}
 
-		for j = 0; uint32(j) < s.nsect; j++ {
-			t = &s.sect[j]
-			if macho64 {
-				strnput(t.name, 16)
-				strnput(t.segname, 16)
-				Thearch.Vput(t.addr)
-				Thearch.Vput(t.size)
-				Thearch.Lput(t.off)
-				Thearch.Lput(t.align)
-				Thearch.Lput(t.reloc)
-				Thearch.Lput(t.nreloc)
-				Thearch.Lput(t.flag)
-				Thearch.Lput(t.res1) /* reserved */
-				Thearch.Lput(t.res2) /* reserved */
-				Thearch.Lput(0)      /* reserved */
+		for j := uint32(0); j < s.nsect; j++ {
+			t := &s.sect[j]
+			if arch.PtrSize == 8 {
+				out.WriteStringN(t.name, 16)
+				out.WriteStringN(t.segname, 16)
+				out.Write64(t.addr)
+				out.Write64(t.size)
+				out.Write32(t.off)
+				out.Write32(t.align)
+				out.Write32(t.reloc)
+				out.Write32(t.nreloc)
+				out.Write32(t.flag)
+				out.Write32(t.res1) /* reserved */
+				out.Write32(t.res2) /* reserved */
+				out.Write32(0)      /* reserved */
 			} else {
-				strnput(t.name, 16)
-				strnput(t.segname, 16)
-				Thearch.Lput(uint32(t.addr))
-				Thearch.Lput(uint32(t.size))
-				Thearch.Lput(t.off)
-				Thearch.Lput(t.align)
-				Thearch.Lput(t.reloc)
-				Thearch.Lput(t.nreloc)
-				Thearch.Lput(t.flag)
-				Thearch.Lput(t.res1) /* reserved */
-				Thearch.Lput(t.res2) /* reserved */
+				out.WriteStringN(t.name, 16)
+				out.WriteStringN(t.segname, 16)
+				out.Write32(uint32(t.addr))
+				out.Write32(uint32(t.size))
+				out.Write32(t.off)
+				out.Write32(t.align)
+				out.Write32(t.reloc)
+				out.Write32(t.nreloc)
+				out.Write32(t.flag)
+				out.Write32(t.res1) /* reserved */
+				out.Write32(t.res2) /* reserved */
 			}
 		}
 	}
 
-	var l *MachoLoad
 	for i := 0; i < len(load); i++ {
-		l = &load[i]
-		Thearch.Lput(l.type_)
-		Thearch.Lput(4 * (uint32(len(l.data)) + 2))
-		for j = 0; j < len(l.data); j++ {
-			Thearch.Lput(l.data[j])
+		l := &load[i]
+		out.Write32(l.type_)
+		out.Write32(4 * (uint32(len(l.data)) + 2))
+		for j := 0; j < len(l.data); j++ {
+			out.Write32(l.data[j])
 		}
 	}
 
-	return int(coutbuf.Offset() - o1)
+	return int(out.Offset() - o1)
 }
 
 func (ctxt *Link) domacho() {
@@ -301,36 +347,41 @@
 	// empirically, string table must begin with " \x00".
 	s := ctxt.Syms.Lookup(".machosymstr", 0)
 
-	s.Type = SMACHOSYMSTR
-	s.Attr |= AttrReachable
-	Adduint8(ctxt, s, ' ')
-	Adduint8(ctxt, s, '\x00')
+	s.Type = sym.SMACHOSYMSTR
+	s.Attr |= sym.AttrReachable
+	s.AddUint8(' ')
+	s.AddUint8('\x00')
 
 	s = ctxt.Syms.Lookup(".machosymtab", 0)
-	s.Type = SMACHOSYMTAB
-	s.Attr |= AttrReachable
+	s.Type = sym.SMACHOSYMTAB
+	s.Attr |= sym.AttrReachable
 
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
-		s.Type = SMACHOPLT
-		s.Attr |= AttrReachable
+		s.Type = sym.SMACHOPLT
+		s.Attr |= sym.AttrReachable
 
 		s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
-		s.Type = SMACHOGOT
-		s.Attr |= AttrReachable
+		s.Type = sym.SMACHOGOT
+		s.Attr |= sym.AttrReachable
 		s.Align = 4
 
 		s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
-		s.Type = SMACHOINDIRECTPLT
-		s.Attr |= AttrReachable
+		s.Type = sym.SMACHOINDIRECTPLT
+		s.Attr |= sym.AttrReachable
 
 		s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
-		s.Type = SMACHOINDIRECTGOT
-		s.Attr |= AttrReachable
+		s.Type = sym.SMACHOINDIRECTGOT
+		s.Attr |= sym.AttrReachable
 	}
 }
 
-func Machoadddynlib(lib string) {
+func machoadddynlib(lib string, linkmode LinkMode) {
+	if seenlib[lib] || linkmode == LinkExternal {
+		return
+	}
+	seenlib[lib] = true
+
 	// Will need to store the library name rounded up
 	// and 24 bytes of header metadata. If not enough
 	// space, grab another page of initial space at the
@@ -346,13 +397,13 @@
 	dylib = append(dylib, lib)
 }
 
-func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
+func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
 	buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
 
 	var msect *MachoSect
-	if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
-		(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin)) ||
-		(SysArch.Family == sys.ARM && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin))) {
+	if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
+		(ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe) ||
+		(ctxt.Arch.Family == sys.ARM && ctxt.BuildMode != BuildModeExe)) {
 		// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
 		// complains about absolute relocs in __TEXT, so if the section is not
 		// executable, put it in __DATA segment.
@@ -379,36 +430,34 @@
 		}
 		msect.off = uint32(sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr)
 	} else {
-		// zero fill
 		msect.off = 0
-
-		msect.flag |= 1
+		msect.flag |= S_ZEROFILL
 	}
 
 	if sect.Rwx&1 != 0 {
-		msect.flag |= 0x400 /* has instructions */
+		msect.flag |= S_ATTR_SOME_INSTRUCTIONS
 	}
 
 	if sect.Name == ".plt" {
 		msect.name = "__symbol_stub1"
-		msect.flag = 0x80000408 /* only instructions, code, symbol stubs */
-		msect.res1 = 0          //nkind[SymKindLocal];
+		msect.flag = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS | S_SYMBOL_STUBS
+		msect.res1 = 0 //nkind[SymKindLocal];
 		msect.res2 = 6
 	}
 
 	if sect.Name == ".got" {
 		msect.name = "__nl_symbol_ptr"
-		msect.flag = 6                                                     /* section with nonlazy symbol pointers */
+		msect.flag = S_NON_LAZY_SYMBOL_POINTERS
 		msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
 	}
 
 	if sect.Name == ".init_array" {
 		msect.name = "__mod_init_func"
-		msect.flag = 9 // S_MOD_INIT_FUNC_POINTERS
+		msect.flag = S_MOD_INIT_FUNC_POINTERS
 	}
 
 	if segname == "__DWARF" {
-		msect.flag |= 0x02000000
+		msect.flag |= S_ATTR_DEBUG
 	}
 }
 
@@ -417,9 +466,9 @@
 	va := *FlagTextAddr - int64(HEADR)
 
 	mh := getMachoHdr()
-	switch SysArch.Family {
+	switch ctxt.Arch.Family {
 	default:
-		Exitf("unknown macho architecture: %v", SysArch.Family)
+		Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
 
 	case sys.ARM:
 		mh.cpu = MACHO_CPU_ARM
@@ -439,12 +488,12 @@
 	}
 
 	var ms *MachoSeg
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		/* segment for entire file */
 		ms = newMachoSeg("", 40)
 
 		ms.fileoffset = Segtext.Fileoff
-		if SysArch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
+		if ctxt.Arch.Family == sys.ARM || ctxt.BuildMode == BuildModeCArchive {
 			ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
 		} else {
 			ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
@@ -453,7 +502,7 @@
 	}
 
 	/* segment for zero page */
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		ms = newMachoSeg("__PAGEZERO", 0)
 		ms.vsize = uint64(va)
 	}
@@ -461,7 +510,7 @@
 	/* text */
 	v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound))
 
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		ms = newMachoSeg("__TEXT", 20)
 		ms.vaddr = uint64(va)
 		ms.vsize = uint64(v)
@@ -476,7 +525,7 @@
 	}
 
 	/* data */
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		w := int64(Segdata.Length)
 		ms = newMachoSeg("__DATA", 20)
 		ms.vaddr = uint64(va) + uint64(v)
@@ -493,7 +542,7 @@
 
 	/* dwarf */
 	if !*FlagW {
-		if Linkmode != LinkExternal {
+		if ctxt.LinkMode != LinkExternal {
 			ms = newMachoSeg("__DWARF", 20)
 			ms.vaddr = Segdwarf.Vaddr
 			ms.vsize = 0
@@ -505,33 +554,33 @@
 		}
 	}
 
-	if Linkmode != LinkExternal {
-		switch SysArch.Family {
+	if ctxt.LinkMode != LinkExternal {
+		switch ctxt.Arch.Family {
 		default:
-			Exitf("unknown macho architecture: %v", SysArch.Family)
+			Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
 
 		case sys.ARM:
-			ml := newMachoLoad(5, 17+2)              /* unix thread */
+			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 17+2)
 			ml.data[0] = 1                           /* thread type */
 			ml.data[1] = 17                          /* word count */
 			ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */
 
 		case sys.AMD64:
-			ml := newMachoLoad(5, 42+2)              /* unix thread */
+			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 42+2)
 			ml.data[0] = 4                           /* thread type */
 			ml.data[1] = 42                          /* word count */
 			ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
 			ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)
 
 		case sys.ARM64:
-			ml := newMachoLoad(5, 68+2)              /* unix thread */
+			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2)
 			ml.data[0] = 6                           /* thread type */
 			ml.data[1] = 68                          /* word count */
 			ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */
 			ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32)
 
 		case sys.I386:
-			ml := newMachoLoad(5, 16+2)              /* unix thread */
+			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 16+2)
 			ml.data[0] = 1                           /* thread type */
 			ml.data[1] = 16                          /* word count */
 			ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
@@ -545,7 +594,7 @@
 		s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
 		s4 := ctxt.Syms.Lookup(".machosymstr", 0)
 
-		if Linkmode != LinkExternal {
+		if ctxt.LinkMode != LinkExternal {
 			ms := newMachoSeg("__LINKEDIT", 0)
 			ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
 			ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
@@ -555,7 +604,7 @@
 			ms.prot2 = 3
 		}
 
-		ml := newMachoLoad(2, 4)                                   /* LC_SYMTAB */
+		ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4)
 		ml.data[0] = uint32(linkoff)                               /* symoff */
 		ml.data[1] = uint32(nsortsym)                              /* nsyms */
 		ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
@@ -563,23 +612,23 @@
 
 		machodysymtab(ctxt)
 
-		if Linkmode != LinkExternal {
-			ml := newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
-			ml.data[0] = 12           /* offset to string */
+		if ctxt.LinkMode != LinkExternal {
+			ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
+			ml.data[0] = 12 /* offset to string */
 			stringtouint32(ml.data[1:], "/usr/lib/dyld")
 
 			for i := 0; i < len(dylib); i++ {
-				ml = newMachoLoad(12, 4+(uint32(len(dylib[i]))+1+7)/8*2) /* LC_LOAD_DYLIB */
-				ml.data[0] = 24                                          /* offset of string from beginning of load */
-				ml.data[1] = 0                                           /* time stamp */
-				ml.data[2] = 0                                           /* version */
-				ml.data[3] = 0                                           /* compatibility version */
+				ml = newMachoLoad(ctxt.Arch, LC_LOAD_DYLIB, 4+(uint32(len(dylib[i]))+1+7)/8*2)
+				ml.data[0] = 24 /* offset of string from beginning of load */
+				ml.data[1] = 0  /* time stamp */
+				ml.data[2] = 0  /* version */
+				ml.data[3] = 0  /* compatibility version */
 				stringtouint32(ml.data[4:], dylib[i])
 			}
 		}
 	}
 
-	if Linkmode == LinkInternal {
+	if ctxt.LinkMode == LinkInternal {
 		// For lldb, must say LC_VERSION_MIN_MACOSX or else
 		// it won't know that this Mach-O binary is from OS X
 		// (could be iOS or WatchOS instead).
@@ -588,21 +637,19 @@
 		// and we can assume OS X.
 		//
 		// See golang.org/issues/12941.
-		const LC_VERSION_MIN_MACOSX = 0x24
-
-		ml := newMachoLoad(LC_VERSION_MIN_MACOSX, 2)
+		ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2)
 		ml.data[0] = 10<<16 | 7<<8 | 0<<0 // OS X version 10.7.0
 		ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
 	}
 
-	a := machowrite()
+	a := machowrite(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
 	if int32(a) > HEADR {
 		Exitf("HEADR too small: %d > %d", a, HEADR)
 	}
 }
 
-func symkind(s *Symbol) int {
-	if s.Type == SDYNIMPORT {
+func symkind(s *sym.Symbol) int {
+	if s.Type == sym.SDYNIMPORT {
 		return SymKindUndef
 	}
 	if s.Attr.CgoExport() {
@@ -611,7 +658,7 @@
 	return SymKindLocal
 }
 
-func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
+func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
 	if s == nil {
 		return
 	}
@@ -632,7 +679,7 @@
 	nsortsym++
 }
 
-type machoscmp []*Symbol
+type machoscmp []*sym.Symbol
 
 func (x machoscmp) Len() int {
 	return len(x)
@@ -658,7 +705,7 @@
 func machogenasmsym(ctxt *Link) {
 	genasmsym(ctxt, addsym)
 	for _, s := range ctxt.Syms.Allsym {
-		if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
+		if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
 			if s.Attr.Reachable() {
 				addsym(ctxt, s, "", DataSym, 0, nil)
 			}
@@ -671,10 +718,10 @@
 	// So we sort them here and pre-allocate dynid for them
 	// See https://golang.org/issue/4029
 	for i := 0; i < len(dynexp); i++ {
-		dynexp[i].Attr |= AttrReachable
+		dynexp[i].Attr |= sym.AttrReachable
 	}
 	machogenasmsym(ctxt)
-	sortsym = make([]*Symbol, nsortsym)
+	sortsym = make([]*sym.Symbol, nsortsym)
 	nsortsym = 0
 	machogenasmsym(ctxt)
 	sort.Sort(machoscmp(sortsym[:nsortsym]))
@@ -687,11 +734,14 @@
 //
 // When dynamically linking, all non-local variables and plugin-exported
 // symbols need to be exported.
-func machoShouldExport(ctxt *Link, s *Symbol) bool {
+func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
 	if !ctxt.DynlinkingGo() || s.Attr.Local() {
 		return false
 	}
-	if Buildmode == BuildmodePlugin && strings.HasPrefix(s.Extname, *flagPluginPath) {
+	if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname, objabi.PathToPrefix(*flagPluginPath)) {
+		return true
+	}
+	if strings.HasPrefix(s.Name, "go.itab.") {
 		return true
 	}
 	if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") {
@@ -703,7 +753,7 @@
 	if strings.HasPrefix(s.Name, "go.link.pkghash") {
 		return true
 	}
-	return s.Type >= SELFSECT // only writable sections
+	return s.Type >= sym.SELFSECT // only writable sections
 }
 
 func machosymtab(ctxt *Link) {
@@ -712,7 +762,7 @@
 
 	for i := 0; i < nsortsym; i++ {
 		s := sortsym[i]
-		Adduint32(ctxt, symtab, uint32(symstr.Size))
+		symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
 
 		export := machoShouldExport(ctxt, s)
 
@@ -723,24 +773,24 @@
 		// symbols like crosscall2 are in pclntab and end up
 		// pointing at the host binary, breaking unwinding.
 		// See Issue #18190.
-		cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
+		cexport := !strings.Contains(s.Extname, ".") && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s))
 		if cexport || export {
-			Adduint8(ctxt, symstr, '_')
+			symstr.AddUint8('_')
 		}
 
 		// replace "·" as ".", because DTrace cannot handle it.
 		Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
 
-		if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
-			Adduint8(ctxt, symtab, 0x01)                // type N_EXT, external symbol
-			Adduint8(ctxt, symtab, 0)                   // no section
-			Adduint16(ctxt, symtab, 0)                  // desc
-			adduintxx(ctxt, symtab, 0, SysArch.PtrSize) // no value
+		if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
+			symtab.AddUint8(0x01)                             // type N_EXT, external symbol
+			symtab.AddUint8(0)                                // no section
+			symtab.AddUint16(ctxt.Arch, 0)                    // desc
+			symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
 		} else {
 			if s.Attr.CgoExport() || export {
-				Adduint8(ctxt, symtab, 0x0f)
+				symtab.AddUint8(0x0f)
 			} else {
-				Adduint8(ctxt, symtab, 0x0e)
+				symtab.AddUint8(0x0e)
 			}
 			o := s
 			for o.Outer != nil {
@@ -748,18 +798,18 @@
 			}
 			if o.Sect == nil {
 				Errorf(s, "missing section for symbol")
-				Adduint8(ctxt, symtab, 0)
+				symtab.AddUint8(0)
 			} else {
-				Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
+				symtab.AddUint8(uint8(o.Sect.Extnum))
 			}
-			Adduint16(ctxt, symtab, 0) // desc
-			adduintxx(ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
+			symtab.AddUint16(ctxt.Arch, 0) // desc
+			symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
 		}
 	}
 }
 
 func machodysymtab(ctxt *Link) {
-	ml := newMachoLoad(11, 18) /* LC_DYSYMTAB */
+	ml := newMachoLoad(ctxt.Arch, LC_DYSYMTAB, 18)
 
 	n := 0
 	ml.data[0] = uint32(n)                   /* ilocalsym */
@@ -822,31 +872,31 @@
 	// any alignment padding itself, working around the
 	// issue.
 	for s4.Size%16 != 0 {
-		Adduint8(ctxt, s4, 0)
+		s4.AddUint8(0)
 	}
 
 	size := int(s1.Size + s2.Size + s3.Size + s4.Size)
 
 	if size > 0 {
 		linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
-		Cseek(linkoff)
+		ctxt.Out.SeekSet(linkoff)
 
-		Cwrite(s1.P[:s1.Size])
-		Cwrite(s2.P[:s2.Size])
-		Cwrite(s3.P[:s3.Size])
-		Cwrite(s4.P[:s4.Size])
+		ctxt.Out.Write(s1.P[:s1.Size])
+		ctxt.Out.Write(s2.P[:s2.Size])
+		ctxt.Out.Write(s3.P[:s3.Size])
+		ctxt.Out.Write(s4.P[:s4.Size])
 	}
 
 	return Rnd(int64(size), int64(*FlagRound))
 }
 
-func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
+func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
 	// If main section has no bits, nothing to relocate.
 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
 		return
 	}
 
-	sect.Reloff = uint64(coutbuf.Offset())
+	sect.Reloff = uint64(ctxt.Out.Offset())
 	for i, s := range syms {
 		if !s.Attr.Reachable() {
 			continue
@@ -858,37 +908,37 @@
 	}
 
 	eaddr := int32(sect.Vaddr + sect.Length)
-	for _, sym := range syms {
-		if !sym.Attr.Reachable() {
+	for _, s := range syms {
+		if !s.Attr.Reachable() {
 			continue
 		}
-		if sym.Value >= int64(eaddr) {
+		if s.Value >= int64(eaddr) {
 			break
 		}
-		for ri := 0; ri < len(sym.R); ri++ {
-			r := &sym.R[ri]
-			if r.Done != 0 {
+		for ri := 0; ri < len(s.R); ri++ {
+			r := &s.R[ri]
+			if r.Done {
 				continue
 			}
 			if r.Xsym == nil {
-				Errorf(sym, "missing xsym in relocation")
+				Errorf(s, "missing xsym in relocation")
 				continue
 			}
 			if !r.Xsym.Attr.Reachable() {
-				Errorf(sym, "unreachable reloc %v target %v", r.Type, r.Xsym.Name)
+				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
 			}
-			if Thearch.Machoreloc1(sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
-				Errorf(sym, "unsupported obj reloc %v/%d to %s", r.Type, r.Siz, r.Sym.Name)
+			if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
+				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
 			}
 		}
 	}
 
-	sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
+	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
 }
 
 func Machoemitreloc(ctxt *Link) {
-	for coutbuf.Offset()&7 != 0 {
-		Cput(0)
+	for ctxt.Out.Offset()&7 != 0 {
+		ctxt.Out.Write8(0)
 	}
 
 	machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
diff --git a/src/cmd/link/internal/ld/macho_combine_dwarf.go b/src/cmd/link/internal/ld/macho_combine_dwarf.go
index 8c6c4a8..17a484c 100644
--- a/src/cmd/link/internal/ld/macho_combine_dwarf.go
+++ b/src/cmd/link/internal/ld/macho_combine_dwarf.go
@@ -17,31 +17,10 @@
 
 var realdwarf, linkseg *macho.Segment
 var dwarfstart, linkstart int64
-var dwarfaddr, linkaddr int64
+var dwarfaddr int64
 var linkoffset uint32
 
 const (
-	LC_ID_DYLIB             = 0xd
-	LC_LOAD_DYLINKER        = 0xe
-	LC_PREBOUND_DYLIB       = 0x10
-	LC_LOAD_WEAK_DYLIB      = 0x18
-	LC_UUID                 = 0x1b
-	LC_RPATH                = 0x8000001c
-	LC_CODE_SIGNATURE       = 0x1d
-	LC_SEGMENT_SPLIT_INFO   = 0x1e
-	LC_REEXPORT_DYLIB       = 0x8000001f
-	LC_ENCRYPTION_INFO      = 0x21
-	LC_DYLD_INFO            = 0x22
-	LC_DYLD_INFO_ONLY       = 0x80000022
-	LC_VERSION_MIN_MACOSX   = 0x24
-	LC_VERSION_MIN_IPHONEOS = 0x25
-	LC_FUNCTION_STARTS      = 0x26
-	LC_MAIN                 = 0x80000028
-	LC_DATA_IN_CODE         = 0x29
-	LC_SOURCE_VERSION       = 0x2A
-	LC_DYLIB_CODE_SIGN_DRS  = 0x2B
-	LC_ENCRYPTION_INFO_64   = 0x2C
-
 	pageAlign = 12 // 4096 = 1 << 12
 )
 
@@ -112,7 +91,7 @@
 // header to add the DWARF sections. (Use ld's -headerpad option)
 // dsym is the path to the macho file containing DWARF from dsymutil.
 // outexe is the path where the combined executable should be saved.
-func machoCombineDwarf(inexe, dsym, outexe string) error {
+func machoCombineDwarf(inexe, dsym, outexe string, buildmode BuildMode) error {
 	exef, err := os.Open(inexe)
 	if err != nil {
 		return err
@@ -251,7 +230,7 @@
 			return err
 		}
 	}
-	return machoUpdateDwarfHeader(&reader)
+	return machoUpdateDwarfHeader(&reader, buildmode)
 }
 
 // machoUpdateSegment updates the load command for a moved segment.
@@ -312,7 +291,7 @@
 }
 
 // machoUpdateDwarfHeader updates the DWARF segment load command.
-func machoUpdateDwarfHeader(r *loadCmdReader) error {
+func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode) error {
 	var seg, sect interface{}
 	cmd, err := r.Next()
 	if err != nil {
@@ -342,7 +321,7 @@
 	// We don't need the DWARF information actually available in memory.
 	// But if we do this for buildmode=c-shared then the user-space
 	// dynamic loader complains about memsz < filesz. Sigh.
-	if Buildmode != BuildmodeCShared {
+	if buildmode != BuildModeCShared {
 		segv.FieldByName("Addr").SetUint(0)
 		segv.FieldByName("Memsz").SetUint(0)
 		deltaAddr = 0
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index f03460d..f86abbc 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -48,8 +48,6 @@
 )
 
 func init() {
-	flag.Var(&Linkmode, "linkmode", "set link `mode`")
-	flag.Var(&Buildmode, "buildmode", "set build `mode`")
 	flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...")
 }
 
@@ -59,7 +57,6 @@
 
 	flagOutfile    = flag.String("o", "", "write output to `file`")
 	flagPluginPath = flag.String("pluginpath", "", "full path name for plugin")
-	FlagLinkshared = flag.Bool("linkshared", false, "link against installed Go shared libraries")
 
 	flagInstallSuffix = flag.String("installsuffix", "", "set package directory `suffix`")
 	flagDumpDep       = flag.Bool("dumpdep", false, "dump symbol dependency graph")
@@ -88,7 +85,6 @@
 	flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
 	FlagDebugTramp  = flag.Int("debugtramp", 0, "debug trampolines")
 
-	flagHeadtype    = flag.String("H", "", "set header `type`")
 	FlagRound       = flag.Int("R", -1, "set address rounding `quantum`")
 	FlagTextAddr    = flag.Int64("T", -1, "set text segment `address`")
 	FlagDataAddr    = flag.Int64("D", -1, "set data segment `address`")
@@ -100,8 +96,9 @@
 )
 
 // Main is the main entry point for the linker code.
-func Main() {
-	ctxt := linknew(SysArch)
+func Main(arch *sys.Arch, theArch Arch) {
+	Thearch = theArch
+	ctxt := linknew(arch)
 	ctxt.Bso = bufio.NewWriter(os.Stdout)
 
 	// For testing behavior of go command when tools crash silently.
@@ -113,43 +110,51 @@
 		}
 	}
 
+	final := gorootFinal()
+	addstrdata1(ctxt, "runtime/internal/sys.DefaultGoroot="+final)
+	addstrdata1(ctxt, "cmd/internal/objabi.defaultGOROOT="+final)
+
 	// TODO(matloob): define these above and then check flag values here
-	if SysArch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
+	if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
 		flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
 	}
+	flagHeadType := flag.String("H", "", "set header `type`")
+	flag.BoolVar(&ctxt.linkShared, "linkshared", false, "link against installed Go shared libraries")
+	flag.Var(&ctxt.LinkMode, "linkmode", "set link `mode`")
+	flag.Var(&ctxt.BuildMode, "buildmode", "set build `mode`")
 	objabi.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
 	objabi.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
-	objabi.Flagfn0("V", "print version and exit", doversion)
+	objabi.AddVersionFlag() // -V
 	objabi.Flagfn1("X", "add string value `definition` of the form importpath.name=value", func(s string) { addstrdata1(ctxt, s) })
 	objabi.Flagcount("v", "print link trace", &ctxt.Debugvlog)
 	objabi.Flagfn1("importcfg", "read import configuration from `file`", ctxt.readImportCfg)
 
 	objabi.Flagparse(usage)
 
-	switch *flagHeadtype {
+	switch *flagHeadType {
 	case "":
 	case "windowsgui":
-		Headtype = objabi.Hwindows
+		ctxt.HeadType = objabi.Hwindows
 		windowsgui = true
 	default:
-		if err := Headtype.Set(*flagHeadtype); err != nil {
+		if err := ctxt.HeadType.Set(*flagHeadType); err != nil {
 			Errorf(nil, "%v", err)
 			usage()
 		}
 	}
 
 	startProfile()
-	if Buildmode == BuildmodeUnset {
-		Buildmode = BuildmodeExe
+	if ctxt.BuildMode == BuildModeUnset {
+		ctxt.BuildMode = BuildModeExe
 	}
 
-	if Buildmode != BuildmodeShared && flag.NArg() != 1 {
+	if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 {
 		usage()
 	}
 
 	if *flagOutfile == "" {
 		*flagOutfile = "a.out"
-		if Headtype == objabi.Hwindows {
+		if ctxt.HeadType == objabi.Hwindows {
 			*flagOutfile += ".exe"
 		}
 	}
@@ -158,23 +163,23 @@
 
 	libinit(ctxt) // creates outfile
 
-	if Headtype == objabi.Hunknown {
-		Headtype.Set(objabi.GOOS)
+	if ctxt.HeadType == objabi.Hunknown {
+		ctxt.HeadType.Set(objabi.GOOS)
 	}
 
 	ctxt.computeTLSOffset()
 	Thearch.Archinit(ctxt)
 
-	if *FlagLinkshared && !Iself {
+	if ctxt.linkShared && !ctxt.IsELF {
 		Exitf("-linkshared can only be used on elf systems")
 	}
 
 	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", Headtype, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound))
+		ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", ctxt.HeadType, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound))
 	}
 
-	switch Buildmode {
-	case BuildmodeShared:
+	switch ctxt.BuildMode {
+	case BuildModeShared:
 		for i := 0; i < flag.NArg(); i++ {
 			arg := flag.Arg(i)
 			parts := strings.SplitN(arg, "=", 2)
@@ -188,24 +193,24 @@
 			pkglistfornote = append(pkglistfornote, '\n')
 			addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
 		}
-	case BuildmodePlugin:
+	case BuildModePlugin:
 		addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "")
 	default:
 		addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
 	}
 	ctxt.loadlib()
 
-	ctxt.checkstrdata()
+	ctxt.dostrdata()
 	deadcode(ctxt)
 	fieldtrack(ctxt)
 	ctxt.callgraph()
 
 	ctxt.doelf()
-	if Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		ctxt.domacho()
 	}
 	ctxt.dostkcheck()
-	if Headtype == objabi.Hwindows {
+	if ctxt.HeadType == objabi.Hwindows {
 		ctxt.dope()
 	}
 	ctxt.addexport()
diff --git a/src/cmd/link/internal/ld/nooptcgolink_test.go b/src/cmd/link/internal/ld/nooptcgolink_test.go
index 1df2965..e019a39 100644
--- a/src/cmd/link/internal/ld/nooptcgolink_test.go
+++ b/src/cmd/link/internal/ld/nooptcgolink_test.go
@@ -22,7 +22,7 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	cmd := exec.Command("go", "build", "-gcflags=-N -l", "-o", filepath.Join(dir, "a.out"))
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-N -l", "-o", filepath.Join(dir, "a.out"))
 	cmd.Dir = filepath.Join(runtime.GOROOT(), "src", "runtime", "testdata", "testprogcgo")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/cmd/link/internal/ld/objfile.go b/src/cmd/link/internal/ld/objfile.go
deleted file mode 100644
index 13dde21..0000000
--- a/src/cmd/link/internal/ld/objfile.go
+++ /dev/null
@@ -1,556 +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 ld
-
-// Reading of Go object files.
-
-import (
-	"bufio"
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/dwarf"
-	"cmd/internal/objabi"
-	"crypto/sha1"
-	"encoding/base64"
-	"io"
-	"log"
-	"strconv"
-	"strings"
-)
-
-const (
-	startmagic = "\x00\x00go19ld"
-	endmagic   = "\xff\xffgo19ld"
-)
-
-var emptyPkg = []byte(`"".`)
-
-// objReader reads Go object files.
-type objReader struct {
-	rd              *bufio.Reader
-	ctxt            *Link
-	lib             *Library
-	pn              string
-	dupSym          *Symbol
-	localSymVersion int
-
-	// rdBuf is used by readString and readSymName as scratch for reading strings.
-	rdBuf []byte
-
-	// List of symbol references for the file being read.
-	refs        []*Symbol
-	data        []byte
-	reloc       []Reloc
-	pcdata      []Pcdata
-	autom       []Auto
-	funcdata    []*Symbol
-	funcdataoff []int64
-	file        []*Symbol
-}
-
-func LoadObjFile(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string) {
-
-	start := f.Offset()
-	r := &objReader{
-		rd:              f.Reader,
-		lib:             lib,
-		ctxt:            ctxt,
-		pn:              pn,
-		dupSym:          &Symbol{Name: ".dup"},
-		localSymVersion: ctxt.Syms.IncVersion(),
-	}
-	r.loadObjFile()
-	if f.Offset() != start+length {
-		log.Fatalf("%s: unexpected end at %d, want %d", pn, f.Offset(), start+length)
-	}
-}
-
-func (r *objReader) loadObjFile() {
-	pkg := objabi.PathToPrefix(r.lib.Pkg)
-
-	// Magic header
-	var buf [8]uint8
-	r.readFull(buf[:])
-	if string(buf[:]) != startmagic {
-		log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", r.pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])
-	}
-
-	// Version
-	c, err := r.rd.ReadByte()
-	if err != nil || c != 1 {
-		log.Fatalf("%s: invalid file version number %d", r.pn, c)
-	}
-
-	// Autolib
-	for {
-		lib := r.readString()
-		if lib == "" {
-			break
-		}
-		l := addlib(r.ctxt, pkg, r.pn, lib)
-		if l != nil {
-			r.lib.imports = append(r.lib.imports, l)
-		}
-	}
-
-	// Symbol references
-	r.refs = []*Symbol{nil} // zeroth ref is nil
-	for {
-		c, err := r.rd.Peek(1)
-		if err != nil {
-			log.Fatalf("%s: peeking: %v", r.pn, err)
-		}
-		if c[0] == 0xff {
-			r.rd.ReadByte()
-			break
-		}
-		r.readRef()
-	}
-
-	// Lengths
-	r.readSlices()
-
-	// Data section
-	r.readFull(r.data)
-
-	// Defined symbols
-	for {
-		c, err := r.rd.Peek(1)
-		if err != nil {
-			log.Fatalf("%s: peeking: %v", r.pn, err)
-		}
-		if c[0] == 0xff {
-			break
-		}
-		r.readSym()
-	}
-
-	// Magic footer
-	buf = [8]uint8{}
-	r.readFull(buf[:])
-	if string(buf[:]) != endmagic {
-		log.Fatalf("%s: invalid file end", r.pn)
-	}
-}
-
-func (r *objReader) readSlices() {
-	n := r.readInt()
-	r.data = make([]byte, n)
-	n = r.readInt()
-	r.reloc = make([]Reloc, n)
-	n = r.readInt()
-	r.pcdata = make([]Pcdata, n)
-	n = r.readInt()
-	r.autom = make([]Auto, n)
-	n = r.readInt()
-	r.funcdata = make([]*Symbol, n)
-	r.funcdataoff = make([]int64, n)
-	n = r.readInt()
-	r.file = make([]*Symbol, n)
-}
-
-// Symbols are prefixed so their content doesn't get confused with the magic footer.
-const symPrefix = 0xfe
-
-func (r *objReader) readSym() {
-	var c byte
-	var err error
-	if c, err = r.rd.ReadByte(); c != symPrefix || err != nil {
-		log.Fatalln("readSym out of sync")
-	}
-	if c, err = r.rd.ReadByte(); err != nil {
-		log.Fatalln("error reading input: ", err)
-	}
-	t := abiSymKindToSymKind[c]
-	s := r.readSymIndex()
-	flags := r.readInt()
-	dupok := flags&1 != 0
-	local := flags&2 != 0
-	makeTypelink := flags&4 != 0
-	size := r.readInt()
-	typ := r.readSymIndex()
-	data := r.readData()
-	nreloc := r.readInt()
-	pkg := objabi.PathToPrefix(r.lib.Pkg)
-	isdup := false
-
-	var dup *Symbol
-	if s.Type != 0 && s.Type != SXREF {
-		if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
-			if s.Size < int64(size) {
-				s.Size = int64(size)
-			}
-			if typ != nil && s.Gotype == nil {
-				s.Gotype = typ
-			}
-			return
-		}
-
-		if (s.Type == SDATA || s.Type == SBSS || s.Type == SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
-			goto overwrite
-		}
-		if s.Type != SBSS && s.Type != SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
-			log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn)
-		}
-		if len(s.P) > 0 {
-			dup = s
-			s = r.dupSym
-			isdup = true
-		}
-	}
-
-overwrite:
-	s.File = pkg
-	if dupok {
-		s.Attr |= AttrDuplicateOK
-	}
-	if t == SXREF {
-		log.Fatalf("bad sxref")
-	}
-	if t == 0 {
-		log.Fatalf("missing type for %s in %s", s.Name, r.pn)
-	}
-	if t == SBSS && (s.Type == SRODATA || s.Type == SNOPTRBSS) {
-		t = s.Type
-	}
-	s.Type = t
-	if s.Size < int64(size) {
-		s.Size = int64(size)
-	}
-	s.Attr.Set(AttrLocal, local)
-	s.Attr.Set(AttrMakeTypelink, makeTypelink)
-	if typ != nil {
-		s.Gotype = typ
-	}
-	if isdup && typ != nil { // if bss sym defined multiple times, take type from any one def
-		dup.Gotype = typ
-	}
-	s.P = data
-	if nreloc > 0 {
-		s.R = r.reloc[:nreloc:nreloc]
-		if !isdup {
-			r.reloc = r.reloc[nreloc:]
-		}
-
-		for i := 0; i < nreloc; i++ {
-			s.R[i] = Reloc{
-				Off:  r.readInt32(),
-				Siz:  r.readUint8(),
-				Type: objabi.RelocType(r.readInt32()),
-				Add:  r.readInt64(),
-				Sym:  r.readSymIndex(),
-			}
-		}
-	}
-
-	if s.Type == STEXT {
-		s.FuncInfo = new(FuncInfo)
-		pc := s.FuncInfo
-
-		pc.Args = r.readInt32()
-		pc.Locals = r.readInt32()
-		if r.readUint8() != 0 {
-			s.Attr |= AttrNoSplit
-		}
-		flags := r.readInt()
-		if flags&(1<<2) != 0 {
-			s.Attr |= AttrReflectMethod
-		}
-		if flags&(1<<3) != 0 {
-			s.Attr |= AttrShared
-		}
-		n := r.readInt()
-		pc.Autom = r.autom[:n:n]
-		if !isdup {
-			r.autom = r.autom[n:]
-		}
-
-		for i := 0; i < n; i++ {
-			pc.Autom[i] = Auto{
-				Asym:    r.readSymIndex(),
-				Aoffset: r.readInt32(),
-				Name:    r.readInt16(),
-				Gotype:  r.readSymIndex(),
-			}
-		}
-
-		pc.Pcsp.P = r.readData()
-		pc.Pcfile.P = r.readData()
-		pc.Pcline.P = r.readData()
-		pc.Pcinline.P = r.readData()
-		n = r.readInt()
-		pc.Pcdata = r.pcdata[:n:n]
-		if !isdup {
-			r.pcdata = r.pcdata[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.Pcdata[i].P = r.readData()
-		}
-		n = r.readInt()
-		pc.Funcdata = r.funcdata[:n:n]
-		pc.Funcdataoff = r.funcdataoff[:n:n]
-		if !isdup {
-			r.funcdata = r.funcdata[n:]
-			r.funcdataoff = r.funcdataoff[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.Funcdata[i] = r.readSymIndex()
-		}
-		for i := 0; i < n; i++ {
-			pc.Funcdataoff[i] = r.readInt64()
-		}
-		n = r.readInt()
-		pc.File = r.file[:n:n]
-		if !isdup {
-			r.file = r.file[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.File[i] = r.readSymIndex()
-		}
-		n = r.readInt()
-		pc.InlTree = make([]InlinedCall, n)
-		for i := 0; i < n; i++ {
-			pc.InlTree[i].Parent = r.readInt32()
-			pc.InlTree[i].File = r.readSymIndex()
-			pc.InlTree[i].Line = r.readInt32()
-			pc.InlTree[i].Func = r.readSymIndex()
-		}
-
-		if !dupok {
-			if s.Attr.OnList() {
-				log.Fatalf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= AttrOnList
-			r.lib.textp = append(r.lib.textp, s)
-		} else {
-			// there may ba a dup in another package
-			// put into a temp list and add to text later
-			if !isdup {
-				r.lib.dupTextSyms = append(r.lib.dupTextSyms, s)
-			} else {
-				r.lib.dupTextSyms = append(r.lib.dupTextSyms, dup)
-			}
-		}
-	}
-	if s.Type == SDWARFINFO {
-		r.patchDWARFName(s)
-	}
-}
-
-func (r *objReader) patchDWARFName(s *Symbol) {
-	// This is kind of ugly. Really the package name should not
-	// even be included here.
-	if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
-		return
-	}
-	e := bytes.IndexByte(s.P, 0)
-	if e == -1 {
-		return
-	}
-	p := bytes.Index(s.P[:e], emptyPkg)
-	if p == -1 {
-		return
-	}
-	pkgprefix := []byte(objabi.PathToPrefix(r.lib.Pkg) + ".")
-	patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1)
-
-	s.P = append(patched, s.P[e:]...)
-	delta := int64(len(s.P)) - s.Size
-	s.Size = int64(len(s.P))
-	for i := range s.R {
-		r := &s.R[i]
-		if r.Off > int32(e) {
-			r.Off += int32(delta)
-		}
-	}
-}
-
-func (r *objReader) readFull(b []byte) {
-	_, err := io.ReadFull(r.rd, b)
-	if err != nil {
-		log.Fatalf("%s: error reading %s", r.pn, err)
-	}
-}
-
-func (r *objReader) readRef() {
-	if c, err := r.rd.ReadByte(); c != symPrefix || err != nil {
-		log.Fatalf("readSym out of sync")
-	}
-	name := r.readSymName()
-	v := r.readInt()
-	if v != 0 && v != 1 {
-		log.Fatalf("invalid symbol version for %q: %d", name, v)
-	}
-	if v == 1 {
-		v = r.localSymVersion
-	}
-	s := r.ctxt.Syms.Lookup(name, v)
-	r.refs = append(r.refs, s)
-
-	if s == nil || v != 0 {
-		return
-	}
-	if s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 {
-		x, err := strconv.ParseUint(s.Name[5:], 16, 64)
-		if err != nil {
-			log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
-		}
-		s.Type = SRODATA
-		s.Attr |= AttrLocal
-		switch s.Name[:5] {
-		case "$f32.":
-			if uint64(uint32(x)) != x {
-				log.Panicf("$-symbol %s too large: %d", s.Name, x)
-			}
-			Adduint32(r.ctxt, s, uint32(x))
-		case "$f64.", "$i64.":
-			Adduint64(r.ctxt, s, x)
-		default:
-			log.Panicf("unrecognized $-symbol: %s", s.Name)
-		}
-		s.Attr.Set(AttrReachable, false)
-	}
-	if strings.HasPrefix(s.Name, "runtime.gcbits.") {
-		s.Attr |= AttrLocal
-	}
-}
-
-func (r *objReader) readInt64() int64 {
-	uv := uint64(0)
-	for shift := uint(0); ; shift += 7 {
-		if shift >= 64 {
-			log.Fatalf("corrupt input")
-		}
-		c, err := r.rd.ReadByte()
-		if err != nil {
-			log.Fatalln("error reading input: ", err)
-		}
-		uv |= uint64(c&0x7F) << shift
-		if c&0x80 == 0 {
-			break
-		}
-	}
-
-	return int64(uv>>1) ^ (int64(uv<<63) >> 63)
-}
-
-func (r *objReader) readInt() int {
-	n := r.readInt64()
-	if int64(int(n)) != n {
-		log.Panicf("%v out of range for int", n)
-	}
-	return int(n)
-}
-
-func (r *objReader) readInt32() int32 {
-	n := r.readInt64()
-	if int64(int32(n)) != n {
-		log.Panicf("%v out of range for int32", n)
-	}
-	return int32(n)
-}
-
-func (r *objReader) readInt16() int16 {
-	n := r.readInt64()
-	if int64(int16(n)) != n {
-		log.Panicf("%v out of range for int16", n)
-	}
-	return int16(n)
-}
-
-func (r *objReader) readUint8() uint8 {
-	n := r.readInt64()
-	if int64(uint8(n)) != n {
-		log.Panicf("%v out of range for uint8", n)
-	}
-	return uint8(n)
-}
-
-func (r *objReader) readString() string {
-	n := r.readInt()
-	if cap(r.rdBuf) < n {
-		r.rdBuf = make([]byte, 2*n)
-	}
-	r.readFull(r.rdBuf[:n])
-	return string(r.rdBuf[:n])
-}
-
-func (r *objReader) readData() []byte {
-	n := r.readInt()
-	p := r.data[:n:n]
-	r.data = r.data[n:]
-	return p
-}
-
-// readSymName reads a symbol name, replacing all "". with pkg.
-func (r *objReader) readSymName() string {
-	pkg := objabi.PathToPrefix(r.lib.Pkg)
-	n := r.readInt()
-	if n == 0 {
-		r.readInt64()
-		return ""
-	}
-	if cap(r.rdBuf) < n {
-		r.rdBuf = make([]byte, 2*n)
-	}
-	origName, err := r.rd.Peek(n)
-	if err == bufio.ErrBufferFull {
-		// Long symbol names are rare but exist. One source is type
-		// symbols for types with long string forms. See #15104.
-		origName = make([]byte, n)
-		r.readFull(origName)
-	} else if err != nil {
-		log.Fatalf("%s: error reading symbol: %v", r.pn, err)
-	}
-	adjName := r.rdBuf[:0]
-	for {
-		i := bytes.Index(origName, emptyPkg)
-		if i == -1 {
-			s := string(append(adjName, origName...))
-			// Read past the peeked origName, now that we're done with it,
-			// using the rfBuf (also no longer used) as the scratch space.
-			// TODO: use bufio.Reader.Discard if available instead?
-			if err == nil {
-				r.readFull(r.rdBuf[:n])
-			}
-			r.rdBuf = adjName[:0] // in case 2*n wasn't enough
-
-			if Buildmode == BuildmodeShared || *FlagLinkshared {
-				// These types are included in the symbol
-				// table when dynamically linking. To keep
-				// binary size down, we replace the names
-				// with SHA-1 prefixes.
-				//
-				// Keep the type.. prefix, which parts of the
-				// linker (like the DWARF generator) know means
-				// the symbol is not decodable.
-				//
-				// Leave type.runtime. symbols alone, because
-				// other parts of the linker manipulates them,
-				// and also symbols whose names would not be
-				// shortened by this process.
-				if len(s) > 14 && strings.HasPrefix(s, "type.") && !strings.HasPrefix(s, "type.runtime.") {
-					hash := sha1.Sum([]byte(s))
-					prefix := "type."
-					if s[5] == '.' {
-						prefix = "type.."
-					}
-					s = prefix + base64.StdEncoding.EncodeToString(hash[:6])
-				}
-			}
-			return s
-		}
-		adjName = append(adjName, origName[:i]...)
-		adjName = append(adjName, pkg...)
-		adjName = append(adjName, '.')
-		origName = origName[i+len(emptyPkg):]
-	}
-}
-
-// Reads the index of a symbol reference and resolves it to a symbol
-func (r *objReader) readSymIndex() *Symbol {
-	i := r.readInt()
-	return r.refs[i]
-}
diff --git a/src/cmd/link/internal/ld/outbuf.go b/src/cmd/link/internal/ld/outbuf.go
new file mode 100644
index 0000000..580435a
--- /dev/null
+++ b/src/cmd/link/internal/ld/outbuf.go
@@ -0,0 +1,120 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ld
+
+import (
+	"bufio"
+	"cmd/internal/sys"
+	"encoding/binary"
+	"os"
+)
+
+// OutBuf is a buffered file writer.
+//
+// It is simlar to the Writer in cmd/internal/bio with a few small differences.
+//
+// First, it tracks the output architecture and uses it to provide
+// endian helpers.
+//
+// Second, it provides a very cheap offset counter that doesn't require
+// any system calls to read the value.
+type OutBuf struct {
+	arch   *sys.Arch
+	off    int64
+	w      *bufio.Writer
+	f      *os.File
+	encbuf [8]byte // temp buffer used by WriteN methods
+}
+
+func (out *OutBuf) SeekSet(p int64) {
+	if p == out.off {
+		return
+	}
+	out.Flush()
+	if _, err := out.f.Seek(p, 0); err != nil {
+		Exitf("seeking to %d in %s: %v", p, out.f.Name(), err)
+	}
+	out.off = p
+}
+
+func (out *OutBuf) Offset() int64 {
+	return out.off
+}
+
+// Write writes the contents of v to the buffer.
+//
+// As Write is backed by a bufio.Writer, callers do not have
+// to explicitly handle the returned error as long as Flush is
+// eventually called.
+func (out *OutBuf) Write(v []byte) (int, error) {
+	n, err := out.w.Write(v)
+	out.off += int64(n)
+	return n, err
+}
+
+func (out *OutBuf) Write8(v uint8) {
+	if err := out.w.WriteByte(v); err == nil {
+		out.off++
+	}
+}
+
+func (out *OutBuf) Write16(v uint16) {
+	out.arch.ByteOrder.PutUint16(out.encbuf[:], v)
+	out.Write(out.encbuf[:2])
+}
+
+func (out *OutBuf) Write32(v uint32) {
+	out.arch.ByteOrder.PutUint32(out.encbuf[:], v)
+	out.Write(out.encbuf[:4])
+}
+
+func (out *OutBuf) Write32b(v uint32) {
+	binary.BigEndian.PutUint32(out.encbuf[:], v)
+	out.Write(out.encbuf[:4])
+}
+
+func (out *OutBuf) Write64(v uint64) {
+	out.arch.ByteOrder.PutUint64(out.encbuf[:], v)
+	out.Write(out.encbuf[:8])
+}
+
+func (out *OutBuf) Write64b(v uint64) {
+	binary.BigEndian.PutUint64(out.encbuf[:], v)
+	out.Write(out.encbuf[:8])
+}
+
+func (out *OutBuf) WriteString(s string) {
+	n, _ := out.w.WriteString(s)
+	out.off += int64(n)
+}
+
+// WriteStringN writes the first n bytes of s.
+// If n is larger than len(s) then it is padded with zero bytes.
+func (out *OutBuf) WriteStringN(s string, n int) {
+	out.WriteStringPad(s, n, zeros[:])
+}
+
+// WriteStringPad writes the first n bytes of s.
+// If n is larger than len(s) then it is padded with the bytes in pad (repeated as needed).
+func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
+	if len(s) >= n {
+		out.WriteString(s[:n])
+	} else {
+		out.WriteString(s)
+		n -= len(s)
+		for n > len(pad) {
+			out.Write(pad)
+			n -= len(pad)
+
+		}
+		out.Write(pad[:n])
+	}
+}
+
+func (out *OutBuf) Flush() {
+	if err := out.w.Flush(); err != nil {
+		Exitf("flushing %s: %v", out.f.Name(), err)
+	}
+}
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 1f6aed3..9d82677 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -7,6 +7,7 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/src"
+	"cmd/link/internal/sym"
 	"log"
 	"os"
 	"path/filepath"
@@ -58,7 +59,7 @@
 	it.nextpc = it.pc + v*it.pcscale
 }
 
-func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
+func pciterinit(ctxt *Link, it *Pciter, d *sym.Pcdata) {
 	it.d = *d
 	it.p = it.d.P
 	it.pc = 0
@@ -70,7 +71,7 @@
 	pciternext(it)
 }
 
-func addvarint(d *Pcdata, val uint32) {
+func addvarint(d *sym.Pcdata, val uint32) {
 	n := int32(0)
 	for v := val; v >= 0x80; v >>= 7 {
 		n++
@@ -92,36 +93,36 @@
 	p[0] = byte(v)
 }
 
-func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 {
+func addpctab(ctxt *Link, ftab *sym.Symbol, off int32, d *sym.Pcdata) int32 {
 	var start int32
 	if len(d.P) > 0 {
 		start = int32(len(ftab.P))
-		Addbytes(ftab, d.P)
+		ftab.AddBytes(d.P)
 	}
-	return int32(setuint32(ctxt, ftab, int64(off), uint32(start)))
+	return int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(start)))
 }
 
-func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
+func ftabaddstring(ctxt *Link, ftab *sym.Symbol, s string) int32 {
 	n := int32(len(s)) + 1
 	start := int32(len(ftab.P))
-	Symgrow(ftab, int64(start)+int64(n)+1)
+	ftab.Grow(int64(start) + int64(n) + 1)
 	copy(ftab.P[start:], s)
 	return start
 }
 
 // numberfile assigns a file number to the file if it hasn't been assigned already.
-func numberfile(ctxt *Link, file *Symbol) {
-	if file.Type != SFILEPATH {
+func numberfile(ctxt *Link, file *sym.Symbol) {
+	if file.Type != sym.SFILEPATH {
 		ctxt.Filesyms = append(ctxt.Filesyms, file)
 		file.Value = int64(len(ctxt.Filesyms))
-		file.Type = SFILEPATH
+		file.Type = sym.SFILEPATH
 		path := file.Name[len(src.FileSymPrefix):]
 		file.Name = expandGoroot(path)
 	}
 }
 
-func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
-	var f *Symbol
+func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) {
+	var f *sym.Symbol
 
 	// Give files numbers.
 	for i := 0; i < len(files); i++ {
@@ -130,7 +131,7 @@
 	}
 
 	newval := int32(-1)
-	var out Pcdata
+	var out sym.Pcdata
 	var it Pciter
 	for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
 		// value delta
@@ -163,7 +164,7 @@
 
 // onlycsymbol reports whether this is a cgo symbol provided by the
 // runtime and only used from C code.
-func onlycsymbol(s *Symbol) bool {
+func onlycsymbol(s *sym.Symbol) bool {
 	switch s.Name {
 	case "_cgo_topofstack", "_cgo_panic", "crosscall2":
 		return true
@@ -171,38 +172,38 @@
 	return false
 }
 
-func container(s *Symbol) int {
+func emitPcln(ctxt *Link, s *sym.Symbol) bool {
 	if s == nil {
-		return 0
+		return true
 	}
-	if Buildmode == BuildmodePlugin && Headtype == objabi.Hdarwin && onlycsymbol(s) {
-		return 1
+	if ctxt.BuildMode == BuildModePlugin && ctxt.HeadType == objabi.Hdarwin && onlycsymbol(s) {
+		return false
 	}
 	// We want to generate func table entries only for the "lowest level" symbols,
 	// not containers of subsymbols.
-	if s.Type&SCONTAINER != 0 {
-		return 1
+	if s.Attr.Container() {
+		return true
 	}
-	return 0
+	return true
 }
 
 // pclntab initializes the pclntab symbol with
 // runtime function and file name information.
 
-var pclntabZpcln FuncInfo
+var pclntabZpcln sym.FuncInfo
 
 // These variables are used to initialize runtime.firstmoduledata, see symtab.go:symtab.
 var pclntabNfunc int32
 var pclntabFiletabOffset int32
 var pclntabPclntabOffset int32
-var pclntabFirstFunc *Symbol
-var pclntabLastFunc *Symbol
+var pclntabFirstFunc *sym.Symbol
+var pclntabLastFunc *sym.Symbol
 
 func (ctxt *Link) pclntab() {
 	funcdataBytes := int64(0)
 	ftab := ctxt.Syms.Lookup("runtime.pclntab", 0)
-	ftab.Type = SPCLNTAB
-	ftab.Attr |= AttrReachable
+	ftab.Type = sym.SPCLNTAB
+	ftab.Attr |= sym.AttrReachable
 
 	// See golang.org/s/go12symtab for the format. Briefly:
 	//	8-byte header
@@ -212,26 +213,26 @@
 	//	offset to file table [4 bytes]
 	nfunc := int32(0)
 
-	// Find container symbols, mark them with SCONTAINER
+	// Find container symbols and mark them as such.
 	for _, s := range ctxt.Textp {
 		if s.Outer != nil {
-			s.Outer.Type |= SCONTAINER
+			s.Outer.Attr |= sym.AttrContainer
 		}
 	}
 
 	for _, s := range ctxt.Textp {
-		if container(s) == 0 {
+		if emitPcln(ctxt, s) {
 			nfunc++
 		}
 	}
 
 	pclntabNfunc = nfunc
-	Symgrow(ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize)+4)
-	setuint32(ctxt, ftab, 0, 0xfffffffb)
-	setuint8(ctxt, ftab, 6, uint8(SysArch.MinLC))
-	setuint8(ctxt, ftab, 7, uint8(SysArch.PtrSize))
-	setuint(ctxt, ftab, 8, uint64(nfunc))
-	pclntabPclntabOffset = int32(8 + SysArch.PtrSize)
+	ftab.Grow(8 + int64(ctxt.Arch.PtrSize) + int64(nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
+	ftab.SetUint32(ctxt.Arch, 0, 0xfffffffb)
+	ftab.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
+	ftab.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
+	ftab.SetUint(ctxt.Arch, 8, uint64(nfunc))
+	pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
 
 	funcnameoff := make(map[string]int32)
 	nameToOffset := func(name string) int32 {
@@ -244,10 +245,10 @@
 	}
 
 	nfunc = 0
-	var last *Symbol
+	var last *sym.Symbol
 	for _, s := range ctxt.Textp {
 		last = s
-		if container(s) != 0 {
+		if !emitPcln(ctxt, s) {
 			continue
 		}
 		pcln := s.FuncInfo
@@ -262,14 +263,14 @@
 		if len(pcln.InlTree) > 0 {
 			if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex {
 				// Create inlining pcdata table.
-				pcdata := make([]Pcdata, objabi.PCDATA_InlTreeIndex+1)
+				pcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1)
 				copy(pcdata, pcln.Pcdata)
 				pcln.Pcdata = pcdata
 			}
 
 			if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree {
 				// Create inline tree funcdata.
-				funcdata := make([]*Symbol, objabi.FUNCDATA_InlTree+1)
+				funcdata := make([]*sym.Symbol, objabi.FUNCDATA_InlTree+1)
 				funcdataoff := make([]int64, objabi.FUNCDATA_InlTree+1)
 				copy(funcdata, pcln.Funcdata)
 				copy(funcdataoff, pcln.Funcdataoff)
@@ -279,10 +280,10 @@
 		}
 
 		funcstart := int32(len(ftab.P))
-		funcstart += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
+		funcstart += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
 
-		setaddr(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), s)
-		setuint(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint64(funcstart))
+		ftab.SetAddr(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s)
+		ftab.SetUint(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart))
 
 		// Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func
 		// and package debug/gosym.
@@ -290,18 +291,18 @@
 		// fixed size of struct, checked below
 		off := funcstart
 
-		end := funcstart + int32(SysArch.PtrSize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(SysArch.PtrSize)
-		if len(pcln.Funcdata) > 0 && (end&int32(SysArch.PtrSize-1) != 0) {
+		end := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(ctxt.Arch.PtrSize)
+		if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
 			end += 4
 		}
-		Symgrow(ftab, int64(end))
+		ftab.Grow(int64(end))
 
 		// entry uintptr
-		off = int32(setaddr(ctxt, ftab, int64(off), s))
+		off = int32(ftab.SetAddr(ctxt.Arch, int64(off), s))
 
 		// name int32
 		nameoff := nameToOffset(s.Name)
-		off = int32(setuint32(ctxt, ftab, int64(off), uint32(nameoff)))
+		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(nameoff)))
 
 		// args int32
 		// TODO: Move into funcinfo.
@@ -309,14 +310,14 @@
 		if s.FuncInfo != nil {
 			args = uint32(s.FuncInfo.Args)
 		}
-		off = int32(setuint32(ctxt, ftab, int64(off), args))
+		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), args))
 
 		// frame int32
 		// This has been removed (it was never set quite correctly anyway).
 		// Nothing should use it.
 		// Leave an obviously incorrect value.
 		// TODO: Remove entirely.
-		off = int32(setuint32(ctxt, ftab, int64(off), 0x1234567))
+		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), 0x1234567))
 
 		if pcln != &pclntabZpcln {
 			renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
@@ -334,8 +335,8 @@
 
 		if len(pcln.InlTree) > 0 {
 			inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0)
-			inlTreeSym.Type = SRODATA
-			inlTreeSym.Attr |= AttrReachable | AttrDuplicateOK
+			inlTreeSym.Type = sym.SRODATA
+			inlTreeSym.Attr |= sym.AttrReachable | sym.AttrDuplicateOK
 
 			for i, call := range pcln.InlTree {
 				// Usually, call.File is already numbered since the file
@@ -346,10 +347,10 @@
 				numberfile(ctxt, call.File)
 				nameoff := nameToOffset(call.Func.Name)
 
-				setuint32(ctxt, inlTreeSym, int64(i*16+0), uint32(call.Parent))
-				setuint32(ctxt, inlTreeSym, int64(i*16+4), uint32(call.File.Value))
-				setuint32(ctxt, inlTreeSym, int64(i*16+8), uint32(call.Line))
-				setuint32(ctxt, inlTreeSym, int64(i*16+12), uint32(nameoff))
+				inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+0), uint32(call.Parent))
+				inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+4), uint32(call.File.Value))
+				inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+8), uint32(call.Line))
+				inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+12), uint32(nameoff))
 			}
 
 			pcln.Funcdata[objabi.FUNCDATA_InlTree] = inlTreeSym
@@ -361,8 +362,8 @@
 
 		off = addpctab(ctxt, ftab, off, &pcln.Pcfile)
 		off = addpctab(ctxt, ftab, off, &pcln.Pcline)
-		off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Pcdata))))
-		off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Funcdata))))
+		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcln.Pcdata))))
+		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcln.Funcdata))))
 		for i := 0; i < len(pcln.Pcdata); i++ {
 			off = addpctab(ctxt, ftab, off, &pcln.Pcdata[i])
 		}
@@ -370,25 +371,25 @@
 		// funcdata, must be pointer-aligned and we're only int32-aligned.
 		// Missing funcdata will be 0 (nil pointer).
 		if len(pcln.Funcdata) > 0 {
-			if off&int32(SysArch.PtrSize-1) != 0 {
+			if off&int32(ctxt.Arch.PtrSize-1) != 0 {
 				off += 4
 			}
 			for i := 0; i < len(pcln.Funcdata); i++ {
 				if pcln.Funcdata[i] == nil {
-					setuint(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
+					ftab.SetUint(ctxt.Arch, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
 				} else {
 					// TODO: Dedup.
 					funcdataBytes += pcln.Funcdata[i].Size
 
-					setaddrplus(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
+					ftab.SetAddrPlus(ctxt.Arch, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
 				}
 			}
 
-			off += int32(len(pcln.Funcdata)) * int32(SysArch.PtrSize)
+			off += int32(len(pcln.Funcdata)) * int32(ctxt.Arch.PtrSize)
 		}
 
 		if off != end {
-			Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), SysArch.PtrSize)
+			Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), ctxt.Arch.PtrSize)
 			errorexit()
 		}
 
@@ -397,20 +398,20 @@
 
 	pclntabLastFunc = last
 	// Final entry of table is just end pc.
-	setaddrplus(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), last, last.Size)
+	ftab.SetAddrPlus(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, last.Size)
 
 	// Start file table.
 	start := int32(len(ftab.P))
 
-	start += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
+	start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
 	pclntabFiletabOffset = start
-	setuint32(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint32(start))
+	ftab.SetUint32(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start))
 
-	Symgrow(ftab, int64(start)+(int64(len(ctxt.Filesyms))+1)*4)
-	setuint32(ctxt, ftab, int64(start), uint32(len(ctxt.Filesyms)+1))
+	ftab.Grow(int64(start) + (int64(len(ctxt.Filesyms))+1)*4)
+	ftab.SetUint32(ctxt.Arch, int64(start), uint32(len(ctxt.Filesyms)+1))
 	for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
 		s := ctxt.Filesyms[i]
-		setuint32(ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ctxt, ftab, s.Name)))
+		ftab.SetUint32(ctxt.Arch, int64(start)+s.Value*4, uint32(ftabaddstring(ctxt, ftab, s.Name)))
 	}
 
 	ftab.Size = int64(len(ftab.P))
@@ -420,14 +421,18 @@
 	}
 }
 
+func gorootFinal() string {
+	root := objabi.GOROOT
+	if final := os.Getenv("GOROOT_FINAL"); final != "" {
+		root = final
+	}
+	return root
+}
+
 func expandGoroot(s string) string {
 	const n = len("$GOROOT")
 	if len(s) >= n+1 && s[:n] == "$GOROOT" && (s[n] == '/' || s[n] == '\\') {
-		root := objabi.GOROOT
-		if final := os.Getenv("GOROOT_FINAL"); final != "" {
-			root = final
-		}
-		return filepath.ToSlash(filepath.Join(root, s[n:]))
+		return filepath.ToSlash(filepath.Join(gorootFinal(), s[n:]))
 	}
 	return s
 }
@@ -443,9 +448,9 @@
 // function for a pc. See src/runtime/symtab.go:findfunc for details.
 func (ctxt *Link) findfunctab() {
 	t := ctxt.Syms.Lookup("runtime.findfunctab", 0)
-	t.Type = SRODATA
-	t.Attr |= AttrReachable
-	t.Attr |= AttrLocal
+	t.Type = sym.SRODATA
+	t.Attr |= sym.AttrReachable
+	t.Attr |= sym.AttrLocal
 
 	// find min and max address
 	min := ctxt.Textp[0].Value
@@ -464,16 +469,16 @@
 	}
 	idx := int32(0)
 	for i, s := range ctxt.Textp {
-		if container(s) != 0 {
+		if !emitPcln(ctxt, s) {
 			continue
 		}
 		p := s.Value
-		var e *Symbol
+		var e *sym.Symbol
 		i++
 		if i < len(ctxt.Textp) {
 			e = ctxt.Textp[i]
 		}
-		for container(e) != 0 && i < len(ctxt.Textp) {
+		for !emitPcln(ctxt, e) && i < len(ctxt.Textp) {
 			e = ctxt.Textp[i]
 			i++
 		}
@@ -500,7 +505,7 @@
 	// allocate table
 	nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
 
-	Symgrow(t, 4*int64(nbuckets)+int64(n))
+	t.Grow(4*int64(nbuckets) + int64(n))
 
 	// fill in table
 	for i := int32(0); i < nbuckets; i++ {
@@ -508,7 +513,7 @@
 		if base == NOIDX {
 			Errorf(nil, "hole in findfunctab")
 		}
-		setuint32(ctxt, t, int64(i)*(4+SUBBUCKETS), uint32(base))
+		t.SetUint32(ctxt.Arch, int64(i)*(4+SUBBUCKETS), uint32(base))
 		for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ {
 			idx = indexes[i*SUBBUCKETS+j]
 			if idx == NOIDX {
@@ -518,7 +523,7 @@
 				Errorf(nil, "too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base)
 			}
 
-			setuint8(ctxt, t, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
+			t.SetUint8(ctxt.Arch, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
 		}
 	}
 }
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
index f26c83e..8586c35 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -7,76 +7,15 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
+	"debug/pe"
 	"encoding/binary"
 	"fmt"
-	"os"
 	"sort"
 	"strconv"
 	"strings"
 )
 
-type IMAGE_FILE_HEADER struct {
-	Machine              uint16
-	NumberOfSections     uint16
-	TimeDateStamp        uint32
-	PointerToSymbolTable uint32
-	NumberOfSymbols      uint32
-	SizeOfOptionalHeader uint16
-	Characteristics      uint16
-}
-
-type IMAGE_DATA_DIRECTORY struct {
-	VirtualAddress uint32
-	Size           uint32
-}
-
-type IMAGE_OPTIONAL_HEADER struct {
-	Magic                       uint16
-	MajorLinkerVersion          uint8
-	MinorLinkerVersion          uint8
-	SizeOfCode                  uint32
-	SizeOfInitializedData       uint32
-	SizeOfUninitializedData     uint32
-	AddressOfEntryPoint         uint32
-	BaseOfCode                  uint32
-	BaseOfData                  uint32
-	ImageBase                   uint32
-	SectionAlignment            uint32
-	FileAlignment               uint32
-	MajorOperatingSystemVersion uint16
-	MinorOperatingSystemVersion uint16
-	MajorImageVersion           uint16
-	MinorImageVersion           uint16
-	MajorSubsystemVersion       uint16
-	MinorSubsystemVersion       uint16
-	Win32VersionValue           uint32
-	SizeOfImage                 uint32
-	SizeOfHeaders               uint32
-	CheckSum                    uint32
-	Subsystem                   uint16
-	DllCharacteristics          uint16
-	SizeOfStackReserve          uint32
-	SizeOfStackCommit           uint32
-	SizeOfHeapReserve           uint32
-	SizeOfHeapCommit            uint32
-	LoaderFlags                 uint32
-	NumberOfRvaAndSizes         uint32
-	DataDirectory               [16]IMAGE_DATA_DIRECTORY
-}
-
-type IMAGE_SECTION_HEADER struct {
-	Name                 [8]uint8
-	VirtualSize          uint32
-	VirtualAddress       uint32
-	SizeOfRawData        uint32
-	PointerToRawData     uint32
-	PointerToRelocations uint32
-	PointerToLineNumbers uint32
-	NumberOfRelocations  uint16
-	NumberOfLineNumbers  uint16
-	Characteristics      uint32
-}
-
 type IMAGE_IMPORT_DESCRIPTOR struct {
 	OriginalFirstThunk uint32
 	TimeDateStamp      uint32
@@ -152,39 +91,25 @@
 	IMAGE_SUBSYSTEM_WINDOWS_CUI          = 3
 )
 
-// X64
-type PE64_IMAGE_OPTIONAL_HEADER struct {
-	Magic                       uint16
-	MajorLinkerVersion          uint8
-	MinorLinkerVersion          uint8
-	SizeOfCode                  uint32
-	SizeOfInitializedData       uint32
-	SizeOfUninitializedData     uint32
-	AddressOfEntryPoint         uint32
-	BaseOfCode                  uint32
-	ImageBase                   uint64
-	SectionAlignment            uint32
-	FileAlignment               uint32
-	MajorOperatingSystemVersion uint16
-	MinorOperatingSystemVersion uint16
-	MajorImageVersion           uint16
-	MinorImageVersion           uint16
-	MajorSubsystemVersion       uint16
-	MinorSubsystemVersion       uint16
-	Win32VersionValue           uint32
-	SizeOfImage                 uint32
-	SizeOfHeaders               uint32
-	CheckSum                    uint32
-	Subsystem                   uint16
-	DllCharacteristics          uint16
-	SizeOfStackReserve          uint64
-	SizeOfStackCommit           uint64
-	SizeOfHeapReserve           uint64
-	SizeOfHeapCommit            uint64
-	LoaderFlags                 uint32
-	NumberOfRvaAndSizes         uint32
-	DataDirectory               [16]IMAGE_DATA_DIRECTORY
-}
+// TODO(crawshaw): add these constants to debug/pe.
+const (
+	// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 and IMAGE_SYM_DTYPE_FUNCTION is 2
+	IMAGE_SYM_TYPE_NULL      = 0
+	IMAGE_SYM_TYPE_STRUCT    = 8
+	IMAGE_SYM_DTYPE_FUNCTION = 0x20
+	IMAGE_SYM_DTYPE_ARRAY    = 0x30
+	IMAGE_SYM_CLASS_EXTERNAL = 2
+	IMAGE_SYM_CLASS_STATIC   = 3
+
+	IMAGE_REL_I386_DIR32  = 0x0006
+	IMAGE_REL_I386_SECREL = 0x000B
+	IMAGE_REL_I386_REL32  = 0x0014
+
+	IMAGE_REL_AMD64_ADDR64 = 0x0001
+	IMAGE_REL_AMD64_ADDR32 = 0x0002
+	IMAGE_REL_AMD64_REL32  = 0x0004
+	IMAGE_REL_AMD64_SECREL = 0x000B
+)
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -326,43 +251,8 @@
 	0x00,
 }
 
-var rsrcsym *Symbol
-
-var strtbl []byte
-
-var PESECTHEADR int32
-
-var PEFILEHEADR int32
-
-var pe64 int
-
-var pensect int
-
-var nextsectoff int
-
-var nextfileoff int
-
-var textsect int
-
-var datasect int
-
-var bsssect int
-
-var fh IMAGE_FILE_HEADER
-
-var oh IMAGE_OPTIONAL_HEADER
-
-var oh64 PE64_IMAGE_OPTIONAL_HEADER
-
-var sh [16]IMAGE_SECTION_HEADER
-
-// shNames stores full names of PE sections stored in sh.
-var shNames []string
-
-var dd []IMAGE_DATA_DIRECTORY
-
 type Imp struct {
-	s       *Symbol
+	s       *sym.Symbol
 	off     uint64
 	next    *Imp
 	argsize int
@@ -376,92 +266,663 @@
 	next     *Dll
 }
 
-var dr *Dll
+var (
+	rsrcsym     *sym.Symbol
+	PESECTHEADR int32
+	PEFILEHEADR int32
+	pe64        int
+	dr          *Dll
+	dexport     [1024]*sym.Symbol
+	nexport     int
+)
 
-var dexport [1024]*Symbol
+// peStringTable is a COFF string table.
+type peStringTable struct {
+	strings    []string
+	stringsLen int
+}
 
-var nexport int
+// size resturns size of string table t.
+func (t *peStringTable) size() int {
+	// string table starts with 4-byte length at the beginning
+	return t.stringsLen + 4
+}
 
-func addpesectionWithLongName(ctxt *Link, shortname, longname string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
-	if pensect == 16 {
-		Errorf(nil, "too many sections")
+// add adds string str to string table t.
+func (t *peStringTable) add(str string) int {
+	off := t.size()
+	t.strings = append(t.strings, str)
+	t.stringsLen += len(str) + 1 // each string will have 0 appended to it
+	return off
+}
+
+// write writes string table t into the output file.
+func (t *peStringTable) write(out *OutBuf) {
+	out.Write32(uint32(t.size()))
+	for _, s := range t.strings {
+		out.WriteString(s)
+		out.Write8(0)
+	}
+}
+
+// peSection represents section from COFF section table.
+type peSection struct {
+	name                 string
+	shortName            string
+	index                int // one-based index into the Section Table
+	virtualSize          uint32
+	virtualAddress       uint32
+	sizeOfRawData        uint32
+	pointerToRawData     uint32
+	pointerToRelocations uint32
+	numberOfRelocations  uint16
+	characteristics      uint32
+}
+
+// checkOffset verifies COFF section sect offset in the file.
+func (sect *peSection) checkOffset(off int64) {
+	if off != int64(sect.pointerToRawData) {
+		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", sect.name, uint64(int64(sect.pointerToRawData)), uint64(off))
 		errorexit()
 	}
+}
 
-	h := &sh[pensect]
-	pensect++
-	copy(h.Name[:], shortname)
-	shNames = append(shNames, longname)
-	h.VirtualSize = uint32(sectsize)
-	h.VirtualAddress = uint32(nextsectoff)
-	nextsectoff = int(Rnd(int64(nextsectoff)+int64(sectsize), PESECTALIGN))
-	h.PointerToRawData = uint32(nextfileoff)
-	if filesize > 0 {
-		h.SizeOfRawData = uint32(Rnd(int64(filesize), PEFILEALIGN))
-		nextfileoff += int(h.SizeOfRawData)
+// checkSegment verifies COFF section sect matches address
+// and file offset provided in segment seg.
+func (sect *peSection) checkSegment(seg *sym.Segment) {
+	if seg.Vaddr-PEBASE != uint64(sect.virtualAddress) {
+		Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-PEBASE)))
+		errorexit()
 	}
+	if seg.Fileoff != uint64(sect.pointerToRawData) {
+		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", sect.name, uint64(int64(sect.pointerToRawData)), uint64(int64(seg.Fileoff)))
+		errorexit()
+	}
+}
 
+// pad adds zeros to the section sect. It writes as many bytes
+// as necessary to make section sect.SizeOfRawData bytes long.
+// It assumes that n bytes are already written to the file.
+func (sect *peSection) pad(out *OutBuf, n uint32) {
+	out.WriteStringN("", int(sect.sizeOfRawData-n))
+}
+
+// write writes COFF section sect into the output file.
+func (sect *peSection) write(out *OutBuf, linkmode LinkMode) error {
+	h := pe.SectionHeader32{
+		VirtualSize:          sect.virtualSize,
+		SizeOfRawData:        sect.sizeOfRawData,
+		PointerToRawData:     sect.pointerToRawData,
+		PointerToRelocations: sect.pointerToRelocations,
+		NumberOfRelocations:  sect.numberOfRelocations,
+		Characteristics:      sect.characteristics,
+	}
+	if linkmode != LinkExternal {
+		h.VirtualAddress = sect.virtualAddress
+	}
+	copy(h.Name[:], sect.shortName)
+	return binary.Write(out, binary.LittleEndian, h)
+}
+
+// emitRelocations emits the relocation entries for the sect.
+// The actual relocations are emitted by relocfn.
+// This updates the corresponding PE section table entry
+// with the relocation offset and count.
+func (sect *peSection) emitRelocations(out *OutBuf, relocfn func() int) {
+	sect.pointerToRelocations = uint32(out.Offset())
+	// first entry: extended relocs
+	out.Write32(0) // placeholder for number of relocation + 1
+	out.Write32(0)
+	out.Write16(0)
+
+	n := relocfn() + 1
+
+	cpos := out.Offset()
+	out.SeekSet(int64(sect.pointerToRelocations))
+	out.Write32(uint32(n))
+	out.SeekSet(cpos)
+	if n > 0x10000 {
+		n = 0x10000
+		sect.characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
+	} else {
+		sect.pointerToRelocations += 10 // skip the extend reloc entry
+	}
+	sect.numberOfRelocations = uint16(n - 1)
+}
+
+// peFile is used to build COFF file.
+type peFile struct {
+	sections       []*peSection
+	stringTable    peStringTable
+	textSect       *peSection
+	dataSect       *peSection
+	bssSect        *peSection
+	ctorsSect      *peSection
+	nextSectOffset uint32
+	nextFileOffset uint32
+	symtabOffset   int64 // offset to the start of symbol table
+	symbolCount    int   // number of symbol table records written
+	dataDirectory  [16]pe.DataDirectory
+}
+
+// addSection adds section to the COFF file f.
+func (f *peFile) addSection(name string, sectsize int, filesize int) *peSection {
+	sect := &peSection{
+		name:             name,
+		shortName:        name,
+		index:            len(f.sections) + 1,
+		virtualSize:      uint32(sectsize),
+		virtualAddress:   f.nextSectOffset,
+		pointerToRawData: f.nextFileOffset,
+	}
+	f.nextSectOffset = uint32(Rnd(int64(f.nextSectOffset)+int64(sectsize), PESECTALIGN))
+	if filesize > 0 {
+		sect.sizeOfRawData = uint32(Rnd(int64(filesize), PEFILEALIGN))
+		f.nextFileOffset += sect.sizeOfRawData
+	}
+	f.sections = append(f.sections, sect)
+	return sect
+}
+
+// addDWARFSection adds DWARF section to the COFF file f.
+// This function is similar to addSection, but DWARF section names are
+// longer than 8 characters, so they need to be stored in the string table.
+func (f *peFile) addDWARFSection(name string, size int) *peSection {
+	if size == 0 {
+		Exitf("DWARF section %q is empty", name)
+	}
+	// DWARF section names are longer than 8 characters.
+	// PE format requires such names to be stored in string table,
+	// and section names replaced with slash (/) followed by
+	// correspondent string table index.
+	// see http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx
+	// for details
+	off := f.stringTable.add(name)
+	h := f.addSection(name, size, size)
+	h.shortName = fmt.Sprintf("/%d", off)
+	h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
 	return h
 }
 
-func addpesection(ctxt *Link, name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
-	return addpesectionWithLongName(ctxt, name, name, sectsize, filesize)
-}
-func chksectoff(ctxt *Link, h *IMAGE_SECTION_HEADER, off int64) {
-	if off != int64(h.PointerToRawData) {
-		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off))
-		errorexit()
+// addDWARF adds DWARF information to the COFF file f.
+func (f *peFile) addDWARF() {
+	if *FlagS { // disable symbol table
+		return
+	}
+	if *FlagW { // disable dwarf
+		return
+	}
+	for _, sect := range Segdwarf.Sections {
+		h := f.addDWARFSection(sect.Name, int(sect.Length))
+		fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
+		if uint64(h.pointerToRawData) != fileoff {
+			Exitf("%s.PointerToRawData = %#x, want %#x", sect.Name, h.pointerToRawData, fileoff)
+		}
 	}
 }
 
-func chksectseg(ctxt *Link, h *IMAGE_SECTION_HEADER, s *Segment) {
-	if s.Vaddr-PEBASE != uint64(h.VirtualAddress) {
-		Errorf(nil, "%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
-		errorexit()
+// addInitArray adds .ctors COFF section to the file f.
+func (f *peFile) addInitArray(ctxt *Link) *peSection {
+	// The size below was determined by the specification for array relocations,
+	// and by observing what GCC writes here. If the initarray section grows to
+	// contain more than one constructor entry, the size will need to be 8 * constructor_count.
+	// However, the entire Go runtime is initialized from just one function, so it is unlikely
+	// that this will need to grow in the future.
+	var size int
+	switch objabi.GOARCH {
+	default:
+		Exitf("peFile.addInitArray: unsupported GOARCH=%q\n", objabi.GOARCH)
+	case "386":
+		size = 4
+	case "amd64":
+		size = 8
+	}
+	sect := f.addSection(".ctors", size, size)
+	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+	sect.sizeOfRawData = uint32(size)
+	ctxt.Out.SeekSet(int64(sect.pointerToRawData))
+	sect.checkOffset(ctxt.Out.Offset())
+
+	init_entry := ctxt.Syms.Lookup(*flagEntrySymbol, 0)
+	addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
+	switch objabi.GOARCH {
+	case "386":
+		ctxt.Out.Write32(uint32(addr))
+	case "amd64":
+		ctxt.Out.Write64(addr)
+	}
+	return sect
+}
+
+// emitRelocations emits relocation entries for go.o in external linking.
+func (f *peFile) emitRelocations(ctxt *Link) {
+	for ctxt.Out.Offset()&7 != 0 {
+		ctxt.Out.Write8(0)
 	}
 
-	if s.Fileoff != uint64(h.PointerToRawData) {
-		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
-		errorexit()
+	// relocsect relocates symbols from first in section sect, and returns
+	// the total number of relocations emitted.
+	relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) int {
+		// If main section has no bits, nothing to relocate.
+		if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
+			return 0
+		}
+		relocs := 0
+		sect.Reloff = uint64(ctxt.Out.Offset())
+		for i, s := range syms {
+			if !s.Attr.Reachable() {
+				continue
+			}
+			if uint64(s.Value) >= sect.Vaddr {
+				syms = syms[i:]
+				break
+			}
+		}
+		eaddr := int32(sect.Vaddr + sect.Length)
+		for _, sym := range syms {
+			if !sym.Attr.Reachable() {
+				continue
+			}
+			if sym.Value >= int64(eaddr) {
+				break
+			}
+			for ri := 0; ri < len(sym.R); ri++ {
+				r := &sym.R[ri]
+				if r.Done {
+					continue
+				}
+				if r.Xsym == nil {
+					Errorf(sym, "missing xsym in relocation")
+					continue
+				}
+				if r.Xsym.Dynid < 0 {
+					Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
+				}
+				if !Thearch.PEreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
+					Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
+				}
+				relocs++
+			}
+		}
+		sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
+		return relocs
+	}
+
+	f.textSect.emitRelocations(ctxt.Out, func() int {
+		n := relocsect(Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
+		for _, sect := range Segtext.Sections[1:] {
+			n += relocsect(sect, datap, Segtext.Vaddr)
+		}
+		return n
+	})
+
+	f.dataSect.emitRelocations(ctxt.Out, func() int {
+		var n int
+		for _, sect := range Segdata.Sections {
+			n += relocsect(sect, datap, Segdata.Vaddr)
+		}
+		return n
+	})
+
+dwarfLoop:
+	for _, sect := range Segdwarf.Sections {
+		for _, pesect := range f.sections {
+			if sect.Name == pesect.name {
+				pesect.emitRelocations(ctxt.Out, func() int {
+					return relocsect(sect, dwarfp, sect.Vaddr)
+				})
+				continue dwarfLoop
+			}
+		}
+		Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
+	}
+
+	f.ctorsSect.emitRelocations(ctxt.Out, func() int {
+		dottext := ctxt.Syms.Lookup(".text", 0)
+		ctxt.Out.Write32(0)
+		ctxt.Out.Write32(uint32(dottext.Dynid))
+		switch objabi.GOARCH {
+		default:
+			Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
+		case "386":
+			ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
+		case "amd64":
+			ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
+		}
+		return 1
+	})
+}
+
+// writeSymbol appends symbol s to file f symbol table.
+// It also sets s.Dynid to written symbol number.
+func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx int, typ uint16, class uint8) {
+	if len(s.Name) > 8 {
+		out.Write32(0)
+		out.Write32(uint32(f.stringTable.add(s.Name)))
+	} else {
+		out.WriteStringN(s.Name, 8)
+	}
+	out.Write32(uint32(value))
+	out.Write16(uint16(sectidx))
+	out.Write16(typ)
+	out.Write8(class)
+	out.Write8(0) // no aux entries
+
+	s.Dynid = int32(f.symbolCount)
+
+	f.symbolCount++
+}
+
+// mapToPESection searches peFile f for s symbol's location.
+// It returns PE section index, and offset within that section.
+func (f *peFile) mapToPESection(s *sym.Symbol, linkmode LinkMode) (pesectidx int, offset int64, err error) {
+	if s.Sect == nil {
+		return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name)
+	}
+	if s.Sect.Seg == &Segtext {
+		return f.textSect.index, int64(uint64(s.Value) - Segtext.Vaddr), nil
+	}
+	if s.Sect.Seg != &Segdata {
+		return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .data section", s.Name)
+	}
+	v := uint64(s.Value) - Segdata.Vaddr
+	if linkmode != LinkExternal {
+		return f.dataSect.index, int64(v), nil
+	}
+	if s.Type == sym.SDATA {
+		return f.dataSect.index, int64(v), nil
+	}
+	// Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss section
+	// it still belongs to the .data section, not the .bss section.
+	if v < Segdata.Filelen {
+		return f.dataSect.index, int64(v), nil
+	}
+	return f.bssSect.index, int64(v - Segdata.Filelen), nil
+}
+
+// writeSymbols writes all COFF symbol table records.
+func (f *peFile) writeSymbols(ctxt *Link) {
+
+	put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
+		if s == nil {
+			return
+		}
+		if s.Sect == nil && type_ != UndefinedSym {
+			return
+		}
+		switch type_ {
+		default:
+			return
+		case DataSym, BSSSym, TextSym, UndefinedSym:
+		}
+
+		// Only windows/386 requires underscore prefix on external symbols.
+		if ctxt.Arch.Family == sys.I386 &&
+			ctxt.LinkMode == LinkExternal &&
+			(s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) {
+			s.Name = "_" + s.Name
+		}
+
+		var typ uint16
+		if ctxt.LinkMode == LinkExternal {
+			typ = IMAGE_SYM_TYPE_NULL
+		} else {
+			// TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308
+			typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
+			typ = 0x0308 // "array of structs"
+		}
+		sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
+		if err != nil {
+			if type_ == UndefinedSym {
+				typ = IMAGE_SYM_DTYPE_FUNCTION
+			} else {
+				Errorf(s, "addpesym: %v", err)
+			}
+		}
+		class := IMAGE_SYM_CLASS_EXTERNAL
+		if s.Version != 0 || s.Attr.VisibilityHidden() || s.Attr.Local() {
+			class = IMAGE_SYM_CLASS_STATIC
+		}
+		f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
+	}
+
+	if ctxt.LinkMode == LinkExternal {
+		// Include section symbols as external, because
+		// .ctors and .debug_* section relocations refer to it.
+		for _, pesect := range f.sections {
+			sym := ctxt.Syms.Lookup(pesect.name, 0)
+			f.writeSymbol(ctxt.Out, sym, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
+		}
+	}
+
+	genasmsym(ctxt, put)
+}
+
+// writeSymbolTableAndStringTable writes out symbol and string tables for peFile f.
+func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
+	f.symtabOffset = ctxt.Out.Offset()
+
+	// write COFF symbol table
+	if !*FlagS || ctxt.LinkMode == LinkExternal {
+		f.writeSymbols(ctxt)
+	}
+
+	// update COFF file header and section table
+	size := f.stringTable.size() + 18*f.symbolCount
+	var h *peSection
+	if ctxt.LinkMode != LinkExternal {
+		// We do not really need .symtab for go.o, and if we have one, ld
+		// will also include it in the exe, and that will confuse windows.
+		h = f.addSection(".symtab", size, size)
+		h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
+		h.checkOffset(f.symtabOffset)
+	}
+
+	// write COFF string table
+	f.stringTable.write(ctxt.Out)
+	if ctxt.LinkMode != LinkExternal {
+		h.pad(ctxt.Out, uint32(size))
 	}
 }
 
+// writeFileHeader writes COFF file header for peFile f.
+func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf, linkmode LinkMode) {
+	var fh pe.FileHeader
+
+	switch arch.Family {
+	default:
+		Exitf("unknown PE architecture: %v", arch.Family)
+	case sys.AMD64:
+		fh.Machine = IMAGE_FILE_MACHINE_AMD64
+	case sys.I386:
+		fh.Machine = IMAGE_FILE_MACHINE_I386
+	}
+
+	fh.NumberOfSections = uint16(len(f.sections))
+
+	// Being able to produce identical output for identical input is
+	// much more beneficial than having build timestamp in the header.
+	fh.TimeDateStamp = 0
+
+	if linkmode == LinkExternal {
+		fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED
+	} else {
+		fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED
+	}
+	if pe64 != 0 {
+		var oh64 pe.OptionalHeader64
+		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
+		fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE
+	} else {
+		var oh pe.OptionalHeader32
+		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
+		fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE
+	}
+
+	fh.PointerToSymbolTable = uint32(f.symtabOffset)
+	fh.NumberOfSymbols = uint32(f.symbolCount)
+
+	binary.Write(out, binary.LittleEndian, &fh)
+}
+
+// writeOptionalHeader writes COFF optional header for peFile f.
+func (f *peFile) writeOptionalHeader(ctxt *Link) {
+	var oh pe.OptionalHeader32
+	var oh64 pe.OptionalHeader64
+
+	if pe64 != 0 {
+		oh64.Magic = 0x20b // PE32+
+	} else {
+		oh.Magic = 0x10b // PE32
+		oh.BaseOfData = f.dataSect.virtualAddress
+	}
+
+	// Fill out both oh64 and oh. We only use one. Oh well.
+	oh64.MajorLinkerVersion = 3
+	oh.MajorLinkerVersion = 3
+	oh64.MinorLinkerVersion = 0
+	oh.MinorLinkerVersion = 0
+	oh64.SizeOfCode = f.textSect.sizeOfRawData
+	oh.SizeOfCode = f.textSect.sizeOfRawData
+	oh64.SizeOfInitializedData = f.dataSect.sizeOfRawData
+	oh.SizeOfInitializedData = f.dataSect.sizeOfRawData
+	oh64.SizeOfUninitializedData = 0
+	oh.SizeOfUninitializedData = 0
+	if ctxt.LinkMode != LinkExternal {
+		oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
+		oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
+	}
+	oh64.BaseOfCode = f.textSect.virtualAddress
+	oh.BaseOfCode = f.textSect.virtualAddress
+	oh64.ImageBase = PEBASE
+	oh.ImageBase = PEBASE
+	oh64.SectionAlignment = uint32(PESECTALIGN)
+	oh.SectionAlignment = uint32(PESECTALIGN)
+	oh64.FileAlignment = uint32(PEFILEALIGN)
+	oh.FileAlignment = uint32(PEFILEALIGN)
+	oh64.MajorOperatingSystemVersion = 4
+	oh.MajorOperatingSystemVersion = 4
+	oh64.MinorOperatingSystemVersion = 0
+	oh.MinorOperatingSystemVersion = 0
+	oh64.MajorImageVersion = 1
+	oh.MajorImageVersion = 1
+	oh64.MinorImageVersion = 0
+	oh.MinorImageVersion = 0
+	oh64.MajorSubsystemVersion = 4
+	oh.MajorSubsystemVersion = 4
+	oh64.MinorSubsystemVersion = 0
+	oh.MinorSubsystemVersion = 0
+	oh64.SizeOfImage = f.nextSectOffset
+	oh.SizeOfImage = f.nextSectOffset
+	oh64.SizeOfHeaders = uint32(PEFILEHEADR)
+	oh.SizeOfHeaders = uint32(PEFILEHEADR)
+	if windowsgui {
+		oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
+		oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
+	} else {
+		oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
+		oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
+	}
+
+	// Disable stack growth as we don't want Windows to
+	// fiddle with the thread stack limits, which we set
+	// ourselves to circumvent the stack checks in the
+	// Windows exception dispatcher.
+	// Commit size must be strictly less than reserve
+	// size otherwise reserve will be rounded up to a
+	// larger size, as verified with VMMap.
+
+	// On 64-bit, we always reserve 2MB stacks. "Pure" Go code is
+	// okay with much smaller stacks, but the syscall package
+	// makes it easy to call into arbitrary C code without cgo,
+	// and system calls even in "pure" Go code are actually C
+	// calls that may need more stack than we think.
+	//
+	// The default stack reserve size affects only the main
+	// thread, ctrlhandler thread, and profileloop thread. For
+	// these, it must be greater than the stack size assumed by
+	// externalthreadhandler.
+	//
+	// For other threads we specify stack size in runtime explicitly.
+	// For these, the reserve must match STACKSIZE in
+	// runtime/cgo/gcc_windows_{386,amd64}.c and the correspondent
+	// CreateThread parameter in runtime.newosproc.
+	oh64.SizeOfStackReserve = 0x00200000
+	if !iscgo {
+		oh64.SizeOfStackCommit = 0x00001000
+	} else {
+		// TODO(brainman): Maybe remove optional header writing altogether for cgo.
+		// For cgo it is the external linker that is building final executable.
+		// And it probably does not use any information stored in optional header.
+		oh64.SizeOfStackCommit = 0x00200000 - 0x2000 // account for 2 guard pages
+	}
+
+	oh.SizeOfStackReserve = 0x00100000
+	if !iscgo {
+		oh.SizeOfStackCommit = 0x00001000
+	} else {
+		oh.SizeOfStackCommit = 0x00100000 - 0x2000 // account for 2 guard pages
+	}
+
+	oh64.SizeOfHeapReserve = 0x00100000
+	oh.SizeOfHeapReserve = 0x00100000
+	oh64.SizeOfHeapCommit = 0x00001000
+	oh.SizeOfHeapCommit = 0x00001000
+	oh64.NumberOfRvaAndSizes = 16
+	oh.NumberOfRvaAndSizes = 16
+
+	if pe64 != 0 {
+		oh64.DataDirectory = f.dataDirectory
+	} else {
+		oh.DataDirectory = f.dataDirectory
+	}
+
+	if pe64 != 0 {
+		binary.Write(ctxt.Out, binary.LittleEndian, &oh64)
+	} else {
+		binary.Write(ctxt.Out, binary.LittleEndian, &oh)
+	}
+}
+
+var pefile peFile
+
 func Peinit(ctxt *Link) {
 	var l int
 
-	switch SysArch.Family {
+	switch ctxt.Arch.Family {
 	// 64-bit architectures
 	case sys.AMD64:
 		pe64 = 1
-
+		var oh64 pe.OptionalHeader64
 		l = binary.Size(&oh64)
-		dd = oh64.DataDirectory[:]
 
 	// 32-bit architectures
 	default:
+		var oh pe.OptionalHeader32
 		l = binary.Size(&oh)
 
-		dd = oh.DataDirectory[:]
 	}
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		PESECTALIGN = 0
 		PEFILEALIGN = 0
 	}
 
+	var sh [16]pe.SectionHeader32
+	var fh pe.FileHeader
 	PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
-	if Linkmode != LinkExternal {
+	if ctxt.LinkMode != LinkExternal {
 		PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
 	} else {
 		PESECTHEADR = 0
 	}
-	nextsectoff = int(PESECTHEADR)
-	nextfileoff = int(PEFILEHEADR)
+	pefile.nextSectOffset = uint32(PESECTHEADR)
+	pefile.nextFileOffset = uint32(PEFILEHEADR)
 
-	if Linkmode == LinkInternal {
+	if ctxt.LinkMode == LinkInternal {
 		// some mingw libs depend on this symbol, for example, FindPESectionByName
-		ctxt.xdefine("__image_base__", SDATA, PEBASE)
-		ctxt.xdefine("_image_base__", SDATA, PEBASE)
+		ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
+		ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
 	}
 
 	HEADR = PEFILEHEADR
@@ -479,34 +940,28 @@
 	}
 }
 
-func pewrite() {
-	Cseek(0)
-	if Linkmode != LinkExternal {
-		Cwrite(dosstub)
-		strnput("PE", 4)
+func pewrite(ctxt *Link) {
+	ctxt.Out.SeekSet(0)
+	if ctxt.LinkMode != LinkExternal {
+		ctxt.Out.Write(dosstub)
+		ctxt.Out.WriteStringN("PE", 4)
 	}
 
-	binary.Write(&coutbuf, binary.LittleEndian, &fh)
+	pefile.writeFileHeader(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
 
-	if pe64 != 0 {
-		binary.Write(&coutbuf, binary.LittleEndian, &oh64)
-	} else {
-		binary.Write(&coutbuf, binary.LittleEndian, &oh)
+	pefile.writeOptionalHeader(ctxt)
+
+	for _, sect := range pefile.sections {
+		sect.write(ctxt.Out, ctxt.LinkMode)
 	}
-	if Linkmode == LinkExternal {
-		for i := range sh[:pensect] {
-			sh[i].VirtualAddress = 0
-		}
-	}
-	binary.Write(&coutbuf, binary.LittleEndian, sh[:pensect])
 }
 
-func strput(s string) {
-	coutbuf.WriteString(s)
-	Cput(0)
+func strput(out *OutBuf, s string) {
+	out.WriteString(s)
+	out.Write8(0)
 	// string must be padded to even size
 	if (len(s)+1)%2 != 0 {
-		Cput(0)
+		out.Write8(0)
 	}
 }
 
@@ -516,7 +971,7 @@
 	dr = nil
 	var m *Imp
 	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || s.Type != SDYNIMPORT {
+		if !s.Attr.Reachable() || s.Type != sym.SDYNIMPORT {
 			continue
 		}
 		for d = dr; d != nil; d = d.next {
@@ -545,7 +1000,7 @@
 			if err != nil {
 				Errorf(s, "failed to parse stdcall decoration: %v", err)
 			}
-			m.argsize *= SysArch.PtrSize
+			m.argsize *= ctxt.Arch.PtrSize
 			s.Extname = s.Extname[:i]
 		}
 
@@ -554,41 +1009,42 @@
 		d.ms = m
 	}
 
-	if Linkmode == LinkExternal {
+	if ctxt.LinkMode == LinkExternal {
 		// Add real symbol name
 		for d := dr; d != nil; d = d.next {
 			for m = d.ms; m != nil; m = m.next {
-				m.s.Type = SDATA
-				Symgrow(m.s, int64(SysArch.PtrSize))
+				m.s.Type = sym.SDATA
+				m.s.Grow(int64(ctxt.Arch.PtrSize))
 				dynName := m.s.Extname
 				// only windows/386 requires stdcall decoration
-				if SysArch.Family == sys.I386 && m.argsize >= 0 {
+				if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
 					dynName += fmt.Sprintf("@%d", m.argsize)
 				}
 				dynSym := ctxt.Syms.Lookup(dynName, 0)
-				dynSym.Attr |= AttrReachable
-				dynSym.Type = SHOSTOBJ
-				r := Addrel(m.s)
+				dynSym.Attr |= sym.AttrReachable
+				dynSym.Type = sym.SHOSTOBJ
+				r := m.s.AddRel()
 				r.Sym = dynSym
 				r.Off = 0
-				r.Siz = uint8(SysArch.PtrSize)
+				r.Siz = uint8(ctxt.Arch.PtrSize)
 				r.Type = objabi.R_ADDR
 			}
 		}
 	} else {
 		dynamic := ctxt.Syms.Lookup(".windynamic", 0)
-		dynamic.Attr |= AttrReachable
-		dynamic.Type = SWINDOWS
+		dynamic.Attr |= sym.AttrReachable
+		dynamic.Type = sym.SWINDOWS
 		for d := dr; d != nil; d = d.next {
 			for m = d.ms; m != nil; m = m.next {
-				m.s.Type = SWINDOWS | SSUB
+				m.s.Type = sym.SWINDOWS
+				m.s.Attr |= sym.AttrSubSymbol
 				m.s.Sub = dynamic.Sub
 				dynamic.Sub = m.s
 				m.s.Value = dynamic.Size
-				dynamic.Size += int64(SysArch.PtrSize)
+				dynamic.Size += int64(ctxt.Arch.PtrSize)
 			}
 
-			dynamic.Size += int64(SysArch.PtrSize)
+			dynamic.Size += int64(ctxt.Arch.PtrSize)
 		}
 	}
 
@@ -607,8 +1063,8 @@
 	return dlls
 }
 
-func addimports(ctxt *Link, datsect *IMAGE_SECTION_HEADER) {
-	startoff := coutbuf.Offset()
+func addimports(ctxt *Link, datsect *peSection) {
+	startoff := ctxt.Out.Offset()
 	dynamic := ctxt.Syms.Lookup(".windynamic", 0)
 
 	// skip import descriptor table (will write it later)
@@ -617,101 +1073,102 @@
 	for d := dr; d != nil; d = d.next {
 		n++
 	}
-	Cseek(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
+	ctxt.Out.SeekSet(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
 
 	// write dll names
 	for d := dr; d != nil; d = d.next {
-		d.nameoff = uint64(coutbuf.Offset()) - uint64(startoff)
-		strput(d.name)
+		d.nameoff = uint64(ctxt.Out.Offset()) - uint64(startoff)
+		strput(ctxt.Out, d.name)
 	}
 
 	// write function names
 	var m *Imp
 	for d := dr; d != nil; d = d.next {
 		for m = d.ms; m != nil; m = m.next {
-			m.off = uint64(nextsectoff) + uint64(coutbuf.Offset()) - uint64(startoff)
-			Wputl(0) // hint
-			strput(m.s.Extname)
+			m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff)
+			ctxt.Out.Write16(0) // hint
+			strput(ctxt.Out, m.s.Extname)
 		}
 	}
 
 	// write OriginalFirstThunks
-	oftbase := uint64(coutbuf.Offset()) - uint64(startoff)
+	oftbase := uint64(ctxt.Out.Offset()) - uint64(startoff)
 
-	n = uint64(coutbuf.Offset())
+	n = uint64(ctxt.Out.Offset())
 	for d := dr; d != nil; d = d.next {
-		d.thunkoff = uint64(coutbuf.Offset()) - n
+		d.thunkoff = uint64(ctxt.Out.Offset()) - n
 		for m = d.ms; m != nil; m = m.next {
 			if pe64 != 0 {
-				Vputl(m.off)
+				ctxt.Out.Write64(m.off)
 			} else {
-				Lputl(uint32(m.off))
+				ctxt.Out.Write32(uint32(m.off))
 			}
 		}
 
 		if pe64 != 0 {
-			Vputl(0)
+			ctxt.Out.Write64(0)
 		} else {
-			Lputl(0)
+			ctxt.Out.Write32(0)
 		}
 	}
 
 	// add pe section and pad it at the end
-	n = uint64(coutbuf.Offset()) - uint64(startoff)
+	n = uint64(ctxt.Out.Offset()) - uint64(startoff)
 
-	isect := addpesection(ctxt, ".idata", int(n), int(n))
-	isect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
-	chksectoff(ctxt, isect, startoff)
-	strnput("", int(uint64(isect.SizeOfRawData)-n))
-	endoff := coutbuf.Offset()
+	isect := pefile.addSection(".idata", int(n), int(n))
+	isect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
+	isect.checkOffset(startoff)
+	isect.pad(ctxt.Out, uint32(n))
+	endoff := ctxt.Out.Offset()
 
 	// write FirstThunks (allocated in .data section)
-	ftbase := uint64(dynamic.Value) - uint64(datsect.VirtualAddress) - PEBASE
+	ftbase := uint64(dynamic.Value) - uint64(datsect.virtualAddress) - PEBASE
 
-	Cseek(int64(uint64(datsect.PointerToRawData) + ftbase))
+	ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
 	for d := dr; d != nil; d = d.next {
 		for m = d.ms; m != nil; m = m.next {
 			if pe64 != 0 {
-				Vputl(m.off)
+				ctxt.Out.Write64(m.off)
 			} else {
-				Lputl(uint32(m.off))
+				ctxt.Out.Write32(uint32(m.off))
 			}
 		}
 
 		if pe64 != 0 {
-			Vputl(0)
+			ctxt.Out.Write64(0)
 		} else {
-			Lputl(0)
+			ctxt.Out.Write32(0)
 		}
 	}
 
 	// finally write import descriptor table
-	Cseek(startoff)
+	out := ctxt.Out
+	out.SeekSet(startoff)
 
 	for d := dr; d != nil; d = d.next {
-		Lputl(uint32(uint64(isect.VirtualAddress) + oftbase + d.thunkoff))
-		Lputl(0)
-		Lputl(0)
-		Lputl(uint32(uint64(isect.VirtualAddress) + d.nameoff))
-		Lputl(uint32(uint64(datsect.VirtualAddress) + ftbase + d.thunkoff))
+		out.Write32(uint32(uint64(isect.virtualAddress) + oftbase + d.thunkoff))
+		out.Write32(0)
+		out.Write32(0)
+		out.Write32(uint32(uint64(isect.virtualAddress) + d.nameoff))
+		out.Write32(uint32(uint64(datsect.virtualAddress) + ftbase + d.thunkoff))
 	}
 
-	Lputl(0) //end
-	Lputl(0)
-	Lputl(0)
-	Lputl(0)
-	Lputl(0)
+	out.Write32(0) //end
+	out.Write32(0)
+	out.Write32(0)
+	out.Write32(0)
+	out.Write32(0)
 
 	// update data directory
-	dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect.VirtualAddress
-	dd[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect.VirtualSize
-	dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(dynamic.Value - PEBASE)
-	dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(dynamic.Size)
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect.virtualAddress
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect.virtualSize
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(dynamic.Value - PEBASE)
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(dynamic.Size)
 
-	Cseek(endoff)
+	out.SeekSet(endoff)
 }
 
-type byExtname []*Symbol
+type byExtname []*sym.Symbol
 
 func (s byExtname) Len() int           { return len(s) }
 func (s byExtname) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
@@ -747,12 +1204,12 @@
 		return
 	}
 
-	sect := addpesection(ctxt, ".edata", size, size)
-	sect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-	chksectoff(ctxt, sect, coutbuf.Offset())
-	va := int(sect.VirtualAddress)
-	dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
-	dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.VirtualSize
+	sect := pefile.addSection(".edata", size, size)
+	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+	sect.checkOffset(ctxt.Out.Offset())
+	va := int(sect.virtualAddress)
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.virtualSize
 
 	vaName := va + binary.Size(&e) + nexport*4
 	vaAddr := va + binary.Size(&e)
@@ -769,331 +1226,50 @@
 	e.AddressOfNames = uint32(vaName)
 	e.AddressOfNameOrdinals = uint32(vaNa)
 
+	out := ctxt.Out
+
 	// put IMAGE_EXPORT_DIRECTORY
-	binary.Write(&coutbuf, binary.LittleEndian, &e)
+	binary.Write(out, binary.LittleEndian, &e)
 
 	// put EXPORT Address Table
 	for i := 0; i < nexport; i++ {
-		Lputl(uint32(dexport[i].Value - PEBASE))
+		out.Write32(uint32(dexport[i].Value - PEBASE))
 	}
 
 	// put EXPORT Name Pointer Table
 	v := int(e.Name + uint32(len(*flagOutfile)) + 1)
 
 	for i := 0; i < nexport; i++ {
-		Lputl(uint32(v))
+		out.Write32(uint32(v))
 		v += len(dexport[i].Extname) + 1
 	}
 
 	// put EXPORT Ordinal Table
 	for i := 0; i < nexport; i++ {
-		Wputl(uint16(i))
+		out.Write16(uint16(i))
 	}
 
 	// put Names
-	strnput(*flagOutfile, len(*flagOutfile)+1)
+	out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
 
 	for i := 0; i < nexport; i++ {
-		strnput(dexport[i].Extname, len(dexport[i].Extname)+1)
+		out.WriteStringN(dexport[i].Extname, len(dexport[i].Extname)+1)
 	}
-	strnput("", int(sect.SizeOfRawData-uint32(size)))
-}
-
-// perelocsect relocates symbols from first in section sect, and returns
-// the total number of relocations emitted.
-func perelocsect(ctxt *Link, sect *Section, syms []*Symbol, base uint64) int {
-	// If main section has no bits, nothing to relocate.
-	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-		return 0
-	}
-
-	relocs := 0
-
-	sect.Reloff = uint64(coutbuf.Offset())
-	for i, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if uint64(s.Value) >= sect.Vaddr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	eaddr := int32(sect.Vaddr + sect.Length)
-	for _, sym := range syms {
-		if !sym.Attr.Reachable() {
-			continue
-		}
-		if sym.Value >= int64(eaddr) {
-			break
-		}
-		for ri := 0; ri < len(sym.R); ri++ {
-			r := &sym.R[ri]
-			if r.Done != 0 {
-				continue
-			}
-			if r.Xsym == nil {
-				Errorf(sym, "missing xsym in relocation")
-				continue
-			}
-
-			if r.Xsym.Dynid < 0 {
-				Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
-			}
-			if !Thearch.PEreloc1(sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
-				Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
-			}
-
-			relocs++
-		}
-	}
-
-	sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
-
-	return relocs
-}
-
-// peemitsectreloc emits the relocation entries for sect.
-// The actual relocations are emitted by relocfn.
-// This updates the corresponding PE section table entry
-// with the relocation offset and count.
-func peemitsectreloc(sect *IMAGE_SECTION_HEADER, relocfn func() int) {
-	sect.PointerToRelocations = uint32(coutbuf.Offset())
-	// first entry: extended relocs
-	Lputl(0) // placeholder for number of relocation + 1
-	Lputl(0)
-	Wputl(0)
-
-	n := relocfn() + 1
-
-	cpos := coutbuf.Offset()
-	Cseek(int64(sect.PointerToRelocations))
-	Lputl(uint32(n))
-	Cseek(cpos)
-	if n > 0x10000 {
-		n = 0x10000
-		sect.Characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
-	} else {
-		sect.PointerToRelocations += 10 // skip the extend reloc entry
-	}
-	sect.NumberOfRelocations = uint16(n - 1)
-}
-
-// peemitreloc emits relocation entries for go.o in external linking.
-func peemitreloc(ctxt *Link, text, data, ctors *IMAGE_SECTION_HEADER) {
-	for coutbuf.Offset()&7 != 0 {
-		Cput(0)
-	}
-
-	peemitsectreloc(text, func() int {
-		n := perelocsect(ctxt, Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
-		for _, sect := range Segtext.Sections[1:] {
-			n += perelocsect(ctxt, sect, datap, Segtext.Vaddr)
-		}
-		return n
-	})
-
-	peemitsectreloc(data, func() int {
-		var n int
-		for _, sect := range Segdata.Sections {
-			n += perelocsect(ctxt, sect, datap, Segdata.Vaddr)
-		}
-		return n
-	})
-
-dwarfLoop:
-	for _, sect := range Segdwarf.Sections {
-		for i, name := range shNames {
-			if sect.Name == name {
-				peemitsectreloc(&sh[i], func() int {
-					return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
-				})
-				continue dwarfLoop
-			}
-		}
-		Errorf(nil, "peemitsectreloc: could not find %q section", sect.Name)
-	}
-
-	peemitsectreloc(ctors, func() int {
-		dottext := ctxt.Syms.Lookup(".text", 0)
-		Lputl(0)
-		Lputl(uint32(dottext.Dynid))
-		switch objabi.GOARCH {
-		default:
-			Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
-		case "386":
-			Wputl(IMAGE_REL_I386_DIR32)
-		case "amd64":
-			Wputl(IMAGE_REL_AMD64_ADDR64)
-		}
-		return 1
-	})
+	sect.pad(out, uint32(size))
 }
 
 func (ctxt *Link) dope() {
 	/* relocation table */
 	rel := ctxt.Syms.Lookup(".rel", 0)
 
-	rel.Attr |= AttrReachable
-	rel.Type = SELFROSECT
+	rel.Attr |= sym.AttrReachable
+	rel.Type = sym.SELFROSECT
 
 	initdynimport(ctxt)
 	initdynexport(ctxt)
 }
 
-func strtbladd(name string) int {
-	off := len(strtbl) + 4 // offset includes 4-byte length at beginning of table
-	strtbl = append(strtbl, name...)
-	strtbl = append(strtbl, 0)
-	return off
-}
-
-/*
- * For more than 8 characters section names, name contains a slash (/) that is
- * followed by an ASCII representation of a decimal number that is an offset into
- * the string table.
- * reference: pecoff_v8.docx Page 24.
- * <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
- */
-func newPEDWARFSection(ctxt *Link, name string, size int64) *IMAGE_SECTION_HEADER {
-	if size == 0 {
-		return nil
-	}
-
-	off := strtbladd(name)
-	s := fmt.Sprintf("/%d", off)
-	h := addpesectionWithLongName(ctxt, s, name, int(size), int(size))
-	h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
-
-	return h
-}
-
-// writePESymTableRecords writes all COFF symbol table records.
-// It returns number of records written.
-func writePESymTableRecords(ctxt *Link) int {
-	var symcnt int
-
-	writeOneSymbol := func(s *Symbol, addr int64, sectidx int, typ uint16, class uint8) {
-		// write COFF symbol table record
-		if len(s.Name) > 8 {
-			Lputl(0)
-			Lputl(uint32(strtbladd(s.Name)))
-		} else {
-			strnput(s.Name, 8)
-		}
-		Lputl(uint32(addr))
-		Wputl(uint16(sectidx))
-		Wputl(typ)
-		Cput(class)
-		Cput(0) // no aux entries
-
-		s.Dynid = int32(symcnt)
-
-		symcnt++
-	}
-
-	put := func(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
-		if s == nil {
-			return
-		}
-		if s.Sect == nil && type_ != UndefinedSym {
-			return
-		}
-		switch type_ {
-		default:
-			return
-		case DataSym, BSSSym, TextSym, UndefinedSym:
-		}
-
-		// Only windows/386 requires underscore prefix on external symbols.
-		if SysArch.Family == sys.I386 &&
-			Linkmode == LinkExternal &&
-			(s.Type == SHOSTOBJ || s.Attr.CgoExport()) {
-			s.Name = "_" + s.Name
-		}
-
-		typ := uint16(IMAGE_SYM_TYPE_NULL)
-		var sect int
-		var value int64
-		if s.Sect != nil && s.Sect.Seg == &Segdata {
-			// Note: although address of runtime.edata (type SDATA) is at the start of .bss section
-			// it still belongs to the .data section, not the .bss section.
-			if uint64(s.Value) >= Segdata.Vaddr+Segdata.Filelen && s.Type != SDATA && Linkmode == LinkExternal {
-				value = int64(uint64(s.Value) - Segdata.Vaddr - Segdata.Filelen)
-				sect = bsssect
-			} else {
-				value = int64(uint64(s.Value) - Segdata.Vaddr)
-				sect = datasect
-			}
-		} else if s.Sect != nil && s.Sect.Seg == &Segtext {
-			value = int64(uint64(s.Value) - Segtext.Vaddr)
-			sect = textsect
-		} else if type_ == UndefinedSym {
-			typ = IMAGE_SYM_DTYPE_FUNCTION
-		} else {
-			Errorf(s, "addpesym %#x", addr)
-		}
-		if typ != IMAGE_SYM_TYPE_NULL {
-		} else if Linkmode != LinkExternal {
-			// TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308
-			typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
-			typ = 0x0308 // "array of structs"
-		}
-		class := IMAGE_SYM_CLASS_EXTERNAL
-		if s.Version != 0 || (s.Type&SHIDDEN != 0) || s.Attr.Local() {
-			class = IMAGE_SYM_CLASS_STATIC
-		}
-		writeOneSymbol(s, value, sect, typ, uint8(class))
-	}
-
-	if Linkmode == LinkExternal {
-		// Include section symbols as external, because
-		// .ctors and .debug_* section relocations refer to it.
-		for idx, name := range shNames {
-			sym := ctxt.Syms.Lookup(name, 0)
-			writeOneSymbol(sym, 0, idx+1, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
-		}
-	}
-
-	genasmsym(ctxt, put)
-
-	return symcnt
-}
-
-func addpesymtable(ctxt *Link) {
-	symtabStartPos := coutbuf.Offset()
-
-	// write COFF symbol table
-	var symcnt int
-	if !*FlagS || Linkmode == LinkExternal {
-		symcnt = writePESymTableRecords(ctxt)
-	}
-
-	// update COFF file header and section table
-	size := len(strtbl) + 4 + 18*symcnt
-	var h *IMAGE_SECTION_HEADER
-	if Linkmode != LinkExternal {
-		// We do not really need .symtab for go.o, and if we have one, ld
-		// will also include it in the exe, and that will confuse windows.
-		h = addpesection(ctxt, ".symtab", size, size)
-		h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
-		chksectoff(ctxt, h, symtabStartPos)
-	}
-	fh.PointerToSymbolTable = uint32(symtabStartPos)
-	fh.NumberOfSymbols = uint32(symcnt)
-
-	// write COFF string table
-	Lputl(uint32(len(strtbl)) + 4)
-	for i := 0; i < len(strtbl); i++ {
-		Cput(strtbl[i])
-	}
-	if Linkmode != LinkExternal {
-		strnput("", int(h.SizeOfRawData-uint32(size)))
-	}
-}
-
-func setpersrc(ctxt *Link, sym *Symbol) {
+func setpersrc(ctxt *Link, sym *sym.Symbol) {
 	if rsrcsym != nil {
 		Errorf(sym, "too many .rsrc sections")
 	}
@@ -1106,18 +1282,18 @@
 		return
 	}
 
-	h := addpesection(ctxt, ".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
-	h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
-	chksectoff(ctxt, h, coutbuf.Offset())
+	h := pefile.addSection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
+	h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
+	h.checkOffset(ctxt.Out.Offset())
 
 	// relocation
 	var p []byte
-	var r *Reloc
+	var r *sym.Reloc
 	var val uint32
 	for ri := 0; ri < len(rsrcsym.R); ri++ {
 		r = &rsrcsym.R[ri]
 		p = rsrcsym.P[r.Off:]
-		val = uint32(int64(h.VirtualAddress) + r.Add)
+		val = uint32(int64(h.virtualAddress) + r.Add)
 
 		// 32-bit little-endian
 		p[0] = byte(val)
@@ -1127,222 +1303,66 @@
 		p[3] = byte(val >> 24)
 	}
 
-	Cwrite(rsrcsym.P)
-	strnput("", int(int64(h.SizeOfRawData)-rsrcsym.Size))
+	ctxt.Out.Write(rsrcsym.P)
+	h.pad(ctxt.Out, uint32(rsrcsym.Size))
 
 	// update data directory
-	dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h.VirtualAddress
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h.virtualAddress
 
-	dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.VirtualSize
-}
-
-func addinitarray(ctxt *Link) (c *IMAGE_SECTION_HEADER) {
-	// The size below was determined by the specification for array relocations,
-	// and by observing what GCC writes here. If the initarray section grows to
-	// contain more than one constructor entry, the size will need to be 8 * constructor_count.
-	// However, the entire Go runtime is initialized from just one function, so it is unlikely
-	// that this will need to grow in the future.
-	var size int
-	switch objabi.GOARCH {
-	default:
-		fmt.Fprintf(os.Stderr, "link: unknown architecture for PE: %q\n", objabi.GOARCH)
-		os.Exit(2)
-	case "386":
-		size = 4
-	case "amd64":
-		size = 8
-	}
-
-	c = addpesection(ctxt, ".ctors", size, size)
-	c.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-	c.SizeOfRawData = uint32(size)
-
-	Cseek(int64(c.PointerToRawData))
-	chksectoff(ctxt, c, coutbuf.Offset())
-	init_entry := ctxt.Syms.Lookup(*flagEntrySymbol, 0)
-	addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
-
-	switch objabi.GOARCH {
-	case "386":
-		Lputl(uint32(addr))
-	case "amd64":
-		Vputl(addr)
-	}
-
-	return c
+	pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.virtualSize
 }
 
 func Asmbpe(ctxt *Link) {
-	switch SysArch.Family {
+	switch ctxt.Arch.Family {
 	default:
-		Exitf("unknown PE architecture: %v", SysArch.Family)
-	case sys.AMD64:
-		fh.Machine = IMAGE_FILE_MACHINE_AMD64
-	case sys.I386:
-		fh.Machine = IMAGE_FILE_MACHINE_I386
+		Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
+	case sys.AMD64, sys.I386:
 	}
 
-	t := addpesection(ctxt, ".text", int(Segtext.Length), int(Segtext.Length))
-	t.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
-	if Linkmode == LinkExternal {
+	t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length))
+	t.characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
+	if ctxt.LinkMode == LinkExternal {
 		// some data symbols (e.g. masks) end up in the .text section, and they normally
 		// expect larger alignment requirement than the default text section alignment.
-		t.Characteristics |= IMAGE_SCN_ALIGN_32BYTES
+		t.characteristics |= IMAGE_SCN_ALIGN_32BYTES
 	}
-	chksectseg(ctxt, t, &Segtext)
-	textsect = pensect
+	t.checkSegment(&Segtext)
+	pefile.textSect = t
 
-	var d *IMAGE_SECTION_HEADER
-	var c *IMAGE_SECTION_HEADER
-	if Linkmode != LinkExternal {
-		d = addpesection(ctxt, ".data", int(Segdata.Length), int(Segdata.Filelen))
-		d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
-		chksectseg(ctxt, d, &Segdata)
-		datasect = pensect
+	var d *peSection
+	if ctxt.LinkMode != LinkExternal {
+		d = pefile.addSection(".data", int(Segdata.Length), int(Segdata.Filelen))
+		d.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
+		d.checkSegment(&Segdata)
+		pefile.dataSect = d
 	} else {
-		d = addpesection(ctxt, ".data", int(Segdata.Filelen), int(Segdata.Filelen))
-		d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
-		chksectseg(ctxt, d, &Segdata)
-		datasect = pensect
+		d = pefile.addSection(".data", int(Segdata.Filelen), int(Segdata.Filelen))
+		d.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
+		d.checkSegment(&Segdata)
+		pefile.dataSect = d
 
-		b := addpesection(ctxt, ".bss", int(Segdata.Length-Segdata.Filelen), 0)
-		b.Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
-		b.PointerToRawData = 0
-		bsssect = pensect
+		b := pefile.addSection(".bss", int(Segdata.Length-Segdata.Filelen), 0)
+		b.characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
+		b.pointerToRawData = 0
+		pefile.bssSect = b
 	}
 
-	if !*FlagS {
-		dwarfaddpeheaders(ctxt)
+	pefile.addDWARF()
+
+	if ctxt.LinkMode == LinkExternal {
+		pefile.ctorsSect = pefile.addInitArray(ctxt)
 	}
 
-	if Linkmode == LinkExternal {
-		c = addinitarray(ctxt)
-	}
-
-	Cseek(int64(nextfileoff))
-	if Linkmode != LinkExternal {
+	ctxt.Out.SeekSet(int64(pefile.nextFileOffset))
+	if ctxt.LinkMode != LinkExternal {
 		addimports(ctxt, d)
 		addexports(ctxt)
 	}
-	addpesymtable(ctxt)
+	pefile.writeSymbolTableAndStringTable(ctxt)
 	addpersrc(ctxt)
-	if Linkmode == LinkExternal {
-		peemitreloc(ctxt, t, d, c)
+	if ctxt.LinkMode == LinkExternal {
+		pefile.emitRelocations(ctxt)
 	}
 
-	fh.NumberOfSections = uint16(pensect)
-
-	// Being able to produce identical output for identical input is
-	// much more beneficial than having build timestamp in the header.
-	fh.TimeDateStamp = 0
-
-	if Linkmode == LinkExternal {
-		fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED
-	} else {
-		fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED
-	}
-	if pe64 != 0 {
-		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
-		fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE
-		oh64.Magic = 0x20b // PE32+
-	} else {
-		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
-		fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE
-		oh.Magic = 0x10b // PE32
-		oh.BaseOfData = d.VirtualAddress
-	}
-
-	// Fill out both oh64 and oh. We only use one. Oh well.
-	oh64.MajorLinkerVersion = 3
-
-	oh.MajorLinkerVersion = 3
-	oh64.MinorLinkerVersion = 0
-	oh.MinorLinkerVersion = 0
-	oh64.SizeOfCode = t.SizeOfRawData
-	oh.SizeOfCode = t.SizeOfRawData
-	oh64.SizeOfInitializedData = d.SizeOfRawData
-	oh.SizeOfInitializedData = d.SizeOfRawData
-	oh64.SizeOfUninitializedData = 0
-	oh.SizeOfUninitializedData = 0
-	if Linkmode != LinkExternal {
-		oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
-		oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
-	}
-	oh64.BaseOfCode = t.VirtualAddress
-	oh.BaseOfCode = t.VirtualAddress
-	oh64.ImageBase = PEBASE
-	oh.ImageBase = PEBASE
-	oh64.SectionAlignment = uint32(PESECTALIGN)
-	oh.SectionAlignment = uint32(PESECTALIGN)
-	oh64.FileAlignment = uint32(PEFILEALIGN)
-	oh.FileAlignment = uint32(PEFILEALIGN)
-	oh64.MajorOperatingSystemVersion = 4
-	oh.MajorOperatingSystemVersion = 4
-	oh64.MinorOperatingSystemVersion = 0
-	oh.MinorOperatingSystemVersion = 0
-	oh64.MajorImageVersion = 1
-	oh.MajorImageVersion = 1
-	oh64.MinorImageVersion = 0
-	oh.MinorImageVersion = 0
-	oh64.MajorSubsystemVersion = 4
-	oh.MajorSubsystemVersion = 4
-	oh64.MinorSubsystemVersion = 0
-	oh.MinorSubsystemVersion = 0
-	oh64.SizeOfImage = uint32(nextsectoff)
-	oh.SizeOfImage = uint32(nextsectoff)
-	oh64.SizeOfHeaders = uint32(PEFILEHEADR)
-	oh.SizeOfHeaders = uint32(PEFILEHEADR)
-	if windowsgui {
-		oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
-		oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
-	} else {
-		oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
-		oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
-	}
-
-	// Disable stack growth as we don't want Windows to
-	// fiddle with the thread stack limits, which we set
-	// ourselves to circumvent the stack checks in the
-	// Windows exception dispatcher.
-	// Commit size must be strictly less than reserve
-	// size otherwise reserve will be rounded up to a
-	// larger size, as verified with VMMap.
-
-	// On 64-bit, we always reserve 2MB stacks. "Pure" Go code is
-	// okay with much smaller stacks, but the syscall package
-	// makes it easy to call into arbitrary C code without cgo,
-	// and system calls even in "pure" Go code are actually C
-	// calls that may need more stack than we think.
-	//
-	// The default stack reserve size affects only the main
-	// thread, ctrlhandler thread, and profileloop thread. For
-	// these, it must be greater than the stack size assumed by
-	// externalthreadhandler.
-	//
-	// For other threads we specify stack size in runtime explicitly.
-	// For these, the reserve must match STACKSIZE in
-	// runtime/cgo/gcc_windows_{386,amd64}.c and the correspondent
-	// CreateThread parameter in runtime.newosproc.
-	oh64.SizeOfStackReserve = 0x00200000
-	oh64.SizeOfStackCommit = 0x00200000 - 0x2000 // account for 2 guard pages
-
-	// 32-bit is trickier since there much less address space to
-	// work with. Here we use large stacks only in cgo binaries as
-	// a compromise.
-	if !iscgo {
-		oh.SizeOfStackReserve = 0x00020000
-		oh.SizeOfStackCommit = 0x00001000
-	} else {
-		oh.SizeOfStackReserve = 0x00100000
-		oh.SizeOfStackCommit = 0x00100000 - 0x2000
-	}
-
-	oh64.SizeOfHeapReserve = 0x00100000
-	oh.SizeOfHeapReserve = 0x00100000
-	oh64.SizeOfHeapCommit = 0x00001000
-	oh.SizeOfHeapCommit = 0x00001000
-	oh64.NumberOfRvaAndSizes = 16
-	oh.NumberOfRvaAndSizes = 16
-
-	pewrite()
+	pewrite(ctxt)
 }
diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go
index 6e239d7..6f019de 100644
--- a/src/cmd/link/internal/ld/sym.go
+++ b/src/cmd/link/internal/ld/sym.go
@@ -34,35 +34,37 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"log"
 )
 
 func linknew(arch *sys.Arch) *Link {
 	ctxt := &Link{
-		Syms: &Symbols{
-			hash: []map[string]*Symbol{
-				// preallocate about 2mb for hash of
-				// non static symbols
-				make(map[string]*Symbol, 100000),
-			},
-			Allsym: make([]*Symbol, 0, 100000),
-		},
+		Syms:         sym.NewSymbols(),
+		Out:          &OutBuf{arch: arch},
 		Arch:         arch,
-		LibraryByPkg: make(map[string]*Library),
+		LibraryByPkg: make(map[string]*sym.Library),
 	}
 
 	if objabi.GOARCH != arch.Name {
 		log.Fatalf("invalid objabi.GOARCH %s (want %s)", objabi.GOARCH, arch.Name)
 	}
 
+	AtExit(func() {
+		if nerrors > 0 && ctxt.Out.f != nil {
+			ctxt.Out.f.Close()
+			mayberemoveoutfile()
+		}
+	})
+
 	return ctxt
 }
 
 // computeTLSOffset records the thread-local storage offset.
 func (ctxt *Link) computeTLSOffset() {
-	switch Headtype {
+	switch ctxt.HeadType {
 	default:
-		log.Fatalf("unknown thread-local storage offset for %v", Headtype)
+		log.Fatalf("unknown thread-local storage offset for %v", ctxt.HeadType)
 
 	case objabi.Hplan9, objabi.Hwindows:
 		break
diff --git a/src/cmd/link/internal/ld/symbols.go b/src/cmd/link/internal/ld/symbols.go
deleted file mode 100644
index 154507d..0000000
--- a/src/cmd/link/internal/ld/symbols.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@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@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.
-
-package ld
-
-type Symbols struct {
-	symbolBatch []Symbol
-
-	// Symbol lookup based on name and indexed by version.
-	hash []map[string]*Symbol
-
-	Allsym []*Symbol
-}
-
-func (syms *Symbols) newsym(name string, v int) *Symbol {
-	batch := syms.symbolBatch
-	if len(batch) == 0 {
-		batch = make([]Symbol, 1000)
-	}
-	s := &batch[0]
-	syms.symbolBatch = batch[1:]
-
-	s.Dynid = -1
-	s.Plt = -1
-	s.Got = -1
-	s.Name = name
-	s.Version = int16(v)
-	syms.Allsym = append(syms.Allsym, s)
-
-	return s
-}
-
-// Look up the symbol with the given name and version, creating the
-// symbol if it is not found.
-func (syms *Symbols) Lookup(name string, v int) *Symbol {
-	m := syms.hash[v]
-	s := m[name]
-	if s != nil {
-		return s
-	}
-	s = syms.newsym(name, v)
-	s.Extname = s.Name
-	m[name] = s
-	return s
-}
-
-// Look up the symbol with the given name and version, returning nil
-// if it is not found.
-func (syms *Symbols) ROLookup(name string, v int) *Symbol {
-	return syms.hash[v][name]
-}
-
-// Allocate a new version (i.e. symbol namespace).
-func (syms *Symbols) IncVersion() int {
-	syms.hash = append(syms.hash, make(map[string]*Symbol))
-	return len(syms.hash) - 1
-}
diff --git a/src/cmd/link/internal/ld/symkind.go b/src/cmd/link/internal/ld/symkind.go
deleted file mode 100644
index c057f6c..0000000
--- a/src/cmd/link/internal/ld/symkind.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@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@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.
-
-package ld
-
-// A SymKind describes the kind of memory represented by a symbol.
-type SymKind int16
-
-// Defined SymKind values.
-//
-// TODO(rsc): Give idiomatic Go names.
-//go:generate stringer -type=SymKind
-const (
-	Sxxx SymKind = iota
-	STEXT
-	SELFRXSECT
-
-	// Read-only sections.
-	STYPE
-	SSTRING
-	SGOSTRING
-	SGOFUNC
-	SGCBITS
-	SRODATA
-	SFUNCTAB
-
-	SELFROSECT
-	SMACHOPLT
-
-	// Read-only sections with relocations.
-	//
-	// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
-	// When linking a shared object, some conceptually "read only" types need to
-	// be written to by relocations and putting them in a section called
-	// ".rodata" interacts poorly with the system linkers. The GNU linkers
-	// support this situation by arranging for sections of the name
-	// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
-	// relocations have applied, so when the Go linker is creating a shared
-	// object it checks all objects of the above types and bumps any object that
-	// has a relocation to it to the corresponding type below, which are then
-	// written to sections with appropriate magic names.
-	STYPERELRO
-	SSTRINGRELRO
-	SGOSTRINGRELRO
-	SGOFUNCRELRO
-	SGCBITSRELRO
-	SRODATARELRO
-	SFUNCTABRELRO
-
-	// Part of .data.rel.ro if it exists, otherwise part of .rodata.
-	STYPELINK
-	SITABLINK
-	SSYMTAB
-	SPCLNTAB
-
-	// Writable sections.
-	SELFSECT
-	SMACHO
-	SMACHOGOT
-	SWINDOWS
-	SELFGOT
-	SNOPTRDATA
-	SINITARR
-	SDATA
-	SBSS
-	SNOPTRBSS
-	STLSBSS
-	SXREF
-	SMACHOSYMSTR
-	SMACHOSYMTAB
-	SMACHOINDIRECTPLT
-	SMACHOINDIRECTGOT
-	SFILE
-	SFILEPATH
-	SCONST
-	SDYNIMPORT
-	SHOSTOBJ
-	SDWARFSECT
-	SDWARFINFO
-	SDWARFRANGE
-	SSUB       = SymKind(1 << 8)
-	SMASK      = SymKind(SSUB - 1)
-	SHIDDEN    = SymKind(1 << 9)
-	SCONTAINER = SymKind(1 << 10) // has a sub-symbol
-)
-
-// abiSymKindToSymKind maps values read from object files (which are
-// of type cmd/internal/objabi.SymKind) to values of type SymKind.
-var abiSymKindToSymKind = [...]SymKind{
-	Sxxx,
-	STEXT,
-	SRODATA,
-	SNOPTRDATA,
-	SDATA,
-	SBSS,
-	SNOPTRBSS,
-	STLSBSS,
-	SDWARFINFO,
-	SDWARFRANGE,
-}
-
-// readOnly are the symbol kinds that form read-only sections. In some
-// cases, if they will require relocations, they are transformed into
-// rel-ro sections using relROMap.
-var readOnly = []SymKind{
-	STYPE,
-	SSTRING,
-	SGOSTRING,
-	SGOFUNC,
-	SGCBITS,
-	SRODATA,
-	SFUNCTAB,
-}
-
-// relROMap describes the transformation of read-only symbols to rel-ro
-// symbols.
-var relROMap = map[SymKind]SymKind{
-	STYPE:     STYPERELRO,
-	SSTRING:   SSTRINGRELRO,
-	SGOSTRING: SGOSTRINGRELRO,
-	SGOFUNC:   SGOFUNCRELRO,
-	SGCBITS:   SGCBITSRELRO,
-	SRODATA:   SRODATARELRO,
-	SFUNCTAB:  SFUNCTABRELRO,
-}
diff --git a/src/cmd/link/internal/ld/symkind_string.go b/src/cmd/link/internal/ld/symkind_string.go
deleted file mode 100644
index 2178b50..0000000
--- a/src/cmd/link/internal/ld/symkind_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
-
-package ld
-
-import "fmt"
-
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFOSDWARFRANGE"
-
-var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 214, 220, 229, 237, 244, 254, 262, 267, 271, 280, 287, 292, 304, 316, 333, 350, 355, 364, 370, 380, 388, 398, 408, 419}
-
-func (i SymKind) String() string {
-	if i < 0 || i >= SymKind(len(_SymKind_index)-1) {
-		return fmt.Sprintf("SymKind(%d)", i)
-	}
-	return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
-}
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 78e9dc2..bb8c199 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -33,6 +33,7 @@
 import (
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"cmd/link/internal/sym"
 	"fmt"
 	"path/filepath"
 	"strings"
@@ -52,31 +53,31 @@
 	return off
 }
 
-func putelfsyment(off int, addr int64, size int64, info int, shndx int, other int) {
+func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx int, other int) {
 	if elf64 {
-		Thearch.Lput(uint32(off))
-		Cput(uint8(info))
-		Cput(uint8(other))
-		Thearch.Wput(uint16(shndx))
-		Thearch.Vput(uint64(addr))
-		Thearch.Vput(uint64(size))
+		out.Write32(uint32(off))
+		out.Write8(uint8(info))
+		out.Write8(uint8(other))
+		out.Write16(uint16(shndx))
+		out.Write64(uint64(addr))
+		out.Write64(uint64(size))
 		Symsize += ELF64SYMSIZE
 	} else {
-		Thearch.Lput(uint32(off))
-		Thearch.Lput(uint32(addr))
-		Thearch.Lput(uint32(size))
-		Cput(uint8(info))
-		Cput(uint8(other))
-		Thearch.Wput(uint16(shndx))
+		out.Write32(uint32(off))
+		out.Write32(uint32(addr))
+		out.Write32(uint32(size))
+		out.Write8(uint8(info))
+		out.Write8(uint8(other))
+		out.Write16(uint16(shndx))
 		Symsize += ELF32SYMSIZE
 	}
 }
 
-var numelfsym int = 1 // 0 is reserved
+var numelfsym = 1 // 0 is reserved
 
 var elfbind int
 
-func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *Symbol) {
+func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go_ *sym.Symbol) {
 	var typ int
 
 	switch t {
@@ -109,7 +110,7 @@
 	}
 
 	var elfshnum int
-	if xo.Type == SDYNIMPORT || xo.Type == SHOSTOBJ {
+	if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ {
 		elfshnum = SHN_UNDEF
 	} else {
 		if xo.Sect == nil {
@@ -120,14 +121,14 @@
 			Errorf(x, "missing ELF section in putelfsym")
 			return
 		}
-		elfshnum = xo.Sect.Elfsect.shnum
+		elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
 	}
 
 	// One pass for each binding: STB_LOCAL, STB_GLOBAL,
 	// maybe one day STB_WEAK.
 	bind := STB_GLOBAL
 
-	if x.Version != 0 || (x.Type&SHIDDEN != 0) || x.Attr.Local() {
+	if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
 		bind = STB_LOCAL
 	}
 
@@ -136,18 +137,23 @@
 	// To avoid filling the dynamic table with lots of unnecessary symbols,
 	// mark all Go symbols local (not global) in the final executable.
 	// But when we're dynamically linking, we need all those global symbols.
-	if !ctxt.DynlinkingGo() && Linkmode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
+	if !ctxt.DynlinkingGo() && ctxt.LinkMode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
 		bind = STB_LOCAL
 	}
 
-	if Linkmode == LinkExternal && elfshnum != SHN_UNDEF {
+	if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
 		addr -= int64(xo.Sect.Vaddr)
 	}
 	other := STV_DEFAULT
-	if x.Type&SHIDDEN != 0 {
+	if x.Attr.VisibilityHidden() {
+		// TODO(mwhudson): We only set AttrVisibilityHidden in ldelf, i.e. when
+		// internally linking. But STV_HIDDEN visibility only matters in object
+		// files and shared libraries, and as we are a long way from implementing
+		// internal linking for shared libraries and only create object files when
+		// externally linking, I don't think this makes a lot of sense.
 		other = STV_HIDDEN
 	}
-	if SysArch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
+	if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
 		// On ppc64 the top three bits of the st_other field indicate how
 		// many instructions separate the global and local entry points. In
 		// our case it is two instructions, indicated by the value 3.
@@ -165,16 +171,16 @@
 		s = strings.Replace(s, "·", ".", -1)
 	}
 
-	if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == STEXT {
+	if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == sym.STEXT {
 		// When dynamically linking, we want references to functions defined
 		// in this module to always be to the function object, not to the
 		// PLT. We force this by writing an additional local symbol for every
 		// global function symbol and making all relocations against the
 		// global symbol refer to this local symbol instead (see
-		// (*Symbol).ElfsymForReloc). This is approximately equivalent to the
+		// (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the
 		// ELF linker -Bsymbolic-functions option, but that is buggy on
 		// several platforms.
-		putelfsyment(putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
+		putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
 		x.LocalElfsym = int32(numelfsym)
 		numelfsym++
 		return
@@ -182,20 +188,20 @@
 		return
 	}
 
-	putelfsyment(putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
+	putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
 	x.Elfsym = int32(numelfsym)
 	numelfsym++
 }
 
-func putelfsectionsym(s *Symbol, shndx int) {
-	putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
+func putelfsectionsym(out *OutBuf, s *sym.Symbol, shndx int) {
+	putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
 	s.Elfsym = int32(numelfsym)
 	numelfsym++
 }
 
 func Asmelfsym(ctxt *Link) {
 	// the first symbol entry is reserved
-	putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
+	putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
 
 	dwarfaddelfsectionsyms(ctxt)
 
@@ -203,7 +209,7 @@
 	// Avoid having the working directory inserted into the symbol table.
 	// It is added with a name to avoid problems with external linking
 	// encountered on some versions of Solaris. See issue #14957.
-	putelfsyment(putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
+	putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
 	numelfsym++
 
 	elfbind = STB_LOCAL
@@ -214,7 +220,7 @@
 	genasmsym(ctxt, putelfsym)
 }
 
-func putplan9sym(ctxt *Link, x *Symbol, s string, typ SymbolType, addr int64, go_ *Symbol) {
+func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64, go_ *sym.Symbol) {
 	t := int(typ)
 	switch typ {
 	case TextSym, DataSym, BSSSym:
@@ -223,28 +229,20 @@
 		}
 		fallthrough
 
-	case AutoSym, ParamSym, FileSym, FrameSym:
+	case AutoSym, ParamSym, FrameSym:
 		l := 4
-		if Headtype == objabi.Hplan9 && SysArch.Family == sys.AMD64 && !Flag8 {
-			Lputb(uint32(addr >> 32))
+		if ctxt.HeadType == objabi.Hplan9 && ctxt.Arch.Family == sys.AMD64 && !Flag8 {
+			ctxt.Out.Write32b(uint32(addr >> 32))
 			l = 8
 		}
 
-		Lputb(uint32(addr))
-		Cput(uint8(t + 0x80)) /* 0x80 is variable length */
+		ctxt.Out.Write32b(uint32(addr))
+		ctxt.Out.Write8(uint8(t + 0x80)) /* 0x80 is variable length */
 
-		var i int
+		ctxt.Out.WriteString(s)
+		ctxt.Out.Write8(0)
 
-		/* skip the '<' in filenames */
-		if t == FileSym {
-			s = s[1:]
-		}
-		for i = 0; i < len(s); i++ {
-			Cput(s[i])
-		}
-		Cput(0)
-
-		Symsize += int32(l) + 1 + int32(i) + 1
+		Symsize += int32(l) + 1 + int32(len(s)) + 1
 
 	default:
 		return
@@ -255,43 +253,9 @@
 	genasmsym(ctxt, putplan9sym)
 }
 
-var symt *Symbol
+var symt *sym.Symbol
 
-var encbuf [10]byte
-
-func Wputb(w uint16) { Cwrite(Append16b(encbuf[:0], w)) }
-func Lputb(l uint32) { Cwrite(Append32b(encbuf[:0], l)) }
-func Vputb(v uint64) { Cwrite(Append64b(encbuf[:0], v)) }
-
-func Wputl(w uint16) { Cwrite(Append16l(encbuf[:0], w)) }
-func Lputl(l uint32) { Cwrite(Append32l(encbuf[:0], l)) }
-func Vputl(v uint64) { Cwrite(Append64l(encbuf[:0], v)) }
-
-func Append16b(b []byte, v uint16) []byte {
-	return append(b, uint8(v>>8), uint8(v))
-}
-func Append16l(b []byte, v uint16) []byte {
-	return append(b, uint8(v), uint8(v>>8))
-}
-
-func Append32b(b []byte, v uint32) []byte {
-	return append(b, uint8(v>>24), uint8(v>>16), uint8(v>>8), uint8(v))
-}
-func Append32l(b []byte, v uint32) []byte {
-	return append(b, uint8(v), uint8(v>>8), uint8(v>>16), uint8(v>>24))
-}
-
-func Append64b(b []byte, v uint64) []byte {
-	return append(b, uint8(v>>56), uint8(v>>48), uint8(v>>40), uint8(v>>32),
-		uint8(v>>24), uint8(v>>16), uint8(v>>8), uint8(v))
-}
-
-func Append64l(b []byte, v uint64) []byte {
-	return append(b, uint8(v), uint8(v>>8), uint8(v>>16), uint8(v>>24),
-		uint8(v>>32), uint8(v>>40), uint8(v>>48), uint8(v>>56))
-}
-
-type byPkg []*Library
+type byPkg []*sym.Library
 
 func (libs byPkg) Len() int {
 	return len(libs)
@@ -310,8 +274,8 @@
 func textsectionmap(ctxt *Link) uint32 {
 
 	t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
-	t.Type = SRODATA
-	t.Attr |= AttrReachable
+	t.Type = sym.SRODATA
+	t.Attr |= sym.AttrReachable
 	nsections := int64(0)
 
 	for _, sect := range Segtext.Sections {
@@ -321,7 +285,7 @@
 			break
 		}
 	}
-	Symgrow(t, 3*nsections*int64(SysArch.PtrSize))
+	t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
 
 	off := int64(0)
 	n := 0
@@ -340,21 +304,21 @@
 		if sect.Name != ".text" {
 			break
 		}
-		off = setuint(ctxt, t, off, sect.Vaddr-textbase)
-		off = setuint(ctxt, t, off, sect.Length)
+		off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
+		off = t.SetUint(ctxt.Arch, off, sect.Length)
 		if n == 0 {
 			s := ctxt.Syms.ROLookup("runtime.text", 0)
 			if s == nil {
 				Errorf(nil, "Unable to find symbol runtime.text\n")
 			}
-			off = setaddr(ctxt, t, off, s)
+			off = t.SetAddr(ctxt.Arch, off, s)
 
 		} else {
 			s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
 			if s == nil {
 				Errorf(nil, "Unable to find symbol runtime.text.%d\n", n)
 			}
-			off = setaddr(ctxt, t, off, s)
+			off = t.SetAddr(ctxt.Arch, off, s)
 		}
 		n++
 	}
@@ -366,98 +330,98 @@
 
 	// Define these so that they'll get put into the symbol table.
 	// data.c:/^address will provide the actual values.
-	ctxt.xdefine("runtime.text", STEXT, 0)
+	ctxt.xdefine("runtime.text", sym.STEXT, 0)
 
-	ctxt.xdefine("runtime.etext", STEXT, 0)
-	ctxt.xdefine("runtime.itablink", SRODATA, 0)
-	ctxt.xdefine("runtime.eitablink", SRODATA, 0)
-	ctxt.xdefine("runtime.rodata", SRODATA, 0)
-	ctxt.xdefine("runtime.erodata", SRODATA, 0)
-	ctxt.xdefine("runtime.types", SRODATA, 0)
-	ctxt.xdefine("runtime.etypes", SRODATA, 0)
-	ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, 0)
-	ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, 0)
-	ctxt.xdefine("runtime.data", SDATA, 0)
-	ctxt.xdefine("runtime.edata", SDATA, 0)
-	ctxt.xdefine("runtime.bss", SBSS, 0)
-	ctxt.xdefine("runtime.ebss", SBSS, 0)
-	ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, 0)
-	ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, 0)
-	ctxt.xdefine("runtime.end", SBSS, 0)
-	ctxt.xdefine("runtime.epclntab", SRODATA, 0)
-	ctxt.xdefine("runtime.esymtab", SRODATA, 0)
+	ctxt.xdefine("runtime.etext", sym.STEXT, 0)
+	ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.types", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
+	ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
+	ctxt.xdefine("runtime.data", sym.SDATA, 0)
+	ctxt.xdefine("runtime.edata", sym.SDATA, 0)
+	ctxt.xdefine("runtime.bss", sym.SBSS, 0)
+	ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
+	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
+	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
+	ctxt.xdefine("runtime.end", sym.SBSS, 0)
+	ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
 
 	// garbage collection symbols
 	s := ctxt.Syms.Lookup("runtime.gcdata", 0)
 
-	s.Type = SRODATA
+	s.Type = sym.SRODATA
 	s.Size = 0
-	s.Attr |= AttrReachable
-	ctxt.xdefine("runtime.egcdata", SRODATA, 0)
+	s.Attr |= sym.AttrReachable
+	ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
 
 	s = ctxt.Syms.Lookup("runtime.gcbss", 0)
-	s.Type = SRODATA
+	s.Type = sym.SRODATA
 	s.Size = 0
-	s.Attr |= AttrReachable
-	ctxt.xdefine("runtime.egcbss", SRODATA, 0)
+	s.Attr |= sym.AttrReachable
+	ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
 
 	// pseudo-symbols to mark locations of type, string, and go string data.
-	var symtype *Symbol
-	var symtyperel *Symbol
-	if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
+	var symtype *sym.Symbol
+	var symtyperel *sym.Symbol
+	if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
 		s = ctxt.Syms.Lookup("type.*", 0)
 
-		s.Type = STYPE
+		s.Type = sym.STYPE
 		s.Size = 0
-		s.Attr |= AttrReachable
+		s.Attr |= sym.AttrReachable
 		symtype = s
 
 		s = ctxt.Syms.Lookup("typerel.*", 0)
 
-		s.Type = STYPERELRO
+		s.Type = sym.STYPERELRO
 		s.Size = 0
-		s.Attr |= AttrReachable
+		s.Attr |= sym.AttrReachable
 		symtyperel = s
 	} else if !ctxt.DynlinkingGo() {
 		s = ctxt.Syms.Lookup("type.*", 0)
 
-		s.Type = STYPE
+		s.Type = sym.STYPE
 		s.Size = 0
-		s.Attr |= AttrReachable
+		s.Attr |= sym.AttrReachable
 		symtype = s
 		symtyperel = s
 	}
 
-	groupSym := func(name string, t SymKind) *Symbol {
+	groupSym := func(name string, t sym.SymKind) *sym.Symbol {
 		s := ctxt.Syms.Lookup(name, 0)
 		s.Type = t
 		s.Size = 0
-		s.Attr |= AttrLocal | AttrReachable
+		s.Attr |= sym.AttrLocal | sym.AttrReachable
 		return s
 	}
 	var (
-		symgostring = groupSym("go.string.*", SGOSTRING)
-		symgofunc   = groupSym("go.func.*", SGOFUNC)
-		symgcbits   = groupSym("runtime.gcbits.*", SGCBITS)
+		symgostring = groupSym("go.string.*", sym.SGOSTRING)
+		symgofunc   = groupSym("go.func.*", sym.SGOFUNC)
+		symgcbits   = groupSym("runtime.gcbits.*", sym.SGCBITS)
 	)
 
-	var symgofuncrel *Symbol
+	var symgofuncrel *sym.Symbol
 	if !ctxt.DynlinkingGo() {
-		if UseRelro() {
-			symgofuncrel = groupSym("go.funcrel.*", SGOFUNCRELRO)
+		if ctxt.UseRelro() {
+			symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
 		} else {
 			symgofuncrel = symgofunc
 		}
 	}
 
 	symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
-	symitablink.Type = SITABLINK
+	symitablink.Type = sym.SITABLINK
 
 	symt = ctxt.Syms.Lookup("runtime.symtab", 0)
-	symt.Attr |= AttrLocal
-	symt.Type = SSYMTAB
+	symt.Attr |= sym.AttrLocal
+	symt.Type = sym.SSYMTAB
 	symt.Size = 0
-	symt.Attr |= AttrReachable
+	symt.Attr |= sym.AttrReachable
 
 	nitablinks := 0
 
@@ -466,53 +430,53 @@
 	// just defined above will be first.
 	// hide the specific symbols.
 	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || s.Attr.Special() || s.Type != SRODATA {
+		if !s.Attr.Reachable() || s.Attr.Special() || s.Type != sym.SRODATA {
 			continue
 		}
 
 		switch {
 		case strings.HasPrefix(s.Name, "type."):
 			if !ctxt.DynlinkingGo() {
-				s.Attr |= AttrNotInSymbolTable
+				s.Attr |= sym.AttrNotInSymbolTable
 			}
-			if UseRelro() {
-				s.Type = STYPERELRO
+			if ctxt.UseRelro() {
+				s.Type = sym.STYPERELRO
 				s.Outer = symtyperel
 			} else {
-				s.Type = STYPE
+				s.Type = sym.STYPE
 				s.Outer = symtype
 			}
 
-		case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro():
+		case strings.HasPrefix(s.Name, "go.importpath.") && ctxt.UseRelro():
 			// Keep go.importpath symbols in the same section as types and
 			// names, as they can be referred to by a section offset.
-			s.Type = STYPERELRO
+			s.Type = sym.STYPERELRO
 
 		case strings.HasPrefix(s.Name, "go.itablink."):
 			nitablinks++
-			s.Type = SITABLINK
-			s.Attr |= AttrNotInSymbolTable
+			s.Type = sym.SITABLINK
+			s.Attr |= sym.AttrNotInSymbolTable
 			s.Outer = symitablink
 
 		case strings.HasPrefix(s.Name, "go.string."):
-			s.Type = SGOSTRING
-			s.Attr |= AttrNotInSymbolTable
+			s.Type = sym.SGOSTRING
+			s.Attr |= sym.AttrNotInSymbolTable
 			s.Outer = symgostring
 
 		case strings.HasPrefix(s.Name, "runtime.gcbits."):
-			s.Type = SGCBITS
-			s.Attr |= AttrNotInSymbolTable
+			s.Type = sym.SGCBITS
+			s.Attr |= sym.AttrNotInSymbolTable
 			s.Outer = symgcbits
 
 		case strings.HasSuffix(s.Name, "·f"):
 			if !ctxt.DynlinkingGo() {
-				s.Attr |= AttrNotInSymbolTable
+				s.Attr |= sym.AttrNotInSymbolTable
 			}
-			if UseRelro() {
-				s.Type = SGOFUNCRELRO
+			if ctxt.UseRelro() {
+				s.Type = sym.SGOFUNCRELRO
 				s.Outer = symgofuncrel
 			} else {
-				s.Type = SGOFUNC
+				s.Type = sym.SGOFUNC
 				s.Outer = symgofunc
 			}
 
@@ -520,34 +484,34 @@
 			strings.HasPrefix(s.Name, "gclocals."),
 			strings.HasPrefix(s.Name, "gclocals·"),
 			strings.HasPrefix(s.Name, "inltree."):
-			s.Type = SGOFUNC
-			s.Attr |= AttrNotInSymbolTable
+			s.Type = sym.SGOFUNC
+			s.Attr |= sym.AttrNotInSymbolTable
 			s.Outer = symgofunc
 			s.Align = 4
 			liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
 		}
 	}
 
-	if Buildmode == BuildmodeShared {
+	if ctxt.BuildMode == BuildModeShared {
 		abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
-		abihashgostr.Attr |= AttrReachable
-		abihashgostr.Type = SRODATA
+		abihashgostr.Attr |= sym.AttrReachable
+		abihashgostr.Type = sym.SRODATA
 		hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-		Addaddr(ctxt, abihashgostr, hashsym)
-		adduint(ctxt, abihashgostr, uint64(hashsym.Size))
+		abihashgostr.AddAddr(ctxt.Arch, hashsym)
+		abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
 	}
-	if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
+	if ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
 		for _, l := range ctxt.Library {
 			s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
-			s.Attr |= AttrReachable
-			s.Type = SRODATA
-			s.Size = int64(len(l.hash))
-			s.P = []byte(l.hash)
+			s.Attr |= sym.AttrReachable
+			s.Type = sym.SRODATA
+			s.Size = int64(len(l.Hash))
+			s.P = []byte(l.Hash)
 			str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
-			str.Attr |= AttrReachable
-			str.Type = SRODATA
-			Addaddr(ctxt, str, s)
-			adduint(ctxt, str, uint64(len(l.hash)))
+			str.Attr |= sym.AttrReachable
+			str.Type = sym.SRODATA
+			str.AddAddr(ctxt.Arch, s)
+			str.AddUint(ctxt.Arch, uint64(len(l.Hash)))
 		}
 	}
 
@@ -559,99 +523,99 @@
 	// This code uses several global variables that are set by pcln.go:pclntab.
 	moduledata := ctxt.Moduledata
 	// The pclntab slice
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0))
-	adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
-	adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0))
+	moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
+	moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
 	// The ftab slice
-	Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
-	adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
-	adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
+	moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
+	moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
+	moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
 	// The filetab slice
-	Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
-	adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
-	adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
+	moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
+	moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
+	moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
 	// findfunctab
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.findfunctab", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.findfunctab", 0))
 	// minpc, maxpc
-	Addaddr(ctxt, moduledata, pclntabFirstFunc)
-	Addaddrplus(ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
+	moduledata.AddAddr(ctxt.Arch, pclntabFirstFunc)
+	moduledata.AddAddrPlus(ctxt.Arch, pclntabLastFunc, pclntabLastFunc.Size)
 	// pointers to specific parts of the module
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.text", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etext", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrdata", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.data", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.edata", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.bss", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.ebss", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrbss", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.end", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcdata", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcbss", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.types", 0))
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etypes", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.text", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etext", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrdata", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.data", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.edata", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.bss", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.ebss", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrbss", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.end", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcdata", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcbss", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.types", 0))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etypes", 0))
 
 	// text section information
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
-	adduint(ctxt, moduledata, uint64(nsections))
-	adduint(ctxt, moduledata, uint64(nsections))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
+	moduledata.AddUint(ctxt.Arch, uint64(nsections))
+	moduledata.AddUint(ctxt.Arch, uint64(nsections))
 
 	// The typelinks slice
 	typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
 	ntypelinks := uint64(typelinkSym.Size) / 4
-	Addaddr(ctxt, moduledata, typelinkSym)
-	adduint(ctxt, moduledata, ntypelinks)
-	adduint(ctxt, moduledata, ntypelinks)
+	moduledata.AddAddr(ctxt.Arch, typelinkSym)
+	moduledata.AddUint(ctxt.Arch, ntypelinks)
+	moduledata.AddUint(ctxt.Arch, ntypelinks)
 	// The itablinks slice
-	Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.itablink", 0))
-	adduint(ctxt, moduledata, uint64(nitablinks))
-	adduint(ctxt, moduledata, uint64(nitablinks))
+	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.itablink", 0))
+	moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
+	moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
 	// The ptab slice
 	if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
-		ptab.Attr |= AttrLocal
-		ptab.Type = SRODATA
+		ptab.Attr |= sym.AttrLocal
+		ptab.Type = sym.SRODATA
 
 		nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
-		Addaddr(ctxt, moduledata, ptab)
-		adduint(ctxt, moduledata, nentries)
-		adduint(ctxt, moduledata, nentries)
+		moduledata.AddAddr(ctxt.Arch, ptab)
+		moduledata.AddUint(ctxt.Arch, nentries)
+		moduledata.AddUint(ctxt.Arch, nentries)
 	} else {
-		adduint(ctxt, moduledata, 0)
-		adduint(ctxt, moduledata, 0)
-		adduint(ctxt, moduledata, 0)
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0)
 	}
-	if Buildmode == BuildmodePlugin {
-		addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
+	if ctxt.BuildMode == BuildModePlugin {
+		addgostring(ctxt, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
 
 		pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
-		pkghashes.Attr |= AttrReachable
-		pkghashes.Attr |= AttrLocal
-		pkghashes.Type = SRODATA
+		pkghashes.Attr |= sym.AttrReachable
+		pkghashes.Attr |= sym.AttrLocal
+		pkghashes.Type = sym.SRODATA
 
 		for i, l := range ctxt.Library {
 			// pkghashes[i].name
 			addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
 			// pkghashes[i].linktimehash
-			addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.hash))
+			addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), l.Hash)
 			// pkghashes[i].runtimehash
 			hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
-			Addaddr(ctxt, pkghashes, hash)
+			pkghashes.AddAddr(ctxt.Arch, hash)
 		}
-		Addaddr(ctxt, moduledata, pkghashes)
-		adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
-		adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
+		moduledata.AddAddr(ctxt.Arch, pkghashes)
+		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
+		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
 	} else {
-		adduint(ctxt, moduledata, 0) // pluginpath
-		adduint(ctxt, moduledata, 0)
-		adduint(ctxt, moduledata, 0) // pkghashes slice
-		adduint(ctxt, moduledata, 0)
-		adduint(ctxt, moduledata, 0)
+		moduledata.AddUint(ctxt.Arch, 0) // pluginpath
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0) // pkghashes slice
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0)
 	}
 	if len(ctxt.Shlibs) > 0 {
 		thismodulename := filepath.Base(*flagOutfile)
-		switch Buildmode {
-		case BuildmodeExe, BuildmodePIE:
+		switch ctxt.BuildMode {
+		case BuildModeExe, BuildModePIE:
 			// When linking an executable, outfile is just "a.out". Make
 			// it something slightly more comprehensible.
 			thismodulename = "the executable"
@@ -659,9 +623,9 @@
 		addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
 
 		modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
-		modulehashes.Attr |= AttrReachable
-		modulehashes.Attr |= AttrLocal
-		modulehashes.Type = SRODATA
+		modulehashes.Attr |= sym.AttrReachable
+		modulehashes.Attr |= sym.AttrLocal
+		modulehashes.Type = sym.SRODATA
 
 		for i, shlib := range ctxt.Shlibs {
 			// modulehashes[i].modulename
@@ -673,13 +637,26 @@
 
 			// modulehashes[i].runtimehash
 			abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
-			abihash.Attr |= AttrReachable
-			Addaddr(ctxt, modulehashes, abihash)
+			abihash.Attr |= sym.AttrReachable
+			modulehashes.AddAddr(ctxt.Arch, abihash)
 		}
 
-		Addaddr(ctxt, moduledata, modulehashes)
-		adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
-		adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
+		moduledata.AddAddr(ctxt.Arch, modulehashes)
+		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
+		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
+	} else {
+		moduledata.AddUint(ctxt.Arch, 0) // modulename
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0) // moduleshashes slice
+		moduledata.AddUint(ctxt.Arch, 0)
+		moduledata.AddUint(ctxt.Arch, 0)
+	}
+
+	hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
+	if hasmain {
+		moduledata.AddUint8(1)
+	} else {
+		moduledata.AddUint8(0)
 	}
 
 	// The rest of moduledata is zero initialized.
@@ -688,12 +665,12 @@
 	// compiler-provided size, so read it from the type data.
 	moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
 	moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype)
-	Symgrow(moduledata, moduledata.Size)
+	moduledata.Grow(moduledata.Size)
 
 	lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
-	if lastmoduledatap.Type != SDYNIMPORT {
-		lastmoduledatap.Type = SNOPTRDATA
+	if lastmoduledatap.Type != sym.SDYNIMPORT {
+		lastmoduledatap.Type = sym.SNOPTRDATA
 		lastmoduledatap.Size = 0 // overwrite existing value
-		Addaddr(ctxt, lastmoduledatap, moduledata)
+		lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
 	}
 }
diff --git a/src/cmd/link/internal/ld/typelink.go b/src/cmd/link/internal/ld/typelink.go
index a3badb3..6b5ab08 100644
--- a/src/cmd/link/internal/ld/typelink.go
+++ b/src/cmd/link/internal/ld/typelink.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/link/internal/sym"
 	"sort"
 )
 
@@ -13,7 +14,7 @@
 
 type typelinkSortKey struct {
 	TypeStr string
-	Type    *Symbol
+	Type    *sym.Symbol
 }
 
 func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
@@ -27,17 +28,17 @@
 	typelinks := byTypeStr{}
 	for _, s := range ctxt.Syms.Allsym {
 		if s.Attr.Reachable() && s.Attr.MakeTypelink() {
-			typelinks = append(typelinks, typelinkSortKey{decodetypeStr(s), s})
+			typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ctxt.Arch, s), s})
 		}
 	}
 	sort.Sort(typelinks)
 
 	tl := ctxt.Syms.Lookup("runtime.typelink", 0)
-	tl.Type = STYPELINK
-	tl.Attr |= AttrReachable | AttrLocal
+	tl.Type = sym.STYPELINK
+	tl.Attr |= sym.AttrReachable | sym.AttrLocal
 	tl.Size = int64(4 * len(typelinks))
 	tl.P = make([]byte, tl.Size)
-	tl.R = make([]Reloc, len(typelinks))
+	tl.R = make([]sym.Reloc, len(typelinks))
 	for i, s := range typelinks {
 		r := &tl.R[i]
 		r.Sym = s.Type
diff --git a/src/cmd/link/internal/ld/util.go b/src/cmd/link/internal/ld/util.go
index 4b72636..9b75dfa 100644
--- a/src/cmd/link/internal/ld/util.go
+++ b/src/cmd/link/internal/ld/util.go
@@ -5,7 +5,7 @@
 package ld
 
 import (
-	"bytes"
+	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
 	"os"
@@ -23,14 +23,6 @@
 	return time.Since(startTime).Seconds()
 }
 
-func cstring(x []byte) string {
-	i := bytes.IndexByte(x, '\x00')
-	if i >= 0 {
-		x = x[:i]
-	}
-	return string(x)
-}
-
 func tokenize(s string) []string {
 	var f []string
 	for {
@@ -92,10 +84,7 @@
 // Exitf logs an error message then calls Exit(2).
 func Exitf(format string, a ...interface{}) {
 	fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
-	if coutbuf.f != nil {
-		coutbuf.f.Close()
-		mayberemoveoutfile()
-	}
+	nerrors++
 	Exit(2)
 }
 
@@ -105,7 +94,7 @@
 //
 // Logging an error means that on exit cmd/link will delete any
 // output file and return a non-zero error code.
-func Errorf(s *Symbol, format string, args ...interface{}) {
+func Errorf(s *sym.Symbol, format string, args ...interface{}) {
 	if s != nil {
 		format = s.Name + ": " + format
 	}
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
new file mode 100644
index 0000000..b956648
--- /dev/null
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -0,0 +1,1202 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package loadelf implements an ELF file reader.
+package loadelf
+
+import (
+	"bytes"
+	"cmd/internal/bio"
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"cmd/link/internal/sym"
+	"debug/elf"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"sort"
+	"strings"
+)
+
+/*
+Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
+http://code.swtch.com/plan9port/src/tip/src/libmach/
+
+	Copyright © 2004 Russ Cox.
+	Portions Copyright © 2008-2010 Google Inc.
+	Portions Copyright © 2010 The Go Authors.
+
+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.
+*/
+const (
+	ElfClassNone = 0
+	ElfClass32   = 1
+	ElfClass64   = 2
+)
+
+const (
+	ElfDataNone = 0
+	ElfDataLsb  = 1
+	ElfDataMsb  = 2
+)
+
+const (
+	ElfTypeNone         = 0
+	ElfTypeRelocatable  = 1
+	ElfTypeExecutable   = 2
+	ElfTypeSharedObject = 3
+	ElfTypeCore         = 4
+)
+
+const (
+	ElfMachNone        = 0
+	ElfMach32100       = 1
+	ElfMachSparc       = 2
+	ElfMach386         = 3
+	ElfMach68000       = 4
+	ElfMach88000       = 5
+	ElfMach486         = 6
+	ElfMach860         = 7
+	ElfMachMips        = 8
+	ElfMachS370        = 9
+	ElfMachMipsLe      = 10
+	ElfMachParisc      = 15
+	ElfMachVpp500      = 17
+	ElfMachSparc32Plus = 18
+	ElfMach960         = 19
+	ElfMachPower       = 20
+	ElfMachPower64     = 21
+	ElfMachS390        = 22
+	ElfMachV800        = 36
+	ElfMachFr20        = 37
+	ElfMachRh32        = 38
+	ElfMachRce         = 39
+	ElfMachArm         = 40
+	ElfMachAlpha       = 41
+	ElfMachSH          = 42
+	ElfMachSparc9      = 43
+	ElfMachAmd64       = 62
+	ElfMachArm64       = 183
+)
+
+const (
+	ElfAbiNone     = 0
+	ElfAbiSystemV  = 0
+	ElfAbiHPUX     = 1
+	ElfAbiNetBSD   = 2
+	ElfAbiLinux    = 3
+	ElfAbiSolaris  = 6
+	ElfAbiAix      = 7
+	ElfAbiIrix     = 8
+	ElfAbiFreeBSD  = 9
+	ElfAbiTru64    = 10
+	ElfAbiModesto  = 11
+	ElfAbiOpenBSD  = 12
+	ElfAbiARM      = 97
+	ElfAbiEmbedded = 255
+)
+
+const (
+	ElfSectNone      = 0
+	ElfSectProgbits  = 1
+	ElfSectSymtab    = 2
+	ElfSectStrtab    = 3
+	ElfSectRela      = 4
+	ElfSectHash      = 5
+	ElfSectDynamic   = 6
+	ElfSectNote      = 7
+	ElfSectNobits    = 8
+	ElfSectRel       = 9
+	ElfSectShlib     = 10
+	ElfSectDynsym    = 11
+	ElfSectFlagWrite = 0x1
+	ElfSectFlagAlloc = 0x2
+	ElfSectFlagExec  = 0x4
+)
+
+const (
+	ElfSymBindLocal  = 0
+	ElfSymBindGlobal = 1
+	ElfSymBindWeak   = 2
+)
+
+const (
+	ElfSymTypeNone    = 0
+	ElfSymTypeObject  = 1
+	ElfSymTypeFunc    = 2
+	ElfSymTypeSection = 3
+	ElfSymTypeFile    = 4
+	ElfSymTypeCommon  = 5
+	ElfSymTypeTLS     = 6
+)
+
+const (
+	ElfSymShnNone   = 0
+	ElfSymShnAbs    = 0xFFF1
+	ElfSymShnCommon = 0xFFF2
+)
+
+const (
+	ElfProgNone      = 0
+	ElfProgLoad      = 1
+	ElfProgDynamic   = 2
+	ElfProgInterp    = 3
+	ElfProgNote      = 4
+	ElfProgShlib     = 5
+	ElfProgPhdr      = 6
+	ElfProgFlagExec  = 0x1
+	ElfProgFlagWrite = 0x2
+	ElfProgFlagRead  = 0x4
+)
+
+const (
+	ElfNotePrStatus     = 1
+	ElfNotePrFpreg      = 2
+	ElfNotePrPsinfo     = 3
+	ElfNotePrTaskstruct = 4
+	ElfNotePrAuxv       = 6
+	ElfNotePrXfpreg     = 0x46e62b7f
+)
+
+// TODO(crawshaw): de-duplicate with cmd/link/internal/ld/elf.go.
+const (
+	ELF64SYMSIZE = 24
+	ELF32SYMSIZE = 16
+
+	SHT_ARM_ATTRIBUTES = 0x70000003
+)
+
+type ElfHdrBytes struct {
+	Ident     [16]uint8
+	Type      [2]uint8
+	Machine   [2]uint8
+	Version   [4]uint8
+	Entry     [4]uint8
+	Phoff     [4]uint8
+	Shoff     [4]uint8
+	Flags     [4]uint8
+	Ehsize    [2]uint8
+	Phentsize [2]uint8
+	Phnum     [2]uint8
+	Shentsize [2]uint8
+	Shnum     [2]uint8
+	Shstrndx  [2]uint8
+}
+
+type ElfSectBytes struct {
+	Name    [4]uint8
+	Type    [4]uint8
+	Flags   [4]uint8
+	Addr    [4]uint8
+	Off     [4]uint8
+	Size    [4]uint8
+	Link    [4]uint8
+	Info    [4]uint8
+	Align   [4]uint8
+	Entsize [4]uint8
+}
+
+type ElfProgBytes struct {
+}
+
+type ElfSymBytes struct {
+	Name  [4]uint8
+	Value [4]uint8
+	Size  [4]uint8
+	Info  uint8
+	Other uint8
+	Shndx [2]uint8
+}
+
+type ElfHdrBytes64 struct {
+	Ident     [16]uint8
+	Type      [2]uint8
+	Machine   [2]uint8
+	Version   [4]uint8
+	Entry     [8]uint8
+	Phoff     [8]uint8
+	Shoff     [8]uint8
+	Flags     [4]uint8
+	Ehsize    [2]uint8
+	Phentsize [2]uint8
+	Phnum     [2]uint8
+	Shentsize [2]uint8
+	Shnum     [2]uint8
+	Shstrndx  [2]uint8
+}
+
+type ElfSectBytes64 struct {
+	Name    [4]uint8
+	Type    [4]uint8
+	Flags   [8]uint8
+	Addr    [8]uint8
+	Off     [8]uint8
+	Size    [8]uint8
+	Link    [4]uint8
+	Info    [4]uint8
+	Align   [8]uint8
+	Entsize [8]uint8
+}
+
+type ElfProgBytes64 struct {
+}
+
+type ElfSymBytes64 struct {
+	Name  [4]uint8
+	Info  uint8
+	Other uint8
+	Shndx [2]uint8
+	Value [8]uint8
+	Size  [8]uint8
+}
+
+type ElfSect struct {
+	name    string
+	nameoff uint32
+	type_   uint32
+	flags   uint64
+	addr    uint64
+	off     uint64
+	size    uint64
+	link    uint32
+	info    uint32
+	align   uint64
+	entsize uint64
+	base    []byte
+	sym     *sym.Symbol
+}
+
+type ElfObj struct {
+	f         *bio.Reader
+	base      int64 // offset in f where ELF begins
+	length    int64 // length of ELF
+	is64      int
+	name      string
+	e         binary.ByteOrder
+	sect      []ElfSect
+	nsect     uint
+	nsymtab   int
+	symtab    *ElfSect
+	symstr    *ElfSect
+	type_     uint32
+	machine   uint32
+	version   uint32
+	entry     uint64
+	phoff     uint64
+	shoff     uint64
+	flags     uint32
+	ehsize    uint32
+	phentsize uint32
+	phnum     uint32
+	shentsize uint32
+	shnum     uint32
+	shstrndx  uint32
+}
+
+type ElfSym struct {
+	name  string
+	value uint64
+	size  uint64
+	bind  uint8
+	type_ uint8
+	other uint8
+	shndx uint16
+	sym   *sym.Symbol
+}
+
+var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
+
+const (
+	TagFile               = 1
+	TagCPUName            = 4
+	TagCPURawName         = 5
+	TagCompatibility      = 32
+	TagNoDefaults         = 64
+	TagAlsoCompatibleWith = 65
+	TagABIVFPArgs         = 28
+)
+
+type elfAttribute struct {
+	tag  uint64
+	sval string
+	ival uint64
+}
+
+type elfAttributeList struct {
+	data []byte
+	err  error
+}
+
+func (a *elfAttributeList) string() string {
+	if a.err != nil {
+		return ""
+	}
+	nul := bytes.IndexByte(a.data, 0)
+	if nul < 0 {
+		a.err = io.EOF
+		return ""
+	}
+	s := string(a.data[:nul])
+	a.data = a.data[nul+1:]
+	return s
+}
+
+func (a *elfAttributeList) uleb128() uint64 {
+	if a.err != nil {
+		return 0
+	}
+	v, size := binary.Uvarint(a.data)
+	a.data = a.data[size:]
+	return v
+}
+
+// Read an elfAttribute from the list following the rules used on ARM systems.
+func (a *elfAttributeList) armAttr() elfAttribute {
+	attr := elfAttribute{tag: a.uleb128()}
+	switch {
+	case attr.tag == TagCompatibility:
+		attr.ival = a.uleb128()
+		attr.sval = a.string()
+
+	case attr.tag == 64: // Tag_nodefaults has no argument
+
+	case attr.tag == 65: // Tag_also_compatible_with
+		// Not really, but we don't actually care about this tag.
+		attr.sval = a.string()
+
+	// Tag with string argument
+	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
+		attr.sval = a.string()
+
+	default: // Tag with integer argument
+		attr.ival = a.uleb128()
+	}
+	return attr
+}
+
+func (a *elfAttributeList) done() bool {
+	if a.err != nil || len(a.data) == 0 {
+		return true
+	}
+	return false
+}
+
+// Look for the attribute that indicates the object uses the hard-float ABI (a
+// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
+// format used means that we have to parse all of the file-level attributes to
+// find the one we are looking for. This format is slightly documented in "ELF
+// for the ARM Architecture" but mostly this is derived from reading the source
+// to gold and readelf.
+func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
+	found = false
+	if data[0] != 'A' {
+		return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
+	}
+	data = data[1:]
+	for len(data) != 0 {
+		sectionlength := e.Uint32(data)
+		sectiondata := data[4:sectionlength]
+		data = data[sectionlength:]
+
+		nulIndex := bytes.IndexByte(sectiondata, 0)
+		if nulIndex < 0 {
+			return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
+		}
+		name := string(sectiondata[:nulIndex])
+		sectiondata = sectiondata[nulIndex+1:]
+
+		if name != "aeabi" {
+			continue
+		}
+		for len(sectiondata) != 0 {
+			subsectiontag, sz := binary.Uvarint(sectiondata)
+			subsectionsize := e.Uint32(sectiondata[sz:])
+			subsectiondata := sectiondata[sz+4 : subsectionsize]
+			sectiondata = sectiondata[subsectionsize:]
+
+			if subsectiontag != TagFile {
+				continue
+			}
+			attrList := elfAttributeList{data: subsectiondata}
+			for !attrList.done() {
+				attr := attrList.armAttr()
+				if attr.tag == TagABIVFPArgs && attr.ival == 1 {
+					found = true
+					ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
+				}
+			}
+			if attrList.err != nil {
+				return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
+			}
+		}
+	}
+	return found, ehdrFlags, nil
+}
+
+// Load loads the ELF file pn from f.
+// Symbols are written into syms, and a slice of the text symbols is returned.
+//
+// On ARM systems, Load will attempt to determine what ELF header flags to
+// emit by scanning the attributes in the ELF file being loaded. The
+// parameter initEhdrFlags contains the current header flags for the output
+// object, and the returnd ehdrFlags contains what this Load function computes.
+// TODO: find a better place for this logic.
+func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
+	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
+		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
+	}
+
+	localSymVersion := syms.IncVersion()
+	base := f.Offset()
+
+	var hdrbuf [64]uint8
+	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
+		return errorf("malformed elf file: %v", err)
+	}
+	hdr := new(ElfHdrBytes)
+	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
+	if string(hdr.Ident[:4]) != "\x7FELF" {
+		return errorf("malformed elf file, bad header")
+	}
+	var e binary.ByteOrder
+	switch hdr.Ident[5] {
+	case ElfDataLsb:
+		e = binary.LittleEndian
+
+	case ElfDataMsb:
+		e = binary.BigEndian
+
+	default:
+		return errorf("malformed elf file, unknown header")
+	}
+
+	// read header
+	elfobj := new(ElfObj)
+
+	elfobj.e = e
+	elfobj.f = f
+	elfobj.base = base
+	elfobj.length = length
+	elfobj.name = pn
+
+	is64 := 0
+	if hdr.Ident[4] == ElfClass64 {
+		is64 = 1
+		hdr := new(ElfHdrBytes64)
+		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
+		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
+		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
+		elfobj.version = e.Uint32(hdr.Version[:])
+		elfobj.phoff = e.Uint64(hdr.Phoff[:])
+		elfobj.shoff = e.Uint64(hdr.Shoff[:])
+		elfobj.flags = e.Uint32(hdr.Flags[:])
+		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
+		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
+		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
+		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
+		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
+		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
+	} else {
+		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
+		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
+		elfobj.version = e.Uint32(hdr.Version[:])
+		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
+		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
+		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
+		elfobj.flags = e.Uint32(hdr.Flags[:])
+		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
+		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
+		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
+		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
+		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
+		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
+	}
+
+	elfobj.is64 = is64
+
+	if v := uint32(hdr.Ident[6]); v != elfobj.version {
+		return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
+	}
+
+	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
+		return errorf("elf but not elf relocatable object")
+	}
+
+	switch arch.Family {
+	default:
+		return errorf("elf %s unimplemented", arch.Name)
+
+	case sys.MIPS:
+		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
+			return errorf("elf object but not mips")
+		}
+
+	case sys.MIPS64:
+		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
+			return errorf("elf object but not mips64")
+		}
+
+	case sys.ARM:
+		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
+			return errorf("elf object but not arm")
+		}
+
+	case sys.AMD64:
+		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
+			return errorf("elf object but not amd64")
+		}
+
+	case sys.ARM64:
+		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
+			return errorf("elf object but not arm64")
+		}
+
+	case sys.I386:
+		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
+			return errorf("elf object but not 386")
+		}
+
+	case sys.PPC64:
+		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
+			return errorf("elf object but not ppc64")
+		}
+
+	case sys.S390X:
+		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
+			return errorf("elf object but not s390x")
+		}
+	}
+
+	// load section list into memory.
+	elfobj.sect = make([]ElfSect, elfobj.shnum)
+
+	elfobj.nsect = uint(elfobj.shnum)
+	for i := 0; uint(i) < elfobj.nsect; i++ {
+		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
+			return errorf("malformed elf file: negative seek")
+		}
+		sect := &elfobj.sect[i]
+		if is64 != 0 {
+			var b ElfSectBytes64
+
+			if err := binary.Read(f, e, &b); err != nil {
+				return errorf("malformed elf file: %v", err)
+			}
+
+			sect.nameoff = e.Uint32(b.Name[:])
+			sect.type_ = e.Uint32(b.Type[:])
+			sect.flags = e.Uint64(b.Flags[:])
+			sect.addr = e.Uint64(b.Addr[:])
+			sect.off = e.Uint64(b.Off[:])
+			sect.size = e.Uint64(b.Size[:])
+			sect.link = e.Uint32(b.Link[:])
+			sect.info = e.Uint32(b.Info[:])
+			sect.align = e.Uint64(b.Align[:])
+			sect.entsize = e.Uint64(b.Entsize[:])
+		} else {
+			var b ElfSectBytes
+
+			if err := binary.Read(f, e, &b); err != nil {
+				return errorf("malformed elf file: %v", err)
+			}
+
+			sect.nameoff = e.Uint32(b.Name[:])
+			sect.type_ = e.Uint32(b.Type[:])
+			sect.flags = uint64(e.Uint32(b.Flags[:]))
+			sect.addr = uint64(e.Uint32(b.Addr[:]))
+			sect.off = uint64(e.Uint32(b.Off[:]))
+			sect.size = uint64(e.Uint32(b.Size[:]))
+			sect.link = e.Uint32(b.Link[:])
+			sect.info = e.Uint32(b.Info[:])
+			sect.align = uint64(e.Uint32(b.Align[:]))
+			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
+		}
+	}
+
+	// read section string table and translate names
+	if elfobj.shstrndx >= uint32(elfobj.nsect) {
+		return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
+	}
+
+	sect := &elfobj.sect[elfobj.shstrndx]
+	if err := elfmap(elfobj, sect); err != nil {
+		return errorf("malformed elf file: %v", err)
+	}
+	for i := 0; uint(i) < elfobj.nsect; i++ {
+		if elfobj.sect[i].nameoff != 0 {
+			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
+		}
+	}
+
+	// load string table for symbols into memory.
+	elfobj.symtab = section(elfobj, ".symtab")
+
+	if elfobj.symtab == nil {
+		// our work is done here - no symbols means nothing can refer to this file
+		return
+	}
+
+	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
+		return errorf("elf object has symbol table with invalid string table link")
+	}
+
+	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
+	if is64 != 0 {
+		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
+	} else {
+		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
+	}
+
+	if err := elfmap(elfobj, elfobj.symtab); err != nil {
+		return errorf("malformed elf file: %v", err)
+	}
+	if err := elfmap(elfobj, elfobj.symstr); err != nil {
+		return errorf("malformed elf file: %v", err)
+	}
+
+	// load text and data segments into memory.
+	// they are not as small as the section lists, but we'll need
+	// the memory anyway for the symbol images, so we might
+	// as well use one large chunk.
+
+	// create symbols for elfmapped sections
+	for i := 0; uint(i) < elfobj.nsect; i++ {
+		sect = &elfobj.sect[i]
+		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
+			if err := elfmap(elfobj, sect); err != nil {
+				return errorf("%s: malformed elf file: %v", pn, err)
+			}
+			// We assume the soft-float ABI unless we see a tag indicating otherwise.
+			if initEhdrFlags == 0x5000002 {
+				ehdrFlags = 0x5000202
+			} else {
+				ehdrFlags = initEhdrFlags
+			}
+			found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
+			if err != nil {
+				// TODO(dfc) should this return an error?
+				log.Printf("%s: %v", pn, err)
+			}
+			if found {
+				ehdrFlags = newEhdrFlags
+			}
+		}
+		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
+			continue
+		}
+		if sect.type_ != ElfSectNobits {
+			if err := elfmap(elfobj, sect); err != nil {
+				return errorf("%s: malformed elf file: %v", pn, err)
+			}
+		}
+
+		name := fmt.Sprintf("%s(%s)", pkg, sect.name)
+		s := syms.Lookup(name, localSymVersion)
+
+		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
+		default:
+			return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
+
+		case ElfSectFlagAlloc:
+			s.Type = sym.SRODATA
+
+		case ElfSectFlagAlloc + ElfSectFlagWrite:
+			if sect.type_ == ElfSectNobits {
+				s.Type = sym.SNOPTRBSS
+			} else {
+				s.Type = sym.SNOPTRDATA
+			}
+
+		case ElfSectFlagAlloc + ElfSectFlagExec:
+			s.Type = sym.STEXT
+		}
+
+		if sect.name == ".got" || sect.name == ".toc" {
+			s.Type = sym.SELFGOT
+		}
+		if sect.type_ == ElfSectProgbits {
+			s.P = sect.base
+			s.P = s.P[:sect.size]
+		}
+
+		s.Size = int64(sect.size)
+		s.Align = int32(sect.align)
+		sect.sym = s
+	}
+
+	// enter sub-symbols into symbol table.
+	// symbol 0 is the null symbol.
+	symbols := make([]*sym.Symbol, elfobj.nsymtab)
+
+	for i := 1; i < elfobj.nsymtab; i++ {
+		var elfsym ElfSym
+		if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
+			return errorf("%s: malformed elf file: %v", pn, err)
+		}
+		symbols[i] = elfsym.sym
+		if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
+			continue
+		}
+		if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
+			s := elfsym.sym
+			if uint64(s.Size) < elfsym.size {
+				s.Size = int64(elfsym.size)
+			}
+			if s.Type == 0 || s.Type == sym.SXREF {
+				s.Type = sym.SNOPTRBSS
+			}
+			continue
+		}
+
+		if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
+			continue
+		}
+
+		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
+		if elfsym.sym == nil {
+			continue
+		}
+		sect = &elfobj.sect[elfsym.shndx]
+		if sect.sym == nil {
+			if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this
+				continue
+			}
+
+			if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
+				// This reportedly happens with clang 3.7 on ARM.
+				// See issue 13139.
+				continue
+			}
+
+			if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
+				continue
+			}
+			return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_)
+		}
+
+		s := elfsym.sym
+		if s.Outer != nil {
+			if s.Attr.DuplicateOK() {
+				continue
+			}
+			return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
+		}
+
+		s.Sub = sect.sym.Sub
+		sect.sym.Sub = s
+		s.Type = sect.sym.Type
+		s.Attr |= sym.AttrSubSymbol
+		if !s.Attr.CgoExportDynamic() {
+			s.Dynimplib = "" // satisfy dynimport
+		}
+		s.Value = int64(elfsym.value)
+		s.Size = int64(elfsym.size)
+		s.Outer = sect.sym
+		if sect.sym.Type == sym.STEXT {
+			if s.Attr.External() && !s.Attr.DuplicateOK() {
+				return errorf("%v: duplicate symbol definition", s)
+			}
+			s.Attr |= sym.AttrExternal
+		}
+
+		if elfobj.machine == ElfMachPower64 {
+			flag := int(elfsym.other) >> 5
+			if 2 <= flag && flag <= 6 {
+				s.Localentry = 1 << uint(flag-2)
+			} else if flag == 7 {
+				return errorf("%v: invalid sym.other 0x%x", s, elfsym.other)
+			}
+		}
+	}
+
+	// Sort outer lists by address, adding to textp.
+	// This keeps textp in increasing address order.
+	for i := uint(0); i < elfobj.nsect; i++ {
+		s := elfobj.sect[i].sym
+		if s == nil {
+			continue
+		}
+		if s.Sub != nil {
+			s.Sub = sym.SortSub(s.Sub)
+		}
+		if s.Type == sym.STEXT {
+			if s.Attr.OnList() {
+				return errorf("symbol %s listed multiple times", s.Name)
+			}
+			s.Attr |= sym.AttrOnList
+			textp = append(textp, s)
+			for s = s.Sub; s != nil; s = s.Sub {
+				if s.Attr.OnList() {
+					return errorf("symbol %s listed multiple times", s.Name)
+				}
+				s.Attr |= sym.AttrOnList
+				textp = append(textp, s)
+			}
+		}
+	}
+
+	// load relocations
+	for i := uint(0); i < elfobj.nsect; i++ {
+		rsect := &elfobj.sect[i]
+		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
+			continue
+		}
+		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
+			continue
+		}
+		sect = &elfobj.sect[rsect.info]
+		if err := elfmap(elfobj, rsect); err != nil {
+			return errorf("malformed elf file: %v", err)
+		}
+		rela := 0
+		if rsect.type_ == ElfSectRela {
+			rela = 1
+		}
+		n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
+		r := make([]sym.Reloc, n)
+		p := rsect.base
+		for j := 0; j < n; j++ {
+			var add uint64
+			rp := &r[j]
+			var info uint64
+			if is64 != 0 {
+				// 64-bit rel/rela
+				rp.Off = int32(e.Uint64(p))
+
+				p = p[8:]
+				info = e.Uint64(p)
+				p = p[8:]
+				if rela != 0 {
+					add = e.Uint64(p)
+					p = p[8:]
+				}
+			} else {
+				// 32-bit rel/rela
+				rp.Off = int32(e.Uint32(p))
+
+				p = p[4:]
+				info = uint64(e.Uint32(p))
+				info = info>>8<<32 | info&0xff // convert to 64-bit info
+				p = p[4:]
+				if rela != 0 {
+					add = uint64(e.Uint32(p))
+					p = p[4:]
+				}
+			}
+
+			if info&0xffffffff == 0 { // skip R_*_NONE relocation
+				j--
+				n--
+				continue
+			}
+
+			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
+				rp.Sym = nil
+			} else {
+				var elfsym ElfSym
+				if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
+					return errorf("malformed elf file: %v", err)
+				}
+				elfsym.sym = symbols[info>>32]
+				if elfsym.sym == nil {
+					return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_)
+				}
+
+				rp.Sym = elfsym.sym
+			}
+
+			rp.Type = 256 + objabi.RelocType(info)
+			rp.Siz, err = relSize(arch, pn, uint32(info))
+			if err != nil {
+				return nil, 0, err
+			}
+			if rela != 0 {
+				rp.Add = int64(add)
+			} else {
+				// load addend from image
+				if rp.Siz == 4 {
+					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
+				} else if rp.Siz == 8 {
+					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
+				} else {
+					return errorf("invalid rela size %d", rp.Siz)
+				}
+			}
+
+			if rp.Siz == 2 {
+				rp.Add = int64(int16(rp.Add))
+			}
+			if rp.Siz == 4 {
+				rp.Add = int64(int32(rp.Add))
+			}
+		}
+
+		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
+		sort.Sort(sym.RelocByOff(r[:n]))
+		// just in case
+
+		s := sect.sym
+		s.R = r
+		s.R = s.R[:n]
+	}
+
+	return textp, ehdrFlags, nil
+}
+
+func section(elfobj *ElfObj, name string) *ElfSect {
+	for i := 0; uint(i) < elfobj.nsect; i++ {
+		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
+			return &elfobj.sect[i]
+		}
+	}
+	return nil
+}
+
+func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
+	if sect.base != nil {
+		return nil
+	}
+
+	if sect.off+sect.size > uint64(elfobj.length) {
+		err = fmt.Errorf("elf section past end of file")
+		return err
+	}
+
+	sect.base = make([]byte, sect.size)
+	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
+		return fmt.Errorf("short read: seek not successful")
+	}
+	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
+		return fmt.Errorf("short read: %v", err)
+	}
+
+	return nil
+}
+
+func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
+	if i >= elfobj.nsymtab || i < 0 {
+		err = fmt.Errorf("invalid elf symbol index")
+		return err
+	}
+
+	if i == 0 {
+		return fmt.Errorf("readym: read null symbol!")
+	}
+
+	if elfobj.is64 != 0 {
+		b := new(ElfSymBytes64)
+		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
+		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
+		elfsym.value = elfobj.e.Uint64(b.Value[:])
+		elfsym.size = elfobj.e.Uint64(b.Size[:])
+		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
+		elfsym.bind = b.Info >> 4
+		elfsym.type_ = b.Info & 0xf
+		elfsym.other = b.Other
+	} else {
+		b := new(ElfSymBytes)
+		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
+		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
+		elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
+		elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
+		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
+		elfsym.bind = b.Info >> 4
+		elfsym.type_ = b.Info & 0xf
+		elfsym.other = b.Other
+	}
+
+	var s *sym.Symbol
+	if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
+		elfsym.name = ".got"
+	}
+	if elfsym.name == ".TOC." {
+		// Magic symbol on ppc64.  Will be set to this object
+		// file's .got+0x8000.
+		elfsym.bind = ElfSymBindLocal
+	}
+
+	switch elfsym.type_ {
+	case ElfSymTypeSection:
+		s = elfobj.sect[elfsym.shndx].sym
+
+	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
+		switch elfsym.bind {
+		case ElfSymBindGlobal:
+			if needSym != 0 {
+				s = syms.Lookup(elfsym.name, 0)
+
+				// for global scoped hidden symbols we should insert it into
+				// symbol hash table, but mark them as hidden.
+				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
+				// workaround that we set dupok.
+				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
+				// set dupok generally. See http://codereview.appspot.com/5823055/
+				// comment #5 for details.
+				if s != nil && elfsym.other == 2 {
+					s.Attr |= sym.AttrDuplicateOK | sym.AttrVisibilityHidden
+				}
+			}
+
+		case ElfSymBindLocal:
+			if arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) {
+				// binutils for arm generate these mapping
+				// symbols, ignore these
+				break
+			}
+
+			if elfsym.name == ".TOC." {
+				// We need to be able to look this up,
+				// so put it in the hash table.
+				if needSym != 0 {
+					s = syms.Lookup(elfsym.name, localSymVersion)
+					s.Attr |= sym.AttrVisibilityHidden
+				}
+
+				break
+			}
+
+			if needSym != 0 {
+				// local names and hidden global names are unique
+				// and should only be referenced by their index, not name, so we
+				// don't bother to add them into the hash table
+				s = syms.Newsym(elfsym.name, localSymVersion)
+
+				s.Attr |= sym.AttrVisibilityHidden
+			}
+
+		case ElfSymBindWeak:
+			if needSym != 0 {
+				s = syms.Lookup(elfsym.name, 0)
+				if elfsym.other == 2 {
+					s.Attr |= sym.AttrVisibilityHidden
+				}
+			}
+
+		default:
+			err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
+			return err
+		}
+	}
+
+	// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
+	// sense and should be removed when someone has thought about it properly.
+	if s != nil && s.Type == 0 && !s.Attr.VisibilityHidden() && elfsym.type_ != ElfSymTypeSection {
+		s.Type = sym.SXREF
+	}
+	elfsym.sym = s
+
+	return nil
+}
+
+func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
+	// TODO(mdempsky): Replace this with a struct-valued switch statement
+	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
+	// performance.
+
+	const (
+		AMD64 = uint32(sys.AMD64)
+		ARM   = uint32(sys.ARM)
+		I386  = uint32(sys.I386)
+		PPC64 = uint32(sys.PPC64)
+		S390X = uint32(sys.S390X)
+	)
+
+	switch uint32(arch.Family) | elftype<<24 {
+	default:
+		return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
+
+	case S390X | uint32(elf.R_390_8)<<24:
+		return 1, nil
+
+	case PPC64 | uint32(elf.R_PPC64_TOC16)<<24,
+		PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<24,
+		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<24,
+		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<24,
+		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<24,
+		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<24,
+		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<24,
+		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<24,
+		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<24,
+		S390X | uint32(elf.R_390_16)<<24,
+		S390X | uint32(elf.R_390_GOT16)<<24,
+		S390X | uint32(elf.R_390_PC16)<<24,
+		S390X | uint32(elf.R_390_PC16DBL)<<24,
+		S390X | uint32(elf.R_390_PLT16DBL)<<24:
+		return 2, nil
+
+	case ARM | uint32(elf.R_ARM_ABS32)<<24,
+		ARM | uint32(elf.R_ARM_GOT32)<<24,
+		ARM | uint32(elf.R_ARM_PLT32)<<24,
+		ARM | uint32(elf.R_ARM_GOTOFF)<<24,
+		ARM | uint32(elf.R_ARM_GOTPC)<<24,
+		ARM | uint32(elf.R_ARM_THM_PC22)<<24,
+		ARM | uint32(elf.R_ARM_REL32)<<24,
+		ARM | uint32(elf.R_ARM_CALL)<<24,
+		ARM | uint32(elf.R_ARM_V4BX)<<24,
+		ARM | uint32(elf.R_ARM_GOT_PREL)<<24,
+		ARM | uint32(elf.R_ARM_PC24)<<24,
+		ARM | uint32(elf.R_ARM_JUMP24)<<24,
+		AMD64 | uint32(elf.R_X86_64_PC32)<<24,
+		AMD64 | uint32(elf.R_X86_64_PLT32)<<24,
+		AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<24,
+		AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<24,
+		AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<24,
+		I386 | uint32(elf.R_386_32)<<24,
+		I386 | uint32(elf.R_386_PC32)<<24,
+		I386 | uint32(elf.R_386_GOT32)<<24,
+		I386 | uint32(elf.R_386_PLT32)<<24,
+		I386 | uint32(elf.R_386_GOTOFF)<<24,
+		I386 | uint32(elf.R_386_GOTPC)<<24,
+		I386 | uint32(elf.R_386_GOT32X)<<24,
+		PPC64 | uint32(elf.R_PPC64_REL24)<<24,
+		PPC64 | uint32(elf.R_PPC_REL32)<<24,
+		S390X | uint32(elf.R_390_32)<<24,
+		S390X | uint32(elf.R_390_PC32)<<24,
+		S390X | uint32(elf.R_390_GOT32)<<24,
+		S390X | uint32(elf.R_390_PLT32)<<24,
+		S390X | uint32(elf.R_390_PC32DBL)<<24,
+		S390X | uint32(elf.R_390_PLT32DBL)<<24,
+		S390X | uint32(elf.R_390_GOTPCDBL)<<24,
+		S390X | uint32(elf.R_390_GOTENT)<<24:
+		return 4, nil
+
+	case AMD64 | uint32(elf.R_X86_64_64)<<24,
+		AMD64 | uint32(elf.R_X86_64_PC64)<<24,
+		PPC64 | uint32(elf.R_PPC64_ADDR64)<<24,
+		S390X | uint32(elf.R_390_GLOB_DAT)<<24,
+		S390X | uint32(elf.R_390_RELATIVE)<<24,
+		S390X | uint32(elf.R_390_GOTOFF)<<24,
+		S390X | uint32(elf.R_390_GOTPC)<<24,
+		S390X | uint32(elf.R_390_64)<<24,
+		S390X | uint32(elf.R_390_PC64)<<24,
+		S390X | uint32(elf.R_390_GOT64)<<24,
+		S390X | uint32(elf.R_390_PLT64)<<24:
+		return 8, nil
+	}
+}
+
+func cstring(x []byte) string {
+	i := bytes.IndexByte(x, '\x00')
+	if i >= 0 {
+		x = x[:i]
+	}
+	return string(x)
+}
diff --git a/src/cmd/link/internal/loadmacho/ldmacho.go b/src/cmd/link/internal/loadmacho/ldmacho.go
new file mode 100644
index 0000000..e6b0f70
--- /dev/null
+++ b/src/cmd/link/internal/loadmacho/ldmacho.go
@@ -0,0 +1,879 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package loadmacho implements a Mach-O file reader.
+package loadmacho
+
+import (
+	"bytes"
+	"cmd/internal/bio"
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"cmd/link/internal/sym"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"sort"
+)
+
+/*
+Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
+http://code.swtch.com/plan9port/src/tip/src/libmach/
+
+	Copyright © 2004 Russ Cox.
+	Portions Copyright © 2008-2010 Google Inc.
+	Portions Copyright © 2010 The Go Authors.
+
+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.
+*/
+const (
+	N_EXT  = 0x01
+	N_TYPE = 0x1e
+	N_STAB = 0xe0
+)
+
+// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld
+const (
+	MACHO_X86_64_RELOC_UNSIGNED = 0
+	MACHO_X86_64_RELOC_SIGNED   = 1
+	MACHO_FAKE_GOTPCREL         = 100
+)
+
+type ldMachoObj struct {
+	f          *bio.Reader
+	base       int64 // off in f where Mach-O begins
+	length     int64 // length of Mach-O
+	is64       bool
+	name       string
+	e          binary.ByteOrder
+	cputype    uint
+	subcputype uint
+	filetype   uint32
+	flags      uint32
+	cmd        []ldMachoCmd
+	ncmd       uint
+}
+
+type ldMachoCmd struct {
+	type_ int
+	off   uint32
+	size  uint32
+	seg   ldMachoSeg
+	sym   ldMachoSymtab
+	dsym  ldMachoDysymtab
+}
+
+type ldMachoSeg struct {
+	name     string
+	vmaddr   uint64
+	vmsize   uint64
+	fileoff  uint32
+	filesz   uint32
+	maxprot  uint32
+	initprot uint32
+	nsect    uint32
+	flags    uint32
+	sect     []ldMachoSect
+}
+
+type ldMachoSect struct {
+	name    string
+	segname string
+	addr    uint64
+	size    uint64
+	off     uint32
+	align   uint32
+	reloff  uint32
+	nreloc  uint32
+	flags   uint32
+	res1    uint32
+	res2    uint32
+	sym     *sym.Symbol
+	rel     []ldMachoRel
+}
+
+type ldMachoRel struct {
+	addr      uint32
+	symnum    uint32
+	pcrel     uint8
+	length    uint8
+	extrn     uint8
+	type_     uint8
+	scattered uint8
+	value     uint32
+}
+
+type ldMachoSymtab struct {
+	symoff  uint32
+	nsym    uint32
+	stroff  uint32
+	strsize uint32
+	str     []byte
+	sym     []ldMachoSym
+}
+
+type ldMachoSym struct {
+	name    string
+	type_   uint8
+	sectnum uint8
+	desc    uint16
+	kind    int8
+	value   uint64
+	sym     *sym.Symbol
+}
+
+type ldMachoDysymtab struct {
+	ilocalsym      uint32
+	nlocalsym      uint32
+	iextdefsym     uint32
+	nextdefsym     uint32
+	iundefsym      uint32
+	nundefsym      uint32
+	tocoff         uint32
+	ntoc           uint32
+	modtaboff      uint32
+	nmodtab        uint32
+	extrefsymoff   uint32
+	nextrefsyms    uint32
+	indirectsymoff uint32
+	nindirectsyms  uint32
+	extreloff      uint32
+	nextrel        uint32
+	locreloff      uint32
+	nlocrel        uint32
+	indir          []uint32
+}
+
+const (
+	LdMachoCpuVax         = 1
+	LdMachoCpu68000       = 6
+	LdMachoCpu386         = 7
+	LdMachoCpuAmd64       = 0x1000007
+	LdMachoCpuMips        = 8
+	LdMachoCpu98000       = 10
+	LdMachoCpuHppa        = 11
+	LdMachoCpuArm         = 12
+	LdMachoCpu88000       = 13
+	LdMachoCpuSparc       = 14
+	LdMachoCpu860         = 15
+	LdMachoCpuAlpha       = 16
+	LdMachoCpuPower       = 18
+	LdMachoCmdSegment     = 1
+	LdMachoCmdSymtab      = 2
+	LdMachoCmdSymseg      = 3
+	LdMachoCmdThread      = 4
+	LdMachoCmdDysymtab    = 11
+	LdMachoCmdSegment64   = 25
+	LdMachoFileObject     = 1
+	LdMachoFileExecutable = 2
+	LdMachoFileFvmlib     = 3
+	LdMachoFileCore       = 4
+	LdMachoFilePreload    = 5
+)
+
+func unpackcmd(p []byte, m *ldMachoObj, c *ldMachoCmd, type_ uint, sz uint) int {
+	e4 := m.e.Uint32
+	e8 := m.e.Uint64
+
+	c.type_ = int(type_)
+	c.size = uint32(sz)
+	switch type_ {
+	default:
+		return -1
+
+	case LdMachoCmdSegment:
+		if sz < 56 {
+			return -1
+		}
+		c.seg.name = cstring(p[8:24])
+		c.seg.vmaddr = uint64(e4(p[24:]))
+		c.seg.vmsize = uint64(e4(p[28:]))
+		c.seg.fileoff = e4(p[32:])
+		c.seg.filesz = e4(p[36:])
+		c.seg.maxprot = e4(p[40:])
+		c.seg.initprot = e4(p[44:])
+		c.seg.nsect = e4(p[48:])
+		c.seg.flags = e4(p[52:])
+		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
+		if uint32(sz) < 56+c.seg.nsect*68 {
+			return -1
+		}
+		p = p[56:]
+		var s *ldMachoSect
+		for i := 0; uint32(i) < c.seg.nsect; i++ {
+			s = &c.seg.sect[i]
+			s.name = cstring(p[0:16])
+			s.segname = cstring(p[16:32])
+			s.addr = uint64(e4(p[32:]))
+			s.size = uint64(e4(p[36:]))
+			s.off = e4(p[40:])
+			s.align = e4(p[44:])
+			s.reloff = e4(p[48:])
+			s.nreloc = e4(p[52:])
+			s.flags = e4(p[56:])
+			s.res1 = e4(p[60:])
+			s.res2 = e4(p[64:])
+			p = p[68:]
+		}
+
+	case LdMachoCmdSegment64:
+		if sz < 72 {
+			return -1
+		}
+		c.seg.name = cstring(p[8:24])
+		c.seg.vmaddr = e8(p[24:])
+		c.seg.vmsize = e8(p[32:])
+		c.seg.fileoff = uint32(e8(p[40:]))
+		c.seg.filesz = uint32(e8(p[48:]))
+		c.seg.maxprot = e4(p[56:])
+		c.seg.initprot = e4(p[60:])
+		c.seg.nsect = e4(p[64:])
+		c.seg.flags = e4(p[68:])
+		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
+		if uint32(sz) < 72+c.seg.nsect*80 {
+			return -1
+		}
+		p = p[72:]
+		var s *ldMachoSect
+		for i := 0; uint32(i) < c.seg.nsect; i++ {
+			s = &c.seg.sect[i]
+			s.name = cstring(p[0:16])
+			s.segname = cstring(p[16:32])
+			s.addr = e8(p[32:])
+			s.size = e8(p[40:])
+			s.off = e4(p[48:])
+			s.align = e4(p[52:])
+			s.reloff = e4(p[56:])
+			s.nreloc = e4(p[60:])
+			s.flags = e4(p[64:])
+			s.res1 = e4(p[68:])
+			s.res2 = e4(p[72:])
+
+			// p+76 is reserved
+			p = p[80:]
+		}
+
+	case LdMachoCmdSymtab:
+		if sz < 24 {
+			return -1
+		}
+		c.sym.symoff = e4(p[8:])
+		c.sym.nsym = e4(p[12:])
+		c.sym.stroff = e4(p[16:])
+		c.sym.strsize = e4(p[20:])
+
+	case LdMachoCmdDysymtab:
+		if sz < 80 {
+			return -1
+		}
+		c.dsym.ilocalsym = e4(p[8:])
+		c.dsym.nlocalsym = e4(p[12:])
+		c.dsym.iextdefsym = e4(p[16:])
+		c.dsym.nextdefsym = e4(p[20:])
+		c.dsym.iundefsym = e4(p[24:])
+		c.dsym.nundefsym = e4(p[28:])
+		c.dsym.tocoff = e4(p[32:])
+		c.dsym.ntoc = e4(p[36:])
+		c.dsym.modtaboff = e4(p[40:])
+		c.dsym.nmodtab = e4(p[44:])
+		c.dsym.extrefsymoff = e4(p[48:])
+		c.dsym.nextrefsyms = e4(p[52:])
+		c.dsym.indirectsymoff = e4(p[56:])
+		c.dsym.nindirectsyms = e4(p[60:])
+		c.dsym.extreloff = e4(p[64:])
+		c.dsym.nextrel = e4(p[68:])
+		c.dsym.locreloff = e4(p[72:])
+		c.dsym.nlocrel = e4(p[76:])
+	}
+
+	return 0
+}
+
+func macholoadrel(m *ldMachoObj, sect *ldMachoSect) int {
+	if sect.rel != nil || sect.nreloc == 0 {
+		return 0
+	}
+	rel := make([]ldMachoRel, sect.nreloc)
+	n := int(sect.nreloc * 8)
+	buf := make([]byte, n)
+	if m.f.Seek(m.base+int64(sect.reloff), 0) < 0 {
+		return -1
+	}
+	if _, err := io.ReadFull(m.f, buf); err != nil {
+		return -1
+	}
+	for i := uint32(0); i < sect.nreloc; i++ {
+		r := &rel[i]
+		p := buf[i*8:]
+		r.addr = m.e.Uint32(p)
+
+		// TODO(rsc): Wrong interpretation for big-endian bitfields?
+		if r.addr&0x80000000 != 0 {
+			// scatterbrained relocation
+			r.scattered = 1
+
+			v := r.addr >> 24
+			r.addr &= 0xFFFFFF
+			r.type_ = uint8(v & 0xF)
+			v >>= 4
+			r.length = 1 << (v & 3)
+			v >>= 2
+			r.pcrel = uint8(v & 1)
+			r.value = m.e.Uint32(p[4:])
+		} else {
+			v := m.e.Uint32(p[4:])
+			r.symnum = v & 0xFFFFFF
+			v >>= 24
+			r.pcrel = uint8(v & 1)
+			v >>= 1
+			r.length = 1 << (v & 3)
+			v >>= 2
+			r.extrn = uint8(v & 1)
+			v >>= 1
+			r.type_ = uint8(v)
+		}
+	}
+
+	sect.rel = rel
+	return 0
+}
+
+func macholoaddsym(m *ldMachoObj, d *ldMachoDysymtab) int {
+	n := int(d.nindirectsyms)
+
+	p := make([]byte, n*4)
+	if m.f.Seek(m.base+int64(d.indirectsymoff), 0) < 0 {
+		return -1
+	}
+	if _, err := io.ReadFull(m.f, p); err != nil {
+		return -1
+	}
+
+	d.indir = make([]uint32, n)
+	for i := 0; i < n; i++ {
+		d.indir[i] = m.e.Uint32(p[4*i:])
+	}
+	return 0
+}
+
+func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
+	if symtab.sym != nil {
+		return 0
+	}
+
+	strbuf := make([]byte, symtab.strsize)
+	if m.f.Seek(m.base+int64(symtab.stroff), 0) < 0 {
+		return -1
+	}
+	if _, err := io.ReadFull(m.f, strbuf); err != nil {
+		return -1
+	}
+
+	symsize := 12
+	if m.is64 {
+		symsize = 16
+	}
+	n := int(symtab.nsym * uint32(symsize))
+	symbuf := make([]byte, n)
+	if m.f.Seek(m.base+int64(symtab.symoff), 0) < 0 {
+		return -1
+	}
+	if _, err := io.ReadFull(m.f, symbuf); err != nil {
+		return -1
+	}
+	sym := make([]ldMachoSym, symtab.nsym)
+	p := symbuf
+	for i := uint32(0); i < symtab.nsym; i++ {
+		s := &sym[i]
+		v := m.e.Uint32(p)
+		if v >= symtab.strsize {
+			return -1
+		}
+		s.name = cstring(strbuf[v:])
+		s.type_ = p[4]
+		s.sectnum = p[5]
+		s.desc = m.e.Uint16(p[6:])
+		if m.is64 {
+			s.value = m.e.Uint64(p[8:])
+		} else {
+			s.value = uint64(m.e.Uint32(p[8:]))
+		}
+		p = p[symsize:]
+	}
+
+	symtab.str = strbuf
+	symtab.sym = sym
+	return 0
+}
+
+// Load loads the Mach-O file pn from f.
+// Symbols are written into syms, and a slice of the text symbols is returned.
+func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
+	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
+		return nil, fmt.Errorf("loadmacho: %v: %v", pn, fmt.Sprintf(str, args...))
+	}
+
+	localSymVersion := syms.IncVersion()
+	base := f.Offset()
+
+	var hdr [7 * 4]uint8
+	if _, err := io.ReadFull(f, hdr[:]); err != nil {
+		return errorf("reading hdr: %v", err)
+	}
+
+	var e binary.ByteOrder
+	if binary.BigEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
+		e = binary.BigEndian
+	} else if binary.LittleEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
+		e = binary.LittleEndian
+	} else {
+		return errorf("bad magic - not mach-o file")
+	}
+
+	is64 := e.Uint32(hdr[:]) == 0xFEEDFACF
+	ncmd := e.Uint32(hdr[4*4:])
+	cmdsz := e.Uint32(hdr[5*4:])
+	if ncmd > 0x10000 || cmdsz >= 0x01000000 {
+		return errorf("implausible mach-o header ncmd=%d cmdsz=%d", ncmd, cmdsz)
+	}
+
+	if is64 {
+		f.Seek(4, 1) // skip reserved word in header
+	}
+
+	m := &ldMachoObj{
+		f:          f,
+		e:          e,
+		cputype:    uint(e.Uint32(hdr[1*4:])),
+		subcputype: uint(e.Uint32(hdr[2*4:])),
+		filetype:   e.Uint32(hdr[3*4:]),
+		ncmd:       uint(ncmd),
+		flags:      e.Uint32(hdr[6*4:]),
+		is64:       is64,
+		base:       base,
+		length:     length,
+		name:       pn,
+	}
+
+	switch arch.Family {
+	default:
+		return errorf("mach-o %s unimplemented", arch.Name)
+
+	case sys.AMD64:
+		if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 {
+			return errorf("mach-o object but not amd64")
+		}
+
+	case sys.I386:
+		if e != binary.LittleEndian || m.cputype != LdMachoCpu386 {
+			return errorf("mach-o object but not 386")
+		}
+	}
+
+	m.cmd = make([]ldMachoCmd, ncmd)
+	cmdp := make([]byte, cmdsz)
+	if _, err := io.ReadFull(f, cmdp); err != nil {
+		return errorf("reading cmds: %v", err)
+	}
+
+	// read and parse load commands
+	var c *ldMachoCmd
+
+	var symtab *ldMachoSymtab
+	var dsymtab *ldMachoDysymtab
+
+	off := uint32(len(hdr))
+	for i := uint32(0); i < ncmd; i++ {
+		ty := e.Uint32(cmdp)
+		sz := e.Uint32(cmdp[4:])
+		m.cmd[i].off = off
+		unpackcmd(cmdp, m, &m.cmd[i], uint(ty), uint(sz))
+		cmdp = cmdp[sz:]
+		off += sz
+		if ty == LdMachoCmdSymtab {
+			if symtab != nil {
+				return errorf("multiple symbol tables")
+			}
+
+			symtab = &m.cmd[i].sym
+			macholoadsym(m, symtab)
+		}
+
+		if ty == LdMachoCmdDysymtab {
+			dsymtab = &m.cmd[i].dsym
+			macholoaddsym(m, dsymtab)
+		}
+
+		if (is64 && ty == LdMachoCmdSegment64) || (!is64 && ty == LdMachoCmdSegment) {
+			if c != nil {
+				return errorf("multiple load commands")
+			}
+
+			c = &m.cmd[i]
+		}
+	}
+
+	// load text and data segments into memory.
+	// they are not as small as the load commands, but we'll need
+	// the memory anyway for the symbol images, so we might
+	// as well use one large chunk.
+	if c == nil {
+		return errorf("no load command")
+	}
+
+	if symtab == nil {
+		// our work is done here - no symbols means nothing can refer to this file
+		return
+	}
+
+	if int64(c.seg.fileoff+c.seg.filesz) >= length {
+		return errorf("load segment out of range")
+	}
+
+	if f.Seek(m.base+int64(c.seg.fileoff), 0) < 0 {
+		return errorf("cannot load object data: seek failed")
+	}
+	dat := make([]byte, c.seg.filesz)
+	if _, err := io.ReadFull(f, dat); err != nil {
+		return errorf("cannot load object data: %v", err)
+	}
+
+	for i := uint32(0); i < c.seg.nsect; i++ {
+		sect := &c.seg.sect[i]
+		if sect.segname != "__TEXT" && sect.segname != "__DATA" {
+			continue
+		}
+		if sect.name == "__eh_frame" {
+			continue
+		}
+		name := fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
+		s := syms.Lookup(name, localSymVersion)
+		if s.Type != 0 {
+			return errorf("duplicate %s/%s", sect.segname, sect.name)
+		}
+
+		if sect.flags&0xff == 1 { // S_ZEROFILL
+			s.P = make([]byte, sect.size)
+		} else {
+			s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
+		}
+		s.Size = int64(len(s.P))
+
+		if sect.segname == "__TEXT" {
+			if sect.name == "__text" {
+				s.Type = sym.STEXT
+			} else {
+				s.Type = sym.SRODATA
+			}
+		} else {
+			if sect.name == "__bss" {
+				s.Type = sym.SNOPTRBSS
+				s.P = s.P[:0]
+			} else {
+				s.Type = sym.SNOPTRDATA
+			}
+		}
+
+		sect.sym = s
+	}
+
+	// enter sub-symbols into symbol table.
+	// have to guess sizes from next symbol.
+	for i := uint32(0); i < symtab.nsym; i++ {
+		machsym := &symtab.sym[i]
+		if machsym.type_&N_STAB != 0 {
+			continue
+		}
+
+		// TODO: check sym->type against outer->type.
+		name := machsym.name
+
+		if name[0] == '_' && name[1] != '\x00' {
+			name = name[1:]
+		}
+		v := 0
+		if machsym.type_&N_EXT == 0 {
+			v = localSymVersion
+		}
+		s := syms.Lookup(name, v)
+		if machsym.type_&N_EXT == 0 {
+			s.Attr |= sym.AttrDuplicateOK
+		}
+		machsym.sym = s
+		if machsym.sectnum == 0 { // undefined
+			continue
+		}
+		if uint32(machsym.sectnum) > c.seg.nsect {
+			return errorf("reference to invalid section %d", machsym.sectnum)
+		}
+
+		sect := &c.seg.sect[machsym.sectnum-1]
+		outer := sect.sym
+		if outer == nil {
+			continue // ignore reference to invalid section
+		}
+
+		if s.Outer != nil {
+			if s.Attr.DuplicateOK() {
+				continue
+			}
+			return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
+		}
+
+		s.Type = outer.Type
+		s.Attr |= sym.AttrSubSymbol
+		s.Sub = outer.Sub
+		outer.Sub = s
+		s.Outer = outer
+		s.Value = int64(machsym.value - sect.addr)
+		if !s.Attr.CgoExportDynamic() {
+			s.Dynimplib = "" // satisfy dynimport
+		}
+		if outer.Type == sym.STEXT {
+			if s.Attr.External() && !s.Attr.DuplicateOK() {
+				return errorf("%v: duplicate symbol definition", s)
+			}
+			s.Attr |= sym.AttrExternal
+		}
+
+		machsym.sym = s
+	}
+
+	// Sort outer lists by address, adding to textp.
+	// This keeps textp in increasing address order.
+	for i := 0; uint32(i) < c.seg.nsect; i++ {
+		sect := &c.seg.sect[i]
+		s := sect.sym
+		if s == nil {
+			continue
+		}
+		if s.Sub != nil {
+			s.Sub = sym.SortSub(s.Sub)
+
+			// assign sizes, now that we know symbols in sorted order.
+			for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
+				if s1.Sub != nil {
+					s1.Size = s1.Sub.Value - s1.Value
+				} else {
+					s1.Size = s.Value + s.Size - s1.Value
+				}
+			}
+		}
+
+		if s.Type == sym.STEXT {
+			if s.Attr.OnList() {
+				return errorf("symbol %s listed multiple times", s.Name)
+			}
+			s.Attr |= sym.AttrOnList
+			textp = append(textp, s)
+			for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
+				if s1.Attr.OnList() {
+					return errorf("symbol %s listed multiple times", s1.Name)
+				}
+				s1.Attr |= sym.AttrOnList
+				textp = append(textp, s1)
+			}
+		}
+	}
+
+	// load relocations
+	for i := 0; uint32(i) < c.seg.nsect; i++ {
+		sect := &c.seg.sect[i]
+		s := sect.sym
+		if s == nil {
+			continue
+		}
+		macholoadrel(m, sect)
+		if sect.rel == nil {
+			continue
+		}
+		r := make([]sym.Reloc, sect.nreloc)
+		rpi := 0
+	Reloc:
+		for j := uint32(0); j < sect.nreloc; j++ {
+			rp := &r[rpi]
+			rel := &sect.rel[j]
+			if rel.scattered != 0 {
+				if arch.Family != sys.I386 {
+					// mach-o only uses scattered relocation on 32-bit platforms
+					return errorf("%v: unexpected scattered relocation", s)
+				}
+
+				// on 386, rewrite scattered 4/1 relocation and some
+				// scattered 2/1 relocation into the pseudo-pc-relative
+				// reference that it is.
+				// assume that the second in the pair is in this section
+				// and use that as the pc-relative base.
+				if j+1 >= sect.nreloc {
+					return errorf("unsupported scattered relocation %d", int(rel.type_))
+				}
+
+				if sect.rel[j+1].scattered == 0 || sect.rel[j+1].type_ != 1 || (rel.type_ != 4 && rel.type_ != 2) || uint64(sect.rel[j+1].value) < sect.addr || uint64(sect.rel[j+1].value) >= sect.addr+sect.size {
+					return errorf("unsupported scattered relocation %d/%d", int(rel.type_), int(sect.rel[j+1].type_))
+				}
+
+				rp.Siz = rel.length
+				rp.Off = int32(rel.addr)
+
+				// NOTE(rsc): I haven't worked out why (really when)
+				// we should ignore the addend on a
+				// scattered relocation, but it seems that the
+				// common case is we ignore it.
+				// It's likely that this is not strictly correct
+				// and that the math should look something
+				// like the non-scattered case below.
+				rp.Add = 0
+
+				// want to make it pc-relative aka relative to rp->off+4
+				// but the scatter asks for relative to off = sect->rel[j+1].value - sect->addr.
+				// adjust rp->add accordingly.
+				rp.Type = objabi.R_PCREL
+
+				rp.Add += int64(uint64(int64(rp.Off)+4) - (uint64(sect.rel[j+1].value) - sect.addr))
+
+				// now consider the desired symbol.
+				// find the section where it lives.
+				for k := 0; uint32(k) < c.seg.nsect; k++ {
+					ks := &c.seg.sect[k]
+					if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
+						if ks.sym != nil {
+							rp.Sym = ks.sym
+							rp.Add += int64(uint64(rel.value) - ks.addr)
+						} else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
+							// handle reference to __IMPORT/__pointers.
+							// how much worse can this get?
+							// why are we supporting 386 on the mac anyway?
+							rp.Type = 512 + MACHO_FAKE_GOTPCREL
+
+							// figure out which pointer this is a reference to.
+							k = int(uint64(ks.res1) + (uint64(rel.value)-ks.addr)/4)
+
+							// load indirect table for __pointers
+							// fetch symbol number
+							if dsymtab == nil || k < 0 || uint32(k) >= dsymtab.nindirectsyms || dsymtab.indir == nil {
+								return errorf("invalid scattered relocation: indirect symbol reference out of range")
+							}
+
+							k = int(dsymtab.indir[k])
+							if k < 0 || uint32(k) >= symtab.nsym {
+								return errorf("invalid scattered relocation: symbol reference out of range")
+							}
+
+							rp.Sym = symtab.sym[k].sym
+						} else {
+							return errorf("unsupported scattered relocation: reference to %s/%s", ks.segname, ks.name)
+						}
+
+						rpi++
+
+						// skip #1 of 2 rel; continue skips #2 of 2.
+						j++
+
+						continue Reloc
+					}
+				}
+
+				return errorf("unsupported scattered relocation: invalid address %#x", rel.addr)
+			}
+
+			rp.Siz = rel.length
+			rp.Type = 512 + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel)
+			rp.Off = int32(rel.addr)
+
+			// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
+			if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
+				// Calculate the addend as the offset into the section.
+				//
+				// The rip-relative offset stored in the object file is encoded
+				// as follows:
+				//
+				//    movsd	0x00000360(%rip),%xmm0
+				//
+				// To get the absolute address of the value this rip-relative address is pointing
+				// to, we must add the address of the next instruction to it. This is done by
+				// taking the address of the relocation and adding 4 to it (since the rip-relative
+				// offset can at most be 32 bits long).  To calculate the offset into the section the
+				// relocation is referencing, we subtract the vaddr of the start of the referenced
+				// section found in the original object file.
+				//
+				// [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
+				secaddr := c.seg.sect[rel.symnum-1].addr
+
+				rp.Add = int64(uint64(int64(int32(e.Uint32(s.P[rp.Off:])))+int64(rp.Off)+4) - secaddr)
+			} else {
+				rp.Add = int64(int32(e.Uint32(s.P[rp.Off:])))
+			}
+
+			// An unsigned internal relocation has a value offset
+			// by the section address.
+			if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_UNSIGNED {
+				secaddr := c.seg.sect[rel.symnum-1].addr
+				rp.Add -= int64(secaddr)
+			}
+
+			// For i386 Mach-O PC-relative, the addend is written such that
+			// it *is* the PC being subtracted. Use that to make
+			// it match our version of PC-relative.
+			if rel.pcrel != 0 && arch.Family == sys.I386 {
+				rp.Add += int64(rp.Off) + int64(rp.Siz)
+			}
+			if rel.extrn == 0 {
+				if rel.symnum < 1 || rel.symnum > c.seg.nsect {
+					return errorf("invalid relocation: section reference out of range %d vs %d", rel.symnum, c.seg.nsect)
+				}
+
+				rp.Sym = c.seg.sect[rel.symnum-1].sym
+				if rp.Sym == nil {
+					return errorf("invalid relocation: %s", c.seg.sect[rel.symnum-1].name)
+				}
+
+				// References to symbols in other sections
+				// include that information in the addend.
+				// We only care about the delta from the
+				// section base.
+				if arch.Family == sys.I386 {
+					rp.Add -= int64(c.seg.sect[rel.symnum-1].addr)
+				}
+			} else {
+				if rel.symnum >= symtab.nsym {
+					return errorf("invalid relocation: symbol reference out of range")
+				}
+
+				rp.Sym = symtab.sym[rel.symnum].sym
+			}
+
+			rpi++
+		}
+
+		sort.Sort(sym.RelocByOff(r[:rpi]))
+		s.R = r
+		s.R = s.R[:rpi]
+	}
+
+	return textp, nil
+}
+
+func cstring(x []byte) string {
+	i := bytes.IndexByte(x, '\x00')
+	if i >= 0 {
+		x = x[:i]
+	}
+	return string(x)
+}
diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
new file mode 100644
index 0000000..09c9e31
--- /dev/null
+++ b/src/cmd/link/internal/loadpe/ldpe.go
@@ -0,0 +1,449 @@
+// 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 loadpe implements a PE/COFF file reader.
+package loadpe
+
+import (
+	"cmd/internal/bio"
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"cmd/link/internal/sym"
+	"debug/pe"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"sort"
+	"strings"
+)
+
+const (
+	// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 (same with IMAGE_SYM_DTYPE_POINTER and IMAGE_SYM_DTYPE_FUNCTION)
+	IMAGE_SYM_UNDEFINED              = 0
+	IMAGE_SYM_ABSOLUTE               = -1
+	IMAGE_SYM_DEBUG                  = -2
+	IMAGE_SYM_TYPE_NULL              = 0
+	IMAGE_SYM_TYPE_VOID              = 1
+	IMAGE_SYM_TYPE_CHAR              = 2
+	IMAGE_SYM_TYPE_SHORT             = 3
+	IMAGE_SYM_TYPE_INT               = 4
+	IMAGE_SYM_TYPE_LONG              = 5
+	IMAGE_SYM_TYPE_FLOAT             = 6
+	IMAGE_SYM_TYPE_DOUBLE            = 7
+	IMAGE_SYM_TYPE_STRUCT            = 8
+	IMAGE_SYM_TYPE_UNION             = 9
+	IMAGE_SYM_TYPE_ENUM              = 10
+	IMAGE_SYM_TYPE_MOE               = 11
+	IMAGE_SYM_TYPE_BYTE              = 12
+	IMAGE_SYM_TYPE_WORD              = 13
+	IMAGE_SYM_TYPE_UINT              = 14
+	IMAGE_SYM_TYPE_DWORD             = 15
+	IMAGE_SYM_TYPE_PCODE             = 32768
+	IMAGE_SYM_DTYPE_NULL             = 0
+	IMAGE_SYM_DTYPE_POINTER          = 0x10
+	IMAGE_SYM_DTYPE_FUNCTION         = 0x20
+	IMAGE_SYM_DTYPE_ARRAY            = 0x30
+	IMAGE_SYM_CLASS_END_OF_FUNCTION  = -1
+	IMAGE_SYM_CLASS_NULL             = 0
+	IMAGE_SYM_CLASS_AUTOMATIC        = 1
+	IMAGE_SYM_CLASS_EXTERNAL         = 2
+	IMAGE_SYM_CLASS_STATIC           = 3
+	IMAGE_SYM_CLASS_REGISTER         = 4
+	IMAGE_SYM_CLASS_EXTERNAL_DEF     = 5
+	IMAGE_SYM_CLASS_LABEL            = 6
+	IMAGE_SYM_CLASS_UNDEFINED_LABEL  = 7
+	IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
+	IMAGE_SYM_CLASS_ARGUMENT         = 9
+	IMAGE_SYM_CLASS_STRUCT_TAG       = 10
+	IMAGE_SYM_CLASS_MEMBER_OF_UNION  = 11
+	IMAGE_SYM_CLASS_UNION_TAG        = 12
+	IMAGE_SYM_CLASS_TYPE_DEFINITION  = 13
+	IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
+	IMAGE_SYM_CLASS_ENUM_TAG         = 15
+	IMAGE_SYM_CLASS_MEMBER_OF_ENUM   = 16
+	IMAGE_SYM_CLASS_REGISTER_PARAM   = 17
+	IMAGE_SYM_CLASS_BIT_FIELD        = 18
+	IMAGE_SYM_CLASS_FAR_EXTERNAL     = 68 /* Not in PECOFF v8 spec */
+	IMAGE_SYM_CLASS_BLOCK            = 100
+	IMAGE_SYM_CLASS_FUNCTION         = 101
+	IMAGE_SYM_CLASS_END_OF_STRUCT    = 102
+	IMAGE_SYM_CLASS_FILE             = 103
+	IMAGE_SYM_CLASS_SECTION          = 104
+	IMAGE_SYM_CLASS_WEAK_EXTERNAL    = 105
+	IMAGE_SYM_CLASS_CLR_TOKEN        = 107
+	IMAGE_REL_I386_ABSOLUTE          = 0x0000
+	IMAGE_REL_I386_DIR16             = 0x0001
+	IMAGE_REL_I386_REL16             = 0x0002
+	IMAGE_REL_I386_DIR32             = 0x0006
+	IMAGE_REL_I386_DIR32NB           = 0x0007
+	IMAGE_REL_I386_SEG12             = 0x0009
+	IMAGE_REL_I386_SECTION           = 0x000A
+	IMAGE_REL_I386_SECREL            = 0x000B
+	IMAGE_REL_I386_TOKEN             = 0x000C
+	IMAGE_REL_I386_SECREL7           = 0x000D
+	IMAGE_REL_I386_REL32             = 0x0014
+	IMAGE_REL_AMD64_ABSOLUTE         = 0x0000
+	IMAGE_REL_AMD64_ADDR64           = 0x0001
+	IMAGE_REL_AMD64_ADDR32           = 0x0002
+	IMAGE_REL_AMD64_ADDR32NB         = 0x0003
+	IMAGE_REL_AMD64_REL32            = 0x0004
+	IMAGE_REL_AMD64_REL32_1          = 0x0005
+	IMAGE_REL_AMD64_REL32_2          = 0x0006
+	IMAGE_REL_AMD64_REL32_3          = 0x0007
+	IMAGE_REL_AMD64_REL32_4          = 0x0008
+	IMAGE_REL_AMD64_REL32_5          = 0x0009
+	IMAGE_REL_AMD64_SECTION          = 0x000A
+	IMAGE_REL_AMD64_SECREL           = 0x000B
+	IMAGE_REL_AMD64_SECREL7          = 0x000C
+	IMAGE_REL_AMD64_TOKEN            = 0x000D
+	IMAGE_REL_AMD64_SREL32           = 0x000E
+	IMAGE_REL_AMD64_PAIR             = 0x000F
+	IMAGE_REL_AMD64_SSPAN32          = 0x0010
+)
+
+// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld, ideally in debug/pe.
+const (
+	IMAGE_SCN_CNT_CODE               = 0x00000020
+	IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040
+	IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
+	IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000
+	IMAGE_SCN_MEM_EXECUTE            = 0x20000000
+	IMAGE_SCN_MEM_READ               = 0x40000000
+	IMAGE_SCN_MEM_WRITE              = 0x80000000
+)
+
+// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf
+
+// peBiobuf makes bio.Reader look like io.ReaderAt.
+type peBiobuf bio.Reader
+
+func (f *peBiobuf) ReadAt(p []byte, off int64) (int, error) {
+	ret := ((*bio.Reader)(f)).Seek(off, 0)
+	if ret < 0 {
+		return 0, errors.New("fail to seek")
+	}
+	n, err := f.Read(p)
+	if err != nil {
+		return 0, err
+	}
+	return n, nil
+}
+
+// Load loads the PE file pn from input.
+// Symbols are written into syms, and a slice of the text symbols is returned.
+// If an .rsrc section is found, its symbol is returned as rsrc.
+func Load(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {
+	localSymVersion := syms.IncVersion()
+
+	sectsyms := make(map[*pe.Section]*sym.Symbol)
+	sectdata := make(map[*pe.Section][]byte)
+
+	// Some input files are archives containing multiple of
+	// object files, and pe.NewFile seeks to the start of
+	// input file and get confused. Create section reader
+	// to stop pe.NewFile looking before current position.
+	sr := io.NewSectionReader((*peBiobuf)(input), input.Offset(), 1<<63-1)
+
+	// TODO: replace pe.NewFile with pe.Load (grep for "add Load function" in debug/pe for details)
+	f, err := pe.NewFile(sr)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer f.Close()
+
+	// TODO return error if found .cormeta
+
+	// create symbols for mapped sections
+	for _, sect := range f.Sections {
+		if sect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
+			continue
+		}
+
+		if sect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
+			// This has been seen for .idata sections, which we
+			// want to ignore. See issues 5106 and 5273.
+			continue
+		}
+
+		name := fmt.Sprintf("%s(%s)", pkg, sect.Name)
+		s := syms.Lookup(name, localSymVersion)
+
+		switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
+		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
+			s.Type = sym.SRODATA
+
+		case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
+			s.Type = sym.SNOPTRBSS
+
+		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
+			s.Type = sym.SNOPTRDATA
+
+		case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
+			s.Type = sym.STEXT
+
+		default:
+			return nil, nil, fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
+		}
+
+		if s.Type != sym.SNOPTRBSS {
+			data, err := sect.Data()
+			if err != nil {
+				return nil, nil, err
+			}
+			sectdata[sect] = data
+			s.P = data
+		}
+		s.Size = int64(sect.Size)
+		sectsyms[sect] = s
+		if sect.Name == ".rsrc" {
+			rsrc = s
+		}
+	}
+
+	// load relocations
+	for _, rsect := range f.Sections {
+		if _, found := sectsyms[rsect]; !found {
+			continue
+		}
+		if rsect.NumberOfRelocations == 0 {
+			continue
+		}
+		if rsect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
+			continue
+		}
+		if rsect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
+			// This has been seen for .idata sections, which we
+			// want to ignore. See issues 5106 and 5273.
+			continue
+		}
+
+		rs := make([]sym.Reloc, rsect.NumberOfRelocations)
+		for j, r := range rsect.Relocs {
+			rp := &rs[j]
+			if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
+				return nil, nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
+			}
+			pesym := &f.COFFSymbols[r.SymbolTableIndex]
+			gosym, err := readpesym(arch, syms, f, pesym, sectsyms, localSymVersion)
+			if err != nil {
+				return nil, nil, err
+			}
+			if gosym == nil {
+				name, err := pesym.FullName(f.StringTable)
+				if err != nil {
+					name = string(pesym.Name[:])
+				}
+				return nil, nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
+			}
+
+			rp.Sym = gosym
+			rp.Siz = 4
+			rp.Off = int32(r.VirtualAddress)
+			switch r.Type {
+			default:
+				return nil, nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, sectsyms[rsect], r.Type)
+
+			case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
+				IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
+				IMAGE_REL_AMD64_ADDR32NB:
+				rp.Type = objabi.R_PCREL
+
+				rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
+
+			case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
+				rp.Type = objabi.R_ADDR
+
+				// load addend from image
+				rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
+
+			case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
+				rp.Siz = 8
+
+				rp.Type = objabi.R_ADDR
+
+				// load addend from image
+				rp.Add = int64(binary.LittleEndian.Uint64(sectdata[rsect][rp.Off:]))
+			}
+
+			// ld -r could generate multiple section symbols for the
+			// same section but with different values, we have to take
+			// that into account
+			if issect(pesym) {
+				rp.Add += int64(pesym.Value)
+			}
+		}
+
+		sort.Sort(sym.RelocByOff(rs[:rsect.NumberOfRelocations]))
+
+		s := sectsyms[rsect]
+		s.R = rs
+		s.R = s.R[:rsect.NumberOfRelocations]
+	}
+
+	// enter sub-symbols into symbol table.
+	for i, numaux := 0, 0; i < len(f.COFFSymbols); i += numaux + 1 {
+		pesym := &f.COFFSymbols[i]
+
+		numaux = int(pesym.NumberOfAuxSymbols)
+
+		name, err := pesym.FullName(f.StringTable)
+		if err != nil {
+			return nil, nil, err
+		}
+		if name == "" {
+			continue
+		}
+		if issect(pesym) {
+			continue
+		}
+		if int(pesym.SectionNumber) > len(f.Sections) {
+			continue
+		}
+		if pesym.SectionNumber == IMAGE_SYM_DEBUG {
+			continue
+		}
+		var sect *pe.Section
+		if pesym.SectionNumber > 0 {
+			sect = f.Sections[pesym.SectionNumber-1]
+			if _, found := sectsyms[sect]; !found {
+				continue
+			}
+		}
+
+		s, err := readpesym(arch, syms, f, pesym, sectsyms, localSymVersion)
+		if err != nil {
+			return nil, nil, err
+		}
+
+		if pesym.SectionNumber == 0 { // extern
+			if s.Type == sym.SDYNIMPORT {
+				s.Plt = -2 // flag for dynimport in PE object files.
+			}
+			if s.Type == sym.SXREF && pesym.Value > 0 { // global data
+				s.Type = sym.SNOPTRDATA
+				s.Size = int64(pesym.Value)
+			}
+
+			continue
+		} else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {
+			sect = f.Sections[pesym.SectionNumber-1]
+			if _, found := sectsyms[sect]; !found {
+				return nil, nil, fmt.Errorf("%s: %v: missing sect.sym", pn, s)
+			}
+		} else {
+			return nil, nil, fmt.Errorf("%s: %v: sectnum < 0!", pn, s)
+		}
+
+		if sect == nil {
+			return nil, rsrc, nil
+		}
+
+		if s.Outer != nil {
+			if s.Attr.DuplicateOK() {
+				continue
+			}
+			return nil, nil, fmt.Errorf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sectsyms[sect].Name)
+		}
+
+		sectsym := sectsyms[sect]
+		s.Sub = sectsym.Sub
+		sectsym.Sub = s
+		s.Type = sectsym.Type
+		s.Attr |= sym.AttrSubSymbol
+		s.Value = int64(pesym.Value)
+		s.Size = 4
+		s.Outer = sectsym
+		if sectsym.Type == sym.STEXT {
+			if s.Attr.External() && !s.Attr.DuplicateOK() {
+				return nil, nil, fmt.Errorf("%s: duplicate symbol definition", s.Name)
+			}
+			s.Attr |= sym.AttrExternal
+		}
+	}
+
+	// Sort outer lists by address, adding to textp.
+	// This keeps textp in increasing address order.
+	for _, sect := range f.Sections {
+		s := sectsyms[sect]
+		if s == nil {
+			continue
+		}
+		if s.Sub != nil {
+			s.Sub = sym.SortSub(s.Sub)
+		}
+		if s.Type == sym.STEXT {
+			if s.Attr.OnList() {
+				return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)
+			}
+			s.Attr |= sym.AttrOnList
+			textp = append(textp, s)
+			for s = s.Sub; s != nil; s = s.Sub {
+				if s.Attr.OnList() {
+					return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)
+				}
+				s.Attr |= sym.AttrOnList
+				textp = append(textp, s)
+			}
+		}
+	}
+
+	return textp, rsrc, nil
+}
+
+func issect(s *pe.COFFSymbol) bool {
+	return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
+}
+
+func readpesym(arch *sys.Arch, syms *sym.Symbols, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {
+	symname, err := pesym.FullName(f.StringTable)
+	if err != nil {
+		return nil, err
+	}
+	var name string
+	if issect(pesym) {
+		name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name
+	} else {
+		name = symname
+		if strings.HasPrefix(name, "__imp_") {
+			name = name[6:] // __imp_Name => Name
+		}
+		if arch.Family == sys.I386 && name[0] == '_' {
+			name = name[1:] // _Name => Name
+		}
+	}
+
+	// remove last @XXX
+	if i := strings.LastIndex(name, "@"); i >= 0 {
+		name = name[:i]
+	}
+
+	var s *sym.Symbol
+	switch pesym.Type {
+	default:
+		return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
+
+	case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
+		switch pesym.StorageClass {
+		case IMAGE_SYM_CLASS_EXTERNAL: //global
+			s = syms.Lookup(name, 0)
+
+		case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
+			s = syms.Lookup(name, localSymVersion)
+			s.Attr |= sym.AttrDuplicateOK
+
+		default:
+			return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)
+		}
+	}
+
+	if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
+		s.Type = sym.SXREF
+	}
+	if strings.HasPrefix(symname, "__imp_") {
+		s.Got = -2 // flag for __imp_
+	}
+
+	return s, nil
+}
diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go
index 353f2c7..306d53f 100644
--- a/src/cmd/link/internal/mips/asm.go
+++ b/src/cmd/link/internal/mips/asm.go
@@ -32,7 +32,10 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"fmt"
 	"log"
 )
@@ -41,51 +44,46 @@
 	return
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	log.Fatalf("adddynrel not implemented")
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Lput(uint32(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		if r.Siz != 4 {
-			return -1
+			return false
 		}
-		ld.Thearch.Lput(ld.R_MIPS_32 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8)
 	case objabi.R_ADDRMIPS:
-		ld.Thearch.Lput(ld.R_MIPS_LO16 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_MIPS_LO16) | uint32(elfsym)<<8)
 	case objabi.R_ADDRMIPSU:
-		ld.Thearch.Lput(ld.R_MIPS_HI16 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_MIPS_HI16) | uint32(elfsym)<<8)
 	case objabi.R_ADDRMIPSTLS:
-		ld.Thearch.Lput(ld.R_MIPS_TLS_TPREL_LO16 | uint32(elfsym)<<8)
-
+		ctxt.Out.Write32(uint32(elf.R_MIPS_TLS_TPREL_LO16) | uint32(elfsym)<<8)
 	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-		ld.Thearch.Lput(ld.R_MIPS_26 | uint32(elfsym)<<8)
+		ctxt.Out.Write32(uint32(elf.R_MIPS_26) | uint32(elfsym)<<8)
 	}
 
-	return 0
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
 	return
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
-	return -1
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+	return false
 }
 
-func applyrel(r *ld.Reloc, s *ld.Symbol, val *int64, t int64) {
-	o := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
+func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64) {
+	o := arch.ByteOrder.Uint32(s.P[r.Off:])
 	switch r.Type {
 	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
 		*val = int64(o&0xffff0000 | uint32(t)&0xffff)
@@ -96,15 +94,13 @@
 	}
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
 		switch r.Type {
 		default:
-			return -1
-
+			return false
 		case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-
-			r.Done = 0
+			r.Done = false
 
 			// set up addend for eventual relocation via outer symbol.
 			rs := r.Sym
@@ -114,36 +110,32 @@
 				rs = rs.Outer
 			}
 
-			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 				ld.Errorf(s, "missing section for %s", rs.Name)
 			}
 			r.Xsym = rs
-			applyrel(r, s, val, r.Xadd)
-			return 0
-
+			applyrel(ctxt.Arch, r, s, val, r.Xadd)
+			return true
 		case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-			r.Done = 0
+			r.Done = false
 			r.Xsym = r.Sym
 			r.Xadd = r.Add
-			applyrel(r, s, val, r.Add)
-			return 0
+			applyrel(ctxt.Arch, r, s, val, r.Add)
+			return true
 		}
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
-
+		return true
 	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
 		t := ld.Symaddr(r.Sym) + r.Add
-		applyrel(r, s, val, t)
-		return 0
-
+		applyrel(ctxt.Arch, r, s, val, t)
+		return true
 	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
 		t := ld.Symaddr(r.Sym) + r.Add
 
@@ -156,23 +148,22 @@
 			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
 		}
 
-		applyrel(r, s, val, t)
-		return 0
-
+		applyrel(ctxt.Arch, r, s, val, t)
+		return true
 	case objabi.R_ADDRMIPSTLS:
 		// thread pointer is at 0x7000 offset from the start of TLS data area
 		t := ld.Symaddr(r.Sym) + r.Add - 0x7000
 		if t < -32768 || t >= 32678 {
 			ld.Errorf(s, "TLS offset out of range %d", t)
 		}
-		applyrel(r, s, val, t)
-		return 0
+		applyrel(ctxt.Arch, r, s, val, t)
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	return -1
 }
 
@@ -181,15 +172,15 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -198,7 +189,7 @@
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
 
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 
@@ -206,10 +197,10 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	/* output symbol table */
@@ -218,7 +209,7 @@
 	ld.Lcsize = 0
 	symo := uint32(0)
 	if !*ld.FlagS {
-		if !ld.Iself {
+		if !ctxt.IsELF {
 			ld.Errorf(nil, "unsupported executable format")
 		}
 		if ctxt.Debugvlog != 0 {
@@ -227,19 +218,19 @@
 		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 
-		ld.Cseek(int64(symo))
+		ctxt.Out.SeekSet(int64(symo))
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 		}
 		ld.Asmelfsym(ctxt)
-		ld.Cflush()
-		ld.Cwrite(ld.Elfstrdat)
+		ctxt.Out.Flush()
+		ctxt.Out.Write(ld.Elfstrdat)
 
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
 		}
 
-		if ld.Linkmode == ld.LinkExternal {
+		if ctxt.LinkMode == ld.LinkExternal {
 			ld.Elfemitreloc(ctxt)
 		}
 	}
@@ -248,15 +239,15 @@
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
 
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 		ld.Errorf(nil, "unsupported operating system")
 	case objabi.Hlinux:
 		ld.Asmbelf(ctxt, int64(symo))
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/mips/obj.go b/src/cmd/link/internal/mips/obj.go
index 3ba02b7..c5d3451 100644
--- a/src/cmd/link/internal/mips/obj.go
+++ b/src/cmd/link/internal/mips/obj.go
@@ -37,59 +37,45 @@
 	"fmt"
 )
 
-// Reading object files.
-
-func Init() {
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchMIPS
 	if objabi.GOARCH == "mipsle" {
-		ld.SysArch = sys.ArchMIPSLE
-	} else {
-		ld.SysArch = sys.ArchMIPS
+		arch = sys.ArchMIPSLE
 	}
 
-	ld.Thearch.Funcalign = FuncAlign
-	ld.Thearch.Maxalign = MaxAlign
-	ld.Thearch.Minalign = MinAlign
-	ld.Thearch.Dwarfregsp = DWARFREGSP
-	ld.Thearch.Dwarfreglr = DWARFREGLR
+	theArch := ld.Arch{
+		Funcalign:  FuncAlign,
+		Maxalign:   MaxAlign,
+		Minalign:   MinAlign,
+		Dwarfregsp: DWARFREGSP,
+		Dwarfreglr: DWARFREGLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	if ld.SysArch == sys.ArchMIPSLE {
-		ld.Thearch.Lput = ld.Lputl
-		ld.Thearch.Wput = ld.Wputl
-		ld.Thearch.Vput = ld.Vputl
-		ld.Thearch.Append16 = ld.Append16l
-		ld.Thearch.Append32 = ld.Append32l
-		ld.Thearch.Append64 = ld.Append64l
-	} else {
-		ld.Thearch.Lput = ld.Lputb
-		ld.Thearch.Wput = ld.Wputb
-		ld.Thearch.Vput = ld.Vputb
-		ld.Thearch.Append16 = ld.Append16b
-		ld.Thearch.Append32 = ld.Append32b
-		ld.Thearch.Append64 = ld.Append64b
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
+
+		Linuxdynld: "/lib/ld.so.1",
+
+		Freebsddynld:   "XXX",
+		Openbsddynld:   "XXX",
+		Netbsddynld:    "XXX",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
 	}
 
-	ld.Thearch.Linuxdynld = "/lib/ld.so.1"
-
-	ld.Thearch.Freebsddynld = "XXX"
-	ld.Thearch.Openbsddynld = "XXX"
-	ld.Thearch.Netbsddynld = "XXX"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 	case objabi.Hlinux: /* mips elf */
 		ld.Elfinit(ctxt)
 		ld.HEADR = ld.ELFRESERVE
diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go
index 3425681..295a0aa 100644
--- a/src/cmd/link/internal/mips64/asm.go
+++ b/src/cmd/link/internal/mips64/asm.go
@@ -34,18 +34,20 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"fmt"
 	"log"
 )
 
 func gentext(ctxt *ld.Link) {}
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	log.Fatalf("adddynrel not implemented")
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
 	// mips64 ELF relocation (endian neutral)
 	//		offset	uint64
 	//		sym		uint32
@@ -55,62 +57,56 @@
 	//		type	uint8
 	//		addend	int64
 
-	ld.Thearch.Vput(uint64(sectoff))
+	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
-	ld.Thearch.Lput(uint32(elfsym))
-	ld.Cput(0)
-	ld.Cput(0)
-	ld.Cput(0)
+	ctxt.Out.Write32(uint32(elfsym))
+	ctxt.Out.Write8(0)
+	ctxt.Out.Write8(0)
+	ctxt.Out.Write8(0)
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		switch r.Siz {
 		case 4:
-			ld.Cput(ld.R_MIPS_32)
+			ctxt.Out.Write8(uint8(elf.R_MIPS_32))
 		case 8:
-			ld.Cput(ld.R_MIPS_64)
+			ctxt.Out.Write8(uint8(elf.R_MIPS_64))
 		default:
-			return -1
+			return false
 		}
-
 	case objabi.R_ADDRMIPS:
-		ld.Cput(ld.R_MIPS_LO16)
-
+		ctxt.Out.Write8(uint8(elf.R_MIPS_LO16))
 	case objabi.R_ADDRMIPSU:
-		ld.Cput(ld.R_MIPS_HI16)
-
+		ctxt.Out.Write8(uint8(elf.R_MIPS_HI16))
 	case objabi.R_ADDRMIPSTLS:
-		ld.Cput(ld.R_MIPS_TLS_TPREL_LO16)
-
+		ctxt.Out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
 	case objabi.R_CALLMIPS,
 		objabi.R_JMPMIPS:
-		ld.Cput(ld.R_MIPS_26)
+		ctxt.Out.Write8(uint8(elf.R_MIPS_26))
 	}
-	ld.Thearch.Vput(uint64(r.Xadd))
+	ctxt.Out.Write64(uint64(r.Xadd))
 
-	return 0
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
 	return
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
-	return -1
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+	return false
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
 		switch r.Type {
 		default:
-			return -1
-
+			return false
 		case objabi.R_ADDRMIPS,
 			objabi.R_ADDRMIPSU:
-			r.Done = 0
+			r.Done = false
 
 			// set up addend for eventual relocation via outer symbol.
 			rs := r.Sym
@@ -120,66 +116,61 @@
 				rs = rs.Outer
 			}
 
-			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 				ld.Errorf(s, "missing section for %s", rs.Name)
 			}
 			r.Xsym = rs
 
-			return 0
-
+			return true
 		case objabi.R_ADDRMIPSTLS,
 			objabi.R_CALLMIPS,
 			objabi.R_JMPMIPS:
-			r.Done = 0
+			r.Done = false
 			r.Xsym = r.Sym
 			r.Xadd = r.Add
-			return 0
+			return true
 		}
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
-
+		return true
 	case objabi.R_ADDRMIPS,
 		objabi.R_ADDRMIPSU:
 		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
+		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
 		if r.Type == objabi.R_ADDRMIPS {
 			*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
 		} else {
 			*val = int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff)
 		}
-		return 0
-
+		return true
 	case objabi.R_ADDRMIPSTLS:
 		// thread pointer is at 0x7000 offset from the start of TLS data area
 		t := ld.Symaddr(r.Sym) + r.Add - 0x7000
 		if t < -32768 || t >= 32678 {
 			ld.Errorf(s, "TLS offset out of range %d", t)
 		}
-		o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
+		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
 		*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
-		return 0
-
+		return true
 	case objabi.R_CALLMIPS,
 		objabi.R_JMPMIPS:
 		// Low 26 bits = (S + A) >> 2
 		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
+		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
 		*val = int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000)
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	return -1
 }
 
@@ -188,15 +179,15 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -204,14 +195,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -219,10 +210,10 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	/* output symbol table */
@@ -235,9 +226,9 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 			}
@@ -246,34 +237,31 @@
 			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
 		}
 
-		ld.Cseek(int64(symo))
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(int64(symo))
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 				}
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 		}
 	}
@@ -281,22 +269,22 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan 9 */
 		magic := uint32(4*18*18 + 7)
-		if ld.SysArch == sys.ArchMIPS64LE {
+		if ctxt.Arch == sys.ArchMIPS64LE {
 			magic = uint32(4*26*26 + 7)
 		}
-		ld.Thearch.Lput(magic)                      /* magic */
-		ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Symsize))          /* nsyms */
-		ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ld.Thearch.Lput(0)
-		ld.Thearch.Lput(uint32(ld.Lcsize))
+		ctxt.Out.Write32(magic)                      /* magic */
+		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
+		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+		ctxt.Out.Write32(0)
+		ctxt.Out.Write32(uint32(ld.Lcsize))
 
 	case objabi.Hlinux,
 		objabi.Hfreebsd,
@@ -306,7 +294,7 @@
 		ld.Asmbelf(ctxt, int64(symo))
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go
index 1a24a7e..83974e5 100644
--- a/src/cmd/link/internal/mips64/obj.go
+++ b/src/cmd/link/internal/mips64/obj.go
@@ -37,57 +37,43 @@
 	"fmt"
 )
 
-func Init() {
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchMIPS64
 	if objabi.GOARCH == "mips64le" {
-		ld.SysArch = sys.ArchMIPS64LE
-	} else {
-		ld.SysArch = sys.ArchMIPS64
+		arch = sys.ArchMIPS64LE
 	}
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:        funcAlign,
+		Maxalign:         maxAlign,
+		Minalign:         minAlign,
+		Dwarfregsp:       dwarfRegSP,
+		Dwarfreglr:       dwarfRegLR,
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	if ld.SysArch == sys.ArchMIPS64LE {
-		ld.Thearch.Lput = ld.Lputl
-		ld.Thearch.Wput = ld.Wputl
-		ld.Thearch.Vput = ld.Vputl
-		ld.Thearch.Append16 = ld.Append16l
-		ld.Thearch.Append32 = ld.Append32l
-		ld.Thearch.Append64 = ld.Append64l
-	} else {
-		ld.Thearch.Lput = ld.Lputb
-		ld.Thearch.Wput = ld.Wputb
-		ld.Thearch.Vput = ld.Vputb
-		ld.Thearch.Append16 = ld.Append16b
-		ld.Thearch.Append32 = ld.Append32b
-		ld.Thearch.Append64 = ld.Append64b
+		Linuxdynld:     "/lib64/ld64.so.1",
+		Freebsddynld:   "XXX",
+		Openbsddynld:   "XXX",
+		Netbsddynld:    "XXX",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
 	}
 
-	ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
-
-	ld.Thearch.Freebsddynld = "XXX"
-	ld.Thearch.Openbsddynld = "XXX"
-	ld.Thearch.Netbsddynld = "XXX"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32
diff --git a/src/cmd/link/internal/objfile/objfile.go b/src/cmd/link/internal/objfile/objfile.go
new file mode 100644
index 0000000..67868be
--- /dev/null
+++ b/src/cmd/link/internal/objfile/objfile.go
@@ -0,0 +1,533 @@
+// 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 objfile reads Go object files for the Go linker, cmd/link.
+//
+// This package is similar to cmd/internal/objfile which also reads
+// Go object files.
+package objfile
+
+import (
+	"bufio"
+	"bytes"
+	"cmd/internal/bio"
+	"cmd/internal/dwarf"
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"cmd/link/internal/sym"
+	"io"
+	"log"
+	"strconv"
+	"strings"
+)
+
+const (
+	startmagic = "\x00\x00go19ld"
+	endmagic   = "\xff\xffgo19ld"
+)
+
+var emptyPkg = []byte(`"".`)
+
+// objReader reads Go object files.
+type objReader struct {
+	rd              *bufio.Reader
+	arch            *sys.Arch
+	syms            *sym.Symbols
+	lib             *sym.Library
+	pn              string
+	dupSym          *sym.Symbol
+	localSymVersion int
+
+	// rdBuf is used by readString and readSymName as scratch for reading strings.
+	rdBuf []byte
+
+	// List of symbol references for the file being read.
+	refs        []*sym.Symbol
+	data        []byte
+	reloc       []sym.Reloc
+	pcdata      []sym.Pcdata
+	autom       []sym.Auto
+	funcdata    []*sym.Symbol
+	funcdataoff []int64
+	file        []*sym.Symbol
+}
+
+// Load loads an object file f into library lib.
+// The symbols loaded are added to syms.
+func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, length int64, pn string) {
+	start := f.Offset()
+	r := &objReader{
+		rd:              f.Reader,
+		lib:             lib,
+		arch:            arch,
+		syms:            syms,
+		pn:              pn,
+		dupSym:          &sym.Symbol{Name: ".dup"},
+		localSymVersion: syms.IncVersion(),
+	}
+	r.loadObjFile()
+	if f.Offset() != start+length {
+		log.Fatalf("%s: unexpected end at %d, want %d", pn, f.Offset(), start+length)
+	}
+}
+
+func (r *objReader) loadObjFile() {
+	// Magic header
+	var buf [8]uint8
+	r.readFull(buf[:])
+	if string(buf[:]) != startmagic {
+		log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", r.pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])
+	}
+
+	// Version
+	c, err := r.rd.ReadByte()
+	if err != nil || c != 1 {
+		log.Fatalf("%s: invalid file version number %d", r.pn, c)
+	}
+
+	// Autolib
+	for {
+		lib := r.readString()
+		if lib == "" {
+			break
+		}
+		r.lib.ImportStrings = append(r.lib.ImportStrings, lib)
+	}
+
+	// Symbol references
+	r.refs = []*sym.Symbol{nil} // zeroth ref is nil
+	for {
+		c, err := r.rd.Peek(1)
+		if err != nil {
+			log.Fatalf("%s: peeking: %v", r.pn, err)
+		}
+		if c[0] == 0xff {
+			r.rd.ReadByte()
+			break
+		}
+		r.readRef()
+	}
+
+	// Lengths
+	r.readSlices()
+
+	// Data section
+	r.readFull(r.data)
+
+	// Defined symbols
+	for {
+		c, err := r.rd.Peek(1)
+		if err != nil {
+			log.Fatalf("%s: peeking: %v", r.pn, err)
+		}
+		if c[0] == 0xff {
+			break
+		}
+		r.readSym()
+	}
+
+	// Magic footer
+	buf = [8]uint8{}
+	r.readFull(buf[:])
+	if string(buf[:]) != endmagic {
+		log.Fatalf("%s: invalid file end", r.pn)
+	}
+}
+
+func (r *objReader) readSlices() {
+	n := r.readInt()
+	r.data = make([]byte, n)
+	n = r.readInt()
+	r.reloc = make([]sym.Reloc, n)
+	n = r.readInt()
+	r.pcdata = make([]sym.Pcdata, n)
+	n = r.readInt()
+	r.autom = make([]sym.Auto, n)
+	n = r.readInt()
+	r.funcdata = make([]*sym.Symbol, n)
+	r.funcdataoff = make([]int64, n)
+	n = r.readInt()
+	r.file = make([]*sym.Symbol, n)
+}
+
+// Symbols are prefixed so their content doesn't get confused with the magic footer.
+const symPrefix = 0xfe
+
+func (r *objReader) readSym() {
+	var c byte
+	var err error
+	if c, err = r.rd.ReadByte(); c != symPrefix || err != nil {
+		log.Fatalln("readSym out of sync")
+	}
+	if c, err = r.rd.ReadByte(); err != nil {
+		log.Fatalln("error reading input: ", err)
+	}
+	t := sym.AbiSymKindToSymKind[c]
+	s := r.readSymIndex()
+	flags := r.readInt()
+	dupok := flags&1 != 0
+	local := flags&2 != 0
+	makeTypelink := flags&4 != 0
+	size := r.readInt()
+	typ := r.readSymIndex()
+	data := r.readData()
+	nreloc := r.readInt()
+	pkg := objabi.PathToPrefix(r.lib.Pkg)
+	isdup := false
+
+	var dup *sym.Symbol
+	if s.Type != 0 && s.Type != sym.SXREF {
+		if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
+			if s.Size < int64(size) {
+				s.Size = int64(size)
+			}
+			if typ != nil && s.Gotype == nil {
+				s.Gotype = typ
+			}
+			return
+		}
+
+		if (s.Type == sym.SDATA || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
+			goto overwrite
+		}
+		if s.Type != sym.SBSS && s.Type != sym.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
+			log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn)
+		}
+		if len(s.P) > 0 {
+			dup = s
+			s = r.dupSym
+			isdup = true
+		}
+	}
+
+overwrite:
+	s.File = pkg
+	if dupok {
+		s.Attr |= sym.AttrDuplicateOK
+	}
+	if t == sym.SXREF {
+		log.Fatalf("bad sxref")
+	}
+	if t == 0 {
+		log.Fatalf("missing type for %s in %s", s.Name, r.pn)
+	}
+	if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
+		t = s.Type
+	}
+	s.Type = t
+	if s.Size < int64(size) {
+		s.Size = int64(size)
+	}
+	s.Attr.Set(sym.AttrLocal, local)
+	s.Attr.Set(sym.AttrMakeTypelink, makeTypelink)
+	if typ != nil {
+		s.Gotype = typ
+	}
+	if isdup && typ != nil { // if bss sym defined multiple times, take type from any one def
+		dup.Gotype = typ
+	}
+	s.P = data
+	if nreloc > 0 {
+		s.R = r.reloc[:nreloc:nreloc]
+		if !isdup {
+			r.reloc = r.reloc[nreloc:]
+		}
+
+		for i := 0; i < nreloc; i++ {
+			s.R[i] = sym.Reloc{
+				Off:  r.readInt32(),
+				Siz:  r.readUint8(),
+				Type: objabi.RelocType(r.readInt32()),
+				Add:  r.readInt64(),
+				Sym:  r.readSymIndex(),
+			}
+		}
+	}
+
+	if s.Type == sym.STEXT {
+		s.FuncInfo = new(sym.FuncInfo)
+		pc := s.FuncInfo
+
+		pc.Args = r.readInt32()
+		pc.Locals = r.readInt32()
+		if r.readUint8() != 0 {
+			s.Attr |= sym.AttrNoSplit
+		}
+		flags := r.readInt()
+		if flags&(1<<2) != 0 {
+			s.Attr |= sym.AttrReflectMethod
+		}
+		if flags&(1<<3) != 0 {
+			s.Attr |= sym.AttrShared
+		}
+		n := r.readInt()
+		pc.Autom = r.autom[:n:n]
+		if !isdup {
+			r.autom = r.autom[n:]
+		}
+
+		for i := 0; i < n; i++ {
+			pc.Autom[i] = sym.Auto{
+				Asym:    r.readSymIndex(),
+				Aoffset: r.readInt32(),
+				Name:    r.readInt16(),
+				Gotype:  r.readSymIndex(),
+			}
+		}
+
+		pc.Pcsp.P = r.readData()
+		pc.Pcfile.P = r.readData()
+		pc.Pcline.P = r.readData()
+		pc.Pcinline.P = r.readData()
+		n = r.readInt()
+		pc.Pcdata = r.pcdata[:n:n]
+		if !isdup {
+			r.pcdata = r.pcdata[n:]
+		}
+		for i := 0; i < n; i++ {
+			pc.Pcdata[i].P = r.readData()
+		}
+		n = r.readInt()
+		pc.Funcdata = r.funcdata[:n:n]
+		pc.Funcdataoff = r.funcdataoff[:n:n]
+		if !isdup {
+			r.funcdata = r.funcdata[n:]
+			r.funcdataoff = r.funcdataoff[n:]
+		}
+		for i := 0; i < n; i++ {
+			pc.Funcdata[i] = r.readSymIndex()
+		}
+		for i := 0; i < n; i++ {
+			pc.Funcdataoff[i] = r.readInt64()
+		}
+		n = r.readInt()
+		pc.File = r.file[:n:n]
+		if !isdup {
+			r.file = r.file[n:]
+		}
+		for i := 0; i < n; i++ {
+			pc.File[i] = r.readSymIndex()
+		}
+		n = r.readInt()
+		pc.InlTree = make([]sym.InlinedCall, n)
+		for i := 0; i < n; i++ {
+			pc.InlTree[i].Parent = r.readInt32()
+			pc.InlTree[i].File = r.readSymIndex()
+			pc.InlTree[i].Line = r.readInt32()
+			pc.InlTree[i].Func = r.readSymIndex()
+		}
+
+		s.Lib = r.lib
+		if !dupok {
+			if s.Attr.OnList() {
+				log.Fatalf("symbol %s listed multiple times", s.Name)
+			}
+			s.Attr |= sym.AttrOnList
+			r.lib.Textp = append(r.lib.Textp, s)
+		} else {
+			// there may ba a dup in another package
+			// put into a temp list and add to text later
+			if !isdup {
+				r.lib.DupTextSyms = append(r.lib.DupTextSyms, s)
+			} else {
+				r.lib.DupTextSyms = append(r.lib.DupTextSyms, dup)
+			}
+		}
+	}
+	if s.Type == sym.SDWARFINFO {
+		r.patchDWARFName(s)
+	}
+}
+
+func (r *objReader) patchDWARFName(s *sym.Symbol) {
+	// This is kind of ugly. Really the package name should not
+	// even be included here.
+	if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
+		return
+	}
+	e := bytes.IndexByte(s.P, 0)
+	if e == -1 {
+		return
+	}
+	p := bytes.Index(s.P[:e], emptyPkg)
+	if p == -1 {
+		return
+	}
+	pkgprefix := []byte(objabi.PathToPrefix(r.lib.Pkg) + ".")
+	patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1)
+
+	s.P = append(patched, s.P[e:]...)
+	delta := int64(len(s.P)) - s.Size
+	s.Size = int64(len(s.P))
+	for i := range s.R {
+		r := &s.R[i]
+		if r.Off > int32(e) {
+			r.Off += int32(delta)
+		}
+	}
+}
+
+func (r *objReader) readFull(b []byte) {
+	_, err := io.ReadFull(r.rd, b)
+	if err != nil {
+		log.Fatalf("%s: error reading %s", r.pn, err)
+	}
+}
+
+func (r *objReader) readRef() {
+	if c, err := r.rd.ReadByte(); c != symPrefix || err != nil {
+		log.Fatalf("readSym out of sync")
+	}
+	name := r.readSymName()
+	v := r.readInt()
+	if v != 0 && v != 1 {
+		log.Fatalf("invalid symbol version for %q: %d", name, v)
+	}
+	if v == 1 {
+		v = r.localSymVersion
+	}
+	s := r.syms.Lookup(name, v)
+	r.refs = append(r.refs, s)
+
+	if s == nil || v != 0 {
+		return
+	}
+	if s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 {
+		x, err := strconv.ParseUint(s.Name[5:], 16, 64)
+		if err != nil {
+			log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
+		}
+		s.Type = sym.SRODATA
+		s.Attr |= sym.AttrLocal
+		switch s.Name[:5] {
+		case "$f32.":
+			if uint64(uint32(x)) != x {
+				log.Panicf("$-symbol %s too large: %d", s.Name, x)
+			}
+			s.AddUint32(r.arch, uint32(x))
+		case "$f64.", "$i64.":
+			s.AddUint64(r.arch, x)
+		default:
+			log.Panicf("unrecognized $-symbol: %s", s.Name)
+		}
+		s.Attr.Set(sym.AttrReachable, false)
+	}
+	if strings.HasPrefix(s.Name, "runtime.gcbits.") {
+		s.Attr |= sym.AttrLocal
+	}
+}
+
+func (r *objReader) readInt64() int64 {
+	uv := uint64(0)
+	for shift := uint(0); ; shift += 7 {
+		if shift >= 64 {
+			log.Fatalf("corrupt input")
+		}
+		c, err := r.rd.ReadByte()
+		if err != nil {
+			log.Fatalln("error reading input: ", err)
+		}
+		uv |= uint64(c&0x7F) << shift
+		if c&0x80 == 0 {
+			break
+		}
+	}
+
+	return int64(uv>>1) ^ (int64(uv<<63) >> 63)
+}
+
+func (r *objReader) readInt() int {
+	n := r.readInt64()
+	if int64(int(n)) != n {
+		log.Panicf("%v out of range for int", n)
+	}
+	return int(n)
+}
+
+func (r *objReader) readInt32() int32 {
+	n := r.readInt64()
+	if int64(int32(n)) != n {
+		log.Panicf("%v out of range for int32", n)
+	}
+	return int32(n)
+}
+
+func (r *objReader) readInt16() int16 {
+	n := r.readInt64()
+	if int64(int16(n)) != n {
+		log.Panicf("%v out of range for int16", n)
+	}
+	return int16(n)
+}
+
+func (r *objReader) readUint8() uint8 {
+	n := r.readInt64()
+	if int64(uint8(n)) != n {
+		log.Panicf("%v out of range for uint8", n)
+	}
+	return uint8(n)
+}
+
+func (r *objReader) readString() string {
+	n := r.readInt()
+	if cap(r.rdBuf) < n {
+		r.rdBuf = make([]byte, 2*n)
+	}
+	r.readFull(r.rdBuf[:n])
+	return string(r.rdBuf[:n])
+}
+
+func (r *objReader) readData() []byte {
+	n := r.readInt()
+	p := r.data[:n:n]
+	r.data = r.data[n:]
+	return p
+}
+
+// readSymName reads a symbol name, replacing all "". with pkg.
+func (r *objReader) readSymName() string {
+	pkg := objabi.PathToPrefix(r.lib.Pkg)
+	n := r.readInt()
+	if n == 0 {
+		r.readInt64()
+		return ""
+	}
+	if cap(r.rdBuf) < n {
+		r.rdBuf = make([]byte, 2*n)
+	}
+	origName, err := r.rd.Peek(n)
+	if err == bufio.ErrBufferFull {
+		// Long symbol names are rare but exist. One source is type
+		// symbols for types with long string forms. See #15104.
+		origName = make([]byte, n)
+		r.readFull(origName)
+	} else if err != nil {
+		log.Fatalf("%s: error reading symbol: %v", r.pn, err)
+	}
+	adjName := r.rdBuf[:0]
+	for {
+		i := bytes.Index(origName, emptyPkg)
+		if i == -1 {
+			s := string(append(adjName, origName...))
+			// Read past the peeked origName, now that we're done with it,
+			// using the rfBuf (also no longer used) as the scratch space.
+			// TODO: use bufio.Reader.Discard if available instead?
+			if err == nil {
+				r.readFull(r.rdBuf[:n])
+			}
+			r.rdBuf = adjName[:0] // in case 2*n wasn't enough
+			return s
+		}
+		adjName = append(adjName, origName[:i]...)
+		adjName = append(adjName, pkg...)
+		adjName = append(adjName, '.')
+		origName = origName[i+len(emptyPkg):]
+	}
+}
+
+// Reads the index of a symbol reference and resolves it to a symbol
+func (r *objReader) readSymIndex() *sym.Symbol {
+	i := r.readInt()
+	return r.refs[i]
+}
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index ee4e218..4e277f9 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -32,7 +32,10 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"encoding/binary"
 	"fmt"
 	"log"
@@ -87,11 +90,11 @@
 	//
 	// This assumes "case 1" from the ABI, where the caller needs
 	// us to save and restore the TOC pointer.
-	var stubs []*ld.Symbol
+	var stubs []*sym.Symbol
 	for _, s := range ctxt.Textp {
 		for i := range s.R {
 			r := &s.R[i]
-			if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != ld.SDYNIMPORT {
+			if r.Type != 256+objabi.RelocType(elf.R_PPC64_REL24) || r.Sym.Type != sym.SDYNIMPORT {
 				continue
 			}
 
@@ -104,7 +107,7 @@
 
 			stub := ctxt.Syms.Lookup(n, 0)
 			if s.Attr.Reachable() {
-				stub.Attr |= ld.AttrReachable
+				stub.Attr |= sym.AttrReachable
 			}
 			if stub.Size == 0 {
 				// Need outer to resolve .TOC.
@@ -131,22 +134,23 @@
 
 func genaddmoduledata(ctxt *ld.Link) {
 	addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT {
+	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
 		return
 	}
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 	o := func(op uint32) {
-		ld.Adduint32(ctxt, initfunc, op)
+		initfunc.AddUint32(ctxt.Arch, op)
 	}
 	// addis r2, r12, .TOC.-func@ha
-	rel := ld.Addrel(initfunc)
+	rel := initfunc.AddRel()
 	rel.Off = int32(initfunc.Size)
 	rel.Siz = 8
 	rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
+	rel.Sym.Attr |= sym.AttrReachable
 	rel.Type = objabi.R_ADDRPOWER_PCREL
 	o(0x3c4c0000)
 	// addi r2, r2, .TOC.-func@l
@@ -156,16 +160,24 @@
 	// stdu r31, -32(r1)
 	o(0xf801ffe1)
 	// addis r3, r2, local.moduledata@got@ha
-	rel = ld.Addrel(initfunc)
+	rel = initfunc.AddRel()
 	rel.Off = int32(initfunc.Size)
 	rel.Siz = 8
-	rel.Sym = ctxt.Syms.Lookup("local.moduledata", 0)
+	if s := ctxt.Syms.ROLookup("local.moduledata", 0); s != nil {
+		rel.Sym = s
+	} else if s := ctxt.Syms.ROLookup("local.pluginmoduledata", 0); s != nil {
+		rel.Sym = s
+	} else {
+		rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
+	}
+	rel.Sym.Attr |= sym.AttrReachable
+	rel.Sym.Attr |= sym.AttrLocal
 	rel.Type = objabi.R_ADDRPOWER_GOT
 	o(0x3c620000)
 	// ld r3, local.moduledata@got@l(r3)
 	o(0xe8630000)
 	// bl runtime.addmoduledata
-	rel = ld.Addrel(initfunc)
+	rel = initfunc.AddRel()
 	rel.Off = int32(initfunc.Size)
 	rel.Siz = 4
 	rel.Sym = addmoduledata
@@ -182,12 +194,15 @@
 	// blr
 	o(0x4e800020)
 
+	if ctxt.BuildMode == ld.BuildModePlugin {
+		ctxt.Textp = append(ctxt.Textp, addmoduledata)
+	}
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
 	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
 func gentext(ctxt *ld.Link) {
@@ -195,14 +210,14 @@
 		genaddmoduledata(ctxt)
 	}
 
-	if ld.Linkmode == ld.LinkInternal {
+	if ctxt.LinkMode == ld.LinkInternal {
 		genplt(ctxt)
 	}
 }
 
 // Construct a call stub in stub that calls symbol targ via its PLT
 // entry.
-func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
+func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) {
 	if abicase != 1 {
 		// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
 		// relocations, we'll need to implement cases 2 and 3.
@@ -211,13 +226,13 @@
 
 	plt := ctxt.Syms.Lookup(".plt", 0)
 
-	stub.Type = ld.STEXT
+	stub.Type = sym.STEXT
 
 	// Save TOC pointer in TOC save slot
-	ld.Adduint32(ctxt, stub, 0xf8410018) // std r2,24(r1)
+	stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
 
 	// Load the function pointer from the PLT.
-	r := ld.Addrel(stub)
+	r := stub.AddRel()
 
 	r.Off = int32(stub.Size)
 	r.Sym = plt
@@ -227,9 +242,9 @@
 		r.Off += int32(r.Siz)
 	}
 	r.Type = objabi.R_POWER_TOC
-	r.Variant = ld.RV_POWER_HA
-	ld.Adduint32(ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
-	r = ld.Addrel(stub)
+	r.Variant = sym.RV_POWER_HA
+	stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
+	r = stub.AddRel()
 	r.Off = int32(stub.Size)
 	r.Sym = plt
 	r.Add = int64(targ.Plt)
@@ -238,26 +253,26 @@
 		r.Off += int32(r.Siz)
 	}
 	r.Type = objabi.R_POWER_TOC
-	r.Variant = ld.RV_POWER_LO
-	ld.Adduint32(ctxt, stub, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
+	r.Variant = sym.RV_POWER_LO
+	stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
 
 	// Jump to the loaded pointer
-	ld.Adduint32(ctxt, stub, 0x7d8903a6) // mtctr r12
-	ld.Adduint32(ctxt, stub, 0x4e800420) // bctr
+	stub.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
+	stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
 	switch r.Type {
 	default:
 		if r.Type >= 256 {
-			ld.Errorf(s, "unexpected relocation type %d", r.Type)
+			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			return false
 		}
 
 		// Handle relocations found in ELF object files.
-	case 256 + ld.R_PPC64_REL24:
+	case 256 + objabi.RelocType(elf.R_PPC64_REL24):
 		r.Type = objabi.R_CALLPOWER
 
 		// This is a local call, so the caller isn't setting
@@ -267,89 +282,89 @@
 		// to use r12 to compute r2.)
 		r.Add += int64(r.Sym.Localentry) * 4
 
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			// Should have been handled in elfsetupplt
 			ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
 		}
 
 		return true
 
-	case 256 + ld.R_PPC_REL32:
+	case 256 + objabi.RelocType(elf.R_PPC_REL32):
 		r.Type = objabi.R_PCREL
 		r.Add += 4
 
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
 		}
 
 		return true
 
-	case 256 + ld.R_PPC64_ADDR64:
+	case 256 + objabi.RelocType(elf.R_PPC64_ADDR64):
 		r.Type = objabi.R_ADDR
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			// These happen in .toc sections
 			ld.Adddynsym(ctxt, targ)
 
 			rela := ctxt.Syms.Lookup(".rela", 0)
-			ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
-			ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
-			ld.Adduint64(ctxt, rela, uint64(r.Add))
+			rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
+			rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
+			rela.AddUint64(ctxt.Arch, uint64(r.Add))
 			r.Type = 256 // ignore during relocsym
 		}
 
 		return true
 
-	case 256 + ld.R_PPC64_TOC16:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_LO | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
 		return true
 
-	case 256 + ld.R_PPC64_TOC16_LO:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16_LO):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_LO
+		r.Variant = sym.RV_POWER_LO
 		return true
 
-	case 256 + ld.R_PPC64_TOC16_HA:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16_HA):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
 		return true
 
-	case 256 + ld.R_PPC64_TOC16_HI:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16_HI):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
 		return true
 
-	case 256 + ld.R_PPC64_TOC16_DS:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16_DS):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_DS | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
 		return true
 
-	case 256 + ld.R_PPC64_TOC16_LO_DS:
+	case 256 + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
 		r.Type = objabi.R_POWER_TOC
-		r.Variant = ld.RV_POWER_DS
+		r.Variant = sym.RV_POWER_DS
 		return true
 
-	case 256 + ld.R_PPC64_REL16_LO:
+	case 256 + objabi.RelocType(elf.R_PPC64_REL16_LO):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_POWER_LO
+		r.Variant = sym.RV_POWER_LO
 		r.Add += 2 // Compensate for relocation size of 2
 		return true
 
-	case 256 + ld.R_PPC64_REL16_HI:
+	case 256 + objabi.RelocType(elf.R_PPC64_REL16_HI):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
 		r.Add += 2
 		return true
 
-	case 256 + ld.R_PPC64_REL16_HA:
+	case 256 + objabi.RelocType(elf.R_PPC64_REL16_HA):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
+		r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
 		r.Add += 2
 		return true
 	}
 
 	// Handle references to ELF symbols from our own object files.
-	if targ.Type != ld.SDYNIMPORT {
+	if targ.Type != sym.SDYNIMPORT {
 		return true
 	}
 
@@ -358,83 +373,72 @@
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Vput(uint64(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		switch r.Siz {
 		case 4:
-			ld.Thearch.Vput(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
 		case 8:
-			ld.Thearch.Vput(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR64) | uint64(elfsym)<<32)
 		default:
-			return -1
+			return false
 		}
-
 	case objabi.R_POWER_TLS:
-		ld.Thearch.Vput(ld.R_PPC64_TLS | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_LE:
-		ld.Thearch.Vput(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TPREL16) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_IE:
-		ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_LO_DS | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_LO_DS) | uint64(elfsym)<<32)
 	case objabi.R_ADDRPOWER:
-		ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO) | uint64(elfsym)<<32)
 	case objabi.R_ADDRPOWER_DS:
-		ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO_DS) | uint64(elfsym)<<32)
 	case objabi.R_ADDRPOWER_GOT:
-		ld.Thearch.Vput(ld.R_PPC64_GOT16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_GOT16_LO_DS | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_LO_DS) | uint64(elfsym)<<32)
 	case objabi.R_ADDRPOWER_PCREL:
-		ld.Thearch.Vput(ld.R_PPC64_REL16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_LO) | uint64(elfsym)<<32)
 		r.Xadd += 4
-
 	case objabi.R_ADDRPOWER_TOCREL:
-		ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO) | uint64(elfsym)<<32)
 	case objabi.R_ADDRPOWER_TOCREL_DS:
-		ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
-		ld.Thearch.Vput(uint64(r.Xadd))
-		ld.Thearch.Vput(uint64(sectoff + 4))
-		ld.Thearch.Vput(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32)
-
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(r.Xadd))
+		ctxt.Out.Write64(uint64(sectoff + 4))
+		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32)
 	case objabi.R_CALLPOWER:
 		if r.Siz != 4 {
-			return -1
+			return false
 		}
-		ld.Thearch.Vput(ld.R_PPC64_REL24 | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
 
 	}
-	ld.Thearch.Vput(uint64(r.Xadd))
+	ctxt.Out.Write64(uint64(r.Xadd))
 
-	return 0
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
@@ -448,13 +452,13 @@
 	}
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
-	return -1
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+	return false
 }
 
 // Return the value of .TOC. for symbol s
-func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
-	var toc *ld.Symbol
+func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
+	var toc *sym.Symbol
 
 	if s.Outer != nil {
 		toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
@@ -470,7 +474,7 @@
 	return toc.Value
 }
 
-func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
+func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
 	var o1, o2 uint32
 	if ctxt.Arch.ByteOrder == binary.BigEndian {
 		o1 = uint32(*val >> 32)
@@ -499,16 +503,14 @@
 	case objabi.R_ADDRPOWER:
 		o1 |= (uint32(t) >> 16) & 0xffff
 		o2 |= uint32(t) & 0xffff
-
 	case objabi.R_ADDRPOWER_DS:
 		o1 |= (uint32(t) >> 16) & 0xffff
 		if t&3 != 0 {
 			ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
 		}
 		o2 |= uint32(t) & 0xfffc
-
 	default:
-		return -1
+		return false
 	}
 
 	if ctxt.Arch.ByteOrder == binary.BigEndian {
@@ -516,17 +518,17 @@
 	} else {
 		*val = int64(o2)<<32 | int64(o1)
 	}
-	return 0
+	return true
 }
 
 // resolve direct jump relocation r in s, and add trampoline if necessary
-func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
+func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
 
 	// Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
 	// For internal linking, trampolines are always created for long calls.
 	// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
 	// r2.  For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
-	if ld.Linkmode == ld.LinkExternal && (ctxt.DynlinkingGo() || ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE) {
+	if ctxt.LinkMode == ld.LinkExternal && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
 		// No trampolines needed since r2 contains the TOC
 		return
 	}
@@ -537,8 +539,8 @@
 
 		// If branch offset is too far then create a trampoline.
 
-		if (ld.Linkmode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
-			var tramp *ld.Symbol
+		if (ctxt.LinkMode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
+			var tramp *sym.Symbol
 			for i := 0; ; i++ {
 
 				// Using r.Add as part of the name is significant in functions like duffzero where the call
@@ -563,29 +565,29 @@
 
 				// With internal linking, the trampoline can be used if it is not too far.
 				// With external linking, the trampoline must be in this section for it to be reused.
-				if (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ld.Linkmode == ld.LinkExternal && s.Sect == tramp.Sect) {
+				if (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ctxt.LinkMode == ld.LinkExternal && s.Sect == tramp.Sect) {
 					break
 				}
 			}
 			if tramp.Type == 0 {
-				if ctxt.DynlinkingGo() || ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE {
+				if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
 					// Should have returned for above cases
 					ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
 				} else {
 					ctxt.AddTramp(tramp)
-					gentramp(tramp, r.Sym, int64(r.Add))
+					gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(r.Add))
 				}
 			}
 			r.Sym = tramp
 			r.Add = 0 // This was folded into the trampoline target address
-			r.Done = 0
+			r.Done = false
 		}
 	default:
-		ld.Errorf(s, "trampoline called with non-jump reloc: %v", r.Type)
+		ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 	}
 }
 
-func gentramp(tramp, target *ld.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
 	// Used for default build mode for an executable
 	// Address of the call target is generated using
 	// relocation and doesn't depend on r2 (TOC).
@@ -596,8 +598,8 @@
 	o2 := uint32(0x3bff0000) // addi r31,targetaddr lo
 	// With external linking, the target address must be
 	// relocated using LO and HA
-	if ld.Linkmode == ld.LinkExternal {
-		tr := ld.Addrel(tramp)
+	if linkmode == ld.LinkExternal {
+		tr := tramp.AddRel()
 		tr.Off = 0
 		tr.Type = objabi.R_ADDRPOWER
 		tr.Siz = 8 // generates 2 relocations:  HA + LO
@@ -615,32 +617,30 @@
 	}
 	o3 := uint32(0x7fe903a6) // mtctr r31
 	o4 := uint32(0x4e800420) // bctr
-	ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
+	arch.ByteOrder.PutUint32(tramp.P, o1)
+	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
+	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
+	arch.ByteOrder.PutUint32(tramp.P[12:], o4)
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
 		switch r.Type {
 		default:
-			return -1
-
+			return false
 		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
-			r.Done = 0
+			r.Done = false
 			// check Outer is nil, Type is TLSBSS?
 			r.Xadd = r.Add
 			r.Xsym = r.Sym
-			return 0
-
+			return true
 		case objabi.R_ADDRPOWER,
 			objabi.R_ADDRPOWER_DS,
 			objabi.R_ADDRPOWER_TOCREL,
 			objabi.R_ADDRPOWER_TOCREL_DS,
 			objabi.R_ADDRPOWER_GOT,
 			objabi.R_ADDRPOWER_PCREL:
-			r.Done = 0
+			r.Done = false
 
 			// set up addend for eventual relocation via outer symbol.
 			rs := r.Sym
@@ -650,33 +650,29 @@
 				rs = rs.Outer
 			}
 
-			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
 				ld.Errorf(s, "missing section for %s", rs.Name)
 			}
 			r.Xsym = rs
 
-			return 0
-
+			return true
 		case objabi.R_CALLPOWER:
-			r.Done = 0
+			r.Done = false
 			r.Xsym = r.Sym
 			r.Xadd = r.Add
-			return 0
+			return true
 		}
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
-
+		return true
 	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
 		return archrelocaddr(ctxt, r, s, val)
-
 	case objabi.R_CALLPOWER:
 		// Bits 6 through 29 = (S + A - P) >> 2
 
@@ -691,13 +687,11 @@
 			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
 		}
 		*val |= int64(uint32(t) &^ 0xfc000003)
-		return 0
-
+		return true
 	case objabi.R_POWER_TOC: // S + A - .TOC.
 		*val = ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s)
 
-		return 0
-
+		return true
 	case objabi.R_POWER_TLS_LE:
 		// The thread pointer points 0x7000 bytes after the start of the the
 		// thread local storage area as documented in section "3.7.2 TLS
@@ -708,23 +702,23 @@
 			ld.Errorf(s, "TLS offset out of range %d", v)
 		}
 		*val = (*val &^ 0xffff) | (v & 0xffff)
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
-	switch r.Variant & ld.RV_TYPE_MASK {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+	switch r.Variant & sym.RV_TYPE_MASK {
 	default:
 		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
 		fallthrough
 
-	case ld.RV_NONE:
+	case sym.RV_NONE:
 		return t
 
-	case ld.RV_POWER_LO:
-		if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
+	case sym.RV_POWER_LO:
+		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
 			// Whether to check for signed or unsigned
 			// overflow depends on the instruction
 			var o1 uint32
@@ -750,15 +744,15 @@
 
 		return int64(int16(t))
 
-	case ld.RV_POWER_HA:
+	case sym.RV_POWER_HA:
 		t += 0x8000
 		fallthrough
 
 		// Fallthrough
-	case ld.RV_POWER_HI:
+	case sym.RV_POWER_HI:
 		t >>= 16
 
-		if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
+		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
 			// Whether to check for signed or unsigned
 			// overflow depends on the instruction
 			var o1 uint32
@@ -784,7 +778,7 @@
 
 		return int64(int16(t))
 
-	case ld.RV_POWER_DS:
+	case sym.RV_POWER_DS:
 		var o1 uint32
 		if ctxt.Arch.ByteOrder == binary.BigEndian {
 			o1 = uint32(ld.Be16(s.P[r.Off:]))
@@ -794,7 +788,7 @@
 		if t&3 != 0 {
 			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
 		}
-		if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
+		if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
 			goto overflow
 		}
 		return int64(o1)&0x3 | int64(int16(t))
@@ -805,14 +799,14 @@
 	return t
 }
 
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Plt >= 0 {
 		return
 	}
 
 	ld.Adddynsym(ctxt, s)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		plt := ctxt.Syms.Lookup(".plt", 0)
 		rela := ctxt.Syms.Lookup(".rela.plt", 0)
 		if plt.Size == 0 {
@@ -824,13 +818,13 @@
 
 		// Write symbol resolver stub (just a branch to the
 		// glink resolver stub)
-		r := ld.Addrel(glink)
+		r := glink.AddRel()
 
 		r.Sym = glink
 		r.Off = int32(glink.Size)
 		r.Siz = 4
 		r.Type = objabi.R_CALLPOWER
-		ld.Adduint32(ctxt, glink, 0x48000000) // b .glink
+		glink.AddUint32(ctxt.Arch, 0x48000000) // b .glink
 
 		// In the ppc64 ABI, the dynamic linker is responsible
 		// for writing the entire PLT.  We just need to
@@ -842,16 +836,16 @@
 
 		plt.Size += 8
 
-		ld.Addaddrplus(ctxt, rela, plt, int64(s.Plt))
-		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
-		ld.Adduint64(ctxt, rela, 0)
+		rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt))
+		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_PPC64_JMP_SLOT)))
+		rela.AddUint64(ctxt.Arch, 0)
 	} else {
 		ld.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
 
 // Generate the glink resolver stub if necessary and return the .glink section
-func ensureglinkresolver(ctxt *ld.Link) *ld.Symbol {
+func ensureglinkresolver(ctxt *ld.Link) *sym.Symbol {
 	glink := ctxt.Syms.Lookup(".glink", 0)
 	if glink.Size != 0 {
 		return glink
@@ -864,39 +858,39 @@
 	//
 	// This stub is PIC, so first get the PC of label 1 into r11.
 	// Other things will be relative to this.
-	ld.Adduint32(ctxt, glink, 0x7c0802a6) // mflr r0
-	ld.Adduint32(ctxt, glink, 0x429f0005) // bcl 20,31,1f
-	ld.Adduint32(ctxt, glink, 0x7d6802a6) // 1: mflr r11
-	ld.Adduint32(ctxt, glink, 0x7c0803a6) // mtlf r0
+	glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
+	glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
+	glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
+	glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlf r0
 
 	// Compute the .plt array index from the entry point address.
 	// Because this is PIC, everything is relative to label 1b (in
 	// r11):
 	//   r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
-	ld.Adduint32(ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48
-	ld.Adduint32(ctxt, glink, 0x7c006214) // add r0,r0,r12
-	ld.Adduint32(ctxt, glink, 0x7c0b0050) // sub r0,r0,r11
-	ld.Adduint32(ctxt, glink, 0x7800f082) // srdi r0,r0,2
+	glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
+	glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
+	glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
+	glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
 
 	// r11 = address of the first byte of the PLT
-	r := ld.Addrel(glink)
+	r := glink.AddRel()
 
 	r.Off = int32(glink.Size)
 	r.Sym = ctxt.Syms.Lookup(".plt", 0)
 	r.Siz = 8
 	r.Type = objabi.R_ADDRPOWER
 
-	ld.Adduint32(ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha
-	ld.Adduint32(ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l
+	glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
+	glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
 
 	// Load r12 = dynamic resolver address and r11 = DSO
 	// identifier from the first two doublewords of the PLT.
-	ld.Adduint32(ctxt, glink, 0xe98b0000) // ld r12,0(r11)
-	ld.Adduint32(ctxt, glink, 0xe96b0008) // ld r11,8(r11)
+	glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
+	glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)
 
 	// Jump to the dynamic resolver
-	ld.Adduint32(ctxt, glink, 0x7d8903a6) // mtctr r12
-	ld.Adduint32(ctxt, glink, 0x4e800420) // bctr
+	glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
+	glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
 
 	// The symbol resolvers must immediately follow.
 	//   res_0:
@@ -915,12 +909,12 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	for _, sect := range ld.Segtext.Sections {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		// Handle additional text sections with Codeblk
 		if sect.Name == ".text" {
 			ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
@@ -933,14 +927,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -948,10 +942,10 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	/* output symbol table */
@@ -964,9 +958,9 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 			}
@@ -975,34 +969,31 @@
 			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
 		}
 
-		ld.Cseek(int64(symo))
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(int64(symo))
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 				}
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 		}
 	}
@@ -1010,18 +1001,18 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan 9 */
-		ld.Thearch.Lput(0x647)                      /* magic */
-		ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Thearch.Lput(uint32(ld.Symsize))          /* nsyms */
-		ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ld.Thearch.Lput(0)
-		ld.Thearch.Lput(uint32(ld.Lcsize))
+		ctxt.Out.Write32(0x647)                      /* magic */
+		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
+		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+		ctxt.Out.Write32(0)
+		ctxt.Out.Write32(uint32(ld.Lcsize))
 
 	case objabi.Hlinux,
 		objabi.Hfreebsd,
@@ -1031,7 +1022,7 @@
 		ld.Asmbelf(ctxt, int64(symo))
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go
index 2d11eb5..273d9b4 100644
--- a/src/cmd/link/internal/ppc64/obj.go
+++ b/src/cmd/link/internal/ppc64/obj.go
@@ -37,59 +37,47 @@
 	"fmt"
 )
 
-func Init() {
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchPPC64
 	if objabi.GOARCH == "ppc64le" {
-		ld.SysArch = sys.ArchPPC64LE
-	} else {
-		ld.SysArch = sys.ArchPPC64
+		arch = sys.ArchPPC64LE
 	}
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Trampoline = trampoline
-	ld.Thearch.Machoreloc1 = machoreloc1
-	if ld.SysArch == sys.ArchPPC64LE {
-		ld.Thearch.Lput = ld.Lputl
-		ld.Thearch.Wput = ld.Wputl
-		ld.Thearch.Vput = ld.Vputl
-		ld.Thearch.Append16 = ld.Append16l
-		ld.Thearch.Append32 = ld.Append32l
-		ld.Thearch.Append64 = ld.Append64l
-	} else {
-		ld.Thearch.Lput = ld.Lputb
-		ld.Thearch.Wput = ld.Wputb
-		ld.Thearch.Vput = ld.Vputb
-		ld.Thearch.Append16 = ld.Append16b
-		ld.Thearch.Append32 = ld.Append32b
-		ld.Thearch.Append64 = ld.Append64b
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Trampoline:       trampoline,
+		Machoreloc1:      machoreloc1,
+
+		// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
+		Linuxdynld: "/lib64/ld64.so.1",
+
+		Freebsddynld:   "XXX",
+		Openbsddynld:   "XXX",
+		Netbsddynld:    "XXX",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
 	}
 
-	// TODO(austin): ABI v1 uses /usr/lib/ld.so.1
-	ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
-
-	ld.Thearch.Freebsddynld = "XXX"
-	ld.Thearch.Openbsddynld = "XXX"
-	ld.Thearch.Netbsddynld = "XXX"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32
@@ -105,7 +93,7 @@
 		}
 
 	case objabi.Hlinux: /* ppc64 elf */
-		if ld.SysArch == sys.ArchPPC64 {
+		if ctxt.Arch == sys.ArchPPC64 {
 			*ld.FlagD = true // TODO(austin): ELF ABI v1 not supported yet
 		}
 		ld.Elfinit(ctxt)
diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go
index 7f120c7..634ba98 100644
--- a/src/cmd/link/internal/s390x/asm.go
+++ b/src/cmd/link/internal/s390x/asm.go
@@ -32,7 +32,9 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
 	"debug/elf"
 	"fmt"
 )
@@ -52,55 +54,55 @@
 		return
 	}
 	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
 		// we're linking a module containing the runtime -> no need for
 		// an init function
 		return
 	}
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 
 	// larl %r2, <local.moduledata>
-	ld.Adduint8(ctxt, initfunc, 0xc0)
-	ld.Adduint8(ctxt, initfunc, 0x20)
-	lmd := ld.Addrel(initfunc)
+	initfunc.AddUint8(0xc0)
+	initfunc.AddUint8(0x20)
+	lmd := initfunc.AddRel()
 	lmd.Off = int32(initfunc.Size)
 	lmd.Siz = 4
 	lmd.Sym = ctxt.Moduledata
 	lmd.Type = objabi.R_PCREL
-	lmd.Variant = ld.RV_390_DBL
+	lmd.Variant = sym.RV_390_DBL
 	lmd.Add = 2 + int64(lmd.Siz)
-	ld.Adduint32(ctxt, initfunc, 0)
+	initfunc.AddUint32(ctxt.Arch, 0)
 
 	// jg <runtime.addmoduledata[@plt]>
-	ld.Adduint8(ctxt, initfunc, 0xc0)
-	ld.Adduint8(ctxt, initfunc, 0xf4)
-	rel := ld.Addrel(initfunc)
+	initfunc.AddUint8(0xc0)
+	initfunc.AddUint8(0xf4)
+	rel := initfunc.AddRel()
 	rel.Off = int32(initfunc.Size)
 	rel.Siz = 4
 	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
 	rel.Type = objabi.R_CALL
-	rel.Variant = ld.RV_390_DBL
+	rel.Variant = sym.RV_390_DBL
 	rel.Add = 2 + int64(rel.Siz)
-	ld.Adduint32(ctxt, initfunc, 0)
+	initfunc.AddUint32(ctxt.Arch, 0)
 
 	// undef (for debugging)
-	ld.Adduint32(ctxt, initfunc, 0)
-	if ld.Buildmode == ld.BuildmodePlugin {
+	initfunc.AddUint32(ctxt.Arch, 0)
+	if ctxt.BuildMode == ld.BuildModePlugin {
 		ctxt.Textp = append(ctxt.Textp, addmoduledata)
 	}
 	ctxt.Textp = append(ctxt.Textp, initfunc)
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
 	switch r.Type {
@@ -111,224 +113,221 @@
 		}
 
 		// Handle relocations found in ELF object files.
-	case 256 + ld.R_390_12,
-		256 + ld.R_390_GOT12:
+	case 256 + objabi.RelocType(elf.R_390_12),
+		256 + objabi.RelocType(elf.R_390_GOT12):
 		ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256)
 		return false
 
-	case 256 + ld.R_390_8,
-		256 + ld.R_390_16,
-		256 + ld.R_390_32,
-		256 + ld.R_390_64:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_390_8),
+		256 + objabi.RelocType(elf.R_390_16),
+		256 + objabi.RelocType(elf.R_390_32),
+		256 + objabi.RelocType(elf.R_390_64):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
 		}
 		r.Type = objabi.R_ADDR
 		return true
 
-	case 256 + ld.R_390_PC16,
-		256 + ld.R_390_PC32,
-		256 + ld.R_390_PC64:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_390_PC16),
+		256 + objabi.RelocType(elf.R_390_PC32),
+		256 + objabi.RelocType(elf.R_390_PC64):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
 		}
-		if targ.Type == 0 || targ.Type == ld.SXREF {
+		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
+		// sense and should be removed when someone has thought about it properly.
+		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
 			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
 		}
 		r.Type = objabi.R_PCREL
 		r.Add += int64(r.Siz)
 		return true
 
-	case 256 + ld.R_390_GOT16,
-		256 + ld.R_390_GOT32,
-		256 + ld.R_390_GOT64:
+	case 256 + objabi.RelocType(elf.R_390_GOT16),
+		256 + objabi.RelocType(elf.R_390_GOT32),
+		256 + objabi.RelocType(elf.R_390_GOT64):
 		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
 		return true
 
-	case 256 + ld.R_390_PLT16DBL,
-		256 + ld.R_390_PLT32DBL:
+	case 256 + objabi.RelocType(elf.R_390_PLT16DBL),
+		256 + objabi.RelocType(elf.R_390_PLT32DBL):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_390_DBL
+		r.Variant = sym.RV_390_DBL
 		r.Add += int64(r.Siz)
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add += int64(targ.Plt)
 		}
 		return true
 
-	case 256 + ld.R_390_PLT32,
-		256 + ld.R_390_PLT64:
+	case 256 + objabi.RelocType(elf.R_390_PLT32),
+		256 + objabi.RelocType(elf.R_390_PLT64):
 		r.Type = objabi.R_PCREL
 		r.Add += int64(r.Siz)
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add += int64(targ.Plt)
 		}
 		return true
 
-	case 256 + ld.R_390_COPY:
+	case 256 + objabi.RelocType(elf.R_390_COPY):
 		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
 		return false
 
-	case 256 + ld.R_390_GLOB_DAT:
+	case 256 + objabi.RelocType(elf.R_390_GLOB_DAT):
 		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
 		return false
 
-	case 256 + ld.R_390_JMP_SLOT:
+	case 256 + objabi.RelocType(elf.R_390_JMP_SLOT):
 		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
 		return false
 
-	case 256 + ld.R_390_RELATIVE:
+	case 256 + objabi.RelocType(elf.R_390_RELATIVE):
 		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
 		return false
 
-	case 256 + ld.R_390_GOTOFF:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_390_GOTOFF):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
 		}
 		r.Type = objabi.R_GOTOFF
 		return true
 
-	case 256 + ld.R_390_GOTPC:
+	case 256 + objabi.RelocType(elf.R_390_GOTPC):
 		r.Type = objabi.R_PCREL
 		r.Sym = ctxt.Syms.Lookup(".got", 0)
 		r.Add += int64(r.Siz)
 		return true
 
-	case 256 + ld.R_390_PC16DBL,
-		256 + ld.R_390_PC32DBL:
+	case 256 + objabi.RelocType(elf.R_390_PC16DBL),
+		256 + objabi.RelocType(elf.R_390_PC32DBL):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_390_DBL
+		r.Variant = sym.RV_390_DBL
 		r.Add += int64(r.Siz)
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
 		}
 		return true
 
-	case 256 + ld.R_390_GOTPCDBL:
+	case 256 + objabi.RelocType(elf.R_390_GOTPCDBL):
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_390_DBL
+		r.Variant = sym.RV_390_DBL
 		r.Sym = ctxt.Syms.Lookup(".got", 0)
 		r.Add += int64(r.Siz)
 		return true
 
-	case 256 + ld.R_390_GOTENT:
+	case 256 + objabi.RelocType(elf.R_390_GOTENT):
 		addgotsym(ctxt, targ)
 
 		r.Type = objabi.R_PCREL
-		r.Variant = ld.RV_390_DBL
+		r.Variant = sym.RV_390_DBL
 		r.Sym = ctxt.Syms.Lookup(".got", 0)
 		r.Add += int64(targ.Got)
 		r.Add += int64(r.Siz)
 		return true
 	}
 	// Handle references to ELF symbols from our own object files.
-	if targ.Type != ld.SDYNIMPORT {
+	if targ.Type != sym.SDYNIMPORT {
 		return true
 	}
 
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Vput(uint64(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_TLS_LE:
 		switch r.Siz {
 		default:
-			return -1
+			return false
 		case 4:
 			// WARNING - silently ignored by linker in ELF64
-			ld.Thearch.Vput(ld.R_390_TLS_LE32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
 		case 8:
 			// WARNING - silently ignored by linker in ELF32
-			ld.Thearch.Vput(ld.R_390_TLS_LE64 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
 		}
-
 	case objabi.R_TLS_IE:
 		switch r.Siz {
 		default:
-			return -1
+			return false
 		case 4:
-			ld.Thearch.Vput(ld.R_390_TLS_IEENT | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
 		}
-
 	case objabi.R_ADDR:
 		switch r.Siz {
 		default:
-			return -1
+			return false
 		case 4:
-			ld.Thearch.Vput(ld.R_390_32 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
 		case 8:
-			ld.Thearch.Vput(ld.R_390_64 | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
 		}
-
 	case objabi.R_GOTPCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Vput(ld.R_390_GOTENT | uint64(elfsym)<<32)
+			ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
-		elfrel := ld.R_390_NONE
-		isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL
+		elfrel := elf.R_390_NONE
+		isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
 		// TODO(mundaym): all DBL style relocations should be
 		// signalled using the variant - see issue 14218.
 		switch r.Type {
 		case objabi.R_PCRELDBL, objabi.R_CALL:
 			isdbl = true
 		}
-		if r.Xsym.Type == ld.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) {
+		if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) {
 			if isdbl {
 				switch r.Siz {
 				case 2:
-					elfrel = ld.R_390_PLT16DBL
+					elfrel = elf.R_390_PLT16DBL
 				case 4:
-					elfrel = ld.R_390_PLT32DBL
+					elfrel = elf.R_390_PLT32DBL
 				}
 			} else {
 				switch r.Siz {
 				case 4:
-					elfrel = ld.R_390_PLT32
+					elfrel = elf.R_390_PLT32
 				case 8:
-					elfrel = ld.R_390_PLT64
+					elfrel = elf.R_390_PLT64
 				}
 			}
 		} else {
 			if isdbl {
 				switch r.Siz {
 				case 2:
-					elfrel = ld.R_390_PC16DBL
+					elfrel = elf.R_390_PC16DBL
 				case 4:
-					elfrel = ld.R_390_PC32DBL
+					elfrel = elf.R_390_PC32DBL
 				}
 			} else {
 				switch r.Siz {
 				case 2:
-					elfrel = ld.R_390_PC16
+					elfrel = elf.R_390_PC16
 				case 4:
-					elfrel = ld.R_390_PC32
+					elfrel = elf.R_390_PC32
 				case 8:
-					elfrel = ld.R_390_PC64
+					elfrel = elf.R_390_PC64
 				}
 			}
 		}
-		if elfrel == ld.R_390_NONE {
-			return -1 // unsupported size/dbl combination
+		if elfrel == elf.R_390_NONE {
+			return false // unsupported size/dbl combination
 		}
-		ld.Thearch.Vput(uint64(elfrel) | uint64(elfsym)<<32)
+		ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
 	}
 
-	ld.Thearch.Vput(uint64(r.Xadd))
-	return 0
+	ctxt.Out.Write64(uint64(r.Xadd))
+	return true
 }
 
 func elfsetupplt(ctxt *ld.Link) {
@@ -336,83 +335,82 @@
 	got := ctxt.Syms.Lookup(".got", 0)
 	if plt.Size == 0 {
 		// stg     %r1,56(%r15)
-		ld.Adduint8(ctxt, plt, 0xe3)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0xf0)
-		ld.Adduint8(ctxt, plt, 0x38)
-		ld.Adduint8(ctxt, plt, 0x00)
-		ld.Adduint8(ctxt, plt, 0x24)
+		plt.AddUint8(0xe3)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0xf0)
+		plt.AddUint8(0x38)
+		plt.AddUint8(0x00)
+		plt.AddUint8(0x24)
 		// larl    %r1,_GLOBAL_OFFSET_TABLE_
-		ld.Adduint8(ctxt, plt, 0xc0)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Addpcrelplus(ctxt, plt, got, 6)
+		plt.AddUint8(0xc0)
+		plt.AddUint8(0x10)
+		plt.AddPCRelPlus(ctxt.Arch, got, 6)
 		// mvc     48(8,%r15),8(%r1)
-		ld.Adduint8(ctxt, plt, 0xd2)
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0xf0)
-		ld.Adduint8(ctxt, plt, 0x30)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x08)
+		plt.AddUint8(0xd2)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0xf0)
+		plt.AddUint8(0x30)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x08)
 		// lg      %r1,16(%r1)
-		ld.Adduint8(ctxt, plt, 0xe3)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x00)
-		ld.Adduint8(ctxt, plt, 0x04)
+		plt.AddUint8(0xe3)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x00)
+		plt.AddUint8(0x04)
 		// br      %r1
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0xf1)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0xf1)
 		// nopr    %r0
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0x00)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0x00)
 		// nopr    %r0
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0x00)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0x00)
 		// nopr    %r0
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0x00)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0x00)
 
 		// assume got->size == 0 too
-		ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
+		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
 
-		ld.Adduint64(ctxt, got, 0)
-		ld.Adduint64(ctxt, got, 0)
+		got.AddUint64(ctxt.Arch, 0)
+		got.AddUint64(ctxt.Arch, 0)
 	}
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
-	return -1
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+	return false
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
-		return -1
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
+		return false
 	}
 
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
-	switch r.Variant & ld.RV_TYPE_MASK {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+	switch r.Variant & sym.RV_TYPE_MASK {
 	default:
 		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
 		return t
 
-	case ld.RV_NONE:
+	case sym.RV_NONE:
 		return t
 
-	case ld.RV_390_DBL:
+	case sym.RV_390_DBL:
 		if (t & 1) != 0 {
 			ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
 		}
@@ -420,14 +418,14 @@
 	}
 }
 
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Plt >= 0 {
 		return
 	}
 
 	ld.Adddynsym(ctxt, s)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		plt := ctxt.Syms.Lookup(".plt", 0)
 		got := ctxt.Syms.Lookup(".got", 0)
 		rela := ctxt.Syms.Lookup(".rela.plt", 0)
@@ -436,45 +434,45 @@
 		}
 		// larl    %r1,_GLOBAL_OFFSET_TABLE_+index
 
-		ld.Adduint8(ctxt, plt, 0xc0)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant?
+		plt.AddUint8(0xc0)
+		plt.AddUint8(0x10)
+		plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
 
 		// add to got: pointer to current pos in plt
-		ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct
+		got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
 		// lg      %r1,0(%r1)
-		ld.Adduint8(ctxt, plt, 0xe3)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x00)
-		ld.Adduint8(ctxt, plt, 0x00)
-		ld.Adduint8(ctxt, plt, 0x04)
+		plt.AddUint8(0xe3)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x00)
+		plt.AddUint8(0x00)
+		plt.AddUint8(0x04)
 		// br      %r1
-		ld.Adduint8(ctxt, plt, 0x07)
-		ld.Adduint8(ctxt, plt, 0xf1)
+		plt.AddUint8(0x07)
+		plt.AddUint8(0xf1)
 		// basr    %r1,%r0
-		ld.Adduint8(ctxt, plt, 0x0d)
-		ld.Adduint8(ctxt, plt, 0x10)
+		plt.AddUint8(0x0d)
+		plt.AddUint8(0x10)
 		// lgf     %r1,12(%r1)
-		ld.Adduint8(ctxt, plt, 0xe3)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x10)
-		ld.Adduint8(ctxt, plt, 0x0c)
-		ld.Adduint8(ctxt, plt, 0x00)
-		ld.Adduint8(ctxt, plt, 0x14)
+		plt.AddUint8(0xe3)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x10)
+		plt.AddUint8(0x0c)
+		plt.AddUint8(0x00)
+		plt.AddUint8(0x14)
 		// jg .plt
-		ld.Adduint8(ctxt, plt, 0xc0)
-		ld.Adduint8(ctxt, plt, 0xf4)
+		plt.AddUint8(0xc0)
+		plt.AddUint8(0xf4)
 
-		ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
+		plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
 		//.plt index
-		ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry
+		plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
 
 		// rela
-		ld.Addaddrplus(ctxt, rela, got, got.Size-8)
+		rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
 
-		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT))
-		ld.Adduint64(ctxt, rela, 0)
+		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
+		rela.AddUint64(ctxt.Arch, 0)
 
 		s.Plt = int32(plt.Size - 32)
 
@@ -483,7 +481,7 @@
 	}
 }
 
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Got >= 0 {
 		return
 	}
@@ -491,13 +489,13 @@
 	ld.Adddynsym(ctxt, s)
 	got := ctxt.Syms.Lookup(".got", 0)
 	s.Got = int32(got.Size)
-	ld.Adduint64(ctxt, got, 0)
+	got.AddUint64(ctxt.Arch, 0)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		rela := ctxt.Syms.Lookup(".rela", 0)
-		ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
-		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
-		ld.Adduint64(ctxt, rela, 0)
+		rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
+		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
+		rela.AddUint64(ctxt.Arch, 0)
 	} else {
 		ld.Errorf(s, "addgotsym: unsupported binary format")
 	}
@@ -508,15 +506,15 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -524,14 +522,14 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -539,10 +537,10 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	/* output symbol table */
@@ -551,7 +549,7 @@
 	ld.Lcsize = 0
 	symo := uint32(0)
 	if !*ld.FlagS {
-		if !ld.Iself {
+		if !ctxt.IsELF {
 			ld.Errorf(nil, "unsupported executable format")
 		}
 		if ctxt.Debugvlog != 0 {
@@ -560,19 +558,19 @@
 		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 
-		ld.Cseek(int64(symo))
+		ctxt.Out.SeekSet(int64(symo))
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 		}
 		ld.Asmelfsym(ctxt)
-		ld.Cflush()
-		ld.Cwrite(ld.Elfstrdat)
+		ctxt.Out.Flush()
+		ctxt.Out.Write(ld.Elfstrdat)
 
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
 		}
 
-		if ld.Linkmode == ld.LinkExternal {
+		if ctxt.LinkMode == ld.LinkExternal {
 			ld.Elfemitreloc(ctxt)
 		}
 	}
@@ -580,15 +578,15 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f header\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 		ld.Errorf(nil, "unsupported operating system")
 	case objabi.Hlinux:
 		ld.Asmbelf(ctxt, int64(symo))
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 	if *ld.FlagC {
 		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
 		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go
index cd5da6a..9ac7eb8 100644
--- a/src/cmd/link/internal/s390x/obj.go
+++ b/src/cmd/link/internal/s390x/obj.go
@@ -37,45 +37,43 @@
 	"fmt"
 )
 
-func Init() {
-	ld.SysArch = sys.ArchS390X
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.ArchS390X
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb // in asm.go
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	ld.Thearch.Lput = ld.Lputb
-	ld.Thearch.Wput = ld.Wputb
-	ld.Thearch.Vput = ld.Vputb
-	ld.Thearch.Append16 = ld.Append16b
-	ld.Thearch.Append32 = ld.Append32b
-	ld.Thearch.Append64 = ld.Append64b
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb, // in asm.go
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
 
-	ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
+		Linuxdynld: "/lib64/ld64.so.1",
 
-	// not relevant for s390x
-	ld.Thearch.Freebsddynld = "XXX"
-	ld.Thearch.Openbsddynld = "XXX"
-	ld.Thearch.Netbsddynld = "XXX"
-	ld.Thearch.Dragonflydynld = "XXX"
-	ld.Thearch.Solarisdynld = "XXX"
+		// not relevant for s390x
+		Freebsddynld:   "XXX",
+		Openbsddynld:   "XXX",
+		Netbsddynld:    "XXX",
+		Dragonflydynld: "XXX",
+		Solarisdynld:   "XXX",
+	}
+
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hlinux: // s390x ELF
 		ld.Elfinit(ctxt)
diff --git a/src/cmd/link/internal/sym/attribute.go b/src/cmd/link/internal/sym/attribute.go
new file mode 100644
index 0000000..45a7939
--- /dev/null
+++ b/src/cmd/link/internal/sym/attribute.go
@@ -0,0 +1,109 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+// Attribute is a set of common symbol attributes.
+type Attribute int32
+
+const (
+	// AttrDuplicateOK marks a symbol that can be present in multiple object
+	// files.
+	AttrDuplicateOK Attribute = 1 << iota
+	// AttrExternal marks function symbols loaded from host object files.
+	AttrExternal
+	// AttrNoSplit marks functions that cannot split the stack; the linker
+	// cares because it checks that there are no call chains of nosplit
+	// functions that require more than StackLimit bytes (see
+	// lib.go:dostkcheck)
+	AttrNoSplit
+	// AttrReachable marks symbols that are transitively referenced from the
+	// entry points. Unreachable symbols are not written to the output.
+	AttrReachable
+	// AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
+	// by directives written by cgo (in response to //export directives in
+	// the source).
+	AttrCgoExportDynamic
+	AttrCgoExportStatic
+	// AttrSpecial marks symbols that do not have their address (i.e. Value)
+	// computed by the usual mechanism of data.go:dodata() &
+	// data.go:address().
+	AttrSpecial
+	// AttrStackCheck is used by dostkcheck to only check each NoSplit
+	// function's stack usage once.
+	AttrStackCheck
+	// AttrNotInSymbolTable marks symbols that are not written to the symbol table.
+	AttrNotInSymbolTable
+	// AttrOnList marks symbols that are on some list (such as the list of
+	// all text symbols, or one of the lists of data symbols) and is
+	// consulted to avoid bugs where a symbol is put on a list twice.
+	AttrOnList
+	// AttrLocal marks symbols that are only visible within the module
+	// (executable or shared library) being linked. Only relevant when
+	// dynamically linking Go code.
+	AttrLocal
+	// AttrReflectMethod marks certain methods from the reflect package that
+	// can be used to call arbitrary methods. If no symbol with this bit set
+	// is marked as reachable, more dead code elimination can be done.
+	AttrReflectMethod
+	// AttrMakeTypelink Amarks types that should be added to the typelink
+	// table. See typelinks.go:typelinks().
+	AttrMakeTypelink
+	// AttrShared marks symbols compiled with the -shared option.
+	AttrShared
+	// AttrVisibilityHidden symbols are ELF symbols with
+	// visibility set to STV_HIDDEN. They become local symbols in
+	// the final executable. Only relevant when internally linking
+	// on an ELF platform.
+	AttrVisibilityHidden
+	// AttrSubSymbol mostly means that the symbol appears on the Sub list of some
+	// other symbol.  Unfortunately, it's not 100% reliable; at least, it's not set
+	// correctly for the .TOC. symbol in Link.dodata.  Usually the Outer field of the
+	// symbol points to the symbol whose list it is on, but that it is not set for the
+	// symbols added to .windynamic in initdynimport in pe.go.
+	//
+	// TODO(mwhudson): fix the inconsistencies noticed above.
+	//
+	// Sub lists are used when loading host objects (sections from the host object
+	// become regular linker symbols and symbols go on the Sub list of their section)
+	// and for constructing the global offset table when internally linking a dynamic
+	// executable.
+	//
+	// TOOD(mwhudson): perhaps a better name for this is AttrNonGoSymbol.
+	AttrSubSymbol
+	// AttrContainer is set on text symbols that are present as the .Outer for some
+	// other symbol.
+	AttrContainer
+	// 17 attributes defined so far.
+)
+
+func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
+func (a Attribute) External() bool         { return a&AttrExternal != 0 }
+func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
+func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
+func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
+func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
+func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
+func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
+func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
+func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
+func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
+func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
+func (a Attribute) MakeTypelink() bool     { return a&AttrMakeTypelink != 0 }
+func (a Attribute) Shared() bool           { return a&AttrShared != 0 }
+func (a Attribute) VisibilityHidden() bool { return a&AttrVisibilityHidden != 0 }
+func (a Attribute) SubSymbol() bool        { return a&AttrSubSymbol != 0 }
+func (a Attribute) Container() bool        { return a&AttrContainer != 0 }
+
+func (a Attribute) CgoExport() bool {
+	return a.CgoExportDynamic() || a.CgoExportStatic()
+}
+
+func (a *Attribute) Set(flag Attribute, value bool) {
+	if value {
+		*a |= flag
+	} else {
+		*a &^= flag
+	}
+}
diff --git a/src/cmd/link/internal/sym/library.go b/src/cmd/link/internal/sym/library.go
new file mode 100644
index 0000000..ee96f4a
--- /dev/null
+++ b/src/cmd/link/internal/sym/library.go
@@ -0,0 +1,22 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+type Library struct {
+	Objref        string
+	Srcref        string
+	File          string
+	Pkg           string
+	Shlib         string
+	Hash          string
+	ImportStrings []string
+	Imports       []*Library
+	Textp         []*Symbol // text symbols defined in this library
+	DupTextSyms   []*Symbol // dupok text symbols defined in this library
+}
+
+func (l Library) String() string {
+	return l.Pkg
+}
diff --git a/src/cmd/link/internal/sym/reloc.go b/src/cmd/link/internal/sym/reloc.go
new file mode 100644
index 0000000..fc62c38
--- /dev/null
+++ b/src/cmd/link/internal/sym/reloc.go
@@ -0,0 +1,116 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+import (
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"debug/elf"
+)
+
+// Reloc is a relocation.
+//
+// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
+// A Reloc is stored in a slice on the Symbol it rewrites.
+//
+// Relocations are generated by the compiler as the type
+// cmd/internal/obj.Reloc, which is encoded into the object file wire
+// format and decoded by the linker into this type. A separate type is
+// used to hold linker-specific state about the relocation.
+//
+// Some relocations are created by cmd/link.
+type Reloc struct {
+	Off     int32            // offset to rewrite
+	Siz     uint8            // number of bytes to rewrite, 1, 2, or 4
+	Done    bool             // set to true when relocation is complete
+	Variant RelocVariant     // variation on Type
+	Type    objabi.RelocType // the relocation type
+	Add     int64            // addend
+	Xadd    int64            // addend passed to external linker
+	Sym     *Symbol          // symbol the relocation addresses
+	Xsym    *Symbol          // symbol passed to external linker
+}
+
+// RelocVariant is a linker-internal variation on a relocation.
+type RelocVariant uint8
+
+const (
+	RV_NONE RelocVariant = iota
+	RV_POWER_LO
+	RV_POWER_HI
+	RV_POWER_HA
+	RV_POWER_DS
+
+	// RV_390_DBL is a s390x-specific relocation variant that indicates that
+	// the value to be placed into the relocatable field should first be
+	// divided by 2.
+	RV_390_DBL
+
+	RV_CHECK_OVERFLOW RelocVariant = 1 << 7
+	RV_TYPE_MASK      RelocVariant = RV_CHECK_OVERFLOW - 1
+)
+
+func RelocName(arch *sys.Arch, r objabi.RelocType) string {
+	// We didn't have some relocation types at Go1.4.
+	// Uncomment code when we include those in bootstrap code.
+
+	switch {
+	case r >= 512: // Mach-O
+		// nr := (r - 512)>>1
+		// switch ctxt.Arch.Family {
+		// case sys.AMD64:
+		// 	return macho.RelocTypeX86_64(nr).String()
+		// case sys.ARM:
+		// 	return macho.RelocTypeARM(nr).String()
+		// case sys.ARM64:
+		// 	return macho.RelocTypeARM64(nr).String()
+		// case sys.I386:
+		// 	return macho.RelocTypeGeneric(nr).String()
+		// default:
+		// 	panic("unreachable")
+		// }
+	case r >= 256: // ELF
+		nr := r - 256
+		switch arch.Family {
+		case sys.AMD64:
+			return elf.R_X86_64(nr).String()
+		case sys.ARM:
+			return elf.R_ARM(nr).String()
+		case sys.ARM64:
+			return elf.R_AARCH64(nr).String()
+		case sys.I386:
+			return elf.R_386(nr).String()
+		case sys.MIPS, sys.MIPS64:
+			// return elf.R_MIPS(nr).String()
+		case sys.PPC64:
+			// return elf.R_PPC64(nr).String()
+		case sys.S390X:
+			// return elf.R_390(nr).String()
+		default:
+			panic("unreachable")
+		}
+	}
+
+	return r.String()
+}
+
+// RelocByOff implements sort.Interface for sorting relocations by offset.
+type RelocByOff []Reloc
+
+func (x RelocByOff) Len() int { return len(x) }
+
+func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x RelocByOff) Less(i, j int) bool {
+	a := &x[i]
+	b := &x[j]
+	if a.Off < b.Off {
+		return true
+	}
+	if a.Off > b.Off {
+		return false
+	}
+	return false
+}
diff --git a/src/cmd/link/internal/sym/segment.go b/src/cmd/link/internal/sym/segment.go
new file mode 100644
index 0000000..d5255bf
--- /dev/null
+++ b/src/cmd/link/internal/sym/segment.go
@@ -0,0 +1,58 @@
+// Inferno utils/8l/asm.c
+// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
+//
+//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@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@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.
+
+package sym
+
+// Terrible but standard terminology.
+// A segment describes a block of file to load into memory.
+// A section further describes the pieces of that block for
+// use in debuggers and such.
+
+type Segment struct {
+	Rwx      uint8  // permission as usual unix bits (5 = r-x etc)
+	Vaddr    uint64 // virtual address
+	Length   uint64 // length in memory
+	Fileoff  uint64 // file offset
+	Filelen  uint64 // length on disk
+	Sections []*Section
+}
+
+type Section struct {
+	Rwx     uint8
+	Extnum  int16
+	Align   int32
+	Name    string
+	Vaddr   uint64
+	Length  uint64
+	Seg     *Segment
+	Elfsect interface{} // an *ld.ElfShdr
+	Reloff  uint64
+	Rellen  uint64
+}
diff --git a/src/cmd/link/internal/sym/symbol.go b/src/cmd/link/internal/sym/symbol.go
new file mode 100644
index 0000000..6faedf4
--- /dev/null
+++ b/src/cmd/link/internal/sym/symbol.go
@@ -0,0 +1,382 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+import (
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+	"debug/elf"
+	"fmt"
+	"log"
+)
+
+// Symbol is an entry in the symbol table.
+type Symbol struct {
+	Name        string
+	Extname     string
+	Type        SymKind
+	Version     int16
+	Attr        Attribute
+	Localentry  uint8
+	Dynid       int32
+	Plt         int32
+	Got         int32
+	Align       int32
+	Elfsym      int32
+	LocalElfsym int32
+	Value       int64
+	Size        int64
+	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
+	// is not set for symbols defined by the packages being linked or by symbols
+	// read by ldelf (and so is left as elf.STT_NOTYPE).
+	ElfType     elf.SymType
+	Sub         *Symbol
+	Outer       *Symbol
+	Gotype      *Symbol
+	Reachparent *Symbol
+	File        string
+	Dynimplib   string
+	Dynimpvers  string
+	Sect        *Section
+	FuncInfo    *FuncInfo
+	Lib         *Library // Package defining this symbol
+	// P contains the raw symbol data.
+	P []byte
+	R []Reloc
+}
+
+func (s *Symbol) String() string {
+	if s.Version == 0 {
+		return s.Name
+	}
+	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
+}
+
+func (s *Symbol) ElfsymForReloc() int32 {
+	// If putelfsym created a local version of this symbol, use that in all
+	// relocations.
+	if s.LocalElfsym != 0 {
+		return s.LocalElfsym
+	} else {
+		return s.Elfsym
+	}
+}
+
+func (s *Symbol) Len() int64 {
+	return s.Size
+}
+
+func (s *Symbol) Grow(siz int64) {
+	if int64(int(siz)) != siz {
+		log.Fatalf("symgrow size %d too long", siz)
+	}
+	if int64(len(s.P)) >= siz {
+		return
+	}
+	if cap(s.P) < int(siz) {
+		p := make([]byte, 2*(siz+1))
+		s.P = append(p[:0], s.P...)
+	}
+	s.P = s.P[:siz]
+}
+
+func (s *Symbol) AddBytes(bytes []byte) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	s.P = append(s.P, bytes...)
+	s.Size = int64(len(s.P))
+
+	return s.Size
+}
+
+func (s *Symbol) AddUint8(v uint8) int64 {
+	off := s.Size
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	s.Size++
+	s.P = append(s.P, v)
+
+	return off
+}
+
+func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
+	return s.AddUintXX(arch, uint64(v), 2)
+}
+
+func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
+	return s.AddUintXX(arch, uint64(v), 4)
+}
+
+func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
+	return s.AddUintXX(arch, v, 8)
+}
+
+func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
+	return s.AddUintXX(arch, v, arch.PtrSize)
+}
+
+func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
+	return s.setUintXX(arch, r, uint64(v), 1)
+}
+
+func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
+	return s.setUintXX(arch, r, uint64(v), 4)
+}
+
+func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
+	return s.setUintXX(arch, r, v, int64(arch.PtrSize))
+}
+
+func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	i := s.Size
+	s.Size += int64(arch.PtrSize)
+	s.Grow(s.Size)
+	r := s.AddRel()
+	r.Sym = t
+	r.Off = int32(i)
+	r.Siz = uint8(arch.PtrSize)
+	r.Type = typ
+	r.Add = add
+	return i + int64(r.Siz)
+}
+
+func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
+	return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
+}
+
+func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
+	return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
+}
+
+func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	i := s.Size
+	s.Size += 4
+	s.Grow(s.Size)
+	r := s.AddRel()
+	r.Sym = t
+	r.Off = int32(i)
+	r.Add = add
+	r.Type = objabi.R_PCREL
+	r.Siz = 4
+	if arch.Family == sys.S390X {
+		r.Variant = RV_390_DBL
+	}
+	return i + int64(r.Siz)
+}
+
+func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
+	return s.AddAddrPlus(arch, t, 0)
+}
+
+func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	if off+int64(arch.PtrSize) > s.Size {
+		s.Size = off + int64(arch.PtrSize)
+		s.Grow(s.Size)
+	}
+
+	r := s.AddRel()
+	r.Sym = t
+	r.Off = int32(off)
+	r.Siz = uint8(arch.PtrSize)
+	r.Type = objabi.R_ADDR
+	r.Add = add
+	return off + int64(r.Siz)
+}
+
+func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
+	return s.SetAddrPlus(arch, off, t, 0)
+}
+
+func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	i := s.Size
+	s.Size += int64(arch.PtrSize)
+	s.Grow(s.Size)
+	r := s.AddRel()
+	r.Sym = t
+	r.Off = int32(i)
+	r.Siz = uint8(arch.PtrSize)
+	r.Type = objabi.R_SIZE
+	return i + int64(r.Siz)
+}
+
+func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	i := s.Size
+	s.Size += 4
+	s.Grow(s.Size)
+	r := s.AddRel()
+	r.Sym = t
+	r.Off = int32(i)
+	r.Siz = 4
+	r.Type = objabi.R_ADDR
+	r.Add = add
+	return i + int64(r.Siz)
+}
+
+func (s *Symbol) AddRel() *Reloc {
+	s.R = append(s.R, Reloc{})
+	return &s.R[len(s.R)-1]
+}
+
+func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
+	off := s.Size
+	s.setUintXX(arch, off, v, int64(wid))
+	return off
+}
+
+func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
+	if s.Type == 0 {
+		s.Type = SDATA
+	}
+	s.Attr |= AttrReachable
+	if s.Size < off+wid {
+		s.Size = off + wid
+		s.Grow(s.Size)
+	}
+
+	switch wid {
+	case 1:
+		s.P[off] = uint8(v)
+	case 2:
+		arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
+	case 4:
+		arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
+	case 8:
+		arch.ByteOrder.PutUint64(s.P[off:], v)
+	}
+
+	return off + wid
+}
+
+// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
+// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
+func SortSub(l *Symbol) *Symbol {
+	if l == nil || l.Sub == nil {
+		return l
+	}
+
+	l1 := l
+	l2 := l
+	for {
+		l2 = l2.Sub
+		if l2 == nil {
+			break
+		}
+		l2 = l2.Sub
+		if l2 == nil {
+			break
+		}
+		l1 = l1.Sub
+	}
+
+	l2 = l1.Sub
+	l1.Sub = nil
+	l1 = SortSub(l)
+	l2 = SortSub(l2)
+
+	/* set up lead element */
+	if l1.Value < l2.Value {
+		l = l1
+		l1 = l1.Sub
+	} else {
+		l = l2
+		l2 = l2.Sub
+	}
+
+	le := l
+
+	for {
+		if l1 == nil {
+			for l2 != nil {
+				le.Sub = l2
+				le = l2
+				l2 = l2.Sub
+			}
+
+			le.Sub = nil
+			break
+		}
+
+		if l2 == nil {
+			for l1 != nil {
+				le.Sub = l1
+				le = l1
+				l1 = l1.Sub
+			}
+
+			break
+		}
+
+		if l1.Value < l2.Value {
+			le.Sub = l1
+			le = l1
+			l1 = l1.Sub
+		} else {
+			le.Sub = l2
+			le = l2
+			l2 = l2.Sub
+		}
+	}
+
+	le.Sub = nil
+	return l
+}
+
+type FuncInfo struct {
+	Args        int32
+	Locals      int32
+	Autom       []Auto
+	Pcsp        Pcdata
+	Pcfile      Pcdata
+	Pcline      Pcdata
+	Pcinline    Pcdata
+	Pcdata      []Pcdata
+	Funcdata    []*Symbol
+	Funcdataoff []int64
+	File        []*Symbol
+	InlTree     []InlinedCall
+}
+
+// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
+type InlinedCall struct {
+	Parent int32   // index of parent in InlTree
+	File   *Symbol // file of the inlined call
+	Line   int32   // line number of the inlined call
+	Func   *Symbol // function that was inlined
+}
+
+type Pcdata struct {
+	P []byte
+}
+
+type Auto struct {
+	Asym    *Symbol
+	Gotype  *Symbol
+	Aoffset int32
+	Name    int16
+}
diff --git a/src/cmd/link/internal/sym/symbols.go b/src/cmd/link/internal/sym/symbols.go
new file mode 100644
index 0000000..98a5ae6
--- /dev/null
+++ b/src/cmd/link/internal/sym/symbols.go
@@ -0,0 +1,117 @@
+// Derived from Inferno utils/6l/l.h and related files.
+// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
+//
+//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@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@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.
+
+package sym
+
+type Symbols struct {
+	symbolBatch []Symbol
+
+	// Symbol lookup based on name and indexed by version.
+	hash []map[string]*Symbol
+
+	Allsym []*Symbol
+}
+
+func NewSymbols() *Symbols {
+	return &Symbols{
+		hash: []map[string]*Symbol{
+			// preallocate about 2mb for hash of
+			// non static symbols
+			make(map[string]*Symbol, 100000),
+		},
+		Allsym: make([]*Symbol, 0, 100000),
+	}
+}
+
+func (syms *Symbols) Newsym(name string, v int) *Symbol {
+	batch := syms.symbolBatch
+	if len(batch) == 0 {
+		batch = make([]Symbol, 1000)
+	}
+	s := &batch[0]
+	syms.symbolBatch = batch[1:]
+
+	s.Dynid = -1
+	s.Plt = -1
+	s.Got = -1
+	s.Name = name
+	s.Version = int16(v)
+	syms.Allsym = append(syms.Allsym, s)
+
+	return s
+}
+
+// Look up the symbol with the given name and version, creating the
+// symbol if it is not found.
+func (syms *Symbols) Lookup(name string, v int) *Symbol {
+	m := syms.hash[v]
+	s := m[name]
+	if s != nil {
+		return s
+	}
+	s = syms.Newsym(name, v)
+	s.Extname = s.Name
+	m[name] = s
+	return s
+}
+
+// Look up the symbol with the given name and version, returning nil
+// if it is not found.
+func (syms *Symbols) ROLookup(name string, v int) *Symbol {
+	return syms.hash[v][name]
+}
+
+// Allocate a new version (i.e. symbol namespace).
+func (syms *Symbols) IncVersion() int {
+	syms.hash = append(syms.hash, make(map[string]*Symbol))
+	return len(syms.hash) - 1
+}
+
+// Rename renames a symbol.
+func (syms *Symbols) Rename(old, new string, v int) {
+	s := syms.hash[v][old]
+	s.Name = new
+	if s.Extname == old {
+		s.Extname = new
+	}
+	delete(syms.hash[v], old)
+
+	dup := syms.hash[v][new]
+	if dup == nil {
+		syms.hash[v][new] = s
+	} else {
+		if s.Type == 0 {
+			*s = *dup
+		} else if dup.Type == 0 {
+			*dup = *s
+			syms.hash[v][new] = s
+		}
+	}
+}
diff --git a/src/cmd/link/internal/sym/symkind.go b/src/cmd/link/internal/sym/symkind.go
new file mode 100644
index 0000000..1c409a6
--- /dev/null
+++ b/src/cmd/link/internal/sym/symkind.go
@@ -0,0 +1,149 @@
+// Derived from Inferno utils/6l/l.h and related files.
+// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
+//
+//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@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@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.
+
+package sym
+
+// A SymKind describes the kind of memory represented by a symbol.
+type SymKind uint8
+
+// Defined SymKind values.
+//
+// TODO(rsc): Give idiomatic Go names.
+//go:generate stringer -type=SymKind
+const (
+	Sxxx SymKind = iota
+	STEXT
+	SELFRXSECT
+
+	// Read-only sections.
+	STYPE
+	SSTRING
+	SGOSTRING
+	SGOFUNC
+	SGCBITS
+	SRODATA
+	SFUNCTAB
+
+	SELFROSECT
+	SMACHOPLT
+
+	// Read-only sections with relocations.
+	//
+	// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
+	// When linking a shared object, some conceptually "read only" types need to
+	// be written to by relocations and putting them in a section called
+	// ".rodata" interacts poorly with the system linkers. The GNU linkers
+	// support this situation by arranging for sections of the name
+	// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
+	// relocations have applied, so when the Go linker is creating a shared
+	// object it checks all objects of the above types and bumps any object that
+	// has a relocation to it to the corresponding type below, which are then
+	// written to sections with appropriate magic names.
+	STYPERELRO
+	SSTRINGRELRO
+	SGOSTRINGRELRO
+	SGOFUNCRELRO
+	SGCBITSRELRO
+	SRODATARELRO
+	SFUNCTABRELRO
+
+	// Part of .data.rel.ro if it exists, otherwise part of .rodata.
+	STYPELINK
+	SITABLINK
+	SSYMTAB
+	SPCLNTAB
+
+	// Writable sections.
+	SELFSECT
+	SMACHO
+	SMACHOGOT
+	SWINDOWS
+	SELFGOT
+	SNOPTRDATA
+	SINITARR
+	SDATA
+	SBSS
+	SNOPTRBSS
+	STLSBSS
+	SXREF
+	SMACHOSYMSTR
+	SMACHOSYMTAB
+	SMACHOINDIRECTPLT
+	SMACHOINDIRECTGOT
+	SFILEPATH
+	SCONST
+	SDYNIMPORT
+	SHOSTOBJ
+	SDWARFSECT
+	SDWARFINFO
+	SDWARFRANGE
+	SDWARFLOC
+)
+
+// AbiSymKindToSymKind maps values read from object files (which are
+// of type cmd/internal/objabi.SymKind) to values of type SymKind.
+var AbiSymKindToSymKind = [...]SymKind{
+	Sxxx,
+	STEXT,
+	SRODATA,
+	SNOPTRDATA,
+	SDATA,
+	SBSS,
+	SNOPTRBSS,
+	STLSBSS,
+	SDWARFINFO,
+	SDWARFRANGE,
+	SDWARFLOC,
+}
+
+// ReadOnly are the symbol kinds that form read-only sections. In some
+// cases, if they will require relocations, they are transformed into
+// rel-ro sections using relROMap.
+var ReadOnly = []SymKind{
+	STYPE,
+	SSTRING,
+	SGOSTRING,
+	SGOFUNC,
+	SGCBITS,
+	SRODATA,
+	SFUNCTAB,
+}
+
+// RelROMap describes the transformation of read-only symbols to rel-ro
+// symbols.
+var RelROMap = map[SymKind]SymKind{
+	STYPE:     STYPERELRO,
+	SSTRING:   SSTRINGRELRO,
+	SGOSTRING: SGOSTRINGRELRO,
+	SGOFUNC:   SGOFUNCRELRO,
+	SGCBITS:   SGCBITSRELRO,
+	SRODATA:   SRODATARELRO,
+	SFUNCTAB:  SFUNCTABRELRO,
+}
diff --git a/src/cmd/link/internal/sym/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go
new file mode 100644
index 0000000..716eabd
--- /dev/null
+++ b/src/cmd/link/internal/sym/symkind_string.go
@@ -0,0 +1,16 @@
+// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
+
+package sym
+
+import "fmt"
+
+const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOC"
+
+var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 214, 220, 229, 237, 244, 254, 262, 267, 271, 280, 287, 292, 304, 316, 333, 350, 359, 365, 375, 383, 393, 403, 414, 423}
+
+func (i SymKind) String() string {
+	if i < 0 || i >= SymKind(len(_SymKind_index)-1) {
+		return fmt.Sprintf("SymKind(%d)", i)
+	}
+	return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
+}
diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go
index 3649e6a..c76c2a5 100644
--- a/src/cmd/link/internal/x86/asm.go
+++ b/src/cmd/link/internal/x86/asm.go
@@ -32,17 +32,20 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"cmd/link/internal/sym"
+	"debug/elf"
 	"log"
 )
 
 // Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
-func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) {
-	s.Attr |= ld.AttrReachable
+func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
+	s.Attr |= sym.AttrReachable
 	i := s.Size
 	s.Size += 4
-	ld.Symgrow(s, s.Size)
-	r := ld.Addrel(s)
+	s.Grow(s.Size)
+	r := s.AddRel()
 	r.Sym = t
 	r.Off = int32(i)
 	r.Type = objabi.R_CALL
@@ -53,12 +56,12 @@
 	if ctxt.DynlinkingGo() {
 		// We need get_pc_thunk.
 	} else {
-		switch ld.Buildmode {
-		case ld.BuildmodeCArchive:
-			if !ld.Iself {
+		switch ctxt.BuildMode {
+		case ld.BuildModeCArchive:
+			if !ctxt.IsELF {
 				return
 			}
-		case ld.BuildmodePIE, ld.BuildmodeCShared, ld.BuildmodePlugin:
+		case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
 			// We need get_pc_thunk.
 		default:
 			return
@@ -66,7 +69,7 @@
 	}
 
 	// Generate little thunks that load the PC of the next instruction into a register.
-	thunks := make([]*ld.Symbol, 0, 7+len(ctxt.Textp))
+	thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
 	for _, r := range [...]struct {
 		name string
 		num  uint8
@@ -81,12 +84,12 @@
 		{"di", 7},
 	} {
 		thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
-		thunkfunc.Type = ld.STEXT
-		thunkfunc.Attr |= ld.AttrLocal
-		thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
+		thunkfunc.Type = sym.STEXT
+		thunkfunc.Attr |= sym.AttrLocal
+		thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
 		o := func(op ...uint8) {
 			for _, op1 := range op {
-				ld.Adduint8(ctxt, thunkfunc, op1)
+				thunkfunc.AddUint8(op1)
 			}
 		}
 		// 8b 04 24	mov    (%esp),%eax
@@ -100,21 +103,21 @@
 	ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
 
 	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
 		// we're linking a module containing the runtime -> no need for
 		// an init function
 		return
 	}
 
-	addmoduledata.Attr |= ld.AttrReachable
+	addmoduledata.Attr |= sym.AttrReachable
 
 	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = ld.STEXT
-	initfunc.Attr |= ld.AttrLocal
-	initfunc.Attr |= ld.AttrReachable
+	initfunc.Type = sym.STEXT
+	initfunc.Attr |= sym.AttrLocal
+	initfunc.Attr |= sym.AttrReachable
 	o := func(op ...uint8) {
 		for _, op1 := range op {
-			ld.Adduint8(ctxt, initfunc, op1)
+			initfunc.AddUint8(op1)
 		}
 	}
 
@@ -133,13 +136,13 @@
 	addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
 
 	o(0x8d, 0x81)
-	ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 6)
+	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
 
 	o(0x8d, 0x99)
 	i := initfunc.Size
 	initfunc.Size += 4
-	ld.Symgrow(initfunc, initfunc.Size)
-	r := ld.Addrel(initfunc)
+	initfunc.Grow(initfunc.Size)
+	r := initfunc.AddRel()
 	r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
 	r.Off = int32(i)
 	r.Type = objabi.R_PCREL
@@ -153,43 +156,45 @@
 
 	o(0xc3)
 
-	if ld.Buildmode == ld.BuildmodePlugin {
+	if ctxt.BuildMode == ld.BuildModePlugin {
 		ctxt.Textp = append(ctxt.Textp, addmoduledata)
 	}
 	ctxt.Textp = append(ctxt.Textp, initfunc)
 	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= ld.AttrReachable
-	initarray_entry.Attr |= ld.AttrLocal
-	initarray_entry.Type = ld.SINITARR
-	ld.Addaddr(ctxt, initarray_entry, initfunc)
+	initarray_entry.Attr |= sym.AttrReachable
+	initarray_entry.Attr |= sym.AttrLocal
+	initarray_entry.Type = sym.SINITARR
+	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
 	switch r.Type {
 	default:
 		if r.Type >= 256 {
-			ld.Errorf(s, "unexpected relocation type %d", r.Type)
+			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
 			return false
 		}
 
 		// Handle relocations found in ELF object files.
-	case 256 + ld.R_386_PC32:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_386_PC32):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
 		}
-		if targ.Type == 0 || targ.Type == ld.SXREF {
+		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
+		// sense and should be removed when someone has thought about it properly.
+		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
 			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
 		}
 		r.Type = objabi.R_PCREL
 		r.Add += 4
 		return true
 
-	case 256 + ld.R_386_PLT32:
+	case 256 + objabi.RelocType(elf.R_386_PLT32):
 		r.Type = objabi.R_PCREL
 		r.Add += 4
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add += int64(targ.Plt)
@@ -197,8 +202,8 @@
 
 		return true
 
-	case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X:
-		if targ.Type != ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_386_GOT32), 256 + objabi.RelocType(elf.R_386_GOT32X):
+		if targ.Type != sym.SDYNIMPORT {
 			// have symbol
 			if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
 				// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
@@ -228,18 +233,18 @@
 		r.Add += int64(targ.Got)
 		return true
 
-	case 256 + ld.R_386_GOTOFF:
+	case 256 + objabi.RelocType(elf.R_386_GOTOFF):
 		r.Type = objabi.R_GOTOFF
 		return true
 
-	case 256 + ld.R_386_GOTPC:
+	case 256 + objabi.RelocType(elf.R_386_GOTPC):
 		r.Type = objabi.R_PCREL
 		r.Sym = ctxt.Syms.Lookup(".got", 0)
 		r.Add += 4
 		return true
 
-	case 256 + ld.R_386_32:
-		if targ.Type == ld.SDYNIMPORT {
+	case 256 + objabi.RelocType(elf.R_386_32):
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
 		}
 		r.Type = objabi.R_ADDR
@@ -247,13 +252,13 @@
 
 	case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
 		r.Type = objabi.R_ADDR
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
 		}
 		return true
 
 	case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
-		if targ.Type == ld.SDYNIMPORT {
+		if targ.Type == sym.SDYNIMPORT {
 			addpltsym(ctxt, targ)
 			r.Sym = ctxt.Syms.Lookup(".plt", 0)
 			r.Add = int64(targ.Plt)
@@ -265,7 +270,7 @@
 		return true
 
 	case 512 + ld.MACHO_FAKE_GOTPCREL:
-		if targ.Type != ld.SDYNIMPORT {
+		if targ.Type != sym.SDYNIMPORT {
 			// have symbol
 			// turn MOVL of GOT entry into LEAL of symbol itself
 			if r.Off < 2 || s.P[r.Off-2] != 0x8b {
@@ -286,7 +291,7 @@
 	}
 
 	// Handle references to ELF symbols from our own object files.
-	if targ.Type != ld.SDYNIMPORT {
+	if targ.Type != sym.SDYNIMPORT {
 		return true
 	}
 	switch r.Type {
@@ -298,20 +303,20 @@
 		return true
 
 	case objabi.R_ADDR:
-		if s.Type != ld.SDATA {
+		if s.Type != sym.SDATA {
 			break
 		}
-		if ld.Iself {
+		if ctxt.IsELF {
 			ld.Adddynsym(ctxt, targ)
 			rel := ctxt.Syms.Lookup(".rel", 0)
-			ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
-			ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
+			rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
+			rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
 			r.Type = objabi.R_CONST // write r->add during relocsym
 			r.Sym = nil
 			return true
 		}
 
-		if ld.Headtype == objabi.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
+		if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
 			// Mach-O relocations are a royal pain to lay out.
 			// They use a compact stateful bytecode representation
 			// that is too much bother to deal with.
@@ -325,99 +330,89 @@
 			ld.Adddynsym(ctxt, targ)
 
 			got := ctxt.Syms.Lookup(".got", 0)
-			s.Type = got.Type | ld.SSUB
+			s.Type = got.Type
+			s.Attr |= sym.AttrSubSymbol
 			s.Outer = got
 			s.Sub = got.Sub
 			got.Sub = s
 			s.Value = got.Size
-			ld.Adduint32(ctxt, got, 0)
-			ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
+			got.AddUint32(ctxt.Arch, 0)
+			ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
 			r.Type = 256 // ignore during relocsym
 			return true
 		}
-
-		if ld.Headtype == objabi.Hwindows && s.Size == int64(ld.SysArch.PtrSize) {
-			// nothing to do, the relocation will be laid out in pereloc1
-			return true
-		}
 	}
 
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
-	ld.Thearch.Lput(uint32(sectoff))
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := r.Xsym.ElfsymForReloc()
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_386_32 | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_GOTPCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_386_GOTPC)
+			ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
 			if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
-				ld.Thearch.Lput(uint32(sectoff))
-				ld.Thearch.Lput(ld.R_386_GOT32 | uint32(elfsym)<<8)
+				ctxt.Out.Write32(uint32(sectoff))
+				ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
 			}
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_CALL:
 		if r.Siz == 4 {
-			if r.Xsym.Type == ld.SDYNIMPORT {
-				ld.Thearch.Lput(ld.R_386_PLT32 | uint32(elfsym)<<8)
+			if r.Xsym.Type == sym.SDYNIMPORT {
+				ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
 			} else {
-				ld.Thearch.Lput(ld.R_386_PC32 | uint32(elfsym)<<8)
+				ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
 			}
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_PCREL:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_386_PC32 | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_TLS_LE:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_386_TLS_LE | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
-
 	case objabi.R_TLS_IE:
 		if r.Siz == 4 {
-			ld.Thearch.Lput(ld.R_386_GOTPC)
-			ld.Thearch.Lput(uint32(sectoff))
-			ld.Thearch.Lput(ld.R_386_TLS_GOTIE | uint32(elfsym)<<8)
+			ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
+			ctxt.Out.Write32(uint32(sectoff))
+			ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
 		} else {
-			return -1
+			return false
 		}
 	}
 
-	return 0
+	return true
 }
 
-func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
 
-	if rs.Type == ld.SHOSTOBJ {
+	if rs.Type == sym.SHOSTOBJ {
 		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+			return false
 		}
 
 		v = uint32(rs.Dynid)
@@ -425,18 +420,16 @@
 	} else {
 		v = uint32(rs.Sect.Extnum)
 		if v == 0 {
-			ld.Errorf(s, "reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
-			return -1
+			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+			return false
 		}
 	}
 
 	switch r.Type {
 	default:
-		return -1
-
+		return false
 	case objabi.R_ADDR:
 		v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
-
 	case objabi.R_CALL,
 		objabi.R_PCREL:
 		v |= 1 << 24 // pc-relative bit
@@ -445,44 +438,40 @@
 
 	switch r.Siz {
 	default:
-		return -1
-
+		return false
 	case 1:
 		v |= 0 << 25
-
 	case 2:
 		v |= 1 << 25
-
 	case 4:
 		v |= 2 << 25
-
 	case 8:
 		v |= 3 << 25
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(v)
-	return 0
+	out.Write32(uint32(sectoff))
+	out.Write32(v)
+	return true
 }
 
-func pereloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
 
 	if rs.Dynid < 0 {
-		ld.Errorf(s, "reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
+		ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
 		return false
 	}
 
-	ld.Thearch.Lput(uint32(sectoff))
-	ld.Thearch.Lput(uint32(rs.Dynid))
+	out.Write32(uint32(sectoff))
+	out.Write32(uint32(rs.Dynid))
 
 	switch r.Type {
 	default:
 		return false
 
-	case objabi.R_DWARFREF:
+	case objabi.R_DWARFSECREF:
 		v = ld.IMAGE_REL_I386_SECREL
 
 	case objabi.R_ADDR:
@@ -493,29 +482,28 @@
 		v = ld.IMAGE_REL_I386_REL32
 	}
 
-	ld.Thearch.Wput(uint16(v))
+	out.Write16(uint16(v))
 
 	return true
 }
 
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
-	if ld.Linkmode == ld.LinkExternal {
-		return -1
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
+	if ctxt.LinkMode == ld.LinkExternal {
+		return false
 	}
 	switch r.Type {
 	case objabi.R_CONST:
 		*val = r.Add
-		return 0
-
+		return true
 	case objabi.R_GOTOFF:
 		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
-		return 0
+		return true
 	}
 
-	return -1
+	return false
 }
 
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return t
 }
@@ -525,36 +513,36 @@
 	got := ctxt.Syms.Lookup(".got.plt", 0)
 	if plt.Size == 0 {
 		// pushl got+4
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x35)
-		ld.Addaddrplus(ctxt, plt, got, 4)
+		plt.AddUint8(0x35)
+		plt.AddAddrPlus(ctxt.Arch, got, 4)
 
 		// jmp *got+8
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addaddrplus(ctxt, plt, got, 8)
+		plt.AddUint8(0x25)
+		plt.AddAddrPlus(ctxt.Arch, got, 8)
 
 		// zero pad
-		ld.Adduint32(ctxt, plt, 0)
+		plt.AddUint32(ctxt.Arch, 0)
 
 		// assume got->size == 0 too
-		ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
+		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
 
-		ld.Adduint32(ctxt, got, 0)
-		ld.Adduint32(ctxt, got, 0)
+		got.AddUint32(ctxt.Arch, 0)
+		got.AddUint32(ctxt.Arch, 0)
 	}
 }
 
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Plt >= 0 {
 		return
 	}
 
 	ld.Adddynsym(ctxt, s)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		plt := ctxt.Syms.Lookup(".plt", 0)
 		got := ctxt.Syms.Lookup(".got.plt", 0)
 		rel := ctxt.Syms.Lookup(".rel.plt", 0)
@@ -563,51 +551,51 @@
 		}
 
 		// jmpq *got+size
-		ld.Adduint8(ctxt, plt, 0xff)
+		plt.AddUint8(0xff)
 
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addaddrplus(ctxt, plt, got, got.Size)
+		plt.AddUint8(0x25)
+		plt.AddAddrPlus(ctxt.Arch, got, got.Size)
 
 		// add to got: pointer to current pos in plt
-		ld.Addaddrplus(ctxt, got, plt, plt.Size)
+		got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
 
 		// pushl $x
-		ld.Adduint8(ctxt, plt, 0x68)
+		plt.AddUint8(0x68)
 
-		ld.Adduint32(ctxt, plt, uint32(rel.Size))
+		plt.AddUint32(ctxt.Arch, uint32(rel.Size))
 
 		// jmp .plt
-		ld.Adduint8(ctxt, plt, 0xe9)
+		plt.AddUint8(0xe9)
 
-		ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
+		plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
 
 		// rel
-		ld.Addaddrplus(ctxt, rel, got, got.Size-4)
+		rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
 
-		ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT))
+		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
 
 		s.Plt = int32(plt.Size - 16)
-	} else if ld.Headtype == objabi.Hdarwin {
+	} else if ctxt.HeadType == objabi.Hdarwin {
 		// Same laziness as in 6l.
 
 		plt := ctxt.Syms.Lookup(".plt", 0)
 
 		addgotsym(ctxt, s)
 
-		ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.plt", 0), uint32(s.Dynid))
+		ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
 
 		// jmpq *got+size(IP)
 		s.Plt = int32(plt.Size)
 
-		ld.Adduint8(ctxt, plt, 0xff)
-		ld.Adduint8(ctxt, plt, 0x25)
-		ld.Addaddrplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
+		plt.AddUint8(0xff)
+		plt.AddUint8(0x25)
+		plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
 	} else {
 		ld.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
 
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
 	if s.Got >= 0 {
 		return
 	}
@@ -615,14 +603,14 @@
 	ld.Adddynsym(ctxt, s)
 	got := ctxt.Syms.Lookup(".got", 0)
 	s.Got = int32(got.Size)
-	ld.Adduint32(ctxt, got, 0)
+	got.AddUint32(ctxt.Arch, 0)
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		rel := ctxt.Syms.Lookup(".rel", 0)
-		ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
-		ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
-	} else if ld.Headtype == objabi.Hdarwin {
-		ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(s.Dynid))
+		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
+		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
+	} else if ctxt.HeadType == objabi.Hdarwin {
+		ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
 	} else {
 		ld.Errorf(s, "addgotsym: unsupported binary format")
 	}
@@ -633,16 +621,16 @@
 		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
 	}
 
-	if ld.Iself {
+	if ctxt.IsELF {
 		ld.Asmbelfsetup()
 	}
 
 	sect := ld.Segtext.Sections[0]
-	ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 	// 0xCC is INT $3 - breakpoint instruction
 	ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
 	for _, sect = range ld.Segtext.Sections[1:] {
-		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
 		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
 	}
 
@@ -651,14 +639,14 @@
 			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
 		}
 
-		ld.Cseek(int64(ld.Segrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
 	}
 	if ld.Segrelrodata.Filelen > 0 {
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
 		}
-		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
+		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
 		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
 	}
 
@@ -666,14 +654,14 @@
 		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
 	}
 
-	ld.Cseek(int64(ld.Segdata.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
 	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
 
-	ld.Cseek(int64(ld.Segdwarf.Fileoff))
+	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
 	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
 	machlink := uint32(0)
-	if ld.Headtype == objabi.Hdarwin {
+	if ctxt.HeadType == objabi.Hdarwin {
 		machlink = uint32(ld.Domacholink(ctxt))
 	}
 
@@ -686,9 +674,9 @@
 		if ctxt.Debugvlog != 0 {
 			ctxt.Logf("%5.2f sym\n", ld.Cputime())
 		}
-		switch ld.Headtype {
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
 				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
 			}
@@ -704,34 +692,31 @@
 			symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
 		}
 
-		ld.Cseek(int64(symo))
-		switch ld.Headtype {
+		ctxt.Out.SeekSet(int64(symo))
+		switch ctxt.HeadType {
 		default:
-			if ld.Iself {
+			if ctxt.IsELF {
 				if ctxt.Debugvlog != 0 {
 					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
 				}
 				ld.Asmelfsym(ctxt)
-				ld.Cflush()
-				ld.Cwrite(ld.Elfstrdat)
+				ctxt.Out.Flush()
+				ctxt.Out.Write(ld.Elfstrdat)
 
-				if ld.Linkmode == ld.LinkExternal {
+				if ctxt.LinkMode == ld.LinkExternal {
 					ld.Elfemitreloc(ctxt)
 				}
 			}
 
 		case objabi.Hplan9:
 			ld.Asmplan9sym(ctxt)
-			ld.Cflush()
+			ctxt.Out.Flush()
 
 			sym := ctxt.Syms.Lookup("pclntab", 0)
 			if sym != nil {
 				ld.Lcsize = int32(len(sym.P))
-				for i := 0; int32(i) < ld.Lcsize; i++ {
-					ld.Cput(sym.P[i])
-				}
-
-				ld.Cflush()
+				ctxt.Out.Write(sym.P)
+				ctxt.Out.Flush()
 			}
 
 		case objabi.Hwindows:
@@ -740,7 +725,7 @@
 			}
 
 		case objabi.Hdarwin:
-			if ld.Linkmode == ld.LinkExternal {
+			if ctxt.LinkMode == ld.LinkExternal {
 				ld.Machoemitreloc(ctxt)
 			}
 		}
@@ -749,20 +734,20 @@
 	if ctxt.Debugvlog != 0 {
 		ctxt.Logf("%5.2f headr\n", ld.Cputime())
 	}
-	ld.Cseek(0)
-	switch ld.Headtype {
+	ctxt.Out.SeekSet(0)
+	switch ctxt.HeadType {
 	default:
 	case objabi.Hplan9: /* plan9 */
 		magic := int32(4*11*11 + 7)
 
-		ld.Lputb(uint32(magic))              /* magic */
-		ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
-		ld.Lputb(uint32(ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ld.Lputb(uint32(ld.Symsize))          /* nsyms */
-		ld.Lputb(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ld.Lputb(uint32(ld.Spsize))           /* sp offsets */
-		ld.Lputb(uint32(ld.Lcsize))           /* line offsets */
+		ctxt.Out.Write32b(uint32(magic))              /* magic */
+		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
+		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+		ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
+		ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+		ctxt.Out.Write32b(uint32(ld.Spsize))           /* sp offsets */
+		ctxt.Out.Write32b(uint32(ld.Lcsize))           /* line offsets */
 
 	case objabi.Hdarwin:
 		ld.Asmbmacho(ctxt)
@@ -778,5 +763,5 @@
 		ld.Asmbpe(ctxt)
 	}
 
-	ld.Cflush()
+	ctxt.Out.Flush()
 }
diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go
index fa925d1..6a744dc 100644
--- a/src/cmd/link/internal/x86/obj.go
+++ b/src/cmd/link/internal/x86/obj.go
@@ -37,43 +37,41 @@
 	"fmt"
 )
 
-func Init() {
-	ld.SysArch = sys.Arch386
+func Init() (*sys.Arch, ld.Arch) {
+	arch := sys.Arch386
 
-	ld.Thearch.Funcalign = funcAlign
-	ld.Thearch.Maxalign = maxAlign
-	ld.Thearch.Minalign = minAlign
-	ld.Thearch.Dwarfregsp = dwarfRegSP
-	ld.Thearch.Dwarfreglr = dwarfRegLR
+	theArch := ld.Arch{
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
 
-	ld.Thearch.Adddynrel = adddynrel
-	ld.Thearch.Archinit = archinit
-	ld.Thearch.Archreloc = archreloc
-	ld.Thearch.Archrelocvariant = archrelocvariant
-	ld.Thearch.Asmb = asmb
-	ld.Thearch.Elfreloc1 = elfreloc1
-	ld.Thearch.Elfsetupplt = elfsetupplt
-	ld.Thearch.Gentext = gentext
-	ld.Thearch.Machoreloc1 = machoreloc1
-	ld.Thearch.PEreloc1 = pereloc1
-	ld.Thearch.Lput = ld.Lputl
-	ld.Thearch.Wput = ld.Wputl
-	ld.Thearch.Vput = ld.Vputl
-	ld.Thearch.Append16 = ld.Append16l
-	ld.Thearch.Append32 = ld.Append32l
-	ld.Thearch.Append64 = ld.Append64l
+		Adddynrel:        adddynrel,
+		Archinit:         archinit,
+		Archreloc:        archreloc,
+		Archrelocvariant: archrelocvariant,
+		Asmb:             asmb,
+		Elfreloc1:        elfreloc1,
+		Elfsetupplt:      elfsetupplt,
+		Gentext:          gentext,
+		Machoreloc1:      machoreloc1,
+		PEreloc1:         pereloc1,
 
-	ld.Thearch.Linuxdynld = "/lib/ld-linux.so.2"
-	ld.Thearch.Freebsddynld = "/usr/libexec/ld-elf.so.1"
-	ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
-	ld.Thearch.Netbsddynld = "/usr/libexec/ld.elf_so"
-	ld.Thearch.Solarisdynld = "/lib/ld.so.1"
+		Linuxdynld:   "/lib/ld-linux.so.2",
+		Freebsddynld: "/usr/libexec/ld-elf.so.1",
+		Openbsddynld: "/usr/libexec/ld.so",
+		Netbsddynld:  "/usr/libexec/ld.elf_so",
+		Solarisdynld: "/lib/ld.so.1",
+	}
+
+	return arch, theArch
 }
 
 func archinit(ctxt *ld.Link) {
-	switch ld.Headtype {
+	switch ctxt.HeadType {
 	default:
-		ld.Exitf("unknown -H option: %v", ld.Headtype)
+		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
 
 	case objabi.Hplan9: /* plan 9 */
 		ld.HEADR = 32
@@ -89,8 +87,6 @@
 		}
 
 	case objabi.Hdarwin: /* apple MACH */
-		ld.Machoinit()
-
 		ld.HEADR = ld.INITIAL_MACHO_HEADR
 		if *ld.FlagTextAddr == -1 {
 			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 4ef1845..4ec03ab 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -1,6 +1,13 @@
 package main
 
-import "testing"
+import (
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
 
 var AuthorPaidByTheColumnInch struct {
 	fog int `
@@ -28,3 +35,38 @@
 	// the bufio buffer. Issue #15104.
 	_ = AuthorPaidByTheColumnInch
 }
+
+func TestIssue21703(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	const source = `
+package main
+const X = "\n!\n"
+func main() {}
+`
+
+	tmpdir, err := ioutil.TempDir("", "issue21703")
+	if err != nil {
+		t.Fatalf("failed to create temp dir: %v\n", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	err = ioutil.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
+	if err != nil {
+		t.Fatalf("failed to write main.go: %v\n", err)
+	}
+
+	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "main.go")
+	cmd.Dir = tmpdir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to compile main.go: %v, output: %s\n", err, out)
+	}
+
+	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "main.o")
+	cmd.Dir = tmpdir
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to link main.o: %v, output: %s\n", err, out)
+	}
+}
diff --git a/src/cmd/link/main.go b/src/cmd/link/main.go
index eab190d..6bc9b5d 100644
--- a/src/cmd/link/main.go
+++ b/src/cmd/link/main.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/sys"
 	"cmd/link/internal/amd64"
 	"cmd/link/internal/arm"
 	"cmd/link/internal/arm64"
@@ -26,7 +27,7 @@
 //
 // Before any argument parsing is done, the Init function of relevant
 // architecture package is called. The only job done in Init is
-// configuration of the ld.Thearch and ld.SysArch variables.
+// configuration of the architecture-specific variables.
 //
 // Then control flow passes to ld.Main, which parses flags, makes
 // some configuration decisions, and then gives the architecture
@@ -34,26 +35,29 @@
 // via the ld.Thearch.Archinit function.
 
 func main() {
+	var arch *sys.Arch
+	var theArch ld.Arch
+
 	switch objabi.GOARCH {
 	default:
 		fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", objabi.GOARCH)
 		os.Exit(2)
 	case "386":
-		x86.Init()
+		arch, theArch = x86.Init()
 	case "amd64", "amd64p32":
-		amd64.Init()
+		arch, theArch = amd64.Init()
 	case "arm":
-		arm.Init()
+		arch, theArch = arm.Init()
 	case "arm64":
-		arm64.Init()
+		arch, theArch = arm64.Init()
 	case "mips", "mipsle":
-		mips.Init()
+		arch, theArch = mips.Init()
 	case "mips64", "mips64le":
-		mips64.Init()
+		arch, theArch = mips64.Init()
 	case "ppc64", "ppc64le":
-		ppc64.Init()
+		arch, theArch = ppc64.Init()
 	case "s390x":
-		s390x.Init()
+		arch, theArch = s390x.Init()
 	}
-	ld.Main()
+	ld.Main(arch, theArch)
 }
diff --git a/src/cmd/nm/nm.go b/src/cmd/nm/nm.go
index 2e2dd75..4572399 100644
--- a/src/cmd/nm/nm.go
+++ b/src/cmd/nm/nm.go
@@ -106,41 +106,62 @@
 	}
 	defer f.Close()
 
-	syms, err := f.Symbols()
-	if err != nil {
-		errorf("reading %s: %v", file, err)
+	w := bufio.NewWriter(os.Stdout)
+
+	entries := f.Entries()
+
+	var found bool
+
+	for _, e := range entries {
+		syms, err := e.Symbols()
+		if err != nil {
+			errorf("reading %s: %v", file, err)
+		}
+		if len(syms) == 0 {
+			continue
+		}
+
+		found = true
+
+		switch *sortOrder {
+		case "address":
+			sort.Slice(syms, func(i, j int) bool { return syms[i].Addr < syms[j].Addr })
+		case "name":
+			sort.Slice(syms, func(i, j int) bool { return syms[i].Name < syms[j].Name })
+		case "size":
+			sort.Slice(syms, func(i, j int) bool { return syms[i].Size > syms[j].Size })
+		}
+
+		for _, sym := range syms {
+			if len(entries) > 1 {
+				name := e.Name()
+				if name == "" {
+					fmt.Fprintf(w, "%s(%s):\t", file, "_go_.o")
+				} else {
+					fmt.Fprintf(w, "%s(%s):\t", file, name)
+				}
+			} else if filePrefix {
+				fmt.Fprintf(w, "%s:\t", file)
+			}
+			if sym.Code == 'U' {
+				fmt.Fprintf(w, "%8s", "")
+			} else {
+				fmt.Fprintf(w, "%8x", sym.Addr)
+			}
+			if *printSize {
+				fmt.Fprintf(w, " %10d", sym.Size)
+			}
+			fmt.Fprintf(w, " %c %s", sym.Code, sym.Name)
+			if *printType && sym.Type != "" {
+				fmt.Fprintf(w, " %s", sym.Type)
+			}
+			fmt.Fprintf(w, "\n")
+		}
 	}
-	if len(syms) == 0 {
+
+	if !found {
 		errorf("reading %s: no symbols", file)
 	}
 
-	switch *sortOrder {
-	case "address":
-		sort.Slice(syms, func(i, j int) bool { return syms[i].Addr < syms[j].Addr })
-	case "name":
-		sort.Slice(syms, func(i, j int) bool { return syms[i].Name < syms[j].Name })
-	case "size":
-		sort.Slice(syms, func(i, j int) bool { return syms[i].Size > syms[j].Size })
-	}
-
-	w := bufio.NewWriter(os.Stdout)
-	for _, sym := range syms {
-		if filePrefix {
-			fmt.Fprintf(w, "%s:\t", file)
-		}
-		if sym.Code == 'U' {
-			fmt.Fprintf(w, "%8s", "")
-		} else {
-			fmt.Fprintf(w, "%8x", sym.Addr)
-		}
-		if *printSize {
-			fmt.Fprintf(w, " %10d", sym.Size)
-		}
-		fmt.Fprintf(w, " %c %s", sym.Code, sym.Name)
-		if *printType && sym.Type != "" {
-			fmt.Fprintf(w, " %s", sym.Type)
-		}
-		fmt.Fprintf(w, "\n")
-	}
 	w.Flush()
 }
diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go
index de16f77..1dfdf7f 100644
--- a/src/cmd/nm/nm_cgo_test.go
+++ b/src/cmd/nm/nm_cgo_test.go
@@ -11,26 +11,30 @@
 	"testing"
 )
 
-func TestInternalLinkerCgoFile(t *testing.T) {
-	if !canInternalLink() {
-		t.Skip("skipping; internal linking is not supported")
-	}
-	testGoFile(t, true, false)
-}
-
 func canInternalLink() bool {
 	switch runtime.GOOS {
 	case "dragonfly":
 		return false
 	case "linux":
 		switch runtime.GOARCH {
-		case "arm64", "mips64", "mips64le", "mips", "mipsle":
+		case "arm64", "mips64", "mips64le", "mips", "mipsle", "ppc64", "ppc64le":
 			return false
 		}
 	}
 	return true
 }
 
-func TestExternalLinkerCgoFile(t *testing.T) {
-	testGoFile(t, true, true)
+func TestInternalLinkerCgoExec(t *testing.T) {
+	if !canInternalLink() {
+		t.Skip("skipping; internal linking is not supported")
+	}
+	testGoExec(t, true, false)
+}
+
+func TestExternalLinkerCgoExec(t *testing.T) {
+	testGoExec(t, true, true)
+}
+
+func TestCgoLib(t *testing.T) {
+	testGoLib(t, true)
 }
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index 170d87a..4be5d0e 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -54,7 +54,7 @@
 	return m.Run()
 }
 
-func TestNonGoFiles(t *testing.T) {
+func TestNonGoExecs(t *testing.T) {
 	testfiles := []string{
 		"elf/testdata/gcc-386-freebsd-exec",
 		"elf/testdata/gcc-amd64-linux-exec",
@@ -75,8 +75,8 @@
 	}
 }
 
-func testGoFile(t *testing.T, iscgo, isexternallinker bool) {
-	tmpdir, err := ioutil.TempDir("", "TestGoFile")
+func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
+	tmpdir, err := ioutil.TempDir("", "TestGoExec")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -87,12 +87,13 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	err = template.Must(template.New("main").Parse(testprog)).Execute(file, iscgo)
+	err = template.Must(template.New("main").Parse(testexec)).Execute(file, iscgo)
+	if e := file.Close(); err == nil {
+		err = e
+	}
 	if err != nil {
-		file.Close()
 		t.Fatal(err)
 	}
-	file.Close()
 
 	exe := filepath.Join(tmpdir, "a.exe")
 	args := []string{"build", "-o", exe}
@@ -156,11 +157,124 @@
 	}
 }
 
-func TestGoFile(t *testing.T) {
-	testGoFile(t, false, false)
+func TestGoExec(t *testing.T) {
+	testGoExec(t, false, false)
 }
 
-const testprog = `
+func testGoLib(t *testing.T, iscgo bool) {
+	tmpdir, err := ioutil.TempDir("", "TestGoLib")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	gopath := filepath.Join(tmpdir, "gopath")
+	libpath := filepath.Join(gopath, "src", "mylib")
+
+	err = os.MkdirAll(libpath, 0777)
+	if err != nil {
+		t.Fatal(err)
+	}
+	src := filepath.Join(libpath, "a.go")
+	file, err := os.Create(src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, iscgo)
+	if e := file.Close(); err == nil {
+		err = e
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	args := []string{"install", "mylib"}
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	cmd.Env = append(os.Environ(), "GOPATH="+gopath)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("building test lib failed: %s %s", err, out)
+	}
+	pat := filepath.Join(gopath, "pkg", "*", "mylib.a")
+	ms, err := filepath.Glob(pat)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(ms) == 0 {
+		t.Fatalf("cannot found paths for pattern %s", pat)
+	}
+	mylib := ms[0]
+
+	out, err = exec.Command(testnmpath, mylib).CombinedOutput()
+	if err != nil {
+		t.Fatalf("go tool nm: %v\n%s", err, string(out))
+	}
+	type symType struct {
+		Type  string
+		Name  string
+		CSym  bool
+		Found bool
+	}
+	var syms = []symType{
+		{"B", "%22%22.Testdata", false, false},
+		{"T", "%22%22.Testfunc", false, false},
+	}
+	if iscgo {
+		syms = append(syms, symType{"B", "%22%22.TestCgodata", false, false})
+		syms = append(syms, symType{"T", "%22%22.TestCgofunc", false, false})
+		if runtime.GOOS == "darwin" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") {
+			syms = append(syms, symType{"D", "_cgodata", true, false})
+			syms = append(syms, symType{"T", "_cgofunc", true, false})
+		} else {
+			syms = append(syms, symType{"D", "cgodata", true, false})
+			syms = append(syms, symType{"T", "cgofunc", true, false})
+		}
+	}
+	scanner := bufio.NewScanner(bytes.NewBuffer(out))
+	for scanner.Scan() {
+		f := strings.Fields(scanner.Text())
+		var typ, name string
+		var csym bool
+		if iscgo {
+			if len(f) < 4 {
+				continue
+			}
+			csym = !strings.Contains(f[0], "_go_.o")
+			typ = f[2]
+			name = f[3]
+		} else {
+			if len(f) < 3 {
+				continue
+			}
+			typ = f[1]
+			name = f[2]
+		}
+		for i := range syms {
+			sym := &syms[i]
+			if sym.Type == typ && sym.Name == name && sym.CSym == csym {
+				if sym.Found {
+					t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name)
+				}
+				sym.Found = true
+			}
+		}
+	}
+	err = scanner.Err()
+	if err != nil {
+		t.Fatalf("error reading nm output: %v", err)
+	}
+	for _, sym := range syms {
+		if !sym.Found {
+			t.Errorf("cannot found symbol %s %s", sym.Type, sym.Name)
+		}
+	}
+}
+
+func TestGoLib(t *testing.T) {
+	testGoLib(t, false)
+}
+
+const testexec = `
 package main
 
 import "fmt"
@@ -179,3 +293,23 @@
 	fmt.Printf("testdata=%p\n", &testdata)
 }
 `
+
+const testlib = `
+package mylib
+
+{{if .}}
+// int cgodata = 5;
+// void cgofunc(void) {}
+import "C"
+
+var TestCgodata = C.cgodata
+
+func TestCgofunc() {
+	C.cgofunc()
+}
+{{end}}
+
+var Testdata uint32
+
+func Testfunc() {}
+`
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index 47e51df..a2ca329 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -63,7 +63,7 @@
 }
 
 var armNeed = []string{
-	//"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021
+	"B main.main(SB)",
 	"BL main.Println(SB)",
 	"RET",
 }
@@ -148,6 +148,13 @@
 			ok = false
 		}
 	}
+	if goarch == "386" {
+		if strings.Contains(text, "(IP)") {
+			t.Errorf("disassembly contains PC-Relative addressing on 386")
+			ok = false
+		}
+	}
+
 	if !ok {
 		t.Logf("full disassembly:\n%s", text)
 	}
@@ -155,8 +162,6 @@
 
 func TestDisasm(t *testing.T) {
 	switch runtime.GOARCH {
-	case "arm64":
-		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
 	case "mips", "mipsle", "mips64", "mips64le":
 		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
 	case "s390x":
@@ -167,8 +172,6 @@
 
 func TestDisasmCode(t *testing.T) {
 	switch runtime.GOARCH {
-	case "arm64":
-		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
 	case "mips", "mipsle", "mips64", "mips64le":
 		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
 	case "s390x":
@@ -185,8 +188,6 @@
 	switch runtime.GOARCH {
 	case "ppc64":
 		t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH)
-	case "arm64":
-		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
 	case "mips64", "mips64le", "mips", "mipsle":
 		t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH)
 	case "s390x":
@@ -204,10 +205,6 @@
 
 func TestDisasmGoobj(t *testing.T) {
 	switch runtime.GOARCH {
-	case "arm":
-		t.Skipf("skipping on %s, issue 19811", runtime.GOARCH)
-	case "arm64":
-		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
 	case "mips", "mipsle", "mips64", "mips64le":
 		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
 	case "s390x":
@@ -244,6 +241,12 @@
 			ok = false
 		}
 	}
+	if runtime.GOARCH == "386" {
+		if strings.Contains(text, "(IP)") {
+			t.Errorf("disassembly contains PC-Relative addressing on 386")
+			ok = false
+		}
+	}
 	if !ok {
 		t.Logf("full disassembly:\n%s", text)
 	}
diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go
index 1c168f9..3abc83e 100644
--- a/src/cmd/pack/pack.go
+++ b/src/cmd/pack/pack.go
@@ -426,8 +426,15 @@
 	// Read from file, collecting header for __.PKGDEF.
 	// The header is from the beginning of the file until a line
 	// containing just "!". The first line must begin with "go object ".
+	//
+	// Note: It's possible for "\n!\n" to appear within the binary
+	// package export data format. To avoid truncating the package
+	// definition prematurely (issue 21703), we keep keep track of
+	// how many "$$" delimiters we've seen.
+
 	rbuf := bufio.NewReader(f)
 	var wbuf bytes.Buffer
+	markers := 0
 	for {
 		line, err := rbuf.ReadBytes('\n')
 		if err != nil {
@@ -436,9 +443,12 @@
 		if wbuf.Len() == 0 && !bytes.HasPrefix(line, []byte("go object ")) {
 			return nil, errors.New("not a Go object file")
 		}
-		if bytes.Equal(line, []byte("!\n")) {
+		if markers%2 == 0 && bytes.Equal(line, []byte("!\n")) {
 			break
 		}
+		if bytes.HasPrefix(line, []byte("$$")) {
+			markers++
+		}
 		wbuf.Write(line)
 	}
 	return wbuf.Bytes(), nil
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index 79d9cde..b2217c0 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -295,6 +295,37 @@
 	}
 }
 
+// Test that "\n!\n" inside export data doesn't result in a truncated
+// package definition when creating a .a archive from a .o Go object.
+func TestIssue21703(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	dir := tmpDir(t)
+	defer os.RemoveAll(dir)
+
+	const aSrc = `package a; const X = "\n!\n"`
+	err := ioutil.WriteFile(filepath.Join(dir, "a.go"), []byte(aSrc), 0666)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	const bSrc = `package b; import _ "a"`
+	err = ioutil.WriteFile(filepath.Join(dir, "b.go"), []byte(bSrc), 0666)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	run := func(args ...string) string {
+		return doRun(t, dir, args...)
+	}
+
+	goBin := testenv.GoToolPath(t)
+	run(goBin, "build", "cmd/pack") // writes pack binary to dir
+	run(goBin, "tool", "compile", "a.go")
+	run("./pack", "c", "a.a", "a.o")
+	run(goBin, "tool", "compile", "-I", ".", "b.go")
+}
+
 // doRun runs a program in a directory and returns the output.
 func doRun(t *testing.T, dir string, args ...string) string {
 	cmd := exec.Command(args[0], args[1:]...)
diff --git a/src/cmd/test2json/main.go b/src/cmd/test2json/main.go
new file mode 100644
index 0000000..654c00a
--- /dev/null
+++ b/src/cmd/test2json/main.go
@@ -0,0 +1,140 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test2json converts go test output to a machine-readable JSON stream.
+//
+// Usage:
+//
+//	go tool test2json [-p pkg] [-t] [./pkg.test -test.v]
+//
+// Test2json runs the given test command and converts its output to JSON;
+// with no command specified, test2json expects test output on standard input.
+// It writes a corresponding stream of JSON events to standard output.
+// There is no unnecessary input or output buffering, so that
+// the JSON stream can be read for “live updates” of test status.
+//
+// The -p flag sets the package reported in each test event.
+//
+// The -t flag requests that time stamps be added to each test event.
+//
+// Note that test2json is only intended for converting a single test
+// binary's output. To convert the output of a "go test" command,
+// use "go test -json" instead of invoking test2json directly.
+//
+// Output Format
+//
+// The JSON stream is a newline-separated sequence of TestEvent objects
+// corresponding to the Go struct:
+//
+//	type TestEvent struct {
+//		Time    time.Time // encodes as an RFC3339-format string
+//		Action  string
+//		Package string
+//		Test    string
+//		Elapsed float64 // seconds
+//		Output  string
+//	}
+//
+// The Time field holds the time the event happened.
+// It is conventionally omitted for cached test results.
+//
+// The Action field is one of a fixed set of action descriptions:
+//
+//	run    - the test has started running
+//	pause  - the test has been paused
+//	cont   - the test has continued running
+//	pass   - the test passed
+//	bench  - the benchmark printed log output but did not fail
+//	fail   - the test or benchmark failed
+//	output - the test printed output
+//
+// The Package field, if present, specifies the package being tested.
+// When the go command runs parallel tests in -json mode, events from
+// different tests are interlaced; the Package field allows readers to
+// separate them.
+//
+// The Test field, if present, specifies the test, example, or benchmark
+// function that caused the event. Events for the overall package test
+// do not set Test.
+//
+// The Elapsed field is set for "pass" and "fail" events. It gives the time
+// elapsed for the specific test or the overall package test that passed or failed.
+//
+// The Output field is set for Action == "output" and is a portion of the test's output
+// (standard output and standard error merged together). The output is
+// unmodified except that invalid UTF-8 output from a test is coerced
+// into valid UTF-8 by use of replacement characters. With that one exception,
+// the concatenation of the Output fields of all output events is the exact
+// output of the test execution.
+//
+// When a benchmark runs, it typically produces a single line of output
+// giving timing results. That line is reported in an event with Action == "output"
+// and no Test field. If a benchmark logs output or reports a failure
+// (for example, by using b.Log or b.Error), that extra output is reported
+// as a sequence of events with Test set to the benchmark name, terminated
+// by a final event with Action == "bench" or "fail".
+// Benchmarks have no events with Action == "run", "pause", or "cont".
+//
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+
+	"cmd/internal/test2json"
+)
+
+var (
+	flagP = flag.String("p", "", "report `pkg` as the package being tested in each event")
+	flagT = flag.Bool("t", false, "include timestamps in events")
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: go tool test2json [-p pkg] [-t] [./pkg.test -test.v]\n")
+	os.Exit(2)
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	var mode test2json.Mode
+	if *flagT {
+		mode |= test2json.Timestamp
+	}
+	c := test2json.NewConverter(os.Stdout, *flagP, mode)
+	defer c.Close()
+
+	if flag.NArg() == 0 {
+		io.Copy(c, os.Stdin)
+	} else {
+		args := flag.Args()
+		cmd := exec.Command(args[0], args[1:]...)
+		w := &countWriter{0, c}
+		cmd.Stdout = w
+		cmd.Stderr = w
+		if err := cmd.Run(); err != nil {
+			if w.n > 0 {
+				// Assume command printed why it failed.
+			} else {
+				fmt.Fprintf(c, "test2json: %v\n", err)
+			}
+			c.Close()
+			os.Exit(1)
+		}
+	}
+}
+
+type countWriter struct {
+	n int64
+	w io.Writer
+}
+
+func (w *countWriter) Write(b []byte) (int, error) {
+	w.n += int64(len(b))
+	return w.w.Write(b)
+}
diff --git a/src/cmd/trace/goroutines.go b/src/cmd/trace/goroutines.go
index f5a4ddb..d0d428c 100644
--- a/src/cmd/trace/goroutines.go
+++ b/src/cmd/trace/goroutines.go
@@ -121,13 +121,16 @@
 	analyzeGoroutines(events)
 	var glist gdescList
 	for _, g := range gs {
-		if g.PC != pc || g.ExecTime == 0 {
+		if g.PC != pc {
 			continue
 		}
 		glist = append(glist, g)
 	}
 	sort.Sort(glist)
-	err = templGoroutine.Execute(w, glist)
+	err = templGoroutine.Execute(w, struct {
+		PC    uint64
+		GList gdescList
+	}{pc, glist})
 	if err != nil {
 		http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
 		return
@@ -142,14 +145,14 @@
 <th> Goroutine </th>
 <th> Total time, ns </th>
 <th> Execution time, ns </th>
-<th> Network wait time, ns </th>
-<th> Sync block time, ns </th>
-<th> Blocking syscall time, ns </th>
-<th> Scheduler wait time, ns </th>
+<th> <a href="/io?id={{.PC}}">Network wait time, ns</a><a href="/io?id={{.PC}}&raw=1" download="io.profile">⬇</a> </th>
+<th> <a href="/block?id={{.PC}}">Sync block time, ns</a><a href="/block?id={{.PC}}&raw=1" download="block.profile">⬇</a> </th>
+<th> <a href="/syscall?id={{.PC}}">Blocking syscall time, ns</a><a href="/syscall?id={{.PC}}&raw=1" download="syscall.profile">⬇</a> </th>
+<th> <a href="/sched?id={{.PC}}">Scheduler wait time, ns</a><a href="/sched?id={{.PC}}&raw=1" download="sched.profile">⬇</a> </th>
 <th> GC sweeping time, ns </th>
 <th> GC pause time, ns </th>
 </tr>
-{{range $}}
+{{range .GList}}
   <tr>
     <td> <a href="/trace?goid={{.ID}}">{{.ID}}</a> </td>
     <td> {{.TotalTime}} </td>
diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go
index 8ea0ba0..d386715 100644
--- a/src/cmd/trace/main.go
+++ b/src/cmd/trace/main.go
@@ -42,6 +42,7 @@
 Flags:
 	-http=addr: HTTP service address (e.g., ':6060')
 	-pprof=type: print a pprof-like profile instead
+	-d: print debug info such as parsed events
 
 Note that while the various profiles available when launching
 'go tool trace' work on every browser, the trace viewer itself
@@ -52,6 +53,7 @@
 var (
 	httpFlag  = flag.String("http", "localhost:0", "HTTP service address (e.g., ':6060')")
 	pprofFlag = flag.String("pprof", "", "print a pprof-like profile instead")
+	debugFlag = flag.Bool("d", false, "print debug information such as parsed events list")
 
 	// The binary file name, left here for serveSVGProfile.
 	programBinary string
@@ -77,7 +79,7 @@
 		flag.Usage()
 	}
 
-	var pprofFunc func(io.Writer) error
+	var pprofFunc func(io.Writer, string) error
 	switch *pprofFlag {
 	case "net":
 		pprofFunc = pprofIO
@@ -89,7 +91,7 @@
 		pprofFunc = pprofSched
 	}
 	if pprofFunc != nil {
-		if err := pprofFunc(os.Stdout); err != nil {
+		if err := pprofFunc(os.Stdout, ""); err != nil {
 			dief("failed to generate pprof: %v\n", err)
 		}
 		os.Exit(0)
@@ -103,15 +105,20 @@
 		dief("failed to create server socket: %v\n", err)
 	}
 
-	log.Printf("Parsing trace...")
-	events, err := parseEvents()
+	log.Print("Parsing trace...")
+	res, err := parseTrace()
 	if err != nil {
 		dief("%v\n", err)
 	}
 
-	log.Printf("Serializing trace...")
+	if *debugFlag {
+		trace.Print(res.Events)
+		os.Exit(0)
+	}
+
+	log.Print("Serializing trace...")
 	params := &traceParams{
-		events:  events,
+		parsed:  res,
 		endTime: int64(1<<63 - 1),
 	}
 	data, err := generateTrace(params)
@@ -119,13 +126,12 @@
 		dief("%v\n", err)
 	}
 
-	log.Printf("Splitting trace...")
+	log.Print("Splitting trace...")
 	ranges = splitTrace(data)
 
-	log.Printf("Opening browser")
-	if !browser.Open("http://" + ln.Addr().String()) {
-		fmt.Fprintf(os.Stderr, "Trace viewer is listening on http://%s\n", ln.Addr().String())
-	}
+	addr := "http://" + ln.Addr().String()
+	log.Printf("Opening browser. Trace viewer is listening on %s", addr)
+	browser.Open(addr)
 
 	// Start http server.
 	http.HandleFunc("/", httpMain)
@@ -136,12 +142,22 @@
 var ranges []Range
 
 var loader struct {
-	once   sync.Once
-	events []*trace.Event
-	err    error
+	once sync.Once
+	res  trace.ParseResult
+	err  error
 }
 
+// parseEvents is a compatibility wrapper that returns only
+// the Events part of trace.ParseResult returned by parseTrace.
 func parseEvents() ([]*trace.Event, error) {
+	res, err := parseTrace()
+	if err != nil {
+		return nil, err
+	}
+	return res.Events, err
+}
+
+func parseTrace() (trace.ParseResult, error) {
 	loader.once.Do(func() {
 		tracef, err := os.Open(traceFile)
 		if err != nil {
@@ -151,14 +167,14 @@
 		defer tracef.Close()
 
 		// Parse and symbolize.
-		events, err := trace.Parse(bufio.NewReader(tracef), programBinary)
+		res, err := trace.Parse(bufio.NewReader(tracef), programBinary)
 		if err != nil {
 			loader.err = fmt.Errorf("failed to parse trace: %v", err)
 			return
 		}
-		loader.events = events
+		loader.res = res
 	})
-	return loader.events, loader.err
+	return loader.res, loader.err
 }
 
 // httpMain serves the starting page.
@@ -181,10 +197,10 @@
 	<a href="/trace">View trace</a><br>
 {{end}}
 <a href="/goroutines">Goroutine analysis</a><br>
-<a href="/io">Network blocking profile</a><br>
-<a href="/block">Synchronization blocking profile</a><br>
-<a href="/syscall">Syscall blocking profile</a><br>
-<a href="/sched">Scheduler latency profile</a><br>
+<a href="/io">Network blocking profile</a> (<a href="/io?raw=1" download="io.profile">⬇</a>)<br>
+<a href="/block">Synchronization blocking profile</a> (<a href="/block?raw=1" download="block.profile">⬇</a>)<br>
+<a href="/syscall">Syscall blocking profile</a> (<a href="/syscall?raw=1" download="syscall.profile">⬇</a>)<br>
+<a href="/sched">Scheduler latency profile</a> (<a href="/sche?raw=1" download="sched.profile">⬇</a>)<br>
 </body>
 </html>
 `))
diff --git a/src/cmd/trace/pprof.go b/src/cmd/trace/pprof.go
index 40803ac..cac36e8 100644
--- a/src/cmd/trace/pprof.go
+++ b/src/cmd/trace/pprof.go
@@ -15,10 +15,25 @@
 	"net/http"
 	"os"
 	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
 
 	"github.com/google/pprof/profile"
 )
 
+func goCmd() string {
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
+	if _, err := os.Stat(path); err == nil {
+		return path
+	}
+	return "go"
+}
+
 func init() {
 	http.HandleFunc("/io", serveSVGProfile(pprofIO))
 	http.HandleFunc("/block", serveSVGProfile(pprofBlock))
@@ -33,17 +48,54 @@
 	time int64
 }
 
-// pprofIO generates IO pprof-like profile (time spent in IO wait).
-func pprofIO(w io.Writer) error {
+// pprofMatchingGoroutines parses the goroutine type id string (i.e. pc)
+// and returns the ids of goroutines of the matching type.
+// If the id string is empty, returns nil without an error.
+func pprofMatchingGoroutines(id string, events []*trace.Event) (map[uint64]bool, error) {
+	if id == "" {
+		return nil, nil
+	}
+	pc, err := strconv.ParseUint(id, 10, 64) // id is string
+	if err != nil {
+		return nil, fmt.Errorf("invalid goroutine type: %v", id)
+	}
+	analyzeGoroutines(events)
+	var res map[uint64]bool
+	for _, g := range gs {
+		if g.PC != pc {
+			continue
+		}
+		if res == nil {
+			res = make(map[uint64]bool)
+		}
+		res[g.ID] = true
+	}
+	if len(res) == 0 && id != "" {
+		return nil, fmt.Errorf("failed to find matching goroutines for id: %s", id)
+	}
+	return res, nil
+}
+
+// pprofIO generates IO pprof-like profile (time spent in IO wait,
+// currently only network blocking event).
+func pprofIO(w io.Writer, id string) error {
 	events, err := parseEvents()
 	if err != nil {
 		return err
 	}
+	goroutines, err := pprofMatchingGoroutines(id, events)
+	if err != nil {
+		return err
+	}
+
 	prof := make(map[uint64]Record)
 	for _, ev := range events {
 		if ev.Type != trace.EvGoBlockNet || ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 {
 			continue
 		}
+		if goroutines != nil && !goroutines[ev.G] {
+			continue
+		}
 		rec := prof[ev.StkID]
 		rec.stk = ev.Stk
 		rec.n++
@@ -54,22 +106,33 @@
 }
 
 // pprofBlock generates blocking pprof-like profile (time spent blocked on synchronization primitives).
-func pprofBlock(w io.Writer) error {
+func pprofBlock(w io.Writer, id string) error {
 	events, err := parseEvents()
 	if err != nil {
 		return err
 	}
+	goroutines, err := pprofMatchingGoroutines(id, events)
+	if err != nil {
+		return err
+	}
+
 	prof := make(map[uint64]Record)
 	for _, ev := range events {
 		switch ev.Type {
 		case trace.EvGoBlockSend, trace.EvGoBlockRecv, trace.EvGoBlockSelect,
 			trace.EvGoBlockSync, trace.EvGoBlockCond, trace.EvGoBlockGC:
+			// TODO(hyangah): figure out why EvGoBlockGC should be here.
+			// EvGoBlockGC indicates the goroutine blocks on GC assist, not
+			// on synchronization primitives.
 		default:
 			continue
 		}
 		if ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 {
 			continue
 		}
+		if goroutines != nil && !goroutines[ev.G] {
+			continue
+		}
 		rec := prof[ev.StkID]
 		rec.stk = ev.Stk
 		rec.n++
@@ -80,16 +143,25 @@
 }
 
 // pprofSyscall generates syscall pprof-like profile (time spent blocked in syscalls).
-func pprofSyscall(w io.Writer) error {
+func pprofSyscall(w io.Writer, id string) error {
+
 	events, err := parseEvents()
 	if err != nil {
 		return err
 	}
+	goroutines, err := pprofMatchingGoroutines(id, events)
+	if err != nil {
+		return err
+	}
+
 	prof := make(map[uint64]Record)
 	for _, ev := range events {
 		if ev.Type != trace.EvGoSysCall || ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 {
 			continue
 		}
+		if goroutines != nil && !goroutines[ev.G] {
+			continue
+		}
 		rec := prof[ev.StkID]
 		rec.stk = ev.Stk
 		rec.n++
@@ -101,17 +173,25 @@
 
 // pprofSched generates scheduler latency pprof-like profile
 // (time between a goroutine become runnable and actually scheduled for execution).
-func pprofSched(w io.Writer) error {
+func pprofSched(w io.Writer, id string) error {
 	events, err := parseEvents()
 	if err != nil {
 		return err
 	}
+	goroutines, err := pprofMatchingGoroutines(id, events)
+	if err != nil {
+		return err
+	}
+
 	prof := make(map[uint64]Record)
 	for _, ev := range events {
 		if (ev.Type != trace.EvGoUnblock && ev.Type != trace.EvGoCreate) ||
 			ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 {
 			continue
 		}
+		if goroutines != nil && !goroutines[ev.G] {
+			continue
+		}
 		rec := prof[ev.StkID]
 		rec.stk = ev.Stk
 		rec.n++
@@ -122,8 +202,20 @@
 }
 
 // serveSVGProfile serves pprof-like profile generated by prof as svg.
-func serveSVGProfile(prof func(w io.Writer) error) http.HandlerFunc {
+func serveSVGProfile(prof func(w io.Writer, id string) error) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
+
+		if r.FormValue("raw") != "" {
+			w.Header().Set("Content-Type", "application/octet-stream")
+			if err := prof(w, r.FormValue("id")); err != nil {
+				w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+				w.Header().Set("X-Go-Pprof", "1")
+				http.Error(w, fmt.Sprintf("failed to get profile: %v", err), http.StatusInternalServerError)
+				return
+			}
+			return
+		}
+
 		blockf, err := ioutil.TempFile("", "block")
 		if err != nil {
 			http.Error(w, fmt.Sprintf("failed to create temp file: %v", err), http.StatusInternalServerError)
@@ -134,7 +226,7 @@
 			os.Remove(blockf.Name())
 		}()
 		blockb := bufio.NewWriter(blockf)
-		if err := prof(blockb); err != nil {
+		if err := prof(blockb, r.FormValue("id")); err != nil {
 			http.Error(w, fmt.Sprintf("failed to generate profile: %v", err), http.StatusInternalServerError)
 			return
 		}
@@ -147,7 +239,7 @@
 			return
 		}
 		svgFilename := blockf.Name() + ".svg"
-		if output, err := exec.Command("go", "tool", "pprof", "-svg", "-output", svgFilename, blockf.Name()).CombinedOutput(); err != nil {
+		if output, err := exec.Command(goCmd(), "tool", "pprof", "-svg", "-output", svgFilename, blockf.Name()).CombinedOutput(); err != nil {
 			http.Error(w, fmt.Sprintf("failed to execute go tool pprof: %v\n%s", err, output), http.StatusInternalServerError)
 			return
 		}
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index 7db2188..b8a7e5d 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -25,7 +25,7 @@
 
 // httpTrace serves either whole trace (goid==0) or trace for goid goroutine.
 func httpTrace(w http.ResponseWriter, r *http.Request) {
-	_, err := parseEvents()
+	_, err := parseTrace()
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
@@ -42,12 +42,30 @@
 // See https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md
 // This is almost verbatim copy of:
 // https://github.com/catapult-project/catapult/blob/master/tracing/bin/index.html
-// on revision 623a005a3ffa9de13c4b92bc72290e7bcd1ca591.
+// on revision 5f9e4c3eaa555bdef18218a89f38c768303b7b6e.
 var templTrace = `
 <html>
 <head>
 <link href="/trace_viewer_html" rel="import">
+<style type="text/css">
+  html, body {
+    box-sizing: border-box;
+    overflow: hidden;
+    margin: 0px;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+  }
+  #trace-viewer {
+    width: 100%;
+    height: 100%;
+  }
+  #trace-viewer:focus {
+    outline: none;
+  }
+</style>
 <script>
+'use strict';
 (function() {
   var viewer;
   var url;
@@ -84,7 +102,9 @@
 
   function onResult(result) {
     model = new tr.Model();
-    var i = new tr.importer.Import(model);
+    var opts = new tr.importer.ImportOptions();
+    opts.shiftWorldToZero = false;
+    var i = new tr.importer.Import(model, opts);
     var p = i.importTracesWithProgressDialog([result]);
     p.then(onModelLoaded, onImportFail);
   }
@@ -94,7 +114,7 @@
     viewer.viewTitle = "trace";
   }
 
-  function onImportFail() {
+  function onImportFail(err) {
     var overlay = new tr.ui.b.Overlay();
     overlay.textContent = tr.b.normalizeException(err).message;
     overlay.title = 'Import error';
@@ -127,20 +147,20 @@
 // httpTraceViewerHTML serves static part of trace-viewer.
 // This URL is queried from templTrace HTML.
 func httpTraceViewerHTML(w http.ResponseWriter, r *http.Request) {
-	http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "trace_viewer_lean.html"))
+	http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "trace_viewer_full.html"))
 }
 
 // httpJsonTrace serves json trace, requested from within templTrace HTML.
 func httpJsonTrace(w http.ResponseWriter, r *http.Request) {
 	// This is an AJAX handler, so instead of http.Error we use log.Printf to log errors.
-	events, err := parseEvents()
+	res, err := parseTrace()
 	if err != nil {
 		log.Printf("failed to parse trace: %v", err)
 		return
 	}
 
 	params := &traceParams{
-		events:  events,
+		parsed:  res,
 		endTime: int64(1<<63 - 1),
 	}
 
@@ -151,13 +171,13 @@
 			log.Printf("failed to parse goid parameter '%v': %v", goids, err)
 			return
 		}
-		analyzeGoroutines(events)
+		analyzeGoroutines(res.Events)
 		g := gs[goid]
 		params.gtrace = true
 		params.startTime = g.StartTime
 		params.endTime = g.EndTime
 		params.maing = goid
-		params.gs = trace.RelatedGoroutines(events, goid)
+		params.gs = trace.RelatedGoroutines(res.Events, goid)
 	}
 
 	data, err := generateTrace(params)
@@ -240,7 +260,7 @@
 }
 
 type traceParams struct {
-	events    []*trace.Event
+	parsed    trace.ParseResult
 	gtrace    bool
 	startTime int64
 	endTime   int64
@@ -258,7 +278,7 @@
 
 	heapStats, prevHeapStats     heapStats
 	threadStats, prevThreadStats threadStats
-	gstates, prevGstates         [gStateCount]uint64
+	gstates, prevGstates         [gStateCount]int64
 }
 
 type heapStats struct {
@@ -267,8 +287,9 @@
 }
 
 type threadStats struct {
-	insyscall uint64
-	prunning  uint64
+	insyscallRuntime uint64 // system goroutine in syscall
+	insyscall        uint64 // user goroutine in syscall
+	prunning         uint64 // thread running P
 }
 
 type frameNode struct {
@@ -289,8 +310,9 @@
 )
 
 type gInfo struct {
-	state      gState       // current state
-	name       string       // name chosen for this goroutine at first EvGoStart
+	state      gState // current state
+	name       string // name chosen for this goroutine at first EvGoStart
+	isSystemG  bool
 	start      *trace.Event // most recent EvGoStart
 	markAssist *trace.Event // if non-nil, the mark assist currently running.
 }
@@ -345,6 +367,7 @@
 	ctx.data.TimeUnit = "ns"
 	maxProc := 0
 	ginfos := make(map[uint64]*gInfo)
+	stacks := params.parsed.Stacks
 
 	getGInfo := func(g uint64) *gInfo {
 		info, ok := ginfos[g]
@@ -371,27 +394,36 @@
 		ctx.gstates[newState]++
 		info.state = newState
 	}
-	for _, ev := range ctx.events {
+
+	for _, ev := range ctx.parsed.Events {
 		// Handle state transitions before we filter out events.
 		switch ev.Type {
 		case trace.EvGoStart, trace.EvGoStartLabel:
 			setGState(ev, ev.G, gRunnable, gRunning)
 			info := getGInfo(ev.G)
-			if info.name == "" {
-				if len(ev.Stk) > 0 {
-					info.name = fmt.Sprintf("G%v %s", ev.G, ev.Stk[0].Fn)
-				} else {
-					info.name = fmt.Sprintf("G%v", ev.G)
-				}
-			}
 			info.start = ev
 		case trace.EvProcStart:
 			ctx.threadStats.prunning++
 		case trace.EvProcStop:
 			ctx.threadStats.prunning--
 		case trace.EvGoCreate:
+			newG := ev.Args[0]
+			info := getGInfo(newG)
+			if info.name != "" {
+				return ctx.data, fmt.Errorf("duplicate go create event for go id=%d detected at offset %d", newG, ev.Off)
+			}
+
+			stk, ok := stacks[ev.Args[1]]
+			if !ok || len(stk) == 0 {
+				return ctx.data, fmt.Errorf("invalid go create event: missing stack information for go id=%d at offset %d", newG, ev.Off)
+			}
+
+			fname := stk[0].Fn
+			info.name = fmt.Sprintf("G%v %s", newG, fname)
+			info.isSystemG = strings.HasPrefix(fname, "runtime.") && fname != "runtime.main"
+
 			ctx.gcount++
-			setGState(ev, ev.Args[0], gDead, gRunnable)
+			setGState(ev, newG, gDead, gRunnable)
 		case trace.EvGoEnd:
 			ctx.gcount--
 			setGState(ev, ev.G, gRunning, gDead)
@@ -399,10 +431,18 @@
 			setGState(ev, ev.Args[0], gWaiting, gRunnable)
 		case trace.EvGoSysExit:
 			setGState(ev, ev.G, gWaiting, gRunnable)
-			ctx.threadStats.insyscall--
+			if getGInfo(ev.G).isSystemG {
+				ctx.threadStats.insyscallRuntime--
+			} else {
+				ctx.threadStats.insyscall--
+			}
 		case trace.EvGoSysBlock:
 			setGState(ev, ev.G, gRunning, gWaiting)
-			ctx.threadStats.insyscall++
+			if getGInfo(ev.G).isSystemG {
+				ctx.threadStats.insyscallRuntime++
+			} else {
+				ctx.threadStats.insyscall++
+			}
 		case trace.EvGoSched, trace.EvGoPreempt:
 			setGState(ev, ev.G, gRunning, gRunnable)
 		case trace.EvGoStop,
@@ -420,7 +460,11 @@
 		case trace.EvGoInSyscall:
 			// Cancel out the effect of EvGoCreate at the beginning.
 			setGState(ev, ev.G, gRunnable, gWaiting)
-			ctx.threadStats.insyscall++
+			if getGInfo(ev.G).isSystemG {
+				ctx.threadStats.insyscallRuntime++
+			} else {
+				ctx.threadStats.insyscall++
+			}
 		case trace.EvHeapAlloc:
 			ctx.heapStats.heapAlloc = ev.Args[0]
 		case trace.EvNextGC:
@@ -429,8 +473,8 @@
 		if setGStateErr != nil {
 			return ctx.data, setGStateErr
 		}
-		if ctx.gstates[gRunnable] < 0 || ctx.gstates[gRunning] < 0 || ctx.threadStats.insyscall < 0 {
-			return ctx.data, fmt.Errorf("invalid state after processing %v: runnable=%d running=%d insyscall=%d", ev, ctx.gstates[gRunnable], ctx.gstates[gRunning], ctx.threadStats.insyscall)
+		if ctx.gstates[gRunnable] < 0 || ctx.gstates[gRunning] < 0 || ctx.threadStats.insyscall < 0 || ctx.threadStats.insyscallRuntime < 0 {
+			return ctx.data, fmt.Errorf("invalid state after processing %v: runnable=%d running=%d insyscall=%d insyscallRuntime=%d", ev, ctx.gstates[gRunnable], ctx.gstates[gRunning], ctx.threadStats.insyscall, ctx.threadStats.insyscallRuntime)
 		}
 
 		// Ignore events that are from uninteresting goroutines
@@ -461,12 +505,12 @@
 		case trace.EvGCStart:
 			ctx.emitSlice(ev, "GC")
 		case trace.EvGCDone:
-		case trace.EvGCScanStart:
+		case trace.EvGCSTWStart:
 			if ctx.gtrace {
 				continue
 			}
-			ctx.emitSlice(ev, "MARK TERMINATION")
-		case trace.EvGCScanDone:
+			ctx.emitSlice(ev, fmt.Sprintf("STW (%s)", ev.SArgs[0]))
+		case trace.EvGCSTWDone:
 		case trace.EvGCMarkAssistStart:
 			// Mark assists can continue past preemptions, so truncate to the
 			// whichever comes first. We'll synthesize another slice if
@@ -627,7 +671,7 @@
 	if ctx.prevGstates == ctx.gstates {
 		return
 	}
-	ctx.emit(&ViewerEvent{Name: "Goroutines", Phase: "C", Time: ctx.time(ev), Pid: 1, Arg: &goroutineCountersArg{ctx.gstates[gRunning], ctx.gstates[gRunnable], ctx.gstates[gWaitingGC]}})
+	ctx.emit(&ViewerEvent{Name: "Goroutines", Phase: "C", Time: ctx.time(ev), Pid: 1, Arg: &goroutineCountersArg{uint64(ctx.gstates[gRunning]), uint64(ctx.gstates[gRunnable]), uint64(ctx.gstates[gWaitingGC])}})
 	ctx.prevGstates = ctx.gstates
 }
 
@@ -643,7 +687,9 @@
 	if ctx.prevThreadStats == ctx.threadStats {
 		return
 	}
-	ctx.emit(&ViewerEvent{Name: "Threads", Phase: "C", Time: ctx.time(ev), Pid: 1, Arg: &threadCountersArg{ctx.threadStats.prunning, ctx.threadStats.insyscall}})
+	ctx.emit(&ViewerEvent{Name: "Threads", Phase: "C", Time: ctx.time(ev), Pid: 1, Arg: &threadCountersArg{
+		Running:   ctx.threadStats.prunning,
+		InSyscall: ctx.threadStats.insyscall}})
 	ctx.prevThreadStats = ctx.threadStats
 }
 
diff --git a/src/cmd/trace/trace_test.go b/src/cmd/trace/trace_test.go
index d96c297..aaffda8 100644
--- a/src/cmd/trace/trace_test.go
+++ b/src/cmd/trace/trace_test.go
@@ -1,3 +1,7 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 import (
@@ -6,6 +10,21 @@
 	"testing"
 )
 
+// stacks is a fake stack map populated for test.
+type stacks map[uint64][]*trace.Frame
+
+// add adds a stack with a single frame whose Fn field is
+// set to the provided fname and returns a unique stack id.
+func (s *stacks) add(fname string) uint64 {
+	if *s == nil {
+		*s = make(map[uint64][]*trace.Frame)
+	}
+
+	id := uint64(len(*s))
+	(*s)[id] = []*trace.Frame{{Fn: fname}}
+	return id
+}
+
 // TestGoroutineCount tests runnable/running goroutine counts computed by generateTrace
 // remain in the valid range.
 //   - the counts must not be negative. generateTrace will return an error.
@@ -15,34 +34,37 @@
 	w.Emit(trace.EvBatch, 0, 0)  // start of per-P batch event [pid, timestamp]
 	w.Emit(trace.EvFrequency, 1) // [ticks per second]
 
+	var s stacks
+
 	// In this test, we assume a valid trace contains EvGoWaiting or EvGoInSyscall
 	// event for every blocked goroutine.
 
 	// goroutine 10: blocked
-	w.Emit(trace.EvGoCreate, 1, 10, 1, 1) // [timestamp, new goroutine id, new stack id, stack id]
-	w.Emit(trace.EvGoWaiting, 1, 10)      // [timestamp, goroutine id]
+	w.Emit(trace.EvGoCreate, 1, 10, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id]
+	w.Emit(trace.EvGoWaiting, 1, 10)                                   // [timestamp, goroutine id]
 
 	// goroutine 20: in syscall
-	w.Emit(trace.EvGoCreate, 1, 20, 2, 1)
+	w.Emit(trace.EvGoCreate, 1, 20, s.add("pkg.f2"), s.add("main.f2"))
 	w.Emit(trace.EvGoInSyscall, 1, 20) // [timestamp, goroutine id]
 
 	// goroutine 30: runnable
-	w.Emit(trace.EvGoCreate, 1, 30, 5, 1)
+	w.Emit(trace.EvGoCreate, 1, 30, s.add("pkg.f3"), s.add("main.f3"))
 
 	w.Emit(trace.EvProcStart, 2, 0) // [timestamp, thread id]
 
 	// goroutine 40: runnable->running->runnable
-	w.Emit(trace.EvGoCreate, 1, 40, 7, 1)
-	w.Emit(trace.EvGoStartLocal, 1, 40) // [timestamp, goroutine id]
-	w.Emit(trace.EvGoSched, 1, 8)       // [timestamp, stack]
+	w.Emit(trace.EvGoCreate, 1, 40, s.add("pkg.f4"), s.add("main.f4"))
+	w.Emit(trace.EvGoStartLocal, 1, 40)          // [timestamp, goroutine id]
+	w.Emit(trace.EvGoSched, 1, s.add("main.f4")) // [timestamp, stack]
 
-	events, err := trace.Parse(w, "")
+	res, err := trace.Parse(w, "")
 	if err != nil {
 		t.Fatalf("failed to parse test trace: %v", err)
 	}
+	res.Stacks = s // use fake stacks.
 
 	params := &traceParams{
-		events:  events,
+		parsed:  res,
 		endTime: int64(1<<63 - 1),
 	}
 
@@ -66,31 +88,34 @@
 	// Test that we handle state changes to selected goroutines
 	// caused by events on goroutines that are not selected.
 
+	var s stacks
+
 	w := trace.NewWriter()
 	w.Emit(trace.EvBatch, 0, 0)  // start of per-P batch event [pid, timestamp]
 	w.Emit(trace.EvFrequency, 1) // [ticks per second]
 
 	// goroutine 10: blocked
-	w.Emit(trace.EvGoCreate, 1, 10, 1, 1) // [timestamp, new goroutine id, new stack id, stack id]
-	w.Emit(trace.EvGoWaiting, 1, 10)      // [timestamp, goroutine id]
+	w.Emit(trace.EvGoCreate, 1, 10, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id]
+	w.Emit(trace.EvGoWaiting, 1, 10)                                   // [timestamp, goroutine id]
 
 	// goroutine 20: runnable->running->unblock 10
-	w.Emit(trace.EvGoCreate, 1, 20, 7, 1)
-	w.Emit(trace.EvGoStartLocal, 1, 20)      // [timestamp, goroutine id]
-	w.Emit(trace.EvGoUnblockLocal, 1, 10, 8) // [timestamp, goroutine id, stack]
-	w.Emit(trace.EvGoEnd, 1)                 // [timestamp]
+	w.Emit(trace.EvGoCreate, 1, 20, s.add("pkg.f2"), s.add("main.f2"))
+	w.Emit(trace.EvGoStartLocal, 1, 20)                    // [timestamp, goroutine id]
+	w.Emit(trace.EvGoUnblockLocal, 1, 10, s.add("pkg.f2")) // [timestamp, goroutine id, stack]
+	w.Emit(trace.EvGoEnd, 1)                               // [timestamp]
 
 	// goroutine 10: runnable->running->block
-	w.Emit(trace.EvGoStartLocal, 1, 10) // [timestamp, goroutine id]
-	w.Emit(trace.EvGoBlock, 1, 9)       // [timestamp, stack]
+	w.Emit(trace.EvGoStartLocal, 1, 10)         // [timestamp, goroutine id]
+	w.Emit(trace.EvGoBlock, 1, s.add("pkg.f3")) // [timestamp, stack]
 
-	events, err := trace.Parse(w, "")
+	res, err := trace.Parse(w, "")
 	if err != nil {
 		t.Fatalf("failed to parse test trace: %v", err)
 	}
+	res.Stacks = s // use fake stacks
 
 	params := &traceParams{
-		events:  events,
+		parsed:  res,
 		endTime: int64(1<<63 - 1),
 		gs:      map[uint64]bool{10: true},
 	}
@@ -106,22 +131,24 @@
 	w.Emit(trace.EvBatch, 0, 0)  // start of per-P batch event [pid, timestamp]
 	w.Emit(trace.EvFrequency, 1) // [ticks per second]
 
+	var s stacks
 	// goroutine 9999: running -> mark assisting -> preempted -> assisting -> running -> block
-	w.Emit(trace.EvGoCreate, 1, 9999, 1, 1) // [timestamp, new goroutine id, new stack id, stack id]
-	w.Emit(trace.EvGoStartLocal, 1, 9999)   // [timestamp, goroutine id]
-	w.Emit(trace.EvGCMarkAssistStart, 1, 2) // [timestamp, stack]
-	w.Emit(trace.EvGoPreempt, 1, 3)         // [timestamp, stack]
-	w.Emit(trace.EvGoStartLocal, 1, 9999)   // [timestamp, goroutine id]
-	w.Emit(trace.EvGCMarkAssistDone, 1)     // [timestamp]
-	w.Emit(trace.EvGoBlock, 1, 4)           // [timestamp, stack]
+	w.Emit(trace.EvGoCreate, 1, 9999, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id]
+	w.Emit(trace.EvGoStartLocal, 1, 9999)                                // [timestamp, goroutine id]
+	w.Emit(trace.EvGCMarkAssistStart, 1, s.add("main.f1"))               // [timestamp, stack]
+	w.Emit(trace.EvGoPreempt, 1, s.add("main.f1"))                       // [timestamp, stack]
+	w.Emit(trace.EvGoStartLocal, 1, 9999)                                // [timestamp, goroutine id]
+	w.Emit(trace.EvGCMarkAssistDone, 1)                                  // [timestamp]
+	w.Emit(trace.EvGoBlock, 1, s.add("main.f2"))                         // [timestamp, stack]
 
-	events, err := trace.Parse(w, "")
+	res, err := trace.Parse(w, "")
 	if err != nil {
 		t.Fatalf("failed to parse test trace: %v", err)
 	}
+	res.Stacks = s // use fake stacks
 
 	params := &traceParams{
-		events:  events,
+		parsed:  res,
 		endTime: int64(1<<63 - 1),
 	}
 
diff --git a/src/cmd/trace/trace_unix_test.go b/src/cmd/trace/trace_unix_test.go
new file mode 100644
index 0000000..1c0d76f
--- /dev/null
+++ b/src/cmd/trace/trace_unix_test.go
@@ -0,0 +1,97 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package main
+
+import (
+	"bytes"
+	"internal/trace"
+	"runtime"
+	rtrace "runtime/trace"
+	"sync"
+	"syscall"
+	"testing"
+	"time"
+)
+
+// TestGoroutineInSyscall tests threads for timer goroutines
+// that preexisted when the tracing started were not counted
+// as threads in syscall. See golang.org/issues/22574.
+func TestGoroutineInSyscall(t *testing.T) {
+	// Start one goroutine blocked in syscall.
+	//
+	// TODO: syscall.Pipe used to cause the goroutine to
+	// remain blocked in syscall is not portable. Replace
+	// it with a more portable way so this test can run
+	// on non-unix architecture e.g. Windows.
+	var p [2]int
+	if err := syscall.Pipe(p[:]); err != nil {
+		t.Fatalf("failed to create pipe: %v", err)
+	}
+
+	var wg sync.WaitGroup
+	defer func() {
+		syscall.Write(p[1], []byte("a"))
+		wg.Wait()
+
+		syscall.Close(p[0])
+		syscall.Close(p[1])
+	}()
+	wg.Add(1)
+	go func() {
+		var tmp [1]byte
+		syscall.Read(p[0], tmp[:])
+		wg.Done()
+	}()
+
+	// Start multiple timer goroutines.
+	allTimers := make([]*time.Timer, 2*runtime.GOMAXPROCS(0))
+	defer func() {
+		for _, timer := range allTimers {
+			timer.Stop()
+		}
+	}()
+
+	var timerSetup sync.WaitGroup
+	for i := range allTimers {
+		timerSetup.Add(1)
+		go func(i int) {
+			defer timerSetup.Done()
+			allTimers[i] = time.AfterFunc(time.Hour, nil)
+		}(i)
+	}
+	timerSetup.Wait()
+
+	// Collect and parse trace.
+	buf := new(bytes.Buffer)
+	if err := rtrace.Start(buf); err != nil {
+		t.Fatalf("failed to start tracing: %v", err)
+	}
+	rtrace.Stop()
+
+	res, err := trace.Parse(buf, "")
+	if err != nil {
+		t.Fatalf("failed to parse trace: %v", err)
+	}
+
+	// Check only one thread for the pipe read goroutine is
+	// considered in-syscall.
+	viewerData, err := generateTrace(&traceParams{
+		parsed:  res,
+		endTime: int64(1<<63 - 1),
+	})
+	if err != nil {
+		t.Fatalf("failed to generate ViewerData: %v", err)
+	}
+	for _, ev := range viewerData.Events {
+		if ev.Name == "Threads" {
+			arg := ev.Arg.(*threadCountersArg)
+			if arg.InSyscall > 1 {
+				t.Errorf("%d threads in syscall at time %v; want less than 1 thread in syscall", arg.InSyscall, ev.Time)
+			}
+		}
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/.gitignore b/src/cmd/vendor/github.com/google/pprof/.gitignore
new file mode 100644
index 0000000..5a0c00f
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+*~
+*.orig
+*.exe
+.*.swp
+core
+coverage.txt
+pprof
diff --git a/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING b/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING
deleted file mode 100644
index 2827b7d..0000000
--- a/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING
+++ /dev/null
@@ -1,27 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement]
-(https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review. We
-use Github pull requests for this purpose.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than
-the one above, the
-[Software Grant and Corporate Contributor License Agreement]
-(https://cla.developers.google.com/about/google-corporate).
diff --git a/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING.md b/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING.md
new file mode 100644
index 0000000..5976686
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/CONTRIBUTING.md
@@ -0,0 +1,27 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+### Before you contribute
+
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first through the issue tracker with your idea so that we can help out and
+possibly guide you. Coordinating up front makes it much easier to avoid
+frustration later on.
+
+### Code reviews
+
+All submissions, including submissions by project members, require review.  
+We use Github pull requests for this purpose.
+
+### The small print
+
+Contributions made by corporations are covered by a different agreement than the one above,  
+the [Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
diff --git a/src/cmd/vendor/github.com/google/pprof/README.md b/src/cmd/vendor/github.com/google/pprof/README.md
index a134872..e8c2f03 100644
--- a/src/cmd/vendor/github.com/google/pprof/README.md
+++ b/src/cmd/vendor/github.com/google/pprof/README.md
@@ -1,3 +1,6 @@
+[![Build Status](https://travis-ci.org/google/pprof.svg?branch=master)](https://travis-ci.org/google/pprof)
+[![codecov](https://codecov.io/gh/google/pprof/graph/badge.svg)](https://codecov.io/gh/google/pprof)
+
 # Introduction
 
 pprof is a tool for visualization and analysis of profiling data.
@@ -24,7 +27,7 @@
 
 Prerequisites:
 
-- Go development kit. Known to work with Go 1.5.
+- Go development kit. Requires Go 1.7 or newer.
   Follow [these instructions](http://golang.org/doc/code.html) to install the 
   go tool and set up GOPATH.
 
@@ -35,6 +38,10 @@
 
     go get github.com/google/pprof
 
+Remember to set GOPATH to the directory where you want pprof to be
+installed.  The binary will be in `$GOPATH/bin` and the sources under
+`$GOPATH/src/github.com/google/pprof`.
+
 # Basic usage
 
 pprof can read a profile from a file or directly from a server via http.
@@ -70,12 +77,28 @@
 Type 'help' for available commands/options.
 ```
 
+## Run pprof via a web interface
+
+If the `-http` flag is specified, pprof starts a web server at
+the specified host:port that provides an interactive web-based interface to pprof.
+Host is optional, and is "localhost" by default. Port is optional, and is a
+random available port by default. `-http=":"` starts a server locally at
+a random port.
+
+```
+pprof -http=[host]:[port] [main_binary] profile.pb.gz
+```
+
+The preceding command should automatically open your web browser at
+the right page; if not, you can manually visit the specified port in
+your web browser.
+
 ## Using pprof with Linux Perf
 
 pprof can read `perf.data` files generated by the
-[Linux perf](https://perf.wiki.kernel.org/index.php) tool by using the
+[Linux perf](https://perf.wiki.kernel.org/index.php/Main_Page) tool by using the
 `perf_to_profile` program from the
-[perf_data_converter](http://github.com/google/perf_data_converter) package.
+[perf_data_converter](https://github.com/google/perf_data_converter) package.
 
 ## Further documentation
 
diff --git a/src/cmd/vendor/github.com/google/pprof/doc/developer/profile.proto.md b/src/cmd/vendor/github.com/google/pprof/doc/developer/profile.proto.md
index 9932e7e..d3b0b84 100644
--- a/src/cmd/vendor/github.com/google/pprof/doc/developer/profile.proto.md
+++ b/src/cmd/vendor/github.com/google/pprof/doc/developer/profile.proto.md
@@ -128,9 +128,11 @@
 
 Labels can be string-based or numeric. They are represented by the Label
 message, with a key identifying the label and either a string or numeric
-value. For numeric labels, by convention the key represents the measurement unit
-of the numeric value. So for the previous example, the samples would have labels
-{“bytes”, 2097152} and {“bytes”, 4194304}.
+value. For numeric labels, the measurement unit can be specified in the profile.
+If no unit is specified and the key is "request" or "alignment",
+then the units are assumed to be "bytes". Otherwise when no unit is specified
+the key will be used as the measurement unit of the numeric value. All tags with
+the same key should have the same unit.
 
 ## Keep and drop expressions
 
diff --git a/src/cmd/vendor/github.com/google/pprof/doc/pprof.md b/src/cmd/vendor/github.com/google/pprof/doc/pprof.md
index d2c7e26..57613fa 100644
--- a/src/cmd/vendor/github.com/google/pprof/doc/pprof.md
+++ b/src/cmd/vendor/github.com/google/pprof/doc/pprof.md
@@ -29,7 +29,40 @@
 possible. The interpretation of the reports generated by pprof depends on the
 semantics defined by the source of the profile.
 
-# General usage
+# Usage Modes
+
+There are few different ways of using `pprof`.
+
+## Report generation
+
+If a report format is requested on the command line:
+
+    pprof <format> [options] source
+
+pprof will generate a report in the specified format and exit.
+Formats can be either text, or graphical. See below for details about
+supported formats, options, and sources.
+
+## Interactive terminal use
+
+Without a format specifier:
+
+    pprof [options] source
+
+pprof will start an interactive shell in which the user can type
+commands.  Type `help` to get online help.
+
+## Web interface
+
+If a host:port is specified on the command line:
+
+    pprof -http=[host]:[port] [options] source
+
+pprof will start serving HTTP requests on the specified port.  Visit
+the HTTP url corresponding to the port (typically `http://<host>:<port>/`)
+in a browser to see the interface.
+
+# Details
 
 The objective of pprof is to generate a report for a profile. The report is
 generated from a location hierarchy, which is reconstructed from the profile
@@ -38,14 +71,12 @@
 descendants. Samples that include a location multiple times (eg for recursive
 functions) are counted only once per location.
 
-The basic usage of pprof is
+## Options
 
-    pprof <format> [options] source
-
-Where *format* selects the nature of the report, and *options* configure the
-contents of the report. Each option has a value, which can be boolean, numeric,
-or strings. While only one format can be specified, most options can be selected
-independently of each other.
+*options* configure the contents of a report. Each option has a value,
+which can be boolean, numeric, or strings. While only one format can
+be specified, most options can be selected independently of each
+other.
 
 Some common pprof options are:
 
@@ -74,10 +105,56 @@
 
 Sample values are numeric values associated to a unit. If pprof can recognize
 these units, it will attempt to scale the values to a suitable unit for
-visualization. The `unite=` option will force the use of a specific unit. For
-example, `sample_index=sec` will force any time values to be reported in
+visualization. The `unit=` option will force the use of a specific unit. For
+example, `unit=sec` will force any time values to be reported in
 seconds. pprof recognizes most common time and memory size units.
 
+## Tag filtering
+
+Samples in a profile may have tags. These tags have a name and a value; this
+value can be either numeric or a string. pprof can select samples from a
+profile based on these tags using the `-tagfocus` and `-tagignore` options.
+
+Generally, these options work as follows:
+* **-tagfocus=_regex_** or **-tagfocus=_range_:** Restrict to samples with tags
+  matched by regexp or in range.
+* **-tagignore=_regex_** or **-tagignore=_range_:** Discard samples with tags
+  matched by regexp or in range.
+
+When using `-tagfocus=regex` and `-tagignore=regex`, the regex will be compared
+to each value associated with each tag. If one specifies a value
+like `regex1,regex2`, then only samples with a tag value matching `regex1`
+and a tag value matching `regex2` will be kept.
+
+In addition to being able to filter on tag values, one can specify the name of
+the tag which a certain value must be associated with using the notation
+`-tagfocus=tagName=value`. Here, the `tagName` must match the tag's name
+exactly, and the value can be either a regex or a range. If one specifies
+a value like `regex1,regex2`, then samples with a tag value (paired with the
+specified tag name) matching either `regex1` or matching `regex2` will match.
+
+Here are examples explaining how `tagfocus` can be used:
+
+* `-tagfocus 128kb:512kb` accepts a sample iff it has any numeric tag with
+  memory value in the specified range.
+* `-tagfocus mytag=128kb:512kb` accepts a sample iff it has a numeric tag
+  `mytag` with memory value in the specified range. There isn't a way to say
+   `-tagfocus mytag=128kb:512kb,16kb:32kb`
+   or `-tagfocus mytag=128kb:512kb,mytag2=128kb:512kb`. Just single value or
+   range for numeric tags.
+* `-tagfocus someregex` accepts a sample iff it has any string tag with
+  `tagName:tagValue` string matching specified regexp. In the future, this
+  will change to accept sample iff it has any string tag with `tagValue` string
+  matching specified regexp.
+* `-tagfocus mytag=myvalue1,myvalue2` matches if either of the two tag values
+  are present.
+
+`-tagignore` works similarly, except that it discards matching samples, instead
+of keeping them.
+
+If both the `-tagignore` and `-tagfocus` expressions (either a regexp or a
+range) match a given sample, then the sample will be discarded.
+
 ## Text reports
 
 pprof text reports show the location hierarchy in text format.
diff --git a/src/cmd/vendor/github.com/google/pprof/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/driver/driver.go
index d01d0fa..ee7d67d 100644
--- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go
@@ -29,10 +29,10 @@
 // manager. Then it generates a report formatted according to the
 // options selected through the flags package.
 func PProf(o *Options) error {
-	return internaldriver.PProf(o.InternalOptions())
+	return internaldriver.PProf(o.internalOptions())
 }
 
-func (o *Options) InternalOptions() *plugin.Options {
+func (o *Options) internalOptions() *plugin.Options {
 	var obj plugin.ObjTool
 	if o.Obj != nil {
 		obj = &internalObjTool{o.Obj}
@@ -273,9 +273,9 @@
 }
 
 func (s *internalSymbolizer) Symbolize(mode string, srcs plugin.MappingSources, prof *profile.Profile) error {
-	isrcs := plugin.MappingSources{}
+	isrcs := MappingSources{}
 	for m, s := range srcs {
 		isrcs[m] = s
 	}
-	return s.Symbolize(mode, isrcs, prof)
+	return s.Symbolizer.Symbolize(mode, isrcs, prof)
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner.go
index e3a7777..71e471b 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner.go
@@ -21,6 +21,7 @@
 	"os/exec"
 	"strconv"
 	"strings"
+	"sync"
 
 	"github.com/google/pprof/internal/plugin"
 )
@@ -36,6 +37,7 @@
 // addr2Liner is a connection to an addr2line command for obtaining
 // address and line number information from a binary.
 type addr2Liner struct {
+	mu   sync.Mutex
 	rw   lineReaderWriter
 	base uint64
 
@@ -170,9 +172,10 @@
 		Line: linenumber}, false
 }
 
-// addrInfo returns the stack frame information for a specific program
-// address. It returns nil if the address could not be identified.
-func (d *addr2Liner) addrInfo(addr uint64) ([]plugin.Frame, error) {
+func (d *addr2Liner) rawAddrInfo(addr uint64) ([]plugin.Frame, error) {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+
 	if err := d.rw.write(fmt.Sprintf("%x", addr-d.base)); err != nil {
 		return nil, err
 	}
@@ -201,6 +204,16 @@
 			stack = append(stack, frame)
 		}
 	}
+	return stack, err
+}
+
+// addrInfo returns the stack frame information for a specific program
+// address. It returns nil if the address could not be identified.
+func (d *addr2Liner) addrInfo(addr uint64) ([]plugin.Frame, error) {
+	stack, err := d.rawAddrInfo(addr)
+	if err != nil {
+		return nil, err
+	}
 
 	// Get better name from nm if possible.
 	if len(stack) > 0 && d.nm != nil {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
index 7692b0a..68fa559 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
@@ -21,6 +21,7 @@
 	"os/exec"
 	"strconv"
 	"strings"
+	"sync"
 
 	"github.com/google/pprof/internal/plugin"
 )
@@ -32,6 +33,7 @@
 // llvmSymbolizer is a connection to an llvm-symbolizer command for
 // obtaining address and line number information from a binary.
 type llvmSymbolizer struct {
+	sync.Mutex
 	filename string
 	rw       lineReaderWriter
 	base     uint64
@@ -150,6 +152,9 @@
 // addrInfo returns the stack frame information for a specific program
 // address. It returns nil if the address could not be identified.
 func (d *llvmSymbolizer) addrInfo(addr uint64) ([]plugin.Frame, error) {
+	d.Lock()
+	defer d.Unlock()
+
 	if err := d.rw.write(fmt.Sprintf("%s 0x%x", d.filename, addr-d.base)); err != nil {
 		return nil, err
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_nm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_nm.go
index e7a8e10..1987bd3 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_nm.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_nm.go
@@ -48,22 +48,23 @@
 	if cmd == "" {
 		cmd = defaultNM
 	}
+	var b bytes.Buffer
+	c := exec.Command(cmd, "-n", file)
+	c.Stdout = &b
+	if err := c.Run(); err != nil {
+		return nil, err
+	}
+	return parseAddr2LinerNM(base, &b)
+}
 
+func parseAddr2LinerNM(base uint64, nm io.Reader) (*addr2LinerNM, error) {
 	a := &addr2LinerNM{
 		m: []symbolInfo{},
 	}
 
-	var b bytes.Buffer
-	c := exec.Command(cmd, "-n", file)
-	c.Stdout = &b
-
-	if err := c.Run(); err != nil {
-		return nil, err
-	}
-
 	// Parse nm output and populate symbol map.
 	// Skip lines we fail to parse.
-	buf := bufio.NewReader(&b)
+	buf := bufio.NewReader(nm)
 	for {
 		line, err := buf.ReadString('\n')
 		if line == "" && err != nil {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
index 9854c9a..9a82cb8 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
@@ -24,14 +24,21 @@
 	"path/filepath"
 	"regexp"
 	"strings"
+	"sync"
 
 	"github.com/google/pprof/internal/elfexec"
 	"github.com/google/pprof/internal/plugin"
 )
 
 // A Binutils implements plugin.ObjTool by invoking the GNU binutils.
-// SetConfig must be called before any of the other methods.
 type Binutils struct {
+	mu  sync.Mutex
+	rep *binrep
+}
+
+// binrep is an immutable representation for Binutils.  It is atomically
+// replaced on every mutation to provide thread-safe access.
+type binrep struct {
 	// Commands to invoke.
 	llvmSymbolizer      string
 	llvmSymbolizerFound bool
@@ -47,11 +54,38 @@
 	fast bool
 }
 
+// get returns the current representation for bu, initializing it if necessary.
+func (bu *Binutils) get() *binrep {
+	bu.mu.Lock()
+	r := bu.rep
+	if r == nil {
+		r = &binrep{}
+		initTools(r, "")
+		bu.rep = r
+	}
+	bu.mu.Unlock()
+	return r
+}
+
+// update modifies the rep for bu via the supplied function.
+func (bu *Binutils) update(fn func(r *binrep)) {
+	r := &binrep{}
+	bu.mu.Lock()
+	defer bu.mu.Unlock()
+	if bu.rep == nil {
+		initTools(r, "")
+	} else {
+		*r = *bu.rep
+	}
+	fn(r)
+	bu.rep = r
+}
+
 // SetFastSymbolization sets a toggle that makes binutils use fast
 // symbolization (using nm), which is much faster than addr2line but
 // provides only symbol name information (no file/line).
-func (b *Binutils) SetFastSymbolization(fast bool) {
-	b.fast = fast
+func (bu *Binutils) SetFastSymbolization(fast bool) {
+	bu.update(func(r *binrep) { r.fast = fast })
 }
 
 // SetTools processes the contents of the tools option. It
@@ -59,7 +93,11 @@
 // of the form t:path, where cmd will be used to look only for the
 // tool named t. If t is not specified, the path is searched for all
 // tools.
-func (b *Binutils) SetTools(config string) {
+func (bu *Binutils) SetTools(config string) {
+	bu.update(func(r *binrep) { initTools(r, config) })
+}
+
+func initTools(b *binrep, config string) {
 	// paths collect paths per tool; Key "" contains the default.
 	paths := make(map[string][]string)
 	for _, t := range strings.Split(config, ",") {
@@ -91,11 +129,8 @@
 
 // Disasm returns the assembly instructions for the specified address range
 // of a binary.
-func (b *Binutils) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
-	if b.addr2line == "" {
-		// Update the command invocations if not initialized.
-		b.SetTools("")
-	}
+func (bu *Binutils) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
+	b := bu.get()
 	cmd := exec.Command(b.objdump, "-d", "-C", "--no-show-raw-insn", "-l",
 		fmt.Sprintf("--start-address=%#x", start),
 		fmt.Sprintf("--stop-address=%#x", end),
@@ -109,11 +144,8 @@
 }
 
 // Open satisfies the plugin.ObjTool interface.
-func (b *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
-	if b.addr2line == "" {
-		// Update the command invocations if not initialized.
-		b.SetTools("")
-	}
+func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+	b := bu.get()
 
 	// Make sure file is a supported executable.
 	// The pprof driver uses Open to sniff the difference
@@ -140,7 +172,7 @@
 	return nil, fmt.Errorf("unrecognized binary: %s", name)
 }
 
-func (b *Binutils) openMachO(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+func (b *binrep) openMachO(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
 	of, err := macho.Open(name)
 	if err != nil {
 		return nil, fmt.Errorf("Parsing %s: %v", name, err)
@@ -153,7 +185,7 @@
 	return &fileAddr2Line{file: file{b: b, name: name}}, nil
 }
 
-func (b *Binutils) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
 	ef, err := elf.Open(name)
 	if err != nil {
 		return nil, fmt.Errorf("Parsing %s: %v", name, err)
@@ -202,7 +234,7 @@
 
 // file implements the binutils.ObjFile interface.
 type file struct {
-	b       *Binutils
+	b       *binrep
 	name    string
 	base    uint64
 	buildID string
@@ -263,22 +295,27 @@
 // information). It can be slow for large binaries with debug
 // information.
 type fileAddr2Line struct {
+	once sync.Once
 	file
 	addr2liner     *addr2Liner
 	llvmSymbolizer *llvmSymbolizer
 }
 
 func (f *fileAddr2Line) SourceLine(addr uint64) ([]plugin.Frame, error) {
+	f.once.Do(f.init)
 	if f.llvmSymbolizer != nil {
 		return f.llvmSymbolizer.addrInfo(addr)
 	}
 	if f.addr2liner != nil {
 		return f.addr2liner.addrInfo(addr)
 	}
+	return nil, fmt.Errorf("could not find local addr2liner")
+}
 
+func (f *fileAddr2Line) init() {
 	if llvmSymbolizer, err := newLLVMSymbolizer(f.b.llvmSymbolizer, f.name, f.base); err == nil {
 		f.llvmSymbolizer = llvmSymbolizer
-		return f.llvmSymbolizer.addrInfo(addr)
+		return
 	}
 
 	if addr2liner, err := newAddr2Liner(f.b.addr2line, f.name, f.base); err == nil {
@@ -290,13 +327,14 @@
 		if nm, err := newAddr2LinerNM(f.b.nm, f.name, f.base); err == nil {
 			f.addr2liner.nm = nm
 		}
-		return f.addr2liner.addrInfo(addr)
 	}
-
-	return nil, fmt.Errorf("could not find local addr2liner")
 }
 
 func (f *fileAddr2Line) Close() error {
+	if f.llvmSymbolizer != nil {
+		f.llvmSymbolizer.rw.close()
+		f.llvmSymbolizer = nil
+	}
 	if f.addr2liner != nil {
 		f.addr2liner.rw.close()
 		f.addr2liner = nil
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go
index b0ba5f6..989a290 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go
@@ -15,7 +15,13 @@
 package binutils
 
 import (
+	"bytes"
 	"fmt"
+	"math"
+	"path/filepath"
+	"reflect"
+	"regexp"
+	"runtime"
 	"testing"
 
 	"github.com/google/pprof/internal/plugin"
@@ -37,7 +43,7 @@
 func TestAddr2Liner(t *testing.T) {
 	const offset = 0x500
 
-	a := addr2Liner{&mockAddr2liner{}, offset, nil}
+	a := addr2Liner{rw: &mockAddr2liner{}, base: offset}
 	for i := 1; i < 8; i++ {
 		addr := i*0x1000 + offset
 		s, err := a.addrInfo(uint64(addr))
@@ -112,24 +118,23 @@
 }
 
 func TestAddr2LinerLookup(t *testing.T) {
-	oddSizedMap := addr2LinerNM{
-		m: []symbolInfo{
-			{0x1000, "0x1000"},
-			{0x2000, "0x2000"},
-			{0x3000, "0x3000"},
-		},
-	}
-	evenSizedMap := addr2LinerNM{
-		m: []symbolInfo{
-			{0x1000, "0x1000"},
-			{0x2000, "0x2000"},
-			{0x3000, "0x3000"},
-			{0x4000, "0x4000"},
-		},
-	}
-	for _, a := range []*addr2LinerNM{
-		&oddSizedMap, &evenSizedMap,
-	} {
+	const oddSizedData = `
+00001000 T 0x1000
+00002000 T 0x2000
+00003000 T 0x3000
+`
+	const evenSizedData = `
+0000000000001000 T 0x1000
+0000000000002000 T 0x2000
+0000000000003000 T 0x3000
+0000000000004000 T 0x4000
+`
+	for _, d := range []string{oddSizedData, evenSizedData} {
+		a, err := parseAddr2LinerNM(0, bytes.NewBufferString(d))
+		if err != nil {
+			t.Errorf("nm parse error: %v", err)
+			continue
+		}
 		for address, want := range map[uint64]string{
 			0x1000: "0x1000",
 			0x1001: "0x1000",
@@ -141,6 +146,11 @@
 				t.Errorf("%x: got %v, want %s", address, got, want)
 			}
 		}
+		for _, unknown := range []uint64{0x0fff, 0x4001} {
+			if got, _ := a.addrInfo(unknown); got != nil {
+				t.Errorf("%x: got %v, want nil", unknown, got)
+			}
+		}
 	}
 }
 
@@ -150,3 +160,116 @@
 	}
 	return got[0].Func == want
 }
+
+func TestSetTools(t *testing.T) {
+	// Test that multiple calls work.
+	bu := &Binutils{}
+	bu.SetTools("")
+	bu.SetTools("")
+}
+
+func TestSetFastSymbolization(t *testing.T) {
+	// Test that multiple calls work.
+	bu := &Binutils{}
+	bu.SetFastSymbolization(true)
+	bu.SetFastSymbolization(false)
+}
+
+func skipUnlessLinuxAmd64(t *testing.T) {
+	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+		t.Skip("Disasm only tested on x86-64 linux")
+	}
+}
+
+func TestDisasm(t *testing.T) {
+	skipUnlessLinuxAmd64(t)
+	bu := &Binutils{}
+	insts, err := bu.Disasm(filepath.Join("testdata", "hello"), 0, math.MaxUint64)
+	if err != nil {
+		t.Fatalf("Disasm: unexpected error %v", err)
+	}
+	mainCount := 0
+	for _, x := range insts {
+		if x.Function == "main" {
+			mainCount++
+		}
+	}
+	if mainCount == 0 {
+		t.Error("Disasm: found no main instructions")
+	}
+}
+
+func TestObjFile(t *testing.T) {
+	skipUnlessLinuxAmd64(t)
+	bu := &Binutils{}
+	f, err := bu.Open(filepath.Join("testdata", "hello"), 0, math.MaxUint64, 0)
+	if err != nil {
+		t.Fatalf("Open: unexpected error %v", err)
+	}
+	defer f.Close()
+	syms, err := f.Symbols(regexp.MustCompile("main"), 0)
+	if err != nil {
+		t.Fatalf("Symbols: unexpected error %v", err)
+	}
+
+	find := func(name string) *plugin.Sym {
+		for _, s := range syms {
+			for _, n := range s.Name {
+				if n == name {
+					return s
+				}
+			}
+		}
+		return nil
+	}
+	m := find("main")
+	if m == nil {
+		t.Fatalf("Symbols: did not find main")
+	}
+	frames, err := f.SourceLine(m.Start)
+	if err != nil {
+		t.Fatalf("SourceLine: unexpected error %v", err)
+	}
+	expect := []plugin.Frame{
+		{Func: "main", File: "/tmp/hello.c", Line: 3},
+	}
+	if !reflect.DeepEqual(frames, expect) {
+		t.Fatalf("SourceLine for main: expect %v; got %v\n", expect, frames)
+	}
+}
+
+func TestLLVMSymbolizer(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("testtdata/llvm-symbolizer has only been tested on linux")
+	}
+
+	cmd := filepath.Join("testdata", "fake-llvm-symbolizer")
+	symbolizer, err := newLLVMSymbolizer(cmd, "foo", 0)
+	if err != nil {
+		t.Fatalf("newLLVMSymbolizer: unexpected error %v", err)
+	}
+	defer symbolizer.rw.close()
+
+	for _, c := range []struct {
+		addr   uint64
+		frames []plugin.Frame
+	}{
+		{0x10, []plugin.Frame{
+			{Func: "Inlined_0x10", File: "foo.h", Line: 0},
+			{Func: "Func_0x10", File: "foo.c", Line: 2},
+		}},
+		{0x20, []plugin.Frame{
+			{Func: "Inlined_0x20", File: "foo.h", Line: 0},
+			{Func: "Func_0x20", File: "foo.c", Line: 2},
+		}},
+	} {
+		frames, err := symbolizer.addrInfo(c.addr)
+		if err != nil {
+			t.Errorf("LLVM: unexpected error %v", err)
+			continue
+		}
+		if !reflect.DeepEqual(frames, c.frames) {
+			t.Errorf("LLVM: expect %v; got %v\n", c.frames, frames)
+		}
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go
index 7fc2574..3563198 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go
@@ -73,7 +73,7 @@
 
 func checkSymbol(got []*plugin.Sym, want []plugin.Sym) error {
 	if len(got) != len(want) {
-		return fmt.Errorf("unexpected number of symbols %d (want %d)\n", len(got), len(want))
+		return fmt.Errorf("unexpected number of symbols %d (want %d)", len(got), len(want))
 	}
 
 	for i, g := range got {
@@ -134,8 +134,6 @@
 		},
 	}
 
-	const objdump = "testdata/wrapper/objdump"
-
 	for _, tc := range testcases {
 		insts, err := disassemble([]byte(tc.asm))
 		if err != nil {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/fake-llvm-symbolizer b/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/fake-llvm-symbolizer
new file mode 100755
index 0000000..596713c
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/fake-llvm-symbolizer
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2014 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Fake llvm-symbolizer to use in tests
+
+set -f
+IFS=" "
+
+while read line; do
+  # line has form:
+  #    filename 0xaddr
+  # Emit dummy output that matches llvm-symbolizer output format.
+  set -- $line
+  fname=$1
+  addr=$2
+  echo "Inlined_$addr"
+  echo "$fname.h"
+  echo "Func_$addr"
+  echo "$fname.c:2"
+  echo
+done
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/hello b/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/hello
new file mode 100755
index 0000000..d86dc7c
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/hello
Binary files differ
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
index 0005ead..e2e8c6c 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
@@ -24,14 +24,17 @@
 )
 
 type source struct {
-	Sources  []string
-	ExecName string
-	BuildID  string
-	Base     []string
+	Sources   []string
+	ExecName  string
+	BuildID   string
+	Base      []string
+	Normalize bool
 
-	Seconds   int
-	Timeout   int
-	Symbolize string
+	Seconds      int
+	Timeout      int
+	Symbolize    string
+	HTTPHostport string
+	Comment      string
 }
 
 // Parse parses the command lines through the specified flags package
@@ -41,9 +44,11 @@
 	flag := o.Flagset
 	// Comparisons.
 	flagBase := flag.StringList("base", "", "Source for base profile for comparison")
-	// Internal options.
+	// Source options.
 	flagSymbolize := flag.String("symbolize", "", "Options for profile symbolization")
 	flagBuildID := flag.String("buildid", "", "Override build id for first mapping")
+	flagTimeout := flag.Int("timeout", -1, "Timeout in seconds for fetching a profile")
+	flagAddComment := flag.String("add_comment", "", "Annotation string to record in the profile")
 	// CPU profile options
 	flagSeconds := flag.Int("seconds", -1, "Length of time for dynamic profiles")
 	// Heap profile options
@@ -57,7 +62,7 @@
 	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")
 
-	flagTimeout := flag.Int("timeout", -1, "Timeout in seconds for fetching a profile")
+	flagHTTP := flag.String("http", "", "Present interactive web based UI at the specified http host:port")
 
 	// Flags used during command processing
 	installedFlags := installFlags(flag)
@@ -106,6 +111,9 @@
 	if err != nil {
 		return nil, nil, err
 	}
+	if cmd != nil && *flagHTTP != "" {
+		return nil, nil, fmt.Errorf("-http is not compatible with an output format on the command line")
+	}
 
 	si := pprofVariables["sample_index"].value
 	si = sampleIndex(flagTotalDelay, si, "delay", "-total_delay", o.UI)
@@ -122,12 +130,14 @@
 	}
 
 	source := &source{
-		Sources:   args,
-		ExecName:  execName,
-		BuildID:   *flagBuildID,
-		Seconds:   *flagSeconds,
-		Timeout:   *flagTimeout,
-		Symbolize: *flagSymbolize,
+		Sources:      args,
+		ExecName:     execName,
+		BuildID:      *flagBuildID,
+		Seconds:      *flagSeconds,
+		Timeout:      *flagTimeout,
+		Symbolize:    *flagSymbolize,
+		HTTPHostport: *flagHTTP,
+		Comment:      *flagAddComment,
 	}
 
 	for _, s := range *flagBase {
@@ -136,6 +146,12 @@
 		}
 	}
 
+	normalize := pprofVariables["normalize"].boolValue()
+	if normalize && len(source.Base) == 0 {
+		return nil, nil, fmt.Errorf("Must have base profile to normalize by")
+	}
+	source.Normalize = normalize
+
 	if bu, ok := o.Obj.(*binutils.Binutils); ok {
 		bu.SetTools(*flagTools)
 	}
@@ -240,13 +256,33 @@
 	return cmd, nil
 }
 
-var usageMsgHdr = "usage: pprof [options] [-base source] [binary] <source> ...\n"
+var usageMsgHdr = `usage:
+
+Produce output in the specified format.
+
+   pprof <format> [options] [binary] <source> ...
+
+Omit the format to get an interactive shell whose commands can be used
+to generate various views of a profile
+
+   pprof [options] [binary] <source> ...
+
+Omit the format and provide the "-http" flag to get an interactive web
+interface at the specified host:port that can be used to navigate through
+various views of a profile.
+
+   pprof -http [host]:[port] [options] [binary] <source> ...
+
+Details:
+`
 
 var usageMsgSrc = "\n\n" +
 	"  Source options:\n" +
 	"    -seconds              Duration for time-based profile collection\n" +
 	"    -timeout              Timeout in seconds for profile collection\n" +
 	"    -buildid              Override build id for main binary\n" +
+	"    -add_comment          Free-form annotation to add to the profile\n" +
+	"                          Displayed on some reports or with pprof -comments\n" +
 	"    -base source          Source of profile to use as baseline\n" +
 	"    profile.pb.gz         Profile in compressed protobuf format\n" +
 	"    legacy_profile        Profile in legacy pprof format\n" +
@@ -261,7 +297,19 @@
 
 var usageMsgVars = "\n\n" +
 	"  Misc options:\n" +
-	"   -tools                 Search path for object tools\n" +
+	"   -http              Provide web based interface at host:port.\n" +
+	"                      Host is optional and 'localhost' by default.\n" +
+	"                      Port is optional and a randomly available port by default.\n" +
+	"   -tools             Search path for object tools\n" +
+	"\n" +
+	"  Legacy convenience options:\n" +
+	"   -inuse_space           Same as -sample_index=inuse_space\n" +
+	"   -inuse_objects         Same as -sample_index=inuse_objects\n" +
+	"   -alloc_space           Same as -sample_index=alloc_space\n" +
+	"   -alloc_objects         Same as -sample_index=alloc_objects\n" +
+	"   -total_delay           Same as -sample_index=delay\n" +
+	"   -contentions           Same as -sample_index=contentions\n" +
+	"   -mean_delay            Same as -mean -sample_index=delay\n" +
 	"\n" +
 	"  Environment Variables:\n" +
 	"   PPROF_TMPDIR       Location for saved profiles (default $HOME/pprof)\n" +
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go
index 5e54062..66e5c86 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go
@@ -139,10 +139,10 @@
 	// Comparisons.
 	"positive_percentages": &variable{boolKind, "f", "", helpText(
 		"Ignore negative samples when computing percentages",
-		" Do not count negative samples when computing the total value",
-		" of the profile, used to compute percentages. If set, and the -base",
-		" option is used, percentages reported will be computed against the",
-		" main profile, ignoring the base profile.")},
+		"Do not count negative samples when computing the total value",
+		"of the profile, used to compute percentages. If set, and the -base",
+		"option is used, percentages reported will be computed against the",
+		"main profile, ignoring the base profile.")},
 
 	// Graph handling options.
 	"call_tree": &variable{boolKind, "f", "", helpText(
@@ -157,9 +157,9 @@
 	"unit": &variable{stringKind, "minimum", "", helpText(
 		"Measurement units to display",
 		"Scale the sample values to this unit.",
-		" For time-based profiles, use seconds, milliseconds, nanoseconds, etc.",
-		" For memory profiles, use megabytes, kilobytes, bytes, etc.",
-		" auto will scale each value independently to the most natural unit.")},
+		"For time-based profiles, use seconds, milliseconds, nanoseconds, etc.",
+		"For memory profiles, use megabytes, kilobytes, bytes, etc.",
+		"Using auto will scale each value independently to the most natural unit.")},
 	"compact_labels": &variable{boolKind, "f", "", "Show minimal headers"},
 	"source_path":    &variable{stringKind, "", "", "Search path for source files"},
 
@@ -195,11 +195,15 @@
 		"If set, only show nodes that match this location.",
 		"Matching includes the function name, filename or object name.")},
 	"tagfocus": &variable{stringKind, "", "", helpText(
-		"Restrict to samples with tags in range or matched by regexp",
-		"Discard samples that do not include a node with a tag matching this regexp.")},
+		"Restricts to samples with tags in range or matched by regexp",
+		"Use name=value syntax to limit the matching to a specific tag.",
+		"Numeric tag filter examples: 1kb, 1kb:10kb, memory=32mb:",
+		"String tag filter examples: foo, foo.*bar, mytag=foo.*bar")},
 	"tagignore": &variable{stringKind, "", "", helpText(
 		"Discard samples with tags in range or matched by regexp",
-		"Discard samples that do include a node with a tag matching this regexp.")},
+		"Use name=value syntax to limit the matching to a specific tag.",
+		"Numeric tag filter examples: 1kb, 1kb:10kb, memory=32mb:",
+		"String tag filter examples: foo, foo.*bar, mytag=foo.*bar")},
 	"tagshow": &variable{stringKind, "", "", helpText(
 		"Only consider tags matching this regexp",
 		"Discard tags that do not match this regexp")},
@@ -218,6 +222,8 @@
 		"Sample value to report (0-based index or name)",
 		"Profiles contain multiple values per sample.",
 		"Use sample_index=i to select the ith value (starting at 0).")},
+	"normalize": &variable{boolKind, "f", "", helpText(
+		"Scales profile based on the base profile.")},
 
 	// Data sorting criteria
 	"flat": &variable{boolKind, "t", "cumulative", helpText("Sort entries based on own weight")},
@@ -227,9 +233,6 @@
 	"functions": &variable{boolKind, "t", "granularity", helpText(
 		"Aggregate at the function level.",
 		"Takes into account the filename/lineno where the function was defined.")},
-	"functionnameonly": &variable{boolKind, "f", "granularity", helpText(
-		"Aggregate at the function level.",
-		"Ignores the filename/lineno where the function was defined.")},
 	"files": &variable{boolKind, "f", "granularity", "Aggregate at the file level."},
 	"lines": &variable{boolKind, "f", "granularity", "Aggregate at the source code line level."},
 	"addresses": &variable{boolKind, "f", "granularity", helpText(
@@ -266,7 +269,7 @@
 
 	var help string
 	if commandLine {
-		help = "  Output formats (select only one):\n"
+		help = "  Output formats (select at most one):\n"
 	} else {
 		help = "  Commands:\n"
 		commands = append(commands, fmtHelp("o/options", "List options and their current values"))
@@ -471,7 +474,7 @@
 	case boolKind:
 		var b bool
 		if b, err = stringToBool(value); err == nil {
-			if v.group != "" && b == false {
+			if v.group != "" && !b {
 				err = fmt.Errorf("%q can only be set to true", name)
 			}
 		}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
index 2ca09df..bc5f366 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
@@ -23,6 +23,7 @@
 	"os"
 	"path/filepath"
 	"regexp"
+	"strings"
 
 	"github.com/google/pprof/internal/plugin"
 	"github.com/google/pprof/internal/report"
@@ -52,24 +53,30 @@
 		return generateReport(p, cmd, pprofVariables, o)
 	}
 
+	if src.HTTPHostport != "" {
+		return serveWebInterface(src.HTTPHostport, p, o)
+	}
 	return interactive(p, o)
 }
 
-func generateReport(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) error {
+func generateRawReport(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) (*command, *report.Report, error) {
 	p = p.Copy() // Prevent modification to the incoming profile.
 
+	// Identify units of numeric tags in profile.
+	numLabelUnits := identifyNumLabelUnits(p, o.UI)
+
 	vars = applyCommandOverrides(cmd, vars)
 
 	// Delay focus after configuring report to get percentages on all samples.
 	relative := vars["relative_percentages"].boolValue()
 	if relative {
-		if err := applyFocus(p, vars, o.UI); err != nil {
-			return err
+		if err := applyFocus(p, numLabelUnits, vars, o.UI); err != nil {
+			return nil, nil, err
 		}
 	}
-	ropt, err := reportOptions(p, vars)
+	ropt, err := reportOptions(p, numLabelUnits, vars)
 	if err != nil {
-		return err
+		return nil, nil, err
 	}
 	c := pprofCommands[cmd[0]]
 	if c == nil {
@@ -79,18 +86,27 @@
 	if len(cmd) == 2 {
 		s, err := regexp.Compile(cmd[1])
 		if err != nil {
-			return fmt.Errorf("parsing argument regexp %s: %v", cmd[1], err)
+			return nil, nil, fmt.Errorf("parsing argument regexp %s: %v", cmd[1], err)
 		}
 		ropt.Symbol = s
 	}
 
 	rpt := report.New(p, ropt)
 	if !relative {
-		if err := applyFocus(p, vars, o.UI); err != nil {
-			return err
+		if err := applyFocus(p, numLabelUnits, vars, o.UI); err != nil {
+			return nil, nil, err
 		}
 	}
 	if err := aggregate(p, vars); err != nil {
+		return nil, nil, err
+	}
+
+	return c, rpt, nil
+}
+
+func generateReport(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) error {
+	c, rpt, err := generateRawReport(p, cmd, vars, o)
+	if err != nil {
 		return err
 	}
 
@@ -160,20 +176,20 @@
 			v.set("nodecount", "80")
 		}
 	}
-	if trim == false {
+	if !trim {
 		v.set("nodecount", "0")
 		v.set("nodefraction", "0")
 		v.set("edgefraction", "0")
 	}
-	if focus == false {
+	if !focus {
 		v.set("focus", "")
 		v.set("ignore", "")
 	}
-	if tagfocus == false {
+	if !tagfocus {
 		v.set("tagfocus", "")
 		v.set("tagignore", "")
 	}
-	if hide == false {
+	if !hide {
 		v.set("hide", "")
 		v.set("show", "")
 	}
@@ -196,25 +212,20 @@
 	case v["functions"].boolValue():
 		inlines = true
 		function = true
-		filename = true
 	case v["noinlines"].boolValue():
 		function = true
-		filename = true
 	case v["addressnoinlines"].boolValue():
 		function = true
 		filename = true
 		linenumber = true
 		address = true
-	case v["functionnameonly"].boolValue():
-		inlines = true
-		function = true
 	default:
 		return fmt.Errorf("unexpected granularity")
 	}
 	return prof.Aggregate(inlines, function, filename, linenumber, address)
 }
 
-func reportOptions(p *profile.Profile, vars variables) (*report.Options, error) {
+func reportOptions(p *profile.Profile, numLabelUnits map[string]string, vars variables) (*report.Options, error) {
 	si, mean := vars["sample_index"].value, vars["mean"].boolValue()
 	value, meanDiv, sample, err := sampleFormat(p, si, mean)
 	if err != nil {
@@ -230,6 +241,14 @@
 		return nil, fmt.Errorf("zero divisor specified")
 	}
 
+	var filters []string
+	for _, k := range []string{"focus", "ignore", "hide", "show", "tagfocus", "tagignore", "tagshow", "taghide"} {
+		v := vars[k].value
+		if v != "" {
+			filters = append(filters, k+"="+v)
+		}
+	}
+
 	ropt := &report.Options{
 		CumSort:             vars["cum"].boolValue(),
 		CallTree:            vars["call_tree"].boolValue(),
@@ -243,6 +262,9 @@
 		NodeFraction: vars["nodefraction"].floatValue(),
 		EdgeFraction: vars["edgefraction"].floatValue(),
 
+		ActiveFilters: filters,
+		NumLabelUnits: numLabelUnits,
+
 		SampleValue:       value,
 		SampleMeanDivisor: meanDiv,
 		SampleType:        stype,
@@ -260,6 +282,19 @@
 	return ropt, nil
 }
 
+// identifyNumLabelUnits returns a map of numeric label keys to the units
+// associated with those keys.
+func identifyNumLabelUnits(p *profile.Profile, ui plugin.UI) map[string]string {
+	numLabelUnits, ignoredUnits := p.NumLabelUnits()
+
+	// Print errors for tags with multiple units associated with
+	// a single key.
+	for k, units := range ignoredUnits {
+		ui.PrintErr(fmt.Sprintf("For tag %s used unit %s, also encountered unit(s) %s", k, numLabelUnits[k], strings.Join(units, ", ")))
+	}
+	return numLabelUnits
+}
+
 type sampleValueFunc func([]int64) int64
 
 // sampleFormat returns a function to extract values out of a profile.Sample,
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go
index c60ad81..ba5b502 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go
@@ -28,13 +28,13 @@
 var tagFilterRangeRx = regexp.MustCompile("([[:digit:]]+)([[:alpha:]]+)")
 
 // applyFocus filters samples based on the focus/ignore options
-func applyFocus(prof *profile.Profile, v variables, ui plugin.UI) error {
+func applyFocus(prof *profile.Profile, numLabelUnits map[string]string, v variables, ui plugin.UI) error {
 	focus, err := compileRegexOption("focus", v["focus"].value, nil)
 	ignore, err := compileRegexOption("ignore", v["ignore"].value, err)
 	hide, err := compileRegexOption("hide", v["hide"].value, err)
 	show, err := compileRegexOption("show", v["show"].value, err)
-	tagfocus, err := compileTagFilter("tagfocus", v["tagfocus"].value, ui, err)
-	tagignore, err := compileTagFilter("tagignore", v["tagignore"].value, ui, err)
+	tagfocus, err := compileTagFilter("tagfocus", v["tagfocus"].value, numLabelUnits, ui, err)
+	tagignore, err := compileTagFilter("tagignore", v["tagignore"].value, numLabelUnits, ui, err)
 	prunefrom, err := compileRegexOption("prune_from", v["prune_from"].value, err)
 	if err != nil {
 		return err
@@ -59,7 +59,7 @@
 	if prunefrom != nil {
 		prof.PruneFrom(prunefrom)
 	}
-	return nil
+	return err
 }
 
 func compileRegexOption(name, value string, err error) (*regexp.Regexp, error) {
@@ -73,23 +73,49 @@
 	return rx, nil
 }
 
-func compileTagFilter(name, value string, ui plugin.UI, err error) (func(*profile.Sample) bool, error) {
+func compileTagFilter(name, value string, numLabelUnits map[string]string, ui plugin.UI, err error) (func(*profile.Sample) bool, error) {
 	if value == "" || err != nil {
 		return nil, err
 	}
+
+	tagValuePair := strings.SplitN(value, "=", 2)
+	var wantKey string
+	if len(tagValuePair) == 2 {
+		wantKey = tagValuePair[0]
+		value = tagValuePair[1]
+	}
+
 	if numFilter := parseTagFilterRange(value); numFilter != nil {
 		ui.PrintErr(name, ":Interpreted '", value, "' as range, not regexp")
-		return func(s *profile.Sample) bool {
-			for key, vals := range s.NumLabel {
-				for _, val := range vals {
-					if numFilter(val, key) {
+		labelFilter := func(vals []int64, unit string) bool {
+			for _, val := range vals {
+				if numFilter(val, unit) {
+					return true
+				}
+			}
+			return false
+		}
+		numLabelUnit := func(key string) string {
+			return numLabelUnits[key]
+		}
+		if wantKey == "" {
+			return func(s *profile.Sample) bool {
+				for key, vals := range s.NumLabel {
+					if labelFilter(vals, numLabelUnit(key)) {
 						return true
 					}
 				}
+				return false
+			}, nil
+		}
+		return func(s *profile.Sample) bool {
+			if vals, ok := s.NumLabel[wantKey]; ok {
+				return labelFilter(vals, numLabelUnit(wantKey))
 			}
 			return false
 		}, nil
 	}
+
 	var rfx []*regexp.Regexp
 	for _, tagf := range strings.Split(value, ",") {
 		fx, err := regexp.Compile(tagf)
@@ -98,19 +124,34 @@
 		}
 		rfx = append(rfx, fx)
 	}
+	if wantKey == "" {
+		return func(s *profile.Sample) bool {
+		matchedrx:
+			for _, rx := range rfx {
+				for key, vals := range s.Label {
+					for _, val := range vals {
+						// TODO: Match against val, not key:val in future
+						if rx.MatchString(key + ":" + val) {
+							continue matchedrx
+						}
+					}
+				}
+				return false
+			}
+			return true
+		}, nil
+	}
 	return func(s *profile.Sample) bool {
-	matchedrx:
-		for _, rx := range rfx {
-			for key, vals := range s.Label {
+		if vals, ok := s.Label[wantKey]; ok {
+			for _, rx := range rfx {
 				for _, val := range vals {
-					if rx.MatchString(key + ":" + val) {
-						continue matchedrx
+					if rx.MatchString(val) {
+						return true
 					}
 				}
 			}
-			return false
 		}
-		return true
+		return false
 	}, nil
 }
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
index 75eaebe..1289a09 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
@@ -16,9 +16,13 @@
 
 import (
 	"bytes"
+	"flag"
 	"fmt"
 	"io/ioutil"
+	"net"
+	_ "net/http/pprof"
 	"os"
+	"reflect"
 	"regexp"
 	"runtime"
 	"strconv"
@@ -32,52 +36,61 @@
 	"github.com/google/pprof/profile"
 )
 
+var updateFlag = flag.Bool("update", false, "Update the golden files")
+
 func TestParse(t *testing.T) {
 	// Override weblist command to collect output in buffer
 	pprofCommands["weblist"].postProcess = nil
 
 	// Our mockObjTool.Open will always return success, causing
-	// driver.locateBinaries to "find" the binaries below in a non-existant
+	// driver.locateBinaries to "find" the binaries below in a non-existent
 	// directory. As a workaround, point the search path to the fake
 	// directory containing out fake binaries.
 	savePath := os.Getenv("PPROF_BINARY_PATH")
 	os.Setenv("PPROF_BINARY_PATH", "/path/to")
 	defer os.Setenv("PPROF_BINARY_PATH", savePath)
-
 	testcase := []struct {
 		flags, source string
 	}{
 		{"text,functions,flat", "cpu"},
 		{"tree,addresses,flat,nodecount=4", "cpusmall"},
-		{"text,functions,flat", "unknown"},
+		{"text,functions,flat,nodecount=5,call_tree", "unknown"},
 		{"text,alloc_objects,flat", "heap_alloc"},
 		{"text,files,flat", "heap"},
+		{"text,files,flat,focus=[12]00,taghide=[X3]00", "heap"},
 		{"text,inuse_objects,flat", "heap"},
 		{"text,lines,cum,hide=line[X3]0", "cpu"},
 		{"text,lines,cum,show=[12]00", "cpu"},
+		{"text,lines,cum,hide=line[X3]0,focus=[12]00", "cpu"},
 		{"topproto,lines,cum,hide=mangled[X3]0", "cpu"},
 		{"tree,lines,cum,focus=[24]00", "heap"},
 		{"tree,relative_percentages,cum,focus=[24]00", "heap"},
 		{"callgrind", "cpu"},
+		{"callgrind,call_tree", "cpu"},
 		{"callgrind", "heap"},
 		{"dot,functions,flat", "cpu"},
+		{"dot,functions,flat,call_tree", "cpu"},
 		{"dot,lines,flat,focus=[12]00", "heap"},
+		{"dot,unit=minimum", "heap_sizetags"},
 		{"dot,addresses,flat,ignore=[X3]002,focus=[X1]000", "contention"},
 		{"dot,files,cum", "contention"},
-		{"comments", "cpu"},
+		{"comments,add_comment=some-comment", "cpu"},
 		{"comments", "heap"},
 		{"tags", "cpu"},
 		{"tags,tagignore=tag[13],tagfocus=key[12]", "cpu"},
 		{"tags", "heap"},
 		{"tags,unit=bytes", "heap"},
 		{"traces", "cpu"},
+		{"traces", "heap_tags"},
 		{"dot,alloc_space,flat,focus=[234]00", "heap_alloc"},
+		{"dot,alloc_space,flat,tagshow=[2]00", "heap_alloc"},
 		{"dot,alloc_space,flat,hide=line.*1?23?", "heap_alloc"},
 		{"dot,inuse_space,flat,tagfocus=1mb:2gb", "heap"},
 		{"dot,inuse_space,flat,tagfocus=30kb:,tagignore=1mb:2mb", "heap"},
 		{"disasm=line[13],addresses,flat", "cpu"},
 		{"peek=line.*01", "cpu"},
 		{"weblist=line[13],addresses,flat", "cpu"},
+		{"tags,tagfocus=400kb:", "heap_request"},
 	}
 
 	baseVars := pprofVariables
@@ -99,6 +112,7 @@
 		if err != nil {
 			t.Errorf("cannot create tempfile: %v", err)
 		}
+		defer os.Remove(protoTempFile.Name())
 		defer protoTempFile.Close()
 		f.strings["output"] = protoTempFile.Name()
 
@@ -124,6 +138,7 @@
 		if err != nil {
 			t.Errorf("cannot create tempfile: %v", err)
 		}
+		defer os.Remove(outputTempFile.Name())
 		defer outputTempFile.Close()
 		f.strings["output"] = outputTempFile.Name()
 		f.args = []string{protoTempFile.Name()}
@@ -140,6 +155,8 @@
 			addFlags(&f, flags[:1])
 			solution = solutionFilename(tc.source, &f)
 		}
+		// The add_comment flag is not idempotent so only apply it on the first run.
+		delete(f.strings, "add_comment")
 
 		// Second pprof invocation to read the profile from profile.proto
 		// and generate a report.
@@ -180,6 +197,12 @@
 				t.Fatalf("diff %s %v", solution, err)
 			}
 			t.Errorf("%s\n%s\n", solution, d)
+			if *updateFlag {
+				err := ioutil.WriteFile(solution, b, 0644)
+				if err != nil {
+					t.Errorf("failed to update the solution file %q: %v", solution, err)
+				}
+			}
 		}
 	}
 }
@@ -214,14 +237,19 @@
 	}
 }
 
+func testSourceURL(port int) string {
+	return fmt.Sprintf("http://%s/", net.JoinHostPort(testSourceAddress, strconv.Itoa(port)))
+}
+
 // solutionFilename returns the name of the solution file for the test
 func solutionFilename(source string, f *testFlags) string {
-	name := []string{"pprof", strings.TrimPrefix(source, "http://host:8000/")}
+	name := []string{"pprof", strings.TrimPrefix(source, testSourceURL(8000))}
 	name = addString(name, f, []string{"flat", "cum"})
 	name = addString(name, f, []string{"functions", "files", "lines", "addresses"})
 	name = addString(name, f, []string{"inuse_space", "inuse_objects", "alloc_space", "alloc_objects"})
 	name = addString(name, f, []string{"relative_percentages"})
 	name = addString(name, f, []string{"seconds"})
+	name = addString(name, f, []string{"call_tree"})
 	name = addString(name, f, []string{"text", "tree", "callgrind", "dot", "svg", "tags", "dot", "traces", "disasm", "peek", "weblist", "topproto", "comments"})
 	if f.strings["focus"] != "" || f.strings["tagfocus"] != "" {
 		name = append(name, "focus")
@@ -247,11 +275,12 @@
 
 // testFlags implements the plugin.FlagSet interface.
 type testFlags struct {
-	bools   map[string]bool
-	ints    map[string]int
-	floats  map[string]float64
-	strings map[string]string
-	args    []string
+	bools       map[string]bool
+	ints        map[string]int
+	floats      map[string]float64
+	strings     map[string]string
+	args        []string
+	stringLists map[string][]*string
 }
 
 func (testFlags) ExtraUsage() string { return "" }
@@ -317,6 +346,9 @@
 }
 
 func (f testFlags) StringList(s, d, c string) *[]*string {
+	if t, ok := f.stringLists[s]; ok {
+		return &t
+	}
 	return &[]*string{}
 }
 
@@ -345,9 +377,6 @@
 	}
 }
 
-type testProfile struct {
-}
-
 const testStart = 0x1000
 const testOffset = 0x5000
 
@@ -355,7 +384,6 @@
 
 func (testFetcher) Fetch(s string, d, t time.Duration) (*profile.Profile, string, error) {
 	var p *profile.Profile
-	s = strings.TrimPrefix(s, "http://host:8000/")
 	switch s {
 	case "cpu", "unknown":
 		p = cpuProfile()
@@ -369,21 +397,36 @@
 			{Type: "alloc_objects", Unit: "count"},
 			{Type: "alloc_space", Unit: "bytes"},
 		}
+	case "heap_request":
+		p = heapProfile()
+		for _, s := range p.Sample {
+			s.NumLabel["request"] = s.NumLabel["bytes"]
+		}
+	case "heap_sizetags":
+		p = heapProfile()
+		tags := []int64{2, 4, 8, 16, 32, 64, 128, 256}
+		for _, s := range p.Sample {
+			numValues := append(s.NumLabel["bytes"], tags...)
+			s.NumLabel["bytes"] = numValues
+		}
+	case "heap_tags":
+		p = heapProfile()
+		for i := 0; i < len(p.Sample); i += 2 {
+			s := p.Sample[i]
+			if s.Label == nil {
+				s.Label = make(map[string][]string)
+			}
+			s.NumLabel["request"] = s.NumLabel["bytes"]
+			s.Label["key1"] = []string{"tag"}
+		}
 	case "contention":
 		p = contentionProfile()
 	case "symbolz":
 		p = symzProfile()
-	case "http://host2/symbolz":
-		p = symzProfile()
-		p.Mapping[0].Start += testOffset
-		p.Mapping[0].Limit += testOffset
-		for i := range p.Location {
-			p.Location[i].Address += testOffset
-		}
 	default:
 		return nil, "", fmt.Errorf("unexpected source: %s", s)
 	}
-	return p, s, nil
+	return p, testSourceURL(8000) + s, nil
 }
 
 type testSymbolizer struct{}
@@ -406,7 +449,19 @@
 func testFetchSymbols(source, post string) ([]byte, error) {
 	var buf bytes.Buffer
 
-	if source == "http://host2/symbolz" {
+	switch source {
+	case testSourceURL(8000) + "symbolz":
+		for _, address := range strings.Split(post, "+") {
+			a, _ := strconv.ParseInt(address, 0, 64)
+			fmt.Fprintf(&buf, "%v\t", address)
+			if a-testStart > testOffset {
+				fmt.Fprintf(&buf, "wrong_source_%v_", address)
+				continue
+			}
+			fmt.Fprintf(&buf, "%#x\n", a-testStart)
+		}
+		return buf.Bytes(), nil
+	case testSourceURL(8001) + "symbolz":
 		for _, address := range strings.Split(post, "+") {
 			a, _ := strconv.ParseInt(address, 0, 64)
 			fmt.Fprintf(&buf, "%v\t", address)
@@ -417,23 +472,15 @@
 			fmt.Fprintf(&buf, "%#x\n", a-testStart-testOffset)
 		}
 		return buf.Bytes(), nil
+	default:
+		return nil, fmt.Errorf("unexpected source: %s", source)
 	}
-	for _, address := range strings.Split(post, "+") {
-		a, _ := strconv.ParseInt(address, 0, 64)
-		fmt.Fprintf(&buf, "%v\t", address)
-		if a-testStart > testOffset {
-			fmt.Fprintf(&buf, "wrong_source_%v_", address)
-			continue
-		}
-		fmt.Fprintf(&buf, "%#x\n", a-testStart)
-	}
-	return buf.Bytes(), nil
 }
 
 type testSymbolzSymbolizer struct{}
 
 func (testSymbolzSymbolizer) Symbolize(variables string, sources plugin.MappingSources, p *profile.Profile) error {
-	return symbolz.Symbolize(sources, testFetchSymbols, p, nil)
+	return symbolz.Symbolize(p, false, sources, testFetchSymbols, nil)
 }
 
 func fakeDemangler(name string) string {
@@ -543,32 +590,32 @@
 				Location: []*profile.Location{cpuL[0], cpuL[1], cpuL[2]},
 				Value:    []int64{1000, 1000},
 				Label: map[string][]string{
-					"key1": []string{"tag1"},
-					"key2": []string{"tag1"},
+					"key1": {"tag1"},
+					"key2": {"tag1"},
 				},
 			},
 			{
 				Location: []*profile.Location{cpuL[0], cpuL[3]},
 				Value:    []int64{100, 100},
 				Label: map[string][]string{
-					"key1": []string{"tag2"},
-					"key3": []string{"tag2"},
+					"key1": {"tag2"},
+					"key3": {"tag2"},
 				},
 			},
 			{
 				Location: []*profile.Location{cpuL[1], cpuL[4]},
 				Value:    []int64{10, 10},
 				Label: map[string][]string{
-					"key1": []string{"tag3"},
-					"key2": []string{"tag2"},
+					"key1": {"tag3"},
+					"key2": {"tag2"},
 				},
 			},
 			{
 				Location: []*profile.Location{cpuL[2]},
 				Value:    []int64{10, 10},
 				Label: map[string][]string{
-					"key1": []string{"tag4"},
-					"key2": []string{"tag1"},
+					"key1": {"tag4"},
+					"key2": {"tag1"},
 				},
 			},
 		},
@@ -744,30 +791,22 @@
 			{
 				Location: []*profile.Location{heapL[0], heapL[1], heapL[2]},
 				Value:    []int64{10, 1024000},
-				NumLabel: map[string][]int64{
-					"bytes": []int64{102400},
-				},
+				NumLabel: map[string][]int64{"bytes": {102400}},
 			},
 			{
 				Location: []*profile.Location{heapL[0], heapL[3]},
 				Value:    []int64{20, 4096000},
-				NumLabel: map[string][]int64{
-					"bytes": []int64{204800},
-				},
+				NumLabel: map[string][]int64{"bytes": {204800}},
 			},
 			{
 				Location: []*profile.Location{heapL[1], heapL[4]},
 				Value:    []int64{40, 65536000},
-				NumLabel: map[string][]int64{
-					"bytes": []int64{1638400},
-				},
+				NumLabel: map[string][]int64{"bytes": {1638400}},
 			},
 			{
 				Location: []*profile.Location{heapL[2]},
 				Value:    []int64{80, 32768000},
-				NumLabel: map[string][]int64{
-					"bytes": []int64{409600},
-				},
+				NumLabel: map[string][]int64{"bytes": {409600}},
 			},
 		},
 		DropFrames: ".*operator new.*|malloc",
@@ -950,40 +989,406 @@
 
 func TestTagFilter(t *testing.T) {
 	var tagFilterTests = []struct {
-		name, value string
+		desc, value string
 		tags        map[string][]string
 		want        bool
 	}{
-		{"test1", "tag2", map[string][]string{"value1": {"tag1", "tag2"}}, true},
-		{"test2", "tag3", map[string][]string{"value1": {"tag1", "tag2"}}, false},
-		{"test3", "tag1,tag3", map[string][]string{"value1": {"tag1", "tag2"}, "value2": {"tag3"}}, true},
-		{"test4", "t..[12],t..3", map[string][]string{"value1": {"tag1", "tag2"}, "value2": {"tag3"}}, true},
-		{"test5", "tag2,tag3", map[string][]string{"value1": {"tag1", "tag2"}}, false},
+		{
+			"1 key with 1 matching value",
+			"tag2",
+			map[string][]string{"value1": {"tag1", "tag2"}},
+			true,
+		},
+		{
+			"1 key with no matching values",
+			"tag3",
+			map[string][]string{"value1": {"tag1", "tag2"}},
+			false,
+		},
+		{
+			"two keys, each with value matching different one value in list",
+			"tag1,tag3",
+			map[string][]string{"value1": {"tag1", "tag2"}, "value2": {"tag3"}},
+			true,
+		},
+		{"two keys, all value matching different regex value in list",
+			"t..[12],t..3",
+			map[string][]string{"value1": {"tag1", "tag2"}, "value2": {"tag3"}},
+			true,
+		},
+		{
+			"one key, not all values in list matched",
+			"tag2,tag3",
+			map[string][]string{"value1": {"tag1", "tag2"}},
+			false,
+		},
+		{
+			"key specified, list of tags where all tags in list matched",
+			"key1=tag1,tag2",
+			map[string][]string{"key1": {"tag1", "tag2"}},
+			true,
+		},
+		{"key specified, list of tag values where not all are matched",
+			"key1=tag1,tag2",
+			map[string][]string{"key1": {"tag1"}},
+			true,
+		},
+		{
+			"key included for regex matching, list of values where all values in list matched",
+			"key1:tag1,tag2",
+			map[string][]string{"key1": {"tag1", "tag2"}},
+			true,
+		},
+		{
+			"key included for regex matching, list of values where not only second value matched",
+			"key1:tag1,tag2",
+			map[string][]string{"key1": {"tag2"}},
+			false,
+		},
+		{
+			"key included for regex matching, list of values where not only first value matched",
+			"key1:tag1,tag2",
+			map[string][]string{"key1": {"tag1"}},
+			false,
+		},
 	}
-
 	for _, test := range tagFilterTests {
-		filter, err := compileTagFilter(test.name, test.value, &proftest.TestUI{T: t}, nil)
-		if err != nil {
-			t.Errorf("tagFilter %s:%v", test.name, err)
-			continue
-		}
-		s := profile.Sample{
-			Label: test.tags,
-		}
-
-		if got := filter(&s); got != test.want {
-			t.Errorf("tagFilter %s: got %v, want %v", test.name, got, test.want)
-		}
+		t.Run(test.desc, func(*testing.T) {
+			filter, err := compileTagFilter(test.desc, test.value, nil, &proftest.TestUI{T: t}, nil)
+			if err != nil {
+				t.Fatalf("tagFilter %s:%v", test.desc, err)
+			}
+			s := profile.Sample{
+				Label: test.tags,
+			}
+			if got := filter(&s); got != test.want {
+				t.Errorf("tagFilter %s: got %v, want %v", test.desc, got, test.want)
+			}
+		})
 	}
 }
 
+func TestIdentifyNumLabelUnits(t *testing.T) {
+	var tagFilterTests = []struct {
+		desc               string
+		tagVals            []map[string][]int64
+		tagUnits           []map[string][]string
+		wantUnits          map[string]string
+		allowedRx          string
+		wantIgnoreErrCount int
+	}{
+		{
+			"Multiple keys, no units for all keys",
+			[]map[string][]int64{{"keyA": {131072}, "keyB": {128}}},
+			[]map[string][]string{{"keyA": {}, "keyB": {""}}},
+			map[string]string{"keyA": "keyA", "keyB": "keyB"},
+			"",
+			0,
+		},
+		{
+			"Multiple keys, different units for each key",
+			[]map[string][]int64{{"keyA": {131072}, "keyB": {128}}},
+			[]map[string][]string{{"keyA": {"bytes"}, "keyB": {"kilobytes"}}},
+			map[string]string{"keyA": "bytes", "keyB": "kilobytes"},
+			"",
+			0,
+		},
+		{
+			"Multiple keys with multiple values, different units for each key",
+			[]map[string][]int64{{"keyC": {131072, 1}, "keyD": {128, 252}}},
+			[]map[string][]string{{"keyC": {"bytes", "bytes"}, "keyD": {"kilobytes", "kilobytes"}}},
+			map[string]string{"keyC": "bytes", "keyD": "kilobytes"},
+			"",
+			0,
+		},
+		{
+			"Multiple keys with multiple values, some units missing",
+			[]map[string][]int64{{"key1": {131072, 1}, "A": {128, 252}, "key3": {128}, "key4": {1}}, {"key3": {128}, "key4": {1}}},
+			[]map[string][]string{{"key1": {"", "bytes"}, "A": {"kilobytes", ""}, "key3": {""}, "key4": {"hour"}}, {"key3": {"seconds"}, "key4": {""}}},
+			map[string]string{"key1": "bytes", "A": "kilobytes", "key3": "seconds", "key4": "hour"},
+			"",
+			0,
+		},
+		{
+			"One key with three units in same sample",
+			[]map[string][]int64{{"key": {8, 8, 16}}},
+			[]map[string][]string{{"key": {"bytes", "megabytes", "kilobytes"}}},
+			map[string]string{"key": "bytes"},
+			`(For tag key used unit bytes, also encountered unit\(s\) kilobytes, megabytes)`,
+			1,
+		},
+		{
+			"One key with four units in same sample",
+			[]map[string][]int64{{"key": {8, 8, 16, 32}}},
+			[]map[string][]string{{"key": {"bytes", "kilobytes", "a", "megabytes"}}},
+			map[string]string{"key": "bytes"},
+			`(For tag key used unit bytes, also encountered unit\(s\) a, kilobytes, megabytes)`,
+			1,
+		},
+		{
+			"One key with two units in same sample",
+			[]map[string][]int64{{"key": {8, 8}}},
+			[]map[string][]string{{"key": {"bytes", "seconds"}}},
+			map[string]string{"key": "bytes"},
+			`(For tag key used unit bytes, also encountered unit\(s\) seconds)`,
+			1,
+		},
+		{
+			"One key with different units in different samples",
+			[]map[string][]int64{{"key1": {8}}, {"key1": {8}}, {"key1": {8}}},
+			[]map[string][]string{{"key1": {"bytes"}}, {"key1": {"kilobytes"}}, {"key1": {"megabytes"}}},
+			map[string]string{"key1": "bytes"},
+			`(For tag key1 used unit bytes, also encountered unit\(s\) kilobytes, megabytes)`,
+			1,
+		},
+		{
+			"Key alignment, unit not specified",
+			[]map[string][]int64{{"alignment": {8}}},
+			[]map[string][]string{nil},
+			map[string]string{"alignment": "bytes"},
+			"",
+			0,
+		},
+		{
+			"Key request, unit not specified",
+			[]map[string][]int64{{"request": {8}}, {"request": {8, 8}}},
+			[]map[string][]string{nil, nil},
+			map[string]string{"request": "bytes"},
+			"",
+			0,
+		},
+		{
+			"Check units not over-written for keys with default units",
+			[]map[string][]int64{{
+				"alignment": {8},
+				"request":   {8},
+				"bytes":     {8},
+			}},
+			[]map[string][]string{{
+				"alignment": {"seconds"},
+				"request":   {"minutes"},
+				"bytes":     {"hours"},
+			}},
+			map[string]string{
+				"alignment": "seconds",
+				"request":   "minutes",
+				"bytes":     "hours",
+			},
+			"",
+			0,
+		},
+	}
+	for _, test := range tagFilterTests {
+		t.Run(test.desc, func(*testing.T) {
+			p := profile.Profile{Sample: make([]*profile.Sample, len(test.tagVals))}
+			for i, numLabel := range test.tagVals {
+				s := profile.Sample{
+					NumLabel: numLabel,
+					NumUnit:  test.tagUnits[i],
+				}
+				p.Sample[i] = &s
+			}
+			testUI := &proftest.TestUI{T: t, AllowRx: test.allowedRx}
+			units := identifyNumLabelUnits(&p, testUI)
+			if !reflect.DeepEqual(test.wantUnits, units) {
+				t.Errorf("got %v units, want %v", units, test.wantUnits)
+			}
+			if got, want := testUI.NumAllowRxMatches, test.wantIgnoreErrCount; want != got {
+				t.Errorf("got %d errors logged, want %d errors logged", got, want)
+			}
+		})
+	}
+}
+
+func TestNumericTagFilter(t *testing.T) {
+	var tagFilterTests = []struct {
+		desc, value     string
+		tags            map[string][]int64
+		identifiedUnits map[string]string
+		want            bool
+	}{
+		{
+			"Match when unit conversion required",
+			"128kb",
+			map[string][]int64{"key1": {131072}, "key2": {128}},
+			map[string]string{"key1": "bytes", "key2": "kilobytes"},
+			true,
+		},
+		{
+			"Match only when values equal after unit conversion",
+			"512kb",
+			map[string][]int64{"key1": {512}, "key2": {128}},
+			map[string]string{"key1": "bytes", "key2": "kilobytes"},
+			false,
+		},
+		{
+			"Match when values and units initially equal",
+			"10bytes",
+			map[string][]int64{"key1": {10}, "key2": {128}},
+			map[string]string{"key1": "bytes", "key2": "kilobytes"},
+			true,
+		},
+		{
+			"Match range without lower bound, no unit conversion required",
+			":10bytes",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "bytes"},
+			true,
+		},
+		{
+			"Match range without lower bound, unit conversion required",
+			":10kb",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "bytes"},
+			true,
+		},
+		{
+			"Match range without upper bound, unit conversion required",
+			"10b:",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "kilobytes"},
+			true,
+		},
+		{
+			"Match range without upper bound, no unit conversion required",
+			"10b:",
+			map[string][]int64{"key1": {12}},
+			map[string]string{"key1": "bytes"},
+			true,
+		},
+		{
+			"Don't match range without upper bound, no unit conversion required",
+			"10b:",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "bytes"},
+			false,
+		},
+		{
+			"Multiple keys with different units, don't match range without upper bound",
+			"10kb:",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "bytes", "key2": "kilobytes"},
+			false,
+		},
+		{
+			"Match range without upper bound, unit conversion required",
+			"10b:",
+			map[string][]int64{"key1": {8}},
+			map[string]string{"key1": "kilobytes"},
+			true,
+		},
+		{
+			"Don't match range without lower bound, no unit conversion required",
+			":10b",
+			map[string][]int64{"key1": {12}},
+			map[string]string{"key1": "bytes"},
+			false,
+		},
+		{
+			"Match specific key, key present, one of two values match",
+			"bytes=5b",
+			map[string][]int64{"bytes": {10, 5}},
+			map[string]string{"bytes": "bytes"},
+			true,
+		},
+		{
+			"Match specific key, key present and value matches",
+			"bytes=1024b",
+			map[string][]int64{"bytes": {1024}},
+			map[string]string{"bytes": "kilobytes"},
+			false,
+		},
+		{
+			"Match specific key, matching key present and value matches, also non-matching key",
+			"bytes=1024b",
+			map[string][]int64{"bytes": {1024}, "key2": {5}},
+			map[string]string{"bytes": "bytes", "key2": "bytes"},
+			true,
+		},
+		{
+			"Match specific key and range of values, value matches",
+			"bytes=512b:1024b",
+			map[string][]int64{"bytes": {780}},
+			map[string]string{"bytes": "bytes"},
+			true,
+		},
+		{
+			"Match specific key and range of values, value too large",
+			"key1=1kb:2kb",
+			map[string][]int64{"key1": {4096}},
+			map[string]string{"key1": "bytes"},
+			false,
+		},
+		{
+			"Match specific key and range of values, value too small",
+			"key1=1kb:2kb",
+			map[string][]int64{"key1": {256}},
+			map[string]string{"key1": "bytes"},
+			false,
+		},
+		{
+			"Match specific key and value, unit conversion required",
+			"bytes=1024b",
+			map[string][]int64{"bytes": {1}},
+			map[string]string{"bytes": "kilobytes"},
+			true,
+		},
+		{
+			"Match specific key and value, key does not appear",
+			"key2=256bytes",
+			map[string][]int64{"key1": {256}},
+			map[string]string{"key1": "bytes"},
+			false,
+		},
+	}
+	for _, test := range tagFilterTests {
+		t.Run(test.desc, func(*testing.T) {
+			wantErrMsg := strings.Join([]string{"(", test.desc, ":Interpreted '", test.value[strings.Index(test.value, "=")+1:], "' as range, not regexp", ")"}, "")
+			filter, err := compileTagFilter(test.desc, test.value, test.identifiedUnits, &proftest.TestUI{T: t,
+				AllowRx: wantErrMsg}, nil)
+			if err != nil {
+				t.Fatalf("%v", err)
+			}
+			s := profile.Sample{
+				NumLabel: test.tags,
+			}
+			if got := filter(&s); got != test.want {
+				t.Fatalf("got %v, want %v", got, test.want)
+			}
+		})
+	}
+}
+
+type testSymbolzMergeFetcher struct{}
+
+func (testSymbolzMergeFetcher) Fetch(s string, d, t time.Duration) (*profile.Profile, string, error) {
+	var p *profile.Profile
+	switch s {
+	case testSourceURL(8000) + "symbolz":
+		p = symzProfile()
+	case testSourceURL(8001) + "symbolz":
+		p = symzProfile()
+		p.Mapping[0].Start += testOffset
+		p.Mapping[0].Limit += testOffset
+		for i := range p.Location {
+			p.Location[i].Address += testOffset
+		}
+	default:
+		return nil, "", fmt.Errorf("unexpected source: %s", s)
+	}
+	return p, s, nil
+}
+
 func TestSymbolzAfterMerge(t *testing.T) {
 	baseVars := pprofVariables
 	pprofVariables = baseVars.makeCopy()
 	defer func() { pprofVariables = baseVars }()
 
 	f := baseFlags()
-	f.args = []string{"symbolz", "http://host2/symbolz"}
+	f.args = []string{
+		testSourceURL(8000) + "symbolz",
+		testSourceURL(8001) + "symbolz",
+	}
 
 	o := setDefaults(nil)
 	o.Flagset = f
@@ -997,7 +1402,7 @@
 		t.Fatalf("parseFlags returned command %v, want [proto]", cmd)
 	}
 
-	o.Fetch = testFetcher{}
+	o.Fetch = testSymbolzMergeFetcher{}
 	o.Sym = testSymbolzSymbolizer{}
 	p, err := fetchProfiles(src, o)
 	if err != nil {
@@ -1028,10 +1433,10 @@
 	switch start {
 	case 0x1000:
 		return []plugin.Inst{
-			{Addr: 0x1000, Text: "instruction one"},
-			{Addr: 0x1001, Text: "instruction two"},
-			{Addr: 0x1002, Text: "instruction three"},
-			{Addr: 0x1003, Text: "instruction four"},
+			{Addr: 0x1000, Text: "instruction one", File: "file1000.src", Line: 1},
+			{Addr: 0x1001, Text: "instruction two", File: "file1000.src", Line: 1},
+			{Addr: 0x1002, Text: "instruction three", File: "file1000.src", Line: 2},
+			{Addr: 0x1003, Text: "instruction four", File: "file1000.src", Line: 1},
 		}, nil
 	case 0x3000:
 		return []plugin.Inst{
@@ -1046,7 +1451,7 @@
 }
 
 type mockFile struct {
-	name, buildId string
+	name, buildID string
 	base          uint64
 }
 
@@ -1062,7 +1467,7 @@
 
 // BuildID returns the GNU build ID of the file, or an empty string.
 func (m *mockFile) BuildID() string {
-	return m.buildId
+	return m.buildID
 }
 
 // SourceLine reports the source line information for a given
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
index f9e8231..2b1d90d 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
@@ -41,39 +41,52 @@
 // there are some failures. It will return an error if it is unable to
 // fetch any profiles.
 func fetchProfiles(s *source, o *plugin.Options) (*profile.Profile, error) {
-	sources := make([]profileSource, 0, len(s.Sources)+len(s.Base))
+	sources := make([]profileSource, 0, len(s.Sources))
 	for _, src := range s.Sources {
 		sources = append(sources, profileSource{
 			addr:   src,
 			source: s,
-			scale:  1,
 		})
 	}
+
+	bases := make([]profileSource, 0, len(s.Base))
 	for _, src := range s.Base {
-		sources = append(sources, profileSource{
+		bases = append(bases, profileSource{
 			addr:   src,
 			source: s,
-			scale:  -1,
 		})
 	}
-	p, msrcs, save, cnt, err := chunkedGrab(sources, o.Fetch, o.Obj, o.UI)
+
+	p, pbase, m, mbase, save, err := grabSourcesAndBases(sources, bases, o.Fetch, o.Obj, o.UI)
 	if err != nil {
 		return nil, err
 	}
-	if cnt == 0 {
-		return nil, fmt.Errorf("failed to fetch any profiles")
-	}
-	if want, got := len(sources), cnt; want != got {
-		o.UI.PrintErr(fmt.Sprintf("fetched %d profiles out of %d", got, want))
+
+	if pbase != nil {
+		if s.Normalize {
+			err := p.Normalize(pbase)
+			if err != nil {
+				return nil, err
+			}
+		}
+		pbase.Scale(-1)
+		p, m, err = combineProfiles([]*profile.Profile{p, pbase}, []plugin.MappingSources{m, mbase})
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	// Symbolize the merged profile.
-	if err := o.Sym.Symbolize(s.Symbolize, msrcs, p); err != nil {
+	if err := o.Sym.Symbolize(s.Symbolize, m, p); err != nil {
 		return nil, err
 	}
 	p.RemoveUninteresting()
 	unsourceMappings(p)
 
+	if s.Comment != "" {
+		p.Comments = append(p.Comments, s.Comment)
+	}
+
 	// Save a copy of the merged profile if there is at least one remote source.
 	if save {
 		dir, err := setTmpDir(o.UI)
@@ -107,6 +120,47 @@
 	return p, nil
 }
 
+func grabSourcesAndBases(sources, bases []profileSource, fetch plugin.Fetcher, obj plugin.ObjTool, ui plugin.UI) (*profile.Profile, *profile.Profile, plugin.MappingSources, plugin.MappingSources, bool, error) {
+	wg := sync.WaitGroup{}
+	wg.Add(2)
+	var psrc, pbase *profile.Profile
+	var msrc, mbase plugin.MappingSources
+	var savesrc, savebase bool
+	var errsrc, errbase error
+	var countsrc, countbase int
+	go func() {
+		defer wg.Done()
+		psrc, msrc, savesrc, countsrc, errsrc = chunkedGrab(sources, fetch, obj, ui)
+	}()
+	go func() {
+		defer wg.Done()
+		pbase, mbase, savebase, countbase, errbase = chunkedGrab(bases, fetch, obj, ui)
+	}()
+	wg.Wait()
+	save := savesrc || savebase
+
+	if errsrc != nil {
+		return nil, nil, nil, nil, false, fmt.Errorf("problem fetching source profiles: %v", errsrc)
+	}
+	if errbase != nil {
+		return nil, nil, nil, nil, false, fmt.Errorf("problem fetching base profiles: %v,", errbase)
+	}
+	if countsrc == 0 {
+		return nil, nil, nil, nil, false, fmt.Errorf("failed to fetch any source profiles")
+	}
+	if countbase == 0 && len(bases) > 0 {
+		return nil, nil, nil, nil, false, fmt.Errorf("failed to fetch any base profiles")
+	}
+	if want, got := len(sources), countsrc; want != got {
+		ui.PrintErr(fmt.Sprintf("Fetched %d source profiles out of %d", got, want))
+	}
+	if want, got := len(bases), countbase; want != got {
+		ui.PrintErr(fmt.Sprintf("Fetched %d base profiles out of %d", got, want))
+	}
+
+	return psrc, pbase, msrc, mbase, save, nil
+}
+
 // chunkedGrab fetches the profiles described in source and merges them into
 // a single profile. It fetches a chunk of profiles concurrently, with a maximum
 // chunk size to limit its memory usage.
@@ -142,6 +196,7 @@
 			count += chunkCount
 		}
 	}
+
 	return p, msrc, save, count, nil
 }
 
@@ -152,7 +207,7 @@
 	for i := range sources {
 		go func(s *profileSource) {
 			defer wg.Done()
-			s.p, s.msrc, s.remote, s.err = grabProfile(s.source, s.addr, s.scale, fetch, obj, ui)
+			s.p, s.msrc, s.remote, s.err = grabProfile(s.source, s.addr, fetch, obj, ui)
 		}(&sources[i])
 	}
 	wg.Wait()
@@ -207,7 +262,6 @@
 type profileSource struct {
 	addr   string
 	source *source
-	scale  float64
 
 	p      *profile.Profile
 	msrc   plugin.MappingSources
@@ -227,12 +281,18 @@
 }
 
 // setTmpDir prepares the directory to use to save profiles retrieved
-// remotely. It is selected from PPROF_TMPDIR, defaults to $HOME/pprof.
+// remotely. It is selected from PPROF_TMPDIR, defaults to $HOME/pprof, and, if
+// $HOME is not set, falls back to os.TempDir().
 func setTmpDir(ui plugin.UI) (string, error) {
+	var dirs []string
 	if profileDir := os.Getenv("PPROF_TMPDIR"); profileDir != "" {
-		return profileDir, nil
+		dirs = append(dirs, profileDir)
 	}
-	for _, tmpDir := range []string{os.Getenv(homeEnv()) + "/pprof", os.TempDir()} {
+	if homeDir := os.Getenv(homeEnv()); homeDir != "" {
+		dirs = append(dirs, filepath.Join(homeDir, "pprof"))
+	}
+	dirs = append(dirs, os.TempDir())
+	for _, tmpDir := range dirs {
 		if err := os.MkdirAll(tmpDir, 0755); err != nil {
 			ui.PrintErr("Could not use temp dir ", tmpDir, ": ", err.Error())
 			continue
@@ -242,10 +302,12 @@
 	return "", fmt.Errorf("failed to identify temp dir")
 }
 
+const testSourceAddress = "pproftest.local"
+
 // grabProfile fetches a profile. Returns the profile, sources for the
 // profile mappings, a bool indicating if the profile was fetched
 // remotely, and an error.
-func grabProfile(s *source, source string, scale float64, fetcher plugin.Fetcher, obj plugin.ObjTool, ui plugin.UI) (p *profile.Profile, msrc plugin.MappingSources, remote bool, err error) {
+func grabProfile(s *source, source string, fetcher plugin.Fetcher, obj plugin.ObjTool, ui plugin.UI) (p *profile.Profile, msrc plugin.MappingSources, remote bool, err error) {
 	var src string
 	duration, timeout := time.Duration(s.Seconds)*time.Second, time.Duration(s.Timeout)*time.Second
 	if fetcher != nil {
@@ -266,9 +328,6 @@
 		return
 	}
 
-	// Apply local changes to the profile.
-	p.Scale(scale)
-
 	// Update the binary locations from command line and paths.
 	locateBinaries(p, s, obj, ui)
 
@@ -276,6 +335,11 @@
 	if src != "" {
 		msrc = collectMappingSources(p, src)
 		remote = true
+		if strings.HasPrefix(src, "http://"+testSourceAddress) {
+			// Treat test inputs as local to avoid saving
+			// testcase profiles during driver testing.
+			remote = false
+		}
 	}
 	return
 }
@@ -366,20 +430,20 @@
 			}
 		}
 	}
+	if len(p.Mapping) == 0 {
+		// If there are no mappings, add a fake mapping to attempt symbolization.
+		// This is useful for some profiles generated by the golang runtime, which
+		// do not include any mappings. Symbolization with a fake mapping will only
+		// be successful against a non-PIE binary.
+		m := &profile.Mapping{ID: 1}
+		p.Mapping = []*profile.Mapping{m}
+		for _, l := range p.Location {
+			l.Mapping = m
+		}
+	}
 	// Replace executable filename/buildID with the overrides from source.
 	// Assumes the executable is the first Mapping entry.
 	if execName, buildID := s.ExecName, s.BuildID; execName != "" || buildID != "" {
-		if len(p.Mapping) == 0 {
-			// If there are no mappings, add a fake mapping to attempt symbolization.
-			// This is useful for some profiles generated by the golang runtime, which
-			// do not include any mappings. Symbolization with a fake mapping will only
-			// be successful against a non-PIE binary.
-			m := &profile.Mapping{ID: 1}
-			p.Mapping = []*profile.Mapping{m}
-			for _, l := range p.Location {
-				l.Mapping = m
-			}
-		}
 		m := p.Mapping[0]
 		if execName != "" {
 			m.File = execName
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go
index 90b84b2..abce5b5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go
@@ -15,8 +15,15 @@
 package driver
 
 import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/pem"
 	"fmt"
 	"io/ioutil"
+	"math/big"
 	"net/http"
 	"net/url"
 	"os"
@@ -24,11 +31,14 @@
 	"reflect"
 	"regexp"
 	"runtime"
+	"strings"
 	"testing"
 	"time"
 
+	"github.com/google/pprof/internal/binutils"
 	"github.com/google/pprof/internal/plugin"
 	"github.com/google/pprof/internal/proftest"
+	"github.com/google/pprof/internal/symbolizer"
 	"github.com/google/pprof/profile"
 )
 
@@ -165,6 +175,8 @@
 	const path = "testdata/"
 
 	// Intercept http.Get calls from HTTPFetcher.
+	savedHTTPGet := httpGet
+	defer func() { httpGet = savedHTTPGet }()
 	httpGet = stubHTTPGet
 
 	type testcase struct {
@@ -176,7 +188,7 @@
 		{path + "go.nomappings.crash", "/bin/gotest.exe"},
 		{"http://localhost/profile?file=cppbench.cpu", ""},
 	} {
-		p, _, _, err := grabProfile(&source{ExecName: tc.execName}, tc.source, 0, nil, testObj{}, &proftest.TestUI{T: t})
+		p, _, _, err := grabProfile(&source{ExecName: tc.execName}, tc.source, nil, testObj{}, &proftest.TestUI{T: t})
 		if err != nil {
 			t.Fatalf("%s: %s", tc.source, err)
 		}
@@ -194,6 +206,117 @@
 	}
 }
 
+func TestFetchWithBase(t *testing.T) {
+	baseVars := pprofVariables
+	defer func() { pprofVariables = baseVars }()
+
+	const path = "testdata/"
+	type testcase struct {
+		desc            string
+		sources         []string
+		bases           []string
+		normalize       bool
+		expectedSamples [][]int64
+	}
+
+	testcases := []testcase{
+		{
+			"not normalized base is same as source",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.contention"},
+			false,
+			[][]int64{},
+		},
+		{
+			"not normalized single source, multiple base (all profiles same)",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.contention", path + "cppbench.contention"},
+			false,
+			[][]int64{{-2700, -608881724}, {-100, -23992}, {-200, -179943}, {-100, -17778444}, {-100, -75976}, {-300, -63568134}},
+		},
+		{
+			"not normalized, different base and source",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.small.contention"},
+			false,
+			[][]int64{{1700, 608878600}, {100, 23992}, {200, 179943}, {100, 17778444}, {100, 75976}, {300, 63568134}},
+		},
+		{
+			"normalized base is same as source",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.contention"},
+			true,
+			[][]int64{},
+		},
+		{
+			"normalized single source, multiple base (all profiles same)",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.contention", path + "cppbench.contention"},
+			true,
+			[][]int64{},
+		},
+		{
+			"normalized different base and source",
+			[]string{path + "cppbench.contention"},
+			[]string{path + "cppbench.small.contention"},
+			true,
+			[][]int64{{-229, -370}, {28, 0}, {57, 0}, {28, 80}, {28, 0}, {85, 287}},
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.desc, func(t *testing.T) {
+			pprofVariables = baseVars.makeCopy()
+
+			base := make([]*string, len(tc.bases))
+			for i, s := range tc.bases {
+				base[i] = &s
+			}
+
+			f := testFlags{
+				stringLists: map[string][]*string{
+					"base": base,
+				},
+				bools: map[string]bool{
+					"normalize": tc.normalize,
+				},
+			}
+			f.args = tc.sources
+
+			o := setDefaults(nil)
+			o.Flagset = f
+			src, _, err := parseFlags(o)
+
+			if err != nil {
+				t.Fatalf("%s: %v", tc.desc, err)
+			}
+
+			p, err := fetchProfiles(src, o)
+			pprofVariables = baseVars
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			if want, got := len(tc.expectedSamples), len(p.Sample); want != got {
+				t.Fatalf("want %d samples got %d", want, got)
+			}
+
+			if len(p.Sample) > 0 {
+				for i, sample := range p.Sample {
+					if want, got := len(tc.expectedSamples[i]), len(sample.Value); want != got {
+						t.Errorf("want %d values for sample %d, got %d", want, i, got)
+					}
+					for j, value := range sample.Value {
+						if want, got := tc.expectedSamples[i][j], value; want != got {
+							t.Errorf("want value of %d for value %d of sample %d, got %d", want, j, i, got)
+						}
+					}
+				}
+			}
+		})
+	}
+}
+
 // mappingSources creates MappingSources map with a single item.
 func mappingSources(key, source string, start uint64) plugin.MappingSources {
 	return plugin.MappingSources{
@@ -227,3 +350,158 @@
 	c := &http.Client{Transport: t}
 	return c.Get("file:///" + file)
 }
+
+func closedError() string {
+	if runtime.GOOS == "plan9" {
+		return "listen hungup"
+	}
+	return "use of closed"
+}
+
+func TestHttpsInsecure(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("test assumes tcp available")
+	}
+	saveHome := os.Getenv(homeEnv())
+	tempdir, err := ioutil.TempDir("", "home")
+	if err != nil {
+		t.Fatal("creating temp dir: ", err)
+	}
+	defer os.RemoveAll(tempdir)
+
+	// pprof writes to $HOME/pprof by default which is not necessarily
+	// writeable (e.g. on a Debian buildd) so set $HOME to something we
+	// know we can write to for the duration of the test.
+	os.Setenv(homeEnv(), tempdir)
+	defer os.Setenv(homeEnv(), saveHome)
+
+	baseVars := pprofVariables
+	pprofVariables = baseVars.makeCopy()
+	defer func() { pprofVariables = baseVars }()
+
+	tlsConfig := &tls.Config{Certificates: []tls.Certificate{selfSignedCert(t)}}
+
+	l, err := tls.Listen("tcp", "localhost:0", tlsConfig)
+	if err != nil {
+		t.Fatalf("net.Listen: got error %v, want no error", err)
+	}
+
+	donec := make(chan error, 1)
+	go func(donec chan<- error) {
+		donec <- http.Serve(l, nil)
+	}(donec)
+	defer func() {
+		if got, want := <-donec, closedError(); !strings.Contains(got.Error(), want) {
+			t.Fatalf("Serve got error %v, want %q", got, want)
+		}
+	}()
+	defer l.Close()
+
+	go func() {
+		deadline := time.Now().Add(5 * time.Second)
+		for time.Now().Before(deadline) {
+			// Simulate a hotspot function. Spin in the inner loop for 100M iterations
+			// to ensure we get most of the samples landed here rather than in the
+			// library calls. We assume Go compiler won't elide the empty loop.
+			for i := 0; i < 1e8; i++ {
+			}
+			runtime.Gosched()
+		}
+	}()
+
+	outputTempFile, err := ioutil.TempFile("", "profile_output")
+	if err != nil {
+		t.Fatalf("Failed to create tempfile: %v", err)
+	}
+	defer os.Remove(outputTempFile.Name())
+	defer outputTempFile.Close()
+
+	address := "https+insecure://" + l.Addr().String() + "/debug/pprof/profile"
+	s := &source{
+		Sources:   []string{address},
+		Seconds:   10,
+		Timeout:   10,
+		Symbolize: "remote",
+	}
+	rx := "Saved profile in"
+	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") ||
+		runtime.GOOS == "android" {
+		// On iOS, $HOME points to the app root directory and is not writable.
+		// On Android, $HOME points to / which is not writable.
+		rx += "|Could not use temp dir"
+	}
+	o := &plugin.Options{
+		Obj: &binutils.Binutils{},
+		UI:  &proftest.TestUI{T: t, AllowRx: rx},
+	}
+	o.Sym = &symbolizer.Symbolizer{Obj: o.Obj, UI: o.UI}
+	p, err := fetchProfiles(s, o)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(p.SampleType) == 0 {
+		t.Fatalf("fetchProfiles(%s) got empty profile: len(p.SampleType)==0", address)
+	}
+	switch runtime.GOOS {
+	case "plan9":
+		// CPU profiling is not supported on Plan9; see golang.org/issues/22564.
+		return
+	case "darwin":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			// CPU profiling on iOS os not symbolized; see golang.org/issues/22612.
+			return
+		}
+	}
+	if len(p.Function) == 0 {
+		t.Fatalf("fetchProfiles(%s) got non-symbolized profile: len(p.Function)==0", address)
+	}
+	if err := checkProfileHasFunction(p, "TestHttpsInsecure"); !badSigprofOS[runtime.GOOS] && err != nil {
+		t.Fatalf("fetchProfiles(%s) %v", address, err)
+	}
+}
+
+// Some operating systems don't trigger the profiling signal right.
+// See https://github.com/golang/go/issues/13841.
+var badSigprofOS = map[string]bool{
+	"darwin": true,
+	"netbsd": true,
+}
+
+func checkProfileHasFunction(p *profile.Profile, fname string) error {
+	for _, f := range p.Function {
+		if strings.Contains(f.Name, fname) {
+			return nil
+		}
+	}
+	return fmt.Errorf("got %s, want function %q", p.String(), fname)
+}
+
+func selfSignedCert(t *testing.T) tls.Certificate {
+	privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("failed to generate private key: %v", err)
+	}
+	b, err := x509.MarshalECPrivateKey(privKey)
+	if err != nil {
+		t.Fatalf("failed to marshal private key: %v", err)
+	}
+	bk := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
+
+	tmpl := x509.Certificate{
+		SerialNumber: big.NewInt(1),
+		NotBefore:    time.Now(),
+		NotAfter:     time.Now().Add(10 * time.Minute),
+	}
+
+	b, err = x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, privKey.Public(), privKey)
+	if err != nil {
+		t.Fatalf("failed to create cert: %v", err)
+	}
+	bc := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: b})
+
+	cert, err := tls.X509KeyPair(bc, bk)
+	if err != nil {
+		t.Fatalf("failed to create TLS key pair: %v", err)
+	}
+	return cert
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
index aa9c5b8..2c36b64 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
@@ -123,7 +123,8 @@
 // greetings prints a brief welcome and some overall profile
 // information before accepting interactive commands.
 func greetings(p *profile.Profile, ui plugin.UI) {
-	ropt, err := reportOptions(p, pprofVariables)
+	numLabelUnits := identifyNumLabelUnits(p, ui)
+	ropt, err := reportOptions(p, numLabelUnits, pprofVariables)
 	if err == nil {
 		ui.Print(strings.Join(report.ProfileLabels(report.New(p, ropt)), "\n"))
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.contention b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.contention
new file mode 100644
index 0000000..66a64c9
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.contention
@@ -0,0 +1,24 @@
+--- contentionz 1 ---
+cycles/second = 3201000000
+sampling period = 100
+ms since reset = 16502830
+discarded samples = 0
+  19490304       27 @ 0xbccc97 0xc61202 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
+       768        1 @ 0xbccc97 0xa42dc7 0xa456e4 0x7fcdc2ff214e
+      5760        2 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87eab 0xb8814c 0x4e969d 0x4faa17 0x4fc5f6 0x4fd028 0x4fd230 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
+    569088        1 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87f08 0xb8814c 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
+      2432        1 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87eab 0xb8814c 0x7aa74c 0x7ab844 0x7ab914 0x79e9e9 0x79e326 0x4d299e 0x4d4b7b 0x4b7be8 0x4b7ff1 0x4d2dae 0x79e80a
+   2034816        3 @ 0xbccc97 0xb82f0f 0xb83003 0xb87d50 0xc635f0 0x42ecc3 0x42e14c 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
+--- Memory map: ---
+  00400000-00fcb000: cppbench_server_main
+  7fcdc231e000-7fcdc2321000: /libnss_cache-2.15.so
+  7fcdc2522000-7fcdc252e000: /libnss_files-2.15.so
+  7fcdc272f000-7fcdc28dd000: /libc-2.15.so
+  7fcdc2ae7000-7fcdc2be2000: /libm-2.15.so
+  7fcdc2de3000-7fcdc2dea000: /librt-2.15.so
+  7fcdc2feb000-7fcdc3003000: /libpthread-2.15.so
+  7fcdc3208000-7fcdc320a000: /libdl-2.15.so
+  7fcdc340c000-7fcdc3415000: /libcrypt-2.15.so
+  7fcdc3645000-7fcdc3669000: /ld-2.15.so
+  7fff86bff000-7fff86c00000: [vdso]
+  ffffffffff600000-ffffffffff601000: [vsyscall]
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.small.contention b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.small.contention
new file mode 100644
index 0000000..230cd90
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.small.contention
@@ -0,0 +1,19 @@
+--- contentionz 1 ---
+cycles/second = 3201000000
+sampling period = 100
+ms since reset = 16502830
+discarded samples = 0
+       100     10 @ 0xbccc97 0xc61202 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
+--- Memory map: ---
+  00400000-00fcb000: cppbench_server_main
+  7fcdc231e000-7fcdc2321000: /libnss_cache-2.15.so
+  7fcdc2522000-7fcdc252e000: /libnss_files-2.15.so
+  7fcdc272f000-7fcdc28dd000: /libc-2.15.so
+  7fcdc2ae7000-7fcdc2be2000: /libm-2.15.so
+  7fcdc2de3000-7fcdc2dea000: /librt-2.15.so
+  7fcdc2feb000-7fcdc3003000: /libpthread-2.15.so
+  7fcdc3208000-7fcdc320a000: /libdl-2.15.so
+  7fcdc340c000-7fcdc3415000: /libcrypt-2.15.so
+  7fcdc3645000-7fcdc3669000: /ld-2.15.so
+  7fff86bff000-7fff86c00000: [vdso]
+  ffffffffff600000-ffffffffff601000: [vsyscall]
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.cum.files.dot b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.cum.files.dot
index 2e130c8..30cece7 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.cum.files.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.cum.files.dot
@@ -1,9 +1,9 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
 subgraph cluster_L { "Build ID: buildid-contention" [shape=box fontsize=16 label="Build ID: buildid-contention\lComment #1\lComment #2\lType: delay\lShowing nodes accounting for 149.50ms, 100% of 149.50ms total\l"] }
-N1 [label="file3000.src\n32.77ms (21.92%)\nof 149.50ms (100%)" fontsize=20 shape=box tooltip="testdata/file3000.src (149.50ms)" color="#b20000" fillcolor="#edd5d5"]
-N2 [label="file1000.src\n51.20ms (34.25%)" fontsize=23 shape=box tooltip="testdata/file1000.src (51.20ms)" color="#b23100" fillcolor="#eddbd5"]
-N3 [label="file2000.src\n65.54ms (43.84%)\nof 75.78ms (50.68%)" fontsize=24 shape=box tooltip="testdata/file2000.src (75.78ms)" color="#b22000" fillcolor="#edd9d5"]
+N1 [label="file3000.src\n32.77ms (21.92%)\nof 149.50ms (100%)" id="node1" fontsize=20 shape=box tooltip="testdata/file3000.src (149.50ms)" color="#b20000" fillcolor="#edd5d5"]
+N2 [label="file1000.src\n51.20ms (34.25%)" id="node2" fontsize=23 shape=box tooltip="testdata/file1000.src (51.20ms)" color="#b23100" fillcolor="#eddbd5"]
+N3 [label="file2000.src\n65.54ms (43.84%)\nof 75.78ms (50.68%)" id="node3" fontsize=24 shape=box tooltip="testdata/file2000.src (75.78ms)" color="#b22000" fillcolor="#edd9d5"]
 N1 -> N3 [label=" 75.78ms" weight=51 penwidth=3 color="#b22000" tooltip="testdata/file3000.src -> testdata/file2000.src (75.78ms)" labeltooltip="testdata/file3000.src -> testdata/file2000.src (75.78ms)"]
 N1 -> N2 [label=" 40.96ms" weight=28 penwidth=2 color="#b23900" tooltip="testdata/file3000.src -> testdata/file1000.src (40.96ms)" labeltooltip="testdata/file3000.src -> testdata/file1000.src (40.96ms)"]
 N3 -> N2 [label=" 10.24ms" weight=7 color="#b29775" tooltip="testdata/file2000.src -> testdata/file1000.src (10.24ms)" labeltooltip="testdata/file2000.src -> testdata/file1000.src (10.24ms)"]
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.flat.addresses.dot.focus.ignore b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.flat.addresses.dot.focus.ignore
index aa08a41..03fbbb5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.flat.addresses.dot.focus.ignore
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.contention.flat.addresses.dot.focus.ignore
@@ -1,9 +1,9 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid-contention" [shape=box fontsize=16 label="Build ID: buildid-contention\lComment #1\lComment #2\lType: delay\lShowing nodes accounting for 40.96ms, 27.40% of 149.50ms total\l"] }
-N1 [label="0000000000001000\nline1000\nfile1000.src:1\n40.96ms (27.40%)" fontsize=24 shape=box tooltip="0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
-N2 [label="0000000000003001\nline3000\nfile3000.src:5\n0 of 40.96ms (27.40%)" fontsize=8 shape=box tooltip="0000000000003001 line3000 testdata/file3000.src:5 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
-N3 [label="0000000000003001\nline3001\nfile3000.src:3\n0 of 40.96ms (27.40%)" fontsize=8 shape=box tooltip="0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
+subgraph cluster_L { "Build ID: buildid-contention" [shape=box fontsize=16 label="Build ID: buildid-contention\lComment #1\lComment #2\lType: delay\lActive filters:\l   focus=[X1]000\l   ignore=[X3]002\lShowing nodes accounting for 40.96ms, 27.40% of 149.50ms total\l"] }
+N1 [label="0000000000001000\nline1000\nfile1000.src:1\n40.96ms (27.40%)" id="node1" fontsize=24 shape=box tooltip="0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
+N2 [label="0000000000003001\nline3000\nfile3000.src:5\n0 of 40.96ms (27.40%)" id="node2" fontsize=8 shape=box tooltip="0000000000003001 line3000 testdata/file3000.src:5 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
+N3 [label="0000000000003001\nline3001\nfile3000.src:3\n0 of 40.96ms (27.40%)" id="node3" fontsize=8 shape=box tooltip="0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
 N2 -> N3 [label=" 40.96ms\n (inline)" weight=28 penwidth=2 color="#b23900" tooltip="0000000000003001 line3000 testdata/file3000.src:5 -> 0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)" labeltooltip="0000000000003001 line3000 testdata/file3000.src:5 -> 0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)"]
 N3 -> N1 [label=" 40.96ms" weight=28 penwidth=2 color="#b23900" tooltip="0000000000003001 line3001 testdata/file3000.src:3 -> 0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)" labeltooltip="0000000000003001 line3001 testdata/file3000.src:3 -> 0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.call_tree.callgrind b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.call_tree.callgrind
new file mode 100644
index 0000000..e2286f6
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.call_tree.callgrind
@@ -0,0 +1,99 @@
+positions: instr line
+events: cpu(ms)
+
+ob=(1) /path/to/testbinary
+fl=(1) testdata/file1000.src
+fn=(1) line1000
+0x1000 1 1000
+* 1 100
+
+ob=(1)
+fl=(2) testdata/file2000.src
+fn=(2) line2001
++4096 9 10
+
+ob=(1)
+fl=(3) testdata/file3000.src
+fn=(3) line3002
++4096 2 10
+cfl=(2)
+cfn=(4) line2000 [1/2]
+calls=0 * 4
+* * 1000
+
+ob=(1)
+fl=(2)
+fn=(5) line2000
+-4096 4 0
+cfl=(2)
+cfn=(6) line2001 [2/2]
+calls=0 -4096 9
+* * 1000
+* 4 0
+cfl=(2)
+cfn=(7) line2001 [1/2]
+calls=0 * 9
+* * 10
+
+ob=(1)
+fl=(2)
+fn=(2)
+* 9 0
+cfl=(1)
+cfn=(8) line1000 [1/2]
+calls=0 -4096 1
+* * 1000
+
+ob=(1)
+fl=(3)
+fn=(9) line3000
++4096 6 0
+cfl=(3)
+cfn=(10) line3001 [1/2]
+calls=0 +4096 5
+* * 1010
+
+ob=(1)
+fl=(3)
+fn=(11) line3001
+* 5 0
+cfl=(3)
+cfn=(12) line3002 [1/2]
+calls=0 * 2
+* * 1010
+
+ob=(1)
+fl=(3)
+fn=(9)
++1 9 0
+cfl=(3)
+cfn=(13) line3001 [2/2]
+calls=0 +1 8
+* * 100
+
+ob=(1)
+fl=(3)
+fn=(11)
+* 8 0
+cfl=(1)
+cfn=(14) line1000 [2/2]
+calls=0 -8193 1
+* * 100
+
+ob=(1)
+fl=(3)
+fn=(9)
++1 9 0
+cfl=(3)
+cfn=(15) line3002 [2/2]
+calls=0 +1 5
+* * 10
+
+ob=(1)
+fl=(3)
+fn=(3)
+* 5 0
+cfl=(2)
+cfn=(16) line2000 [2/2]
+calls=0 -4098 4
+* * 10
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments
index e69de29..e6d9824 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments
@@ -0,0 +1 @@
+some-comment
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.focus.hide b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.focus.hide
new file mode 100644
index 0000000..f0d928d
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.focus.hide
@@ -0,0 +1,8 @@
+Active filters:
+   focus=[12]00
+   hide=line[X3]0
+Showing nodes accounting for 1.11s, 99.11% of 1.12s total
+      flat  flat%   sum%        cum   cum%
+     1.10s 98.21% 98.21%      1.10s 98.21%  line1000 testdata/file1000.src:1
+         0     0% 98.21%      1.01s 90.18%  line2000 testdata/file2000.src:4
+     0.01s  0.89% 99.11%      1.01s 90.18%  line2001 testdata/file2000.src:9 (inline)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.hide b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.hide
index 9d17271..bf503a5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.hide
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.hide
@@ -1,3 +1,5 @@
+Active filters:
+   hide=line[X3]0
 Showing nodes accounting for 1.11s, 99.11% of 1.12s total
       flat  flat%   sum%        cum   cum%
      1.10s 98.21% 98.21%      1.10s 98.21%  line1000 testdata/file1000.src:1
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.show b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.show
index 9d17271..7604cb8 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.show
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.text.show
@@ -1,3 +1,5 @@
+Active filters:
+   show=[12]00
 Showing nodes accounting for 1.11s, 99.11% of 1.12s total
       flat  flat%   sum%        cum   cum%
      1.10s 98.21% 98.21%      1.10s 98.21%  line1000 testdata/file1000.src:1
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.topproto.hide b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.topproto.hide
index 33bf681..94b9be8 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.topproto.hide
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.cum.lines.topproto.hide
@@ -1,3 +1,5 @@
+Active filters:
+   hide=mangled[X3]0
 Showing nodes accounting for 1s, 100% of 1s total
       flat  flat%   sum%        cum   cum%
         1s   100%   100%         1s   100%  mangled1000 testdata/file1000.src:1
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.disasm b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.disasm
index 9c8e603..e1df7b1 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.disasm
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.disasm
@@ -2,9 +2,9 @@
 ROUTINE ======================== line1000
      1.10s      1.10s (flat, cum) 98.21% of Total
      1.10s      1.10s       1000: instruction one                         ;line1000 file1000.src:1
-         .          .       1001: instruction two
-         .          .       1002: instruction three
-         .          .       1003: instruction four
+         .          .       1001: instruction two                         ;file1000.src:1
+         .          .       1002: instruction three                       ;file1000.src:2
+         .          .       1003: instruction four                        ;file1000.src:1
 ROUTINE ======================== line3000
       10ms      1.12s (flat, cum)   100% of Total
       10ms      1.01s       3000: instruction one                         ;line3000 file3000.src:6
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.weblist b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.weblist
index ccf4ee8..befc412 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.weblist
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.addresses.weblist
@@ -2,6 +2,7 @@
 <!DOCTYPE html>
 <html>
 <head>
+<meta charset="UTF-8">
 <title>Pprof listing</title>
 <style type="text/css">
 body {
@@ -14,17 +15,11 @@
 .legend {
   font-size: 1.25em;
 }
-.line {
-color: #aaaaaa;
+.line, .nop, .unimportant {
+  color: #aaaaaa;
 }
-.nop {
-color: #aaaaaa;
-}
-.unimportant {
-color: #cccccc;
-}
-.disasmloc {
-color: #000000;
+.inlinesrc {
+  color: #000066;
 }
 .deadsrc {
 cursor: pointer;
@@ -69,39 +64,41 @@
 Duration: 10s, Total samples = 1.12s (11.20%)<br>Total: 1.12s</div><h1>line1000</h1>testdata/file1000.src
 <pre onClick="pprof_toggle_asm(event)">
   Total:       1.10s      1.10s (flat, cum) 98.21%
-<span class=line>      1</span> <span class=deadsrc>       1.10s      1.10s line1 </span><span class=asm>               1.10s      1.10s     1000: instruction one                                  <span class=disasmloc>file1000.src:1</span>
-                   .          .     1001: instruction two                                  <span class=disasmloc></span>
-                   .          .     1002: instruction three                                <span class=disasmloc></span>
-                   .          .     1003: instruction four                                 <span class=disasmloc></span>
+<span class=line>      1</span> <span class=deadsrc>       1.10s      1.10s           line1 </span><span class=asm>               1.10s      1.10s     1000:     instruction one                                                              <span class=unimportant>file1000.src:1</span>
+                   .          .     1001:     instruction two                                                              <span class=unimportant>file1000.src:1</span>
+                                     ⋮
+                   .          .     1003:     instruction four                                                             <span class=unimportant>file1000.src:1</span>
 </span>
-<span class=line>      2</span> <span class=nop>           .          . line2 </span>
-<span class=line>      3</span> <span class=nop>           .          . line3 </span>
-<span class=line>      4</span> <span class=nop>           .          . line4 </span>
-<span class=line>      5</span> <span class=nop>           .          . line5 </span>
-<span class=line>      6</span> <span class=nop>           .          . line6 </span>
+<span class=line>      2</span> <span class=deadsrc>           .          .           line2 </span><span class=asm>                   .          .     1002:     instruction three                                                            <span class=unimportant>file1000.src:2</span>
+</span>
+<span class=line>      3</span> <span class=nop>           .          .           line3 </span>
+<span class=line>      4</span> <span class=nop>           .          .           line4 </span>
+<span class=line>      5</span> <span class=nop>           .          .           line5 </span>
+<span class=line>      6</span> <span class=nop>           .          .           line6 </span>
+<span class=line>      7</span> <span class=nop>           .          .           line7 </span>
 </pre>
 <h1>line3000</h1>testdata/file3000.src
 <pre onClick="pprof_toggle_asm(event)">
   Total:        10ms      1.12s (flat, cum)   100%
-<span class=line>      1</span> <span class=nop>           .          . line1 </span>
-<span class=line>      2</span> <span class=nop>           .          . line2 </span>
-<span class=line>      3</span> <span class=nop>           .          . line3 </span>
-<span class=line>      4</span> <span class=nop>           .          . line4 </span>
-<span class=line>      5</span> <span class=nop>           .          . line5 </span>
-<span class=line>      6</span> <span class=deadsrc>        10ms      1.01s line6 </span><span class=asm>                10ms      1.01s     3000: instruction one                                  <span class=disasmloc>file3000.src:6</span>
+<span class=line>      1</span> <span class=nop>           .          .           line1 </span>
+<span class=line>      2</span> <span class=nop>           .          .           line2 </span>
+<span class=line>      3</span> <span class=nop>           .          .           line3 </span>
+<span class=line>      4</span> <span class=nop>           .          .           line4 </span>
+<span class=line>      5</span> <span class=nop>           .          .           line5 </span>
+<span class=line>      6</span> <span class=deadsrc>        10ms      1.01s           line6 </span><span class=asm>                10ms      1.01s     3000:     instruction one                                                              <span class=unimportant>file3000.src:6</span>
 </span>
-<span class=line>      7</span> <span class=nop>           .          . line7 </span>
-<span class=line>      8</span> <span class=nop>           .          . line8 </span>
-<span class=line>      9</span> <span class=deadsrc>           .      110ms line9 </span><span class=asm>                   .      100ms     3001: instruction two                                  <span class=disasmloc>file3000.src:9</span>
-                   .       10ms     3002: instruction three                                <span class=disasmloc>file3000.src:9</span>
-                   .          .     3003: instruction four                                 <span class=disasmloc></span>
-                   .          .     3004: instruction five                                 <span class=disasmloc></span>
+<span class=line>      7</span> <span class=nop>           .          .           line7 </span>
+<span class=line>      8</span> <span class=nop>           .          .           line8 </span>
+<span class=line>      9</span> <span class=deadsrc>           .      110ms           line9 </span><span class=asm>                   .      100ms     3001:     instruction two                                                              <span class=unimportant>file3000.src:9</span>
+                   .       10ms     3002:     instruction three                                                            <span class=unimportant>file3000.src:9</span>
+                   .          .     3003:     instruction four                                                             <span class=unimportant></span>
+                   .          .     3004:     instruction five                                                             <span class=unimportant></span>
 </span>
-<span class=line>     10</span> <span class=nop>           .          . line0 </span>
-<span class=line>     11</span> <span class=nop>           .          . line1 </span>
-<span class=line>     12</span> <span class=nop>           .          . line2 </span>
-<span class=line>     13</span> <span class=nop>           .          . line3 </span>
-<span class=line>     14</span> <span class=nop>           .          . line4 </span>
+<span class=line>     10</span> <span class=nop>           .          .           line0 </span>
+<span class=line>     11</span> <span class=nop>           .          .           line1 </span>
+<span class=line>     12</span> <span class=nop>           .          .           line2 </span>
+<span class=line>     13</span> <span class=nop>           .          .           line3 </span>
+<span class=line>     14</span> <span class=nop>           .          .           line4 </span>
 </pre>
 
 </body>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.call_tree.dot b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.call_tree.dot
new file mode 100644
index 0000000..e854b5d
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.call_tree.dot
@@ -0,0 +1,21 @@
+digraph "testbinary" {
+node [style=filled fillcolor="#f8f8f8"]
+subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.12s (11.20%)\lShowing nodes accounting for 1.11s, 99.11% of 1.12s total\lDropped 3 nodes (cum <= 0.06s)\l" tooltip="testbinary"] }
+N1 [label="line1000\n1s (89.29%)" id="node1" fontsize=24 shape=box tooltip="line1000 (1s)" color="#b20500" fillcolor="#edd6d5"]
+N1_0 [label = "key1:tag1\nkey2:tag1" id="N1_0" fontsize=8 shape=box3d tooltip="1s"]
+N1 -> N1_0 [label=" 1s" weight=100 tooltip="1s" labeltooltip="1s"]
+N2 [label="line3000\n0 of 1.12s (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (1.12s)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="line3001\n0 of 1.11s (99.11%)" id="node3" fontsize=8 shape=box tooltip="line3001 (1.11s)" color="#b20000" fillcolor="#edd5d5"]
+N4 [label="line1000\n0.10s (8.93%)" id="node4" fontsize=14 shape=box tooltip="line1000 (0.10s)" color="#b28b62" fillcolor="#ede8e2"]
+N4_0 [label = "key1:tag2\nkey3:tag2" id="N4_0" fontsize=8 shape=box3d tooltip="0.10s"]
+N4 -> N4_0 [label=" 0.10s" weight=100 tooltip="0.10s" labeltooltip="0.10s"]
+N5 [label="line3002\n0.01s (0.89%)\nof 1.01s (90.18%)" id="node5" fontsize=10 shape=box tooltip="line3002 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
+N6 [label="line2000\n0 of 1s (89.29%)" id="node6" fontsize=8 shape=box tooltip="line2000 (1s)" color="#b20500" fillcolor="#edd6d5"]
+N7 [label="line2001\n0 of 1s (89.29%)" id="node7" fontsize=8 shape=box tooltip="line2001 (1s)" color="#b20500" fillcolor="#edd6d5"]
+N2 -> N3 [label=" 1.11s\n (inline)" weight=100 penwidth=5 color="#b20000" tooltip="line3000 -> line3001 (1.11s)" labeltooltip="line3000 -> line3001 (1.11s)"]
+N3 -> N5 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line3001 -> line3002 (1.01s)" labeltooltip="line3001 -> line3002 (1.01s)"]
+N6 -> N7 [label=" 1s\n (inline)" weight=90 penwidth=5 color="#b20500" tooltip="line2000 -> line2001 (1s)" labeltooltip="line2000 -> line2001 (1s)"]
+N7 -> N1 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line2001 -> line1000 (1s)" labeltooltip="line2001 -> line1000 (1s)"]
+N5 -> N6 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line3002 -> line2000 (1s)" labeltooltip="line3002 -> line2000 (1s)"]
+N3 -> N4 [label=" 0.10s" weight=9 color="#b28b62" tooltip="line3001 -> line1000 (0.10s)" labeltooltip="line3001 -> line1000 (0.10s)"]
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.dot b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.dot
index 18b1abf..f0a5226 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.dot
@@ -1,20 +1,20 @@
 digraph "testbinary" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.12s (11.20%)\lShowing nodes accounting for 1.12s, 100% of 1.12s total\l"] }
-N1 [label="line1000\nfile1000.src\n1.10s (98.21%)" fontsize=24 shape=box tooltip="line1000 testdata/file1000.src (1.10s)" color="#b20000" fillcolor="#edd5d5"]
-N1_0 [label = "key1:tag1\nkey2:tag1" fontsize=8 shape=box3d tooltip="1s"]
+subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.12s (11.20%)\lShowing nodes accounting for 1.12s, 100% of 1.12s total\l" tooltip="testbinary"] }
+N1 [label="line1000\n1.10s (98.21%)" id="node1" fontsize=24 shape=box tooltip="line1000 (1.10s)" color="#b20000" fillcolor="#edd5d5"]
+N1_0 [label = "key1:tag1\nkey2:tag1" id="N1_0" fontsize=8 shape=box3d tooltip="1s"]
 N1 -> N1_0 [label=" 1s" weight=100 tooltip="1s" labeltooltip="1s"]
-N1_1 [label = "key1:tag2\nkey3:tag2" fontsize=8 shape=box3d tooltip="0.10s"]
+N1_1 [label = "key1:tag2\nkey3:tag2" id="N1_1" fontsize=8 shape=box3d tooltip="0.10s"]
 N1 -> N1_1 [label=" 0.10s" weight=100 tooltip="0.10s" labeltooltip="0.10s"]
-N2 [label="line3000\nfile3000.src\n0 of 1.12s (100%)" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src (1.12s)" color="#b20000" fillcolor="#edd5d5"]
-N3 [label="line3001\nfile3000.src\n0 of 1.11s (99.11%)" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src (1.11s)" color="#b20000" fillcolor="#edd5d5"]
-N4 [label="line3002\nfile3000.src\n0.01s (0.89%)\nof 1.02s (91.07%)" fontsize=10 shape=box tooltip="line3002 testdata/file3000.src (1.02s)" color="#b20400" fillcolor="#edd6d5"]
-N5 [label="line2001\nfile2000.src\n0.01s (0.89%)\nof 1.01s (90.18%)" fontsize=10 shape=box tooltip="line2001 testdata/file2000.src (1.01s)" color="#b20500" fillcolor="#edd6d5"]
-N6 [label="line2000\nfile2000.src\n0 of 1.01s (90.18%)" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src (1.01s)" color="#b20500" fillcolor="#edd6d5"]
-N2 -> N3 [label=" 1.11s\n (inline)" weight=100 penwidth=5 color="#b20000" tooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (1.11s)" labeltooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (1.11s)"]
-N6 -> N5 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (1.01s)" labeltooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (1.01s)"]
-N3 -> N4 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (1.01s)" labeltooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (1.01s)"]
-N4 -> N6 [label=" 1.01s" weight=91 penwidth=5 color="#b20500" tooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (1.01s)" labeltooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (1.01s)"]
-N5 -> N1 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line2001 testdata/file2000.src -> line1000 testdata/file1000.src (1s)" labeltooltip="line2001 testdata/file2000.src -> line1000 testdata/file1000.src (1s)"]
-N3 -> N1 [label=" 0.10s" weight=9 color="#b28b62" tooltip="line3001 testdata/file3000.src -> line1000 testdata/file1000.src (0.10s)" labeltooltip="line3001 testdata/file3000.src -> line1000 testdata/file1000.src (0.10s)"]
+N2 [label="line3000\n0 of 1.12s (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (1.12s)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="line3001\n0 of 1.11s (99.11%)" id="node3" fontsize=8 shape=box tooltip="line3001 (1.11s)" color="#b20000" fillcolor="#edd5d5"]
+N4 [label="line3002\n0.01s (0.89%)\nof 1.02s (91.07%)" id="node4" fontsize=10 shape=box tooltip="line3002 (1.02s)" color="#b20400" fillcolor="#edd6d5"]
+N5 [label="line2001\n0.01s (0.89%)\nof 1.01s (90.18%)" id="node5" fontsize=10 shape=box tooltip="line2001 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
+N6 [label="line2000\n0 of 1.01s (90.18%)" id="node6" fontsize=8 shape=box tooltip="line2000 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
+N2 -> N3 [label=" 1.11s\n (inline)" weight=100 penwidth=5 color="#b20000" tooltip="line3000 -> line3001 (1.11s)" labeltooltip="line3000 -> line3001 (1.11s)"]
+N6 -> N5 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line2000 -> line2001 (1.01s)" labeltooltip="line2000 -> line2001 (1.01s)"]
+N3 -> N4 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line3001 -> line3002 (1.01s)" labeltooltip="line3001 -> line3002 (1.01s)"]
+N4 -> N6 [label=" 1.01s" weight=91 penwidth=5 color="#b20500" tooltip="line3002 -> line2000 (1.01s)" labeltooltip="line3002 -> line2000 (1.01s)"]
+N5 -> N1 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line2001 -> line1000 (1s)" labeltooltip="line2001 -> line1000 (1s)"]
+N3 -> N1 [label=" 0.10s" weight=9 color="#b28b62" tooltip="line3001 -> line1000 (0.10s)" labeltooltip="line3001 -> line1000 (0.10s)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.text b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.text
index 0807ed2..66e4189 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.text
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.flat.functions.text
@@ -1,8 +1,8 @@
 Showing nodes accounting for 1.12s, 100% of 1.12s total
       flat  flat%   sum%        cum   cum%
-     1.10s 98.21% 98.21%      1.10s 98.21%  line1000 testdata/file1000.src
-     0.01s  0.89% 99.11%      1.01s 90.18%  line2001 testdata/file2000.src (inline)
-     0.01s  0.89%   100%      1.02s 91.07%  line3002 testdata/file3000.src (inline)
-         0     0%   100%      1.01s 90.18%  line2000 testdata/file2000.src
-         0     0%   100%      1.12s   100%  line3000 testdata/file3000.src
-         0     0%   100%      1.11s 99.11%  line3001 testdata/file3000.src (inline)
+     1.10s 98.21% 98.21%      1.10s 98.21%  line1000
+     0.01s  0.89% 99.11%      1.01s 90.18%  line2001 (inline)
+     0.01s  0.89%   100%      1.02s 91.07%  line3002 (inline)
+         0     0%   100%      1.01s 90.18%  line2000
+         0     0%   100%      1.12s   100%  line3000
+         0     0%   100%      1.11s 99.11%  line3001 (inline)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek
index 1a4a70c..3b8a353 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek
@@ -2,12 +2,12 @@
 ----------------------------------------------------------+-------------
       flat  flat%   sum%        cum   cum%   calls calls% + context 	 	 
 ----------------------------------------------------------+-------------
-                                             1.01s   100% |   line2000 testdata/file2000.src (inline)
-     0.01s  0.89%  0.89%      1.01s 90.18%                | line2001 testdata/file2000.src
-                                                1s 99.01% |   line1000 testdata/file1000.src
+                                             1.01s   100% |   line2000 (inline)
+     0.01s  0.89%  0.89%      1.01s 90.18%                | line2001
+                                                1s 99.01% |   line1000
 ----------------------------------------------------------+-------------
-                                             1.11s   100% |   line3000 testdata/file3000.src (inline)
-         0     0%  0.89%      1.11s 99.11%                | line3001 testdata/file3000.src
-                                             1.01s 90.99% |   line3002 testdata/file3000.src (inline)
-                                             0.10s  9.01% |   line1000 testdata/file1000.src
+                                             1.11s   100% |   line3000 (inline)
+         0     0%  0.89%      1.11s 99.11%                | line3001
+                                             1.01s 90.99% |   line3002 (inline)
+                                             0.10s  9.01% |   line1000
 ----------------------------------------------------------+-------------
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags
index fc784f0..5998b5b 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags
@@ -1,13 +1,13 @@
-key1: Total 1120
-      1000 (89.29%): tag1
-       100 ( 8.93%): tag2
-        10 ( 0.89%): tag3
-        10 ( 0.89%): tag4
+ key1: Total 1.1s
+          1.0s (89.29%): tag1
+       100.0ms ( 8.93%): tag2
+        10.0ms ( 0.89%): tag3
+        10.0ms ( 0.89%): tag4
 
-key2: Total 1020
-      1010 (99.02%): tag1
-        10 ( 0.98%): tag2
+ key2: Total 1.0s
+         1.0s (99.02%): tag1
+       10.0ms ( 0.98%): tag2
 
-key3: Total 100
-       100 (  100%): tag2
+ key3: Total 100.0ms
+       100.0ms (  100%): tag2
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags.focus.ignore b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags.focus.ignore
index 650ebb1..9b99d43 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags.focus.ignore
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags.focus.ignore
@@ -1,6 +1,6 @@
-key1: Total 100
-       100 (  100%): tag2
+ key1: Total 100.0ms
+       100.0ms (  100%): tag2
 
-key3: Total 100
-       100 (  100%): tag2
+ key3: Total 100.0ms
+       100.0ms (  100%): tag2
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces
index d59fe30..d9637c0 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces
@@ -4,29 +4,29 @@
 -----------+-------------------------------------------------------
       key1:  tag1
       key2:  tag1
-        1s   line1000 testdata/file1000.src
-             line2001 testdata/file2000.src
-             line2000 testdata/file2000.src
-             line3002 testdata/file3000.src
-             line3001 testdata/file3000.src
-             line3000 testdata/file3000.src
+        1s   line1000
+             line2001
+             line2000
+             line3002
+             line3001
+             line3000
 -----------+-------------------------------------------------------
       key1:  tag2
       key3:  tag2
-     100ms   line1000 testdata/file1000.src
-             line3001 testdata/file3000.src
-             line3000 testdata/file3000.src
+     100ms   line1000
+             line3001
+             line3000
 -----------+-------------------------------------------------------
       key1:  tag3
       key2:  tag2
-      10ms   line2001 testdata/file2000.src
-             line2000 testdata/file2000.src
-             line3002 testdata/file3000.src
-             line3000 testdata/file3000.src
+      10ms   line2001
+             line2000
+             line3002
+             line3000
 -----------+-------------------------------------------------------
       key1:  tag4
       key2:  tag1
-      10ms   line3002 testdata/file3000.src
-             line3001 testdata/file3000.src
-             line3000 testdata/file3000.src
+      10ms   line3002
+             line3001
+             line3000
 -----------+-------------------------------------------------------
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.lines.tree.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.lines.tree.focus
index cda6d65..9d4ba72 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.lines.tree.focus
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.lines.tree.focus
@@ -1,3 +1,5 @@
+Active filters:
+   focus=[24]00
 Showing nodes accounting for 62.50MB, 63.37% of 98.63MB total
 Dropped 2 nodes (cum <= 4.93MB)
 ----------------------------------------------------------+-------------
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.relative_percentages.tree.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.relative_percentages.tree.focus
index 35f0bf5..c2d1183 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.relative_percentages.tree.focus
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.cum.relative_percentages.tree.focus
@@ -1,19 +1,21 @@
+Active filters:
+   focus=[24]00
 Showing nodes accounting for 62.50MB, 98.46% of 63.48MB total
 Dropped 2 nodes (cum <= 3.17MB)
 ----------------------------------------------------------+-------------
       flat  flat%   sum%        cum   cum%   calls calls% + context 	 	 
 ----------------------------------------------------------+-------------
-                                           63.48MB   100% |   line3002 testdata/file3000.src
-         0     0%     0%    63.48MB   100%                | line2000 testdata/file2000.src
-                                           63.48MB   100% |   line2001 testdata/file2000.src (inline)
+                                           63.48MB   100% |   line3002
+         0     0%     0%    63.48MB   100%                | line2000
+                                           63.48MB   100% |   line2001 (inline)
 ----------------------------------------------------------+-------------
-                                           63.48MB   100% |   line2000 testdata/file2000.src (inline)
-   62.50MB 98.46% 98.46%    63.48MB   100%                | line2001 testdata/file2000.src
+                                           63.48MB   100% |   line2000 (inline)
+   62.50MB 98.46% 98.46%    63.48MB   100%                | line2001
 ----------------------------------------------------------+-------------
-         0     0% 98.46%    63.48MB   100%                | line3000 testdata/file3000.src
-                                           63.48MB   100% |   line3002 testdata/file3000.src (inline)
+         0     0% 98.46%    63.48MB   100%                | line3000
+                                           63.48MB   100% |   line3002 (inline)
 ----------------------------------------------------------+-------------
-                                           63.48MB   100% |   line3000 testdata/file3000.src (inline)
-         0     0% 98.46%    63.48MB   100%                | line3002 testdata/file3000.src
-                                           63.48MB   100% |   line2000 testdata/file2000.src
+                                           63.48MB   100% |   line3000 (inline)
+         0     0% 98.46%    63.48MB   100%                | line3002
+                                           63.48MB   100% |   line2000
 ----------------------------------------------------------+-------------
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.files.text.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.files.text.focus
new file mode 100644
index 0000000..20a503f
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.files.text.focus
@@ -0,0 +1,8 @@
+Active filters:
+   focus=[12]00
+   taghide=[X3]00
+Showing nodes accounting for 67.38MB, 68.32% of 98.63MB total
+      flat  flat%   sum%        cum   cum%
+   62.50MB 63.37% 63.37%    63.48MB 64.36%  testdata/file2000.src
+    4.88MB  4.95% 68.32%     4.88MB  4.95%  testdata/file1000.src
+         0     0% 68.32%    67.38MB 68.32%  testdata/file3000.src
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_objects.text b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_objects.text
index bc061ad..929461a 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_objects.text
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_objects.text
@@ -1,8 +1,8 @@
 Showing nodes accounting for 150, 100% of 150 total
       flat  flat%   sum%        cum   cum%
-        80 53.33% 53.33%        130 86.67%  line3002 testdata/file3000.src (inline)
-        40 26.67% 80.00%         50 33.33%  line2001 testdata/file2000.src (inline)
-        30 20.00%   100%         30 20.00%  line1000 testdata/file1000.src
-         0     0%   100%         50 33.33%  line2000 testdata/file2000.src
-         0     0%   100%        150   100%  line3000 testdata/file3000.src
-         0     0%   100%        110 73.33%  line3001 testdata/file3000.src (inline)
+        80 53.33% 53.33%        130 86.67%  line3002 (inline)
+        40 26.67% 80.00%         50 33.33%  line2001 (inline)
+        30 20.00%   100%         30 20.00%  line1000
+         0     0%   100%         50 33.33%  line2000
+         0     0%   100%        150   100%  line3000
+         0     0%   100%        110 73.33%  line3001 (inline)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus
index c8533f3..909a824 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus
@@ -1,13 +1,13 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lShowing nodes accounting for 62.50MB, 63.37% of 98.63MB total\l"] }
-N1 [label="line2001\nfile2000.src\n62.50MB (63.37%)" fontsize=24 shape=box tooltip="line2001 testdata/file2000.src (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
-NN1_0 [label = "1.56MB" fontsize=8 shape=box3d tooltip="62.50MB"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l   tagfocus=1mb:2gb\lShowing nodes accounting for 62.50MB, 63.37% of 98.63MB total\l"] }
+N1 [label="line2001\n62.50MB (63.37%)" id="node1" fontsize=24 shape=box tooltip="line2001 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
+NN1_0 [label = "1.56MB" id="NN1_0" fontsize=8 shape=box3d tooltip="62.50MB"]
 N1 -> NN1_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
-N2 [label="line3000\nfile3000.src\n0 of 62.50MB (63.37%)" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
-N3 [label="line2000\nfile2000.src\n0 of 62.50MB (63.37%)" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
-N4 [label="line3002\nfile3000.src\n0 of 62.50MB (63.37%)" fontsize=8 shape=box tooltip="line3002 testdata/file3000.src (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
-N3 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (62.50MB)" labeltooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (62.50MB)"]
-N2 -> N4 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 testdata/file3000.src -> line3002 testdata/file3000.src (62.50MB)" labeltooltip="line3000 testdata/file3000.src -> line3002 testdata/file3000.src (62.50MB)"]
-N4 -> N3 [label=" 62.50MB" weight=64 penwidth=4 color="#b21600" tooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (62.50MB)" labeltooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (62.50MB)"]
+N2 [label="line3000\n0 of 62.50MB (63.37%)" id="node2" fontsize=8 shape=box tooltip="line3000 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
+N3 [label="line2000\n0 of 62.50MB (63.37%)" id="node3" fontsize=8 shape=box tooltip="line2000 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
+N4 [label="line3002\n0 of 62.50MB (63.37%)" id="node4" fontsize=8 shape=box tooltip="line3002 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
+N3 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (62.50MB)" labeltooltip="line2000 -> line2001 (62.50MB)"]
+N2 -> N4 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
+N4 -> N3 [label=" 62.50MB" weight=64 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (62.50MB)" labeltooltip="line3002 -> line2000 (62.50MB)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus.ignore b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus.ignore
index 40354dd..b2929ae 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus.ignore
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.inuse_space.dot.focus.ignore
@@ -1,16 +1,16 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lShowing nodes accounting for 36.13MB, 36.63% of 98.63MB total\lDropped 2 nodes (cum <= 4.93MB)\l"] }
-N1 [label="line3002\nfile3000.src\n31.25MB (31.68%)\nof 32.23MB (32.67%)" fontsize=24 shape=box tooltip="line3002 testdata/file3000.src (32.23MB)" color="#b23200" fillcolor="#eddcd5"]
-NN1_0 [label = "400kB" fontsize=8 shape=box3d tooltip="31.25MB"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l   tagfocus=30kb:\l   tagignore=1mb:2mb\lShowing nodes accounting for 36.13MB, 36.63% of 98.63MB total\lDropped 2 nodes (cum <= 4.93MB)\l"] }
+N1 [label="line3002\n31.25MB (31.68%)\nof 32.23MB (32.67%)" id="node1" fontsize=24 shape=box tooltip="line3002 (32.23MB)" color="#b23200" fillcolor="#eddcd5"]
+NN1_0 [label = "400kB" id="NN1_0" fontsize=8 shape=box3d tooltip="31.25MB"]
 N1 -> NN1_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
-N2 [label="line3000\nfile3000.src\n0 of 36.13MB (36.63%)" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
-N3 [label="line3001\nfile3000.src\n0 of 36.13MB (36.63%)" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
-N4 [label="line1000\nfile1000.src\n4.88MB (4.95%)" fontsize=15 shape=box tooltip="line1000 testdata/file1000.src (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
-NN4_0 [label = "200kB" fontsize=8 shape=box3d tooltip="3.91MB"]
+N2 [label="line3000\n0 of 36.13MB (36.63%)" id="node2" fontsize=8 shape=box tooltip="line3000 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+N3 [label="line3001\n0 of 36.13MB (36.63%)" id="node3" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+N4 [label="line1000\n4.88MB (4.95%)" id="node4" fontsize=15 shape=box tooltip="line1000 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
+NN4_0 [label = "200kB" id="NN4_0" fontsize=8 shape=box3d tooltip="3.91MB"]
 N4 -> NN4_0 [label=" 3.91MB" weight=100 tooltip="3.91MB" labeltooltip="3.91MB"]
-N2 -> N3 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)" labeltooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)"]
-N3 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (32.23MB)" labeltooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (32.23MB)"]
-N3 -> N4 [label=" 3.91MB" weight=4 color="#b2a58f" tooltip="line3001 testdata/file3000.src -> line1000 testdata/file1000.src (3.91MB)" labeltooltip="line3001 testdata/file3000.src -> line1000 testdata/file1000.src (3.91MB)"]
-N1 -> N4 [label=" 0.98MB" color="#b2b0a9" tooltip="line3002 testdata/file3000.src ... line1000 testdata/file1000.src (0.98MB)" labeltooltip="line3002 testdata/file3000.src ... line1000 testdata/file1000.src (0.98MB)" style="dotted" minlen=2]
+N2 -> N3 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
+N3 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
+N3 -> N4 [label=" 3.91MB" weight=4 color="#b2a58f" tooltip="line3001 -> line1000 (3.91MB)" labeltooltip="line3001 -> line1000 (3.91MB)"]
+N1 -> N4 [label=" 0.98MB" color="#b2b0a9" tooltip="line3002 ... line1000 (0.98MB)" labeltooltip="line3002 ... line1000 (0.98MB)" style="dotted" minlen=2]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.lines.dot.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.lines.dot.focus
index f05969c..9af0341 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.lines.dot.focus
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.flat.lines.dot.focus
@@ -1,16 +1,16 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lShowing nodes accounting for 67.38MB, 68.32% of 98.63MB total\l"] }
-N1 [label="line3000\nfile3000.src:4\n0 of 67.38MB (68.32%)" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src:4 (67.38MB)" color="#b21300" fillcolor="#edd7d5"]
-N2 [label="line2001\nfile2000.src:2\n62.50MB (63.37%)\nof 63.48MB (64.36%)" fontsize=24 shape=box tooltip="line2001 testdata/file2000.src:2 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
-NN2_0 [label = "1.56MB" fontsize=8 shape=box3d tooltip="62.50MB"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l   focus=[12]00\lShowing nodes accounting for 67.38MB, 68.32% of 98.63MB total\l"] }
+N1 [label="line3000\nfile3000.src:4\n0 of 67.38MB (68.32%)" id="node1" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src:4 (67.38MB)" color="#b21300" fillcolor="#edd7d5"]
+N2 [label="line2001\nfile2000.src:2\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node2" fontsize=24 shape=box tooltip="line2001 testdata/file2000.src:2 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+NN2_0 [label = "1.56MB" id="NN2_0" fontsize=8 shape=box3d tooltip="62.50MB"]
 N2 -> NN2_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
-N3 [label="line1000\nfile1000.src:1\n4.88MB (4.95%)" fontsize=13 shape=box tooltip="line1000 testdata/file1000.src:1 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
-NN3_0 [label = "200kB" fontsize=8 shape=box3d tooltip="3.91MB"]
+N3 [label="line1000\nfile1000.src:1\n4.88MB (4.95%)" id="node3" fontsize=13 shape=box tooltip="line1000 testdata/file1000.src:1 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
+NN3_0 [label = "200kB" id="NN3_0" fontsize=8 shape=box3d tooltip="3.91MB"]
 N3 -> NN3_0 [label=" 3.91MB" weight=100 tooltip="3.91MB" labeltooltip="3.91MB"]
-N4 [label="line3002\nfile3000.src:3\n0 of 63.48MB (64.36%)" fontsize=8 shape=box tooltip="line3002 testdata/file3000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
-N5 [label="line3001\nfile3000.src:2\n0 of 4.88MB (4.95%)" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src:2 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
-N6 [label="line2000\nfile2000.src:3\n0 of 63.48MB (64.36%)" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N4 [label="line3002\nfile3000.src:3\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line3002 testdata/file3000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N5 [label="line3001\nfile3000.src:2\n0 of 4.88MB (4.95%)" id="node5" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src:2 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
+N6 [label="line2000\nfile2000.src:3\n0 of 63.48MB (64.36%)" id="node6" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
 N6 -> N2 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 testdata/file2000.src:3 -> line2001 testdata/file2000.src:2 (63.48MB)" labeltooltip="line2000 testdata/file2000.src:3 -> line2001 testdata/file2000.src:2 (63.48MB)"]
 N4 -> N6 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 testdata/file3000.src:3 -> line2000 testdata/file2000.src:3 (63.48MB)" labeltooltip="line3002 testdata/file3000.src:3 -> line2000 testdata/file2000.src:3 (63.48MB)"]
 N1 -> N4 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 testdata/file3000.src:4 -> line3002 testdata/file3000.src:3 (62.50MB)" labeltooltip="line3000 testdata/file3000.src:4 -> line3002 testdata/file3000.src:3 (62.50MB)"]
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags
index 7a6f0a7..630e452 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags
@@ -1,6 +1,6 @@
-bytes: Total 150
-        80 (53.33%): 400kB
-        40 (26.67%): 1.56MB
-        20 (13.33%): 200kB
-        10 ( 6.67%): 100kB
+ bytes: Total 98.6MB
+          62.5MB (63.37%): 1.56MB
+          31.2MB (31.68%): 400kB
+           3.9MB ( 3.96%): 200kB
+        1000.0kB ( 0.99%): 100kB
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit
index 7238b36..5e565fc 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit
@@ -1,6 +1,6 @@
-bytes: Total 150
-        80 (53.33%): 409600B
-        40 (26.67%): 1638400B
-        20 (13.33%): 204800B
-        10 ( 6.67%): 102400B
+ bytes: Total 103424000.0B
+        65536000.0B (63.37%): 1638400B
+        32768000.0B (31.68%): 409600B
+         4096000.0B ( 3.96%): 204800B
+         1024000.0B ( 0.99%): 102400B
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_objects.text b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_objects.text
index bc061ad..929461a 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_objects.text
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_objects.text
@@ -1,8 +1,8 @@
 Showing nodes accounting for 150, 100% of 150 total
       flat  flat%   sum%        cum   cum%
-        80 53.33% 53.33%        130 86.67%  line3002 testdata/file3000.src (inline)
-        40 26.67% 80.00%         50 33.33%  line2001 testdata/file2000.src (inline)
-        30 20.00%   100%         30 20.00%  line1000 testdata/file1000.src
-         0     0%   100%         50 33.33%  line2000 testdata/file2000.src
-         0     0%   100%        150   100%  line3000 testdata/file3000.src
-         0     0%   100%        110 73.33%  line3001 testdata/file3000.src (inline)
+        80 53.33% 53.33%        130 86.67%  line3002 (inline)
+        40 26.67% 80.00%         50 33.33%  line2001 (inline)
+        30 20.00%   100%         30 20.00%  line1000
+         0     0%   100%         50 33.33%  line2000
+         0     0%   100%        150   100%  line3000
+         0     0%   100%        110 73.33%  line3001 (inline)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot
new file mode 100644
index 0000000..f0621a0
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot
@@ -0,0 +1,14 @@
+digraph "unnamed" {
+node [style=filled fillcolor="#f8f8f8"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l   tagshow=[2]00\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
+N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
+N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
+N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)"]
+N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
+N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
+N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.focus
index c693ef3..e412ff4 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.focus
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.focus
@@ -1,18 +1,18 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
-N1 [label="line3002\nfile3000.src\n31.25MB (31.68%)\nof 94.73MB (96.04%)" fontsize=20 shape=box tooltip="line3002 testdata/file3000.src (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
-NN1_0 [label = "400kB" fontsize=8 shape=box3d tooltip="31.25MB"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l   focus=[234]00\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
+N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
+NN1_0 [label = "400kB" id="NN1_0" fontsize=8 shape=box3d tooltip="31.25MB"]
 N1 -> NN1_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
-N2 [label="line3000\nfile3000.src\n0 of 98.63MB (100%)" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
-N3 [label="line2001\nfile2000.src\n62.50MB (63.37%)\nof 63.48MB (64.36%)" fontsize=24 shape=box tooltip="line2001 testdata/file2000.src (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
-NN3_0 [label = "1.56MB" fontsize=8 shape=box3d tooltip="62.50MB"]
+N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+NN3_0 [label = "1.56MB" id="NN3_0" fontsize=8 shape=box3d tooltip="62.50MB"]
 N3 -> NN3_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
-N4 [label="line2000\nfile2000.src\n0 of 63.48MB (64.36%)" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
-N5 [label="line3001\nfile3000.src\n0 of 36.13MB (36.63%)" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
-N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (63.48MB)" labeltooltip="line2000 testdata/file2000.src -> line2001 testdata/file2000.src (63.48MB)"]
-N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (63.48MB)" labeltooltip="line3002 testdata/file3000.src -> line2000 testdata/file2000.src (63.48MB)" minlen=2]
-N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 testdata/file3000.src -> line3002 testdata/file3000.src (62.50MB)" labeltooltip="line3000 testdata/file3000.src -> line3002 testdata/file3000.src (62.50MB)"]
-N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)" labeltooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)"]
-N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (32.23MB)" labeltooltip="line3001 testdata/file3000.src -> line3002 testdata/file3000.src (32.23MB)"]
+N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
+N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)" minlen=2]
+N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
+N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
+N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.hide b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.hide
index 26a51c5..6110b11 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.hide
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_alloc.flat.alloc_space.dot.hide
@@ -1,11 +1,11 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
-N1 [label="line3000\nfile3000.src\n62.50MB (63.37%)\nof 98.63MB (100%)" fontsize=24 shape=box tooltip="line3000 testdata/file3000.src (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
-NN1_0 [label = "1.56MB" fontsize=8 shape=box3d tooltip="62.50MB"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l   hide=line.*1?23?\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
+N1 [label="line3000\n62.50MB (63.37%)\nof 98.63MB (100%)" id="node1" fontsize=24 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
+NN1_0 [label = "1.56MB" id="NN1_0" fontsize=8 shape=box3d tooltip="62.50MB"]
 N1 -> NN1_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
-N2 [label="line3001\nfile3000.src\n31.25MB (31.68%)\nof 36.13MB (36.63%)" fontsize=20 shape=box tooltip="line3001 testdata/file3000.src (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
-NN2_0 [label = "400kB" fontsize=8 shape=box3d tooltip="31.25MB"]
+N2 [label="line3001\n31.25MB (31.68%)\nof 36.13MB (36.63%)" id="node2" fontsize=20 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+NN2_0 [label = "400kB" id="NN2_0" fontsize=8 shape=box3d tooltip="31.25MB"]
 N2 -> NN2_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
-N1 -> N2 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)" labeltooltip="line3000 testdata/file3000.src -> line3001 testdata/file3000.src (36.13MB)" minlen=2]
+N1 -> N2 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)" minlen=2]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_request.tags.focus b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_request.tags.focus
new file mode 100644
index 0000000..b1a5f44
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_request.tags.focus
@@ -0,0 +1,8 @@
+ bytes: Total 93.8MB
+        62.5MB (66.67%): 1.56MB
+        31.2MB (33.33%): 400kB
+
+ request: Total 93.8MB
+          62.5MB (66.67%): 1.56MB
+          31.2MB (33.33%): 400kB
+
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_sizetags.dot b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_sizetags.dot
new file mode 100644
index 0000000..6be6112
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_sizetags.dot
@@ -0,0 +1,30 @@
+digraph "unnamed" {
+node [style=filled fillcolor="#f8f8f8"]
+subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
+N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
+NN1_0 [label = "16B..64B" id="NN1_0" fontsize=8 shape=box3d tooltip="93.75MB"]
+N1 -> NN1_0 [label=" 93.75MB" weight=100 tooltip="93.75MB" labeltooltip="93.75MB"]
+NN1_1 [label = "2B..8B" id="NN1_1" fontsize=8 shape=box3d tooltip="93.75MB"]
+N1 -> NN1_1 [label=" 93.75MB" weight=100 tooltip="93.75MB" labeltooltip="93.75MB"]
+NN1_2 [label = "256B..1.56MB" id="NN1_2" fontsize=8 shape=box3d tooltip="62.50MB"]
+N1 -> NN1_2 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
+NN1_3 [label = "128B" id="NN1_3" fontsize=8 shape=box3d tooltip="31.25MB"]
+N1 -> NN1_3 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
+N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+NN3_0 [label = "16B..64B" id="NN3_0" fontsize=8 shape=box3d tooltip="190.43MB"]
+N3 -> NN3_0 [label=" 190.43MB" weight=100 tooltip="190.43MB" labeltooltip="190.43MB" style="dotted"]
+NN3_1 [label = "2B..8B" id="NN3_1" fontsize=8 shape=box3d tooltip="190.43MB"]
+N3 -> NN3_1 [label=" 190.43MB" weight=100 tooltip="190.43MB" labeltooltip="190.43MB" style="dotted"]
+NN3_2 [label = "256B..1.56MB" id="NN3_2" fontsize=8 shape=box3d tooltip="125.98MB"]
+N3 -> NN3_2 [label=" 125.98MB" weight=100 tooltip="125.98MB" labeltooltip="125.98MB" style="dotted"]
+NN3_3 [label = "128B" id="NN3_3" fontsize=8 shape=box3d tooltip="63.48MB"]
+N3 -> NN3_3 [label=" 63.48MB" weight=100 tooltip="63.48MB" labeltooltip="63.48MB" style="dotted"]
+N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
+N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
+N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
+N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)" minlen=2]
+N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
+N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
+N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_tags.traces b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_tags.traces
new file mode 100644
index 0000000..547aea7
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_tags.traces
@@ -0,0 +1,32 @@
+Build ID: buildid
+comment
+Type: inuse_space
+-----------+-------------------------------------------------------
+      key1:  tag
+     bytes:  100kB
+   request:  100kB
+    1000kB   line1000
+             line2001
+             line2000
+             line3002
+             line3001
+             line3000
+-----------+-------------------------------------------------------
+     bytes:  200kB
+    3.91MB   line1000
+             line3001
+             line3000
+-----------+-------------------------------------------------------
+      key1:  tag
+     bytes:  1.56MB
+   request:  1.56MB
+   62.50MB   line2001
+             line2000
+             line3002
+             line3000
+-----------+-------------------------------------------------------
+     bytes:  400kB
+   31.25MB   line3002
+             line3001
+             line3000
+-----------+-------------------------------------------------------
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.call_tree.text b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.call_tree.text
new file mode 100644
index 0000000..78a2298
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.call_tree.text
@@ -0,0 +1,8 @@
+Showing nodes accounting for 1.12s, 100% of 1.12s total
+Showing top 5 nodes out of 6
+      flat  flat%   sum%        cum   cum%
+     1.10s 98.21% 98.21%      1.10s 98.21%  line1000
+     0.01s  0.89% 99.11%      1.01s 90.18%  line2001 (inline)
+     0.01s  0.89%   100%      1.02s 91.07%  line3002 (inline)
+         0     0%   100%      1.01s 90.18%  line2000
+         0     0%   100%      1.12s   100%  line3000
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.text b/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.text
deleted file mode 100644
index 0807ed2..0000000
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.unknown.flat.functions.text
+++ /dev/null
@@ -1,8 +0,0 @@
-Showing nodes accounting for 1.12s, 100% of 1.12s total
-      flat  flat%   sum%        cum   cum%
-     1.10s 98.21% 98.21%      1.10s 98.21%  line1000 testdata/file1000.src
-     0.01s  0.89% 99.11%      1.01s 90.18%  line2001 testdata/file2000.src (inline)
-     0.01s  0.89%   100%      1.02s 91.07%  line3002 testdata/file3000.src (inline)
-         0     0%   100%      1.01s 90.18%  line2000 testdata/file2000.src
-         0     0%   100%      1.12s   100%  line3000 testdata/file3000.src
-         0     0%   100%      1.11s 99.11%  line3001 testdata/file3000.src (inline)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
new file mode 100644
index 0000000..48f0fa1
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
@@ -0,0 +1,965 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package driver
+
+import "html/template"
+
+// addTemplates adds a set of template definitions to templates.
+func addTemplates(templates *template.Template) {
+	template.Must(templates.Parse(`
+{{define "css"}}
+<style type="text/css">
+html {
+  height: 100%;
+  min-height: 100%;
+  margin: 0px;
+}
+body {
+  margin: 0px;
+  width: 100%;
+  height: 100%;
+  min-height: 100%;
+  overflow: hidden;
+}
+#graphcontainer {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  min-height: 100%;
+  width: 100%;
+  min-width: 100%;
+  margin: 0px;
+}
+#graph {
+  flex: 1 1 auto;
+  overflow: hidden;
+}
+svg {
+  width: 100%;
+  height: auto;
+}
+button {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+#detailtext {
+  display: none;
+  position: fixed;
+  top: 20px;
+  right: 10px;
+  background-color: #ffffff;
+  min-width: 160px;
+  border: 1px solid #888;
+  box-shadow: 4px 4px 4px 0px rgba(0,0,0,0.2);
+  z-index: 1;
+}
+#closedetails {
+  float: right;
+  margin: 2px;
+}
+#home {
+  font-size: 14pt;
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+  float: right;
+}
+.menubar {
+  display: inline-block;
+  background-color: #f8f8f8;
+  border: 1px solid #ccc;
+  width: 100%;
+}
+.menu-header {
+  position: relative;
+  display: inline-block;
+  padding: 2px 2px;
+  font-size: 14pt;
+}
+.menu {
+  display: none;
+  position: absolute;
+  background-color: #f8f8f8;
+  border: 1px solid #888;
+  box-shadow: 4px 4px 4px 0px rgba(0,0,0,0.2);
+  z-index: 1;
+  margin-top: 2px;
+  left: 0px;
+  min-width: 5em;
+}
+.menu-header, .menu {
+  cursor: default;
+  user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -webkit-user-select: none;
+}
+.menu hr {
+  background-color: #fff;
+  margin-top: 0px;
+  margin-bottom: 0px;
+}
+.menu a, .menu button {
+  display: block;
+  width: 100%;
+  margin: 0px;
+  padding: 2px 0px 2px 0px;
+  text-align: left;
+  text-decoration: none;
+  color: #000;
+  background-color: #f8f8f8;
+  font-size: 12pt;
+  border: none;
+}
+.menu-header:hover {
+  background-color: #ccc;
+}
+.menu a:hover, .menu button:hover {
+  background-color: #ccc;
+}
+.menu a.disabled {
+  color: gray;
+  pointer-events: none;
+}
+#searchbox {
+  margin-left: 10pt;
+}
+#bodycontainer {
+  width: 100%;
+  height: 100%;
+  max-height: 100%;
+  overflow: scroll;
+  padding-top: 5px;
+}
+#toptable {
+  border-spacing: 0px;
+  width: 100%;
+  padding-bottom: 1em;
+}
+#toptable tr th {
+  border-bottom: 1px solid black;
+  text-align: right;
+  padding-left: 1em;
+  padding-top: 0.2em;
+  padding-bottom: 0.2em;
+}
+#toptable tr td {
+  padding-left: 1em;
+  font: monospace;
+  text-align: right;
+  white-space: nowrap;
+  cursor: default;
+}
+#toptable tr th:nth-child(6),
+#toptable tr th:nth-child(7),
+#toptable tr td:nth-child(6),
+#toptable tr td:nth-child(7) {
+  text-align: left;
+}
+#toptable tr td:nth-child(6) {
+  max-width: 30em;  // Truncate very long names
+  overflow: hidden;
+}
+#flathdr1, #flathdr2, #cumhdr1, #cumhdr2, #namehdr {
+  cursor: ns-resize;
+}
+.hilite {
+  background-color: #ccf;
+}
+</style>
+{{end}}
+
+{{define "header"}}
+<div id="detailtext">
+<button id="closedetails">Close</button>
+{{range .Legend}}<div>{{.}}</div>{{end}}
+</div>
+
+<div class="menubar">
+
+<div class="menu-header">
+View
+<div class="menu">
+<a title="{{.Help.top}}"  href="/top" id="topbtn">Top</a>
+<a title="{{.Help.graph}}" href="/" id="graphbtn">Graph</a>
+<a title="{{.Help.peek}}" href="/peek" id="peek">Peek</a>
+<a title="{{.Help.list}}" href="/source" id="list">Source</a>
+<a title="{{.Help.disasm}}" href="/disasm" id="disasm">Disassemble</a>
+<hr>
+<button title="{{.Help.details}}" id="details">Details</button>
+</div>
+</div>
+
+<div class="menu-header">
+Refine
+<div class="menu">
+<a title="{{.Help.focus}}" href="{{.BaseURL}}" id="focus">Focus</a>
+<a title="{{.Help.ignore}}" href="{{.BaseURL}}" id="ignore">Ignore</a>
+<a title="{{.Help.hide}}" href="{{.BaseURL}}" id="hide">Hide</a>
+<a title="{{.Help.show}}" href="{{.BaseURL}}" id="show">Show</a>
+<hr>
+<a title="{{.Help.reset}}" href="{{.BaseURL}}">Reset</a>
+</div>
+</div>
+
+<input id="searchbox" type="text" placeholder="Search regexp" autocomplete="off" autocapitalize="none" size=40>
+
+<span id="home">{{.Title}}</span>
+
+</div> <!-- menubar -->
+
+<div id="errors">{{range .Errors}}<div>{{.}}</div>{{end}}</div>
+{{end}}
+
+{{define "graph" -}}
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>{{.Title}}</title>
+{{template "css" .}}
+</head>
+<body>
+
+{{template "header" .}}
+<div id="graphcontainer">
+<div id="graph">
+{{.HTMLBody}}
+</div>
+
+</div>
+{{template "script" .}}
+<script>viewer({{.BaseURL}}, {{.Nodes}})</script>
+</body>
+</html>
+{{end}}
+
+{{define "script"}}
+<script>
+// Make svg pannable and zoomable.
+// Call clickHandler(t) if a click event is caught by the pan event handlers.
+function initPanAndZoom(svg, clickHandler) {
+  'use strict';
+
+  // Current mouse/touch handling mode
+  const IDLE = 0
+  const MOUSEPAN = 1
+  const TOUCHPAN = 2
+  const TOUCHZOOM = 3
+  let mode = IDLE
+
+  // State needed to implement zooming.
+  let currentScale = 1.0
+  const initWidth = svg.viewBox.baseVal.width
+  const initHeight = svg.viewBox.baseVal.height
+
+  // State needed to implement panning.
+  let panLastX = 0      // Last event X coordinate
+  let panLastY = 0      // Last event Y coordinate
+  let moved = false     // Have we seen significant movement
+  let touchid = null    // Current touch identifier
+
+  // State needed for pinch zooming
+  let touchid2 = null     // Second id for pinch zooming
+  let initGap = 1.0       // Starting gap between two touches
+  let initScale = 1.0     // currentScale when pinch zoom started
+  let centerPoint = null  // Center point for scaling
+
+  // Convert event coordinates to svg coordinates.
+  function toSvg(x, y) {
+    const p = svg.createSVGPoint()
+    p.x = x
+    p.y = y
+    let m = svg.getCTM()
+    if (m == null) m = svg.getScreenCTM()  // Firefox workaround.
+    return p.matrixTransform(m.inverse())
+  }
+
+  // Change the scaling for the svg to s, keeping the point denoted
+  // by u (in svg coordinates]) fixed at the same screen location.
+  function rescale(s, u) {
+    // Limit to a good range.
+    if (s < 0.2) s = 0.2
+    if (s > 10.0) s = 10.0
+
+    currentScale = s
+
+    // svg.viewBox defines the visible portion of the user coordinate
+    // system.  So to magnify by s, divide the visible portion by s,
+    // which will then be stretched to fit the viewport.
+    const vb = svg.viewBox
+    const w1 = vb.baseVal.width
+    const w2 = initWidth / s
+    const h1 = vb.baseVal.height
+    const h2 = initHeight / s
+    vb.baseVal.width = w2
+    vb.baseVal.height = h2
+
+    // We also want to adjust vb.baseVal.x so that u.x remains at same
+    // screen X coordinate.  In other words, want to change it from x1 to x2
+    // so that:
+    //     (u.x - x1) / w1 = (u.x - x2) / w2
+    // Simplifying that, we get
+    //     (u.x - x1) * (w2 / w1) = u.x - x2
+    //     x2 = u.x - (u.x - x1) * (w2 / w1)
+    vb.baseVal.x = u.x - (u.x - vb.baseVal.x) * (w2 / w1)
+    vb.baseVal.y = u.y - (u.y - vb.baseVal.y) * (h2 / h1)
+  }
+
+  function handleWheel(e) {
+    if (e.deltaY == 0) return
+    // Change scale factor by 1.1 or 1/1.1
+    rescale(currentScale * (e.deltaY < 0 ? 1.1 : (1/1.1)),
+            toSvg(e.offsetX, e.offsetY))
+  }
+
+  function setMode(m) {
+    mode = m
+    touchid = null
+    touchid2 = null
+  }
+
+  function panStart(x, y) {
+    moved = false
+    panLastX = x
+    panLastY = y
+  }
+
+  function panMove(x, y) {
+    let dx = x - panLastX
+    let dy = y - panLastY
+    if (Math.abs(dx) <= 2 && Math.abs(dy) <= 2) return  // Ignore tiny moves
+
+    moved = true
+    panLastX = x
+    panLastY = y
+
+    // Firefox workaround: get dimensions from parentNode.
+    const swidth = svg.clientWidth || svg.parentNode.clientWidth
+    const sheight = svg.clientHeight || svg.parentNode.clientHeight
+
+    // Convert deltas from screen space to svg space.
+    dx *= (svg.viewBox.baseVal.width / swidth)
+    dy *= (svg.viewBox.baseVal.height / sheight)
+
+    svg.viewBox.baseVal.x -= dx
+    svg.viewBox.baseVal.y -= dy
+  }
+
+  function handleScanStart(e) {
+    if (e.button != 0) return  // Do not catch right-clicks etc.
+    setMode(MOUSEPAN)
+    panStart(e.clientX, e.clientY)
+    e.preventDefault()
+    svg.addEventListener("mousemove", handleScanMove)
+  }
+
+  function handleScanMove(e) {
+    if (e.buttons == 0) {
+      // Missed an end event, perhaps because mouse moved outside window.
+      setMode(IDLE)
+      svg.removeEventListener("mousemove", handleScanMove)
+      return
+    }
+    if (mode == MOUSEPAN) panMove(e.clientX, e.clientY)
+  }
+
+  function handleScanEnd(e) {
+    if (mode == MOUSEPAN) panMove(e.clientX, e.clientY)
+    setMode(IDLE)
+    svg.removeEventListener("mousemove", handleScanMove)
+    if (!moved) clickHandler(e.target)
+  }
+
+  // Find touch object with specified identifier.
+  function findTouch(tlist, id) {
+    for (const t of tlist) {
+      if (t.identifier == id) return t
+    }
+    return null
+  }
+
+ // Return distance between two touch points
+  function touchGap(t1, t2) {
+    const dx = t1.clientX - t2.clientX
+    const dy = t1.clientY - t2.clientY
+    return Math.hypot(dx, dy)
+  }
+
+  function handleTouchStart(e) {
+    if (mode == IDLE && e.changedTouches.length == 1) {
+      // Start touch based panning
+      const t = e.changedTouches[0]
+      setMode(TOUCHPAN)
+      touchid = t.identifier
+      panStart(t.clientX, t.clientY)
+      e.preventDefault()
+    } else if (mode == TOUCHPAN && e.touches.length == 2) {
+      // Start pinch zooming
+      setMode(TOUCHZOOM)
+      const t1 = e.touches[0]
+      const t2 = e.touches[1]
+      touchid = t1.identifier
+      touchid2 = t2.identifier
+      initScale = currentScale
+      initGap = touchGap(t1, t2)
+      centerPoint = toSvg((t1.clientX + t2.clientX) / 2,
+                          (t1.clientY + t2.clientY) / 2)
+      e.preventDefault()
+    }
+  }
+
+  function handleTouchMove(e) {
+    if (mode == TOUCHPAN) {
+      const t = findTouch(e.changedTouches, touchid)
+      if (t == null) return
+      if (e.touches.length != 1) {
+        setMode(IDLE)
+        return
+      }
+      panMove(t.clientX, t.clientY)
+      e.preventDefault()
+    } else if (mode == TOUCHZOOM) {
+      // Get two touches; new gap; rescale to ratio.
+      const t1 = findTouch(e.touches, touchid)
+      const t2 = findTouch(e.touches, touchid2)
+      if (t1 == null || t2 == null) return
+      const gap = touchGap(t1, t2)
+      rescale(initScale * gap / initGap, centerPoint)
+      e.preventDefault()
+    }
+  }
+
+  function handleTouchEnd(e) {
+    if (mode == TOUCHPAN) {
+      const t = findTouch(e.changedTouches, touchid)
+      if (t == null) return
+      panMove(t.clientX, t.clientY)
+      setMode(IDLE)
+      e.preventDefault()
+      if (!moved) clickHandler(t.target)
+    } else if (mode == TOUCHZOOM) {
+      setMode(IDLE)
+      e.preventDefault()
+    }
+  }
+
+  svg.addEventListener("mousedown", handleScanStart)
+  svg.addEventListener("mouseup", handleScanEnd)
+  svg.addEventListener("touchstart", handleTouchStart)
+  svg.addEventListener("touchmove", handleTouchMove)
+  svg.addEventListener("touchend", handleTouchEnd)
+  svg.addEventListener("wheel", handleWheel, true)
+}
+
+function initMenus() {
+  'use strict';
+
+  let activeMenu = null;
+  let activeMenuHdr = null;
+
+  function cancelActiveMenu() {
+    if (activeMenu == null) return;
+    activeMenu.style.display = "none";
+    activeMenu = null;
+    activeMenuHdr = null;
+  }
+
+  // Set click handlers on every menu header.
+  for (const menu of document.getElementsByClassName("menu")) {
+    const hdr = menu.parentElement;
+    if (hdr == null) return;
+    function showMenu(e) {
+      // menu is a child of hdr, so this event can fire for clicks
+      // inside menu. Ignore such clicks.
+      if (e.target != hdr) return;
+      activeMenu = menu;
+      activeMenuHdr = hdr;
+      menu.style.display = "block";
+    }
+    hdr.addEventListener("mousedown", showMenu);
+    hdr.addEventListener("touchstart", showMenu);
+  }
+
+  // If there is an active menu and a down event outside, retract the menu.
+  for (const t of ["mousedown", "touchstart"]) {
+    document.addEventListener(t, (e) => {
+      // Note: to avoid unnecessary flicker, if the down event is inside
+      // the active menu header, do not retract the menu.
+      if (activeMenuHdr != e.target.closest(".menu-header")) {
+        cancelActiveMenu();
+      }
+    }, { passive: true, capture: true });
+  }
+
+  // If there is an active menu and an up event inside, retract the menu.
+  document.addEventListener("mouseup", (e) => {
+    if (activeMenu == e.target.closest(".menu")) {
+      cancelActiveMenu();
+    }
+  }, { passive: true, capture: true });
+}
+
+function viewer(baseUrl, nodes) {
+  'use strict';
+
+  // Elements
+  const search = document.getElementById("searchbox")
+  const graph0 = document.getElementById("graph0")
+  const svg = (graph0 == null ? null : graph0.parentElement)
+  const toptable = document.getElementById("toptable")
+
+  let regexpActive = false
+  let selected = new Map()
+  let origFill = new Map()
+  let searchAlarm = null
+  let buttonsEnabled = true
+
+  function handleDetails() {
+    const detailsText = document.getElementById("detailtext")
+    if (detailsText != null) detailsText.style.display = "block"
+  }
+
+  function handleCloseDetails() {
+    const detailsText = document.getElementById("detailtext")
+    if (detailsText != null) detailsText.style.display = "none"
+  }
+
+  function handleKey(e) {
+    if (e.keyCode != 13) return
+    window.location.href =
+        updateUrl(new URL({{.BaseURL}}, window.location.href), "f")
+    e.preventDefault()
+  }
+
+  function handleSearch() {
+    // Delay expensive processing so a flurry of key strokes is handled once.
+    if (searchAlarm != null) {
+      clearTimeout(searchAlarm)
+    }
+    searchAlarm = setTimeout(selectMatching, 300)
+
+    regexpActive = true
+    updateButtons()
+  }
+
+  function selectMatching() {
+    searchAlarm = null
+    let re = null
+    if (search.value != "") {
+      try {
+        re = new RegExp(search.value)
+      } catch (e) {
+        // TODO: Display error state in search box
+        return
+      }
+    }
+
+    function match(text) {
+      return re != null && re.test(text)
+    }
+
+    // drop currently selected items that do not match re.
+    selected.forEach(function(v, n) {
+      if (!match(nodes[n])) {
+        unselect(n, document.getElementById("node" + n))
+      }
+    })
+
+    // add matching items that are not currently selected.
+    for (let n = 0; n < nodes.length; n++) {
+      if (!selected.has(n) && match(nodes[n])) {
+        select(n, document.getElementById("node" + n))
+      }
+    }
+
+    updateButtons()
+  }
+
+  function toggleSvgSelect(elem) {
+    // Walk up to immediate child of graph0
+    while (elem != null && elem.parentElement != graph0) {
+      elem = elem.parentElement
+    }
+    if (!elem) return
+
+    // Disable regexp mode.
+    regexpActive = false
+
+    const n = nodeId(elem)
+    if (n < 0) return
+    if (selected.has(n)) {
+      unselect(n, elem)
+    } else {
+      select(n, elem)
+    }
+    updateButtons()
+  }
+
+  function unselect(n, elem) {
+    if (elem == null) return
+    selected.delete(n)
+    setBackground(elem, false)
+  }
+
+  function select(n, elem) {
+    if (elem == null) return
+    selected.set(n, true)
+    setBackground(elem, true)
+  }
+
+  function nodeId(elem) {
+    const id = elem.id
+    if (!id) return -1
+    if (!id.startsWith("node")) return -1
+    const n = parseInt(id.slice(4), 10)
+    if (isNaN(n)) return -1
+    if (n < 0 || n >= nodes.length) return -1
+    return n
+  }
+
+  function setBackground(elem, set) {
+    // Handle table row highlighting.
+    if (elem.nodeName == "TR") {
+      elem.classList.toggle("hilite", set)
+      return
+    }
+
+    // Handle svg element highlighting.
+    const p = findPolygon(elem)
+    if (p != null) {
+      if (set) {
+        origFill.set(p, p.style.fill)
+        p.style.fill = "#ccccff"
+      } else if (origFill.has(p)) {
+        p.style.fill = origFill.get(p)
+      }
+    }
+  }
+
+  function findPolygon(elem) {
+    if (elem.localName == "polygon") return elem
+    for (const c of elem.children) {
+      const p = findPolygon(c)
+      if (p != null) return p
+    }
+    return null
+  }
+
+  // convert a string to a regexp that matches that string.
+  function quotemeta(str) {
+    return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1')
+  }
+
+  // Update id's href to reflect current selection whenever it is
+  // liable to be followed.
+  function makeLinkDynamic(id) {
+    const elem = document.getElementById(id)
+    if (elem == null) return
+
+    // Most links copy current selection into the "f" parameter,
+    // but Refine menu links are different.
+    let param = "f"
+    if (id == "ignore") param = "i"
+    if (id == "hide") param = "h"
+    if (id == "show") param = "s"
+
+    // We update on mouseenter so middle-click/right-click work properly.
+    elem.addEventListener("mouseenter", updater)
+    elem.addEventListener("touchstart", updater)
+
+    function updater() {
+      elem.href = updateUrl(new URL(elem.href), param)
+    }
+  }
+
+  // Update URL to reflect current selection.
+  function updateUrl(url, param) {
+    url.hash = ""
+
+    // The selection can be in one of two modes: regexp-based or
+    // list-based.  Construct regular expression depending on mode.
+    let re = regexpActive
+        ? search.value
+        : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join("|")
+
+    // Copy params from this page's URL.
+    const params = url.searchParams
+    for (const p of new URLSearchParams(window.location.search)) {
+      params.set(p[0], p[1])
+    }
+
+    if (re != "") {
+      // For focus/show, forget old parameter.  For others, add to re.
+      if (param != "f" && param != "s" && params.has(param)) {
+        const old = params.get(param)
+         if (old != "") {
+          re += "|" + old
+        }
+      }
+      params.set(param, re)
+    } else {
+      params.delete(param)
+    }
+
+    return url.toString()
+  }
+
+  function handleTopClick(e) {
+    // Walk back until we find TR and then get the Name column (index 5)
+    let elem = e.target
+    while (elem != null && elem.nodeName != "TR") {
+      elem = elem.parentElement
+    }
+    if (elem == null || elem.children.length < 6) return
+
+    e.preventDefault()
+    const tr = elem
+    const td = elem.children[5]
+    if (td.nodeName != "TD") return
+    const name = td.innerText
+    const index = nodes.indexOf(name)
+    if (index < 0) return
+
+    // Disable regexp mode.
+    regexpActive = false
+
+    if (selected.has(index)) {
+      unselect(index, elem)
+    } else {
+      select(index, elem)
+    }
+    updateButtons()
+  }
+
+  function updateButtons() {
+    const enable = (search.value != "" || selected.size != 0)
+    if (buttonsEnabled == enable) return
+    buttonsEnabled = enable
+    for (const id of ["focus", "ignore", "hide", "show"]) {
+      const link = document.getElementById(id)
+      if (link != null) {
+        link.classList.toggle("disabled", !enable)
+      }
+    }
+  }
+
+  // Initialize button states
+  updateButtons()
+
+  // Setup event handlers
+  initMenus()
+  if (svg != null) {
+    initPanAndZoom(svg, toggleSvgSelect)
+  }
+  if (toptable != null) {
+    toptable.addEventListener("mousedown", handleTopClick)
+    toptable.addEventListener("touchstart", handleTopClick)
+  }
+
+  const ids = ["topbtn", "graphbtn", "peek", "list", "disasm",
+               "focus", "ignore", "hide", "show"]
+  ids.forEach(makeLinkDynamic)
+
+  // Bind action to button with specified id.
+  function addAction(id, action) {
+    const btn = document.getElementById(id)
+    if (btn != null) {
+      btn.addEventListener("click", action)
+      btn.addEventListener("touchstart", action)
+    }
+  }
+
+  addAction("details", handleDetails)
+  addAction("closedetails", handleCloseDetails)
+
+  search.addEventListener("input", handleSearch)
+  search.addEventListener("keydown", handleKey)
+
+  // Give initial focus to main container so it can be scrolled using keys.
+  const main = document.getElementById("bodycontainer")
+  if (main) {
+    main.focus()
+  }
+}
+</script>
+{{end}}
+
+{{define "top" -}}
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>{{.Title}}</title>
+{{template "css" .}}
+<style type="text/css">
+</style>
+</head>
+<body>
+
+{{template "header" .}}
+
+<div id="bodycontainer">
+<table id="toptable">
+<tr>
+<th id="flathdr1">Flat
+<th id="flathdr2">Flat%
+<th>Sum%
+<th id="cumhdr1">Cum
+<th id="cumhdr2">Cum%
+<th id="namehdr">Name
+<th>Inlined?</tr>
+<tbody id="rows">
+</tbody>
+</table>
+</div>
+
+{{template "script" .}}
+<script>
+function makeTopTable(total, entries) {
+  const rows = document.getElementById("rows")
+  if (rows == null) return
+
+  // Store initial index in each entry so we have stable node ids for selection.
+  for (let i = 0; i < entries.length; i++) {
+    entries[i].Id = "node" + i
+  }
+
+  // Which column are we currently sorted by and in what order?
+  let currentColumn = ""
+  let descending = false
+  sortBy("Flat")
+
+  function sortBy(column) {
+    // Update sort criteria
+    if (column == currentColumn) {
+      descending = !descending  // Reverse order
+    } else {
+      currentColumn = column
+      descending = (column != "Name")
+    }
+
+    // Sort according to current criteria.
+    function cmp(a, b) {
+      const av = a[currentColumn]
+      const bv = b[currentColumn]
+      if (av < bv) return -1
+      if (av > bv) return +1
+      return 0
+    }
+    entries.sort(cmp)
+    if (descending) entries.reverse()
+
+    function addCell(tr, val) {
+      const td = document.createElement('td')
+      td.textContent = val
+      tr.appendChild(td)
+    }
+
+    function percent(v) {
+      return (v * 100.0 / total).toFixed(2) + "%"
+    }
+
+    // Generate rows
+    const fragment = document.createDocumentFragment()
+    let sum = 0
+    for (const row of entries) {
+      const tr = document.createElement('tr')
+      tr.id = row.Id
+      sum += row.Flat
+      addCell(tr, row.FlatFormat)
+      addCell(tr, percent(row.Flat))
+      addCell(tr, percent(sum))
+      addCell(tr, row.CumFormat)
+      addCell(tr, percent(row.Cum))
+      addCell(tr, row.Name)
+      addCell(tr, row.InlineLabel)
+      fragment.appendChild(tr)
+    }
+
+    rows.textContent = ''  // Remove old rows
+    rows.appendChild(fragment)
+  }
+
+  // Make different column headers trigger sorting.
+  function bindSort(id, column) {
+    const hdr = document.getElementById(id)
+    if (hdr == null) return
+    const fn = function() { sortBy(column) }
+    hdr.addEventListener("click", fn)
+    hdr.addEventListener("touch", fn)
+  }
+  bindSort("flathdr1", "Flat")
+  bindSort("flathdr2", "Flat")
+  bindSort("cumhdr1", "Cum")
+  bindSort("cumhdr2", "Cum")
+  bindSort("namehdr", "Name")
+}
+
+viewer({{.BaseURL}}, {{.Nodes}})
+makeTopTable({{.Total}}, {{.Top}})
+</script>
+</body>
+</html>
+{{end}}
+
+{{define "sourcelisting" -}}
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>{{.Title}}</title>
+{{template "css" .}}
+{{template "weblistcss" .}}
+{{template "weblistjs" .}}
+</head>
+<body>
+
+{{template "header" .}}
+
+<div id="bodycontainer">
+{{.HTMLBody}}
+</div>
+
+{{template "script" .}}
+<script>viewer({{.BaseURL}}, null)</script>
+</body>
+</html>
+{{end}}
+
+{{define "plaintext" -}}
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>{{.Title}}</title>
+{{template "css" .}}
+</head>
+<body>
+
+{{template "header" .}}
+
+<div id="bodycontainer">
+<pre>
+{{.TextBody}}
+</pre>
+</div>
+
+{{template "script" .}}
+<script>viewer({{.BaseURL}}, null)</script>
+</body>
+</html>
+{{end}}
+`))
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
new file mode 100644
index 0000000..67ae262
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
@@ -0,0 +1,393 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package driver
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"net"
+	"net/http"
+	gourl "net/url"
+	"os"
+	"os/exec"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/google/pprof/internal/graph"
+	"github.com/google/pprof/internal/plugin"
+	"github.com/google/pprof/internal/report"
+	"github.com/google/pprof/profile"
+)
+
+// webInterface holds the state needed for serving a browser based interface.
+type webInterface struct {
+	prof      *profile.Profile
+	options   *plugin.Options
+	help      map[string]string
+	templates *template.Template
+}
+
+func makeWebInterface(p *profile.Profile, opt *plugin.Options) *webInterface {
+	templates := template.New("templategroup")
+	addTemplates(templates)
+	report.AddSourceTemplates(templates)
+	return &webInterface{
+		prof:      p,
+		options:   opt,
+		help:      make(map[string]string),
+		templates: templates,
+	}
+}
+
+// maxEntries is the maximum number of entries to print for text interfaces.
+const maxEntries = 50
+
+// errorCatcher is a UI that captures errors for reporting to the browser.
+type errorCatcher struct {
+	plugin.UI
+	errors []string
+}
+
+func (ec *errorCatcher) PrintErr(args ...interface{}) {
+	ec.errors = append(ec.errors, strings.TrimSuffix(fmt.Sprintln(args...), "\n"))
+	ec.UI.PrintErr(args...)
+}
+
+// webArgs contains arguments passed to templates in webhtml.go.
+type webArgs struct {
+	BaseURL  string
+	Title    string
+	Errors   []string
+	Total    int64
+	Legend   []string
+	Help     map[string]string
+	Nodes    []string
+	HTMLBody template.HTML
+	TextBody string
+	Top      []report.TextItem
+}
+
+func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options) error {
+	host, portStr, err := net.SplitHostPort(hostport)
+	if err != nil {
+		return fmt.Errorf("could not split http address: %v", err)
+	}
+	port, err := strconv.Atoi(portStr)
+	if err != nil {
+		return fmt.Errorf("invalid port number: %v", err)
+	}
+	if host == "" {
+		host = "localhost"
+	}
+
+	interactiveMode = true
+	ui := makeWebInterface(p, o)
+	for n, c := range pprofCommands {
+		ui.help[n] = c.description
+	}
+	for n, v := range pprofVariables {
+		ui.help[n] = v.help
+	}
+	ui.help["details"] = "Show information about the profile and this view"
+	ui.help["graph"] = "Display profile as a directed graph"
+	ui.help["reset"] = "Show the entire profile"
+
+	server := o.HTTPServer
+	if server == nil {
+		server = defaultWebServer
+	}
+	args := &plugin.HTTPServerArgs{
+		Hostport: net.JoinHostPort(host, portStr),
+		Host:     host,
+		Port:     port,
+		Handlers: map[string]http.Handler{
+			"/":       http.HandlerFunc(ui.dot),
+			"/top":    http.HandlerFunc(ui.top),
+			"/disasm": http.HandlerFunc(ui.disasm),
+			"/source": http.HandlerFunc(ui.source),
+			"/peek":   http.HandlerFunc(ui.peek),
+		},
+	}
+
+	go openBrowser("http://"+args.Hostport, o)
+	return server(args)
+}
+
+func defaultWebServer(args *plugin.HTTPServerArgs) error {
+	ln, err := net.Listen("tcp", args.Hostport)
+	if err != nil {
+		return err
+	}
+	isLocal := isLocalhost(args.Host)
+	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		if isLocal {
+			// Only allow local clients
+			host, _, err := net.SplitHostPort(req.RemoteAddr)
+			if err != nil || !isLocalhost(host) {
+				http.Error(w, "permission denied", http.StatusForbidden)
+				return
+			}
+		}
+		h := args.Handlers[req.URL.Path]
+		if h == nil {
+			// Fall back to default behavior
+			h = http.DefaultServeMux
+		}
+		h.ServeHTTP(w, req)
+	})
+	s := &http.Server{Handler: handler}
+	return s.Serve(ln)
+}
+
+func isLocalhost(host string) bool {
+	for _, v := range []string{"localhost", "127.0.0.1", "[::1]", "::1"} {
+		if host == v {
+			return true
+		}
+	}
+	return false
+}
+
+func openBrowser(url string, o *plugin.Options) {
+	// Construct URL.
+	u, _ := gourl.Parse(url)
+	q := u.Query()
+	for _, p := range []struct{ param, key string }{
+		{"f", "focus"},
+		{"s", "show"},
+		{"i", "ignore"},
+		{"h", "hide"},
+	} {
+		if v := pprofVariables[p.key].value; v != "" {
+			q.Set(p.param, v)
+		}
+	}
+	u.RawQuery = q.Encode()
+
+	// Give server a little time to get ready.
+	time.Sleep(time.Millisecond * 500)
+
+	for _, b := range browsers() {
+		args := strings.Split(b, " ")
+		if len(args) == 0 {
+			continue
+		}
+		viewer := exec.Command(args[0], append(args[1:], u.String())...)
+		viewer.Stderr = os.Stderr
+		if err := viewer.Start(); err == nil {
+			return
+		}
+	}
+	// No visualizer succeeded, so just print URL.
+	o.UI.PrintErr(u.String())
+}
+
+func varsFromURL(u *gourl.URL) variables {
+	vars := pprofVariables.makeCopy()
+	vars["focus"].value = u.Query().Get("f")
+	vars["show"].value = u.Query().Get("s")
+	vars["ignore"].value = u.Query().Get("i")
+	vars["hide"].value = u.Query().Get("h")
+	return vars
+}
+
+// makeReport generates a report for the specified command.
+func (ui *webInterface) makeReport(w http.ResponseWriter, req *http.Request,
+	cmd []string, vars ...string) (*report.Report, []string) {
+	v := varsFromURL(req.URL)
+	for i := 0; i+1 < len(vars); i += 2 {
+		v[vars[i]].value = vars[i+1]
+	}
+	catcher := &errorCatcher{UI: ui.options.UI}
+	options := *ui.options
+	options.UI = catcher
+	_, rpt, err := generateRawReport(ui.prof, cmd, v, &options)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		ui.options.UI.PrintErr(err)
+		return nil, nil
+	}
+	return rpt, catcher.errors
+}
+
+// render generates html using the named template based on the contents of data.
+func (ui *webInterface) render(w http.ResponseWriter, baseURL, tmpl string,
+	rpt *report.Report, errList, legend []string, data webArgs) {
+	file := getFromLegend(legend, "File: ", "unknown")
+	profile := getFromLegend(legend, "Type: ", "unknown")
+	data.BaseURL = baseURL
+	data.Title = file + " " + profile
+	data.Errors = errList
+	data.Total = rpt.Total()
+	data.Legend = legend
+	data.Help = ui.help
+	html := &bytes.Buffer{}
+	if err := ui.templates.ExecuteTemplate(html, tmpl, data); err != nil {
+		http.Error(w, "internal template error", http.StatusInternalServerError)
+		ui.options.UI.PrintErr(err)
+		return
+	}
+	w.Header().Set("Content-Type", "text/html")
+	w.Write(html.Bytes())
+}
+
+// dot generates a web page containing an svg diagram.
+func (ui *webInterface) dot(w http.ResponseWriter, req *http.Request) {
+	rpt, errList := ui.makeReport(w, req, []string{"svg"})
+	if rpt == nil {
+		return // error already reported
+	}
+
+	// Generate dot graph.
+	g, config := report.GetDOT(rpt)
+	legend := config.Labels
+	config.Labels = nil
+	dot := &bytes.Buffer{}
+	graph.ComposeDot(dot, g, &graph.DotAttributes{}, config)
+
+	// Convert to svg.
+	svg, err := dotToSvg(dot.Bytes())
+	if err != nil {
+		http.Error(w, "Could not execute dot; may need to install graphviz.",
+			http.StatusNotImplemented)
+		ui.options.UI.PrintErr("Failed to execute dot. Is Graphviz installed?\n", err)
+		return
+	}
+
+	// Get all node names into an array.
+	nodes := []string{""} // dot starts with node numbered 1
+	for _, n := range g.Nodes {
+		nodes = append(nodes, n.Info.Name)
+	}
+
+	ui.render(w, "/", "graph", rpt, errList, legend, webArgs{
+		HTMLBody: template.HTML(string(svg)),
+		Nodes:    nodes,
+	})
+}
+
+func dotToSvg(dot []byte) ([]byte, error) {
+	cmd := exec.Command("dot", "-Tsvg")
+	out := &bytes.Buffer{}
+	cmd.Stdin, cmd.Stdout, cmd.Stderr = bytes.NewBuffer(dot), out, os.Stderr
+	if err := cmd.Run(); err != nil {
+		return nil, err
+	}
+
+	// Fix dot bug related to unquoted amperands.
+	svg := bytes.Replace(out.Bytes(), []byte("&;"), []byte("&amp;;"), -1)
+
+	// Cleanup for embedding by dropping stuff before the <svg> start.
+	if pos := bytes.Index(svg, []byte("<svg")); pos >= 0 {
+		svg = svg[pos:]
+	}
+	return svg, nil
+}
+
+func (ui *webInterface) top(w http.ResponseWriter, req *http.Request) {
+	rpt, errList := ui.makeReport(w, req, []string{"top"}, "nodecount", "500")
+	if rpt == nil {
+		return // error already reported
+	}
+	top, legend := report.TextItems(rpt)
+	var nodes []string
+	for _, item := range top {
+		nodes = append(nodes, item.Name)
+	}
+
+	ui.render(w, "/top", "top", rpt, errList, legend, webArgs{
+		Top:   top,
+		Nodes: nodes,
+	})
+}
+
+// disasm generates a web page containing disassembly.
+func (ui *webInterface) disasm(w http.ResponseWriter, req *http.Request) {
+	args := []string{"disasm", req.URL.Query().Get("f")}
+	rpt, errList := ui.makeReport(w, req, args)
+	if rpt == nil {
+		return // error already reported
+	}
+
+	out := &bytes.Buffer{}
+	if err := report.PrintAssembly(out, rpt, ui.options.Obj, maxEntries); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		ui.options.UI.PrintErr(err)
+		return
+	}
+
+	legend := report.ProfileLabels(rpt)
+	ui.render(w, "/disasm", "plaintext", rpt, errList, legend, webArgs{
+		TextBody: out.String(),
+	})
+
+}
+
+// source generates a web page containing source code annotated with profile
+// data.
+func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) {
+	args := []string{"weblist", req.URL.Query().Get("f")}
+	rpt, errList := ui.makeReport(w, req, args)
+	if rpt == nil {
+		return // error already reported
+	}
+
+	// Generate source listing.
+	var body bytes.Buffer
+	if err := report.PrintWebList(&body, rpt, ui.options.Obj, maxEntries); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		ui.options.UI.PrintErr(err)
+		return
+	}
+
+	legend := report.ProfileLabels(rpt)
+	ui.render(w, "/source", "sourcelisting", rpt, errList, legend, webArgs{
+		HTMLBody: template.HTML(body.String()),
+	})
+}
+
+// peek generates a web page listing callers/callers.
+func (ui *webInterface) peek(w http.ResponseWriter, req *http.Request) {
+	args := []string{"peek", req.URL.Query().Get("f")}
+	rpt, errList := ui.makeReport(w, req, args, "lines", "t")
+	if rpt == nil {
+		return // error already reported
+	}
+
+	out := &bytes.Buffer{}
+	if err := report.Generate(out, rpt, ui.options.Obj); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		ui.options.UI.PrintErr(err)
+		return
+	}
+
+	legend := report.ProfileLabels(rpt)
+	ui.render(w, "/peek", "plaintext", rpt, errList, legend, webArgs{
+		TextBody: out.String(),
+	})
+}
+
+// getFromLegend returns the suffix of an entry in legend that starts
+// with param.  It returns def if no such entry is found.
+func getFromLegend(legend []string, param, def string) string {
+	for _, s := range legend {
+		if strings.HasPrefix(s, param) {
+			return s[len(param):]
+		}
+	}
+	return def
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui_test.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui_test.go
new file mode 100644
index 0000000..96380a0
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui_test.go
@@ -0,0 +1,243 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package driver
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"os/exec"
+	"regexp"
+	"sync"
+	"testing"
+	"time"
+
+	"runtime"
+
+	"github.com/google/pprof/internal/plugin"
+	"github.com/google/pprof/profile"
+)
+
+func TestWebInterface(t *testing.T) {
+	// This test starts a web browser in a background goroutine
+	// after a 500ms delay. Sometimes the test exits before it
+	// can run the browser, but sometimes the browser does open.
+	// That's obviously unacceptable.
+	defer time.Sleep(2 * time.Second) // to see the browser open
+	t.Skip("golang.org/issue/22651")
+
+	if runtime.GOOS == "nacl" {
+		t.Skip("test assumes tcp available")
+	}
+
+	prof := makeFakeProfile()
+
+	// Custom http server creator
+	var server *httptest.Server
+	serverCreated := make(chan bool)
+	creator := func(a *plugin.HTTPServerArgs) error {
+		server = httptest.NewServer(http.HandlerFunc(
+			func(w http.ResponseWriter, r *http.Request) {
+				if h := a.Handlers[r.URL.Path]; h != nil {
+					h.ServeHTTP(w, r)
+				}
+			}))
+		serverCreated <- true
+		return nil
+	}
+
+	// Start server and wait for it to be initialized
+	go serveWebInterface("unused:1234", prof, &plugin.Options{
+		Obj:        fakeObjTool{},
+		UI:         &stdUI{},
+		HTTPServer: creator,
+	})
+	<-serverCreated
+	defer server.Close()
+
+	haveDot := false
+	if _, err := exec.LookPath("dot"); err == nil {
+		haveDot = true
+	}
+
+	type testCase struct {
+		path    string
+		want    []string
+		needDot bool
+	}
+	testcases := []testCase{
+		{"/", []string{"F1", "F2", "F3", "testbin", "cpu"}, true},
+		{"/top", []string{`"Name":"F2","InlineLabel":"","Flat":200,"Cum":300,"FlatFormat":"200ms","CumFormat":"300ms"}`}, false},
+		{"/source?f=" + url.QueryEscape("F[12]"),
+			[]string{"F1", "F2", "300ms +line1"}, false},
+		{"/peek?f=" + url.QueryEscape("F[12]"),
+			[]string{"300ms.*F1", "200ms.*300ms.*F2"}, false},
+		{"/disasm?f=" + url.QueryEscape("F[12]"),
+			[]string{"f1:asm", "f2:asm"}, false},
+	}
+	for _, c := range testcases {
+		if c.needDot && !haveDot {
+			t.Log("skipping", c.path, "since dot (graphviz) does not seem to be installed")
+			continue
+		}
+
+		res, err := http.Get(server.URL + c.path)
+		if err != nil {
+			t.Error("could not fetch", c.path, err)
+			continue
+		}
+		data, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Error("could not read response", c.path, err)
+			continue
+		}
+		result := string(data)
+		for _, w := range c.want {
+			if match, _ := regexp.MatchString(w, result); !match {
+				t.Errorf("response for %s does not match "+
+					"expected pattern '%s'; "+
+					"actual result:\n%s", c.path, w, result)
+			}
+		}
+	}
+
+	// Also fetch all the test case URLs in parallel to test thread
+	// safety when run under the race detector.
+	var wg sync.WaitGroup
+	for _, c := range testcases {
+		if c.needDot && !haveDot {
+			continue
+		}
+		path := server.URL + c.path
+		for count := 0; count < 2; count++ {
+			wg.Add(1)
+			go func() {
+				http.Get(path)
+				wg.Done()
+			}()
+		}
+	}
+	wg.Wait()
+
+	time.Sleep(5 * time.Second)
+}
+
+// Implement fake object file support.
+
+const addrBase = 0x1000
+const fakeSource = "testdata/file1000.src"
+
+type fakeObj struct{}
+
+func (f fakeObj) Close() error    { return nil }
+func (f fakeObj) Name() string    { return "testbin" }
+func (f fakeObj) Base() uint64    { return 0 }
+func (f fakeObj) BuildID() string { return "" }
+func (f fakeObj) SourceLine(addr uint64) ([]plugin.Frame, error) {
+	return nil, fmt.Errorf("SourceLine unimplemented")
+}
+func (f fakeObj) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
+	return []*plugin.Sym{
+		{[]string{"F1"}, fakeSource, addrBase, addrBase + 10},
+		{[]string{"F2"}, fakeSource, addrBase + 10, addrBase + 20},
+		{[]string{"F3"}, fakeSource, addrBase + 20, addrBase + 30},
+	}, nil
+}
+
+type fakeObjTool struct{}
+
+func (obj fakeObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
+	return fakeObj{}, nil
+}
+
+func (obj fakeObjTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
+	return []plugin.Inst{
+		{Addr: addrBase + 0, Text: "f1:asm", Function: "F1"},
+		{Addr: addrBase + 10, Text: "f2:asm", Function: "F2"},
+		{Addr: addrBase + 20, Text: "d3:asm", Function: "F3"},
+	}, nil
+}
+
+func makeFakeProfile() *profile.Profile {
+	// Three functions: F1, F2, F3 with three lines, 11, 22, 33.
+	funcs := []*profile.Function{
+		{ID: 1, Name: "F1", Filename: fakeSource, StartLine: 3},
+		{ID: 2, Name: "F2", Filename: fakeSource, StartLine: 5},
+		{ID: 3, Name: "F3", Filename: fakeSource, StartLine: 7},
+	}
+	lines := []profile.Line{
+		{Function: funcs[0], Line: 11},
+		{Function: funcs[1], Line: 22},
+		{Function: funcs[2], Line: 33},
+	}
+	mapping := []*profile.Mapping{
+		{
+			ID:             1,
+			Start:          addrBase,
+			Limit:          addrBase + 10,
+			Offset:         0,
+			File:           "testbin",
+			HasFunctions:   true,
+			HasFilenames:   true,
+			HasLineNumbers: true,
+		},
+	}
+
+	// Three interesting addresses: base+{10,20,30}
+	locs := []*profile.Location{
+		{ID: 1, Address: addrBase + 10, Line: lines[0:1], Mapping: mapping[0]},
+		{ID: 2, Address: addrBase + 20, Line: lines[1:2], Mapping: mapping[0]},
+		{ID: 3, Address: addrBase + 30, Line: lines[2:3], Mapping: mapping[0]},
+	}
+
+	// Two stack traces.
+	return &profile.Profile{
+		PeriodType:    &profile.ValueType{Type: "cpu", Unit: "milliseconds"},
+		Period:        1,
+		DurationNanos: 10e9,
+		SampleType: []*profile.ValueType{
+			{Type: "cpu", Unit: "milliseconds"},
+		},
+		Sample: []*profile.Sample{
+			{
+				Location: []*profile.Location{locs[2], locs[1], locs[0]},
+				Value:    []int64{100},
+			},
+			{
+				Location: []*profile.Location{locs[1], locs[0]},
+				Value:    []int64{200},
+			},
+		},
+		Location: locs,
+		Function: funcs,
+		Mapping:  mapping,
+	}
+}
+
+func TestIsLocalHost(t *testing.T) {
+	for _, s := range []string{"localhost:10000", "[::1]:10000", "127.0.0.1:10000"} {
+		host, _, err := net.SplitHostPort(s)
+		if err != nil {
+			t.Error("unexpected error when splitting", s)
+			continue
+		}
+		if !isLocalhost(host) {
+			t.Errorf("host %s from %s not considered local", host, s)
+		}
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
index c46272e..9b238c5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
@@ -131,7 +131,7 @@
 				if buildID == nil {
 					buildID = note.Desc
 				} else {
-					return nil, fmt.Errorf("multiple build ids found, don't know which to use!")
+					return nil, fmt.Errorf("multiple build ids found, don't know which to use")
 				}
 			}
 		}
@@ -240,17 +240,22 @@
 		}
 		return start, nil
 	case elf.ET_DYN:
-		if offset != 0 {
-			if loadSegment == nil || loadSegment.Vaddr == 0 {
-				return start - offset, nil
-			}
-			return 0, fmt.Errorf("Don't know how to handle mapping. Offset=%x, vaddr=%x",
-				offset, loadSegment.Vaddr)
-		}
+		// The process mapping information, start = start of virtual address range,
+		// and offset = offset in the executable file of the start address, tells us
+		// that a runtime virtual address x maps to a file offset
+		// fx = x - start + offset.
 		if loadSegment == nil {
-			return start, nil
+			return start - offset, nil
 		}
-		return start - loadSegment.Vaddr, nil
+		// The program header, if not nil, indicates the offset in the file where
+		// the executable segment is located (loadSegment.Off), and the base virtual
+		// address where the first byte of the segment is loaded
+		// (loadSegment.Vaddr). A file offset fx maps to a virtual (symbol) address
+		// sx = fx - loadSegment.Off + loadSegment.Vaddr.
+		//
+		// Thus, a runtime virtual address x maps to a symbol address
+		// sx = x - start + offset - loadSegment.Off + loadSegment.Vaddr.
+		return start - offset + loadSegment.Off - loadSegment.Vaddr, nil
 	}
 	return 0, fmt.Errorf("Don't know how to handle FileHeader.Type %v", fh.Type)
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
index b9f2a84..c6b8fe4 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
@@ -62,8 +62,9 @@
 		{"exec chromeos kernel 4", fhExec, kernelHeader, uint64p(0xffffffff81200198), 0x198, 0x100000, 0, 0x7ee00000, false},
 		{"exec chromeos kernel unremapped", fhExec, kernelHeader, uint64p(0xffffffff810001c8), 0xffffffff834001c8, 0xffffffffc0000000, 0xffffffff834001c8, 0x2400000, false},
 		{"dyn", fhDyn, nil, nil, 0x200000, 0x300000, 0, 0x200000, false},
-		{"dyn offset", fhDyn, lsOffset, nil, 0x0, 0x300000, 0, 0xFFFFFFFFFFC00000, false},
+		{"dyn map", fhDyn, lsOffset, nil, 0x0, 0x300000, 0, 0xFFFFFFFFFFE00000, false},
 		{"dyn nomap", fhDyn, nil, nil, 0x0, 0x0, 0, 0, false},
+		{"dyn map+offset", fhDyn, lsOffset, nil, 0x900000, 0xa00000, 0x200000, 0x500000, false},
 		{"rel", fhRel, nil, nil, 0x2000000, 0x3000000, 0, 0x2000000, false},
 		{"rel nomap", fhRel, nil, nil, 0x0, ^uint64(0), 0, 0, false},
 		{"rel offset", fhRel, nil, nil, 0x100000, 0x200000, 0x1, 0, true},
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
index c99e899..4e5d12f 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
@@ -42,15 +42,17 @@
 // DotConfig contains attributes about how a graph should be
 // constructed and how it should look.
 type DotConfig struct {
-	Title  string   // The title of the DOT graph
-	Labels []string // The labels for the DOT's legend
+	Title     string   // The title of the DOT graph
+	LegendURL string   // The URL to link to from the legend.
+	Labels    []string // The labels for the DOT's legend
 
-	FormatValue func(int64) string         // A formatting function for values
-	FormatTag   func(int64, string) string // A formatting function for numeric tags
-	Total       int64                      // The total weight of the graph, used to compute percentages
+	FormatValue func(int64) string // A formatting function for values
+	Total       int64              // The total weight of the graph, used to compute percentages
 }
 
-// Compose creates and writes a in the DOT format to the writer, using
+const maxNodelets = 4 // Number of nodelets for labels (both numeric and non)
+
+// ComposeDot creates and writes a in the DOT format to the writer, using
 // the configurations given.
 func ComposeDot(w io.Writer, g *Graph, a *DotAttributes, c *DotConfig) {
 	builder := &builder{w, a, c}
@@ -120,11 +122,19 @@
 // addLegend generates a legend in DOT format.
 func (b *builder) addLegend() {
 	labels := b.config.Labels
-	var title string
-	if len(labels) > 0 {
-		title = labels[0]
+	if len(labels) == 0 {
+		return
 	}
-	fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16 label="%s\l"] }`+"\n", title, strings.Join(labels, `\l`))
+	title := labels[0]
+	fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, title)
+	fmt.Fprintf(b, ` label="%s\l"`, strings.Join(labels, `\l`))
+	if b.config.LegendURL != "" {
+		fmt.Fprintf(b, ` URL="%s" target="_blank"`, b.config.LegendURL)
+	}
+	if b.config.Title != "" {
+		fmt.Fprintf(b, ` tooltip="%s"`, b.config.Title)
+	}
+	fmt.Fprintf(b, "] }\n")
 }
 
 // addNode generates a graph node in DOT format.
@@ -176,8 +186,8 @@
 	}
 
 	// Create DOT attribute for node.
-	attr := fmt.Sprintf(`label="%s" fontsize=%d shape=%s tooltip="%s (%s)" color="%s" fillcolor="%s"`,
-		label, fontSize, shape, node.Info.PrintableName(), cumValue,
+	attr := fmt.Sprintf(`label="%s" id="node%d" fontsize=%d shape=%s tooltip="%s (%s)" color="%s" fillcolor="%s"`,
+		label, nodeID, fontSize, shape, node.Info.PrintableName(), cumValue,
 		dotColor(float64(node.CumValue())/float64(abs64(b.config.Total)), false),
 		dotColor(float64(node.CumValue())/float64(abs64(b.config.Total)), true))
 
@@ -204,13 +214,11 @@
 
 // addNodelets generates the DOT boxes for the node tags if they exist.
 func (b *builder) addNodelets(node *Node, nodeID int) bool {
-	const maxNodelets = 4    // Number of nodelets for alphanumeric labels
-	const maxNumNodelets = 4 // Number of nodelets for numeric labels
 	var nodelets string
 
 	// Populate two Tag slices, one for LabelTags and one for NumericTags.
 	var ts []*Tag
-	lnts := make(map[string][]*Tag, 0)
+	lnts := make(map[string][]*Tag)
 	for _, t := range node.LabelTags {
 		ts = append(ts, t)
 	}
@@ -239,15 +247,15 @@
 			continue
 		}
 		weight := b.config.FormatValue(w)
-		nodelets += fmt.Sprintf(`N%d_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", nodeID, i, t.Name, weight)
+		nodelets += fmt.Sprintf(`N%d_%d [label = "%s" id="N%d_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", nodeID, i, t.Name, nodeID, i, weight)
 		nodelets += fmt.Sprintf(`N%d -> N%d_%d [label=" %s" weight=100 tooltip="%s" labeltooltip="%s"]`+"\n", nodeID, nodeID, i, weight, weight, weight)
 		if nts := lnts[t.Name]; nts != nil {
-			nodelets += b.numericNodelets(nts, maxNumNodelets, flatTags, fmt.Sprintf(`N%d_%d`, nodeID, i))
+			nodelets += b.numericNodelets(nts, maxNodelets, flatTags, fmt.Sprintf(`N%d_%d`, nodeID, i))
 		}
 	}
 
 	if nts := lnts[""]; nts != nil {
-		nodelets += b.numericNodelets(nts, maxNumNodelets, flatTags, fmt.Sprintf(`N%d`, nodeID))
+		nodelets += b.numericNodelets(nts, maxNodelets, flatTags, fmt.Sprintf(`N%d`, nodeID))
 	}
 
 	fmt.Fprint(b, nodelets)
@@ -266,7 +274,7 @@
 		}
 		if w != 0 {
 			weight := b.config.FormatValue(w)
-			nodelets += fmt.Sprintf(`N%s_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", source, j, t.Name, weight)
+			nodelets += fmt.Sprintf(`N%s_%d [label = "%s" id="N%s_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", source, j, t.Name, source, j, weight)
 			nodelets += fmt.Sprintf(`%s -> N%s_%d [label=" %s" weight=100 tooltip="%s" labeltooltip="%s"%s]`+"\n", source, source, j, weight, weight, weight, attr)
 		}
 	}
@@ -441,14 +449,9 @@
 }
 
 func (b *builder) tagGroupLabel(g []*Tag) (label string, flat, cum int64) {
-	formatTag := b.config.FormatTag
-	if formatTag == nil {
-		formatTag = measurement.Label
-	}
-
 	if len(g) == 1 {
 		t := g[0]
-		return formatTag(t.Value, t.Unit), t.FlatValue(), t.CumValue()
+		return measurement.Label(t.Value, t.Unit), t.FlatValue(), t.CumValue()
 	}
 	min := g[0]
 	max := g[0]
@@ -472,7 +475,11 @@
 	if dc != 0 {
 		c = c / dc
 	}
-	return formatTag(min.Value, min.Unit) + ".." + formatTag(max.Value, max.Unit), f, c
+
+	// Tags are not scaled with the selected output unit because tags are often
+	// much smaller than other values which appear, so the range of tag sizes
+	// sometimes would appear to be "0..0" when scaled to the selected output unit.
+	return measurement.Label(min.Value, min.Unit) + ".." + measurement.Label(max.Value, max.Unit), f, c
 }
 
 func min64(a, b int64) int64 {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go
index 7f51269..b8368b8 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go
@@ -16,8 +16,10 @@
 
 import (
 	"bytes"
+	"flag"
 	"fmt"
 	"io/ioutil"
+	"path/filepath"
 	"reflect"
 	"strconv"
 	"strings"
@@ -26,7 +28,7 @@
 	"github.com/google/pprof/internal/proftest"
 )
 
-const path = "testdata/"
+var updateFlag = flag.Bool("update", false, "Update the golden files")
 
 func TestComposeWithStandardGraph(t *testing.T) {
 	g := baseGraph()
@@ -35,12 +37,7 @@
 	var buf bytes.Buffer
 	ComposeDot(&buf, g, a, c)
 
-	want, err := ioutil.ReadFile(path + "compose1.dot")
-	if err != nil {
-		t.Fatalf("error reading test file: %v", err)
-	}
-
-	compareGraphs(t, buf.Bytes(), want)
+	compareGraphs(t, buf.Bytes(), "compose1.dot")
 }
 
 func TestComposeWithNodeAttributesAndZeroFlat(t *testing.T) {
@@ -64,12 +61,7 @@
 	var buf bytes.Buffer
 	ComposeDot(&buf, g, a, c)
 
-	want, err := ioutil.ReadFile(path + "compose2.dot")
-	if err != nil {
-		t.Fatalf("error reading test file: %v", err)
-	}
-
-	compareGraphs(t, buf.Bytes(), want)
+	compareGraphs(t, buf.Bytes(), "compose2.dot")
 }
 
 func TestComposeWithTagsAndResidualEdge(t *testing.T) {
@@ -97,12 +89,7 @@
 	var buf bytes.Buffer
 	ComposeDot(&buf, g, a, c)
 
-	want, err := ioutil.ReadFile(path + "compose3.dot")
-	if err != nil {
-		t.Fatalf("error reading test file: %v", err)
-	}
-
-	compareGraphs(t, buf.Bytes(), want)
+	compareGraphs(t, buf.Bytes(), "compose3.dot")
 }
 
 func TestComposeWithNestedTags(t *testing.T) {
@@ -127,12 +114,7 @@
 	var buf bytes.Buffer
 	ComposeDot(&buf, g, a, c)
 
-	want, err := ioutil.ReadFile(path + "compose5.dot")
-	if err != nil {
-		t.Fatalf("error reading test file: %v", err)
-	}
-
-	compareGraphs(t, buf.Bytes(), want)
+	compareGraphs(t, buf.Bytes(), "compose5.dot")
 }
 
 func TestComposeWithEmptyGraph(t *testing.T) {
@@ -142,12 +124,18 @@
 	var buf bytes.Buffer
 	ComposeDot(&buf, g, a, c)
 
-	want, err := ioutil.ReadFile(path + "compose4.dot")
-	if err != nil {
-		t.Fatalf("error reading test file: %v", err)
-	}
+	compareGraphs(t, buf.Bytes(), "compose4.dot")
+}
 
-	compareGraphs(t, buf.Bytes(), want)
+func TestComposeWithStandardGraphAndURL(t *testing.T) {
+	g := baseGraph()
+	a, c := baseAttrsAndConfig()
+	c.LegendURL = "http://example.com"
+
+	var buf bytes.Buffer
+	ComposeDot(&buf, g, a, c)
+
+	compareGraphs(t, buf.Bytes(), "compose6.dot")
 }
 
 func baseGraph() *Graph {
@@ -199,13 +187,78 @@
 	return a, c
 }
 
-func compareGraphs(t *testing.T, got, want []byte) {
+func compareGraphs(t *testing.T, got []byte, wantFile string) {
+	wantFile = filepath.Join("testdata", wantFile)
+	want, err := ioutil.ReadFile(wantFile)
+	if err != nil {
+		t.Fatalf("error reading test file %s: %v", wantFile, err)
+	}
+
 	if string(got) != string(want) {
 		d, err := proftest.Diff(got, want)
 		if err != nil {
 			t.Fatalf("error finding diff: %v", err)
 		}
 		t.Errorf("Compose incorrectly wrote %s", string(d))
+		if *updateFlag {
+			err := ioutil.WriteFile(wantFile, got, 0644)
+			if err != nil {
+				t.Errorf("failed to update the golden file %q: %v", wantFile, err)
+			}
+		}
+	}
+}
+
+func TestNodeletCountCapping(t *testing.T) {
+	labelTags := make(TagMap)
+	for i := 0; i < 10; i++ {
+		name := fmt.Sprintf("tag-%d", i)
+		labelTags[name] = &Tag{
+			Name: name,
+			Flat: 10,
+			Cum:  10,
+		}
+	}
+	numTags := make(TagMap)
+	for i := 0; i < 10; i++ {
+		name := fmt.Sprintf("num-tag-%d", i)
+		numTags[name] = &Tag{
+			Name:  name,
+			Unit:  "mb",
+			Value: 16,
+			Flat:  10,
+			Cum:   10,
+		}
+	}
+	node1 := &Node{
+		Info:        NodeInfo{Name: "node1-with-tags"},
+		Flat:        10,
+		Cum:         10,
+		NumericTags: map[string]TagMap{"": numTags},
+		LabelTags:   labelTags,
+	}
+	node2 := &Node{
+		Info: NodeInfo{Name: "node2"},
+		Flat: 15,
+		Cum:  15,
+	}
+	node3 := &Node{
+		Info: NodeInfo{Name: "node3"},
+		Flat: 15,
+		Cum:  15,
+	}
+	g := &Graph{
+		Nodes: Nodes{
+			node1,
+			node2,
+			node3,
+		},
+	}
+	for n := 1; n <= 3; n++ {
+		input := maxNodelets + n
+		if got, want := len(g.SelectTopNodes(input, true)), n; got != want {
+			t.Errorf("SelectTopNodes(%d): got %d nodes, want %d", input, got, want)
+		}
 	}
 }
 
@@ -240,19 +293,19 @@
 	}
 
 	tagWant := [][]*Tag{
-		[]*Tag{
+		{
 			makeTag("1B..2GB", "", 0, 2401, 2401),
 		},
-		[]*Tag{
+		{
 			makeTag("2GB", "", 0, 1000, 1000),
 			makeTag("1B..12MB", "", 0, 1401, 1401),
 		},
-		[]*Tag{
+		{
 			makeTag("2GB", "", 0, 1000, 1000),
 			makeTag("12MB", "", 0, 100, 100),
 			makeTag("1B..1MB", "", 0, 1301, 1301),
 		},
-		[]*Tag{
+		{
 			makeTag("2GB", "", 0, 1000, 1000),
 			makeTag("1MB", "", 0, 1000, 1000),
 			makeTag("2B..1kB", "", 0, 201, 201),
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go
index 428e625..cd72bf2 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go
@@ -240,6 +240,8 @@
 	Inline bool
 }
 
+// WeightValue returns the weight value for this edge, normalizing if a
+// divisor is available.
 func (e *Edge) WeightValue() int64 {
 	if e.WeightDiv == 0 {
 		return e.Weight
@@ -327,7 +329,7 @@
 				// Add cum weight to all nodes in stack, avoiding double counting.
 				if _, ok := seenNode[n]; !ok {
 					seenNode[n] = true
-					n.addSample(dw, w, labels, sample.NumLabel, o.FormatTag, false)
+					n.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, false)
 				}
 				// Update edge weights for all edges in stack, avoiding double counting.
 				if _, ok := seenEdge[nodePair{n, parent}]; !ok && parent != nil && n != parent {
@@ -340,7 +342,7 @@
 		}
 		if parent != nil && !residual {
 			// Add flat weight to leaf node.
-			parent.addSample(dw, w, labels, sample.NumLabel, o.FormatTag, true)
+			parent.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, true)
 		}
 	}
 
@@ -399,7 +401,7 @@
 				if n == nil {
 					continue
 				}
-				n.addSample(dw, w, labels, sample.NumLabel, o.FormatTag, false)
+				n.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, false)
 				if parent != nil {
 					parent.AddToEdgeDiv(n, dw, w, false, lidx != len(lines)-1)
 				}
@@ -407,7 +409,7 @@
 			}
 		}
 		if parent != nil {
-			parent.addSample(dw, w, labels, sample.NumLabel, o.FormatTag, true)
+			parent.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, true)
 		}
 	}
 
@@ -600,7 +602,7 @@
 	return
 }
 
-func (n *Node) addSample(dw, w int64, labels string, numLabel map[string][]int64, format func(int64, string) string, flat bool) {
+func (n *Node) addSample(dw, w int64, labels string, numLabel map[string][]int64, numUnit map[string][]string, format func(int64, string) string, flat bool) {
 	// Update sample value
 	if flat {
 		n.FlatDiv += dw
@@ -631,9 +633,15 @@
 	if format == nil {
 		format = defaultLabelFormat
 	}
-	for key, nvals := range numLabel {
-		for _, v := range nvals {
-			t := numericTags.findOrAddTag(format(v, key), key, v)
+	for k, nvals := range numLabel {
+		units := numUnit[k]
+		for i, v := range nvals {
+			var t *Tag
+			if len(units) > 0 {
+				t = numericTags.findOrAddTag(format(v, units[i]), units[i], v)
+			} else {
+				t = numericTags.findOrAddTag(format(v, k), k, v)
+			}
 			if flat {
 				t.FlatDiv += dw
 				t.Flat += w
@@ -800,7 +808,11 @@
 			// If generating a visual graph, count tags as nodes. Update
 			// maxNodes to account for them.
 			for i, n := range g.Nodes {
-				if count += countTags(n) + 1; count >= maxNodes {
+				tags := countTags(n)
+				if tags > maxNodelets {
+					tags = maxNodelets
+				}
+				if count += tags + 1; count >= maxNodes {
 					maxNodes = i + 1
 					break
 				}
@@ -832,17 +844,6 @@
 	return count
 }
 
-// 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
-}
-
 // RemoveRedundantEdges removes residual edges if the destination can
 // be reached through another path. This is done to simplify the graph
 // while preserving connectivity.
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go
index c2848f8..5657084 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go
@@ -171,7 +171,7 @@
 	}
 }
 
-// createTestCase1 creates a test case that initally looks like:
+// createTestCase1 creates a test case that initially looks like:
 //     0
 //     |(5)
 //     1
@@ -255,7 +255,7 @@
 	}
 }
 
-// createTestCase3 creates an initally empty graph and expects an empty graph
+// createTestCase3 creates an initially empty graph and expects an empty graph
 // after trimming.
 func createTestCase3() trimTreeTestcase {
 	graph := &Graph{make(Nodes, 0)}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot
index ceed025..da349a4 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot
@@ -1,7 +1,7 @@
 digraph "testtitle" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l"] }
-N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
-N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
+N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
+N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
 N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot
index ee951fe..0c1a6eb 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot
@@ -1,7 +1,7 @@
 digraph "testtitle" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l"] }
-N1 [label="SRC10 (10.00%)\nof 25 (25.00%)" fontsize=24 shape=folder tooltip="src (25)" color="#b23c00" fillcolor="#edddd5" style="bold,filled" peripheries=2 URL="www.google.com" target="_blank"]
-N2 [label="dest\n0 of 25 (25.00%)" fontsize=8 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
+N1 [label="SRC10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=24 shape=folder tooltip="src (25)" color="#b23c00" fillcolor="#edddd5" style="bold,filled" peripheries=2 URL="www.google.com" target="_blank"]
+N2 [label="dest\n0 of 25 (25.00%)" id="node2" fontsize=8 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
 N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot
index 99a3119..1b878b7 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot
@@ -1,11 +1,11 @@
 digraph "testtitle" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l"] }
-N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
-N1_0 [label = "tag1" fontsize=8 shape=box3d tooltip="10"]
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
+N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
+N1_0 [label = "tag1" id="N1_0" fontsize=8 shape=box3d tooltip="10"]
 N1 -> N1_0 [label=" 10" weight=100 tooltip="10" labeltooltip="10"]
-NN1_0 [label = "tag2" fontsize=8 shape=box3d tooltip="20"]
+NN1_0 [label = "tag2" id="NN1_0" fontsize=8 shape=box3d tooltip="20"]
 N1 -> NN1_0 [label=" 20" weight=100 tooltip="20" labeltooltip="20"]
-N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
+N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
 N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src ... dest (10)" labeltooltip="src ... dest (10)" style="dotted" minlen=2]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot
index adc9cc6..302da8c 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot
@@ -1,4 +1,4 @@
 digraph "testtitle" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l"] }
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot
index 352975f..8876e33 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot
@@ -1,11 +1,11 @@
 digraph "testtitle" {
 node [style=filled fillcolor="#f8f8f8"]
-subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l"] }
-N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
-N1_0 [label = "tag1" fontsize=8 shape=box3d tooltip="10"]
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
+N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
+N1_0 [label = "tag1" id="N1_0" fontsize=8 shape=box3d tooltip="10"]
 N1 -> N1_0 [label=" 10" weight=100 tooltip="10" labeltooltip="10"]
-NN1_0_0 [label = "tag2" fontsize=8 shape=box3d tooltip="20"]
+NN1_0_0 [label = "tag2" id="NN1_0_0" fontsize=8 shape=box3d tooltip="20"]
 N1_0 -> NN1_0_0 [label=" 20" weight=100 tooltip="20" labeltooltip="20"]
-N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
+N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
 N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)" minlen=2]
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose6.dot b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose6.dot
new file mode 100644
index 0000000..cf88439
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose6.dot
@@ -0,0 +1,7 @@
+digraph "testtitle" {
+node [style=filled fillcolor="#f8f8f8"]
+subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" URL="http://example.com" target="_blank" tooltip="testtitle"] }
+N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
+N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
+N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go
index 0f7a21d..0a60435 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go
@@ -170,12 +170,16 @@
 
 	switch fromUnit {
 	case "byte", "b":
-	case "kilobyte", "kb":
+	case "kb", "kbyte", "kilobyte":
 		value *= 1024
-	case "megabyte", "mb":
+	case "mb", "mbyte", "megabyte":
 		value *= 1024 * 1024
-	case "gigabyte", "gb":
+	case "gb", "gbyte", "gigabyte":
 		value *= 1024 * 1024 * 1024
+	case "tb", "tbyte", "terabyte":
+		value *= 1024 * 1024 * 1024 * 1024
+	case "pb", "pbyte", "petabyte":
+		value *= 1024 * 1024 * 1024 * 1024 * 1024
 	default:
 		return 0, "", false
 	}
@@ -188,8 +192,12 @@
 			toUnit = "kb"
 		case value < 1024*1024*1024:
 			toUnit = "mb"
-		default:
+		case value < 1024*1024*1024*1024:
 			toUnit = "gb"
+		case value < 1024*1024*1024*1024*1024:
+			toUnit = "tb"
+		default:
+			toUnit = "pb"
 		}
 	}
 
@@ -203,6 +211,10 @@
 		output, toUnit = float64(value)/(1024*1024), "MB"
 	case "gb", "gbyte", "gigabyte":
 		output, toUnit = float64(value)/(1024*1024*1024), "GB"
+	case "tb", "tbyte", "terabyte":
+		output, toUnit = float64(value)/(1024*1024*1024*1024), "TB"
+	case "pb", "pbyte", "petabyte":
+		output, toUnit = float64(value)/(1024*1024*1024*1024*1024), "PB"
 	}
 	return output, toUnit, true
 }
@@ -289,7 +301,7 @@
 	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"
+		output, toUnit = dd/float64(365*24*time.Hour), "yrs"
 	default:
 		fallthrough
 	case "sec", "second", "s":
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement_test.go b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement_test.go
new file mode 100644
index 0000000..155cafa
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement_test.go
@@ -0,0 +1,47 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package measurement
+
+import (
+	"testing"
+)
+
+func TestScale(t *testing.T) {
+	for _, tc := range []struct {
+		value            int64
+		fromUnit, toUnit string
+		wantValue        float64
+		wantUnit         string
+	}{
+		{1, "s", "ms", 1000, "ms"},
+		{1, "kb", "b", 1024, "B"},
+		{1, "kbyte", "b", 1024, "B"},
+		{1, "kilobyte", "b", 1024, "B"},
+		{1, "mb", "kb", 1024, "kB"},
+		{1, "gb", "mb", 1024, "MB"},
+		{1024, "gb", "tb", 1, "TB"},
+		{1024, "tb", "pb", 1, "PB"},
+		{2048, "mb", "auto", 2, "GB"},
+		{3.1536e7, "s", "auto", 1, "yrs"},
+		{-1, "s", "ms", -1000, "ms"},
+		{1, "foo", "count", 1, ""},
+		{1, "foo", "bar", 1, "bar"},
+	} {
+		if gotValue, gotUnit := Scale(tc.value, tc.fromUnit, tc.toUnit); gotValue != tc.wantValue || gotUnit != tc.wantUnit {
+			t.Errorf("Scale(%d, %q, %q) = (%f, %q), want (%f, %q)",
+				tc.value, tc.fromUnit, tc.toUnit, gotValue, gotUnit, tc.wantValue, tc.wantUnit)
+		}
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
index d14ac2c..e5878ae 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
@@ -17,6 +17,7 @@
 
 import (
 	"io"
+	"net/http"
 	"regexp"
 	"time"
 
@@ -31,6 +32,16 @@
 	Sym     Symbolizer
 	Obj     ObjTool
 	UI      UI
+
+	// HTTPServer is a function that should block serving http requests,
+	// including the handlers specfied in args.  If non-nil, pprof will
+	// invoke this function if necessary to provide a web interface.
+	//
+	// If HTTPServer is nil, pprof will use its own internal HTTP server.
+	//
+	// A common use for a custom HTTPServer is to provide custom
+	// authentication checks.
+	HTTPServer func(args *HTTPServerArgs) error
 }
 
 // Writer provides a mechanism to write data under a certain name,
@@ -185,3 +196,17 @@
 	// the auto-completion of cmd, if the UI supports auto-completion at all.
 	SetAutoComplete(complete func(string) string)
 }
+
+// HTTPServerArgs contains arguments needed by an HTTP server that
+// is exporting a pprof web interface.
+type HTTPServerArgs struct {
+	// Hostport contains the http server address (derived from flags).
+	Hostport string
+
+	Host string // Host portion of Hostport
+	Port int    // Port portion of Hostport
+
+	// Handlers maps from URL paths to the handler to invoke to
+	// serve that path.
+	Handlers map[string]http.Handler
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go b/src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go
index 9767b2e..7f9dcab 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go
@@ -22,6 +22,7 @@
 	"io/ioutil"
 	"os"
 	"os/exec"
+	"regexp"
 	"testing"
 )
 
@@ -71,10 +72,14 @@
 }
 
 // TestUI implements the plugin.UI interface, triggering test failures
-// if more than Ignore errors are printed.
+// if more than Ignore errors not matching AllowRx are printed.
+// Also tracks the number of times the error matches AllowRx in
+// NumAllowRxMatches.
 type TestUI struct {
-	T      *testing.T
-	Ignore int
+	T                 *testing.T
+	Ignore            int
+	AllowRx           string
+	NumAllowRxMatches int
 }
 
 // ReadLine returns no input, as no input is expected during testing.
@@ -89,11 +94,24 @@
 // PrintErr messages may trigger an error failure. A fixed number of
 // error messages are permitted when appropriate.
 func (ui *TestUI) PrintErr(args ...interface{}) {
+	if ui.AllowRx != "" {
+		if matched, err := regexp.MatchString(ui.AllowRx, fmt.Sprint(args...)); matched || err != nil {
+			if err != nil {
+				ui.T.Errorf("failed to match against regex %q: %v", ui.AllowRx, err)
+			}
+			ui.NumAllowRxMatches++
+			return
+		}
+	}
 	if ui.Ignore > 0 {
 		ui.Ignore--
 		return
 	}
-	ui.T.Error(args)
+	// Stringify arguments with fmt.Sprint() to match what default UI
+	// implementation does. Without this Error() calls fmt.Sprintln() which
+	// _always_ adds spaces between arguments, unlike fmt.Sprint() which only
+	// adds them between arguments if neither is string.
+	ui.T.Error(fmt.Sprint(args...))
 }
 
 // IsTerminal indicates if the UI is an interactive terminal.
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
index ecfd698..f434554 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
@@ -25,6 +25,7 @@
 	"sort"
 	"strconv"
 	"strings"
+	"text/tabwriter"
 	"time"
 
 	"github.com/google/pprof/internal/graph"
@@ -63,6 +64,8 @@
 	Ratio               float64
 	Title               string
 	ProfileLabels       []string
+	ActiveFilters       []string
+	NumLabelUnits       map[string]string
 
 	NodeCount    int
 	NodeFraction float64
@@ -125,6 +128,9 @@
 	visualMode := o.OutputFormat == Dot
 	cumSort := o.CumSort
 
+	// The call_tree option is only honored when generating visual representations of the callgraph.
+	callTree := o.CallTree && (o.OutputFormat == Dot || o.OutputFormat == Callgrind)
+
 	// First step: Build complete graph to identify low frequency nodes, based on their cum weight.
 	g = rpt.newGraph(nil)
 	totalValue, _ := g.Nodes.Sum()
@@ -133,7 +139,7 @@
 
 	// Filter out nodes with cum value below nodeCutoff.
 	if nodeCutoff > 0 {
-		if o.CallTree {
+		if callTree {
 			if nodesKept := g.DiscardLowFrequencyNodePtrs(nodeCutoff); len(g.Nodes) != len(nodesKept) {
 				droppedNodes = len(g.Nodes) - len(nodesKept)
 				g.TrimTree(nodesKept)
@@ -154,7 +160,7 @@
 		// Remove low frequency tags and edges as they affect selection.
 		g.TrimLowFrequencyTags(nodeCutoff)
 		g.TrimLowFrequencyEdges(edgeCutoff)
-		if o.CallTree {
+		if callTree {
 			if nodesKept := g.SelectTopNodePtrs(nodeCount, visualMode); len(g.Nodes) != len(nodesKept) {
 				g.TrimTree(nodesKept)
 				g.SortNodes(cumSort, visualMode)
@@ -236,15 +242,27 @@
 	for _, f := range prof.Function {
 		f.Filename = trimPath(f.Filename)
 	}
-	// Remove numeric tags not recognized by pprof.
+	// Removes all numeric tags except for the bytes tag prior
+	// to making graph.
+	// TODO: modify to select first numeric tag if no bytes tag
 	for _, s := range prof.Sample {
 		numLabels := make(map[string][]int64, len(s.NumLabel))
-		for k, v := range s.NumLabel {
+		numUnits := make(map[string][]string, len(s.NumLabel))
+		for k, vs := range s.NumLabel {
 			if k == "bytes" {
-				numLabels[k] = append(numLabels[k], v...)
+				unit := o.NumLabelUnits[k]
+				numValues := make([]int64, len(vs))
+				numUnit := make([]string, len(vs))
+				for i, v := range vs {
+					numValues[i] = v
+					numUnit[i] = unit
+				}
+				numLabels[k] = append(numLabels[k], numValues...)
+				numUnits[k] = append(numUnits[k], numUnit...)
 			}
 		}
 		s.NumLabel = numLabels
+		s.NumUnit = numUnits
 	}
 
 	formatTag := func(v int64, key string) string {
@@ -337,6 +355,11 @@
 
 // printAssembly prints an annotated assembly listing.
 func printAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
+	return PrintAssembly(w, rpt, obj, -1)
+}
+
+// PrintAssembly prints annotated disasssembly of rpt to w.
+func PrintAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFuncs int) error {
 	o := rpt.options
 	prof := rpt.prof
 
@@ -352,12 +375,34 @@
 	fmt.Fprintln(w, "Total:", rpt.formatValue(rpt.total))
 	symbols := symbolsFromBinaries(prof, g, o.Symbol, address, obj)
 	symNodes := nodesPerSymbol(g.Nodes, symbols)
-	// Sort function names for printing.
-	var syms objSymbols
+
+	// Sort for printing.
+	var syms []*objSymbol
 	for s := range symNodes {
 		syms = append(syms, s)
 	}
-	sort.Sort(syms)
+	byName := func(a, b *objSymbol) bool {
+		if na, nb := a.sym.Name[0], b.sym.Name[0]; na != nb {
+			return na < nb
+		}
+		return a.sym.Start < b.sym.Start
+	}
+	if maxFuncs < 0 {
+		sort.Sort(orderSyms{syms, byName})
+	} else {
+		byFlatSum := func(a, b *objSymbol) bool {
+			suma, _ := symNodes[a].Sum()
+			sumb, _ := symNodes[b].Sum()
+			if suma != sumb {
+				return suma > sumb
+			}
+			return byName(a, b)
+		}
+		sort.Sort(orderSyms{syms, byFlatSum})
+		if len(syms) > maxFuncs {
+			syms = syms[:maxFuncs]
+		}
+	}
 
 	// Correlate the symbols from the binary with the profile samples.
 	for _, s := range syms {
@@ -471,6 +516,7 @@
 				&objSymbol{
 					sym:  ms,
 					base: base,
+					file: f,
 				},
 			)
 		}
@@ -485,25 +531,18 @@
 type objSymbol struct {
 	sym  *plugin.Sym
 	base uint64
+	file plugin.ObjFile
 }
 
-// objSymbols is a wrapper type to enable sorting of []*objSymbol.
-type objSymbols []*objSymbol
-
-func (o objSymbols) Len() int {
-	return len(o)
+// orderSyms is a wrapper type to sort []*objSymbol by a supplied comparator.
+type orderSyms struct {
+	v    []*objSymbol
+	less func(a, b *objSymbol) bool
 }
 
-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]
-}
+func (o orderSyms) Len() int           { return len(o.v) }
+func (o orderSyms) Less(i, j int) bool { return o.less(o.v[i], o.v[j]) }
+func (o orderSyms) Swap(i, j int)      { o.v[i], o.v[j] = o.v[j], o.v[i] }
 
 // nodesPerSymbol classifies nodes into a group of symbols.
 func nodesPerSymbol(ns graph.Nodes, symbols []*objSymbol) map[*objSymbol]graph.Nodes {
@@ -528,6 +567,13 @@
 	line            int
 	flat, cum       int64
 	flatDiv, cumDiv int64
+	startsBlock     bool
+	inlineCalls     []callID
+}
+
+type callID struct {
+	file string
+	line int
 }
 
 func (a *assemblyInstruction) flatValue() int64 {
@@ -617,25 +663,24 @@
 	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, ok := tagMap[key]
+				if !ok {
+					valueMap = make(map[string]int64)
+					tagMap[key] = valueMap
 				}
-				valueMap := make(map[string]int64)
-				valueMap[val] = s.Value[0]
-				tagMap[key] = valueMap
+				valueMap[val] += o.SampleValue(s.Value)
 			}
 		}
 		for key, vals := range s.NumLabel {
+			unit := o.NumLabelUnits[key]
 			for _, nval := range vals {
-				val := formatTag(nval, key)
-				if valueMap, ok := tagMap[key]; ok {
-					valueMap[val] = valueMap[val] + s.Value[0]
-					continue
+				val := formatTag(nval, unit)
+				valueMap, ok := tagMap[key]
+				if !ok {
+					valueMap = make(map[string]int64)
+					tagMap[key] = valueMap
 				}
-				valueMap := make(map[string]int64)
-				valueMap[val] = s.Value[0]
-				tagMap[key] = valueMap
+				valueMap[val] += o.SampleValue(s.Value)
 			}
 		}
 	}
@@ -644,6 +689,7 @@
 	for key := range tagMap {
 		tagKeys = append(tagKeys, &graph.Tag{Name: key})
 	}
+	tabw := tabwriter.NewWriter(w, 0, 0, 1, ' ', tabwriter.AlignRight)
 	for _, tagKey := range graph.SortTags(tagKeys, true) {
 		var total int64
 		key := tagKey.Name
@@ -653,18 +699,19 @@
 			tags = append(tags, &graph.Tag{Name: t, Flat: c})
 		}
 
-		fmt.Fprintf(w, "%s: Total %d\n", key, total)
+		f, u := measurement.Scale(total, o.SampleUnit, o.OutputUnit)
+		fmt.Fprintf(tabw, "%s:\t Total %.1f%s\n", key, f, u)
 		for _, t := range graph.SortTags(tags, true) {
+			f, u := measurement.Scale(t.FlatValue(), o.SampleUnit, o.OutputUnit)
 			if total > 0 {
-				fmt.Fprintf(w, "  %8d (%s): %s\n", t.FlatValue(),
-					percentage(t.FlatValue(), total), t.Name)
+				fmt.Fprintf(tabw, " \t%.1f%s (%s):\t %s\n", f, u, percentage(t.FlatValue(), total), t.Name)
 			} else {
-				fmt.Fprintf(w, "  %8d: %s\n", t.FlatValue(), t.Name)
+				fmt.Fprintf(tabw, " \t%.1f%s:\t %s\n", f, u, t.Name)
 			}
 		}
-		fmt.Fprintln(w)
+		fmt.Fprintln(tabw)
 	}
-	return nil
+	return tabw.Flush()
 }
 
 // printComments prints all freeform comments in the profile.
@@ -677,16 +724,22 @@
 	return nil
 }
 
-// printText prints a flat text report for a profile.
-func printText(w io.Writer, rpt *Report) error {
+// TextItem holds a single text report entry.
+type TextItem struct {
+	Name                  string
+	InlineLabel           string // Not empty if inlined
+	Flat, Cum             int64  // Raw values
+	FlatFormat, CumFormat string // Formatted values
+}
+
+// TextItems returns a list of text items from the report and a list
+// of labels that describe the report.
+func TextItems(rpt *Report) ([]TextItem, []string) {
 	g, origCount, droppedNodes, _ := rpt.newTrimmedGraph()
 	rpt.selectOutputUnit(g)
+	labels := reportLabels(rpt, g, origCount, droppedNodes, 0, false)
 
-	fmt.Fprintln(w, strings.Join(reportLabels(rpt, g, origCount, droppedNodes, 0, false), "\n"))
-
-	fmt.Fprintf(w, "%10s %5s%% %5s%% %10s %5s%%\n",
-		"flat", "flat", "sum", "cum", "cum")
-
+	var items []TextItem
 	var flatSum int64
 	for _, n := range g.Nodes {
 		name, flat, cum := n.Info.PrintableName(), n.FlatValue(), n.CumValue()
@@ -700,22 +753,46 @@
 			}
 		}
 
+		var inl string
 		if inline {
 			if noinline {
-				name = name + " (partial-inline)"
+				inl = "(partial-inline)"
 			} else {
-				name = name + " (inline)"
+				inl = "(inline)"
 			}
 		}
 
 		flatSum += flat
-		fmt.Fprintf(w, "%10s %s %s %10s %s  %s\n",
-			rpt.formatValue(flat),
-			percentage(flat, rpt.total),
+		items = append(items, TextItem{
+			Name:        name,
+			InlineLabel: inl,
+			Flat:        flat,
+			Cum:         cum,
+			FlatFormat:  rpt.formatValue(flat),
+			CumFormat:   rpt.formatValue(cum),
+		})
+	}
+	return items, labels
+}
+
+// printText prints a flat text report for a profile.
+func printText(w io.Writer, rpt *Report) error {
+	items, labels := TextItems(rpt)
+	fmt.Fprintln(w, strings.Join(labels, "\n"))
+	fmt.Fprintf(w, "%10s %5s%% %5s%% %10s %5s%%\n",
+		"flat", "flat", "sum", "cum", "cum")
+	var flatSum int64
+	for _, item := range items {
+		inl := item.InlineLabel
+		if inl != "" {
+			inl = " " + inl
+		}
+		flatSum += item.Flat
+		fmt.Fprintf(w, "%10s %s %s %10s %s  %s%s\n",
+			item.FlatFormat, percentage(item.Flat, rpt.total),
 			percentage(flatSum, rpt.total),
-			rpt.formatValue(cum),
-			percentage(cum, rpt.total),
-			name)
+			item.CumFormat, percentage(item.Cum, rpt.total),
+			item.Name, inl)
 	}
 	return nil
 }
@@ -749,6 +826,20 @@
 		}
 		sort.Strings(labels)
 		fmt.Fprint(w, strings.Join(labels, ""))
+
+		// Print any numeric labels for the sample
+		var numLabels []string
+		for key, vals := range sample.NumLabel {
+			unit := o.NumLabelUnits[key]
+			numValues := make([]string, len(vals))
+			for i, vv := range vals {
+				numValues[i] = measurement.Label(vv, unit)
+			}
+			numLabels = append(numLabels, fmt.Sprintf("%10s:  %s\n", key, strings.Join(numValues, " ")))
+		}
+		sort.Strings(numLabels)
+		fmt.Fprint(w, strings.Join(numLabels, ""))
+
 		var d, v int64
 		v = o.SampleValue(sample.Value)
 		if o.SampleMeanDivisor != nil {
@@ -969,24 +1060,25 @@
 	return nil
 }
 
-// printDOT prints an annotated callgraph in DOT format.
-func printDOT(w io.Writer, rpt *Report) error {
+// GetDOT returns a graph suitable for dot processing along with some
+// configuration information.
+func GetDOT(rpt *Report) (*graph.Graph, *graph.DotConfig) {
 	g, origCount, droppedNodes, droppedEdges := rpt.newTrimmedGraph()
 	rpt.selectOutputUnit(g)
 	labels := reportLabels(rpt, g, origCount, droppedNodes, droppedEdges, true)
 
-	o := rpt.options
-	formatTag := func(v int64, key string) string {
-		return measurement.ScaledLabel(v, key, o.OutputUnit)
-	}
-
 	c := &graph.DotConfig{
 		Title:       rpt.options.Title,
 		Labels:      labels,
 		FormatValue: rpt.formatValue,
-		FormatTag:   formatTag,
 		Total:       rpt.total,
 	}
+	return g, c
+}
+
+// printDOT prints an annotated callgraph in DOT format.
+func printDOT(w io.Writer, rpt *Report) error {
+	g, c := GetDOT(rpt)
 	graph.ComposeDot(w, g, &graph.DotAttributes{}, c)
 	return nil
 }
@@ -1055,9 +1147,7 @@
 
 	var label []string
 	if len(rpt.options.ProfileLabels) > 0 {
-		for _, l := range rpt.options.ProfileLabels {
-			label = append(label, l)
-		}
+		label = append(label, rpt.options.ProfileLabels...)
 	} else if fullHeaders || !rpt.options.CompactLabels {
 		label = ProfileLabels(rpt)
 	}
@@ -1067,6 +1157,11 @@
 		flatSum = flatSum + n.FlatValue()
 	}
 
+	if len(rpt.options.ActiveFilters) > 0 {
+		activeFilters := legendActiveFilters(rpt.options.ActiveFilters)
+		label = append(label, activeFilters...)
+	}
+
 	label = append(label, fmt.Sprintf("Showing nodes accounting for %s, %s of %s total", rpt.formatValue(flatSum), strings.TrimSpace(percentage(flatSum, rpt.total)), rpt.formatValue(rpt.total)))
 
 	if rpt.total != 0 {
@@ -1086,6 +1181,18 @@
 	return label
 }
 
+func legendActiveFilters(activeFilters []string) []string {
+	legendActiveFilters := make([]string, len(activeFilters)+1)
+	legendActiveFilters[0] = "Active filters:"
+	for i, s := range activeFilters {
+		if len(s) > 80 {
+			s = s[:80] + "…"
+		}
+		legendActiveFilters[i+1] = "   " + s
+	}
+	return legendActiveFilters
+}
+
 func genLabel(d int, n, l, f string) string {
 	if d > 1 {
 		n = n + "s"
@@ -1159,6 +1266,9 @@
 	formatValue func(int64) string
 }
 
+// Total returns the total number of samples in a report.
+func (rpt *Report) Total() int64 { return rpt.total }
+
 func abs64(i int64) int64 {
 	if i < 0 {
 		return -i
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go
index 28cf6b4..e05cf5a 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go
@@ -264,3 +264,24 @@
 		}
 	}
 }
+
+func TestLegendActiveFilters(t *testing.T) {
+	activeFilterInput := []string{
+		"focus=123|456|789|101112|131415|161718|192021|222324|252627|282930|313233|343536|363738|acbdefghijklmnop",
+		"show=short filter",
+	}
+	expectedLegendActiveFilter := []string{
+		"Active filters:",
+		"   focus=123|456|789|101112|131415|161718|192021|222324|252627|282930|313233|343536…",
+		"   show=short filter",
+	}
+	legendActiveFilter := legendActiveFilters(activeFilterInput)
+	if len(legendActiveFilter) != len(expectedLegendActiveFilter) {
+		t.Errorf("wanted length %v got length %v", len(expectedLegendActiveFilter), len(legendActiveFilter))
+	}
+	for i := range legendActiveFilter {
+		if legendActiveFilter[i] != expectedLegendActiveFilter[i] {
+			t.Errorf("%d: want \"%v\", got \"%v\"", i, expectedLegendActiveFilter[i], legendActiveFilter[i])
+		}
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
index f5e3b6b..ce82ae5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
@@ -62,6 +62,7 @@
 		}
 		sourcePath = wd
 	}
+	reader := newSourceReader(sourcePath)
 
 	fmt.Fprintf(w, "Total: %s\n", rpt.formatValue(rpt.total))
 	for _, fn := range functions {
@@ -94,7 +95,7 @@
 			fns := fileNodes[filename]
 			flatSum, cumSum := fns.Sum()
 
-			fnodes, _, err := getSourceFromFile(filename, sourcePath, fns, 0, 0)
+			fnodes, _, err := getSourceFromFile(filename, reader, fns, 0, 0)
 			fmt.Fprintf(w, "ROUTINE ======================== %s in %s\n", name, filename)
 			fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
 				rpt.formatValue(flatSum), rpt.formatValue(cumSum),
@@ -116,6 +117,16 @@
 // 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 {
+	printHeader(w, rpt)
+	if err := PrintWebList(w, rpt, obj, -1); err != nil {
+		return err
+	}
+	printPageClosing(w)
+	return nil
+}
+
+// PrintWebList prints annotated source listing of rpt to w.
+func PrintWebList(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFiles int) error {
 	o := rpt.options
 	g := rpt.newGraph(nil)
 
@@ -134,6 +145,7 @@
 		}
 		sourcePath = wd
 	}
+	reader := newSourceReader(sourcePath)
 
 	type fileFunction struct {
 		fileName, functionName string
@@ -167,7 +179,7 @@
 	}
 
 	if len(fileNodes) == 0 {
-		return fmt.Errorf("No source information for %s\n", o.Symbol.String())
+		return fmt.Errorf("No source information for %s", o.Symbol.String())
 	}
 
 	sourceFiles := make(graph.Nodes, 0, len(fileNodes))
@@ -176,10 +188,18 @@
 		sNode.Flat, sNode.Cum = nodes.Sum()
 		sourceFiles = append(sourceFiles, &sNode)
 	}
-	sourceFiles.Sort(graph.FileOrder)
+
+	// Limit number of files printed?
+	if maxFiles < 0 {
+		sourceFiles.Sort(graph.FileOrder)
+	} else {
+		sourceFiles.Sort(graph.FlatNameOrder)
+		if maxFiles < len(sourceFiles) {
+			sourceFiles = sourceFiles[:maxFiles]
+		}
+	}
 
 	// Print each file associated with this function.
-	printHeader(w, rpt)
 	for _, n := range sourceFiles {
 		ff := fileFunction{n.Info.File, n.Info.Name}
 		fns := fileNodes[ff]
@@ -187,18 +207,17 @@
 		asm := assemblyPerSourceLine(symbols, fns, ff.fileName, obj)
 		start, end := sourceCoordinates(asm)
 
-		fnodes, path, err := getSourceFromFile(ff.fileName, sourcePath, fns, start, end)
+		fnodes, path, err := getSourceFromFile(ff.fileName, reader, fns, start, end)
 		if err != nil {
 			fnodes, path = getMissingFunctionSource(ff.fileName, asm, start, end)
 		}
 
 		printFunctionHeader(w, ff.functionName, path, n.Flat, n.Cum, rpt)
 		for _, fn := range fnodes {
-			printFunctionSourceLine(w, fn, asm[fn.Info.Lineno], rpt)
+			printFunctionSourceLine(w, fn, asm[fn.Info.Lineno], reader, rpt)
 		}
 		printFunctionClosing(w)
 	}
-	printPageClosing(w)
 	return nil
 }
 
@@ -236,11 +255,41 @@
 	srcBase := filepath.Base(src)
 	anodes := annotateAssembly(insts, rs, o.base)
 	var lineno = 0
+	var prevline = 0
 	for _, an := range anodes {
-		if filepath.Base(an.file) == srcBase {
+		// Do not rely solely on the line number produced by Disasm
+		// since it is not what we want in the presence of inlining.
+		//
+		// E.g., suppose we are printing source code for F and this
+		// instruction is from H where F called G called H and both
+		// of those calls were inlined.  We want to use the line
+		// number from F, not from H (which is what Disasm gives us).
+		//
+		// So find the outer-most linenumber in the source file.
+		found := false
+		if frames, err := o.file.SourceLine(an.address + o.base); err == nil {
+			for i := len(frames) - 1; i >= 0; i-- {
+				if filepath.Base(frames[i].File) == srcBase {
+					for j := i - 1; j >= 0; j-- {
+						an.inlineCalls = append(an.inlineCalls, callID{frames[j].File, frames[j].Line})
+					}
+					lineno = frames[i].Line
+					found = true
+					break
+				}
+			}
+		}
+		if !found && filepath.Base(an.file) == srcBase {
 			lineno = an.line
 		}
+
 		if lineno != 0 {
+			if lineno != prevline {
+				// This instruction starts a new block
+				// of contiguous instructions on this line.
+				an.startsBlock = true
+			}
+			prevline = lineno
 			assembly[lineno] = append(assembly[lineno], an)
 		}
 	}
@@ -265,7 +314,15 @@
 
 // printHeader prints the page header for a weblist report.
 func printHeader(w io.Writer, rpt *Report) {
-	fmt.Fprintln(w, weblistPageHeader)
+	fmt.Fprintln(w, `
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Pprof listing</title>`)
+	fmt.Fprintln(w, weblistPageCSS)
+	fmt.Fprintln(w, weblistPageScript)
+	fmt.Fprint(w, "</head>\n<body>\n\n")
 
 	var labels []string
 	for _, l := range ProfileLabels(rpt) {
@@ -290,30 +347,33 @@
 }
 
 // printFunctionSourceLine prints a source line and the corresponding assembly.
-func printFunctionSourceLine(w io.Writer, fn *graph.Node, assembly []assemblyInstruction, rpt *Report) {
+func printFunctionSourceLine(w io.Writer, fn *graph.Node, assembly []assemblyInstruction, reader *sourceReader, rpt *Report) {
 	if len(assembly) == 0 {
 		fmt.Fprintf(w,
-			"<span class=line> %6d</span> <span class=nop>  %10s %10s %s </span>\n",
+			"<span class=line> %6d</span> <span class=nop>  %10s %10s %8s  %s </span>\n",
 			fn.Info.Lineno,
 			valueOrDot(fn.Flat, rpt), valueOrDot(fn.Cum, rpt),
-			template.HTMLEscapeString(fn.Info.Name))
+			"", template.HTMLEscapeString(fn.Info.Name))
 		return
 	}
 
 	fmt.Fprintf(w,
-		"<span class=line> %6d</span> <span class=deadsrc>  %10s %10s %s </span>",
+		"<span class=line> %6d</span> <span class=deadsrc>  %10s %10s %8s  %s </span>",
 		fn.Info.Lineno,
 		valueOrDot(fn.Flat, rpt), valueOrDot(fn.Cum, rpt),
-		template.HTMLEscapeString(fn.Info.Name))
+		"", template.HTMLEscapeString(fn.Info.Name))
+	srcIndent := indentation(fn.Info.Name)
 	fmt.Fprint(w, "<span class=asm>")
-	for _, an := range assembly {
+	var curCalls []callID
+	for i, an := range assembly {
+		if an.startsBlock && i != 0 {
+			// Insert a separator between discontiguous blocks.
+			fmt.Fprintf(w, " %8s %28s\n", "", "⋮")
+		}
+
 		var fileline string
-		class := "disasmloc"
 		if an.file != "" {
 			fileline = fmt.Sprintf("%s:%d", template.HTMLEscapeString(an.file), an.line)
-			if an.line != fn.Info.Lineno {
-				class = "unimportant"
-			}
 		}
 		flat, cum := an.flat, an.cum
 		if an.flatDiv != 0 {
@@ -322,11 +382,30 @@
 		if an.cumDiv != 0 {
 			cum = cum / an.cumDiv
 		}
-		fmt.Fprintf(w, " %8s %10s %10s %8x: %-48s <span class=%s>%s</span>\n", "",
-			valueOrDot(flat, rpt), valueOrDot(cum, rpt),
-			an.address,
-			template.HTMLEscapeString(an.instruction),
-			class,
+
+		// Print inlined call context.
+		for j, c := range an.inlineCalls {
+			if j < len(curCalls) && curCalls[j] == c {
+				// Skip if same as previous instruction.
+				continue
+			}
+			curCalls = nil
+			fname := trimPath(c.file)
+			fline, ok := reader.line(fname, c.line)
+			if !ok {
+				fline = ""
+			}
+			text := strings.Repeat(" ", srcIndent+4+4*j) + strings.TrimSpace(fline)
+			fmt.Fprintf(w, " %8s %10s %10s %8s  <span class=inlinesrc>%s</span> <span class=unimportant>%s:%d</span>\n",
+				"", "", "", "",
+				template.HTMLEscapeString(fmt.Sprintf("%-80s", text)),
+				template.HTMLEscapeString(filepath.Base(fname)), c.line)
+		}
+		curCalls = an.inlineCalls
+		text := strings.Repeat(" ", srcIndent+4+4*len(curCalls)) + an.instruction
+		fmt.Fprintf(w, " %8s %10s %10s %8x: %s <span class=unimportant>%s</span>\n",
+			"", valueOrDot(flat, rpt), valueOrDot(cum, rpt), an.address,
+			template.HTMLEscapeString(fmt.Sprintf("%-80s", text)),
 			template.HTMLEscapeString(fileline))
 	}
 	fmt.Fprintln(w, "</span>")
@@ -345,14 +424,10 @@
 // getSourceFromFile 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 getSourceFromFile(file, sourcePath string, fns graph.Nodes, start, end int) (graph.Nodes, string, error) {
+func getSourceFromFile(file string, reader *sourceReader, fns graph.Nodes, start, end int) (graph.Nodes, string, error) {
 	file = trimPath(file)
-	f, err := openSourceFile(file, sourcePath)
-	if err != nil {
-		return nil, file, err
-	}
-
 	lineNodes := make(map[int]graph.Nodes)
+
 	// Collect source coordinates from profile.
 	const margin = 5 // Lines before first/after last sample.
 	if start == 0 {
@@ -382,36 +457,28 @@
 		}
 		lineNodes[lineno] = append(lineNodes[lineno], n)
 	}
+	if start < 1 {
+		start = 1
+	}
 
 	var src graph.Nodes
-	buf := bufio.NewReader(f)
-	lineno := 1
-	for {
-		line, err := buf.ReadString('\n')
-		if err != nil {
-			if err != io.EOF {
-				return nil, file, err
-			}
-			if line == "" {
-				break
-			}
-		}
-		if lineno >= start {
-			flat, cum := lineNodes[lineno].Sum()
-
-			src = append(src, &graph.Node{
-				Info: graph.NodeInfo{
-					Name:   strings.TrimRight(line, "\n"),
-					Lineno: lineno,
-				},
-				Flat: flat,
-				Cum:  cum,
-			})
-		}
-		lineno++
-		if lineno > end {
+	for lineno := start; lineno <= end; lineno++ {
+		line, ok := reader.line(file, lineno)
+		if !ok {
 			break
 		}
+		flat, cum := lineNodes[lineno].Sum()
+		src = append(src, &graph.Node{
+			Info: graph.NodeInfo{
+				Name:   strings.TrimRight(line, "\n"),
+				Lineno: lineno,
+			},
+			Flat: flat,
+			Cum:  cum,
+		})
+	}
+	if err := reader.fileError(file); err != nil {
+		return nil, file, err
 	}
 	return src, file, nil
 }
@@ -446,6 +513,57 @@
 	return fnodes, filename
 }
 
+// sourceReader provides access to source code with caching of file contents.
+type sourceReader struct {
+	searchPath string
+
+	// files maps from path name to a list of lines.
+	// files[*][0] is unused since line numbering starts at 1.
+	files map[string][]string
+
+	// errors collects errors encountered per file.  These errors are
+	// consulted before returning out of these module.
+	errors map[string]error
+}
+
+func newSourceReader(searchPath string) *sourceReader {
+	return &sourceReader{
+		searchPath,
+		make(map[string][]string),
+		make(map[string]error),
+	}
+}
+
+func (reader *sourceReader) fileError(path string) error {
+	return reader.errors[path]
+}
+
+func (reader *sourceReader) line(path string, lineno int) (string, bool) {
+	lines, ok := reader.files[path]
+	if !ok {
+		// Read and cache file contents.
+		lines = []string{""} // Skip 0th line
+		f, err := openSourceFile(path, reader.searchPath)
+		if err != nil {
+			reader.errors[path] = err
+		} else {
+			s := bufio.NewScanner(f)
+			for s.Scan() {
+				lines = append(lines, s.Text())
+			}
+			f.Close()
+			if s.Err() != nil {
+				reader.errors[path] = err
+			}
+		}
+		reader.files[path] = lines
+	}
+	if lineno <= 0 || lineno >= len(lines) {
+		return "", false
+	}
+	return lines[lineno], true
+}
+
 // openSourceFile opens a source file from a name encoded in a
 // profile. File names in a profile after often relative paths, so
 // search them in each of the paths in searchPath (or CWD by default),
@@ -492,3 +610,20 @@
 	}
 	return path
 }
+
+func indentation(line string) int {
+	column := 0
+	for _, c := range line {
+		if c == ' ' {
+			column++
+		} else if c == '\t' {
+			column++
+			for column%8 != 0 {
+				column++
+			}
+		} else {
+			break
+		}
+	}
+	return column
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source_html.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source_html.go
index 2bb81f2..02a6d77 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/source_html.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source_html.go
@@ -14,12 +14,17 @@
 
 package report
 
-const weblistPageHeader = `
-<!DOCTYPE html>
-<html>
-<head>
-<title>Pprof listing</title>
-<style type="text/css">
+import (
+	"html/template"
+)
+
+// AddSourceTemplates adds templates used by PrintWebList to t.
+func AddSourceTemplates(t *template.Template) {
+	template.Must(t.Parse(`{{define "weblistcss"}}` + weblistPageCSS + `{{end}}`))
+	template.Must(t.Parse(`{{define "weblistjs"}}` + weblistPageScript + `{{end}}`))
+}
+
+const weblistPageCSS = `<style type="text/css">
 body {
 font-family: sans-serif;
 }
@@ -30,17 +35,11 @@
 .legend {
   font-size: 1.25em;
 }
-.line {
-color: #aaaaaa;
+.line, .nop, .unimportant {
+  color: #aaaaaa;
 }
-.nop {
-color: #aaaaaa;
-}
-.unimportant {
-color: #cccccc;
-}
-.disasmloc {
-color: #000000;
+.inlinesrc {
+  color: #000066;
 }
 .deadsrc {
 cursor: pointer;
@@ -59,8 +58,9 @@
 color: #008800;
 display: none;
 }
-</style>
-<script type="text/javascript">
+</style>`
+
+const weblistPageScript = `<script type="text/javascript">
 function pprof_toggle_asm(e) {
   var target;
   if (!e) e = window.event;
@@ -76,10 +76,7 @@
     }
   }
 }
-</script>
-</head>
-<body>
-`
+</script>`
 
 const weblistPageClosing = `
 </body>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source_test.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source_test.go
new file mode 100644
index 0000000..9a2b5a2
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source_test.go
@@ -0,0 +1,89 @@
+package report
+
+import (
+	"bytes"
+	"os"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strings"
+	"testing"
+
+	"github.com/google/pprof/internal/binutils"
+	"github.com/google/pprof/profile"
+)
+
+func TestWebList(t *testing.T) {
+	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+		t.Skip("weblist only tested on x86-64 linux")
+	}
+
+	cpu := readProfile(filepath.Join("testdata", "sample.cpu"), t)
+	rpt := New(cpu, &Options{
+		OutputFormat: WebList,
+		Symbol:       regexp.MustCompile("busyLoop"),
+		SampleValue:  func(v []int64) int64 { return v[1] },
+		SampleUnit:   cpu.SampleType[1].Unit,
+	})
+	buf := bytes.NewBuffer(nil)
+	if err := Generate(buf, rpt, &binutils.Binutils{}); err != nil {
+		t.Fatalf("could not generate weblist: %v", err)
+	}
+	output := buf.String()
+
+	for _, expect := range []string{"func busyLoop", "callq", "math.Abs"} {
+		if !strings.Contains(output, expect) {
+			t.Errorf("weblist output does not contain '%s':\n%s", expect, output)
+		}
+	}
+}
+
+func TestIndentation(t *testing.T) {
+	for _, c := range []struct {
+		str        string
+		wantIndent int
+	}{
+		{"", 0},
+		{"foobar", 0},
+		{"  foo", 2},
+		{"\tfoo", 8},
+		{"\t foo", 9},
+		{"  \tfoo", 8},
+		{"       \tfoo", 8},
+		{"        \tfoo", 16},
+	} {
+		if n := indentation(c.str); n != c.wantIndent {
+			t.Errorf("indentation(%v): got %d, want %d", c.str, n, c.wantIndent)
+		}
+	}
+}
+
+func readProfile(fname string, t *testing.T) *profile.Profile {
+	file, err := os.Open(fname)
+	if err != nil {
+		t.Fatalf("%s: could not open profile: %v", fname, err)
+	}
+	defer file.Close()
+	p, err := profile.Parse(file)
+	if err != nil {
+		t.Fatalf("%s: could not parse profile: %v", fname, err)
+	}
+
+	// Fix file names so they do not include absolute path names.
+	fix := func(s string) string {
+		const testdir = "/internal/report/"
+		pos := strings.Index(s, testdir)
+		if pos == -1 {
+			return s
+		}
+		return s[pos+len(testdir):]
+	}
+	for _, m := range p.Mapping {
+		m.File = fix(m.File)
+	}
+	for _, f := range p.Function {
+		f.Filename = fix(f.Filename)
+	}
+
+	return p
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/README.md b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/README.md
new file mode 100644
index 0000000..2b60fcc
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/README.md
@@ -0,0 +1,10 @@
+sample/ contains a sample program that can be profiled.
+sample.bin is its x86-64 binary.
+sample.cpu is a profile generated by sample.bin.
+
+To update the binary and profile:
+
+```shell
+go build -o sample.bin ./sample
+./sample.bin -cpuprofile sample.cpu
+```
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.bin b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.bin
new file mode 100755
index 0000000..25929e6
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.bin
Binary files differ
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.cpu b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.cpu
new file mode 100644
index 0000000..50eea72
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.cpu
Binary files differ
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample/sample.go b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample/sample.go
new file mode 100644
index 0000000..3c812dd
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample/sample.go
@@ -0,0 +1,41 @@
+// sample program that is used to produce some of the files in
+// pprof/internal/report/testdata.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"math"
+	"os"
+	"runtime/pprof"
+)
+
+var cpuProfile = flag.String("cpuprofile", "", "where to write cpu profile")
+
+func main() {
+	flag.Parse()
+	f, err := os.Create(*cpuProfile)
+	if err != nil {
+		log.Fatal("could not create CPU profile: ", err)
+	}
+	if err := pprof.StartCPUProfile(f); err != nil {
+		log.Fatal("could not start CPU profile: ", err)
+	}
+	defer pprof.StopCPUProfile()
+	busyLoop()
+}
+
+func busyLoop() {
+	m := make(map[int]int)
+	for i := 0; i < 1000000; i++ {
+		m[i] = i + 10
+	}
+	var sum float64
+	for i := 0; i < 100; i++ {
+		for _, v := range m {
+			sum += math.Abs(float64(v))
+		}
+	}
+	fmt.Println("Sum", sum)
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot
index 19746a4..b67ca16 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot
@@ -1,13 +1,13 @@
 digraph "unnamed" {
 node [style=filled fillcolor="#f8f8f8"]
 subgraph cluster_L { "Duration: 10s, Total samples = 11111 " [shape=box fontsize=16 label="Duration: 10s, Total samples = 11111 \lShowing nodes accounting for 11111, 100% of 11111 total\l"] }
-N1 [label="tee\nsource2:8\n10000 (90.00%)" fontsize=24 shape=box tooltip="tee testdata/source2:8 (10000)" color="#b20500" fillcolor="#edd6d5"]
-N2 [label="main\nsource1:2\n1 (0.009%)\nof 11111 (100%)" fontsize=9 shape=box tooltip="main testdata/source1:2 (11111)" color="#b20000" fillcolor="#edd5d5"]
-N3 [label="tee\nsource2:2\n1000 (9.00%)\nof 11000 (99.00%)" fontsize=14 shape=box tooltip="tee testdata/source2:2 (11000)" color="#b20000" fillcolor="#edd5d5"]
-N4 [label="tee\nsource2:8\n100 (0.9%)" fontsize=10 shape=box tooltip="tee testdata/source2:8 (100)" color="#b2b0aa" fillcolor="#edecec"]
-N5 [label="bar\nsource1:10\n10 (0.09%)" fontsize=9 shape=box tooltip="bar testdata/source1:10 (10)" color="#b2b2b1" fillcolor="#ededed"]
-N6 [label="bar\nsource1:10\n0 of 100 (0.9%)" fontsize=8 shape=box tooltip="bar testdata/source1:10 (100)" color="#b2b0aa" fillcolor="#edecec"]
-N7 [label="foo\nsource1:4\n0 of 10 (0.09%)" fontsize=8 shape=box tooltip="foo testdata/source1:4 (10)" color="#b2b2b1" fillcolor="#ededed"]
+N1 [label="tee\nsource2:8\n10000 (90.00%)" id="node1" fontsize=24 shape=box tooltip="tee testdata/source2:8 (10000)" color="#b20500" fillcolor="#edd6d5"]
+N2 [label="main\nsource1:2\n1 (0.009%)\nof 11111 (100%)" id="node2" fontsize=9 shape=box tooltip="main testdata/source1:2 (11111)" color="#b20000" fillcolor="#edd5d5"]
+N3 [label="tee\nsource2:2\n1000 (9.00%)\nof 11000 (99.00%)" id="node3" fontsize=14 shape=box tooltip="tee testdata/source2:2 (11000)" color="#b20000" fillcolor="#edd5d5"]
+N4 [label="tee\nsource2:8\n100 (0.9%)" id="node4" fontsize=10 shape=box tooltip="tee testdata/source2:8 (100)" color="#b2b0aa" fillcolor="#edecec"]
+N5 [label="bar\nsource1:10\n10 (0.09%)" id="node5" fontsize=9 shape=box tooltip="bar testdata/source1:10 (10)" color="#b2b2b1" fillcolor="#ededed"]
+N6 [label="bar\nsource1:10\n0 of 100 (0.9%)" id="node6" fontsize=8 shape=box tooltip="bar testdata/source1:10 (100)" color="#b2b0aa" fillcolor="#edecec"]
+N7 [label="foo\nsource1:4\n0 of 10 (0.09%)" id="node7" fontsize=8 shape=box tooltip="foo testdata/source1:4 (10)" color="#b2b2b1" fillcolor="#ededed"]
 N2 -> N3 [label=" 11000" weight=100 penwidth=5 color="#b20000" tooltip="main testdata/source1:2 -> tee testdata/source2:2 (11000)" labeltooltip="main testdata/source1:2 -> tee testdata/source2:2 (11000)"]
 N3 -> N1 [label=" 10000" weight=91 penwidth=5 color="#b20500" tooltip="tee testdata/source2:2 -> tee testdata/source2:8 (10000)" labeltooltip="tee testdata/source2:2 -> tee testdata/source2:8 (10000)"]
 N6 -> N4 [label=" 100" color="#b2b0aa" tooltip="bar testdata/source1:10 -> tee testdata/source2:8 (100)" labeltooltip="bar testdata/source1:10 -> tee testdata/source2:8 (100)"]
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
index 2c1c729..727b7e8 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
@@ -18,6 +18,7 @@
 package symbolizer
 
 import (
+	"crypto/tls"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -41,21 +42,26 @@
 // test taps for dependency injection
 var symbolzSymbolize = symbolz.Symbolize
 var localSymbolize = doLocalSymbolize
+var demangleFunction = Demangle
 
 // Symbolize attempts to symbolize profile p. First uses binutils on
 // local binaries; if the source is a URL it attempts to get any
 // missed entries using symbolz.
 func (s *Symbolizer) Symbolize(mode string, sources plugin.MappingSources, p *profile.Profile) error {
-	remote, local, force, demanglerMode := true, true, false, ""
+	remote, local, fast, force, demanglerMode := true, true, false, false, ""
 	for _, o := range strings.Split(strings.ToLower(mode), ":") {
 		switch o {
+		case "":
+			continue
 		case "none", "no":
 			return nil
-		case "local", "fastlocal":
+		case "local":
 			remote, local = false, true
+		case "fastlocal":
+			remote, local, fast = false, true, true
 		case "remote":
 			remote, local = true, false
-		case "", "force":
+		case "force":
 			force = true
 		default:
 			switch d := strings.TrimPrefix(o, "demangle="); d {
@@ -74,29 +80,48 @@
 	var err error
 	if local {
 		// Symbolize locally using binutils.
-		if err = localSymbolize(mode, p, s.Obj, s.UI); err != nil {
+		if err = localSymbolize(p, fast, force, s.Obj, s.UI); err != nil {
 			s.UI.PrintErr("local symbolization: " + err.Error())
 		}
 	}
 	if remote {
-		if err = symbolzSymbolize(sources, postURL, p, s.UI); err != nil {
+		if err = symbolzSymbolize(p, force, sources, postURL, s.UI); err != nil {
 			return err // Ran out of options.
 		}
 	}
 
-	Demangle(p, force, demanglerMode)
+	demangleFunction(p, force, demanglerMode)
 	return 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))
+	url, err := url.Parse(source)
+	if err != nil {
+		return nil, err
+	}
+
+	var tlsConfig *tls.Config
+	if url.Scheme == "https+insecure" {
+		tlsConfig = &tls.Config{
+			InsecureSkipVerify: true,
+		}
+		url.Scheme = "https"
+		source = url.String()
+	}
+
+	client := &http.Client{
+		Transport: &http.Transport{
+			TLSClientConfig: tlsConfig,
+		},
+	}
+	resp, err := client.Post(source, "application/octet-stream", strings.NewReader(post))
 	if err != nil {
 		return nil, fmt.Errorf("http post %s: %v", source, err)
 	}
 	defer resp.Body.Close()
 	if resp.StatusCode != http.StatusOK {
-		return nil, statusCodeError(resp)
+		return nil, fmt.Errorf("http post %s: %v", source, statusCodeError(resp))
 	}
 	return ioutil.ReadAll(resp.Body)
 }
@@ -114,18 +139,10 @@
 // doLocalSymbolize adds symbol and line number information to all locations
 // in a profile. mode enables some options to control
 // symbolization.
-func doLocalSymbolize(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 {
-		case o == "force":
-			force = true
-		case o == "fastlocal":
-			if bu, ok := obj.(*binutils.Binutils); ok {
-				bu.SetFastSymbolization(true)
-			}
-		default:
+func doLocalSymbolize(prof *profile.Profile, fast, force bool, obj plugin.ObjTool, ui plugin.UI) error {
+	if fast {
+		if bu, ok := obj.(*binutils.Binutils); ok {
+			bu.SetFastSymbolization(true)
 		}
 	}
 
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer_test.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer_test.go
index 66cad3e..956519d 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer_test.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"regexp"
+	"sort"
 	"strings"
 	"testing"
 
@@ -101,9 +102,11 @@
 	defer func() {
 		symbolzSymbolize = sSym
 		localSymbolize = lSym
+		demangleFunction = Demangle
 	}()
 	symbolzSymbolize = symbolzMock
 	localSymbolize = localMock
+	demangleFunction = demangleMock
 
 	type testcase struct {
 		mode        string
@@ -117,19 +120,35 @@
 	for i, tc := range []testcase{
 		{
 			"local",
-			"local=local",
+			"local=[]",
 		},
 		{
 			"fastlocal",
-			"local=fastlocal",
+			"local=[fast]",
 		},
 		{
 			"remote",
-			"symbolz",
+			"symbolz=[]",
 		},
 		{
 			"",
-			"local=:symbolz",
+			"local=[]:symbolz=[]",
+		},
+		{
+			"demangle=none",
+			"demangle=[none]:force:local=[force]:symbolz=[force]",
+		},
+		{
+			"remote:demangle=full",
+			"demangle=[full]:force:symbolz=[force]",
+		},
+		{
+			"local:demangle=templates",
+			"demangle=[templates]:force:local=[force]",
+		},
+		{
+			"force:remote",
+			"force:symbolz=[force]",
 		},
 	} {
 		prof := testProfile.Copy()
@@ -137,23 +156,44 @@
 			t.Errorf("symbolize #%d: %v", i, err)
 			continue
 		}
+		sort.Strings(prof.Comments)
 		if got, want := strings.Join(prof.Comments, ":"), tc.wantComment; got != want {
-			t.Errorf("got %s, want %s", got, want)
+			t.Errorf("%q: got %s, want %s", tc.mode, got, want)
 			continue
 		}
 	}
 }
 
-func symbolzMock(sources plugin.MappingSources, syms func(string, string) ([]byte, error), p *profile.Profile, ui plugin.UI) error {
-	p.Comments = append(p.Comments, "symbolz")
+func symbolzMock(p *profile.Profile, force bool, sources plugin.MappingSources, syms func(string, string) ([]byte, error), ui plugin.UI) error {
+	var args []string
+	if force {
+		args = append(args, "force")
+	}
+	p.Comments = append(p.Comments, "symbolz=["+strings.Join(args, ",")+"]")
 	return nil
 }
 
-func localMock(mode string, p *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
-	p.Comments = append(p.Comments, "local="+mode)
+func localMock(p *profile.Profile, fast, force bool, obj plugin.ObjTool, ui plugin.UI) error {
+	var args []string
+	if fast {
+		args = append(args, "fast")
+	}
+	if force {
+		args = append(args, "force")
+	}
+	p.Comments = append(p.Comments, "local=["+strings.Join(args, ",")+"]")
 	return nil
 }
 
+func demangleMock(p *profile.Profile, force bool, mode string) {
+	if force {
+		p.Comments = append(p.Comments, "force")
+	}
+	if mode != "" {
+		p.Comments = append(p.Comments, "demangle=["+mode+"]")
+	}
+}
+
 func TestLocalSymbolization(t *testing.T) {
 	prof := testProfile.Copy()
 
@@ -165,7 +205,7 @@
 	}
 
 	b := mockObjTool{}
-	if err := localSymbolize("", prof, b, &proftest.TestUI{T: t}); err != nil {
+	if err := localSymbolize(prof, false, false, b, &proftest.TestUI{T: t}); err != nil {
 		t.Fatalf("localSymbolize(): %v", err)
 	}
 
@@ -207,11 +247,11 @@
 }
 
 var mockAddresses = map[uint64][]plugin.Frame{
-	1000: []plugin.Frame{frame("fun11", "file11.src", 10)},
-	2000: []plugin.Frame{frame("fun21", "file21.src", 20), frame("fun22", "file22.src", 20)},
-	3000: []plugin.Frame{frame("fun31", "file31.src", 30), frame("fun32", "file32.src", 30), frame("fun33", "file33.src", 30)},
-	4000: []plugin.Frame{frame("fun41", "file41.src", 40), frame("fun42", "file42.src", 40), frame("fun43", "file43.src", 40), frame("fun44", "file44.src", 40)},
-	5000: []plugin.Frame{frame("fun51", "file51.src", 50), frame("fun52", "file52.src", 50), frame("fun53", "file53.src", 50), frame("fun54", "file54.src", 50), frame("fun55", "file55.src", 50)},
+	1000: {frame("fun11", "file11.src", 10)},
+	2000: {frame("fun21", "file21.src", 20), frame("fun22", "file22.src", 20)},
+	3000: {frame("fun31", "file31.src", 30), frame("fun32", "file32.src", 30), frame("fun33", "file33.src", 30)},
+	4000: {frame("fun41", "file41.src", 40), frame("fun42", "file42.src", 40), frame("fun43", "file43.src", 40), frame("fun44", "file44.src", 40)},
+	5000: {frame("fun51", "file51.src", 50), frame("fun52", "file52.src", 50), frame("fun53", "file53.src", 50), frame("fun54", "file54.src", 50), frame("fun55", "file55.src", 50)},
 }
 
 func frame(fname, file string, line int) plugin.Frame {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz.go
index e84765b..34c119c 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz.go
@@ -36,12 +36,13 @@
 
 // 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(sources plugin.MappingSources, syms func(string, string) ([]byte, error), p *profile.Profile, ui plugin.UI) error {
+// separated by '+') and returns the symbolz output in a string. If
+// force is false, it will only symbolize locations from mappings
+// not already marked as HasFunctions.
+func Symbolize(p *profile.Profile, force bool, sources plugin.MappingSources, syms func(string, string) ([]byte, error), ui plugin.UI) error {
 	for _, m := range p.Mapping {
-		if m.HasFunctions {
+		if !force && m.HasFunctions {
+			// Only check for HasFunctions as symbolz only populates function names.
 			continue
 		}
 		mappingSources := sources[m.File]
@@ -65,16 +66,13 @@
 // symbolz returns the corresponding symbolz source for a profile URL.
 func symbolz(source string) string {
 	if url, err := url.Parse(source); err == nil && url.Host != "" {
-		if strings.Contains(url.Path, "/") {
-			if dir := path.Dir(url.Path); dir == "/debug/pprof" {
-				// For Go language profile handlers in net/http/pprof package.
-				url.Path = "/debug/pprof/symbol"
-			} else {
-				url.Path = "/symbolz"
-			}
-			url.RawQuery = ""
-			return url.String()
+		if strings.Contains(url.Path, "/debug/pprof/") {
+			url.Path = path.Clean(url.Path + "/../symbol")
+		} else {
+			url.Path = "/symbolz"
 		}
+		url.RawQuery = ""
+		return url.String()
 	}
 
 	return ""
@@ -82,7 +80,7 @@
 
 // symbolizeMapping symbolizes locations belonging to a Mapping by querying
 // a symbolz handler. An offset is applied to all addresses to take care of
-// normalization occured for merged Mappings.
+// normalization occurred for merged Mappings.
 func symbolizeMapping(source string, offset int64, syms func(string, string) ([]byte, error), m *profile.Mapping, p *profile.Profile) error {
 	// Construct query of addresses to symbolize.
 	var a []string
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz_test.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz_test.go
index 641b5ca..270a619 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolz/symbolz_test.go
@@ -26,13 +26,14 @@
 
 func TestSymbolzURL(t *testing.T) {
 	for try, want := range map[string]string{
-		"http://host:8000/profilez":                        "http://host:8000/symbolz",
-		"http://host:8000/profilez?seconds=5":              "http://host:8000/symbolz",
-		"http://host:8000/profilez?seconds=5&format=proto": "http://host:8000/symbolz",
-		"http://host:8000/heapz?format=legacy":             "http://host:8000/symbolz",
-		"http://host:8000/debug/pprof/profile":             "http://host:8000/debug/pprof/symbol",
-		"http://host:8000/debug/pprof/profile?seconds=10":  "http://host:8000/debug/pprof/symbol",
-		"http://host:8000/debug/pprof/heap":                "http://host:8000/debug/pprof/symbol",
+		"http://host:8000/profilez":                                               "http://host:8000/symbolz",
+		"http://host:8000/profilez?seconds=5":                                     "http://host:8000/symbolz",
+		"http://host:8000/profilez?seconds=5&format=proto":                        "http://host:8000/symbolz",
+		"http://host:8000/heapz?format=legacy":                                    "http://host:8000/symbolz",
+		"http://host:8000/debug/pprof/profile":                                    "http://host:8000/debug/pprof/symbol",
+		"http://host:8000/debug/pprof/profile?seconds=10":                         "http://host:8000/debug/pprof/symbol",
+		"http://host:8000/debug/pprof/heap":                                       "http://host:8000/debug/pprof/symbol",
+		"http://some.host:8080/some/deeper/path/debug/pprof/endpoint?param=value": "http://some.host:8080/some/deeper/path/debug/pprof/symbol",
 	} {
 		if got := symbolz(try); got != want {
 			t.Errorf(`symbolz(%s)=%s, want "%s"`, try, got, want)
@@ -41,12 +42,49 @@
 }
 
 func TestSymbolize(t *testing.T) {
+	s := plugin.MappingSources{
+		"buildid": []struct {
+			Source string
+			Start  uint64
+		}{
+			{Source: "http://localhost:80/profilez"},
+		},
+	}
+
+	for _, hasFunctions := range []bool{false, true} {
+		for _, force := range []bool{false, true} {
+			p := testProfile(hasFunctions)
+
+			if err := Symbolize(p, force, s, fetchSymbols, &proftest.TestUI{T: t}); err != nil {
+				t.Errorf("symbolz: %v", err)
+				continue
+			}
+			var wantSym, wantNoSym []*profile.Location
+			if force || !hasFunctions {
+				wantNoSym = p.Location[:1]
+				wantSym = p.Location[1:]
+			} else {
+				wantNoSym = p.Location
+			}
+
+			if err := checkSymbolized(wantSym, true); err != nil {
+				t.Errorf("symbolz hasFns=%v force=%v: %v", hasFunctions, force, err)
+			}
+			if err := checkSymbolized(wantNoSym, false); err != nil {
+				t.Errorf("symbolz hasFns=%v force=%v: %v", hasFunctions, force, err)
+			}
+		}
+	}
+}
+
+func testProfile(hasFunctions bool) *profile.Profile {
 	m := []*profile.Mapping{
 		{
-			ID:      1,
-			Start:   0x1000,
-			Limit:   0x5000,
-			BuildID: "buildid",
+			ID:           1,
+			Start:        0x1000,
+			Limit:        0x5000,
+			BuildID:      "buildid",
+			HasFunctions: hasFunctions,
 		},
 	}
 	p := &profile.Profile{
@@ -59,33 +97,25 @@
 		Mapping: m,
 	}
 
-	s := plugin.MappingSources{
-		"buildid": []struct {
-			Source string
-			Start  uint64
-		}{
-			{Source: "http://localhost:80/profilez"},
-		},
-	}
+	return p
+}
 
-	if err := Symbolize(s, fetchSymbols, p, &proftest.TestUI{T: t}); err != nil {
-		t.Errorf("symbolz: %v", err)
-	}
-
-	if l := p.Location[0]; len(l.Line) != 0 {
-		t.Errorf("unexpected symbolization for %#x: %v", l.Address, l.Line)
-	}
-
-	for _, l := range p.Location[1:] {
-		if len(l.Line) != 1 {
-			t.Errorf("failed to symbolize %#x", l.Address)
-			continue
+func checkSymbolized(locs []*profile.Location, wantSymbolized bool) error {
+	for _, loc := range locs {
+		if !wantSymbolized && len(loc.Line) != 0 {
+			return fmt.Errorf("unexpected symbolization for %#x: %v", loc.Address, loc.Line)
 		}
-		address := l.Address - l.Mapping.Start
-		if got, want := l.Line[0].Function.Name, fmt.Sprintf("%#x", address); got != want {
-			t.Errorf("symbolz %#x, got %s, want %s", address, got, want)
+		if wantSymbolized {
+			if len(loc.Line) != 1 {
+				return fmt.Errorf("expected symbolization for %#x: %v", loc.Address, loc.Line)
+			}
+			address := loc.Address - loc.Mapping.Start
+			if got, want := loc.Line[0].Function.Name, fmt.Sprintf("%#x", address); got != want {
+				return fmt.Errorf("symbolz %#x, got %s, want %s", address, got, want)
+			}
 		}
 	}
+	return nil
 }
 
 func fetchSymbols(source, post string) ([]byte, error) {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/encode.go b/src/cmd/vendor/github.com/google/pprof/profile/encode.go
index c64083a..6223194 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/encode.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/encode.go
@@ -59,12 +59,19 @@
 		}
 		sort.Strings(numKeys)
 		for _, k := range numKeys {
+			keyX := addString(strings, k)
 			vs := s.NumLabel[k]
-			for _, v := range vs {
+			units := s.NumUnit[k]
+			for i, v := range vs {
+				var unitX int64
+				if len(units) != 0 {
+					unitX = addString(strings, units[i])
+				}
 				s.labelX = append(s.labelX,
 					label{
-						keyX: addString(strings, k),
-						numX: v,
+						keyX:  keyX,
+						numX:  v,
+						unitX: unitX,
 					},
 				)
 			}
@@ -289,6 +296,7 @@
 	for _, s := range p.Sample {
 		labels := make(map[string][]string, len(s.labelX))
 		numLabels := make(map[string][]int64, len(s.labelX))
+		numUnits := make(map[string][]string, len(s.labelX))
 		for _, l := range s.labelX {
 			var key, value string
 			key, err = getString(p.stringTable, &l.keyX, err)
@@ -296,6 +304,14 @@
 				value, err = getString(p.stringTable, &l.strX, err)
 				labels[key] = append(labels[key], value)
 			} else if l.numX != 0 {
+				numValues := numLabels[key]
+				units := numUnits[key]
+				if l.unitX != 0 {
+					var unit string
+					unit, err = getString(p.stringTable, &l.unitX, err)
+					units = padStringArray(units, len(numValues))
+					numUnits[key] = append(units, unit)
+				}
 				numLabels[key] = append(numLabels[key], l.numX)
 			}
 		}
@@ -304,6 +320,12 @@
 		}
 		if len(numLabels) > 0 {
 			s.NumLabel = numLabels
+			for key, units := range numUnits {
+				if len(units) > 0 {
+					numUnits[key] = padStringArray(units, len(numLabels[key]))
+				}
+			}
+			s.NumUnit = numUnits
 		}
 		s.Location = make([]*Location, len(s.locationIDX))
 		for i, lid := range s.locationIDX {
@@ -340,6 +362,15 @@
 	return err
 }
 
+// padStringArray pads arr with enough empty strings to make arr
+// length l when arr's length is less than l.
+func padStringArray(arr []string, l int) []string {
+	if l <= len(arr) {
+		return arr
+	}
+	return append(arr, make([]string, l-len(arr))...)
+}
+
 func (p *ValueType) decoder() []decoder {
 	return valueTypeDecoder
 }
@@ -392,6 +423,7 @@
 	encodeInt64Opt(b, 1, p.keyX)
 	encodeInt64Opt(b, 2, p.strX)
 	encodeInt64Opt(b, 3, p.numX)
+	encodeInt64Opt(b, 4, p.unitX)
 }
 
 var labelDecoder = []decoder{
@@ -402,6 +434,8 @@
 	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) },
+	// optional int64 num = 4
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).unitX) },
 }
 
 func (p *Mapping) decoder() []decoder {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/filter.go b/src/cmd/vendor/github.com/google/pprof/profile/filter.go
index 85361e8..f857fdf 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/filter.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/filter.go
@@ -41,10 +41,11 @@
 			}
 		}
 		if show != nil {
-			hnm = true
 			l.Line = l.matchedLines(show)
 			if len(l.Line) == 0 {
 				hidden[l.ID] = true
+			} else {
+				hnm = true
 			}
 		}
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go b/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
index 7b40f5d..06322e5 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
@@ -212,7 +212,10 @@
 			switch pType {
 			case "heap":
 				const javaHeapzSamplingRate = 524288 // 512K
-				s.NumLabel = map[string][]int64{"bytes": []int64{s.Value[1] / s.Value[0]}}
+				if s.Value[0] == 0 {
+					return nil, nil, fmt.Errorf("parsing sample %s: second value must be non-zero", line)
+				}
+				s.NumLabel = map[string][]int64{"bytes": {s.Value[1] / s.Value[0]}}
 				s.Value[0], s.Value[1] = scaleHeapSample(s.Value[0], s.Value[1], javaHeapzSamplingRate)
 			case "contention":
 				if period := p.Period; period != 0 {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/merge.go b/src/cmd/vendor/github.com/google/pprof/profile/merge.go
index 2e9c2cd..e00829c 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/merge.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/merge.go
@@ -85,6 +85,41 @@
 	return p, nil
 }
 
+// Normalize normalizes the source profile by multiplying each value in profile by the
+// ratio of the sum of the base profile's values of that sample type to the sum of the
+// source profile's value of that sample type.
+func (p *Profile) Normalize(pb *Profile) error {
+
+	if err := p.compatible(pb); err != nil {
+		return err
+	}
+
+	baseVals := make([]int64, len(p.SampleType))
+	for _, s := range pb.Sample {
+		for i, v := range s.Value {
+			baseVals[i] += v
+		}
+	}
+
+	srcVals := make([]int64, len(p.SampleType))
+	for _, s := range p.Sample {
+		for i, v := range s.Value {
+			srcVals[i] += v
+		}
+	}
+
+	normScale := make([]float64, len(baseVals))
+	for i := range baseVals {
+		if srcVals[i] == 0 {
+			normScale[i] = 0.0
+		} else {
+			normScale[i] = float64(baseVals[i]) / float64(srcVals[i])
+		}
+	}
+	p.ScaleN(normScale)
+	return nil
+}
+
 func isZeroSample(s *Sample) bool {
 	for _, v := range s.Value {
 		if v != 0 {
@@ -120,6 +155,7 @@
 		Value:    make([]int64, len(src.Value)),
 		Label:    make(map[string][]string, len(src.Label)),
 		NumLabel: make(map[string][]int64, len(src.NumLabel)),
+		NumUnit:  make(map[string][]string, len(src.NumLabel)),
 	}
 	for i, l := range src.Location {
 		s.Location[i] = pm.mapLocation(l)
@@ -130,9 +166,13 @@
 		s.Label[k] = vv
 	}
 	for k, v := range src.NumLabel {
+		u := src.NumUnit[k]
 		vv := make([]int64, len(v))
+		uu := make([]string, len(u))
 		copy(vv, v)
+		copy(uu, u)
 		s.NumLabel[k] = vv
+		s.NumUnit[k] = uu
 	}
 	// Check memoization table. Must be done on the remapped location to
 	// account for the remapped mapping. Add current values to the
@@ -165,7 +205,7 @@
 
 	numlabels := make([]string, 0, len(sample.NumLabel))
 	for k, v := range sample.NumLabel {
-		numlabels = append(numlabels, fmt.Sprintf("%q%x", k, v))
+		numlabels = append(numlabels, fmt.Sprintf("%q%x%x", k, v, sample.NumUnit[k]))
 	}
 	sort.Strings(numlabels)
 
@@ -432,7 +472,6 @@
 			return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
 		}
 	}
-
 	return nil
 }
 
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile.go b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
index fb3d4fd..a0f53ef 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
@@ -26,6 +26,7 @@
 	"regexp"
 	"sort"
 	"strings"
+	"sync"
 	"time"
 )
 
@@ -47,6 +48,10 @@
 	PeriodType    *ValueType
 	Period        int64
 
+	// The following fields are modified during encoding and copying,
+	// so are protected by a Mutex.
+	encodeMu sync.Mutex
+
 	commentX           []int64
 	dropFramesX        int64
 	keepFramesX        int64
@@ -69,6 +74,7 @@
 	Value    []int64
 	Label    map[string][]string
 	NumLabel map[string][]int64
+	NumUnit  map[string][]string
 
 	locationIDX []uint64
 	labelX      []label
@@ -80,6 +86,8 @@
 	// Exactly one of the two following values must be set
 	strX int64
 	numX int64 // Integer value for this label
+	// can be set if numX has value
+	unitX int64
 }
 
 // Mapping corresponds to Profile.Mapping
@@ -296,21 +304,25 @@
 	}
 }
 
-// Write writes the profile as a gzip-compressed marshaled protobuf.
-func (p *Profile) Write(w io.Writer) error {
+func serialize(p *Profile) []byte {
+	p.encodeMu.Lock()
 	p.preEncode()
 	b := marshal(p)
+	p.encodeMu.Unlock()
+	return b
+}
+
+// Write writes the profile as a gzip-compressed marshaled protobuf.
+func (p *Profile) Write(w io.Writer) error {
 	zw := gzip.NewWriter(w)
 	defer zw.Close()
-	_, err := zw.Write(b)
+	_, err := zw.Write(serialize(p))
 	return err
 }
 
 // WriteUncompressed writes the profile as a marshaled protobuf.
 func (p *Profile) WriteUncompressed(w io.Writer) error {
-	p.preEncode()
-	b := marshal(p)
-	_, err := w.Write(b)
+	_, err := w.Write(serialize(p))
 	return err
 }
 
@@ -325,8 +337,11 @@
 		return fmt.Errorf("missing sample type information")
 	}
 	for _, s := range p.Sample {
+		if s == nil {
+			return fmt.Errorf("profile has nil sample")
+		}
 		if len(s.Value) != sampleLen {
-			return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType))
+			return fmt.Errorf("mismatch: sample has %d values vs. %d types", len(s.Value), len(p.SampleType))
 		}
 		for _, l := range s.Location {
 			if l == nil {
@@ -339,6 +354,9 @@
 	// Check that there are no duplicate ids
 	mappings := make(map[uint64]*Mapping, len(p.Mapping))
 	for _, m := range p.Mapping {
+		if m == nil {
+			return fmt.Errorf("profile has nil mapping")
+		}
 		if m.ID == 0 {
 			return fmt.Errorf("found mapping with reserved ID=0")
 		}
@@ -349,6 +367,9 @@
 	}
 	functions := make(map[uint64]*Function, len(p.Function))
 	for _, f := range p.Function {
+		if f == nil {
+			return fmt.Errorf("profile has nil function")
+		}
 		if f.ID == 0 {
 			return fmt.Errorf("found function with reserved ID=0")
 		}
@@ -359,6 +380,9 @@
 	}
 	locations := make(map[uint64]*Location, len(p.Location))
 	for _, l := range p.Location {
+		if l == nil {
+			return fmt.Errorf("profile has nil location")
+		}
 		if l.ID == 0 {
 			return fmt.Errorf("found location with reserved id=0")
 		}
@@ -426,6 +450,70 @@
 	return p.CheckValid()
 }
 
+// NumLabelUnits returns a map of numeric label keys to the units
+// associated with those keys and a map of those keys to any units
+// that were encountered but not used.
+// Unit for a given key is the first encountered unit for that key. If multiple
+// units are encountered for values paired with a particular key, then the first
+// unit encountered is used and all other units are returned in sorted order
+// in map of ignored units.
+// If no units are encountered for a particular key, the unit is then inferred
+// based on the key.
+func (p *Profile) NumLabelUnits() (map[string]string, map[string][]string) {
+	numLabelUnits := map[string]string{}
+	ignoredUnits := map[string]map[string]bool{}
+	encounteredKeys := map[string]bool{}
+
+	// Determine units based on numeric tags for each sample.
+	for _, s := range p.Sample {
+		for k := range s.NumLabel {
+			encounteredKeys[k] = true
+			for _, unit := range s.NumUnit[k] {
+				if unit == "" {
+					continue
+				}
+				if wantUnit, ok := numLabelUnits[k]; !ok {
+					numLabelUnits[k] = unit
+				} else if wantUnit != unit {
+					if v, ok := ignoredUnits[k]; ok {
+						v[unit] = true
+					} else {
+						ignoredUnits[k] = map[string]bool{unit: true}
+					}
+				}
+			}
+		}
+	}
+	// Infer units for keys without any units associated with
+	// numeric tag values.
+	for key := range encounteredKeys {
+		unit := numLabelUnits[key]
+		if unit == "" {
+			switch key {
+			case "alignment", "request":
+				numLabelUnits[key] = "bytes"
+			default:
+				numLabelUnits[key] = key
+			}
+		}
+	}
+
+	// Copy ignored units into more readable format
+	unitsIgnored := make(map[string][]string, len(ignoredUnits))
+	for key, values := range ignoredUnits {
+		units := make([]string, len(values))
+		i := 0
+		for unit := range values {
+			units[i] = unit
+			i++
+		}
+		sort.Strings(units)
+		unitsIgnored[key] = units
+	}
+
+	return numLabelUnits, unitsIgnored
+}
+
 // String dumps a text representation of a profile. Intended mainly
 // for debugging purposes.
 func (p *Profile) String() string {
@@ -455,87 +543,132 @@
 	}
 	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 := []string{}
-			for k, v := range s.Label {
-				ls = append(ls, fmt.Sprintf("%s:%v", k, v))
-			}
-			sort.Strings(ls)
-			ss = append(ss, labelHeader+strings.Join(ls, " "))
-		}
-		if len(s.NumLabel) > 0 {
-			ls := []string{}
-			for k, v := range s.NumLabel {
-				ls = append(ls, fmt.Sprintf("%s:%v", k, v))
-			}
-			sort.Strings(ls)
-			ss = append(ss, labelHeader+strings.Join(ls, " "))
-		}
+		ss = append(ss, s.string())
 	}
 
 	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, l.string())
 	}
 
 	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))
+		ss = append(ss, m.string())
 	}
 
 	return strings.Join(ss, "\n") + "\n"
 }
 
+// string dumps a text representation of a mapping. Intended mainly
+// for debugging purposes.
+func (m *Mapping) string() string {
+	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]"
+	}
+	return fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s",
+		m.ID,
+		m.Start, m.Limit, m.Offset,
+		m.File,
+		m.BuildID,
+		bits)
+}
+
+// string dumps a text representation of a location. Intended mainly
+// for debugging purposes.
+func (l *Location) string() string {
+	ss := []string{}
+	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 = "             "
+	}
+	return strings.Join(ss, "\n")
+}
+
+// string dumps a text representation of a sample. Intended mainly
+// for debugging purposes.
+func (s *Sample) string() string {
+	ss := []string{}
+	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 {
+		ss = append(ss, labelHeader+labelsToString(s.Label))
+	}
+	if len(s.NumLabel) > 0 {
+		ss = append(ss, labelHeader+numLabelsToString(s.NumLabel, s.NumUnit))
+	}
+	return strings.Join(ss, "\n")
+}
+
+// labelsToString returns a string representation of a
+// map representing labels.
+func labelsToString(labels map[string][]string) string {
+	ls := []string{}
+	for k, v := range labels {
+		ls = append(ls, fmt.Sprintf("%s:%v", k, v))
+	}
+	sort.Strings(ls)
+	return strings.Join(ls, " ")
+}
+
+// numLablesToString returns a string representation of a map
+// representing numeric labels.
+func numLabelsToString(numLabels map[string][]int64, numUnits map[string][]string) string {
+	ls := []string{}
+	for k, v := range numLabels {
+		units := numUnits[k]
+		var labelString string
+		if len(units) == len(v) {
+			values := make([]string, len(v))
+			for i, vv := range v {
+				values[i] = fmt.Sprintf("%d %s", vv, units[i])
+			}
+			labelString = fmt.Sprintf("%s:%v", k, values)
+		} else {
+			labelString = fmt.Sprintf("%s:%v", k, v)
+		}
+		ls = append(ls, labelString)
+	}
+	sort.Strings(ls)
+	return strings.Join(ls, " ")
+}
+
 // Scale multiplies all sample values in a profile by a constant.
 func (p *Profile) Scale(ratio float64) {
 	if ratio == 1 {
@@ -596,19 +729,17 @@
 }
 
 // Unsymbolizable returns true if a mapping points to a binary for which
-// locations can't be symbolized in principle, at least now.
+// locations can't be symbolized in principle, at least now. Examples are
+// "[vdso]", [vsyscall]" and some others, see the code.
 func (m *Mapping) Unsymbolizable() bool {
 	name := filepath.Base(m.File)
-	return name == "[vdso]" || strings.HasPrefix(name, "linux-vdso") || name == "[heap]" || strings.HasPrefix(m.File, "/dev/dri/")
+	return strings.HasPrefix(name, "[") || strings.HasPrefix(name, "linux-vdso") || strings.HasPrefix(m.File, "/dev/dri/")
 }
 
 // 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 {
+	if err := unmarshal(serialize(p), pp); err != nil {
 		panic(err)
 	}
 	if err := pp.postDecode(); err != nil {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go b/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
index c2319a6..bc2ab8b 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
@@ -19,8 +19,10 @@
 	"fmt"
 	"io/ioutil"
 	"path/filepath"
+	"reflect"
 	"regexp"
 	"strings"
+	"sync"
 	"testing"
 
 	"github.com/google/pprof/internal/proftest"
@@ -91,7 +93,6 @@
 }
 
 func TestParseError(t *testing.T) {
-
 	testcases := []string{
 		"",
 		"garbage text",
@@ -107,6 +108,63 @@
 	}
 }
 
+func TestCheckValid(t *testing.T) {
+	const path = "testdata/java.cpu"
+
+	inbytes, err := ioutil.ReadFile(path)
+	if err != nil {
+		t.Fatalf("failed to read profile file %q: %v", path, err)
+	}
+	p, err := Parse(bytes.NewBuffer(inbytes))
+	if err != nil {
+		t.Fatalf("failed to parse profile %q: %s", path, err)
+	}
+
+	for _, tc := range []struct {
+		mutateFn func(*Profile)
+		wantErr  string
+	}{
+		{
+			mutateFn: func(p *Profile) { p.SampleType = nil },
+			wantErr:  "missing sample type information",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Sample[0] = nil },
+			wantErr:  "profile has nil sample",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Sample[0].Value = append(p.Sample[0].Value, 0) },
+			wantErr:  "sample has 3 values vs. 2 types",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Sample[0].Location[0] = nil },
+			wantErr:  "sample has nil location",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Location[0] = nil },
+			wantErr:  "profile has nil location",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Mapping = append(p.Mapping, nil) },
+			wantErr:  "profile has nil mapping",
+		},
+		{
+			mutateFn: func(p *Profile) { p.Function[0] = nil },
+			wantErr:  "profile has nil function",
+		},
+	} {
+		t.Run(tc.wantErr, func(t *testing.T) {
+			p := p.Copy()
+			tc.mutateFn(p)
+			if err := p.CheckValid(); err == nil {
+				t.Errorf("CheckValid(): got no error, want error %q", tc.wantErr)
+			} else if !strings.Contains(err.Error(), tc.wantErr) {
+				t.Errorf("CheckValid(): got error %v, want error %q", err, tc.wantErr)
+			}
+		})
+	}
+}
+
 // leaveTempfile leaves |b| in a temporary file on disk and returns the
 // temp filename. This is useful to recover a profile when the test
 // fails.
@@ -217,7 +275,7 @@
 	},
 }
 
-var testProfile = &Profile{
+var testProfile1 = &Profile{
 	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
 	Period:        1,
 	DurationNanos: 10e9,
@@ -230,40 +288,181 @@
 			Location: []*Location{cpuL[0]},
 			Value:    []int64{1000, 1000},
 			Label: map[string][]string{
-				"key1": []string{"tag1"},
-				"key2": []string{"tag1"},
+				"key1": {"tag1"},
+				"key2": {"tag1"},
 			},
 		},
 		{
 			Location: []*Location{cpuL[1], cpuL[0]},
 			Value:    []int64{100, 100},
 			Label: map[string][]string{
-				"key1": []string{"tag2"},
-				"key3": []string{"tag2"},
+				"key1": {"tag2"},
+				"key3": {"tag2"},
 			},
 		},
 		{
 			Location: []*Location{cpuL[2], cpuL[0]},
 			Value:    []int64{10, 10},
 			Label: map[string][]string{
-				"key1": []string{"tag3"},
-				"key2": []string{"tag2"},
+				"key1": {"tag3"},
+				"key2": {"tag2"},
 			},
 		},
 		{
 			Location: []*Location{cpuL[3], cpuL[0]},
 			Value:    []int64{10000, 10000},
 			Label: map[string][]string{
-				"key1": []string{"tag4"},
-				"key2": []string{"tag1"},
+				"key1": {"tag4"},
+				"key2": {"tag1"},
 			},
 		},
 		{
 			Location: []*Location{cpuL[4], cpuL[0]},
 			Value:    []int64{1, 1},
 			Label: map[string][]string{
-				"key1": []string{"tag4"},
-				"key2": []string{"tag1"},
+				"key1": {"tag4"},
+				"key2": {"tag1"},
+			},
+		},
+	},
+	Location: cpuL,
+	Function: cpuF,
+	Mapping:  cpuM,
+}
+
+var testProfile2 = &Profile{
+	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
+	Period:        1,
+	DurationNanos: 10e9,
+	SampleType: []*ValueType{
+		{Type: "samples", Unit: "count"},
+		{Type: "cpu", Unit: "milliseconds"},
+	},
+	Sample: []*Sample{
+		{
+			Location: []*Location{cpuL[0]},
+			Value:    []int64{70, 1000},
+			Label: map[string][]string{
+				"key1": {"tag1"},
+				"key2": {"tag1"},
+			},
+		},
+		{
+			Location: []*Location{cpuL[1], cpuL[0]},
+			Value:    []int64{60, 100},
+			Label: map[string][]string{
+				"key1": {"tag2"},
+				"key3": {"tag2"},
+			},
+		},
+		{
+			Location: []*Location{cpuL[2], cpuL[0]},
+			Value:    []int64{50, 10},
+			Label: map[string][]string{
+				"key1": {"tag3"},
+				"key2": {"tag2"},
+			},
+		},
+		{
+			Location: []*Location{cpuL[3], cpuL[0]},
+			Value:    []int64{40, 10000},
+			Label: map[string][]string{
+				"key1": {"tag4"},
+				"key2": {"tag1"},
+			},
+		},
+		{
+			Location: []*Location{cpuL[4], cpuL[0]},
+			Value:    []int64{1, 1},
+			Label: map[string][]string{
+				"key1": {"tag4"},
+				"key2": {"tag1"},
+			},
+		},
+	},
+	Location: cpuL,
+	Function: cpuF,
+	Mapping:  cpuM,
+}
+
+var testProfile3 = &Profile{
+	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
+	Period:        1,
+	DurationNanos: 10e9,
+	SampleType: []*ValueType{
+		{Type: "samples", Unit: "count"},
+	},
+	Sample: []*Sample{
+		{
+			Location: []*Location{cpuL[0]},
+			Value:    []int64{1000},
+			Label: map[string][]string{
+				"key1": {"tag1"},
+				"key2": {"tag1"},
+			},
+		},
+	},
+	Location: cpuL,
+	Function: cpuF,
+	Mapping:  cpuM,
+}
+
+var testProfile4 = &Profile{
+	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
+	Period:        1,
+	DurationNanos: 10e9,
+	SampleType: []*ValueType{
+		{Type: "samples", Unit: "count"},
+	},
+	Sample: []*Sample{
+		{
+			Location: []*Location{cpuL[0]},
+			Value:    []int64{1000},
+			NumLabel: map[string][]int64{
+				"key1": {10},
+				"key2": {30},
+			},
+			NumUnit: map[string][]string{
+				"key1": {"bytes"},
+				"key2": {"bytes"},
+			},
+		},
+	},
+	Location: cpuL,
+	Function: cpuF,
+	Mapping:  cpuM,
+}
+
+var testProfile5 = &Profile{
+	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
+	Period:        1,
+	DurationNanos: 10e9,
+	SampleType: []*ValueType{
+		{Type: "samples", Unit: "count"},
+	},
+	Sample: []*Sample{
+		{
+			Location: []*Location{cpuL[0]},
+			Value:    []int64{1000},
+			NumLabel: map[string][]int64{
+				"key1": {10},
+				"key2": {30},
+			},
+			NumUnit: map[string][]string{
+				"key1": {"bytes"},
+				"key2": {"bytes"},
+			},
+		},
+		{
+			Location: []*Location{cpuL[0]},
+			Value:    []int64{1000},
+			NumLabel: map[string][]int64{
+				"key1": {10},
+				"key2": {30},
+			},
+			NumUnit: map[string][]string{
+				"key1": {"kilobytes"},
+				"key2": {"kilobytes"},
 			},
 		},
 	},
@@ -273,10 +472,10 @@
 }
 
 var aggTests = map[string]aggTest{
-	"precise":         aggTest{true, true, true, true, 5},
-	"fileline":        aggTest{false, true, true, true, 4},
-	"inline_function": aggTest{false, true, false, true, 3},
-	"function":        aggTest{false, true, false, false, 2},
+	"precise":         {true, true, true, true, 5},
+	"fileline":        {false, true, true, true, 4},
+	"inline_function": {false, true, false, true, 3},
+	"function":        {false, true, false, false, 2},
 }
 
 type aggTest struct {
@@ -287,7 +486,7 @@
 const totalSamples = int64(11111)
 
 func TestAggregation(t *testing.T) {
-	prof := testProfile.Copy()
+	prof := testProfile1.Copy()
 	for _, resolution := range []string{"precise", "fileline", "inline_function", "function"} {
 		a := aggTests[resolution]
 		if !a.precise {
@@ -362,7 +561,7 @@
 
 // Test merge leaves the main binary in place.
 func TestMergeMain(t *testing.T) {
-	prof := testProfile.Copy()
+	prof := testProfile1.Copy()
 	p1, err := Merge([]*Profile{prof})
 	if err != nil {
 		t.Fatalf("merge error: %v", err)
@@ -377,7 +576,7 @@
 	// -2. Should end up with an empty profile (all samples for a
 	// location should add up to 0).
 
-	prof := testProfile.Copy()
+	prof := testProfile1.Copy()
 	p1, err := Merge([]*Profile{prof, prof})
 	if err != nil {
 		t.Errorf("merge error: %v", err)
@@ -409,7 +608,7 @@
 	// Aggregate 10 copies of the profile.
 	profs := make([]*Profile, 10)
 	for i := 0; i < 10; i++ {
-		profs[i] = testProfile.Copy()
+		profs[i] = testProfile1.Copy()
 	}
 	prof, err := Merge(profs)
 	if err != nil {
@@ -420,7 +619,7 @@
 		tb := locationHash(s)
 		samples[tb] = samples[tb] + s.Value[0]
 	}
-	for _, s := range testProfile.Sample {
+	for _, s := range testProfile1.Sample {
 		tb := locationHash(s)
 		if samples[tb] != s.Value[0]*10 {
 			t.Errorf("merge got wrong value at %s : %d instead of %d", tb, samples[tb], s.Value[0]*10)
@@ -428,6 +627,140 @@
 	}
 }
 
+func TestNumLabelMerge(t *testing.T) {
+	for _, tc := range []struct {
+		name          string
+		profs         []*Profile
+		wantNumLabels []map[string][]int64
+		wantNumUnits  []map[string][]string
+	}{
+		{
+			name:  "different tag units not merged",
+			profs: []*Profile{testProfile4.Copy(), testProfile5.Copy()},
+			wantNumLabels: []map[string][]int64{
+				{
+					"key1": {10},
+					"key2": {30},
+				},
+				{
+					"key1": {10},
+					"key2": {30},
+				},
+			},
+			wantNumUnits: []map[string][]string{
+				{
+					"key1": {"bytes"},
+					"key2": {"bytes"},
+				},
+				{
+					"key1": {"kilobytes"},
+					"key2": {"kilobytes"},
+				},
+			},
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			prof, err := Merge(tc.profs)
+			if err != nil {
+				t.Errorf("merge error: %v", err)
+			}
+
+			if want, got := len(tc.wantNumLabels), len(prof.Sample); want != got {
+				t.Fatalf("got %d samples, want %d samples", got, want)
+			}
+			for i, wantLabels := range tc.wantNumLabels {
+				numLabels := prof.Sample[i].NumLabel
+				if !reflect.DeepEqual(wantLabels, numLabels) {
+					t.Errorf("got numeric labels %v, want %v", numLabels, wantLabels)
+				}
+
+				wantUnits := tc.wantNumUnits[i]
+				numUnits := prof.Sample[i].NumUnit
+				if !reflect.DeepEqual(wantUnits, numUnits) {
+					t.Errorf("got numeric labels %v, want %v", numUnits, wantUnits)
+				}
+			}
+		})
+	}
+}
+
+func TestNormalizeBySameProfile(t *testing.T) {
+	pb := testProfile1.Copy()
+	p := testProfile1.Copy()
+
+	if err := p.Normalize(pb); err != nil {
+		t.Fatal(err)
+	}
+
+	for i, s := range p.Sample {
+		for j, v := range s.Value {
+			expectedSampleValue := testProfile1.Sample[i].Value[j]
+			if v != expectedSampleValue {
+				t.Errorf("For sample %d, value %d want %d got %d", i, j, expectedSampleValue, v)
+			}
+		}
+	}
+}
+
+func TestNormalizeByDifferentProfile(t *testing.T) {
+	p := testProfile1.Copy()
+	pb := testProfile2.Copy()
+
+	if err := p.Normalize(pb); err != nil {
+		t.Fatal(err)
+	}
+
+	expectedSampleValues := [][]int64{
+		{19, 1000},
+		{1, 100},
+		{0, 10},
+		{198, 10000},
+		{0, 1},
+	}
+
+	for i, s := range p.Sample {
+		for j, v := range s.Value {
+			if v != expectedSampleValues[i][j] {
+				t.Errorf("For sample %d, value %d want %d got %d", i, j, expectedSampleValues[i][j], v)
+			}
+		}
+	}
+}
+
+func TestNormalizeByMultipleOfSameProfile(t *testing.T) {
+	pb := testProfile1.Copy()
+	for i, s := range pb.Sample {
+		for j, v := range s.Value {
+			pb.Sample[i].Value[j] = 10 * v
+		}
+	}
+
+	p := testProfile1.Copy()
+
+	err := p.Normalize(pb)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for i, s := range p.Sample {
+		for j, v := range s.Value {
+			expectedSampleValue := 10 * testProfile1.Sample[i].Value[j]
+			if v != expectedSampleValue {
+				t.Errorf("For sample %d, value %d, want %d got %d", i, j, expectedSampleValue, v)
+			}
+		}
+	}
+}
+
+func TestNormalizeIncompatibleProfiles(t *testing.T) {
+	p := testProfile1.Copy()
+	pb := testProfile3.Copy()
+
+	if err := p.Normalize(pb); err == nil {
+		t.Errorf("Expected an error")
+	}
+}
+
 func TestFilter(t *testing.T) {
 	// Perform several forms of filtering on the test profile.
 
@@ -437,12 +770,33 @@
 	}
 
 	for tx, tc := range []filterTestcase{
-		{nil, nil, nil, nil, true, false, false, false},
-		{regexp.MustCompile("notfound"), nil, nil, nil, false, false, false, false},
-		{nil, regexp.MustCompile("foo.c"), nil, nil, true, true, false, false},
-		{nil, nil, regexp.MustCompile("lib.so"), nil, true, false, true, false},
+		{
+			fm: true, // nil focus matches every sample
+		},
+		{
+			focus: regexp.MustCompile("notfound"),
+		},
+		{
+			ignore: regexp.MustCompile("foo.c"),
+			fm:     true,
+			im:     true,
+		},
+		{
+			hide: regexp.MustCompile("lib.so"),
+			fm:   true,
+			hm:   true,
+		},
+		{
+			show: regexp.MustCompile("foo.c"),
+			fm:   true,
+			hnm:  true,
+		},
+		{
+			show: regexp.MustCompile("notfound"),
+			fm:   true,
+		},
 	} {
-		prof := *testProfile.Copy()
+		prof := *testProfile1.Copy()
 		gf, gi, gh, gnh := prof.FilterSamplesByName(tc.focus, tc.ignore, tc.hide, tc.show)
 		if gf != tc.fm {
 			t.Errorf("Filter #%d, got fm=%v, want %v", tx, gf, tc.fm)
@@ -488,7 +842,7 @@
 		{regexp.MustCompile("key1"), nil, true, false, 1},
 		{nil, regexp.MustCompile("key[12]"), true, true, 1},
 	} {
-		prof := testProfile.Copy()
+		prof := testProfile1.Copy()
 		gim, gem := prof.FilterTagsByName(tc.include, tc.exclude)
 		if gim != tc.im {
 			t.Errorf("Filter #%d, got include match=%v, want %v", tx, gim, tc.im)
@@ -513,9 +867,152 @@
 	return tb
 }
 
-func TestSetMain(t *testing.T) {
-	testProfile.massageMappings()
-	if testProfile.Mapping[0].File != mainBinary {
-		t.Errorf("got %s for main", testProfile.Mapping[0].File)
+func TestNumLabelUnits(t *testing.T) {
+	var tagFilterTests = []struct {
+		desc             string
+		tagVals          []map[string][]int64
+		tagUnits         []map[string][]string
+		wantUnits        map[string]string
+		wantIgnoredUnits map[string][]string
+	}{
+		{
+			"One sample, multiple keys, different specified units",
+			[]map[string][]int64{{"key1": {131072}, "key2": {128}}},
+			[]map[string][]string{{"key1": {"bytes"}, "key2": {"kilobytes"}}},
+			map[string]string{"key1": "bytes", "key2": "kilobytes"},
+			map[string][]string{},
+		},
+		{
+			"One sample, one key with one value, unit specified",
+			[]map[string][]int64{{"key1": {8}}},
+			[]map[string][]string{{"key1": {"bytes"}}},
+			map[string]string{"key1": "bytes"},
+			map[string][]string{},
+		},
+		{
+			"One sample, one key with one value, empty unit specified",
+			[]map[string][]int64{{"key1": {8}}},
+			[]map[string][]string{{"key1": {""}}},
+			map[string]string{"key1": "key1"},
+			map[string][]string{},
+		},
+		{
+			"Key bytes, unit not specified",
+			[]map[string][]int64{{"bytes": {8}}},
+			[]map[string][]string{nil},
+			map[string]string{"bytes": "bytes"},
+			map[string][]string{},
+		},
+		{
+			"One sample, one key with one value, unit not specified",
+			[]map[string][]int64{{"kilobytes": {8}}},
+			[]map[string][]string{nil},
+			map[string]string{"kilobytes": "kilobytes"},
+			map[string][]string{},
+		},
+		{
+			"Key request, unit not specified",
+			[]map[string][]int64{{"request": {8}}},
+			[]map[string][]string{nil},
+			map[string]string{"request": "bytes"},
+			map[string][]string{},
+		},
+		{
+			"Key alignment, unit not specified",
+			[]map[string][]int64{{"alignment": {8}}},
+			[]map[string][]string{nil},
+			map[string]string{"alignment": "bytes"},
+			map[string][]string{},
+		},
+		{
+			"One sample, one key with multiple values and two different units",
+			[]map[string][]int64{{"key1": {8, 8}}},
+			[]map[string][]string{{"key1": {"bytes", "kilobytes"}}},
+			map[string]string{"key1": "bytes"},
+			map[string][]string{"key1": {"kilobytes"}},
+		},
+		{
+			"One sample, one key with multiple values and three different units",
+			[]map[string][]int64{{"key1": {8, 8}}},
+			[]map[string][]string{{"key1": {"bytes", "megabytes", "kilobytes"}}},
+			map[string]string{"key1": "bytes"},
+			map[string][]string{"key1": {"kilobytes", "megabytes"}},
+		},
+		{
+			"Two samples, one key, different units specified",
+			[]map[string][]int64{{"key1": {8}}, {"key1": {8}}},
+			[]map[string][]string{{"key1": {"bytes"}}, {"key1": {"kilobytes"}}},
+			map[string]string{"key1": "bytes"},
+			map[string][]string{"key1": {"kilobytes"}},
+		},
+		{
+			"Keys alignment, request, and bytes have units specified",
+			[]map[string][]int64{{
+				"alignment": {8},
+				"request":   {8},
+				"bytes":     {8},
+			}},
+			[]map[string][]string{{
+				"alignment": {"seconds"},
+				"request":   {"minutes"},
+				"bytes":     {"hours"},
+			}},
+			map[string]string{
+				"alignment": "seconds",
+				"request":   "minutes",
+				"bytes":     "hours",
+			},
+			map[string][]string{},
+		},
 	}
+	for _, test := range tagFilterTests {
+		p := &Profile{Sample: make([]*Sample, len(test.tagVals))}
+		for i, numLabel := range test.tagVals {
+			s := Sample{
+				NumLabel: numLabel,
+				NumUnit:  test.tagUnits[i],
+			}
+			p.Sample[i] = &s
+		}
+		units, ignoredUnits := p.NumLabelUnits()
+		if !reflect.DeepEqual(test.wantUnits, units) {
+			t.Errorf("%s: got %v units, want %v", test.desc, units, test.wantUnits)
+		}
+		if !reflect.DeepEqual(test.wantIgnoredUnits, ignoredUnits) {
+			t.Errorf("%s: got %v ignored units, want %v", test.desc, ignoredUnits, test.wantIgnoredUnits)
+		}
+	}
+}
+
+func TestSetMain(t *testing.T) {
+	testProfile1.massageMappings()
+	if testProfile1.Mapping[0].File != mainBinary {
+		t.Errorf("got %s for main", testProfile1.Mapping[0].File)
+	}
+}
+
+// parallel runs n copies of fn in parallel.
+func parallel(n int, fn func()) {
+	var wg sync.WaitGroup
+	wg.Add(n)
+	for i := 0; i < n; i++ {
+		go func() {
+			fn()
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+}
+
+func TestThreadSafety(t *testing.T) {
+	src := testProfile1.Copy()
+	parallel(4, func() { src.Copy() })
+	parallel(4, func() {
+		var b bytes.Buffer
+		src.WriteUncompressed(&b)
+	})
+	parallel(4, func() {
+		var b bytes.Buffer
+		src.Write(&b)
+	})
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/proto.go b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
index 01b7f7a..e7df33a 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/proto.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
@@ -71,7 +71,7 @@
 
 func encodeUint64(b *buffer, tag int, x uint64) {
 	// append varint to b.data
-	encodeVarint(b, uint64(tag)<<3|0)
+	encodeVarint(b, uint64(tag)<<3)
 	encodeVarint(b, x)
 }
 
@@ -145,13 +145,6 @@
 	}
 }
 
-func encodeStringOpt(b *buffer, tag int, x string) {
-	if x == "" {
-		return
-	}
-	encodeString(b, tag, x)
-}
-
 func encodeBool(b *buffer, tag int, x bool) {
 	if x {
 		encodeUint64(b, tag, 1)
@@ -161,10 +154,9 @@
 }
 
 func encodeBoolOpt(b *buffer, tag int, x bool) {
-	if x == false {
-		return
+	if x {
+		encodeBool(b, tag, x)
 	}
-	encodeBool(b, tag, x)
 }
 
 func encodeMessage(b *buffer, tag int, m message) {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go b/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
index d2a3513..e083229 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
@@ -100,8 +100,8 @@
 		{
 			Location: []*Location{testL[0], testL[1], testL[2], testL[1], testL[1]},
 			Label: map[string][]string{
-				"key1": []string{"value1"},
-				"key2": []string{"value2"},
+				"key1": {"value1"},
+				"key2": {"value2"},
 			},
 			Value: []int64{10, 20},
 		},
@@ -109,12 +109,19 @@
 			Location: []*Location{testL[1], testL[2], testL[0], testL[1]},
 			Value:    []int64{30, 40},
 			Label: map[string][]string{
-				"key1": []string{"value1"},
-				"key2": []string{"value2"},
+				"key1": {"value1"},
+				"key2": {"value2"},
 			},
 			NumLabel: map[string][]int64{
-				"key1": []int64{1, 2},
-				"key2": []int64{3, 4},
+				"key1":      {1, 2},
+				"key2":      {3, 4},
+				"bytes":     {3, 4},
+				"requests":  {1, 1, 3, 4, 5},
+				"alignment": {3, 4},
+			},
+			NumUnit: map[string][]string{
+				"requests":  {"", "", "seconds", "", "s"},
+				"alignment": {"kilobytes", "kilobytes"},
 			},
 		},
 	},
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/prune.go b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
index cf9cbb3..02d21a8 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/prune.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
@@ -22,6 +22,39 @@
 	"strings"
 )
 
+var (
+	reservedNames = []string{"(anonymous namespace)", "operator()"}
+	bracketRx     = func() *regexp.Regexp {
+		var quotedNames []string
+		for _, name := range append(reservedNames, "(") {
+			quotedNames = append(quotedNames, regexp.QuoteMeta(name))
+		}
+		return regexp.MustCompile(strings.Join(quotedNames, "|"))
+	}()
+)
+
+// simplifyFunc does some primitive simplification of function names.
+func simplifyFunc(f string) string {
+	// Account for leading '.' on the PPC ELF v1 ABI.
+	funcName := strings.TrimPrefix(f, ".")
+	// Account for unsimplified names -- try  to remove the argument list by trimming
+	// starting from the first '(', but skipping reserved names that have '('.
+	for _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) {
+		foundReserved := false
+		for _, res := range reservedNames {
+			if funcName[ind[0]:ind[1]] == res {
+				foundReserved = true
+				break
+			}
+		}
+		if !foundReserved {
+			funcName = funcName[:ind[0]]
+			break
+		}
+	}
+	return funcName
+}
+
 // 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.
@@ -33,12 +66,7 @@
 		var i int
 		for i = len(loc.Line) - 1; i >= 0; i-- {
 			if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
-				// Account for leading '.' on the PPC ELF v1 ABI.
-				funcName := strings.TrimPrefix(fn.Name, ".")
-				// Account for unsimplified names -- trim starting from the first '('.
-				if index := strings.Index(funcName, "("); index > 0 {
-					funcName = funcName[:index]
-				}
+				funcName := simplifyFunc(fn.Name)
 				if dropRx.MatchString(funcName) {
 					if keepRx == nil || !keepRx.MatchString(funcName) {
 						break
@@ -126,12 +154,7 @@
 	for _, loc := range p.Location {
 		for i := 0; i < len(loc.Line); i++ {
 			if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
-				// Account for leading '.' on the PPC ELF v1 ABI.
-				funcName := strings.TrimPrefix(fn.Name, ".")
-				// Account for unsimplified names -- trim starting from the first '('.
-				if index := strings.Index(funcName, "("); index > 0 {
-					funcName = funcName[:index]
-				}
+				funcName := simplifyFunc(fn.Name)
 				if dropRx.MatchString(funcName) {
 					// Found matching entry to prune.
 					pruneBeneath[loc.ID] = true
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go b/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
index 58fa25e..75d7c6d 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
@@ -25,6 +25,7 @@
 		want string
 	}{
 		{in1, out1},
+		{in2, out2},
 	} {
 		in := test.in.Copy()
 		in.RemoveUninteresting()
@@ -50,6 +51,10 @@
 	{ID: 4, Name: "fun3", SystemName: "fun3", Filename: "fun.c"},
 	{ID: 5, Name: "fun4", SystemName: "fun4", Filename: "fun.c"},
 	{ID: 6, Name: "fun5", SystemName: "fun5", Filename: "fun.c"},
+	{ID: 7, Name: "unsimplified_fun(int)", SystemName: "unsimplified_fun(int)", Filename: "fun.c"},
+	{ID: 8, Name: "Foo::(anonymous namespace)::Test::Bar", SystemName: "Foo::(anonymous namespace)::Test::Bar", Filename: "fun.c"},
+	{ID: 9, Name: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", SystemName: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", Filename: "fun.c"},
+	{ID: 10, Name: "Foo::operator()(::Bar)", SystemName: "Foo::operator()(::Bar)", Filename: "fun.c"},
 }
 
 var locs1 = []*Location{
@@ -137,3 +142,89 @@
      4: 0x0 fun5 fun.c:2 s=0
 Mappings
 `
+
+var locs2 = []*Location{
+	{
+		ID: 1,
+		Line: []Line{
+			{Function: funs[0], Line: 1},
+		},
+	},
+	{
+		ID: 2,
+		Line: []Line{
+			{Function: funs[6], Line: 1},
+		},
+	},
+	{
+		ID: 3,
+		Line: []Line{
+			{Function: funs[7], Line: 1},
+		},
+	},
+	{
+		ID: 4,
+		Line: []Line{
+			{Function: funs[8], Line: 1},
+		},
+	},
+	{
+		ID: 5,
+		Line: []Line{
+			{Function: funs[9], Line: 1},
+		},
+	},
+}
+
+var in2 = &Profile{
+	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
+	Period:        1,
+	DurationNanos: 10e9,
+	SampleType: []*ValueType{
+		{Type: "samples", Unit: "count"},
+		{Type: "cpu", Unit: "milliseconds"},
+	},
+	Sample: []*Sample{
+		// Unsimplified name with parameters shouldn't match.
+		{
+			Location: []*Location{locs2[1], locs2[0]},
+			Value:    []int64{1, 1},
+		},
+		// .*Foo::.*::Bar.* should (and will be dropped) regardless of the anonymous namespace.
+		{
+			Location: []*Location{locs2[2], locs2[0]},
+			Value:    []int64{1, 1},
+		},
+		// .*Foo::.*::Bar.* shouldn't match inside the parameter list.
+		{
+			Location: []*Location{locs2[3], locs2[0]},
+			Value:    []int64{1, 1},
+		},
+		// .*operator\(\) should match, regardless of parameters.
+		{
+			Location: []*Location{locs2[4], locs2[0]},
+			Value:    []int64{1, 1},
+		},
+	},
+	Location:   locs2,
+	Function:   funs,
+	DropFrames: `unsimplified_fun\(int\)|.*Foo::.*::Bar.*|.*operator\(\)`,
+}
+
+const out2 = `PeriodType: cpu milliseconds
+Period: 1
+Duration: 10s
+Samples:
+samples/count cpu/milliseconds
+          1          1: 2 1
+          1          1: 1
+          1          1: 4 1
+          1          1: 1
+Locations
+     1: 0x0 main main.c:1 s=0
+     2: 0x0 unsimplified_fun(int) fun.c:1 s=0
+     3: 0x0 Foo::(anonymous namespace)::Test::Bar fun.c:1 s=0
+     4: 0x0 Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar) fun.c:1 s=0
+     5: 0x0 Foo::operator()(::Bar) fun.c:1 s=0
+Mappings
+`
diff --git a/src/cmd/vendor/github.com/google/pprof/proto/profile.proto b/src/cmd/vendor/github.com/google/pprof/proto/profile.proto
index aa790e0..78caf41 100644
--- a/src/cmd/vendor/github.com/google/pprof/proto/profile.proto
+++ b/src/cmd/vendor/github.com/google/pprof/proto/profile.proto
@@ -109,6 +109,15 @@
   // At most one of the following must be present
   int64 str = 2;   // Index into string table
   int64 num = 3;
+
+  // Should only be present when num is present.
+  // Specifies the units of num.
+  // Use arbitrary string (for example, "requests") as a custom count unit.
+  // If no unit is specified, consumer may apply heuristic to deduce the unit.
+  // Consumers may also  interpret units like "bytes" and "kilobytes" as memory
+  // units and units like "seconds" and "nanoseconds" as time units,
+  // and apply appropriate unit conversions to these.
+  int64 num_unit = 4;  // Index into string table
 }
 
 message Mapping {
diff --git a/src/cmd/vendor/github.com/google/pprof/test.sh b/src/cmd/vendor/github.com/google/pprof/test.sh
new file mode 100755
index 0000000..81b9089
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/test.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -e
+MODE=atomic
+echo "mode: $MODE" > coverage.txt
+
+PKG=$(go list ./... | grep -v /vendor/)
+
+staticcheck $PKG
+unused $PKG
+go test -v $PKG
+
+for d in $PKG; do
+  go test -race -coverprofile=profile.out -covermode=$MODE $d
+  if [ -f profile.out ]; then
+    cat profile.out | grep -v "^mode: " >> coverage.txt
+    rm profile.out
+  fi
+done
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
index cc81dc3..6b4d738 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
@@ -233,9 +233,9 @@
 		typ, count := decodeShift(x)
 		// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
 		if typ == RotateRightExt {
-			return Rm
+			return Reg(Rm)
 		}
-		return RegShift{Rm, typ, count}
+		return RegShift{Rm, typ, uint8(count)}
 
 	case arg_R_shift_R:
 		Rm := Reg(x & (1<<4 - 1))
@@ -247,9 +247,9 @@
 		Rm := Reg(x & (1<<4 - 1))
 		typ, count := decodeShift(x)
 		if typ == ShiftLeft && count == 0 {
-			return Rm
+			return Reg(Rm)
 		}
-		return RegShift{Rm, typ, count}
+		return RegShift{Rm, typ, uint8(count)}
 
 	case arg_R1_0:
 		return Reg((x & (1<<4 - 1)))
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go
index 98192b3..3556ae7 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go
@@ -34,7 +34,7 @@
 	debug      = false
 )
 
-// A ExtInst represents a single decoded instruction parsed
+// An ExtInst represents a single decoded instruction parsed
 // from an external disassembler's output.
 type ExtInst struct {
 	addr uint32
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go
index 60d633b..0e05644 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go
@@ -105,7 +105,7 @@
 	return fmt.Sprintf("#%#x", uint32(i))
 }
 
-// A ImmAlt is an alternate encoding of an integer constant.
+// An ImmAlt is an alternate encoding of an integer constant.
 type ImmAlt struct {
 	Val uint8
 	Rot uint8
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go
index fae0ca6..321b081 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go
@@ -9,6 +9,7 @@
 	"encoding/binary"
 	"fmt"
 	"io"
+	"math"
 	"strings"
 )
 
@@ -37,7 +38,7 @@
 	op := inst.Op.String()
 
 	switch inst.Op &^ 15 {
-	case LDR_EQ, LDRB_EQ, LDRH_EQ:
+	case LDR_EQ, LDRB_EQ, LDRH_EQ, LDRSB_EQ, LDRSH_EQ, VLDR_EQ:
 		// Check for RET
 		reg, _ := inst.Args[0].(Reg)
 		mem, _ := inst.Args[1].(Mem)
@@ -48,22 +49,22 @@
 		// 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)
+			buf := make([]byte, 8)
 			switch inst.Op &^ 15 {
-			case LDRB_EQ:
+			case LDRB_EQ, LDRSB_EQ:
 				if _, err := text.ReadAt(buf[:1], int64(addr)); err != nil {
 					break
 				}
 				args[1] = fmt.Sprintf("$%#x", buf[0])
 
-			case LDRH_EQ:
+			case LDRH_EQ, LDRSH_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 {
+				if _, err := text.ReadAt(buf[:4], int64(addr)); err != nil {
 					break
 				}
 				x := binary.LittleEndian.Uint32(buf)
@@ -72,6 +73,22 @@
 				} else {
 					args[1] = fmt.Sprintf("$%#x", x)
 				}
+
+			case VLDR_EQ:
+				switch {
+				case strings.HasPrefix(args[0], "D"): // VLDR.F64
+					if _, err := text.ReadAt(buf, int64(addr)); err != nil {
+						break
+					}
+					args[1] = fmt.Sprintf("$%f", math.Float64frombits(binary.LittleEndian.Uint64(buf)))
+				case strings.HasPrefix(args[0], "S"): // VLDR.F32
+					if _, err := text.ReadAt(buf[:4], int64(addr)); err != nil {
+						break
+					}
+					args[1] = fmt.Sprintf("$%f", math.Float32frombits(binary.LittleEndian.Uint32(buf)))
+				default:
+					panic(fmt.Sprintf("wrong FP register: %v", inst))
+				}
 			}
 		}
 	}
@@ -79,7 +96,7 @@
 	// Move addressing mode into opcode suffix.
 	suffix := ""
 	switch inst.Op &^ 15 {
-	case LDR_EQ, LDRB_EQ, LDRH_EQ, STR_EQ, STRB_EQ, STRH_EQ:
+	case LDR_EQ, LDRB_EQ, LDRSB_EQ, LDRH_EQ, LDRSH_EQ, STR_EQ, STRB_EQ, STRH_EQ, VLDR_EQ, VSTR_EQ:
 		mem, _ := inst.Args[1].(Mem)
 		switch mem.Mode {
 		case AddrOffset, AddrLDM:
@@ -98,7 +115,7 @@
 		if mem.Sign != 0 {
 			sign := ""
 			if mem.Sign < 0 {
-				sign = ""
+				suffix += ".U"
 			}
 			shift := ""
 			if mem.Count != 0 {
@@ -113,6 +130,11 @@
 	for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
 		args[i], args[j] = args[j], args[i]
 	}
+	// For MLA-like instructions, the addend is the third operand.
+	switch inst.Op &^ 15 {
+	case SMLAWT_EQ, SMLAWB_EQ, MLA_EQ, MLA_S_EQ, MLS_EQ, SMMLA_EQ, SMMLS_EQ, SMLABB_EQ, SMLATB_EQ, SMLABT_EQ, SMLATT_EQ, SMLAD_EQ, SMLAD_X_EQ, SMLSD_EQ, SMLSD_X_EQ:
+		args = []string{args[1], args[2], args[0], args[3]}
+	}
 
 	switch inst.Op &^ 15 {
 	case MOV_EQ:
@@ -121,9 +143,26 @@
 	case LDR_EQ:
 		op = "MOVW" + op[3:] + suffix
 	case LDRB_EQ:
-		op = "MOVB" + op[4:] + suffix
+		op = "MOVBU" + op[4:] + suffix
+	case LDRSB_EQ:
+		op = "MOVBS" + op[5:] + suffix
 	case LDRH_EQ:
-		op = "MOVH" + op[4:] + suffix
+		op = "MOVHU" + op[4:] + suffix
+	case LDRSH_EQ:
+		op = "MOVHS" + op[5:] + suffix
+	case VLDR_EQ:
+		switch {
+		case strings.HasPrefix(args[1], "D"): // VLDR.F64
+			op = "MOVD" + op[4:] + suffix
+			args[1] = "F" + args[1][1:] // Dx -> Fx
+		case strings.HasPrefix(args[1], "S"): // VLDR.F32
+			op = "MOVF" + op[4:] + suffix
+			if inst.Args[0].(Reg)&1 == 0 { // Sx -> Fy, y = x/2, if x is even
+				args[1] = fmt.Sprintf("F%d", (inst.Args[0].(Reg)-S0)/2)
+			}
+		default:
+			panic(fmt.Sprintf("wrong FP register: %v", inst))
+		}
 
 	case STR_EQ:
 		op = "MOVW" + op[3:] + suffix
@@ -134,6 +173,20 @@
 	case STRH_EQ:
 		op = "MOVH" + op[4:] + suffix
 		args[0], args[1] = args[1], args[0]
+	case VSTR_EQ:
+		switch {
+		case strings.HasPrefix(args[1], "D"): // VSTR.F64
+			op = "MOVD" + op[4:] + suffix
+			args[1] = "F" + args[1][1:] // Dx -> Fx
+		case strings.HasPrefix(args[1], "S"): // VSTR.F32
+			op = "MOVF" + op[4:] + suffix
+			if inst.Args[0].(Reg)&1 == 0 { // Sx -> Fy, y = x/2, if x is even
+				args[1] = fmt.Sprintf("F%d", (inst.Args[0].(Reg)-S0)/2)
+			}
+		default:
+			panic(fmt.Sprintf("wrong FP register: %v", inst))
+		}
+		args[0], args[1] = args[1], args[0]
 	}
 
 	if args != nil {
@@ -154,7 +207,7 @@
 	case Endian:
 
 	case Imm:
-		return fmt.Sprintf("$%d", int(a))
+		return fmt.Sprintf("$%d", uint32(a))
 
 	case Mem:
 
@@ -185,6 +238,8 @@
 				} else {
 					fmt.Fprintf(&buf, "R%d-R%d", start, end)
 				}
+				start = -2
+				end = -2
 			}
 		}
 		for i := 0; i < 16; i++ {
@@ -195,6 +250,8 @@
 				}
 				start = i
 				end = i
+			} else {
+				flush()
 			}
 		}
 		flush()
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go
index 58f51fe..3ad489e 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go
@@ -945,6 +945,22 @@
 	MRS_LE
 	MRS
 	MRS_ZZ
+	MSR_EQ
+	MSR_NE
+	MSR_CS
+	MSR_CC
+	MSR_MI
+	MSR_PL
+	MSR_VS
+	MSR_VC
+	MSR_HI
+	MSR_LS
+	MSR_GE
+	MSR_LT
+	MSR_GT
+	MSR_LE
+	MSR
+	MSR_ZZ
 	MUL_EQ
 	MUL_NE
 	MUL_CS
@@ -1585,6 +1601,22 @@
 	SBFX_LE
 	SBFX
 	SBFX_ZZ
+	SDIV_EQ
+	SDIV_NE
+	SDIV_CS
+	SDIV_CC
+	SDIV_MI
+	SDIV_PL
+	SDIV_VS
+	SDIV_VC
+	SDIV_HI
+	SDIV_LS
+	SDIV_GE
+	SDIV_LT
+	SDIV_GT
+	SDIV_LE
+	SDIV
+	SDIV_ZZ
 	SEL_EQ
 	SEL_NE
 	SEL_CS
@@ -2929,6 +2961,22 @@
 	UBFX_LE
 	UBFX
 	UBFX_ZZ
+	UDIV_EQ
+	UDIV_NE
+	UDIV_CS
+	UDIV_CC
+	UDIV_MI
+	UDIV_PL
+	UDIV_VS
+	UDIV_VC
+	UDIV_HI
+	UDIV_LS
+	UDIV_GE
+	UDIV_LT
+	UDIV_GT
+	UDIV_LE
+	UDIV
+	UDIV_ZZ
 	UHADD16_EQ
 	UHADD16_NE
 	UHADD16_CS
@@ -5480,6 +5528,22 @@
 	MRS_LE:            "MRS.LE",
 	MRS:               "MRS",
 	MRS_ZZ:            "MRS.ZZ",
+	MSR_EQ:            "MSR.EQ",
+	MSR_NE:            "MSR.NE",
+	MSR_CS:            "MSR.CS",
+	MSR_CC:            "MSR.CC",
+	MSR_MI:            "MSR.MI",
+	MSR_PL:            "MSR.PL",
+	MSR_VS:            "MSR.VS",
+	MSR_VC:            "MSR.VC",
+	MSR_HI:            "MSR.HI",
+	MSR_LS:            "MSR.LS",
+	MSR_GE:            "MSR.GE",
+	MSR_LT:            "MSR.LT",
+	MSR_GT:            "MSR.GT",
+	MSR_LE:            "MSR.LE",
+	MSR:               "MSR",
+	MSR_ZZ:            "MSR.ZZ",
 	MUL_EQ:            "MUL.EQ",
 	MUL_NE:            "MUL.NE",
 	MUL_CS:            "MUL.CS",
@@ -6107,6 +6171,22 @@
 	SBFX_LE:           "SBFX.LE",
 	SBFX:              "SBFX",
 	SBFX_ZZ:           "SBFX.ZZ",
+	SDIV_EQ:           "SDIV.EQ",
+	SDIV_NE:           "SDIV.NE",
+	SDIV_CS:           "SDIV.CS",
+	SDIV_CC:           "SDIV.CC",
+	SDIV_MI:           "SDIV.MI",
+	SDIV_PL:           "SDIV.PL",
+	SDIV_VS:           "SDIV.VS",
+	SDIV_VC:           "SDIV.VC",
+	SDIV_HI:           "SDIV.HI",
+	SDIV_LS:           "SDIV.LS",
+	SDIV_GE:           "SDIV.GE",
+	SDIV_LT:           "SDIV.LT",
+	SDIV_GT:           "SDIV.GT",
+	SDIV_LE:           "SDIV.LE",
+	SDIV:              "SDIV",
+	SDIV_ZZ:           "SDIV.ZZ",
 	SEL_EQ:            "SEL.EQ",
 	SEL_NE:            "SEL.NE",
 	SEL_CS:            "SEL.CS",
@@ -7436,6 +7516,22 @@
 	UBFX_LE:           "UBFX.LE",
 	UBFX:              "UBFX",
 	UBFX_ZZ:           "UBFX.ZZ",
+	UDIV_EQ:           "UDIV.EQ",
+	UDIV_NE:           "UDIV.NE",
+	UDIV_CS:           "UDIV.CS",
+	UDIV_CC:           "UDIV.CC",
+	UDIV_MI:           "UDIV.MI",
+	UDIV_PL:           "UDIV.PL",
+	UDIV_VS:           "UDIV.VS",
+	UDIV_VC:           "UDIV.VC",
+	UDIV_HI:           "UDIV.HI",
+	UDIV_LS:           "UDIV.LS",
+	UDIV_GE:           "UDIV.GE",
+	UDIV_LT:           "UDIV.LT",
+	UDIV_GT:           "UDIV.GT",
+	UDIV_LE:           "UDIV.LE",
+	UDIV:              "UDIV",
+	UDIV_ZZ:           "UDIV.ZZ",
 	UHADD16_EQ:        "UHADD16.EQ",
 	UHADD16_NE:        "UHADD16.NE",
 	UHADD16_CS:        "UHADD16.CS",
@@ -9194,6 +9290,10 @@
 	{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)
+	{0x0ffffff0, 0x012cf000, 4, MSR_EQ, 0x1c04, instArgs{arg_APSR, arg_R_0}},                                      // MSR<c> APSR,<Rn> cond:4|0|0|0|1|0|0|1|0|1|1|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|Rn:4
+	{0x0fff00f0, 0x012cf000, 3, MSR_EQ, 0x1c04, instArgs{arg_APSR, arg_R_0}},                                      // MSR<c> APSR,<Rn> cond:4|0|0|0|1|0|0|1|0|1|1|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|Rn:4
+	{0x0ffff000, 0x032cf000, 4, MSR_EQ, 0x1c04, instArgs{arg_APSR, arg_const}},                                    // MSR<c> APSR,#<const> cond:4|0|0|1|1|0|0|1|0|1|1|0|0|(1)|(1)|(1)|(1)|imm12:12
+	{0x0fff0000, 0x032cf000, 3, MSR_EQ, 0x1c04, instArgs{arg_APSR, arg_const}},                                    // MSR<c> APSR,#<const> cond:4|0|0|1|1|0|0|1|0|1|1|0|0|(1)|(1)|(1)|(1)|imm12:12
 	{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
@@ -9267,6 +9367,8 @@
 	{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
+	{0x0ff0f0f0, 0x0710f010, 4, SDIV_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                            // SDIV<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|1|Rd:4|(1)|(1)|(1)|(1)|Rm:4|0|0|0|1|Rn:4
+	{0x0ff000f0, 0x0710f010, 3, SDIV_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                            // SDIV<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|1|Rd:4|(1)|(1)|(1)|(1)|Rm:4|0|0|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)
@@ -9365,6 +9467,8 @@
 	{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
+	{0x0ff0f0f0, 0x0730f010, 4, UDIV_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                            // UDIV<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|1|1|Rd:4|(1)|(1)|(1)|(1)|Rm:4|0|0|0|1|Rn:4
+	{0x0ff000f0, 0x0730f010, 3, UDIV_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                            // UDIV<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|1|1|Rd:4|(1)|(1)|(1)|(1)|Rm:4|0|0|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
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt b/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
index cc1ea0a..f38c61f 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
@@ -304,3 +304,1253 @@
 |6b5721d3	1	gnu	error: unknown instruction
 |76452001	1	gnu	error: unknown instruction
 |97acd647	1	gnu	error: unknown instruction
+11f71507|	1	plan9	SDIV.EQ R7, R1, R5
+15f715e7|	1	plan9	SDIV R7, R5, R5
+11f93517|	1	plan9	UDIV.NE R9, R1, R5
+12fb33e7|	1	plan9	UDIV R11, R2, R3
+ed003be9|	1	plan9	LDMDB [R0,R2-R3,R5-R7], R11!
+923124e0|	1	plan9	MLA R1, R2, R3, R4
+923134e0|	1	plan9	MLA.S R1, R2, R3, R4
+923164e0|	1	plan9	MLS R1, R2, R3, R4
+ff1000e2|	1	plan9	AND $255, R0, R1
+ff1400e2|	1	plan9	AND $4278190080, R0, R1
+ff1010e2|	1	plan9	AND.S $255, R0, R1
+ff1410e2|	1	plan9	AND.S $4278190080, R0, R1
+ff0000e2|	1	plan9	AND $255, R0, R0
+ff0400e2|	1	plan9	AND $4278190080, R0, R0
+ff0010e2|	1	plan9	AND.S $255, R0, R0
+ff0410e2|	1	plan9	AND.S $4278190080, R0, R0
+002001e0|	1	plan9	AND R0, R1, R2
+002011e0|	1	plan9	AND.S R0, R1, R2
+001001e0|	1	plan9	AND R0, R1, R1
+001011e0|	1	plan9	AND.S R0, R1, R1
+202e01e0|	1	plan9	AND R0>>$28, R1, R2
+002e01e0|	1	plan9	AND R0<<$28, R1, R2
+402e01e0|	1	plan9	AND R0->$28, R1, R2
+602e01e0|	1	plan9	AND R0@>$28, R1, R2
+202e11e0|	1	plan9	AND.S R0>>$28, R1, R2
+002e11e0|	1	plan9	AND.S R0<<$28, R1, R2
+402e11e0|	1	plan9	AND.S R0->$28, R1, R2
+602e11e0|	1	plan9	AND.S R0@>$28, R1, R2
+001e01e0|	1	plan9	AND R0<<$28, R1, R1
+201e01e0|	1	plan9	AND R0>>$28, R1, R1
+401e01e0|	1	plan9	AND R0->$28, R1, R1
+601e01e0|	1	plan9	AND R0@>$28, R1, R1
+001e11e0|	1	plan9	AND.S R0<<$28, R1, R1
+201e11e0|	1	plan9	AND.S R0>>$28, R1, R1
+401e11e0|	1	plan9	AND.S R0->$28, R1, R1
+601e11e0|	1	plan9	AND.S R0@>$28, R1, R1
+103102e0|	1	plan9	AND R0<<R1, R2, R3
+303102e0|	1	plan9	AND R0>>R1, R2, R3
+503102e0|	1	plan9	AND R0->R1, R2, R3
+703102e0|	1	plan9	AND R0@>R1, R2, R3
+103112e0|	1	plan9	AND.S R0<<R1, R2, R3
+303112e0|	1	plan9	AND.S R0>>R1, R2, R3
+503112e0|	1	plan9	AND.S R0->R1, R2, R3
+703112e0|	1	plan9	AND.S R0@>R1, R2, R3
+102102e0|	1	plan9	AND R0<<R1, R2, R2
+302102e0|	1	plan9	AND R0>>R1, R2, R2
+502102e0|	1	plan9	AND R0->R1, R2, R2
+702102e0|	1	plan9	AND R0@>R1, R2, R2
+102112e0|	1	plan9	AND.S R0<<R1, R2, R2
+302112e0|	1	plan9	AND.S R0>>R1, R2, R2
+502112e0|	1	plan9	AND.S R0->R1, R2, R2
+702112e0|	1	plan9	AND.S R0@>R1, R2, R2
+ff1020e2|	1	plan9	EOR $255, R0, R1
+ff1420e2|	1	plan9	EOR $4278190080, R0, R1
+ff1030e2|	1	plan9	EOR.S $255, R0, R1
+ff1430e2|	1	plan9	EOR.S $4278190080, R0, R1
+ff0020e2|	1	plan9	EOR $255, R0, R0
+ff0420e2|	1	plan9	EOR $4278190080, R0, R0
+ff0030e2|	1	plan9	EOR.S $255, R0, R0
+ff0430e2|	1	plan9	EOR.S $4278190080, R0, R0
+002021e0|	1	plan9	EOR R0, R1, R2
+002031e0|	1	plan9	EOR.S R0, R1, R2
+001021e0|	1	plan9	EOR R0, R1, R1
+001031e0|	1	plan9	EOR.S R0, R1, R1
+202e21e0|	1	plan9	EOR R0>>$28, R1, R2
+002e21e0|	1	plan9	EOR R0<<$28, R1, R2
+402e21e0|	1	plan9	EOR R0->$28, R1, R2
+602e21e0|	1	plan9	EOR R0@>$28, R1, R2
+202e31e0|	1	plan9	EOR.S R0>>$28, R1, R2
+002e31e0|	1	plan9	EOR.S R0<<$28, R1, R2
+402e31e0|	1	plan9	EOR.S R0->$28, R1, R2
+602e31e0|	1	plan9	EOR.S R0@>$28, R1, R2
+001e21e0|	1	plan9	EOR R0<<$28, R1, R1
+201e21e0|	1	plan9	EOR R0>>$28, R1, R1
+401e21e0|	1	plan9	EOR R0->$28, R1, R1
+601e21e0|	1	plan9	EOR R0@>$28, R1, R1
+001e31e0|	1	plan9	EOR.S R0<<$28, R1, R1
+201e31e0|	1	plan9	EOR.S R0>>$28, R1, R1
+401e31e0|	1	plan9	EOR.S R0->$28, R1, R1
+601e31e0|	1	plan9	EOR.S R0@>$28, R1, R1
+103122e0|	1	plan9	EOR R0<<R1, R2, R3
+303122e0|	1	plan9	EOR R0>>R1, R2, R3
+503122e0|	1	plan9	EOR R0->R1, R2, R3
+703122e0|	1	plan9	EOR R0@>R1, R2, R3
+103132e0|	1	plan9	EOR.S R0<<R1, R2, R3
+303132e0|	1	plan9	EOR.S R0>>R1, R2, R3
+503132e0|	1	plan9	EOR.S R0->R1, R2, R3
+703132e0|	1	plan9	EOR.S R0@>R1, R2, R3
+102122e0|	1	plan9	EOR R0<<R1, R2, R2
+302122e0|	1	plan9	EOR R0>>R1, R2, R2
+502122e0|	1	plan9	EOR R0->R1, R2, R2
+702122e0|	1	plan9	EOR R0@>R1, R2, R2
+102132e0|	1	plan9	EOR.S R0<<R1, R2, R2
+302132e0|	1	plan9	EOR.S R0>>R1, R2, R2
+502132e0|	1	plan9	EOR.S R0->R1, R2, R2
+702132e0|	1	plan9	EOR.S R0@>R1, R2, R2
+ff1080e3|	1	plan9	ORR $255, R0, R1
+ff1480e3|	1	plan9	ORR $4278190080, R0, R1
+ff1090e3|	1	plan9	ORR.S $255, R0, R1
+ff1490e3|	1	plan9	ORR.S $4278190080, R0, R1
+ff0080e3|	1	plan9	ORR $255, R0, R0
+ff0480e3|	1	plan9	ORR $4278190080, R0, R0
+ff0090e3|	1	plan9	ORR.S $255, R0, R0
+ff0490e3|	1	plan9	ORR.S $4278190080, R0, R0
+002081e1|	1	plan9	ORR R0, R1, R2
+002091e1|	1	plan9	ORR.S R0, R1, R2
+001081e1|	1	plan9	ORR R0, R1, R1
+001091e1|	1	plan9	ORR.S R0, R1, R1
+202e81e1|	1	plan9	ORR R0>>$28, R1, R2
+002e81e1|	1	plan9	ORR R0<<$28, R1, R2
+402e81e1|	1	plan9	ORR R0->$28, R1, R2
+602e81e1|	1	plan9	ORR R0@>$28, R1, R2
+202e91e1|	1	plan9	ORR.S R0>>$28, R1, R2
+002e91e1|	1	plan9	ORR.S R0<<$28, R1, R2
+402e91e1|	1	plan9	ORR.S R0->$28, R1, R2
+602e91e1|	1	plan9	ORR.S R0@>$28, R1, R2
+001e81e1|	1	plan9	ORR R0<<$28, R1, R1
+201e81e1|	1	plan9	ORR R0>>$28, R1, R1
+401e81e1|	1	plan9	ORR R0->$28, R1, R1
+601e81e1|	1	plan9	ORR R0@>$28, R1, R1
+001e91e1|	1	plan9	ORR.S R0<<$28, R1, R1
+201e91e1|	1	plan9	ORR.S R0>>$28, R1, R1
+401e91e1|	1	plan9	ORR.S R0->$28, R1, R1
+601e91e1|	1	plan9	ORR.S R0@>$28, R1, R1
+103182e1|	1	plan9	ORR R0<<R1, R2, R3
+303182e1|	1	plan9	ORR R0>>R1, R2, R3
+503182e1|	1	plan9	ORR R0->R1, R2, R3
+703182e1|	1	plan9	ORR R0@>R1, R2, R3
+103192e1|	1	plan9	ORR.S R0<<R1, R2, R3
+303192e1|	1	plan9	ORR.S R0>>R1, R2, R3
+503192e1|	1	plan9	ORR.S R0->R1, R2, R3
+703192e1|	1	plan9	ORR.S R0@>R1, R2, R3
+102182e1|	1	plan9	ORR R0<<R1, R2, R2
+302182e1|	1	plan9	ORR R0>>R1, R2, R2
+502182e1|	1	plan9	ORR R0->R1, R2, R2
+702182e1|	1	plan9	ORR R0@>R1, R2, R2
+102192e1|	1	plan9	ORR.S R0<<R1, R2, R2
+302192e1|	1	plan9	ORR.S R0>>R1, R2, R2
+502192e1|	1	plan9	ORR.S R0->R1, R2, R2
+702192e1|	1	plan9	ORR.S R0@>R1, R2, R2
+ff1040e2|	1	plan9	SUB $255, R0, R1
+ff1440e2|	1	plan9	SUB $4278190080, R0, R1
+ff1050e2|	1	plan9	SUB.S $255, R0, R1
+ff1450e2|	1	plan9	SUB.S $4278190080, R0, R1
+ff0040e2|	1	plan9	SUB $255, R0, R0
+ff0440e2|	1	plan9	SUB $4278190080, R0, R0
+ff0050e2|	1	plan9	SUB.S $255, R0, R0
+ff0450e2|	1	plan9	SUB.S $4278190080, R0, R0
+002041e0|	1	plan9	SUB R0, R1, R2
+002051e0|	1	plan9	SUB.S R0, R1, R2
+001041e0|	1	plan9	SUB R0, R1, R1
+001051e0|	1	plan9	SUB.S R0, R1, R1
+202e41e0|	1	plan9	SUB R0>>$28, R1, R2
+002e41e0|	1	plan9	SUB R0<<$28, R1, R2
+402e41e0|	1	plan9	SUB R0->$28, R1, R2
+602e41e0|	1	plan9	SUB R0@>$28, R1, R2
+202e51e0|	1	plan9	SUB.S R0>>$28, R1, R2
+002e51e0|	1	plan9	SUB.S R0<<$28, R1, R2
+402e51e0|	1	plan9	SUB.S R0->$28, R1, R2
+602e51e0|	1	plan9	SUB.S R0@>$28, R1, R2
+001e41e0|	1	plan9	SUB R0<<$28, R1, R1
+201e41e0|	1	plan9	SUB R0>>$28, R1, R1
+401e41e0|	1	plan9	SUB R0->$28, R1, R1
+601e41e0|	1	plan9	SUB R0@>$28, R1, R1
+001e51e0|	1	plan9	SUB.S R0<<$28, R1, R1
+201e51e0|	1	plan9	SUB.S R0>>$28, R1, R1
+401e51e0|	1	plan9	SUB.S R0->$28, R1, R1
+601e51e0|	1	plan9	SUB.S R0@>$28, R1, R1
+103142e0|	1	plan9	SUB R0<<R1, R2, R3
+303142e0|	1	plan9	SUB R0>>R1, R2, R3
+503142e0|	1	plan9	SUB R0->R1, R2, R3
+703142e0|	1	plan9	SUB R0@>R1, R2, R3
+103152e0|	1	plan9	SUB.S R0<<R1, R2, R3
+303152e0|	1	plan9	SUB.S R0>>R1, R2, R3
+503152e0|	1	plan9	SUB.S R0->R1, R2, R3
+703152e0|	1	plan9	SUB.S R0@>R1, R2, R3
+102142e0|	1	plan9	SUB R0<<R1, R2, R2
+302142e0|	1	plan9	SUB R0>>R1, R2, R2
+502142e0|	1	plan9	SUB R0->R1, R2, R2
+702142e0|	1	plan9	SUB R0@>R1, R2, R2
+102152e0|	1	plan9	SUB.S R0<<R1, R2, R2
+302152e0|	1	plan9	SUB.S R0>>R1, R2, R2
+502152e0|	1	plan9	SUB.S R0->R1, R2, R2
+702152e0|	1	plan9	SUB.S R0@>R1, R2, R2
+ff10c0e2|	1	plan9	SBC $255, R0, R1
+ff14c0e2|	1	plan9	SBC $4278190080, R0, R1
+ff10d0e2|	1	plan9	SBC.S $255, R0, R1
+ff14d0e2|	1	plan9	SBC.S $4278190080, R0, R1
+ff00c0e2|	1	plan9	SBC $255, R0, R0
+ff04c0e2|	1	plan9	SBC $4278190080, R0, R0
+ff00d0e2|	1	plan9	SBC.S $255, R0, R0
+ff04d0e2|	1	plan9	SBC.S $4278190080, R0, R0
+0020c1e0|	1	plan9	SBC R0, R1, R2
+0020d1e0|	1	plan9	SBC.S R0, R1, R2
+0010c1e0|	1	plan9	SBC R0, R1, R1
+0010d1e0|	1	plan9	SBC.S R0, R1, R1
+202ec1e0|	1	plan9	SBC R0>>$28, R1, R2
+002ec1e0|	1	plan9	SBC R0<<$28, R1, R2
+402ec1e0|	1	plan9	SBC R0->$28, R1, R2
+602ec1e0|	1	plan9	SBC R0@>$28, R1, R2
+202ed1e0|	1	plan9	SBC.S R0>>$28, R1, R2
+002ed1e0|	1	plan9	SBC.S R0<<$28, R1, R2
+402ed1e0|	1	plan9	SBC.S R0->$28, R1, R2
+602ed1e0|	1	plan9	SBC.S R0@>$28, R1, R2
+001ec1e0|	1	plan9	SBC R0<<$28, R1, R1
+201ec1e0|	1	plan9	SBC R0>>$28, R1, R1
+401ec1e0|	1	plan9	SBC R0->$28, R1, R1
+601ec1e0|	1	plan9	SBC R0@>$28, R1, R1
+001ed1e0|	1	plan9	SBC.S R0<<$28, R1, R1
+201ed1e0|	1	plan9	SBC.S R0>>$28, R1, R1
+401ed1e0|	1	plan9	SBC.S R0->$28, R1, R1
+601ed1e0|	1	plan9	SBC.S R0@>$28, R1, R1
+1031c2e0|	1	plan9	SBC R0<<R1, R2, R3
+3031c2e0|	1	plan9	SBC R0>>R1, R2, R3
+5031c2e0|	1	plan9	SBC R0->R1, R2, R3
+7031c2e0|	1	plan9	SBC R0@>R1, R2, R3
+1031d2e0|	1	plan9	SBC.S R0<<R1, R2, R3
+3031d2e0|	1	plan9	SBC.S R0>>R1, R2, R3
+5031d2e0|	1	plan9	SBC.S R0->R1, R2, R3
+7031d2e0|	1	plan9	SBC.S R0@>R1, R2, R3
+1021c2e0|	1	plan9	SBC R0<<R1, R2, R2
+3021c2e0|	1	plan9	SBC R0>>R1, R2, R2
+5021c2e0|	1	plan9	SBC R0->R1, R2, R2
+7021c2e0|	1	plan9	SBC R0@>R1, R2, R2
+1021d2e0|	1	plan9	SBC.S R0<<R1, R2, R2
+3021d2e0|	1	plan9	SBC.S R0>>R1, R2, R2
+5021d2e0|	1	plan9	SBC.S R0->R1, R2, R2
+7021d2e0|	1	plan9	SBC.S R0@>R1, R2, R2
+ff1060e2|	1	plan9	RSB $255, R0, R1
+ff1460e2|	1	plan9	RSB $4278190080, R0, R1
+ff1070e2|	1	plan9	RSB.S $255, R0, R1
+ff1470e2|	1	plan9	RSB.S $4278190080, R0, R1
+ff0060e2|	1	plan9	RSB $255, R0, R0
+ff0460e2|	1	plan9	RSB $4278190080, R0, R0
+ff0070e2|	1	plan9	RSB.S $255, R0, R0
+ff0470e2|	1	plan9	RSB.S $4278190080, R0, R0
+002061e0|	1	plan9	RSB R0, R1, R2
+002071e0|	1	plan9	RSB.S R0, R1, R2
+001061e0|	1	plan9	RSB R0, R1, R1
+001071e0|	1	plan9	RSB.S R0, R1, R1
+202e61e0|	1	plan9	RSB R0>>$28, R1, R2
+002e61e0|	1	plan9	RSB R0<<$28, R1, R2
+402e61e0|	1	plan9	RSB R0->$28, R1, R2
+602e61e0|	1	plan9	RSB R0@>$28, R1, R2
+202e71e0|	1	plan9	RSB.S R0>>$28, R1, R2
+002e71e0|	1	plan9	RSB.S R0<<$28, R1, R2
+402e71e0|	1	plan9	RSB.S R0->$28, R1, R2
+602e71e0|	1	plan9	RSB.S R0@>$28, R1, R2
+001e61e0|	1	plan9	RSB R0<<$28, R1, R1
+201e61e0|	1	plan9	RSB R0>>$28, R1, R1
+401e61e0|	1	plan9	RSB R0->$28, R1, R1
+601e61e0|	1	plan9	RSB R0@>$28, R1, R1
+001e71e0|	1	plan9	RSB.S R0<<$28, R1, R1
+201e71e0|	1	plan9	RSB.S R0>>$28, R1, R1
+401e71e0|	1	plan9	RSB.S R0->$28, R1, R1
+601e71e0|	1	plan9	RSB.S R0@>$28, R1, R1
+103162e0|	1	plan9	RSB R0<<R1, R2, R3
+303162e0|	1	plan9	RSB R0>>R1, R2, R3
+503162e0|	1	plan9	RSB R0->R1, R2, R3
+703162e0|	1	plan9	RSB R0@>R1, R2, R3
+103172e0|	1	plan9	RSB.S R0<<R1, R2, R3
+303172e0|	1	plan9	RSB.S R0>>R1, R2, R3
+503172e0|	1	plan9	RSB.S R0->R1, R2, R3
+703172e0|	1	plan9	RSB.S R0@>R1, R2, R3
+102162e0|	1	plan9	RSB R0<<R1, R2, R2
+302162e0|	1	plan9	RSB R0>>R1, R2, R2
+502162e0|	1	plan9	RSB R0->R1, R2, R2
+702162e0|	1	plan9	RSB R0@>R1, R2, R2
+102172e0|	1	plan9	RSB.S R0<<R1, R2, R2
+302172e0|	1	plan9	RSB.S R0>>R1, R2, R2
+502172e0|	1	plan9	RSB.S R0->R1, R2, R2
+702172e0|	1	plan9	RSB.S R0@>R1, R2, R2
+ff10e0e2|	1	plan9	RSC $255, R0, R1
+ff14e0e2|	1	plan9	RSC $4278190080, R0, R1
+ff10f0e2|	1	plan9	RSC.S $255, R0, R1
+ff14f0e2|	1	plan9	RSC.S $4278190080, R0, R1
+ff00e0e2|	1	plan9	RSC $255, R0, R0
+ff04e0e2|	1	plan9	RSC $4278190080, R0, R0
+ff00f0e2|	1	plan9	RSC.S $255, R0, R0
+ff04f0e2|	1	plan9	RSC.S $4278190080, R0, R0
+0020e1e0|	1	plan9	RSC R0, R1, R2
+0020f1e0|	1	plan9	RSC.S R0, R1, R2
+0010e1e0|	1	plan9	RSC R0, R1, R1
+0010f1e0|	1	plan9	RSC.S R0, R1, R1
+202ee1e0|	1	plan9	RSC R0>>$28, R1, R2
+002ee1e0|	1	plan9	RSC R0<<$28, R1, R2
+402ee1e0|	1	plan9	RSC R0->$28, R1, R2
+602ee1e0|	1	plan9	RSC R0@>$28, R1, R2
+202ef1e0|	1	plan9	RSC.S R0>>$28, R1, R2
+002ef1e0|	1	plan9	RSC.S R0<<$28, R1, R2
+402ef1e0|	1	plan9	RSC.S R0->$28, R1, R2
+602ef1e0|	1	plan9	RSC.S R0@>$28, R1, R2
+001ee1e0|	1	plan9	RSC R0<<$28, R1, R1
+201ee1e0|	1	plan9	RSC R0>>$28, R1, R1
+401ee1e0|	1	plan9	RSC R0->$28, R1, R1
+601ee1e0|	1	plan9	RSC R0@>$28, R1, R1
+001ef1e0|	1	plan9	RSC.S R0<<$28, R1, R1
+201ef1e0|	1	plan9	RSC.S R0>>$28, R1, R1
+401ef1e0|	1	plan9	RSC.S R0->$28, R1, R1
+601ef1e0|	1	plan9	RSC.S R0@>$28, R1, R1
+1031e2e0|	1	plan9	RSC R0<<R1, R2, R3
+3031e2e0|	1	plan9	RSC R0>>R1, R2, R3
+5031e2e0|	1	plan9	RSC R0->R1, R2, R3
+7031e2e0|	1	plan9	RSC R0@>R1, R2, R3
+1031f2e0|	1	plan9	RSC.S R0<<R1, R2, R3
+3031f2e0|	1	plan9	RSC.S R0>>R1, R2, R3
+5031f2e0|	1	plan9	RSC.S R0->R1, R2, R3
+7031f2e0|	1	plan9	RSC.S R0@>R1, R2, R3
+1021e2e0|	1	plan9	RSC R0<<R1, R2, R2
+3021e2e0|	1	plan9	RSC R0>>R1, R2, R2
+5021e2e0|	1	plan9	RSC R0->R1, R2, R2
+7021e2e0|	1	plan9	RSC R0@>R1, R2, R2
+1021f2e0|	1	plan9	RSC.S R0<<R1, R2, R2
+3021f2e0|	1	plan9	RSC.S R0>>R1, R2, R2
+5021f2e0|	1	plan9	RSC.S R0->R1, R2, R2
+7021f2e0|	1	plan9	RSC.S R0@>R1, R2, R2
+ff1080e2|	1	plan9	ADD $255, R0, R1
+ff1480e2|	1	plan9	ADD $4278190080, R0, R1
+ff1090e2|	1	plan9	ADD.S $255, R0, R1
+ff1490e2|	1	plan9	ADD.S $4278190080, R0, R1
+ff0080e2|	1	plan9	ADD $255, R0, R0
+ff0480e2|	1	plan9	ADD $4278190080, R0, R0
+ff0090e2|	1	plan9	ADD.S $255, R0, R0
+ff0490e2|	1	plan9	ADD.S $4278190080, R0, R0
+002081e0|	1	plan9	ADD R0, R1, R2
+002091e0|	1	plan9	ADD.S R0, R1, R2
+001081e0|	1	plan9	ADD R0, R1, R1
+001091e0|	1	plan9	ADD.S R0, R1, R1
+202e81e0|	1	plan9	ADD R0>>$28, R1, R2
+002e81e0|	1	plan9	ADD R0<<$28, R1, R2
+402e81e0|	1	plan9	ADD R0->$28, R1, R2
+602e81e0|	1	plan9	ADD R0@>$28, R1, R2
+202e91e0|	1	plan9	ADD.S R0>>$28, R1, R2
+002e91e0|	1	plan9	ADD.S R0<<$28, R1, R2
+402e91e0|	1	plan9	ADD.S R0->$28, R1, R2
+602e91e0|	1	plan9	ADD.S R0@>$28, R1, R2
+001e81e0|	1	plan9	ADD R0<<$28, R1, R1
+201e81e0|	1	plan9	ADD R0>>$28, R1, R1
+401e81e0|	1	plan9	ADD R0->$28, R1, R1
+601e81e0|	1	plan9	ADD R0@>$28, R1, R1
+001e91e0|	1	plan9	ADD.S R0<<$28, R1, R1
+201e91e0|	1	plan9	ADD.S R0>>$28, R1, R1
+401e91e0|	1	plan9	ADD.S R0->$28, R1, R1
+601e91e0|	1	plan9	ADD.S R0@>$28, R1, R1
+103182e0|	1	plan9	ADD R0<<R1, R2, R3
+303182e0|	1	plan9	ADD R0>>R1, R2, R3
+503182e0|	1	plan9	ADD R0->R1, R2, R3
+703182e0|	1	plan9	ADD R0@>R1, R2, R3
+103192e0|	1	plan9	ADD.S R0<<R1, R2, R3
+303192e0|	1	plan9	ADD.S R0>>R1, R2, R3
+503192e0|	1	plan9	ADD.S R0->R1, R2, R3
+703192e0|	1	plan9	ADD.S R0@>R1, R2, R3
+102182e0|	1	plan9	ADD R0<<R1, R2, R2
+302182e0|	1	plan9	ADD R0>>R1, R2, R2
+502182e0|	1	plan9	ADD R0->R1, R2, R2
+702182e0|	1	plan9	ADD R0@>R1, R2, R2
+102192e0|	1	plan9	ADD.S R0<<R1, R2, R2
+302192e0|	1	plan9	ADD.S R0>>R1, R2, R2
+502192e0|	1	plan9	ADD.S R0->R1, R2, R2
+702192e0|	1	plan9	ADD.S R0@>R1, R2, R2
+ff10a0e2|	1	plan9	ADC $255, R0, R1
+ff14a0e2|	1	plan9	ADC $4278190080, R0, R1
+ff10b0e2|	1	plan9	ADC.S $255, R0, R1
+ff14b0e2|	1	plan9	ADC.S $4278190080, R0, R1
+ff00a0e2|	1	plan9	ADC $255, R0, R0
+ff04a0e2|	1	plan9	ADC $4278190080, R0, R0
+ff00b0e2|	1	plan9	ADC.S $255, R0, R0
+ff04b0e2|	1	plan9	ADC.S $4278190080, R0, R0
+0020a1e0|	1	plan9	ADC R0, R1, R2
+0020b1e0|	1	plan9	ADC.S R0, R1, R2
+0010a1e0|	1	plan9	ADC R0, R1, R1
+0010b1e0|	1	plan9	ADC.S R0, R1, R1
+202ea1e0|	1	plan9	ADC R0>>$28, R1, R2
+002ea1e0|	1	plan9	ADC R0<<$28, R1, R2
+402ea1e0|	1	plan9	ADC R0->$28, R1, R2
+602ea1e0|	1	plan9	ADC R0@>$28, R1, R2
+202eb1e0|	1	plan9	ADC.S R0>>$28, R1, R2
+002eb1e0|	1	plan9	ADC.S R0<<$28, R1, R2
+402eb1e0|	1	plan9	ADC.S R0->$28, R1, R2
+602eb1e0|	1	plan9	ADC.S R0@>$28, R1, R2
+001ea1e0|	1	plan9	ADC R0<<$28, R1, R1
+201ea1e0|	1	plan9	ADC R0>>$28, R1, R1
+401ea1e0|	1	plan9	ADC R0->$28, R1, R1
+601ea1e0|	1	plan9	ADC R0@>$28, R1, R1
+001eb1e0|	1	plan9	ADC.S R0<<$28, R1, R1
+201eb1e0|	1	plan9	ADC.S R0>>$28, R1, R1
+401eb1e0|	1	plan9	ADC.S R0->$28, R1, R1
+601eb1e0|	1	plan9	ADC.S R0@>$28, R1, R1
+1031a2e0|	1	plan9	ADC R0<<R1, R2, R3
+3031a2e0|	1	plan9	ADC R0>>R1, R2, R3
+5031a2e0|	1	plan9	ADC R0->R1, R2, R3
+7031a2e0|	1	plan9	ADC R0@>R1, R2, R3
+1031b2e0|	1	plan9	ADC.S R0<<R1, R2, R3
+3031b2e0|	1	plan9	ADC.S R0>>R1, R2, R3
+5031b2e0|	1	plan9	ADC.S R0->R1, R2, R3
+7031b2e0|	1	plan9	ADC.S R0@>R1, R2, R3
+1021a2e0|	1	plan9	ADC R0<<R1, R2, R2
+3021a2e0|	1	plan9	ADC R0>>R1, R2, R2
+5021a2e0|	1	plan9	ADC R0->R1, R2, R2
+7021a2e0|	1	plan9	ADC R0@>R1, R2, R2
+1021b2e0|	1	plan9	ADC.S R0<<R1, R2, R2
+3021b2e0|	1	plan9	ADC.S R0>>R1, R2, R2
+5021b2e0|	1	plan9	ADC.S R0->R1, R2, R2
+7021b2e0|	1	plan9	ADC.S R0@>R1, R2, R2
+ff0037e3|	1	plan9	TEQ $255, R7
+ff0439e3|	1	plan9	TEQ $4278190080, R9
+090f37e1|	1	plan9	TEQ R9<<$30, R7
+290f37e1|	1	plan9	TEQ R9>>$30, R7
+490f37e1|	1	plan9	TEQ R9->$30, R7
+690f37e1|	1	plan9	TEQ R9@>$30, R7
+190837e1|	1	plan9	TEQ R9<<R8, R7
+390837e1|	1	plan9	TEQ R9>>R8, R7
+590837e1|	1	plan9	TEQ R9->R8, R7
+790837e1|	1	plan9	TEQ R9@>R8, R7
+ff0017e3|	1	plan9	TST $255, R7
+ff0419e3|	1	plan9	TST $4278190080, R9
+090f17e1|	1	plan9	TST R9<<$30, R7
+290f17e1|	1	plan9	TST R9>>$30, R7
+490f17e1|	1	plan9	TST R9->$30, R7
+690f17e1|	1	plan9	TST R9@>$30, R7
+190817e1|	1	plan9	TST R9<<R8, R7
+390817e1|	1	plan9	TST R9>>R8, R7
+590817e1|	1	plan9	TST R9->R8, R7
+790817e1|	1	plan9	TST R9@>R8, R7
+ff0057e3|	1	plan9	CMP $255, R7
+ff0459e3|	1	plan9	CMP $4278190080, R9
+090f57e1|	1	plan9	CMP R9<<$30, R7
+290f57e1|	1	plan9	CMP R9>>$30, R7
+490f57e1|	1	plan9	CMP R9->$30, R7
+690f57e1|	1	plan9	CMP R9@>$30, R7
+190857e1|	1	plan9	CMP R9<<R8, R7
+390857e1|	1	plan9	CMP R9>>R8, R7
+590857e1|	1	plan9	CMP R9->R8, R7
+790857e1|	1	plan9	CMP R9@>R8, R7
+ff0077e3|	1	plan9	CMN $255, R7
+ff0479e3|	1	plan9	CMN $4278190080, R9
+090f77e1|	1	plan9	CMN R9<<$30, R7
+290f77e1|	1	plan9	CMN R9>>$30, R7
+490f77e1|	1	plan9	CMN R9->$30, R7
+690f77e1|	1	plan9	CMN R9@>$30, R7
+190877e1|	1	plan9	CMN R9<<R8, R7
+390877e1|	1	plan9	CMN R9>>R8, R7
+590877e1|	1	plan9	CMN R9->R8, R7
+790877e1|	1	plan9	CMN R9@>R8, R7
+0c00000a|	1	plan9	B.EQ 0x38
+0b00001a|	1	plan9	B.NE 0x34
+0a00002a|	1	plan9	B.CS 0x30
+0900003a|	1	plan9	B.CC 0x2c
+0800004a|	1	plan9	B.MI 0x28
+0700005a|	1	plan9	B.PL 0x24
+0600006a|	1	plan9	B.VS 0x20
+0500007a|	1	plan9	B.VC 0x1c
+0400008a|	1	plan9	B.HI 0x18
+0300009a|	1	plan9	B.LS 0x14
+020000aa|	1	plan9	B.GE 0x10
+010000ba|	1	plan9	B.LT 0xc
+000000ca|	1	plan9	B.GT 0x8
+ffffffda|	1	plan9	B.LE 0x4
+fdffffea|	1	plan9	B 0xfffffffc
+fcffffea|	1	plan9	B 0xfffffff8
+fbffffea|	1	plan9	B 0xfffffff4
+faffffea|	1	plan9	B 0xfffffff0
+f9ffffea|	1	plan9	B 0xffffffec
+feffffea|	1	plan9	B 0x0
+0c00000b|	1	plan9	BL.EQ 0x38
+0b00001b|	1	plan9	BL.NE 0x34
+0a00002b|	1	plan9	BL.CS 0x30
+0900003b|	1	plan9	BL.CC 0x2c
+0800004b|	1	plan9	BL.MI 0x28
+0700005b|	1	plan9	BL.PL 0x24
+0600006b|	1	plan9	BL.VS 0x20
+0500007b|	1	plan9	BL.VC 0x1c
+0400008b|	1	plan9	BL.HI 0x18
+0300009b|	1	plan9	BL.LS 0x14
+020000ab|	1	plan9	BL.GE 0x10
+010000bb|	1	plan9	BL.LT 0xc
+000000cb|	1	plan9	BL.GT 0x8
+ffffffdb|	1	plan9	BL.LE 0x4
+fdffffeb|	1	plan9	BL 0xfffffffc
+fcffffeb|	1	plan9	BL 0xfffffff8
+fbffffeb|	1	plan9	BL 0xfffffff4
+faffffeb|	1	plan9	BL 0xfffffff0
+f9ffffeb|	1	plan9	BL 0xffffffec
+feffffeb|	1	plan9	BL 0x0
+ff10c0e3|	1	plan9	BIC $255, R0, R1
+ff14c0e3|	1	plan9	BIC $4278190080, R0, R1
+ff10d0e3|	1	plan9	BIC.S $255, R0, R1
+ff14d0e3|	1	plan9	BIC.S $4278190080, R0, R1
+ff00c0e3|	1	plan9	BIC $255, R0, R0
+ff04c0e3|	1	plan9	BIC $4278190080, R0, R0
+ff00d0e3|	1	plan9	BIC.S $255, R0, R0
+ff04d0e3|	1	plan9	BIC.S $4278190080, R0, R0
+0020c1e1|	1	plan9	BIC R0, R1, R2
+0020d1e1|	1	plan9	BIC.S R0, R1, R2
+0010c1e1|	1	plan9	BIC R0, R1, R1
+0010d1e1|	1	plan9	BIC.S R0, R1, R1
+202ec1e1|	1	plan9	BIC R0>>$28, R1, R2
+002ec1e1|	1	plan9	BIC R0<<$28, R1, R2
+402ec1e1|	1	plan9	BIC R0->$28, R1, R2
+602ec1e1|	1	plan9	BIC R0@>$28, R1, R2
+202ed1e1|	1	plan9	BIC.S R0>>$28, R1, R2
+002ed1e1|	1	plan9	BIC.S R0<<$28, R1, R2
+402ed1e1|	1	plan9	BIC.S R0->$28, R1, R2
+602ed1e1|	1	plan9	BIC.S R0@>$28, R1, R2
+001ec1e1|	1	plan9	BIC R0<<$28, R1, R1
+201ec1e1|	1	plan9	BIC R0>>$28, R1, R1
+401ec1e1|	1	plan9	BIC R0->$28, R1, R1
+601ec1e1|	1	plan9	BIC R0@>$28, R1, R1
+001ed1e1|	1	plan9	BIC.S R0<<$28, R1, R1
+201ed1e1|	1	plan9	BIC.S R0>>$28, R1, R1
+401ed1e1|	1	plan9	BIC.S R0->$28, R1, R1
+601ed1e1|	1	plan9	BIC.S R0@>$28, R1, R1
+1031c2e1|	1	plan9	BIC R0<<R1, R2, R3
+3031c2e1|	1	plan9	BIC R0>>R1, R2, R3
+5031c2e1|	1	plan9	BIC R0->R1, R2, R3
+7031c2e1|	1	plan9	BIC R0@>R1, R2, R3
+1031d2e1|	1	plan9	BIC.S R0<<R1, R2, R3
+3031d2e1|	1	plan9	BIC.S R0>>R1, R2, R3
+5031d2e1|	1	plan9	BIC.S R0->R1, R2, R3
+7031d2e1|	1	plan9	BIC.S R0@>R1, R2, R3
+1021c2e1|	1	plan9	BIC R0<<R1, R2, R2
+3021c2e1|	1	plan9	BIC R0>>R1, R2, R2
+5021c2e1|	1	plan9	BIC R0->R1, R2, R2
+7021c2e1|	1	plan9	BIC R0@>R1, R2, R2
+1021d2e1|	1	plan9	BIC.S R0<<R1, R2, R2
+3021d2e1|	1	plan9	BIC.S R0>>R1, R2, R2
+5021d2e1|	1	plan9	BIC.S R0->R1, R2, R2
+7021d2e1|	1	plan9	BIC.S R0@>R1, R2, R2
+2567a0e1|	1	plan9	LSR $14, R5, R6
+a567a0e1|	1	plan9	LSR $15, R5, R6
+256fa0e1|	1	plan9	LSR $30, R5, R6
+a56fa0e1|	1	plan9	LSR $31, R5, R6
+2567b0e1|	1	plan9	LSR.S $14, R5, R6
+a567b0e1|	1	plan9	LSR.S $15, R5, R6
+256fb0e1|	1	plan9	LSR.S $30, R5, R6
+a56fb0e1|	1	plan9	LSR.S $31, R5, R6
+2557a0e1|	1	plan9	LSR $14, R5, R5
+a557a0e1|	1	plan9	LSR $15, R5, R5
+255fa0e1|	1	plan9	LSR $30, R5, R5
+a55fa0e1|	1	plan9	LSR $31, R5, R5
+2557b0e1|	1	plan9	LSR.S $14, R5, R5
+a557b0e1|	1	plan9	LSR.S $15, R5, R5
+255fb0e1|	1	plan9	LSR.S $30, R5, R5
+a55fb0e1|	1	plan9	LSR.S $31, R5, R5
+3675a0e1|	1	plan9	LSR R5, R6, R7
+3675b0e1|	1	plan9	LSR.S R5, R6, R7
+3775a0e1|	1	plan9	LSR R5, R7, R7
+3775b0e1|	1	plan9	LSR.S R5, R7, R7
+4567a0e1|	1	plan9	ASR $14, R5, R6
+c567a0e1|	1	plan9	ASR $15, R5, R6
+456fa0e1|	1	plan9	ASR $30, R5, R6
+c56fa0e1|	1	plan9	ASR $31, R5, R6
+4567b0e1|	1	plan9	ASR.S $14, R5, R6
+c567b0e1|	1	plan9	ASR.S $15, R5, R6
+456fb0e1|	1	plan9	ASR.S $30, R5, R6
+c56fb0e1|	1	plan9	ASR.S $31, R5, R6
+4557a0e1|	1	plan9	ASR $14, R5, R5
+c557a0e1|	1	plan9	ASR $15, R5, R5
+455fa0e1|	1	plan9	ASR $30, R5, R5
+c55fa0e1|	1	plan9	ASR $31, R5, R5
+4557b0e1|	1	plan9	ASR.S $14, R5, R5
+c557b0e1|	1	plan9	ASR.S $15, R5, R5
+455fb0e1|	1	plan9	ASR.S $30, R5, R5
+c55fb0e1|	1	plan9	ASR.S $31, R5, R5
+5675a0e1|	1	plan9	ASR R5, R6, R7
+5675b0e1|	1	plan9	ASR.S R5, R6, R7
+5775a0e1|	1	plan9	ASR R5, R7, R7
+5775b0e1|	1	plan9	ASR.S R5, R7, R7
+0567a0e1|	1	plan9	LSL $14, R5, R6
+8567a0e1|	1	plan9	LSL $15, R5, R6
+056fa0e1|	1	plan9	LSL $30, R5, R6
+856fa0e1|	1	plan9	LSL $31, R5, R6
+0567b0e1|	1	plan9	LSL.S $14, R5, R6
+8567b0e1|	1	plan9	LSL.S $15, R5, R6
+056fb0e1|	1	plan9	LSL.S $30, R5, R6
+856fb0e1|	1	plan9	LSL.S $31, R5, R6
+0557a0e1|	1	plan9	LSL $14, R5, R5
+8557a0e1|	1	plan9	LSL $15, R5, R5
+055fa0e1|	1	plan9	LSL $30, R5, R5
+855fa0e1|	1	plan9	LSL $31, R5, R5
+0557b0e1|	1	plan9	LSL.S $14, R5, R5
+8557b0e1|	1	plan9	LSL.S $15, R5, R5
+055fb0e1|	1	plan9	LSL.S $30, R5, R5
+855fb0e1|	1	plan9	LSL.S $31, R5, R5
+1675a0e1|	1	plan9	LSL R5, R6, R7
+1675b0e1|	1	plan9	LSL.S R5, R6, R7
+1775a0e1|	1	plan9	LSL R5, R7, R7
+1775b0e1|	1	plan9	LSL.S R5, R7, R7
+c23124e1|	1	plan9	SMLAWT R1, R2, R3, R4
+823124e1|	1	plan9	SMLAWB R1, R2, R3, R4
+923164e0|	1	plan9	MLS R1, R2, R3, R4
+923124e0|	1	plan9	MLA R1, R2, R3, R4
+923134e0|	1	plan9	MLA.S R1, R2, R3, R4
+123154e7|	1	plan9	SMMLA R1, R2, R3, R4
+d23154e7|	1	plan9	SMMLS R1, R2, R3, R4
+823104e1|	1	plan9	SMLABB R1, R2, R3, R4
+a23104e1|	1	plan9	SMLATB R1, R2, R3, R4
+c23104e1|	1	plan9	SMLABT R1, R2, R3, R4
+e23104e1|	1	plan9	SMLATT R1, R2, R3, R4
+123104e7|	1	plan9	SMLAD R1, R2, R3, R4
+323104e7|	1	plan9	SMLAD.X R1, R2, R3, R4
+523104e7|	1	plan9	SMLSD R1, R2, R3, R4
+723104e7|	1	plan9	SMLSD.X R1, R2, R3, R4
+9231e4e0|	1	plan9	SMLAL R1, R2, R4, R3
+9231f4e0|	1	plan9	SMLAL.S R1, R2, R4, R3
+123144e7|	1	plan9	SMLALD R1, R2, R4, R3
+323144e7|	1	plan9	SMLALD.X R1, R2, R4, R3
+523144e7|	1	plan9	SMLSLD R1, R2, R4, R3
+723144e7|	1	plan9	SMLSLD.X R1, R2, R4, R3
+9231a4e0|	1	plan9	UMLAL R1, R2, R4, R3
+923144e0|	1	plan9	UMAAL R1, R2, R4, R3
+9231b4e0|	1	plan9	UMLAL.S R1, R2, R4, R3
+930204e0|	1	plan9	MUL R2, R3, R4
+920404e0|	1	plan9	MUL R4, R2, R4
+930214e0|	1	plan9	MUL.S R2, R3, R4
+920414e0|	1	plan9	MUL.S R4, R2, R4
+960507e0|	1	plan9	MUL R5, R6, R7
+950707e0|	1	plan9	MUL R7, R5, R7
+960517e0|	1	plan9	MUL.S R5, R6, R7
+950717e0|	1	plan9	MUL.S R7, R5, R7
+923184e0|	1	plan9	UMULL R1, R2, R4, R3
+923194e0|	1	plan9	UMULL.S R1, R2, R4, R3
+9231c4e0|	1	plan9	SMULL R1, R2, R4, R3
+9231d4e0|	1	plan9	SMULL.S R1, R2, R4, R3
+12f153e7|	1	plan9	SMMUL R1, R2, R3
+820163e1|	1	plan9	SMULBB R1, R2, R3
+a20163e1|	1	plan9	SMULTB R1, R2, R3
+c20163e1|	1	plan9	SMULBT R1, R2, R3
+e20163e1|	1	plan9	SMULTT R1, R2, R3
+a20123e1|	1	plan9	SMULWB R1, R2, R3
+e20123e1|	1	plan9	SMULWT R1, R2, R3
+12f103e7|	1	plan9	SMUAD R1, R2, R3
+32f103e7|	1	plan9	SMUAD.X R1, R2, R3
+52f103e7|	1	plan9	SMUSD R1, R2, R3
+72f103e7|	1	plan9	SMUSD.X R1, R2, R3
+312fbfe6|	1	plan9	REV R1, R2
+b12fbfe6|	1	plan9	REV16 R1, R2
+b12fffe6|	1	plan9	REVSH R1, R2
+312fffe6|	1	plan9	RBIT R1, R2
+112f6fe1|	1	plan9	CLZ R1, R2
+f0ffd6f5|	1	gnu	pld [r6, #4080]
+f0ff59f5|	1	gnu	pld [r9, #-4080]
+f0ff96f5|	1	gnu	pldw [r6, #4080]
+f0ff19f5|	1	gnu	pldw [r9, #-4080]
+f0ffdff5|	1	gnu	pld [pc, #4080]
+f0ff5ff5|	1	gnu	pld [pc, #-4080]
+00f0d2f7|	1	gnu	pld [r2, r0]
+00f052f7|	1	gnu	pld [r2, -r0]
+00f092f7|	1	gnu	pldw [r2, r0]
+00f012f7|	1	gnu	pldw [r2, -r0]
+80f0d2f7|	1	gnu	pld [r2, r0, lsl #1]
+80f052f7|	1	gnu	pld [r2, -r0, lsl #1]
+a0f0d2f7|	1	gnu	pld [r2, r0, lsr #1]
+a0f052f7|	1	gnu	pld [r2, -r0, lsr #1]
+c0f0d2f7|	1	gnu	pld [r2, r0, asr #1]
+c0f052f7|	1	gnu	pld [r2, -r0, asr #1]
+e0f0d2f7|	1	gnu	pld [r2, r0, ror #1]
+e0f052f7|	1	gnu	pld [r2, -r0, ror #1]
+80f092f7|	1	gnu	pldw [r2, r0, lsl #1]
+80f012f7|	1	gnu	pldw [r2, -r0, lsl #1]
+a0f092f7|	1	gnu	pldw [r2, r0, lsr #1]
+a0f012f7|	1	gnu	pldw [r2, -r0, lsr #1]
+c0f092f7|	1	gnu	pldw [r2, r0, asr #1]
+c0f012f7|	1	gnu	pldw [r2, -r0, asr #1]
+e0f092f7|	1	gnu	pldw [r2, r0, ror #1]
+e0f012f7|	1	gnu	pldw [r2, -r0, ror #1]
+f0ffd2f4|	1	gnu	pli [r2, #4080]
+f0ff52f4|	1	gnu	pli [r2, #-4080]
+82f0d3f6|	1	gnu	pli [r3, r2, lsl #1]
+82f053f6|	1	gnu	pli [r3, -r2, lsl #1]
+a2f0d3f6|	1	gnu	pli [r3, r2, lsr #1]
+a2f053f6|	1	gnu	pli [r3, -r2, lsr #1]
+c2f0d3f6|	1	gnu	pli [r3, r2, asr #1]
+c2f053f6|	1	gnu	pli [r3, -r2, asr #1]
+e2f0d3f6|	1	gnu	pli [r3, r2, ror #1]
+e2f053f6|	1	gnu	pli [r3, -r2, ror #1]
+939007e1|	1	gnu	swp r9, r3, [r7]
+948042e1|	1	gnu	swpb r8, r4, [r2]
+000000ef|	1	plan9	SVC $0
+ffff00ef|	1	plan9	SVC $65535
+ff10e0e3|	1	plan9	MVN $255, R1
+ff14e0e3|	1	plan9	MVN $4278190080, R1
+ff10f0e3|	1	plan9	MVN.S $255, R1
+ff14f0e3|	1	plan9	MVN.S $4278190080, R1
+097fe0e1|	1	plan9	MVN R9<<$30, R7
+297fe0e1|	1	plan9	MVN R9>>$30, R7
+497fe0e1|	1	plan9	MVN R9->$30, R7
+697fe0e1|	1	plan9	MVN R9@>$30, R7
+097ff0e1|	1	plan9	MVN.S R9<<$30, R7
+297ff0e1|	1	plan9	MVN.S R9>>$30, R7
+497ff0e1|	1	plan9	MVN.S R9->$30, R7
+697ff0e1|	1	plan9	MVN.S R9@>$30, R7
+1978e0e1|	1	plan9	MVN R9<<R8, R7
+3978e0e1|	1	plan9	MVN R9>>R8, R7
+5978e0e1|	1	plan9	MVN R9->R8, R7
+7978e0e1|	1	plan9	MVN R9@>R8, R7
+1978f0e1|	1	plan9	MVN.S R9<<R8, R7
+3978f0e1|	1	plan9	MVN.S R9>>R8, R7
+5978f0e1|	1	plan9	MVN.S R9->R8, R7
+7978f0e1|	1	plan9	MVN.S R9@>R8, R7
+550081e8|	1	plan9	STM [R0,R2,R4,R6], R1
+5f0f81e8|	1	plan9	STM [R0-R4,R6,R8-R11], R1
+5500a1e8|	1	plan9	STM [R0,R2,R4,R6], R1!
+5f0fa1e8|	1	plan9	STM [R0-R4,R6,R8-R11], R1!
+550091e8|	1	plan9	LDM [R0,R2,R4,R6], R1
+5f0f91e8|	1	plan9	LDM [R0-R4,R6,R8-R11], R1
+5500b1e8|	1	plan9	LDM [R0,R2,R4,R6], R1!
+5f0fb1e8|	1	plan9	LDM [R0-R4,R6,R8-R11], R1!
+550001e8|	1	plan9	STMDA [R0,R2,R4,R6], R1
+5f0f01e8|	1	plan9	STMDA [R0-R4,R6,R8-R11], R1
+550021e8|	1	plan9	STMDA [R0,R2,R4,R6], R1!
+5f0f21e8|	1	plan9	STMDA [R0-R4,R6,R8-R11], R1!
+550011e8|	1	plan9	LDMDA [R0,R2,R4,R6], R1
+5f0f11e8|	1	plan9	LDMDA [R0-R4,R6,R8-R11], R1
+550031e8|	1	plan9	LDMDA [R0,R2,R4,R6], R1!
+5f0f31e8|	1	plan9	LDMDA [R0-R4,R6,R8-R11], R1!
+550001e9|	1	plan9	STMDB [R0,R2,R4,R6], R1
+5f0f01e9|	1	plan9	STMDB [R0-R4,R6,R8-R11], R1
+550021e9|	1	plan9	STMDB [R0,R2,R4,R6], R1!
+5f0f21e9|	1	plan9	STMDB [R0-R4,R6,R8-R11], R1!
+550011e9|	1	plan9	LDMDB [R0,R2,R4,R6], R1
+5f0f11e9|	1	plan9	LDMDB [R0-R4,R6,R8-R11], R1
+550031e9|	1	plan9	LDMDB [R0,R2,R4,R6], R1!
+5f0f31e9|	1	plan9	LDMDB [R0-R4,R6,R8-R11], R1!
+55008ae9|	1	plan9	STMIB [R0,R2,R4,R6], R10
+5f0f8ae9|	1	plan9	STMIB [R0-R4,R6,R8-R11], R10
+5500aae9|	1	plan9	STMIB [R0,R2,R4,R6], R10!
+5f0faae9|	1	plan9	STMIB [R0-R4,R6,R8-R11], R10!
+55009ae9|	1	plan9	LDMIB [R0,R2,R4,R6], R10
+5f0f9ae9|	1	plan9	LDMIB [R0-R4,R6,R8-R11], R10
+5500bae9|	1	plan9	LDMIB [R0,R2,R4,R6], R10!
+5f0fbae9|	1	plan9	LDMIB [R0-R4,R6,R8-R11], R10!
+0340a0e1|	1	plan9	MOVW R3, R4
+0920a0e1|	1	plan9	MOVW R9, R2
+ff90a0e3|	1	plan9	MOVW $255, R9
+ff94a0e3|	1	plan9	MOVW $4278190080, R9
+aaaa0a13|	1	plan9	MOVW.NE $43690, R10
+aaaa4a03|	1	plan9	MOVT.EQ $43690, R10
+5110e0e3|	1	plan9	MVN $81, R1
+001082e5|	1	plan9	MOVW R1, (R2)
+001082e4|	1	plan9	MOVW.P R1, (R2)
+0010a2e5|	1	plan9	MOVW.W R1, (R2)
+201082e5|	1	plan9	MOVW R1, 0x20(R2)
+201082e4|	1	plan9	MOVW.P R1, 0x20(R2)
+2010a2e5|	1	plan9	MOVW.W R1, 0x20(R2)
+201002e5|	1	plan9	MOVW R1, -0x20(R2)
+201002e4|	1	plan9	MOVW.P R1, -0x20(R2)
+201022e5|	1	plan9	MOVW.W R1, -0x20(R2)
+001092e5|	1	plan9	MOVW (R2), R1
+001092e4|	1	plan9	MOVW.P (R2), R1
+0010b2e5|	1	plan9	MOVW.W (R2), R1
+201092e5|	1	plan9	MOVW 0x20(R2), R1
+201092e4|	1	plan9	MOVW.P 0x20(R2), R1
+2010b2e5|	1	plan9	MOVW.W 0x20(R2), R1
+201012e5|	1	plan9	MOVW -0x20(R2), R1
+201012e4|	1	plan9	MOVW.P -0x20(R2), R1
+201032e5|	1	plan9	MOVW.W -0x20(R2), R1
+00100fe1|	1	plan9	MRS APSR, R1
+fef02ce3|	1	plan9	MSR $254, APSR
+fff42ce3|	1	plan9	MSR $4278190080, APSR
+05f02c01|	1	plan9	MSR.EQ R5, APSR
+09f02c11|	1	plan9	MSR.NE R9, APSR
+109af1ee|	1	plan9	VMRS FPSCR, R9
+10aaf1ee|	1	plan9	VMRS FPSCR, R10
+109ae1ee|	1	plan9	VMSR R9, FPSCR
+10aae1ee|	1	plan9	VMSR R10, FPSCR
+202e91e7|	1	plan9	MOVW (R1)(R0>>28), R2
+002e91e7|	1	plan9	MOVW (R1)(R0<<28), R2
+402e91e7|	1	plan9	MOVW (R1)(R0->28), R2
+602e91e7|	1	plan9	MOVW (R1)(R0@>28), R2
+202e11e7|	1	plan9	MOVW.U (R1)(R0>>28), R2
+002e11e7|	1	plan9	MOVW.U (R1)(R0<<28), R2
+402e11e7|	1	plan9	MOVW.U (R1)(R0->28), R2
+602e11e7|	1	plan9	MOVW.U (R1)(R0@>28), R2
+202eb1e7|	1	plan9	MOVW.W (R1)(R0>>28), R2
+002eb1e7|	1	plan9	MOVW.W (R1)(R0<<28), R2
+402eb1e7|	1	plan9	MOVW.W (R1)(R0->28), R2
+602eb1e7|	1	plan9	MOVW.W (R1)(R0@>28), R2
+202e9ae6|	1	plan9	MOVW.P (R10)(R0>>28), R2
+002e9ae6|	1	plan9	MOVW.P (R10)(R0<<28), R2
+402e9ae6|	1	plan9	MOVW.P (R10)(R0->28), R2
+602e9ae6|	1	plan9	MOVW.P (R10)(R0@>28), R2
+202e81e7|	1	plan9	MOVW R2, (R1)(R0>>28)
+002e81e7|	1	plan9	MOVW R2, (R1)(R0<<28)
+402e81e7|	1	plan9	MOVW R2, (R1)(R0->28)
+602e81e7|	1	plan9	MOVW R2, (R1)(R0@>28)
+202e01e7|	1	plan9	MOVW.U R2, (R1)(R0>>28)
+002e01e7|	1	plan9	MOVW.U R2, (R1)(R0<<28)
+402e01e7|	1	plan9	MOVW.U R2, (R1)(R0->28)
+602e01e7|	1	plan9	MOVW.U R2, (R1)(R0@>28)
+202ea1e7|	1	plan9	MOVW.W R2, (R1)(R0>>28)
+002ea1e7|	1	plan9	MOVW.W R2, (R1)(R0<<28)
+402ea1e7|	1	plan9	MOVW.W R2, (R1)(R0->28)
+602ea1e7|	1	plan9	MOVW.W R2, (R1)(R0@>28)
+202e85e6|	1	plan9	MOVW.P R2, (R5)(R0>>28)
+002e85e6|	1	plan9	MOVW.P R2, (R5)(R0<<28)
+402e85e6|	1	plan9	MOVW.P R2, (R5)(R0->28)
+602e85e6|	1	plan9	MOVW.P R2, (R5)(R0@>28)
+0010c2e5|	1	plan9	MOVB R1, (R2)
+0010c2e4|	1	plan9	MOVB.P R1, (R2)
+0010e2e5|	1	plan9	MOVB.W R1, (R2)
+2010c2e5|	1	plan9	MOVB R1, 0x20(R2)
+2010c2e4|	1	plan9	MOVB.P R1, 0x20(R2)
+2010e2e5|	1	plan9	MOVB.W R1, 0x20(R2)
+201042e5|	1	plan9	MOVB R1, -0x20(R2)
+201042e4|	1	plan9	MOVB.P R1, -0x20(R2)
+201062e5|	1	plan9	MOVB.W R1, -0x20(R2)
+d010d2e1|	1	plan9	MOVBS (R2), R1
+d010d2e0|	1	plan9	MOVBS.P (R2), R1
+d010f2e1|	1	plan9	MOVBS.W (R2), R1
+d012d2e1|	1	plan9	MOVBS 0x20(R2), R1
+d012d2e0|	1	plan9	MOVBS.P 0x20(R2), R1
+d012f2e1|	1	plan9	MOVBS.W 0x20(R2), R1
+d01252e1|	1	plan9	MOVBS -0x20(R2), R1
+d01252e0|	1	plan9	MOVBS.P -0x20(R2), R1
+d01272e1|	1	plan9	MOVBS.W -0x20(R2), R1
+0010d2e5|	1	plan9	MOVBU (R2), R1
+0010dfe5|	1	plan9	MOVBU (R15), R1
+0020dfe5|	1	plan9	MOVBU (R15), R2
+0010d2e4|	1	plan9	MOVBU.P (R2), R1
+0010f2e5|	1	plan9	MOVBU.W (R2), R1
+2010d2e5|	1	plan9	MOVBU 0x20(R2), R1
+2010d2e4|	1	plan9	MOVBU.P 0x20(R2), R1
+2010f2e5|	1	plan9	MOVBU.W 0x20(R2), R1
+201052e5|	1	plan9	MOVBU -0x20(R2), R1
+201052e4|	1	plan9	MOVBU.P -0x20(R2), R1
+201072e5|	1	plan9	MOVBU.W -0x20(R2), R1
+202ec1e7|	1	plan9	MOVB R2, (R1)(R0>>28)
+002ec1e7|	1	plan9	MOVB R2, (R1)(R0<<28)
+402ec1e7|	1	plan9	MOVB R2, (R1)(R0->28)
+602ec1e7|	1	plan9	MOVB R2, (R1)(R0@>28)
+202e41e7|	1	plan9	MOVB.U R2, (R1)(R0>>28)
+002e41e7|	1	plan9	MOVB.U R2, (R1)(R0<<28)
+402e41e7|	1	plan9	MOVB.U R2, (R1)(R0->28)
+602e41e7|	1	plan9	MOVB.U R2, (R1)(R0@>28)
+202ee1e7|	1	plan9	MOVB.W R2, (R1)(R0>>28)
+002ee1e7|	1	plan9	MOVB.W R2, (R1)(R0<<28)
+402ee1e7|	1	plan9	MOVB.W R2, (R1)(R0->28)
+602ee1e7|	1	plan9	MOVB.W R2, (R1)(R0@>28)
+202e61e7|	1	plan9	MOVB.W.U R2, (R1)(R0>>28)
+002e61e7|	1	plan9	MOVB.W.U R2, (R1)(R0<<28)
+402e61e7|	1	plan9	MOVB.W.U R2, (R1)(R0->28)
+602e61e7|	1	plan9	MOVB.W.U R2, (R1)(R0@>28)
+202ec5e6|	1	plan9	MOVB.P R2, (R5)(R0>>28)
+002ec5e6|	1	plan9	MOVB.P R2, (R5)(R0<<28)
+402ec5e6|	1	plan9	MOVB.P R2, (R5)(R0->28)
+602ec5e6|	1	plan9	MOVB.P R2, (R5)(R0@>28)
+202ed1e7|	1	plan9	MOVBU (R1)(R0>>28), R2
+002ed1e7|	1	plan9	MOVBU (R1)(R0<<28), R2
+402ed1e7|	1	plan9	MOVBU (R1)(R0->28), R2
+602ed1e7|	1	plan9	MOVBU (R1)(R0@>28), R2
+202e51e7|	1	plan9	MOVBU.U (R1)(R0>>28), R2
+002e51e7|	1	plan9	MOVBU.U (R1)(R0<<28), R2
+402e51e7|	1	plan9	MOVBU.U (R1)(R0->28), R2
+602e51e7|	1	plan9	MOVBU.U (R1)(R0@>28), R2
+202ef1e7|	1	plan9	MOVBU.W (R1)(R0>>28), R2
+002ef1e7|	1	plan9	MOVBU.W (R1)(R0<<28), R2
+402ef1e7|	1	plan9	MOVBU.W (R1)(R0->28), R2
+602ef1e7|	1	plan9	MOVBU.W (R1)(R0@>28), R2
+202e71e7|	1	plan9	MOVBU.W.U (R1)(R0>>28), R2
+002e71e7|	1	plan9	MOVBU.W.U (R1)(R0<<28), R2
+402e71e7|	1	plan9	MOVBU.W.U (R1)(R0->28), R2
+602e71e7|	1	plan9	MOVBU.W.U (R1)(R0@>28), R2
+202edae6|	1	plan9	MOVBU.P (R10)(R0>>28), R2
+002edae6|	1	plan9	MOVBU.P (R10)(R0<<28), R2
+402edae6|	1	plan9	MOVBU.P (R10)(R0->28), R2
+602edae6|	1	plan9	MOVBU.P (R10)(R0@>28), R2
+d02091e1|	1	plan9	MOVBS (R1)(R0), R2
+d02011e1|	1	plan9	MOVBS.U (R1)(R0), R2
+d020b1e1|	1	plan9	MOVBS.W (R1)(R0), R2
+d02091e0|	1	plan9	MOVBS.P (R1)(R0), R2
+b040c3e1|	1	plan9	MOVH R4, (R3)
+b032c4e1|	1	plan9	MOVH R3, 0x20(R4)
+b032e4e1|	1	plan9	MOVH.W R3, 0x20(R4)
+b032c4e0|	1	plan9	MOVH.P R3, 0x20(R4)
+b03244e1|	1	plan9	MOVH R3, -0x20(R4)
+b03264e1|	1	plan9	MOVH.W R3, -0x20(R4)
+b03244e0|	1	plan9	MOVH.P R3, -0x20(R4)
+b080d9e1|	1	plan9	MOVHU (R9), R8
+b080f9e1|	1	plan9	MOVHU.W (R9), R8
+b080d9e0|	1	plan9	MOVHU.P (R9), R8
+f080d9e1|	1	plan9	MOVHS (R9), R8
+f080f9e1|	1	plan9	MOVHS.W (R9), R8
+f080d9e0|	1	plan9	MOVHS.P (R9), R8
+b282d9e1|	1	plan9	MOVHU 0x22(R9), R8
+b282f9e1|	1	plan9	MOVHU.W 0x22(R9), R8
+b282d9e0|	1	plan9	MOVHU.P 0x22(R9), R8
+f282d9e1|	1	plan9	MOVHS 0x22(R9), R8
+f282f9e1|	1	plan9	MOVHS.W 0x22(R9), R8
+f282d9e0|	1	plan9	MOVHS.P 0x22(R9), R8
+b48259e1|	1	plan9	MOVHU -0x24(R9), R8
+b48279e1|	1	plan9	MOVHU.W -0x24(R9), R8
+b48259e0|	1	plan9	MOVHU.P -0x24(R9), R8
+f48259e1|	1	plan9	MOVHS -0x24(R9), R8
+f48279e1|	1	plan9	MOVHS.W -0x24(R9), R8
+f48259e0|	1	plan9	MOVHS.P -0x24(R9), R8
+002a31ee|	1	plan9	VADD.F32 S0, S2, S4
+202a31ee|	1	plan9	VADD.F32 S1, S2, S4
+802a31ee|	1	plan9	VADD.F32 S0, S3, S4
+002a71ee|	1	plan9	VADD.F32 S0, S2, S5
+035b340e|	1	plan9	VADD.EQ.F64 D3, D4, D5
+002a321e|	1	plan9	VADD.NE.F32 S0, S4, S4
+035b35ee|	1	plan9	VADD.F64 D3, D5, D5
+402a31ee|	1	plan9	VSUB.F32 S0, S2, S4
+602a31ee|	1	plan9	VSUB.F32 S1, S2, S4
+c02a31ee|	1	plan9	VSUB.F32 S0, S3, S4
+402a71ee|	1	plan9	VSUB.F32 S0, S2, S5
+435b340e|	1	plan9	VSUB.EQ.F64 D3, D4, D5
+402a321e|	1	plan9	VSUB.NE.F32 S0, S4, S4
+435b35ee|	1	plan9	VSUB.F64 D3, D5, D5
+002a21ee|	1	plan9	VMUL.F32 S0, S2, S4
+202a21ee|	1	plan9	VMUL.F32 S1, S2, S4
+802a21ee|	1	plan9	VMUL.F32 S0, S3, S4
+002a61ee|	1	plan9	VMUL.F32 S0, S2, S5
+035b240e|	1	plan9	VMUL.EQ.F64 D3, D4, D5
+002a221e|	1	plan9	VMUL.NE.F32 S0, S4, S4
+035b25ee|	1	plan9	VMUL.F64 D3, D5, D5
+002a81ee|	1	plan9	VDIV.F32 S0, S2, S4
+202a81ee|	1	plan9	VDIV.F32 S1, S2, S4
+802a81ee|	1	plan9	VDIV.F32 S0, S3, S4
+002ac1ee|	1	plan9	VDIV.F32 S0, S2, S5
+035b840e|	1	plan9	VDIV.EQ.F64 D3, D4, D5
+002a821e|	1	plan9	VDIV.NE.F32 S0, S4, S4
+035b85ee|	1	plan9	VDIV.F64 D3, D5, D5
+401ab1ee|	1	plan9	VNEG.F32 S0, S2
+601ab1ee|	1	plan9	VNEG.F32 S1, S2
+401af1ee|	1	plan9	VNEG.F32 S0, S3
+445bb1ee|	1	plan9	VNEG.F64 D4, D5
+c01ab0ee|	1	plan9	VABS.F32 S0, S2
+e01ab0ee|	1	plan9	VABS.F32 S1, S2
+c01af0ee|	1	plan9	VABS.F32 S0, S3
+c45bb0ee|	1	plan9	VABS.F64 D4, D5
+c01ab1ee|	1	plan9	VSQRT.F32 S0, S2
+e01ab1ee|	1	plan9	VSQRT.F32 S1, S2
+c01af1ee|	1	plan9	VSQRT.F32 S0, S3
+c45bb1ee|	1	plan9	VSQRT.F64 D4, D5
+c01ab7ee|	1	gnu	vcvt.f64.f32 d1, s0
+c45bb7ee|	1	gnu	vcvt.f32.f64 s10, d4
+9f9f98e1|	1	gnu	ldrex r9, [r8]
+9f9fd8e1|	1	gnu	ldrexb r9, [r8]
+9f9ff8e1|	1	gnu	ldrexh r9, [r8]
+9fcfbbe1|	1	gnu	ldrexd ip, [fp]
+935f84e1|	1	gnu	strex r5, r3, [r4]
+935fc4e1|	1	gnu	strexb r5, r3, [r4]
+935fe4e1|	1	gnu	strexh r5, r3, [r4]
+98afa9e1|	1	gnu	strexd sl, r8, [r9]
+104b08ee|	1	gnu	vmov.32 d8[0], r4
+108b14ee|	1	gnu	vmov.32 r8, d4[0]
+445ab0ee|	1	gnu	vmov.f32 s10, s8
+467bb0ee|	1	gnu	vmov.f64 d7, d6
+c68abdee|	1	gnu	vcvt.s32.f32 s16, s12
+c68abcee|	1	gnu	vcvt.u32.f32 s16, s12
+c68bbdee|	1	gnu	vcvt.s32.f64 s16, d6
+c68bbcee|	1	gnu	vcvt.u32.f64 s16, d6
+c68ab8ee|	1	gnu	vcvt.f32.s32 s16, s12
+468ab8ee|	1	gnu	vcvt.f32.u32 s16, s12
+c68bb8ee|	1	gnu	vcvt.f64.s32 d8, s12
+468bb8ee|	1	gnu	vcvt.f64.u32 d8, s12
+000000ea|	1	plan9	B 0x8
+feffffea|	1	plan9	B 0x0
+fcffffea|	1	plan9	B 0xfffffff8
+1f90cfe7|	1	plan9	BFC $16, $0, R9
+9fb4dee7|	1	plan9	BFC $22, $9, R11
+1790cfe7|	1	plan9	BFI $16, $0, R7, R9
+98b4dee7|	1	plan9	BFI $22, $9, R8, R11
+742321e1|	1	plan9	BKPT $4660
+000000eb|	1	plan9	BL 0x8
+feffffeb|	1	plan9	BL 0x0
+fcffffeb|	1	plan9	BL 0xfffffff8
+000000fa|	1	plan9	BLX 0x8
+fefffffa|	1	plan9	BLX 0x0
+fcfffffa|	1	plan9	BLX 0xfffffff8
+33ff2fe1|	1	plan9	BLX R3
+13ff2fe1|	1	plan9	BX R3
+23ff2fe1|	1	plan9	BXJ R3
+1ff07ff5|	1	plan9	CLREX
+f7f020e3|	1	gnu	dbg #7
+58f07ff5|	1	gnu	dmb #8
+49f07ff5|	1	gnu	dsb #9
+62f07ff5|	1	gnu	isb #2
+009a94ed|	1	plan9	MOVF (R4), F9
+009ad4ed|	1	plan9	MOVF (R4), S19
+009b940d|	1	plan9	MOVD.EQ (R4), F9
+003a9a1d|	1	plan9	MOVF.NE (R10), F3
+003ada1d|	1	plan9	MOVF.NE (R10), S7
+003b9aed|	1	plan9	MOVD (R10), F3
+089a93ed|	1	plan9	MOVF 0x20(R3), F9
+089ad3ed|	1	plan9	MOVF 0x20(R3), S19
+089b940d|	1	plan9	MOVD.EQ 0x20(R4), F9
+083a1a1d|	1	plan9	MOVF.NE -0x20(R10), F3
+083a5a1d|	1	plan9	MOVF.NE -0x20(R10), S7
+083b1aed|	1	plan9	MOVD -0x20(R10), F3
+009a84ed|	1	plan9	MOVF F9, (R4)
+009ac4ed|	1	plan9	MOVF S19, (R4)
+009b840d|	1	plan9	MOVD.EQ F9, (R4)
+003a8a1d|	1	plan9	MOVF.NE F3, (R10)
+003aca1d|	1	plan9	MOVF.NE S7, (R10)
+003b8aed|	1	plan9	MOVD F3, (R10)
+089a83ed|	1	plan9	MOVF F9, 0x20(R3)
+089ac3ed|	1	plan9	MOVF S19, 0x20(R3)
+089b840d|	1	plan9	MOVD.EQ F9, 0x20(R4)
+083a0a1d|	1	plan9	MOVF.NE F3, -0x20(R10)
+083a4a1d|	1	plan9	MOVF.NE S7, -0x20(R10)
+083b0aed|	1	plan9	MOVD F3, -0x20(R10)
+d060c8e1|	1	gnu	ldrd r6, [r8]
+d06048e1|	1	gnu	ldrd r6, [r8]
+d060e8e1|	1	gnu	ldrd r6, [r8, #0]!
+d06068e1|	1	gnu	ldrd r6, [r8, #0]!
+d060c8e0|	1	gnu	ldrd r6, [r8], #0
+d06048e0|	1	gnu	ldrd r6, [r8], #0
+d062c8e1|	1	gnu	ldrd r6, [r8, #32]
+d06248e1|	1	gnu	ldrd r6, [r8, #-32]
+d062e8e1|	1	gnu	ldrd r6, [r8, #32]!
+d06268e1|	1	gnu	ldrd r6, [r8, #-32]!
+d062c8e0|	1	gnu	ldrd r6, [r8], #32
+d06248e0|	1	gnu	ldrd r6, [r8], #-32
+d24089e1|	1	gnu	ldrd r4, [r9, r2]
+d240a9e1|	1	gnu	ldrd r4, [r9, r2]!
+d24009e1|	1	gnu	ldrd r4, [r9, -r2]
+d24029e1|	1	gnu	ldrd r4, [r9, -r2]!
+f060c8e1|	1	gnu	strd r6, [r8]
+f06048e1|	1	gnu	strd r6, [r8]
+f060e8e1|	1	gnu	strd r6, [r8, #0]!
+f06068e1|	1	gnu	strd r6, [r8, #0]!
+f060c8e0|	1	gnu	strd r6, [r8], #0
+f06048e0|	1	gnu	strd r6, [r8], #0
+f062c8e1|	1	gnu	strd r6, [r8, #32]
+f06248e1|	1	gnu	strd r6, [r8, #-32]
+f062e8e1|	1	gnu	strd r6, [r8, #32]!
+f06268e1|	1	gnu	strd r6, [r8, #-32]!
+f062c8e0|	1	gnu	strd r6, [r8], #32
+f06248e0|	1	gnu	strd r6, [r8], #-32
+f24089e1|	1	gnu	strd r4, [r9, r2]
+f240a9e1|	1	gnu	strd r4, [r9, r2]!
+f24009e1|	1	gnu	strd r4, [r9, -r2]
+f24029e1|	1	gnu	strd r4, [r9, -r2]!
+0010b2e4|	1	gnu	ldrt r1, [r2], #0
+2010b2e4|	1	gnu	ldrt r1, [r2], #32
+201032e4|	1	gnu	ldrt r1, [r2], #-32
+0040bde4|	1	gnu	ldrt r4, [sp], #0
+2040bde4|	1	gnu	ldrt r4, [sp], #32
+20403de4|	1	gnu	ldrt r4, [sp], #-32
+2314b2e6|	1	gnu	ldrt r1, [r2], r3, lsr #8
+0314b2e6|	1	gnu	ldrt r1, [r2], r3, lsl #8
+4314b2e6|	1	gnu	ldrt r1, [r2], r3, asr #8
+6314b2e6|	1	gnu	ldrt r1, [r2], r3, ror #8
+231432e6|	1	gnu	ldrt r1, [r2], -r3, lsr #8
+031432e6|	1	gnu	ldrt r1, [r2], -r3, lsl #8
+431432e6|	1	gnu	ldrt r1, [r2], -r3, asr #8
+631432e6|	1	gnu	ldrt r1, [r2], -r3, ror #8
+0010a2e4|	1	gnu	strt r1, [r2], #0
+2010a2e4|	1	gnu	strt r1, [r2], #32
+201022e4|	1	gnu	strt r1, [r2], #-32
+0040ade4|	1	gnu	strt r4, [sp], #0
+2040ade4|	1	gnu	strt r4, [sp], #32
+20402de4|	1	gnu	strt r4, [sp], #-32
+2314a2e6|	1	gnu	strt r1, [r2], r3, lsr #8
+0314a2e6|	1	gnu	strt r1, [r2], r3, lsl #8
+4314a2e6|	1	gnu	strt r1, [r2], r3, asr #8
+6314a2e6|	1	gnu	strt r1, [r2], r3, ror #8
+231422e6|	1	gnu	strt r1, [r2], -r3, lsr #8
+031422e6|	1	gnu	strt r1, [r2], -r3, lsl #8
+431422e6|	1	gnu	strt r1, [r2], -r3, asr #8
+631422e6|	1	gnu	strt r1, [r2], -r3, ror #8
+0010f2e4|	1	gnu	ldrbt r1, [r2], #0
+2010f2e4|	1	gnu	ldrbt r1, [r2], #32
+201072e4|	1	gnu	ldrbt r1, [r2], #-32
+0040fde4|	1	gnu	ldrbt r4, [sp], #0
+2040fde4|	1	gnu	ldrbt r4, [sp], #32
+20407de4|	1	gnu	ldrbt r4, [sp], #-32
+2314f2e6|	1	gnu	ldrbt r1, [r2], r3, lsr #8
+0314f2e6|	1	gnu	ldrbt r1, [r2], r3, lsl #8
+4314f2e6|	1	gnu	ldrbt r1, [r2], r3, asr #8
+6314f2e6|	1	gnu	ldrbt r1, [r2], r3, ror #8
+231472e6|	1	gnu	ldrbt r1, [r2], -r3, lsr #8
+031472e6|	1	gnu	ldrbt r1, [r2], -r3, lsl #8
+431472e6|	1	gnu	ldrbt r1, [r2], -r3, asr #8
+631472e6|	1	gnu	ldrbt r1, [r2], -r3, ror #8
+0010e2e4|	1	gnu	strbt r1, [r2], #0
+2010e2e4|	1	gnu	strbt r1, [r2], #32
+201062e4|	1	gnu	strbt r1, [r2], #-32
+0040ede4|	1	gnu	strbt r4, [sp], #0
+2040ede4|	1	gnu	strbt r4, [sp], #32
+20406de4|	1	gnu	strbt r4, [sp], #-32
+2314e2e6|	1	gnu	strbt r1, [r2], r3, lsr #8
+0314e2e6|	1	gnu	strbt r1, [r2], r3, lsl #8
+4314e2e6|	1	gnu	strbt r1, [r2], r3, asr #8
+6314e2e6|	1	gnu	strbt r1, [r2], r3, ror #8
+231462e6|	1	gnu	strbt r1, [r2], -r3, lsr #8
+031462e6|	1	gnu	strbt r1, [r2], -r3, lsl #8
+431462e6|	1	gnu	strbt r1, [r2], -r3, asr #8
+631462e6|	1	gnu	strbt r1, [r2], -r3, ror #8
+d010f2e0|	1	gnu	ldrsbt r1, [r2], #0
+d012f2e0|	1	gnu	ldrsbt r1, [r2], #32
+d01272e0|	1	gnu	ldrsbt r1, [r2], #-32
+d040fde0|	1	gnu	ldrsbt r4, [sp], #0
+d042fde0|	1	gnu	ldrsbt r4, [sp], #32
+d0427de0|	1	gnu	ldrsbt r4, [sp], #-32
+d310b2e0|	1	gnu	ldrsbt r1, [r2], r3
+d640bde0|	1	gnu	ldrsbt r4, [sp], r6
+d31032e0|	1	gnu	ldrsbt r1, [r2], -r3
+d6403de0|	1	gnu	ldrsbt r4, [sp], -r6
+b010f2e0|	1	gnu	ldrht r1, [r2], #0
+b012f2e0|	1	gnu	ldrht r1, [r2], #32
+b01272e0|	1	gnu	ldrht r1, [r2], #-32
+b040fde0|	1	gnu	ldrht r4, [sp], #0
+b042fde0|	1	gnu	ldrht r4, [sp], #32
+b0427de0|	1	gnu	ldrht r4, [sp], #-32
+b310b2e0|	1	gnu	ldrht r1, [r2], r3
+b640bde0|	1	gnu	ldrht r4, [sp], r6
+b31032e0|	1	gnu	ldrht r1, [r2], -r3
+b6403de0|	1	gnu	ldrht r4, [sp], -r6
+f010f2e0|	1	gnu	ldrsht r1, [r2], #0
+f012f2e0|	1	gnu	ldrsht r1, [r2], #32
+f01272e0|	1	gnu	ldrsht r1, [r2], #-32
+f040fde0|	1	gnu	ldrsht r4, [sp], #0
+f042fde0|	1	gnu	ldrsht r4, [sp], #32
+f0427de0|	1	gnu	ldrsht r4, [sp], #-32
+f310b2e0|	1	gnu	ldrsht r1, [r2], r3
+f640bde0|	1	gnu	ldrsht r4, [sp], r6
+f31032e0|	1	gnu	ldrsht r1, [r2], -r3
+f6403de0|	1	gnu	ldrsht r4, [sp], -r6
+b010f2e0|	1	gnu	ldrht r1, [r2], #0
+b012f2e0|	1	gnu	ldrht r1, [r2], #32
+b01272e0|	1	gnu	ldrht r1, [r2], #-32
+b040fde0|	1	gnu	ldrht r4, [sp], #0
+b042fde0|	1	gnu	ldrht r4, [sp], #32
+b0427de0|	1	gnu	ldrht r4, [sp], #-32
+b310b2e0|	1	gnu	ldrht r1, [r2], r3
+b640bde0|	1	gnu	ldrht r4, [sp], r6
+b31032e0|	1	gnu	ldrht r1, [r2], -r3
+b6403de0|	1	gnu	ldrht r4, [sp], -r6
+b010e2e0|	1	gnu	strht r1, [r2], #0
+b012e2e0|	1	gnu	strht r1, [r2], #32
+b01262e0|	1	gnu	strht r1, [r2], #-32
+b040ede0|	1	gnu	strht r4, [sp], #0
+b042ede0|	1	gnu	strht r4, [sp], #32
+b0426de0|	1	gnu	strht r4, [sp], #-32
+b310a2e0|	1	gnu	strht r1, [r2], r3
+b640ade0|	1	gnu	strht r4, [sp], r6
+b31022e0|	1	gnu	strht r1, [r2], -r3
+b6402de0|	1	gnu	strht r4, [sp], -r6
+00f020e3|	1	gnu	nop
+445ab0ee|	1	gnu	vmov.f32 s10, s8
+645af0ee|	1	gnu	vmov.f32 s11, s9
+467bb0ee|	1	gnu	vmov.f64 d7, d6
+104b08ee|	1	gnu	vmov.32 d8[0], r4
+104b28ee|	1	gnu	vmov.32 d8[1], r4
+108b14ee|	1	gnu	vmov.32 r8, d4[0]
+108b34ee|	1	gnu	vmov.32 r8, d4[1]
+c68abdee|	1	gnu	vcvt.s32.f32 s16, s12
+e68afdee|	1	gnu	vcvt.s32.f32 s17, s13
+c68abcee|	1	gnu	vcvt.u32.f32 s16, s12
+e68afcee|	1	gnu	vcvt.u32.f32 s17, s13
+c68bbdee|	1	gnu	vcvt.s32.f64 s16, d6
+c68bfdee|	1	gnu	vcvt.s32.f64 s17, d6
+c68bbcee|	1	gnu	vcvt.u32.f64 s16, d6
+c68bfcee|	1	gnu	vcvt.u32.f64 s17, d6
+c68ab8ee|	1	gnu	vcvt.f32.s32 s16, s12
+e68af8ee|	1	gnu	vcvt.f32.s32 s17, s13
+468ab8ee|	1	gnu	vcvt.f32.u32 s16, s12
+668af8ee|	1	gnu	vcvt.f32.u32 s17, s13
+c68bb8ee|	1	gnu	vcvt.f64.s32 d8, s12
+e68bb8ee|	1	gnu	vcvt.f64.s32 d8, s13
+468bb8ee|	1	gnu	vcvt.f64.u32 d8, s12
+668bb8ee|	1	gnu	vcvt.f64.u32 d8, s13
+c01ab7ee|	1	gnu	vcvt.f64.f32 d1, s0
+e01ab7ee|	1	gnu	vcvt.f64.f32 d1, s1
+c45bb7ee|	1	gnu	vcvt.f32.f64 s10, d4
+c65bf7ee|	1	gnu	vcvt.f32.f64 s11, d6
+102083e6|	1	gnu	pkhbt r2, r3, r0
+102283e6|	1	gnu	pkhbt r2, r3, r0, lsl #4
+502083e6|	1	gnu	pkhtb r2, r3, r0, asr #32
+d02083e6|	1	gnu	pkhtb r2, r3, r0, asr #1
+502283e6|	1	gnu	pkhtb r2, r3, r0, asr #4
+faaf2de9|	1	gnu	push {r1, r3, r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
+04202de5|	1	gnu	push {r2}
+faafbde8|	1	gnu	pop {r1, r3, r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
+04209de4|	1	gnu	pop {r2}
+556003e1|	1	gnu	qadd r6, r5, r3
+156f28e6|	1	gnu	qadd16 r6, r8, r5
+956f28e6|	1	gnu	qadd8 r6, r8, r5
+550044e1|	1	gnu	qdadd r0, r5, r4
+550066e1|	1	gnu	qdsub r0, r5, r6
+156f68e6|	1	gnu	uqadd16 r6, r8, r5
+956f68e6|	1	gnu	uqadd8 r6, r8, r5
+356f28e6|	1	gnu	qasx r6, r8, r5
+556f28e6|	1	gnu	qsax r6, r8, r5
+356f64e6|	1	gnu	uqasx r6, r4, r5
+553f64e6|	1	gnu	uqsax r3, r4, r5
+556022e1|	1	gnu	qsub r6, r5, r2
+774f21e6|	1	gnu	qsub16 r4, r1, r7
+f74f21e6|	1	gnu	qsub8 r4, r1, r7
+774f61e6|	1	gnu	uqsub16 r4, r1, r7
+f74f61e6|	1	gnu	uqsub8 r4, r1, r7
+6670a0e1|	1	gnu	rrx r7, r6
+6670b0e1|	1	gnu	rrxs r7, r6
+112f13e6|	1	gnu	sadd16 r2, r3, r1
+992f13e6|	1	gnu	sadd8 r2, r3, r9
+112f33e6|	1	gnu	shadd16 r2, r3, r1
+992f33e6|	1	gnu	shadd8 r2, r3, r9
+712f13e6|	1	gnu	ssub16 r2, r3, r1
+f92f13e6|	1	gnu	ssub8 r2, r3, r9
+712f33e6|	1	gnu	shsub16 r2, r3, r1
+f92f33e6|	1	gnu	shsub8 r2, r3, r9
+112f53e6|	1	gnu	uadd16 r2, r3, r1
+992f53e6|	1	gnu	uadd8 r2, r3, r9
+112f73e6|	1	gnu	uhadd16 r2, r3, r1
+992f73e6|	1	gnu	uhadd8 r2, r3, r9
+712f53e6|	1	gnu	usub16 r2, r3, r1
+f92f53e6|	1	gnu	usub8 r2, r3, r9
+712f73e6|	1	gnu	uhsub16 r2, r3, r1
+f92f73e6|	1	gnu	uhsub8 r2, r3, r9
+332f14e6|	1	gnu	sasx r2, r4, r3
+532f14e6|	1	gnu	ssax r2, r4, r3
+332f54e6|	1	gnu	uasx r2, r4, r3
+532f54e6|	1	gnu	usax r2, r4, r3
+332f34e6|	1	gnu	shasx r2, r4, r3
+532f34e6|	1	gnu	shsax r2, r4, r3
+332f74e6|	1	gnu	uhasx r2, r4, r3
+532f74e6|	1	gnu	uhsax r2, r4, r3
+dc51afe7|	1	gnu	sbfx r5, ip, #3, #16
+dc51efe7|	1	gnu	ubfx r5, ip, #3, #16
+b12f88e6|	1	gnu	sel r2, r8, r1
+000201f1|	1	gnu	setend be
+000001f1|	1	gnu	setend le
+04f020e3|	1	gnu	sev
+1155aae6|	1	gnu	ssat r5, #11, r1, lsl #10
+5155aae6|	1	gnu	ssat r5, #11, r1, asr #10
+335faae6|	1	gnu	ssat16 r5, #11, r3
+1155eae6|	1	gnu	usat r5, #10, r1, lsl #10
+5155eae6|	1	gnu	usat r5, #10, r1, asr #10
+335feae6|	1	gnu	usat16 r5, #10, r3
+7788a9e6|	1	gnu	sxtab r8, r9, r7, ror #16
+778889e6|	1	gnu	sxtab16 r8, r9, r7, ror #16
+7788b9e6|	1	gnu	sxtah r8, r9, r7, ror #16
+7784afe6|	1	gnu	sxtb r8, r7, ror #8
+778c8fe6|	1	gnu	sxtb16 r8, r7, ror #24
+7780bfe6|	1	gnu	sxth r8, r7
+7788e9e6|	1	gnu	uxtab r8, r9, r7, ror #16
+7788c9e6|	1	gnu	uxtab16 r8, r9, r7, ror #16
+7788f9e6|	1	gnu	uxtah r8, r9, r7, ror #16
+7784efe6|	1	gnu	uxtb r8, r7, ror #8
+778ccfe6|	1	gnu	uxtb16 r8, r7, ror #24
+7780ffe6|	1	gnu	uxth r8, r7
+11f288e7|	1	gnu	usad8 r8, r1, r2
+112388e7|	1	gnu	usada8 r8, r1, r3, r2
+02f020e3|	1	gnu	wfe
+03f020e3|	1	gnu	wfi
+01f020e3|	1	gnu	yield
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/arg.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/arg.go
new file mode 100644
index 0000000..96df14d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/arg.go
@@ -0,0 +1,494 @@
+// Generated by ARM internal tool
+// DO NOT EDIT
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+// Naming for Go decoder arguments:
+//
+// - arg_Wd: a W register encoded in the Rd[4:0] field (31 is wzr)
+//
+// - arg_Xd: a X register encoded in the Rd[4:0] field (31 is xzr)
+//
+// - arg_Wds: a W register encoded in the Rd[4:0] field (31 is wsp)
+//
+// - arg_Xds: a X register encoded in the Rd[4:0] field (31 is sp)
+//
+// - arg_Wn: encoded in Rn[9:5]
+//
+// - arg_Wm: encoded in Rm[20:16]
+//
+// - arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4:
+//     a W register encoded in Rm with an extend encoded in option[15:13] and an amount
+//     encoded in imm3[12:10] in the range [0,4].
+//
+// - arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4:
+//     a W or X register encoded in Rm with an extend encoded in option[15:13] and an
+//     amount encoded in imm3[12:10] in the range [0,4]. If the extend is UXTX or SXTX,
+//     it's an X register else, it's a W register.
+//
+// - arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31:
+//     a W register encoded in Rm with a shift encoded in shift[23:22] and an amount
+//     encoded in imm6[15:10] in the range [0,31].
+//
+// - arg_IAddSub:
+//     An immediate for a add/sub instruction encoded in imm12[21:10] with an optional
+//     left shift of 12 encoded in shift[23:22].
+//
+// - arg_Rt_31_1__W_0__X_1:
+//     a W or X register encoded in Rt[4:0]. The width specifier is encoded in the field
+//     [31:31] (offset 31, bit count 1) and the register is W for 0 and X for 1.
+//
+// - arg_[s|u]label_FIELDS_POWER:
+//     a program label encoded as "FIELDS" times 2^POWER in the range [MIN, MAX] (determined
+//     by signd/unsigned, FIELDS and POWER), e.g.
+//       arg_slabel_imm14_2
+//       arg_slabel_imm19_2
+//       arg_slabel_imm26_2
+//       arg_slabel_immhi_immlo_0
+//       arg_slabel_immhi_immlo_12
+//
+// - arg_Xns_mem_post_imm7_8_signed:
+//     addressing mode of post-index with a base register: Xns and a signed offset encoded
+//     in the "imm7" field times 8
+//
+// - arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1:
+//     addressing mode of extended register with a base register: Xns, an offset register
+//     (<Wm>|<Xm>) with an extend encoded in option[15:13] and a shift amount encoded in
+//     S[12:12] in the range [0,3] (S=0:0, S=1:3).
+//
+// - arg_Xns_mem_optional_imm12_4_unsigned:
+//     addressing mode of unsigned offset with a base register: Xns and an optional unsigned
+//     offset encoded in the "imm12" field times 4
+//
+// - arg_Xns_mem_wb_imm7_4_signed:
+//     addressing mode of pre-index with a base register: Xns and the signed offset encoded
+//     in the "imm7" field times 4
+//
+// - arg_Xns_mem_post_size_1_8_unsigned__4_0__8_1__16_2__32_3:
+//     a post-index immediate offset, encoded in the "size" field. It can have the following values:
+//       #4 when size = 00
+//       #8 when size = 01
+//       #16 when size = 10
+//       #32 when size = 11
+//
+// - arg_immediate_0_127_CRm_op2:
+//     an immediate encoded in "CRm:op2" in the range 0 to 127
+//
+// - arg_immediate_bitmask_64_N_imms_immr:
+//     a bitmask immediate for 64-bit variant and encoded in "N:imms:immr"
+//
+// - arg_immediate_SBFX_SBFM_64M_bitfield_width_64_imms:
+//     an immediate for the <width> bitfield of SBFX 64-bit variant
+//
+// - arg_immediate_shift_32_implicit_inverse_imm16_hw:
+//     a 32-bit immediate of the bitwise inverse of which can be encoded in "imm16:hw"
+//
+// - arg_cond_[Not]AllowALNV_[Invert|Normal]:
+//     a standard condition, encoded in the "cond" field, excluding (NotAllow) AL and NV with
+//     its least significant bit [Yes|No] inverted, e.g.
+//       arg_cond_AllowALNV_Normal
+//       arg_cond_NotAllowALNV_Invert
+//
+// - arg_immediate_OptLSL_amount_16_0_48:
+//     An immediate for MOV[KNZ] instruction encoded in imm16[20:5] with an optional
+//     left shift of 16 in the range [0, 48] encoded in hw[22, 21]
+//
+// - arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8:
+//     the left shift amount, in the range 0 to the operand width in bits minus 1,
+//     encoded in the "immh:immb" field. It can have the following values:
+//       (UInt(immh:immb)-8) when immh = 0001
+//       (UInt(immh:immb)-16) when immh = 001x
+//       (UInt(immh:immb)-32) when immh = 01xx
+//       (UInt(immh:immb)-64) when immh = 1xxx
+//
+// - arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4:
+//     the right shift amount, in the range 1 to the destination operand width in
+//     bits, encoded in the "immh:immb" field. It can have the following values:
+//       (16-UInt(immh:immb)) when immh = 0001
+//       (32-UInt(immh:immb)) when immh = 001x
+//       (64-UInt(immh:immb)) when immh = 01xx
+//
+// - arg_immediate_8x8_a_b_c_d_e_f_g_h:
+//     a 64-bit immediate 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
+//     encoded in "a:b:c:d:e:f:g:h".
+//
+// - arg_immediate_fbits_min_1_max_32_sub_64_scale:
+//     the number of bits after the binary point in the fixed-point destination,
+//     in the range 1 to 32, encoded as 64 minus "scale".
+//
+// - arg_immediate_floatzero: #0.0
+//
+// - arg_immediate_exp_3_pre_4_a_b_c_d_e_f_g_h:
+//     a signed floating-point constant with 3-bit exponent and normalized 4 bits of precision,
+//     encoded in "a:b:c:d:e:f:g:h"
+//
+// - arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8:
+//     the number of fractional bits, in the range 1 to the operand width, encoded
+//     in the "immh:immb" field. It can have the following values:
+//       (64-UInt(immh:immb)) when immh = 01xx
+//       (128-UInt(immh:immb)) when immh = 1xxx
+//
+// - arg_immediate_index_Q_imm4__imm4lt20gt_00__imm4_10:
+//     the lowest numbered byte element to be extracted, encoded in the "Q:imm4" field.
+//     It can have the following values:
+//       imm4<2:0> when Q = 0, imm4<3> = 0
+//       imm4 when Q = 1, imm4<3> = x
+//
+// - arg_sysop_AT_SYS_CR_system:
+//     system operation for system instruction: AT encoded in the "op1:CRm<0>:op2" field
+//
+// - arg_prfop_Rt:
+//     prefectch operation encoded in the "Rt"
+//
+// - arg_sysreg_o0_op1_CRn_CRm_op2:
+//     system register name encoded in the "o0:op1:CRn:CRm:op2"
+//
+// - arg_pstatefield_op1_op2__SPSel_05__DAIFSet_36__DAIFClr_37:
+//     PSTATE field name encoded in the "op1:op2" field
+//
+// - arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+//     one register with arrangement specifier encoded in the "size:Q" field which can have the following values:
+//       8B when size = 00, Q = 0
+//       16B when size = 00, Q = 1
+//       4H when size = 01, Q = 0
+//       8H when size = 01, Q = 1
+//       2S when size = 10, Q = 0
+//       4S when size = 10, Q = 1
+//       2D when size = 11, Q = 1
+//       The encoding size = 11, Q = 0 is reserved.
+//
+// - arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31:
+//     three registers with arrangement specifier encoded in the "size:Q" field which can have the following values:
+//       8B when size = 00, Q = 0
+//       16B when size = 00, Q = 1
+//       4H when size = 01, Q = 0
+//       8H when size = 01, Q = 1
+//       2S when size = 10, Q = 0
+//       4S when size = 10, Q = 1
+//       2D when size = 11, Q = 1
+//       The encoding size = 11, Q = 0 is reserved.
+//
+// - arg_Vt_1_arrangement_H_index__Q_S_size_1:
+//     one register with arrangement:H and element index encoded in "Q:S:size<1>".
+
+type instArg uint16
+
+const (
+	_ instArg = iota
+	arg_Bt
+	arg_Cm
+	arg_Cn
+	arg_cond_AllowALNV_Normal
+	arg_conditional
+	arg_cond_NotAllowALNV_Invert
+	arg_Da
+	arg_Dd
+	arg_Dm
+	arg_Dn
+	arg_Dt
+	arg_Dt2
+	arg_Hd
+	arg_Hn
+	arg_Ht
+	arg_IAddSub
+	arg_immediate_0_127_CRm_op2
+	arg_immediate_0_15_CRm
+	arg_immediate_0_15_nzcv
+	arg_immediate_0_31_imm5
+	arg_immediate_0_31_immr
+	arg_immediate_0_31_imms
+	arg_immediate_0_63_b5_b40
+	arg_immediate_0_63_immh_immb__UIntimmhimmb64_8
+	arg_immediate_0_63_immr
+	arg_immediate_0_63_imms
+	arg_immediate_0_65535_imm16
+	arg_immediate_0_7_op1
+	arg_immediate_0_7_op2
+	arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4
+	arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8
+	arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8
+	arg_immediate_0_width_size__8_0__16_1__32_2
+	arg_immediate_1_64_immh_immb__128UIntimmhimmb_8
+	arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4
+	arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4
+	arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8
+	arg_immediate_8x8_a_b_c_d_e_f_g_h
+	arg_immediate_ASR_SBFM_32M_bitfield_0_31_immr
+	arg_immediate_ASR_SBFM_64M_bitfield_0_63_immr
+	arg_immediate_BFI_BFM_32M_bitfield_lsb_32_immr
+	arg_immediate_BFI_BFM_32M_bitfield_width_32_imms
+	arg_immediate_BFI_BFM_64M_bitfield_lsb_64_immr
+	arg_immediate_BFI_BFM_64M_bitfield_width_64_imms
+	arg_immediate_BFXIL_BFM_32M_bitfield_lsb_32_immr
+	arg_immediate_BFXIL_BFM_32M_bitfield_width_32_imms
+	arg_immediate_BFXIL_BFM_64M_bitfield_lsb_64_immr
+	arg_immediate_BFXIL_BFM_64M_bitfield_width_64_imms
+	arg_immediate_bitmask_32_imms_immr
+	arg_immediate_bitmask_64_N_imms_immr
+	arg_immediate_exp_3_pre_4_a_b_c_d_e_f_g_h
+	arg_immediate_exp_3_pre_4_imm8
+	arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8
+	arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8
+	arg_immediate_fbits_min_1_max_32_sub_64_scale
+	arg_immediate_fbits_min_1_max_64_sub_64_scale
+	arg_immediate_floatzero
+	arg_immediate_index_Q_imm4__imm4lt20gt_00__imm4_10
+	arg_immediate_LSL_UBFM_32M_bitfield_0_31_immr
+	arg_immediate_LSL_UBFM_64M_bitfield_0_63_immr
+	arg_immediate_LSR_UBFM_32M_bitfield_0_31_immr
+	arg_immediate_LSR_UBFM_64M_bitfield_0_63_immr
+	arg_immediate_MSL__a_b_c_d_e_f_g_h_cmode__8_0__16_1
+	arg_immediate_optional_0_15_CRm
+	arg_immediate_optional_0_65535_imm16
+	arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1
+	arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3
+	arg_immediate_OptLSL_amount_16_0_16
+	arg_immediate_OptLSL_amount_16_0_48
+	arg_immediate_OptLSLZero__a_b_c_d_e_f_g_h
+	arg_immediate_SBFIZ_SBFM_32M_bitfield_lsb_32_immr
+	arg_immediate_SBFIZ_SBFM_32M_bitfield_width_32_imms
+	arg_immediate_SBFIZ_SBFM_64M_bitfield_lsb_64_immr
+	arg_immediate_SBFIZ_SBFM_64M_bitfield_width_64_imms
+	arg_immediate_SBFX_SBFM_32M_bitfield_lsb_32_immr
+	arg_immediate_SBFX_SBFM_32M_bitfield_width_32_imms
+	arg_immediate_SBFX_SBFM_64M_bitfield_lsb_64_immr
+	arg_immediate_SBFX_SBFM_64M_bitfield_width_64_imms
+	arg_immediate_shift_32_implicit_imm16_hw
+	arg_immediate_shift_32_implicit_inverse_imm16_hw
+	arg_immediate_shift_64_implicit_imm16_hw
+	arg_immediate_shift_64_implicit_inverse_imm16_hw
+	arg_immediate_UBFIZ_UBFM_32M_bitfield_lsb_32_immr
+	arg_immediate_UBFIZ_UBFM_32M_bitfield_width_32_imms
+	arg_immediate_UBFIZ_UBFM_64M_bitfield_lsb_64_immr
+	arg_immediate_UBFIZ_UBFM_64M_bitfield_width_64_imms
+	arg_immediate_UBFX_UBFM_32M_bitfield_lsb_32_immr
+	arg_immediate_UBFX_UBFM_32M_bitfield_width_32_imms
+	arg_immediate_UBFX_UBFM_64M_bitfield_lsb_64_immr
+	arg_immediate_UBFX_UBFM_64M_bitfield_width_64_imms
+	arg_immediate_zero
+	arg_option_DMB_BO_system_CRm
+	arg_option_DSB_BO_system_CRm
+	arg_option_ISB_BI_system_CRm
+	arg_prfop_Rt
+	arg_pstatefield_op1_op2__SPSel_05__DAIFSet_36__DAIFClr_37
+	arg_Qd
+	arg_Qn
+	arg_Qt
+	arg_Qt2
+	arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4
+	arg_Rn_16_5__W_1__W_2__W_4__X_8
+	arg_Rt_31_1__W_0__X_1
+	arg_Sa
+	arg_Sd
+	arg_slabel_imm14_2
+	arg_slabel_imm19_2
+	arg_slabel_imm26_2
+	arg_slabel_immhi_immlo_0
+	arg_slabel_immhi_immlo_12
+	arg_Sm
+	arg_Sn
+	arg_St
+	arg_St2
+	arg_sysop_AT_SYS_CR_system
+	arg_sysop_DC_SYS_CR_system
+	arg_sysop_IC_SYS_CR_system
+	arg_sysop_SYS_CR_system
+	arg_sysop_TLBI_SYS_CR_system
+	arg_sysreg_o0_op1_CRn_CRm_op2
+	arg_Vd_16_5__B_1__H_2__S_4__D_8
+	arg_Vd_19_4__B_1__H_2__S_4
+	arg_Vd_19_4__B_1__H_2__S_4__D_8
+	arg_Vd_19_4__D_8
+	arg_Vd_19_4__S_4__D_8
+	arg_Vd_22_1__S_0
+	arg_Vd_22_1__S_0__D_1
+	arg_Vd_22_1__S_1
+	arg_Vd_22_2__B_0__H_1__S_2
+	arg_Vd_22_2__B_0__H_1__S_2__D_3
+	arg_Vd_22_2__D_3
+	arg_Vd_22_2__H_0__S_1__D_2
+	arg_Vd_22_2__H_1__S_2
+	arg_Vd_22_2__S_1__D_2
+	arg_Vd_arrangement_16B
+	arg_Vd_arrangement_2D
+	arg_Vd_arrangement_4S
+	arg_Vd_arrangement_D_index__1
+	arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1
+	arg_Vd_arrangement_imm5_Q___8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81
+	arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81
+	arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41
+	arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81
+	arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4
+	arg_Vd_arrangement_Q___2S_0__4S_1
+	arg_Vd_arrangement_Q___4H_0__8H_1
+	arg_Vd_arrangement_Q___8B_0__16B_1
+	arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11
+	arg_Vd_arrangement_size___4S_1__2D_2
+	arg_Vd_arrangement_size___8H_0__1Q_3
+	arg_Vd_arrangement_size___8H_0__4S_1__2D_2
+	arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21
+	arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21
+	arg_Vd_arrangement_size_Q___8B_00__16B_01
+	arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11
+	arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21
+	arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Vd_arrangement_sz___4S_0__2D_1
+	arg_Vd_arrangement_sz_Q___2S_00__4S_01
+	arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11
+	arg_Vd_arrangement_sz_Q___2S_10__4S_11
+	arg_Vd_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11
+	arg_Vm_22_1__S_0__D_1
+	arg_Vm_22_2__B_0__H_1__S_2__D_3
+	arg_Vm_22_2__D_3
+	arg_Vm_22_2__H_1__S_2
+	arg_Vm_arrangement_4S
+	arg_Vm_arrangement_Q___8B_0__16B_1
+	arg_Vm_arrangement_size___8H_0__4S_1__2D_2
+	arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1
+	arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21
+	arg_Vm_arrangement_size_Q___8B_00__16B_01
+	arg_Vm_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31
+	arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21
+	arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11
+	arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1
+	arg_Vn_19_4__B_1__H_2__S_4__D_8
+	arg_Vn_19_4__D_8
+	arg_Vn_19_4__H_1__S_2__D_4
+	arg_Vn_19_4__S_4__D_8
+	arg_Vn_1_arrangement_16B
+	arg_Vn_22_1__D_1
+	arg_Vn_22_1__S_0__D_1
+	arg_Vn_22_2__B_0__H_1__S_2__D_3
+	arg_Vn_22_2__D_3
+	arg_Vn_22_2__H_0__S_1__D_2
+	arg_Vn_22_2__H_1__S_2
+	arg_Vn_2_arrangement_16B
+	arg_Vn_3_arrangement_16B
+	arg_Vn_4_arrangement_16B
+	arg_Vn_arrangement_16B
+	arg_Vn_arrangement_4S
+	arg_Vn_arrangement_D_index__1
+	arg_Vn_arrangement_D_index__imm5_1
+	arg_Vn_arrangement_imm5___B_1__H_2_index__imm5__imm5lt41gt_1__imm5lt42gt_2_1
+	arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5_imm4__imm4lt30gt_1__imm4lt31gt_2__imm4lt32gt_4__imm4lt3gt_8_1
+	arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1
+	arg_Vn_arrangement_imm5___B_1__H_2__S_4_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1
+	arg_Vn_arrangement_imm5___D_8_index__imm5_1
+	arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81
+	arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41
+	arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81
+	arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4
+	arg_Vn_arrangement_Q___8B_0__16B_1
+	arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11
+	arg_Vn_arrangement_Q_sz___4S_10
+	arg_Vn_arrangement_S_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1
+	arg_Vn_arrangement_size___2D_3
+	arg_Vn_arrangement_size___8H_0__4S_1__2D_2
+	arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21
+	arg_Vn_arrangement_size_Q___8B_00__16B_01
+	arg_Vn_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31
+	arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11
+	arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21
+	arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21
+	arg_Vn_arrangement_sz___2D_1
+	arg_Vn_arrangement_sz___2S_0__2D_1
+	arg_Vn_arrangement_sz___4S_0__2D_1
+	arg_Vn_arrangement_sz_Q___2S_00__4S_01
+	arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11
+	arg_Vn_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11
+	arg_Vt_1_arrangement_B_index__Q_S_size_1
+	arg_Vt_1_arrangement_D_index__Q_1
+	arg_Vt_1_arrangement_H_index__Q_S_size_1
+	arg_Vt_1_arrangement_S_index__Q_S_1
+	arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31
+	arg_Vt_2_arrangement_B_index__Q_S_size_1
+	arg_Vt_2_arrangement_D_index__Q_1
+	arg_Vt_2_arrangement_H_index__Q_S_size_1
+	arg_Vt_2_arrangement_S_index__Q_S_1
+	arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31
+	arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Vt_3_arrangement_B_index__Q_S_size_1
+	arg_Vt_3_arrangement_D_index__Q_1
+	arg_Vt_3_arrangement_H_index__Q_S_size_1
+	arg_Vt_3_arrangement_S_index__Q_S_1
+	arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31
+	arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Vt_4_arrangement_B_index__Q_S_size_1
+	arg_Vt_4_arrangement_D_index__Q_1
+	arg_Vt_4_arrangement_H_index__Q_S_size_1
+	arg_Vt_4_arrangement_S_index__Q_S_1
+	arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31
+	arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31
+	arg_Wa
+	arg_Wd
+	arg_Wds
+	arg_Wm
+	arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4
+	arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31
+	arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31
+	arg_Wn
+	arg_Wns
+	arg_Ws
+	arg_Wt
+	arg_Wt2
+	arg_Xa
+	arg_Xd
+	arg_Xds
+	arg_Xm
+	arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63
+	arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63
+	arg_Xn
+	arg_Xns
+	arg_Xns_mem
+	arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1
+	arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1
+	arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1
+	arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__4_1
+	arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1
+	arg_Xns_mem_offset
+	arg_Xns_mem_optional_imm12_16_unsigned
+	arg_Xns_mem_optional_imm12_1_unsigned
+	arg_Xns_mem_optional_imm12_2_unsigned
+	arg_Xns_mem_optional_imm12_4_unsigned
+	arg_Xns_mem_optional_imm12_8_unsigned
+	arg_Xns_mem_optional_imm7_16_signed
+	arg_Xns_mem_optional_imm7_4_signed
+	arg_Xns_mem_optional_imm7_8_signed
+	arg_Xns_mem_optional_imm9_1_signed
+	arg_Xns_mem_post_fixedimm_1
+	arg_Xns_mem_post_fixedimm_12
+	arg_Xns_mem_post_fixedimm_16
+	arg_Xns_mem_post_fixedimm_2
+	arg_Xns_mem_post_fixedimm_24
+	arg_Xns_mem_post_fixedimm_3
+	arg_Xns_mem_post_fixedimm_32
+	arg_Xns_mem_post_fixedimm_4
+	arg_Xns_mem_post_fixedimm_6
+	arg_Xns_mem_post_fixedimm_8
+	arg_Xns_mem_post_imm7_16_signed
+	arg_Xns_mem_post_imm7_4_signed
+	arg_Xns_mem_post_imm7_8_signed
+	arg_Xns_mem_post_imm9_1_signed
+	arg_Xns_mem_post_Q__16_0__32_1
+	arg_Xns_mem_post_Q__24_0__48_1
+	arg_Xns_mem_post_Q__32_0__64_1
+	arg_Xns_mem_post_Q__8_0__16_1
+	arg_Xns_mem_post_size__1_0__2_1__4_2__8_3
+	arg_Xns_mem_post_size__2_0__4_1__8_2__16_3
+	arg_Xns_mem_post_size__3_0__6_1__12_2__24_3
+	arg_Xns_mem_post_size__4_0__8_1__16_2__32_3
+	arg_Xns_mem_post_Xm
+	arg_Xns_mem_wb_imm7_16_signed
+	arg_Xns_mem_wb_imm7_4_signed
+	arg_Xns_mem_wb_imm7_8_signed
+	arg_Xns_mem_wb_imm9_1_signed
+	arg_Xs
+	arg_Xt
+	arg_Xt2
+)
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition.go
new file mode 100644
index 0000000..d673857
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition.go
@@ -0,0 +1,329 @@
+// Generated by ARM internal tool
+// DO NOT EDIT
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+// Following functions are used as the predicator: canDecode of according instruction
+// Refer to instFormat inside decode.go for more details
+
+func at_sys_cr_system_cond(instr uint32) bool {
+	return sys_op_4((instr>>16)&0x7, 0x7, 0x8, (instr>>5)&0x7) == Sys_AT
+}
+
+func bfi_bfm_32m_bitfield_cond(instr uint32) bool {
+	return (instr>>5)&0x1f != 0x1f && uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func bfi_bfm_64m_bitfield_cond(instr uint32) bool {
+	return (instr>>5)&0x1f != 0x1f && uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func bfxil_bfm_32m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) >= uint8((instr>>16)&0x3f)
+}
+
+func bfxil_bfm_64m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) >= uint8((instr>>16)&0x3f)
+}
+
+func cinc_csinc_32_condsel_cond(instr uint32) bool {
+	return instr&0x1f0000 != 0x1f0000 && instr&0xe000 != 0xe000 && instr&0x3e0 != 0x3e0 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func cinc_csinc_64_condsel_cond(instr uint32) bool {
+	return instr&0x1f0000 != 0x1f0000 && instr&0xe000 != 0xe000 && instr&0x3e0 != 0x3e0 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func cinv_csinv_32_condsel_cond(instr uint32) bool {
+	return instr&0x1f0000 != 0x1f0000 && instr&0xe000 != 0xe000 && instr&0x3e0 != 0x3e0 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func cinv_csinv_64_condsel_cond(instr uint32) bool {
+	return instr&0x1f0000 != 0x1f0000 && instr&0xe000 != 0xe000 && instr&0x3e0 != 0x3e0 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func cneg_csneg_32_condsel_cond(instr uint32) bool {
+	return instr&0xe000 != 0xe000 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func cneg_csneg_64_condsel_cond(instr uint32) bool {
+	return instr&0xe000 != 0xe000 && (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func csinc_general_cond(instr uint32) bool {
+	return instr&0xe000 != 0xe000
+}
+func csinv_general_cond(instr uint32) bool {
+	return instr&0xe000 != 0xe000
+}
+func dc_sys_cr_system_cond(instr uint32) bool {
+	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_DC
+}
+
+func ic_sys_cr_system_cond(instr uint32) bool {
+	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_IC
+}
+
+func lsl_ubfm_32m_bitfield_cond(instr uint32) bool {
+	return instr&0xfc00 != 0x7c00 && (instr>>10)&0x3f+1 == (instr>>16)&0x3f
+}
+
+func lsl_ubfm_64m_bitfield_cond(instr uint32) bool {
+	return instr&0xfc00 != 0xfc00 && (instr>>10)&0x3f+1 == (instr>>16)&0x3f
+}
+
+func mov_orr_32_log_imm_cond(instr uint32) bool {
+	return !move_wide_preferred_4((instr>>31)&0x1, (instr>>22)&0x1, (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func mov_orr_64_log_imm_cond(instr uint32) bool {
+	return !move_wide_preferred_4((instr>>31)&0x1, (instr>>22)&0x1, (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func mov_movn_32_movewide_cond(instr uint32) bool {
+	return !(is_zero((instr>>5)&0xffff) && (instr>>21)&0x3 != 0x0) && !is_ones_n16((instr>>5)&0xffff)
+}
+
+func mov_movn_64_movewide_cond(instr uint32) bool {
+	return !(is_zero((instr>>5)&0xffff) && (instr>>21)&0x3 != 0x0)
+}
+
+func mov_add_32_addsub_imm_cond(instr uint32) bool {
+	return instr&0x1f == 0x1f || (instr>>5)&0x1f == 0x1f
+}
+
+func mov_add_64_addsub_imm_cond(instr uint32) bool {
+	return instr&0x1f == 0x1f || (instr>>5)&0x1f == 0x1f
+}
+
+func mov_movz_32_movewide_cond(instr uint32) bool {
+	return !(is_zero((instr>>5)&0xffff) && (instr>>21)&0x3 != 0x0)
+}
+
+func mov_movz_64_movewide_cond(instr uint32) bool {
+	return !(is_zero((instr>>5)&0xffff) && (instr>>21)&0x3 != 0x0)
+}
+
+func ror_extr_32_extract_cond(instr uint32) bool {
+	return (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func ror_extr_64_extract_cond(instr uint32) bool {
+	return (instr>>5)&0x1f == (instr>>16)&0x1f
+}
+
+func sbfiz_sbfm_32m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func sbfiz_sbfm_64m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func sbfx_sbfm_32m_bitfield_cond(instr uint32) bool {
+	return bfxpreferred_4((instr>>31)&0x1, extract_bit((instr>>29)&0x3, 1), (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func sbfx_sbfm_64m_bitfield_cond(instr uint32) bool {
+	return bfxpreferred_4((instr>>31)&0x1, extract_bit((instr>>29)&0x3, 1), (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func tlbi_sys_cr_system_cond(instr uint32) bool {
+	return sys_op_4((instr>>16)&0x7, 0x8, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_TLBI
+}
+
+func ubfiz_ubfm_32m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func ubfiz_ubfm_64m_bitfield_cond(instr uint32) bool {
+	return uint8((instr>>10)&0x3f) < uint8((instr>>16)&0x3f)
+}
+
+func ubfx_ubfm_32m_bitfield_cond(instr uint32) bool {
+	return bfxpreferred_4((instr>>31)&0x1, extract_bit((instr>>29)&0x3, 1), (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func ubfx_ubfm_64m_bitfield_cond(instr uint32) bool {
+	return bfxpreferred_4((instr>>31)&0x1, extract_bit((instr>>29)&0x3, 1), (instr>>10)&0x3f, (instr>>16)&0x3f)
+}
+
+func fcvtzs_asisdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func fcvtzs_asimdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func fcvtzu_asisdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func fcvtzu_asimdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func mov_umov_asimdins_w_w_cond(instr uint32) bool {
+	return ((instr>>16)&0x1f)&0x7 == 0x4
+}
+
+func mov_umov_asimdins_x_x_cond(instr uint32) bool {
+	return ((instr>>16)&0x1f)&0xf == 0x8
+}
+
+func mov_orr_asimdsame_only_cond(instr uint32) bool {
+	return (instr>>16)&0x1f == (instr>>5)&0x1f
+}
+
+func rshrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func scvtf_asisdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func scvtf_asimdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func shl_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func shl_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func shrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sli_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sli_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqrshrn_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqrshrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqrshrun_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqrshrun_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshl_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshl_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshlu_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshlu_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshrn_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshrun_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sqshrun_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sri_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sri_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func srshr_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func srshr_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func srsra_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func srsra_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sshll_asimdshf_l_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sshr_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sshr_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ssra_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ssra_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func sxtl_sshll_asimdshf_l_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0 && bit_count((instr>>19)&0xf) == 1
+}
+
+func ucvtf_asisdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ucvtf_asimdshf_c_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqrshrn_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqrshrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqshl_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqshl_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqshrn_asisdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uqshrn_asimdshf_n_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func urshr_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func urshr_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ursra_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ursra_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ushll_asimdshf_l_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ushr_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func ushr_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func usra_asisdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func usra_asimdshf_r_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0
+}
+func uxtl_ushll_asimdshf_l_cond(instr uint32) bool {
+	return instr&0x780000 != 0x0 && bit_count((instr>>19)&0xf) == 1
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition_util.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition_util.go
new file mode 100644
index 0000000..62c0c3b
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/condition_util.go
@@ -0,0 +1,81 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+func extract_bit(value, bit uint32) uint32 {
+	return (value >> bit) & 1
+}
+
+func bfxpreferred_4(sf, opc1, imms, immr uint32) bool {
+	if imms < immr {
+		return false
+	}
+	if (imms>>5 == sf) && (imms&0x1f == 0x1f) {
+		return false
+	}
+	if immr == 0 {
+		if sf == 0 && (imms == 7 || imms == 15) {
+			return false
+		}
+		if sf == 1 && opc1 == 0 && (imms == 7 ||
+			imms == 15 || imms == 31) {
+			return false
+		}
+	}
+	return true
+}
+
+func move_wide_preferred_4(sf, N, imms, immr uint32) bool {
+	if sf == 1 && N != 1 {
+		return false
+	}
+	if sf == 0 && !(N == 0 && ((imms>>5)&1) == 0) {
+		return false
+	}
+	if imms < 16 {
+		return (-immr)%16 <= (15 - imms)
+	}
+	width := uint32(32)
+	if sf == 1 {
+		width = uint32(64)
+	}
+	if imms >= (width - 15) {
+		return (immr % 16) <= (imms - (width - 15))
+	}
+	return false
+}
+
+type Sys uint8
+
+const (
+	Sys_AT Sys = iota
+	Sys_DC
+	Sys_IC
+	Sys_TLBI
+	Sys_SYS
+)
+
+func sys_op_4(op1, crn, crm, op2 uint32) Sys {
+	// TODO: system instruction
+	return Sys_SYS
+}
+
+func is_zero(x uint32) bool {
+	return x == 0
+}
+
+func is_ones_n16(x uint32) bool {
+	return x == 0xffff
+}
+
+func bit_count(x uint32) uint8 {
+	var count uint8
+	for count = 0; x > 0; x >>= 1 {
+		if (x & 1) == 1 {
+			count++
+		}
+	}
+	return count
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode.go
new file mode 100644
index 0000000..5e29c47
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode.go
@@ -0,0 +1,2768 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"encoding/binary"
+	"fmt"
+)
+
+type instArgs [5]instArg
+
+// 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 predicator: canDecode(x) return true.
+type instFormat struct {
+	mask  uint32
+	value uint32
+	op    Op
+	// 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.
+	args      instArgs
+	canDecode func(instr uint32) bool
+}
+
+var (
+	errShort   = fmt.Errorf("truncated instruction")
+	errUnknown = fmt.Errorf("unknown instruction")
+)
+
+var decoderCover []bool
+
+func init() {
+	decoderCover = make([]bool, len(instFormats))
+}
+
+// Decode decodes the 4 bytes in src as a single instruction.
+func Decode(src []byte) (inst Inst, err error) {
+	if len(src) < 4 {
+		return Inst{}, errShort
+	}
+
+	x := binary.LittleEndian.Uint32(src)
+
+Search:
+	for i := range instFormats {
+		f := &instFormats[i]
+		if x&f.mask != f.value {
+			continue
+		}
+		if f.canDecode != nil && !f.canDecode(x) {
+			continue
+		}
+		// Decode args.
+		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:   f.op,
+			Args: args,
+			Enc:  x,
+		}
+		return inst, nil
+	}
+	return Inst{}, errUnknown
+}
+
+// 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_Da:
+		return D0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Dd:
+		return D0 + Reg(x&(1<<5-1))
+
+	case arg_Dm:
+		return D0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Dn:
+		return D0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_Hd:
+		return H0 + Reg(x&(1<<5-1))
+
+	case arg_Hn:
+		return H0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_IAddSub:
+		imm12 := (x >> 10) & (1<<12 - 1)
+		shift := (x >> 22) & (1<<2 - 1)
+		if shift > 1 {
+			return nil
+		}
+		shift = shift * 12
+		return ImmShift{uint16(imm12), uint8(shift)}
+
+	case arg_Sa:
+		return S0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Sd:
+		return S0 + Reg(x&(1<<5-1))
+
+	case arg_Sm:
+		return S0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Sn:
+		return S0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_Wa:
+		return W0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Wd:
+		return W0 + Reg(x&(1<<5-1))
+
+	case arg_Wds:
+		return RegSP(W0) + RegSP(x&(1<<5-1))
+
+	case arg_Wm:
+		return W0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4:
+		return handle_ExtendedRegister(x, true)
+
+	case arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4:
+		return handle_ExtendedRegister(x, false)
+
+	case arg_Wn:
+		return W0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_Wns:
+		return RegSP(W0) + RegSP((x>>5)&(1<<5-1))
+
+	case arg_Xa:
+		return X0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Xd:
+		return X0 + Reg(x&(1<<5-1))
+
+	case arg_Xds:
+		return RegSP(X0) + RegSP(x&(1<<5-1))
+
+	case arg_Xm:
+		return X0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31:
+		return handle_ImmediateShiftedRegister(x, 31, true, false)
+
+	case arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31:
+		return handle_ImmediateShiftedRegister(x, 31, true, true)
+
+	case arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63:
+		return handle_ImmediateShiftedRegister(x, 63, false, false)
+
+	case arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63:
+		return handle_ImmediateShiftedRegister(x, 63, false, true)
+
+	case arg_Xn:
+		return X0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_Xns:
+		return RegSP(X0) + RegSP((x>>5)&(1<<5-1))
+
+	case arg_slabel_imm14_2:
+		imm14 := ((x >> 5) & (1<<14 - 1))
+		return PCRel(((int64(imm14) << 2) << 48) >> 48)
+
+	case arg_slabel_imm19_2:
+		imm19 := ((x >> 5) & (1<<19 - 1))
+		return PCRel(((int64(imm19) << 2) << 43) >> 43)
+
+	case arg_slabel_imm26_2:
+		imm26 := (x & (1<<26 - 1))
+		return PCRel(((int64(imm26) << 2) << 36) >> 36)
+
+	case arg_slabel_immhi_immlo_0:
+		immhi := ((x >> 5) & (1<<19 - 1))
+		immlo := ((x >> 29) & (1<<2 - 1))
+		immhilo := (immhi)<<2 | immlo
+		return PCRel((int64(immhilo) << 43) >> 43)
+
+	case arg_slabel_immhi_immlo_12:
+		immhi := ((x >> 5) & (1<<19 - 1))
+		immlo := ((x >> 29) & (1<<2 - 1))
+		immhilo := (immhi)<<2 | immlo
+		return PCRel(((int64(immhilo) << 12) << 31) >> 31)
+
+	case arg_Xns_mem:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrOffset, 0}
+
+	case arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1:
+		return handle_MemExtend(x, 1, false)
+
+	case arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1:
+		return handle_MemExtend(x, 2, false)
+
+	case arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1:
+		return handle_MemExtend(x, 3, false)
+
+	case arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1:
+		return handle_MemExtend(x, 1, true)
+
+	case arg_Xns_mem_optional_imm12_1_unsigned:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm12 := (x >> 10) & (1<<12 - 1)
+		return MemImmediate{Rn, AddrOffset, int32(imm12)}
+
+	case arg_Xns_mem_optional_imm12_2_unsigned:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm12 := (x >> 10) & (1<<12 - 1)
+		return MemImmediate{Rn, AddrOffset, int32(imm12 << 1)}
+
+	case arg_Xns_mem_optional_imm12_4_unsigned:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm12 := (x >> 10) & (1<<12 - 1)
+		return MemImmediate{Rn, AddrOffset, int32(imm12 << 2)}
+
+	case arg_Xns_mem_optional_imm12_8_unsigned:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm12 := (x >> 10) & (1<<12 - 1)
+		return MemImmediate{Rn, AddrOffset, int32(imm12 << 3)}
+
+	case arg_Xns_mem_optional_imm7_4_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrOffset, ((int32(imm7 << 2)) << 23) >> 23}
+
+	case arg_Xns_mem_optional_imm7_8_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrOffset, ((int32(imm7 << 3)) << 22) >> 22}
+
+	case arg_Xns_mem_optional_imm9_1_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm9 := (x >> 12) & (1<<9 - 1)
+		return MemImmediate{Rn, AddrOffset, (int32(imm9) << 23) >> 23}
+
+	case arg_Xns_mem_post_imm7_4_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPostIndex, ((int32(imm7 << 2)) << 23) >> 23}
+
+	case arg_Xns_mem_post_imm7_8_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPostIndex, ((int32(imm7 << 3)) << 22) >> 22}
+
+	case arg_Xns_mem_post_imm9_1_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm9 := (x >> 12) & (1<<9 - 1)
+		return MemImmediate{Rn, AddrPostIndex, ((int32(imm9)) << 23) >> 23}
+
+	case arg_Xns_mem_wb_imm7_4_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPreIndex, ((int32(imm7 << 2)) << 23) >> 23}
+
+	case arg_Xns_mem_wb_imm7_8_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPreIndex, ((int32(imm7 << 3)) << 22) >> 22}
+
+	case arg_Xns_mem_wb_imm9_1_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm9 := (x >> 12) & (1<<9 - 1)
+		return MemImmediate{Rn, AddrPreIndex, ((int32(imm9)) << 23) >> 23}
+
+	case arg_Ws:
+		return W0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Wt:
+		return W0 + Reg(x&(1<<5-1))
+
+	case arg_Wt2:
+		return W0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Xs:
+		return X0 + Reg((x>>16)&(1<<5-1))
+
+	case arg_Xt:
+		return X0 + Reg(x&(1<<5-1))
+
+	case arg_Xt2:
+		return X0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_immediate_0_127_CRm_op2:
+		crm_op2 := (x >> 5) & (1<<7 - 1)
+		return Imm_hint(crm_op2)
+
+	case arg_immediate_0_15_CRm:
+		crm := (x >> 8) & (1<<4 - 1)
+		return Imm{crm, false}
+
+	case arg_immediate_0_15_nzcv:
+		nzcv := x & (1<<4 - 1)
+		return Imm{nzcv, false}
+
+	case arg_immediate_0_31_imm5:
+		imm5 := (x >> 16) & (1<<5 - 1)
+		return Imm{imm5, false}
+
+	case arg_immediate_0_31_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, false}
+
+	case arg_immediate_0_31_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		if imms > 31 {
+			return nil
+		}
+		return Imm{imms, true}
+
+	case arg_immediate_0_63_b5_b40:
+		b5 := (x >> 31) & 1
+		b40 := (x >> 19) & (1<<5 - 1)
+		return Imm{(b5 << 5) | b40, true}
+
+	case arg_immediate_0_63_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, false}
+
+	case arg_immediate_0_63_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		return Imm{imms, true}
+
+	case arg_immediate_0_65535_imm16:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		return Imm{imm16, false}
+
+	case arg_immediate_0_7_op1:
+		op1 := (x >> 16) & (1<<3 - 1)
+		return Imm{op1, true}
+
+	case arg_immediate_0_7_op2:
+		op2 := (x >> 5) & (1<<3 - 1)
+		return Imm{op2, true}
+
+	case arg_immediate_ASR_SBFM_32M_bitfield_0_31_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, true}
+
+	case arg_immediate_ASR_SBFM_64M_bitfield_0_63_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, true}
+
+	case arg_immediate_BFI_BFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{32 - immr, true}
+
+	case arg_immediate_BFI_BFM_32M_bitfield_width_32_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		if imms > 31 {
+			return nil
+		}
+		return Imm{imms + 1, true}
+
+	case arg_immediate_BFI_BFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{64 - immr, true}
+
+	case arg_immediate_BFI_BFM_64M_bitfield_width_64_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		return Imm{imms + 1, true}
+
+	case arg_immediate_BFXIL_BFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, true}
+
+	case arg_immediate_BFXIL_BFM_32M_bitfield_width_32_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 32-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_immediate_BFXIL_BFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, true}
+
+	case arg_immediate_BFXIL_BFM_64M_bitfield_width_64_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 64-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_immediate_bitmask_32_imms_immr:
+		return handle_bitmasks(x, 32)
+
+	case arg_immediate_bitmask_64_N_imms_immr:
+		return handle_bitmasks(x, 64)
+
+	case arg_immediate_LSL_UBFM_32M_bitfield_0_31_immr:
+		imms := (x >> 10) & (1<<6 - 1)
+		shift := 31 - imms
+		if shift > 31 {
+			return nil
+		}
+		return Imm{shift, true}
+
+	case arg_immediate_LSL_UBFM_64M_bitfield_0_63_immr:
+		imms := (x >> 10) & (1<<6 - 1)
+		shift := 63 - imms
+		if shift > 63 {
+			return nil
+		}
+		return Imm{shift, true}
+
+	case arg_immediate_LSR_UBFM_32M_bitfield_0_31_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, true}
+
+	case arg_immediate_LSR_UBFM_64M_bitfield_0_63_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, true}
+
+	case arg_immediate_optional_0_15_CRm:
+		crm := (x >> 8) & (1<<4 - 1)
+		return Imm_clrex(crm)
+
+	case arg_immediate_optional_0_65535_imm16:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		return Imm_dcps(imm16)
+
+	case arg_immediate_OptLSL_amount_16_0_16:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		if shift > 16 {
+			return nil
+		}
+		return ImmShift{uint16(imm16), uint8(shift)}
+
+	case arg_immediate_OptLSL_amount_16_0_48:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		return ImmShift{uint16(imm16), uint8(shift)}
+
+	case arg_immediate_SBFIZ_SBFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{32 - immr, true}
+
+	case arg_immediate_SBFIZ_SBFM_32M_bitfield_width_32_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		if imms > 31 {
+			return nil
+		}
+		return Imm{imms + 1, true}
+
+	case arg_immediate_SBFIZ_SBFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{64 - immr, true}
+
+	case arg_immediate_SBFIZ_SBFM_64M_bitfield_width_64_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		return Imm{imms + 1, true}
+
+	case arg_immediate_SBFX_SBFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, true}
+
+	case arg_immediate_SBFX_SBFM_32M_bitfield_width_32_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 32-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_immediate_SBFX_SBFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, true}
+
+	case arg_immediate_SBFX_SBFM_64M_bitfield_width_64_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 64-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_immediate_shift_32_implicit_imm16_hw:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		if shift > 16 {
+			return nil
+		}
+		result := uint32(imm16) << shift
+		return Imm{result, false}
+
+	case arg_immediate_shift_32_implicit_inverse_imm16_hw:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		if shift > 16 {
+			return nil
+		}
+		result := uint32(imm16) << shift
+		return Imm{^result, false}
+
+	case arg_immediate_shift_64_implicit_imm16_hw:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		result := uint64(imm16) << shift
+		return Imm64{result, false}
+
+	case arg_immediate_shift_64_implicit_inverse_imm16_hw:
+		imm16 := (x >> 5) & (1<<16 - 1)
+		hw := (x >> 21) & (1<<2 - 1)
+		shift := hw * 16
+		result := uint64(imm16) << shift
+		return Imm64{^result, false}
+
+	case arg_immediate_UBFIZ_UBFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{32 - immr, true}
+
+	case arg_immediate_UBFIZ_UBFM_32M_bitfield_width_32_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		if imms > 31 {
+			return nil
+		}
+		return Imm{imms + 1, true}
+
+	case arg_immediate_UBFIZ_UBFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{64 - immr, true}
+
+	case arg_immediate_UBFIZ_UBFM_64M_bitfield_width_64_imms:
+		imms := (x >> 10) & (1<<6 - 1)
+		return Imm{imms + 1, true}
+
+	case arg_immediate_UBFX_UBFM_32M_bitfield_lsb_32_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		if immr > 31 {
+			return nil
+		}
+		return Imm{immr, true}
+
+	case arg_immediate_UBFX_UBFM_32M_bitfield_width_32_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 32-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_immediate_UBFX_UBFM_64M_bitfield_lsb_64_immr:
+		immr := (x >> 16) & (1<<6 - 1)
+		return Imm{immr, true}
+
+	case arg_immediate_UBFX_UBFM_64M_bitfield_width_64_imms:
+		immr := (x >> 16) & (1<<6 - 1)
+		imms := (x >> 10) & (1<<6 - 1)
+		width := imms - immr + 1
+		if width < 1 || width > 64-immr {
+			return nil
+		}
+		return Imm{width, true}
+
+	case arg_Rt_31_1__W_0__X_1:
+		b5 := (x >> 31) & 1
+		Rt := x & (1<<5 - 1)
+		if b5 == 0 {
+			return W0 + Reg(Rt)
+		} else {
+			return X0 + Reg(Rt)
+		}
+
+	case arg_cond_AllowALNV_Normal:
+		cond := (x >> 12) & (1<<4 - 1)
+		return Cond{uint8(cond), false}
+
+	case arg_conditional:
+		cond := x & (1<<4 - 1)
+		return Cond{uint8(cond), false}
+
+	case arg_cond_NotAllowALNV_Invert:
+		cond := (x >> 12) & (1<<4 - 1)
+		if (cond >> 1) == 7 {
+			return nil
+		}
+		return Cond{uint8(cond), true}
+
+	case arg_Cm:
+		CRm := (x >> 8) & (1<<4 - 1)
+		return Imm_c(CRm)
+
+	case arg_Cn:
+		CRn := (x >> 12) & (1<<4 - 1)
+		return Imm_c(CRn)
+
+	case arg_option_DMB_BO_system_CRm:
+		CRm := (x >> 8) & (1<<4 - 1)
+		return Imm_option(CRm)
+
+	case arg_option_DSB_BO_system_CRm:
+		CRm := (x >> 8) & (1<<4 - 1)
+		return Imm_option(CRm)
+
+	case arg_option_ISB_BI_system_CRm:
+		CRm := (x >> 8) & (1<<4 - 1)
+		if CRm == 15 {
+			return Imm_option(CRm)
+		}
+		return Imm{CRm, false}
+
+	case arg_prfop_Rt:
+		Rt := x & (1<<5 - 1)
+		return Imm_prfop(Rt)
+
+	case arg_pstatefield_op1_op2__SPSel_05__DAIFSet_36__DAIFClr_37:
+		op1 := (x >> 16) & (1<<3 - 1)
+		op2 := (x >> 5) & (1<<3 - 1)
+		if (op1 == 0) && (op2 == 5) {
+			return SPSel
+		} else if (op1 == 3) && (op2 == 6) {
+			return DAIFSet
+		} else if (op1 == 3) && (op2 == 7) {
+			return DAIFClr
+		}
+		return nil
+
+	case arg_sysreg_o0_op1_CRn_CRm_op2:
+		op0 := (x >> 19) & (1<<2 - 1)
+		op1 := (x >> 16) & (1<<3 - 1)
+		CRn := (x >> 12) & (1<<4 - 1)
+		CRm := (x >> 8) & (1<<4 - 1)
+		op2 := (x >> 5) & (1<<3 - 1)
+		return Systemreg{uint8(op0), uint8(op1), uint8(CRn), uint8(CRm), uint8(op2)}
+
+	case arg_sysop_AT_SYS_CR_system:
+		//TODO: system instruction
+		return nil
+
+	case arg_sysop_DC_SYS_CR_system:
+		//TODO: system instruction
+		return nil
+
+	case arg_sysop_SYS_CR_system:
+		//TODO: system instruction
+		return nil
+
+	case arg_sysop_TLBI_SYS_CR_system:
+		//TODO: system instruction
+		return nil
+
+	case arg_Bt:
+		return B0 + Reg(x&(1<<5-1))
+
+	case arg_Dt:
+		return D0 + Reg(x&(1<<5-1))
+
+	case arg_Dt2:
+		return D0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Ht:
+		return H0 + Reg(x&(1<<5-1))
+
+	case arg_immediate_0_63_immh_immb__UIntimmhimmb64_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		if (immh & 8) == 0 {
+			return nil
+		}
+		immb := (x >> 16) & (1<<3 - 1)
+		return Imm{(immh << 3) + immb - 64, true}
+
+	case arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4:
+		immh := (x >> 19) & (1<<4 - 1)
+		immb := (x >> 16) & (1<<3 - 1)
+		if immh == 1 {
+			return Imm{(immh << 3) + immb - 8, true}
+		} else if (immh >> 1) == 1 {
+			return Imm{(immh << 3) + immb - 16, true}
+		} else if (immh >> 2) == 1 {
+			return Imm{(immh << 3) + immb - 32, true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8:
+		fallthrough
+
+	case arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		immb := (x >> 16) & (1<<3 - 1)
+		if immh == 1 {
+			return Imm{(immh << 3) + immb - 8, true}
+		} else if (immh >> 1) == 1 {
+			return Imm{(immh << 3) + immb - 16, true}
+		} else if (immh >> 2) == 1 {
+			return Imm{(immh << 3) + immb - 32, true}
+		} else if (immh >> 3) == 1 {
+			return Imm{(immh << 3) + immb - 64, true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_0_width_size__8_0__16_1__32_2:
+		size := (x >> 22) & (1<<2 - 1)
+		switch size {
+		case 0:
+			return Imm{8, true}
+		case 1:
+			return Imm{16, true}
+		case 2:
+			return Imm{32, true}
+		default:
+			return nil
+		}
+
+	case arg_immediate_1_64_immh_immb__128UIntimmhimmb_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		if (immh & 8) == 0 {
+			return nil
+		}
+		immb := (x >> 16) & (1<<3 - 1)
+		return Imm{128 - ((immh << 3) + immb), true}
+
+	case arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4:
+		fallthrough
+
+	case arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4:
+		immh := (x >> 19) & (1<<4 - 1)
+		immb := (x >> 16) & (1<<3 - 1)
+		if immh == 1 {
+			return Imm{16 - ((immh << 3) + immb), true}
+		} else if (immh >> 1) == 1 {
+			return Imm{32 - ((immh << 3) + immb), true}
+		} else if (immh >> 2) == 1 {
+			return Imm{64 - ((immh << 3) + immb), true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		immb := (x >> 16) & (1<<3 - 1)
+		if immh == 1 {
+			return Imm{16 - ((immh << 3) + immb), true}
+		} else if (immh >> 1) == 1 {
+			return Imm{32 - ((immh << 3) + immb), true}
+		} else if (immh >> 2) == 1 {
+			return Imm{64 - ((immh << 3) + immb), true}
+		} else if (immh >> 3) == 1 {
+			return Imm{128 - ((immh << 3) + immb), true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_8x8_a_b_c_d_e_f_g_h:
+		var imm uint64
+		if x&(1<<5) != 0 {
+			imm = (1 << 8) - 1
+		} else {
+			imm = 0
+		}
+		if x&(1<<6) != 0 {
+			imm += ((1 << 8) - 1) << 8
+		}
+		if x&(1<<7) != 0 {
+			imm += ((1 << 8) - 1) << 16
+		}
+		if x&(1<<8) != 0 {
+			imm += ((1 << 8) - 1) << 24
+		}
+		if x&(1<<9) != 0 {
+			imm += ((1 << 8) - 1) << 32
+		}
+		if x&(1<<16) != 0 {
+			imm += ((1 << 8) - 1) << 40
+		}
+		if x&(1<<17) != 0 {
+			imm += ((1 << 8) - 1) << 48
+		}
+		if x&(1<<18) != 0 {
+			imm += ((1 << 8) - 1) << 56
+		}
+		return Imm64{imm, false}
+
+	case arg_immediate_exp_3_pre_4_a_b_c_d_e_f_g_h:
+		pre := (x >> 5) & (1<<4 - 1)
+		exp := 1 - ((x >> 17) & 1)
+		exp = (exp << 2) + (((x >> 16) & 1) << 1) + ((x >> 9) & 1)
+		s := ((x >> 18) & 1)
+		return Imm_fp{uint8(s), int8(exp) - 3, uint8(pre)}
+
+	case arg_immediate_exp_3_pre_4_imm8:
+		pre := (x >> 13) & (1<<4 - 1)
+		exp := 1 - ((x >> 19) & 1)
+		exp = (exp << 2) + ((x >> 17) & (1<<2 - 1))
+		s := ((x >> 20) & 1)
+		return Imm_fp{uint8(s), int8(exp) - 3, uint8(pre)}
+
+	case arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8:
+		fallthrough
+
+	case arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		immb := (x >> 16) & (1<<3 - 1)
+		if (immh >> 2) == 1 {
+			return Imm{64 - ((immh << 3) + immb), true}
+		} else if (immh >> 3) == 1 {
+			return Imm{128 - ((immh << 3) + immb), true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_fbits_min_1_max_32_sub_64_scale:
+		scale := (x >> 10) & (1<<6 - 1)
+		fbits := 64 - scale
+		if fbits > 32 {
+			return nil
+		}
+		return Imm{fbits, true}
+
+	case arg_immediate_fbits_min_1_max_64_sub_64_scale:
+		scale := (x >> 10) & (1<<6 - 1)
+		fbits := 64 - scale
+		return Imm{fbits, true}
+
+	case arg_immediate_floatzero:
+		return Imm{0, true}
+
+	case arg_immediate_index_Q_imm4__imm4lt20gt_00__imm4_10:
+		Q := (x >> 30) & 1
+		imm4 := (x >> 11) & (1<<4 - 1)
+		if Q == 1 || (imm4>>3) == 0 {
+			return Imm{imm4, true}
+		} else {
+			return nil
+		}
+
+	case arg_immediate_MSL__a_b_c_d_e_f_g_h_cmode__8_0__16_1:
+		var shift uint8
+		imm8 := (x >> 16) & (1<<3 - 1)
+		imm8 = (imm8 << 5) | ((x >> 5) & (1<<5 - 1))
+		if (x>>12)&1 == 0 {
+			shift = 8 + 128
+		} else {
+			shift = 16 + 128
+		}
+		return ImmShift{uint16(imm8), shift}
+
+	case arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1:
+		imm8 := (x >> 16) & (1<<3 - 1)
+		imm8 = (imm8 << 5) | ((x >> 5) & (1<<5 - 1))
+		cmode1 := (x >> 13) & 1
+		shift := 8 * cmode1
+		return ImmShift{uint16(imm8), uint8(shift)}
+
+	case arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3:
+		imm8 := (x >> 16) & (1<<3 - 1)
+		imm8 = (imm8 << 5) | ((x >> 5) & (1<<5 - 1))
+		cmode1 := (x >> 13) & (1<<2 - 1)
+		shift := 8 * cmode1
+		return ImmShift{uint16(imm8), uint8(shift)}
+
+	case arg_immediate_OptLSLZero__a_b_c_d_e_f_g_h:
+		imm8 := (x >> 16) & (1<<3 - 1)
+		imm8 = (imm8 << 5) | ((x >> 5) & (1<<5 - 1))
+		return ImmShift{uint16(imm8), 0}
+
+	case arg_immediate_zero:
+		return Imm{0, true}
+
+	case arg_Qd:
+		return Q0 + Reg(x&(1<<5-1))
+
+	case arg_Qn:
+		return Q0 + Reg((x>>5)&(1<<5-1))
+
+	case arg_Qt:
+		return Q0 + Reg(x&(1<<5-1))
+
+	case arg_Qt2:
+		return Q0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Rn_16_5__W_1__W_2__W_4__X_8:
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if ((imm5 & 1) == 1) || ((imm5 & 2) == 2) || ((imm5 & 4) == 4) {
+			return W0 + Reg((x>>5)&(1<<5-1))
+		} else if (imm5 & 8) == 8 {
+			return X0 + Reg((x>>5)&(1<<5-1))
+		} else {
+			return nil
+		}
+
+	case arg_St:
+		return S0 + Reg(x&(1<<5-1))
+
+	case arg_St2:
+		return S0 + Reg((x>>10)&(1<<5-1))
+
+	case arg_Vd_16_5__B_1__H_2__S_4__D_8:
+		imm5 := (x >> 16) & (1<<5 - 1)
+		Rd := x & (1<<5 - 1)
+		if imm5&1 == 1 {
+			return B0 + Reg(Rd)
+		} else if imm5&2 == 2 {
+			return H0 + Reg(Rd)
+		} else if imm5&4 == 4 {
+			return S0 + Reg(Rd)
+		} else if imm5&8 == 8 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_19_4__B_1__H_2__S_4:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rd := x & (1<<5 - 1)
+		if immh == 1 {
+			return B0 + Reg(Rd)
+		} else if immh>>1 == 1 {
+			return H0 + Reg(Rd)
+		} else if immh>>2 == 1 {
+			return S0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_19_4__B_1__H_2__S_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rd := x & (1<<5 - 1)
+		if immh == 1 {
+			return B0 + Reg(Rd)
+		} else if immh>>1 == 1 {
+			return H0 + Reg(Rd)
+		} else if immh>>2 == 1 {
+			return S0 + Reg(Rd)
+		} else if immh>>3 == 1 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_19_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rd := x & (1<<5 - 1)
+		if immh>>3 == 1 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_19_4__S_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rd := x & (1<<5 - 1)
+		if immh>>2 == 1 {
+			return S0 + Reg(Rd)
+		} else if immh>>3 == 1 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_1__S_0:
+		sz := (x >> 22) & 1
+		Rd := x & (1<<5 - 1)
+		if sz == 0 {
+			return S0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_1__S_0__D_1:
+		sz := (x >> 22) & 1
+		Rd := x & (1<<5 - 1)
+		if sz == 0 {
+			return S0 + Reg(Rd)
+		} else {
+			return D0 + Reg(Rd)
+		}
+
+	case arg_Vd_22_1__S_1:
+		sz := (x >> 22) & 1
+		Rd := x & (1<<5 - 1)
+		if sz == 1 {
+			return S0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_2__B_0__H_1__S_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 0 {
+			return B0 + Reg(Rd)
+		} else if size == 1 {
+			return H0 + Reg(Rd)
+		} else if size == 2 {
+			return S0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_2__B_0__H_1__S_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 0 {
+			return B0 + Reg(Rd)
+		} else if size == 1 {
+			return H0 + Reg(Rd)
+		} else if size == 2 {
+			return S0 + Reg(Rd)
+		} else {
+			return D0 + Reg(Rd)
+		}
+
+	case arg_Vd_22_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 3 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_2__H_0__S_1__D_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 0 {
+			return H0 + Reg(Rd)
+		} else if size == 1 {
+			return S0 + Reg(Rd)
+		} else if size == 2 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_2__H_1__S_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 1 {
+			return H0 + Reg(Rd)
+		} else if size == 2 {
+			return S0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_22_2__S_1__D_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rd := x & (1<<5 - 1)
+		if size == 1 {
+			return S0 + Reg(Rd)
+		} else if size == 2 {
+			return D0 + Reg(Rd)
+		} else {
+			return nil
+		}
+
+	case arg_Vd_arrangement_16B:
+		Rd := x & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+
+	case arg_Vd_arrangement_2D:
+		Rd := x & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+
+	case arg_Vd_arrangement_4S:
+		Rd := x & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+
+	case arg_Vd_arrangement_D_index__1:
+		Rd := x & (1<<5 - 1)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rd), ArrangementD, 1, 0}
+
+	case arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1:
+		var a Arrangement
+		var index uint32
+		Rd := x & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if imm5&1 == 1 {
+			a = ArrangementB
+			index = imm5 >> 1
+		} else if imm5&2 == 2 {
+			a = ArrangementH
+			index = imm5 >> 2
+		} else if imm5&4 == 4 {
+			a = ArrangementS
+			index = imm5 >> 3
+		} else if imm5&8 == 8 {
+			a = ArrangementD
+			index = imm5 >> 4
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rd), a, uint8(index), 0}
+
+	case arg_Vd_arrangement_imm5_Q___8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81:
+		Rd := x & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if imm5&1 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+			}
+		} else if imm5&2 == 2 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+			}
+		} else if imm5&4 == 4 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+			}
+		} else if (imm5&8 == 8) && (Q == 1) {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		} else {
+			return nil
+		}
+
+	case arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81:
+		Rd := x & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+			}
+		} else if immh>>3 == 1 {
+			if Q == 1 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+			}
+		}
+		return nil
+
+	case arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41:
+		Rd := x & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+			}
+		} else if immh>>1 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+			}
+		} else if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+			}
+		}
+		return nil
+
+	case arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81:
+		Rd := x & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+			}
+		} else if immh>>1 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+			}
+		} else if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+			}
+		} else if immh>>3 == 1 {
+			if Q == 1 {
+				return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+			}
+		}
+		return nil
+
+	case arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4:
+		Rd := x & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		if immh == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if immh>>1 == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if immh>>2 == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_Q___2S_0__4S_1:
+		Rd := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+
+	case arg_Vd_arrangement_Q___4H_0__8H_1:
+		Rd := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		}
+
+	case arg_Vd_arrangement_Q___8B_0__16B_1:
+		Rd := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+		}
+
+	case arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11:
+		Rd := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		sz := (x >> 22) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size___4S_1__2D_2:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if size == 2 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size___8H_0__1Q_3:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 3 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement1Q, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size___8H_0__4S_1__2D_2:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if size == 2 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement1D, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___8B_00__16B_01:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rd := x & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_sz___4S_0__2D_1:
+		Rd := x & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		if sz == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+
+	case arg_Vd_arrangement_sz_Q___2S_00__4S_01:
+		Rd := x & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11:
+		Rd := x & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_sz_Q___2S_10__4S_11:
+		Rd := x & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vd_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11:
+		Rd := x & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4H, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement8H, 0}
+		} else if sz == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement2S, 0}
+		} else /* sz == 1 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rd), Arrangement4S, 0}
+		}
+
+	case arg_Vm_22_1__S_0__D_1:
+		sz := (x >> 22) & 1
+		Rm := (x >> 16) & (1<<5 - 1)
+		if sz == 0 {
+			return S0 + Reg(Rm)
+		} else {
+			return D0 + Reg(Rm)
+		}
+
+	case arg_Vm_22_2__B_0__H_1__S_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rm := (x >> 16) & (1<<5 - 1)
+		if size == 0 {
+			return B0 + Reg(Rm)
+		} else if size == 1 {
+			return H0 + Reg(Rm)
+		} else if size == 2 {
+			return S0 + Reg(Rm)
+		} else {
+			return D0 + Reg(Rm)
+		}
+
+	case arg_Vm_22_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rm := (x >> 16) & (1<<5 - 1)
+		if size == 3 {
+			return D0 + Reg(Rm)
+		} else {
+			return nil
+		}
+
+	case arg_Vm_22_2__H_1__S_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rm := (x >> 16) & (1<<5 - 1)
+		if size == 1 {
+			return H0 + Reg(Rm)
+		} else if size == 2 {
+			return S0 + Reg(Rm)
+		} else {
+			return nil
+		}
+
+	case arg_Vm_arrangement_4S:
+		Rm := (x >> 16) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+
+	case arg_Vm_arrangement_Q___8B_0__16B_1:
+		Rm := (x >> 16) & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8B, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement16B, 0}
+		}
+
+	case arg_Vm_arrangement_size___8H_0__4S_1__2D_2:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8H, 0}
+		} else if size == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+		} else if size == 2 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1:
+		var a Arrangement
+		var index uint32
+		var vm uint32
+		Rm := (x >> 16) & (1<<4 - 1)
+		size := (x >> 22) & 3
+		H := (x >> 11) & 1
+		L := (x >> 21) & 1
+		M := (x >> 20) & 1
+		if size == 1 {
+			a = ArrangementH
+			index = (H << 2) | (L << 1) | M
+			vm = Rm
+		} else if size == 2 {
+			a = ArrangementS
+			index = (H << 1) | L
+			vm = (M << 4) | Rm
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(vm), a, uint8(index), 0}
+
+	case arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_size_Q___8B_00__16B_01:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement16B, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement16B, 0}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement1D, 0}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rm := (x >> 16) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11:
+		Rm := (x >> 16) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement4S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rm), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1:
+		var a Arrangement
+		var index uint32
+		Rm := (x >> 16) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		H := (x >> 11) & 1
+		L := (x >> 21) & 1
+		if sz == 0 {
+			a = ArrangementS
+			index = (H << 1) | L
+		} else if sz == 1 && L == 0 {
+			a = ArrangementD
+			index = H
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rm), a, uint8(index), 0}
+
+	case arg_Vn_19_4__B_1__H_2__S_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if immh == 1 {
+			return B0 + Reg(Rn)
+		} else if immh>>1 == 1 {
+			return H0 + Reg(Rn)
+		} else if immh>>2 == 1 {
+			return S0 + Reg(Rn)
+		} else if immh>>3 == 1 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_19_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if immh>>3 == 1 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_19_4__H_1__S_2__D_4:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if immh == 1 {
+			return H0 + Reg(Rn)
+		} else if immh>>1 == 1 {
+			return S0 + Reg(Rn)
+		} else if immh>>2 == 1 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_19_4__S_4__D_8:
+		immh := (x >> 19) & (1<<4 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if immh>>2 == 1 {
+			return S0 + Reg(Rn)
+		} else if immh>>3 == 1 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_1_arrangement_16B:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 1}
+
+	case arg_Vn_22_1__D_1:
+		sz := (x >> 22) & 1
+		Rn := (x >> 5) & (1<<5 - 1)
+		if sz == 1 {
+			return D0 + Reg(Rn)
+		}
+		return nil
+
+	case arg_Vn_22_1__S_0__D_1:
+		sz := (x >> 22) & 1
+		Rn := (x >> 5) & (1<<5 - 1)
+		if sz == 0 {
+			return S0 + Reg(Rn)
+		} else {
+			return D0 + Reg(Rn)
+		}
+
+	case arg_Vn_22_2__B_0__H_1__S_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if size == 0 {
+			return B0 + Reg(Rn)
+		} else if size == 1 {
+			return H0 + Reg(Rn)
+		} else if size == 2 {
+			return S0 + Reg(Rn)
+		} else {
+			return D0 + Reg(Rn)
+		}
+
+	case arg_Vn_22_2__D_3:
+		size := (x >> 22) & (1<<2 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if size == 3 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_22_2__H_0__S_1__D_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if size == 0 {
+			return H0 + Reg(Rn)
+		} else if size == 1 {
+			return S0 + Reg(Rn)
+		} else if size == 2 {
+			return D0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_22_2__H_1__S_2:
+		size := (x >> 22) & (1<<2 - 1)
+		Rn := (x >> 5) & (1<<5 - 1)
+		if size == 1 {
+			return H0 + Reg(Rn)
+		} else if size == 2 {
+			return S0 + Reg(Rn)
+		} else {
+			return nil
+		}
+
+	case arg_Vn_2_arrangement_16B:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 2}
+
+	case arg_Vn_3_arrangement_16B:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 3}
+
+	case arg_Vn_4_arrangement_16B:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 4}
+
+	case arg_Vn_arrangement_16B:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+
+	case arg_Vn_arrangement_4S:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+
+	case arg_Vn_arrangement_D_index__1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), ArrangementD, 1, 0}
+
+	case arg_Vn_arrangement_D_index__imm5_1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		index := (x >> 20) & 1
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), ArrangementD, uint8(index), 0}
+
+	case arg_Vn_arrangement_imm5___B_1__H_2_index__imm5__imm5lt41gt_1__imm5lt42gt_2_1:
+		var a Arrangement
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if imm5&1 == 1 {
+			a = ArrangementB
+			index = imm5 >> 1
+		} else if imm5&2 == 2 {
+			a = ArrangementH
+			index = imm5 >> 2
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), a, uint8(index), 0}
+
+	case arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5_imm4__imm4lt30gt_1__imm4lt31gt_2__imm4lt32gt_4__imm4lt3gt_8_1:
+		var a Arrangement
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		imm4 := (x >> 11) & (1<<4 - 1)
+		if imm5&1 == 1 {
+			a = ArrangementB
+			index = imm4
+		} else if imm5&2 == 2 {
+			a = ArrangementH
+			index = imm4 >> 1
+		} else if imm5&4 == 4 {
+			a = ArrangementS
+			index = imm4 >> 2
+		} else if imm5&8 == 8 {
+			a = ArrangementD
+			index = imm4 >> 3
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), a, uint8(index), 0}
+
+	case arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1:
+		var a Arrangement
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if imm5&1 == 1 {
+			a = ArrangementB
+			index = imm5 >> 1
+		} else if imm5&2 == 2 {
+			a = ArrangementH
+			index = imm5 >> 2
+		} else if imm5&4 == 4 {
+			a = ArrangementS
+			index = imm5 >> 3
+		} else if imm5&8 == 8 {
+			a = ArrangementD
+			index = imm5 >> 4
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), a, uint8(index), 0}
+
+	case arg_Vn_arrangement_imm5___B_1__H_2__S_4_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1:
+		var a Arrangement
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if imm5&1 == 1 {
+			a = ArrangementB
+			index = imm5 >> 1
+		} else if imm5&2 == 2 {
+			a = ArrangementH
+			index = imm5 >> 2
+		} else if imm5&4 == 4 {
+			a = ArrangementS
+			index = imm5 >> 3
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), a, uint8(index), 0}
+
+	case arg_Vn_arrangement_imm5___D_8_index__imm5_1:
+		var a Arrangement
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		if imm5&15 == 8 {
+			a = ArrangementD
+			index = imm5 >> 4
+		} else {
+			return nil
+		}
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), a, uint8(index), 0}
+
+	case arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81:
+		Rn := (x >> 5) & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+			}
+		} else if immh>>3 == 1 {
+			if Q == 1 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+			}
+		}
+		return nil
+
+	case arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41:
+		Rn := (x >> 5) & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+			}
+		} else if immh>>1 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+			}
+		} else if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+			}
+		}
+		return nil
+
+	case arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81:
+		Rn := (x >> 5) & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		Q := (x >> 30) & 1
+		if immh == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+			}
+		} else if immh>>1 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+			}
+		} else if immh>>2 == 1 {
+			if Q == 0 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+			} else {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+			}
+		} else if immh>>3 == 1 {
+			if Q == 1 {
+				return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+			}
+		}
+		return nil
+
+	case arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4:
+		Rn := (x >> 5) & (1<<5 - 1)
+		immh := (x >> 19) & (1<<4 - 1)
+		if immh == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if immh>>1 == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else if immh>>2 == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_Q___8B_0__16B_1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		if Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		}
+
+	case arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11:
+		Rn := (x >> 5) & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		sz := (x >> 22) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_Q_sz___4S_10:
+		Rn := (x >> 5) & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		sz := (x >> 22) & 1
+		if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_S_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1:
+		var index uint32
+		Rn := (x >> 5) & (1<<5 - 1)
+		imm5 := (x >> 16) & (1<<5 - 1)
+		index = imm5 >> 3
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rn), ArrangementS, uint8(index), 0}
+
+	case arg_Vn_arrangement_size___2D_3:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 3 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size___8H_0__4S_1__2D_2:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		if size == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if size == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else if size == 2 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement1D, 0}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21:
+		Rn := (x >> 5) & (1<<5 - 1)
+		size := (x >> 22) & 3
+		Q := (x >> 30) & 1
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8B, 0}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement16B, 0}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_sz___2D_1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		if sz == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_sz___2S_0__2D_1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		if sz == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+
+	case arg_Vn_arrangement_sz___4S_0__2D_1:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		if sz == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+
+	case arg_Vn_arrangement_sz_Q___2S_00__4S_01:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		} else if sz == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2D, 0}
+		}
+		return nil
+
+	case arg_Vn_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11:
+		Rn := (x >> 5) & (1<<5 - 1)
+		sz := (x >> 22) & 1
+		Q := (x >> 30) & 1
+		if sz == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4H, 0}
+		} else if sz == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement8H, 0}
+		} else if sz == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement2S, 0}
+		} else /* sz == 1 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rn), Arrangement4S, 0}
+		}
+
+	case arg_Vt_1_arrangement_B_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 10) & 3
+		index := (Q << 3) | (S << 2) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementB, uint8(index), 1}
+
+	case arg_Vt_1_arrangement_D_index__Q_1:
+		Rt := x & (1<<5 - 1)
+		index := (x >> 30) & 1
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementD, uint8(index), 1}
+
+	case arg_Vt_1_arrangement_H_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 11) & 1
+		index := (Q << 2) | (S << 1) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementH, uint8(index), 1}
+
+	case arg_Vt_1_arrangement_S_index__Q_S_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		index := (Q << 1) | S
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementS, uint8(index), 1}
+
+	case arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 1}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 1}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 1}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 1}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 1}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 1}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement1D, 1}
+		} else /* size == 3 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 1}
+		}
+
+	case arg_Vt_2_arrangement_B_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 10) & 3
+		index := (Q << 3) | (S << 2) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementB, uint8(index), 2}
+
+	case arg_Vt_2_arrangement_D_index__Q_1:
+		Rt := x & (1<<5 - 1)
+		index := (x >> 30) & 1
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementD, uint8(index), 2}
+
+	case arg_Vt_2_arrangement_H_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 11) & 1
+		index := (Q << 2) | (S << 1) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementH, uint8(index), 2}
+
+	case arg_Vt_2_arrangement_S_index__Q_S_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		index := (Q << 1) | S
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementS, uint8(index), 2}
+
+	case arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 2}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 2}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 2}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 2}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 2}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 2}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement1D, 2}
+		} else /* size == 3 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 2}
+		}
+
+	case arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 2}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 2}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 2}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 2}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 2}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 2}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 2}
+		}
+		return nil
+
+	case arg_Vt_3_arrangement_B_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 10) & 3
+		index := (Q << 3) | (S << 2) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementB, uint8(index), 3}
+
+	case arg_Vt_3_arrangement_D_index__Q_1:
+		Rt := x & (1<<5 - 1)
+		index := (x >> 30) & 1
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementD, uint8(index), 3}
+
+	case arg_Vt_3_arrangement_H_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 11) & 1
+		index := (Q << 2) | (S << 1) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementH, uint8(index), 3}
+
+	case arg_Vt_3_arrangement_S_index__Q_S_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		index := (Q << 1) | S
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementS, uint8(index), 3}
+
+	case arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 3}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 3}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 3}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 3}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 3}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 3}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement1D, 3}
+		} else /* size == 3 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 3}
+		}
+
+	case arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 3}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 3}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 3}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 3}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 3}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 3}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 3}
+		}
+		return nil
+
+	case arg_Vt_4_arrangement_B_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 10) & 3
+		index := (Q << 3) | (S << 2) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementB, uint8(index), 4}
+
+	case arg_Vt_4_arrangement_D_index__Q_1:
+		Rt := x & (1<<5 - 1)
+		index := (x >> 30) & 1
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementD, uint8(index), 4}
+
+	case arg_Vt_4_arrangement_H_index__Q_S_size_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		size := (x >> 11) & 1
+		index := (Q << 2) | (S << 1) | (size)
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementH, uint8(index), 4}
+
+	case arg_Vt_4_arrangement_S_index__Q_S_1:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		S := (x >> 12) & 1
+		index := (Q << 1) | S
+		return RegisterWithArrangementAndIndex{V0 + Reg(Rt), ArrangementS, uint8(index), 4}
+
+	case arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 4}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 4}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 4}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 4}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 4}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 4}
+		} else if size == 3 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement1D, 4}
+		} else /* size == 3 && Q == 1 */ {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 4}
+		}
+
+	case arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31:
+		Rt := x & (1<<5 - 1)
+		Q := (x >> 30) & 1
+		size := (x >> 10) & 3
+		if size == 0 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8B, 4}
+		} else if size == 0 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement16B, 4}
+		} else if size == 1 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4H, 4}
+		} else if size == 1 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement8H, 4}
+		} else if size == 2 && Q == 0 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2S, 4}
+		} else if size == 2 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement4S, 4}
+		} else if size == 3 && Q == 1 {
+			return RegisterWithArrangement{V0 + Reg(Rt), Arrangement2D, 4}
+		}
+		return nil
+
+	case arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__4_1:
+		return handle_MemExtend(x, 4, false)
+
+	case arg_Xns_mem_offset:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrOffset, 0}
+
+	case arg_Xns_mem_optional_imm12_16_unsigned:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm12 := (x >> 10) & (1<<12 - 1)
+		return MemImmediate{Rn, AddrOffset, int32(imm12 << 4)}
+
+	case arg_Xns_mem_optional_imm7_16_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrOffset, ((int32(imm7 << 4)) << 21) >> 21}
+
+	case arg_Xns_mem_post_fixedimm_1:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 1}
+
+	case arg_Xns_mem_post_fixedimm_12:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 12}
+
+	case arg_Xns_mem_post_fixedimm_16:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 16}
+
+	case arg_Xns_mem_post_fixedimm_2:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 2}
+
+	case arg_Xns_mem_post_fixedimm_24:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 24}
+
+	case arg_Xns_mem_post_fixedimm_3:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 3}
+
+	case arg_Xns_mem_post_fixedimm_32:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 32}
+
+	case arg_Xns_mem_post_fixedimm_4:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 4}
+
+	case arg_Xns_mem_post_fixedimm_6:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 6}
+
+	case arg_Xns_mem_post_fixedimm_8:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		return MemImmediate{Rn, AddrPostIndex, 8}
+
+	case arg_Xns_mem_post_imm7_16_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPostIndex, ((int32(imm7 << 4)) << 21) >> 21}
+
+	case arg_Xns_mem_post_Q__16_0__32_1:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		Q := (x >> 30) & 1
+		return MemImmediate{Rn, AddrPostIndex, int32((Q + 1) * 16)}
+
+	case arg_Xns_mem_post_Q__24_0__48_1:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		Q := (x >> 30) & 1
+		return MemImmediate{Rn, AddrPostIndex, int32((Q + 1) * 24)}
+
+	case arg_Xns_mem_post_Q__32_0__64_1:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		Q := (x >> 30) & 1
+		return MemImmediate{Rn, AddrPostIndex, int32((Q + 1) * 32)}
+
+	case arg_Xns_mem_post_Q__8_0__16_1:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		Q := (x >> 30) & 1
+		return MemImmediate{Rn, AddrPostIndex, int32((Q + 1) * 8)}
+
+	case arg_Xns_mem_post_size__1_0__2_1__4_2__8_3:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		size := (x >> 10) & 3
+		return MemImmediate{Rn, AddrPostIndex, int32(1 << size)}
+
+	case arg_Xns_mem_post_size__2_0__4_1__8_2__16_3:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		size := (x >> 10) & 3
+		return MemImmediate{Rn, AddrPostIndex, int32(2 << size)}
+
+	case arg_Xns_mem_post_size__3_0__6_1__12_2__24_3:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		size := (x >> 10) & 3
+		return MemImmediate{Rn, AddrPostIndex, int32(3 << size)}
+
+	case arg_Xns_mem_post_size__4_0__8_1__16_2__32_3:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		size := (x >> 10) & 3
+		return MemImmediate{Rn, AddrPostIndex, int32(4 << size)}
+
+	case arg_Xns_mem_post_Xm:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		Rm := (x >> 16) & (1<<5 - 1)
+		return MemImmediate{Rn, AddrPostReg, int32(Rm)}
+
+	case arg_Xns_mem_wb_imm7_16_signed:
+		Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+		imm7 := (x >> 15) & (1<<7 - 1)
+		return MemImmediate{Rn, AddrPreIndex, ((int32(imm7 << 4)) << 21) >> 21}
+	}
+}
+
+func handle_ExtendedRegister(x uint32, has_width bool) Arg {
+	s := (x >> 29) & 1
+	rm := (x >> 16) & (1<<5 - 1)
+	option := (x >> 13) & (1<<3 - 1)
+	imm3 := (x >> 10) & (1<<3 - 1)
+	rn := (x >> 5) & (1<<5 - 1)
+	rd := x & (1<<5 - 1)
+	is_32bit := !has_width
+	var rea RegExtshiftAmount
+	if has_width {
+		if option&0x3 != 0x3 {
+			rea.reg = W0 + Reg(rm)
+		} else {
+			rea.reg = X0 + Reg(rm)
+		}
+	} else {
+		rea.reg = W0 + Reg(rm)
+	}
+	switch option {
+	case 0:
+		rea.extShift = uxtb
+	case 1:
+		rea.extShift = uxth
+	case 2:
+		if is_32bit && (rn == 31 || (s == 0 && rd == 31)) {
+			if imm3 != 0 {
+				rea.extShift = lsl
+			} else {
+				rea.extShift = ExtShift(0)
+			}
+		} else {
+			rea.extShift = uxtw
+		}
+	case 3:
+		if !is_32bit && (rn == 31 || (s == 0 && rd == 31)) {
+			if imm3 != 0 {
+				rea.extShift = lsl
+			} else {
+				rea.extShift = ExtShift(0)
+			}
+		} else {
+			rea.extShift = uxtx
+		}
+	case 4:
+		rea.extShift = sxtb
+	case 5:
+		rea.extShift = sxth
+	case 6:
+		rea.extShift = sxtw
+	case 7:
+		rea.extShift = sxtx
+	}
+	rea.show_zero = false
+	rea.amount = uint8(imm3)
+	return rea
+}
+
+func handle_ImmediateShiftedRegister(x uint32, max uint8, is_w, has_ror bool) Arg {
+	var rsa RegExtshiftAmount
+	if is_w {
+		rsa.reg = W0 + Reg((x>>16)&(1<<5-1))
+	} else {
+		rsa.reg = X0 + Reg((x>>16)&(1<<5-1))
+	}
+	switch (x >> 22) & 0x3 {
+	case 0:
+		rsa.extShift = lsl
+	case 1:
+		rsa.extShift = lsr
+	case 2:
+		rsa.extShift = asr
+	case 3:
+		if has_ror {
+			rsa.extShift = ror
+		} else {
+			return nil
+		}
+	}
+	rsa.show_zero = true
+	rsa.amount = uint8((x >> 10) & (1<<6 - 1))
+	if rsa.amount == 0 && rsa.extShift == lsl {
+		rsa.extShift = ExtShift(0)
+	} else if rsa.amount > max {
+		return nil
+	}
+	return rsa
+}
+
+func handle_MemExtend(x uint32, mult uint8, absent bool) Arg {
+	var extend ExtShift
+	var Rm Reg
+	option := (x >> 13) & (1<<3 - 1)
+	Rn := RegSP(X0) + RegSP(x>>5&(1<<5-1))
+	if (option & 1) != 0 {
+		Rm = Reg(X0) + Reg(x>>16&(1<<5-1))
+	} else {
+		Rm = Reg(W0) + Reg(x>>16&(1<<5-1))
+	}
+	switch option {
+	default:
+		return nil
+	case 2:
+		extend = uxtw
+	case 3:
+		extend = lsl
+	case 6:
+		extend = sxtw
+	case 7:
+		extend = sxtx
+	}
+	amount := (uint8((x >> 12) & 1)) * mult
+	return MemExtend{Rn, Rm, extend, amount, absent}
+}
+
+func handle_bitmasks(x uint32, datasize uint8) Arg {
+	var length, levels, esize, i uint8
+	var welem, wmask uint64
+	n := (x >> 22) & 1
+	imms := uint8((x >> 10) & (1<<6 - 1))
+	immr := uint8((x >> 16) & (1<<6 - 1))
+	if n != 0 {
+		length = 6
+	} else if (imms & 32) == 0 {
+		length = 5
+	} else if (imms & 16) == 0 {
+		length = 4
+	} else if (imms & 8) == 0 {
+		length = 3
+	} else if (imms & 4) == 0 {
+		length = 2
+	} else if (imms & 2) == 0 {
+		length = 1
+	} else {
+		return nil
+	}
+	levels = 1<<length - 1
+	s := imms & levels
+	r := immr & levels
+	esize = 1 << length
+	if esize > datasize {
+		return nil
+	}
+	welem = 1<<(s+1) - 1
+	ror := (welem >> r) | (welem << (esize - r))
+	ror &= ((1 << esize) - 1)
+	wmask = 0
+	for i = 0; i < datasize; i += esize {
+		wmask = (wmask << esize) | ror
+	}
+	return Imm64{wmask, false}
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode_test.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode_test.go
new file mode 100644
index 0000000..a79ee1c
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/decode_test.go
@@ -0,0 +1,78 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"encoding/hex"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func TestDecode(t *testing.T) {
+	data, err := ioutil.ReadFile("testdata/cases.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", 3)
+		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])
+		}
+		code, err := hex.DecodeString(f[0][:i] + f[0][i+1:])
+		if err != nil {
+			t.Errorf("parsing %q: %v", f[0], err)
+			continue
+		}
+		syntax, asm := f[1], f[2]
+		inst, decodeErr := Decode(code)
+		if decodeErr != nil && decodeErr != errUnknown {
+			// Some rarely used system instructions are not supported
+			// Following logicals will filter such unknown instructions
+
+			t.Errorf("parsing %x: %s", code, decodeErr)
+			continue
+		}
+		var out string
+		switch syntax {
+		case "gnu":
+			out = GNUSyntax(inst)
+		case "plan9":
+			out = GoSyntax(inst, 0, nil, nil)
+		default:
+			t.Errorf("unknown syntax %q", syntax)
+			continue
+		}
+		// TODO: system instruction.
+		var Todo = strings.Fields(`
+			sys
+			dc
+			at
+			tlbi
+			ic
+			hvc
+			smc
+		`)
+		if strings.Replace(out, " ", "", -1) != strings.Replace(asm, " ", "", -1) && !hasPrefix(asm, Todo...) {
+			// Exclude MSR since GNU objdump result is incorrect. eg. 0xd504431f msr s0_4_c4_c3_0, xzr
+			if !strings.HasSuffix(asm, " nv") && !strings.HasPrefix(asm, "msr") {
+				t.Errorf("Decode(%s) [%s] = %s, want %s", f[0], syntax, out, asm)
+			}
+		}
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/ext_test.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/ext_test.go
new file mode 100644
index 0000000..bf0ee13
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/ext_test.go
@@ -0,0 +1,601 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for testing against external disassembler program.
+// Copied and simplified from ../../arm/armasm/ext_test.go.
+
+package arm64asm
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/hex"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"math/rand"
+	"os"
+	"os/exec"
+	"regexp"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+var (
+	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
+)
+
+// An ExtInst represents a single decoded instruction parsed
+// from an external disassembler's output.
+type ExtInst struct {
+	addr uint64
+	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
+}
+
+// InstJson describes instruction fields value got from ARMv8-A Reference Manual
+type InstJson struct {
+	Name   string
+	Bits   string
+	Arch   string
+	Syntax string
+	Code   string
+	Alias  string
+	Enc    uint32
+}
+
+// A Mode is an instruction execution mode.
+type Mode int
+
+const (
+	_ Mode = iota
+	ModeARM64
+)
+
+// 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 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, 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, pad(enc))
+
+		totalTests++
+		if *dumpTest {
+			fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc)
+		}
+		if text != dec.text && !strings.Contains(dec.text, "unknown") && syntax == "gnu" {
+			suffix := ""
+			if allowedMismatch(text, &inst, dec) {
+				totalSkips++
+				if !*mismatch {
+					return
+				}
+				suffix += " (allowed mismatch)"
+			}
+			totalErrors++
+			cmp := fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s\n", enc, text, len(enc), dec.text, dec.nenc, suffix)
+
+			if len(errors) >= cap(errors) {
+				j := rand.Intn(totalErrors)
+				if j >= cap(errors) {
+					return
+				}
+				errors = append(errors[:j], errors[j+1:]...)
+			}
+			errors = append(errors, cmp)
+		}
+	})
+
+	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())
+	t.Logf("decoder coverage: %.1f%%;\n", decodeCoverage())
+	if err := <-errc; err != nil {
+		t.Fatalf("external disassembler: %v", err)
+	}
+
+}
+
+// Start address of text.
+const start = 0x8000
+
+// 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("", "arm64asm")
+	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 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 sequence 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, src []byte) (inst Inst, text string) {
+	var err error
+	inst, err = Decode(src)
+	if err != nil {
+		text = "error: " + err.Error()
+		return
+	}
+	text = inst.String()
+	switch syntax {
+	case "gnu":
+		text = GNUSyntax(inst)
+	case "plan9": // [sic]
+		text = GoSyntax(inst, 0, nil, nil)
+	default:
+		text = "error: unknown syntax " + syntax
+	}
+	return
+}
+
+// decodecoverage returns a floating point number denoting the
+// decoder coverage.
+func decodeCoverage() float64 {
+	n := 0
+	for _, t := range decoderCover {
+		if t {
+			n++
+		}
+	}
+	return 100 * 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 cur_s := s; cur_s != ""; {
+			if strings.HasPrefix(cur_s, prefix) {
+				return true
+			}
+			i := strings.Index(cur_s, " ")
+			if i < 0 {
+				break
+			}
+			cur_s = cur_s[i+1:]
+		}
+	}
+	return false
+}
+
+// isHex reports whether b is a hexadecimal character (0-9a-fA-F).
+func isHex(b byte) bool {
+	return ('0' <= b && b <= '9') || ('a' <= b && b <= 'f') || ('A' <= b && b <= 'F')
+}
+
+// parseHex parses the hexadecimal byte dump in hex,
+// appending the parsed bytes to raw and returning the updated slice.
+// The returned bool reports 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 = bytes.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
+}
+
+func unhex(b byte) byte {
+	if '0' <= b && b <= '9' {
+		return b - '0'
+	} else if 'A' <= b && b <= 'F' {
+		return b - 'A' + 10
+	} else if 'a' <= b && b <= 'f' {
+		return b - 'a' + 10
+	}
+	return 0
+}
+
+// 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 = bytes.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]
+}
+
+// Fllowing regular expressions matches instructions using relative addressing mode.
+// pcrel matches B instructions and BL instructions.
+// pcrelr matches instrucions which consisted of register arguments and label arguments.
+// pcrelim matches instructions which consisted of register arguments, immediate
+// arguments and lable arguments.
+// pcrelrzr and prcelimzr matches instructions when register arguments is zero register.
+// pcrelprfm matches PRFM instructions when arguments consisted of register and lable.
+// pcrelprfmim matches PRFM instructions when arguments consisted of immediate and lable.
+var (
+	pcrel       = regexp.MustCompile(`^((?:.* )?(?:b|bl)x?(?:\.)?(?:eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|nv)?) 0x([0-9a-f]+)$`)
+	pcrelr      = regexp.MustCompile(`^((?:.*)?(?:ldr|adrp|adr|cbnz|cbz|ldrsw) (?:x|w|s|d|q)(?:[0-9]+,)) 0x([0-9a-f]+)$`)
+	pcrelrzr    = regexp.MustCompile(`^((?:.*)?(?:ldr|adrp|adr|cbnz|cbz|ldrsw) (?:x|w)zr,) 0x([0-9a-f]+)$`)
+	pcrelim     = regexp.MustCompile(`^((?:.*)?(?:tbnz|tbz) (?:x|w)(?:[0-9]+,) (?:#[0-9a-f]+,)) 0x([0-9a-f]+)$`)
+	pcrelimzr   = regexp.MustCompile(`^((?:.*)?(?:tbnz|tbz) (?:x|w)zr, (?:#[0-9a-f]+,)) 0x([0-9a-f]+)$`)
+	pcrelprfm   = regexp.MustCompile(`^((?:.*)?(?:prfm) (?:[0-9a-z]+,)) 0x([0-9a-f]+)$`)
+	pcrelprfmim = regexp.MustCompile(`^((?:.*)?(?:prfm) (?:#0x[0-9a-f]+,)) 0x([0-9a-f]+)$`)
+)
+
+// Round is the multiple of the number of instructions that read from Json file.
+// Round used as seed value for pseudo-random number generator provides the same sequence
+// in the same round run for the external disassembler and decoder.
+var Round int
+
+// condmark is used to mark conditional instructions when need to generate and test
+// conditional instructions.
+var condmark bool = false
+
+// Generate instruction binary according to Json file
+// Encode variable field of instruction with random value
+func doFuzzy(inst *InstJson, Ninst int) {
+	var testdata uint32
+	var NonDigRE = regexp.MustCompile(`[\D]`)
+	rand.Seed(int64(Round + Ninst))
+	off := 0
+	DigBit := ""
+	if condmark == true && !strings.Contains(inst.Bits, "cond") {
+		inst.Enc = 0xffffffff
+	} else {
+		for _, f := range strings.Split(inst.Bits, "|") {
+			if i := strings.Index(f, ":"); i >= 0 {
+				// consider f contains "01:2" and "Rm:5"
+				DigBit = f[:i]
+				m := NonDigRE.FindStringSubmatch(DigBit)
+				if m == nil {
+					DigBit = strings.TrimSpace(DigBit)
+					s := strings.Split(DigBit, "")
+					for i := 0; i < len(s); i++ {
+						switch s[i] {
+						case "1", "(1)":
+							testdata |= 1 << uint(31-off)
+						}
+						off++
+					}
+				} else {
+					// DigBit is "Rn" or "imm3"
+					n, _ := strconv.Atoi(f[i+1:])
+					if DigBit == "cond" && condmark == true {
+						r := uint8(Round)
+						for i := n - 1; i >= 0; i-- {
+							switch (r >> uint(i)) & 1 {
+							case 1:
+								testdata |= 1 << uint(31-off)
+							}
+							off++
+						}
+					} else {
+						for i := 0; i < n; i++ {
+							r := rand.Intn(2)
+							switch r {
+							case 1:
+								testdata |= 1 << uint(31-off)
+							}
+							off++
+						}
+					}
+				}
+				continue
+			}
+			for _, bit := range strings.Fields(f) {
+				switch bit {
+				case "0", "(0)":
+					off++
+					continue
+				case "1", "(1)":
+					testdata |= 1 << uint(31-off)
+				default:
+					r := rand.Intn(2)
+					switch r {
+					case 1:
+						testdata |= 1 << uint(31-off)
+					}
+				}
+				off++
+			}
+		}
+		if off != 32 {
+			log.Printf("incorrect bit count for %s %s: have %d", inst.Name, inst.Bits, off)
+		}
+		inst.Enc = testdata
+	}
+}
+
+// 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.
+
+// JSONCases generates ARM64 instructions according to inst.json.
+func JSONCases(t *testing.T) func(func([]byte)) {
+	return func(try func([]byte)) {
+		data, err := ioutil.ReadFile("inst.json")
+		if err != nil {
+			t.Fatal(err)
+		}
+		var insts []InstJson
+		var instsN []InstJson
+		// Change N value to get more cases only when condmark=false.
+		N := 100
+		if condmark == true {
+			N = 16
+		}
+		if err := json.Unmarshal(data, &insts); err != nil {
+			t.Fatal(err)
+		}
+		// Append instructions to get more test cases.
+		for i := 0; i < N; {
+			for _, inst := range insts {
+				instsN = append(instsN, inst)
+			}
+			i++
+		}
+		Round = 0
+		for i := range instsN {
+			if i%len(insts) == 0 {
+				Round++
+			}
+			doFuzzy(&instsN[i], i)
+		}
+		for _, inst := range instsN {
+			if condmark == true && inst.Enc == 0xffffffff {
+				continue
+			}
+			enc := inst.Enc
+			try([]byte{byte(enc), byte(enc >> 8), byte(enc >> 16), byte(enc >> 24)})
+		}
+	}
+}
+
+// condCases generates conditional instructions.
+func condCases(t *testing.T) func(func([]byte)) {
+	return func(try func([]byte)) {
+		condmark = true
+		JSONCases(t)(func(enc []byte) {
+			try(enc)
+		})
+	}
+}
+
+// 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/cases.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/cases.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)
+		}
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/gnu.go
new file mode 100644
index 0000000..d1be046
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/gnu.go
@@ -0,0 +1,35 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"strings"
+)
+
+// 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 {
+	switch inst.Op {
+	case RET:
+		if r, ok := inst.Args[0].(Reg); ok && r == X30 {
+			return "ret"
+		}
+	case B:
+		if _, ok := inst.Args[0].(Cond); ok {
+			return strings.ToLower("b." + inst.Args[0].String() + " " + inst.Args[1].String())
+		}
+	case SYSL:
+		result := strings.ToLower(inst.String())
+		return strings.Replace(result, "c", "C", -1)
+	case DCPS1, DCPS2, DCPS3, CLREX:
+		return strings.ToLower(strings.TrimSpace(inst.String()))
+	case ISB:
+		if strings.Contains(inst.String(), "SY") {
+			result := strings.TrimSuffix(inst.String(), " SY")
+			return strings.ToLower(result)
+		}
+	}
+	return strings.ToLower(inst.String())
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go
new file mode 100644
index 0000000..3ff31be
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go
@@ -0,0 +1,963 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"fmt"
+	"strings"
+)
+
+// An Op is an ARM64 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.
+	Args Args   // Instruction arguments, in ARM manual order.
+}
+
+func (i Inst) String() string {
+	var args []string
+	for _, arg := range i.Args {
+		if arg == nil {
+			break
+		}
+		args = append(args, arg.String())
+	}
+	return i.Op.String() + " " + strings.Join(args, ", ")
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 5 arguments,
+// the final elements in the array are nil.
+type Args [5]Arg
+
+// An Arg is a single instruction argument, one of these types:
+// Reg, RegSP, ImmShift, RegExtshiftAmount, PCRel, MemImmediate,
+// MemExtend, Imm, Imm64, Imm_hint, Imm_clrex, Imm_dcps, Cond,
+// Imm_c, Imm_option, Imm_prfop, Pstatefield, Systemreg, Imm_fp
+// RegisterWithArrangement, RegisterWithArrangementAndIndex.
+type Arg interface {
+	isArg()
+	String() string
+}
+
+// A Reg is a single register.
+// The zero value denotes W0, not the absence of a register.
+type Reg uint16
+
+const (
+	W0 Reg = iota
+	W1
+	W2
+	W3
+	W4
+	W5
+	W6
+	W7
+	W8
+	W9
+	W10
+	W11
+	W12
+	W13
+	W14
+	W15
+	W16
+	W17
+	W18
+	W19
+	W20
+	W21
+	W22
+	W23
+	W24
+	W25
+	W26
+	W27
+	W28
+	W29
+	W30
+	WZR
+
+	X0
+	X1
+	X2
+	X3
+	X4
+	X5
+	X6
+	X7
+	X8
+	X9
+	X10
+	X11
+	X12
+	X13
+	X14
+	X15
+	X16
+	X17
+	X18
+	X19
+	X20
+	X21
+	X22
+	X23
+	X24
+	X25
+	X26
+	X27
+	X28
+	X29
+	X30
+	XZR
+
+	B0
+	B1
+	B2
+	B3
+	B4
+	B5
+	B6
+	B7
+	B8
+	B9
+	B10
+	B11
+	B12
+	B13
+	B14
+	B15
+	B16
+	B17
+	B18
+	B19
+	B20
+	B21
+	B22
+	B23
+	B24
+	B25
+	B26
+	B27
+	B28
+	B29
+	B30
+	B31
+
+	H0
+	H1
+	H2
+	H3
+	H4
+	H5
+	H6
+	H7
+	H8
+	H9
+	H10
+	H11
+	H12
+	H13
+	H14
+	H15
+	H16
+	H17
+	H18
+	H19
+	H20
+	H21
+	H22
+	H23
+	H24
+	H25
+	H26
+	H27
+	H28
+	H29
+	H30
+	H31
+
+	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
+
+	Q0
+	Q1
+	Q2
+	Q3
+	Q4
+	Q5
+	Q6
+	Q7
+	Q8
+	Q9
+	Q10
+	Q11
+	Q12
+	Q13
+	Q14
+	Q15
+	Q16
+	Q17
+	Q18
+	Q19
+	Q20
+	Q21
+	Q22
+	Q23
+	Q24
+	Q25
+	Q26
+	Q27
+	Q28
+	Q29
+	Q30
+	Q31
+
+	V0
+	V1
+	V2
+	V3
+	V4
+	V5
+	V6
+	V7
+	V8
+	V9
+	V10
+	V11
+	V12
+	V13
+	V14
+	V15
+	V16
+	V17
+	V18
+	V19
+	V20
+	V21
+	V22
+	V23
+	V24
+	V25
+	V26
+	V27
+	V28
+	V29
+	V30
+	V31
+
+	WSP = WZR // These are different registers with the same encoding.
+	SP  = XZR // These are different registers with the same encoding.
+)
+
+func (Reg) isArg() {}
+
+func (r Reg) String() string {
+	switch {
+	case r == WZR:
+		return "WZR"
+	case r == XZR:
+		return "XZR"
+	case W0 <= r && r <= W30:
+		return fmt.Sprintf("W%d", int(r-W0))
+	case X0 <= r && r <= X30:
+		return fmt.Sprintf("X%d", int(r-X0))
+
+	case B0 <= r && r <= B31:
+		return fmt.Sprintf("B%d", int(r-B0))
+	case H0 <= r && r <= H31:
+		return fmt.Sprintf("H%d", int(r-H0))
+	case S0 <= r && r <= S31:
+		return fmt.Sprintf("S%d", int(r-S0))
+	case D0 <= r && r <= D31:
+		return fmt.Sprintf("D%d", int(r-D0))
+	case Q0 <= r && r <= Q31:
+		return fmt.Sprintf("Q%d", int(r-Q0))
+
+	case V0 <= r && r <= V31:
+		return fmt.Sprintf("V%d", int(r-V0))
+	default:
+		return fmt.Sprintf("Reg(%d)", int(r))
+	}
+}
+
+// A RegSP represent a register and X31/W31 is regarded as SP/WSP.
+type RegSP Reg
+
+func (RegSP) isArg() {}
+
+func (r RegSP) String() string {
+	switch Reg(r) {
+	case WSP:
+		return "WSP"
+	case SP:
+		return "SP"
+	default:
+		return Reg(r).String()
+	}
+}
+
+type ImmShift struct {
+	imm   uint16
+	shift uint8
+}
+
+func (ImmShift) isArg() {}
+
+func (is ImmShift) String() string {
+	if is.shift == 0 {
+		return fmt.Sprintf("#%#x", is.imm)
+	}
+	if is.shift < 128 {
+		return fmt.Sprintf("#%#x, LSL #%d", is.imm, is.shift)
+	}
+	return fmt.Sprintf("#%#x, MSL #%d", is.imm, is.shift-128)
+}
+
+type ExtShift uint8
+
+const (
+	_ ExtShift = iota
+	uxtb
+	uxth
+	uxtw
+	uxtx
+	sxtb
+	sxth
+	sxtw
+	sxtx
+	lsl
+	lsr
+	asr
+	ror
+)
+
+func (extShift ExtShift) String() string {
+	switch extShift {
+	case uxtb:
+		return "UXTB"
+
+	case uxth:
+		return "UXTH"
+
+	case uxtw:
+		return "UXTW"
+
+	case uxtx:
+		return "UXTX"
+
+	case sxtb:
+		return "SXTB"
+
+	case sxth:
+		return "SXTH"
+
+	case sxtw:
+		return "SXTW"
+
+	case sxtx:
+		return "SXTX"
+
+	case lsl:
+		return "LSL"
+
+	case lsr:
+		return "LSR"
+
+	case asr:
+		return "ASR"
+
+	case ror:
+		return "ROR"
+	}
+	return ""
+}
+
+type RegExtshiftAmount struct {
+	reg       Reg
+	extShift  ExtShift
+	amount    uint8
+	show_zero bool
+}
+
+func (RegExtshiftAmount) isArg() {}
+
+func (rea RegExtshiftAmount) String() string {
+	buf := rea.reg.String()
+	if rea.extShift != ExtShift(0) {
+		buf += ", " + rea.extShift.String()
+		if rea.amount != 0 {
+			buf += fmt.Sprintf(" #%d", rea.amount)
+		} else {
+			if rea.show_zero == true {
+				buf += fmt.Sprintf(" #%d", rea.amount)
+			}
+		}
+	}
+	return buf
+}
+
+// A PCRel describes a memory address (usually a code label)
+// as a distance relative to the program counter.
+type PCRel int64
+
+func (PCRel) isArg() {}
+
+func (r PCRel) String() string {
+	return fmt.Sprintf(".%+#x", uint64(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
+	AddrPostReg            // [Rn], Rm - - use address Rn, set Rn = Rn + Rm
+)
+
+// A MemImmediate is a memory reference made up of a base R and immediate X.
+// The effective memory address is R or R+X depending on AddrMode.
+type MemImmediate struct {
+	Base RegSP
+	Mode AddrMode
+	imm  int32
+}
+
+func (MemImmediate) isArg() {}
+
+func (m MemImmediate) String() string {
+	R := m.Base.String()
+	X := fmt.Sprintf("#%d", m.imm)
+
+	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 AddrPostReg:
+		post := Reg(X0) + Reg(m.imm)
+		postR := post.String()
+		return fmt.Sprintf("[%s], %s", R, postR)
+	}
+	return fmt.Sprintf("unimplemented!")
+}
+
+// A MemExtend 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 Index, Extend and Amount.
+type MemExtend struct {
+	Base   RegSP
+	Index  Reg
+	Extend ExtShift
+	Amount uint8
+	Absent bool
+}
+
+func (MemExtend) isArg() {}
+
+func (m MemExtend) String() string {
+	Rbase := m.Base.String()
+	RIndex := m.Index.String()
+	if m.Absent {
+		if m.Amount != 0 {
+			return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String())
+		} else {
+			if m.Extend != lsl {
+				return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
+			} else {
+				return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
+			}
+		}
+	} else {
+		if m.Amount != 0 {
+			return fmt.Sprintf("[%s,%s,%s #%d]", Rbase, RIndex, m.Extend.String(), m.Amount)
+		} else {
+			if m.Extend != lsl {
+				return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
+			} else {
+				return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
+			}
+		}
+	}
+}
+
+// An Imm is an integer constant.
+type Imm struct {
+	Imm     uint32
+	Decimal bool
+}
+
+func (Imm) isArg() {}
+
+func (i Imm) String() string {
+	if !i.Decimal {
+		return fmt.Sprintf("#%#x", i.Imm)
+	} else {
+		return fmt.Sprintf("#%d", i.Imm)
+	}
+}
+
+type Imm64 struct {
+	Imm     uint64
+	Decimal bool
+}
+
+func (Imm64) isArg() {}
+
+func (i Imm64) String() string {
+	if !i.Decimal {
+		return fmt.Sprintf("#%#x", i.Imm)
+	} else {
+		return fmt.Sprintf("#%d", i.Imm)
+	}
+}
+
+// An Imm_hint is an integer constant for HINT instruction.
+type Imm_hint uint8
+
+func (Imm_hint) isArg() {}
+
+func (i Imm_hint) String() string {
+	return fmt.Sprintf("#%#x", uint32(i))
+}
+
+// An Imm_clrex is an integer constant for CLREX instruction.
+type Imm_clrex uint8
+
+func (Imm_clrex) isArg() {}
+
+func (i Imm_clrex) String() string {
+	if i == 15 {
+		return ""
+	}
+	return fmt.Sprintf("#%#x", uint32(i))
+}
+
+// An Imm_dcps is an integer constant for DCPS[123] instruction.
+type Imm_dcps uint16
+
+func (Imm_dcps) isArg() {}
+
+func (i Imm_dcps) String() string {
+	if i == 0 {
+		return ""
+	}
+	return fmt.Sprintf("#%#x", uint32(i))
+}
+
+// Standard conditions.
+type Cond struct {
+	Value  uint8
+	Invert bool
+}
+
+func (Cond) isArg() {}
+
+func (c Cond) String() string {
+	cond31 := c.Value >> 1
+	invert := bool((c.Value & 1) == 1)
+	invert = (invert != c.Invert)
+	switch cond31 {
+	case 0:
+		if invert {
+			return "NE"
+		} else {
+			return "EQ"
+		}
+	case 1:
+		if invert {
+			return "CC"
+		} else {
+			return "CS"
+		}
+	case 2:
+		if invert {
+			return "PL"
+		} else {
+			return "MI"
+		}
+	case 3:
+		if invert {
+			return "VC"
+		} else {
+			return "VS"
+		}
+	case 4:
+		if invert {
+			return "LS"
+		} else {
+			return "HI"
+		}
+	case 5:
+		if invert {
+			return "LT"
+		} else {
+			return "GE"
+		}
+	case 6:
+		if invert {
+			return "LE"
+		} else {
+			return "GT"
+		}
+	case 7:
+		return "AL"
+	}
+	return ""
+}
+
+// An Imm_c is an integer constant for SYS/SYSL/TLBI instruction.
+type Imm_c uint8
+
+func (Imm_c) isArg() {}
+
+func (i Imm_c) String() string {
+	return fmt.Sprintf("C%d", uint8(i))
+}
+
+// An Imm_option is an integer constant for DMB/DSB/ISB instruction.
+type Imm_option uint8
+
+func (Imm_option) isArg() {}
+
+func (i Imm_option) String() string {
+	switch uint8(i) {
+	case 15:
+		return "SY"
+	case 14:
+		return "ST"
+	case 13:
+		return "LD"
+	case 11:
+		return "ISH"
+	case 10:
+		return "ISHST"
+	case 9:
+		return "ISHLD"
+	case 7:
+		return "NSH"
+	case 6:
+		return "NSHST"
+	case 5:
+		return "NSHLD"
+	case 3:
+		return "OSH"
+	case 2:
+		return "OSHST"
+	case 1:
+		return "OSHLD"
+	}
+	return fmt.Sprintf("#%#02x", uint8(i))
+}
+
+// An Imm_prfop is an integer constant for PRFM instruction.
+type Imm_prfop uint8
+
+func (Imm_prfop) isArg() {}
+
+func (i Imm_prfop) String() string {
+	prf_type := (i >> 3) & (1<<2 - 1)
+	prf_target := (i >> 1) & (1<<2 - 1)
+	prf_policy := i & 1
+	var result string
+
+	switch prf_type {
+	case 0:
+		result = "PLD"
+	case 1:
+		result = "PLI"
+	case 2:
+		result = "PST"
+	case 3:
+		return fmt.Sprintf("#%#02x", uint8(i))
+	}
+	switch prf_target {
+	case 0:
+		result += "L1"
+	case 1:
+		result += "L2"
+	case 2:
+		result += "L3"
+	case 3:
+		return fmt.Sprintf("#%#02x", uint8(i))
+	}
+	if prf_policy == 0 {
+		result += "KEEP"
+	} else {
+		result += "STRM"
+	}
+	return result
+}
+
+type Pstatefield uint8
+
+const (
+	SPSel Pstatefield = iota
+	DAIFSet
+	DAIFClr
+)
+
+func (Pstatefield) isArg() {}
+
+func (p Pstatefield) String() string {
+	switch p {
+	case SPSel:
+		return "SPSel"
+	case DAIFSet:
+		return "DAIFSet"
+	case DAIFClr:
+		return "DAIFClr"
+	default:
+		return "unimplemented"
+	}
+}
+
+type Systemreg struct {
+	op0 uint8
+	op1 uint8
+	cn  uint8
+	cm  uint8
+	op2 uint8
+}
+
+func (Systemreg) isArg() {}
+
+func (s Systemreg) String() string {
+	return fmt.Sprintf("S%d_%d_C%d_C%d_%d",
+		s.op0, s.op1, s.cn, s.cm, s.op2)
+}
+
+// An Imm_fp is a signed floating-point constant.
+type Imm_fp struct {
+	s   uint8
+	exp int8
+	pre uint8
+}
+
+func (Imm_fp) isArg() {}
+
+func (i Imm_fp) String() string {
+	var s, pre, numerator, denominator int16
+	var result float64
+	if i.s == 0 {
+		s = 1
+	} else {
+		s = -1
+	}
+	pre = s * int16(16+i.pre)
+	if i.exp > 0 {
+		numerator = (pre << uint8(i.exp))
+		denominator = 16
+	} else {
+		numerator = pre
+		denominator = (16 << uint8(-1*i.exp))
+	}
+	result = float64(numerator) / float64(denominator)
+	return fmt.Sprintf("#%.18e", result)
+}
+
+type Arrangement uint8
+
+const (
+	_ Arrangement = iota
+	ArrangementB
+	Arrangement8B
+	Arrangement16B
+	ArrangementH
+	Arrangement4H
+	Arrangement8H
+	ArrangementS
+	Arrangement2S
+	Arrangement4S
+	ArrangementD
+	Arrangement1D
+	Arrangement2D
+	Arrangement1Q
+)
+
+func (a Arrangement) String() (result string) {
+	switch a {
+	case ArrangementB:
+		result = ".B"
+	case Arrangement8B:
+		result = ".8B"
+	case Arrangement16B:
+		result = ".16B"
+	case ArrangementH:
+		result = ".H"
+	case Arrangement4H:
+		result = ".4H"
+	case Arrangement8H:
+		result = ".8H"
+	case ArrangementS:
+		result = ".S"
+	case Arrangement2S:
+		result = ".2S"
+	case Arrangement4S:
+		result = ".4S"
+	case ArrangementD:
+		result = ".D"
+	case Arrangement1D:
+		result = ".1D"
+	case Arrangement2D:
+		result = ".2D"
+	case Arrangement1Q:
+		result = ".1Q"
+	}
+	return
+}
+
+// Register with arrangement: <Vd>.<T>, { <Vt>.8B, <Vt2>.8B},
+type RegisterWithArrangement struct {
+	r   Reg
+	a   Arrangement
+	cnt uint8
+}
+
+func (RegisterWithArrangement) isArg() {}
+
+func (r RegisterWithArrangement) String() string {
+	result := r.r.String()
+	result += r.a.String()
+	if r.cnt > 0 {
+		result = "{" + result
+		if r.cnt == 2 {
+			r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
+			result += ", " + r1.String() + r.a.String()
+		} else if r.cnt > 2 {
+			if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
+				for i := 1; i < int(r.cnt); i++ {
+					cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
+					result += ", " + cur.String() + r.a.String()
+				}
+			} else {
+				r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
+				result += "-" + r1.String() + r.a.String()
+			}
+		}
+		result += "}"
+	}
+	return result
+}
+
+// Register with arrangement and index: <Vm>.<Ts>[<index>],
+//   { <Vt>.B, <Vt2>.B }[<index>].
+type RegisterWithArrangementAndIndex struct {
+	r     Reg
+	a     Arrangement
+	index uint8
+	cnt   uint8
+}
+
+func (RegisterWithArrangementAndIndex) isArg() {}
+
+func (r RegisterWithArrangementAndIndex) String() string {
+	result := r.r.String()
+	result += r.a.String()
+	if r.cnt > 0 {
+		result = "{" + result
+		if r.cnt == 2 {
+			r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
+			result += ", " + r1.String() + r.a.String()
+		} else if r.cnt > 2 {
+			if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
+				for i := 1; i < int(r.cnt); i++ {
+					cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
+					result += ", " + cur.String() + r.a.String()
+				}
+			} else {
+				r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
+				result += "-" + r1.String() + r.a.String()
+			}
+		}
+		result += "}"
+	}
+	return fmt.Sprintf("%s[%d]", result, r.index)
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.json b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.json
new file mode 100644
index 0000000..2d25c94
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.json
@@ -0,0 +1,1219 @@
+[{"Name":"ADC","Bits":"0|0|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADC <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"ADC","Bits":"1|0|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADC <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"ADCS","Bits":"0|0|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADCS <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"ADCS","Bits":"1|0|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADCS <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"ADD (extended register)","Bits":"0|0|0|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":""},
+{"Name":"ADD (extended register)","Bits":"1|0|0|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADD <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":""},
+{"Name":"ADD (immediate)","Bits":"0|0|0|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias MOV (to/from SP)."},
+{"Name":"ADD (immediate)","Bits":"1|0|0|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias MOV (to/from SP)."},
+{"Name":"ADD (shifted register)","Bits":"0|0|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADD <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"ADD (shifted register)","Bits":"1|0|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"ADDS (extended register)","Bits":"0|0|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is used by the alias CMN (extended register)."},
+{"Name":"ADDS (extended register)","Bits":"1|0|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADDS <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is used by the alias CMN (extended register)."},
+{"Name":"ADDS (immediate)","Bits":"0|0|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias CMN (immediate)."},
+{"Name":"ADDS (immediate)","Bits":"1|0|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias CMN (immediate)."},
+{"Name":"ADDS (shifted register)","Bits":"0|0|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ADDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias CMN (shifted register)."},
+{"Name":"ADDS (shifted register)","Bits":"1|0|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ADDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias CMN (shifted register)."},
+{"Name":"ADR","Bits":"0|immlo:2|1|0|0|0|0|immhi:19|Rd:5","Arch":"Literal variant","Syntax":"ADR <Xd>, <label>","Code":"","Alias":""},
+{"Name":"ADRP","Bits":"1|immlo:2|1|0|0|0|0|immhi:19|Rd:5","Arch":"Literal variant","Syntax":"ADRP <Xd>, <label>","Code":"","Alias":""},
+{"Name":"AND (immediate)","Bits":"0|0|0|1|0|0|1|0|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"AND <Wd|WSP>, <Wn>, #<imm>","Code":"","Alias":""},
+{"Name":"AND (immediate)","Bits":"1|0|0|1|0|0|1|0|0|N|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"AND <Xd|SP>, <Xn>, #<imm>","Code":"","Alias":""},
+{"Name":"AND (shifted register)","Bits":"0|0|0|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"AND <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"AND (shifted register)","Bits":"1|0|0|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"AND <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"ANDS (immediate)","Bits":"0|1|1|1|0|0|1|0|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ANDS <Wd>, <Wn>, #<imm>","Code":"","Alias":"This instruction is used by the alias TST (immediate)."},
+{"Name":"ANDS (immediate)","Bits":"1|1|1|1|0|0|1|0|0|N|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ANDS <Xd>, <Xn>, #<imm>","Code":"","Alias":"This instruction is used by the alias TST (immediate)."},
+{"Name":"ANDS (shifted register)","Bits":"0|1|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ANDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias TST (shifted register)."},
+{"Name":"ANDS (shifted register)","Bits":"1|1|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ANDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias TST (shifted register)."},
+{"Name":"ASR (register)","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ASR <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the ASRV instruction."},
+{"Name":"ASR (register)","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ASR <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the ASRV instruction."},
+{"Name":"ASR (immediate)","Bits":"0|0|0|1|0|0|1|1|0|0|immr:6|011111:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ASR <Wd>, <Wn>, #<shift>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"ASR (immediate)","Bits":"1|0|0|1|0|0|1|1|0|1|immr:6|111111:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ASR <Xd>, <Xn>, #<shift>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"ASRV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ASRV <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias ASR (register)."},
+{"Name":"ASRV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ASRV <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias ASR (register)."},
+{"Name":"AT","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|1|op1:3|0|1|1|1|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"AT <at_op>, <Xt>","Code":"","Alias":"This instruction is an alias of the SYS instruction."},
+{"Name":"B.cond","Bits":"0|1|0|1|0|1|0|0|imm19:19|0|cond:4","Arch":"19-bit signed PC-relative branch offset variant","Syntax":"B.<cond> <label>","Code":"","Alias":""},
+{"Name":"B","Bits":"0|0|0|1|0|1|imm26:26","Arch":"26-bit signed PC-relative branch offset variant","Syntax":"B <label>","Code":"","Alias":""},
+{"Name":"BFI","Bits":"0|0|1|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"BFI <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the BFM instruction."},
+{"Name":"BFI","Bits":"1|0|1|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"BFI <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the BFM instruction."},
+{"Name":"BFM","Bits":"0|0|1|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"BFM <Wd>, <Wn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases BFI and BFXIL."},
+{"Name":"BFM","Bits":"1|0|1|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"BFM <Xd>, <Xn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases BFI and BFXIL."},
+{"Name":"BFXIL","Bits":"0|0|1|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"BFXIL <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the BFM instruction."},
+{"Name":"BFXIL","Bits":"1|0|1|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"BFXIL <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the BFM instruction."},
+{"Name":"BIC (shifted register)","Bits":"0|0|0|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"BIC <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"BIC (shifted register)","Bits":"1|0|0|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"BICS (shifted register)","Bits":"0|1|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"BICS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"BICS (shifted register)","Bits":"1|1|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"BICS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"BL","Bits":"1|0|0|1|0|1|imm26:26","Arch":"26-bit signed PC-relative branch offset variant","Syntax":"BL <label>","Code":"","Alias":""},
+{"Name":"BLR","Bits":"1|1|0|1|0|1|1|0|0|0|1|1|1|1|1|1|0|0|0|0|0|0|Rn:5|0|0|0|0|0","Arch":"Integer variant","Syntax":"BLR <Xn>","Code":"","Alias":""},
+{"Name":"BR","Bits":"1|1|0|1|0|1|1|0|0|0|0|1|1|1|1|1|0|0|0|0|0|0|Rn:5|0|0|0|0|0","Arch":"Integer variant","Syntax":"BR <Xn>","Code":"","Alias":""},
+{"Name":"BRK","Bits":"1|1|0|1|0|1|0|0|0|0|1|imm16:16|0|0|0|0|0","Arch":"System variant","Syntax":"BRK #<imm>","Code":"","Alias":""},
+{"Name":"CBNZ","Bits":"0|0|1|1|0|1|0|1|imm19:19|Rt:5","Arch":"32-bit variant","Syntax":"CBNZ <Wt>, <label>","Code":"","Alias":""},
+{"Name":"CBNZ","Bits":"1|0|1|1|0|1|0|1|imm19:19|Rt:5","Arch":"64-bit variant","Syntax":"CBNZ <Xt>, <label>","Code":"","Alias":""},
+{"Name":"CBZ","Bits":"0|0|1|1|0|1|0|0|imm19:19|Rt:5","Arch":"32-bit variant","Syntax":"CBZ <Wt>, <label>","Code":"","Alias":""},
+{"Name":"CBZ","Bits":"1|0|1|1|0|1|0|0|imm19:19|Rt:5","Arch":"64-bit variant","Syntax":"CBZ <Xt>, <label>","Code":"","Alias":""},
+{"Name":"CCMN (immediate)","Bits":"0|0|1|1|1|0|1|0|0|1|0|imm5:5|cond:4|1|0|Rn:5|0|nzcv:4","Arch":"32-bit variant","Syntax":"CCMN <Wn>, #<imm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMN (immediate)","Bits":"1|0|1|1|1|0|1|0|0|1|0|imm5:5|cond:4|1|0|Rn:5|0|nzcv:4","Arch":"64-bit variant","Syntax":"CCMN <Xn>, #<imm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMN (register)","Bits":"0|0|1|1|1|0|1|0|0|1|0|Rm:5|cond:4|0|0|Rn:5|0|nzcv:4","Arch":"32-bit variant","Syntax":"CCMN <Wn>, <Wm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMN (register)","Bits":"1|0|1|1|1|0|1|0|0|1|0|Rm:5|cond:4|0|0|Rn:5|0|nzcv:4","Arch":"64-bit variant","Syntax":"CCMN <Xn>, <Xm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMP (immediate)","Bits":"0|1|1|1|1|0|1|0|0|1|0|imm5:5|cond:4|1|0|Rn:5|0|nzcv:4","Arch":"32-bit variant","Syntax":"CCMP <Wn>, #<imm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMP (immediate)","Bits":"1|1|1|1|1|0|1|0|0|1|0|imm5:5|cond:4|1|0|Rn:5|0|nzcv:4","Arch":"64-bit variant","Syntax":"CCMP <Xn>, #<imm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMP (register)","Bits":"0|1|1|1|1|0|1|0|0|1|0|Rm:5|cond:4|0|0|Rn:5|0|nzcv:4","Arch":"32-bit variant","Syntax":"CCMP <Wn>, <Wm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CCMP (register)","Bits":"1|1|1|1|1|0|1|0|0|1|0|Rm:5|cond:4|0|0|Rn:5|0|nzcv:4","Arch":"64-bit variant","Syntax":"CCMP <Xn>, <Xm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"CINC","Bits":"0|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CINC <Wd>, <Wn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINC instruction."},
+{"Name":"CINC","Bits":"1|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CINC <Xd>, <Xn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINC instruction."},
+{"Name":"CINV","Bits":"0|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CINV <Wd>, <Wn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINV instruction."},
+{"Name":"CINV","Bits":"1|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CINV <Xd>, <Xn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINV instruction."},
+{"Name":"CLREX","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|1|CRm:4|0|1|0|1|1|1|1|1","Arch":"System variant","Syntax":"CLREX {#<imm>}","Code":"","Alias":""},
+{"Name":"CLS","Bits":"0|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CLS <Wd>, <Wn>","Code":"","Alias":""},
+{"Name":"CLS","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CLS <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"CLZ","Bits":"0|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CLZ <Wd>, <Wn>","Code":"","Alias":""},
+{"Name":"CLZ","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CLZ <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"CMN (extended register)","Bits":"0|0|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMN <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is an alias of the ADDS (extended register) instruction."},
+{"Name":"CMN (extended register)","Bits":"1|0|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMN <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is an alias of the ADDS (extended register) instruction."},
+{"Name":"CMN (immediate)","Bits":"0|0|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMN <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is an alias of the ADDS (immediate) instruction."},
+{"Name":"CMN (immediate)","Bits":"1|0|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMN <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is an alias of the ADDS (immediate) instruction."},
+{"Name":"CMN (shifted register)","Bits":"0|0|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMN <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ADDS (shifted register) instruction."},
+{"Name":"CMN (shifted register)","Bits":"1|0|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMN <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ADDS (shifted register) instruction."},
+{"Name":"CMP (extended register)","Bits":"0|1|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMP <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is an alias of the SUBS (extended register) instruction."},
+{"Name":"CMP (extended register)","Bits":"1|1|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is an alias of the SUBS (extended register) instruction."},
+{"Name":"CMP (immediate)","Bits":"0|1|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMP <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is an alias of the SUBS (immediate) instruction."},
+{"Name":"CMP (immediate)","Bits":"1|1|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMP <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is an alias of the SUBS (immediate) instruction."},
+{"Name":"CMP (shifted register)","Bits":"0|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"CMP <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUBS (shifted register) instruction."},
+{"Name":"CMP (shifted register)","Bits":"1|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"CMP <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUBS (shifted register) instruction."},
+{"Name":"CNEG","Bits":"0|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CNEG <Wd>, <Wn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSNEG instruction."},
+{"Name":"CNEG","Bits":"1|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CNEG <Xd>, <Xn>, <cond>","Code":"","Alias":"This instruction is an alias of the CSNEG instruction."},
+{"Name":"CRC32B, CRC32H, CRC32W, CRC32X","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|0|00:2|Rn:5|Rd:5","Arch":"CRC32B variant","Syntax":"CRC32B <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32B, CRC32H, CRC32W, CRC32X","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|0|01:2|Rn:5|Rd:5","Arch":"CRC32H variant","Syntax":"CRC32H <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32B, CRC32H, CRC32W, CRC32X","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|0|10:2|Rn:5|Rd:5","Arch":"CRC32W variant","Syntax":"CRC32W <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32B, CRC32H, CRC32W, CRC32X","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|0|11:2|Rn:5|Rd:5","Arch":"CRC32X variant","Syntax":"CRC32X <Wd>, <Wn>, <Xm>","Code":"","Alias":""},
+{"Name":"CRC32CB, CRC32CH, CRC32CW, CRC32CX","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|1|00:2|Rn:5|Rd:5","Arch":"CRC32CB variant","Syntax":"CRC32CB <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32CB, CRC32CH, CRC32CW, CRC32CX","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|1|01:2|Rn:5|Rd:5","Arch":"CRC32CH variant","Syntax":"CRC32CH <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32CB, CRC32CH, CRC32CW, CRC32CX","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|1|10:2|Rn:5|Rd:5","Arch":"CRC32CW variant","Syntax":"CRC32CW <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"CRC32CB, CRC32CH, CRC32CW, CRC32CX","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|1|0|1|11:2|Rn:5|Rd:5","Arch":"CRC32CX variant","Syntax":"CRC32CX <Wd>, <Wn>, <Xm>","Code":"","Alias":""},
+{"Name":"CSEL","Bits":"0|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CSEL <Wd>, <Wn>, <Wm>, <cond>","Code":"","Alias":""},
+{"Name":"CSEL","Bits":"1|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CSEL <Xd>, <Xn>, <Xm>, <cond>","Code":"","Alias":""},
+{"Name":"CSET","Bits":"0|0|0|1|1|0|1|0|1|0|0|1|1|1|1|1|cond:4|0|1|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"CSET <Wd>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINC instruction."},
+{"Name":"CSET","Bits":"1|0|0|1|1|0|1|0|1|0|0|1|1|1|1|1|cond:4|0|1|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"CSET <Xd>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINC instruction."},
+{"Name":"CSETM","Bits":"0|1|0|1|1|0|1|0|1|0|0|1|1|1|1|1|cond:4|0|0|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"CSETM <Wd>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINV instruction."},
+{"Name":"CSETM","Bits":"1|1|0|1|1|0|1|0|1|0|0|1|1|1|1|1|cond:4|0|0|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"CSETM <Xd>, <cond>","Code":"","Alias":"This instruction is an alias of the CSINV instruction."},
+{"Name":"CSINC","Bits":"0|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CSINC <Wd>, <Wn>, <Wm>, <cond>","Code":"","Alias":"This instruction is used by the aliases CINC and CSET."},
+{"Name":"CSINC","Bits":"1|0|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CSINC <Xd>, <Xn>, <Xm>, <cond>","Code":"","Alias":"This instruction is used by the aliases CINC and CSET."},
+{"Name":"CSINV","Bits":"0|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CSINV <Wd>, <Wn>, <Wm>, <cond>","Code":"","Alias":"This instruction is used by the aliases CINV and CSETM."},
+{"Name":"CSINV","Bits":"1|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CSINV <Xd>, <Xn>, <Xm>, <cond>","Code":"","Alias":"This instruction is used by the aliases CINV and CSETM."},
+{"Name":"CSNEG","Bits":"0|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"CSNEG <Wd>, <Wn>, <Wm>, <cond>","Code":"","Alias":"This instruction is used by the alias CNEG."},
+{"Name":"CSNEG","Bits":"1|1|0|1|1|0|1|0|1|0|0|Rm:5|cond:4|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"CSNEG <Xd>, <Xn>, <Xm>, <cond>","Code":"","Alias":"This instruction is used by the alias CNEG."},
+{"Name":"DC","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|1|op1:3|0|1|1|1|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"DC <dc_op>, <Xt>","Code":"","Alias":"This instruction is an alias of the SYS instruction."},
+{"Name":"DCPS1","Bits":"1|1|0|1|0|1|0|0|1|0|1|imm16:16|0|0|0|0|1","Arch":"System variant","Syntax":"DCPS1 {#<imm>}","Code":"","Alias":""},
+{"Name":"DCPS2","Bits":"1|1|0|1|0|1|0|0|1|0|1|imm16:16|0|0|0|1|0","Arch":"System variant","Syntax":"DCPS2 {#<imm>}","Code":"","Alias":""},
+{"Name":"DCPS3","Bits":"1|1|0|1|0|1|0|0|1|0|1|imm16:16|0|0|0|1|1","Arch":"System variant","Syntax":"DCPS3 {#<imm>}","Code":"","Alias":""},
+{"Name":"DMB","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|1|CRm:4|1|0|1|1|1|1|1|1","Arch":"System variant","Syntax":"DMB <option>|#<imm>","Code":"","Alias":""},
+{"Name":"DRPS","Bits":"1|1|0|1|0|1|1|0|1|0|1|1|1|1|1|1|0|0|0|0|0|0|1|1|1|1|1|0|0|0|0|0","Arch":"System variant","Syntax":"DRPS","Code":"","Alias":""},
+{"Name":"DSB","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|1|CRm:4|1|0|0|1|1|1|1|1","Arch":"System variant","Syntax":"DSB <option>|#<imm>","Code":"","Alias":""},
+{"Name":"EON (shifted register)","Bits":"0|1|0|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"EON <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"EON (shifted register)","Bits":"1|1|0|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"EON <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"EOR (immediate)","Bits":"0|1|0|1|0|0|1|0|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"EOR <Wd|WSP>, <Wn>, #<imm>","Code":"","Alias":""},
+{"Name":"EOR (immediate)","Bits":"1|1|0|1|0|0|1|0|0|N|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"EOR <Xd|SP>, <Xn>, #<imm>","Code":"","Alias":""},
+{"Name":"EOR (shifted register)","Bits":"0|1|0|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"EOR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"EOR (shifted register)","Bits":"1|1|0|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"EOR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":""},
+{"Name":"ERET","Bits":"1|1|0|1|0|1|1|0|1|0|0|1|1|1|1|1|0|0|0|0|0|0|1|1|1|1|1|0|0|0|0|0","Arch":"System variant","Syntax":"ERET","Code":"","Alias":""},
+{"Name":"EXTR","Bits":"0|0|0|1|0|0|1|1|1|0|0|Rm:5|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"EXTR <Wd>, <Wn>, <Wm>, #<lsb>","Code":"","Alias":"This instruction is used by the alias ROR (immediate)."},
+{"Name":"EXTR","Bits":"1|0|0|1|0|0|1|1|1|1|0|Rm:5|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"EXTR <Xd>, <Xn>, <Xm>, #<lsb>","Code":"","Alias":"This instruction is used by the alias ROR (immediate)."},
+{"Name":"HINT","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0000:4|op2:3|1|1|1|1|1","Arch":"Hints 6 and 7 variant","Syntax":"HINT #<imm>","Code":"","Alias":""},
+{"Name":"HINT","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|CRm:4|op2:3|1|1|1|1|1","Arch":"Hints 8 to 127 variant","Syntax":"HINT #<imm>","Code":"","Alias":""},
+{"Name":"HLT","Bits":"1|1|0|1|0|1|0|0|0|1|0|imm16:16|0|0|0|0|0","Arch":"System variant","Syntax":"HLT #<imm>","Code":"","Alias":""},
+{"Name":"HVC","Bits":"1|1|0|1|0|1|0|0|0|0|0|imm16:16|0|0|0|1|0","Arch":"System variant","Syntax":"HVC #<imm>","Code":"","Alias":""},
+{"Name":"IC","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|1|op1:3|0|1|1|1|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"IC <ic_op>{, <Xt>}","Code":"","Alias":"This instruction is an alias of the SYS instruction."},
+{"Name":"ISB","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|1|CRm:4|1|1|0|1|1|1|1|1","Arch":"System variant","Syntax":"ISB {<option>|#<imm>}","Code":"","Alias":""},
+{"Name":"LDAR","Bits":"10:2|0|0|1|0|0|0|1|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDAR <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAR","Bits":"11:2|0|0|1|0|0|0|1|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDAR <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDARB","Bits":"0|0|0|0|1|0|0|0|1|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDARB <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDARH","Bits":"0|1|0|0|1|0|0|0|1|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDARH <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXP","Bits":"1|0|0|0|1|0|0|0|0|1|1|(1)|(1)|(1)|(1)|(1)|1|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDAXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXP","Bits":"1|1|0|0|1|0|0|0|0|1|1|(1)|(1)|(1)|(1)|(1)|1|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDAXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXR","Bits":"10:2|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDAXR <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXR","Bits":"11:2|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDAXR <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXRB","Bits":"0|0|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDAXRB <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDAXRH","Bits":"0|1|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDAXRH <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDNP","Bits":"00:2|1|0|1|0|0|0|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDNP","Bits":"10:2|1|0|1|0|0|0|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDP","Bits":"00:2|1|0|1|0|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDP","Bits":"10:2|1|0|1|0|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDP","Bits":"00:2|1|0|1|0|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDP","Bits":"10:2|1|0|1|0|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDP","Bits":"00:2|1|0|1|0|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 32-bit variant","Syntax":"LDP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDP","Bits":"10:2|1|0|1|0|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 64-bit variant","Syntax":"LDP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDPSW","Bits":"0|1|1|0|1|0|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"LDPSW <Xt1>, <Xt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDPSW","Bits":"0|1|1|0|1|0|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"LDPSW <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDPSW","Bits":"0|1|1|0|1|0|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset Signed offset variant","Syntax":"LDPSW <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"10:2|1|1|1|0|0|0|0|1|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDR <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"11:2|1|1|1|0|0|0|0|1|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDR <Xt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"10:2|1|1|1|0|0|0|0|1|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDR <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"11:2|1|1|1|0|0|0|0|1|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDR <Xt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"10:2|1|1|1|0|0|1|0|1|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"LDR <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate)","Bits":"11:2|1|1|1|0|0|1|0|1|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"LDR <Xt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (literal)","Bits":"00:2|0|1|1|0|0|0|imm19:19|Rt:5","Arch":"32-bit variant","Syntax":"LDR <Wt>, <label>","Code":"","Alias":""},
+{"Name":"LDR (literal)","Bits":"01:2|0|1|1|0|0|0|imm19:19|Rt:5","Arch":"64-bit variant","Syntax":"LDR <Xt>, <label>","Code":"","Alias":""},
+{"Name":"LDR (register)","Bits":"10:2|1|1|1|0|0|0|0|1|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDR <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDR (register)","Bits":"11:2|1|1|1|0|0|0|0|1|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDR <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDRB (immediate)","Bits":"0|0|1|1|1|0|0|0|0|1|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"LDRB <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRB (immediate)","Bits":"0|0|1|1|1|0|0|0|0|1|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"LDRB <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRB (immediate)","Bits":"0|0|1|1|1|0|0|1|0|1|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset Unsigned offset variant","Syntax":"LDRB <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRB (register)","Bits":"0|0|1|1|1|0|0|0|0|1|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"Extended register variant","Syntax":"LDRB <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"LDRB (register)","Bits":"0|0|1|1|1|0|0|0|0|1|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"Shifted register variant","Syntax":"LDRB <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"LDRH (immediate)","Bits":"0|1|1|1|1|0|0|0|0|1|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"LDRH <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRH (immediate)","Bits":"0|1|1|1|1|0|0|0|0|1|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"LDRH <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRH (immediate)","Bits":"0|1|1|1|1|0|0|1|0|1|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset Unsigned offset variant","Syntax":"LDRH <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRH (register)","Bits":"0|1|1|1|1|0|0|0|0|1|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDRH <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|0|11:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDRSB <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|0|10:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDRSB <Xt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|0|11:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDRSB <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|0|10:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDRSB <Xt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|1|11:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"LDRSB <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRSB (immediate)","Bits":"0|0|1|1|1|0|0|1|10:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"LDRSB <Xt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRSB (register)","Bits":"0|0|1|1|1|0|0|0|11:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit with extended register offset variant","Syntax":"LDRSB <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"LDRSB (register)","Bits":"0|0|1|1|1|0|0|0|11:2|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit with shifted register offset variant","Syntax":"LDRSB <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"LDRSB (register)","Bits":"0|0|1|1|1|0|0|0|10:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit with extended register offset variant","Syntax":"LDRSB <Xt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"LDRSB (register)","Bits":"0|0|1|1|1|0|0|0|10:2|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit with shifted register offset variant","Syntax":"LDRSB <Xt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|0|11:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDRSH <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|0|10:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDRSH <Xt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|0|11:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDRSH <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|0|10:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDRSH <Xt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|1|11:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"LDRSH <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRSH (immediate)","Bits":"0|1|1|1|1|0|0|1|10:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"LDRSH <Xt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRSH (register)","Bits":"0|1|1|1|1|0|0|0|11:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDRSH <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDRSH (register)","Bits":"0|1|1|1|1|0|0|0|10:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDRSH <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDRSW (immediate)","Bits":"1|0|1|1|1|0|0|0|1|0|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"LDRSW <Xt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDRSW (immediate)","Bits":"1|0|1|1|1|0|0|0|1|0|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"LDRSW <Xt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDRSW (immediate)","Bits":"1|0|1|1|1|0|0|1|1|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset Unsigned offset variant","Syntax":"LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDRSW (literal)","Bits":"1|0|0|1|1|0|0|0|imm19:19|Rt:5","Arch":"Literal variant","Syntax":"LDRSW <Xt>, <label>","Code":"","Alias":""},
+{"Name":"LDRSW (register)","Bits":"1|0|1|1|1|0|0|0|1|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDRSW <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDTR","Bits":"10:2|1|1|1|0|0|0|0|1|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDTR <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTR","Bits":"11:2|1|1|1|0|0|0|0|1|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDTR <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRB","Bits":"0|0|1|1|1|0|0|0|0|1|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDTRB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRH","Bits":"0|1|1|1|1|0|0|0|0|1|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDTRH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRSB","Bits":"0|0|1|1|1|0|0|0|11:2|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDTRSB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRSB","Bits":"0|0|1|1|1|0|0|0|10:2|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDTRSB <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRSH","Bits":"0|1|1|1|1|0|0|0|11:2|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDTRSH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRSH","Bits":"0|1|1|1|1|0|0|0|10:2|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDTRSH <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDTRSW","Bits":"1|0|1|1|1|0|0|0|1|0|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDTRSW <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR","Bits":"10:2|1|1|1|0|0|0|0|1|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDUR <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR","Bits":"11:2|1|1|1|0|0|0|0|1|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDUR <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURB","Bits":"0|0|1|1|1|0|0|0|0|1|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDURB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURH","Bits":"0|1|1|1|1|0|0|0|0|1|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDURH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURSB","Bits":"0|0|1|1|1|0|0|0|11:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDURSB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURSB","Bits":"0|0|1|1|1|0|0|0|10:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDURSB <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURSH","Bits":"0|1|1|1|1|0|0|0|11:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDURSH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURSH","Bits":"0|1|1|1|1|0|0|0|10:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDURSH <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDURSW","Bits":"1|0|1|1|1|0|0|0|1|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"LDURSW <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDXP","Bits":"1|0|0|0|1|0|0|0|0|1|1|(1)|(1)|(1)|(1)|(1)|0|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDXP","Bits":"1|1|0|0|1|0|0|0|0|1|1|(1)|(1)|(1)|(1)|(1)|0|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDXR","Bits":"10:2|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDXR <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDXR","Bits":"11:2|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDXR <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDXRB","Bits":"0|0|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDXRB <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LDXRH","Bits":"0|1|0|0|1|0|0|0|0|1|0|(1)|(1)|(1)|(1)|(1)|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"LDXRH <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"LSL (register)","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSL <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the LSLV instruction."},
+{"Name":"LSL (register)","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSL <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the LSLV instruction."},
+{"Name":"LSL (immediate)","Bits":"0|1|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSL <Wd>, <Wn>, #<shift>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"LSL (immediate)","Bits":"1|1|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSL <Xd>, <Xn>, #<shift>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"LSLV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSLV <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias LSL (register)."},
+{"Name":"LSLV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSLV <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias LSL (register)."},
+{"Name":"LSR (register)","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSR <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the LSRV instruction."},
+{"Name":"LSR (register)","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSR <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the LSRV instruction."},
+{"Name":"LSR (immediate)","Bits":"0|1|0|1|0|0|1|1|0|0|immr:6|011111:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSR <Wd>, <Wn>, #<shift>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"LSR (immediate)","Bits":"1|1|0|1|0|0|1|1|0|1|immr:6|111111:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSR <Xd>, <Xn>, #<shift>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"LSRV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"LSRV <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias LSR (register)."},
+{"Name":"LSRV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"LSRV <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias LSR (register)."},
+{"Name":"MADD","Bits":"0|0|0|1|1|0|1|1|0|0|0|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MADD <Wd>, <Wn>, <Wm>, <Wa>","Code":"","Alias":"This instruction is used by the alias MUL."},
+{"Name":"MADD","Bits":"1|0|0|1|1|0|1|1|0|0|0|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MADD <Xd>, <Xn>, <Xm>, <Xa>","Code":"","Alias":"This instruction is used by the alias MUL."},
+{"Name":"MNEG","Bits":"0|0|0|1|1|0|1|1|0|0|0|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MNEG <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the MSUB instruction."},
+{"Name":"MNEG","Bits":"1|0|0|1|1|0|1|1|0|0|0|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MNEG <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the MSUB instruction."},
+{"Name":"MOV (to/from SP)","Bits":"0|0|0|1|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd|WSP>, <Wn|WSP>","Code":"","Alias":"This instruction is an alias of the ADD (immediate) instruction."},
+{"Name":"MOV (to/from SP)","Bits":"1|0|0|1|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd|SP>, <Xn|SP>","Code":"","Alias":"This instruction is an alias of the ADD (immediate) instruction."},
+{"Name":"MOV (inverted wide immediate)","Bits":"0|0|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd>, #<imm>","Code":"","Alias":"This instruction is an alias of the MOVN instruction."},
+{"Name":"MOV (inverted wide immediate)","Bits":"1|0|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd>, #<imm>","Code":"","Alias":"This instruction is an alias of the MOVN instruction."},
+{"Name":"MOV (wide immediate)","Bits":"0|1|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd>, #<imm>","Code":"","Alias":"This instruction is an alias of the MOVZ instruction."},
+{"Name":"MOV (wide immediate)","Bits":"1|1|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd>, #<imm>","Code":"","Alias":"This instruction is an alias of the MOVZ instruction."},
+{"Name":"MOV (bitmask immediate)","Bits":"0|0|1|1|0|0|1|0|0|0|immr:6|imms:6|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd|WSP>, #<imm>","Code":"","Alias":"This instruction is an alias of the ORR (immediate) instruction."},
+{"Name":"MOV (bitmask immediate)","Bits":"1|0|1|1|0|0|1|0|0|N|immr:6|imms:6|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd|SP>, #<imm>","Code":"","Alias":"This instruction is an alias of the ORR (immediate) instruction."},
+{"Name":"MOV (register)","Bits":"0|0|1|0|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd>, <Wm>","Code":"","Alias":"This instruction is an alias of the ORR (shifted register) instruction."},
+{"Name":"MOV (register)","Bits":"1|0|1|0|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd>, <Xm>","Code":"","Alias":"This instruction is an alias of the ORR (shifted register) instruction."},
+{"Name":"MOVK","Bits":"0|1|1|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"32-bit variant","Syntax":"MOVK <Wd>, #<imm>{, LSL #<shift>}","Code":"","Alias":""},
+{"Name":"MOVK","Bits":"1|1|1|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"64-bit variant","Syntax":"MOVK <Xd>, #<imm>{, LSL #<shift>}","Code":"","Alias":""},
+{"Name":"MOVN","Bits":"0|0|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"32-bit variant","Syntax":"MOVN <Wd>, #<imm>{, LSL #<shift>}","Code":"","Alias":"This instruction is used by the alias MOV (inverted wide immediate)."},
+{"Name":"MOVN","Bits":"1|0|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"64-bit variant","Syntax":"MOVN <Xd>, #<imm>{, LSL #<shift>}","Code":"","Alias":"This instruction is used by the alias MOV (inverted wide immediate)."},
+{"Name":"MOVZ","Bits":"0|1|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"32-bit variant","Syntax":"MOVZ <Wd>, #<imm>{, LSL #<shift>}","Code":"","Alias":"This instruction is used by the alias MOV (wide immediate)."},
+{"Name":"MOVZ","Bits":"1|1|0|1|0|0|1|0|1|hw:2|imm16:16|Rd:5","Arch":"64-bit variant","Syntax":"MOVZ <Xd>, #<imm>{, LSL #<shift>}","Code":"","Alias":"This instruction is used by the alias MOV (wide immediate)."},
+{"Name":"MRS","Bits":"1|1|0|1|0|1|0|1|0|0|1|1|o0|op1:3|CRn:4|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"MRS <Xt>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)","Code":"","Alias":""},
+{"Name":"MSR (immediate)","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|op1:3|0|1|0|0|CRm:4|op2:3|1|1|1|1|1","Arch":"System variant","Syntax":"MSR <pstatefield>, #<imm>","Code":"","Alias":""},
+{"Name":"MSR (register)","Bits":"1|1|0|1|0|1|0|1|0|0|0|1|o0|op1:3|CRn:4|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"MSR (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>","Code":"","Alias":""},
+{"Name":"MSUB","Bits":"0|0|0|1|1|0|1|1|0|0|0|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MSUB <Wd>, <Wn>, <Wm>, <Wa>","Code":"","Alias":"This instruction is used by the alias MNEG."},
+{"Name":"MSUB","Bits":"1|0|0|1|1|0|1|1|0|0|0|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MSUB <Xd>, <Xn>, <Xm>, <Xa>","Code":"","Alias":"This instruction is used by the alias MNEG."},
+{"Name":"MUL","Bits":"0|0|0|1|1|0|1|1|0|0|0|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MUL <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the MADD instruction."},
+{"Name":"MUL","Bits":"1|0|0|1|1|0|1|1|0|0|0|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MUL <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the MADD instruction."},
+{"Name":"MVN","Bits":"0|0|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"MVN <Wd>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ORN (shifted register) instruction."},
+{"Name":"MVN","Bits":"1|0|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"MVN <Xd>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ORN (shifted register) instruction."},
+{"Name":"NEG (shifted register)","Bits":"0|1|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"NEG <Wd>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUB (shifted register) instruction."},
+{"Name":"NEG (shifted register)","Bits":"1|1|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"NEG <Xd>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUB (shifted register) instruction."},
+{"Name":"NEGS","Bits":"0|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"NEGS <Wd>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUBS (shifted register) instruction."},
+{"Name":"NEGS","Bits":"1|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"NEGS <Xd>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the SUBS (shifted register) instruction."},
+{"Name":"NGC","Bits":"0|1|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"NGC <Wd>, <Wm>","Code":"","Alias":"This instruction is an alias of the SBC instruction."},
+{"Name":"NGC","Bits":"1|1|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"NGC <Xd>, <Xm>","Code":"","Alias":"This instruction is an alias of the SBC instruction."},
+{"Name":"NGCS","Bits":"0|1|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"32-bit variant","Syntax":"NGCS <Wd>, <Wm>","Code":"","Alias":"This instruction is an alias of the SBCS instruction."},
+{"Name":"NGCS","Bits":"1|1|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|1|1|1|1|1|Rd:5","Arch":"64-bit variant","Syntax":"NGCS <Xd>, <Xm>","Code":"","Alias":"This instruction is an alias of the SBCS instruction."},
+{"Name":"NOP","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|0|0|1|1|1|1|1","Arch":"System variant","Syntax":"NOP","Code":"","Alias":""},
+{"Name":"ORN (shifted register)","Bits":"0|0|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ORN <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias MVN."},
+{"Name":"ORN (shifted register)","Bits":"1|0|1|0|1|0|1|0|shift:2|1|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ORN <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias MVN."},
+{"Name":"ORR (immediate)","Bits":"0|0|1|1|0|0|1|0|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ORR <Wd|WSP>, <Wn>, #<imm>","Code":"","Alias":"This instruction is used by the alias MOV (bitmask immediate)."},
+{"Name":"ORR (immediate)","Bits":"1|0|1|1|0|0|1|0|0|N|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ORR <Xd|SP>, <Xn>, #<imm>","Code":"","Alias":"This instruction is used by the alias MOV (bitmask immediate)."},
+{"Name":"ORR (shifted register)","Bits":"0|0|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ORR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias MOV (register)."},
+{"Name":"ORR (shifted register)","Bits":"1|0|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias MOV (register)."},
+{"Name":"PRFM (immediate)","Bits":"1|1|1|1|1|0|0|1|1|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset variant","Syntax":"PRFM (<prfop>|#<imm5>), [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"PRFM (literal)","Bits":"1|1|0|1|1|0|0|0|imm19:19|Rt:5","Arch":"Literal variant","Syntax":"PRFM (<prfop>|#<imm5>), <label>","Code":"","Alias":""},
+{"Name":"PRFM (register)","Bits":"1|1|1|1|1|0|0|0|1|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"Integer variant","Syntax":"PRFM (<prfop>|#<imm5>), [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"PRFM (unscaled offset)","Bits":"1|1|1|1|1|0|0|0|1|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"PRFUM (<prfop>|#<imm5>), [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"RBIT","Bits":"0|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"RBIT <Wd>, <Wn>","Code":"","Alias":""},
+{"Name":"RBIT","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"RBIT <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"RET","Bits":"1|1|0|1|0|1|1|0|0|1|0|1|1|1|1|1|0|0|0|0|0|0|Rn:5|0|0|0|0|0","Arch":"Integer variant","Syntax":"RET {<Xn>}","Code":"","Alias":""},
+{"Name":"REV","Bits":"0|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|10:2|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"REV <Wd>, <Wn>","Code":"","Alias":""},
+{"Name":"REV","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|11:2|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"REV <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"REV16","Bits":"0|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"REV16 <Wd>, <Wn>","Code":"","Alias":""},
+{"Name":"REV16","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"REV16 <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"REV32","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"REV32 <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"REV64","Bits":"1|1|0|1|1|0|1|0|1|1|0|0|0|0|0|0|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"REV64 <Xd>, <Xn>","Code":"","Alias":""},
+{"Name":"ROR (immediate)","Bits":"0|0|0|1|0|0|1|1|1|0|0|Rm:5|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ROR <Wd>, <Ws>, #<shift>","Code":"","Alias":"This instruction is an alias of the EXTR instruction."},
+{"Name":"ROR (immediate)","Bits":"1|0|0|1|0|0|1|1|1|1|0|Rm:5|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ROR <Xd>, <Xs>, #<shift>","Code":"","Alias":"This instruction is an alias of the EXTR instruction."},
+{"Name":"ROR (register)","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"ROR <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the RORV instruction."},
+{"Name":"ROR (register)","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"ROR <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is an alias of the RORV instruction."},
+{"Name":"RORV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"RORV <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias ROR (register)."},
+{"Name":"RORV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"RORV <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias ROR (register)."},
+{"Name":"SBC","Bits":"0|1|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SBC <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias NGC."},
+{"Name":"SBC","Bits":"1|1|0|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SBC <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias NGC."},
+{"Name":"SBCS","Bits":"0|1|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SBCS <Wd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is used by the alias NGCS."},
+{"Name":"SBCS","Bits":"1|1|1|1|1|0|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SBCS <Xd>, <Xn>, <Xm>","Code":"","Alias":"This instruction is used by the alias NGCS."},
+{"Name":"SBFIZ","Bits":"0|0|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SBFIZ <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SBFIZ","Bits":"1|0|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SBFIZ <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SBFM","Bits":"0|0|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SBFM <Wd>, <Wn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases ASR (immediate), SBFIZ, SBFX, SXTB, SXTH, and SXTW."},
+{"Name":"SBFM","Bits":"1|0|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SBFM <Xd>, <Xn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases ASR (immediate), SBFIZ, SBFX, SXTB, SXTH, and SXTW."},
+{"Name":"SBFX","Bits":"0|0|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SBFX <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SBFX","Bits":"1|0|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SBFX <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SDIV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SDIV <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"SDIV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SDIV <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"SEV","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|1|0|0|1|1|1|1|1","Arch":"System variant","Syntax":"SEV","Code":"","Alias":""},
+{"Name":"SEVL","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|1|0|1|1|1|1|1|1","Arch":"System variant","Syntax":"SEVL","Code":"","Alias":""},
+{"Name":"SMADDL","Bits":"1|0|0|1|1|0|1|1|0|0|1|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMADDL <Xd>, <Wn>, <Wm>, <Xa>","Code":"","Alias":"This instruction is used by the alias SMULL."},
+{"Name":"SMC","Bits":"1|1|0|1|0|1|0|0|0|0|0|imm16:16|0|0|0|1|1","Arch":"System variant","Syntax":"SMC #<imm>","Code":"","Alias":""},
+{"Name":"SMNEGL","Bits":"1|0|0|1|1|0|1|1|0|0|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMNEGL <Xd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the SMSUBL instruction."},
+{"Name":"SMSUBL","Bits":"1|0|0|1|1|0|1|1|0|0|1|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMSUBL <Xd>, <Wn>, <Wm>, <Xa>","Code":"","Alias":"This instruction is used by the alias SMNEGL."},
+{"Name":"SMULH","Bits":"1|0|0|1|1|0|1|1|0|1|0|Rm:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMULH <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"SMULL","Bits":"1|0|0|1|1|0|1|1|0|0|1|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMULL <Xd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the SMADDL instruction."},
+{"Name":"STLR","Bits":"10:2|0|0|1|0|0|0|1|0|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STLR <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLR","Bits":"11:2|0|0|1|0|0|0|1|0|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STLR <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLRB","Bits":"0|0|0|0|1|0|0|0|1|0|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STLRB <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLRH","Bits":"0|1|0|0|1|0|0|0|1|0|0|(1)|(1)|(1)|(1)|(1)|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STLRH <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXP","Bits":"1|0|0|0|1|0|0|0|0|0|1|Rs:5|1|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STLXP <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXP","Bits":"1|1|0|0|1|0|0|0|0|0|1|Rs:5|1|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STLXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXR","Bits":"10:2|0|0|1|0|0|0|0|0|0|Rs:5|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STLXR <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXR","Bits":"11:2|0|0|1|0|0|0|0|0|0|Rs:5|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STLXR <Ws>, <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXRB","Bits":"0|0|0|0|1|0|0|0|0|0|0|Rs:5|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STLXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STLXRH","Bits":"0|1|0|0|1|0|0|0|0|0|0|Rs:5|1|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STLXRH <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STNP","Bits":"00:2|1|0|1|0|0|0|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STNP","Bits":"10:2|1|0|1|0|0|0|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STP","Bits":"00:2|1|0|1|0|0|0|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"STP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"STP","Bits":"10:2|1|0|1|0|0|0|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"STP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"STP","Bits":"00:2|1|0|1|0|0|1|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"STP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"STP","Bits":"10:2|1|0|1|0|0|1|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"STP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"STP","Bits":"00:2|1|0|1|0|0|1|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 32-bit variant","Syntax":"STP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STP","Bits":"10:2|1|0|1|0|0|1|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 64-bit variant","Syntax":"STP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"10:2|1|1|1|0|0|0|0|0|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"STR <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"11:2|1|1|1|0|0|0|0|0|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"STR <Xt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"10:2|1|1|1|0|0|0|0|0|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"STR <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"11:2|1|1|1|0|0|0|0|0|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"STR <Xt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"10:2|1|1|1|0|0|1|0|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"STR <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate)","Bits":"11:2|1|1|1|0|0|1|0|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"STR <Xt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (register)","Bits":"10:2|1|1|1|0|0|0|0|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STR <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STR (register)","Bits":"11:2|1|1|1|0|0|0|0|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STR <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STRB (immediate)","Bits":"0|0|1|1|1|0|0|0|0|0|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"STRB <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STRB (immediate)","Bits":"0|0|1|1|1|0|0|0|0|0|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"STRB <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STRB (immediate)","Bits":"0|0|1|1|1|0|0|1|0|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset Unsigned offset variant","Syntax":"STRB <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STRB (register)","Bits":"0|0|1|1|1|0|0|0|0|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"Extended register variant","Syntax":"STRB <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"STRB (register)","Bits":"0|0|1|1|1|0|0|0|0|0|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"Shifted register variant","Syntax":"STRB <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"STRH (immediate)","Bits":"0|1|1|1|1|0|0|0|0|0|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index Post-index variant","Syntax":"STRH <Wt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STRH (immediate)","Bits":"0|1|1|1|1|0|0|0|0|0|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index Pre-index variant","Syntax":"STRH <Wt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STRH (immediate)","Bits":"0|1|1|1|1|0|0|1|0|0|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset Unsigned offset variant","Syntax":"STRH <Wt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STRH (register)","Bits":"0|1|1|1|1|0|0|0|0|0|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STRH <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STTR","Bits":"10:2|1|1|1|0|0|0|0|0|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STTR <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STTR","Bits":"11:2|1|1|1|0|0|0|0|0|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STTR <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STTRB","Bits":"0|0|1|1|1|0|0|0|0|0|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"STTRB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STTRH","Bits":"0|1|1|1|1|0|0|0|0|0|0|imm9:9|1|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"STTRH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR","Bits":"10:2|1|1|1|0|0|0|0|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STUR <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR","Bits":"11:2|1|1|1|0|0|0|0|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STUR <Xt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STURB","Bits":"0|0|1|1|1|0|0|0|0|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"STURB <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STURH","Bits":"0|1|1|1|1|0|0|0|0|0|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"Unscaled offset variant","Syntax":"STURH <Wt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STXP","Bits":"1|0|0|0|1|0|0|0|0|0|1|Rs:5|0|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STXP <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STXP","Bits":"1|1|0|0|1|0|0|0|0|0|1|Rs:5|0|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STXR","Bits":"10:2|0|0|1|0|0|0|0|0|0|Rs:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STXR <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STXR","Bits":"11:2|0|0|1|0|0|0|0|0|0|Rs:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STXR <Ws>, <Xt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STXRB","Bits":"0|0|0|0|1|0|0|0|0|0|0|Rs:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"STXRH","Bits":"0|1|0|0|1|0|0|0|0|0|0|Rs:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rt:5","Arch":"No offset variant","Syntax":"STXRH <Ws>, <Wt>, [<Xn|SP>{,#0}]","Code":"","Alias":""},
+{"Name":"SUB (extended register)","Bits":"0|1|0|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":""},
+{"Name":"SUB (extended register)","Bits":"1|1|0|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUB <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":""},
+{"Name":"SUB (immediate)","Bits":"0|1|0|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":""},
+{"Name":"SUB (immediate)","Bits":"1|1|0|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":""},
+{"Name":"SUB (shifted register)","Bits":"0|1|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUB <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias NEG (shifted register)."},
+{"Name":"SUB (shifted register)","Bits":"1|1|0|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUB <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the alias NEG (shifted register)."},
+{"Name":"SUBS (extended register)","Bits":"0|1|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is used by the alias CMP (extended register)."},
+{"Name":"SUBS (extended register)","Bits":"1|1|1|0|1|0|1|1|0|0|1|Rm:5|option:3|imm3:3|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUBS <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}","Code":"","Alias":"This instruction is used by the alias CMP (extended register)."},
+{"Name":"SUBS (immediate)","Bits":"0|1|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias CMP (immediate)."},
+{"Name":"SUBS (immediate)","Bits":"1|1|1|1|0|0|0|1|shift:2|imm12:12|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}","Code":"","Alias":"This instruction is used by the alias CMP (immediate)."},
+{"Name":"SUBS (shifted register)","Bits":"0|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SUBS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the aliases CMP (shifted register) and NEGS."},
+{"Name":"SUBS (shifted register)","Bits":"1|1|1|0|1|0|1|1|shift:2|0|Rm:5|imm6:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SUBS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is used by the aliases CMP (shifted register) and NEGS."},
+{"Name":"SVC","Bits":"1|1|0|1|0|1|0|0|0|0|0|imm16:16|0|0|0|0|1","Arch":"System variant","Syntax":"SVC #<imm>","Code":"","Alias":""},
+{"Name":"SXTB","Bits":"0|0|0|1|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SXTB <Wd>, <Wn>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SXTB","Bits":"1|0|0|1|0|0|1|1|0|1|0|0|0|0|0|0|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SXTB <Xd>, <Wn>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SXTH","Bits":"0|0|0|1|0|0|1|1|0|0|0|0|0|0|0|0|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SXTH <Wd>, <Wn>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SXTH","Bits":"1|0|0|1|0|0|1|1|0|1|0|0|0|0|0|0|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SXTH <Xd>, <Wn>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SXTW","Bits":"1|0|0|1|0|0|1|1|0|1|0|0|0|0|0|0|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SXTW <Xd>, <Wn>","Code":"","Alias":"This instruction is an alias of the SBFM instruction."},
+{"Name":"SYS","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|1|op1:3|CRn:4|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"SYS #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>}","Code":"","Alias":"This instruction is used by the aliases AT, DC, IC, and TLBI."},
+{"Name":"SYSL","Bits":"1|1|0|1|0|1|0|1|0|0|1|0|1|op1:3|CRn:4|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"SYSL <Xt>, #<op1>, <Cn>, <Cm>, #<op2>","Code":"","Alias":""},
+{"Name":"TBNZ","Bits":"b5|0|1|1|0|1|1|1|b40:5|imm14:14|Rt:5","Arch":"14-bit signed PC-relative branch offset variant","Syntax":"TBNZ <R><t>, #<imm>, <label>","Code":"","Alias":""},
+{"Name":"TBZ","Bits":"b5|0|1|1|0|1|1|0|b40:5|imm14:14|Rt:5","Arch":"14-bit signed PC-relative branch offset variant","Syntax":"TBZ <R><t>, #<imm>, <label>","Code":"","Alias":""},
+{"Name":"TLBI","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|1|op1:3|1|0|0|0|CRm:4|op2:3|Rt:5","Arch":"System variant","Syntax":"TLBI <tlbi_op>{, <Xt>}","Code":"","Alias":"This instruction is an alias of the SYS instruction."},
+{"Name":"TST (immediate)","Bits":"0|1|1|1|0|0|1|0|0|0|immr:6|imms:6|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"TST <Wn>, #<imm>","Code":"","Alias":"This instruction is an alias of the ANDS (immediate) instruction."},
+{"Name":"TST (immediate)","Bits":"1|1|1|1|0|0|1|0|0|N|immr:6|imms:6|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"TST <Xn>, #<imm>","Code":"","Alias":"This instruction is an alias of the ANDS (immediate) instruction."},
+{"Name":"TST (shifted register)","Bits":"0|1|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"32-bit variant","Syntax":"TST <Wn>, <Wm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ANDS (shifted register) instruction."},
+{"Name":"TST (shifted register)","Bits":"1|1|1|0|1|0|1|0|shift:2|0|Rm:5|imm6:6|Rn:5|1|1|1|1|1","Arch":"64-bit variant","Syntax":"TST <Xn>, <Xm>{, <shift> #<amount>}","Code":"","Alias":"This instruction is an alias of the ANDS (shifted register) instruction."},
+{"Name":"UBFIZ","Bits":"0|1|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UBFIZ <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"UBFIZ","Bits":"1|1|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UBFIZ <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"UBFM","Bits":"0|1|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UBFM <Wd>, <Wn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases LSL (immediate), LSR (immediate), UBFIZ, UBFX, UXTB, and UXTH."},
+{"Name":"UBFM","Bits":"1|1|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UBFM <Xd>, <Xn>, #<immr>, #<imms>","Code":"","Alias":"This instruction is used by the aliases LSL (immediate), LSR (immediate), UBFIZ, UBFX, UXTB, and UXTH."},
+{"Name":"UBFX","Bits":"0|1|0|1|0|0|1|1|0|0|immr:6|imms:6|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UBFX <Wd>, <Wn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"UBFX","Bits":"1|1|0|1|0|0|1|1|0|1|immr:6|imms:6|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UBFX <Xd>, <Xn>, #<lsb>, #<width>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"UDIV","Bits":"0|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UDIV <Wd>, <Wn>, <Wm>","Code":"","Alias":""},
+{"Name":"UDIV","Bits":"1|0|0|1|1|0|1|0|1|1|0|Rm:5|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UDIV <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"UMADDL","Bits":"1|0|0|1|1|0|1|1|1|0|1|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMADDL <Xd>, <Wn>, <Wm>, <Xa>","Code":"","Alias":"This instruction is used by the alias UMULL."},
+{"Name":"UMNEGL","Bits":"1|0|0|1|1|0|1|1|1|0|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMNEGL <Xd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the UMSUBL instruction."},
+{"Name":"UMSUBL","Bits":"1|0|0|1|1|0|1|1|1|0|1|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMSUBL <Xd>, <Wn>, <Wm>, <Xa>","Code":"","Alias":"This instruction is used by the alias UMNEGL."},
+{"Name":"UMULH","Bits":"1|0|0|1|1|0|1|1|1|1|0|Rm:5|0|(1)|(1)|(1)|(1)|(1)|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMULH <Xd>, <Xn>, <Xm>","Code":"","Alias":""},
+{"Name":"UMULL","Bits":"1|0|0|1|1|0|1|1|1|0|1|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMULL <Xd>, <Wn>, <Wm>","Code":"","Alias":"This instruction is an alias of the UMADDL instruction."},
+{"Name":"UXTB","Bits":"0|1|0|1|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UXTB <Wd>, <Wn>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"UXTH","Bits":"0|1|0|1|0|0|1|1|0|0|0|0|0|0|0|0|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UXTH <Wd>, <Wn>","Code":"","Alias":"This instruction is an alias of the UBFM instruction."},
+{"Name":"WFE","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|1|0|1|1|1|1|1","Arch":"System variant","Syntax":"WFE","Code":"","Alias":""},
+{"Name":"WFI","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|1|1|1|1|1|1|1","Arch":"System variant","Syntax":"WFI","Code":"","Alias":""},
+{"Name":"YIELD","Bits":"1|1|0|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|0|1|1|1|1|1|1","Arch":"System variant","Syntax":"YIELD","Code":"","Alias":""},
+{"Name":"ABS","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"ABS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"ABS","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"ABS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"ADD (vector)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"ADD <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"ADD (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"ADDHN, ADDHN2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"ADDHN <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"ADDHN, ADDHN2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"ADDHN2 <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"ADDP (scalar)","Bits":"0|1|0|1|1|1|1|0|size:2|1|1|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"ADDP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"ADDP (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"ADDV","Bits":"0|Q|0|0|1|1|1|0|size:2|1|1|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"ADDV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"AESD","Bits":"0|1|0|0|1|1|1|0|0|0|1|0|1|0|0|0|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"AESD <Vd>.16B, <Vn>.16B","Code":"","Alias":""},
+{"Name":"AESE","Bits":"0|1|0|0|1|1|1|0|0|0|1|0|1|0|0|0|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"AESE <Vd>.16B, <Vn>.16B","Code":"","Alias":""},
+{"Name":"AESIMC","Bits":"0|1|0|0|1|1|1|0|0|0|1|0|1|0|0|0|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"AESIMC <Vd>.16B, <Vn>.16B","Code":"","Alias":""},
+{"Name":"AESMC","Bits":"0|1|0|0|1|1|1|0|0|0|1|0|1|0|0|0|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"AESMC <Vd>.16B, <Vn>.16B","Code":"","Alias":""},
+{"Name":"AND (vector)","Bits":"0|Q|0|0|1|1|1|0|0|0|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"BIC (vector, immediate)","Bits":"0|Q|1|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"16-bit variant","Syntax":"BIC <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"BIC (vector, immediate)","Bits":"0|Q|1|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit variant","Syntax":"BIC <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"BIC (vector, register)","Bits":"0|Q|0|0|1|1|1|0|0|1|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"BIF","Bits":"0|Q|1|0|1|1|1|0|1|1|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"BIT","Bits":"0|Q|1|0|1|1|1|0|1|0|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"BSL","Bits":"0|Q|1|0|1|1|1|0|0|1|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CLS (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"CLS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"CLZ (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"CLZ <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"CMEQ (register)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMEQ <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMEQ (register)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CMEQ (zero)","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMEQ <V><d>, <V><n>, #0","Code":"","Alias":""},
+{"Name":"CMEQ (zero)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMEQ <Vd>.<T>, <Vn>.<T>, #0","Code":"","Alias":""},
+{"Name":"CMGE (register)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMGE <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMGE (register)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CMGE (zero)","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMGE <V><d>, <V><n>, #0","Code":"","Alias":""},
+{"Name":"CMGE (zero)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMGE <Vd>.<T>, <Vn>.<T>, #0","Code":"","Alias":""},
+{"Name":"CMGT (register)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMGT <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMGT (register)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CMGT (zero)","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMGT <V><d>, <V><n>, #0","Code":"","Alias":""},
+{"Name":"CMGT (zero)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMGT <Vd>.<T>, <Vn>.<T>, #0","Code":"","Alias":""},
+{"Name":"CMHI (register)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMHI <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMHI (register)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMHI <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CMHS (register)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMHS <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMHS (register)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMHS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CMLE (zero)","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMLE <V><d>, <V><n>, #0","Code":"","Alias":""},
+{"Name":"CMLE (zero)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMLE <Vd>.<T>, <Vn>.<T>, #0","Code":"","Alias":""},
+{"Name":"CMLT (zero)","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMLT <V><d>, <V><n>, #0","Code":"","Alias":""},
+{"Name":"CMLT (zero)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMLT <Vd>.<T>, <Vn>.<T>, #0","Code":"","Alias":""},
+{"Name":"CMTST","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"CMTST <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"CMTST","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"CMTST <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"CNT","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"CNT <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"DUP (element)","Bits":"0|1|0|1|1|1|1|0|0|0|0|imm5:5|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"DUP <V><d>, <Vn>.<T>[<index>]","Code":"","Alias":"This instruction is used by the alias MOV (scalar)."},
+{"Name":"DUP (element)","Bits":"0|Q|0|0|1|1|1|0|0|0|0|imm5:5|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"DUP <Vd>.<T>, <Vn>.<Ts>[<index>]","Code":"","Alias":"This instruction is used by the alias MOV (scalar)."},
+{"Name":"DUP (general)","Bits":"0|Q|0|0|1|1|1|0|0|0|0|imm5:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"DUP <Vd>.<T>, <R><n>","Code":"","Alias":""},
+{"Name":"EOR (vector)","Bits":"0|Q|1|0|1|1|1|0|0|0|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"EOR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"EXT","Bits":"0|Q|1|0|1|1|1|0|0|0|0|Rm:5|0|imm4:4|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"EXT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<index>","Code":"","Alias":""},
+{"Name":"FABD","Bits":"0|1|1|1|1|1|1|0|1|sz|1|Rm:5|1|1|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FABD <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FABD","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|Rm:5|1|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FABS (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FABS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FABS (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|0|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FABS <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FABS (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|0|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FABS <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FACGE","Bits":"0|1|1|1|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FACGE <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FACGE","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FACGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FACGT","Bits":"0|1|1|1|1|1|1|0|1|sz|1|Rm:5|1|1|1|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FACGT <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FACGT","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|Rm:5|1|1|1|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FACGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FADD (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FADD (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FADD <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FADD (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FADD <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FADDP (scalar)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|1|0|0|0|0|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FADDP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FADDP (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FCCMP","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|cond:4|0|1|Rn:5|0|nzcv:4","Arch":"Single-precision variant","Syntax":"FCCMP <Sn>, <Sm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"FCCMP","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|cond:4|0|1|Rn:5|0|nzcv:4","Arch":"Double-precision variant","Syntax":"FCCMP <Dn>, <Dm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"FCCMPE","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|cond:4|0|1|Rn:5|1|nzcv:4","Arch":"Single-precision variant","Syntax":"FCCMPE <Sn>, <Sm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"FCCMPE","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|cond:4|0|1|Rn:5|1|nzcv:4","Arch":"Double-precision variant","Syntax":"FCCMPE <Dn>, <Dm>, #<nzcv>, <cond>","Code":"","Alias":""},
+{"Name":"FCMEQ (register)","Bits":"0|1|0|1|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMEQ <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FCMEQ (register)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FCMEQ (zero)","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMEQ <V><d>, <V><n>, #0.0","Code":"","Alias":""},
+{"Name":"FCMEQ (zero)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMEQ <Vd>.<T>, <Vn>.<T>, #0.0","Code":"","Alias":""},
+{"Name":"FCMGE (register)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMGE <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FCMGE (register)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FCMGE (zero)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMGE <V><d>, <V><n>, #0.0","Code":"","Alias":""},
+{"Name":"FCMGE (zero)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMGE <Vd>.<T>, <Vn>.<T>, #0.0","Code":"","Alias":""},
+{"Name":"FCMGT (register)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMGT <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FCMGT (register)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|Rm:5|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FCMGT (zero)","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMGT <V><d>, <V><n>, #0.0","Code":"","Alias":""},
+{"Name":"FCMGT (zero)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMGT <Vd>.<T>, <Vn>.<T>, #0.0","Code":"","Alias":""},
+{"Name":"FCMLE (zero)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMLE <V><d>, <V><n>, #0.0","Code":"","Alias":""},
+{"Name":"FCMLE (zero)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMLE <Vd>.<T>, <Vn>.<T>, #0.0","Code":"","Alias":""},
+{"Name":"FCMLT (zero)","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCMLT <V><d>, <V><n>, #0.0","Code":"","Alias":""},
+{"Name":"FCMLT (zero)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCMLT <Vd>.<T>, <Vn>.<T>, #0.0","Code":"","Alias":""},
+{"Name":"FCMP","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|1|0|0|0|Rn:5|00:2|0|0|0","Arch":"Single-precision variant","Syntax":"FCMP <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FCMP","Bits":"0|0|0|1|1|1|1|0|00:2|1|(00000):5|0|0|1|0|0|0|Rn:5|01:2|0|0|0","Arch":"Single-precision, zero variant","Syntax":"FCMP <Sn>, #0.0","Code":"","Alias":""},
+{"Name":"FCMP","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|1|0|0|0|Rn:5|00:2|0|0|0","Arch":"Double-precision variant","Syntax":"FCMP <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FCMP","Bits":"0|0|0|1|1|1|1|0|01:2|1|(00000):5|0|0|1|0|0|0|Rn:5|01:2|0|0|0","Arch":"Double-precision, zero variant","Syntax":"FCMP <Dn>, #0.0","Code":"","Alias":""},
+{"Name":"FCMPE","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|1|0|0|0|Rn:5|10:2|0|0|0","Arch":"Single-precision variant","Syntax":"FCMPE <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FCMPE","Bits":"0|0|0|1|1|1|1|0|00:2|1|(00000):5|0|0|1|0|0|0|Rn:5|11:2|0|0|0","Arch":"Single-precision, zero variant","Syntax":"FCMPE <Sn>, #0.0","Code":"","Alias":""},
+{"Name":"FCMPE","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|1|0|0|0|Rn:5|10:2|0|0|0","Arch":"Double-precision variant","Syntax":"FCMPE <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FCMPE","Bits":"0|0|0|1|1|1|1|0|01:2|1|(00000):5|0|0|1|0|0|0|Rn:5|11:2|0|0|0","Arch":"Double-precision, zero variant","Syntax":"FCMPE <Dn>, #0.0","Code":"","Alias":""},
+{"Name":"FCSEL","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|cond:4|1|1|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FCSEL <Sd>, <Sn>, <Sm>, <cond>","Code":"","Alias":""},
+{"Name":"FCSEL","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|cond:4|1|1|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FCSEL <Dd>, <Dn>, <Dm>, <cond>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|11:2|1|0|0|0|1|00:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Half-precision to single-precision variant","Syntax":"FCVT <Sd>, <Hn>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|11:2|1|0|0|0|1|01:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Half-precision to double-precision variant","Syntax":"FCVT <Dd>, <Hn>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|1|11:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to half-precision variant","Syntax":"FCVT <Hd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|1|01:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to double-precision variant","Syntax":"FCVT <Dd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|1|11:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to half-precision variant","Syntax":"FCVT <Hd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVT","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|1|00:2|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to single-precision variant","Syntax":"FCVT <Sd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTAS (vector)","Bits":"0|1|0|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTAS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTAS (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTAS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTAS (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTAS <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTAS (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|1|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTAS <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTAS (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTAS <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTAS (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|1|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTAS <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTAU (vector)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTAU <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTAU (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTAU <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTAU (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTAU <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTAU (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|1|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTAU <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTAU (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTAU <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTAU (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|1|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTAU <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTL, FCVTL2","Bits":"0|0|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FCVTL <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"FCVTL, FCVTL2","Bits":"0|1|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FCVTL2 <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"FCVTMS (vector)","Bits":"0|1|0|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTMS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTMS (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTMS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTMS (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|1|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTMS <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTMS (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|1|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTMS <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTMS (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|1|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTMS <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTMS (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|1|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTMS <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTMU (vector)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTMU <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTMU (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTMU <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTMU (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|1|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTMU <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTMU (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|1|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTMU <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTMU (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|1|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTMU <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTMU (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|1|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTMU <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTN, FCVTN2","Bits":"0|0|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FCVTN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"FCVTN, FCVTN2","Bits":"0|1|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FCVTN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"FCVTNS (vector)","Bits":"0|1|0|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTNS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTNS (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTNS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTNS (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTNS <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTNS (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTNS <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTNS (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTNS <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTNS (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTNS <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTNU (vector)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTNU <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTNU (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTNU <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTNU (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTNU <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTNU (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTNU <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTNU (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTNU <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTNU (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTNU <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTPS (vector)","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTPS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTPS (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTPS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTPS (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTPS <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTPS (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTPS <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTPS (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTPS <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTPS (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTPS <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTPU (vector)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTPU <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTPU (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTPU <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTPU (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTPU <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTPU (scalar)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTPU <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTPU (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTPU <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTPU (scalar)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTPU <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTXN, FCVTXN2","Bits":"0|1|1|1|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTXN <Vb><d>, <Va><n>","Code":"","Alias":""},
+{"Name":"FCVTXN, FCVTXN2","Bits":"0|0|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTXN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"FCVTXN, FCVTXN2","Bits":"0|1|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTXN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"FCVTZS (vector, fixed-point)","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTZS <V><d>, <V><n>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZS (vector, fixed-point)","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTZS <Vd>.<T>, <Vn>.<T>, #<fbits>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"FCVTZS (vector, integer)","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTZS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTZS (vector, integer)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTZS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|00:2|0|1|1|0|0|0|scale:6|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTZS <Wd>, <Sn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|00:2|0|1|1|0|0|0|scale:6|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTZS <Xd>, <Sn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|01:2|0|1|1|0|0|0|scale:6|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTZS <Wd>, <Dn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|01:2|0|1|1|0|0|0|scale:6|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTZS <Xd>, <Dn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|00:2|1|1|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTZS <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|00:2|1|1|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTZS <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|01:2|1|1|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTZS <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTZS (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|01:2|1|1|1|0|0|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTZS <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTZU (vector, fixed-point)","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTZU <V><d>, <V><n>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZU (vector, fixed-point)","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTZU <Vd>.<T>, <Vn>.<T>, #<fbits>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"FCVTZU (vector, integer)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FCVTZU <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FCVTZU (vector, integer)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FCVTZU <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|00:2|0|1|1|0|0|1|scale:6|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTZU <Wd>, <Sn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|00:2|0|1|1|0|0|1|scale:6|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTZU <Xd>, <Sn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|01:2|0|1|1|0|0|1|scale:6|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTZU <Wd>, <Dn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|01:2|0|1|1|0|0|1|scale:6|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTZU <Xd>, <Dn>, #<fbits>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|00:2|1|1|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FCVTZU <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|00:2|1|1|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 64-bit variant","Syntax":"FCVTZU <Xd>, <Sn>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|01:2|1|1|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 32-bit variant","Syntax":"FCVTZU <Wd>, <Dn>","Code":"","Alias":""},
+{"Name":"FCVTZU (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|01:2|1|1|1|0|0|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FCVTZU <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FDIV (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FDIV <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FDIV (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|0|1|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FDIV <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FDIV (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|0|1|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FDIV <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMADD","Bits":"0|0|0|1|1|1|1|1|00:2|0|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMADD <Sd>, <Sn>, <Sm>, <Sa>","Code":"","Alias":""},
+{"Name":"FMADD","Bits":"0|0|0|1|1|1|1|1|01:2|0|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMADD <Dd>, <Dn>, <Dm>, <Da>","Code":"","Alias":""},
+{"Name":"FMAX (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMAX (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMAX <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FMAX (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMAX <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMAXNM (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMAXNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMAXNM (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMAXNM <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FMAXNM (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMAXNM <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMAXNMP (scalar)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|1|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMAXNMP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMAXNMP (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMAXNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMAXNMV","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|1|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMAXNMV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMAXP (scalar)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|1|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMAXP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMAXP (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMAXV","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|1|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMAXV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMIN (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|Rm:5|1|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMIN (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMIN <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FMIN (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMIN <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMINNM (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|Rm:5|1|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMINNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMINNM (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMINNM <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FMINNM (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMINNM <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMINNMP (scalar)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|1|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMINNMP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMINNMP (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|Rm:5|1|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMINNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMINNMV","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|1|0|0|0|0|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMINNMV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMINP (scalar)","Bits":"0|1|1|1|1|1|1|0|1|sz|1|1|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMINP <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMINP (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|Rm:5|1|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMINV","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|1|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision and double-precision variant","Syntax":"FMINV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FMLA (by element)","Bits":"0|1|0|1|1|1|1|1|1|sz|L|M|Rm:4|0|0|0|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FMLA <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMLA (by element)","Bits":"0|Q|0|0|1|1|1|1|1|sz|L|M|Rm:4|0|0|0|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMLA (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|0|1|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMLS (by element)","Bits":"0|1|0|1|1|1|1|1|1|sz|L|M|Rm:4|0|1|0|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FMLS <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMLS (by element)","Bits":"0|Q|0|0|1|1|1|1|1|sz|L|M|Rm:4|0|1|0|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMLS (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|Rm:5|1|1|0|0|1|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMOV (vector, immediate)","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|1|1|1|1|0|1|d|e|f|g|h|Rd:5","Arch":"Single-precision variant","Syntax":"FMOV <Vd>.<T>, #<imm>","Code":"","Alias":""},
+{"Name":"FMOV (vector, immediate)","Bits":"0|1|1|0|1|1|1|1|0|0|0|0|0|a|b|c|1|1|1|1|0|1|d|e|f|g|h|Rd:5","Arch":"Double-precision variant","Syntax":"FMOV <Vd>.2D, #<imm>","Code":"","Alias":""},
+{"Name":"FMOV (register)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMOV <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FMOV (register)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMOV <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"0|0|0|1|1|1|1|0|00:2|1|00:2|111:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit to single-precision variant","Syntax":"FMOV <Sd>, <Wn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"0|0|0|1|1|1|1|0|00:2|1|00:2|110:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision to 32-bit variant","Syntax":"FMOV <Wd>, <Sn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"1|0|0|1|1|1|1|0|01:2|1|00:2|111:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to double-precision variant","Syntax":"FMOV <Dd>, <Xn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"1|0|0|1|1|1|1|0|10:2|1|01:2|111:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to top half of 128-bit variant","Syntax":"FMOV <Vd>.D[1], <Xn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"1|0|0|1|1|1|1|0|01:2|1|00:2|110:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision to 64-bit variant","Syntax":"FMOV <Xd>, <Dn>","Code":"","Alias":""},
+{"Name":"FMOV (general)","Bits":"1|0|0|1|1|1|1|0|10:2|1|01:2|110:3|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Top half of 128-bit to 64-bit variant","Syntax":"FMOV <Xd>, <Vn>.D[1]","Code":"","Alias":""},
+{"Name":"FMOV (scalar, immediate)","Bits":"0|0|0|1|1|1|1|0|00:2|1|imm8:8|1|0|0|0|0|0|0|0|Rd:5","Arch":"Single-precision variant","Syntax":"FMOV <Sd>, #<imm>","Code":"","Alias":""},
+{"Name":"FMOV (scalar, immediate)","Bits":"0|0|0|1|1|1|1|0|01:2|1|imm8:8|1|0|0|0|0|0|0|0|Rd:5","Arch":"Double-precision variant","Syntax":"FMOV <Dd>, #<imm>","Code":"","Alias":""},
+{"Name":"FMSUB","Bits":"0|0|0|1|1|1|1|1|00:2|0|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMSUB <Sd>, <Sn>, <Sm>, <Sa>","Code":"","Alias":""},
+{"Name":"FMSUB","Bits":"0|0|0|1|1|1|1|1|01:2|0|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMSUB <Dd>, <Dn>, <Dm>, <Da>","Code":"","Alias":""},
+{"Name":"FMUL (by element)","Bits":"0|1|0|1|1|1|1|1|1|sz|L|M|Rm:4|1|0|0|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FMUL <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMUL (by element)","Bits":"0|Q|0|0|1|1|1|1|1|sz|L|M|Rm:4|1|0|0|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMUL (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|1|1|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FMUL (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FMUL <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FMUL (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FMUL <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FMULX (by element)","Bits":"0|1|1|1|1|1|1|1|1|sz|L|M|Rm:4|1|0|0|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FMULX <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMULX (by element)","Bits":"0|Q|1|0|1|1|1|1|1|sz|L|M|Rm:4|1|0|0|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"FMULX","Bits":"0|1|0|1|1|1|1|0|0|sz|1|Rm:5|1|1|0|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FMULX <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FMULX","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FNEG (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|0|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FNEG <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FNEG (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FNEG <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FNEG (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FNEG <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FNMADD","Bits":"0|0|0|1|1|1|1|1|00:2|1|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FNMADD <Sd>, <Sn>, <Sm>, <Sa>","Code":"","Alias":""},
+{"Name":"FNMADD","Bits":"0|0|0|1|1|1|1|1|01:2|1|Rm:5|0|Ra:5|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FNMADD <Dd>, <Dn>, <Dm>, <Da>","Code":"","Alias":""},
+{"Name":"FNMSUB","Bits":"0|0|0|1|1|1|1|1|00:2|1|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FNMSUB <Sd>, <Sn>, <Sm>, <Sa>","Code":"","Alias":""},
+{"Name":"FNMSUB","Bits":"0|0|0|1|1|1|1|1|01:2|1|Rm:5|1|Ra:5|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FNMSUB <Dd>, <Dn>, <Dm>, <Da>","Code":"","Alias":""},
+{"Name":"FNMUL (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FNMUL <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FNMUL (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FNMUL <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"FRECPE","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FRECPE <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FRECPE","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FRECPE <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRECPS","Bits":"0|1|0|1|1|1|1|0|0|sz|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FRECPS <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FRECPS","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FRECPS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FRECPX","Bits":"0|1|0|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar single-precision and double-precision variant","Syntax":"FRECPX <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FRINTA (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTA <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTA (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|1|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTA <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTA (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|1|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTA <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTI (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTI <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTI (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|1|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTI <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTI (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|1|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTI <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTM (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTM <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTM (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTM <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTM (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTM <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTN (vector)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTN <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTN (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTN <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTN (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|0|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTN <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTP (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTP <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTP (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|0|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTP <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTP (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|0|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTP <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTX (vector)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTX <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTX (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|1|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTX <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTX (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|1|1|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTX <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRINTZ (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FRINTZ <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRINTZ (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|1|0|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FRINTZ <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FRINTZ (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|1|0|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FRINTZ <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FRSQRTE","Bits":"0|1|1|1|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FRSQRTE <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"FRSQRTE","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FRSQRTE <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FRSQRTS","Bits":"0|1|0|1|1|1|1|0|1|sz|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"FRSQRTS <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"FRSQRTS","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|Rm:5|1|1|1|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"FRSQRTS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FSQRT (vector)","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FSQRT <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"FSQRT (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|0|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FSQRT <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"FSQRT (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|0|1|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FSQRT <Dd>, <Dn>","Code":"","Alias":""},
+{"Name":"FSUB (vector)","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|Rm:5|1|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector single-precision and double-precision variant","Syntax":"FSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"FSUB (scalar)","Bits":"0|0|0|1|1|1|1|0|00:2|1|Rm:5|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Single-precision variant","Syntax":"FSUB <Sd>, <Sn>, <Sm>","Code":"","Alias":""},
+{"Name":"FSUB (scalar)","Bits":"0|0|0|1|1|1|1|0|01:2|1|Rm:5|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Double-precision variant","Syntax":"FSUB <Dd>, <Dn>, <Dm>","Code":"","Alias":""},
+{"Name":"INS (element)","Bits":"0|1|1|0|1|1|1|0|0|0|0|imm5:5|0|imm4:4|1|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]","Code":"","Alias":"This instruction is used by the alias MOV (element)."},
+{"Name":"INS (general)","Bits":"0|1|0|0|1|1|1|0|0|0|0|imm5:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"INS <Vd>.<Ts>[<index>], <R><n>","Code":"","Alias":"This instruction is used by the alias MOV (from general)."},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|0111:4|size:2|Rn:5|Rt:5","Arch":"No offset One register variant","Syntax":"LD1 { <Vt>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|1010:4|size:2|Rn:5|Rt:5","Arch":"No offset Two registers variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|0110:4|size:2|Rn:5|Rt:5","Arch":"No offset Three registers variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|0010:4|size:2|Rn:5|Rt:5","Arch":"No offset Four registers variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|0111:4|size:2|Rn:5|Rt:5","Arch":"Post-index One register, immediate offset variant","Syntax":"LD1 { <Vt>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|0111:4|size:2|Rn:5|Rt:5","Arch":"Post-index One register, register offset variant","Syntax":"LD1 { <Vt>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|1010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Two registers, immediate offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|1010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Two registers, register offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|0110:4|size:2|Rn:5|Rt:5","Arch":"Post-index Three registers, immediate offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|0110:4|size:2|Rn:5|Rt:5","Arch":"Post-index Three registers, register offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|0010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Four registers, immediate offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|0010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Four registers, register offset variant","Syntax":"LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|000:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"LD1 { <Vt>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|010:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"LD1 { <Vt>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|100:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"LD1 { <Vt>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|100:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"LD1 { <Vt>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"LD1 { <Vt>.B }[<index>], [<Xn|SP>], #1","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"LD1 { <Vt>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"LD1 { <Vt>.H }[<index>], [<Xn|SP>], #2","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"LD1 { <Vt>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"LD1 { <Vt>.S }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"LD1 { <Vt>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"LD1 { <Vt>.D }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"LD1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"LD1 { <Vt>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD1R","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD1R { <Vt>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD1R","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD1R { <Vt>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD1R","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD1R { <Vt>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|000:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|010:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|100:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|100:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16","Code":"","Alias":""},
+{"Name":"LD2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD2R","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD2R","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD2R","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|1|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|001:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|011:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|101:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|101:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24","Code":"","Alias":""},
+{"Name":"LD3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD3R","Bits":"0|Q|0|0|1|1|0|1|0|1|0|0|0|0|0|0|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD3R","Bits":"0|Q|0|0|1|1|0|1|1|1|0|11111:5|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD3R","Bits":"0|Q|0|0|1|1|0|1|1|1|0|Rm:5|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|1|0|0|0|0|0|0|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|11111:5|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|1|0|Rm:5|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|001:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|011:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|101:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|101:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32","Code":"","Alias":""},
+{"Name":"LD4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LD4R","Bits":"0|Q|0|0|1|1|0|1|0|1|1|0|0|0|0|0|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"LD4R","Bits":"0|Q|0|0|1|1|0|1|1|1|1|11111:5|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"LD4R","Bits":"0|Q|0|0|1|1|0|1|1|1|1|Rm:5|1|1|1|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"LDNP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|0|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDNP <St1>, <St2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDNP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|0|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDNP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDNP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|0|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"LDNP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDP <St1>, <St2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDP <Dt1>, <Dt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|0|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 128-bit variant","Syntax":"LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDP <St1>, <St2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDP <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|1|1|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 128-bit variant","Syntax":"LDP <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 32-bit variant","Syntax":"LDP <St1>, <St2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 64-bit variant","Syntax":"LDP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|1|0|1|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 128-bit variant","Syntax":"LDP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|01:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 8-bit variant","Syntax":"LDR <Bt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|01:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 16-bit variant","Syntax":"LDR <Ht>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|01:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"LDR <St>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|01:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"LDR <Dt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|11:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 128-bit variant","Syntax":"LDR <Qt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|01:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 8-bit variant","Syntax":"LDR <Bt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|01:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 16-bit variant","Syntax":"LDR <Ht>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|01:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"LDR <St>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|01:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"LDR <Dt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|11:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 128-bit variant","Syntax":"LDR <Qt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|1|01:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 8-bit variant","Syntax":"LDR <Bt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|1|01:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 16-bit variant","Syntax":"LDR <Ht>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|1|01:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"LDR <St>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|1|01:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"LDR <Dt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|1|11:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 128-bit variant","Syntax":"LDR <Qt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"LDR (literal, SIMD&FP)","Bits":"00:2|0|1|1|1|0|0|imm19:19|Rt:5","Arch":"32-bit variant","Syntax":"LDR <St>, <label>","Code":"","Alias":""},
+{"Name":"LDR (literal, SIMD&FP)","Bits":"01:2|0|1|1|1|0|0|imm19:19|Rt:5","Arch":"64-bit variant","Syntax":"LDR <Dt>, <label>","Code":"","Alias":""},
+{"Name":"LDR (literal, SIMD&FP)","Bits":"10:2|0|1|1|1|0|0|imm19:19|Rt:5","Arch":"128-bit variant","Syntax":"LDR <Qt>, <label>","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|01:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"LDR <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|01:2|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"LDR <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|01:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"16-bit variant","Syntax":"LDR <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|01:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDR <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|01:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDR <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|11:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"LDR <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"LDUR (SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|01:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"LDUR <Bt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR (SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|01:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"16-bit variant","Syntax":"LDUR <Ht>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR (SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|01:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"LDUR <St>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR (SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|01:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"LDUR <Dt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"LDUR (SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|11:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"LDUR <Qt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"MLA (by element)","Bits":"0|Q|1|0|1|1|1|1|size:2|L|M|Rm:4|0|0|0|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"MLA (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"MLS (by element)","Bits":"0|Q|1|0|1|1|1|1|size:2|L|M|Rm:4|0|1|0|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"MLS (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"MOV (scalar)","Bits":"0|1|0|1|1|1|1|0|0|0|0|imm5:5|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar variant","Syntax":"MOV <V><d>, <Vn>.<T>[<index>]","Code":"","Alias":"This instruction is an alias of the DUP (element) instruction."},
+{"Name":"MOV (element)","Bits":"0|1|1|0|1|1|1|0|0|0|0|imm5:5|0|imm4:4|1|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"MOV <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]","Code":"","Alias":"This instruction is an alias of the INS (element) instruction."},
+{"Name":"MOV (from general)","Bits":"0|1|0|0|1|1|1|0|0|0|0|imm5:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"MOV <Vd>.<Ts>[<index>], <R><n>","Code":"","Alias":"This instruction is an alias of the INS (general) instruction."},
+{"Name":"MOV (vector)","Bits":"0|Q|0|0|1|1|1|0|1|0|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"MOV <Vd>.<T>, <Vn>.<T>","Code":"","Alias":"This instruction is an alias of the ORR (vector, register) instruction."},
+{"Name":"MOV (to general)","Bits":"0|0|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"MOV <Wd>, <Vn>.S[<index>]","Code":"","Alias":"This instruction is an alias of the UMOV instruction."},
+{"Name":"MOV (to general)","Bits":"0|1|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"MOV <Xd>, <Vn>.D[<index>]","Code":"","Alias":"This instruction is an alias of the UMOV instruction."},
+{"Name":"MOVI","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|1110:4|0|1|d|e|f|g|h|Rd:5","Arch":"8-bit variant","Syntax":"MOVI <Vd>.<T>, #<imm8>{, LSL #0}","Code":"","Alias":""},
+{"Name":"MOVI","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"16-bit shifted immediate variant","Syntax":"MOVI <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"MOVI","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit shifted immediate variant","Syntax":"MOVI <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"MOVI","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit shifting ones variant","Syntax":"MOVI <Vd>.<T>, #<imm8>, MSL #<amount>","Code":"","Alias":""},
+{"Name":"MOVI","Bits":"0|0|1|0|1|1|1|1|0|0|0|0|0|a|b|c|1110:4|0|1|d|e|f|g|h|Rd:5","Arch":"64-bit scalar variant","Syntax":"MOVI <Dd>, #<imm>","Code":"","Alias":""},
+{"Name":"MOVI","Bits":"0|1|1|0|1|1|1|1|0|0|0|0|0|a|b|c|1110:4|0|1|d|e|f|g|h|Rd:5","Arch":"64-bit vector variant","Syntax":"MOVI <Vd>.2D, #<imm>","Code":"","Alias":""},
+{"Name":"MUL (by element)","Bits":"0|Q|0|0|1|1|1|1|size:2|L|M|Rm:4|1|0|0|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"MUL <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"MUL (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"MUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"MVN","Bits":"0|Q|1|0|1|1|1|0|0|0|1|0|0|0|0|0|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"MVN <Vd>.<T>, <Vn>.<T>","Code":"","Alias":"This instruction is an alias of the NOT instruction."},
+{"Name":"MVNI","Bits":"0|Q|1|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"16-bit shifted immediate variant","Syntax":"MVNI <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"MVNI","Bits":"0|Q|1|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit shifted immediate variant","Syntax":"MVNI <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"MVNI","Bits":"0|Q|1|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit shifting ones variant","Syntax":"MVNI <Vd>.<T>, #<imm8>, MSL #<amount>","Code":"","Alias":""},
+{"Name":"NEG (vector)","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"NEG <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"NEG (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|1|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"NEG <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"NOT","Bits":"0|Q|1|0|1|1|1|0|0|0|1|0|0|0|0|0|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"NOT <Vd>.<T>, <Vn>.<T>","Code":"","Alias":"This instruction is used by the alias MVN."},
+{"Name":"ORN (vector)","Bits":"0|Q|0|0|1|1|1|0|1|1|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"ORN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"ORR (vector, immediate)","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"16-bit variant","Syntax":"ORR <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"ORR (vector, immediate)","Bits":"0|Q|0|0|1|1|1|1|0|0|0|0|0|a|b|c|cmode:4|0|1|d|e|f|g|h|Rd:5","Arch":"32-bit variant","Syntax":"ORR <Vd>.<T>, #<imm8>{, LSL #<amount>}","Code":"","Alias":""},
+{"Name":"ORR (vector, register)","Bits":"0|Q|0|0|1|1|1|0|1|0|1|Rm:5|0|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"ORR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":"This instruction is used by the alias MOV (vector)."},
+{"Name":"PMUL","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"PMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"PMULL, PMULL2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"PMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"PMULL, PMULL2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"PMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"RADDHN, RADDHN2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"RADDHN <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"RADDHN, RADDHN2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"RADDHN2 <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"RBIT (vector)","Bits":"0|Q|1|0|1|1|1|0|0|1|1|0|0|0|0|0|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"RBIT <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"REV16 (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|0|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"REV16 <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"REV32 (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"REV32 <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"REV64","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"REV64 <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"RSHRN, RSHRN2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"RSHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"RSHRN, RSHRN2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"RSHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"RSUBHN, RSUBHN2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"RSUBHN <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"RSUBHN, RSUBHN2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"RSUBHN2 <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"SABA","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SABAL, SABAL2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SABAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SABAL, SABAL2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SABAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SABD","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SABDL, SABDL2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SABDL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SABDL, SABDL2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SABDL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SADALP","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SADALP <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"SADDL, SADDL2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SADDL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SADDL, SADDL2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SADDL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SADDLP","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SADDLP <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"SADDLV","Bits":"0|Q|0|0|1|1|1|0|size:2|1|1|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SADDLV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SADDW, SADDW2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SADDW <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SADDW, SADDW2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SADDW2 <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SCVTF (vector, fixed-point)","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SCVTF <V><d>, <V><n>, #<fbits>","Code":"","Alias":""},
+{"Name":"SCVTF (vector, fixed-point)","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SCVTF <Vd>.<T>, <Vn>.<T>, #<fbits>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SCVTF (vector, integer)","Bits":"0|1|0|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SCVTF <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"SCVTF (vector, integer)","Bits":"0|Q|0|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SCVTF <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|00:2|0|0|0|0|1|0|scale:6|Rn:5|Rd:5","Arch":"32-bit to single-precision variant","Syntax":"SCVTF <Sd>, <Wn>, #<fbits>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|01:2|0|0|0|0|1|0|scale:6|Rn:5|Rd:5","Arch":"32-bit to double-precision variant","Syntax":"SCVTF <Dd>, <Wn>, #<fbits>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|00:2|0|0|0|0|1|0|scale:6|Rn:5|Rd:5","Arch":"64-bit to single-precision variant","Syntax":"SCVTF <Sd>, <Xn>, #<fbits>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|01:2|0|0|0|0|1|0|scale:6|Rn:5|Rd:5","Arch":"64-bit to double-precision variant","Syntax":"SCVTF <Dd>, <Xn>, #<fbits>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|1|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit to single-precision variant","Syntax":"SCVTF <Sd>, <Wn>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|1|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit to double-precision variant","Syntax":"SCVTF <Dd>, <Wn>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|0|1|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to single-precision variant","Syntax":"SCVTF <Sd>, <Xn>","Code":"","Alias":""},
+{"Name":"SCVTF (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|0|1|0|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to double-precision variant","Syntax":"SCVTF <Dd>, <Xn>","Code":"","Alias":""},
+{"Name":"SHA1C","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1C <Qd>, <Sn>, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA1H","Bits":"0|1|0|1|1|1|1|0|0|0|1|0|1|0|0|0|0|0|0|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1H <Sd>, <Sn>","Code":"","Alias":""},
+{"Name":"SHA1M","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1M <Qd>, <Sn>, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA1P","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1P <Qd>, <Sn>, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA1SU0","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|0|1|1|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1SU0 <Vd>.4S, <Vn>.4S, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA1SU1","Bits":"0|1|0|1|1|1|1|0|0|0|1|0|1|0|0|0|0|0|0|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA1SU1 <Vd>.4S, <Vn>.4S","Code":"","Alias":""},
+{"Name":"SHA256H2","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|1|0|1|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA256H2 <Qd>, <Qn>, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA256H","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|1|0|0|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA256H <Qd>, <Qn>, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHA256SU0","Bits":"0|1|0|1|1|1|1|0|0|0|1|0|1|0|0|0|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA256SU0 <Vd>.4S, <Vn>.4S","Code":"","Alias":""},
+{"Name":"SHA256SU1","Bits":"0|1|0|1|1|1|1|0|0|0|0|Rm:5|0|1|1|0|0|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SHA256SU1 <Vd>.4S, <Vn>.4S, <Vm>.4S","Code":"","Alias":""},
+{"Name":"SHADD","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SHL","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SHL <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SHL","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SHL <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SHLL, SHLL2","Bits":"0|0|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SHLL <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"","Alias":""},
+{"Name":"SHLL, SHLL2","Bits":"0|1|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SHLL2 <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"","Alias":""},
+{"Name":"SHRN, SHRN2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SHRN, SHRN2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SHSUB","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SHSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SLI","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SLI <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SLI","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SLI <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SMAX","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SMAXP","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SMAXV","Bits":"0|Q|0|0|1|1|1|0|size:2|1|1|0|0|0|0|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SMAXV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SMIN","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SMINP","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SMINV","Bits":"0|Q|0|0|1|1|1|0|size:2|1|1|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"SMINV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SMLAL, SMLAL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMLAL, SMLAL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMLAL, SMLAL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SMLAL, SMLAL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SMLSL, SMLSL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMLSL, SMLSL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMLSL, SMLSL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SMLSL, SMLSL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SMOV","Bits":"0|0|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"SMOV <Wd>, <Vn>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMOV","Bits":"0|1|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"SMOV <Xd>, <Vn>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMULL, SMULL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMULL, SMULL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SMULL, SMULL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SMULL, SMULL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQABS","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQABS <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"SQABS","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQABS <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SQADD","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQADD <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQADD","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (by element)","Bits":"0|1|0|1|1|1|1|1|size:2|L|M|Rm:4|0|0|1|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (vector)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|0|0|1|0|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMLAL <Va><d>, <Vb><n>, <Vb><m>","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQDMLAL, SQDMLAL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|0|0|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (by element)","Bits":"0|1|0|1|1|1|1|1|size:2|L|M|Rm:4|0|1|1|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMLSL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (vector)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMLSL <Va><d>, <Vb><n>, <Vb><m>","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQDMLSL, SQDMLSL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQDMULH (by element)","Bits":"0|1|0|1|1|1|1|1|size:2|L|M|Rm:4|1|1|0|0|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMULH <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMULH (by element)","Bits":"0|Q|0|0|1|1|1|1|size:2|L|M|Rm:4|1|1|0|0|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMULH (vector)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMULH <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQDMULH (vector)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (by element)","Bits":"0|1|0|1|1|1|1|1|size:2|L|M|Rm:4|1|0|1|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMULL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (by element)","Bits":"0|0|0|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (by element)","Bits":"0|1|0|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (vector)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|1|1|0|1|0|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQDMULL <Va><d>, <Vb><n>, <Vb><m>","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (vector)","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|1|1|0|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQDMULL, SQDMULL2 (vector)","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|1|1|0|1|0|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQDMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SQNEG","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQNEG <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"SQNEG","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQNEG <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SQRDMULH (by element)","Bits":"0|1|0|1|1|1|1|1|size:2|L|M|Rm:4|1|1|0|1|H|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQRDMULH <V><d>, <V><n>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQRDMULH (by element)","Bits":"0|Q|0|0|1|1|1|1|size:2|L|M|Rm:4|1|1|0|1|H|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"SQRDMULH (vector)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQRDMULH <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQRDMULH (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQRSHL","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|1|0|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQRSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQRSHL","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQRSHRN, SQRSHRN2","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQRSHRN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQRSHRN, SQRSHRN2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRSHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQRSHRN, SQRSHRN2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRSHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQRSHRUN, SQRSHRUN2","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQRSHRUN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQRSHRUN, SQRSHRUN2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRSHRUN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQRSHRUN, SQRSHRUN2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQRSHRUN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHL (immediate)","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSHL <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQSHL (immediate)","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHL <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHL (register)","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|1|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQSHL (register)","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQSHLU","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSHLU <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQSHLU","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHLU <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHRN, SQSHRN2","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSHRN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQSHRN, SQSHRN2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHRN, SQSHRN2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHRUN, SQSHRUN2","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSHRUN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SQSHRUN, SQSHRUN2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHRUN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSHRUN, SQSHRUN2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSHRUN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SQSUB","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQSUB <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SQSUB","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SQXTN, SQXTN2","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQXTN <Vb><d>, <Va><n>","Code":"","Alias":""},
+{"Name":"SQXTN, SQXTN2","Bits":"0|0|0|0|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQXTN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"SQXTN, SQXTN2","Bits":"0|1|0|0|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQXTN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"SQXTUN, SQXTUN2","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SQXTUN <Vb><d>, <Va><n>","Code":"","Alias":""},
+{"Name":"SQXTUN, SQXTUN2","Bits":"0|0|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQXTUN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"SQXTUN, SQXTUN2","Bits":"0|1|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SQXTUN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"SRHADD","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"SRHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SRI","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SRI <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SRI","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SRI <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SRSHL","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SRSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SRSHL","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SRSHR","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SRSHR <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SRSHR","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SRSHR <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SRSRA","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SRSRA <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SRSRA","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SRSRA <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SSHL","Bits":"0|1|0|1|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SSHL","Bits":"0|Q|0|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SSHLL, SSHLL2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|immb:3|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SSHLL <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":"This instruction is used by the alias SXTL, SXTL2."},
+{"Name":"SSHLL, SSHLL2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|immb:3|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SSHLL2 <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":"This instruction is used by the alias SXTL, SXTL2."},
+{"Name":"SSHR","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SSHR <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SSHR","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SSHR <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SSRA","Bits":"0|1|0|1|1|1|1|1|0|immh:4|immb:3|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SSRA <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"SSRA","Bits":"0|Q|0|0|1|1|1|1|0|immh:4|immb:3|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SSRA <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"SSUBL, SSUBL2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SSUBL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SSUBL, SSUBL2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SSUBL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SSUBW, SSUBW2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SSUBW <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"SSUBW, SSUBW2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SSUBW2 <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0111:4|size:2|Rn:5|Rt:5","Arch":"No offset One register variant","Syntax":"ST1 { <Vt>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|1010:4|size:2|Rn:5|Rt:5","Arch":"No offset Two registers variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0110:4|size:2|Rn:5|Rt:5","Arch":"No offset Three registers variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0010:4|size:2|Rn:5|Rt:5","Arch":"No offset Four registers variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|0111:4|size:2|Rn:5|Rt:5","Arch":"Post-index One register, immediate offset variant","Syntax":"ST1 { <Vt>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|0111:4|size:2|Rn:5|Rt:5","Arch":"Post-index One register, register offset variant","Syntax":"ST1 { <Vt>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|1010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Two registers, immediate offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|1010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Two registers, register offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|0110:4|size:2|Rn:5|Rt:5","Arch":"Post-index Three registers, immediate offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|0110:4|size:2|Rn:5|Rt:5","Arch":"Post-index Three registers, register offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|0010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Four registers, immediate offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST1 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|0010:4|size:2|Rn:5|Rt:5","Arch":"Post-index Four registers, register offset variant","Syntax":"ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|000:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"ST1 { <Vt>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|010:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"ST1 { <Vt>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|100:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"ST1 { <Vt>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|100:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"ST1 { <Vt>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"ST1 { <Vt>.B }[<index>], [<Xn|SP>], #1","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"ST1 { <Vt>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"ST1 { <Vt>.H }[<index>], [<Xn|SP>], #2","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"ST1 { <Vt>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"ST1 { <Vt>.S }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"ST1 { <Vt>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"ST1 { <Vt>.D }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"ST1 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"ST1 { <Vt>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST2 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|1|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|000:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"ST2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|010:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"ST2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|100:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"ST2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|100:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"ST2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"ST2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|000:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"ST2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"ST2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|010:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"ST2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"ST2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|100:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"ST2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"ST2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16","Code":"","Alias":""},
+{"Name":"ST2 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|100:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"ST2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST3 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|0|1|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|001:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"ST3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|011:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"ST3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|101:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"ST3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|0|0|0|0|0|0|101:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"ST3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"ST3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"ST3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"ST3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"ST3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"ST3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"ST3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|11111:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"ST3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24","Code":"","Alias":""},
+{"Name":"ST3 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|0|Rm:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"ST3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"No offset No offset variant","Syntax":"ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|11111:5|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Immediate offset variant","Syntax":"ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>","Code":"","Alias":""},
+{"Name":"ST4 (multiple structures)","Bits":"0|Q|0|0|1|1|0|0|1|0|0|Rm:5|0|0|0|0|size:2|Rn:5|Rt:5","Arch":"Post-index Register offset variant","Syntax":"ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|001:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 8-bit variant","Syntax":"ST4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|011:3|S|size:2|Rn:5|Rt:5","Arch":"No offset 16-bit variant","Syntax":"ST4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|101:3|S|00:2|Rn:5|Rt:5","Arch":"No offset 32-bit variant","Syntax":"ST4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|0|0|1|0|0|0|0|0|101:3|0|01:2|Rn:5|Rt:5","Arch":"No offset 64-bit variant","Syntax":"ST4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, immediate offset variant","Syntax":"ST4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|001:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 8-bit, register offset variant","Syntax":"ST4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, immediate offset variant","Syntax":"ST4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|011:3|S|size:2|Rn:5|Rt:5","Arch":"Post-index 16-bit, register offset variant","Syntax":"ST4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, immediate offset variant","Syntax":"ST4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|101:3|S|00:2|Rn:5|Rt:5","Arch":"Post-index 32-bit, register offset variant","Syntax":"ST4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|11111:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, immediate offset variant","Syntax":"ST4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32","Code":"","Alias":""},
+{"Name":"ST4 (single structure)","Bits":"0|Q|0|0|1|1|0|1|1|0|1|Rm:5|101:3|0|01:2|Rn:5|Rt:5","Arch":"Post-index 64-bit, register offset variant","Syntax":"ST4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>","Code":"","Alias":""},
+{"Name":"STNP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|0|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STNP <St1>, <St2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STNP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|0|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STNP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STNP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|0|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"STNP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|0|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"STP <St1>, <St2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|0|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"STP <Dt1>, <Dt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|0|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Post-index 128-bit variant","Syntax":"STP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|1|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"STP <St1>, <St2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|1|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"STP <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|1|1|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Pre-index 128-bit variant","Syntax":"STP <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"00:2|1|0|1|1|0|1|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 32-bit variant","Syntax":"STP <St1>, <St2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"01:2|1|0|1|1|0|1|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 64-bit variant","Syntax":"STP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STP (SIMD&FP)","Bits":"10:2|1|0|1|1|0|1|0|0|imm7:7|Rt2:5|Rn:5|Rt:5","Arch":"Signed offset 128-bit variant","Syntax":"STP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|00:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 8-bit variant","Syntax":"STR <Bt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|00:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 16-bit variant","Syntax":"STR <Ht>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|00:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 32-bit variant","Syntax":"STR <St>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|00:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 64-bit variant","Syntax":"STR <Dt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|10:2|0|imm9:9|0|1|Rn:5|Rt:5","Arch":"Post-index 128-bit variant","Syntax":"STR <Qt>, [<Xn|SP>], #<simm>","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|00:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 8-bit variant","Syntax":"STR <Bt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|00:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 16-bit variant","Syntax":"STR <Ht>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|00:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 32-bit variant","Syntax":"STR <St>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|00:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 64-bit variant","Syntax":"STR <Dt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|10:2|0|imm9:9|1|1|Rn:5|Rt:5","Arch":"Pre-index 128-bit variant","Syntax":"STR <Qt>, [<Xn|SP>, #<simm>]!","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|1|00:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 8-bit variant","Syntax":"STR <Bt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"01:2|1|1|1|1|0|1|00:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 16-bit variant","Syntax":"STR <Ht>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"10:2|1|1|1|1|0|1|00:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 32-bit variant","Syntax":"STR <St>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"11:2|1|1|1|1|0|1|00:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 64-bit variant","Syntax":"STR <Dt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (immediate, SIMD&FP)","Bits":"00:2|1|1|1|1|0|1|10:2|imm12:12|Rn:5|Rt:5","Arch":"Unsigned offset 128-bit variant","Syntax":"STR <Qt>, [<Xn|SP>{, #<pimm>}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|00:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"STR <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|00:2|1|Rm:5|011:3|S|1|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"STR <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|00:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"16-bit variant","Syntax":"STR <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|00:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STR <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|00:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STR <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STR (register, SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|10:2|1|Rm:5|option:3|S|1|0|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"STR <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]","Code":"","Alias":""},
+{"Name":"STUR (SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|00:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"8-bit variant","Syntax":"STUR <Bt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR (SIMD&FP)","Bits":"01:2|1|1|1|1|0|0|00:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"16-bit variant","Syntax":"STUR <Ht>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR (SIMD&FP)","Bits":"10:2|1|1|1|1|0|0|00:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"32-bit variant","Syntax":"STUR <St>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR (SIMD&FP)","Bits":"11:2|1|1|1|1|0|0|00:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"64-bit variant","Syntax":"STUR <Dt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"STUR (SIMD&FP)","Bits":"00:2|1|1|1|1|0|0|10:2|0|imm9:9|0|0|Rn:5|Rt:5","Arch":"128-bit variant","Syntax":"STUR <Qt>, [<Xn|SP>{, #<simm>}]","Code":"","Alias":""},
+{"Name":"SUB (vector)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SUB <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"SUB (vector)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"SUBHN, SUBHN2","Bits":"0|0|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SUBHN <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"SUBHN, SUBHN2","Bits":"0|1|0|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"SUBHN2 <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"SUQADD","Bits":"0|1|0|1|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"SUQADD <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"SUQADD","Bits":"0|Q|0|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"SUQADD <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"SXTL, SXTL2","Bits":"0|0|0|0|1|1|1|1|0|immh:4|0|0|0|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SXTL <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":"This instruction is an alias of the SSHLL, SSHLL2 instruction."},
+{"Name":"SXTL, SXTL2","Bits":"0|1|0|0|1|1|1|1|0|immh:4|0|0|0|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"SXTL2 <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":"This instruction is an alias of the SSHLL, SSHLL2 instruction."},
+{"Name":"TBL","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|01:2|0|0|0|Rn:5|Rd:5","Arch":"Two register table variant","Syntax":"TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBL","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|10:2|0|0|0|Rn:5|Rd:5","Arch":"Three register table variant","Syntax":"TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBL","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|11:2|0|0|0|Rn:5|Rd:5","Arch":"Four register table variant","Syntax":"TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBL","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|00:2|0|0|0|Rn:5|Rd:5","Arch":"Single register table variant","Syntax":"TBL <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBX","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|01:2|1|0|0|Rn:5|Rd:5","Arch":"Two register table variant","Syntax":"TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBX","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|10:2|1|0|0|Rn:5|Rd:5","Arch":"Three register table variant","Syntax":"TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBX","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|11:2|1|0|0|Rn:5|Rd:5","Arch":"Four register table variant","Syntax":"TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TBX","Bits":"0|Q|0|0|1|1|1|0|0|0|0|Rm:5|0|00:2|1|0|0|Rn:5|Rd:5","Arch":"Single register table variant","Syntax":"TBX <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>","Code":"","Alias":""},
+{"Name":"TRN1","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"TRN1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"TRN2","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"TRN2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UABA","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UABAL, UABAL2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UABAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UABAL, UABAL2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UABAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UABD","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UABDL, UABDL2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UABDL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UABDL, UABDL2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UABDL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UADALP","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|1|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UADALP <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"UADDL, UADDL2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UADDL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UADDL, UADDL2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UADDL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UADDLP","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UADDLP <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":""},
+{"Name":"UADDLV","Bits":"0|Q|1|0|1|1|1|0|size:2|1|1|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"UADDLV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"UADDW, UADDW2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UADDW <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UADDW, UADDW2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UADDW2 <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UCVTF (vector, fixed-point)","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UCVTF <V><d>, <V><n>, #<fbits>","Code":"","Alias":""},
+{"Name":"UCVTF (vector, fixed-point)","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|1|1|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UCVTF <Vd>.<T>, <Vn>.<T>, #<fbits>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UCVTF (vector, integer)","Bits":"0|1|1|1|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UCVTF <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"UCVTF (vector, integer)","Bits":"0|Q|1|0|1|1|1|0|0|sz|1|0|0|0|0|1|1|1|0|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UCVTF <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|00:2|0|0|0|0|1|1|scale:6|Rn:5|Rd:5","Arch":"32-bit to single-precision variant","Syntax":"UCVTF <Sd>, <Wn>, #<fbits>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, fixed-point)","Bits":"0|0|0|1|1|1|1|0|01:2|0|0|0|0|1|1|scale:6|Rn:5|Rd:5","Arch":"32-bit to double-precision variant","Syntax":"UCVTF <Dd>, <Wn>, #<fbits>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|00:2|0|0|0|0|1|1|scale:6|Rn:5|Rd:5","Arch":"64-bit to single-precision variant","Syntax":"UCVTF <Sd>, <Xn>, #<fbits>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, fixed-point)","Bits":"1|0|0|1|1|1|1|0|01:2|0|0|0|0|1|1|scale:6|Rn:5|Rd:5","Arch":"64-bit to double-precision variant","Syntax":"UCVTF <Dd>, <Xn>, #<fbits>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|00:2|1|0|0|0|1|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit to single-precision variant","Syntax":"UCVTF <Sd>, <Wn>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, integer)","Bits":"0|0|0|1|1|1|1|0|01:2|1|0|0|0|1|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"32-bit to double-precision variant","Syntax":"UCVTF <Dd>, <Wn>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|00:2|1|0|0|0|1|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to single-precision variant","Syntax":"UCVTF <Sd>, <Xn>","Code":"","Alias":""},
+{"Name":"UCVTF (scalar, integer)","Bits":"1|0|0|1|1|1|1|0|01:2|1|0|0|0|1|1|0|0|0|0|0|0|Rn:5|Rd:5","Arch":"64-bit to double-precision variant","Syntax":"UCVTF <Dd>, <Xn>","Code":"","Alias":""},
+{"Name":"UHADD","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UHSUB","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UHSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UMAX","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UMAXP","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UMAXV","Bits":"0|Q|1|0|1|1|1|0|size:2|1|1|0|0|0|0|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"UMAXV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"UMIN","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|1|0|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UMINP","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|1|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"UMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UMINV","Bits":"0|Q|1|0|1|1|1|0|size:2|1|1|0|0|0|1|1|0|1|0|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"UMINV <V><d>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"UMLAL, UMLAL2 (by element)","Bits":"0|0|1|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMLAL, UMLAL2 (by element)","Bits":"0|1|1|0|1|1|1|1|size:2|L|M|Rm:4|0|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMLAL, UMLAL2 (vector)","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMLAL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UMLAL, UMLAL2 (vector)","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|1|0|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMLAL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UMLSL, UMLSL2 (by element)","Bits":"0|0|1|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMLSL, UMLSL2 (by element)","Bits":"0|1|1|0|1|1|1|1|size:2|L|M|Rm:4|0|1|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMLSL, UMLSL2 (vector)","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMLSL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UMLSL, UMLSL2 (vector)","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|1|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMLSL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UMOV","Bits":"0|0|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"32-bit variant","Syntax":"UMOV <Wd>, <Vn>.<Ts>[<index>]","Code":"","Alias":"This instruction is used by the alias MOV (to general)."},
+{"Name":"UMOV","Bits":"0|1|0|0|1|1|1|0|0|0|0|imm5:5|0|0|1|1|1|1|Rn:5|Rd:5","Arch":"64-bit variant","Syntax":"UMOV <Xd>, <Vn>.<Ts>[<index>]","Code":"","Alias":"This instruction is used by the alias MOV (to general)."},
+{"Name":"UMULL, UMULL2 (by element)","Bits":"0|0|1|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMULL, UMULL2 (by element)","Bits":"0|1|1|0|1|1|1|1|size:2|L|M|Rm:4|1|0|1|0|H|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]","Code":"","Alias":""},
+{"Name":"UMULL, UMULL2 (vector)","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMULL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UMULL, UMULL2 (vector)","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|1|1|0|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"UMULL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UQADD","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQADD <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"UQADD","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UQRSHL","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|1|0|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQRSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"UQRSHL","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UQRSHRN, UQRSHRN2","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQRSHRN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"UQRSHRN, UQRSHRN2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQRSHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UQRSHRN, UQRSHRN2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQRSHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UQSHL (immediate)","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQSHL <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"UQSHL (immediate)","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|1|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQSHL <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UQSHL (register)","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|1|0|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"UQSHL (register)","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UQSHRN, UQSHRN2","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQSHRN <Vb><d>, <Va><n>, #<shift>","Code":"","Alias":""},
+{"Name":"UQSHRN, UQSHRN2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQSHRN <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UQSHRN, UQSHRN2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|immb:3|1|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQSHRN2 <Vd>.<Tb>, <Vn>.<Ta>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"UQSUB","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQSUB <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"UQSUB","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|1|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UQXTN, UQXTN2","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"UQXTN <Vb><d>, <Va><n>","Code":"","Alias":""},
+{"Name":"UQXTN, UQXTN2","Bits":"0|0|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQXTN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"UQXTN, UQXTN2","Bits":"0|1|1|0|1|1|1|0|size:2|1|0|0|0|0|1|0|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"UQXTN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"URECPE","Bits":"0|Q|0|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"URECPE <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"URHADD","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Three registers of the same type variant","Syntax":"URHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"URSHL","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"URSHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"URSHL","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"URSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"URSHR","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"URSHR <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"URSHR","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"URSHR <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"URSQRTE","Bits":"0|Q|1|0|1|1|1|0|1|sz|1|0|0|0|0|1|1|1|0|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"URSQRTE <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"URSRA","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"URSRA <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"URSRA","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|0|1|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"URSRA <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"USHL","Bits":"0|1|1|1|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"USHL <V><d>, <V><n>, <V><m>","Code":"","Alias":""},
+{"Name":"USHL","Bits":"0|Q|1|0|1|1|1|0|size:2|1|Rm:5|0|1|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"USHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"USHLL, USHLL2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|immb:3|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"USHLL <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":"This instruction is used by the alias UXTL, UXTL2."},
+{"Name":"USHLL, USHLL2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|immb:3|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"USHLL2 <Vd>.<Ta>, <Vn>.<Tb>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":"This instruction is used by the alias UXTL, UXTL2."},
+{"Name":"USHR","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"USHR <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"USHR","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|0|0|0|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"USHR <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"USQADD","Bits":"0|1|1|1|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"USQADD <V><d>, <V><n>","Code":"","Alias":""},
+{"Name":"USQADD","Bits":"0|Q|1|0|1|1|1|0|size:2|1|0|0|0|0|0|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"USQADD <Vd>.<T>, <Vn>.<T>","Code":"","Alias":""},
+{"Name":"USRA","Bits":"0|1|1|1|1|1|1|1|0|immh:4|immb:3|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Scalar Scalar variant","Syntax":"USRA <V><d>, <V><n>, #<shift>","Code":"","Alias":""},
+{"Name":"USRA","Bits":"0|Q|1|0|1|1|1|1|0|immh:4|immb:3|0|0|0|1|0|1|Rn:5|Rd:5","Arch":"Vector Vector variant","Syntax":"USRA <Vd>.<T>, <Vn>.<T>, #<shift>","Code":"if immh == '0000' then SEE \"Advanced SIMD modified immediate\";","Alias":""},
+{"Name":"USUBL, USUBL2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"USUBL <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"USUBL, USUBL2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|0|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"USUBL2 <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"USUBW, USUBW2","Bits":"0|0|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"USUBW <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"USUBW, USUBW2","Bits":"0|1|1|0|1|1|1|0|size:2|1|Rm:5|0|0|1|1|0|0|Rn:5|Rd:5","Arch":"Three registers, not all the same type variant","Syntax":"USUBW2 <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>","Code":"","Alias":""},
+{"Name":"UXTL, UXTL2","Bits":"0|0|1|0|1|1|1|1|0|immh:4|0|0|0|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UXTL <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":"This instruction is an alias of the USHLL, USHLL2 instruction."},
+{"Name":"UXTL, UXTL2","Bits":"0|1|1|0|1|1|1|1|0|immh:4|0|0|0|1|0|1|0|0|1|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"UXTL2 <Vd>.<Ta>, <Vn>.<Tb>","Code":"","Alias":"This instruction is an alias of the USHLL, USHLL2 instruction."},
+{"Name":"UZP1","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|0|0|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"UZP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"UZP2","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|1|0|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"UZP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"XTN, XTN2","Bits":"0|0|0|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"XTN <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"XTN, XTN2","Bits":"0|1|0|0|1|1|1|0|size:2|1|0|0|0|0|1|0|0|1|0|1|0|Rn:5|Rd:5","Arch":"Vector variant","Syntax":"XTN2 <Vd>.<Tb>, <Vn>.<Ta>","Code":"","Alias":""},
+{"Name":"ZIP1","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|0|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"ZIP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""},
+{"Name":"ZIP2","Bits":"0|Q|0|0|1|1|1|0|size:2|0|Rm:5|0|1|1|1|1|0|Rn:5|Rd:5","Arch":"Advanced SIMD variant","Syntax":"ZIP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>","Code":"","Alias":""}
+]
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdump_test.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdump_test.go
new file mode 100644
index 0000000..1e7966d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdump_test.go
@@ -0,0 +1,145 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestObjdumpARM64Testdata(t *testing.T) { testObjdumpARM64(t, testdataCases(t)) }
+func TestObjdumpARM64Manual(t *testing.T)   { testObjdumpARM64(t, hexCases(t, objdumpManualTests)) }
+func TestObjdumpARM64Cond(t *testing.T)     { testObjdumpARM64(t, condCases(t)) }
+func TestObjdumpARM64(t *testing.T)         { testObjdumpARM64(t, JSONCases(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 = `
+bf2003d5
+9f2003d5
+7f2003d5
+5f2003d5
+3f2003d5
+1f2003d5
+df4d03d5
+ff4d03d5
+28d91b14
+da6cb530
+15e5e514
+ff4603d5
+df4803d5
+bf4100d5
+9f3f03d5
+9f3e03d5
+9f3d03d5
+9f3b03d5
+9f3a03d5
+9f3903d5
+9f3703d5
+9f3603d5
+9f3503d5
+9f3303d5
+9f3203d5
+9f3103d5
+ff4603d5
+df4803d5
+bf4100d5
+a3681b53
+47dc78d3
+0500a012
+0500e092
+0500a052
+0500a0d2
+cd5a206e
+cd5a202e
+743d050e
+743d0a0e
+743d0c0e
+743d084e
+`
+
+// allowedMismatchObjdump reports whether the mismatch between text and dec
+// should be allowed by the test.
+func allowedMismatchObjdump(text string, inst *Inst, dec ExtInst) bool {
+	// Skip unsupported instructions
+	if hasPrefix(dec.text, todo...) {
+		return true
+	}
+	// GNU objdump has incorrect alias conditions for following instructions
+	if inst.Enc&0x000003ff == 0x000003ff && hasPrefix(dec.text, "negs") && hasPrefix(text, "cmp") {
+		return true
+	}
+	// GNU objdump "NV" is equal to our "AL"
+	if strings.HasSuffix(dec.text, " nv") && strings.HasSuffix(text, " al") {
+		return true
+	}
+	if strings.HasPrefix(dec.text, "b.nv") && strings.HasPrefix(text, "b.al") {
+		return true
+	}
+	// GNU objdump recognizes invalid binaries as following instructions
+	if hasPrefix(dec.text, "hint", "mrs", "msr", "bfc", "orr", "mov") {
+		return true
+	}
+	if strings.HasPrefix(text, "hint") {
+		return true
+	}
+	// GNU objdump recognizes reserved valuse as valid ones
+	if strings.Contains(text, "unknown instruction") && hasPrefix(dec.text, "fmla", "fmul", "fmulx", "fcvtzs", "fcvtzu", "fmls", "fmov", "scvtf", "ucvtf") {
+		return true
+	}
+	// Some old objdump recognizes ldur*/stur*/prfum as ldr*/str*/prfm
+	for k, v := range oldObjdumpMismatch {
+		if strings.HasPrefix(dec.text, k) && strings.Replace(dec.text, k, v, 1) == text {
+			return true
+		}
+	}
+	// GNU objdump misses spaces between operands for some instructions (e.g., "ld1 {v10.2s, v11.2s}, [x23],#16")
+	if strings.Replace(text, " ", "", -1) == strings.Replace(dec.text, " ", "", -1) {
+		return true
+	}
+	return false
+}
+
+// TODO: system instruction.
+var todo = strings.Fields(`
+	sys
+	dc
+	at
+	tlbi
+	ic
+	hvc
+	smc
+`)
+
+// Following instructions can't be covered because they are just aliases to another instructions which are always preferred
+var Ncover = strings.Fields(`
+	sbfm
+	asrv
+	bfm
+	ubfm
+	lslv
+	lsrv
+	rorv
+	ins
+	dup
+`)
+
+// Some old objdump wrongly decodes following instructions and allow their mismatches to avoid false alarm
+var oldObjdumpMismatch = map[string]string{
+	//oldObjValue	correctValue
+	"ldr":   "ldur",
+	"ldrb":  "ldurb",
+	"ldrh":  "ldurh",
+	"ldrsb": "ldursb",
+	"ldrsh": "ldursh",
+	"ldrsw": "ldursw",
+	"str":   "stur",
+	"strb":  "sturb",
+	"strh":  "sturh",
+	"prfm":  "prfum",
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdumpext_test.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdumpext_test.go
new file mode 100644
index 0000000..533ef67
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/objdumpext_test.go
@@ -0,0 +1,299 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Copied and simplified from ../../arm/armasm/objdumpext_test.go.
+
+package arm64asm
+
+import (
+	"bytes"
+	"debug/elf"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+const objdumpPath = "/usr/bin/objdump"
+
+func testObjdumpARM64(t *testing.T, generate func(func([]byte))) {
+	testObjdumpArch(t, generate, ModeARM64)
+}
+
+func testObjdumpArch(t *testing.T, generate func(func([]byte)), arch Mode) {
+	checkObjdumpAarch64(t)
+	testExtDis(t, "gnu", arch, objdump, generate, allowedMismatchObjdump)
+	testExtDis(t, "plan9", arch, objdump, generate, allowedMismatchObjdump)
+}
+
+func checkObjdumpAarch64(t *testing.T) {
+	out, err := exec.Command(objdumpPath, "-i").Output()
+	if err != nil {
+		t.Skipf("cannot run objdump: %v\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "aarch64") {
+		t.Skip("objdump does not have aarch64 support")
+	}
+}
+
+func objdump(ext *ExtDis) error {
+	// File already written with instructions; add ELF header.
+	if ext.Arch == ModeARM64 {
+		if err := writeELF64(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    uint64 = start
+		addr    uint64
+		encbuf  [4]byte
+		enc     []byte
+		text    string
+	)
+	flush := func() {
+		if addr == next {
+			// PC-relative addresses are translated to absolute addresses based on PC by GNU objdump
+			// Following logical rewrites the absolute addresses back to PC-relative ones for comparing
+			// with our disassembler output which are PC-relative
+
+			if m := pcrelprfmim.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+			}
+			if m := pcrelprfm.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+			}
+			if m := pcrelim.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+			}
+			if m := pcrelimzr.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+			}
+			if m := pcrelr.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				if strings.Contains(m[1], "adrp") {
+					text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr&0xfffff000)))
+				} else {
+					text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+				}
+			}
+			if m := pcrelrzr.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				if strings.Contains(m[1], "adrp") {
+					text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr&0xfffff000)))
+				} else {
+					text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+				}
+			}
+			if m := pcrel.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], uint64(targ-uint64(addr)))
+			}
+			if strings.HasPrefix(text, "mov") && strings.Contains(text, "//") {
+				s := strings.Split(text, " //")
+				text = s[0]
+			}
+			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+uint64(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")
+	slashslash    = []byte("//")
+)
+
+func parseLine(line []byte, encstart []byte) (addr uint64, enc []byte, text string) {
+	ok := false
+	oline := line
+	i := index(line, ":\t")
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	x, err := strconv.ParseUint(string(bytes.TrimSpace(line[:i])), 16, 32)
+	if err != nil {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	addr = uint64(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 = bytes.TrimSpace(line[i:])
+	if bytes.Contains(line, undefined) {
+		text = "undefined"
+		return
+	}
+	if false && bytes.Contains(line, unpredictable) {
+		text = "unpredictable"
+		return
+	}
+	// Strip trailing comment starting with ';'
+	//   e.g: "csinv x23, x2, x19, cc ; xxx"
+	if i := bytes.IndexByte(line, ';'); i >= 0 {
+		line = bytes.TrimSpace(line[:i])
+	}
+	// Strip trailing comment starting with "//"
+	//   e.g:  "fccmpe s2, s9, #0x7, ne // xxx"
+	if i := bytes.Index(line, slashslash); i >= 0 {
+		line = bytes.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
+}
+
+// writeELF64 writes an ELF64 header to the file, describing a text
+// segment that starts at start (0x8000) 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_AARCH64),
+		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/vendor/golang.org/x/arch/arm64/arm64asm/plan9x.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/plan9x.go
new file mode 100644
index 0000000..e597276
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/plan9x.go
@@ -0,0 +1,611 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+import (
+	"fmt"
+	"io"
+	"sort"
+	"strings"
+)
+
+// GoSyntax 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 text should read from the text segment using text addresses
+// as offsets; it is used to display pc-relative loads as constant loads.
+func GoSyntax(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 {
+	case LDR, LDRB, LDRH, LDRSB, LDRSH, LDRSW:
+		// Check for PC-relative load.
+		if offset, ok := inst.Args[1].(PCRel); ok {
+			addr := pc + uint64(offset)
+			if _, ok := inst.Args[0].(Reg); !ok {
+				break
+			}
+			if s, base := symname(addr); s != "" && addr == base {
+				args[1] = fmt.Sprintf("$%s(SB)", s)
+			}
+		}
+	}
+
+	// Move addressing mode into opcode suffix.
+	suffix := ""
+	switch inst.Op {
+	case LDR, LDRB, LDRH, LDRSB, LDRSH, LDRSW, STR, STRB, STRH, STUR, STURB, STURH, LD1:
+		switch mem := inst.Args[1].(type) {
+		case MemImmediate:
+			switch mem.Mode {
+			case AddrOffset:
+				// no suffix
+			case AddrPreIndex:
+				suffix = ".W"
+			case AddrPostIndex, AddrPostReg:
+				suffix = ".P"
+			}
+		}
+
+	case STP, LDP:
+		switch mem := inst.Args[2].(type) {
+		case MemImmediate:
+			switch mem.Mode {
+			case AddrOffset:
+				// no suffix
+			case AddrPreIndex:
+				suffix = ".W"
+			case AddrPostIndex:
+				suffix = ".P"
+			}
+		}
+	}
+
+	switch inst.Op {
+	case BL:
+		return "CALL " + args[0]
+
+	case BLR:
+		r := inst.Args[0].(Reg)
+		regno := uint16(r) & 31
+		return fmt.Sprintf("CALL (R%d)", regno)
+
+	case RET:
+		if r, ok := inst.Args[0].(Reg); ok && r == X30 {
+			return "RET"
+		}
+
+	case B:
+		if cond, ok := inst.Args[0].(Cond); ok {
+			return "B" + cond.String() + " " + args[1]
+		}
+		return "JMP" + " " + args[0]
+
+	case BR:
+		r := inst.Args[0].(Reg)
+		regno := uint16(r) & 31
+		return fmt.Sprintf("JMP (R%d)", regno)
+
+	case MOV:
+		rno := -1
+		switch a := inst.Args[0].(type) {
+		case Reg:
+			rno = int(a)
+		case RegSP:
+			rno = int(a)
+		case RegisterWithArrangementAndIndex:
+			op = "VMOV"
+		}
+		if rno >= 0 && rno <= int(WZR) {
+			op = "MOVW"
+		} else if rno >= int(X0) && rno <= int(XZR) {
+			op = "MOVD"
+		}
+		if _, ok := inst.Args[1].(RegisterWithArrangementAndIndex); ok {
+			op = "VMOV"
+		}
+
+	case LDR:
+		var rno uint16
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno = uint16(r)
+		} else {
+			rno = uint16(inst.Args[0].(RegSP))
+		}
+		if rno <= uint16(WZR) {
+			op = "MOVWU" + suffix
+		} else {
+			op = "MOVD" + suffix
+		}
+
+	case LDRB:
+		op = "MOVBU" + suffix
+
+	case LDRH:
+		op = "MOVHU" + suffix
+
+	case LDRSW:
+		op = "MOVW" + suffix
+
+	case LDRSB:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op = "MOVBW" + suffix
+			} else {
+				op = "MOVB" + suffix
+			}
+		}
+	case LDRSH:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op = "MOVHW" + suffix
+			} else {
+				op = "MOVH" + suffix
+			}
+		}
+	case STR, STUR:
+		var rno uint16
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno = uint16(r)
+		} else {
+			rno = uint16(inst.Args[0].(RegSP))
+		}
+		if rno <= uint16(WZR) {
+			op = "MOVW" + suffix
+		} else {
+			op = "MOVD" + suffix
+		}
+		args[0], args[1] = args[1], args[0]
+
+	case STRB, STURB:
+		op = "MOVB" + suffix
+		args[0], args[1] = args[1], args[0]
+
+	case STRH, STURH:
+		op = "MOVH" + suffix
+		args[0], args[1] = args[1], args[0]
+
+	case TBNZ, TBZ:
+		args[0], args[1], args[2] = args[2], args[0], args[1]
+
+	case MADD, MSUB, SMADDL, SMSUBL, UMADDL, UMSUBL:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op += "W"
+			}
+		}
+		args[2], args[3] = args[3], args[2]
+	case STLR:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op += "W"
+			}
+		}
+		args[0], args[1] = args[1], args[0]
+
+	case STLRB, STLRH:
+		args[0], args[1] = args[1], args[0]
+
+	case STLXR, STXR:
+		if r, ok := inst.Args[1].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op += "W"
+			}
+		}
+		args[1], args[2] = args[2], args[1]
+
+	case STLXRB, STLXRH, STXRB, STXRH:
+		args[1], args[2] = args[2], args[1]
+
+	case BFI, BFXIL, SBFIZ, SBFX, UBFIZ, UBFX:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op += "W"
+			}
+		}
+		args[1], args[2], args[3] = args[3], args[1], args[2]
+
+	case STP, LDP:
+		args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
+		args[1] = args[2]
+		if op == "STP" {
+			op = op + suffix
+			return op + " " + args[0] + ", " + args[1]
+		} else if op == "LDP" {
+			op = op + suffix
+			return op + " " + args[1] + ", " + args[0]
+		}
+
+	case FCCMP, FCCMPE:
+		args[0], args[1] = args[1], args[0]
+		fallthrough
+
+	case FCMP, FCMPE:
+		if _, ok := inst.Args[1].(Imm); ok {
+			args[1] = "$(0.0)"
+		}
+		fallthrough
+
+	case FADD, FSUB, FMUL, FNMUL, FDIV, FMAX, FMIN, FMAXNM, FMINNM, FCSEL:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno >= uint16(S0) && rno <= uint16(S31) {
+				op = fmt.Sprintf("%sS", op)
+			} else if rno >= uint16(D0) && rno <= uint16(D31) {
+				op = fmt.Sprintf("%sD", op)
+			}
+		}
+
+	case FCVT:
+		for i := 1; i >= 0; i-- {
+			if r, ok := inst.Args[i].(Reg); ok {
+				rno := uint16(r)
+				if rno >= uint16(H0) && rno <= uint16(H31) {
+					op = fmt.Sprintf("%sH", op)
+				} else if rno >= uint16(S0) && rno <= uint16(S31) {
+					op = fmt.Sprintf("%sS", op)
+				} else if rno >= uint16(D0) && rno <= uint16(D31) {
+					op = fmt.Sprintf("%sD", op)
+				}
+			}
+		}
+
+	case FABS, FNEG, FSQRT, FRINTN, FRINTP, FRINTM, FRINTZ, FRINTA, FRINTX, FRINTI:
+		if r, ok := inst.Args[1].(Reg); ok {
+			rno := uint16(r)
+			if rno >= uint16(S0) && rno <= uint16(S31) {
+				op = fmt.Sprintf("%sS", op)
+			} else if rno >= uint16(D0) && rno <= uint16(D31) {
+				op = fmt.Sprintf("%sD", op)
+			}
+		}
+
+	case FCVTZS, FCVTZU, SCVTF, UCVTF:
+		if _, ok := inst.Args[2].(Imm); !ok {
+			for i := 1; i >= 0; i-- {
+				if r, ok := inst.Args[i].(Reg); ok {
+					rno := uint16(r)
+					if rno >= uint16(S0) && rno <= uint16(S31) {
+						op = fmt.Sprintf("%sS", op)
+					} else if rno >= uint16(D0) && rno <= uint16(D31) {
+						op = fmt.Sprintf("%sD", op)
+					} else if rno <= uint16(WZR) {
+						op += "W"
+					}
+				}
+			}
+		}
+
+	case FMOV:
+		for i := 0; i <= 1; i++ {
+			if r, ok := inst.Args[i].(Reg); ok {
+				rno := uint16(r)
+				if rno >= uint16(S0) && rno <= uint16(S31) {
+					op = fmt.Sprintf("%sS", op)
+					break
+				} else if rno >= uint16(D0) && rno <= uint16(D31) {
+					op = fmt.Sprintf("%sD", op)
+					break
+				}
+			}
+		}
+
+	case SYSL:
+		op1 := int(inst.Args[1].(Imm).Imm)
+		cn := int(inst.Args[2].(Imm_c))
+		cm := int(inst.Args[3].(Imm_c))
+		op2 := int(inst.Args[4].(Imm).Imm)
+		sysregno := int32(op1<<16 | cn<<12 | cm<<8 | op2<<5)
+		args[1] = fmt.Sprintf("$%d", sysregno)
+		return op + " " + args[1] + ", " + args[0]
+
+	case CBNZ, CBZ:
+		if r, ok := inst.Args[0].(Reg); ok {
+			rno := uint16(r)
+			if rno <= uint16(WZR) {
+				op += "W"
+			}
+		}
+		args[0], args[1] = args[1], args[0]
+
+	case ADR, ADRP:
+		addr := int64(inst.Args[1].(PCRel))
+		args[1] = fmt.Sprintf("%d(PC)", addr)
+
+	default:
+		index := sort.SearchStrings(noSuffixOpSet, op)
+		if !(index < len(noSuffixOpSet) && noSuffixOpSet[index] == op) {
+			rno := -1
+			switch a := inst.Args[0].(type) {
+			case Reg:
+				rno = int(a)
+			case RegSP:
+				rno = int(a)
+			case RegisterWithArrangement:
+				op = fmt.Sprintf("V%s", op)
+			}
+
+			if rno >= 0 && rno <= int(WZR) {
+				// Add "w" to opcode suffix.
+				op += "W"
+			}
+		}
+		op = op + suffix
+	}
+
+	// conditional instructions, replace args.
+	if _, ok := inst.Args[3].(Cond); ok {
+		if _, ok := inst.Args[2].(Reg); ok {
+			args[1], args[2] = args[2], args[1]
+		} else {
+			args[0], args[2] = args[2], args[0]
+		}
+	}
+	// 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]
+	}
+
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+
+	return op
+}
+
+// No need add "W" to opcode suffix.
+// Opcode must be inserted in ascending order.
+var noSuffixOpSet = strings.Fields(`
+CRC32B
+CRC32CB
+CRC32CH
+CRC32CW
+CRC32CX
+CRC32H
+CRC32W
+CRC32X
+LDARB
+LDARH
+LDAXRB
+LDAXRH
+LDXRB
+LDXRH
+`)
+
+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
+	switch a := arg.(type) {
+	case Imm:
+		return fmt.Sprintf("$%d", uint32(a.Imm))
+
+	case Imm64:
+		return fmt.Sprintf("$%d", int64(a.Imm))
+
+	case ImmShift:
+		if a.shift == 0 {
+			return fmt.Sprintf("$%d", a.imm)
+		}
+		return fmt.Sprintf("$(%d<<%d)", a.imm, a.shift)
+
+	case PCRel:
+		addr := int64(pc) + int64(a)
+		if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
+			return fmt.Sprintf("%s(SB)", s)
+		}
+		return fmt.Sprintf("%d(PC)", a/4)
+
+	case Reg:
+		regenum := uint16(a)
+		regno := uint16(a) & 31
+
+		if regenum >= uint16(B0) && regenum <= uint16(D31) {
+			// FP registers are the same ones as SIMD registers
+			// Print Fn for scalar variant to align with assembler (e.g., FCVT)
+			return fmt.Sprintf("F%d", regno)
+		} else if regenum >= uint16(Q0) && regenum <= uint16(Q31) {
+			// Print Vn to align with assembler (e.g., SHA256H)
+			return fmt.Sprintf("V%d", regno)
+		}
+
+		if regno == 31 {
+			return "ZR"
+		}
+		return fmt.Sprintf("R%d", regno)
+
+	case RegSP:
+		regno := uint16(a) & 31
+		if regno == 31 {
+			return "RSP"
+		}
+		return fmt.Sprintf("R%d", regno)
+
+	case RegExtshiftAmount:
+		reg := ""
+		regno := uint16(a.reg) & 31
+		if regno == 31 {
+			reg = "ZR"
+		} else {
+			reg = fmt.Sprintf("R%d", uint16(a.reg)&31)
+		}
+		extshift := ""
+		amount := ""
+		if a.extShift != ExtShift(0) {
+			switch a.extShift {
+			default:
+				extshift = "." + a.extShift.String()
+
+			case lsl:
+				extshift = "<<"
+				amount = fmt.Sprintf("%d", a.amount)
+				return reg + extshift + amount
+
+			case lsr:
+				extshift = ">>"
+				amount = fmt.Sprintf("%d", a.amount)
+				return reg + extshift + amount
+
+			case asr:
+				extshift = "->"
+				amount = fmt.Sprintf("%d", a.amount)
+				return reg + extshift + amount
+			case ror:
+				extshift = "@>"
+				amount = fmt.Sprintf("%d", a.amount)
+				return reg + extshift + amount
+			}
+			if a.amount != 0 {
+				amount = fmt.Sprintf("<<%d", a.amount)
+			}
+		}
+		return reg + extshift + amount
+
+	case MemImmediate:
+		off := ""
+		base := ""
+		regno := uint16(a.Base) & 31
+		if regno == 31 {
+			base = "(RSP)"
+		} else {
+			base = fmt.Sprintf("(R%d)", regno)
+		}
+		if a.imm != 0 && a.Mode != AddrPostReg {
+			off = fmt.Sprintf("%d", a.imm)
+		} else if a.Mode == AddrPostReg {
+			postR := fmt.Sprintf("(R%d)", a.imm)
+			return base + postR
+		}
+		return off + base
+
+	case MemExtend:
+		base := ""
+		index := ""
+		extend := ""
+		indexreg := ""
+		regno := uint16(a.Base) & 31
+		if regno == 31 {
+			base = "(RSP)"
+		} else {
+			base = fmt.Sprintf("(R%d)", regno)
+		}
+		regno = uint16(a.Index) & 31
+		if regno == 31 {
+			indexreg = "ZR"
+		} else {
+			indexreg = fmt.Sprintf("R%d", regno)
+		}
+		if a.Extend == lsl {
+			if a.Amount != 0 {
+				extend = fmt.Sprintf("<<%d", a.Amount)
+			}
+		} else {
+			extend = "unimplemented!"
+		}
+		index = indexreg + extend
+		return index + base
+
+	case Cond:
+		switch arg.String() {
+		case "CS":
+			return "HS"
+		case "CC":
+			return "LO"
+		}
+
+	case Imm_clrex:
+		return fmt.Sprintf("$%d", uint32(a))
+
+	case Imm_dcps:
+		return fmt.Sprintf("$%d", uint32(a))
+
+	case Imm_option:
+		return fmt.Sprintf("$%d", uint8(a))
+
+	case Imm_hint:
+		return fmt.Sprintf("$%d", uint8(a))
+
+	case Imm_fp:
+		var s, pre, numerator, denominator int16
+		var result float64
+		if a.s == 0 {
+			s = 1
+		} else {
+			s = -1
+		}
+		pre = s * int16(16+a.pre)
+		if a.exp > 0 {
+			numerator = (pre << uint8(a.exp))
+			denominator = 16
+		} else {
+			numerator = pre
+			denominator = (16 << uint8(-1*a.exp))
+		}
+		result = float64(numerator) / float64(denominator)
+		return strings.TrimRight(fmt.Sprintf("$%f", result), "0")
+
+	case RegisterWithArrangement:
+		result := a.r.String()
+		arrange := a.a.String()
+		c := []rune(arrange)
+		switch len(c) {
+		case 3:
+			c[1], c[2] = c[2], c[1] // .8B -> .B8
+		case 4:
+			c[1], c[2], c[3] = c[3], c[1], c[2] // 16B -> B16
+		}
+		arrange = string(c)
+		result += arrange
+		if a.cnt > 0 {
+			result = "[" + result
+			for i := 1; i < int(a.cnt); i++ {
+				cur := V0 + Reg((uint16(a.r)-uint16(V0)+uint16(i))&31)
+				result += ", " + cur.String() + arrange
+			}
+			result += "]"
+		}
+		return result
+
+	case RegisterWithArrangementAndIndex:
+		result := a.r.String()
+		arrange := a.a.String()
+		result += arrange
+		if a.cnt > 0 {
+			result = "[" + result
+			for i := 1; i < int(a.cnt); i++ {
+				cur := V0 + Reg((uint16(a.r)-uint16(V0)+uint16(i))&31)
+				result += ", " + cur.String() + arrange
+			}
+			result += "]"
+		}
+		return fmt.Sprintf("%s[%d]", result, a.index)
+
+	case Systemreg:
+		return fmt.Sprintf("$%d", uint32(a.op0&1)<<14|uint32(a.op1&7)<<11|uint32(a.cn&15)<<7|uint32(a.cm&15)<<3|uint32(a.op2)&7)
+
+	}
+
+	return strings.ToUpper(arg.String())
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/tables.go
new file mode 100644
index 0000000..ef5237d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/tables.go
@@ -0,0 +1,3366 @@
+// Generated by ARM internal tool
+// DO NOT EDIT
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arm64asm
+
+const (
+	_ Op = iota
+	ABS
+	ADC
+	ADCS
+	ADD
+	ADDHN
+	ADDHN2
+	ADDP
+	ADDS
+	ADDV
+	ADR
+	ADRP
+	AESD
+	AESE
+	AESIMC
+	AESMC
+	AND
+	ANDS
+	ASR
+	ASRV
+	AT
+	B
+	BFI
+	BFM
+	BFXIL
+	BIC
+	BICS
+	BIF
+	BIT
+	BL
+	BLR
+	BR
+	BRK
+	BSL
+	CBNZ
+	CBZ
+	CCMN
+	CCMP
+	CINC
+	CINV
+	CLREX
+	CLS
+	CLZ
+	CMEQ
+	CMGE
+	CMGT
+	CMHI
+	CMHS
+	CMLE
+	CMLT
+	CMN
+	CMP
+	CMTST
+	CNEG
+	CNT
+	CRC32B
+	CRC32CB
+	CRC32CH
+	CRC32CW
+	CRC32CX
+	CRC32H
+	CRC32W
+	CRC32X
+	CSEL
+	CSET
+	CSETM
+	CSINC
+	CSINV
+	CSNEG
+	DC
+	DCPS1
+	DCPS2
+	DCPS3
+	DMB
+	DRPS
+	DSB
+	DUP
+	EON
+	EOR
+	ERET
+	EXT
+	EXTR
+	FABD
+	FABS
+	FACGE
+	FACGT
+	FADD
+	FADDP
+	FCCMP
+	FCCMPE
+	FCMEQ
+	FCMGE
+	FCMGT
+	FCMLE
+	FCMLT
+	FCMP
+	FCMPE
+	FCSEL
+	FCVT
+	FCVTAS
+	FCVTAU
+	FCVTL
+	FCVTL2
+	FCVTMS
+	FCVTMU
+	FCVTN
+	FCVTN2
+	FCVTNS
+	FCVTNU
+	FCVTPS
+	FCVTPU
+	FCVTXN
+	FCVTXN2
+	FCVTZS
+	FCVTZU
+	FDIV
+	FMADD
+	FMAX
+	FMAXNM
+	FMAXNMP
+	FMAXNMV
+	FMAXP
+	FMAXV
+	FMIN
+	FMINNM
+	FMINNMP
+	FMINNMV
+	FMINP
+	FMINV
+	FMLA
+	FMLS
+	FMOV
+	FMSUB
+	FMUL
+	FMULX
+	FNEG
+	FNMADD
+	FNMSUB
+	FNMUL
+	FRECPE
+	FRECPS
+	FRECPX
+	FRINTA
+	FRINTI
+	FRINTM
+	FRINTN
+	FRINTP
+	FRINTX
+	FRINTZ
+	FRSQRTE
+	FRSQRTS
+	FSQRT
+	FSUB
+	HINT
+	HLT
+	HVC
+	IC
+	INS
+	ISB
+	LD1
+	LD1R
+	LD2
+	LD2R
+	LD3
+	LD3R
+	LD4
+	LD4R
+	LDAR
+	LDARB
+	LDARH
+	LDAXP
+	LDAXR
+	LDAXRB
+	LDAXRH
+	LDNP
+	LDP
+	LDPSW
+	LDR
+	LDRB
+	LDRH
+	LDRSB
+	LDRSH
+	LDRSW
+	LDTR
+	LDTRB
+	LDTRH
+	LDTRSB
+	LDTRSH
+	LDTRSW
+	LDUR
+	LDURB
+	LDURH
+	LDURSB
+	LDURSH
+	LDURSW
+	LDXP
+	LDXR
+	LDXRB
+	LDXRH
+	LSL
+	LSLV
+	LSR
+	LSRV
+	MADD
+	MLA
+	MLS
+	MNEG
+	MOV
+	MOVI
+	MOVK
+	MOVN
+	MOVZ
+	MRS
+	MSR
+	MSUB
+	MUL
+	MVN
+	MVNI
+	NEG
+	NEGS
+	NGC
+	NGCS
+	NOP
+	NOT
+	ORN
+	ORR
+	PMUL
+	PMULL
+	PMULL2
+	PRFM
+	PRFUM
+	RADDHN
+	RADDHN2
+	RBIT
+	RET
+	REV
+	REV16
+	REV32
+	REV64
+	ROR
+	RORV
+	RSHRN
+	RSHRN2
+	RSUBHN
+	RSUBHN2
+	SABA
+	SABAL
+	SABAL2
+	SABD
+	SABDL
+	SABDL2
+	SADALP
+	SADDL
+	SADDL2
+	SADDLP
+	SADDLV
+	SADDW
+	SADDW2
+	SBC
+	SBCS
+	SBFIZ
+	SBFM
+	SBFX
+	SCVTF
+	SDIV
+	SEV
+	SEVL
+	SHA1C
+	SHA1H
+	SHA1M
+	SHA1P
+	SHA1SU0
+	SHA1SU1
+	SHA256H
+	SHA256H2
+	SHA256SU0
+	SHA256SU1
+	SHADD
+	SHL
+	SHLL
+	SHLL2
+	SHRN
+	SHRN2
+	SHSUB
+	SLI
+	SMADDL
+	SMAX
+	SMAXP
+	SMAXV
+	SMC
+	SMIN
+	SMINP
+	SMINV
+	SMLAL
+	SMLAL2
+	SMLSL
+	SMLSL2
+	SMNEGL
+	SMOV
+	SMSUBL
+	SMULH
+	SMULL
+	SMULL2
+	SQABS
+	SQADD
+	SQDMLAL
+	SQDMLAL2
+	SQDMLSL
+	SQDMLSL2
+	SQDMULH
+	SQDMULL
+	SQDMULL2
+	SQNEG
+	SQRDMULH
+	SQRSHL
+	SQRSHRN
+	SQRSHRN2
+	SQRSHRUN
+	SQRSHRUN2
+	SQSHL
+	SQSHLU
+	SQSHRN
+	SQSHRN2
+	SQSHRUN
+	SQSHRUN2
+	SQSUB
+	SQXTN
+	SQXTN2
+	SQXTUN
+	SQXTUN2
+	SRHADD
+	SRI
+	SRSHL
+	SRSHR
+	SRSRA
+	SSHL
+	SSHLL
+	SSHLL2
+	SSHR
+	SSRA
+	SSUBL
+	SSUBL2
+	SSUBW
+	SSUBW2
+	ST1
+	ST2
+	ST3
+	ST4
+	STLR
+	STLRB
+	STLRH
+	STLXP
+	STLXR
+	STLXRB
+	STLXRH
+	STNP
+	STP
+	STR
+	STRB
+	STRH
+	STTR
+	STTRB
+	STTRH
+	STUR
+	STURB
+	STURH
+	STXP
+	STXR
+	STXRB
+	STXRH
+	SUB
+	SUBHN
+	SUBHN2
+	SUBS
+	SUQADD
+	SVC
+	SXTB
+	SXTH
+	SXTL
+	SXTL2
+	SXTW
+	SYS
+	SYSL
+	TBL
+	TBNZ
+	TBX
+	TBZ
+	TLBI
+	TRN1
+	TRN2
+	TST
+	UABA
+	UABAL
+	UABAL2
+	UABD
+	UABDL
+	UABDL2
+	UADALP
+	UADDL
+	UADDL2
+	UADDLP
+	UADDLV
+	UADDW
+	UADDW2
+	UBFIZ
+	UBFM
+	UBFX
+	UCVTF
+	UDIV
+	UHADD
+	UHSUB
+	UMADDL
+	UMAX
+	UMAXP
+	UMAXV
+	UMIN
+	UMINP
+	UMINV
+	UMLAL
+	UMLAL2
+	UMLSL
+	UMLSL2
+	UMNEGL
+	UMOV
+	UMSUBL
+	UMULH
+	UMULL
+	UMULL2
+	UQADD
+	UQRSHL
+	UQRSHRN
+	UQRSHRN2
+	UQSHL
+	UQSHRN
+	UQSHRN2
+	UQSUB
+	UQXTN
+	UQXTN2
+	URECPE
+	URHADD
+	URSHL
+	URSHR
+	URSQRTE
+	URSRA
+	USHL
+	USHLL
+	USHLL2
+	USHR
+	USQADD
+	USRA
+	USUBL
+	USUBL2
+	USUBW
+	USUBW2
+	UXTB
+	UXTH
+	UXTL
+	UXTL2
+	UZP1
+	UZP2
+	WFE
+	WFI
+	XTN
+	XTN2
+	YIELD
+	ZIP1
+	ZIP2
+)
+
+var opstr = [...]string{
+	ABS:       "ABS",
+	ADC:       "ADC",
+	ADCS:      "ADCS",
+	ADD:       "ADD",
+	ADDHN:     "ADDHN",
+	ADDHN2:    "ADDHN2",
+	ADDP:      "ADDP",
+	ADDS:      "ADDS",
+	ADDV:      "ADDV",
+	ADR:       "ADR",
+	ADRP:      "ADRP",
+	AESD:      "AESD",
+	AESE:      "AESE",
+	AESIMC:    "AESIMC",
+	AESMC:     "AESMC",
+	AND:       "AND",
+	ANDS:      "ANDS",
+	ASR:       "ASR",
+	ASRV:      "ASRV",
+	AT:        "AT",
+	B:         "B",
+	BFI:       "BFI",
+	BFM:       "BFM",
+	BFXIL:     "BFXIL",
+	BIC:       "BIC",
+	BICS:      "BICS",
+	BIF:       "BIF",
+	BIT:       "BIT",
+	BL:        "BL",
+	BLR:       "BLR",
+	BR:        "BR",
+	BRK:       "BRK",
+	BSL:       "BSL",
+	CBNZ:      "CBNZ",
+	CBZ:       "CBZ",
+	CCMN:      "CCMN",
+	CCMP:      "CCMP",
+	CINC:      "CINC",
+	CINV:      "CINV",
+	CLREX:     "CLREX",
+	CLS:       "CLS",
+	CLZ:       "CLZ",
+	CMEQ:      "CMEQ",
+	CMGE:      "CMGE",
+	CMGT:      "CMGT",
+	CMHI:      "CMHI",
+	CMHS:      "CMHS",
+	CMLE:      "CMLE",
+	CMLT:      "CMLT",
+	CMN:       "CMN",
+	CMP:       "CMP",
+	CMTST:     "CMTST",
+	CNEG:      "CNEG",
+	CNT:       "CNT",
+	CRC32B:    "CRC32B",
+	CRC32CB:   "CRC32CB",
+	CRC32CH:   "CRC32CH",
+	CRC32CW:   "CRC32CW",
+	CRC32CX:   "CRC32CX",
+	CRC32H:    "CRC32H",
+	CRC32W:    "CRC32W",
+	CRC32X:    "CRC32X",
+	CSEL:      "CSEL",
+	CSET:      "CSET",
+	CSETM:     "CSETM",
+	CSINC:     "CSINC",
+	CSINV:     "CSINV",
+	CSNEG:     "CSNEG",
+	DC:        "DC",
+	DCPS1:     "DCPS1",
+	DCPS2:     "DCPS2",
+	DCPS3:     "DCPS3",
+	DMB:       "DMB",
+	DRPS:      "DRPS",
+	DSB:       "DSB",
+	DUP:       "DUP",
+	EON:       "EON",
+	EOR:       "EOR",
+	ERET:      "ERET",
+	EXT:       "EXT",
+	EXTR:      "EXTR",
+	FABD:      "FABD",
+	FABS:      "FABS",
+	FACGE:     "FACGE",
+	FACGT:     "FACGT",
+	FADD:      "FADD",
+	FADDP:     "FADDP",
+	FCCMP:     "FCCMP",
+	FCCMPE:    "FCCMPE",
+	FCMEQ:     "FCMEQ",
+	FCMGE:     "FCMGE",
+	FCMGT:     "FCMGT",
+	FCMLE:     "FCMLE",
+	FCMLT:     "FCMLT",
+	FCMP:      "FCMP",
+	FCMPE:     "FCMPE",
+	FCSEL:     "FCSEL",
+	FCVT:      "FCVT",
+	FCVTAS:    "FCVTAS",
+	FCVTAU:    "FCVTAU",
+	FCVTL:     "FCVTL",
+	FCVTL2:    "FCVTL2",
+	FCVTMS:    "FCVTMS",
+	FCVTMU:    "FCVTMU",
+	FCVTN:     "FCVTN",
+	FCVTN2:    "FCVTN2",
+	FCVTNS:    "FCVTNS",
+	FCVTNU:    "FCVTNU",
+	FCVTPS:    "FCVTPS",
+	FCVTPU:    "FCVTPU",
+	FCVTXN:    "FCVTXN",
+	FCVTXN2:   "FCVTXN2",
+	FCVTZS:    "FCVTZS",
+	FCVTZU:    "FCVTZU",
+	FDIV:      "FDIV",
+	FMADD:     "FMADD",
+	FMAX:      "FMAX",
+	FMAXNM:    "FMAXNM",
+	FMAXNMP:   "FMAXNMP",
+	FMAXNMV:   "FMAXNMV",
+	FMAXP:     "FMAXP",
+	FMAXV:     "FMAXV",
+	FMIN:      "FMIN",
+	FMINNM:    "FMINNM",
+	FMINNMP:   "FMINNMP",
+	FMINNMV:   "FMINNMV",
+	FMINP:     "FMINP",
+	FMINV:     "FMINV",
+	FMLA:      "FMLA",
+	FMLS:      "FMLS",
+	FMOV:      "FMOV",
+	FMSUB:     "FMSUB",
+	FMUL:      "FMUL",
+	FMULX:     "FMULX",
+	FNEG:      "FNEG",
+	FNMADD:    "FNMADD",
+	FNMSUB:    "FNMSUB",
+	FNMUL:     "FNMUL",
+	FRECPE:    "FRECPE",
+	FRECPS:    "FRECPS",
+	FRECPX:    "FRECPX",
+	FRINTA:    "FRINTA",
+	FRINTI:    "FRINTI",
+	FRINTM:    "FRINTM",
+	FRINTN:    "FRINTN",
+	FRINTP:    "FRINTP",
+	FRINTX:    "FRINTX",
+	FRINTZ:    "FRINTZ",
+	FRSQRTE:   "FRSQRTE",
+	FRSQRTS:   "FRSQRTS",
+	FSQRT:     "FSQRT",
+	FSUB:      "FSUB",
+	HINT:      "HINT",
+	HLT:       "HLT",
+	HVC:       "HVC",
+	IC:        "IC",
+	INS:       "INS",
+	ISB:       "ISB",
+	LD1:       "LD1",
+	LD1R:      "LD1R",
+	LD2:       "LD2",
+	LD2R:      "LD2R",
+	LD3:       "LD3",
+	LD3R:      "LD3R",
+	LD4:       "LD4",
+	LD4R:      "LD4R",
+	LDAR:      "LDAR",
+	LDARB:     "LDARB",
+	LDARH:     "LDARH",
+	LDAXP:     "LDAXP",
+	LDAXR:     "LDAXR",
+	LDAXRB:    "LDAXRB",
+	LDAXRH:    "LDAXRH",
+	LDNP:      "LDNP",
+	LDP:       "LDP",
+	LDPSW:     "LDPSW",
+	LDR:       "LDR",
+	LDRB:      "LDRB",
+	LDRH:      "LDRH",
+	LDRSB:     "LDRSB",
+	LDRSH:     "LDRSH",
+	LDRSW:     "LDRSW",
+	LDTR:      "LDTR",
+	LDTRB:     "LDTRB",
+	LDTRH:     "LDTRH",
+	LDTRSB:    "LDTRSB",
+	LDTRSH:    "LDTRSH",
+	LDTRSW:    "LDTRSW",
+	LDUR:      "LDUR",
+	LDURB:     "LDURB",
+	LDURH:     "LDURH",
+	LDURSB:    "LDURSB",
+	LDURSH:    "LDURSH",
+	LDURSW:    "LDURSW",
+	LDXP:      "LDXP",
+	LDXR:      "LDXR",
+	LDXRB:     "LDXRB",
+	LDXRH:     "LDXRH",
+	LSL:       "LSL",
+	LSLV:      "LSLV",
+	LSR:       "LSR",
+	LSRV:      "LSRV",
+	MADD:      "MADD",
+	MLA:       "MLA",
+	MLS:       "MLS",
+	MNEG:      "MNEG",
+	MOV:       "MOV",
+	MOVI:      "MOVI",
+	MOVK:      "MOVK",
+	MOVN:      "MOVN",
+	MOVZ:      "MOVZ",
+	MRS:       "MRS",
+	MSR:       "MSR",
+	MSUB:      "MSUB",
+	MUL:       "MUL",
+	MVN:       "MVN",
+	MVNI:      "MVNI",
+	NEG:       "NEG",
+	NEGS:      "NEGS",
+	NGC:       "NGC",
+	NGCS:      "NGCS",
+	NOP:       "NOP",
+	NOT:       "NOT",
+	ORN:       "ORN",
+	ORR:       "ORR",
+	PMUL:      "PMUL",
+	PMULL:     "PMULL",
+	PMULL2:    "PMULL2",
+	PRFM:      "PRFM",
+	PRFUM:     "PRFUM",
+	RADDHN:    "RADDHN",
+	RADDHN2:   "RADDHN2",
+	RBIT:      "RBIT",
+	RET:       "RET",
+	REV:       "REV",
+	REV16:     "REV16",
+	REV32:     "REV32",
+	REV64:     "REV64",
+	ROR:       "ROR",
+	RORV:      "RORV",
+	RSHRN:     "RSHRN",
+	RSHRN2:    "RSHRN2",
+	RSUBHN:    "RSUBHN",
+	RSUBHN2:   "RSUBHN2",
+	SABA:      "SABA",
+	SABAL:     "SABAL",
+	SABAL2:    "SABAL2",
+	SABD:      "SABD",
+	SABDL:     "SABDL",
+	SABDL2:    "SABDL2",
+	SADALP:    "SADALP",
+	SADDL:     "SADDL",
+	SADDL2:    "SADDL2",
+	SADDLP:    "SADDLP",
+	SADDLV:    "SADDLV",
+	SADDW:     "SADDW",
+	SADDW2:    "SADDW2",
+	SBC:       "SBC",
+	SBCS:      "SBCS",
+	SBFIZ:     "SBFIZ",
+	SBFM:      "SBFM",
+	SBFX:      "SBFX",
+	SCVTF:     "SCVTF",
+	SDIV:      "SDIV",
+	SEV:       "SEV",
+	SEVL:      "SEVL",
+	SHA1C:     "SHA1C",
+	SHA1H:     "SHA1H",
+	SHA1M:     "SHA1M",
+	SHA1P:     "SHA1P",
+	SHA1SU0:   "SHA1SU0",
+	SHA1SU1:   "SHA1SU1",
+	SHA256H:   "SHA256H",
+	SHA256H2:  "SHA256H2",
+	SHA256SU0: "SHA256SU0",
+	SHA256SU1: "SHA256SU1",
+	SHADD:     "SHADD",
+	SHL:       "SHL",
+	SHLL:      "SHLL",
+	SHLL2:     "SHLL2",
+	SHRN:      "SHRN",
+	SHRN2:     "SHRN2",
+	SHSUB:     "SHSUB",
+	SLI:       "SLI",
+	SMADDL:    "SMADDL",
+	SMAX:      "SMAX",
+	SMAXP:     "SMAXP",
+	SMAXV:     "SMAXV",
+	SMC:       "SMC",
+	SMIN:      "SMIN",
+	SMINP:     "SMINP",
+	SMINV:     "SMINV",
+	SMLAL:     "SMLAL",
+	SMLAL2:    "SMLAL2",
+	SMLSL:     "SMLSL",
+	SMLSL2:    "SMLSL2",
+	SMNEGL:    "SMNEGL",
+	SMOV:      "SMOV",
+	SMSUBL:    "SMSUBL",
+	SMULH:     "SMULH",
+	SMULL:     "SMULL",
+	SMULL2:    "SMULL2",
+	SQABS:     "SQABS",
+	SQADD:     "SQADD",
+	SQDMLAL:   "SQDMLAL",
+	SQDMLAL2:  "SQDMLAL2",
+	SQDMLSL:   "SQDMLSL",
+	SQDMLSL2:  "SQDMLSL2",
+	SQDMULH:   "SQDMULH",
+	SQDMULL:   "SQDMULL",
+	SQDMULL2:  "SQDMULL2",
+	SQNEG:     "SQNEG",
+	SQRDMULH:  "SQRDMULH",
+	SQRSHL:    "SQRSHL",
+	SQRSHRN:   "SQRSHRN",
+	SQRSHRN2:  "SQRSHRN2",
+	SQRSHRUN:  "SQRSHRUN",
+	SQRSHRUN2: "SQRSHRUN2",
+	SQSHL:     "SQSHL",
+	SQSHLU:    "SQSHLU",
+	SQSHRN:    "SQSHRN",
+	SQSHRN2:   "SQSHRN2",
+	SQSHRUN:   "SQSHRUN",
+	SQSHRUN2:  "SQSHRUN2",
+	SQSUB:     "SQSUB",
+	SQXTN:     "SQXTN",
+	SQXTN2:    "SQXTN2",
+	SQXTUN:    "SQXTUN",
+	SQXTUN2:   "SQXTUN2",
+	SRHADD:    "SRHADD",
+	SRI:       "SRI",
+	SRSHL:     "SRSHL",
+	SRSHR:     "SRSHR",
+	SRSRA:     "SRSRA",
+	SSHL:      "SSHL",
+	SSHLL:     "SSHLL",
+	SSHLL2:    "SSHLL2",
+	SSHR:      "SSHR",
+	SSRA:      "SSRA",
+	SSUBL:     "SSUBL",
+	SSUBL2:    "SSUBL2",
+	SSUBW:     "SSUBW",
+	SSUBW2:    "SSUBW2",
+	ST1:       "ST1",
+	ST2:       "ST2",
+	ST3:       "ST3",
+	ST4:       "ST4",
+	STLR:      "STLR",
+	STLRB:     "STLRB",
+	STLRH:     "STLRH",
+	STLXP:     "STLXP",
+	STLXR:     "STLXR",
+	STLXRB:    "STLXRB",
+	STLXRH:    "STLXRH",
+	STNP:      "STNP",
+	STP:       "STP",
+	STR:       "STR",
+	STRB:      "STRB",
+	STRH:      "STRH",
+	STTR:      "STTR",
+	STTRB:     "STTRB",
+	STTRH:     "STTRH",
+	STUR:      "STUR",
+	STURB:     "STURB",
+	STURH:     "STURH",
+	STXP:      "STXP",
+	STXR:      "STXR",
+	STXRB:     "STXRB",
+	STXRH:     "STXRH",
+	SUB:       "SUB",
+	SUBHN:     "SUBHN",
+	SUBHN2:    "SUBHN2",
+	SUBS:      "SUBS",
+	SUQADD:    "SUQADD",
+	SVC:       "SVC",
+	SXTB:      "SXTB",
+	SXTH:      "SXTH",
+	SXTL:      "SXTL",
+	SXTL2:     "SXTL2",
+	SXTW:      "SXTW",
+	SYS:       "SYS",
+	SYSL:      "SYSL",
+	TBL:       "TBL",
+	TBNZ:      "TBNZ",
+	TBX:       "TBX",
+	TBZ:       "TBZ",
+	TLBI:      "TLBI",
+	TRN1:      "TRN1",
+	TRN2:      "TRN2",
+	TST:       "TST",
+	UABA:      "UABA",
+	UABAL:     "UABAL",
+	UABAL2:    "UABAL2",
+	UABD:      "UABD",
+	UABDL:     "UABDL",
+	UABDL2:    "UABDL2",
+	UADALP:    "UADALP",
+	UADDL:     "UADDL",
+	UADDL2:    "UADDL2",
+	UADDLP:    "UADDLP",
+	UADDLV:    "UADDLV",
+	UADDW:     "UADDW",
+	UADDW2:    "UADDW2",
+	UBFIZ:     "UBFIZ",
+	UBFM:      "UBFM",
+	UBFX:      "UBFX",
+	UCVTF:     "UCVTF",
+	UDIV:      "UDIV",
+	UHADD:     "UHADD",
+	UHSUB:     "UHSUB",
+	UMADDL:    "UMADDL",
+	UMAX:      "UMAX",
+	UMAXP:     "UMAXP",
+	UMAXV:     "UMAXV",
+	UMIN:      "UMIN",
+	UMINP:     "UMINP",
+	UMINV:     "UMINV",
+	UMLAL:     "UMLAL",
+	UMLAL2:    "UMLAL2",
+	UMLSL:     "UMLSL",
+	UMLSL2:    "UMLSL2",
+	UMNEGL:    "UMNEGL",
+	UMOV:      "UMOV",
+	UMSUBL:    "UMSUBL",
+	UMULH:     "UMULH",
+	UMULL:     "UMULL",
+	UMULL2:    "UMULL2",
+	UQADD:     "UQADD",
+	UQRSHL:    "UQRSHL",
+	UQRSHRN:   "UQRSHRN",
+	UQRSHRN2:  "UQRSHRN2",
+	UQSHL:     "UQSHL",
+	UQSHRN:    "UQSHRN",
+	UQSHRN2:   "UQSHRN2",
+	UQSUB:     "UQSUB",
+	UQXTN:     "UQXTN",
+	UQXTN2:    "UQXTN2",
+	URECPE:    "URECPE",
+	URHADD:    "URHADD",
+	URSHL:     "URSHL",
+	URSHR:     "URSHR",
+	URSQRTE:   "URSQRTE",
+	URSRA:     "URSRA",
+	USHL:      "USHL",
+	USHLL:     "USHLL",
+	USHLL2:    "USHLL2",
+	USHR:      "USHR",
+	USQADD:    "USQADD",
+	USRA:      "USRA",
+	USUBL:     "USUBL",
+	USUBL2:    "USUBL2",
+	USUBW:     "USUBW",
+	USUBW2:    "USUBW2",
+	UXTB:      "UXTB",
+	UXTH:      "UXTH",
+	UXTL:      "UXTL",
+	UXTL2:     "UXTL2",
+	UZP1:      "UZP1",
+	UZP2:      "UZP2",
+	WFE:       "WFE",
+	WFI:       "WFI",
+	XTN:       "XTN",
+	XTN2:      "XTN2",
+	YIELD:     "YIELD",
+	ZIP1:      "ZIP1",
+	ZIP2:      "ZIP2",
+}
+
+var instFormats = [...]instFormat{
+	// ADC <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1a000000, ADC, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// ADC <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9a000000, ADC, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// ADCS <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x3a000000, ADCS, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// ADCS <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0xba000000, ADCS, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe00000, 0x0b200000, ADD, instArgs{arg_Wds, arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// ADD <Xd|SP>, <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe00000, 0x8b200000, ADD, instArgs{arg_Xds, arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// MOV <Wd|WSP>, <Wn|WSP>
+	{0xfffffc00, 0x11000000, MOV, instArgs{arg_Wds, arg_Wns}, mov_add_32_addsub_imm_cond},
+	// ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
+	{0xff000000, 0x11000000, ADD, instArgs{arg_Wds, arg_Wns, arg_IAddSub}, nil},
+	// MOV <Xd|SP>, <Xn|SP>
+	{0xfffffc00, 0x91000000, MOV, instArgs{arg_Xds, arg_Xns}, mov_add_64_addsub_imm_cond},
+	// ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
+	{0xff000000, 0x91000000, ADD, instArgs{arg_Xds, arg_Xns, arg_IAddSub}, nil},
+	// ADD <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x0b000000, ADD, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// ADD <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0x8b000000, ADD, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// CMN <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe0001f, 0x2b20001f, CMN, instArgs{arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe00000, 0x2b200000, ADDS, instArgs{arg_Wd, arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// CMN <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe0001f, 0xab20001f, CMN, instArgs{arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// ADDS <Xd>, <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe00000, 0xab200000, ADDS, instArgs{arg_Xd, arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// CMN <Wn|WSP>, #<imm>{, <shift>}
+	{0xff00001f, 0x3100001f, CMN, instArgs{arg_Wns, arg_IAddSub}, nil},
+	// ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}
+	{0xff000000, 0x31000000, ADDS, instArgs{arg_Wd, arg_Wns, arg_IAddSub}, nil},
+	// CMN <Xn|SP>, #<imm>{, <shift>}
+	{0xff00001f, 0xb100001f, CMN, instArgs{arg_Xns, arg_IAddSub}, nil},
+	// ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}
+	{0xff000000, 0xb1000000, ADDS, instArgs{arg_Xd, arg_Xns, arg_IAddSub}, nil},
+	// CMN <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff20801f, 0x2b00001f, CMN, instArgs{arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// ADDS <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x2b000000, ADDS, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// CMN <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff20001f, 0xab00001f, CMN, instArgs{arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// ADDS <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xab000000, ADDS, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// ADR <Xd>, <label>
+	{0x9f000000, 0x10000000, ADR, instArgs{arg_Xd, arg_slabel_immhi_immlo_0}, nil},
+	// ADRP <Xd>, <label>
+	{0x9f000000, 0x90000000, ADRP, instArgs{arg_Xd, arg_slabel_immhi_immlo_12}, nil},
+	// AND <Wd|WSP>, <Wn>, #<imm>
+	{0xffc00000, 0x12000000, AND, instArgs{arg_Wds, arg_Wn, arg_immediate_bitmask_32_imms_immr}, nil},
+	// AND <Xd|SP>, <Xn>, #<imm>
+	{0xff800000, 0x92000000, AND, instArgs{arg_Xds, arg_Xn, arg_immediate_bitmask_64_N_imms_immr}, nil},
+	// AND <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x0a000000, AND, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// AND <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0x8a000000, AND, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// TST <Wn>, #<imm>
+	{0xffc0001f, 0x7200001f, TST, instArgs{arg_Wn, arg_immediate_bitmask_32_imms_immr}, nil},
+	// ANDS <Wd>, <Wn>, #<imm>
+	{0xffc00000, 0x72000000, ANDS, instArgs{arg_Wd, arg_Wn, arg_immediate_bitmask_32_imms_immr}, nil},
+	// TST <Xn>, #<imm>
+	{0xff80001f, 0xf200001f, TST, instArgs{arg_Xn, arg_immediate_bitmask_64_N_imms_immr}, nil},
+	// ANDS <Xd>, <Xn>, #<imm>
+	{0xff800000, 0xf2000000, ANDS, instArgs{arg_Xd, arg_Xn, arg_immediate_bitmask_64_N_imms_immr}, nil},
+	// TST <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff20801f, 0x6a00001f, TST, instArgs{arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// ANDS <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x6a000000, ANDS, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// TST <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff20001f, 0xea00001f, TST, instArgs{arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// ANDS <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xea000000, ANDS, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// ASR <Wd>, <Wn>, #<shift>
+	{0xffc0fc00, 0x13007c00, ASR, instArgs{arg_Wd, arg_Wn, arg_immediate_ASR_SBFM_32M_bitfield_0_31_immr}, nil},
+	// SBFIZ <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x13000000, SBFIZ, instArgs{arg_Wd, arg_Wn, arg_immediate_SBFIZ_SBFM_32M_bitfield_lsb_32_immr, arg_immediate_SBFIZ_SBFM_32M_bitfield_width_32_imms}, sbfiz_sbfm_32m_bitfield_cond},
+	// SBFX <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x13000000, SBFX, instArgs{arg_Wd, arg_Wn, arg_immediate_SBFX_SBFM_32M_bitfield_lsb_32_immr, arg_immediate_SBFX_SBFM_32M_bitfield_width_32_imms}, sbfx_sbfm_32m_bitfield_cond},
+	// SXTB <Wd>, <Wn>
+	{0xfffffc00, 0x13001c00, SXTB, instArgs{arg_Wd, arg_Wn}, nil},
+	// SXTH <Wd>, <Wn>
+	{0xfffffc00, 0x13003c00, SXTH, instArgs{arg_Wd, arg_Wn}, nil},
+	// SBFM <Wd>, <Wn>, #<immr>, #<imms>
+	{0xffc00000, 0x13000000, SBFM, instArgs{arg_Wd, arg_Wn, arg_immediate_0_31_immr, arg_immediate_0_31_imms}, nil},
+	// ASR <Xd>, <Xn>, #<shift>
+	{0xffc0fc00, 0x9340fc00, ASR, instArgs{arg_Xd, arg_Xn, arg_immediate_ASR_SBFM_64M_bitfield_0_63_immr}, nil},
+	// SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0x93400000, SBFIZ, instArgs{arg_Xd, arg_Xn, arg_immediate_SBFIZ_SBFM_64M_bitfield_lsb_64_immr, arg_immediate_SBFIZ_SBFM_64M_bitfield_width_64_imms}, sbfiz_sbfm_64m_bitfield_cond},
+	// SBFX <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0x93400000, SBFX, instArgs{arg_Xd, arg_Xn, arg_immediate_SBFX_SBFM_64M_bitfield_lsb_64_immr, arg_immediate_SBFX_SBFM_64M_bitfield_width_64_imms}, sbfx_sbfm_64m_bitfield_cond},
+	// SXTB <Xd>, <Wn>
+	{0xfffffc00, 0x93401c00, SXTB, instArgs{arg_Xd, arg_Wn}, nil},
+	// SXTH <Xd>, <Wn>
+	{0xfffffc00, 0x93403c00, SXTH, instArgs{arg_Xd, arg_Wn}, nil},
+	// SXTW <Xd>, <Wn>
+	{0xfffffc00, 0x93407c00, SXTW, instArgs{arg_Xd, arg_Wn}, nil},
+	// SBFM <Xd>, <Xn>, #<immr>, #<imms>
+	{0xffc00000, 0x93400000, SBFM, instArgs{arg_Xd, arg_Xn, arg_immediate_0_63_immr, arg_immediate_0_63_imms}, nil},
+	// ASR <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02800, ASR, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// ASRV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02800, ASRV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// ASR <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02800, ASR, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// ASRV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02800, ASRV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// AT <at>, <Xt>
+	{0xfff8ff00, 0xd5087800, AT, instArgs{arg_sysop_AT_SYS_CR_system}, at_sys_cr_system_cond},
+	// DC <dc>, <Xt>
+	{0xfff8f000, 0xd5087000, DC, instArgs{arg_sysop_DC_SYS_CR_system}, dc_sys_cr_system_cond},
+	// IC <ic>, {<Xt>}
+	{0xfff8f000, 0xd5087000, IC, instArgs{arg_sysop_IC_SYS_CR_system}, ic_sys_cr_system_cond},
+	// TLBI <tlbi>, {<Xt>}
+	{0xfff8f000, 0xd5088000, TLBI, instArgs{arg_sysop_TLBI_SYS_CR_system}, tlbi_sys_cr_system_cond},
+	// SYS #<op1>, <Cn>, <Cm>, <op>, {<Xt>}
+	{0xfff80000, 0xd5080000, SYS, instArgs{arg_immediate_0_7_op1, arg_Cn, arg_Cm, arg_sysop_SYS_CR_system}, nil},
+	// B <label>
+	{0xfc000000, 0x14000000, B, instArgs{arg_slabel_imm26_2}, nil},
+	// B<c> <label>
+	{0xff000010, 0x54000000, B, instArgs{arg_conditional, arg_slabel_imm19_2}, nil},
+	// BFI <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x33000000, BFI, instArgs{arg_Wd, arg_Wn, arg_immediate_BFI_BFM_32M_bitfield_lsb_32_immr, arg_immediate_BFI_BFM_32M_bitfield_width_32_imms}, bfi_bfm_32m_bitfield_cond},
+	// BFXIL <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x33000000, BFXIL, instArgs{arg_Wd, arg_Wn, arg_immediate_BFXIL_BFM_32M_bitfield_lsb_32_immr, arg_immediate_BFXIL_BFM_32M_bitfield_width_32_imms}, bfxil_bfm_32m_bitfield_cond},
+	// BFM <Wd>, <Wn>, #<immr>, #<imms>
+	{0xffc00000, 0x33000000, BFM, instArgs{arg_Wd, arg_Wn, arg_immediate_0_31_immr, arg_immediate_0_31_imms}, nil},
+	// BFI <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0xb3400000, BFI, instArgs{arg_Xd, arg_Xn, arg_immediate_BFI_BFM_64M_bitfield_lsb_64_immr, arg_immediate_BFI_BFM_64M_bitfield_width_64_imms}, bfi_bfm_64m_bitfield_cond},
+	// BFXIL <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0xb3400000, BFXIL, instArgs{arg_Xd, arg_Xn, arg_immediate_BFXIL_BFM_64M_bitfield_lsb_64_immr, arg_immediate_BFXIL_BFM_64M_bitfield_width_64_imms}, bfxil_bfm_64m_bitfield_cond},
+	// BFM <Xd>, <Xn>, #<immr>, #<imms>
+	{0xffc00000, 0xb3400000, BFM, instArgs{arg_Xd, arg_Xn, arg_immediate_0_63_immr, arg_immediate_0_63_imms}, nil},
+	// BIC <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x0a200000, BIC, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// BIC <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0x8a200000, BIC, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// BICS <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x6a200000, BICS, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// BICS <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xea200000, BICS, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// BL <label>
+	{0xfc000000, 0x94000000, BL, instArgs{arg_slabel_imm26_2}, nil},
+	// BLR <Xn>
+	{0xfffffc1f, 0xd63f0000, BLR, instArgs{arg_Xn}, nil},
+	// BR <Xn>
+	{0xfffffc1f, 0xd61f0000, BR, instArgs{arg_Xn}, nil},
+	// BRK #<imm>
+	{0xffe0001f, 0xd4200000, BRK, instArgs{arg_immediate_0_65535_imm16}, nil},
+	// CBNZ <Wt>, <label>
+	{0xff000000, 0x35000000, CBNZ, instArgs{arg_Wt, arg_slabel_imm19_2}, nil},
+	// CBNZ <Xt>, <label>
+	{0xff000000, 0xb5000000, CBNZ, instArgs{arg_Xt, arg_slabel_imm19_2}, nil},
+	// CBZ <Wt>, <label>
+	{0xff000000, 0x34000000, CBZ, instArgs{arg_Wt, arg_slabel_imm19_2}, nil},
+	// CBZ <Xt>, <label>
+	{0xff000000, 0xb4000000, CBZ, instArgs{arg_Xt, arg_slabel_imm19_2}, nil},
+	// CCMN <Wn>, #<imm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x3a400800, CCMN, instArgs{arg_Wn, arg_immediate_0_31_imm5, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMN <Xn>, #<imm>, #<nzcv>, <cond>
+	{0xffe00c10, 0xba400800, CCMN, instArgs{arg_Xn, arg_immediate_0_31_imm5, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMN <Wn>, <Wm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x3a400000, CCMN, instArgs{arg_Wn, arg_Wm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMN <Xn>, <Xm>, #<nzcv>, <cond>
+	{0xffe00c10, 0xba400000, CCMN, instArgs{arg_Xn, arg_Xm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMP <Wn>, #<imm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x7a400800, CCMP, instArgs{arg_Wn, arg_immediate_0_31_imm5, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMP <Xn>, #<imm>, #<nzcv>, <cond>
+	{0xffe00c10, 0xfa400800, CCMP, instArgs{arg_Xn, arg_immediate_0_31_imm5, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMP <Wn>, <Wm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x7a400000, CCMP, instArgs{arg_Wn, arg_Wm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CCMP <Xn>, <Xm>, #<nzcv>, <cond>
+	{0xffe00c10, 0xfa400000, CCMP, instArgs{arg_Xn, arg_Xm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// CINC <Wd>, <Wn>, <cond>
+	{0xffe00c00, 0x1a800400, CINC, instArgs{arg_Wd, arg_Wn, arg_cond_NotAllowALNV_Invert}, cinc_csinc_32_condsel_cond},
+	// CSET <Wd>, <cond>
+	{0xffff0fe0, 0x1a9f07e0, CSET, instArgs{arg_Wd, arg_cond_NotAllowALNV_Invert}, csinc_general_cond},
+	// CSINC <Wd>, <Wn>, <Wm>, <cond>
+	{0xffe00c00, 0x1a800400, CSINC, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_cond_AllowALNV_Normal}, nil},
+	// CINC <Xd>, <Xn>, <cond>
+	{0xffe00c00, 0x9a800400, CINC, instArgs{arg_Xd, arg_Xn, arg_cond_NotAllowALNV_Invert}, cinc_csinc_64_condsel_cond},
+	// CSET <Xd>, <cond>
+	{0xffff0fe0, 0x9a9f07e0, CSET, instArgs{arg_Xd, arg_cond_NotAllowALNV_Invert}, csinc_general_cond},
+	// CSINC <Xd>, <Xn>, <Xm>, <cond>
+	{0xffe00c00, 0x9a800400, CSINC, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_cond_AllowALNV_Normal}, nil},
+	// CINV <Wd>, <Wn>, <cond>
+	{0xffe00c00, 0x5a800000, CINV, instArgs{arg_Wd, arg_Wn, arg_cond_NotAllowALNV_Invert}, cinv_csinv_32_condsel_cond},
+	// CSETM <Wd>, <cond>
+	{0xffff0fe0, 0x5a9f03e0, CSETM, instArgs{arg_Wd, arg_cond_NotAllowALNV_Invert}, csinv_general_cond},
+	// CSINV <Wd>, <Wn>, <Wm>, <cond>
+	{0xffe00c00, 0x5a800000, CSINV, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_cond_AllowALNV_Normal}, nil},
+	// CINV <Xd>, <Xn>, <cond>
+	{0xffe00c00, 0xda800000, CINV, instArgs{arg_Xd, arg_Xn, arg_cond_NotAllowALNV_Invert}, cinv_csinv_64_condsel_cond},
+	// CSETM <Xd>, <cond>
+	{0xffff0fe0, 0xda9f03e0, CSETM, instArgs{arg_Xd, arg_cond_NotAllowALNV_Invert}, csinv_general_cond},
+	// CSINV <Xd>, <Xn>, <Xm>, <cond>
+	{0xffe00c00, 0xda800000, CSINV, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_cond_AllowALNV_Normal}, nil},
+	// CLREX {#<imm>}
+	{0xfffff0ff, 0xd503305f, CLREX, instArgs{arg_immediate_optional_0_15_CRm}, nil},
+	// CLS <Wd>, <Wn>
+	{0xfffffc00, 0x5ac01400, CLS, instArgs{arg_Wd, arg_Wn}, nil},
+	// CLS <Xd>, <Xn>
+	{0xfffffc00, 0xdac01400, CLS, instArgs{arg_Xd, arg_Xn}, nil},
+	// CLZ <Wd>, <Wn>
+	{0xfffffc00, 0x5ac01000, CLZ, instArgs{arg_Wd, arg_Wn}, nil},
+	// CLZ <Xd>, <Xn>
+	{0xfffffc00, 0xdac01000, CLZ, instArgs{arg_Xd, arg_Xn}, nil},
+	// CMP <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe0001f, 0x6b20001f, CMP, instArgs{arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe00000, 0x6b200000, SUBS, instArgs{arg_Wd, arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// CMP <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe0001f, 0xeb20001f, CMP, instArgs{arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// SUBS <Xd>, <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe00000, 0xeb200000, SUBS, instArgs{arg_Xd, arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// CMP <Wn|WSP>, #<imm>{, <shift>}
+	{0xff00001f, 0x7100001f, CMP, instArgs{arg_Wns, arg_IAddSub}, nil},
+	// SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}
+	{0xff000000, 0x71000000, SUBS, instArgs{arg_Wd, arg_Wns, arg_IAddSub}, nil},
+	// CMP <Xn|SP>, #<imm>{, <shift>}
+	{0xff00001f, 0xf100001f, CMP, instArgs{arg_Xns, arg_IAddSub}, nil},
+	// SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}
+	{0xff000000, 0xf1000000, SUBS, instArgs{arg_Xd, arg_Xns, arg_IAddSub}, nil},
+	// CMP <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff20801f, 0x6b00001f, CMP, instArgs{arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// NEGS <Wd>, <Wm> {, <shift> #<amount> }
+	{0xff2003e0, 0x6b0003e0, NEGS, instArgs{arg_Wd, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// SUBS <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x6b000000, SUBS, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// CMP <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff20001f, 0xeb00001f, CMP, instArgs{arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// NEGS <Xd>, <Xm> {, <shift> #<amount> }
+	{0xff2003e0, 0xeb0003e0, NEGS, instArgs{arg_Xd, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xeb000000, SUBS, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// CNEG <Wd>, <Wn>, <cond>
+	{0xffe00c00, 0x5a800400, CNEG, instArgs{arg_Wd, arg_Wn, arg_cond_NotAllowALNV_Invert}, cneg_csneg_32_condsel_cond},
+	// CSNEG <Wd>, <Wn>, <Wm>, <cond>
+	{0xffe00c00, 0x5a800400, CSNEG, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_cond_AllowALNV_Normal}, nil},
+	// CNEG <Xd>, <Xn>, <cond>
+	{0xffe00c00, 0xda800400, CNEG, instArgs{arg_Xd, arg_Xn, arg_cond_NotAllowALNV_Invert}, cneg_csneg_64_condsel_cond},
+	// CSNEG <Xd>, <Xn>, <Xm>, <cond>
+	{0xffe00c00, 0xda800400, CSNEG, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_cond_AllowALNV_Normal}, nil},
+	// CRC32B <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac04000, CRC32B, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32H <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac04400, CRC32H, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32W <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac04800, CRC32W, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32X <Wd>, <Wn>, <Xm>
+	{0xffe0fc00, 0x9ac04c00, CRC32X, instArgs{arg_Wd, arg_Wn, arg_Xm}, nil},
+	// CRC32CB <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac05000, CRC32CB, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32CH <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac05400, CRC32CH, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32CW <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac05800, CRC32CW, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// CRC32CX <Wd>, <Wn>, <Xm>
+	{0xffe0fc00, 0x9ac05c00, CRC32CX, instArgs{arg_Wd, arg_Wn, arg_Xm}, nil},
+	// CSEL <Wd>, <Wn>, <Wm>, <cond>
+	{0xffe00c00, 0x1a800000, CSEL, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_cond_AllowALNV_Normal}, nil},
+	// CSEL <Xd>, <Xn>, <Xm>, <cond>
+	{0xffe00c00, 0x9a800000, CSEL, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_cond_AllowALNV_Normal}, nil},
+	// DCPS1 {#<imm>}
+	{0xffe0001f, 0xd4a00001, DCPS1, instArgs{arg_immediate_optional_0_65535_imm16}, nil},
+	// DCPS2 {#<imm>}
+	{0xffe0001f, 0xd4a00002, DCPS2, instArgs{arg_immediate_optional_0_65535_imm16}, nil},
+	// DCPS3 {#<imm>}
+	{0xffe0001f, 0xd4a00003, DCPS3, instArgs{arg_immediate_optional_0_65535_imm16}, nil},
+	// DMB <option>|<imm>
+	{0xfffff0ff, 0xd50330bf, DMB, instArgs{arg_option_DMB_BO_system_CRm}, nil},
+	// DRPS
+	{0xffffffff, 0xd6bf03e0, DRPS, instArgs{}, nil},
+	// DSB <option>|<imm>
+	{0xfffff0ff, 0xd503309f, DSB, instArgs{arg_option_DSB_BO_system_CRm}, nil},
+	// EON <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x4a200000, EON, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// EON <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xca200000, EON, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// EOR <Wd|WSP>, <Wn>, #<imm>
+	{0xffc00000, 0x52000000, EOR, instArgs{arg_Wds, arg_Wn, arg_immediate_bitmask_32_imms_immr}, nil},
+	// EOR <Xd|SP>, <Xn>, #<imm>
+	{0xff800000, 0xd2000000, EOR, instArgs{arg_Xds, arg_Xn, arg_immediate_bitmask_64_N_imms_immr}, nil},
+	// EOR <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x4a000000, EOR, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// EOR <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xca000000, EOR, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// ERET
+	{0xffffffff, 0xd69f03e0, ERET, instArgs{}, nil},
+	// ROR <Wd>, <Ws>, #<shift>
+	{0xffe08000, 0x13800000, ROR, instArgs{arg_Wd, arg_Ws, arg_immediate_0_31_imms}, ror_extr_32_extract_cond},
+	// EXTR <Wd>, <Wn>, <Wm>, #<lsb>
+	{0xffe08000, 0x13800000, EXTR, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_immediate_0_31_imms}, nil},
+	// ROR <Xd>, <Xs>, #<shift>
+	{0xffe00000, 0x93c00000, ROR, instArgs{arg_Xd, arg_Xs, arg_immediate_0_63_imms}, ror_extr_64_extract_cond},
+	// EXTR <Xd>, <Xn>, <Xm>, #<lsb>
+	{0xffe00000, 0x93c00000, EXTR, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_immediate_0_63_imms}, nil},
+	// NOP
+	{0xffffffff, 0xd503201f, NOP, instArgs{}, nil},
+	// SEV
+	{0xffffffff, 0xd503209f, SEV, instArgs{}, nil},
+	// SEVL
+	{0xffffffff, 0xd50320bf, SEVL, instArgs{}, nil},
+	// WFE
+	{0xffffffff, 0xd503205f, WFE, instArgs{}, nil},
+	// WFI
+	{0xffffffff, 0xd503207f, WFI, instArgs{}, nil},
+	// YIELD
+	{0xffffffff, 0xd503203f, YIELD, instArgs{}, nil},
+	// HINT #<imm>
+	{0xfffff01f, 0xd503201f, HINT, instArgs{arg_immediate_0_127_CRm_op2}, nil},
+	// HLT #<imm>
+	{0xffe0001f, 0xd4400000, HLT, instArgs{arg_immediate_0_65535_imm16}, nil},
+	// ISB {<option>|<imm>}
+	{0xfffff0ff, 0xd50330df, ISB, instArgs{arg_option_ISB_BI_system_CRm}, nil},
+	// LDAR <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88c08000, LDAR, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDAR <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8c08000, LDAR, instArgs{arg_Xt, arg_Xns_mem}, nil},
+	// LDARB <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08c08000, LDARB, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDARH <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48c08000, LDARH, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDAXP <Wt>, <Wt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88608000, LDAXP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem}, nil},
+	// LDAXP <Xt>, <Xt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8608000, LDAXP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem}, nil},
+	// LDAXR <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88408000, LDAXR, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDAXR <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8408000, LDAXR, instArgs{arg_Xt, arg_Xns_mem}, nil},
+	// LDAXRB <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08408000, LDAXRB, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDAXRH <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48408000, LDAXRH, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDNP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x28400000, LDNP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// LDNP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_1>}]
+	{0xffc00000, 0xa8400000, LDNP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// LDP <Wt>, <Wt2>, [<Xn|SP>], #<imm_1>
+	{0xffc00000, 0x28c00000, LDP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_post_imm7_4_signed}, nil},
+	// LDP <Xt>, <Xt2>, [<Xn|SP>], #<imm_3>
+	{0xffc00000, 0xa8c00000, LDP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_post_imm7_8_signed}, nil},
+	// LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm_1>}]!
+	{0xffc00000, 0x29c00000, LDP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_wb_imm7_4_signed}, nil},
+	// LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_3>}]!
+	{0xffc00000, 0xa9c00000, LDP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_wb_imm7_8_signed}, nil},
+	// LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x29400000, LDP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0xa9400000, LDP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// LDPSW <Xt>, <Xt2>, [<Xn|SP>], #<imm_1>
+	{0xffc00000, 0x68c00000, LDPSW, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_post_imm7_4_signed}, nil},
+	// LDPSW <Xt>, <Xt2>, [<Xn|SP>{, #<imm_1>}]!
+	{0xffc00000, 0x69c00000, LDPSW, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_wb_imm7_4_signed}, nil},
+	// LDPSW <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x69400000, LDPSW, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// LDR <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xb8400400, LDR, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Xt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xf8400400, LDR, instArgs{arg_Xt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xb8400c00, LDR, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Xt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xf8400c00, LDR, instArgs{arg_Xt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0xb9400000, LDR, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_4_unsigned}, nil},
+	// LDR <Xt>, [<Xn|SP>{, #<pimm_1>}]
+	{0xffc00000, 0xf9400000, LDR, instArgs{arg_Xt, arg_Xns_mem_optional_imm12_8_unsigned}, nil},
+	// LDR <Wt>, <label>
+	{0xff000000, 0x18000000, LDR, instArgs{arg_Wt, arg_slabel_imm19_2}, nil},
+	// LDR <Xt>, <label>
+	{0xff000000, 0x58000000, LDR, instArgs{arg_Xt, arg_slabel_imm19_2}, nil},
+	// LDR <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xb8600800, LDR, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1}, nil},
+	// LDR <Xt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xf8600800, LDR, instArgs{arg_Xt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1}, nil},
+	// LDRB <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x38400400, LDRB, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRB <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x38400c00, LDRB, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRB <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x39400000, LDRB, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// LDRB <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x38600800, LDRB, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// LDRH <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x78400400, LDRH, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRH <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x78400c00, LDRH, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRH <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x79400000, LDRH, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// LDRH <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x78600800, LDRH, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// LDRSB <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x38c00400, LDRSB, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRSB <Xt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x38800400, LDRSB, instArgs{arg_Xt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRSB <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x38c00c00, LDRSB, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRSB <Xt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x38800c00, LDRSB, instArgs{arg_Xt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRSB <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x39c00000, LDRSB, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// LDRSB <Xt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x39800000, LDRSB, instArgs{arg_Xt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// LDRSB <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x38e00800, LDRSB, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// LDRSB <Xt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x38a00800, LDRSB, instArgs{arg_Xt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// LDRSH <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x78c00400, LDRSH, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRSH <Xt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x78800400, LDRSH, instArgs{arg_Xt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRSH <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x78c00c00, LDRSH, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRSH <Xt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x78800c00, LDRSH, instArgs{arg_Xt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRSH <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x79c00000, LDRSH, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// LDRSH <Xt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x79800000, LDRSH, instArgs{arg_Xt, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// LDRSH <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x78e00800, LDRSH, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// LDRSH <Xt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x78a00800, LDRSH, instArgs{arg_Xt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// LDRSW <Xt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xb8800400, LDRSW, instArgs{arg_Xt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDRSW <Xt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xb8800c00, LDRSW, instArgs{arg_Xt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0xb9800000, LDRSW, instArgs{arg_Xt, arg_Xns_mem_optional_imm12_4_unsigned}, nil},
+	// LDRSW <Xt>, <label>
+	{0xff000000, 0x98000000, LDRSW, instArgs{arg_Xt, arg_slabel_imm19_2}, nil},
+	// LDRSW <Xt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xb8a00800, LDRSW, instArgs{arg_Xt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1}, nil},
+	// LDTR <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8400800, LDTR, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTR <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xf8400800, LDTR, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38400800, LDTRB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78400800, LDTRH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRSB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38c00800, LDTRSB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRSB <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38800800, LDTRSB, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRSH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78c00800, LDTRSH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRSH <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78800800, LDTRSH, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDTRSW <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8800800, LDTRSW, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8400000, LDUR, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xf8400000, LDUR, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38400000, LDURB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78400000, LDURH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURSB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38c00000, LDURSB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURSB <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38800000, LDURSB, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURSH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78c00000, LDURSH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURSH <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78800000, LDURSH, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDURSW <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8800000, LDURSW, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDXP <Wt>, <Wt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88600000, LDXP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem}, nil},
+	// LDXP <Xt>, <Xt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8600000, LDXP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem}, nil},
+	// LDXR <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88400000, LDXR, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDXR <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8400000, LDXR, instArgs{arg_Xt, arg_Xns_mem}, nil},
+	// LDXRB <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08400000, LDXRB, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LDXRH <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48400000, LDXRH, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// LSL <Wd>, <Wn>, #<shift>
+	{0xffc08000, 0x53000000, LSL, instArgs{arg_Wd, arg_Wn, arg_immediate_LSL_UBFM_32M_bitfield_0_31_immr}, lsl_ubfm_32m_bitfield_cond},
+	// LSR <Wd>, <Wn>, #<shift>
+	{0xffc0fc00, 0x53007c00, LSR, instArgs{arg_Wd, arg_Wn, arg_immediate_LSR_UBFM_32M_bitfield_0_31_immr}, nil},
+	// UBFIZ <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x53000000, UBFIZ, instArgs{arg_Wd, arg_Wn, arg_immediate_UBFIZ_UBFM_32M_bitfield_lsb_32_immr, arg_immediate_UBFIZ_UBFM_32M_bitfield_width_32_imms}, ubfiz_ubfm_32m_bitfield_cond},
+	// UBFX <Wd>, <Wn>, #<lsb>, #<width>
+	{0xffc00000, 0x53000000, UBFX, instArgs{arg_Wd, arg_Wn, arg_immediate_UBFX_UBFM_32M_bitfield_lsb_32_immr, arg_immediate_UBFX_UBFM_32M_bitfield_width_32_imms}, ubfx_ubfm_32m_bitfield_cond},
+	// UXTB <Wd>, <Wn>
+	{0xfffffc00, 0x53001c00, UXTB, instArgs{arg_Wd, arg_Wn}, nil},
+	// UXTH <Wd>, <Wn>
+	{0xfffffc00, 0x53003c00, UXTH, instArgs{arg_Wd, arg_Wn}, nil},
+	// UBFM <Wd>, <Wn>, #<immr>, #<imms>
+	{0xffc00000, 0x53000000, UBFM, instArgs{arg_Wd, arg_Wn, arg_immediate_0_31_immr, arg_immediate_0_31_imms}, nil},
+	// LSL <Xd>, <Xn>, #<shift>
+	{0xffc00000, 0xd3400000, LSL, instArgs{arg_Xd, arg_Xn, arg_immediate_LSL_UBFM_64M_bitfield_0_63_immr}, lsl_ubfm_64m_bitfield_cond},
+	// LSR <Xd>, <Xn>, #<shift>
+	{0xffc0fc00, 0xd340fc00, LSR, instArgs{arg_Xd, arg_Xn, arg_immediate_LSR_UBFM_64M_bitfield_0_63_immr}, nil},
+	// UBFIZ <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0xd3400000, UBFIZ, instArgs{arg_Xd, arg_Xn, arg_immediate_UBFIZ_UBFM_64M_bitfield_lsb_64_immr, arg_immediate_UBFIZ_UBFM_64M_bitfield_width_64_imms}, ubfiz_ubfm_64m_bitfield_cond},
+	// UBFX <Xd>, <Xn>, #<lsb>, #<width>
+	{0xffc00000, 0xd3400000, UBFX, instArgs{arg_Xd, arg_Xn, arg_immediate_UBFX_UBFM_64M_bitfield_lsb_64_immr, arg_immediate_UBFX_UBFM_64M_bitfield_width_64_imms}, ubfx_ubfm_64m_bitfield_cond},
+	// UBFM <Xd>, <Xn>, #<immr>, #<imms>
+	{0xffc00000, 0xd3400000, UBFM, instArgs{arg_Xd, arg_Xn, arg_immediate_0_63_immr, arg_immediate_0_63_imms}, nil},
+	// LSL <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02000, LSL, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// LSLV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02000, LSLV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// LSL <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02000, LSL, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// LSLV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02000, LSLV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// LSR <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02400, LSR, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// LSRV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02400, LSRV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// LSR <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02400, LSR, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// LSRV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02400, LSRV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// MUL <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1b007c00, MUL, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// MADD <Wd>, <Wn>, <Wm>, <Wa>
+	{0xffe08000, 0x1b000000, MADD, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_Wa}, nil},
+	// MUL <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9b007c00, MUL, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// MADD <Xd>, <Xn>, <Xm>, <Xa>
+	{0xffe08000, 0x9b000000, MADD, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_Xa}, nil},
+	// MNEG <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1b00fc00, MNEG, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// MSUB <Wd>, <Wn>, <Wm>, <Wa>
+	{0xffe08000, 0x1b008000, MSUB, instArgs{arg_Wd, arg_Wn, arg_Wm, arg_Wa}, nil},
+	// MNEG <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9b00fc00, MNEG, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// MSUB <Xd>, <Xn>, <Xm>, <Xa>
+	{0xffe08000, 0x9b008000, MSUB, instArgs{arg_Xd, arg_Xn, arg_Xm, arg_Xa}, nil},
+	// MOV <Wd|WSP>, #<imm>
+	{0xffc003e0, 0x320003e0, MOV, instArgs{arg_Wds, arg_immediate_bitmask_32_imms_immr}, mov_orr_32_log_imm_cond},
+	// ORR <Wd|WSP>, <Wn>, #<imm>
+	{0xffc00000, 0x32000000, ORR, instArgs{arg_Wds, arg_Wn, arg_immediate_bitmask_32_imms_immr}, nil},
+	// MOV <Xd|SP>, #<imm>
+	{0xff8003e0, 0xb20003e0, MOV, instArgs{arg_Xds, arg_immediate_bitmask_64_N_imms_immr}, mov_orr_64_log_imm_cond},
+	// ORR <Xd|SP>, <Xn>, #<imm>
+	{0xff800000, 0xb2000000, ORR, instArgs{arg_Xds, arg_Xn, arg_immediate_bitmask_64_N_imms_immr}, nil},
+	// MOV <Wd>, #<imm>
+	{0xff800000, 0x12800000, MOV, instArgs{arg_Wd, arg_immediate_shift_32_implicit_inverse_imm16_hw}, mov_movn_32_movewide_cond},
+	// MOVN <Wd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0x12800000, MOVN, instArgs{arg_Wd, arg_immediate_OptLSL_amount_16_0_16}, nil},
+	// MOV <Xd>, #<imm>
+	{0xff800000, 0x92800000, MOV, instArgs{arg_Xd, arg_immediate_shift_64_implicit_inverse_imm16_hw}, mov_movn_64_movewide_cond},
+	// MOVN <Xd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0x92800000, MOVN, instArgs{arg_Xd, arg_immediate_OptLSL_amount_16_0_48}, nil},
+	// MOV <Wd>, <Wm>
+	{0xffe0ffe0, 0x2a0003e0, MOV, instArgs{arg_Wd, arg_Wm}, nil},
+	// ORR <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x2a000000, ORR, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// MOV <Xd>, <Xm>
+	{0xffe0ffe0, 0xaa0003e0, MOV, instArgs{arg_Xd, arg_Xm}, nil},
+	// ORR <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xaa000000, ORR, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// MOV <Wd>, #<imm>
+	{0xff800000, 0x52800000, MOV, instArgs{arg_Wd, arg_immediate_shift_32_implicit_imm16_hw}, mov_movz_32_movewide_cond},
+	// MOVZ <Wd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0x52800000, MOVZ, instArgs{arg_Wd, arg_immediate_OptLSL_amount_16_0_16}, nil},
+	// MOV <Xd>, #<imm>
+	{0xff800000, 0xd2800000, MOV, instArgs{arg_Xd, arg_immediate_shift_64_implicit_imm16_hw}, mov_movz_64_movewide_cond},
+	// MOVZ <Xd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0xd2800000, MOVZ, instArgs{arg_Xd, arg_immediate_OptLSL_amount_16_0_48}, nil},
+	// MOVK <Wd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0x72800000, MOVK, instArgs{arg_Wd, arg_immediate_OptLSL_amount_16_0_16}, nil},
+	// MOVK <Xd>, #<imm>{, LSL #<shift>}
+	{0xff800000, 0xf2800000, MOVK, instArgs{arg_Xd, arg_immediate_OptLSL_amount_16_0_48}, nil},
+	// MRS <Xt>, <systemreg>
+	{0xfff00000, 0xd5300000, MRS, instArgs{arg_Xt, arg_sysreg_o0_op1_CRn_CRm_op2}, nil},
+	// MSR <pstatefield>, #<imm>
+	{0xfff8f01f, 0xd500401f, MSR, instArgs{arg_pstatefield_op1_op2__SPSel_05__DAIFSet_36__DAIFClr_37, arg_immediate_0_15_CRm}, nil},
+	// MSR <systemreg>, <Xt>
+	{0xfff00000, 0xd5100000, MSR, instArgs{arg_sysreg_o0_op1_CRn_CRm_op2, arg_Xt}, nil},
+	// MVN <Wd>, <Wm> {, <shift> #<amount> }
+	{0xff2003e0, 0x2a2003e0, MVN, instArgs{arg_Wd, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// ORN <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x2a200000, ORN, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_31}, nil},
+	// MVN <Xd>, <Xm> {, <shift> #<amount> }
+	{0xff2003e0, 0xaa2003e0, MVN, instArgs{arg_Xd, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// ORN <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xaa200000, ORN, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__ROR_3__0_63}, nil},
+	// NEG <Wd>, <Wm> {, <shift> #<amount> }
+	{0xff2003e0, 0x4b0003e0, NEG, instArgs{arg_Wd, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// SUB <Wd>, <Wn>, <Wm> {, <shift> #<amount> }
+	{0xff208000, 0x4b000000, SUB, instArgs{arg_Wd, arg_Wn, arg_Wm_shift__LSL_0__LSR_1__ASR_2__0_31}, nil},
+	// NEG <Xd>, <Xm> {, <shift> #<amount> }
+	{0xff2003e0, 0xcb0003e0, NEG, instArgs{arg_Xd, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// SUB <Xd>, <Xn>, <Xm> {, <shift> #<amount> }
+	{0xff200000, 0xcb000000, SUB, instArgs{arg_Xd, arg_Xn, arg_Xm_shift__LSL_0__LSR_1__ASR_2__0_63}, nil},
+	// NGC <Wd>, <Wm>
+	{0xffe0ffe0, 0x5a0003e0, NGC, instArgs{arg_Wd, arg_Wm}, nil},
+	// SBC <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x5a000000, SBC, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// NGC <Xd>, <Xm>
+	{0xffe0ffe0, 0xda0003e0, NGC, instArgs{arg_Xd, arg_Xm}, nil},
+	// SBC <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0xda000000, SBC, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// NGCS <Wd>, <Wm>
+	{0xffe0ffe0, 0x7a0003e0, NGCS, instArgs{arg_Wd, arg_Wm}, nil},
+	// SBCS <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x7a000000, SBCS, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// NGCS <Xd>, <Xm>
+	{0xffe0ffe0, 0xfa0003e0, NGCS, instArgs{arg_Xd, arg_Xm}, nil},
+	// SBCS <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0xfa000000, SBCS, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// PRFM <prfop>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0xf9800000, PRFM, instArgs{arg_prfop_Rt, arg_Xns_mem_optional_imm12_8_unsigned}, nil},
+	// PRFM <prfop>, <label>
+	{0xff000000, 0xd8000000, PRFM, instArgs{arg_prfop_Rt, arg_slabel_imm19_2}, nil},
+	// PRFM <prfop>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xf8a00800, PRFM, instArgs{arg_prfop_Rt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1}, nil},
+	// PRFUM <prfop>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xf8800000, PRFUM, instArgs{arg_prfop_Rt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// RBIT <Wd>, <Wn>
+	{0xfffffc00, 0x5ac00000, RBIT, instArgs{arg_Wd, arg_Wn}, nil},
+	// RBIT <Xd>, <Xn>
+	{0xfffffc00, 0xdac00000, RBIT, instArgs{arg_Xd, arg_Xn}, nil},
+	// RET {<Xn>}
+	{0xfffffc1f, 0xd65f0000, RET, instArgs{arg_Xn}, nil},
+	// REV <Wd>, <Wn>
+	{0xfffffc00, 0x5ac00800, REV, instArgs{arg_Wd, arg_Wn}, nil},
+	// REV <Xd>, <Xn>
+	{0xfffffc00, 0xdac00c00, REV, instArgs{arg_Xd, arg_Xn}, nil},
+	// REV16 <Wd>, <Wn>
+	{0xfffffc00, 0x5ac00400, REV16, instArgs{arg_Wd, arg_Wn}, nil},
+	// REV16 <Xd>, <Xn>
+	{0xfffffc00, 0xdac00400, REV16, instArgs{arg_Xd, arg_Xn}, nil},
+	// REV32 <Xd>, <Xn>
+	{0xfffffc00, 0xdac00800, REV32, instArgs{arg_Xd, arg_Xn}, nil},
+	// ROR <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02c00, ROR, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// RORV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac02c00, RORV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// ROR <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02c00, ROR, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// RORV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac02c00, RORV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// SDIV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac00c00, SDIV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// SDIV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac00c00, SDIV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// SMULL <Xd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x9b207c00, SMULL, instArgs{arg_Xd, arg_Wn, arg_Wm}, nil},
+	// SMADDL <Xd>, <Wn>, <Wm>, <Xa>
+	{0xffe08000, 0x9b200000, SMADDL, instArgs{arg_Xd, arg_Wn, arg_Wm, arg_Xa}, nil},
+	// SMNEGL <Xd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x9b20fc00, SMNEGL, instArgs{arg_Xd, arg_Wn, arg_Wm}, nil},
+	// SMSUBL <Xd>, <Wn>, <Wm>, <Xa>
+	{0xffe08000, 0x9b208000, SMSUBL, instArgs{arg_Xd, arg_Wn, arg_Wm, arg_Xa}, nil},
+	// SMULH <Xd>, <Xn>, <Xm>
+	{0xffe08000, 0x9b400000, SMULH, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// STLR <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88808000, STLR, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// STLR <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8808000, STLR, instArgs{arg_Xt, arg_Xns_mem}, nil},
+	// STLRB <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08808000, STLRB, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// STLRH <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48808000, STLRH, instArgs{arg_Wt, arg_Xns_mem}, nil},
+	// STLXP <Ws>, <Wt>, <Wt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88208000, STLXP, instArgs{arg_Ws, arg_Wt, arg_Wt2, arg_Xns_mem}, nil},
+	// STLXP <Ws>, <Xt>, <Xt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8208000, STLXP, instArgs{arg_Ws, arg_Xt, arg_Xt2, arg_Xns_mem}, nil},
+	// STLXR <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88008000, STLXR, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// STLXR <Ws>, <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8008000, STLXR, instArgs{arg_Ws, arg_Xt, arg_Xns_mem}, nil},
+	// STLXRB <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08008000, STLXRB, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// STLXRH <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48008000, STLXRH, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// STNP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x28000000, STNP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// STNP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_1>}]
+	{0xffc00000, 0xa8000000, STNP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// STP <Wt>, <Wt2>, [<Xn|SP>], #<imm_1>
+	{0xffc00000, 0x28800000, STP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_post_imm7_4_signed}, nil},
+	// STP <Xt>, <Xt2>, [<Xn|SP>], #<imm_3>
+	{0xffc00000, 0xa8800000, STP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_post_imm7_8_signed}, nil},
+	// STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm_1>}]!
+	{0xffc00000, 0x29800000, STP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_wb_imm7_4_signed}, nil},
+	// STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_3>}]!
+	{0xffc00000, 0xa9800000, STP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_wb_imm7_8_signed}, nil},
+	// STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x29000000, STP, instArgs{arg_Wt, arg_Wt2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0xa9000000, STP, instArgs{arg_Xt, arg_Xt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// STR <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xb8000400, STR, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Xt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xf8000400, STR, instArgs{arg_Xt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xb8000c00, STR, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Xt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xf8000c00, STR, instArgs{arg_Xt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0xb9000000, STR, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_4_unsigned}, nil},
+	// STR <Xt>, [<Xn|SP>{, #<pimm_1>}]
+	{0xffc00000, 0xf9000000, STR, instArgs{arg_Xt, arg_Xns_mem_optional_imm12_8_unsigned}, nil},
+	// STR <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xb8200800, STR, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1}, nil},
+	// STR <Xt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xf8200800, STR, instArgs{arg_Xt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1}, nil},
+	// STRB <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x38000400, STRB, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STRB <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x38000c00, STRB, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STRB <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x39000000, STRB, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// STRB <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x38200800, STRB, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// STRH <Wt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x78000400, STRH, instArgs{arg_Wt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STRH <Wt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x78000c00, STRH, instArgs{arg_Wt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STRH <Wt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x79000000, STRH, instArgs{arg_Wt, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// STRH <Wt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x78200800, STRH, instArgs{arg_Wt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// STTR <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8000800, STTR, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STTR <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xf8000800, STTR, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STTRB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38000800, STTRB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STTRH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78000800, STTRH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xb8000000, STUR, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <Xt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xf8000000, STUR, instArgs{arg_Xt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STURB <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x38000000, STURB, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STURH <Wt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x78000000, STURH, instArgs{arg_Wt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STXP <Ws>, <Wt>, <Wt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88200000, STXP, instArgs{arg_Ws, arg_Wt, arg_Wt2, arg_Xns_mem}, nil},
+	// STXP <Ws>, <Xt>, <Xt2>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8200000, STXP, instArgs{arg_Ws, arg_Xt, arg_Xt2, arg_Xns_mem}, nil},
+	// STXR <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x88000000, STXR, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// STXR <Ws>, <Xt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0xc8000000, STXR, instArgs{arg_Ws, arg_Xt, arg_Xns_mem}, nil},
+	// STXRB <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x08000000, STXRB, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// STXRH <Ws>, <Wt>, [<Xn|SP>{, #0}]
+	{0xffe08000, 0x48000000, STXRH, instArgs{arg_Ws, arg_Wt, arg_Xns_mem}, nil},
+	// SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
+	{0xffe00000, 0x4b200000, SUB, instArgs{arg_Wds, arg_Wns, arg_Wm_extend__UXTB_0__UXTH_1__LSL_UXTW_2__UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// SUB <Xd|SP>, <Xn|SP>, <R><m>{, <extend_1> {#<amount>}}
+	{0xffe00000, 0xcb200000, SUB, instArgs{arg_Xds, arg_Xns, arg_Rm_extend__UXTB_0__UXTH_1__UXTW_2__LSL_UXTX_3__SXTB_4__SXTH_5__SXTW_6__SXTX_7__0_4}, nil},
+	// SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
+	{0xff000000, 0x51000000, SUB, instArgs{arg_Wds, arg_Wns, arg_IAddSub}, nil},
+	// SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
+	{0xff000000, 0xd1000000, SUB, instArgs{arg_Xds, arg_Xns, arg_IAddSub}, nil},
+	// SVC #<imm>
+	{0xffe0001f, 0xd4000001, SVC, instArgs{arg_immediate_0_65535_imm16}, nil},
+	// SYSL <Xt>, #<op1>, <Cn>, <Cm>, #<op2>
+	{0xfff80000, 0xd5280000, SYSL, instArgs{arg_Xt, arg_immediate_0_7_op1, arg_Cn, arg_Cm, arg_immediate_0_7_op2}, nil},
+	// TBNZ <R><t>, #<imm>, <label>
+	{0x7f000000, 0x37000000, TBNZ, instArgs{arg_Rt_31_1__W_0__X_1, arg_immediate_0_63_b5_b40, arg_slabel_imm14_2}, nil},
+	// TBZ <R><t>, #<imm>, <label>
+	{0x7f000000, 0x36000000, TBZ, instArgs{arg_Rt_31_1__W_0__X_1, arg_immediate_0_63_b5_b40, arg_slabel_imm14_2}, nil},
+	// UDIV <Wd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x1ac00800, UDIV, instArgs{arg_Wd, arg_Wn, arg_Wm}, nil},
+	// UDIV <Xd>, <Xn>, <Xm>
+	{0xffe0fc00, 0x9ac00800, UDIV, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// UMULL <Xd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x9ba07c00, UMULL, instArgs{arg_Xd, arg_Wn, arg_Wm}, nil},
+	// UMADDL <Xd>, <Wn>, <Wm>, <Xa>
+	{0xffe08000, 0x9ba00000, UMADDL, instArgs{arg_Xd, arg_Wn, arg_Wm, arg_Xa}, nil},
+	// UMNEGL <Xd>, <Wn>, <Wm>
+	{0xffe0fc00, 0x9ba0fc00, UMNEGL, instArgs{arg_Xd, arg_Wn, arg_Wm}, nil},
+	// UMSUBL <Xd>, <Wn>, <Wm>, <Xa>
+	{0xffe08000, 0x9ba08000, UMSUBL, instArgs{arg_Xd, arg_Wn, arg_Wm, arg_Xa}, nil},
+	// UMULH <Xd>, <Xn>, <Xm>
+	{0xffe08000, 0x9bc00000, UMULH, instArgs{arg_Xd, arg_Xn, arg_Xm}, nil},
+	// ABS <V><d>, <V><n>
+	{0xff3ffc00, 0x5e20b800, ABS, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3}, nil},
+	// ABS <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e20b800, ABS, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// ADD <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e208400, ADD, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// ADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e208400, ADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// ADDHN <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x0e204000, ADDHN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// ADDHN2 <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x4e204000, ADDHN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// ADDP <V><d>, <Vn>.<t>
+	{0xff3ffc00, 0x5e31b800, ADDP, instArgs{arg_Vd_22_2__D_3, arg_Vn_arrangement_size___2D_3}, nil},
+	// ADDP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e20bc00, ADDP, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// ADDV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e31b800, ADDV, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// AESD <Vd>.16B, <Vn>.16B
+	{0xfffffc00, 0x4e285800, AESD, instArgs{arg_Vd_arrangement_16B, arg_Vn_arrangement_16B}, nil},
+	// AESE <Vd>.16B, <Vn>.16B
+	{0xfffffc00, 0x4e284800, AESE, instArgs{arg_Vd_arrangement_16B, arg_Vn_arrangement_16B}, nil},
+	// AESIMC <Vd>.16B, <Vn>.16B
+	{0xfffffc00, 0x4e287800, AESIMC, instArgs{arg_Vd_arrangement_16B, arg_Vn_arrangement_16B}, nil},
+	// AESMC <Vd>.16B, <Vn>.16B
+	{0xfffffc00, 0x4e286800, AESMC, instArgs{arg_Vd_arrangement_16B, arg_Vn_arrangement_16B}, nil},
+	// AND <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x0e201c00, AND, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// BIC <Vd>.<t>, #<imm8>{, LSL #<amount>}
+	{0xbff8dc00, 0x2f009400, BIC, instArgs{arg_Vd_arrangement_Q___4H_0__8H_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1}, nil},
+	// BIC <Vd>.<t_1>, #<imm8>{, LSL #<amount>}
+	{0xbff89c00, 0x2f001400, BIC, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3}, nil},
+	// BIC <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x0e601c00, BIC, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// BIF <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x2ee01c00, BIF, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// BIT <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x2ea01c00, BIT, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// BSL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x2e601c00, BSL, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// CLS <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e204800, CLS, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// CLZ <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e204800, CLZ, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// CMEQ <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e208c00, CMEQ, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMEQ <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e208c00, CMEQ, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CMEQ <V><d>, <V><n>, #0
+	{0xff3ffc00, 0x5e209800, CMEQ, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_immediate_zero}, nil},
+	// CMEQ <Vd>.<t>, <Vn>.<t>, #0
+	{0xbf3ffc00, 0x0e209800, CMEQ, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_immediate_zero}, nil},
+	// CMGE <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e203c00, CMGE, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMGE <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e203c00, CMGE, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CMGE <V><d>, <V><n>, #0
+	{0xff3ffc00, 0x7e208800, CMGE, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_immediate_zero}, nil},
+	// CMGE <Vd>.<t>, <Vn>.<t>, #0
+	{0xbf3ffc00, 0x2e208800, CMGE, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_immediate_zero}, nil},
+	// CMGT <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e203400, CMGT, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMGT <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e203400, CMGT, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CMGT <V><d>, <V><n>, #0
+	{0xff3ffc00, 0x5e208800, CMGT, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_immediate_zero}, nil},
+	// CMGT <Vd>.<t>, <Vn>.<t>, #0
+	{0xbf3ffc00, 0x0e208800, CMGT, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_immediate_zero}, nil},
+	// CMHI <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e203400, CMHI, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMHI <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e203400, CMHI, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CMHS <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e203c00, CMHS, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMHS <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e203c00, CMHS, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CMLE <V><d>, <V><n>, #0
+	{0xff3ffc00, 0x7e209800, CMLE, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_immediate_zero}, nil},
+	// CMLE <Vd>.<t>, <Vn>.<t>, #0
+	{0xbf3ffc00, 0x2e209800, CMLE, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_immediate_zero}, nil},
+	// CMLT <V><d>, <V><n>, #0
+	{0xff3ffc00, 0x5e20a800, CMLT, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_immediate_zero}, nil},
+	// CMLT <Vd>.<t>, <Vn>.<t>, #0
+	{0xbf3ffc00, 0x0e20a800, CMLT, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_immediate_zero}, nil},
+	// CMTST <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e208c00, CMTST, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// CMTST <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e208c00, CMTST, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// CNT <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e205800, CNT, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01, arg_Vn_arrangement_size_Q___8B_00__16B_01}, nil},
+	// MOV <V><d>, <Vn>.<t_1>[<index>]
+	{0xffe0fc00, 0x5e000400, MOV, instArgs{arg_Vd_16_5__B_1__H_2__S_4__D_8, arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1}, nil},
+	// DUP <V><d>, <Vn>.<t_1>[<index>]
+	{0xffe0fc00, 0x5e000400, DUP, instArgs{arg_Vd_16_5__B_1__H_2__S_4__D_8, arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1}, nil},
+	// DUP <Vd>.<t>, <Vn>.<ts>[<index>]
+	{0xbfe0fc00, 0x0e000400, DUP, instArgs{arg_Vd_arrangement_imm5_Q___8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1}, nil},
+	// DUP <Vd>.<t>, <R><n>
+	{0xbfe0fc00, 0x0e000c00, DUP, instArgs{arg_Vd_arrangement_imm5_Q___8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Rn_16_5__W_1__W_2__W_4__X_8}, nil},
+	// EOR <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x2e201c00, EOR, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// EXT <Vd>.<t>, <Vn>.<t>, <Vm>.<t>, #<index>
+	{0xbfe08400, 0x2e000000, EXT, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1, arg_immediate_index_Q_imm4__imm4lt20gt_00__imm4_10}, nil},
+	// FABD <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x7ea0d400, FABD, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FABD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2ea0d400, FABD, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FABS <Sd>, <Sn>
+	{0xfffffc00, 0x1e20c000, FABS, instArgs{arg_Sd, arg_Sn}, nil},
+	// FABS <Dd>, <Dn>
+	{0xfffffc00, 0x1e60c000, FABS, instArgs{arg_Dd, arg_Dn}, nil},
+	// FABS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea0f800, FABS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FACGE <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x7e20ec00, FACGE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FACGE <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20ec00, FACGE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FACGT <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x7ea0ec00, FACGT, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FACGT <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2ea0ec00, FACGT, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FADD <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e202800, FADD, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FADD <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e602800, FADD, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20d400, FADD, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FADDP <V><d>, <Vn>.<t>
+	{0xffbffc00, 0x7e30d800, FADDP, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_arrangement_sz___2S_0__2D_1}, nil},
+	// FADDP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20d400, FADDP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCCMP <Sn>, <Sm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x1e200400, FCCMP, instArgs{arg_Sn, arg_Sm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// FCCMP <Dn>, <Dm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x1e600400, FCCMP, instArgs{arg_Dn, arg_Dm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// FCCMPE <Sn>, <Sm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x1e200410, FCCMPE, instArgs{arg_Sn, arg_Sm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// FCCMPE <Dn>, <Dm>, #<nzcv>, <cond>
+	{0xffe00c10, 0x1e600410, FCCMPE, instArgs{arg_Dn, arg_Dm, arg_immediate_0_15_nzcv, arg_cond_AllowALNV_Normal}, nil},
+	// FCMEQ <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x5e20e400, FCMEQ, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FCMEQ <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20e400, FCMEQ, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCMEQ <V><d>, <V><n>, #0.0
+	{0xffbffc00, 0x5ea0d800, FCMEQ, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_immediate_floatzero}, nil},
+	// FCMEQ <Vd>.<t>, <Vn>.<t>, #0.0
+	{0xbfbffc00, 0x0ea0d800, FCMEQ, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_immediate_floatzero}, nil},
+	// FCMGE <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x7e20e400, FCMGE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FCMGE <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20e400, FCMGE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCMGE <V><d>, <V><n>, #0.0
+	{0xffbffc00, 0x7ea0c800, FCMGE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_immediate_floatzero}, nil},
+	// FCMGE <Vd>.<t>, <Vn>.<t>, #0.0
+	{0xbfbffc00, 0x2ea0c800, FCMGE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_immediate_floatzero}, nil},
+	// FCMGT <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x7ea0e400, FCMGT, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FCMGT <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2ea0e400, FCMGT, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCMGT <V><d>, <V><n>, #0.0
+	{0xffbffc00, 0x5ea0c800, FCMGT, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_immediate_floatzero}, nil},
+	// FCMGT <Vd>.<t>, <Vn>.<t>, #0.0
+	{0xbfbffc00, 0x0ea0c800, FCMGT, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_immediate_floatzero}, nil},
+	// FCMLE <V><d>, <V><n>, #0.0
+	{0xffbffc00, 0x7ea0d800, FCMLE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_immediate_floatzero}, nil},
+	// FCMLE <Vd>.<t>, <Vn>.<t>, #0.0
+	{0xbfbffc00, 0x2ea0d800, FCMLE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_immediate_floatzero}, nil},
+	// FCMLT <V><d>, <V><n>, #0.0
+	{0xffbffc00, 0x5ea0e800, FCMLT, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_immediate_floatzero}, nil},
+	// FCMLT <Vd>.<t>, <Vn>.<t>, #0.0
+	{0xbfbffc00, 0x0ea0e800, FCMLT, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_immediate_floatzero}, nil},
+	// FCMP <Sn>, <Sm>
+	{0xffe0fc1f, 0x1e202000, FCMP, instArgs{arg_Sn, arg_Sm}, nil},
+	// FCMP <Sn>, #0.0
+	{0xffe0fc1f, 0x1e202008, FCMP, instArgs{arg_Sn, arg_immediate_floatzero}, nil},
+	// FCMP <Dn>, <Dm>
+	{0xffe0fc1f, 0x1e602000, FCMP, instArgs{arg_Dn, arg_Dm}, nil},
+	// FCMP <Dn>, #0.0
+	{0xffe0fc1f, 0x1e602008, FCMP, instArgs{arg_Dn, arg_immediate_floatzero}, nil},
+	// FCMPE <Sn>, <Sm>
+	{0xffe0fc1f, 0x1e202010, FCMPE, instArgs{arg_Sn, arg_Sm}, nil},
+	// FCMPE <Sn>, #0.0
+	{0xffe0fc1f, 0x1e202018, FCMPE, instArgs{arg_Sn, arg_immediate_floatzero}, nil},
+	// FCMPE <Dn>, <Dm>
+	{0xffe0fc1f, 0x1e602010, FCMPE, instArgs{arg_Dn, arg_Dm}, nil},
+	// FCMPE <Dn>, #0.0
+	{0xffe0fc1f, 0x1e602018, FCMPE, instArgs{arg_Dn, arg_immediate_floatzero}, nil},
+	// FCSEL <Sd>, <Sn>, <Sm>, <cond>
+	{0xffe00c00, 0x1e200c00, FCSEL, instArgs{arg_Sd, arg_Sn, arg_Sm, arg_cond_AllowALNV_Normal}, nil},
+	// FCSEL <Dd>, <Dn>, <Dm>, <cond>
+	{0xffe00c00, 0x1e600c00, FCSEL, instArgs{arg_Dd, arg_Dn, arg_Dm, arg_cond_AllowALNV_Normal}, nil},
+	// FCVT <Sd>, <Hn>
+	{0xfffffc00, 0x1ee24000, FCVT, instArgs{arg_Sd, arg_Hn}, nil},
+	// FCVT <Dd>, <Hn>
+	{0xfffffc00, 0x1ee2c000, FCVT, instArgs{arg_Dd, arg_Hn}, nil},
+	// FCVT <Hd>, <Sn>
+	{0xfffffc00, 0x1e23c000, FCVT, instArgs{arg_Hd, arg_Sn}, nil},
+	// FCVT <Dd>, <Sn>
+	{0xfffffc00, 0x1e22c000, FCVT, instArgs{arg_Dd, arg_Sn}, nil},
+	// FCVT <Hd>, <Dn>
+	{0xfffffc00, 0x1e63c000, FCVT, instArgs{arg_Hd, arg_Dn}, nil},
+	// FCVT <Sd>, <Dn>
+	{0xfffffc00, 0x1e624000, FCVT, instArgs{arg_Sd, arg_Dn}, nil},
+	// FCVTAS <Wd>, <Sn>
+	{0xfffffc00, 0x1e240000, FCVTAS, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTAS <Xd>, <Sn>
+	{0xfffffc00, 0x9e240000, FCVTAS, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTAS <Wd>, <Dn>
+	{0xfffffc00, 0x1e640000, FCVTAS, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTAS <Xd>, <Dn>
+	{0xfffffc00, 0x9e640000, FCVTAS, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTAS <V><d>, <V><n>
+	{0xffbffc00, 0x5e21c800, FCVTAS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTAS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e21c800, FCVTAS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTAU <Wd>, <Sn>
+	{0xfffffc00, 0x1e250000, FCVTAU, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTAU <Xd>, <Sn>
+	{0xfffffc00, 0x9e250000, FCVTAU, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTAU <Wd>, <Dn>
+	{0xfffffc00, 0x1e650000, FCVTAU, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTAU <Xd>, <Dn>
+	{0xfffffc00, 0x9e650000, FCVTAU, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTAU <V><d>, <V><n>
+	{0xffbffc00, 0x7e21c800, FCVTAU, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTAU <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e21c800, FCVTAU, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTL <Vd>.<ta>, <Vn>.<tb>
+	{0xffbffc00, 0x0e217800, FCVTL, instArgs{arg_Vd_arrangement_sz___4S_0__2D_1, arg_Vn_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11}, nil},
+	// FCVTL2 <Vd>.<ta>, <Vn>.<tb>
+	{0xffbffc00, 0x4e217800, FCVTL2, instArgs{arg_Vd_arrangement_sz___4S_0__2D_1, arg_Vn_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11}, nil},
+	// FCVTMS <Wd>, <Sn>
+	{0xfffffc00, 0x1e300000, FCVTMS, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTMS <Xd>, <Sn>
+	{0xfffffc00, 0x9e300000, FCVTMS, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTMS <Wd>, <Dn>
+	{0xfffffc00, 0x1e700000, FCVTMS, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTMS <Xd>, <Dn>
+	{0xfffffc00, 0x9e700000, FCVTMS, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTMS <V><d>, <V><n>
+	{0xffbffc00, 0x5e21b800, FCVTMS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTMS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e21b800, FCVTMS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTMU <Wd>, <Sn>
+	{0xfffffc00, 0x1e310000, FCVTMU, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTMU <Xd>, <Sn>
+	{0xfffffc00, 0x9e310000, FCVTMU, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTMU <Wd>, <Dn>
+	{0xfffffc00, 0x1e710000, FCVTMU, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTMU <Xd>, <Dn>
+	{0xfffffc00, 0x9e710000, FCVTMU, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTMU <V><d>, <V><n>
+	{0xffbffc00, 0x7e21b800, FCVTMU, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTMU <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e21b800, FCVTMU, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTN <Vd>.<tb>, <Vn>.<ta>
+	{0xffbffc00, 0x0e216800, FCVTN, instArgs{arg_Vd_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11, arg_Vn_arrangement_sz___4S_0__2D_1}, nil},
+	// FCVTN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xffbffc00, 0x4e216800, FCVTN2, instArgs{arg_Vd_arrangement_sz_Q___4H_00__8H_01__2S_10__4S_11, arg_Vn_arrangement_sz___4S_0__2D_1}, nil},
+	// FCVTNS <Wd>, <Sn>
+	{0xfffffc00, 0x1e200000, FCVTNS, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTNS <Xd>, <Sn>
+	{0xfffffc00, 0x9e200000, FCVTNS, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTNS <Wd>, <Dn>
+	{0xfffffc00, 0x1e600000, FCVTNS, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTNS <Xd>, <Dn>
+	{0xfffffc00, 0x9e600000, FCVTNS, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTNS <V><d>, <V><n>
+	{0xffbffc00, 0x5e21a800, FCVTNS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTNS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e21a800, FCVTNS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTNU <Wd>, <Sn>
+	{0xfffffc00, 0x1e210000, FCVTNU, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTNU <Xd>, <Sn>
+	{0xfffffc00, 0x9e210000, FCVTNU, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTNU <Wd>, <Dn>
+	{0xfffffc00, 0x1e610000, FCVTNU, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTNU <Xd>, <Dn>
+	{0xfffffc00, 0x9e610000, FCVTNU, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTNU <V><d>, <V><n>
+	{0xffbffc00, 0x7e21a800, FCVTNU, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTNU <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e21a800, FCVTNU, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTPS <Wd>, <Sn>
+	{0xfffffc00, 0x1e280000, FCVTPS, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTPS <Xd>, <Sn>
+	{0xfffffc00, 0x9e280000, FCVTPS, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTPS <Wd>, <Dn>
+	{0xfffffc00, 0x1e680000, FCVTPS, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTPS <Xd>, <Dn>
+	{0xfffffc00, 0x9e680000, FCVTPS, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTPS <V><d>, <V><n>
+	{0xffbffc00, 0x5ea1a800, FCVTPS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTPS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea1a800, FCVTPS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTPU <Wd>, <Sn>
+	{0xfffffc00, 0x1e290000, FCVTPU, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTPU <Xd>, <Sn>
+	{0xfffffc00, 0x9e290000, FCVTPU, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTPU <Wd>, <Dn>
+	{0xfffffc00, 0x1e690000, FCVTPU, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTPU <Xd>, <Dn>
+	{0xfffffc00, 0x9e690000, FCVTPU, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTPU <V><d>, <V><n>
+	{0xffbffc00, 0x7ea1a800, FCVTPU, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTPU <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea1a800, FCVTPU, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTXN <V><d>, <V><n>
+	{0xffbffc00, 0x7e216800, FCVTXN, instArgs{arg_Vd_22_1__S_1, arg_Vn_22_1__D_1}, nil},
+	// FCVTXN <Vd>.<tb>, <Vn>.<ta>
+	{0xffbffc00, 0x2e216800, FCVTXN, instArgs{arg_Vd_arrangement_sz_Q___2S_10__4S_11, arg_Vn_arrangement_sz___2D_1}, nil},
+	// FCVTXN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xffbffc00, 0x6e216800, FCVTXN2, instArgs{arg_Vd_arrangement_sz_Q___2S_10__4S_11, arg_Vn_arrangement_sz___2D_1}, nil},
+	// FCVTZS <Wd>, <Sn>, #<fbits>
+	{0xffff0000, 0x1e180000, FCVTZS, instArgs{arg_Wd, arg_Sn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// FCVTZS <Xd>, <Sn>, #<fbits>
+	{0xffff0000, 0x9e180000, FCVTZS, instArgs{arg_Xd, arg_Sn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// FCVTZS <Wd>, <Dn>, #<fbits>
+	{0xffff0000, 0x1e580000, FCVTZS, instArgs{arg_Wd, arg_Dn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// FCVTZS <Xd>, <Dn>, #<fbits>
+	{0xffff0000, 0x9e580000, FCVTZS, instArgs{arg_Xd, arg_Dn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// FCVTZS <Wd>, <Sn>
+	{0xfffffc00, 0x1e380000, FCVTZS, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTZS <Xd>, <Sn>
+	{0xfffffc00, 0x9e380000, FCVTZS, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTZS <Wd>, <Dn>
+	{0xfffffc00, 0x1e780000, FCVTZS, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTZS <Xd>, <Dn>
+	{0xfffffc00, 0x9e780000, FCVTZS, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTZS <V><d>, <V><n>, #<fbits>
+	{0xff80fc00, 0x5f00fc00, FCVTZS, instArgs{arg_Vd_19_4__S_4__D_8, arg_Vn_19_4__S_4__D_8, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8}, fcvtzs_asisdshf_c_cond},
+	// FCVTZS <Vd>.<t>, <Vn>.<t>, #<fbits>
+	{0xbf80fc00, 0x0f00fc00, FCVTZS, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8}, fcvtzs_asimdshf_c_cond},
+	// FCVTZS <V><d>, <V><n>
+	{0xffbffc00, 0x5ea1b800, FCVTZS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTZS <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea1b800, FCVTZS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FCVTZU <Wd>, <Sn>, #<fbits>
+	{0xffff0000, 0x1e190000, FCVTZU, instArgs{arg_Wd, arg_Sn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// FCVTZU <Xd>, <Sn>, #<fbits>
+	{0xffff0000, 0x9e190000, FCVTZU, instArgs{arg_Xd, arg_Sn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// FCVTZU <Wd>, <Dn>, #<fbits>
+	{0xffff0000, 0x1e590000, FCVTZU, instArgs{arg_Wd, arg_Dn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// FCVTZU <Xd>, <Dn>, #<fbits>
+	{0xffff0000, 0x9e590000, FCVTZU, instArgs{arg_Xd, arg_Dn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// FCVTZU <Wd>, <Sn>
+	{0xfffffc00, 0x1e390000, FCVTZU, instArgs{arg_Wd, arg_Sn}, nil},
+	// FCVTZU <Xd>, <Sn>
+	{0xfffffc00, 0x9e390000, FCVTZU, instArgs{arg_Xd, arg_Sn}, nil},
+	// FCVTZU <Wd>, <Dn>
+	{0xfffffc00, 0x1e790000, FCVTZU, instArgs{arg_Wd, arg_Dn}, nil},
+	// FCVTZU <Xd>, <Dn>
+	{0xfffffc00, 0x9e790000, FCVTZU, instArgs{arg_Xd, arg_Dn}, nil},
+	// FCVTZU <V><d>, <V><n>, #<fbits>
+	{0xff80fc00, 0x7f00fc00, FCVTZU, instArgs{arg_Vd_19_4__S_4__D_8, arg_Vn_19_4__S_4__D_8, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8}, fcvtzu_asisdshf_c_cond},
+	// FCVTZU <Vd>.<t>, <Vn>.<t>, #<fbits>
+	{0xbf80fc00, 0x2f00fc00, FCVTZU, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8}, fcvtzu_asimdshf_c_cond},
+	// FCVTZU <V><d>, <V><n>
+	{0xffbffc00, 0x7ea1b800, FCVTZU, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FCVTZU <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea1b800, FCVTZU, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FDIV <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e201800, FDIV, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FDIV <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e601800, FDIV, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FDIV <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20fc00, FDIV, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMADD <Sd>, <Sn>, <Sm>, <Sa>
+	{0xffe08000, 0x1f000000, FMADD, instArgs{arg_Sd, arg_Sn, arg_Sm, arg_Sa}, nil},
+	// FMADD <Dd>, <Dn>, <Dm>, <Da>
+	{0xffe08000, 0x1f400000, FMADD, instArgs{arg_Dd, arg_Dn, arg_Dm, arg_Da}, nil},
+	// FMAX <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e204800, FMAX, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FMAX <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e604800, FMAX, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FMAX <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20f400, FMAX, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMAXNM <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e206800, FMAXNM, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FMAXNM <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e606800, FMAXNM, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FMAXNM <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20c400, FMAXNM, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMAXNMP <V><d>, <Vn>.<t>
+	{0xffbffc00, 0x7e30c800, FMAXNMP, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_arrangement_sz___2S_0__2D_1}, nil},
+	// FMAXNMP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20c400, FMAXNMP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMAXNMV <V><d>, <Vn>.<t>
+	{0xbfbffc00, 0x2e30c800, FMAXNMV, instArgs{arg_Vd_22_1__S_0, arg_Vn_arrangement_Q_sz___4S_10}, nil},
+	// FMAXP <V><d>, <Vn>.<t>
+	{0xffbffc00, 0x7e30f800, FMAXP, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_arrangement_sz___2S_0__2D_1}, nil},
+	// FMAXP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20f400, FMAXP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMAXV <V><d>, <Vn>.<t>
+	{0xbfbffc00, 0x2e30f800, FMAXV, instArgs{arg_Vd_22_1__S_0, arg_Vn_arrangement_Q_sz___4S_10}, nil},
+	// FMIN <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e205800, FMIN, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FMIN <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e605800, FMIN, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FMIN <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0ea0f400, FMIN, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMINNM <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e207800, FMINNM, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FMINNM <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e607800, FMINNM, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FMINNM <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0ea0c400, FMINNM, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMINNMP <V><d>, <Vn>.<t>
+	{0xffbffc00, 0x7eb0c800, FMINNMP, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_arrangement_sz___2S_0__2D_1}, nil},
+	// FMINNMP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2ea0c400, FMINNMP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMINNMV <V><d>, <Vn>.<t>
+	{0xbfbffc00, 0x2eb0c800, FMINNMV, instArgs{arg_Vd_22_1__S_0, arg_Vn_arrangement_Q_sz___4S_10}, nil},
+	// FMINP <V><d>, <Vn>.<t>
+	{0xffbffc00, 0x7eb0f800, FMINP, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_arrangement_sz___2S_0__2D_1}, nil},
+	// FMINP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2ea0f400, FMINP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMINV <V><d>, <Vn>.<t>
+	{0xbfbffc00, 0x2eb0f800, FMINV, instArgs{arg_Vd_22_1__S_0, arg_Vn_arrangement_Q_sz___4S_10}, nil},
+	// FMLA <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff80f400, 0x5f801000, FMLA, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMLA <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf80f400, 0x0f801000, FMLA, instArgs{arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMLA <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20cc00, FMLA, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMLS <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff80f400, 0x5f805000, FMLS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMLS <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf80f400, 0x0f805000, FMLS, instArgs{arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMLS <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0ea0cc00, FMLS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMOV <Sd>, <Wn>
+	{0xfffffc00, 0x1e270000, FMOV, instArgs{arg_Sd, arg_Wn}, nil},
+	// FMOV <Wd>, <Sn>
+	{0xfffffc00, 0x1e260000, FMOV, instArgs{arg_Wd, arg_Sn}, nil},
+	// FMOV <Dd>, <Xn>
+	{0xfffffc00, 0x9e670000, FMOV, instArgs{arg_Dd, arg_Xn}, nil},
+	// FMOV <Vd>.D[1], <Xn>
+	{0xfffffc00, 0x9eaf0000, FMOV, instArgs{arg_Vd_arrangement_D_index__1, arg_Xn}, nil},
+	// FMOV <Xd>, <Dn>
+	{0xfffffc00, 0x9e660000, FMOV, instArgs{arg_Xd, arg_Dn}, nil},
+	// FMOV <Xd>, <Vn>.D[1]
+	{0xfffffc00, 0x9eae0000, FMOV, instArgs{arg_Xd, arg_Vn_arrangement_D_index__1}, nil},
+	// FMOV <Sd>, <Sn>
+	{0xfffffc00, 0x1e204000, FMOV, instArgs{arg_Sd, arg_Sn}, nil},
+	// FMOV <Dd>, <Dn>
+	{0xfffffc00, 0x1e604000, FMOV, instArgs{arg_Dd, arg_Dn}, nil},
+	// FMOV <Sd>, #<imm>
+	{0xffe01fe0, 0x1e201000, FMOV, instArgs{arg_Sd, arg_immediate_exp_3_pre_4_imm8}, nil},
+	// FMOV <Dd>, #<imm>
+	{0xffe01fe0, 0x1e601000, FMOV, instArgs{arg_Dd, arg_immediate_exp_3_pre_4_imm8}, nil},
+	// FMOV <Vd>.<t>, #<imm>
+	{0xbff8fc00, 0x0f00f400, FMOV, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_exp_3_pre_4_a_b_c_d_e_f_g_h}, nil},
+	// FMOV <Vd>.2D, #<imm>
+	{0xfff8fc00, 0x6f00f400, FMOV, instArgs{arg_Vd_arrangement_2D, arg_immediate_exp_3_pre_4_a_b_c_d_e_f_g_h}, nil},
+	// FMSUB <Sd>, <Sn>, <Sm>, <Sa>
+	{0xffe08000, 0x1f008000, FMSUB, instArgs{arg_Sd, arg_Sn, arg_Sm, arg_Sa}, nil},
+	// FMSUB <Dd>, <Dn>, <Dm>, <Da>
+	{0xffe08000, 0x1f408000, FMSUB, instArgs{arg_Dd, arg_Dn, arg_Dm, arg_Da}, nil},
+	// FMUL <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff80f400, 0x5f809000, FMUL, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMUL <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf80f400, 0x0f809000, FMUL, instArgs{arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMUL <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e200800, FMUL, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FMUL <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e600800, FMUL, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FMUL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x2e20dc00, FMUL, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMULX <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x5e20dc00, FMULX, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FMULX <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20dc00, FMULX, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FMULX <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff80f400, 0x7f809000, FMULX, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FMULX <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf80f400, 0x2f809000, FMULX, instArgs{arg_Vd_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vn_arrangement_Q_sz___2S_00__4S_10__2D_11, arg_Vm_arrangement_sz___S_0__D_1_index__sz_L_H__HL_00__H_10_1}, nil},
+	// FNEG <Sd>, <Sn>
+	{0xfffffc00, 0x1e214000, FNEG, instArgs{arg_Sd, arg_Sn}, nil},
+	// FNEG <Dd>, <Dn>
+	{0xfffffc00, 0x1e614000, FNEG, instArgs{arg_Dd, arg_Dn}, nil},
+	// FNEG <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea0f800, FNEG, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FNMADD <Sd>, <Sn>, <Sm>, <Sa>
+	{0xffe08000, 0x1f200000, FNMADD, instArgs{arg_Sd, arg_Sn, arg_Sm, arg_Sa}, nil},
+	// FNMADD <Dd>, <Dn>, <Dm>, <Da>
+	{0xffe08000, 0x1f600000, FNMADD, instArgs{arg_Dd, arg_Dn, arg_Dm, arg_Da}, nil},
+	// FNMSUB <Sd>, <Sn>, <Sm>, <Sa>
+	{0xffe08000, 0x1f208000, FNMSUB, instArgs{arg_Sd, arg_Sn, arg_Sm, arg_Sa}, nil},
+	// FNMSUB <Dd>, <Dn>, <Dm>, <Da>
+	{0xffe08000, 0x1f608000, FNMSUB, instArgs{arg_Dd, arg_Dn, arg_Dm, arg_Da}, nil},
+	// FNMUL <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e208800, FNMUL, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FNMUL <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e608800, FNMUL, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FRECPE <V><d>, <V><n>
+	{0xffbffc00, 0x5ea1d800, FRECPE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FRECPE <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea1d800, FRECPE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRECPS <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x5e20fc00, FRECPS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FRECPS <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0e20fc00, FRECPS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRECPX <V><d>, <V><n>
+	{0xffbffc00, 0x5ea1f800, FRECPX, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FRINTA <Sd>, <Sn>
+	{0xfffffc00, 0x1e264000, FRINTA, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTA <Dd>, <Dn>
+	{0xfffffc00, 0x1e664000, FRINTA, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTA <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e218800, FRINTA, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTI <Sd>, <Sn>
+	{0xfffffc00, 0x1e27c000, FRINTI, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTI <Dd>, <Dn>
+	{0xfffffc00, 0x1e67c000, FRINTI, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTI <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea19800, FRINTI, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTM <Sd>, <Sn>
+	{0xfffffc00, 0x1e254000, FRINTM, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTM <Dd>, <Dn>
+	{0xfffffc00, 0x1e654000, FRINTM, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTM <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e219800, FRINTM, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTN <Sd>, <Sn>
+	{0xfffffc00, 0x1e244000, FRINTN, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTN <Dd>, <Dn>
+	{0xfffffc00, 0x1e644000, FRINTN, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTN <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e218800, FRINTN, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTP <Sd>, <Sn>
+	{0xfffffc00, 0x1e24c000, FRINTP, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTP <Dd>, <Dn>
+	{0xfffffc00, 0x1e64c000, FRINTP, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTP <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea18800, FRINTP, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTX <Sd>, <Sn>
+	{0xfffffc00, 0x1e274000, FRINTX, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTX <Dd>, <Dn>
+	{0xfffffc00, 0x1e674000, FRINTX, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTX <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e219800, FRINTX, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRINTZ <Sd>, <Sn>
+	{0xfffffc00, 0x1e25c000, FRINTZ, instArgs{arg_Sd, arg_Sn}, nil},
+	// FRINTZ <Dd>, <Dn>
+	{0xfffffc00, 0x1e65c000, FRINTZ, instArgs{arg_Dd, arg_Dn}, nil},
+	// FRINTZ <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea19800, FRINTZ, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRSQRTE <V><d>, <V><n>
+	{0xffbffc00, 0x7ea1d800, FRSQRTE, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// FRSQRTE <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea1d800, FRSQRTE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FRSQRTS <V><d>, <V><n>, <V><m>
+	{0xffa0fc00, 0x5ea0fc00, FRSQRTS, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1, arg_Vm_22_1__S_0__D_1}, nil},
+	// FRSQRTS <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0ea0fc00, FRSQRTS, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FSQRT <Sd>, <Sn>
+	{0xfffffc00, 0x1e21c000, FSQRT, instArgs{arg_Sd, arg_Sn}, nil},
+	// FSQRT <Dd>, <Dn>
+	{0xfffffc00, 0x1e61c000, FSQRT, instArgs{arg_Dd, arg_Dn}, nil},
+	// FSQRT <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea1f800, FSQRT, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// FSUB <Sd>, <Sn>, <Sm>
+	{0xffe0fc00, 0x1e203800, FSUB, instArgs{arg_Sd, arg_Sn, arg_Sm}, nil},
+	// FSUB <Dd>, <Dn>, <Dm>
+	{0xffe0fc00, 0x1e603800, FSUB, instArgs{arg_Dd, arg_Dn, arg_Dm}, nil},
+	// FSUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfa0fc00, 0x0ea0d400, FSUB, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vm_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// MOV <Vd>.<ts>[<index1>], <Vn>.<ts>[<index2>]
+	{0xffe08400, 0x6e000400, MOV, instArgs{arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1, arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5_imm4__imm4lt30gt_1__imm4lt31gt_2__imm4lt32gt_4__imm4lt3gt_8_1}, nil},
+	// INS <Vd>.<ts>[<index1>], <Vn>.<ts>[<index2>]
+	{0xffe08400, 0x6e000400, INS, instArgs{arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1, arg_Vn_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5_imm4__imm4lt30gt_1__imm4lt31gt_2__imm4lt32gt_4__imm4lt3gt_8_1}, nil},
+	// MOV <Vd>.<ts>[<index>], <R><n>
+	{0xffe0fc00, 0x4e001c00, MOV, instArgs{arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1, arg_Rn_16_5__W_1__W_2__W_4__X_8}, nil},
+	// INS <Vd>.<ts>[<index>], <R><n>
+	{0xffe0fc00, 0x4e001c00, INS, instArgs{arg_Vd_arrangement_imm5___B_1__H_2__S_4__D_8_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4__imm5lt4gt_8_1, arg_Rn_16_5__W_1__W_2__W_4__X_8}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c407000, LD1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c40a000, LD1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c406000, LD1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c402000, LD1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0cdf7000, LD1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__8_0__16_1}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc07000, LD1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<imm_1>
+	{0xbffff000, 0x0cdfa000, LD1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__16_0__32_1}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc0a000, LD1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<imm_2>
+	{0xbffff000, 0x0cdf6000, LD1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__24_0__48_1}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc06000, LD1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<imm_3>
+	{0xbffff000, 0x0cdf2000, LD1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__32_0__64_1}, nil},
+	// LD1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc02000, LD1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d400000, LD1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d404000, LD1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d408000, LD1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d408400, LD1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// LD1 <Vt>.B[<index>], [<Xn|SP>], #1
+	{0xbfffe000, 0x0ddf0000, LD1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_1}, nil},
+	// LD1 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0dc00000, LD1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.H[<index_2>], [<Xn|SP>], #2
+	{0xbfffe400, 0x0ddf4000, LD1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_2}, nil},
+	// LD1 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0dc04000, LD1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.S[<index_3>], [<Xn|SP>], #4
+	{0xbfffec00, 0x0ddf8000, LD1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// LD1 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0dc08000, LD1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// LD1 <Vt>.D[<index_1>], [<Xn|SP>], #8
+	{0xbffffc00, 0x0ddf8400, LD1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// LD1 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0dc08400, LD1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// LD1R <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0d40c000, LD1R, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD1R <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0ddfc000, LD1R, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_size__1_0__2_1__4_2__8_3}, nil},
+	// LD1R <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0dc0c000, LD1R, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD2 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c408000, LD2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// LD2 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0cdf8000, LD2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__16_0__32_1}, nil},
+	// LD2 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc08000, LD2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD2 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d600000, LD2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD2 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d604000, LD2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD2 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d608000, LD2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// LD2 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d608400, LD2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// LD2 <Vt>.B[<index>], [<Xn|SP>], #2
+	{0xbfffe000, 0x0dff0000, LD2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_2}, nil},
+	// LD2 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0de00000, LD2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD2 <Vt>.H[<index_2>], [<Xn|SP>], #4
+	{0xbfffe400, 0x0dff4000, LD2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// LD2 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0de04000, LD2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD2 <Vt>.S[<index_3>], [<Xn|SP>], #8
+	{0xbfffec00, 0x0dff8000, LD2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// LD2 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0de08000, LD2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// LD2 <Vt>.D[<index_1>], [<Xn|SP>], #16
+	{0xbffffc00, 0x0dff8400, LD2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_16}, nil},
+	// LD2 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0de08400, LD2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// LD2R <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0d60c000, LD2R, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD2R <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0dffc000, LD2R, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_size__2_0__4_1__8_2__16_3}, nil},
+	// LD2R <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0de0c000, LD2R, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD3 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c404000, LD3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// LD3 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0cdf4000, LD3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__24_0__48_1}, nil},
+	// LD3 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc04000, LD3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD3 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d402000, LD3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD3 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d406000, LD3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD3 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d40a000, LD3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// LD3 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d40a400, LD3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// LD3 <Vt>.B[<index>], [<Xn|SP>], #3
+	{0xbfffe000, 0x0ddf2000, LD3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_3}, nil},
+	// LD3 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0dc02000, LD3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD3 <Vt>.H[<index_2>], [<Xn|SP>], #6
+	{0xbfffe400, 0x0ddf6000, LD3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_6}, nil},
+	// LD3 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0dc06000, LD3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD3 <Vt>.S[<index_3>], [<Xn|SP>], #12
+	{0xbfffec00, 0x0ddfa000, LD3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_12}, nil},
+	// LD3 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0dc0a000, LD3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// LD3 <Vt>.D[<index_1>], [<Xn|SP>], #24
+	{0xbffffc00, 0x0ddfa400, LD3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_24}, nil},
+	// LD3 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0dc0a400, LD3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// LD3R <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0d40e000, LD3R, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD3R <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0ddfe000, LD3R, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_size__3_0__6_1__12_2__24_3}, nil},
+	// LD3R <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0dc0e000, LD3R, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD4 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c400000, LD4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// LD4 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0cdf0000, LD4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__32_0__64_1}, nil},
+	// LD4 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0cc00000, LD4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LD4 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d602000, LD4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD4 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d606000, LD4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// LD4 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d60a000, LD4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// LD4 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d60a400, LD4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// LD4 <Vt>.B[<index>], [<Xn|SP>], #4
+	{0xbfffe000, 0x0dff2000, LD4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// LD4 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0de02000, LD4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD4 <Vt>.H[<index_2>], [<Xn|SP>], #8
+	{0xbfffe400, 0x0dff6000, LD4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// LD4 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0de06000, LD4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// LD4 <Vt>.S[<index_3>], [<Xn|SP>], #16
+	{0xbfffec00, 0x0dffa000, LD4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_16}, nil},
+	// LD4 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0de0a000, LD4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// LD4 <Vt>.D[<index_1>], [<Xn|SP>], #32
+	{0xbffffc00, 0x0dffa400, LD4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_32}, nil},
+	// LD4 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0de0a400, LD4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// LD4R <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0d60e000, LD4R, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// LD4R <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0dffe000, LD4R, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_size__4_0__8_1__16_2__32_3}, nil},
+	// LD4R <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0de0e000, LD4R, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// LDNP <St>, <St2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0x2c400000, LDNP, instArgs{arg_St, arg_St2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// LDNP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x6c400000, LDNP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// LDNP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_1>}]
+	{0xffc00000, 0xac400000, LDNP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_optional_imm7_16_signed}, nil},
+	// LDP <St>, <St2>, [<Xn|SP>], #<imm_5>
+	{0xffc00000, 0x2cc00000, LDP, instArgs{arg_St, arg_St2, arg_Xns_mem_post_imm7_4_signed}, nil},
+	// LDP <Dt>, <Dt2>, [<Xn|SP>], #<imm_1>
+	{0xffc00000, 0x6cc00000, LDP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_post_imm7_8_signed}, nil},
+	// LDP <Qt>, <Qt2>, [<Xn|SP>], #<imm_3>
+	{0xffc00000, 0xacc00000, LDP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_post_imm7_16_signed}, nil},
+	// LDP <St>, <St2>, [<Xn|SP>{, #<imm_5>}]!
+	{0xffc00000, 0x2dc00000, LDP, instArgs{arg_St, arg_St2, arg_Xns_mem_wb_imm7_4_signed}, nil},
+	// LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm_1>}]!
+	{0xffc00000, 0x6dc00000, LDP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_wb_imm7_8_signed}, nil},
+	// LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_3>}]!
+	{0xffc00000, 0xadc00000, LDP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_wb_imm7_16_signed}, nil},
+	// LDP <St>, <St2>, [<Xn|SP>{, #<imm_4>}]
+	{0xffc00000, 0x2d400000, LDP, instArgs{arg_St, arg_St2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x6d400000, LDP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0xad400000, LDP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_optional_imm7_16_signed}, nil},
+	// LDR <Bt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x3c400400, LDR, instArgs{arg_Bt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Ht>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x7c400400, LDR, instArgs{arg_Ht, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <St>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xbc400400, LDR, instArgs{arg_St, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Dt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xfc400400, LDR, instArgs{arg_Dt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Qt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x3cc00400, LDR, instArgs{arg_Qt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// LDR <Bt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x3c400c00, LDR, instArgs{arg_Bt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Ht>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x7c400c00, LDR, instArgs{arg_Ht, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <St>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xbc400c00, LDR, instArgs{arg_St, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Dt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xfc400c00, LDR, instArgs{arg_Dt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Qt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x3cc00c00, LDR, instArgs{arg_Qt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// LDR <Bt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x3d400000, LDR, instArgs{arg_Bt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// LDR <Ht>, [<Xn|SP>{, #<pimm_2>}]
+	{0xffc00000, 0x7d400000, LDR, instArgs{arg_Ht, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// LDR <St>, [<Xn|SP>{, #<pimm_4>}]
+	{0xffc00000, 0xbd400000, LDR, instArgs{arg_St, arg_Xns_mem_optional_imm12_4_unsigned}, nil},
+	// LDR <Dt>, [<Xn|SP>{, #<pimm_1>}]
+	{0xffc00000, 0xfd400000, LDR, instArgs{arg_Dt, arg_Xns_mem_optional_imm12_8_unsigned}, nil},
+	// LDR <Qt>, [<Xn|SP>{, #<pimm_3>}]
+	{0xffc00000, 0x3dc00000, LDR, instArgs{arg_Qt, arg_Xns_mem_optional_imm12_16_unsigned}, nil},
+	// LDR <St>, <label>
+	{0xff000000, 0x1c000000, LDR, instArgs{arg_St, arg_slabel_imm19_2}, nil},
+	// LDR <Dt>, <label>
+	{0xff000000, 0x5c000000, LDR, instArgs{arg_Dt, arg_slabel_imm19_2}, nil},
+	// LDR <Qt>, <label>
+	{0xff000000, 0x9c000000, LDR, instArgs{arg_Qt, arg_slabel_imm19_2}, nil},
+	// LDR <Bt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x3c600800, LDR, instArgs{arg_Bt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// LDR <Ht>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x7c600800, LDR, instArgs{arg_Ht, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// LDR <St>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xbc600800, LDR, instArgs{arg_St, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1}, nil},
+	// LDR <Dt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xfc600800, LDR, instArgs{arg_Dt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1}, nil},
+	// LDR <Qt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x3ce00800, LDR, instArgs{arg_Qt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__4_1}, nil},
+	// LDUR <Bt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x3c400000, LDUR, instArgs{arg_Bt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <Ht>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x7c400000, LDUR, instArgs{arg_Ht, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <St>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xbc400000, LDUR, instArgs{arg_St, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <Dt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xfc400000, LDUR, instArgs{arg_Dt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// LDUR <Qt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x3cc00000, LDUR, instArgs{arg_Qt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// MLA <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf00f400, 0x2f000000, MLA, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// MLA <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e209400, MLA, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// MLS <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf00f400, 0x2f004000, MLS, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// MLS <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e209400, MLS, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// MOV <Wd>, <Vn>.S[<index>]
+	{0xffe0fc00, 0x0e003c00, MOV, instArgs{arg_Wd, arg_Vn_arrangement_S_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1}, mov_umov_asimdins_w_w_cond},
+	// UMOV <Wd>, <Vn>.<ts>[<index>]
+	{0xffe0fc00, 0x0e003c00, UMOV, instArgs{arg_Wd, arg_Vn_arrangement_imm5___B_1__H_2__S_4_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1}, nil},
+	// MOV <Xd>, <Vn>.D[<index_1>]
+	{0xffe0fc00, 0x4e003c00, MOV, instArgs{arg_Xd, arg_Vn_arrangement_D_index__imm5_1}, mov_umov_asimdins_x_x_cond},
+	// UMOV <Xd>, <Vn>.<ts_1>[<index_1>]
+	{0xffe0fc00, 0x4e003c00, UMOV, instArgs{arg_Xd, arg_Vn_arrangement_imm5___D_8_index__imm5_1}, nil},
+	// MOV <Vd>.<t>, <Vn>.<t>
+	{0xbfe0fc00, 0x0ea01c00, MOV, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1}, mov_orr_asimdsame_only_cond},
+	// ORR <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x0ea01c00, ORR, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// MOVI <Vd>.<t_2>, #<imm8>{, LSL #0}
+	{0xbff8fc00, 0x0f00e400, MOVI, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_immediate_OptLSLZero__a_b_c_d_e_f_g_h}, nil},
+	// MOVI <Vd>.<t>, #<imm8>{, LSL #<amount>}
+	{0xbff8dc00, 0x0f008400, MOVI, instArgs{arg_Vd_arrangement_Q___4H_0__8H_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1}, nil},
+	// MOVI <Vd>.<t_1>, #<imm8>{, LSL #<amount>}
+	{0xbff89c00, 0x0f000400, MOVI, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3}, nil},
+	// MOVI <Vd>.<t_1>, #<imm8>, MSL #<amount>
+	{0xbff8ec00, 0x0f00c400, MOVI, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_MSL__a_b_c_d_e_f_g_h_cmode__8_0__16_1}, nil},
+	// MOVI <Dd>, #<imm>
+	{0xfff8fc00, 0x2f00e400, MOVI, instArgs{arg_Dd, arg_immediate_8x8_a_b_c_d_e_f_g_h}, nil},
+	// MOVI <Vd>.2D, #<imm>
+	{0xfff8fc00, 0x6f00e400, MOVI, instArgs{arg_Vd_arrangement_2D, arg_immediate_8x8_a_b_c_d_e_f_g_h}, nil},
+	// MUL <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf00f400, 0x0f008000, MUL, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// MUL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e209c00, MUL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// MVN <Vd>.<t>, <Vn>.<t>
+	{0xbffffc00, 0x2e205800, MVN, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1}, nil},
+	// NOT <Vd>.<t>, <Vn>.<t>
+	{0xbffffc00, 0x2e205800, NOT, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1}, nil},
+	// MVNI <Vd>.<t>, #<imm8>{, LSL #<amount>}
+	{0xbff8dc00, 0x2f008400, MVNI, instArgs{arg_Vd_arrangement_Q___4H_0__8H_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1}, nil},
+	// MVNI <Vd>.<t_1>, #<imm8>{, LSL #<amount>}
+	{0xbff89c00, 0x2f000400, MVNI, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3}, nil},
+	// MVNI <Vd>.<t_1>, #<imm8>, MSL #<amount>
+	{0xbff8ec00, 0x2f00c400, MVNI, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_MSL__a_b_c_d_e_f_g_h_cmode__8_0__16_1}, nil},
+	// NEG <V><d>, <V><n>
+	{0xff3ffc00, 0x7e20b800, NEG, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3}, nil},
+	// NEG <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e20b800, NEG, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// ORN <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbfe0fc00, 0x0ee01c00, ORN, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// ORR <Vd>.<t>, #<imm8>{, LSL #<amount>}
+	{0xbff8dc00, 0x0f009400, ORR, instArgs{arg_Vd_arrangement_Q___4H_0__8H_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1}, nil},
+	// ORR <Vd>.<t_1>, #<imm8>{, LSL #<amount>}
+	{0xbff89c00, 0x0f001400, ORR, instArgs{arg_Vd_arrangement_Q___2S_0__4S_1, arg_immediate_OptLSL__a_b_c_d_e_f_g_h_cmode__0_0__8_1__16_2__24_3}, nil},
+	// PMUL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e209c00, PMUL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01, arg_Vn_arrangement_size_Q___8B_00__16B_01, arg_Vm_arrangement_size_Q___8B_00__16B_01}, nil},
+	// PMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e20e000, PMULL, instArgs{arg_Vd_arrangement_size___8H_0__1Q_3, arg_Vn_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31}, nil},
+	// PMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e20e000, PMULL2, instArgs{arg_Vd_arrangement_size___8H_0__1Q_3, arg_Vn_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__1D_30__2D_31}, nil},
+	// RADDHN <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x2e204000, RADDHN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// RADDHN2 <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x6e204000, RADDHN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// RBIT <Vd>.<t>, <Vn>.<t>
+	{0xbffffc00, 0x2e605800, RBIT, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_arrangement_Q___8B_0__16B_1}, nil},
+	// REV16 <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e201800, REV16, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01, arg_Vn_arrangement_size_Q___8B_00__16B_01}, nil},
+	// REV32 <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e200800, REV32, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11}, nil},
+	// REV64 <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e200800, REV64, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// RSHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x0f008c00, RSHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, rshrn_asimdshf_n_cond},
+	// RSHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x4f008c00, RSHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, rshrn_asimdshf_n_cond},
+	// RSUBHN <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x2e206000, RSUBHN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// RSUBHN2 <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x6e206000, RSUBHN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SABA <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e207c00, SABA, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SABAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e205000, SABAL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SABAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e205000, SABAL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SABD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e207400, SABD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SABDL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e207000, SABDL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SABDL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e207000, SABDL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADALP <Vd>.<ta>, <Vn>.<tb>
+	{0xbf3ffc00, 0x0e206800, SADALP, instArgs{arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADDL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e200000, SADDL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADDL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e200000, SADDL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADDLP <Vd>.<ta>, <Vn>.<tb>
+	{0xbf3ffc00, 0x0e202800, SADDLP, instArgs{arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADDLV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e303800, SADDLV, instArgs{arg_Vd_22_2__H_0__S_1__D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// SADDW <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x0e201000, SADDW, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SADDW2 <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x4e201000, SADDW2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SCVTF <Sd>, <Wn>, #<fbits>
+	{0xffff0000, 0x1e020000, SCVTF, instArgs{arg_Sd, arg_Wn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// SCVTF <Dd>, <Wn>, #<fbits>
+	{0xffff0000, 0x1e420000, SCVTF, instArgs{arg_Dd, arg_Wn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// SCVTF <Sd>, <Xn>, #<fbits>
+	{0xffff0000, 0x9e020000, SCVTF, instArgs{arg_Sd, arg_Xn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// SCVTF <Dd>, <Xn>, #<fbits>
+	{0xffff0000, 0x9e420000, SCVTF, instArgs{arg_Dd, arg_Xn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// SCVTF <Sd>, <Wn>
+	{0xfffffc00, 0x1e220000, SCVTF, instArgs{arg_Sd, arg_Wn}, nil},
+	// SCVTF <Dd>, <Wn>
+	{0xfffffc00, 0x1e620000, SCVTF, instArgs{arg_Dd, arg_Wn}, nil},
+	// SCVTF <Sd>, <Xn>
+	{0xfffffc00, 0x9e220000, SCVTF, instArgs{arg_Sd, arg_Xn}, nil},
+	// SCVTF <Dd>, <Xn>
+	{0xfffffc00, 0x9e620000, SCVTF, instArgs{arg_Dd, arg_Xn}, nil},
+	// SCVTF <V><d>, <V><n>, #<fbits>
+	{0xff80fc00, 0x5f00e400, SCVTF, instArgs{arg_Vd_19_4__S_4__D_8, arg_Vn_19_4__S_4__D_8, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8}, scvtf_asisdshf_c_cond},
+	// SCVTF <Vd>.<t>, <Vn>.<t>, #<fbits>
+	{0xbf80fc00, 0x0f00e400, SCVTF, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8}, scvtf_asimdshf_c_cond},
+	// SCVTF <V><d>, <V><n>
+	{0xffbffc00, 0x5e21d800, SCVTF, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// SCVTF <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0e21d800, SCVTF, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// SHA1C <Qd>, <Sn>, <Vm>.4S
+	{0xffe0fc00, 0x5e000000, SHA1C, instArgs{arg_Qd, arg_Sn, arg_Vm_arrangement_4S}, nil},
+	// SHA1H <Sd>, <Sn>
+	{0xfffffc00, 0x5e280800, SHA1H, instArgs{arg_Sd, arg_Sn}, nil},
+	// SHA1M <Qd>, <Sn>, <Vm>.4S
+	{0xffe0fc00, 0x5e002000, SHA1M, instArgs{arg_Qd, arg_Sn, arg_Vm_arrangement_4S}, nil},
+	// SHA1P <Qd>, <Sn>, <Vm>.4S
+	{0xffe0fc00, 0x5e001000, SHA1P, instArgs{arg_Qd, arg_Sn, arg_Vm_arrangement_4S}, nil},
+	// SHA1SU0 <Vd>.4S, <Vn>.4S, <Vm>.4S
+	{0xffe0fc00, 0x5e003000, SHA1SU0, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S, arg_Vm_arrangement_4S}, nil},
+	// SHA1SU1 <Vd>.4S, <Vn>.4S
+	{0xfffffc00, 0x5e281800, SHA1SU1, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S}, nil},
+	// SHA256H <Qd>, <Qn>, <Vm>.4S
+	{0xffe0fc00, 0x5e004000, SHA256H, instArgs{arg_Qd, arg_Qn, arg_Vm_arrangement_4S}, nil},
+	// SHA256H2 <Qd>, <Qn>, <Vm>.4S
+	{0xffe0fc00, 0x5e005000, SHA256H2, instArgs{arg_Qd, arg_Qn, arg_Vm_arrangement_4S}, nil},
+	// SHA256SU0 <Vd>.4S, <Vn>.4S
+	{0xfffffc00, 0x5e282800, SHA256SU0, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S}, nil},
+	// SHA256SU1 <Vd>.4S, <Vn>.4S, <Vm>.4S
+	{0xffe0fc00, 0x5e006000, SHA256SU1, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S, arg_Vm_arrangement_4S}, nil},
+	// SHADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e200400, SHADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SHL <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f005400, SHL, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_0_63_immh_immb__UIntimmhimmb64_8}, shl_asisdshf_r_cond},
+	// SHL <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f005400, SHL, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, shl_asimdshf_r_cond},
+	// SHLL <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff3ffc00, 0x2e213800, SHLL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_immediate_0_width_size__8_0__16_1__32_2}, nil},
+	// SHLL2 <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff3ffc00, 0x6e213800, SHLL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_immediate_0_width_size__8_0__16_1__32_2}, nil},
+	// SHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x0f008400, SHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, shrn_asimdshf_n_cond},
+	// SHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x4f008400, SHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, shrn_asimdshf_n_cond},
+	// SHSUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e202400, SHSUB, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SLI <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f005400, SLI, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_0_63_immh_immb__UIntimmhimmb64_8}, sli_asisdshf_r_cond},
+	// SLI <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f005400, SLI, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, sli_asimdshf_r_cond},
+	// SMAX <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e206400, SMAX, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMAXP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e20a400, SMAXP, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMAXV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e30a800, SMAXV, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// SMIN <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e206c00, SMIN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMINP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e20ac00, SMINP, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMINV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e31a800, SMINV, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// SMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f002000, SMLAL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f002000, SMLAL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e208000, SMLAL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e208000, SMLAL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f006000, SMLSL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f006000, SMLSL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e20a000, SMLSL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e20a000, SMLSL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMOV <Wd>, <Vn>.<ts>[<index>]
+	{0xffe0fc00, 0x0e002c00, SMOV, instArgs{arg_Wd, arg_Vn_arrangement_imm5___B_1__H_2_index__imm5__imm5lt41gt_1__imm5lt42gt_2_1}, nil},
+	// SMOV <Xd>, <Vn>.<ts_1>[<index_1>]
+	{0xffe0fc00, 0x4e002c00, SMOV, instArgs{arg_Xd, arg_Vn_arrangement_imm5___B_1__H_2__S_4_index__imm5__imm5lt41gt_1__imm5lt42gt_2__imm5lt43gt_4_1}, nil},
+	// SMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f00a000, SMULL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f00a000, SMULL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e20c000, SMULL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e20c000, SMULL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQABS <V><d>, <V><n>
+	{0xff3ffc00, 0x5e207800, SQABS, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQABS <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e207800, SQABS, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQADD <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e200c00, SQADD, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e200c00, SQADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQDMLAL <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff00f400, 0x5f003000, SQDMLAL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f003000, SQDMLAL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f003000, SQDMLAL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLAL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e209000, SQDMLAL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_22_2__H_1__S_2}, nil},
+	// SQDMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e209000, SQDMLAL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e209000, SQDMLAL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMLSL <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff00f400, 0x5f007000, SQDMLSL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f007000, SQDMLSL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f007000, SQDMLSL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMLSL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e20b000, SQDMLSL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_22_2__H_1__S_2}, nil},
+	// SQDMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e20b000, SQDMLSL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e20b000, SQDMLSL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMULH <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff00f400, 0x5f00c000, SQDMULH, instArgs{arg_Vd_22_2__H_1__S_2, arg_Vn_22_2__H_1__S_2, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMULH <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf00f400, 0x0f00c000, SQDMULH, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMULH <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e20b400, SQDMULH, instArgs{arg_Vd_22_2__H_1__S_2, arg_Vn_22_2__H_1__S_2, arg_Vm_22_2__H_1__S_2}, nil},
+	// SQDMULH <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e20b400, SQDMULH, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMULL <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff00f400, 0x5f00b000, SQDMULL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x0f00b000, SQDMULL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x4f00b000, SQDMULL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQDMULL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e20d000, SQDMULL, instArgs{arg_Vd_22_2__S_1__D_2, arg_Vn_22_2__H_1__S_2, arg_Vm_22_2__H_1__S_2}, nil},
+	// SQDMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e20d000, SQDMULL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQDMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e20d000, SQDMULL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQNEG <V><d>, <V><n>
+	{0xff3ffc00, 0x7e207800, SQNEG, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQNEG <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e207800, SQNEG, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQRDMULH <V><d>, <V><n>, <Vm>.<ts_1>[<index_1>]
+	{0xff00f400, 0x5f00d000, SQRDMULH, instArgs{arg_Vd_22_2__H_1__S_2, arg_Vn_22_2__H_1__S_2, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQRDMULH <Vd>.<t>, <Vn>.<t>, <Vm>.<ts>[<index>]
+	{0xbf00f400, 0x0f00d000, SQRDMULH, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// SQRDMULH <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e20b400, SQRDMULH, instArgs{arg_Vd_22_2__H_1__S_2, arg_Vn_22_2__H_1__S_2, arg_Vm_22_2__H_1__S_2}, nil},
+	// SQRDMULH <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e20b400, SQRDMULH, instArgs{arg_Vd_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21}, nil},
+	// SQRSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e205c00, SQRSHL, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQRSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e205c00, SQRSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQRSHRN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f009c00, SQRSHRN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrn_asisdshf_n_cond},
+	// SQRSHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x0f009c00, SQRSHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrn_asimdshf_n_cond},
+	// SQRSHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x4f009c00, SQRSHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrn_asimdshf_n_cond},
+	// SQRSHRUN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f008c00, SQRSHRUN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrun_asisdshf_n_cond},
+	// SQRSHRUN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x2f008c00, SQRSHRUN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrun_asimdshf_n_cond},
+	// SQRSHRUN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x6f008c00, SQRSHRUN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqrshrun_asimdshf_n_cond},
+	// SQSHL <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f007400, SQSHL, instArgs{arg_Vd_19_4__B_1__H_2__S_4__D_8, arg_Vn_19_4__B_1__H_2__S_4__D_8, arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, sqshl_asisdshf_r_cond},
+	// SQSHL <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f007400, SQSHL, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, sqshl_asimdshf_r_cond},
+	// SQSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e204c00, SQSHL, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e204c00, SQSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQSHLU <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f006400, SQSHLU, instArgs{arg_Vd_19_4__B_1__H_2__S_4__D_8, arg_Vn_19_4__B_1__H_2__S_4__D_8, arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, sqshlu_asisdshf_r_cond},
+	// SQSHLU <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f006400, SQSHLU, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, sqshlu_asimdshf_r_cond},
+	// SQSHRN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f009400, SQSHRN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrn_asisdshf_n_cond},
+	// SQSHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x0f009400, SQSHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrn_asimdshf_n_cond},
+	// SQSHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x4f009400, SQSHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrn_asimdshf_n_cond},
+	// SQSHRUN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f008400, SQSHRUN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrun_asisdshf_n_cond},
+	// SQSHRUN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x2f008400, SQSHRUN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrun_asimdshf_n_cond},
+	// SQSHRUN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x6f008400, SQSHRUN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, sqshrun_asimdshf_n_cond},
+	// SQSUB <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e202c00, SQSUB, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SQSUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e202c00, SQSUB, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SQXTN <V><d>, <V><n>
+	{0xff3ffc00, 0x5e214800, SQXTN, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_22_2__H_0__S_1__D_2}, nil},
+	// SQXTN <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x0e214800, SQXTN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SQXTN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x4e214800, SQXTN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SQXTUN <V><d>, <V><n>
+	{0xff3ffc00, 0x7e212800, SQXTUN, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_22_2__H_0__S_1__D_2}, nil},
+	// SQXTUN <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x2e212800, SQXTUN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SQXTUN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x6e212800, SQXTUN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SRHADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e201400, SRHADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SRI <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f004400, SRI, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, sri_asisdshf_r_cond},
+	// SRI <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f004400, SRI, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, sri_asimdshf_r_cond},
+	// SRSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e205400, SRSHL, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// SRSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e205400, SRSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SRSHR <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f002400, SRSHR, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, srshr_asisdshf_r_cond},
+	// SRSHR <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f002400, SRSHR, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, srshr_asimdshf_r_cond},
+	// SRSRA <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f003400, SRSRA, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, srsra_asisdshf_r_cond},
+	// SRSRA <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f003400, SRSRA, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, srsra_asimdshf_r_cond},
+	// SSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x5e204400, SSHL, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// SSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e204400, SSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SXTL <Vd>.<ta>, <Vn>.<tb>
+	{0xff87fc00, 0x0f00a400, SXTL, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41}, sxtl_sshll_asimdshf_l_cond},
+	// SXTL2 <Vd>.<ta>, <Vn>.<tb>
+	{0xff87fc00, 0x4f00a400, SXTL2, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41}, sxtl_sshll_asimdshf_l_cond},
+	// SSHLL <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff80fc00, 0x0f00a400, SSHLL, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4}, sshll_asimdshf_l_cond},
+	// SSHLL2 <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff80fc00, 0x4f00a400, SSHLL2, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4}, sshll_asimdshf_l_cond},
+	// SSHR <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f000400, SSHR, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, sshr_asisdshf_r_cond},
+	// SSHR <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f000400, SSHR, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, sshr_asimdshf_r_cond},
+	// SSRA <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x5f001400, SSRA, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, ssra_asisdshf_r_cond},
+	// SSRA <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x0f001400, SSRA, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, ssra_asimdshf_r_cond},
+	// SSUBL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x0e202000, SSUBL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SSUBL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x4e202000, SSUBL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SSUBW <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x0e203000, SSUBW, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// SSUBW2 <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x4e203000, SSUBW2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c007000, ST1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c00a000, ST1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c006000, ST1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c002000, ST1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0c9f7000, ST1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__8_0__16_1}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c807000, ST1, instArgs{arg_Vt_1_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<imm_1>
+	{0xbffff000, 0x0c9fa000, ST1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__16_0__32_1}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c80a000, ST1, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<imm_2>
+	{0xbffff000, 0x0c9f6000, ST1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__24_0__48_1}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c806000, ST1, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<imm_3>
+	{0xbffff000, 0x0c9f2000, ST1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Q__32_0__64_1}, nil},
+	// ST1 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c802000, ST1, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__1D_30__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d000000, ST1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d004000, ST1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d008000, ST1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d008400, ST1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// ST1 <Vt>.B[<index>], [<Xn|SP>], #1
+	{0xbfffe000, 0x0d9f0000, ST1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_1}, nil},
+	// ST1 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0d800000, ST1, instArgs{arg_Vt_1_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.H[<index_2>], [<Xn|SP>], #2
+	{0xbfffe400, 0x0d9f4000, ST1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_2}, nil},
+	// ST1 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0d804000, ST1, instArgs{arg_Vt_1_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.S[<index_3>], [<Xn|SP>], #4
+	{0xbfffec00, 0x0d9f8000, ST1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// ST1 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0d808000, ST1, instArgs{arg_Vt_1_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// ST1 <Vt>.D[<index_1>], [<Xn|SP>], #8
+	{0xbffffc00, 0x0d9f8400, ST1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// ST1 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0d808400, ST1, instArgs{arg_Vt_1_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// ST2 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c008000, ST2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// ST2 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0c9f8000, ST2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__16_0__32_1}, nil},
+	// ST2 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c808000, ST2, instArgs{arg_Vt_2_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST2 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d200000, ST2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST2 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d204000, ST2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST2 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d208000, ST2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// ST2 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d208400, ST2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// ST2 <Vt>.B[<index>], [<Xn|SP>], #2
+	{0xbfffe000, 0x0dbf0000, ST2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_2}, nil},
+	// ST2 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0da00000, ST2, instArgs{arg_Vt_2_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST2 <Vt>.H[<index_2>], [<Xn|SP>], #4
+	{0xbfffe400, 0x0dbf4000, ST2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// ST2 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0da04000, ST2, instArgs{arg_Vt_2_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST2 <Vt>.S[<index_3>], [<Xn|SP>], #8
+	{0xbfffec00, 0x0dbf8000, ST2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// ST2 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0da08000, ST2, instArgs{arg_Vt_2_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// ST2 <Vt>.D[<index_1>], [<Xn|SP>], #16
+	{0xbffffc00, 0x0dbf8400, ST2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_16}, nil},
+	// ST2 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0da08400, ST2, instArgs{arg_Vt_2_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// ST3 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c004000, ST3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// ST3 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0c9f4000, ST3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__24_0__48_1}, nil},
+	// ST3 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c804000, ST3, instArgs{arg_Vt_3_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST3 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d002000, ST3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST3 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d006000, ST3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST3 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d00a000, ST3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// ST3 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d00a400, ST3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// ST3 <Vt>.B[<index>], [<Xn|SP>], #3
+	{0xbfffe000, 0x0d9f2000, ST3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_3}, nil},
+	// ST3 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0d802000, ST3, instArgs{arg_Vt_3_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST3 <Vt>.H[<index_2>], [<Xn|SP>], #6
+	{0xbfffe400, 0x0d9f6000, ST3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_6}, nil},
+	// ST3 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0d806000, ST3, instArgs{arg_Vt_3_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST3 <Vt>.S[<index_3>], [<Xn|SP>], #12
+	{0xbfffec00, 0x0d9fa000, ST3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_12}, nil},
+	// ST3 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0d80a000, ST3, instArgs{arg_Vt_3_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// ST3 <Vt>.D[<index_1>], [<Xn|SP>], #24
+	{0xbffffc00, 0x0d9fa400, ST3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_24}, nil},
+	// ST3 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0d80a400, ST3, instArgs{arg_Vt_3_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// ST4 <Vt>.<t>, [<Xn|SP>]
+	{0xbffff000, 0x0c000000, ST4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_offset}, nil},
+	// ST4 <Vt>.<t>, [<Xn|SP>], #<imm>
+	{0xbffff000, 0x0c9f0000, ST4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Q__32_0__64_1}, nil},
+	// ST4 <Vt>.<t>, [<Xn|SP>], #<Xm>
+	{0xbfe0f000, 0x0c800000, ST4, instArgs{arg_Vt_4_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Xns_mem_post_Xm}, nil},
+	// ST4 <Vt>.B[<index>], [<Xn|SP>]
+	{0xbfffe000, 0x0d202000, ST4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST4 <Vt>.H[<index_2>], [<Xn|SP>]
+	{0xbfffe400, 0x0d206000, ST4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_offset}, nil},
+	// ST4 <Vt>.S[<index_3>], [<Xn|SP>]
+	{0xbfffec00, 0x0d20a000, ST4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_offset}, nil},
+	// ST4 <Vt>.D[<index_1>], [<Xn|SP>]
+	{0xbffffc00, 0x0d20a400, ST4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_offset}, nil},
+	// ST4 <Vt>.B[<index>], [<Xn|SP>], #4
+	{0xbfffe000, 0x0dbf2000, ST4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_4}, nil},
+	// ST4 <Vt>.B[<index>], [<Xn|SP>], #<Xm>
+	{0xbfe0e000, 0x0da02000, ST4, instArgs{arg_Vt_4_arrangement_B_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST4 <Vt>.H[<index_2>], [<Xn|SP>], #8
+	{0xbfffe400, 0x0dbf6000, ST4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_fixedimm_8}, nil},
+	// ST4 <Vt>.H[<index_2>], [<Xn|SP>], #<Xm>
+	{0xbfe0e400, 0x0da06000, ST4, instArgs{arg_Vt_4_arrangement_H_index__Q_S_size_1, arg_Xns_mem_post_Xm}, nil},
+	// ST4 <Vt>.S[<index_3>], [<Xn|SP>], #16
+	{0xbfffec00, 0x0dbfa000, ST4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_post_fixedimm_16}, nil},
+	// ST4 <Vt>.S[<index_3>], [<Xn|SP>], #<Xm>
+	{0xbfe0ec00, 0x0da0a000, ST4, instArgs{arg_Vt_4_arrangement_S_index__Q_S_1, arg_Xns_mem_post_Xm}, nil},
+	// ST4 <Vt>.D[<index_1>], [<Xn|SP>], #32
+	{0xbffffc00, 0x0dbfa400, ST4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_post_fixedimm_32}, nil},
+	// ST4 <Vt>.D[<index_1>], [<Xn|SP>], #<Xm>
+	{0xbfe0fc00, 0x0da0a400, ST4, instArgs{arg_Vt_4_arrangement_D_index__Q_1, arg_Xns_mem_post_Xm}, nil},
+	// STNP <St>, <St2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0x2c000000, STNP, instArgs{arg_St, arg_St2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// STNP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x6c000000, STNP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// STNP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_1>}]
+	{0xffc00000, 0xac000000, STNP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_optional_imm7_16_signed}, nil},
+	// STP <St>, <St2>, [<Xn|SP>], #<imm_5>
+	{0xffc00000, 0x2c800000, STP, instArgs{arg_St, arg_St2, arg_Xns_mem_post_imm7_4_signed}, nil},
+	// STP <Dt>, <Dt2>, [<Xn|SP>], #<imm_1>
+	{0xffc00000, 0x6c800000, STP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_post_imm7_8_signed}, nil},
+	// STP <Qt>, <Qt2>, [<Xn|SP>], #<imm_3>
+	{0xffc00000, 0xac800000, STP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_post_imm7_16_signed}, nil},
+	// STP <St>, <St2>, [<Xn|SP>{, #<imm_5>}]!
+	{0xffc00000, 0x2d800000, STP, instArgs{arg_St, arg_St2, arg_Xns_mem_wb_imm7_4_signed}, nil},
+	// STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm_1>}]!
+	{0xffc00000, 0x6d800000, STP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_wb_imm7_8_signed}, nil},
+	// STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_3>}]!
+	{0xffc00000, 0xad800000, STP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_wb_imm7_16_signed}, nil},
+	// STP <St>, <St2>, [<Xn|SP>{, #<imm_4>}]
+	{0xffc00000, 0x2d000000, STP, instArgs{arg_St, arg_St2, arg_Xns_mem_optional_imm7_4_signed}, nil},
+	// STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]
+	{0xffc00000, 0x6d000000, STP, instArgs{arg_Dt, arg_Dt2, arg_Xns_mem_optional_imm7_8_signed}, nil},
+	// STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm_2>}]
+	{0xffc00000, 0xad000000, STP, instArgs{arg_Qt, arg_Qt2, arg_Xns_mem_optional_imm7_16_signed}, nil},
+	// STR <Bt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x3c000400, STR, instArgs{arg_Bt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Ht>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x7c000400, STR, instArgs{arg_Ht, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <St>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xbc000400, STR, instArgs{arg_St, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Dt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0xfc000400, STR, instArgs{arg_Dt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Qt>, [<Xn|SP>], #<simm>
+	{0xffe00c00, 0x3c800400, STR, instArgs{arg_Qt, arg_Xns_mem_post_imm9_1_signed}, nil},
+	// STR <Bt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x3c000c00, STR, instArgs{arg_Bt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Ht>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x7c000c00, STR, instArgs{arg_Ht, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <St>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xbc000c00, STR, instArgs{arg_St, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Dt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0xfc000c00, STR, instArgs{arg_Dt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Qt>, [<Xn|SP>{, #<simm>}]!
+	{0xffe00c00, 0x3c800c00, STR, instArgs{arg_Qt, arg_Xns_mem_wb_imm9_1_signed}, nil},
+	// STR <Bt>, [<Xn|SP>{, #<pimm>}]
+	{0xffc00000, 0x3d000000, STR, instArgs{arg_Bt, arg_Xns_mem_optional_imm12_1_unsigned}, nil},
+	// STR <Ht>, [<Xn|SP>{, #<pimm_2>}]
+	{0xffc00000, 0x7d000000, STR, instArgs{arg_Ht, arg_Xns_mem_optional_imm12_2_unsigned}, nil},
+	// STR <St>, [<Xn|SP>{, #<pimm_4>}]
+	{0xffc00000, 0xbd000000, STR, instArgs{arg_St, arg_Xns_mem_optional_imm12_4_unsigned}, nil},
+	// STR <Dt>, [<Xn|SP>{, #<pimm_1>}]
+	{0xffc00000, 0xfd000000, STR, instArgs{arg_Dt, arg_Xns_mem_optional_imm12_8_unsigned}, nil},
+	// STR <Qt>, [<Xn|SP>{, #<pimm_3>}]
+	{0xffc00000, 0x3d800000, STR, instArgs{arg_Qt, arg_Xns_mem_optional_imm12_16_unsigned}, nil},
+	// STR <Bt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x3c200800, STR, instArgs{arg_Bt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__absent_0__0_1}, nil},
+	// STR <Ht>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x7c200800, STR, instArgs{arg_Ht, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__1_1}, nil},
+	// STR <St>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xbc200800, STR, instArgs{arg_St, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__2_1}, nil},
+	// STR <Dt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0xfc200800, STR, instArgs{arg_Dt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__3_1}, nil},
+	// STR <Qt>, [<Xn|SP>, (<Wm>|<Xm>) {, <extend> {<amount>}}]
+	{0xffe00c00, 0x3ca00800, STR, instArgs{arg_Qt, arg_Xns_mem_extend_m__UXTW_2__LSL_3__SXTW_6__SXTX_7__0_0__4_1}, nil},
+	// STUR <Bt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x3c000000, STUR, instArgs{arg_Bt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <Ht>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x7c000000, STUR, instArgs{arg_Ht, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <St>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xbc000000, STUR, instArgs{arg_St, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <Dt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0xfc000000, STUR, instArgs{arg_Dt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// STUR <Qt>, [<Xn|SP>{, #<simm>}]
+	{0xffe00c00, 0x3c800000, STUR, instArgs{arg_Qt, arg_Xns_mem_optional_imm9_1_signed}, nil},
+	// SUB <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e208400, SUB, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// SUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e208400, SUB, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// SUBHN <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x0e206000, SUBHN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SUBHN2 <Vd>.<tb>, <Vn>.<ta>, <Vm>.<ta>
+	{0xff20fc00, 0x4e206000, SUBHN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// SUQADD <V><d>, <V><n>
+	{0xff3ffc00, 0x5e203800, SUQADD, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3}, nil},
+	// SUQADD <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x0e203800, SUQADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// TBL <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e002000, TBL, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_2_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBL <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e004000, TBL, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_3_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBL <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e006000, TBL, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_4_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBL <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e000000, TBL, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_1_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBX <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e003000, TBX, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_2_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBX <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e005000, TBX, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_3_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBX <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e007000, TBX, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_4_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TBX <Vd>.<ta>, <Vn>.16B, <Vm>.<ta>
+	{0xbfe0fc00, 0x0e001000, TBX, instArgs{arg_Vd_arrangement_Q___8B_0__16B_1, arg_Vn_1_arrangement_16B, arg_Vm_arrangement_Q___8B_0__16B_1}, nil},
+	// TRN1 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e002800, TRN1, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// TRN2 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e006800, TRN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UABA <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e207c00, UABA, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UABAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e205000, UABAL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UABAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e205000, UABAL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UABD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e207400, UABD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UABDL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e207000, UABDL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UABDL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e207000, UABDL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADALP <Vd>.<ta>, <Vn>.<tb>
+	{0xbf3ffc00, 0x2e206800, UADALP, instArgs{arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADDL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e200000, UADDL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADDL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e200000, UADDL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADDLP <Vd>.<ta>, <Vn>.<tb>
+	{0xbf3ffc00, 0x2e202800, UADDLP, instArgs{arg_Vd_arrangement_size_Q___4H_00__8H_01__2S_10__4S_11__1D_20__2D_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADDLV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e303800, UADDLV, instArgs{arg_Vd_22_2__H_0__S_1__D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// UADDW <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x2e201000, UADDW, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UADDW2 <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x6e201000, UADDW2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UCVTF <Sd>, <Wn>, #<fbits>
+	{0xffff0000, 0x1e030000, UCVTF, instArgs{arg_Sd, arg_Wn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// UCVTF <Dd>, <Wn>, #<fbits>
+	{0xffff0000, 0x1e430000, UCVTF, instArgs{arg_Dd, arg_Wn, arg_immediate_fbits_min_1_max_32_sub_64_scale}, nil},
+	// UCVTF <Sd>, <Xn>, #<fbits>
+	{0xffff0000, 0x9e030000, UCVTF, instArgs{arg_Sd, arg_Xn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// UCVTF <Dd>, <Xn>, #<fbits>
+	{0xffff0000, 0x9e430000, UCVTF, instArgs{arg_Dd, arg_Xn, arg_immediate_fbits_min_1_max_64_sub_64_scale}, nil},
+	// UCVTF <Sd>, <Wn>
+	{0xfffffc00, 0x1e230000, UCVTF, instArgs{arg_Sd, arg_Wn}, nil},
+	// UCVTF <Dd>, <Wn>
+	{0xfffffc00, 0x1e630000, UCVTF, instArgs{arg_Dd, arg_Wn}, nil},
+	// UCVTF <Sd>, <Xn>
+	{0xfffffc00, 0x9e230000, UCVTF, instArgs{arg_Sd, arg_Xn}, nil},
+	// UCVTF <Dd>, <Xn>
+	{0xfffffc00, 0x9e630000, UCVTF, instArgs{arg_Dd, arg_Xn}, nil},
+	// UCVTF <V><d>, <V><n>, #<fbits>
+	{0xff80fc00, 0x7f00e400, UCVTF, instArgs{arg_Vd_19_4__S_4__D_8, arg_Vn_19_4__S_4__D_8, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__64UIntimmhimmb_4__128UIntimmhimmb_8}, ucvtf_asisdshf_c_cond},
+	// UCVTF <Vd>.<t>, <Vn>.<t>, #<fbits>
+	{0xbf80fc00, 0x2f00e400, UCVTF, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__2S_40__4S_41__2D_81, arg_immediate_fbits_min_1_max_0_sub_0_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__64UIntimmhimmb_4__128UIntimmhimmb_8}, ucvtf_asimdshf_c_cond},
+	// UCVTF <V><d>, <V><n>
+	{0xffbffc00, 0x7e21d800, UCVTF, instArgs{arg_Vd_22_1__S_0__D_1, arg_Vn_22_1__S_0__D_1}, nil},
+	// UCVTF <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2e21d800, UCVTF, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01__2D_11, arg_Vn_arrangement_sz_Q___2S_00__4S_01__2D_11}, nil},
+	// UHADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e200400, UHADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UHSUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e202400, UHSUB, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMAX <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e206400, UMAX, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMAXP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e20a400, UMAXP, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMAXV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e30a800, UMAXV, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// UMIN <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e206c00, UMIN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMINP <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e20ac00, UMINP, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMINV <V><d>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e31a800, UMINV, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__4S_21}, nil},
+	// UMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x2f002000, UMLAL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x6f002000, UMLAL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMLAL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e208000, UMLAL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMLAL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e208000, UMLAL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x2f006000, UMLSL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x6f006000, UMLSL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMLSL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e20a000, UMLSL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMLSL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e20a000, UMLSL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x2f00a000, UMULL, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<ts>[<index>]
+	{0xff00f400, 0x6f00a000, UMULL2, instArgs{arg_Vd_arrangement_size___4S_1__2D_2, arg_Vn_arrangement_size_Q___4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size___H_1__S_2_index__size_L_H_M__HLM_1__HL_2_1}, nil},
+	// UMULL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e20c000, UMULL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UMULL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e20c000, UMULL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UQADD <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e200c00, UQADD, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// UQADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e200c00, UQADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UQRSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e205c00, UQRSHL, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// UQRSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e205c00, UQRSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UQRSHRN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f009c00, UQRSHRN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqrshrn_asisdshf_n_cond},
+	// UQRSHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x2f009c00, UQRSHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqrshrn_asimdshf_n_cond},
+	// UQRSHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x6f009c00, UQRSHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqrshrn_asimdshf_n_cond},
+	// UQSHL <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f007400, UQSHL, instArgs{arg_Vd_19_4__B_1__H_2__S_4__D_8, arg_Vn_19_4__B_1__H_2__S_4__D_8, arg_immediate_0_width_m1_immh_immb__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, uqshl_asisdshf_r_cond},
+	// UQSHL <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f007400, UQSHL, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4__UIntimmhimmb64_8}, uqshl_asimdshf_r_cond},
+	// UQSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e204c00, UQSHL, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// UQSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e204c00, UQSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UQSHRN <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f009400, UQSHRN, instArgs{arg_Vd_19_4__B_1__H_2__S_4, arg_Vn_19_4__H_1__S_2__D_4, arg_immediate_1_width_immh_immb__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqshrn_asisdshf_n_cond},
+	// UQSHRN <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x2f009400, UQSHRN, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqshrn_asimdshf_n_cond},
+	// UQSHRN2 <Vd>.<tb>, <Vn>.<ta>, #<shift>
+	{0xff80fc00, 0x6f009400, UQSHRN2, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_Vn_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4}, uqshrn_asimdshf_n_cond},
+	// UQSUB <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e202c00, UQSUB, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3, arg_Vm_22_2__B_0__H_1__S_2__D_3}, nil},
+	// UQSUB <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e202c00, UQSUB, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UQXTN <V><d>, <V><n>
+	{0xff3ffc00, 0x7e214800, UQXTN, instArgs{arg_Vd_22_2__B_0__H_1__S_2, arg_Vn_22_2__H_0__S_1__D_2}, nil},
+	// UQXTN <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x2e214800, UQXTN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// UQXTN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x6e214800, UQXTN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// URECPE <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x0ea1c800, URECPE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01, arg_Vn_arrangement_sz_Q___2S_00__4S_01}, nil},
+	// URHADD <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e201400, URHADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// URSHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e205400, URSHL, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// URSHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e205400, URSHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// URSHR <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f002400, URSHR, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, urshr_asisdshf_r_cond},
+	// URSHR <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f002400, URSHR, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, urshr_asimdshf_r_cond},
+	// URSQRTE <Vd>.<t>, <Vn>.<t>
+	{0xbfbffc00, 0x2ea1c800, URSQRTE, instArgs{arg_Vd_arrangement_sz_Q___2S_00__4S_01, arg_Vn_arrangement_sz_Q___2S_00__4S_01}, nil},
+	// URSRA <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f003400, URSRA, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, ursra_asisdshf_r_cond},
+	// URSRA <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f003400, URSRA, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, ursra_asimdshf_r_cond},
+	// USHL <V><d>, <V><n>, <V><m>
+	{0xff20fc00, 0x7e204400, USHL, instArgs{arg_Vd_22_2__D_3, arg_Vn_22_2__D_3, arg_Vm_22_2__D_3}, nil},
+	// USHL <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x2e204400, USHL, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UXTL <Vd>.<ta>, <Vn>.<tb>
+	{0xff87fc00, 0x2f00a400, UXTL, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41}, uxtl_ushll_asimdshf_l_cond},
+	// UXTL2 <Vd>.<ta>, <Vn>.<tb>
+	{0xff87fc00, 0x6f00a400, UXTL2, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41}, uxtl_ushll_asimdshf_l_cond},
+	// USHLL <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff80fc00, 0x2f00a400, USHLL, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4}, ushll_asimdshf_l_cond},
+	// USHLL2 <Vd>.<ta>, <Vn>.<tb>, #<shift>
+	{0xff80fc00, 0x6f00a400, USHLL2, instArgs{arg_Vd_arrangement_immh___SEEAdvancedSIMDmodifiedimmediate_0__8H_1__4S_2__2D_4, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41, arg_immediate_0_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__UIntimmhimmb8_1__UIntimmhimmb16_2__UIntimmhimmb32_4}, ushll_asimdshf_l_cond},
+	// USHR <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f000400, USHR, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, ushr_asisdshf_r_cond},
+	// USHR <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f000400, USHR, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, ushr_asimdshf_r_cond},
+	// USQADD <V><d>, <V><n>
+	{0xff3ffc00, 0x7e203800, USQADD, instArgs{arg_Vd_22_2__B_0__H_1__S_2__D_3, arg_Vn_22_2__B_0__H_1__S_2__D_3}, nil},
+	// USQADD <Vd>.<t>, <Vn>.<t>
+	{0xbf3ffc00, 0x2e203800, USQADD, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// USRA <V><d>, <V><n>, #<shift>
+	{0xff80fc00, 0x7f001400, USRA, instArgs{arg_Vd_19_4__D_8, arg_Vn_19_4__D_8, arg_immediate_1_64_immh_immb__128UIntimmhimmb_8}, usra_asisdshf_r_cond},
+	// USRA <Vd>.<t>, <Vn>.<t>, #<shift>
+	{0xbf80fc00, 0x2f001400, USRA, instArgs{arg_Vd_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_Vn_arrangement_immh_Q___SEEAdvancedSIMDmodifiedimmediate_00__8B_10__16B_11__4H_20__8H_21__2S_40__4S_41__2D_81, arg_immediate_1_width_immh_immb__SEEAdvancedSIMDmodifiedimmediate_0__16UIntimmhimmb_1__32UIntimmhimmb_2__64UIntimmhimmb_4__128UIntimmhimmb_8}, usra_asimdshf_r_cond},
+	// USUBL <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x2e202000, USUBL, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// USUBL2 <Vd>.<ta>, <Vn>.<tb>, <Vm>.<tb>
+	{0xff20fc00, 0x6e202000, USUBL2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// USUBW <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x2e203000, USUBW, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// USUBW2 <Vd>.<ta>, <Vn>.<ta>, <Vm>.<tb>
+	{0xff20fc00, 0x6e203000, USUBW2, instArgs{arg_Vd_arrangement_size___8H_0__4S_1__2D_2, arg_Vn_arrangement_size___8H_0__4S_1__2D_2, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21}, nil},
+	// UZP1 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e001800, UZP1, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// UZP2 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e005800, UZP2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// XTN <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x0e212800, XTN, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// XTN2 <Vd>.<tb>, <Vn>.<ta>
+	{0xff3ffc00, 0x4e212800, XTN2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21, arg_Vn_arrangement_size___8H_0__4S_1__2D_2}, nil},
+	// ZIP1 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e003800, ZIP1, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+	// ZIP2 <Vd>.<t>, <Vn>.<t>, <Vm>.<t>
+	{0xbf20fc00, 0x0e007800, ZIP2, instArgs{arg_Vd_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vn_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31, arg_Vm_arrangement_size_Q___8B_00__16B_01__4H_10__8H_11__2S_20__4S_21__2D_31}, nil},
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/Makefile b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/Makefile
new file mode 100644
index 0000000..914a9a0
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/Makefile
@@ -0,0 +1,7 @@
+go test command:
+	cd ..; go test -run 'ObjdumpARM64Cond' -v -timeout 10h -long 2>&1 | tee log
+	cd ..; go test -run 'ObjdumpARM64Testdata' -v -timeout 10h -long 2>&1 | tee -a log
+	cd ..; go test -run 'ObjdumpARM64' -v -timeout 10h -long 2>&1 | tee -a log
+	cd ..; go test -run 'ObjdumpARM64Manual' -v -timeout 10h -long 2>&1 | tee -a log
+	cd ..; go test -run 'TestDecode'
+	cd ..; go test -run '.*'
diff --git a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/cases.txt b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/cases.txt
new file mode 100644
index 0000000..57795dd
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/testdata/cases.txt
@@ -0,0 +1,9203 @@
+0a011f1a|	gnu	adc w10, w8, wzr
+4c00009a|	gnu	adc x12, x2, x0
+a602093a|	gnu	adcs w6, w21, w9
+d60217ba|	gnu	adcs x22, x22, x23
+0921250b|	gnu	add w9, w8, w5, uxth
+ee9e288b|	gnu	add x14, x23, w8, sxtb #7
+23123011|	gnu	add w3, w17, #0xc04
+2ba32391|	gnu	add x11, x25, #0x8e8
+67158d0b|	gnu	add w7, w11, w13, asr #5
+30da198b|	gnu	add x16, x17, x25, lsl #54
+a7e72c2b|	gnu	adds w7, w29, w12, sxtx #1
+357338ab|	gnu	adds x21, x25, x24, uxtx #4
+6b147731|	gnu	adds w11, w3, #0xdc5, lsl #12
+cd59872b|	gnu	adds w13, w14, w7, asr #22
+e41f4eab|	gnu	adds x4, xzr, x14, lsr #7
+b7dd8470|	gnu	adr x23, .+0xfffffffffff09bb7
+0f4996d0|	gnu	adrp x15, .+0xffffffff2c922000
+a2432412|	gnu	and w2, w29, #0xf0001fff
+93910e92|	gnu	and x19, x12, #0x7c007c007c007c
+7a1ec98a|	gnu	and x26, x19, x9, ror #7
+1ff32972|	gnu	tst w24, #0xaaaaaaaa
+458051f2|	gnu	ands x5, x2, #0xffff80000000ffff
+af629a6a|	gnu	ands w15, w21, w26, asr #24
+7ab0dfea|	gnu	ands x26, x3, xzr, ror #44
+792bcc1a|	gnu	asr w25, w27, w12
+872bce9a|	gnu	asr x7, x28, x14
+99ff4b93|	gnu	asr x25, x28, #11
+1628c91a|	gnu	asr w22, w0, w9
+4e2acf9a|	gnu	asr x14, x18, x15
+4be5a454|	gnu	b.lt .+0xfffffffffff49ca8
+53257114|	gnu	b .+0x1c4954c
+dbb557b3|	gnu	bfxil x27, x14, #23, #23
+70e861b3|	gnu	bfxil x16, x3, #33, #26
+88a75ab3|	gnu	bfxil x8, x28, #26, #16
+b03ce70a|	gnu	bic w16, w5, w7, ror #15
+9235ec8a|	gnu	bic x18, x12, x12, ror #13
+7450b96a|	gnu	bics w20, w3, w25, asr #20
+3730b3ea|	gnu	bics x23, x1, x19, asr #12
+9b897797|	gnu	bl .+0xfffffffffdde266c
+e0013fd6|	gnu	blr x15
+a0031fd6|	gnu	br x29
+e08c31d4|	gnu	brk #0x8c67
+027eb435|	gnu	cbnz w2, .+0xfffffffffff68fc0
+c7eb42b5|	gnu	cbnz x7, .+0x85d78
+8f1d4c34|	gnu	cbz w15, .+0x983b0
+e1c5abb4|	gnu	cbz x1, .+0xfffffffffff578bc
+4bfb543a|	gnu	ccmn w26, #0x14, #0xb, al
+015b46ba|	gnu	ccmn x24, #0x6, #0x1, pl
+8602463a|	gnu	ccmn w20, w6, #0x6, eq
+c6d34cba|	gnu	ccmn x30, x12, #0x6, le
+a76b4f7a|	gnu	ccmp w29, #0xf, #0x7, vs
+e3d853fa|	gnu	ccmp x7, #0x13, #0x3, le
+4022467a|	gnu	ccmp w18, w6, #0x0, cs
+c7b346fa|	gnu	ccmp x30, x6, #0x7, lt
+ee279b1a|	gnu	csinc w14, wzr, w27, cs
+4174819a|	gnu	csinc x1, x2, x1, vc
+5100955a|	gnu	csinv w17, w2, w21, eq
+573093da|	gnu	csinv x23, x2, x19, cc
+5f3403d5|	gnu	clrex #0x4
+e615c05a|	gnu	cls w6, w15
+ff15c0da|	gnu	cls xzr, x15
+2e10c05a|	gnu	clz w14, w1
+a912c0da|	gnu	clz x9, x21
+ff11352b|	gnu	cmn w15, w21, uxtb #4
+1f5220ab|	gnu	cmn x16, w0, uxtw #4
+ff02266b|	gnu	cmp w23, w6, uxtb
+5fb739eb|	gnu	cmp x26, w25, sxth #5
+bfa73bf1|	gnu	cmp x29, #0xee9
+7f5c47eb|	gnu	cmp x3, x7, lsr #23
+2e458e5a|	gnu	csneg w14, w9, w14, mi
+c3559cda|	gnu	csneg x3, x14, x28, pl
+1041d11a|	gnu	crc32b w16, w8, w17
+bb46c31a|	gnu	crc32h w27, w21, w3
+c94bd61a|	gnu	crc32w w9, w30, w22
+8f4cd49a|	gnu	crc32x w15, w4, x20
+7653d21a|	gnu	crc32cb w22, w27, w18
+1454d51a|	gnu	crc32ch w20, w0, w21
+7c58c91a|	gnu	crc32cw w28, w3, w9
+185ccb9a|	gnu	crc32cx w24, w0, x11
+8c30941a|	gnu	csel w12, w4, w20, cc
+0ea08c9a|	gnu	csel x14, x0, x12, ge
+e3b79f1a|	gnu	cset w3, ge
+fea79f9a|	gnu	cset x30, lt
+e5639f5a|	gnu	csetm w5, vc
+e4739fda|	gnu	csetm x4, vs
+bad4981a|	gnu	csinc w26, w5, w24, le
+5167909a|	gnu	csinc x17, x26, x16, vs
+65e3955a|	gnu	csinv w5, w27, w21, al
+8e338bda|	gnu	csinv x14, x28, x11, cc
+0a269d5a|	gnu	csneg w10, w16, w29, cs
+ab1692da|	gnu	csneg x11, x21, x18, ne
+418ea5d4|	gnu	dcps1 #0x2c72
+6239a5d4|	gnu	dcps2 #0x29cb
+e3ebabd4|	gnu	dcps3 #0x5f5f
+bf3a03d5|	gnu	dmb ishst
+e003bfd6|	gnu	drps
+9f3003d5|	gnu	dsb #0x00
+c974354a|	gnu	eon w9, w6, w21, lsl #29
+89b86eca|	gnu	eon x9, x4, x14, lsr #46
+76e343d2|	gnu	eor x22, x27, #0xe03fffffffffffff
+536d8c4a|	gnu	eor w19, w10, w12, asr #27
+d1ef1cca|	gnu	eor x17, x30, x28, lsl #59
+e0039fd6|	gnu	eret
+591d8813|	gnu	extr w25, w10, w8, #7
+888dd693|	gnu	extr x8, x12, x22, #35
+bf2003d5|	gnu	sevl
+df2003d5|	gnu	hint #0x6
+a0fc5fd4|	gnu	hlt #0xffe5
+df3103d5|	gnu	isb #0x1
+9dfddf88|	gnu	ldar w29, [x12]
+76ffdfc8|	gnu	ldar x22, [x27]
+36ffdf08|	gnu	ldarb w22, [x25]
+bcfcdf48|	gnu	ldarh w28, [x5]
+54c17f88|	gnu	ldaxp w20, w16, [x10]
+3eaf7fc8|	gnu	ldaxp x30, x11, [x25]
+e2fd5f88|	gnu	ldaxr w2, [x15]
+f5fd5fc8|	gnu	ldaxr x21, [x15]
+70fe5f08|	gnu	ldaxrb w16, [x19]
+bcfc5f48|	gnu	ldaxrh w28, [x5]
+ecff5928|	gnu	ldnp w12, wzr, [sp,#204]
+852744a8|	gnu	ldnp x5, x9, [x28,#64]
+1286d728|	gnu	ldp w18, w1, [x16],#188
+7668e8a8|	gnu	ldp x22, x26, [x3],#-384
+6d8bc729|	gnu	ldp w13, w2, [x27,#60]!
+1cadd1a9|	gnu	ldp x28, x11, [x8,#280]!
+bf4e7e29|	gnu	ldp wzr, w19, [x21,#-16]
+61695fa9|	gnu	ldp x1, x26, [x11,#496]
+4c00e668|	gnu	ldpsw x12, x0, [x2],#-208
+85a0cb69|	gnu	ldpsw x5, x8, [x4,#92]!
+9b894d69|	gnu	ldpsw x27, x2, [x12,#108]
+e9955ab8|	gnu	ldr w9, [x15],#-87
+5c255df8|	gnu	ldr x28, [x10],#-46
+703c57b8|	gnu	ldr w16, [x3,#-141]!
+1dac57f8|	gnu	ldr x29, [x0,#-134]!
+393c50b9|	gnu	ldr w25, [x1,#4156]
+498d5cf9|	gnu	ldr x9, [x10,#14616]
+841fe218|	gnu	ldr w4, .+0xfffffffffffc43f0
+cce88858|	gnu	ldr x12, .+0xfffffffffff11d18
+72fa72b8|	gnu	ldr w18, [x19,x18,sxtx #2]
+daeb66f8|	gnu	ldr x26, [x30,x6,sxtx]
+8ca74238|	gnu	ldrb w12, [x28],#42
+4e5c5e38|	gnu	ldrb w14, [x2,#-27]!
+03936d39|	gnu	ldrb w3, [x24,#2916]
+577a6e38|	gnu	ldrb w23, [x18,x14,lsl #0]
+adb54678|	gnu	ldrh w13, [x13],#107
+820f4c78|	gnu	ldrh w2, [x28,#192]!
+92787579|	gnu	ldrh w18, [x4,#6844]
+4bd6c438|	gnu	ldrsb w11, [x18],#77
+fb478238|	gnu	ldrsb x27, [sp],#36
+4d7edc38|	gnu	ldrsb w13, [x18,#-57]!
+18ee9438|	gnu	ldrsb x24, [x16,#-178]!
+16b9c639|	gnu	ldrsb w22, [x8,#430]
+37958f39|	gnu	ldrsb x23, [x9,#997]
+af7ae238|	gnu	ldrsb w15, [x21,x2,lsl #0]
+1568fa38|	gnu	ldrsb w21, [x0,x26]
+744bbf38|	gnu	ldrsb x20, [x27,wzr,uxtw]
+f069a538|	gnu	ldrsb x16, [x15,x5]
+d9a6cd78|	gnu	ldrsh w25, [x22],#218
+ff368b78|	gnu	ldrsh xzr, [x23],#179
+5b8cc878|	gnu	ldrsh w27, [x2,#136]!
+361f9c78|	gnu	ldrsh x22, [x25,#-63]!
+359bec79|	gnu	ldrsh w21, [x25,#5708]
+4d6c8079|	gnu	ldrsh x13, [x2,#54]
+9deae578|	gnu	ldrsh w29, [x20,x5,sxtx]
+f2fab878|	gnu	ldrsh x18, [x23,x24,sxtx #1]
+02669cb8|	gnu	ldrsw x2, [x16],#-58
+5c8e92b8|	gnu	ldrsw x28, [x18,#-216]!
+ea9e92b9|	gnu	ldrsw x10, [x23,#4764]
+6e280c98|	gnu	ldrsw x14, .+0x1850c
+49dabcb8|	gnu	ldrsw x9, [x18,w28,sxtw #2]
+64285eb8|	gnu	ldtr w4, [x3,#-30]
+6ab851f8|	gnu	ldtr x10, [x3,#-229]
+aa094f38|	gnu	ldtrb w10, [x13,#240]
+b7894e78|	gnu	ldtrh w23, [x13,#232]
+85cadd38|	gnu	ldtrsb w5, [x20,#-36]
+2db99838|	gnu	ldtrsb x13, [x9,#-117]
+7ef8ce78|	gnu	ldtrsh w30, [x3,#239]
+786a8978|	gnu	ldtrsh x24, [x19,#150]
+c5eb81b8|	gnu	ldtrsw x5, [x30,#30]
+a1f14bb8|	gnu	ldur w1, [x13,#191]
+c3425cf8|	gnu	ldur x3, [x22,#-60]
+2e125038|	gnu	ldurb w14, [x17,#-255]
+26004878|	gnu	ldurh w6, [x1,#128]
+c3e3cd38|	gnu	ldursb w3, [x30,#222]
+27618938|	gnu	ldursb x7, [x9,#150]
+7c71db78|	gnu	ldursh w28, [x11,#-73]
+1d109e78|	gnu	ldursh x29, [x0,#-31]
+d48084b8|	gnu	ldursw x20, [x6,#72]
+172f7f88|	gnu	ldxp w23, w11, [x24]
+10347fc8|	gnu	ldxp x16, x13, [x0]
+fe7f5f88|	gnu	ldxr w30, [sp]
+6c7f5fc8|	gnu	ldxr x12, [x27]
+047c5f08|	gnu	ldxrb w4, [x0]
+9a7d5f48|	gnu	ldxrh w26, [x12]
+4f21cb1a|	gnu	lsl w15, w10, w11
+1523db9a|	gnu	lsl x21, x24, x27
+81c74fd3|	gnu	ubfx x1, x28, #15, #35
+c922c81a|	gnu	lsl w9, w22, w8
+fd22dc9a|	gnu	lsl x29, x23, x28
+4226dd1a|	gnu	lsr w2, w18, w29
+a224ca9a|	gnu	lsr x2, x5, x10
+707c0153|	gnu	lsr w16, w3, #1
+34fc4cd3|	gnu	lsr x20, x1, #12
+6c24c91a|	gnu	lsr w12, w3, w9
+8527c89a|	gnu	lsr x5, x28, x8
+ea36171b|	gnu	madd w10, w23, w23, w13
+e47a0a9b|	gnu	madd x4, x23, x10, x30
+35fd001b|	gnu	mneg w21, w9, w0
+77ff0e9b|	gnu	mneg x23, x27, x14
+38030011|	gnu	add w24, w25, #0x0
+37030091|	gnu	add x23, x25, #0x0
+94b8ad12|	gnu	mov w20, #0x923bffff
+fff29892|	gnu	mov xzr, #0xffffffffffff3868
+d4adb252|	gnu	mov w20, #0x956e0000
+8747e2d2|	gnu	mov x7, #0x123c000000000000
+f5132d32|	gnu	orr w21, wzr, #0xf80000
+eb7f34b2|	gnu	mov x11, #0xffffffffffffffff
+f503092a|	gnu	mov w21, w9
+e7031eaa|	gnu	mov x7, x30
+35e8c1f2|	gnu	movk x21, #0xf41, lsl #32
+44629512|	gnu	mov w4, #0xffff54ed
+cc0dd392|	gnu	mov x12, #0xffff6791ffffffff
+cbfb9152|	gnu	mov w11, #0x8fde
+3d25ebd2|	gnu	mov x29, #0x5929000000000000
+e67a3fd5|	gnu	mrs x6, s3_7_c7_c10_7
+f9dd15d5|	gnu	msr s2_5_c13_c13_7, x25
+25840c1b|	gnu	msub w5, w1, w12, w1
+02ce1a9b|	gnu	msub x2, x16, x26, x19
+b67c1a1b|	gnu	mul w22, w5, w26
+607c049b|	gnu	mul x0, x3, x4
+e97f6daa|	gnu	mvn x9, x13, lsr #31
+fe071f6b|	gnu	negs w30, wzr, lsl #1
+f68f14eb|	gnu	negs x22, x20, lsl #35
+e8030d5a|	gnu	ngc w8, w13
+fe031eda|	gnu	ngc x30, x30
+e5030a7a|	gnu	ngcs w5, w10
+f00318fa|	gnu	ngcs x16, x24
+1f2003d5|	gnu	nop
+032ee42a|	gnu	orn w3, w16, w4, ror #11
+634cf6aa|	gnu	orn x3, x3, x22, ror #19
+f8492d32|	gnu	orr w24, w15, #0xfff8003f
+96f542b2|	gnu	orr x22, x12, #0xcfffffffffffffff
+1c110d2a|	gnu	orr w28, w8, w13, lsl #4
+c65b1eaa|	gnu	orr x6, x30, x30, lsl #22
+f300b2f9|	gnu	prfm pstl2strm, [x7,#25600]
+2aa196d8|	gnu	prfm plil2keep, .+0xfffffffffff2d424
+2ad8bef8|	gnu	prfm plil2keep, [x1,w30,sxtw #3]
+c62184f8|	gnu	prfum #0x06, [x14,#66]
+3601c05a|	gnu	rbit w22, w9
+6401c0da|	gnu	rbit x4, x11
+e0035fd6|	gnu	ret xzr
+0a09c05a|	gnu	rev w10, w8
+220cc0da|	gnu	rev x2, x1
+b206c05a|	gnu	rev16 w18, w21
+2407c0da|	gnu	rev16 x4, x25
+7e0bc0da|	gnu	rev32 x30, x27
+ae0ec0da|	gnu	rev x14, x21
+336f8413|	gnu	extr w19, w25, w4, #27
+af47ca93|	gnu	extr x15, x29, x10, #17
+bc2cdb1a|	gnu	ror w28, w5, w27
+e52fdd9a|	gnu	ror x5, xzr, x29
+832dc31a|	gnu	ror w3, w12, w3
+e22ec09a|	gnu	ror x2, x23, x0
+1801045a|	gnu	sbc w24, w8, w4
+5a0119da|	gnu	sbc x26, x10, x25
+52021b7a|	gnu	sbcs w18, w18, w27
+250105fa|	gnu	sbcs x5, x9, x5
+fc430b13|	gnu	sbfx w28, wzr, #11, #6
+a0574093|	gnu	sbfx x0, x29, #0, #22
+8b3b7a93|	gnu	sbfiz x11, x28, #6, #15
+fc310513|	gnu	sbfx w28, w15, #5, #8
+fbdc4293|	gnu	sbfx x27, x7, #2, #54
+c90dd61a|	gnu	sdiv w9, w14, w22
+a90ecd9a|	gnu	sdiv x9, x21, x13
+9f2003d5|	gnu	sev
+bf2003d5|	gnu	sevl
+d27f229b|	gnu	smull x18, w30, w2
+efff3a9b|	gnu	smnegl x15, wzr, w26
+7d963f9b|	gnu	smsubl x29, w19, wzr, x5
+b57e519b|	gnu	smulh x21, x21, x17
+a07c209b|	gnu	smull x0, w5, w0
+d0fe9f88|	gnu	stlr w16, [x22]
+03ff9fc8|	gnu	stlr x3, [x24]
+8bff9f08|	gnu	stlrb w11, [x28]
+f0fe9f48|	gnu	stlrh w16, [x23]
+c6ae3588|	gnu	stlxp w21, w6, w11, [x22]
+c6fa22c8|	gnu	stlxp w2, x6, x30, [x22]
+affd0e88|	gnu	stlxr w14, w15, [x13]
+67ff1cc8|	gnu	stlxr w28, x7, [x27]
+17ff1c08|	gnu	stlxrb w28, w23, [x24]
+7bfe0b48|	gnu	stlxrh w11, w27, [x19]
+2a8c0528|	gnu	stnp w10, w3, [x1,#44]
+67fc10a8|	gnu	stnp x7, xzr, [x3,#264]
+5559bd28|	gnu	stp w21, w22, [x10],#-24
+166c96a8|	gnu	stp x22, x27, [x0],#352
+3d4a8729|	gnu	stp w29, w18, [x17,#56]!
+912f86a9|	gnu	stp x17, x11, [x28,#96]!
+c40d3029|	gnu	stp w4, w3, [x14,#-128]
+f73f39a9|	gnu	stp x23, x15, [sp,#-112]
+34441eb8|	gnu	str w20, [x1],#-28
+11f60bf8|	gnu	str x17, [x16],#191
+c15d15b8|	gnu	str w1, [x14,#-171]!
+ae4d12f8|	gnu	str x14, [x13,#-220]!
+03ef39b9|	gnu	str w3, [x24,#14828]
+208228f9|	gnu	str x0, [x17,#20736]
+734823f8|	gnu	str x19, [x3,w3,uxtw]
+ffb41838|	gnu	strb wzr, [x7],#-117
+bb0d1a38|	gnu	strb w27, [x13,#-96]!
+b1612239|	gnu	strb w17, [x13,#2200]
+92682038|	gnu	strb w18, [x4,x0]
+81682638|	gnu	strb w1, [x4,x6]
+87841b78|	gnu	strh w7, [x4],#-72
+cc3d1878|	gnu	strh w12, [x14,#-125]!
+53cf1c79|	gnu	strh w19, [x26,#3686]
+63792d78|	gnu	strh w3, [x11,x13,lsl #1]
+9d7803b8|	gnu	sttr w29, [x4,#55]
+b9c807f8|	gnu	sttr x25, [x5,#124]
+f04a1e38|	gnu	sttrb w16, [x23,#-28]
+52990078|	gnu	sttrh w18, [x10,#9]
+152002b8|	gnu	stur w21, [x0,#34]
+397217f8|	gnu	stur x25, [x17,#-137]
+8f320138|	gnu	sturb w15, [x20,#19]
+eb021b78|	gnu	sturh w11, [x23,#-80]
+854a3f88|	gnu	stxp wzr, w5, w18, [x20]
+d12620c8|	gnu	stxp w0, x17, x9, [x22]
+537e0288|	gnu	stxr w2, w19, [x18]
+af7d15c8|	gnu	stxr w21, x15, [x13]
+e97c1d08|	gnu	stxrb w29, w9, [x7]
+837d1b48|	gnu	stxrh w27, w3, [x12]
+f25e344b|	gnu	sub w18, w23, w20, uxtw #7
+3ac825cb|	gnu	sub x26, x1, w5, sxtw #2
+e8f40ccb|	gnu	sub x8, x7, x12, lsl #61
+a6ad226b|	gnu	subs w6, w13, w2, sxth #3
+647735eb|	gnu	subs x4, x27, x21, uxtx #5
+c770566b|	gnu	subs w7, w6, w22, lsr #28
+d03c1aeb|	gnu	subs x16, x6, x26, lsl #15
+a17f03d4|	gnu	svc #0x1bfd
+991f0013|	gnu	sxtb w25, w28
+a91d4093|	gnu	sxtb x9, w13
+083d0013|	gnu	sxth w8, w8
+393e4093|	gnu	sxth x25, w17
+1b7c4093|	gnu	sxtw x27, w0
+0c5b2cd5|	gnu	sysl x12, #4, C5, C11, #0
+09868bb7|	gnu	tbnz x9, #49, .+0x70c0
+8c2e6836|	gnu	tbz w12, #13, .+0x5d0
+3f0d0172|	gnu	tst w9, #0x80000007
+df6f7cf2|	gnu	tst x30, #0xfffffff0
+1f2f11ea|	gnu	tst x24, x17, lsl #11
+9ced71d3|	gnu	ubfx x28, x12, #49, #11
+1cbb7fd3|	gnu	ubfiz x28, x24, #1, #47
+25e661d3|	gnu	ubfx x5, x17, #33, #25
+af0adc1a|	gnu	udiv w15, w21, w28
+550ac29a|	gnu	udiv x21, x18, x2
+9102b19b|	gnu	umaddl x17, w20, w17, x0
+41fea39b|	gnu	umnegl x1, w18, w3
+87d8a39b|	gnu	umsubl x7, w4, w3, x22
+987ed89b|	gnu	umulh x24, x20, x24
+d37eb29b|	gnu	umull x19, w22, w18
+461c0053|	gnu	uxtb w6, w2
+f43c0053|	gnu	uxth w20, w7
+5f2003d5|	gnu	wfe
+7f2003d5|	gnu	wfi
+3f2003d5|	gnu	yield
+e5bb200e|	gnu	abs v5.8b, v31.8b
+c9842d0e|	gnu	add v9.8b, v6.8b, v13.8b
+f4bd394e|	gnu	addp v20.16b, v15.16b, v25.16b
+b3b8b14e|	gnu	addv s19, v5.4s
+cd5b284e|	gnu	aesd v13.16b, v30.16b
+4b4b284e|	gnu	aese v11.16b, v26.16b
+2879284e|	gnu	aesimc v8.16b, v9.16b
+fe68284e|	gnu	aesmc v30.16b, v7.16b
+f61e334e|	gnu	and v22.16b, v23.16b, v19.16b
+88a4002f|	gnu	mvni v8.4h, #0x4, lsl #8
+1877076f|	gnu	bic v24.4s, #0xf8, lsl #24
+0d1e6c0e|	gnu	bic v13.8b, v16.8b, v12.8b
+b81ce26e|	gnu	bif v24.16b, v5.16b, v2.16b
+381cbf2e|	gnu	bit v24.8b, v1.8b, v31.8b
+cd1f6c6e|	gnu	bsl v13.16b, v30.16b, v12.16b
+8d48a00e|	gnu	cls v13.2s, v4.2s
+324ba02e|	gnu	clz v18.2s, v25.2s
+c88f2b2e|	gnu	cmeq v8.8b, v30.8b, v11.8b
+a799e05e|	gnu	cmeq d7, d13, #0
+dc9be04e|	gnu	cmeq v28.2d, v30.2d, #0
+623f2d4e|	gnu	cmge v2.16b, v27.16b, v13.16b
+e889e06e|	gnu	cmge v8.2d, v15.2d, #0
+cb37e55e|	gnu	cmgt d11, d30, d5
+8e37b00e|	gnu	cmgt v14.2s, v28.2s, v16.2s
+1a8be04e|	gnu	cmgt v26.2d, v24.2d, #0
+7f37eb7e|	gnu	cmhi d31, d27, d11
+333d356e|	gnu	cmhs v19.16b, v9.16b, v21.16b
+bd9ae07e|	gnu	cmle d29, d21, #0
+8999602e|	gnu	cmle v9.4h, v12.4h, #0
+aca9e05e|	gnu	cmlt d12, d13, #0
+7fa8204e|	gnu	cmlt v31.16b, v3.16b, #0
+588db20e|	gnu	cmtst v24.2s, v10.2s, v18.2s
+cc051d5e|	gnu	mov b12, v14.b[14]
+4c06050e|	gnu	dup v12.8b, v18.b[2]
+790c020e|	gnu	dup v25.4h, w3
+391d286e|	gnu	eor v25.16b, v9.16b, v8.16b
+4b30156e|	gnu	ext v11.16b, v2.16b, v21.16b, #6
+44d6bf7e|	gnu	fabd s4, s18, s31
+17fba00e|	gnu	fabs v23.2s, v24.2s
+90c2201e|	gnu	fabs s16, s20
+62c2601e|	gnu	fabs d2, d19
+eeef3f7e|	gnu	facge s14, s31, s31
+09efa07e|	gnu	facgt s9, s24, s0
+72edae6e|	gnu	facgt v18.4s, v11.4s, v14.4s
+61d5394e|	gnu	fadd v1.4s, v11.4s, v25.4s
+0d2a3d1e|	gnu	fadd s13, s16, s29
+4b296f1e|	gnu	fadd d11, d10, d15
+78d8307e|	gnu	faddp s24, v3.2s
+e7d7322e|	gnu	faddp v7.2s, v31.2s, v18.2s
+e8253c1e|	gnu	fccmp s15, s28, #0x8, cs
+e8857f1e|	gnu	fccmp d15, d31, #0x8, hi
+5714291e|	gnu	fccmpe s2, s9, #0x7, ne
+b484631e|	gnu	fccmpe d5, d3, #0x4, hi
+3ce5685e|	gnu	fcmeq d28, d9, d8
+50e6214e|	gnu	fcmeq v16.4s, v18.4s, v1.4s
+9ddae05e|	gnu	fcmeq d29, d20, #0
+b3e62b7e|	gnu	fcmge s19, s21, s11
+0ce4396e|	gnu	fcmge v12.4s, v0.4s, v25.4s
+a6c9e07e|	gnu	fcmge d6, d13, #0
+ede6bd7e|	gnu	fcmgt s13, s23, s29
+13e6ae2e|	gnu	fcmgt v19.2s, v16.2s, v14.2s
+4cc9e05e|	gnu	fcmgt d12, d10, #0
+41cba04e|	gnu	fcmgt v1.4s, v26.4s, #0
+96d8e07e|	gnu	fcmle d22, d4, #0
+0be9a05e|	gnu	fcmlt s11, s8, #0
+dfe9a04e|	gnu	fcmlt v31.4s, v14.4s, #0
+a023301e|	gnu	fcmp s29, s16
+68213e1e|	gnu	fcmp s11, #0
+20236d1e|	gnu	fcmp d25, d13
+68216b1e|	gnu	fcmp d11, #0
+3023351e|	gnu	fcmpe s25, s21
+78203e1e|	gnu	fcmpe s3, #0
+b022721e|	gnu	fcmpe d21, d18
+f8226f1e|	gnu	fcmpe d23, #0
+b54e271e|	gnu	fcsel s21, s21, s7, mi
+319f611e|	gnu	fcsel d17, d25, d1, ls
+2142e21e|	gnu	fcvt s1, h17
+cfc3e21e|	gnu	fcvt d15, h30
+01c1231e|	gnu	fcvt h1, s8
+4fc0221e|	gnu	fcvt d15, s2
+f9c0631e|	gnu	fcvt h25, d7
+2b43621e|	gnu	fcvt s11, d25
+f1c8615e|	gnu	fcvtas d17, d7
+ea01241e|	gnu	fcvtas w10, s15
+0c02249e|	gnu	fcvtas x12, s16
+e702641e|	gnu	fcvtas w7, d23
+f501649e|	gnu	fcvtas x21, d15
+45ca217e|	gnu	fcvtau s5, s18
+66c9212e|	gnu	fcvtau v6.2s, v11.2s
+b302251e|	gnu	fcvtau w19, s21
+e102259e|	gnu	fcvtau x1, s23
+5703651e|	gnu	fcvtau w23, d26
+2c01659e|	gnu	fcvtau x12, d9
+2c7b210e|	gnu	fcvtl v12.4s, v25.4h
+f478214e|	gnu	fcvtl2 v20.4s, v7.8h
+d1b8615e|	gnu	fcvtms d17, d6
+a2ba614e|	gnu	fcvtms v2.2d, v21.2d
+ee01301e|	gnu	fcvtms w14, s15
+de01309e|	gnu	fcvtms x30, s14
+8401701e|	gnu	fcvtms w4, d12
+c502709e|	gnu	fcvtms x5, d22
+44b8617e|	gnu	fcvtmu d4, d2
+5601311e|	gnu	fcvtmu w22, s10
+4602319e|	gnu	fcvtmu x6, s18
+1003711e|	gnu	fcvtmu w16, d24
+e602719e|	gnu	fcvtmu x6, d23
+c16b210e|	gnu	fcvtn v1.4h, v30.4s
+4d6b614e|	gnu	fcvtn2 v13.4s, v26.2d
+95ab215e|	gnu	fcvtns s21, s28
+65a9614e|	gnu	fcvtns v5.2d, v11.2d
+8a02201e|	gnu	fcvtns w10, s20
+bc03209e|	gnu	fcvtns x28, s29
+fc01601e|	gnu	fcvtns w28, d15
+9800609e|	gnu	fcvtns x24, d4
+b1aa617e|	gnu	fcvtnu d17, d21
+80a9216e|	gnu	fcvtnu v0.4s, v12.4s
+3201211e|	gnu	fcvtnu w18, s9
+e101219e|	gnu	fcvtnu x1, s15
+ae00611e|	gnu	fcvtnu w14, d5
+9503619e|	gnu	fcvtnu x21, d28
+3faae15e|	gnu	fcvtps d31, d17
+c4a8e14e|	gnu	fcvtps v4.2d, v6.2d
+ab01281e|	gnu	fcvtps w11, s13
+5800289e|	gnu	fcvtps x24, s2
+9b02681e|	gnu	fcvtps w27, d20
+de03689e|	gnu	fcvtps x30, d30
+d8aaa17e|	gnu	fcvtpu s24, s22
+e203291e|	gnu	fcvtpu w2, s31
+5302299e|	gnu	fcvtpu x19, s18
+5302691e|	gnu	fcvtpu w19, d18
+8501699e|	gnu	fcvtpu x5, d12
+93ff735f|	gnu	fcvtzs d19, d28, #13
+b7fd504f|	gnu	fcvtzs v23.2d, v13.2d, #48
+7ebba15e|	gnu	fcvtzs s30, s27
+d49f181e|	gnu	fcvtzs w20, s30, #25
+538d189e|	gnu	fcvtzs x19, s10, #29
+7e74589e|	gnu	fcvtzs x30, d3, #35
+4300381e|	gnu	fcvtzs w3, s2
+bc03389e|	gnu	fcvtzs x28, s29
+c702781e|	gnu	fcvtzs w7, d22
+0401789e|	gnu	fcvtzs x4, d8
+d1ff2e7f|	gnu	fcvtzu s17, s30, #18
+d0fd3b2f|	gnu	fcvtzu v16.2s, v14.2s, #5
+70bae17e|	gnu	fcvtzu d16, d19
+3ef6191e|	gnu	fcvtzu w30, s17, #3
+cae7199e|	gnu	fcvtzu x10, s30, #7
+cffb599e|	gnu	fcvtzu x15, d30, #2
+e402391e|	gnu	fcvtzu w4, s23
+1a03399e|	gnu	fcvtzu x26, s24
+0401791e|	gnu	fcvtzu w4, d8
+c200799e|	gnu	fcvtzu x2, d6
+ebfe346e|	gnu	fdiv v11.4s, v23.4s, v20.4s
+c918371e|	gnu	fdiv s9, s6, s23
+911a7f1e|	gnu	fdiv d17, d20, d31
+a81f0c1f|	gnu	fmadd s8, s29, s12, s7
+d0404a1f|	gnu	fmadd d16, d6, d10, d16
+7ff6324e|	gnu	fmax v31.4s, v19.4s, v18.4s
+b84b351e|	gnu	fmax s24, s29, s21
+d64b621e|	gnu	fmax d22, d30, d2
+016b241e|	gnu	fmaxnm s1, s24, s4
+5b69781e|	gnu	fmaxnm d27, d10, d24
+f1c8707e|	gnu	fmaxnmp d17, v7.2d
+27c5306e|	gnu	fmaxnmp v7.4s, v9.4s, v16.4s
+aef8707e|	gnu	fmaxp d14, v5.2d
+53f6202e|	gnu	fmaxp v19.2s, v18.2s, v0.2s
+78fb306e|	gnu	fmaxv s24, v27.4s
+5af4ec4e|	gnu	fmin v26.2d, v2.2d, v12.2d
+505a3c1e|	gnu	fmin s16, s18, s28
+4858661e|	gnu	fmin d8, d2, d6
+a9c6e04e|	gnu	fminnm v9.2d, v21.2d, v0.2d
+987b311e|	gnu	fminnm s24, s28, s17
+95796f1e|	gnu	fminnm d21, d12, d15
+f5cbb07e|	gnu	fminnmp s21, v31.2s
+b0f8f07e|	gnu	fminp d16, v5.2d
+8bf5a42e|	gnu	fminp v11.2s, v12.2s, v4.2s
+87cd384e|	gnu	fmla v7.4s, v12.4s, v24.4s
+fd50db5f|	gnu	fmls d29, d7, v27.d[0]
+d1ccb44e|	gnu	fmls v17.4s, v6.4s, v20.4s
+ebf5064f|	gnu	fmov v11.4s, #-2.421875000000000000e-01
+49f4056f|	gnu	fmov v9.2d, #-9.000000000000000000e+00
+0940201e|	gnu	fmov s9, s0
+db43601e|	gnu	fmov d27, d30
+a901271e|	gnu	fmov s9, w13
+3702261e|	gnu	fmov w23, s17
+4d02679e|	gnu	fmov d13, x18
+9d02af9e|	gnu	fmov v29.d[1], x20
+ef03669e|	gnu	fmov x15, d31
+7101ae9e|	gnu	fmov x17, v11.d[1]
+0e103d1e|	gnu	fmov s14, #-7.500000000000000000e-01
+1e50761e|	gnu	fmov d30, #-1.800000000000000000e+01
+d2b4121f|	gnu	fmsub s18, s6, s18, s13
+0a9c4c1f|	gnu	fmsub d10, d0, d12, d7
+0d99b35f|	gnu	fmul s13, s8, v19.s[3]
+a89b9b0f|	gnu	fmul v8.2s, v29.2s, v27.s[2]
+75dc376e|	gnu	fmul v21.4s, v3.4s, v23.4s
+7909241e|	gnu	fmul s25, s11, s4
+d7096b1e|	gnu	fmul d23, d14, d11
+2999ab7f|	gnu	fmulx s9, s9, v11.s[3]
+35dd6d5e|	gnu	fmulx d21, d9, d13
+c8dc284e|	gnu	fmulx v8.4s, v6.4s, v8.4s
+c043211e|	gnu	fneg s0, s30
+4742611e|	gnu	fneg d7, d18
+9c51251f|	gnu	fnmadd s28, s12, s5, s20
+e407771f|	gnu	fnmadd d4, d31, d23, d1
+fbfa3a1f|	gnu	fnmsub s27, s23, s26, s30
+bbb0691f|	gnu	fnmsub d27, d5, d9, d12
+6a8b3f1e|	gnu	fnmul s10, s27, s31
+1a8b751e|	gnu	fnmul d26, d24, d21
+57d8e15e|	gnu	frecpe d23, d2
+62dba14e|	gnu	frecpe v2.4s, v27.4s
+81fd325e|	gnu	frecps s1, s12, s18
+31fe224e|	gnu	frecps v17.4s, v17.4s, v2.4s
+ecf9e15e|	gnu	frecpx d12, d15
+c18b216e|	gnu	frinta v1.4s, v30.4s
+0240261e|	gnu	frinta s2, s0
+8041661e|	gnu	frinta d0, d12
+c89ba12e|	gnu	frinti v8.2s, v30.2s
+2ec2271e|	gnu	frinti s14, s17
+5cc0671e|	gnu	frinti d28, d2
+3898210e|	gnu	frintm v24.2s, v1.2s
+9843251e|	gnu	frintm s24, s28
+5b40651e|	gnu	frintm d27, d2
+2189614e|	gnu	frintn v1.2d, v9.2d
+7e42241e|	gnu	frintn s30, s19
+5d40641e|	gnu	frintn d29, d2
+85c3241e|	gnu	frintp s5, s28
+46c2641e|	gnu	frintp d6, d18
+c39b216e|	gnu	frintx v3.4s, v30.4s
+a243271e|	gnu	frintx s2, s29
+1d41671e|	gnu	frintx d29, d8
+5499e14e|	gnu	frintz v20.2d, v10.2d
+92c2251e|	gnu	frintz s18, s20
+75c2651e|	gnu	frintz d21, d19
+ddd9e17e|	gnu	frsqrte d29, d14
+60fff85e|	gnu	frsqrts d0, d27, d24
+dafffb4e|	gnu	frsqrts v26.2d, v30.2d, v27.2d
+1ff9a12e|	gnu	fsqrt v31.2s, v8.2s
+2dc3211e|	gnu	fsqrt s13, s25
+72c0611e|	gnu	fsqrt d18, d3
+7d3a3e1e|	gnu	fsub s29, s19, s30
+3f38771e|	gnu	fsub d31, d1, d23
+185e016e|	gnu	mov v24.b[0], v16.b[11]
+911d0d4e|	gnu	mov v17.b[6], w12
+2877400c|	gnu	ld1 {v8.4h}, [x25]
+8ea8404c|	gnu	ld1 {v14.4s, v15.4s}, [x4]
+0f62404c|	gnu	ld1 {v15.16b-v17.16b}, [x16]
+0f27400c|	gnu	ld1 {v15.4h-v18.4h}, [x24]
+4c75df0c|	gnu	ld1 {v12.4h}, [x10],#8
+2f7bd04c|	gnu	ld1 {v15.4s}, [x25], x16
+eaaadf0c|	gnu	ld1 {v10.2s, v11.2s}, [x23],#16
+eca7cc4c|	gnu	ld1 {v12.8h, v13.8h}, [sp], x12
+cd60df4c|	gnu	ld1 {v13.16b-v15.16b}, [x6],#48
+9163df0c|	gnu	ld1 {v17.8b-v19.8b}, [x28],#24
+152ddf4c|	gnu	ld1 {v21.2d-v24.2d}, [x8],#64
+0725c04c|	gnu	ld1 {v7.8h-v10.8h}, [x8], x0
+7c04404d|	gnu	ld1 {v28.b}[9], [x3]
+6d49404d|	gnu	ld1 {v13.h}[5], [x11]
+9e81400d|	gnu	ld1 {v30.s}[0], [x12]
+d384404d|	gnu	ld1 {v19.d}[1], [x6]
+b20ddf4d|	gnu	ld1 {v18.b}[11], [x13],#1
+f114cd4d|	gnu	ld1 {v17.b}[13], [x7], x13
+bb92df4d|	gnu	ld1 {v27.s}[3], [x21],#4
+a883d64d|	gnu	ld1 {v8.s}[2], [x29], x22
+f584df4d|	gnu	ld1 {v21.d}[1], [x7],#8
+0284c80d|	gnu	ld1 {v2.d}[0], [x0], x8
+91c3400d|	gnu	ld1r {v17.8b}, [x28]
+71c9df0d|	gnu	ld1r {v17.2s}, [x11],#4
+e7c4db0d|	gnu	ld1r {v7.4h}, [x7], x27
+b787404c|	gnu	ld2 {v23.8h, v24.8h}, [x29]
+1280df0c|	gnu	ld2 {v18.8b, v19.8b}, [x0],#16
+2f88c10c|	gnu	ld2 {v15.2s, v16.2s}, [x1], x1
+a01e604d|	gnu	ld2 {v0.b, v1.b}[15], [x21]
+eb82604d|	gnu	ld2 {v11.s, v12.s}[2], [x23]
+f985600d|	gnu	ld2 {v25.d, v26.d}[0], [x15]
+e315ff0d|	gnu	ld2 {v3.b, v4.b}[5], [x15],#2
+1c11f24d|	gnu	ld2 {v28.b, v29.b}[12], [x8], x18
+f341ef4d|	gnu	ld2 {v19.h, v20.h}[4], [x15], x15
+5a80ff4d|	gnu	ld2 {v26.s, v27.s}[2], [x2],#8
+d781fd0d|	gnu	ld2 {v23.s, v24.s}[0], [x14], x29
+c885ff0d|	gnu	ld2 {v8.d, v9.d}[0], [x14],#16
+1286f34d|	gnu	ld2 {v18.d, v19.d}[1], [x16], x19
+06c2600d|	gnu	ld2r {v6.8b, v7.8b}, [x16]
+95c7ff4d|	gnu	ld2r {v21.8h, v22.8h}, [x28],#4
+d4c1e14d|	gnu	ld2r {v20.16b, v21.16b}, [x14], x1
+eb4bdf4c|	gnu	ld3 {v11.4s-v13.4s}, [sp],#48
+ce4fc24c|	gnu	ld3 {v14.2d-v16.2d}, [x30], x2
+db23400d|	gnu	ld3 {v27.b-v29.b}[0], [x30]
+26b3400d|	gnu	ld3 {v6.s-v8.s}[1], [x25]
+37a4400d|	gnu	ld3 {v23.d-v25.d}[0], [x1]
+052edf4d|	gnu	ld3 {v5.b-v7.b}[11], [x16],#3
+8c3ccd0d|	gnu	ld3 {v12.b-v14.b}[7], [x4], x13
+74b0df4d|	gnu	ld3 {v20.s-v22.s}[3], [x3],#12
+b7b1c84d|	gnu	ld3 {v23.s-v25.s}[3], [x13], x8
+e6a5df4d|	gnu	ld3 {v6.d-v8.d}[1], [x15],#24
+42a5c80d|	gnu	ld3 {v2.d-v4.d}[0], [x10], x8
+9ceb400d|	gnu	ld3r {v28.2s-v30.2s}, [x28]
+6aeadf4d|	gnu	ld3r {v10.4s-v12.4s}, [x19],#12
+65ebce4d|	gnu	ld3r {v5.4s-v7.4s}, [x27], x14
+ea05400c|	gnu	ld4 {v10.4h-v13.4h}, [x15]
+1f03df0c|	gnu	ld4 {v31.8b, v0.8b, v1.8b, v2.8b}, [x24],#32
+ae09c90c|	gnu	ld4 {v14.2s-v17.2s}, [x13], x9
+fd3a604d|	gnu	ld4 {v29.b, v30.b, v31.b, v0.b}[14], [x23]
+d8a0604d|	gnu	ld4 {v24.s-v27.s}[2], [x6]
+62a4604d|	gnu	ld4 {v2.d-v5.d}[1], [x3]
+712fff0d|	gnu	ld4 {v17.b-v20.b}[3], [x27],#4
+aa27f40d|	gnu	ld4 {v10.b-v13.b}[1], [x29], x20
+be71ff4d|	gnu	ld4 {v30.h, v31.h, v0.h, v1.h}[6], [x13],#8
+e360ee4d|	gnu	ld4 {v3.h-v6.h}[4], [x7], x14
+c0a0ff0d|	gnu	ld4 {v0.s-v3.s}[0], [x6],#16
+d3a3e00d|	gnu	ld4 {v19.s-v22.s}[0], [x30], x0
+95a7ff0d|	gnu	ld4 {v21.d-v24.d}[0], [x28],#32
+32a6e14d|	gnu	ld4 {v18.d-v21.d}[1], [x17], x1
+56e0604d|	gnu	ld4r {v22.16b-v25.16b}, [x2]
+dce7ff0d|	gnu	ld4r {v28.4h-v31.4h}, [x30],#8
+14e8ef0d|	gnu	ld4r {v20.2s-v23.2s}, [x0], x15
+7776732c|	gnu	ldnp s23, s29, [x19,#-104]
+23dd746c|	gnu	ldnp d3, d23, [x9,#-184]
+383e48ac|	gnu	ldnp q24, q15, [x17,#256]
+0d10c12c|	gnu	ldp s13, s4, [x0],#8
+fe3ae66c|	gnu	ldp d30, d14, [x23],#-416
+f627f9ac|	gnu	ldp q22, q9, [sp],#-224
+918cd82d|	gnu	ldp s17, s3, [x4,#196]!
+986be46d|	gnu	ldp d24, d26, [x28,#-448]!
+ebd8f8ad|	gnu	ldp q11, q22, [x7,#-240]!
+3c905c2d|	gnu	ldp s28, s4, [x1,#228]
+5887536d|	gnu	ldp d24, d1, [x26,#312]
+08957cad|	gnu	ldp q8, q5, [x8,#-112]
+c5e5543c|	gnu	ldr b5, [x14],#-178
+4ff5417c|	gnu	ldr h15, [x10],#31
+72e54bbc|	gnu	ldr s18, [x11],#190
+16b55dfc|	gnu	ldr d22, [x8],#-37
+9e24db3c|	gnu	ldr q30, [x4],#-78
+d20c503c|	gnu	ldr b18, [x6,#-256]!
+1f1c4d7c|	gnu	ldr h31, [x0,#209]!
+2fbf4dbc|	gnu	ldr s15, [x25,#219]!
+a06c59fc|	gnu	ldr d0, [x5,#-106]!
+886ddd3c|	gnu	ldr q8, [x12,#-42]!
+58f64e3d|	gnu	ldr b24, [x18,#957]
+f5c3547d|	gnu	ldr h21, [sp,#2656]
+8e8a7bbd|	gnu	ldr s14, [x20,#15240]
+8e3c7afd|	gnu	ldr d14, [x4,#29816]
+f2aeff3d|	gnu	ldr q18, [x23,#65200]
+92831b1c|	gnu	ldr s18, .+0x37070
+3e01b55c|	gnu	ldr d30, .+0xfffffffffff6a024
+fdee3b9c|	gnu	ldr q29, .+0x77ddc
+1d78793c|	gnu	ldr b29, [x0,x25,lsl #0]
+b8f15d3c|	gnu	ldur b24, [x13,#-33]
+95635c7c|	gnu	ldur h21, [x28,#-58]
+27d046bc|	gnu	ldur s7, [x1,#109]
+21624efc|	gnu	ldur d1, [x17,#230]
+6dd2d83c|	gnu	ldur q13, [x19,#-115]
+dc09be6f|	gnu	mla v28.4s, v14.4s, v30.s[3]
+eb97af4e|	gnu	mla v11.4s, v31.4s, v15.4s
+0495722e|	gnu	mls v4.4h, v8.4h, v18.4h
+21070a5e|	gnu	mov h1, v25.h[2]
+92471b6e|	gnu	mov v18.b[13], v28.b[8]
+7a1e134e|	gnu	mov v26.b[9], w19
+761fa30e|	gnu	orr v22.8b, v27.8b, v3.8b
+f23d070e|	gnu	umov w18, v15.b[3]
+a5e6064f|	gnu	movi v5.16b, #0xd5
+63c5064f|	gnu	movi v3.4s, #0xcb, msl #8
+bca7014f|	gnu	movi v28.8h, #0x3d, lsl #8
+95e4040f|	gnu	movi v21.8b, #0x84
+fce4072f|	gnu	movi d28, #0xffffff0000ffffff
+24e6036f|	gnu	movi v4.2d, #0xffffff000000ff
+429d6a4e|	gnu	mul v2.8h, v10.8h, v10.8h
+e558202e|	gnu	mvn v5.8b, v7.8b
+fe65012f|	gnu	mvni v30.2s, #0x2f, lsl #24
+2b16046f|	gnu	bic v11.4s, #0x91
+7756016f|	gnu	bic v23.4s, #0x33, lsl #16
+e159202e|	gnu	mvn v1.8b, v15.8b
+da1cf14e|	gnu	orn v26.16b, v6.16b, v17.16b
+ca04014f|	gnu	movi v10.4s, #0x26
+14a6020f|	gnu	movi v20.4h, #0x50, lsl #8
+2f1fbf0e|	gnu	orr v15.8b, v25.8b, v31.8b
+74e2f20e|	gnu	pmull v20.1q, v19.1d, v18.1d
+2740262e|	gnu	raddhn v7.8b, v1.8h, v6.8h
+17412e6e|	gnu	raddhn2 v23.16b, v8.8h, v14.8h
+da59602e|	gnu	rbit v26.8b, v14.8b
+230a604e|	gnu	rev64 v3.8h, v17.8h
+178d210f|	gnu	rshrn v23.2s, v8.2d, #31
+6b8d2c4f|	gnu	rshrn2 v11.4s, v11.2d, #20
+b57c2a0e|	gnu	saba v21.8b, v5.8b, v10.8b
+71533d0e|	gnu	sabal v17.8h, v27.8b, v29.8b
+1c50774e|	gnu	sabal2 v28.4s, v0.8h, v23.8h
+1974be4e|	gnu	sabd v25.4s, v0.4s, v30.4s
+6b71ad0e|	gnu	sabdl v11.2d, v11.2s, v13.2s
+5270324e|	gnu	sabdl2 v18.8h, v2.16b, v18.16b
+366b200e|	gnu	sadalp v22.4h, v25.8b
+1802680e|	gnu	saddl v24.4s, v16.4h, v8.4h
+022b604e|	gnu	saddlp v2.4s, v24.8h
+413ab04e|	gnu	saddlv d1, v18.4s
+4013750e|	gnu	saddw v0.4s, v26.4s, v21.4h
+4412744e|	gnu	saddw2 v4.4s, v18.4s, v20.8h
+2ee6255f|	gnu	scvtf s14, s17, #27
+dce75f4f|	gnu	scvtf v28.2d, v30.2d, #33
+5bdb615e|	gnu	scvtf d27, d26
+3ad9210e|	gnu	scvtf v26.2s, v9.2s
+1ceb421e|	gnu	scvtf d28, w24, #6
+9dde029e|	gnu	scvtf s29, x20, #9
+57d1429e|	gnu	scvtf d23, x10, #12
+d600221e|	gnu	scvtf s22, w6
+c503621e|	gnu	scvtf d5, w30
+3303229e|	gnu	scvtf s19, x25
+0003629e|	gnu	scvtf d0, x24
+6f01075e|	gnu	sha1c q15, s11, v7.4s
+9308285e|	gnu	sha1h s19, s4
+b420105e|	gnu	sha1m q20, s5, v16.4s
+f4131f5e|	gnu	sha1p q20, s31, v31.4s
+dc311f5e|	gnu	sha1su0 v28.4s, v14.4s, v31.4s
+bb1a285e|	gnu	sha1su1 v27.4s, v21.4s
+2753075e|	gnu	sha256h2 q7, q25, v7.4s
+3141065e|	gnu	sha256h q17, q9, v6.4s
+172b285e|	gnu	sha256su0 v23.4s, v24.4s
+bb621b5e|	gnu	sha256su1 v27.4s, v21.4s, v27.4s
+7005644e|	gnu	shadd v16.8h, v11.8h, v4.8h
+2d870e0f|	gnu	shrn v13.8b, v25.8h, #2
+ac86024f|	gnu	movi v12.8h, #0x55
+1c26a50e|	gnu	shsub v28.2s, v16.2s, v5.2s
+db576b6f|	gnu	sli v27.2d, v30.2d, #43
+c3652c4e|	gnu	smax v3.16b, v14.16b, v12.16b
+b5a7ab0e|	gnu	smaxp v21.2s, v29.2s, v11.2s
+f1aeb34e|	gnu	sminp v17.4s, v23.4s, v19.4s
+87a8b14e|	gnu	sminv s7, v4.4s
+1e21bc4f|	gnu	smlal2 v30.2d, v8.4s, v28.s[1]
+50a33a0e|	gnu	smlsl v16.8h, v26.8b, v26.8b
+4e2d1a0e|	gnu	smov w14, v10.h[6]
+9ba9b30f|	gnu	smull v27.2d, v12.2s, v19.s[3]
+417a205e|	gnu	sqabs b1, b18
+9f78a04e|	gnu	sqabs v31.4s, v4.4s
+580d2e5e|	gnu	sqadd b24, b10, b14
+3d30764f|	gnu	sqdmlal2 v29.4s, v1.8h, v6.h[3]
+9591b25e|	gnu	sqdmlal d21, s12, s18
+0d92670e|	gnu	sqdmlal v13.4s, v16.4h, v7.4h
+90b1765e|	gnu	sqdmlsl s16, h12, h22
+83c2ad5f|	gnu	sqdmulh s3, s20, v13.s[1]
+bbb7aa5e|	gnu	sqdmulh s27, s29, s10
+c8b99a5f|	gnu	sqdmull d8, s14, v26.s[2]
+75b3920f|	gnu	sqdmull v21.2d, v27.2s, v18.s[0]
+86d1b75e|	gnu	sqdmull d6, s12, s23
+edd06f4e|	gnu	sqdmull2 v13.4s, v7.8h, v15.8h
+0f7ae07e|	gnu	sqneg d15, d16
+e87b602e|	gnu	sqneg v8.4h, v31.4h
+ecb5a92e|	gnu	sqrdmulh v12.2s, v15.2s, v9.2s
+d75fba5e|	gnu	sqrshl s23, s30, s26
+f75f324e|	gnu	sqrshl v23.16b, v31.16b, v18.16b
+af9c114f|	gnu	sqrshrn2 v15.8h, v5.4s, #15
+318d2f6f|	gnu	sqrshrun2 v17.4s, v9.2d, #17
+b3757c5f|	gnu	sqshl d19, d13, #60
+0c776f4f|	gnu	sqshl v12.2d, v24.2d, #47
+d84c2a5e|	gnu	sqshl b24, b6, b10
+ae4e704e|	gnu	sqshl v14.8h, v21.8h, v16.8h
+b566727f|	gnu	sqshlu d21, d21, #50
+4566596f|	gnu	sqshlu v5.2d, v18.2d, #25
+d595140f|	gnu	sqshrn v21.4h, v14.4s, #12
+00940b4f|	gnu	sqshrn2 v0.16b, v0.8h, #5
+5384352f|	gnu	sqshrun v19.2s, v2.2d, #11
+1a2e3d5e|	gnu	sqsub b26, b16, b29
+b02e6b4e|	gnu	sqsub v16.8h, v21.8h, v11.8h
+1249a15e|	gnu	sqxtn s18, d8
+eb49610e|	gnu	sqxtn v11.4h, v15.4s
+cb4a614e|	gnu	sqxtn2 v11.8h, v22.4s
+102b217e|	gnu	sqxtun b16, h24
+492a212e|	gnu	sqxtun v9.8b, v18.8h
+112a616e|	gnu	sqxtun2 v17.8h, v16.4s
+6c16ae4e|	gnu	srhadd v12.4s, v19.4s, v14.4s
+5946467f|	gnu	sri d25, d18, #58
+21460a2f|	gnu	sri v1.8b, v17.8b, #6
+9f56b10e|	gnu	srshl v31.2s, v20.2s, v17.2s
+e724635f|	gnu	srshr d7, d7, #29
+e8266b4f|	gnu	srshr v8.2d, v23.2d, #21
+2b37180f|	gnu	srsra v11.4h, v25.4h, #8
+1644f95e|	gnu	sshl d22, d0, d25
+3644fc4e|	gnu	sshl v22.2d, v1.2d, v28.2d
+d9a61f4f|	gnu	sshll2 v25.4s, v22.8h, #15
+9b075e5f|	gnu	sshr d27, d28, #34
+2c044c4f|	gnu	sshr v12.2d, v1.2d, #52
+d915324f|	gnu	ssra v25.4s, v14.4s, #14
+de21260e|	gnu	ssubl v30.8h, v14.8b, v6.8b
+c720254e|	gnu	ssubl2 v7.8h, v6.16b, v5.16b
+9d33b90e|	gnu	ssubw v29.2d, v28.2d, v25.2s
+7e71000c|	gnu	st1 {v30.8b}, [x11]
+cca6000c|	gnu	st1 {v12.4h, v13.4h}, [x22]
+5467000c|	gnu	st1 {v20.4h-v22.4h}, [x26]
+cc28004c|	gnu	st1 {v12.4s-v15.4s}, [x6]
+9e7e9f4c|	gnu	st1 {v30.2d}, [x20],#16
+4b769d0c|	gnu	st1 {v11.4h}, [x18], x29
+adaa9f0c|	gnu	st1 {v13.2s, v14.2s}, [x21],#16
+bca7844c|	gnu	st1 {v28.8h, v29.8h}, [x29], x4
+b5659f0c|	gnu	st1 {v21.4h-v23.4h}, [x13],#24
+e669874c|	gnu	st1 {v6.4s-v8.4s}, [x15], x7
+9b2a9f0c|	gnu	st1 {v27.2s-v30.2s}, [x20],#32
+14278b0c|	gnu	st1 {v20.4h-v23.4h}, [x24], x11
+d002004d|	gnu	st1 {v16.b}[8], [x22]
+9780004d|	gnu	st1 {v23.s}[2], [x4]
+7787004d|	gnu	st1 {v23.d}[1], [x27]
+850d9f0d|	gnu	st1 {v5.b}[3], [x12],#1
+7b1f8f0d|	gnu	st1 {v27.b}[7], [x27], x15
+7a5a9f4d|	gnu	st1 {v26.h}[7], [x19],#2
+e14b9e4d|	gnu	st1 {v1.h}[5], [sp], x30
+dd819f4d|	gnu	st1 {v29.s}[2], [x14],#4
+a281910d|	gnu	st1 {v2.s}[0], [x13], x17
+b2849f0d|	gnu	st1 {v18.d}[0], [x5],#8
+c484964d|	gnu	st1 {v4.d}[1], [x6], x22
+f686004c|	gnu	st2 {v22.8h, v23.8h}, [x23]
+2e869f0c|	gnu	st2 {v14.4h, v15.4h}, [x17],#16
+d200200d|	gnu	st2 {v18.b, v19.b}[0], [x6]
+ab58200d|	gnu	st2 {v11.h, v12.h}[3], [x5]
+c491204d|	gnu	st2 {v4.s, v5.s}[3], [x14]
+5a85204d|	gnu	st2 {v26.d, v27.d}[1], [x10]
+f217bf0d|	gnu	st2 {v18.b, v19.b}[5], [sp],#2
+2b0ea04d|	gnu	st2 {v11.b, v12.b}[11], [x17], x0
+4042bf0d|	gnu	st2 {v0.h, v1.h}[0], [x18],#4
+9342af4d|	gnu	st2 {v19.h, v20.h}[4], [x20], x15
+9b91bf4d|	gnu	st2 {v27.s, v28.s}[3], [x12],#8
+7480a10d|	gnu	st2 {v20.s, v21.s}[0], [x3], x1
+c884bf0d|	gnu	st2 {v8.d, v9.d}[0], [x6],#16
+ae86ac4d|	gnu	st2 {v14.d, v15.d}[1], [x21], x12
+614d004c|	gnu	st3 {v1.2d-v3.2d}, [x11]
+324b9f4c|	gnu	st3 {v18.4s-v20.4s}, [x25],#48
+7340870c|	gnu	st3 {v19.8b-v21.8b}, [x3], x7
+ac24004d|	gnu	st3 {v12.b-v14.b}[9], [x5]
+a161004d|	gnu	st3 {v1.h-v3.h}[4], [x13]
+09b1004d|	gnu	st3 {v9.s-v11.s}[3], [x8]
+78a7004d|	gnu	st3 {v24.d-v26.d}[1], [x27]
+4f349f0d|	gnu	st3 {v15.b-v17.b}[5], [x2],#3
+643d840d|	gnu	st3 {v4.b-v6.b}[7], [x11], x4
+48699f0d|	gnu	st3 {v8.h-v10.h}[1], [x10],#6
+85b19f4d|	gnu	st3 {v5.s-v7.s}[3], [x12],#12
+60a18a0d|	gnu	st3 {v0.s-v2.s}[0], [x11], x10
+69a49f0d|	gnu	st3 {v9.d-v11.d}[0], [x3],#24
+ada7814d|	gnu	st3 {v13.d-v15.d}[1], [x29], x1
+760c004c|	gnu	st4 {v22.2d-v25.2d}, [x3]
+ee0d9f4c|	gnu	st4 {v14.2d-v17.2d}, [x15],#64
+7800970c|	gnu	st4 {v24.8b-v27.8b}, [x3], x23
+a221200d|	gnu	st4 {v2.b-v5.b}[0], [x13]
+9a69204d|	gnu	st4 {v26.h-v29.h}[5], [x12]
+02a1204d|	gnu	st4 {v2.s-v5.s}[2], [x8]
+3fa6200d|	gnu	st4 {v31.d, v0.d, v1.d, v2.d}[0], [x17]
+943abf0d|	gnu	st4 {v20.b-v23.b}[6], [x20],#4
+bf26a60d|	gnu	st4 {v31.b, v0.b, v1.b, v2.b}[1], [x21], x6
+55b3bf4d|	gnu	st4 {v21.s-v24.s}[3], [x26],#16
+dda1b04d|	gnu	st4 {v29.s, v30.s, v31.s, v0.s}[2], [x14], x16
+6aa5bf0d|	gnu	st4 {v10.d-v13.d}[0], [x11],#32
+e7a7ac0d|	gnu	st4 {v7.d-v10.d}[0], [sp], x12
+f9c9202c|	gnu	stnp s25, s18, [x15,#-252]
+18b8316c|	gnu	stnp d24, d14, [x0,#-232]
+409c1cac|	gnu	stnp q0, q7, [x2,#912]
+73f0812c|	gnu	stp s19, s28, [x3],#12
+28d0826c|	gnu	stp d8, d20, [x1],#40
+9bf5bfac|	gnu	stp q27, q29, [x12],#-16
+885ead2d|	gnu	stp s8, s23, [x20,#-152]!
+b0de926d|	gnu	stp d16, d23, [x21,#296]!
+713387ad|	gnu	stp q17, q12, [x27,#224]!
+52130a2d|	gnu	stp s18, s4, [x26,#80]
+b63a236d|	gnu	stp d22, d14, [x21,#-464]
+6d5424ad|	gnu	stp q13, q21, [x3,#-896]
+afb60f3c|	gnu	str b15, [x21],#251
+81e7077c|	gnu	str h1, [x28],#126
+203713bc|	gnu	str s0, [x25],#-205
+60c61ffc|	gnu	str d0, [x19],#-4
+d256813c|	gnu	str q18, [x22],#21
+ffce083c|	gnu	str b31, [x23,#140]!
+6d3d017c|	gnu	str h13, [x11,#19]!
+52ed01bc|	gnu	str s18, [x10,#30]!
+fafd11fc|	gnu	str d26, [x15,#-225]!
+663e9b3c|	gnu	str q6, [x19,#-77]!
+7d0c393d|	gnu	str b29, [x3,#3651]
+8f50067d|	gnu	str h15, [x4,#808]
+94680dbd|	gnu	str s20, [x4,#3432]
+b7673bfd|	gnu	str d23, [x29,#30408]
+fed3a63d|	gnu	str q30, [sp,#39744]
+8a6a243c|	gnu	str b10, [x20,x4]
+29493fbc|	gnu	str s9, [x9,wzr,uxtw]
+8bd93bfc|	gnu	str d11, [x12,w27,sxtw #3]
+c768a93c|	gnu	str q7, [x6,x9]
+a7b00a3c|	gnu	stur b7, [x5,#171]
+40e3107c|	gnu	stur h0, [x26,#-242]
+18911fbc|	gnu	stur s24, [x8,#-7]
+fcc007fc|	gnu	stur d28, [x7,#124]
+db12893c|	gnu	stur q27, [x22,#145]
+1686716e|	gnu	sub v22.8h, v16.8h, v17.8h
+5362320e|	gnu	subhn v19.8b, v18.8h, v18.8h
+6163bf4e|	gnu	subhn2 v1.4s, v27.2d, v31.2d
+a73be05e|	gnu	suqadd d7, d29
+21a4100f|	gnu	sxtl v1.4s, v1.4h
+8b23164e|	gnu	tbl v11.16b, {v28.16b, v29.16b}, v22.16b
+3642120e|	gnu	tbl v22.8b, {v17.16b-v19.16b}, v18.8b
+cf611f0e|	gnu	tbl v15.8b, {v14.16b-v17.16b}, v31.8b
+0b020e4e|	gnu	tbl v11.16b, {v16.16b}, v14.16b
+9830014e|	gnu	tbx v24.16b, {v4.16b, v5.16b}, v1.16b
+1452044e|	gnu	tbx v20.16b, {v16.16b-v18.16b}, v4.16b
+b4711a0e|	gnu	tbx v20.8b, {v13.16b-v16.16b}, v26.8b
+f911140e|	gnu	tbx v25.8b, {v15.16b}, v20.8b
+9f28500e|	gnu	trn1 v31.4h, v4.4h, v16.4h
+2e69c64e|	gnu	trn2 v14.2d, v9.2d, v6.2d
+c752756e|	gnu	uabal2 v7.4s, v22.8h, v21.8h
+8675696e|	gnu	uabd v6.8h, v12.8h, v9.8h
+a973ab6e|	gnu	uabdl2 v9.2d, v29.4s, v11.4s
+fa006c2e|	gnu	uaddl v26.4s, v7.4h, v12.4h
+da00236e|	gnu	uaddl2 v26.8h, v6.16b, v3.16b
+ab3a306e|	gnu	uaddlv h11, v21.16b
+a312746e|	gnu	uaddw2 v3.4s, v21.4s, v20.8h
+cee55e7f|	gnu	ucvtf d14, d14, #34
+8edb617e|	gnu	ucvtf d14, d28
+ab8f431e|	gnu	ucvtf d11, w29, #29
+68b3039e|	gnu	ucvtf s8, x27, #20
+7686439e|	gnu	ucvtf d22, x19, #31
+2a03231e|	gnu	ucvtf s10, w25
+9f01631e|	gnu	ucvtf d31, w12
+a800239e|	gnu	ucvtf s8, x5
+0302639e|	gnu	ucvtf d3, x16
+df65a42e|	gnu	umax v31.2s, v14.2s, v4.2s
+29ab702e|	gnu	umaxv h9, v25.4h
+6f6e2e6e|	gnu	umin v15.16b, v19.16b, v14.16b
+fdada32e|	gnu	uminp v29.2s, v15.2s, v3.2s
+07289a6f|	gnu	umlal2 v7.2d, v0.4s, v26.s[2]
+aa80ad2e|	gnu	umlal v10.2d, v5.2s, v13.2s
+d66b462f|	gnu	umlsl v22.4s, v30.4h, v6.h[4]
+12a3b62e|	gnu	umlsl v18.2d, v24.2s, v22.2s
+583e0d0e|	gnu	umov w24, v18.b[6]
+20c3b52e|	gnu	umull v0.2d, v25.2s, v21.2s
+20c2616e|	gnu	umull2 v0.4s, v17.8h, v1.8h
+2f0f6d7e|	gnu	uqadd h15, h25, h13
+a60c272e|	gnu	uqadd v6.8b, v5.8b, v7.8b
+5b5da27e|	gnu	uqrshl s27, s10, s2
+195c786e|	gnu	uqrshl v25.8h, v0.8h, v24.8h
+209e282f|	gnu	uqrshrn v0.2s, v17.2d, #24
+e89e3b6f|	gnu	uqrshrn2 v8.4s, v23.2d, #5
+4f75147f|	gnu	uqshl h15, h10, #4
+d2767d6f|	gnu	uqshl v18.2d, v22.2d, #61
+bb4cfe7e|	gnu	uqshl d27, d5, d30
+794ea42e|	gnu	uqshl v25.2s, v19.2s, v4.2s
+51960b7f|	gnu	uqshrn b17, h18, #5
+642ce77e|	gnu	uqsub d4, d3, d7
+6149617e|	gnu	uqxtn h1, s11
+4e48a12e|	gnu	uqxtn v14.2s, v2.2d
+9cc8a14e|	gnu	urecpe v28.4s, v4.4s
+2f15a52e|	gnu	urhadd v15.2s, v9.2s, v5.2s
+5757fb7e|	gnu	urshl d23, d26, d27
+2756706e|	gnu	urshl v7.8h, v17.8h, v16.8h
+a424487f|	gnu	urshr d4, d5, #56
+b926796f|	gnu	urshr v25.2d, v21.2d, #7
+1336076f|	gnu	bic v19.4s, #0xf0, lsl #8
+e347e06e|	gnu	ushl v3.2d, v31.2d, v0.2d
+f7a5272f|	gnu	ushll v23.2d, v15.2s, #7
+9ba63d6f|	gnu	ushll2 v27.2d, v20.4s, #29
+d405737f|	gnu	ushr d20, d14, #13
+3a05116f|	gnu	ushr v26.8h, v9.8h, #15
+1d39607e|	gnu	usqadd h29, h8
+0e39e06e|	gnu	usqadd v14.2d, v8.2d
+8022b02e|	gnu	usubl v0.2d, v20.2s, v16.2s
+9a20786e|	gnu	usubl2 v26.4s, v4.8h, v24.8h
+df33692e|	gnu	usubw v31.4s, v30.4s, v9.4h
+92a5102f|	gnu	uxtl v18.4s, v12.4h
+0e19464e|	gnu	uzp1 v14.8h, v8.8h, v6.8h
+7629610e|	gnu	xtn v22.4h, v11.4s
+7338504e|	gnu	zip1 v19.8h, v3.8h, v16.8h
+357bd64e|	gnu	zip2 v21.2d, v25.2d, v22.2d
+63020f1a|	gnu	adc w3, w19, w15
+1f03159a|	gnu	adc xzr, x24, x21
+d300103a|	gnu	adcs w19, w6, w16
+1b0010ba|	gnu	adcs x27, x0, x16
+dd133f0b|	gnu	add w29, w30, wzr, uxtb #4
+89c42f8b|	gnu	add x9, x4, w15, sxtw #1
+4e242a11|	gnu	add w14, w2, #0xa89
+e1c12f2b|	gnu	adds w1, w15, w15, sxtw
+733421ab|	gnu	adds x19, x3, w1, uxth #5
+0ccc5aab|	gnu	adds x12, x0, x26, lsr #51
+51354470|	gnu	adr x17, .+0x886ab
+ef6796d0|	gnu	adrp x15, .+0xffffffff2ccfe000
+2e122612|	gnu	and w14, w17, #0x7c000000
+5e4c2992|	gnu	and x30, x2, #0xff8007ffff8007ff
+2805410a|	gnu	and w8, w9, w1, lsr #1
+ede1938a|	gnu	and x13, x15, x19, asr #56
+e7c10f72|	gnu	ands w7, w15, #0x2020202
+23ed55f2|	gnu	ands x3, x9, #0xfffff87fffffffff
+e6935bea|	gnu	ands x6, xzr, x27, lsr #36
+0e2ac61a|	gnu	asr w14, w16, w6
+802ad59a|	gnu	asr x0, x20, x21
+7cfd7793|	gnu	asr x28, x11, #55
+f028cd1a|	gnu	asr w16, w7, w13
+132bd29a|	gnu	asr x19, x24, x18
+c2560e54|	gnu	b.cs .+0x1cad8
+83516b17|	gnu	b .+0xfffffffffdad460c
+7a571233|	gnu	bfxil w26, w27, #18, #4
+71b858b3|	gnu	bfxil x17, x3, #24, #23
+c3964bb3|	gnu	bfxil x3, x22, #11, #27
+eb561233|	gnu	bfxil w11, w23, #18, #4
+063f5db3|	gnu	bfi x6, x24, #35, #16
+0a337a0a|	gnu	bic w10, w24, w26, lsr #12
+2a71e28a|	gnu	bic x10, x9, x2, ror #28
+c168bf6a|	gnu	bics w1, w6, wzr, asr #26
+d8bb3cea|	gnu	bics x24, x30, x28, lsl #46
+82e81795|	gnu	bl .+0x45fa208
+40033fd6|	gnu	blr x26
+c0011fd6|	gnu	br x14
+00dd31d4|	gnu	brk #0x8ee8
+7267db35|	gnu	cbnz w18, .+0xfffffffffffb6cec
+e44c7fb5|	gnu	cbnz x4, .+0xfe99c
+9dc4c334|	gnu	cbz w29, .+0xfffffffffff87890
+376eceb4|	gnu	cbz x23, .+0xfffffffffff9cdc4
+a6cb563a|	gnu	ccmn w29, #0x16, #0x6, gt
+87db55ba|	gnu	ccmn x28, #0x15, #0x7, le
+a042493a|	gnu	ccmn w21, w9, #0x0, mi
+6a0040ba|	gnu	ccmn x3, x0, #0xa, eq
+46bb5c7a|	gnu	ccmp w26, #0x1c, #0x6, lt
+c72942fa|	gnu	ccmp x14, #0x2, #0x7, cs
+cda1427a|	gnu	ccmp w14, w2, #0xd, ge
+a1314dfa|	gnu	ccmp x13, x13, #0x1, cc
+8706931a|	gnu	csinc w7, w20, w19, eq
+3ae69a9a|	gnu	csinc x26, x17, x26, al
+9e51945a|	gnu	csinv w30, w12, w20, pl
+d5e386da|	gnu	csinv x21, x30, x6, al
+5f3503d5|	gnu	clrex #0x5
+e515c05a|	gnu	cls w5, w15
+a815c0da|	gnu	cls x8, x13
+4a12c05a|	gnu	clz w10, w18
+3c10c0da|	gnu	clz x28, x1
+ff70252b|	gnu	cmn w7, w5, uxtx #4
+9fa133ab|	gnu	cmn x12, w19, sxth
+3f3a822b|	gnu	cmn w17, w2, asr #14
+df1d44ab|	gnu	cmn x14, x4, lsr #7
+3f95386b|	gnu	cmp w9, w24, sxtb #5
+9f653feb|	gnu	cmp x12, xzr, uxtx #1
+1626915a|	gnu	csneg w22, w16, w17, cs
+b4d587da|	gnu	csneg x20, x13, x7, le
+9841d41a|	gnu	crc32b w24, w12, w20
+ec45d01a|	gnu	crc32h w12, w15, w16
+8048ca1a|	gnu	crc32w w0, w4, w10
+d44ec19a|	gnu	crc32x w20, w22, x1
+1552d31a|	gnu	crc32cb w21, w16, w19
+4b54c71a|	gnu	crc32ch w11, w2, w7
+245ad41a|	gnu	crc32cw w4, w17, w20
+c35cc89a|	gnu	crc32cx w3, w6, x8
+14219f1a|	gnu	csel w20, w8, wzr, cs
+9c73979a|	gnu	csel x28, x28, x23, vc
+e7279f1a|	gnu	cset w7, cc
+ec579f9a|	gnu	cset x12, mi
+e5f39f5a|	gnu	csinv w5, wzr, wzr, al
+e8639fda|	gnu	csetm x8, vc
+ea76971a|	gnu	cinc w10, w23, vs
+78a7859a|	gnu	csinc x24, x27, x5, ge
+b590845a|	gnu	csinv w21, w5, w4, ls
+b4029eda|	gnu	csinv x20, x21, x30, eq
+b3969b5a|	gnu	csneg w19, w21, w27, ls
+938591da|	gnu	csneg x19, x12, x17, hi
+016ea8d4|	gnu	dcps1 #0x4370
+0275a4d4|	gnu	dcps2 #0x23a8
+a3e9a6d4|	gnu	dcps3 #0x374d
+bf3903d5|	gnu	dmb ishld
+e003bfd6|	gnu	drps
+9f3e03d5|	gnu	dsb st
+50b1a0ca|	gnu	eon x16, x10, x0, asr #44
+c0b02f52|	gnu	eor w0, w6, #0x3ffe3ffe
+4b0c1ed2|	gnu	eor x11, x2, #0x3c0000003c
+693c074a|	gnu	eor w9, w3, w7, lsl #15
+113e1aca|	gnu	eor x17, x16, x26, lsl #15
+e0039fd6|	gnu	eret
+fef8c693|	gnu	extr x30, x7, x6, #62
+3f2003d5|	gnu	yield
+3f2403d5|	gnu	hint #0x21
+c0425ad4|	gnu	hlt #0xd216
+df3003d5|	gnu	isb #0x0
+f7fddf88|	gnu	ldar w23, [x15]
+96fedfc8|	gnu	ldar x22, [x20]
+11fedf08|	gnu	ldarb w17, [x16]
+c2fedf48|	gnu	ldarh w2, [x22]
+2d927f88|	gnu	ldaxp w13, w4, [x17]
+198f7fc8|	gnu	ldaxp x25, x3, [x24]
+46ff5f88|	gnu	ldaxr w6, [x26]
+81fe5fc8|	gnu	ldaxr x1, [x20]
+86fe5f08|	gnu	ldaxrb w6, [x20]
+78ff5f48|	gnu	ldaxrh w24, [x27]
+35864a28|	gnu	ldnp w21, w1, [x17,#84]
+6da05fa8|	gnu	ldnp x13, x8, [x3,#504]
+a8f9f428|	gnu	ldp w8, w30, [x13],#-92
+b749e3a8|	gnu	ldp x23, x18, [x13],#-464
+bdedd929|	gnu	ldp w29, w27, [x13,#204]!
+c8e5c6a9|	gnu	ldp x8, x25, [x14,#104]!
+c0857f29|	gnu	ldp w0, w1, [x14,#-4]
+388a6ca9|	gnu	ldp x24, x2, [x17,#-312]
+086be468|	gnu	ldpsw x8, x26, [x24],#-224
+d107d269|	gnu	ldpsw x17, x1, [x30,#144]!
+738e4e69|	gnu	ldpsw x19, x3, [x19,#116]
+6ee55fb8|	gnu	ldr w14, [x11],#-2
+233459f8|	gnu	ldr x3, [x1],#-109
+919f44b8|	gnu	ldr w17, [x28,#73]!
+acdd45f8|	gnu	ldr x12, [x13,#93]!
+e1cd51b9|	gnu	ldr w1, [x15,#4556]
+95e27bf9|	gnu	ldr x21, [x20,#30656]
+09c4fa18|	gnu	ldr w9, .+0xffffffffffff5880
+f528ad58|	gnu	ldr x21, .+0xfffffffffff5a51c
+0c554b38|	gnu	ldrb w12, [x8],#181
+054f5938|	gnu	ldrb w5, [x24,#-108]!
+1f206539|	gnu	ldrb wzr, [x0,#2376]
+73796a38|	gnu	ldrb w19, [x11,x10,lsl #0]
+a8b74f78|	gnu	ldrh w8, [x29],#251
+021e5e78|	gnu	ldrh w2, [x16,#-31]!
+ec126b79|	gnu	ldrh w12, [x23,#5512]
+fc5a6178|	gnu	ldrh w28, [x23,w1,uxtw #1]
+eaf6c238|	gnu	ldrsb w10, [x23],#47
+87679838|	gnu	ldrsb x7, [x28],#-122
+567fdb38|	gnu	ldrsb w22, [x26,#-73]!
+3b2e8138|	gnu	ldrsb x27, [x17,#18]!
+7d74c039|	gnu	ldrsb w29, [x3,#29]
+7d1f8539|	gnu	ldrsb x29, [x27,#327]
+225bff38|	gnu	ldrsb w2, [x25,wzr,uxtw #0]
+6a7bed38|	gnu	ldrsb w10, [x27,x13,lsl #0]
+0f69b538|	gnu	ldrsb x15, [x8,x21]
+c796cc78|	gnu	ldrsh w7, [x22],#201
+50268e78|	gnu	ldrsh x16, [x18],#226
+229ddb78|	gnu	ldrsh w2, [x9,#-71]!
+0f4f9178|	gnu	ldrsh x15, [x24,#-236]!
+59ecc379|	gnu	ldrsh w25, [x2,#502]
+83d49679|	gnu	ldrsh x3, [x4,#2922]
+986be878|	gnu	ldrsh w24, [x28,x8]
+cad8bf78|	gnu	ldrsh x10, [x6,wzr,sxtw #1]
+6b4693b8|	gnu	ldrsw x11, [x19],#-204
+cb9e81b8|	gnu	ldrsw x11, [x22,#25]!
+280d9eb9|	gnu	ldrsw x8, [x9,#7692]
+93dec198|	gnu	ldrsw x19, .+0xfffffffffff83bd0
+1a68b8b8|	gnu	ldrsw x26, [x0,x24]
+35b955b8|	gnu	ldtr w21, [x9,#-165]
+658b57f8|	gnu	ldtr x5, [x27,#-136]
+b3594038|	gnu	ldtrb w19, [x13,#5]
+5ac95d78|	gnu	ldtrh w26, [x10,#-36]
+2c3ade38|	gnu	ldtrsb w12, [x17,#-29]
+4de99038|	gnu	ldtrsb x13, [x10,#-242]
+e178c378|	gnu	ldtrsh w1, [x7,#55]
+a77a8778|	gnu	ldtrsh x7, [x21,#119]
+cde982b8|	gnu	ldtrsw x13, [x14,#46]
+04d15bb8|	gnu	ldur w4, [x8,#-67]
+02a256f8|	gnu	ldur x2, [x16,#-150]
+97405438|	gnu	ldurb w23, [x4,#-188]
+99b14b78|	gnu	ldurh w25, [x12,#187]
+f9a1cf38|	gnu	ldursb w25, [x15,#250]
+c0218c38|	gnu	ldursb x0, [x14,#194]
+5790d278|	gnu	ldursh w23, [x2,#-215]
+a3808278|	gnu	ldursh x3, [x5,#40]
+a9b08fb8|	gnu	ldursw x9, [x5,#251]
+98217f88|	gnu	ldxp w24, w8, [x12]
+4d6a7fc8|	gnu	ldxp x13, x26, [x18]
+9c7e5f88|	gnu	ldxr w28, [x20]
+0e7c5fc8|	gnu	ldxr x14, [x0]
+507c5f08|	gnu	ldxrb w16, [x2]
+ea7f5f48|	gnu	ldxrh w10, [sp]
+5523dd1a|	gnu	lsl w21, w26, w29
+9721ca9a|	gnu	lsl x23, x12, x10
+75665bd3|	gnu	ubfiz x21, x19, #37, #26
+0a20df1a|	gnu	lsl w10, w0, wzr
+5222c99a|	gnu	lsl x18, x18, x9
+5124df1a|	gnu	lsr w17, w2, wzr
+6b26d69a|	gnu	lsr x11, x19, x22
+9a7c0753|	gnu	lsr w26, w4, #7
+7bfd53d3|	gnu	lsr x27, x11, #19
+5f26d91a|	gnu	lsr wzr, w18, w25
+3625d89a|	gnu	lsr x22, x9, x24
+9d76001b|	gnu	madd w29, w20, w0, w29
+822f0e9b|	gnu	madd x2, x28, x14, x11
+e8fe101b|	gnu	mneg w8, w23, w16
+88fc099b|	gnu	mneg x8, x4, x9
+dd030011|	gnu	add w29, w30, #0x0
+db010091|	gnu	add x27, x14, #0x0
+0c6db012|	gnu	mov w12, #0x7c97ffff
+3ff5aa92|	gnu	mov xzr, #0xffffffffa856ffff
+87f0f6d2|	gnu	mov x7, #0xb784000000000000
+f3571132|	gnu	orr w19, wzr, #0xffff801f
+f3bb0bb2|	gnu	mov x19, #0xffefffefffefffef
+f103082a|	gnu	mov w17, w8
+ef031faa|	gnu	mov x15, xzr
+4a6bf5f2|	gnu	movk x10, #0xab5a, lsl #48
+383b9312|	gnu	mov w24, #0xffff6626
+f5fb9092|	gnu	mov x21, #0xffffffffffff7820
+d5b4b052|	gnu	mov w21, #0x85a60000
+fdc5eed2|	gnu	mov x29, #0x762f000000000000
+c58435d5|	gnu	mrs x5, s2_5_c8_c4_6
+1a0f13d5|	gnu	msr s2_3_c0_c15_0, x26
+52d5181b|	gnu	msub w18, w10, w24, w21
+c4f81d9b|	gnu	msub x4, x6, x29, x30
+a57c1b1b|	gnu	mul w5, w5, w27
+8f7f0a9b|	gnu	mul x15, x28, x10
+e75361aa|	gnu	mvn x7, x1, lsr #20
+e0cb15cb|	gnu	neg x0, x21, lsl #50
+ffdb49eb|	gnu	cmp xzr, x9, lsr #54
+f5031c5a|	gnu	ngc w21, w28
+e6031eda|	gnu	ngc x6, x30
+e103077a|	gnu	ngcs w1, w7
+f20301fa|	gnu	ngcs x18, x1
+1f2003d5|	gnu	nop
+9347722a|	gnu	orn w19, w28, w18, lsr #17
+0591e1aa|	gnu	orn x5, x8, x1, ror #36
+7ba82a32|	gnu	orr w27, w3, #0xffc1ffc1
+ae087db2|	gnu	orr x14, x5, #0x38
+9608472a|	gnu	orr w22, w4, w7, lsr #2
+c40dc5aa|	gnu	orr x4, x14, x5, ror #3
+9d83bcf9|	gnu	prfm #0x1d, [x28,#30976]
+78ab03d8|	gnu	prfm #0x18, .+0x756c
+6e9186f8|	gnu	prfum #0x0e, [x11,#105]
+c001c05a|	gnu	rbit w0, w14
+4203c0da|	gnu	rbit x2, x26
+c0035fd6|	gnu	ret
+9b08c05a|	gnu	rev w27, w4
+740cc0da|	gnu	rev x20, x3
+0205c05a|	gnu	rev16 w2, w8
+dd07c0da|	gnu	rev16 x29, x30
+020bc0da|	gnu	rev32 x2, x24
+780cc0da|	gnu	rev x24, x3
+9b7f9513|	gnu	extr w27, w28, w21, #31
+5243dd93|	gnu	extr x18, x26, x29, #16
+822eca1a|	gnu	ror w2, w20, w10
+f02ddb9a|	gnu	ror x16, x15, x27
+082ed81a|	gnu	ror w8, w16, w24
+7b2cc39a|	gnu	ror x27, x3, x3
+3b030b5a|	gnu	sbc w27, w25, w11
+f2021dda|	gnu	sbc x18, x23, x29
+e600127a|	gnu	sbcs w6, w7, w18
+cf030ffa|	gnu	sbcs x15, x30, x15
+3a797793|	gnu	sbfiz x26, x9, #9, #31
+4a305193|	gnu	sbfiz x10, x2, #47, #13
+a1c74493|	gnu	sbfx x1, x29, #4, #46
+a00fc01a|	gnu	sdiv w0, w29, w0
+f10edd9a|	gnu	sdiv x17, x23, x29
+9f2003d5|	gnu	sev
+bf2003d5|	gnu	sevl
+a52d319b|	gnu	smaddl x5, w13, w17, x11
+b4fc399b|	gnu	smnegl x20, w5, w25
+579e369b|	gnu	smsubl x23, w18, w22, x7
+ea7e429b|	gnu	smulh x10, x23, x2
+eb7f219b|	gnu	smull x11, wzr, w1
+f1fe9f88|	gnu	stlr w17, [x23]
+edff9fc8|	gnu	stlr x13, [sp]
+bffe9f08|	gnu	stlrb wzr, [x21]
+9cfd9f48|	gnu	stlrh w28, [x12]
+41bf2688|	gnu	stlxp w6, w1, w15, [x26]
+01e93cc8|	gnu	stlxp w28, x1, x26, [x8]
+e0fd1f88|	gnu	stlxr wzr, w0, [x15]
+12fe17c8|	gnu	stlxr w23, x18, [x16]
+d4fc1008|	gnu	stlxrb w16, w20, [x6]
+befc0048|	gnu	stlxrh w0, w30, [x5]
+76613728|	gnu	stnp w22, w24, [x11,#-72]
+c7523ba8|	gnu	stnp x7, x20, [x22,#-80]
+8e3a9f28|	gnu	stp w14, w14, [x20],#248
+aa1fa6a8|	gnu	stp x10, x7, [x29],#-416
+fbae8d29|	gnu	stp w27, w11, [x23,#108]!
+f63c80a9|	gnu	stp x22, x15, [x7,#0]!
+43d73629|	gnu	stp w3, w21, [x26,#-76]
+1ae01ba9|	gnu	stp x26, x24, [x0,#440]
+8f650cb8|	gnu	str w15, [x12],#198
+aad503f8|	gnu	str x10, [x13],#61
+ec4d00b8|	gnu	str w12, [x15,#4]!
+7dbc1df8|	gnu	str x29, [x3,#-37]!
+9b0226b9|	gnu	str w27, [x20,#9728]
+91691af9|	gnu	str x17, [x12,#13520]
+20840838|	gnu	strb w0, [x1],#136
+060c1f38|	gnu	strb w6, [x0,#-16]!
+2b213a39|	gnu	strb w11, [x9,#3720]
+ab6b3438|	gnu	strb w11, [x29,x20]
+50e51e78|	gnu	strh w16, [x10],#-18
+5d5d1878|	gnu	strh w29, [x10,#-123]!
+ea862379|	gnu	strh w10, [x23,#4546]
+d65a2778|	gnu	strh w22, [x22,w7,uxtw #1]
+d5ca12b8|	gnu	sttr w21, [x22,#-212]
+001b18f8|	gnu	sttr x0, [x24,#-127]
+290a1e38|	gnu	sttrb w9, [x17,#-32]
+0b381078|	gnu	sttrh w11, [x0,#-253]
+c78101b8|	gnu	stur w7, [x14,#24]
+c0b217f8|	gnu	stur x0, [x22,#-133]
+f8401e38|	gnu	sturb w24, [x7,#-28]
+5e911a78|	gnu	sturh w30, [x10,#-87]
+b7622d88|	gnu	stxp w13, w23, w24, [x21]
+233d37c8|	gnu	stxp w23, x3, x15, [x9]
+847d0088|	gnu	stxr w0, w4, [x12]
+a27d0bc8|	gnu	stxr w11, x2, [x13]
+f27f1e08|	gnu	stxrb w30, w18, [sp]
+3a7d1848|	gnu	stxrh w24, w26, [x9]
+d4dc204b|	gnu	sub w20, w6, w0, sxtw #7
+874023cb|	gnu	sub x7, x4, w3, uxtw
+44eb4f51|	gnu	sub w4, w26, #0x3fa, lsl #12
+17b012cb|	gnu	sub x23, x0, x18, lsl #44
+ac1e376b|	gnu	subs w12, w21, w23, uxtb #7
+b0483beb|	gnu	subs x16, x5, w27, uxtw #2
+d1f994eb|	gnu	subs x17, x14, x20, asr #62
+61d513d4|	gnu	svc #0x9eab
+591d0013|	gnu	sxtb w25, w10
+9f1f4093|	gnu	sxtb xzr, w28
+773f0013|	gnu	sxth w23, w27
+453c4093|	gnu	sxth x5, w2
+b77c4093|	gnu	sxtw x23, w5
+743628d5|	gnu	sysl x20, #0, C3, C6, #3
+6fd248b7|	gnu	tbnz x15, #41, .+0x1a4c
+5afe3036|	gnu	tbz w26, #6, .+0x1fc8
+9f613672|	gnu	tst w12, #0xfffffc07
+1f8d22f2|	gnu	tst x8, #0xc003c003c003c003
+ff6e93ea|	gnu	tst x23, x19, asr #27
+06997ed3|	gnu	ubfiz x6, x8, #2, #39
+5dd054d3|	gnu	ubfx x29, x2, #20, #33
+a54273d3|	gnu	ubfiz x5, x21, #13, #17
+7d08d11a|	gnu	udiv w29, w3, w17
+120acf9a|	gnu	udiv x18, x16, x15
+1401a89b|	gnu	umaddl x20, w8, w8, x0
+08feb29b|	gnu	umnegl x8, w16, w18
+eeb0b99b|	gnu	umsubl x14, w7, w25, x12
+967fdd9b|	gnu	umulh x22, x28, x29
+947eb59b|	gnu	umull x20, w20, w21
+7e1f0053|	gnu	uxtb w30, w27
+983c0053|	gnu	uxth w24, w4
+5f2003d5|	gnu	wfe
+7f2003d5|	gnu	wfi
+3f2003d5|	gnu	yield
+02bb200e|	gnu	abs v2.8b, v24.8b
+0686ec4e|	gnu	add v6.2d, v16.2d, v12.2d
+ea42ac0e|	gnu	addhn v10.2s, v23.2d, v12.2d
+7d43624e|	gnu	addhn2 v29.8h, v27.4s, v2.4s
+2cbd710e|	gnu	addp v12.4h, v9.4h, v17.4h
+f5bab14e|	gnu	addv s21, v23.4s
+8158284e|	gnu	aesd v1.16b, v4.16b
+ba48284e|	gnu	aese v26.16b, v5.16b
+0c7a284e|	gnu	aesimc v12.16b, v16.16b
+3e6a284e|	gnu	aesmc v30.16b, v17.16b
+091f384e|	gnu	and v9.16b, v24.16b, v24.16b
+07b6046f|	gnu	bic v7.8h, #0x90, lsl #8
+00c5006f|	gnu	mvni v0.4s, #0x8, msl #8
+f81e6c0e|	gnu	bic v24.8b, v23.8b, v12.8b
+6f1ced2e|	gnu	bif v15.8b, v3.8b, v13.8b
+e31da16e|	gnu	bit v3.16b, v15.16b, v1.16b
+6a1d7c6e|	gnu	bsl v10.16b, v11.16b, v28.16b
+284a600e|	gnu	cls v8.4h, v17.4h
+9a49202e|	gnu	clz v26.8b, v12.8b
+d78f706e|	gnu	cmeq v23.8h, v30.8h, v16.8h
+7798e05e|	gnu	cmeq d23, d3, #0
+739a200e|	gnu	cmeq v19.8b, v19.8b, #0
+ff3f2b4e|	gnu	cmge v31.16b, v31.16b, v11.16b
+5337370e|	gnu	cmgt v19.8b, v26.8b, v23.8b
+3489604e|	gnu	cmgt v20.8h, v9.8h, #0
+083d782e|	gnu	cmhs v8.4h, v8.4h, v24.4h
+c899e07e|	gnu	cmle d8, d14, #0
+3498a06e|	gnu	cmle v20.4s, v1.4s, #0
+ebaa200e|	gnu	cmlt v11.8b, v23.8b, #0
+408dfe4e|	gnu	cmtst v0.2d, v10.2d, v30.2d
+0e06085e|	gnu	mov d14, v16.d[0]
+1e0d0d0e|	gnu	dup v30.8b, w8
+8e1d3a6e|	gnu	eor v14.16b, v12.16b, v26.16b
+632a086e|	gnu	ext v3.16b, v19.16b, v8.16b, #5
+97d7e57e|	gnu	fabd d23, d28, d5
+6bd4a82e|	gnu	fabd v11.2s, v3.2s, v8.2s
+f7faa00e|	gnu	fabs v23.2s, v23.2s
+54c2201e|	gnu	fabs s20, s18
+3ec3601e|	gnu	fabs d30, d25
+2aee317e|	gnu	facge s10, s17, s17
+2fed392e|	gnu	facge v15.2s, v9.2s, v25.2s
+2befe97e|	gnu	facgt d11, d25, d9
+65eced6e|	gnu	facgt v5.2d, v3.2d, v13.2d
+55d53c4e|	gnu	fadd v21.4s, v10.4s, v28.4s
+8b283f1e|	gnu	fadd s11, s4, s31
+d828601e|	gnu	fadd d24, d6, d0
+e9d8307e|	gnu	faddp s9, v7.2s
+4084391e|	gnu	fccmp s2, s25, #0x0, hi
+ef046d1e|	gnu	fccmp d7, d13, #0xf, eq
+d7a4241e|	gnu	fccmpe s6, s4, #0x7, ge
+dbf5601e|	gnu	fccmpe d14, d0, #0xb, al
+77e7625e|	gnu	fcmeq d23, d27, d2
+2de67f4e|	gnu	fcmeq v13.2d, v17.2d, v31.2d
+59daa05e|	gnu	fcmeq s25, s18, #0
+add9a00e|	gnu	fcmeq v13.2s, v13.2s, #0
+dce42d7e|	gnu	fcmge s28, s6, s13
+62e6776e|	gnu	fcmge v2.2d, v19.2d, v23.2d
+f9cae07e|	gnu	fcmge d25, d23, #0
+18e5ab7e|	gnu	fcmgt s24, s8, s11
+84e7ae6e|	gnu	fcmgt v4.4s, v28.4s, v14.4s
+a0c8e05e|	gnu	fcmgt d0, d5, #0
+c6cae04e|	gnu	fcmgt v6.2d, v22.2d, #0
+4fdaa07e|	gnu	fcmle s15, s18, #0
+e1d9a02e|	gnu	fcmle v1.2s, v15.2s, #0
+1ee9a05e|	gnu	fcmlt s30, s8, #0
+23eaa04e|	gnu	fcmlt v3.4s, v17.4s, #0
+6023321e|	gnu	fcmp s27, s18
+2823391e|	gnu	fcmp s25, #0
+00236d1e|	gnu	fcmp d24, d13
+e820601e|	gnu	fcmp d7, #0
+3022381e|	gnu	fcmpe s17, s24
+f8233e1e|	gnu	fcmpe s31, #0
+b0206a1e|	gnu	fcmpe d5, d10
+3820691e|	gnu	fcmpe d1, #0
+d85f271e|	gnu	fcsel s24, s30, s7, pl
+ed8f7a1e|	gnu	fcsel d13, d31, d26, hi
+0042e21e|	gnu	fcvt s0, h16
+efc1e21e|	gnu	fcvt d15, h15
+edc1231e|	gnu	fcvt h13, s15
+0ac0221e|	gnu	fcvt d10, s0
+39c3631e|	gnu	fcvt h25, d25
+da43621e|	gnu	fcvt s26, d30
+10cb615e|	gnu	fcvtas d16, d24
+f400241e|	gnu	fcvtas w20, s7
+2f00249e|	gnu	fcvtas x15, s1
+1d02641e|	gnu	fcvtas w29, d16
+9303649e|	gnu	fcvtas x19, d28
+02ca217e|	gnu	fcvtau s2, s16
+afc8212e|	gnu	fcvtau v15.2s, v5.2s
+6e02251e|	gnu	fcvtau w14, s19
+fd02259e|	gnu	fcvtau x29, s23
+8603651e|	gnu	fcvtau w6, d28
+4001659e|	gnu	fcvtau x0, d10
+1f78210e|	gnu	fcvtl v31.4s, v0.4h
+d179214e|	gnu	fcvtl2 v17.4s, v14.8h
+fdbb615e|	gnu	fcvtms d29, d31
+9601301e|	gnu	fcvtms w22, s12
+f403309e|	gnu	fcvtms x20, s31
+6b02701e|	gnu	fcvtms w11, d19
+4802709e|	gnu	fcvtms x8, d18
+84ba217e|	gnu	fcvtmu s4, s20
+ae01311e|	gnu	fcvtmu w14, s13
+8402319e|	gnu	fcvtmu x4, s20
+7403711e|	gnu	fcvtmu w20, d27
+2a03719e|	gnu	fcvtmu x10, d25
+a36b210e|	gnu	fcvtn v3.4h, v29.4s
+5c6a214e|	gnu	fcvtn2 v28.8h, v18.4s
+78a9215e|	gnu	fcvtns s24, s11
+b1ab614e|	gnu	fcvtns v17.2d, v29.2d
+0c01201e|	gnu	fcvtns w12, s8
+b303209e|	gnu	fcvtns x19, s29
+c401601e|	gnu	fcvtns w4, d14
+5200609e|	gnu	fcvtns x18, d2
+c2a8617e|	gnu	fcvtnu d2, d6
+daab616e|	gnu	fcvtnu v26.2d, v30.2d
+d001211e|	gnu	fcvtnu w16, s14
+0402219e|	gnu	fcvtnu x4, s16
+7800611e|	gnu	fcvtnu w24, d3
+e602619e|	gnu	fcvtnu x6, d23
+74aaa15e|	gnu	fcvtps s20, s19
+c801281e|	gnu	fcvtps w8, s14
+8f02289e|	gnu	fcvtps x15, s20
+6d02681e|	gnu	fcvtps w13, d19
+bc00689e|	gnu	fcvtps x28, d5
+43aba17e|	gnu	fcvtpu s3, s26
+cda9a12e|	gnu	fcvtpu v13.2s, v14.2s
+c102291e|	gnu	fcvtpu w1, s22
+9103299e|	gnu	fcvtpu x17, s28
+7602691e|	gnu	fcvtpu w22, d19
+4501699e|	gnu	fcvtpu x5, d10
+976a616e|	gnu	fcvtxn2 v23.4s, v20.2d
+d5fc575f|	gnu	fcvtzs d21, d6, #41
+babaa15e|	gnu	fcvtzs s26, s21
+7aa6181e|	gnu	fcvtzs w26, s19, #23
+c410189e|	gnu	fcvtzs x4, s6, #60
+4db5589e|	gnu	fcvtzs x13, d10, #19
+9000381e|	gnu	fcvtzs w16, s4
+1702389e|	gnu	fcvtzs x23, s16
+8a03781e|	gnu	fcvtzs w10, d28
+d501789e|	gnu	fcvtzs x21, d14
+eefd2d7f|	gnu	fcvtzu s14, s15, #19
+4dfc3c6f|	gnu	fcvtzu v13.4s, v2.4s, #4
+96bbe17e|	gnu	fcvtzu d22, d28
+30b8e16e|	gnu	fcvtzu v16.2d, v1.2d
+fdef191e|	gnu	fcvtzu w29, s31, #5
+1d7b199e|	gnu	fcvtzu x29, s24, #34
+b8f5591e|	gnu	fcvtzu w24, d13, #3
+5080599e|	gnu	fcvtzu x16, d2, #32
+d002391e|	gnu	fcvtzu w16, s22
+9b03399e|	gnu	fcvtzu x27, s28
+7501791e|	gnu	fcvtzu w21, d11
+7603799e|	gnu	fcvtzu x22, d27
+06fe3c6e|	gnu	fdiv v6.4s, v16.4s, v28.4s
+c41b201e|	gnu	fdiv s4, s30, s0
+1618781e|	gnu	fdiv d22, d0, d24
+507b0d1f|	gnu	fmadd s16, s26, s13, s30
+8803491f|	gnu	fmadd d8, d28, d9, d0
+75f7394e|	gnu	fmax v21.4s, v27.4s, v25.4s
+804b3c1e|	gnu	fmax s0, s28, s28
+c1496c1e|	gnu	fmax d1, d14, d12
+5b69371e|	gnu	fmaxnm s27, s10, s23
+1468711e|	gnu	fmaxnm d20, d0, d17
+a4c8707e|	gnu	fmaxnmp d4, v5.2d
+89f9707e|	gnu	fmaxp d9, v12.2d
+4af63e2e|	gnu	fmaxp v10.2s, v18.2s, v30.2s
+25fa306e|	gnu	fmaxv s5, v17.4s
+01f4e04e|	gnu	fmin v1.2d, v0.2d, v0.2d
+59592a1e|	gnu	fmin s25, s10, s10
+3959611e|	gnu	fmin d25, d9, d1
+73c7ba4e|	gnu	fminnm v19.4s, v27.4s, v26.4s
+1279391e|	gnu	fminnm s18, s8, s25
+75796c1e|	gnu	fminnm d21, d11, d12
+90cbb07e|	gnu	fminnmp s16, v28.2s
+c5c8b06e|	gnu	fminnmv s5, v6.4s
+cdfbf07e|	gnu	fminp d13, v30.2d
+edf6f66e|	gnu	fminp v13.2d, v23.2d, v22.2d
+6513b85f|	gnu	fmla s5, s27, v24.s[1]
+ee18984f|	gnu	fmla v14.4s, v7.4s, v24.s[2]
+b85ab75f|	gnu	fmls s24, s21, v23.s[3]
+a3f5030f|	gnu	fmov v3.2s, #9.062500000000000000e-01
+eaf7056f|	gnu	fmov v10.2d, #-3.100000000000000000e+01
+3b41201e|	gnu	fmov s27, s9
+0d41601e|	gnu	fmov d13, d8
+9700271e|	gnu	fmov s23, w4
+ad03261e|	gnu	fmov w13, s29
+2302679e|	gnu	fmov d3, x17
+e101af9e|	gnu	fmov v1.d[1], x15
+f301669e|	gnu	fmov x19, d15
+1103ae9e|	gnu	fmov x17, v24.d[1]
+0230321e|	gnu	fmov s2, #-4.250000000000000000e+00
+18b0751e|	gnu	fmov d24, #-1.450000000000000000e+01
+92bc1b1f|	gnu	fmsub s18, s4, s27, s15
+f8e14a1f|	gnu	fmsub d24, d15, d10, d24
+ef91d35f|	gnu	fmul d15, d15, v19.d[0]
+d293c24f|	gnu	fmul v18.2d, v30.2d, v2.d[0]
+18dd2b2e|	gnu	fmul v24.2s, v8.2s, v11.2s
+a4093d1e|	gnu	fmul s4, s13, s29
+94096f1e|	gnu	fmul d20, d12, d15
+fe918e7f|	gnu	fmulx s30, s15, v14.s[0]
+7199c56f|	gnu	fmulx v17.2d, v11.2d, v5.d[1]
+32dc695e|	gnu	fmulx d18, d1, d9
+c8f9e06e|	gnu	fneg v8.2d, v14.2d
+9c41211e|	gnu	fneg s28, s12
+c443611e|	gnu	fneg d4, d30
+e77f301f|	gnu	fnmadd s7, s31, s16, s31
+9f326c1f|	gnu	fnmadd d31, d20, d12, d12
+d9e92f1f|	gnu	fnmsub s25, s14, s15, s26
+00ad711f|	gnu	fnmsub d0, d8, d17, d11
+c889211e|	gnu	fnmul s8, s14, s1
+528b761e|	gnu	fnmul d18, d26, d22
+01d8e15e|	gnu	frecpe d1, d0
+9aff7e5e|	gnu	frecps d26, d28, d30
+78fe2a4e|	gnu	frecps v24.4s, v19.4s, v10.4s
+01f9e15e|	gnu	frecpx d1, d8
+128b216e|	gnu	frinta v18.4s, v24.4s
+b241261e|	gnu	frinta s18, s13
+a841661e|	gnu	frinta d8, d13
+799aa16e|	gnu	frinti v25.4s, v19.4s
+1cc2271e|	gnu	frinti s28, s16
+93c2671e|	gnu	frinti d19, d20
+1a40251e|	gnu	frintm s26, s0
+ac42651e|	gnu	frintm d12, d21
+5889214e|	gnu	frintn v24.4s, v10.4s
+5740241e|	gnu	frintn s23, s2
+9443641e|	gnu	frintn d20, d28
+4b89a10e|	gnu	frintp v11.2s, v10.2s
+a0c1241e|	gnu	frintp s0, s13
+93c2641e|	gnu	frintp d19, d20
+d49b216e|	gnu	frintx v20.4s, v30.4s
+df41271e|	gnu	frintx s31, s14
+8d41671e|	gnu	frintx d13, d12
+3998a10e|	gnu	frintz v25.2s, v1.2s
+fdc2251e|	gnu	frintz s29, s23
+abc2651e|	gnu	frintz d11, d21
+10dba17e|	gnu	frsqrte s16, s24
+edd9e16e|	gnu	frsqrte v13.2d, v15.2d
+75ffe35e|	gnu	frsqrts d21, d27, d3
+b4fdbe4e|	gnu	frsqrts v20.4s, v13.4s, v30.4s
+24f8a16e|	gnu	fsqrt v4.4s, v1.4s
+b6c1211e|	gnu	fsqrt s22, s13
+c1c3611e|	gnu	fsqrt d1, d30
+ffd5b44e|	gnu	fsub v31.4s, v15.4s, v20.4s
+d438331e|	gnu	fsub s20, s6, s19
+f038771e|	gnu	fsub d16, d7, d23
+675e1a6e|	gnu	mov v7.h[6], v19.h[5]
+2a1c0a4e|	gnu	mov v10.h[2], w1
+de7f400c|	gnu	ld1 {v30.1d}, [x30]
+4aa7404c|	gnu	ld1 {v10.8h, v11.8h}, [x26]
+5d61400c|	gnu	ld1 {v29.8b-v31.8b}, [x10]
+af21404c|	gnu	ld1 {v15.16b-v18.16b}, [x13]
+737edf0c|	gnu	ld1 {v19.1d}, [x19],#8
+757dd10c|	gnu	ld1 {v21.1d}, [x11], x17
+5ca3df4c|	gnu	ld1 {v28.16b, v29.16b}, [x26],#32
+93a1ce0c|	gnu	ld1 {v19.8b, v20.8b}, [x12], x14
+1c65df0c|	gnu	ld1 {v28.4h-v30.4h}, [x8],#24
+4461d34c|	gnu	ld1 {v4.16b-v6.16b}, [x10], x19
+b22edf4c|	gnu	ld1 {v18.2d-v21.2d}, [x21],#64
+c12fcc4c|	gnu	ld1 {v1.2d-v4.2d}, [x30], x12
+5a03400d|	gnu	ld1 {v26.b}[0], [x26]
+8d93404d|	gnu	ld1 {v13.s}[3], [x28]
+2186404d|	gnu	ld1 {v1.d}[1], [x17]
+9604df4d|	gnu	ld1 {v22.b}[9], [x4],#1
+4a1dc94d|	gnu	ld1 {v10.b}[15], [x10], x9
+4852df4d|	gnu	ld1 {v8.h}[6], [x18],#2
+2582df4d|	gnu	ld1 {v5.s}[2], [x17],#4
+2191c84d|	gnu	ld1 {v1.s}[3], [x9], x8
+c284df4d|	gnu	ld1 {v2.d}[1], [x6],#8
+8f85ce0d|	gnu	ld1 {v15.d}[0], [x12], x14
+87cd400d|	gnu	ld1r {v7.1d}, [x12]
+3bc8df4d|	gnu	ld1r {v27.4s}, [x1],#4
+77c4dd4d|	gnu	ld1r {v23.8h}, [x3], x29
+5384404c|	gnu	ld2 {v19.8h, v20.8h}, [x2]
+ca87df0c|	gnu	ld2 {v10.4h, v11.4h}, [x30],#16
+1280d70c|	gnu	ld2 {v18.8b, v19.8b}, [x0], x23
+4c0a604d|	gnu	ld2 {v12.b, v13.b}[10], [x18]
+3080600d|	gnu	ld2 {v16.s, v17.s}[0], [x1]
+6686600d|	gnu	ld2 {v6.d, v7.d}[0], [x19]
+061eff0d|	gnu	ld2 {v6.b, v7.b}[7], [x16],#2
+db05fa0d|	gnu	ld2 {v27.b, v28.b}[1], [x14], x26
+8a49ff4d|	gnu	ld2 {v10.h, v11.h}[5], [x12],#4
+bb59ec4d|	gnu	ld2 {v27.h, v28.h}[7], [x13], x12
+5a82ff0d|	gnu	ld2 {v26.s, v27.s}[0], [x18],#8
+6180e30d|	gnu	ld2 {v1.s, v2.s}[0], [x3], x3
+6485ff0d|	gnu	ld2 {v4.d, v5.d}[0], [x11],#16
+7c86ed4d|	gnu	ld2 {v28.d, v29.d}[1], [x19], x13
+54c0604d|	gnu	ld2r {v20.16b, v21.16b}, [x2]
+fdcaff0d|	gnu	ld2r {v29.2s, v30.2s}, [x23],#8
+7bc5e40d|	gnu	ld2r {v27.4h, v28.4h}, [x11], x4
+b349404c|	gnu	ld3 {v19.4s-v21.4s}, [x13]
+cf46df4c|	gnu	ld3 {v15.8h-v17.8h}, [x22],#48
+934acc4c|	gnu	ld3 {v19.4s-v21.4s}, [x20], x12
+2c33404d|	gnu	ld3 {v12.b-v14.b}[12], [x25]
+897a400d|	gnu	ld3 {v9.h-v11.h}[3], [x20]
+f9b2400d|	gnu	ld3 {v25.s-v27.s}[1], [x23]
+4aa7404d|	gnu	ld3 {v10.d-v12.d}[1], [x26]
+4e25df4d|	gnu	ld3 {v14.b-v16.b}[9], [x10],#3
+7827c40d|	gnu	ld3 {v24.b-v26.b}[1], [x27], x4
+c4a3df4d|	gnu	ld3 {v4.s-v6.s}[2], [x30],#12
+f0a1cf0d|	gnu	ld3 {v16.s-v18.s}[0], [x15], x15
+1ba7df0d|	gnu	ld3 {v27.d-v29.d}[0], [x24],#24
+f7a7d50d|	gnu	ld3 {v23.d-v25.d}[0], [sp], x21
+a9ed404d|	gnu	ld3r {v9.2d-v11.2d}, [x13]
+5aecdf4d|	gnu	ld3r {v26.2d-v28.2d}, [x2],#24
+bae9c74d|	gnu	ld3r {v26.4s-v28.4s}, [x13], x7
+5904404c|	gnu	ld4 {v25.8h-v28.8h}, [x2]
+743b604d|	gnu	ld4 {v20.b-v23.b}[14], [x27]
+bda1600d|	gnu	ld4 {v29.s, v30.s, v31.s, v0.s}[0], [x13]
+a3a4600d|	gnu	ld4 {v3.d-v6.d}[0], [x5]
+2f3aff4d|	gnu	ld4 {v15.b-v18.b}[14], [x17],#4
+e73bef4d|	gnu	ld4 {v7.b-v10.b}[14], [sp], x15
+5d78ef0d|	gnu	ld4 {v29.h, v30.h, v31.h, v0.h}[3], [x2], x15
+acb3ff0d|	gnu	ld4 {v12.s-v15.s}[1], [x29],#16
+a8b2f04d|	gnu	ld4 {v8.s-v11.s}[3], [x21], x16
+75a7ff4d|	gnu	ld4 {v21.d-v24.d}[1], [x27],#32
+75a6ee4d|	gnu	ld4 {v21.d-v24.d}[1], [x19], x14
+d8e3604d|	gnu	ld4r {v24.16b-v27.16b}, [x30]
+49e9ff0d|	gnu	ld4r {v9.2s-v12.2s}, [x10],#16
+81effc0d|	gnu	ld4r {v1.1d-v4.1d}, [x28], x28
+893e622c|	gnu	ldnp s9, s15, [x20,#-240]
+f90e626c|	gnu	ldnp d25, d3, [x23,#-480]
+b0224fac|	gnu	ldnp q16, q8, [x21,#480]
+9186de2c|	gnu	ldp s17, s1, [x20],#244
+e820d06c|	gnu	ldp d8, d8, [x7],#256
+417de8ac|	gnu	ldp q1, q31, [x10],#-768
+7969ed2d|	gnu	ldp s25, s26, [x11,#-152]!
+70c8c36d|	gnu	ldp d16, d18, [x3,#56]!
+30b4c4ad|	gnu	ldp q16, q13, [x1,#144]!
+a1857f2d|	gnu	ldp s1, s1, [x13,#-4]
+f4ae786d|	gnu	ldp d20, d11, [x23,#-120]
+998366ad|	gnu	ldp q25, q0, [x28,#-816]
+7535453c|	gnu	ldr b21, [x11],#83
+5465477c|	gnu	ldr h20, [x10],#118
+a2b44bbc|	gnu	ldr s2, [x5],#187
+ab045bfc|	gnu	ldr d11, [x5],#-80
+0515d43c|	gnu	ldr q5, [x8],#-191
+43ad413c|	gnu	ldr b3, [x10,#26]!
+22cd4f7c|	gnu	ldr h2, [x9,#252]!
+5fad44bc|	gnu	ldr s31, [x10,#74]!
+db7d5afc|	gnu	ldr d27, [x14,#-89]!
+15ccd63c|	gnu	ldr q21, [x0,#-148]!
+95c34b3d|	gnu	ldr b21, [x28,#752]
+f5885e7d|	gnu	ldr h21, [x7,#3908]
+54db66bd|	gnu	ldr s20, [x26,#9944]
+46ee78fd|	gnu	ldr d6, [x18,#29144]
+0cc4e93d|	gnu	ldr q12, [x0,#42768]
+e1c4211c|	gnu	ldr s1, .+0x4389c
+2071c35c|	gnu	ldr d0, .+0xfffffffffff86e24
+4765789c|	gnu	ldr q7, .+0xf0ca8
+ae79703c|	gnu	ldr b14, [x13,x16,lsl #0]
+38fb67bc|	gnu	ldr s24, [x25,x7,sxtx #2]
+3e6b6dfc|	gnu	ldr d30, [x25,x13]
+a278ff3c|	gnu	ldr q2, [x5,xzr,lsl #4]
+ed02563c|	gnu	ldur b13, [x23,#-160]
+01c0507c|	gnu	ldur h1, [x0,#-244]
+7fd24ebc|	gnu	ldur s31, [x19,#237]
+7a734ffc|	gnu	ldur d26, [x27,#247]
+d4a3dd3c|	gnu	ldur q20, [x30,#-38]
+1c97250e|	gnu	mla v28.8b, v24.8b, v5.8b
+af97a12e|	gnu	mls v15.2s, v29.2s, v1.2s
+2b061f5e|	gnu	mov b11, v17.b[15]
+805e086e|	gnu	mov v0.d[0], v20.d[1]
+d91fbc4e|	gnu	orr v25.16b, v30.16b, v28.16b
+a43f040e|	gnu	mov w4, v29.s[0]
+fbe6054f|	gnu	movi v27.16b, #0xb7
+9b75024f|	gnu	orr v27.4s, #0x4c, lsl #24
+8436020f|	gnu	orr v4.2s, #0x54, lsl #8
+19f5010f|	gnu	fmov v25.2s, #1.200000000000000000e+01
+02e5062f|	gnu	movi d2, #0xffff0000ff000000
+d6e5066f|	gnu	movi v22.2d, #0xffff0000ffffff00
+be9c240e|	gnu	mul v30.8b, v5.8b, v4.8b
+2659202e|	gnu	mvn v6.8b, v9.8b
+f394046f|	gnu	bic v19.8h, #0x87
+d856056f|	gnu	bic v24.4s, #0xb6, lsl #16
+2f85022f|	gnu	mvni v15.4h, #0x49
+24baa02e|	gnu	neg v4.2s, v17.2s
+145b206e|	gnu	mvn v20.16b, v24.16b
+191fff4e|	gnu	orn v25.16b, v24.16b, v31.16b
+6f96004f|	gnu	orr v15.8h, #0x13
+a564020f|	gnu	movi v5.2s, #0x45, lsl #24
+ae1ead0e|	gnu	orr v14.8b, v21.8b, v13.8b
+f2e1e00e|	gnu	pmull v18.1q, v15.1d, v0.1d
+0d426e2e|	gnu	raddhn v13.4h, v16.4s, v14.4s
+4443246e|	gnu	raddhn2 v4.16b, v26.8h, v4.8h
+015b602e|	gnu	rbit v1.8b, v24.8b
+4209202e|	gnu	rev32 v2.8b, v10.8b
+d109a04e|	gnu	rev64 v17.4s, v14.4s
+5a8e380f|	gnu	rshrn v26.2s, v18.2d, #8
+438d234f|	gnu	rshrn2 v3.4s, v10.2d, #29
+a861716e|	gnu	rsubhn2 v8.8h, v13.4s, v17.4s
+017c2f0e|	gnu	saba v1.8b, v0.8b, v15.8b
+5d51a90e|	gnu	sabal v29.2d, v10.2s, v9.2s
+c076a04e|	gnu	sabd v0.4s, v22.4s, v0.4s
+2d722e0e|	gnu	sabdl v13.8h, v17.8b, v14.8b
+1f732e4e|	gnu	sabdl2 v31.8h, v24.16b, v14.16b
+c628604e|	gnu	saddlp v6.4s, v6.8h
+103b704e|	gnu	saddlv s16, v24.8h
+8f122f0e|	gnu	saddw v15.8h, v20.8h, v15.8b
+30e6755f|	gnu	scvtf d16, d17, #11
+73e7544f|	gnu	scvtf v19.2d, v27.2d, #44
+51d9615e|	gnu	scvtf d17, d10
+fad9210e|	gnu	scvtf v26.2s, v15.2s
+96c0421e|	gnu	scvtf d22, w4, #16
+76e1029e|	gnu	scvtf s22, x11, #8
+a791429e|	gnu	scvtf d7, x13, #28
+f100221e|	gnu	scvtf s17, w7
+e101621e|	gnu	scvtf d1, w15
+6e03229e|	gnu	scvtf s14, x27
+0b01629e|	gnu	scvtf d11, x8
+2401025e|	gnu	sha1c q4, s9, v2.4s
+5d08285e|	gnu	sha1h s29, s2
+65210d5e|	gnu	sha1m q5, s11, v13.4s
+29131a5e|	gnu	sha1p q9, s25, v26.4s
+2b311a5e|	gnu	sha1su0 v11.4s, v9.4s, v26.4s
+0919285e|	gnu	sha1su1 v9.4s, v8.4s
+f052035e|	gnu	sha256h2 q16, q23, v3.4s
+fe401e5e|	gnu	sha256h q30, q7, v30.4s
+7529285e|	gnu	sha256su0 v21.4s, v11.4s
+cc60195e|	gnu	sha256su1 v12.4s, v6.4s, v25.4s
+8b56060f|	gnu	orr v11.2s, #0xd4, lsl #16
+3f3aa16e|	gnu	shll2 v31.2d, v17.4s, #32
+0986394f|	gnu	shrn2 v9.4s, v16.2d, #7
+35276e4e|	gnu	shsub v21.8h, v25.8h, v14.8h
+e2556d7f|	gnu	sli d2, d15, #45
+f7541e6f|	gnu	sli v23.8h, v7.8h, #14
+3167630e|	gnu	smax v17.4h, v25.4h, v3.4h
+68a6230e|	gnu	smaxp v8.8b, v19.8b, v3.8b
+a4aa304e|	gnu	smaxv b4, v21.16b
+2520440f|	gnu	smlal v5.4s, v1.4h, v4.h[0]
+8c286f4f|	gnu	smlal2 v12.4s, v4.8h, v15.h[6]
+3a82660e|	gnu	smlal v26.4s, v17.4h, v6.4h
+d92f1f0e|	gnu	smov w25, v30.b[15]
+912d114e|	gnu	smov x17, v12.b[8]
+b87ae05e|	gnu	sqabs d24, d21
+2d7b200e|	gnu	sqabs v13.8b, v25.8b
+560f645e|	gnu	sqadd h22, h26, h4
+4f0da54e|	gnu	sqadd v15.4s, v10.4s, v5.4s
+5992ba5e|	gnu	sqdmlal d25, s18, s26
+b892684e|	gnu	sqdmlal2 v24.4s, v21.8h, v8.8h
+63786e5f|	gnu	sqdmlsl s3, h3, v14.h[6]
+0c79a10f|	gnu	sqdmlsl v12.2d, v8.2s, v1.s[3]
+1d73504f|	gnu	sqdmlsl2 v29.4s, v24.8h, v0.h[1]
+6cb36c5e|	gnu	sqdmlsl s12, h27, h12
+82b36e4e|	gnu	sqdmlsl2 v2.4s, v28.8h, v14.8h
+8dca5d4f|	gnu	sqdmulh v13.8h, v20.8h, v13.h[5]
+fcb6b64e|	gnu	sqdmulh v28.4s, v23.4s, v22.4s
+d6b0974f|	gnu	sqdmull2 v22.2d, v6.4s, v23.s[0]
+afd0b84e|	gnu	sqdmull2 v15.2d, v5.4s, v24.4s
+067b207e|	gnu	sqneg b6, b24
+9979606e|	gnu	sqneg v25.8h, v12.8h
+bfdbae0f|	gnu	sqrdmulh v31.2s, v29.2s, v14.s[3]
+c3b7a07e|	gnu	sqrdmulh s3, s30, s0
+845d3d5e|	gnu	sqrshl b4, b12, b29
+495dba0e|	gnu	sqrshl v9.2s, v10.2s, v26.2s
+fa8e0d7f|	gnu	sqrshrun b26, h23, #3
+cf75185f|	gnu	sqshl h15, h14, #8
+a975250f|	gnu	sqshl v9.2s, v13.2s, #5
+424da05e|	gnu	sqshl s2, s10, s0
+464db90e|	gnu	sqshl v6.2s, v10.2s, v25.2s
+af656d7f|	gnu	sqshlu d15, d13, #45
+e564436f|	gnu	sqshlu v5.2d, v7.2d, #3
+c1973b5f|	gnu	sqshrn s1, d30, #5
+d586036f|	gnu	mvni v21.8h, #0x76
+4c2ea95e|	gnu	sqsub s12, s18, s9
+df2efe4e|	gnu	sqsub v31.2d, v22.2d, v30.2d
+c149a10e|	gnu	sqxtn v1.2s, v14.2d
+712a217e|	gnu	sqxtun b17, h19
+9a29a12e|	gnu	sqxtun v26.2s, v12.2d
+6a166e0e|	gnu	srhadd v10.4h, v19.4h, v14.4h
+0445647f|	gnu	sri d4, d8, #28
+6f44172f|	gnu	sri v15.4h, v3.4h, #9
+cd56f94e|	gnu	srshl v13.2d, v22.2d, v25.2d
+12345b5f|	gnu	srsra d18, d0, #37
+f746fa5e|	gnu	sshl d23, d23, d26
+89476c4e|	gnu	sshl v9.8h, v28.8h, v12.8h
+0da60e0f|	gnu	sshll v13.8h, v16.8b, #6
+a504585f|	gnu	sshr d5, d5, #40
+3b07544f|	gnu	sshr v27.2d, v25.2d, #44
+3417350f|	gnu	ssra v20.2s, v25.2s, #11
+1a213f0e|	gnu	ssubl v26.8h, v8.8b, v31.8b
+1322a34e|	gnu	ssubl2 v19.2d, v16.4s, v3.4s
+e931b84e|	gnu	ssubw2 v9.2d, v15.2d, v24.4s
+dd7d004c|	gnu	st1 {v29.2d}, [x14]
+cea4000c|	gnu	st1 {v14.4h, v15.4h}, [x6]
+5a64000c|	gnu	st1 {v26.4h-v28.4h}, [x2]
+2b2c004c|	gnu	st1 {v11.2d-v14.2d}, [x1]
+39719f0c|	gnu	st1 {v25.8b}, [x9],#8
+b771874c|	gnu	st1 {v23.16b}, [x13], x7
+1da39f0c|	gnu	st1 {v29.8b, v30.8b}, [x24],#16
+20a0800c|	gnu	st1 {v0.8b, v1.8b}, [x1], x0
+5a6a9f4c|	gnu	st1 {v26.4s-v28.4s}, [x18],#48
+0d69994c|	gnu	st1 {v13.4s-v15.4s}, [x8], x25
+7e239f0c|	gnu	st1 {v30.8b, v31.8b, v0.8b, v1.8b}, [x27],#32
+9a2d8e0c|	gnu	st1 {v26.1d-v29.1d}, [x12], x14
+fd0b004d|	gnu	st1 {v29.b}[10], [sp]
+1058004d|	gnu	st1 {v16.h}[7], [x0]
+0593000d|	gnu	st1 {v5.s}[1], [x24]
+3d87000d|	gnu	st1 {v29.d}[0], [x25]
+1a079f0d|	gnu	st1 {v26.b}[1], [x24],#1
+421b8f4d|	gnu	st1 {v2.b}[14], [x26], x15
+54489f4d|	gnu	st1 {v20.h}[5], [x2],#2
+c4809f4d|	gnu	st1 {v4.s}[2], [x6],#4
+0481840d|	gnu	st1 {v4.s}[0], [x8], x4
+6b859f0d|	gnu	st1 {v11.d}[0], [x11],#8
+f7878e4d|	gnu	st1 {v23.d}[1], [sp], x14
+e788004c|	gnu	st2 {v7.4s, v8.4s}, [x7]
+79889f0c|	gnu	st2 {v25.2s, v26.2s}, [x3],#16
+a502204d|	gnu	st2 {v5.b, v6.b}[8], [x21]
+0e50204d|	gnu	st2 {v14.h, v15.h}[6], [x0]
+6b93204d|	gnu	st2 {v11.s, v12.s}[3], [x27]
+0987200d|	gnu	st2 {v9.d, v10.d}[0], [x24]
+7003bf0d|	gnu	st2 {v16.b, v17.b}[0], [x27],#2
+1a09a94d|	gnu	st2 {v26.b, v27.b}[10], [x8], x9
+1e43b00d|	gnu	st2 {v30.h, v31.h}[0], [x24], x16
+1a82bf0d|	gnu	st2 {v26.s, v27.s}[0], [x16],#8
+9892a50d|	gnu	st2 {v24.s, v25.s}[1], [x20], x5
+5884bf0d|	gnu	st2 {v24.d, v25.d}[0], [x2],#16
+9e87a34d|	gnu	st2 {v30.d, v31.d}[1], [x28], x3
+4e47004c|	gnu	st3 {v14.8h-v16.8h}, [x26]
+76489f4c|	gnu	st3 {v22.4s-v24.4s}, [x3],#48
+3b48860c|	gnu	st3 {v27.2s-v29.2s}, [x1], x6
+e52a000d|	gnu	st3 {v5.b-v7.b}[2], [x23]
+6f73004d|	gnu	st3 {v15.h-v17.h}[6], [x27]
+9bb1004d|	gnu	st3 {v27.s-v29.s}[3], [x12]
+0ca7000d|	gnu	st3 {v12.d-v14.d}[0], [x24]
+2a259f0d|	gnu	st3 {v10.b-v12.b}[1], [x9],#3
+0524860d|	gnu	st3 {v5.b-v7.b}[1], [x0], x6
+94689a4d|	gnu	st3 {v20.h-v22.h}[5], [x4], x26
+c2a19f4d|	gnu	st3 {v2.s-v4.s}[2], [x14],#12
+5fb38c0d|	gnu	st3 {v31.s, v0.s, v1.s}[1], [x26], x12
+6da59f4d|	gnu	st3 {v13.d-v15.d}[1], [x11],#24
+32a7924d|	gnu	st3 {v18.d-v20.d}[1], [x25], x18
+5b03000c|	gnu	st4 {v27.8b-v30.8b}, [x26]
+cd059f0c|	gnu	st4 {v13.4h-v16.4h}, [x14],#32
+8601820c|	gnu	st4 {v6.8b-v9.8b}, [x12], x2
+7925200d|	gnu	st4 {v25.b-v28.b}[1], [x11]
+cd7a204d|	gnu	st4 {v13.h-v16.h}[7], [x22]
+dfb2204d|	gnu	st4 {v31.s, v0.s, v1.s, v2.s}[3], [x22]
+daa4200d|	gnu	st4 {v26.d-v29.d}[0], [x6]
+2135bf0d|	gnu	st4 {v1.b-v4.b}[5], [x9],#4
+7727a90d|	gnu	st4 {v23.b-v26.b}[1], [x27], x9
+b4a3bf0d|	gnu	st4 {v20.s-v23.s}[0], [x29],#16
+1ba3ae0d|	gnu	st4 {v27.s-v30.s}[0], [x24], x14
+93a4bf0d|	gnu	st4 {v19.d-v22.d}[0], [x4],#32
+50a6b80d|	gnu	st4 {v16.d-v19.d}[0], [x18], x24
+79b53d2c|	gnu	stnp s25, s13, [x11,#-20]
+d895326c|	gnu	stnp d24, d5, [x14,#-216]
+d1810dac|	gnu	stnp q17, q0, [x14,#432]
+08728c2c|	gnu	stp s8, s28, [x16],#96
+ac1ba16c|	gnu	stp d12, d6, [x29],#-496
+f4fab1ac|	gnu	stp q20, q30, [x23],#-464
+c15bbe2d|	gnu	stp s1, s22, [x30,#-16]!
+2422856d|	gnu	stp d4, d8, [x17,#80]!
+3d5282ad|	gnu	stp q29, q20, [x17,#64]!
+5df5352d|	gnu	stp s29, s29, [x10,#-84]
+5c54286d|	gnu	stp d28, d21, [x2,#-384]
+753c11ad|	gnu	stp q21, q15, [x3,#544]
+54e4033c|	gnu	str b20, [x2],#62
+aa54137c|	gnu	str h10, [x5],#-203
+c9d615bc|	gnu	str s9, [x22],#-163
+fc471efc|	gnu	str d28, [sp],#-28
+20f78d3c|	gnu	str q0, [x25],#223
+028d1b3c|	gnu	str b2, [x8,#-72]!
+35be037c|	gnu	str h21, [x17,#59]!
+b98c15bc|	gnu	str s25, [x5,#-168]!
+fd1e11fc|	gnu	str d29, [x23,#-239]!
+13ec9a3c|	gnu	str q19, [x0,#-82]!
+b12d123d|	gnu	str b17, [x13,#1163]
+d6500b7d|	gnu	str h22, [x6,#1448]
+d46e39bd|	gnu	str s20, [x22,#14700]
+b84f30fd|	gnu	str d24, [x29,#24728]
+3cee993d|	gnu	str q28, [x17,#26544]
+4348293c|	gnu	str b3, [x2,w9,uxtw]
+ed7b253c|	gnu	str b13, [sp,x5,lsl #0]
+8fc9357c|	gnu	str h15, [x12,w21,sxtw]
+87f832bc|	gnu	str s7, [x4,x18,sxtx #2]
+f1ea38fc|	gnu	str d17, [x23,x24,sxtx]
+1c68a43c|	gnu	str q28, [x0,x4]
+dcb1023c|	gnu	stur b28, [x14,#43]
+6701117c|	gnu	stur h7, [x11,#-240]
+85b11bbc|	gnu	stur s5, [x12,#-69]
+8ea10efc|	gnu	stur d14, [x12,#234]
+eab08f3c|	gnu	stur q10, [x7,#251]
+ca876a2e|	gnu	sub v10.4h, v30.4h, v10.4h
+603be05e|	gnu	suqadd d0, d27
+513a600e|	gnu	suqadd v17.4h, v18.4h
+25231c4e|	gnu	tbl v5.16b, {v25.16b, v26.16b}, v28.16b
+8c40100e|	gnu	tbl v12.8b, {v4.16b-v6.16b}, v16.8b
+0462040e|	gnu	tbl v4.8b, {v16.16b-v19.16b}, v4.8b
+34000f0e|	gnu	tbl v20.8b, {v1.16b}, v15.8b
+eb301f4e|	gnu	tbx v11.16b, {v7.16b, v8.16b}, v31.16b
+bb51124e|	gnu	tbx v27.16b, {v13.16b-v15.16b}, v18.16b
+cf701d0e|	gnu	tbx v15.8b, {v6.16b-v9.16b}, v29.8b
+4213080e|	gnu	tbx v2.8b, {v26.16b}, v8.8b
+2b2b114e|	gnu	trn1 v11.16b, v25.16b, v17.16b
+766ada4e|	gnu	trn2 v22.2d, v19.2d, v26.2d
+4152672e|	gnu	uabal v1.4s, v18.4h, v7.4h
+0953296e|	gnu	uabal2 v9.8h, v24.16b, v9.16b
+41756c6e|	gnu	uabd v1.8h, v10.8h, v12.8h
+3670ae2e|	gnu	uabdl v22.2d, v1.2s, v14.2s
+5401312e|	gnu	uaddl v20.8h, v10.8b, v17.8b
+d103286e|	gnu	uaddl2 v17.8h, v30.16b, v8.16b
+a92a206e|	gnu	uaddlp v9.8h, v21.16b
+b839706e|	gnu	uaddlv s24, v13.8h
+ea106d2e|	gnu	uaddw v10.4s, v7.4s, v13.4h
+c010726e|	gnu	uaddw2 v0.4s, v6.4s, v18.8h
+e7e5517f|	gnu	ucvtf d7, d15, #47
+49e7376f|	gnu	ucvtf v9.4s, v26.4s, #9
+4ada617e|	gnu	ucvtf d10, d18
+6b82431e|	gnu	ucvtf d11, w19, #32
+db84039e|	gnu	ucvtf s27, x6, #31
+1c72439e|	gnu	ucvtf d28, x16, #36
+f301231e|	gnu	ucvtf s19, w15
+3503631e|	gnu	ucvtf d21, w25
+e602239e|	gnu	ucvtf s6, x23
+d503639e|	gnu	ucvtf d21, x30
+ec04606e|	gnu	uhadd v12.8h, v7.8h, v0.8h
+3f65782e|	gnu	umax v31.4h, v9.4h, v24.4h
+afa6232e|	gnu	umaxp v15.8b, v21.8b, v3.8b
+cdaa706e|	gnu	umaxv h13, v22.8h
+736c236e|	gnu	umin v19.16b, v3.16b, v3.16b
+a0afa62e|	gnu	uminp v0.2s, v29.2s, v6.2s
+3c229e2f|	gnu	umlal v28.2d, v17.2s, v30.s[0]
+9d29a56f|	gnu	umlal2 v29.2d, v12.4s, v5.s[3]
+6c80392e|	gnu	umlal v12.8h, v3.8b, v25.8b
+4f60692f|	gnu	umlsl v15.4s, v2.4h, v9.h[2]
+61a1606e|	gnu	umlsl2 v1.4s, v11.8h, v0.8h
+183e0b0e|	gnu	umov w24, v16.b[5]
+c0a89b6f|	gnu	umull2 v0.2d, v6.4s, v27.s[2]
+36c0736e|	gnu	umull2 v22.4s, v1.8h, v19.8h
+120d757e|	gnu	uqadd h18, h8, h21
+3a0c2e2e|	gnu	uqadd v26.8b, v1.8b, v14.8b
+0d5d617e|	gnu	uqrshl h13, h8, h1
+4d5cb16e|	gnu	uqrshl v13.4s, v2.4s, v17.4s
+439c382f|	gnu	uqrshrn v3.2s, v2.2d, #8
+9d745c7f|	gnu	uqshl d29, d4, #28
+7b76656f|	gnu	uqshl v27.2d, v19.2d, #37
+774ef37e|	gnu	uqshl d23, d19, d19
+124eb32e|	gnu	uqshl v18.2s, v16.2s, v19.2s
+bc961f6f|	gnu	uqshrn2 v28.8h, v21.4s, #1
+a62ce07e|	gnu	uqsub d6, d5, d0
+0f2dae2e|	gnu	uqsub v15.2s, v8.2s, v14.2s
+b24b217e|	gnu	uqxtn b18, h29
+f148216e|	gnu	uqxtn2 v17.16b, v7.8h
+7d15a42e|	gnu	urhadd v29.2s, v11.2s, v4.2s
+9055fc6e|	gnu	urshl v16.2d, v12.2d, v28.2d
+eb275e7f|	gnu	urshr d11, d31, #34
+c0347c7f|	gnu	ursra d0, d6, #4
+fe44e97e|	gnu	ushl d30, d7, d9
+fa47e86e|	gnu	ushl v26.2d, v31.2d, v8.2d
+95a7262f|	gnu	ushll v21.2d, v28.2s, #6
+9ca7096f|	gnu	ushll2 v28.8h, v28.16b, #1
+8a07527f|	gnu	ushr d10, d28, #46
+c7076b6f|	gnu	ushr v7.2d, v30.2d, #21
+8d39e07e|	gnu	usqadd d13, d12
+f716727f|	gnu	usra d23, d23, #14
+3f14066f|	gnu	bic v31.4s, #0xc1
+b423ac2e|	gnu	usubl v20.2d, v29.2s, v12.2s
+7c22736e|	gnu	usubl2 v28.4s, v19.8h, v19.8h
+76317d2e|	gnu	usubw v22.4s, v11.4s, v29.4h
+8f302a6e|	gnu	usubw2 v15.8h, v4.8h, v10.16b
+c5a4286f|	gnu	ushll2 v5.2d, v6.4s, #8
+d3198c0e|	gnu	uzp1 v19.2s, v14.2s, v12.2s
+c05bdb4e|	gnu	uzp2 v0.2d, v30.2d, v27.2d
+362b610e|	gnu	xtn v22.4h, v25.4s
+0c29214e|	gnu	xtn2 v12.16b, v8.8h
+2b39c64e|	gnu	zip1 v11.2d, v9.2d, v6.2d
+9500091a|	gnu	adc w21, w4, w9
+c2001a9a|	gnu	adc x2, x6, x26
+6a02163a|	gnu	adcs w10, w19, w22
+0c0118ba|	gnu	adcs x12, x8, x24
+b1c42b0b|	gnu	add w17, w5, w11, sxtw #1
+bf15368b|	gnu	add sp, x13, w22, uxtb #5
+be1f468b|	gnu	add x30, x29, x6, lsr #7
+8f51352b|	gnu	adds w15, w12, w21, uxtw #4
+97043eab|	gnu	adds x23, x4, w30, uxtb #1
+09b00931|	gnu	adds w9, w0, #0x26c
+4de204ab|	gnu	adds x13, x18, x4, lsl #56
+bba87030|	gnu	adr x27, .+0xe1515
+a9bf40d0|	gnu	adrp x9, .+0x817f6000
+f6b60912|	gnu	and w22, w23, #0xff9fff9f
+a6d13b92|	gnu	and x6, x13, #0xe3e3e3e3e3e3e3e3
+1cc0138a|	gnu	and x28, x0, x19, lsl #48
+73882072|	gnu	ands w19, w3, #0x70007
+b5780af2|	gnu	ands x21, x5, #0xffdfffffffdfffff
+766c90ea|	gnu	ands x22, x3, x16, asr #27
+a72ac31a|	gnu	asr w7, w21, w3
+ff28d59a|	gnu	asr xzr, x7, x21
+3e7f0913|	gnu	asr w30, w25, #9
+bafd5493|	gnu	asr x26, x13, #20
+302ad21a|	gnu	asr w16, w17, w18
+602bd79a|	gnu	asr x0, x27, x23
+4fa4df54|	gnu	b.al .+0xfffffffffffbf488
+a2e9cf15|	gnu	b .+0x73fa688
+eff373b3|	gnu	bfxil x15, xzr, #51, #10
+9e3e7db3|	gnu	bfi x30, x20, #3, #16
+87fa41b3|	gnu	bfxil x7, x20, #1, #62
+b831f80a|	gnu	bic w24, w13, w24, ror #12
+ffe0ae8a|	gnu	bic xzr, x7, x14, asr #56
+7c2c276a|	gnu	bics w28, w3, w7, lsl #11
+ccf2fbea|	gnu	bics x12, x22, x27, ror #60
+722cd195|	gnu	bl .+0x744b1c8
+20003fd6|	gnu	blr x1
+e0021fd6|	gnu	br x23
+80db37d4|	gnu	brk #0xbedc
+f25a4335|	gnu	cbnz w18, .+0x86b5c
+5d5376b5|	gnu	cbnz x29, .+0xeca68
+5ce56834|	gnu	cbz w28, .+0xd1ca8
+29b08cb4|	gnu	cbz x9, .+0xfffffffffff19604
+e048533a|	gnu	ccmn w7, #0x13, #0x0, mi
+e7da4fba|	gnu	ccmn x23, #0xf, #0x7, le
+67f2583a|	gnu	ccmn w19, w24, #0x7, al
+60a05aba|	gnu	ccmn x3, x26, #0x0, ge
+6a3b517a|	gnu	ccmp w27, #0x11, #0xa, cc
+8a4b55fa|	gnu	ccmp x28, #0x15, #0xa, mi
+ed934b7a|	gnu	ccmp wzr, w11, #0xd, ls
+24414ffa|	gnu	ccmp x9, x15, #0x4, mi
+0e169c1a|	gnu	csinc w14, w16, w28, ne
+8264949a|	gnu	csinc x2, x4, x20, vs
+b363935a|	gnu	csinv w19, w29, w19, vs
+ff619dda|	gnu	csinv xzr, x15, x29, vs
+5f3703d5|	gnu	clrex #0x7
+0017c05a|	gnu	cls w0, w24
+8216c0da|	gnu	cls x2, x20
+3310c05a|	gnu	clz w19, w1
+6e13c0da|	gnu	clz x14, x27
+7fd02b2b|	gnu	cmn w3, w11, sxtw #4
+5f3928ab|	gnu	cmn x10, w8, uxth #6
+1fb92cb1|	gnu	cmn x8, #0xb2e
+ff164eab|	gnu	cmn x23, x14, lsr #5
+ff71256b|	gnu	cmp w15, w5, uxtx #4
+df6034eb|	gnu	cmp x6, x20, uxtx
+ff776af1|	gnu	cmp sp, #0xa9d, lsl #12
+80e4855a|	gnu	csneg w0, w4, w5, al
+da3490da|	gnu	csneg x26, x6, x16, cc
+af40c71a|	gnu	crc32b w15, w5, w7
+c546cf1a|	gnu	crc32h w5, w22, w15
+6148c01a|	gnu	crc32w w1, w3, w0
+0f4eda9a|	gnu	crc32x w15, w16, x26
+4950d01a|	gnu	crc32cb w9, w2, w16
+8155c31a|	gnu	crc32ch w1, w12, w3
+835ace1a|	gnu	crc32cw w3, w20, w14
+f05fc59a|	gnu	crc32cx w16, wzr, x5
+0ae3901a|	gnu	csel w10, w24, w16, al
+ed51969a|	gnu	csel x13, x15, x22, pl
+ee679f1a|	gnu	cset w14, vc
+ed579f9a|	gnu	cset x13, mi
+f2539f5a|	gnu	csetm w18, mi
+ffe39fda|	gnu	csinv xzr, xzr, xzr, al
+9d25941a|	gnu	csinc w29, w12, w20, cs
+afb7829a|	gnu	csinc x15, x29, x2, lt
+7602895a|	gnu	csinv w22, w19, w9, eq
+011394da|	gnu	csinv x1, x24, x20, ne
+68b7935a|	gnu	csneg w8, w27, w19, lt
+a32784da|	gnu	csneg x3, x29, x4, cs
+8159a6d4|	gnu	dcps1 #0x32cc
+c2d9aad4|	gnu	dcps2 #0x56ce
+63ceb7d4|	gnu	dcps3 #0xbe73
+bf3903d5|	gnu	dmb ishld
+e003bfd6|	gnu	drps
+9f3603d5|	gnu	dsb nshst
+fc76a9ca|	gnu	eon x28, x23, x9, asr #29
+540f2352|	gnu	eor w20, w26, #0xe0000001
+187e1ed2|	gnu	eor x24, x16, #0xffffffffffffffff
+fd37004a|	gnu	eor w29, wzr, w0, lsl #13
+b8c542ca|	gnu	eor x24, x13, x2, lsr #49
+e0039fd6|	gnu	eret
+5f26c193|	gnu	extr xzr, x18, x1, #9
+7f2003d5|	gnu	wfi
+ff2a03d5|	gnu	hint #0x57
+804a59d4|	gnu	hlt #0xca54
+df3003d5|	gnu	isb #0x0
+10fcdf88|	gnu	ldar w16, [x0]
+fafcdfc8|	gnu	ldar x26, [x7]
+30fedf08|	gnu	ldarb w16, [x17]
+63fedf48|	gnu	ldarh w3, [x19]
+82ba7f88|	gnu	ldaxp w2, w14, [x20]
+d6917fc8|	gnu	ldaxp x22, x4, [x14]
+59ff5f88|	gnu	ldaxr w25, [x26]
+fefe5fc8|	gnu	ldaxr x30, [x23]
+a0fc5f08|	gnu	ldaxrb w0, [x5]
+fafd5f48|	gnu	ldaxrh w26, [x15]
+b8804428|	gnu	ldnp w24, w0, [x5,#36]
+93e969a8|	gnu	ldnp x19, x26, [x12,#-360]
+caccef28|	gnu	ldp w10, w19, [x6],#-132
+7365c3a8|	gnu	ldp x19, x25, [x11],#48
+3106ca29|	gnu	ldp w17, w1, [x17,#80]!
+0c02f7a9|	gnu	ldp x12, x0, [x16,#-144]!
+41af6529|	gnu	ldp w1, w11, [x26,#-212]
+706b65a9|	gnu	ldp x16, x26, [x27,#-432]
+746ecf68|	gnu	ldpsw x20, x27, [x19],#120
+c051c669|	gnu	ldpsw x0, x20, [x14,#48]!
+aded5b69|	gnu	ldpsw x13, x27, [x13,#220]
+990457b8|	gnu	ldr w25, [x4],#-144
+bbd556f8|	gnu	ldr x27, [x13],#-147
+a45c51b8|	gnu	ldr w4, [x5,#-235]!
+344c41f8|	gnu	ldr x20, [x1,#20]!
+2d8755b9|	gnu	ldr w13, [x25,#5508]
+56e360f9|	gnu	ldr x22, [x26,#16832]
+1739b718|	gnu	ldr w23, .+0xfffffffffff6e720
+97b91c58|	gnu	ldr x23, .+0x39730
+3b264e38|	gnu	ldrb w27, [x17],#226
+898f5738|	gnu	ldrb w9, [x28,#-136]!
+c44e6839|	gnu	ldrb w4, [x22,#2579]
+2d687738|	gnu	ldrb w13, [x1,x23]
+4d475978|	gnu	ldrh w13, [x26],#-108
+39de5278|	gnu	ldrh w25, [x17,#-211]!
+9cc54879|	gnu	ldrh w28, [x12,#1122]
+87fb6978|	gnu	ldrh w7, [x28,x9,sxtx #1]
+3967cb38|	gnu	ldrsb w25, [x25],#182
+abf69438|	gnu	ldrsb x11, [x21],#-177
+159ed138|	gnu	ldrsb w21, [x16,#-231]!
+b63e8038|	gnu	ldrsb x22, [x21,#3]!
+4491c939|	gnu	ldrsb w4, [x10,#612]
+497e8039|	gnu	ldrsb x9, [x18,#31]
+7d6bf638|	gnu	ldrsb w29, [x27,x22]
+e578ba38|	gnu	ldrsb x5, [x7,x26,lsl #0]
+9f06ca78|	gnu	ldrsh wzr, [x20],#160
+15c59d78|	gnu	ldrsh x21, [x8],#-36
+c07fd278|	gnu	ldrsh w0, [x30,#-217]!
+bdec9278|	gnu	ldrsh x29, [x5,#-210]!
+10e2c979|	gnu	ldrsh w16, [x16,#1264]
+54d29d79|	gnu	ldrsh x20, [x18,#3816]
+eb9484b8|	gnu	ldrsw x11, [x7],#73
+ba2e8ab8|	gnu	ldrsw x26, [x21,#162]!
+ac7f8ab9|	gnu	ldrsw x12, [x29,#2684]
+9466e898|	gnu	ldrsw x20, .+0xfffffffffffd0cd0
+a359b3b8|	gnu	ldrsw x3, [x13,w19,uxtw #2]
+f8b941b8|	gnu	ldtr w24, [x15,#27]
+fc0a4ef8|	gnu	ldtr x28, [x23,#224]
+60d84638|	gnu	ldtrb w0, [x3,#109]
+44685978|	gnu	ldtrh w4, [x2,#-106]
+5379dc38|	gnu	ldtrsb w19, [x10,#-57]
+ade99538|	gnu	ldtrsb x13, [x13,#-162]
+905ac078|	gnu	ldtrsh w16, [x20,#5]
+10898478|	gnu	ldtrsh x16, [x8,#72]
+37188eb8|	gnu	ldtrsw x23, [x1,#225]
+992351b8|	gnu	ldur w25, [x28,#-238]
+c9f155f8|	gnu	ldur x9, [x14,#-161]
+76e14e38|	gnu	ldurb w22, [x11,#238]
+47b24478|	gnu	ldurh w7, [x18,#75]
+4020da38|	gnu	ldursb w0, [x2,#-94]
+0dd09e38|	gnu	ldursb x13, [x0,#-19]
+8f81d478|	gnu	ldursh w15, [x12,#-184]
+96918378|	gnu	ldursh x22, [x12,#57]
+b2e383b8|	gnu	ldursw x18, [x29,#62]
+d3717f88|	gnu	ldxp w19, w28, [x14]
+cb677fc8|	gnu	ldxp x11, x25, [x30]
+ed7c5f88|	gnu	ldxr w13, [x7]
+aa7d5fc8|	gnu	ldxr x10, [x13]
+1c7d5f08|	gnu	ldxrb w28, [x8]
+de7f5f48|	gnu	ldxrh w30, [x30]
+1622dc1a|	gnu	lsl w22, w16, w28
+cd20d59a|	gnu	lsl x13, x6, x21
+882957d3|	gnu	ubfiz x8, x12, #41, #11
+3320cc1a|	gnu	lsl w19, w1, w12
+7320de9a|	gnu	lsl x19, x3, x30
+af25d31a|	gnu	lsr w15, w13, w19
+e426c39a|	gnu	lsr x4, x23, x3
+e87f0653|	gnu	lsr w8, wzr, #6
+85fe5fd3|	gnu	lsr x5, x20, #31
+0025dc1a|	gnu	lsr w0, w8, w28
+6e27c79a|	gnu	lsr x14, x27, x7
+6d69111b|	gnu	madd w13, w11, w17, w26
+245d0d9b|	gnu	madd x4, x9, x13, x23
+85fe1f1b|	gnu	mneg w5, w20, wzr
+9bfc199b|	gnu	mneg x27, x4, x25
+13000011|	gnu	add w19, w0, #0x0
+e3000091|	gnu	add x3, x7, #0x0
+986c9e12|	gnu	mov w24, #0xffff0c9b
+cb24f092|	gnu	mov x11, #0x7ed9ffffffffffff
+3cbb88d2|	gnu	mov x28, #0x45d9
+e4170232|	gnu	mov w4, #0xc000000f
+fe636bb2|	gnu	mov x30, #0x3fffffe00000
+ed031b2a|	gnu	mov w13, w27
+fb0308aa|	gnu	mov x27, x8
+be3ed1f2|	gnu	movk x30, #0x89f5, lsl #32
+e0a08312|	gnu	mov w0, #0xffffe2f8
+a1a6e592|	gnu	mov x1, #0xd2caffffffffffff
+5260f0d2|	gnu	mov x18, #0x8302000000000000
+a60739d5|	gnu	mrs x6, s3_1_c0_c7_5
+281a1ed5|	gnu	msr s3_6_c1_c10_1, x8
+10f31b1b|	gnu	msub w16, w24, w27, w28
+46b41a9b|	gnu	msub x6, x2, x26, x13
+ec7f041b|	gnu	mul w12, wzr, w4
+147f009b|	gnu	mul x20, x24, x0
+f67f692a|	gnu	mvn w22, w9, lsr #31
+f2a3f7aa|	gnu	mvn x18, x23, ror #40
+fe8b0bcb|	gnu	neg x30, x11, lsl #34
+fef710eb|	gnu	negs x30, x16, lsl #61
+e0031b5a|	gnu	ngc w0, w27
+e0031dda|	gnu	ngc x0, x29
+f003167a|	gnu	ngcs w16, w22
+e60302fa|	gnu	ngcs x6, x2
+1f2003d5|	gnu	nop
+2f51732a|	gnu	orn w15, w9, w19, lsr #20
+9b0facaa|	gnu	orn x27, x28, x12, asr #3
+efa40032|	gnu	orr w15, w7, #0x3ff03ff
+3a0b19b2|	gnu	orr x26, x25, #0x38000000380
+4b9ec4aa|	gnu	orr x11, x18, x4, ror #39
+f5eaa2f9|	gnu	prfm pstl3strm, [x23,#17872]
+731df8d8|	gnu	prfm pstl2strm, .+0xffffffffffff03ac
+85c194f8|	gnu	prfum pldl3strm, [x12,#-180]
+c303c05a|	gnu	rbit w3, w30
+3000c0da|	gnu	rbit x16, x1
+20025fd6|	gnu	ret x17
+ec08c05a|	gnu	rev w12, w7
+180cc0da|	gnu	rev x24, x0
+4b07c05a|	gnu	rev16 w11, w26
+7805c0da|	gnu	rev16 x24, x11
+ea08c0da|	gnu	rev32 x10, x7
+a90fc0da|	gnu	rev x9, x29
+fd788213|	gnu	extr w29, w7, w2, #30
+e1a0cc93|	gnu	extr x1, x7, x12, #40
+792fdc1a|	gnu	ror w25, w27, w28
+2b2cc39a|	gnu	ror x11, x1, x3
+7e2ec71a|	gnu	ror w30, w19, w7
+392edd9a|	gnu	ror x25, x17, x29
+47020a5a|	gnu	sbc w7, w18, w10
+b7021dda|	gnu	sbc x23, x21, x29
+7800197a|	gnu	sbcs w24, w3, w25
+1e0203fa|	gnu	sbcs x30, x16, x3
+a6b07393|	gnu	sbfiz x6, x5, #13, #45
+94957d93|	gnu	sbfiz x20, x12, #3, #38
+ecff5e93|	gnu	asr x12, xzr, #30
+a50ddb1a|	gnu	sdiv w5, w13, w27
+7c0ec89a|	gnu	sdiv x28, x19, x8
+9f2003d5|	gnu	sev
+bf2003d5|	gnu	sevl
+5953349b|	gnu	smaddl x25, w26, w20, x20
+bafc399b|	gnu	smnegl x26, w5, w25
+a5cc289b|	gnu	smsubl x5, w5, w8, x19
+297c579b|	gnu	smulh x9, x1, x23
+5e7e299b|	gnu	smull x30, w18, w9
+29fd9f88|	gnu	stlr w9, [x9]
+fdff9fc8|	gnu	stlr x29, [sp]
+defe9f08|	gnu	stlrb w30, [x22]
+2ffc9f48|	gnu	stlrh w15, [x1]
+c1e12f88|	gnu	stlxp w15, w1, w24, [x14]
+62aa2ec8|	gnu	stlxp w14, x2, x10, [x19]
+b9fe1b88|	gnu	stlxr w27, w25, [x21]
+cbff14c8|	gnu	stlxr w20, x11, [x30]
+edfc0608|	gnu	stlxrb w6, w13, [x7]
+8dfe1048|	gnu	stlxrh w16, w13, [x20]
+1a323628|	gnu	stnp w26, w12, [x16,#-80]
+b3cb3da8|	gnu	stnp x19, x18, [x29,#-40]
+52398828|	gnu	stp w18, w14, [x10],#64
+434c95a8|	gnu	stp x3, x19, [x2],#336
+2badbd29|	gnu	stp w11, w11, [x9,#-20]!
+daeabaa9|	gnu	stp x26, x26, [x22,#-88]!
+9bc91529|	gnu	stp w27, w18, [x12,#172]
+eea024a9|	gnu	stp x14, x8, [x7,#-440]
+fec514b8|	gnu	str w30, [x15],#-180
+d21508f8|	gnu	str x18, [x14],#129
+7c5c0ab8|	gnu	str w28, [x3,#165]!
+6dec1ff8|	gnu	str x13, [x3,#-2]!
+35681eb9|	gnu	str w21, [x1,#7784]
+374d35f9|	gnu	str x23, [x9,#27288]
+1dd83df8|	gnu	str x29, [x0,w29,sxtw #3]
+1b441b38|	gnu	strb w27, [x0],#-76
+d69c0f38|	gnu	strb w22, [x6,#249]!
+b7ce0d39|	gnu	strb w23, [x21,#883]
+2b7b3938|	gnu	strb w11, [x25,x25,lsl #0]
+4e771d78|	gnu	strh w14, [x26],#-41
+64cc0b78|	gnu	strh w4, [x3,#188]!
+07b90279|	gnu	strh w7, [x8,#348]
+2eb91cb8|	gnu	sttr w14, [x9,#-53]
+373a1bf8|	gnu	sttr x23, [x17,#-77]
+d0881138|	gnu	sttrb w16, [x6,#-232]
+941a0e78|	gnu	sttrh w20, [x20,#225]
+da3000b8|	gnu	stur w26, [x6,#3]
+5e921cf8|	gnu	stur x30, [x18,#-55]
+09821e38|	gnu	sturb w9, [x16,#-24]
+67d21c78|	gnu	sturh w7, [x19,#-51]
+0c352188|	gnu	stxp w1, w12, w13, [x8]
+146d26c8|	gnu	stxp w6, x20, x27, [x8]
+837d1888|	gnu	stxr w24, w3, [x12]
+f17f1bc8|	gnu	stxr w27, x17, [sp]
+3b7d0f08|	gnu	stxrb w15, w27, [x9]
+6b7c1f48|	gnu	stxrh wzr, w11, [x3]
+70ab204b|	gnu	sub w16, w27, w0, sxth #2
+303b20cb|	gnu	sub x16, x25, w0, uxth #6
+69a909d1|	gnu	sub x9, x11, #0x26a
+87384e4b|	gnu	sub w7, w4, w14, lsr #14
+ec720ecb|	gnu	sub x12, x23, x14, lsl #28
+2b58256b|	gnu	subs w11, w1, w5, uxtw #6
+59e93ceb|	gnu	subs x25, x10, x28, sxtx #2
+9e7b6ff1|	gnu	subs x30, x28, #0xbde, lsl #12
+3e6d196b|	gnu	subs w30, w9, w25, lsl #27
+54029ceb|	gnu	subs x20, x18, x28, asr #0
+c1f91cd4|	gnu	svc #0xe7ce
+091e0013|	gnu	sxtb w9, w16
+7f1c4093|	gnu	sxtb xzr, w3
+b53c0013|	gnu	sxth w21, w5
+773e4093|	gnu	sxth x23, w19
+707f4093|	gnu	sxtw x16, w27
+df3a2dd5|	gnu	sysl xzr, #5, C3, C10, #6
+607f3137|	gnu	tbnz w0, #6, .+0x2fec
+3b700c36|	gnu	tbz w27, #1, .+0xffffffffffff8e04
+5f612972|	gnu	tst w10, #0xff80ffff
+bf2007f2|	gnu	tst x5, #0xfe000003fe000003
+1f11136a|	gnu	tst w8, w19, lsl #4
+5fd10dea|	gnu	tst x10, x13, lsl #52
+5c826bd3|	gnu	ubfiz x28, x18, #21, #33
+ad690c53|	gnu	ubfx w13, w13, #12, #15
+3a0f41d3|	gnu	ubfx x26, x25, #1, #3
+6a197dd3|	gnu	ubfiz x10, x11, #3, #7
+520aca1a|	gnu	udiv w18, w18, w10
+0809c89a|	gnu	udiv x8, x8, x8
+4e55a69b|	gnu	umaddl x14, w10, w6, x21
+99fda59b|	gnu	umnegl x25, w12, w5
+1adabb9b|	gnu	umsubl x26, w16, w27, x22
+177ddf9b|	gnu	umulh x23, x8, xzr
+1d7da49b|	gnu	umull x29, w8, w4
+5a1c0053|	gnu	uxtb w26, w2
+603c0053|	gnu	uxth w0, w3
+5f2003d5|	gnu	wfe
+7f2003d5|	gnu	wfi
+3f2003d5|	gnu	yield
+02b8600e|	gnu	abs v2.4h, v0.4h
+c886f94e|	gnu	add v8.2d, v22.2d, v25.2d
+5642740e|	gnu	addhn v22.4h, v18.4s, v20.4s
+3743294e|	gnu	addhn2 v23.16b, v25.8h, v9.8h
+2abef74e|	gnu	addp v10.2d, v17.2d, v23.2d
+18bbb14e|	gnu	addv s24, v24.4s
+1a59284e|	gnu	aesd v26.16b, v8.16b
+cf48284e|	gnu	aese v15.16b, v6.16b
+557a284e|	gnu	aesimc v21.16b, v18.16b
+2f6b284e|	gnu	aesmc v15.16b, v25.16b
+cf1c324e|	gnu	and v15.16b, v6.16b, v18.16b
+c9c6032f|	gnu	mvni v9.2s, #0x76, msl #8
+f1a7012f|	gnu	mvni v17.4h, #0x3f, lsl #8
+691d600e|	gnu	bic v9.8b, v11.8b, v0.8b
+c31dfe6e|	gnu	bif v3.16b, v14.16b, v30.16b
+c81cb66e|	gnu	bit v8.16b, v6.16b, v22.16b
+701f6b2e|	gnu	bsl v16.8b, v27.8b, v11.8b
+7c4b600e|	gnu	cls v28.4h, v27.4h
+ce4a602e|	gnu	clz v14.4h, v22.4h
+d08de37e|	gnu	cmeq d16, d14, d3
+e98db96e|	gnu	cmeq v9.4s, v15.4s, v25.4s
+6e99a00e|	gnu	cmeq v14.2s, v11.2s, #0
+933d304e|	gnu	cmge v19.16b, v12.16b, v16.16b
+0e88e07e|	gnu	cmge d14, d0, #0
+9b89202e|	gnu	cmge v27.8b, v12.8b, #0
+6a372f4e|	gnu	cmgt v10.16b, v27.16b, v15.16b
+128be05e|	gnu	cmgt d18, d24, #0
+9189a00e|	gnu	cmgt v17.2s, v12.2s, #0
+f734e67e|	gnu	cmhi d23, d7, d6
+4d36b82e|	gnu	cmhi v13.2s, v18.2s, v24.2s
+003e2b2e|	gnu	cmhs v0.8b, v16.8b, v11.8b
+729ae07e|	gnu	cmle d18, d19, #0
+3699206e|	gnu	cmle v22.16b, v9.16b, #0
+d1ab600e|	gnu	cmlt v17.4h, v30.4h, #0
+ad8e244e|	gnu	cmtst v13.16b, v21.16b, v4.16b
+ef06035e|	gnu	mov b15, v23.b[1]
+5007040e|	gnu	dup v16.2s, v26.s[0]
+890e0b4e|	gnu	dup v9.16b, w20
+951c276e|	gnu	eor v21.16b, v4.16b, v7.16b
+98d4bf7e|	gnu	fabd s24, s4, s31
+bcd4ad6e|	gnu	fabd v28.4s, v5.4s, v13.4s
+78f8e04e|	gnu	fabs v24.2d, v3.2d
+8cc0201e|	gnu	fabs s12, s4
+9ac1601e|	gnu	fabs d26, d12
+3aee307e|	gnu	facge s26, s17, s16
+41ed352e|	gnu	facge v1.2s, v10.2s, v21.2s
+35edaf7e|	gnu	facgt s21, s9, s15
+02efe36e|	gnu	facgt v2.2d, v24.2d, v3.2d
+21d6664e|	gnu	fadd v1.2d, v17.2d, v6.2d
+5e282e1e|	gnu	fadd s30, s2, s14
+4d2a621e|	gnu	fadd d13, d18, d2
+7cd8707e|	gnu	faddp d28, v3.2d
+5dd4386e|	gnu	faddp v29.4s, v2.4s, v24.4s
+69363e1e|	gnu	fccmp s19, s30, #0x9, cc
+c8b56a1e|	gnu	fccmp d14, d10, #0x8, lt
+d1f5271e|	gnu	fccmpe s14, s7, #0x1, al
+3645751e|	gnu	fccmpe d9, d21, #0x6, mi
+21e6735e|	gnu	fcmeq d1, d17, d19
+b6dba05e|	gnu	fcmeq s22, s29, #0
+49d8a04e|	gnu	fcmeq v9.4s, v2.4s, #0
+2ee5667e|	gnu	fcmge d14, d9, d6
+4ee7766e|	gnu	fcmge v14.2d, v26.2d, v22.2d
+4bcba07e|	gnu	fcmge s11, s26, #0
+11c9a02e|	gnu	fcmge v17.2s, v8.2s, #0
+81e4a97e|	gnu	fcmgt s1, s4, s9
+d3e4b56e|	gnu	fcmgt v19.4s, v6.4s, v21.4s
+efc8e05e|	gnu	fcmgt d15, d7, #0
+3ec9e04e|	gnu	fcmgt v30.2d, v9.2d, #0
+38d9a07e|	gnu	fcmle s24, s9, #0
+7dd9a02e|	gnu	fcmle v29.2s, v11.2s, #0
+bae8a05e|	gnu	fcmlt s26, s5, #0
+a2eaa04e|	gnu	fcmlt v2.4s, v21.4s, #0
+60212f1e|	gnu	fcmp s11, s15
+a8233a1e|	gnu	fcmp s29, #0
+a020641e|	gnu	fcmp d5, d4
+e820701e|	gnu	fcmp d7, #0
+b0203a1e|	gnu	fcmpe s5, s26
+78203d1e|	gnu	fcmpe s3, #0
+70226e1e|	gnu	fcmpe d19, d14
+3821601e|	gnu	fcmpe d9, #0
+06de241e|	gnu	fcsel s6, s16, s4, le
+51de761e|	gnu	fcsel d17, d18, d22, le
+5e42e21e|	gnu	fcvt s30, h18
+b9c1e21e|	gnu	fcvt d25, h13
+58c0231e|	gnu	fcvt h24, s2
+9bc2221e|	gnu	fcvt d27, s20
+2bc3631e|	gnu	fcvt h11, d25
+f640621e|	gnu	fcvt s22, d7
+caca215e|	gnu	fcvtas s10, s22
+5ec9210e|	gnu	fcvtas v30.2s, v10.2s
+0302241e|	gnu	fcvtas w3, s16
+c103249e|	gnu	fcvtas x1, s30
+3003641e|	gnu	fcvtas w16, d25
+6201649e|	gnu	fcvtas x2, d11
+d3c9217e|	gnu	fcvtau s19, s14
+3bc8212e|	gnu	fcvtau v27.2s, v1.2s
+0802251e|	gnu	fcvtau w8, s16
+5f02259e|	gnu	fcvtau xzr, s18
+2801651e|	gnu	fcvtau w8, d9
+f200659e|	gnu	fcvtau x18, d7
+d179610e|	gnu	fcvtl v17.2d, v14.2s
+347b614e|	gnu	fcvtl2 v20.2d, v25.4s
+08b9615e|	gnu	fcvtms d8, d8
+f000301e|	gnu	fcvtms w16, s7
+8002309e|	gnu	fcvtms x0, s20
+5202701e|	gnu	fcvtms w18, d18
+c803709e|	gnu	fcvtms x8, d30
+1cbb217e|	gnu	fcvtmu s28, s24
+d1b9212e|	gnu	fcvtmu v17.2s, v14.2s
+2e02311e|	gnu	fcvtmu w14, s17
+d003319e|	gnu	fcvtmu x16, s30
+ce03711e|	gnu	fcvtmu w14, d30
+0801719e|	gnu	fcvtmu x8, d8
+4c6b210e|	gnu	fcvtn v12.4h, v26.4s
+6869214e|	gnu	fcvtn2 v8.8h, v11.4s
+2faa615e|	gnu	fcvtns d15, d17
+33aa614e|	gnu	fcvtns v19.2d, v17.2d
+d303201e|	gnu	fcvtns w19, s30
+4001209e|	gnu	fcvtns x0, s10
+b202601e|	gnu	fcvtns w18, d21
+c603609e|	gnu	fcvtns x6, d30
+8ea8217e|	gnu	fcvtnu s14, s4
+cc01211e|	gnu	fcvtnu w12, s14
+3a00219e|	gnu	fcvtnu x26, s1
+2002611e|	gnu	fcvtnu w0, d17
+ff01619e|	gnu	fcvtnu xzr, d15
+1baba15e|	gnu	fcvtps s27, s24
+9d00281e|	gnu	fcvtps w29, s4
+eb02289e|	gnu	fcvtps x11, s23
+3503681e|	gnu	fcvtps w21, d25
+4301689e|	gnu	fcvtps x3, d10
+63aba17e|	gnu	fcvtpu s3, s27
+caa8a12e|	gnu	fcvtpu v10.2s, v6.2s
+7702291e|	gnu	fcvtpu w23, s19
+b503299e|	gnu	fcvtpu x21, s29
+2f03691e|	gnu	fcvtpu w15, d25
+5b01699e|	gnu	fcvtpu x27, d10
+7369617e|	gnu	fcvtxn s19, d11
+6b6b612e|	gnu	fcvtxn v11.2s, v27.2d
+f268616e|	gnu	fcvtxn2 v18.4s, v7.2d
+bcff7b5f|	gnu	fcvtzs d28, d29, #5
+19bbe15e|	gnu	fcvtzs d25, d24
+c6b9e14e|	gnu	fcvtzs v6.2d, v14.2d
+e9fc189e|	gnu	fcvtzs x9, s7, #1
+6661589e|	gnu	fcvtzs x6, d11, #40
+9702381e|	gnu	fcvtzs w23, s20
+ed00389e|	gnu	fcvtzs x13, s7
+3a01781e|	gnu	fcvtzs w26, d9
+8801789e|	gnu	fcvtzs x8, d12
+a5ff2e2f|	gnu	fcvtzu v5.2s, v29.2s, #18
+5bbbe17e|	gnu	fcvtzu d27, d26
+1a74199e|	gnu	fcvtzu x26, s0, #35
+e391599e|	gnu	fcvtzu x3, d15, #28
+b203391e|	gnu	fcvtzu w18, s29
+ed01399e|	gnu	fcvtzu x13, s15
+c200791e|	gnu	fcvtzu w2, d6
+5402799e|	gnu	fcvtzu x20, d18
+1aff2b6e|	gnu	fdiv v26.4s, v24.4s, v11.4s
+171a391e|	gnu	fdiv s23, s16, s25
+7d196b1e|	gnu	fdiv d29, d11, d11
+f9721f1f|	gnu	fmadd s25, s23, s31, s28
+7070551f|	gnu	fmadd d16, d3, d21, d28
+05f7624e|	gnu	fmax v5.2d, v24.2d, v2.2d
+88493d1e|	gnu	fmax s8, s12, s29
+4a496d1e|	gnu	fmax d10, d10, d13
+5068321e|	gnu	fmaxnm s16, s2, s18
+a66a761e|	gnu	fmaxnm d6, d21, d22
+0ccb707e|	gnu	fmaxnmp d12, v24.2d
+6ec66f6e|	gnu	fmaxnmp v14.2d, v19.2d, v15.2d
+41f8307e|	gnu	fmaxp s1, v2.2s
+05f72a6e|	gnu	fmaxp v5.4s, v24.4s, v10.4s
+aa5b231e|	gnu	fmin s10, s29, s3
+d6596a1e|	gnu	fmin d22, d14, d10
+15c4b24e|	gnu	fminnm v21.4s, v0.4s, v18.4s
+6279281e|	gnu	fminnm s2, s11, s8
+af7b6a1e|	gnu	fminnm d15, d29, d10
+7dc9f07e|	gnu	fminnmp d29, v11.2d
+dfc6bb6e|	gnu	fminnmp v31.4s, v22.4s, v27.4s
+56c8b06e|	gnu	fminnmv s22, v2.4s
+0ff8f07e|	gnu	fminp d15, v0.2d
+a211c55f|	gnu	fmla d2, d13, v5.d[0]
+0dce224e|	gnu	fmla v13.4s, v16.4s, v2.4s
+4c5ba15f|	gnu	fmls s12, s26, v1.s[3]
+8953ba0f|	gnu	fmls v9.2s, v28.2s, v26.s[1]
+09cdbd4e|	gnu	fmls v9.4s, v8.4s, v29.4s
+97f7044f|	gnu	fmov v23.4s, #-7.000000000000000000e+00
+dff4006f|	gnu	fmov v31.2d, #2.750000000000000000e+00
+c543201e|	gnu	fmov s5, s30
+1740601e|	gnu	fmov d23, d0
+a100271e|	gnu	fmov s1, w5
+f102261e|	gnu	fmov w17, s23
+b302679e|	gnu	fmov d19, x21
+4001af9e|	gnu	fmov v0.d[1], x10
+db01669e|	gnu	fmov x27, d14
+8300ae9e|	gnu	fmov x3, v4.d[1]
+1870331e|	gnu	fmov s24, #-6.750000000000000000e+00
+08507d1e|	gnu	fmov d8, #-8.125000000000000000e-01
+5cbf0c1f|	gnu	fmsub s28, s26, s12, s15
+89e3501f|	gnu	fmsub d9, d28, d16, d24
+3a93c95f|	gnu	fmul d26, d25, v9.d[0]
+5a90ae4f|	gnu	fmul v26.4s, v2.4s, v14.s[1]
+ba0a2f1e|	gnu	fmul s26, s21, s15
+5b0a7c1e|	gnu	fmul d27, d18, d28
+e991c07f|	gnu	fmulx d9, d15, v0.d[0]
+be989c6f|	gnu	fmulx v30.4s, v5.4s, v28.s[2]
+d3dc7a5e|	gnu	fmulx d19, d6, d26
+d4de7f4e|	gnu	fmulx v20.2d, v22.2d, v31.2d
+8e41211e|	gnu	fneg s14, s12
+dc42611e|	gnu	fneg d28, d22
+cb362e1f|	gnu	fnmadd s11, s22, s14, s13
+6441791f|	gnu	fnmadd d4, d11, d25, d16
+36ed291f|	gnu	fnmsub s22, s9, s9, s27
+35b27a1f|	gnu	fnmsub d21, d17, d26, d12
+9388301e|	gnu	fnmul s19, s4, s16
+c088711e|	gnu	fnmul d0, d6, d17
+e8daa15e|	gnu	frecpe s8, s23
+a9fc395e|	gnu	frecps s9, s5, s25
+49fe284e|	gnu	frecps v9.4s, v18.4s, v8.4s
+85f8a15e|	gnu	frecpx s5, s4
+ee43261e|	gnu	frinta s14, s31
+7042661e|	gnu	frinta d16, d19
+2b98a16e|	gnu	frinti v11.4s, v1.4s
+fac2271e|	gnu	frinti s26, s23
+76c3671e|	gnu	frinti d22, d27
+7942251e|	gnu	frintm s25, s19
+8742651e|	gnu	frintm d7, d20
+fc8a214e|	gnu	frintn v28.4s, v23.4s
+c041241e|	gnu	frintn s0, s14
+b241641e|	gnu	frintn d18, d13
+c588a14e|	gnu	frintp v5.4s, v6.4s
+6ec2241e|	gnu	frintp s14, s19
+ddc0641e|	gnu	frintp d29, d6
+1a9a616e|	gnu	frintx v26.2d, v16.2d
+7c41271e|	gnu	frintx s28, s11
+d243671e|	gnu	frintx d18, d30
+b49aa14e|	gnu	frintz v20.4s, v21.4s
+5bc0251e|	gnu	frintz s27, s2
+43c1651e|	gnu	frintz d3, d10
+3bdba17e|	gnu	frsqrte s27, s25
+9ddba12e|	gnu	frsqrte v29.2s, v28.2s
+1ffee65e|	gnu	frsqrts d31, d16, d6
+8bfdb54e|	gnu	frsqrts v11.4s, v12.4s, v21.4s
+33c1211e|	gnu	fsqrt s19, s9
+a5c0611e|	gnu	fsqrt d5, d5
+a2d7b74e|	gnu	fsub v2.4s, v29.4s, v23.4s
+a338301e|	gnu	fsub s3, s5, s16
+e139681e|	gnu	fsub d1, d15, d8
+96170e6e|	gnu	mov v22.h[3], v28.h[1]
+791c014e|	gnu	mov v25.b[0], w3
+cf79404c|	gnu	ld1 {v15.4s}, [x14]
+75a6404c|	gnu	ld1 {v21.8h, v22.8h}, [x19]
+ed62404c|	gnu	ld1 {v13.16b-v15.16b}, [x23]
+392a400c|	gnu	ld1 {v25.2s-v28.2s}, [x17]
+cd7cdf4c|	gnu	ld1 {v13.2d}, [x6],#16
+f677ce4c|	gnu	ld1 {v22.8h}, [sp], x14
+d4a3df0c|	gnu	ld1 {v20.8b, v21.8b}, [x30],#16
+8ba1d90c|	gnu	ld1 {v11.8b, v12.8b}, [x12], x25
+396fdf0c|	gnu	ld1 {v25.1d-v27.1d}, [x25],#24
+4c64db0c|	gnu	ld1 {v12.4h-v14.4h}, [x2], x27
+3f2adf4c|	gnu	ld1 {v31.4s, v0.4s, v1.4s, v2.4s}, [x17],#64
+b329ce4c|	gnu	ld1 {v19.4s-v22.4s}, [x13], x14
+aa02400d|	gnu	ld1 {v10.b}[0], [x21]
+7980404d|	gnu	ld1 {v25.s}[2], [x3]
+5884404d|	gnu	ld1 {v24.d}[1], [x2]
+f203df4d|	gnu	ld1 {v18.b}[8], [sp],#1
+3519c40d|	gnu	ld1 {v21.b}[6], [x9], x4
+ed59df0d|	gnu	ld1 {v13.h}[3], [x15],#2
+9e52d90d|	gnu	ld1 {v30.h}[2], [x20], x25
+cd93df4d|	gnu	ld1 {v13.s}[3], [x30],#4
+5982cb4d|	gnu	ld1 {v25.s}[2], [x18], x11
+4f84df4d|	gnu	ld1 {v15.d}[1], [x2],#8
+2d85d50d|	gnu	ld1 {v13.d}[0], [x9], x21
+33c2400d|	gnu	ld1r {v19.8b}, [x17]
+e2c8df4d|	gnu	ld1r {v2.4s}, [x7],#4
+83c2c44d|	gnu	ld1r {v3.16b}, [x20], x4
+5487400c|	gnu	ld2 {v20.4h, v21.4h}, [x26]
+e08adf0c|	gnu	ld2 {v0.2s, v1.2s}, [x23],#16
+768ac40c|	gnu	ld2 {v22.2s, v23.2s}, [x19], x4
+4c0f604d|	gnu	ld2 {v12.b, v13.b}[11], [x26]
+e043604d|	gnu	ld2 {v0.h, v1.h}[4], [sp]
+c281600d|	gnu	ld2 {v2.s, v3.s}[0], [x14]
+e585600d|	gnu	ld2 {v5.d, v6.d}[0], [x15]
+2c1aff4d|	gnu	ld2 {v12.b, v13.b}[14], [x17],#2
+820bfd4d|	gnu	ld2 {v2.b, v3.b}[10], [x28], x29
+d593ff0d|	gnu	ld2 {v21.s, v22.s}[1], [x30],#8
+6780ea0d|	gnu	ld2 {v7.s, v8.s}[0], [x3], x10
+3484ff4d|	gnu	ld2 {v20.d, v21.d}[1], [x1],#16
+6a86ee4d|	gnu	ld2 {v10.d, v11.d}[1], [x19], x14
+e4c7604d|	gnu	ld2r {v4.8h, v5.8h}, [sp]
+69c8ff0d|	gnu	ld2r {v9.2s, v10.2s}, [x3],#8
+52ccf30d|	gnu	ld2r {v18.1d, v19.1d}, [x2], x19
+9e4b404c|	gnu	ld3 {v30.4s, v31.4s, v0.4s}, [x28]
+0440df4c|	gnu	ld3 {v4.16b-v6.16b}, [x0],#48
+0f49cf0c|	gnu	ld3 {v15.2s-v17.2s}, [x8], x15
+b22e400d|	gnu	ld3 {v18.b-v20.b}[3], [x21]
+9473400d|	gnu	ld3 {v20.h-v22.h}[2], [x28]
+1da0404d|	gnu	ld3 {v29.s-v31.s}[2], [x0]
+21a5404d|	gnu	ld3 {v1.d-v3.d}[1], [x9]
+3b23df0d|	gnu	ld3 {v27.b-v29.b}[0], [x25],#3
+0937c60d|	gnu	ld3 {v9.b-v11.b}[5], [x24], x6
+926bcb4d|	gnu	ld3 {v18.h-v20.h}[5], [x28], x11
+f5a1df4d|	gnu	ld3 {v21.s-v23.s}[2], [x15],#12
+dba3c44d|	gnu	ld3 {v27.s-v29.s}[2], [x30], x4
+12a5df0d|	gnu	ld3 {v18.d-v20.d}[0], [x8],#24
+daa7d30d|	gnu	ld3 {v26.d-v28.d}[0], [x30], x19
+3beb400d|	gnu	ld3r {v27.2s-v29.2s}, [x25]
+cde4df4d|	gnu	ld3r {v13.8h-v15.8h}, [x6],#6
+a4efc44d|	gnu	ld3r {v4.2d-v6.2d}, [x29], x4
+fc0a400c|	gnu	ld4 {v28.2s-v31.2s}, [x23]
+ae05df0c|	gnu	ld4 {v14.4h-v17.4h}, [x13],#32
+cb07c84c|	gnu	ld4 {v11.8h-v14.8h}, [x30], x8
+1825604d|	gnu	ld4 {v24.b-v27.b}[9], [x8]
+2869604d|	gnu	ld4 {v8.h-v11.h}[5], [x9]
+07b2600d|	gnu	ld4 {v7.s-v10.s}[1], [x16]
+9fa4600d|	gnu	ld4 {v31.d, v0.d, v1.d, v2.d}[0], [x4]
+de22ff0d|	gnu	ld4 {v30.b, v31.b, v0.b, v1.b}[0], [x22],#4
+6a36ed4d|	gnu	ld4 {v10.b-v13.b}[13], [x19], x13
+23a2ff4d|	gnu	ld4 {v3.s-v6.s}[2], [x17],#16
+22a0fe4d|	gnu	ld4 {v2.s-v5.s}[2], [x1], x30
+7ca4ff4d|	gnu	ld4 {v28.d-v31.d}[1], [x3],#32
+03a7ec4d|	gnu	ld4 {v3.d-v6.d}[1], [x24], x12
+b9ee600d|	gnu	ld4r {v25.1d-v28.1d}, [x21]
+03e8ff0d|	gnu	ld4r {v3.2s-v6.2s}, [x0],#16
+e7e3f24d|	gnu	ld4r {v7.16b-v10.16b}, [sp], x18
+451a4e2c|	gnu	ldnp s5, s6, [x18,#112]
+01236f6c|	gnu	ldnp d1, d8, [x24,#-272]
+204041ac|	gnu	ldnp q0, q16, [x1,#32]
+1b21cc2c|	gnu	ldp s27, s8, [x8],#96
+41ccc06c|	gnu	ldp d1, d19, [x2],#8
+65b8e6ac|	gnu	ldp q5, q14, [x3],#-816
+a58bed2d|	gnu	ldp s5, s2, [x29,#-148]!
+d8a3c46d|	gnu	ldp d24, d8, [x30,#72]!
+dc82c0ad|	gnu	ldp q28, q0, [x22,#16]!
+eda7782d|	gnu	ldp s13, s9, [sp,#-60]
+041b6c6d|	gnu	ldp d4, d6, [x24,#-320]
+17ea6bad|	gnu	ldp q23, q26, [x16,#-656]
+4e14433c|	gnu	ldr b14, [x2],#49
+cd844e7c|	gnu	ldr h13, [x6],#232
+99945dbc|	gnu	ldr s25, [x4],#-39
+170556fc|	gnu	ldr d23, [x8],#-160
+3115d53c|	gnu	ldr q17, [x9],#-175
+3c6d403c|	gnu	ldr b28, [x9,#6]!
+f8fc527c|	gnu	ldr h24, [x7,#-209]!
+776c58bc|	gnu	ldr s23, [x3,#-122]!
+075f57fc|	gnu	ldr d7, [x24,#-139]!
+28cdc33c|	gnu	ldr q8, [x9,#60]!
+40a15f3d|	gnu	ldr b0, [x10,#2024]
+3b8c597d|	gnu	ldr h27, [x1,#3270]
+28f958bd|	gnu	ldr s8, [x9,#6392]
+852d6ffd|	gnu	ldr d5, [x12,#24152]
+e149ea3d|	gnu	ldr q1, [x15,#43296]
+807f7c1c|	gnu	ldr s0, .+0xf8ff0
+e7a61c5c|	gnu	ldr d7, .+0x394dc
+261ec59c|	gnu	ldr q6, .+0xfffffffffff8a3c4
+4bca773c|	gnu	ldr b11, [x18,w23,sxtw]
+8d69623c|	gnu	ldr b13, [x12,x2]
+cef8797c|	gnu	ldr h14, [x6,x25,sxtx #1]
+b7497bfc|	gnu	ldr d23, [x13,w27,uxtw]
+dbdbfc3c|	gnu	ldr q27, [x30,w28,sxtw #4]
+1a60553c|	gnu	ldur b26, [x0,#-170]
+74f3477c|	gnu	ldur h20, [x27,#127]
+f46249bc|	gnu	ldur s20, [x23,#150]
+b8015bfc|	gnu	ldur d24, [x13,#-80]
+3372de3c|	gnu	ldur q19, [x17,#-25]
+04972c0e|	gnu	mla v4.8b, v24.8b, v12.8b
+f0051b5e|	gnu	mov b16, v15.b[13]
+7f76146e|	gnu	mov v31.s[2], v19.s[3]
+6c1cb60e|	gnu	orr v12.8b, v3.8b, v22.8b
+ae3f1e0e|	gnu	umov w14, v29.h[7]
+f8e5004f|	gnu	movi v24.16b, #0xf
+0355010f|	gnu	orr v3.2s, #0x28, lsl #16
+4825020f|	gnu	movi v8.2s, #0x4a, lsl #8
+64d7040f|	gnu	movi v4.2s, #0x9b, msl #16
+46e6062f|	gnu	movi d6, #0xffff00ff0000ff00
+bde6056f|	gnu	movi v29.2d, #0xff00ffff00ff00ff
+789f350e|	gnu	mul v24.8b, v27.8b, v21.8b
+7b5b202e|	gnu	mvn v27.8b, v27.8b
+2dd4066f|	gnu	mvni v13.4s, #0xc1, msl #16
+8266012f|	gnu	mvni v2.2s, #0x34, lsl #24
+1025022f|	gnu	mvni v16.2s, #0x48, lsl #8
+eabba06e|	gnu	neg v10.4s, v31.4s
+7e5a206e|	gnu	mvn v30.16b, v19.16b
+6a1fea0e|	gnu	orn v10.8b, v27.8b, v10.8b
+b406010f|	gnu	movi v20.2s, #0x35
+f564040f|	gnu	movi v21.2s, #0x87, lsl #24
+b21cb80e|	gnu	orr v18.8b, v5.8b, v24.8b
+2b437a2e|	gnu	raddhn v11.4h, v25.4s, v26.4s
+6d402c6e|	gnu	raddhn2 v13.16b, v3.8h, v12.8h
+655a606e|	gnu	rbit v5.16b, v19.16b
+5108202e|	gnu	rev32 v17.8b, v2.8b
+750a200e|	gnu	rev64 v21.8b, v19.8b
+f88f0b0f|	gnu	rshrn v24.8b, v31.8h, #5
+8263236e|	gnu	rsubhn2 v2.16b, v28.8h, v3.8h
+787c320e|	gnu	saba v24.8b, v3.8b, v18.8b
+f551220e|	gnu	sabal v21.8h, v15.8b, v2.8b
+b5766d0e|	gnu	sabd v21.4h, v21.4h, v13.4h
+9270240e|	gnu	sabdl v18.8h, v4.8b, v4.8b
+4d71384e|	gnu	sabdl2 v13.8h, v10.16b, v24.16b
+8f6a600e|	gnu	sadalp v15.2s, v20.4h
+e501750e|	gnu	saddl v5.4s, v15.4h, v21.4h
+5202ab4e|	gnu	saddl2 v18.2d, v18.4s, v11.4s
+7029200e|	gnu	saddlp v16.4h, v11.8b
+3913710e|	gnu	saddw v25.4s, v25.4s, v17.4h
+d7e4575f|	gnu	scvtf d23, d6, #41
+c6db215e|	gnu	scvtf s6, s30
+17d8214e|	gnu	scvtf v23.4s, v0.4s
+62c4021e|	gnu	scvtf s2, w3, #15
+f5cd421e|	gnu	scvtf d21, w15, #13
+6128029e|	gnu	scvtf s1, x3, #54
+9a7c429e|	gnu	scvtf d26, x4, #33
+6102221e|	gnu	scvtf s1, w19
+0b03621e|	gnu	scvtf d11, w24
+ed01229e|	gnu	scvtf s13, x15
+6f02629e|	gnu	scvtf d15, x19
+ac03055e|	gnu	sha1c q12, s29, v5.4s
+e309285e|	gnu	sha1h s3, s15
+2a221b5e|	gnu	sha1m q10, s17, v27.4s
+a013185e|	gnu	sha1p q0, s29, v24.4s
+6032005e|	gnu	sha1su0 v0.4s, v19.4s, v0.4s
+f918285e|	gnu	sha1su1 v25.4s, v7.4s
+fb50035e|	gnu	sha256h2 q27, q7, v3.4s
+6d421c5e|	gnu	sha256h q13, q19, v28.4s
+c12b285e|	gnu	sha256su0 v1.4s, v30.4s
+6362095e|	gnu	sha256su1 v3.4s, v19.4s, v9.4s
+a805bb0e|	gnu	shadd v8.2s, v13.2s, v27.2s
+783b616e|	gnu	shll2 v24.4s, v27.8h, #16
+48841b0f|	gnu	shrn v8.4h, v2.4s, #5
+a924bc4e|	gnu	shsub v9.4s, v5.4s, v28.4s
+1557717f|	gnu	sli d21, d24, #49
+2a56456f|	gnu	sli v10.2d, v17.2d, #5
+7c663b0e|	gnu	smax v28.8b, v19.8b, v27.8b
+b5a7694e|	gnu	smaxp v21.8h, v29.8h, v9.8h
+8ea8b04e|	gnu	smaxv s14, v4.4s
+936cb44e|	gnu	smin v19.4s, v4.4s, v20.4s
+15af7e4e|	gnu	sminp v21.8h, v24.8h, v30.8h
+3e81694e|	gnu	smlal2 v30.4s, v9.8h, v9.8h
+29a26d0e|	gnu	smlsl v9.4s, v17.4h, v13.4h
+442e0b4e|	gnu	smov x4, v18.b[5]
+e1a0540f|	gnu	smull v1.4s, v7.4h, v4.h[1]
+5eaa604f|	gnu	smull2 v30.4s, v18.8h, v0.h[6]
+4cc32d4e|	gnu	smull2 v12.8h, v26.16b, v13.16b
+1e7a205e|	gnu	sqabs b30, b16
+e67ae04e|	gnu	sqabs v6.2d, v23.2d
+a80ded5e|	gnu	sqadd d8, d13, d13
+e60dae4e|	gnu	sqadd v6.4s, v15.4s, v14.4s
+fe33570f|	gnu	sqdmlal v30.4s, v31.4h, v7.h[1]
+ee90b64e|	gnu	sqdmlal2 v14.2d, v7.4s, v22.4s
+ce79a05f|	gnu	sqdmlsl d14, s14, v0.s[3]
+d5b2a14e|	gnu	sqdmlsl2 v21.2d, v22.4s, v1.4s
+51cb575f|	gnu	sqdmulh h17, h26, v7.h[5]
+0cb5b54e|	gnu	sqdmulh v12.4s, v8.4s, v21.4s
+95d0760e|	gnu	sqdmull v21.4s, v4.4h, v22.4h
+a1d37c4e|	gnu	sqdmull2 v1.4s, v29.8h, v28.8h
+d679e07e|	gnu	sqneg d22, d14
+3f78602e|	gnu	sqneg v31.4h, v1.4h
+80b4717e|	gnu	sqrdmulh h0, h4, h17
+4cb76e2e|	gnu	sqrdmulh v12.4h, v26.4h, v14.4h
+aa5ce95e|	gnu	sqrshl d10, d5, d9
+d25fb74e|	gnu	sqrshl v18.4s, v30.4s, v23.4s
+998c0c6f|	gnu	sqrshrun2 v25.16b, v4.8h, #4
+4375605f|	gnu	sqshl d3, d10, #32
+de743f0f|	gnu	sqshl v30.2s, v6.2s, #31
+a84d675e|	gnu	sqshl h8, h13, h7
+674dbe4e|	gnu	sqshl v7.4s, v11.4s, v30.4s
+5165587f|	gnu	sqshlu d17, d10, #24
+b464042f|	gnu	mvni v20.2s, #0x85, lsl #24
+2086207f|	gnu	sqshrun s0, d17, #32
+8a851a2f|	gnu	sqshrun v10.4h, v12.4s, #6
+652c255e|	gnu	sqsub b5, b3, b5
+632eb30e|	gnu	sqsub v3.2s, v19.2s, v19.2s
+104ba15e|	gnu	sqxtn s16, d24
+2249214e|	gnu	sqxtn2 v2.16b, v9.8h
+1c14360e|	gnu	srhadd v28.8b, v0.8b, v22.8b
+8044076f|	gnu	mvni v0.4s, #0xe4, lsl #16
+3a57ed5e|	gnu	srshl d26, d25, d13
+2c56ef4e|	gnu	srshl v12.2d, v17.2d, v15.2d
+9627140f|	gnu	srshr v22.4h, v28.4h, #12
+bd37565f|	gnu	srsra d29, d29, #42
+db34594f|	gnu	srsra v27.2d, v6.2d, #39
+4546a10e|	gnu	sshl v5.2s, v18.2s, v1.2s
+aca7020f|	gnu	movi v12.4h, #0x5d, lsl #8
+e004675f|	gnu	sshr d0, d7, #25
+e5057f4f|	gnu	sshr v5.2d, v15.2d, #1
+1b15595f|	gnu	ssra d27, d8, #39
+ba15250f|	gnu	ssra v26.2s, v13.2s, #27
+3620330e|	gnu	ssubl v22.8h, v1.8b, v19.8b
+c1316d4e|	gnu	ssubw2 v1.4s, v14.4s, v13.8h
+8a76000c|	gnu	st1 {v10.4h}, [x20]
+10a5004c|	gnu	st1 {v16.8h, v17.8h}, [x8]
+ab6b004c|	gnu	st1 {v11.4s-v13.4s}, [x29]
+8d2b004c|	gnu	st1 {v13.4s-v16.4s}, [x28]
+8d7d9f0c|	gnu	st1 {v13.1d}, [x12],#8
+eb73840c|	gnu	st1 {v11.8b}, [sp], x4
+48a69f4c|	gnu	st1 {v8.8h, v9.8h}, [x18],#32
+dca19b4c|	gnu	st1 {v28.16b, v29.16b}, [x14], x27
+7c699f4c|	gnu	st1 {v28.4s-v30.4s}, [x11],#48
+da6d870c|	gnu	st1 {v26.1d-v28.1d}, [x14], x7
+7f279f0c|	gnu	st1 {v31.4h, v0.4h, v1.4h, v2.4h}, [x27],#32
+4421810c|	gnu	st1 {v4.8b-v7.8b}, [x10], x1
+a615004d|	gnu	st1 {v6.b}[13], [x13]
+ce92000d|	gnu	st1 {v14.s}[1], [x22]
+c985000d|	gnu	st1 {v9.d}[0], [x14]
+380f9f0d|	gnu	st1 {v24.b}[3], [x25],#1
+de0b944d|	gnu	st1 {v30.b}[10], [x30], x20
+3141880d|	gnu	st1 {v17.h}[0], [x9], x8
+8e939f0d|	gnu	st1 {v14.s}[1], [x28],#4
+c890870d|	gnu	st1 {v8.s}[1], [x6], x7
+9f869f4d|	gnu	st1 {v31.d}[1], [x20],#8
+38879b4d|	gnu	st1 {v24.d}[1], [x25], x27
+4181004c|	gnu	st2 {v1.16b, v2.16b}, [x10]
+d6819f0c|	gnu	st2 {v22.8b, v23.8b}, [x14],#16
+bf808a0c|	gnu	st2 {v31.8b, v0.8b}, [x5], x10
+bd0e204d|	gnu	st2 {v29.b, v30.b}[11], [x21]
+4551204d|	gnu	st2 {v5.h, v6.h}[6], [x10]
+9982204d|	gnu	st2 {v25.s, v26.s}[2], [x20]
+ea86200d|	gnu	st2 {v10.d, v11.d}[0], [x23]
+7b02bf0d|	gnu	st2 {v27.b, v28.b}[0], [x19],#2
+c000a04d|	gnu	st2 {v0.b, v1.b}[8], [x6], x0
+fb59a40d|	gnu	st2 {v27.h, v28.h}[3], [x15], x4
+f880bf0d|	gnu	st2 {v24.s, v25.s}[0], [x7],#8
+f582ac4d|	gnu	st2 {v21.s, v22.s}[2], [x23], x12
+9c86bf4d|	gnu	st2 {v28.d, v29.d}[1], [x20],#16
+3386b14d|	gnu	st2 {v19.d, v20.d}[1], [x17], x17
+c0469f0c|	gnu	st3 {v0.4h-v2.4h}, [x22],#24
+2243820c|	gnu	st3 {v2.8b-v4.8b}, [x25], x2
+c629000d|	gnu	st3 {v6.b-v8.b}[2], [x14]
+4f6a004d|	gnu	st3 {v15.h-v17.h}[5], [x18]
+72a0004d|	gnu	st3 {v18.s-v20.s}[2], [x3]
+c1a4000d|	gnu	st3 {v1.d-v3.d}[0], [x6]
+312e9f0d|	gnu	st3 {v17.b-v19.b}[3], [x17],#3
+9a28934d|	gnu	st3 {v26.b-v28.b}[10], [x4], x19
+a1799f4d|	gnu	st3 {v1.h-v3.h}[7], [x13],#6
+3ba29f0d|	gnu	st3 {v27.s-v29.s}[0], [x17],#12
+80b2870d|	gnu	st3 {v0.s-v2.s}[1], [x20], x7
+f6a49f4d|	gnu	st3 {v22.d-v24.d}[1], [x7],#24
+8fa69a4d|	gnu	st3 {v15.d-v17.d}[1], [x20], x26
+ee09000c|	gnu	st4 {v14.2s-v17.2s}, [x15]
+1e07880c|	gnu	st4 {v30.4h, v31.4h, v0.4h, v1.4h}, [x24], x8
+6426204d|	gnu	st4 {v4.b-v7.b}[9], [x19]
+4ea2204d|	gnu	st4 {v14.s-v17.s}[2], [x18]
+05a6200d|	gnu	st4 {v5.d-v8.d}[0], [x16]
+5b21bf0d|	gnu	st4 {v27.b-v30.b}[0], [x10],#4
+ce28a00d|	gnu	st4 {v14.b-v17.b}[2], [x6], x0
+767bbf4d|	gnu	st4 {v22.h-v25.h}[7], [x27],#8
+747aa24d|	gnu	st4 {v20.h-v23.h}[7], [x19], x2
+24b0bf0d|	gnu	st4 {v4.s-v7.s}[1], [x1],#16
+c7b1a90d|	gnu	st4 {v7.s-v10.s}[1], [x14], x9
+9fa4bf4d|	gnu	st4 {v31.d, v0.d, v1.d, v2.d}[1], [x4],#32
+70a4ab4d|	gnu	st4 {v16.d-v19.d}[1], [x3], x11
+89fe2e2c|	gnu	stnp s9, s31, [x20,#-140]
+bfd31d6c|	gnu	stnp d31, d20, [x29,#472]
+ddf301ac|	gnu	stnp q29, q28, [x30,#48]
+14f6ac2c|	gnu	stp s20, s29, [x16],#-156
+251db76c|	gnu	stp d5, d7, [x9],#-144
+e51fb7ac|	gnu	stp q5, q7, [sp],#-288
+5c90852d|	gnu	stp s28, s4, [x2,#44]!
+4c51a56d|	gnu	stp d12, d20, [x10,#-432]!
+265d8aad|	gnu	stp q6, q23, [x9,#320]!
+9c0c392d|	gnu	stp s28, s3, [x4,#-56]
+b49e1e6d|	gnu	stp d20, d7, [x21,#488]
+55f105ad|	gnu	stp q21, q28, [x10,#176]
+4dd6003c|	gnu	str b13, [x18],#13
+e357067c|	gnu	str h3, [sp],#101
+f6841dbc|	gnu	str s22, [x7],#-40
+54b710fc|	gnu	str d20, [x26],#-245
+0d07833c|	gnu	str q13, [x24],#48
+393f003c|	gnu	str b25, [x25,#3]!
+1fac007c|	gnu	str h31, [x0,#10]!
+d41d13bc|	gnu	str s20, [x14,#-207]!
+908f0dfc|	gnu	str d16, [x28,#216]!
+5ded9d3c|	gnu	str q29, [x10,#-34]!
+6d72073d|	gnu	str b13, [x19,#476]
+68752d7d|	gnu	str h8, [x11,#5818]
+084728bd|	gnu	str s8, [x24,#10308]
+409503fd|	gnu	str d0, [x10,#1832]
+58a1963d|	gnu	str q24, [x10,#23168]
+51c8253c|	gnu	str b17, [x2,w5,sxtw]
+967b313c|	gnu	str b22, [x28,x17,lsl #0]
+b4683e7c|	gnu	str h20, [x5,x30]
+64d9a33c|	gnu	str q4, [x11,w3,sxtw #4]
+e5e1143c|	gnu	stur b5, [x15,#-178]
+99901e7c|	gnu	stur h25, [x4,#-23]
+bb0012bc|	gnu	stur s27, [x5,#-224]
+1d710cfc|	gnu	stur d29, [x8,#199]
+17e1873c|	gnu	stur q23, [x8,#126]
+ed84a26e|	gnu	sub v13.4s, v7.4s, v2.4s
+7761b80e|	gnu	subhn v23.2s, v11.2d, v24.2d
+f838205e|	gnu	suqadd b24, b7
+7739600e|	gnu	suqadd v23.4h, v11.4h
+26a5204f|	gnu	sxtl2 v6.2d, v9.4s
+5a201a4e|	gnu	tbl v26.16b, {v2.16b, v3.16b}, v26.16b
+c2400f0e|	gnu	tbl v2.8b, {v6.16b-v8.16b}, v15.8b
+7263024e|	gnu	tbl v18.16b, {v27.16b-v30.16b}, v2.16b
+bb010b4e|	gnu	tbl v27.16b, {v13.16b}, v11.16b
+5f31184e|	gnu	tbx v31.16b, {v10.16b, v11.16b}, v24.16b
+a952100e|	gnu	tbx v9.8b, {v21.16b-v23.16b}, v16.8b
+4872170e|	gnu	tbx v8.8b, {v18.16b-v21.16b}, v23.8b
+dc110e4e|	gnu	tbx v28.16b, {v14.16b}, v14.16b
+d7289a4e|	gnu	trn1 v23.4s, v6.4s, v26.4s
+cd6a924e|	gnu	trn2 v13.4s, v22.4s, v18.4s
+a552392e|	gnu	uabal v5.8h, v21.8b, v25.8b
+a653256e|	gnu	uabal2 v6.8h, v29.16b, v5.16b
+fb70b42e|	gnu	uabdl v27.2d, v7.2s, v20.2s
+3b6a202e|	gnu	uadalp v27.4h, v17.8b
+8a03b22e|	gnu	uaddl v10.2d, v28.2s, v18.2s
+262a206e|	gnu	uaddlp v6.8h, v17.16b
+8410312e|	gnu	uaddw v4.8h, v4.8h, v17.8b
+bf11ae6e|	gnu	uaddw2 v31.2d, v13.2d, v14.4s
+a7e65d7f|	gnu	ucvtf d7, d21, #35
+8bda617e|	gnu	ucvtf d11, d20
+7fb8431e|	gnu	ucvtf d31, w3, #18
+1c0f039e|	gnu	ucvtf s28, x24, #61
+2241439e|	gnu	ucvtf d2, x9, #48
+d701231e|	gnu	ucvtf s23, w14
+9600631e|	gnu	ucvtf d22, w4
+8b01239e|	gnu	ucvtf s11, x12
+7202639e|	gnu	ucvtf d18, x19
+3406b82e|	gnu	uhadd v20.2s, v17.2s, v24.2s
+9264612e|	gnu	umax v18.4h, v4.4h, v1.4h
+d9a5772e|	gnu	umaxp v25.4h, v14.4h, v23.4h
+74a8b06e|	gnu	umaxv s20, v3.4s
+24a8312e|	gnu	uminv b4, v1.8b
+c5218e2f|	gnu	umlal v5.2d, v14.2s, v14.s[0]
+3d20a76f|	gnu	umlal2 v29.2d, v1.4s, v7.s[1]
+90817e6e|	gnu	umlal2 v16.4s, v12.8h, v30.8h
+0f69a46f|	gnu	umlsl2 v15.2d, v8.4s, v4.s[3]
+4aa27c2e|	gnu	umlsl v10.4s, v18.4h, v28.4h
+48a27b6e|	gnu	umlsl2 v8.4s, v18.8h, v27.8h
+833c0d0e|	gnu	umov w3, v4.b[6]
+e2a1b22f|	gnu	umull v2.2d, v15.2s, v18.s[1]
+07c06f2e|	gnu	umull v7.4s, v0.4h, v15.4h
+470e367e|	gnu	uqadd b7, b18, b22
+490e252e|	gnu	uqadd v9.8b, v18.8b, v5.8b
+bf5eaa7e|	gnu	uqrshl s31, s21, s10
+c49c347f|	gnu	uqrshrn s4, d6, #12
+b4757a7f|	gnu	uqshl d20, d13, #58
+d14f777e|	gnu	uqshl h17, h30, h23
+9e2d7a7e|	gnu	uqsub h30, h12, h26
+a62c296e|	gnu	uqsub v6.16b, v5.16b, v9.16b
+5d4ba17e|	gnu	uqxtn s29, d26
+454b212e|	gnu	uqxtn v5.8b, v26.8h
+1c48a16e|	gnu	uqxtn2 v28.4s, v0.2d
+4157736e|	gnu	urshl v1.8h, v26.8h, v19.8h
+2d26797f|	gnu	urshr d13, d17, #7
+bd27466f|	gnu	urshr v29.2d, v29.2d, #58
+bcc8a12e|	gnu	ursqrte v28.2s, v5.2s
+f5345d7f|	gnu	ursra d21, d7, #35
+f8353a6f|	gnu	ursra v24.4s, v15.4s, #6
+85a6342f|	gnu	ushll v5.2d, v20.2s, #20
+e7a70e6f|	gnu	ushll2 v7.8h, v31.16b, #6
+ed04787f|	gnu	ushr d13, d7, #8
+8f07362f|	gnu	ushr v15.2s, v28.2s, #10
+963a607e|	gnu	usqadd h22, h20
+383a206e|	gnu	usqadd v24.16b, v17.16b
+ef16596f|	gnu	usra v15.2d, v23.2d, #39
+f222ab2e|	gnu	usubl v18.2d, v23.2s, v11.2s
+9220696e|	gnu	usubl2 v18.4s, v4.8h, v9.8h
+0130312e|	gnu	usubw v1.8h, v0.8h, v17.8b
+a932a06e|	gnu	usubw2 v9.2d, v21.2d, v0.4s
+9a19910e|	gnu	uzp1 v26.2s, v12.2s, v17.2s
+a379ca4e|	gnu	zip2 v3.2d, v13.2d, v10.2d
+1202011a|	gnu	adc w18, w16, w1
+6900199a|	gnu	adc x9, x3, x25
+01010f3a|	gnu	adcs w1, w8, w15
+13010fba|	gnu	adcs x19, x8, x15
+55ed280b|	gnu	add w21, w10, w8, sxtx #3
+2077268b|	gnu	add x0, x25, x6, uxtx #5
+7f40560b|	gnu	add wzr, w3, w22, lsr #16
+3a16282b|	gnu	adds w26, w17, w8, uxtb #5
+f8a336ab|	gnu	adds x24, sp, w22, sxth
+000e6d31|	gnu	adds w0, w16, #0xb43, lsl #12
+b48e49b1|	gnu	adds x20, x21, #0x263, lsl #12
+7e174e2b|	gnu	adds w30, w27, w14, lsr #5
+25e2f250|	gnu	adr x5, .+0xfffffffffffe5c46
+294079f0|	gnu	adrp x9, .+0xf2807000
+3aa13f12|	gnu	and w26, w9, #0x3fe03fe
+32a23592|	gnu	and x18, x17, #0xf80ff80ff80ff80f
+b478070a|	gnu	and w20, w5, w7, lsl #30
+dd1f988a|	gnu	and x29, x30, x24, asr #7
+a7351b72|	gnu	ands w7, w13, #0x7ffe0
+1c056ef2|	gnu	ands x28, x8, #0xc0000
+defd52ea|	gnu	ands x30, x14, x18, lsr #63
+8c28d01a|	gnu	asr w12, w4, w16
+582ac09a|	gnu	asr x24, x18, x0
+647d1813|	gnu	asr w4, w11, #24
+d1fe5b93|	gnu	asr x17, x22, #27
+2329c31a|	gnu	asr w3, w9, w3
+d929d69a|	gnu	asr x25, x14, x22
+aefa5354|	gnu	b.al .+0xa7f54
+76ad3917|	gnu	b .+0xfffffffffce6b5d8
+de320f33|	gnu	bfi w30, w22, #17, #13
+af144db3|	gnu	bfi x15, x5, #51, #6
+161c7eb3|	gnu	bfi x22, x0, #2, #8
+f9791733|	gnu	bfxil w25, w15, #23, #8
+781577b3|	gnu	bfi x24, x11, #9, #6
+0f65f98a|	gnu	bic x15, x8, x25, ror #25
+2c37e16a|	gnu	bics w12, w25, w1, ror #13
+a6f473ea|	gnu	bics x6, x5, x19, lsr #61
+f064ad96|	gnu	bl .+0xfffffffffab593c0
+80023fd6|	gnu	blr x20
+00001fd6|	gnu	br x0
+80de3ed4|	gnu	brk #0xf6f4
+08276a35|	gnu	cbnz w8, .+0xd44e0
+acd1c0b5|	gnu	cbnz x12, .+0xfffffffffff81a34
+ef50bf34|	gnu	cbz w15, .+0xfffffffffff7ea1c
+4bd681b4|	gnu	cbz x11, .+0xfffffffffff03ac8
+4e2a483a|	gnu	ccmn w18, #0x8, #0xe, cs
+4a3a4eba|	gnu	ccmn x18, #0xe, #0xa, cc
+0143553a|	gnu	ccmn w24, w21, #0x1, mi
+c09359ba|	gnu	ccmn x30, x25, #0x0, ls
+020a567a|	gnu	ccmp w16, #0x16, #0x2, eq
+a6985afa|	gnu	ccmp x5, #0x1a, #0x6, ls
+6fc0487a|	gnu	ccmp w3, w8, #0xf, gt
+21d14bfa|	gnu	ccmp x9, x11, #0x1, le
+75f5991a|	gnu	csinc w21, w11, w25, al
+5a25919a|	gnu	csinc x26, x10, x17, cs
+6a938c5a|	gnu	csinv w10, w27, w12, ls
+6a408eda|	gnu	csinv x10, x3, x14, mi
+5f3603d5|	gnu	clrex #0x6
+a017c05a|	gnu	cls w0, w29
+2616c0da|	gnu	cls x6, x17
+9411c05a|	gnu	clz w20, w12
+c611c0da|	gnu	clz x6, x14
+9fc3322b|	gnu	cmn w28, w18, sxtw
+3f9638ab|	gnu	cmn x17, w24, sxtb #5
+3f681db1|	gnu	cmn x1, #0x75a
+bfd15bab|	gnu	cmn x13, x27, lsr #52
+ff723b6b|	gnu	cmp w23, w27, uxtx #4
+1f5234eb|	gnu	cmp x16, w20, uxtw #4
+9fb22a71|	gnu	cmp w20, #0xaac
+df2478f1|	gnu	cmp x6, #0xe09, lsl #12
+bf07026b|	gnu	cmp w29, w2, lsl #1
+bfc514eb|	gnu	cmp x13, x20, lsl #49
+d494975a|	gnu	csneg w20, w6, w23, ls
+763591da|	gnu	csneg x22, x11, x17, cc
+b440c91a|	gnu	crc32b w20, w5, w9
+5745cd1a|	gnu	crc32h w23, w10, w13
+684ad01a|	gnu	crc32w w8, w19, w16
+884fd59a|	gnu	crc32x w8, w28, x21
+ea50c61a|	gnu	crc32cb w10, w7, w6
+1357cf1a|	gnu	crc32ch w19, w24, w15
+9859c21a|	gnu	crc32cw w24, w12, w2
+6e5fde9a|	gnu	crc32cx w14, w27, x30
+9340941a|	gnu	csel w19, w4, w20, mi
+dd42839a|	gnu	csel x29, x22, x3, mi
+fe779f1a|	gnu	cset w30, vs
+f1279f9a|	gnu	cset x17, cc
+eb839f5a|	gnu	csetm w11, ls
+e3139fda|	gnu	csetm x3, eq
+a986841a|	gnu	csinc w9, w21, w4, hi
+19b78b9a|	gnu	csinc x25, x24, x11, lt
+4643835a|	gnu	csinv w6, w26, w3, mi
+5ee38cda|	gnu	csinv x30, x26, x12, al
+d166945a|	gnu	csneg w17, w22, w20, vs
+55f793da|	gnu	csneg x21, x26, x19, al
+0158add4|	gnu	dcps1 #0x6ac0
+82ceb2d4|	gnu	dcps2 #0x9674
+a31eb3d4|	gnu	dcps3 #0x98f5
+bf3203d5|	gnu	dmb oshst
+e003bfd6|	gnu	drps
+9f3403d5|	gnu	dsb #0x04
+2e2faeca|	gnu	eon x14, x25, x14, asr #11
+de6b0152|	gnu	eor w30, w30, #0x83ffffff
+4a7714d2|	gnu	eor x10, x26, #0xfffff3fffffff3ff
+2cea0dca|	gnu	eor x12, x17, x13, lsl #58
+e0039fd6|	gnu	eret
+834cce93|	gnu	extr x3, x4, x14, #19
+5f2003d5|	gnu	wfe
+bf2e03d5|	gnu	hint #0x75
+e0f055d4|	gnu	hlt #0xaf87
+df3403d5|	gnu	isb #0x4
+22fcdf88|	gnu	ldar w2, [x1]
+78fedfc8|	gnu	ldar x24, [x19]
+cffcdf08|	gnu	ldarb w15, [x6]
+34fedf48|	gnu	ldarh w20, [x17]
+17bb7f88|	gnu	ldaxp w23, w14, [x24]
+6ffe7fc8|	gnu	ldaxp x15, xzr, [x19]
+acfe5f88|	gnu	ldaxr w12, [x21]
+cafe5fc8|	gnu	ldaxr x10, [x22]
+ddfd5f08|	gnu	ldaxrb w29, [x14]
+0efd5f48|	gnu	ldaxrh w14, [x8]
+66445128|	gnu	ldnp w6, w17, [x3,#136]
+3fa77fa8|	gnu	ldnp xzr, x9, [x25,#-8]
+1e04eb28|	gnu	ldp w30, w1, [x0],#-168
+0da6c0a8|	gnu	ldp x13, x9, [x16],#8
+7d00d429|	gnu	ldp w29, w0, [x3,#160]!
+d26ae1a9|	gnu	ldp x18, x26, [x22,#-496]!
+d0ca6829|	gnu	ldp w16, w18, [x22,#-188]
+a5e34fa9|	gnu	ldp x5, x24, [x29,#248]
+3e44d168|	gnu	ldpsw x30, x17, [x1],#136
+5f08e169|	gnu	ldpsw xzr, x2, [x2,#-248]!
+430d6769|	gnu	ldpsw x3, x3, [x10,#-200]
+2c555bb8|	gnu	ldr w12, [x9],#-75
+83c557f8|	gnu	ldr x3, [x12],#-132
+f36e47b8|	gnu	ldr w19, [x23,#118]!
+6b1f48f8|	gnu	ldr x11, [x27,#129]!
+f5d64ab9|	gnu	ldr w21, [x23,#2772]
+872d7cf9|	gnu	ldr x7, [x12,#30808]
+f23e8c18|	gnu	ldr w18, .+0xfffffffffff187dc
+a7e72a58|	gnu	ldr x7, .+0x55cf4
+82a75438|	gnu	ldrb w2, [x28],#-182
+a7fd5738|	gnu	ldrb w7, [x13,#-129]!
+c83d4239|	gnu	ldrb w8, [x14,#143]
+58c96438|	gnu	ldrb w24, [x10,w4,sxtw]
+8e687e38|	gnu	ldrb w14, [x4,x30]
+70575378|	gnu	ldrh w16, [x27],#-203
+015f5078|	gnu	ldrh w1, [x24,#-251]!
+7add5c79|	gnu	ldrh w26, [x11,#3694]
+2fcb7778|	gnu	ldrh w15, [x25,w23,sxtw]
+c474c338|	gnu	ldrsb w4, [x6],#55
+28869638|	gnu	ldrsb x8, [x17],#-152
+fe3fd438|	gnu	ldrsb w30, [sp,#-189]!
+da0f9938|	gnu	ldrsb x26, [x30,#-112]!
+5b3ac739|	gnu	ldrsb w27, [x18,#462]
+2c579e39|	gnu	ldrsb x12, [x25,#1941]
+54faf838|	gnu	ldrsb w20, [x18,x24,sxtx #0]
+fb68f238|	gnu	ldrsb w27, [x7,x18]
+f26aad38|	gnu	ldrsb x18, [x23,x13]
+17e4c978|	gnu	ldrsh w23, [x0],#158
+a2759f78|	gnu	ldrsh x2, [x13],#-9
+9c6ec478|	gnu	ldrsh w28, [x20,#70]!
+fd6f8278|	gnu	ldrsh x29, [sp,#38]!
+a82bc279|	gnu	ldrsh w8, [x29,#276]
+9d89b979|	gnu	ldrsh x29, [x12,#7364]
+962685b8|	gnu	ldrsw x22, [x20],#82
+76ae8bb8|	gnu	ldrsw x22, [x19,#186]!
+fc2193b9|	gnu	ldrsw x28, [x15,#4896]
+7561fa98|	gnu	ldrsw x21, .+0xffffffffffff4c2c
+e34842b8|	gnu	ldtr w3, [x7,#36]
+4ff84df8|	gnu	ldtr x15, [x2,#223]
+d9e84f38|	gnu	ldtrb w25, [x6,#254]
+397b5378|	gnu	ldtrh w25, [x25,#-201]
+c4c9d138|	gnu	ldtrsb w4, [x14,#-228]
+02789638|	gnu	ldtrsb x2, [x0,#-153]
+a988cb78|	gnu	ldtrsh w9, [x5,#184]
+03888978|	gnu	ldtrsh x3, [x0,#152]
+ccb99fb8|	gnu	ldtrsw x12, [x14,#-5]
+efb154b8|	gnu	ldur w15, [x15,#-181]
+fc2051f8|	gnu	ldur x28, [x7,#-238]
+86d04438|	gnu	ldurb w6, [x4,#77]
+73405d78|	gnu	ldurh w19, [x3,#-44]
+7a81d538|	gnu	ldursb w26, [x11,#-168]
+b0b28038|	gnu	ldursb x16, [x21,#11]
+b4a1d278|	gnu	ldursh w20, [x13,#-214]
+3ed18078|	gnu	ldursh x30, [x9,#13]
+09628eb8|	gnu	ldursw x9, [x16,#230]
+c07e7f88|	gnu	ldxp w0, wzr, [x22]
+3e167fc8|	gnu	ldxp x30, x5, [x17]
+727c5f88|	gnu	ldxr w18, [x3]
+487c5fc8|	gnu	ldxr x8, [x2]
+867d5f08|	gnu	ldxrb w6, [x12]
+747f5f48|	gnu	ldxrh w20, [x27]
+d920d71a|	gnu	lsl w25, w6, w23
+b920c59a|	gnu	lsl x25, x5, x5
+4da947d3|	gnu	ubfx x13, x10, #7, #36
+be23ca1a|	gnu	lsl w30, w29, w10
+cc20d19a|	gnu	lsl x12, x6, x17
+ae26c31a|	gnu	lsr w14, w21, w3
+fc27cb9a|	gnu	lsr x28, xzr, x11
+2b7e1053|	gnu	lsr w11, w17, #16
+cefe75d3|	gnu	lsr x14, x22, #53
+3b25d01a|	gnu	lsr w27, w9, w16
+e826d79a|	gnu	lsr x8, x23, x23
+5504031b|	gnu	madd w21, w2, w3, w1
+9e5c109b|	gnu	madd x30, x4, x16, x23
+00fe1f1b|	gnu	mneg w0, w16, wzr
+6efe179b|	gnu	mneg x14, x19, x23
+31020011|	gnu	add w17, w17, #0x0
+21000091|	gnu	add x1, x1, #0x0
+39f1bf12|	gnu	mov w25, #0x76ffff
+53b3e992|	gnu	mov x19, #0xb265ffffffffffff
+c0fd9552|	gnu	mov w0, #0xafee
+f16b97d2|	gnu	mov x17, #0xbb5f
+e8972232|	gnu	mov w8, #0xc00fc00f
+e27323b2|	gnu	mov x2, #0xe3ffffffe3ffffff
+e9030e2a|	gnu	mov w9, w14
+fb0310aa|	gnu	mov x27, x16
+d0e48472|	gnu	movk w16, #0x2726
+432dbcf2|	gnu	movk x3, #0xe16a, lsl #16
+4b679612|	gnu	mov w11, #0xffff4cc5
+9121e492|	gnu	mov x17, #0xdef3ffffffffffff
+00be90d2|	gnu	mov x0, #0x85f0
+91d730d5|	gnu	mrs x17, s2_0_c13_c7_4
+cf301fd5|	gnu	msr s3_7_c3_c0_6, x15
+daea181b|	gnu	msub w26, w22, w24, w26
+e1a7109b|	gnu	msub x1, xzr, x16, x9
+477f0d1b|	gnu	mul w7, w26, w13
+a17d1c9b|	gnu	mul x1, x13, x28
+fc9b79aa|	gnu	mvn x28, x25, lsr #38
+f71b904b|	gnu	neg w23, w16, asr #6
+e3df4acb|	gnu	neg x3, x10, lsr #55
+f0334e6b|	gnu	negs w16, w14, lsr #12
+e6031f5a|	gnu	ngc w6, wzr
+f40302da|	gnu	ngc x20, x2
+ee03137a|	gnu	ngcs w14, w19
+ee0303fa|	gnu	ngcs x14, x3
+1f2003d5|	gnu	nop
+ab14e92a|	gnu	orn w11, w5, w9, ror #5
+185c3faa|	gnu	orn x24, x0, xzr, lsl #23
+a8850c32|	gnu	orr w8, w13, #0x300030
+cad023b2|	gnu	orr x10, x6, #0xe3e3e3e3e3e3e3e3
+5487ccaa|	gnu	orr x20, x26, x12, ror #33
+293783f9|	gnu	prfm plil1strm, [x25,#1640]
+501010d8|	gnu	prfm pstl1keep, .+0x20208
+bc7389f8|	gnu	prfum #0x1c, [x29,#151]
+9203c05a|	gnu	rbit w18, w28
+0501c0da|	gnu	rbit x5, x8
+40005fd6|	gnu	ret x2
+940ac05a|	gnu	rev w20, w20
+ca0fc0da|	gnu	rev x10, x30
+7807c05a|	gnu	rev16 w24, w27
+fb06c0da|	gnu	rev16 x27, x23
+dc0ac0da|	gnu	rev32 x28, x22
+970dc0da|	gnu	rev x23, x12
+42408813|	gnu	extr w2, w2, w8, #16
+5a96db93|	gnu	extr x26, x18, x27, #37
+782cc41a|	gnu	ror w24, w3, w4
+8c2ec69a|	gnu	ror x12, x20, x6
+372ec61a|	gnu	ror w23, w17, w6
+b72ddc9a|	gnu	ror x23, x13, x28
+e501185a|	gnu	sbc w5, w15, w24
+ac0011da|	gnu	sbc x12, x5, x17
+7a03067a|	gnu	sbcs w26, w27, w6
+310008fa|	gnu	sbcs x17, x1, x8
+65837f93|	gnu	sbfiz x5, x27, #1, #33
+5c1b4793|	gnu	sbfiz x28, x26, #57, #7
+a71f5b93|	gnu	sbfiz x7, x29, #37, #8
+640ede1a|	gnu	sdiv w4, w19, w30
+2a0dd99a|	gnu	sdiv x10, x9, x25
+9f2003d5|	gnu	sev
+bf2003d5|	gnu	sevl
+045c389b|	gnu	smaddl x4, w0, w24, x23
+6efe3e9b|	gnu	smnegl x14, w19, w30
+ebac239b|	gnu	smsubl x11, w7, w3, x11
+947f459b|	gnu	smulh x20, x28, x5
+d67e3e9b|	gnu	smull x22, w22, w30
+6dff9f88|	gnu	stlr w13, [x27]
+1ffd9fc8|	gnu	stlr xzr, [x8]
+a8fe9f08|	gnu	stlrb w8, [x21]
+abfd9f48|	gnu	stlrh w11, [x13]
+2ec02888|	gnu	stlxp w8, w14, w16, [x1]
+11993ec8|	gnu	stlxp w30, x17, x6, [x8]
+bbfe0f88|	gnu	stlxr w15, w27, [x21]
+e9fc09c8|	gnu	stlxr w9, x9, [x7]
+c6fe0708|	gnu	stlxrb w7, w6, [x22]
+c6fe0c48|	gnu	stlxrh w12, w6, [x22]
+b3283028|	gnu	stnp w19, w10, [x5,#-128]
+252e26a8|	gnu	stnp x5, x11, [x17,#-416]
+9fb18c28|	gnu	stp wzr, w12, [x12],#100
+9ce5aba8|	gnu	stp x28, x25, [x12],#-328
+e5d08229|	gnu	stp w5, w20, [x7,#20]!
+d6e79ea9|	gnu	stp x22, x25, [x30,#488]!
+9eef2029|	gnu	stp w30, w27, [x28,#-252]
+57b314a9|	gnu	stp x23, x12, [x26,#328]
+eda503b8|	gnu	str w13, [x15],#58
+62241df8|	gnu	str x2, [x3],#-46
+d2bd18b8|	gnu	str w18, [x14,#-117]!
+542d12f8|	gnu	str x20, [x10,#-222]!
+e92c3bb9|	gnu	str w9, [x7,#15148]
+de4804f9|	gnu	str x30, [x6,#2192]
+cce40b38|	gnu	strb w12, [x6],#190
+eafd1238|	gnu	strb w10, [x15,#-209]!
+7fcb0639|	gnu	strb wzr, [x27,#434]
+03f82738|	gnu	strb w3, [x0,x7,sxtx #0]
+5c6a3e38|	gnu	strb w28, [x18,x30]
+a8551978|	gnu	strh w8, [x13],#-107
+9e6c0c78|	gnu	strh w30, [x4,#198]!
+c83d0e79|	gnu	strh w8, [x14,#1822]
+502a1db8|	gnu	sttr w16, [x18,#-46]
+ae180af8|	gnu	sttr x14, [x5,#161]
+ea1a0138|	gnu	sttrb w10, [x23,#17]
+416b0278|	gnu	sttrh w1, [x26,#38]
+659107b8|	gnu	stur w5, [x11,#121]
+6b611ff8|	gnu	stur x11, [x11,#-10]
+99a01c38|	gnu	sturb w25, [x4,#-54]
+99421e78|	gnu	sturh w25, [x20,#-28]
+3e2a2688|	gnu	stxp w6, w30, w10, [x17]
+2f6a2cc8|	gnu	stxp w12, x15, x26, [x17]
+7d7f1b88|	gnu	stxr w27, w29, [x27]
+6e7e1bc8|	gnu	stxr w27, x14, [x19]
+ec7c0208|	gnu	stxrb w2, w12, [x7]
+ee7f0648|	gnu	stxrh w6, w14, [sp]
+2f8d204b|	gnu	sub w15, w9, w0, sxtb #3
+1fbe3acb|	gnu	sub sp, x16, w26, sxth #7
+5af778d1|	gnu	sub x26, x26, #0xe3d, lsl #12
+6729034b|	gnu	sub w7, w11, w3, lsl #10
+ae683f6b|	gnu	subs w14, w5, wzr, uxtx #2
+2f993deb|	gnu	subs x15, x9, w29, sxtb #6
+db0d5f71|	gnu	subs w27, w14, #0x7c3, lsl #12
+3aec1ff1|	gnu	subs x26, x1, #0x7fb
+1f24016b|	gnu	cmp w0, w1, lsl #9
+a1ae1bd4|	gnu	svc #0xdd75
+a61e0013|	gnu	sxtb w6, w21
+441c4093|	gnu	sxtb x4, w2
+0c3c0013|	gnu	sxth w12, w0
+b33f4093|	gnu	sxth x19, w29
+407f4093|	gnu	sxtw x0, w26
+455929d5|	gnu	sysl x5, #1, C5, C9, #2
+d1005b37|	gnu	tbnz w17, #11, .+0x6018
+798eaeb6|	gnu	tbz x25, #53, .+0xffffffffffffd1cc
+bf8c1f72|	gnu	tst w5, #0x1e001e
+ff10836a|	gnu	tst w7, w3, asr #4
+dfc5daea|	gnu	tst x14, x26, ror #49
+aa6e43d3|	gnu	ubfx x10, x21, #3, #25
+46181a53|	gnu	ubfiz w6, w2, #6, #7
+43294bd3|	gnu	lsl x3, x10, #53
+77787dd3|	gnu	ubfiz x23, x3, #3, #31
+1a0bd61a|	gnu	udiv w26, w24, w22
+9308c19a|	gnu	udiv x19, x4, x1
+755aa19b|	gnu	umaddl x21, w19, w1, x22
+1ffdbe9b|	gnu	umnegl xzr, w8, w30
+cbaaba9b|	gnu	umsubl x11, w22, w26, x10
+0c7fdb9b|	gnu	umulh x12, x24, x27
+cc7da79b|	gnu	umull x12, w14, w7
+3d1c0053|	gnu	uxtb w29, w1
+0e3f0053|	gnu	uxth w14, w24
+5f2003d5|	gnu	wfe
+7f2003d5|	gnu	wfi
+3f2003d5|	gnu	yield
+71b9604e|	gnu	abs v17.8h, v11.8h
+5186f65e|	gnu	add d17, d18, d22
+4986f34e|	gnu	add v9.2d, v18.2d, v19.2d
+1243720e|	gnu	addhn v18.4h, v24.4s, v18.4s
+0640354e|	gnu	addhn2 v6.16b, v0.8h, v21.8h
+d9bdfa4e|	gnu	addp v25.2d, v14.2d, v26.2d
+4c59284e|	gnu	aesd v12.16b, v10.16b
+8c48284e|	gnu	aese v12.16b, v4.16b
+f47a284e|	gnu	aesimc v20.16b, v23.16b
+c56b284e|	gnu	aesmc v5.16b, v30.16b
+bf1c3b0e|	gnu	and v31.8b, v5.8b, v27.8b
+6444026f|	gnu	mvni v4.4s, #0x43, lsl #16
+1357032f|	gnu	bic v19.2s, #0x78, lsl #16
+561d6a0e|	gnu	bic v22.8b, v10.8b, v10.8b
+cd1ff06e|	gnu	bif v13.16b, v30.16b, v16.16b
+f31ebd6e|	gnu	bit v19.16b, v23.16b, v29.16b
+6f1d6c2e|	gnu	bsl v15.8b, v11.8b, v12.8b
+1e48600e|	gnu	cls v30.4h, v0.4h
+6948202e|	gnu	clz v9.8b, v3.8b
+968efd7e|	gnu	cmeq d22, d20, d29
+e58f6d6e|	gnu	cmeq v5.8h, v31.8h, v13.8h
+8f98600e|	gnu	cmeq v15.4h, v4.4h, #0
+4f3db84e|	gnu	cmge v15.4s, v10.4s, v24.4s
+2788a02e|	gnu	cmge v7.2s, v1.2s, #0
+bf35714e|	gnu	cmgt v31.8h, v13.8h, v17.8h
+4a89604e|	gnu	cmgt v10.8h, v10.8h, #0
+9635252e|	gnu	cmhi v22.8b, v12.8b, v5.8b
+d83eff6e|	gnu	cmhs v24.2d, v22.2d, v31.2d
+cb99206e|	gnu	cmle v11.16b, v14.16b, #0
+29a9604e|	gnu	cmlt v9.8h, v9.8h, #0
+d18eea5e|	gnu	cmtst d17, d22, d10
+d18ea94e|	gnu	cmtst v17.4s, v22.4s, v9.4s
+4a04075e|	gnu	mov b10, v2.b[3]
+0504040e|	gnu	dup v5.2s, v0.s[0]
+b20e1f4e|	gnu	dup v18.16b, w21
+2a1f3e6e|	gnu	eor v10.16b, v25.16b, v30.16b
+0bd5aa7e|	gnu	fabd s11, s8, s10
+12d7b96e|	gnu	fabd v18.4s, v24.4s, v25.4s
+a1f9a04e|	gnu	fabs v1.4s, v13.4s
+1ac3201e|	gnu	fabs s26, s24
+d8c3601e|	gnu	fabs d24, d30
+95ee267e|	gnu	facge s21, s20, s6
+2bee262e|	gnu	facge v11.2s, v17.2s, v6.2s
+1aedec7e|	gnu	facgt d26, d8, d12
+74effa6e|	gnu	facgt v20.2d, v27.2d, v26.2d
+7ed4260e|	gnu	fadd v30.2s, v3.2s, v6.2s
+4528251e|	gnu	fadd s5, s2, s5
+262b661e|	gnu	fadd d6, d25, d6
+84d8707e|	gnu	faddp d4, v4.2d
+71d4276e|	gnu	faddp v17.4s, v3.4s, v7.4s
+a5f43f1e|	gnu	fccmp s5, s31, #0x5, al
+20e5601e|	gnu	fccmp d9, d0, #0x0, al
+52d4331e|	gnu	fccmpe s2, s19, #0x2, le
+1e66761e|	gnu	fccmpe d16, d22, #0xe, vs
+d7e6695e|	gnu	fcmeq d23, d22, d9
+e7d9a05e|	gnu	fcmeq s7, s15, #0
+dadaa04e|	gnu	fcmeq v26.4s, v22.4s, #0
+28e5737e|	gnu	fcmge d8, d9, d19
+a2e73a6e|	gnu	fcmge v2.4s, v29.4s, v26.4s
+4fcba07e|	gnu	fcmge s15, s26, #0
+43c8a02e|	gnu	fcmge v3.2s, v2.2s, #0
+ffe5a67e|	gnu	fcmgt s31, s15, s6
+7ee7bd2e|	gnu	fcmgt v30.2s, v27.2s, v29.2s
+5bc8e05e|	gnu	fcmgt d27, d2, #0
+3dc9a04e|	gnu	fcmgt v29.4s, v9.4s, #0
+38daa07e|	gnu	fcmle s24, s17, #0
+8fdaa02e|	gnu	fcmle v15.2s, v20.2s, #0
+93e8e05e|	gnu	fcmlt d19, d4, #0
+9fe9a04e|	gnu	fcmlt v31.4s, v12.4s, #0
+a023201e|	gnu	fcmp s29, s0
+c822231e|	gnu	fcmp s22, #0
+a022651e|	gnu	fcmp d21, d5
+a8227d1e|	gnu	fcmp d21, #0
+70203e1e|	gnu	fcmpe s3, s30
+38232b1e|	gnu	fcmpe s25, #0
+70206c1e|	gnu	fcmpe d3, d12
+b823731e|	gnu	fcmpe d29, #0
+3e6f331e|	gnu	fcsel s30, s25, s19, vs
+a64f6d1e|	gnu	fcsel d6, d29, d13, mi
+0d41e21e|	gnu	fcvt s13, h8
+cbc0e21e|	gnu	fcvt d11, h6
+18c0231e|	gnu	fcvt h24, s0
+a7c0221e|	gnu	fcvt d7, s5
+e7c3631e|	gnu	fcvt h7, d31
+9f43621e|	gnu	fcvt s31, d28
+a0c8215e|	gnu	fcvtas s0, s5
+4dc8210e|	gnu	fcvtas v13.2s, v2.2s
+0300241e|	gnu	fcvtas w3, s0
+fd03249e|	gnu	fcvtas x29, s31
+ef01641e|	gnu	fcvtas w15, d15
+4c01649e|	gnu	fcvtas x12, d10
+9ac8617e|	gnu	fcvtau d26, d4
+b802251e|	gnu	fcvtau w24, s21
+2a03259e|	gnu	fcvtau x10, s25
+ea00651e|	gnu	fcvtau w10, d7
+0102659e|	gnu	fcvtau x1, d16
+0d7a610e|	gnu	fcvtl v13.2d, v16.2s
+ed79214e|	gnu	fcvtl2 v13.4s, v15.8h
+43bb615e|	gnu	fcvtms d3, d26
+c000301e|	gnu	fcvtms w0, s6
+9202309e|	gnu	fcvtms x18, s20
+0800701e|	gnu	fcvtms w8, d0
+6603709e|	gnu	fcvtms x6, d27
+f0b9217e|	gnu	fcvtmu s16, s15
+3bba212e|	gnu	fcvtmu v27.2s, v17.2s
+5900311e|	gnu	fcvtmu w25, s2
+9a03319e|	gnu	fcvtmu x26, s28
+fa01711e|	gnu	fcvtmu w26, d15
+6f01719e|	gnu	fcvtmu x15, d11
+1968210e|	gnu	fcvtn v25.4h, v0.4s
+3d69214e|	gnu	fcvtn2 v29.8h, v9.4s
+87aa615e|	gnu	fcvtns d7, d20
+e301201e|	gnu	fcvtns w3, s15
+6002209e|	gnu	fcvtns x0, s19
+1600601e|	gnu	fcvtns w22, d0
+8503609e|	gnu	fcvtns x5, d28
+f5ab617e|	gnu	fcvtnu d21, d31
+2b02211e|	gnu	fcvtnu w11, s17
+f902219e|	gnu	fcvtnu x25, s23
+0702611e|	gnu	fcvtnu w7, d16
+9d03619e|	gnu	fcvtnu x29, d28
+dcaba15e|	gnu	fcvtps s28, s30
+b4a8a10e|	gnu	fcvtps v20.2s, v5.2s
+5302281e|	gnu	fcvtps w19, s18
+e003289e|	gnu	fcvtps x0, s31
+9501681e|	gnu	fcvtps w21, d12
+6703689e|	gnu	fcvtps x7, d27
+68a8a17e|	gnu	fcvtpu s8, s3
+dcaba12e|	gnu	fcvtpu v28.2s, v30.2s
+9d03291e|	gnu	fcvtpu w29, s28
+5f01299e|	gnu	fcvtpu xzr, s10
+e101691e|	gnu	fcvtpu w1, d15
+3f00699e|	gnu	fcvtpu xzr, d1
+ee6b612e|	gnu	fcvtxn v14.2s, v31.2d
+b1fd215f|	gnu	fcvtzs s17, s13, #31
+bafd2c0f|	gnu	fcvtzs v26.2s, v13.2s, #20
+47b8e15e|	gnu	fcvtzs d7, d2
+dcbbe14e|	gnu	fcvtzs v28.2d, v30.2d
+56f8181e|	gnu	fcvtzs w22, s2, #2
+9265189e|	gnu	fcvtzs x18, s12, #39
+d3ad581e|	gnu	fcvtzs w19, d14, #21
+3d9b589e|	gnu	fcvtzs x29, d25, #26
+1a00381e|	gnu	fcvtzs w26, s0
+d302389e|	gnu	fcvtzs x19, s22
+5303781e|	gnu	fcvtzs w19, d26
+8f01789e|	gnu	fcvtzs x15, d12
+57fe537f|	gnu	fcvtzu d23, d18, #45
+beff796f|	gnu	fcvtzu v30.2d, v29.2d, #7
+08b9e17e|	gnu	fcvtzu d8, d8
+cdbbe16e|	gnu	fcvtzu v13.2d, v30.2d
+2126199e|	gnu	fcvtzu x1, s17, #55
+70a9591e|	gnu	fcvtzu w16, d11, #22
+8c25599e|	gnu	fcvtzu x12, d12, #55
+1201391e|	gnu	fcvtzu w18, s8
+0800399e|	gnu	fcvtzu x8, s0
+da00791e|	gnu	fcvtzu w26, d6
+2903799e|	gnu	fcvtzu x9, d25
+56fd3f2e|	gnu	fdiv v22.2s, v10.2s, v31.2s
+1f182e1e|	gnu	fdiv s31, s0, s14
+ce1b741e|	gnu	fdiv d14, d30, d20
+0d61021f|	gnu	fmadd s13, s8, s2, s24
+03205e1f|	gnu	fmadd d3, d0, d30, d8
+72f6654e|	gnu	fmax v18.2d, v19.2d, v5.2d
+1849281e|	gnu	fmax s24, s8, s8
+8e4a6e1e|	gnu	fmax d14, d20, d14
+54c7304e|	gnu	fmaxnm v20.4s, v26.4s, v16.4s
+91683a1e|	gnu	fmaxnm s17, s4, s26
+f56a721e|	gnu	fmaxnm d21, d23, d18
+c8cb307e|	gnu	fmaxnmp s8, v30.2s
+06c9306e|	gnu	fmaxnmv s6, v8.4s
+b6fb707e|	gnu	fmaxp d22, v29.2d
+1759341e|	gnu	fmin s23, s8, s20
+675b721e|	gnu	fmin d7, d27, d18
+69792d1e|	gnu	fminnm s9, s11, s13
+ab786b1e|	gnu	fminnm d11, d5, d11
+0fcab07e|	gnu	fminnmp s15, v16.2s
+d2c6b26e|	gnu	fminnmp v18.4s, v22.4s, v18.4s
+22fab07e|	gnu	fminp s2, v17.2s
+f5f5f56e|	gnu	fminp v21.2d, v15.2d, v21.2d
+bc13c95f|	gnu	fmla d28, d29, v9.d[0]
+5d51a85f|	gnu	fmls s29, s10, v8.s[1]
+d3ccb94e|	gnu	fmls v19.4s, v6.4s, v25.4s
+5bf4014f|	gnu	fmov v27.4s, #9.000000000000000000e+00
+5bf5026f|	gnu	fmov v27.2d, #2.031250000000000000e-01
+6541201e|	gnu	fmov s5, s11
+b742601e|	gnu	fmov d23, d21
+6002271e|	gnu	fmov s0, w19
+5301261e|	gnu	fmov w19, s10
+c103679e|	gnu	fmov d1, x30
+3301af9e|	gnu	fmov v19.d[1], x9
+bd00669e|	gnu	fmov x29, d5
+ee02ae9e|	gnu	fmov x14, v23.d[1]
+0ff0251e|	gnu	fmov s15, #1.550000000000000000e+01
+16506a1e|	gnu	fmov d22, #2.812500000000000000e-01
+d1c20e1f|	gnu	fmsub s17, s22, s14, s16
+fdae491f|	gnu	fmsub d29, d23, d9, d11
+a4989d4f|	gnu	fmul v4.4s, v5.4s, v29.s[2]
+efde706e|	gnu	fmul v15.2d, v23.2d, v16.2d
+190a291e|	gnu	fmul s25, s16, s9
+430a671e|	gnu	fmul d3, d18, d7
+21919e7f|	gnu	fmulx s1, s9, v30.s[0]
+5298c76f|	gnu	fmulx v18.2d, v2.2d, v7.d[1]
+1ddf3c5e|	gnu	fmulx s29, s24, s28
+a2fba06e|	gnu	fneg v2.4s, v29.4s
+7a40211e|	gnu	fneg s26, s3
+f843611e|	gnu	fneg d24, d31
+326b381f|	gnu	fnmadd s18, s25, s24, s26
+4b636a1f|	gnu	fnmadd d11, d26, d10, d24
+48fa201f|	gnu	fnmsub s8, s18, s0, s30
+04d87f1f|	gnu	fnmsub d4, d0, d31, d22
+0289371e|	gnu	fnmul s2, s8, s23
+0e8a691e|	gnu	fnmul d14, d16, d9
+05dba15e|	gnu	frecpe s5, s24
+42d9a14e|	gnu	frecpe v2.4s, v10.4s
+2eff655e|	gnu	frecps d14, d25, d5
+03fe774e|	gnu	frecps v3.2d, v16.2d, v23.2d
+b4fba15e|	gnu	frecpx s20, s29
+9d41261e|	gnu	frinta s29, s12
+ea42661e|	gnu	frinta d10, d23
+e399a16e|	gnu	frinti v3.4s, v15.4s
+6ec3271e|	gnu	frinti s14, s27
+ecc1671e|	gnu	frinti d12, d15
+4543251e|	gnu	frintm s5, s26
+f242651e|	gnu	frintm d18, d23
+898a214e|	gnu	frintn v9.4s, v20.4s
+1641241e|	gnu	frintn s22, s8
+5341641e|	gnu	frintn d19, d10
+248be14e|	gnu	frintp v4.2d, v25.2d
+35c2241e|	gnu	frintp s21, s17
+6fc3641e|	gnu	frintp d15, d27
+0940271e|	gnu	frintx s9, s0
+4643671e|	gnu	frintx d6, d26
+749aa14e|	gnu	frintz v20.4s, v19.4s
+8bc0251e|	gnu	frintz s11, s4
+7cc1651e|	gnu	frintz d28, d11
+dedbe17e|	gnu	frsqrte d30, d30
+04daa16e|	gnu	frsqrte v4.4s, v16.4s
+cdfce45e|	gnu	frsqrts d13, d6, d4
+d9fda04e|	gnu	frsqrts v25.4s, v14.4s, v0.4s
+c5c1211e|	gnu	fsqrt s5, s14
+67c1611e|	gnu	fsqrt d7, d11
+a4d6b14e|	gnu	fsub v4.4s, v21.4s, v17.4s
+6138351e|	gnu	fsub s1, s3, s21
+be3b6a1e|	gnu	fsub d30, d29, d10
+4d2f016e|	gnu	mov v13.b[0], v26.b[5]
+741e174e|	gnu	mov v20.b[11], w19
+e170404c|	gnu	ld1 {v1.16b}, [x7]
+7aa9404c|	gnu	ld1 {v26.4s, v27.4s}, [x11]
+4b6d400c|	gnu	ld1 {v11.1d-v13.1d}, [x10]
+582b400c|	gnu	ld1 {v24.2s-v27.2s}, [x26]
+8f7cdf4c|	gnu	ld1 {v15.2d}, [x4],#16
+0a76ce4c|	gnu	ld1 {v10.8h}, [x16], x14
+2aa6df0c|	gnu	ld1 {v10.4h, v11.4h}, [x17],#16
+35a7d70c|	gnu	ld1 {v21.4h, v22.4h}, [x25], x23
+ae6ddf4c|	gnu	ld1 {v14.2d-v16.2d}, [x13],#48
+b362d74c|	gnu	ld1 {v19.16b-v21.16b}, [x21], x23
+6d22df0c|	gnu	ld1 {v13.8b-v16.8b}, [x19],#32
+6722c90c|	gnu	ld1 {v7.8b-v10.8b}, [x19], x9
+c71f404d|	gnu	ld1 {v7.b}[15], [x30]
+f55a400d|	gnu	ld1 {v21.h}[3], [x23]
+f080400d|	gnu	ld1 {v16.s}[0], [x7]
+ed84404d|	gnu	ld1 {v13.d}[1], [x7]
+fd0bdf4d|	gnu	ld1 {v29.b}[10], [sp],#1
+c811dc0d|	gnu	ld1 {v8.b}[4], [x14], x28
+6548cb4d|	gnu	ld1 {v5.h}[5], [x3], x11
+9882df4d|	gnu	ld1 {v24.s}[2], [x20],#4
+f482c74d|	gnu	ld1 {v20.s}[2], [x23], x7
+0d87df0d|	gnu	ld1 {v13.d}[0], [x24],#8
+1b85db0d|	gnu	ld1 {v27.d}[0], [x8], x27
+58c3404d|	gnu	ld1r {v24.16b}, [x26]
+c0c6df4d|	gnu	ld1r {v0.8h}, [x22],#2
+a6cec90d|	gnu	ld1r {v6.1d}, [x21], x9
+e68a400c|	gnu	ld2 {v6.2s, v7.2s}, [x23]
+4007604d|	gnu	ld2 {v0.b, v1.b}[9], [x26]
+8c49604d|	gnu	ld2 {v12.h, v13.h}[5], [x12]
+4f92600d|	gnu	ld2 {v15.s, v16.s}[1], [x18]
+b186600d|	gnu	ld2 {v17.d, v18.d}[0], [x21]
+631aff0d|	gnu	ld2 {v3.b, v4.b}[6], [x19],#2
+330ceb4d|	gnu	ld2 {v19.b, v20.b}[11], [x1], x11
+454bff4d|	gnu	ld2 {v5.h, v6.h}[5], [x26],#4
+0792ff0d|	gnu	ld2 {v7.s, v8.s}[1], [x16],#8
+3b91fd0d|	gnu	ld2 {v27.s, v28.s}[1], [x9], x29
+b086ff4d|	gnu	ld2 {v16.d, v17.d}[1], [x21],#16
+da86e30d|	gnu	ld2 {v26.d, v27.d}[0], [x22], x3
+e7cf604d|	gnu	ld2r {v7.2d, v8.2d}, [sp]
+5ac8ff0d|	gnu	ld2r {v26.2s, v27.2s}, [x2],#8
+13c1f10d|	gnu	ld2r {v19.8b, v20.8b}, [x8], x17
+0947404c|	gnu	ld3 {v9.8h-v11.8h}, [x24]
+8043df0c|	gnu	ld3 {v0.8b-v2.8b}, [x28],#24
+6344d50c|	gnu	ld3 {v3.4h-v5.4h}, [x3], x21
+663d400d|	gnu	ld3 {v6.b-v8.b}[7], [x11]
+5b6b400d|	gnu	ld3 {v27.h-v29.h}[1], [x26]
+02a0404d|	gnu	ld3 {v2.s-v4.s}[2], [x0]
+e1a5404d|	gnu	ld3 {v1.d-v3.d}[1], [x15]
+b53edf0d|	gnu	ld3 {v21.b-v23.b}[7], [x21],#3
+f625d10d|	gnu	ld3 {v22.b-v24.b}[1], [x15], x17
+3d7bda4d|	gnu	ld3 {v29.h-v31.h}[7], [x25], x26
+6ea0df0d|	gnu	ld3 {v14.s-v16.s}[0], [x3],#12
+d9a0c60d|	gnu	ld3 {v25.s-v27.s}[0], [x6], x6
+b6a7df0d|	gnu	ld3 {v22.d-v24.d}[0], [x29],#24
+dfa6d94d|	gnu	ld3 {v31.d, v0.d, v1.d}[1], [x22], x25
+7de9404d|	gnu	ld3r {v29.4s-v31.4s}, [x11]
+2fe6df4d|	gnu	ld3r {v15.8h-v17.8h}, [x17],#6
+cae7c84d|	gnu	ld3r {v10.8h-v12.8h}, [x30], x8
+9a0b400c|	gnu	ld4 {v26.2s-v29.2s}, [x28]
+4b03df0c|	gnu	ld4 {v11.8b-v14.8b}, [x26],#32
+8e0bcc4c|	gnu	ld4 {v14.4s-v17.4s}, [x28], x12
+182c604d|	gnu	ld4 {v24.b-v27.b}[11], [x0]
+feb2600d|	gnu	ld4 {v30.s, v31.s, v0.s, v1.s}[1], [x23]
+59a4604d|	gnu	ld4 {v25.d-v28.d}[1], [x2]
+9b25ff4d|	gnu	ld4 {v27.b-v30.b}[9], [x12],#4
+1f35e84d|	gnu	ld4 {v31.b, v0.b, v1.b, v2.b}[13], [x8], x8
+91b2ff4d|	gnu	ld4 {v17.s-v20.s}[3], [x20],#16
+88b3ed4d|	gnu	ld4 {v8.s-v11.s}[3], [x28], x13
+9aa5ff4d|	gnu	ld4 {v26.d-v29.d}[1], [x12],#32
+efa5e10d|	gnu	ld4 {v15.d-v18.d}[0], [x15], x1
+07ed604d|	gnu	ld4r {v7.2d-v10.2d}, [x8]
+0defff0d|	gnu	ld4r {v13.1d-v16.1d}, [x24],#32
+43e1f14d|	gnu	ld4r {v3.16b-v6.16b}, [x10], x17
+136e682c|	gnu	ldnp s19, s27, [x16,#-192]
+cc67676c|	gnu	ldnp d12, d25, [x30,#-400]
+e6dd4eac|	gnu	ldnp q6, q23, [x15,#464]
+b7e9c22c|	gnu	ldp s23, s26, [x13],#20
+92c3fe6c|	gnu	ldp d18, d16, [x28],#-24
+f281e6ac|	gnu	ldp q18, q0, [x15],#-816
+4f06cd2d|	gnu	ldp s15, s1, [x18,#104]!
+0f6fdc6d|	gnu	ldp d15, d27, [x24,#448]!
+170ccbad|	gnu	ldp q23, q3, [x0,#352]!
+71ea7a2d|	gnu	ldp s17, s26, [x19,#-44]
+c8816c6d|	gnu	ldp d8, d0, [x14,#-312]
+da6540ad|	gnu	ldp q26, q25, [x14]
+92064c3c|	gnu	ldr b18, [x20],#192
+94d4577c|	gnu	ldr h20, [x4],#-131
+39055fbc|	gnu	ldr s25, [x9],#-16
+989551fc|	gnu	ldr d24, [x12],#-231
+4764c23c|	gnu	ldr q7, [x2],#38
+c15e4e3c|	gnu	ldr b1, [x22,#229]!
+c8ce487c|	gnu	ldr h8, [x22,#140]!
+ca5d5bbc|	gnu	ldr s10, [x14,#-75]!
+34fd56fc|	gnu	ldr d20, [x9,#-145]!
+bd0dd53c|	gnu	ldr q29, [x13,#-176]!
+ab65443d|	gnu	ldr b11, [x13,#281]
+cb57537d|	gnu	ldr h11, [x30,#2474]
+f2606fbd|	gnu	ldr s18, [x7,#12128]
+088b67fd|	gnu	ldr d8, [x24,#20240]
+0173ce3d|	gnu	ldr q1, [x24,#14784]
+ba112c1c|	gnu	ldr s26, .+0x58234
+e489c25c|	gnu	ldr d4, .+0xfffffffffff8513c
+42458d9c|	gnu	ldr q2, .+0xfffffffffff1a8a8
+3cdb753c|	gnu	ldr b28, [x25,w21,sxtw #0]
+726b733c|	gnu	ldr b18, [x27,x19]
+395b627c|	gnu	ldr h25, [x25,w2,uxtw #1]
+9b486cbc|	gnu	ldr s27, [x4,w12,uxtw]
+1cda7efc|	gnu	ldr d28, [x16,w30,sxtw #3]
+365bf33c|	gnu	ldr q22, [x25,w19,uxtw #4]
+43a1413c|	gnu	ldur b3, [x10,#26]
+c7034f7c|	gnu	ldur h7, [x30,#240]
+ad8350bc|	gnu	ldur s13, [x29,#-248]
+07a350fc|	gnu	ldur d7, [x24,#-246]
+0212c63c|	gnu	ldur q2, [x16,#97]
+6f0a7a2f|	gnu	mla v15.4h, v19.4h, v10.h[7]
+fe95294e|	gnu	mla v30.16b, v15.16b, v9.16b
+f24a4f2f|	gnu	mls v18.4h, v23.4h, v15.h[4]
+26947e2e|	gnu	mls v6.4h, v1.4h, v30.4h
+6606115e|	gnu	mov b6, v19.b[8]
+0866116e|	gnu	mov v8.b[8], v16.b[12]
+6e1d0f4e|	gnu	mov v14.b[7], w11
+6d1fa10e|	gnu	orr v13.8b, v27.8b, v1.8b
+b93f1a0e|	gnu	umov w25, v29.h[6]
+74e7020f|	gnu	movi v20.8b, #0x5b
+0ff4040f|	gnu	fmov v15.2s, #-2.000000000000000000e+00
+4c47060f|	gnu	movi v12.2s, #0xda, lsl #16
+aa06064f|	gnu	movi v10.4s, #0xd5
+8de4042f|	gnu	movi d13, #0xff00000000ff0000
+b1e6046f|	gnu	movi v17.2d, #0xff0000ff00ff00ff
+609f214e|	gnu	mul v0.16b, v27.16b, v1.16b
+9f5a206e|	gnu	mvn v31.16b, v20.16b
+da65032f|	gnu	mvni v26.2s, #0x6e, lsl #24
+4d36036f|	gnu	bic v13.4s, #0x72, lsl #8
+4d66052f|	gnu	mvni v13.2s, #0xb2, lsl #24
+a4bbe06e|	gnu	neg v4.2d, v29.2d
+bf5a206e|	gnu	mvn v31.16b, v21.16b
+2b1fe24e|	gnu	orn v11.16b, v25.16b, v2.16b
+22e4024f|	gnu	movi v2.16b, #0x41
+3086050f|	gnu	movi v16.4h, #0xb1
+051db80e|	gnu	orr v5.8b, v8.8b, v24.8b
+48e2290e|	gnu	pmull v8.8h, v18.8b, v9.8b
+7341652e|	gnu	raddhn v19.4h, v11.4s, v5.4s
+1b417f6e|	gnu	raddhn2 v27.8h, v8.4s, v31.4s
+e158606e|	gnu	rbit v1.16b, v7.16b
+f418200e|	gnu	rev16 v20.8b, v7.8b
+228d2a0f|	gnu	rshrn v2.2s, v9.2d, #22
+a861aa2e|	gnu	rsubhn v8.2s, v13.2d, v10.2d
+7160786e|	gnu	rsubhn2 v17.8h, v3.4s, v24.4s
+cc7f314e|	gnu	saba v12.16b, v30.16b, v17.16b
+1350644e|	gnu	sabal2 v19.4s, v0.8h, v4.8h
+a1757d4e|	gnu	sabd v1.8h, v13.8h, v29.8h
+0971a00e|	gnu	sabdl v9.2d, v8.2s, v0.2s
+af70214e|	gnu	sabdl2 v15.8h, v5.16b, v1.16b
+626ba04e|	gnu	sadalp v2.2d, v27.4s
+1503374e|	gnu	saddl2 v21.8h, v24.16b, v23.16b
+592b204e|	gnu	saddlp v25.8h, v26.16b
+d813600e|	gnu	saddw v24.4s, v30.4s, v0.4h
+31e5210f|	gnu	scvtf v17.2s, v9.2s, #31
+aeda215e|	gnu	scvtf s14, s21
+f0e9021e|	gnu	scvtf s16, w15, #6
+42b4421e|	gnu	scvtf d2, w2, #19
+8b10029e|	gnu	scvtf s11, x4, #60
+59e6429e|	gnu	scvtf d25, x18, #7
+cf01221e|	gnu	scvtf s15, w14
+2d03621e|	gnu	scvtf d13, w25
+af00229e|	gnu	scvtf s15, x5
+bf00629e|	gnu	scvtf d31, x5
+2a02025e|	gnu	sha1c q10, s17, v2.4s
+8b0b285e|	gnu	sha1h s11, s28
+11201f5e|	gnu	sha1m q17, s0, v31.4s
+f110115e|	gnu	sha1p q17, s7, v17.4s
+b732115e|	gnu	sha1su0 v23.4s, v21.4s, v17.4s
+cf18285e|	gnu	sha1su1 v15.4s, v6.4s
+2e520f5e|	gnu	sha256h2 q14, q17, v15.4s
+77401a5e|	gnu	sha256h q23, q3, v26.4s
+b92a285e|	gnu	sha256su0 v25.4s, v21.4s
+7e63175e|	gnu	sha256su1 v30.4s, v27.4s, v23.4s
+d504ab0e|	gnu	shadd v21.2s, v6.2s, v11.2s
+5a54734f|	gnu	shl v26.2d, v2.2d, #51
+0638212e|	gnu	shll v6.8h, v0.8b, #8
+a238216e|	gnu	shll2 v2.8h, v5.16b, #8
+f5863e0f|	gnu	shrn v21.2s, v23.2d, #2
+f187234f|	gnu	shrn2 v17.4s, v31.2d, #29
+e124b04e|	gnu	shsub v1.4s, v7.4s, v16.4s
+3657252f|	gnu	sli v22.2s, v25.2s, #5
+c266aa4e|	gnu	smax v2.4s, v22.4s, v10.4s
+2c6ca74e|	gnu	smin v12.4s, v1.4s, v7.4s
+4aae390e|	gnu	sminp v10.8b, v18.8b, v25.8b
+1a82ba0e|	gnu	smlal v26.2d, v16.2s, v26.2s
+2381ad4e|	gnu	smlal2 v3.2d, v9.4s, v13.4s
+0da17a4e|	gnu	smlsl2 v13.4s, v8.8h, v26.8h
+4f2e0d4e|	gnu	smov x15, v18.b[6]
+e4a0980f|	gnu	smull v4.2d, v7.2s, v24.s[0]
+51c2220e|	gnu	smull v17.8h, v18.8b, v2.8b
+01c26d4e|	gnu	smull2 v1.4s, v16.8h, v13.8h
+f978205e|	gnu	sqabs b25, b7
+760cef5e|	gnu	sqadd d22, d3, d15
+390c224e|	gnu	sqadd v25.16b, v1.16b, v2.16b
+5439455f|	gnu	sqdmlal s20, h10, v5.h[4]
+8391765e|	gnu	sqdmlal s3, h12, h22
+c9907a4e|	gnu	sqdmlal2 v9.4s, v6.8h, v26.8h
+0b73445f|	gnu	sqdmlsl s11, h24, v4.h[0]
+8e728d0f|	gnu	sqdmlsl v14.2d, v20.2s, v13.s[0]
+fe787d4f|	gnu	sqdmlsl2 v30.4s, v7.8h, v13.h[7]
+bdb2b55e|	gnu	sqdmlsl d29, s21, s21
+d0c9be4f|	gnu	sqdmulh v16.4s, v14.4s, v30.s[3]
+89b77c5e|	gnu	sqdmulh h9, h28, h28
+c9bb515f|	gnu	sqdmull s9, h30, v1.h[5]
+5379e07e|	gnu	sqneg d19, d10
+4b7aa06e|	gnu	sqneg v11.4s, v18.4s
+1bd1750f|	gnu	sqrdmulh v27.4h, v8.4h, v5.h[3]
+f55e755e|	gnu	sqrshl h21, h23, h21
+ba5fbd4e|	gnu	sqrshl v26.4s, v29.4s, v29.4s
+ba9d1e0f|	gnu	sqrshrn v26.4h, v13.4s, #2
+3d9c284f|	gnu	sqrshrn2 v29.4s, v1.2d, #24
+8a8f2c6f|	gnu	sqrshrun2 v10.4s, v28.2d, #20
+eb760b5f|	gnu	sqshl b11, b23, #3
+4a77220f|	gnu	sqshl v10.2s, v26.2s, #2
+6c4cfb5e|	gnu	sqshl d12, d3, d27
+ad4eba4e|	gnu	sqshl v13.4s, v21.4s, v26.4s
+9364257f|	gnu	sqshlu s19, s4, #5
+b267392f|	gnu	sqshlu v18.2s, v29.2s, #25
+c085042f|	gnu	mvni v0.4h, #0x8e
+7584326f|	gnu	sqshrun2 v21.4s, v3.2d, #14
+3a2fe25e|	gnu	sqsub d26, d25, d2
+2c2ca34e|	gnu	sqsub v12.4s, v1.4s, v3.4s
+484ba15e|	gnu	sqxtn s8, d26
+824b210e|	gnu	sqxtn v2.8b, v28.8h
+5b48214e|	gnu	sqxtn2 v27.16b, v2.8h
+e228a16e|	gnu	sqxtun2 v2.4s, v7.2d
+1c44416f|	gnu	sri v28.2d, v0.2d, #63
+1e56eb5e|	gnu	srshl d30, d16, d11
+bb56fe4e|	gnu	srshl v27.2d, v21.2d, v30.2d
+c6262d0f|	gnu	srshr v6.2s, v22.2s, #19
+0c366c5f|	gnu	srsra d12, d16, #20
+13376e4f|	gnu	srsra v19.2d, v24.2d, #18
+7ba5040f|	gnu	movi v27.4h, #0x8b, lsl #8
+9c076f5f|	gnu	sshr d28, d28, #17
+2804434f|	gnu	sshr v8.2d, v1.2d, #61
+b717535f|	gnu	ssra d23, d29, #45
+c2160f0f|	gnu	ssra v2.8b, v22.8b, #1
+8a333a4e|	gnu	ssubw2 v10.8h, v28.8h, v26.16b
+3a70000c|	gnu	st1 {v26.8b}, [x1]
+1bab004c|	gnu	st1 {v27.4s, v28.4s}, [x24]
+8d69004c|	gnu	st1 {v13.4s-v15.4s}, [x12]
+9c26004c|	gnu	st1 {v28.8h-v31.8h}, [x20]
+c87a9f0c|	gnu	st1 {v8.2s}, [x22],#8
+5a7f800c|	gnu	st1 {v26.1d}, [x26], x0
+eea99f4c|	gnu	st1 {v14.4s, v15.4s}, [x15],#32
+11af9d4c|	gnu	st1 {v17.2d, v18.2d}, [x24], x29
+ec689f0c|	gnu	st1 {v12.2s-v14.2s}, [x7],#24
+8662900c|	gnu	st1 {v6.8b-v8.8b}, [x20], x16
+0b249f4c|	gnu	st1 {v11.8h-v14.8h}, [x0],#64
+6b2d8b4c|	gnu	st1 {v11.2d-v14.2d}, [x11], x11
+3212004d|	gnu	st1 {v18.b}[12], [x17]
+3392004d|	gnu	st1 {v19.s}[3], [x17]
+0284000d|	gnu	st1 {v2.d}[0], [x0]
+340f9f0d|	gnu	st1 {v20.b}[3], [x25],#1
+0d069a4d|	gnu	st1 {v13.b}[9], [x16], x26
+2e51950d|	gnu	st1 {v14.h}[2], [x9], x21
+3f839f0d|	gnu	st1 {v31.s}[0], [x25],#4
+1492844d|	gnu	st1 {v20.s}[3], [x16], x4
+dd869f4d|	gnu	st1 {v29.d}[1], [x22],#8
+2e869b4d|	gnu	st1 {v14.d}[1], [x17], x27
+1e87000c|	gnu	st2 {v30.4h, v31.4h}, [x24]
+07829f0c|	gnu	st2 {v7.8b, v8.8b}, [x16],#16
+d38a884c|	gnu	st2 {v19.4s, v20.4s}, [x22], x8
+541c204d|	gnu	st2 {v20.b, v21.b}[15], [x2]
+9180200d|	gnu	st2 {v17.s, v18.s}[0], [x4]
+2585204d|	gnu	st2 {v5.d, v6.d}[1], [x9]
+2f06bf4d|	gnu	st2 {v15.b, v16.b}[9], [x17],#2
+3b08b44d|	gnu	st2 {v27.b, v28.b}[10], [x1], x20
+805bbf0d|	gnu	st2 {v0.h, v1.h}[3], [x28],#4
+fb80bf0d|	gnu	st2 {v27.s, v28.s}[0], [x7],#8
+6290a80d|	gnu	st2 {v2.s, v3.s}[1], [x3], x8
+b587bf4d|	gnu	st2 {v21.d, v22.d}[1], [x29],#16
+2c84b64d|	gnu	st2 {v12.d, v13.d}[1], [x1], x22
+22469f0c|	gnu	st3 {v2.4h-v4.4h}, [x17],#24
+0e30004d|	gnu	st3 {v14.b-v16.b}[12], [x0]
+62a1004d|	gnu	st3 {v2.s-v4.s}[2], [x11]
+54a4000d|	gnu	st3 {v20.d-v22.d}[0], [x2]
+84259f4d|	gnu	st3 {v4.b-v6.b}[9], [x12],#3
+693c9d4d|	gnu	st3 {v9.b-v11.b}[15], [x3], x29
+5b709f0d|	gnu	st3 {v27.h-v29.h}[2], [x2],#6
+e47a960d|	gnu	st3 {v4.h-v6.h}[3], [x23], x22
+a0a39f0d|	gnu	st3 {v0.s-v2.s}[0], [x29],#12
+37b0890d|	gnu	st3 {v23.s-v25.s}[1], [x1], x9
+9aa59f4d|	gnu	st3 {v26.d-v28.d}[1], [x12],#24
+26a5924d|	gnu	st3 {v6.d-v8.d}[1], [x9], x18
+3e05000c|	gnu	st4 {v30.4h, v31.4h, v0.4h, v1.4h}, [x9]
+a8039f0c|	gnu	st4 {v8.8b-v11.8b}, [x29],#32
+4126204d|	gnu	st4 {v1.b-v4.b}[9], [x18]
+3b71204d|	gnu	st4 {v27.h-v30.h}[6], [x9]
+f2b3204d|	gnu	st4 {v18.s-v21.s}[3], [sp]
+7fa4200d|	gnu	st4 {v31.d, v0.d, v1.d, v2.d}[0], [x3]
+562ebf4d|	gnu	st4 {v22.b-v25.b}[11], [x18],#4
+563cae0d|	gnu	st4 {v22.b-v25.b}[7], [x2], x14
+1271bf4d|	gnu	st4 {v18.h-v21.h}[6], [x8],#8
+e7a1bf0d|	gnu	st4 {v7.s-v10.s}[0], [x15],#16
+f3b2a30d|	gnu	st4 {v19.s-v22.s}[1], [x23], x3
+eca5bf4d|	gnu	st4 {v12.d-v15.d}[1], [x15],#32
+4ca7bb0d|	gnu	st4 {v12.d-v15.d}[0], [x26], x27
+4f5b182c|	gnu	stnp s15, s22, [x26,#192]
+e05e0b6c|	gnu	stnp d0, d23, [x23,#176]
+77be2eac|	gnu	stnp q23, q15, [x19,#-560]
+bb3fa72c|	gnu	stp s27, s15, [x29],#-200
+ef18bb6c|	gnu	stp d15, d6, [x7],#-80
+777d84ac|	gnu	stp q23, q31, [x11],#128
+d0f9952d|	gnu	stp s16, s30, [x14,#172]!
+125ca26d|	gnu	stp d18, d23, [x0,#-480]!
+33bbbfad|	gnu	stp q19, q14, [x25,#-16]!
+6ebb322d|	gnu	stp s14, s14, [x27,#-108]
+cb92096d|	gnu	stp d11, d4, [x22,#152]
+f2871dad|	gnu	stp q18, q1, [sp,#944]
+f676003c|	gnu	str b22, [x23],#7
+50f50d7c|	gnu	str h16, [x10],#223
+0d251ebc|	gnu	str s13, [x8],#-30
+1f3510fc|	gnu	str d31, [x8],#-253
+05a4883c|	gnu	str q5, [x0],#138
+800e063c|	gnu	str b0, [x20,#96]!
+668d157c|	gnu	str h6, [x11,#-168]!
+1f3d11bc|	gnu	str s31, [x8,#-237]!
+71bf06fc|	gnu	str d17, [x27,#107]!
+f50c843c|	gnu	str q21, [x7,#64]!
+f186013d|	gnu	str b17, [x23,#97]
+f0e5357d|	gnu	str h16, [x15,#6898]
+938d3bbd|	gnu	str s19, [x12,#15244]
+aeb813fd|	gnu	str d14, [x5,#10096]
+2cc4943d|	gnu	str q12, [x1,#21264]
+e2f8263c|	gnu	str b2, [x7,x6,sxtx #0]
+1d79373c|	gnu	str b29, [x8,x23,lsl #0]
+bc70003c|	gnu	stur b28, [x5,#7]
+7190157c|	gnu	stur h17, [x3,#-167]
+073309bc|	gnu	stur s7, [x24,#147]
+298100fc|	gnu	stur d9, [x9,#8]
+e8c1843c|	gnu	stur q8, [x15,#76]
+3384266e|	gnu	sub v19.16b, v1.16b, v6.16b
+9163750e|	gnu	subhn v17.4h, v28.4s, v21.4s
+f3627d4e|	gnu	subhn2 v19.8h, v23.4s, v29.4s
+1939205e|	gnu	suqadd b25, b8
+0638604e|	gnu	suqadd v6.8h, v0.8h
+81a4284f|	gnu	sshll2 v1.2d, v4.4s, #8
+f920030e|	gnu	tbl v25.8b, {v7.16b, v8.16b}, v3.8b
+71400e4e|	gnu	tbl v17.16b, {v3.16b-v5.16b}, v14.16b
+bc630d4e|	gnu	tbl v28.16b, {v29.16b, v30.16b, v31.16b, v0.16b}, v13.16b
+6803030e|	gnu	tbl v8.8b, {v27.16b}, v3.8b
+4b32124e|	gnu	tbx v11.16b, {v18.16b, v19.16b}, v18.16b
+8f50170e|	gnu	tbx v15.8b, {v4.16b-v6.16b}, v23.8b
+5673020e|	gnu	tbx v22.8b, {v26.16b-v29.16b}, v2.8b
+f2130f4e|	gnu	tbx v18.16b, {v31.16b}, v15.16b
+9e29c34e|	gnu	trn1 v30.2d, v12.2d, v3.2d
+9b6bcf4e|	gnu	trn2 v27.2d, v28.2d, v15.2d
+157cb02e|	gnu	uaba v21.2s, v0.2s, v16.2s
+28513c2e|	gnu	uabal v8.8h, v9.8b, v28.8b
+f950a26e|	gnu	uabal2 v25.2d, v7.4s, v2.4s
+a776b26e|	gnu	uabd v7.4s, v21.4s, v18.4s
+da726b2e|	gnu	uabdl v26.4s, v22.4h, v11.4h
+9473746e|	gnu	uabdl2 v20.4s, v28.8h, v20.8h
+aa6b602e|	gnu	uadalp v10.2s, v29.4h
+ac013d2e|	gnu	uaddl v12.8h, v13.8b, v29.8b
+e500a86e|	gnu	uaddl2 v5.2d, v7.4s, v8.4s
+9c28a02e|	gnu	uaddlp v28.1d, v4.2s
+4c3a302e|	gnu	uaddlv h12, v18.8b
+2810b62e|	gnu	uaddw v8.2d, v1.2d, v22.2s
+f2132d6e|	gnu	uaddw2 v18.8h, v31.8h, v13.16b
+b3e67f7f|	gnu	ucvtf d19, d21, #1
+ece5676f|	gnu	ucvtf v12.2d, v15.2d, #25
+d7d8217e|	gnu	ucvtf s23, s6
+cdd9212e|	gnu	ucvtf v13.2s, v14.2s
+5788031e|	gnu	ucvtf s23, w2, #30
+c7ac431e|	gnu	ucvtf d7, w6, #21
+0777039e|	gnu	ucvtf s7, x24, #35
+e4f4439e|	gnu	ucvtf d4, x7, #3
+9100231e|	gnu	ucvtf s17, w4
+e202631e|	gnu	ucvtf d2, w23
+3903239e|	gnu	ucvtf s25, x25
+2001639e|	gnu	ucvtf d0, x9
+2a07b76e|	gnu	uhadd v10.4s, v25.4s, v23.4s
+dc25372e|	gnu	uhsub v28.8b, v14.8b, v23.8b
+de646f2e|	gnu	umax v30.4h, v6.4h, v15.4h
+4ba6766e|	gnu	umaxp v11.8h, v18.8h, v22.8h
+e26db42e|	gnu	umin v2.2s, v15.2s, v20.2s
+a7ae712e|	gnu	uminp v7.4h, v21.4h, v17.4h
+afaa716e|	gnu	uminv h15, v21.8h
+42298c2f|	gnu	umlal v2.2d, v10.2s, v12.s[2]
+0a826e2e|	gnu	umlal v10.4s, v16.4h, v14.4h
+2681a06e|	gnu	umlal2 v6.2d, v9.4s, v0.4s
+2860bd6f|	gnu	umlsl2 v8.2d, v1.4s, v29.s[1]
+19a26b6e|	gnu	umlsl2 v25.4s, v16.8h, v11.8h
+8a3d140e|	gnu	mov w10, v12.s[2]
+22a1ba6f|	gnu	umull2 v2.2d, v9.4s, v26.s[1]
+15c0712e|	gnu	umull v21.4s, v0.4h, v17.4h
+2ec0296e|	gnu	umull2 v14.8h, v1.16b, v9.16b
+6e0fba7e|	gnu	uqadd s14, s27, s26
+db0fe06e|	gnu	uqadd v27.2d, v30.2d, v0.2d
+535e6c7e|	gnu	uqrshl h19, h18, h12
+7c5cfe6e|	gnu	uqrshl v28.2d, v3.2d, v30.2d
+9a9e327f|	gnu	uqrshrn s26, d20, #14
+339f0b2f|	gnu	uqrshrn v19.8b, v25.8h, #5
+7e77337f|	gnu	uqshl s30, s27, #19
+8b4d657e|	gnu	uqshl h11, h12, h5
+414c622e|	gnu	uqshl v1.4h, v2.4h, v2.4h
+95942b2f|	gnu	uqshrn v21.2s, v4.2d, #21
+d396246f|	gnu	uqshrn2 v19.4s, v22.2d, #28
+b22ff27e|	gnu	uqsub d18, d29, d18
+b32e756e|	gnu	uqsub v19.8h, v21.8h, v21.8h
+0e4b616e|	gnu	uqxtn2 v14.8h, v24.4s
+ca16236e|	gnu	urhadd v10.16b, v22.16b, v3.16b
+1f57a26e|	gnu	urshl v31.4s, v24.4s, v2.4s
+8324777f|	gnu	urshr d3, d4, #9
+37caa16e|	gnu	ursqrte v23.4s, v17.4s
+b735517f|	gnu	ursra d23, d13, #47
+0a47f67e|	gnu	ushl d10, d24, d22
+e7a71c2f|	gnu	ushll v7.4s, v31.4h, #12
+9c38607e|	gnu	usqadd h28, h4
+dc39206e|	gnu	usqadd v28.16b, v14.16b
+dc145d7f|	gnu	usra d28, d6, #35
+d720752e|	gnu	usubl v23.4s, v6.4h, v21.4h
+2c236f6e|	gnu	usubl2 v12.4s, v25.8h, v15.8h
+ed32222e|	gnu	usubw v13.8h, v23.8h, v2.8b
+72332d6e|	gnu	usubw2 v18.8h, v27.8h, v13.16b
+655a1c4e|	gnu	uzp2 v5.16b, v19.16b, v28.16b
+972a210e|	gnu	xtn v23.8b, v20.8h
+5f2aa14e|	gnu	xtn2 v31.4s, v18.2d
+9a38910e|	gnu	zip1 v26.2s, v4.2s, v17.2s
+d979990e|	gnu	zip2 v25.2s, v14.2s, v25.2s
+41e5a454|	gnu	b.ne .+0xfffffffffff49ca8
+ea1b543a|	gnu	ccmn wzr, #0x14, #0xa, ne
+681946ba|	gnu	ccmn x11, #0x6, #0x8, ne
+2410463a|	gnu	ccmn w1, w6, #0x4, ne
+6e134cba|	gnu	ccmn x27, x12, #0xe, ne
+ad194f7a|	gnu	ccmp w13, #0xf, #0xd, ne
+471b53fa|	gnu	ccmp x26, #0x13, #0x7, ne
+a210467a|	gnu	ccmp w5, w6, #0x2, ne
+ee1246fa|	gnu	ccmp x23, x6, #0xe, ne
+be149b1a|	gnu	csinc w30, w5, w27, ne
+c415819a|	gnu	csinc x4, x14, x1, ne
+0510955a|	gnu	csinv w5, w0, w21, ne
+c51093da|	gnu	csinv x5, x6, x19, ne
+12158e5a|	gnu	csneg w18, w8, w14, ne
+5c159cda|	gnu	csneg x28, x10, x28, ne
+c810941a|	gnu	csel w8, w6, w20, ne
+80128c9a|	gnu	csel x0, x20, x12, ne
+f6179f1a|	gnu	cset w22, eq
+f5179f9a|	gnu	cset x21, eq
+ec139f5a|	gnu	csetm w12, eq
+ee139fda|	gnu	csetm x14, eq
+4b17981a|	gnu	csinc w11, w26, w24, ne
+b515909a|	gnu	csinc x21, x13, x16, ne
+b613955a|	gnu	csinv w22, w29, w21, ne
+f8108bda|	gnu	csinv x24, x7, x11, ne
+a0149d5a|	gnu	csneg w0, w5, w29, ne
+6a1492da|	gnu	csneg x10, x3, x18, ne
+8f143c1e|	gnu	fccmp s4, s28, #0xf, ne
+0f167f1e|	gnu	fccmp d16, d31, #0xf, ne
+5214291e|	gnu	fccmpe s2, s9, #0x2, ne
+1516631e|	gnu	fccmpe d16, d3, #0x5, ne
+2b1d271e|	gnu	fcsel s11, s9, s7, ne
+731e611e|	gnu	fcsel d19, d19, d1, ne
+c2560e54|	gnu	b.cs .+0x1cad8
+2d2b563a|	gnu	ccmn w25, #0x16, #0xd, cs
+6c2b55ba|	gnu	ccmn x27, #0x15, #0xc, cs
+2521493a|	gnu	ccmn w9, w9, #0x5, cs
+032040ba|	gnu	ccmn x0, x0, #0x3, cs
+ea2a5c7a|	gnu	ccmp w23, #0x1c, #0xa, cs
+8e2842fa|	gnu	ccmp x4, #0x2, #0xe, cs
+8e22427a|	gnu	ccmp w20, w2, #0xe, cs
+cd204dfa|	gnu	ccmp x6, x13, #0xd, cs
+2824931a|	gnu	csinc w8, w1, w19, cs
+a3279a9a|	gnu	csinc x3, x29, x26, cs
+5921945a|	gnu	csinv w25, w10, w20, cs
+bd2386da|	gnu	csinv x29, x29, x6, cs
+a124915a|	gnu	csneg w1, w5, w17, cs
+5b2787da|	gnu	csneg x27, x26, x7, cs
+91209f1a|	gnu	csel w17, w4, wzr, cs
+f921979a|	gnu	csel x25, x15, x23, cs
+e4279f1a|	gnu	cset w4, cc
+ea279f9a|	gnu	cset x10, cc
+fe239f5a|	gnu	csetm w30, cc
+ec239fda|	gnu	csetm x12, cc
+ee25971a|	gnu	csinc w14, w15, w23, cs
+b726859a|	gnu	csinc x23, x21, x5, cs
+4b22845a|	gnu	csinv w11, w18, w4, cs
+2b209eda|	gnu	csinv x11, x1, x30, cs
+6b269b5a|	gnu	csneg w11, w19, w27, cs
+192691da|	gnu	csneg x25, x16, x17, cs
+0226391e|	gnu	fccmp s16, s25, #0x2, cs
+07246d1e|	gnu	fccmp d0, d13, #0x7, cs
+9626241e|	gnu	fccmpe s20, s4, #0x6, cs
+de27601e|	gnu	fccmpe d30, d0, #0xe, cs
+7d2d271e|	gnu	fcsel s29, s11, s7, cs
+3e2e7a1e|	gnu	fcsel d30, d17, d26, cs
+43a4df54|	gnu	b.cc .+0xfffffffffffbf488
+0739533a|	gnu	ccmn w8, #0x13, #0x7, cc
+673b4fba|	gnu	ccmn x27, #0xf, #0x7, cc
+e333583a|	gnu	ccmn wzr, w24, #0x3, cc
+83325aba|	gnu	ccmn x20, x26, #0x3, cc
+eb38517a|	gnu	ccmp w7, #0x11, #0xb, cc
+2c3955fa|	gnu	ccmp x9, #0x15, #0xc, cc
+6f324b7a|	gnu	ccmp w19, w11, #0xf, cc
+09314ffa|	gnu	ccmp x8, x15, #0x9, cc
+60349c1a|	gnu	csinc w0, w3, w28, cc
+8835949a|	gnu	csinc x8, x12, x20, cc
+bb31935a|	gnu	csinv w27, w13, w19, cc
+9f319dda|	gnu	csinv xzr, x12, x29, cc
+8837855a|	gnu	csneg w8, w28, w5, cc
+cd3490da|	gnu	csneg x13, x6, x16, cc
+b033901a|	gnu	csel w16, w29, w16, cc
+5e31969a|	gnu	csel x30, x10, x22, cc
+ec379f1a|	gnu	cset w12, cs
+ea379f9a|	gnu	cset x10, cs
+eb339f5a|	gnu	csetm w11, cs
+fd339fda|	gnu	csetm x29, cs
+9934941a|	gnu	csinc w25, w4, w20, cc
+fa36829a|	gnu	csinc x26, x23, x2, cc
+2730895a|	gnu	csinv w7, w1, w9, cc
+703094da|	gnu	csinv x16, x3, x20, cc
+f636935a|	gnu	csneg w22, w23, w19, cc
+ba3484da|	gnu	csneg x26, x5, x4, cc
+e3343e1e|	gnu	fccmp s7, s30, #0x3, cc
+ce366a1e|	gnu	fccmp d22, d10, #0xe, cc
+de37271e|	gnu	fccmpe s30, s7, #0xe, cc
+1935751e|	gnu	fccmpe d8, d21, #0x9, cc
+603f241e|	gnu	fcsel s0, s27, s4, cc
+653f761e|	gnu	fcsel d5, d27, d22, cc
+a4fa5354|	gnu	b.mi .+0xa7f54
+a248483a|	gnu	ccmn w5, #0x8, #0x2, mi
+e2484eba|	gnu	ccmn x7, #0xe, #0x2, mi
+2841553a|	gnu	ccmn w9, w21, #0x8, mi
+6e4259ba|	gnu	ccmn x19, x25, #0xe, mi
+2048567a|	gnu	ccmp w1, #0x16, #0x0, mi
+454a5afa|	gnu	ccmp x18, #0x1a, #0x5, mi
+0343487a|	gnu	ccmp w24, w8, #0x3, mi
+49434bfa|	gnu	ccmp x26, x11, #0x9, mi
+d747991a|	gnu	csinc w23, w30, w25, mi
+9544919a|	gnu	csinc x21, x4, x17, mi
+76428c5a|	gnu	csinv w22, w19, w12, mi
+06418eda|	gnu	csinv x6, x8, x14, mi
+4d46975a|	gnu	csneg w13, w18, w23, mi
+d74491da|	gnu	csneg x23, x6, x17, mi
+0941941a|	gnu	csel w9, w8, w20, mi
+2d41839a|	gnu	csel x13, x9, x3, mi
+ef479f1a|	gnu	cset w15, pl
+e5479f9a|	gnu	cset x5, pl
+f0439f5a|	gnu	csetm w16, pl
+e2439fda|	gnu	csetm x2, pl
+2a46841a|	gnu	csinc w10, w17, w4, mi
+f1468b9a|	gnu	csinc x17, x23, x11, mi
+3441835a|	gnu	csinv w20, w9, w3, mi
+b5438cda|	gnu	csinv x21, x29, x12, mi
+ad45945a|	gnu	csneg w13, w13, w20, mi
+f54793da|	gnu	csneg x21, xzr, x19, mi
+c5473f1e|	gnu	fccmp s30, s31, #0x5, mi
+8947601e|	gnu	fccmp d28, d0, #0x9, mi
+5247331e|	gnu	fccmpe s26, s19, #0x2, mi
+b045761e|	gnu	fccmpe d13, d22, #0x0, mi
+b34d331e|	gnu	fcsel s19, s13, s19, mi
+3a4d6d1e|	gnu	fcsel d26, d9, d13, mi
+a5497054|	gnu	b.pl .+0xe0934
+eb5a493a|	gnu	ccmn w23, #0x9, #0xb, pl
+0a5941ba|	gnu	ccmn x8, #0x1, #0xa, pl
+0452523a|	gnu	ccmn w16, w18, #0x4, pl
+e55053ba|	gnu	ccmn x7, x19, #0x5, pl
+a45b407a|	gnu	ccmp w29, #0x0, #0x4, pl
+ca5b4efa|	gnu	ccmp x30, #0xe, #0xa, pl
+ab514e7a|	gnu	ccmp w13, w14, #0xb, pl
+ce5349fa|	gnu	ccmp x30, x9, #0xe, pl
+8555971a|	gnu	csinc w5, w12, w23, pl
+4b569e9a|	gnu	csinc x11, x18, x30, pl
+90538f5a|	gnu	csinv w16, w28, w15, pl
+c3508bda|	gnu	csinv x3, x6, x11, pl
+1f55955a|	gnu	csneg wzr, w8, w21, pl
+52568eda|	gnu	csneg x18, x18, x14, pl
+a750851a|	gnu	csel w7, w5, w5, pl
+b252899a|	gnu	csel x18, x21, x9, pl
+eb579f1a|	gnu	cset w11, mi
+e6579f9a|	gnu	cset x6, mi
+fd539f5a|	gnu	csetm w29, mi
+e1539fda|	gnu	csetm x1, mi
+33579e1a|	gnu	csinc w19, w25, w30, pl
+b5558c9a|	gnu	csinc x21, x13, x12, pl
+ec53885a|	gnu	csinv w12, wzr, w8, pl
+ec5196da|	gnu	csinv x12, x15, x22, pl
+ae57945a|	gnu	csneg w14, w29, w20, pl
+64578bda|	gnu	csneg x4, x27, x11, pl
+2657241e|	gnu	fccmp s25, s4, #0x6, pl
+2357761e|	gnu	fccmp d25, d22, #0x3, pl
+f255361e|	gnu	fccmpe s15, s22, #0x2, pl
+3756781e|	gnu	fccmpe d17, d24, #0x7, pl
+985c3f1e|	gnu	fcsel s24, s4, s31, pl
+5b5d621e|	gnu	fcsel d27, d10, d2, pl
+c6d26454|	gnu	b.vs .+0xc9a58
+6c6a4f3a|	gnu	ccmn w19, #0xf, #0xc, vs
+2f694cba|	gnu	ccmn x9, #0xc, #0xf, vs
+e962583a|	gnu	ccmn w23, w24, #0x9, vs
+80615fba|	gnu	ccmn x12, xzr, #0x0, vs
+4b6b497a|	gnu	ccmp w26, #0x9, #0xb, vs
+cc6a48fa|	gnu	ccmp x22, #0x8, #0xc, vs
+4e61567a|	gnu	ccmp w10, w22, #0xe, vs
+476054fa|	gnu	ccmp x2, x20, #0x7, vs
+c965911a|	gnu	csinc w9, w14, w17, vs
+41668f9a|	gnu	csinc x1, x18, x15, vs
+db608f5a|	gnu	csinv w27, w6, w15, vs
+896097da|	gnu	csinv x9, x4, x23, vs
+1867915a|	gnu	csneg w24, w24, w17, vs
+49678eda|	gnu	csneg x9, x26, x14, vs
+3162881a|	gnu	csel w17, w17, w8, vs
+db608f9a|	gnu	csel x27, x6, x15, vs
+f9679f1a|	gnu	cset w25, vc
+f9679f9a|	gnu	cset x25, vc
+f7639f5a|	gnu	csetm w23, vc
+e1639fda|	gnu	csetm x1, vc
+f4678a1a|	gnu	csinc w20, wzr, w10, vs
+3e65879a|	gnu	csinc x30, x9, x7, vs
+6c63975a|	gnu	csinv w12, w27, w23, vs
+806191da|	gnu	csinv x0, x12, x17, vs
+7f679f5a|	gnu	csneg wzr, w27, wzr, vs
+3b6488da|	gnu	csneg x27, x1, x8, vs
+0565301e|	gnu	fccmp s8, s16, #0x5, vs
+e266621e|	gnu	fccmp d23, d2, #0x2, vs
+b7653a1e|	gnu	fccmpe s13, s26, #0x7, vs
+d866791e|	gnu	fccmpe d22, d25, #0x8, vs
+326d3d1e|	gnu	fcsel s18, s9, s29, vs
+f66e7b1e|	gnu	fcsel d22, d23, d27, vs
+e774fd54|	gnu	b.vc .+0xffffffffffffae9c
+0479483a|	gnu	ccmn w8, #0x8, #0x4, vc
+897b56ba|	gnu	ccmn x28, #0x16, #0x9, vc
+8b70513a|	gnu	ccmn w4, w17, #0xb, vc
+ca7150ba|	gnu	ccmn x14, x16, #0xa, vc
+46794f7a|	gnu	ccmp w10, #0xf, #0x6, vc
+057948fa|	gnu	ccmp x8, #0x8, #0x5, vc
+0373417a|	gnu	ccmp w24, w1, #0x3, vc
+ca705ffa|	gnu	ccmp x6, xzr, #0xa, vc
+d3769f1a|	gnu	csinc w19, w22, wzr, vc
+1076899a|	gnu	csinc x16, x16, x9, vc
+c8718e5a|	gnu	cinv w8, w14, vs
+06729eda|	gnu	csinv x6, x16, x30, vc
+6076895a|	gnu	csneg w0, w19, w9, vc
+b87589da|	gnu	csneg x24, x13, x9, vc
+3b72891a|	gnu	csel w27, w17, w9, vc
+fd70899a|	gnu	csel x29, x7, x9, vc
+e3779f1a|	gnu	cset w3, vs
+f4779f9a|	gnu	cset x20, vs
+fc739f5a|	gnu	csetm w28, vs
+ea739fda|	gnu	csetm x10, vs
+ab75891a|	gnu	csinc w11, w13, w9, vc
+6177859a|	gnu	csinc x1, x27, x5, vc
+3272945a|	gnu	csinv w18, w17, w20, vc
+7a729dda|	gnu	csinv x26, x19, x29, vc
+b5779e5a|	gnu	csneg w21, w29, w30, vc
+fe748eda|	gnu	csneg x30, x7, x14, vc
+ed76231e|	gnu	fccmp s23, s3, #0xd, vc
+cf74791e|	gnu	fccmp d6, d25, #0xf, vc
+b4763e1e|	gnu	fccmpe s21, s30, #0x4, vc
+59766e1e|	gnu	fccmpe d18, d14, #0x9, vc
+ce7c271e|	gnu	fcsel s14, s6, s7, vc
+be7c651e|	gnu	fcsel d30, d5, d5, vc
+88f29d54|	gnu	b.hi .+0xfffffffffff3be50
+8f8b513a|	gnu	ccmn w28, #0x11, #0xf, hi
+6f8b5cba|	gnu	ccmn x27, #0x1c, #0xf, hi
+8780463a|	gnu	ccmn w4, w6, #0x7, hi
+4f8348ba|	gnu	ccmn x26, x8, #0xf, hi
+48884d7a|	gnu	ccmp w2, #0xd, #0x8, hi
+088957fa|	gnu	ccmp x8, #0x17, #0x8, hi
+0180517a|	gnu	ccmp w0, w17, #0x1, hi
+ce805efa|	gnu	ccmp x6, x30, #0xe, hi
+1d868e1a|	gnu	csinc w29, w16, w14, hi
+0785889a|	gnu	cinc x7, x8, ls
+4782935a|	gnu	csinv w7, w18, w19, hi
+118197da|	gnu	csinv x17, x8, x23, hi
+00868a5a|	gnu	csneg w0, w16, w10, hi
+128585da|	gnu	csneg x18, x8, x5, hi
+4c808f1a|	gnu	csel w12, w2, w15, hi
+7783909a|	gnu	csel x23, x27, x16, hi
+e5879f1a|	gnu	cset w5, ls
+f3879f9a|	gnu	cset x19, ls
+f9839f5a|	gnu	csetm w25, ls
+eb839fda|	gnu	csetm x11, ls
+b3869e1a|	gnu	csinc w19, w21, w30, hi
+f086909a|	gnu	csinc x16, x23, x16, hi
+34839c5a|	gnu	csinv w20, w25, w28, hi
+ea8294da|	gnu	csinv x10, x23, x20, hi
+8e84895a|	gnu	csneg w14, w4, w9, hi
+c48695da|	gnu	csneg x4, x22, x21, hi
+cc84361e|	gnu	fccmp s6, s22, #0xc, hi
+8086781e|	gnu	fccmp d20, d24, #0x0, hi
+7187341e|	gnu	fccmpe s27, s20, #0x1, hi
+30867e1e|	gnu	fccmpe d17, d30, #0x0, hi
+b98e361e|	gnu	fcsel s25, s21, s22, hi
+2c8c651e|	gnu	fcsel d12, d1, d5, hi
+69888c54|	gnu	b.ls .+0xfffffffffff1910c
+0e9b523a|	gnu	ccmn w24, #0x12, #0xe, ls
+679854ba|	gnu	ccmn x3, #0x14, #0x7, ls
+0492563a|	gnu	ccmn w16, w22, #0x4, ls
+42924dba|	gnu	ccmn x18, x13, #0x2, ls
+2198417a|	gnu	ccmp w1, #0x1, #0x1, ls
+c89a54fa|	gnu	ccmp x22, #0x14, #0x8, ls
+0f905e7a|	gnu	ccmp w0, w30, #0xf, ls
+c59342fa|	gnu	ccmp x30, x2, #0x5, ls
+0d958c1a|	gnu	csinc w13, w8, w12, ls
+7596879a|	gnu	csinc x21, x19, x7, ls
+1791905a|	gnu	csinv w23, w8, w16, ls
+5e9186da|	gnu	csinv x30, x10, x6, ls
+23969e5a|	gnu	csneg w3, w17, w30, ls
+619493da|	gnu	csneg x1, x3, x19, ls
+b5918e1a|	gnu	csel w21, w13, w14, ls
+b393819a|	gnu	csel x19, x29, x1, ls
+f9979f1a|	gnu	cset w25, hi
+ee979f9a|	gnu	cset x14, hi
+eb939f5a|	gnu	csetm w11, hi
+ea939fda|	gnu	csetm x10, hi
+f497871a|	gnu	csinc w20, wzr, w7, ls
+c4949d9a|	gnu	csinc x4, x6, x29, ls
+e892895a|	gnu	csinv w8, w23, w9, ls
+6c908eda|	gnu	csinv x12, x3, x14, ls
+26949f5a|	gnu	csneg w6, w1, wzr, ls
+329498da|	gnu	csneg x18, x1, x24, ls
+81952d1e|	gnu	fccmp s12, s13, #0x1, ls
+60967f1e|	gnu	fccmp d19, d31, #0x0, ls
+1794321e|	gnu	fccmpe s0, s18, #0x7, ls
+3f97641e|	gnu	fccmpe d25, d4, #0xf, ls
+089c2d1e|	gnu	fcsel s8, s0, s13, ls
+699f631e|	gnu	fcsel d9, d27, d3, ls
+8afbfe54|	gnu	b.ge .+0xffffffffffffdf70
+44aa573a|	gnu	ccmn w18, #0x17, #0x4, ge
+00a84fba|	gnu	ccmn x0, #0xf, #0x0, ge
+c9a04d3a|	gnu	ccmn w6, w13, #0x9, ge
+88a041ba|	gnu	ccmn x4, x1, #0x8, ge
+caaa467a|	gnu	ccmp w22, #0x6, #0xa, ge
+85a85cfa|	gnu	ccmp x4, #0x1c, #0x5, ge
+47a35f7a|	gnu	ccmp w26, wzr, #0x7, ge
+0aa34dfa|	gnu	ccmp x24, x13, #0xa, ge
+dea7981a|	gnu	csinc w30, w30, w24, ge
+c6a5909a|	gnu	csinc x6, x14, x16, ge
+8aa1965a|	gnu	csinv w10, w12, w22, ge
+e3a392da|	gnu	csinv x3, xzr, x18, ge
+20a5845a|	gnu	csneg w0, w9, w4, ge
+fba694da|	gnu	csneg x27, x23, x20, ge
+faa1851a|	gnu	csel w26, w15, w5, ge
+25a3959a|	gnu	csel x5, x25, x21, ge
+e2a79f1a|	gnu	cset w2, lt
+fda79f9a|	gnu	cset x29, lt
+eea39f5a|	gnu	csetm w14, lt
+e2a39fda|	gnu	csetm x2, lt
+efa6951a|	gnu	csinc w15, w23, w21, ge
+4ca69e9a|	gnu	csinc x12, x18, x30, ge
+22a2885a|	gnu	csinv w2, w17, w8, ge
+53a089da|	gnu	csinv x19, x2, x9, ge
+f9a6875a|	gnu	csneg w25, w23, w7, ge
+c9a795da|	gnu	csneg x9, x30, x21, ge
+24a73e1e|	gnu	fccmp s25, s30, #0x4, ge
+6da5651e|	gnu	fccmp d11, d5, #0xd, ge
+bda52e1e|	gnu	fccmpe s13, s14, #0xd, ge
+f6a7651e|	gnu	fccmpe d31, d5, #0x6, ge
+e3ac251e|	gnu	fcsel s3, s7, s5, ge
+b3ae781e|	gnu	fcsel d19, d21, d24, ge
+ab621754|	gnu	b.lt .+0x2ec54
+e1b84c3a|	gnu	ccmn w7, #0xc, #0x1, lt
+89ba4eba|	gnu	ccmn x20, #0xe, #0x9, lt
+88b14a3a|	gnu	ccmn w12, w10, #0x8, lt
+89b145ba|	gnu	ccmn x12, x5, #0x9, lt
+47b9547a|	gnu	ccmp w10, #0x14, #0x7, lt
+07b95bfa|	gnu	ccmp x8, #0x1b, #0x7, lt
+4ab2407a|	gnu	ccmp w18, w0, #0xa, lt
+8ab144fa|	gnu	ccmp x12, x4, #0xa, lt
+79b5821a|	gnu	csinc w25, w11, w2, lt
+8bb4919a|	gnu	csinc x11, x4, x17, lt
+c9b19f5a|	gnu	csinv w9, w14, wzr, lt
+10b28bda|	gnu	csinv x16, x16, x11, lt
+d8b4925a|	gnu	csneg w24, w6, w18, lt
+3ab69fda|	gnu	csneg x26, x17, xzr, lt
+2cb3841a|	gnu	csel w12, w25, w4, lt
+77b0969a|	gnu	csel x23, x3, x22, lt
+e2b79f1a|	gnu	cset w2, ge
+e9b79f9a|	gnu	cset x9, ge
+f4b39f5a|	gnu	csetm w20, ge
+f2b39fda|	gnu	csetm x18, ge
+87b59a1a|	gnu	csinc w7, w12, w26, lt
+70b69c9a|	gnu	csinc x16, x19, x28, lt
+17b08f5a|	gnu	csinv w23, w0, w15, lt
+cab288da|	gnu	csinv x10, x22, x8, lt
+bab7905a|	gnu	csneg w26, w29, w16, lt
+08b796da|	gnu	csneg x8, x24, x22, lt
+2eb73e1e|	gnu	fccmp s25, s30, #0xe, lt
+86b7671e|	gnu	fccmp d28, d7, #0x6, lt
+f0b6211e|	gnu	fccmpe s23, s1, #0x0, lt
+b2b76b1e|	gnu	fccmpe d29, d11, #0x2, lt
+e8bf241e|	gnu	fcsel s8, s31, s4, lt
+9ebd7d1e|	gnu	fcsel d30, d12, d29, lt
+cc87d354|	gnu	b.gt .+0xfffffffffffa70f8
+43c8563a|	gnu	ccmn w2, #0x16, #0x3, gt
+c5c94dba|	gnu	ccmn x14, #0xd, #0x5, gt
+6fc0533a|	gnu	ccmn w3, w19, #0xf, gt
+06c351ba|	gnu	ccmn x24, x17, #0x6, gt
+c3c95c7a|	gnu	ccmp w14, #0x1c, #0x3, gt
+29cb52fa|	gnu	ccmp x25, #0x12, #0x9, gt
+8bc25a7a|	gnu	ccmp w20, w26, #0xb, gt
+45c14dfa|	gnu	ccmp x10, x13, #0x5, gt
+80c7841a|	gnu	csinc w0, w28, w4, gt
+40c4919a|	gnu	csinc x0, x2, x17, gt
+04c2805a|	gnu	csinv w4, w16, w0, gt
+55c086da|	gnu	csinv x21, x2, x6, gt
+32c7935a|	gnu	csneg w18, w25, w19, gt
+31c59fda|	gnu	csneg x17, x9, xzr, gt
+6cc2921a|	gnu	csel w12, w19, w18, gt
+37c08d9a|	gnu	csel x23, x1, x13, gt
+eec79f1a|	gnu	cset w14, le
+eec79f9a|	gnu	cset x14, le
+f4c39f5a|	gnu	csetm w20, le
+f6c39fda|	gnu	csetm x22, le
+31c5971a|	gnu	csinc w17, w9, w23, gt
+76c7899a|	gnu	csinc x22, x27, x9, gt
+bbc1805a|	gnu	csinv w27, w13, w0, gt
+e8c384da|	gnu	csinv x8, xzr, x4, gt
+83c5955a|	gnu	csneg w3, w12, w21, gt
+77c790da|	gnu	csneg x23, x27, x16, gt
+e9c5251e|	gnu	fccmp s15, s5, #0x9, gt
+a3c4671e|	gnu	fccmp d5, d7, #0x3, gt
+71c72e1e|	gnu	fccmpe s27, s14, #0x1, gt
+3dc4781e|	gnu	fccmpe d1, d24, #0xd, gt
+57cf3d1e|	gnu	fcsel s23, s26, s29, gt
+8fcc7e1e|	gnu	fcsel d15, d4, d30, gt
+8d1ec054|	gnu	b.le .+0xfffffffffff803d0
+4bdb5b3a|	gnu	ccmn w26, #0x1b, #0xb, le
+47d94fba|	gnu	ccmn x10, #0xf, #0x7, le
+4dd1443a|	gnu	ccmn w10, w4, #0xd, le
+82d353ba|	gnu	ccmn x28, x19, #0x2, le
+e8d9527a|	gnu	ccmp w15, #0x12, #0x8, le
+00db45fa|	gnu	ccmp x24, #0x5, #0x0, le
+c5d1437a|	gnu	ccmp w14, w3, #0x5, le
+e4d041fa|	gnu	ccmp x7, x1, #0x4, le
+0bd6941a|	gnu	csinc w11, w16, w20, le
+57d6929a|	gnu	cinc x23, x18, gt
+3dd29a5a|	gnu	csinv w29, w17, w26, le
+ded085da|	gnu	csinv x30, x6, x5, le
+27d5985a|	gnu	csneg w7, w9, w24, le
+7fd59ada|	gnu	csneg xzr, x11, x26, le
+b7d0911a|	gnu	csel w23, w5, w17, le
+a4d3879a|	gnu	csel x4, x29, x7, le
+e6d79f1a|	gnu	cset w6, gt
+f1d79f9a|	gnu	cset x17, gt
+f3d39f5a|	gnu	csetm w19, gt
+f9d39fda|	gnu	csetm x25, gt
+42d78d1a|	gnu	csinc w2, w26, w13, le
+88d58a9a|	gnu	csinc x8, x12, x10, le
+ccd3805a|	gnu	csinv w12, w30, w0, le
+0fd085da|	gnu	csinv x15, x0, x5, le
+55d5975a|	gnu	csneg w21, w10, w23, le
+3fd699da|	gnu	csneg xzr, x17, x25, le
+60d4251e|	gnu	fccmp s3, s5, #0x0, le
+6dd6601e|	gnu	fccmp d19, d0, #0xd, le
+bdd5221e|	gnu	fccmpe s13, s2, #0xd, le
+f4d67d1e|	gnu	fccmpe d23, d29, #0x4, le
+0cdd381e|	gnu	fcsel s12, s8, s24, le
+70de7e1e|	gnu	fcsel d16, d19, d30, le
+8e585454|	gnu	b.al .+0xa8b10
+41eb483a|	gnu	ccmn w26, #0x8, #0x1, al
+8aeb42ba|	gnu	ccmn x28, #0x2, #0xa, al
+c8e3473a|	gnu	ccmn w30, w7, #0x8, al
+ade059ba|	gnu	ccmn x5, x25, #0xd, al
+67eb5b7a|	gnu	ccmp w27, #0x1b, #0x7, al
+05e849fa|	gnu	ccmp x0, #0x9, #0x5, al
+42e3407a|	gnu	ccmp w26, w0, #0x2, al
+03e053fa|	gnu	ccmp x0, x19, #0x3, al
+9ce4931a|	gnu	csinc w28, w4, w19, al
+8ee69d9a|	gnu	csinc x14, x20, x29, al
+68e0835a|	gnu	csinv w8, w3, w3, al
+20e381da|	gnu	csinv x0, x25, x1, al
+e0e58d5a|	gnu	csneg w0, w15, w13, al
+9ae589da|	gnu	csneg x26, x12, x9, al
+6ee0941a|	gnu	csel w14, w3, w20, al
+77e38a9a|	gnu	csel x23, x27, x10, al
+efe79f1a|	gnu	csinc w15, wzr, wzr, al
+e5e79f9a|	gnu	csinc x5, xzr, xzr, al
+f2e39f5a|	gnu	csinv w18, wzr, wzr, al
+fae39fda|	gnu	csinv x26, xzr, xzr, al
+ede7861a|	gnu	csinc w13, wzr, w6, al
+0ce58a9a|	gnu	csinc x12, x8, x10, al
+75e2835a|	gnu	csinv w21, w19, w3, al
+38e391da|	gnu	csinv x24, x25, x17, al
+fee4845a|	gnu	csneg w30, w7, w4, al
+09e49bda|	gnu	csneg x9, x0, x27, al
+a8e6271e|	gnu	fccmp s21, s7, #0x8, al
+ede67d1e|	gnu	fccmp d23, d29, #0xd, al
+bbe53b1e|	gnu	fccmpe s13, s27, #0xb, al
+70e6661e|	gnu	fccmpe d19, d6, #0x0, al
+01ee3b1e|	gnu	fcsel s1, s16, s27, al
+15ec651e|	gnu	fcsel d21, d0, d5, al
+4f462554|	gnu	b.al .+0x4a8c8
+eef9493a|	gnu	ccmn w15, #0x9, #0xe, al
+88fa53ba|	gnu	ccmn x20, #0x13, #0x8, al
+c0f25f3a|	gnu	ccmn w22, wzr, #0x0, al
+c6f05cba|	gnu	ccmn x6, x28, #0x6, al
+45f84c7a|	gnu	ccmp w2, #0xc, #0x5, al
+a3fa4afa|	gnu	ccmp x21, #0xa, #0x3, al
+caf3517a|	gnu	ccmp w30, w17, #0xa, al
+81f055fa|	gnu	ccmp x4, x21, #0x1, al
+cbf69e1a|	gnu	csinc w11, w22, w30, al
+01f48e9a|	gnu	csinc x1, x0, x14, al
+61f1845a|	gnu	csinv w1, w11, w4, al
+11f397da|	gnu	csinv x17, x24, x23, al
+7bf69f5a|	gnu	csneg w27, w19, wzr, al
+b1f686da|	gnu	csneg x17, x21, x6, al
+69f39e1a|	gnu	csel w9, w27, w30, al
+79f2859a|	gnu	csel x25, x19, x5, al
+e1f79f1a|	gnu	csinc w1, wzr, wzr, al
+e6f79f9a|	gnu	csinc x6, xzr, xzr, al
+fcf39f5a|	gnu	csinv w28, wzr, wzr, al
+fbf39fda|	gnu	csinv x27, xzr, xzr, al
+2ef4831a|	gnu	csinc w14, w1, w3, al
+55f6859a|	gnu	csinc x21, x18, x5, al
+4ff0905a|	gnu	csinv w15, w2, w16, al
+81f393da|	gnu	csinv x1, x28, x19, al
+8bf68d5a|	gnu	csneg w11, w20, w13, al
+c2f48fda|	gnu	csneg x2, x6, x15, al
+e9f6391e|	gnu	fccmp s23, s25, #0x9, al
+27f46f1e|	gnu	fccmp d1, d15, #0x7, al
+72f6301e|	gnu	fccmpe s19, s16, #0x2, al
+37f57a1e|	gnu	fccmpe d9, d26, #0x7, al
+fcfe3a1e|	gnu	fcsel s28, s23, s26, al
+80fd701e|	gnu	fcsel d0, d12, d16, al
+40946454|	gnu	b.eq .+0xc9288
+8b09473a|	gnu	ccmn w12, #0x7, #0xb, eq
+c50a5eba|	gnu	ccmn x22, #0x1e, #0x5, eq
+05005a3a|	gnu	ccmn w0, w26, #0x5, eq
+cf024bba|	gnu	ccmn x22, x11, #0xf, eq
+8a084f7a|	gnu	ccmp w4, #0xf, #0xa, eq
+e20a41fa|	gnu	ccmp x23, #0x1, #0x2, eq
+8c015f7a|	gnu	ccmp w12, wzr, #0xc, eq
+e4015cfa|	gnu	ccmp x15, x28, #0x4, eq
+42078e1a|	gnu	csinc w2, w26, w14, eq
+2005879a|	gnu	csinc x0, x9, x7, eq
+f003955a|	gnu	csinv w16, wzr, w21, eq
+dc019dda|	gnu	csinv x28, x14, x29, eq
+4607885a|	gnu	csneg w6, w26, w8, eq
+26069eda|	gnu	csneg x6, x17, x30, eq
+72018a1a|	gnu	csel w18, w11, w10, eq
+8003849a|	gnu	csel x0, x28, x4, eq
+f1079f1a|	gnu	cset w17, ne
+fb079f9a|	gnu	cset x27, ne
+ef039f5a|	gnu	csetm w15, ne
+e1039fda|	gnu	csetm x1, ne
+5307881a|	gnu	csinc w19, w26, w8, eq
+8a06969a|	gnu	csinc x10, x20, x22, eq
+ab00955a|	gnu	csinv w11, w5, w21, eq
+c3039bda|	gnu	csinv x3, x30, x27, eq
+8005875a|	gnu	csneg w0, w12, w7, eq
+740694da|	gnu	csneg x20, x19, x20, eq
+e207281e|	gnu	fccmp s31, s8, #0x2, eq
+2b056a1e|	gnu	fccmp d9, d10, #0xb, eq
+7e063f1e|	gnu	fccmpe s19, s31, #0xe, eq
+3c05671e|	gnu	fccmpe d9, d7, #0xc, eq
+830f271e|	gnu	fcsel s3, s28, s7, eq
+4d0d621e|	gnu	fcsel d13, d10, d2, eq
+bf2003d5|	gnu	sevl
+9f2003d5|	gnu	sev
+7f2003d5|	gnu	wfi
+5f2003d5|	gnu	wfe
+3f2003d5|	gnu	yield
+1f2003d5|	gnu	nop
+df4d03d5|	gnu	msr daifset, #0xd
+ff4d03d5|	gnu	msr daifclr, #0xd
+28d91b14|	gnu	b .+0x6f64a0
+da6cb530|	gnu	adr x26, .+0xfffffffffff6ad99
+15e5e514|	gnu	b .+0x3979454
+ff4603d5|	gnu	msr daifclr, #0x6
+df4803d5|	gnu	msr daifset, #0x8
+bf4100d5|	gnu	msr spsel, #0x1
+9f3f03d5|	gnu	dsb sy
+9f3e03d5|	gnu	dsb st
+9f3d03d5|	gnu	dsb ld
+9f3b03d5|	gnu	dsb ish
+9f3a03d5|	gnu	dsb ishst
+9f3903d5|	gnu	dsb ishld
+9f3703d5|	gnu	dsb nsh
+9f3603d5|	gnu	dsb nshst
+9f3503d5|	gnu	dsb nshld
+9f3303d5|	gnu	dsb osh
+9f3203d5|	gnu	dsb oshst
+9f3103d5|	gnu	dsb oshld
+ff4603d5|	gnu	msr daifclr, #0x6
+df4803d5|	gnu	msr daifset, #0x8
+bf4100d5|	gnu	msr spsel, #0x1
+a3681b53|	gnu	lsl w3, w5, #5
+47dc78d3|	gnu	lsl x7, x2, #8
+0500a012|	gnu	movn w5, #0x0, lsl #16
+0500e092|	gnu	movn x5, #0x0, lsl #48
+0500a052|	gnu	movz w5, #0x0, lsl #16
+0500a0d2|	gnu	movz x5, #0x0, lsl #16
+cd5a206e|	gnu	mvn v13.16b, v22.16b
+cd5a202e|	gnu	mvn v13.8b, v22.8b
+743d050e|	gnu	umov w20, v11.b[2]
+743d0a0e|	gnu	umov w20, v11.h[2]
+743d0c0e|	gnu	mov w20, v11.s[1]
+743d084e|	gnu	mov x20, v11.d[0]
+0a011f1a|	plan9	ADCW ZR, R8, R10
+4c00009a|	plan9	ADC R0, R2, R12
+a602093a|	plan9	ADCSW R9, R21, R6
+d60217ba|	plan9	ADCS R23, R22, R22
+0921250b|	plan9	ADDW R5.UXTH, R8, R9
+ee9e288b|	plan9	ADD R8.SXTB<<7, R23, R14
+23123011|	plan9	ADDW $3076, R17, R3
+2ba32391|	plan9	ADD $2280, R25, R11
+67158d0b|	plan9	ADDW R13->5, R11, R7
+30da198b|	plan9	ADD R25<<54, R17, R16
+a7e72c2b|	plan9	ADDSW R12.SXTX<<1, R29, R7
+357338ab|	plan9	ADDS R24.UXTX<<4, R25, R21
+6b147731|	plan9	ADDSW $(3525<<12), R3, R11
+cd59872b|	plan9	ADDSW R7->22, R14, R13
+e41f4eab|	plan9	ADDS R14>>7, ZR, R4
+a2432412|	plan9	ANDW $4026540031, R29, R2
+93910e92|	plan9	AND $34903429696192636, R12, R19
+7a1ec98a|	plan9	AND R9@>7, R19, R26
+1ff32972|	plan9	TSTW $2863311530, R24
+458051f2|	plan9	ANDS $-140737488289793, R2, R5
+af629a6a|	plan9	ANDSW R26->24, R21, R15
+7ab0dfea|	plan9	ANDS ZR@>44, R3, R26
+792bcc1a|	plan9	ASRW R12, R27, R25
+872bce9a|	plan9	ASR R14, R28, R7
+99ff4b93|	plan9	ASR $11, R28, R25
+1628c91a|	plan9	ASRW R9, R0, R22
+4e2acf9a|	plan9	ASR R15, R18, R14
+4be5a454|	plan9	BLT -186582(PC)
+53257114|	plan9	JMP 7415123(PC)
+dbb557b3|	plan9	BFXIL $23, R14, $23, R27
+70e861b3|	plan9	BFXIL $33, R3, $26, R16
+88a75ab3|	plan9	BFXIL $26, R28, $16, R8
+b03ce70a|	plan9	BICW R7@>15, R5, R16
+9235ec8a|	plan9	BIC R12@>13, R12, R18
+7450b96a|	plan9	BICSW R25->20, R3, R20
+3730b3ea|	plan9	BICS R19->12, R1, R23
+9b897797|	plan9	CALL -8943205(PC)
+e0013fd6|	plan9	CALL (R15)
+a0031fd6|	plan9	JMP (R29)
+e08c31d4|	plan9	BRK $35943
+4bfb543a|	plan9	CCMNW AL, R26, $20, $11
+015b46ba|	plan9	CCMN PL, R24, $6, $1
+8602463a|	plan9	CCMNW EQ, R20, R6, $6
+c6d34cba|	plan9	CCMN LE, R30, R12, $6
+a76b4f7a|	plan9	CCMPW VS, R29, $15, $7
+e3d853fa|	plan9	CCMP LE, R7, $19, $3
+4022467a|	plan9	CCMPW HS, R18, R6, $0
+c7b346fa|	plan9	CCMP LT, R30, R6, $7
+ee279b1a|	plan9	CSINCW HS, ZR, R27, R14
+4174819a|	plan9	CSINC VC, R2, R1, R1
+5100955a|	plan9	CSINVW EQ, R2, R21, R17
+573093da|	plan9	CSINV LO, R2, R19, R23
+5f3403d5|	plan9	CLREX $4
+e615c05a|	plan9	CLSW R15, R6
+ff15c0da|	plan9	CLS R15, ZR
+2e10c05a|	plan9	CLZW R1, R14
+a912c0da|	plan9	CLZ R21, R9
+ff11352b|	plan9	CMNW R21.UXTB<<4, R15
+1f5220ab|	plan9	CMN R0.UXTW<<4, R16
+ff02266b|	plan9	CMPW R6.UXTB, R23
+5fb739eb|	plan9	CMP R25.SXTH<<5, R26
+bfa73bf1|	plan9	CMP $3817, R29
+7f5c47eb|	plan9	CMP R7>>23, R3
+2e458e5a|	plan9	CSNEGW MI, R9, R14, R14
+c3559cda|	plan9	CSNEG PL, R14, R28, R3
+1041d11a|	plan9	CRC32B R17, R8, R16
+bb46c31a|	plan9	CRC32H R3, R21, R27
+c94bd61a|	plan9	CRC32W R22, R30, R9
+8f4cd49a|	plan9	CRC32X R20, R4, R15
+7653d21a|	plan9	CRC32CB R18, R27, R22
+1454d51a|	plan9	CRC32CH R21, R0, R20
+7c58c91a|	plan9	CRC32CW R9, R3, R28
+185ccb9a|	plan9	CRC32CX R11, R0, R24
+8c30941a|	plan9	CSELW LO, R4, R20, R12
+0ea08c9a|	plan9	CSEL GE, R0, R12, R14
+e3b79f1a|	plan9	CSETW GE, R3
+fea79f9a|	plan9	CSET LT, R30
+e5639f5a|	plan9	CSETMW VC, R5
+e4739fda|	plan9	CSETM VS, R4
+bad4981a|	plan9	CSINCW LE, R5, R24, R26
+5167909a|	plan9	CSINC VS, R26, R16, R17
+65e3955a|	plan9	CSINVW AL, R27, R21, R5
+8e338bda|	plan9	CSINV LO, R28, R11, R14
+0a269d5a|	plan9	CSNEGW HS, R16, R29, R10
+ab1692da|	plan9	CSNEG NE, R21, R18, R11
+418ea5d4|	plan9	DCPS1 $11378
+6239a5d4|	plan9	DCPS2 $10699
+e3ebabd4|	plan9	DCPS3 $24415
+bf3a03d5|	plan9	DMB $10
+e003bfd6|	plan9	DRPS
+9f3003d5|	plan9	DSB $0
+c974354a|	plan9	EONW R21<<29, R6, R9
+89b86eca|	plan9	EON R14>>46, R4, R9
+76e343d2|	plan9	EOR $-2287828610704211969, R27, R22
+536d8c4a|	plan9	EORW R12->27, R10, R19
+d1ef1cca|	plan9	EOR R28<<59, R30, R17
+e0039fd6|	plan9	ERET
+591d8813|	plan9	EXTRW $7, R8, R10, R25
+888dd693|	plan9	EXTR $35, R22, R12, R8
+bf2003d5|	plan9	SEVL
+df2003d5|	plan9	HINT $6
+a0fc5fd4|	plan9	HLT $65509
+df3103d5|	plan9	ISB $1
+9dfddf88|	plan9	LDARW (R12), R29
+76ffdfc8|	plan9	LDAR (R27), R22
+36ffdf08|	plan9	LDARB (R25), R22
+bcfcdf48|	plan9	LDARH (R5), R28
+54c17f88|	plan9	LDAXPW (R10), R16, R20
+3eaf7fc8|	plan9	LDAXP (R25), R11, R30
+e2fd5f88|	plan9	LDAXRW (R15), R2
+f5fd5fc8|	plan9	LDAXR (R15), R21
+70fe5f08|	plan9	LDAXRB (R19), R16
+bcfc5f48|	plan9	LDAXRH (R5), R28
+ecff5928|	plan9	LDNPW 204(RSP), ZR, R12
+852744a8|	plan9	LDNP 64(R28), R9, R5
+1286d728|	plan9	LDP.P 188(R16), (R18, R1)
+7668e8a8|	plan9	LDP.P -384(R3), (R22, R26)
+6d8bc729|	plan9	LDP.W 60(R27), (R13, R2)
+1cadd1a9|	plan9	LDP.W 280(R8), (R28, R11)
+bf4e7e29|	plan9	LDP -16(R21), (ZR, R19)
+61695fa9|	plan9	LDP 496(R11), (R1, R26)
+4c00e668|	plan9	LDPSW -208(R2), R0, R12
+85a0cb69|	plan9	LDPSW 92(R4), R8, R5
+9b894d69|	plan9	LDPSW 108(R12), R2, R27
+e9955ab8|	plan9	MOVWU.P -87(R15), R9
+5c255df8|	plan9	MOVD.P -46(R10), R28
+703c57b8|	plan9	MOVWU.W -141(R3), R16
+1dac57f8|	plan9	MOVD.W -134(R0), R29
+393c50b9|	plan9	MOVWU 4156(R1), R25
+498d5cf9|	plan9	MOVD 14616(R10), R9
+8ca74238|	plan9	MOVBU.P 42(R28), R12
+4e5c5e38|	plan9	MOVBU.W -27(R2), R14
+03936d39|	plan9	MOVBU 2916(R24), R3
+577a6e38|	plan9	MOVBU R14<<1(R18), R23
+adb54678|	plan9	MOVHU.P 107(R13), R13
+820f4c78|	plan9	MOVHU.W 192(R28), R2
+92787579|	plan9	MOVHU 6844(R4), R18
+4bd6c438|	plan9	MOVBW.P 77(R18), R11
+fb478238|	plan9	MOVB.P 36(RSP), R27
+4d7edc38|	plan9	MOVBW.W -57(R18), R13
+18ee9438|	plan9	MOVB.W -178(R16), R24
+16b9c639|	plan9	MOVBW 430(R8), R22
+37958f39|	plan9	MOVB 997(R9), R23
+af7ae238|	plan9	MOVBW R2<<1(R21), R15
+1568fa38|	plan9	MOVBW R26(R0), R21
+f069a538|	plan9	MOVB R5(R15), R16
+d9a6cd78|	plan9	MOVHW.P 218(R22), R25
+ff368b78|	plan9	MOVH.P 179(R23), ZR
+5b8cc878|	plan9	MOVHW.W 136(R2), R27
+361f9c78|	plan9	MOVH.W -63(R25), R22
+359bec79|	plan9	MOVHW 5708(R25), R21
+4d6c8079|	plan9	MOVH 54(R2), R13
+02669cb8|	plan9	MOVW.P -58(R16), R2
+5c8e92b8|	plan9	MOVW.W -216(R18), R28
+ea9e92b9|	plan9	MOVW 4764(R23), R10
+64285eb8|	plan9	LDTRW -30(R3), R4
+6ab851f8|	plan9	LDTR -229(R3), R10
+aa094f38|	plan9	LDTRBW 240(R13), R10
+b7894e78|	plan9	LDTRHW 232(R13), R23
+85cadd38|	plan9	LDTRSBW -36(R20), R5
+2db99838|	plan9	LDTRSB -117(R9), R13
+7ef8ce78|	plan9	LDTRSHW 239(R3), R30
+786a8978|	plan9	LDTRSH 150(R19), R24
+c5eb81b8|	plan9	LDTRSW 30(R30), R5
+a1f14bb8|	plan9	LDURW 191(R13), R1
+c3425cf8|	plan9	LDUR -60(R22), R3
+2e125038|	plan9	LDURBW -255(R17), R14
+26004878|	plan9	LDURHW 128(R1), R6
+c3e3cd38|	plan9	LDURSBW 222(R30), R3
+27618938|	plan9	LDURSB 150(R9), R7
+7c71db78|	plan9	LDURSHW -73(R11), R28
+1d109e78|	plan9	LDURSH -31(R0), R29
+d48084b8|	plan9	LDURSW 72(R6), R20
+172f7f88|	plan9	LDXPW (R24), R11, R23
+10347fc8|	plan9	LDXP (R0), R13, R16
+fe7f5f88|	plan9	LDXRW (RSP), R30
+6c7f5fc8|	plan9	LDXR (R27), R12
+047c5f08|	plan9	LDXRB (R0), R4
+9a7d5f48|	plan9	LDXRH (R12), R26
+4f21cb1a|	plan9	LSLW R11, R10, R15
+1523db9a|	plan9	LSL R27, R24, R21
+81c74fd3|	plan9	UBFX $15, R28, $35, R1
+c922c81a|	plan9	LSLW R8, R22, R9
+fd22dc9a|	plan9	LSL R28, R23, R29
+4226dd1a|	plan9	LSRW R29, R18, R2
+a224ca9a|	plan9	LSR R10, R5, R2
+707c0153|	plan9	LSRW $1, R3, R16
+34fc4cd3|	plan9	LSR $12, R1, R20
+6c24c91a|	plan9	LSRW R9, R3, R12
+8527c89a|	plan9	LSR R8, R28, R5
+ea36171b|	plan9	MADDW R23, R13, R23, R10
+e47a0a9b|	plan9	MADD R10, R30, R23, R4
+35fd001b|	plan9	MNEGW R0, R9, R21
+77ff0e9b|	plan9	MNEG R14, R27, R23
+38030011|	plan9	ADDW $0, R25, R24
+37030091|	plan9	ADD $0, R25, R23
+94b8ad12|	plan9	MOVW $2453405695, R20
+fff29892|	plan9	MOVD $-51096, ZR
+d4adb252|	plan9	MOVW $2507014144, R20
+8747e2d2|	plan9	MOVD $1313925191285342208, R7
+f5132d32|	plan9	ORRW $16252928, ZR, R21
+eb7f34b2|	plan9	MOVD $-1, R11
+f503092a|	plan9	MOVW R9, R21
+e7031eaa|	plan9	MOVD R30, R7
+35e8c1f2|	plan9	MOVK $(3905<<32), R21
+44629512|	plan9	MOVW $4294923501, R4
+cc0dd392|	plan9	MOVD $-167598213824513, R12
+cbfb9152|	plan9	MOVW $36830, R11
+3d25ebd2|	plan9	MOVD $6424666343420723200, R29
+e67a3fd5|	plan9	MRS $31703, R6
+f9dd15d5|	plan9	MSR R25, $12015
+25840c1b|	plan9	MSUBW R12, R1, R1, R5
+02ce1a9b|	plan9	MSUB R26, R19, R16, R2
+b67c1a1b|	plan9	MULW R26, R5, R22
+607c049b|	plan9	MUL R4, R3, R0
+e97f6daa|	plan9	MVN R13>>31, R9
+fe071f6b|	plan9	NEGSW ZR<<1, R30
+f68f14eb|	plan9	NEGS R20<<35, R22
+e8030d5a|	plan9	NGCW R13, R8
+fe031eda|	plan9	NGC R30, R30
+e5030a7a|	plan9	NGCSW R10, R5
+f00318fa|	plan9	NGCS R24, R16
+1f2003d5|	plan9	NOP
+032ee42a|	plan9	ORNW R4@>11, R16, R3
+634cf6aa|	plan9	ORN R22@>19, R3, R3
+f8492d32|	plan9	ORRW $4294443071, R15, R24
+96f542b2|	plan9	ORR $-3458764513820540929, R12, R22
+1c110d2a|	plan9	ORRW R13<<4, R8, R28
+c65b1eaa|	plan9	ORR R30<<22, R30, R6
+f300b2f9|	plan9	PRFM 25600(R7), PSTL2STRM
+c62184f8|	plan9	PRFUM 66(R14), #0X06
+3601c05a|	plan9	RBITW R9, R22
+6401c0da|	plan9	RBIT R11, R4
+e0035fd6|	plan9	RET ZR
+0a09c05a|	plan9	REVW R8, R10
+220cc0da|	plan9	REV R1, R2
+b206c05a|	plan9	REV16W R21, R18
+2407c0da|	plan9	REV16 R25, R4
+7e0bc0da|	plan9	REV32 R27, R30
+ae0ec0da|	plan9	REV R21, R14
+336f8413|	plan9	EXTRW $27, R4, R25, R19
+af47ca93|	plan9	EXTR $17, R10, R29, R15
+bc2cdb1a|	plan9	RORW R27, R5, R28
+e52fdd9a|	plan9	ROR R29, ZR, R5
+832dc31a|	plan9	RORW R3, R12, R3
+e22ec09a|	plan9	ROR R0, R23, R2
+1801045a|	plan9	SBCW R4, R8, R24
+5a0119da|	plan9	SBC R25, R10, R26
+52021b7a|	plan9	SBCSW R27, R18, R18
+250105fa|	plan9	SBCS R5, R9, R5
+fc430b13|	plan9	SBFXW $11, ZR, $6, R28
+a0574093|	plan9	SBFX $0, R29, $22, R0
+8b3b7a93|	plan9	SBFIZ $6, R28, $15, R11
+fc310513|	plan9	SBFXW $5, R15, $8, R28
+fbdc4293|	plan9	SBFX $2, R7, $54, R27
+c90dd61a|	plan9	SDIVW R22, R14, R9
+a90ecd9a|	plan9	SDIV R13, R21, R9
+9f2003d5|	plan9	SEV
+bf2003d5|	plan9	SEVL
+d27f229b|	plan9	SMULL R2, R30, R18
+efff3a9b|	plan9	SMNEGL R26, ZR, R15
+7d963f9b|	plan9	SMSUBL ZR, R5, R19, R29
+b57e519b|	plan9	SMULH R17, R21, R21
+a07c209b|	plan9	SMULL R0, R5, R0
+d0fe9f88|	plan9	STLRW R16, (R22)
+03ff9fc8|	plan9	STLR R3, (R24)
+8bff9f08|	plan9	STLRB R11, (R28)
+f0fe9f48|	plan9	STLRH R16, (R23)
+c6ae3588|	plan9	STLXPW (R22), R11, R6, R21
+c6fa22c8|	plan9	STLXPW (R22), R30, R6, R2
+affd0e88|	plan9	STLXRW R15, (R13), R14
+67ff1cc8|	plan9	STLXR R7, (R27), R28
+17ff1c08|	plan9	STLXRB R23, (R24), R28
+7bfe0b48|	plan9	STLXRH R27, (R19), R11
+2a8c0528|	plan9	STNPW 44(R1), R3, R10
+67fc10a8|	plan9	STNP 264(R3), ZR, R7
+5559bd28|	plan9	STP.P (R21, R22), -24(R10)
+166c96a8|	plan9	STP.P (R22, R27), 352(R0)
+3d4a8729|	plan9	STP.W (R29, R18), 56(R17)
+912f86a9|	plan9	STP.W (R17, R11), 96(R28)
+c40d3029|	plan9	STP (R4, R3), -128(R14)
+f73f39a9|	plan9	STP (R23, R15), -112(RSP)
+34441eb8|	plan9	MOVW.P R20, -28(R1)
+11f60bf8|	plan9	MOVD.P R17, 191(R16)
+c15d15b8|	plan9	MOVW.W R1, -171(R14)
+ae4d12f8|	plan9	MOVD.W R14, -220(R13)
+03ef39b9|	plan9	MOVW R3, 14828(R24)
+208228f9|	plan9	MOVD R0, 20736(R17)
+ffb41838|	plan9	MOVB.P ZR, -117(R7)
+bb0d1a38|	plan9	MOVB.W R27, -96(R13)
+b1612239|	plan9	MOVB R17, 2200(R13)
+92682038|	plan9	MOVB R18, R0(R4)
+81682638|	plan9	MOVB R1, R6(R4)
+87841b78|	plan9	MOVH.P R7, -72(R4)
+cc3d1878|	plan9	MOVH.W R12, -125(R14)
+53cf1c79|	plan9	MOVH R19, 3686(R26)
+63792d78|	plan9	MOVH R3, R13<<1(R11)
+9d7803b8|	plan9	STTRW 55(R4), R29
+b9c807f8|	plan9	STTR 124(R5), R25
+f04a1e38|	plan9	STTRBW -28(R23), R16
+52990078|	plan9	STTRHW 9(R10), R18
+152002b8|	plan9	MOVW R21, 34(R0)
+397217f8|	plan9	MOVD R25, -137(R17)
+8f320138|	plan9	MOVB R15, 19(R20)
+eb021b78|	plan9	MOVH R11, -80(R23)
+854a3f88|	plan9	STXPW (R20), R18, R5, ZR
+d12620c8|	plan9	STXPW (R22), R9, R17, R0
+537e0288|	plan9	STXRW R19, (R18), R2
+af7d15c8|	plan9	STXR R15, (R13), R21
+e97c1d08|	plan9	STXRB R9, (R7), R29
+837d1b48|	plan9	STXRH R3, (R12), R27
+f25e344b|	plan9	SUBW R20.UXTW<<7, R23, R18
+3ac825cb|	plan9	SUB R5.SXTW<<2, R1, R26
+e8f40ccb|	plan9	SUB R12<<61, R7, R8
+a6ad226b|	plan9	SUBSW R2.SXTH<<3, R13, R6
+647735eb|	plan9	SUBS R21.UXTX<<5, R27, R4
+c770566b|	plan9	SUBSW R22>>28, R6, R7
+d03c1aeb|	plan9	SUBS R26<<15, R6, R16
+a17f03d4|	plan9	SVC $7165
+991f0013|	plan9	SXTBW R28, R25
+a91d4093|	plan9	SXTB R13, R9
+083d0013|	plan9	SXTHW R8, R8
+393e4093|	plan9	SXTH R17, R25
+1b7c4093|	plan9	SXTW R0, R27
+0c5b2cd5|	plan9	SYSL $285440, R12
+3f0d0172|	plan9	TSTW $2147483655, R9
+df6f7cf2|	plan9	TST $4294967280, R30
+1f2f11ea|	plan9	TST R17<<11, R24
+9ced71d3|	plan9	UBFX $49, R12, $11, R28
+1cbb7fd3|	plan9	UBFIZ $1, R24, $47, R28
+25e661d3|	plan9	UBFX $33, R17, $25, R5
+af0adc1a|	plan9	UDIVW R28, R21, R15
+550ac29a|	plan9	UDIV R2, R18, R21
+9102b19b|	plan9	UMADDL R17, R0, R20, R17
+41fea39b|	plan9	UMNEGL R3, R18, R1
+87d8a39b|	plan9	UMSUBL R3, R22, R4, R7
+987ed89b|	plan9	UMULH R24, R20, R24
+d37eb29b|	plan9	UMULL R18, R22, R19
+461c0053|	plan9	UXTBW R2, R6
+f43c0053|	plan9	UXTHW R7, R20
+5f2003d5|	plan9	WFE
+7f2003d5|	plan9	WFI
+3f2003d5|	plan9	YIELD
+e5bb200e|	plan9	VABS V31.B8, V5.B8
+c9842d0e|	plan9	VADD V13.B8, V6.B8, V9.B8
+f4bd394e|	plan9	VADDP V25.B16, V15.B16, V20.B16
+b3b8b14e|	plan9	ADDV V5.S4, F19
+cd5b284e|	plan9	VAESD V30.B16, V13.B16
+4b4b284e|	plan9	VAESE V26.B16, V11.B16
+2879284e|	plan9	VAESIMC V9.B16, V8.B16
+fe68284e|	plan9	VAESMC V7.B16, V30.B16
+f61e334e|	plan9	VAND V19.B16, V23.B16, V22.B16
+88a4002f|	plan9	VMVNI $(4<<8), V8.H4
+1877076f|	plan9	VBIC $(248<<24), V24.S4
+0d1e6c0e|	plan9	VBIC V12.B8, V16.B8, V13.B8
+b81ce26e|	plan9	VBIF V2.B16, V5.B16, V24.B16
+381cbf2e|	plan9	VBIT V31.B8, V1.B8, V24.B8
+cd1f6c6e|	plan9	VBSL V12.B16, V30.B16, V13.B16
+8d48a00e|	plan9	VCLS V4.S2, V13.S2
+324ba02e|	plan9	VCLZ V25.S2, V18.S2
+c88f2b2e|	plan9	VCMEQ V11.B8, V30.B8, V8.B8
+a799e05e|	plan9	CMEQ $0, F13, F7
+dc9be04e|	plan9	VCMEQ $0, V30.D2, V28.D2
+623f2d4e|	plan9	VCMGE V13.B16, V27.B16, V2.B16
+e889e06e|	plan9	VCMGE $0, V15.D2, V8.D2
+cb37e55e|	plan9	CMGT F5, F30, F11
+8e37b00e|	plan9	VCMGT V16.S2, V28.S2, V14.S2
+1a8be04e|	plan9	VCMGT $0, V24.D2, V26.D2
+7f37eb7e|	plan9	CMHI F11, F27, F31
+333d356e|	plan9	VCMHS V21.B16, V9.B16, V19.B16
+bd9ae07e|	plan9	CMLE $0, F21, F29
+8999602e|	plan9	VCMLE $0, V12.H4, V9.H4
+aca9e05e|	plan9	CMLT $0, F13, F12
+7fa8204e|	plan9	VCMLT $0, V3.B16, V31.B16
+588db20e|	plan9	VCMTST V18.S2, V10.S2, V24.S2
+cc051d5e|	plan9	VMOV V14.B[14], F12
+4c06050e|	plan9	VDUP V18.B[2], V12.B8
+790c020e|	plan9	VDUP R3, V25.H4
+391d286e|	plan9	VEOR V8.B16, V9.B16, V25.B16
+4b30156e|	plan9	VEXT $6, V21.B16, V2.B16, V11.B16
+44d6bf7e|	plan9	FABD F31, F18, F4
+17fba00e|	plan9	FABS V24.S2, V23.S2
+90c2201e|	plan9	FABSS F20, F16
+62c2601e|	plan9	FABSD F19, F2
+eeef3f7e|	plan9	FACGE F31, F31, F14
+09efa07e|	plan9	FACGT F0, F24, F9
+72edae6e|	plan9	VFACGT V14.S4, V11.S4, V18.S4
+61d5394e|	plan9	FADD V25.S4, V11.S4, V1.S4
+0d2a3d1e|	plan9	FADDS F29, F16, F13
+4b296f1e|	plan9	FADDD F15, F10, F11
+78d8307e|	plan9	FADDP V3.S2, F24
+e7d7322e|	plan9	VFADDP V18.S2, V31.S2, V7.S2
+e8253c1e|	plan9	FCCMPS HS, F28, F15, $8
+e8857f1e|	plan9	FCCMPD HI, F31, F15, $8
+5714291e|	plan9	FCCMPES NE, F9, F2, $7
+b484631e|	plan9	FCCMPED HI, F3, F5, $4
+3ce5685e|	plan9	FCMEQ F8, F9, F28
+50e6214e|	plan9	VFCMEQ V1.S4, V18.S4, V16.S4
+9ddae05e|	plan9	FCMEQ $0, F20, F29
+b3e62b7e|	plan9	FCMGE F11, F21, F19
+0ce4396e|	plan9	VFCMGE V25.S4, V0.S4, V12.S4
+a6c9e07e|	plan9	FCMGE $0, F13, F6
+ede6bd7e|	plan9	FCMGT F29, F23, F13
+13e6ae2e|	plan9	VFCMGT V14.S2, V16.S2, V19.S2
+4cc9e05e|	plan9	FCMGT $0, F10, F12
+41cba04e|	plan9	VFCMGT $0, V26.S4, V1.S4
+96d8e07e|	plan9	FCMLE $0, F4, F22
+0be9a05e|	plan9	FCMLT $0, F8, F11
+dfe9a04e|	plan9	VFCMLT $0, V14.S4, V31.S4
+a023301e|	plan9	FCMPS F16, F29
+68213e1e|	plan9	FCMPS $(0.0), F11
+20236d1e|	plan9	FCMPD F13, F25
+68216b1e|	plan9	FCMPD $(0.0), F11
+3023351e|	plan9	FCMPES F21, F25
+78203e1e|	plan9	FCMPES $(0.0), F3
+b022721e|	plan9	FCMPED F18, F21
+f8226f1e|	plan9	FCMPED $(0.0), F23
+b54e271e|	plan9	FCSELS MI, F21, F7, F21
+319f611e|	plan9	FCSELD LS, F25, F1, F17
+2142e21e|	plan9	FCVTHS F17, F1
+cfc3e21e|	plan9	FCVTHD F30, F15
+01c1231e|	plan9	FCVTSH F8, F1
+4fc0221e|	plan9	FCVTSD F2, F15
+f9c0631e|	plan9	FCVTDH F7, F25
+2b43621e|	plan9	FCVTDS F25, F11
+f1c8615e|	plan9	FCVTAS F7, F17
+ea01241e|	plan9	FCVTASW F15, R10
+0c02249e|	plan9	FCVTAS F16, R12
+e702641e|	plan9	FCVTASW F23, R7
+f501649e|	plan9	FCVTAS F15, R21
+45ca217e|	plan9	FCVTAU F18, F5
+66c9212e|	plan9	VFCVTAU V11.S2, V6.S2
+b302251e|	plan9	FCVTAUW F21, R19
+e102259e|	plan9	FCVTAU F23, R1
+5703651e|	plan9	FCVTAUW F26, R23
+2c01659e|	plan9	FCVTAU F9, R12
+2c7b210e|	plan9	VFCVTL V25.H4, V12.S4
+f478214e|	plan9	VFCVTL2 V7.H8, V20.S4
+d1b8615e|	plan9	FCVTMS F6, F17
+a2ba614e|	plan9	VFCVTMS V21.D2, V2.D2
+ee01301e|	plan9	FCVTMSW F15, R14
+de01309e|	plan9	FCVTMS F14, R30
+8401701e|	plan9	FCVTMSW F12, R4
+c502709e|	plan9	FCVTMS F22, R5
+44b8617e|	plan9	FCVTMU F2, F4
+5601311e|	plan9	FCVTMUW F10, R22
+4602319e|	plan9	FCVTMU F18, R6
+1003711e|	plan9	FCVTMUW F24, R16
+e602719e|	plan9	FCVTMU F23, R6
+c16b210e|	plan9	VFCVTN V30.S4, V1.H4
+4d6b614e|	plan9	VFCVTN2 V26.D2, V13.S4
+95ab215e|	plan9	FCVTNS F28, F21
+65a9614e|	plan9	VFCVTNS V11.D2, V5.D2
+8a02201e|	plan9	FCVTNSW F20, R10
+bc03209e|	plan9	FCVTNS F29, R28
+fc01601e|	plan9	FCVTNSW F15, R28
+9800609e|	plan9	FCVTNS F4, R24
+b1aa617e|	plan9	FCVTNU F21, F17
+80a9216e|	plan9	VFCVTNU V12.S4, V0.S4
+3201211e|	plan9	FCVTNUW F9, R18
+e101219e|	plan9	FCVTNU F15, R1
+ae00611e|	plan9	FCVTNUW F5, R14
+9503619e|	plan9	FCVTNU F28, R21
+3faae15e|	plan9	FCVTPS F17, F31
+c4a8e14e|	plan9	VFCVTPS V6.D2, V4.D2
+ab01281e|	plan9	FCVTPSW F13, R11
+5800289e|	plan9	FCVTPS F2, R24
+9b02681e|	plan9	FCVTPSW F20, R27
+de03689e|	plan9	FCVTPS F30, R30
+d8aaa17e|	plan9	FCVTPU F22, F24
+e203291e|	plan9	FCVTPUW F31, R2
+5302299e|	plan9	FCVTPU F18, R19
+5302691e|	plan9	FCVTPUW F18, R19
+8501699e|	plan9	FCVTPU F12, R5
+93ff735f|	plan9	FCVTZS $13, F28, F19
+b7fd504f|	plan9	FCVTZS $48, V13.D2, V23.D2
+7ebba15e|	plan9	FCVTZSSS F27, F30
+d49f181e|	plan9	FCVTZS $25, F30, R20
+538d189e|	plan9	FCVTZS $29, F10, R19
+7e74589e|	plan9	FCVTZS $35, F3, R30
+4300381e|	plan9	FCVTZSSW F2, R3
+bc03389e|	plan9	FCVTZSS F29, R28
+c702781e|	plan9	FCVTZSDW F22, R7
+0401789e|	plan9	FCVTZSD F8, R4
+d1ff2e7f|	plan9	FCVTZU $18, F30, F17
+d0fd3b2f|	plan9	FCVTZU $5, V14.S2, V16.S2
+70bae17e|	plan9	FCVTZUDD F19, F16
+3ef6191e|	plan9	FCVTZU $3, F17, R30
+cae7199e|	plan9	FCVTZU $7, F30, R10
+cffb599e|	plan9	FCVTZU $2, F30, R15
+e402391e|	plan9	FCVTZUSW F23, R4
+1a03399e|	plan9	FCVTZUS F24, R26
+0401791e|	plan9	FCVTZUDW F8, R4
+c200799e|	plan9	FCVTZUD F6, R2
+ebfe346e|	plan9	FDIV V20.S4, V23.S4, V11.S4
+c918371e|	plan9	FDIVS F23, F6, F9
+911a7f1e|	plan9	FDIVD F31, F20, F17
+a81f0c1f|	plan9	FMADD F7, F12, F29, F8
+d0404a1f|	plan9	FMADD F16, F10, F6, F16
+7ff6324e|	plan9	FMAX V18.S4, V19.S4, V31.S4
+b84b351e|	plan9	FMAXS F21, F29, F24
+d64b621e|	plan9	FMAXD F2, F30, F22
+016b241e|	plan9	FMAXNMS F4, F24, F1
+5b69781e|	plan9	FMAXNMD F24, F10, F27
+f1c8707e|	plan9	FMAXNMP V7.D2, F17
+27c5306e|	plan9	VFMAXNMP V16.S4, V9.S4, V7.S4
+aef8707e|	plan9	FMAXP V5.D2, F14
+53f6202e|	plan9	VFMAXP V0.S2, V18.S2, V19.S2
+78fb306e|	plan9	FMAXV V27.S4, F24
+5af4ec4e|	plan9	FMIN V12.D2, V2.D2, V26.D2
+505a3c1e|	plan9	FMINS F28, F18, F16
+4858661e|	plan9	FMIND F6, F2, F8
+a9c6e04e|	plan9	FMINNM V0.D2, V21.D2, V9.D2
+987b311e|	plan9	FMINNMS F17, F28, F24
+95796f1e|	plan9	FMINNMD F15, F12, F21
+f5cbb07e|	plan9	FMINNMP V31.S2, F21
+b0f8f07e|	plan9	FMINP V5.D2, F16
+8bf5a42e|	plan9	VFMINP V4.S2, V12.S2, V11.S2
+87cd384e|	plan9	VFMLA V24.S4, V12.S4, V7.S4
+fd50db5f|	plan9	FMLS V27.D[0], F7, F29
+d1ccb44e|	plan9	VFMLS V20.S4, V6.S4, V17.S4
+ebf5064f|	plan9	FMOV $-0.242188, V11.S4
+49f4056f|	plan9	FMOV $-9., V9.D2
+0940201e|	plan9	FMOVS F0, F9
+db43601e|	plan9	FMOVD F30, F27
+a901271e|	plan9	FMOVS R13, F9
+3702261e|	plan9	FMOVS F17, R23
+4d02679e|	plan9	FMOVD R18, F13
+9d02af9e|	plan9	FMOV R20, V29.D[1]
+ef03669e|	plan9	FMOVD F31, R15
+7101ae9e|	plan9	FMOV V11.D[1], R17
+0e103d1e|	plan9	FMOVS $-0.75, F14
+1e50761e|	plan9	FMOVD $-18., F30
+d2b4121f|	plan9	FMSUB F13, F18, F6, F18
+0a9c4c1f|	plan9	FMSUB F7, F12, F0, F10
+0d99b35f|	plan9	FMULS V19.S[3], F8, F13
+a89b9b0f|	plan9	FMUL V27.S[2], V29.S2, V8.S2
+75dc376e|	plan9	FMUL V23.S4, V3.S4, V21.S4
+7909241e|	plan9	FMULS F4, F11, F25
+d7096b1e|	plan9	FMULD F11, F14, F23
+2999ab7f|	plan9	FMULX V11.S[3], F9, F9
+35dd6d5e|	plan9	FMULX F13, F9, F21
+c8dc284e|	plan9	VFMULX V8.S4, V6.S4, V8.S4
+c043211e|	plan9	FNEGS F30, F0
+4742611e|	plan9	FNEGD F18, F7
+9c51251f|	plan9	FNMADD F20, F5, F12, F28
+e407771f|	plan9	FNMADD F1, F23, F31, F4
+fbfa3a1f|	plan9	FNMSUB F30, F26, F23, F27
+bbb0691f|	plan9	FNMSUB F12, F9, F5, F27
+6a8b3f1e|	plan9	FNMULS F31, F27, F10
+1a8b751e|	plan9	FNMULD F21, F24, F26
+57d8e15e|	plan9	FRECPE F2, F23
+62dba14e|	plan9	VFRECPE V27.S4, V2.S4
+81fd325e|	plan9	FRECPS F18, F12, F1
+31fe224e|	plan9	VFRECPS V2.S4, V17.S4, V17.S4
+ecf9e15e|	plan9	FRECPX F15, F12
+c18b216e|	plan9	FRINTA V30.S4, V1.S4
+0240261e|	plan9	FRINTAS F0, F2
+8041661e|	plan9	FRINTAD F12, F0
+c89ba12e|	plan9	FRINTI V30.S2, V8.S2
+2ec2271e|	plan9	FRINTIS F17, F14
+5cc0671e|	plan9	FRINTID F2, F28
+3898210e|	plan9	FRINTM V1.S2, V24.S2
+9843251e|	plan9	FRINTMS F28, F24
+5b40651e|	plan9	FRINTMD F2, F27
+2189614e|	plan9	FRINTN V9.D2, V1.D2
+7e42241e|	plan9	FRINTNS F19, F30
+5d40641e|	plan9	FRINTND F2, F29
+85c3241e|	plan9	FRINTPS F28, F5
+46c2641e|	plan9	FRINTPD F18, F6
+c39b216e|	plan9	FRINTX V30.S4, V3.S4
+a243271e|	plan9	FRINTXS F29, F2
+1d41671e|	plan9	FRINTXD F8, F29
+5499e14e|	plan9	FRINTZ V10.D2, V20.D2
+92c2251e|	plan9	FRINTZS F20, F18
+75c2651e|	plan9	FRINTZD F19, F21
+ddd9e17e|	plan9	FRSQRTE F14, F29
+60fff85e|	plan9	FRSQRTS F24, F27, F0
+dafffb4e|	plan9	VFRSQRTS V27.D2, V30.D2, V26.D2
+1ff9a12e|	plan9	FSQRT V8.S2, V31.S2
+2dc3211e|	plan9	FSQRTS F25, F13
+72c0611e|	plan9	FSQRTD F3, F18
+7d3a3e1e|	plan9	FSUBS F30, F19, F29
+3f38771e|	plan9	FSUBD F23, F1, F31
+185e016e|	plan9	VMOV V16.B[11], V24.B[0]
+911d0d4e|	plan9	VMOV R12, V17.B[6]
+2877400c|	plan9	VLD1 (R25), [V8.H4]
+8ea8404c|	plan9	VLD1 (R4), [V14.S4, V15.S4]
+0f62404c|	plan9	VLD1 (R16), [V15.B16, V16.B16, V17.B16]
+0f27400c|	plan9	VLD1 (R24), [V15.H4, V16.H4, V17.H4, V18.H4]
+4c75df0c|	plan9	VLD1.P 8(R10), [V12.H4]
+2f7bd04c|	plan9	VLD1.P (R25)(R16), [V15.S4]
+eaaadf0c|	plan9	VLD1.P 16(R23), [V10.S2, V11.S2]
+eca7cc4c|	plan9	VLD1.P (RSP)(R12), [V12.H8, V13.H8]
+cd60df4c|	plan9	VLD1.P 48(R6), [V13.B16, V14.B16, V15.B16]
+9163df0c|	plan9	VLD1.P 24(R28), [V17.B8, V18.B8, V19.B8]
+152ddf4c|	plan9	VLD1.P 64(R8), [V21.D2, V22.D2, V23.D2, V24.D2]
+0725c04c|	plan9	VLD1.P (R8)(R0), [V7.H8, V8.H8, V9.H8, V10.H8]
+7c04404d|	plan9	LD1 (R3), [V28.B][9]
+6d49404d|	plan9	LD1 (R11), [V13.H][5]
+9e81400d|	plan9	LD1 (R12), [V30.S][0]
+d384404d|	plan9	LD1 (R6), [V19.D][1]
+b20ddf4d|	plan9	LD1.P 1(R13), [V18.B][11]
+f114cd4d|	plan9	LD1.P (R7)(R13), [V17.B][13]
+bb92df4d|	plan9	LD1.P 4(R21), [V27.S][3]
+a883d64d|	plan9	LD1.P (R29)(R22), [V8.S][2]
+f584df4d|	plan9	LD1.P 8(R7), [V21.D][1]
+0284c80d|	plan9	LD1.P (R0)(R8), [V2.D][0]
+91c3400d|	plan9	VLD1R (R28), [V17.B8]
+71c9df0d|	plan9	VLD1R 4(R11), [V17.S2]
+e7c4db0d|	plan9	VLD1R (R7)(R27), [V7.H4]
+b787404c|	plan9	VLD2 (R29), [V23.H8, V24.H8]
+1280df0c|	plan9	VLD2 16(R0), [V18.B8, V19.B8]
+2f88c10c|	plan9	VLD2 (R1)(R1), [V15.S2, V16.S2]
+a01e604d|	plan9	LD2 (R21), [V0.B, V1.B][15]
+eb82604d|	plan9	LD2 (R23), [V11.S, V12.S][2]
+f985600d|	plan9	LD2 (R15), [V25.D, V26.D][0]
+e315ff0d|	plan9	LD2 2(R15), [V3.B, V4.B][5]
+1c11f24d|	plan9	LD2 (R8)(R18), [V28.B, V29.B][12]
+f341ef4d|	plan9	LD2 (R15)(R15), [V19.H, V20.H][4]
+5a80ff4d|	plan9	LD2 8(R2), [V26.S, V27.S][2]
+d781fd0d|	plan9	LD2 (R14)(R29), [V23.S, V24.S][0]
+c885ff0d|	plan9	LD2 16(R14), [V8.D, V9.D][0]
+1286f34d|	plan9	LD2 (R16)(R19), [V18.D, V19.D][1]
+06c2600d|	plan9	VLD2R (R16), [V6.B8, V7.B8]
+95c7ff4d|	plan9	VLD2R 4(R28), [V21.H8, V22.H8]
+d4c1e14d|	plan9	VLD2R (R14)(R1), [V20.B16, V21.B16]
+eb4bdf4c|	plan9	VLD3 48(RSP), [V11.S4, V12.S4, V13.S4]
+ce4fc24c|	plan9	VLD3 (R30)(R2), [V14.D2, V15.D2, V16.D2]
+db23400d|	plan9	LD3 (R30), [V27.B, V28.B, V29.B][0]
+26b3400d|	plan9	LD3 (R25), [V6.S, V7.S, V8.S][1]
+37a4400d|	plan9	LD3 (R1), [V23.D, V24.D, V25.D][0]
+052edf4d|	plan9	LD3 3(R16), [V5.B, V6.B, V7.B][11]
+8c3ccd0d|	plan9	LD3 (R4)(R13), [V12.B, V13.B, V14.B][7]
+74b0df4d|	plan9	LD3 12(R3), [V20.S, V21.S, V22.S][3]
+b7b1c84d|	plan9	LD3 (R13)(R8), [V23.S, V24.S, V25.S][3]
+e6a5df4d|	plan9	LD3 24(R15), [V6.D, V7.D, V8.D][1]
+42a5c80d|	plan9	LD3 (R10)(R8), [V2.D, V3.D, V4.D][0]
+9ceb400d|	plan9	VLD3R (R28), [V28.S2, V29.S2, V30.S2]
+6aeadf4d|	plan9	VLD3R 12(R19), [V10.S4, V11.S4, V12.S4]
+65ebce4d|	plan9	VLD3R (R27)(R14), [V5.S4, V6.S4, V7.S4]
+ea05400c|	plan9	VLD4 (R15), [V10.H4, V11.H4, V12.H4, V13.H4]
+1f03df0c|	plan9	VLD4 32(R24), [V31.B8, V0.B8, V1.B8, V2.B8]
+ae09c90c|	plan9	VLD4 (R13)(R9), [V14.S2, V15.S2, V16.S2, V17.S2]
+fd3a604d|	plan9	LD4 (R23), [V29.B, V30.B, V31.B, V0.B][14]
+d8a0604d|	plan9	LD4 (R6), [V24.S, V25.S, V26.S, V27.S][2]
+62a4604d|	plan9	LD4 (R3), [V2.D, V3.D, V4.D, V5.D][1]
+712fff0d|	plan9	LD4 4(R27), [V17.B, V18.B, V19.B, V20.B][3]
+aa27f40d|	plan9	LD4 (R29)(R20), [V10.B, V11.B, V12.B, V13.B][1]
+be71ff4d|	plan9	LD4 8(R13), [V30.H, V31.H, V0.H, V1.H][6]
+e360ee4d|	plan9	LD4 (R7)(R14), [V3.H, V4.H, V5.H, V6.H][4]
+c0a0ff0d|	plan9	LD4 16(R6), [V0.S, V1.S, V2.S, V3.S][0]
+d3a3e00d|	plan9	LD4 (R30)(R0), [V19.S, V20.S, V21.S, V22.S][0]
+95a7ff0d|	plan9	LD4 32(R28), [V21.D, V22.D, V23.D, V24.D][0]
+32a6e14d|	plan9	LD4 (R17)(R1), [V18.D, V19.D, V20.D, V21.D][1]
+56e0604d|	plan9	VLD4R (R2), [V22.B16, V23.B16, V24.B16, V25.B16]
+dce7ff0d|	plan9	VLD4R 8(R30), [V28.H4, V29.H4, V30.H4, V31.H4]
+14e8ef0d|	plan9	VLD4R (R0)(R15), [V20.S2, V21.S2, V22.S2, V23.S2]
+7776732c|	plan9	LDNP -104(R19), F29, F23
+23dd746c|	plan9	LDNP -184(R9), F23, F3
+383e48ac|	plan9	LDNP 256(R17), V15, V24
+0d10c12c|	plan9	LDP.P 8(R0), (F13, F4)
+fe3ae66c|	plan9	LDP.P -416(R23), (F30, F14)
+f627f9ac|	plan9	LDP.P -224(RSP), (V22, V9)
+918cd82d|	plan9	LDP.W 196(R4), (F17, F3)
+986be46d|	plan9	LDP.W -448(R28), (F24, F26)
+ebd8f8ad|	plan9	LDP.W -240(R7), (V11, V22)
+3c905c2d|	plan9	LDP 228(R1), (F28, F4)
+5887536d|	plan9	LDP 312(R26), (F24, F1)
+08957cad|	plan9	LDP -112(R8), (V8, V5)
+c5e5543c|	plan9	MOVD.P -178(R14), F5
+4ff5417c|	plan9	MOVD.P 31(R10), F15
+72e54bbc|	plan9	MOVD.P 190(R11), F18
+16b55dfc|	plan9	MOVD.P -37(R8), F22
+9e24db3c|	plan9	MOVD.P -78(R4), V30
+d20c503c|	plan9	MOVD.W -256(R6), F18
+1f1c4d7c|	plan9	MOVD.W 209(R0), F31
+2fbf4dbc|	plan9	MOVD.W 219(R25), F15
+a06c59fc|	plan9	MOVD.W -106(R5), F0
+886ddd3c|	plan9	MOVD.W -42(R12), V8
+58f64e3d|	plan9	MOVD 957(R18), F24
+f5c3547d|	plan9	MOVD 2656(RSP), F21
+8e8a7bbd|	plan9	MOVD 15240(R20), F14
+8e3c7afd|	plan9	MOVD 29816(R4), F14
+f2aeff3d|	plan9	MOVD 65200(R23), V18
+1d78793c|	plan9	MOVD R25<<1(R0), F29
+b8f15d3c|	plan9	LDUR -33(R13), F24
+95635c7c|	plan9	LDUR -58(R28), F21
+27d046bc|	plan9	LDUR 109(R1), F7
+21624efc|	plan9	LDUR 230(R17), F1
+6dd2d83c|	plan9	LDUR -115(R19), V13
+dc09be6f|	plan9	VMLA V30.S[3], V14.S4, V28.S4
+eb97af4e|	plan9	VMLA V15.S4, V31.S4, V11.S4
+0495722e|	plan9	VMLS V18.H4, V8.H4, V4.H4
+21070a5e|	plan9	VMOV V25.H[2], F1
+92471b6e|	plan9	VMOV V28.B[8], V18.B[13]
+7a1e134e|	plan9	VMOV R19, V26.B[9]
+761fa30e|	plan9	VORR V3.B8, V27.B8, V22.B8
+f23d070e|	plan9	UMOVW V15.B[3], R18
+a5e6064f|	plan9	VMOVI $213, V5.B16
+63c5064f|	plan9	VMOVI $(203<<136), V3.S4
+bca7014f|	plan9	VMOVI $(61<<8), V28.H8
+95e4040f|	plan9	VMOVI $132, V21.B8
+fce4072f|	plan9	MOVI $-1099494850561, F28
+24e6036f|	plan9	VMOVI $72057589742960895, V4.D2
+429d6a4e|	plan9	VMUL V10.H8, V10.H8, V2.H8
+e558202e|	plan9	VMVN V7.B8, V5.B8
+fe65012f|	plan9	VMVNI $(47<<24), V30.S2
+2b16046f|	plan9	VBIC $145, V11.S4
+7756016f|	plan9	VBIC $(51<<16), V23.S4
+e159202e|	plan9	VMVN V15.B8, V1.B8
+da1cf14e|	plan9	VORN V17.B16, V6.B16, V26.B16
+ca04014f|	plan9	VMOVI $38, V10.S4
+14a6020f|	plan9	VMOVI $(80<<8), V20.H4
+2f1fbf0e|	plan9	VORR V31.B8, V25.B8, V15.B8
+74e2f20e|	plan9	VPMULL V18.D1, V19.D1, V20.Q1
+2740262e|	plan9	VRADDHN V6.H8, V1.H8, V7.B8
+17412e6e|	plan9	VRADDHN2 V14.H8, V8.H8, V23.B16
+da59602e|	plan9	VRBIT V14.B8, V26.B8
+230a604e|	plan9	VREV64 V17.H8, V3.H8
+178d210f|	plan9	VRSHRN $31, V8.D2, V23.S2
+6b8d2c4f|	plan9	VRSHRN2 $20, V11.D2, V11.S4
+b57c2a0e|	plan9	VSABA V10.B8, V5.B8, V21.B8
+71533d0e|	plan9	VSABAL V29.B8, V27.B8, V17.H8
+1c50774e|	plan9	VSABAL2 V23.H8, V0.H8, V28.S4
+1974be4e|	plan9	VSABD V30.S4, V0.S4, V25.S4
+6b71ad0e|	plan9	VSABDL V13.S2, V11.S2, V11.D2
+5270324e|	plan9	VSABDL2 V18.B16, V2.B16, V18.H8
+366b200e|	plan9	VSADALP V25.B8, V22.H4
+1802680e|	plan9	VSADDL V8.H4, V16.H4, V24.S4
+022b604e|	plan9	VSADDLP V24.H8, V2.S4
+413ab04e|	plan9	SADDLV V18.S4, F1
+4013750e|	plan9	VSADDW V21.H4, V26.S4, V0.S4
+4412744e|	plan9	VSADDW2 V20.H8, V18.S4, V4.S4
+2ee6255f|	plan9	SCVTF $27, F17, F14
+dce75f4f|	plan9	SCVTF $33, V30.D2, V28.D2
+5bdb615e|	plan9	SCVTFDD F26, F27
+3ad9210e|	plan9	SCVTF V9.S2, V26.S2
+1ceb421e|	plan9	SCVTF $6, R24, F28
+9dde029e|	plan9	SCVTF $9, R20, F29
+57d1429e|	plan9	SCVTF $12, R10, F23
+d600221e|	plan9	SCVTFWS R6, F22
+c503621e|	plan9	SCVTFWD R30, F5
+3303229e|	plan9	SCVTFS R25, F19
+0003629e|	plan9	SCVTFD R24, F0
+6f01075e|	plan9	SHA1C V7.S4, F11, V15
+9308285e|	plan9	SHA1H F4, F19
+b420105e|	plan9	SHA1M V16.S4, F5, V20
+f4131f5e|	plan9	SHA1P V31.S4, F31, V20
+dc311f5e|	plan9	VSHA1SU0 V31.S4, V14.S4, V28.S4
+bb1a285e|	plan9	VSHA1SU1 V21.S4, V27.S4
+2753075e|	plan9	SHA256H2 V7.S4, V25, V7
+3141065e|	plan9	SHA256H V6.S4, V9, V17
+172b285e|	plan9	VSHA256SU0 V24.S4, V23.S4
+bb621b5e|	plan9	VSHA256SU1 V27.S4, V21.S4, V27.S4
+7005644e|	plan9	VSHADD V4.H8, V11.H8, V16.H8
+2d870e0f|	plan9	VSHRN $2, V25.H8, V13.B8
+ac86024f|	plan9	VMOVI $85, V12.H8
+1c26a50e|	plan9	VSHSUB V5.S2, V16.S2, V28.S2
+db576b6f|	plan9	VSLI $43, V30.D2, V27.D2
+c3652c4e|	plan9	VSMAX V12.B16, V14.B16, V3.B16
+b5a7ab0e|	plan9	VSMAXP V11.S2, V29.S2, V21.S2
+f1aeb34e|	plan9	VSMINP V19.S4, V23.S4, V17.S4
+87a8b14e|	plan9	SMINV V4.S4, F7
+1e21bc4f|	plan9	VSMLAL2 V28.S[1], V8.S4, V30.D2
+50a33a0e|	plan9	VSMLSL V26.B8, V26.B8, V16.H8
+4e2d1a0e|	plan9	SMOVW V10.H[6], R14
+9ba9b30f|	plan9	VSMULL V19.S[3], V12.S2, V27.D2
+417a205e|	plan9	SQABS F18, F1
+9f78a04e|	plan9	VSQABS V4.S4, V31.S4
+580d2e5e|	plan9	SQADD F14, F10, F24
+3d30764f|	plan9	VSQDMLAL2 V6.H[3], V1.H8, V29.S4
+9591b25e|	plan9	SQDMLAL F18, F12, F21
+0d92670e|	plan9	VSQDMLAL V7.H4, V16.H4, V13.S4
+90b1765e|	plan9	SQDMLSL F22, F12, F16
+83c2ad5f|	plan9	SQDMULH V13.S[1], F20, F3
+bbb7aa5e|	plan9	SQDMULH F10, F29, F27
+c8b99a5f|	plan9	SQDMULL V26.S[2], F14, F8
+75b3920f|	plan9	VSQDMULL V18.S[0], V27.S2, V21.D2
+86d1b75e|	plan9	SQDMULL F23, F12, F6
+edd06f4e|	plan9	VSQDMULL2 V15.H8, V7.H8, V13.S4
+0f7ae07e|	plan9	SQNEG F16, F15
+e87b602e|	plan9	VSQNEG V31.H4, V8.H4
+ecb5a92e|	plan9	VSQRDMULH V9.S2, V15.S2, V12.S2
+d75fba5e|	plan9	SQRSHL F26, F30, F23
+f75f324e|	plan9	VSQRSHL V18.B16, V31.B16, V23.B16
+af9c114f|	plan9	VSQRSHRN2 $15, V5.S4, V15.H8
+318d2f6f|	plan9	VSQRSHRUN2 $17, V9.D2, V17.S4
+b3757c5f|	plan9	SQSHL $60, F13, F19
+0c776f4f|	plan9	VSQSHL $47, V24.D2, V12.D2
+d84c2a5e|	plan9	SQSHL F10, F6, F24
+ae4e704e|	plan9	VSQSHL V16.H8, V21.H8, V14.H8
+b566727f|	plan9	SQSHLU $50, F21, F21
+4566596f|	plan9	VSQSHLU $25, V18.D2, V5.D2
+d595140f|	plan9	VSQSHRN $12, V14.S4, V21.H4
+00940b4f|	plan9	VSQSHRN2 $5, V0.H8, V0.B16
+5384352f|	plan9	VSQSHRUN $11, V2.D2, V19.S2
+1a2e3d5e|	plan9	SQSUB F29, F16, F26
+b02e6b4e|	plan9	VSQSUB V11.H8, V21.H8, V16.H8
+1249a15e|	plan9	SQXTN F8, F18
+eb49610e|	plan9	VSQXTN V15.S4, V11.H4
+cb4a614e|	plan9	VSQXTN2 V22.S4, V11.H8
+102b217e|	plan9	SQXTUN F24, F16
+492a212e|	plan9	VSQXTUN V18.H8, V9.B8
+112a616e|	plan9	VSQXTUN2 V16.S4, V17.H8
+6c16ae4e|	plan9	VSRHADD V14.S4, V19.S4, V12.S4
+5946467f|	plan9	SRI $58, F18, F25
+21460a2f|	plan9	VSRI $6, V17.B8, V1.B8
+9f56b10e|	plan9	VSRSHL V17.S2, V20.S2, V31.S2
+e724635f|	plan9	SRSHR $29, F7, F7
+e8266b4f|	plan9	VSRSHR $21, V23.D2, V8.D2
+2b37180f|	plan9	VSRSRA $8, V25.H4, V11.H4
+1644f95e|	plan9	SSHL F25, F0, F22
+3644fc4e|	plan9	VSSHL V28.D2, V1.D2, V22.D2
+d9a61f4f|	plan9	VSSHLL2 $15, V22.H8, V25.S4
+9b075e5f|	plan9	SSHR $34, F28, F27
+2c044c4f|	plan9	VSSHR $52, V1.D2, V12.D2
+d915324f|	plan9	VSSRA $14, V14.S4, V25.S4
+de21260e|	plan9	VSSUBL V6.B8, V14.B8, V30.H8
+c720254e|	plan9	VSSUBL2 V5.B16, V6.B16, V7.H8
+9d33b90e|	plan9	VSSUBW V25.S2, V28.D2, V29.D2
+7e71000c|	plan9	VST1 (R11), [V30.B8]
+cca6000c|	plan9	VST1 (R22), [V12.H4, V13.H4]
+5467000c|	plan9	VST1 (R26), [V20.H4, V21.H4, V22.H4]
+cc28004c|	plan9	VST1 (R6), [V12.S4, V13.S4, V14.S4, V15.S4]
+9e7e9f4c|	plan9	VST1 16(R20), [V30.D2]
+4b769d0c|	plan9	VST1 (R18)(R29), [V11.H4]
+adaa9f0c|	plan9	VST1 16(R21), [V13.S2, V14.S2]
+bca7844c|	plan9	VST1 (R29)(R4), [V28.H8, V29.H8]
+b5659f0c|	plan9	VST1 24(R13), [V21.H4, V22.H4, V23.H4]
+e669874c|	plan9	VST1 (R15)(R7), [V6.S4, V7.S4, V8.S4]
+9b2a9f0c|	plan9	VST1 32(R20), [V27.S2, V28.S2, V29.S2, V30.S2]
+14278b0c|	plan9	VST1 (R24)(R11), [V20.H4, V21.H4, V22.H4, V23.H4]
+d002004d|	plan9	ST1 (R22), [V16.B][8]
+9780004d|	plan9	ST1 (R4), [V23.S][2]
+7787004d|	plan9	ST1 (R27), [V23.D][1]
+850d9f0d|	plan9	ST1 1(R12), [V5.B][3]
+7b1f8f0d|	plan9	ST1 (R27)(R15), [V27.B][7]
+7a5a9f4d|	plan9	ST1 2(R19), [V26.H][7]
+e14b9e4d|	plan9	ST1 (RSP)(R30), [V1.H][5]
+dd819f4d|	plan9	ST1 4(R14), [V29.S][2]
+a281910d|	plan9	ST1 (R13)(R17), [V2.S][0]
+b2849f0d|	plan9	ST1 8(R5), [V18.D][0]
+c484964d|	plan9	ST1 (R6)(R22), [V4.D][1]
+f686004c|	plan9	VST2 (R23), [V22.H8, V23.H8]
+2e869f0c|	plan9	VST2 16(R17), [V14.H4, V15.H4]
+d200200d|	plan9	ST2 (R6), [V18.B, V19.B][0]
+ab58200d|	plan9	ST2 (R5), [V11.H, V12.H][3]
+c491204d|	plan9	ST2 (R14), [V4.S, V5.S][3]
+5a85204d|	plan9	ST2 (R10), [V26.D, V27.D][1]
+f217bf0d|	plan9	ST2 2(RSP), [V18.B, V19.B][5]
+2b0ea04d|	plan9	ST2 (R17)(R0), [V11.B, V12.B][11]
+4042bf0d|	plan9	ST2 4(R18), [V0.H, V1.H][0]
+9342af4d|	plan9	ST2 (R20)(R15), [V19.H, V20.H][4]
+9b91bf4d|	plan9	ST2 8(R12), [V27.S, V28.S][3]
+7480a10d|	plan9	ST2 (R3)(R1), [V20.S, V21.S][0]
+c884bf0d|	plan9	ST2 16(R6), [V8.D, V9.D][0]
+ae86ac4d|	plan9	ST2 (R21)(R12), [V14.D, V15.D][1]
+614d004c|	plan9	VST3 (R11), [V1.D2, V2.D2, V3.D2]
+324b9f4c|	plan9	VST3 48(R25), [V18.S4, V19.S4, V20.S4]
+7340870c|	plan9	VST3 (R3)(R7), [V19.B8, V20.B8, V21.B8]
+ac24004d|	plan9	ST3 (R5), [V12.B, V13.B, V14.B][9]
+a161004d|	plan9	ST3 (R13), [V1.H, V2.H, V3.H][4]
+09b1004d|	plan9	ST3 (R8), [V9.S, V10.S, V11.S][3]
+78a7004d|	plan9	ST3 (R27), [V24.D, V25.D, V26.D][1]
+4f349f0d|	plan9	ST3 3(R2), [V15.B, V16.B, V17.B][5]
+643d840d|	plan9	ST3 (R11)(R4), [V4.B, V5.B, V6.B][7]
+48699f0d|	plan9	ST3 6(R10), [V8.H, V9.H, V10.H][1]
+85b19f4d|	plan9	ST3 12(R12), [V5.S, V6.S, V7.S][3]
+60a18a0d|	plan9	ST3 (R11)(R10), [V0.S, V1.S, V2.S][0]
+69a49f0d|	plan9	ST3 24(R3), [V9.D, V10.D, V11.D][0]
+ada7814d|	plan9	ST3 (R29)(R1), [V13.D, V14.D, V15.D][1]
+760c004c|	plan9	VST4 (R3), [V22.D2, V23.D2, V24.D2, V25.D2]
+ee0d9f4c|	plan9	VST4 64(R15), [V14.D2, V15.D2, V16.D2, V17.D2]
+7800970c|	plan9	VST4 (R3)(R23), [V24.B8, V25.B8, V26.B8, V27.B8]
+a221200d|	plan9	ST4 (R13), [V2.B, V3.B, V4.B, V5.B][0]
+9a69204d|	plan9	ST4 (R12), [V26.H, V27.H, V28.H, V29.H][5]
+02a1204d|	plan9	ST4 (R8), [V2.S, V3.S, V4.S, V5.S][2]
+3fa6200d|	plan9	ST4 (R17), [V31.D, V0.D, V1.D, V2.D][0]
+943abf0d|	plan9	ST4 4(R20), [V20.B, V21.B, V22.B, V23.B][6]
+bf26a60d|	plan9	ST4 (R21)(R6), [V31.B, V0.B, V1.B, V2.B][1]
+55b3bf4d|	plan9	ST4 16(R26), [V21.S, V22.S, V23.S, V24.S][3]
+dda1b04d|	plan9	ST4 (R14)(R16), [V29.S, V30.S, V31.S, V0.S][2]
+6aa5bf0d|	plan9	ST4 32(R11), [V10.D, V11.D, V12.D, V13.D][0]
+e7a7ac0d|	plan9	ST4 (RSP)(R12), [V7.D, V8.D, V9.D, V10.D][0]
+f9c9202c|	plan9	STNP -252(R15), F18, F25
+18b8316c|	plan9	STNP -232(R0), F14, F24
+409c1cac|	plan9	STNP 912(R2), V7, V0
+73f0812c|	plan9	STP.P (F19, F28), 12(R3)
+28d0826c|	plan9	STP.P (F8, F20), 40(R1)
+9bf5bfac|	plan9	STP.P (V27, V29), -16(R12)
+885ead2d|	plan9	STP.W (F8, F23), -152(R20)
+b0de926d|	plan9	STP.W (F16, F23), 296(R21)
+713387ad|	plan9	STP.W (V17, V12), 224(R27)
+52130a2d|	plan9	STP (F18, F4), 80(R26)
+b63a236d|	plan9	STP (F22, F14), -464(R21)
+6d5424ad|	plan9	STP (V13, V21), -896(R3)
+afb60f3c|	plan9	MOVD.P F15, 251(R21)
+81e7077c|	plan9	MOVD.P F1, 126(R28)
+203713bc|	plan9	MOVD.P F0, -205(R25)
+60c61ffc|	plan9	MOVD.P F0, -4(R19)
+d256813c|	plan9	MOVD.P V18, 21(R22)
+ffce083c|	plan9	MOVD.W F31, 140(R23)
+6d3d017c|	plan9	MOVD.W F13, 19(R11)
+52ed01bc|	plan9	MOVD.W F18, 30(R10)
+fafd11fc|	plan9	MOVD.W F26, -225(R15)
+663e9b3c|	plan9	MOVD.W V6, -77(R19)
+7d0c393d|	plan9	MOVD F29, 3651(R3)
+8f50067d|	plan9	MOVD F15, 808(R4)
+94680dbd|	plan9	MOVD F20, 3432(R4)
+b7673bfd|	plan9	MOVD F23, 30408(R29)
+fed3a63d|	plan9	MOVD V30, 39744(RSP)
+8a6a243c|	plan9	MOVD F10, R4(R20)
+c768a93c|	plan9	MOVD V7, R9(R6)
+a7b00a3c|	plan9	MOVD F7, 171(R5)
+40e3107c|	plan9	MOVD F0, -242(R26)
+18911fbc|	plan9	MOVD F24, -7(R8)
+fcc007fc|	plan9	MOVD F28, 124(R7)
+db12893c|	plan9	MOVD V27, 145(R22)
+1686716e|	plan9	VSUB V17.H8, V16.H8, V22.H8
+5362320e|	plan9	VSUBHN V18.H8, V18.H8, V19.B8
+6163bf4e|	plan9	VSUBHN2 V31.D2, V27.D2, V1.S4
+a73be05e|	plan9	SUQADD F29, F7
+21a4100f|	plan9	VSXTL V1.H4, V1.S4
+8b23164e|	plan9	VTBL V22.B16, [V28.B16, V29.B16], V11.B16
+3642120e|	plan9	VTBL V18.B8, [V17.B16, V18.B16, V19.B16], V22.B8
+cf611f0e|	plan9	VTBL V31.B8, [V14.B16, V15.B16, V16.B16, V17.B16], V15.B8
+0b020e4e|	plan9	VTBL V14.B16, [V16.B16], V11.B16
+9830014e|	plan9	VTBX V1.B16, [V4.B16, V5.B16], V24.B16
+1452044e|	plan9	VTBX V4.B16, [V16.B16, V17.B16, V18.B16], V20.B16
+b4711a0e|	plan9	VTBX V26.B8, [V13.B16, V14.B16, V15.B16, V16.B16], V20.B8
+f911140e|	plan9	VTBX V20.B8, [V15.B16], V25.B8
+9f28500e|	plan9	VTRN1 V16.H4, V4.H4, V31.H4
+2e69c64e|	plan9	VTRN2 V6.D2, V9.D2, V14.D2
+c752756e|	plan9	VUABAL2 V21.H8, V22.H8, V7.S4
+8675696e|	plan9	VUABD V9.H8, V12.H8, V6.H8
+a973ab6e|	plan9	VUABDL2 V11.S4, V29.S4, V9.D2
+fa006c2e|	plan9	VUADDL V12.H4, V7.H4, V26.S4
+da00236e|	plan9	VUADDL2 V3.B16, V6.B16, V26.H8
+ab3a306e|	plan9	UADDLV V21.B16, F11
+a312746e|	plan9	VUADDW2 V20.H8, V21.S4, V3.S4
+cee55e7f|	plan9	UCVTF $34, F14, F14
+8edb617e|	plan9	UCVTFDD F28, F14
+ab8f431e|	plan9	UCVTF $29, R29, F11
+68b3039e|	plan9	UCVTF $20, R27, F8
+7686439e|	plan9	UCVTF $31, R19, F22
+2a03231e|	plan9	UCVTFWS R25, F10
+9f01631e|	plan9	UCVTFWD R12, F31
+a800239e|	plan9	UCVTFS R5, F8
+0302639e|	plan9	UCVTFD R16, F3
+df65a42e|	plan9	VUMAX V4.S2, V14.S2, V31.S2
+29ab702e|	plan9	UMAXV V25.H4, F9
+6f6e2e6e|	plan9	VUMIN V14.B16, V19.B16, V15.B16
+fdada32e|	plan9	VUMINP V3.S2, V15.S2, V29.S2
+07289a6f|	plan9	VUMLAL2 V26.S[2], V0.S4, V7.D2
+aa80ad2e|	plan9	VUMLAL V13.S2, V5.S2, V10.D2
+d66b462f|	plan9	VUMLSL V6.H[4], V30.H4, V22.S4
+12a3b62e|	plan9	VUMLSL V22.S2, V24.S2, V18.D2
+583e0d0e|	plan9	UMOVW V18.B[6], R24
+20c3b52e|	plan9	VUMULL V21.S2, V25.S2, V0.D2
+20c2616e|	plan9	VUMULL2 V1.H8, V17.H8, V0.S4
+2f0f6d7e|	plan9	UQADD F13, F25, F15
+a60c272e|	plan9	VUQADD V7.B8, V5.B8, V6.B8
+5b5da27e|	plan9	UQRSHL F2, F10, F27
+195c786e|	plan9	VUQRSHL V24.H8, V0.H8, V25.H8
+209e282f|	plan9	VUQRSHRN $24, V17.D2, V0.S2
+e89e3b6f|	plan9	VUQRSHRN2 $5, V23.D2, V8.S4
+4f75147f|	plan9	UQSHL $4, F10, F15
+d2767d6f|	plan9	VUQSHL $61, V22.D2, V18.D2
+bb4cfe7e|	plan9	UQSHL F30, F5, F27
+794ea42e|	plan9	VUQSHL V4.S2, V19.S2, V25.S2
+51960b7f|	plan9	UQSHRN $5, F18, F17
+642ce77e|	plan9	UQSUB F7, F3, F4
+6149617e|	plan9	UQXTN F11, F1
+4e48a12e|	plan9	VUQXTN V2.D2, V14.S2
+9cc8a14e|	plan9	VURECPE V4.S4, V28.S4
+2f15a52e|	plan9	VURHADD V5.S2, V9.S2, V15.S2
+5757fb7e|	plan9	URSHL F27, F26, F23
+2756706e|	plan9	VURSHL V16.H8, V17.H8, V7.H8
+a424487f|	plan9	URSHR $56, F5, F4
+b926796f|	plan9	VURSHR $7, V21.D2, V25.D2
+1336076f|	plan9	VBIC $(240<<8), V19.S4
+e347e06e|	plan9	VUSHL V0.D2, V31.D2, V3.D2
+f7a5272f|	plan9	VUSHLL $7, V15.S2, V23.D2
+9ba63d6f|	plan9	VUSHLL2 $29, V20.S4, V27.D2
+d405737f|	plan9	USHR $13, F14, F20
+3a05116f|	plan9	VUSHR $15, V9.H8, V26.H8
+1d39607e|	plan9	USQADD F8, F29
+0e39e06e|	plan9	VUSQADD V8.D2, V14.D2
+8022b02e|	plan9	VUSUBL V16.S2, V20.S2, V0.D2
+9a20786e|	plan9	VUSUBL2 V24.H8, V4.H8, V26.S4
+df33692e|	plan9	VUSUBW V9.H4, V30.S4, V31.S4
+92a5102f|	plan9	VUXTL V12.H4, V18.S4
+0e19464e|	plan9	VUZP1 V6.H8, V8.H8, V14.H8
+7629610e|	plan9	VXTN V11.S4, V22.H4
+7338504e|	plan9	VZIP1 V16.H8, V3.H8, V19.H8
+357bd64e|	plan9	VZIP2 V22.D2, V25.D2, V21.D2
+63020f1a|	plan9	ADCW R15, R19, R3
+1f03159a|	plan9	ADC R21, R24, ZR
+d300103a|	plan9	ADCSW R16, R6, R19
+1b0010ba|	plan9	ADCS R16, R0, R27
+dd133f0b|	plan9	ADDW ZR.UXTB<<4, R30, R29
+89c42f8b|	plan9	ADD R15.SXTW<<1, R4, R9
+4e242a11|	plan9	ADDW $2697, R2, R14
+e1c12f2b|	plan9	ADDSW R15.SXTW, R15, R1
+733421ab|	plan9	ADDS R1.UXTH<<5, R3, R19
+0ccc5aab|	plan9	ADDS R26>>51, R0, R12
+2e122612|	plan9	ANDW $2080374784, R17, R14
+5e4c2992|	plan9	AND $-36020000934328321, R2, R30
+2805410a|	plan9	ANDW R1>>1, R9, R8
+ede1938a|	plan9	AND R19->56, R15, R13
+e7c10f72|	plan9	ANDSW $33686018, R15, R7
+23ed55f2|	plan9	ANDS $-8246337208321, R9, R3
+e6935bea|	plan9	ANDS R27>>36, ZR, R6
+0e2ac61a|	plan9	ASRW R6, R16, R14
+802ad59a|	plan9	ASR R21, R20, R0
+7cfd7793|	plan9	ASR $55, R11, R28
+f028cd1a|	plan9	ASRW R13, R7, R16
+132bd29a|	plan9	ASR R18, R24, R19
+c2560e54|	plan9	BCS 29366(PC)
+83516b17|	plan9	JMP -9743997(PC)
+7a571233|	plan9	BFXILW $18, R27, $4, R26
+71b858b3|	plan9	BFXIL $24, R3, $23, R17
+c3964bb3|	plan9	BFXIL $11, R22, $27, R3
+eb561233|	plan9	BFXILW $18, R23, $4, R11
+063f5db3|	plan9	BFI $35, R24, $16, R6
+0a337a0a|	plan9	BICW R26>>12, R24, R10
+2a71e28a|	plan9	BIC R2@>28, R9, R10
+c168bf6a|	plan9	BICSW ZR->26, R6, R1
+d8bb3cea|	plan9	BICS R28<<46, R30, R24
+82e81795|	plan9	CALL 18344066(PC)
+40033fd6|	plan9	CALL (R26)
+c0011fd6|	plan9	JMP (R14)
+00dd31d4|	plan9	BRK $36584
+a6cb563a|	plan9	CCMNW GT, R29, $22, $6
+87db55ba|	plan9	CCMN LE, R28, $21, $7
+a042493a|	plan9	CCMNW MI, R21, R9, $0
+6a0040ba|	plan9	CCMN EQ, R3, R0, $10
+46bb5c7a|	plan9	CCMPW LT, R26, $28, $6
+c72942fa|	plan9	CCMP HS, R14, $2, $7
+cda1427a|	plan9	CCMPW GE, R14, R2, $13
+a1314dfa|	plan9	CCMP LO, R13, R13, $1
+8706931a|	plan9	CSINCW EQ, R20, R19, R7
+3ae69a9a|	plan9	CSINC AL, R17, R26, R26
+9e51945a|	plan9	CSINVW PL, R12, R20, R30
+d5e386da|	plan9	CSINV AL, R30, R6, R21
+5f3503d5|	plan9	CLREX $5
+e515c05a|	plan9	CLSW R15, R5
+a815c0da|	plan9	CLS R13, R8
+4a12c05a|	plan9	CLZW R18, R10
+3c10c0da|	plan9	CLZ R1, R28
+ff70252b|	plan9	CMNW R5.UXTX<<4, R7
+9fa133ab|	plan9	CMN R19.SXTH, R12
+3f3a822b|	plan9	CMNW R2->14, R17
+df1d44ab|	plan9	CMN R4>>7, R14
+3f95386b|	plan9	CMPW R24.SXTB<<5, R9
+9f653feb|	plan9	CMP ZR.UXTX<<1, R12
+1626915a|	plan9	CSNEGW HS, R16, R17, R22
+b4d587da|	plan9	CSNEG LE, R13, R7, R20
+9841d41a|	plan9	CRC32B R20, R12, R24
+ec45d01a|	plan9	CRC32H R16, R15, R12
+8048ca1a|	plan9	CRC32W R10, R4, R0
+d44ec19a|	plan9	CRC32X R1, R22, R20
+1552d31a|	plan9	CRC32CB R19, R16, R21
+4b54c71a|	plan9	CRC32CH R7, R2, R11
+245ad41a|	plan9	CRC32CW R20, R17, R4
+c35cc89a|	plan9	CRC32CX R8, R6, R3
+14219f1a|	plan9	CSELW HS, R8, ZR, R20
+9c73979a|	plan9	CSEL VC, R28, R23, R28
+e7279f1a|	plan9	CSETW LO, R7
+ec579f9a|	plan9	CSET MI, R12
+e5f39f5a|	plan9	CSINVW AL, ZR, ZR, R5
+e8639fda|	plan9	CSETM VC, R8
+ea76971a|	plan9	CINCW VS, R23, R10
+78a7859a|	plan9	CSINC GE, R27, R5, R24
+b590845a|	plan9	CSINVW LS, R5, R4, R21
+b4029eda|	plan9	CSINV EQ, R21, R30, R20
+b3969b5a|	plan9	CSNEGW LS, R21, R27, R19
+938591da|	plan9	CSNEG HI, R12, R17, R19
+016ea8d4|	plan9	DCPS1 $17264
+0275a4d4|	plan9	DCPS2 $9128
+a3e9a6d4|	plan9	DCPS3 $14157
+bf3903d5|	plan9	DMB $9
+e003bfd6|	plan9	DRPS
+9f3e03d5|	plan9	DSB $14
+50b1a0ca|	plan9	EON R0->44, R10, R16
+c0b02f52|	plan9	EORW $1073627134, R6, R0
+4b0c1ed2|	plan9	EOR $257698037820, R2, R11
+693c074a|	plan9	EORW R7<<15, R3, R9
+113e1aca|	plan9	EOR R26<<15, R16, R17
+e0039fd6|	plan9	ERET
+fef8c693|	plan9	EXTR $62, R6, R7, R30
+3f2003d5|	plan9	YIELD
+3f2403d5|	plan9	HINT $33
+c0425ad4|	plan9	HLT $53782
+df3003d5|	plan9	ISB $0
+f7fddf88|	plan9	LDARW (R15), R23
+96fedfc8|	plan9	LDAR (R20), R22
+11fedf08|	plan9	LDARB (R16), R17
+c2fedf48|	plan9	LDARH (R22), R2
+2d927f88|	plan9	LDAXPW (R17), R4, R13
+198f7fc8|	plan9	LDAXP (R24), R3, R25
+46ff5f88|	plan9	LDAXRW (R26), R6
+81fe5fc8|	plan9	LDAXR (R20), R1
+86fe5f08|	plan9	LDAXRB (R20), R6
+78ff5f48|	plan9	LDAXRH (R27), R24
+35864a28|	plan9	LDNPW 84(R17), R1, R21
+6da05fa8|	plan9	LDNP 504(R3), R8, R13
+a8f9f428|	plan9	LDP.P -92(R13), (R8, R30)
+b749e3a8|	plan9	LDP.P -464(R13), (R23, R18)
+bdedd929|	plan9	LDP.W 204(R13), (R29, R27)
+c8e5c6a9|	plan9	LDP.W 104(R14), (R8, R25)
+c0857f29|	plan9	LDP -4(R14), (R0, R1)
+388a6ca9|	plan9	LDP -312(R17), (R24, R2)
+086be468|	plan9	LDPSW -224(R24), R26, R8
+d107d269|	plan9	LDPSW 144(R30), R1, R17
+738e4e69|	plan9	LDPSW 116(R19), R3, R19
+6ee55fb8|	plan9	MOVWU.P -2(R11), R14
+233459f8|	plan9	MOVD.P -109(R1), R3
+919f44b8|	plan9	MOVWU.W 73(R28), R17
+acdd45f8|	plan9	MOVD.W 93(R13), R12
+e1cd51b9|	plan9	MOVWU 4556(R15), R1
+95e27bf9|	plan9	MOVD 30656(R20), R21
+0c554b38|	plan9	MOVBU.P 181(R8), R12
+054f5938|	plan9	MOVBU.W -108(R24), R5
+1f206539|	plan9	MOVBU 2376(R0), ZR
+73796a38|	plan9	MOVBU R10<<1(R11), R19
+a8b74f78|	plan9	MOVHU.P 251(R29), R8
+021e5e78|	plan9	MOVHU.W -31(R16), R2
+ec126b79|	plan9	MOVHU 5512(R23), R12
+eaf6c238|	plan9	MOVBW.P 47(R23), R10
+87679838|	plan9	MOVB.P -122(R28), R7
+567fdb38|	plan9	MOVBW.W -73(R26), R22
+3b2e8138|	plan9	MOVB.W 18(R17), R27
+7d74c039|	plan9	MOVBW 29(R3), R29
+7d1f8539|	plan9	MOVB 327(R27), R29
+6a7bed38|	plan9	MOVBW R13<<1(R27), R10
+0f69b538|	plan9	MOVB R21(R8), R15
+c796cc78|	plan9	MOVHW.P 201(R22), R7
+50268e78|	plan9	MOVH.P 226(R18), R16
+229ddb78|	plan9	MOVHW.W -71(R9), R2
+0f4f9178|	plan9	MOVH.W -236(R24), R15
+59ecc379|	plan9	MOVHW 502(R2), R25
+83d49679|	plan9	MOVH 2922(R4), R3
+986be878|	plan9	MOVHW R8(R28), R24
+6b4693b8|	plan9	MOVW.P -204(R19), R11
+cb9e81b8|	plan9	MOVW.W 25(R22), R11
+280d9eb9|	plan9	MOVW 7692(R9), R8
+1a68b8b8|	plan9	MOVW R24(R0), R26
+35b955b8|	plan9	LDTRW -165(R9), R21
+658b57f8|	plan9	LDTR -136(R27), R5
+b3594038|	plan9	LDTRBW 5(R13), R19
+5ac95d78|	plan9	LDTRHW -36(R10), R26
+2c3ade38|	plan9	LDTRSBW -29(R17), R12
+4de99038|	plan9	LDTRSB -242(R10), R13
+e178c378|	plan9	LDTRSHW 55(R7), R1
+a77a8778|	plan9	LDTRSH 119(R21), R7
+cde982b8|	plan9	LDTRSW 46(R14), R13
+04d15bb8|	plan9	LDURW -67(R8), R4
+02a256f8|	plan9	LDUR -150(R16), R2
+97405438|	plan9	LDURBW -188(R4), R23
+99b14b78|	plan9	LDURHW 187(R12), R25
+f9a1cf38|	plan9	LDURSBW 250(R15), R25
+c0218c38|	plan9	LDURSB 194(R14), R0
+5790d278|	plan9	LDURSHW -215(R2), R23
+a3808278|	plan9	LDURSH 40(R5), R3
+a9b08fb8|	plan9	LDURSW 251(R5), R9
+98217f88|	plan9	LDXPW (R12), R8, R24
+4d6a7fc8|	plan9	LDXP (R18), R26, R13
+9c7e5f88|	plan9	LDXRW (R20), R28
+0e7c5fc8|	plan9	LDXR (R0), R14
+507c5f08|	plan9	LDXRB (R2), R16
+ea7f5f48|	plan9	LDXRH (RSP), R10
+5523dd1a|	plan9	LSLW R29, R26, R21
+9721ca9a|	plan9	LSL R10, R12, R23
+75665bd3|	plan9	UBFIZ $37, R19, $26, R21
+0a20df1a|	plan9	LSLW ZR, R0, R10
+5222c99a|	plan9	LSL R9, R18, R18
+5124df1a|	plan9	LSRW ZR, R2, R17
+6b26d69a|	plan9	LSR R22, R19, R11
+9a7c0753|	plan9	LSRW $7, R4, R26
+7bfd53d3|	plan9	LSR $19, R11, R27
+5f26d91a|	plan9	LSRW R25, R18, ZR
+3625d89a|	plan9	LSR R24, R9, R22
+9d76001b|	plan9	MADDW R0, R29, R20, R29
+822f0e9b|	plan9	MADD R14, R11, R28, R2
+e8fe101b|	plan9	MNEGW R16, R23, R8
+88fc099b|	plan9	MNEG R9, R4, R8
+dd030011|	plan9	ADDW $0, R30, R29
+db010091|	plan9	ADD $0, R14, R27
+0c6db012|	plan9	MOVW $2090336255, R12
+3ff5aa92|	plan9	MOVD $-1470693377, ZR
+87f0f6d2|	plan9	MOVD $-5223049667842932736, R7
+f3571132|	plan9	ORRW $4294934559, ZR, R19
+f3bb0bb2|	plan9	MOVD $-4503668347895825, R19
+f103082a|	plan9	MOVW R8, R17
+ef031faa|	plan9	MOVD ZR, R15
+4a6bf5f2|	plan9	MOVK $(43866<<48), R10
+383b9312|	plan9	MOVW $4294927910, R24
+f5fb9092|	plan9	MOVD $-34784, R21
+d5b4b052|	plan9	MOVW $2242248704, R21
+fdc5eed2|	plan9	MOVD $8516025420380897280, R29
+c58435d5|	plan9	MRS $11302, R5
+1a0f13d5|	plan9	MSR R26, $6264
+52d5181b|	plan9	MSUBW R24, R21, R10, R18
+c4f81d9b|	plan9	MSUB R29, R30, R6, R4
+a57c1b1b|	plan9	MULW R27, R5, R5
+8f7f0a9b|	plan9	MUL R10, R28, R15
+e75361aa|	plan9	MVN R1>>20, R7
+e0cb15cb|	plan9	NEG R21<<50, R0
+ffdb49eb|	plan9	CMP R9>>54, ZR
+f5031c5a|	plan9	NGCW R28, R21
+e6031eda|	plan9	NGC R30, R6
+e103077a|	plan9	NGCSW R7, R1
+f20301fa|	plan9	NGCS R1, R18
+1f2003d5|	plan9	NOP
+9347722a|	plan9	ORNW R18>>17, R28, R19
+0591e1aa|	plan9	ORN R1@>36, R8, R5
+7ba82a32|	plan9	ORRW $4290904001, R3, R27
+ae087db2|	plan9	ORR $56, R5, R14
+9608472a|	plan9	ORRW R7>>2, R4, R22
+c40dc5aa|	plan9	ORR R5@>3, R14, R4
+9d83bcf9|	plan9	PRFM 30976(R28), #0X1D
+6e9186f8|	plan9	PRFUM 105(R11), #0X0E
+c001c05a|	plan9	RBITW R14, R0
+4203c0da|	plan9	RBIT R26, R2
+c0035fd6|	plan9	RET
+9b08c05a|	plan9	REVW R4, R27
+740cc0da|	plan9	REV R3, R20
+0205c05a|	plan9	REV16W R8, R2
+dd07c0da|	plan9	REV16 R30, R29
+020bc0da|	plan9	REV32 R24, R2
+780cc0da|	plan9	REV R3, R24
+9b7f9513|	plan9	EXTRW $31, R21, R28, R27
+5243dd93|	plan9	EXTR $16, R29, R26, R18
+822eca1a|	plan9	RORW R10, R20, R2
+f02ddb9a|	plan9	ROR R27, R15, R16
+082ed81a|	plan9	RORW R24, R16, R8
+7b2cc39a|	plan9	ROR R3, R3, R27
+3b030b5a|	plan9	SBCW R11, R25, R27
+f2021dda|	plan9	SBC R29, R23, R18
+e600127a|	plan9	SBCSW R18, R7, R6
+cf030ffa|	plan9	SBCS R15, R30, R15
+3a797793|	plan9	SBFIZ $9, R9, $31, R26
+4a305193|	plan9	SBFIZ $47, R2, $13, R10
+a1c74493|	plan9	SBFX $4, R29, $46, R1
+a00fc01a|	plan9	SDIVW R0, R29, R0
+f10edd9a|	plan9	SDIV R29, R23, R17
+9f2003d5|	plan9	SEV
+bf2003d5|	plan9	SEVL
+a52d319b|	plan9	SMADDL R17, R11, R13, R5
+b4fc399b|	plan9	SMNEGL R25, R5, R20
+579e369b|	plan9	SMSUBL R22, R7, R18, R23
+ea7e429b|	plan9	SMULH R2, R23, R10
+eb7f219b|	plan9	SMULL R1, ZR, R11
+f1fe9f88|	plan9	STLRW R17, (R23)
+edff9fc8|	plan9	STLR R13, (RSP)
+bffe9f08|	plan9	STLRB ZR, (R21)
+9cfd9f48|	plan9	STLRH R28, (R12)
+41bf2688|	plan9	STLXPW (R26), R15, R1, R6
+01e93cc8|	plan9	STLXPW (R8), R26, R1, R28
+e0fd1f88|	plan9	STLXRW R0, (R15), ZR
+12fe17c8|	plan9	STLXR R18, (R16), R23
+d4fc1008|	plan9	STLXRB R20, (R6), R16
+befc0048|	plan9	STLXRH R30, (R5), R0
+76613728|	plan9	STNPW -72(R11), R24, R22
+c7523ba8|	plan9	STNP -80(R22), R20, R7
+8e3a9f28|	plan9	STP.P (R14, R14), 248(R20)
+aa1fa6a8|	plan9	STP.P (R10, R7), -416(R29)
+fbae8d29|	plan9	STP.W (R27, R11), 108(R23)
+f63c80a9|	plan9	STP.W (R22, R15), (R7)
+43d73629|	plan9	STP (R3, R21), -76(R26)
+1ae01ba9|	plan9	STP (R26, R24), 440(R0)
+8f650cb8|	plan9	MOVW.P R15, 198(R12)
+aad503f8|	plan9	MOVD.P R10, 61(R13)
+ec4d00b8|	plan9	MOVW.W R12, 4(R15)
+7dbc1df8|	plan9	MOVD.W R29, -37(R3)
+9b0226b9|	plan9	MOVW R27, 9728(R20)
+91691af9|	plan9	MOVD R17, 13520(R12)
+20840838|	plan9	MOVB.P R0, 136(R1)
+060c1f38|	plan9	MOVB.W R6, -16(R0)
+2b213a39|	plan9	MOVB R11, 3720(R9)
+ab6b3438|	plan9	MOVB R11, R20(R29)
+50e51e78|	plan9	MOVH.P R16, -18(R10)
+5d5d1878|	plan9	MOVH.W R29, -123(R10)
+ea862379|	plan9	MOVH R10, 4546(R23)
+d5ca12b8|	plan9	STTRW -212(R22), R21
+001b18f8|	plan9	STTR -127(R24), R0
+290a1e38|	plan9	STTRBW -32(R17), R9
+0b381078|	plan9	STTRHW -253(R0), R11
+c78101b8|	plan9	MOVW R7, 24(R14)
+c0b217f8|	plan9	MOVD R0, -133(R22)
+f8401e38|	plan9	MOVB R24, -28(R7)
+5e911a78|	plan9	MOVH R30, -87(R10)
+b7622d88|	plan9	STXPW (R21), R24, R23, R13
+233d37c8|	plan9	STXPW (R9), R15, R3, R23
+847d0088|	plan9	STXRW R4, (R12), R0
+a27d0bc8|	plan9	STXR R2, (R13), R11
+f27f1e08|	plan9	STXRB R18, (RSP), R30
+3a7d1848|	plan9	STXRH R26, (R9), R24
+d4dc204b|	plan9	SUBW R0.SXTW<<7, R6, R20
+874023cb|	plan9	SUB R3.UXTW, R4, R7
+44eb4f51|	plan9	SUBW $(1018<<12), R26, R4
+17b012cb|	plan9	SUB R18<<44, R0, R23
+ac1e376b|	plan9	SUBSW R23.UXTB<<7, R21, R12
+b0483beb|	plan9	SUBS R27.UXTW<<2, R5, R16
+d1f994eb|	plan9	SUBS R20->62, R14, R17
+61d513d4|	plan9	SVC $40619
+591d0013|	plan9	SXTBW R10, R25
+9f1f4093|	plan9	SXTB R28, ZR
+773f0013|	plan9	SXTHW R27, R23
+453c4093|	plan9	SXTH R2, R5
+b77c4093|	plan9	SXTW R5, R23
+743628d5|	plan9	SYSL $13920, R20
+9f613672|	plan9	TSTW $4294966279, R12
+1f8d22f2|	plan9	TST $-4610630471158349821, R8
+ff6e93ea|	plan9	TST R19->27, R23
+06997ed3|	plan9	UBFIZ $2, R8, $39, R6
+5dd054d3|	plan9	UBFX $20, R2, $33, R29
+a54273d3|	plan9	UBFIZ $13, R21, $17, R5
+7d08d11a|	plan9	UDIVW R17, R3, R29
+120acf9a|	plan9	UDIV R15, R16, R18
+1401a89b|	plan9	UMADDL R8, R0, R8, R20
+08feb29b|	plan9	UMNEGL R18, R16, R8
+eeb0b99b|	plan9	UMSUBL R25, R12, R7, R14
+967fdd9b|	plan9	UMULH R29, R28, R22
+947eb59b|	plan9	UMULL R21, R20, R20
+7e1f0053|	plan9	UXTBW R27, R30
+983c0053|	plan9	UXTHW R4, R24
+5f2003d5|	plan9	WFE
+7f2003d5|	plan9	WFI
+3f2003d5|	plan9	YIELD
+02bb200e|	plan9	VABS V24.B8, V2.B8
+0686ec4e|	plan9	VADD V12.D2, V16.D2, V6.D2
+ea42ac0e|	plan9	VADDHN V12.D2, V23.D2, V10.S2
+7d43624e|	plan9	VADDHN2 V2.S4, V27.S4, V29.H8
+2cbd710e|	plan9	VADDP V17.H4, V9.H4, V12.H4
+f5bab14e|	plan9	ADDV V23.S4, F21
+8158284e|	plan9	VAESD V4.B16, V1.B16
+ba48284e|	plan9	VAESE V5.B16, V26.B16
+0c7a284e|	plan9	VAESIMC V16.B16, V12.B16
+3e6a284e|	plan9	VAESMC V17.B16, V30.B16
+091f384e|	plan9	VAND V24.B16, V24.B16, V9.B16
+07b6046f|	plan9	VBIC $(144<<8), V7.H8
+00c5006f|	plan9	VMVNI $(8<<136), V0.S4
+f81e6c0e|	plan9	VBIC V12.B8, V23.B8, V24.B8
+6f1ced2e|	plan9	VBIF V13.B8, V3.B8, V15.B8
+e31da16e|	plan9	VBIT V1.B16, V15.B16, V3.B16
+6a1d7c6e|	plan9	VBSL V28.B16, V11.B16, V10.B16
+284a600e|	plan9	VCLS V17.H4, V8.H4
+9a49202e|	plan9	VCLZ V12.B8, V26.B8
+d78f706e|	plan9	VCMEQ V16.H8, V30.H8, V23.H8
+7798e05e|	plan9	CMEQ $0, F3, F23
+739a200e|	plan9	VCMEQ $0, V19.B8, V19.B8
+ff3f2b4e|	plan9	VCMGE V11.B16, V31.B16, V31.B16
+5337370e|	plan9	VCMGT V23.B8, V26.B8, V19.B8
+3489604e|	plan9	VCMGT $0, V9.H8, V20.H8
+083d782e|	plan9	VCMHS V24.H4, V8.H4, V8.H4
+c899e07e|	plan9	CMLE $0, F14, F8
+3498a06e|	plan9	VCMLE $0, V1.S4, V20.S4
+ebaa200e|	plan9	VCMLT $0, V23.B8, V11.B8
+408dfe4e|	plan9	VCMTST V30.D2, V10.D2, V0.D2
+0e06085e|	plan9	VMOV V16.D[0], F14
+1e0d0d0e|	plan9	VDUP R8, V30.B8
+8e1d3a6e|	plan9	VEOR V26.B16, V12.B16, V14.B16
+632a086e|	plan9	VEXT $5, V8.B16, V19.B16, V3.B16
+97d7e57e|	plan9	FABD F5, F28, F23
+6bd4a82e|	plan9	VFABD V8.S2, V3.S2, V11.S2
+f7faa00e|	plan9	FABS V23.S2, V23.S2
+54c2201e|	plan9	FABSS F18, F20
+3ec3601e|	plan9	FABSD F25, F30
+2aee317e|	plan9	FACGE F17, F17, F10
+2fed392e|	plan9	VFACGE V25.S2, V9.S2, V15.S2
+2befe97e|	plan9	FACGT F9, F25, F11
+65eced6e|	plan9	VFACGT V13.D2, V3.D2, V5.D2
+55d53c4e|	plan9	FADD V28.S4, V10.S4, V21.S4
+8b283f1e|	plan9	FADDS F31, F4, F11
+d828601e|	plan9	FADDD F0, F6, F24
+e9d8307e|	plan9	FADDP V7.S2, F9
+4084391e|	plan9	FCCMPS HI, F25, F2, $0
+ef046d1e|	plan9	FCCMPD EQ, F13, F7, $15
+d7a4241e|	plan9	FCCMPES GE, F4, F6, $7
+dbf5601e|	plan9	FCCMPED AL, F0, F14, $11
+77e7625e|	plan9	FCMEQ F2, F27, F23
+2de67f4e|	plan9	VFCMEQ V31.D2, V17.D2, V13.D2
+59daa05e|	plan9	FCMEQ $0, F18, F25
+add9a00e|	plan9	VFCMEQ $0, V13.S2, V13.S2
+dce42d7e|	plan9	FCMGE F13, F6, F28
+62e6776e|	plan9	VFCMGE V23.D2, V19.D2, V2.D2
+f9cae07e|	plan9	FCMGE $0, F23, F25
+18e5ab7e|	plan9	FCMGT F11, F8, F24
+84e7ae6e|	plan9	VFCMGT V14.S4, V28.S4, V4.S4
+a0c8e05e|	plan9	FCMGT $0, F5, F0
+c6cae04e|	plan9	VFCMGT $0, V22.D2, V6.D2
+4fdaa07e|	plan9	FCMLE $0, F18, F15
+e1d9a02e|	plan9	VFCMLE $0, V15.S2, V1.S2
+1ee9a05e|	plan9	FCMLT $0, F8, F30
+23eaa04e|	plan9	VFCMLT $0, V17.S4, V3.S4
+6023321e|	plan9	FCMPS F18, F27
+2823391e|	plan9	FCMPS $(0.0), F25
+00236d1e|	plan9	FCMPD F13, F24
+e820601e|	plan9	FCMPD $(0.0), F7
+3022381e|	plan9	FCMPES F24, F17
+f8233e1e|	plan9	FCMPES $(0.0), F31
+b0206a1e|	plan9	FCMPED F10, F5
+3820691e|	plan9	FCMPED $(0.0), F1
+d85f271e|	plan9	FCSELS PL, F30, F7, F24
+ed8f7a1e|	plan9	FCSELD HI, F31, F26, F13
+0042e21e|	plan9	FCVTHS F16, F0
+efc1e21e|	plan9	FCVTHD F15, F15
+edc1231e|	plan9	FCVTSH F15, F13
+0ac0221e|	plan9	FCVTSD F0, F10
+39c3631e|	plan9	FCVTDH F25, F25
+da43621e|	plan9	FCVTDS F30, F26
+10cb615e|	plan9	FCVTAS F24, F16
+f400241e|	plan9	FCVTASW F7, R20
+2f00249e|	plan9	FCVTAS F1, R15
+1d02641e|	plan9	FCVTASW F16, R29
+9303649e|	plan9	FCVTAS F28, R19
+02ca217e|	plan9	FCVTAU F16, F2
+afc8212e|	plan9	VFCVTAU V5.S2, V15.S2
+6e02251e|	plan9	FCVTAUW F19, R14
+fd02259e|	plan9	FCVTAU F23, R29
+8603651e|	plan9	FCVTAUW F28, R6
+4001659e|	plan9	FCVTAU F10, R0
+1f78210e|	plan9	VFCVTL V0.H4, V31.S4
+d179214e|	plan9	VFCVTL2 V14.H8, V17.S4
+fdbb615e|	plan9	FCVTMS F31, F29
+9601301e|	plan9	FCVTMSW F12, R22
+f403309e|	plan9	FCVTMS F31, R20
+6b02701e|	plan9	FCVTMSW F19, R11
+4802709e|	plan9	FCVTMS F18, R8
+84ba217e|	plan9	FCVTMU F20, F4
+ae01311e|	plan9	FCVTMUW F13, R14
+8402319e|	plan9	FCVTMU F20, R4
+7403711e|	plan9	FCVTMUW F27, R20
+2a03719e|	plan9	FCVTMU F25, R10
+a36b210e|	plan9	VFCVTN V29.S4, V3.H4
+5c6a214e|	plan9	VFCVTN2 V18.S4, V28.H8
+78a9215e|	plan9	FCVTNS F11, F24
+b1ab614e|	plan9	VFCVTNS V29.D2, V17.D2
+0c01201e|	plan9	FCVTNSW F8, R12
+b303209e|	plan9	FCVTNS F29, R19
+c401601e|	plan9	FCVTNSW F14, R4
+5200609e|	plan9	FCVTNS F2, R18
+c2a8617e|	plan9	FCVTNU F6, F2
+daab616e|	plan9	VFCVTNU V30.D2, V26.D2
+d001211e|	plan9	FCVTNUW F14, R16
+0402219e|	plan9	FCVTNU F16, R4
+7800611e|	plan9	FCVTNUW F3, R24
+e602619e|	plan9	FCVTNU F23, R6
+74aaa15e|	plan9	FCVTPS F19, F20
+c801281e|	plan9	FCVTPSW F14, R8
+8f02289e|	plan9	FCVTPS F20, R15
+6d02681e|	plan9	FCVTPSW F19, R13
+bc00689e|	plan9	FCVTPS F5, R28
+43aba17e|	plan9	FCVTPU F26, F3
+cda9a12e|	plan9	VFCVTPU V14.S2, V13.S2
+c102291e|	plan9	FCVTPUW F22, R1
+9103299e|	plan9	FCVTPU F28, R17
+7602691e|	plan9	FCVTPUW F19, R22
+4501699e|	plan9	FCVTPU F10, R5
+976a616e|	plan9	VFCVTXN2 V20.D2, V23.S4
+d5fc575f|	plan9	FCVTZS $41, F6, F21
+babaa15e|	plan9	FCVTZSSS F21, F26
+7aa6181e|	plan9	FCVTZS $23, F19, R26
+c410189e|	plan9	FCVTZS $60, F6, R4
+4db5589e|	plan9	FCVTZS $19, F10, R13
+9000381e|	plan9	FCVTZSSW F4, R16
+1702389e|	plan9	FCVTZSS F16, R23
+8a03781e|	plan9	FCVTZSDW F28, R10
+d501789e|	plan9	FCVTZSD F14, R21
+eefd2d7f|	plan9	FCVTZU $19, F15, F14
+4dfc3c6f|	plan9	FCVTZU $4, V2.S4, V13.S4
+96bbe17e|	plan9	FCVTZUDD F28, F22
+30b8e16e|	plan9	FCVTZU V1.D2, V16.D2
+fdef191e|	plan9	FCVTZU $5, F31, R29
+1d7b199e|	plan9	FCVTZU $34, F24, R29
+b8f5591e|	plan9	FCVTZU $3, F13, R24
+5080599e|	plan9	FCVTZU $32, F2, R16
+d002391e|	plan9	FCVTZUSW F22, R16
+9b03399e|	plan9	FCVTZUS F28, R27
+7501791e|	plan9	FCVTZUDW F11, R21
+7603799e|	plan9	FCVTZUD F27, R22
+06fe3c6e|	plan9	FDIV V28.S4, V16.S4, V6.S4
+c41b201e|	plan9	FDIVS F0, F30, F4
+1618781e|	plan9	FDIVD F24, F0, F22
+507b0d1f|	plan9	FMADD F30, F13, F26, F16
+8803491f|	plan9	FMADD F0, F9, F28, F8
+75f7394e|	plan9	FMAX V25.S4, V27.S4, V21.S4
+804b3c1e|	plan9	FMAXS F28, F28, F0
+c1496c1e|	plan9	FMAXD F12, F14, F1
+5b69371e|	plan9	FMAXNMS F23, F10, F27
+1468711e|	plan9	FMAXNMD F17, F0, F20
+a4c8707e|	plan9	FMAXNMP V5.D2, F4
+89f9707e|	plan9	FMAXP V12.D2, F9
+4af63e2e|	plan9	VFMAXP V30.S2, V18.S2, V10.S2
+25fa306e|	plan9	FMAXV V17.S4, F5
+01f4e04e|	plan9	FMIN V0.D2, V0.D2, V1.D2
+59592a1e|	plan9	FMINS F10, F10, F25
+3959611e|	plan9	FMIND F1, F9, F25
+73c7ba4e|	plan9	FMINNM V26.S4, V27.S4, V19.S4
+1279391e|	plan9	FMINNMS F25, F8, F18
+75796c1e|	plan9	FMINNMD F12, F11, F21
+90cbb07e|	plan9	FMINNMP V28.S2, F16
+c5c8b06e|	plan9	FMINNMV V6.S4, F5
+cdfbf07e|	plan9	FMINP V30.D2, F13
+edf6f66e|	plan9	VFMINP V22.D2, V23.D2, V13.D2
+6513b85f|	plan9	FMLA V24.S[1], F27, F5
+ee18984f|	plan9	VFMLA V24.S[2], V7.S4, V14.S4
+b85ab75f|	plan9	FMLS V23.S[3], F21, F24
+a3f5030f|	plan9	FMOV $0.90625, V3.S2
+eaf7056f|	plan9	FMOV $-31., V10.D2
+3b41201e|	plan9	FMOVS F9, F27
+0d41601e|	plan9	FMOVD F8, F13
+9700271e|	plan9	FMOVS R4, F23
+ad03261e|	plan9	FMOVS F29, R13
+2302679e|	plan9	FMOVD R17, F3
+e101af9e|	plan9	FMOV R15, V1.D[1]
+f301669e|	plan9	FMOVD F15, R19
+1103ae9e|	plan9	FMOV V24.D[1], R17
+0230321e|	plan9	FMOVS $-4.25, F2
+18b0751e|	plan9	FMOVD $-14.5, F24
+92bc1b1f|	plan9	FMSUB F15, F27, F4, F18
+f8e14a1f|	plan9	FMSUB F24, F10, F15, F24
+ef91d35f|	plan9	FMULD V19.D[0], F15, F15
+d293c24f|	plan9	FMUL V2.D[0], V30.D2, V18.D2
+18dd2b2e|	plan9	FMUL V11.S2, V8.S2, V24.S2
+a4093d1e|	plan9	FMULS F29, F13, F4
+94096f1e|	plan9	FMULD F15, F12, F20
+fe918e7f|	plan9	FMULX V14.S[0], F15, F30
+7199c56f|	plan9	VFMULX V5.D[1], V11.D2, V17.D2
+32dc695e|	plan9	FMULX F9, F1, F18
+c8f9e06e|	plan9	FNEG V14.D2, V8.D2
+9c41211e|	plan9	FNEGS F12, F28
+c443611e|	plan9	FNEGD F30, F4
+e77f301f|	plan9	FNMADD F31, F16, F31, F7
+9f326c1f|	plan9	FNMADD F12, F12, F20, F31
+d9e92f1f|	plan9	FNMSUB F26, F15, F14, F25
+00ad711f|	plan9	FNMSUB F11, F17, F8, F0
+c889211e|	plan9	FNMULS F1, F14, F8
+528b761e|	plan9	FNMULD F22, F26, F18
+01d8e15e|	plan9	FRECPE F0, F1
+9aff7e5e|	plan9	FRECPS F30, F28, F26
+78fe2a4e|	plan9	VFRECPS V10.S4, V19.S4, V24.S4
+01f9e15e|	plan9	FRECPX F8, F1
+128b216e|	plan9	FRINTA V24.S4, V18.S4
+b241261e|	plan9	FRINTAS F13, F18
+a841661e|	plan9	FRINTAD F13, F8
+799aa16e|	plan9	FRINTI V19.S4, V25.S4
+1cc2271e|	plan9	FRINTIS F16, F28
+93c2671e|	plan9	FRINTID F20, F19
+1a40251e|	plan9	FRINTMS F0, F26
+ac42651e|	plan9	FRINTMD F21, F12
+5889214e|	plan9	FRINTN V10.S4, V24.S4
+5740241e|	plan9	FRINTNS F2, F23
+9443641e|	plan9	FRINTND F28, F20
+4b89a10e|	plan9	FRINTP V10.S2, V11.S2
+a0c1241e|	plan9	FRINTPS F13, F0
+93c2641e|	plan9	FRINTPD F20, F19
+d49b216e|	plan9	FRINTX V30.S4, V20.S4
+df41271e|	plan9	FRINTXS F14, F31
+8d41671e|	plan9	FRINTXD F12, F13
+3998a10e|	plan9	FRINTZ V1.S2, V25.S2
+fdc2251e|	plan9	FRINTZS F23, F29
+abc2651e|	plan9	FRINTZD F21, F11
+10dba17e|	plan9	FRSQRTE F24, F16
+edd9e16e|	plan9	VFRSQRTE V15.D2, V13.D2
+75ffe35e|	plan9	FRSQRTS F3, F27, F21
+b4fdbe4e|	plan9	VFRSQRTS V30.S4, V13.S4, V20.S4
+24f8a16e|	plan9	FSQRT V1.S4, V4.S4
+b6c1211e|	plan9	FSQRTS F13, F22
+c1c3611e|	plan9	FSQRTD F30, F1
+ffd5b44e|	plan9	FSUB V20.S4, V15.S4, V31.S4
+d438331e|	plan9	FSUBS F19, F6, F20
+f038771e|	plan9	FSUBD F23, F7, F16
+675e1a6e|	plan9	VMOV V19.H[5], V7.H[6]
+2a1c0a4e|	plan9	VMOV R1, V10.H[2]
+de7f400c|	plan9	VLD1 (R30), [V30.D1]
+4aa7404c|	plan9	VLD1 (R26), [V10.H8, V11.H8]
+5d61400c|	plan9	VLD1 (R10), [V29.B8, V30.B8, V31.B8]
+af21404c|	plan9	VLD1 (R13), [V15.B16, V16.B16, V17.B16, V18.B16]
+737edf0c|	plan9	VLD1.P 8(R19), [V19.D1]
+757dd10c|	plan9	VLD1.P (R11)(R17), [V21.D1]
+5ca3df4c|	plan9	VLD1.P 32(R26), [V28.B16, V29.B16]
+93a1ce0c|	plan9	VLD1.P (R12)(R14), [V19.B8, V20.B8]
+1c65df0c|	plan9	VLD1.P 24(R8), [V28.H4, V29.H4, V30.H4]
+4461d34c|	plan9	VLD1.P (R10)(R19), [V4.B16, V5.B16, V6.B16]
+b22edf4c|	plan9	VLD1.P 64(R21), [V18.D2, V19.D2, V20.D2, V21.D2]
+c12fcc4c|	plan9	VLD1.P (R30)(R12), [V1.D2, V2.D2, V3.D2, V4.D2]
+5a03400d|	plan9	LD1 (R26), [V26.B][0]
+8d93404d|	plan9	LD1 (R28), [V13.S][3]
+2186404d|	plan9	LD1 (R17), [V1.D][1]
+9604df4d|	plan9	LD1.P 1(R4), [V22.B][9]
+4a1dc94d|	plan9	LD1.P (R10)(R9), [V10.B][15]
+4852df4d|	plan9	LD1.P 2(R18), [V8.H][6]
+2582df4d|	plan9	LD1.P 4(R17), [V5.S][2]
+2191c84d|	plan9	LD1.P (R9)(R8), [V1.S][3]
+c284df4d|	plan9	LD1.P 8(R6), [V2.D][1]
+8f85ce0d|	plan9	LD1.P (R12)(R14), [V15.D][0]
+87cd400d|	plan9	VLD1R (R12), [V7.D1]
+3bc8df4d|	plan9	VLD1R 4(R1), [V27.S4]
+77c4dd4d|	plan9	VLD1R (R3)(R29), [V23.H8]
+5384404c|	plan9	VLD2 (R2), [V19.H8, V20.H8]
+ca87df0c|	plan9	VLD2 16(R30), [V10.H4, V11.H4]
+1280d70c|	plan9	VLD2 (R0)(R23), [V18.B8, V19.B8]
+4c0a604d|	plan9	LD2 (R18), [V12.B, V13.B][10]
+3080600d|	plan9	LD2 (R1), [V16.S, V17.S][0]
+6686600d|	plan9	LD2 (R19), [V6.D, V7.D][0]
+061eff0d|	plan9	LD2 2(R16), [V6.B, V7.B][7]
+db05fa0d|	plan9	LD2 (R14)(R26), [V27.B, V28.B][1]
+8a49ff4d|	plan9	LD2 4(R12), [V10.H, V11.H][5]
+bb59ec4d|	plan9	LD2 (R13)(R12), [V27.H, V28.H][7]
+5a82ff0d|	plan9	LD2 8(R18), [V26.S, V27.S][0]
+6180e30d|	plan9	LD2 (R3)(R3), [V1.S, V2.S][0]
+6485ff0d|	plan9	LD2 16(R11), [V4.D, V5.D][0]
+7c86ed4d|	plan9	LD2 (R19)(R13), [V28.D, V29.D][1]
+54c0604d|	plan9	VLD2R (R2), [V20.B16, V21.B16]
+fdcaff0d|	plan9	VLD2R 8(R23), [V29.S2, V30.S2]
+7bc5e40d|	plan9	VLD2R (R11)(R4), [V27.H4, V28.H4]
+b349404c|	plan9	VLD3 (R13), [V19.S4, V20.S4, V21.S4]
+cf46df4c|	plan9	VLD3 48(R22), [V15.H8, V16.H8, V17.H8]
+934acc4c|	plan9	VLD3 (R20)(R12), [V19.S4, V20.S4, V21.S4]
+2c33404d|	plan9	LD3 (R25), [V12.B, V13.B, V14.B][12]
+897a400d|	plan9	LD3 (R20), [V9.H, V10.H, V11.H][3]
+f9b2400d|	plan9	LD3 (R23), [V25.S, V26.S, V27.S][1]
+4aa7404d|	plan9	LD3 (R26), [V10.D, V11.D, V12.D][1]
+4e25df4d|	plan9	LD3 3(R10), [V14.B, V15.B, V16.B][9]
+7827c40d|	plan9	LD3 (R27)(R4), [V24.B, V25.B, V26.B][1]
+c4a3df4d|	plan9	LD3 12(R30), [V4.S, V5.S, V6.S][2]
+f0a1cf0d|	plan9	LD3 (R15)(R15), [V16.S, V17.S, V18.S][0]
+1ba7df0d|	plan9	LD3 24(R24), [V27.D, V28.D, V29.D][0]
+f7a7d50d|	plan9	LD3 (RSP)(R21), [V23.D, V24.D, V25.D][0]
+a9ed404d|	plan9	VLD3R (R13), [V9.D2, V10.D2, V11.D2]
+5aecdf4d|	plan9	VLD3R 24(R2), [V26.D2, V27.D2, V28.D2]
+bae9c74d|	plan9	VLD3R (R13)(R7), [V26.S4, V27.S4, V28.S4]
+5904404c|	plan9	VLD4 (R2), [V25.H8, V26.H8, V27.H8, V28.H8]
+743b604d|	plan9	LD4 (R27), [V20.B, V21.B, V22.B, V23.B][14]
+bda1600d|	plan9	LD4 (R13), [V29.S, V30.S, V31.S, V0.S][0]
+a3a4600d|	plan9	LD4 (R5), [V3.D, V4.D, V5.D, V6.D][0]
+2f3aff4d|	plan9	LD4 4(R17), [V15.B, V16.B, V17.B, V18.B][14]
+e73bef4d|	plan9	LD4 (RSP)(R15), [V7.B, V8.B, V9.B, V10.B][14]
+5d78ef0d|	plan9	LD4 (R2)(R15), [V29.H, V30.H, V31.H, V0.H][3]
+acb3ff0d|	plan9	LD4 16(R29), [V12.S, V13.S, V14.S, V15.S][1]
+a8b2f04d|	plan9	LD4 (R21)(R16), [V8.S, V9.S, V10.S, V11.S][3]
+75a7ff4d|	plan9	LD4 32(R27), [V21.D, V22.D, V23.D, V24.D][1]
+75a6ee4d|	plan9	LD4 (R19)(R14), [V21.D, V22.D, V23.D, V24.D][1]
+d8e3604d|	plan9	VLD4R (R30), [V24.B16, V25.B16, V26.B16, V27.B16]
+49e9ff0d|	plan9	VLD4R 16(R10), [V9.S2, V10.S2, V11.S2, V12.S2]
+81effc0d|	plan9	VLD4R (R28)(R28), [V1.D1, V2.D1, V3.D1, V4.D1]
+893e622c|	plan9	LDNP -240(R20), F15, F9
+f90e626c|	plan9	LDNP -480(R23), F3, F25
+b0224fac|	plan9	LDNP 480(R21), V8, V16
+9186de2c|	plan9	LDP.P 244(R20), (F17, F1)
+e820d06c|	plan9	LDP.P 256(R7), (F8, F8)
+417de8ac|	plan9	LDP.P -768(R10), (V1, V31)
+7969ed2d|	plan9	LDP.W -152(R11), (F25, F26)
+70c8c36d|	plan9	LDP.W 56(R3), (F16, F18)
+30b4c4ad|	plan9	LDP.W 144(R1), (V16, V13)
+a1857f2d|	plan9	LDP -4(R13), (F1, F1)
+f4ae786d|	plan9	LDP -120(R23), (F20, F11)
+998366ad|	plan9	LDP -816(R28), (V25, V0)
+7535453c|	plan9	MOVD.P 83(R11), F21
+5465477c|	plan9	MOVD.P 118(R10), F20
+a2b44bbc|	plan9	MOVD.P 187(R5), F2
+ab045bfc|	plan9	MOVD.P -80(R5), F11
+0515d43c|	plan9	MOVD.P -191(R8), V5
+43ad413c|	plan9	MOVD.W 26(R10), F3
+22cd4f7c|	plan9	MOVD.W 252(R9), F2
+5fad44bc|	plan9	MOVD.W 74(R10), F31
+db7d5afc|	plan9	MOVD.W -89(R14), F27
+15ccd63c|	plan9	MOVD.W -148(R0), V21
+95c34b3d|	plan9	MOVD 752(R28), F21
+f5885e7d|	plan9	MOVD 3908(R7), F21
+54db66bd|	plan9	MOVD 9944(R26), F20
+46ee78fd|	plan9	MOVD 29144(R18), F6
+0cc4e93d|	plan9	MOVD 42768(R0), V12
+ae79703c|	plan9	MOVD R16<<1(R13), F14
+3e6b6dfc|	plan9	MOVD R13(R25), F30
+a278ff3c|	plan9	MOVD ZR<<4(R5), V2
+ed02563c|	plan9	LDUR -160(R23), F13
+01c0507c|	plan9	LDUR -244(R0), F1
+7fd24ebc|	plan9	LDUR 237(R19), F31
+7a734ffc|	plan9	LDUR 247(R27), F26
+d4a3dd3c|	plan9	LDUR -38(R30), V20
+1c97250e|	plan9	VMLA V5.B8, V24.B8, V28.B8
+af97a12e|	plan9	VMLS V1.S2, V29.S2, V15.S2
+2b061f5e|	plan9	VMOV V17.B[15], F11
+805e086e|	plan9	VMOV V20.D[1], V0.D[0]
+d91fbc4e|	plan9	VORR V28.B16, V30.B16, V25.B16
+a43f040e|	plan9	VMOV V29.S[0], R4
+fbe6054f|	plan9	VMOVI $183, V27.B16
+9b75024f|	plan9	VORR $(76<<24), V27.S4
+8436020f|	plan9	VORR $(84<<8), V4.S2
+19f5010f|	plan9	FMOV $12., V25.S2
+02e5062f|	plan9	MOVI $-281470698520576, F2
+d6e5066f|	plan9	VMOVI $-281470681743616, V22.D2
+be9c240e|	plan9	VMUL V4.B8, V5.B8, V30.B8
+2659202e|	plan9	VMVN V9.B8, V6.B8
+f394046f|	plan9	VBIC $135, V19.H8
+d856056f|	plan9	VBIC $(182<<16), V24.S4
+2f85022f|	plan9	VMVNI $73, V15.H4
+24baa02e|	plan9	VNEG V17.S2, V4.S2
+145b206e|	plan9	VMVN V24.B16, V20.B16
+191fff4e|	plan9	VORN V31.B16, V24.B16, V25.B16
+6f96004f|	plan9	VORR $19, V15.H8
+a564020f|	plan9	VMOVI $(69<<24), V5.S2
+ae1ead0e|	plan9	VORR V13.B8, V21.B8, V14.B8
+f2e1e00e|	plan9	VPMULL V0.D1, V15.D1, V18.Q1
+0d426e2e|	plan9	VRADDHN V14.S4, V16.S4, V13.H4
+4443246e|	plan9	VRADDHN2 V4.H8, V26.H8, V4.B16
+015b602e|	plan9	VRBIT V24.B8, V1.B8
+4209202e|	plan9	VREV32 V10.B8, V2.B8
+d109a04e|	plan9	VREV64 V14.S4, V17.S4
+5a8e380f|	plan9	VRSHRN $8, V18.D2, V26.S2
+438d234f|	plan9	VRSHRN2 $29, V10.D2, V3.S4
+a861716e|	plan9	VRSUBHN2 V17.S4, V13.S4, V8.H8
+017c2f0e|	plan9	VSABA V15.B8, V0.B8, V1.B8
+5d51a90e|	plan9	VSABAL V9.S2, V10.S2, V29.D2
+c076a04e|	plan9	VSABD V0.S4, V22.S4, V0.S4
+2d722e0e|	plan9	VSABDL V14.B8, V17.B8, V13.H8
+1f732e4e|	plan9	VSABDL2 V14.B16, V24.B16, V31.H8
+c628604e|	plan9	VSADDLP V6.H8, V6.S4
+103b704e|	plan9	SADDLV V24.H8, F16
+8f122f0e|	plan9	VSADDW V15.B8, V20.H8, V15.H8
+30e6755f|	plan9	SCVTF $11, F17, F16
+73e7544f|	plan9	SCVTF $44, V27.D2, V19.D2
+51d9615e|	plan9	SCVTFDD F10, F17
+fad9210e|	plan9	SCVTF V15.S2, V26.S2
+96c0421e|	plan9	SCVTF $16, R4, F22
+76e1029e|	plan9	SCVTF $8, R11, F22
+a791429e|	plan9	SCVTF $28, R13, F7
+f100221e|	plan9	SCVTFWS R7, F17
+e101621e|	plan9	SCVTFWD R15, F1
+6e03229e|	plan9	SCVTFS R27, F14
+0b01629e|	plan9	SCVTFD R8, F11
+2401025e|	plan9	SHA1C V2.S4, F9, V4
+5d08285e|	plan9	SHA1H F2, F29
+65210d5e|	plan9	SHA1M V13.S4, F11, V5
+29131a5e|	plan9	SHA1P V26.S4, F25, V9
+2b311a5e|	plan9	VSHA1SU0 V26.S4, V9.S4, V11.S4
+0919285e|	plan9	VSHA1SU1 V8.S4, V9.S4
+f052035e|	plan9	SHA256H2 V3.S4, V23, V16
+fe401e5e|	plan9	SHA256H V30.S4, V7, V30
+7529285e|	plan9	VSHA256SU0 V11.S4, V21.S4
+cc60195e|	plan9	VSHA256SU1 V25.S4, V6.S4, V12.S4
+8b56060f|	plan9	VORR $(212<<16), V11.S2
+3f3aa16e|	plan9	VSHLL2 $32, V17.S4, V31.D2
+0986394f|	plan9	VSHRN2 $7, V16.D2, V9.S4
+35276e4e|	plan9	VSHSUB V14.H8, V25.H8, V21.H8
+e2556d7f|	plan9	SLI $45, F15, F2
+f7541e6f|	plan9	VSLI $14, V7.H8, V23.H8
+3167630e|	plan9	VSMAX V3.H4, V25.H4, V17.H4
+68a6230e|	plan9	VSMAXP V3.B8, V19.B8, V8.B8
+a4aa304e|	plan9	SMAXV V21.B16, F4
+2520440f|	plan9	VSMLAL V4.H[0], V1.H4, V5.S4
+8c286f4f|	plan9	VSMLAL2 V15.H[6], V4.H8, V12.S4
+3a82660e|	plan9	VSMLAL V6.H4, V17.H4, V26.S4
+d92f1f0e|	plan9	SMOVW V30.B[15], R25
+912d114e|	plan9	SMOV V12.B[8], R17
+b87ae05e|	plan9	SQABS F21, F24
+2d7b200e|	plan9	VSQABS V25.B8, V13.B8
+560f645e|	plan9	SQADD F4, F26, F22
+4f0da54e|	plan9	VSQADD V5.S4, V10.S4, V15.S4
+5992ba5e|	plan9	SQDMLAL F26, F18, F25
+b892684e|	plan9	VSQDMLAL2 V8.H8, V21.H8, V24.S4
+63786e5f|	plan9	SQDMLSL V14.H[6], F3, F3
+0c79a10f|	plan9	VSQDMLSL V1.S[3], V8.S2, V12.D2
+1d73504f|	plan9	VSQDMLSL2 V0.H[1], V24.H8, V29.S4
+6cb36c5e|	plan9	SQDMLSL F12, F27, F12
+82b36e4e|	plan9	VSQDMLSL2 V14.H8, V28.H8, V2.S4
+8dca5d4f|	plan9	VSQDMULH V13.H[5], V20.H8, V13.H8
+fcb6b64e|	plan9	VSQDMULH V22.S4, V23.S4, V28.S4
+d6b0974f|	plan9	VSQDMULL2 V23.S[0], V6.S4, V22.D2
+afd0b84e|	plan9	VSQDMULL2 V24.S4, V5.S4, V15.D2
+067b207e|	plan9	SQNEG F24, F6
+9979606e|	plan9	VSQNEG V12.H8, V25.H8
+bfdbae0f|	plan9	VSQRDMULH V14.S[3], V29.S2, V31.S2
+c3b7a07e|	plan9	SQRDMULH F0, F30, F3
+845d3d5e|	plan9	SQRSHL F29, F12, F4
+495dba0e|	plan9	VSQRSHL V26.S2, V10.S2, V9.S2
+fa8e0d7f|	plan9	SQRSHRUN $3, F23, F26
+cf75185f|	plan9	SQSHL $8, F14, F15
+a975250f|	plan9	VSQSHL $5, V13.S2, V9.S2
+424da05e|	plan9	SQSHL F0, F10, F2
+464db90e|	plan9	VSQSHL V25.S2, V10.S2, V6.S2
+af656d7f|	plan9	SQSHLU $45, F13, F15
+e564436f|	plan9	VSQSHLU $3, V7.D2, V5.D2
+c1973b5f|	plan9	SQSHRN $5, F30, F1
+d586036f|	plan9	VMVNI $118, V21.H8
+4c2ea95e|	plan9	SQSUB F9, F18, F12
+df2efe4e|	plan9	VSQSUB V30.D2, V22.D2, V31.D2
+c149a10e|	plan9	VSQXTN V14.D2, V1.S2
+712a217e|	plan9	SQXTUN F19, F17
+9a29a12e|	plan9	VSQXTUN V12.D2, V26.S2
+6a166e0e|	plan9	VSRHADD V14.H4, V19.H4, V10.H4
+0445647f|	plan9	SRI $28, F8, F4
+6f44172f|	plan9	VSRI $9, V3.H4, V15.H4
+cd56f94e|	plan9	VSRSHL V25.D2, V22.D2, V13.D2
+12345b5f|	plan9	SRSRA $37, F0, F18
+f746fa5e|	plan9	SSHL F26, F23, F23
+89476c4e|	plan9	VSSHL V12.H8, V28.H8, V9.H8
+0da60e0f|	plan9	VSSHLL $6, V16.B8, V13.H8
+a504585f|	plan9	SSHR $40, F5, F5
+3b07544f|	plan9	VSSHR $44, V25.D2, V27.D2
+3417350f|	plan9	VSSRA $11, V25.S2, V20.S2
+1a213f0e|	plan9	VSSUBL V31.B8, V8.B8, V26.H8
+1322a34e|	plan9	VSSUBL2 V3.S4, V16.S4, V19.D2
+e931b84e|	plan9	VSSUBW2 V24.S4, V15.D2, V9.D2
+dd7d004c|	plan9	VST1 (R14), [V29.D2]
+cea4000c|	plan9	VST1 (R6), [V14.H4, V15.H4]
+5a64000c|	plan9	VST1 (R2), [V26.H4, V27.H4, V28.H4]
+2b2c004c|	plan9	VST1 (R1), [V11.D2, V12.D2, V13.D2, V14.D2]
+39719f0c|	plan9	VST1 8(R9), [V25.B8]
+b771874c|	plan9	VST1 (R13)(R7), [V23.B16]
+1da39f0c|	plan9	VST1 16(R24), [V29.B8, V30.B8]
+20a0800c|	plan9	VST1 (R1)(R0), [V0.B8, V1.B8]
+5a6a9f4c|	plan9	VST1 48(R18), [V26.S4, V27.S4, V28.S4]
+0d69994c|	plan9	VST1 (R8)(R25), [V13.S4, V14.S4, V15.S4]
+7e239f0c|	plan9	VST1 32(R27), [V30.B8, V31.B8, V0.B8, V1.B8]
+9a2d8e0c|	plan9	VST1 (R12)(R14), [V26.D1, V27.D1, V28.D1, V29.D1]
+fd0b004d|	plan9	ST1 (RSP), [V29.B][10]
+1058004d|	plan9	ST1 (R0), [V16.H][7]
+0593000d|	plan9	ST1 (R24), [V5.S][1]
+3d87000d|	plan9	ST1 (R25), [V29.D][0]
+1a079f0d|	plan9	ST1 1(R24), [V26.B][1]
+421b8f4d|	plan9	ST1 (R26)(R15), [V2.B][14]
+54489f4d|	plan9	ST1 2(R2), [V20.H][5]
+c4809f4d|	plan9	ST1 4(R6), [V4.S][2]
+0481840d|	plan9	ST1 (R8)(R4), [V4.S][0]
+6b859f0d|	plan9	ST1 8(R11), [V11.D][0]
+f7878e4d|	plan9	ST1 (RSP)(R14), [V23.D][1]
+e788004c|	plan9	VST2 (R7), [V7.S4, V8.S4]
+79889f0c|	plan9	VST2 16(R3), [V25.S2, V26.S2]
+a502204d|	plan9	ST2 (R21), [V5.B, V6.B][8]
+0e50204d|	plan9	ST2 (R0), [V14.H, V15.H][6]
+6b93204d|	plan9	ST2 (R27), [V11.S, V12.S][3]
+0987200d|	plan9	ST2 (R24), [V9.D, V10.D][0]
+7003bf0d|	plan9	ST2 2(R27), [V16.B, V17.B][0]
+1a09a94d|	plan9	ST2 (R8)(R9), [V26.B, V27.B][10]
+1e43b00d|	plan9	ST2 (R24)(R16), [V30.H, V31.H][0]
+1a82bf0d|	plan9	ST2 8(R16), [V26.S, V27.S][0]
+9892a50d|	plan9	ST2 (R20)(R5), [V24.S, V25.S][1]
+5884bf0d|	plan9	ST2 16(R2), [V24.D, V25.D][0]
+9e87a34d|	plan9	ST2 (R28)(R3), [V30.D, V31.D][1]
+4e47004c|	plan9	VST3 (R26), [V14.H8, V15.H8, V16.H8]
+76489f4c|	plan9	VST3 48(R3), [V22.S4, V23.S4, V24.S4]
+3b48860c|	plan9	VST3 (R1)(R6), [V27.S2, V28.S2, V29.S2]
+e52a000d|	plan9	ST3 (R23), [V5.B, V6.B, V7.B][2]
+6f73004d|	plan9	ST3 (R27), [V15.H, V16.H, V17.H][6]
+9bb1004d|	plan9	ST3 (R12), [V27.S, V28.S, V29.S][3]
+0ca7000d|	plan9	ST3 (R24), [V12.D, V13.D, V14.D][0]
+2a259f0d|	plan9	ST3 3(R9), [V10.B, V11.B, V12.B][1]
+0524860d|	plan9	ST3 (R0)(R6), [V5.B, V6.B, V7.B][1]
+94689a4d|	plan9	ST3 (R4)(R26), [V20.H, V21.H, V22.H][5]
+c2a19f4d|	plan9	ST3 12(R14), [V2.S, V3.S, V4.S][2]
+5fb38c0d|	plan9	ST3 (R26)(R12), [V31.S, V0.S, V1.S][1]
+6da59f4d|	plan9	ST3 24(R11), [V13.D, V14.D, V15.D][1]
+32a7924d|	plan9	ST3 (R25)(R18), [V18.D, V19.D, V20.D][1]
+5b03000c|	plan9	VST4 (R26), [V27.B8, V28.B8, V29.B8, V30.B8]
+cd059f0c|	plan9	VST4 32(R14), [V13.H4, V14.H4, V15.H4, V16.H4]
+8601820c|	plan9	VST4 (R12)(R2), [V6.B8, V7.B8, V8.B8, V9.B8]
+7925200d|	plan9	ST4 (R11), [V25.B, V26.B, V27.B, V28.B][1]
+cd7a204d|	plan9	ST4 (R22), [V13.H, V14.H, V15.H, V16.H][7]
+dfb2204d|	plan9	ST4 (R22), [V31.S, V0.S, V1.S, V2.S][3]
+daa4200d|	plan9	ST4 (R6), [V26.D, V27.D, V28.D, V29.D][0]
+2135bf0d|	plan9	ST4 4(R9), [V1.B, V2.B, V3.B, V4.B][5]
+7727a90d|	plan9	ST4 (R27)(R9), [V23.B, V24.B, V25.B, V26.B][1]
+b4a3bf0d|	plan9	ST4 16(R29), [V20.S, V21.S, V22.S, V23.S][0]
+1ba3ae0d|	plan9	ST4 (R24)(R14), [V27.S, V28.S, V29.S, V30.S][0]
+93a4bf0d|	plan9	ST4 32(R4), [V19.D, V20.D, V21.D, V22.D][0]
+50a6b80d|	plan9	ST4 (R18)(R24), [V16.D, V17.D, V18.D, V19.D][0]
+79b53d2c|	plan9	STNP -20(R11), F13, F25
+d895326c|	plan9	STNP -216(R14), F5, F24
+d1810dac|	plan9	STNP 432(R14), V0, V17
+08728c2c|	plan9	STP.P (F8, F28), 96(R16)
+ac1ba16c|	plan9	STP.P (F12, F6), -496(R29)
+f4fab1ac|	plan9	STP.P (V20, V30), -464(R23)
+c15bbe2d|	plan9	STP.W (F1, F22), -16(R30)
+2422856d|	plan9	STP.W (F4, F8), 80(R17)
+3d5282ad|	plan9	STP.W (V29, V20), 64(R17)
+5df5352d|	plan9	STP (F29, F29), -84(R10)
+5c54286d|	plan9	STP (F28, F21), -384(R2)
+753c11ad|	plan9	STP (V21, V15), 544(R3)
+54e4033c|	plan9	MOVD.P F20, 62(R2)
+aa54137c|	plan9	MOVD.P F10, -203(R5)
+c9d615bc|	plan9	MOVD.P F9, -163(R22)
+fc471efc|	plan9	MOVD.P F28, -28(RSP)
+20f78d3c|	plan9	MOVD.P V0, 223(R25)
+028d1b3c|	plan9	MOVD.W F2, -72(R8)
+35be037c|	plan9	MOVD.W F21, 59(R17)
+b98c15bc|	plan9	MOVD.W F25, -168(R5)
+fd1e11fc|	plan9	MOVD.W F29, -239(R23)
+13ec9a3c|	plan9	MOVD.W V19, -82(R0)
+b12d123d|	plan9	MOVD F17, 1163(R13)
+d6500b7d|	plan9	MOVD F22, 1448(R6)
+d46e39bd|	plan9	MOVD F20, 14700(R22)
+b84f30fd|	plan9	MOVD F24, 24728(R29)
+3cee993d|	plan9	MOVD V28, 26544(R17)
+ed7b253c|	plan9	MOVD F13, R5<<1(RSP)
+1c68a43c|	plan9	MOVD V28, R4(R0)
+dcb1023c|	plan9	MOVD F28, 43(R14)
+6701117c|	plan9	MOVD F7, -240(R11)
+85b11bbc|	plan9	MOVD F5, -69(R12)
+8ea10efc|	plan9	MOVD F14, 234(R12)
+eab08f3c|	plan9	MOVD V10, 251(R7)
+ca876a2e|	plan9	VSUB V10.H4, V30.H4, V10.H4
+603be05e|	plan9	SUQADD F27, F0
+513a600e|	plan9	VSUQADD V18.H4, V17.H4
+25231c4e|	plan9	VTBL V28.B16, [V25.B16, V26.B16], V5.B16
+8c40100e|	plan9	VTBL V16.B8, [V4.B16, V5.B16, V6.B16], V12.B8
+0462040e|	plan9	VTBL V4.B8, [V16.B16, V17.B16, V18.B16, V19.B16], V4.B8
+34000f0e|	plan9	VTBL V15.B8, [V1.B16], V20.B8
+eb301f4e|	plan9	VTBX V31.B16, [V7.B16, V8.B16], V11.B16
+bb51124e|	plan9	VTBX V18.B16, [V13.B16, V14.B16, V15.B16], V27.B16
+cf701d0e|	plan9	VTBX V29.B8, [V6.B16, V7.B16, V8.B16, V9.B16], V15.B8
+4213080e|	plan9	VTBX V8.B8, [V26.B16], V2.B8
+2b2b114e|	plan9	VTRN1 V17.B16, V25.B16, V11.B16
+766ada4e|	plan9	VTRN2 V26.D2, V19.D2, V22.D2
+4152672e|	plan9	VUABAL V7.H4, V18.H4, V1.S4
+0953296e|	plan9	VUABAL2 V9.B16, V24.B16, V9.H8
+41756c6e|	plan9	VUABD V12.H8, V10.H8, V1.H8
+3670ae2e|	plan9	VUABDL V14.S2, V1.S2, V22.D2
+5401312e|	plan9	VUADDL V17.B8, V10.B8, V20.H8
+d103286e|	plan9	VUADDL2 V8.B16, V30.B16, V17.H8
+a92a206e|	plan9	VUADDLP V21.B16, V9.H8
+b839706e|	plan9	UADDLV V13.H8, F24
+ea106d2e|	plan9	VUADDW V13.H4, V7.S4, V10.S4
+c010726e|	plan9	VUADDW2 V18.H8, V6.S4, V0.S4
+e7e5517f|	plan9	UCVTF $47, F15, F7
+49e7376f|	plan9	UCVTF $9, V26.S4, V9.S4
+4ada617e|	plan9	UCVTFDD F18, F10
+6b82431e|	plan9	UCVTF $32, R19, F11
+db84039e|	plan9	UCVTF $31, R6, F27
+1c72439e|	plan9	UCVTF $36, R16, F28
+f301231e|	plan9	UCVTFWS R15, F19
+3503631e|	plan9	UCVTFWD R25, F21
+e602239e|	plan9	UCVTFS R23, F6
+d503639e|	plan9	UCVTFD R30, F21
+ec04606e|	plan9	VUHADD V0.H8, V7.H8, V12.H8
+3f65782e|	plan9	VUMAX V24.H4, V9.H4, V31.H4
+afa6232e|	plan9	VUMAXP V3.B8, V21.B8, V15.B8
+cdaa706e|	plan9	UMAXV V22.H8, F13
+736c236e|	plan9	VUMIN V3.B16, V3.B16, V19.B16
+a0afa62e|	plan9	VUMINP V6.S2, V29.S2, V0.S2
+3c229e2f|	plan9	VUMLAL V30.S[0], V17.S2, V28.D2
+9d29a56f|	plan9	VUMLAL2 V5.S[3], V12.S4, V29.D2
+6c80392e|	plan9	VUMLAL V25.B8, V3.B8, V12.H8
+4f60692f|	plan9	VUMLSL V9.H[2], V2.H4, V15.S4
+61a1606e|	plan9	VUMLSL2 V0.H8, V11.H8, V1.S4
+183e0b0e|	plan9	UMOVW V16.B[5], R24
+c0a89b6f|	plan9	VUMULL2 V27.S[2], V6.S4, V0.D2
+36c0736e|	plan9	VUMULL2 V19.H8, V1.H8, V22.S4
+120d757e|	plan9	UQADD F21, F8, F18
+3a0c2e2e|	plan9	VUQADD V14.B8, V1.B8, V26.B8
+0d5d617e|	plan9	UQRSHL F1, F8, F13
+4d5cb16e|	plan9	VUQRSHL V17.S4, V2.S4, V13.S4
+439c382f|	plan9	VUQRSHRN $8, V2.D2, V3.S2
+9d745c7f|	plan9	UQSHL $28, F4, F29
+7b76656f|	plan9	VUQSHL $37, V19.D2, V27.D2
+774ef37e|	plan9	UQSHL F19, F19, F23
+124eb32e|	plan9	VUQSHL V19.S2, V16.S2, V18.S2
+bc961f6f|	plan9	VUQSHRN2 $1, V21.S4, V28.H8
+a62ce07e|	plan9	UQSUB F0, F5, F6
+0f2dae2e|	plan9	VUQSUB V14.S2, V8.S2, V15.S2
+b24b217e|	plan9	UQXTN F29, F18
+f148216e|	plan9	VUQXTN2 V7.H8, V17.B16
+7d15a42e|	plan9	VURHADD V4.S2, V11.S2, V29.S2
+9055fc6e|	plan9	VURSHL V28.D2, V12.D2, V16.D2
+eb275e7f|	plan9	URSHR $34, F31, F11
+c0347c7f|	plan9	URSRA $4, F6, F0
+fe44e97e|	plan9	USHL F9, F7, F30
+fa47e86e|	plan9	VUSHL V8.D2, V31.D2, V26.D2
+95a7262f|	plan9	VUSHLL $6, V28.S2, V21.D2
+9ca7096f|	plan9	VUSHLL2 $1, V28.B16, V28.H8
+8a07527f|	plan9	USHR $46, F28, F10
+c7076b6f|	plan9	VUSHR $21, V30.D2, V7.D2
+8d39e07e|	plan9	USQADD F12, F13
+f716727f|	plan9	USRA $14, F23, F23
+3f14066f|	plan9	VBIC $193, V31.S4
+b423ac2e|	plan9	VUSUBL V12.S2, V29.S2, V20.D2
+7c22736e|	plan9	VUSUBL2 V19.H8, V19.H8, V28.S4
+76317d2e|	plan9	VUSUBW V29.H4, V11.S4, V22.S4
+8f302a6e|	plan9	VUSUBW2 V10.B16, V4.H8, V15.H8
+c5a4286f|	plan9	VUSHLL2 $8, V6.S4, V5.D2
+d3198c0e|	plan9	VUZP1 V12.S2, V14.S2, V19.S2
+c05bdb4e|	plan9	VUZP2 V27.D2, V30.D2, V0.D2
+362b610e|	plan9	VXTN V25.S4, V22.H4
+0c29214e|	plan9	VXTN2 V8.H8, V12.B16
+2b39c64e|	plan9	VZIP1 V6.D2, V9.D2, V11.D2
+9500091a|	plan9	ADCW R9, R4, R21
+c2001a9a|	plan9	ADC R26, R6, R2
+6a02163a|	plan9	ADCSW R22, R19, R10
+0c0118ba|	plan9	ADCS R24, R8, R12
+b1c42b0b|	plan9	ADDW R11.SXTW<<1, R5, R17
+bf15368b|	plan9	ADD R22.UXTB<<5, R13, RSP
+be1f468b|	plan9	ADD R6>>7, R29, R30
+8f51352b|	plan9	ADDSW R21.UXTW<<4, R12, R15
+97043eab|	plan9	ADDS R30.UXTB<<1, R4, R23
+09b00931|	plan9	ADDSW $620, R0, R9
+4de204ab|	plan9	ADDS R4<<56, R18, R13
+f6b60912|	plan9	ANDW $4288675743, R23, R22
+a6d13b92|	plan9	AND $-2025524839466146845, R13, R6
+1cc0138a|	plan9	AND R19<<48, R0, R28
+73882072|	plan9	ANDSW $458759, R3, R19
+b5780af2|	plan9	ANDS $-9007199256838145, R5, R21
+766c90ea|	plan9	ANDS R16->27, R3, R22
+a72ac31a|	plan9	ASRW R3, R21, R7
+ff28d59a|	plan9	ASR R21, R7, ZR
+3e7f0913|	plan9	ASRW $9, R25, R30
+bafd5493|	plan9	ASR $20, R13, R26
+302ad21a|	plan9	ASRW R18, R17, R16
+602bd79a|	plan9	ASR R23, R27, R0
+4fa4df54|	plan9	BAL -66270(PC)
+a2e9cf15|	plan9	JMP 30402978(PC)
+eff373b3|	plan9	BFXIL $51, ZR, $10, R15
+9e3e7db3|	plan9	BFI $3, R20, $16, R30
+87fa41b3|	plan9	BFXIL $1, R20, $62, R7
+b831f80a|	plan9	BICW R24@>12, R13, R24
+ffe0ae8a|	plan9	BIC R14->56, R7, ZR
+7c2c276a|	plan9	BICSW R7<<11, R3, R28
+ccf2fbea|	plan9	BICS R27@>60, R22, R12
+722cd195|	plan9	CALL 30485618(PC)
+20003fd6|	plan9	CALL (R1)
+e0021fd6|	plan9	JMP (R23)
+80db37d4|	plan9	BRK $48860
+e048533a|	plan9	CCMNW MI, R7, $19, $0
+e7da4fba|	plan9	CCMN LE, R23, $15, $7
+67f2583a|	plan9	CCMNW AL, R19, R24, $7
+60a05aba|	plan9	CCMN GE, R3, R26, $0
+6a3b517a|	plan9	CCMPW LO, R27, $17, $10
+8a4b55fa|	plan9	CCMP MI, R28, $21, $10
+ed934b7a|	plan9	CCMPW LS, ZR, R11, $13
+24414ffa|	plan9	CCMP MI, R9, R15, $4
+0e169c1a|	plan9	CSINCW NE, R16, R28, R14
+8264949a|	plan9	CSINC VS, R4, R20, R2
+b363935a|	plan9	CSINVW VS, R29, R19, R19
+ff619dda|	plan9	CSINV VS, R15, R29, ZR
+5f3703d5|	plan9	CLREX $7
+0017c05a|	plan9	CLSW R24, R0
+8216c0da|	plan9	CLS R20, R2
+3310c05a|	plan9	CLZW R1, R19
+6e13c0da|	plan9	CLZ R27, R14
+7fd02b2b|	plan9	CMNW R11.SXTW<<4, R3
+5f3928ab|	plan9	CMN R8.UXTH<<6, R10
+1fb92cb1|	plan9	CMN $2862, R8
+ff164eab|	plan9	CMN R14>>5, R23
+ff71256b|	plan9	CMPW R5.UXTX<<4, R15
+df6034eb|	plan9	CMP R20.UXTX, R6
+ff776af1|	plan9	CMP $(2717<<12), RSP
+80e4855a|	plan9	CSNEGW AL, R4, R5, R0
+da3490da|	plan9	CSNEG LO, R6, R16, R26
+af40c71a|	plan9	CRC32B R7, R5, R15
+c546cf1a|	plan9	CRC32H R15, R22, R5
+6148c01a|	plan9	CRC32W R0, R3, R1
+0f4eda9a|	plan9	CRC32X R26, R16, R15
+4950d01a|	plan9	CRC32CB R16, R2, R9
+8155c31a|	plan9	CRC32CH R3, R12, R1
+835ace1a|	plan9	CRC32CW R14, R20, R3
+f05fc59a|	plan9	CRC32CX R5, ZR, R16
+0ae3901a|	plan9	CSELW AL, R24, R16, R10
+ed51969a|	plan9	CSEL PL, R15, R22, R13
+ee679f1a|	plan9	CSETW VC, R14
+ed579f9a|	plan9	CSET MI, R13
+f2539f5a|	plan9	CSETMW MI, R18
+ffe39fda|	plan9	CSINV AL, ZR, ZR, ZR
+9d25941a|	plan9	CSINCW HS, R12, R20, R29
+afb7829a|	plan9	CSINC LT, R29, R2, R15
+7602895a|	plan9	CSINVW EQ, R19, R9, R22
+011394da|	plan9	CSINV NE, R24, R20, R1
+68b7935a|	plan9	CSNEGW LT, R27, R19, R8
+a32784da|	plan9	CSNEG HS, R29, R4, R3
+8159a6d4|	plan9	DCPS1 $13004
+c2d9aad4|	plan9	DCPS2 $22222
+63ceb7d4|	plan9	DCPS3 $48755
+bf3903d5|	plan9	DMB $9
+e003bfd6|	plan9	DRPS
+9f3603d5|	plan9	DSB $6
+fc76a9ca|	plan9	EON R9->29, R23, R28
+540f2352|	plan9	EORW $3758096385, R26, R20
+187e1ed2|	plan9	EOR $-1, R16, R24
+fd37004a|	plan9	EORW R0<<13, ZR, R29
+b8c542ca|	plan9	EOR R2>>49, R13, R24
+e0039fd6|	plan9	ERET
+5f26c193|	plan9	EXTR $9, R1, R18, ZR
+7f2003d5|	plan9	WFI
+ff2a03d5|	plan9	HINT $87
+804a59d4|	plan9	HLT $51796
+df3003d5|	plan9	ISB $0
+10fcdf88|	plan9	LDARW (R0), R16
+fafcdfc8|	plan9	LDAR (R7), R26
+30fedf08|	plan9	LDARB (R17), R16
+63fedf48|	plan9	LDARH (R19), R3
+82ba7f88|	plan9	LDAXPW (R20), R14, R2
+d6917fc8|	plan9	LDAXP (R14), R4, R22
+59ff5f88|	plan9	LDAXRW (R26), R25
+fefe5fc8|	plan9	LDAXR (R23), R30
+a0fc5f08|	plan9	LDAXRB (R5), R0
+fafd5f48|	plan9	LDAXRH (R15), R26
+b8804428|	plan9	LDNPW 36(R5), R0, R24
+93e969a8|	plan9	LDNP -360(R12), R26, R19
+caccef28|	plan9	LDP.P -132(R6), (R10, R19)
+7365c3a8|	plan9	LDP.P 48(R11), (R19, R25)
+3106ca29|	plan9	LDP.W 80(R17), (R17, R1)
+0c02f7a9|	plan9	LDP.W -144(R16), (R12, R0)
+41af6529|	plan9	LDP -212(R26), (R1, R11)
+706b65a9|	plan9	LDP -432(R27), (R16, R26)
+746ecf68|	plan9	LDPSW 120(R19), R27, R20
+c051c669|	plan9	LDPSW 48(R14), R20, R0
+aded5b69|	plan9	LDPSW 220(R13), R27, R13
+990457b8|	plan9	MOVWU.P -144(R4), R25
+bbd556f8|	plan9	MOVD.P -147(R13), R27
+a45c51b8|	plan9	MOVWU.W -235(R5), R4
+344c41f8|	plan9	MOVD.W 20(R1), R20
+2d8755b9|	plan9	MOVWU 5508(R25), R13
+56e360f9|	plan9	MOVD 16832(R26), R22
+3b264e38|	plan9	MOVBU.P 226(R17), R27
+898f5738|	plan9	MOVBU.W -136(R28), R9
+c44e6839|	plan9	MOVBU 2579(R22), R4
+2d687738|	plan9	MOVBU R23(R1), R13
+4d475978|	plan9	MOVHU.P -108(R26), R13
+39de5278|	plan9	MOVHU.W -211(R17), R25
+9cc54879|	plan9	MOVHU 1122(R12), R28
+3967cb38|	plan9	MOVBW.P 182(R25), R25
+abf69438|	plan9	MOVB.P -177(R21), R11
+159ed138|	plan9	MOVBW.W -231(R16), R21
+b63e8038|	plan9	MOVB.W 3(R21), R22
+4491c939|	plan9	MOVBW 612(R10), R4
+497e8039|	plan9	MOVB 31(R18), R9
+7d6bf638|	plan9	MOVBW R22(R27), R29
+e578ba38|	plan9	MOVB R26<<1(R7), R5
+9f06ca78|	plan9	MOVHW.P 160(R20), ZR
+15c59d78|	plan9	MOVH.P -36(R8), R21
+c07fd278|	plan9	MOVHW.W -217(R30), R0
+bdec9278|	plan9	MOVH.W -210(R5), R29
+10e2c979|	plan9	MOVHW 1264(R16), R16
+54d29d79|	plan9	MOVH 3816(R18), R20
+eb9484b8|	plan9	MOVW.P 73(R7), R11
+ba2e8ab8|	plan9	MOVW.W 162(R21), R26
+ac7f8ab9|	plan9	MOVW 2684(R29), R12
+f8b941b8|	plan9	LDTRW 27(R15), R24
+fc0a4ef8|	plan9	LDTR 224(R23), R28
+60d84638|	plan9	LDTRBW 109(R3), R0
+44685978|	plan9	LDTRHW -106(R2), R4
+5379dc38|	plan9	LDTRSBW -57(R10), R19
+ade99538|	plan9	LDTRSB -162(R13), R13
+905ac078|	plan9	LDTRSHW 5(R20), R16
+10898478|	plan9	LDTRSH 72(R8), R16
+37188eb8|	plan9	LDTRSW 225(R1), R23
+992351b8|	plan9	LDURW -238(R28), R25
+c9f155f8|	plan9	LDUR -161(R14), R9
+76e14e38|	plan9	LDURBW 238(R11), R22
+47b24478|	plan9	LDURHW 75(R18), R7
+4020da38|	plan9	LDURSBW -94(R2), R0
+0dd09e38|	plan9	LDURSB -19(R0), R13
+8f81d478|	plan9	LDURSHW -184(R12), R15
+96918378|	plan9	LDURSH 57(R12), R22
+b2e383b8|	plan9	LDURSW 62(R29), R18
+d3717f88|	plan9	LDXPW (R14), R28, R19
+cb677fc8|	plan9	LDXP (R30), R25, R11
+ed7c5f88|	plan9	LDXRW (R7), R13
+aa7d5fc8|	plan9	LDXR (R13), R10
+1c7d5f08|	plan9	LDXRB (R8), R28
+de7f5f48|	plan9	LDXRH (R30), R30
+1622dc1a|	plan9	LSLW R28, R16, R22
+cd20d59a|	plan9	LSL R21, R6, R13
+882957d3|	plan9	UBFIZ $41, R12, $11, R8
+3320cc1a|	plan9	LSLW R12, R1, R19
+7320de9a|	plan9	LSL R30, R3, R19
+af25d31a|	plan9	LSRW R19, R13, R15
+e426c39a|	plan9	LSR R3, R23, R4
+e87f0653|	plan9	LSRW $6, ZR, R8
+85fe5fd3|	plan9	LSR $31, R20, R5
+0025dc1a|	plan9	LSRW R28, R8, R0
+6e27c79a|	plan9	LSR R7, R27, R14
+6d69111b|	plan9	MADDW R17, R26, R11, R13
+245d0d9b|	plan9	MADD R13, R23, R9, R4
+85fe1f1b|	plan9	MNEGW ZR, R20, R5
+9bfc199b|	plan9	MNEG R25, R4, R27
+13000011|	plan9	ADDW $0, R0, R19
+e3000091|	plan9	ADD $0, R7, R3
+986c9e12|	plan9	MOVW $4294904987, R24
+cb24f092|	plan9	MOVD $9140618393701842943, R11
+3cbb88d2|	plan9	MOVD $17881, R28
+e4170232|	plan9	MOVW $3221225487, R4
+fe636bb2|	plan9	MOVD $70368742080512, R30
+ed031b2a|	plan9	MOVW R27, R13
+fb0308aa|	plan9	MOVD R8, R27
+be3ed1f2|	plan9	MOVK $(35317<<32), R30
+e0a08312|	plan9	MOVW $4294959864, R0
+a1a6e592|	plan9	MOVD $-3257509905472421889, R1
+5260f0d2|	plan9	MOVD $-9006636304787570688, R18
+a60739d5|	plan9	MRS $18493, R6
+281a1ed5|	plan9	MSR R8, $28881
+10f31b1b|	plan9	MSUBW R27, R28, R24, R16
+46b41a9b|	plan9	MSUB R26, R13, R2, R6
+ec7f041b|	plan9	MULW R4, ZR, R12
+147f009b|	plan9	MUL R0, R24, R20
+f67f692a|	plan9	MVNW R9>>31, R22
+f2a3f7aa|	plan9	MVN R23@>40, R18
+fe8b0bcb|	plan9	NEG R11<<34, R30
+fef710eb|	plan9	NEGS R16<<61, R30
+e0031b5a|	plan9	NGCW R27, R0
+e0031dda|	plan9	NGC R29, R0
+f003167a|	plan9	NGCSW R22, R16
+e60302fa|	plan9	NGCS R2, R6
+1f2003d5|	plan9	NOP
+2f51732a|	plan9	ORNW R19>>20, R9, R15
+9b0facaa|	plan9	ORN R12->3, R28, R27
+efa40032|	plan9	ORRW $67044351, R7, R15
+3a0b19b2|	plan9	ORR $3848290698112, R25, R26
+4b9ec4aa|	plan9	ORR R4@>39, R18, R11
+f5eaa2f9|	plan9	PRFM 17872(R23), PSTL3STRM
+85c194f8|	plan9	PRFUM -180(R12), PLDL3STRM
+c303c05a|	plan9	RBITW R30, R3
+3000c0da|	plan9	RBIT R1, R16
+20025fd6|	plan9	RET R17
+ec08c05a|	plan9	REVW R7, R12
+180cc0da|	plan9	REV R0, R24
+4b07c05a|	plan9	REV16W R26, R11
+7805c0da|	plan9	REV16 R11, R24
+ea08c0da|	plan9	REV32 R7, R10
+a90fc0da|	plan9	REV R29, R9
+fd788213|	plan9	EXTRW $30, R2, R7, R29
+e1a0cc93|	plan9	EXTR $40, R12, R7, R1
+792fdc1a|	plan9	RORW R28, R27, R25
+2b2cc39a|	plan9	ROR R3, R1, R11
+7e2ec71a|	plan9	RORW R7, R19, R30
+392edd9a|	plan9	ROR R29, R17, R25
+47020a5a|	plan9	SBCW R10, R18, R7
+b7021dda|	plan9	SBC R29, R21, R23
+7800197a|	plan9	SBCSW R25, R3, R24
+1e0203fa|	plan9	SBCS R3, R16, R30
+a6b07393|	plan9	SBFIZ $13, R5, $45, R6
+94957d93|	plan9	SBFIZ $3, R12, $38, R20
+ecff5e93|	plan9	ASR $30, ZR, R12
+a50ddb1a|	plan9	SDIVW R27, R13, R5
+7c0ec89a|	plan9	SDIV R8, R19, R28
+9f2003d5|	plan9	SEV
+bf2003d5|	plan9	SEVL
+5953349b|	plan9	SMADDL R20, R20, R26, R25
+bafc399b|	plan9	SMNEGL R25, R5, R26
+a5cc289b|	plan9	SMSUBL R8, R19, R5, R5
+297c579b|	plan9	SMULH R23, R1, R9
+5e7e299b|	plan9	SMULL R9, R18, R30
+29fd9f88|	plan9	STLRW R9, (R9)
+fdff9fc8|	plan9	STLR R29, (RSP)
+defe9f08|	plan9	STLRB R30, (R22)
+2ffc9f48|	plan9	STLRH R15, (R1)
+c1e12f88|	plan9	STLXPW (R14), R24, R1, R15
+62aa2ec8|	plan9	STLXPW (R19), R10, R2, R14
+b9fe1b88|	plan9	STLXRW R25, (R21), R27
+cbff14c8|	plan9	STLXR R11, (R30), R20
+edfc0608|	plan9	STLXRB R13, (R7), R6
+8dfe1048|	plan9	STLXRH R13, (R20), R16
+1a323628|	plan9	STNPW -80(R16), R12, R26
+b3cb3da8|	plan9	STNP -40(R29), R18, R19
+52398828|	plan9	STP.P (R18, R14), 64(R10)
+434c95a8|	plan9	STP.P (R3, R19), 336(R2)
+2badbd29|	plan9	STP.W (R11, R11), -20(R9)
+daeabaa9|	plan9	STP.W (R26, R26), -88(R22)
+9bc91529|	plan9	STP (R27, R18), 172(R12)
+eea024a9|	plan9	STP (R14, R8), -440(R7)
+fec514b8|	plan9	MOVW.P R30, -180(R15)
+d21508f8|	plan9	MOVD.P R18, 129(R14)
+7c5c0ab8|	plan9	MOVW.W R28, 165(R3)
+6dec1ff8|	plan9	MOVD.W R13, -2(R3)
+35681eb9|	plan9	MOVW R21, 7784(R1)
+374d35f9|	plan9	MOVD R23, 27288(R9)
+1b441b38|	plan9	MOVB.P R27, -76(R0)
+d69c0f38|	plan9	MOVB.W R22, 249(R6)
+b7ce0d39|	plan9	MOVB R23, 883(R21)
+2b7b3938|	plan9	MOVB R11, R25<<1(R25)
+4e771d78|	plan9	MOVH.P R14, -41(R26)
+64cc0b78|	plan9	MOVH.W R4, 188(R3)
+07b90279|	plan9	MOVH R7, 348(R8)
+2eb91cb8|	plan9	STTRW -53(R9), R14
+373a1bf8|	plan9	STTR -77(R17), R23
+d0881138|	plan9	STTRBW -232(R6), R16
+941a0e78|	plan9	STTRHW 225(R20), R20
+da3000b8|	plan9	MOVW R26, 3(R6)
+5e921cf8|	plan9	MOVD R30, -55(R18)
+09821e38|	plan9	MOVB R9, -24(R16)
+67d21c78|	plan9	MOVH R7, -51(R19)
+0c352188|	plan9	STXPW (R8), R13, R12, R1
+146d26c8|	plan9	STXPW (R8), R27, R20, R6
+837d1888|	plan9	STXRW R3, (R12), R24
+f17f1bc8|	plan9	STXR R17, (RSP), R27
+3b7d0f08|	plan9	STXRB R27, (R9), R15
+6b7c1f48|	plan9	STXRH R11, (R3), ZR
+70ab204b|	plan9	SUBW R0.SXTH<<2, R27, R16
+303b20cb|	plan9	SUB R0.UXTH<<6, R25, R16
+69a909d1|	plan9	SUB $618, R11, R9
+87384e4b|	plan9	SUBW R14>>14, R4, R7
+ec720ecb|	plan9	SUB R14<<28, R23, R12
+2b58256b|	plan9	SUBSW R5.UXTW<<6, R1, R11
+59e93ceb|	plan9	SUBS R28.SXTX<<2, R10, R25
+9e7b6ff1|	plan9	SUBS $(3038<<12), R28, R30
+3e6d196b|	plan9	SUBSW R25<<27, R9, R30
+54029ceb|	plan9	SUBS R28->0, R18, R20
+c1f91cd4|	plan9	SVC $59342
+091e0013|	plan9	SXTBW R16, R9
+7f1c4093|	plan9	SXTB R3, ZR
+b53c0013|	plan9	SXTHW R5, R21
+773e4093|	plan9	SXTH R19, R23
+707f4093|	plan9	SXTW R27, R16
+df3a2dd5|	plan9	SYSL $342720, ZR
+5f612972|	plan9	TSTW $4286644223, R10
+bf2007f2|	plan9	TST $-144115170929541117, R5
+1f11136a|	plan9	TSTW R19<<4, R8
+5fd10dea|	plan9	TST R13<<52, R10
+5c826bd3|	plan9	UBFIZ $21, R18, $33, R28
+ad690c53|	plan9	UBFXW $12, R13, $15, R13
+3a0f41d3|	plan9	UBFX $1, R25, $3, R26
+6a197dd3|	plan9	UBFIZ $3, R11, $7, R10
+520aca1a|	plan9	UDIVW R10, R18, R18
+0809c89a|	plan9	UDIV R8, R8, R8
+4e55a69b|	plan9	UMADDL R6, R21, R10, R14
+99fda59b|	plan9	UMNEGL R5, R12, R25
+1adabb9b|	plan9	UMSUBL R27, R22, R16, R26
+177ddf9b|	plan9	UMULH ZR, R8, R23
+1d7da49b|	plan9	UMULL R4, R8, R29
+5a1c0053|	plan9	UXTBW R2, R26
+603c0053|	plan9	UXTHW R3, R0
+5f2003d5|	plan9	WFE
+7f2003d5|	plan9	WFI
+3f2003d5|	plan9	YIELD
+02b8600e|	plan9	VABS V0.H4, V2.H4
+c886f94e|	plan9	VADD V25.D2, V22.D2, V8.D2
+5642740e|	plan9	VADDHN V20.S4, V18.S4, V22.H4
+3743294e|	plan9	VADDHN2 V9.H8, V25.H8, V23.B16
+2abef74e|	plan9	VADDP V23.D2, V17.D2, V10.D2
+18bbb14e|	plan9	ADDV V24.S4, F24
+1a59284e|	plan9	VAESD V8.B16, V26.B16
+cf48284e|	plan9	VAESE V6.B16, V15.B16
+557a284e|	plan9	VAESIMC V18.B16, V21.B16
+2f6b284e|	plan9	VAESMC V25.B16, V15.B16
+cf1c324e|	plan9	VAND V18.B16, V6.B16, V15.B16
+c9c6032f|	plan9	VMVNI $(118<<136), V9.S2
+f1a7012f|	plan9	VMVNI $(63<<8), V17.H4
+691d600e|	plan9	VBIC V0.B8, V11.B8, V9.B8
+c31dfe6e|	plan9	VBIF V30.B16, V14.B16, V3.B16
+c81cb66e|	plan9	VBIT V22.B16, V6.B16, V8.B16
+701f6b2e|	plan9	VBSL V11.B8, V27.B8, V16.B8
+7c4b600e|	plan9	VCLS V27.H4, V28.H4
+ce4a602e|	plan9	VCLZ V22.H4, V14.H4
+d08de37e|	plan9	CMEQ F3, F14, F16
+e98db96e|	plan9	VCMEQ V25.S4, V15.S4, V9.S4
+6e99a00e|	plan9	VCMEQ $0, V11.S2, V14.S2
+933d304e|	plan9	VCMGE V16.B16, V12.B16, V19.B16
+0e88e07e|	plan9	CMGE $0, F0, F14
+9b89202e|	plan9	VCMGE $0, V12.B8, V27.B8
+6a372f4e|	plan9	VCMGT V15.B16, V27.B16, V10.B16
+128be05e|	plan9	CMGT $0, F24, F18
+9189a00e|	plan9	VCMGT $0, V12.S2, V17.S2
+f734e67e|	plan9	CMHI F6, F7, F23
+4d36b82e|	plan9	VCMHI V24.S2, V18.S2, V13.S2
+003e2b2e|	plan9	VCMHS V11.B8, V16.B8, V0.B8
+729ae07e|	plan9	CMLE $0, F19, F18
+3699206e|	plan9	VCMLE $0, V9.B16, V22.B16
+d1ab600e|	plan9	VCMLT $0, V30.H4, V17.H4
+ad8e244e|	plan9	VCMTST V4.B16, V21.B16, V13.B16
+ef06035e|	plan9	VMOV V23.B[1], F15
+5007040e|	plan9	VDUP V26.S[0], V16.S2
+890e0b4e|	plan9	VDUP R20, V9.B16
+951c276e|	plan9	VEOR V7.B16, V4.B16, V21.B16
+98d4bf7e|	plan9	FABD F31, F4, F24
+bcd4ad6e|	plan9	VFABD V13.S4, V5.S4, V28.S4
+78f8e04e|	plan9	FABS V3.D2, V24.D2
+8cc0201e|	plan9	FABSS F4, F12
+9ac1601e|	plan9	FABSD F12, F26
+3aee307e|	plan9	FACGE F16, F17, F26
+41ed352e|	plan9	VFACGE V21.S2, V10.S2, V1.S2
+35edaf7e|	plan9	FACGT F15, F9, F21
+02efe36e|	plan9	VFACGT V3.D2, V24.D2, V2.D2
+21d6664e|	plan9	FADD V6.D2, V17.D2, V1.D2
+5e282e1e|	plan9	FADDS F14, F2, F30
+4d2a621e|	plan9	FADDD F2, F18, F13
+7cd8707e|	plan9	FADDP V3.D2, F28
+5dd4386e|	plan9	VFADDP V24.S4, V2.S4, V29.S4
+69363e1e|	plan9	FCCMPS LO, F30, F19, $9
+c8b56a1e|	plan9	FCCMPD LT, F10, F14, $8
+d1f5271e|	plan9	FCCMPES AL, F7, F14, $1
+3645751e|	plan9	FCCMPED MI, F21, F9, $6
+21e6735e|	plan9	FCMEQ F19, F17, F1
+b6dba05e|	plan9	FCMEQ $0, F29, F22
+49d8a04e|	plan9	VFCMEQ $0, V2.S4, V9.S4
+2ee5667e|	plan9	FCMGE F6, F9, F14
+4ee7766e|	plan9	VFCMGE V22.D2, V26.D2, V14.D2
+4bcba07e|	plan9	FCMGE $0, F26, F11
+11c9a02e|	plan9	VFCMGE $0, V8.S2, V17.S2
+81e4a97e|	plan9	FCMGT F9, F4, F1
+d3e4b56e|	plan9	VFCMGT V21.S4, V6.S4, V19.S4
+efc8e05e|	plan9	FCMGT $0, F7, F15
+3ec9e04e|	plan9	VFCMGT $0, V9.D2, V30.D2
+38d9a07e|	plan9	FCMLE $0, F9, F24
+7dd9a02e|	plan9	VFCMLE $0, V11.S2, V29.S2
+bae8a05e|	plan9	FCMLT $0, F5, F26
+a2eaa04e|	plan9	VFCMLT $0, V21.S4, V2.S4
+60212f1e|	plan9	FCMPS F15, F11
+a8233a1e|	plan9	FCMPS $(0.0), F29
+a020641e|	plan9	FCMPD F4, F5
+e820701e|	plan9	FCMPD $(0.0), F7
+b0203a1e|	plan9	FCMPES F26, F5
+78203d1e|	plan9	FCMPES $(0.0), F3
+70226e1e|	plan9	FCMPED F14, F19
+3821601e|	plan9	FCMPED $(0.0), F9
+06de241e|	plan9	FCSELS LE, F16, F4, F6
+51de761e|	plan9	FCSELD LE, F18, F22, F17
+5e42e21e|	plan9	FCVTHS F18, F30
+b9c1e21e|	plan9	FCVTHD F13, F25
+58c0231e|	plan9	FCVTSH F2, F24
+9bc2221e|	plan9	FCVTSD F20, F27
+2bc3631e|	plan9	FCVTDH F25, F11
+f640621e|	plan9	FCVTDS F7, F22
+caca215e|	plan9	FCVTAS F22, F10
+5ec9210e|	plan9	VFCVTAS V10.S2, V30.S2
+0302241e|	plan9	FCVTASW F16, R3
+c103249e|	plan9	FCVTAS F30, R1
+3003641e|	plan9	FCVTASW F25, R16
+6201649e|	plan9	FCVTAS F11, R2
+d3c9217e|	plan9	FCVTAU F14, F19
+3bc8212e|	plan9	VFCVTAU V1.S2, V27.S2
+0802251e|	plan9	FCVTAUW F16, R8
+5f02259e|	plan9	FCVTAU F18, ZR
+2801651e|	plan9	FCVTAUW F9, R8
+f200659e|	plan9	FCVTAU F7, R18
+d179610e|	plan9	VFCVTL V14.S2, V17.D2
+347b614e|	plan9	VFCVTL2 V25.S4, V20.D2
+08b9615e|	plan9	FCVTMS F8, F8
+f000301e|	plan9	FCVTMSW F7, R16
+8002309e|	plan9	FCVTMS F20, R0
+5202701e|	plan9	FCVTMSW F18, R18
+c803709e|	plan9	FCVTMS F30, R8
+1cbb217e|	plan9	FCVTMU F24, F28
+d1b9212e|	plan9	VFCVTMU V14.S2, V17.S2
+2e02311e|	plan9	FCVTMUW F17, R14
+d003319e|	plan9	FCVTMU F30, R16
+ce03711e|	plan9	FCVTMUW F30, R14
+0801719e|	plan9	FCVTMU F8, R8
+4c6b210e|	plan9	VFCVTN V26.S4, V12.H4
+6869214e|	plan9	VFCVTN2 V11.S4, V8.H8
+2faa615e|	plan9	FCVTNS F17, F15
+33aa614e|	plan9	VFCVTNS V17.D2, V19.D2
+d303201e|	plan9	FCVTNSW F30, R19
+4001209e|	plan9	FCVTNS F10, R0
+b202601e|	plan9	FCVTNSW F21, R18
+c603609e|	plan9	FCVTNS F30, R6
+8ea8217e|	plan9	FCVTNU F4, F14
+cc01211e|	plan9	FCVTNUW F14, R12
+3a00219e|	plan9	FCVTNU F1, R26
+2002611e|	plan9	FCVTNUW F17, R0
+ff01619e|	plan9	FCVTNU F15, ZR
+1baba15e|	plan9	FCVTPS F24, F27
+9d00281e|	plan9	FCVTPSW F4, R29
+eb02289e|	plan9	FCVTPS F23, R11
+3503681e|	plan9	FCVTPSW F25, R21
+4301689e|	plan9	FCVTPS F10, R3
+63aba17e|	plan9	FCVTPU F27, F3
+caa8a12e|	plan9	VFCVTPU V6.S2, V10.S2
+7702291e|	plan9	FCVTPUW F19, R23
+b503299e|	plan9	FCVTPU F29, R21
+2f03691e|	plan9	FCVTPUW F25, R15
+5b01699e|	plan9	FCVTPU F10, R27
+7369617e|	plan9	FCVTXN F11, F19
+6b6b612e|	plan9	VFCVTXN V27.D2, V11.S2
+f268616e|	plan9	VFCVTXN2 V7.D2, V18.S4
+bcff7b5f|	plan9	FCVTZS $5, F29, F28
+19bbe15e|	plan9	FCVTZSDD F24, F25
+c6b9e14e|	plan9	FCVTZS V14.D2, V6.D2
+e9fc189e|	plan9	FCVTZS $1, F7, R9
+6661589e|	plan9	FCVTZS $40, F11, R6
+9702381e|	plan9	FCVTZSSW F20, R23
+ed00389e|	plan9	FCVTZSS F7, R13
+3a01781e|	plan9	FCVTZSDW F9, R26
+8801789e|	plan9	FCVTZSD F12, R8
+a5ff2e2f|	plan9	FCVTZU $18, V29.S2, V5.S2
+5bbbe17e|	plan9	FCVTZUDD F26, F27
+1a74199e|	plan9	FCVTZU $35, F0, R26
+e391599e|	plan9	FCVTZU $28, F15, R3
+b203391e|	plan9	FCVTZUSW F29, R18
+ed01399e|	plan9	FCVTZUS F15, R13
+c200791e|	plan9	FCVTZUDW F6, R2
+5402799e|	plan9	FCVTZUD F18, R20
+1aff2b6e|	plan9	FDIV V11.S4, V24.S4, V26.S4
+171a391e|	plan9	FDIVS F25, F16, F23
+7d196b1e|	plan9	FDIVD F11, F11, F29
+f9721f1f|	plan9	FMADD F28, F31, F23, F25
+7070551f|	plan9	FMADD F28, F21, F3, F16
+05f7624e|	plan9	FMAX V2.D2, V24.D2, V5.D2
+88493d1e|	plan9	FMAXS F29, F12, F8
+4a496d1e|	plan9	FMAXD F13, F10, F10
+5068321e|	plan9	FMAXNMS F18, F2, F16
+a66a761e|	plan9	FMAXNMD F22, F21, F6
+0ccb707e|	plan9	FMAXNMP V24.D2, F12
+6ec66f6e|	plan9	VFMAXNMP V15.D2, V19.D2, V14.D2
+41f8307e|	plan9	FMAXP V2.S2, F1
+05f72a6e|	plan9	VFMAXP V10.S4, V24.S4, V5.S4
+aa5b231e|	plan9	FMINS F3, F29, F10
+d6596a1e|	plan9	FMIND F10, F14, F22
+15c4b24e|	plan9	FMINNM V18.S4, V0.S4, V21.S4
+6279281e|	plan9	FMINNMS F8, F11, F2
+af7b6a1e|	plan9	FMINNMD F10, F29, F15
+7dc9f07e|	plan9	FMINNMP V11.D2, F29
+dfc6bb6e|	plan9	VFMINNMP V27.S4, V22.S4, V31.S4
+56c8b06e|	plan9	FMINNMV V2.S4, F22
+0ff8f07e|	plan9	FMINP V0.D2, F15
+a211c55f|	plan9	FMLA V5.D[0], F13, F2
+0dce224e|	plan9	VFMLA V2.S4, V16.S4, V13.S4
+4c5ba15f|	plan9	FMLS V1.S[3], F26, F12
+8953ba0f|	plan9	VFMLS V26.S[1], V28.S2, V9.S2
+09cdbd4e|	plan9	VFMLS V29.S4, V8.S4, V9.S4
+97f7044f|	plan9	FMOV $-7., V23.S4
+dff4006f|	plan9	FMOV $2.75, V31.D2
+c543201e|	plan9	FMOVS F30, F5
+1740601e|	plan9	FMOVD F0, F23
+a100271e|	plan9	FMOVS R5, F1
+f102261e|	plan9	FMOVS F23, R17
+b302679e|	plan9	FMOVD R21, F19
+4001af9e|	plan9	FMOV R10, V0.D[1]
+db01669e|	plan9	FMOVD F14, R27
+8300ae9e|	plan9	FMOV V4.D[1], R3
+1870331e|	plan9	FMOVS $-6.75, F24
+08507d1e|	plan9	FMOVD $-0.8125, F8
+5cbf0c1f|	plan9	FMSUB F15, F12, F26, F28
+89e3501f|	plan9	FMSUB F24, F16, F28, F9
+3a93c95f|	plan9	FMULD V9.D[0], F25, F26
+5a90ae4f|	plan9	FMUL V14.S[1], V2.S4, V26.S4
+ba0a2f1e|	plan9	FMULS F15, F21, F26
+5b0a7c1e|	plan9	FMULD F28, F18, F27
+e991c07f|	plan9	FMULX V0.D[0], F15, F9
+be989c6f|	plan9	VFMULX V28.S[2], V5.S4, V30.S4
+d3dc7a5e|	plan9	FMULX F26, F6, F19
+d4de7f4e|	plan9	VFMULX V31.D2, V22.D2, V20.D2
+8e41211e|	plan9	FNEGS F12, F14
+dc42611e|	plan9	FNEGD F22, F28
+cb362e1f|	plan9	FNMADD F13, F14, F22, F11
+6441791f|	plan9	FNMADD F16, F25, F11, F4
+36ed291f|	plan9	FNMSUB F27, F9, F9, F22
+35b27a1f|	plan9	FNMSUB F12, F26, F17, F21
+9388301e|	plan9	FNMULS F16, F4, F19
+c088711e|	plan9	FNMULD F17, F6, F0
+e8daa15e|	plan9	FRECPE F23, F8
+a9fc395e|	plan9	FRECPS F25, F5, F9
+49fe284e|	plan9	VFRECPS V8.S4, V18.S4, V9.S4
+85f8a15e|	plan9	FRECPX F4, F5
+ee43261e|	plan9	FRINTAS F31, F14
+7042661e|	plan9	FRINTAD F19, F16
+2b98a16e|	plan9	FRINTI V1.S4, V11.S4
+fac2271e|	plan9	FRINTIS F23, F26
+76c3671e|	plan9	FRINTID F27, F22
+7942251e|	plan9	FRINTMS F19, F25
+8742651e|	plan9	FRINTMD F20, F7
+fc8a214e|	plan9	FRINTN V23.S4, V28.S4
+c041241e|	plan9	FRINTNS F14, F0
+b241641e|	plan9	FRINTND F13, F18
+c588a14e|	plan9	FRINTP V6.S4, V5.S4
+6ec2241e|	plan9	FRINTPS F19, F14
+ddc0641e|	plan9	FRINTPD F6, F29
+1a9a616e|	plan9	FRINTX V16.D2, V26.D2
+7c41271e|	plan9	FRINTXS F11, F28
+d243671e|	plan9	FRINTXD F30, F18
+b49aa14e|	plan9	FRINTZ V21.S4, V20.S4
+5bc0251e|	plan9	FRINTZS F2, F27
+43c1651e|	plan9	FRINTZD F10, F3
+3bdba17e|	plan9	FRSQRTE F25, F27
+9ddba12e|	plan9	VFRSQRTE V28.S2, V29.S2
+1ffee65e|	plan9	FRSQRTS F6, F16, F31
+8bfdb54e|	plan9	VFRSQRTS V21.S4, V12.S4, V11.S4
+33c1211e|	plan9	FSQRTS F9, F19
+a5c0611e|	plan9	FSQRTD F5, F5
+a2d7b74e|	plan9	FSUB V23.S4, V29.S4, V2.S4
+a338301e|	plan9	FSUBS F16, F5, F3
+e139681e|	plan9	FSUBD F8, F15, F1
+96170e6e|	plan9	VMOV V28.H[1], V22.H[3]
+791c014e|	plan9	VMOV R3, V25.B[0]
+cf79404c|	plan9	VLD1 (R14), [V15.S4]
+75a6404c|	plan9	VLD1 (R19), [V21.H8, V22.H8]
+ed62404c|	plan9	VLD1 (R23), [V13.B16, V14.B16, V15.B16]
+392a400c|	plan9	VLD1 (R17), [V25.S2, V26.S2, V27.S2, V28.S2]
+cd7cdf4c|	plan9	VLD1.P 16(R6), [V13.D2]
+f677ce4c|	plan9	VLD1.P (RSP)(R14), [V22.H8]
+d4a3df0c|	plan9	VLD1.P 16(R30), [V20.B8, V21.B8]
+8ba1d90c|	plan9	VLD1.P (R12)(R25), [V11.B8, V12.B8]
+396fdf0c|	plan9	VLD1.P 24(R25), [V25.D1, V26.D1, V27.D1]
+4c64db0c|	plan9	VLD1.P (R2)(R27), [V12.H4, V13.H4, V14.H4]
+3f2adf4c|	plan9	VLD1.P 64(R17), [V31.S4, V0.S4, V1.S4, V2.S4]
+b329ce4c|	plan9	VLD1.P (R13)(R14), [V19.S4, V20.S4, V21.S4, V22.S4]
+aa02400d|	plan9	LD1 (R21), [V10.B][0]
+7980404d|	plan9	LD1 (R3), [V25.S][2]
+5884404d|	plan9	LD1 (R2), [V24.D][1]
+f203df4d|	plan9	LD1.P 1(RSP), [V18.B][8]
+3519c40d|	plan9	LD1.P (R9)(R4), [V21.B][6]
+ed59df0d|	plan9	LD1.P 2(R15), [V13.H][3]
+9e52d90d|	plan9	LD1.P (R20)(R25), [V30.H][2]
+cd93df4d|	plan9	LD1.P 4(R30), [V13.S][3]
+5982cb4d|	plan9	LD1.P (R18)(R11), [V25.S][2]
+4f84df4d|	plan9	LD1.P 8(R2), [V15.D][1]
+2d85d50d|	plan9	LD1.P (R9)(R21), [V13.D][0]
+33c2400d|	plan9	VLD1R (R17), [V19.B8]
+e2c8df4d|	plan9	VLD1R 4(R7), [V2.S4]
+83c2c44d|	plan9	VLD1R (R20)(R4), [V3.B16]
+5487400c|	plan9	VLD2 (R26), [V20.H4, V21.H4]
+e08adf0c|	plan9	VLD2 16(R23), [V0.S2, V1.S2]
+768ac40c|	plan9	VLD2 (R19)(R4), [V22.S2, V23.S2]
+4c0f604d|	plan9	LD2 (R26), [V12.B, V13.B][11]
+e043604d|	plan9	LD2 (RSP), [V0.H, V1.H][4]
+c281600d|	plan9	LD2 (R14), [V2.S, V3.S][0]
+e585600d|	plan9	LD2 (R15), [V5.D, V6.D][0]
+2c1aff4d|	plan9	LD2 2(R17), [V12.B, V13.B][14]
+820bfd4d|	plan9	LD2 (R28)(R29), [V2.B, V3.B][10]
+d593ff0d|	plan9	LD2 8(R30), [V21.S, V22.S][1]
+6780ea0d|	plan9	LD2 (R3)(R10), [V7.S, V8.S][0]
+3484ff4d|	plan9	LD2 16(R1), [V20.D, V21.D][1]
+6a86ee4d|	plan9	LD2 (R19)(R14), [V10.D, V11.D][1]
+e4c7604d|	plan9	VLD2R (RSP), [V4.H8, V5.H8]
+69c8ff0d|	plan9	VLD2R 8(R3), [V9.S2, V10.S2]
+52ccf30d|	plan9	VLD2R (R2)(R19), [V18.D1, V19.D1]
+9e4b404c|	plan9	VLD3 (R28), [V30.S4, V31.S4, V0.S4]
+0440df4c|	plan9	VLD3 48(R0), [V4.B16, V5.B16, V6.B16]
+0f49cf0c|	plan9	VLD3 (R8)(R15), [V15.S2, V16.S2, V17.S2]
+b22e400d|	plan9	LD3 (R21), [V18.B, V19.B, V20.B][3]
+9473400d|	plan9	LD3 (R28), [V20.H, V21.H, V22.H][2]
+1da0404d|	plan9	LD3 (R0), [V29.S, V30.S, V31.S][2]
+21a5404d|	plan9	LD3 (R9), [V1.D, V2.D, V3.D][1]
+3b23df0d|	plan9	LD3 3(R25), [V27.B, V28.B, V29.B][0]
+0937c60d|	plan9	LD3 (R24)(R6), [V9.B, V10.B, V11.B][5]
+926bcb4d|	plan9	LD3 (R28)(R11), [V18.H, V19.H, V20.H][5]
+f5a1df4d|	plan9	LD3 12(R15), [V21.S, V22.S, V23.S][2]
+dba3c44d|	plan9	LD3 (R30)(R4), [V27.S, V28.S, V29.S][2]
+12a5df0d|	plan9	LD3 24(R8), [V18.D, V19.D, V20.D][0]
+daa7d30d|	plan9	LD3 (R30)(R19), [V26.D, V27.D, V28.D][0]
+3beb400d|	plan9	VLD3R (R25), [V27.S2, V28.S2, V29.S2]
+cde4df4d|	plan9	VLD3R 6(R6), [V13.H8, V14.H8, V15.H8]
+a4efc44d|	plan9	VLD3R (R29)(R4), [V4.D2, V5.D2, V6.D2]
+fc0a400c|	plan9	VLD4 (R23), [V28.S2, V29.S2, V30.S2, V31.S2]
+ae05df0c|	plan9	VLD4 32(R13), [V14.H4, V15.H4, V16.H4, V17.H4]
+cb07c84c|	plan9	VLD4 (R30)(R8), [V11.H8, V12.H8, V13.H8, V14.H8]
+1825604d|	plan9	LD4 (R8), [V24.B, V25.B, V26.B, V27.B][9]
+2869604d|	plan9	LD4 (R9), [V8.H, V9.H, V10.H, V11.H][5]
+07b2600d|	plan9	LD4 (R16), [V7.S, V8.S, V9.S, V10.S][1]
+9fa4600d|	plan9	LD4 (R4), [V31.D, V0.D, V1.D, V2.D][0]
+de22ff0d|	plan9	LD4 4(R22), [V30.B, V31.B, V0.B, V1.B][0]
+6a36ed4d|	plan9	LD4 (R19)(R13), [V10.B, V11.B, V12.B, V13.B][13]
+23a2ff4d|	plan9	LD4 16(R17), [V3.S, V4.S, V5.S, V6.S][2]
+22a0fe4d|	plan9	LD4 (R1)(R30), [V2.S, V3.S, V4.S, V5.S][2]
+7ca4ff4d|	plan9	LD4 32(R3), [V28.D, V29.D, V30.D, V31.D][1]
+03a7ec4d|	plan9	LD4 (R24)(R12), [V3.D, V4.D, V5.D, V6.D][1]
+b9ee600d|	plan9	VLD4R (R21), [V25.D1, V26.D1, V27.D1, V28.D1]
+03e8ff0d|	plan9	VLD4R 16(R0), [V3.S2, V4.S2, V5.S2, V6.S2]
+e7e3f24d|	plan9	VLD4R (RSP)(R18), [V7.B16, V8.B16, V9.B16, V10.B16]
+451a4e2c|	plan9	LDNP 112(R18), F6, F5
+01236f6c|	plan9	LDNP -272(R24), F8, F1
+204041ac|	plan9	LDNP 32(R1), V16, V0
+1b21cc2c|	plan9	LDP.P 96(R8), (F27, F8)
+41ccc06c|	plan9	LDP.P 8(R2), (F1, F19)
+65b8e6ac|	plan9	LDP.P -816(R3), (V5, V14)
+a58bed2d|	plan9	LDP.W -148(R29), (F5, F2)
+d8a3c46d|	plan9	LDP.W 72(R30), (F24, F8)
+dc82c0ad|	plan9	LDP.W 16(R22), (V28, V0)
+eda7782d|	plan9	LDP -60(RSP), (F13, F9)
+041b6c6d|	plan9	LDP -320(R24), (F4, F6)
+17ea6bad|	plan9	LDP -656(R16), (V23, V26)
+4e14433c|	plan9	MOVD.P 49(R2), F14
+cd844e7c|	plan9	MOVD.P 232(R6), F13
+99945dbc|	plan9	MOVD.P -39(R4), F25
+170556fc|	plan9	MOVD.P -160(R8), F23
+3115d53c|	plan9	MOVD.P -175(R9), V17
+3c6d403c|	plan9	MOVD.W 6(R9), F28
+f8fc527c|	plan9	MOVD.W -209(R7), F24
+776c58bc|	plan9	MOVD.W -122(R3), F23
+075f57fc|	plan9	MOVD.W -139(R24), F7
+28cdc33c|	plan9	MOVD.W 60(R9), V8
+40a15f3d|	plan9	MOVD 2024(R10), F0
+3b8c597d|	plan9	MOVD 3270(R1), F27
+28f958bd|	plan9	MOVD 6392(R9), F8
+852d6ffd|	plan9	MOVD 24152(R12), F5
+e149ea3d|	plan9	MOVD 43296(R15), V1
+8d69623c|	plan9	MOVD R2(R12), F13
+1a60553c|	plan9	LDUR -170(R0), F26
+74f3477c|	plan9	LDUR 127(R27), F20
+f46249bc|	plan9	LDUR 150(R23), F20
+b8015bfc|	plan9	LDUR -80(R13), F24
+3372de3c|	plan9	LDUR -25(R17), V19
+04972c0e|	plan9	VMLA V12.B8, V24.B8, V4.B8
+f0051b5e|	plan9	VMOV V15.B[13], F16
+7f76146e|	plan9	VMOV V19.S[3], V31.S[2]
+6c1cb60e|	plan9	VORR V22.B8, V3.B8, V12.B8
+ae3f1e0e|	plan9	UMOVW V29.H[7], R14
+f8e5004f|	plan9	VMOVI $15, V24.B16
+0355010f|	plan9	VORR $(40<<16), V3.S2
+4825020f|	plan9	VMOVI $(74<<8), V8.S2
+64d7040f|	plan9	VMOVI $(155<<144), V4.S2
+46e6062f|	plan9	MOVI $-280379759984896, F6
+bde6056f|	plan9	VMOVI $-71776123339472641, V29.D2
+789f350e|	plan9	VMUL V21.B8, V27.B8, V24.B8
+7b5b202e|	plan9	VMVN V27.B8, V27.B8
+2dd4066f|	plan9	VMVNI $(193<<144), V13.S4
+8266012f|	plan9	VMVNI $(52<<24), V2.S2
+1025022f|	plan9	VMVNI $(72<<8), V16.S2
+eabba06e|	plan9	VNEG V31.S4, V10.S4
+7e5a206e|	plan9	VMVN V19.B16, V30.B16
+6a1fea0e|	plan9	VORN V10.B8, V27.B8, V10.B8
+b406010f|	plan9	VMOVI $53, V20.S2
+f564040f|	plan9	VMOVI $(135<<24), V21.S2
+b21cb80e|	plan9	VORR V24.B8, V5.B8, V18.B8
+2b437a2e|	plan9	VRADDHN V26.S4, V25.S4, V11.H4
+6d402c6e|	plan9	VRADDHN2 V12.H8, V3.H8, V13.B16
+655a606e|	plan9	VRBIT V19.B16, V5.B16
+5108202e|	plan9	VREV32 V2.B8, V17.B8
+750a200e|	plan9	VREV64 V19.B8, V21.B8
+f88f0b0f|	plan9	VRSHRN $5, V31.H8, V24.B8
+8263236e|	plan9	VRSUBHN2 V3.H8, V28.H8, V2.B16
+787c320e|	plan9	VSABA V18.B8, V3.B8, V24.B8
+f551220e|	plan9	VSABAL V2.B8, V15.B8, V21.H8
+b5766d0e|	plan9	VSABD V13.H4, V21.H4, V21.H4
+9270240e|	plan9	VSABDL V4.B8, V4.B8, V18.H8
+4d71384e|	plan9	VSABDL2 V24.B16, V10.B16, V13.H8
+8f6a600e|	plan9	VSADALP V20.H4, V15.S2
+e501750e|	plan9	VSADDL V21.H4, V15.H4, V5.S4
+5202ab4e|	plan9	VSADDL2 V11.S4, V18.S4, V18.D2
+7029200e|	plan9	VSADDLP V11.B8, V16.H4
+3913710e|	plan9	VSADDW V17.H4, V25.S4, V25.S4
+d7e4575f|	plan9	SCVTF $41, F6, F23
+c6db215e|	plan9	SCVTFSS F30, F6
+17d8214e|	plan9	SCVTF V0.S4, V23.S4
+62c4021e|	plan9	SCVTF $15, R3, F2
+f5cd421e|	plan9	SCVTF $13, R15, F21
+6128029e|	plan9	SCVTF $54, R3, F1
+9a7c429e|	plan9	SCVTF $33, R4, F26
+6102221e|	plan9	SCVTFWS R19, F1
+0b03621e|	plan9	SCVTFWD R24, F11
+ed01229e|	plan9	SCVTFS R15, F13
+6f02629e|	plan9	SCVTFD R19, F15
+ac03055e|	plan9	SHA1C V5.S4, F29, V12
+e309285e|	plan9	SHA1H F15, F3
+2a221b5e|	plan9	SHA1M V27.S4, F17, V10
+a013185e|	plan9	SHA1P V24.S4, F29, V0
+6032005e|	plan9	VSHA1SU0 V0.S4, V19.S4, V0.S4
+f918285e|	plan9	VSHA1SU1 V7.S4, V25.S4
+fb50035e|	plan9	SHA256H2 V3.S4, V7, V27
+6d421c5e|	plan9	SHA256H V28.S4, V19, V13
+c12b285e|	plan9	VSHA256SU0 V30.S4, V1.S4
+6362095e|	plan9	VSHA256SU1 V9.S4, V19.S4, V3.S4
+a805bb0e|	plan9	VSHADD V27.S2, V13.S2, V8.S2
+783b616e|	plan9	VSHLL2 $16, V27.H8, V24.S4
+48841b0f|	plan9	VSHRN $5, V2.S4, V8.H4
+a924bc4e|	plan9	VSHSUB V28.S4, V5.S4, V9.S4
+1557717f|	plan9	SLI $49, F24, F21
+2a56456f|	plan9	VSLI $5, V17.D2, V10.D2
+7c663b0e|	plan9	VSMAX V27.B8, V19.B8, V28.B8
+b5a7694e|	plan9	VSMAXP V9.H8, V29.H8, V21.H8
+8ea8b04e|	plan9	SMAXV V4.S4, F14
+936cb44e|	plan9	VSMIN V20.S4, V4.S4, V19.S4
+15af7e4e|	plan9	VSMINP V30.H8, V24.H8, V21.H8
+3e81694e|	plan9	VSMLAL2 V9.H8, V9.H8, V30.S4
+29a26d0e|	plan9	VSMLSL V13.H4, V17.H4, V9.S4
+442e0b4e|	plan9	SMOV V18.B[5], R4
+e1a0540f|	plan9	VSMULL V4.H[1], V7.H4, V1.S4
+5eaa604f|	plan9	VSMULL2 V0.H[6], V18.H8, V30.S4
+4cc32d4e|	plan9	VSMULL2 V13.B16, V26.B16, V12.H8
+1e7a205e|	plan9	SQABS F16, F30
+e67ae04e|	plan9	VSQABS V23.D2, V6.D2
+a80ded5e|	plan9	SQADD F13, F13, F8
+e60dae4e|	plan9	VSQADD V14.S4, V15.S4, V6.S4
+fe33570f|	plan9	VSQDMLAL V7.H[1], V31.H4, V30.S4
+ee90b64e|	plan9	VSQDMLAL2 V22.S4, V7.S4, V14.D2
+ce79a05f|	plan9	SQDMLSL V0.S[3], F14, F14
+d5b2a14e|	plan9	VSQDMLSL2 V1.S4, V22.S4, V21.D2
+51cb575f|	plan9	SQDMULH V7.H[5], F26, F17
+0cb5b54e|	plan9	VSQDMULH V21.S4, V8.S4, V12.S4
+95d0760e|	plan9	VSQDMULL V22.H4, V4.H4, V21.S4
+a1d37c4e|	plan9	VSQDMULL2 V28.H8, V29.H8, V1.S4
+d679e07e|	plan9	SQNEG F14, F22
+3f78602e|	plan9	VSQNEG V1.H4, V31.H4
+80b4717e|	plan9	SQRDMULH F17, F4, F0
+4cb76e2e|	plan9	VSQRDMULH V14.H4, V26.H4, V12.H4
+aa5ce95e|	plan9	SQRSHL F9, F5, F10
+d25fb74e|	plan9	VSQRSHL V23.S4, V30.S4, V18.S4
+998c0c6f|	plan9	VSQRSHRUN2 $4, V4.H8, V25.B16
+4375605f|	plan9	SQSHL $32, F10, F3
+de743f0f|	plan9	VSQSHL $31, V6.S2, V30.S2
+a84d675e|	plan9	SQSHL F7, F13, F8
+674dbe4e|	plan9	VSQSHL V30.S4, V11.S4, V7.S4
+5165587f|	plan9	SQSHLU $24, F10, F17
+b464042f|	plan9	VMVNI $(133<<24), V20.S2
+2086207f|	plan9	SQSHRUN $32, F17, F0
+8a851a2f|	plan9	VSQSHRUN $6, V12.S4, V10.H4
+652c255e|	plan9	SQSUB F5, F3, F5
+632eb30e|	plan9	VSQSUB V19.S2, V19.S2, V3.S2
+104ba15e|	plan9	SQXTN F24, F16
+2249214e|	plan9	VSQXTN2 V9.H8, V2.B16
+1c14360e|	plan9	VSRHADD V22.B8, V0.B8, V28.B8
+8044076f|	plan9	VMVNI $(228<<16), V0.S4
+3a57ed5e|	plan9	SRSHL F13, F25, F26
+2c56ef4e|	plan9	VSRSHL V15.D2, V17.D2, V12.D2
+9627140f|	plan9	VSRSHR $12, V28.H4, V22.H4
+bd37565f|	plan9	SRSRA $42, F29, F29
+db34594f|	plan9	VSRSRA $39, V6.D2, V27.D2
+4546a10e|	plan9	VSSHL V1.S2, V18.S2, V5.S2
+aca7020f|	plan9	VMOVI $(93<<8), V12.H4
+e004675f|	plan9	SSHR $25, F7, F0
+e5057f4f|	plan9	VSSHR $1, V15.D2, V5.D2
+1b15595f|	plan9	SSRA $39, F8, F27
+ba15250f|	plan9	VSSRA $27, V13.S2, V26.S2
+3620330e|	plan9	VSSUBL V19.B8, V1.B8, V22.H8
+c1316d4e|	plan9	VSSUBW2 V13.H8, V14.S4, V1.S4
+8a76000c|	plan9	VST1 (R20), [V10.H4]
+10a5004c|	plan9	VST1 (R8), [V16.H8, V17.H8]
+ab6b004c|	plan9	VST1 (R29), [V11.S4, V12.S4, V13.S4]
+8d2b004c|	plan9	VST1 (R28), [V13.S4, V14.S4, V15.S4, V16.S4]
+8d7d9f0c|	plan9	VST1 8(R12), [V13.D1]
+eb73840c|	plan9	VST1 (RSP)(R4), [V11.B8]
+48a69f4c|	plan9	VST1 32(R18), [V8.H8, V9.H8]
+dca19b4c|	plan9	VST1 (R14)(R27), [V28.B16, V29.B16]
+7c699f4c|	plan9	VST1 48(R11), [V28.S4, V29.S4, V30.S4]
+da6d870c|	plan9	VST1 (R14)(R7), [V26.D1, V27.D1, V28.D1]
+7f279f0c|	plan9	VST1 32(R27), [V31.H4, V0.H4, V1.H4, V2.H4]
+4421810c|	plan9	VST1 (R10)(R1), [V4.B8, V5.B8, V6.B8, V7.B8]
+a615004d|	plan9	ST1 (R13), [V6.B][13]
+ce92000d|	plan9	ST1 (R22), [V14.S][1]
+c985000d|	plan9	ST1 (R14), [V9.D][0]
+380f9f0d|	plan9	ST1 1(R25), [V24.B][3]
+de0b944d|	plan9	ST1 (R30)(R20), [V30.B][10]
+3141880d|	plan9	ST1 (R9)(R8), [V17.H][0]
+8e939f0d|	plan9	ST1 4(R28), [V14.S][1]
+c890870d|	plan9	ST1 (R6)(R7), [V8.S][1]
+9f869f4d|	plan9	ST1 8(R20), [V31.D][1]
+38879b4d|	plan9	ST1 (R25)(R27), [V24.D][1]
+4181004c|	plan9	VST2 (R10), [V1.B16, V2.B16]
+d6819f0c|	plan9	VST2 16(R14), [V22.B8, V23.B8]
+bf808a0c|	plan9	VST2 (R5)(R10), [V31.B8, V0.B8]
+bd0e204d|	plan9	ST2 (R21), [V29.B, V30.B][11]
+4551204d|	plan9	ST2 (R10), [V5.H, V6.H][6]
+9982204d|	plan9	ST2 (R20), [V25.S, V26.S][2]
+ea86200d|	plan9	ST2 (R23), [V10.D, V11.D][0]
+7b02bf0d|	plan9	ST2 2(R19), [V27.B, V28.B][0]
+c000a04d|	plan9	ST2 (R6)(R0), [V0.B, V1.B][8]
+fb59a40d|	plan9	ST2 (R15)(R4), [V27.H, V28.H][3]
+f880bf0d|	plan9	ST2 8(R7), [V24.S, V25.S][0]
+f582ac4d|	plan9	ST2 (R23)(R12), [V21.S, V22.S][2]
+9c86bf4d|	plan9	ST2 16(R20), [V28.D, V29.D][1]
+3386b14d|	plan9	ST2 (R17)(R17), [V19.D, V20.D][1]
+c0469f0c|	plan9	VST3 24(R22), [V0.H4, V1.H4, V2.H4]
+2243820c|	plan9	VST3 (R25)(R2), [V2.B8, V3.B8, V4.B8]
+c629000d|	plan9	ST3 (R14), [V6.B, V7.B, V8.B][2]
+4f6a004d|	plan9	ST3 (R18), [V15.H, V16.H, V17.H][5]
+72a0004d|	plan9	ST3 (R3), [V18.S, V19.S, V20.S][2]
+c1a4000d|	plan9	ST3 (R6), [V1.D, V2.D, V3.D][0]
+312e9f0d|	plan9	ST3 3(R17), [V17.B, V18.B, V19.B][3]
+9a28934d|	plan9	ST3 (R4)(R19), [V26.B, V27.B, V28.B][10]
+a1799f4d|	plan9	ST3 6(R13), [V1.H, V2.H, V3.H][7]
+3ba29f0d|	plan9	ST3 12(R17), [V27.S, V28.S, V29.S][0]
+80b2870d|	plan9	ST3 (R20)(R7), [V0.S, V1.S, V2.S][1]
+f6a49f4d|	plan9	ST3 24(R7), [V22.D, V23.D, V24.D][1]
+8fa69a4d|	plan9	ST3 (R20)(R26), [V15.D, V16.D, V17.D][1]
+ee09000c|	plan9	VST4 (R15), [V14.S2, V15.S2, V16.S2, V17.S2]
+1e07880c|	plan9	VST4 (R24)(R8), [V30.H4, V31.H4, V0.H4, V1.H4]
+6426204d|	plan9	ST4 (R19), [V4.B, V5.B, V6.B, V7.B][9]
+4ea2204d|	plan9	ST4 (R18), [V14.S, V15.S, V16.S, V17.S][2]
+05a6200d|	plan9	ST4 (R16), [V5.D, V6.D, V7.D, V8.D][0]
+5b21bf0d|	plan9	ST4 4(R10), [V27.B, V28.B, V29.B, V30.B][0]
+ce28a00d|	plan9	ST4 (R6)(R0), [V14.B, V15.B, V16.B, V17.B][2]
+767bbf4d|	plan9	ST4 8(R27), [V22.H, V23.H, V24.H, V25.H][7]
+747aa24d|	plan9	ST4 (R19)(R2), [V20.H, V21.H, V22.H, V23.H][7]
+24b0bf0d|	plan9	ST4 16(R1), [V4.S, V5.S, V6.S, V7.S][1]
+c7b1a90d|	plan9	ST4 (R14)(R9), [V7.S, V8.S, V9.S, V10.S][1]
+9fa4bf4d|	plan9	ST4 32(R4), [V31.D, V0.D, V1.D, V2.D][1]
+70a4ab4d|	plan9	ST4 (R3)(R11), [V16.D, V17.D, V18.D, V19.D][1]
+89fe2e2c|	plan9	STNP -140(R20), F31, F9
+bfd31d6c|	plan9	STNP 472(R29), F20, F31
+ddf301ac|	plan9	STNP 48(R30), V28, V29
+14f6ac2c|	plan9	STP.P (F20, F29), -156(R16)
+251db76c|	plan9	STP.P (F5, F7), -144(R9)
+e51fb7ac|	plan9	STP.P (V5, V7), -288(RSP)
+5c90852d|	plan9	STP.W (F28, F4), 44(R2)
+4c51a56d|	plan9	STP.W (F12, F20), -432(R10)
+265d8aad|	plan9	STP.W (V6, V23), 320(R9)
+9c0c392d|	plan9	STP (F28, F3), -56(R4)
+b49e1e6d|	plan9	STP (F20, F7), 488(R21)
+55f105ad|	plan9	STP (V21, V28), 176(R10)
+4dd6003c|	plan9	MOVD.P F13, 13(R18)
+e357067c|	plan9	MOVD.P F3, 101(RSP)
+f6841dbc|	plan9	MOVD.P F22, -40(R7)
+54b710fc|	plan9	MOVD.P F20, -245(R26)
+0d07833c|	plan9	MOVD.P V13, 48(R24)
+393f003c|	plan9	MOVD.W F25, 3(R25)
+1fac007c|	plan9	MOVD.W F31, 10(R0)
+d41d13bc|	plan9	MOVD.W F20, -207(R14)
+908f0dfc|	plan9	MOVD.W F16, 216(R28)
+5ded9d3c|	plan9	MOVD.W V29, -34(R10)
+6d72073d|	plan9	MOVD F13, 476(R19)
+68752d7d|	plan9	MOVD F8, 5818(R11)
+084728bd|	plan9	MOVD F8, 10308(R24)
+409503fd|	plan9	MOVD F0, 1832(R10)
+58a1963d|	plan9	MOVD V24, 23168(R10)
+967b313c|	plan9	MOVD F22, R17<<1(R28)
+b4683e7c|	plan9	MOVD F20, R30(R5)
+e5e1143c|	plan9	MOVD F5, -178(R15)
+99901e7c|	plan9	MOVD F25, -23(R4)
+bb0012bc|	plan9	MOVD F27, -224(R5)
+1d710cfc|	plan9	MOVD F29, 199(R8)
+17e1873c|	plan9	MOVD V23, 126(R8)
+ed84a26e|	plan9	VSUB V2.S4, V7.S4, V13.S4
+7761b80e|	plan9	VSUBHN V24.D2, V11.D2, V23.S2
+f838205e|	plan9	SUQADD F7, F24
+7739600e|	plan9	VSUQADD V11.H4, V23.H4
+26a5204f|	plan9	VSXTL2 V9.S4, V6.D2
+5a201a4e|	plan9	VTBL V26.B16, [V2.B16, V3.B16], V26.B16
+c2400f0e|	plan9	VTBL V15.B8, [V6.B16, V7.B16, V8.B16], V2.B8
+7263024e|	plan9	VTBL V2.B16, [V27.B16, V28.B16, V29.B16, V30.B16], V18.B16
+bb010b4e|	plan9	VTBL V11.B16, [V13.B16], V27.B16
+5f31184e|	plan9	VTBX V24.B16, [V10.B16, V11.B16], V31.B16
+a952100e|	plan9	VTBX V16.B8, [V21.B16, V22.B16, V23.B16], V9.B8
+4872170e|	plan9	VTBX V23.B8, [V18.B16, V19.B16, V20.B16, V21.B16], V8.B8
+dc110e4e|	plan9	VTBX V14.B16, [V14.B16], V28.B16
+d7289a4e|	plan9	VTRN1 V26.S4, V6.S4, V23.S4
+cd6a924e|	plan9	VTRN2 V18.S4, V22.S4, V13.S4
+a552392e|	plan9	VUABAL V25.B8, V21.B8, V5.H8
+a653256e|	plan9	VUABAL2 V5.B16, V29.B16, V6.H8
+fb70b42e|	plan9	VUABDL V20.S2, V7.S2, V27.D2
+3b6a202e|	plan9	VUADALP V17.B8, V27.H4
+8a03b22e|	plan9	VUADDL V18.S2, V28.S2, V10.D2
+262a206e|	plan9	VUADDLP V17.B16, V6.H8
+8410312e|	plan9	VUADDW V17.B8, V4.H8, V4.H8
+bf11ae6e|	plan9	VUADDW2 V14.S4, V13.D2, V31.D2
+a7e65d7f|	plan9	UCVTF $35, F21, F7
+8bda617e|	plan9	UCVTFDD F20, F11
+7fb8431e|	plan9	UCVTF $18, R3, F31
+1c0f039e|	plan9	UCVTF $61, R24, F28
+2241439e|	plan9	UCVTF $48, R9, F2
+d701231e|	plan9	UCVTFWS R14, F23
+9600631e|	plan9	UCVTFWD R4, F22
+8b01239e|	plan9	UCVTFS R12, F11
+7202639e|	plan9	UCVTFD R19, F18
+3406b82e|	plan9	VUHADD V24.S2, V17.S2, V20.S2
+9264612e|	plan9	VUMAX V1.H4, V4.H4, V18.H4
+d9a5772e|	plan9	VUMAXP V23.H4, V14.H4, V25.H4
+74a8b06e|	plan9	UMAXV V3.S4, F20
+24a8312e|	plan9	UMINV V1.B8, F4
+c5218e2f|	plan9	VUMLAL V14.S[0], V14.S2, V5.D2
+3d20a76f|	plan9	VUMLAL2 V7.S[1], V1.S4, V29.D2
+90817e6e|	plan9	VUMLAL2 V30.H8, V12.H8, V16.S4
+0f69a46f|	plan9	VUMLSL2 V4.S[3], V8.S4, V15.D2
+4aa27c2e|	plan9	VUMLSL V28.H4, V18.H4, V10.S4
+48a27b6e|	plan9	VUMLSL2 V27.H8, V18.H8, V8.S4
+833c0d0e|	plan9	UMOVW V4.B[6], R3
+e2a1b22f|	plan9	VUMULL V18.S[1], V15.S2, V2.D2
+07c06f2e|	plan9	VUMULL V15.H4, V0.H4, V7.S4
+470e367e|	plan9	UQADD F22, F18, F7
+490e252e|	plan9	VUQADD V5.B8, V18.B8, V9.B8
+bf5eaa7e|	plan9	UQRSHL F10, F21, F31
+c49c347f|	plan9	UQRSHRN $12, F6, F4
+b4757a7f|	plan9	UQSHL $58, F13, F20
+d14f777e|	plan9	UQSHL F23, F30, F17
+9e2d7a7e|	plan9	UQSUB F26, F12, F30
+a62c296e|	plan9	VUQSUB V9.B16, V5.B16, V6.B16
+5d4ba17e|	plan9	UQXTN F26, F29
+454b212e|	plan9	VUQXTN V26.H8, V5.B8
+1c48a16e|	plan9	VUQXTN2 V0.D2, V28.S4
+4157736e|	plan9	VURSHL V19.H8, V26.H8, V1.H8
+2d26797f|	plan9	URSHR $7, F17, F13
+bd27466f|	plan9	VURSHR $58, V29.D2, V29.D2
+bcc8a12e|	plan9	VURSQRTE V5.S2, V28.S2
+f5345d7f|	plan9	URSRA $35, F7, F21
+f8353a6f|	plan9	VURSRA $6, V15.S4, V24.S4
+85a6342f|	plan9	VUSHLL $20, V20.S2, V5.D2
+e7a70e6f|	plan9	VUSHLL2 $6, V31.B16, V7.H8
+ed04787f|	plan9	USHR $8, F7, F13
+8f07362f|	plan9	VUSHR $10, V28.S2, V15.S2
+963a607e|	plan9	USQADD F20, F22
+383a206e|	plan9	VUSQADD V17.B16, V24.B16
+ef16596f|	plan9	VUSRA $39, V23.D2, V15.D2
+f222ab2e|	plan9	VUSUBL V11.S2, V23.S2, V18.D2
+9220696e|	plan9	VUSUBL2 V9.H8, V4.H8, V18.S4
+0130312e|	plan9	VUSUBW V17.B8, V0.H8, V1.H8
+a932a06e|	plan9	VUSUBW2 V0.S4, V21.D2, V9.D2
+9a19910e|	plan9	VUZP1 V17.S2, V12.S2, V26.S2
+a379ca4e|	plan9	VZIP2 V10.D2, V13.D2, V3.D2
+1202011a|	plan9	ADCW R1, R16, R18
+6900199a|	plan9	ADC R25, R3, R9
+01010f3a|	plan9	ADCSW R15, R8, R1
+13010fba|	plan9	ADCS R15, R8, R19
+55ed280b|	plan9	ADDW R8.SXTX<<3, R10, R21
+2077268b|	plan9	ADD R6.UXTX<<5, R25, R0
+7f40560b|	plan9	ADDW R22>>16, R3, ZR
+3a16282b|	plan9	ADDSW R8.UXTB<<5, R17, R26
+f8a336ab|	plan9	ADDS R22.SXTH, RSP, R24
+000e6d31|	plan9	ADDSW $(2883<<12), R16, R0
+b48e49b1|	plan9	ADDS $(611<<12), R21, R20
+7e174e2b|	plan9	ADDSW R14>>5, R27, R30
+3aa13f12|	plan9	ANDW $66978814, R9, R26
+32a23592|	plan9	AND $-571965880182769649, R17, R18
+b478070a|	plan9	ANDW R7<<30, R5, R20
+dd1f988a|	plan9	AND R24->7, R30, R29
+a7351b72|	plan9	ANDSW $524256, R13, R7
+1c056ef2|	plan9	ANDS $786432, R8, R28
+defd52ea|	plan9	ANDS R18>>63, R14, R30
+8c28d01a|	plan9	ASRW R16, R4, R12
+582ac09a|	plan9	ASR R0, R18, R24
+647d1813|	plan9	ASRW $24, R11, R4
+d1fe5b93|	plan9	ASR $27, R22, R17
+2329c31a|	plan9	ASRW R3, R9, R3
+d929d69a|	plan9	ASR R22, R14, R25
+aefa5354|	plan9	BAL 171989(PC)
+76ad3917|	plan9	JMP -12997258(PC)
+de320f33|	plan9	BFIW $17, R22, $13, R30
+af144db3|	plan9	BFI $51, R5, $6, R15
+161c7eb3|	plan9	BFI $2, R0, $8, R22
+f9791733|	plan9	BFXILW $23, R15, $8, R25
+781577b3|	plan9	BFI $9, R11, $6, R24
+0f65f98a|	plan9	BIC R25@>25, R8, R15
+2c37e16a|	plan9	BICSW R1@>13, R25, R12
+a6f473ea|	plan9	BICS R19>>61, R5, R6
+f064ad96|	plan9	CALL -22190864(PC)
+80023fd6|	plan9	CALL (R20)
+00001fd6|	plan9	JMP (R0)
+80de3ed4|	plan9	BRK $63220
+4e2a483a|	plan9	CCMNW HS, R18, $8, $14
+4a3a4eba|	plan9	CCMN LO, R18, $14, $10
+0143553a|	plan9	CCMNW MI, R24, R21, $1
+c09359ba|	plan9	CCMN LS, R30, R25, $0
+020a567a|	plan9	CCMPW EQ, R16, $22, $2
+a6985afa|	plan9	CCMP LS, R5, $26, $6
+6fc0487a|	plan9	CCMPW GT, R3, R8, $15
+21d14bfa|	plan9	CCMP LE, R9, R11, $1
+75f5991a|	plan9	CSINCW AL, R11, R25, R21
+5a25919a|	plan9	CSINC HS, R10, R17, R26
+6a938c5a|	plan9	CSINVW LS, R27, R12, R10
+6a408eda|	plan9	CSINV MI, R3, R14, R10
+5f3603d5|	plan9	CLREX $6
+a017c05a|	plan9	CLSW R29, R0
+2616c0da|	plan9	CLS R17, R6
+9411c05a|	plan9	CLZW R12, R20
+c611c0da|	plan9	CLZ R14, R6
+9fc3322b|	plan9	CMNW R18.SXTW, R28
+3f9638ab|	plan9	CMN R24.SXTB<<5, R17
+3f681db1|	plan9	CMN $1882, R1
+bfd15bab|	plan9	CMN R27>>52, R13
+ff723b6b|	plan9	CMPW R27.UXTX<<4, R23
+1f5234eb|	plan9	CMP R20.UXTW<<4, R16
+9fb22a71|	plan9	CMPW $2732, R20
+df2478f1|	plan9	CMP $(3593<<12), R6
+bf07026b|	plan9	CMPW R2<<1, R29
+bfc514eb|	plan9	CMP R20<<49, R13
+d494975a|	plan9	CSNEGW LS, R6, R23, R20
+763591da|	plan9	CSNEG LO, R11, R17, R22
+b440c91a|	plan9	CRC32B R9, R5, R20
+5745cd1a|	plan9	CRC32H R13, R10, R23
+684ad01a|	plan9	CRC32W R16, R19, R8
+884fd59a|	plan9	CRC32X R21, R28, R8
+ea50c61a|	plan9	CRC32CB R6, R7, R10
+1357cf1a|	plan9	CRC32CH R15, R24, R19
+9859c21a|	plan9	CRC32CW R2, R12, R24
+6e5fde9a|	plan9	CRC32CX R30, R27, R14
+9340941a|	plan9	CSELW MI, R4, R20, R19
+dd42839a|	plan9	CSEL MI, R22, R3, R29
+fe779f1a|	plan9	CSETW VS, R30
+f1279f9a|	plan9	CSET LO, R17
+eb839f5a|	plan9	CSETMW LS, R11
+e3139fda|	plan9	CSETM EQ, R3
+a986841a|	plan9	CSINCW HI, R21, R4, R9
+19b78b9a|	plan9	CSINC LT, R24, R11, R25
+4643835a|	plan9	CSINVW MI, R26, R3, R6
+5ee38cda|	plan9	CSINV AL, R26, R12, R30
+d166945a|	plan9	CSNEGW VS, R22, R20, R17
+55f793da|	plan9	CSNEG AL, R26, R19, R21
+0158add4|	plan9	DCPS1 $27328
+82ceb2d4|	plan9	DCPS2 $38516
+a31eb3d4|	plan9	DCPS3 $39157
+bf3203d5|	plan9	DMB $2
+e003bfd6|	plan9	DRPS
+9f3403d5|	plan9	DSB $4
+2e2faeca|	plan9	EON R14->11, R25, R14
+de6b0152|	plan9	EORW $2214592511, R30, R30
+4a7714d2|	plan9	EOR $-13194139536385, R26, R10
+2cea0dca|	plan9	EOR R13<<58, R17, R12
+e0039fd6|	plan9	ERET
+834cce93|	plan9	EXTR $19, R14, R4, R3
+5f2003d5|	plan9	WFE
+bf2e03d5|	plan9	HINT $117
+e0f055d4|	plan9	HLT $44935
+df3403d5|	plan9	ISB $4
+22fcdf88|	plan9	LDARW (R1), R2
+78fedfc8|	plan9	LDAR (R19), R24
+cffcdf08|	plan9	LDARB (R6), R15
+34fedf48|	plan9	LDARH (R17), R20
+17bb7f88|	plan9	LDAXPW (R24), R14, R23
+6ffe7fc8|	plan9	LDAXP (R19), ZR, R15
+acfe5f88|	plan9	LDAXRW (R21), R12
+cafe5fc8|	plan9	LDAXR (R22), R10
+ddfd5f08|	plan9	LDAXRB (R14), R29
+0efd5f48|	plan9	LDAXRH (R8), R14
+66445128|	plan9	LDNPW 136(R3), R17, R6
+3fa77fa8|	plan9	LDNP -8(R25), R9, ZR
+1e04eb28|	plan9	LDP.P -168(R0), (R30, R1)
+0da6c0a8|	plan9	LDP.P 8(R16), (R13, R9)
+7d00d429|	plan9	LDP.W 160(R3), (R29, R0)
+d26ae1a9|	plan9	LDP.W -496(R22), (R18, R26)
+d0ca6829|	plan9	LDP -188(R22), (R16, R18)
+a5e34fa9|	plan9	LDP 248(R29), (R5, R24)
+3e44d168|	plan9	LDPSW 136(R1), R17, R30
+5f08e169|	plan9	LDPSW -248(R2), R2, ZR
+430d6769|	plan9	LDPSW -200(R10), R3, R3
+2c555bb8|	plan9	MOVWU.P -75(R9), R12
+83c557f8|	plan9	MOVD.P -132(R12), R3
+f36e47b8|	plan9	MOVWU.W 118(R23), R19
+6b1f48f8|	plan9	MOVD.W 129(R27), R11
+f5d64ab9|	plan9	MOVWU 2772(R23), R21
+872d7cf9|	plan9	MOVD 30808(R12), R7
+82a75438|	plan9	MOVBU.P -182(R28), R2
+a7fd5738|	plan9	MOVBU.W -129(R13), R7
+c83d4239|	plan9	MOVBU 143(R14), R8
+8e687e38|	plan9	MOVBU R30(R4), R14
+70575378|	plan9	MOVHU.P -203(R27), R16
+015f5078|	plan9	MOVHU.W -251(R24), R1
+7add5c79|	plan9	MOVHU 3694(R11), R26
+c474c338|	plan9	MOVBW.P 55(R6), R4
+28869638|	plan9	MOVB.P -152(R17), R8
+fe3fd438|	plan9	MOVBW.W -189(RSP), R30
+da0f9938|	plan9	MOVB.W -112(R30), R26
+5b3ac739|	plan9	MOVBW 462(R18), R27
+2c579e39|	plan9	MOVB 1941(R25), R12
+fb68f238|	plan9	MOVBW R18(R7), R27
+f26aad38|	plan9	MOVB R13(R23), R18
+17e4c978|	plan9	MOVHW.P 158(R0), R23
+a2759f78|	plan9	MOVH.P -9(R13), R2
+9c6ec478|	plan9	MOVHW.W 70(R20), R28
+fd6f8278|	plan9	MOVH.W 38(RSP), R29
+a82bc279|	plan9	MOVHW 276(R29), R8
+9d89b979|	plan9	MOVH 7364(R12), R29
+962685b8|	plan9	MOVW.P 82(R20), R22
+76ae8bb8|	plan9	MOVW.W 186(R19), R22
+fc2193b9|	plan9	MOVW 4896(R15), R28
+e34842b8|	plan9	LDTRW 36(R7), R3
+4ff84df8|	plan9	LDTR 223(R2), R15
+d9e84f38|	plan9	LDTRBW 254(R6), R25
+397b5378|	plan9	LDTRHW -201(R25), R25
+c4c9d138|	plan9	LDTRSBW -228(R14), R4
+02789638|	plan9	LDTRSB -153(R0), R2
+a988cb78|	plan9	LDTRSHW 184(R5), R9
+03888978|	plan9	LDTRSH 152(R0), R3
+ccb99fb8|	plan9	LDTRSW -5(R14), R12
+efb154b8|	plan9	LDURW -181(R15), R15
+fc2051f8|	plan9	LDUR -238(R7), R28
+86d04438|	plan9	LDURBW 77(R4), R6
+73405d78|	plan9	LDURHW -44(R3), R19
+7a81d538|	plan9	LDURSBW -168(R11), R26
+b0b28038|	plan9	LDURSB 11(R21), R16
+b4a1d278|	plan9	LDURSHW -214(R13), R20
+3ed18078|	plan9	LDURSH 13(R9), R30
+09628eb8|	plan9	LDURSW 230(R16), R9
+c07e7f88|	plan9	LDXPW (R22), ZR, R0
+3e167fc8|	plan9	LDXP (R17), R5, R30
+727c5f88|	plan9	LDXRW (R3), R18
+487c5fc8|	plan9	LDXR (R2), R8
+867d5f08|	plan9	LDXRB (R12), R6
+747f5f48|	plan9	LDXRH (R27), R20
+d920d71a|	plan9	LSLW R23, R6, R25
+b920c59a|	plan9	LSL R5, R5, R25
+4da947d3|	plan9	UBFX $7, R10, $36, R13
+be23ca1a|	plan9	LSLW R10, R29, R30
+cc20d19a|	plan9	LSL R17, R6, R12
+ae26c31a|	plan9	LSRW R3, R21, R14
+fc27cb9a|	plan9	LSR R11, ZR, R28
+2b7e1053|	plan9	LSRW $16, R17, R11
+cefe75d3|	plan9	LSR $53, R22, R14
+3b25d01a|	plan9	LSRW R16, R9, R27
+e826d79a|	plan9	LSR R23, R23, R8
+5504031b|	plan9	MADDW R3, R1, R2, R21
+9e5c109b|	plan9	MADD R16, R23, R4, R30
+00fe1f1b|	plan9	MNEGW ZR, R16, R0
+6efe179b|	plan9	MNEG R23, R19, R14
+31020011|	plan9	ADDW $0, R17, R17
+21000091|	plan9	ADD $0, R1, R1
+39f1bf12|	plan9	MOVW $7798783, R25
+53b3e992|	plan9	MOVD $-5591781887333892097, R19
+c0fd9552|	plan9	MOVW $45038, R0
+f16b97d2|	plan9	MOVD $47967, R17
+e8972232|	plan9	MOVW $3222257679, R8
+e27323b2|	plan9	MOVD $-2017612633531744257, R2
+e9030e2a|	plan9	MOVW R14, R9
+fb0310aa|	plan9	MOVD R16, R27
+d0e48472|	plan9	MOVKW $10022, R16
+432dbcf2|	plan9	MOVK $(57706<<16), R3
+4b679612|	plan9	MOVW $4294921413, R11
+9121e492|	plan9	MOVD $-2381278302972149761, R17
+00be90d2|	plan9	MOVD $34288, R0
+91d730d5|	plan9	MRS $1724, R17
+cf301fd5|	plan9	MSR R15, $31110
+daea181b|	plan9	MSUBW R24, R26, R22, R26
+e1a7109b|	plan9	MSUB R16, R9, ZR, R1
+477f0d1b|	plan9	MULW R13, R26, R7
+a17d1c9b|	plan9	MUL R28, R13, R1
+fc9b79aa|	plan9	MVN R25>>38, R28
+f71b904b|	plan9	NEGW R16->6, R23
+e3df4acb|	plan9	NEG R10>>55, R3
+f0334e6b|	plan9	NEGSW R14>>12, R16
+e6031f5a|	plan9	NGCW ZR, R6
+f40302da|	plan9	NGC R2, R20
+ee03137a|	plan9	NGCSW R19, R14
+ee0303fa|	plan9	NGCS R3, R14
+1f2003d5|	plan9	NOP
+ab14e92a|	plan9	ORNW R9@>5, R5, R11
+185c3faa|	plan9	ORN ZR<<23, R0, R24
+a8850c32|	plan9	ORRW $3145776, R13, R8
+cad023b2|	plan9	ORR $-2025524839466146845, R6, R10
+5487ccaa|	plan9	ORR R12@>33, R26, R20
+293783f9|	plan9	PRFM 1640(R25), PLIL1STRM
+bc7389f8|	plan9	PRFUM 151(R29), #0X1C
+9203c05a|	plan9	RBITW R28, R18
+0501c0da|	plan9	RBIT R8, R5
+40005fd6|	plan9	RET R2
+940ac05a|	plan9	REVW R20, R20
+ca0fc0da|	plan9	REV R30, R10
+7807c05a|	plan9	REV16W R27, R24
+fb06c0da|	plan9	REV16 R23, R27
+dc0ac0da|	plan9	REV32 R22, R28
+970dc0da|	plan9	REV R12, R23
+42408813|	plan9	EXTRW $16, R8, R2, R2
+5a96db93|	plan9	EXTR $37, R27, R18, R26
+782cc41a|	plan9	RORW R4, R3, R24
+8c2ec69a|	plan9	ROR R6, R20, R12
+372ec61a|	plan9	RORW R6, R17, R23
+b72ddc9a|	plan9	ROR R28, R13, R23
+e501185a|	plan9	SBCW R24, R15, R5
+ac0011da|	plan9	SBC R17, R5, R12
+7a03067a|	plan9	SBCSW R6, R27, R26
+310008fa|	plan9	SBCS R8, R1, R17
+65837f93|	plan9	SBFIZ $1, R27, $33, R5
+5c1b4793|	plan9	SBFIZ $57, R26, $7, R28
+a71f5b93|	plan9	SBFIZ $37, R29, $8, R7
+640ede1a|	plan9	SDIVW R30, R19, R4
+2a0dd99a|	plan9	SDIV R25, R9, R10
+9f2003d5|	plan9	SEV
+bf2003d5|	plan9	SEVL
+045c389b|	plan9	SMADDL R24, R23, R0, R4
+6efe3e9b|	plan9	SMNEGL R30, R19, R14
+ebac239b|	plan9	SMSUBL R3, R11, R7, R11
+947f459b|	plan9	SMULH R5, R28, R20
+d67e3e9b|	plan9	SMULL R30, R22, R22
+6dff9f88|	plan9	STLRW R13, (R27)
+1ffd9fc8|	plan9	STLR ZR, (R8)
+a8fe9f08|	plan9	STLRB R8, (R21)
+abfd9f48|	plan9	STLRH R11, (R13)
+2ec02888|	plan9	STLXPW (R1), R16, R14, R8
+11993ec8|	plan9	STLXPW (R8), R6, R17, R30
+bbfe0f88|	plan9	STLXRW R27, (R21), R15
+e9fc09c8|	plan9	STLXR R9, (R7), R9
+c6fe0708|	plan9	STLXRB R6, (R22), R7
+c6fe0c48|	plan9	STLXRH R6, (R22), R12
+b3283028|	plan9	STNPW -128(R5), R10, R19
+252e26a8|	plan9	STNP -416(R17), R11, R5
+9fb18c28|	plan9	STP.P (ZR, R12), 100(R12)
+9ce5aba8|	plan9	STP.P (R28, R25), -328(R12)
+e5d08229|	plan9	STP.W (R5, R20), 20(R7)
+d6e79ea9|	plan9	STP.W (R22, R25), 488(R30)
+9eef2029|	plan9	STP (R30, R27), -252(R28)
+57b314a9|	plan9	STP (R23, R12), 328(R26)
+eda503b8|	plan9	MOVW.P R13, 58(R15)
+62241df8|	plan9	MOVD.P R2, -46(R3)
+d2bd18b8|	plan9	MOVW.W R18, -117(R14)
+542d12f8|	plan9	MOVD.W R20, -222(R10)
+e92c3bb9|	plan9	MOVW R9, 15148(R7)
+de4804f9|	plan9	MOVD R30, 2192(R6)
+cce40b38|	plan9	MOVB.P R12, 190(R6)
+eafd1238|	plan9	MOVB.W R10, -209(R15)
+7fcb0639|	plan9	MOVB ZR, 434(R27)
+5c6a3e38|	plan9	MOVB R28, R30(R18)
+a8551978|	plan9	MOVH.P R8, -107(R13)
+9e6c0c78|	plan9	MOVH.W R30, 198(R4)
+c83d0e79|	plan9	MOVH R8, 1822(R14)
+502a1db8|	plan9	STTRW -46(R18), R16
+ae180af8|	plan9	STTR 161(R5), R14
+ea1a0138|	plan9	STTRBW 17(R23), R10
+416b0278|	plan9	STTRHW 38(R26), R1
+659107b8|	plan9	MOVW R5, 121(R11)
+6b611ff8|	plan9	MOVD R11, -10(R11)
+99a01c38|	plan9	MOVB R25, -54(R4)
+99421e78|	plan9	MOVH R25, -28(R20)
+3e2a2688|	plan9	STXPW (R17), R10, R30, R6
+2f6a2cc8|	plan9	STXPW (R17), R26, R15, R12
+7d7f1b88|	plan9	STXRW R29, (R27), R27
+6e7e1bc8|	plan9	STXR R14, (R19), R27
+ec7c0208|	plan9	STXRB R12, (R7), R2
+ee7f0648|	plan9	STXRH R14, (RSP), R6
+2f8d204b|	plan9	SUBW R0.SXTB<<3, R9, R15
+1fbe3acb|	plan9	SUB R26.SXTH<<7, R16, RSP
+5af778d1|	plan9	SUB $(3645<<12), R26, R26
+6729034b|	plan9	SUBW R3<<10, R11, R7
+ae683f6b|	plan9	SUBSW ZR.UXTX<<2, R5, R14
+2f993deb|	plan9	SUBS R29.SXTB<<6, R9, R15
+db0d5f71|	plan9	SUBSW $(1987<<12), R14, R27
+3aec1ff1|	plan9	SUBS $2043, R1, R26
+1f24016b|	plan9	CMPW R1<<9, R0
+a1ae1bd4|	plan9	SVC $56693
+a61e0013|	plan9	SXTBW R21, R6
+441c4093|	plan9	SXTB R2, R4
+0c3c0013|	plan9	SXTHW R0, R12
+b33f4093|	plan9	SXTH R29, R19
+407f4093|	plan9	SXTW R26, R0
+455929d5|	plan9	SYSL $88384, R5
+bf8c1f72|	plan9	TSTW $1966110, R5
+ff10836a|	plan9	TSTW R3->4, R7
+dfc5daea|	plan9	TST R26@>49, R14
+aa6e43d3|	plan9	UBFX $3, R21, $25, R10
+46181a53|	plan9	UBFIZW $6, R2, $7, R6
+43294bd3|	plan9	LSL $53, R10, R3
+77787dd3|	plan9	UBFIZ $3, R3, $31, R23
+1a0bd61a|	plan9	UDIVW R22, R24, R26
+9308c19a|	plan9	UDIV R1, R4, R19
+755aa19b|	plan9	UMADDL R1, R22, R19, R21
+1ffdbe9b|	plan9	UMNEGL R30, R8, ZR
+cbaaba9b|	plan9	UMSUBL R26, R10, R22, R11
+0c7fdb9b|	plan9	UMULH R27, R24, R12
+cc7da79b|	plan9	UMULL R7, R14, R12
+3d1c0053|	plan9	UXTBW R1, R29
+0e3f0053|	plan9	UXTHW R24, R14
+5f2003d5|	plan9	WFE
+7f2003d5|	plan9	WFI
+3f2003d5|	plan9	YIELD
+71b9604e|	plan9	VABS V11.H8, V17.H8
+5186f65e|	plan9	ADD F22, F18, F17
+4986f34e|	plan9	VADD V19.D2, V18.D2, V9.D2
+1243720e|	plan9	VADDHN V18.S4, V24.S4, V18.H4
+0640354e|	plan9	VADDHN2 V21.H8, V0.H8, V6.B16
+d9bdfa4e|	plan9	VADDP V26.D2, V14.D2, V25.D2
+4c59284e|	plan9	VAESD V10.B16, V12.B16
+8c48284e|	plan9	VAESE V4.B16, V12.B16
+f47a284e|	plan9	VAESIMC V23.B16, V20.B16
+c56b284e|	plan9	VAESMC V30.B16, V5.B16
+bf1c3b0e|	plan9	VAND V27.B8, V5.B8, V31.B8
+6444026f|	plan9	VMVNI $(67<<16), V4.S4
+1357032f|	plan9	VBIC $(120<<16), V19.S2
+561d6a0e|	plan9	VBIC V10.B8, V10.B8, V22.B8
+cd1ff06e|	plan9	VBIF V16.B16, V30.B16, V13.B16
+f31ebd6e|	plan9	VBIT V29.B16, V23.B16, V19.B16
+6f1d6c2e|	plan9	VBSL V12.B8, V11.B8, V15.B8
+1e48600e|	plan9	VCLS V0.H4, V30.H4
+6948202e|	plan9	VCLZ V3.B8, V9.B8
+968efd7e|	plan9	CMEQ F29, F20, F22
+e58f6d6e|	plan9	VCMEQ V13.H8, V31.H8, V5.H8
+8f98600e|	plan9	VCMEQ $0, V4.H4, V15.H4
+4f3db84e|	plan9	VCMGE V24.S4, V10.S4, V15.S4
+2788a02e|	plan9	VCMGE $0, V1.S2, V7.S2
+bf35714e|	plan9	VCMGT V17.H8, V13.H8, V31.H8
+4a89604e|	plan9	VCMGT $0, V10.H8, V10.H8
+9635252e|	plan9	VCMHI V5.B8, V12.B8, V22.B8
+d83eff6e|	plan9	VCMHS V31.D2, V22.D2, V24.D2
+cb99206e|	plan9	VCMLE $0, V14.B16, V11.B16
+29a9604e|	plan9	VCMLT $0, V9.H8, V9.H8
+d18eea5e|	plan9	CMTST F10, F22, F17
+d18ea94e|	plan9	VCMTST V9.S4, V22.S4, V17.S4
+4a04075e|	plan9	VMOV V2.B[3], F10
+0504040e|	plan9	VDUP V0.S[0], V5.S2
+b20e1f4e|	plan9	VDUP R21, V18.B16
+2a1f3e6e|	plan9	VEOR V30.B16, V25.B16, V10.B16
+0bd5aa7e|	plan9	FABD F10, F8, F11
+12d7b96e|	plan9	VFABD V25.S4, V24.S4, V18.S4
+a1f9a04e|	plan9	FABS V13.S4, V1.S4
+1ac3201e|	plan9	FABSS F24, F26
+d8c3601e|	plan9	FABSD F30, F24
+95ee267e|	plan9	FACGE F6, F20, F21
+2bee262e|	plan9	VFACGE V6.S2, V17.S2, V11.S2
+1aedec7e|	plan9	FACGT F12, F8, F26
+74effa6e|	plan9	VFACGT V26.D2, V27.D2, V20.D2
+7ed4260e|	plan9	FADD V6.S2, V3.S2, V30.S2
+4528251e|	plan9	FADDS F5, F2, F5
+262b661e|	plan9	FADDD F6, F25, F6
+84d8707e|	plan9	FADDP V4.D2, F4
+71d4276e|	plan9	VFADDP V7.S4, V3.S4, V17.S4
+a5f43f1e|	plan9	FCCMPS AL, F31, F5, $5
+20e5601e|	plan9	FCCMPD AL, F0, F9, $0
+52d4331e|	plan9	FCCMPES LE, F19, F2, $2
+1e66761e|	plan9	FCCMPED VS, F22, F16, $14
+d7e6695e|	plan9	FCMEQ F9, F22, F23
+e7d9a05e|	plan9	FCMEQ $0, F15, F7
+dadaa04e|	plan9	VFCMEQ $0, V22.S4, V26.S4
+28e5737e|	plan9	FCMGE F19, F9, F8
+a2e73a6e|	plan9	VFCMGE V26.S4, V29.S4, V2.S4
+4fcba07e|	plan9	FCMGE $0, F26, F15
+43c8a02e|	plan9	VFCMGE $0, V2.S2, V3.S2
+ffe5a67e|	plan9	FCMGT F6, F15, F31
+7ee7bd2e|	plan9	VFCMGT V29.S2, V27.S2, V30.S2
+5bc8e05e|	plan9	FCMGT $0, F2, F27
+3dc9a04e|	plan9	VFCMGT $0, V9.S4, V29.S4
+38daa07e|	plan9	FCMLE $0, F17, F24
+8fdaa02e|	plan9	VFCMLE $0, V20.S2, V15.S2
+93e8e05e|	plan9	FCMLT $0, F4, F19
+9fe9a04e|	plan9	VFCMLT $0, V12.S4, V31.S4
+a023201e|	plan9	FCMPS F0, F29
+c822231e|	plan9	FCMPS $(0.0), F22
+a022651e|	plan9	FCMPD F5, F21
+a8227d1e|	plan9	FCMPD $(0.0), F21
+70203e1e|	plan9	FCMPES F30, F3
+38232b1e|	plan9	FCMPES $(0.0), F25
+70206c1e|	plan9	FCMPED F12, F3
+b823731e|	plan9	FCMPED $(0.0), F29
+3e6f331e|	plan9	FCSELS VS, F25, F19, F30
+a64f6d1e|	plan9	FCSELD MI, F29, F13, F6
+0d41e21e|	plan9	FCVTHS F8, F13
+cbc0e21e|	plan9	FCVTHD F6, F11
+18c0231e|	plan9	FCVTSH F0, F24
+a7c0221e|	plan9	FCVTSD F5, F7
+e7c3631e|	plan9	FCVTDH F31, F7
+9f43621e|	plan9	FCVTDS F28, F31
+a0c8215e|	plan9	FCVTAS F5, F0
+4dc8210e|	plan9	VFCVTAS V2.S2, V13.S2
+0300241e|	plan9	FCVTASW F0, R3
+fd03249e|	plan9	FCVTAS F31, R29
+ef01641e|	plan9	FCVTASW F15, R15
+4c01649e|	plan9	FCVTAS F10, R12
+9ac8617e|	plan9	FCVTAU F4, F26
+b802251e|	plan9	FCVTAUW F21, R24
+2a03259e|	plan9	FCVTAU F25, R10
+ea00651e|	plan9	FCVTAUW F7, R10
+0102659e|	plan9	FCVTAU F16, R1
+0d7a610e|	plan9	VFCVTL V16.S2, V13.D2
+ed79214e|	plan9	VFCVTL2 V15.H8, V13.S4
+43bb615e|	plan9	FCVTMS F26, F3
+c000301e|	plan9	FCVTMSW F6, R0
+9202309e|	plan9	FCVTMS F20, R18
+0800701e|	plan9	FCVTMSW F0, R8
+6603709e|	plan9	FCVTMS F27, R6
+f0b9217e|	plan9	FCVTMU F15, F16
+3bba212e|	plan9	VFCVTMU V17.S2, V27.S2
+5900311e|	plan9	FCVTMUW F2, R25
+9a03319e|	plan9	FCVTMU F28, R26
+fa01711e|	plan9	FCVTMUW F15, R26
+6f01719e|	plan9	FCVTMU F11, R15
+1968210e|	plan9	VFCVTN V0.S4, V25.H4
+3d69214e|	plan9	VFCVTN2 V9.S4, V29.H8
+87aa615e|	plan9	FCVTNS F20, F7
+e301201e|	plan9	FCVTNSW F15, R3
+6002209e|	plan9	FCVTNS F19, R0
+1600601e|	plan9	FCVTNSW F0, R22
+8503609e|	plan9	FCVTNS F28, R5
+f5ab617e|	plan9	FCVTNU F31, F21
+2b02211e|	plan9	FCVTNUW F17, R11
+f902219e|	plan9	FCVTNU F23, R25
+0702611e|	plan9	FCVTNUW F16, R7
+9d03619e|	plan9	FCVTNU F28, R29
+dcaba15e|	plan9	FCVTPS F30, F28
+b4a8a10e|	plan9	VFCVTPS V5.S2, V20.S2
+5302281e|	plan9	FCVTPSW F18, R19
+e003289e|	plan9	FCVTPS F31, R0
+9501681e|	plan9	FCVTPSW F12, R21
+6703689e|	plan9	FCVTPS F27, R7
+68a8a17e|	plan9	FCVTPU F3, F8
+dcaba12e|	plan9	VFCVTPU V30.S2, V28.S2
+9d03291e|	plan9	FCVTPUW F28, R29
+5f01299e|	plan9	FCVTPU F10, ZR
+e101691e|	plan9	FCVTPUW F15, R1
+3f00699e|	plan9	FCVTPU F1, ZR
+ee6b612e|	plan9	VFCVTXN V31.D2, V14.S2
+b1fd215f|	plan9	FCVTZS $31, F13, F17
+bafd2c0f|	plan9	FCVTZS $20, V13.S2, V26.S2
+47b8e15e|	plan9	FCVTZSDD F2, F7
+dcbbe14e|	plan9	FCVTZS V30.D2, V28.D2
+56f8181e|	plan9	FCVTZS $2, F2, R22
+9265189e|	plan9	FCVTZS $39, F12, R18
+d3ad581e|	plan9	FCVTZS $21, F14, R19
+3d9b589e|	plan9	FCVTZS $26, F25, R29
+1a00381e|	plan9	FCVTZSSW F0, R26
+d302389e|	plan9	FCVTZSS F22, R19
+5303781e|	plan9	FCVTZSDW F26, R19
+8f01789e|	plan9	FCVTZSD F12, R15
+57fe537f|	plan9	FCVTZU $45, F18, F23
+beff796f|	plan9	FCVTZU $7, V29.D2, V30.D2
+08b9e17e|	plan9	FCVTZUDD F8, F8
+cdbbe16e|	plan9	FCVTZU V30.D2, V13.D2
+2126199e|	plan9	FCVTZU $55, F17, R1
+70a9591e|	plan9	FCVTZU $22, F11, R16
+8c25599e|	plan9	FCVTZU $55, F12, R12
+1201391e|	plan9	FCVTZUSW F8, R18
+0800399e|	plan9	FCVTZUS F0, R8
+da00791e|	plan9	FCVTZUDW F6, R26
+2903799e|	plan9	FCVTZUD F25, R9
+56fd3f2e|	plan9	FDIV V31.S2, V10.S2, V22.S2
+1f182e1e|	plan9	FDIVS F14, F0, F31
+ce1b741e|	plan9	FDIVD F20, F30, F14
+0d61021f|	plan9	FMADD F24, F2, F8, F13
+03205e1f|	plan9	FMADD F8, F30, F0, F3
+72f6654e|	plan9	FMAX V5.D2, V19.D2, V18.D2
+1849281e|	plan9	FMAXS F8, F8, F24
+8e4a6e1e|	plan9	FMAXD F14, F20, F14
+54c7304e|	plan9	FMAXNM V16.S4, V26.S4, V20.S4
+91683a1e|	plan9	FMAXNMS F26, F4, F17
+f56a721e|	plan9	FMAXNMD F18, F23, F21
+c8cb307e|	plan9	FMAXNMP V30.S2, F8
+06c9306e|	plan9	FMAXNMV V8.S4, F6
+b6fb707e|	plan9	FMAXP V29.D2, F22
+1759341e|	plan9	FMINS F20, F8, F23
+675b721e|	plan9	FMIND F18, F27, F7
+69792d1e|	plan9	FMINNMS F13, F11, F9
+ab786b1e|	plan9	FMINNMD F11, F5, F11
+0fcab07e|	plan9	FMINNMP V16.S2, F15
+d2c6b26e|	plan9	VFMINNMP V18.S4, V22.S4, V18.S4
+22fab07e|	plan9	FMINP V17.S2, F2
+f5f5f56e|	plan9	VFMINP V21.D2, V15.D2, V21.D2
+bc13c95f|	plan9	FMLA V9.D[0], F29, F28
+5d51a85f|	plan9	FMLS V8.S[1], F10, F29
+d3ccb94e|	plan9	VFMLS V25.S4, V6.S4, V19.S4
+5bf4014f|	plan9	FMOV $9., V27.S4
+5bf5026f|	plan9	FMOV $0.203125, V27.D2
+6541201e|	plan9	FMOVS F11, F5
+b742601e|	plan9	FMOVD F21, F23
+6002271e|	plan9	FMOVS R19, F0
+5301261e|	plan9	FMOVS F10, R19
+c103679e|	plan9	FMOVD R30, F1
+3301af9e|	plan9	FMOV R9, V19.D[1]
+bd00669e|	plan9	FMOVD F5, R29
+ee02ae9e|	plan9	FMOV V23.D[1], R14
+0ff0251e|	plan9	FMOVS $15.5, F15
+16506a1e|	plan9	FMOVD $0.28125, F22
+d1c20e1f|	plan9	FMSUB F16, F14, F22, F17
+fdae491f|	plan9	FMSUB F11, F9, F23, F29
+a4989d4f|	plan9	FMUL V29.S[2], V5.S4, V4.S4
+efde706e|	plan9	FMUL V16.D2, V23.D2, V15.D2
+190a291e|	plan9	FMULS F9, F16, F25
+430a671e|	plan9	FMULD F7, F18, F3
+21919e7f|	plan9	FMULX V30.S[0], F9, F1
+5298c76f|	plan9	VFMULX V7.D[1], V2.D2, V18.D2
+1ddf3c5e|	plan9	FMULX F28, F24, F29
+a2fba06e|	plan9	FNEG V29.S4, V2.S4
+7a40211e|	plan9	FNEGS F3, F26
+f843611e|	plan9	FNEGD F31, F24
+326b381f|	plan9	FNMADD F26, F24, F25, F18
+4b636a1f|	plan9	FNMADD F24, F10, F26, F11
+48fa201f|	plan9	FNMSUB F30, F0, F18, F8
+04d87f1f|	plan9	FNMSUB F22, F31, F0, F4
+0289371e|	plan9	FNMULS F23, F8, F2
+0e8a691e|	plan9	FNMULD F9, F16, F14
+05dba15e|	plan9	FRECPE F24, F5
+42d9a14e|	plan9	VFRECPE V10.S4, V2.S4
+2eff655e|	plan9	FRECPS F5, F25, F14
+03fe774e|	plan9	VFRECPS V23.D2, V16.D2, V3.D2
+b4fba15e|	plan9	FRECPX F29, F20
+9d41261e|	plan9	FRINTAS F12, F29
+ea42661e|	plan9	FRINTAD F23, F10
+e399a16e|	plan9	FRINTI V15.S4, V3.S4
+6ec3271e|	plan9	FRINTIS F27, F14
+ecc1671e|	plan9	FRINTID F15, F12
+4543251e|	plan9	FRINTMS F26, F5
+f242651e|	plan9	FRINTMD F23, F18
+898a214e|	plan9	FRINTN V20.S4, V9.S4
+1641241e|	plan9	FRINTNS F8, F22
+5341641e|	plan9	FRINTND F10, F19
+248be14e|	plan9	FRINTP V25.D2, V4.D2
+35c2241e|	plan9	FRINTPS F17, F21
+6fc3641e|	plan9	FRINTPD F27, F15
+0940271e|	plan9	FRINTXS F0, F9
+4643671e|	plan9	FRINTXD F26, F6
+749aa14e|	plan9	FRINTZ V19.S4, V20.S4
+8bc0251e|	plan9	FRINTZS F4, F11
+7cc1651e|	plan9	FRINTZD F11, F28
+dedbe17e|	plan9	FRSQRTE F30, F30
+04daa16e|	plan9	VFRSQRTE V16.S4, V4.S4
+cdfce45e|	plan9	FRSQRTS F4, F6, F13
+d9fda04e|	plan9	VFRSQRTS V0.S4, V14.S4, V25.S4
+c5c1211e|	plan9	FSQRTS F14, F5
+67c1611e|	plan9	FSQRTD F11, F7
+a4d6b14e|	plan9	FSUB V17.S4, V21.S4, V4.S4
+6138351e|	plan9	FSUBS F21, F3, F1
+be3b6a1e|	plan9	FSUBD F10, F29, F30
+4d2f016e|	plan9	VMOV V26.B[5], V13.B[0]
+741e174e|	plan9	VMOV R19, V20.B[11]
+e170404c|	plan9	VLD1 (R7), [V1.B16]
+7aa9404c|	plan9	VLD1 (R11), [V26.S4, V27.S4]
+4b6d400c|	plan9	VLD1 (R10), [V11.D1, V12.D1, V13.D1]
+582b400c|	plan9	VLD1 (R26), [V24.S2, V25.S2, V26.S2, V27.S2]
+8f7cdf4c|	plan9	VLD1.P 16(R4), [V15.D2]
+0a76ce4c|	plan9	VLD1.P (R16)(R14), [V10.H8]
+2aa6df0c|	plan9	VLD1.P 16(R17), [V10.H4, V11.H4]
+35a7d70c|	plan9	VLD1.P (R25)(R23), [V21.H4, V22.H4]
+ae6ddf4c|	plan9	VLD1.P 48(R13), [V14.D2, V15.D2, V16.D2]
+b362d74c|	plan9	VLD1.P (R21)(R23), [V19.B16, V20.B16, V21.B16]
+6d22df0c|	plan9	VLD1.P 32(R19), [V13.B8, V14.B8, V15.B8, V16.B8]
+6722c90c|	plan9	VLD1.P (R19)(R9), [V7.B8, V8.B8, V9.B8, V10.B8]
+c71f404d|	plan9	LD1 (R30), [V7.B][15]
+f55a400d|	plan9	LD1 (R23), [V21.H][3]
+f080400d|	plan9	LD1 (R7), [V16.S][0]
+ed84404d|	plan9	LD1 (R7), [V13.D][1]
+fd0bdf4d|	plan9	LD1.P 1(RSP), [V29.B][10]
+c811dc0d|	plan9	LD1.P (R14)(R28), [V8.B][4]
+6548cb4d|	plan9	LD1.P (R3)(R11), [V5.H][5]
+9882df4d|	plan9	LD1.P 4(R20), [V24.S][2]
+f482c74d|	plan9	LD1.P (R23)(R7), [V20.S][2]
+0d87df0d|	plan9	LD1.P 8(R24), [V13.D][0]
+1b85db0d|	plan9	LD1.P (R8)(R27), [V27.D][0]
+58c3404d|	plan9	VLD1R (R26), [V24.B16]
+c0c6df4d|	plan9	VLD1R 2(R22), [V0.H8]
+a6cec90d|	plan9	VLD1R (R21)(R9), [V6.D1]
+e68a400c|	plan9	VLD2 (R23), [V6.S2, V7.S2]
+4007604d|	plan9	LD2 (R26), [V0.B, V1.B][9]
+8c49604d|	plan9	LD2 (R12), [V12.H, V13.H][5]
+4f92600d|	plan9	LD2 (R18), [V15.S, V16.S][1]
+b186600d|	plan9	LD2 (R21), [V17.D, V18.D][0]
+631aff0d|	plan9	LD2 2(R19), [V3.B, V4.B][6]
+330ceb4d|	plan9	LD2 (R1)(R11), [V19.B, V20.B][11]
+454bff4d|	plan9	LD2 4(R26), [V5.H, V6.H][5]
+0792ff0d|	plan9	LD2 8(R16), [V7.S, V8.S][1]
+3b91fd0d|	plan9	LD2 (R9)(R29), [V27.S, V28.S][1]
+b086ff4d|	plan9	LD2 16(R21), [V16.D, V17.D][1]
+da86e30d|	plan9	LD2 (R22)(R3), [V26.D, V27.D][0]
+e7cf604d|	plan9	VLD2R (RSP), [V7.D2, V8.D2]
+5ac8ff0d|	plan9	VLD2R 8(R2), [V26.S2, V27.S2]
+13c1f10d|	plan9	VLD2R (R8)(R17), [V19.B8, V20.B8]
+0947404c|	plan9	VLD3 (R24), [V9.H8, V10.H8, V11.H8]
+8043df0c|	plan9	VLD3 24(R28), [V0.B8, V1.B8, V2.B8]
+6344d50c|	plan9	VLD3 (R3)(R21), [V3.H4, V4.H4, V5.H4]
+663d400d|	plan9	LD3 (R11), [V6.B, V7.B, V8.B][7]
+5b6b400d|	plan9	LD3 (R26), [V27.H, V28.H, V29.H][1]
+02a0404d|	plan9	LD3 (R0), [V2.S, V3.S, V4.S][2]
+e1a5404d|	plan9	LD3 (R15), [V1.D, V2.D, V3.D][1]
+b53edf0d|	plan9	LD3 3(R21), [V21.B, V22.B, V23.B][7]
+f625d10d|	plan9	LD3 (R15)(R17), [V22.B, V23.B, V24.B][1]
+3d7bda4d|	plan9	LD3 (R25)(R26), [V29.H, V30.H, V31.H][7]
+6ea0df0d|	plan9	LD3 12(R3), [V14.S, V15.S, V16.S][0]
+d9a0c60d|	plan9	LD3 (R6)(R6), [V25.S, V26.S, V27.S][0]
+b6a7df0d|	plan9	LD3 24(R29), [V22.D, V23.D, V24.D][0]
+dfa6d94d|	plan9	LD3 (R22)(R25), [V31.D, V0.D, V1.D][1]
+7de9404d|	plan9	VLD3R (R11), [V29.S4, V30.S4, V31.S4]
+2fe6df4d|	plan9	VLD3R 6(R17), [V15.H8, V16.H8, V17.H8]
+cae7c84d|	plan9	VLD3R (R30)(R8), [V10.H8, V11.H8, V12.H8]
+9a0b400c|	plan9	VLD4 (R28), [V26.S2, V27.S2, V28.S2, V29.S2]
+4b03df0c|	plan9	VLD4 32(R26), [V11.B8, V12.B8, V13.B8, V14.B8]
+8e0bcc4c|	plan9	VLD4 (R28)(R12), [V14.S4, V15.S4, V16.S4, V17.S4]
+182c604d|	plan9	LD4 (R0), [V24.B, V25.B, V26.B, V27.B][11]
+feb2600d|	plan9	LD4 (R23), [V30.S, V31.S, V0.S, V1.S][1]
+59a4604d|	plan9	LD4 (R2), [V25.D, V26.D, V27.D, V28.D][1]
+9b25ff4d|	plan9	LD4 4(R12), [V27.B, V28.B, V29.B, V30.B][9]
+1f35e84d|	plan9	LD4 (R8)(R8), [V31.B, V0.B, V1.B, V2.B][13]
+91b2ff4d|	plan9	LD4 16(R20), [V17.S, V18.S, V19.S, V20.S][3]
+88b3ed4d|	plan9	LD4 (R28)(R13), [V8.S, V9.S, V10.S, V11.S][3]
+9aa5ff4d|	plan9	LD4 32(R12), [V26.D, V27.D, V28.D, V29.D][1]
+efa5e10d|	plan9	LD4 (R15)(R1), [V15.D, V16.D, V17.D, V18.D][0]
+07ed604d|	plan9	VLD4R (R8), [V7.D2, V8.D2, V9.D2, V10.D2]
+0defff0d|	plan9	VLD4R 32(R24), [V13.D1, V14.D1, V15.D1, V16.D1]
+43e1f14d|	plan9	VLD4R (R10)(R17), [V3.B16, V4.B16, V5.B16, V6.B16]
+136e682c|	plan9	LDNP -192(R16), F27, F19
+cc67676c|	plan9	LDNP -400(R30), F25, F12
+e6dd4eac|	plan9	LDNP 464(R15), V23, V6
+b7e9c22c|	plan9	LDP.P 20(R13), (F23, F26)
+92c3fe6c|	plan9	LDP.P -24(R28), (F18, F16)
+f281e6ac|	plan9	LDP.P -816(R15), (V18, V0)
+4f06cd2d|	plan9	LDP.W 104(R18), (F15, F1)
+0f6fdc6d|	plan9	LDP.W 448(R24), (F15, F27)
+170ccbad|	plan9	LDP.W 352(R0), (V23, V3)
+71ea7a2d|	plan9	LDP -44(R19), (F17, F26)
+c8816c6d|	plan9	LDP -312(R14), (F8, F0)
+da6540ad|	plan9	LDP (R14), (V26, V25)
+92064c3c|	plan9	MOVD.P 192(R20), F18
+94d4577c|	plan9	MOVD.P -131(R4), F20
+39055fbc|	plan9	MOVD.P -16(R9), F25
+989551fc|	plan9	MOVD.P -231(R12), F24
+4764c23c|	plan9	MOVD.P 38(R2), V7
+c15e4e3c|	plan9	MOVD.W 229(R22), F1
+c8ce487c|	plan9	MOVD.W 140(R22), F8
+ca5d5bbc|	plan9	MOVD.W -75(R14), F10
+34fd56fc|	plan9	MOVD.W -145(R9), F20
+bd0dd53c|	plan9	MOVD.W -176(R13), V29
+ab65443d|	plan9	MOVD 281(R13), F11
+cb57537d|	plan9	MOVD 2474(R30), F11
+f2606fbd|	plan9	MOVD 12128(R7), F18
+088b67fd|	plan9	MOVD 20240(R24), F8
+0173ce3d|	plan9	MOVD 14784(R24), V1
+726b733c|	plan9	MOVD R19(R27), F18
+43a1413c|	plan9	LDUR 26(R10), F3
+c7034f7c|	plan9	LDUR 240(R30), F7
+ad8350bc|	plan9	LDUR -248(R29), F13
+07a350fc|	plan9	LDUR -246(R24), F7
+0212c63c|	plan9	LDUR 97(R16), V2
+6f0a7a2f|	plan9	VMLA V10.H[7], V19.H4, V15.H4
+fe95294e|	plan9	VMLA V9.B16, V15.B16, V30.B16
+f24a4f2f|	plan9	VMLS V15.H[4], V23.H4, V18.H4
+26947e2e|	plan9	VMLS V30.H4, V1.H4, V6.H4
+6606115e|	plan9	VMOV V19.B[8], F6
+0866116e|	plan9	VMOV V16.B[12], V8.B[8]
+6e1d0f4e|	plan9	VMOV R11, V14.B[7]
+6d1fa10e|	plan9	VORR V1.B8, V27.B8, V13.B8
+b93f1a0e|	plan9	UMOVW V29.H[6], R25
+74e7020f|	plan9	VMOVI $91, V20.B8
+0ff4040f|	plan9	FMOV $-2., V15.S2
+4c47060f|	plan9	VMOVI $(218<<16), V12.S2
+aa06064f|	plan9	VMOVI $213, V10.S4
+8de4042f|	plan9	MOVI $-72057594021216256, F13
+b1e6046f|	plan9	VMOVI $-72056498804555521, V17.D2
+609f214e|	plan9	VMUL V1.B16, V27.B16, V0.B16
+9f5a206e|	plan9	VMVN V20.B16, V31.B16
+da65032f|	plan9	VMVNI $(110<<24), V26.S2
+4d36036f|	plan9	VBIC $(114<<8), V13.S4
+4d66052f|	plan9	VMVNI $(178<<24), V13.S2
+a4bbe06e|	plan9	VNEG V29.D2, V4.D2
+bf5a206e|	plan9	VMVN V21.B16, V31.B16
+2b1fe24e|	plan9	VORN V2.B16, V25.B16, V11.B16
+22e4024f|	plan9	VMOVI $65, V2.B16
+3086050f|	plan9	VMOVI $177, V16.H4
+051db80e|	plan9	VORR V24.B8, V8.B8, V5.B8
+48e2290e|	plan9	VPMULL V9.B8, V18.B8, V8.H8
+7341652e|	plan9	VRADDHN V5.S4, V11.S4, V19.H4
+1b417f6e|	plan9	VRADDHN2 V31.S4, V8.S4, V27.H8
+e158606e|	plan9	VRBIT V7.B16, V1.B16
+f418200e|	plan9	VREV16 V7.B8, V20.B8
+228d2a0f|	plan9	VRSHRN $22, V9.D2, V2.S2
+a861aa2e|	plan9	VRSUBHN V10.D2, V13.D2, V8.S2
+7160786e|	plan9	VRSUBHN2 V24.S4, V3.S4, V17.H8
+cc7f314e|	plan9	VSABA V17.B16, V30.B16, V12.B16
+1350644e|	plan9	VSABAL2 V4.H8, V0.H8, V19.S4
+a1757d4e|	plan9	VSABD V29.H8, V13.H8, V1.H8
+0971a00e|	plan9	VSABDL V0.S2, V8.S2, V9.D2
+af70214e|	plan9	VSABDL2 V1.B16, V5.B16, V15.H8
+626ba04e|	plan9	VSADALP V27.S4, V2.D2
+1503374e|	plan9	VSADDL2 V23.B16, V24.B16, V21.H8
+592b204e|	plan9	VSADDLP V26.B16, V25.H8
+d813600e|	plan9	VSADDW V0.H4, V30.S4, V24.S4
+31e5210f|	plan9	SCVTF $31, V9.S2, V17.S2
+aeda215e|	plan9	SCVTFSS F21, F14
+f0e9021e|	plan9	SCVTF $6, R15, F16
+42b4421e|	plan9	SCVTF $19, R2, F2
+8b10029e|	plan9	SCVTF $60, R4, F11
+59e6429e|	plan9	SCVTF $7, R18, F25
+cf01221e|	plan9	SCVTFWS R14, F15
+2d03621e|	plan9	SCVTFWD R25, F13
+af00229e|	plan9	SCVTFS R5, F15
+bf00629e|	plan9	SCVTFD R5, F31
+2a02025e|	plan9	SHA1C V2.S4, F17, V10
+8b0b285e|	plan9	SHA1H F28, F11
+11201f5e|	plan9	SHA1M V31.S4, F0, V17
+f110115e|	plan9	SHA1P V17.S4, F7, V17
+b732115e|	plan9	VSHA1SU0 V17.S4, V21.S4, V23.S4
+cf18285e|	plan9	VSHA1SU1 V6.S4, V15.S4
+2e520f5e|	plan9	SHA256H2 V15.S4, V17, V14
+77401a5e|	plan9	SHA256H V26.S4, V3, V23
+b92a285e|	plan9	VSHA256SU0 V21.S4, V25.S4
+7e63175e|	plan9	VSHA256SU1 V23.S4, V27.S4, V30.S4
+d504ab0e|	plan9	VSHADD V11.S2, V6.S2, V21.S2
+5a54734f|	plan9	VSHL $51, V2.D2, V26.D2
+0638212e|	plan9	VSHLL $8, V0.B8, V6.H8
+a238216e|	plan9	VSHLL2 $8, V5.B16, V2.H8
+f5863e0f|	plan9	VSHRN $2, V23.D2, V21.S2
+f187234f|	plan9	VSHRN2 $29, V31.D2, V17.S4
+e124b04e|	plan9	VSHSUB V16.S4, V7.S4, V1.S4
+3657252f|	plan9	VSLI $5, V25.S2, V22.S2
+c266aa4e|	plan9	VSMAX V10.S4, V22.S4, V2.S4
+2c6ca74e|	plan9	VSMIN V7.S4, V1.S4, V12.S4
+4aae390e|	plan9	VSMINP V25.B8, V18.B8, V10.B8
+1a82ba0e|	plan9	VSMLAL V26.S2, V16.S2, V26.D2
+2381ad4e|	plan9	VSMLAL2 V13.S4, V9.S4, V3.D2
+0da17a4e|	plan9	VSMLSL2 V26.H8, V8.H8, V13.S4
+4f2e0d4e|	plan9	SMOV V18.B[6], R15
+e4a0980f|	plan9	VSMULL V24.S[0], V7.S2, V4.D2
+51c2220e|	plan9	VSMULL V2.B8, V18.B8, V17.H8
+01c26d4e|	plan9	VSMULL2 V13.H8, V16.H8, V1.S4
+f978205e|	plan9	SQABS F7, F25
+760cef5e|	plan9	SQADD F15, F3, F22
+390c224e|	plan9	VSQADD V2.B16, V1.B16, V25.B16
+5439455f|	plan9	SQDMLAL V5.H[4], F10, F20
+8391765e|	plan9	SQDMLAL F22, F12, F3
+c9907a4e|	plan9	VSQDMLAL2 V26.H8, V6.H8, V9.S4
+0b73445f|	plan9	SQDMLSL V4.H[0], F24, F11
+8e728d0f|	plan9	VSQDMLSL V13.S[0], V20.S2, V14.D2
+fe787d4f|	plan9	VSQDMLSL2 V13.H[7], V7.H8, V30.S4
+bdb2b55e|	plan9	SQDMLSL F21, F21, F29
+d0c9be4f|	plan9	VSQDMULH V30.S[3], V14.S4, V16.S4
+89b77c5e|	plan9	SQDMULH F28, F28, F9
+c9bb515f|	plan9	SQDMULL V1.H[5], F30, F9
+5379e07e|	plan9	SQNEG F10, F19
+4b7aa06e|	plan9	VSQNEG V18.S4, V11.S4
+1bd1750f|	plan9	VSQRDMULH V5.H[3], V8.H4, V27.H4
+f55e755e|	plan9	SQRSHL F21, F23, F21
+ba5fbd4e|	plan9	VSQRSHL V29.S4, V29.S4, V26.S4
+ba9d1e0f|	plan9	VSQRSHRN $2, V13.S4, V26.H4
+3d9c284f|	plan9	VSQRSHRN2 $24, V1.D2, V29.S4
+8a8f2c6f|	plan9	VSQRSHRUN2 $20, V28.D2, V10.S4
+eb760b5f|	plan9	SQSHL $3, F23, F11
+4a77220f|	plan9	VSQSHL $2, V26.S2, V10.S2
+6c4cfb5e|	plan9	SQSHL F27, F3, F12
+ad4eba4e|	plan9	VSQSHL V26.S4, V21.S4, V13.S4
+9364257f|	plan9	SQSHLU $5, F4, F19
+b267392f|	plan9	VSQSHLU $25, V29.S2, V18.S2
+c085042f|	plan9	VMVNI $142, V0.H4
+7584326f|	plan9	VSQSHRUN2 $14, V3.D2, V21.S4
+3a2fe25e|	plan9	SQSUB F2, F25, F26
+2c2ca34e|	plan9	VSQSUB V3.S4, V1.S4, V12.S4
+484ba15e|	plan9	SQXTN F26, F8
+824b210e|	plan9	VSQXTN V28.H8, V2.B8
+5b48214e|	plan9	VSQXTN2 V2.H8, V27.B16
+e228a16e|	plan9	VSQXTUN2 V7.D2, V2.S4
+1c44416f|	plan9	VSRI $63, V0.D2, V28.D2
+1e56eb5e|	plan9	SRSHL F11, F16, F30
+bb56fe4e|	plan9	VSRSHL V30.D2, V21.D2, V27.D2
+c6262d0f|	plan9	VSRSHR $19, V22.S2, V6.S2
+0c366c5f|	plan9	SRSRA $20, F16, F12
+13376e4f|	plan9	VSRSRA $18, V24.D2, V19.D2
+7ba5040f|	plan9	VMOVI $(139<<8), V27.H4
+9c076f5f|	plan9	SSHR $17, F28, F28
+2804434f|	plan9	VSSHR $61, V1.D2, V8.D2
+b717535f|	plan9	SSRA $45, F29, F23
+c2160f0f|	plan9	VSSRA $1, V22.B8, V2.B8
+8a333a4e|	plan9	VSSUBW2 V26.B16, V28.H8, V10.H8
+3a70000c|	plan9	VST1 (R1), [V26.B8]
+1bab004c|	plan9	VST1 (R24), [V27.S4, V28.S4]
+8d69004c|	plan9	VST1 (R12), [V13.S4, V14.S4, V15.S4]
+9c26004c|	plan9	VST1 (R20), [V28.H8, V29.H8, V30.H8, V31.H8]
+c87a9f0c|	plan9	VST1 8(R22), [V8.S2]
+5a7f800c|	plan9	VST1 (R26)(R0), [V26.D1]
+eea99f4c|	plan9	VST1 32(R15), [V14.S4, V15.S4]
+11af9d4c|	plan9	VST1 (R24)(R29), [V17.D2, V18.D2]
+ec689f0c|	plan9	VST1 24(R7), [V12.S2, V13.S2, V14.S2]
+8662900c|	plan9	VST1 (R20)(R16), [V6.B8, V7.B8, V8.B8]
+0b249f4c|	plan9	VST1 64(R0), [V11.H8, V12.H8, V13.H8, V14.H8]
+6b2d8b4c|	plan9	VST1 (R11)(R11), [V11.D2, V12.D2, V13.D2, V14.D2]
+3212004d|	plan9	ST1 (R17), [V18.B][12]
+3392004d|	plan9	ST1 (R17), [V19.S][3]
+0284000d|	plan9	ST1 (R0), [V2.D][0]
+340f9f0d|	plan9	ST1 1(R25), [V20.B][3]
+0d069a4d|	plan9	ST1 (R16)(R26), [V13.B][9]
+2e51950d|	plan9	ST1 (R9)(R21), [V14.H][2]
+3f839f0d|	plan9	ST1 4(R25), [V31.S][0]
+1492844d|	plan9	ST1 (R16)(R4), [V20.S][3]
+dd869f4d|	plan9	ST1 8(R22), [V29.D][1]
+2e869b4d|	plan9	ST1 (R17)(R27), [V14.D][1]
+1e87000c|	plan9	VST2 (R24), [V30.H4, V31.H4]
+07829f0c|	plan9	VST2 16(R16), [V7.B8, V8.B8]
+d38a884c|	plan9	VST2 (R22)(R8), [V19.S4, V20.S4]
+541c204d|	plan9	ST2 (R2), [V20.B, V21.B][15]
+9180200d|	plan9	ST2 (R4), [V17.S, V18.S][0]
+2585204d|	plan9	ST2 (R9), [V5.D, V6.D][1]
+2f06bf4d|	plan9	ST2 2(R17), [V15.B, V16.B][9]
+3b08b44d|	plan9	ST2 (R1)(R20), [V27.B, V28.B][10]
+805bbf0d|	plan9	ST2 4(R28), [V0.H, V1.H][3]
+fb80bf0d|	plan9	ST2 8(R7), [V27.S, V28.S][0]
+6290a80d|	plan9	ST2 (R3)(R8), [V2.S, V3.S][1]
+b587bf4d|	plan9	ST2 16(R29), [V21.D, V22.D][1]
+2c84b64d|	plan9	ST2 (R1)(R22), [V12.D, V13.D][1]
+22469f0c|	plan9	VST3 24(R17), [V2.H4, V3.H4, V4.H4]
+0e30004d|	plan9	ST3 (R0), [V14.B, V15.B, V16.B][12]
+62a1004d|	plan9	ST3 (R11), [V2.S, V3.S, V4.S][2]
+54a4000d|	plan9	ST3 (R2), [V20.D, V21.D, V22.D][0]
+84259f4d|	plan9	ST3 3(R12), [V4.B, V5.B, V6.B][9]
+693c9d4d|	plan9	ST3 (R3)(R29), [V9.B, V10.B, V11.B][15]
+5b709f0d|	plan9	ST3 6(R2), [V27.H, V28.H, V29.H][2]
+e47a960d|	plan9	ST3 (R23)(R22), [V4.H, V5.H, V6.H][3]
+a0a39f0d|	plan9	ST3 12(R29), [V0.S, V1.S, V2.S][0]
+37b0890d|	plan9	ST3 (R1)(R9), [V23.S, V24.S, V25.S][1]
+9aa59f4d|	plan9	ST3 24(R12), [V26.D, V27.D, V28.D][1]
+26a5924d|	plan9	ST3 (R9)(R18), [V6.D, V7.D, V8.D][1]
+3e05000c|	plan9	VST4 (R9), [V30.H4, V31.H4, V0.H4, V1.H4]
+a8039f0c|	plan9	VST4 32(R29), [V8.B8, V9.B8, V10.B8, V11.B8]
+4126204d|	plan9	ST4 (R18), [V1.B, V2.B, V3.B, V4.B][9]
+3b71204d|	plan9	ST4 (R9), [V27.H, V28.H, V29.H, V30.H][6]
+f2b3204d|	plan9	ST4 (RSP), [V18.S, V19.S, V20.S, V21.S][3]
+7fa4200d|	plan9	ST4 (R3), [V31.D, V0.D, V1.D, V2.D][0]
+562ebf4d|	plan9	ST4 4(R18), [V22.B, V23.B, V24.B, V25.B][11]
+563cae0d|	plan9	ST4 (R2)(R14), [V22.B, V23.B, V24.B, V25.B][7]
+1271bf4d|	plan9	ST4 8(R8), [V18.H, V19.H, V20.H, V21.H][6]
+e7a1bf0d|	plan9	ST4 16(R15), [V7.S, V8.S, V9.S, V10.S][0]
+f3b2a30d|	plan9	ST4 (R23)(R3), [V19.S, V20.S, V21.S, V22.S][1]
+eca5bf4d|	plan9	ST4 32(R15), [V12.D, V13.D, V14.D, V15.D][1]
+4ca7bb0d|	plan9	ST4 (R26)(R27), [V12.D, V13.D, V14.D, V15.D][0]
+4f5b182c|	plan9	STNP 192(R26), F22, F15
+e05e0b6c|	plan9	STNP 176(R23), F23, F0
+77be2eac|	plan9	STNP -560(R19), V15, V23
+bb3fa72c|	plan9	STP.P (F27, F15), -200(R29)
+ef18bb6c|	plan9	STP.P (F15, F6), -80(R7)
+777d84ac|	plan9	STP.P (V23, V31), 128(R11)
+d0f9952d|	plan9	STP.W (F16, F30), 172(R14)
+125ca26d|	plan9	STP.W (F18, F23), -480(R0)
+33bbbfad|	plan9	STP.W (V19, V14), -16(R25)
+6ebb322d|	plan9	STP (F14, F14), -108(R27)
+cb92096d|	plan9	STP (F11, F4), 152(R22)
+f2871dad|	plan9	STP (V18, V1), 944(RSP)
+f676003c|	plan9	MOVD.P F22, 7(R23)
+50f50d7c|	plan9	MOVD.P F16, 223(R10)
+0d251ebc|	plan9	MOVD.P F13, -30(R8)
+1f3510fc|	plan9	MOVD.P F31, -253(R8)
+05a4883c|	plan9	MOVD.P V5, 138(R0)
+800e063c|	plan9	MOVD.W F0, 96(R20)
+668d157c|	plan9	MOVD.W F6, -168(R11)
+1f3d11bc|	plan9	MOVD.W F31, -237(R8)
+71bf06fc|	plan9	MOVD.W F17, 107(R27)
+f50c843c|	plan9	MOVD.W V21, 64(R7)
+f186013d|	plan9	MOVD F17, 97(R23)
+f0e5357d|	plan9	MOVD F16, 6898(R15)
+938d3bbd|	plan9	MOVD F19, 15244(R12)
+aeb813fd|	plan9	MOVD F14, 10096(R5)
+2cc4943d|	plan9	MOVD V12, 21264(R1)
+1d79373c|	plan9	MOVD F29, R23<<1(R8)
+bc70003c|	plan9	MOVD F28, 7(R5)
+7190157c|	plan9	MOVD F17, -167(R3)
+073309bc|	plan9	MOVD F7, 147(R24)
+298100fc|	plan9	MOVD F9, 8(R9)
+e8c1843c|	plan9	MOVD V8, 76(R15)
+3384266e|	plan9	VSUB V6.B16, V1.B16, V19.B16
+9163750e|	plan9	VSUBHN V21.S4, V28.S4, V17.H4
+f3627d4e|	plan9	VSUBHN2 V29.S4, V23.S4, V19.H8
+1939205e|	plan9	SUQADD F8, F25
+0638604e|	plan9	VSUQADD V0.H8, V6.H8
+81a4284f|	plan9	VSSHLL2 $8, V4.S4, V1.D2
+f920030e|	plan9	VTBL V3.B8, [V7.B16, V8.B16], V25.B8
+71400e4e|	plan9	VTBL V14.B16, [V3.B16, V4.B16, V5.B16], V17.B16
+bc630d4e|	plan9	VTBL V13.B16, [V29.B16, V30.B16, V31.B16, V0.B16], V28.B16
+6803030e|	plan9	VTBL V3.B8, [V27.B16], V8.B8
+4b32124e|	plan9	VTBX V18.B16, [V18.B16, V19.B16], V11.B16
+8f50170e|	plan9	VTBX V23.B8, [V4.B16, V5.B16, V6.B16], V15.B8
+5673020e|	plan9	VTBX V2.B8, [V26.B16, V27.B16, V28.B16, V29.B16], V22.B8
+f2130f4e|	plan9	VTBX V15.B16, [V31.B16], V18.B16
+9e29c34e|	plan9	VTRN1 V3.D2, V12.D2, V30.D2
+9b6bcf4e|	plan9	VTRN2 V15.D2, V28.D2, V27.D2
+157cb02e|	plan9	VUABA V16.S2, V0.S2, V21.S2
+28513c2e|	plan9	VUABAL V28.B8, V9.B8, V8.H8
+f950a26e|	plan9	VUABAL2 V2.S4, V7.S4, V25.D2
+a776b26e|	plan9	VUABD V18.S4, V21.S4, V7.S4
+da726b2e|	plan9	VUABDL V11.H4, V22.H4, V26.S4
+9473746e|	plan9	VUABDL2 V20.H8, V28.H8, V20.S4
+aa6b602e|	plan9	VUADALP V29.H4, V10.S2
+ac013d2e|	plan9	VUADDL V29.B8, V13.B8, V12.H8
+e500a86e|	plan9	VUADDL2 V8.S4, V7.S4, V5.D2
+9c28a02e|	plan9	VUADDLP V4.S2, V28.D1
+4c3a302e|	plan9	UADDLV V18.B8, F12
+2810b62e|	plan9	VUADDW V22.S2, V1.D2, V8.D2
+f2132d6e|	plan9	VUADDW2 V13.B16, V31.H8, V18.H8
+b3e67f7f|	plan9	UCVTF $1, F21, F19
+ece5676f|	plan9	UCVTF $25, V15.D2, V12.D2
+d7d8217e|	plan9	UCVTFSS F6, F23
+cdd9212e|	plan9	UCVTF V14.S2, V13.S2
+5788031e|	plan9	UCVTF $30, R2, F23
+c7ac431e|	plan9	UCVTF $21, R6, F7
+0777039e|	plan9	UCVTF $35, R24, F7
+e4f4439e|	plan9	UCVTF $3, R7, F4
+9100231e|	plan9	UCVTFWS R4, F17
+e202631e|	plan9	UCVTFWD R23, F2
+3903239e|	plan9	UCVTFS R25, F25
+2001639e|	plan9	UCVTFD R9, F0
+2a07b76e|	plan9	VUHADD V23.S4, V25.S4, V10.S4
+dc25372e|	plan9	VUHSUB V23.B8, V14.B8, V28.B8
+de646f2e|	plan9	VUMAX V15.H4, V6.H4, V30.H4
+4ba6766e|	plan9	VUMAXP V22.H8, V18.H8, V11.H8
+e26db42e|	plan9	VUMIN V20.S2, V15.S2, V2.S2
+a7ae712e|	plan9	VUMINP V17.H4, V21.H4, V7.H4
+afaa716e|	plan9	UMINV V21.H8, F15
+42298c2f|	plan9	VUMLAL V12.S[2], V10.S2, V2.D2
+0a826e2e|	plan9	VUMLAL V14.H4, V16.H4, V10.S4
+2681a06e|	plan9	VUMLAL2 V0.S4, V9.S4, V6.D2
+2860bd6f|	plan9	VUMLSL2 V29.S[1], V1.S4, V8.D2
+19a26b6e|	plan9	VUMLSL2 V11.H8, V16.H8, V25.S4
+8a3d140e|	plan9	VMOV V12.S[2], R10
+22a1ba6f|	plan9	VUMULL2 V26.S[1], V9.S4, V2.D2
+15c0712e|	plan9	VUMULL V17.H4, V0.H4, V21.S4
+2ec0296e|	plan9	VUMULL2 V9.B16, V1.B16, V14.H8
+6e0fba7e|	plan9	UQADD F26, F27, F14
+db0fe06e|	plan9	VUQADD V0.D2, V30.D2, V27.D2
+535e6c7e|	plan9	UQRSHL F12, F18, F19
+7c5cfe6e|	plan9	VUQRSHL V30.D2, V3.D2, V28.D2
+9a9e327f|	plan9	UQRSHRN $14, F20, F26
+339f0b2f|	plan9	VUQRSHRN $5, V25.H8, V19.B8
+7e77337f|	plan9	UQSHL $19, F27, F30
+8b4d657e|	plan9	UQSHL F5, F12, F11
+414c622e|	plan9	VUQSHL V2.H4, V2.H4, V1.H4
+95942b2f|	plan9	VUQSHRN $21, V4.D2, V21.S2
+d396246f|	plan9	VUQSHRN2 $28, V22.D2, V19.S4
+b22ff27e|	plan9	UQSUB F18, F29, F18
+b32e756e|	plan9	VUQSUB V21.H8, V21.H8, V19.H8
+0e4b616e|	plan9	VUQXTN2 V24.S4, V14.H8
+ca16236e|	plan9	VURHADD V3.B16, V22.B16, V10.B16
+1f57a26e|	plan9	VURSHL V2.S4, V24.S4, V31.S4
+8324777f|	plan9	URSHR $9, F4, F3
+37caa16e|	plan9	VURSQRTE V17.S4, V23.S4
+b735517f|	plan9	URSRA $47, F13, F23
+0a47f67e|	plan9	USHL F22, F24, F10
+e7a71c2f|	plan9	VUSHLL $12, V31.H4, V7.S4
+9c38607e|	plan9	USQADD F4, F28
+dc39206e|	plan9	VUSQADD V14.B16, V28.B16
+dc145d7f|	plan9	USRA $35, F6, F28
+d720752e|	plan9	VUSUBL V21.H4, V6.H4, V23.S4
+2c236f6e|	plan9	VUSUBL2 V15.H8, V25.H8, V12.S4
+ed32222e|	plan9	VUSUBW V2.B8, V23.H8, V13.H8
+72332d6e|	plan9	VUSUBW2 V13.B16, V27.H8, V18.H8
+655a1c4e|	plan9	VUZP2 V28.B16, V19.B16, V5.B16
+972a210e|	plan9	VXTN V20.H8, V23.B8
+5f2aa14e|	plan9	VXTN2 V18.D2, V31.S4
+9a38910e|	plan9	VZIP1 V17.S2, V4.S2, V26.S2
+d979990e|	plan9	VZIP2 V25.S2, V14.S2, V25.S2
+41e5a454|	plan9	BNE -186582(PC)
+ea1b543a|	plan9	CCMNW NE, ZR, $20, $10
+681946ba|	plan9	CCMN NE, R11, $6, $8
+2410463a|	plan9	CCMNW NE, R1, R6, $4
+6e134cba|	plan9	CCMN NE, R27, R12, $14
+ad194f7a|	plan9	CCMPW NE, R13, $15, $13
+471b53fa|	plan9	CCMP NE, R26, $19, $7
+a210467a|	plan9	CCMPW NE, R5, R6, $2
+ee1246fa|	plan9	CCMP NE, R23, R6, $14
+be149b1a|	plan9	CSINCW NE, R5, R27, R30
+c415819a|	plan9	CSINC NE, R14, R1, R4
+0510955a|	plan9	CSINVW NE, R0, R21, R5
+c51093da|	plan9	CSINV NE, R6, R19, R5
+12158e5a|	plan9	CSNEGW NE, R8, R14, R18
+5c159cda|	plan9	CSNEG NE, R10, R28, R28
+c810941a|	plan9	CSELW NE, R6, R20, R8
+80128c9a|	plan9	CSEL NE, R20, R12, R0
+f6179f1a|	plan9	CSETW EQ, R22
+f5179f9a|	plan9	CSET EQ, R21
+ec139f5a|	plan9	CSETMW EQ, R12
+ee139fda|	plan9	CSETM EQ, R14
+4b17981a|	plan9	CSINCW NE, R26, R24, R11
+b515909a|	plan9	CSINC NE, R13, R16, R21
+b613955a|	plan9	CSINVW NE, R29, R21, R22
+f8108bda|	plan9	CSINV NE, R7, R11, R24
+a0149d5a|	plan9	CSNEGW NE, R5, R29, R0
+6a1492da|	plan9	CSNEG NE, R3, R18, R10
+8f143c1e|	plan9	FCCMPS NE, F28, F4, $15
+0f167f1e|	plan9	FCCMPD NE, F31, F16, $15
+5214291e|	plan9	FCCMPES NE, F9, F2, $2
+1516631e|	plan9	FCCMPED NE, F3, F16, $5
+2b1d271e|	plan9	FCSELS NE, F9, F7, F11
+731e611e|	plan9	FCSELD NE, F19, F1, F19
+c2560e54|	plan9	BCS 29366(PC)
+2d2b563a|	plan9	CCMNW HS, R25, $22, $13
+6c2b55ba|	plan9	CCMN HS, R27, $21, $12
+2521493a|	plan9	CCMNW HS, R9, R9, $5
+032040ba|	plan9	CCMN HS, R0, R0, $3
+ea2a5c7a|	plan9	CCMPW HS, R23, $28, $10
+8e2842fa|	plan9	CCMP HS, R4, $2, $14
+8e22427a|	plan9	CCMPW HS, R20, R2, $14
+cd204dfa|	plan9	CCMP HS, R6, R13, $13
+2824931a|	plan9	CSINCW HS, R1, R19, R8
+a3279a9a|	plan9	CSINC HS, R29, R26, R3
+5921945a|	plan9	CSINVW HS, R10, R20, R25
+bd2386da|	plan9	CSINV HS, R29, R6, R29
+a124915a|	plan9	CSNEGW HS, R5, R17, R1
+5b2787da|	plan9	CSNEG HS, R26, R7, R27
+91209f1a|	plan9	CSELW HS, R4, ZR, R17
+f921979a|	plan9	CSEL HS, R15, R23, R25
+e4279f1a|	plan9	CSETW LO, R4
+ea279f9a|	plan9	CSET LO, R10
+fe239f5a|	plan9	CSETMW LO, R30
+ec239fda|	plan9	CSETM LO, R12
+ee25971a|	plan9	CSINCW HS, R15, R23, R14
+b726859a|	plan9	CSINC HS, R21, R5, R23
+4b22845a|	plan9	CSINVW HS, R18, R4, R11
+2b209eda|	plan9	CSINV HS, R1, R30, R11
+6b269b5a|	plan9	CSNEGW HS, R19, R27, R11
+192691da|	plan9	CSNEG HS, R16, R17, R25
+0226391e|	plan9	FCCMPS HS, F25, F16, $2
+07246d1e|	plan9	FCCMPD HS, F13, F0, $7
+9626241e|	plan9	FCCMPES HS, F4, F20, $6
+de27601e|	plan9	FCCMPED HS, F0, F30, $14
+7d2d271e|	plan9	FCSELS HS, F11, F7, F29
+3e2e7a1e|	plan9	FCSELD HS, F17, F26, F30
+43a4df54|	plan9	BCC -66270(PC)
+0739533a|	plan9	CCMNW LO, R8, $19, $7
+673b4fba|	plan9	CCMN LO, R27, $15, $7
+e333583a|	plan9	CCMNW LO, ZR, R24, $3
+83325aba|	plan9	CCMN LO, R20, R26, $3
+eb38517a|	plan9	CCMPW LO, R7, $17, $11
+2c3955fa|	plan9	CCMP LO, R9, $21, $12
+6f324b7a|	plan9	CCMPW LO, R19, R11, $15
+09314ffa|	plan9	CCMP LO, R8, R15, $9
+60349c1a|	plan9	CSINCW LO, R3, R28, R0
+8835949a|	plan9	CSINC LO, R12, R20, R8
+bb31935a|	plan9	CSINVW LO, R13, R19, R27
+9f319dda|	plan9	CSINV LO, R12, R29, ZR
+8837855a|	plan9	CSNEGW LO, R28, R5, R8
+cd3490da|	plan9	CSNEG LO, R6, R16, R13
+b033901a|	plan9	CSELW LO, R29, R16, R16
+5e31969a|	plan9	CSEL LO, R10, R22, R30
+ec379f1a|	plan9	CSETW HS, R12
+ea379f9a|	plan9	CSET HS, R10
+eb339f5a|	plan9	CSETMW HS, R11
+fd339fda|	plan9	CSETM HS, R29
+9934941a|	plan9	CSINCW LO, R4, R20, R25
+fa36829a|	plan9	CSINC LO, R23, R2, R26
+2730895a|	plan9	CSINVW LO, R1, R9, R7
+703094da|	plan9	CSINV LO, R3, R20, R16
+f636935a|	plan9	CSNEGW LO, R23, R19, R22
+ba3484da|	plan9	CSNEG LO, R5, R4, R26
+e3343e1e|	plan9	FCCMPS LO, F30, F7, $3
+ce366a1e|	plan9	FCCMPD LO, F10, F22, $14
+de37271e|	plan9	FCCMPES LO, F7, F30, $14
+1935751e|	plan9	FCCMPED LO, F21, F8, $9
+603f241e|	plan9	FCSELS LO, F27, F4, F0
+653f761e|	plan9	FCSELD LO, F27, F22, F5
+a4fa5354|	plan9	BMI 171989(PC)
+a248483a|	plan9	CCMNW MI, R5, $8, $2
+e2484eba|	plan9	CCMN MI, R7, $14, $2
+2841553a|	plan9	CCMNW MI, R9, R21, $8
+6e4259ba|	plan9	CCMN MI, R19, R25, $14
+2048567a|	plan9	CCMPW MI, R1, $22, $0
+454a5afa|	plan9	CCMP MI, R18, $26, $5
+0343487a|	plan9	CCMPW MI, R24, R8, $3
+49434bfa|	plan9	CCMP MI, R26, R11, $9
+d747991a|	plan9	CSINCW MI, R30, R25, R23
+9544919a|	plan9	CSINC MI, R4, R17, R21
+76428c5a|	plan9	CSINVW MI, R19, R12, R22
+06418eda|	plan9	CSINV MI, R8, R14, R6
+4d46975a|	plan9	CSNEGW MI, R18, R23, R13
+d74491da|	plan9	CSNEG MI, R6, R17, R23
+0941941a|	plan9	CSELW MI, R8, R20, R9
+2d41839a|	plan9	CSEL MI, R9, R3, R13
+ef479f1a|	plan9	CSETW PL, R15
+e5479f9a|	plan9	CSET PL, R5
+f0439f5a|	plan9	CSETMW PL, R16
+e2439fda|	plan9	CSETM PL, R2
+2a46841a|	plan9	CSINCW MI, R17, R4, R10
+f1468b9a|	plan9	CSINC MI, R23, R11, R17
+3441835a|	plan9	CSINVW MI, R9, R3, R20
+b5438cda|	plan9	CSINV MI, R29, R12, R21
+ad45945a|	plan9	CSNEGW MI, R13, R20, R13
+f54793da|	plan9	CSNEG MI, ZR, R19, R21
+c5473f1e|	plan9	FCCMPS MI, F31, F30, $5
+8947601e|	plan9	FCCMPD MI, F0, F28, $9
+5247331e|	plan9	FCCMPES MI, F19, F26, $2
+b045761e|	plan9	FCCMPED MI, F22, F13, $0
+b34d331e|	plan9	FCSELS MI, F13, F19, F19
+3a4d6d1e|	plan9	FCSELD MI, F9, F13, F26
+a5497054|	plan9	BPL 229965(PC)
+eb5a493a|	plan9	CCMNW PL, R23, $9, $11
+0a5941ba|	plan9	CCMN PL, R8, $1, $10
+0452523a|	plan9	CCMNW PL, R16, R18, $4
+e55053ba|	plan9	CCMN PL, R7, R19, $5
+a45b407a|	plan9	CCMPW PL, R29, $0, $4
+ca5b4efa|	plan9	CCMP PL, R30, $14, $10
+ab514e7a|	plan9	CCMPW PL, R13, R14, $11
+ce5349fa|	plan9	CCMP PL, R30, R9, $14
+8555971a|	plan9	CSINCW PL, R12, R23, R5
+4b569e9a|	plan9	CSINC PL, R18, R30, R11
+90538f5a|	plan9	CSINVW PL, R28, R15, R16
+c3508bda|	plan9	CSINV PL, R6, R11, R3
+1f55955a|	plan9	CSNEGW PL, R8, R21, ZR
+52568eda|	plan9	CSNEG PL, R18, R14, R18
+a750851a|	plan9	CSELW PL, R5, R5, R7
+b252899a|	plan9	CSEL PL, R21, R9, R18
+eb579f1a|	plan9	CSETW MI, R11
+e6579f9a|	plan9	CSET MI, R6
+fd539f5a|	plan9	CSETMW MI, R29
+e1539fda|	plan9	CSETM MI, R1
+33579e1a|	plan9	CSINCW PL, R25, R30, R19
+b5558c9a|	plan9	CSINC PL, R13, R12, R21
+ec53885a|	plan9	CSINVW PL, ZR, R8, R12
+ec5196da|	plan9	CSINV PL, R15, R22, R12
+ae57945a|	plan9	CSNEGW PL, R29, R20, R14
+64578bda|	plan9	CSNEG PL, R27, R11, R4
+2657241e|	plan9	FCCMPS PL, F4, F25, $6
+2357761e|	plan9	FCCMPD PL, F22, F25, $3
+f255361e|	plan9	FCCMPES PL, F22, F15, $2
+3756781e|	plan9	FCCMPED PL, F24, F17, $7
+985c3f1e|	plan9	FCSELS PL, F4, F31, F24
+5b5d621e|	plan9	FCSELD PL, F10, F2, F27
+c6d26454|	plan9	BVS 206486(PC)
+6c6a4f3a|	plan9	CCMNW VS, R19, $15, $12
+2f694cba|	plan9	CCMN VS, R9, $12, $15
+e962583a|	plan9	CCMNW VS, R23, R24, $9
+80615fba|	plan9	CCMN VS, R12, ZR, $0
+4b6b497a|	plan9	CCMPW VS, R26, $9, $11
+cc6a48fa|	plan9	CCMP VS, R22, $8, $12
+4e61567a|	plan9	CCMPW VS, R10, R22, $14
+476054fa|	plan9	CCMP VS, R2, R20, $7
+c965911a|	plan9	CSINCW VS, R14, R17, R9
+41668f9a|	plan9	CSINC VS, R18, R15, R1
+db608f5a|	plan9	CSINVW VS, R6, R15, R27
+896097da|	plan9	CSINV VS, R4, R23, R9
+1867915a|	plan9	CSNEGW VS, R24, R17, R24
+49678eda|	plan9	CSNEG VS, R26, R14, R9
+3162881a|	plan9	CSELW VS, R17, R8, R17
+db608f9a|	plan9	CSEL VS, R6, R15, R27
+f9679f1a|	plan9	CSETW VC, R25
+f9679f9a|	plan9	CSET VC, R25
+f7639f5a|	plan9	CSETMW VC, R23
+e1639fda|	plan9	CSETM VC, R1
+f4678a1a|	plan9	CSINCW VS, ZR, R10, R20
+3e65879a|	plan9	CSINC VS, R9, R7, R30
+6c63975a|	plan9	CSINVW VS, R27, R23, R12
+806191da|	plan9	CSINV VS, R12, R17, R0
+7f679f5a|	plan9	CSNEGW VS, R27, ZR, ZR
+3b6488da|	plan9	CSNEG VS, R1, R8, R27
+0565301e|	plan9	FCCMPS VS, F16, F8, $5
+e266621e|	plan9	FCCMPD VS, F2, F23, $2
+b7653a1e|	plan9	FCCMPES VS, F26, F13, $7
+d866791e|	plan9	FCCMPED VS, F25, F22, $8
+326d3d1e|	plan9	FCSELS VS, F9, F29, F18
+f66e7b1e|	plan9	FCSELD VS, F23, F27, F22
+e774fd54|	plan9	BVC -5209(PC)
+0479483a|	plan9	CCMNW VC, R8, $8, $4
+897b56ba|	plan9	CCMN VC, R28, $22, $9
+8b70513a|	plan9	CCMNW VC, R4, R17, $11
+ca7150ba|	plan9	CCMN VC, R14, R16, $10
+46794f7a|	plan9	CCMPW VC, R10, $15, $6
+057948fa|	plan9	CCMP VC, R8, $8, $5
+0373417a|	plan9	CCMPW VC, R24, R1, $3
+ca705ffa|	plan9	CCMP VC, R6, ZR, $10
+d3769f1a|	plan9	CSINCW VC, R22, ZR, R19
+1076899a|	plan9	CSINC VC, R16, R9, R16
+c8718e5a|	plan9	CINVW VS, R14, R8
+06729eda|	plan9	CSINV VC, R16, R30, R6
+6076895a|	plan9	CSNEGW VC, R19, R9, R0
+b87589da|	plan9	CSNEG VC, R13, R9, R24
+3b72891a|	plan9	CSELW VC, R17, R9, R27
+fd70899a|	plan9	CSEL VC, R7, R9, R29
+e3779f1a|	plan9	CSETW VS, R3
+f4779f9a|	plan9	CSET VS, R20
+fc739f5a|	plan9	CSETMW VS, R28
+ea739fda|	plan9	CSETM VS, R10
+ab75891a|	plan9	CSINCW VC, R13, R9, R11
+6177859a|	plan9	CSINC VC, R27, R5, R1
+3272945a|	plan9	CSINVW VC, R17, R20, R18
+7a729dda|	plan9	CSINV VC, R19, R29, R26
+b5779e5a|	plan9	CSNEGW VC, R29, R30, R21
+fe748eda|	plan9	CSNEG VC, R7, R14, R30
+ed76231e|	plan9	FCCMPS VC, F3, F23, $13
+cf74791e|	plan9	FCCMPD VC, F25, F6, $15
+b4763e1e|	plan9	FCCMPES VC, F30, F21, $4
+59766e1e|	plan9	FCCMPED VC, F14, F18, $9
+ce7c271e|	plan9	FCSELS VC, F6, F7, F14
+be7c651e|	plan9	FCSELD VC, F5, F5, F30
+88f29d54|	plan9	BHI -200812(PC)
+8f8b513a|	plan9	CCMNW HI, R28, $17, $15
+6f8b5cba|	plan9	CCMN HI, R27, $28, $15
+8780463a|	plan9	CCMNW HI, R4, R6, $7
+4f8348ba|	plan9	CCMN HI, R26, R8, $15
+48884d7a|	plan9	CCMPW HI, R2, $13, $8
+088957fa|	plan9	CCMP HI, R8, $23, $8
+0180517a|	plan9	CCMPW HI, R0, R17, $1
+ce805efa|	plan9	CCMP HI, R6, R30, $14
+1d868e1a|	plan9	CSINCW HI, R16, R14, R29
+0785889a|	plan9	CINC LS, R8, R7
+4782935a|	plan9	CSINVW HI, R18, R19, R7
+118197da|	plan9	CSINV HI, R8, R23, R17
+00868a5a|	plan9	CSNEGW HI, R16, R10, R0
+128585da|	plan9	CSNEG HI, R8, R5, R18
+4c808f1a|	plan9	CSELW HI, R2, R15, R12
+7783909a|	plan9	CSEL HI, R27, R16, R23
+e5879f1a|	plan9	CSETW LS, R5
+f3879f9a|	plan9	CSET LS, R19
+f9839f5a|	plan9	CSETMW LS, R25
+eb839fda|	plan9	CSETM LS, R11
+b3869e1a|	plan9	CSINCW HI, R21, R30, R19
+f086909a|	plan9	CSINC HI, R23, R16, R16
+34839c5a|	plan9	CSINVW HI, R25, R28, R20
+ea8294da|	plan9	CSINV HI, R23, R20, R10
+8e84895a|	plan9	CSNEGW HI, R4, R9, R14
+c48695da|	plan9	CSNEG HI, R22, R21, R4
+cc84361e|	plan9	FCCMPS HI, F22, F6, $12
+8086781e|	plan9	FCCMPD HI, F24, F20, $0
+7187341e|	plan9	FCCMPES HI, F20, F27, $1
+30867e1e|	plan9	FCCMPED HI, F30, F17, $0
+b98e361e|	plan9	FCSELS HI, F21, F22, F25
+2c8c651e|	plan9	FCSELD HI, F1, F5, F12
+69888c54|	plan9	BLS -236477(PC)
+0e9b523a|	plan9	CCMNW LS, R24, $18, $14
+679854ba|	plan9	CCMN LS, R3, $20, $7
+0492563a|	plan9	CCMNW LS, R16, R22, $4
+42924dba|	plan9	CCMN LS, R18, R13, $2
+2198417a|	plan9	CCMPW LS, R1, $1, $1
+c89a54fa|	plan9	CCMP LS, R22, $20, $8
+0f905e7a|	plan9	CCMPW LS, R0, R30, $15
+c59342fa|	plan9	CCMP LS, R30, R2, $5
+0d958c1a|	plan9	CSINCW LS, R8, R12, R13
+7596879a|	plan9	CSINC LS, R19, R7, R21
+1791905a|	plan9	CSINVW LS, R8, R16, R23
+5e9186da|	plan9	CSINV LS, R10, R6, R30
+23969e5a|	plan9	CSNEGW LS, R17, R30, R3
+619493da|	plan9	CSNEG LS, R3, R19, R1
+b5918e1a|	plan9	CSELW LS, R13, R14, R21
+b393819a|	plan9	CSEL LS, R29, R1, R19
+f9979f1a|	plan9	CSETW HI, R25
+ee979f9a|	plan9	CSET HI, R14
+eb939f5a|	plan9	CSETMW HI, R11
+ea939fda|	plan9	CSETM HI, R10
+f497871a|	plan9	CSINCW LS, ZR, R7, R20
+c4949d9a|	plan9	CSINC LS, R6, R29, R4
+e892895a|	plan9	CSINVW LS, R23, R9, R8
+6c908eda|	plan9	CSINV LS, R3, R14, R12
+26949f5a|	plan9	CSNEGW LS, R1, ZR, R6
+329498da|	plan9	CSNEG LS, R1, R24, R18
+81952d1e|	plan9	FCCMPS LS, F13, F12, $1
+60967f1e|	plan9	FCCMPD LS, F31, F19, $0
+1794321e|	plan9	FCCMPES LS, F18, F0, $7
+3f97641e|	plan9	FCCMPED LS, F4, F25, $15
+089c2d1e|	plan9	FCSELS LS, F0, F13, F8
+699f631e|	plan9	FCSELD LS, F27, F3, F9
+8afbfe54|	plan9	BGE -2084(PC)
+44aa573a|	plan9	CCMNW GE, R18, $23, $4
+00a84fba|	plan9	CCMN GE, R0, $15, $0
+c9a04d3a|	plan9	CCMNW GE, R6, R13, $9
+88a041ba|	plan9	CCMN GE, R4, R1, $8
+caaa467a|	plan9	CCMPW GE, R22, $6, $10
+85a85cfa|	plan9	CCMP GE, R4, $28, $5
+47a35f7a|	plan9	CCMPW GE, R26, ZR, $7
+0aa34dfa|	plan9	CCMP GE, R24, R13, $10
+dea7981a|	plan9	CSINCW GE, R30, R24, R30
+c6a5909a|	plan9	CSINC GE, R14, R16, R6
+8aa1965a|	plan9	CSINVW GE, R12, R22, R10
+e3a392da|	plan9	CSINV GE, ZR, R18, R3
+20a5845a|	plan9	CSNEGW GE, R9, R4, R0
+fba694da|	plan9	CSNEG GE, R23, R20, R27
+faa1851a|	plan9	CSELW GE, R15, R5, R26
+25a3959a|	plan9	CSEL GE, R25, R21, R5
+e2a79f1a|	plan9	CSETW LT, R2
+fda79f9a|	plan9	CSET LT, R29
+eea39f5a|	plan9	CSETMW LT, R14
+e2a39fda|	plan9	CSETM LT, R2
+efa6951a|	plan9	CSINCW GE, R23, R21, R15
+4ca69e9a|	plan9	CSINC GE, R18, R30, R12
+22a2885a|	plan9	CSINVW GE, R17, R8, R2
+53a089da|	plan9	CSINV GE, R2, R9, R19
+f9a6875a|	plan9	CSNEGW GE, R23, R7, R25
+c9a795da|	plan9	CSNEG GE, R30, R21, R9
+24a73e1e|	plan9	FCCMPS GE, F30, F25, $4
+6da5651e|	plan9	FCCMPD GE, F5, F11, $13
+bda52e1e|	plan9	FCCMPES GE, F14, F13, $13
+f6a7651e|	plan9	FCCMPED GE, F5, F31, $6
+e3ac251e|	plan9	FCSELS GE, F7, F5, F3
+b3ae781e|	plan9	FCSELD GE, F21, F24, F19
+ab621754|	plan9	BLT 47893(PC)
+e1b84c3a|	plan9	CCMNW LT, R7, $12, $1
+89ba4eba|	plan9	CCMN LT, R20, $14, $9
+88b14a3a|	plan9	CCMNW LT, R12, R10, $8
+89b145ba|	plan9	CCMN LT, R12, R5, $9
+47b9547a|	plan9	CCMPW LT, R10, $20, $7
+07b95bfa|	plan9	CCMP LT, R8, $27, $7
+4ab2407a|	plan9	CCMPW LT, R18, R0, $10
+8ab144fa|	plan9	CCMP LT, R12, R4, $10
+79b5821a|	plan9	CSINCW LT, R11, R2, R25
+8bb4919a|	plan9	CSINC LT, R4, R17, R11
+c9b19f5a|	plan9	CSINVW LT, R14, ZR, R9
+10b28bda|	plan9	CSINV LT, R16, R11, R16
+d8b4925a|	plan9	CSNEGW LT, R6, R18, R24
+3ab69fda|	plan9	CSNEG LT, R17, ZR, R26
+2cb3841a|	plan9	CSELW LT, R25, R4, R12
+77b0969a|	plan9	CSEL LT, R3, R22, R23
+e2b79f1a|	plan9	CSETW GE, R2
+e9b79f9a|	plan9	CSET GE, R9
+f4b39f5a|	plan9	CSETMW GE, R20
+f2b39fda|	plan9	CSETM GE, R18
+87b59a1a|	plan9	CSINCW LT, R12, R26, R7
+70b69c9a|	plan9	CSINC LT, R19, R28, R16
+17b08f5a|	plan9	CSINVW LT, R0, R15, R23
+cab288da|	plan9	CSINV LT, R22, R8, R10
+bab7905a|	plan9	CSNEGW LT, R29, R16, R26
+08b796da|	plan9	CSNEG LT, R24, R22, R8
+2eb73e1e|	plan9	FCCMPS LT, F30, F25, $14
+86b7671e|	plan9	FCCMPD LT, F7, F28, $6
+f0b6211e|	plan9	FCCMPES LT, F1, F23, $0
+b2b76b1e|	plan9	FCCMPED LT, F11, F29, $2
+e8bf241e|	plan9	FCSELS LT, F31, F4, F8
+9ebd7d1e|	plan9	FCSELD LT, F12, F29, F30
+cc87d354|	plan9	BGT -91074(PC)
+43c8563a|	plan9	CCMNW GT, R2, $22, $3
+c5c94dba|	plan9	CCMN GT, R14, $13, $5
+6fc0533a|	plan9	CCMNW GT, R3, R19, $15
+06c351ba|	plan9	CCMN GT, R24, R17, $6
+c3c95c7a|	plan9	CCMPW GT, R14, $28, $3
+29cb52fa|	plan9	CCMP GT, R25, $18, $9
+8bc25a7a|	plan9	CCMPW GT, R20, R26, $11
+45c14dfa|	plan9	CCMP GT, R10, R13, $5
+80c7841a|	plan9	CSINCW GT, R28, R4, R0
+40c4919a|	plan9	CSINC GT, R2, R17, R0
+04c2805a|	plan9	CSINVW GT, R16, R0, R4
+55c086da|	plan9	CSINV GT, R2, R6, R21
+32c7935a|	plan9	CSNEGW GT, R25, R19, R18
+31c59fda|	plan9	CSNEG GT, R9, ZR, R17
+6cc2921a|	plan9	CSELW GT, R19, R18, R12
+37c08d9a|	plan9	CSEL GT, R1, R13, R23
+eec79f1a|	plan9	CSETW LE, R14
+eec79f9a|	plan9	CSET LE, R14
+f4c39f5a|	plan9	CSETMW LE, R20
+f6c39fda|	plan9	CSETM LE, R22
+31c5971a|	plan9	CSINCW GT, R9, R23, R17
+76c7899a|	plan9	CSINC GT, R27, R9, R22
+bbc1805a|	plan9	CSINVW GT, R13, R0, R27
+e8c384da|	plan9	CSINV GT, ZR, R4, R8
+83c5955a|	plan9	CSNEGW GT, R12, R21, R3
+77c790da|	plan9	CSNEG GT, R27, R16, R23
+e9c5251e|	plan9	FCCMPS GT, F5, F15, $9
+a3c4671e|	plan9	FCCMPD GT, F7, F5, $3
+71c72e1e|	plan9	FCCMPES GT, F14, F27, $1
+3dc4781e|	plan9	FCCMPED GT, F24, F1, $13
+57cf3d1e|	plan9	FCSELS GT, F26, F29, F23
+8fcc7e1e|	plan9	FCSELD GT, F4, F30, F15
+8d1ec054|	plan9	BLE -130828(PC)
+4bdb5b3a|	plan9	CCMNW LE, R26, $27, $11
+47d94fba|	plan9	CCMN LE, R10, $15, $7
+4dd1443a|	plan9	CCMNW LE, R10, R4, $13
+82d353ba|	plan9	CCMN LE, R28, R19, $2
+e8d9527a|	plan9	CCMPW LE, R15, $18, $8
+00db45fa|	plan9	CCMP LE, R24, $5, $0
+c5d1437a|	plan9	CCMPW LE, R14, R3, $5
+e4d041fa|	plan9	CCMP LE, R7, R1, $4
+0bd6941a|	plan9	CSINCW LE, R16, R20, R11
+57d6929a|	plan9	CINC GT, R18, R23
+3dd29a5a|	plan9	CSINVW LE, R17, R26, R29
+ded085da|	plan9	CSINV LE, R6, R5, R30
+27d5985a|	plan9	CSNEGW LE, R9, R24, R7
+7fd59ada|	plan9	CSNEG LE, R11, R26, ZR
+b7d0911a|	plan9	CSELW LE, R5, R17, R23
+a4d3879a|	plan9	CSEL LE, R29, R7, R4
+e6d79f1a|	plan9	CSETW GT, R6
+f1d79f9a|	plan9	CSET GT, R17
+f3d39f5a|	plan9	CSETMW GT, R19
+f9d39fda|	plan9	CSETM GT, R25
+42d78d1a|	plan9	CSINCW LE, R26, R13, R2
+88d58a9a|	plan9	CSINC LE, R12, R10, R8
+ccd3805a|	plan9	CSINVW LE, R30, R0, R12
+0fd085da|	plan9	CSINV LE, R0, R5, R15
+55d5975a|	plan9	CSNEGW LE, R10, R23, R21
+3fd699da|	plan9	CSNEG LE, R17, R25, ZR
+60d4251e|	plan9	FCCMPS LE, F5, F3, $0
+6dd6601e|	plan9	FCCMPD LE, F0, F19, $13
+bdd5221e|	plan9	FCCMPES LE, F2, F13, $13
+f4d67d1e|	plan9	FCCMPED LE, F29, F23, $4
+0cdd381e|	plan9	FCSELS LE, F8, F24, F12
+70de7e1e|	plan9	FCSELD LE, F19, F30, F16
+8e585454|	plan9	BAL 172740(PC)
+41eb483a|	plan9	CCMNW AL, R26, $8, $1
+8aeb42ba|	plan9	CCMN AL, R28, $2, $10
+c8e3473a|	plan9	CCMNW AL, R30, R7, $8
+ade059ba|	plan9	CCMN AL, R5, R25, $13
+67eb5b7a|	plan9	CCMPW AL, R27, $27, $7
+05e849fa|	plan9	CCMP AL, R0, $9, $5
+42e3407a|	plan9	CCMPW AL, R26, R0, $2
+03e053fa|	plan9	CCMP AL, R0, R19, $3
+9ce4931a|	plan9	CSINCW AL, R4, R19, R28
+8ee69d9a|	plan9	CSINC AL, R20, R29, R14
+68e0835a|	plan9	CSINVW AL, R3, R3, R8
+20e381da|	plan9	CSINV AL, R25, R1, R0
+e0e58d5a|	plan9	CSNEGW AL, R15, R13, R0
+9ae589da|	plan9	CSNEG AL, R12, R9, R26
+6ee0941a|	plan9	CSELW AL, R3, R20, R14
+77e38a9a|	plan9	CSEL AL, R27, R10, R23
+efe79f1a|	plan9	CSINCW AL, ZR, ZR, R15
+e5e79f9a|	plan9	CSINC AL, ZR, ZR, R5
+f2e39f5a|	plan9	CSINVW AL, ZR, ZR, R18
+fae39fda|	plan9	CSINV AL, ZR, ZR, R26
+ede7861a|	plan9	CSINCW AL, ZR, R6, R13
+0ce58a9a|	plan9	CSINC AL, R8, R10, R12
+75e2835a|	plan9	CSINVW AL, R19, R3, R21
+38e391da|	plan9	CSINV AL, R25, R17, R24
+fee4845a|	plan9	CSNEGW AL, R7, R4, R30
+09e49bda|	plan9	CSNEG AL, R0, R27, R9
+a8e6271e|	plan9	FCCMPS AL, F7, F21, $8
+ede67d1e|	plan9	FCCMPD AL, F29, F23, $13
+bbe53b1e|	plan9	FCCMPES AL, F27, F13, $11
+70e6661e|	plan9	FCCMPED AL, F6, F19, $0
+01ee3b1e|	plan9	FCSELS AL, F16, F27, F1
+15ec651e|	plan9	FCSELD AL, F0, F5, F21
+4f462554|	plan9	BAL 76338(PC)
+eef9493a|	plan9	CCMNW AL, R15, $9, $14
+88fa53ba|	plan9	CCMN AL, R20, $19, $8
+c0f25f3a|	plan9	CCMNW AL, R22, ZR, $0
+c6f05cba|	plan9	CCMN AL, R6, R28, $6
+45f84c7a|	plan9	CCMPW AL, R2, $12, $5
+a3fa4afa|	plan9	CCMP AL, R21, $10, $3
+caf3517a|	plan9	CCMPW AL, R30, R17, $10
+81f055fa|	plan9	CCMP AL, R4, R21, $1
+cbf69e1a|	plan9	CSINCW AL, R22, R30, R11
+01f48e9a|	plan9	CSINC AL, R0, R14, R1
+61f1845a|	plan9	CSINVW AL, R11, R4, R1
+11f397da|	plan9	CSINV AL, R24, R23, R17
+7bf69f5a|	plan9	CSNEGW AL, R19, ZR, R27
+b1f686da|	plan9	CSNEG AL, R21, R6, R17
+69f39e1a|	plan9	CSELW AL, R27, R30, R9
+79f2859a|	plan9	CSEL AL, R19, R5, R25
+e1f79f1a|	plan9	CSINCW AL, ZR, ZR, R1
+e6f79f9a|	plan9	CSINC AL, ZR, ZR, R6
+fcf39f5a|	plan9	CSINVW AL, ZR, ZR, R28
+fbf39fda|	plan9	CSINV AL, ZR, ZR, R27
+2ef4831a|	plan9	CSINCW AL, R1, R3, R14
+55f6859a|	plan9	CSINC AL, R18, R5, R21
+4ff0905a|	plan9	CSINVW AL, R2, R16, R15
+81f393da|	plan9	CSINV AL, R28, R19, R1
+8bf68d5a|	plan9	CSNEGW AL, R20, R13, R11
+c2f48fda|	plan9	CSNEG AL, R6, R15, R2
+e9f6391e|	plan9	FCCMPS AL, F25, F23, $9
+27f46f1e|	plan9	FCCMPD AL, F15, F1, $7
+72f6301e|	plan9	FCCMPES AL, F16, F19, $2
+37f57a1e|	plan9	FCCMPED AL, F26, F9, $7
+fcfe3a1e|	plan9	FCSELS AL, F23, F26, F28
+80fd701e|	plan9	FCSELD AL, F12, F16, F0
+40946454|	plan9	BEQ 205986(PC)
+8b09473a|	plan9	CCMNW EQ, R12, $7, $11
+c50a5eba|	plan9	CCMN EQ, R22, $30, $5
+05005a3a|	plan9	CCMNW EQ, R0, R26, $5
+cf024bba|	plan9	CCMN EQ, R22, R11, $15
+8a084f7a|	plan9	CCMPW EQ, R4, $15, $10
+e20a41fa|	plan9	CCMP EQ, R23, $1, $2
+8c015f7a|	plan9	CCMPW EQ, R12, ZR, $12
+e4015cfa|	plan9	CCMP EQ, R15, R28, $4
+42078e1a|	plan9	CSINCW EQ, R26, R14, R2
+2005879a|	plan9	CSINC EQ, R9, R7, R0
+f003955a|	plan9	CSINVW EQ, ZR, R21, R16
+dc019dda|	plan9	CSINV EQ, R14, R29, R28
+4607885a|	plan9	CSNEGW EQ, R26, R8, R6
+26069eda|	plan9	CSNEG EQ, R17, R30, R6
+72018a1a|	plan9	CSELW EQ, R11, R10, R18
+8003849a|	plan9	CSEL EQ, R28, R4, R0
+f1079f1a|	plan9	CSETW NE, R17
+fb079f9a|	plan9	CSET NE, R27
+ef039f5a|	plan9	CSETMW NE, R15
+e1039fda|	plan9	CSETM NE, R1
+5307881a|	plan9	CSINCW EQ, R26, R8, R19
+8a06969a|	plan9	CSINC EQ, R20, R22, R10
+ab00955a|	plan9	CSINVW EQ, R5, R21, R11
+c3039bda|	plan9	CSINV EQ, R30, R27, R3
+8005875a|	plan9	CSNEGW EQ, R12, R7, R0
+740694da|	plan9	CSNEG EQ, R19, R20, R20
+e207281e|	plan9	FCCMPS EQ, F8, F31, $2
+2b056a1e|	plan9	FCCMPD EQ, F10, F9, $11
+7e063f1e|	plan9	FCCMPES EQ, F31, F19, $14
+3c05671e|	plan9	FCCMPED EQ, F7, F9, $12
+830f271e|	plan9	FCSELS EQ, F28, F7, F3
+4d0d621e|	plan9	FCSELD EQ, F10, F2, F13
+bf2003d5|	plan9	SEVL
+9f2003d5|	plan9	SEV
+7f2003d5|	plan9	WFI
+5f2003d5|	plan9	WFE
+3f2003d5|	plan9	YIELD
+1f2003d5|	plan9	NOP
+df4d03d5|	plan9	MSR $13, DAIFSET
+ff4d03d5|	plan9	MSR $13, DAIFCLR
+28d91b14|	plan9	JMP 1825064(PC)
+15e5e514|	plan9	JMP 15066389(PC)
+ff4603d5|	plan9	MSR $6, DAIFCLR
+df4803d5|	plan9	MSR $8, DAIFSET
+bf4100d5|	plan9	MSR $1, SPSEL
+9f3f03d5|	plan9	DSB $15
+9f3e03d5|	plan9	DSB $14
+9f3d03d5|	plan9	DSB $13
+9f3b03d5|	plan9	DSB $11
+9f3a03d5|	plan9	DSB $10
+9f3903d5|	plan9	DSB $9
+9f3703d5|	plan9	DSB $7
+9f3603d5|	plan9	DSB $6
+9f3503d5|	plan9	DSB $5
+9f3303d5|	plan9	DSB $3
+9f3203d5|	plan9	DSB $2
+9f3103d5|	plan9	DSB $1
+ff4603d5|	plan9	MSR $6, DAIFCLR
+df4803d5|	plan9	MSR $8, DAIFSET
+bf4100d5|	plan9	MSR $1, SPSEL
+a3681b53|	plan9	LSLW $5, R5, R3
+47dc78d3|	plan9	LSL $8, R2, R7
+0500a012|	plan9	MOVNW $(0<<16), R5
+0500e092|	plan9	MOVN $(0<<48), R5
+0500a052|	plan9	MOVZW $(0<<16), R5
+0500a0d2|	plan9	MOVZ $(0<<16), R5
+cd5a206e|	plan9	VMVN V22.B16, V13.B16
+cd5a202e|	plan9	VMVN V22.B8, V13.B8
+743d050e|	plan9	UMOVW V11.B[2], R20
+743d0a0e|	plan9	UMOVW V11.H[2], R20
+743d0c0e|	plan9	VMOV V11.S[1], R20
+743d084e|	plan9	VMOV V11.D[0], R20
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/ext_test.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/ext_test.go
index b553984..95d4d46 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/ext_test.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/ext_test.go
@@ -35,7 +35,7 @@
 	debug      = false
 )
 
-// A ExtInst represents a single decoded instruction parsed
+// An ExtInst represents a single decoded instruction parsed
 // from an external disassembler's output.
 type ExtInst struct {
 	addr uint32
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go
index b6098b8..127be26 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go
@@ -54,9 +54,9 @@
 		} else {
 			switch syntax {
 			case "gnu":
-				out = GNUSyntax(inst)
+				out = GNUSyntax(inst, 0, nil)
 			case "intel":
-				out = IntelSyntax(inst)
+				out = IntelSyntax(inst, 0, nil)
 			case "plan9": // [sic]
 				out = GoSyntax(inst, 0, nil)
 			default:
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go
index eadfd71..72fe45b 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go
@@ -33,7 +33,7 @@
 	debug      = false
 )
 
-// A ExtInst represents a single decoded instruction parsed
+// An ExtInst represents a single decoded instruction parsed
 // from an external disassembler's output.
 type ExtInst struct {
 	addr uint32
@@ -248,9 +248,9 @@
 	} else {
 		switch syntax {
 		case "gnu":
-			text = GNUSyntax(inst)
+			text = GNUSyntax(inst, 0, nil)
 		case "intel":
-			text = IntelSyntax(inst)
+			text = IntelSyntax(inst, 0, nil)
 		case "plan9": // [sic]
 			text = GoSyntax(inst, 0, nil)
 		default:
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/format_test.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/format_test.go
new file mode 100644
index 0000000..9f110f8
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/format_test.go
@@ -0,0 +1,68 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x86asm
+
+import (
+	"encoding/hex"
+	"testing"
+)
+
+func testFormattingSymname(addr uint64) (string, uint64) {
+	switch addr {
+	case 0x424080:
+		return "runtime.printint", 0x424080
+	case 0x4c8068:
+		return "main.A", 0x4c8068
+	}
+	return "", 0
+}
+
+func TestFormatting(t *testing.T) {
+	testCases := []struct {
+		PC    uint64
+		bytes string
+
+		goSyntax, intelSyntax, gnuSyntax string
+	}{
+		{0x4816b2, "0f8677010000",
+			"JBE 0x48182f",
+			"jbe 0x48182f",
+			"jbe 0x48182f"},
+		{0x45065b, "488b442408",
+			"MOVQ 0x8(SP), AX",
+			"mov rax, qword ptr [rsp+0x8]",
+			"mov 0x8(%rsp),%rax"},
+		{0x450678, "488b05e9790700",
+			"MOVQ main.A(SB), AX",
+			"mov rax, qword ptr [main.A]",
+			"mov main.A,%rax"},
+		{0x450664, "e8173afdff",
+			"CALL runtime.printint(SB)",
+			"call runtime.printint",
+			"callq runtime.printint"},
+		{0x45069b, "488d0575d90100",
+			"LEAQ 0x1d975(IP), AX",
+			"lea rax, ptr [rip+0x1d975]",
+			"lea 0x1d975(%rip),%rax"},
+	}
+
+	for _, testCase := range testCases {
+		t.Logf("%#x %s %s", testCase.PC, testCase.bytes, testCase.goSyntax)
+		bs, _ := hex.DecodeString(testCase.bytes)
+		inst, err := Decode(bs, 64)
+		if err != nil {
+			t.Errorf("decode error %v", err)
+		}
+		if out := GoSyntax(inst, testCase.PC, testFormattingSymname); out != testCase.goSyntax {
+			t.Errorf("GoSyntax: %q", out)
+		}
+		if out := IntelSyntax(inst, testCase.PC, testFormattingSymname); out != testCase.intelSyntax {
+			t.Errorf("IntelSyntax: %q expected: %q", out, testCase.intelSyntax)
+		}
+		if out := GNUSyntax(inst, testCase.PC, testFormattingSymname); out != testCase.gnuSyntax {
+			t.Errorf("GNUSyntax: %q expected: %q", out, testCase.gnuSyntax)
+		}
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
index 728e5d1..75cff72 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
@@ -11,12 +11,16 @@
 
 // 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 {
+func GNUSyntax(inst Inst, pc uint64, symname SymLookup) 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.
 
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+
 	// Adjust opcode [sic].
 	switch inst.Op {
 	case FDIV, FDIVR, FSUB, FSUBR, FDIVP, FDIVRP, FSUBP, FSUBRP:
@@ -403,7 +407,7 @@
 		if a == Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
 			continue
 		}
-		args = append(args, gnuArg(&inst, a, &usedPrefixes))
+		args = append(args, gnuArg(&inst, pc, symname, a, &usedPrefixes))
 	}
 
 	// The default is to print the arguments in reverse Intel order.
@@ -513,7 +517,7 @@
 // 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 {
+func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool) string {
 	if x == nil {
 		return "<nil>"
 	}
@@ -535,6 +539,13 @@
 		}
 		return gccRegName[x]
 	case Mem:
+		if s, disp := memArgToSymbol(x, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
+			}
+			return fmt.Sprintf("%s%s", s, suffix)
+		}
 		seg := ""
 		var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
 		switch x.Segment {
@@ -644,8 +655,25 @@
 		}
 		return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
 	case Rel:
-		return fmt.Sprintf(".%+#x", int32(x))
+		if pc == 0 {
+			return fmt.Sprintf(".%+#x", int64(x))
+		} else {
+			addr := pc + uint64(inst.Len) + uint64(x)
+			if s, base := symname(addr); s != "" && addr == base {
+				return fmt.Sprintf("%s", s)
+			} else {
+				addr := pc + uint64(inst.Len) + uint64(x)
+				return fmt.Sprintf("%#x", addr)
+			}
+		}
 	case Imm:
+		if s, base := symname(uint64(x)); s != "" {
+			suffix := ""
+			if uint64(x) != base {
+				suffix = fmt.Sprintf("%+d", uint64(x)-base)
+			}
+			return fmt.Sprintf("$%s%s", s, suffix)
+		}
 		if inst.Mode == 32 {
 			return fmt.Sprintf("$%#x", uint32(x))
 		}
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
index 63fa2cf..472eabd 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
@@ -10,7 +10,11 @@
 )
 
 // IntelSyntax returns the Intel assembler syntax for the instruction, as defined by Intel's XED tool.
-func IntelSyntax(inst Inst) string {
+func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+
 	var iargs []Arg
 	for _, a := range inst.Args {
 		if a == nil {
@@ -256,7 +260,7 @@
 		if a == nil {
 			break
 		}
-		args = append(args, intelArg(&inst, a))
+		args = append(args, intelArg(&inst, pc, symname, a))
 	}
 
 	var op string
@@ -334,9 +338,16 @@
 	return prefix + op
 }
 
-func intelArg(inst *Inst, arg Arg) string {
+func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
 	switch a := arg.(type) {
 	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", s, suffix)
+		}
 		if inst.Mode == 32 {
 			return fmt.Sprintf("%#x", uint32(a))
 		}
@@ -417,18 +428,25 @@
 		}
 
 		prefix += "ptr "
+		if s, disp := memArgToSymbol(a, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
+			}
+			return prefix + fmt.Sprintf("[%s%s]", s, suffix)
+		}
 		if a.Segment != 0 {
 			prefix += strings.ToLower(a.Segment.String()) + ":"
 		}
 		prefix += "["
 		if a.Base != 0 {
-			prefix += intelArg(inst, a.Base)
+			prefix += intelArg(inst, pc, symname, 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)
+			prefix += fmt.Sprintf("%s*%d", intelArg(inst, pc, symname, a.Index), a.Scale)
 		}
 		if a.Disp != 0 {
 			if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
@@ -440,7 +458,17 @@
 		prefix += "]"
 		return prefix
 	case Rel:
-		return fmt.Sprintf(".%+#x", int64(a))
+		if pc == 0 {
+			return fmt.Sprintf(".%+#x", int64(a))
+		} else {
+			addr := pc + uint64(inst.Len) + uint64(a)
+			if s, base := symname(addr); s != "" && addr == base {
+				return fmt.Sprintf("%s", s)
+			} else {
+				addr := pc + uint64(inst.Len) + uint64(a)
+				return fmt.Sprintf("%#x", addr)
+			}
+		}
 	case Reg:
 		if int(a) < len(intelReg) && intelReg[a] != "" {
 			switch inst.Op {
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
index 41cfc08..a93bffd 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
@@ -9,6 +9,8 @@
 	"strings"
 )
 
+type SymLookup func(uint64) (string, uint64)
+
 // GoSyntax 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
@@ -16,7 +18,7 @@
 // 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 GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
+func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
 	if symname == nil {
 		symname = func(uint64) (string, uint64) { return "", 0 }
 	}
@@ -119,14 +121,12 @@
 		}
 		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)
+		if s, disp := memArgToSymbol(a, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
 			}
+			return fmt.Sprintf("%s%s(SB)", s, suffix)
 		}
 		s := ""
 		if a.Segment != 0 {
@@ -148,6 +148,25 @@
 	return arg.String()
 }
 
+func memArgToSymbol(a Mem, pc uint64, instrLen int, symname SymLookup) (string, int64) {
+	if a.Segment != 0 || a.Disp == 0 || a.Index != 0 || a.Scale != 0 {
+		return "", 0
+	}
+
+	var disp uint64
+	switch a.Base {
+	case IP, EIP, RIP:
+		disp = uint64(a.Disp + int64(pc) + int64(instrLen))
+	case 0:
+		disp = uint64(a.Disp)
+	default:
+		return "", 0
+	}
+
+	s, base := symname(disp)
+	return s, int64(disp) - int64(base)
+}
+
 var plan9Suffix = [maxOp + 1]bool{
 	ADC:       true,
 	ADD:       true,
diff --git a/src/cmd/vendor/vendor.json b/src/cmd/vendor/vendor.json
index 6e8171d..506325a 100644
--- a/src/cmd/vendor/vendor.json
+++ b/src/cmd/vendor/vendor.json
@@ -9,26 +9,32 @@
 		{
 			"canonical": "github.com/google/pprof",
 			"local": "github.com/google/pprof",
-			"revision": "dec22b42d9eee442222c36c8da24ddc9905e7ee6",
-			"revisionTime": "2017-03-01T19:58:13Z",
+			"revision": "9e20b5b106e946f4cd1df94c1f6fe3f88456628d",
+			"revisionTime": "2017-11-08T17:47:23Z"
 		},
 		{
 			"canonical": "golang.org/x/arch/x86/x86asm",
 			"local": "golang.org/x/arch/x86/x86asm",
-			"revision": "58ea1a195b1a354bcd572b7ef6bbbd264dc63732",
-			"revisionTime": "2017-02-16T08:17:04Z"
+			"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2"
+			"revisionTime": "2017-12-26T02:13:20Z"
 		},
 		{
 			"canonical": "golang.org/x/arch/arm/armasm",
 			"local": "golang.org/x/arch/arm/armasm",
-			"revision": "ad6a463afcf9bd5b38c81fa9ba612dae11859d40",
-			"revisionTime": "2015-08-28T15:42:14Z"
+			"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2"
+			"revisionTime": "2017-12-26T02:13:20Z"
 		},
 		{
 			"canonical": "golang.org/x/arch/ppc64/ppc64asm",
 			"local": "golang.org/x/arch/ppc64/ppc64asm",
-			"revision": "4831b0a617f7a819d4bf3c877d8e827d0283542c",
-			"revisionTime": "2016-10-12T18:28:04Z"
+			"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2"
+			"revisionTime": "2017-12-26T02:13:20Z"
+		},
+		{
+			"canonical": "golang.org/x/arch/arm64/arm6464asm",
+			"local": "golang.org/x/arch/arm64/arm64asm",
+			"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2"
+			"revisionTime": "2017-12-26T02:13:20Z"
 		}
 	]
 }
diff --git a/src/cmd/vet/README b/src/cmd/vet/README
index 56d4889..5ab7549 100644
--- a/src/cmd/vet/README
+++ b/src/cmd/vet/README
@@ -1,6 +1,6 @@
 Vet is a tool that checks correctness of Go programs. It runs a suite of tests,
 each tailored to check for a particular class of errors. Examples include incorrect
-Printf format verbs or malformed build tags.
+Printf format verbs and malformed build tags.
 
 Over time many checks have been added to vet's suite, but many more have been
 rejected as not appropriate for the tool. The criteria applied when selecting which
@@ -8,7 +8,7 @@
 
 Correctness:
 
-Vet's tools are about correctness, not style. A vet check must identify real or
+Vet's checks are about correctness, not style. A vet check must identify real or
 potential bugs that could cause incorrect compilation or execution. A check that
 only identifies stylistic points or alternative correct approaches to a situation
 is not acceptable.
diff --git a/src/cmd/vet/all/whitelist/386.txt b/src/cmd/vet/all/whitelist/386.txt
index 33b63e1..505856f 100644
--- a/src/cmd/vet/all/whitelist/386.txt
+++ b/src/cmd/vet/all/whitelist/386.txt
@@ -2,9 +2,11 @@
 
 runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: Compare is in package bytes
 
+// startup code uses non-standard calling convention and intentionally
+// omits args.
+runtime/asm_386.s: [386] rt0_go: use of 4(SP) points beyond argument frame
+
 // reflect trampolines intentionally omit arg size. Same for morestack.
-reflect/asm_386.s: [386] makeFuncStub: use of 4(SP) points beyond argument frame
-reflect/asm_386.s: [386] methodValueCall: use of 4(SP) points beyond argument frame
 runtime/asm_386.s: [386] morestack: use of 4(SP) points beyond argument frame
 runtime/asm_386.s: [386] morestack: use of 8(SP) points beyond argument frame
 runtime/asm_386.s: [386] morestack: use of 4(SP) points beyond argument frame
@@ -23,7 +25,3 @@
 runtime/asm_386.s: [386] float64touint32: function float64touint32 missing Go declaration
 
 runtime/asm_386.s: [386] stackcheck: function stackcheck missing Go declaration
-
-// Clearer using FP than SP, but that requires named offsets.
-runtime/asm_386.s: [386] rt0_go: unknown variable argc
-runtime/asm_386.s: [386] rt0_go: unknown variable argv
diff --git a/src/cmd/vet/all/whitelist/all.txt b/src/cmd/vet/all/whitelist/all.txt
index c28035f..6792d26 100644
--- a/src/cmd/vet/all/whitelist/all.txt
+++ b/src/cmd/vet/all/whitelist/all.txt
@@ -1,9 +1,5 @@
 // Non-platform-specific vet whitelist. See readme.txt for details.
 
-// Issue 17580 (remove when fixed)
-cmd/go/go_test.go: +build comment must appear before package clause and be followed by a blank line
-
-
 // Real problems that we can't fix.
 
 // This is a bad WriteTo signature. Errors are being ignored!
@@ -13,9 +9,6 @@
 
 // False positives.
 
-// Test of how fmt handles nil.
-fmt/fmt_test.go: arg nil for printf verb %s of wrong type: untyped nil
-
 // Nothing much to do about cross-package assembly. Unfortunate.
 runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: call is in package reflect
 runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: Equal is in package bytes
@@ -48,6 +41,7 @@
 encoding/xml/marshal_test.go: method MarshalXML(e *Encoder, start StartElement) error should have signature MarshalXML(*xml.Encoder, xml.StartElement) error
 encoding/xml/read.go: method UnmarshalXML(d *Decoder, start StartElement) error should have signature UnmarshalXML(*xml.Decoder, xml.StartElement) error
 encoding/xml/read_test.go: method UnmarshalXML(d *Decoder, start StartElement) error should have signature UnmarshalXML(*xml.Decoder, xml.StartElement) error
+encoding/xml/xml_test.go: method UnmarshalXML(*Decoder, StartElement) error should have signature UnmarshalXML(*xml.Decoder, xml.StartElement) error
 
 // Long struct tags used to test reflect internals
 cmd/link/link_test.go: struct field tag "\n\tLondon. Michaelmas term lately over, and the Lord Chancellor sitting in Lincoln’s Inn Hall. Implacable November weather. As much mud in the streets as if the waters had but newly retired from the face of the earth, and it would not be wonderful to meet a Megalosaurus, forty feet long or so, waddling like an elephantine lizard up Holborn Hill. Smoke lowering down from chimney-pots, making a soft black drizzle, with flakes of soot in it as big as full-grown snowflakes—gone into mourning, one might imagine, for the death of the sun. Dogs, undistinguishable in mire. Horses, scarcely better; splashed to their very blinkers. Foot passengers, jostling one another’s umbrellas in a general infection of ill temper, and losing their foot-hold at street-corners, where tens of thousands of other foot passengers have been slipping and sliding since the day broke (if this day ever broke), adding new deposits to the crust upon crust of mud, sticking at those points tenaciously to the pavement, and accumulating at compound interest.\n\n\tFog everywhere. Fog up the river, where it flows among green aits and meadows; fog down the river, where it rolls defiled among the tiers of shipping and the waterside pollutions of a great (and dirty) city. Fog on the Essex marshes, fog on the Kentish heights. Fog creeping into the cabooses of collier-brigs; fog lying out on the yards and hovering in the rigging of great ships; fog drooping on the gunwales of barges and small boats. Fog in the eyes and throats of ancient Greenwich pensioners, wheezing by the firesides of their wards; fog in the stem and bowl of the afternoon pipe of the wrathful skipper, down in his close cabin; fog cruelly pinching the toes and fingers of his shivering little ‘prentice boy on deck. Chance people on the bridges peeping over the parapets into a nether sky of fog, with fog all round them, as if they were up in a balloon and hanging in the misty clouds.\n\n\tGas looming through the fog in divers places in the streets, much as the sun may, from the spongey fields, be seen to loom by husbandman and ploughboy. Most of the shops lighted two hours before their time—as the gas seems to know, for it has a haggard and unwilling look.\n\n\tThe raw afternoon is rawest, and the dense fog is densest, and the muddy streets are muddiest near that leaden-headed old obstruction, appropriate ornament for the threshold of a leaden-headed old corporation, Temple Bar. And hard by Temple Bar, in Lincoln’s Inn Hall, at the very heart of the fog, sits the Lord High Chancellor in his High Court of Chancery." not compatible with reflect.StructTag.Get: bad syntax for struct tag key
diff --git a/src/cmd/vet/all/whitelist/amd64.txt b/src/cmd/vet/all/whitelist/amd64.txt
index fb617d5..ebde7be 100644
--- a/src/cmd/vet/all/whitelist/amd64.txt
+++ b/src/cmd/vet/all/whitelist/amd64.txt
@@ -5,8 +5,6 @@
 
 
 // reflect trampolines intentionally omit arg size. Same for morestack.
-reflect/asm_amd64.s: [amd64] makeFuncStub: use of 8(SP) points beyond argument frame
-reflect/asm_amd64.s: [amd64] methodValueCall: use of 8(SP) points beyond argument frame
 runtime/asm_amd64.s: [amd64] morestack: use of 8(SP) points beyond argument frame
 runtime/asm_amd64.s: [amd64] morestack: use of 16(SP) points beyond argument frame
 runtime/asm_amd64.s: [amd64] morestack: use of 8(SP) points beyond argument frame
@@ -33,3 +31,4 @@
 runtime/asm_amd64.s: [amd64] stackcheck: function stackcheck missing Go declaration
 runtime/asm_amd64.s: [amd64] indexShortStr: function indexShortStr missing Go declaration
 runtime/asm_amd64.s: [amd64] countByte: function countByte missing Go declaration
+runtime/asm_amd64.s: [amd64] gcWriteBarrier: function gcWriteBarrier missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/arm.txt b/src/cmd/vet/all/whitelist/arm.txt
index c0ab9de..839346c 100644
--- a/src/cmd/vet/all/whitelist/arm.txt
+++ b/src/cmd/vet/all/whitelist/arm.txt
@@ -3,8 +3,6 @@
 runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: Compare is in package bytes
 
 // reflect trampolines intentionally omit arg size. Same for morestack.
-reflect/asm_arm.s: [arm] makeFuncStub: use of 8(R13) points beyond argument frame
-reflect/asm_arm.s: [arm] methodValueCall: use of 8(R13) points beyond argument frame
 runtime/asm_arm.s: [arm] morestack: use of 4(R13) points beyond argument frame
 
 // Intentionally missing declarations.
@@ -20,7 +18,4 @@
 runtime/tls_arm.s: [arm] load_g: function load_g missing Go declaration
 runtime/tls_arm.s: [arm] _initcgo: function _initcgo missing Go declaration
 
-// Clearer using FP than SP, but that requires named offsets.
-runtime/asm_arm.s: [arm] rt0_go: use of 4(R13) points beyond argument frame
-
 runtime/internal/atomic/asm_arm.s: [arm] cas: function cas missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/arm64.txt b/src/cmd/vet/all/whitelist/arm64.txt
index 8a3c891..24fc6f4 100644
--- a/src/cmd/vet/all/whitelist/arm64.txt
+++ b/src/cmd/vet/all/whitelist/arm64.txt
@@ -2,12 +2,6 @@
 
 runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: Compare is in package bytes
 
-// False positives.
-
-// reflect trampolines intentionally omit arg size. Same for morestack.
-reflect/asm_arm64.s: [arm64] makeFuncStub: use of 16(RSP) points beyond argument frame
-reflect/asm_arm64.s: [arm64] methodValueCall: use of 16(RSP) points beyond argument frame
-
 // Intentionally missing declarations.
 runtime/asm_arm64.s: [arm64] abort: function abort missing Go declaration
 runtime/asm_arm64.s: [arm64] addmoduledata: function addmoduledata missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/darwin_arm64.txt b/src/cmd/vet/all/whitelist/darwin_arm64.txt
index 080a4ca..793cccf 100644
--- a/src/cmd/vet/all/whitelist/darwin_arm64.txt
+++ b/src/cmd/vet/all/whitelist/darwin_arm64.txt
@@ -5,10 +5,4 @@
 runtime/sys_darwin_arm64.s: [arm64] bsdthread_create: RET without writing to 4-byte ret+24(FP)
 runtime/sys_darwin_arm64.s: [arm64] bsdthread_start: function bsdthread_start missing Go declaration
 runtime/sys_darwin_arm64.s: [arm64] bsdthread_register: RET without writing to 4-byte ret+0(FP)
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 8(RSP) points beyond argument frame
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 8(RSP) points beyond argument frame
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 16(RSP) points beyond argument frame
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 8(RSP) points beyond argument frame
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 16(RSP) points beyond argument frame
-runtime/cgo/signal_darwin_arm64.s: [arm64] panicmem: use of 16(RSP) points beyond argument frame
 runtime/asm_arm64.s: [arm64] sigreturn: function sigreturn missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/mips64x.txt b/src/cmd/vet/all/whitelist/mips64x.txt
index b29cf3e..5354d21 100644
--- a/src/cmd/vet/all/whitelist/mips64x.txt
+++ b/src/cmd/vet/all/whitelist/mips64x.txt
@@ -1,7 +1,5 @@
 // mips64-specific vet whitelist. See readme.txt for details.
 
-reflect/asm_mips64x.s: [GOARCH] makeFuncStub: use of 16(R29) points beyond argument frame
-reflect/asm_mips64x.s: [GOARCH] methodValueCall: use of 16(R29) points beyond argument frame
 runtime/asm_mips64x.s: [GOARCH] abort: function abort missing Go declaration
 runtime/duff_mips64x.s: [GOARCH] duffzero: function duffzero missing Go declaration
 runtime/tls_mips64x.s: [GOARCH] save_g: function save_g missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/mipsx.txt b/src/cmd/vet/all/whitelist/mipsx.txt
index 949a1b3..860f839 100644
--- a/src/cmd/vet/all/whitelist/mipsx.txt
+++ b/src/cmd/vet/all/whitelist/mipsx.txt
@@ -1,7 +1,5 @@
 // mips64-specific vet whitelist. See readme.txt for details.
 
-reflect/asm_mipsx.s: [GOARCH] makeFuncStub: use of 8(R29) points beyond argument frame
-reflect/asm_mipsx.s: [GOARCH] methodValueCall: use of 8(R29) points beyond argument frame
 runtime/asm_mipsx.s: [GOARCH] abort: function abort missing Go declaration
 runtime/tls_mipsx.s: [GOARCH] save_g: function save_g missing Go declaration
 runtime/tls_mipsx.s: [GOARCH] load_g: function load_g missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/nacl_amd64p32.txt b/src/cmd/vet/all/whitelist/nacl_amd64p32.txt
index 83bcfe9..4b2aad2 100644
--- a/src/cmd/vet/all/whitelist/nacl_amd64p32.txt
+++ b/src/cmd/vet/all/whitelist/nacl_amd64p32.txt
@@ -1,8 +1,6 @@
 // nacl/amd64p32-specific vet whitelist. See readme.txt for details.
 
 // reflect trampolines intentionally omit arg size. Same for morestack.
-reflect/asm_amd64p32.s: [amd64p32] makeFuncStub: use of 4(SP) points beyond argument frame
-reflect/asm_amd64p32.s: [amd64p32] methodValueCall: use of 4(SP) points beyond argument frame
 runtime/asm_amd64p32.s: [amd64p32] morestack: use of 8(SP) points beyond argument frame
 runtime/asm_amd64p32.s: [amd64p32] morestack: use of 16(SP) points beyond argument frame
 runtime/asm_amd64p32.s: [amd64p32] morestack: use of 8(SP) points beyond argument frame
diff --git a/src/cmd/vet/all/whitelist/s390x.txt b/src/cmd/vet/all/whitelist/s390x.txt
index 875835e..f18236c 100644
--- a/src/cmd/vet/all/whitelist/s390x.txt
+++ b/src/cmd/vet/all/whitelist/s390x.txt
@@ -1,5 +1,3 @@
-reflect/asm_s390x.s: [s390x] makeFuncStub: use of 16(R15) points beyond argument frame
-reflect/asm_s390x.s: [s390x] methodValueCall: use of 16(R15) points beyond argument frame
 runtime/asm_s390x.s: [s390x] abort: function abort missing Go declaration
 runtime/asm_s390x.s: [s390x] memeqbody: function memeqbody missing Go declaration
 runtime/asm_s390x.s: [s390x] memeqbodyclc: function memeqbodyclc missing Go declaration
diff --git a/src/cmd/vet/all/whitelist/windows.txt b/src/cmd/vet/all/whitelist/windows.txt
index 1a208ad..2c101ae 100644
--- a/src/cmd/vet/all/whitelist/windows.txt
+++ b/src/cmd/vet/all/whitelist/windows.txt
@@ -3,7 +3,5 @@
 // Issue 18609
 crypto/x509/root_windows.go: unreachable code
 
-path/filepath/path_windows_test.go: possible formatting directive in Fatal call
-
 runtime/sys_windows_ARCHSUFF.s: [GOARCH] sigtramp: function sigtramp missing Go declaration
 runtime/sys_windows_ARCHSUFF.s: [GOARCH] onosstack: unknown variable usec; offset 0 is fn+0(FP)
diff --git a/src/cmd/vet/asmdecl.go b/src/cmd/vet/asmdecl.go
index 7882112..b01d23d 100644
--- a/src/cmd/vet/asmdecl.go
+++ b/src/cmd/vet/asmdecl.go
@@ -109,7 +109,7 @@
 var (
 	re           = regexp.MustCompile
 	asmPlusBuild = re(`//\s+\+build\s+([^\n]+)`)
-	asmTEXT      = re(`\bTEXT\b(.*)·([^\(]+)\(SB\)(?:\s*,\s*([0-9A-Z|+]+))?(?:\s*,\s*\$(-?[0-9]+)(?:-([0-9]+))?)?`)
+	asmTEXT      = re(`\bTEXT\b(.*)·([^\(]+)\(SB\)(?:\s*,\s*([0-9A-Z|+()]+))?(?:\s*,\s*\$(-?[0-9]+)(?:-([0-9]+))?)?`)
 	asmDATA      = re(`\b(DATA|GLOBL)\b`)
 	asmNamedFP   = re(`([a-zA-Z0-9_\xFF-\x{10FFFF}]+)(?:\+([0-9]+))\(FP\)`)
 	asmUnnamedFP = re(`[^+\-0-9](([0-9]+)\(FP\))`)
diff --git a/src/cmd/vet/assign.go b/src/cmd/vet/assign.go
index 54c1ae1..bfa5b30 100644
--- a/src/cmd/vet/assign.go
+++ b/src/cmd/vet/assign.go
@@ -37,6 +37,9 @@
 	}
 	for i, lhs := range stmt.Lhs {
 		rhs := stmt.Rhs[i]
+		if hasSideEffects(lhs) || hasSideEffects(rhs) {
+			continue // expressions may not be equal
+		}
 		if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
 			continue // short-circuit the heavy-weight gofmt check
 		}
diff --git a/src/cmd/vet/buildtag.go b/src/cmd/vet/buildtag.go
index 5fa08b6..80d8f81 100644
--- a/src/cmd/vet/buildtag.go
+++ b/src/cmd/vet/buildtag.go
@@ -69,9 +69,7 @@
 						setExit(1)
 						break Args
 					}
-					if strings.HasPrefix(elem, "!") {
-						elem = elem[1:]
-					}
+					elem = strings.TrimPrefix(elem, "!")
 					for _, c := range elem {
 						if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
 							fmt.Fprintf(os.Stderr, "%s:%d: invalid non-alphanumeric build constraint: %s\n", name, i+1, arg)
diff --git a/src/cmd/vet/cgo.go b/src/cmd/vet/cgo.go
index 984911c..76364ff 100644
--- a/src/cmd/vet/cgo.go
+++ b/src/cmd/vet/cgo.go
@@ -34,7 +34,12 @@
 		return
 	}
 	id, ok := sel.X.(*ast.Ident)
-	if !ok || id.Name != "C" {
+	if !ok {
+		return
+	}
+
+	pkgname, ok := f.pkg.uses[id].(*types.PkgName)
+	if !ok || pkgname.Imported().Path() != "C" {
 		return
 	}
 
diff --git a/src/cmd/vet/copylock.go b/src/cmd/vet/copylock.go
index 27eb5d4..ce14e1a 100644
--- a/src/cmd/vet/copylock.go
+++ b/src/cmd/vet/copylock.go
@@ -93,9 +93,16 @@
 
 // checkCopyLocksCallExpr detects lock copy in the arguments to a function call
 func checkCopyLocksCallExpr(f *File, ce *ast.CallExpr) {
-	if id, ok := ce.Fun.(*ast.Ident); ok && f.pkg.types[id].IsBuiltin() {
-		switch id.Name {
-		case "new", "len", "cap":
+	var id *ast.Ident
+	switch fun := ce.Fun.(type) {
+	case *ast.Ident:
+		id = fun
+	case *ast.SelectorExpr:
+		id = fun.Sel
+	}
+	if fun, ok := f.pkg.uses[id].(*types.Builtin); ok {
+		switch fun.Name() {
+		case "new", "len", "cap", "Sizeof":
 			return
 		}
 	}
diff --git a/src/cmd/vet/dead.go b/src/cmd/vet/dead.go
index b3a157b..130f619 100644
--- a/src/cmd/vet/dead.go
+++ b/src/cmd/vet/dead.go
@@ -4,7 +4,7 @@
 //
 // Simplified dead code detector. Used for skipping certain checks
 // on unreachable code (for instance, shift checks on arch-specific code).
-//
+
 package main
 
 import (
diff --git a/src/cmd/vet/doc.go b/src/cmd/vet/doc.go
index 1ee44a4..3df975c 100644
--- a/src/cmd/vet/doc.go
+++ b/src/cmd/vet/doc.go
@@ -9,19 +9,15 @@
 that do not guarantee all reports are genuine problems, but it can find errors
 not caught by the compilers.
 
-It can be invoked three ways:
+Vet is normally invoked using the go command by running "go vet":
 
-By package, from the go tool:
+	go vet
+vets the package in the current directory.
+
 	go vet package/path/name
 vets the package whose path is provided.
 
-By files:
-	go tool vet source/directory/*.go
-vets the files named, all of which must be in the same package.
-
-By directory:
-	go tool vet source/directory
-recursively descends the directory, vetting each package it finds.
+Use "go help packages" to see other ways of specifying which packages to vet.
 
 Vet's exit code is 2 for erroneous invocation of the tool, 1 if a
 problem was reported, and 0 otherwise. Note that the tool does not
@@ -211,5 +207,18 @@
 		For more information, see the discussion of the -printf flag.
 	-shadowstrict
 		Whether to be strict about shadowing; can be noisy.
+
+Using vet directly
+
+For testing and debugging vet can be run directly by invoking
+"go tool vet" or just running the binary. Run this way, vet might not
+have up to date information for imported packages.
+
+	go tool vet source/directory/*.go
+vets the files named, all of which must be in the same package.
+
+	go tool vet source/directory
+recursively descends the directory, vetting each package it finds.
+
 */
 package main
diff --git a/src/cmd/vet/httpresponse.go b/src/cmd/vet/httpresponse.go
index ce5ae46..791d11d 100644
--- a/src/cmd/vet/httpresponse.go
+++ b/src/cmd/vet/httpresponse.go
@@ -19,10 +19,6 @@
 }
 
 func checkHTTPResponse(f *File, node ast.Node) {
-	// If http.Response or http.Client are not defined, skip this check.
-	if httpResponseType == nil || httpClientType == nil {
-		return
-	}
 	call := node.(*ast.CallExpr)
 	if !isHTTPFuncOrMethodOnClient(f, call) {
 		return // the function call is not related to this check.
@@ -72,7 +68,7 @@
 	if res.Len() != 2 {
 		return false // the function called does not return two values.
 	}
-	if ptr, ok := res.At(0).Type().(*types.Pointer); !ok || !types.Identical(ptr.Elem(), httpResponseType) {
+	if ptr, ok := res.At(0).Type().(*types.Pointer); !ok || !isNamedType(ptr.Elem(), "net/http", "Response") {
 		return false // the first return type is not *http.Response.
 	}
 	if !types.Identical(res.At(1).Type().Underlying(), errorType) {
@@ -85,11 +81,11 @@
 		return ok && id.Name == "http" // function in net/http package.
 	}
 
-	if types.Identical(typ, httpClientType) {
+	if isNamedType(typ, "net/http", "Client") {
 		return true // method on http.Client.
 	}
 	ptr, ok := typ.(*types.Pointer)
-	return ok && types.Identical(ptr.Elem(), httpClientType) // method on *http.Client.
+	return ok && isNamedType(ptr.Elem(), "net/http", "Client") // method on *http.Client.
 }
 
 // blockStmtFinder is an ast.Visitor that given any ast node can find the
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index 34c5297..7265aa6 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -8,14 +8,17 @@
 
 import (
 	"bytes"
+	"encoding/json"
 	"flag"
 	"fmt"
 	"go/ast"
 	"go/build"
+	"go/importer"
 	"go/parser"
 	"go/printer"
 	"go/token"
 	"go/types"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -30,6 +33,9 @@
 	source  = flag.Bool("source", false, "import from source instead of compiled object files")
 	tags    = flag.String("tags", "", "space-separated list of build tags to apply when parsing")
 	tagList = []string{} // exploded version of tags flag; set in main
+
+	vcfg          vetConfig
+	mustTypecheck bool
 )
 
 var exitCode = 0
@@ -136,6 +142,7 @@
 	callExpr      *ast.CallExpr
 	compositeLit  *ast.CompositeLit
 	exprStmt      *ast.ExprStmt
+	forStmt       *ast.ForStmt
 	funcDecl      *ast.FuncDecl
 	funcLit       *ast.FuncLit
 	genDecl       *ast.GenDecl
@@ -188,9 +195,11 @@
 	// Parsed package "foo" when checking package "foo_test"
 	basePkg *Package
 
-	// The objects that are receivers of a "String() string" method.
+	// The keys are the objects that are receivers of a "String()
+	// string" method. The value reports whether the method has a
+	// pointer receiver.
 	// This is used by the recursiveStringer method in print.go.
-	stringers map[*ast.Object]bool
+	stringerPtrs map[*ast.Object]bool
 
 	// Registered checkers to run.
 	checkers map[ast.Node][]func(*File, ast.Node)
@@ -225,6 +234,18 @@
 	if flag.NArg() == 0 {
 		Usage()
 	}
+
+	// Special case for "go vet" passing an explicit configuration:
+	// single argument ending in vet.cfg.
+	// Once we have a more general mechanism for obtaining this
+	// information from build tools like the go command,
+	// vet should be changed to use it. This vet.cfg hack is an
+	// experiment to learn about what form that information should take.
+	if flag.NArg() == 1 && strings.HasSuffix(flag.Arg(0), "vet.cfg") {
+		doPackageCfg(flag.Arg(0))
+		os.Exit(exitCode)
+	}
+
 	for _, name := range flag.Args() {
 		// Is it a directory?
 		fi, err := os.Stat(name)
@@ -250,7 +271,7 @@
 		}
 		os.Exit(exitCode)
 	}
-	if doPackage(".", flag.Args(), nil) == nil {
+	if doPackage(flag.Args(), nil) == nil {
 		warnf("no files checked")
 	}
 	os.Exit(exitCode)
@@ -265,6 +286,67 @@
 	}
 }
 
+// vetConfig is the JSON config struct prepared by the Go command.
+type vetConfig struct {
+	Compiler    string
+	Dir         string
+	ImportPath  string
+	GoFiles     []string
+	ImportMap   map[string]string
+	PackageFile map[string]string
+
+	SucceedOnTypecheckFailure bool
+
+	imp types.Importer
+}
+
+func (v *vetConfig) Import(path string) (*types.Package, error) {
+	if v.imp == nil {
+		v.imp = importer.For(v.Compiler, v.openPackageFile)
+	}
+	if path == "unsafe" {
+		return v.imp.Import("unsafe")
+	}
+	p := v.ImportMap[path]
+	if p == "" {
+		return nil, fmt.Errorf("unknown import path %q", path)
+	}
+	if v.PackageFile[p] == "" {
+		return nil, fmt.Errorf("unknown package file for import %q", path)
+	}
+	return v.imp.Import(p)
+}
+
+func (v *vetConfig) openPackageFile(path string) (io.ReadCloser, error) {
+	file := v.PackageFile[path]
+	if file == "" {
+		// Note that path here has been translated via v.ImportMap,
+		// unlike in the error in Import above. We prefer the error in
+		// Import, but it's worth diagnosing this one too, just in case.
+		return nil, fmt.Errorf("unknown package file for %q", path)
+	}
+	f, err := os.Open(file)
+	if err != nil {
+		return nil, err
+	}
+	return f, nil
+}
+
+// doPackageCfg analyzes a single package described in a config file.
+func doPackageCfg(cfgFile string) {
+	js, err := ioutil.ReadFile(cfgFile)
+	if err != nil {
+		errorf("%v", err)
+	}
+	if err := json.Unmarshal(js, &vcfg); err != nil {
+		errorf("parsing vet config %s: %v", cfgFile, err)
+	}
+	stdImporter = &vcfg
+	inittypes()
+	mustTypecheck = true
+	doPackage(vcfg.GoFiles, nil)
+}
+
 // doPackageDir analyzes the single package found in the directory, if there is one,
 // plus a test package, if there is one.
 func doPackageDir(directory string) {
@@ -290,12 +372,12 @@
 	names = append(names, pkg.TestGoFiles...) // These are also in the "foo" package.
 	names = append(names, pkg.SFiles...)
 	prefixDirectory(directory, names)
-	basePkg := doPackage(directory, names, nil)
+	basePkg := doPackage(names, nil)
 	// Is there also a "foo_test" package? If so, do that one as well.
 	if len(pkg.XTestGoFiles) > 0 {
 		names = pkg.XTestGoFiles
 		prefixDirectory(directory, names)
-		doPackage(directory, names, basePkg)
+		doPackage(names, basePkg)
 	}
 }
 
@@ -312,7 +394,7 @@
 
 // doPackage analyzes the single package constructed from the named files.
 // It returns the parsed Package or nil if none of the files have been checked.
-func doPackage(directory string, names []string, basePkg *Package) *Package {
+func doPackage(names []string, basePkg *Package) *Package {
 	var files []*File
 	var astFiles []*ast.File
 	fs := token.NewFileSet()
@@ -348,10 +430,23 @@
 	pkg.path = astFiles[0].Name.Name
 	pkg.files = files
 	// Type check the package.
-	err := pkg.check(fs, astFiles)
-	if err != nil {
-		// Note that we only report this error when *verbose.
-		Println(err)
+	errs := pkg.check(fs, astFiles)
+	if errs != nil {
+		if vcfg.SucceedOnTypecheckFailure {
+			os.Exit(0)
+		}
+		if *verbose || mustTypecheck {
+			for _, err := range errs {
+				fmt.Fprintf(os.Stderr, "%v\n", err)
+			}
+			if mustTypecheck {
+				// This message could be silenced, and we could just exit,
+				// but it might be helpful at least at first to make clear that the
+				// above errors are coming from vet and not the compiler
+				// (they often look like compiler errors, such as "declared but not used").
+				errorf("typecheck failures")
+			}
+		}
 	}
 
 	// Check.
@@ -495,6 +590,8 @@
 		key = compositeLit
 	case *ast.ExprStmt:
 		key = exprStmt
+	case *ast.ForStmt:
+		key = forStmt
 	case *ast.FuncDecl:
 		key = funcDecl
 	case *ast.FuncLit:
diff --git a/src/cmd/vet/method.go b/src/cmd/vet/method.go
index baefa55..b13ce2f 100644
--- a/src/cmd/vet/method.go
+++ b/src/cmd/vet/method.go
@@ -138,7 +138,7 @@
 			t = append(t, f.Type)
 			continue
 		}
-		for _ = range f.Names {
+		for range f.Names {
 			t = append(t, f.Type)
 		}
 	}
diff --git a/src/cmd/vet/print.go b/src/cmd/vet/print.go
index 9998dda..04c5955 100644
--- a/src/cmd/vet/print.go
+++ b/src/cmd/vet/print.go
@@ -9,10 +9,12 @@
 import (
 	"bytes"
 	"flag"
+	"fmt"
 	"go/ast"
 	"go/constant"
 	"go/token"
 	"go/types"
+	"regexp"
 	"strconv"
 	"strings"
 	"unicode/utf8"
@@ -42,41 +44,73 @@
 			name = name[:colon]
 		}
 
-		name = strings.ToLower(name)
-		if name[len(name)-1] == 'f' {
-			isFormattedPrint[name] = true
-		} else {
-			isPrint[name] = true
-		}
+		isPrint[strings.ToLower(name)] = true
 	}
 }
 
-// isFormattedPrint records the formatted-print functions. Names are
-// lower-cased so the lookup is case insensitive.
-var isFormattedPrint = map[string]bool{
-	"errorf":  true,
-	"fatalf":  true,
-	"fprintf": true,
-	"logf":    true,
-	"panicf":  true,
-	"printf":  true,
-	"sprintf": true,
-}
+// TODO(rsc): Incorporate user-defined printf wrappers again.
+// The general plan is to allow vet of one package P to output
+// additional information to supply to later vets of packages
+// importing P. Then vet of P can record a list of printf wrappers
+// and the later vet using P.Printf will find it in the list and check it.
+// That's not ready for Go 1.10.
+// When that does happen, uncomment the user-defined printf
+// wrapper tests in testdata/print.go.
 
-// isPrint records the unformatted-print functions. Names are lower-cased
-// so the lookup is case insensitive.
+// isPrint records the print functions.
+// If a key ends in 'f' then it is assumed to be a formatted print.
 var isPrint = map[string]bool{
-	"error":    true,
-	"fatal":    true,
-	"fprint":   true,
-	"fprintln": true,
-	"log":      true,
-	"panic":    true,
-	"panicln":  true,
-	"print":    true,
-	"println":  true,
-	"sprint":   true,
-	"sprintln": true,
+	"fmt.Errorf":         true,
+	"fmt.Fprint":         true,
+	"fmt.Fprintf":        true,
+	"fmt.Fprintln":       true,
+	"fmt.Print":          true,
+	"fmt.Printf":         true,
+	"fmt.Println":        true,
+	"fmt.Sprint":         true,
+	"fmt.Sprintf":        true,
+	"fmt.Sprintln":       true,
+	"log.Fatal":          true,
+	"log.Fatalf":         true,
+	"log.Fatalln":        true,
+	"log.Logger.Fatal":   true,
+	"log.Logger.Fatalf":  true,
+	"log.Logger.Fatalln": true,
+	"log.Logger.Panic":   true,
+	"log.Logger.Panicf":  true,
+	"log.Logger.Panicln": true,
+	"log.Logger.Printf":  true,
+	"log.Logger.Println": true,
+	"log.Panic":          true,
+	"log.Panicf":         true,
+	"log.Panicln":        true,
+	"log.Print":          true,
+	"log.Printf":         true,
+	"log.Println":        true,
+	"testing.B.Error":    true,
+	"testing.B.Errorf":   true,
+	"testing.B.Fatal":    true,
+	"testing.B.Fatalf":   true,
+	"testing.B.Log":      true,
+	"testing.B.Logf":     true,
+	"testing.B.Skip":     true,
+	"testing.B.Skipf":    true,
+	"testing.T.Error":    true,
+	"testing.T.Errorf":   true,
+	"testing.T.Fatal":    true,
+	"testing.T.Fatalf":   true,
+	"testing.T.Log":      true,
+	"testing.T.Logf":     true,
+	"testing.T.Skip":     true,
+	"testing.T.Skipf":    true,
+	"testing.TB.Error":   true,
+	"testing.TB.Errorf":  true,
+	"testing.TB.Fatal":   true,
+	"testing.TB.Fatalf":  true,
+	"testing.TB.Log":     true,
+	"testing.TB.Logf":    true,
+	"testing.TB.Skip":    true,
+	"testing.TB.Skipf":   true,
 }
 
 // formatString returns the format string argument and its index within
@@ -88,8 +122,8 @@
 // The first string literal or string constant is assumed to be a format string
 // if the call's signature cannot be determined.
 //
-// If it cannot find any format string parameter, it returns  ("", -1).
-func formatString(f *File, call *ast.CallExpr) (string, int) {
+// If it cannot find any format string parameter, it returns ("", -1).
+func formatString(f *File, call *ast.CallExpr) (format string, idx int) {
 	typ := f.pkg.types[call.Fun].Type
 	if typ != nil {
 		if sig, ok := typ.(*types.Signature); ok {
@@ -146,14 +180,21 @@
 
 // checkCall triggers the print-specific checks if the call invokes a print function.
 func checkFmtPrintfCall(f *File, node ast.Node) {
+	if f.pkg.typesPkg == nil {
+		// This check now requires type information.
+		return
+	}
+
 	if d, ok := node.(*ast.FuncDecl); ok && isStringer(f, d) {
 		// Remember we saw this.
-		if f.stringers == nil {
-			f.stringers = make(map[*ast.Object]bool)
+		if f.stringerPtrs == nil {
+			f.stringerPtrs = make(map[*ast.Object]bool)
 		}
 		if l := d.Recv.List; len(l) == 1 {
 			if n := l[0].Names; len(n) == 1 {
-				f.stringers[n[0].Obj] = true
+				typ := f.pkg.types[l[0].Type]
+				_, ptrRecv := typ.Type.(*types.Pointer)
+				f.stringerPtrs[n[0].Obj] = ptrRecv
 			}
 		}
 		return
@@ -163,24 +204,67 @@
 	if !ok {
 		return
 	}
-	var Name string
+
+	// Construct name like pkg.Printf or pkg.Type.Printf for lookup.
+	var name string
 	switch x := call.Fun.(type) {
 	case *ast.Ident:
-		Name = x.Name
+		if fn, ok := f.pkg.uses[x].(*types.Func); ok {
+			var pkg string
+			if fn.Pkg() == nil || fn.Pkg() == f.pkg.typesPkg {
+				pkg = vcfg.ImportPath
+			} else {
+				pkg = fn.Pkg().Path()
+			}
+			name = pkg + "." + x.Name
+			break
+		}
+
 	case *ast.SelectorExpr:
-		Name = x.Sel.Name
-	default:
+		// Check for "fmt.Printf".
+		if id, ok := x.X.(*ast.Ident); ok {
+			if pkgName, ok := f.pkg.uses[id].(*types.PkgName); ok {
+				name = pkgName.Imported().Path() + "." + x.Sel.Name
+				break
+			}
+		}
+
+		// Check for t.Logf where t is a *testing.T.
+		if sel := f.pkg.selectors[x]; sel != nil {
+			recv := sel.Recv()
+			if p, ok := recv.(*types.Pointer); ok {
+				recv = p.Elem()
+			}
+			if named, ok := recv.(*types.Named); ok {
+				obj := named.Obj()
+				var pkg string
+				if obj.Pkg() == nil || obj.Pkg() == f.pkg.typesPkg {
+					pkg = vcfg.ImportPath
+				} else {
+					pkg = obj.Pkg().Path()
+				}
+				name = pkg + "." + obj.Name() + "." + x.Sel.Name
+				break
+			}
+		}
+	}
+	if name == "" {
 		return
 	}
 
-	name := strings.ToLower(Name)
-	if _, ok := isFormattedPrint[name]; ok {
-		f.checkPrintf(call, Name)
-		return
+	shortName := name[strings.LastIndex(name, ".")+1:]
+
+	_, ok = isPrint[name]
+	if !ok {
+		// Next look up just "printf", for use with -printfuncs.
+		_, ok = isPrint[strings.ToLower(shortName)]
 	}
-	if _, ok := isPrint[name]; ok {
-		f.checkPrint(call, Name)
-		return
+	if ok {
+		if strings.HasSuffix(name, "f") {
+			f.checkPrintf(call, shortName)
+		} else {
+			f.checkPrint(call, shortName)
+		}
 	}
 }
 
@@ -211,6 +295,7 @@
 	file         *File
 	call         *ast.CallExpr
 	argNum       int  // Which argument we're expecting to format now.
+	hasIndex     bool // Whether the argument is indexed.
 	indexPending bool // Whether we have an indexed argument that has not resolved.
 	nbytes       int  // number of bytes of the format string consumed.
 }
@@ -228,32 +313,37 @@
 	firstArg := idx + 1 // Arguments are immediately after format string.
 	if !strings.Contains(format, "%") {
 		if len(call.Args) > firstArg {
-			f.Badf(call.Pos(), "no formatting directive in %s call", name)
+			f.Badf(call.Pos(), "%s call has arguments but no formatting directives", name)
 		}
 		return
 	}
 	// Hard part: check formats against args.
 	argNum := firstArg
 	maxArgNum := firstArg
+	anyIndex := false
 	for i, w := 0, 0; i < len(format); i += w {
 		w = 1
-		if format[i] == '%' {
-			state := f.parsePrintfVerb(call, name, format[i:], firstArg, argNum)
-			if state == nil {
-				return
-			}
-			w = len(state.format)
-			if !f.okPrintfArg(call, state) { // One error per format is enough.
-				return
-			}
-			if len(state.argNums) > 0 {
-				// Continue with the next sequential argument.
-				argNum = state.argNums[len(state.argNums)-1] + 1
-			}
-			for _, n := range state.argNums {
-				if n >= maxArgNum {
-					maxArgNum = n + 1
-				}
+		if format[i] != '%' {
+			continue
+		}
+		state := f.parsePrintfVerb(call, name, format[i:], firstArg, argNum)
+		if state == nil {
+			return
+		}
+		w = len(state.format)
+		if !f.okPrintfArg(call, state) { // One error per format is enough.
+			return
+		}
+		if state.hasIndex {
+			anyIndex = true
+		}
+		if len(state.argNums) > 0 {
+			// Continue with the next sequential argument.
+			argNum = state.argNums[len(state.argNums)-1] + 1
+		}
+		for _, n := range state.argNums {
+			if n >= maxArgNum {
+				maxArgNum = n + 1
 			}
 		}
 	}
@@ -261,11 +351,15 @@
 	if call.Ellipsis.IsValid() && maxArgNum >= len(call.Args)-1 {
 		return
 	}
+	// If any formats are indexed, extra arguments are ignored.
+	if anyIndex {
+		return
+	}
 	// There should be no leftover arguments.
 	if maxArgNum != len(call.Args) {
 		expect := maxArgNum - firstArg
 		numArgs := len(call.Args) - firstArg
-		f.Badf(call.Pos(), "wrong number of args for format in %s call: %d needed but %d args", name, expect, numArgs)
+		f.Badf(call.Pos(), "%s call needs %v but has %v", name, count(expect, "arg"), count(numArgs, "arg"))
 	}
 }
 
@@ -301,23 +395,25 @@
 	s.nbytes++ // skip '['
 	start := s.nbytes
 	s.scanNum()
+	ok := true
 	if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' {
-		end := strings.Index(s.format, "]")
-		if end < 0 {
-			end = len(s.format)
+		ok = false
+		s.nbytes = strings.Index(s.format, "]")
+		if s.nbytes < 0 {
+			s.file.Badf(s.call.Pos(), "%s format %s is missing closing ]", s.name, s.format)
+			return false
 		}
-		s.file.Badf(s.call.Pos(), "bad syntax for printf argument index: [%s]", s.format[start:end])
-		return false
 	}
 	arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
-	if err != nil {
-		s.file.Badf(s.call.Pos(), "bad syntax for printf argument index: %s", err)
+	if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) {
+		s.file.Badf(s.call.Pos(), "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes])
 		return false
 	}
 	s.nbytes++ // skip ']'
 	arg := int(arg32)
 	arg += s.firstArg - 1 // We want to zero-index the actual arguments.
 	s.argNum = arg
+	s.hasIndex = true
 	s.indexPending = true
 	return true
 }
@@ -387,7 +483,7 @@
 		return nil
 	}
 	if state.nbytes == len(state.format) {
-		f.Badf(call.Pos(), "missing verb at end of format string in %s call", name)
+		f.Badf(call.Pos(), "%s format %s is missing verb at end of string", name, state.format)
 		return nil
 	}
 	verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:])
@@ -439,12 +535,12 @@
 	{'b', numFlag, argInt | argFloat | argComplex},
 	{'c', "-", argRune | argInt},
 	{'d', numFlag, argInt},
-	{'e', numFlag, argFloat | argComplex},
-	{'E', numFlag, argFloat | argComplex},
-	{'f', numFlag, argFloat | argComplex},
-	{'F', numFlag, argFloat | argComplex},
-	{'g', numFlag, argFloat | argComplex},
-	{'G', numFlag, argFloat | argComplex},
+	{'e', sharpNumFlag, argFloat | argComplex},
+	{'E', sharpNumFlag, argFloat | argComplex},
+	{'f', sharpNumFlag, argFloat | argComplex},
+	{'F', sharpNumFlag, argFloat | argComplex},
+	{'g', sharpNumFlag, argFloat | argComplex},
+	{'G', sharpNumFlag, argFloat | argComplex},
 	{'o', sharpNumFlag, argInt},
 	{'p', "-#", argPointer},
 	{'q', " -+.0#", argRune | argInt | argString},
@@ -479,15 +575,22 @@
 		}
 	}
 
-	if !found && !formatter {
-		f.Badf(call.Pos(), "unrecognized printf verb %q", state.verb)
-		return false
-	}
-	for _, flag := range state.flags {
-		if !strings.ContainsRune(v.flags, rune(flag)) {
-			f.Badf(call.Pos(), "unrecognized printf flag for verb %q: %q", state.verb, flag)
+	if !formatter {
+		if !found {
+			f.Badf(call.Pos(), "%s format %s has unknown verb %c", state.name, state.format, state.verb)
 			return false
 		}
+		for _, flag := range state.flags {
+			// TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
+			// See issues 23598 and 23605.
+			if flag == '0' {
+				continue
+			}
+			if !strings.ContainsRune(v.flags, rune(flag)) {
+				f.Badf(call.Pos(), "%s format %s has unrecognized flag %c", state.name, state.format, flag)
+				return false
+			}
+		}
 	}
 	// Verb is good. If len(state.argNums)>trueArgs, we have something like %.*s and all
 	// but the final arg must be an integer.
@@ -498,12 +601,12 @@
 	nargs := len(state.argNums)
 	for i := 0; i < nargs-trueArgs; i++ {
 		argNum := state.argNums[i]
-		if !f.argCanBeChecked(call, i, true, state) {
+		if !f.argCanBeChecked(call, i, state) {
 			return
 		}
 		arg := call.Args[argNum]
 		if !f.matchArgType(argInt, nil, arg) {
-			f.Badf(call.Pos(), "arg %s for * in printf format not of type int", f.gofmt(arg))
+			f.Badf(call.Pos(), "%s format %s uses non-int %s as argument of *", state.name, state.format, f.gofmt(arg))
 			return false
 		}
 	}
@@ -511,12 +614,12 @@
 		return true
 	}
 	argNum := state.argNums[len(state.argNums)-1]
-	if !f.argCanBeChecked(call, len(state.argNums)-1, false, state) {
+	if !f.argCanBeChecked(call, len(state.argNums)-1, state) {
 		return false
 	}
 	arg := call.Args[argNum]
 	if f.isFunctionValue(arg) && state.verb != 'p' && state.verb != 'T' {
-		f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
+		f.Badf(call.Pos(), "%s format %s arg %s is a func value, not called", state.name, state.format, f.gofmt(arg))
 		return false
 	}
 	if !f.matchArgType(v.typ, nil, arg) {
@@ -524,11 +627,11 @@
 		if typ := f.pkg.types[arg].Type; typ != nil {
 			typeString = typ.String()
 		}
-		f.Badf(call.Pos(), "arg %s for printf verb %%%c of wrong type: %s", f.gofmt(arg), state.verb, typeString)
+		f.Badf(call.Pos(), "%s format %s has arg %s of wrong type %s", state.name, state.format, f.gofmt(arg), typeString)
 		return false
 	}
 	if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) && f.recursiveStringer(arg) {
-		f.Badf(call.Pos(), "arg %s for printf causes recursive call to String method", f.gofmt(arg))
+		f.Badf(call.Pos(), "%s format %s with arg %s causes recursive String method call", state.name, state.format, f.gofmt(arg))
 		return false
 	}
 	return true
@@ -537,9 +640,10 @@
 // recursiveStringer reports whether the provided argument is r or &r for the
 // fmt.Stringer receiver identifier r.
 func (f *File) recursiveStringer(e ast.Expr) bool {
-	if len(f.stringers) == 0 {
+	if len(f.stringerPtrs) == 0 {
 		return false
 	}
+	ptr := false
 	var obj *ast.Object
 	switch e := e.(type) {
 	case *ast.Ident:
@@ -547,6 +651,7 @@
 	case *ast.UnaryExpr:
 		if id, ok := e.X.(*ast.Ident); ok && e.Op == token.AND {
 			obj = id.Obj
+			ptr = true
 		}
 	}
 
@@ -561,7 +666,16 @@
 	// We compare the underlying Object, which checks that the identifier
 	// is the one we declared as the receiver for the String method in
 	// which this printf appears.
-	return f.stringers[obj]
+	ptrRecv, exist := f.stringerPtrs[obj]
+	if !exist {
+		return false
+	}
+	// We also need to check that using &t when we declared String
+	// on (t *T) is ok; in such a case, the address is printed.
+	if ptr && ptrRecv {
+		return false
+	}
+	return true
 }
 
 // isFunctionValue reports whether the expression is a function as opposed to a function call.
@@ -577,16 +691,12 @@
 // argCanBeChecked reports whether the specified argument is statically present;
 // it may be beyond the list of arguments or in a terminal slice... argument, which
 // means we can't see it.
-func (f *File) argCanBeChecked(call *ast.CallExpr, formatArg int, isStar bool, state *formatState) bool {
+func (f *File) argCanBeChecked(call *ast.CallExpr, formatArg int, state *formatState) bool {
 	argNum := state.argNums[formatArg]
-	if argNum < 0 {
+	if argNum <= 0 {
 		// Shouldn't happen, so catch it with prejudice.
 		panic("negative arg num")
 	}
-	if argNum == 0 {
-		f.Badf(call.Pos(), `index value [0] for %s("%s"); indexes start at 1`, state.name, state.format)
-		return false
-	}
 	if argNum < len(call.Args)-1 {
 		return true // Always OK.
 	}
@@ -599,10 +709,22 @@
 	// There are bad indexes in the format or there are fewer arguments than the format needs.
 	// This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
 	arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed.
-	f.Badf(call.Pos(), `missing argument for %s("%s"): format reads arg %d, have only %d args`, state.name, state.format, arg, len(call.Args)-state.firstArg)
+	f.Badf(call.Pos(), "%s format %s reads arg #%d, but call has only %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg"))
 	return false
 }
 
+// printFormatRE is the regexp we match and report as a possible format string
+// in the first argument to unformatted prints like fmt.Print.
+// We exclude the space flag, so that printing a string like "x % y" is not reported as a format.
+var printFormatRE = regexp.MustCompile(`%` + flagsRE + numOptRE + `\.?` + numOptRE + indexOptRE + verbRE)
+
+const (
+	flagsRE    = `[+\-#]*`
+	indexOptRE = `(\[[0-9]+\])?`
+	numOptRE   = `([0-9]+|` + indexOptRE + `\*)?`
+	verbRE     = `[bcdefgopqstvxEFGUX]`
+)
+
 // checkPrint checks a call to an unformatted print routine such as Println.
 func (f *File) checkPrint(call *ast.CallExpr, name string) {
 	firstArg := 0
@@ -634,40 +756,53 @@
 	}
 	args = args[firstArg:]
 
-	// check for Println(os.Stderr, ...)
 	if firstArg == 0 {
-		if sel, ok := args[0].(*ast.SelectorExpr); ok {
+		if sel, ok := call.Args[0].(*ast.SelectorExpr); ok {
 			if x, ok := sel.X.(*ast.Ident); ok {
 				if x.Name == "os" && strings.HasPrefix(sel.Sel.Name, "Std") {
-					f.Badf(call.Pos(), "first argument to %s is %s.%s", name, x.Name, sel.Sel.Name)
+					f.Badf(call.Pos(), "%s does not take io.Writer but has first arg %s", name, f.gofmt(call.Args[0]))
 				}
 			}
 		}
 	}
+
 	arg := args[0]
 	if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
 		// Ignore trailing % character in lit.Value.
 		// The % in "abc 0.0%" couldn't be a formatting directive.
 		s := strings.TrimSuffix(lit.Value, `%"`)
 		if strings.Contains(s, "%") {
-			f.Badf(call.Pos(), "possible formatting directive in %s call", name)
+			m := printFormatRE.FindStringSubmatch(s)
+			if m != nil {
+				f.Badf(call.Pos(), "%s call has possible formatting directive %s", name, m[0])
+			}
 		}
 	}
 	if strings.HasSuffix(name, "ln") {
 		// The last item, if a string, should not have a newline.
 		arg = args[len(args)-1]
 		if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
-			if strings.HasSuffix(lit.Value, `\n"`) {
-				f.Badf(call.Pos(), "%s call ends with newline", name)
+			str, _ := strconv.Unquote(lit.Value)
+			if strings.HasSuffix(str, "\n") {
+				f.Badf(call.Pos(), "%s arg list ends with redundant newline", name)
 			}
 		}
 	}
 	for _, arg := range args {
 		if f.isFunctionValue(arg) {
-			f.Badf(call.Pos(), "arg %s in %s call is a function value, not a function call", f.gofmt(arg), name)
+			f.Badf(call.Pos(), "%s arg %s is a func value, not called", name, f.gofmt(arg))
 		}
 		if f.recursiveStringer(arg) {
-			f.Badf(call.Pos(), "arg %s in %s call causes recursive call to String method", f.gofmt(arg), name)
+			f.Badf(call.Pos(), "%s arg %s causes recursive call to String method", name, f.gofmt(arg))
 		}
 	}
 }
+
+// count(n, what) returns "1 what" or "N whats"
+// (assuming the plural of what is whats).
+func count(n int, what string) string {
+	if n == 1 {
+		return "1 " + what
+	}
+	return fmt.Sprintf("%d %ss", n, what)
+}
diff --git a/src/cmd/vet/rangeloop.go b/src/cmd/vet/rangeloop.go
index e085e21..53a4136 100644
--- a/src/cmd/vet/rangeloop.go
+++ b/src/cmd/vet/rangeloop.go
@@ -25,27 +25,55 @@
 
 func init() {
 	register("rangeloops",
-		"check that range loop variables are used correctly",
-		checkRangeLoop,
-		rangeStmt)
+		"check that loop variables are used correctly",
+		checkLoop,
+		rangeStmt, forStmt)
 }
 
-// checkRangeLoop walks the body of the provided range statement, checking if
+// checkLoop walks the body of the provided loop statement, checking whether
 // its index or value variables are used unsafely inside goroutines or deferred
 // function literals.
-func checkRangeLoop(f *File, node ast.Node) {
-	n := node.(*ast.RangeStmt)
-	key, _ := n.Key.(*ast.Ident)
-	val, _ := n.Value.(*ast.Ident)
-	if key == nil && val == nil {
+func checkLoop(f *File, node ast.Node) {
+	// Find the variables updated by the loop statement.
+	var vars []*ast.Ident
+	addVar := func(expr ast.Expr) {
+		if id, ok := expr.(*ast.Ident); ok {
+			vars = append(vars, id)
+		}
+	}
+	var body *ast.BlockStmt
+	switch n := node.(type) {
+	case *ast.RangeStmt:
+		body = n.Body
+		addVar(n.Key)
+		addVar(n.Value)
+	case *ast.ForStmt:
+		body = n.Body
+		switch post := n.Post.(type) {
+		case *ast.AssignStmt:
+			// e.g. for p = head; p != nil; p = p.next
+			for _, lhs := range post.Lhs {
+				addVar(lhs)
+			}
+		case *ast.IncDecStmt:
+			// e.g. for i := 0; i < n; i++
+			addVar(post.X)
+		}
+	}
+	if vars == nil {
 		return
 	}
-	sl := n.Body.List
-	if len(sl) == 0 {
+
+	// Inspect a go or defer statement
+	// if it's the last one in the loop body.
+	// (We give up if there are following statements,
+	// because it's hard to prove go isn't followed by wait,
+	// or defer by return.)
+	if len(body.List) == 0 {
 		return
 	}
 	var last *ast.CallExpr
-	switch s := sl[len(sl)-1].(type) {
+	switch s := body.List[len(body.List)-1].(type) {
 	case *ast.GoStmt:
 		last = s.Call
 	case *ast.DeferStmt:
@@ -63,11 +91,14 @@
 			return true
 		}
 		if f.pkg.types[id].Type == nil {
-			// Not referring to a variable
+			// Not referring to a variable (e.g. struct field name)
 			return true
 		}
-		if key != nil && id.Obj == key.Obj || val != nil && id.Obj == val.Obj {
-			f.Bad(id.Pos(), "range variable", id.Name, "captured by func literal")
+		for _, v := range vars {
+			if v.Obj == id.Obj {
+				f.Badf(id.Pos(), "loop variable %s captured by func literal",
+					id.Name)
+			}
 		}
 		return true
 	})
diff --git a/src/cmd/vet/structtag.go b/src/cmd/vet/structtag.go
index 872fde7..3bc30c4 100644
--- a/src/cmd/vet/structtag.go
+++ b/src/cmd/vet/structtag.go
@@ -31,6 +31,7 @@
 }
 
 var checkTagDups = []string{"json", "xml"}
+var checkTagSpaces = map[string]bool{"json": true, "xml": true, "asn1": true}
 
 // checkCanonicalFieldTag checks a single struct field tag.
 func checkCanonicalFieldTag(f *File, field *ast.Field, seen *map[[2]string]token.Pos) {
@@ -114,6 +115,7 @@
 	errTagSyntax      = errors.New("bad syntax for struct tag pair")
 	errTagKeySyntax   = errors.New("bad syntax for struct tag key")
 	errTagValueSyntax = errors.New("bad syntax for struct tag value")
+	errTagValueSpace  = errors.New("suspicious space in struct tag value")
 	errTagSpace       = errors.New("key:\"value\" pairs not separated by spaces")
 )
 
@@ -157,6 +159,7 @@
 		if tag[i+1] != '"' {
 			return errTagValueSyntax
 		}
+		key := tag[:i]
 		tag = tag[i+1:]
 
 		// Scan quoted string to find value.
@@ -173,9 +176,51 @@
 		qvalue := tag[:i+1]
 		tag = tag[i+1:]
 
-		if _, err := strconv.Unquote(qvalue); err != nil {
+		value, err := strconv.Unquote(qvalue)
+		if err != nil {
 			return errTagValueSyntax
 		}
+
+		if !checkTagSpaces[key] {
+			continue
+		}
+
+		switch key {
+		case "xml":
+			// If the first or last character in the XML tag is a space, it is
+			// suspicious.
+			if strings.Trim(value, " ") != value {
+				return errTagValueSpace
+			}
+
+			// If there are multiple spaces, they are suspicious.
+			if strings.Count(value, " ") > 1 {
+				return errTagValueSpace
+			}
+
+			// If there is no comma, skip the rest of the checks.
+			comma := strings.IndexRune(value, ',')
+			if comma < 0 {
+				continue
+			}
+
+			// If the character before a comma is a space, this is suspicious.
+			if comma > 0 && value[comma-1] == ' ' {
+				return errTagValueSpace
+			}
+			value = value[comma+1:]
+		case "json":
+			// JSON allows using spaces in the name, so skip it.
+			comma := strings.IndexRune(value, ',')
+			if comma < 0 {
+				continue
+			}
+			value = value[comma+1:]
+		}
+
+		if strings.IndexByte(value, ' ') >= 0 {
+			return errTagValueSpace
+		}
 	}
 	return nil
 }
diff --git a/src/cmd/vet/testdata/assign.go b/src/cmd/vet/testdata/assign.go
index 32ba868..6140ad4 100644
--- a/src/cmd/vet/testdata/assign.go
+++ b/src/cmd/vet/testdata/assign.go
@@ -6,13 +6,26 @@
 
 package testdata
 
+import "math/rand"
+
 type ST struct {
 	x int
+	l []int
 }
 
-func (s *ST) SetX(x int) {
+func (s *ST) SetX(x int, ch chan int) {
 	// Accidental self-assignment; it should be "s.x = x"
 	x = x // ERROR "self-assignment of x to x"
 	// Another mistake
 	s.x = s.x // ERROR "self-assignment of s.x to s.x"
+
+	s.l[0] = s.l[0] // ERROR "self-assignment of s.l.0. to s.l.0."
+
+	// Bail on any potential side effects to avoid false positives
+	s.l[num()] = s.l[num()]
+	rng := rand.New(rand.NewSource(0))
+	s.l[rng.Intn(len(s.l))] = s.l[rng.Intn(len(s.l))]
+	s.l[<-ch] = s.l[<-ch]
 }
+
+func num() int { return 2 }
diff --git a/src/cmd/vet/testdata/cgo/cgo2.go b/src/cmd/vet/testdata/cgo/cgo2.go
index 276aea9..4f27116 100644
--- a/src/cmd/vet/testdata/cgo/cgo2.go
+++ b/src/cmd/vet/testdata/cgo/cgo2.go
@@ -7,3 +7,6 @@
 package testdata
 
 var _ = C.f(*p(**p))
+
+// Passing a pointer (via the slice), but C isn't cgo.
+var _ = C.f([]int{3})
diff --git a/src/cmd/vet/testdata/cgo/cgo4.go b/src/cmd/vet/testdata/cgo/cgo4.go
new file mode 100644
index 0000000..67b5450
--- /dev/null
+++ b/src/cmd/vet/testdata/cgo/cgo4.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test the cgo checker on a file that doesn't use cgo, but has an
+// import named "C".
+
+package testdata
+
+import C "fmt"
+
+var _ = C.Println(*p(**p))
+
+// Passing a pointer (via a slice), but C is fmt, not cgo.
+var _ = C.Println([]int{3})
diff --git a/src/cmd/vet/testdata/copylock.go b/src/cmd/vet/testdata/copylock.go
index 6fabbc3..e9902a2 100644
--- a/src/cmd/vet/testdata/copylock.go
+++ b/src/cmd/vet/testdata/copylock.go
@@ -3,6 +3,9 @@
 import (
 	"sync"
 	"sync/atomic"
+	"unsafe"
+	. "unsafe"
+	unsafe1 "unsafe"
 )
 
 func OkFunc() {
@@ -102,6 +105,17 @@
 	cap(a) // ERROR "call of cap copies lock value: sync.Mutex"
 }
 
+func SizeofMutex() {
+	var mu sync.Mutex
+	unsafe.Sizeof(mu)  // OK
+	unsafe1.Sizeof(mu) // OK
+	Sizeof(mu)         // OK
+	unsafe := struct{ Sizeof func(interface{}) }{}
+	unsafe.Sizeof(mu) // ERROR "call of unsafe.Sizeof copies lock value: sync.Mutex"
+	Sizeof := func(interface{}) {}
+	Sizeof(mu) // ERROR "call of Sizeof copies lock value: sync.Mutex"
+}
+
 // SyncTypesCheck checks copying of sync.* types except sync.Mutex
 func SyncTypesCheck() {
 	// sync.RWMutex copying
@@ -164,9 +178,11 @@
 	var vX atomic.Value
 	var vXX = atomic.Value{}
 	vX1 := new(atomic.Value)
-	vY := vX     // ERROR "assignment copies lock value to vY: sync/atomic.Value contains sync/atomic.noCopy"
-	vY = vX      // ERROR "assignment copies lock value to vY: sync/atomic.Value contains sync/atomic.noCopy"
-	var vYY = vX // ERROR "variable declaration copies lock value to vYY: sync/atomic.Value contains sync/atomic.noCopy"
+	// These are OK because the value has not been used yet.
+	// (And vet can't tell whether it has been used, so they're always OK.)
+	vY := vX
+	vY = vX
+	var vYY = vX
 	vP := &vX
 	vZ := &atomic.Value{}
 }
diff --git a/src/cmd/vet/testdata/copylock_func.go b/src/cmd/vet/testdata/copylock_func.go
index 0f7ffcb..280747a 100644
--- a/src/cmd/vet/testdata/copylock_func.go
+++ b/src/cmd/vet/testdata/copylock_func.go
@@ -11,12 +11,14 @@
 
 func OkFunc(*sync.Mutex) {}
 func BadFunc(sync.Mutex) {} // ERROR "BadFunc passes lock by value: sync.Mutex"
+func BadFunc2(sync.Map)  {} // ERROR "BadFunc2 passes lock by value: sync.Map contains sync.Mutex"
 func OkRet() *sync.Mutex {}
 func BadRet() sync.Mutex {} // Don't warn about results
 
 var (
-	OkClosure  = func(*sync.Mutex) {}
-	BadClosure = func(sync.Mutex) {} // ERROR "func passes lock by value: sync.Mutex"
+	OkClosure   = func(*sync.Mutex) {}
+	BadClosure  = func(sync.Mutex) {} // ERROR "func passes lock by value: sync.Mutex"
+	BadClosure2 = func(sync.Map) {}   // ERROR "func passes lock by value: sync.Map contains sync.Mutex"
 )
 
 type EmbeddedRWMutex struct {
diff --git a/src/cmd/vet/testdata/print.go b/src/cmd/vet/testdata/print.go
index 76e7bd7..6508c8e 100644
--- a/src/cmd/vet/testdata/print.go
+++ b/src/cmd/vet/testdata/print.go
@@ -4,17 +4,22 @@
 
 // This file contains tests for the printf checker.
 
+// TODO(rsc): The user-defined wrapper tests are commented out
+// because they produced too many false positives when vet was
+// enabled during go test. See the TODO in ../print.go for a plan
+// to fix that; when it's fixed, uncomment the user-defined wrapper tests.
+
 package testdata
 
 import (
 	"fmt"
-	"io"
+	. "fmt"
 	"math"
 	"os"
+	"testing"
 	"unsafe" // just for test case printing unsafe.Pointer
-
 	// For testing printf-like functions from external package.
-	"github.com/foobar/externalprintf"
+	// "github.com/foobar/externalprintf"
 )
 
 func UnsafePointerPrintfTest() {
@@ -102,75 +107,78 @@
 	fmt.Printf("%s", interface{}(nil)) // Nothing useful we can say.
 
 	fmt.Printf("%g", 1+2i)
+	fmt.Printf("%#e %#E %#f %#F %#g %#G", 1.2, 1.2, 1.2, 1.2, 1.2, 1.2) // OK since Go 1.9
 	// Some bad format/argTypes
-	fmt.Printf("%b", "hi")                     // ERROR "arg .hi. for printf verb %b of wrong type"
-	fmt.Printf("%t", c)                        // ERROR "arg c for printf verb %t of wrong type"
-	fmt.Printf("%t", 1+2i)                     // ERROR "arg 1 \+ 2i for printf verb %t of wrong type"
-	fmt.Printf("%c", 2.3)                      // ERROR "arg 2.3 for printf verb %c of wrong type"
-	fmt.Printf("%d", 2.3)                      // ERROR "arg 2.3 for printf verb %d of wrong type"
-	fmt.Printf("%e", "hi")                     // ERROR "arg .hi. for printf verb %e of wrong type"
-	fmt.Printf("%E", true)                     // ERROR "arg true for printf verb %E of wrong type"
-	fmt.Printf("%f", "hi")                     // ERROR "arg .hi. for printf verb %f of wrong type"
-	fmt.Printf("%F", 'x')                      // ERROR "arg 'x' for printf verb %F of wrong type"
-	fmt.Printf("%g", "hi")                     // ERROR "arg .hi. for printf verb %g of wrong type"
-	fmt.Printf("%g", imap)                     // ERROR "arg imap for printf verb %g of wrong type"
-	fmt.Printf("%G", i)                        // ERROR "arg i for printf verb %G of wrong type"
-	fmt.Printf("%o", x)                        // ERROR "arg x for printf verb %o of wrong type"
-	fmt.Printf("%p", 23)                       // ERROR "arg 23 for printf verb %p of wrong type"
-	fmt.Printf("%q", x)                        // ERROR "arg x for printf verb %q of wrong type"
-	fmt.Printf("%s", b)                        // ERROR "arg b for printf verb %s of wrong type"
-	fmt.Printf("%s", byte(65))                 // ERROR "arg byte\(65\) for printf verb %s of wrong type"
-	fmt.Printf("%t", 23)                       // ERROR "arg 23 for printf verb %t of wrong type"
-	fmt.Printf("%U", x)                        // ERROR "arg x for printf verb %U of wrong type"
-	fmt.Printf("%x", nil)                      // ERROR "arg nil for printf verb %x of wrong type"
-	fmt.Printf("%X", 2.3)                      // ERROR "arg 2.3 for printf verb %X of wrong type"
-	fmt.Printf("%s", stringerv)                // ERROR "arg stringerv for printf verb %s of wrong type"
-	fmt.Printf("%t", stringerv)                // ERROR "arg stringerv for printf verb %t of wrong type"
-	fmt.Printf("%s", embeddedStringerv)        // ERROR "arg embeddedStringerv for printf verb %s of wrong type"
-	fmt.Printf("%t", embeddedStringerv)        // ERROR "arg embeddedStringerv for printf verb %t of wrong type"
-	fmt.Printf("%q", notstringerv)             // ERROR "arg notstringerv for printf verb %q of wrong type"
-	fmt.Printf("%t", notstringerv)             // ERROR "arg notstringerv for printf verb %t of wrong type"
-	fmt.Printf("%t", stringerarrayv)           // ERROR "arg stringerarrayv for printf verb %t of wrong type"
-	fmt.Printf("%t", notstringerarrayv)        // ERROR "arg notstringerarrayv for printf verb %t of wrong type"
-	fmt.Printf("%q", notstringerarrayv)        // ERROR "arg notstringerarrayv for printf verb %q of wrong type"
-	fmt.Printf("%d", Formatter(true))          // ERROR "arg Formatter\(true\) for printf verb %d of wrong type: testdata.Formatter"
-	fmt.Printf("%z", FormatterVal(true))       // correct (the type is responsible for formatting)
-	fmt.Printf("%d", FormatterVal(true))       // correct (the type is responsible for formatting)
-	fmt.Printf("%s", nonemptyinterface)        // correct (the type is responsible for formatting)
-	fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type"
-	fmt.Println()                              // not an error
-	fmt.Println("%s", "hi")                    // ERROR "possible formatting directive in Println call"
-	fmt.Println("0.0%")                        // correct (trailing % couldn't be a formatting directive)
-	fmt.Printf("%s", "hi", 3)                  // ERROR "wrong number of args for format in Printf call"
-	_ = fmt.Sprintf("%"+("s"), "hi", 3)        // ERROR "wrong number of args for format in Sprintf call"
-	fmt.Printf("%s%%%d", "hi", 3)              // correct
-	fmt.Printf("%08s", "woo")                  // correct
-	fmt.Printf("% 8s", "woo")                  // correct
-	fmt.Printf("%.*d", 3, 3)                   // correct
-	fmt.Printf("%.*d", 3, 3, 3, 3)             // ERROR "wrong number of args for format in Printf call.*4 args"
-	fmt.Printf("%.*d", "hi", 3)                // ERROR "arg .hi. for \* in printf format not of type int"
-	fmt.Printf("%.*d", i, 3)                   // correct
-	fmt.Printf("%.*d", s, 3)                   // ERROR "arg s for \* in printf format not of type int"
-	fmt.Printf("%*%", 0.22)                    // ERROR "arg 0.22 for \* in printf format not of type int"
-	fmt.Printf("%q %q", multi()...)            // ok
-	fmt.Printf("%#q", `blah`)                  // ok
-	printf("now is the time", "buddy")         // ERROR "no formatting directive"
-	Printf("now is the time", "buddy")         // ERROR "no formatting directive"
-	Printf("hi")                               // ok
+	fmt.Printf("%b", "hi")                      // ERROR "Printf format %b has arg \x22hi\x22 of wrong type string"
+	fmt.Printf("%t", c)                         // ERROR "Printf format %t has arg c of wrong type complex64"
+	fmt.Printf("%t", 1+2i)                      // ERROR "Printf format %t has arg 1 \+ 2i of wrong type complex128"
+	fmt.Printf("%c", 2.3)                       // ERROR "Printf format %c has arg 2.3 of wrong type float64"
+	fmt.Printf("%d", 2.3)                       // ERROR "Printf format %d has arg 2.3 of wrong type float64"
+	fmt.Printf("%e", "hi")                      // ERROR "Printf format %e has arg \x22hi\x22 of wrong type string"
+	fmt.Printf("%E", true)                      // ERROR "Printf format %E has arg true of wrong type bool"
+	fmt.Printf("%f", "hi")                      // ERROR "Printf format %f has arg \x22hi\x22 of wrong type string"
+	fmt.Printf("%F", 'x')                       // ERROR "Printf format %F has arg 'x' of wrong type rune"
+	fmt.Printf("%g", "hi")                      // ERROR "Printf format %g has arg \x22hi\x22 of wrong type string"
+	fmt.Printf("%g", imap)                      // ERROR "Printf format %g has arg imap of wrong type map\[int\]int"
+	fmt.Printf("%G", i)                         // ERROR "Printf format %G has arg i of wrong type int"
+	fmt.Printf("%o", x)                         // ERROR "Printf format %o has arg x of wrong type float64"
+	fmt.Printf("%p", 23)                        // ERROR "Printf format %p has arg 23 of wrong type int"
+	fmt.Printf("%q", x)                         // ERROR "Printf format %q has arg x of wrong type float64"
+	fmt.Printf("%s", b)                         // ERROR "Printf format %s has arg b of wrong type bool"
+	fmt.Printf("%s", byte(65))                  // ERROR "Printf format %s has arg byte\(65\) of wrong type byte"
+	fmt.Printf("%t", 23)                        // ERROR "Printf format %t has arg 23 of wrong type int"
+	fmt.Printf("%U", x)                         // ERROR "Printf format %U has arg x of wrong type float64"
+	fmt.Printf("%x", nil)                       // ERROR "Printf format %x has arg nil of wrong type untyped nil"
+	fmt.Printf("%X", 2.3)                       // ERROR "Printf format %X has arg 2.3 of wrong type float64"
+	fmt.Printf("%s", stringerv)                 // ERROR "Printf format %s has arg stringerv of wrong type testdata.ptrStringer"
+	fmt.Printf("%t", stringerv)                 // ERROR "Printf format %t has arg stringerv of wrong type testdata.ptrStringer"
+	fmt.Printf("%s", embeddedStringerv)         // ERROR "Printf format %s has arg embeddedStringerv of wrong type testdata.embeddedStringer"
+	fmt.Printf("%t", embeddedStringerv)         // ERROR "Printf format %t has arg embeddedStringerv of wrong type testdata.embeddedStringer"
+	fmt.Printf("%q", notstringerv)              // ERROR "Printf format %q has arg notstringerv of wrong type testdata.notstringer"
+	fmt.Printf("%t", notstringerv)              // ERROR "Printf format %t has arg notstringerv of wrong type testdata.notstringer"
+	fmt.Printf("%t", stringerarrayv)            // ERROR "Printf format %t has arg stringerarrayv of wrong type testdata.stringerarray"
+	fmt.Printf("%t", notstringerarrayv)         // ERROR "Printf format %t has arg notstringerarrayv of wrong type testdata.notstringerarray"
+	fmt.Printf("%q", notstringerarrayv)         // ERROR "Printf format %q has arg notstringerarrayv of wrong type testdata.notstringerarray"
+	fmt.Printf("%d", BoolFormatter(true))       // ERROR "Printf format %d has arg BoolFormatter\(true\) of wrong type testdata.BoolFormatter"
+	fmt.Printf("%z", FormatterVal(true))        // correct (the type is responsible for formatting)
+	fmt.Printf("%d", FormatterVal(true))        // correct (the type is responsible for formatting)
+	fmt.Printf("%s", nonemptyinterface)         // correct (the type is responsible for formatting)
+	fmt.Printf("%.*s %d %6g", 3, "hi", 23, 'x') // ERROR "Printf format %6g has arg 'x' of wrong type rune"
+	fmt.Println()                               // not an error
+	fmt.Println("%s", "hi")                     // ERROR "Println call has possible formatting directive %s"
+	fmt.Println("%v", "hi")                     // ERROR "Println call has possible formatting directive %v"
+	fmt.Println("0.0%")                         // correct (trailing % couldn't be a formatting directive)
+	fmt.Printf("%s", "hi", 3)                   // ERROR "Printf call needs 1 arg but has 2 args"
+	_ = fmt.Sprintf("%"+("s"), "hi", 3)         // ERROR "Sprintf call needs 1 arg but has 2 args"
+	fmt.Printf("%s%%%d", "hi", 3)               // correct
+	fmt.Printf("%08s", "woo")                   // correct
+	fmt.Printf("% 8s", "woo")                   // correct
+	fmt.Printf("%.*d", 3, 3)                    // correct
+	fmt.Printf("%.*d x", 3, 3, 3, 3)            // ERROR "Printf call needs 2 args but has 4 args"
+	fmt.Printf("%.*d x", "hi", 3)               // ERROR "Printf format %.*d uses non-int \x22hi\x22 as argument of \*"
+	fmt.Printf("%.*d x", i, 3)                  // correct
+	fmt.Printf("%.*d x", s, 3)                  // ERROR "Printf format %.\*d uses non-int s as argument of \*"
+	fmt.Printf("%*% x", 0.22)                   // ERROR "Printf format %\*% uses non-int 0.22 as argument of \*"
+	fmt.Printf("%q %q", multi()...)             // ok
+	fmt.Printf("%#q", `blah`)                   // ok
+	// printf("now is the time", "buddy")          // no error "printf call has arguments but no formatting directives"
+	Printf("now is the time", "buddy") // ERROR "Printf call has arguments but no formatting directives"
+	Printf("hi")                       // ok
 	const format = "%s %s\n"
 	Printf(format, "hi", "there")
-	Printf(format, "hi")              // ERROR "missing argument for Printf..%s..: format reads arg 2, have only 1"
-	Printf("%s %d %.3v %q", "str", 4) // ERROR "missing argument for Printf..%.3v..: format reads arg 3, have only 2"
-	f := new(stringer)
-	f.Warn(0, "%s", "hello", 3)  // ERROR "possible formatting directive in Warn call"
-	f.Warnf(0, "%s", "hello", 3) // ERROR "wrong number of args for format in Warnf call"
-	f.Warnf(0, "%r", "hello")    // ERROR "unrecognized printf verb"
-	f.Warnf(0, "%#s", "hello")   // ERROR "unrecognized printf flag"
-	Printf("d%", 2)              // ERROR "missing verb at end of format string in Printf call"
+	Printf(format, "hi")              // ERROR "Printf format %s reads arg #2, but call has only 1 arg$"
+	Printf("%s %d %.3v %q", "str", 4) // ERROR "Printf format %.3v reads arg #3, but call has only 2 args"
+	f := new(ptrStringer)
+	f.Warn(0, "%s", "hello", 3)           // ERROR "Warn call has possible formatting directive %s"
+	f.Warnf(0, "%s", "hello", 3)          // ERROR "Warnf call needs 1 arg but has 2 args"
+	f.Warnf(0, "%r", "hello")             // ERROR "Warnf format %r has unknown verb r"
+	f.Warnf(0, "%#s", "hello")            // ERROR "Warnf format %#s has unrecognized flag #"
+	fmt.Printf("%#s", FormatterVal(true)) // correct (the type is responsible for formatting)
+	Printf("d%", 2)                       // ERROR "Printf format % is missing verb at end of string"
 	Printf("%d", percentDV)
 	Printf("%d", &percentDV)
-	Printf("%d", notPercentDV)  // ERROR "arg notPercentDV for printf verb %d of wrong type"
-	Printf("%d", &notPercentDV) // ERROR "arg &notPercentDV for printf verb %d of wrong type"
+	Printf("%d", notPercentDV)  // ERROR "Printf format %d has arg notPercentDV of wrong type testdata.notPercentDStruct"
+	Printf("%d", &notPercentDV) // ERROR "Printf format %d has arg &notPercentDV of wrong type \*testdata.notPercentDStruct"
 	Printf("%p", &notPercentDV) // Works regardless: we print it as a pointer.
 	Printf("%s", percentSV)
 	Printf("%s", &percentSV)
@@ -181,26 +189,22 @@
 	Printf("%[2]*.[1]*[3]d", 2, 3, 4)
 	fmt.Fprintf(os.Stderr, "%[2]*.[1]*[3]d", 2, 3, 4) // Use Fprintf to make sure we count arguments correctly.
 	// Bad argument reorderings.
-	Printf("%[xd", 3)                    // ERROR "bad syntax for printf argument index: \[xd\]"
-	Printf("%[x]d", 3)                   // ERROR "bad syntax for printf argument index: \[x\]"
-	Printf("%[3]*s", "hi", 2)            // ERROR "missing argument for Printf.* reads arg 3, have only 2"
-	_ = fmt.Sprintf("%[3]d", 2)          // ERROR "missing argument for Sprintf.* reads arg 3, have only 1"
-	Printf("%[2]*.[1]*[3]d", 2, "hi", 4) // ERROR "arg .hi. for \* in printf format not of type int"
-	Printf("%[0]s", "arg1")              // ERROR "index value \[0\] for Printf.*; indexes start at 1"
-	Printf("%[0]d", 1)                   // ERROR "index value \[0\] for Printf.*; indexes start at 1"
+	Printf("%[xd", 3)                      // ERROR "Printf format %\[xd is missing closing \]"
+	Printf("%[x]d x", 3)                   // ERROR "Printf format has invalid argument index \[x\]"
+	Printf("%[3]*s x", "hi", 2)            // ERROR "Printf format has invalid argument index \[3\]"
+	_ = fmt.Sprintf("%[3]d x", 2)          // ERROR "Sprintf format has invalid argument index \[3\]"
+	Printf("%[2]*.[1]*[3]d x", 2, "hi", 4) // ERROR "Printf format %\[2]\*\.\[1\]\*\[3\]d uses non-int \x22hi\x22 as argument of \*"
+	Printf("%[0]s x", "arg1")              // ERROR "Printf format has invalid argument index \[0\]"
+	Printf("%[0]d x", 1)                   // ERROR "Printf format has invalid argument index \[0\]"
 	// Something that satisfies the error interface.
 	var e error
 	fmt.Println(e.Error()) // ok
 	// Something that looks like an error interface but isn't, such as the (*T).Error method
 	// in the testing package.
-	var et1 errorTest1
-	fmt.Println(et1.Error())        // ok
-	fmt.Println(et1.Error("hi"))    // ok
-	fmt.Println(et1.Error("%d", 3)) // ERROR "possible formatting directive in Error call"
-	var et2 errorTest2
-	et2.Error()        // ok
-	et2.Error("hi")    // ok, not an error method.
-	et2.Error("%d", 3) // ERROR "possible formatting directive in Error call"
+	var et1 *testing.T
+	et1.Error()        // ok
+	et1.Error("hi")    // ok
+	et1.Error("%d", 3) // ERROR "Error call has possible formatting directive %d"
 	var et3 errorTest3
 	et3.Error() // ok, not an error method.
 	var et4 errorTest4
@@ -213,9 +217,9 @@
 	}
 	fmt.Printf("%f", iface) // ok: fmt treats interfaces as transparent and iface may well have a float concrete type
 	// Can't print a function.
-	Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
-	Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
-	Println(someFunction)      // ERROR "arg someFunction in Println call is a function value, not a function call"
+	Printf("%d", someFunction) // ERROR "Printf format %d arg someFunction is a func value, not called"
+	Printf("%v", someFunction) // ERROR "Printf format %v arg someFunction is a func value, not called"
+	Println(someFunction)      // ERROR "Println arg someFunction is a func value, not called"
 	Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
 	Printf("%T", someFunction) // ok: maybe someone wants to see the type
 	// Bug: used to recur forever.
@@ -224,30 +228,30 @@
 	Printf("%p %x", recursiveSliceV, recursiveSliceV)
 	Printf("%p %x", recursiveMapV, recursiveMapV)
 	// Special handling for Log.
-	math.Log(3)  // OK
-	Log(3)       // OK
-	Log("%d", 3) // ERROR "possible formatting directive in Log call"
-	Logf("%d", 3)
-	Logf("%d", "hi") // ERROR "arg .hi. for printf verb %d of wrong type: string"
+	math.Log(3) // OK
+	var t *testing.T
+	t.Log("%d", 3) // ERROR "Log call has possible formatting directive %d"
+	t.Logf("%d", 3)
+	t.Logf("%d", "hi") // ERROR "Logf format %d has arg \x22hi\x22 of wrong type string"
 
-	Errorf(1, "%d", 3)    // OK
-	Errorf(1, "%d", "hi") // ERROR "arg .hi. for printf verb %d of wrong type: string"
+	// Errorf(1, "%d", 3)    // OK
+	// Errorf(1, "%d", "hi") // no error "Errorf format %d has arg \x22hi\x22 of wrong type string"
 
 	// Multiple string arguments before variadic args
-	errorf("WARNING", "foobar")            // OK
-	errorf("INFO", "s=%s, n=%d", "foo", 1) // OK
-	errorf("ERROR", "%d")                  // ERROR "format reads arg 1, have only 0 args"
+	// errorf("WARNING", "foobar")            // OK
+	// errorf("INFO", "s=%s, n=%d", "foo", 1) // OK
+	// errorf("ERROR", "%d")                  // no error "errorf format %d reads arg #1, but call has only 0 args"
 
 	// Printf from external package
-	externalprintf.Printf("%d", 42) // OK
-	externalprintf.Printf("foobar") // OK
-	level := 123
-	externalprintf.Logf(level, "%d", 42)                        // OK
-	externalprintf.Errorf(level, level, "foo %q bar", "foobar") // OK
-	externalprintf.Logf(level, "%d")                            // ERROR "format reads arg 1, have only 0 args"
-	var formatStr = "%s %s"
-	externalprintf.Sprintf(formatStr, "a", "b")     // OK
-	externalprintf.Logf(level, formatStr, "a", "b") // OK
+	// externalprintf.Printf("%d", 42) // OK
+	// externalprintf.Printf("foobar") // OK
+	// level := 123
+	// externalprintf.Logf(level, "%d", 42)                        // OK
+	// externalprintf.Errorf(level, level, "foo %q bar", "foobar") // OK
+	// externalprintf.Logf(level, "%d")                            // no error "Logf format %d reads arg #1, but call has only 0 args"
+	// var formatStr = "%s %s"
+	// externalprintf.Sprintf(formatStr, "a", "b")     // OK
+	// externalprintf.Logf(level, formatStr, "a", "b") // OK
 
 	// user-defined Println-like functions
 	ss := &someStruct{}
@@ -255,21 +259,31 @@
 	ss.Error(someFunction, someFunction) // OK
 	ss.Println()                         // OK
 	ss.Println(1.234, "foo")             // OK
-	ss.Println(1, someFunction)          // ERROR "arg someFunction in Println call is a function value, not a function call"
+	ss.Println(1, someFunction)          // no error "Println arg someFunction is a func value, not called"
 	ss.log(someFunction)                 // OK
 	ss.log(someFunction, "bar", 1.33)    // OK
-	ss.log(someFunction, someFunction)   // ERROR "arg someFunction in log call is a function value, not a function call"
+	ss.log(someFunction, someFunction)   // no error "log arg someFunction is a func value, not called"
 
 	// indexed arguments
-	Printf("%d %[3]d %d %[2]d", 1, 2, 3, 4)             // OK
-	Printf("%d %[0]d %d %[2]d", 1, 2, 3, 4)             // ERROR "indexes start at 1"
-	Printf("%d %[3]d %d %[-2]d", 1, 2, 3, 4)            // ERROR "bad syntax for printf argument index: \[-2\]"
-	Printf("%d %[3]d %d %[2234234234234]d", 1, 2, 3, 4) // ERROR "bad syntax for printf argument index: .+ value out of range"
-	Printf("%d %[3]d %d %[2]d", 1, 2, 3)                // ERROR "format reads arg 4, have only 3 args"
-	Printf("%d %[3]d %d %[2]d", 1, 2, 3, 4, 5)          // ERROR "wrong number of args for format in Printf call: 4 needed but 5 args"
-	Printf("%[1][3]d", 1, 2)                            // ERROR "unrecognized printf verb '\['"
+	Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4)             // OK
+	Printf("%d %[0]d %d %[2]d x", 1, 2, 3, 4)             // ERROR "Printf format has invalid argument index \[0\]"
+	Printf("%d %[3]d %d %[-2]d x", 1, 2, 3, 4)            // ERROR "Printf format has invalid argument index \[-2\]"
+	Printf("%d %[3]d %d %[2234234234234]d x", 1, 2, 3, 4) // ERROR "Printf format has invalid argument index \[2234234234234\]"
+	Printf("%d %[3]d %-10d %[2]d x", 1, 2, 3)             // ERROR "Printf format %-10d reads arg #4, but call has only 3 args"
+	Printf("%[1][3]d x", 1, 2)                            // ERROR "Printf format %\[1\]\[ has unknown verb \["
+	Printf("%[1]d x", 1, 2)                               // OK
+	Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4, 5)          // OK
+
+	// wrote Println but meant Fprintln
+	Printf("%p\n", os.Stdout)   // OK
+	Println(os.Stdout, "hello") // ERROR "Println does not take io.Writer but has first arg os.Stdout"
+
+	Printf(someString(), "hello") // OK
+
 }
 
+func someString() string { return "X" }
+
 type someStruct struct{}
 
 // Log is non-variadic user-define Println-like function.
@@ -293,6 +307,7 @@
 // A function we use as a function value; it has no other purpose.
 func someFunction() {}
 
+/*
 // Printf is used by the test so we must declare it.
 func Printf(format string, args ...interface{}) {
 	panic("don't call - testing only")
@@ -312,12 +327,14 @@
 func Log(args ...interface{}) {
 	panic("don't call - testing only")
 }
+*/
 
 // printf is used by the test so we must declare it.
 func printf(format string, args ...interface{}) {
 	panic("don't call - testing only")
 }
 
+/*
 // Errorf is used by the test for a case in which the first parameter
 // is not a format string.
 func Errorf(i int, format string, args ...interface{}) {
@@ -329,31 +346,36 @@
 func errorf(level, format string, args ...interface{}) {
 	panic("don't call - testing only")
 }
+*/
 
 // multi is used by the test.
 func multi() []interface{} {
 	panic("don't call - testing only")
 }
 
-type stringer float64
+type stringer int
 
-var stringerv stringer
+func (stringer) String() string { return "string" }
 
-func (*stringer) String() string {
+type ptrStringer float64
+
+var stringerv ptrStringer
+
+func (*ptrStringer) String() string {
 	return "string"
 }
 
-func (*stringer) Warn(int, ...interface{}) string {
+func (*ptrStringer) Warn(int, ...interface{}) string {
 	return "warn"
 }
 
-func (*stringer) Warnf(int, string, ...interface{}) string {
+func (*ptrStringer) Warnf(int, string, ...interface{}) string {
 	return "warnf"
 }
 
 type embeddedStringer struct {
 	foo string
-	stringer
+	ptrStringer
 	bar int
 }
 
@@ -403,7 +425,7 @@
 type percentSStruct struct {
 	a string
 	b []byte
-	c stringerarray
+	C stringerarray
 }
 
 var percentSV percentSStruct
@@ -413,22 +435,23 @@
 func (s recursiveStringer) String() string {
 	_ = fmt.Sprintf("%d", s)
 	_ = fmt.Sprintf("%#v", s)
-	_ = fmt.Sprintf("%v", s)  // ERROR "arg s for printf causes recursive call to String method"
-	_ = fmt.Sprintf("%v", &s) // ERROR "arg &s for printf causes recursive call to String method"
+	_ = fmt.Sprintf("%v", s)  // ERROR "Sprintf format %v with arg s causes recursive String method call"
+	_ = fmt.Sprintf("%v", &s) // ERROR "Sprintf format %v with arg &s causes recursive String method call"
 	_ = fmt.Sprintf("%T", s)  // ok; does not recursively call String
-	return fmt.Sprintln(s)    // ERROR "arg s in Sprintln call causes recursive call to String method"
+	return fmt.Sprintln(s)    // ERROR "Sprintln arg s causes recursive call to String method"
 }
 
 type recursivePtrStringer int
 
 func (p *recursivePtrStringer) String() string {
 	_ = fmt.Sprintf("%v", *p)
-	return fmt.Sprintln(p) // ERROR "arg p in Sprintln call causes recursive call to String method"
+	_ = fmt.Sprint(&p)     // ok; prints address
+	return fmt.Sprintln(p) // ERROR "Sprintln arg p causes recursive call to String method"
 }
 
-type Formatter bool
+type BoolFormatter bool
 
-func (*Formatter) Format(fmt.State, rune) {
+func (*BoolFormatter) Format(fmt.State, rune) {
 }
 
 // Formatter with value receiver
@@ -452,23 +475,108 @@
 var recursiveStructV = &RecursiveStruct{}
 
 type RecursiveStruct1 struct {
-	next *Recursive2Struct
+	next *RecursiveStruct2
 }
 
 type RecursiveStruct2 struct {
-	next *Recursive1Struct
+	next *RecursiveStruct1
 }
 
 var recursiveStruct1V = &RecursiveStruct1{}
 
-// Fix for issue 7149: Missing return type on String method caused fault.
-func (int) String() {
-	return ""
+type unexportedInterface struct {
+	f interface{}
 }
 
-func (s *unknownStruct) Fprintln(w io.Writer, s string) {}
+// Issue 17798: unexported ptrStringer cannot be formatted.
+type unexportedStringer struct {
+	t ptrStringer
+}
+type unexportedStringerOtherFields struct {
+	s string
+	t ptrStringer
+	S string
+}
 
-func UnknownStructFprintln() {
-	s := unknownStruct{}
-	s.Fprintln(os.Stdout, "hello, world!") // OK
+// Issue 17798: unexported error cannot be formatted.
+type unexportedError struct {
+	e error
+}
+type unexportedErrorOtherFields struct {
+	s string
+	e error
+	S string
+}
+
+type errorer struct{}
+
+func (e errorer) Error() string { return "errorer" }
+
+type unexportedCustomError struct {
+	e errorer
+}
+
+type errorInterface interface {
+	error
+	ExtraMethod()
+}
+
+type unexportedErrorInterface struct {
+	e errorInterface
+}
+
+func UnexportedStringerOrError() {
+	fmt.Printf("%s", unexportedInterface{"foo"}) // ok; prints {foo}
+	fmt.Printf("%s", unexportedInterface{3})     // ok; we can't see the problem
+
+	us := unexportedStringer{}
+	fmt.Printf("%s", us)  // ERROR "Printf format %s has arg us of wrong type testdata.unexportedStringer"
+	fmt.Printf("%s", &us) // ERROR "Printf format %s has arg &us of wrong type [*]testdata.unexportedStringer"
+
+	usf := unexportedStringerOtherFields{
+		s: "foo",
+		S: "bar",
+	}
+	fmt.Printf("%s", usf)  // ERROR "Printf format %s has arg usf of wrong type testdata.unexportedStringerOtherFields"
+	fmt.Printf("%s", &usf) // ERROR "Printf format %s has arg &usf of wrong type [*]testdata.unexportedStringerOtherFields"
+
+	ue := unexportedError{
+		e: &errorer{},
+	}
+	fmt.Printf("%s", ue)  // ERROR "Printf format %s has arg ue of wrong type testdata.unexportedError"
+	fmt.Printf("%s", &ue) // ERROR "Printf format %s has arg &ue of wrong type [*]testdata.unexportedError"
+
+	uef := unexportedErrorOtherFields{
+		s: "foo",
+		e: &errorer{},
+		S: "bar",
+	}
+	fmt.Printf("%s", uef)  // ERROR "Printf format %s has arg uef of wrong type testdata.unexportedErrorOtherFields"
+	fmt.Printf("%s", &uef) // ERROR "Printf format %s has arg &uef of wrong type [*]testdata.unexportedErrorOtherFields"
+
+	uce := unexportedCustomError{
+		e: errorer{},
+	}
+	fmt.Printf("%s", uce) // ERROR "Printf format %s has arg uce of wrong type testdata.unexportedCustomError"
+
+	uei := unexportedErrorInterface{}
+	fmt.Printf("%s", uei)       // ERROR "Printf format %s has arg uei of wrong type testdata.unexportedErrorInterface"
+	fmt.Println("foo\n", "bar") // not an error
+
+	fmt.Println("foo\n")  // ERROR "Println arg list ends with redundant newline"
+	fmt.Println("foo\\n") // not an error
+	fmt.Println(`foo\n`)  // not an error
+
+	intSlice := []int{3, 4}
+	fmt.Printf("%s", intSlice) // ERROR "Printf format %s has arg intSlice of wrong type \[\]int"
+	nonStringerArray := [1]unexportedStringer{{}}
+	fmt.Printf("%s", nonStringerArray)  // ERROR "Printf format %s has arg nonStringerArray of wrong type \[1\]testdata.unexportedStringer"
+	fmt.Printf("%s", []stringer{3, 4})  // not an error
+	fmt.Printf("%s", [2]stringer{3, 4}) // not an error
+}
+
+// TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
+// See issues 23598 and 23605.
+func DisableErrorForFlag0() {
+	fmt.Printf("%0t", true)
 }
diff --git a/src/cmd/vet/testdata/rangeloop.go b/src/cmd/vet/testdata/rangeloop.go
index 66223aa..cd3b4cb 100644
--- a/src/cmd/vet/testdata/rangeloop.go
+++ b/src/cmd/vet/testdata/rangeloop.go
@@ -10,24 +10,24 @@
 	var s []int
 	for i, v := range s {
 		go func() {
-			println(i) // ERROR "range variable i captured by func literal"
-			println(v) // ERROR "range variable v captured by func literal"
+			println(i) // ERROR "loop variable i captured by func literal"
+			println(v) // ERROR "loop variable v captured by func literal"
 		}()
 	}
 	for i, v := range s {
 		defer func() {
-			println(i) // ERROR "range variable i captured by func literal"
-			println(v) // ERROR "range variable v captured by func literal"
+			println(i) // ERROR "loop variable i captured by func literal"
+			println(v) // ERROR "loop variable v captured by func literal"
 		}()
 	}
 	for i := range s {
 		go func() {
-			println(i) // ERROR "range variable i captured by func literal"
+			println(i) // ERROR "loop variable i captured by func literal"
 		}()
 	}
 	for _, v := range s {
 		go func() {
-			println(v) // ERROR "range variable v captured by func literal"
+			println(v) // ERROR "loop variable v captured by func literal"
 		}()
 	}
 	for i, v := range s {
@@ -53,7 +53,7 @@
 	var f int
 	for x[0], f = range s {
 		go func() {
-			_ = f // ERROR "range variable f captured by func literal"
+			_ = f // ERROR "loop variable f captured by func literal"
 		}()
 	}
 	type T struct {
@@ -62,7 +62,29 @@
 	for _, v := range s {
 		go func() {
 			_ = T{v: 1}
-			_ = []int{v: 1} // ERROR "range variable v captured by func literal"
+			_ = []int{v: 1} // ERROR "loop variable v captured by func literal"
+		}()
+	}
+
+	// ordinary for-loops
+	for i := 0; i < 10; i++ {
+		go func() {
+			print(i) // ERROR "loop variable i captured by func literal"
+		}()
+	}
+	for i, j := 0, 1; i < 100; i, j = j, i+j {
+		go func() {
+			print(j) // ERROR "loop variable j captured by func literal"
+		}()
+	}
+	type cons struct {
+		car int
+		cdr *cons
+	}
+	var head *cons
+	for p := head; p != nil; p = p.next {
+		go func() {
+			print(p.car) // ERROR "loop variable p captured by func literal"
 		}()
 	}
 }
diff --git a/src/cmd/vet/testdata/shift.go b/src/cmd/vet/testdata/shift.go
index 50a042e..73cbaf8 100644
--- a/src/cmd/vet/testdata/shift.go
+++ b/src/cmd/vet/testdata/shift.go
@@ -6,7 +6,10 @@
 
 package testdata
 
-import "unsafe"
+import (
+	"fmt"
+	"unsafe"
+)
 
 func ShiftTest() {
 	var i8 int8
@@ -154,6 +157,6 @@
 	// Make sure other vet checks work in dead code.
 	if iBits == 1024 {
 		_ = i << 512                  // OK
-		fmt.Printf("foo %s bar", 123) // ERROR "arg 123 for printf verb %s of wrong type: untyped int"
+		fmt.Printf("foo %s bar", 123) // ERROR "Printf"
 	}
 }
diff --git a/src/cmd/vet/testdata/structtag.go b/src/cmd/vet/testdata/structtag.go
index 363aa89..c87e42f 100644
--- a/src/cmd/vet/testdata/structtag.go
+++ b/src/cmd/vet/testdata/structtag.go
@@ -80,3 +80,23 @@
 		AnonymousXML `xml:"b,attr"` // ERROR "struct field AnonymousXML repeats xml attribute tag .b. also at testdata/structtag.go:76"
 	}
 }
+
+type UnexpectedSpacetest struct {
+	A int `json:"a,omitempty"`
+	B int `json:"b, omitempty"` // ERROR "suspicious space in struct tag value"
+	C int `json:"c ,omitempty"`
+	D int `json:"d,omitempty, string"` // ERROR "suspicious space in struct tag value"
+	E int `xml:"e local"`
+	F int `xml:"f "`                 // ERROR "suspicious space in struct tag value"
+	G int `xml:" g"`                 // ERROR "suspicious space in struct tag value"
+	H int `xml:"h ,omitempty"`       // ERROR "suspicious space in struct tag value"
+	I int `xml:"i, omitempty"`       // ERROR "suspicious space in struct tag value"
+	J int `xml:"j local ,omitempty"` // ERROR "suspicious space in struct tag value"
+	K int `xml:"k local, omitempty"` // ERROR "suspicious space in struct tag value"
+	L int `xml:" l local,omitempty"` // ERROR "suspicious space in struct tag value"
+	M int `xml:"m  local,omitempty"` // ERROR "suspicious space in struct tag value"
+	N int `xml:" "`                  // ERROR "suspicious space in struct tag value"
+	O int `xml:""`
+	P int `xml:","`
+	Q int `foo:" doesn't care "`
+}
diff --git a/src/cmd/vet/tests.go b/src/cmd/vet/tests.go
index 8c051f1..5b15708 100644
--- a/src/cmd/vet/tests.go
+++ b/src/cmd/vet/tests.go
@@ -161,7 +161,7 @@
 type reporter func(format string, args ...interface{})
 
 // checkTestFunctions walks Test, Benchmark and Example functions checking
-// malformed names, wrong signatures and examples documenting inexistent
+// malformed names, wrong signatures and examples documenting nonexistent
 // identifiers.
 func checkTestFunctions(f *File, node ast.Node) {
 	if !strings.HasSuffix(f.name, "_test.go") {
diff --git a/src/cmd/vet/types.go b/src/cmd/vet/types.go
index 77bd1c1..1f30b4b 100644
--- a/src/cmd/vet/types.go
+++ b/src/cmd/vet/types.go
@@ -19,11 +19,9 @@
 var stdImporter types.Importer
 
 var (
-	errorType        *types.Interface
-	stringerType     *types.Interface // possibly nil
-	formatterType    *types.Interface // possibly nil
-	httpResponseType types.Type       // possibly nil
-	httpClientType   types.Type       // possibly nil
+	errorType     *types.Interface
+	stringerType  *types.Interface // possibly nil
+	formatterType *types.Interface // possibly nil
 )
 
 func inittypes() {
@@ -35,12 +33,16 @@
 	if typ := importType("fmt", "Formatter"); typ != nil {
 		formatterType = typ.Underlying().(*types.Interface)
 	}
-	if typ := importType("net/http", "Response"); typ != nil {
-		httpResponseType = typ
+}
+
+// isNamedType reports whether t is the named type path.name.
+func isNamedType(t types.Type, path, name string) bool {
+	n, ok := t.(*types.Named)
+	if !ok {
+		return false
 	}
-	if typ := importType("net/http", "Client"); typ != nil {
-		httpClientType = typ
-	}
+	obj := n.Obj()
+	return obj.Name() == name && obj.Pkg() != nil && obj.Pkg().Path() == path
 }
 
 // importType returns the type denoted by the qualified identifier
@@ -60,7 +62,7 @@
 	return nil
 }
 
-func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
+func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) []error {
 	if stdImporter == nil {
 		if *source {
 			stdImporter = importer.For("source", nil)
@@ -74,13 +76,17 @@
 	pkg.selectors = make(map[*ast.SelectorExpr]*types.Selection)
 	pkg.spans = make(map[types.Object]Span)
 	pkg.types = make(map[ast.Expr]types.TypeAndValue)
+
+	var allErrors []error
 	config := types.Config{
 		// We use the same importer for all imports to ensure that
 		// everybody sees identical packages for the given paths.
 		Importer: stdImporter,
 		// By providing a Config with our own error function, it will continue
-		// past the first error. There is no need for that function to do anything.
-		Error: func(error) {},
+		// past the first error. We collect them all for printing later.
+		Error: func(e error) {
+			allErrors = append(allErrors, e)
+		},
 
 		Sizes: archSizes,
 	}
@@ -91,6 +97,9 @@
 		Uses:       pkg.uses,
 	}
 	typesPkg, err := config.Check(pkg.path, fs, astFiles, info)
+	if len(allErrors) == 0 && err != nil {
+		allErrors = append(allErrors, err)
+	}
 	pkg.typesPkg = typesPkg
 	// update spans
 	for id, obj := range pkg.defs {
@@ -99,7 +108,7 @@
 	for id, obj := range pkg.uses {
 		pkg.growSpan(id, obj)
 	}
-	return err
+	return allErrors
 }
 
 // matchArgType reports an error if printf verb t is not appropriate
@@ -134,10 +143,8 @@
 		return true
 	}
 	// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
-	if t&argString != 0 {
-		if types.AssertableTo(errorType, typ) || stringerType != nil && types.AssertableTo(stringerType, typ) {
-			return true
-		}
+	if t&argString != 0 && isConvertibleToString(typ) {
+		return true
 	}
 
 	typ = typ.Underlying()
@@ -165,7 +172,7 @@
 			return true // %s matches []byte
 		}
 		// Recur: []int matches %d.
-		return t&argPointer != 0 || f.matchArgTypeInternal(t, typ.Elem().Underlying(), arg, inProgress)
+		return t&argPointer != 0 || f.matchArgTypeInternal(t, typ.Elem(), arg, inProgress)
 
 	case *types.Slice:
 		// Same as array.
@@ -261,6 +268,22 @@
 	return false
 }
 
+func isConvertibleToString(typ types.Type) bool {
+	if bt, ok := typ.(*types.Basic); ok && bt.Kind() == types.UntypedNil {
+		// We explicitly don't want untyped nil, which is
+		// convertible to both of the interfaces below, as it
+		// would just panic anyway.
+		return false
+	}
+	if types.ConvertibleTo(typ, errorType) {
+		return true // via .Error()
+	}
+	if stringerType != nil && types.ConvertibleTo(typ, stringerType) {
+		return true // via .String()
+	}
+	return false
+}
+
 // hasBasicType reports whether x's type is a types.Basic with the given kind.
 func (f *File) hasBasicType(x ast.Expr, kind types.BasicKind) bool {
 	t := f.pkg.types[x].Type
@@ -275,7 +298,12 @@
 // type. For instance, with "%d" all the elements must be printable with the "%d" format.
 func (f *File) matchStructArgType(t printfArgType, typ *types.Struct, arg ast.Expr, inProgress map[types.Type]bool) bool {
 	for i := 0; i < typ.NumFields(); i++ {
-		if !f.matchArgTypeInternal(t, typ.Field(i).Type(), arg, inProgress) {
+		typf := typ.Field(i)
+		if !f.matchArgTypeInternal(t, typf.Type(), arg, inProgress) {
+			return false
+		}
+		if t&argString != 0 && !typf.Exported() && isConvertibleToString(typf.Type()) {
+			// Issue #17798: unexported Stringer or error cannot be properly fomatted.
 			return false
 		}
 	}
diff --git a/src/cmd/vet/unused.go b/src/cmd/vet/unused.go
index df2317a..02fcd84 100644
--- a/src/cmd/vet/unused.go
+++ b/src/cmd/vet/unused.go
@@ -82,7 +82,7 @@
 		}
 	} else if !ok {
 		// package-qualified function (e.g. fmt.Errorf)
-		obj, _ := f.pkg.uses[selector.Sel]
+		obj := f.pkg.uses[selector.Sel]
 		if obj, ok := obj.(*types.Func); ok {
 			qname := obj.Pkg().Path() + "." + obj.Name()
 			if unusedFuncs[qname] {
diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go
index 8db8ff4..f654d46 100644
--- a/src/cmd/vet/vet_test.go
+++ b/src/cmd/vet/vet_test.go
@@ -12,6 +12,7 @@
 	"os/exec"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"sync"
 	"testing"
 )
@@ -105,9 +106,17 @@
 	}
 	batch := make([][]string, wide)
 	for i, file := range gos {
+		// TODO: Remove print.go exception once we require type checking for everything,
+		// and then delete TestVetPrint.
+		if strings.HasSuffix(file, "print.go") {
+			continue
+		}
 		batch[i%wide] = append(batch[i%wide], file)
 	}
 	for i, files := range batch {
+		if len(files) == 0 {
+			continue
+		}
 		files := files
 		t.Run(fmt.Sprint(i), func(t *testing.T) {
 			t.Parallel()
@@ -117,6 +126,21 @@
 	}
 }
 
+func TestVetPrint(t *testing.T) {
+	Build(t)
+	errchk := filepath.Join(runtime.GOROOT(), "test", "errchk")
+	cmd := exec.Command(
+		errchk,
+		"go", "vet", "-vettool=./"+binary,
+		"-printf",
+		"-printfuncs=Warn:1,Warnf:1",
+		"testdata/print.go",
+	)
+	if !run(cmd, t) {
+		t.Fatal("vet command failed")
+	}
+}
+
 func TestVetAsm(t *testing.T) {
 	Build(t)
 
diff --git a/src/compress/bzip2/bzip2.go b/src/compress/bzip2/bzip2.go
index 4278844..f07c7e8 100644
--- a/src/compress/bzip2/bzip2.go
+++ b/src/compress/bzip2/bzip2.go
@@ -163,7 +163,7 @@
 func (bz2 *reader) read(buf []byte) (int, error) {
 	for {
 		n := bz2.readFromBlock(buf)
-		if n > 0 {
+		if n > 0 || len(buf) == 0 {
 			bz2.blockCRC = updateCRC(bz2.blockCRC, buf[:n])
 			return n, nil
 		}
diff --git a/src/compress/bzip2/bzip2_test.go b/src/compress/bzip2/bzip2_test.go
index a6c3080..3848603 100644
--- a/src/compress/bzip2/bzip2_test.go
+++ b/src/compress/bzip2/bzip2_test.go
@@ -204,6 +204,14 @@
 	}
 }
 
+func TestZeroRead(t *testing.T) {
+	b := mustDecodeHex("425a6839314159265359b5aa5098000000600040000004200021008283177245385090b5aa5098")
+	r := NewReader(bytes.NewReader(b))
+	if n, err := r.Read(nil); n != 0 || err != nil {
+		t.Errorf("Read(nil) = (%d, %v), want (0, nil)", n, err)
+	}
+}
+
 var (
 	digits = mustLoadFile("testdata/e.txt.bz2")
 	twain  = mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
diff --git a/src/compress/flate/huffman_bit_writer.go b/src/compress/flate/huffman_bit_writer.go
index 6cd6281..f42a921 100644
--- a/src/compress/flate/huffman_bit_writer.go
+++ b/src/compress/flate/huffman_bit_writer.go
@@ -54,23 +54,15 @@
 	0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
 	4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
 	9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
-	/* extended window */
-	14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20,
 }
 
 var offsetBase = []uint32{
-	/* normal deflate */
 	0x000000, 0x000001, 0x000002, 0x000003, 0x000004,
 	0x000006, 0x000008, 0x00000c, 0x000010, 0x000018,
 	0x000020, 0x000030, 0x000040, 0x000060, 0x000080,
 	0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300,
 	0x000400, 0x000600, 0x000800, 0x000c00, 0x001000,
 	0x001800, 0x002000, 0x003000, 0x004000, 0x006000,
-
-	/* extended window */
-	0x008000, 0x00c000, 0x010000, 0x018000, 0x020000,
-	0x030000, 0x040000, 0x060000, 0x080000, 0x0c0000,
-	0x100000, 0x180000, 0x200000, 0x300000,
 }
 
 // The odd order in which the codegen code sizes are written.
diff --git a/src/compress/gzip/gunzip.go b/src/compress/gzip/gunzip.go
index 8bd750b..85d52e8 100644
--- a/src/compress/gzip/gunzip.go
+++ b/src/compress/gzip/gunzip.go
@@ -66,7 +66,7 @@
 // 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
+// The Reader will return an 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
diff --git a/src/container/heap/heap_test.go b/src/container/heap/heap_test.go
index d411104..f19f9cf 100644
--- a/src/container/heap/heap_test.go
+++ b/src/container/heap/heap_test.go
@@ -33,6 +33,7 @@
 }
 
 func (h myHeap) verify(t *testing.T, i int) {
+	t.Helper()
 	n := h.Len()
 	j1 := 2*i + 1
 	j2 := 2*i + 2
diff --git a/src/container/list/list.go b/src/container/list/list.go
index 0256768..dc4260e 100644
--- a/src/container/list/list.go
+++ b/src/container/list/list.go
@@ -65,7 +65,7 @@
 // The complexity is O(1).
 func (l *List) Len() int { return l.len }
 
-// Front returns the first element of list l or nil.
+// Front returns the first element of list l or nil if the list is empty.
 func (l *List) Front() *Element {
 	if l.len == 0 {
 		return nil
@@ -73,7 +73,7 @@
 	return l.root.next
 }
 
-// Back returns the last element of list l or nil.
+// Back returns the last element of list l or nil if the list is empty.
 func (l *List) Back() *Element {
 	if l.len == 0 {
 		return nil
@@ -118,6 +118,7 @@
 
 // Remove removes e from l if e is an element of list l.
 // It returns the element value e.Value.
+// The element must not be nil.
 func (l *List) Remove(e *Element) interface{} {
 	if e.list == l {
 		// if e.list == l, l must have been initialized when e was inserted
@@ -141,6 +142,7 @@
 
 // InsertBefore inserts a new element e with value v immediately before mark and returns e.
 // If mark is not an element of l, the list is not modified.
+// The mark must not be nil.
 func (l *List) InsertBefore(v interface{}, mark *Element) *Element {
 	if mark.list != l {
 		return nil
@@ -151,6 +153,7 @@
 
 // InsertAfter inserts a new element e with value v immediately after mark and returns e.
 // If mark is not an element of l, the list is not modified.
+// The mark must not be nil.
 func (l *List) InsertAfter(v interface{}, mark *Element) *Element {
 	if mark.list != l {
 		return nil
@@ -161,6 +164,7 @@
 
 // MoveToFront moves element e to the front of list l.
 // If e is not an element of l, the list is not modified.
+// The element must not be nil.
 func (l *List) MoveToFront(e *Element) {
 	if e.list != l || l.root.next == e {
 		return
@@ -171,6 +175,7 @@
 
 // MoveToBack moves element e to the back of list l.
 // If e is not an element of l, the list is not modified.
+// The element must not be nil.
 func (l *List) MoveToBack(e *Element) {
 	if e.list != l || l.root.prev == e {
 		return
@@ -181,6 +186,7 @@
 
 // MoveBefore moves element e to its new position before mark.
 // If e or mark is not an element of l, or e == mark, the list is not modified.
+// The element and mark must not be nil.
 func (l *List) MoveBefore(e, mark *Element) {
 	if e.list != l || e == mark || mark.list != l {
 		return
@@ -190,6 +196,7 @@
 
 // MoveAfter moves element e to its new position after mark.
 // If e or mark is not an element of l, or e == mark, the list is not modified.
+// The element and mark must not be nil.
 func (l *List) MoveAfter(e, mark *Element) {
 	if e.list != l || e == mark || mark.list != l {
 		return
@@ -198,7 +205,7 @@
 }
 
 // PushBackList inserts a copy of an other list at the back of list l.
-// The lists l and other may be the same.
+// The lists l and other may be the same. They must not be nil.
 func (l *List) PushBackList(other *List) {
 	l.lazyInit()
 	for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
@@ -207,7 +214,7 @@
 }
 
 // PushFrontList inserts a copy of an other list at the front of list l.
-// The lists l and other may be the same.
+// The lists l and other may be the same. They must not be nil.
 func (l *List) PushFrontList(other *List) {
 	l.lazyInit()
 	for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
diff --git a/src/container/ring/example_test.go b/src/container/ring/example_test.go
new file mode 100644
index 0000000..30bd0d7
--- /dev/null
+++ b/src/container/ring/example_test.go
@@ -0,0 +1,193 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ring_test
+
+import (
+	"container/ring"
+	"fmt"
+)
+
+func ExampleRing_Len() {
+	// Create a new ring of size 4
+	r := ring.New(4)
+
+	// Print out its length
+	fmt.Println(r.Len())
+
+	// Output:
+	// 4
+}
+
+func ExampleRing_Next() {
+	// Create a new ring of size 5
+	r := ring.New(5)
+
+	// Get the length of the ring
+	n := r.Len()
+
+	// Initialize the ring with some integer values
+	for i := 0; i < n; i++ {
+		r.Value = i
+		r = r.Next()
+	}
+
+	// Iterate through the ring and print its contents
+	for j := 0; j < n; j++ {
+		fmt.Println(r.Value)
+		r = r.Next()
+	}
+
+	// Output:
+	// 0
+	// 1
+	// 2
+	// 3
+	// 4
+}
+
+func ExampleRing_Prev() {
+	// Create a new ring of size 5
+	r := ring.New(5)
+
+	// Get the length of the ring
+	n := r.Len()
+
+	// Initialize the ring with some integer values
+	for i := 0; i < n; i++ {
+		r.Value = i
+		r = r.Next()
+	}
+
+	// Iterate through the ring backwards and print its contents
+	for j := 0; j < n; j++ {
+		r = r.Prev()
+		fmt.Println(r.Value)
+	}
+
+	// Output:
+	// 4
+	// 3
+	// 2
+	// 1
+	// 0
+}
+
+func ExampleRing_Do() {
+	// Create a new ring of size 5
+	r := ring.New(5)
+
+	// Get the length of the ring
+	n := r.Len()
+
+	// Initialize the ring with some integer values
+	for i := 0; i < n; i++ {
+		r.Value = i
+		r = r.Next()
+	}
+
+	// Iterate through the ring and print its contents
+	r.Do(func(p interface{}) {
+		fmt.Println(p.(int))
+	})
+
+	// Output:
+	// 0
+	// 1
+	// 2
+	// 3
+	// 4
+}
+
+func ExampleRing_Move() {
+	// Create a new ring of size 5
+	r := ring.New(5)
+
+	// Get the length of the ring
+	n := r.Len()
+
+	// Initialize the ring with some integer values
+	for i := 0; i < n; i++ {
+		r.Value = i
+		r = r.Next()
+	}
+
+	// Move the pointer forward by three steps
+	r = r.Move(3)
+
+	// Iterate through the ring and print its contents
+	r.Do(func(p interface{}) {
+		fmt.Println(p.(int))
+	})
+
+	// Output:
+	// 3
+	// 4
+	// 0
+	// 1
+	// 2
+}
+
+func ExampleRing_Link() {
+	// Create two rings, r and s, of size 2
+	r := ring.New(2)
+	s := ring.New(2)
+
+	// Get the length of the ring
+	lr := r.Len()
+	ls := s.Len()
+
+	// Initialize r with 0s
+	for i := 0; i < lr; i++ {
+		r.Value = 0
+		r = r.Next()
+	}
+
+	// Initialize s with 1s
+	for j := 0; j < ls; j++ {
+		s.Value = 1
+		s = s.Next()
+	}
+
+	// Link ring r and ring s
+	rs := r.Link(s)
+
+	// Iterate through the combined ring and print its contents
+	rs.Do(func(p interface{}) {
+		fmt.Println(p.(int))
+	})
+
+	// Output:
+	// 0
+	// 0
+	// 1
+	// 1
+}
+
+func ExampleRing_Unlink() {
+	// Create a new ring of size 6
+	r := ring.New(6)
+
+	// Get the length of the ring
+	n := r.Len()
+
+	// Initialize the ring with some integer values
+	for i := 0; i < n; i++ {
+		r.Value = i
+		r = r.Next()
+	}
+
+	// Unlink three elements from r, starting from r.Next()
+	r.Unlink(3)
+
+	// Iterate through the remaining ring and print its contents
+	r.Do(func(p interface{}) {
+		fmt.Println(p.(int))
+	})
+
+	// Output:
+	// 0
+	// 4
+	// 5
+}
diff --git a/src/context/benchmark_test.go b/src/context/benchmark_test.go
index b792327..3c526dd 100644
--- a/src/context/benchmark_test.go
+++ b/src/context/benchmark_test.go
@@ -7,10 +7,64 @@
 import (
 	. "context"
 	"fmt"
+	"runtime"
+	"sync"
 	"testing"
+	"time"
 )
 
-func BenchmarkContextCancelTree(b *testing.B) {
+func BenchmarkWithTimeout(b *testing.B) {
+	for concurrency := 40; concurrency <= 4e5; concurrency *= 100 {
+		name := fmt.Sprintf("concurrency=%d", concurrency)
+		b.Run(name, func(b *testing.B) {
+			benchmarkWithTimeout(b, concurrency)
+		})
+	}
+}
+
+func benchmarkWithTimeout(b *testing.B, concurrentContexts int) {
+	gomaxprocs := runtime.GOMAXPROCS(0)
+	perPContexts := concurrentContexts / gomaxprocs
+	root := Background()
+
+	// Generate concurrent contexts.
+	var wg sync.WaitGroup
+	ccf := make([][]CancelFunc, gomaxprocs)
+	for i := range ccf {
+		wg.Add(1)
+		go func(i int) {
+			defer wg.Done()
+			cf := make([]CancelFunc, perPContexts)
+			for j := range cf {
+				_, cf[j] = WithTimeout(root, time.Hour)
+			}
+			ccf[i] = cf
+		}(i)
+	}
+	wg.Wait()
+
+	b.ResetTimer()
+	b.RunParallel(func(pb *testing.PB) {
+		wcf := make([]CancelFunc, 10)
+		for pb.Next() {
+			for i := range wcf {
+				_, wcf[i] = WithTimeout(root, time.Hour)
+			}
+			for _, f := range wcf {
+				f()
+			}
+		}
+	})
+	b.StopTimer()
+
+	for _, cf := range ccf {
+		for _, f := range cf {
+			f()
+		}
+	}
+}
+
+func BenchmarkCancelTree(b *testing.B) {
 	depths := []int{1, 10, 100, 1000}
 	for _, d := range depths {
 		b.Run(fmt.Sprintf("depth=%d", d), func(b *testing.B) {
diff --git a/src/context/context.go b/src/context/context.go
index 892ff27..06580e0 100644
--- a/src/context/context.go
+++ b/src/context/context.go
@@ -136,7 +136,7 @@
 	// 	// userKey is the key for user.User values in Contexts. It is
 	// 	// unexported; clients use user.NewContext and user.FromContext
 	// 	// instead of using this key directly.
-	// 	var userKey key = 0
+	// 	var userKey key
 	//
 	// 	// NewContext returns a new Context that carries value u.
 	// 	func NewContext(ctx context.Context, u *User) context.Context {
@@ -380,25 +380,25 @@
 //
 // Canceling this context releases resources associated with it, so code should
 // call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
-	if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
+func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
+	if cur, ok := parent.Deadline(); ok && cur.Before(d) {
 		// The current deadline is already sooner than the new one.
 		return WithCancel(parent)
 	}
 	c := &timerCtx{
 		cancelCtx: newCancelCtx(parent),
-		deadline:  deadline,
+		deadline:  d,
 	}
 	propagateCancel(parent, c)
-	d := time.Until(deadline)
-	if d <= 0 {
+	dur := time.Until(d)
+	if dur <= 0 {
 		c.cancel(true, DeadlineExceeded) // deadline has already passed
 		return c, func() { c.cancel(true, Canceled) }
 	}
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	if c.err == nil {
-		c.timer = time.AfterFunc(d, func() {
+		c.timer = time.AfterFunc(dur, func() {
 			c.cancel(true, DeadlineExceeded)
 		})
 	}
diff --git a/src/context/example_test.go b/src/context/example_test.go
index 2d48d4e..b2c2aa9 100644
--- a/src/context/example_test.go
+++ b/src/context/example_test.go
@@ -52,7 +52,7 @@
 	// 5
 }
 
-// This example passes a context with a arbitrary deadline to tell a blocking
+// This example passes a context with an arbitrary deadline to tell a blocking
 // function that it should abandon its work as soon as it gets to it.
 func ExampleWithDeadline() {
 	d := time.Now().Add(50 * time.Millisecond)
diff --git a/src/crypto/aes/asm_ppc64le.s b/src/crypto/aes/asm_ppc64le.s
index 05e0018..a69cb78 100644
--- a/src/crypto/aes/asm_ppc64le.s
+++ b/src/crypto/aes/asm_ppc64le.s
@@ -2,21 +2,23 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This is a derived work from OpenSSL of AES using assembly optimizations. The
-// original code was written by Andy Polyakov <appro@openssl.org> and it's dual
-// licensed under OpenSSL and CRYPTOGAMS licenses depending on where you obtain
-// it. For further details see http://www.openssl.org/~appro/cryptogams/.
+// Based on CRYPTOGAMS code with the following comment:
+// # ====================================================================
+// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+// # project. The module is, however, dual licensed under OpenSSL and
+// # CRYPTOGAMS licenses depending on where you obtain it. For further
+// # details see http://www.openssl.org/~appro/cryptogams/.
+// # ====================================================================
 
 // Original code can be found at the link below:
-// https://git.openssl.org/?p=openssl.git;a=blob;f=crypto/aes/asm/aesp8-ppc.pl
+// https://github.com/dot-asm/cryptogams/blob/master/ppc/aesp8-ppc.pl
 
-// The code is based on 627c953376 from 4 Jun 2016. I changed some function
-// names in order to be more likely to go standards. For instance, function
-// aes_p8_set_{en,de}crypt_key become set{En,De}cryptKeyAsm. I also split
-// setEncryptKeyAsm in two parts and a new session was created
-// (doEncryptKeyAsm). This was necessary to avoid arguments overwriting when
-// setDecryptKeyAsm calls setEncryptKeyAsm. There were other modifications as
-// well but kept the same functionality.
+// I changed some function names in order to be more likely to go standards.
+// For instance, function aes_p8_set_{en,de}crypt_key become
+// set{En,De}cryptKeyAsm. I also split setEncryptKeyAsm in two parts
+// and a new session was created (doEncryptKeyAsm). This was necessary to
+// avoid arguments overwriting when setDecryptKeyAsm calls setEncryptKeyAsm.
+// There were other modifications as well but kept the same functionality.
 
 #include "textflag.h"
 
diff --git a/src/crypto/aes/asm_s390x.s b/src/crypto/aes/asm_s390x.s
index 2cf3ddd..cbeb622 100644
--- a/src/crypto/aes/asm_s390x.s
+++ b/src/crypto/aes/asm_s390x.s
@@ -150,3 +150,65 @@
 	MVC     $16, (R1), (R8)
 	MOVD	$0, R0
 	RET
+
+// func supportsKMA() bool
+TEXT ·supportsKMA(SB),NOSPLIT,$24-1
+	MOVD	$tmp-24(SP), R1
+	MOVD	$2, R0       // store 24-bytes
+	XC	$24, (R1), (R1)
+	WORD	$0xb2b01000  // STFLE (R1)
+	MOVWZ	16(R1), R2
+	ANDW	$(1<<13), R2 // test bit 146 (message-security-assist 8)
+	BEQ	no
+
+	MOVD	$0, R0       // KMA-Query
+	XC	$16, (R1), (R1)
+	WORD	$0xb9296024  // kma %r6,%r2,%r4
+	MOVWZ	(R1), R2
+	WORD	$0xa7213800  // TMLL R2, $0x3800
+	BVS	yes
+no:
+	MOVB	$0, ret+0(FP)
+	RET
+yes:
+	MOVB	$1, ret+0(FP)
+	RET
+
+// func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
+TEXT ·kmaGCM(SB),NOSPLIT,$112-120
+	MOVD	fn+0(FP), R0
+	MOVD	$params-112(SP), R1
+
+	// load ptr/len pairs
+	LMG	dst+32(FP), R2, R3 // R2=base R3=len
+	LMG	src+56(FP), R4, R5 // R4=base R5=len
+	LMG	aad+80(FP), R6, R7 // R6=base R7=len
+
+	// setup parameters
+	MOVD	cnt+112(FP), R8
+	XC	$12, (R1), (R1)     // reserved
+	MVC	$4, 12(R8), 12(R1)  // set chain value
+	MVC	$16, (R8), 64(R1)   // set initial counter value
+	XC	$32, 16(R1), 16(R1) // set hash subkey and tag
+	SLD	$3, R7, R12
+	MOVD	R12, 48(R1)         // set total AAD length
+	SLD	$3, R5, R12
+	MOVD	R12, 56(R1)         // set total plaintext/ciphertext length
+
+	LMG	key+8(FP), R8, R9   // R8=base R9=len
+	MVC	$16, (R8), 80(R1)   // set key
+	CMPBEQ	R9, $16, kma
+	MVC	$8, 16(R8), 96(R1)
+	CMPBEQ	R9, $24, kma
+	MVC	$8, 24(R8), 104(R1)
+
+kma:
+	WORD	$0xb9296024 // kma %r6,%r2,%r4
+	BVS	kma
+
+	MOVD	tag+104(FP), R2
+	MVC	$16, 16(R1), 0(R2) // copy tag to output
+	MOVD	cnt+112(FP), R8
+	MVC	$4, 12(R1), 12(R8) // update counter value
+
+	RET
diff --git a/src/crypto/aes/ctr_s390x.go b/src/crypto/aes/ctr_s390x.go
index 94dea5c..8078aa6 100644
--- a/src/crypto/aes/ctr_s390x.go
+++ b/src/crypto/aes/ctr_s390x.go
@@ -64,6 +64,10 @@
 }
 
 func (c *aesctr) XORKeyStream(dst, src []byte) {
+	if len(src) > 0 {
+		// Assert len(dst) >= len(src)
+		_ = dst[len(src)-1]
+	}
 	for len(src) > 0 {
 		if len(c.buffer) == 0 {
 			c.refill()
diff --git a/src/crypto/aes/gcm_amd64.s b/src/crypto/aes/gcm_amd64.s
index c25badd..c1fc923 100644
--- a/src/crypto/aes/gcm_amd64.s
+++ b/src/crypto/aes/gcm_amd64.s
@@ -324,6 +324,20 @@
 #define tPtr CX
 #define autLen DX
 
+#define reduceRound(a) 	MOVOU POLY, T0;	PCLMULQDQ $0x01, a, T0; PSHUFD $78, a, a; PXOR T0, a
+#define mulRoundAAD(X ,i) \
+	MOVOU (16*(i*2))(pTbl), T1;\
+	MOVOU T1, T2;\
+	PCLMULQDQ $0x00, X, T1;\
+	PXOR T1, ACC0;\
+	PCLMULQDQ $0x11, X, T2;\
+	PXOR T2, ACC1;\
+	PSHUFD $78, X, T1;\
+	PXOR T1, X;\
+	MOVOU (16*(i*2+1))(pTbl), T1;\
+	PCLMULQDQ $0x00, X, T1;\
+	PXOR T1, ACCM
+
 	MOVQ productTable+0(FP), pTbl
 	MOVQ data_base+8(FP), aut
 	MOVQ data_len+16(FP), autLen
@@ -333,15 +347,18 @@
 	MOVOU bswapMask<>(SB), BSWAP
 	MOVOU gcmPoly<>(SB), POLY
 
-	MOVOU (16*14)(pTbl), T1
-	MOVOU (16*15)(pTbl), T2
-
 	TESTQ autLen, autLen
 	JEQ dataBail
 
 	CMPQ autLen, $13	// optimize the TLS case
-	JNE dataSinglesLoop
+	JE dataTLS
+	CMPQ autLen, $128
+	JB startSinglesLoop
+	JMP dataOctaLoop
 
+dataTLS:
+	MOVOU (16*14)(pTbl), T1
+	MOVOU (16*15)(pTbl), T2
 	PXOR B0, B0
 	MOVQ (aut), B0
 	PINSRD $2, 8(aut), B0
@@ -349,6 +366,63 @@
 	XORQ autLen, autLen
 	JMP dataMul
 
+dataOctaLoop:
+		CMPQ autLen, $128
+		JB startSinglesLoop
+		SUBQ $128, autLen
+
+		MOVOU (16*0)(aut), X0
+		MOVOU (16*1)(aut), X1
+		MOVOU (16*2)(aut), X2
+		MOVOU (16*3)(aut), X3
+		MOVOU (16*4)(aut), X4
+		MOVOU (16*5)(aut), X5
+		MOVOU (16*6)(aut), X6
+		MOVOU (16*7)(aut), X7
+		LEAQ (16*8)(aut), aut
+		PSHUFB BSWAP, X0
+		PSHUFB BSWAP, X1
+		PSHUFB BSWAP, X2
+		PSHUFB BSWAP, X3
+		PSHUFB BSWAP, X4
+		PSHUFB BSWAP, X5
+		PSHUFB BSWAP, X6
+		PSHUFB BSWAP, X7
+		PXOR ACC0, X0
+
+		MOVOU (16*0)(pTbl), ACC0
+		MOVOU (16*1)(pTbl), ACCM
+		MOVOU ACC0, ACC1
+		PSHUFD $78, X0, T1
+		PXOR X0, T1
+		PCLMULQDQ $0x00, X0, ACC0
+		PCLMULQDQ $0x11, X0, ACC1
+		PCLMULQDQ $0x00, T1, ACCM
+
+		mulRoundAAD(X1, 1)
+		mulRoundAAD(X2, 2)
+		mulRoundAAD(X3, 3)
+		mulRoundAAD(X4, 4)
+		mulRoundAAD(X5, 5)
+		mulRoundAAD(X6, 6)
+		mulRoundAAD(X7, 7)
+
+		PXOR ACC0, ACCM
+		PXOR ACC1, ACCM
+		MOVOU ACCM, T0
+		PSRLDQ $8, ACCM
+		PSLLDQ $8, T0
+		PXOR ACCM, ACC1
+		PXOR T0, ACC0
+		reduceRound(ACC0)
+		reduceRound(ACC0)
+		PXOR ACC1, ACC0
+	JMP dataOctaLoop
+
+startSinglesLoop:
+	MOVOU (16*14)(pTbl), T1
+	MOVOU (16*15)(pTbl), T2
+
 dataSinglesLoop:
 
 		CMPQ autLen, $16
@@ -438,7 +512,6 @@
 #define aesRnd(k) AESENC k, B0; AESENC k, B1; AESENC k, B2; AESENC k, B3; AESENC k, B4; AESENC k, B5; AESENC k, B6; AESENC k, B7
 #define aesRound(i) MOVOU (16*i)(ks), T0;AESENC T0, B0; AESENC T0, B1; AESENC T0, B2; AESENC T0, B3; AESENC T0, B4; AESENC T0, B5; AESENC T0, B6; AESENC T0, B7
 #define aesRndLast(k) AESENCLAST k, B0; AESENCLAST k, B1; AESENCLAST k, B2; AESENCLAST k, B3; AESENCLAST k, B4; AESENCLAST k, B5; AESENCLAST k, B6; AESENCLAST k, B7
-#define reduceRound(a) 	MOVOU POLY, T0;	PCLMULQDQ $0x01, a, T0; PSHUFD $78, a, a; PXOR T0, a
 #define combinedRound(i) \
 	MOVOU (16*i)(ks), T0;\
 	AESENC T0, B0;\
diff --git a/src/crypto/aes/gcm_s390x.go b/src/crypto/aes/gcm_s390x.go
index 438310d..055a9a9 100644
--- a/src/crypto/aes/gcm_s390x.go
+++ b/src/crypto/aes/gcm_s390x.go
@@ -10,6 +10,11 @@
 	"errors"
 )
 
+// This file contains two implementations of AES-GCM. The first implementation
+// (gcmAsm) uses the KMCTR instruction to encrypt using AES in counter mode and
+// the KIMD instruction for GHASH. The second implementation (gcmKMA) uses the
+// newer KMA instruction which performs both operations.
+
 // gcmCount represents a 16-byte big-endian count value.
 type gcmCount [16]byte
 
@@ -71,12 +76,16 @@
 func (c *aesCipherAsm) NewGCM(nonceSize int) (cipher.AEAD, error) {
 	var hk gcmHashKey
 	c.Encrypt(hk[:], hk[:])
-	g := &gcmAsm{
+	g := gcmAsm{
 		block:     c,
 		hashKey:   hk,
 		nonceSize: nonceSize,
 	}
-	return g, nil
+	if hasKMA {
+		g := gcmKMA{g}
+		return &g, nil
+	}
+	return &g, nil
 }
 
 func (g *gcmAsm) NonceSize() int {
@@ -268,3 +277,90 @@
 	g.counterCrypt(out, ciphertext, &counter)
 	return ret, nil
 }
+
+// supportsKMA reports whether the message-security-assist 8 facility is available.
+// This function call may be expensive so hasKMA should be queried instead.
+func supportsKMA() bool
+
+// hasKMA contains the result of supportsKMA.
+var hasKMA = supportsKMA()
+
+// gcmKMA implements the cipher.AEAD interface using the KMA instruction. It should
+// only be used if hasKMA is true.
+type gcmKMA struct {
+	gcmAsm
+}
+
+// flags for the KMA instruction
+const (
+	kmaHS      = 1 << 10 // hash subkey supplied
+	kmaLAAD    = 1 << 9  // last series of additional authenticated data
+	kmaLPC     = 1 << 8  // last series of plaintext or ciphertext blocks
+	kmaDecrypt = 1 << 7  // decrypt
+)
+
+// kmaGCM executes the encryption or decryption operation given by fn. The tag
+// will be calculated and written to tag. cnt should contain the current
+// counter state and will be overwritten with the updated counter state.
+// TODO(mundaym): could pass in hash subkey
+//go:noescape
+func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
+
+// Seal encrypts and authenticates plaintext. See the cipher.AEAD interface for
+// details.
+func (g *gcmKMA) Seal(dst, nonce, plaintext, data []byte) []byte {
+	if len(nonce) != g.nonceSize {
+		panic("cipher: incorrect nonce length given to GCM")
+	}
+	if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize {
+		panic("cipher: message too large for GCM")
+	}
+
+	ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
+
+	counter := g.deriveCounter(nonce)
+	fc := g.block.function | kmaLAAD | kmaLPC
+
+	var tag [gcmTagSize]byte
+	kmaGCM(fc, g.block.key, out[:len(plaintext)], plaintext, data, &tag, &counter)
+	copy(out[len(plaintext):], tag[:])
+
+	return ret
+}
+
+// Open authenticates and decrypts ciphertext. See the cipher.AEAD interface
+// for details.
+func (g *gcmKMA) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
+	if len(nonce) != g.nonceSize {
+		panic("cipher: incorrect nonce length given to GCM")
+	}
+	if len(ciphertext) < gcmTagSize {
+		return nil, errOpen
+	}
+	if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize {
+		return nil, errOpen
+	}
+
+	tag := ciphertext[len(ciphertext)-gcmTagSize:]
+	ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
+	ret, out := sliceForAppend(dst, len(ciphertext))
+
+	counter := g.deriveCounter(nonce)
+	fc := g.block.function | kmaLAAD | kmaLPC | kmaDecrypt
+
+	var expectedTag [gcmTagSize]byte
+	kmaGCM(fc, g.block.key, out[:len(ciphertext)], ciphertext, data, &expectedTag, &counter)
+
+	if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 {
+		// The AESNI code decrypts and authenticates concurrently, and
+		// so overwrites dst in the event of a tag mismatch. That
+		// behavior is mimicked here in order to be consistent across
+		// platforms.
+		for i := range out {
+			out[i] = 0
+		}
+		return nil, errOpen
+	}
+
+	return ret, nil
+}
diff --git a/src/crypto/cipher/benchmark_test.go b/src/crypto/cipher/benchmark_test.go
index 93c40d0..1a3f1bd 100644
--- a/src/crypto/cipher/benchmark_test.go
+++ b/src/crypto/cipher/benchmark_test.go
@@ -10,6 +10,21 @@
 	"testing"
 )
 
+func benchmarkAESGCMSign(b *testing.B, buf []byte) {
+	b.SetBytes(int64(len(buf)))
+
+	var key [16]byte
+	var nonce [12]byte
+	aes, _ := aes.NewCipher(key[:])
+	aesgcm, _ := cipher.NewGCM(aes)
+	var out []byte
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		out = aesgcm.Seal(out[:0], nonce[:], nil, buf)
+	}
+}
+
 func benchmarkAESGCMSeal(b *testing.B, buf []byte) {
 	b.SetBytes(int64(len(buf)))
 
@@ -54,6 +69,10 @@
 	benchmarkAESGCMOpen(b, make([]byte, 1024))
 }
 
+func BenchmarkAESGCMSign8K(b *testing.B) {
+	benchmarkAESGCMSign(b, make([]byte, 8*1024))
+}
+
 func BenchmarkAESGCMSeal8K(b *testing.B) {
 	benchmarkAESGCMSeal(b, make([]byte, 8*1024))
 }
diff --git a/src/crypto/cipher/cipher.go b/src/crypto/cipher/cipher.go
index 531ecad..31c14d7 100644
--- a/src/crypto/cipher/cipher.go
+++ b/src/crypto/cipher/cipher.go
@@ -17,21 +17,26 @@
 	BlockSize() int
 
 	// Encrypt encrypts the first block in src into dst.
-	// Dst and src may point at the same memory.
+	// Dst and src must overlap entirely or not at all.
 	Encrypt(dst, src []byte)
 
 	// Decrypt decrypts the first block in src into dst.
-	// Dst and src may point at the same memory.
+	// Dst and src must overlap entirely or not at all.
 	Decrypt(dst, src []byte)
 }
 
 // A Stream represents a stream cipher.
 type Stream interface {
 	// XORKeyStream XORs each byte in the given slice with a byte from the
-	// cipher's key stream. Dst and src may point to the same memory.
+	// cipher's key stream. Dst and src must overlap entirely or not at all.
+	//
 	// If len(dst) < len(src), XORKeyStream should panic. It is acceptable
 	// to pass a dst bigger than src, and in that case, XORKeyStream will
 	// only update dst[:len(src)] and will not touch the rest of dst.
+	//
+	// Multiple calls to XORKeyStream behave as if the concatenation of
+	// the src buffers was passed in a single run. That is, Stream
+	// maintains state and does not reset at each XORKeyStream call.
 	XORKeyStream(dst, src []byte)
 }
 
@@ -42,8 +47,16 @@
 	BlockSize() int
 
 	// CryptBlocks encrypts or decrypts a number of blocks. The length of
-	// src must be a multiple of the block size. Dst and src may point to
-	// the same memory.
+	// src must be a multiple of the block size. Dst and src must overlap
+	// entirely or not at all.
+	//
+	// If len(dst) < len(src), CryptBlocks should panic. It is acceptable
+	// to pass a dst bigger than src, and in that case, CryptBlocks will
+	// only update dst[:len(src)] and will not touch the rest of dst.
+	//
+	// Multiple calls to CryptBlocks behave as if the concatenation of
+	// the src buffers was passed in a single run. That is, BlockMode
+	// maintains state and does not reset at each CryptBlocks call.
 	CryptBlocks(dst, src []byte)
 }
 
diff --git a/src/crypto/cipher/example_test.go b/src/crypto/cipher/example_test.go
index 956cc2e..6e050a9 100644
--- a/src/crypto/cipher/example_test.go
+++ b/src/crypto/cipher/example_test.go
@@ -15,9 +15,12 @@
 )
 
 func ExampleNewGCM_encrypt() {
-	// The key argument should be the AES key, either 16 or 32 bytes
-	// to select AES-128 or AES-256.
-	key := []byte("AES256Key-32Characters1234567890")
+	// Load your secret key from a safe place and reuse it across multiple
+	// Seal/Open calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
+	key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574")
 	plaintext := []byte("exampleplaintext")
 
 	block, err := aes.NewCipher(key)
@@ -41,12 +44,14 @@
 }
 
 func ExampleNewGCM_decrypt() {
-	// The key argument should be the AES key, either 16 or 32 bytes
-	// to select AES-128 or AES-256.
-	key := []byte("AES256Key-32Characters1234567890")
-	ciphertext, _ := hex.DecodeString("1019aa66cd7c024f9efd0038899dae1973ee69427f5a6579eba292ffe1b5a260")
-
-	nonce, _ := hex.DecodeString("37b8e8a308c354048d245f6d")
+	// Load your secret key from a safe place and reuse it across multiple
+	// Seal/Open calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
+	key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574")
+	ciphertext, _ := hex.DecodeString("c3aaa29f002ca75870806e44086700f62ce4d43e902b3888e23ceff797a7a471")
+	nonce, _ := hex.DecodeString("64a9433eae7ccceee2fc0eda")
 
 	block, err := aes.NewCipher(key)
 	if err != nil {
@@ -68,8 +73,12 @@
 }
 
 func ExampleNewCBCDecrypter() {
-	key := []byte("example key 1234")
-	ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
+	ciphertext, _ := hex.DecodeString("73c86d43a9d700a253a96c85b0f6b03ac9792e0e757f869cca306bd3cba1c62b")
 
 	block, err := aes.NewCipher(key)
 	if err != nil {
@@ -107,7 +116,11 @@
 }
 
 func ExampleNewCBCEncrypter() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 	plaintext := []byte("exampleplaintext")
 
 	// CBC mode works on blocks so plaintexts may need to be padded to the
@@ -142,8 +155,12 @@
 }
 
 func ExampleNewCFBDecrypter() {
-	key := []byte("example key 1234")
-	ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
+	ciphertext, _ := hex.DecodeString("7dd015f06bec7f1b8f6559dad89f4131da62261786845100056b353194ad")
 
 	block, err := aes.NewCipher(key)
 	if err != nil {
@@ -167,7 +184,11 @@
 }
 
 func ExampleNewCFBEncrypter() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 	plaintext := []byte("some plaintext")
 
 	block, err := aes.NewCipher(key)
@@ -189,10 +210,15 @@
 	// 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 ExampleNewCTR() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 	plaintext := []byte("some plaintext")
 
 	block, err := aes.NewCipher(key)
@@ -227,7 +253,11 @@
 }
 
 func ExampleNewOFB() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 	plaintext := []byte("some plaintext")
 
 	block, err := aes.NewCipher(key)
@@ -262,7 +292,11 @@
 }
 
 func ExampleStreamReader() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 
 	inFile, err := os.Open("encrypted-file")
 	if err != nil {
@@ -299,7 +333,11 @@
 }
 
 func ExampleStreamWriter() {
-	key := []byte("example key 1234")
+	// Load your secret key from a safe place and reuse it across multiple
+	// NewCipher calls. (Obviously don't use this example key for anything
+	// real.) If you want to convert a passphrase to a key, use a suitable
+	// package like bcrypt or scrypt.
+	key, _ := hex.DecodeString("6368616e676520746869732070617373")
 
 	inFile, err := os.Open("plaintext-file")
 	if err != nil {
diff --git a/src/crypto/cipher/gcm.go b/src/crypto/cipher/gcm.go
index 62085aa..28f3ddd 100644
--- a/src/crypto/cipher/gcm.go
+++ b/src/crypto/cipher/gcm.go
@@ -26,7 +26,7 @@
 	// slice. The nonce must be NonceSize() bytes long and unique for all
 	// time, for a given key.
 	//
-	// The plaintext and dst may alias exactly or not at all. To reuse
+	// The plaintext and dst must overlap exactly or not at all. To reuse
 	// plaintext's storage for the encrypted output, use plaintext[:0] as dst.
 	Seal(dst, nonce, plaintext, additionalData []byte) []byte
 
@@ -36,7 +36,7 @@
 	// bytes long and both it and the additional data must match the
 	// value passed to Seal.
 	//
-	// The ciphertext and dst may alias exactly or not at all. To reuse
+	// The ciphertext and dst must overlap exactly or not at all. To reuse
 	// ciphertext's storage for the decrypted output, use ciphertext[:0] as dst.
 	//
 	// Even if the function fails, the contents of dst, up to its capacity,
diff --git a/src/crypto/cipher/io.go b/src/crypto/cipher/io.go
index 3938c0a..0974ac7 100644
--- a/src/crypto/cipher/io.go
+++ b/src/crypto/cipher/io.go
@@ -37,10 +37,8 @@
 	c := make([]byte, len(src))
 	w.S.XORKeyStream(c, src)
 	n, err = w.W.Write(c)
-	if n != len(src) {
-		if err == nil { // should never happen
-			err = io.ErrShortWrite
-		}
+	if n != len(src) && err == nil { // should never happen
+		err = io.ErrShortWrite
 	}
 	return
 }
diff --git a/src/crypto/cipher/ofb.go b/src/crypto/cipher/ofb.go
index e86ebcb..7b35f89 100644
--- a/src/crypto/cipher/ofb.go
+++ b/src/crypto/cipher/ofb.go
@@ -19,7 +19,7 @@
 func NewOFB(b Block, iv []byte) Stream {
 	blockSize := b.BlockSize()
 	if len(iv) != blockSize {
-		return nil
+		panic("cipher.NewOFB: IV length must equal block size")
 	}
 	bufSize := streamBufferSize
 	if bufSize < blockSize {
diff --git a/src/crypto/cipher/xor.go b/src/crypto/cipher/xor.go
index 01ca0a9..5b26eac 100644
--- a/src/crypto/cipher/xor.go
+++ b/src/crypto/cipher/xor.go
@@ -19,6 +19,11 @@
 	if len(b) < n {
 		n = len(b)
 	}
+	if n == 0 {
+		return 0
+	}
+	// Assert dst has enough space
+	_ = dst[n-1]
 
 	w := n / wordSize
 	if w > 0 {
@@ -48,8 +53,8 @@
 	return n
 }
 
-// xorBytes xors the bytes in a and b. The destination is assumed to have enough
-// space. Returns the number of bytes xor'd.
+// xorBytes xors the bytes in a and b. The destination should have enough
+// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.
 func xorBytes(dst, a, b []byte) int {
 	if supportsUnaligned {
 		return fastXORBytes(dst, a, b)
diff --git a/src/crypto/dsa/dsa.go b/src/crypto/dsa/dsa.go
index bc0c3e3..e945855 100644
--- a/src/crypto/dsa/dsa.go
+++ b/src/crypto/dsa/dsa.go
@@ -37,7 +37,7 @@
 // this error must be handled.
 var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
 
-// ParameterSizes is a enumeration of the acceptable bit lengths of the primes
+// ParameterSizes is an enumeration of the acceptable bit lengths of the primes
 // in a set of DSA parameters. See FIPS 186-3, section 4.2.
 type ParameterSizes int
 
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index 02848fd..755ed28 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -49,7 +49,7 @@
 	X, Y *big.Int
 }
 
-// PrivateKey represents a ECDSA private key.
+// PrivateKey represents an ECDSA private key.
 type PrivateKey struct {
 	PublicKey
 	D *big.Int
@@ -64,12 +64,15 @@
 	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)
+// Sign signs digest with priv, reading randomness from rand. The opts argument
+// is not currently used but, in keeping with the crypto.Signer interface,
+// should be the hash function used to digest the message.
+//
+// This method implements crypto.Signer, which is an interface 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, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+	r, s, err := Sign(rand, priv, digest)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
index 9546f67..9224a03 100644
--- a/src/crypto/ecdsa/ecdsa_test.go
+++ b/src/crypto/ecdsa/ecdsa_test.go
@@ -48,10 +48,13 @@
 	hashed := []byte("testing")
 	priv, _ := GenerateKey(p256, rand.Reader)
 
+	b.ReportAllocs()
 	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _, _ = Sign(rand.Reader, priv, hashed)
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			_, _, _ = Sign(rand.Reader, priv, hashed)
+		}
+	})
 }
 
 func BenchmarkSignP384(b *testing.B) {
@@ -60,10 +63,13 @@
 	hashed := []byte("testing")
 	priv, _ := GenerateKey(p384, rand.Reader)
 
+	b.ReportAllocs()
 	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _, _ = Sign(rand.Reader, priv, hashed)
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			_, _, _ = Sign(rand.Reader, priv, hashed)
+		}
+	})
 }
 
 func BenchmarkVerifyP256(b *testing.B) {
@@ -73,20 +79,26 @@
 	priv, _ := GenerateKey(p256, rand.Reader)
 	r, s, _ := Sign(rand.Reader, priv, hashed)
 
+	b.ReportAllocs()
 	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		Verify(&priv.PublicKey, hashed, r, s)
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Verify(&priv.PublicKey, hashed, r, s)
+		}
+	})
 }
 
 func BenchmarkKeyGeneration(b *testing.B) {
 	b.ResetTimer()
 	p256 := elliptic.P256()
 
+	b.ReportAllocs()
 	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		GenerateKey(p256, rand.Reader)
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			GenerateKey(p256, rand.Reader)
+		}
+	})
 }
 
 func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) {
@@ -331,3 +343,25 @@
 	testNegativeInputs(t, elliptic.P384(), "p384")
 	testNegativeInputs(t, elliptic.P521(), "p521")
 }
+
+func TestZeroHashSignature(t *testing.T) {
+	zeroHash := make([]byte, 64)
+
+	for _, curve := range []elliptic.Curve{elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521()} {
+		privKey, err := GenerateKey(curve, rand.Reader)
+		if err != nil {
+			panic(err)
+		}
+
+		// Sign a hash consisting of all zeros.
+		r, s, err := Sign(rand.Reader, privKey, zeroHash)
+		if err != nil {
+			panic(err)
+		}
+
+		// Confirm that it can be verified.
+		if !Verify(&privKey.PublicKey, zeroHash, r, s) {
+			t.Errorf("zero hash signature verify failed for %T", curve)
+		}
+	}
+}
diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
index d352724..35aacf2 100644
--- a/src/crypto/elliptic/elliptic.go
+++ b/src/crypto/elliptic/elliptic.go
@@ -301,7 +301,7 @@
 	return
 }
 
-// Marshal converts a point into the form specified in section 4.3.6 of ANSI X9.62.
+// Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
 func Marshal(curve Curve, x, y *big.Int) []byte {
 	byteLen := (curve.Params().BitSize + 7) >> 3
 
@@ -316,7 +316,8 @@
 }
 
 // Unmarshal converts a point, serialized by Marshal, into an x, y pair.
-// It is an error if the point is not on the curve. On error, x = nil.
+// It is an error if the point is not in uncompressed form or is not on the curve.
+// On error, x = nil.
 func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
 	byteLen := (curve.Params().BitSize + 7) >> 3
 	if len(data) != 1+2*byteLen {
@@ -325,10 +326,14 @@
 	if data[0] != 4 { // uncompressed form
 		return
 	}
+	p := curve.Params().P
 	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
 	y = new(big.Int).SetBytes(data[1+byteLen:])
+	if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 {
+		return nil, nil
+	}
 	if !curve.IsOnCurve(x, y) {
-		x, y = nil, nil
+		return nil, nil
 	}
 	return
 }
diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go
index c3e4c17..f661359 100644
--- a/src/crypto/elliptic/elliptic_test.go
+++ b/src/crypto/elliptic/elliptic_test.go
@@ -455,15 +455,81 @@
 	}
 }
 
+type synthCombinedMult struct {
+	Curve
+}
+
+func (s synthCombinedMult) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
+	x1, y1 := s.ScalarBaseMult(baseScalar)
+	x2, y2 := s.ScalarMult(bigX, bigY, scalar)
+	return s.Add(x1, y1, x2, y2)
+}
+
+func TestCombinedMult(t *testing.T) {
+	type combinedMult interface {
+		Curve
+		CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
+	}
+
+	p256, ok := P256().(combinedMult)
+	if !ok {
+		p256 = &synthCombinedMult{P256()}
+	}
+
+	gx := p256.Params().Gx
+	gy := p256.Params().Gy
+
+	zero := make([]byte, 32)
+	one := make([]byte, 32)
+	one[31] = 1
+	two := make([]byte, 32)
+	two[31] = 2
+
+	// 0×G + 0×G = ∞
+	x, y := p256.CombinedMult(gx, gy, zero, zero)
+	if x.Sign() != 0 || y.Sign() != 0 {
+		t.Errorf("0×G + 0×G = (%d, %d), should be ∞", x, y)
+	}
+
+	// 1×G + 0×G = G
+	x, y = p256.CombinedMult(gx, gy, one, zero)
+	if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
+		t.Errorf("1×G + 0×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
+	}
+
+	// 0×G + 1×G = G
+	x, y = p256.CombinedMult(gx, gy, zero, one)
+	if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
+		t.Errorf("0×G + 1×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
+	}
+
+	// 1×G + 1×G = 2×G
+	x, y = p256.CombinedMult(gx, gy, one, one)
+	ggx, ggy := p256.ScalarBaseMult(two)
+	if x.Cmp(ggx) != 0 || y.Cmp(ggy) != 0 {
+		t.Errorf("1×G + 1×G = (%d, %d), should be (%d, %d)", x, y, ggx, ggy)
+	}
+
+	minusOne := new(big.Int).Sub(p256.Params().N, big.NewInt(1))
+	// 1×G + (-1)×G = ∞
+	x, y = p256.CombinedMult(gx, gy, one, minusOne.Bytes())
+	if x.Sign() != 0 || y.Sign() != 0 {
+		t.Errorf("1×G + (-1)×G = (%d, %d), should be ∞", x, y)
+	}
+}
+
 func BenchmarkBaseMult(b *testing.B) {
 	b.ResetTimer()
 	p224 := P224()
 	e := p224BaseMultTests[25]
 	k, _ := new(big.Int).SetString(e.k, 10)
+	b.ReportAllocs()
 	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		p224.ScalarBaseMult(k.Bytes())
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p224.ScalarBaseMult(k.Bytes())
+		}
+	})
 }
 
 func BenchmarkBaseMultP256(b *testing.B) {
@@ -471,10 +537,13 @@
 	p256 := P256()
 	e := p224BaseMultTests[25]
 	k, _ := new(big.Int).SetString(e.k, 10)
+	b.ReportAllocs()
 	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		p256.ScalarBaseMult(k.Bytes())
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p256.ScalarBaseMult(k.Bytes())
+		}
+	})
 }
 
 func BenchmarkScalarMultP256(b *testing.B) {
@@ -483,10 +552,13 @@
 	_, x, y, _ := GenerateKey(p256, rand.Reader)
 	priv, _, _, _ := GenerateKey(p256, rand.Reader)
 
+	b.ReportAllocs()
 	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		p256.ScalarMult(x, y, priv)
-	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p256.ScalarMult(x, y, priv)
+		}
+	})
 }
 
 func TestMarshal(t *testing.T) {
@@ -517,3 +589,42 @@
 		t.Error("P224 failed to validate a correct point")
 	}
 }
+
+// See https://golang.org/issues/20482
+func TestUnmarshalToLargeCoordinates(t *testing.T) {
+	curve := P256()
+	p := curve.Params().P
+
+	invalidX, invalidY := make([]byte, 65), make([]byte, 65)
+	invalidX[0], invalidY[0] = 4, 4 // uncompressed encoding
+
+	// Set x to be greater than curve's parameter P – specifically, to P+5.
+	// Set y to mod_sqrt(x^3 - 3x + B)) so that (x mod P = 5 , y) is on the
+	// curve.
+	x := new(big.Int).Add(p, big.NewInt(5))
+	y, _ := new(big.Int).SetString("31468013646237722594854082025316614106172411895747863909393730389177298123724", 10)
+
+	copy(invalidX[1:], x.Bytes())
+	copy(invalidX[33:], y.Bytes())
+
+	if X, Y := Unmarshal(curve, invalidX); X != nil || Y != nil {
+		t.Errorf("Unmarshal accpets invalid X coordinate")
+	}
+
+	// This is a point on the curve with a small y value, small enough that we can add p and still be within 32 bytes.
+	x, _ = new(big.Int).SetString("31931927535157963707678568152204072984517581467226068221761862915403492091210", 10)
+	y, _ = new(big.Int).SetString("5208467867388784005506817585327037698770365050895731383201516607147", 10)
+	y.Add(y, p)
+
+	if p.Cmp(y) > 0 || y.BitLen() != 256 {
+		t.Fatal("y not within expected range")
+	}
+
+	// marshal
+	copy(invalidY[1:], x.Bytes())
+	copy(invalidY[33:], y.Bytes())
+
+	if X, Y := Unmarshal(curve, invalidY); X != nil || Y != nil {
+		t.Errorf("Unmarshal accpets invalid Y coordinate")
+	}
+}
diff --git a/src/crypto/elliptic/p256_amd64.go b/src/crypto/elliptic/p256_amd64.go
index 66b7cf8..6f8c999 100644
--- a/src/crypto/elliptic/p256_amd64.go
+++ b/src/crypto/elliptic/p256_amd64.go
@@ -52,44 +52,62 @@
 
 // Functions implemented in p256_asm_amd64.s
 // Montgomery multiplication modulo P256
+//go:noescape
 func p256Mul(res, in1, in2 []uint64)
 
 // Montgomery square modulo P256
+//go:noescape
 func p256Sqr(res, in []uint64)
 
 // Montgomery multiplication by 1
+//go:noescape
 func p256FromMont(res, in []uint64)
 
 // iff cond == 1  val <- -val
+//go:noescape
 func p256NegCond(val []uint64, cond int)
 
 // if cond == 0 res <- b; else res <- a
+//go:noescape
 func p256MovCond(res, a, b []uint64, cond int)
 
 // Endianness swap
+//go:noescape
 func p256BigToLittle(res []uint64, in []byte)
+
+//go:noescape
 func p256LittleToBig(res []byte, in []uint64)
 
 // Constant time table access
+//go:noescape
 func p256Select(point, table []uint64, idx int)
+
+//go:noescape
 func p256SelectBase(point, table []uint64, idx int)
 
 // Montgomery multiplication modulo Ord(G)
+//go:noescape
 func p256OrdMul(res, in1, in2 []uint64)
 
 // Montgomery square modulo Ord(G), repeated n times
+//go:noescape
 func p256OrdSqr(res, in []uint64, n int)
 
 // Point add with in2 being affine point
 // If sign == 1 -> in2 = -in2
 // If sel == 0 -> res = in1
 // if zero == 0 -> res = in2
+//go:noescape
 func p256PointAddAffineAsm(res, in1, in2 []uint64, sign, sel, zero int)
 
-// Point add
-func p256PointAddAsm(res, in1, in2 []uint64)
+// Point add. Returns one if the two input points were equal and zero
+// otherwise. (Note that, due to the way that the equations work out, some
+// representations of ∞ are considered equal to everything by this function.)
+//go:noescape
+func p256PointAddAsm(res, in1, in2 []uint64) int
 
 // Point double
+//go:noescape
 func p256PointDoubleAsm(res, in []uint64)
 
 func (curve p256Curve) Inverse(k *big.Int) *big.Int {
@@ -213,9 +231,11 @@
 	scalarReversed := make([]uint64, 4)
 	var r1, r2 p256Point
 	p256GetScalar(scalarReversed, baseScalar)
+	r1IsInfinity := scalarIsZero(scalarReversed)
 	r1.p256BaseMult(scalarReversed)
 
 	p256GetScalar(scalarReversed, scalar)
+	r2IsInfinity := scalarIsZero(scalarReversed)
 	fromBig(r2.xyz[0:4], maybeReduceModP(bigX))
 	fromBig(r2.xyz[4:8], maybeReduceModP(bigY))
 	p256Mul(r2.xyz[0:4], r2.xyz[0:4], rr[:])
@@ -228,8 +248,15 @@
 	r2.xyz[11] = 0x00000000fffffffe
 
 	r2.p256ScalarMult(scalarReversed)
-	p256PointAddAsm(r1.xyz[:], r1.xyz[:], r2.xyz[:])
-	return r1.p256PointToAffine()
+
+	var sum, double p256Point
+	pointsEqual := p256PointAddAsm(sum.xyz[:], r1.xyz[:], r2.xyz[:])
+	p256PointDoubleAsm(double.xyz[:], r1.xyz[:])
+	sum.CopyConditional(&double, pointsEqual)
+	sum.CopyConditional(&r1, r2IsInfinity)
+	sum.CopyConditional(&r2, r1IsInfinity)
+
+	return sum.p256PointToAffine()
 }
 
 func (curve p256Curve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
@@ -260,6 +287,24 @@
 	return r.p256PointToAffine()
 }
 
+// uint64IsZero returns 1 if x is zero and zero otherwise.
+func uint64IsZero(x uint64) int {
+	x = ^x
+	x &= x >> 32
+	x &= x >> 16
+	x &= x >> 8
+	x &= x >> 4
+	x &= x >> 2
+	x &= x >> 1
+	return int(x & 1)
+}
+
+// scalarIsZero returns 1 if scalar represents the zero value, and zero
+// otherwise.
+func scalarIsZero(scalar []uint64) int {
+	return uint64IsZero(scalar[0] | scalar[1] | scalar[2] | scalar[3])
+}
+
 func (p *p256Point) p256PointToAffine() (x, y *big.Int) {
 	zInv := make([]uint64, 4)
 	zInvSq := make([]uint64, 4)
@@ -281,6 +326,17 @@
 	return new(big.Int).SetBytes(xOut), new(big.Int).SetBytes(yOut)
 }
 
+// CopyConditional copies overwrites p with src if v == 1, and leaves p
+// unchanged if v == 0.
+func (p *p256Point) CopyConditional(src *p256Point, v int) {
+	pMask := uint64(v) - 1
+	srcMask := ^pMask
+
+	for i, n := range p.xyz {
+		p.xyz[i] = (n & pMask) | (src.xyz[i] & srcMask)
+	}
+}
+
 // p256Inverse sets out to in^-1 mod p.
 func p256Inverse(out, in []uint64) {
 	var stack [6 * 4]uint64
diff --git a/src/crypto/elliptic/p256_asm_amd64.s b/src/crypto/elliptic/p256_asm_amd64.s
index ea4a6fa..3f9d624 100644
--- a/src/crypto/elliptic/p256_asm_amd64.s
+++ b/src/crypto/elliptic/p256_asm_amd64.s
@@ -81,17 +81,23 @@
 	PCMPEQL X13, X12
 
 	MOVOU X12, X0
-	PANDN (16*0)(x_ptr), X0
+	MOVOU (16*0)(x_ptr), X6
+	PANDN X6, X0
 	MOVOU X12, X1
-	PANDN (16*1)(x_ptr), X1
+	MOVOU (16*1)(x_ptr), X7
+	PANDN X7, X1
 	MOVOU X12, X2
-	PANDN (16*2)(x_ptr), X2
+	MOVOU (16*2)(x_ptr), X8
+	PANDN X8, X2
 	MOVOU X12, X3
-	PANDN (16*3)(x_ptr), X3
+	MOVOU (16*3)(x_ptr), X9
+	PANDN X9, X3
 	MOVOU X12, X4
-	PANDN (16*4)(x_ptr), X4
+	MOVOU (16*4)(x_ptr), X10
+	PANDN X10, X4
 	MOVOU X12, X5
-	PANDN (16*5)(x_ptr), X5
+	MOVOU (16*5)(x_ptr), X11
+	PANDN X11, X5
 
 	MOVOU (16*0)(y_ptr), X6
 	MOVOU (16*1)(y_ptr), X7
@@ -1972,6 +1978,36 @@
 #undef rptr
 #undef sel_save
 #undef zero_save
+
+// p256IsZero returns 1 in AX if [acc4..acc7] represents zero and zero
+// otherwise. It writes to [acc4..acc7], t0 and t1.
+TEXT p256IsZero(SB),NOSPLIT,$0
+	// AX contains a flag that is set if the input is zero.
+	XORQ AX, AX
+	MOVQ $1, t1
+
+	// Check whether [acc4..acc7] are all zero.
+	MOVQ acc4, t0
+	ORQ acc5, t0
+	ORQ acc6, t0
+	ORQ acc7, t0
+
+	// Set the zero flag if so. (CMOV of a constant to a register doesn't
+	// appear to be supported in Go. Thus t1 = 1.)
+	CMOVQEQ t1, AX
+
+	// XOR [acc4..acc7] with P and compare with zero again.
+	XORQ $-1, acc4
+	XORQ p256const0<>(SB), acc5
+	XORQ p256const1<>(SB), acc7
+	ORQ acc5, acc4
+	ORQ acc6, acc4
+	ORQ acc7, acc4
+
+	// Set the zero flag if so.
+	CMOVQEQ t1, AX
+	RET
+
 /* ---------------------------------------*/
 #define x1in(off) (32*0 + off)(SP)
 #define y1in(off) (32*1 + off)(SP)
@@ -1996,9 +2032,11 @@
 #define rsqr(off)  (32*18 + off)(SP)
 #define hcub(off)  (32*19 + off)(SP)
 #define rptr       (32*20)(SP)
+#define points_eq  (32*20+8)(SP)
 
-//func p256PointAddAsm(res, in1, in2 []uint64)
-TEXT ·p256PointAddAsm(SB),0,$672-72
+//func p256PointAddAsm(res, in1, in2 []uint64) int
+TEXT ·p256PointAddAsm(SB),0,$680-80
+	// See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
 	// Move input to stack in order to free registers
 	MOVQ res+0(FP), AX
 	MOVQ in1+24(FP), BX
@@ -2055,6 +2093,8 @@
 	LDt (s1)
 	CALL p256SubInternal(SB)	// r = s2 - s1
 	ST (r)
+	CALL p256IsZero(SB)
+	MOVQ AX, points_eq
 
 	LDacc (z2sqr)
 	LDt (x1in)
@@ -2068,6 +2108,9 @@
 	LDt (u1)
 	CALL p256SubInternal(SB)	// h = u2 - u1
 	ST (h)
+	CALL p256IsZero(SB)
+	ANDQ points_eq, AX
+	MOVQ AX, points_eq
 
 	LDacc (r)
 	CALL p256SqrInternal(SB)	// rsqr = rˆ2
@@ -2135,6 +2178,9 @@
 	MOVOU X4, (16*4)(AX)
 	MOVOU X5, (16*5)(AX)
 
+	MOVQ points_eq, AX
+	MOVQ AX, ret+72(FP)
+
 	RET
 #undef x1in
 #undef y1in
diff --git a/src/crypto/elliptic/p256_asm_s390x.s b/src/crypto/elliptic/p256_asm_s390x.s
index 96b59be..d0e6d09 100644
--- a/src/crypto/elliptic/p256_asm_s390x.s
+++ b/src/crypto/elliptic/p256_asm_s390x.s
@@ -1944,10 +1944,12 @@
 #undef CAR2
 
 // p256PointAddAsm(P3, P1, P2 *p256Point)
-#define P3ptr   R1
-#define P1ptr   R2
-#define P2ptr   R3
-#define CPOOL   R4
+#define P3ptr  R1
+#define P1ptr  R2
+#define P2ptr  R3
+#define CPOOL  R4
+#define ISZERO R5
+#define TRUE   R6
 
 // Temporaries in REGs
 #define T1L   V16
@@ -2102,6 +2104,21 @@
 	// SUB(H<H-T)            // H  = H-U1
 	p256SubInternal(HH,HL,HH,HL,T1,T0)
 
+	// if H == 0 or H^P == 0 then ret=1 else ret=0
+	// clobbers T1H and T1L
+	MOVD   $0, ISZERO
+	MOVD   $1, TRUE
+	VZERO  ZER
+	VO     HL, HH, T1H
+	VCEQGS ZER, T1H, T1H
+	MOVDEQ TRUE, ISZERO
+	VX     HL, PL, T1L
+	VX     HH, PH, T1H
+	VO     T1L, T1H, T1H
+	VCEQGS ZER, T1H, T1H
+	MOVDEQ TRUE, ISZERO
+	MOVD   ISZERO, ret+24(FP)
+
 	// X=Z1; Y=Z2; MUL; T-   // Z3 = Z1*Z2
 	VL   64(P1ptr), X1       // Z1H
 	VL   80(P1ptr), X0       // Z1L
@@ -2137,6 +2154,22 @@
 	// SUB(R<T-S1)           // R  = T-S1
 	p256SubInternal(RH,RL,T1,T0,S1H,S1L)
 
+	// if R == 0 or R^P == 0 then ret=ret else ret=0
+	// clobbers T1H and T1L
+	MOVD   $0, ISZERO
+	MOVD   $1, TRUE
+	VZERO  ZER
+	VO     RL, RH, T1H
+	VCEQGS ZER, T1H, T1H
+	MOVDEQ TRUE, ISZERO
+	VX     RL, PL, T1L
+	VX     RH, PH, T1H
+	VO     T1L, T1H, T1H
+	VCEQGS ZER, T1H, T1H
+	MOVDEQ TRUE, ISZERO
+	AND    ret+24(FP), ISZERO
+	MOVD   ISZERO, ret+24(FP)
+
 	// X=H ; Y=H ; MUL; T-   // T1 = H*H
 	VLR  HL, X0
 	VLR  HH, X1
diff --git a/src/crypto/elliptic/p256_s390x.go b/src/crypto/elliptic/p256_s390x.go
index 2ed4c0b..a36786e 100644
--- a/src/crypto/elliptic/p256_s390x.go
+++ b/src/crypto/elliptic/p256_s390x.go
@@ -7,6 +7,7 @@
 package elliptic
 
 import (
+	"crypto/subtle"
 	"math/big"
 )
 
@@ -49,6 +50,8 @@
 
 // Functions implemented in p256_asm_s390x.s
 // Montgomery multiplication modulo P256
+//
+//go:noescape
 func p256MulAsm(res, in1, in2 []byte)
 
 // Montgomery square modulo P256
@@ -57,19 +60,31 @@
 }
 
 // Montgomery multiplication by 1
+//
+//go:noescape
 func p256FromMont(res, in []byte)
 
 // iff cond == 1  val <- -val
+//
+//go:noescape
 func p256NegCond(val *p256Point, cond int)
 
 // if cond == 0 res <- b; else res <- a
+//
+//go:noescape
 func p256MovCond(res, a, b *p256Point, cond int)
 
 // Constant time table access
+//
+//go:noescape
 func p256Select(point *p256Point, table []p256Point, idx int)
+
+//go:noescape
 func p256SelectBase(point *p256Point, table []p256Point, idx int)
 
 // Montgomery multiplication modulo Ord(G)
+//
+//go:noescape
 func p256OrdMul(res, in1, in2 []byte)
 
 // Montgomery square modulo Ord(G), repeated n times
@@ -84,10 +99,16 @@
 // If sign == 1 -> P2 = -P2
 // If sel == 0 -> P3 = P1
 // if zero == 0 -> P3 = P2
+//
+//go:noescape
 func p256PointAddAffineAsm(P3, P1, P2 *p256Point, sign, sel, zero int)
 
 // Point add
-func p256PointAddAsm(P3, P1, P2 *p256Point)
+//
+//go:noescape
+func p256PointAddAsm(P3, P1, P2 *p256Point) int
+
+//go:noescape
 func p256PointDoubleAsm(P3, P1 *p256Point)
 
 func (curve p256CurveFast) Inverse(k *big.Int) *big.Int {
@@ -202,7 +223,9 @@
 
 func (curve p256CurveFast) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
 	var r1, r2 p256Point
-	r1.p256BaseMult(p256GetMultiplier(baseScalar))
+	scalarReduced := p256GetMultiplier(baseScalar)
+	r1IsInfinity := scalarIsZero(scalarReduced)
+	r1.p256BaseMult(scalarReduced)
 
 	copy(r2.x[:], fromBig(maybeReduceModP(bigX)))
 	copy(r2.y[:], fromBig(maybeReduceModP(bigY)))
@@ -210,9 +233,17 @@
 	p256MulAsm(r2.x[:], r2.x[:], rr[:])
 	p256MulAsm(r2.y[:], r2.y[:], rr[:])
 
+	scalarReduced = p256GetMultiplier(scalar)
+	r2IsInfinity := scalarIsZero(scalarReduced)
 	r2.p256ScalarMult(p256GetMultiplier(scalar))
-	p256PointAddAsm(&r1, &r1, &r2)
-	return r1.p256PointToAffine()
+
+	var sum, double p256Point
+	pointsEqual := p256PointAddAsm(&sum, &r1, &r2)
+	p256PointDoubleAsm(&double, &r1)
+	p256MovCond(&sum, &double, &sum, pointsEqual)
+	p256MovCond(&sum, &r1, &sum, r2IsInfinity)
+	p256MovCond(&sum, &r2, &sum, r1IsInfinity)
+	return sum.p256PointToAffine()
 }
 
 func (curve p256CurveFast) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
@@ -232,6 +263,16 @@
 	return r.p256PointToAffine()
 }
 
+// scalarIsZero returns 1 if scalar represents the zero value, and zero
+// otherwise.
+func scalarIsZero(scalar []byte) int {
+	b := byte(0)
+	for _, s := range scalar {
+		b |= s
+	}
+	return subtle.ConstantTimeByteEq(b, 0)
+}
+
 func (p *p256Point) p256PointToAffine() (x, y *big.Int) {
 	zInv := make([]byte, 32)
 	zInvSq := make([]byte, 32)
diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go
index 9ef9c44..3c8e727 100644
--- a/src/crypto/hmac/hmac.go
+++ b/src/crypto/hmac/hmac.go
@@ -64,6 +64,9 @@
 }
 
 // New returns a new HMAC hash using the given hash.Hash type and key.
+// Note that unlike other hash implementations in the standard library,
+// the returned Hash does not implement encoding.BinaryMarshaler
+// or encoding.BinaryUnmarshaler.
 func New(h func() hash.Hash, key []byte) hash.Hash {
 	hm := new(hmac)
 	hm.outer = h()
diff --git a/src/crypto/issue21104_test.go b/src/crypto/issue21104_test.go
new file mode 100644
index 0000000..b4276df
--- /dev/null
+++ b/src/crypto/issue21104_test.go
@@ -0,0 +1,61 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package crypto
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rc4"
+	"testing"
+)
+
+func TestRC4OutOfBoundsWrite(t *testing.T) {
+	// This cipherText is encrypted "0123456789"
+	cipherText := []byte{238, 41, 187, 114, 151, 2, 107, 13, 178, 63}
+	cipher, err := rc4.NewCipher([]byte{0})
+	if err != nil {
+		panic(err)
+	}
+	test(t, "RC4", cipherText, cipher.XORKeyStream)
+}
+func TestCTROutOfBoundsWrite(t *testing.T) {
+	testBlock(t, "CTR", cipher.NewCTR)
+}
+func TestOFBOutOfBoundsWrite(t *testing.T) {
+	testBlock(t, "OFB", cipher.NewOFB)
+}
+func TestCFBEncryptOutOfBoundsWrite(t *testing.T) {
+	testBlock(t, "CFB Encrypt", cipher.NewCFBEncrypter)
+}
+func TestCFBDecryptOutOfBoundsWrite(t *testing.T) {
+	testBlock(t, "CFB Decrypt", cipher.NewCFBDecrypter)
+}
+func testBlock(t *testing.T, name string, newCipher func(cipher.Block, []byte) cipher.Stream) {
+	// This cipherText is encrypted "0123456789"
+	cipherText := []byte{86, 216, 121, 231, 219, 191, 26, 12, 176, 117}
+	var iv, key [16]byte
+	block, err := aes.NewCipher(key[:])
+	if err != nil {
+		panic(err)
+	}
+	stream := newCipher(block, iv[:])
+	test(t, name, cipherText, stream.XORKeyStream)
+}
+func test(t *testing.T, name string, cipherText []byte, xor func([]byte, []byte)) {
+	want := "abcdefghij"
+	plainText := []byte(want)
+	shorterLen := len(cipherText) / 2
+	defer func() {
+		err := recover()
+		if err == nil {
+			t.Errorf("%v XORKeyStream expected to panic on len(dst) < len(src), but didn't", name)
+		}
+		const plain = "0123456789"
+		if plainText[shorterLen] == plain[shorterLen] {
+			t.Errorf("%v XORKeyStream did out of bounds write, want %v, got %v", name, want, string(plainText))
+		}
+	}()
+	xor(plainText[:shorterLen], cipherText)
+}
diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go
index b682f00..7aeee60 100644
--- a/src/crypto/md5/md5.go
+++ b/src/crypto/md5/md5.go
@@ -12,6 +12,7 @@
 
 import (
 	"crypto"
+	"errors"
 	"hash"
 )
 
@@ -50,7 +51,82 @@
 	d.len = 0
 }
 
-// New returns a new hash.Hash computing the MD5 checksum.
+const (
+	magic         = "md5\x01"
+	marshaledSize = len(magic) + 4*4 + chunk + 8
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	b = appendUint32(b, d.s[0])
+	b = appendUint32(b, d.s[1])
+	b = appendUint32(b, d.s[2])
+	b = appendUint32(b, d.s[3])
+	b = append(b, d.x[:d.nx]...)
+	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+	b = appendUint64(b, d.len)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/md5: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/md5: invalid hash state size")
+	}
+	b = b[len(magic):]
+	b, d.s[0] = consumeUint32(b)
+	b, d.s[1] = consumeUint32(b)
+	b, d.s[2] = consumeUint32(b)
+	b, d.s[3] = consumeUint32(b)
+	b = b[copy(d.x[:], b):]
+	b, d.len = consumeUint64(b)
+	d.nx = int(d.len) % chunk
+	return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	a := [8]byte{
+		byte(x >> 56),
+		byte(x >> 48),
+		byte(x >> 40),
+		byte(x >> 32),
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	a := [4]byte{
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	_ = b[7]
+	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+	return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	_ = b[3]
+	x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+	return b[4:], x
+}
+
+// New returns a new hash.Hash computing the MD5 checksum. The Hash also
+// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 func New() hash.Hash {
 	d := new(digest)
 	d.Reset()
diff --git a/src/crypto/md5/md5_test.go b/src/crypto/md5/md5_test.go
index e7faf49..64a62e4 100644
--- a/src/crypto/md5/md5_test.go
+++ b/src/crypto/md5/md5_test.go
@@ -5,7 +5,9 @@
 package md5
 
 import (
+	"bytes"
 	"crypto/rand"
+	"encoding"
 	"fmt"
 	"io"
 	"testing"
@@ -13,42 +15,43 @@
 )
 
 type md5Test struct {
-	out string
-	in  string
+	out       string
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden = []md5Test{
-	{"d41d8cd98f00b204e9800998ecf8427e", ""},
-	{"0cc175b9c0f1b6a831c399e269772661", "a"},
-	{"187ef4436122d1cc2f40dc2b92f0eba0", "ab"},
-	{"900150983cd24fb0d6963f7d28e17f72", "abc"},
-	{"e2fc714c4727ee9395f324cd2e7f331f", "abcd"},
-	{"ab56b4d92b40713acc5af89985d4b786", "abcde"},
-	{"e80b5017098950fc58aad83c8c14978e", "abcdef"},
-	{"7ac66c0f148de9519b8bd264312c4d64", "abcdefg"},
-	{"e8dc4081b13434b45189a720b77b6818", "abcdefgh"},
-	{"8aa99b1f439ff71293e95357bac6fd94", "abcdefghi"},
-	{"a925576942e94b2ef57a066101b48876", "abcdefghij"},
-	{"d747fc1719c7eacb84058196cfe56d57", "Discard medicine more than two years old."},
-	{"bff2dcb37ef3a44ba43ab144768ca837", "He who has a shady past knows that nice guys finish last."},
-	{"0441015ecb54a7342d017ed1bcfdbea5", "I wouldn't marry him with a ten foot pole."},
-	{"9e3cac8e9e9757a60c3ea391130d3689", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"a0f04459b031f916a59a35cc482dc039", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"e7a48e0fe884faf31475d2a04b1362cc", "Nepal premier won't resign."},
-	{"637d2fe925c07c113800509964fb0e06", "For every action there is an equal and opposite government program."},
-	{"834a8d18d5c6562119cf4c7f5086cb71", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"de3a4d2fd6c73ec2db2abad23b444281", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"acf203f997e2cf74ea3aff86985aefaf", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"e1c1384cb4d2221dfdd7c795a4222c9a", "size:  a.out:  bad magic"},
-	{"c90f3ddecc54f34228c063d7525bf644", "The major problem is with sendmail.  -Mark Horton"},
-	{"cdf7ab6c1fd49bd9933c43f3ea5af185", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"83bc85234942fc883c063cbd7f0ad5d0", "If the enemy is within range, then so are you."},
-	{"277cbe255686b48dd7e8f389394d9299", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"fd3fb0a7ffb8af16603f3d3af98f8e1f", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"469b13a78ebf297ecda64d4723655154", "C is as portable as Stonehedge!!"},
-	{"63eb3a2f466410104731c4b037600110", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"72c2ed7592debca1c90fc0100f931a2f", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"132f7619d33b523b1d9e5bd8e0928355", "How can you write a big system without C++?  -Paul Glick"},
+	{"d41d8cd98f00b204e9800998ecf8427e", "", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"0cc175b9c0f1b6a831c399e269772661", "a", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"187ef4436122d1cc2f40dc2b92f0eba0", "ab", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tva\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"900150983cd24fb0d6963f7d28e17f72", "abc", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tva\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"e2fc714c4727ee9395f324cd2e7f331f", "abcd", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"ab56b4d92b40713acc5af89985d4b786", "abcde", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"e80b5017098950fc58aad83c8c14978e", "abcdef", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvabc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"7ac66c0f148de9519b8bd264312c4d64", "abcdefg", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvabc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"e8dc4081b13434b45189a720b77b6818", "abcdefgh", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"8aa99b1f439ff71293e95357bac6fd94", "abcdefghi", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"a925576942e94b2ef57a066101b48876", "abcdefghij", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvabcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
+	{"d747fc1719c7eacb84058196cfe56d57", "Discard medicine more than two years old.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvDiscard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
+	{"bff2dcb37ef3a44ba43ab144768ca837", "He who has a shady past knows that nice guys finish last.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvHe who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"0441015ecb54a7342d017ed1bcfdbea5", "I wouldn't marry him with a ten foot pole.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvI wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
+	{"9e3cac8e9e9757a60c3ea391130d3689", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvFree! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"a0f04459b031f916a59a35cc482dc039", "The days of the digital watch are numbered.  -Tom Stoppard", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvThe days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
+	{"e7a48e0fe884faf31475d2a04b1362cc", "Nepal premier won't resign.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvNepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
+	{"637d2fe925c07c113800509964fb0e06", "For every action there is an equal and opposite government program.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvFor every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
+	{"834a8d18d5c6562119cf4c7f5086cb71", "His money is twice tainted: 'taint yours and 'taint mine.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvHis money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"de3a4d2fd6c73ec2db2abad23b444281", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvThere is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"acf203f997e2cf74ea3aff86985aefaf", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvIt's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
+	{"e1c1384cb4d2221dfdd7c795a4222c9a", "size:  a.out:  bad magic", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102Tvsize:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
+	{"c90f3ddecc54f34228c063d7525bf644", "The major problem is with sendmail.  -Mark Horton", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvThe major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
+	{"cdf7ab6c1fd49bd9933c43f3ea5af185", "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvGive me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
+	{"83bc85234942fc883c063cbd7f0ad5d0", "If the enemy is within range, then so are you.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvIf the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
+	{"277cbe255686b48dd7e8f389394d9299", "It's well we cannot hear the screams/That we create in others' dreams.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvIt's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
+	{"fd3fb0a7ffb8af16603f3d3af98f8e1f", "You remind me of a TV show, but that's all right: I watch it anyway.", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvYou remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
+	{"469b13a78ebf297ecda64d4723655154", "C is as portable as Stonehedge!!", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvC is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
+	{"63eb3a2f466410104731c4b037600110", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvEven if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"72c2ed7592debca1c90fc0100f931a2f", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "md5\x01\xa7\xc9\x18\x9b\xc3E\x18\xf2\x82\xfd\xf3$\x9d_\v\nem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
+	{"132f7619d33b523b1d9e5bd8e0928355", "How can you write a big system without C++?  -Paul Glick", "md5\x01gE#\x01\xefͫ\x89\x98\xba\xdc\xfe\x102TvHow can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
 }
 
 func TestGolden(t *testing.T) {
@@ -82,6 +85,38 @@
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	for _, g := range golden {
+		h := New()
+		h2 := New()
+
+		io.WriteString(h, g.in[:len(g.in)/2])
+
+		state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+		if err != nil {
+			t.Errorf("could not marshal: %v", err)
+			continue
+		}
+
+		if string(state) != g.halfState {
+			t.Errorf("md5(%q) state = %q, want %q", g.in, state, g.halfState)
+			continue
+		}
+
+		if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+			t.Errorf("could not unmarshal: %v", err)
+			continue
+		}
+
+		io.WriteString(h, g.in[len(g.in)/2:])
+		io.WriteString(h2, g.in[len(g.in)/2:])
+
+		if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
+			t.Errorf("md5(%q) = 0x%x != marshaled 0x%x", g.in, actual, actual2)
+		}
+	}
+}
+
 func TestLarge(t *testing.T) {
 	const N = 10000
 	ok := "2bb571599a4180e1d542f76904adc3df" // md5sum of "0123456789" * 1000
diff --git a/src/crypto/rand/rand_linux.go b/src/crypto/rand/rand_linux.go
index 8a4c757..dbd038c 100644
--- a/src/crypto/rand/rand_linux.go
+++ b/src/crypto/rand/rand_linux.go
@@ -9,7 +9,30 @@
 )
 
 func init() {
-	altGetRandom = getRandomLinux
+	altGetRandom = batched(getRandomLinux, maxGetRandomRead)
+}
+
+// maxGetRandomRead is the maximum number of bytes to ask for in one call to the
+// getrandom() syscall. In linux at most 2^25-1 bytes will be returned per call.
+// From the manpage
+//
+//	*  When reading from the urandom source, a maximum of 33554431 bytes
+//	   is returned by a single call to getrandom() on systems where int
+//	   has a size of 32 bits.
+const maxGetRandomRead = (1 << 25) - 1
+
+// batched returns a function that calls f to populate a []byte by chunking it
+// into subslices of, at most, readMax bytes.
+func batched(f func([]byte) bool, readMax int) func([]byte) bool {
+	return func(buf []byte) bool {
+		for len(buf) > readMax {
+			if !f(buf[:readMax]) {
+				return false
+			}
+			buf = buf[readMax:]
+		}
+		return len(buf) == 0 || f(buf)
+	}
 }
 
 // If the kernel is too old (before 3.17) to support the getrandom syscall(),
diff --git a/src/crypto/rand/rand_linux_test.go b/src/crypto/rand/rand_linux_test.go
new file mode 100644
index 0000000..77b7b6e
--- /dev/null
+++ b/src/crypto/rand/rand_linux_test.go
@@ -0,0 +1,42 @@
+// Copyright 2014 The Go Authors. 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 (
+	"bytes"
+	"testing"
+)
+
+func TestBatched(t *testing.T) {
+	fillBatched := batched(func(p []byte) bool {
+		for i := range p {
+			p[i] = byte(i)
+		}
+		return true
+	}, 5)
+
+	p := make([]byte, 13)
+	if !fillBatched(p) {
+		t.Fatal("batched function returned false")
+	}
+	expected := []byte{0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2}
+	if !bytes.Equal(expected, p) {
+		t.Errorf("incorrect batch result: got %x, want %x", p, expected)
+	}
+}
+
+func TestBatchedError(t *testing.T) {
+	b := batched(func(p []byte) bool { return false }, 5)
+	if b(make([]byte, 13)) {
+		t.Fatal("batched function should have returned false")
+	}
+}
+
+func TestBatchedEmpty(t *testing.T) {
+	b := batched(func(p []byte) bool { return false }, 5)
+	if !b(make([]byte, 0)) {
+		t.Fatal("empty slice should always return true")
+	}
+}
diff --git a/src/crypto/rc4/rc4.go b/src/crypto/rc4/rc4.go
index 772af0e..8274325 100644
--- a/src/crypto/rc4/rc4.go
+++ b/src/crypto/rc4/rc4.go
@@ -52,8 +52,7 @@
 }
 
 // xorKeyStreamGeneric 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.
+// key stream. Dst and src must overlap entirely or not at all.
 //
 // This is the pure Go version. rc4_{amd64,386,arm}* contain assembly
 // implementations. This is here for tests and to prevent bitrot.
diff --git a/src/crypto/rc4/rc4_asm.go b/src/crypto/rc4/rc4_asm.go
index 02e5b67..7e5f8b2 100644
--- a/src/crypto/rc4/rc4_asm.go
+++ b/src/crypto/rc4/rc4_asm.go
@@ -9,10 +9,12 @@
 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.
+// Dst and src must overlap entirely or not at all.
 func (c *Cipher) XORKeyStream(dst, src []byte) {
 	if len(src) == 0 {
 		return
 	}
+	// Assert len(dst) >= len(src)
+	_ = dst[len(src)-1]
 	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
index e34bd34..9b98fc4 100644
--- a/src/crypto/rc4/rc4_ref.go
+++ b/src/crypto/rc4/rc4_ref.go
@@ -7,7 +7,7 @@
 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.
+// Dst and src must overlap entirely or not at all.
 func (c *Cipher) XORKeyStream(dst, src []byte) {
 	c.xorKeyStreamGeneric(dst, src)
 }
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
index 1ba194a..75558a9 100644
--- a/src/crypto/rsa/pss.go
+++ b/src/crypto/rsa/pss.go
@@ -6,7 +6,7 @@
 
 // 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
+// [1] https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
 
 import (
 	"bytes"
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index 1de4fcb..0faca43 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -92,17 +92,19 @@
 	return &priv.PublicKey
 }
 
-// Sign signs msg with priv, reading randomness from rand. If opts is a
+// Sign signs digest 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) {
+// be used.
+//
+// This method implements crypto.Signer, which is an interface 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 directly.
+func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
 	if pssOpts, ok := opts.(*PSSOptions); ok {
-		return SignPSS(rand, priv, pssOpts.Hash, msg, pssOpts)
+		return SignPSS(rand, priv, pssOpts.Hash, digest, pssOpts)
 	}
 
-	return SignPKCS1v15(rand, priv, opts.HashFunc(), msg)
+	return SignPKCS1v15(rand, priv, opts.HashFunc(), digest)
 }
 
 // Decrypt decrypts ciphertext with priv. If opts is nil or of type
@@ -424,8 +426,7 @@
 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)
+	g.GCD(x, nil, 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
diff --git a/src/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go
index 6b17214..ae4896f 100644
--- a/src/crypto/sha1/sha1.go
+++ b/src/crypto/sha1/sha1.go
@@ -10,6 +10,7 @@
 
 import (
 	"crypto"
+	"errors"
 	"hash"
 )
 
@@ -40,6 +41,69 @@
 	len uint64
 }
 
+const (
+	magic         = "sha\x01"
+	marshaledSize = len(magic) + 5*4 + chunk + 8
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	b = appendUint32(b, d.h[0])
+	b = appendUint32(b, d.h[1])
+	b = appendUint32(b, d.h[2])
+	b = appendUint32(b, d.h[3])
+	b = appendUint32(b, d.h[4])
+	b = append(b, d.x[:d.nx]...)
+	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+	b = appendUint64(b, d.len)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/sha1: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/sha1: invalid hash state size")
+	}
+	b = b[len(magic):]
+	b, d.h[0] = consumeUint32(b)
+	b, d.h[1] = consumeUint32(b)
+	b, d.h[2] = consumeUint32(b)
+	b, d.h[3] = consumeUint32(b)
+	b, d.h[4] = consumeUint32(b)
+	b = b[copy(d.x[:], b):]
+	b, d.len = consumeUint64(b)
+	d.nx = int(d.len) % chunk
+	return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	var a [8]byte
+	putUint64(a[:], x)
+	return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	var a [4]byte
+	putUint32(a[:], x)
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	_ = b[7]
+	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+	return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	_ = b[3]
+	x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+	return b[4:], x
+}
+
 func (d *digest) Reset() {
 	d.h[0] = init0
 	d.h[1] = init1
@@ -50,7 +114,9 @@
 	d.len = 0
 }
 
-// New returns a new hash.Hash computing the SHA1 checksum.
+// New returns a new hash.Hash computing the SHA1 checksum. The Hash also
+// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 func New() hash.Hash {
 	d := new(digest)
 	d.Reset()
@@ -104,9 +170,7 @@
 
 	// Length in bits.
 	len <<= 3
-	for i := uint(0); i < 8; i++ {
-		tmp[i] = byte(len >> (56 - 8*i))
-	}
+	putUint64(tmp[:], len)
 	d.Write(tmp[0:8])
 
 	if d.nx != 0 {
@@ -114,12 +178,12 @@
 	}
 
 	var digest [Size]byte
-	for i, s := range d.h {
-		digest[i*4] = byte(s >> 24)
-		digest[i*4+1] = byte(s >> 16)
-		digest[i*4+2] = byte(s >> 8)
-		digest[i*4+3] = byte(s)
-	}
+
+	putUint32(digest[0:], d.h[0])
+	putUint32(digest[4:], d.h[1])
+	putUint32(digest[8:], d.h[2])
+	putUint32(digest[12:], d.h[3])
+	putUint32(digest[16:], d.h[4])
 
 	return digest
 }
@@ -199,3 +263,23 @@
 	d.Write(data)
 	return d.checkSum()
 }
+
+func putUint64(x []byte, s uint64) {
+	_ = x[7]
+	x[0] = byte(s >> 56)
+	x[1] = byte(s >> 48)
+	x[2] = byte(s >> 40)
+	x[3] = byte(s >> 32)
+	x[4] = byte(s >> 24)
+	x[5] = byte(s >> 16)
+	x[6] = byte(s >> 8)
+	x[7] = byte(s)
+}
+
+func putUint32(x []byte, s uint32) {
+	_ = x[3]
+	x[0] = byte(s >> 24)
+	x[1] = byte(s >> 16)
+	x[2] = byte(s >> 8)
+	x[3] = byte(s)
+}
diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go
index faa9916..4f22926 100644
--- a/src/crypto/sha1/sha1_test.go
+++ b/src/crypto/sha1/sha1_test.go
@@ -7,50 +7,53 @@
 package sha1
 
 import (
+	"bytes"
 	"crypto/rand"
+	"encoding"
 	"fmt"
 	"io"
 	"testing"
 )
 
 type sha1Test struct {
-	out string
-	in  string
+	out       string
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden = []sha1Test{
-	{"76245dbf96f661bd221046197ab8b9f063f11bad", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"},
-	{"da39a3ee5e6b4b0d3255bfef95601890afd80709", ""},
-	{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a"},
-	{"da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab"},
-	{"a9993e364706816aba3e25717850c26c9cd0d89d", "abc"},
-	{"81fe8bfe87576c3ecb22426f8e57847382917acf", "abcd"},
-	{"03de6c570bfe24bfc328ccd7ca46b76eadaf4334", "abcde"},
-	{"1f8ac10f23c5b5bc1167bda84b833e5c057a77d2", "abcdef"},
-	{"2fb5e13419fc89246865e7a324f476ec624e8740", "abcdefg"},
-	{"425af12a0743502b322e93a015bcf868e324d56a", "abcdefgh"},
-	{"c63b19f1e4c8b5f76b25c49b8b87f57d8e4872a1", "abcdefghi"},
-	{"d68c19a0a345b7eab78d5e11e991c026ec60db63", "abcdefghij"},
-	{"ebf81ddcbe5bf13aaabdc4d65354fdf2044f38a7", "Discard medicine more than two years old."},
-	{"e5dea09392dd886ca63531aaa00571dc07554bb6", "He who has a shady past knows that nice guys finish last."},
-	{"45988f7234467b94e3e9494434c96ee3609d8f8f", "I wouldn't marry him with a ten foot pole."},
-	{"55dee037eb7460d5a692d1ce11330b260e40c988", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"b7bc5fb91080c7de6b582ea281f8a396d7c0aee8", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"c3aed9358f7c77f523afe86135f06b95b3999797", "Nepal premier won't resign."},
-	{"6e29d302bf6e3a5e4305ff318d983197d6906bb9", "For every action there is an equal and opposite government program."},
-	{"597f6a540010f94c15d71806a99a2c8710e747bd", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"6859733b2590a8a091cecf50086febc5ceef1e80", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"514b2630ec089b8aee18795fc0cf1f4860cdacad", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"c5ca0d4a7b6676fc7aa72caa41cc3d5df567ed69", "size:  a.out:  bad magic"},
-	{"74c51fa9a04eadc8c1bbeaa7fc442f834b90a00a", "The major problem is with sendmail.  -Mark Horton"},
-	{"0b4c4ce5f52c3ad2821852a8dc00217fa18b8b66", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"3ae7937dd790315beb0f48330e8642237c61550a", "If the enemy is within range, then so are you."},
-	{"410a2b296df92b9a47412b13281df8f830a9f44b", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"841e7c85ca1adcddbdd0187f1289acb5c642f7f5", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"163173b825d03b952601376b25212df66763e1db", "C is as portable as Stonehedge!!"},
-	{"32b0377f2687eb88e22106f133c586ab314d5279", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"0885aaf99b569542fd165fa44e322718f4a984e0", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"6627d6904d71420b0bf3886ab629623538689f45", "How can you write a big system without C++?  -Paul Glick"},
+	{"76245dbf96f661bd221046197ab8b9f063f11bad", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", "sha\x01\v\xa0)I\xdeq(8h\x9ev\xe5\x88[\xf8\x81\x17\xba4Daaaaaaaaaaaaaaaaaaaaaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96"},
+	{"da39a3ee5e6b4b0d3255bfef95601890afd80709", "", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"a9993e364706816aba3e25717850c26c9cd0d89d", "abc", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"81fe8bfe87576c3ecb22426f8e57847382917acf", "abcd", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"03de6c570bfe24bfc328ccd7ca46b76eadaf4334", "abcde", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"1f8ac10f23c5b5bc1167bda84b833e5c057a77d2", "abcdef", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"2fb5e13419fc89246865e7a324f476ec624e8740", "abcdefg", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"425af12a0743502b322e93a015bcf868e324d56a", "abcdefgh", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"c63b19f1e4c8b5f76b25c49b8b87f57d8e4872a1", "abcdefghi", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"d68c19a0a345b7eab78d5e11e991c026ec60db63", "abcdefghij", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
+	{"ebf81ddcbe5bf13aaabdc4d65354fdf2044f38a7", "Discard medicine more than two years old.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
+	{"e5dea09392dd886ca63531aaa00571dc07554bb6", "He who has a shady past knows that nice guys finish last.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"45988f7234467b94e3e9494434c96ee3609d8f8f", "I wouldn't marry him with a ten foot pole.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
+	{"55dee037eb7460d5a692d1ce11330b260e40c988", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"b7bc5fb91080c7de6b582ea281f8a396d7c0aee8", "The days of the digital watch are numbered.  -Tom Stoppard", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
+	{"c3aed9358f7c77f523afe86135f06b95b3999797", "Nepal premier won't resign.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
+	{"6e29d302bf6e3a5e4305ff318d983197d6906bb9", "For every action there is an equal and opposite government program.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
+	{"597f6a540010f94c15d71806a99a2c8710e747bd", "His money is twice tainted: 'taint yours and 'taint mine.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"6859733b2590a8a091cecf50086febc5ceef1e80", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"514b2630ec089b8aee18795fc0cf1f4860cdacad", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
+	{"c5ca0d4a7b6676fc7aa72caa41cc3d5df567ed69", "size:  a.out:  bad magic", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
+	{"74c51fa9a04eadc8c1bbeaa7fc442f834b90a00a", "The major problem is with sendmail.  -Mark Horton", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
+	{"0b4c4ce5f52c3ad2821852a8dc00217fa18b8b66", "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
+	{"3ae7937dd790315beb0f48330e8642237c61550a", "If the enemy is within range, then so are you.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
+	{"410a2b296df92b9a47412b13281df8f830a9f44b", "It's well we cannot hear the screams/That we create in others' dreams.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
+	{"841e7c85ca1adcddbdd0187f1289acb5c642f7f5", "You remind me of a TV show, but that's all right: I watch it anyway.", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
+	{"163173b825d03b952601376b25212df66763e1db", "C is as portable as Stonehedge!!", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
+	{"32b0377f2687eb88e22106f133c586ab314d5279", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"0885aaf99b569542fd165fa44e322718f4a984e0", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "sha\x01x}\xf4\r\xeb\xf2\x10\x87\xe8[\xb2JA$D\xb7\u063ax8em\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
+	{"6627d6904d71420b0bf3886ab629623538689f45", "How can you write a big system without C++?  -Paul Glick", "sha\x01gE#\x01\xef\u036b\x89\x98\xba\xdc\xfe\x102Tv\xc3\xd2\xe1\xf0How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
 }
 
 func TestGolden(t *testing.T) {
@@ -87,6 +90,40 @@
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	h := New()
+	h2 := New()
+	for _, g := range golden {
+		h.Reset()
+		h2.Reset()
+
+		io.WriteString(h, g.in[:len(g.in)/2])
+
+		state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+		if err != nil {
+			t.Errorf("could not marshal: %v", err)
+			continue
+		}
+
+		if string(state) != g.halfState {
+			t.Errorf("sha1(%q) state = %+q, want %+q", g.in, state, g.halfState)
+			continue
+		}
+
+		if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+			t.Errorf("could not unmarshal: %v", err)
+			continue
+		}
+
+		io.WriteString(h, g.in[len(g.in)/2:])
+		io.WriteString(h2, g.in[len(g.in)/2:])
+
+		if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
+			t.Errorf("sha1(%q) = 0x%x != marshaled 0x%x", g.in, actual, actual2)
+		}
+	}
+}
+
 func TestSize(t *testing.T) {
 	c := New()
 	if got := c.Size(); got != Size {
diff --git a/src/crypto/sha1/sha1block_amd64.s b/src/crypto/sha1/sha1block_amd64.s
index 3adb6d2..a0032c4 100644
--- a/src/crypto/sha1/sha1block_amd64.s
+++ b/src/crypto/sha1/sha1block_amd64.s
@@ -1451,9 +1451,7 @@
 	CMPQ	R13, R11
 	CMOVQCC	R8, R13
 
-	MOVQ    $BSWAP_SHUFB_CTL<>(SB), R8
-	VMOVDQU (R8), Y10
-	MOVQ	$K_XMM_AR<>(SB), R8 //restore R8
+	VMOVDQU	BSWAP_SHUFB_CTL<>(SB), Y10
 
 	CALC // RET is inside macros
 
diff --git a/src/crypto/sha1/sha1block_arm64.go b/src/crypto/sha1/sha1block_arm64.go
new file mode 100644
index 0000000..173c40f
--- /dev/null
+++ b/src/crypto/sha1/sha1block_arm64.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha1
+
+import "internal/cpu"
+
+var k = []uint32{
+	0x5A827999,
+	0x6ED9EBA1,
+	0x8F1BBCDC,
+	0xCA62C1D6,
+}
+
+var hasSHA1 = cpu.ARM64.HasSHA1
+
+//go:noescape
+func sha1block(h []uint32, p []byte, k []uint32)
+
+func block(dig *digest, p []byte) {
+	if !hasSHA1 {
+		blockGeneric(dig, p)
+	} else {
+		h := dig.h[:]
+		sha1block(h, p, k)
+	}
+}
diff --git a/src/crypto/sha1/sha1block_arm64.s b/src/crypto/sha1/sha1block_arm64.s
new file mode 100644
index 0000000..ef94353
--- /dev/null
+++ b/src/crypto/sha1/sha1block_arm64.s
@@ -0,0 +1,152 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define HASHUPDATECHOOSE \
+	SHA1C	V16.S4, V1, V2 \
+	SHA1H	V3, V1 \
+	VMOV	V2.B16, V3.B16
+
+#define HASHUPDATEPARITY \
+	SHA1P	V16.S4, V1, V2 \
+	SHA1H	V3, V1 \
+	VMOV	V2.B16, V3.B16
+
+#define HASHUPDATEMAJ \
+	SHA1M	V16.S4, V1, V2 \
+	SHA1H	V3, V1 \
+	VMOV	V2.B16, V3.B16
+
+// func sha1block(h []uint32, p []byte, k []uint32)
+TEXT ·sha1block(SB),NOSPLIT,$0
+	MOVD	h_base+0(FP), R0                             // hash value first address
+	MOVD	p_base+24(FP), R1                            // message first address
+	MOVD	k_base+48(FP), R2                            // k constants first address
+	MOVD	p_len+32(FP), R3                             // message length
+	VLD1.P	16(R0), [V0.S4]
+	VMOVS	(R0), V20
+	SUB	$16, R0, R0
+
+blockloop:
+
+	VLD1.P	16(R1), [V4.B16]                             // load message
+	VLD1.P	16(R1), [V5.B16]
+	VLD1.P	16(R1), [V6.B16]
+	VLD1.P	16(R1), [V7.B16]
+	VLD1	(R2), [V19.S4]                               // load constant k0-k79
+	VMOV	V0.B16, V2.B16
+	VMOV	V20.S[0], V1
+	VMOV	V2.B16, V3.B16
+	VDUP	V19.S[0], V17.S4
+	VREV32	V4.B16, V4.B16                               // prepare for using message in Byte format
+	VREV32	V5.B16, V5.B16
+	VREV32	V6.B16, V6.B16
+	VREV32	V7.B16, V7.B16
+
+
+	VDUP	V19.S[1], V18.S4
+	VADD	V17.S4, V4.S4, V16.S4
+	SHA1SU0	V6.S4, V5.S4, V4.S4
+	HASHUPDATECHOOSE
+	SHA1SU1	V7.S4, V4.S4
+
+	VADD	V17.S4, V5.S4, V16.S4
+	SHA1SU0	V7.S4, V6.S4, V5.S4
+	HASHUPDATECHOOSE
+	SHA1SU1	V4.S4, V5.S4
+	VADD	V17.S4, V6.S4, V16.S4
+	SHA1SU0	V4.S4, V7.S4, V6.S4
+	HASHUPDATECHOOSE
+	SHA1SU1	V5.S4, V6.S4
+
+	VADD	V17.S4, V7.S4, V16.S4
+	SHA1SU0	V5.S4, V4.S4, V7.S4
+	HASHUPDATECHOOSE
+	SHA1SU1	V6.S4, V7.S4
+
+	VADD	V17.S4, V4.S4, V16.S4
+	SHA1SU0	V6.S4, V5.S4, V4.S4
+	HASHUPDATECHOOSE
+	SHA1SU1	V7.S4, V4.S4
+
+	VDUP	V19.S[2], V17.S4
+	VADD	V18.S4, V5.S4, V16.S4
+	SHA1SU0	V7.S4, V6.S4, V5.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V4.S4, V5.S4
+
+	VADD	V18.S4, V6.S4, V16.S4
+	SHA1SU0	V4.S4, V7.S4, V6.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V5.S4, V6.S4
+
+	VADD	V18.S4, V7.S4, V16.S4
+	SHA1SU0	V5.S4, V4.S4, V7.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V6.S4, V7.S4
+
+	VADD	V18.S4, V4.S4, V16.S4
+	SHA1SU0	V6.S4, V5.S4, V4.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V7.S4, V4.S4
+
+	VADD	V18.S4, V5.S4, V16.S4
+	SHA1SU0	V7.S4, V6.S4, V5.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V4.S4, V5.S4
+
+	VDUP	V19.S[3], V18.S4
+	VADD	V17.S4, V6.S4, V16.S4
+	SHA1SU0	V4.S4, V7.S4, V6.S4
+	HASHUPDATEMAJ
+	SHA1SU1	V5.S4, V6.S4
+
+	VADD	V17.S4, V7.S4, V16.S4
+	SHA1SU0	V5.S4, V4.S4, V7.S4
+	HASHUPDATEMAJ
+	SHA1SU1	V6.S4, V7.S4
+
+	VADD	V17.S4, V4.S4, V16.S4
+	SHA1SU0	V6.S4, V5.S4, V4.S4
+	HASHUPDATEMAJ
+	SHA1SU1	V7.S4, V4.S4
+
+	VADD	V17.S4, V5.S4, V16.S4
+	SHA1SU0	V7.S4, V6.S4, V5.S4
+	HASHUPDATEMAJ
+	SHA1SU1	V4.S4, V5.S4
+
+	VADD	V17.S4, V6.S4, V16.S4
+	SHA1SU0	V4.S4, V7.S4, V6.S4
+	HASHUPDATEMAJ
+	SHA1SU1	V5.S4, V6.S4
+
+	VADD	V18.S4, V7.S4, V16.S4
+	SHA1SU0	V5.S4, V4.S4, V7.S4
+	HASHUPDATEPARITY
+	SHA1SU1	V6.S4, V7.S4
+
+	VADD	V18.S4, V4.S4, V16.S4
+	HASHUPDATEPARITY
+
+	VADD	V18.S4, V5.S4, V16.S4
+	HASHUPDATEPARITY
+
+	VADD	V18.S4, V6.S4, V16.S4
+	HASHUPDATEPARITY
+
+	VADD	V18.S4, V7.S4, V16.S4
+	HASHUPDATEPARITY
+
+	SUB	$64, R3, R3                                  // message length - 64bytes, then compare with 64bytes
+	VADD	V2.S4, V0.S4, V0.S4
+	VADD	V1.S4, V20.S4, V20.S4
+	CBNZ	R3, blockloop
+
+sha1ret:
+
+	VST1.P	[V0.S4], 16(R0)                               // store hash value H(dcba)
+	VMOVS	V20, (R0)                                     // store hash value H(e)
+	RET
diff --git a/src/crypto/sha1/sha1block_generic.go b/src/crypto/sha1/sha1block_generic.go
index f019462..5823e08 100644
--- a/src/crypto/sha1/sha1block_generic.go
+++ b/src/crypto/sha1/sha1block_generic.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!amd64p32,!386,!arm,!s390x
+// +build !amd64,!amd64p32,!386,!arm,!s390x,!arm64
 
 package sha1
 
diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go
index 74b05b9..b8ddaf4 100644
--- a/src/crypto/sha256/sha256.go
+++ b/src/crypto/sha256/sha256.go
@@ -8,6 +8,7 @@
 
 import (
 	"crypto"
+	"errors"
 	"hash"
 )
 
@@ -54,6 +55,92 @@
 	is224 bool // mark if this digest is SHA-224
 }
 
+const (
+	magic224      = "sha\x02"
+	magic256      = "sha\x03"
+	marshaledSize = len(magic256) + 8*4 + chunk + 8
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	if d.is224 {
+		b = append(b, magic224...)
+	} else {
+		b = append(b, magic256...)
+	}
+	b = appendUint32(b, d.h[0])
+	b = appendUint32(b, d.h[1])
+	b = appendUint32(b, d.h[2])
+	b = appendUint32(b, d.h[3])
+	b = appendUint32(b, d.h[4])
+	b = appendUint32(b, d.h[5])
+	b = appendUint32(b, d.h[6])
+	b = appendUint32(b, d.h[7])
+	b = append(b, d.x[:d.nx]...)
+	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+	b = appendUint64(b, d.len)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic224) || (d.is224 && string(b[:len(magic224)]) != magic224) || (!d.is224 && string(b[:len(magic256)]) != magic256) {
+		return errors.New("crypto/sha256: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/sha256: invalid hash state size")
+	}
+	b = b[len(magic224):]
+	b, d.h[0] = consumeUint32(b)
+	b, d.h[1] = consumeUint32(b)
+	b, d.h[2] = consumeUint32(b)
+	b, d.h[3] = consumeUint32(b)
+	b, d.h[4] = consumeUint32(b)
+	b, d.h[5] = consumeUint32(b)
+	b, d.h[6] = consumeUint32(b)
+	b, d.h[7] = consumeUint32(b)
+	b = b[copy(d.x[:], b):]
+	b, d.len = consumeUint64(b)
+	d.nx = int(d.len) % chunk
+	return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	a := [8]byte{
+		byte(x >> 56),
+		byte(x >> 48),
+		byte(x >> 40),
+		byte(x >> 32),
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	a := [4]byte{
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	_ = b[7]
+	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+	return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	_ = b[3]
+	x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+	return b[4:], x
+}
+
 func (d *digest) Reset() {
 	if !d.is224 {
 		d.h[0] = init0
@@ -78,7 +165,10 @@
 	d.len = 0
 }
 
-// New returns a new hash.Hash computing the SHA256 checksum.
+// New returns a new hash.Hash computing the SHA256 checksum. The Hash
+// also implements encoding.BinaryMarshaler and
+// encoding.BinaryUnmarshaler to marshal and unmarshal the internal
+// state of the hash.
 func New() hash.Hash {
 	d := new(digest)
 	d.Reset()
diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go
index 279cf5a..cd40286 100644
--- a/src/crypto/sha256/sha256_test.go
+++ b/src/crypto/sha256/sha256_test.go
@@ -7,83 +7,87 @@
 package sha256
 
 import (
+	"bytes"
 	"crypto/rand"
+	"encoding"
 	"fmt"
+	"hash"
 	"io"
 	"testing"
 )
 
 type sha256Test struct {
-	out string
-	in  string
+	out       string
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden = []sha256Test{
-	{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""},
-	{"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "a"},
-	{"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", "ab"},
-	{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc"},
-	{"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", "abcd"},
-	{"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", "abcde"},
-	{"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", "abcdef"},
-	{"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", "abcdefg"},
-	{"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", "abcdefgh"},
-	{"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", "abcdefghi"},
-	{"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", "abcdefghij"},
-	{"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", "Discard medicine more than two years old."},
-	{"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", "He who has a shady past knows that nice guys finish last."},
-	{"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", "I wouldn't marry him with a ten foot pole."},
-	{"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", "Nepal premier won't resign."},
-	{"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", "For every action there is an equal and opposite government program."},
-	{"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", "size:  a.out:  bad magic"},
-	{"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", "The major problem is with sendmail.  -Mark Horton"},
-	{"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", "If the enemy is within range, then so are you."},
-	{"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", "C is as portable as Stonehedge!!"},
-	{"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", "How can you write a big system without C++?  -Paul Glick"},
+	{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "a", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", "ab", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", "abcd", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", "abcde", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", "abcdef", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", "abcdefg", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", "abcdefgh", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", "abcdefghi", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", "abcdefghij", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
+	{"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", "Discard medicine more than two years old.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
+	{"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", "He who has a shady past knows that nice guys finish last.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", "I wouldn't marry him with a ten foot pole.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
+	{"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", "The days of the digital watch are numbered.  -Tom Stoppard", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
+	{"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", "Nepal premier won't resign.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
+	{"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", "For every action there is an equal and opposite government program.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
+	{"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", "His money is twice tainted: 'taint yours and 'taint mine.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
+	{"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", "size:  a.out:  bad magic", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
+	{"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", "The major problem is with sendmail.  -Mark Horton", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
+	{"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
+	{"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", "If the enemy is within range, then so are you.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
+	{"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", "It's well we cannot hear the screams/That we create in others' dreams.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
+	{"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", "You remind me of a TV show, but that's all right: I watch it anyway.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
+	{"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", "C is as portable as Stonehedge!!", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
+	{"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "sha\x03\x93\x14\xc8z\x87\x0e\vo\xf1E\x0f\xa4V\xb2a\x00\x87\xb5ǔ\xfc\xeaV\u009eg\xbc\x17\xb1\x85њem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
+	{"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", "How can you write a big system without C++?  -Paul Glick", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
 }
 
 var golden224 = []sha256Test{
-	{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""},
-	{"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", "a"},
-	{"db3cda86d4429a1d39c148989566b38f7bda0156296bd364ba2f878b", "ab"},
-	{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"},
-	{"a76654d8e3550e9a2d67a0eeb6c67b220e5885eddd3fde135806e601", "abcd"},
-	{"bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6", "abcde"},
-	{"7043631cb415556a275a4ebecb802c74ee9f6153908e1792a90b6a98", "abcdef"},
-	{"d1884e711701ad81abe0c77a3b0ea12e19ba9af64077286c72fc602d", "abcdefg"},
-	{"17eb7d40f0356f8598e89eafad5f6c759b1f822975d9c9b737c8a517", "abcdefgh"},
-	{"aeb35915346c584db820d2de7af3929ffafef9222a9bcb26516c7334", "abcdefghi"},
-	{"d35e1e5af29ddb0d7e154357df4ad9842afee527c689ee547f753188", "abcdefghij"},
-	{"19297f1cef7ddc8a7e947f5c5a341e10f7245045e425db67043988d7", "Discard medicine more than two years old."},
-	{"0f10c2eb436251f777fbbd125e260d36aecf180411726c7c885f599a", "He who has a shady past knows that nice guys finish last."},
-	{"4d1842104919f314cad8a3cd20b3cba7e8ed3e7abed62b57441358f6", "I wouldn't marry him with a ten foot pole."},
-	{"a8ba85c6fe0c48fbffc72bbb2f03fcdbc87ae2dc7a56804d1590fb3b", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"5543fbab26e67e8885b1a852d567d1cb8b9bfe42e0899584c50449a9", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"65ca107390f5da9efa05d28e57b221657edc7e43a9a18fb15b053ddb", "Nepal premier won't resign."},
-	{"84953962be366305a9cc9b5cd16ed019edc37ac96c0deb3e12cca116", "For every action there is an equal and opposite government program."},
-	{"35a189ce987151dfd00b3577583cc6a74b9869eecf894459cb52038d", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"2fc333713983edfd4ef2c0da6fb6d6415afb94987c91e4069eb063e6", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"cbe32d38d577a1b355960a4bc3c659c2dc4670859a19777a875842c4", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"a2dc118ce959e027576413a7b440c875cdc8d40df9141d6ef78a57e1", "size:  a.out:  bad magic"},
-	{"d10787e24052bcff26dc484787a54ed819e4e4511c54890ee977bf81", "The major problem is with sendmail.  -Mark Horton"},
-	{"62efcf16ab8a893acdf2f348aaf06b63039ff1bf55508c830532c9fb", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"3e9b7e4613c59f58665104c5fa86c272db5d3a2ff30df5bb194a5c99", "If the enemy is within range, then so are you."},
-	{"5999c208b8bdf6d471bb7c359ac5b829e73a8211dff686143a4e7f18", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"3b2d67ff54eabc4ef737b14edf87c64280ef582bcdf2a6d56908b405", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"d0733595d20e4d3d6b5c565a445814d1bbb2fd08b9a3b8ffb97930c6", "C is as portable as Stonehedge!!"},
-	{"43fb8aeed8a833175c9295c1165415f98c866ef08a4922959d673507", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"ec18e66e93afc4fb1604bc2baedbfd20b44c43d76e65c0996d7851c6", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"86ed2eaa9c75ba98396e5c9fb2f679ecf0ea2ed1e0ee9ceecb4a9332", "How can you write a big system without C++?  -Paul Glick"},
+	{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", "a", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"db3cda86d4429a1d39c148989566b38f7bda0156296bd364ba2f878b", "ab", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"a76654d8e3550e9a2d67a0eeb6c67b220e5885eddd3fde135806e601", "abcd", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6", "abcde", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"7043631cb415556a275a4ebecb802c74ee9f6153908e1792a90b6a98", "abcdef", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"d1884e711701ad81abe0c77a3b0ea12e19ba9af64077286c72fc602d", "abcdefg", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"17eb7d40f0356f8598e89eafad5f6c759b1f822975d9c9b737c8a517", "abcdefgh", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"aeb35915346c584db820d2de7af3929ffafef9222a9bcb26516c7334", "abcdefghi", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"d35e1e5af29ddb0d7e154357df4ad9842afee527c689ee547f753188", "abcdefghij", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
+	{"19297f1cef7ddc8a7e947f5c5a341e10f7245045e425db67043988d7", "Discard medicine more than two years old.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
+	{"0f10c2eb436251f777fbbd125e260d36aecf180411726c7c885f599a", "He who has a shady past knows that nice guys finish last.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"4d1842104919f314cad8a3cd20b3cba7e8ed3e7abed62b57441358f6", "I wouldn't marry him with a ten foot pole.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
+	{"a8ba85c6fe0c48fbffc72bbb2f03fcdbc87ae2dc7a56804d1590fb3b", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"5543fbab26e67e8885b1a852d567d1cb8b9bfe42e0899584c50449a9", "The days of the digital watch are numbered.  -Tom Stoppard", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
+	{"65ca107390f5da9efa05d28e57b221657edc7e43a9a18fb15b053ddb", "Nepal premier won't resign.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
+	{"84953962be366305a9cc9b5cd16ed019edc37ac96c0deb3e12cca116", "For every action there is an equal and opposite government program.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
+	{"35a189ce987151dfd00b3577583cc6a74b9869eecf894459cb52038d", "His money is twice tainted: 'taint yours and 'taint mine.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"2fc333713983edfd4ef2c0da6fb6d6415afb94987c91e4069eb063e6", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"cbe32d38d577a1b355960a4bc3c659c2dc4670859a19777a875842c4", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
+	{"a2dc118ce959e027576413a7b440c875cdc8d40df9141d6ef78a57e1", "size:  a.out:  bad magic", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
+	{"d10787e24052bcff26dc484787a54ed819e4e4511c54890ee977bf81", "The major problem is with sendmail.  -Mark Horton", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
+	{"62efcf16ab8a893acdf2f348aaf06b63039ff1bf55508c830532c9fb", "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
+	{"3e9b7e4613c59f58665104c5fa86c272db5d3a2ff30df5bb194a5c99", "If the enemy is within range, then so are you.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
+	{"5999c208b8bdf6d471bb7c359ac5b829e73a8211dff686143a4e7f18", "It's well we cannot hear the screams/That we create in others' dreams.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
+	{"3b2d67ff54eabc4ef737b14edf87c64280ef582bcdf2a6d56908b405", "You remind me of a TV show, but that's all right: I watch it anyway.", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
+	{"d0733595d20e4d3d6b5c565a445814d1bbb2fd08b9a3b8ffb97930c6", "C is as portable as Stonehedge!!", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
+	{"43fb8aeed8a833175c9295c1165415f98c866ef08a4922959d673507", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"ec18e66e93afc4fb1604bc2baedbfd20b44c43d76e65c0996d7851c6", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "sha\x02\xea\xc9\xc2e\xddH\x0f\\.\xeb\xc4G\xda\xea\xd5TX\x17\xca3l\xfaV\x9d\x9d\x056\x85&1\rDem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
+	{"86ed2eaa9c75ba98396e5c9fb2f679ecf0ea2ed1e0ee9ceecb4a9332", "How can you write a big system without C++?  -Paul Glick", "sha\x02\xc1\x05\x9e\xd86|\xd5\a0p\xdd\x17\xf7\x0eY9\xff\xc0\v1hX\x15\x11d\xf9\x8f\xa7\xbe\xfaO\xa4How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
 }
 
 func TestGolden(t *testing.T) {
@@ -133,6 +137,65 @@
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	tests := []struct {
+		name    string
+		newHash func() hash.Hash
+		gold    []sha256Test
+	}{
+		{"256", New, golden},
+		{"224", New224, golden224},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			for _, g := range tt.gold {
+				h := tt.newHash()
+				h2 := tt.newHash()
+
+				io.WriteString(h, g.in[:len(g.in)/2])
+
+				state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+				if err != nil {
+					t.Errorf("could not marshal: %v", err)
+					continue
+				}
+
+				if string(state) != g.halfState {
+					t.Errorf("sha%s(%q) state = %q, want %q", tt.name, g.in, state, g.halfState)
+					continue
+				}
+
+				if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+					t.Errorf("could not unmarshal: %v", err)
+					continue
+				}
+
+				io.WriteString(h, g.in[len(g.in)/2:])
+				io.WriteString(h2, g.in[len(g.in)/2:])
+
+				if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
+					t.Errorf("sha%s(%q) = 0x%x != marshaled 0x%x", tt.name, g.in, actual, actual2)
+				}
+			}
+		})
+	}
+}
+
+func TestMarshalTypeMismatch(t *testing.T) {
+	h1 := New()
+	h2 := New224()
+
+	state1, err := h1.(encoding.BinaryMarshaler).MarshalBinary()
+	if err != nil {
+		t.Errorf("could not marshal: %v", err)
+	}
+
+	if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state1); err == nil {
+		t.Errorf("no error when one was expected")
+	}
+}
+
 func TestSize(t *testing.T) {
 	c := New()
 	if got := c.Size(); got != Size {
diff --git a/src/crypto/sha256/sha256block_amd64.s b/src/crypto/sha256/sha256block_amd64.s
index d7ac1e5..f30f482 100644
--- a/src/crypto/sha256/sha256block_amd64.s
+++ b/src/crypto/sha256/sha256block_amd64.s
@@ -213,13 +213,11 @@
 #define XFER_SIZE 2*64*4
 #define INP_END_SIZE 8
 #define INP_SIZE 8
-#define TMP_SIZE 4
 
 #define _XFER 0
 #define _INP_END _XFER + XFER_SIZE
 #define _INP _INP_END + INP_END_SIZE
-#define _TMP _INP + INP_SIZE
-#define STACK_SIZE _TMP + TMP_SIZE
+#define STACK_SIZE _INP + INP_SIZE
 
 #define ROUND_AND_SCHED_N_0(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
 	;                                     \ // #############################  RND N + 0 ############################//
@@ -341,10 +339,7 @@
 	VPXOR   XTMP2, XTMP4, XTMP4;         \ // XTMP4 = s1 {xBxA}
 	XORL    g, y2;                       \ // y2 = CH = ((f^g)&e)^g			// CH
 	;                                    \
-	MOVL    f, _TMP(SP);                 \
-	MOVQ    $shuff_00BA<>(SB), f;        \ // f is used to keep SHUF_00BA
-	VPSHUFB (f), XTMP4, XTMP4;           \ // XTMP4 = s1 {00BA}
-	MOVL    _TMP(SP), f;                 \ // f is restored
+	VPSHUFB shuff_00BA<>(SB), XTMP4, XTMP4;\ // XTMP4 = s1 {00BA}
 	;                                    \
 	XORL    T1, y1;                      \ // y1 = (a>>22) ^ (a>>13)		// S0
 	RORXL   $2, a, T1;                   \ // T1 = (a >> 2)				// S0
@@ -398,10 +393,7 @@
 	;                                    \
 	RORXL   $2, a, T1;                   \ // T1 = (a >> 2)				// S0
 	;                                    \
-	MOVL    f, _TMP(SP);                 \ // Save f
-	MOVQ    $shuff_DC00<>(SB), f;        \ // SHUF_00DC
-	VPSHUFB (f), XTMP5, XTMP5;           \ // XTMP5 = s1 {DC00}
-	MOVL    _TMP(SP), f;                 \ // Restore f
+	VPSHUFB shuff_DC00<>(SB), XTMP5, XTMP5;\ // XTMP5 = s1 {DC00}
 	;                                    \
 	VPADDD  XTMP0, XTMP5, XDWORD0;       \ // XDWORD0 = {W[3], W[2], W[1], W[0]}
 	XORL    T1, y1;                      \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2)	// S0
@@ -704,8 +696,7 @@
 	VMOVDQU (2*32)(INP), XTMP2
 	VMOVDQU (3*32)(INP), XTMP3
 
-	MOVQ    $flip_mask<>(SB), BP // BYTE_FLIP_MASK
-	VMOVDQU (BP), BYTE_FLIP_MASK
+	VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
 
 	// Apply Byte Flip Mask: LE -> BE
 	VPSHUFB BYTE_FLIP_MASK, XTMP0, XTMP0
@@ -843,8 +834,7 @@
 	VMOVDQU 32(INP), XWORD2
 	VMOVDQU 48(INP), XWORD3
 
-	MOVQ    $flip_mask<>(SB), BP
-	VMOVDQU (BP), X_BYTE_FLIP_MASK
+	VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
 
 	VPSHUFB X_BYTE_FLIP_MASK, XWORD0, XWORD0
 	VPSHUFB X_BYTE_FLIP_MASK, XWORD1, XWORD1
diff --git a/src/crypto/sha256/sha256block_arm64.go b/src/crypto/sha256/sha256block_arm64.go
new file mode 100644
index 0000000..75bbcbe
--- /dev/null
+++ b/src/crypto/sha256/sha256block_arm64.go
@@ -0,0 +1,23 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha256
+
+import "internal/cpu"
+
+var k = _K
+
+var hasSHA2 = cpu.ARM64.HasSHA2
+
+//go:noescape
+func sha256block(h []uint32, p []byte, k []uint32)
+
+func block(dig *digest, p []byte) {
+	if !hasSHA2 {
+		blockGeneric(dig, p)
+	} else {
+		h := dig.h[:]
+		sha256block(h, p, k)
+	}
+}
diff --git a/src/crypto/sha256/sha256block_arm64.s b/src/crypto/sha256/sha256block_arm64.s
new file mode 100644
index 0000000..d5c1eb0
--- /dev/null
+++ b/src/crypto/sha256/sha256block_arm64.s
@@ -0,0 +1,119 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define HASHUPDATE \
+	SHA256H	V9.S4, V3, V2 \
+	SHA256H2	V9.S4, V8, V3 \
+	VMOV	V2.B16, V8.B16
+
+// func sha256block(h []uint32, p []byte, k []uint32)
+TEXT ·sha256block(SB),NOSPLIT,$0
+	MOVD	h_base+0(FP), R0                           // Hash value first address
+	MOVD	p_base+24(FP), R1                          // message first address
+	MOVD	k_base+48(FP), R2                          // k constants first address
+	MOVD	p_len+32(FP), R3                           // message length
+	VLD1	(R0), [V0.S4, V1.S4]                       // load h(a,b,c,d,e,f,g,h)
+	VLD1.P	64(R2), [V16.S4, V17.S4, V18.S4, V19.S4]
+	VLD1.P	64(R2), [V20.S4, V21.S4, V22.S4, V23.S4]
+	VLD1.P	64(R2), [V24.S4, V25.S4, V26.S4, V27.S4]
+	VLD1	(R2), [V28.S4, V29.S4, V30.S4, V31.S4]     //load 64*4bytes K constant(K0-K63)
+
+blockloop:
+
+	VLD1.P	16(R1), [V4.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V5.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V6.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V7.B16]                            // load 16bytes message
+	VMOV	V0.B16, V2.B16                              // backup: VO h(dcba)
+	VMOV	V1.B16, V3.B16                              // backup: V1 h(hgfe)
+	VMOV	V2.B16, V8.B16
+	VREV32	V4.B16, V4.B16                              // prepare for using message in Byte format
+	VREV32	V5.B16, V5.B16
+	VREV32	V6.B16, V6.B16
+	VREV32	V7.B16, V7.B16
+
+	VADD	V16.S4, V4.S4, V9.S4                        // V18(W0+K0...W3+K3)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W1)+W0,...,su0(W4)+W3)
+	HASHUPDATE                                          // H4
+
+	VADD	V17.S4, V5.S4, V9.S4                        // V18(W4+K4...W7+K7)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W5)+W4,...,su0(W8)+W7)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W16-W19
+	HASHUPDATE                                          // H8
+
+	VADD	V18.S4, V6.S4, V9.S4                        // V18(W8+K8...W11+K11)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W9)+W8,...,su0(W12)+W11)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W20-W23
+	HASHUPDATE                                          // H12
+
+	VADD	V19.S4, V7.S4, V9.S4                        // V18(W12+K12...W15+K15)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W13)+W12,...,su0(W16)+W15)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W24-W27
+	HASHUPDATE                                          // H16
+
+	VADD	V20.S4, V4.S4, V9.S4                        // V18(W16+K16...W19+K19)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W17)+W16,...,su0(W20)+W19)
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W28-W31
+	HASHUPDATE                                          // H20
+
+	VADD	V21.S4, V5.S4, V9.S4                        // V18(W20+K20...W23+K23)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W21)+W20,...,su0(W24)+W23)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W32-W35
+	HASHUPDATE                                          // H24
+
+	VADD	V22.S4, V6.S4, V9.S4                        // V18(W24+K24...W27+K27)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W25)+W24,...,su0(W28)+W27)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W36-W39
+	HASHUPDATE                                          // H28
+
+	VADD	V23.S4, V7.S4, V9.S4                        // V18(W28+K28...W31+K31)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W29)+W28,...,su0(W32)+W31)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W40-W43
+	HASHUPDATE                                          // H32
+
+	VADD	V24.S4, V4.S4, V9.S4                        // V18(W32+K32...W35+K35)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W33)+W32,...,su0(W36)+W35)
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W44-W47
+	HASHUPDATE                                          // H36
+
+	VADD	V25.S4, V5.S4, V9.S4                        // V18(W36+K36...W39+K39)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W37)+W36,...,su0(W40)+W39)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W48-W51
+	HASHUPDATE                                          // H40
+
+	VADD	V26.S4, V6.S4, V9.S4                        // V18(W40+K40...W43+K43)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W41)+W40,...,su0(W44)+W43)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W52-W55
+	HASHUPDATE                                          // H44
+
+	VADD	V27.S4, V7.S4, V9.S4                        // V18(W44+K44...W47+K47)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W45)+W44,...,su0(W48)+W47)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W56-W59
+	HASHUPDATE                                          // H48
+
+	VADD	V28.S4, V4.S4, V9.S4                        // V18(W48+K48,...,W51+K51)
+	HASHUPDATE                                          // H52
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W60-W63
+
+	VADD	V29.S4, V5.S4, V9.S4                        // V18(W52+K52,...,W55+K55)
+	HASHUPDATE                                          // H56
+
+	VADD	V30.S4, V6.S4, V9.S4                        // V18(W59+K59,...,W59+K59)
+	HASHUPDATE                                          // H60
+
+	VADD	V31.S4, V7.S4, V9.S4                        // V18(W60+K60,...,W63+K63)
+	HASHUPDATE                                          // H64
+
+	SUB	$64, R3, R3                                 // message length - 64bytes, then compare with 64bytes
+	VADD	V2.S4, V0.S4, V0.S4
+	VADD	V3.S4, V1.S4, V1.S4
+	CBNZ	R3, blockloop
+
+sha256ret:
+
+	VST1	[V0.S4, V1.S4], (R0)                       // store hash value H
+	RET
+
diff --git a/src/crypto/sha256/sha256block_generic.go b/src/crypto/sha256/sha256block_generic.go
index a182a5e..61362f4 100644
--- a/src/crypto/sha256/sha256block_generic.go
+++ b/src/crypto/sha256/sha256block_generic.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!386,!s390x,!ppc64le
+// +build !amd64,!386,!s390x,!ppc64le,!arm64
 
 package sha256
 
diff --git a/src/crypto/sha256/sha256block_ppc64le.s b/src/crypto/sha256/sha256block_ppc64le.s
index 9ffa5f8..f543560 100644
--- a/src/crypto/sha256/sha256block_ppc64le.s
+++ b/src/crypto/sha256/sha256block_ppc64le.s
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This is a derived work from OpenSSL of SHA-2 using assembly optimizations. The
-// original code was written by Andy Polyakov <appro@openssl.org> and it's dual
-// licensed under OpenSSL and CRYPTOGAMS licenses depending on where you obtain
-// it. For further details see http://www.openssl.org/~appro/cryptogams/.
+// Based on CRYPTOGAMS code with the following comment:
+// # ====================================================================
+// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+// # project. The module is, however, dual licensed under OpenSSL and
+// # CRYPTOGAMS licenses depending on where you obtain it. For further
+// # details see http://www.openssl.org/~appro/cryptogams/.
+// # ====================================================================
 
 #include "textflag.h"
 
diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go
index 5603c90..b199951 100644
--- a/src/crypto/sha512/sha512.go
+++ b/src/crypto/sha512/sha512.go
@@ -4,10 +4,15 @@
 
 // Package sha512 implements the SHA-384, SHA-512, SHA-512/224, and SHA-512/256
 // hash algorithms as defined in FIPS 180-4.
+//
+// All the hash.Hash implementations returned by this package also
+// implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 package sha512
 
 import (
 	"crypto"
+	"errors"
 	"hash"
 )
 
@@ -124,6 +129,93 @@
 	d.len = 0
 }
 
+const (
+	magic384      = "sha\x04"
+	magic512_224  = "sha\x05"
+	magic512_256  = "sha\x06"
+	magic512      = "sha\x07"
+	marshaledSize = len(magic512) + 8*8 + chunk + 8
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	switch d.function {
+	case crypto.SHA384:
+		b = append(b, magic384...)
+	case crypto.SHA512_224:
+		b = append(b, magic512_224...)
+	case crypto.SHA512_256:
+		b = append(b, magic512_256...)
+	case crypto.SHA512:
+		b = append(b, magic512...)
+	default:
+		return nil, errors.New("crypto/sha512: invalid hash function")
+	}
+	b = appendUint64(b, d.h[0])
+	b = appendUint64(b, d.h[1])
+	b = appendUint64(b, d.h[2])
+	b = appendUint64(b, d.h[3])
+	b = appendUint64(b, d.h[4])
+	b = appendUint64(b, d.h[5])
+	b = appendUint64(b, d.h[6])
+	b = appendUint64(b, d.h[7])
+	b = append(b, d.x[:d.nx]...)
+	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+	b = appendUint64(b, d.len)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic512) {
+		return errors.New("crypto/sha512: invalid hash state identifier")
+	}
+	switch {
+	case d.function == crypto.SHA384 && string(b[:len(magic384)]) == magic384:
+	case d.function == crypto.SHA512_224 && string(b[:len(magic512_224)]) == magic512_224:
+	case d.function == crypto.SHA512_256 && string(b[:len(magic512_256)]) == magic512_256:
+	case d.function == crypto.SHA512 && string(b[:len(magic512)]) == magic512:
+	default:
+		return errors.New("crypto/sha512: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/sha512: invalid hash state size")
+	}
+	b = b[len(magic512):]
+	b, d.h[0] = consumeUint64(b)
+	b, d.h[1] = consumeUint64(b)
+	b, d.h[2] = consumeUint64(b)
+	b, d.h[3] = consumeUint64(b)
+	b, d.h[4] = consumeUint64(b)
+	b, d.h[5] = consumeUint64(b)
+	b, d.h[6] = consumeUint64(b)
+	b, d.h[7] = consumeUint64(b)
+	b = b[copy(d.x[:], b):]
+	b, d.len = consumeUint64(b)
+	d.nx = int(d.len) % chunk
+	return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	a := [8]byte{
+		byte(x >> 56),
+		byte(x >> 48),
+		byte(x >> 40),
+		byte(x >> 32),
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	_ = b[7]
+	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+	return b[8:], x
+}
+
 // New returns a new hash.Hash computing the SHA-512 checksum.
 func New() hash.Hash {
 	d := &digest{function: crypto.SHA512}
diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go
index a3a136a..4423cf5 100644
--- a/src/crypto/sha512/sha512_test.go
+++ b/src/crypto/sha512/sha512_test.go
@@ -7,7 +7,9 @@
 package sha512
 
 import (
+	"bytes"
 	"crypto/rand"
+	"encoding"
 	"encoding/hex"
 	"hash"
 	"io"
@@ -15,230 +17,640 @@
 )
 
 type sha512Test struct {
-	in     string
-	out224 string
-	out256 string
-	out384 string
-	out512 string
+	out       string
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
-var golden = []sha512Test{
+var golden224 = []sha512Test{
 	{
-		"",
 		"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4",
-		"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a",
-		"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
-		"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+		"",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
 	},
 	{
-		"a",
 		"d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327",
-		"455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8",
-		"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31",
-		"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
+		"a",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
 	},
 	{
-		"ab",
 		"b35878d07bfedf39fc638af08547eb5d1072d8546319f247b442fbf5",
-		"22d4d37ec6370571af7109fb12eae79673d5f7c83e6e677083faa3cfac3b2c14",
-		"c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd",
-		"2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d",
+		"ab",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
 	},
 	{
-		"abc",
 		"4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa",
-		"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23",
-		"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
-		"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+		"abc",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
 	},
 	{
-		"abcd",
 		"0c9f157ab030fb06e957c14e3938dc5908962e5dd7b66f04a36fc534",
-		"d2891c7978be0e24948f37caa415b87cb5cbe2b26b7bad9dc6391b8a6f6ddcc9",
-		"1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b",
-		"d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f",
+		"abcd",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
 	},
 	{
-		"abcde",
 		"880e79bb0a1d2c9b7528d851edb6b8342c58c831de98123b432a4515",
-		"de8322b46e78b67d4431997070703e9764e03a1237b896fd8b379ed4576e8363",
-		"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0",
-		"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1",
+		"abcde",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
 	},
 	{
-		"abcdef",
 		"236c829cfea4fd6d4de61ad15fcf34dca62342adaf9f2001c16f29b8",
-		"e4fdcb11d1ac14e698743acd8805174cea5ddc0d312e3e47f6372032571bad84",
-		"c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5",
-		"e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7",
+		"abcdef",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
 	},
 	{
-		"abcdefg",
 		"4767af672b3ed107f25018dc22d6fa4b07d156e13b720971e2c4f6bf",
-		"a8117f680bdceb5d1443617cbdae9255f6900075422326a972fdd2f65ba9bee3",
-		"9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22",
-		"d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c",
+		"abcdefg",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
 	},
 	{
-		"abcdefgh",
 		"792e25e0ae286d123a38950007e037d3122e76c4ee201668c385edab",
-		"a29b9645d2a02a8b582888d044199787220e316bf2e89d1422d3df26bf545bbe",
-		"9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806",
-		"a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce",
+		"abcdefgh",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
 	},
 	{
-		"abcdefghi",
 		"56b275d36127dc070cda4019baf2ce2579a25d8c67fa2bc9be61b539",
-		"b955095330f9c8188d11884ec1679dc44c9c5b25ff9bda700416df9cdd39188f",
-		"ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df",
-		"f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe",
+		"abcdefghi",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
 	},
 	{
-		"abcdefghij",
 		"f809423cbb25e81a2a64aecee2cd5fdc7d91d5db583901fbf1db3116",
-		"550762913d51eefbcd1a55068fcfc9b154fd11c1078b996df0d926ea59d2a68d",
-		"a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c",
-		"ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745",
+		"abcdefghij",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05",
 	},
 	{
-		"Discard medicine more than two years old.",
 		"4c46e10b5b72204e509c3c06072cea970bc020cd45a61a0acdfa97ac",
-		"690c8ad3916cefd3ad29226d9875965e3ee9ec0d4482eacc248f2ff4aa0d8e5b",
-		"86f58ec2d74d1b7f8eb0c2ff0967316699639e8d4eb129de54bdf34c96cdbabe200d052149f2dd787f43571ba74670d4",
-		"2210d99af9c8bdecda1b4beff822136753d8342505ddce37f1314e2cdbb488c6016bdaa9bd2ffa513dd5de2e4b50f031393d8ab61f773b0e0130d7381e0f8a1d",
+		"Discard medicine more than two years old.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14",
 	},
 	{
-		"He who has a shady past knows that nice guys finish last.",
 		"cb0cef13c1848d91a6d02637c7c520de1914ad4a7aea824671cc328e",
-		"25938ca49f7ef1178ce81620842b65e576245fcaed86026a36b516b80bb86b3b",
-		"ae4a2b639ca9bfa04b1855d5a05fe7f230994f790891c6979103e2605f660c4c1262a48142dcbeb57a1914ba5f7c3fa7",
-		"a687a8985b4d8d0a24f115fe272255c6afaf3909225838546159c1ed685c211a203796ae8ecc4c81a5b6315919b3a64f10713da07e341fcdbb08541bf03066ce",
+		"He who has a shady past knows that nice guys finish last.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
 	},
 	{
-		"I wouldn't marry him with a ten foot pole.",
 		"6c7bd0f3a6544ea698006c2ea583a85f80ea2913590a186db8bb2f1b",
-		"698e420c3a7038e53d8e73f4be2b02e03b93464ac1a61ebe69f557079921ef65",
-		"40ae213df6436eca952aa6841886fcdb82908ef1576a99c8f49bb9dd5023169f7c53035abdda0b54c302f4974e2105e7",
-		"8ddb0392e818b7d585ab22769a50df660d9f6d559cca3afc5691b8ca91b8451374e42bcdabd64589ed7c91d85f626596228a5c8572677eb98bc6b624befb7af8",
+		"I wouldn't marry him with a ten foot pole.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15",
 	},
 	{
-		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
 		"981323be3eca6ccfa598e58dd74ed8cb05d5f7f6653b7604b684f904",
-		"839b414d7e3900ee243aa3d1f9b6955720e64041f5ab9bedd3eb0a08da5a2ca8",
-		"e7cf8b873c9bc950f06259aa54309f349cefa72c00d597aebf903e6519a50011dfe355afff064a10701c705693848df9",
-		"26ed8f6ca7f8d44b6a8a54ae39640fa8ad5c673f70ee9ce074ba4ef0d483eea00bab2f61d8695d6b34df9c6c48ae36246362200ed820448bdc03a720366a87c6",
+		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
 	},
 	{
-		"The days of the digital watch are numbered.  -Tom Stoppard",
 		"e6fbf82df5138bf361e826903cadf0612cb2986649ba47a57e1bca99",
-		"5625ecb9d284e54c00b257b67a8cacb25a78db2845c60ef2d29e43c84f236e8e",
-		"c3d4f0f4047181c7d39d34703365f7bf70207183caf2c2f6145f04da895ef69124d9cdeb635da636c3a474e61024e29b",
-		"e5a14bf044be69615aade89afcf1ab0389d5fc302a884d403579d1386a2400c089b0dbb387ed0f463f9ee342f8244d5a38cfbc0e819da9529fbff78368c9a982",
+		"The days of the digital watch are numbered.  -Tom Stoppard",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d",
 	},
 	{
-		"Nepal premier won't resign.",
 		"6ec2cb2ecafc1a9bddaf4caf57344d853e6ded398927d5694fd7714f",
-		"9b81d06bca2f985e6ad3249096ff3c0f2a9ec5bb16ef530d738d19d81e7806f2",
-		"a097aab567e167d5cf93676ed73252a69f9687cb3179bb2d27c9878119e94bf7b7c4b58dc90582edfaf66e11388ed714",
-		"420a1faa48919e14651bed45725abe0f7a58e0f099424c4e5a49194946e38b46c1f8034b18ef169b2e31050d1648e0b982386595f7df47da4b6fd18e55333015",
+		"Nepal premier won't resign.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r",
 	},
 	{
-		"For every action there is an equal and opposite government program.",
 		"7f62f36e716e0badaf4a4658da9d09bea26357a1bc6aeb8cf7c3ae35",
-		"08241df8d91edfcd68bb1a1dada6e0ae1475a5c6e7b8f12d8e24ca43a38240a9",
-		"5026ca45c41fc64712eb65065da92f6467541c78f8966d3fe2c8e3fb769a3ec14215f819654b47bd64f7f0eac17184f3",
-		"d926a863beadb20134db07683535c72007b0e695045876254f341ddcccde132a908c5af57baa6a6a9c63e6649bba0c213dc05fadcf9abccea09f23dcfb637fbe",
+		"For every action there is an equal and opposite government program.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!",
 	},
 	{
-		"His money is twice tainted: 'taint yours and 'taint mine.",
 		"45adffcb86a05ee4d91263a6115dda011b805d442c60836963cb8378",
-		"4ff74d9213a8117745f5d37b5353a774ec81c5dfe65c4c8986a56fc01f2c551e",
-		"ac1cc0f5ac8d5f5514a7b738ac322b7fb52a161b449c3672e9b6a6ad1a5e4b26b001cf3bad24c56598676ca17d4b445a",
-		"9a98dd9bb67d0da7bf83da5313dff4fd60a4bac0094f1b05633690ffa7f6d61de9a1d4f8617937d560833a9aaa9ccafe3fd24db418d0e728833545cadd3ad92d",
+		"His money is twice tainted: 'taint yours and 'taint mine.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
 	},
 	{
-		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
 		"51cb518f1f68daa901a3075a0a5e1acc755b4e5c82cb47687537f880",
-		"b5baf747c307f98849ec881cf0d48605ae4edd386372aea9b26e71db517e650b",
-		"722d10c5de371ec0c8c4b5247ac8a5f1d240d68c73f8da13d8b25f0166d6f309bf9561979a111a0049405771d201941a",
-		"d7fde2d2351efade52f4211d3746a0780a26eec3df9b2ed575368a8a1c09ec452402293a8ea4eceb5a4f60064ea29b13cdd86918cd7a4faf366160b009804107",
+		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
 	},
 	{
-		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
 		"3b59c5e64b0da7bfc18d7017bf458d90f2c83601ff1afc6263ac0993",
-		"7eef0538ebd7ecf18611d23b0e1cd26a74d65b929a2e374197dc66e755ca4944",
-		"dc2d3ea18bfa10549c63bf2b75b39b5167a80c12aff0e05443168ea87ff149fb0eda5e0bd234eb5d48c7d02ffc5807f1",
-		"b0f35ffa2697359c33a56f5c0cf715c7aeed96da9905ca2698acadb08fbc9e669bf566b6bd5d61a3e86dc22999bcc9f2224e33d1d4f32a228cf9d0349e2db518",
+		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%",
 	},
 	{
-		"size:  a.out:  bad magic",
 		"6a9525c0fac0f91b489bc4f0f539b9ec4a156a4e98bc15b655c2c881",
-		"d05600964f83f55323104aadab434f32391c029718a7690d08ddb2d7e8708443",
-		"1d67c969e2a945ae5346d2139760261504d4ba164c522443afe19ef3e29b152a4c52445489cfc9d7215e5a450e8e1e4e",
-		"3d2e5f91778c9e66f7e061293aaa8a8fc742dd3b2e4f483772464b1144189b49273e610e5cccd7a81a19ca1fa70f16b10f1a100a4d8c1372336be8484c64b311",
+		"size:  a.out:  bad magic",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f",
 	},
 	{
-		"The major problem is with sendmail.  -Mark Horton",
 		"a1b2b2905b1527d682049c6a76e35c7d8c72551abfe7833ac1be595f",
-		"53ed5f9b5c0b674ac0f3425d9f9a5d462655b07cc90f5d0f692eec093884a607",
-		"5ff8e075e465646e7b73ef36d812c6e9f7d60fa6ea0e533e5569b4f73cde53cdd2cc787f33540af57cca3fe467d32fe0",
-		"b2f68ff58ac015efb1c94c908b0d8c2bf06f491e4de8e6302c49016f7f8a33eac3e959856c7fddbc464de618701338a4b46f76dbfaf9a1e5262b5f40639771c7",
+		"The major problem is with sendmail.  -Mark Horton",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18",
 	},
 	{
-		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
 		"76cf045c76a5f2e3d64d56c3cdba6a25479334611bc375460526f8c1",
-		"5a0147685a44eea2435dbd582724efca7637acd9c428e5e1a05115bc3bc2a0e0",
-		"5bd0a997a67c9ae1979a894eb0cde403dde003c9b6f2c03cf21925c42ff4e1176e6df1ca005381612ef18457b9b7ec3b",
-		"d8c92db5fdf52cf8215e4df3b4909d29203ff4d00e9ad0b64a6a4e04dec5e74f62e7c35c7fb881bd5de95442123df8f57a489b0ae616bd326f84d10021121c57",
+		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$",
 	},
 	{
-		"If the enemy is within range, then so are you.",
 		"4473671daeecfdb6f6c5bc06b26374aa5e497cc37119fe14144c430c",
-		"1152c9b27a99dbf4057d21438f4e63dd0cd0977d5ff12317c64d3b97fcac875a",
-		"1eee6da33e7e54fc5be52ae23b94b16ba4d2a947ae4505c6a3edfc7401151ea5205ac01b669b56f27d8ef7f175ed7762",
-		"19a9f8dc0a233e464e8566ad3ca9b91e459a7b8c4780985b015776e1bf239a19bc233d0556343e2b0a9bc220900b4ebf4f8bdf89ff8efeaf79602d6849e6f72e",
+		"If the enemy is within range, then so are you.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17",
 	},
 	{
-		"It's well we cannot hear the screams/That we create in others' dreams.",
 		"6accb6394758523fcd453d47d37ebd10868957a0a9e81c796736abf8",
-		"105e890f5d5cf1748d9a7b4cdaf58b69855779deebc2097747c2210a17b2cb51",
-		"76b06e9dea66bfbb1a96029426dc0dfd7830bd297eb447ff5358d94a87cd00c88b59df2493fef56ecbb5231073892ea9",
-		"00b4c41f307bde87301cdc5b5ab1ae9a592e8ecbb2021dd7bc4b34e2ace60741cc362560bec566ba35178595a91932b8d5357e2c9cec92d393b0fa7831852476",
+		"It's well we cannot hear the screams/That we create in others' dreams.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#",
 	},
 	{
-		"You remind me of a TV show, but that's all right: I watch it anyway.",
 		"6f173f4b6eac7f2a73eaa0833c4563752df2c869dc00b7d30219e12e",
-		"74644ead770da1434365cd912656fe1aca2056d3039d39f10eb1151bddb32cf3",
-		"12acaf21452cff586143e3f5db0bfdf7802c057e1adf2a619031c4e1b0ccc4208cf6cef8fe722bbaa2fb46a30d9135d8",
-		"91eccc3d5375fd026e4d6787874b1dce201cecd8a27dbded5065728cb2d09c58a3d467bb1faf353bf7ba567e005245d5321b55bc344f7c07b91cb6f26c959be7",
+		"You remind me of a TV show, but that's all right: I watch it anyway.",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"",
 	},
 	{
-		"C is as portable as Stonehedge!!",
 		"db05bf4d0f73325208755f4af96cfac6cb3db5dbfc323d675d68f938",
-		"50a234625de5587581883dad9ef399460928032a5ea6bd005d7dc7b68d8cc3d6",
-		"0fc23d7f4183efd186f0bc4fc5db867e026e2146b06cb3d52f4bdbd57d1740122caa853b41868b197b2ac759db39df88",
-		"fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7be128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7",
+		"C is as portable as Stonehedge!!",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10",
 	},
 	{
-		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
 		"05ffa71bb02e855de1aaee1777b3bdbaf7507646f19c4c6aa29933d0",
-		"a7a3846005f8a9935a0a2d43e7fd56d95132a9a3609bf3296ef80b8218acffa0",
-		"bc805578a7f85d34a86a32976e1c34fe65cf815186fbef76f46ef99cda10723f971f3f1464d488243f5e29db7488598d",
-		"2ecdec235c1fa4fc2a154d8fba1dddb8a72a1ad73838b51d792331d143f8b96a9f6fcb0f34d7caa351fe6d88771c4f105040e0392f06e0621689d33b2f3ba92e",
+		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
 	},
 	{
-		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
 		"3ad3c89e15b91e6273534c5d18adadbb528e7b840b288f64e81b8c6d",
-		"688ff03e367680757aa9906cb1e2ad218c51f4526dc0426ea229a5ba9d002c69",
-		"b23918399a12ebf4431559eec3813eaf7412e875fd7464f16d581e473330842d2e96c6be49a7ce3f9bb0b8bc0fcbe0fe",
-		"7ad681f6f96f82f7abfa7ecc0334e8fa16d3dc1cdc45b60b7af43fe4075d2357c0c1d60e98350f1afb1f2fe7a4d7cd2ad55b88e458e06b73c40b437331f5dab4",
+		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1The fugacity of a constituent in a mixture of gases at a given tem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B",
 	},
 	{
-		"How can you write a big system without C++?  -Paul Glick",
 		"e3763669d1b760c1be7bfcb6625f92300a8430419d1dbad57ec9f53c",
+		"How can you write a big system without C++?  -Paul Glick",
+		"sha\x05\x8c=7\xc8\x19TM\xa2s\xe1\x99f\x89\xdc\xd4\xd6\x1d\xfa\xb7\xae2\xff\x9c\x82g\x9d\xd5\x14X/\x9f\xcf\x0fm+i{\xd4M\xa8w\xe3os\x04ĉB?\x9d\x85\xa8j\x1d6\xc8\x11\x12歑֒\xa1How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+}
+
+var golden256 = []sha512Test{
+	{
+		"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a",
+		"",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8",
+		"a",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"22d4d37ec6370571af7109fb12eae79673d5f7c83e6e677083faa3cfac3b2c14",
+		"ab",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23",
+		"abc",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"d2891c7978be0e24948f37caa415b87cb5cbe2b26b7bad9dc6391b8a6f6ddcc9",
+		"abcd",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"de8322b46e78b67d4431997070703e9764e03a1237b896fd8b379ed4576e8363",
+		"abcde",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"e4fdcb11d1ac14e698743acd8805174cea5ddc0d312e3e47f6372032571bad84",
+		"abcdef",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"a8117f680bdceb5d1443617cbdae9255f6900075422326a972fdd2f65ba9bee3",
+		"abcdefg",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"a29b9645d2a02a8b582888d044199787220e316bf2e89d1422d3df26bf545bbe",
+		"abcdefgh",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"b955095330f9c8188d11884ec1679dc44c9c5b25ff9bda700416df9cdd39188f",
+		"abcdefghi",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"550762913d51eefbcd1a55068fcfc9b154fd11c1078b996df0d926ea59d2a68d",
+		"abcdefghij",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05",
+	},
+	{
+		"690c8ad3916cefd3ad29226d9875965e3ee9ec0d4482eacc248f2ff4aa0d8e5b",
+		"Discard medicine more than two years old.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14",
+	},
+	{
+		"25938ca49f7ef1178ce81620842b65e576245fcaed86026a36b516b80bb86b3b",
+		"He who has a shady past knows that nice guys finish last.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"698e420c3a7038e53d8e73f4be2b02e03b93464ac1a61ebe69f557079921ef65",
+		"I wouldn't marry him with a ten foot pole.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15",
+	},
+	{
+		"839b414d7e3900ee243aa3d1f9b6955720e64041f5ab9bedd3eb0a08da5a2ca8",
+		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"5625ecb9d284e54c00b257b67a8cacb25a78db2845c60ef2d29e43c84f236e8e",
+		"The days of the digital watch are numbered.  -Tom Stoppard",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d",
+	},
+	{
+		"9b81d06bca2f985e6ad3249096ff3c0f2a9ec5bb16ef530d738d19d81e7806f2",
+		"Nepal premier won't resign.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r",
+	},
+	{
+		"08241df8d91edfcd68bb1a1dada6e0ae1475a5c6e7b8f12d8e24ca43a38240a9",
+		"For every action there is an equal and opposite government program.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!",
+	},
+	{
+		"4ff74d9213a8117745f5d37b5353a774ec81c5dfe65c4c8986a56fc01f2c551e",
+		"His money is twice tainted: 'taint yours and 'taint mine.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"b5baf747c307f98849ec881cf0d48605ae4edd386372aea9b26e71db517e650b",
+		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"7eef0538ebd7ecf18611d23b0e1cd26a74d65b929a2e374197dc66e755ca4944",
+		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%",
+	},
+	{
+		"d05600964f83f55323104aadab434f32391c029718a7690d08ddb2d7e8708443",
+		"size:  a.out:  bad magic",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f",
+	},
+	{
+		"53ed5f9b5c0b674ac0f3425d9f9a5d462655b07cc90f5d0f692eec093884a607",
+		"The major problem is with sendmail.  -Mark Horton",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18",
+	},
+	{
+		"5a0147685a44eea2435dbd582724efca7637acd9c428e5e1a05115bc3bc2a0e0",
+		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$",
+	},
+	{
+		"1152c9b27a99dbf4057d21438f4e63dd0cd0977d5ff12317c64d3b97fcac875a",
+		"If the enemy is within range, then so are you.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17",
+	},
+	{
+		"105e890f5d5cf1748d9a7b4cdaf58b69855779deebc2097747c2210a17b2cb51",
+		"It's well we cannot hear the screams/That we create in others' dreams.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#",
+	},
+	{
+		"74644ead770da1434365cd912656fe1aca2056d3039d39f10eb1151bddb32cf3",
+		"You remind me of a TV show, but that's all right: I watch it anyway.",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"",
+	},
+	{
+		"50a234625de5587581883dad9ef399460928032a5ea6bd005d7dc7b68d8cc3d6",
+		"C is as portable as Stonehedge!!",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10",
+	},
+	{
+		"a7a3846005f8a9935a0a2d43e7fd56d95132a9a3609bf3296ef80b8218acffa0",
+		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"688ff03e367680757aa9906cb1e2ad218c51f4526dc0426ea229a5ba9d002c69",
+		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2The fugacity of a constituent in a mixture of gases at a given tem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B",
+	},
+	{
 		"3fa46d52094b01021cff5af9a438982b887a5793f624c0a6644149b6b7c3f485",
+		"How can you write a big system without C++?  -Paul Glick",
+		"sha\x06\"1!\x94\xfc+\xf7,\x9fU_\xa3\xc8Ld\xc2#\x93\xb8koS\xb1Q\x968w\x19Y@꽖(>⨎\xff\xe3\xbe^\x1e%S\x869\x92+\x01\x99\xfc,\x85\xb8\xaa\x0e\xb7-܁\xc5,\xa2How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+}
+
+var golden384 = []sha512Test{
+	{
+		"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
+		"",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31",
+		"a",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd",
+		"ab",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+		"abc",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b",
+		"abcd",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0",
+		"abcde",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5",
+		"abcdef",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22",
+		"abcdefg",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806",
+		"abcdefgh",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df",
+		"abcdefghi",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c",
+		"abcdefghij",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05",
+	},
+	{
+		"86f58ec2d74d1b7f8eb0c2ff0967316699639e8d4eb129de54bdf34c96cdbabe200d052149f2dd787f43571ba74670d4",
+		"Discard medicine more than two years old.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14",
+	},
+	{
+		"ae4a2b639ca9bfa04b1855d5a05fe7f230994f790891c6979103e2605f660c4c1262a48142dcbeb57a1914ba5f7c3fa7",
+		"He who has a shady past knows that nice guys finish last.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"40ae213df6436eca952aa6841886fcdb82908ef1576a99c8f49bb9dd5023169f7c53035abdda0b54c302f4974e2105e7",
+		"I wouldn't marry him with a ten foot pole.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15",
+	},
+	{
+		"e7cf8b873c9bc950f06259aa54309f349cefa72c00d597aebf903e6519a50011dfe355afff064a10701c705693848df9",
+		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"c3d4f0f4047181c7d39d34703365f7bf70207183caf2c2f6145f04da895ef69124d9cdeb635da636c3a474e61024e29b",
+		"The days of the digital watch are numbered.  -Tom Stoppard",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d",
+	},
+	{
+		"a097aab567e167d5cf93676ed73252a69f9687cb3179bb2d27c9878119e94bf7b7c4b58dc90582edfaf66e11388ed714",
+		"Nepal premier won't resign.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r",
+	},
+	{
+		"5026ca45c41fc64712eb65065da92f6467541c78f8966d3fe2c8e3fb769a3ec14215f819654b47bd64f7f0eac17184f3",
+		"For every action there is an equal and opposite government program.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!",
+	},
+	{
+		"ac1cc0f5ac8d5f5514a7b738ac322b7fb52a161b449c3672e9b6a6ad1a5e4b26b001cf3bad24c56598676ca17d4b445a",
+		"His money is twice tainted: 'taint yours and 'taint mine.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"722d10c5de371ec0c8c4b5247ac8a5f1d240d68c73f8da13d8b25f0166d6f309bf9561979a111a0049405771d201941a",
+		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"dc2d3ea18bfa10549c63bf2b75b39b5167a80c12aff0e05443168ea87ff149fb0eda5e0bd234eb5d48c7d02ffc5807f1",
+		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%",
+	},
+	{
+		"1d67c969e2a945ae5346d2139760261504d4ba164c522443afe19ef3e29b152a4c52445489cfc9d7215e5a450e8e1e4e",
+		"size:  a.out:  bad magic",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f",
+	},
+	{
+		"5ff8e075e465646e7b73ef36d812c6e9f7d60fa6ea0e533e5569b4f73cde53cdd2cc787f33540af57cca3fe467d32fe0",
+		"The major problem is with sendmail.  -Mark Horton",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18",
+	},
+	{
+		"5bd0a997a67c9ae1979a894eb0cde403dde003c9b6f2c03cf21925c42ff4e1176e6df1ca005381612ef18457b9b7ec3b",
+		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$",
+	},
+	{
+		"1eee6da33e7e54fc5be52ae23b94b16ba4d2a947ae4505c6a3edfc7401151ea5205ac01b669b56f27d8ef7f175ed7762",
+		"If the enemy is within range, then so are you.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17",
+	},
+	{
+		"76b06e9dea66bfbb1a96029426dc0dfd7830bd297eb447ff5358d94a87cd00c88b59df2493fef56ecbb5231073892ea9",
+		"It's well we cannot hear the screams/That we create in others' dreams.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#",
+	},
+	{
+		"12acaf21452cff586143e3f5db0bfdf7802c057e1adf2a619031c4e1b0ccc4208cf6cef8fe722bbaa2fb46a30d9135d8",
+		"You remind me of a TV show, but that's all right: I watch it anyway.",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"",
+	},
+	{
+		"0fc23d7f4183efd186f0bc4fc5db867e026e2146b06cb3d52f4bdbd57d1740122caa853b41868b197b2ac759db39df88",
+		"C is as portable as Stonehedge!!",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10",
+	},
+	{
+		"bc805578a7f85d34a86a32976e1c34fe65cf815186fbef76f46ef99cda10723f971f3f1464d488243f5e29db7488598d",
+		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"b23918399a12ebf4431559eec3813eaf7412e875fd7464f16d581e473330842d2e96c6be49a7ce3f9bb0b8bc0fcbe0fe",
+		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4The fugacity of a constituent in a mixture of gases at a given tem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B",
+	},
+	{
 		"1764b700eb1ead52a2fc33cc28975c2180f1b8faa5038d94cffa8d78154aab16e91dd787e7b0303948ebed62561542c8",
+		"How can you write a big system without C++?  -Paul Glick",
+		"sha\x04˻\x9d]\xc1\x05\x9e\xd8b\x9a)*6|\xd5\a\x91Y\x01Z0p\xdd\x17\x15/\xec\xd8\xf7\x0eY9g3&g\xff\xc0\v1\x8e\xb4J\x87hX\x15\x11\xdb\f.\rd\xf9\x8f\xa7G\xb5H\x1d\xbe\xfaO\xa4How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+}
+
+var golden512 = []sha512Test{
+	{
+		"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+		"",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!y\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
+		"a",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!y\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		"2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d",
+		"ab",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!ya\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+		"abc",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!ya\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+	},
+	{
+		"d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f",
+		"abcd",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1",
+		"abcde",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
+	},
+	{
+		"e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7",
+		"abcdef",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yabc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c",
+		"abcdefg",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yabc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",
+	},
+	{
+		"a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce",
+		"abcdefgh",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe",
+		"abcdefghi",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04",
+	},
+	{
+		"ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745",
+		"abcdefghij",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yabcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05",
+	},
+	{
+		"2210d99af9c8bdecda1b4beff822136753d8342505ddce37f1314e2cdbb488c6016bdaa9bd2ffa513dd5de2e4b50f031393d8ab61f773b0e0130d7381e0f8a1d",
+		"Discard medicine more than two years old.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yDiscard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14",
+	},
+	{
+		"a687a8985b4d8d0a24f115fe272255c6afaf3909225838546159c1ed685c211a203796ae8ecc4c81a5b6315919b3a64f10713da07e341fcdbb08541bf03066ce",
+		"He who has a shady past knows that nice guys finish last.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yHe who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"8ddb0392e818b7d585ab22769a50df660d9f6d559cca3afc5691b8ca91b8451374e42bcdabd64589ed7c91d85f626596228a5c8572677eb98bc6b624befb7af8",
+		"I wouldn't marry him with a ten foot pole.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yI wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15",
+	},
+	{
+		"26ed8f6ca7f8d44b6a8a54ae39640fa8ad5c673f70ee9ce074ba4ef0d483eea00bab2f61d8695d6b34df9c6c48ae36246362200ed820448bdc03a720366a87c6",
+		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yFree! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"e5a14bf044be69615aade89afcf1ab0389d5fc302a884d403579d1386a2400c089b0dbb387ed0f463f9ee342f8244d5a38cfbc0e819da9529fbff78368c9a982",
+		"The days of the digital watch are numbered.  -Tom Stoppard",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yThe days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d",
+	},
+	{
+		"420a1faa48919e14651bed45725abe0f7a58e0f099424c4e5a49194946e38b46c1f8034b18ef169b2e31050d1648e0b982386595f7df47da4b6fd18e55333015",
+		"Nepal premier won't resign.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yNepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r",
+	},
+	{
+		"d926a863beadb20134db07683535c72007b0e695045876254f341ddcccde132a908c5af57baa6a6a9c63e6649bba0c213dc05fadcf9abccea09f23dcfb637fbe",
+		"For every action there is an equal and opposite government program.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yFor every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!",
+	},
+	{
+		"9a98dd9bb67d0da7bf83da5313dff4fd60a4bac0094f1b05633690ffa7f6d61de9a1d4f8617937d560833a9aaa9ccafe3fd24db418d0e728833545cadd3ad92d",
+		"His money is twice tainted: 'taint yours and 'taint mine.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yHis money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
+	},
+	{
+		"d7fde2d2351efade52f4211d3746a0780a26eec3df9b2ed575368a8a1c09ec452402293a8ea4eceb5a4f60064ea29b13cdd86918cd7a4faf366160b009804107",
+		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yThere is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"b0f35ffa2697359c33a56f5c0cf715c7aeed96da9905ca2698acadb08fbc9e669bf566b6bd5d61a3e86dc22999bcc9f2224e33d1d4f32a228cf9d0349e2db518",
+		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yIt's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%",
+	},
+	{
+		"3d2e5f91778c9e66f7e061293aaa8a8fc742dd3b2e4f483772464b1144189b49273e610e5cccd7a81a19ca1fa70f16b10f1a100a4d8c1372336be8484c64b311",
+		"size:  a.out:  bad magic",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!ysize:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f",
+	},
+	{
+		"b2f68ff58ac015efb1c94c908b0d8c2bf06f491e4de8e6302c49016f7f8a33eac3e959856c7fddbc464de618701338a4b46f76dbfaf9a1e5262b5f40639771c7",
+		"The major problem is with sendmail.  -Mark Horton",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yThe major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18",
+	},
+	{
+		"d8c92db5fdf52cf8215e4df3b4909d29203ff4d00e9ad0b64a6a4e04dec5e74f62e7c35c7fb881bd5de95442123df8f57a489b0ae616bd326f84d10021121c57",
+		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yGive me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$",
+	},
+	{
+		"19a9f8dc0a233e464e8566ad3ca9b91e459a7b8c4780985b015776e1bf239a19bc233d0556343e2b0a9bc220900b4ebf4f8bdf89ff8efeaf79602d6849e6f72e",
+		"If the enemy is within range, then so are you.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yIf the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17",
+	},
+	{
+		"00b4c41f307bde87301cdc5b5ab1ae9a592e8ecbb2021dd7bc4b34e2ace60741cc362560bec566ba35178595a91932b8d5357e2c9cec92d393b0fa7831852476",
+		"It's well we cannot hear the screams/That we create in others' dreams.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yIt's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#",
+	},
+	{
+		"91eccc3d5375fd026e4d6787874b1dce201cecd8a27dbded5065728cb2d09c58a3d467bb1faf353bf7ba567e005245d5321b55bc344f7c07b91cb6f26c959be7",
+		"You remind me of a TV show, but that's all right: I watch it anyway.",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yYou remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"",
+	},
+	{
+		"fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7be128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7",
+		"C is as portable as Stonehedge!!",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yC is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10",
+	},
+	{
+		"2ecdec235c1fa4fc2a154d8fba1dddb8a72a1ad73838b51d792331d143f8b96a9f6fcb0f34d7caa351fe6d88771c4f105040e0392f06e0621689d33b2f3ba92e",
+		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yEven if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
+	},
+	{
+		"7ad681f6f96f82f7abfa7ecc0334e8fa16d3dc1cdc45b60b7af43fe4075d2357c0c1d60e98350f1afb1f2fe7a4d7cd2ad55b88e458e06b73c40b437331f5dab4",
+		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yThe fugacity of a constituent in a mixture of gases at a given tem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B",
+	},
+	{
 		"833f9248ab4a3b9e5131f745fda1ffd2dd435b30e965957e78291c7ab73605fd1912b0794e5c233ab0a12d205a39778d19b83515d6a47003f19cdee51d98c7e0",
+		"How can you write a big system without C++?  -Paul Glick",
+		"sha\aj\t\xe6g\xf3\xbc\xc9\b\xbbg\xae\x85\x84ʧ;<n\xf3r\xfe\x94\xf8+\xa5O\xf5:_\x1d6\xf1Q\x0eR\u007f\xad\xe6\x82ћ\x05h\x8c+>l\x1f\x1f\x83٫\xfbA\xbdk[\xe0\xcd\x19\x13~!yHow can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c",
 	},
 }
 
@@ -265,17 +677,119 @@
 }
 
 func TestGolden(t *testing.T) {
-	for _, test := range golden {
-		in := []byte(test.in)
+	tests := []struct {
+		name        string
+		oneShotHash func(in []byte) []byte
+		digest      hash.Hash
+		golden      []sha512Test
+	}{
+		{
+			"SHA512/224",
+			func(in []byte) []byte { a := Sum512_224(in); return a[:] },
+			New512_224(),
+			golden224,
+		},
+		{
+			"SHA512/256",
+			func(in []byte) []byte { a := Sum512_256(in); return a[:] },
+			New512_256(),
+			golden256,
+		},
+		{
+			"SHA384",
+			func(in []byte) []byte { a := Sum384(in); return a[:] },
+			New384(),
+			golden384,
+		},
+		{
+			"SHA512",
+			func(in []byte) []byte { a := Sum512(in); return a[:] },
+			New(),
+			golden512,
+		},
+	}
+	for _, tt := range tests {
+		for _, test := range tt.golden {
+			in := []byte(test.in)
+			testHash(t, tt.name, test.in, test.out, tt.oneShotHash(in), tt.digest)
+		}
+	}
+}
 
-		sum224 := Sum512_224(in)
-		sum256 := Sum512_256(in)
-		sum384 := Sum384(in)
-		sum512 := Sum512(in)
-		testHash(t, "SHA512/224", test.in, test.out224, sum224[:], New512_224())
-		testHash(t, "SHA512/256", test.in, test.out256, sum256[:], New512_256())
-		testHash(t, "SHA384", test.in, test.out384, sum384[:], New384())
-		testHash(t, "SHA512", test.in, test.out512, sum512[:], New())
+func TestGoldenMarshal(t *testing.T) {
+	tests := []struct {
+		name    string
+		newHash func() hash.Hash
+		golden  []sha512Test
+	}{
+		{"512/224", New512_224, golden224},
+		{"512/256", New512_256, golden256},
+		{"384", New384, golden384},
+		{"512", New, golden512},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			for _, test := range tt.golden {
+				h := tt.newHash()
+				h2 := tt.newHash()
+
+				io.WriteString(h, test.in[:len(test.in)/2])
+
+				state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+				if err != nil {
+					t.Errorf("could not marshal: %v", err)
+					return
+				}
+
+				if string(state) != test.halfState {
+					t.Errorf("New%s(%q) state = %q, want %q", tt.name, test.in, state, test.halfState)
+					continue
+				}
+
+				if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+					t.Errorf("could not unmarshal: %v", err)
+					return
+				}
+
+				io.WriteString(h, test.in[len(test.in)/2:])
+				io.WriteString(h2, test.in[len(test.in)/2:])
+
+				if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
+					t.Errorf("New%s(%q) = 0x%x != marshaled 0x%x", tt.name, test.in, actual, actual2)
+				}
+			}
+		})
+	}
+}
+
+func TestMarshalMismatch(t *testing.T) {
+	h := []func() hash.Hash{
+		New,
+		New384,
+		New512_224,
+		New512_256,
+	}
+
+	for i, fn1 := range h {
+		for j, fn2 := range h {
+			if i == j {
+				continue
+			}
+
+			h1 := fn1()
+			h2 := fn2()
+
+			state, err := h1.(encoding.BinaryMarshaler).MarshalBinary()
+			if err != nil {
+				t.Errorf("i=%d: could not marshal: %v", i, err)
+				continue
+			}
+
+			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err == nil {
+				t.Errorf("i=%d, j=%d: got no error , expected one: %v", i, j, err)
+			}
+		}
 	}
 }
 
diff --git a/src/crypto/sha512/sha512block_amd64.s b/src/crypto/sha512/sha512block_amd64.s
index 5b42420..a023566 100644
--- a/src/crypto/sha512/sha512block_amd64.s
+++ b/src/crypto/sha512/sha512block_amd64.s
@@ -340,8 +340,7 @@
 	MOVQ (6*8)(SI), R10
 	MOVQ (7*8)(SI), R11
 
-	MOVQ    $PSHUFFLE_BYTE_FLIP_MASK<>(SB), R12
-	VMOVDQU (R12), Y9
+	VMOVDQU PSHUFFLE_BYTE_FLIP_MASK<>(SB), Y9
 
 loop0:
 	MOVQ ·_K+0(SB), BP
@@ -419,9 +418,7 @@
 
 	VPERM2F128 $0x0, Y0, Y0, Y4
 
-	MOVQ $MASK_YMM_LO<>(SB), R13
-
-	VPAND (R13), Y0, Y0
+	VPAND MASK_YMM_LO<>(SB), Y0, Y0
 
 	VPERM2F128 $0x11, Y7, Y7, Y2
 	VPSRLQ     $6, Y2, Y8
@@ -620,8 +617,7 @@
 
 	VPERM2F128 $0x0, Y0, Y0, Y5
 
-	MOVQ  $MASK_YMM_LO<>(SB), R13
-	VPAND (R13), Y0, Y0
+	VPAND MASK_YMM_LO<>(SB), Y0, Y0
 
 	VPERM2F128 $0x11, Y4, Y4, Y2
 	VPSRLQ     $6, Y2, Y8
@@ -820,8 +816,7 @@
 
 	VPERM2F128 $0x0, Y0, Y0, Y6
 
-	MOVQ  $MASK_YMM_LO<>(SB), R13
-	VPAND (R13), Y0, Y0
+	VPAND MASK_YMM_LO<>(SB), Y0, Y0
 
 	VPERM2F128 $0x11, Y5, Y5, Y2
 	VPSRLQ     $6, Y2, Y8
@@ -1021,8 +1016,7 @@
 
 	VPERM2F128 $0x0, Y0, Y0, Y7
 
-	MOVQ  $MASK_YMM_LO<>(SB), R13
-	VPAND (R13), Y0, Y0
+	VPAND MASK_YMM_LO<>(SB), Y0, Y0
 
 	VPERM2F128 $0x11, Y6, Y6, Y2
 	VPSRLQ     $6, Y2, Y8
diff --git a/src/crypto/sha512/sha512block_ppc64le.s b/src/crypto/sha512/sha512block_ppc64le.s
index 4419c00..170e3a6 100644
--- a/src/crypto/sha512/sha512block_ppc64le.s
+++ b/src/crypto/sha512/sha512block_ppc64le.s
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This is a derived work from OpenSSL of SHA-2 using assembly optimizations. The
-// original code was written by Andy Polyakov <appro@openssl.org> and it's dual
-// licensed under OpenSSL and CRYPTOGAMS licenses depending on where you obtain
-// it. For further details see http://www.openssl.org/~appro/cryptogams/.
+// Based on CRYPTOGAMS code with the following comment:
+// # ====================================================================
+// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+// # project. The module is, however, dual licensed under OpenSSL and
+// # CRYPTOGAMS licenses depending on where you obtain it. For further
+// # details see http://www.openssl.org/~appro/cryptogams/.
+// # ====================================================================
 
 #include "textflag.h"
 
diff --git a/src/crypto/subtle/constant_time.go b/src/crypto/subtle/constant_time.go
index 11312b8..9f5fee8 100644
--- a/src/crypto/subtle/constant_time.go
+++ b/src/crypto/subtle/constant_time.go
@@ -29,24 +29,12 @@
 
 // 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)
+	return int((uint32(x^y) - 1) >> 31)
 }
 
 // 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)
+	return int((uint64(uint32(x^y)) - 1) >> 63)
 }
 
 // ConstantTimeCopy copies the contents of y into x (a slice of equal length)
diff --git a/src/crypto/subtle/constant_time_test.go b/src/crypto/subtle/constant_time_test.go
index 619a454..033301a 100644
--- a/src/crypto/subtle/constant_time_test.go
+++ b/src/crypto/subtle/constant_time_test.go
@@ -125,3 +125,35 @@
 		}
 	}
 }
+
+var benchmarkGlobal uint8
+
+func BenchmarkConstantTimeByteEq(b *testing.B) {
+	var x, y uint8
+
+	for i := 0; i < b.N; i++ {
+		x, y = uint8(ConstantTimeByteEq(x, y)), x
+	}
+
+	benchmarkGlobal = x
+}
+
+func BenchmarkConstantTimeEq(b *testing.B) {
+	var x, y int
+
+	for i := 0; i < b.N; i++ {
+		x, y = ConstantTimeEq(int32(x), int32(y)), x
+	}
+
+	benchmarkGlobal = uint8(x)
+}
+
+func BenchmarkConstantTimeLessOrEq(b *testing.B) {
+	var x, y int
+
+	for i := 0; i < b.N; i++ {
+		x, y = ConstantTimeLessOrEq(x, y), x
+	}
+
+	benchmarkGlobal = uint8(x)
+}
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index 5860838..646b107 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -29,10 +29,11 @@
 )
 
 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)
+	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)
+	maxWarnAlertCount = 5            // maximum number of consecutive warning alerts
 
 	minVersion = VersionTLS10
 	maxVersion = VersionTLS12
@@ -126,35 +127,25 @@
 	// 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
-	hashSHA384 uint8 = 5
-)
-
 // 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
-}
-
 // supportedSignatureAlgorithms contains the signature and hash algorithms that
 // the code advertises as supported in a TLS 1.2 ClientHello and in a TLS 1.2
-// CertificateRequest.
-var supportedSignatureAlgorithms = []signatureAndHash{
-	{hashSHA256, signatureRSA},
-	{hashSHA256, signatureECDSA},
-	{hashSHA384, signatureRSA},
-	{hashSHA384, signatureECDSA},
-	{hashSHA1, signatureRSA},
-	{hashSHA1, signatureECDSA},
+// CertificateRequest. The two fields are merged to match with TLS 1.3.
+// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
+var supportedSignatureAlgorithms = []SignatureScheme{
+	PKCS1WithSHA256,
+	ECDSAWithP256AndSHA256,
+	PKCS1WithSHA384,
+	ECDSAWithP384AndSHA384,
+	PKCS1WithSHA512,
+	ECDSAWithP521AndSHA512,
+	PKCS1WithSHA1,
+	ECDSAWithSHA1,
 }
 
 // ConnectionState records basic TLS details about the connection.
@@ -234,6 +225,9 @@
 	ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
 	ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
 	ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
+
+	// Legacy signature and hash algorithms for TLS 1.2.
+	ECDSAWithSHA1 SignatureScheme = 0x0203
 )
 
 // ClientHelloInfo contains information from a ClientHello message in order to
@@ -412,8 +406,9 @@
 	//
 	// If normal verification fails then the handshake will abort before
 	// considering this callback. If normal verification is disabled by
-	// setting InsecureSkipVerify then this callback will be considered but
-	// the verifiedChains argument will always be nil.
+	// setting InsecureSkipVerify, or (for a server) when ClientAuth is
+	// RequestClientCert or RequireAnyClientCert, then this callback will
+	// be considered but the verifiedChains argument will always be nil.
 	VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
 
 	// RootCAs defines the set of root certificate authorities
@@ -471,8 +466,8 @@
 	// connections using that key are compromised.
 	SessionTicketKey [32]byte
 
-	// SessionCache is a cache of ClientSessionState entries for TLS session
-	// resumption.
+	// ClientSessionCache is a cache of ClientSessionState entries for TLS
+	// session resumption.
 	ClientSessionCache ClientSessionCache
 
 	// MinVersion contains the minimum SSL/TLS version that is acceptable.
@@ -961,11 +956,24 @@
 	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
 }
 
-func isSupportedSignatureAndHash(sigHash signatureAndHash, sigHashes []signatureAndHash) bool {
-	for _, s := range sigHashes {
-		if s == sigHash {
+func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {
+	for _, s := range supportedSignatureAlgorithms {
+		if s == sigAlg {
 			return true
 		}
 	}
 	return false
 }
+
+// signatureFromSignatureScheme maps a signature algorithm to the underlying
+// signature method (without hash function).
+func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 {
+	switch signatureAlgorithm {
+	case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
+		return signatureRSA
+	case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
+		return signatureECDSA
+	default:
+		return 0
+	}
+}
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index e6d85aa..31c5053 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -94,6 +94,10 @@
 	bytesSent   int64
 	packetsSent int64
 
+	// warnCount counts the number of consecutive warning alerts received
+	// by Conn.readRecord. Protected by in.Mutex.
+	warnCount int
+
 	// activeCall is an atomic int32; the low bit is whether Close has
 	// been called. the rest of the bits are the number of goroutines
 	// in Conn.Write.
@@ -213,10 +217,11 @@
 	// 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 maximum possible padding length plus the actual length field
+	toCheck := 256
 	// The length of the padded data is public, so we can use an if here
-	if toCheck+1 > len(payload) {
-		toCheck = len(payload) - 1
+	if toCheck > len(payload) {
+		toCheck = len(payload)
 	}
 
 	for i := 0; i < toCheck; i++ {
@@ -657,6 +662,11 @@
 		return c.in.setErrorLocked(err)
 	}
 
+	if typ != recordTypeAlert && len(data) > 0 {
+		// this is a valid non-alert message: reset the count of alerts
+		c.warnCount = 0
+	}
+
 	switch typ {
 	default:
 		c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
@@ -674,6 +684,13 @@
 		case alertLevelWarning:
 			// drop on the floor
 			c.in.freeBlock(b)
+
+			c.warnCount++
+			if c.warnCount > maxWarnAlertCount {
+				c.sendAlert(alertUnexpectedMessage)
+				return c.in.setErrorLocked(errors.New("tls: too many warn alerts"))
+			}
+
 			goto Again
 		case alertLevelError:
 			c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
@@ -686,6 +703,11 @@
 			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
 			break
 		}
+		// Handshake messages are not allowed to fragment across the CCS
+		if c.hand.Len() > 0 {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
 		err := c.in.changeCipherSpec()
 		if err != nil {
 			c.in.setErrorLocked(c.sendAlert(err.(alert)))
diff --git a/src/crypto/tls/conn_test.go b/src/crypto/tls/conn_test.go
index e27c541..5c7f7ce 100644
--- a/src/crypto/tls/conn_test.go
+++ b/src/crypto/tls/conn_test.go
@@ -21,6 +21,12 @@
 	}
 }
 
+// will be initialized with {0, 255, 255, ..., 255}
+var padding255Bad = [256]byte{}
+
+// will be initialized with {255, 255, 255, ..., 255}
+var padding255Good = [256]byte{255}
+
 var paddingTests = []struct {
 	in          []byte
 	good        bool
@@ -36,9 +42,15 @@
 	{[]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},
+	{padding255Bad[:], false, 0},
+	{padding255Good[:], true, 0},
 }
 
 func TestRemovePadding(t *testing.T) {
+	for i := 1; i < len(padding255Bad); i++ {
+		padding255Bad[i] = 255
+		padding255Good[i] = 255
+	}
 	for i, test := range paddingTests {
 		paddingLen, good := extractPadding(test.in)
 		expectedGood := byte(255)
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index a4ca5d3..e5e0df2 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -29,51 +29,38 @@
 	session      *ClientSessionState
 }
 
-// c.out.Mutex <= L; c.handshakeMutex <= L.
-func (c *Conn) clientHandshake() error {
-	if c.config == nil {
-		c.config = defaultConfig()
-	}
-
-	// This may be a renegotiation handshake, in which case some fields
-	// need to be reset.
-	c.didResume = false
-
-	if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
-		return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
+func makeClientHello(config *Config) (*clientHelloMsg, error) {
+	if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
+		return nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
 	}
 
 	nextProtosLength := 0
-	for _, proto := range c.config.NextProtos {
+	for _, proto := range config.NextProtos {
 		if l := len(proto); l == 0 || l > 255 {
-			return errors.New("tls: invalid NextProtos value")
+			return nil, errors.New("tls: invalid NextProtos value")
 		} else {
 			nextProtosLength += 1 + l
 		}
 	}
+
 	if nextProtosLength > 0xffff {
-		return errors.New("tls: NextProtos values too large")
+		return nil, errors.New("tls: NextProtos values too large")
 	}
 
 	hello := &clientHelloMsg{
-		vers:                         c.config.maxVersion(),
+		vers:                         config.maxVersion(),
 		compressionMethods:           []uint8{compressionNone},
 		random:                       make([]byte, 32),
 		ocspStapling:                 true,
 		scts:                         true,
-		serverName:                   hostnameInSNI(c.config.ServerName),
-		supportedCurves:              c.config.curvePreferences(),
+		serverName:                   hostnameInSNI(config.ServerName),
+		supportedCurves:              config.curvePreferences(),
 		supportedPoints:              []uint8{pointFormatUncompressed},
-		nextProtoNeg:                 len(c.config.NextProtos) > 0,
+		nextProtoNeg:                 len(config.NextProtos) > 0,
 		secureRenegotiationSupported: true,
-		alpnProtocols:                c.config.NextProtos,
+		alpnProtocols:                config.NextProtos,
 	}
-
-	if c.handshakes > 0 {
-		hello.secureRenegotiation = c.clientFinished[:]
-	}
-
-	possibleCipherSuites := c.config.cipherSuites()
+	possibleCipherSuites := config.cipherSuites()
 	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
 
 NextCipherSuite:
@@ -92,14 +79,35 @@
 		}
 	}
 
-	_, err := io.ReadFull(c.config.rand(), hello.random)
+	_, err := io.ReadFull(config.rand(), hello.random)
 	if err != nil {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: short read from Rand: " + err.Error())
+		return nil, errors.New("tls: short read from Rand: " + err.Error())
 	}
 
 	if hello.vers >= VersionTLS12 {
-		hello.signatureAndHashes = supportedSignatureAlgorithms
+		hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+	}
+
+	return hello, nil
+}
+
+// c.out.Mutex <= L; c.handshakeMutex <= L.
+func (c *Conn) clientHandshake() error {
+	if c.config == nil {
+		c.config = defaultConfig()
+	}
+
+	// This may be a renegotiation handshake, in which case some fields
+	// need to be reset.
+	c.didResume = false
+
+	hello, err := makeClientHello(c.config)
+	if err != nil {
+		return err
+	}
+
+	if c.handshakes > 0 {
+		hello.secureRenegotiation = c.clientFinished[:]
 	}
 
 	var session *ClientSessionState
@@ -147,12 +155,36 @@
 		// (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())
 		}
 	}
 
-	if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
+	hs := &clientHandshakeState{
+		c:       c,
+		hello:   hello,
+		session: session,
+	}
+
+	if err = hs.handshake(); err != nil {
+		return err
+	}
+
+	// If we had a successful handshake and hs.session is different from
+	// the one already cached - cache a new one
+	if sessionCache != nil && hs.session != nil && session != hs.session {
+		sessionCache.Put(cacheKey, hs.session)
+	}
+
+	return nil
+}
+
+// Does the handshake, either a full one or resumes old session.
+// Requires hs.c, hs.hello, and, optionally, hs.session to be set.
+func (hs *clientHandshakeState) handshake() error {
+	c := hs.c
+
+	// send ClientHello
+	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
 		return err
 	}
 
@@ -160,34 +192,19 @@
 	if err != nil {
 		return err
 	}
-	serverHello, ok := msg.(*serverHelloMsg)
-	if !ok {
+
+	var ok bool
+	if hs.serverHello, ok = msg.(*serverHelloMsg); !ok {
 		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverHello, msg)
+		return unexpectedMessageError(hs.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(hello.cipherSuites, serverHello.cipherSuite)
-	if suite == nil {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: server chose an unconfigured cipher suite")
+	if err = hs.pickTLSVersion(); err != nil {
+		return err
 	}
 
-	hs := &clientHandshakeState{
-		c:            c,
-		serverHello:  serverHello,
-		hello:        hello,
-		suite:        suite,
-		finishedHash: newFinishedHash(c.vers, suite),
-		session:      session,
+	if err = hs.pickCipherSuite(); err != nil {
+		return err
 	}
 
 	isResume, err := hs.processServerHello()
@@ -195,6 +212,8 @@
 		return err
 	}
 
+	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+
 	// No signatures of the handshake are needed in a resumption.
 	// Otherwise, in a full handshake, if we don't have any certificates
 	// configured then we will never send a CertificateVerify message and
@@ -246,13 +265,33 @@
 		}
 	}
 
-	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) pickTLSVersion() error {
+	vers, ok := hs.c.config.mutualVersion(hs.serverHello.vers)
+	if !ok || vers < VersionTLS10 {
+		// TLS 1.0 is the minimum version supported as a client.
+		hs.c.sendAlert(alertProtocolVersion)
+		return fmt.Errorf("tls: server selected unsupported protocol version %x", hs.serverHello.vers)
+	}
+
+	hs.c.vers = vers
+	hs.c.haveVers = true
+
+	return nil
+}
+
+func (hs *clientHandshakeState) pickCipherSuite() error {
+	if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
+		hs.c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: server chose an unconfigured cipher suite")
+	}
+
+	hs.c.cipherSuite = hs.suite.id
 	return nil
 }
 
@@ -333,26 +372,34 @@
 		}
 	}
 
-	if hs.serverHello.ocspStapling {
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-		cs, ok := msg.(*certificateStatusMsg)
-		if !ok {
+	msg, err = c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	cs, ok := msg.(*certificateStatusMsg)
+	if ok {
+		// RFC4366 on Certificate Status Request:
+		// The server MAY return a "certificate_status" message.
+
+		if !hs.serverHello.ocspStapling {
+			// If a server returns a "CertificateStatus" message, then the
+			// server MUST have included an extension of type "status_request"
+			// with empty "extension_data" in the extended server hello.
+
 			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(cs, msg)
+			return errors.New("tls: received unexpected CertificateStatus message")
 		}
 		hs.finishedHash.Write(cs.marshal())
 
 		if cs.statusType == statusTypeOCSP {
 			c.ocspResponse = cs.response
 		}
-	}
 
-	msg, err = c.readHandshake()
-	if err != nil {
-		return err
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
 	}
 
 	keyAgreement := hs.suite.ka(c.vers)
@@ -443,12 +490,15 @@
 			return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
 		}
 
-		certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType)
-		if err != nil {
-			c.sendAlert(alertInternalError)
-			return err
+		// SignatureAndHashAlgorithm was introduced in TLS 1.2.
+		if certVerify.hasSignatureAndHash {
+			certVerify.signatureAlgorithm, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.supportedSignatureAlgorithms, signatureType)
+			if err != nil {
+				c.sendAlert(alertInternalError)
+				return err
+			}
 		}
-		digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
+		digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(signatureType, certVerify.signatureAlgorithm, hs.masterSecret)
 		if err != nil {
 			c.sendAlert(alertInternalError)
 			return err
@@ -707,10 +757,7 @@
 				signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
 			}
 		} else {
-			signatureSchemes = make([]SignatureScheme, 0, len(certReq.signatureAndHashes))
-			for _, sah := range certReq.signatureAndHashes {
-				signatureSchemes = append(signatureSchemes, SignatureScheme(sah.hash)<<8+SignatureScheme(sah.signature))
-			}
+			signatureSchemes = certReq.supportedSignatureAlgorithms
 		}
 
 		return c.config.GetClientCertificate(&CertificateRequestInfo{
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 5851f89..cc3ab71 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -85,7 +85,7 @@
 	o.all = append(o.all, data...)
 
 	for {
-		i := bytes.Index(o.line, []byte{'\n'})
+		i := bytes.IndexByte(o.line, '\n')
 		if i < 0 {
 			break
 		}
@@ -1189,7 +1189,7 @@
 					// callback should still be called but
 					// validatedChains must be empty.
 					if l := len(validatedChains); l != 0 {
-						return errors.New("got len(validatedChains) = 0, wanted zero")
+						return fmt.Errorf("got len(validatedChains) = %d, wanted zero", l)
 					}
 					*called = true
 					return nil
@@ -1438,19 +1438,23 @@
 }
 
 var getClientCertificateTests = []struct {
-	setup               func(*Config)
+	setup               func(*Config, *Config)
 	expectedClientError string
 	verify              func(*testing.T, int, *ConnectionState)
 }{
 	{
-		func(clientConfig *Config) {
+		func(clientConfig, serverConfig *Config) {
 			// Returning a Certificate with no certificate data
 			// should result in an empty message being sent to the
 			// server.
+			serverConfig.ClientCAs = nil
 			clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
 				if len(cri.SignatureSchemes) == 0 {
 					panic("empty SignatureSchemes")
 				}
+				if len(cri.AcceptableCAs) != 0 {
+					panic("AcceptableCAs should have been empty")
+				}
 				return new(Certificate), nil
 			}
 		},
@@ -1462,7 +1466,7 @@
 		},
 	},
 	{
-		func(clientConfig *Config) {
+		func(clientConfig, serverConfig *Config) {
 			// With TLS 1.1, the SignatureSchemes should be
 			// synthesised from the supported certificate types.
 			clientConfig.MaxVersion = VersionTLS11
@@ -1481,7 +1485,7 @@
 		},
 	},
 	{
-		func(clientConfig *Config) {
+		func(clientConfig, serverConfig *Config) {
 			// Returning an error should abort the handshake with
 			// that error.
 			clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
@@ -1493,14 +1497,21 @@
 		},
 	},
 	{
-		func(clientConfig *Config) {
+		func(clientConfig, serverConfig *Config) {
 			clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
-				return &testConfig.Certificates[0], nil
+				if len(cri.AcceptableCAs) == 0 {
+					panic("empty AcceptableCAs")
+				}
+				cert := &Certificate{
+					Certificate: [][]byte{testRSACertificate},
+					PrivateKey:  testRSAPrivateKey,
+				}
+				return cert, nil
 			}
 		},
 		"",
 		func(t *testing.T, testNum int, cs *ConnectionState) {
-			if l := len(cs.VerifiedChains); l != 0 {
+			if len(cs.VerifiedChains) == 0 {
 				t.Errorf("#%d: expected some verified chains, but found none", testNum)
 			}
 		},
@@ -1515,13 +1526,15 @@
 
 	for i, test := range getClientCertificateTests {
 		serverConfig := testConfig.Clone()
-		serverConfig.ClientAuth = RequestClientCert
+		serverConfig.ClientAuth = VerifyClientCertIfGiven
 		serverConfig.RootCAs = x509.NewCertPool()
 		serverConfig.RootCAs.AddCert(issuer)
+		serverConfig.ClientCAs = serverConfig.RootCAs
+		serverConfig.Time = func() time.Time { return time.Unix(1476984729, 0) }
 
 		clientConfig := testConfig.Clone()
 
-		test.setup(clientConfig)
+		test.setup(clientConfig, serverConfig)
 
 		type serverResult struct {
 			cs  ConnectionState
@@ -1553,6 +1566,8 @@
 				t.Errorf("#%d: client error: %v", i, clientErr)
 			} else if got := clientErr.Error(); got != test.expectedClientError {
 				t.Errorf("#%d: expected client error %q, but got %q", i, test.expectedClientError, got)
+			} else {
+				test.verify(t, i, &result.cs)
 			}
 		} else if len(test.expectedClientError) > 0 {
 			t.Errorf("#%d: expected client error %q, but got no error", i, test.expectedClientError)
diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go
index 0c7581f..f8c8d57 100644
--- a/src/crypto/tls/handshake_messages.go
+++ b/src/crypto/tls/handshake_messages.go
@@ -24,7 +24,7 @@
 	supportedPoints              []uint8
 	ticketSupported              bool
 	sessionTicket                []uint8
-	signatureAndHashes           []signatureAndHash
+	supportedSignatureAlgorithms []SignatureScheme
 	secureRenegotiation          []byte
 	secureRenegotiationSupported bool
 	alpnProtocols                []string
@@ -50,7 +50,7 @@
 		bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
 		m.ticketSupported == m1.ticketSupported &&
 		bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
-		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
+		eqSignatureAlgorithms(m.supportedSignatureAlgorithms, m1.supportedSignatureAlgorithms) &&
 		m.secureRenegotiationSupported == m1.secureRenegotiationSupported &&
 		bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
 		eqStrings(m.alpnProtocols, m1.alpnProtocols)
@@ -87,8 +87,8 @@
 		extensionsLength += len(m.sessionTicket)
 		numExtensions++
 	}
-	if len(m.signatureAndHashes) > 0 {
-		extensionsLength += 2 + 2*len(m.signatureAndHashes)
+	if len(m.supportedSignatureAlgorithms) > 0 {
+		extensionsLength += 2 + 2*len(m.supportedSignatureAlgorithms)
 		numExtensions++
 	}
 	if m.secureRenegotiationSupported {
@@ -234,11 +234,11 @@
 		copy(z, m.sessionTicket)
 		z = z[len(m.sessionTicket):]
 	}
-	if len(m.signatureAndHashes) > 0 {
+	if len(m.supportedSignatureAlgorithms) > 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)
+		l := 2 + 2*len(m.supportedSignatureAlgorithms)
 		z[2] = byte(l >> 8)
 		z[3] = byte(l)
 		z = z[4:]
@@ -247,9 +247,9 @@
 		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
+		for _, sigAlgo := range m.supportedSignatureAlgorithms {
+			z[0] = byte(sigAlgo >> 8)
+			z[1] = byte(sigAlgo)
 			z = z[2:]
 		}
 	}
@@ -344,7 +344,7 @@
 	m.ocspStapling = false
 	m.ticketSupported = false
 	m.sessionTicket = nil
-	m.signatureAndHashes = nil
+	m.supportedSignatureAlgorithms = nil
 	m.alpnProtocols = nil
 	m.scts = false
 
@@ -455,10 +455,9 @@
 			}
 			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]
+			m.supportedSignatureAlgorithms = make([]SignatureScheme, n)
+			for i := range m.supportedSignatureAlgorithms {
+				m.supportedSignatureAlgorithms[i] = SignatureScheme(d[0])<<8 | SignatureScheme(d[1])
 				d = d[2:]
 			}
 		case extensionRenegotiationInfo:
@@ -1203,9 +1202,9 @@
 	// 1.2.
 	hasSignatureAndHash bool
 
-	certificateTypes       []byte
-	signatureAndHashes     []signatureAndHash
-	certificateAuthorities [][]byte
+	certificateTypes             []byte
+	supportedSignatureAlgorithms []SignatureScheme
+	certificateAuthorities       [][]byte
 }
 
 func (m *certificateRequestMsg) equal(i interface{}) bool {
@@ -1217,7 +1216,7 @@
 	return bytes.Equal(m.raw, m1.raw) &&
 		bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
 		eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
-		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
+		eqSignatureAlgorithms(m.supportedSignatureAlgorithms, m1.supportedSignatureAlgorithms)
 }
 
 func (m *certificateRequestMsg) marshal() (x []byte) {
@@ -1234,7 +1233,7 @@
 	length += casLength
 
 	if m.hasSignatureAndHash {
-		length += 2 + 2*len(m.signatureAndHashes)
+		length += 2 + 2*len(m.supportedSignatureAlgorithms)
 	}
 
 	x = make([]byte, 4+length)
@@ -1249,13 +1248,13 @@
 	y := x[5+len(m.certificateTypes):]
 
 	if m.hasSignatureAndHash {
-		n := len(m.signatureAndHashes) * 2
+		n := len(m.supportedSignatureAlgorithms) * 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
+		for _, sigAlgo := range m.supportedSignatureAlgorithms {
+			y[0] = uint8(sigAlgo >> 8)
+			y[1] = uint8(sigAlgo)
 			y = y[2:]
 		}
 	}
@@ -1312,11 +1311,10 @@
 		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]
+		numSigAlgos := sigAndHashLen / 2
+		m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
+		for i := range m.supportedSignatureAlgorithms {
+			m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
 			data = data[2:]
 		}
 	}
@@ -1355,7 +1353,7 @@
 type certificateVerifyMsg struct {
 	raw                 []byte
 	hasSignatureAndHash bool
-	signatureAndHash    signatureAndHash
+	signatureAlgorithm  SignatureScheme
 	signature           []byte
 }
 
@@ -1367,8 +1365,7 @@
 
 	return bytes.Equal(m.raw, m1.raw) &&
 		m.hasSignatureAndHash == m1.hasSignatureAndHash &&
-		m.signatureAndHash.hash == m1.signatureAndHash.hash &&
-		m.signatureAndHash.signature == m1.signatureAndHash.signature &&
+		m.signatureAlgorithm == m1.signatureAlgorithm &&
 		bytes.Equal(m.signature, m1.signature)
 }
 
@@ -1390,8 +1387,8 @@
 	x[3] = uint8(length)
 	y := x[4:]
 	if m.hasSignatureAndHash {
-		y[0] = m.signatureAndHash.hash
-		y[1] = m.signatureAndHash.signature
+		y[0] = uint8(m.signatureAlgorithm >> 8)
+		y[1] = uint8(m.signatureAlgorithm)
 		y = y[2:]
 	}
 	y[0] = uint8(siglength >> 8)
@@ -1417,8 +1414,7 @@
 
 	data = data[4:]
 	if m.hasSignatureAndHash {
-		m.signatureAndHash.hash = data[0]
-		m.signatureAndHash.signature = data[1]
+		m.signatureAlgorithm = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
 		data = data[2:]
 	}
 
@@ -1554,13 +1550,12 @@
 	return true
 }
 
-func eqSignatureAndHashes(x, y []signatureAndHash) bool {
+func eqSignatureAlgorithms(x, y []SignatureScheme) 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 {
+		if v != y[i] {
 			return false
 		}
 	}
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
index 7add97c..37eb748 100644
--- a/src/crypto/tls/handshake_messages_test.go
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -98,8 +98,8 @@
 
 func randomBytes(n int, rand *rand.Rand) []byte {
 	r := make([]byte, n)
-	for i := 0; i < n; i++ {
-		r[i] = byte(rand.Int31())
+	if _, err := rand.Read(r); err != nil {
+		panic("rand.Read failed: " + err.Error())
 	}
 	return r
 }
@@ -116,7 +116,11 @@
 	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())
+		cs := uint16(rand.Int31())
+		if cs == scsvRenegotiation {
+			cs += 1
+		}
+		m.cipherSuites[i] = cs
 	}
 	m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
 	if rand.Intn(10) > 5 {
@@ -141,7 +145,7 @@
 		}
 	}
 	if rand.Intn(10) > 5 {
-		m.signatureAndHashes = supportedSignatureAlgorithms
+		m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
 	}
 	m.alpnProtocols = make([]string, rand.Intn(5))
 	for i := range m.alpnProtocols {
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index ae32848..991b4e9 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -418,7 +418,7 @@
 		}
 		if c.vers >= VersionTLS12 {
 			certReq.hasSignatureAndHash = true
-			certReq.signatureAndHashes = supportedSignatureAlgorithms
+			certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
 		}
 
 		// An empty list of certificateAuthorities signals to
@@ -519,27 +519,30 @@
 		}
 
 		// Determine the signature type.
-		var signatureAndHash signatureAndHash
+		var signatureAlgorithm SignatureScheme
+		var sigType uint8
 		if certVerify.hasSignatureAndHash {
-			signatureAndHash = certVerify.signatureAndHash
-			if !isSupportedSignatureAndHash(signatureAndHash, supportedSignatureAlgorithms) {
+			signatureAlgorithm = certVerify.signatureAlgorithm
+			if !isSupportedSignatureAlgorithm(signatureAlgorithm, supportedSignatureAlgorithms) {
 				return errors.New("tls: unsupported hash function for client certificate")
 			}
+			sigType = signatureFromSignatureScheme(signatureAlgorithm)
 		} else {
 			// Before TLS 1.2 the signature algorithm was implicit
 			// from the key type, and only one hash per signature
-			// algorithm was possible. Leave the hash as zero.
+			// algorithm was possible. Leave signatureAlgorithm
+			// unset.
 			switch pub.(type) {
 			case *ecdsa.PublicKey:
-				signatureAndHash.signature = signatureECDSA
+				sigType = signatureECDSA
 			case *rsa.PublicKey:
-				signatureAndHash.signature = signatureRSA
+				sigType = signatureRSA
 			}
 		}
 
 		switch key := pub.(type) {
 		case *ecdsa.PublicKey:
-			if signatureAndHash.signature != signatureECDSA {
+			if sigType != signatureECDSA {
 				err = errors.New("tls: bad signature type for client's ECDSA certificate")
 				break
 			}
@@ -552,20 +555,20 @@
 				break
 			}
 			var digest []byte
-			if digest, _, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
+			if digest, _, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
 				break
 			}
 			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
 				err = errors.New("tls: ECDSA verification failure")
 			}
 		case *rsa.PublicKey:
-			if signatureAndHash.signature != signatureRSA {
+			if sigType != signatureRSA {
 				err = errors.New("tls: bad signature type for client's RSA certificate")
 				break
 			}
 			var digest []byte
 			var hashFunc crypto.Hash
-			if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
+			if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
 				break
 			}
 			err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
@@ -818,17 +821,12 @@
 		supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:]
 	}
 
-	signatureSchemes := make([]SignatureScheme, 0, len(hs.clientHello.signatureAndHashes))
-	for _, sah := range hs.clientHello.signatureAndHashes {
-		signatureSchemes = append(signatureSchemes, SignatureScheme(sah.hash)<<8+SignatureScheme(sah.signature))
-	}
-
 	hs.cachedClientHelloInfo = &ClientHelloInfo{
 		CipherSuites:      hs.clientHello.cipherSuites,
 		ServerName:        hs.clientHello.serverName,
 		SupportedCurves:   hs.clientHello.supportedCurves,
 		SupportedPoints:   hs.clientHello.supportedPoints,
-		SignatureSchemes:  signatureSchemes,
+		SignatureSchemes:  hs.clientHello.supportedSignatureAlgorithms,
 		SupportedProtos:   hs.clientHello.alpnProtocols,
 		SupportedVersions: supportedVersions,
 		Conn:              hs.c.conn,
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 63845c1..6716021 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -6,9 +6,11 @@
 
 import (
 	"bytes"
+	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rsa"
+	"crypto/x509"
 	"encoding/hex"
 	"encoding/pem"
 	"errors"
@@ -996,6 +998,87 @@
 	runServerTestTLS11(t, test)
 }
 
+func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
+	config := testConfig.Clone()
+	config.CipherSuites = []uint16{cipherSuite}
+	config.CurvePreferences = []CurveID{curve}
+	config.Certificates = make([]Certificate, 1)
+	config.Certificates[0].Certificate = [][]byte{cert}
+	config.Certificates[0].PrivateKey = key
+	config.BuildNameToCertificate()
+
+	clientConn, serverConn := net.Pipe()
+	serverConn = &recordingConn{Conn: serverConn}
+	go func() {
+		client := Client(clientConn, testConfig)
+		client.Handshake()
+	}()
+	server := Server(serverConn, config)
+	if err := server.Handshake(); err != nil {
+		b.Fatalf("handshake failed: %v", err)
+	}
+	serverConn.Close()
+	flows := serverConn.(*recordingConn).flows
+
+	feeder := make(chan struct{})
+	clientConn, serverConn = net.Pipe()
+
+	go func() {
+		for range feeder {
+			for i, f := range flows {
+				if i%2 == 0 {
+					clientConn.Write(f)
+					continue
+				}
+				ff := make([]byte, len(f))
+				n, err := io.ReadFull(clientConn, ff)
+				if err != nil {
+					b.Fatalf("#%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", i+1, err, n, len(ff), ff[:n], f)
+				}
+				if !bytes.Equal(f, ff) {
+					b.Fatalf("#%d: mismatch on read: got:%x want:%x", i+1, ff, f)
+				}
+			}
+		}
+	}()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		feeder <- struct{}{}
+		server := Server(serverConn, config)
+		if err := server.Handshake(); err != nil {
+			b.Fatalf("handshake failed: %v", err)
+		}
+	}
+	close(feeder)
+}
+
+func BenchmarkHandshakeServer(b *testing.B) {
+	b.Run("RSA", func(b *testing.B) {
+		benchmarkHandshakeServer(b, TLS_RSA_WITH_AES_128_GCM_SHA256,
+			0, testRSACertificate, testRSAPrivateKey)
+	})
+	b.Run("ECDHE-P256-RSA", func(b *testing.B) {
+		benchmarkHandshakeServer(b, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+			CurveP256, testRSACertificate, testRSAPrivateKey)
+	})
+	b.Run("ECDHE-P256-ECDSA-P256", func(b *testing.B) {
+		benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+			CurveP256, testP256Certificate, testP256PrivateKey)
+	})
+	b.Run("ECDHE-X25519-ECDSA-P256", func(b *testing.B) {
+		benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+			X25519, testP256Certificate, testP256PrivateKey)
+	})
+	b.Run("ECDHE-P521-ECDSA-P521", func(b *testing.B) {
+		if testECDSAPrivateKey.PublicKey.Curve != elliptic.P521() {
+			b.Fatal("test ECDSA key doesn't use curve P-521")
+		}
+		benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+			CurveP521, testECDSACertificate, testECDSAPrivateKey)
+	})
+}
+
 // clientCertificatePEM and clientKeyPEM were generated with generate_cert.go
 // Thus, they have no ExtKeyUsage fields and trigger an error when verification
 // is turned on.
@@ -1296,6 +1379,8 @@
 
 var testSNICertificate = fromHex("0441883421114c81480804c430820237308201a0a003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a3023310b3009060355040a1302476f311430120603550403130b736e69746573742e636f6d30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a3773075300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e041204109f91161f43433e49a6de6db680d79f60301b0603551d230414301280104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b0500038181007beeecff0230dbb2e7a334af65430b7116e09f327c3bbf918107fc9c66cb497493207ae9b4dbb045cb63d605ec1b5dd485bb69124d68fa298dc776699b47632fd6d73cab57042acb26f083c4087459bc5a3bb3ca4d878d7fe31016b7bc9a627438666566e3389bfaeebe6becc9a0093ceed18d0f9ac79d56f3a73f18188988ed")
 
+var testP256Certificate = fromHex("308201693082010ea00302010202105012dc24e1124ade4f3e153326ff27bf300a06082a8648ce3d04030230123110300e060355040a130741636d6520436f301e170d3137303533313232343934375a170d3138303533313232343934375a30123110300e060355040a130741636d6520436f3059301306072a8648ce3d020106082a8648ce3d03010703420004c02c61c9b16283bbcc14956d886d79b358aa614596975f78cece787146abf74c2d5dc578c0992b4f3c631373479ebf3892efe53d21c4f4f1cc9a11c3536b7f75a3463044300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000300f0603551d1104083006820474657374300a06082a8648ce3d0403020349003046022100963712d6226c7b2bef41512d47e1434131aaca3ba585d666c924df71ac0448b3022100f4d05c725064741aef125f243cdbccaa2a5d485927831f221c43023bd5ae471a")
+
 var testRSAPrivateKey = &rsa.PrivateKey{
 	PublicKey: rsa.PublicKey{
 		N: bigFromString("153980389784927331788354528594524332344709972855165340650588877572729725338415474372475094155672066328274535240275856844648695200875763869073572078279316458648124537905600131008790701752441155668003033945258023841165089852359980273279085783159654751552359397986180318708491098942831252291841441726305535546071"),
@@ -1316,3 +1401,5 @@
 	},
 	D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"),
 }
+
+var testP256PrivateKey, _ = x509.ParseECPrivateKey(fromHex("30770201010420012f3b52bc54c36ba3577ad45034e2e8efe1e6999851284cb848725cfe029991a00a06082a8648ce3d030107a14403420004c02c61c9b16283bbcc14956d886d79b358aa614596975f78cece787146abf74c2d5dc578c0992b4f3c631373479ebf3892efe53d21c4f4f1cc9a11c3536b7f75"))
diff --git a/src/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
index 8e5410a..4b3fa23 100644
--- a/src/crypto/tls/handshake_test.go
+++ b/src/crypto/tls/handshake_test.go
@@ -32,10 +32,10 @@
 // implementation.
 //
 // Tests can be updated by running them with the -update flag. This will cause
-// the test files. Generally one should combine the -update flag with -test.run
-// to updated a specific test. Since the reference implementation will always
-// generate fresh random numbers, large parts of the reference connection will
-// always change.
+// the test files to be regenerated. Generally one should combine the -update
+// flag with -test.run to updated a specific test. Since the reference
+// implementation will always generate fresh random numbers, large parts of
+// the reference connection will always change.
 
 var (
 	update = flag.Bool("update", false, "update golden files on disk")
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
index 1b27c04..3f570b6 100644
--- a/src/crypto/tls/key_agreement.go
+++ b/src/crypto/tls/key_agreement.go
@@ -110,14 +110,14 @@
 }
 
 // hashForServerKeyExchange hashes the given slices and returns their digest
-// and the identifier of the hash function used. The sigAndHash argument is
-// only used for >= TLS 1.2 and precisely identifies the hash function to use.
-func hashForServerKeyExchange(sigAndHash signatureAndHash, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
+// and the identifier of the hash function used. The signatureAlgorithm argument
+// is only used for >= TLS 1.2 and identifies the hash function to use.
+func hashForServerKeyExchange(sigType uint8, signatureAlgorithm SignatureScheme, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
 	if version >= VersionTLS12 {
-		if !isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) {
+		if !isSupportedSignatureAlgorithm(signatureAlgorithm, supportedSignatureAlgorithms) {
 			return nil, crypto.Hash(0), errors.New("tls: unsupported hash function used by peer")
 		}
-		hashFunc, err := lookupTLSHash(sigAndHash.hash)
+		hashFunc, err := lookupTLSHash(signatureAlgorithm)
 		if err != nil {
 			return nil, crypto.Hash(0), err
 		}
@@ -128,7 +128,7 @@
 		digest := h.Sum(nil)
 		return digest, hashFunc, nil
 	}
-	if sigAndHash.signature == signatureECDSA {
+	if sigType == signatureECDSA {
 		return sha1Hash(slices), crypto.SHA1, nil
 	}
 	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
@@ -137,20 +137,27 @@
 // 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, clientList []signatureAndHash) (uint8, error) {
+func pickTLS12HashForSignature(sigType uint8, clientList []SignatureScheme) (SignatureScheme, error) {
 	if len(clientList) == 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
+		switch sigType {
+		case signatureRSA:
+			return PKCS1WithSHA1, nil
+		case signatureECDSA:
+			return ECDSAWithSHA1, nil
+		default:
+			return 0, errors.New("tls: unknown signature algorithm")
+		}
 	}
 
-	for _, sigAndHash := range clientList {
-		if sigAndHash.signature != sigType {
+	for _, sigAlg := range clientList {
+		if signatureFromSignatureScheme(sigAlg) != sigType {
 			continue
 		}
-		if isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) {
-			return sigAndHash.hash, nil
+		if isSupportedSignatureAlgorithm(sigAlg, supportedSignatureAlgorithms) {
+			return sigAlg, nil
 		}
 	}
 
@@ -172,7 +179,7 @@
 }
 
 // ecdheRSAKeyAgreement implements a TLS key agreement where the server
-// generates a ephemeral EC public/private key pair and signs it. The
+// generates an 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 {
@@ -240,16 +247,17 @@
 	serverECDHParams[3] = byte(len(ecdhePublic))
 	copy(serverECDHParams[4:], ecdhePublic)
 
-	sigAndHash := signatureAndHash{signature: ka.sigType}
+	var signatureAlgorithm SignatureScheme
 
 	if ka.version >= VersionTLS12 {
 		var err error
-		if sigAndHash.hash, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
+		signatureAlgorithm, err = pickTLS12HashForSignature(ka.sigType, clientHello.supportedSignatureAlgorithms)
+		if err != nil {
 			return nil, err
 		}
 	}
 
-	digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, hello.random, serverECDHParams)
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, signatureAlgorithm, ka.version, clientHello.random, hello.random, serverECDHParams)
 	if err != nil {
 		return nil, err
 	}
@@ -287,8 +295,8 @@
 	copy(skx.key, serverECDHParams)
 	k := skx.key[len(serverECDHParams):]
 	if ka.version >= VersionTLS12 {
-		k[0] = sigAndHash.hash
-		k[1] = sigAndHash.signature
+		k[0] = byte(signatureAlgorithm >> 8)
+		k[1] = byte(signatureAlgorithm)
 		k = k[2:]
 	}
 	k[0] = byte(len(sig) >> 8)
@@ -319,13 +327,10 @@
 	if !ok {
 		panic("internal error")
 	}
-	x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:])
+	x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:]) // Unmarshal also checks whether the given point is on the curve
 	if x == nil {
 		return nil, errClientKeyExchange
 	}
-	if !curve.IsOnCurve(x, y) {
-		return nil, errClientKeyExchange
-	}
 	x, _ = curve.ScalarMult(x, y, ka.privateKey)
 	preMasterSecret := make([]byte, (curve.Params().BitSize+7)>>3)
 	xBytes := x.Bytes()
@@ -365,21 +370,17 @@
 		if !ok {
 			return errors.New("tls: server selected unsupported curve")
 		}
-
-		ka.x, ka.y = elliptic.Unmarshal(curve, publicKey)
+		ka.x, ka.y = elliptic.Unmarshal(curve, publicKey) // Unmarshal also checks whether the given point is on the curve
 		if ka.x == nil {
 			return errServerKeyExchange
 		}
-		if !curve.IsOnCurve(ka.x, ka.y) {
-			return errServerKeyExchange
-		}
 	}
 
-	sigAndHash := signatureAndHash{signature: ka.sigType}
+	var signatureAlgorithm SignatureScheme
 	if ka.version >= VersionTLS12 {
 		// handle SignatureAndHashAlgorithm
-		sigAndHash = signatureAndHash{hash: sig[0], signature: sig[1]}
-		if sigAndHash.signature != ka.sigType {
+		signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
+		if signatureFromSignatureScheme(signatureAlgorithm) != ka.sigType {
 			return errServerKeyExchange
 		}
 		sig = sig[2:]
@@ -393,7 +394,7 @@
 	}
 	sig = sig[2:]
 
-	digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, serverHello.random, serverECDHParams)
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, signatureAlgorithm, ka.version, clientHello.random, serverHello.random, serverECDHParams)
 	if err != nil {
 		return err
 	}
diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go
index 5833fc1..74438f8 100644
--- a/src/crypto/tls/prf.go
+++ b/src/crypto/tls/prf.go
@@ -12,6 +12,7 @@
 	"crypto/sha256"
 	"crypto/sha512"
 	"errors"
+	"fmt"
 	"hash"
 )
 
@@ -34,12 +35,8 @@
 		h.Write(a)
 		h.Write(seed)
 		b := h.Sum(nil)
-		todo := len(b)
-		if j+todo > len(result) {
-			todo = len(result) - j
-		}
-		copy(result[j:j+todo], b)
-		j += todo
+		copy(result[j:], b)
+		j += len(b)
 
 		h.Reset()
 		h.Write(a)
@@ -180,17 +177,19 @@
 }
 
 // lookupTLSHash looks up the corresponding crypto.Hash for a given
-// TLS hash identifier.
-func lookupTLSHash(hash uint8) (crypto.Hash, error) {
-	switch hash {
-	case hashSHA1:
+// hash from a TLS SignatureScheme.
+func lookupTLSHash(signatureAlgorithm SignatureScheme) (crypto.Hash, error) {
+	switch signatureAlgorithm {
+	case PKCS1WithSHA1, ECDSAWithSHA1:
 		return crypto.SHA1, nil
-	case hashSHA256:
+	case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
 		return crypto.SHA256, nil
-	case hashSHA384:
+	case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
 		return crypto.SHA384, nil
+	case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
+		return crypto.SHA512, nil
 	default:
-		return 0, errors.New("tls: unsupported hash algorithm")
+		return 0, fmt.Errorf("tls: unsupported signature algorithm: %#04x", signatureAlgorithm)
 	}
 }
 
@@ -310,31 +309,26 @@
 	return out
 }
 
-// selectClientCertSignatureAlgorithm returns a signatureAndHash to sign a
+// selectClientCertSignatureAlgorithm returns a SignatureScheme to sign a
 // client's CertificateVerify with, or an error if none can be found.
-func (h finishedHash) selectClientCertSignatureAlgorithm(serverList []signatureAndHash, sigType uint8) (signatureAndHash, error) {
-	if h.version < VersionTLS12 {
-		// Nothing to negotiate before TLS 1.2.
-		return signatureAndHash{signature: sigType}, nil
-	}
-
+func (h finishedHash) selectClientCertSignatureAlgorithm(serverList []SignatureScheme, sigType uint8) (SignatureScheme, error) {
 	for _, v := range serverList {
-		if v.signature == sigType && isSupportedSignatureAndHash(v, supportedSignatureAlgorithms) {
+		if signatureFromSignatureScheme(v) == sigType && isSupportedSignatureAlgorithm(v, supportedSignatureAlgorithms) {
 			return v, nil
 		}
 	}
-	return signatureAndHash{}, errors.New("tls: no supported signature algorithm found for signing client certificate")
+	return 0, errors.New("tls: no supported signature algorithm found for signing client certificate")
 }
 
 // hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
 // id suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(signatureAndHash signatureAndHash, masterSecret []byte) ([]byte, crypto.Hash, error) {
+func (h finishedHash) hashForClientCertificate(sigType uint8, signatureAlgorithm SignatureScheme, masterSecret []byte) ([]byte, crypto.Hash, error) {
 	if (h.version == VersionSSL30 || h.version >= VersionTLS12) && h.buffer == nil {
 		panic("a handshake hash for a client-certificate was requested after discarding the handshake buffer")
 	}
 
 	if h.version == VersionSSL30 {
-		if signatureAndHash.signature != signatureRSA {
+		if sigType != signatureRSA {
 			return nil, 0, errors.New("tls: unsupported signature type for client certificate")
 		}
 
@@ -345,7 +339,7 @@
 		return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), crypto.MD5SHA1, nil
 	}
 	if h.version >= VersionTLS12 {
-		hashAlg, err := lookupTLSHash(signatureAndHash.hash)
+		hashAlg, err := lookupTLSHash(signatureAlgorithm)
 		if err != nil {
 			return nil, 0, err
 		}
@@ -354,7 +348,7 @@
 		return hash.Sum(nil), hashAlg, nil
 	}
 
-	if signatureAndHash.signature == signatureECDSA {
+	if sigType == signatureECDSA {
 		return h.server.Sum(nil), crypto.SHA1, nil
 	}
 
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
index 099cef4..f7b6612 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 4f 5d 09 43 37  |....Y...U..O].C7|
-00000010  70 c6 d9 8b 07 ca 1a f0  fb a7 05 51 53 67 7a 7e  |p..........QSgz~|
-00000020  c9 c6 68 10 10 2a 69 bd  47 db 8e 20 f2 13 5b 26  |..h..*i.G.. ..[&|
-00000030  e6 8e 19 b0 bc b5 ee 1f  ca 44 5d 32 11 37 b0 78  |.........D]2.7.x|
-00000040  49 16 6e c2 44 86 52 3f  9f 05 15 aa c0 09 00 00  |I.n.D.R?........|
+00000000  16 03 01 00 59 02 00 00  55 03 01 37 4c 3d 48 47  |....Y...U..7L=HG|
+00000010  2c b1 fb 63 1d 94 a6 b7  57 87 72 ec 4d 29 f9 4e  |,..c....W.r.M).N|
+00000020  81 d1 b6 27 8c 6a 27 c0  d3 c5 32 20 2d 80 95 68  |...'.j'...2 -..h|
+00000030  a9 f9 2a 79 af be 9f d3  ce 4f 6a 2c 6b b3 dd 9e  |..*y.....Oj,k...|
+00000040  62 e2 08 b9 24 a3 fe 23  11 f8 cd ab c0 09 00 00  |b...$..#........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,18 +49,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 56 b4  |*............ V.|
-00000280  39 d4 8f 18 79 87 89 d0  04 ee 12 54 20 2b be c1  |9...y......T +..|
-00000290  94 99 40 a2 73 df 1e 92  66 0b d1 f1 d6 38 00 8b  |..@.s...f....8..|
-000002a0  30 81 88 02 42 01 38 12  59 bd ea 44 59 f4 6f a9  |0...B.8.Y..DY.o.|
-000002b0  8e 9e a0 85 b5 b3 55 3e  76 49 b7 75 98 6e 81 30  |......U>vI.u.n.0|
-000002c0  c4 73 bd 54 78 39 f7 e2  22 49 4c 93 0d c1 26 89  |.s.Tx9.."IL...&.|
-000002d0  08 b9 9c 8b 86 3e 81 2c  a5 50 7c e9 88 ec c0 ad  |.....>.,.P|.....|
-000002e0  9e e0 40 ac 4e 0a fd 02  42 01 2e 0d 37 73 6a 0d  |..@.N...B...7sj.|
-000002f0  a4 60 08 a0 2b 32 0f 87  8d f8 9b c7 68 cf 50 79  |.`..+2......h.Py|
-00000300  73 f7 cf 93 aa 75 57 20  58 3d 13 c0 f3 66 7d 59  |s....uW X=...f}Y|
-00000310  15 73 d4 29 03 34 df 33  00 c0 b5 71 bc 2a 90 ef  |.s.).4.3...q.*..|
-00000320  3c 02 5e ea 9d 29 93 1c  18 db 04 16 03 01 00 0a  |<.^..)..........|
+00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 14 a7  |*............ ..|
+00000280  f5 4f 06 cf f6 92 3d 98  59 e2 36 72 2c 45 ce 98  |.O....=.Y.6r,E..|
+00000290  a2 97 c3 3c ba 67 b3 6a  fe 0a 2c f7 ae 03 00 8b  |...<.g.j..,.....|
+000002a0  30 81 88 02 42 00 cd a1  a2 cc 81 c9 7a c5 a9 54  |0...B.......z..T|
+000002b0  19 61 0a d3 23 7a cb f8  52 54 16 c3 38 b6 9e f2  |.a..#z..RT..8...|
+000002c0  a6 7f 5a 5c e7 3f ae c8  85 c1 01 6f 90 94 c4 e1  |..Z\.?.....o....|
+000002d0  c3 56 b3 da 4c 92 9c 11  0f 4d 06 31 3f d9 a4 77  |.V..L....M.1?..w|
+000002e0  1e 99 f6 3d ef 5e 06 02  42 01 4c f6 ac 3b 87 7b  |...=.^..B.L..;.{|
+000002f0  a1 3b 59 28 ab 00 dd 06  e7 9c 8a 8b 0e 50 48 49  |.;Y(.........PHI|
+00000300  4d b8 56 34 94 6a 7f 7a  6c 17 b0 2a 29 42 18 aa  |M.V4.j.zl..*)B..|
+00000310  a6 86 ce e0 d7 77 c1 e0  ea 40 96 50 79 ee e0 3c  |.....w...@.Py..<|
+00000320  6b 4e c1 07 b3 05 f5 9a  71 aa 9d 16 03 01 00 0a  |kN......q.......|
 00000330  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000340  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -99,30 +99,30 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 01 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 00 8b 30 81 88 02  42 01 53 2c a8 59 57 d2  |....0...B.S,.YW.|
-00000250  fc 0b 12 27 6f 9a f7 4e  a0 dd 2c af 1b 4c 81 0b  |...'o..N..,..L..|
-00000260  97 79 7e 6f dd a1 cf cb  e2 14 4d af 76 99 d8 06  |.y~o......M.v...|
-00000270  4f 8d 4f 86 d3 25 04 ea  80 02 ae 25 10 9d 2d 59  |O.O..%.....%..-Y|
-00000280  11 39 65 6b 83 d0 16 7d  bf a8 a4 02 42 01 f2 16  |.9ek...}....B...|
-00000290  6c f1 e6 3b b1 af fb 3f  99 f0 8a e3 c8 62 ba 71  |l..;...?.....b.q|
-000002a0  12 a1 2c 1e 15 74 d5 98  b5 ae 9f 50 a2 15 9b 73  |..,..t.....P...s|
-000002b0  9a 5f 2c 90 d4 9d 20 6f  35 b6 32 3e f4 b7 dd 50  |._,... o5.2>...P|
-000002c0  64 42 e3 4e 51 f3 11 4b  b4 9e a3 92 a2 10 59 14  |dB.NQ..K......Y.|
-000002d0  03 01 00 01 01 16 03 01  00 30 78 8c 7c 31 ce 16  |.........0x.|1..|
-000002e0  8f 1f 2a b9 ee cb 72 7f  1e 59 5b ad c2 58 32 77  |..*...r..Y[..X2w|
-000002f0  fa 46 83 b9 67 0c 5f 41  25 6a 38 ec 20 d2 80 e6  |.F..g._A%j8. ...|
-00000300  be 85 ce 94 b1 89 5f 8d  17 9b                    |......_...|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 90 0f 00  |...._X.;t.......|
+00000240  00 8c 00 8a 30 81 87 02  41 69 90 2d 22 89 47 af  |....0...Ai.-".G.|
+00000250  7e ab 99 d8 fc 71 00 e0  03 d8 03 36 2c 9f 5d 59  |~....q.....6,.]Y|
+00000260  27 2e c8 88 6f ba 7f 61  5a 86 8e 87 fd 3e 92 23  |'...o..aZ....>.#|
+00000270  e3 4e 49 af fe 2b 34 80  63 dd e3 e4 6b ca bd 08  |.NI..+4.c...k...|
+00000280  31 c8 54 27 d2 31 75 68  56 5d 02 42 01 1c 80 ed  |1.T'.1uhV].B....|
+00000290  fc 67 1a e1 cd c0 dc 9d  22 2b 7f 9b 0a 6d 3e 3b  |.g......"+...m>;|
+000002a0  ac 37 90 20 67 50 a1 e0  16 3c 3c 8c a1 46 2b 81  |.7. gP...<<..F+.|
+000002b0  48 b3 c3 c7 57 3b 26 17  51 4e d7 30 08 9c 2e d9  |H...W;&.QN.0....|
+000002c0  87 41 93 21 94 fe 47 34  16 a1 e3 dc 68 a7 14 03  |.A.!..G4....h...|
+000002d0  01 00 01 01 16 03 01 00  30 68 22 41 51 d1 f0 15  |........0h"AQ...|
+000002e0  e5 19 86 95 89 c2 a1 65  23 b2 61 44 fa 7e 07 9e  |.......e#.aD.~..|
+000002f0  f9 91 4b 17 a5 3b 7c 6e  e5 ee bf 06 4c 91 00 f5  |..K..;|n....L...|
+00000300  be b7 d5 b5 7c 88 21 0d  ae                       |....|.!..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 95 d6 f2 a2 75  |..........0....u|
-00000010  0e f8 c7 7c f9 1d 65 b4  82 08 c9 62 aa 93 24 8f  |...|..e....b..$.|
-00000020  4d 11 c7 b0 17 04 f1 0a  8b be 64 06 f9 07 20 0b  |M.........d... .|
-00000030  f0 3b 92 db 62 ba 63 91  a1 58 fe                 |.;..b.c..X.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 22 37 a1 e7 52  |..........0"7..R|
+00000010  94 4a e6 d8 e2 0a 96 37  9e 3e f2 a1 96 42 0f c9  |.J.....7.>...B..|
+00000020  ba 95 15 27 3e 9c 01 04  0e 41 01 e5 a6 c7 b4 c7  |...'>....A......|
+00000030  c6 54 b2 0e 96 52 6c cd  73 11 d3                 |.T...Rl.s..|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 3e a4 b5  b5 2f 4f c8 e0 08 cf 8a  |.... >.../O.....|
-00000010  9c f6 69 94 a9 91 0f 5d  c5 06 ee 71 e2 42 11 b4  |..i....]...q.B..|
-00000020  a8 17 54 19 3d 17 03 01  00 20 ce d2 8d 8a 78 e4  |..T.=.... ....x.|
-00000030  15 a4 ab 83 0d 9c fa 47  1c 8f 2d 87 a8 55 65 9d  |.......G..-..Ue.|
-00000040  7f 03 75 11 62 83 0b 44  0b f1 15 03 01 00 20 eb  |..u.b..D...... .|
-00000050  1a 46 95 1e 1b 10 b7 25  a8 c4 5b db 8b 3c 61 c9  |.F.....%..[..<a.|
-00000060  25 38 27 1e 69 11 18 16  0a 25 44 ad 9f 52 64     |%8'.i....%D..Rd|
+00000000  17 03 01 00 20 fa c5 7a  84 51 d8 01 1a bf c9 1c  |.... ..z.Q......|
+00000010  74 79 18 31 01 37 d3 65  64 34 1b 29 4e 94 d3 51  |ty.1.7.ed4.)N..Q|
+00000020  e2 97 dd 9a af 17 03 01  00 20 bc 47 62 6c 06 28  |......... .Gbl.(|
+00000030  4d 7d 61 26 0f 06 00 2a  a9 cb cf a2 a9 5a 20 2f  |M}a&...*.....Z /|
+00000040  f5 57 40 06 46 06 cd 31  bb 2c 15 03 01 00 20 53  |.W@.F..1.,.... S|
+00000050  b1 0e 13 ba 83 40 ff 9c  2b f2 70 05 29 0f 27 a1  |.....@..+.p.).'.|
+00000060  32 98 b6 96 ab d7 2b 0e  70 53 6e 09 d8 82 99     |2.....+.pSn....|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
index 7e9c272..082c05d 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 32 7c 5c ac bd  |....Y...U..2|\..|
-00000010  77 70 c2 f8 f0 20 37 e4  e8 45 db be 97 22 e4 f3  |wp... 7..E..."..|
-00000020  24 1c c1 29 8f 02 e1 bc  ba 4a 1e 20 81 6f b5 12  |$..).....J. .o..|
-00000030  c0 9d 9e de 2f b6 04 b2  74 34 da 2b 04 55 2c 4f  |..../...t4.+.U,O|
-00000040  dd 01 8a 30 d9 67 45 9f  f1 31 f1 78 c0 13 00 00  |...0.gE..1.x....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 af af 0f 49 f7  |....Y...U.....I.|
+00000010  fa 29 30 cb 90 30 b4 70  d2 94 96 db 99 f9 4d 10  |.)0..0.p......M.|
+00000020  4c 14 67 a0 2f ac cc e6  7f 89 c2 20 d8 e0 15 ba  |L.g./...... ....|
+00000030  55 99 b7 20 04 e2 84 e4  5d 97 4b ea 6e d5 6b db  |U.. ....].K.n.k.|
+00000040  dc 23 2a a1 76 4c fd c0  5f a6 4a e1 c0 13 00 00  |.#*.vL.._.J.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,17 +54,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 01 00  |.=.`.\!.;.......|
-000002c0  aa 0c 00 00 a6 03 00 1d  20 2f f7 3b 44 1a 47 85  |........ /.;D.G.|
-000002d0  d7 db 40 28 4e 6a f1 2f  1e b5 cc b0 58 0d 92 93  |..@(Nj./....X...|
-000002e0  30 41 65 08 05 f7 51 23  57 00 80 87 0d c3 22 ff  |0Ae...Q#W.....".|
-000002f0  aa d1 3f 55 09 cf 98 dc  91 f8 d0 63 58 da dc 52  |..?U.......cX..R|
-00000300  03 f0 06 a6 4e 7e 5b 96  a1 3b d7 8e 1e 68 50 ef  |....N~[..;...hP.|
-00000310  59 3f 78 06 eb 9a 33 c5  01 3c e0 fb c6 f1 b6 bc  |Y?x...3..<......|
-00000320  5a bc 95 e8 43 d9 ab 36  05 26 13 c5 a6 68 9b e2  |Z...C..6.&...h..|
-00000330  b1 42 6e 89 60 5c b3 91  02 c5 8b ab 53 d1 d9 79  |.Bn.`\......S..y|
-00000340  d0 37 b5 5e 2c 16 72 29  f8 9c d0 4a 46 87 46 f4  |.7.^,.r)...JF.F.|
-00000350  01 2b e8 6a 4f 59 d1 2d  3d de 4b 3b 0e c7 cd 42  |.+.jOY.-=.K;...B|
-00000360  ae d2 94 e9 a6 6b 65 ad  3f 77 57 16 03 01 00 0a  |.....ke.?wW.....|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 b7 12 77 ce bd 55 19  |........ ..w..U.|
+000002d0  d6 16 92 11 72 ad dc b4  9c fd 7a cd dc 31 53 0f  |....r.....z..1S.|
+000002e0  bc bf 12 0a 9f 32 c9 e3  09 00 80 6e 49 99 f1 c2  |.....2.....nI...|
+000002f0  6c 4e cd c1 bb cc b1 db  fd e5 3a 12 c9 94 dd 11  |lN........:.....|
+00000300  84 b3 5f 43 15 7c f5 05  a0 13 90 05 0e bb 13 60  |.._C.|.........`|
+00000310  c5 ef 30 e6 cb 5d b2 50  10 99 1f 01 13 43 37 e8  |..0..].P.....C7.|
+00000320  6c 95 aa ae 3e f6 53 25  92 48 d1 f6 e1 7d 88 0e  |l...>.S%.H...}..|
+00000330  23 fb ee 72 e8 84 83 6b  bc d6 96 3c 1d 62 98 3e  |#..r...k...<.b.>|
+00000340  89 c7 19 cc cd 08 d3 cb  b2 fe 39 51 f0 62 89 71  |..........9Q.b.q|
+00000350  d7 83 78 33 0d de f8 81  5a e4 f3 ea 55 e9 58 41  |..x3....Z...U.XA|
+00000360  94 b2 1b b9 1f 3b 52 f1  d3 d0 51 16 03 01 00 0a  |.....;R...Q.....|
 00000370  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -104,29 +104,29 @@
 00000210  03 01 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 00 8b 30 81 88 02  42 01 b3 df 59 06 71 e6  |....0...B...Y.q.|
-00000250  74 c9 9d d5 2c b0 a7 f8  1e ac bc f3 5a e2 ed 0b  |t...,.......Z...|
-00000260  f2 e9 37 82 c6 fe 7c 23  b9 63 6e 88 1d 63 31 ad  |..7...|#.cn..c1.|
-00000270  d3 29 48 eb f3 5d 52 f5  76 ab fc 16 9e 09 4f 49  |.)H..]R.v.....OI|
-00000280  cf b4 03 6a ed db e5 13  ea 67 74 02 42 01 8e 2f  |...j.....gt.B../|
-00000290  b8 12 38 c9 a6 8c 77 40  85 89 ef d8 ac 08 00 c0  |..8...w@........|
-000002a0  ee 70 68 a6 88 1f d1 67  0d 1b 7b 1f be e0 a7 b9  |.ph....g..{.....|
-000002b0  c3 7d ff 6a 39 3c b9 aa  f6 78 ac 9a ca 67 55 0c  |.}.j9<...x...gU.|
-000002c0  38 23 cc ab 18 c0 b9 ea  9c 84 61 32 0a 0d f3 14  |8#........a2....|
-000002d0  03 01 00 01 01 16 03 01  00 30 73 12 76 94 30 37  |.........0s.v.07|
-000002e0  e5 e3 30 59 88 2f 5f e9  f2 7b 3d 02 88 65 09 14  |..0Y./_..{=..e..|
-000002f0  68 23 02 d0 ae e5 7f 7f  8d 95 3b 1c 75 f5 1f 24  |h#........;.u..$|
-00000300  43 60 29 bb 0e 69 88 36  a9 68                    |C`)..i.6.h|
+00000240  00 8d 00 8b 30 81 88 02  42 01 8b 84 b3 ac 64 4e  |....0...B.....dN|
+00000250  77 d2 47 77 13 2f 45 ec  0b 3f 92 ef 55 cc 78 8e  |w.Gw./E..?..U.x.|
+00000260  d9 c1 ae 4b c5 6f 01 d0  55 ca 0b 12 cf 3c ac c8  |...K.o..U....<..|
+00000270  46 7b 6a c4 22 f3 16 85  1a 2a ea 4f f6 65 1c c9  |F{j."....*.O.e..|
+00000280  90 7b d1 c5 9f c8 59 73  43 47 bd 02 42 00 93 a3  |.{....YsCG..B...|
+00000290  35 0a 1f 14 de 23 fa 92  a4 d6 5e dc fd c0 85 87  |5....#....^.....|
+000002a0  fb 23 12 bd 8e d7 f3 98  33 49 fc 88 92 13 8a 7d  |.#......3I.....}|
+000002b0  ee 12 e5 d6 b3 ff bf 04  7e 48 ff 83 6b 76 70 b8  |........~H..kvp.|
+000002c0  8c 1f f5 44 4b a7 fb 48  81 87 a0 6b 66 45 15 14  |...DK..H...kfE..|
+000002d0  03 01 00 01 01 16 03 01  00 30 83 d6 1c 9f e9 ef  |.........0......|
+000002e0  49 45 e4 97 17 2c af 6f  4e 59 0e 4d 43 69 88 fd  |IE...,.oNY.MCi..|
+000002f0  3d 99 00 9e 02 3c 33 78  d6 37 6e f9 55 43 ac 16  |=....<3x.7n.UC..|
+00000300  2e 14 0e 0e 44 a1 f7 1e  fc 09                    |....D.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 a0 5f 7f 59 e0  |..........0._.Y.|
-00000010  b1 7e ed ad de 6a 47 94  21 e5 1b 77 a7 d0 88 fd  |.~...jG.!..w....|
-00000020  9e 4e 48 87 1d cf 40 e4  b9 38 a3 2e e4 00 c3 94  |.NH...@..8......|
-00000030  95 20 1c 97 d2 a9 3a 11  86 30 5f                 |. ....:..0_|
+00000000  14 03 01 00 01 01 16 03  01 00 30 75 1b 70 70 73  |..........0u.pps|
+00000010  c3 2d d5 7a a5 ca 63 b3  b7 b1 57 a8 bc fd 5c 95  |.-.z..c...W...\.|
+00000020  ed e7 88 26 b3 9b a6 8d  c7 3f 02 70 a7 98 1c 33  |...&.....?.p...3|
+00000030  86 67 f7 ca 76 42 53 99  3b 17 ef                 |.g..vBS.;..|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 ca 4c f5  cb 81 66 2f 97 e3 5d 8b  |.... .L...f/..].|
-00000010  dd 7d dd fa fe 8c 98 45  3f 3d 16 17 98 4d b5 15  |.}.....E?=...M..|
-00000020  6c 91 8a 79 7a 17 03 01  00 20 96 ec 30 cb d3 78  |l..yz.... ..0..x|
-00000030  b9 0a a1 ab fd 12 25 d5  82 7b 7a 3c 17 56 7b b7  |......%..{z<.V{.|
-00000040  c4 6e ea a2 5b d7 6b b6  22 a9 15 03 01 00 20 ba  |.n..[.k."..... .|
-00000050  ff fe 2b 60 83 34 ad 45  75 15 d5 95 b3 27 92 46  |..+`.4.Eu....'.F|
-00000060  47 ae f1 d4 a4 9d 63 ef  db d9 b5 37 0f f1 74     |G.....c....7..t|
+00000000  17 03 01 00 20 61 40 b2  4d fe 8d 3c a1 d2 4b 36  |.... a@.M..<..K6|
+00000010  bb 5d 6c 77 65 6e 66 55  57 12 a5 62 9d 56 f6 53  |.]lwenfUW..b.V.S|
+00000020  dd a6 38 7c 32 17 03 01  00 20 e5 98 82 47 a0 cc  |..8|2.... ...G..|
+00000030  a7 02 98 71 01 00 d7 ee  1c 35 16 d6 7a 03 80 95  |...q.....5..z...|
+00000040  d0 69 9a e9 bb 4c 9c 0a  92 59 15 03 01 00 20 a2  |.i...L...Y.... .|
+00000050  96 8a 21 a9 a4 28 83 f8  fb 3c aa 6e 53 fb 23 7e  |..!..(...<.nS.#~|
+00000060  a1 08 4f 16 8f 34 02 27  34 e2 c2 71 1e a2 c7     |..O..4.'4..q...|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
index 67772e1..65bc278 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 ed 13 de 15 cc  |....Y...U.......|
-00000010  90 4f f3 72 5a d4 7a 01  26 fa 7a ae 38 92 a0 d6  |.O.rZ.z.&.z.8...|
-00000020  70 4a 20 f6 7e 11 f7 ac  e6 94 87 20 9f 37 0f 8f  |pJ .~...... .7..|
-00000030  55 a6 6a 97 b8 0f 56 aa  2d 69 c5 79 01 d5 c0 01  |U.j...V.-i.y....|
-00000040  2c 2b 0e 16 d8 79 a3 f3  44 99 7c 01 c0 09 00 00  |,+...y..D.|.....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 3b ff d1 3d 27  |....Y...U..;..='|
+00000010  af 29 b4 e8 d8 71 40 08  5c 7b 8b a9 23 8a 70 1a  |.)...q@.\{..#.p.|
+00000020  c8 a4 19 11 71 7b 92 58  03 af 99 20 c8 18 fc 7d  |....q{.X... ...}|
+00000030  e6 ed 7b d7 1c 2a 5e d5  5b 22 d9 dc 9e b1 aa 88  |..{..*^.["......|
+00000040  0a 9f fb 4a 8a d7 27 d9  65 df 76 3a c0 09 00 00  |...J..'.e.v:....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,18 +49,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 b4 0c 00  00 b0 03 00 1d 20 ca e8  |*............ ..|
-00000280  ef 79 56 cd aa eb 12 8f  e1 89 d1 3c 63 1f c8 54  |.yV........<c..T|
-00000290  5f 4e cf 6b 72 7d 1c bb  f6 80 ae 17 33 69 00 8a  |_N.kr}......3i..|
-000002a0  30 81 87 02 42 01 d1 45  df fc 46 21 5b 9b 49 f0  |0...B..E..F![.I.|
-000002b0  3c f2 16 65 1e 33 90 d8  be 1d 65 12 2f 46 93 5b  |<..e.3....e./F.[|
-000002c0  e2 14 67 b8 67 9b c1 10  31 a1 96 b8 86 c3 8b 26  |..g.g...1......&|
-000002d0  3f da 5e 86 e7 b1 f9 3f  f1 04 57 ed e6 6f a5 86  |?.^....?..W..o..|
-000002e0  f7 58 38 6e 0d ae 42 02  41 05 1b 07 9b 4c 4d 39  |.X8n..B.A....LM9|
-000002f0  2d 0c 4e d7 94 d6 86 c9  6c b9 4d 54 a2 56 87 12  |-.N.....l.MT.V..|
-00000300  08 ec 4e f1 a4 19 5e 52  69 ed 9f 6c 59 5f 31 0f  |..N...^Ri..lY_1.|
-00000310  8d 33 1f a7 42 e5 56 9d  54 f4 18 9b 33 31 97 b9  |.3..B.V.T...31..|
-00000320  57 55 c9 9f ea 7d f2 9e  24 e0 16 03 01 00 0a 0d  |WU...}..$.......|
+00000270  2a 16 03 01 00 b4 0c 00  00 b0 03 00 1d 20 80 a2  |*............ ..|
+00000280  7b 8d 6e 35 2d f1 f5 f3  1b 97 df 4b 1e df a7 bc  |{.n5-......K....|
+00000290  2d 16 b7 3b bb 2a 97 8e  1f b6 e3 9f 05 76 00 8a  |-..;.*.......v..|
+000002a0  30 81 87 02 42 01 ca 48  71 d3 b9 18 46 c7 9b e3  |0...B..Hq...F...|
+000002b0  e8 af 4c 6c 7d 9a 9b 00  1f b1 cf 90 a6 63 38 b0  |..Ll}........c8.|
+000002c0  a3 cb e3 9a a1 ae 79 25  bb 6b 08 d6 b2 4f 32 a8  |......y%.k...O2.|
+000002d0  91 bc c8 5a 59 25 ff 00  eb 33 4f b4 e8 d7 97 80  |...ZY%...3O.....|
+000002e0  ad 9c 66 a2 73 78 d7 02  41 5e 26 e2 cf d4 cf 8e  |..f.sx..A^&.....|
+000002f0  40 7f 18 f0 e6 d7 1e 3b  3f f4 ed c6 d5 05 2c 67  |@......;?.....,g|
+00000300  0d 73 0f a0 db 03 cb 5c  bf c3 a5 c3 02 1f b8 64  |.s.....\.......d|
+00000310  6f e7 35 74 ba f1 b8 1b  d1 a8 c2 43 c9 b9 83 ba  |o.5t.......C....|
+00000320  30 2b 0b c0 00 a0 be b1  f1 33 16 03 01 00 0a 0d  |0+.......3......|
 00000330  00 00 06 03 01 02 40 00  00 16 03 01 00 04 0e 00  |......@.........|
 00000340  00 00                                             |..|
 >>> Flow 3 (client to server)
@@ -99,29 +99,29 @@
 00000200  e5 35 16 03 01 00 25 10  00 00 21 20 2f e5 7d a3  |.5....%...! /.}.|
 00000210  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
 00000220  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 16 03 01 00  |......._X.;t....|
-00000230  86 0f 00 00 82 00 80 8f  6f 77 5d d5 99 28 0c 7a  |........ow]..(.z|
-00000240  36 f2 50 ec 9a e6 eb 88  ac 45 f7 9b 6f 98 84 ba  |6.P......E..o...|
-00000250  fb 3c b8 d6 54 61 b8 87  25 50 3c 31 5a d2 c1 54  |.<..Ta..%P<1Z..T|
-00000260  e8 ed c3 93 cc 98 b1 c3  d4 84 11 d8 a0 c7 ae 67  |...............g|
-00000270  67 35 6a 0f 93 18 bb 18  52 f8 25 88 1f d2 19 4d  |g5j.....R.%....M|
-00000280  3b 4c f2 0f f7 06 68 57  cf 45 20 e0 57 75 37 e9  |;L....hW.E .Wu7.|
-00000290  cd 86 1f e5 d2 90 1e cf  3a 18 fd 45 bc a1 84 63  |........:..E...c|
-000002a0  36 d8 ac 6b 09 41 da 0a  87 7f ab ce 8e 49 e6 c8  |6..k.A.......I..|
-000002b0  bf fb 2c 3b 7b e9 ae 14  03 01 00 01 01 16 03 01  |..,;{...........|
-000002c0  00 30 7d 65 9c c1 25 e4  85 d7 39 d4 67 cf eb f1  |.0}e..%...9.g...|
-000002d0  b7 c2 4d e6 5d bd 13 74  55 22 f0 8a 7e a6 a2 eb  |..M.]..tU"..~...|
-000002e0  93 cc b7 fa 86 b1 b5 e0  a3 ef ee 56 f0 cd f7 a5  |...........V....|
-000002f0  d8 9e                                             |..|
+00000230  86 0f 00 00 82 00 80 35  95 c1 44 9d 66 18 82 91  |.......5..D.f...|
+00000240  5b 25 68 80 9c 07 78 c6  ed da 98 25 07 9a c4 08  |[%h...x....%....|
+00000250  b3 10 a2 67 b0 5b 0e c2  3d 25 af ea bc e1 5f a7  |...g.[..=%...._.|
+00000260  d2 58 e9 a7 0c c8 c4 10  d0 44 a4 a1 a6 07 12 b1  |.X.......D......|
+00000270  7f 22 6c 54 4e 97 ad b5  55 a0 58 ed c7 52 7a d6  |."lTN...U.X..Rz.|
+00000280  5a 23 4f 6b b2 41 0f 01  2b 97 93 02 6f ce bd 32  |Z#Ok.A..+...o..2|
+00000290  12 d3 af 32 09 0c a8 1a  16 58 f3 d8 d6 fe ba 84  |...2.....X......|
+000002a0  57 b0 18 5c 86 35 83 54  6e f7 04 21 29 62 1c 76  |W..\.5.Tn..!)b.v|
+000002b0  dc 44 03 5c 3a 1a 41 14  03 01 00 01 01 16 03 01  |.D.\:.A.........|
+000002c0  00 30 2e 3f d7 4c 32 5f  13 48 47 46 b0 30 c1 00  |.0.?.L2_.HGF.0..|
+000002d0  49 5d 6d 58 b6 1c ea f4  f9 1c 48 b9 01 9c 9c 94  |I]mX......H.....|
+000002e0  7f 83 5a e7 c3 10 92 ad  9f fa a8 c6 57 49 ae 3a  |..Z.........WI.:|
+000002f0  3a 2a                                             |:*|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 ff 13 14 c5 ad  |..........0.....|
-00000010  88 ec a1 cf cc 0d 3f 7b  ec 50 4a 25 69 1f 18 dc  |......?{.PJ%i...|
-00000020  b1 99 1f 3b 78 60 e0 83  c0 cd 9a b3 0d 59 0b f8  |...;x`.......Y..|
-00000030  8a b7 7c 2c b4 2c e4 d0  49 82 82                 |..|,.,..I..|
+00000000  14 03 01 00 01 01 16 03  01 00 30 29 fc da 17 09  |..........0)....|
+00000010  5a 69 1b 4f 2e 4f 40 1d  9e 69 6c 62 ee 8b f9 53  |Zi.O.O@..ilb...S|
+00000020  48 6a ae b6 85 df ab f3  89 8d f3 6e df f0 8f 14  |Hj.........n....|
+00000030  79 a3 d8 d5 e4 3c 6b dd  fb 77 24                 |y....<k..w$|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 51 91 74  f6 31 07 15 6b 9e 0b 28  |.... Q.t.1..k..(|
-00000010  02 b8 ec 9d c6 e3 15 24  d3 ea 4b 27 d0 fa 9f c2  |.......$..K'....|
-00000020  c4 8d 37 b3 d9 17 03 01  00 20 7d 97 75 fe de 3f  |..7...... }.u..?|
-00000030  ae ab e6 a8 1d 76 1c 06  9c 02 61 cc f5 1d fe c8  |.....v....a.....|
-00000040  a2 dc ae 97 7f 1c 05 19  e5 14 15 03 01 00 20 4a  |.............. J|
-00000050  bc 45 97 6b 09 8e 47 5f  d5 a0 97 78 79 67 09 8d  |.E.k..G_...xyg..|
-00000060  d3 80 38 58 5c cc ae 8e  d4 67 1d 93 2b 20 79     |..8X\....g..+ y|
+00000000  17 03 01 00 20 89 6b 03  b2 9d cc f2 6f 8f 27 6c  |.... .k.....o.'l|
+00000010  d4 49 61 4f 88 c1 6c b6  ef 2e 75 b9 0d d4 06 b0  |.IaO..l...u.....|
+00000020  cb 6f 80 70 f6 17 03 01  00 20 ab 92 7f df 5f 38  |.o.p..... ...._8|
+00000030  87 d7 7e ff 9c 17 14 cc  41 8d 28 98 7d 6a 59 78  |..~.....A.(.}jYx|
+00000040  f0 9f d1 f1 f1 5a 75 27  fa 57 15 03 01 00 20 a3  |.....Zu'.W.... .|
+00000050  3b 0c 84 bc d7 5d f6 87  b1 14 bd c4 6e a8 14 ae  |;....]......n...|
+00000060  e8 fd f2 50 67 b9 fa 6c  86 d8 6d 84 87 5e fe     |...Pg..l..m..^.|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
index e585894..fef2ac0 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 61 6b 2e 41 7f  |....Y...U..ak.A.|
-00000010  af 26 6f a2 8b 63 ee e4  b1 76 19 3a 6d a3 c2 30  |.&o..c...v.:m..0|
-00000020  37 e8 47 c2 90 10 7e e8  c5 b2 eb 20 00 1c 8f 70  |7.G...~.... ...p|
-00000030  0d 15 4a c7 7d ab ca 79  a7 d8 c2 01 62 6e 6f aa  |..J.}..y....bno.|
-00000040  df a2 1c 8f 7c 27 d9 e6  fe e9 c8 ab c0 13 00 00  |....|'..........|
+00000000  16 03 01 00 59 02 00 00  55 03 01 58 89 71 77 b1  |....Y...U..X.qw.|
+00000010  c2 2a 4e e4 5a 4f bb 76  8a b5 9b f3 b1 c6 fc 30  |.*N.ZO.v.......0|
+00000020  a8 ca 7e 5c d6 29 41 7d  17 04 5d 20 86 f6 c6 6f  |..~\.)A}..] ...o|
+00000030  5f 48 2c 43 07 ea d1 b3  81 da 6d 2f 70 aa 4c 2e  |_H,C......m/p.L.|
+00000040  d4 87 bb 4c 38 c9 67 bc  80 38 d0 c3 c0 13 00 00  |...L8.g..8......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,17 +54,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 01 00  |.=.`.\!.;.......|
-000002c0  aa 0c 00 00 a6 03 00 1d  20 29 0b ca 37 f3 a1 52  |........ )..7..R|
-000002d0  49 1c 84 9a e4 74 6b 4b  2d 1f e6 e9 83 1d 5d 59  |I....tkK-.....]Y|
-000002e0  5a 2f 09 9f bc a4 30 af  71 00 80 d9 bb 6d 09 a7  |Z/....0.q....m..|
-000002f0  ab 47 6f e8 a6 1a da fb  66 7d a5 f0 c9 c3 24 4c  |.Go.....f}....$L|
-00000300  99 56 c6 29 71 27 08 0b  c1 60 44 cc 6d 42 1b 5e  |.V.)q'...`D.mB.^|
-00000310  cd 9f 82 24 38 23 ec d9  fa 32 49 2f 16 5d d2 9d  |...$8#...2I/.]..|
-00000320  e9 13 4e 66 3d f8 bf 30  2e 8c eb 35 4c e8 81 86  |..Nf=..0...5L...|
-00000330  c0 de c7 0d a9 60 7e 7c  4a c4 1d a0 89 70 de 82  |.....`~|J....p..|
-00000340  1b 37 a0 ea 7f 20 a5 fe  d4 20 1d 6f 1a 84 dd a4  |.7... ... .o....|
-00000350  13 46 18 c6 31 14 81 4b  a4 bb 43 5c c4 49 1c 5a  |.F..1..K..C\.I.Z|
-00000360  8d 12 57 e0 1d 9a b6 cd  f1 39 ff 16 03 01 00 0a  |..W......9......|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 0c 12 68 b0 30 bb 4b  |........ ..h.0.K|
+000002d0  b0 c2 38 4d fa 65 f1 43  4a f1 47 dc 6e 6d ae 6b  |..8M.e.CJ.G.nm.k|
+000002e0  35 f5 4a 3c fa bc a6 6e  27 00 80 38 ef 5d 08 06  |5.J<...n'..8.]..|
+000002f0  e5 f9 86 86 2e f3 6d b6  d4 12 94 5d 18 6b 11 67  |......m....].k.g|
+00000300  17 65 d3 5c 0b fe 09 2d  bb ca a6 2d c4 d7 fc b9  |.e.\...-...-....|
+00000310  71 c1 4a 38 bb 14 bf dc  1b 4d 61 38 c6 76 3e 24  |q.J8.....Ma8.v>$|
+00000320  ff e6 c5 7e f8 5d 5f 80  3d 8a 4e 5f bb 91 b7 c5  |...~.]_.=.N_....|
+00000330  59 f8 b7 a1 7b d5 c3 72  57 83 de 52 40 75 1c ec  |Y...{..rW..R@u..|
+00000340  77 e9 0e a6 3a ad e4 57  ae d4 92 44 40 00 74 fa  |w...:..W...D@.t.|
+00000350  ae 16 b9 82 0d 9e 2a 43  12 1b a6 bb a1 89 6a 99  |......*C......j.|
+00000360  09 80 d1 ad b6 9c 92 01  60 14 bb 16 03 01 00 0a  |........`.......|
 00000370  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -103,29 +103,29 @@
 00000200  e5 35 16 03 01 00 25 10  00 00 21 20 2f e5 7d a3  |.5....%...! /.}.|
 00000210  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
 00000220  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 16 03 01 00  |......._X.;t....|
-00000230  86 0f 00 00 82 00 80 12  76 af 25 e4 e7 ff d6 e4  |........v.%.....|
-00000240  27 58 31 0f 6b 1e 84 13  2f d0 60 80 18 c3 f8 c1  |'X1.k.../.`.....|
-00000250  f8 04 39 d4 07 05 d3 96  e2 b2 10 de 1f 68 88 67  |..9..........h.g|
-00000260  1d dd 0a 11 52 9d 16 0e  af 07 de cb f1 7c f4 b4  |....R........|..|
-00000270  5d 0f 4f 43 5b 3c 25 07  32 13 f2 ab 9b 2d d0 a8  |].OC[<%.2....-..|
-00000280  28 90 cb 04 48 c3 43 bd  2b b4 ef b9 7b cd bd d5  |(...H.C.+...{...|
-00000290  bc d1 cc 00 17 46 fa 9b  1f 44 58 b7 6c de 1b 7a  |.....F...DX.l..z|
-000002a0  e0 d7 12 38 a3 09 f8 7a  9b 26 0b ee 37 bc 79 1b  |...8...z.&..7.y.|
-000002b0  51 9f 9a 1f f9 a9 51 14  03 01 00 01 01 16 03 01  |Q.....Q.........|
-000002c0  00 30 97 df fb 79 78 a8  27 fd 2b 68 6b ec 4d 29  |.0...yx.'.+hk.M)|
-000002d0  a1 02 59 ae 18 0b 46 62  af 61 53 2f 95 50 f2 ac  |..Y...Fb.aS/.P..|
-000002e0  c8 c3 5e 78 ca b0 e2 5d  ff d7 1b 9b 00 30 f6 da  |..^x...].....0..|
-000002f0  d7 91                                             |..|
+00000230  86 0f 00 00 82 00 80 1d  64 73 05 fa f9 5e ef eb  |........ds...^..|
+00000240  c7 1b 07 99 0e d1 52 83  9e 19 ba 62 11 14 0a c2  |......R....b....|
+00000250  11 e0 ff 6e 43 03 85 1d  ef 73 f8 c2 4d b0 c6 5a  |...nC....s..M..Z|
+00000260  ba 14 14 1e 95 d1 f8 1a  3f 7f c3 08 f4 86 e6 2c  |........?......,|
+00000270  43 2f 00 fd d7 e1 4e 07  45 09 19 98 33 ad 6e e2  |C/....N.E...3.n.|
+00000280  17 21 3b 8c a4 5e 50 6c  5a a3 75 68 93 a5 ee 42  |.!;..^PlZ.uh...B|
+00000290  a9 88 6d c4 4e 9c 3f ce  ee e1 a1 9b c4 c6 8e f7  |..m.N.?.........|
+000002a0  65 b8 7f 10 a9 5f b8 07  70 8a 4f 89 2c 59 a1 46  |e...._..p.O.,Y.F|
+000002b0  f9 a2 05 bc 01 45 7e 14  03 01 00 01 01 16 03 01  |.....E~.........|
+000002c0  00 30 43 ec 90 51 04 0a  70 f7 8b a4 15 63 df 1b  |.0C..Q..p....c..|
+000002d0  70 eb 59 63 d1 54 41 4e  7e 82 e4 fb fe ca 87 6e  |p.Yc.TAN~......n|
+000002e0  86 2d c6 d2 ee 1c 7b 9e  72 2d d6 d6 12 15 a8 8b  |.-....{.r-......|
+000002f0  b2 9d                                             |..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 f9 e9 d7 8c 4a  |..........0....J|
-00000010  6b f4 c9 88 d6 98 70 53  13 fc 51 9c 81 14 cf 71  |k.....pS..Q....q|
-00000020  d9 30 7a d9 2c 34 96 00  a4 a0 2b 1e 7d ff d0 f2  |.0z.,4....+.}...|
-00000030  b7 81 ed 86 c5 e1 09 16  82 47 20                 |.........G |
+00000000  14 03 01 00 01 01 16 03  01 00 30 d2 8f 01 3c 0e  |..........0...<.|
+00000010  0d 9e 0d bb 92 0b e8 90  b8 39 53 b8 50 7a b0 c1  |.........9S.Pz..|
+00000020  f3 89 3d 5c 1c a0 e8 97  21 c5 30 0f f1 14 11 6b  |..=\....!.0....k|
+00000030  ec 6e 8f 75 c8 7f 89 dd  3e 19 44                 |.n.u....>.D|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 db b5 66  4e fb b1 47 8a 8e 6b a8  |.... ..fN..G..k.|
-00000010  03 53 1a 51 22 8e 47 a3  3a 74 ed a4 6a aa 79 fd  |.S.Q".G.:t..j.y.|
-00000020  55 0f ac 35 a9 17 03 01  00 20 3e 0b 39 f5 5a 03  |U..5..... >.9.Z.|
-00000030  43 d9 e2 7d 1c dc 3b 42  82 2a 2d d4 04 0a 76 97  |C..}..;B.*-...v.|
-00000040  70 ed ee 99 58 15 40 c1  3a d5 15 03 01 00 20 bf  |p...X.@.:..... .|
-00000050  ea e8 93 67 a4 91 1a b5  f5 03 a5 94 50 95 41 16  |...g........P.A.|
-00000060  b0 2a 74 d9 32 65 94 35  45 b9 0f 2e 80 87 fd     |.*t.2e.5E......|
+00000000  17 03 01 00 20 19 f5 38  97 ac a5 5a 25 d4 1e 3a  |.... ..8...Z%..:|
+00000010  8c e6 89 36 88 80 f9 95  09 b2 f5 1d a8 09 02 b6  |...6............|
+00000020  ec aa 8e aa c6 17 03 01  00 20 3e ee df 1b 09 ff  |......... >.....|
+00000030  88 77 4a da 5c 74 cf 64  3d 92 a0 08 1c 7b 12 db  |.wJ.\t.d=....{..|
+00000040  72 99 0f d4 4e 20 55 17  1d d3 15 03 01 00 20 19  |r...N U....... .|
+00000050  ee bc fc da 0b 15 72 da  43 bc 0b 0a 49 4d 67 63  |......r.C...IMgc|
+00000060  3d 04 78 00 c3 9d 66 a5  16 96 68 80 88 27 47     |=.x...f...h..'G|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
index 529b7ce..ca39d9b 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 b0 ec 4b 2e 9e  |....Y...U....K..|
-00000010  19 7d 7b 7e 7c 52 8a d2  2e 8a 97 05 8a c6 ae aa  |.}{~|R..........|
-00000020  c5 62 bd 6f bd 7e fe 6b  c6 9f d4 20 74 db 02 b1  |.b.o.~.k... t...|
-00000030  65 88 41 bb 9a 55 22 f3  01 c4 5c ca 39 86 b1 77  |e.A..U"...\.9..w|
-00000040  c4 b3 45 16 eb 55 d8 15  b8 4d ac 12 c0 09 00 00  |..E..U...M......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 b2 70 62 50 ad  |....Y...U...pbP.|
+00000010  93 c5 c2 a6 66 60 f0 ed  9a 44 56 1a 9a 9c c0 00  |....f`...DV.....|
+00000020  a4 5b 59 ee d5 b5 91 c2  04 c8 7d 20 d3 a3 00 df  |.[Y.......} ....|
+00000030  93 72 69 c9 d6 dd 3b ba  45 5c d2 7a cc 0e 10 3b  |.ri...;.E\.z...;|
+00000040  6b 6f eb 6a 7a d3 55 d6  eb e9 0a 8a c0 09 00 00  |ko.jz.U.........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,37 +49,37 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 7d 74  |*............ }t|
-00000280  bf aa a8 b6 c0 1f 78 0c  1a ee c5 b7 56 ff 5c aa  |......x.....V.\.|
-00000290  f4 e3 a5 0c f7 64 31 eb  85 8a c9 bd 05 1b 00 8b  |.....d1.........|
-000002a0  30 81 88 02 42 00 f8 5d  e5 bf 2e 70 79 f4 36 90  |0...B..]...py.6.|
-000002b0  fc 6e 9a cc f1 c4 01 50  8c b9 92 4e bd e0 82 2d  |.n.....P...N...-|
-000002c0  1b ab 30 71 d1 db 76 af  50 75 08 fb cb 50 5b 00  |..0q..v.Pu...P[.|
-000002d0  49 72 f5 d7 d9 44 48 94  ac 1d 8d 2e 50 90 ad a3  |Ir...DH.....P...|
-000002e0  42 2b 5f 57 48 5e 9e 02  42 00 bb 0b 9a d7 25 53  |B+_WH^..B.....%S|
-000002f0  04 5c 58 01 07 8e 3d ee  f5 4f 0b 80 bd 02 07 3e  |.\X...=..O.....>|
-00000300  ff b9 01 ac 7a 49 be 94  fa cf 58 5c 59 91 b5 5d  |....zI....X\Y..]|
-00000310  cc 61 b9 e3 2f 53 7d 3c  3f 41 c5 31 1a 90 fc fa  |.a../S}<?A.1....|
-00000320  f7 0b eb e9 01 17 ab 23  ab 28 63 16 03 01 00 04  |.......#.(c.....|
-00000330  0e 00 00 00                                       |....|
+00000270  2a 16 03 01 00 b3 0c 00  00 af 03 00 1d 20 a3 a5  |*............ ..|
+00000280  47 e6 96 56 75 cb d6 1e  b7 1b 3d 23 95 be 97 ac  |G..Vu.....=#....|
+00000290  03 a5 15 60 c2 ab 91 aa  52 ac e6 e7 f3 16 00 89  |...`....R.......|
+000002a0  30 81 86 02 41 73 1b 9c  5b 66 9d b2 a7 74 83 ad  |0...As..[f...t..|
+000002b0  18 8e 29 ce 37 2f 44 a1  0e dd 80 df 60 3e 0c e1  |..).7/D.....`>..|
+000002c0  06 ad e6 1e 2f 31 75 90  f1 22 28 39 d3 af 96 73  |..../1u.."(9...s|
+000002d0  52 76 34 9b cd 7c 5d 46  6b 48 30 9a d9 b7 63 23  |Rv4..|]FkH0...c#|
+000002e0  f8 7f c2 80 22 55 02 41  6c bb 0c 49 c3 a3 57 a7  |...."U.Al..I..W.|
+000002f0  cf 2b 3e 96 a1 53 01 72  d0 5a e4 af 54 8f 23 6c  |.+>..S.r.Z..T.#l|
+00000300  2d 60 91 f2 4a 93 1f 75  0f cc a4 0a 5c 2d 40 7b  |-`..J..u....\-@{|
+00000310  11 8c a1 96 fb 2b ad 6f  eb 07 78 e5 70 26 37 7b  |.....+.o..x.p&7{|
+00000320  f4 19 1c d7 98 43 11 be  88 16 03 01 00 04 0e 00  |.....C..........|
+00000330  00 00                                             |..|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 01 00 01 01  |....._X.;t......|
-00000030  16 03 01 00 30 f5 d0 86  ef 96 7e b9 94 cc 19 62  |....0.....~....b|
-00000040  cc 3a 14 f1 74 a2 0d c8  b9 4c 5d 8a c5 80 60 23  |.:..t....L]...`#|
-00000050  d5 f5 04 06 16 e2 69 ca  4d 99 1b a0 b5 3b 7d 62  |......i.M....;}b|
-00000060  51 62 ee d9 60                                    |Qb..`|
+00000030  16 03 01 00 30 7a cf 24  f7 f6 69 1a ab 34 31 d5  |....0z.$..i..41.|
+00000040  af ed 37 9f 1d 8d 3a 6b  72 a3 b0 fc b9 49 fb bc  |..7...:kr....I..|
+00000050  c5 94 9e 37 ce b0 87 8f  ed 52 25 eb 2d 53 b9 39  |...7.....R%.-S.9|
+00000060  d2 d3 f0 d6 97                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 4d f9 c2 63 4f  |..........0M..cO|
-00000010  98 1b 02 ce df ca d1 15  a2 4f 6f 4c 2c b8 1a 88  |.........OoL,...|
-00000020  11 c9 b3 45 e6 1d cf e8  6b dd 8c 89 c6 1d 0b 66  |...E....k......f|
-00000030  82 d5 1d c6 55 14 1c 56  59 3e 69                 |....U..VY>i|
+00000000  14 03 01 00 01 01 16 03  01 00 30 92 72 cc c3 1f  |..........0.r...|
+00000010  4b a5 c4 d7 6f d1 17 4b  4e 27 b7 f5 72 fd c2 a0  |K...o..KN'..r...|
+00000020  30 cb 4c cf 82 1f 0a 49  3d 23 bc 47 f1 e8 a7 b5  |0.L....I=#.G....|
+00000030  c7 6a 92 25 55 3a f0 0f  b0 30 74                 |.j.%U:...0t|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 12 be 42  b4 31 07 55 8e f9 a1 64  |.... ..B.1.U...d|
-00000010  96 70 46 68 3e fd 4e 4f  9c af b3 11 de fc 80 f1  |.pFh>.NO........|
-00000020  c8 11 84 ba ae 17 03 01  00 20 2f f9 ec dd 50 97  |......... /...P.|
-00000030  1e a4 f1 66 fe 28 e3 c1  51 8d c0 f6 c3 d8 b3 ad  |...f.(..Q.......|
-00000040  7d dc a5 98 87 90 34 71  b4 73 15 03 01 00 20 d1  |}.....4q.s.... .|
-00000050  6f 91 91 01 68 c4 11 6a  e5 a2 ed 20 3f 3a 3d b7  |o...h..j... ?:=.|
-00000060  d9 7f c3 b3 29 c3 df 3e  17 69 76 9f 04 f8 58     |....)..>.iv...X|
+00000000  17 03 01 00 20 85 49 7a  58 80 e9 59 63 d0 74 a1  |.... .IzX..Yc.t.|
+00000010  b7 d9 1b 46 41 5f 51 c0  66 4a 10 e1 ad dd 9f 9a  |...FA_Q.fJ......|
+00000020  c3 cf 32 77 72 17 03 01  00 20 05 7d 08 38 3d f0  |..2wr.... .}.8=.|
+00000030  02 f7 17 71 b7 1c 29 c3  a6 c8 ff 7a 82 36 1e 42  |...q..)....z.6.B|
+00000040  00 1e 6c d8 b1 39 22 ec  62 43 15 03 01 00 20 0d  |..l..9".bC.... .|
+00000050  80 5b da 89 4d 42 ab 95  17 11 0f 9b 79 2f c8 3f  |.[..MB......y/.?|
+00000060  f2 fd 54 2e ea 4a f9 de  fc 5d 7f 75 51 86 e5     |..T..J...].uQ..|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
index 78947ac..2cae087 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 45 04 14 a2 70  |....Y...U..E...p|
-00000010  3e 1e d9 2c d4 bd f3 e8  9c f3 e0 08 d8 0f 7f 82  |>..,............|
-00000020  2b 07 a0 bd 47 56 a0 e1  06 0d 36 20 fc 0f 5b 85  |+...GV....6 ..[.|
-00000030  8e 17 20 f1 f6 1e 80 c3  79 1a e1 86 c3 ed e9 24  |.. .....y......$|
-00000040  6d bb 24 3c 0c 8d 2c 79  f2 03 27 b0 c0 13 00 00  |m.$<..,y..'.....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 f8 80 7d dd cc  |....Y...U....}..|
+00000010  ab 8c 66 56 c7 e9 18 88  87 44 39 67 57 91 e8 ee  |..fV.....D9gW...|
+00000020  3a c0 bc 2e bf 50 54 5e  8d c2 61 20 da b0 2d 85  |:....PT^..a ..-.|
+00000030  e2 ed f5 5f 2b af 14 87  e6 26 6b af a4 4a 24 2d  |..._+....&k..J$-|
+00000040  1a bc 15 96 11 c8 c0 8b  e9 0c 27 91 c0 13 00 00  |..........'.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,36 +54,36 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 01 00  |.=.`.\!.;.......|
-000002c0  aa 0c 00 00 a6 03 00 1d  20 85 05 5f e3 a2 b2 12  |........ .._....|
-000002d0  c8 82 53 2b c2 38 e1 a8  08 87 a7 d5 b3 98 6f 81  |..S+.8........o.|
-000002e0  ce 81 6b 78 3e 3a b7 1d  71 00 80 43 81 fb 47 5e  |..kx>:..q..C..G^|
-000002f0  08 16 39 35 d3 c2 f3 ea  bb 2c 7d bc 01 9b 35 5d  |..95.....,}...5]|
-00000300  63 7e c3 38 f3 04 96 eb  d7 3f d1 df 71 97 ec 22  |c~.8.....?..q.."|
-00000310  1b 4a 89 14 4d e5 44 08  87 52 69 ea 28 f8 6a ea  |.J..M.D..Ri.(.j.|
-00000320  3e ff 17 de 4d 20 95 e3  6e 3f af 05 20 9b a3 ac  |>...M ..n?.. ...|
-00000330  70 1b 1c bf f9 52 d6 11  6d d9 85 90 08 4d 64 1f  |p....R..m....Md.|
-00000340  c5 35 34 37 11 b8 44 a3  ef 93 a6 b6 87 58 0b c4  |.547..D......X..|
-00000350  8e 94 d8 67 4d 09 7a 2a  aa 95 db e6 af 29 21 a2  |...gM.z*.....)!.|
-00000360  ee c3 90 ef c6 53 46 12  fb 87 06 16 03 01 00 04  |.....SF.........|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 0a d4 a1 84 63 ba 2d  |........ ....c.-|
+000002d0  23 89 b1 37 eb 97 d3 a7  09 36 3d ac 2a 30 7c f9  |#..7.....6=.*0|.|
+000002e0  f6 87 67 86 22 fa f5 f9  06 00 80 c9 ea 8a 76 f2  |..g.".........v.|
+000002f0  a5 1b e8 14 2c 2a 2f 2e  a0 78 ac 06 9b 48 a8 d9  |....,*/..x...H..|
+00000300  03 91 e7 c1 e5 e6 a3 9e  5e 33 73 0a f4 b3 d7 64  |........^3s....d|
+00000310  5f 86 d6 36 e5 88 25 90  3c a2 d6 3f d6 07 7a 5c  |_..6..%.<..?..z\|
+00000320  64 c4 0f ac a9 3e c9 f6  b6 35 2a df a3 a3 79 8f  |d....>...5*...y.|
+00000330  b3 a6 f4 d8 e4 0a 4f 5f  11 3a 85 9a 0c 48 7b 3b  |......O_.:...H{;|
+00000340  a2 24 ec c0 44 7e eb b5  f3 f8 52 e6 83 bf 45 91  |.$..D~....R...E.|
+00000350  9a 7c a4 e3 29 97 ea 9c  94 28 66 73 45 ed 52 2f  |.|..)....(fsE.R/|
+00000360  df a8 44 8b a5 0b 7a 31  92 eb 72 16 03 01 00 04  |..D...z1..r.....|
 00000370  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 01 00 01 01  |....._X.;t......|
-00000030  16 03 01 00 30 50 f5 a9  34 25 ed a2 fb c8 7f 35  |....0P..4%.....5|
-00000040  08 57 59 da 54 c1 8d 92  ec 23 73 af f3 92 8d 19  |.WY.T....#s.....|
-00000050  03 ce ab 5b eb dc 5b 81  3f 51 a1 20 31 3f 33 da  |...[..[.?Q. 1?3.|
-00000060  27 c5 c3 9c fd                                    |'....|
+00000030  16 03 01 00 30 19 34 cf  68 d1 8f ea be 56 24 71  |....0.4.h....V$q|
+00000040  e4 ad ad f8 b3 dd 57 43  46 d5 8d f3 1c 0c df 4f  |......WCF......O|
+00000050  1c af 3b 2a 24 e4 8a 98  b5 b7 61 6f 5f 48 68 20  |..;*$.....ao_Hh |
+00000060  b7 6a 9c ee 80                                    |.j...|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 b1 61 9b 63 4e  |..........0.a.cN|
-00000010  43 96 80 49 ac 2d 93 7d  b9 f2 bb 81 79 5e 94 bf  |C..I.-.}....y^..|
-00000020  06 d0 a6 14 46 91 cd 90  b0 8a 85 ee fe 41 a7 4d  |....F........A.M|
-00000030  97 d7 4d 40 5e f4 5b bd  d3 0c db                 |..M@^.[....|
+00000000  14 03 01 00 01 01 16 03  01 00 30 fc 42 2b 0f 86  |..........0.B+..|
+00000010  73 e1 a1 1a 09 1e 78 7d  61 f1 7c a4 94 14 26 53  |s.....x}a.|...&S|
+00000020  de 28 f3 63 63 c3 65 7b  e4 fd 10 2d 66 ed f7 dd  |.(.cc.e{...-f...|
+00000030  f9 9e 13 5c c1 e8 94 6a  32 c0 db                 |...\...j2..|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 49 21 bc  a5 4c 96 41 3f 22 87 0a  |.... I!..L.A?"..|
-00000010  c0 4e 0e 54 cb c2 27 8a  4f b0 37 fb b4 1f c1 4e  |.N.T..'.O.7....N|
-00000020  77 e1 09 57 23 17 03 01  00 20 f0 f0 3b 78 a8 ae  |w..W#.... ..;x..|
-00000030  ef b1 e0 f4 29 0f 90 4a  0f e5 48 34 84 5e 4f d8  |....)..J..H4.^O.|
-00000040  53 46 f8 29 64 2b 8e 87  79 0a 15 03 01 00 20 71  |SF.)d+..y..... q|
-00000050  32 6c 08 2a f7 18 c8 d5  48 a8 c7 d1 68 7a 65 ec  |2l.*....H...hze.|
-00000060  3e fa 4b fe ff 76 1a 57  64 22 61 27 a0 5d b6     |>.K..v.Wd"a'.].|
+00000000  17 03 01 00 20 36 9a 1b  7f 79 a7 ff 31 92 36 5f  |.... 6...y..1.6_|
+00000010  7c d2 21 69 01 b6 24 da  ea b4 b2 42 81 b5 55 94  ||.!i..$....B..U.|
+00000020  8e b8 25 83 35 17 03 01  00 20 27 28 1c 8a fa 21  |..%.5.... '(...!|
+00000030  57 39 77 57 5b bd ef 05  5b 39 e2 07 1b c9 3c f7  |W9wW[...[9....<.|
+00000040  b9 ac be ce 7e 16 87 6d  5b a7 15 03 01 00 20 c0  |....~..m[..... .|
+00000050  9b 05 b5 eb ac 65 08 ae  12 c7 18 be 00 a4 d6 30  |.....e.........0|
+00000060  15 dd 90 5d d7 25 89 37  be 3d 56 d3 8c a9 3d     |...].%.7.=V...=|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
index 7ecfbde..2e10537 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 51 02 00 00  4d 03 01 4c 98 ce a5 80  |....Q...M..L....|
-00000010  84 dc d3 70 de 75 bf 26  5c 15 8b b7 2c 78 30 a7  |...p.u.&\...,x0.|
-00000020  65 1a 0c f7 1a e5 51 91  7c cb ca 20 83 2c 90 3b  |e.....Q.|.. .,.;|
-00000030  cf dd 4e 51 8b 27 98 95  aa d9 1d da 4d 3d e1 18  |..NQ.'......M=..|
-00000040  f5 58 fd 85 c5 ed c9 5f  12 2f 4b b3 00 05 00 00  |.X....._./K.....|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 ba 66 88 b5 b3  |....Q...M...f...|
+00000010  17 e1 9a c1 b6 27 e0 3f  1c 80 73 b6 6c 16 c9 4e  |.....'.?..s.l..N|
+00000020  33 c4 8c 75 26 46 01 1b  31 dc a3 20 e3 57 4f 91  |3..u&F..1.. .WO.|
+00000030  3e 5b 91 cf 75 77 71 66  2f be 84 20 1c 7f 02 dd  |>[..uwqf/.. ....|
+00000040  8b 63 43 6c 4d 1d a4 7a  da 89 35 5a 00 05 00 00  |.cClM..z..5Z....|
 00000050  05 ff 01 00 01 00 16 03  01 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -64,15 +64,15 @@
 00000060  c5 70 0f 08 83 48 e9 48  ef 6e 50 8b 05 7e e5 84  |.p...H.H.nP..~..|
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 01 00 01  |.Y(.....ia5.....|
-00000090  01 16 03 01 00 24 0e 4d  ff 2c 39 80 ba a5 96 18  |.....$.M.,9.....|
-000000a0  56 15 94 9f e2 1e 7d 13  62 51 d5 e1 05 f8 d8 b3  |V.....}.bQ......|
-000000b0  bd 77 58 38 95 b4 7d 37  66 8a                    |.wX8..}7f.|
+00000090  01 16 03 01 00 24 b6 4b  4c 75 2d d9 8d 1c 85 df  |.....$.KLu-.....|
+000000a0  f1 8d ff 7a 24 6b 02 3f  fa 80 d7 f4 71 76 77 97  |...z$k.?....qvw.|
+000000b0  fd b3 59 d7 91 9f 3a e9  ec 3b                    |..Y...:..;|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 dc 6f da 57 0d  |..........$.o.W.|
-00000010  f8 b8 aa d5 e5 0a 2e 81  ed 2a b7 f8 0e 2a f1 05  |.........*...*..|
-00000020  76 8d 4f b0 0e db 16 c5  d7 c8 5e f9 fb 9e e0     |v.O.......^....|
+00000000  14 03 01 00 01 01 16 03  01 00 24 b6 51 7e 95 65  |..........$.Q~.e|
+00000010  c5 85 08 c3 31 5c ae 2e  e9 9e 6e bb 3d e8 68 c5  |....1\....n.=.h.|
+00000020  26 a0 8c 61 a8 96 09 3c  ec c7 9a 80 ff a2 5d     |&..a...<......]|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 47 97 4d  e6 59 d4 2f bb 60 56 69  |.....G.M.Y./.`Vi|
-00000010  d8 bc 8d 91 44 7c cd 85  7e c5 18 5f 57 8e 08 15  |....D|..~.._W...|
-00000020  03 01 00 16 f7 79 56 72  e6 77 8d af 94 55 d7 0e  |.....yVr.w...U..|
-00000030  96 c8 3b 35 52 ea f7 e7  b8 d6                    |..;5R.....|
+00000000  17 03 01 00 1a 0b 83 3a  24 a0 b4 7f cc 86 6c 4f  |.......:$.....lO|
+00000010  db 19 1b 09 23 77 a6 91  c6 09 db aa 3c 1a f3 15  |....#w......<...|
+00000020  03 01 00 16 80 dc 14 9b  a7 ff 08 af 25 5e 67 8c  |............%^g.|
+00000030  2d 2a 8e c9 bc 17 5a 29  48 99                    |-*....Z)H.|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
index 5232ad5..2ef4407 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 30 f8 f6 b2 af  |....Y...U..0....|
-00000010  99 b0 e0 f6 9a eb 47 6f  2f ad 2f 45 18 56 b3 dd  |......Go/./E.V..|
-00000020  b6 b9 20 fb af 97 43 1f  0e 51 c0 20 fe 6c 12 64  |.. ...C..Q. .l.d|
-00000030  8e cc a4 24 d6 e6 80 cf  f2 9e 74 3f a7 1e 8b da  |...$......t?....|
-00000040  0e 3c 58 74 f4 8f be 1f  60 86 57 c6 c0 09 00 00  |.<Xt....`.W.....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 cd 65 75 71 6d  |....Y...U...euqm|
+00000010  da bd fe 6b ac ce 01 2f  8e 17 f6 5c 25 37 16 0d  |...k.../...\%7..|
+00000020  bb 5f 39 e1 c3 14 94 d8  9f 26 02 20 ba 75 d9 3c  |._9......&. .u.<|
+00000030  2d 56 1f 77 0d 36 52 38  20 44 e2 33 83 4d 93 a0  |-V.w.6R8 D.3.M..|
+00000040  fa fe 38 58 d3 1e db 72  ee 14 76 12 c0 09 00 00  |..8X...r..v.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  02 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,39 +49,39 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 02 00 b3 0c 00  00 af 03 00 1d 20 4b 2d  |*............ K-|
-00000280  60 48 54 b4 48 42 10 de  e1 98 f0 fb 73 d9 49 16  |`HT.HB......s.I.|
-00000290  3e a2 11 b3 84 50 de 26  00 09 d8 36 34 04 00 89  |>....P.&...64...|
-000002a0  30 81 86 02 41 24 90 6f  3e 1a 2c a5 7f 08 dc b2  |0...A$.o>.,.....|
-000002b0  d3 46 27 5e cb 1f 2a 6d  92 ba 1b fe e3 c5 64 79  |.F'^..*m......dy|
-000002c0  31 50 8c 43 4b b1 ee 0d  6f 53 ad 6f e9 db 86 e7  |1P.CK...oS.o....|
-000002d0  1f e3 77 f1 8d a8 ab 81  2a d6 fa e7 98 d5 bc 0d  |..w.....*.......|
-000002e0  ec af ea 84 c4 f8 02 41  6a d2 66 32 e1 d7 46 1a  |.......Aj.f2..F.|
-000002f0  95 5a 91 c3 76 82 20 c2  a3 a2 32 f5 fd eb a2 0e  |.Z..v. ...2.....|
-00000300  0f d8 a9 31 7a ef a8 05  6c 5d bf 27 d0 2d 94 ca  |...1z...l].'.-..|
-00000310  fb d6 62 7a 1c 6a 46 20  fe ed a6 60 a3 db b1 bd  |..bz.jF ...`....|
-00000320  11 82 05 c3 db 0c 4a 2d  6c 16 03 02 00 04 0e 00  |......J-l.......|
+00000270  2a 16 03 02 00 b3 0c 00  00 af 03 00 1d 20 63 d9  |*............ c.|
+00000280  4a 4e 6b ef 1c 95 89 ab  f8 93 20 46 3f 51 40 a3  |JNk....... F?Q@.|
+00000290  2a d5 e7 6b 18 04 01 55  6f d7 3f de 6f 20 00 89  |*..k...Uo.?.o ..|
+000002a0  30 81 86 02 41 72 0a a5  28 94 81 35 17 04 6b 6c  |0...Ar..(..5..kl|
+000002b0  9b 66 0f 31 2e 83 55 bb  af 97 87 8b 41 cd eb 2c  |.f.1..U.....A..,|
+000002c0  d0 71 87 4f d8 80 33 ec  d2 57 6e 16 20 7a a7 aa  |.q.O..3..Wn. z..|
+000002d0  93 9a 14 5b 56 cb df ff  b6 bc 5f 98 64 3c e2 cb  |...[V....._.d<..|
+000002e0  e3 45 0c ac 94 a5 02 41  41 97 c8 5e 64 74 93 ee  |.E.....AA..^dt..|
+000002f0  2e 56 fb 8a 0b ca f8 e7  5e 80 c7 8c 78 89 37 1b  |.V......^...x.7.|
+00000300  f2 ff de a0 df 54 9b 58  32 26 c7 cf ad af 5d 06  |.....T.X2&....].|
+00000310  d9 7e 0b 96 a0 e0 64 64  e7 f4 04 08 40 b2 d6 a5  |.~....dd....@...|
+00000320  bd 75 f4 7c 33 cd 3f 34  02 16 03 02 00 04 0e 00  |.u.|3.?4........|
 00000330  00 00                                             |..|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 02 00 01 01  |....._X.;t......|
 00000030  16 03 02 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000040  00 00 00 00 00 22 71 28  3d 07 73 61 5e 84 72 36  |....."q(=.sa^.r6|
-00000050  c0 87 37 4a 5b c2 d9 40  96 a2 01 20 b2 04 23 2f  |..7J[..@... ..#/|
-00000060  c1 6f 1e 7c a1 77 20 0f  87 46 98 a2 5c aa 35 37  |.o.|.w ..F..\.57|
-00000070  37 87 5a 75 33                                    |7.Zu3|
+00000040  00 00 00 00 00 e8 63 07  7b aa d4 3b ce 03 91 f7  |......c.{..;....|
+00000050  4e 28 74 df 52 5f 3e 80  81 30 9d 4e e3 a5 f5 11  |N(t.R_>..0.N....|
+00000060  57 80 db 52 1d 4c c4 f3  38 c0 62 3d 84 57 1b 5d  |W..R.L..8.b=.W.]|
+00000070  1a 51 b3 bb c3                                    |.Q...|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 21 b5 1f 8d 4b  |..........@!...K|
-00000010  1c a7 28 4e 73 3e d7 c5  75 6e eb e4 b3 95 02 4e  |..(Ns>..un.....N|
-00000020  a3 47 03 44 97 69 c9 89  f5 ac e2 29 5e 22 e7 2c  |.G.D.i.....)^".,|
-00000030  a2 2d e3 ac 64 45 ae 9d  07 9e fe f8 c6 85 47 4d  |.-..dE........GM|
-00000040  59 be 72 8d e6 50 da c7  83 91 14                 |Y.r..P.....|
+00000000  14 03 02 00 01 01 16 03  02 00 40 25 b2 b4 08 64  |..........@%...d|
+00000010  e0 09 4f 9a 25 35 7a 29  d8 0f 6d c6 39 3e 9e 17  |..O.%5z)..m.9>..|
+00000020  9f bb a2 cc e5 17 5c 76  36 b2 10 13 a2 c5 e9 ba  |......\v6.......|
+00000030  08 5b f5 ff 8e 64 cc 3a  72 54 22 84 e9 d5 15 8e  |.[...d.:rT".....|
+00000040  85 44 f4 d3 e2 a8 48 46  32 9d b5                 |.D....HF2..|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 57 45 25  4c 1b 90 d3 28 e1 69 43  |.....WE%L...(.iC|
-00000020  c5 28 d9 d5 15 35 cf 41  bb 38 f2 12 c6 18 a5 a2  |.(...5.A.8......|
-00000030  f5 e4 64 1d 59 15 03 02  00 30 00 00 00 00 00 00  |..d.Y....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 35 06 5f e3 ff e7  |..........5._...|
-00000050  f0 f1 0c d5 b1 59 42 80  19 8d 67 1b 18 18 5c 18  |.....YB...g...\.|
-00000060  42 38 67 85 c3 ab e2 dc  60 d4                    |B8g.....`.|
+00000010  00 00 00 00 00 29 6a 84  08 a0 1e eb 43 8e c2 c7  |.....)j.....C...|
+00000020  db 45 cc ee 39 0d a7 17  5f da e4 f5 70 d4 10 73  |.E..9..._...p..s|
+00000030  40 94 f4 81 4c 15 03 02  00 30 00 00 00 00 00 00  |@...L....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 17 41 90 a8 d4 70  |...........A...p|
+00000050  c2 5e 89 b6 4e d9 49 83  31 58 c1 ca 59 ec 55 a7  |.^..N.I.1X..Y.U.|
+00000060  78 83 63 d0 97 32 a0 78  f5 61                    |x.c..2.x.a|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
index 48ff7bc..ccf3001 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 10 ca d9 1b 83  |....Y...U.......|
-00000010  59 c8 a5 a5 6a 89 65 6e  1c 0a 49 98 69 05 49 27  |Y...j.en..I.i.I'|
-00000020  96 72 74 5f 6e 5b 66 26  3b fd f8 20 23 b5 d6 c5  |.rt_n[f&;.. #...|
-00000030  09 f1 66 02 27 5c 5a 15  17 83 c5 11 a4 32 cf d8  |..f.'\Z......2..|
-00000040  1e a0 e7 93 83 35 6e aa  61 ae 97 77 c0 13 00 00  |.....5n.a..w....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 25 c4 bc bf ab  |....Y...U..%....|
+00000010  16 38 05 55 b8 78 a8 b6  e4 0c cb 70 f9 72 a9 5f  |.8.U.x.....p.r._|
+00000020  f3 59 86 32 ca 92 b6 dd  66 83 42 20 e8 b9 6d 35  |.Y.2....f.B ..m5|
+00000030  25 ec e2 37 91 f1 9e 8b  0b 7f 15 cf fd 34 16 9e  |%..7.........4..|
+00000040  ff 44 67 72 df bd 95 75  d3 fd 89 a5 c0 13 00 00  |.Dgr...u........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  02 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,38 +54,38 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 02 00  |.=.`.\!.;.......|
-000002c0  aa 0c 00 00 a6 03 00 1d  20 97 a4 91 6b cd ca 44  |........ ...k..D|
-000002d0  7e ac fd a5 b1 c0 ce 88  07 f3 a2 d9 93 2b a8 d9  |~............+..|
-000002e0  0b 65 0b 47 c0 2e 4f 3b  26 00 80 00 18 01 a1 29  |.e.G..O;&......)|
-000002f0  0b 84 c9 09 5e 8c 58 5f  62 b6 22 8b 94 6e 72 26  |....^.X_b."..nr&|
-00000300  44 27 32 b9 22 12 67 58  34 a1 ce 6f 87 19 a0 5c  |D'2.".gX4..o...\|
-00000310  5d 58 dc 91 fb c7 e6 31  33 76 6d 1f 8e 4f 46 55  |]X.....13vm..OFU|
-00000320  f1 08 57 9b bb fe 8d c7  6c 0b cd 8b ad b7 51 28  |..W.....l.....Q(|
-00000330  f8 5b 75 97 fe a0 d4 a1  2e 9a d3 d5 45 62 f8 19  |.[u.........Eb..|
-00000340  f6 73 d0 f6 6d e8 43 49  a2 f5 71 66 c5 29 1a 99  |.s..m.CI..qf.)..|
-00000350  e6 c0 cc f9 a5 cd a5 b7  58 08 4d cc 17 46 91 4c  |........X.M..F.L|
-00000360  29 99 b4 05 78 af e7 b0  d1 2d 38 16 03 02 00 04  |)...x....-8.....|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 07 e7 bf ce 93 eb a9  |........ .......|
+000002d0  c7 5d 78 3f bc 62 d4 d3  88 10 98 5e 6e 90 3e b5  |.]x?.b.....^n.>.|
+000002e0  11 cb 3d ed 42 1a d8 ac  2b 00 80 17 fa bd aa a4  |..=.B...+.......|
+000002f0  9c 14 78 9f d8 e7 65 3f  1f 54 b8 37 fc 2f a4 61  |..x...e?.T.7./.a|
+00000300  aa 47 ce ca 0f 59 f0 22  8c 5a e6 c8 ed 4e aa 91  |.G...Y.".Z...N..|
+00000310  c3 ce a8 08 21 7d d7 ef  88 c6 fc 04 6b b2 c8 d6  |....!}......k...|
+00000320  f0 3e aa dc 25 8c bd e7  fd 35 ea 44 7f 6d 2f bb  |.>..%....5.D.m/.|
+00000330  f4 8d a2 39 f9 a1 69 9e  8e bc 08 50 1b 3d fe a9  |...9..i....P.=..|
+00000340  91 bd ab 67 2f 7a 71 a2  85 b2 3e ef 3f a5 45 c7  |...g/zq...>.?.E.|
+00000350  b1 2c 69 a0 ae 50 f8 12  73 c2 26 6a f0 7d 1f 28  |.,i..P..s.&j.}.(|
+00000360  49 1b c0 96 45 d8 e9 19  bd 47 af 16 03 02 00 04  |I...E....G......|
 00000370  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 02 00 01 01  |....._X.;t......|
 00000030  16 03 02 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000040  00 00 00 00 00 f2 fb 8f  ab ae 46 f2 6a 18 1b 77  |..........F.j..w|
-00000050  f3 ce 0c b6 83 9c d6 34  54 82 76 db 5c 79 5d cf  |.......4T.v.\y].|
-00000060  24 f3 26 6d 9d f0 af d3  fc e0 96 69 0a 04 f7 ba  |$.&m.......i....|
-00000070  78 54 af 37 a5                                    |xT.7.|
+00000040  00 00 00 00 00 f4 1e 67  b5 2c 02 b9 fc 49 44 f1  |.......g.,...ID.|
+00000050  85 9f df bd 47 03 f5 68  a4 54 68 ea 13 c8 4c f8  |....G..h.Th...L.|
+00000060  81 5e 06 c3 df 2c bb f9  9c a6 99 36 26 60 e0 ac  |.^...,.....6&`..|
+00000070  5f 82 0a c1 ea                                    |_....|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 e7 d9 0e af 0c  |..........@.....|
-00000010  06 55 85 ab b0 0a 5e d9  11 81 7a 53 c0 f6 3f 84  |.U....^...zS..?.|
-00000020  06 7d 9c 20 05 e9 0d 1d  df 9b 48 11 d9 df 0c e6  |.}. ......H.....|
-00000030  6b c2 a8 8f f4 d9 e8 8e  f6 1a 3e db 7c e5 97 ac  |k.........>.|...|
-00000040  5d 63 08 b2 3a 54 91 62  fc 2e a5                 |]c..:T.b...|
+00000000  14 03 02 00 01 01 16 03  02 00 40 82 b5 a3 75 27  |..........@...u'|
+00000010  3d 41 d0 00 f7 7d 1a e8  97 98 f6 f1 df f7 00 37  |=A...}.........7|
+00000020  a7 2e 29 e6 5a 26 ca ef  94 2c 05 06 c4 94 66 01  |..).Z&...,....f.|
+00000030  94 65 e3 45 50 7d 7a f4  78 ab 24 f6 9b 84 4b 7d  |.e.EP}z.x.$...K}|
+00000040  a7 02 9c 32 f7 90 39 ac  a6 61 47                 |...2..9..aG|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 3f ef e9  bc 10 07 75 99 67 8f 99  |.....?.....u.g..|
-00000020  bb c0 15 94 86 a2 80 cc  15 97 54 f8 4e 1a d1 9a  |..........T.N...|
-00000030  33 80 aa da ec 15 03 02  00 30 00 00 00 00 00 00  |3........0......|
-00000040  00 00 00 00 00 00 00 00  00 00 6f 78 7b d2 80 62  |..........ox{..b|
-00000050  5c cf 34 d6 5a 72 d8 63  95 24 c6 ff 69 d0 6d 90  |\.4.Zr.c.$..i.m.|
-00000060  8d a2 9f 37 e8 7b b1 d4  68 04                    |...7.{..h.|
+00000010  00 00 00 00 00 76 c0 94  ff b2 5a f4 4a 17 47 43  |.....v....Z.J.GC|
+00000020  94 d0 b3 7a 77 c0 e6 5d  0e 92 6d 6b 72 b9 d4 58  |...zw..]..mkr..X|
+00000030  d3 d5 be 50 95 15 03 02  00 30 00 00 00 00 00 00  |...P.....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 25 f0 64 c9 b4 f7  |..........%.d...|
+00000050  3c 36 ea e2 df 8c 47 aa  1d a9 ba 5e d0 ce 10 6b  |<6....G....^...k|
+00000060  a3 4b 08 04 10 60 ce 75  a1 5b                    |.K...`.u.[|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
index 2e9c49e..0c8ae35 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 51 02 00 00  4d 03 02 36 8f 18 79 0f  |....Q...M..6..y.|
-00000010  99 6b 3d 1d f4 19 aa ff  79 7c 50 15 52 db 9d c5  |.k=.....y|P.R...|
-00000020  62 40 2d 5b de 45 0c 66  b1 cb be 20 9e 00 c3 00  |b@-[.E.f... ....|
-00000030  22 2f b5 c6 79 c1 f7 72  8f 4b 94 f4 ac fe a9 53  |"/..y..r.K.....S|
-00000040  97 4e fb 00 df 34 b6 24  8f ff 89 db 00 05 00 00  |.N...4.$........|
+00000000  16 03 02 00 51 02 00 00  4d 03 02 17 49 a0 13 8a  |....Q...M...I...|
+00000010  1d 7a e5 dd dd f3 ba 71  8c 9f b9 16 55 98 4e 56  |.z.....q....U.NV|
+00000020  74 da 97 99 09 b7 5a cb  16 17 a8 20 b4 67 96 70  |t.....Z.... .g.p|
+00000030  f5 7c 25 f3 5e 47 6b 38  fb 2a 18 67 a7 35 b6 93  |.|%.^Gk8.*.g.5..|
+00000040  88 26 c7 da 67 7c d7 d9  4d 23 46 15 00 05 00 00  |.&..g|..M#F.....|
 00000050  05 ff 01 00 01 00 16 03  02 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -64,15 +64,15 @@
 00000060  c5 70 0f 08 83 48 e9 48  ef 6e 50 8b 05 7e e5 84  |.p...H.H.nP..~..|
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 02 00 01  |.Y(.....ia5.....|
-00000090  01 16 03 02 00 24 92 fa  9a bb 9b a3 39 3f 6b 0c  |.....$......9?k.|
-000000a0  70 b5 48 4a fc cf 79 86  c7 90 e8 db ca 6a ff 95  |p.HJ..y......j..|
-000000b0  11 9b 65 b2 07 61 00 a8  dc 14                    |..e..a....|
+00000090  01 16 03 02 00 24 57 25  f5 73 5b e7 e4 e5 41 29  |.....$W%.s[...A)|
+000000a0  0f 6f c5 92 93 17 17 fe  3f 84 cb 62 c0 69 ef ae  |.o......?..b.i..|
+000000b0  c4 96 c7 32 76 b9 fb 2a  01 03                    |...2v..*..|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 47 d5 78 31 32  |..........$G.x12|
-00000010  db db 2b f4 2f e6 a4 fa  fa 04 31 ba c0 bc 86 38  |..+./.....1....8|
-00000020  29 70 53 c6 8c 28 e5 75  90 ed 0f 4f 3e cb 06     |)pS..(.u...O>..|
+00000000  14 03 02 00 01 01 16 03  02 00 24 74 40 46 d2 01  |..........$t@F..|
+00000010  85 de 99 2e 04 b7 c4 a6  50 61 22 01 23 fd 77 be  |........Pa".#.w.|
+00000020  55 6a 6d 1a 79 17 c7 3d  75 64 99 fc bb 42 a7     |Ujm.y..=ud...B.|
 >>> Flow 5 (client to server)
-00000000  17 03 02 00 1a f3 e7 6c  01 c5 70 c6 69 dd 4f 40  |.......l..p.i.O@|
-00000010  38 c1 b2 d2 28 69 2f 99  b1 bd 71 d0 c2 00 08 15  |8...(i/...q.....|
-00000020  03 02 00 16 4c 44 14 02  8e 46 f8 84 40 f1 3d 6d  |....LD...F..@.=m|
-00000030  f2 01 f6 9d 7a 0b 18 ee  9d 41                    |....z....A|
+00000000  17 03 02 00 1a d0 cc 3e  2e f5 09 1d 14 b6 ec f4  |.......>........|
+00000010  19 64 30 40 eb 86 31 8b  61 fd 94 b5 3a 0c d5 15  |.d0@..1.a...:...|
+00000020  03 02 00 16 f2 d9 24 a4  f7 65 0e 26 1e c0 c9 7d  |......$..e.&...}|
+00000030  5c 57 59 fb 80 fd ab ab  83 e4                    |\WY.......|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
index c20dcc6..c63e71a 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 65 9c b1 7a 5c  |....Q...M..e..z\|
-00000010  84 e5 a5 12 ba 54 1f 4c  ec 95 0b 8f ea 5c cc 3b  |.....T.L.....\.;|
-00000020  de b8 18 23 8e c4 95 59  d7 7f 8f 20 36 fe ec 27  |...#...Y... 6..'|
-00000030  10 85 43 fb 9c 68 3f 69  d0 08 a6 57 10 a6 29 a4  |..C..h?i...W..).|
-00000040  f6 0c 2e 05 6e 0d e5 44  61 e1 2e 07 00 9c 00 00  |....n..Da.......|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 49 4c e7 e2 d1  |....Q...M..IL...|
+00000010  f6 48 5a 9c 53 86 a7 b4  43 a2 35 a1 6a cd 40 8d  |.HZ.S...C.5.j.@.|
+00000020  db 5a 93 d2 66 1a 9e b3  cd ab 8b 20 52 21 cc 8d  |.Z..f...... R!..|
+00000030  24 23 ed 26 f1 c0 44 17  74 1a ef 01 5c c5 8e 79  |$#.&..D.t...\..y|
+00000040  f6 e5 00 e8 b3 71 72 99  a5 2d 4d cf 00 9c 00 00  |.....qr..-M.....|
 00000050  05 ff 01 00 01 00 16 03  03 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -64,17 +64,17 @@
 00000060  c5 70 0f 08 83 48 e9 48  ef 6e 50 8b 05 7e e5 84  |.p...H.H.nP..~..|
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 03 00 01  |.Y(.....ia5.....|
-00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 97 f1  |.....(..........|
-000000a0  fe 34 f7 de 76 9b 56 27  e6 9f 36 48 30 a6 de 78  |.4..v.V'..6H0..x|
-000000b0  10 6a ef bf 92 8a 6e 99  21 2f 1b 7b 48 80        |.j....n.!/.{H.|
+00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 c5 41  |.....(.........A|
+000000a0  79 78 69 d0 e6 8f 11 e0  19 7a a2 51 0f b4 1f 8f  |yxi......z.Q....|
+000000b0  8a a5 d9 48 1a b8 cd 2f  ea e2 04 9b e8 9f        |...H.../......|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 23 9d a2 ae a1  |..........(#....|
-00000010  7d dd 92 1f 42 18 68 f6  fb 31 56 7b e4 58 a4 e9  |}...B.h..1V{.X..|
-00000020  c2 1c e7 67 1b 40 b1 b9  63 9d 05 fb c7 44 9e f6  |...g.@..c....D..|
-00000030  7a 14 bb                                          |z..|
+00000000  14 03 03 00 01 01 16 03  03 00 28 f3 72 0c 34 0f  |..........(.r.4.|
+00000010  59 fa 8d 0f d1 37 6d 3b  9c e6 41 66 8b 30 4a d0  |Y....7m;..Af.0J.|
+00000020  ef 21 f1 42 79 f0 55 0e  a1 43 d5 d7 b1 d6 45 aa  |.!.By.U..C....E.|
+00000030  5a 3a 69                                          |Z:i|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 d7 31 70  |..............1p|
-00000010  c8 11 3f bd 83 fc 6e f8  3b e0 ee 45 c5 1a c8 41  |..?...n.;..E...A|
-00000020  80 22 d4 15 03 03 00 1a  00 00 00 00 00 00 00 02  |."..............|
-00000030  7a fe 3a 11 7c c0 26 30  55 24 85 0b 43 cb 7c ac  |z.:.|.&0U$..C.|.|
-00000040  ef 2c                                             |.,|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 7d bd ac  |.............}..|
+00000010  69 1a 3c b3 4d 0f 1b 25  40 95 34 f0 b1 97 60 39  |i.<.M..%@.4...`9|
+00000020  93 42 10 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.B..............|
+00000030  a0 65 f5 b0 94 a5 2e 1a  c4 a5 97 76 12 8f 82 70  |.e.........v...p|
+00000040  49 0c                                             |I.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
index 774481e..17826d3 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 26 31 ba 4a 56  |....Q...M..&1.JV|
-00000010  16 83 15 47 b9 c4 7e 10  ca 92 31 4d 77 af cc cd  |...G..~...1Mw...|
-00000020  70 f4 cc 82 6e b9 ac 1b  0d 17 25 20 e9 08 ec 95  |p...n.....% ....|
-00000030  ea 84 a4 bd 8f 9d 8e d3  58 a7 5e 72 42 e4 19 8f  |........X.^rB...|
-00000040  46 c3 d9 be 16 3c d4 53  5a 02 8f a1 00 3c 00 00  |F....<.SZ....<..|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 89 90 c7 c5 d0  |....Q...M.......|
+00000010  21 e2 50 ac 35 a7 b1 10  8a 32 45 b8 48 02 0e 19  |!.P.5....2E.H...|
+00000020  45 58 31 81 a4 db 0f 19  21 53 80 20 ca a7 7f 02  |EX1.....!S. ....|
+00000030  5a f4 9b cc 70 72 fa e8  ed 4f 0c 1b c7 7a b2 58  |Z...pr...O...z.X|
+00000040  e1 c1 b3 c8 3e a1 82 8e  78 3b c6 02 00 3c 00 00  |....>...x;...<..|
 00000050  05 ff 01 00 01 00 16 03  03 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -65,25 +65,25 @@
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 03 00 01  |.Y(.....ia5.....|
 00000090  01 16 03 03 00 50 00 00  00 00 00 00 00 00 00 00  |.....P..........|
-000000a0  00 00 00 00 00 00 46 91  40 e2 65 40 fe 42 c3 34  |......F.@.e@.B.4|
-000000b0  98 65 89 d0 96 7e 7b 67  8e c4 d5 e6 37 f5 96 04  |.e...~{g....7...|
-000000c0  b7 c8 63 83 76 5c ca 9d  89 18 d4 97 8b 3f f6 75  |..c.v\.......?.u|
-000000d0  1d 51 0b b9 90 1c 85 8f  83 20 9e 9a 21 d9 db 14  |.Q....... ..!...|
-000000e0  1e 02 d4 ab aa c4                                 |......|
+000000a0  00 00 00 00 00 00 e0 31  66 d7 3b a5 a2 cd 61 c5  |.......1f.;...a.|
+000000b0  76 26 ce b4 a7 a3 86 8b  68 98 8a 0c 14 df 71 39  |v&......h.....q9|
+000000c0  29 b0 29 05 97 87 2f d5  81 25 0b 46 e7 91 2a fc  |).).../..%.F..*.|
+000000d0  bb 76 d3 19 31 37 ad 8b  01 f0 66 1f 0f 7f 7a 0f  |.v..17....f...z.|
+000000e0  bd 2b 76 3f 84 2b                                 |.+v?.+|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 6d 34 72 de 79  |..........Pm4r.y|
-00000010  ad 96 d0 92 5f d7 01 de  90 f4 5d 0f de 02 ae 19  |...._.....].....|
-00000020  61 a3 ee 29 ab 18 f1 09  2e 5b bc e0 73 9a 68 19  |a..).....[..s.h.|
-00000030  17 dd c8 d9 63 b4 28 c8  da 1a 81 40 ca d3 5a 99  |....c.(....@..Z.|
-00000040  17 67 fe e9 dd 1a 52 c4  6e 70 0a 0e cf e8 c0 f8  |.g....R.np......|
-00000050  6c 1f ee d2 70 97 dc ee  b8 95 35                 |l...p.....5|
+00000000  14 03 03 00 01 01 16 03  03 00 50 b7 1d 0b ad 4a  |..........P....J|
+00000010  05 27 59 4e 95 11 58 6e  90 02 12 52 40 b2 0e 1d  |.'YN..Xn...R@...|
+00000020  ca 82 a6 85 2f 01 ad 9c  29 41 f9 a0 3d b2 39 be  |..../...)A..=.9.|
+00000030  9f 76 72 3e de db 17 de  d7 9e 4e 0a 89 be 27 9c  |.vr>......N...'.|
+00000040  37 88 46 87 8c a9 a9 41  70 01 72 60 18 4a 3b ac  |7.F....Ap.r`.J;.|
+00000050  97 8e 4f 2c 4b 4e 87 0b  bd e4 89                 |..O,KN.....|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000010  00 00 00 00 00 ee 03 cc  04 97 17 f0 04 85 02 b7  |................|
-00000020  5c 24 ca 9f c2 25 e0 76  f4 72 e5 71 2b ac f4 a5  |\$...%.v.r.q+...|
-00000030  c4 62 08 9a da b7 ab 30  2f 34 b0 70 20 a3 b9 b3  |.b.....0/4.p ...|
-00000040  df 90 9b 01 0b 15 03 03  00 40 00 00 00 00 00 00  |.........@......|
-00000050  00 00 00 00 00 00 00 00  00 00 3b ca fc 0e 08 f2  |..........;.....|
-00000060  c8 b7 22 61 43 24 b3 54  1b ca 58 c6 bd 27 f3 3d  |.."aC$.T..X..'.=|
-00000070  ac a0 d8 fe 0e b5 15 7c  1f 98 32 f0 6b 28 bc 61  |.......|..2.k(.a|
-00000080  6c c7 ba 66 54 19 92 a9  6f 43                    |l..fT...oC|
+00000010  00 00 00 00 00 b6 0c c1  ab 01 1a 69 8f 48 80 5e  |...........i.H.^|
+00000020  f8 d6 b7 b9 7c 9e 30 01  ff 4d 27 94 ef 3e 05 c3  |....|.0..M'..>..|
+00000030  64 fd 38 f9 b9 29 fe 49  bf 6a fc 6f ac 1e 6d ee  |d.8..).I.j.o..m.|
+00000040  42 a2 2f 05 e5 15 03 03  00 40 00 00 00 00 00 00  |B./......@......|
+00000050  00 00 00 00 00 00 00 00  00 00 37 ca 1c 12 fd 31  |..........7....1|
+00000060  2b 9e 56 51 a7 f5 3e 37  48 fe 08 b9 a3 8d 4c 26  |+.VQ..>7H.....L&|
+00000070  7d c2 9d 04 f8 7f b9 47  00 87 bd 86 51 36 83 a7  |}......G....Q6..|
+00000080  98 cf de ac 76 d6 78 ac  bd 95                    |....v.x...|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
index 6d26746..598430d 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 98 b0 4a 9a c8  |....Q...M....J..|
-00000010  8f f9 1f f9 70 03 d9 1a  ee 7c 29 30 6a 71 7c 6c  |....p....|)0jq|l|
-00000020  ea 2c de 84 f9 ee 4d 2c  d7 58 12 20 a4 e2 1b f3  |.,....M,.X. ....|
-00000030  42 b8 9a 0b 71 8c 27 57  61 98 c5 c5 1b 04 01 5b  |B...q.'Wa......[|
-00000040  a0 bc 88 64 d9 ce 5a a1  b2 7b 6c 4e 00 9d 00 00  |...d..Z..{lN....|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 de 31 eb 89 cf  |....Q...M...1...|
+00000010  06 df 45 b2 68 3c 70 8e  ef ec 11 14 d1 f3 8c 95  |..E.h<p.........|
+00000020  c7 11 b6 f9 63 d1 f3 12  5e ec 4b 20 b9 eb 00 03  |....c...^.K ....|
+00000030  2b 2e ff 13 96 50 36 9e  9c 38 ce a7 c8 1b a3 5b  |+....P6..8.....[|
+00000040  a2 c2 99 af c7 0b cb 71  17 56 23 e8 00 9d 00 00  |.......q.V#.....|
 00000050  05 ff 01 00 01 00 16 03  03 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -64,17 +64,17 @@
 00000060  c5 70 0f 08 83 48 e9 48  ef 6e 50 8b 05 7e e5 84  |.p...H.H.nP..~..|
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 03 00 01  |.Y(.....ia5.....|
-00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 57 97  |.....(........W.|
-000000a0  64 ef 80 07 b0 31 02 c8  2a a2 b7 1f d6 a3 7c 7a  |d....1..*.....|z|
-000000b0  e9 c4 e1 55 9f 0a ef 0d  8f 0a 57 13 f5 a4        |...U......W...|
+00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 26 0c  |.....(........&.|
+000000a0  81 5b e0 e4 c5 0f 8b b4  53 f3 84 f8 7c 63 76 2e  |.[......S...|cv.|
+000000b0  47 23 b3 48 a4 2b c0 e8  30 68 0c 34 42 03        |G#.H.+..0h.4B.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 42 49 9c 67 4f  |..........(BI.gO|
-00000010  36 75 b8 34 0e ee 00 98  1a ba 52 d5 96 7b 91 d7  |6u.4......R..{..|
-00000020  ba ec e4 5e 2e 42 e3 72  a0 ea 60 24 31 30 3d a2  |...^.B.r..`$10=.|
-00000030  c5 6c 8f                                          |.l.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 f0 52 59 4b c1  |..........(.RYK.|
+00000010  54 7c 0d 0c 4a 82 96 0a  50 d2 6d ce 7c 2f e9 3c  |T|..J...P.m.|/.<|
+00000020  55 ea da ea 8a 1a 6f 1d  fe 96 01 0f 42 61 61 45  |U.....o.....BaaE|
+00000030  ef 31 97                                          |.1.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 42 9f da  |.............B..|
-00000010  a1 e6 98 48 a8 6c 78 a0  f7 fd e7 0f bc df 97 ef  |...H.lx.........|
-00000020  b8 62 4c 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.bL.............|
-00000030  99 ac 35 a4 d9 1f 58 26  51 c6 6a b9 1f 53 ec 19  |..5...X&Q.j..S..|
-00000040  90 78                                             |.x|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 cb 28 8f  |..............(.|
+00000010  dd 5d cf 29 ef 92 72 71  43 85 c1 1b fe 41 a4 f8  |.].)..rqC....A..|
+00000020  07 f7 96 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  25 52 2c d6 5a f4 95 ea  21 bb 35 70 d1 78 cc 15  |%R,.Z...!.5p.x..|
+00000040  d5 79                                             |.y|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN b/src/crypto/tls/testdata/Client-TLSv12-ALPN
index 9f90ff2..05c4afb 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ALPN
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -1,21 +1,22 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 a9 01 00 00  a5 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 ad 01 00 00  a9 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 50 33 74  |.............P3t|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 54 33 74  |.............T3t|
 00000060  00 00 00 05 00 05 01 00  00 00 00 00 0a 00 0a 00  |................|
 00000070  08 00 1d 00 17 00 18 00  19 00 0b 00 02 01 00 00  |................|
-00000080  0d 00 0e 00 0c 04 01 04  03 05 01 05 03 02 01 02  |................|
-00000090  03 ff 01 00 01 00 00 10  00 10 00 0e 06 70 72 6f  |.............pro|
-000000a0  74 6f 32 06 70 72 6f 74  6f 31 00 12 00 00        |to2.proto1....|
+00000080  0d 00 12 00 10 04 01 04  03 05 01 05 03 06 01 06  |................|
+00000090  03 02 01 02 03 ff 01 00  01 00 00 10 00 10 00 0e  |................|
+000000a0  06 70 72 6f 74 6f 32 06  70 72 6f 74 6f 31 00 12  |.proto2.proto1..|
+000000b0  00 00                                             |..|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 66 02 00 00  62 03 03 8d 70 c6 03 ad  |....f...b...p...|
-00000010  2f 20 b3 c2 ab e0 fc 80  74 c4 23 9e 82 65 61 a1  |/ ......t.#..ea.|
-00000020  26 97 14 a0 9b 9c d5 e0  92 43 ee 20 ec 84 cf 78  |&........C. ...x|
-00000030  44 16 7d f3 ad 94 a9 f8  c3 e0 c6 e1 b6 c5 e3 3d  |D.}............=|
-00000040  77 ea 76 1d 58 cc 94 3a  ad 1a 1a 6c cc a8 00 00  |w.v.X..:...l....|
+00000000  16 03 03 00 66 02 00 00  62 03 03 cb 8e 3f a0 07  |....f...b....?..|
+00000010  c3 0e b3 b2 07 39 e2 2d  b9 5f 03 31 05 b0 0d b6  |.....9.-._.1....|
+00000020  c7 c5 4d 39 2b 3f 1a d7  38 43 69 20 f5 35 e2 93  |..M9+?..8Ci .5..|
+00000030  75 c4 eb b3 eb a3 ad cd  9f e3 c6 dc b8 ea 20 7c  |u............. ||
+00000040  94 1b 9c 73 bd 2e af f1  4d 97 6d eb cc a8 00 00  |...s....M.m.....|
 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 59  |.....proto1....Y|
 00000070  0b 00 02 55 00 02 52 00  02 4f 30 82 02 4b 30 82  |...U..R..O0..K0.|
@@ -56,31 +57,31 @@
 000002a0  1c f1 0f a1 d8 40 83 61  c9 4c 72 2b 9d ae db 46  |.....@.a.Lr+...F|
 000002b0  06 06 4d f4 c1 b3 3e c0  d1 bd 42 d4 db fe 3d 13  |..M...>...B...=.|
 000002c0  60 84 5c 21 d3 3b e9 fa  e7 16 03 03 00 ac 0c 00  |`.\!.;..........|
-000002d0  00 a8 03 00 1d 20 84 de  31 92 b6 a5 d8 a4 88 a2  |..... ..1.......|
-000002e0  54 67 e6 61 40 f2 5a 87  0f ce 15 b1 d6 af f3 5d  |Tg.a@.Z........]|
-000002f0  99 71 d6 04 f5 52 04 01  00 80 a8 1d 8b 8c e9 a3  |.q...R..........|
-00000300  af 2d 31 e4 0f f0 26 74  c2 e5 1b ae ac 47 9c 6e  |.-1...&t.....G.n|
-00000310  6c 5f 45 7d b1 b3 2a af  36 68 42 13 95 0d 33 1c  |l_E}..*.6hB...3.|
-00000320  8d 6c 72 48 4a 94 f0 fb  82 20 cc 76 21 7f 62 e7  |.lrHJ.... .v!.b.|
-00000330  23 a3 c8 4e 3a ce f1 5c  c3 60 73 26 59 4c 94 f3  |#..N:..\.`s&YL..|
-00000340  07 36 f6 a0 b3 60 03 d5  72 1e bf c8 d9 1d 61 01  |.6...`..r.....a.|
-00000350  9a 18 57 a3 b4 de 36 1f  e1 7d dc 69 c0 fb c0 71  |..W...6..}.i...q|
-00000360  45 1f 73 0d 50 69 d3 18  97 23 60 1c 5a 9a 93 b4  |E.s.Pi...#`.Z...|
-00000370  67 cc e5 80 3b 25 d0 6c  50 c8 16 03 03 00 04 0e  |g...;%.lP.......|
+000002d0  00 a8 03 00 1d 20 4c d6  65 c1 74 2c 78 ab 45 87  |..... L.e.t,x.E.|
+000002e0  bc 6e 9a cd 6c d4 2f 1e  ed 1b ed 68 e0 20 3b 13  |.n..l./....h. ;.|
+000002f0  7b b9 45 a1 38 78 04 01  00 80 31 26 2b b6 f8 fe  |{.E.8x....1&+...|
+00000300  bf 3c c6 8e ec 30 87 09  18 87 27 ec 9f 4f 93 74  |.<...0....'..O.t|
+00000310  6b 65 94 12 3e 4d 5e a8  f7 0f ec 9e 60 c5 d5 a0  |ke..>M^.....`...|
+00000320  c1 53 10 1d 8a 5b 82 2e  64 07 59 2e 0c b8 e3 90  |.S...[..d.Y.....|
+00000330  20 a5 0a 88 3e 7e d6 b9  85 58 78 f1 58 56 a6 d8  | ...>~...Xx.XV..|
+00000340  ee 60 52 59 d1 5b 16 58  de ce bc 09 79 99 65 e0  |.`RY.[.X....y.e.|
+00000350  6b 0b 4e 3d fb 80 35 6b  56 48 33 b3 17 4e 61 cf  |k.N=..5kVH3..Na.|
+00000360  88 78 41 14 c8 fa 41 32  f9 2b 87 27 40 d7 2b 51  |.xA...A2.+.'@.+Q|
+00000370  bd 16 54 cd f3 79 3a 7d  c9 f0 16 03 03 00 04 0e  |..T..y:}........|
 00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 5c c5 3e  7a 14 97 1b 55 88 25 08  |.... \.>z...U.%.|
-00000040  ad 86 48 ac f0 43 8c 17  5b 58 93 6c 7a 95 69 a8  |..H..C..[X.lz.i.|
-00000050  ad 0c b3 61 4d                                    |...aM|
+00000030  16 03 03 00 20 40 b0 f2  80 ce 38 b3 98 fd 34 ba  |.... @....8...4.|
+00000040  84 d3 f7 30 dc 9f 09 4b  0e 44 0b 79 b1 28 39 53  |...0...K.D.y.(9S|
+00000050  94 03 db c8 2b                                    |....+|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 dd 1b 80 da d9  |.......... .....|
-00000010  73 da 7d 15 9b 92 82 01  a7 8f fe 4a 75 97 8f f4  |s.}........Ju...|
-00000020  64 1b bf cf c3 40 78 f2  52 f5 7a                 |d....@x.R.z|
+00000000  14 03 03 00 01 01 16 03  03 00 20 6f 6c ec 1a 29  |.......... ol..)|
+00000010  d8 29 6c 10 67 12 4f 45  d3 64 85 e4 bc 28 5b 52  |.)l.g.OE.d...([R|
+00000020  d0 46 45 3c ac bc fa 51  c1 00 84                 |.FE<...Q...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 4e fa 7c  37 80 48 19 a6 03 25 7c  |.....N.|7.H...%||
-00000010  65 56 43 af 9a e8 e2 aa  e5 79 98 15 03 03 00 12  |eVC......y......|
-00000020  f9 b7 01 e8 2e 85 33 89  60 44 84 93 26 4c ec ac  |......3.`D..&L..|
-00000030  2e 6f                                             |.o|
+00000000  17 03 03 00 16 7d 3e 49  f0 a6 61 18 fc 10 f4 7f  |.....}>I..a.....|
+00000010  e2 df b7 58 7d ad 31 84  de 60 e0 15 03 03 00 12  |...X}.1..`......|
+00000020  08 cd 3f b6 58 d8 72 12  e0 f5 c6 8f f7 76 d5 29  |..?.X.r......v.)|
+00000030  4f b2                                             |O.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
index 336e10d..6fc1b1b 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 cf 28 2c 3e 4f  |....Y...U...(,>O|
-00000010  da 6b ae 24 74 a9 91 c3  c5 55 4b ab ec 07 f8 cd  |.k.$t....UK.....|
-00000020  65 f8 fe 08 f6 9a 23 da  99 6c 5d 20 af 4a 1e 32  |e.....#..l] .J.2|
-00000030  7b bd 3c 0b b1 14 66 a3  b7 2f a4 2a c3 43 c4 e0  |{.<...f../.*.C..|
-00000040  c2 ad 78 b1 28 ab 51 06  1b 87 d2 75 c0 09 00 00  |..x.(.Q....u....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 3d c4 44 53 fd  |....Y...U..=.DS.|
+00000010  1d ce 32 ba 0a ba 77 43  7a ba d1 e1 5b 7d 78 d4  |..2...wCz...[}x.|
+00000020  d3 29 5f e2 2b ab a1 e0  20 70 bd 20 4c 6b 28 a6  |.)_.+... p. Lk(.|
+00000030  f0 d0 51 92 3d ed 65 5c  bd 26 8f 81 93 14 b0 93  |..Q.=.e\.&......|
+00000040  80 af ae f6 3c 59 1f 1c  65 45 f0 13 c0 09 00 00  |....<Y..eE......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,18 +49,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 18 6f  |*............ .o|
-00000280  77 a5 2b 27 2c 52 fc 6c  8a 34 41 1c a8 c6 4f 90  |w.+',R.l.4A...O.|
-00000290  a9 4b b7 e0 39 8b b1 f5  a6 15 4b 94 e8 2c 04 03  |.K..9.....K..,..|
-000002a0  00 8b 30 81 88 02 42 00  dc 3a 14 a2 38 32 c1 40  |..0...B..:..82.@|
-000002b0  98 83 17 94 e9 2a 0d 95  c3 59 d6 76 94 c2 3e a0  |.....*...Y.v..>.|
-000002c0  f7 e0 5d 64 47 5a d1 d9  ed d2 1c 6b 13 3e e7 83  |..]dGZ.....k.>..|
-000002d0  6e bb 53 33 03 7d 69 c6  8f 9d 98 d7 96 9c 73 e3  |n.S3.}i.......s.|
-000002e0  12 bd 69 1f b1 d3 f4 25  d7 02 42 01 11 6d c8 53  |..i....%..B..m.S|
-000002f0  9b bf f4 db ff 8a 00 82  93 f7 b5 bf c9 bb cd ec  |................|
-00000300  64 f8 d9 6d 36 0d f8 db  ce 9d 65 a0 5e 5a e0 13  |d..m6.....e.^Z..|
-00000310  ec 08 73 2c 3f 8c c6 5b  08 cc 0f 4a 7d 6b 5e 89  |..s,?..[...J}k^.|
-00000320  bf 4a 4e db 51 5a 9f 51  3e 9d 9a c5 84 16 03 03  |.JN.QZ.Q>.......|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 b4 47  |*............ .G|
+00000280  68 85 aa c9 1b 4f ac c6  c6 08 39 e2 91 a8 0f a7  |h....O....9.....|
+00000290  26 d0 60 1a 68 62 7d 22  61 d2 66 1f 42 71 04 03  |&.`.hb}"a.f.Bq..|
+000002a0  00 8b 30 81 88 02 42 00  86 22 15 eb 04 d8 98 69  |..0...B..".....i|
+000002b0  71 75 c9 d7 17 61 d2 dc  a7 2f 21 22 fd b9 da 6e  |qu...a.../!"...n|
+000002c0  b2 36 65 22 1a 20 c8 49  3e a6 2a e4 4e a1 93 8d  |.6e". .I>.*.N...|
+000002d0  47 59 42 4f 54 51 3f dd  fc b9 b0 b4 fe d2 77 28  |GYBOTQ?.......w(|
+000002e0  15 58 4f b5 f5 56 da b2  02 02 42 00 cb 0b 69 b7  |.XO..V....B...i.|
+000002f0  1b 48 85 7e e3 bf be 27  64 c7 38 4d dc a1 49 73  |.H.~...'d.8M..Is|
+00000300  ba f9 45 6b cc 95 d1 72  d8 45 9c 39 3d 3a 93 85  |..Ek...r.E.9=:..|
+00000310  a7 22 20 c3 ce 48 e3 0d  31 9c f4 cf 2c dc d7 9d  |." ..H..1...,...|
+00000320  d3 b4 6a fe 98 31 d9 32  dc 37 1a c0 fa 16 03 03  |..j..1.2.7......|
 00000330  00 2a 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.*...&...@......|
 00000340  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000350  03 02 03 03 02 01 02 02  02 03 00 00 16 03 03 00  |................|
@@ -101,32 +101,32 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 93 0f 00  |...._X.;t.......|
-00000240  00 8f 05 03 00 8b 30 81  88 02 42 01 32 6d 32 38  |......0...B.2m28|
-00000250  d6 bd 1b b6 c5 80 f2 ea  60 b8 bf 3f b6 76 68 1b  |........`..?.vh.|
-00000260  66 fb 5d 69 0b 25 09 7f  2d 73 ad 7e cd 98 cb b5  |f.]i.%..-s.~....|
-00000270  93 4e 4f 1c 4e 3f a1 39  cf a0 70 a6 3d 29 36 27  |.NO.N?.9..p.=)6'|
-00000280  51 e0 55 95 11 df 00 88  6c 38 d6 de 36 02 42 01  |Q.U.....l8..6.B.|
-00000290  67 50 81 90 a7 ae b5 e2  34 75 81 41 c2 71 8d 0c  |gP......4u.A.q..|
-000002a0  9a 20 e7 33 af 0e 61 48  85 51 a1 f7 90 17 d1 ad  |. .3..aH.Q......|
-000002b0  b3 e1 cf 3e 12 fc ce 39  16 a8 78 3b 69 0d 79 76  |...>...9..x;i.yv|
-000002c0  03 17 75 c2 a0 63 5e dc  0a a7 c9 aa 15 2a 83 65  |..u..c^......*.e|
-000002d0  df 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |...........@....|
-000002e0  00 00 00 00 00 00 00 00  00 00 00 00 27 da 48 f6  |............'.H.|
-000002f0  d3 00 98 b9 a6 b7 41 0b  eb e6 d1 d7 82 9a 0c 59  |......A........Y|
-00000300  8a 42 1c 99 59 af da a7  5b 88 ab b6 7d 01 bc 0f  |.B..Y...[...}...|
-00000310  45 08 c4 05 0d 2a 4a 83  bf eb b1 b6              |E....*J.....|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 92 0f 00  |...._X.;t.......|
+00000240  00 8e 06 03 00 8a 30 81  87 02 42 00 cb 61 7d bc  |......0...B..a}.|
+00000250  af 48 88 32 98 9b 34 a0  71 0e 3a 33 bd da 73 16  |.H.2..4.q.:3..s.|
+00000260  05 f4 8e d8 30 11 c8 da  dd 7a 84 80 57 a1 76 d8  |....0....z..W.v.|
+00000270  af 3d 90 d7 e2 44 85 78  c4 12 ed 8d dc 4e 82 08  |.=...D.x.....N..|
+00000280  51 20 59 d7 38 26 29 c9  2b 5b 77 fc d2 02 41 3b  |Q Y.8&).+[w...A;|
+00000290  70 99 7c 46 bf 8e 85 40  d7 75 c5 43 36 f8 e3 30  |p.|F...@.u.C6..0|
+000002a0  28 ac 20 1e 79 43 b2 f3  6d b1 ae 6e cf 41 b5 ed  |(. .yC..m..n.A..|
+000002b0  76 2b d5 17 78 2c fa 91  75 ba 63 8f e9 1c c8 c0  |v+..x,..u.c.....|
+000002c0  1e 02 63 70 53 41 e0 98  77 a5 ae 54 6a 74 c0 91  |..cpSA..w..Tjt..|
+000002d0  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
+000002e0  00 00 00 00 00 00 00 00  00 00 00 7d 12 bc ba f4  |...........}....|
+000002f0  34 59 b7 c2 a9 5d 11 88  38 cc bc cc 1c 14 b7 5a  |4Y...]..8......Z|
+00000300  ae d8 0a 45 bc 61 b5 bc  d6 8e c4 69 80 10 7a ea  |...E.a.....i..z.|
+00000310  07 f4 dc 1a c9 dc b8 90  66 6c bc                 |........fl.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 73 7c e6 43 b9  |..........@s|.C.|
-00000010  47 85 1c 50 f1 cb a1 29  79 02 dd 13 85 2a d9 a2  |G..P...)y....*..|
-00000020  07 50 e4 80 c4 7e 66 ee  f2 1a 21 1d cd e4 ff 4a  |.P...~f...!....J|
-00000030  a4 61 9d b4 a1 26 88 72  20 2b 06 77 c3 8b 3b 21  |.a...&.r +.w..;!|
-00000040  53 33 02 3d a2 06 77 3b  a5 a6 0b                 |S3.=..w;...|
+00000000  14 03 03 00 01 01 16 03  03 00 40 df ff fd 43 0b  |..........@...C.|
+00000010  d1 28 4b db ce 29 8b 01  56 e7 44 9d 69 92 e7 11  |.(K..)..V.D.i...|
+00000020  7c 57 f2 a1 cf 35 d4 3a  8f 90 69 ce 80 4e 8b 6c  ||W...5.:..i..N.l|
+00000030  e9 eb 90 65 0e 89 49 20  41 ae 32 62 66 f4 aa 85  |...e..I A.2bf...|
+00000040  cd ca f7 a2 37 8f ef 22  ab b6 7b                 |....7.."..{|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 1a 45 68  03 9b f0 42 e4 21 5e d8  |......Eh...B.!^.|
-00000020  98 d6 46 67 2b 93 80 92  1f 91 60 a3 05 04 1c a0  |..Fg+.....`.....|
-00000030  1b a9 ce 45 03 15 03 03  00 30 00 00 00 00 00 00  |...E.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 6b 23 42 c8 5c 29  |..........k#B.\)|
-00000050  f5 1f 7c d5 80 c4 9f 6f  12 77 95 71 8f 82 f9 63  |..|....o.w.q...c|
-00000060  07 2c 6d ed 6d c6 4f 90  50 a3                    |.,m.m.O.P.|
+00000010  00 00 00 00 00 76 a4 88  f6 fb 0a 0f 8d a6 1f e0  |.....v..........|
+00000020  96 4d d0 93 30 c9 b6 27  1e 3c 87 d7 98 f9 d6 e9  |.M..0..'.<......|
+00000030  96 f7 e0 af b6 15 03 03  00 30 00 00 00 00 00 00  |.........0......|
+00000040  00 00 00 00 00 00 00 00  00 00 82 01 3b 93 6f 78  |............;.ox|
+00000050  1b e8 b6 ed 45 11 85 26  0f 40 63 2a a6 c9 f8 7b  |....E..&.@c*...{|
+00000060  7f 01 42 6b c1 8b 4f c0  a6 b5                    |..Bk..O...|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
index fb6c940..47c083e 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 2e d2 1c 3f f8  |....Y...U.....?.|
-00000010  3a dc be 78 0b fa 03 00  e0 9a b9 62 34 45 f8 34  |:..x.......b4E.4|
-00000020  54 21 4c c0 76 a6 e1 5a  a1 67 c2 20 1b 98 25 34  |T!L.v..Z.g. ..%4|
-00000030  79 ac 59 b5 39 c8 93 10  a9 ea 9d 25 3d 2c d8 69  |y.Y.9......%=,.i|
-00000040  da d8 33 75 ef 44 4c 76  92 2b 3b b4 c0 2f 00 00  |..3u.DLv.+;../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 b1 01 db c2 3f  |....Y...U......?|
+00000010  11 0c d0 d2 fd 1d 5f 54  f6 62 4a 47 f9 62 e6 88  |......_T.bJG.b..|
+00000020  72 d7 f5 91 78 73 99 94  72 26 ed 20 51 91 b2 bf  |r...xs..r&. Q...|
+00000030  78 94 0c 1f bb 7b ff a2  b6 8f 57 5d 03 f2 97 b8  |x....{....W]....|
+00000040  c2 20 99 cd 48 f3 14 fc  63 38 97 44 c0 2f 00 00  |. ..H...c8.D./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,17 +54,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 06 be 1b 0b d8 95 59  |........ ......Y|
-000002d0  b2 13 1c 4a 06 b8 36 3e  4f 98 3f 81 11 3e 7d 21  |...J..6>O.?..>}!|
-000002e0  fa d9 f0 db 1b 41 4a d0  14 04 01 00 80 ca 57 f5  |.....AJ.......W.|
-000002f0  e7 b6 72 7e 3f b0 67 f2  a2 d0 84 d5 7f 7d 83 ff  |..r~?.g......}..|
-00000300  92 73 4f 19 f7 94 b6 d7  95 f4 1b 56 2a fc fa 24  |.sO........V*..$|
-00000310  3e fe 00 65 52 76 c8 30  8a bf ae fe b5 c9 f2 47  |>..eRv.0.......G|
-00000320  0a 71 ad c1 6a 61 8c b5  ab 59 09 12 92 b2 b4 ad  |.q..ja...Y......|
-00000330  cb cc ac c4 30 e9 a4 8a  82 4e 2e d6 1d 16 46 dd  |....0....N....F.|
-00000340  60 37 50 b8 ae 83 c1 e6  1d ba 8c c7 18 f7 5e d7  |`7P...........^.|
-00000350  23 e5 8a 14 ba e4 8e a1  77 8a b6 41 03 61 8a 25  |#.......w..A.a.%|
-00000360  8a 27 f8 cb 2e 4a e0 07  aa bf 03 32 98 16 03 03  |.'...J.....2....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 22 78 15 4f d2 33 df  |........ "x.O.3.|
+000002d0  3e 82 b7 10 ca 8b 5c d6  f2 84 8f e7 cb cf 3e 2f  |>.....\.......>/|
+000002e0  65 dd 5b 5c 0a 48 f4 f6  1e 04 01 00 80 40 08 09  |e.[\.H.......@..|
+000002f0  e5 bc a2 e3 27 a9 7e 2d  e2 1d 47 7c 8c 95 44 28  |....'.~-..G|..D(|
+00000300  f8 3d 00 5d f7 38 26 31  8f f3 61 27 f6 c0 a0 12  |.=.].8&1..a'....|
+00000310  ed 3b 59 18 ed aa 4c 4a  54 8a 23 0a 13 7a 7d 1c  |.;Y...LJT.#..z}.|
+00000320  26 5e 7a f1 55 d5 68 dc  f9 97 ef 6d 98 0f 87 41  |&^z.U.h....m...A|
+00000330  31 e5 a0 f1 84 19 3a 19  cf b3 f7 9d 34 13 05 ab  |1.....:.....4...|
+00000340  85 2e 6f 4e 8f fd c3 37  63 3e c9 3d 48 87 6a 9b  |..oN...7c>.=H.j.|
+00000350  c1 21 d1 4f 89 7d a1 dc  23 bb cf d8 b1 d9 91 e0  |.!.O.}..#.......|
+00000360  f6 48 f0 20 64 8b f8 f1  86 5c b3 6c 70 16 03 03  |.H. d....\.lp...|
 00000370  00 2a 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.*...&...@......|
 00000380  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000390  03 02 03 03 02 01 02 02  02 03 00 00 16 03 03 00  |................|
@@ -105,28 +105,28 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 92 0f 00  |...._X.;t.......|
-00000240  00 8e 05 03 00 8a 30 81  87 02 41 19 c6 1e f0 f4  |......0...A.....|
-00000250  ca 79 d7 8c 36 0f 56 9a  9d 07 55 31 fe 63 f1 ec  |.y..6.V...U1.c..|
-00000260  20 80 6f 12 ed 7f bb c0  87 0a 0d 68 81 89 bd 8b  | .o........h....|
-00000270  19 04 5e c0 19 8a d2 0f  6d 71 83 59 ee a7 be be  |..^.....mq.Y....|
-00000280  1d bb 2f 12 53 9b ca 58  0e a6 8d ae 02 42 00 d0  |../.S..X.....B..|
-00000290  4c 69 75 30 86 d1 da 73  1b 8e 3e e1 82 9b f3 58  |Liu0...s..>....X|
-000002a0  8f 6d 0a 10 86 72 5f 90  17 d1 ac 34 8a b5 60 d0  |.m...r_....4..`.|
-000002b0  b8 54 0f 05 7f cd 6a c0  62 b5 04 d9 3a 98 95 b6  |.T....j.b...:...|
-000002c0  b3 00 1d 94 6e 79 35 57  d2 78 a4 7a 4a 45 89 d1  |....ny5W.x.zJE..|
-000002d0  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-000002e0  00 00 00 cf b5 3c cf 0a  b7 6b 51 cb fe 06 4c df  |.....<...kQ...L.|
-000002f0  2c 79 a6 5e a8 75 8b 4c  44 7b ae ff 64 d7 67 dc  |,y.^.u.LD{..d.g.|
-00000300  af ef 54                                          |..T|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 93 0f 00  |...._X.;t.......|
+00000240  00 8f 06 03 00 8b 30 81  88 02 42 01 9e be 18 6a  |......0...B....j|
+00000250  b3 8d c4 2f b9 ed db b9  89 cf 2f e5 d6 13 64 68  |.../....../...dh|
+00000260  72 e4 51 01 12 a9 83 08  d7 2e fa cc 64 09 80 79  |r.Q.........d..y|
+00000270  ce 3d 51 a1 e1 f7 3c 5c  2c dd 97 a2 f9 61 c3 7a  |.=Q...<\,....a.z|
+00000280  bc 25 ad c1 04 a1 cf bf  06 f5 e2 b5 15 02 42 00  |.%............B.|
+00000290  bf 72 20 6f 0e 49 f2 07  bd 07 ef f3 e8 9c 1a 61  |.r o.I.........a|
+000002a0  b0 7a 6c b0 14 71 4a aa  76 05 9f d1 ef 5b 41 be  |.zl..qJ.v....[A.|
+000002b0  4c 20 7b 5c 31 86 da e3  3b 54 0f af 79 6b 54 84  |L {\1...;T..ykT.|
+000002c0  72 0b 0a e4 ea 33 48 a2  1a e8 8d dd 16 45 80 d1  |r....3H......E..|
+000002d0  88 14 03 03 00 01 01 16  03 03 00 28 00 00 00 00  |...........(....|
+000002e0  00 00 00 00 4d 58 00 50  6d 12 ea c2 6c f8 1c 51  |....MX.Pm...l..Q|
+000002f0  e8 91 8c 24 dd c2 28 af  c7 c7 ed 28 29 34 62 2c  |...$..(....()4b,|
+00000300  c0 d3 06 7d                                       |...}|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 1c 12 5e 29 ba  |..........(..^).|
-00000010  34 b3 d8 ae f7 2a 83 0d  3e 21 ec 91 c9 fa 7f d1  |4....*..>!......|
-00000020  42 7e 8d d9 e5 ed 4e f9  ae 95 66 27 85 cc 44 2d  |B~....N...f'..D-|
-00000030  cd a3 26                                          |..&|
+00000000  14 03 03 00 01 01 16 03  03 00 28 b3 71 11 c5 31  |..........(.q..1|
+00000010  7b 22 87 23 7b 71 05 ca  95 fc d1 7d 0e fd 68 d3  |{".#{q.....}..h.|
+00000020  7f 08 af 41 16 ff cf 87  a4 5a 6b fb b1 5e 89 e0  |...A.....Zk..^..|
+00000030  8e 0c 88                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 8b 4c 36  |..............L6|
-00000010  6f b8 69 16 0a 40 67 05  5e a8 e6 48 cc ad 7b 29  |o.i..@g.^..H..{)|
-00000020  95 3d 02 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.=..............|
-00000030  58 e3 b5 8e 30 e7 5d 02  cd e5 c0 11 95 3a ef a9  |X...0.]......:..|
-00000040  d7 86                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 3b 83 10  |.............;..|
+00000010  ee 6d c5 a9 6a 9e 61 7f  df 00 c4 03 39 6a b8 4a  |.m..j.a.....9j.J|
+00000020  0f 0c e6 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  35 b9 7d a7 29 d0 ba e1  5e 4e f1 67 4a 81 12 e7  |5.}.)...^N.gJ...|
+00000040  62 72                                             |br|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
index 17fc8f8..892db8a 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 31 df 35 e4 36  |....Y...U..1.5.6|
-00000010  c5 f1 b4 9f e7 5d fa e1  e0 23 04 54 bd 2b fb ab  |.....]...#.T.+..|
-00000020  a2 37 8f 35 eb 79 47 e6  f8 2b cb 20 ba d8 db 26  |.7.5.yG..+. ...&|
-00000030  ce 6b 4a e9 1e 0c 46 9f  4d 85 cb d7 b0 e2 3d 20  |.kJ...F.M.....= |
-00000040  58 43 83 37 e1 53 ac 3b  d9 b3 fd 0a c0 30 00 00  |XC.7.S.;.....0..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 76 09 a7 74 97  |....Y...U..v..t.|
+00000010  df 92 1b 14 fb 0f 5c 82  a9 04 22 5f 32 1f 04 50  |......\..."_2..P|
+00000020  52 8c ec 30 c1 5e 73 51  8a 0d 22 20 12 f5 11 b3  |R..0.^sQ.." ....|
+00000030  3b 8e 49 9a 0b 79 3e 0a  a8 7f a8 01 eb b0 ea 4e  |;.I..y>........N|
+00000040  d5 19 0d 4e c5 7d d7 a0  ff 6e 75 a1 c0 30 00 00  |...N.}...nu..0..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,17 +54,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 9a 18 f9 2e 33 f7 bb  |........ ....3..|
-000002d0  ca 60 0b 51 ad 5c 01 e2  61 82 0b 3f 09 8f 78 9d  |.`.Q.\..a..?..x.|
-000002e0  3b 11 8b e0 4a 35 2e d5  54 04 01 00 80 90 94 0e  |;...J5..T.......|
-000002f0  bf 3a b7 95 d3 58 cc 65  c3 79 5e 1e bb d9 21 56  |.:...X.e.y^...!V|
-00000300  06 93 6c 2b 6e 26 55 ee  26 c3 02 44 7e db 35 9b  |..l+n&U.&..D~.5.|
-00000310  d4 d4 1a a0 65 35 41 a4  6c ce de 1f 94 ff b4 1b  |....e5A.l.......|
-00000320  1e 9c 28 0b 4c 8d 55 d0  d8 be f1 df e0 d1 1a b5  |..(.L.U.........|
-00000330  c8 be 2c 5a 2c c3 3f ea  4f e6 d5 b4 6b e1 ff eb  |..,Z,.?.O...k...|
-00000340  f3 f3 40 54 d5 62 1f a0  fc b2 34 66 ee c5 27 a6  |..@T.b....4f..'.|
-00000350  2b 2a b9 5d 3f 36 28 eb  39 99 25 e5 04 d2 18 13  |+*.]?6(.9.%.....|
-00000360  3c 23 93 d0 04 37 85 b0  4d 6e 9b 32 9a 16 03 03  |<#...7..Mn.2....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 24 0d ab 23 1c 61 5d  |........ $..#.a]|
+000002d0  26 01 04 dd ea 32 2d e4  a1 95 28 fc a7 17 93 6f  |&....2-...(....o|
+000002e0  ce b8 ef 0a 74 cf 28 ca  33 04 01 00 80 1e e1 03  |....t.(.3.......|
+000002f0  e6 a7 bd 38 7b 32 52 01  47 b3 fa 0a 8f 29 2c 98  |...8{2R.G....),.|
+00000300  58 37 21 3d 9e 78 48 dc  74 a9 ec d2 9a cb 56 8e  |X7!=.xH.t.....V.|
+00000310  4a 90 d6 b6 87 82 03 b8  60 04 bf 73 b2 61 e6 ab  |J.......`..s.a..|
+00000320  7d cd eb ba cf e8 16 86  db 38 7e 96 6b 14 c4 4f  |}........8~.k..O|
+00000330  05 fb 2b b5 6e 50 9a f5  02 f3 a2 84 95 8d a6 91  |..+.nP..........|
+00000340  d2 16 33 98 16 c0 61 55  fe a8 70 02 d1 db 86 d1  |..3...aU..p.....|
+00000350  37 0c 02 36 cf b2 10 6d  63 94 f6 18 29 a7 6b 1b  |7..6...mc...).k.|
+00000360  8f 7c 51 8e 8f e4 ef a8  2b 99 0b ae 1b 16 03 03  |.|Q.....+.......|
 00000370  00 2a 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.*...&...@......|
 00000380  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000390  03 02 03 03 02 01 02 02  02 03 00 00 16 03 03 00  |................|
@@ -105,26 +105,26 @@
 00000200  e5 35 16 03 03 00 25 10  00 00 21 20 2f e5 7d a3  |.5....%...! /.}.|
 00000210  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
 00000220  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 16 03 03 00  |......._X.;t....|
-00000230  88 0f 00 00 84 05 01 00  80 ad f7 ff a0 cb d0 6e  |...............n|
-00000240  8f 19 0c 40 2a 1f bb dd  11 52 81 84 f1 7b 3f cf  |...@*....R...{?.|
-00000250  75 72 83 a4 4c 0a 9c 70  95 98 d5 51 a2 28 0c 8c  |ur..L..p...Q.(..|
-00000260  20 08 d7 2a a5 3e 0c cf  6c a2 1d 32 bd cc a1 b4  | ..*.>..l..2....|
-00000270  61 e0 6d 9a 61 16 03 5c  7a b8 fa 15 ea cd e4 de  |a.m.a..\z.......|
-00000280  d6 16 93 b2 e0 d2 55 b9  03 e0 67 04 27 64 8c e2  |......U...g.'d..|
-00000290  01 ee 8f f7 59 3e 12 16  51 f2 07 20 fe 03 e2 3e  |....Y>..Q.. ...>|
-000002a0  09 1f 96 24 c5 73 0e 69  ac 57 ff 43 2b 6a c6 20  |...$.s.i.W.C+j. |
-000002b0  2f e4 ef 7e bc b3 38 57  06 14 03 03 00 01 01 16  |/..~..8W........|
-000002c0  03 03 00 28 00 00 00 00  00 00 00 00 fd 71 f5 ca  |...(.........q..|
-000002d0  91 26 67 54 a5 e6 f3 06  c8 40 24 9d a9 bd b1 9a  |.&gT.....@$.....|
-000002e0  63 c4 c2 53 56 ba af c0  16 bc 06 5c              |c..SV......\|
+00000230  88 0f 00 00 84 06 01 00  80 9f 32 29 c2 47 12 3b  |..........2).G.;|
+00000240  c1 2a f5 02 2b be 51 88  68 ed d6 f6 06 72 b8 02  |.*..+.Q.h....r..|
+00000250  32 5f f6 c6 a0 72 d1 df  d4 01 8c f7 37 ca 3a 8f  |2_...r......7.:.|
+00000260  cb ee d8 1d 7b 8a 80 0b  21 30 14 55 32 19 ba 8e  |....{...!0.U2...|
+00000270  a0 6a 0a 8b 53 01 71 09  d2 1c 19 b2 50 4f a4 35  |.j..S.q.....PO.5|
+00000280  4d 22 71 74 62 fb 24 8d  d1 b2 0e d7 60 ae 9e a9  |M"qtb.$.....`...|
+00000290  07 60 84 99 da c9 a4 04  09 35 da c3 98 4e ab fe  |.`.......5...N..|
+000002a0  41 68 f2 0c 8a 94 b3 26  af 2c 19 52 48 08 8d 00  |Ah.....&.,.RH...|
+000002b0  05 69 d8 9f 35 b5 9e 00  2e 14 03 03 00 01 01 16  |.i..5...........|
+000002c0  03 03 00 28 00 00 00 00  00 00 00 00 bf fd 71 87  |...(..........q.|
+000002d0  c2 8c 1e 69 59 95 8a 75  da 56 7e db e6 5c fd 6c  |...iY..u.V~..\.l|
+000002e0  74 97 46 66 37 23 3f 39  91 23 c0 d1              |t.Ff7#?9.#..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 92 8f bd c5 97  |..........(.....|
-00000010  94 76 70 f4 0a f9 9a 79  69 31 27 0e c0 c5 0b 3c  |.vp....yi1'....<|
-00000020  9f 4f c2 2f cb 6c 56 62  80 3b e5 72 6a 05 9e 4b  |.O./.lVb.;.rj..K|
-00000030  34 b9 66                                          |4.f|
+00000000  14 03 03 00 01 01 16 03  03 00 28 16 d9 d6 d4 2f  |..........(..../|
+00000010  8c 6f 50 8d e6 6f ea eb  6a 55 6a 12 10 d2 dc aa  |.oP..o..jUj.....|
+00000020  83 7a 38 6a bc 10 aa da  62 ab 94 7b ac f2 03 1a  |.z8j....b..{....|
+00000030  2f 95 6d                                          |/.m|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 43 fb 43  |.............C.C|
-00000010  3d 96 63 dd 25 94 9d 7a  fb 9e 15 6f 62 5e ed 34  |=.c.%..z...ob^.4|
-00000020  19 89 b8 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  53 c2 2d 6c b7 91 6c 62  84 09 a2 1c 9b 3d 9e 89  |S.-l..lb.....=..|
-00000040  6a 3d                                             |j=|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 36 84 d7  |.............6..|
+00000010  5c ef b0 3e 11 86 a9 a1  2c 0c 05 2f fa 86 3b dc  |\..>....,../..;.|
+00000020  fb 8c 94 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  86 fb 4d dd 33 11 53 9c  c2 9f e6 48 79 19 69 f3  |..M.3.S....Hy.i.|
+00000040  db 3b                                             |.;|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
index 1ff9198..9f717b1 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 84 4b ff a4 2a  |....Y...U...K..*|
-00000010  a4 76 c0 26 f6 05 72 94  01 15 44 f2 c6 7d b0 4b  |.v.&..r...D..}.K|
-00000020  1b fa da 51 54 45 78 66  e6 0a dd 20 17 df d2 0c  |...QTExf... ....|
-00000030  2f d6 55 b9 ae 82 ce 2f  2f 07 67 54 5e 02 bd 2f  |/.U....//.gT^../|
-00000040  48 f6 fb 3d 9c fa 4f a8  66 15 08 da c0 09 00 00  |H..=..O.f.......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 63 c7 66 ed 90  |....Y...U..c.f..|
+00000010  6f f2 a3 65 32 55 e2 00  ce 15 46 33 22 ad 1a 6f  |o..e2U....F3"..o|
+00000020  ac 21 89 0e b0 66 a8 04  98 f2 99 20 02 7c 4f 57  |.!...f..... .|OW|
+00000030  f4 69 17 6f 23 f5 a6 db  8f a6 ef eb 83 70 53 5d  |.i.o#........pS]|
+00000040  0e 85 b9 d7 53 01 10 9b  65 97 c0 c1 c0 09 00 00  |....S...e.......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,22 +49,22 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 5d 4e  |*............ ]N|
-00000280  0c 9e ad 7b f1 48 0c db  03 96 26 2e 16 87 2c e2  |...{.H....&...,.|
-00000290  ce a2 47 5a 57 30 e8 e1  7e b2 53 5b c6 7b 04 03  |..GZW0..~.S[.{..|
-000002a0  00 8b 30 81 88 02 42 00  e8 8e 68 a8 e3 b5 b4 fe  |..0...B...h.....|
-000002b0  b9 91 aa 4f 96 3d 97 8d  b2 ef 23 a4 3d 16 db 2b  |...O.=....#.=..+|
-000002c0  50 6d 52 cd a5 e7 79 ae  65 10 d6 36 e0 ba c3 6b  |PmR...y.e..6...k|
-000002d0  53 61 14 bb 05 47 5a df  26 2f cb 3a 95 c6 6b dc  |Sa...GZ.&/.:..k.|
-000002e0  88 fd 2e 22 b5 ef ff 31  0e 02 42 01 be ce 6e 53  |..."...1..B...nS|
-000002f0  42 43 1c 1c d8 83 7f 45  c4 16 ee d2 7b 66 a0 f4  |BC.....E....{f..|
-00000300  f3 14 da 5c 14 e8 fc bc  86 7d 18 43 b9 7b 90 8c  |...\.....}.C.{..|
-00000310  af f1 05 95 c6 53 0b 0b  0d 10 a1 e9 bb 89 35 c2  |.....S........5.|
-00000320  b2 e1 d7 dd 99 7c bf 85  19 3c 4e 8e 8f 16 03 03  |.....|...<N.....|
-00000330  00 2a 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.*...&...@......|
-00000340  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000350  03 02 03 03 02 01 02 02  02 03 00 00 16 03 03 00  |................|
-00000360  04 0e 00 00 00                                    |.....|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 e2 11  |*............ ..|
+00000280  47 88 ee 44 bb 63 68 cc  aa 2e ee 22 66 93 25 2b  |G..D.ch...."f.%+|
+00000290  19 c4 a1 0c 2f c0 a4 9e  bb f3 f1 4d de 18 04 03  |..../......M....|
+000002a0  00 8a 30 81 87 02 41 7b  fc 56 81 1e f9 fe 44 a7  |..0...A{.V....D.|
+000002b0  d3 b9 4e 4e 0b 5e d9 11  c1 11 c1 b5 94 60 1d e4  |..NN.^.......`..|
+000002c0  82 4b 6d 14 45 02 e3 06  d8 32 b4 c1 da 64 e4 92  |.Km.E....2...d..|
+000002d0  b7 52 a4 39 19 4e 21 53  03 4f 64 40 23 7a 75 db  |.R.9.N!S.Od@#zu.|
+000002e0  e1 67 a8 29 d4 90 56 af  02 42 01 2d c0 14 ed 33  |.g.)..V..B.-...3|
+000002f0  7e f9 7d d2 6b 4c ba 06  7d 41 e1 7c d1 82 51 03  |~.}.kL..}A.|..Q.|
+00000300  ea b1 66 e5 c5 27 34 b1  b4 36 8e 5d d0 69 f9 10  |..f..'4..6.].i..|
+00000310  cc 60 f2 f1 30 2a ff a7  09 4f 87 93 28 26 9d 8d  |.`..0*...O..(&..|
+00000320  75 a0 11 17 dd 6c e2 33  87 21 6d 0f 16 03 03 00  |u....l.3.!m.....|
+00000330  2a 0d 00 00 26 03 01 02  40 00 1e 06 01 06 02 06  |*...&...@.......|
+00000340  03 05 01 05 02 05 03 04  01 04 02 04 03 03 01 03  |................|
+00000350  02 03 03 02 01 02 02 02  03 00 00 16 03 03 00 04  |................|
+00000360  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fd 0b 00 01  f9 00 01 f6 00 01 f3 30  |...............0|
 00000010  82 01 ef 30 82 01 58 a0  03 02 01 02 02 10 5c 19  |...0..X.......\.|
@@ -101,31 +101,31 @@
 00000200  e5 35 16 03 03 00 25 10  00 00 21 20 2f e5 7d a3  |.5....%...! /.}.|
 00000210  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
 00000220  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 16 03 03 00  |......._X.;t....|
-00000230  88 0f 00 00 84 05 01 00  80 98 58 a8 77 3d db 0b  |..........X.w=..|
-00000240  04 36 78 51 8b 23 48 fc  70 2b c9 94 1f ee 32 ae  |.6xQ.#H.p+....2.|
-00000250  41 c0 42 20 19 51 67 e7  fa c0 fd 15 a1 5f 55 4f  |A.B .Qg......_UO|
-00000260  aa be 29 77 f5 47 71 b9  6c 51 89 18 df 25 98 fd  |..)w.Gq.lQ...%..|
-00000270  c8 6e ae e3 fd 99 63 ca  2c d2 fb ca bc 57 b7 7f  |.n....c.,....W..|
-00000280  a2 90 a6 6f b7 2e b7 2a  52 29 e6 75 57 86 cc b1  |...o...*R).uW...|
-00000290  d8 6c f3 4e 49 ab 4b 66  0a 72 aa ec c2 f7 6e 57  |.l.NI.Kf.r....nW|
-000002a0  15 26 79 1a a4 24 c2 ba  76 9e dd b9 f9 d4 da 1b  |.&y..$..v.......|
-000002b0  c9 29 66 eb 64 1b 68 66  66 14 03 03 00 01 01 16  |.)f.d.hff.......|
+00000230  88 0f 00 00 84 06 01 00  80 0a d6 0d 0a 0f 6b 18  |..............k.|
+00000240  f4 e3 3a b7 84 cd 56 53  ae 81 3f e8 50 a4 6a ab  |..:...VS..?.P.j.|
+00000250  4e f7 f5 8f e6 c5 6f e1  88 47 a9 ba 35 07 a3 5d  |N.....o..G..5..]|
+00000260  d0 e3 f3 b9 2a 33 33 1c  af d5 91 4b 92 3d da eb  |....*33....K.=..|
+00000270  96 3f 4c 0e ac 55 3e 32  8c 56 f9 3e 64 d1 51 03  |.?L..U>2.V.>d.Q.|
+00000280  a1 46 2a 47 0b d6 fd 0c  94 15 de 66 22 24 11 06  |.F*G.......f"$..|
+00000290  ed 17 ab f0 c5 5b 39 7d  f2 ce 02 3f 3a 16 b4 14  |.....[9}...?:...|
+000002a0  81 f7 4f 38 a9 46 ee 09  bf ed 14 b5 d8 3c d6 32  |..O8.F.......<.2|
+000002b0  26 48 6d 9d 49 70 12 a0  f3 14 03 03 00 01 01 16  |&Hm.Ip..........|
 000002c0  03 03 00 40 00 00 00 00  00 00 00 00 00 00 00 00  |...@............|
-000002d0  00 00 00 00 70 2b 69 27  05 9a 96 e6 e8 52 ea 0f  |....p+i'.....R..|
-000002e0  3a d6 40 b5 e2 89 5b bf  aa 95 6c c1 7d 53 09 89  |:.@...[...l.}S..|
-000002f0  23 38 6b 83 85 84 fa f4  2e fb cd b3 57 4e 79 8a  |#8k.........WNy.|
-00000300  92 74 03 22                                       |.t."|
+000002d0  00 00 00 00 d5 b2 cc f7  6b 74 c0 77 c3 05 7f 09  |........kt.w....|
+000002e0  28 54 fe 44 ef b1 4c 40  ff 47 00 59 ae 22 96 53  |(T.D..L@.G.Y.".S|
+000002f0  6d db b1 5b fd af 24 10  ca 0d f6 8b 24 7a c0 38  |m..[..$.....$z.8|
+00000300  d7 92 7c c2                                       |..|.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 8f 91 f1 f5 6b  |..........@....k|
-00000010  cc 52 9d db 35 1f db b4  64 fe 33 a5 83 08 24 2f  |.R..5...d.3...$/|
-00000020  57 18 0e 60 4e 18 54 bb  80 31 37 fe 26 14 b8 c8  |W..`N.T..17.&...|
-00000030  dd c4 8c 07 42 0b 80 0b  41 82 40 f6 9b b8 60 4f  |....B...A.@...`O|
-00000040  cb 7b 43 ea 1a 6e 31 8d  9f 82 f7                 |.{C..n1....|
+00000000  14 03 03 00 01 01 16 03  03 00 40 c3 48 00 56 17  |..........@.H.V.|
+00000010  16 d1 dd 17 a2 c7 48 c9  d6 3e 6a 1e 4c cc 0a a2  |......H..>j.L...|
+00000020  40 3e 31 2e 50 69 d6 06  15 48 87 45 2f f0 a1 04  |@>1.Pi...H.E/...|
+00000030  38 b2 81 15 b9 0d ac f4  9e 51 9f b0 9c 79 20 57  |8........Q...y W|
+00000040  ab 8a 56 08 97 2b d0 62  12 7d b3                 |..V..+.b.}.|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 70 e7 c8  03 9c e2 58 73 68 ab 9b  |.....p.....Xsh..|
-00000020  5c bf 32 57 f8 f1 13 97  02 59 de 99 d3 3e 16 3d  |\.2W.....Y...>.=|
-00000030  87 11 d4 b4 63 15 03 03  00 30 00 00 00 00 00 00  |....c....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 9b 99 45 f3 0d f1  |............E...|
-00000050  c5 36 07 8c 81 94 b7 0a  dc 7c ee 0c 22 1b 36 fd  |.6.......|..".6.|
-00000060  d4 fc 7d f1 98 8b 87 be  5f c6                    |..}....._.|
+00000010  00 00 00 00 00 27 df 11  a5 71 1a f9 c9 fb d3 a8  |.....'...q......|
+00000020  cd f1 5f 88 e4 db ca 2f  ec c7 26 e2 c9 69 11 c5  |.._..../..&..i..|
+00000030  a4 ba 6f 58 69 15 03 03  00 30 00 00 00 00 00 00  |..oXi....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 e8 9d f0 1d f8 4b  |...............K|
+00000050  fc d1 7e ac 10 b2 5d af  ea 87 b9 d8 4b 0d 24 d6  |..~...].....K.$.|
+00000060  ff 44 9f 93 bf 51 9d 21  9d 1d                    |.D...Q.!..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
index 76f0c25..656281c 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 92 93 45 4c f9  |....Y...U....EL.|
-00000010  93 bf ee 78 58 e0 42 b6  df 32 c2 63 6d ec 89 66  |...xX.B..2.cm..f|
-00000020  5a 11 7c 0d 31 2f b5 90  22 ab 3d 20 65 f3 40 c4  |Z.|.1/..".= e.@.|
-00000030  f8 31 fa 80 f3 fb a7 f6  9e dc 0c 94 67 48 d9 2b  |.1..........gH.+|
-00000040  cb 94 82 5f 4e 8b 41 5e  c6 63 27 da c0 2f 00 00  |..._N.A^.c'../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 cd 8e 54 03 73  |....Y...U....T.s|
+00000010  80 fb 7a 0a 38 a0 cd d3  5c 1a 84 a2 66 43 47 68  |..z.8...\...fCGh|
+00000020  7b d9 c0 5b c3 14 2f 51  45 12 62 20 9e 32 b0 17  |{..[../QE.b .2..|
+00000030  85 6e 8a de ae 7a f7 09  76 79 5f 74 eb b1 3c e9  |.n...z..vy_t..<.|
+00000040  4f 36 09 ef b2 f9 8f 25  c1 db 37 46 c0 2f 00 00  |O6.....%..7F./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,17 +54,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 66 49 44 2b 04 fe f5  |........ fID+...|
-000002d0  41 68 60 09 81 0e 24 c4  46 68 33 87 41 dd 48 69  |Ah`...$.Fh3.A.Hi|
-000002e0  4c be c8 22 2d 4e ff 80  20 04 01 00 80 30 85 40  |L.."-N.. ....0.@|
-000002f0  30 56 d5 1d 41 14 9d e8  27 39 a2 18 d5 eb 92 27  |0V..A...'9.....'|
-00000300  63 4b 05 85 1a 9e 5f 60  2c 80 a3 20 9f 9c 57 29  |cK...._`,.. ..W)|
-00000310  ba 5f ac 0a aa 89 98 fc  ca 8e 37 6b 44 bc 0f 33  |._........7kD..3|
-00000320  5d 47 91 46 55 d4 f9 4f  76 73 51 c4 f6 a9 90 e4  |]G.FU..OvsQ.....|
-00000330  95 10 92 94 f1 33 11 3d  83 0a eb 5d ff e6 9d 9c  |.....3.=...]....|
-00000340  19 ec e1 65 11 ad d7 7b  6a a4 f9 d8 b6 0c 53 8a  |...e...{j.....S.|
-00000350  16 d5 1f a7 0b 80 6f c5  d8 6a 57 11 2f b1 84 65  |......o..jW./..e|
-00000360  24 8a 02 de aa 10 40 bd  9b 68 a2 b7 b6 16 03 03  |$.....@..h......|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 57 b6 34 6b 1c 97 1f  |........ W.4k...|
+000002d0  51 f1 d5 38 68 a2 2f 69  fb 9e 94 cf 7e c3 25 97  |Q..8h./i....~.%.|
+000002e0  82 e9 32 c0 0e 99 0c 7c  50 04 01 00 80 2d 08 85  |..2....|P....-..|
+000002f0  c5 bc d6 3b 94 c5 7e 26  80 bc 0d 63 50 84 d0 77  |...;..~&...cP..w|
+00000300  f8 4b cd 2c d4 cb e0 f2  7c 63 dc 9e 42 4e 3f 3c  |.K.,....|c..BN?<|
+00000310  a3 b7 c7 41 e6 e9 2c da  ff 06 6d ec b5 f3 57 22  |...A..,...m...W"|
+00000320  3a 6b cc 6b 00 d0 53 6e  b1 89 7c 09 cc db 8e f1  |:k.k..Sn..|.....|
+00000330  00 32 d1 68 2f ae 7a 83  00 71 a8 81 e6 66 c2 e7  |.2.h/.z..q...f..|
+00000340  13 94 bf 9b 30 84 23 3d  95 03 11 4d 3a e7 4c 0a  |....0.#=...M:.L.|
+00000350  43 c7 6d 31 c1 92 b1 ab  7d 11 a1 2f 4a 2d bd fe  |C.m1....}../J-..|
+00000360  f5 d4 b1 ab ef 2d e3 79  ee 2f 6b 44 29 16 03 03  |.....-.y./kD)...|
 00000370  00 2a 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.*...&...@......|
 00000380  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000390  03 02 03 03 02 01 02 02  02 03 00 00 16 03 03 00  |................|
@@ -105,26 +105,26 @@
 00000200  e5 35 16 03 03 00 25 10  00 00 21 20 2f e5 7d a3  |.5....%...! /.}.|
 00000210  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
 00000220  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 16 03 03 00  |......._X.;t....|
-00000230  88 0f 00 00 84 05 01 00  80 05 9b 97 90 30 0b 21  |.............0.!|
-00000240  ed 52 16 19 e0 54 7d 59  42 17 94 81 9b 2c b6 5b  |.R...T}YB....,.[|
-00000250  7f 7c 8e a5 bf 27 a9 25  14 74 f0 37 fa 6e 2b 84  |.|...'.%.t.7.n+.|
-00000260  80 a4 cd ae a6 8a 1b 62  2d 5e 03 ff 70 55 d7 99  |.......b-^..pU..|
-00000270  68 3c b3 0e 03 41 ae af  c6 3e 09 d4 16 8e 06 71  |h<...A...>.....q|
-00000280  14 f8 90 97 cd f6 eb 7d  90 3c d1 f3 95 db 35 3c  |.......}.<....5<|
-00000290  c9 7d dc 30 55 e1 a0 66  8e 26 20 4f 43 89 08 6f  |.}.0U..f.& OC..o|
-000002a0  95 58 42 ae e8 6c b6 77  45 c6 8c c7 ad e5 ed ff  |.XB..l.wE.......|
-000002b0  09 6f 2e 7e b0 e4 5c f2  db 14 03 03 00 01 01 16  |.o.~..\.........|
-000002c0  03 03 00 28 00 00 00 00  00 00 00 00 c0 2c cc 32  |...(.........,.2|
-000002d0  78 5e 6c 3e e9 a3 83 65  b4 bb 4e 79 b2 04 08 30  |x^l>...e..Ny...0|
-000002e0  09 e9 04 99 70 48 44 95  26 b0 37 c9              |....pHD.&.7.|
+00000230  88 0f 00 00 84 06 01 00  80 72 5e f2 3f d2 7d 33  |.........r^.?.}3|
+00000240  ec 01 70 e5 91 5b 71 ac  48 88 99 5a af ad 40 82  |..p..[q.H..Z..@.|
+00000250  a7 de 2f 25 16 67 e1 e3  7d e6 d5 0f 79 63 63 56  |../%.g..}...yccV|
+00000260  1b 45 da 38 f7 99 4d a2  8e 6f 70 02 92 21 da 69  |.E.8..M..op..!.i|
+00000270  ba 2d 95 ea e5 5a f1 be  23 bb d2 8c 8b 36 b8 bf  |.-...Z..#....6..|
+00000280  c3 b5 c8 48 3c 27 26 c8  52 9c a4 53 d0 4e a6 7e  |...H<'&.R..S.N.~|
+00000290  cf 95 01 20 62 e1 47 59  82 b0 f1 64 e7 8e f4 f4  |... b.GY...d....|
+000002a0  c7 50 67 83 ec 56 10 9d  0b 54 60 5a 1a 0f 0d 31  |.Pg..V...T`Z...1|
+000002b0  31 c6 2d 12 e6 e4 22 77  6a 14 03 03 00 01 01 16  |1.-..."wj.......|
+000002c0  03 03 00 28 00 00 00 00  00 00 00 00 91 d6 08 d4  |...(............|
+000002d0  74 3f 02 78 ed c3 9d 0b  a7 f0 10 c7 e8 4a a3 a7  |t?.x.........J..|
+000002e0  d7 b7 c1 ca d4 fc e9 dc  b5 ca 35 39              |..........59|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 5f 80 e2 f1 78  |..........(_...x|
-00000010  0f cb 58 5c 3c 50 4c 1e  33 8a 1f b7 89 92 37 11  |..X\<PL.3.....7.|
-00000020  a3 8a 76 39 4a 3d b0 1f  a3 e9 ba 52 f8 2b e5 a3  |..v9J=.....R.+..|
-00000030  59 7c ac                                          |Y|.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 d8 3b 3c 00 02  |..........(.;<..|
+00000010  7d c2 88 cf 6e 9b b3 99  cb b6 60 74 da 07 cb 6d  |}...n.....`t...m|
+00000020  95 ce dd 08 d4 a3 5f 0d  79 89 40 8f 71 03 76 0a  |......_.y.@.q.v.|
+00000030  c3 c0 d3                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 75 dc 54  |.............u.T|
-00000010  d9 c5 b1 c2 c9 64 9a ea  20 e5 76 61 6c 05 af 33  |.....d.. .val..3|
-00000020  6b bc d7 15 03 03 00 1a  00 00 00 00 00 00 00 02  |k...............|
-00000030  24 6b 03 76 d3 da d0 ee  a6 32 c3 58 a1 5e a5 21  |$k.v.....2.X.^.!|
-00000040  b8 3a                                             |.:|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 3e 3d cd  |.............>=.|
+00000010  9b 8c 53 b7 86 e1 60 bc  3c 3a 7b b1 cf a5 d1 c8  |..S...`.<:{.....|
+00000020  1b d1 92 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  83 58 15 c4 87 a3 bf 7b  cf e6 e0 b4 10 37 ad 3b  |.X.....{.....7.;|
+00000040  d9 9a                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
index 5d795e7..3403023 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 c3 2f 08 30 ba  |....Y...U.../.0.|
-00000010  5d 9e 55 ef 23 f9 8a 0d  2f b4 25 02 5f c0 d2 c2  |].U.#.../.%._...|
-00000020  50 7c da db a4 ee 7c 18  df af aa 20 f3 a5 02 de  |P|....|.... ....|
-00000030  54 9f ce b9 6d 69 66 5d  57 76 ff 18 91 d3 93 ab  |T...mif]Wv......|
-00000040  39 13 29 4c b9 a7 3c db  7f 4d 97 fc c0 09 00 00  |9.)L..<..M......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 78 e9 9b 0c e1  |....Y...U..x....|
+00000010  45 f0 55 05 58 ef 80 4f  22 88 e4 7d eb af a5 b2  |E.U.X..O"..}....|
+00000020  75 36 9f a2 cc 6d 51 27  ca 7e 38 20 c8 89 89 e7  |u6...mQ'.~8 ....|
+00000030  95 70 01 01 67 b0 9a 1a  7a 54 d8 bb 22 72 c6 9c  |.p..g...zT.."r..|
+00000040  09 ff d4 2c 0a 94 86 bc  51 cb 56 7d c0 09 00 00  |...,....Q.V}....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,39 +49,39 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 46 07  |*............ F.|
-00000280  78 fd 3b 0c e0 2c 96 f8  44 b9 e9 06 e9 66 17 35  |x.;..,..D....f.5|
-00000290  c0 92 87 51 f6 e3 d7 f5  09 50 56 c6 e9 3b 04 03  |...Q.....PV..;..|
-000002a0  00 8a 30 81 87 02 41 5d  88 4b fe eb 45 ee 5e 9f  |..0...A].K..E.^.|
-000002b0  ec 20 90 1f 41 aa 47 87  f7 ae 46 71 dc 55 8b 2c  |. ..A.G...Fq.U.,|
-000002c0  ce 70 5f ad 3e fa 3c c3  cb 77 d2 69 67 25 27 08  |.p_.>.<..w.ig%'.|
-000002d0  23 de 52 3c 0e 6c ca 8f  86 8f 61 cd 5b cf d8 42  |#.R<.l....a.[..B|
-000002e0  aa 5a 95 aa 4b d4 d9 f3  02 42 01 81 78 53 9c bd  |.Z..K....B..xS..|
-000002f0  af 7e d9 be 26 07 24 11  ca 4b 1d dd 2b 49 ec 35  |.~..&.$..K..+I.5|
-00000300  25 8d 58 87 ad 80 4f 90  c7 f8 a4 b9 c2 75 b5 12  |%.X...O......u..|
-00000310  a7 2c 49 82 76 e8 ce c4  a7 23 68 75 fc 88 82 13  |.,I.v....#hu....|
-00000320  27 55 a7 50 3c d6 d0 ae  e3 88 94 b4 16 03 03 00  |'U.P<...........|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 0f 61  |*............ .a|
+00000280  6e 56 ec 74 54 e2 24 09  61 64 45 89 44 aa cb 79  |nV.tT.$.adE.D..y|
+00000290  18 37 12 42 07 f8 d7 a3  42 b8 d7 06 21 28 04 03  |.7.B....B...!(..|
+000002a0  00 8a 30 81 87 02 42 00  af 5c 33 04 e8 e1 fa b7  |..0...B..\3.....|
+000002b0  98 38 96 ea c1 ee 7d 2c  45 85 ab 41 bd d8 88 af  |.8....},E..A....|
+000002c0  a6 0b e4 22 56 7d 3a e6  a6 8e 0d b5 81 cb 38 43  |..."V}:.......8C|
+000002d0  e7 b6 94 ee 20 e7 61 89  00 99 69 18 b3 06 d0 15  |.... .a...i.....|
+000002e0  0e f4 10 e9 5a dd 74 10  d1 02 41 27 4c dc 89 d4  |....Z.t...A'L...|
+000002f0  75 56 d4 c2 82 7d 53 a0  61 c5 ba 6a 9a ca fa 36  |uV...}S.a..j...6|
+00000300  16 db 82 5d 5e b7 9b 6a  b8 13 0b 69 2f b5 c9 8e  |...]^..j...i/...|
+00000310  53 18 03 24 b3 31 b1 48  8c b9 e0 16 96 cc e2 5d  |S..$.1.H.......]|
+00000320  71 6a 1d 70 8c 1b 57 8e  5d 9a f2 e1 16 03 03 00  |qj.p..W.].......|
 00000330  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
 00000030  16 03 03 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000040  00 00 00 00 00 04 f4 cc  a8 9f 48 44 ca 19 e6 4c  |..........HD...L|
-00000050  3d 51 f2 29 40 0b 70 06  09 f0 69 5c 51 78 51 1e  |=Q.)@.p...i\QxQ.|
-00000060  2b d1 47 22 8d d6 fb f5  41 bd e4 fd 3d f4 1b 48  |+.G"....A...=..H|
-00000070  44 96 2d 97 b9                                    |D.-..|
+00000040  00 00 00 00 00 c1 47 dc  05 80 89 9f 04 e8 88 58  |......G........X|
+00000050  bc 59 78 df ce bb d4 f7  cf 45 e2 2a ff ce 09 9c  |.Yx......E.*....|
+00000060  07 f3 90 49 ad 4d 07 b4  21 46 e3 37 e9 54 82 4d  |...I.M..!F.7.T.M|
+00000070  a2 05 ad 83 fa                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 f1 a2 70 ba 50  |..........@..p.P|
-00000010  9d 7a 9f 8f c6 fb 7e 83  75 bd 94 cf e6 c1 4a f0  |.z....~.u.....J.|
-00000020  e6 54 e9 2c 30 23 a2 5c  c2 09 32 d4 06 f7 54 e7  |.T.,0#.\..2...T.|
-00000030  ab 27 a6 66 ab 86 e6 2c  20 12 cf 61 4d ef 12 20  |.'.f..., ..aM.. |
-00000040  ba b6 42 39 b7 76 b9 1b  fc f4 44                 |..B9.v....D|
+00000000  14 03 03 00 01 01 16 03  03 00 40 a6 27 61 cd 85  |..........@.'a..|
+00000010  3a 7c 35 bb 33 61 ed 4b  0f 0c 42 bd 25 a5 5a a8  |:|5.3a.K..B.%.Z.|
+00000020  ef 27 b3 d7 d2 38 64 c7  46 51 5c f2 4b 32 a1 eb  |.'...8d.FQ\.K2..|
+00000030  b2 6a ba af fc d0 2d 7a  9d 72 d5 23 ae 15 2a fc  |.j....-z.r.#..*.|
+00000040  1c 03 cd 99 dd ac b0 31  83 0a 1e                 |.......1...|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 0b 5b d0  ab 14 3f ae 1f 4b 12 25  |......[...?..K.%|
-00000020  05 2a 67 11 0c 17 42 1b  b6 d2 af 16 40 26 fd 7b  |.*g...B.....@&.{|
-00000030  d7 57 10 2a f8 15 03 03  00 30 00 00 00 00 00 00  |.W.*.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 83 54 64 d6 31 32  |...........Td.12|
-00000050  55 62 32 49 b9 54 7b e3  34 02 1c 75 e3 1b 5a 41  |Ub2I.T{.4..u..ZA|
-00000060  a2 cd 47 26 f0 ed c2 d5  41 34                    |..G&....A4|
+00000010  00 00 00 00 00 a7 0f 50  52 17 a2 5b 19 33 4e 97  |.......PR..[.3N.|
+00000020  33 4e 56 2e 1e bf 93 ca  ae fa 4c ca ff 47 08 7b  |3NV.......L..G.{|
+00000030  d2 f8 e1 29 29 15 03 03  00 30 00 00 00 00 00 00  |...))....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 a5 ac 57 1c ca 5f  |............W.._|
+00000050  f2 39 b2 85 a5 4a 06 11  a2 8f e5 1d 55 1d 4f 89  |.9...J......U.O.|
+00000060  6c d9 47 bd a2 8b d3 d0  eb d6                    |l.G.......|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
index 28a9ef7..3ae5fac 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 72 81 c3 91 37  |....Y...U..r...7|
-00000010  54 37 fb 0f 2b 16 3b 7b  bc a6 d9 2e e2 83 23 83  |T7..+.;{......#.|
-00000020  b3 67 cf 36 dc 65 8d a6  3d cb 72 20 ac b9 b9 48  |.g.6.e..=.r ...H|
-00000030  30 9d fe 67 09 39 f5 47  d2 9a c8 3e 22 02 50 5e  |0..g.9.G...>".P^|
-00000040  fd 02 c9 ff c1 84 2e 2e  ab 78 ef c6 c0 2b 00 00  |.........x...+..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 e1 a8 35 92 15  |....Y...U....5..|
+00000010  b2 f2 02 ae 4f 1b c5 1c  46 04 d1 bf 60 d6 bd 66  |....O...F...`..f|
+00000020  d0 c4 d5 18 26 10 6d 53  19 35 d2 20 15 d3 4b 3f  |....&.mS.5. ..K?|
+00000030  de 5a f3 8d f7 02 c4 71  8b 4f c2 b6 69 49 f1 2a  |.Z.....q.O..iI.*|
+00000040  79 66 40 45 ee 9d 1b d8  72 7e b0 23 c0 2b 00 00  |yf@E....r~.#.+..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,34 +49,34 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 b7 1c  |*............ ..|
-00000280  2f 05 5e c8 ae 68 6b 54  c5 88 19 cf 7c 04 b2 ed  |/.^..hkT....|...|
-00000290  8d 5a e9 7e 6b 50 8a ee  12 66 2d 6f e4 7a 04 03  |.Z.~kP...f-o.z..|
-000002a0  00 8a 30 81 87 02 42 01  8d 7e 23 bc d7 a7 ad 73  |..0...B..~#....s|
-000002b0  5f 45 9e 04 da 6e c0 34  a8 09 59 e3 bc ab 80 e1  |_E...n.4..Y.....|
-000002c0  d4 84 79 7d de 90 c1 f2  ea 95 ed fc 7e d3 f0 31  |..y}........~..1|
-000002d0  4c 9b da 82 a0 97 ed e6  c9 f2 b9 2a 0a 1e 0a 2c  |L..........*...,|
-000002e0  7f 1d 62 ea 11 a9 77 5e  2f 02 41 09 88 2b eb 84  |..b...w^/.A..+..|
-000002f0  4f 62 9a c9 8a 0b a2 c6  88 0e 3e d9 29 f0 2b ba  |Ob........>.).+.|
-00000300  08 40 b0 9c 17 70 d9 84  1e d3 39 ad 70 fc df 63  |.@...p....9.p..c|
-00000310  a0 f6 69 3c 19 ce 0b a5  95 d2 6a b1 46 b1 e5 ba  |..i<......j.F...|
-00000320  fd d2 67 4b 76 e3 eb b9  21 d0 7c 85 16 03 03 00  |..gKv...!.|.....|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 2e b4  |*............ ..|
+00000280  dd 41 46 08 4d c2 c9 37  b8 50 0b 50 6f c7 bd 13  |.AF.M..7.P.Po...|
+00000290  de 59 d4 9f d0 2b 44 2a  8c 6f 2a f9 67 7a 04 03  |.Y...+D*.o*.gz..|
+000002a0  00 8a 30 81 87 02 41 7c  9a e0 93 cc 65 a2 af 0e  |..0...A|....e...|
+000002b0  32 9c 37 b7 39 9a 45 95  fb 2e b2 a9 34 f8 ab 47  |2.7.9.E.....4..G|
+000002c0  d8 3b 6f 7d b8 03 32 a9  d0 30 1a 37 cc fd 4a 16  |.;o}..2..0.7..J.|
+000002d0  94 f9 23 ce b7 8a e6 91  d7 33 00 25 d3 c7 88 d8  |..#......3.%....|
+000002e0  49 2c 81 73 e2 b1 b8 78  02 42 01 c8 58 dc 43 96  |I,.s...x.B..X.C.|
+000002f0  40 00 c3 4c 9c a1 ba ef  4a 20 e6 ee 53 28 6e 82  |@..L....J ..S(n.|
+00000300  97 ba f3 0b 71 5c f9 4f  05 1e 61 a7 ba 03 60 5c  |....q\.O..a...`\|
+00000310  f5 61 1e fd 53 c1 74 30  5c 92 b4 4c 6e d2 9f 05  |.a..S.t0\..Ln...|
+00000320  6b ad 92 e5 14 b8 a9 07  a0 f3 34 71 16 03 03 00  |k.........4q....|
 00000330  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 32 49 7e  |....(........2I~|
-00000040  8f d6 2e 81 d7 03 a6 61  a3 04 98 81 95 84 58 d1  |.......a......X.|
-00000050  a2 33 fe 4a 5d cd 96 76  64 1e 1a 62 03           |.3.J]..vd..b.|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 71 c9 39  |....(........q.9|
+00000040  50 b8 91 9e eb f6 48 c6  04 d0 ae 99 dc 63 14 1b  |P.....H......c..|
+00000050  e9 4f 6b c0 18 46 b6 ca  38 bc 58 c3 85           |.Ok..F..8.X..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 28 14 2d ae 7c  |..........((.-.||
-00000010  b8 7d dc 27 b2 18 39 57  c8 be 5c 3d a3 ab fa 5a  |.}.'..9W..\=...Z|
-00000020  3d 55 1b 3d 31 77 95 af  42 86 af 2b e7 5a 98 40  |=U.=1w..B..+.Z.@|
-00000030  18 77 d1                                          |.w.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 e3 f3 fe 51 7c  |..........(...Q||
+00000010  7c f9 ad fe 85 6c 37 fd  8f e2 76 2f 10 38 62 b0  ||....l7...v/.8b.|
+00000020  37 7c cf 6e e6 65 c6 f4  5e 67 33 03 10 62 14 29  |7|.n.e..^g3..b.)|
+00000030  8a ca 2e                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 30 50 2f  |.............0P/|
-00000010  36 4a 7c ee e6 f0 b9 b8  bf 4d e3 63 4d 5e 58 08  |6J|......M.cM^X.|
-00000020  ac ac 82 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  80 e2 42 ca 91 65 04 4e  ca a8 6f 81 7c 30 c0 1f  |..B..e.N..o.|0..|
-00000040  aa 7b                                             |.{|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 5a 2d fa  |.............Z-.|
+00000010  9d 55 ff 55 ee 77 9e c0  60 3d 37 aa 82 14 a9 8c  |.U.U.w..`=7.....|
+00000020  7b d3 92 15 03 03 00 1a  00 00 00 00 00 00 00 02  |{...............|
+00000030  8a 69 ad 03 ec 4f 06 55  e6 0c 3a 59 ea 15 26 e7  |.i...O.U..:Y..&.|
+00000040  17 de                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
index 831fa21..9d79b14 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 be c0 b6 d7 fe  |....Y...U.......|
-00000010  43 9d 21 1f 89 27 bd db  0a 9a 5a 44 dd 79 d1 f2  |C.!..'....ZD.y..|
-00000020  18 9a 2a 04 8c eb e6 a9  93 ef ee 20 35 48 44 08  |..*........ 5HD.|
-00000030  8c 7a 3e f6 0f d7 5f 33  54 60 0b c9 65 4e 17 8d  |.z>..._3T`..eN..|
-00000040  d2 69 b7 20 0b c5 ba 9a  d4 b7 40 39 c0 23 00 00  |.i. ......@9.#..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 c7 69 06 a9 64  |....Y...U...i..d|
+00000010  53 1a 6c 7b 39 f3 2e e3  01 5e ef e0 ac 69 a6 2e  |S.l{9....^...i..|
+00000020  39 59 c4 a8 06 60 9c 5b  0a 93 f2 20 b1 ba 93 61  |9Y...`.[... ...a|
+00000030  3f c3 a8 d0 e7 22 60 8a  0b c2 68 14 69 c5 8a 9c  |?...."`...h.i...|
+00000040  35 b2 ba 8a d2 9b a4 e0  13 d8 fc bb c0 23 00 00  |5............#..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,43 +49,43 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 0e 53  |*............ .S|
-00000280  82 54 1a ba f8 a4 52 1d  6d b8 70 18 41 e8 67 f9  |.T....R.m.p.A.g.|
-00000290  38 1e fb fa b8 89 2d d6  4d 1b ae 67 fe 75 04 03  |8.....-.M..g.u..|
-000002a0  00 8b 30 81 88 02 42 01  68 0e d4 92 a6 1a d9 66  |..0...B.h......f|
-000002b0  ff 0e ca 4c 32 b8 78 d3  52 d1 ad a2 32 83 f0 3c  |...L2.x.R...2..<|
-000002c0  43 e0 7e 92 94 e9 c6 99  00 d9 f7 06 c0 2c 72 c0  |C.~..........,r.|
-000002d0  9b f7 c0 ec 1f 23 8f b5  e5 74 9d ff 89 17 12 b4  |.....#...t......|
-000002e0  f1 f5 25 f7 2e 0d 78 f6  1c 02 42 01 fc da dd c8  |..%...x...B.....|
-000002f0  65 30 67 a3 ff 42 e3 37  19 ba 7c 04 6b a1 b3 97  |e0g..B.7..|.k...|
-00000300  b0 ca 8c 2d fc b0 40 1c  a1 d8 c9 64 fe df 48 3b  |...-..@....d..H;|
-00000310  07 57 1f 81 a2 3e a4 84  96 00 fb 55 29 1c 94 9d  |.W...>.....U)...|
-00000320  f9 0d a4 71 4f 5f fd c3  22 e2 88 07 21 16 03 03  |...qO_.."...!...|
-00000330  00 04 0e 00 00 00                                 |......|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 bd cd  |*............ ..|
+00000280  69 00 ff 76 9e 27 f5 4d  cb f2 be 87 ec f3 c6 08  |i..v.'.M........|
+00000290  79 fa cc 4e a5 db e6 dd  19 cb b1 66 e5 2b 04 03  |y..N.......f.+..|
+000002a0  00 8a 30 81 87 02 41 33  72 4b 8e 13 f1 3c 7b 9b  |..0...A3rK...<{.|
+000002b0  4e 63 e0 28 1c 62 b0 a9  bf 70 96 68 93 52 4b 64  |Nc.(.b...p.h.RKd|
+000002c0  02 4b 79 0b 50 7c 16 df  21 8f e4 8b c2 c6 4b cc  |.Ky.P|..!.....K.|
+000002d0  96 b8 bb 4a cc 89 f6 a5  6d c2 a3 70 b6 5a 25 26  |...J....m..p.Z%&|
+000002e0  ad aa 56 95 72 fa d6 13  02 42 01 de 8a 1f 83 51  |..V.r....B.....Q|
+000002f0  ce 3e 37 ff 3e ba 0e ed  bd f3 95 0c 1b 69 8f f3  |.>7.>........i..|
+00000300  f4 a9 26 cb c6 f4 70 79  da 93 5b 25 76 89 e8 3d  |..&...py..[%v..=|
+00000310  94 7f a9 5b 4f 25 83 63  a2 cb 71 27 41 5e 41 a1  |...[O%.c..q'A^A.|
+00000320  5c 65 f2 2d a4 81 91 ca  79 bc 45 d3 16 03 03 00  |\e.-....y.E.....|
+00000330  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
 00000030  16 03 03 00 50 00 00 00  00 00 00 00 00 00 00 00  |....P...........|
-00000040  00 00 00 00 00 7c e9 97  4b 98 8a 4c 59 95 3e 31  |.....|..K..LY.>1|
-00000050  c4 b6 e2 79 10 de bc 8e  aa 1e 52 07 b2 e1 52 bc  |...y......R...R.|
-00000060  3b da 8d 5f 12 6a 18 d1  0a 5d 93 1c ad bb f9 b7  |;.._.j...]......|
-00000070  6b 58 49 39 ea 3a 9e 20  47 69 43 b4 b4 d8 16 d0  |kXI9.:. GiC.....|
-00000080  f0 9d 36 74 04                                    |..6t.|
+00000040  00 00 00 00 00 fe 52 a2  0a 9f de 8c 45 36 c5 0e  |......R.....E6..|
+00000050  a0 b5 f6 06 80 9f 2b 0e  72 4b 86 a7 4c 2a 37 0c  |......+.rK..L*7.|
+00000060  a0 a3 4c 2c 32 32 cf ed  45 ee e3 a2 1c 17 7d 4f  |..L,22..E.....}O|
+00000070  d8 60 d6 79 08 01 d7 35  0c 40 c8 85 f1 3e 73 b5  |.`.y...5.@...>s.|
+00000080  5d 89 c9 db 03                                    |]....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 60 d5 ac 39 b6  |..........P`..9.|
-00000010  58 50 03 90 9f c9 78 f1  45 43 b1 34 bd c8 29 65  |XP....x.EC.4..)e|
-00000020  54 38 7a 88 46 15 e8 a4  fb 9d 80 4e d6 45 e1 8d  |T8z.F......N.E..|
-00000030  27 d6 09 66 1d ee 46 6d  dd 8e 89 34 0f 4a fb fd  |'..f..Fm...4.J..|
-00000040  bc 85 08 07 f0 5b 1c 24  e2 11 1b e2 a4 94 f5 80  |.....[.$........|
-00000050  fa 47 f4 62 0e b9 1c 31  cb 7b bf                 |.G.b...1.{.|
+00000000  14 03 03 00 01 01 16 03  03 00 50 99 8b 66 fc b2  |..........P..f..|
+00000010  0c 18 de 47 7b 72 a2 9b  47 64 58 45 00 70 b6 d3  |...G{r..GdXE.p..|
+00000020  33 62 c2 c6 41 da 5d 08  37 16 5c 24 50 06 e0 e6  |3b..A.].7.\$P...|
+00000030  7c 90 5e 32 5e 3f 2e bc  70 d2 77 b5 29 d8 d4 fb  ||.^2^?..p.w.)...|
+00000040  38 8c 05 40 e1 42 1a 25  44 79 fa a6 cc f6 50 5a  |8..@.B.%Dy....PZ|
+00000050  da e0 85 99 30 20 7d ee  04 fe ca                 |....0 }....|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000010  00 00 00 00 00 37 b7 23  a2 06 97 f3 60 9a f0 7e  |.....7.#....`..~|
-00000020  b7 11 6d 0d 66 0e db 38  1a eb cd 72 80 c8 54 ef  |..m.f..8...r..T.|
-00000030  cf 90 6d 22 68 41 63 03  46 b9 28 4f 2f d6 fe fa  |..m"hAc.F.(O/...|
-00000040  b2 91 07 36 71 15 03 03  00 40 00 00 00 00 00 00  |...6q....@......|
-00000050  00 00 00 00 00 00 00 00  00 00 ca 17 d9 fd 1a 0e  |................|
-00000060  21 db a4 92 dc 92 e8 89  9d 14 6b 8a d3 ee a7 95  |!.........k.....|
-00000070  c0 91 8d 3c af 5a 48 d5  c6 2f 66 b8 b8 d4 ce f9  |...<.ZH../f.....|
-00000080  59 e5 e0 e2 df e5 7e ea  94 03                    |Y.....~...|
+00000010  00 00 00 00 00 cb cb 98  55 3f 17 18 42 7b 52 0c  |........U?..B{R.|
+00000020  6f 6c 50 87 b1 af ef 25  ac a5 24 4a d2 bc 39 33  |olP....%..$J..93|
+00000030  29 81 c0 4f cf 20 8f 0c  4c a8 64 5f 97 4d da f4  |)..O. ..L.d_.M..|
+00000040  89 7c 28 f3 d4 15 03 03  00 40 00 00 00 00 00 00  |.|(......@......|
+00000050  00 00 00 00 00 00 00 00  00 00 6b c5 03 a6 9b 87  |..........k.....|
+00000060  ac df 05 8d 79 3c 46 12  70 3a 1d a0 d0 29 7c 2a  |....y<F.p:...)|*|
+00000070  7e 33 ee 58 99 46 0a f0  8c 03 60 b8 ee 70 c9 b7  |~3.X.F....`..p..|
+00000080  40 ba 19 d9 d4 8a e3 95  ef 16                    |@.........|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
index c22edd0..85f4607 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 e6 0e 27 a7 58  |....Y...U....'.X|
-00000010  1d a3 1d 1d 21 64 31 f6  1e bc 28 b4 46 7e 26 be  |....!d1...(.F~&.|
-00000020  de 0a 65 eb f0 18 dc 7f  3e 1b 55 20 fe 66 50 20  |..e.....>.U .fP |
-00000030  f0 f0 48 a8 db 0a ff ee  60 ea 3d 7f 07 5e b9 65  |..H.....`.=..^.e|
-00000040  c3 e4 2a 19 9c bd 57 36  ca e3 a7 2d c0 2c 00 00  |..*...W6...-.,..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 93 2e 79 54 e7  |....Y...U....yT.|
+00000010  e4 ce 82 cd 46 2b d1 99  d2 ba c7 37 1e f5 86 2f  |....F+.....7.../|
+00000020  6c 7d b1 10 e1 98 03 b1  93 a9 d9 20 c2 b6 55 f9  |l}......... ..U.|
+00000030  d0 b3 65 3e 99 33 4c a4  5d a3 58 8b b4 ee c3 91  |..e>.3L.].X.....|
+00000040  80 34 1c 07 c2 b9 9c bf  e4 c0 bd f2 c0 2c 00 00  |.4...........,..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -49,34 +49,34 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 17 21  |*............ .!|
-00000280  a9 b8 65 8b aa 41 d2 d1  45 45 e5 ce 39 60 54 b6  |..e..A..EE..9`T.|
-00000290  43 9f c4 19 a4 aa ec 71  08 b0 d1 22 f7 46 04 03  |C......q...".F..|
-000002a0  00 8b 30 81 88 02 42 00  8b a5 d9 d3 8f a1 72 48  |..0...B.......rH|
-000002b0  06 42 25 c3 f6 c8 46 8d  88 30 36 7d d8 18 a9 cc  |.B%...F..06}....|
-000002c0  de e4 c8 3f e9 d2 f0 88  18 cc c6 fb 14 e0 05 b1  |...?............|
-000002d0  ec 50 3d 57 b4 e9 83 57  55 4b 0d 2c 89 69 ff b1  |.P=W...WUK.,.i..|
-000002e0  58 0b 01 89 48 97 ee 88  7e 02 42 01 e1 6f 9c 36  |X...H...~.B..o.6|
-000002f0  6a 6c 86 24 d6 b3 45 f1  6c 03 d8 fd da d8 cc 52  |jl.$..E.l......R|
-00000300  04 41 7a c5 f9 b5 91 a5  6c d8 5a 03 ad de e3 da  |.Az.....l.Z.....|
-00000310  de f8 db b0 bc 75 38 03  ab 84 ac 3f b2 c2 7e 6d  |.....u8....?..~m|
-00000320  a7 2e c0 d9 bd 85 e2 7b  36 11 2b 12 14 16 03 03  |.......{6.+.....|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 d2 39  |*............ .9|
+00000280  f6 fc 9c 40 cb ba 04 7c  37 ac df 95 5f 46 44 f4  |...@...|7..._FD.|
+00000290  2b 0c 63 24 4e 95 1d 35  b3 68 ab 27 d1 5a 04 03  |+.c$N..5.h.'.Z..|
+000002a0  00 8b 30 81 88 02 42 01  3e ff 73 74 01 f5 c8 32  |..0...B.>.st...2|
+000002b0  31 f1 d5 0b 26 db 0c ef  d0 c9 a7 aa 21 c8 0f 50  |1...&.......!..P|
+000002c0  2f ce eb 41 ce 1e de 5d  29 8d c1 20 f2 d9 5d 39  |/..A...]).. ..]9|
+000002d0  9d 1d c1 10 b1 a8 35 33  cc 58 f3 fd df 5d 7e fc  |......53.X...]~.|
+000002e0  ee 8b 15 02 03 2e b0 2b  b1 02 42 00 e0 f1 cf e9  |.......+..B.....|
+000002f0  e7 e2 1a a7 e1 3c 47 40  c4 fb b2 0d 15 47 4e 26  |.....<G@.....GN&|
+00000300  46 bc 16 49 dd 17 2c ef  2c 4a d0 ba e5 76 90 f1  |F..I..,.,J...v..|
+00000310  e8 4b 2c d3 83 ef 36 2a  6d b7 83 52 ff b0 a0 44  |.K,...6*m..R...D|
+00000320  52 9b 25 7e 8a 20 af 74  e3 fc b3 75 cd 16 03 03  |R.%~. .t...u....|
 00000330  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 4b a3 cc  |....(........K..|
-00000040  a1 5b 04 d4 1e 6c 2c 26  56 23 62 50 bc d6 90 0b  |.[...l,&V#bP....|
-00000050  67 41 d9 7c 79 a5 53 54  73 0a 93 e2 73           |gA.|y.STs...s|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 5c 78 1d  |....(........\x.|
+00000040  a7 00 de 4e 5e 13 6a 1d  1d 82 28 f6 b6 8a 88 fe  |...N^.j...(.....|
+00000050  00 81 fe 04 95 a0 4e 93  e0 01 19 a3 6d           |......N.....m|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 e3 19 7b 8c 8a  |..........(..{..|
-00000010  52 35 82 cc 70 50 83 22  88 8b 0a 54 bc eb ff 57  |R5..pP."...T...W|
-00000020  2c df 0d 50 d6 21 2f d2  d9 e8 15 27 b9 d7 01 a3  |,..P.!/....'....|
-00000030  f2 62 0b                                          |.b.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 0a 61 1d 77 66  |..........(.a.wf|
+00000010  67 ca 17 5a 94 fc bf 36  07 33 f8 7e 34 bc 65 aa  |g..Z...6.3.~4.e.|
+00000020  0f 28 7d 40 80 6e 33 99  83 09 02 78 b7 d1 cd 56  |.(}@.n3....x...V|
+00000030  a7 f7 e5                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 cc cf 92  |................|
-00000010  4d 25 58 96 1d dc df fb  d9 1f a5 49 87 45 dd 73  |M%X........I.E.s|
-00000020  1a 17 ae 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  fb b5 c5 e4 aa ea e7 7e  ff dd f7 11 63 c0 e4 a3  |.......~....c...|
-00000040  86 fc                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 56 48 af  |.............VH.|
+00000010  45 e1 76 a8 67 ef 80 cc  92 03 aa b5 88 fc 48 84  |E.v.g.........H.|
+00000020  1b 81 39 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..9.............|
+00000030  5a 53 90 c9 25 a6 99 ce  e7 09 74 97 63 68 fe 0c  |ZS..%.....t.ch..|
+00000040  5e 89                                             |^.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
index 61e6657..4d3fbfe 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
@@ -1,17 +1,17 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 67 01 00 00  63 03 03 00 00 00 00 00  |....g...c.......|
+00000000  16 03 01 00 6b 01 00 00  67 03 03 00 00 00 00 00  |....k...g.......|
 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 02 cc a9  |................|
-00000030  01 00 00 38 00 05 00 05  01 00 00 00 00 00 0a 00  |...8............|
+00000030  01 00 00 3c 00 05 00 05  01 00 00 00 00 00 0a 00  |...<............|
 00000040  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
-00000050  00 00 0d 00 0e 00 0c 04  01 04 03 05 01 05 03 02  |................|
-00000060  01 02 03 ff 01 00 01 00  00 12 00 00              |............|
+00000050  00 00 0d 00 12 00 10 04  01 04 03 05 01 05 03 06  |................|
+00000060  01 06 03 02 01 02 03 ff  01 00 01 00 00 12 00 00  |................|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 d6 47 27 38 fc  |....Y...U...G'8.|
-00000010  16 92 2c 1f a6 53 a9 31  85 65 a7 83 0a 8f cb 4d  |..,..S.1.e.....M|
-00000020  7d 5b df c1 2e b9 b1 08  e3 b9 96 20 16 0c e5 07  |}[......... ....|
-00000030  27 cc 4f 7d 11 ef 1a 14  c6 42 bf e9 c1 b7 a5 89  |'.O}.....B......|
-00000040  ca 2b 4c 30 4f c7 c8 10  13 b0 b1 6b cc a9 00 00  |.+L0O......k....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 3c 9c e9 fb 22  |....Y...U..<..."|
+00000010  8b 32 cb 0d 56 1d a7 a2  c7 c5 d4 41 3d 9f 84 1b  |.2..V......A=...|
+00000020  26 50 b6 a3 fa f2 c5 20  0d f9 a6 20 38 86 ba 26  |&P..... ... 8..&|
+00000030  db 6e d9 ab 3c 73 ec d8  34 56 d1 f2 d3 60 42 9a  |.n..<s..4V...`B.|
+00000040  b5 e6 2f 24 c5 a7 fa 42  bc b8 13 df cc a9 00 00  |../$...B........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -46,32 +46,32 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 69 78  |*............ ix|
-00000280  7b e5 14 95 c8 d1 3c 7e  c2 d7 38 33 c3 9f 8f dc  |{.....<~..83....|
-00000290  25 8d 89 8a 99 a4 e4 8b  40 17 fc 80 43 67 04 03  |%.......@...Cg..|
-000002a0  00 8b 30 81 88 02 42 01  32 a8 dd d9 ec 11 d2 f2  |..0...B.2.......|
-000002b0  6d 86 da 31 00 8c bf ed  81 1d 8c c8 23 87 98 f7  |m..1........#...|
-000002c0  25 0c 1b 3d 9f 07 80 11  bc 07 b1 15 5f 3a 81 0e  |%..=........_:..|
-000002d0  59 04 e8 09 be ea 21 97  34 a9 8a 2f ef 3a 47 ad  |Y.....!.4../.:G.|
-000002e0  3b f9 9d f3 b8 b8 9a 93  03 02 42 01 bc 88 6b 99  |;.........B...k.|
-000002f0  d7 7a df de 5a 75 53 b0  3c 4c 1d 8b 15 c5 a7 9d  |.z..ZuS.<L......|
-00000300  3d 00 c0 f7 19 47 88 30  00 29 24 80 23 45 88 2e  |=....G.0.)$.#E..|
-00000310  11 60 3e 4b 6a 41 ad dc  3d 7d 3f 59 a0 0e fd d6  |.`>KjA..=}?Y....|
-00000320  f7 c7 7f 63 49 2f e4 4e  d9 8f 2d e5 98 16 03 03  |...cI/.N..-.....|
-00000330  00 04 0e 00 00 00                                 |......|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 ef e6  |*............ ..|
+00000280  9e e3 b7 29 0e db 15 72  e8 a8 14 db 99 9c 81 05  |...)...r........|
+00000290  29 a0 52 3d 4b a8 76 a3  6d 45 9a 19 72 50 04 03  |).R=K.v.mE..rP..|
+000002a0  00 8a 30 81 87 02 41 59  79 0e 40 7d ee 88 af a4  |..0...AYy.@}....|
+000002b0  23 dd 4e 18 6a 15 20 af  98 d9 f7 4f 0a ff 7a c6  |#.N.j. ....O..z.|
+000002c0  a7 36 53 f0 1e 1a a7 90  25 e6 bd 82 69 cc bc aa  |.6S.....%...i...|
+000002d0  5d dd c5 0d 01 ed f8 75  57 18 3b d9 52 9d e2 3b  |]......uW.;.R..;|
+000002e0  a2 fb 7a 71 ea 61 7c 34  02 42 01 f3 ed 1f 6d e8  |..zq.a|4.B....m.|
+000002f0  15 ce a1 af ff f5 2f fb  e4 6f 83 9c ac f4 05 e2  |....../..o......|
+00000300  27 15 bb dd 63 9c ea ac  06 a1 08 4c 5f ad 1a 80  |'...c......L_...|
+00000310  cd ee d6 b7 d0 96 6d 42  54 ff cb 42 9b 48 24 0c  |......mBT..B.H$.|
+00000320  fe fa 07 2a 0a 7a d3 c0  58 4b cd 79 16 03 03 00  |...*.z..XK.y....|
+00000330  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 7c 89 36  36 77 8c 09 31 e4 48 01  |.... |.66w..1.H.|
-00000040  6f 08 27 a8 bb 1b 1c a6  0c 09 ec 0b f6 a3 be bd  |o.'.............|
-00000050  76 70 fb f8 e5                                    |vp...|
+00000030  16 03 03 00 20 6e 2a ec  f4 3a e8 88 99 f1 77 94  |.... n*..:....w.|
+00000040  b3 a2 c5 3a 59 c2 9a f5  4a fb 89 e4 51 1a 54 a4  |...:Y...J...Q.T.|
+00000050  72 d9 54 99 c3                                    |r.T..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 a0 db 6c df b1  |.......... ..l..|
-00000010  87 77 78 ad 22 b2 98 77  e8 57 aa 13 a8 98 35 63  |.wx."..w.W....5c|
-00000020  00 c5 13 b9 88 5d ca bf  bc c5 c3                 |.....].....|
+00000000  14 03 03 00 01 01 16 03  03 00 20 be 1a 60 4e 4a  |.......... ..`NJ|
+00000010  2d 81 19 6b 7c f2 80 15  18 9c 38 70 6d a3 49 88  |-..k|.....8pm.I.|
+00000020  93 4b e8 cc 9f b2 0e cc  ed 29 64                 |.K.......)d|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 16 00 c8  c6 25 ae 11 9d a5 10 75  |.........%.....u|
-00000010  e4 4c e3 69 12 2b d9 9e  8e 40 88 15 03 03 00 12  |.L.i.+...@......|
-00000020  cf ab ac d4 c4 8e 9c 92  c4 2f 1f c6 96 0b 36 c9  |........./....6.|
-00000030  f5 22                                             |."|
+00000000  17 03 03 00 16 bd 4c d9  d3 ea d0 d3 4e db dc ea  |......L.....N...|
+00000010  ad e7 20 17 ec 36 04 29  a5 7c ab 15 03 03 00 12  |.. ..6.).|......|
+00000020  7b e1 b6 9b fc f9 18 83  87 31 b3 02 e7 b2 e3 c6  |{........1......|
+00000030  37 d8                                             |7.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
index 45728cf..9cc3e8f 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 2f 51 e0 81 eb  |....Y...U../Q...|
-00000010  d2 db 4f 22 fa 11 d2 56  f3 06 d6 a0 97 d2 f3 74  |..O"...V.......t|
-00000020  fc a9 a7 73 ba a8 ee f2  05 89 15 20 0f 96 70 60  |...s....... ..p`|
-00000030  6f 78 aa 56 fa 92 5e e3  bc e7 f0 40 00 48 8b 84  |ox.V..^....@.H..|
-00000040  57 b8 49 e9 f9 00 99 ff  73 29 f6 e7 c0 13 00 00  |W.I.....s)......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 66 3d ff 45 dc  |....Y...U..f=.E.|
+00000010  ea f8 4c 56 5d 55 71 63  c1 64 33 9f f5 09 aa 38  |..LV]Uqc.d3....8|
+00000020  bd 13 27 d7 85 ed 0a b4  68 83 9a 20 98 69 c4 d9  |..'.....h.. .i..|
+00000030  a1 46 f4 30 ed 4d ae 31  7b 3c 18 23 fa b5 b4 a1  |.F.0.M.1{<.#....|
+00000040  74 98 34 7f b8 d0 00 e5  22 35 eb 4f c0 13 00 00  |t.4....."5.O....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,38 +54,38 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 48 77 87 3e 04 c9 14  |........ Hw.>...|
-000002d0  56 9d 1b 41 4b d0 eb 65  8d 56 56 97 fd 73 97 cd  |V..AK..e.VV..s..|
-000002e0  c6 88 8f 8e 79 99 09 65  53 04 01 00 80 98 c2 ff  |....y..eS.......|
-000002f0  49 aa 41 ce 0e 7b 03 99  39 c0 b5 ac 72 16 1c 5e  |I.A..{..9...r..^|
-00000300  a0 92 f1 07 0c 93 dc f6  25 2b 5c be e3 65 41 a9  |........%+\..eA.|
-00000310  1e 57 6d 9f 28 50 ca 87  2f c7 b0 15 2e 15 d2 cc  |.Wm.(P../.......|
-00000320  4d 0e 42 4c 0a 01 4d 1b  9c d1 17 e7 22 9a 6a a9  |M.BL..M.....".j.|
-00000330  27 0b 7a a7 32 e3 c7 5a  d1 7f f2 1c 45 61 91 a8  |'.z.2..Z....Ea..|
-00000340  e0 e0 49 de b7 2f a6 89  63 94 ed 0e 63 15 6b 4f  |..I../..c...c.kO|
-00000350  fb 62 c4 35 cb 98 89 c2  d1 bc f6 e2 2d 8f 9f 72  |.b.5........-..r|
-00000360  56 79 50 5f cd 73 00 f1  65 bf a4 3f 87 16 03 03  |VyP_.s..e..?....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 f1 a9 e3 69 c6 9b 08  |........ ...i...|
+000002d0  76 5c 45 2f 7d 16 73 79  b2 c5 9f 01 05 13 74 56  |v\E/}.sy......tV|
+000002e0  93 4a dd b2 db 97 61 f9  11 04 01 00 80 81 a1 58  |.J....a........X|
+000002f0  99 41 95 ab 7b cc ac 46  e8 04 3e c9 2d 9c 66 63  |.A..{..F..>.-.fc|
+00000300  0d 80 19 43 85 bc b5 cf  d2 a4 db 9d 28 c2 f4 f7  |...C........(...|
+00000310  fe a1 f3 8f 6b e3 b5 6e  e2 c2 e2 ac b9 0f f8 8d  |....k..n........|
+00000320  29 d2 ba 46 dc 10 ae c2  f3 0f b0 8f 1c e6 22 54  |)..F.........."T|
+00000330  84 9f 10 c9 a5 ae 53 43  15 61 eb 0c ad 49 78 47  |......SC.a...IxG|
+00000340  69 f9 52 9e 58 23 dc df  d7 92 0d f5 50 b2 43 44  |i.R.X#......P.CD|
+00000350  fe 8b 8b b3 ed 69 e7 15  9c 10 20 51 67 bd b9 40  |.....i.... Qg..@|
+00000360  0e 0a f9 65 bf e7 bf 5d  33 5c 71 3d 4c 16 03 03  |...e...]3\q=L...|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
 00000030  16 03 03 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000040  00 00 00 00 00 93 4b 37  8d 57 43 52 77 56 d2 af  |......K7.WCRwV..|
-00000050  7c 56 d0 bf 1e 7b 29 55  3e b7 d0 1c 02 2e 0d de  ||V...{)U>.......|
-00000060  09 66 f2 98 21 57 ab d2  d2 4a 73 c1 c5 fe f1 b8  |.f..!W...Js.....|
-00000070  95 d3 fc 70 ce                                    |...p.|
+00000040  00 00 00 00 00 8a cb 7f  37 ba e5 13 2b db f4 15  |........7...+...|
+00000050  97 6e b5 08 7b 89 16 21  f8 45 1b ef df 17 e0 ad  |.n..{..!.E......|
+00000060  44 12 39 4a e6 fb 78 9d  aa ab 8a 95 2a 02 1d 74  |D.9J..x.....*..t|
+00000070  25 f1 3d 38 21                                    |%.=8!|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 b3 e1 81 3e 0a  |..........@...>.|
-00000010  f8 f3 c6 05 c1 09 f5 73  01 eb 18 1a 05 fa 2f 9b  |.......s....../.|
-00000020  b2 bc c7 44 23 38 ed b9  99 a0 56 7d 8b e4 a5 4b  |...D#8....V}...K|
-00000030  f1 89 45 bc 95 ea 06 a8  48 de 07 bf d5 cb 53 bc  |..E.....H.....S.|
-00000040  50 fa 25 fb d5 79 17 ec  4d be 3d                 |P.%..y..M.=|
+00000000  14 03 03 00 01 01 16 03  03 00 40 1c 73 dd bb 45  |..........@.s..E|
+00000010  89 89 e4 a9 05 db 10 5d  22 20 75 c7 b7 82 c5 64  |.......]" u....d|
+00000020  2e 30 70 fc 0c a7 a8 c0  cb da ab 60 1e 68 12 bc  |.0p........`.h..|
+00000030  47 68 87 01 00 96 e1 f4  a1 a3 20 d1 05 31 7f 79  |Gh........ ..1.y|
+00000040  28 36 f9 5c 24 a7 ba 68  b0 b6 e2                 |(6.\$..h...|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 3e 90 61  a4 f1 53 ac 7b b2 9f 4e  |.....>.a..S.{..N|
-00000020  2c 16 5a 77 8b da 5d 68  5c 8b a8 6d 44 52 f3 ad  |,.Zw..]h\..mDR..|
-00000030  8e ba c8 89 2f 15 03 03  00 30 00 00 00 00 00 00  |..../....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 e5 01 5d ef 4c 0c  |............].L.|
-00000050  07 8f 21 99 60 83 ee 36  13 8e 25 15 32 85 a5 96  |..!.`..6..%.2...|
-00000060  36 90 60 49 4f c7 54 99  dd 76                    |6.`IO.T..v|
+00000010  00 00 00 00 00 5d f7 4e  68 f6 93 58 4d 14 ae 10  |.....].Nh..XM...|
+00000020  14 93 a4 01 58 59 b2 cf  18 da 91 13 5d be da 9e  |....XY......]...|
+00000030  12 a4 2c 02 f9 15 03 03  00 30 00 00 00 00 00 00  |..,......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 71 41 f1 68 4e 97  |..........qA.hN.|
+00000050  b6 30 45 8b b9 89 4c 95  04 da 3e cb 4c ab 05 41  |.0E...L...>.L..A|
+00000060  65 af 4e 60 91 34 8b 07  a3 10                    |e.N`.4....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
index 6b02249..480ff42 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 ab d3 05 5e d0  |....Y...U.....^.|
-00000010  80 0b 87 e9 43 26 e2 c9  28 04 3f eb 68 05 54 3d  |....C&..(.?.h.T=|
-00000020  9b 28 d0 4e d4 d9 25 e5  b0 27 2b 20 89 27 da d5  |.(.N..%..'+ .'..|
-00000030  3d 19 38 63 01 34 f6 43  1b a9 f7 09 12 7d 27 e1  |=.8c.4.C.....}'.|
-00000040  f6 23 b8 39 24 8b 1e c7  a3 2f 07 16 c0 27 00 00  |.#.9$..../...'..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 6a 17 b0 7f 77  |....Y...U..j...w|
+00000010  da 35 bb 45 c1 43 37 52  59 4d 8f 61 1f f8 77 dc  |.5.E.C7RYM.a..w.|
+00000020  fd 9d 55 5d a7 7f 58 4f  dd 3d 42 20 cf e2 65 8f  |..U]..XO.=B ..e.|
+00000030  7a b8 d3 2c 99 cc 31 2f  d7 fa b2 0b 34 2c 72 7e  |z..,..1/....4,r~|
+00000040  86 a1 c6 e7 b7 55 26 1f  9a 69 43 63 c0 27 00 00  |.....U&..iCc.'..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,42 +54,42 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 ec 71 cc fb 07 bd 0f  |........ .q.....|
-000002d0  6b e0 e1 27 7f 62 59 06  09 3c 09 bc b1 c9 09 93  |k..'.bY..<......|
-000002e0  e9 b0 a4 5b f3 be 14 d1  3c 04 01 00 80 a9 c7 98  |...[....<.......|
-000002f0  ea ac 6a 9b 49 7c 72 45  4d 5c c8 4c d6 56 64 1b  |..j.I|rEM\.L.Vd.|
-00000300  44 7f 13 4f 2a ed e9 6b  c7 c0 a2 25 3b 7a 99 f4  |D..O*..k...%;z..|
-00000310  93 84 35 78 72 21 ca f6  29 1b 60 d7 f6 bd 31 5b  |..5xr!..).`...1[|
-00000320  7a fb 57 20 30 cc e6 90  07 b2 0e 08 82 86 56 a7  |z.W 0.........V.|
-00000330  55 00 fd f4 ce f4 b1 74  27 e9 0a 28 1c bc 56 47  |U......t'..(..VG|
-00000340  f7 18 3e 9e 9c 45 2d 1d  82 a8 66 51 27 25 be ec  |..>..E-...fQ'%..|
-00000350  cd 9e 83 89 7e e0 e3 0f  3b 7b 32 f2 26 7b 30 c8  |....~...;{2.&{0.|
-00000360  c1 e3 7b 4c f4 14 d5 51  ea b7 45 7a 59 16 03 03  |..{L...Q..EzY...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 35 8c 3a f9 8a 04 e7  |........ 5.:....|
+000002d0  2e dd 2c 82 05 62 da 91  3f 60 2b 0d a8 4d ec 50  |..,..b..?`+..M.P|
+000002e0  d1 b1 e0 f6 34 38 e5 7c  11 04 01 00 80 97 25 9e  |....48.|......%.|
+000002f0  22 b3 40 b2 b9 ec 0f 0e  44 92 11 82 06 70 26 23  |".@.....D....p&#|
+00000300  38 b5 fe de 08 32 cd 8e  e5 d7 19 3a ba 40 76 74  |8....2.....:.@vt|
+00000310  22 cf 19 dd cc 33 cf 34  a9 3a d4 82 e8 92 79 23  |"....3.4.:....y#|
+00000320  c1 14 10 79 08 65 43 e9  02 93 32 c8 5f a4 68 ed  |...y.eC...2._.h.|
+00000330  24 b7 aa 4c 71 4e 01 63  74 2a f5 36 1a d0 15 95  |$..LqN.ct*.6....|
+00000340  10 9c 46 87 75 16 55 88  b7 38 14 10 1c b8 34 84  |..F.u.U..8....4.|
+00000350  4f 4a 99 0f 17 95 26 a4  31 e3 8f 71 5b 92 f3 27  |OJ....&.1..q[..'|
+00000360  df d7 c4 6d 34 8d 14 e7  8e 62 ae 27 12 16 03 03  |...m4....b.'....|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
 00000030  16 03 03 00 50 00 00 00  00 00 00 00 00 00 00 00  |....P...........|
-00000040  00 00 00 00 00 76 d8 c4  58 a1 94 11 ab 19 4c 7b  |.....v..X.....L{|
-00000050  7c 34 d1 b6 8b 7f a2 96  41 e6 e9 98 d8 55 62 2b  ||4......A....Ub+|
-00000060  56 54 2a 65 25 f0 fa 15  ac cb b7 cc 3b 59 8b 99  |VT*e%.......;Y..|
-00000070  e9 be 9e fe 56 97 07 ae  39 38 a7 f4 f0 d0 e9 f5  |....V...98......|
-00000080  33 de 20 a6 04                                    |3. ..|
+00000040  00 00 00 00 00 6d a8 40  a4 2f 8d ea bb a0 fb f3  |.....m.@./......|
+00000050  a7 38 78 1b 25 57 5c 8a  c8 e6 e6 be e2 78 78 c1  |.8x.%W\......xx.|
+00000060  dc ec ca 48 9a 85 56 6b  da 40 bd 0b cc 0a aa 08  |...H..Vk.@......|
+00000070  02 31 57 31 c2 57 ff ac  57 7e e5 08 3a 14 b0 11  |.1W1.W..W~..:...|
+00000080  fb 46 83 db 37                                    |.F..7|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 8c 0f 2a be cd  |..........P..*..|
-00000010  30 f7 46 cf 58 5b 38 88  86 5e d1 33 b1 61 d6 95  |0.F.X[8..^.3.a..|
-00000020  13 c7 e7 f2 fb bc 37 e5  a3 db ac a7 74 49 00 89  |......7.....tI..|
-00000030  db 94 25 aa 00 b6 b2 34  0a dd 97 bf fa cf 33 6e  |..%....4......3n|
-00000040  6e f7 ab bf 70 a6 85 91  9b 4f f2 86 15 83 60 0d  |n...p....O....`.|
-00000050  79 9e 11 51 17 a6 6f 06  2f 98 bc                 |y..Q..o./..|
+00000000  14 03 03 00 01 01 16 03  03 00 50 b7 d0 f9 1f 96  |..........P.....|
+00000010  64 b8 99 14 da c9 ae d9  40 ff 8f 3f 69 9d bf 56  |d.......@..?i..V|
+00000020  ac 9d 15 d7 84 82 bb e9  1e f3 15 1a b3 3a 96 58  |.............:.X|
+00000030  9f a7 9e 7a fb 50 5f f2  9d 46 8d ed fc cb 3b 2c  |...z.P_..F....;,|
+00000040  6e fd 5a fc d5 8f 8b 11  f8 28 3d c7 e2 36 c4 1b  |n.Z......(=..6..|
+00000050  da ce ec b2 89 f1 80 a5  ec 7f a2                 |...........|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000010  00 00 00 00 00 c3 c9 23  7b bd 57 1a 29 5f ac f6  |.......#{.W.)_..|
-00000020  8d bb 90 bb 48 8a 9a 75  65 3b 5b 52 c0 ee 0e 24  |....H..ue;[R...$|
-00000030  43 f6 62 1f 1e 51 36 4e  3e a3 e4 96 d8 2b d8 a7  |C.b..Q6N>....+..|
-00000040  d0 18 97 d7 1e 15 03 03  00 40 00 00 00 00 00 00  |.........@......|
-00000050  00 00 00 00 00 00 00 00  00 00 c0 c8 9f 7d df b1  |.............}..|
-00000060  78 72 b5 3d 0d 3e d9 88  38 c2 42 eb 2b 4d e0 b3  |xr.=.>..8.B.+M..|
-00000070  d7 69 19 31 57 16 7c 0a  bb 24 5b 9c 9b c2 4b b9  |.i.1W.|..$[...K.|
-00000080  55 ef ad 2c c1 eb 9b 59  06 5a                    |U..,...Y.Z|
+00000010  00 00 00 00 00 78 0e 09  23 37 5d ad e5 97 da 83  |.....x..#7].....|
+00000020  93 90 d8 dc 96 5a 61 85  8c 8b e8 35 46 46 ac ac  |.....Za....5FF..|
+00000030  42 fa ee e1 88 41 bd 1c  9c 6a 0c 00 29 cc a4 56  |B....A...j..)..V|
+00000040  40 27 8f 6c e3 15 03 03  00 40 00 00 00 00 00 00  |@'.l.....@......|
+00000050  00 00 00 00 00 00 00 00  00 00 51 8d 6f 62 be c4  |..........Q.ob..|
+00000060  aa d0 f1 83 04 67 7e c2  0a 8b 50 32 71 17 87 95  |.....g~...P2q...|
+00000070  a6 31 f6 3d 3f a8 14 00  5d e0 5b c1 db b4 fa 79  |.1.=?...].[....y|
+00000080  01 0f 63 0b fe 8c c9 e1  b4 6b                    |..c......k|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
index 64f999a..0ddfbdc 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
@@ -1,17 +1,17 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 67 01 00 00  63 03 03 00 00 00 00 00  |....g...c.......|
+00000000  16 03 01 00 6b 01 00 00  67 03 03 00 00 00 00 00  |....k...g.......|
 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 02 cc a8  |................|
-00000030  01 00 00 38 00 05 00 05  01 00 00 00 00 00 0a 00  |...8............|
+00000030  01 00 00 3c 00 05 00 05  01 00 00 00 00 00 0a 00  |...<............|
 00000040  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
-00000050  00 00 0d 00 0e 00 0c 04  01 04 03 05 01 05 03 02  |................|
-00000060  01 02 03 ff 01 00 01 00  00 12 00 00              |............|
+00000050  00 00 0d 00 12 00 10 04  01 04 03 05 01 05 03 06  |................|
+00000060  01 06 03 02 01 02 03 ff  01 00 01 00 00 12 00 00  |................|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 45 f5 61 06 a8  |....Y...U..E.a..|
-00000010  4e ce c0 32 d6 af fb 12  5e c8 6c 06 ac c9 d7 e4  |N..2....^.l.....|
-00000020  02 49 09 b9 42 ee ae fa  e4 52 18 20 12 3a 53 7d  |.I..B....R. .:S}|
-00000030  11 cf 13 13 a3 f8 42 c3  98 bb bc a6 10 3e f4 13  |......B......>..|
-00000040  a5 a2 fd ef aa b3 01 3c  cb 8a 3a 2c cc a8 00 00  |.......<..:,....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 34 5a e3 34 22  |....Y...U..4Z.4"|
+00000010  a6 72 28 26 73 2d 3c 9e  f1 39 88 13 07 dd 75 7c  |.r(&s-<..9....u||
+00000020  00 58 04 bc 18 28 d0 75  4d 80 96 20 46 c7 3c b7  |.X...(.uM.. F.<.|
+00000030  05 16 0d ef 32 51 ab 46  47 95 4b 49 e8 cc 8b 47  |....2Q.FG.KI...G|
+00000040  d2 41 e8 05 9a de 5a c3  05 7d d4 b2 cc a8 00 00  |.A....Z..}......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -51,31 +51,31 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 57 53 06 53 e5 14 06  |........ WS.S...|
-000002d0  df 26 9d 3a 06 dc a9 d5  49 d3 3f 5f 7b c2 ab 77  |.&.:....I.?_{..w|
-000002e0  fd a1 fe 28 dc 54 36 06  22 04 01 00 80 da 23 f5  |...(.T6.".....#.|
-000002f0  19 de e8 d2 a9 79 b8 37  3d c0 8c ae f6 7c d5 d9  |.....y.7=....|..|
-00000300  87 ab 6b 3f 76 7c 5f 94  be 11 55 a3 78 66 1e e3  |..k?v|_...U.xf..|
-00000310  f3 11 3d 1a f7 02 26 a4  a6 cd 7c fe 87 0d 68 a1  |..=...&...|...h.|
-00000320  50 e8 7e 94 41 bd 5b 74  d0 6d 3b 6c ef ee 88 2d  |P.~.A.[t.m;l...-|
-00000330  60 0a a9 53 cf 1f f4 03  a3 54 e5 91 36 50 62 54  |`..S.....T..6PbT|
-00000340  5f e6 e5 36 63 58 ba 7b  bb 3a 79 59 58 08 a8 f2  |_..6cX.{.:yYX...|
-00000350  f5 1e 35 f8 f5 0f 7f 19  e7 7f 5f 56 e2 50 6d 8c  |..5......._V.Pm.|
-00000360  da 45 70 60 0d 58 32 94  e7 a0 f7 da 93 16 03 03  |.Ep`.X2.........|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 1a 1c c4 a1 b6 04 70  |........ ......p|
+000002d0  b8 b9 cd 26 b1 c0 74 56  6c b5 5c ff e7 20 79 74  |...&..tVl.\.. yt|
+000002e0  f7 84 d5 8d 62 57 fa 40  49 04 01 00 80 1b d8 2a  |....bW.@I......*|
+000002f0  60 af a6 8c 2d 7e 23 be  b8 53 c8 8e 32 b2 29 49  |`...-~#..S..2.)I|
+00000300  8c 54 c5 fc 7b 2e e4 b9  6c c3 26 21 84 89 2e cd  |.T..{...l.&!....|
+00000310  7c c1 e0 1e 16 dc 8f 76  1e c2 65 f0 c2 21 6e f7  ||......v..e..!n.|
+00000320  cf 91 f9 d5 c5 bf 33 5e  4f bb 8a 85 86 dd 10 c0  |......3^O.......|
+00000330  85 22 e6 c0 36 0b 67 48  10 0a 04 49 1d dd aa 97  |."..6.gH...I....|
+00000340  11 4f 80 f0 66 cd 82 85  e1 fa 0c b6 3d e7 bd 16  |.O..f.......=...|
+00000350  20 82 cd cc 44 bb 67 47  2a db 9f 22 1b 9e cc 13  | ...D.gG*.."....|
+00000360  e2 de d1 1d 9f 16 0e 6f  01 5e de f4 72 16 03 03  |.......o.^..r...|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 9d 2f a6  b7 21 56 ad 38 a8 31 20  |.... ./..!V.8.1 |
-00000040  0b 2e dc 3f 8a 34 64 de  81 0e d3 a5 b1 c1 fc 05  |...?.4d.........|
-00000050  18 d9 3e 77 35                                    |..>w5|
+00000030  16 03 03 00 20 3a 2e f4  52 80 92 77 cb e3 54 43  |.... :..R..w..TC|
+00000040  cb d5 ba c4 62 e4 77 81  eb fe fc f1 88 c6 e6 46  |....b.w........F|
+00000050  7f d9 23 38 e4                                    |..#8.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 a8 82 60 8a ef  |.......... ..`..|
-00000010  31 55 42 e9 1d 33 0e d8  a9 b1 43 85 1c 04 7b 20  |1UB..3....C...{ |
-00000020  81 df 03 e9 fd c0 f7 32  b9 b3 31                 |.......2..1|
+00000000  14 03 03 00 01 01 16 03  03 00 20 21 4e a1 16 d0  |.......... !N...|
+00000010  35 9f 19 c6 cc 64 64 f7  a0 25 13 3b 97 75 81 9f  |5....dd..%.;.u..|
+00000020  2f d3 30 d9 02 ad c7 72  8d 32 20                 |/.0....r.2 |
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 ef 72 f7  1b 26 1a 47 99 f9 4c e7  |......r..&.G..L.|
-00000010  be 8e ab c5 8e ea 8c c6  60 6c 10 15 03 03 00 12  |........`l......|
-00000020  2c f4 39 e3 3a 74 a4 3c  72 63 77 e8 82 cf a9 e2  |,.9.:t.<rcw.....|
-00000030  2b 04                                             |+.|
+00000000  17 03 03 00 16 af 57 12  aa e5 9b e4 c3 54 d9 a8  |......W......T..|
+00000010  af ce 8c 28 39 ba df 5d  71 9d 0f 15 03 03 00 12  |...(9..]q.......|
+00000020  69 3f 95 18 31 04 5b 17  2a cf 53 9c ca 2d 07 7f  |i?..1.[.*.S..-..|
+00000030  c1 f8                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
index 74282d4..b743b56 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 ac bf 85 b8 5f  |....Q...M......_|
-00000010  56 44 a0 c5 3b 20 77 71  af de 34 bc 79 a0 a4 a7  |VD..; wq..4.y...|
-00000020  fa 2e cf b5 ee c5 a7 a2  5e 11 48 20 05 89 5e a6  |........^.H ..^.|
-00000030  cd ad 91 e4 be c3 c3 6c  6a 0e 1d ab 27 03 5e 0f  |.......lj...'.^.|
-00000040  05 9d ef b0 63 8d 2d b6  29 08 66 e3 00 05 00 00  |....c.-.).f.....|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 90 26 c2 6e 52  |....Q...M...&.nR|
+00000010  59 b2 e8 f1 c5 fc 4d 59  13 76 43 4e a4 ab 0b 33  |Y.....MY.vCN...3|
+00000020  96 d0 4e 89 bd 1e bd 89  f6 2b d7 20 39 94 41 68  |..N......+. 9.Ah|
+00000030  81 74 78 60 e1 5f f7 7d  e3 9d 81 f1 62 bd 45 67  |.tx`._.}....b.Eg|
+00000040  51 50 bd 84 76 70 52 c3  ce 32 90 51 00 05 00 00  |QP..vpR..2.Q....|
 00000050  05 ff 01 00 01 00 16 03  03 02 59 0b 00 02 55 00  |..........Y...U.|
 00000060  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
 00000070  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
@@ -64,15 +64,15 @@
 00000060  c5 70 0f 08 83 48 e9 48  ef 6e 50 8b 05 7e e5 84  |.p...H.H.nP..~..|
 00000070  25 fa 55 c7 ae 31 02 27  00 ef 3f 98 86 20 12 89  |%.U..1.'..?.. ..|
 00000080  91 59 28 b4 f7 d7 af d2  69 61 35 14 03 03 00 01  |.Y(.....ia5.....|
-00000090  01 16 03 03 00 24 e1 ef  77 60 cf 7a 44 79 74 59  |.....$..w`.zDytY|
-000000a0  ff 81 72 b9 b5 f5 97 af  60 59 78 f5 01 49 2d bb  |..r.....`Yx..I-.|
-000000b0  4a ec 98 1f f5 31 f4 00  a2 f3                    |J....1....|
+00000090  01 16 03 03 00 24 4b 7c  05 1b 5d ed 28 c0 ce db  |.....$K|..].(...|
+000000a0  c9 1d bb e8 a1 94 d7 30  ac aa 54 08 2a 82 a2 a0  |.......0..T.*...|
+000000b0  52 e7 cb 32 0f c2 f8 ad  f3 c9                    |R..2......|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 52 fd a3 51 aa  |..........$R..Q.|
-00000010  ee 9d 4d be 8c 08 32 f6  f7 4a a5 26 26 6c b2 5a  |..M...2..J.&&l.Z|
-00000020  49 7f 31 7d 44 b1 83 67  19 4a e3 07 7d 59 34     |I.1}D..g.J..}Y4|
+00000000  14 03 03 00 01 01 16 03  03 00 24 ad ef e3 a0 c4  |..........$.....|
+00000010  2c a0 ca 82 a6 f0 eb 8f  73 f3 48 11 0f 1f cc 6f  |,.......s.H....o|
+00000020  6f 63 fa d8 9d 47 6b b2  ab 3e fe bc 0e 44 ce     |oc...Gk..>...D.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a 61 73 4d  86 b2 a1 36 b2 3e b0 1d  |.....asM...6.>..|
-00000010  6a b9 8a 8b 00 e0 3a d9  7e 23 c7 83 72 97 28 15  |j.....:.~#..r.(.|
-00000020  03 03 00 16 4a 8a 04 00  0a b2 75 80 20 ad 76 2a  |....J.....u. .v*|
-00000030  88 16 56 e6 4a a5 c0 ea  c7 0c                    |..V.J.....|
+00000000  17 03 03 00 1a e7 90 92  8b a5 a6 4f 22 97 2f 23  |...........O"./#|
+00000010  f1 3c 54 65 2c 14 7e fd  1d 8f c7 76 97 e8 f8 15  |.<Te,.~....v....|
+00000020  03 03 00 16 c0 c9 cc 98  62 c6 ac 36 0f a5 2d a5  |........b..6..-.|
+00000030  73 9a 9c 0f 26 5a f6 89  3b c9                    |s...&Z..;.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
index 8a9ac36..9304adf 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 16 d2 11 2e d6  |....Y...U.......|
-00000010  62 0c 5e 5c 9b 1f d2 31  87 b3 43 3e cd 47 4f f1  |b.^\...1..C>.GO.|
-00000020  0b a9 d1 4f f1 2a 42 5d  35 e0 ce 20 f2 f3 45 4b  |...O.*B]5.. ..EK|
-00000030  98 2f 80 06 49 9a c3 4f  3f 70 0d e5 9a 2a 2e ff  |./..I..O?p...*..|
-00000040  34 1b 0e 30 2c 85 52 e1  84 8c 3c dc cc a8 00 00  |4..0,.R...<.....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 f1 85 19 85 1e  |....Y...U.......|
+00000010  f5 97 e1 e6 08 15 6f a9  05 93 6f b9 41 ad 11 ae  |......o...o.A...|
+00000020  92 90 5e 00 97 46 42 af  2f b0 5d 20 b7 f3 e7 76  |..^..FB./.] ...v|
+00000030  20 e4 c2 99 6e ba 87 79  21 5c 5c 62 d9 1f 08 88  | ...n..y!\\b....|
+00000040  e1 1f 05 0c 31 9c d5 b3  65 19 26 4c cc a8 00 00  |....1...e.&L....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,178 +54,126 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 63 85 d4 43 2a d6 9f  |........ c..C*..|
-000002d0  2f 1f 0c 73 fe dc 96 1e  51 50 a5 0d 5e fd b0 5b  |/..s....QP..^..[|
-000002e0  a5 88 2a cd 1e bf c1 ec  4d 04 01 00 80 90 fc 48  |..*.....M......H|
-000002f0  53 eb 1b bc ec 39 be ae  60 4d c9 d1 49 eb 97 cf  |S....9..`M..I...|
-00000300  94 53 75 30 84 35 ff 0c  f6 ad 9f 24 98 70 2b d3  |.Su0.5.....$.p+.|
-00000310  45 0a 7f 25 ca a3 eb 37  5a a5 97 f1 78 8b b6 02  |E..%...7Z...x...|
-00000320  92 f9 12 9e 90 52 36 0e  40 15 76 de 37 02 c5 22  |.....R6.@.v.7.."|
-00000330  44 8f a4 fc f9 ac 88 88  ad 0c 9b f6 0e d6 9f f3  |D...............|
-00000340  68 cb f1 41 dd 2d c2 71  b6 43 36 12 d2 35 1c 9a  |h..A.-.q.C6..5..|
-00000350  a9 72 ea af a9 9e 77 19  16 86 be 3e ec 5f 5a 53  |.r....w....>._ZS|
-00000360  f8 38 27 7f 08 2a ae 68  e0 17 31 df 9b 16 03 03  |.8'..*.h..1.....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 f8 4d 81 d8 29 29 e9  |........ .M..)).|
+000002d0  2a 96 44 4b e3 d2 95 11  19 7a d5 26 ed 60 f2 d8  |*.DK.....z.&.`..|
+000002e0  e7 7d 96 9e 06 9f 37 f8  3e 04 01 00 80 51 70 fb  |.}....7.>....Qp.|
+000002f0  66 2e 1f 40 97 95 47 34  e5 69 8b a7 f6 d2 d1 71  |f..@..G4.i.....q|
+00000300  0a 4c 34 d8 4f 8a 59 fc  a0 93 db 10 77 12 a9 52  |.L4.O.Y.....w..R|
+00000310  b6 be 1b 48 2c 56 9a ad  89 57 58 30 90 03 bb 46  |...H,V...WX0...F|
+00000320  df 8a 4b 81 9a 14 6a a0  c9 60 76 e5 c6 73 da 35  |..K...j..`v..s.5|
+00000330  e5 98 81 31 6c c4 ff 41  0c b1 7c 6e fd 82 75 de  |...1l..A..|n..u.|
+00000340  d8 84 db 3e fa 80 bc a8  6a 77 6f c9 9b 78 1a 0a  |...>....jwo..x..|
+00000350  dc 7b f0 65 4d 0f 14 b2  78 e8 db fb ee ca 74 83  |.{.eM...x.....t.|
+00000360  2c d5 78 1e 48 09 17 0a  d8 08 de f9 9d 16 03 03  |,.x.H...........|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 b1 f2 9a  ca 02 d3 ac 26 f5 32 03  |.... .......&.2.|
-00000040  4c b6 de cb f2 a3 11 19  eb c3 e0 e9 3b 8e 99 7d  |L...........;..}|
-00000050  c2 f3 d0 6d 4d                                    |...mM|
+00000030  16 03 03 00 20 c9 e3 4a  a0 72 57 a2 c6 8d e9 98  |.... ..J.rW.....|
+00000040  28 8d 40 22 6e ed 46 50  0d 08 38 b4 b0 6e a6 0b  |(.@"n.FP..8..n..|
+00000050  16 57 3f 6a 96                                    |.W?j.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 c5 d4 b1 e2 0f  |.......... .....|
-00000010  37 ad d5 c1 1a 6c 7f da  5f 25 e3 bd 20 1d 6e 58  |7....l.._%.. .nX|
-00000020  27 7a 07 55 76 11 76 72  1b 28 9e                 |'z.Uv.vr.(.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 28 1b b9 e9 46  |.......... (...F|
+00000010  3d 61 64 fe 84 b5 ea ff  79 e3 b9 5f 7e 1d 9c e1  |=ad.....y.._~...|
+00000020  84 0f 17 9b be 67 0e b7  71 b3 de                 |.....g..q..|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 3d 89 e4  a6 38 75 31 c2 08 3d 86  |.....=...8u1..=.|
-00000010  45 ed 8d c4 49 c4 da 54  3b 8f e3                 |E...I..T;..|
+00000000  17 03 03 00 16 0d d9 98  93 d7 c2 0e 48 53 34 1c  |............HS4.|
+00000010  b6 58 70 58 af 24 7c 3e  43 55 8a                 |.XpX.$|>CU.|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 aa 85 e4  64 46 2f 8e dc 89 3e ef  |........dF/...>.|
-00000010  6d 9e 1a af 53 3b a0 81  c2                       |m...S;...|
+00000000  16 03 03 00 14 96 19 2b  56 4c 10 ea 1a c4 6e e3  |.......+VL....n.|
+00000010  95 31 61 ed 22 ce 87 b2  bb                       |.1a."....|
 >>> Flow 7 (client to server)
-00000000  16 03 03 00 ad c3 12 d1  1a b2 88 da c1 0b 5a 32  |..............Z2|
-00000010  cf 05 35 53 ce 5d d8 42  cd 99 7e e7 9f 62 b8 35  |..5S.].B..~..b.5|
-00000020  9e f5 b5 a6 15 fd 82 26  9b 6a fe 3b 8e c0 43 27  |.......&.j.;..C'|
-00000030  1c 56 37 d1 6f d9 2c a6  a8 e8 b4 50 64 80 ae 5c  |.V7.o.,....Pd..\|
-00000040  ed eb a6 58 58 52 cf 32  de 1d be 80 69 63 38 a6  |...XXR.2....ic8.|
-00000050  12 4e 11 9b 50 aa 4b 10  f7 ad 6f 5b 08 c6 cc bd  |.N..P.K...o[....|
-00000060  94 42 64 90 c7 33 58 65  18 c5 a7 66 ce dd 83 8b  |.Bd..3Xe...f....|
-00000070  b0 15 8a 61 26 c7 eb 15  4b 6c 0b 15 45 33 2a 01  |...a&...Kl..E3*.|
-00000080  ea 13 5a 20 52 16 15 a0  70 8f 86 dc 28 50 bb e4  |..Z R...p...(P..|
-00000090  9d 01 f4 c9 7f 27 5a 54  3f 42 34 c9 5c 04 3f a3  |.....'ZT?B4.\.?.|
-000000a0  6a 5c a1 3f 03 7c fc 57  94 9b 3e 76 65 bf 78 40  |j\.?.|.W..>ve.x@|
-000000b0  b1 4f                                             |.O|
+00000000  16 03 03 00 b1 a7 01 a1  b3 16 21 88 5a 74 bd a0  |..........!.Zt..|
+00000010  58 fa d2 fa ba e3 a2 21  ae b6 92 28 a4 90 e7 f7  |X......!...(....|
+00000020  fc 1b 6e dd 12 19 18 30  5d 6e fe be b7 12 16 fc  |..n....0]n......|
+00000030  26 27 8d e0 8c 18 25 3e  97 fa 5b 3c 06 c0 ee 49  |&'....%>..[<...I|
+00000040  6e 6f 29 28 ac 46 02 92  38 c3 e1 1b d8 cc 6e 23  |no)(.F..8.....n#|
+00000050  a1 4e 67 58 3e 33 45 ed  85 da f1 e6 76 0d ab f5  |.NgX>3E.....v...|
+00000060  25 a7 a1 ac 67 f5 b7 14  52 04 57 6b e7 7f ac 5e  |%...g...R.Wk...^|
+00000070  bb c4 3f 0b 3b 54 86 a0  9c 4f 9b b5 1e 9d f5 8a  |..?.;T...O......|
+00000080  0b 62 fd 89 84 16 ee 13  49 40 32 3d 90 d1 4a 11  |.b......I@2=..J.|
+00000090  ea 13 84 b8 18 4c 50 9b  18 54 ab f1 b8 77 e7 b2  |.....LP..T...w..|
+000000a0  8b 7a 85 34 47 0a 83 fb  86 f2 94 e6 4a 17 db a8  |.z.4G.......J...|
+000000b0  31 61 8e e7 d8 f9                                 |1a....|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 33 ef 78  c8 2d 94 4b e3 b8 ea eb  |.....3.x.-.K....|
-00000010  67 1e 6c 10 98 25 5f df  ce 46 4c 13 77 ec d1 b1  |g.l..%_..FL.w...|
-00000020  e9 e2 c9 b0 de 9c ce 40  d0 d9 6f a5 fb a6 69 1f  |.......@..o...i.|
-00000030  9f 53 68 6c ab f8 f0 10  4a c9 43 f0 ad 61 59 01  |.Shl....J.C..aY.|
-00000040  b2 90 97 9e cf 62 64 a5  46 b2 27 2f 1e b8 33 24  |.....bd.F.'/..3$|
-00000050  ed 7e 6b 5a dd 45 4d 00  61 a3 7e 22 5e bc 02 af  |.~kZ.EM.a.~"^...|
-00000060  5a a0 73 fb c5 1c 0f 11  f6 70 5f cc 9e 1c fa 3c  |Z.s......p_....<|
-00000070  13 0d 8b 03 4c 3b d5 5a  02 7b 95 64 ae cb 2f 50  |....L;.Z.{.d../P|
-00000080  e7 e1 32 13 72 96 16 03  03 02 69 f0 60 6a b8 fb  |..2.r.....i.`j..|
-00000090  50 6e f9 f2 65 d0 73 90  f7 55 0d bc 3a 66 72 32  |Pn..e.s..U..:fr2|
-000000a0  b7 32 ad 1d de 18 04 90  55 70 2d b8 c9 3f 4b 2f  |.2......Up-..?K/|
-000000b0  37 98 1c 4e c1 78 c1 ed  1f e2 bf 50 78 40 04 10  |7..N.x.....Px@..|
-000000c0  b8 55 48 29 26 b0 a4 4d  ea aa 45 65 b4 21 93 ed  |.UH)&..M..Ee.!..|
-000000d0  49 4c 1d d9 77 33 38 2e  14 92 b4 e3 06 ce fe 51  |IL..w38........Q|
-000000e0  6a 19 1c aa e9 a6 7d fa  45 86 66 1a 6e bb 01 01  |j.....}.E.f.n...|
-000000f0  82 86 89 86 81 ce 0a 93  1a b2 f1 90 71 7a 43 fa  |............qzC.|
-00000100  b1 03 24 75 a1 48 f8 ee  a0 b4 c0 18 ff 81 95 2a  |..$u.H.........*|
-00000110  aa 74 87 39 da 23 ba ab  33 6b 63 ee df 2b f1 d1  |.t.9.#..3kc..+..|
-00000120  1a 9a 4a 0d ef de 68 13  28 81 49 d5 c6 08 57 a9  |..J...h.(.I...W.|
-00000130  d7 5e 56 a4 ec 81 42 de  28 39 51 7d 3a 66 cf a7  |.^V...B.(9Q}:f..|
-00000140  f7 81 7a b2 a7 09 b3 24  a6 b0 a5 cc 96 24 30 b2  |..z....$.....$0.|
-00000150  5b 94 1b ef 70 dd 7f bc  63 2f 7b bc 80 70 9e 9f  |[...p...c/{..p..|
-00000160  01 c9 20 ab 35 53 7c 3b  d6 70 d9 1d 9a f6 e8 76  |.. .5S|;.p.....v|
-00000170  f5 46 f8 b1 10 46 a9 eb  da 7b 80 cc 74 18 f9 30  |.F...F...{..t..0|
-00000180  56 1a cb 4e 60 2a b3 9f  35 fe a9 b8 b8 76 02 a7  |V..N`*..5....v..|
-00000190  4e f9 43 c9 52 70 6a fd  9c 3e dd c4 3f 28 08 19  |N.C.Rpj..>..?(..|
-000001a0  28 ed f9 44 e3 d1 b9 53  7e b7 cd 1b e9 11 c8 9f  |(..D...S~.......|
-000001b0  35 ed ab e3 5e 26 e8 49  7a 13 5c 20 9a b7 a0 95  |5...^&.Iz.\ ....|
-000001c0  60 0f 54 68 5c a8 c9 1d  37 0b 9f f6 61 3b fe 4c  |`.Th\...7...a;.L|
-000001d0  dc 4f 11 98 0c 7a b7 32  0b 50 e2 cd a7 59 bf 05  |.O...z.2.P...Y..|
-000001e0  a2 8a 51 33 23 ab 99 49  23 97 42 3b 0f 1c 39 b1  |..Q3#..I#.B;..9.|
-000001f0  43 c4 01 aa f9 f8 54 d7  2c b4 ef 33 f3 05 13 d0  |C.....T.,..3....|
-00000200  8d 81 06 23 d3 38 cb 3a  6b 37 f0 4d 1f be ed 0c  |...#.8.:k7.M....|
-00000210  b7 58 00 3a bd 74 02 a4  f4 b4 fc fd b8 fa 89 15  |.X.:.t..........|
-00000220  01 46 49 52 47 f1 4c 94  ee de 00 a1 25 aa b4 9b  |.FIRG.L.....%...|
-00000230  f6 b4 23 a1 0d fd 00 5a  de 45 38 ee 69 17 6f c3  |..#....Z.E8.i.o.|
-00000240  0b ed c5 3b b1 7d b1 2c  a4 8f ed 30 44 9a 0b 51  |...;.}.,...0D..Q|
-00000250  34 12 cc 6a 09 e4 74 ec  11 94 4b ba ce 72 93 64  |4..j..t...K..r.d|
-00000260  07 c8 ff 78 6e 1a bd 5e  26 15 a7 e8 72 90 71 a9  |...xn..^&...r.q.|
-00000270  0a bb cf 25 40 1d 20 a7  d7 b3 46 4b 53 6c c2 50  |...%@. ...FKSl.P|
-00000280  c7 7b 58 e1 3c df 6d db  28 71 15 f9 84 b7 ad b0  |.{X.<.m.(q......|
-00000290  9f e9 7a 08 5d 85 7a dd  bc c0 62 2e 6a d0 63 6a  |..z.].z...b.j.cj|
-000002a0  e2 46 6b 80 68 cf e5 a7  9e 60 42 8a 17 54 9c ec  |.Fk.h....`B..T..|
-000002b0  80 9b 81 80 7e 6f 33 8c  d1 be 95 30 f2 a9 19 f8  |....~o3....0....|
-000002c0  36 2c 8e 89 c2 5a b4 04  2e 12 05 21 3b 4f 42 26  |6,...Z.....!;OB&|
-000002d0  d1 98 11 f4 17 c2 a3 06  54 37 31 8e ca 9b 07 62  |........T71....b|
-000002e0  79 95 b8 fd 49 aa 60 5b  03 7d 60 50 b6 2f 3b 0a  |y...I.`[.}`P./;.|
-000002f0  5d c2 9f 92 16 03 03 00  bc ba f6 73 85 34 20 c4  |]..........s.4 .|
-00000300  b3 a4 15 01 fe 37 b3 b4  57 a5 b5 26 0c 64 2b 3e  |.....7..W..&.d+>|
-00000310  07 d3 e4 59 a8 64 3f fd  15 24 24 70 61 77 9b 96  |...Y.d?..$$paw..|
-00000320  c6 4b 79 2e a8 a7 c4 ac  5e cd 6e 8f 30 e5 3f f8  |.Ky.....^.n.0.?.|
-00000330  08 22 cb de 5f 8c b8 dc  07 4b 79 ec 41 41 20 20  |.".._....Ky.AA  |
-00000340  02 f6 4e 98 a3 5e 38 e2  5a d9 4a 2d 2e 3b 29 13  |..N..^8.Z.J-.;).|
-00000350  26 dc 4e eb a5 5e a3 b6  6f 16 75 b3 9e 63 4e 8e  |&.N..^..o.u..cN.|
-00000360  00 c1 46 30 fc 25 f9 05  86 ed 00 87 f2 6b 5c 18  |..F0.%.......k\.|
-00000370  69 e5 5c 32 9e 15 d2 47  9e 0e d8 c1 7a 9d 45 7a  |i.\2...G....z.Ez|
-00000380  76 4a ef 8d b5 60 7d 4d  fa 99 8f c5 58 18 ad a2  |vJ...`}M....X...|
-00000390  93 c1 36 85 39 73 e1 7b  46 be 69 de 88 fa 68 8e  |..6.9s.{F.i...h.|
-000003a0  be d1 48 bc 7b 29 2a 21  ba 60 60 58 51 c2 03 66  |..H.{)*!.``XQ..f|
-000003b0  51 9a 4e 70 06 16 03 03  00 3a c5 ed 8d 5d b9 c0  |Q.Np.....:...]..|
-000003c0  a2 07 15 c3 ef 76 ff fb  ca f6 b6 4b ab a5 7a 80  |.....v.....K..z.|
-000003d0  a9 2e 43 d0 d2 f1 d9 96  61 ff 43 59 3d d1 82 57  |..C.....a.CY=..W|
-000003e0  68 d7 c8 3a 5f 86 4a 2e  00 8f 3d 0e 73 49 c6 4a  |h..:_.J...=.sI.J|
-000003f0  81 4e ec e2 16 03 03 00  14 d5 5f c3 d2 9c 13 36  |.N........_....6|
-00000400  cb 22 23 3d e4 03 5b b9  26 66 cf 79 7c           |."#=..[.&f.y||
+00000000  16 03 03 00 81 8b 09 74  4a 5b 74 ef c4 91 26 84  |.......tJ[t...&.|
+00000010  25 33 c2 f7 05 1c 13 cf  00 ba 54 dd 16 e9 f3 4d  |%3........T....M|
+00000020  80 f5 1f f9 9b 7e a8 a9  60 f1 d6 be f9 c1 75 b0  |.....~..`.....u.|
+00000030  1b 98 c4 d2 f0 69 c5 d5  d9 07 dd 19 56 4f cd 6f  |.....i......VO.o|
+00000040  b0 df 58 a8 da 66 23 e6  8e 20 03 75 33 1a ee 61  |..X..f#.. .u3..a|
+00000050  ab 31 f7 2e e0 ea f4 29  26 34 1d 8e 52 0d 1a 6f  |.1.....)&4..R..o|
+00000060  cc c7 bf 14 dc 1c 47 80  42 b7 d0 ac 26 f5 e1 8e  |......G.B...&...|
+00000070  08 d7 63 8a 3b c4 d3 e7  15 a1 46 e3 9b c1 4a 5a  |..c.;.....F...JZ|
+00000080  14 30 da 62 8f 3a 16 03  03 02 69 54 7c 6d 38 37  |.0.b.:....iT|m87|
+00000090  01 fe 7c fe 75 30 f1 c0  e8 16 89 b7 d8 7e e0 70  |..|.u0.......~.p|
+000000a0  90 4e c5 7d 37 1b 44 57  7b 91 50 cc aa 71 47 9d  |.N.}7.DW{.P..qG.|
+000000b0  64 67 42 2c b0 01 64 b1  05 6f b3 a9 07 61 f9 99  |dgB,..d..o...a..|
+000000c0  f8 2c 59 08 12 80 c5 48  0c 88 67 05 74 da 91 e0  |.,Y....H..g.t...|
+000000d0  6d 53 2a ac 02 14 cb f9  f5 c1 dd c2 29 29 e6 7d  |mS*.........)).}|
+000000e0  78 52 cb 19 74 80 6f 1b  ab a9 4c b7 88 09 01 b8  |xR..t.o...L.....|
+000000f0  66 a1 8c 1d 1a 06 08 05  7d 60 5d e6 a7 da 36 17  |f.......}`]...6.|
+00000100  ef 5c 90 c3 77 d8 34 d4  99 e5 bd 1d 70 15 78 db  |.\..w.4.....p.x.|
+00000110  71 23 4d 4a 18 bd ac ab  36 86 79 05 70 1c 51 15  |q#MJ....6.y.p.Q.|
+00000120  82 c9 a0 c2 cd 80 d0 41  a1 51 10 c5 96 44 1f 97  |.......A.Q...D..|
+00000130  a7 20 0a 80 a4 7c fe 6d  f3 b4 ae 19 17 17 d4 97  |. ...|.m........|
+00000140  37 cf 69 34 8e ad 5a e6  66 fc f3 07 7d a7 5c 0d  |7.i4..Z.f...}.\.|
+00000150  c2 fd d6 3d 69 dc 41 6f  b0 fd 3b db 3a 95 25 52  |...=i.Ao..;.:.%R|
+00000160  a0 82 54 7c f3 4d d2 65  8b c6 55 3a 9c 89 19 f1  |..T|.M.e..U:....|
+00000170  aa c0 49 7a bf 1c ec 7a  78 d2 11 c0 8f ab 53 2d  |..Iz...zx.....S-|
+00000180  68 69 9e 12 db ec 77 df  7d 7b 5f 75 76 df 76 1e  |hi....w.}{_uv.v.|
+00000190  b4 c3 32 3f c9 cb 58 bd  c4 b0 45 61 2a dc 14 fb  |..2?..X...Ea*...|
+000001a0  3a 83 84 e0 ad a0 25 16  e7 1c 3c 4b f6 4e 6d a8  |:.....%...<K.Nm.|
+000001b0  60 f5 ba b8 69 c5 90 f8  45 05 2c 28 4e ab ff d9  |`...i...E.,(N...|
+000001c0  f6 4a de 83 ec 2b fa 64  3b 59 40 86 b6 7a 8c e3  |.J...+.d;Y@..z..|
+000001d0  0e 02 b2 59 fa cb 58 f2  ca e2 ce f3 44 25 51 bc  |...Y..X.....D%Q.|
+000001e0  6c 10 5f 8b 9b 57 3e 7d  61 ad 3e d0 62 2b bc 18  |l._..W>}a.>.b+..|
+000001f0  0b 71 d8 1d ae 65 c0 f8  71 98 aa 08 af 10 09 6f  |.q...e..q......o|
+00000200  9d 79 9b 70 d5 48 5c 96  ac d0 2d ee 61 1f 8a 96  |.y.p.H\...-.a...|
+00000210  5e 8b 04 06 80 20 f1 cc  61 93 9f ea c3 3a f0 ba  |^.... ..a....:..|
+00000220  ed 7c 80 25 4c ba e8 a6  97 62 04 cd 8b 58 00 d6  |.|.%L....b...X..|
+00000230  e1 0d 0b f3 c0 73 b9 0d  57 e3 76 8d f8 a9 43 72  |.....s..W.v...Cr|
+00000240  c0 37 d9 f5 16 02 0a 0c  d1 44 2d e6 fe 57 3d 9f  |.7.......D-..W=.|
+00000250  64 ef a6 f6 9b 44 7a 16  de f7 64 94 6f 4c c4 57  |d....Dz...d.oL.W|
+00000260  f8 ba dd 64 61 87 55 6e  ac 96 1c 68 f4 68 b2 90  |...da.Un...h.h..|
+00000270  ec 7a a5 f3 7c dd f0 30  af 27 9d c4 dc fe 05 c7  |.z..|..0.'......|
+00000280  4b d3 44 63 5c bb e0 e0  eb 0d bc ef ea fa dd 17  |K.Dc\...........|
+00000290  1f 27 a6 b7 79 6c 0c 64  25 91 4d a1 cf ae 5b 81  |.'..yl.d%.M...[.|
+000002a0  2b d3 18 0b 82 3e 4a 4b  02 6c cb be c7 b7 a7 e0  |+....>JK.l......|
+000002b0  2f a7 a0 32 f4 5d b2 5b  6e 9f b4 cd ee 58 e4 bd  |/..2.].[n....X..|
+000002c0  ac 44 4d 0d 37 31 8b d1  d5 01 83 0a 63 85 14 e3  |.DM.71......c...|
+000002d0  55 93 1d 25 61 4b 43 b5  a4 e5 d3 50 e9 01 96 02  |U..%aKC....P....|
+000002e0  10 aa 58 6a 9d e0 e4 80  c4 a9 20 c9 b5 0c 79 bb  |..Xj...... ...y.|
+000002f0  5c 5f 22 43 16 03 03 00  bc 56 b6 aa ae 4c 5f f5  |\_"C.....V...L_.|
+00000300  4f 16 84 92 4b d3 be 30  7f ab 74 d2 5e eb 23 de  |O...K..0..t.^.#.|
+00000310  2f 5b 6e c4 1a b4 e6 39  33 f8 c9 0f a3 b0 d5 bb  |/[n....93.......|
+00000320  77 21 76 6d 6e 45 b9 75  d1 86 b8 be ad 31 85 db  |w!vmnE.u.....1..|
+00000330  90 39 92 74 3a fc e1 5c  71 b9 64 b5 ae d8 5b a5  |.9.t:..\q.d...[.|
+00000340  ac ca b5 9c 3a ad 58 a3  b3 2d 80 52 47 8f 5c 9b  |....:.X..-.RG.\.|
+00000350  fd 09 a9 b0 b9 84 e5 01  03 69 ca b3 79 bc 61 da  |.........i..y.a.|
+00000360  f9 58 0a 0e 86 a3 aa 3a  b9 e8 8d 87 a5 0b 62 fa  |.X.....:......b.|
+00000370  7f de 17 29 ed 75 38 49  4a f9 5f a3 cd 92 f7 bd  |...).u8IJ._.....|
+00000380  fd 5d d3 0e 2f 49 38 a1  ba b5 87 e2 65 e0 68 c1  |.]../I8.....e.h.|
+00000390  c1 3d f2 57 06 25 9e b8  54 6e 9a 33 ee 3f 6a fc  |.=.W.%..Tn.3.?j.|
+000003a0  53 1c cc 1f ee 6a 0f 43  c5 68 08 02 4e d7 3e 5e  |S....j.C.h..N.>^|
+000003b0  a6 c9 aa da 0b 16 03 03  00 14 8b 31 f6 f0 2c bf  |...........1..,.|
+000003c0  d1 fa 59 12 4a 4d 9d 51  d2 79 ff 58 3a fa        |..Y.JM.Q.y.X:.|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 15 0b 29  0e 27 a9 4b 52 4d 0a 77  |....i..).'.KRM.w|
-00000010  b8 3a 40 95 84 a7 7a 8d  b1 6b 90 61 94 3a e4 06  |.:@...z..k.a.:..|
-00000020  20 6f 88 40 8a 8c c2 4e  dc 3a 01 39 c2 11 5a 9b  | o.@...N.:.9..Z.|
-00000030  28 92 bc 72 04 a3 60 c3  42 c0 b8 dd f3 41 40 be  |(..r..`.B....A@.|
-00000040  6d 51 5b b8 db 75 63 3d  4f 2a cf f5 04 3d 53 be  |mQ[..uc=O*...=S.|
-00000050  47 f1 ae be 0a 97 5d 2c  df 55 5d dd 9a f6 0e 40  |G.....],.U]....@|
-00000060  59 02 91 d8 55 c9 3b e6  84 9c 8d 40 af 29 77 59  |Y...U.;....@.)wY|
-00000070  15 0c 83 dd ec c7 e2 16  85 d8 6e e7 4e c5 a5 b1  |..........n.N...|
-00000080  8b 4b 46 3e 62 7c ff 27  1b 37 b7 5c 05 32 30 fb  |.KF>b|.'.7.\.20.|
-00000090  c1 cc 1d 13 1f 09 db 57  6a 70 2b 9f a7 25 9b 75  |.......Wjp+..%.u|
-000000a0  d3 62 20 45 d1 2f 28 c0  d7 84 d6 2e b3 6d 4a c3  |.b E./(......mJ.|
-000000b0  46 0d 92 32 87 65 dd b8  98 68 1a 52 0a df be b3  |F..2.e...h.R....|
-000000c0  09 bc 63 bb a3 da f7 52  5a 81 53 9a e0 ff bb 06  |..c....RZ.S.....|
-000000d0  7f 81 f8 ea 02 bb 3b 96  7b 0f 84 a5 4d 17 3a 2a  |......;.{...M.:*|
-000000e0  20 e9 21 70 b2 ab 8a 55  31 4b 1b 60 52 7f a8 39  | .!p...U1K.`R..9|
-000000f0  5a 0f 0b 00 4e eb 01 0c  a6 d8 f0 30 2b a3 6f 7b  |Z...N......0+.o{|
-00000100  99 82 90 9e 4c c8 03 1c  0e 85 55 bc 2d 42 28 66  |....L.....U.-B(f|
-00000110  35 c3 1e 08 70 d0 45 05  5b 2e 00 fc 9a f1 44 0e  |5...p.E.[.....D.|
-00000120  cb 91 ce b8 0f 2a 9f 5a  18 a8 ca 38 ff 2a ab 11  |.....*.Z...8.*..|
-00000130  57 a5 03 2f 3e 92 21 77  df dc 85 e7 fd d4 7e d0  |W../>.!w......~.|
-00000140  d9 6e ef 99 66 5d a8 f5  9a d3 c3 0f 0c 98 cd fe  |.n..f]..........|
-00000150  5a 46 79 77 c9 28 fb 5e  3e c0 d5 b3 db 98 79 9d  |ZFyw.(.^>.....y.|
-00000160  d4 20 a5 ad 25 d8 3b 39  35 60 fd 21 e0 eb 86 be  |. ..%.;95`.!....|
-00000170  8f 65 72 a2 d3 91 4c 25  70 31 b1 02 29 17 da e0  |.er...L%p1..)...|
-00000180  9f 7d 4e 5f 1a 7b 93 09  4c 84 5b 40 f8 3c 98 36  |.}N_.{..L.[@.<.6|
-00000190  9b 14 43 db 43 11 0a e2  9a 8b 73 96 a3 7b 4d 67  |..C.C.....s..{Mg|
-000001a0  d7 35 a6 85 40 6d 45 0e  9d 47 43 96 b8 64 d4 d7  |.5..@mE..GC..d..|
-000001b0  d1 28 c8 32 7e ab d5 11  ad b4 a7 9c c9 ab c5 96  |.(.2~...........|
-000001c0  72 69 1a db 42 06 8e 03  d0 70 f9 7a 75 56 53 49  |ri..B....p.zuVSI|
-000001d0  29 e1 60 16 86 99 da 9e  d6 c3 95 94 e3 e4 6c 9c  |).`...........l.|
-000001e0  4f d0 5d e7 a6 23 e1 49  a5 b8 3d 41 a4 e0 8c a2  |O.]..#.I..=A....|
-000001f0  f8 35 40 4d 12 f1 0b 70  06 f5 b5 29 f8 5d 74 73  |.5@M...p...).]ts|
-00000200  32 35 11 7f 50 a3 22 5b  d6 db a5 a8 9f ca db 47  |25..P."[.......G|
-00000210  b9 a8 c7 fc 16 40 ae 94  6e 6c 40 30 7a d6 9c 89  |.....@..nl@0z...|
-00000220  d7 e9 1b 6b 26 72 1f d7  c9 bc ce 6f 84 03 3d 65  |...k&r.....o..=e|
-00000230  34 f9 7b 32 54 e4 b4 72  8c e1 31 9e e5 13 50 2f  |4.{2T..r..1...P/|
-00000240  ea 16 27 15 cb ec 0f 1b  21 aa dd cb 25 74 b9 4d  |..'.....!...%t.M|
-00000250  36 c0 0d fe a4 99 2f 86  50 52 d0 83 e2 3f fa e7  |6...../.PR...?..|
-00000260  2d 24 b6 7a ca 7f 69 3e  7d 0b 61 df 29 3b 16 03  |-$.z..i>}.a.);..|
-00000270  03 00 35 8e 89 3d 7b 39  aa d2 21 01 6a 3d fe 4f  |..5..={9..!.j=.O|
-00000280  e2 d9 e6 6d 5d 1e d3 a5  1d 3f f8 8e fb 97 3d 06  |...m]....?....=.|
-00000290  9b 68 67 45 15 3b a1 e8  e8 39 77 1a 41 77 2b c5  |.hgE.;...9w.Aw+.|
-000002a0  8c fe bd 28 7a 85 eb 7a  16 03 03 00 98 f0 ed 3c  |...(z..z.......<|
-000002b0  37 3f 34 3b 35 e4 15 a8  f3 b4 b6 76 49 65 e8 26  |7?4;5......vIe.&|
-000002c0  93 4b cc b1 31 7a 4c e7  7d 80 63 60 65 9a ff 11  |.K..1zL.}.c`e...|
-000002d0  a8 c5 c4 4e c2 7a ca 95  cb 08 21 77 42 ce 70 1e  |...N.z....!wB.p.|
-000002e0  bf d9 b5 6d de dc 03 67  2e 11 b5 47 c1 c0 74 6b  |...m...g...G..tk|
-000002f0  b4 9d c4 de 8c d4 80 e4  99 92 31 68 09 85 00 34  |..........1h...4|
-00000300  43 cc 06 09 bc a8 6e 83  a0 fa df 6e a0 04 e9 37  |C.....n....n...7|
-00000310  b3 05 69 b9 f1 85 7f 48  27 73 d0 64 2c 33 48 1f  |..i....H's.d,3H.|
-00000320  f9 7c 0a 21 1f cb 0f 4c  c2 28 b0 3b 8c 9b 23 21  |.|.!...L.(.;..#!|
-00000330  f4 8c 69 b2 1d 55 35 20  b9 92 09 36 01 aa e1 e3  |..i..U5 ...6....|
-00000340  ee b7 3d 83 7b 14 03 03  00 11 40 bb bb 2e 3d 48  |..=.{.....@...=H|
-00000350  9f fa c6 0c d8 4f 45 cb  11 b3 a5 16 03 03 00 20  |.....OE........ |
-00000360  39 b7 46 30 00 68 12 c5  f5 d7 a0 85 7f ce 49 70  |9.F0.h........Ip|
-00000370  05 83 64 26 7a 0c 43 fb  a9 4d bb 61 3a c3 8a 91  |..d&z.C..M.a:...|
+00000000  16 03 03 00 35 24 68 32  63 8a 43 11 1f 91 a5 8b  |....5$h2c.C.....|
+00000010  4f 57 63 f6 de a8 23 c2  d2 68 33 d0 fc 9d 41 b1  |OWc...#..h3...A.|
+00000020  5f 71 d8 e4 fb b6 71 e6  83 2f cc 15 53 e1 70 48  |_q....q../..S.pH|
+00000030  34 92 68 ae 1f f4 88 b0  d0 59 14 03 03 00 11 e9  |4.h......Y......|
+00000040  01 e9 1d fa c2 c3 2a 60  68 98 83 fa f5 7e 5f 2a  |......*`h....~_*|
+00000050  16 03 03 00 20 33 0c 00  8d 8a 60 06 dc 43 9d ae  |.... 3....`..C..|
+00000060  a5 a7 23 05 3a 55 53 e4  41 42 46 bb 35 ef a6 2c  |..#.:US.ABF.5..,|
+00000070  d4 d8 4d 85 d4                                    |..M..|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 d1 d7 7e  3c 5f 01 cb f8 eb af d5  |.......~<_......|
-00000010  ba 09 32 68 4b cf 16 03  03 00 20 02 f1 23 45 32  |..2hK..... ..#E2|
-00000020  60 9b 49 db 2f 3a cb 5c  e4 f3 64 b1 cb ca 09 b0  |`.I./:.\..d.....|
-00000030  b3 34 a3 75 7d a5 a0 80  44 fd b7 17 03 03 00 19  |.4.u}...D.......|
-00000040  d7 c3 c4 33 e6 f2 73 d2  2c 0b 7e 0e 40 d3 8b f6  |...3..s.,.~.@...|
-00000050  47 57 13 88 be 4b 12 43  57                       |GW...K.CW|
+00000000  14 03 03 00 11 ce 28 cc  ba 60 2b 9a 92 b1 a1 fc  |......(..`+.....|
+00000010  73 25 71 fd f5 59 16 03  03 00 20 5d 9c a5 c1 2f  |s%q..Y.... ].../|
+00000020  2a f3 af 84 9b 15 cd fa  a1 6e ca a0 09 2b a4 b8  |*........n...+..|
+00000030  e9 e2 b8 eb 17 84 d0 fb  20 7e fc 17 03 03 00 19  |........ ~......|
+00000040  43 86 e9 94 82 d6 08 ac  a3 90 97 05 b6 f0 54 28  |C.............T(|
+00000050  3d d1 c9 f8 d9 19 5a d4  ed                       |=.....Z..|
 >>> Flow 11 (client to server)
-00000000  15 03 03 00 12 3a 90 85  e8 ce 53 d1 2a 3b d6 9a  |.....:....S.*;..|
-00000010  f3 61 c1 72 81 c0 03                              |.a.r...|
+00000000  15 03 03 00 12 05 a9 95  98 5c 81 dc ae eb bc 17  |.........\......|
+00000010  2e 08 b5 32 82 45 23                              |...2.E#|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
index c2f4e4a..fb5ca90 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 30 5b 03 80 cf  |....Y...U..0[...|
-00000010  ad 5e 69 9b da 4a de 2f  07 f3 6c 42 d7 50 99 10  |.^i..J./..lB.P..|
-00000020  80 15 dc dd d2 ef 3d 20  b9 eb bd 20 51 63 fd 9d  |......= ... Qc..|
-00000030  3d b7 3e ea 4e 18 45 90  40 50 f2 f3 2b b8 00 42  |=.>.N.E.@P..+..B|
-00000040  bf 77 ae d1 ff 29 2d ca  d8 c2 4e c7 cc a8 00 00  |.w...)-...N.....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 72 05 00 95 36  |....Y...U..r...6|
+00000010  6c a5 d1 0f 06 bd 25 80  25 19 16 0d 70 56 8f c4  |l.....%.%...pV..|
+00000020  b4 e9 17 be d2 06 09 b4  05 bc 2e 20 bc b9 5a 92  |........... ..Z.|
+00000030  44 a5 91 7c 82 7e b6 c3  50 da cd f2 98 e1 26 14  |D..|.~..P.....&.|
+00000040  d3 eb e2 98 c7 f6 6c 96  71 d3 7e b4 cc a8 00 00  |......l.q.~.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,323 +54,219 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 6b cd 37 6d a7 76 7a  |........ k.7m.vz|
-000002d0  04 0e 8c 93 db b0 62 67  14 65 26 5e 91 b3 8d 66  |......bg.e&^...f|
-000002e0  20 40 31 c1 84 3c ef d8  67 04 01 00 80 ce 3a f2  | @1..<..g.....:.|
-000002f0  16 01 b2 8a cd d6 1c b3  c4 46 a5 e8 1f 17 85 d9  |.........F......|
-00000300  5b 97 fb dd 43 65 52 82  e3 49 99 e8 49 d9 09 13  |[...CeR..I..I...|
-00000310  05 73 19 d0 d9 66 54 03  de 4b fa 43 2d f1 f8 98  |.s...fT..K.C-...|
-00000320  79 21 3b fa a9 ea 29 78  fa 87 59 8e 9b 2f f2 99  |y!;...)x..Y../..|
-00000330  14 85 21 9c 7e 59 5b 4b  2f e3 33 c4 7c 2c ac 35  |..!.~Y[K/.3.|,.5|
-00000340  4f 68 c8 a3 0b f5 43 7e  72 9a e6 4f 9c 10 4d 4a  |Oh....C~r..O..MJ|
-00000350  d4 b5 84 62 61 4e f4 0f  3f a5 b5 23 89 d9 33 e2  |...baN..?..#..3.|
-00000360  06 22 02 c5 fe db 27 fb  40 87 8c e7 6e 16 03 03  |."....'.@...n...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 f0 1b 05 7a 25 88 37  |........ ...z%.7|
+000002d0  65 0d 93 e7 44 ff b4 bd  8d 9a eb ca 4f 31 c6 42  |e...D.......O1.B|
+000002e0  f8 83 aa 1e 33 6c c8 3f  2a 04 01 00 80 0c 5b 0c  |....3l.?*.....[.|
+000002f0  92 86 55 5a 05 c9 f0 df  0a 1f 57 46 24 53 a6 77  |..UZ......WF$S.w|
+00000300  f9 6b b0 a0 2e a3 64 f0  21 f1 93 10 de 9c 6f fb  |.k....d.!.....o.|
+00000310  68 8c f0 d4 f6 b4 81 f6  60 8a 64 ee af f6 ee 3c  |h.......`.d....<|
+00000320  d8 45 fc 3a 70 1d 89 c2  11 94 4e 9a 5c ee 67 64  |.E.:p.....N.\.gd|
+00000330  24 91 2c 97 09 ba 1f 76  2d ca e4 a1 52 e9 d6 8a  |$.,....v-...R...|
+00000340  e5 21 42 66 80 95 72 61  6e d7 09 eb db 30 fc b7  |.!Bf..ran....0..|
+00000350  8e d6 3a 91 97 14 09 33  15 9a 5d 45 a9 53 0b 3d  |..:....3..]E.S.=|
+00000360  49 3b ba 95 8c ae 96 06  e1 e9 4c 2f 72 16 03 03  |I;........L/r...|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 5a b9 f7  81 81 7f 65 84 c9 87 40  |.... Z.....e...@|
-00000040  a4 66 07 85 38 3b 85 8d  ff c4 7e b7 f6 16 1d c1  |.f..8;....~.....|
-00000050  36 4f 53 1a bb                                    |6OS..|
+00000030  16 03 03 00 20 f7 8a a0  59 29 4a b5 a1 1a d2 9c  |.... ...Y)J.....|
+00000040  d7 4f f7 eb 76 ed 9f d5  93 cb 30 dc dd a1 28 0a  |.O..v.....0...(.|
+00000050  82 3e fb 3b d0                                    |.>.;.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 ff b2 f4 3b af  |.......... ...;.|
-00000010  ba 44 66 0b f9 31 09 18  df 9d d0 04 82 38 11 dd  |.Df..1.......8..|
-00000020  a7 ee 83 ef 03 51 21 08  f9 c4 8a                 |.....Q!....|
+00000000  14 03 03 00 01 01 16 03  03 00 20 01 ce 8d 74 22  |.......... ...t"|
+00000010  4a 7e 22 fe ab b4 ed 5e  05 27 3f e9 35 97 f4 ef  |J~"....^.'?.5...|
+00000020  c5 df 0c 7f d7 6a 10 94  a0 72 dc                 |.....j...r.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 b6 45 4e  35 df 21 f4 c7 24 ba e6  |......EN5.!..$..|
-00000010  18 65 1c 75 ba 72 5d 5b  4a fd 78                 |.e.u.r][J.x|
+00000000  17 03 03 00 16 cc f5 66  f6 5e d6 b5 53 e6 d6 29  |.......f.^..S..)|
+00000010  90 c6 dc b3 ad b5 43 ea  16 80 88                 |......C....|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 1a ec 37  ab 36 23 80 76 1c 0b d0  |.......7.6#.v...|
-00000010  54 9a 8f 7e 7a c0 bd 09  9a                       |T..~z....|
+00000000  16 03 03 00 14 0e 28 a6  a0 4a 78 90 fa d5 ed 0a  |......(..Jx.....|
+00000010  45 b8 21 75 18 de 93 16  12                       |E.!u.....|
 >>> Flow 7 (client to server)
-00000000  16 03 03 00 ad 7a d4 bf  4d bf 48 0a 0f 2c d1 38  |.....z..M.H..,.8|
-00000010  9f 20 f7 c7 36 27 82 d9  5e f4 21 44 0e 75 46 ca  |. ..6'..^.!D.uF.|
-00000020  67 f8 87 6c 4f 1e c7 1e  5f 8d f2 88 58 1b 92 12  |g..lO..._...X...|
-00000030  e0 f6 d5 5c d7 4b 21 b9  8c 93 a8 bc a4 e6 e5 cb  |...\.K!.........|
-00000040  d0 33 eb d5 10 ad 53 50  58 e0 94 f0 b8 52 20 8c  |.3....SPX....R .|
-00000050  c2 69 7a c3 43 73 3f 2e  4a 42 2c c1 8d c1 ff 1e  |.iz.Cs?.JB,.....|
-00000060  57 ba 7d 99 9c a2 10 99  19 d6 72 38 96 ba 2b ff  |W.}.......r8..+.|
-00000070  7b a8 42 c0 c0 c4 d4 50  20 39 39 b8 18 23 a1 d3  |{.B....P 99..#..|
-00000080  38 d3 9d 41 81 c2 4b ba  4c 28 c0 14 22 71 df d9  |8..A..K.L(.."q..|
-00000090  e1 57 fc 9c 4f 0e 28 9a  13 c6 a1 e2 de f0 81 3b  |.W..O.(........;|
-000000a0  5f c1 7b 61 f5 fc 74 93  f1 06 7d 9b 67 56 45 a4  |_.{a..t...}.gVE.|
-000000b0  f8 83                                             |..|
+00000000  16 03 03 00 b1 60 7a a2  91 30 f4 5b a4 5f 4c 38  |.....`z..0.[._L8|
+00000010  5e 44 34 09 02 13 c3 1b  02 d3 64 e4 f3 c2 35 87  |^D4.......d...5.|
+00000020  b2 4b 39 fd 89 10 12 42  97 b9 97 e5 67 82 0a 5c  |.K9....B....g..\|
+00000030  24 28 5a 0c be db d2 0b  f7 ac b7 f4 9d c1 0f 0a  |$(Z.............|
+00000040  76 e4 6f 41 e2 31 e3 35  0b 39 71 a9 31 56 b0 41  |v.oA.1.5.9q.1V.A|
+00000050  13 d6 0f 2c 10 e9 e7 bb  37 2a e9 b2 4d 8a f3 8a  |...,....7*..M...|
+00000060  5a ab 12 02 99 ba e4 45  b9 2d c6 be 45 35 37 6a  |Z......E.-..E57j|
+00000070  e5 24 be db 79 39 df 5e  c8 a8 58 42 2d 40 00 96  |.$..y9.^..XB-@..|
+00000080  89 8a 2e 45 32 61 3e 65  18 c1 8f bf 90 da 60 bd  |...E2a>e......`.|
+00000090  03 34 ad 93 ac aa 33 55  31 8c 41 fa d0 85 42 a8  |.4....3U1.A...B.|
+000000a0  dd 69 2f fb e5 21 c6 64  39 42 8c af b6 1d 21 e2  |.i/..!.d9B....!.|
+000000b0  47 ec 11 ed 4d 6d                                 |G...Mm|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 ec 0e 7c  60 5b ed 0f 29 e6 cd 3a  |.......|`[..)..:|
-00000010  ca ff f7 68 3e 22 30 cf  43 b2 29 71 ca 3a 06 db  |...h>"0.C.)q.:..|
-00000020  e0 df bc 87 51 62 df 37  37 7a 9d b4 2d 35 ab bb  |....Qb.77z..-5..|
-00000030  d2 ed d1 50 e7 61 a4 27  18 43 23 74 4b 1d 14 46  |...P.a.'.C#tK..F|
-00000040  80 5c 10 99 10 47 b2 51  92 11 1f aa f1 5a c3 cf  |.\...G.Q.....Z..|
-00000050  f5 30 69 96 26 f6 0e 7c  e9 e1 7c 4b d5 2f 46 1c  |.0i.&..|..|K./F.|
-00000060  7d 18 a5 20 f1 ff 40 9e  c7 d5 d4 54 33 c4 99 9c  |}.. ..@....T3...|
-00000070  26 95 d9 ca 82 fc e7 27  37 fc 33 9f f8 c7 cb 0a  |&......'7.3.....|
-00000080  9d 4e bc 66 ca fc 16 03  03 02 69 ab be 55 39 99  |.N.f......i..U9.|
-00000090  ac 66 a6 86 03 51 70 d8  fa 7d e7 89 09 fc eb b5  |.f...Qp..}......|
-000000a0  25 f6 95 0c 40 3d b8 ea  b6 78 41 db a4 f3 92 83  |%...@=...xA.....|
-000000b0  00 c8 8d 1f 19 0c ec ec  e5 60 07 d9 31 2d 3b 91  |.........`..1-;.|
-000000c0  ba ad b3 c1 fb b5 57 52  73 37 43 89 22 e0 45 7c  |......WRs7C.".E||
-000000d0  b0 da 1f 69 76 d3 af fc  ba f0 98 ec d2 7f be f0  |...iv...........|
-000000e0  a4 76 f0 d9 30 1b 78 22  bb 43 fd 45 64 07 e4 64  |.v..0.x".C.Ed..d|
-000000f0  c5 74 2f ed ba 23 8d 3a  5a ff 7f 35 de 25 53 0d  |.t/..#.:Z..5.%S.|
-00000100  ac ae 5b da b1 7d 86 fe  da c8 9e 79 58 6c 4c 9c  |..[..}.....yXlL.|
-00000110  6d f9 e9 1d 31 ff aa fb  8e 2e 98 f4 3a 67 33 9b  |m...1.......:g3.|
-00000120  a3 63 5e fc 74 f5 c5 28  76 30 e6 22 8a 85 79 56  |.c^.t..(v0."..yV|
-00000130  4e cf 94 38 92 61 09 22  00 95 d4 16 b4 e0 80 05  |N..8.a."........|
-00000140  28 35 30 6f 56 7d f8 b9  ed 49 72 b0 9f 47 9f 07  |(50oV}...Ir..G..|
-00000150  7f 1d b9 3b 6d ce c9 09  72 2f 65 b0 88 b4 ec 24  |...;m...r/e....$|
-00000160  29 8d 57 93 a7 51 85 32  26 4c 31 21 24 b1 ab 97  |).W..Q.2&L1!$...|
-00000170  c6 3c 38 44 d4 8f d0 3b  ea 62 39 48 90 ca c4 5c  |.<8D...;.b9H...\|
-00000180  9c 72 08 a4 3f d0 1e 3e  9f 23 02 0e 94 b4 14 cc  |.r..?..>.#......|
-00000190  96 bc 23 22 2f af c5 ed  81 da 49 ca 26 f4 55 6a  |..#"/.....I.&.Uj|
-000001a0  b3 24 3f 13 a5 f7 d6 82  70 04 37 63 dc 92 63 0f  |.$?.....p.7c..c.|
-000001b0  3d f7 4e 42 7c 5a 42 df  53 17 48 25 cb da 31 e1  |=.NB|ZB.S.H%..1.|
-000001c0  67 a7 22 8c ca db 2d 33  49 86 62 b5 ba 38 53 4c  |g."...-3I.b..8SL|
-000001d0  12 f3 c3 f6 b6 01 53 b1  11 43 e1 e8 ba 3f 68 7a  |......S..C...?hz|
-000001e0  9c 10 09 82 d1 90 cd 9e  52 2e 29 15 0b 13 c3 e3  |........R.).....|
-000001f0  34 ef 76 8a 0d f9 f6 17  76 57 c2 55 cb 7d 45 e0  |4.v.....vW.U.}E.|
-00000200  d5 e6 53 93 75 57 c2 ab  26 5a 13 02 05 7a 60 2b  |..S.uW..&Z...z`+|
-00000210  b6 92 1a 88 0c 34 59 81  40 42 70 d5 4e 7b d3 14  |.....4Y.@Bp.N{..|
-00000220  3c e6 70 81 90 ff 53 79  c5 f3 7c d9 02 6f 35 6b  |<.p...Sy..|..o5k|
-00000230  d4 81 ff 32 a2 71 28 a0  4b 22 75 9f 3b 50 c8 03  |...2.q(.K"u.;P..|
-00000240  22 e7 4f 1f c5 c5 99 67  f3 2c 97 5e 43 89 84 39  |".O....g.,.^C..9|
-00000250  04 c9 4c 1e e0 da 39 8f  78 8f 95 3a 64 74 d3 63  |..L...9.x..:dt.c|
-00000260  13 d4 14 9d 98 6c bb 27  81 1e 12 88 8c d4 11 1c  |.....l.'........|
-00000270  4a 71 2f 10 dc 5b 9a 8e  70 e6 bf 0b a2 50 4c d1  |Jq/..[..p....PL.|
-00000280  c4 29 b7 85 9e 0f 86 33  7c 38 e4 ae d4 53 5e 81  |.).....3|8...S^.|
-00000290  95 cf 6c 1a 15 7d af 20  53 21 f4 84 5c 46 5f 10  |..l..}. S!..\F_.|
-000002a0  1f 68 7d 9a 20 0d a8 1f  90 2f ae b8 c0 57 e0 4b  |.h}. ..../...W.K|
-000002b0  ad ec 9d ae 51 52 78 5d  3f bb de 54 54 d4 18 ff  |....QRx]?..TT...|
-000002c0  e6 b4 c9 52 f8 66 63 e3  bf 7a f3 5e c6 3f d9 27  |...R.fc..z.^.?.'|
-000002d0  71 07 e7 69 6d cb 60 24  55 4e f9 34 e7 5f a3 37  |q..im.`$UN.4._.7|
-000002e0  76 90 ec b5 eb ff 49 38  15 71 23 fd 77 30 80 c8  |v.....I8.q#.w0..|
-000002f0  ca 0e 38 3c 16 03 03 00  bc 89 27 c8 13 dd 05 8b  |..8<......'.....|
-00000300  46 97 5f 19 76 db 29 8d  b1 24 52 fe 7a 2e 2c 4d  |F._.v.)..$R.z.,M|
-00000310  e2 f9 59 89 48 82 f5 d7  87 af 99 4b 98 c5 7c 1d  |..Y.H......K..|.|
-00000320  1a e1 4d fd 0c 37 d0 d3  d8 e2 f8 0f 04 d5 15 21  |..M..7.........!|
-00000330  60 09 47 0c d6 bf 09 bf  55 c1 ae 33 11 35 94 29  |`.G.....U..3.5.)|
-00000340  80 96 3a 53 ae a8 29 c4  84 37 e2 80 f9 da 79 18  |..:S..)..7....y.|
-00000350  77 50 26 32 bf f6 b2 6d  3a 73 25 e7 cd 34 6d ea  |wP&2...m:s%..4m.|
-00000360  a0 92 40 7e f8 eb d0 82  06 b3 a1 f5 1c 8e b2 ef  |..@~............|
-00000370  b2 4f 0c bb 04 1b c7 cf  bc dd 42 19 00 3e 45 93  |.O........B..>E.|
-00000380  e6 72 57 ed eb d9 1d b3  71 b7 fe 84 03 57 e4 9c  |.rW.....q....W..|
-00000390  71 78 35 39 63 b1 cf 36  b9 5a d6 95 13 ee 4d 2f  |qx59c..6.Z....M/|
-000003a0  22 ef ed 2e fc 69 7c 12  c2 0e 32 ed 05 17 42 5c  |"....i|...2...B\|
-000003b0  a7 62 ab 6b 46 16 03 03  00 3a b9 af 3d 25 e4 6a  |.b.kF....:..=%.j|
-000003c0  a9 b5 b4 00 79 21 aa 3c  f3 56 50 bd 32 a4 a8 ab  |....y!.<.VP.2...|
-000003d0  8a 60 77 5d b7 3e 89 d3  60 a2 b8 5c a8 99 27 bb  |.`w].>..`..\..'.|
-000003e0  0e dd 93 af 3e 2b 66 8e  56 19 03 29 44 6a 63 a1  |....>+f.V..)Djc.|
-000003f0  c7 17 f3 1e 16 03 03 00  14 1c bd e4 7b c3 88 d9  |............{...|
-00000400  be ba c3 c3 fb b7 07 9d  f1 58 3e b0 61           |.........X>.a|
+00000000  16 03 03 00 81 1b 98 a8  9a 8f 4f c6 d0 1f b0 21  |..........O....!|
+00000010  74 47 2a af 9f 6d a0 fb  4e 99 ed ad 05 99 5a 34  |tG*..m..N.....Z4|
+00000020  ab 9c 4d c0 24 72 15 f4  6f ba 8f d2 43 33 d5 8b  |..M.$r..o...C3..|
+00000030  3a f6 10 cd d3 50 3e 8c  b7 d6 03 b7 1c 28 d7 fb  |:....P>......(..|
+00000040  47 1c b9 a7 14 a4 6e 8e  06 65 d3 b8 8a 8c 73 ee  |G.....n..e....s.|
+00000050  36 63 24 bf 5a c8 0a 27  1f 93 a4 fc 50 c9 48 d0  |6c$.Z..'....P.H.|
+00000060  43 27 63 6d c3 d9 ca bf  2c 03 c8 d1 e3 d1 94 43  |C'cm....,......C|
+00000070  e0 12 87 b1 96 14 b4 7f  ac 8a 85 50 5d f7 64 0e  |...........P].d.|
+00000080  05 cd 47 43 59 5e 16 03  03 02 69 90 f1 fe ba 32  |..GCY^....i....2|
+00000090  b5 0d 2f 98 95 2f c1 95  9a 09 32 ab 9f a8 a8 bc  |../../....2.....|
+000000a0  2d f0 cf 7e 7f d0 f8 b9  0c e0 11 84 03 8e d3 27  |-..~...........'|
+000000b0  c5 15 07 81 02 fa 64 7b  eb 21 63 59 15 ba 9e 4e  |......d{.!cY...N|
+000000c0  6d 03 81 f4 d8 8b 4d f4  82 fd 62 1f 9f 28 64 80  |m.....M...b..(d.|
+000000d0  5b af d3 fc fc 2e dd 6c  b0 5c 28 5e 58 e7 01 07  |[......l.\(^X...|
+000000e0  86 d1 40 35 f2 9c 2c 45  c0 2a 86 67 30 d4 d4 51  |..@5..,E.*.g0..Q|
+000000f0  6c 18 31 bd 22 2e d0 6c  ea d8 f4 9b 87 30 ea 09  |l.1."..l.....0..|
+00000100  66 11 36 a3 ae f5 a7 91  a0 76 8e 77 c1 3d f7 3a  |f.6......v.w.=.:|
+00000110  88 29 b2 c4 2f 4e cd c6  d9 93 80 7f 9b 29 3a a4  |.)../N.......):.|
+00000120  f5 63 77 7d 54 07 62 8c  bc 23 c8 36 ea a8 e5 c4  |.cw}T.b..#.6....|
+00000130  46 4b 59 dc 02 58 9d 21  00 47 39 29 60 9a 14 d8  |FKY..X.!.G9)`...|
+00000140  ae 55 5c 03 fd 05 b7 66  30 de 81 87 9c 45 9f 52  |.U\....f0....E.R|
+00000150  1e c5 2d d8 6a 7d d0 64  7b 0c 3a 47 b9 ff dd dd  |..-.j}.d{.:G....|
+00000160  60 a6 fa 69 f9 a0 43 a5  97 27 e8 fe 2d 99 94 01  |`..i..C..'..-...|
+00000170  d7 52 c2 b2 ec 77 10 af  ed 5e f6 82 d4 15 60 aa  |.R...w...^....`.|
+00000180  d3 cd 39 e5 a6 92 c9 f8  9e 63 e1 83 71 33 f2 dc  |..9......c..q3..|
+00000190  dd 7a eb de ac 91 46 06  ef 23 b2 6f 39 33 69 75  |.z....F..#.o93iu|
+000001a0  43 d7 e5 e1 b0 5c 2f 0f  2d 39 d6 14 11 cd 6b a2  |C....\/.-9....k.|
+000001b0  37 d2 32 0b b6 45 ad 2c  b8 26 ef 43 3e 63 b0 1f  |7.2..E.,.&.C>c..|
+000001c0  a1 79 d2 c7 84 f9 7a 5f  b2 c2 fd 4e 22 89 23 1d  |.y....z_...N".#.|
+000001d0  b7 4c 6c b5 b1 c1 19 a9  7c f7 23 bf 91 0e aa 8c  |.Ll.....|.#.....|
+000001e0  da 67 68 57 84 b9 68 5f  69 16 ad c7 32 86 98 81  |.ghW..h_i...2...|
+000001f0  06 01 91 66 fd 5e e3 f5  63 4b e3 05 6d 41 f0 4e  |...f.^..cK..mA.N|
+00000200  f2 b1 70 26 de ed e5 83  87 d3 cf 5d 5c 7b d5 14  |..p&.......]\{..|
+00000210  08 e9 e3 88 9a d0 9a e4  d6 40 44 1b 61 57 8f a3  |.........@D.aW..|
+00000220  8a 52 5e 83 75 07 3d c2  16 00 3c a3 e9 61 cb 41  |.R^.u.=...<..a.A|
+00000230  66 e7 54 7c e1 e5 7b 85  cb 0d f6 50 93 7d 85 c1  |f.T|..{....P.}..|
+00000240  de 98 a8 8d 5a 0d 12 80  25 78 25 15 a3 0c 7a 7f  |....Z...%x%...z.|
+00000250  43 45 2e 0f e0 47 05 9f  b2 2a 0d 9f 23 e3 0b 62  |CE...G...*..#..b|
+00000260  33 91 d9 d8 7f f5 ac ed  ef fd ea a5 f5 df 04 e8  |3...............|
+00000270  6f 4a bd a2 bf aa fe 56  49 13 7a d3 58 2b ef ab  |oJ.....VI.z.X+..|
+00000280  ed f8 4b 6f 77 18 1e 37  59 2c 98 85 c4 59 f5 08  |..Kow..7Y,...Y..|
+00000290  a6 03 f3 9b b0 79 24 cc  61 55 e3 b7 a7 f5 96 58  |.....y$.aU.....X|
+000002a0  39 57 ec 40 33 a8 94 a2  c8 7f d4 5a f6 5e b0 be  |9W.@3......Z.^..|
+000002b0  89 b8 4d 45 73 ef 9f e9  cc d1 31 f8 46 97 82 be  |..MEs.....1.F...|
+000002c0  fa 44 de 62 36 47 6f 7b  5e 50 af b6 1b d2 0b 02  |.D.b6Go{^P......|
+000002d0  17 df 6b c4 b5 ca 60 39  49 2e 86 d7 84 60 37 34  |..k...`9I....`74|
+000002e0  65 43 0d f7 04 88 38 e4  5f 65 19 d0 62 8c 29 b6  |eC....8._e..b.).|
+000002f0  2d d2 52 0f 16 03 03 00  bc 30 b3 f2 e1 bd 5e ec  |-.R......0....^.|
+00000300  c3 68 8a cc b4 4d e1 f1  76 e7 c1 47 0a c2 54 c1  |.h...M..v..G..T.|
+00000310  9d d9 2d 72 1b 44 2d 3e  3d 22 5b 7d a1 c0 17 27  |..-r.D->="[}...'|
+00000320  97 dd fe 9e a1 c5 5b ce  5f eb 9d 72 0e 14 ca b1  |......[._..r....|
+00000330  61 f6 03 6e 84 d5 c4 53  91 ed 22 41 6e c9 84 91  |a..n...S.."An...|
+00000340  59 a2 30 38 2a 29 b3 b8  9e 45 3a 1f 98 30 ce a4  |Y.08*)...E:..0..|
+00000350  41 8a d9 ea e8 8d ee 43  cc 29 94 8c e5 86 cc 7b  |A......C.).....{|
+00000360  04 a7 31 1e 87 2b aa da  6c d0 4a a7 08 6e 31 2f  |..1..+..l.J..n1/|
+00000370  c3 95 06 3e 6d 9c 1b bb  db 74 f5 a2 7e 6a 17 5f  |...>m....t..~j._|
+00000380  4c 2f f5 56 69 89 04 f7  17 41 85 ea 35 2f 59 db  |L/.Vi....A..5/Y.|
+00000390  d3 b9 f9 7a 6c 08 f8 f2  2d ba 04 ef 57 b5 d0 2f  |...zl...-...W../|
+000003a0  f3 3d 31 e6 c1 f8 26 9d  06 be 38 94 ba 8e ca 3f  |.=1...&...8....?|
+000003b0  4c 5b 70 c6 09 16 03 03  00 14 1e 86 bf c9 1e 7c  |L[p............||
+000003c0  08 0c 5a fb e4 92 8c f9  78 85 34 e3 56 86        |..Z.....x.4.V.|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 d3 b2 83  ca 08 61 36 6f fa 66 de  |....i.....a6o.f.|
-00000010  5c 42 5f 35 17 f4 4c b3  5e 17 94 07 c5 2a 89 90  |\B_5..L.^....*..|
-00000020  b8 31 50 af 55 91 b1 28  bc 00 00 da 57 85 cc d5  |.1P.U..(....W...|
-00000030  a5 a7 ec ba 52 d5 1f ab  b5 4f a3 53 9c af 59 20  |....R....O.S..Y |
-00000040  be 13 f6 c5 70 b0 cc f7  59 69 d1 db 80 7f 60 29  |....p...Yi....`)|
-00000050  e1 e8 7a 1e 97 a6 e1 a2  11 70 4f b4 7b 53 7c 9a  |..z......pO.{S|.|
-00000060  dd fa 58 5d 12 a4 fb 3e  46 dd d3 4d ac e3 b6 73  |..X]...>F..M...s|
-00000070  05 42 03 f3 37 79 a0 10  34 ef 01 6f c6 27 52 4b  |.B..7y..4..o.'RK|
-00000080  75 4c b2 86 1b d6 ca 13  b4 31 41 db 93 2f a3 35  |uL.......1A../.5|
-00000090  e1 e9 bc 65 85 c8 1a e2  7b 6e 36 49 e8 ed 04 a9  |...e....{n6I....|
-000000a0  cb a9 70 32 c0 4d e5 f5  94 d8 af 7d 41 b6 dc e5  |..p2.M.....}A...|
-000000b0  fc ff db 9f 91 50 df c6  b2 4a 0c bb 86 4e 50 a5  |.....P...J...NP.|
-000000c0  2a 3b 69 e2 3d fa 10 eb  cc 48 21 9d 98 78 02 0b  |*;i.=....H!..x..|
-000000d0  e7 4d 83 63 9e e5 ad 2c  7b 46 d1 09 28 35 07 6c  |.M.c...,{F..(5.l|
-000000e0  12 c9 ae f0 4c 7c 00 aa  54 ba 7b e8 42 be e0 18  |....L|..T.{.B...|
-000000f0  f4 df a0 9d eb 8f a2 3a  d0 00 b6 e0 eb 90 65 38  |.......:......e8|
-00000100  b2 cc 21 87 57 b7 50 07  41 e2 5a 9b c8 2b ae 64  |..!.W.P.A.Z..+.d|
-00000110  55 6a d7 b5 0d 5d f0 ac  da 0b f0 80 75 8d 6a 0a  |Uj...]......u.j.|
-00000120  5b c5 2a 20 f2 ab 75 76  a3 33 f1 43 24 06 45 75  |[.* ..uv.3.C$.Eu|
-00000130  63 58 60 57 ca 7f d2 8f  e8 a5 b8 e3 72 37 39 bd  |cX`W........r79.|
-00000140  9c dd 10 b0 f8 b5 e8 46  4a 39 ac 94 69 08 51 29  |.......FJ9..i.Q)|
-00000150  27 2d 28 0f 15 8a 91 00  3b cc 99 77 ea 82 0d e1  |'-(.....;..w....|
-00000160  66 ed 34 da 6e 88 47 e5  f4 1b 28 28 cd 38 9f e5  |f.4.n.G...((.8..|
-00000170  1c 26 67 3d 83 d0 b1 88  a3 08 9c 2e 08 a5 b7 af  |.&g=............|
-00000180  15 28 d5 1e aa c9 58 17  48 85 f7 13 17 6f 55 c3  |.(....X.H....oU.|
-00000190  dc 9d 2e 7e 67 45 7a cb  80 a7 e5 77 86 96 36 4d  |...~gEz....w..6M|
-000001a0  f7 df 27 7d f4 5d 53 9b  be e6 b2 b9 44 b9 86 e9  |..'}.]S.....D...|
-000001b0  8f 33 26 4e 20 97 e4 34  66 58 6d d5 28 be e8 84  |.3&N ..4fXm.(...|
-000001c0  de 2f 19 f2 46 52 80 84  e9 ef 0e 6c 55 5c 43 8c  |./..FR.....lU\C.|
-000001d0  51 19 8b 22 30 b7 b3 eb  9f ed 35 a1 fe 09 aa 6a  |Q.."0.....5....j|
-000001e0  f8 b6 37 7e 20 4c e5 76  ae 10 4c dd 67 7c 07 e2  |..7~ L.v..L.g|..|
-000001f0  0c dc 78 77 a1 8e c1 d1  aa fa d3 36 8b 9c 74 ed  |..xw.......6..t.|
-00000200  e2 fe 84 98 40 95 f2 1a  a6 fd 77 cf 47 d3 c3 d6  |....@.....w.G...|
-00000210  bc 38 45 a9 94 63 13 52  2d 7b 3f 3d 06 1e 0a 31  |.8E..c.R-{?=...1|
-00000220  cb 98 1d 18 fa a7 86 21  65 c7 58 dd 78 13 2d 4d  |.......!e.X.x.-M|
-00000230  76 57 9d 65 15 a3 2d be  7f c9 58 78 b7 89 3c d6  |vW.e..-...Xx..<.|
-00000240  dc 7e 5b c5 1b 93 78 04  7b ca ef 61 77 6c 27 6b  |.~[...x.{..awl'k|
-00000250  a5 30 67 43 64 a7 30 f0  dd 5c 63 92 76 9a e3 a2  |.0gCd.0..\c.v...|
-00000260  31 12 49 8e c4 7e 80 ce  1e ce 94 66 2f 6f 16 03  |1.I..~.....f/o..|
-00000270  03 00 35 39 86 a0 5a 88  07 66 5f 43 59 ed fb b5  |..59..Z..f_CY...|
-00000280  0c 0b ee ff 76 62 28 ea  62 7e 53 72 3d d9 26 9f  |....vb(.b~Sr=.&.|
-00000290  06 64 99 83 a5 3c 59 45  84 4d 79 86 1d b4 21 14  |.d...<YE.My...!.|
-000002a0  29 df f1 99 aa 6a 64 91  16 03 03 00 98 22 32 c2  |)....jd......"2.|
-000002b0  63 2c 82 b9 47 02 65 97  6b 14 fc 35 b8 20 ce 3c  |c,..G.e.k..5. .<|
-000002c0  1b 16 fd 51 55 e8 31 b5  58 e6 64 a8 2b b0 f2 ab  |...QU.1.X.d.+...|
-000002d0  31 7a cd 3e 32 43 64 eb  08 b0 52 d4 81 56 e3 04  |1z.>2Cd...R..V..|
-000002e0  4e d2 1a b8 f6 ae 64 d2  c0 05 9b 18 84 71 a7 ad  |N.....d......q..|
-000002f0  ea 49 f6 b5 ae 91 ad 66  6f cb fa 56 de 1e 40 22  |.I.....fo..V..@"|
-00000300  7f d3 44 c4 a7 bf b1 7b  61 e3 09 1f fe 3b 4b 7b  |..D....{a....;K{|
-00000310  5a 3f ae 4e c4 5c a8 ac  a4 c2 fc 0e 1f 12 4f 9b  |Z?.N.\........O.|
-00000320  f9 e0 a2 89 ab a0 bb e8  f9 97 5a 7c 8d e8 58 87  |..........Z|..X.|
-00000330  3f 4c 1c f3 ff 6e b9 a0  e6 f7 e4 c2 43 cc af 9e  |?L...n......C...|
-00000340  06 3a 1c ee ef 14 03 03  00 11 8b 6d c3 12 83 c4  |.:.........m....|
-00000350  2f e7 67 81 db 18 9a 33  e6 fa 82 16 03 03 00 20  |/.g....3....... |
-00000360  ef c9 6f 3f b7 9d 9d 2d  a0 05 b6 fd 74 8e ff de  |..o?...-....t...|
-00000370  cc 4b ca 4c 5b 4d 61 30  76 b5 f3 7a d1 46 d6 6a  |.K.L[Ma0v..z.F.j|
+00000000  16 03 03 00 35 a7 bb 37  bb b1 b0 8e 12 72 8b a8  |....5..7.....r..|
+00000010  c5 d4 cc 44 1c 4b 87 1f  bc cb 39 35 60 fb 06 de  |...D.K....95`...|
+00000020  44 ac 0a c5 13 cb 15 1b  ce 6b d8 45 28 d6 80 1b  |D........k.E(...|
+00000030  06 1f 32 4c 26 81 77 08  9c 23 14 03 03 00 11 c0  |..2L&.w..#......|
+00000040  1b 3b 4d e8 9d ba d9 2c  50 10 03 b9 0c 57 83 60  |.;M....,P....W.`|
+00000050  16 03 03 00 20 e0 d7 07  fe 04 89 25 3c b6 c0 8a  |.... ......%<...|
+00000060  33 14 6c 3e f4 48 5c 17  33 f8 f0 11 3a cb d8 17  |3.l>.H\.3...:...|
+00000070  cd 42 be 22 68                                    |.B."h|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 2e d9 0e  1b 6b 4b 9a 60 96 e9 38  |.........kK.`..8|
-00000010  35 a3 72 3d c4 5b 16 03  03 00 20 62 1f 2b 02 e8  |5.r=.[.... b.+..|
-00000020  22 0a 89 a2 f6 60 8a da  f2 09 52 5a 92 12 a8 f6  |"....`....RZ....|
-00000030  c3 ee 25 17 6b 91 25 3e  2b 75 ba 17 03 03 00 19  |..%.k.%>+u......|
-00000040  b9 4e 6b c3 74 30 39 f9  3f a2 aa af 80 49 6b 8a  |.Nk.t09.?....Ik.|
-00000050  f2 a1 9b f5 c7 34 f7 1b  2f 16 03 03 00 14 2d 25  |.....4../.....-%|
-00000060  74 c2 c7 80 a8 5f 65 ff  65 b0 c2 50 c8 bc fe 8c  |t...._e.e..P....|
-00000070  d4 9e                                             |..|
+00000000  14 03 03 00 11 05 69 30  af cd 8e 28 8b 04 3c de  |......i0...(..<.|
+00000010  39 2c cc 79 60 dc 16 03  03 00 20 64 e4 49 e1 a5  |9,.y`..... d.I..|
+00000020  59 be ed d9 04 59 24 01  16 65 aa b9 22 7d 91 5f  |Y....Y$..e.."}._|
+00000030  e5 e4 db a7 67 a0 10 51  7e 3b 77 17 03 03 00 19  |....g..Q~;w.....|
+00000040  70 cc 7d 13 21 aa ac d3  fb a7 ee cc f6 db 51 4b  |p.}.!.........QK|
+00000050  2d 2a e2 66 f4 ba 29 aa  e1 16 03 03 00 14 e2 ba  |-*.f..).........|
+00000060  56 31 77 97 4a 4a a5 f0  05 28 d5 9f b7 3e 38 50  |V1w.JJ...(...>8P|
+00000070  1f 1b                                             |..|
 >>> Flow 11 (client to server)
-00000000  16 03 03 00 ad d0 25 9a  38 60 d3 94 8e b8 23 45  |......%.8`....#E|
-00000010  44 67 95 20 79 1a 27 5f  cf bb dc 72 8c 95 2a 02  |Dg. y.'_...r..*.|
-00000020  1d d9 80 c6 61 12 c2 5c  ae d5 62 a9 aa b0 4a d0  |....a..\..b...J.|
-00000030  13 ad 6d ae df c9 63 e2  6b 27 bb ca 88 c3 dc 8b  |..m...c.k'......|
-00000040  e9 bc 0b fb 32 d6 0f 99  b6 d1 03 7e c9 8d 72 ee  |....2......~..r.|
-00000050  09 7b 82 f1 79 11 a7 23  43 8b 77 b8 a9 bd 9e 67  |.{..y..#C.w....g|
-00000060  43 03 79 88 34 ab c2 6b  d1 2a cf c7 c9 b6 14 ee  |C.y.4..k.*......|
-00000070  ee 32 01 10 fb 85 dc 5a  04 cf 9a ea 8d 8c fc f8  |.2.....Z........|
-00000080  b3 b2 49 c0 93 37 93 09  24 1c 26 97 43 5f dd 09  |..I..7..$.&.C_..|
-00000090  7a 0d c0 6c bd 17 df 78  37 3d 23 6b 9d 27 d2 f7  |z..l...x7=#k.'..|
-000000a0  1c 2e 82 5c ba 95 1c 0f  b3 40 af 9f 2f 5e 42 40  |...\.....@../^B@|
-000000b0  cc b9                                             |..|
+00000000  16 03 03 00 b1 86 78 3d  4f eb 03 b0 00 ca a5 94  |......x=O.......|
+00000010  9d 70 04 ff 30 82 59 9c  ea 95 44 02 f0 14 fa 3c  |.p..0.Y...D....<|
+00000020  aa af fa e8 17 3c ac 69  91 3d b6 23 85 85 7a be  |.....<.i.=.#..z.|
+00000030  11 9e 17 4e 32 79 de 3e  04 54 71 d0 ae 94 03 97  |...N2y.>.Tq.....|
+00000040  d1 90 50 1f d5 8d d3 ff  aa ce 0a fb 81 bd e9 11  |..P.............|
+00000050  3f c2 c5 68 f9 e6 71 00  4f d9 ef cb c9 fd 0e 0d  |?..h..q.O.......|
+00000060  23 ce 04 f3 19 86 cb 4c  a0 71 52 8e c2 90 a1 5b  |#......L.qR....[|
+00000070  e2 1e f4 e7 24 4c 9a b0  0c fc eb 70 d0 94 44 4e  |....$L.....p..DN|
+00000080  fc 5d 2e 16 2d 0f ff 61  20 3a 4d 19 cd 1c 22 d7  |.]..-..a :M...".|
+00000090  d0 23 ff a9 a1 bf 79 7c  91 ba d8 15 47 9a a3 88  |.#....y|....G...|
+000000a0  cb 06 f9 5d bd 8b c1 cb  f6 16 ee 5d af 9c 7a 54  |...].......]..zT|
+000000b0  0c af 31 ee 4a d0                                 |..1.J.|
 >>> Flow 12 (server to client)
-00000000  16 03 03 00 81 39 20 22  4a e1 4e 21 2e 78 35 50  |.....9 "J.N!.x5P|
-00000010  8a d4 c4 c6 a9 20 74 8e  10 4b fd 31 4c ba c4 7f  |..... t..K.1L...|
-00000020  14 91 ab 4b 7a b2 7a 86  56 cc 61 ed 12 63 4a d5  |...Kz.z.V.a..cJ.|
-00000030  b5 c9 48 6e ae 10 71 fc  30 f5 e5 36 8b e2 7d 9d  |..Hn..q.0..6..}.|
-00000040  93 e2 34 cd 8e a0 72 c4  19 9b 62 eb 9b c4 5e c3  |..4...r...b...^.|
-00000050  df 22 d4 16 4d 88 b1 d5  e5 74 ac 9d 38 40 7d 1f  |."..M....t..8@}.|
-00000060  40 bd 86 e5 fc 19 88 bb  67 cf 3f 22 0f 39 1f 8f  |@.......g.?".9..|
-00000070  40 5c ee 29 48 00 c1 bf  6a f1 85 51 03 c0 e8 7a  |@\.)H...j..Q...z|
-00000080  2e f4 2a f9 b6 fb 16 03  03 02 69 59 b1 5a b9 98  |..*.......iY.Z..|
-00000090  86 77 af 76 a7 4c 69 0d  83 79 3c 9a b9 3c dd 49  |.w.v.Li..y<..<.I|
-000000a0  f2 0f ef d2 38 ac 31 b0  9b 5d 57 ed a7 ca f9 79  |....8.1..]W....y|
-000000b0  7c ef 58 f7 ca 7e 0c 60  1c 53 09 c5 06 dd b8 31  ||.X..~.`.S.....1|
-000000c0  09 88 af 50 9f c2 2a 2c  24 89 9e 57 ae c8 e6 49  |...P..*,$..W...I|
-000000d0  f4 6f 46 e9 dd 38 f1 52  e9 06 50 38 69 b3 e1 69  |.oF..8.R..P8i..i|
-000000e0  f5 33 28 54 39 43 05 b9  04 04 c2 d9 3d 34 da 48  |.3(T9C......=4.H|
-000000f0  99 7e 8a b2 59 d1 d3 20  da 34 c8 ab 91 f7 66 69  |.~..Y.. .4....fi|
-00000100  3a 4f fc 6d ee e6 ef f5  c0 b0 08 bf 59 c0 f8 e5  |:O.m........Y...|
-00000110  dc c6 dc c6 49 a7 d5 3c  22 0f e3 9f 39 0b 2a 09  |....I..<"...9.*.|
-00000120  7a 56 f8 90 33 05 06 09  21 6f 6a 53 0d 89 63 2a  |zV..3...!ojS..c*|
-00000130  76 28 19 33 73 e5 a0 2a  fa d2 82 bf 4c 43 84 f9  |v(.3s..*....LC..|
-00000140  e1 bb 7f 31 62 04 c5 26  ed 16 40 f5 6a 04 e0 c5  |...1b..&..@.j...|
-00000150  4e fe bd e3 4c 57 e2 61  41 2f 9a 95 7f 8a e1 34  |N...LW.aA/.....4|
-00000160  64 f4 fc ce 13 e5 0c 68  c1 e5 29 df e7 b1 56 0b  |d......h..)...V.|
-00000170  42 6b fc d6 5d 63 0b 3c  0c ca ce 38 11 50 f2 64  |Bk..]c.<...8.P.d|
-00000180  1a 6e 16 da 3e 69 cf 82  ba a0 03 0f 9d 72 ed 10  |.n..>i.......r..|
-00000190  78 b2 54 c0 be 9c 16 fa  15 4b 88 db dd 85 dd 08  |x.T......K......|
-000001a0  bd f4 50 a0 50 01 77 7a  cf 20 c1 3e 50 55 5f bd  |..P.P.wz. .>PU_.|
-000001b0  4a ba b4 d5 6d 51 38 b2  6d 4f fc b5 af b9 92 ff  |J...mQ8.mO......|
-000001c0  c4 44 f1 0e db 4d 71 09  15 b3 c3 37 47 57 03 35  |.D...Mq....7GW.5|
-000001d0  95 de da 33 31 8c 60 bc  8a 97 2d f8 27 9b 4e dc  |...31.`...-.'.N.|
-000001e0  2a 6d aa 3e 4d eb 8f 97  b8 fa d4 ef f6 27 d9 da  |*m.>M........'..|
-000001f0  a6 fe 38 91 4b 96 ff 75  4b 71 52 9f 37 e4 d9 85  |..8.K..uKqR.7...|
-00000200  a8 d8 ac 21 e9 b2 c0 4f  c0 c0 e3 3a 9f ab e0 93  |...!...O...:....|
-00000210  dc 03 18 30 92 55 33 67  58 f3 47 f3 0a 95 bc 33  |...0.U3gX.G....3|
-00000220  70 73 e1 5b 9d 63 cf f7  c7 9b da 9e 5d 2e 7a 66  |ps.[.c......].zf|
-00000230  03 b1 b8 5c fa b9 f4 fb  4e 0b 38 9a 97 f0 c9 e5  |...\....N.8.....|
-00000240  ce 18 33 ea 66 1c 59 cd  41 3e af 71 7c bf 00 a0  |..3.f.Y.A>.q|...|
-00000250  d9 ee 20 d7 80 a9 5d 55  b8 f8 92 7b 7e 4f bc 66  |.. ...]U...{~O.f|
-00000260  92 98 6a c6 15 5b e3 1d  59 14 d9 d0 5a 30 c0 4d  |..j..[..Y...Z0.M|
-00000270  37 f5 d9 40 a4 f9 f4 ad  b6 cf 55 98 03 1e e7 13  |7..@......U.....|
-00000280  5a 23 49 69 36 fa ae 9d  c2 cb 90 16 cc 36 f4 41  |Z#Ii6........6.A|
-00000290  3a c7 56 9f 05 23 be 1d  3f 8f 90 41 09 6b 88 9a  |:.V..#..?..A.k..|
-000002a0  70 91 76 e1 6d f0 5c 86  de 77 a4 83 c7 d5 3c c4  |p.v.m.\..w....<.|
-000002b0  67 ff b1 a2 e2 f5 61 4f  3b 4d 38 5d c9 c2 8c 97  |g.....aO;M8]....|
-000002c0  e2 a7 c0 72 3b 5e 4c d9  0f 18 a8 b9 77 8d 31 8f  |...r;^L.....w.1.|
-000002d0  d9 73 ac 33 a6 7a b5 bd  5e 58 b4 51 22 be d8 d4  |.s.3.z..^X.Q"...|
-000002e0  f5 e1 bc 37 80 d3 cf 3b  58 be 3e ce 33 83 1c 46  |...7...;X.>.3..F|
-000002f0  8b f3 f3 56 16 03 03 00  bc 30 f0 e1 0b eb 80 fe  |...V.....0......|
-00000300  5f fb 94 c9 5a 04 08 82  0f 0b b5 9b f7 f6 f6 d3  |_...Z...........|
-00000310  7e 68 e7 e5 2e cf a0 56  e6 b7 70 0a 63 5e 53 42  |~h.....V..p.c^SB|
-00000320  7f 27 ec 82 a0 5d e3 e8  77 27 40 3c 6d 47 ce dd  |.'...]..w'@<mG..|
-00000330  89 6e ac 0c 48 ab 25 d1  8e 4e 4e b8 99 69 a5 94  |.n..H.%..NN..i..|
-00000340  8d 19 ab f9 82 6b 28 e3  b8 5f f7 75 a8 dd 1f b5  |.....k(.._.u....|
-00000350  0a ff d1 72 4f 82 9b 9e  8e b3 3f f9 73 d6 cd ea  |...rO.....?.s...|
-00000360  c8 5b 51 4e 7f 16 a5 4b  81 5e 9a d7 a3 f2 64 35  |.[QN...K.^....d5|
-00000370  fd 2e dc 11 07 10 04 63  80 77 eb 0d d2 ba 9f 7c  |.......c.w.....||
-00000380  ad 66 eb 0a 2e f7 f2 3d  d3 a4 04 7b 83 8f 84 94  |.f.....=...{....|
-00000390  93 8e 8c 74 2a b0 3a 3e  e1 33 92 f9 59 e5 0a 56  |...t*.:>.3..Y..V|
-000003a0  95 3a 8b dc 1f 24 6c 08  07 c0 f1 20 6d 96 43 71  |.:...$l.... m.Cq|
-000003b0  bf c6 92 81 e3 16 03 03  00 3a 91 c1 13 a0 26 c9  |.........:....&.|
-000003c0  12 6a 09 23 5b 8b e8 da  10 cc 4d 00 ed 9e a6 09  |.j.#[.....M.....|
-000003d0  d8 d4 c0 b7 f0 cd 5f 7a  6e 4d 31 21 f6 6a 22 e7  |......_znM1!.j".|
-000003e0  6e 25 11 94 4a f2 b1 f1  b2 c9 30 4b e4 cd f3 f5  |n%..J.....0K....|
-000003f0  ce 86 e7 5d 16 03 03 00  14 20 c5 91 f0 6e 21 b8  |...]..... ...n!.|
-00000400  e8 a1 bb cf 62 ed 4b 5a  fa 19 40 ea 54           |....b.KZ..@.T|
+00000000  16 03 03 00 81 d3 34 51  a2 7a 93 5e f9 ef 8f f7  |......4Q.z.^....|
+00000010  a3 be aa 40 2c 53 e4 5d  62 2e 19 4a bf f3 dc ce  |...@,S.]b..J....|
+00000020  da e8 49 8e 4d 0c 68 72  3f 79 74 59 e2 8d 0c 78  |..I.M.hr?ytY...x|
+00000030  b7 13 05 0f 4f df 4f 01  71 40 38 f3 79 b2 33 51  |....O.O.q@8.y.3Q|
+00000040  f5 25 73 11 9a 30 b9 3c  5f d2 8b 32 71 6f 0d ef  |.%s..0.<_..2qo..|
+00000050  6a 42 da f6 c5 1d a4 90  ad e4 08 60 39 55 19 97  |jB.........`9U..|
+00000060  a6 2c 5e 2c e3 96 ba 0c  54 50 bc b9 0f 3c 53 bd  |.,^,....TP...<S.|
+00000070  e7 63 5f 13 e8 ce 35 34  c4 d0 1b da 1a fd 5a 52  |.c_...54......ZR|
+00000080  6e 5f 43 e8 d0 22 16 03  03 02 69 42 85 86 7e 3e  |n_C.."....iB..~>|
+00000090  92 4c 49 8e 40 86 28 53  c2 aa 43 2f 49 00 fa ee  |.LI.@.(S..C/I...|
+000000a0  48 0d 01 ec 94 e0 37 1a  05 97 6e ec a4 71 1e aa  |H.....7...n..q..|
+000000b0  50 5a 49 e9 cc 21 b0 d6  ab 38 4a 30 a7 84 ec 7d  |PZI..!...8J0...}|
+000000c0  38 34 91 63 3f 1a 59 eb  22 91 9b 23 23 b1 3f 7d  |84.c?.Y."..##.?}|
+000000d0  0c 70 23 71 0d 50 09 80  21 56 fe f2 c8 14 3d 19  |.p#q.P..!V....=.|
+000000e0  91 04 a8 10 b8 2b b0 cb  ff b7 6f 53 62 86 61 22  |.....+....oSb.a"|
+000000f0  4e 6d 67 12 d3 18 ac 90  ab 62 42 0f cb 08 47 73  |Nmg......bB...Gs|
+00000100  42 97 01 37 67 13 99 49  d6 f1 7f 0d 8a 83 6b 01  |B..7g..I......k.|
+00000110  00 76 d9 3a bd 0c 7a 64  c7 49 9e 06 d6 6c 04 48  |.v.:..zd.I...l.H|
+00000120  07 cc 96 03 f1 fe 38 76  b2 c3 97 ae 37 57 25 5e  |......8v....7W%^|
+00000130  54 18 07 b5 e2 6a ca fe  07 01 d7 9c a6 5c 95 df  |T....j.......\..|
+00000140  02 66 88 53 51 23 ba f2  0f b2 66 b2 df 14 61 28  |.f.SQ#....f...a(|
+00000150  50 cd 7a 56 47 79 33 6e  75 0d b6 0d 66 69 eb c6  |P.zVGy3nu...fi..|
+00000160  07 31 97 10 46 ec a7 59  b6 02 0b ab 40 d3 ce 88  |.1..F..Y....@...|
+00000170  62 aa ab ce 1b 73 9a 62  d7 8c 7c ca 40 a0 bb 1d  |b....s.b..|.@...|
+00000180  ff f4 85 54 fe ae 83 61  10 ec 38 64 ab 60 36 e1  |...T...a..8d.`6.|
+00000190  88 92 ba 74 e0 68 30 0b  61 7b da eb 3b d3 6b ed  |...t.h0.a{..;.k.|
+000001a0  fc eb 3f 98 dd 30 f1 28  bd e0 07 6b 77 53 29 02  |..?..0.(...kwS).|
+000001b0  d7 18 69 2b ac 0b 4c 38  3b 35 e0 15 91 c4 34 42  |..i+..L8;5....4B|
+000001c0  74 67 c0 2a 2b df 2f 70  13 7c 99 ba f6 cc e4 f4  |tg.*+./p.|......|
+000001d0  bd 3c 7f cd 08 b4 3c 05  da bf c7 01 61 93 21 d6  |.<....<.....a.!.|
+000001e0  1b ca b0 35 d1 89 f3 08  67 85 93 c9 da 6f cf a4  |...5....g....o..|
+000001f0  ad 1e a8 70 71 4a ac 56  73 25 8f 9c 25 13 5f 2c  |...pqJ.Vs%..%._,|
+00000200  20 bc f2 56 af a0 03 38  43 9c 83 79 33 ea 81 8c  | ..V...8C..y3...|
+00000210  d8 5d c0 50 d4 44 cd df  55 e7 4e fc f6 67 55 92  |.].P.D..U.N..gU.|
+00000220  39 a2 ec 25 3e 1f 7e 14  28 3b d8 84 f5 83 66 c4  |9..%>.~.(;....f.|
+00000230  e1 d7 c3 63 51 d7 4e e4  72 1a da 76 ce 91 6b 56  |...cQ.N.r..v..kV|
+00000240  0a 68 42 63 7e 57 31 98  cc d0 e0 3c 7c 7e 81 be  |.hBc~W1....<|~..|
+00000250  be 37 8d cd e7 da df 91  55 8c 71 e3 67 ec bf 6e  |.7......U.q.g..n|
+00000260  4c 5a a6 b6 2b 2c 31 0b  da 19 66 26 f1 92 c2 7e  |LZ..+,1...f&...~|
+00000270  fd 12 50 6f 04 ee 83 85  bb d0 f1 77 12 10 c9 e7  |..Po.......w....|
+00000280  4a 2f 17 96 55 0f 7e 1e  fd 6d 18 13 74 a8 54 38  |J/..U.~..m..t.T8|
+00000290  a5 ef bb 70 c9 71 07 09  c5 a3 26 f9 73 1f d0 e8  |...p.q....&.s...|
+000002a0  a2 23 a1 46 46 1b f6 b1  e7 ac 22 22 ee df b9 5b  |.#.FF.....""...[|
+000002b0  38 02 c6 59 33 e5 12 0b  9f 49 e2 d7 de 77 30 ac  |8..Y3....I...w0.|
+000002c0  1e a0 ee 20 9f 1b 1d e0  8c fd d4 02 09 7b 1b d6  |... .........{..|
+000002d0  c7 41 de 67 90 71 5f 06  ea ac 18 e7 5f 11 67 c3  |.A.g.q_....._.g.|
+000002e0  d6 5d c1 37 0a 67 5b f7  93 93 eb 29 70 e3 cb 7f  |.].7.g[....)p...|
+000002f0  2c c9 bb 6b 16 03 03 00  bc ab 60 8e 1d 2e e1 42  |,..k......`....B|
+00000300  81 91 89 69 78 5d 99 9c  e7 1b d1 ac 36 39 c5 32  |...ix]......69.2|
+00000310  58 4e 4c 48 b9 15 eb 21  b6 24 df 8e b2 16 f0 95  |XNLH...!.$......|
+00000320  cd 57 8e 14 3b 5b a2 f9  7a 10 0d fa 57 52 70 f9  |.W..;[..z...WRp.|
+00000330  b8 a9 b0 fd 22 0a 51 ef  dd ba 3c fb 68 00 05 45  |....".Q...<.h..E|
+00000340  d6 c3 1f 56 91 b4 06 80  a4 28 84 a5 bb 11 72 af  |...V.....(....r.|
+00000350  b7 f6 14 58 76 b7 76 ad  1b e6 65 57 af f7 46 a2  |...Xv.v...eW..F.|
+00000360  bc 60 12 6d 30 d3 cf 26  62 9d 9f 19 b0 28 96 d2  |.`.m0..&b....(..|
+00000370  e2 43 de 64 90 49 1d 29  2c bb 59 4c c7 d1 9b be  |.C.d.I.),.YL....|
+00000380  c3 e9 ae 8e 74 36 1b 03  00 43 65 56 30 3b e6 8b  |....t6...CeV0;..|
+00000390  4c d9 98 a2 f7 2b 06 77  4b 9c 53 c4 7f 24 88 75  |L....+.wK.S..$.u|
+000003a0  30 91 66 fa ba 9c 7f 84  ab c1 51 21 1c d3 2e 93  |0.f.......Q!....|
+000003b0  f9 4d db 6e 08 16 03 03  00 14 ed f9 cc ef c4 2b  |.M.n...........+|
+000003c0  fd 97 fe 35 ad 33 01 46  9b 52 d7 e9 49 c2        |...5.3.F.R..I.|
 >>> Flow 13 (client to server)
-00000000  16 03 03 02 69 1a b5 80  9c c6 42 be a6 d9 d1 c8  |....i.....B.....|
-00000010  0b 2c f7 f8 2a 1a 02 f6  db 48 8b 5c 45 fc 28 41  |.,..*....H.\E.(A|
-00000020  a4 db 35 fb a7 a9 72 07  19 86 9e e9 dc 53 48 fb  |..5...r......SH.|
-00000030  97 94 f3 a0 0d 8d 46 69  cf eb d9 ea de 21 a3 f4  |......Fi.....!..|
-00000040  b9 94 4f 8f 09 c3 de 66  fa 20 83 34 fc 50 ae c6  |..O....f. .4.P..|
-00000050  13 f6 7c c5 80 45 17 51  af a9 da bd 24 dd f6 15  |..|..E.Q....$...|
-00000060  8e c4 b4 e6 10 54 85 23  9d fe 72 b1 4c 2f ab ec  |.....T.#..r.L/..|
-00000070  78 9a 06 60 03 96 f7 d0  af dd 94 26 c9 67 1d e5  |x..`.......&.g..|
-00000080  9f 87 22 c4 11 82 f1 4c  f5 68 a7 fd d8 f3 dc ac  |.."....L.h......|
-00000090  35 90 6b c2 97 1c 78 54  d9 b2 3c d8 9d 13 66 42  |5.k...xT..<...fB|
-000000a0  6e 3b 1b 8f 32 4e 8f b5  a0 60 6e e4 35 fd d5 b4  |n;..2N...`n.5...|
-000000b0  f8 fb a6 a9 c7 b7 31 39  8e 90 0c 42 bc 1a 4f 67  |......19...B..Og|
-000000c0  fa b3 10 a8 45 01 88 8a  dd 41 43 c6 6c 41 9d 28  |....E....AC.lA.(|
-000000d0  bd 4c 43 85 4c 3b 7c 03  c4 55 70 f1 49 a0 d6 52  |.LC.L;|..Up.I..R|
-000000e0  5c 49 3e 2b d7 e8 a9 75  5e 92 bf f3 4c 1c c3 7e  |\I>+...u^...L..~|
-000000f0  69 ca 52 25 07 bb 54 e0  58 2d 28 ba 50 30 81 e8  |i.R%..T.X-(.P0..|
-00000100  93 0d 9d 78 3d c0 f1 c3  34 72 29 f1 da 60 de 84  |...x=...4r)..`..|
-00000110  aa fc d3 0f 2b 1e 1a 9c  7c af 6f 6a 4c cc 88 36  |....+...|.ojL..6|
-00000120  03 03 34 79 f9 89 6d 41  bb 19 61 6a 60 75 d7 0f  |..4y..mA..aj`u..|
-00000130  dc 22 7a e4 36 91 32 2b  99 24 36 19 4b 4c c4 ae  |."z.6.2+.$6.KL..|
-00000140  4f 98 6d f0 97 ce bc b4  ee 97 30 97 0b 54 8c 14  |O.m.......0..T..|
-00000150  8f d5 9d 44 ae 0a a6 07  9f 39 f6 66 80 cb fa 27  |...D.....9.f...'|
-00000160  bb 2f 26 bb c3 1a a4 9b  a0 d3 e8 75 13 49 da 0a  |./&........u.I..|
-00000170  8f cc e8 15 77 f8 05 c2  17 a0 ff e7 2a 59 bc c8  |....w.......*Y..|
-00000180  67 b5 7e b8 78 1e 32 81  22 3e 57 28 ee 51 96 b7  |g.~.x.2.">W(.Q..|
-00000190  0e dc 3f d1 00 16 a5 eb  01 cb c3 e3 5b 01 ad a9  |..?.........[...|
-000001a0  d5 1b ac 9b e2 0d 9a 6f  7a 2f f1 7d 05 57 6d 2d  |.......oz/.}.Wm-|
-000001b0  9d 35 68 88 e7 c5 e0 fb  9d 87 a7 ef 71 d8 47 b8  |.5h.........q.G.|
-000001c0  19 8e 87 d8 b1 36 0f 52  ab 98 8b 97 43 53 86 be  |.....6.R....CS..|
-000001d0  9d 86 2a cd 7c b0 46 c4  48 89 5b 6c 1e 93 9e a2  |..*.|.F.H.[l....|
-000001e0  15 af 60 8f 84 75 99 97  53 11 23 f9 0d ba 78 12  |..`..u..S.#...x.|
-000001f0  9b a9 04 91 d0 3a b3 4d  7b 67 a0 fa 78 5c 19 d6  |.....:.M{g..x\..|
-00000200  88 d2 21 f6 8d e4 91 d1  76 95 67 9d 4e 3b a1 d2  |..!.....v.g.N;..|
-00000210  61 c3 d2 a6 53 fd 82 93  20 7e f6 07 a0 49 3a ea  |a...S... ~...I:.|
-00000220  bc 73 03 0b f2 df 51 ac  35 d8 e4 35 9d 13 56 b5  |.s....Q.5..5..V.|
-00000230  be fc 7c 36 8b 37 a0 71  57 62 bd 89 38 18 90 1e  |..|6.7.qWb..8...|
-00000240  7a 1f b3 8f 73 55 32 94  5a 3a 31 91 b3 95 bd 61  |z...sU2.Z:1....a|
-00000250  ea 93 9d f0 38 33 fb 5b  28 3d a7 29 a4 91 de 85  |....83.[(=.)....|
-00000260  9c 16 63 10 81 c6 e0 11  92 3d 53 db 69 95 16 03  |..c......=S.i...|
-00000270  03 00 35 f7 3a b7 d1 20  aa f7 ed b1 c7 46 52 cb  |..5.:.. .....FR.|
-00000280  6e dd e2 f4 ae 83 20 cd  6c 59 b5 26 f9 81 7e 6c  |n..... .lY.&..~l|
-00000290  ed e9 0b 2a f1 3a dc f8  d6 ed e5 6d 89 14 3d 79  |...*.:.....m..=y|
-000002a0  e7 c8 af 89 30 eb 98 3d  16 03 03 00 98 a0 59 2f  |....0..=......Y/|
-000002b0  cd d9 f6 63 e3 53 47 77  e5 c4 fc 2e 12 d7 24 8a  |...c.SGw......$.|
-000002c0  4c c7 d8 c9 77 4f bc 3c  af 93 6f 57 3d 6f 5d 1c  |L...wO.<..oW=o].|
-000002d0  6a 5a 2c 42 1c e0 92 d5  5e 34 c8 a5 9e 11 21 16  |jZ,B....^4....!.|
-000002e0  01 1a 08 af 4e f6 a1 e3  19 a6 81 41 3d 7a f3 d1  |....N......A=z..|
-000002f0  e0 9e 55 90 42 4b d9 5c  46 b7 eb c8 fb 83 1c 97  |..U.BK.\F.......|
-00000300  9e d9 74 bb 7f 2f 4d 61  89 46 db 32 da 1a 76 95  |..t../Ma.F.2..v.|
-00000310  88 f8 ca 62 14 88 dc 97  b8 58 82 74 16 78 be c5  |...b.....X.t.x..|
-00000320  f9 78 a4 88 c1 d4 6b 36  6e 54 60 a5 21 30 47 07  |.x....k6nT`.!0G.|
-00000330  e8 2d 22 ce a5 17 fb 43  10 9d 74 c9 64 a3 db ac  |.-"....C..t.d...|
-00000340  d9 24 7a a7 5d 14 03 03  00 11 68 20 87 e9 9b 91  |.$z.].....h ....|
-00000350  81 67 2b 31 c4 47 e8 9b  2e 7c c4 16 03 03 00 20  |.g+1.G...|..... |
-00000360  ef 6f 3d 0f 23 fa 77 8c  a9 46 d9 0d b0 d9 f8 16  |.o=.#.w..F......|
-00000370  62 e2 07 21 ec b6 a7 78  ce a6 ea b3 68 c1 c7 af  |b..!...x....h...|
+00000000  16 03 03 00 35 77 aa f6  e5 92 a0 83 9f b7 0e e3  |....5w..........|
+00000010  d2 ae 3e 72 3d 67 59 0a  67 04 10 3c 44 9c 6f 8e  |..>r=gY.g..<D.o.|
+00000020  ea 0c 79 ed da e5 b8 51  79 45 b2 9a 23 fd b5 5a  |..y....QyE..#..Z|
+00000030  40 3d 84 90 b1 72 45 36  98 80 14 03 03 00 11 69  |@=...rE6.......i|
+00000040  3d 4e 7a a6 d0 a3 08 5f  5c 11 12 a6 78 7f ec c3  |=Nz...._\...x...|
+00000050  16 03 03 00 20 6f 61 99  d2 0f 9b 70 f4 13 0a 15  |.... oa....p....|
+00000060  66 d9 05 22 40 db 66 cb  75 16 de c3 91 d7 71 21  |f.."@.f.u.....q!|
+00000070  5d 9c 4c 5a 87                                    |].LZ.|
 >>> Flow 14 (server to client)
-00000000  14 03 03 00 11 bb 45 96  9e 08 cb e4 24 c2 e3 71  |......E.....$..q|
-00000010  40 d1 ef a1 5e 2f 16 03  03 00 20 1b 3f 69 fb ae  |@...^/.... .?i..|
-00000020  cd 98 15 59 16 14 cf a5  16 af 36 6d 6d 3a 49 06  |...Y......6mm:I.|
-00000030  a6 f9 cf 53 ea 9a b7 3b  48 d2 e3 17 03 03 00 19  |...S...;H.......|
-00000040  72 2c 82 a0 8c 6c 8b c3  78 e4 41 1b ff ba 92 6d  |r,...l..x.A....m|
-00000050  3c 4d 9c c3 95 e3 27 b9  82                       |<M....'..|
+00000000  14 03 03 00 11 d8 e7 6c  77 f7 f2 11 7c 9b 9b 4e  |.......lw...|..N|
+00000010  3a a6 e5 d6 2b 47 16 03  03 00 20 b6 28 ee e6 7b  |:...+G.... .(..{|
+00000020  27 b1 3d c7 b4 d0 ba aa  65 b8 44 f1 8b 1e c2 1a  |'.=.....e.D.....|
+00000030  1c 63 4d d6 d8 f6 08 e2  9b bb 34 17 03 03 00 19  |.cM.......4.....|
+00000040  ed 7c 4e b7 db f6 88 4f  68 85 e9 ff a3 48 96 39  |.|N....Oh....H.9|
+00000050  5d 39 69 5b 92 8f 43 c5  ba                       |]9i[..C..|
 >>> Flow 15 (client to server)
-00000000  15 03 03 00 12 3d f9 72  53 84 b5 a4 ec 27 39 cc  |.....=.rS....'9.|
-00000010  72 29 c0 e6 37 7b 0f                              |r)..7{.|
+00000000  15 03 03 00 12 45 0b 80  2d f1 c6 08 39 3c 70 07  |.....E..-...9<p.|
+00000010  1d d1 b6 33 01 79 ef                              |...3.y.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
index 737ccc6..a89bd2d 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 75 f6 1b 17 2f  |....Y...U..u.../|
-00000010  e0 d4 19 06 0d 93 90 51  46 d9 c3 a0 cd 45 6c 85  |.......QF....El.|
-00000020  94 87 01 21 3e 92 62 1d  e7 d1 39 20 07 26 a1 5b  |...!>.b...9 .&.[|
-00000030  d2 4a 61 40 ba 58 c0 23  0c 3f c3 08 5d 28 04 94  |.Ja@.X.#.?..](..|
-00000040  a9 34 37 28 64 75 6f 9c  ae fa 1f 24 cc a8 00 00  |.47(duo....$....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 15 c2 a7 b9 2f  |....Y...U....../|
+00000010  c7 f0 d8 ce 09 47 ff 49  c2 09 ea b1 59 ab ab cf  |.....G.I....Y...|
+00000020  d8 97 31 dd e6 5a 84 6e  39 af 23 20 7d 9c ed cb  |..1..Z.n9.# }...|
+00000030  b4 fc 4f 6b ec 07 75 b2  c4 ca 44 63 12 f5 35 95  |..Ok..u...Dc..5.|
+00000040  93 c8 6e d0 59 7e 58 cb  00 05 ae d7 cc a8 00 00  |..n.Y~X.........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,181 +54,129 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 84 74 e5 bc 24 39 39  |........ .t..$99|
-000002d0  e0 6e 35 fb 34 87 76 0d  78 89 35 5c 85 e7 92 da  |.n5.4.v.x.5\....|
-000002e0  e1 39 f4 b2 e7 ec d5 cd  58 04 01 00 80 cf 3a 57  |.9......X.....:W|
-000002f0  6a 8b b7 72 d8 a2 6b 47  87 77 8b 7a bf 63 6c e8  |j..r..kG.w.z.cl.|
-00000300  d4 20 6a 6a 9c 62 b6 ef  4b 9f a7 89 8c a6 fd 02  |. jj.b..K.......|
-00000310  92 2f 8d 07 44 09 f6 d9  03 99 39 49 1d 8d 1b 7f  |./..D.....9I....|
-00000320  eb eb 4b a6 fb 9f 83 3b  3d d3 61 3e e4 d3 22 24  |..K....;=.a>.."$|
-00000330  c1 44 76 e8 75 c7 aa 31  96 e3 50 bb 76 3e 87 02  |.Dv.u..1..P.v>..|
-00000340  b9 1d 82 dd 55 ee 05 b9  b5 1e 65 90 2c 50 c9 87  |....U.....e.,P..|
-00000350  49 dd 35 c8 84 67 6e 52  3a 3b ec 3c 63 f4 0f 95  |I.5..gnR:;.<c...|
-00000360  87 05 8e ec bd d7 97 9f  9a 14 78 d7 97 16 03 03  |..........x.....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 85 eb 3a 12 97 d7 9a  |........ ..:....|
+000002d0  a3 11 49 ba 0f 32 c8 4c  09 68 b4 15 22 1f fb 78  |..I..2.L.h.."..x|
+000002e0  71 25 40 8c 83 1e 0d 6e  65 04 01 00 80 a4 2b 3a  |q%@....ne.....+:|
+000002f0  aa 92 ce 24 47 ab 1f 02  4e e2 65 34 b3 15 65 0a  |...$G...N.e4..e.|
+00000300  57 73 d7 a9 27 c5 c7 da  cd 23 e1 8a 02 00 56 b8  |Ws..'....#....V.|
+00000310  44 90 d2 66 ad a2 05 f6  d6 27 dc 07 52 a9 e5 e6  |D..f.....'..R...|
+00000320  af 00 74 ea f0 42 d0 bc  f2 c7 94 bd 19 27 cb ca  |..t..B.......'..|
+00000330  53 96 6c 2e f6 87 8f 68  93 24 4d 8b 62 cd 15 a4  |S.l....h.$M.b...|
+00000340  7e 99 86 41 1f 4e 9b ac  3b 2a 23 64 8a 98 8b 0d  |~..A.N..;*#d....|
+00000350  4a 1c 37 f6 f4 bc fa 11  e7 07 e6 8f 3b 59 06 fd  |J.7.........;Y..|
+00000360  27 30 e1 45 ef 9f 91 30  42 86 31 11 9f 16 03 03  |'0.E...0B.1.....|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 3e a2 12  3b a4 83 4a c2 0e 93 d5  |.... >..;..J....|
-00000040  98 d5 2e 11 9e 60 60 23  78 5a 63 49 f1 7a ee c4  |.....``#xZcI.z..|
-00000050  47 00 6c 4e fb                                    |G.lN.|
+00000030  16 03 03 00 20 1d 93 0e  bd 9d 79 c8 be 62 9e c3  |.... .....y..b..|
+00000040  5b 6d 1e e7 3a d1 35 32  1b 20 3b 66 70 71 95 f4  |[m..:.52. ;fpq..|
+00000050  88 58 6d b8 f1                                    |.Xm..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 6d 78 5b 5f 1b  |.......... mx[_.|
-00000010  2c 05 ba 92 46 e2 f0 04  48 fa a1 da be 93 ed fd  |,...F...H.......|
-00000020  f5 f8 b8 dd 00 60 09 a6  36 3c c4                 |.....`..6<.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 76 95 22 fc b0  |.......... v."..|
+00000010  06 76 53 a8 f5 41 60 39  2b 22 ce 5e d9 d1 1b 6a  |.vS..A`9+".^...j|
+00000020  36 cc a2 3a 59 a0 a1 51  48 db d3                 |6..:Y..QH..|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 a4 db 13  bc c1 6e 06 9e 6d 1a c9  |..........n..m..|
-00000010  85 a7 e9 28 b8 27 74 19  8f 1a bc                 |...(.'t....|
+00000000  17 03 03 00 16 67 62 ca  a7 ec ee 51 18 ad 90 65  |.....gb....Q...e|
+00000010  fc 87 10 13 5c 2d 66 6f  e2 5b d6                 |....\-fo.[.|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 fa a3 77  3c 76 11 5d be 12 4f 6a  |.......w<v.]..Oj|
-00000010  f7 0d 26 73 ab 7c bd 4b  19                       |..&s.|.K.|
+00000000  16 03 03 00 14 11 51 b5  e4 d5 d7 df 48 69 2c f8  |......Q.....Hi,.|
+00000010  ff 11 fc 02 b2 00 80 30  aa                       |.......0.|
 >>> Flow 7 (client to server)
-00000000  16 03 03 00 ad 59 80 a4  91 95 56 2a 01 ee 04 84  |.....Y....V*....|
-00000010  f9 d2 dd a5 2c a6 46 a8  69 a3 c7 47 7e eb 54 da  |....,.F.i..G~.T.|
-00000020  ec cc 9d aa e1 0a b1 7c  e9 cf 9f c9 c8 12 62 35  |.......|......b5|
-00000030  d2 4a eb 28 0d 9b aa a4  d5 79 66 f7 72 4c 26 10  |.J.(.....yf.rL&.|
-00000040  b6 71 db 4a 68 8b 47 f9  47 e3 6d a6 4e 99 d5 0b  |.q.Jh.G.G.m.N...|
-00000050  27 b2 2c 23 9b 58 60 8a  37 a1 8e 26 09 26 2a 46  |'.,#.X`.7..&.&*F|
-00000060  e6 24 7f 9b cb 6b d1 9d  b1 c0 48 c9 50 8b ab 06  |.$...k....H.P...|
-00000070  05 57 ef 1a e0 bd ce db  ca 3d e1 59 df 24 4c 02  |.W.......=.Y.$L.|
-00000080  bf 1b 9e 48 52 42 6c dd  8f fa 82 68 56 52 a6 be  |...HRBl....hVR..|
-00000090  d0 93 cb 43 74 e1 2f 86  cc e1 4c fa ba fc 1d f0  |...Ct./...L.....|
-000000a0  d5 20 3a 79 b3 b8 b7 24  b5 cf 4c dd a5 d0 4d 18  |. :y...$..L...M.|
-000000b0  15 55                                             |.U|
+00000000  16 03 03 00 b1 92 1a 73  ea 30 62 10 b9 c7 83 ec  |.......s.0b.....|
+00000010  55 24 17 f7 ba a1 3a 13  5f cb 8b ff 64 79 5e 5b  |U$....:._...dy^[|
+00000020  6c 34 7b c8 0b 38 92 b6  14 7f fd 35 be ba 72 2d  |l4{..8.....5..r-|
+00000030  bd 78 e3 f6 bc 61 ba 65  83 a6 6a 5e cd 1f 34 ab  |.x...a.e..j^..4.|
+00000040  5d 84 58 03 06 a0 4d 32  a0 a9 42 92 8f d4 27 3d  |].X...M2..B...'=|
+00000050  e8 a5 75 9b b7 06 c2 3b  4f 8e 83 10 be 12 4f ea  |..u....;O.....O.|
+00000060  d1 e7 37 9c 29 dc a9 0f  aa f6 a1 0c 1c 3b 19 67  |..7.)........;.g|
+00000070  b1 7c 41 9a fd b8 dd 86  92 49 4f 7e 23 75 df 82  |.|A......IO~#u..|
+00000080  d0 ca 43 94 61 a8 d4 1f  3f 15 69 b0 6c bf f7 15  |..C.a...?.i.l...|
+00000090  1c 8d dc 61 11 73 3c 5e  b0 bd 23 a9 3d fb ed 1d  |...a.s<^..#.=...|
+000000a0  d5 3d 6d de b7 29 fe 85  0d af 85 6c 8a 32 90 09  |.=m..).....l.2..|
+000000b0  87 c2 a2 4f f9 9b                                 |...O..|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 10 b8 d9  9a 82 21 14 86 6d ef e4  |..........!..m..|
-00000010  b6 bc 10 84 80 a6 72 7b  dc 24 ba e1 e5 d2 bb d2  |......r{.$......|
-00000020  9f 09 d3 d7 37 20 ec 7d  bd 13 e0 bd 40 44 8a 6e  |....7 .}....@D.n|
-00000030  7f f6 d5 42 03 4b 00 b5  87 99 ac 6d 11 03 38 46  |...B.K.....m..8F|
-00000040  33 71 c4 10 ce da 36 d6  c1 41 9f 96 8e eb 4b 99  |3q....6..A....K.|
-00000050  24 07 8c 6b 88 2c f1 dd  31 35 ba 43 0f 60 bf b0  |$..k.,..15.C.`..|
-00000060  74 77 a9 d4 a7 65 f6 68  e2 70 4a 7e fe db ab 13  |tw...e.h.pJ~....|
-00000070  7f 51 c3 0f b4 93 42 12  d6 29 5d 44 5c df 17 6e  |.Q....B..)]D\..n|
-00000080  73 1d b8 95 fc 8b 16 03  03 02 69 64 5d 4f b4 3a  |s.........id]O.:|
-00000090  23 98 07 51 63 18 09 07  9a 8c dd 8e 51 a8 ca 23  |#..Qc.......Q..#|
-000000a0  37 21 f4 d5 e0 8f 03 1c  6f 6d c4 60 dd 99 8f 4b  |7!......om.`...K|
-000000b0  4c 11 f7 78 f8 aa f6 29  87 cf 4d ba 89 87 2a c9  |L..x...)..M...*.|
-000000c0  48 66 48 d3 a6 19 8a 84  f6 db 17 b4 59 5b e4 8e  |HfH.........Y[..|
-000000d0  8e ef fc 32 10 aa 0d 57  47 68 82 07 72 95 03 f6  |...2...WGh..r...|
-000000e0  e5 c1 c3 01 00 f9 85 4f  0f 85 37 73 f7 c5 af a2  |.......O..7s....|
-000000f0  37 96 ba 06 49 6a 2d a2  23 39 2e 9b f1 fc 01 de  |7...Ij-.#9......|
-00000100  53 75 ee 34 ae 27 ea 49  6a d8 d0 cd 9b e8 60 b7  |Su.4.'.Ij.....`.|
-00000110  f6 b1 8e 26 ec 6c 36 87  d6 70 49 07 e0 96 2a bd  |...&.l6..pI...*.|
-00000120  45 a3 b1 f5 dc b0 a3 4f  dc d8 c3 fd 4f fb 98 13  |E......O....O...|
-00000130  67 55 99 39 b5 16 19 72  9d f1 5a cf 6e 53 d9 03  |gU.9...r..Z.nS..|
-00000140  05 f5 81 07 a1 38 a1 e5  4c 76 51 1a ae f6 4b f6  |.....8..LvQ...K.|
-00000150  b2 a7 84 1e 2a 31 b0 b8  9f 41 e8 e5 32 18 44 4c  |....*1...A..2.DL|
-00000160  0b fb e3 d9 4c dd 45 c5  c4 c4 57 bf f7 5a dc f6  |....L.E...W..Z..|
-00000170  73 98 d4 ea 2f c0 cb 35  97 c1 45 94 37 87 d3 8c  |s.../..5..E.7...|
-00000180  65 3f ee a8 67 a6 00 80  92 02 76 e8 0a 04 ce 7a  |e?..g.....v....z|
-00000190  79 4f cd 70 1a 31 5a 03  83 01 de 1f 4a 46 39 4e  |yO.p.1Z.....JF9N|
-000001a0  d0 80 6e 67 d7 e6 fc ba  74 4b 57 d2 3c 19 7b 03  |..ng....tKW.<.{.|
-000001b0  ab 9a e2 f7 db 58 c2 b7  58 96 55 88 e6 e2 e2 f8  |.....X..X.U.....|
-000001c0  ab e9 b0 12 ef ff e6 53  7b 4e 01 2f 65 0d 05 f0  |.......S{N./e...|
-000001d0  95 9f 46 d2 ae e7 33 5c  37 56 ab 67 95 87 81 59  |..F...3\7V.g...Y|
-000001e0  f2 35 76 78 ed 13 63 a3  58 52 af 46 e6 aa c3 99  |.5vx..c.XR.F....|
-000001f0  37 9d 10 25 cc 7f 7e 63  e1 96 6d 7a 8e ac 9e 00  |7..%..~c..mz....|
-00000200  d1 0e 7a 48 b6 82 77 6a  a0 17 d1 77 70 f8 40 4a  |..zH..wj...wp.@J|
-00000210  c4 90 da b0 3f 25 68 f5  9f dd 5e ec 95 02 19 53  |....?%h...^....S|
-00000220  08 6a 13 11 88 9e 2b 25  b8 28 cd 58 36 d7 d3 95  |.j....+%.(.X6...|
-00000230  f5 91 63 92 ff 3b d2 4f  75 ae 47 6c 64 8a a4 76  |..c..;.Ou.Gld..v|
-00000240  48 96 a7 35 d6 35 22 96  4d 4f ee 45 fb 88 52 68  |H..5.5".MO.E..Rh|
-00000250  4e 38 93 e8 08 6a e6 f3  00 a7 f7 b0 0b 68 41 ab  |N8...j.......hA.|
-00000260  9b 3a 92 2b fd b2 71 14  77 91 48 e7 70 62 b5 b0  |.:.+..q.w.H.pb..|
-00000270  45 90 35 d2 b3 22 f5 70  6c 62 7f 55 6b 56 42 f8  |E.5..".plb.UkVB.|
-00000280  6c 87 a7 60 45 37 f0 41  41 ec 73 f5 f1 d9 d2 84  |l..`E7.AA.s.....|
-00000290  bd 88 bc 9b 43 ec 8b b3  c4 3a 59 2c 30 61 30 98  |....C....:Y,0a0.|
-000002a0  78 d3 e7 85 dd 7e 80 b8  fb b3 bf 7e 11 79 e8 20  |x....~.....~.y. |
-000002b0  aa b8 81 94 10 5c f8 ba  70 4c 1e 7c 35 8f 48 30  |.....\..pL.|5.H0|
-000002c0  17 38 d6 1c 91 ed 00 2c  f7 af 29 d3 cb 9b ab 6b  |.8.....,..)....k|
-000002d0  b3 fa 6e 1a 9b a8 cf 08  8e 03 a5 f7 76 17 74 3a  |..n.........v.t:|
-000002e0  9e 36 ae 19 fd 2c 44 14  f3 2b 1d 01 db e1 96 22  |.6...,D..+....."|
-000002f0  25 14 5b d8 16 03 03 00  bc bb 8c bb cf f9 d7 76  |%.[............v|
-00000300  7a a7 d6 e0 29 cb 45 21  8d 57 0b 81 0c e0 96 05  |z...).E!.W......|
-00000310  c7 96 67 43 0f 41 11 e9  c2 07 2d 62 17 b4 64 01  |..gC.A....-b..d.|
-00000320  c5 75 79 dc 9c 36 3f ea  42 ea 09 a7 bc 0f 6b b1  |.uy..6?.B.....k.|
-00000330  b4 4d ae 38 0a ca 51 d0  97 46 b6 55 12 7c 24 28  |.M.8..Q..F.U.|$(|
-00000340  77 16 64 42 53 70 c4 52  ed e5 aa 20 3a 00 7e d0  |w.dBSp.R... :.~.|
-00000350  9e 99 e4 56 5f ef 30 56  00 8b e7 31 6d 66 6d dc  |...V_.0V...1mfm.|
-00000360  58 8a b0 60 6f 16 a7 b0  14 a5 9d 3d 38 94 6e 16  |X..`o......=8.n.|
-00000370  a3 22 76 e9 59 d8 90 cd  32 83 bb 8c c5 23 cb c2  |."v.Y...2....#..|
-00000380  c5 03 02 de 13 97 ac 4e  99 9f 4d 6d aa ed 72 b7  |.......N..Mm..r.|
-00000390  76 db 8b c9 31 17 b9 1c  4a fa 87 2c 6b dc 07 82  |v...1...J..,k...|
-000003a0  a2 39 e0 09 32 a2 8e 1c  6e 68 e1 14 ba ab 3a d4  |.9..2...nh....:.|
-000003b0  1e 4f f4 39 c7 16 03 03  00 3a cf b2 61 5f 7e ef  |.O.9.....:..a_~.|
-000003c0  04 51 64 f6 3d b3 54 44  bd 8a d0 87 48 64 76 a6  |.Qd.=.TD....Hdv.|
-000003d0  0d bc 7f b7 99 d4 67 8b  cd e3 c4 5d df c5 c8 fc  |......g....]....|
-000003e0  be d1 c4 03 6d 61 2d 10  58 b1 7a 7c 9e 1c 6b 16  |....ma-.X.z|..k.|
-000003f0  ff 31 a8 87 16 03 03 00  14 85 99 57 4b a1 19 33  |.1.........WK..3|
-00000400  bd 9a 86 ed be 5d 24 f0  02 9d ca 1e 26           |.....]$.....&|
+00000000  16 03 03 00 81 69 80 3b  d5 74 82 55 ad c5 6d 92  |.....i.;.t.U..m.|
+00000010  5c d6 02 a0 5a e5 c7 a9  64 94 20 5f b4 03 7d 25  |\...Z...d. _..}%|
+00000020  aa 6b de 09 09 cb 92 a1  73 fa 58 bc 02 a2 01 d4  |.k......s.X.....|
+00000030  e6 c6 56 42 4e 8e c5 09  de 2d e1 6a 96 9e 1a b4  |..VBN....-.j....|
+00000040  1f 73 44 f2 20 07 3d 99  5f 8e 6e 76 ba 6f 8f d5  |.sD. .=._.nv.o..|
+00000050  a1 f9 78 22 9d 84 b3 b1  9c 91 88 3c a7 0f d4 64  |..x".......<...d|
+00000060  6d 6e 16 54 b4 1c 38 07  3c 56 b7 67 b5 ab d7 79  |mn.T..8.<V.g...y|
+00000070  8b 93 87 75 e2 45 a6 0c  e7 0c 10 49 ab 53 c9 d7  |...u.E.....I.S..|
+00000080  22 04 72 b9 da eb 16 03  03 02 69 23 fa 4f 38 89  |".r.......i#.O8.|
+00000090  93 c7 ba 31 52 1a 67 e9  b0 77 8b f6 0a e5 81 b7  |...1R.g..w......|
+000000a0  ea eb 7b 9d 23 a4 00 94  63 5d 91 e9 f7 33 a2 e5  |..{.#...c]...3..|
+000000b0  8f 7f 03 8d e6 92 09 a3  a5 22 af 90 f2 2d 8b b7  |........."...-..|
+000000c0  26 0d dd 3a 3c ee 45 d0  f4 e0 b6 cd d0 f6 74 95  |&..:<.E.......t.|
+000000d0  c8 92 40 a1 7a 2f 97 4b  29 90 8c 17 8f c9 57 70  |..@.z/.K).....Wp|
+000000e0  20 9f 8a cc 60 ea 78 c5  ab eb bf 79 f3 2d ef de  | ...`.x....y.-..|
+000000f0  09 32 6e e7 b4 1f 4e 01  32 9f 38 b0 4b e0 ec 8a  |.2n...N.2.8.K...|
+00000100  0e 39 bb b5 43 55 72 ad  27 1a 61 53 76 a7 ec ec  |.9..CUr.'.aSv...|
+00000110  29 38 8c e7 2f 08 8e 2e  0f 76 a5 5f 8f 5c b2 90  |)8../....v._.\..|
+00000120  da da b1 9b c1 8a 2c 16  15 d1 f5 cd f3 86 38 71  |......,.......8q|
+00000130  40 b5 b5 63 08 57 7c b2  d1 f5 23 f8 30 4c d1 96  |@..c.W|...#.0L..|
+00000140  e1 3c 28 4c b6 49 d5 d4  31 00 a2 72 65 36 51 92  |.<(L.I..1..re6Q.|
+00000150  f8 14 89 a2 9b 2e 93 7e  30 62 03 21 68 db 6a 94  |.......~0b.!h.j.|
+00000160  a4 67 b2 19 b7 ff 54 cd  4b 56 ff d9 c3 ab 5f 31  |.g....T.KV...._1|
+00000170  8a cb bb a3 05 3b ce 81  ac 6a b0 94 0f 2e 2a 9f  |.....;...j....*.|
+00000180  d3 c8 5a 61 33 d6 94 af  4e 5a 1d 37 48 96 89 d4  |..Za3...NZ.7H...|
+00000190  42 78 5e 65 40 69 8d 2e  11 5b c9 a7 92 3b 68 ec  |Bx^e@i...[...;h.|
+000001a0  37 1b 13 37 c2 b5 a4 9e  98 6b 52 e1 41 fc 8f 36  |7..7.....kR.A..6|
+000001b0  a1 ae 93 26 ae 09 5c 8f  bf b4 a8 9e cd 6e 4d 9d  |...&..\......nM.|
+000001c0  b0 7e 19 e0 40 79 b0 ab  22 23 7d d0 f7 d7 eb 8e  |.~..@y.."#}.....|
+000001d0  41 b6 9b 5c 17 51 bf a7  ff fb 12 2c fd ca 8b 23  |A..\.Q.....,...#|
+000001e0  1c df 59 d4 d8 01 d7 7c  96 a3 49 5a d5 29 78 5a  |..Y....|..IZ.)xZ|
+000001f0  10 1e 3c 32 4e c3 f1 c1  c8 49 f8 d8 4d 29 74 b7  |..<2N....I..M)t.|
+00000200  8b db a7 9c 7d f4 21 65  ef f5 a2 ff 1a 4e 72 44  |....}.!e.....NrD|
+00000210  54 1b cd a3 a7 3d c4 f4  2d a5 42 2b e4 ff 15 6b  |T....=..-.B+...k|
+00000220  26 18 69 15 46 24 3a e4  fb ee 3e 9c 15 bc a3 dc  |&.i.F$:...>.....|
+00000230  7b 65 85 82 ba 23 3d 78  22 17 d0 03 02 a0 04 1d  |{e...#=x".......|
+00000240  e5 b0 be d7 4d a4 6e 40  83 b2 ae ee b9 c3 18 ce  |....M.n@........|
+00000250  45 7d d8 2e 6d d1 92 7d  60 bd 44 dd 29 11 cd 7d  |E}..m..}`.D.)..}|
+00000260  13 2f a2 97 b1 ca 6a 76  e0 88 fd 6a b4 cc f3 f1  |./....jv...j....|
+00000270  63 4b 4a 74 cb c6 49 ba  82 2b 29 22 0e a0 23 78  |cKJt..I..+)"..#x|
+00000280  ad 25 59 85 a8 b2 6e d3  34 1f 31 ff 94 ac 3b 42  |.%Y...n.4.1...;B|
+00000290  84 97 17 8a 21 1d 3f 7c  e5 ac 17 50 d9 77 a9 54  |....!.?|...P.w.T|
+000002a0  2f bd 19 3b b9 de 90 64  8a 02 46 bf 7e 02 ac 60  |/..;...d..F.~..`|
+000002b0  55 0c 6f c3 58 04 3a a7  fd e9 26 26 41 a1 8f 43  |U.o.X.:...&&A..C|
+000002c0  7a 9e dd a6 1a 7f cf 1d  0c 40 11 59 4f 36 bc e1  |z........@.YO6..|
+000002d0  63 20 0b ef 3c e7 de 25  e2 e0 d2 4d 42 62 84 97  |c ..<..%...MBb..|
+000002e0  23 64 b2 b5 22 e4 8f f5  b2 1f 9e 99 00 e5 27 f6  |#d..".........'.|
+000002f0  02 b9 b3 d0 16 03 03 00  bc 9c 9e 74 fe d3 9f c5  |...........t....|
+00000300  50 2a 35 af 0d 27 96 94  a0 0a b4 79 f5 ca 9e 30  |P*5..'.....y...0|
+00000310  8c 03 87 75 9c ac 63 a4  96 a5 d8 05 ef cd d5 1a  |...u..c.........|
+00000320  13 24 81 a7 84 aa 69 a2  e4 a4 13 85 25 c0 ca c8  |.$....i.....%...|
+00000330  ec 8f 27 68 77 12 78 bc  98 b2 4e 8b b4 ae c8 47  |..'hw.x...N....G|
+00000340  53 b8 7f d6 cf f0 9a 1e  65 33 b0 77 11 9e f4 72  |S.......e3.w...r|
+00000350  57 f5 c4 55 06 07 1f a7  3e 3e 31 ce 52 97 58 0c  |W..U....>>1.R.X.|
+00000360  23 6e 3c 4c b6 a7 f5 c5  ec 3a fa 96 a4 f6 ee 0d  |#n<L.....:......|
+00000370  c7 71 e8 7b df dc 8f 8a  09 cb 27 68 91 e7 6a c5  |.q.{......'h..j.|
+00000380  84 16 51 66 ae c1 9c d6  dd 80 89 a9 78 95 de 2b  |..Qf........x..+|
+00000390  d4 d7 74 86 5d fa e6 9c  07 bb ea 15 3d 5b e5 b8  |..t.].......=[..|
+000003a0  f0 f5 69 06 61 16 56 49  7f a1 18 78 c8 68 d4 4f  |..i.a.VI...x.h.O|
+000003b0  5b d4 5e a9 1a 16 03 03  00 14 7e 53 00 b2 e5 d6  |[.^.......~S....|
+000003c0  8e 63 25 c3 33 89 49 ee  a8 39 65 ba c1 af        |.c%.3.I..9e...|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 8c c7 01  da 38 a5 36 3d 2c 21 1c  |....i....8.6=,!.|
-00000010  64 1b b8 e7 c2 cd 17 06  b6 51 0e e6 d9 d9 18 c5  |d........Q......|
-00000020  a9 c9 ac 5d 2d 23 f8 15  92 b2 e1 62 6e d7 8d 58  |...]-#.....bn..X|
-00000030  5b d9 b8 26 e5 ec 0f 61  15 3e 12 70 89 0d 3f 4e  |[..&...a.>.p..?N|
-00000040  e3 2e 18 42 7c c7 59 7b  e1 48 d9 a8 cf b1 cd 38  |...B|.Y{.H.....8|
-00000050  17 90 97 89 2e 4f 4b df  58 b0 9f 4e 95 d2 e9 70  |.....OK.X..N...p|
-00000060  6d 0b 82 af b7 05 be 11  26 d8 f9 89 e6 d6 44 f5  |m.......&.....D.|
-00000070  db 7c 8c 91 61 78 dc 68  98 9b 10 17 5b 85 42 93  |.|..ax.h....[.B.|
-00000080  31 a2 16 97 72 c5 f2 d0  81 76 a6 9b b7 9c 14 ab  |1...r....v......|
-00000090  a7 bf 19 f7 34 e3 8f 3f  a5 aa 23 c8 49 07 1b 6f  |....4..?..#.I..o|
-000000a0  e5 5d 65 66 a1 dc d2 e7  bb c2 4b 9e a7 9a dc d6  |.]ef......K.....|
-000000b0  72 42 d3 71 d3 51 a4 3a  82 f7 cd 2a 15 34 da 6d  |rB.q.Q.:...*.4.m|
-000000c0  44 3a a9 7d 6e 4c ce a5  ba 6b 5b 3b 88 8c e1 29  |D:.}nL...k[;...)|
-000000d0  ee a8 17 1b 02 36 8f 68  c9 9e e6 f1 bf e3 e3 e0  |.....6.h........|
-000000e0  cd 6d 7f ff c2 4d 3f 88  c7 9b 75 20 e5 cd fa fa  |.m...M?...u ....|
-000000f0  a0 d7 10 6a c1 00 73 f9  df bd 22 60 8c 82 71 e6  |...j..s..."`..q.|
-00000100  56 aa 90 bf c7 a8 82 51  e7 23 42 ec 99 f5 b9 aa  |V......Q.#B.....|
-00000110  3c cc c6 32 11 29 1f a6  ae 89 03 04 e8 de 9f f4  |<..2.)..........|
-00000120  bd 87 ae af 91 ee a2 f3  e2 6d 7b 87 ad 67 16 2d  |.........m{..g.-|
-00000130  ad 92 34 38 52 ed 7c 38  92 45 16 26 9f 65 d2 67  |..48R.|8.E.&.e.g|
-00000140  3e 33 a1 bd b2 f6 d3 c8  76 96 52 11 0d 8d ac a6  |>3......v.R.....|
-00000150  27 10 6a 43 63 5f 82 41  e7 fe 91 24 68 70 bd 2c  |'.jCc_.A...$hp.,|
-00000160  35 fd 0e 49 ec 3a dd f3  c0 af 5c f4 61 9a 2a 00  |5..I.:....\.a.*.|
-00000170  59 b5 28 24 f0 cf d3 25  bc 77 65 74 04 ee 4b 5e  |Y.($...%.wet..K^|
-00000180  2b 9f 1d 27 e2 dd 1a ed  ab e5 ff d6 1a 55 d7 4d  |+..'.........U.M|
-00000190  5c da 14 96 21 43 f6 c3  2d 78 e5 75 60 69 26 ce  |\...!C..-x.u`i&.|
-000001a0  7a 66 5e 42 91 0e ef 41  c2 c4 e6 15 8a 9a 17 a1  |zf^B...A........|
-000001b0  d9 23 2c cc c7 81 00 71  b0 52 ec 4e ea eb f9 75  |.#,....q.R.N...u|
-000001c0  2e 87 16 b4 ba 25 8c 09  f1 23 f9 ee ea db 0e b5  |.....%...#......|
-000001d0  d0 dd 47 9b b6 06 a3 f3  5e 0d 34 5a ba 76 cd 0a  |..G.....^.4Z.v..|
-000001e0  b1 9f 8a 99 aa d3 02 2e  b6 04 7b c5 d3 2f dc d7  |..........{../..|
-000001f0  68 af 6b 88 90 0a 94 a4  29 65 0b ba b3 da f2 cd  |h.k.....)e......|
-00000200  51 93 4f ea b4 f8 54 c7  28 e3 2d 63 d0 62 54 d9  |Q.O...T.(.-c.bT.|
-00000210  27 a0 85 57 7b a2 f2 f5  a5 25 83 1b e2 36 15 06  |'..W{....%...6..|
-00000220  41 ae e1 f9 ca a5 c6 59  2d da 4a ed 10 7b 80 01  |A......Y-.J..{..|
-00000230  06 39 f2 a8 4b 22 37 4d  aa 84 79 85 71 29 1b 4e  |.9..K"7M..y.q).N|
-00000240  c3 79 af 13 f5 4e 3c 6d  fa 8c d7 55 13 2b 48 3d  |.y...N<m...U.+H=|
-00000250  9a 79 e2 b4 3f 59 f8 f9  6c d2 39 51 e0 6e c2 c3  |.y..?Y..l.9Q.n..|
-00000260  09 06 d4 e0 4f 76 a6 54  b8 9d ef 30 ba 80 16 03  |....Ov.T...0....|
-00000270  03 00 35 df a1 cc 0f 77  42 24 fe 38 ac ec 25 cf  |..5....wB$.8..%.|
-00000280  13 85 03 87 73 b4 c0 d9  97 d0 a8 8e 12 f4 13 61  |....s..........a|
-00000290  42 40 03 a6 b6 6c d3 dd  d9 92 f0 e9 bc bc a7 22  |B@...l........."|
-000002a0  64 cf 4b 00 97 71 ac 3b  16 03 03 00 98 f7 61 85  |d.K..q.;......a.|
-000002b0  47 fc 23 b5 34 4b 1f 10  c7 12 51 07 a2 40 40 48  |G.#.4K....Q..@@H|
-000002c0  1c 79 52 3a a7 9d ca 45  62 a2 53 71 bd 23 0a 77  |.yR:...Eb.Sq.#.w|
-000002d0  0b 7f 8c ff f2 51 da 91  07 d7 67 71 bb ec 02 8d  |.....Q....gq....|
-000002e0  3f 79 dc d9 af f4 4c 78  3e ac 8d 30 ed eb c9 19  |?y....Lx>..0....|
-000002f0  96 89 a7 0f 7c fb 96 18  84 86 e7 bd e2 35 31 0c  |....|........51.|
-00000300  7a 51 d7 94 6b 61 62 7a  6a d8 56 62 e6 cf bf 60  |zQ..kabzj.Vb...`|
-00000310  df 7a c5 ce d3 87 ea 2f  5a ad 90 d4 39 f7 47 8e  |.z...../Z...9.G.|
-00000320  8b d3 6b 8e e0 3f 2f 59  71 e4 e6 bf 3f 4a 29 a8  |..k..?/Yq...?J).|
-00000330  60 df 1b 5c 2d 21 ab 0a  a5 9f 5a a2 a3 d6 08 3c  |`..\-!....Z....<|
-00000340  4a 4b f9 d6 a0 14 03 03  00 11 44 a4 62 7e c1 4a  |JK........D.b~.J|
-00000350  4e 56 dd 08 65 b2 ab 12  cd fa 8d 16 03 03 00 20  |NV..e.......... |
-00000360  b4 52 5a e8 33 b6 23 b1  b4 e6 59 da b0 84 52 94  |.RZ.3.#...Y...R.|
-00000370  70 de dc 02 f6 41 e3 27  7c 27 56 6a 7c 92 e3 48  |p....A.'|'Vj|..H|
+00000000  16 03 03 00 35 01 62 fd  6b 2e 24 0f 01 03 98 44  |....5.b.k.$....D|
+00000010  7a 1a 51 4c 09 f0 da 53  b7 cf 31 06 94 9d 09 bd  |z.QL...S..1.....|
+00000020  d2 ec 3a 20 47 1e 28 e6  d6 66 4d bb dd 2f 9d 4b  |..: G.(..fM../.K|
+00000030  ff e5 4e ed 84 1d 9b 0c  40 a4 14 03 03 00 11 58  |..N.....@......X|
+00000040  2f a4 8e f0 38 bb f8 44  b2 e9 61 68 63 ba 8e 63  |/...8..D..ahc..c|
+00000050  16 03 03 00 20 f3 0f ac  3d e2 65 c4 0e c8 b7 22  |.... ...=.e...."|
+00000060  2f c9 08 d3 b1 75 e1 f8  91 ea 98 c3 9b c8 9b 21  |/....u.........!|
+00000070  cb cd 35 b3 ce                                    |..5..|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 c7 92 b3  aa a0 91 21 4f 42 96 0c  |...........!OB..|
-00000010  3a 92 c3 53 55 d1 16 03  03 00 20 4b da e5 1c 08  |:..SU..... K....|
-00000020  ce a7 33 f1 a6 c7 47 52  19 68 b4 f5 1d 66 a7 38  |..3...GR.h...f.8|
-00000030  97 45 43 9f ca b5 db 2c  14 fc f4 17 03 03 00 19  |.EC....,........|
-00000040  28 f4 bb bf c1 5a 2d 1e  b8 fc c7 fc 55 16 e9 cc  |(....Z-.....U...|
-00000050  43 a3 63 58 7e 2c 60 77  23 16 03 03 00 14 2c e6  |C.cX~,`w#.....,.|
-00000060  25 0a b7 26 7b 13 55 62  f1 fe 6e fe 0e 57 53 57  |%..&{.Ub..n..WSW|
-00000070  19 1b                                             |..|
+00000000  14 03 03 00 11 c0 ed 05  6a 71 44 98 9a d6 b8 ae  |........jqD.....|
+00000010  ab 10 43 a9 27 91 16 03  03 00 20 93 fe ed 5f 3e  |..C.'..... ..._>|
+00000020  61 9f 10 95 c9 f6 82 c5  68 14 3d 9e 3e c3 9d e9  |a.......h.=.>...|
+00000030  f2 2d a1 a5 ff ec b9 31  ae 78 e8 17 03 03 00 19  |.-.....1.x......|
+00000040  27 c4 6c 54 03 88 b2 36  38 79 1f 1d 68 c2 ca fd  |'.lT...68y..h...|
+00000050  bf 47 67 44 e1 13 3b f2  fb 16 03 03 00 14 9d 9d  |.GgD..;.........|
+00000060  67 bf 0e 28 3c 56 a3 7b  49 cb 56 b5 5d 3e 39 45  |g..(<V.{I.V.]>9E|
+00000070  c8 c5                                             |..|
 >>> Flow 11 (client to server)
-00000000  15 03 03 00 12 dd 2b 00  09 fd 8c 7d 21 3d 7c 06  |......+....}!=|.|
-00000010  93 ca c9 21 b2 3e 20 15  03 03 00 12 90 32 4b 3b  |...!.> ......2K;|
-00000020  33 4d fd 69 55 81 aa 42  16 ae 47 b9 4c 06        |3M.iU..B..G.L.|
+00000000  15 03 03 00 12 00 dc 08  22 b1 d3 cc d2 f7 6b 03  |........".....k.|
+00000010  92 e9 4d 62 8d 5d f6 15  03 03 00 12 ce e8 8d 1b  |..Mb.]..........|
+00000020  78 a3 63 10 bc 77 e8 88  1f 91 9c a5 b5 f2        |x.c..w........|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
index cb96432..71d9841 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 91 a6 bc 02 ab  |....Y...U.......|
-00000010  19 62 2c de 45 57 ba 71  c0 b0 4d 78 5e f4 c2 b9  |.b,.EW.q..Mx^...|
-00000020  81 ba 8b d6 b1 9b c8 fb  0c 7c 40 20 dc 66 80 5b  |.........|@ .f.[|
-00000030  20 3c 60 65 7f 9e 0c 67  a8 f3 22 c9 c5 48 80 fa  | <`e...g.."..H..|
-00000040  02 a1 1a 48 6d 1c 46 07  db 6c 8e 85 cc a8 00 00  |...Hm.F..l......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 db bb 55 42 4d  |....Y...U....UBM|
+00000010  7e 2c 47 97 1c 97 97 e4  35 a1 a9 f4 d6 1a 2f 97  |~,G.....5...../.|
+00000020  96 f7 d6 3b 7e 81 7c 96  f4 42 f8 20 b1 92 02 f0  |...;~.|..B. ....|
+00000030  91 56 81 2c 4e ba e0 02  26 c7 f6 d9 0a ef e9 40  |.V.,N...&......@|
+00000040  54 10 60 a4 d3 e1 b5 cf  d3 ad 59 c7 cc a8 00 00  |T.`.......Y.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -54,36 +54,36 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 f5 fd 54 ea 3e bb 70  |........ ..T.>.p|
-000002d0  fb 8e fb e4 8a 25 1f 9d  3d 9a fb fb 9d ff d1 52  |.....%..=......R|
-000002e0  81 9d b0 ea a1 e6 b0 87  2f 04 01 00 80 77 54 16  |......../....wT.|
-000002f0  98 5d 22 c4 7f 9b 2a 44  dd e4 0d 78 c2 60 6a ad  |.]"...*D...x.`j.|
-00000300  91 9d d9 ed 93 0b 4e b4  c6 26 f1 94 6d e0 cc f4  |......N..&..m...|
-00000310  8d fa 9c ec 70 f5 5b ac  80 d7 5e 4f 49 04 bc 24  |....p.[...^OI..$|
-00000320  8e 0a 7d 44 e1 7e 47 1e  a8 68 d1 fe 6f 41 0d 4a  |..}D.~G..h..oA.J|
-00000330  e5 5b f6 f6 a3 af 76 21  56 1a 25 d2 03 3c f4 dd  |.[....v!V.%..<..|
-00000340  0c 13 ce 56 8a 61 6f 5b  8c a1 04 43 82 87 64 20  |...V.ao[...C..d |
-00000350  4a 3b ec 90 d7 59 aa ca  08 3a 39 57 f1 56 57 6a  |J;...Y...:9W.VWj|
-00000360  18 c9 14 7f e3 8d 83 0f  e2 0b 4d 24 01 16 03 03  |..........M$....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 7c 4a f0 08 30 5f 04  |........ |J..0_.|
+000002d0  46 3d 38 6c 55 57 44 82  a5 98 a1 fd 60 26 ce 03  |F=8lUWD.....`&..|
+000002e0  cd 93 14 0a 0b 69 02 bf  03 04 01 00 80 c6 a5 05  |.....i..........|
+000002f0  fa 60 d4 cb 47 ad 03 16  04 bf a7 43 7c 84 54 b3  |.`..G......C|.T.|
+00000300  29 dc 73 29 d2 43 29 90  3b 1f ff dd da 8b 56 06  |).s).C).;.....V.|
+00000310  08 9d fd 1f f6 42 7a 3e  f9 ab 76 87 0b 42 e3 d8  |.....Bz>..v..B..|
+00000320  29 32 55 50 d0 1a 1e 00  8e c9 83 cc 08 bc e5 39  |)2UP...........9|
+00000330  9c 58 79 ab 27 5a 55 21  99 fb 2b ee 3a 3a a2 27  |.Xy.'ZU!..+.::.'|
+00000340  d6 64 a7 d9 c9 c6 46 dc  03 0a 30 b4 1b 8a 61 36  |.d....F...0...a6|
+00000350  b8 22 46 6a ea cc ee 30  e5 58 8e 7e 09 b2 0d 6a  |."Fj...0.X.~...j|
+00000360  b5 84 54 ea ab ed d5 29  1e 7e 67 17 48 16 03 03  |..T....).~g.H...|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 6b ce 5c  2f df 85 e7 5e fa 51 48  |.... k.\/...^.QH|
-00000040  f9 31 a5 02 64 c7 1e b1  2e f2 6b 86 30 43 23 91  |.1..d.....k.0C#.|
-00000050  76 6b 40 74 2b                                    |vk@t+|
+00000030  16 03 03 00 20 c8 0e 66  f9 0a 9c 23 fb ed 6a 04  |.... ..f...#..j.|
+00000040  83 b3 72 c4 5f 7b 2f 9f  03 c9 32 d5 60 30 6d 07  |..r._{/...2.`0m.|
+00000050  e7 d3 fc ed 83                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 e7 1e 88 10 2d  |.......... ....-|
-00000010  dc 35 6d 2b 4a 91 39 5d  5c 46 ed 2e 45 6f 41 38  |.5m+J.9]\F..EoA8|
-00000020  66 0f 15 58 f8 af d8 a6  6c 99 61                 |f..X....l.a|
+00000000  14 03 03 00 01 01 16 03  03 00 20 2e 07 51 3c b8  |.......... ..Q<.|
+00000010  97 34 f5 21 da 22 b1 e9  e6 98 61 83 22 06 45 c2  |.4.!."....a.".E.|
+00000020  db 60 08 27 bc 64 30 3e  1c 77 70                 |.`.'.d0>.wp|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 ab 2a df  2f 3c 07 6a 24 98 55 0b  |......*./<.j$.U.|
-00000010  67 20 2d 92 cd 9a 44 74  da fd 6a                 |g -...Dt..j|
+00000000  17 03 03 00 16 89 dc 04  82 f8 16 f2 0d 91 53 80  |..............S.|
+00000010  7a a7 7b 43 66 f4 95 b3  c2 db ec                 |z.{Cf......|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 d6 fb e7  9a 76 2a 6f e1 e9 33 1a  |.........v*o..3.|
-00000010  77 07 fd 7f 98 af 1e 04  43                       |w.......C|
+00000000  16 03 03 00 14 c7 99 03  a6 e5 88 0c f4 31 22 67  |.............1"g|
+00000010  ee 08 ff ff df d8 5d 63  ad                       |......]c.|
 >>> Flow 7 (client to server)
-00000000  15 03 03 00 12 7e e3 20  96 03 31 8c 6a 31 f8 62  |.....~. ..1.j1.b|
-00000010  02 a7 a4 ce 77 83 c1 15  03 03 00 12 b9 91 75 45  |....w.........uE|
-00000020  a5 4a f9 c6 6d b2 5c c3  0a 1a 26 63 00 04        |.J..m.\...&c..|
+00000000  15 03 03 00 12 ea 8d 5d  03 03 80 85 91 ca cf 7e  |.......].......~|
+00000010  10 53 60 44 f6 86 3d 15  03 03 00 12 96 b9 d3 2b  |.S`D..=........+|
+00000020  c9 d0 bd 38 c3 4d 32 10  4c e9 c4 9a b3 01        |...8.M2.L.....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-SCT b/src/crypto/tls/testdata/Client-TLSv12-SCT
index a0f6a09..e081554 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-SCT
+++ b/src/crypto/tls/testdata/Client-TLSv12-SCT
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 91 01 00 00  8d 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 95 01 00 00  91 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 38 00 05  |.............8..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 3c 00 05  |.............<..|
 00000060  00 05 01 00 00 00 00 00  0a 00 0a 00 08 00 1d 00  |................|
-00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
-00000080  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
-00000090  01 00 00 12 00 00                                 |......|
+00000070  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 12 00  |................|
+00000080  10 04 01 04 03 05 01 05  03 06 01 06 03 02 01 02  |................|
+00000090  03 ff 01 00 01 00 00 12  00 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 01 c6 02 00 01  c2 03 03 08 db 5c c4 da  |.............\..|
-00000010  fe 2c a2 21 0d c4 9e c4  14 b9 e3 15 d7 c5 2c 84  |.,.!..........,.|
-00000020  f2 b8 0e 32 67 9e 72 08  9c 17 6b 20 86 09 60 52  |...2g.r...k ..`R|
-00000030  9d 53 ba c8 8a c3 1a 11  c0 e5 c6 a0 59 49 ed cb  |.S..........YI..|
-00000040  e0 6f 0a 56 e9 4f bf 02  2f 23 10 b8 cc a8 00 01  |.o.V.O../#......|
+00000000  16 03 03 01 c6 02 00 01  c2 03 03 7c 81 f9 b1 c8  |...........|....|
+00000010  a6 92 26 e6 ef 52 6b 33  51 64 e1 e8 77 73 c2 c6  |..&..Rk3Qd..ws..|
+00000020  9a 7c 38 c8 df 43 8e da  8c ea 21 20 6b ea 4c 41  |.|8..C....! k.LA|
+00000030  1e 3d d0 b9 e9 d8 e9 0b  12 e1 a2 82 b7 69 0a d7  |.=...........i..|
+00000040  42 57 8e 24 62 77 3d e0  af 5b 97 2c cc a8 00 01  |BW.$bw=..[.,....|
 00000050  7a ff 01 00 01 00 00 0b  00 04 03 00 01 02 00 12  |z...............|
 00000060  01 69 01 67 00 75 00 a4  b9 09 90 b4 18 58 14 87  |.i.g.u.......X..|
 00000070  bb 13 a2 cc 67 70 0a 3c  35 98 04 f9 1b df b8 e3  |....gp.<5.......|
@@ -77,31 +77,31 @@
 00000400  1c f1 0f a1 d8 40 83 61  c9 4c 72 2b 9d ae db 46  |.....@.a.Lr+...F|
 00000410  06 06 4d f4 c1 b3 3e c0  d1 bd 42 d4 db fe 3d 13  |..M...>...B...=.|
 00000420  60 84 5c 21 d3 3b e9 fa  e7 16 03 03 00 ac 0c 00  |`.\!.;..........|
-00000430  00 a8 03 00 1d 20 27 94  d8 62 00 f3 3f 21 e6 e1  |..... '..b..?!..|
-00000440  0f 1f 2d 9b 37 4d cf 72  34 48 72 2e 85 46 dd b6  |..-.7M.r4Hr..F..|
-00000450  32 23 64 b3 4b 63 04 01  00 80 82 34 e5 7f 70 51  |2#d.Kc.....4..pQ|
-00000460  42 3b ab 51 61 73 1f 2c  64 04 1d 66 96 ff f9 95  |B;.Qas.,d..f....|
-00000470  86 09 a8 75 11 16 34 05  17 fb 96 9c fb 78 40 4c  |...u..4......x@L|
-00000480  10 5b ee 0d 31 a0 77 32  a8 0f 19 ef a4 30 cd 08  |.[..1.w2.....0..|
-00000490  cb f5 ec 36 fa 24 0a ca  0b d8 16 02 d1 34 86 a7  |...6.$.......4..|
-000004a0  f8 e3 cb e6 62 1c cd 40  d6 4f 0c 2f 5b 66 12 6f  |....b..@.O./[f.o|
-000004b0  8a 2f c4 ef ac 46 86 44  90 e0 65 38 94 4d 5e df  |./...F.D..e8.M^.|
-000004c0  51 a3 40 6e 64 b6 00 6b  88 97 7b 43 78 d9 df 70  |Q.@nd..k..{Cx..p|
-000004d0  fe 66 66 56 82 14 ed ab  08 cd 16 03 03 00 04 0e  |.ffV............|
+00000430  00 a8 03 00 1d 20 46 5e  b3 7c 5b 77 d3 2d ff 1a  |..... F^.|[w.-..|
+00000440  60 d8 56 9b c8 f0 fa 09  ec 33 89 08 8f 9e 54 86  |`.V......3....T.|
+00000450  7e 5d 72 e5 3d 37 04 01  00 80 6e e6 45 b9 1d b5  |~]r.=7....n.E...|
+00000460  03 a5 d6 ec 37 ca 35 a1  b0 e9 3f b5 b8 2f 65 d2  |....7.5...?../e.|
+00000470  f6 8e 28 e8 23 76 23 f7  26 b6 96 64 89 bb ab 88  |..(.#v#.&..d....|
+00000480  4b c5 9a b0 f5 df f2 44  19 15 25 67 5e 66 8c f7  |K......D..%g^f..|
+00000490  3d 9a 6a 2a c7 1d 85 d3  7c 2e 5e 9c 9d ca 87 c3  |=.j*....|.^.....|
+000004a0  ee 12 ec bd ba 19 fd bc  86 0e d7 8e d2 6a 90 f6  |.............j..|
+000004b0  bf bb 15 ab 2e 6b 6a 4d  6f 59 dd c9 ca 40 f5 60  |.....kjMoY...@.`|
+000004c0  b0 ab 47 2a 6e ee 1b 20  d8 ca c4 8c 8b f3 51 65  |..G*n.. ......Qe|
+000004d0  18 25 41 d3 1f 4e 6b fe  ef 10 16 03 03 00 04 0e  |.%A..Nk.........|
 000004e0  00 00 00                                          |...|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 20 7a 58 e1  33 d4 ce ca 57 ef ea b9  |.... zX.3...W...|
-00000040  9d f2 4d ec ce 86 4b e9  c2 b5 64 dd 0f 32 f0 66  |..M...K...d..2.f|
-00000050  65 42 74 d8 59                                    |eBt.Y|
+00000030  16 03 03 00 20 5f a3 77  a5 b0 8f 47 73 4c a9 1d  |.... _.w...GsL..|
+00000040  84 17 76 fe a5 17 6e c8  cd a4 dc 47 e5 76 23 2f  |..v...n....G.v#/|
+00000050  18 8b 59 41 12                                    |..YA.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 27 df 9b 14 a1  |.......... '....|
-00000010  cd a5 83 5b 6b 30 60 a3  ae 8d 64 56 fe 8e 87 a2  |...[k0`...dV....|
-00000020  ff 1b 54 72 c8 7c b2 85  9d 8a de                 |..Tr.|.....|
+00000000  14 03 03 00 01 01 16 03  03 00 20 3e 65 a2 34 77  |.......... >e.4w|
+00000010  84 52 61 db 52 89 e8 f0  27 f3 ab 70 17 38 1f 37  |.Ra.R...'..p.8.7|
+00000020  17 ad d8 56 23 32 2d 2d  e2 b3 d0                 |...V#2--...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 c7 bf a9  7a 72 07 27 88 9a ec 1b  |........zr.'....|
-00000010  d3 44 f2 20 88 e4 c2 8b  61 86 5c 15 03 03 00 12  |.D. ....a.\.....|
-00000020  35 ab f5 f6 92 f9 db 23  bf f1 8e e8 65 62 cf 48  |5......#....eb.H|
-00000030  91 9d                                             |..|
+00000000  17 03 03 00 16 92 d2 88  0c 8a ac 62 fe fd d5 d4  |...........b....|
+00000010  fd 98 b2 60 02 97 a2 80  d7 5f f9 15 03 03 00 12  |...`....._......|
+00000020  e9 3d 30 95 1b f8 fd 05  3b ba ac af f9 66 f7 ac  |.=0.....;....f..|
+00000030  e5 ec                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM
index 90541fd..7a265ea 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM
+++ b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM
@@ -1,19 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 8b 01 00 00  87 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 8f 01 00 00  8b 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 2c cc a8  |.............,..|
 00000030  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
 00000040  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 32 00 05  |.............2..|
+00000050  c0 12 00 0a 00 05 c0 11  c0 07 01 00 00 36 00 05  |.............6..|
 00000060  00 05 01 00 00 00 00 00  0a 00 04 00 02 00 1d 00  |................|
-00000070  0b 00 02 01 00 00 0d 00  0e 00 0c 04 01 04 03 05  |................|
-00000080  01 05 03 02 01 02 03 ff  01 00 01 00 00 12 00 00  |................|
+00000070  0b 00 02 01 00 00 0d 00  12 00 10 04 01 04 03 05  |................|
+00000080  01 05 03 06 01 06 03 02  01 02 03 ff 01 00 01 00  |................|
+00000090  00 12 00 00                                       |....|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 07 42 b0 44 05  |....Y...U...B.D.|
-00000010  b1 6d 3c f0 60 fe 6a f2  1f 8f 1d 88 de 4b 6a 1b  |.m<.`.j......Kj.|
-00000020  4f 72 60 4d 42 a5 f7 77  eb 86 c2 20 99 35 47 07  |Or`MB..w... .5G.|
-00000030  64 60 32 52 2e 1d 54 d5  b7 e2 26 85 72 c1 ec 8d  |d`2R..T...&.r...|
-00000040  fb 59 86 91 46 7d ad 16  bd b7 38 94 c0 2f 00 00  |.Y..F}....8../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 ff 52 25 9b 48  |....Y...U...R%.H|
+00000010  77 0c cd cf 49 c4 b4 5e  02 32 d4 56 99 d0 ce ad  |w...I..^.2.V....|
+00000020  d4 9d 8b e9 ae 4c 50 26  4b 65 c3 20 99 54 f7 5d  |.....LP&Ke. .T.]|
+00000030  68 da 00 e0 88 d8 0c ed  b1 8f 60 d1 70 16 c4 c6  |h.........`.p...|
+00000040  84 69 55 23 43 27 22 b7  94 2a 79 4c c0 2f 00 00  |.iU#C'"..*yL./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -53,33 +54,33 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 cc f6 2e 98 6c e0 8b  |........ ....l..|
-000002d0  15 17 63 6f 97 5e 37 6a  a7 3c 4b f2 d4 91 e0 87  |..co.^7j.<K.....|
-000002e0  53 1d d3 9e f3 43 a9 21  40 04 01 00 80 3c 35 db  |S....C.!@....<5.|
-000002f0  b1 ef 58 96 b4 3f eb 6b  d5 0d b7 ab cd 51 8d 57  |..X..?.k.....Q.W|
-00000300  2b fe 3a 7f 72 42 a0 a7  7d 1d db c1 6c cd df de  |+.:.rB..}...l...|
-00000310  7f 98 69 b0 0b c1 56 07  34 51 79 dc 1a 52 d1 11  |..i...V.4Qy..R..|
-00000320  ea b4 dd 0f 9d 9a 8c a3  4f 23 da 0e aa dc 2a e1  |........O#....*.|
-00000330  16 51 a4 33 e2 4f f8 34  2d b0 ba f5 f5 ed 3e 24  |.Q.3.O.4-.....>$|
-00000340  04 f0 b9 ab 81 b8 4e 39  88 8f b7 46 2c 60 b8 5c  |......N9...F,`.\|
-00000350  6f 4d d4 5d 7a 04 f7 1d  82 98 a2 b1 f9 7e f0 1f  |oM.]z........~..|
-00000360  cf a5 e5 28 25 d4 3d b0  32 ea eb 21 c6 16 03 03  |...(%.=.2..!....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 7e 24 e6 eb 12 22 e0  |........ ~$...".|
+000002d0  7b 1e ad 2d 1e a8 3a ea  ff 9e 87 bf 38 21 6e 51  |{..-..:.....8!nQ|
+000002e0  a8 42 0b 13 a2 3f 01 b9  7d 04 01 00 80 be e8 7e  |.B...?..}......~|
+000002f0  db 65 e8 0c 5e 31 4c 72  b4 fb 42 ca f0 e2 e2 32  |.e..^1Lr..B....2|
+00000300  26 46 f5 62 e5 09 71 8c  82 60 d3 e1 3b 1d d4 3d  |&F.b..q..`..;..=|
+00000310  6f 9d 5e 22 e7 22 41 44  1b b1 77 18 dc 5a 82 18  |o.^"."AD..w..Z..|
+00000320  f3 ae 31 a2 46 32 86 cb  6e f7 37 b3 a4 7e 5c 62  |..1.F2..n.7..~\b|
+00000330  11 8d 78 aa 78 6b 6f 78  da 75 26 bf 9b fc 5a 4b  |..x.xkox.u&...ZK|
+00000340  18 d7 28 84 9d 66 70 69  2f f5 24 c5 90 ef 33 14  |..(..fpi/.$...3.|
+00000350  2e c8 14 3f 46 5c 61 c1  a5 2e ee 81 b5 4e 32 01  |...?F\a......N2.|
+00000360  85 8b 3a 30 de 0d e7 23  07 be 36 9a 66 16 03 03  |..:0...#..6.f...|
 00000370  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
 00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
 00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
-00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 75 70 c8  |....(........up.|
-00000040  c5 ef ae 60 b5 8d ba 98  1a 7d 8d c3 e4 32 fc 33  |...`.....}...2.3|
-00000050  5e 15 cc e2 d7 5d d5 76  52 1a fe ac 1e           |^....].vR....|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 71 e9 b4  |....(........q..|
+00000040  8b 8a 93 23 22 6a 61 09  5f e6 5b 05 53 f6 7e b0  |...#"ja._.[.S.~.|
+00000050  18 53 da 44 b4 04 4d a4  d6 8e fe 8e d8           |.S.D..M......|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 7f 2b fe 0d 9f  |..........(.+...|
-00000010  93 07 fd ee 48 76 09 fb  8d 4c dd 7b b5 b5 26 36  |....Hv...L.{..&6|
-00000020  3e 05 e1 1b a7 dc 0b 4a  c0 69 a8 22 33 0b 17 fc  |>......J.i."3...|
-00000030  6f ab b8                                          |o..|
+00000000  14 03 03 00 01 01 16 03  03 00 28 b0 0e df 0e b0  |..........(.....|
+00000010  b0 3b 09 c7 9e 23 21 34  35 3a 15 94 64 8e 54 c9  |.;...#!45:..d.T.|
+00000020  5c c7 e3 3f b6 8f ca 10  4e d9 60 60 b7 b4 f9 13  |\..?....N.``....|
+00000030  5d c4 53                                          |].S|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 49 61 5c  |.............Ia\|
-00000010  db f2 e5 63 23 3a f1 dd  12 3e 61 ed d9 4b 5f b5  |...c#:...>a..K_.|
-00000020  d3 f7 38 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..8.............|
-00000030  af 09 a7 f1 e1 d9 1f 54  d1 35 19 16 b7 23 ce 4e  |.......T.5...#.N|
-00000040  3a b1                                             |:.|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 6b a1 83  |.............k..|
+00000010  cc af 9b e1 88 55 43 c2  7d 05 b7 2d 7d 33 d9 b6  |.....UC.}..-}3..|
+00000020  a3 9b 85 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  e2 8b 82 76 99 3d 8b b7  7d 69 76 d5 cd 6c aa 7c  |...v.=..}iv..l.||
+00000040  64 82                                             |d.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN b/src/crypto/tls/testdata/Server-TLSv12-ALPN
index 3e90ebd..f2e7eb7 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ALPN
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 bf 01 00 00  bb 03 03 18 c9 32 10 f3  |.............2..|
-00000010  be ff a8 60 c5 2a 03 cb  25 8a b3 54 8d 70 27 90  |...`.*..%..T.p'.|
-00000020  74 1e 15 3e 61 48 9b be  f0 77 1f 00 00 38 c0 2c  |t..>aH...w...8.,|
+00000000  16 03 01 00 bf 01 00 00  bb 03 03 dc d0 a1 64 e2  |..............d.|
+00000010  38 c3 1c 2b 8c fc d4 e9  25 b7 20 01 fb 72 37 8f  |8..+....%. ..r7.|
+00000020  1b da 7b ec 74 f3 20 c4  78 eb 15 00 00 38 c0 2c  |..{.t. .x....8.,|
 00000030  c0 30 00 9f cc a9 cc a8  cc aa c0 2b c0 2f 00 9e  |.0.........+./..|
 00000040  c0 24 c0 28 00 6b c0 23  c0 27 00 67 c0 0a c0 14  |.$.(.k.#.'.g....|
 00000050  00 39 c0 09 c0 13 00 33  00 9d 00 9c 00 3d 00 3c  |.9.....3.....=.<|
@@ -58,37 +58,37 @@
 000002a0  d3 3b e9 fa e7 16 03 03  00 ac 0c 00 00 a8 03 00  |.;..............|
 000002b0  1d 20 2f e5 7d a3 47 cd  62 43 15 28 da ac 5f bb  |. /.}.G.bC.(.._.|
 000002c0  29 07 30 ff f6 84 af c4  cf c2 ed 90 99 5f 58 cb  |).0.........._X.|
-000002d0  3b 74 05 01 00 80 2e c1  51 a1 e8 92 a6 bb ad 1e  |;t......Q.......|
-000002e0  4d f1 22 c5 e7 10 e6 31  1d 78 61 8a 22 a3 93 84  |M."....1.xa."...|
-000002f0  58 d6 5a c6 94 d0 da 6c  6a 35 d1 31 ea 1b 7e 55  |X.Z....lj5.1..~U|
-00000300  d6 35 a3 b7 42 e4 04 f8  31 15 15 88 5f 91 a8 7e  |.5..B...1..._..~|
-00000310  3e 73 52 8f 32 50 2e ad  95 44 83 b6 88 d6 18 99  |>sR.2P...D......|
-00000320  cf 86 57 97 c0 b2 a0 91  ee a7 ac f8 38 4b 1c 8e  |..W.........8K..|
-00000330  a4 58 59 4a f6 fc 88 a4  02 ed c8 04 1a 8b 7b 9e  |.XYJ..........{.|
-00000340  83 91 72 ca 1e 1c e0 76  58 73 89 3a 7d 12 c5 ef  |..r....vXs.:}...|
-00000350  f8 f7 45 dc ca c4 16 03  03 00 04 0e 00 00 00     |..E............|
+000002d0  3b 74 06 01 00 80 54 89  2f 46 ff 41 c2 56 47 33  |;t....T./F.A.VG3|
+000002e0  fa d6 91 64 47 df 46 89  75 73 6d 84 c6 8a 54 f8  |...dG.F.usm...T.|
+000002f0  80 34 55 00 34 8d 64 ab  72 94 6e e9 e6 18 a1 e9  |.4U.4.d.r.n.....|
+00000300  15 00 f5 2a 84 9f 22 95  c5 a3 17 91 b3 36 3a 9c  |...*.."......6:.|
+00000310  b9 65 54 bd 03 29 69 1a  5b 44 bd 1f c1 16 5a 7d  |.eT..)i.[D....Z}|
+00000320  53 35 8c c3 28 5f 3c ac  71 d2 bc c7 86 82 08 e7  |S5..(_<.q.......|
+00000330  72 22 1f 98 68 5d a7 0e  8b 2c 6c 80 b9 36 79 4a  |r"..h]...,l..6yJ|
+00000340  f2 64 c1 14 8b b2 61 a8  c2 ca 83 44 e9 5a f8 fb  |.d....a....D.Z..|
+00000350  6d 67 b4 d6 7e fa 16 03  03 00 04 0e 00 00 00     |mg..~..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 be 4e 0d d5 31 aa  |....%...! .N..1.|
-00000010  27 13 df 73 d3 8d 17 8c  b3 5f 44 61 7b 01 b6 99  |'..s....._Da{...|
-00000020  7b ba b3 5d bf d4 be 3c  87 26 14 03 03 00 01 01  |{..]...<.&......|
-00000030  16 03 03 00 28 9c 86 e0  30 d4 a5 ec 0c 9e a6 08  |....(...0.......|
-00000040  ce 8a 7a ff ef be 52 0c  56 86 62 de 49 09 a1 18  |..z...R.V.b.I...|
-00000050  aa 62 e5 e3 d3 2e 4a 24  c9 ef 44 c9 67           |.b....J$..D.g|
+00000000  16 03 03 00 25 10 00 00  21 20 61 b6 16 25 fb ca  |....%...! a..%..|
+00000010  39 11 1b 39 91 0f ad a0  1b 53 cb 23 3a 8b 4c bf  |9..9.....S.#:.L.|
+00000020  c3 95 b7 fa 74 2c 44 55  d3 3b 14 03 03 00 01 01  |....t,DU.;......|
+00000030  16 03 03 00 28 2a f0 0e  a4 54 25 0c 3f 46 9e d4  |....(*...T%.?F..|
+00000040  32 63 db 36 71 11 9d 63  57 d5 5d e6 70 86 01 f8  |2c.6q..cW.].p...|
+00000050  2f 8e 79 65 b7 39 4f 31  a9 f5 a5 70 9a           |/.ye.9O1...p.|
 >>> Flow 4 (server to client)
 00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
 00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
-00000030  6f ec 80 83 61 da 3d a1  df 0d 11 25 4b 66 55 09  |o...a.=....%KfU.|
-00000040  af 7a c1 82 b9 ea 2f 9f  5c f4 0a 62 15 62 c2 32  |.z..../.\..b.b.2|
-00000050  c6 37 51 5b bb 19 14 f8  73 f8 fb 82 00 ef 19 21  |.7Q[....s......!|
-00000060  e2 52 7d ab 0a 33 94 df  78 54 ba 6c 5e 94 eb 16  |.R}..3..xT.l^...|
-00000070  ad 85 01 ca d5 98 8f 8e  b7 04 7e 9a 3c 35 c0 e5  |..........~.<5..|
-00000080  8f cf 27 6d b4 12 c2 14  03 03 00 01 01 16 03 03  |..'m............|
-00000090  00 28 00 00 00 00 00 00  00 00 75 da b5 10 2e 7c  |.(........u....||
-000000a0  39 ec 3d 98 12 fb 5d 15  81 79 f3 c7 b1 e4 e0 54  |9.=...]..y.....T|
-000000b0  ed 27 6e bc c3 81 a0 74  7e 38 17 03 03 00 25 00  |.'n....t~8....%.|
-000000c0  00 00 00 00 00 00 01 bf  81 cc 93 49 4f b2 59 8b  |...........IO.Y.|
-000000d0  53 4a 61 96 04 00 4b ac  34 d5 bd 5a 94 44 18 5b  |SJa...K.4..Z.D.[|
-000000e0  7d 81 dc 05 15 03 03 00  1a 00 00 00 00 00 00 00  |}...............|
-000000f0  02 bd 32 d5 cf 4d 13 61  6a 77 8b 3e 51 b3 13 84  |..2..M.ajw.>Q...|
-00000100  e6 1a 23                                          |..#|
+00000030  6f ec 80 83 61 19 68 1a  40 8c 4c 8f 85 a2 2e fa  |o...a.h.@.L.....|
+00000040  3f b5 7c 5f 46 d1 fa 20  23 89 e7 e6 d6 82 6f 78  |?.|_F.. #.....ox|
+00000050  5b 28 32 89 60 4a e7 22  51 9a 13 f5 0e 82 9c 1e  |[(2.`J."Q.......|
+00000060  29 e1 2a 91 62 33 94 51  e1 bf b8 99 2a 20 e6 87  |).*.b3.Q....* ..|
+00000070  c4 1f 65 fe 7e 6e 0e 33  7f 77 f9 33 0c 9d 05 df  |..e.~n.3.w.3....|
+00000080  e5 7d 2c db cc 48 f6 14  03 03 00 01 01 16 03 03  |.},..H..........|
+00000090  00 28 00 00 00 00 00 00  00 00 91 05 0e 09 9f b6  |.(..............|
+000000a0  e1 48 98 28 ae 68 0a 89  9f a7 47 1b 67 d5 8c 0a  |.H.(.h....G.g...|
+000000b0  3c 4f da 1e 4f 3f 13 80  cd a5 17 03 03 00 25 00  |<O..O?........%.|
+000000c0  00 00 00 00 00 00 01 60  3b c1 2b 3c 20 b8 bc b9  |.......`;.+< ...|
+000000d0  1b d6 07 f9 1d aa 25 3b  b1 be 7b de fc 69 86 82  |......%;..{..i..|
+000000e0  56 ca 8b ae 15 03 03 00  1a 00 00 00 00 00 00 00  |V...............|
+000000f0  02 00 8c a8 46 d8 ff b1  5f e3 0f f9 34 81 e1 f5  |....F..._...4...|
+00000100  32 ff cc                                          |2..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
index d40300e..8346ea9 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 bf 01 00 00  bb 03 03 82 57 14 fc ab  |............W...|
-00000010  56 21 ff 72 39 72 3f fe  f1 9b 0f 22 00 ff ef 44  |V!.r9r?...."...D|
-00000020  da db e0 83 d2 c0 a7 1c  fb f0 6c 00 00 38 c0 2c  |..........l..8.,|
+00000000  16 03 01 00 bf 01 00 00  bb 03 03 12 5f 10 32 01  |............_.2.|
+00000010  84 0f 82 05 7e ca 97 58  65 65 d5 ad d3 94 e4 88  |....~..Xee......|
+00000020  e9 15 91 0a 2c 99 55 ca  ae 18 aa 00 00 38 c0 2c  |....,.U......8.,|
 00000030  c0 30 00 9f cc a9 cc a8  cc aa c0 2b c0 2f 00 9e  |.0.........+./..|
 00000040  c0 24 c0 28 00 6b c0 23  c0 27 00 67 c0 0a c0 14  |.$.(.k.#.'.g....|
 00000050  00 39 c0 09 c0 13 00 33  00 9d 00 9c 00 3d 00 3c  |.9.....3.....=.<|
@@ -57,38 +57,38 @@
 00000290  84 5c 21 d3 3b e9 fa e7  16 03 03 00 ac 0c 00 00  |.\!.;...........|
 000002a0  a8 03 00 1d 20 2f e5 7d  a3 47 cd 62 43 15 28 da  |.... /.}.G.bC.(.|
 000002b0  ac 5f bb 29 07 30 ff f6  84 af c4 cf c2 ed 90 99  |._.).0..........|
-000002c0  5f 58 cb 3b 74 05 01 00  80 bf 6d 57 f5 0c 78 c4  |_X.;t.....mW..x.|
-000002d0  77 48 0e 60 67 7a 3a 1b  3e 9e d2 88 a4 89 07 ef  |wH.`gz:.>.......|
-000002e0  d1 45 1a 66 7e 8c ec cb  da 71 ea ec ba ed 81 9e  |.E.f~....q......|
-000002f0  21 4d 2e ba d4 8f c2 0a  67 ea 3a a1 d1 67 09 66  |!M......g.:..g.f|
-00000300  dc a8 ad 16 a2 23 2a db  4f 31 65 b1 54 13 73 d1  |.....#*.O1e.T.s.|
-00000310  f6 7b 75 d9 f1 07 19 b8  67 21 87 d2 3b cf a5 6c  |.{u.....g!..;..l|
-00000320  61 8e af ed 60 7f f2 56  9f 0d 0f 19 88 98 30 3a  |a...`..V......0:|
-00000330  61 8c 21 e7 8b 5d ab 6f  cf 93 73 33 63 cd 50 bb  |a.!..].o..s3c.P.|
-00000340  dd 0e ab 4f 6a fb a3 f9  68 16 03 03 00 04 0e 00  |...Oj...h.......|
+000002c0  5f 58 cb 3b 74 06 01 00  80 50 95 28 ab df d3 74  |_X.;t....P.(...t|
+000002d0  7a 9b 7a d8 d2 31 34 87  75 29 a9 d0 fd 3c e4 be  |z.z..14.u)...<..|
+000002e0  59 e6 60 52 39 9f 8e 9d  e3 1c 1d 75 47 b0 86 57  |Y.`R9......uG..W|
+000002f0  3f e1 a8 a5 72 21 1a 22  49 61 71 83 20 76 8c b6  |?...r!."Iaq. v..|
+00000300  e4 c4 99 de 4e 9c f6 22  df 8d 92 1e a9 c7 0e 83  |....N.."........|
+00000310  d2 93 a9 2d 9b 74 f8 1b  1b 2f 1e 71 b6 7c d0 99  |...-.t.../.q.|..|
+00000320  a3 d2 95 45 87 36 28 be  0a 26 53 89 77 6b b6 e4  |...E.6(..&S.wk..|
+00000330  f9 3a 82 7c 67 81 08 22  cf 3a 94 83 68 29 f3 a5  |.:.|g..".:..h)..|
+00000340  67 b4 95 77 0f fb 06 da  5f 16 03 03 00 04 0e 00  |g..w...._.......|
 00000350  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 05 0c 3b 8b 22 36  |....%...! ..;."6|
-00000010  61 79 58 28 b0 82 65 44  39 67 93 c5 2c 3b d1 40  |ayX(..eD9g..,;.@|
-00000020  88 af 9f 38 c1 fa e0 81  a0 19 14 03 03 00 01 01  |...8............|
-00000030  16 03 03 00 28 87 2e d2  c2 ce 65 6d e8 d9 da a0  |....(.....em....|
-00000040  9d dc f5 51 b0 84 88 8d  c6 a3 0a 5d 08 10 ca c6  |...Q.......]....|
-00000050  e3 83 0c 0a cb 6d ec 09  b8 9f a5 45 99           |.....m.....E.|
+00000000  16 03 03 00 25 10 00 00  21 20 a4 d7 31 f0 60 aa  |....%...! ..1.`.|
+00000010  97 48 1f a8 fb 3c 78 77  5f 90 b3 f7 f2 0c 5e ed  |.H...<xw_.....^.|
+00000020  3e 2e 77 a4 72 14 b0 bb  c2 65 14 03 03 00 01 01  |>.w.r....e......|
+00000030  16 03 03 00 28 6d 3e 7f  a1 0e 5b ea 24 ee ec 77  |....(m>...[.$..w|
+00000040  3c 03 eb cb 5c ad b4 21  b2 c1 9c 5e 4f 36 88 01  |<...\..!...^O6..|
+00000050  b6 0c 7c 92 70 70 63 4f  d4 e1 98 45 e4           |..|.ppcO...E.|
 >>> Flow 4 (server to client)
 00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
 00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
-00000030  6f ec 80 83 61 34 53 e2  a4 e2 ff 73 4f 1b 15 8f  |o...a4S....sO...|
-00000040  3b 43 47 ac 20 c6 2d 5e  52 7a 61 6f af 40 c3 5a  |;CG. .-^Rzao.@.Z|
-00000050  cb 3f 7d 10 a9 90 ca cf  8d c4 c4 d4 a3 b8 1d 62  |.?}............b|
-00000060  7d a9 68 32 01 33 94 65  8b 67 73 aa 51 d4 08 1d  |}.h2.3.e.gs.Q...|
-00000070  ce 76 6b ef 3d e6 ce d3  42 fe 24 cf f3 82 5b 17  |.vk.=...B.$...[.|
-00000080  5c 03 e9 50 94 8e 8b 14  03 03 00 01 01 16 03 03  |\..P............|
-00000090  00 28 00 00 00 00 00 00  00 00 c2 7c e6 69 c9 ec  |.(.........|.i..|
-000000a0  b5 55 57 34 8e 86 38 e6  28 85 b0 c8 2e c8 0f a6  |.UW4..8.(.......|
-000000b0  a9 07 f4 91 47 46 dd fe  c8 57 17 03 03 00 25 00  |....GF...W....%.|
-000000c0  00 00 00 00 00 00 01 39  9a a2 da d8 3d 7f 25 0e  |.......9....=.%.|
-000000d0  83 a8 cd 57 d8 a4 7e 9f  e1 e2 fe 3f 5a ed b9 99  |...W..~....?Z...|
-000000e0  b6 4d 97 3a 15 03 03 00  1a 00 00 00 00 00 00 00  |.M.:............|
-000000f0  02 d5 2a aa 1e 7a 60 b8  79 56 c6 56 75 11 b7 4c  |..*..z`.yV.Vu..L|
-00000100  83 19 9c                                          |...|
+00000030  6f ec 80 83 61 34 3a 86  15 18 26 50 d0 12 69 5a  |o...a4:...&P..iZ|
+00000040  8e 67 6a ce 99 67 0a 90  09 d5 ad 29 62 08 9b 29  |.gj..g.....)b..)|
+00000050  6c 12 bb d4 74 3c fb 5b  dc e5 89 f0 98 93 03 e9  |l...t<.[........|
+00000060  2a ea 31 74 0a 33 94 96  49 53 80 c9 3e 9b 53 32  |*.1t.3..IS..>.S2|
+00000070  4a 15 31 0e fa 90 bd da  af 07 d1 a8 fa 15 e8 df  |J.1.............|
+00000080  3d f1 d1 7a 21 8c 7a 14  03 03 00 01 01 16 03 03  |=..z!.z.........|
+00000090  00 28 00 00 00 00 00 00  00 00 70 0c c0 3b 84 68  |.(........p..;.h|
+000000a0  4d e5 7d 54 18 ba 77 3d  8c 20 03 3e 50 69 45 0d  |M.}T..w=. .>PiE.|
+000000b0  64 a2 0f 1e 4e bf 86 0b  9c 05 17 03 03 00 25 00  |d...N.........%.|
+000000c0  00 00 00 00 00 00 01 43  a9 fa 0f e3 5a 86 46 2a  |.......C....Z.F*|
+000000d0  56 3a 6c d5 88 b7 40 a0  d5 59 45 45 ac 06 5d b0  |V:l...@..YEE..].|
+000000e0  d7 c9 ed 00 15 03 03 00  1a 00 00 00 00 00 00 00  |................|
+000000f0  02 ce de ef aa b4 47 77  4c f6 e9 fb 67 e8 fb 7f  |......GwL...g...|
+00000100  c6 05 20                                          |.. |
diff --git a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
index e286407..3a84905 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
+++ b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 a7 01 00 00  a3 03 03 27 01 f3 21 98  |...........'..!.|
-00000010  ff 55 7f 78 32 44 b7 9d  88 6b 82 43 26 52 00 74  |.U.x2D...k.C&R.t|
-00000020  fb 05 ca be 23 1f d0 18  1f 74 c2 00 00 38 c0 2c  |....#....t...8.,|
+00000000  16 03 01 00 a7 01 00 00  a3 03 03 7e 8a c0 04 93  |...........~....|
+00000010  7a be 32 5c b3 38 83 b1  ec d0 31 8d a1 61 f3 2b  |z.2\.8....1..a.+|
+00000020  b2 6a 0d 08 71 41 fb 20  c2 46 0c 00 00 38 c0 2c  |.j..qA. .F...8.,|
 00000030  c0 30 00 9f cc a9 cc a8  cc aa c0 2b c0 2f 00 9e  |.0.........+./..|
 00000040  c0 24 c0 28 00 6b c0 23  c0 27 00 67 c0 0a c0 14  |.$.(.k.#.'.g....|
 00000050  00 39 c0 09 c0 13 00 33  00 9d 00 9c 00 3d 00 3c  |.9.....3.....=.<|
@@ -47,39 +47,39 @@
 00000210  0e bd 3f a3 8c 25 c1 33  13 83 0d 94 06 bb d4 37  |..?..%.3.......7|
 00000220  7a f6 ec 7a c9 86 2e dd  d7 11 69 7f 85 7c 56 de  |z..z......i..|V.|
 00000230  fb 31 78 2b e4 c7 78 0d  ae cb be 9e 4e 36 24 31  |.1x+..x.....N6$1|
-00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 03 00 b7 0c 00  |{j.9....*.......|
-00000250  00 b3 03 00 1d 20 2f e5  7d a3 47 cd 62 43 15 28  |..... /.}.G.bC.(|
+00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 03 00 b6 0c 00  |{j.9....*.......|
+00000250  00 b2 03 00 1d 20 2f e5  7d a3 47 cd 62 43 15 28  |..... /.}.G.bC.(|
 00000260  da ac 5f bb 29 07 30 ff  f6 84 af c4 cf c2 ed 90  |.._.).0.........|
-00000270  99 5f 58 cb 3b 74 05 03  00 8b 30 81 88 02 42 01  |._X.;t....0...B.|
-00000280  4f 30 aa d0 4d e5 61 db  ba fc 95 15 52 ef 2a 41  |O0..M.a.....R.*A|
-00000290  b4 d6 59 ac 39 61 b6 38  08 1e 87 b3 ca 9b 49 d3  |..Y.9a.8......I.|
-000002a0  95 5a c5 29 84 cd 10 73  4a cc 09 df 1a b0 54 6d  |.Z.)...sJ.....Tm|
-000002b0  b8 61 28 80 2e ec cf 95  9d 6f c3 d9 ed 80 53 63  |.a(......o....Sc|
-000002c0  d9 02 42 00 af 71 2f 91  80 ff a1 79 82 c7 d9 79  |..B..q/....y...y|
-000002d0  fa 12 a9 88 7b 93 47 be  6a dc 80 42 17 9d 85 7a  |....{.G.j..B...z|
-000002e0  b8 1b fe 85 7f 5c 10 9c  9e 0e e1 71 a7 b0 12 02  |.....\.....q....|
-000002f0  e2 a4 79 c4 8d d8 02 09  01 9c 6f 7a 27 7c 1f f4  |..y.......oz'|..|
-00000300  38 46 59 46 94 16 03 03  00 04 0e 00 00 00        |8FYF..........|
+00000270  99 5f 58 cb 3b 74 06 03  00 8a 30 81 87 02 42 01  |._X.;t....0...B.|
+00000280  ed a6 35 6b 28 3f cc 4a  66 c1 21 a0 ba e3 a2 c2  |..5k(?.Jf.!.....|
+00000290  3b 45 41 87 9b c4 5d 01  b7 8b 01 89 b4 b1 16 99  |;EA...].........|
+000002a0  72 e2 94 6d 24 f2 9f be  6a 8b 9b b5 c7 9c cb 65  |r..m$...j......e|
+000002b0  38 ab 29 de 38 e5 64 4c  0b 75 67 c9 9d 5b dc 37  |8.).8.dL.ug..[.7|
+000002c0  86 02 41 33 ac b4 ff f3  db f7 2c c9 0b 43 8a 62  |..A3......,..C.b|
+000002d0  df 9d b9 c5 50 0b 8c f1  da 40 b1 ba a8 41 99 66  |....P....@...A.f|
+000002e0  1b e8 a0 20 0b 4f 0d 1e  55 12 c5 a2 a3 89 88 a0  |... .O..U.......|
+000002f0  9f 91 b9 73 9b b1 19 95  d6 53 3a b3 d7 5d 73 5c  |...s.....S:..]s\|
+00000300  c4 d6 6a 1a 16 03 03 00  04 0e 00 00 00           |..j..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 8c 80 e4 c7 bd d7  |....%...! ......|
-00000010  ea ea 42 f7 53 24 50 28  6a e9 f3 ff 4f 4a 28 22  |..B.S$P(j...OJ("|
-00000020  a2 95 09 fc f0 d9 3e fc  cc 6e 14 03 03 00 01 01  |......>..n......|
-00000030  16 03 03 00 40 79 56 60  f5 45 e7 48 9e 97 1d 49  |....@yV`.E.H...I|
-00000040  de 59 dd b0 f0 0a d2 cc  10 f0 98 3c c2 d5 67 d6  |.Y.........<..g.|
-00000050  2c 18 2b 21 ae a3 2f ea  2d 0b ff fd e6 c2 73 25  |,.+!../.-.....s%|
-00000060  1c 01 3e 94 3a cc 1d 58  6b fb 7f 85 e4 50 ec 10  |..>.:..Xk....P..|
-00000070  b9 d7 71 cb be                                    |..q..|
+00000000  16 03 03 00 25 10 00 00  21 20 5e 83 48 ba 4f 66  |....%...! ^.H.Of|
+00000010  74 7d 8a c6 53 d2 a9 cf  68 f1 50 f4 2a 06 74 ef  |t}..S...h.P.*.t.|
+00000020  07 57 b0 f9 3e 1a 49 98  52 44 14 03 03 00 01 01  |.W..>.I.RD......|
+00000030  16 03 03 00 40 1a b1 de  ad 95 eb 28 ed 07 ce fe  |....@......(....|
+00000040  8b 8a fc 9a 24 a8 c3 d4  2f 27 20 52 9d 47 ac 45  |....$.../' R.G.E|
+00000050  cc 66 c0 a4 03 cb 49 3c  93 05 3c 3e 64 91 d6 5c  |.f....I<..<>d..\|
+00000060  f9 73 1b 18 54 0b 67 c7  97 53 c8 7d 72 18 ab 47  |.s..T.g..S.}r..G|
+00000070  98 32 54 4c ff                                    |.2TL.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 83 5c 5c e3 c0  |............\\..|
-00000020  20 56 8c 92 4b 75 f0 30  bd 67 74 52 f1 af 9c 14  | V..Ku.0.gtR....|
-00000030  29 1e e4 b2 5b c0 2c e6  48 6f 94 42 7b 21 92 96  |)...[.,.Ho.B{!..|
-00000040  0a 83 ce 1c 91 36 95 8c  14 38 57 17 03 03 00 40  |.....6...8W....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 21 f3 63 c9 0a  |...........!.c..|
+00000020  7e 39 23 21 2d 2b 4b 72  47 65 30 b4 43 21 d1 d7  |~9#!-+KrGe0.C!..|
+00000030  4f fa 00 65 a1 95 fd 62  2c d3 4d 7d 30 d7 fd eb  |O..e...b,.M}0...|
+00000040  64 08 41 d6 70 ab cf 9d  75 c5 e1 17 03 03 00 40  |d.A.p...u......@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  73 a4 40 cf ad 86 cc 05  9e 47 5f 83 50 ae 68 d5  |s.@......G_.P.h.|
-00000070  d1 6a a9 8c ba 74 fe c0  cc 4a 1a e3 b0 14 0d 31  |.j...t...J.....1|
-00000080  9f 06 54 e3 95 3a 89 6d  34 54 0c e4 b4 34 38 21  |..T..:.m4T...48!|
+00000060  50 e5 5e 3a c1 2a 71 0a  ba eb 40 74 f1 70 0d 0a  |P.^:.*q...@t.p..|
+00000070  e1 86 22 fd 13 de e8 8f  a0 d3 22 a8 62 76 ca fa  |..".......".bv..|
+00000080  5f 63 95 ba bb e2 f3 b3  ef 5b d8 bf 56 0b 60 53  |_c.......[..V.`S|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 e6 dd b2  11 ab a7 34 61 00 d4 09  |...........4a...|
-000000b0  bc ea c1 5f c4 e2 52 60  63 96 f0 fd 44 4e f9 0e  |..._..R`c...DN..|
-000000c0  af 32 99 e4 12                                    |.2...|
+000000a0  00 00 00 00 00 4d 2c 41  d8 4c 63 71 bd bc 83 5a  |.....M,A.Lcq...Z|
+000000b0  1b 2b b7 20 5b 14 51 d4  5b 38 4b fc 61 58 97 34  |.+. [.Q.[8K.aX.4|
+000000c0  1a cf 08 f1 16                                    |.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
index 1f9fbc1..154521d 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
+++ b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 a7 01 00 00  a3 03 03 1d 39 c9 33 73  |............9.3s|
-00000010  c2 b9 71 d8 66 23 63 a7  5c 9e 50 b6 3e a5 f9 bb  |..q.f#c.\.P.>...|
-00000020  34 1b 71 e1 09 4f ae d5  53 8a e8 00 00 38 c0 2c  |4.q..O..S....8.,|
+00000000  16 03 01 00 a7 01 00 00  a3 03 03 df fc 06 29 d8  |..............).|
+00000010  a1 69 bd 2c d2 21 97 39  e8 4f 81 94 fa b9 58 6d  |.i.,.!.9.O....Xm|
+00000020  aa 15 ae f7 bc 03 7a fa  e3 33 bf 00 00 38 c0 2c  |......z..3...8.,|
 00000030  c0 30 00 9f cc a9 cc a8  cc aa c0 2b c0 2f 00 9e  |.0.........+./..|
 00000040  c0 24 c0 28 00 6b c0 23  c0 27 00 67 c0 0a c0 14  |.$.(.k.#.'.g....|
 00000050  00 39 c0 09 c0 13 00 33  00 9d 00 9c 00 3d 00 3c  |.9.....3.....=.<|
@@ -55,35 +55,35 @@
 00000290  3b e9 fa e7 16 03 03 00  ac 0c 00 00 a8 03 00 1d  |;...............|
 000002a0  20 2f e5 7d a3 47 cd 62  43 15 28 da ac 5f bb 29  | /.}.G.bC.(.._.)|
 000002b0  07 30 ff f6 84 af c4 cf  c2 ed 90 99 5f 58 cb 3b  |.0.........._X.;|
-000002c0  74 05 01 00 80 06 d4 bd  e4 7b 10 77 89 d7 d4 d6  |t........{.w....|
-000002d0  4e f6 3e 46 49 db ee 5c  4e bc ee fe cb 8b a6 9b  |N.>FI..\N.......|
-000002e0  5c f6 99 fb 31 96 60 a8  23 09 f6 31 65 53 f0 6e  |\...1.`.#..1eS.n|
-000002f0  07 5c 32 f9 59 5d 8b c0  b4 74 c8 01 85 8a b7 19  |.\2.Y]...t......|
-00000300  ab 19 08 68 6a e8 2f 81  bd 04 9b 38 ab d9 27 66  |...hj./....8..'f|
-00000310  d7 a5 3f 75 9c 4f 81 5b  9e 69 10 20 2b f2 1d a2  |..?u.O.[.i. +...|
-00000320  8f fc 7f ba ee 5b 76 8b  19 3f 46 60 01 25 99 72  |.....[v..?F`.%.r|
-00000330  78 24 02 8e 28 d5 24 f1  2e 6b 70 53 75 ec e2 8d  |x$..(.$..kpSu...|
-00000340  76 ab e0 8e e8 16 03 03  00 04 0e 00 00 00        |v.............|
+000002c0  74 06 01 00 80 a3 e7 63  ff 8a 7e 1c cb 9b ab 8a  |t......c..~.....|
+000002d0  7e f3 d1 fe c0 34 23 10  5e 0c e3 60 0d c5 cc 11  |~....4#.^..`....|
+000002e0  49 37 37 b6 ad b1 9a 29  b7 e4 1f 90 29 bf b3 bd  |I77....)....)...|
+000002f0  31 ed e6 20 4d 4c 2a a1  64 d8 cb 44 5e b1 5d b5  |1.. ML*.d..D^.].|
+00000300  a5 d5 67 de 29 e4 89 29  a9 51 bd b9 1f 01 de 72  |..g.)..).Q.....r|
+00000310  8b c1 b2 d0 fd 96 ec 94  29 4d 2e ee da 08 58 81  |........)M....X.|
+00000320  3b db 53 26 26 0e cb 57  37 f4 d0 fe 19 3e 41 a0  |;.S&&..W7....>A.|
+00000330  d5 0e a8 7a bf 29 56 a9  d4 84 da 33 bb bf f9 ba  |...z.)V....3....|
+00000340  54 7b d0 4a 95 16 03 03  00 04 0e 00 00 00        |T{.J..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 21 75 22 84 bc b7  |....%...! !u"...|
-00000010  82 b3 03 d2 42 ff b6 ce  76 26 88 bf 8f 72 fc dd  |....B...v&...r..|
-00000020  63 9b f1 4c 22 6d 12 cc  d3 57 14 03 03 00 01 01  |c..L"m...W......|
-00000030  16 03 03 00 40 20 2b 26  bd 60 1b 27 a1 32 cb ab  |....@ +&.`.'.2..|
-00000040  30 83 9c 47 59 7d f5 bb  d9 45 8a d9 3e 29 86 4d  |0..GY}...E..>).M|
-00000050  54 86 48 38 25 d9 b9 af  36 7c 7a f0 ae f6 b6 4e  |T.H8%...6|z....N|
-00000060  a1 76 93 91 26 f3 c9 49  b5 6d 49 cf 22 97 bf c7  |.v..&..I.mI."...|
-00000070  db 44 c8 7a e3                                    |.D.z.|
+00000000  16 03 03 00 25 10 00 00  21 20 36 84 23 91 d3 76  |....%...! 6.#..v|
+00000010  b3 ea 4a a6 39 f6 c9 1a  99 2c 69 c0 70 2d b2 72  |..J.9....,i.p-.r|
+00000020  72 be b3 24 4b d3 72 a1  eb 76 14 03 03 00 01 01  |r..$K.r..v......|
+00000030  16 03 03 00 40 e9 a5 32  9d 72 3d 9d 38 f3 0b fa  |....@..2.r=.8...|
+00000040  38 95 0f de 7d 99 42 b2  5b 1c f0 fe e4 66 2b 5a  |8...}.B.[....f+Z|
+00000050  98 1c e5 0e bf d9 37 d4  4c 72 29 a3 eb 8a f5 0e  |......7.Lr).....|
+00000060  44 ee 1e 21 c7 8c 10 23  dc 41 6d ac ee 72 5b d5  |D..!...#.Am..r[.|
+00000070  4b 3f 66 f3 d1                                    |K?f..|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 43 7c 61 f2 30  |...........C|a.0|
-00000020  c6 4a c2 76 da 7d 84 c6  ed 5d ee 2e 9c 33 e4 3b  |.J.v.}...]...3.;|
-00000030  e3 a1 ea ee 44 02 4b f7  90 f6 0c 8b 45 d7 26 2e  |....D.K.....E.&.|
-00000040  4a 37 43 1d 93 44 79 e6  5d c5 8c 17 03 03 00 40  |J7C..Dy.]......@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 f8 fb 0a 12 f2  |................|
+00000020  ee 27 b0 88 5d c9 02 c0  16 3c b8 a5 54 86 4b cb  |.'..]....<..T.K.|
+00000030  01 ef d1 6e 31 a8 88 86  e3 9f 71 f5 fb 2a a9 12  |...n1.....q..*..|
+00000040  72 76 98 30 1e 59 49 64  b1 6b e5 17 03 03 00 40  |rv.0.YId.k.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  b2 e4 62 17 e2 d4 d8 73  2b ea 77 39 78 51 1a 86  |..b....s+.w9xQ..|
-00000070  64 54 1f 36 9a cc a1 c0  d2 6d df b7 8a 2e 68 b0  |dT.6.....m....h.|
-00000080  79 9a 9f a1 15 b1 78 fa  db 2e 5a 43 0d fe 45 71  |y.....x...ZC..Eq|
+00000060  da fe c6 34 b0 e7 8d 34  78 11 b1 94 43 da 85 21  |...4...4x...C..!|
+00000070  28 9a f3 f8 f0 7f 14 9a  59 be 4e c4 a0 81 17 1b  |(.......Y.N.....|
+00000080  08 cd 6d 47 57 73 f1 10  e4 df 25 1b 8b 9d 87 98  |..mGWs....%.....|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 04 8c d0  bf 15 9f b4 55 22 b8 8e  |............U"..|
-000000b0  a5 a7 df ed bd b2 ab 88  71 38 bd b2 5d b4 5e 8e  |........q8..].^.|
-000000c0  54 fc e4 63 5a                                    |T..cZ|
+000000a0  00 00 00 00 00 41 b6 ed  ca 43 0d 83 67 da 4b 0e  |.....A...C..g.K.|
+000000b0  5a f4 a8 90 85 7f d6 d7  76 03 62 2e 49 7e 4a 62  |Z.......v.b.I~Jb|
+000000c0  32 03 a8 7c a0                                    |2..|.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
index 7a950db..8c6a7ed 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 8e 50 ff 02 c4  |....]...Y...P...|
-00000010  3b 5e dd ee 59 d1 3a e1  db f1 30 f4 bb a7 8a 8c  |;^..Y.:...0.....|
-00000020  b2 d2 1a fd f8 a4 c9 e4  5f 41 e1 00 00 04 00 2f  |........_A...../|
+00000000  16 03 01 00 5d 01 00 00  59 03 03 ba cf e7 3a 42  |....]...Y.....:B|
+00000010  aa f9 cd ca b8 b7 46 a0  4a 87 2c f8 76 14 d6 d0  |......F.J.,.v...|
+00000020  f8 66 ad ed 80 57 b0 9f  bf f5 32 00 00 04 00 2f  |.f...W....2..../|
 00000030  00 ff 01 00 00 2c 00 0d  00 20 00 1e 06 01 06 02  |.....,... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000050  03 02 03 03 02 01 02 02  02 03 00 16 00 00 00 17  |................|
@@ -48,9 +48,9 @@
 00000260  f1 6c 04 ed 73 bb b3 43  77 8d 0c 1c f1 0f a1 d8  |.l..s..Cw.......|
 00000270  40 83 61 c9 4c 72 2b 9d  ae db 46 06 06 4d f4 c1  |@.a.Lr+...F..M..|
 00000280  b3 3e c0 d1 bd 42 d4 db  fe 3d 13 60 84 5c 21 d3  |.>...B...=.`.\!.|
-00000290  3b e9 fa e7 16 03 03 00  17 0d 00 00 13 02 01 40  |;..............@|
-000002a0  00 0c 04 01 04 03 05 01  05 03 02 01 02 03 00 00  |................|
-000002b0  16 03 03 00 04 0e 00 00  00                       |.........|
+00000290  3b e9 fa e7 16 03 03 00  1b 0d 00 00 17 02 01 40  |;..............@|
+000002a0  00 10 04 01 04 03 05 01  05 03 06 01 06 03 02 01  |................|
+000002b0  02 03 00 00 16 03 03 00  04 0e 00 00 00           |.............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
@@ -85,40 +85,36 @@
 000001e0  be e8 91 b3 da 1a f5 5d  a3 23 f5 26 8b 45 70 8d  |.......].#.&.Ep.|
 000001f0  65 62 9b 7e 01 99 3d 18  f6 10 9a 38 61 9b 2e 57  |eb.~..=....8a..W|
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
-00000210  03 03 00 86 10 00 00 82  00 80 2b 80 6e 49 b8 ec  |..........+.nI..|
-00000220  12 7a 7c f3 2a d3 7e 16  a0 39 e5 77 61 7a 56 15  |.z|.*.~..9.wazV.|
-00000230  97 c6 64 63 13 cf 09 d0  1b f5 b6 78 1d cb 86 4f  |..dc.......x...O|
-00000240  14 84 c9 e6 5d 3c 6b 61  5e 46 83 7e ef 1d 74 d4  |....]<ka^F.~..t.|
-00000250  3b 8c 78 be 26 92 24 04  b4 6f 21 88 03 8d 92 a8  |;.x.&.$..o!.....|
-00000260  60 c6 08 b5 75 5d 2f 2c  71 60 5f 54 27 a0 fa 83  |`...u]/,q`_T'...|
-00000270  4d 39 1e 22 1e 1e 60 92  51 ac 2d 35 c7 cf fc 5e  |M9."..`.Q.-5...^|
-00000280  db e3 60 37 6b 4e 7c d8  04 f3 09 54 de 38 af 57  |..`7kN|....T.8.W|
-00000290  20 d0 f5 08 5a a8 6f 65  03 55 16 03 03 00 93 0f  | ...Z.oe.U......|
-000002a0  00 00 8f 04 03 00 8b 30  81 88 02 42 00 97 84 ac  |.......0...B....|
-000002b0  cf 9b df b0 3a c8 9d a6  da 8c 11 87 35 2a d7 d0  |....:.......5*..|
-000002c0  15 df e1 02 ca 85 3f 1c  a5 21 17 8c 8a 73 1b 76  |......?..!...s.v|
-000002d0  8d 0f af 26 ea b5 7f 87  a6 b6 c8 61 32 27 fc f4  |...&.......a2'..|
-000002e0  b7 c5 c3 2c 53 61 59 5a  5d 12 c6 dd 9e 54 02 42  |...,SaYZ]....T.B|
-000002f0  01 04 3f 82 bb a4 5c ea  ea c9 9c 2a 75 96 c2 88  |..?...\....*u...|
-00000300  5a ae f8 2e 29 01 cf 7b  a4 20 83 df ec c8 9d 37  |Z...)..{. .....7|
-00000310  0c 33 fb 20 73 51 47 6d  81 d0 75 b1 19 ed 02 00  |.3. sQGm..u.....|
-00000320  b8 40 67 75 b9 72 63 9c  1e e1 c9 44 93 d6 ec e7  |.@gu.rc....D....|
-00000330  16 5c 14 03 03 00 01 01  16 03 03 00 40 43 51 cf  |.\..........@CQ.|
-00000340  07 b2 de 6e 40 10 eb dd  3f 84 6a 54 a3 7f b2 48  |...n@...?.jT...H|
-00000350  b3 aa 3c d4 e7 69 32 7c  77 ba e9 0b 99 b3 c9 e8  |..<..i2|w.......|
-00000360  c5 53 29 9a 6b 82 ee 7d  5e a9 ae 63 fa a9 af 21  |.S).k..}^..c...!|
-00000370  f2 04 b1 a1 bf f1 10 4c  65 6c 49 34 a0           |.......LelI4.|
+00000210  03 03 00 86 10 00 00 82  00 80 d4 03 c6 f3 e2 5d  |...............]|
+00000220  15 db 9d c5 28 c4 30 e9  80 7b 56 89 0f 20 5b 8f  |....(.0..{V.. [.|
+00000230  47 8f bf 04 a5 d4 49 c9  ac 0f 54 c9 3d f0 cc 37  |G.....I...T.=..7|
+00000240  51 3c f8 3e 18 69 5b 58  a9 5a 88 ac 2c ff 5c b9  |Q<.>.i[X.Z..,.\.|
+00000250  65 2e 9a 9d 9e d4 3f 01  6b 47 e3 c8 ec e2 90 23  |e.....?.kG.....#|
+00000260  b9 9f a7 1f bf 7a c4 b3  68 e5 8a ee f5 4e 7b 49  |.....z..h....N{I|
+00000270  f3 3c b7 86 89 76 60 14  d5 a4 8e b1 5e 3f 5c 89  |.<...v`.....^?\.|
+00000280  a5 f8 69 7e 12 88 9d 30  7a 07 c2 ff 8f bb d0 94  |..i~...0z.......|
+00000290  1b 3c c4 fe 73 e6 25 99  77 d3 16 03 03 00 93 0f  |.<..s.%.w.......|
+000002a0  00 00 8f 04 03 00 8b 30  81 88 02 42 01 21 35 66  |.......0...B.!5f|
+000002b0  57 df 29 1a e5 10 1d e0  e0 00 ee 2a 0b 20 22 8b  |W.)........*. ".|
+000002c0  1d 70 4f 39 cb 96 30 b1  f0 8d 12 ba c8 15 67 05  |.pO9..0.......g.|
+000002d0  45 d2 fe 0a 4e 25 ce f4  8d 14 7b b8 6c 92 8b 99  |E...N%....{.l...|
+000002e0  9b 56 0a 78 ad 45 d6 09  88 ae c7 e6 2d 13 02 42  |.V.x.E......-..B|
+000002f0  01 5e 7e c9 ae 56 9e b6  de 38 fc a9 a6 e7 b9 35  |.^~..V...8.....5|
+00000300  9b 47 cd f7 82 1a 56 1c  cc d4 3a 15 79 d9 44 c4  |.G....V...:.y.D.|
+00000310  96 1a 10 69 31 ad c7 96  6b 3f f7 81 b6 04 4c bd  |...i1...k?....L.|
+00000320  ee e2 a1 15 8a 83 bc a0  42 b9 0f aa 6a 14 d1 fd  |........B...j...|
+00000330  9d 95 14 03 03 00 01 01  16 03 03 00 40 46 6b 0c  |............@Fk.|
+00000340  5d 7e 32 26 ef 7c a5 88  f0 ec 50 92 de 5f 87 7c  |]~2&.|....P.._.||
+00000350  b4 80 19 80 f4 89 19 f5  28 8f 21 09 fc 19 43 81  |........(.!...C.|
+00000360  92 94 37 f5 9b 6e 07 b1  35 29 ed 9a 87 a5 e9 ce  |..7..n..5)......|
+00000370  c3 e3 83 42 dd 2e 5a 0b  8e 22 bf 32 4e           |...B..Z..".2N|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 93 a2 18 a9 e2  |................|
-00000020  51 be f7 bd c0 05 64 51  0a 17 9d 58 11 d1 a6 b9  |Q.....dQ...X....|
-00000030  6d 1e 42 16 e4 bc bf 09  f2 b9 29 20 74 8a cd 8a  |m.B.......) t...|
-00000040  b6 31 04 64 fb 5b 1f 83  c3 19 78 17 03 03 00 40  |.1.d.[....x....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 13 c4 d2 3f b0  |..............?.|
+00000020  84 08 32 74 de cc e0 97  90 8a c6 cc 94 87 ac 48  |..2t...........H|
+00000030  65 f7 20 04 18 42 68 46  8e c0 19 b6 9d 2a 84 58  |e. ..BhF.....*.X|
+00000040  85 20 b3 ed 75 94 71 4e  5b 0a de 17 03 03 00 40  |. ..u.qN[......@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  ee c4 d0 5d 69 37 2b fc  dc 9c f1 77 df 44 6f da  |...]i7+....w.Do.|
-00000070  4e 22 05 05 3a 6c 32 a8  6c c2 fb ce ca a7 1b 54  |N"..:l2.l......T|
-00000080  2a 25 ae cf 77 e4 47 21  33 b6 29 54 62 00 dd 30  |*%..w.G!3.)Tb..0|
-00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 cf e1 fd  e3 5f d3 19 cd 05 70 79  |........._....py|
-000000b0  be 16 a5 26 18 f1 92 bc  73 bd 6f 4d 33 3d 6f 8a  |...&....s.oM3=o.|
-000000c0  13 51 7c 57 c7                                    |.Q|W.|
+00000060  c2 6e c5 13 4d 35 ab b1  de e2 1b a6 6f 0e 40 64  |.n..M5......o.@d|
+00000070  cc 67 bf 0d b1 e4 fe 48  c4 01 35 6a 94 50 17 7a  |.g.....H..5j.P.z|
+00000080  b3 6b f6 6b 2a 24 c9 b9  7b b0 42 0e 71 4d c2 da  |.k.k*$..{.B.qM..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
index c81acc8..aa4cfe1 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 f3 3a db 98 ff  |....]...Y...:...|
-00000010  29 a2 30 75 53 87 b3 5f  00 b5 9f 77 4d 88 38 ea  |).0uS.._...wM.8.|
-00000020  e9 87 f4 a4 e4 da dd 73  00 47 d1 00 00 04 00 2f  |.......s.G...../|
+00000000  16 03 01 00 5d 01 00 00  59 03 03 ed f9 4a 41 31  |....]...Y....JA1|
+00000010  20 6a df af 85 92 37 a1  38 81 ed 3c 1a 7e d2 31  | j....7.8..<.~.1|
+00000020  80 5b 68 87 b6 72 43 8e  c0 f0 dd 00 00 04 00 2f  |.[h..rC......../|
 00000030  00 ff 01 00 00 2c 00 0d  00 20 00 1e 06 01 06 02  |.....,... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000050  03 02 03 03 02 01 02 02  02 03 00 16 00 00 00 17  |................|
@@ -48,9 +48,9 @@
 00000260  f1 6c 04 ed 73 bb b3 43  77 8d 0c 1c f1 0f a1 d8  |.l..s..Cw.......|
 00000270  40 83 61 c9 4c 72 2b 9d  ae db 46 06 06 4d f4 c1  |@.a.Lr+...F..M..|
 00000280  b3 3e c0 d1 bd 42 d4 db  fe 3d 13 60 84 5c 21 d3  |.>...B...=.`.\!.|
-00000290  3b e9 fa e7 16 03 03 00  17 0d 00 00 13 02 01 40  |;..............@|
-000002a0  00 0c 04 01 04 03 05 01  05 03 02 01 02 03 00 00  |................|
-000002b0  16 03 03 00 04 0e 00 00  00                       |.........|
+00000290  3b e9 fa e7 16 03 03 00  1b 0d 00 00 17 02 01 40  |;..............@|
+000002a0  00 10 04 01 04 03 05 01  05 03 06 01 06 03 02 01  |................|
+000002b0  02 03 00 00 16 03 03 00  04 0e 00 00 00           |.............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fd 0b 00 01  f9 00 01 f6 00 01 f3 30  |...............0|
 00000010  82 01 ef 30 82 01 58 a0  03 02 01 02 02 10 5c 19  |...0..X.......\.|
@@ -84,40 +84,40 @@
 000001d0  ac 11 b1 28 56 be 1d cd  61 62 84 09 bf d6 80 c6  |...(V...ab......|
 000001e0  45 8d 82 2c b4 d8 83 9b  db c9 22 b7 2a 12 11 7b  |E..,......".*..{|
 000001f0  fa 02 3b c1 c9 ff ea c9  9d a8 49 d3 95 d7 d5 0e  |..;.......I.....|
-00000200  e5 35 16 03 03 00 86 10  00 00 82 00 80 47 31 82  |.5...........G1.|
-00000210  ae c1 d2 74 3f a4 74 5a  57 16 ae e2 d0 46 72 53  |...t?.tZW....FrS|
-00000220  e1 5e 6a e8 e4 d5 8c 84  2b d9 82 c1 4a da 9e 1d  |.^j.....+...J...|
-00000230  a0 da 60 08 0d 35 0c 55  6d 6a 68 04 09 ee 94 39  |..`..5.Umjh....9|
-00000240  c7 a3 49 7f 2c ee 6a cf  09 01 bd 08 d3 59 0a bd  |..I.,.j......Y..|
-00000250  7f 6c d3 26 eb be 7b fd  9b 17 fd e2 6e 82 d1 c7  |.l.&..{.....n...|
-00000260  dd c3 64 8c 87 f0 41 f2  71 75 f1 0a 01 26 5b 97  |..d...A.qu...&[.|
-00000270  94 ba ac 50 df 19 32 39  80 ae 14 ea 4a d2 e5 9f  |...P..29....J...|
-00000280  5d 07 9f 2d 89 ac 83 33  40 aa 8e cc 2c 16 03 03  |]..-...3@...,...|
-00000290  00 88 0f 00 00 84 04 01  00 80 7d 37 8b 6f be e9  |..........}7.o..|
-000002a0  e7 fa 4c 28 cf 16 0d 28  40 e9 f2 9a 11 22 fc 8a  |..L(...(@...."..|
-000002b0  2c 52 f7 36 af 1a cf d7  8a f8 17 19 9f ed 9d 1d  |,R.6............|
-000002c0  43 f9 e2 fb 0f dd ca d6  1d 4c 03 4e 25 8d 5c 4c  |C........L.N%.\L|
-000002d0  95 98 02 db cf ea 44 2a  ad 36 74 e3 08 07 e3 9a  |......D*.6t.....|
-000002e0  50 6c dc 46 a1 f5 84 9b  65 7f 48 94 b5 de cc a9  |Pl.F....e.H.....|
-000002f0  cf ee 0e 31 f2 f8 6f 8f  19 4b 29 14 b4 32 1d 21  |...1..o..K)..2.!|
-00000300  02 d2 da 64 68 e8 a1 72  cc ee 64 48 d8 74 e5 64  |...dh..r..dH.t.d|
-00000310  90 b3 50 cc 3e 25 0e b1  88 53 14 03 03 00 01 01  |..P.>%...S......|
-00000320  16 03 03 00 40 6a 61 6b  3e ea 63 2c b8 26 95 e2  |....@jak>.c,.&..|
-00000330  5f 83 e3 c3 cd c3 b7 a8  0b 76 81 8a 5b 46 ff 41  |_........v..[F.A|
-00000340  c2 02 eb 21 85 31 b9 ba  2e 30 e7 6e 8d 1c 49 15  |...!.1...0.n..I.|
-00000350  af a0 a7 67 62 b7 42 8c  fa a8 04 8c 23 7a 3d 39  |...gb.B.....#z=9|
-00000360  74 18 70 2b 99                                    |t.p+.|
+00000200  e5 35 16 03 03 00 86 10  00 00 82 00 80 90 96 a6  |.5..............|
+00000210  45 0a 8d 6a 38 86 3a f0  0a cb d6 bb db 9b 27 a6  |E..j8.:.......'.|
+00000220  17 ca 02 6d 67 3c 56 80  74 9b 06 6e 62 58 55 43  |...mg<V.t..nbXUC|
+00000230  7e 7d 08 be cb 46 c4 60  45 e5 1c 3c 7d 89 bd 0d  |~}...F.`E..<}...|
+00000240  c1 0a 7f d9 7c c2 c1 c6  c5 62 83 9e 88 a3 20 1c  |....|....b.... .|
+00000250  d5 d6 32 b5 f8 4a 44 d5  35 e5 45 c1 68 c3 99 d3  |..2..JD.5.E.h...|
+00000260  f3 7b 0b 46 0a 8d 02 81  ca bb 0c ce b1 53 f0 0a  |.{.F.........S..|
+00000270  10 b6 92 b3 b9 2a d5 8d  9d 68 94 54 11 37 69 12  |.....*...h.T.7i.|
+00000280  54 21 8a 95 a2 72 a8 1c  1a 21 74 9c 6f 16 03 03  |T!...r...!t.o...|
+00000290  00 88 0f 00 00 84 04 01  00 80 b9 cf 9f 51 c7 0b  |.............Q..|
+000002a0  5c b0 2f ce 33 b0 d9 b6  c6 ae 47 29 09 8c 44 51  |\./.3.....G)..DQ|
+000002b0  40 86 04 66 d2 13 ff 22  f4 97 c6 c2 a0 1f 98 8e  |@..f..."........|
+000002c0  a6 6e 9f 61 b1 fe ce 0d  82 43 42 06 9b 47 09 48  |.n.a.....CB..G.H|
+000002d0  a4 94 40 9f d3 2c 0f 22  f8 01 53 f0 a7 2a fd 86  |..@..,."..S..*..|
+000002e0  0b a2 b8 d7 b0 ee 0c a8  b7 c8 61 80 85 28 73 0b  |..........a..(s.|
+000002f0  c0 8f 8a 2c 53 cc 2c 8a  5b 72 5a a6 9e 66 ea 96  |...,S.,.[rZ..f..|
+00000300  7d e2 14 47 7e 17 a9 2b  d7 27 ca f7 21 ff 28 57  |}..G~..+.'..!.(W|
+00000310  fa 20 88 99 db 4f 91 0a  be 07 14 03 03 00 01 01  |. ...O..........|
+00000320  16 03 03 00 40 af 85 82  66 bd 2c 4b c8 17 4c d8  |....@...f.,K..L.|
+00000330  69 6d 62 37 88 70 cf b2  31 f5 46 90 a6 fa ac 3d  |imb7.p..1.F....=|
+00000340  02 1e 74 bb 24 83 35 34  ed 3f 7c ba d9 03 e1 4a  |..t.$.54.?|....J|
+00000350  cf d5 16 aa 56 47 47 27  0e 68 de 12 bd 56 6e df  |....VGG'.h...Vn.|
+00000360  fc 7e f1 34 ad                                    |.~.4.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 a6 5b 7c b0 91  |............[|..|
-00000020  53 f6 d5 e4 34 71 4f 64  2a 03 9d 75 62 d9 8d a8  |S...4qOd*..ub...|
-00000030  39 7b e1 d8 31 80 26 db  14 f3 3a 52 66 7d 12 31  |9{..1.&...:Rf}.1|
-00000040  29 14 7f a1 39 b6 1c e0  c9 55 6e 17 03 03 00 40  |)...9....Un....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 52 d1 34 99 c9  |...........R.4..|
+00000020  60 18 c3 99 36 2d c5 c2  14 ae f4 e5 10 e1 6f af  |`...6-........o.|
+00000030  70 3b c3 d6 d1 81 ee da  fe 6e a5 96 81 53 cf 9a  |p;.......n...S..|
+00000040  cc c2 ac 98 95 0c 75 81  ac 55 6b 17 03 03 00 40  |......u..Uk....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  5e 00 64 9b 25 cd 74 94  b7 65 6e 83 8e 5b 68 e8  |^.d.%.t..en..[h.|
-00000070  59 4c f0 31 8b f2 0c 59  2a ff 11 8e 43 d4 73 fd  |YL.1...Y*...C.s.|
-00000080  b3 2a 76 59 25 52 32 76  bd 2e 1d 4d 0a 53 d7 c2  |.*vY%R2v...M.S..|
+00000060  46 ff 8d a9 0d 65 e1 82  48 4c 31 ec 60 24 61 52  |F....e..HL1.`$aR|
+00000070  33 41 b1 7b 6a a8 96 b3  59 eb c9 2c f8 f2 4d 15  |3A.{j...Y..,..M.|
+00000080  83 3e 99 c4 08 89 24 e3  de 4a bf 54 f4 eb a3 2a  |.>....$..J.T...*|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 23 96 6e  7d 41 bb 51 4f 40 52 07  |.....#.n}A.QO@R.|
-000000b0  90 cc 6c bd c0 bb 99 d4  8a 91 7b 8a f3 24 ef 71  |..l.......{..$.q|
-000000c0  20 d4 98 b0 14                                    | ....|
+000000a0  00 00 00 00 00 dc f3 c7  14 24 b7 a8 fa f4 78 6f  |.........$....xo|
+000000b0  7a 0c bd ad 14 d5 83 f7  97 30 58 0a a8 b5 76 88  |z........0X...v.|
+000000c0  60 00 3d 4c 1a                                    |`.=L.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
index 091de90..924ef9d 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 41 24 db 27 37  |....]...Y..A$.'7|
-00000010  2e 1e a8 61 b7 7f 08 f1  83 84 fb d5 a2 96 e0 53  |...a...........S|
-00000020  1a 2b cd 8e 50 38 7b a5  64 d8 92 00 00 04 00 2f  |.+..P8{.d....../|
+00000000  16 03 01 00 5d 01 00 00  59 03 03 ee 51 24 51 2c  |....]...Y...Q$Q,|
+00000010  0b 9f 26 d2 7c e0 8b 8a  9b a8 d3 a9 a7 59 05 a3  |..&.|........Y..|
+00000020  67 92 fc 3f cb e8 cd ba  62 b7 19 00 00 04 00 2f  |g..?....b....../|
 00000030  00 ff 01 00 00 2c 00 0d  00 20 00 1e 06 01 06 02  |.....,... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
 00000050  03 02 03 03 02 01 02 02  02 03 00 16 00 00 00 17  |................|
@@ -48,36 +48,36 @@
 00000260  f1 6c 04 ed 73 bb b3 43  77 8d 0c 1c f1 0f a1 d8  |.l..s..Cw.......|
 00000270  40 83 61 c9 4c 72 2b 9d  ae db 46 06 06 4d f4 c1  |@.a.Lr+...F..M..|
 00000280  b3 3e c0 d1 bd 42 d4 db  fe 3d 13 60 84 5c 21 d3  |.>...B...=.`.\!.|
-00000290  3b e9 fa e7 16 03 03 00  17 0d 00 00 13 02 01 40  |;..............@|
-000002a0  00 0c 04 01 04 03 05 01  05 03 02 01 02 03 00 00  |................|
-000002b0  16 03 03 00 04 0e 00 00  00                       |.........|
+00000290  3b e9 fa e7 16 03 03 00  1b 0d 00 00 17 02 01 40  |;..............@|
+000002a0  00 10 04 01 04 03 05 01  05 03 06 01 06 03 02 01  |................|
+000002b0  02 03 00 00 16 03 03 00  04 0e 00 00 00           |.............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 07 0b 00 00  03 00 00 00 16 03 03 00  |................|
-00000010  86 10 00 00 82 00 80 61  2e 6b ad 77 48 8d 2f 0e  |.......a.k.wH./.|
-00000020  e6 27 64 fd 95 22 72 68  80 8e 2b 0e b2 0f cc be  |.'d.."rh..+.....|
-00000030  19 31 93 1d d3 0a fb 00  da 50 26 66 17 59 6b e9  |.1.......P&f.Yk.|
-00000040  7e 16 4e 24 ba 68 0a 0c  69 2f 03 74 34 50 12 85  |~.N$.h..i/.t4P..|
-00000050  4a f0 6c 52 d4 dd 13 18  c7 a4 9d ea f0 c6 94 d9  |J.lR............|
-00000060  ae fe 19 6c 83 dd ed 38  e3 d2 21 18 e6 76 11 e7  |...l...8..!..v..|
-00000070  62 13 8b 56 65 e0 f6 61  d9 db 7c 7b 5b 57 13 3d  |b..Ve..a..|{[W.=|
-00000080  58 64 67 8d 9f 3f 6a a0  70 c5 c6 d0 db eb 17 3f  |Xdg..?j.p......?|
-00000090  6c 58 d7 c3 ba ec 4c 14  03 03 00 01 01 16 03 03  |lX....L.........|
-000000a0  00 40 6e 24 1b a4 b3 e7  d4 c2 7e cb bd 82 2d 4c  |.@n$......~...-L|
-000000b0  a8 f1 5e 81 c8 61 a6 2c  6a e3 6d 30 7f fa c7 f3  |..^..a.,j.m0....|
-000000c0  f6 b1 b1 4f 0b 23 9a fd  66 81 48 97 4b 0f 88 07  |...O.#..f.H.K...|
-000000d0  37 7b 97 b0 62 6c 2a e1  47 65 e9 f9 cd c1 79 99  |7{..bl*.Ge....y.|
-000000e0  6d 84                                             |m.|
+00000010  86 10 00 00 82 00 80 0b  e8 d9 4f fa 7d 63 8c 89  |..........O.}c..|
+00000020  b7 c8 73 76 9b fa 7f b6  c3 57 f2 54 75 90 90 ec  |..sv.....W.Tu...|
+00000030  9e 8d 08 ae 3f dc 6e fa  df 2a 32 2b 35 e9 03 f7  |....?.n..*2+5...|
+00000040  c5 d1 7c f5 20 1f 77 0a  24 b8 4e 7e 11 fe b0 87  |..|. .w.$.N~....|
+00000050  db f6 ff 92 1a fc 6a 8d  48 7e ac bc 95 99 4a f8  |......j.H~....J.|
+00000060  1b cc 07 42 48 0c 25 d2  47 82 59 14 76 84 d3 e9  |...BH.%.G.Y.v...|
+00000070  d6 0a 5a b1 0a c6 31 3e  80 e2 29 c8 a6 31 dd 64  |..Z...1>..)..1.d|
+00000080  96 7a f5 ee d9 0f 03 b5  93 05 b8 a2 04 66 ff fc  |.z...........f..|
+00000090  f5 2f e7 6c b9 2d 98 14  03 03 00 01 01 16 03 03  |./.l.-..........|
+000000a0  00 40 f2 d2 da 46 89 c4  17 25 b8 33 d6 38 46 5c  |.@...F...%.3.8F\|
+000000b0  80 a0 eb cf fd 5a 27 f3  0b 16 e1 29 bd b8 46 28  |.....Z'....)..F(|
+000000c0  11 d3 cc 12 12 96 9b b8  31 52 50 73 81 57 aa 29  |........1RPs.W.)|
+000000d0  5c 66 da 39 2d f8 cb 15  e0 01 86 b5 0b d5 1f 56  |\f.9-..........V|
+000000e0  23 a0                                             |#.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 40 c6 62 4e 26  |...........@.bN&|
-00000020  e7 32 09 ba d6 3b 71 79  8e 75 ee fb af 09 db c5  |.2...;qy.u......|
-00000030  a5 8b cd 1f 90 f3 65 86  4a b4 b1 9a e8 1e 80 f6  |......e.J.......|
-00000040  ad db bd c2 9f ec 98 42  0b 37 30 17 03 03 00 40  |.......B.70....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 65 58 5e 2f 25  |...........eX^/%|
+00000020  67 71 87 7d a9 75 73 80  6b 03 76 63 a8 1f 80 06  |gq.}.us.k.vc....|
+00000030  0f 78 b0 75 20 9e ab 36  59 d7 f9 88 22 c1 d1 be  |.x.u ..6Y..."...|
+00000040  c9 d2 c1 13 20 6a 75 07  95 00 ca 17 03 03 00 40  |.... ju........@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  a9 74 3c 13 87 f4 cf 77  be 07 c2 a1 e0 47 4e 52  |.t<....w.....GNR|
-00000070  c2 86 da 08 c2 93 21 80  4c 19 51 cc 0d 76 49 75  |......!.L.Q..vIu|
-00000080  0b 48 3d e0 e2 01 93 4b  f1 73 91 17 aa 00 b5 71  |.H=....K.s.....q|
+00000060  25 31 9c 1d 48 d9 c3 e4  59 3a 3a e2 85 3a 78 27  |%1..H...Y::..:x'|
+00000070  85 69 63 8e 3c 32 b2 03  65 3f 7a 7f 3b fe b1 83  |.ic.<2..e?z.;...|
+00000080  f6 64 a1 3e 83 55 7b 39  2a 01 86 de 79 a3 55 b1  |.d.>.U{9*...y.U.|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 1f 2f 2d  d7 39 06 c4 59 49 80 66  |....../-.9..YI.f|
-000000b0  6c 35 2e a7 45 ee 0a 05  4b 1e 7f 78 5d cd 24 2c  |l5..E...K..x].$,|
-000000c0  0a 3e 55 1c 7d                                    |.>U.}|
+000000a0  00 00 00 00 00 40 26 48  75 e5 e0 83 c0 1a 66 5a  |.....@&Hu.....fZ|
+000000b0  5f b2 11 a6 b7 a3 4d f2  ca 49 6a f2 48 a1 ee 99  |_.....M..Ij.H...|
+000000c0  ff 0d c1 f7 4f                                    |....O|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
index b412980..8aa11ab 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 73 01 00 00  6f 03 03 f0 4f 82 cc 2a  |....s...o...O..*|
-00000010  27 0b 7f 2e e4 af 6d ba  4e fe 61 99 fc 0a 44 ee  |'.....m.N.a...D.|
-00000020  c0 4e 7b 3a 7c f0 6d 12  b7 7d 9e 00 00 04 c0 0a  |.N{:|.m..}......|
+00000000  16 03 01 00 73 01 00 00  6f 03 03 8b 7a 0c fa 8b  |....s...o...z...|
+00000010  92 b9 b6 d6 b8 93 50 29  07 2e 8e 70 9b a1 55 65  |......P)...p..Ue|
+00000020  ba 05 9d 74 2e 7e a6 2a  10 e1 3c 00 00 04 c0 0a  |...t.~.*..<.....|
 00000030  00 ff 01 00 00 42 00 0b  00 04 03 00 01 02 00 0a  |.....B..........|
 00000040  00 0a 00 08 00 1d 00 17  00 19 00 18 00 0d 00 20  |............... |
 00000050  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
@@ -47,36 +47,36 @@
 00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 03 00 b7 0c 00  |{j.9....*.......|
 00000250  00 b3 03 00 1d 20 2f e5  7d a3 47 cd 62 43 15 28  |..... /.}.G.bC.(|
 00000260  da ac 5f bb 29 07 30 ff  f6 84 af c4 cf c2 ed 90  |.._.).0.........|
-00000270  99 5f 58 cb 3b 74 05 03  00 8b 30 81 88 02 42 01  |._X.;t....0...B.|
-00000280  2d d4 82 80 01 6b e6 8c  6a 2a b3 09 1b 0d 86 e6  |-....k..j*......|
-00000290  62 92 85 46 d9 e3 b2 e9  f1 5e 77 c2 27 fd 2b 68  |b..F.....^w.'.+h|
-000002a0  6a e1 3d e2 42 d2 86 96  42 b1 3b 50 7b e2 2c 34  |j.=.B...B.;P{.,4|
-000002b0  d3 e7 f6 14 89 48 eb 5c  9a 98 98 ab f3 db 85 06  |.....H.\........|
-000002c0  cb 02 42 00 df 42 94 63  a5 ff 43 a5 20 5d 83 09  |..B..B.c..C. ]..|
-000002d0  88 7d 10 ff ec 32 33 28  1d 43 b2 d2 bf 39 0c 63  |.}...23(.C...9.c|
-000002e0  9a c0 f8 0e 9f 71 a7 9a  5d 27 1a 5c f2 36 80 b3  |.....q..]'.\.6..|
-000002f0  71 0f d3 c0 fd 0d 5d 02  90 c4 9d 90 db 74 ad f6  |q.....]......t..|
-00000300  22 8f 6b 9d 55 16 03 03  00 04 0e 00 00 00        |".k.U.........|
+00000270  99 5f 58 cb 3b 74 06 03  00 8b 30 81 88 02 42 00  |._X.;t....0...B.|
+00000280  cb 8e af 48 f8 79 66 5b  9a 52 8d 67 ec 13 02 a5  |...H.yf[.R.g....|
+00000290  ab 77 9e 15 17 c2 4e ff  7a b4 5b 53 1a 16 22 3f  |.w....N.z.[S.."?|
+000002a0  b8 83 40 99 64 67 b3 54  19 29 6b 2d a8 3c 63 44  |..@.dg.T.)k-.<cD|
+000002b0  d5 45 20 3f 9a 8e b9 71  d6 7a 85 d5 aa 99 7f 02  |.E ?...q.z......|
+000002c0  a8 02 42 00 c1 15 3b 9b  9d de eb 2e 63 52 35 b2  |..B...;.....cR5.|
+000002d0  1e 63 b1 1a 20 58 e5 e7  6d b3 e8 c8 3d 0f af 98  |.c.. X..m...=...|
+000002e0  4a 2a a0 f8 8e aa 2a f2  2a 1e 41 98 be 6f 6c bc  |J*....*.*.A..ol.|
+000002f0  ad 57 1d 2b 50 0b d9 47  d2 7a 62 08 a5 e5 28 44  |.W.+P..G.zb...(D|
+00000300  a7 e2 eb 4a b8 16 03 03  00 04 0e 00 00 00        |...J..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 af 52 73 d4 46 4d  |....%...! .Rs.FM|
-00000010  bc 0e dd 56 1f 7f 72 ce  6c 99 b9 64 53 7d 53 8d  |...V..r.l..dS}S.|
-00000020  0c a4 75 8c 83 3b 4b 76  2d 4f 14 03 03 00 01 01  |..u..;Kv-O......|
-00000030  16 03 03 00 40 a0 ef 9f  54 a8 ab 7c 5b 4a a1 b2  |....@...T..|[J..|
-00000040  5d 5b 6a d7 a7 32 35 46  58 d0 ba 38 6f 94 6e 9a  |][j..25FX..8o.n.|
-00000050  41 16 82 ed 4d 39 c4 ff  06 bf 2c 67 47 70 56 4e  |A...M9....,gGpVN|
-00000060  c5 ac 7f a0 5d d9 89 82  7a d9 36 07 55 b3 20 f4  |....]...z.6.U. .|
-00000070  b2 73 cf c3 7d                                    |.s..}|
+00000000  16 03 03 00 25 10 00 00  21 20 d2 c0 5b 2a f2 05  |....%...! ..[*..|
+00000010  4d 57 b0 d0 8b 51 b0 7f  1f 71 8b d9 55 76 46 c9  |MW...Q...q..UvF.|
+00000020  a8 40 44 2c a1 51 74 50  4a 22 14 03 03 00 01 01  |.@D,.QtPJ"......|
+00000030  16 03 03 00 40 79 6d 1b  bc e7 5b 5c 7b 99 62 2b  |....@ym...[\{.b+|
+00000040  4a 1a b2 0f 76 72 67 d1  ec 25 04 5f fb 25 f4 9c  |J...vrg..%._.%..|
+00000050  9c 47 bb b9 85 28 59 0c  0c 15 3f 86 a5 16 c8 ef  |.G...(Y...?.....|
+00000060  a4 e6 8e c0 96 37 47 5a  c8 cd f2 90 41 9b 94 dc  |.....7GZ....A...|
+00000070  ec fe e2 df d4                                    |.....|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 73 5f db 9e 08  |...........s_...|
-00000020  10 38 3b c0 95 6b dd fc  16 b2 d1 db 63 13 ca d5  |.8;..k......c...|
-00000030  b5 be 5a 1d 74 b5 75 f3  a2 63 59 be a7 d0 ab 0d  |..Z.t.u..cY.....|
-00000040  d3 43 83 8a 1d 59 ed fd  ea f0 b9 17 03 03 00 40  |.C...Y.........@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 8a 19 1e 82 d0  |................|
+00000020  46 f4 79 8d 9b fd 55 25  a9 6b d8 30 b3 41 f8 df  |F.y...U%.k.0.A..|
+00000030  a5 f8 9d 4c fe cc e1 1c  62 70 cf 60 12 cb 14 3e  |...L....bp.`...>|
+00000040  86 e9 d1 bb 46 60 7d b5  74 5f f5 17 03 03 00 40  |....F`}.t_.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  cf 20 4f 4f bf c4 00 05  1e ca 7f 6f 69 77 e9 52  |. OO.......oiw.R|
-00000070  14 61 02 6d f1 c0 ad 7c  1a 34 cf b2 7a 58 4a 70  |.a.m...|.4..zXJp|
-00000080  11 36 5f e9 21 62 cb eb  8f e7 11 04 bf 66 03 69  |.6_.!b.......f.i|
+00000060  97 1c 70 9d cf 17 89 8c  c7 ad 84 38 6e f5 c6 d1  |..p........8n...|
+00000070  c8 6e b2 a2 69 27 9a 59  fb bc af c0 15 47 40 b9  |.n..i'.Y.....G@.|
+00000080  e1 35 9b 37 50 9f 05 53  60 f8 f9 91 40 67 36 a8  |.5.7P..S`...@g6.|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 f5 35 92  09 6c 45 c0 27 95 98 a9  |......5..lE.'...|
-000000b0  86 56 53 1f a8 01 d5 0b  79 0e 91 15 3b 9a 07 21  |.VS.....y...;..!|
-000000c0  cb ce f0 2b 6a                                    |...+j|
+000000a0  00 00 00 00 00 0f 90 a8  00 9e 0e 51 29 b5 96 da  |...........Q)...|
+000000b0  b1 0d 81 7b 71 ff c9 de  f8 aa c4 bd e1 7d 0d 35  |...{q........}.5|
+000000c0  b1 ed ae 20 3c                                    |... <|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
index 4e52915..4c1cbc9 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 73 01 00 00  6f 03 03 4e 1a d7 67 e4  |....s...o..N..g.|
-00000010  d1 11 85 bc 62 59 da 8f  ea d0 a0 2b 9b d3 47 aa  |....bY.....+..G.|
-00000020  d0 39 6f 3f 42 dc 7c 16  bb 25 ef 00 00 04 c0 2f  |.9o?B.|..%...../|
+00000000  16 03 01 00 73 01 00 00  6f 03 03 38 2b d9 54 15  |....s...o..8+.T.|
+00000010  60 c3 a7 88 e6 c3 73 8f  b0 76 4f d0 10 72 2c d6  |`.....s..vO..r,.|
+00000020  55 fc c2 f0 ab 0f 62 43  f1 86 f8 00 00 04 c0 2f  |U.....bC......./|
 00000030  00 ff 01 00 00 42 00 0b  00 04 03 00 01 02 00 0a  |.....B..........|
 00000040  00 0a 00 08 00 1d 00 17  00 19 00 18 00 0d 00 20  |............... |
 00000050  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
@@ -52,28 +52,28 @@
 00000290  3b e9 fa e7 16 03 03 00  ac 0c 00 00 a8 03 00 1d  |;...............|
 000002a0  20 2f e5 7d a3 47 cd 62  43 15 28 da ac 5f bb 29  | /.}.G.bC.(.._.)|
 000002b0  07 30 ff f6 84 af c4 cf  c2 ed 90 99 5f 58 cb 3b  |.0.........._X.;|
-000002c0  74 05 01 00 80 b2 49 30  60 b7 0c 48 cb 9f 1c 75  |t.....I0`..H...u|
-000002d0  a6 b0 b0 7b 5e e6 f9 bc  5a 49 d4 51 e2 76 4c 01  |...{^...ZI.Q.vL.|
-000002e0  55 bd 37 cf 86 75 4f 33  9b fd 3c fc bb da 81 a9  |U.7..uO3..<.....|
-000002f0  26 7b 82 31 c5 51 0f d4  e8 fa a3 16 45 19 c8 40  |&{.1.Q......E..@|
-00000300  23 fa 32 bc 05 36 fb a7  a2 d9 6f e7 bc b8 27 0b  |#.2..6....o...'.|
-00000310  2a 9e 7b 95 fd b4 c0 2e  f0 73 fe fb a2 ea 20 a2  |*.{......s.... .|
-00000320  73 73 96 c8 bc 82 58 09  84 fc f4 09 2a c8 68 cb  |ss....X.....*.h.|
-00000330  66 b0 de 2c 78 7a d4 ec  06 f1 1c 52 03 5a 69 24  |f..,xz.....R.Zi$|
-00000340  c4 e6 bb 68 f4 16 03 03  00 04 0e 00 00 00        |...h..........|
+000002c0  74 06 01 00 80 65 4e 5d  69 d6 97 39 e8 dc 13 58  |t....eN]i..9...X|
+000002d0  c1 2a cf 72 12 42 34 8c  4a c1 b5 94 44 0c f2 97  |.*.r.B4.J...D...|
+000002e0  46 ba 59 20 1c f2 9d 23  d7 2e 9f 7c 52 ac 08 fe  |F.Y ...#...|R...|
+000002f0  02 23 e3 ee ec 21 1f bd  08 8a 50 48 aa 21 b7 ed  |.#...!....PH.!..|
+00000300  be 30 be ac ff 8f e8 71  c9 bc d8 b8 56 63 8a fc  |.0.....q....Vc..|
+00000310  52 0e 3d e1 4e ce cc 53  d4 f8 36 70 1f 4e 16 61  |R.=.N..S..6p.N.a|
+00000320  14 4d dd fe 17 08 f5 09  53 9b c6 24 7d de af dc  |.M......S..$}...|
+00000330  1b 84 23 c2 72 9c 25 73  1a 4f 42 27 b5 95 b1 06  |..#.r.%s.OB'....|
+00000340  dd 36 de 0c 76 16 03 03  00 04 0e 00 00 00        |.6..v.........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 41 d4 8d 53 2e 47  |....%...! A..S.G|
-00000010  b8 35 ba 86 3c 41 07 2e  c1 a0 9d c2 e9 11 d8 20  |.5..<A......... |
-00000020  a1 fa 0a ff 28 64 5b af  c3 67 14 03 03 00 01 01  |....(d[..g......|
-00000030  16 03 03 00 28 78 fd 19  36 4d a7 ca ab ba 06 6b  |....(x..6M.....k|
-00000040  3f a5 79 17 2f 2b ec f6  19 db 17 1a 52 ea 72 0b  |?.y./+......R.r.|
-00000050  01 af 56 8b 14 8f 8a 04  f3 ff ea fe 33           |..V.........3|
+00000000  16 03 03 00 25 10 00 00  21 20 95 a4 0d a1 cd 3a  |....%...! .....:|
+00000010  5e 81 bb e3 77 39 f0 6b  37 fe 35 e2 dc 29 6c b0  |^...w9.k7.5..)l.|
+00000020  2b e9 b9 84 1d 65 b1 63  d7 0e 14 03 03 00 01 01  |+....e.c........|
+00000030  16 03 03 00 28 13 84 cb  17 e5 aa c8 09 43 ed 1a  |....(........C..|
+00000040  08 92 55 3c e1 b8 5a c0  05 00 30 ae 63 6f 4c 78  |..U<..Z...0.coLx|
+00000050  22 42 66 18 91 85 9c 2b  c6 88 76 7d bd           |"Bf....+..v}.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-00000010  00 00 00 ec 99 e0 9a 83  28 94 e6 72 4f be 28 24  |........(..rO.($|
-00000020  64 bd 9d 86 79 cc ab 05  15 39 06 6e da 0c b8 4e  |d...y....9.n...N|
-00000030  6c a9 f3 17 03 03 00 25  00 00 00 00 00 00 00 01  |l......%........|
-00000040  9a d7 b0 54 dd 3c ae 8e  3f 1f 41 68 a5 01 a0 da  |...T.<..?.Ah....|
-00000050  e8 8e 90 55 1a 11 f0 70  8d a3 af a4 29 15 03 03  |...U...p....)...|
-00000060  00 1a 00 00 00 00 00 00  00 02 a8 96 cb 16 d7 b1  |................|
-00000070  41 7e bc 0e 01 8f cc 47  40 e5 c7 2a              |A~.....G@..*|
+00000010  00 00 00 fb 80 e0 2e 22  3e 45 98 c2 64 a1 0d 0a  |.......">E..d...|
+00000020  0c 55 40 6e 1b a9 de 29  e3 c8 1a b3 36 ba 5d 88  |.U@n...)....6.].|
+00000030  c0 c9 d6 17 03 03 00 25  00 00 00 00 00 00 00 01  |.......%........|
+00000040  ef 6a 01 41 ec 78 94 2d  d5 c3 48 b8 5e 57 93 34  |.j.A.x.-..H.^W.4|
+00000050  82 03 33 ae 03 22 69 9b  32 8f 71 73 6c 15 03 03  |..3.."i.2.qsl...|
+00000060  00 1a 00 00 00 00 00 00  00 02 31 37 35 60 f8 01  |..........175`..|
+00000070  5d 1f ab be 0d 79 ac c8  34 f0 14 f9              |]....y..4...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
index 36be9da..f80f166 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 73 01 00 00  6f 03 03 b7 d2 dc fe 53  |....s...o......S|
-00000010  d6 13 08 19 be 30 22 17  db a7 06 9b 62 82 14 38  |.....0".....b..8|
-00000020  2e 68 70 08 02 7d 22 64  13 75 f5 00 00 04 c0 30  |.hp..}"d.u.....0|
+00000000  16 03 01 00 73 01 00 00  6f 03 03 7c 43 b4 7c 36  |....s...o..|C.|6|
+00000010  56 e5 d4 47 83 a7 ae 17  cb 5e 7d 5f b7 ef 41 dd  |V..G.....^}_..A.|
+00000020  63 d3 e6 a0 62 f7 af 91  25 75 15 00 00 04 c0 30  |c...b...%u.....0|
 00000030  00 ff 01 00 00 42 00 0b  00 04 03 00 01 02 00 0a  |.....B..........|
 00000040  00 0a 00 08 00 1d 00 17  00 19 00 18 00 0d 00 20  |............... |
 00000050  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
@@ -52,28 +52,28 @@
 00000290  3b e9 fa e7 16 03 03 00  ac 0c 00 00 a8 03 00 1d  |;...............|
 000002a0  20 2f e5 7d a3 47 cd 62  43 15 28 da ac 5f bb 29  | /.}.G.bC.(.._.)|
 000002b0  07 30 ff f6 84 af c4 cf  c2 ed 90 99 5f 58 cb 3b  |.0.........._X.;|
-000002c0  74 05 01 00 80 b8 c4 6a  be 2a dd 47 03 7b 84 72  |t......j.*.G.{.r|
-000002d0  0b a4 c0 a7 2e b5 a4 be  c7 6a 2a 8b d0 23 6f b5  |.........j*..#o.|
-000002e0  bc 0e ba 3c f5 9d a3 90  b0 af 80 11 bd 22 b5 7b  |...<.........".{|
-000002f0  3c 53 f8 54 d0 b4 b0 53  28 75 0d 15 58 88 c2 90  |<S.T...S(u..X...|
-00000300  69 ea e0 08 aa 07 93 15  ae ed e5 a8 3d 2d 9c 62  |i...........=-.b|
-00000310  1d 40 26 7d 0e d3 23 52  71 71 ff ea 18 f9 0a eb  |.@&}..#Rqq......|
-00000320  78 8a 8f 9e 12 8c 0b 33  a8 ee 42 76 16 29 58 ec  |x......3..Bv.)X.|
-00000330  ea 6d 22 48 0d d0 68 c3  97 8d e9 ec cd 10 f6 47  |.m"H..h........G|
-00000340  c9 9d 42 12 54 16 03 03  00 04 0e 00 00 00        |..B.T.........|
+000002c0  74 06 01 00 80 8b b6 3e  52 d2 87 bf 9f 82 6d 0e  |t......>R.....m.|
+000002d0  8f de 69 34 58 71 9e 36  46 35 7e 73 ad f0 ee 30  |..i4Xq.6F5~s...0|
+000002e0  0c 95 dc cc 28 ce 9b ee  e6 44 3d ab ab 60 13 7c  |....(....D=..`.||
+000002f0  3d 37 2d d0 36 95 04 74  df 5a a5 ef 9b 68 7c 58  |=7-.6..t.Z...h|X|
+00000300  b4 22 e9 5d 15 aa 18 cc  fc 8d 35 f4 ad aa dc 0d  |.".]......5.....|
+00000310  86 b6 e5 ac e3 8f ea c7  63 c6 a5 1e 2a 7e e2 9b  |........c...*~..|
+00000320  05 33 81 04 d4 87 ad 15  2d 7f 91 fd ca 85 a8 cb  |.3......-.......|
+00000330  66 56 e3 7a 4a 90 8c dc  7d 8f d0 af 6e 5e 88 7b  |fV.zJ...}...n^.{|
+00000340  34 2e 2f a0 2e 16 03 03  00 04 0e 00 00 00        |4./...........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 20 df 4a b8 02 4f  |....%...!  .J..O|
-00000010  31 db 22 90 59 57 20 23  e1 72 8d 28 60 b3 f2 77  |1.".YW #.r.(`..w|
-00000020  db 3a ce 64 5a a5 63 94  be 09 14 03 03 00 01 01  |.:.dZ.c.........|
-00000030  16 03 03 00 28 de 72 f3  c3 b2 aa b4 9b b7 fe 35  |....(.r........5|
-00000040  3b 25 af 74 47 d3 49 39  07 d9 70 37 30 d0 b7 47  |;%.tG.I9..p70..G|
-00000050  bf ad 97 08 44 59 a7 3c  12 f2 4a 2d 7c           |....DY.<..J-||
+00000000  16 03 03 00 25 10 00 00  21 20 a5 ce 37 03 eb 08  |....%...! ..7...|
+00000010  67 8e 6b f8 37 b6 f8 cd  c6 62 59 c1 8f 46 22 0d  |g.k.7....bY..F".|
+00000020  d8 e1 85 2e 26 dc 40 d3  f0 60 14 03 03 00 01 01  |....&.@..`......|
+00000030  16 03 03 00 28 7d cf e0  cb 63 b3 22 fb b2 94 82  |....(}...c."....|
+00000040  a7 1e 8d 71 15 a8 ba 14  b6 4b 67 37 f9 78 c4 33  |...q.....Kg7.x.3|
+00000050  1b 7d 6c 8b 56 8f 85 d1  3e d3 9c 9f 95           |.}l.V...>....|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-00000010  00 00 00 16 18 e1 e8 d4  c0 d1 19 3a 50 10 85 fc  |...........:P...|
-00000020  fc 3e 27 54 e4 57 b6 e7  c4 25 d5 4e 10 ad 0f ff  |.>'T.W...%.N....|
-00000030  ad 45 8c 17 03 03 00 25  00 00 00 00 00 00 00 01  |.E.....%........|
-00000040  50 b8 af 5f a2 3e 0f f7  f0 81 1f 32 69 39 2f f2  |P.._.>.....2i9/.|
-00000050  47 28 80 fb d0 46 d4 b7  a2 ba e3 71 ea 15 03 03  |G(...F.....q....|
-00000060  00 1a 00 00 00 00 00 00  00 02 c4 64 7a 81 b3 3a  |...........dz..:|
-00000070  2c 71 35 ec f7 0c 52 36  20 2c eb fe              |,q5...R6 ,..|
+00000010  00 00 00 3e cd 20 97 7b  b3 2c 24 f2 cc ac 70 a4  |...>. .{.,$...p.|
+00000020  4f f5 db 05 51 52 a8 ff  6e 01 98 c3 ec c7 2c 97  |O...QR..n.....,.|
+00000030  6f f9 2c 17 03 03 00 25  00 00 00 00 00 00 00 01  |o.,....%........|
+00000040  67 b8 c3 d5 7e 02 18 6f  b8 db 10 5c 28 29 3d f6  |g...~..o...\()=.|
+00000050  d0 69 a1 4f e8 a4 ce 22  81 65 10 7e d1 15 03 03  |.i.O...".e.~....|
+00000060  00 1a 00 00 00 00 00 00  00 02 b0 df 28 f8 b8 f2  |............(...|
+00000070  32 43 c3 d0 01 55 8f 47  c1 52 8d e3              |2C...U.G.R..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM b/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM
index 89587e9..17136d4 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM
+++ b/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM
@@ -1,7 +1,7 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 73 01 00 00  6f 03 03 33 6d f4 4a 4b  |....s...o..3m.JK|
-00000010  48 35 ef 62 e9 bd 66 90  7e 73 62 bf 93 51 3d 90  |H5.b..f.~sb..Q=.|
-00000020  9e f1 17 ae bd 24 28 54  44 50 8e 00 00 04 c0 2f  |.....$(TDP...../|
+00000000  16 03 01 00 73 01 00 00  6f 03 03 c3 5c 1e ad 54  |....s...o...\..T|
+00000010  5b 03 af 49 42 dd cc 76  83 21 fe b4 4f 15 84 81  |[..IB..v.!..O...|
+00000020  e5 07 5c 7d 58 3d 37 5a  3a ae f8 00 00 04 c0 2f  |..\}X=7Z:....../|
 00000030  00 ff 01 00 00 42 00 0b  00 04 03 00 01 02 00 0a  |.....B..........|
 00000040  00 0a 00 08 00 1d 00 17  00 19 00 18 00 0d 00 20  |............... |
 00000050  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
@@ -52,28 +52,28 @@
 00000290  3b e9 fa e7 16 03 03 00  ac 0c 00 00 a8 03 00 1d  |;...............|
 000002a0  20 2f e5 7d a3 47 cd 62  43 15 28 da ac 5f bb 29  | /.}.G.bC.(.._.)|
 000002b0  07 30 ff f6 84 af c4 cf  c2 ed 90 99 5f 58 cb 3b  |.0.........._X.;|
-000002c0  74 05 01 00 80 61 aa 96  74 97 9f 2a 81 df 73 4d  |t....a..t..*..sM|
-000002d0  58 fb 8b 34 d9 51 02 1d  30 45 98 11 fa 20 cc 48  |X..4.Q..0E... .H|
-000002e0  18 8d 92 4a bc bf 34 c2  52 cc 7b 7d 93 32 f9 98  |...J..4.R.{}.2..|
-000002f0  eb d0 6d 58 4c 24 71 f1  78 cc ee 4d f8 26 26 d3  |..mXL$q.x..M.&&.|
-00000300  b0 1c 46 67 ff 75 fc b5  b3 75 31 f3 9d d6 51 07  |..Fg.u...u1...Q.|
-00000310  7a c1 2f 52 3f 88 23 f2  90 74 d0 77 6d 2b c7 31  |z./R?.#..t.wm+.1|
-00000320  3d 81 a8 b9 84 a6 8f 96  25 91 e8 31 3b e9 20 b8  |=.......%..1;. .|
-00000330  c4 11 68 da 58 0a ee 79  de fe 32 29 d6 24 b0 56  |..h.X..y..2).$.V|
-00000340  ab e8 b5 57 fc 16 03 03  00 04 0e 00 00 00        |...W..........|
+000002c0  74 06 01 00 80 d1 1b d9  90 1c 69 ef 70 d8 76 10  |t.........i.p.v.|
+000002d0  fe ea ce c5 42 ea e7 da  1a 45 83 11 75 51 e9 a4  |....B....E..uQ..|
+000002e0  fe 4c c6 b2 76 62 35 83  ae 45 08 80 07 76 0c d2  |.L..vb5..E...v..|
+000002f0  b6 a7 7d b4 ca 5d a0 70  88 2c ad 03 44 30 14 d7  |..}..].p.,..D0..|
+00000300  0b 9e 19 77 5f 2f 95 83  8a 5e 07 3e 7f 22 ca 86  |...w_/...^.>."..|
+00000310  b9 ae 0d eb b8 0e ce ec  5d 1f 72 95 cf a5 3f 2c  |........].r...?,|
+00000320  82 2f 17 f7 63 07 cd 01  d1 50 31 49 e4 d1 2c 75  |./..c....P1I..,u|
+00000330  1a 18 b9 76 51 33 f4 ff  74 37 cc bd 18 f9 3a 09  |...vQ3..t7....:.|
+00000340  25 38 56 a4 7b 16 03 03  00 04 0e 00 00 00        |%8V.{.........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 eb 0e 38 40 3f 32  |....%...! ..8@?2|
-00000010  a4 95 fb c4 de e5 82 9a  4b 46 37 de 29 e5 6b e6  |........KF7.).k.|
-00000020  44 bf f0 af 0c 62 19 bd  5c 0e 14 03 03 00 01 01  |D....b..\.......|
-00000030  16 03 03 00 28 67 ad 91  f6 8d 8a 39 f7 f2 a6 42  |....(g.....9...B|
-00000040  f2 8c 2f 1d b3 1d dd f1  88 65 7e 66 d2 d9 70 09  |../......e~f..p.|
-00000050  4e 12 90 0d 0b d5 a5 a6  20 bc 32 63 05           |N....... .2c.|
+00000000  16 03 03 00 25 10 00 00  21 20 71 94 86 30 e3 73  |....%...! q..0.s|
+00000010  65 46 cb e3 ea 30 0b 32  77 f5 52 28 6f 98 a2 ed  |eF...0.2w.R(o...|
+00000020  52 6e 14 eb 5f 89 33 98  13 4a 14 03 03 00 01 01  |Rn.._.3..J......|
+00000030  16 03 03 00 28 31 f7 9a  7d 84 21 17 7f c4 6e 9e  |....(1..}.!...n.|
+00000040  78 59 64 d1 d0 e7 74 fb  77 1b 7a b9 d5 e0 a6 c6  |xYd...t.w.z.....|
+00000050  ec a4 9f 64 38 dd 24 8c  d8 13 71 69 4f           |...d8.$...qiO|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-00000010  00 00 00 56 b1 b8 16 9a  27 c6 ee d4 7f b7 68 83  |...V....'.....h.|
-00000020  43 3b 04 92 ec cc c7 db  82 f8 7d 04 64 1d 55 cf  |C;........}.d.U.|
-00000030  02 69 ac 17 03 03 00 25  00 00 00 00 00 00 00 01  |.i.....%........|
-00000040  d6 69 51 5d 3b 00 93 c2  a6 19 97 7d bf a9 d9 96  |.iQ];......}....|
-00000050  43 1d ae 32 c3 52 1a f0  18 ba 10 4c e0 15 03 03  |C..2.R.....L....|
-00000060  00 1a 00 00 00 00 00 00  00 02 1e 8a 5e 37 c0 b1  |............^7..|
-00000070  0d 1e c9 6a 90 23 d6 4c  5c 47 5b bf              |...j.#.L\G[.|
+00000010  00 00 00 65 fc d6 aa c0  c7 6d 5e 94 bb cb 7c 19  |...e.....m^...|.|
+00000020  f4 4f 4b 0e d5 b1 66 cc  fb 7b d0 bb bc d3 de 55  |.OK...f..{.....U|
+00000030  79 d5 57 17 03 03 00 25  00 00 00 00 00 00 00 01  |y.W....%........|
+00000040  bf d0 4a cb ab f0 86 9a  ec 92 19 5e 51 6e 63 4e  |..J........^QncN|
+00000050  00 c6 1f e8 af 15 ec e7  29 45 f5 54 dd 15 03 03  |........)E.T....|
+00000060  00 1a 00 00 00 00 00 00  00 02 7e 20 a1 70 fa b9  |..........~ .p..|
+00000070  6f b3 3b b0 65 b5 96 15  b0 f6 db 8a              |o.;.e.......|
diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go
index 86812f0..97934cc 100644
--- a/src/crypto/tls/tls_test.go
+++ b/src/crypto/tls/tls_test.go
@@ -566,6 +566,58 @@
 	}
 }
 
+func TestWarningAlertFlood(t *testing.T) {
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	server := func() error {
+		sconn, err := ln.Accept()
+		if err != nil {
+			return fmt.Errorf("accept: %v", err)
+		}
+		defer sconn.Close()
+
+		serverConfig := testConfig.Clone()
+		srv := Server(sconn, serverConfig)
+		if err := srv.Handshake(); err != nil {
+			return fmt.Errorf("handshake: %v", err)
+		}
+		defer srv.Close()
+
+		_, err = ioutil.ReadAll(srv)
+		if err == nil {
+			return errors.New("unexpected lack of error from server")
+		}
+		const expected = "too many warn"
+		if str := err.Error(); !strings.Contains(str, expected) {
+			return fmt.Errorf("expected error containing %q, but saw: %s", expected, str)
+		}
+
+		return nil
+	}
+
+	errChan := make(chan error, 1)
+	go func() { errChan <- server() }()
+
+	clientConfig := testConfig.Clone()
+	conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+	if err := conn.Handshake(); err != nil {
+		t.Fatal(err)
+	}
+
+	for i := 0; i < maxWarnAlertCount+1; i++ {
+		conn.sendAlert(alertNoRenegotiation)
+	}
+
+	if err := <-errChan; err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestCloneFuncFields(t *testing.T) {
 	const expectedCount = 5
 	called := 0
diff --git a/src/crypto/x509/name_constraints_test.go b/src/crypto/x509/name_constraints_test.go
new file mode 100644
index 0000000..10cc348
--- /dev/null
+++ b/src/crypto/x509/name_constraints_test.go
@@ -0,0 +1,2002 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+	"bytes"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/pem"
+	"fmt"
+	"io/ioutil"
+	"math/big"
+	"net"
+	"net/url"
+	"os"
+	"os/exec"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+const (
+	// testNameConstraintsAgainstOpenSSL can be set to true to run tests
+	// against the system OpenSSL. This is disabled by default because Go
+	// cannot depend on having OpenSSL installed at testing time.
+	testNameConstraintsAgainstOpenSSL = false
+
+	// debugOpenSSLFailure can be set to true, when
+	// testNameConstraintsAgainstOpenSSL is also true, to cause
+	// intermediate files to be preserved for debugging.
+	debugOpenSSLFailure = false
+)
+
+type nameConstraintsTest struct {
+	roots         []constraintsSpec
+	intermediates [][]constraintsSpec
+	leaf          leafSpec
+	expectedError string
+	noOpenSSL     bool
+}
+
+type constraintsSpec struct {
+	ok   []string
+	bad  []string
+	ekus []string
+}
+
+type leafSpec struct {
+	sans []string
+	ekus []string
+}
+
+var nameConstraintsTests = []nameConstraintsTest{
+	// #0: dummy test for the certificate generation process itself.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #1: dummy test for the certificate generation process itself: single
+	// level of intermediate.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #2: dummy test for the certificate generation process itself: two
+	// levels of intermediates.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #3: matching DNS constraint in root
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #4: matching DNS constraint in intermediate.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #5: .example.com only matches subdomains.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+		expectedError: "\"example.com\" is not permitted",
+	},
+
+	// #6: .example.com matches subdomains.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.example.com"},
+		},
+	},
+
+	// #7: .example.com matches multiple levels of subdomains
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.bar.example.com"},
+		},
+	},
+
+	// #8: specifying a permitted list of names does not exclude other name
+	// types
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:10.1.1.1"},
+		},
+	},
+
+	// #9: specifying a permitted list of names does not exclude other name
+	// types
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:10.0.0.0/8"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #10: intermediates can try to permit other names, which isn't
+	// forbidden if the leaf doesn't mention them. I.e. name constraints
+	// apply to names, not constraints themselves.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:example.com", "dns:foo.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #11: intermediates cannot add permitted names that the root doesn't
+	// grant them.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:example.com", "dns:foo.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.com"},
+		},
+		expectedError: "\"foo.com\" is not permitted",
+	},
+
+	// #12: intermediates can further limit their scope if they wish.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:.bar.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.bar.example.com"},
+		},
+	},
+
+	// #13: intermediates can further limit their scope and that limitation
+	// is effective
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:.bar.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.notbar.example.com"},
+		},
+		expectedError: "\"foo.notbar.example.com\" is not permitted",
+	},
+
+	// #14: roots can exclude subtrees and that doesn't affect other names.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.com"},
+		},
+	},
+
+	// #15: roots exclusions are effective.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.example.com"},
+		},
+		expectedError: "\"foo.example.com\" is excluded",
+	},
+
+	// #16: intermediates can also exclude names and that doesn't affect
+	// other names.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					bad: []string{"dns:.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.com"},
+		},
+	},
+
+	// #17: intermediate exclusions are effective.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					bad: []string{"dns:.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.example.com"},
+		},
+		expectedError: "\"foo.example.com\" is excluded",
+	},
+
+	// #18: having an exclusion doesn't prohibit other types of names.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"dns:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.com", "ip:10.1.1.1"},
+		},
+	},
+
+	// #19: IP-based exclusions are permitted and don't affect unrelated IP
+	// addresses.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:10.0.0.0/8"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:192.168.1.1"},
+		},
+	},
+
+	// #20: IP-based exclusions are effective
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:10.0.0.0/8"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:10.0.0.1"},
+		},
+		expectedError: "\"10.0.0.1\" is excluded",
+	},
+
+	// #21: intermediates can further constrain IP ranges.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:0.0.0.0/1"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					bad: []string{"ip:11.0.0.0/8"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:11.0.0.1"},
+		},
+		expectedError: "\"11.0.0.1\" is excluded",
+	},
+
+	// #22: when multiple intermediates are present, chain building can
+	// avoid intermediates with incompatible constraints.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:.foo.com"},
+				},
+				constraintsSpec{
+					ok: []string{"dns:.example.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.example.com"},
+		},
+		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
+	},
+
+	// #23: (same as the previous test, but in the other order in ensure
+	// that we don't pass it by luck.)
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:.example.com"},
+				},
+				constraintsSpec{
+					ok: []string{"dns:.foo.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:foo.example.com"},
+		},
+		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
+	},
+
+	// #24: when multiple roots are valid, chain building can avoid roots
+	// with incompatible constraints.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+			constraintsSpec{
+				ok: []string{"dns:foo.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
+	},
+
+	// #25: (same as the previous test, but in the other order in ensure
+	// that we don't pass it by luck.)
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:foo.com"},
+			},
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
+	},
+
+	// #26: chain building can find a valid path even with multiple levels
+	// of alternative intermediates and alternative roots.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:foo.com"},
+			},
+			constraintsSpec{
+				ok: []string{"dns:example.com"},
+			},
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+				constraintsSpec{
+					ok: []string{"dns:foo.com"},
+				},
+			},
+			[]constraintsSpec{
+				constraintsSpec{},
+				constraintsSpec{
+					ok: []string{"dns:foo.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:bar.com"},
+		},
+		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
+	},
+
+	// #27: chain building doesn't get stuck when there is no valid path.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:foo.com"},
+			},
+			constraintsSpec{
+				ok: []string{"dns:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+				constraintsSpec{
+					ok: []string{"dns:foo.com"},
+				},
+			},
+			[]constraintsSpec{
+				constraintsSpec{
+					ok: []string{"dns:bar.com"},
+				},
+				constraintsSpec{
+					ok: []string{"dns:foo.com"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:bar.com"},
+		},
+		expectedError: "\"bar.com\" is not permitted",
+	},
+
+	// #28: unknown name types don't cause a problem without constraints.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"unknown:"},
+		},
+	},
+
+	// #29: unknown name types are allowed even in constrained chains.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:foo.com", "dns:.foo.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"unknown:"},
+		},
+	},
+
+	// #30: without SANs, a certificate is rejected in a constrained chain.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:foo.com", "dns:.foo.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{},
+		},
+		expectedError: "leaf doesn't have a SAN extension",
+		noOpenSSL:     true, // OpenSSL doesn't require SANs in this case.
+	},
+
+	// #31: IPv6 addresses work in constraints: roots can permit them as
+	// expected.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:abcd:1234::"},
+		},
+	},
+
+	// #32: IPv6 addresses work in constraints: root restrictions are
+	// effective.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:1234:abcd::"},
+		},
+		expectedError: "\"2000:1234:abcd::\" is not permitted",
+	},
+
+	// #33: An IPv6 permitted subtree doesn't affect DNS names.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:abcd::", "dns:foo.com"},
+		},
+	},
+
+	// #34: IPv6 exclusions don't affect unrelated addresses.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:1234::"},
+		},
+	},
+
+	// #35: IPv6 exclusions are effective.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:abcd::"},
+		},
+		expectedError: "\"2000:abcd::\" is excluded",
+	},
+
+	// #36: IPv6 constraints do not permit IPv4 addresses.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:2000:abcd::/32"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:10.0.0.1"},
+		},
+		expectedError: "\"10.0.0.1\" is not permitted",
+	},
+
+	// #37: IPv4 constraints do not permit IPv6 addresses.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"ip:10.0.0.0/8"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:2000:abcd::"},
+		},
+		expectedError: "\"2000:abcd::\" is not permitted",
+	},
+
+	// #38: an exclusion of an unknown type doesn't affect other names.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"unknown:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #39: a permitted subtree of an unknown type doesn't affect other
+	// name types.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"unknown:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #40: exact email constraints work
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:foo@example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+	},
+
+	// #41: exact email constraints are effective
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:foo@example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:bar@example.com"},
+		},
+		expectedError: "\"bar@example.com\" is not permitted",
+	},
+
+	// #42: email canonicalisation works.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:foo@example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:\"\\f\\o\\o\"@example.com"},
+		},
+		noOpenSSL: true, // OpenSSL doesn't canonicalise email addresses before matching
+	},
+
+	// #43: limiting email addresses to a host works.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+	},
+
+	// #44: a leading dot matches hosts one level deep
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@sub.example.com"},
+		},
+	},
+
+	// #45: a leading dot does not match the host itself
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+		expectedError: "\"foo@example.com\" is not permitted",
+	},
+
+	// #46: a leading dot also matches two (or more) levels deep.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:.example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@sub.sub.example.com"},
+		},
+	},
+
+	// #47: the local part of an email is case-sensitive
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:foo@example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:Foo@example.com"},
+		},
+		expectedError: "\"Foo@example.com\" is not permitted",
+	},
+
+	// #48: the domain part of an email is not case-sensitive
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:foo@EXAMPLE.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+	},
+
+	// #49: the domain part of a DNS constraint is also not case-sensitive.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:EXAMPLE.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #50: URI constraints only cover the host part of the URI
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{
+				"uri:http://example.com/bar",
+				"uri:http://example.com:8080/",
+				"uri:https://example.com/wibble#bar",
+			},
+		},
+	},
+
+	// #51: URIs with IPs are rejected
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://1.2.3.4/"},
+		},
+		expectedError: "URI with IP",
+	},
+
+	// #52: URIs with IPs and ports are rejected
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://1.2.3.4:43/"},
+		},
+		expectedError: "URI with IP",
+	},
+
+	// #53: URIs with IPv6 addresses are also rejected
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://[2006:abcd::1]/"},
+		},
+		expectedError: "URI with IP",
+	},
+
+	// #54: URIs with IPv6 addresses with ports are also rejected
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://[2006:abcd::1]:16/"},
+		},
+		expectedError: "URI with IP",
+	},
+
+	// #55: URI constraints are effective
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://bar.com/"},
+		},
+		expectedError: "\"http://bar.com/\" is not permitted",
+	},
+
+	// #56: URI constraints are effective
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"uri:foo.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://foo.com/"},
+		},
+		expectedError: "\"http://foo.com/\" is excluded",
+	},
+
+	// #57: URI constraints can allow subdomains
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:.foo.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:http://www.foo.com/"},
+		},
+	},
+
+	// #58: excluding an IPv4-mapped-IPv6 address doesn't affect the IPv4
+	// version of that address.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"ip:::ffff:1.2.3.4/128"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:1.2.3.4"},
+		},
+	},
+
+	// #59: a URI constraint isn't matched by a URN.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:example.com"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:urn:example"},
+		},
+		expectedError: "URI with empty host",
+	},
+
+	// #60: excluding all IPv6 addresses doesn't exclude all IPv4 addresses
+	// too, even though IPv4 is mapped into the IPv6 range.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok:  []string{"ip:1.2.3.0/24"},
+				bad: []string{"ip:::0/0"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"ip:1.2.3.4"},
+		},
+	},
+
+	// #61: omitting extended key usage in a CA certificate implies that
+	// any usage is ok.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth", "other"},
+		},
+	},
+
+	// #62: The “any” EKU also means that any usage is ok.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"any"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth", "other"},
+		},
+	},
+
+	// #63: A specified key usage in an intermediate forbids other usages
+	// in the leaf.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"email"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth"},
+		},
+		expectedError: "EKU not permitted",
+	},
+
+	// #64: A specified key usage in an intermediate forbids other usages
+	// in the leaf, even if we don't recognise them.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"email"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"other"},
+		},
+		expectedError: "EKU not permitted",
+	},
+
+	// #65: trying to add extra permitted key usages in an intermediate
+	// (after a limitation in the root) is acceptable so long as the leaf
+	// certificate doesn't use them.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ekus: []string{"serverAuth"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"serverAuth", "email"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth"},
+		},
+	},
+
+	// #66: EKUs in roots are ignored.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ekus: []string{"serverAuth"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"serverAuth", "email"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth", "email"},
+		},
+	},
+
+	// #67: in order to support COMODO chains, SGC key usages permit
+	// serverAuth and clientAuth.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"netscapeSGC"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth", "clientAuth"},
+		},
+	},
+
+	// #68: in order to support COMODO chains, SGC key usages permit
+	// serverAuth and clientAuth.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{
+					ekus: []string{"msSGC"},
+				},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+			ekus: []string{"serverAuth", "clientAuth"},
+		},
+	},
+
+	// #69: an empty DNS constraint should allow anything.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"dns:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+	},
+
+	// #70: an empty DNS constraint should also reject everything.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"dns:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"dns:example.com"},
+		},
+		expectedError: "\"example.com\" is excluded",
+	},
+
+	// #71: an empty email constraint should allow anything
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"email:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+	},
+
+	// #72: an empty email constraint should also reject everything.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"email:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"email:foo@example.com"},
+		},
+		expectedError: "\"foo@example.com\" is excluded",
+	},
+
+	// #73: an empty URI constraint should allow anything
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				ok: []string{"uri:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:https://example.com/test"},
+		},
+	},
+
+	// #74: an empty URI constraint should also reject everything.
+	nameConstraintsTest{
+		roots: []constraintsSpec{
+			constraintsSpec{
+				bad: []string{"uri:"},
+			},
+		},
+		intermediates: [][]constraintsSpec{
+			[]constraintsSpec{
+				constraintsSpec{},
+			},
+		},
+		leaf: leafSpec{
+			sans: []string{"uri:https://example.com/test"},
+		},
+		expectedError: "\"https://example.com/test\" is excluded",
+	},
+}
+
+func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
+	var serialBytes [16]byte
+	rand.Read(serialBytes[:])
+
+	template := &Certificate{
+		SerialNumber: new(big.Int).SetBytes(serialBytes[:]),
+		Subject: pkix.Name{
+			CommonName: name,
+		},
+		NotBefore:             time.Unix(1000, 0),
+		NotAfter:              time.Unix(2000, 0),
+		KeyUsage:              KeyUsageCertSign,
+		BasicConstraintsValid: true,
+		IsCA: true,
+	}
+
+	if err := addConstraintsToTemplate(constraints, template); err != nil {
+		return nil, err
+	}
+
+	if parent == nil {
+		parent = template
+	}
+	derBytes, err := CreateCertificate(rand.Reader, template, parent, &key.PublicKey, parentKey)
+	if err != nil {
+		return nil, err
+	}
+
+	caCert, err := ParseCertificate(derBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	return caCert, nil
+}
+
+func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
+	var serialBytes [16]byte
+	rand.Read(serialBytes[:])
+
+	template := &Certificate{
+		SerialNumber: new(big.Int).SetBytes(serialBytes[:]),
+		Subject: pkix.Name{
+			// Don't set a CommonName because OpenSSL (at least) will try to
+			// match it against name constraints.
+			OrganizationalUnit: []string{"Leaf"},
+		},
+		NotBefore:             time.Unix(1000, 0),
+		NotAfter:              time.Unix(2000, 0),
+		KeyUsage:              KeyUsageDigitalSignature,
+		BasicConstraintsValid: true,
+		IsCA: false,
+	}
+
+	for _, name := range leaf.sans {
+		switch {
+		case strings.HasPrefix(name, "dns:"):
+			template.DNSNames = append(template.DNSNames, name[4:])
+
+		case strings.HasPrefix(name, "ip:"):
+			ip := net.ParseIP(name[3:])
+			if ip == nil {
+				return nil, fmt.Errorf("cannot parse IP %q", name[3:])
+			}
+			template.IPAddresses = append(template.IPAddresses, ip)
+
+		case strings.HasPrefix(name, "email:"):
+			template.EmailAddresses = append(template.EmailAddresses, name[6:])
+
+		case strings.HasPrefix(name, "uri:"):
+			uri, err := url.Parse(name[4:])
+			if err != nil {
+				return nil, fmt.Errorf("cannot parse URI %q: %s", name[4:], err)
+			}
+			template.URIs = append(template.URIs, uri)
+
+		case strings.HasPrefix(name, "unknown:"):
+			// This is a special case for testing unknown
+			// name types. A custom SAN extension is
+			// injected into the certificate.
+			if len(leaf.sans) != 1 {
+				panic("when using unknown name types, it must be the sole name")
+			}
+
+			template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{
+				Id: []int{2, 5, 29, 17},
+				Value: []byte{
+					0x30, // SEQUENCE
+					3,    // three bytes
+					9,    // undefined GeneralName type 9
+					1,
+					1,
+				},
+			})
+
+		default:
+			return nil, fmt.Errorf("unknown name type %q", name)
+		}
+	}
+
+	var err error
+	if template.ExtKeyUsage, template.UnknownExtKeyUsage, err = parseEKUs(leaf.ekus); err != nil {
+		return nil, err
+	}
+
+	if parent == nil {
+		parent = template
+	}
+
+	derBytes, err := CreateCertificate(rand.Reader, template, parent, &key.PublicKey, parentKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return ParseCertificate(derBytes)
+}
+
+func customConstraintsExtension(typeNum int, constraint []byte, isExcluded bool) pkix.Extension {
+	appendConstraint := func(contents []byte, tag uint8) []byte {
+		contents = append(contents, tag|32 /* constructed */ |0x80 /* context-specific */)
+		contents = append(contents, byte(4+len(constraint)) /* length */)
+		contents = append(contents, 0x30 /* SEQUENCE */)
+		contents = append(contents, byte(2+len(constraint)) /* length */)
+		contents = append(contents, byte(typeNum) /* GeneralName type */)
+		contents = append(contents, byte(len(constraint)))
+		return append(contents, constraint...)
+	}
+
+	var contents []byte
+	if !isExcluded {
+		contents = appendConstraint(contents, 0 /* tag 0 for permitted */)
+	} else {
+		contents = appendConstraint(contents, 1 /* tag 1 for excluded */)
+	}
+
+	var value []byte
+	value = append(value, 0x30 /* SEQUENCE */)
+	value = append(value, byte(len(contents)))
+	value = append(value, contents...)
+
+	return pkix.Extension{
+		Id:    []int{2, 5, 29, 30},
+		Value: value,
+	}
+}
+
+func addConstraintsToTemplate(constraints constraintsSpec, template *Certificate) error {
+	parse := func(constraints []string) (dnsNames []string, ips []*net.IPNet, emailAddrs []string, uriDomains []string, err error) {
+		for _, constraint := range constraints {
+			switch {
+			case strings.HasPrefix(constraint, "dns:"):
+				dnsNames = append(dnsNames, constraint[4:])
+
+			case strings.HasPrefix(constraint, "ip:"):
+				_, ipNet, err := net.ParseCIDR(constraint[3:])
+				if err != nil {
+					return nil, nil, nil, nil, err
+				}
+				ips = append(ips, ipNet)
+
+			case strings.HasPrefix(constraint, "email:"):
+				emailAddrs = append(emailAddrs, constraint[6:])
+
+			case strings.HasPrefix(constraint, "uri:"):
+				uriDomains = append(uriDomains, constraint[4:])
+
+			default:
+				return nil, nil, nil, nil, fmt.Errorf("unknown constraint %q", constraint)
+			}
+		}
+
+		return dnsNames, ips, emailAddrs, uriDomains, err
+	}
+
+	handleSpecialConstraint := func(constraint string, isExcluded bool) bool {
+		switch {
+		case constraint == "unknown:":
+			template.ExtraExtensions = append(template.ExtraExtensions, customConstraintsExtension(9 /* undefined GeneralName type */, []byte{1}, isExcluded))
+
+		default:
+			return false
+		}
+
+		return true
+	}
+
+	if len(constraints.ok) == 1 && len(constraints.bad) == 0 {
+		if handleSpecialConstraint(constraints.ok[0], false) {
+			return nil
+		}
+	}
+
+	if len(constraints.bad) == 1 && len(constraints.ok) == 0 {
+		if handleSpecialConstraint(constraints.bad[0], true) {
+			return nil
+		}
+	}
+
+	var err error
+	template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains, err = parse(constraints.ok)
+	if err != nil {
+		return err
+	}
+
+	template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains, err = parse(constraints.bad)
+	if err != nil {
+		return err
+	}
+
+	if template.ExtKeyUsage, template.UnknownExtKeyUsage, err = parseEKUs(constraints.ekus); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func parseEKUs(ekuStrs []string) (ekus []ExtKeyUsage, unknowns []asn1.ObjectIdentifier, err error) {
+	for _, s := range ekuStrs {
+		switch s {
+		case "serverAuth":
+			ekus = append(ekus, ExtKeyUsageServerAuth)
+		case "clientAuth":
+			ekus = append(ekus, ExtKeyUsageClientAuth)
+		case "email":
+			ekus = append(ekus, ExtKeyUsageEmailProtection)
+		case "netscapeSGC":
+			ekus = append(ekus, ExtKeyUsageNetscapeServerGatedCrypto)
+		case "msSGC":
+			ekus = append(ekus, ExtKeyUsageMicrosoftServerGatedCrypto)
+		case "any":
+			ekus = append(ekus, ExtKeyUsageAny)
+		case "other":
+			unknowns = append(unknowns, asn1.ObjectIdentifier{2, 4, 1, 2, 3})
+		default:
+			return nil, nil, fmt.Errorf("unknown EKU %q", s)
+		}
+	}
+
+	return
+}
+
+func TestConstraintCases(t *testing.T) {
+	privateKeys := sync.Pool{
+		New: func() interface{} {
+			priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+			if err != nil {
+				panic(err)
+			}
+			return priv
+		},
+	}
+
+	for i, test := range nameConstraintsTests {
+		rootPool := NewCertPool()
+		rootKey := privateKeys.Get().(*ecdsa.PrivateKey)
+		rootName := "Root " + strconv.Itoa(i)
+
+		// keys keeps track of all the private keys used in a given
+		// test and puts them back in the privateKeys pool at the end.
+		keys := []*ecdsa.PrivateKey{rootKey}
+
+		// At each level (root, intermediate(s), leaf), parent points to
+		// an example parent certificate and parentKey the key for the
+		// parent level. Since all certificates at a given level have
+		// the same name and public key, any parent certificate is
+		// sufficient to get the correct issuer name and authority
+		// key ID.
+		var parent *Certificate
+		parentKey := rootKey
+
+		for _, root := range test.roots {
+			rootCert, err := makeConstraintsCACert(root, rootName, rootKey, nil, rootKey)
+			if err != nil {
+				t.Fatalf("#%d: failed to create root: %s", i, err)
+			}
+
+			parent = rootCert
+			rootPool.AddCert(rootCert)
+		}
+
+		intermediatePool := NewCertPool()
+
+		for level, intermediates := range test.intermediates {
+			levelKey := privateKeys.Get().(*ecdsa.PrivateKey)
+			keys = append(keys, levelKey)
+			levelName := "Intermediate level " + strconv.Itoa(level)
+			var last *Certificate
+
+			for _, intermediate := range intermediates {
+				caCert, err := makeConstraintsCACert(intermediate, levelName, levelKey, parent, parentKey)
+				if err != nil {
+					t.Fatalf("#%d: failed to create %q: %s", i, levelName, err)
+				}
+
+				last = caCert
+				intermediatePool.AddCert(caCert)
+			}
+
+			parent = last
+			parentKey = levelKey
+		}
+
+		leafKey := privateKeys.Get().(*ecdsa.PrivateKey)
+		keys = append(keys, leafKey)
+
+		leafCert, err := makeConstraintsLeafCert(test.leaf, leafKey, parent, parentKey)
+		if err != nil {
+			t.Fatalf("#%d: cannot create leaf: %s", i, err)
+		}
+
+		if !test.noOpenSSL && testNameConstraintsAgainstOpenSSL {
+			output, err := testChainAgainstOpenSSL(leafCert, intermediatePool, rootPool)
+			if err == nil && len(test.expectedError) > 0 {
+				t.Errorf("#%d: unexpectedly succeeded against OpenSSL", i)
+				if debugOpenSSLFailure {
+					return
+				}
+			}
+
+			if err != nil {
+				if _, ok := err.(*exec.ExitError); !ok {
+					t.Errorf("#%d: OpenSSL failed to run: %s", i, err)
+				} else if len(test.expectedError) == 0 {
+					t.Errorf("#%d: OpenSSL unexpectedly failed: %q", i, output)
+					if debugOpenSSLFailure {
+						return
+					}
+				}
+			}
+		}
+
+		verifyOpts := VerifyOptions{
+			Roots:         rootPool,
+			Intermediates: intermediatePool,
+			CurrentTime:   time.Unix(1500, 0),
+		}
+		_, err = leafCert.Verify(verifyOpts)
+
+		logInfo := true
+		if len(test.expectedError) == 0 {
+			if err != nil {
+				t.Errorf("#%d: unexpected failure: %s", i, err)
+			} else {
+				logInfo = false
+			}
+		} else {
+			if err == nil {
+				t.Errorf("#%d: unexpected success", i)
+			} else if !strings.Contains(err.Error(), test.expectedError) {
+				t.Errorf("#%d: expected error containing %q, but got: %s", i, test.expectedError, err)
+			} else {
+				logInfo = false
+			}
+		}
+
+		if logInfo {
+			certAsPEM := func(cert *Certificate) string {
+				var buf bytes.Buffer
+				pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
+				return string(buf.Bytes())
+			}
+			t.Errorf("#%d: root:\n%s", i, certAsPEM(rootPool.certs[0]))
+			t.Errorf("#%d: leaf:\n%s", i, certAsPEM(leafCert))
+		}
+
+		for _, key := range keys {
+			privateKeys.Put(key)
+		}
+		keys = keys[:0]
+	}
+}
+
+func writePEMsToTempFile(certs []*Certificate) *os.File {
+	file, err := ioutil.TempFile("", "name_constraints_test")
+	if err != nil {
+		panic("cannot create tempfile")
+	}
+
+	pemBlock := &pem.Block{Type: "CERTIFICATE"}
+	for _, cert := range certs {
+		pemBlock.Bytes = cert.Raw
+		pem.Encode(file, pemBlock)
+	}
+
+	return file
+}
+
+func testChainAgainstOpenSSL(leaf *Certificate, intermediates, roots *CertPool) (string, error) {
+	args := []string{"verify", "-no_check_time"}
+
+	rootsFile := writePEMsToTempFile(roots.certs)
+	if debugOpenSSLFailure {
+		println("roots file:", rootsFile.Name())
+	} else {
+		defer os.Remove(rootsFile.Name())
+	}
+	args = append(args, "-CAfile", rootsFile.Name())
+
+	if len(intermediates.certs) > 0 {
+		intermediatesFile := writePEMsToTempFile(intermediates.certs)
+		if debugOpenSSLFailure {
+			println("intermediates file:", intermediatesFile.Name())
+		} else {
+			defer os.Remove(intermediatesFile.Name())
+		}
+		args = append(args, "-untrusted", intermediatesFile.Name())
+	}
+
+	leafFile := writePEMsToTempFile([]*Certificate{leaf})
+	if debugOpenSSLFailure {
+		println("leaf file:", leafFile.Name())
+	} else {
+		defer os.Remove(leafFile.Name())
+	}
+	args = append(args, leafFile.Name())
+
+	var output bytes.Buffer
+	cmd := exec.Command("openssl", args...)
+	cmd.Stdout = &output
+	cmd.Stderr = &output
+
+	err := cmd.Run()
+	return string(output.Bytes()), err
+}
+
+var rfc2821Tests = []struct {
+	in                string
+	localPart, domain string
+}{
+	{"foo@example.com", "foo", "example.com"},
+	{"@example.com", "", ""},
+	{"\"@example.com", "", ""},
+	{"\"\"@example.com", "", "example.com"},
+	{"\"a\"@example.com", "a", "example.com"},
+	{"\"\\a\"@example.com", "a", "example.com"},
+	{"a\"@example.com", "", ""},
+	{"foo..bar@example.com", "", ""},
+	{".foo.bar@example.com", "", ""},
+	{"foo.bar.@example.com", "", ""},
+	{"|{}?'@example.com", "|{}?'", "example.com"},
+
+	// Examples from RFC 3696
+	{"Abc\\@def@example.com", "Abc@def", "example.com"},
+	{"Fred\\ Bloggs@example.com", "Fred Bloggs", "example.com"},
+	{"Joe.\\\\Blow@example.com", "Joe.\\Blow", "example.com"},
+	{"\"Abc@def\"@example.com", "Abc@def", "example.com"},
+	{"\"Fred Bloggs\"@example.com", "Fred Bloggs", "example.com"},
+	{"customer/department=shipping@example.com", "customer/department=shipping", "example.com"},
+	{"$A12345@example.com", "$A12345", "example.com"},
+	{"!def!xyz%abc@example.com", "!def!xyz%abc", "example.com"},
+	{"_somename@example.com", "_somename", "example.com"},
+}
+
+func TestRFC2821Parsing(t *testing.T) {
+	for i, test := range rfc2821Tests {
+		mailbox, ok := parseRFC2821Mailbox(test.in)
+		expectedFailure := len(test.localPart) == 0 && len(test.domain) == 0
+
+		if ok && expectedFailure {
+			t.Errorf("#%d: %q unexpectedly parsed as (%q, %q)", i, test.in, mailbox.local, mailbox.domain)
+			continue
+		}
+
+		if !ok && !expectedFailure {
+			t.Errorf("#%d: unexpected failure for %q", i, test.in)
+			continue
+		}
+
+		if !ok {
+			continue
+		}
+
+		if mailbox.local != test.localPart || mailbox.domain != test.domain {
+			t.Errorf("#%d: %q parsed as (%q, %q), but wanted (%q, %q)", i, test.in, mailbox.local, mailbox.domain, test.localPart, test.domain)
+		}
+	}
+}
+
+func TestBadNamesInConstraints(t *testing.T) {
+	constraintParseError := func(err error) bool {
+		str := err.Error()
+		return strings.Contains(str, "failed to parse ") && strings.Contains(str, "constraint")
+	}
+
+	encodingError := func(err error) bool {
+		return strings.Contains(err.Error(), "cannot be encoded as an IA5String")
+	}
+
+	// Bad names in constraints should not parse.
+	badNames := []struct {
+		name    string
+		matcher func(error) bool
+	}{
+		{"dns:foo.com.", constraintParseError},
+		{"email:abc@foo.com.", constraintParseError},
+		{"email:foo.com.", constraintParseError},
+		{"uri:example.com.", constraintParseError},
+		{"uri:1.2.3.4", constraintParseError},
+		{"uri:ffff::1", constraintParseError},
+		{"dns:not–hyphen.com", encodingError},
+		{"email:foo@not–hyphen.com", encodingError},
+		{"uri:not–hyphen.com", encodingError},
+	}
+
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+
+	for _, test := range badNames {
+		_, err := makeConstraintsCACert(constraintsSpec{
+			ok: []string{test.name},
+		}, "TestAbsoluteNamesInConstraints", priv, nil, priv)
+
+		if err == nil {
+			t.Errorf("bad name %q unexpectedly accepted in name constraint", test.name)
+			continue
+		} else {
+			if !test.matcher(err) {
+				t.Errorf("bad name %q triggered unrecognised error: %s", test.name, err)
+			}
+		}
+	}
+}
+
+func TestBadNamesInSANs(t *testing.T) {
+	// Bad names in SANs should not parse.
+	badNames := []string{
+		"dns:foo.com.",
+		"email:abc@foo.com.",
+		"email:foo.com.",
+		"uri:https://example.com./dsf",
+	}
+
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+
+	for _, badName := range badNames {
+		_, err := makeConstraintsLeafCert(leafSpec{sans: []string{badName}}, priv, nil, priv)
+
+		if err == nil {
+			t.Errorf("bad name %q unexpectedly accepted in SAN", badName)
+			continue
+		}
+
+		if err != nil {
+			if str := err.Error(); !strings.Contains(str, "cannot parse ") {
+				t.Errorf("bad name %q triggered unrecognised error: %s", badName, str)
+			}
+		}
+	}
+}
diff --git a/src/crypto/x509/pkcs1.go b/src/crypto/x509/pkcs1.go
index 73bc762..82502cf 100644
--- a/src/crypto/x509/pkcs1.go
+++ b/src/crypto/x509/pkcs1.go
@@ -119,3 +119,36 @@
 	b, _ := asn1.Marshal(priv)
 	return b
 }
+
+// ParsePKCS1PublicKey parses a PKCS#1 public key in ASN.1 DER form.
+func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) {
+	var pub pkcs1PublicKey
+	rest, err := asn1.Unmarshal(der, &pub)
+	if err != nil {
+		return nil, err
+	}
+	if len(rest) > 0 {
+		return nil, asn1.SyntaxError{Msg: "trailing data"}
+	}
+
+	if pub.N.Sign() <= 0 || pub.E <= 0 {
+		return nil, errors.New("x509: public key contains zero or negative value")
+	}
+	if pub.E > 1<<31-1 {
+		return nil, errors.New("x509: public key contains large public exponent")
+	}
+
+	return &rsa.PublicKey{
+		E: pub.E,
+		N: pub.N,
+	}, nil
+}
+
+// MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form.
+func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte {
+	derBytes, _ := asn1.Marshal(pkcs1PublicKey{
+		N: key.N,
+		E: key.E,
+	})
+	return derBytes
+}
diff --git a/src/crypto/x509/pkcs8.go b/src/crypto/x509/pkcs8.go
index b304a3f..eb051b6 100644
--- a/src/crypto/x509/pkcs8.go
+++ b/src/crypto/x509/pkcs8.go
@@ -5,6 +5,8 @@
 package x509
 
 import (
+	"crypto/ecdsa"
+	"crypto/rsa"
 	"crypto/x509/pkix"
 	"encoding/asn1"
 	"errors"
@@ -52,3 +54,48 @@
 		return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
 	}
 }
+
+// MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form.
+// The following key types are supported: *rsa.PrivateKey, *ecdsa.PublicKey.
+// Unsupported key types result in an error.
+//
+// See RFC 5208.
+func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
+	var privKey pkcs8
+
+	switch k := key.(type) {
+	case *rsa.PrivateKey:
+		privKey.Algo = pkix.AlgorithmIdentifier{
+			Algorithm:  oidPublicKeyRSA,
+			Parameters: asn1.NullRawValue,
+		}
+		privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
+
+	case *ecdsa.PrivateKey:
+		oid, ok := oidFromNamedCurve(k.Curve)
+		if !ok {
+			return nil, errors.New("x509: unknown curve while marshalling to PKCS#8")
+		}
+
+		oidBytes, err := asn1.Marshal(oid)
+		if err != nil {
+			return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
+		}
+
+		privKey.Algo = pkix.AlgorithmIdentifier{
+			Algorithm: oidPublicKeyECDSA,
+			Parameters: asn1.RawValue{
+				FullBytes: oidBytes,
+			},
+		}
+
+		if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
+			return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
+		}
+
+	default:
+		return nil, fmt.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key)
+	}
+
+	return asn1.Marshal(privKey)
+}
diff --git a/src/crypto/x509/pkcs8_test.go b/src/crypto/x509/pkcs8_test.go
index 4114efd..c8f11e6 100644
--- a/src/crypto/x509/pkcs8_test.go
+++ b/src/crypto/x509/pkcs8_test.go
@@ -5,24 +5,105 @@
 package x509
 
 import (
+	"bytes"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
 	"encoding/hex"
+	"reflect"
 	"testing"
 )
 
+// Generated using:
+//   openssl genrsa 1024 | openssl pkcs8 -topk8 -nocrypt
 var pkcs8RSAPrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031`
 
 // Generated using:
+//   openssl ecparam -genkey -name secp224r1 | openssl pkcs8 -topk8 -nocrypt
+var pkcs8P224PrivateKeyHex = `3078020100301006072a8648ce3d020106052b810400210461305f020101041cca3d72b3e88fed2684576dad9b80a9180363a5424986900e3abcab3fa13c033a0004f8f2a6372872a4e61263ed893afb919576a4cacfecd6c081a2cbc76873cf4ba8530703c6042b3a00e2205087e87d2435d2e339e25702fae1`
+
+// Generated using:
+//   openssl ecparam -genkey -name secp256r1 | openssl pkcs8 -topk8 -nocrypt
+var pkcs8P256PrivateKeyHex = `308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420dad6b2f49ca774c36d8ae9517e935226f667c929498f0343d2424d0b9b591b43a14403420004b9c9b90095476afe7b860d8bd43568cab7bcb2eed7b8bf2fa0ce1762dd20b04193f859d2d782b1e4cbfd48492f1f533113a6804903f292258513837f07fda735`
+
+// Generated using:
+//   openssl ecparam -genkey -name secp384r1 | openssl pkcs8 -topk8 -nocrypt
+var pkcs8P384PrivateKeyHex = `3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104309bf832f6aaaeacb78ce47ffb15e6fd0fd48683ae79df6eca39bfb8e33829ac94aa29d08911568684c2264a08a4ceb679a164036200049070ad4ed993c7770d700e9f6dc2baa83f63dd165b5507f98e8ff29b5d2e78ccbe05c8ddc955dbf0f7497e8222cfa49314fe4e269459f8e880147f70d785e530f2939e4bf9f838325bb1a80ad4cf59272ae0e5efe9a9dc33d874492596304bd3`
+
+// Generated using:
 //   openssl ecparam -genkey -name secp521r1 | openssl pkcs8 -topk8 -nocrypt
-var pkcs8ECPrivateKeyHex = `3081ed020100301006072a8648ce3d020106052b810400230481d53081d20201010441850d81618c5da1aec74c2eed608ba816038506975e6427237c2def150c96a3b13efbfa1f89f1be15cdf4d0ac26422e680e65a0ddd4ad3541ad76165fbf54d6e34ba18189038186000400da97bcedba1eb6d30aeb93c9f9a1454598fa47278df27d6f60ea73eb672d8dc528a9b67885b5b5dcef93c9824f7449ab512ee6a27e76142f56b94b474cfd697e810046c8ca70419365245c1d7d44d0db82c334073835d002232714548abbae6e5700f5ef315ee08b929d8581383dcf2d1c98c2f8a9fccbf79c9579f7b2fd8a90115ac2`
+//
+// Note that OpenSSL will truncate the private key if it can (i.e. it emits it
+// like an integer, even though it's an OCTET STRING field). Thus if you
+// regenerate this you may, randomly, find that it's a byte shorter than
+// expected and the Go test will fail to recreate it exactly.
+var pkcs8P521PrivateKeyHex = `3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044200cfe0b87113a205cf291bb9a8cd1a74ac6c7b2ebb8199aaa9a5010d8b8012276fa3c22ac913369fa61beec2a3b8b4516bc049bde4fb3b745ac11b56ab23ac52e361a1818903818600040138f75acdd03fbafa4f047a8e4b272ba9d555c667962b76f6f232911a5786a0964e5edea6bd21a6f8725720958de049c6e3e6661c1c91b227cebee916c0319ed6ca003db0a3206d372229baf9dd25d868bf81140a518114803ce40c1855074d68c4e9dab9e65efba7064c703b400f1767f217dac82715ac1f6d88c74baf47a7971de4ea`
 
 func TestPKCS8(t *testing.T) {
-	derBytes, _ := hex.DecodeString(pkcs8RSAPrivateKeyHex)
-	if _, err := ParsePKCS8PrivateKey(derBytes); err != nil {
-		t.Errorf("failed to decode PKCS8 with RSA private key: %s", err)
+	tests := []struct {
+		name    string
+		keyHex  string
+		keyType reflect.Type
+		curve   elliptic.Curve
+	}{
+		{
+			name:    "RSA private key",
+			keyHex:  pkcs8RSAPrivateKeyHex,
+			keyType: reflect.TypeOf(&rsa.PrivateKey{}),
+		},
+		{
+			name:    "P-224 private key",
+			keyHex:  pkcs8P224PrivateKeyHex,
+			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
+			curve:   elliptic.P224(),
+		},
+		{
+			name:    "P-256 private key",
+			keyHex:  pkcs8P256PrivateKeyHex,
+			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
+			curve:   elliptic.P256(),
+		},
+		{
+			name:    "P-384 private key",
+			keyHex:  pkcs8P384PrivateKeyHex,
+			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
+			curve:   elliptic.P384(),
+		},
+		{
+			name:    "P-521 private key",
+			keyHex:  pkcs8P521PrivateKeyHex,
+			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
+			curve:   elliptic.P521(),
+		},
 	}
 
-	derBytes, _ = hex.DecodeString(pkcs8ECPrivateKeyHex)
-	if _, err := ParsePKCS8PrivateKey(derBytes); err != nil {
-		t.Errorf("failed to decode PKCS8 with EC private key: %s", err)
+	for _, test := range tests {
+		derBytes, err := hex.DecodeString(test.keyHex)
+		if err != nil {
+			t.Errorf("%s: failed to decode hex: %s", test.name, err)
+			continue
+		}
+		privKey, err := ParsePKCS8PrivateKey(derBytes)
+		if err != nil {
+			t.Errorf("%s: failed to decode PKCS#8: %s", test.name, err)
+			continue
+		}
+		if reflect.TypeOf(privKey) != test.keyType {
+			t.Errorf("%s: decoded PKCS#8 returned unexpected key type: %T", test.name, privKey)
+			continue
+		}
+		if ecKey, isEC := privKey.(*ecdsa.PrivateKey); isEC && ecKey.Curve != test.curve {
+			t.Errorf("%s: decoded PKCS#8 returned unexpected curve %#v", test.name, ecKey.Curve)
+			continue
+		}
+		reserialised, err := MarshalPKCS8PrivateKey(privKey)
+		if err != nil {
+			t.Errorf("%s: failed to marshal into PKCS#8: %s", test.name, err)
+			continue
+		}
+		if !bytes.Equal(derBytes, reserialised) {
+			t.Errorf("%s: marshalled PKCS#8 didn't match original: got %x, want %x", test.name, reserialised, derBytes)
+			continue
+		}
 	}
 }
diff --git a/src/crypto/x509/pkix/pkix.go b/src/crypto/x509/pkix/pkix.go
index 39fd78d..7b32220 100644
--- a/src/crypto/x509/pkix/pkix.go
+++ b/src/crypto/x509/pkix/pkix.go
@@ -8,6 +8,8 @@
 
 import (
 	"encoding/asn1"
+	"encoding/hex"
+	"fmt"
 	"math/big"
 	"time"
 )
@@ -21,6 +23,75 @@
 
 type RDNSequence []RelativeDistinguishedNameSET
 
+var attributeTypeNames = map[string]string{
+	"2.5.4.6":  "C",
+	"2.5.4.10": "O",
+	"2.5.4.11": "OU",
+	"2.5.4.3":  "CN",
+	"2.5.4.5":  "SERIALNUMBER",
+	"2.5.4.7":  "L",
+	"2.5.4.8":  "ST",
+	"2.5.4.9":  "STREET",
+	"2.5.4.17": "POSTALCODE",
+}
+
+// String returns a string representation of the sequence r,
+// roughly following the RFC 2253 Distinguished Names syntax.
+func (r RDNSequence) String() string {
+	s := ""
+	for i := 0; i < len(r); i++ {
+		rdn := r[len(r)-1-i]
+		if i > 0 {
+			s += ","
+		}
+		for j, tv := range rdn {
+			if j > 0 {
+				s += "+"
+			}
+
+			oidString := tv.Type.String()
+			typeName, ok := attributeTypeNames[oidString]
+			if !ok {
+				derBytes, err := asn1.Marshal(tv.Value)
+				if err == nil {
+					s += oidString + "=#" + hex.EncodeToString(derBytes)
+					continue // No value escaping necessary.
+				}
+
+				typeName = oidString
+			}
+
+			valueString := fmt.Sprint(tv.Value)
+			escaped := make([]rune, 0, len(valueString))
+
+			for k, c := range valueString {
+				escape := false
+
+				switch c {
+				case ',', '+', '"', '\\', '<', '>', ';':
+					escape = true
+
+				case ' ':
+					escape = k == 0 || k == len(valueString)-1
+
+				case '#':
+					escape = k == 0
+				}
+
+				if escape {
+					escaped = append(escaped, '\\', c)
+				} else {
+					escaped = append(escaped, c)
+				}
+			}
+
+			s += typeName + "=" + string(escaped)
+		}
+	}
+
+	return s
+}
+
 type RelativeDistinguishedNameSET []AttributeTypeAndValue
 
 // AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
@@ -150,6 +221,12 @@
 	return ret
 }
 
+// String returns the string form of n, roughly following
+// the RFC 2253 Distinguished Names syntax.
+func (n Name) String() string {
+	return n.ToRDNSequence().String()
+}
+
 // oidInAttributeTypeAndValue returns whether a type with the given OID exists
 // in atv.
 func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool {
@@ -170,9 +247,9 @@
 	SignatureValue     asn1.BitString
 }
 
-// HasExpired reports whether now is past the expiry time of certList.
+// HasExpired reports whether certList should have been updated by now.
 func (certList *CertificateList) HasExpired(now time.Time) bool {
-	return now.After(certList.TBSCertList.NextUpdate)
+	return !now.Before(certList.TBSCertList.NextUpdate)
 }
 
 // TBSCertificateList represents the ASN.1 structure of the same name. See RFC
diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go
index 8e80533..80cd250 100644
--- a/src/crypto/x509/root_cgo_darwin.go
+++ b/src/crypto/x509/root_cgo_darwin.go
@@ -119,7 +119,11 @@
 			}
 			// We only want trusted certs.
 			int untrusted = 0;
-			if (i != 0) {
+			int trustAsRoot = 0;
+			int trustRoot = 0;
+			if (i == 0) {
+				trustAsRoot = 1;
+			} else {
 				// Certs found in the system domain are always trusted. If the user
 				// configures "Never Trust" on such a cert, it will also be found in the
 				// admin or user domain, causing it to be added to untrustedPemRoots. The
@@ -129,7 +133,7 @@
 				// SecTrustServer.c, "user trust settings overrule admin trust settings",
 				// so take the last trust settings array we find.
 				// Skip the system domain since it is always trusted.
-				for (int k = 1; k < numDomains; k++) {
+				for (int k = i; k < numDomains; k++) {
 					CFArrayRef domainTrustSettings = NULL;
 					err = SecTrustSettingsCopyTrustSettings(cert, domains[k], &domainTrustSettings);
 					if (err == errSecSuccess && domainTrustSettings != NULL) {
@@ -152,28 +156,35 @@
 						// TODO: The rest of the dictionary specifies conditions for evaluation.
 						if (result == kSecTrustSettingsResultDeny) {
 							untrusted = 1;
+						} else if (result == kSecTrustSettingsResultTrustAsRoot) {
+							trustAsRoot = 1;
+						} else if (result == kSecTrustSettingsResultTrustRoot) {
+							trustRoot = 1;
 						}
 					}
 				}
 				CFRelease(trustSettings);
 			}
-			// We only want to add Root CAs, so make sure Subject and Issuer Name match
-			CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
-			if (errRef != NULL) {
-				CFRelease(errRef);
-				continue;
-			}
-			CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
-			if (errRef != NULL) {
+
+			if (trustRoot) {
+				// We only want to add Root CAs, so make sure Subject and Issuer Name match
+				CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
+				if (errRef != NULL) {
+					CFRelease(errRef);
+					continue;
+				}
+				CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
+				if (errRef != NULL) {
+					CFRelease(subjectName);
+					CFRelease(errRef);
+					continue;
+				}
+				Boolean equal = CFEqual(subjectName, issuerName);
 				CFRelease(subjectName);
-				CFRelease(errRef);
-				continue;
-			}
-			Boolean equal = CFEqual(subjectName, issuerName);
-			CFRelease(subjectName);
-			CFRelease(issuerName);
-			if (!equal) {
-				continue;
+				CFRelease(issuerName);
+				if (!equal) {
+					continue;
+				}
 			}
 
 			// Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
@@ -185,6 +196,9 @@
 			}
 
 			if (data != NULL) {
+				if (!trustRoot && !trustAsRoot) {
+					untrusted = 1;
+				}
 				CFMutableDataRef appendTo = untrusted ? combinedUntrustedData : combinedData;
 				CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data));
 				CFRelease(data);
@@ -207,8 +221,8 @@
 func loadSystemRoots() (*CertPool, error) {
 	roots := NewCertPool()
 
-	var data C.CFDataRef = nil
-	var untrustedData C.CFDataRef = nil
+	var data C.CFDataRef = 0
+	var untrustedData C.CFDataRef = 0
 	err := C.FetchPEMRoots(&data, &untrustedData)
 	if err == -1 {
 		// TODO: better error message
@@ -218,7 +232,7 @@
 	defer C.CFRelease(C.CFTypeRef(data))
 	buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
 	roots.AppendCertsFromPEM(buf)
-	if untrustedData == nil {
+	if untrustedData == 0 {
 		return roots, nil
 	}
 	defer C.CFRelease(C.CFTypeRef(untrustedData))
diff --git a/src/crypto/x509/root_darwin_arm_gen.go b/src/crypto/x509/root_darwin_arm_gen.go
index fc2488a..b5580d6 100644
--- a/src/crypto/x509/root_darwin_arm_gen.go
+++ b/src/crypto/x509/root_darwin_arm_gen.go
@@ -18,16 +18,18 @@
 
 import (
 	"bytes"
+	"crypto/sha256"
 	"crypto/x509"
+	"encoding/hex"
 	"encoding/pem"
 	"flag"
 	"fmt"
 	"go/format"
 	"io/ioutil"
 	"log"
-	"math/big"
 	"net/http"
 	"os/exec"
+	"regexp"
 	"strings"
 )
 
@@ -41,7 +43,7 @@
 
 	buf := new(bytes.Buffer)
 
-	fmt.Fprintf(buf, "// Created by root_darwin_arm_gen --output %s; DO NOT EDIT\n", *output)
+	fmt.Fprintf(buf, "// Code generated by root_darwin_arm_gen --output %s; DO NOT EDIT.\n", *output)
 	fmt.Fprintf(buf, "%s", header)
 
 	fmt.Fprintf(buf, "const systemRootsPEM = `\n")
@@ -78,36 +80,22 @@
 
 	var certs []*x509.Certificate
 	for _, id := range ids {
-		sn, ok := big.NewInt(0).SetString(id.serialNumber, 0) // 0x prefix selects hex
-		if !ok {
-			return nil, fmt.Errorf("invalid serial number: %q", id.serialNumber)
-		}
-		ski, ok := big.NewInt(0).SetString(id.subjectKeyID, 0)
-		if !ok {
-			return nil, fmt.Errorf("invalid Subject Key ID: %q", id.subjectKeyID)
-		}
-
-		for _, cert := range scerts {
-			if sn.Cmp(cert.SerialNumber) != 0 {
-				continue
-			}
-			cski := big.NewInt(0).SetBytes(cert.SubjectKeyId)
-			if ski.Cmp(cski) != 0 {
-				continue
-			}
-			certs = append(certs, cert)
-			break
+		if c, ok := scerts[id.fingerprint]; ok {
+			certs = append(certs, c)
+		} else {
+			fmt.Printf("WARNING: cannot find certificate: %s (fingerprint: %s)\n", id.name, id.fingerprint)
 		}
 	}
 	return certs, nil
 }
 
-func sysCerts() (certs []*x509.Certificate, err error) {
+func sysCerts() (certs map[string]*x509.Certificate, err error) {
 	cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
 	data, err := cmd.Output()
 	if err != nil {
 		return nil, err
 	}
+	certs = make(map[string]*x509.Certificate)
 	for len(data) > 0 {
 		var block *pem.Block
 		block, data = pem.Decode(data)
@@ -122,19 +110,23 @@
 		if err != nil {
 			continue
 		}
-		certs = append(certs, cert)
+
+		fingerprint := sha256.Sum256(cert.Raw)
+		certs[hex.EncodeToString(fingerprint[:])] = cert
 	}
 	return certs, nil
 }
 
 type certID struct {
-	serialNumber string
-	subjectKeyID string
+	name        string
+	fingerprint string
 }
 
 // fetchCertIDs fetches IDs of iOS X509 certificates from apple.com.
 func fetchCertIDs() ([]certID, error) {
-	resp, err := http.Get("https://support.apple.com/en-us/HT204132")
+	// Download the iOS 11 support page. The index for all iOS versions is here:
+	// https://support.apple.com/en-us/HT204132
+	resp, err := http.Get("https://support.apple.com/en-us/HT208125")
 	if err != nil {
 		return nil, err
 	}
@@ -144,31 +136,33 @@
 		return nil, err
 	}
 	text := string(body)
-	text = text[strings.Index(text, "<section id=trusted"):]
-	text = text[:strings.Index(text, "</section>")]
+	text = text[strings.Index(text, "<div id=trusted"):]
+	text = text[:strings.Index(text, "</div>")]
 
-	lines := strings.Split(text, "\n")
 	var ids []certID
-	var id certID
-	for i, ln := range lines {
-		if i == len(lines)-1 {
-			break
-		}
-		const sn = "Serial Number:"
-		if ln == sn {
-			id.serialNumber = "0x" + strings.Replace(strings.TrimSpace(lines[i+1]), ":", "", -1)
+	cols := make(map[string]int)
+	for i, rowmatch := range regexp.MustCompile("(?s)<tr>(.*?)</tr>").FindAllStringSubmatch(text, -1) {
+		row := rowmatch[1]
+		if i == 0 {
+			// Parse table header row to extract column names
+			for i, match := range regexp.MustCompile("(?s)<th>(.*?)</th>").FindAllStringSubmatch(row, -1) {
+				cols[match[1]] = i
+			}
 			continue
 		}
-		if strings.HasPrefix(ln, sn) {
-			// extract hex value from parentheses.
-			id.serialNumber = ln[strings.Index(ln, "(")+1 : len(ln)-1]
-			continue
-		}
-		if strings.TrimSpace(ln) == "X509v3 Subject Key Identifier:" {
-			id.subjectKeyID = "0x" + strings.Replace(strings.TrimSpace(lines[i+1]), ":", "", -1)
-			ids = append(ids, id)
-			id = certID{}
-		}
+
+		values := regexp.MustCompile("(?s)<td>(.*?)</td>").FindAllStringSubmatch(row, -1)
+		name := values[cols["Certificate name"]][1]
+		fingerprint := values[cols["Fingerprint (SHA-256)"]][1]
+		fingerprint = strings.Replace(fingerprint, "<br>", "", -1)
+		fingerprint = strings.Replace(fingerprint, "\n", "", -1)
+		fingerprint = strings.Replace(fingerprint, " ", "", -1)
+		fingerprint = strings.ToLower(fingerprint)
+
+		ids = append(ids, certID{
+			name:        name,
+			fingerprint: fingerprint,
+		})
 	}
 	return ids, nil
 }
@@ -180,7 +174,7 @@
 
 // +build cgo
 // +build darwin
-// +build arm arm64
+// +build arm arm64 ios
 
 package x509
 
diff --git a/src/crypto/x509/root_darwin_armx.go b/src/crypto/x509/root_darwin_armx.go
index ad1c53d..fcbbd6b 100644
--- a/src/crypto/x509/root_darwin_armx.go
+++ b/src/crypto/x509/root_darwin_armx.go
@@ -1,4 +1,4 @@
-// Created by root_darwin_arm_gen --output root_darwin_armx.go; DO NOT EDIT
+// Code generated by root_darwin_arm_gen --output root_darwin_armx.go; DO NOT EDIT.
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -18,96 +18,29 @@
 
 const systemRootsPEM = `
 -----BEGIN CERTIFICATE-----
-MIIF8DCCA9igAwIBAgIPBuhGJy8fCo/RhFzjafbVMA0GCSqGSIb3DQEBBQUAMDgx
-CzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXpl
-bnBlLmNvbTAeFw0wNzEyMTMxMzA4MjdaFw0zNzEyMTMwODI3MjVaMDgxCzAJBgNV
-BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXplbnBlLmNv
-bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMnTesoPHqynhugWZWqx
-whtFMnGV2f4QW8yv56V5AY+Jw8ryVXH3d753lPNypCxE2J6SmxQ6oeckkAoKVo7F
-2CaU4dlI4S0+2gpy3aOZFdqBoof0e24md4lYrdbrDLJBenNubdt6eEHpCIgSfocu
-ZhFjbFT7PJ1ywLwu/8K33Q124zrX97RovqL144FuwUZvXY3gTcZUVYkaMzEKsVe5
-o4qYw+w7NMWVQWl+dcI8IMVhulFHoCCQk6GQS/NOfIVFVJrRBSZBsLVNHTO+xAPI
-JXzBcNs79AktVCdIrC/hxKw+yMuSTFM5NyPs0wH54AlETU1kwOENWocivK0bo/4m
-tRXzp/yEGensoYi0RGmEg/OJ0XQGqcwL1sLeJ4VQJsoXuMl6h1YsGgEebL4TrRCs
-tST1OJGh1kva8bvS3ke18byB9llrzxlT6Y0Vy0rLqW9E5RtBz+GGp8rQap+8TI0G
-M1qiheWQNaBiXBZO8OOi+gMatCxxs1gs3nsL2xoP694hHwZ3BgOwye+Z/MC5TwuG
-KP7Suerj2qXDR2kS4Nvw9hmL7Xtw1wLW7YcYKCwEJEx35EiKGsY7mtQPyvp10gFA
-Wo15v4vPS8+qFsGV5K1Mij4XkdSxYuWC5YAEpAN+jb/af6IPl08M0w3719Hlcn4c
-yHf/W5oPt64FRuXxqBbsR6QXAgMBAAGjgfYwgfMwgbAGA1UdEQSBqDCBpYEPaW5m
-b0BpemVucGUuY29tpIGRMIGOMUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBB
-MDEzMzcyNjAtUk1lcmMuVml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEG
-A1UECQw6QXZkYSBkZWwgTWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEw
-IFZpdG9yaWEtR2FzdGVpejAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUHRxlDqjyJXu0kc/ksbHmvVV0bAUwDQYJKoZIhvcNAQEFBQAD
-ggIBAMeBRm8hGE+gBe/n1bqXUKJg7aWSFBpSm/nxiEqg3Hh10dUflU7F57dp5iL0
-+CmoKom+z892j+Mxc50m0xwbRxYpB2iEitL7sRskPtKYGCwkjq/2e+pEFhsqxPqg
-l+nqbFik73WrAGLRne0TNtsiC7bw0fRue0aHwp28vb5CO7dz0JoqPLRbEhYArxk5
-ja2DUBzIgU+9Ag89njWW7u/kwgN8KRwCfr00J16vU9adF79XbOnQgxCvv11N75B7
-XSus7Op9ACYXzAJcY9cZGKfsK8eKPlgOiofmg59OsjQerFQJTx0CCzl+gQgVuaBp
-E8gyK+OtbBPWg50jLbJtooiGfqgNASYJQNntKE6MkyQP2/EeTXp6WuKlWPHcj1+Z
-ggwuz7LdmMySlD/5CbOlliVbN/UShUHiGUzGigjB3Bh6Dx4/glmimj4/+eAJn/3B
-kUtdyXvWton83x18hqrNA/ILUpLxYm9/h+qrdslsUMIZgq+qHfUgKGgu1fxkN0/P
-pUTEvnK0jHS0bKf68r10OEMr3q/53NjgnZ/cPcqlY0S/kqJPTIAcuxrDmkoEVU3K
-7iYLHL8CxWTTnn7S05EcS6L1HOUXHA0MUqORH5zwIe0ClG+poEnK6EOMxPQ02nwi
-o8ZmPrgbBYhdurz3vOXcFD2nhqi2WVIhA16L4wTtSyoeo09Q
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
-RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
-IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
-MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
-LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
-YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
-A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
-K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
-sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
-MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
-XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
-HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
-4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
-HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
-j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
-U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
-zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
-u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
-bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
-fF6adulZkMV8gzURZVE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
-BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu
-IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw
-WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD
-ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y
-IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn
-IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+
-6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob
-jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw
-izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl
-+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY
-zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP
-pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF
-KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW
-ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB
-AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0
-ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
-IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA
-A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0
-uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+
-FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7
-jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/
-u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D
-YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1
-puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa
-icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG
-DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x
-kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z
-Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
@@ -143,6 +76,106 @@
 LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
+MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
+MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
+VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
+CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
+tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
+dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
+PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
+BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
+ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
+IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
+7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
+43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
+eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
+pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
+WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj
+aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB
+MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx
+DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi
+C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go
+vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB
+++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy
+fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm
+vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC
+AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI
+YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290
+LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu
+LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f
+BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT
+GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w
+DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM
+Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk
+bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp
+Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD
+Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
+AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM
+vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9
+QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr
+a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn
+0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/
+RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
 MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
 BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
 dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
@@ -163,394 +196,17 @@
 x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
-b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
-MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
-ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
-IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
-AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
-unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
-BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
-7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
-0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
-roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
-A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
-aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
-26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
-BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
-EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
-BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
-aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
-AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
-p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
-1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
-XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
-eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
-tGWaIZDgqtCYvDi1czyL+Nw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
-YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
-GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
-BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
-3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
-YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
-rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
-ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
-oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
-MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
-QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
-b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
-AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
-GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
-Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
-G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
-l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
-smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
-gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
-BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
-MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
-YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
-RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
-UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
-2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
-Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
-+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
-DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
-nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
-/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
-PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
-QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
-SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
-IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
-RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
-zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
-BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
-ZQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDcDCCAligAwIBAgIBBTANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQGEwJVUzEY
-MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT
-A1BLSTEWMBQGA1UEAxMNRG9EIFJvb3QgQ0EgMjAeFw0wNDEyMTMxNTAwMTBaFw0y
-OTEyMDUxNTAwMTBaMFsxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVy
-bm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRYwFAYDVQQDEw1Eb0Qg
-Um9vdCBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCzB9o07
-rP8/PNZxvrh0IgfscEEV/KtA4weqwcPYn/7aTDq/P8jYKHtLNgHArEUlw9IOCo+F
-GGQQPRoTcCpvjtfcjZOzQQ84Ic2tq8I9KgXTVxE3Dc2MUfmT48xGSSGOFLTNyxQ+
-OM1yMe6rEvJl6jQuVl3/7mN1y226kTT8nvP0LRy+UMRC31mI/2qz+qhsPctWcXEF
-lrufgOWARVlnQbDrw61gpIB1BhecDvRD4JkOG/t/9bPMsoGCsf0ywbi+QaRktWA6
-WlEwjM7eQSwZR1xJEGS5dKmHQa99brrBuKG/ZTE6BGf5tbuOkooAY7ix5ow4X4P/
-UNU7ol1rshDMYwIDAQABoz8wPTAdBgNVHQ4EFgQUSXS7DF66ev4CVO97oMaVxgmA
-cJYwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBAJiRjT+JyLv1wGlzKTs1rLqzCHY9cAmS6YREIQF9FHYb7lFsHY0VNy17MWn0
-mkS4r0bMNPojywMnGdKDIXUr5+AbmSbchECV6KjSzPZYXGbvP0qXEIIdugqi3VsG
-K52nZE7rLgE1pLQ/E61V5NVzqGmbEfGY8jEeb0DU+HifjpGgb3AEkGaqBivO4XqS
-tX3h4NGW56E6LcyxnR8FRO2HmdNNGnA5wQQM5X7Z8a/XIA7xInolpHOZzD+kByeW
-qKKV7YK5FtOeC4fCwfKI9WLfaN/HvGlR7bFc3FRUKQ8JOZqsA8HbDE2ubwp6Fknx
-v5HSOJTT9pUst2zJQraNypCNhdk=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
-PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
-cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
-MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
-IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
-ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
-VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
-kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
-EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
-H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
-HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
-DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
-QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
-Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
-AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
-yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
-FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
-ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
-kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
-l7+ijrRU
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
-cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
-IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
-dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
-NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
-dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
-dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
-aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
-RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
-cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
-wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
-U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
-jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
-BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
-jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
-Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
-1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
-nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
-VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID9jCCAt6gAwIBAgIQZIKe/DcedF38l/+XyLH/QTANBgkqhkiG9w0BAQsFADCB
-lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
-HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
-YyBDbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
-BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
-eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAy
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNzOkFyGOFyz9AYxe9GPo15gRn
-V2WYKaRPyVyPDzTS+NqoE2KquB5QZ3iwFkygOakVeq7t0qLA8JA3KRgmXOgNPLZs
-ST/B4NzZS7YUGQum05bh1gnjGSYc+R9lS/kaQxwAg9bQqkmi1NvmYji6UBRDbfkx
-+FYW2TgCkc/rbN27OU6Z4TBnRfHU8I3D3/7yOAchfQBeVkSz5GC9kSucq1sEcg+y
-KNlyqwUgQiWpWwNqIBDMMfAr2jUs0Pual07wgksr2F82owstr2MNHSV/oW5cYqGN
-KD6h/Bwg+AEvulWaEbAZ0shQeWsOagXXqgQ2sqPy4V93p3ec5R7c6d9qwWVdAgMB
-AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBSHjCCVyJhK0daABkqQNETfHE2/sDANBgkqhkiG9w0BAQsFAAOCAQEAgY6ypWaW
-tyGltu9vI1pf24HFQqV4wWn99DzX+VxrcHIa/FqXTQCAiIiCisNxDY7FiZss7Y0L
-0nJU9X3UXENX6fOupQIR9nYrgVfdfdp0MP1UR/bgFm6mtApI5ud1Bw8pGTnOefS2
-bMVfmdUfS/rfbSw8DVSAcPCIC4DPxmiiuB1w2XaM/O6lyc+tHc+ZJVdaYkXLFmu9
-Sc2lo4xpeSWuuExsi0BmSxY/zwIa3eFsawdhanYVKZl/G92IgMG/tY9zxaaWI4Sm
-KIYkM2oBLldzJbZev4/mHWGoQClnHYebHX+bn5nNMdZUvmK7OaxoEkiRIKXLsd3+
-b/xa5IJVWa8xqQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
-lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
-SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
-A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
-MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
-d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
-cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
-0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
-M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
-MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
-oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
-DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
-oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
-dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
-bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
-BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
-//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
-CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
-CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
-3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
-KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
-MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
-cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
-bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
-CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
-dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
-cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
-2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
-lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
-ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
-299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
-vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
-dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
-AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
-zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
-LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
-7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
-++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
-398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
-bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
-MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
-ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
-206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
-KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
-JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
-BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
-Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
-PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
-Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
-Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
-o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
-+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
-YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
-FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
-AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
-xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
-LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
-obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
-CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
-IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
-DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
-AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
-Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
-AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
-Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
-RY8mkaKO/qk=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
-VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
-ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
-CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
-OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
-FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
-Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
-dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
-kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
-cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
-fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
-N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
-xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
-+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
-Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
-SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
-mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
-ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
-tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
-2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
-HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIHqTCCBZGgAwIBAgIQYwaGp8U3ZaVDkKhqWMzUMjANBgkqhkiG9w0BAQUFADCB
-jzELMAkGA1UEBhMCTFYxNTAzBgNVBAoTLFZBUyBMYXR2aWphcyBQYXN0cyAtIFZp
-ZW4ucmVnLk5yLjQwMDAzMDUyNzkwMSMwIQYDVQQLExpTZXJ0aWZpa2FjaWphcyBw
-YWthbHBvanVtaTEkMCIGA1UEAxMbVkFTIExhdHZpamFzIFBhc3RzIFNTSShSQ0Ep
-MB4XDTA2MDkxMzA5MjIxMFoXDTI0MDkxMzA5Mjc1N1owgY8xCzAJBgNVBAYTAkxW
-MTUwMwYDVQQKEyxWQVMgTGF0dmlqYXMgUGFzdHMgLSBWaWVuLnJlZy5Oci40MDAw
-MzA1Mjc5MDEjMCEGA1UECxMaU2VydGlmaWthY2lqYXMgcGFrYWxwb2p1bWkxJDAi
-BgNVBAMTG1ZBUyBMYXR2aWphcyBQYXN0cyBTU0koUkNBKTCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBAJu4+f1hVS9PpKUUtS6OuSSPrPuxVD9A/0/F5YZo
-e1OT+zWCNahQLpRSoNuDPnXaFXCsCc/ugkmtNkm5tHGLtAChQgbKCApjl7YI/O60
-3Jh4GYLJ+H9kPqrJ/rGN67Bk9bzzxD46kOpOjj8bGbxqg8ORPGxV+wpSwOjhXXeF
-M8VJ3+xqv79sN/6OSaIVGM6LjmseOKMwb4iBfnJWRBrEejkP9sSPltSy6wBOXN67
-5zu35iQFk2tN5pFEv+6YG8eFGxFBeyI2p74+6Ho33BjekJ2PzbLXmj/iF39bDOHv
-P2Y9biTksM7DDIhslNo4JXxSOeNzFLMARWOaDEJAXgTG93JkzsluM7Pk020klTeT
-fvIAXRmLH/NDc6ifRdIGqey0Qrv67gzHTz9RH9Gv0KwYf4eBIv6p3QeWbXz4TtlN
-OlBp1UF+xdp02I5z5X6D4cMZgbe9v0COvi6aogyqTgIuuyrhCF0xA8msJ7Cv3NXI
-FH1AnVWJIfmQzNTJYEFzq+jN2DpVOQqCmf6b9fU8HJHLwPpGVK4h/CqsXHveepdx
-/WxrzUiapNuBfBg3L5B9YZS9F8lctlQWd8oJSqrpvE+UdQFaVryS0o+515feVnQB
-9xZxSbH1GEaZQe5i4bMsZXVpKXJDA/ibH/o49J7sQBCOrJfVsDO+nxjcLfdBeFRK
-YkTnAgMBAAGjggH9MIIB+TAOBgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAK
-MAgGBgQAjkYBATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTMw/Vm/3OsOFqW
-GyGJuIFMH8teJTAQBgkrBgEEAYI3FQEEAwIBADCCAYkGA1UdIASCAYAwggF8MIIB
-eAYLKwYBBAGBxFkBAQIwggFnMIIBOAYIKwYBBQUHAgIwggEqHoIBJgBTAGkAcwAg
-AGkAcgAgAHMAZQByAHQAaQBmAGkAawBhAHQAcwAsACAAawBvACAAaQB6AGQAZQB2
-AGkAcwAgAFYAQQBTACAATABhAHQAdgBpAGoAYQBzACAAUABhAHMAdABzACwAIABu
-AG8AZAByAG8AcwBpAG4AbwB0ACAAYQB0AGIAaQBsAHMAdABpAGIAdQAgAEUAbABl
-AGsAdAByAG8AbgBpAHMAawBvACAAZABvAGsAdQBtAGUAbgB0AHUAIABsAGkAawB1
-AG0AYQBtACAAdQBuACAARQBpAHIAbwBwAGEAcwAgAFAAYQByAGwAYQBtAGUAbgB0
-AGEAIABkAGkAcgBlAGsAdABpAHYAYQBpACAAMQA5ADkAOQAvADkAMwAvAEUASzAp
-BggrBgEFBQcCARYdaHR0cDovL3d3dy5lLW1lLmx2L3JlcG9zaXRvcnkwDQYJKoZI
-hvcNAQEFBQADggIBAB8oSjWQIWNoCi94r6MegiaXoz8nGdJLo0J6BhNlW8EEy+t9
-fO+U8vGJ9bffUgIhadLqljTloM+XuJxVDhCFoxReLAX4tTp28/l6uN62DCdp8suU
-kQsdudWOb5kvzfIZVjk6SFbwAf+Cdbay/dHU9fJjV0xNoX7MELoEae/0FPyzlx9F
-7m9KKH/Rxie8x6Opa3vtghNvq94P+3HrXBEaqSzQMJ/8NjdW75XpurcTtq6fAmGt
-nuxrBG82nw+Z98LJyEwouSjUIdeeVNXAzvSO5FWUe48kxjj8q3qkVnc9qEXvZJKk
-0Ep+u3OL9A1Sc7g6SF5DgNOpcHdi/8coHHMeQ+YnJFtJueY2pI79xS0veqV5EnrX
-IbIlbcgPosNhS+VI4le6n/KKId3bZPDaGd/OwJuAOcJ3d2MVU3KE+qSPBzeGIX1Q
-+j1qN9uRDjez/c4Lynth0Jx0nH04aG3pex3W8Sq07ztgUncF5gLCX4xbvPB9t3PH
-kWuyKrNjozTVq60lcUf/Gj56to2VdsPups0DCWzuRWeYz5lIdsHOinSaaFIBNCLI
-7eIUC4S9bhCMsXKbvugI11fVf+q0AT1O5OLoZ+eMfunnQhHvlUbIkda+JxeAGTSY
-58bfHvwhX56GPbx+8Jy9cp70R4JbcWfz+txUTKhc2FnH0AcOEzMnvPRp8Gsh
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
-MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
-AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw
-CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg
-YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE
-Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX
-mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD
-XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW
-S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp
-FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD
-AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu
-ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z
-ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv
-Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw
-DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6
-yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq
-EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
-CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB
-EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN
-PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDXTCCAkWgAwIBAgIDAOJCMA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNVBAYTAkFU
-MRAwDgYDVQQKEwdBLVRydXN0MRkwFwYDVQQLExBBLVRydXN0LW5RdWFsLTAxMRkw
-FwYDVQQDExBBLVRydXN0LW5RdWFsLTAxMB4XDTA0MTEzMDIzMDAwMFoXDTE0MTEz
-MDIzMDAwMFowVTELMAkGA1UEBhMCQVQxEDAOBgNVBAoTB0EtVHJ1c3QxGTAXBgNV
-BAsTEEEtVHJ1c3QtblF1YWwtMDExGTAXBgNVBAMTEEEtVHJ1c3QtblF1YWwtMDEw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD/9RyAEZ6eHmhYzNJ328f0
-jmdSUFi6EqRqOxb3jHNPTIpK82CR6z5lmSnZQNUuCPD+htbNZffd2DKVB06NOyZ1
-2zcOMCgj4GtkZoqE0zPpPT3bpoE55nkZZe/qWEX/64wz/L/4EdkvKDSKG/UsP75M
-tmCVY5m2Eg73RVFRz4ccBIMpHel4lzEqSkdDtZOY5fnkrE333hx67nxq21vY8Eyf
-8O4fPQ5RtN8eohQCcPQ1z6ypU1R7N9jPRpnI+yzMOiwd3+QcKhHi1miCzo0pkOaB
-1CwmfsTyNl8qU0NJUL9Ta6cea7WThwTiWol2yD88cd2cy388xpbNkfrCPmZNGLoV
-AgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECE5ZzscCMocwMA4G
-A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEA69I9R1hU9Gbl9vV7W7AH
-QpUJAlFAvv2It/eY8p2ouQUPVaSZikaKtAYrCD/arzfXB43Qet+dM6CpHsn8ikYR
-vQKePjXv3Evf+C1bxwJAimcnZV6W+bNOTpdo8lXljxkmfN+Z5S+XzvK2ttUtP4Et
-YOVaxHw2mPMNbvDeY+foJkiBn3KYjGabMaR8moZqof5ofj4iS/WyamTZti6v/fKx
-n1vII+/uWkcxV5DT5+r9HLon0NYF0Vg317Wh+gWDV59VZo+dcwJDb+keYqMFYoqp
-77SGkZGu41S8NGYkQY3X9rNHRkDbLfpKYDmy6NanpOE1EHW1/sNSFAs43qZZKJEQ
-xg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB
-rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt
-Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa
-Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV
-BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l
-dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE
-AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B
-YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9
-hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l
-L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm
-SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM
-1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
-6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
-DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw
-Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50
-aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
-AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u
-7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0
-xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ
-rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim
-eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk
-USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
@@ -584,333 +240,985 @@
 KeC2uAloGRwYQw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
-MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
-ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
-BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
-6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
-GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
-dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
-1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
-62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
-BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
-AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
-MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
-cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
-b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
-IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
-iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
-GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
-4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
-XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
+MIIIGDCCBgCgAwIBAgIGAT8vMXfmMA0GCSqGSIb3DQEBCwUAMIIBCjELMAkGA1UE
+BhMCRVMxEjAQBgNVBAgMCUJhcmNlbG9uYTFYMFYGA1UEBwxPQmFyY2Vsb25hIChz
+ZWUgY3VycmVudCBhZGRyZXNzIGF0IGh0dHA6Ly93d3cuYW5mLmVzL2VzL2FkZHJl
+c3MtZGlyZWNjaW9uLmh0bWwgKTEnMCUGA1UECgweQU5GIEF1dG9yaWRhZCBkZSBD
+ZXJ0aWZpY2FjaW9uMRcwFQYDVQQLDA5BTkYgQ2xhc2UgMSBDQTEaMBgGCSqGSIb3
+DQEJARYLaW5mb0BhbmYuZXMxEjAQBgNVBAUTCUc2MzI4NzUxMDEbMBkGA1UEAwwS
+QU5GIEdsb2JhbCBSb290IENBMB4XDTEzMDYxMDE3NDUzOFoXDTMzMDYwNTE3NDUz
+OFowggEKMQswCQYDVQQGEwJFUzESMBAGA1UECAwJQmFyY2Vsb25hMVgwVgYDVQQH
+DE9CYXJjZWxvbmEgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgaHR0cDovL3d3dy5h
+bmYuZXMvZXMvYWRkcmVzcy1kaXJlY2Npb24uaHRtbCApMScwJQYDVQQKDB5BTkYg
+QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xFzAVBgNVBAsMDkFORiBDbGFzZSAx
+IENBMRowGAYJKoZIhvcNAQkBFgtpbmZvQGFuZi5lczESMBAGA1UEBRMJRzYzMjg3
+NTEwMRswGQYDVQQDDBJBTkYgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDHPi9xy4wynbcUbWjorVUgQKeUAVh937J7P37XmsfH
+ZLOBZKIIlhhCtRwnDlg7x+BUvtJOTkIbEGMujDygUQ2s3HDYr5I41hTyM2Pl0cq2
+EuSGEbPIHb3dEX8NAguFexM0jqNjrreN3hM2/+TOkAxSdDJP2aMurlySC5zwl47K
+ZLHtcVrkZnkDa0o5iN24hJT4vBDT4t2q9khQ+qb1D8KgCOb02r1PxWXu3vfd6Ha2
+mkdB97iGuEh5gO2n4yOmFS5goFlVA2UdPbbhJsb8oKVKDd+YdCKGQDCkQyG4AjmC
+YiNm3UPG/qtftTH5cWri67DlLtm6fyUFOMmO6NSh0RtR745pL8GyWJUanyq/Q4bF
+HQB21E+WtTsCaqjGaoFcrBunMypmCd+jUZXl27TYENRFbrwNdAh7m2UztcIyb+Sg
+VJFyfvVsBQNvnp7GPimVxXZNc4VpxEXObRuPWQN1oZN/90PcZVqTia/SHzEyTryL
+ckhiLG3jZiaFZ7pTZ5I9wti9Pn+4kOHvE3Y/4nEnUo4mTxPX9pOlinF+VCiybtV2
+u1KSlc+YaIM7VmuyndDZCJRXm3v0/qTE7t5A5fArZl9lvibigMbWB8fpD+c1GpGH
+Eo8NRY0lkaM+DkIqQoaziIsz3IKJrfdKaq9bQMSlIfameKBZ8fNYTBZrH9KZAIhz
+YwIDAQABo4IBfjCCAXowHQYDVR0OBBYEFIf6nt9SdnXsSUogb1twlo+d77sXMB8G
+A1UdIwQYMBaAFIf6nt9SdnXsSUogb1twlo+d77sXMA8GA1UdEwEB/wQFMAMBAf8w
+DgYDVR0PAQH/BAQDAgEGMIIBFQYDVR0RBIIBDDCCAQiCEWh0dHA6Ly93d3cuYW5m
+LmVzgQtpbmZvQGFuZi5lc6SB5TCB4jE0MDIGA1UECQwrR3JhbiBWaWEgZGUgbGVz
+IENvcnRzIENhdGFsYW5lcy4gOTk2LiAwODAxODESMBAGA1UEBwwJQmFyY2Vsb25h
+MScwJQYDVQQKDB5BTkYgQXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xEjAQBgNV
+BAUTCUc2MzI4NzUxMDFZMFcGA1UECwxQSW5zY3JpdGEgZW4gZWwgTWluaXN0ZXJp
+byBkZWwgSW50ZXJpb3IgZGUgRXNwYcOxYSBjb24gZWwgbnVtZXJvIG5hY2lvbmFs
+IDE3MS40NDMwDQYJKoZIhvcNAQELBQADggIBAIgR9tFTZ9BCYg+HViMxOfF0MHN2
+Pe/eC128ARdS+GH8A4thtbqiH/SOYbWofO/0zssHhNKa5iQEj45lCAb8BANpWJMD
+nWkPr6jq2+50a6d0MMgSS2l1rvjSF+3nIrEuicshHXSTi3q/vBLKr7uGKMVFaM68
+XAropIwk6ndlA0JseARSPsbetv7ALESMIZAxlHV1TcctYHd0bB3c/Jz+PLszJQqs
+Cg/kBPo2D111OXZkIY8W/fJuG9veR783khAK2gUnC0zLLCNsYzEbdGt8zUmBsAsM
+cGxqGm6B6vDXd65OxWqw13xdq/24+5R8Ng1PF9tvfjZkUFBF30CxjWur7P90WiKI
+G7IGfr6BE1NgXlhEQQu4F+HizB1ypEPzGWltecXQ4yOzO+H0WfFTjLTYX6VSveyW
+DQV18ixF8M4tHP/SwNE+yyv2b2JJ3/3RpxjtFlLk+opJ574x0gD/dMJuWTH0JqVY
+3PbRfE1jIxFpk164Qz/Xp7H7w7f6xh+tQCkBs3PUYmnGIZcPwq44Q6JHlCNsKx4K
+hxfggTvRCk4w79cUID45c2qDsRCqTPoOo/cbOpcfVhbH9LdMORpmuLwNogRZEUSE
+fWpqR9q+0kcQf4zGSWIURIyDrogdpDgoHDxktqgMgc+qA4ZE2WQl1D8hmev53A46
+lUSrWUiWfDXtK3ux
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEajCCA1KgAwIBAgIBATANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJKUDEN
-MAsGA1UECgwESlBLSTEpMCcGA1UECwwgUHJlZmVjdHVyYWwgQXNzb2NpYXRpb24g
-Rm9yIEpQS0kxETAPBgNVBAsMCEJyaWRnZUNBMB4XDTAzMTIyNzA1MDgxNVoXDTEz
-MTIyNjE0NTk1OVowWjELMAkGA1UEBhMCSlAxDTALBgNVBAoMBEpQS0kxKTAnBgNV
-BAsMIFByZWZlY3R1cmFsIEFzc29jaWF0aW9uIEZvciBKUEtJMREwDwYDVQQLDAhC
-cmlkZ2VDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTnUmg7K3m8
-52vd77kwkq156euwoWm5no8E8kmaTSc7x2RABPpqNTlMKdZ6ttsyYrqREeDkcvPL
-yF7yf/I8+innasNtsytcTAy8xY8Avsbd4JkCGW9dyPjk9pzzc3yLQ64Rx2fujRn2
-agcEVdPCr/XpJygX8FD5bbhkZ0CVoiASBmlHOcC3YpFlfbT1QcpOSOb7o+VdKVEi
-MMfbBuU2IlYIaSr/R1nO7RPNtkqkFWJ1/nKjKHyzZje7j70qSxb+BTGcNgTHa1YA
-UrogKB+UpBftmb4ds+XlkEJ1dvwokiSbCDaWFKD+YD4B2s0bvjCbw8xuZFYGhNyR
-/2D5XfN1s2MCAwEAAaOCATkwggE1MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MG0GA1UdHwRmMGQwYqBgoF6kXDBaMQswCQYDVQQGEwJKUDENMAsGA1UE
-CgwESlBLSTEpMCcGA1UECwwgUHJlZmVjdHVyYWwgQXNzb2NpYXRpb24gRm9yIEpQ
-S0kxETAPBgNVBAsMCEJyaWRnZUNBMIGDBgNVHREEfDB6pHgwdjELMAkGA1UEBhMC
-SlAxJzAlBgNVBAoMHuWFrOeahOWAi+S6uuiqjeiovOOCteODvOODk+OCuTEeMBwG
-A1UECwwV6YO96YGT5bqc55yM5Y2U6K2w5LyaMR4wHAYDVQQLDBXjg5bjg6rjg4Pj
-grjoqo3oqLzlsYAwHQYDVR0OBBYEFNQXMiCqQNkR2OaZmQgLtf8mR8p8MA0GCSqG
-SIb3DQEBBQUAA4IBAQATjJo4reTNPC5CsvAKu1RYT8PyXFVYHbKsEpGt4GR8pDCg
-HEGAiAhHSNrGh9CagZMXADvlG0gmMOnXowriQQixrtpkmx0TB8tNAlZptZWkZC+R
-8TnjOkHrk2nFAEC3ezbdK0R7MR4tJLDQCnhEWbg50rf0wZ/aF8uAaVeEtHXa6W0M
-Xq3dSe0XAcrLbX4zZHQTaWvdpLAIjl6DZ3SCieRMyoWUL+LXaLFdTP5WBCd+No58
-IounD9X4xxze2aeRVaiV/WnQ0OSPNS7n7YXy6xQdnaOU4KRW/Lne1EDf5IfWC/ih
-bVAmhZMbcrkWWcsR6aCPG+2mV3zTD6AUzuKPal8Y
+MIIFkjCCA3qgAwIBAgIIAeDltYNno+AwDQYJKoZIhvcNAQEMBQAwZzEbMBkGA1UE
+AwwSQXBwbGUgUm9vdCBDQSAtIEcyMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw
+HhcNMTQwNDMwMTgxMDA5WhcNMzkwNDMwMTgxMDA5WjBnMRswGQYDVQQDDBJBcHBs
+ZSBSb290IENBIC0gRzIxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgREkhI2imKScUcx+xuM23+TfvgHN6s
+XuI2pyT5f1BrTM65MFQn5bPW7SXmMLYFN14UIhHF6Kob0vuy0gmVOKTvKkmMXT5x
+ZgM4+xb1hYjkWpIMBDLyyED7Ul+f9sDx47pFoFDVEovy3d6RhiPw9bZyLgHaC/Yu
+OQhfGaFjQQscp5TBhsRTL3b2CtcM0YM/GlMZ81fVJ3/8E7j4ko380yhDPLVoACVd
+J2LT3VXdRCCQgzWTxb+4Gftr49wIQuavbfqeQMpOhYV4SbHXw8EwOTKrfl+q04tv
+ny0aIWhwZ7Oj8ZhBbZF8+NfbqOdfIRqMM78xdLe40fTgIvS/cjTf94FNcX1RoeKz
+8NMoFnNvzcytN31O661A4T+B/fc9Cj6i8b0xlilZ3MIZgIxbdMYs0xBTJh0UT8TU
+gWY8h2czJxQI6bR3hDRSj4n4aJgXv8O7qhOTH11UL6jHfPsNFL4VPSQ08prcdUFm
+IrQB1guvkJ4M6mL4m1k8COKWNORj3rw31OsMiANDC1CvoDTdUE0V+1ok2Az6DGOe
+HwOx4e7hqkP0ZmUoNwIx7wHHHtHMn23KVDpA287PT0aLSmWaasZobNfMmRtHsHLD
+d4/E92GcdB/O/WuhwpyUgquUoue9G7q5cDmVF8Up8zlYNPXEpMZ7YLlmQ1A/bmH8
+DvmGqmAMQ0uVAgMBAAGjQjBAMB0GA1UdDgQWBBTEmRNsGAPCe8CjoA1/coB6HHcm
+jTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwF
+AAOCAgEAUabz4vS4PZO/Lc4Pu1vhVRROTtHlznldgX/+tvCHM/jvlOV+3Gp5pxy+
+8JS3ptEwnMgNCnWefZKVfhidfsJxaXwU6s+DDuQUQp50DhDNqxq6EWGBeNjxtUVA
+eKuowM77fWM3aPbn+6/Gw0vsHzYmE1SGlHKy6gLti23kDKaQwFd1z4xCfVzmMX3z
+ybKSaUYOiPjjLUKyOKimGY3xn83uamW8GrAlvacp/fQ+onVJv57byfenHmOZ4VxG
+/5IFjPoeIPmGlFYl5bRXOJ3riGQUIUkhOb9iZqmxospvPyFgxYnURTbImHy99v6Z
+SYA7LNKmp4gDBDEZt7Y6YUX6yfIjyGNzv1aJMbDZfGKnexWoiIqrOEDCzBL/FePw
+N983csvMmOa/orz6JopxVtfnJBtIRD6e/J/JzBrsQzwBvDR4yGn1xuZW7AYJNpDr
+FEobXsmII9oDMJELuDY++ee1KG++P+w8j2Ud5cAeh6Squpj9kuNsJnfdBrRkBof0
+Tta6SqoWqPQFZ2aWuuJVecMsXUmPgEkrihLHdoBR37q9ZV0+N0djMenl9MU/S60E
+inpxLK8JQzcPqOMyT/RFtm2XNuyE9QoB6he7hY1Ck3DDUOUUi78/w0EP3SIEIwiK
+um1xRKtzCTrJ+VKACd+66eYWyi4uTLLT3OUEVLLUNIAytbwPF+E=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
-AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
-yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
-38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
-AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
-DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
-HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS
+QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN
+MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS
+b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf
+TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517
+IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA
+MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4
+at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM
+6BgD56KyKA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQU
-YHtmGkUNl8qJUC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
-AQQFAAOCAQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq7
-5bCdPTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q
-gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT2iHR
-rH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlDNPYPhyk7
-ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBgHcl5JLL2bP2o
-Zg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w==
+MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET
+MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0
+MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw
+bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
+FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+
++FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1
+XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w
+tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW
+q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM
+aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3
+R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE
+ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93
+d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl
+IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0
+YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj
+b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp
+Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc
+NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP
+y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7
+R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg
+xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP
+IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX
+UKqK1drk/NAJBzewdXUh
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE
-SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg
-Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV
-BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl
-cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA
-vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu
-Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a
-0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1
-4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN
-eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD
-R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG
-A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu
-dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME
-Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3
-WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
-HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ
-KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO
-Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX
-wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
-2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89
-9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0
-jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38
-aQNiuJkFBT1reBK9sG9l
+MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx
+HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD
+b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv
+b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx
+MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl
+ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0
+aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
+eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e
+eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq
+wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV
+WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO
+2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+
+H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU
+yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
+MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH
+lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB
+MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj
+YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu
+Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl
+cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k
+IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp
+ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz
+aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu
+Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw
+bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG
+SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS
+9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y
+m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv
+Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961
+kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH
+CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
-FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
-uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
-kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
-ewv4n4Q=
+MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG
+A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT
+BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw
+MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw
+YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj
+YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq
+rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo
++rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN
+dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk
+KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq
+0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa
+2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g
+by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG
+EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo
+qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB
+MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs
+B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL
+nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0
+HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m
+Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i
+Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf
+SUJiOxMfFui61/0=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
-MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
-IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
-dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
-li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
-rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
-WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
-F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
-xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
-Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
-dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
-IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
-c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
-ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
-KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
-KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
-y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
-dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
-VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
-fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
-7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
-cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
-mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
-SnQ2+Q==
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
-AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
-FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
-1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
-jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
-wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
-WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
-NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
-uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
-IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
-g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
-9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
-BSeOE6Fuwg==
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
+MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
+VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
+ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
+AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
+661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
+am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
+ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
+PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
+3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
+SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
+3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
+ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
+StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
+Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
+jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
-NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
-b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
-VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
-VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
-7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
-Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
-/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
-81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
-dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
-Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
-sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
-pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
-slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
-arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
-9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
-dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
-0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
-TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
-Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
-Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
-OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
-vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
-t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
-HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
-SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+MIIJmzCCB4OgAwIBAgIBATANBgkqhkiG9w0BAQwFADCCAR4xPjA8BgNVBAMTNUF1
+dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
+YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
+dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
+aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
+IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
+KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyMjE4MDgy
+MVoXDTMwMTIxNzIzNTk1OVowggEeMT4wPAYDVQQDEzVBdXRvcmlkYWQgZGUgQ2Vy
+dGlmaWNhY2lvbiBSYWl6IGRlbCBFc3RhZG8gVmVuZXpvbGFubzELMAkGA1UEBhMC
+VkUxEDAOBgNVBAcTB0NhcmFjYXMxGTAXBgNVBAgTEERpc3RyaXRvIENhcGl0YWwx
+NjA0BgNVBAoTLVNpc3RlbWEgTmFjaW9uYWwgZGUgQ2VydGlmaWNhY2lvbiBFbGVj
+dHJvbmljYTFDMEEGA1UECxM6U3VwZXJpbnRlbmRlbmNpYSBkZSBTZXJ2aWNpb3Mg
+ZGUgQ2VydGlmaWNhY2lvbiBFbGVjdHJvbmljYTElMCMGCSqGSIb3DQEJARYWYWNy
+YWl6QHN1c2NlcnRlLmdvYi52ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAME77xNS8ZlW47RsBeEaaRZhJoZ4rw785UAFCuPZOAVMqNS1wMYqzy95q6Gk
+UO81ER/ugiQX/KMcq/4HBn83fwdYWxPZfwBfK7BP2p/JsFgzYeFP0BXOLmvoJIzl
+Jb6FW+1MPwGBjuaZGFImWZsSmGUclb51mRYMZETh9/J5CLThR1exStxHQptwSzra
+zNFpkQY/zmj7+YZNA9yDoroVFv6sybYOZ7OxNDo7zkSLo45I7gMwtxqWZ8VkJZkC
+8+p0dX6mkhUT0QAV64Zc9HsZiH/oLhEkXjhrgZ28cF73MXIqLx1fyM4kPH1yOJi/
+R72nMwL7D+Sd6mZgI035TxuHXc2/uOwXfKrrTjaJDz8Jp6DdessOkxIgkKXRjP+F
+K3ze3n4NUIRGhGRtyvEjK95/2g02t6PeYiYVGur6ruS49n0RAaSS0/LJb6XzaAAe
+0mmO2evnEqxIKwy2mZRNPfAVW1l3wCnWiUwryBU6OsbFcFFrQm+00wOicXvOTHBM
+aiCVAVZTb9RSLyi+LJ1llzJZO3pq3IRiiBj38Nooo+2ZNbMEciSgmig7YXaUcmud
+SVQvLSL+Yw+SqawyezwZuASbp7d/0rutQ59d81zlbMt3J7yB567rT2IqIydQ8qBW
+k+fmXzghX+/FidYsh/aK+zZ7Wy68kKHuzEw1Vqkat5DGs+VzAgMBAAGjggLeMIIC
+2jASBgNVHRMBAf8ECDAGAQH/AgECMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52
+ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMB0GA1UdDgQWBBStuyIdxuDS
+Aaj9dlBSk+2YwU2u0zCCAVAGA1UdIwSCAUcwggFDgBStuyIdxuDSAaj9dlBSk+2Y
+wU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRpZmlj
+YWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAw
+DgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYD
+VQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25p
+Y2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEgZGUgU2VydmljaW9zIGRlIENl
+cnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG9w0BCQEWFmFjcmFpekBz
+dXNjZXJ0ZS5nb2IudmWCAQEwDgYDVR0PAQH/BAQDAgEGMDcGA1UdEQQwMC6CD3N1
+c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMFQGA1Ud
+HwRNMEswJKAioCCGHmhodHA6Ly93d3cuc3VzY2VydGUuZ29iLnZlL2xjcjAjoCGg
+H4YdbGRhcDovL2FjcmFpei5zdXNjZXJ0ZS5nb2IudmUwNwYIKwYBBQUHAQEEKzAp
+MCcGCCsGAQUFBzABhhtoaHRwOi8vb2NzcC5zdXNjZXJ0ZS5nb2IudmUwQAYDVR0g
+BDkwNzA1BgVghl4BAjAsMCoGCCsGAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRl
+LmdvYi52ZS9kcGMwDQYJKoZIhvcNAQEMBQADggIBAK4qy/zmZ9zBwfW3yOYtLcBT
+Oy4szJyPz7/RhNH3bPVH7HbDTGpi6JZ4YXdXMBeJE5qBF4a590Kgj8Rlnltt+Rbo
+OFQOU1UDqKuTdBsA//Zry5899fmn8jBUkg4nh09jhHHbLlaUScdz704Zz2+UVg7i
+s/r3Legxap60KzmdrmTAE9VKte1TQRgavQwVX5/2mO/J+SCas//UngI+h8SyOucq
+mjudYEgBrZaodUsagUfn/+AzFNrGLy+al+5nZeHb8JnCfLHWS0M9ZyhgoeO/czyn
+99+5G93VWNv4zfc4KiavHZKrkn8F9pg0ycIZh+OwPT/RE2zq4gTazBMlP3ACIe/p
+olkNaOEa8KvgzW96sjBZpMW49zFmyINYkcj+uaNCJrVGsXgdBmkuRGJNWFZ9r0cG
+woIaxViFBypsz045r1ESfYPlfDOavBhZ/giR/Xocm9CHkPRY2BApMMR0DUCyGETg
+Ql+L3kfdTKzuDjUp2DM9FqysQmaM81YDZufWkMhlZPfHwC7KbNougoLroa5Umeos
+bqAXWmk46SwIdWRPLLqbUpDTKooynZKpSYIkkotdgJoVZUUCY+RCO8jsVPEU6ece
+SxztNUm5UOta1OJPMwSAKRHOo3ilVb9c6lAixDdvV8MeNbqe6asM1mpCHWbJ/0rg
+5Ls9Cxx8hracyp0ev7b0
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
-NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
-LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
-A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
-W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
-3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
-6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
-Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
-NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
-r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
-DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
-YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
-/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
-LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
-jVaMaA==
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER
-MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw
-MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu
-aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC
-XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB
-a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD
-Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx
-QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ
-th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC
-AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG
-CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD
-BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d
-SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg
-14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe
-JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU
-LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr
-A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9
-+tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g==
+MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE
+BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw
+WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1
+bSBSb290IENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZzQh6S
+/3UPi790hqc/7bIYLS2X+an7mEoj39WN4IzGMhwWLQdC1i22bi+n9fzGhYJdld61
+IgDMqFNAn68KNaJ6x+HK92AQZw6nUHMXU5WfIp8MXW+2QbyM69odRr2nlL/zGsvU
++40OHjPIltfsjFPekx40HopQcSZYtF3CiInaYNKJIT/e1wEYNm7hLHADBGXvmAYr
+XR5i3FVr/mZkIV/4L+HXmymvb82fqgxG0YjFnaKVn6w/Fa7yYd/vw2uaItgscf1Y
+HewApDgglVrH1Tdjuk+bqv5WRi5j2Qsj1Yr6tSPwiRuhFA0m2kHwOI8w7QUmecFL
+TqG4flVSOmlGhHUCAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4CQEBMC4wLAYIKwYBBQUHAgEWIGh0dHA6
+Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBSFiuv0xbu+DlkD
+lN7WgAEV4xCcOTARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUhYrr9MW7
+vg5ZA5Te1oABFeMQnDkwDQYJKoZIhvcNAQEFBQADggEBAFHYhd27V2/MoGy1oyCc
+UwnzSgEMdL8rs5qauhjyC4isHLMzr87lEwEnkoRYmhC598wUkmt0FoqW6FHvv/pK
+JaeJtmMrXZRY0c8RcrYeuTlBFk0pvDVTC9rejg7NqZV3JcqUWumyaa7YwBO+mPyW
+nIR/VRPmPIfjvCCkpDZoa01gZhz5v6yAlGYuuUGK02XThIAC71AdXkbc98m6tTR8
+KvPG2F9fVJ3bTc0R5/0UAoNmXsimABKgX77OFP67H6dh96tK8QYUn8pJQsKpvO2F
+sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO
+hXY=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
-ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
-aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
-ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
-NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
-A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
-VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
-SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
-VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
-w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
-mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
-4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
-4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
-EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
-SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
-ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
-vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
-hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
-Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
-/L7fCg0=
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIQWAsFbFMk27JQVxhf+eWmUDANBgkqhkiG9w0BAQUFADAn
-MQswCQYDVQQGEwJCRTEYMBYGA1UEAxMPQmVsZ2l1bSBSb290IENBMB4XDTAzMDEy
-NjIzMDAwMFoXDTE0MDEyNjIzMDAwMFowJzELMAkGA1UEBhMCQkUxGDAWBgNVBAMT
-D0JlbGdpdW0gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AMihcekcRkJ5eHFvna6pqKsot03HIOswkVp19eLSz8hMFJhCWK3HEcVAQGpa+XQS
-J4fpnOVxTiIs0RIYqjBeoiG52bv/9nTrMQHnO35YD5EWTXaJqAFPrSJmcPpLHZXB
-MFjqvNll2Jq0iOtJRlLf0lMVdssUXRlJsW9q09P9vMIt7EU/CT9YvvzU7wCMgTVy
-v/cY6pZifSsofxVsY9LKyn0FrMhtB20yvmi4BUCuVJhWPmbxMOjvxKuTXgfeMo8S
-dKpbNCNUwOpszv42kqgJF+qhLc9s44Qd3ocuMws8dOIhUDiVLlzg5cYx+dtA+mqh
-pIqTm6chBocdJ9PEoclMsG8CAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4AQEBMC4wLAYIKwYBBQUHAgEW
-IGh0dHA6Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBQQ8AxW
-m2HqVzq2NZdtn925FI7b5jARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAU
-EPAMVpth6lc6tjWXbZ/duRSO2+YwDQYJKoZIhvcNAQEFBQADggEBAMhtIlGKYfgP
-lm7VILKB+MbcoxYA2s1q52sq+llIp0xJN9dzoWoBZV4yveeX09AuPHPTjHuD79ZC
-wT+oqV0PN7p20kC9zC0/00RBSZz9Wyn0AiMiW3Ebv1jZKE4tRfTa57VjRUQRDSp/
-M382SbTObqkCMa5c/ciJv0J71/Fg8teH9lcuen5qE4Ad3OPQYx49cTGxYNSeCMqr
-8JTHSHVUgfMbrXec6LKP24OsjzRr6L/D2fVDw2RV6xq9NoY2uiGMlxoh1OotO6y6
-7Kcdq765Sps1LxxcHVGnH1TtEpf/8m6HfUbJdNbv6z195lluBpQE5KJVhzgoaiJe
-4r50ErAEQyo=
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
-Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
-ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
-MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
-yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
-VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
-nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
-XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
-vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
-Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
-N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
-nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
+MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
+D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
+OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
+fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
+IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
+oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
+/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
+rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
+3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
+7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
+yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
+qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
+hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
+xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
+SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
+HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
+emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
+AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
+7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
+DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
+F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
+a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
+Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
+BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
+Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
+cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
+aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
+F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
+8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
+rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
+/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
+7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
+28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
+lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
+nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
+0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
+5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
+WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
+jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
+KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
+ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
+OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
+619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
+2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
+o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
+nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
+5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
+pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
+dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
+BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb
+BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz
+MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx
+FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g
+Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2
+fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl
+LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV
+WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF
+TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb
+5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc
+CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri
+wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ
+wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG
+m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4
+F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng
+WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0
+2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/
+0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw
+F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS
+g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj
+qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN
+h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/
+ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V
+btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj
+Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ
+8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW
+gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
+jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
+ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
+ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
+Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
+AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
+HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
+uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
+TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
+xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
+CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
+O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
+6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
+gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
+A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
+OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
+VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
+b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
+DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
+0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
+OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
+fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
+Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
+o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
+sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
+OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
+Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
+adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
+3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
+F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
+CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
+XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
+djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
+WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
+AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
+P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
+b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
+XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
+5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
+DrW5viSP
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
+TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
+MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
+aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
+T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
+sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
+TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
+/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
+7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
+EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
+hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
+a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
+aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
+TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
+PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
+cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
+tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
+BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
+ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
+jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
+ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
+P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
+xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
+Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
+5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
+/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
+AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
+5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
+IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
+MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
+dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
+EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
+MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
+28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
+VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
+DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
+5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
+ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
+Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
+UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
+Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
+ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
+hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
+HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
+YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
+L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
+ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
+IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
+HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
+DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
+PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
+5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
+glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
+FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
+pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
+xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
+tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
+jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
+fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
+OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
+d0jQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
+b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
+MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
+ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
+IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
+AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
+unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
+BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
+7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
+0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
+roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
+A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
+aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
+26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
+BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
+EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
+BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
+aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
+AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
+p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
+1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
+XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
+eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
+tGWaIZDgqtCYvDi1czyL+Nw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1
+MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB
+IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK
+Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg
+MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH
+xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ
+FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q
+VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH
+jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l
+Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED
+o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI
+FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF
+BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW
+Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX
+cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz
+Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4
+CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId
+kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
+PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
+cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
+MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
+IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
+ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
+VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
+kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
+EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
+H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
+HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
+DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
+QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
+Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
+AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
+yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
+FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
+ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
+kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgIQKTZHquOKrIZKI1byyrdhrzANBgkqhkiG9w0BAQUFADBO
+MQswCQYDVQQGEwJ1czEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQ0wCwYDVQQL
+EwRGQkNBMRYwFAYDVQQDEw1Db21tb24gUG9saWN5MB4XDTA3MTAxNTE1NTgwMFoX
+DTI3MTAxNTE2MDgwMFowTjELMAkGA1UEBhMCdXMxGDAWBgNVBAoTD1UuUy4gR292
+ZXJubWVudDENMAsGA1UECxMERkJDQTEWMBQGA1UEAxMNQ29tbW9uIFBvbGljeTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeNvTMn5K1b+3i9L0dHbsd4
+6ZOcpN7JHP0vGzk4rEcXwH53KQA7Ax9oD81Npe53uCxiazH2+nIJfTApBnznfKM9
+hBiKHa4skqgf6F5PjY7rPxr4nApnnbBnTfAu0DDew5SwoM8uCjR/VAnTNr2kSVdS
+c+md/uRIeUYbW40y5KVIZPMiDZKdCBW/YDyD90ciJSKtKXG3d+8XyaK2lF7IMJCk
+FEhcVlcLQUwF1CpMP64Sm1kRdXAHImktLNMxzJJ+zM2kfpRHqpwJCPZLr1LoakCR
+xVW9QLHIbVeGlRfmH3O+Ry4+i0wXubklHKVSFzYIWcBCvgortFZRPBtVyYyQd+sC
+AwEAAaN7MHkwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFC9Yl9ipBZilVh/72at17wI8NjTHMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJ
+KwYBBAGCNxUCBBYEFHa3YJbdFFYprHWF03BjwbxHhhyLMA0GCSqGSIb3DQEBBQUA
+A4IBAQBgrvNIFkBypgiIybxHLCRLXaCRc+1leJDwZ5B6pb8KrbYq+Zln34PFdx80
+CTj5fp5B4Ehg/uKqXYeI6oj9XEWyyWrafaStsU+/HA2fHprA1RRzOCuKeEBuMPdi
+4c2Z/FFpZ2wR3bgQo2jeJqVW/TZsN5hs++58PGxrcD/3SDcJjwtCga1GRrgLgwb0
+Gzigf0/NC++DiYeXHIowZ9z9VKEDfgHLhUyxCynDvux84T8PCVI8L6eaSP436REG
+WOE2QYrEtr+O3c5Ks7wawM36GpnScZv6z7zyxFSjiDV2zBssRm8MtNHDYXaSdBHq
+S4CNHIkRi+xb/xfJSPzn4AYR4oRe
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0
+MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG
+EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT
+CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK
+8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2
+98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb
+2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC
+ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi
+Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB
+o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl
+ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD
+AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL
+AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd
+foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M
+cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq
+8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp
+hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk
+Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
+AGegcQCCSA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw
+RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t
+U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx
+MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV
+BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3
+3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs
+3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4
+O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W
+igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X
+O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx
+46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU
+b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf
+5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut
+TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf
+woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID
+AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0
+dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh
+LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln
+bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY
+DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ
+sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj
+kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9
+SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL
+dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm
+WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J
+kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv
+hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C
+BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS
+Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i
+2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB
+VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3
+DscLP1I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
+PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
+MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
+GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
+MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
+HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
+gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
+v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
+Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
+9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
+6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
+MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
+Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
+ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
+hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
+iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
+dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
+kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
+hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
+OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
@@ -938,133 +1246,614 @@
 KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
-jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
-0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
-2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
-ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
-y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
-tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
-6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
-uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
-acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
-k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
-VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
-BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
-b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
-fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
-/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
-REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
-srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
-aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
-woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
-Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
-t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
-8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
-9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
-wSsSnqaeG8XmDtkx2Q==
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
+MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
+IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
+IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
+RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
+U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
+IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
+ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
+QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
+rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
+NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
+QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
+txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
+BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
+tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
+IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
+6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB
-lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt
-T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV
-BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc
-BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3
-dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP
-HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO
-KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo
-5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+
-pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb
-kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC
-AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov
-L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV
-HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN
-AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
-NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB
-mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU
-4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5
-81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR
-Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE
-BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw
-WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1
-bSBSb290IENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZzQh6S
-/3UPi790hqc/7bIYLS2X+an7mEoj39WN4IzGMhwWLQdC1i22bi+n9fzGhYJdld61
-IgDMqFNAn68KNaJ6x+HK92AQZw6nUHMXU5WfIp8MXW+2QbyM69odRr2nlL/zGsvU
-+40OHjPIltfsjFPekx40HopQcSZYtF3CiInaYNKJIT/e1wEYNm7hLHADBGXvmAYr
-XR5i3FVr/mZkIV/4L+HXmymvb82fqgxG0YjFnaKVn6w/Fa7yYd/vw2uaItgscf1Y
-HewApDgglVrH1Tdjuk+bqv5WRi5j2Qsj1Yr6tSPwiRuhFA0m2kHwOI8w7QUmecFL
-TqG4flVSOmlGhHUCAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4CQEBMC4wLAYIKwYBBQUHAgEWIGh0dHA6
-Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBSFiuv0xbu+DlkD
-lN7WgAEV4xCcOTARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUhYrr9MW7
-vg5ZA5Te1oABFeMQnDkwDQYJKoZIhvcNAQEFBQADggEBAFHYhd27V2/MoGy1oyCc
-UwnzSgEMdL8rs5qauhjyC4isHLMzr87lEwEnkoRYmhC598wUkmt0FoqW6FHvv/pK
-JaeJtmMrXZRY0c8RcrYeuTlBFk0pvDVTC9rejg7NqZV3JcqUWumyaa7YwBO+mPyW
-nIR/VRPmPIfjvCCkpDZoa01gZhz5v6yAlGYuuUGK02XThIAC71AdXkbc98m6tTR8
-KvPG2F9fVJ3bTc0R5/0UAoNmXsimABKgX77OFP67H6dh96tK8QYUn8pJQsKpvO2F
-sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO
-hXY=
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
-DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
-ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
-b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
-qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
-uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
-Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
-pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
-5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
-UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
-GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
-5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
-6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
-eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
-B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
-BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
-L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
-SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
-CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
-5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
-IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
-gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
-+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
-vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
-bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
-N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
-Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
-ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
-8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
-hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
-KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
-515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
-xwy8p2Fp8fc74SrL+SvzZpA3
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
+ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
+MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
+VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
+FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
+ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
+gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
+fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
+ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
+ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
+c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
+dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
+aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
+hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
+QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
+h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
+nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
+rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
+9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDOzCCAiOgAwIBAgIRANAeRlAAACmMAAAAAgAAAAIwDQYJKoZIhvcNAQEFBQAw
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYNDAeFw0wMDA5MTMwNjIyNTBaFw0yMDA5MTMwNjIyNTBa
+MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UE
+AxMORFNUIFJvb3QgQ0EgWDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCthX3OFEYY8gSeIYur0O4ypOT68HnDrjLfIutL5PZHRwQGjzCPb9PFo/ihboJ8
+RvfGhBAqpQCo47zwYEhpWm1jB+L/OE/dBBiyn98krfU2NiBKSom2J58RBeAwHGEy
+cO+lewyjVvbDDLUy4CheY059vfMjPAftCRXjqSZIolQb9FdPcAoa90mFwB7rKniE
+J7vppdrUScSS0+eBrHSUPLdvwyn4RGp+lSwbWYcbg5EpSpE0GRJdchic0YDjvIoC
+YHpe7Rkj93PYRTQyU4bhC88ck8tMqbvRYqMRqR+vobbkrj5LLCOQCHV5WEoxWh+0
+E2SpIFe7RkV++MmpIAc0h1tZAgMBAAGjMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFPCD6nPIP1ubWzdf9UyPWvf0hki9MA0GCSqGSIb3DQEBBQUAA4IBAQCE
+G85wl5eEWd7adH6XW/ikGN5salvpq/Fix6yVTzE6CrhlP5LBdkf6kx1bSPL18M45
+g0rw2zA/MWOhJ3+S6U+BE0zPGCuu8YQaZibR7snm3HiHUaZNMu5c8D0x0bcMxDjY
+AVVcHCoNiL53Q4PLW27nbY6wwG0ffFKmgV3blxrYWfuUDgGpyPwHwkfVFvz9qjaV
+mf12VJffL6W8omBPtgteb6UaT/k1oJ7YI0ldGf+ngpVbRhD+LC3cUtT6GO/BEPZu
+8YTV/hbiDH5v3khVqMIeKT6o8IuXGG7F6a6vKwP1F1FwTXf4UC/ivhme7vdUH7B/
+Vv4AEbT8dNfEeFxrkDbh
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
+BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
+aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
+BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
+Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
+MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
+em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
+B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
+D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
+Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
+q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
+k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
+fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
+dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
+ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
+zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
+U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
+Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
+XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
+Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
+HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
+GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
+77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
+vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
+FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
+yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
+AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
+y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
+NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex
+EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj
+aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp
+Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa
+Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
+bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp
+b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj
+aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA
+utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6
+Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/
+KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA
+byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR
+k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP
+ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j
+BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC
+Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT
+FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH
+MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv
+cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/
+0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE
+7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74
+HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56
+QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+
+A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq
+zIzvO2jHyu9PQqo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
+MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
+czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
+CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
+MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
+ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
+b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
+euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
+bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
+WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
+MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
+1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
+zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
+BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
+BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
+v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
+E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
+uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
+iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
+GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
+MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
+vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
+CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
+WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
+oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
+h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
+f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
+B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
+vUxFnmG6v4SBkgPR0ml8xQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEYDCCA0igAwIBAgICATAwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCVVMx
+GDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UE
+AxMYRmVkZXJhbCBDb21tb24gUG9saWN5IENBMB4XDTEwMTIwMTE2NDUyN1oXDTMw
+MTIwMTE2NDUyN1owWTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJu
+bWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UEAxMYRmVkZXJhbCBDb21tb24gUG9s
+aWN5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2HX7NRY0WkG/
+Wq9cMAQUHK14RLXqJup1YcfNNnn4fNi9KVFmWSHjeavUeL6wLbCh1bI1FiPQzB6+
+Duir3MPJ1hLXp3JoGDG4FyKyPn66CG3G/dFYLGmgA/Aqo/Y/ISU937cyxY4nsyOl
+4FKzXZbpsLjFxZ+7xaBugkC7xScFNknWJidpDDSPzyd6KgqjQV+NHQOGgxXgVcHF
+mCye7Bpy3EjBPvmE0oSCwRvDdDa3ucc2Mnr4MrbQNq4iGDGMUHMhnv6DOzCIJOPp
+wX7e7ZjHH5IQip9bYi+dpLzVhW86/clTpyBLqtsgqyFOHQ1O5piF5asRR12dP8Qj
+wOMUBm7+nQIDAQABo4IBMDCCASwwDwYDVR0TAQH/BAUwAwEB/zCB6QYIKwYBBQUH
+AQsEgdwwgdkwPwYIKwYBBQUHMAWGM2h0dHA6Ly9odHRwLmZwa2kuZ292L2ZjcGNh
+L2NhQ2VydHNJc3N1ZWRCeWZjcGNhLnA3YzCBlQYIKwYBBQUHMAWGgYhsZGFwOi8v
+bGRhcC5mcGtpLmdvdi9jbj1GZWRlcmFsJTIwQ29tbW9uJTIwUG9saWN5JTIwQ0Es
+b3U9RlBLSSxvPVUuUy4lMjBHb3Zlcm5tZW50LGM9VVM/Y0FDZXJ0aWZpY2F0ZTti
+aW5hcnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUrQx6dVzl85jEeZgOrCj9l/TnAvwwDQYJKoZIhvcNAQELBQAD
+ggEBAI9z2uF/gLGH9uwsz9GEYx728Yi3mvIRte9UrYpuGDco71wb5O9Qt2wmGCMi
+TR0mRyDpCZzicGJxqxHPkYnos/UqoEfAFMtOQsHdDA4b8Idb7OV316rgVNdF9IU+
+7LQd3nyKf1tNnJaK0KIyn9psMQz4pO9+c+iR3Ah6cFqgr2KBWfgAdKLI3VTKQVZH
+venAT+0g3eOlCd+uKML80cgX2BLHb94u6b2akfI8WpQukSKAiaGMWMyDeiYZdQKl
+Dn0KJnNR6obLB6jI/WNaNZvSr79PMUjBhHDbNXuaGQ/lj/RqDG8z2esccKIN47lQ
+A2EC/0rskqTcLe4qNJMHtyznGI8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
+NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
+BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
+So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
+tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
+CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
+qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
+rD6ogRLQy7rQkgu2npaqBA+K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
+MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
+BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
+MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
+BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
+hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
+5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
+JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
+DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
+huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
+HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
+AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
+zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
+kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
+AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
+SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
+spki4cErx5z481+oghLrGREt
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
+MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
+AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
+ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
+7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
+kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
+mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
+KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
+6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
+4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
+oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
+UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
+AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
@@ -1108,342 +1897,663 @@
 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF3zCCA8egAwIBAgIOGTMAAQACKBqaBLzyVUUwDQYJKoZIhvcNAQEFBQAwejEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
-BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUGA1UEAxMeVEMgVHJ1
-c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMB4XDTA2MDMyMjE1NTgzNFoXDTMwMTIz
-MTIyNTk1OVowejELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVy
-IEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUG
-A1UEAxMeVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMIICIjANBgkqhkiG
-9w0BAQEFAAOCAg8AMIICCgKCAgEAi9R3azRs5TbYalxeOO781R15Azt7g2JEgk6I
-7d6D/+7MUGIFBZWZdpj2ufJf2AaRksL2LWYXH/1TA+iojWOpbuHWG4y8mLOLO9Tk
-Lsp9hUkmW3m4GotAnn+7yT9jLM/RWny6KCJBElpN+Rd3/IX9wkngKhh/6aAsnPlE
-/AxoOUL1JwW+jhV6YJ3wO8c85j4WvK923mq3ouGrRkXrjGV90ZfzlxElq1nroCLZ
-gt2Y7X7i+qBhCkoy3iwX921E6oFHWZdXNwM53V6CItQzuPomCba8OYgvURVOm8M7
-3xOCiN1LNPIz1pDp81PcNXzAw9l8eLPNcD+NauCjgUjkKa1juPD8KGQ7mbN9/pqd
-iPaZIgiRRxaJNXhdd6HPv0nh/SSUK2k2e+gc5iqQilvVOzRZQtxtz7sPQRxVzfUN
-Wy4WIibvYR6X/OJTyM9bo8ep8boOhhLLE8oVx+zkNo3aXBM9ZdIOXXB03L+PemrB
-Lg/Txl4PK1lszGFs/sBhTtnmT0ayWuIZFHCE+CAA7QGnl37DvRJckiMXoKUdRRcV
-I5qSCLUiiI3cKyTr4LEXaNOvYb3ZhXj2jbp4yjeNY77nrB/fpUcJucglMVRGURFV
-DYlcjdrSGC1z8rjVJ/VIIjfRYvd7Dcg4i6FKsPzQ8eu3hmPn4A5zf/1yUbXpfeJV
-BWR4Z38CAwEAAaNjMGEwHwYDVR0jBBgwFoAUzdeQoW6jv9sw1toyJZAM5jkegGUw
-DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFM3XkKFu
-o7/bMNbaMiWQDOY5HoBlMA0GCSqGSIb3DQEBBQUAA4ICAQB+FojoEw42zG4qhQc4
-xlaJeuNHIWZMUAgxWlHQ/KZeFHXeTDvs8e3MfhEHSmHu6rOOOqQzxu2KQmZP8Tx7
-yaUFQZmx7Cxb7tyW0ohTS3g0uW7muw/FeqZ8Dhjfbw90TNGp8aHp2FRkzF6WeKJW
-GsFzshXGVwXf2vdIJIqOf2qp+U3pPmrOYCx9LZAI9mOPFdAtnIz/8f38DBZQVhT7
-upeG7rRJA1TuG1l/MDoCgoYhrv7wFfLfToPmmcW6NfcgkIw47XXP4S73BDD7Ua2O
-giRAyn0pXdXZ92Vk/KqfdLh9kl3ShCngE+qK99CrxK7vFcXCifJ7tjtJmGHzTnKR
-N4xJkunI7Cqg90lufA0kxmts8jgvynAF5X/fxisrgIDV2m/LQLvYG/AkyRDIRAJ+
-LtOYqqIN8SvQ2vqOHP9U6OFKbt2o1ni1N6WsZNUUI8cOpevhCTjXwHxgpV2Yj4wC
-1dxWqPNNWKkL1HxkdAEy8t8PSoqpAqKiHYR3wvHMl700GXRd4nQ+dSf3r7/ufA5t
-VIimVuImrTESPB5BeW0X6hNeH/Vcn0lZo7Ivo0LD+qh+v6WfSMlgYmIK371F3uNC
-tVGW/cT1Gpm4UqJEzS1hjBWPgdVdotSQPYxuQGHDWV3Y2eH2dEcieXR92sqjbzcV
-NvAsGnE8EXbfXRo+VGN4a2V+Hw==
+MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
+YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
+MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
+NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
+A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
+A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
+Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
+QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
+eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
+B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
+z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
+AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
+ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
+TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
+MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
+VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
+VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
+bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
+AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
+bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
+ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
+VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
+ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
+AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
-m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
-FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
-TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
-EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
-kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
-HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
-vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
-19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
-L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
-bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
-JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
-BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
-K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
-ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
-Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
-sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
-3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
-ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
-mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
-b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
-rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
-hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
-zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
-MBr1mmz0DlP5OlvRHA==
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
-kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
-IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
-EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
-VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
-dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
-E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
-D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
-4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
-lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
-bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
-o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
-MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
-LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
-BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
-AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
-j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
-KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
-2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
-mfnGV/TJVTl4uix5yaaIK/QI
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
+FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
+uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
+kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
+ewv4n4Q=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEBDCCAuygAwIBAgIIGHqpqMKWIQwwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
-BhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTEy
-MDIwMTIyMTIxNVoXDTI3MDIwMTIyMTIxNVoweTEtMCsGA1UEAwwkRGV2ZWxvcGVy
-IElEIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSYwJAYDVQQLDB1BcHBsZSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE
-BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJdk8GW5pB7qUj
-KwKjX9dzP8A1sIuECj8GJH+nlT/rTw6Tr7QO0Mg+5W0Ysx/oiUe/1wkI5P9WmCkV
-55SduTWjCs20wOHiYPTK7Cl4RWlpYGtfipL8niPmOsIiszFPHLrytjRZQu6wqQID
-GJEEtrN4LjMfgEUNRW+7Dlpbfzrn2AjXCw4ybfuGNuRsq8QRinCEJqqfRNHxuMZ7
-lBebSPcLWBa6I8WfFTl+yl3DMl8P4FJ/QOq+rAhklVvJGpzlgMofakQcbD7EsCYf
-Hex7r16gaj1HqVgSMT8gdihtHRywwk4RaSaLy9bQEYLJTg/xVnTQ2QhLZniiq6yn
-4tJMh1nJAgMBAAGjgaYwgaMwHQYDVR0OBBYEFFcX7aLP3HyYoRDg/L6HLSzy4xdU
-MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/
-CF4wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5j
-cmwwDgYDVR0PAQH/BAQDAgGGMBAGCiqGSIb3Y2QGAgYEAgUAMA0GCSqGSIb3DQEB
-CwUAA4IBAQBCOXRrodzGpI83KoyzHQpEvJUsf7xZuKxh+weQkjK51L87wVA5akR0
-ouxbH3Dlqt1LbBwjcS1f0cWTvu6binBlgp0W4xoQF4ktqM39DHhYSQwofzPuAHob
-tHastrW7T9+oG53IGZdKC1ZnL8I+trPEgzrwd210xC4jUe6apQNvYPSlSKcGwrta
-4h8fRkV+5Jf1JxC3ICJyb3LaxlB1xT0lj12jAOmfNoxIOY+zO+qQgC6VmmD0eM70
-DgpTPqL6T9geroSVjTK8Vk2J6XgY4KyaQrp6RhuEoonOFOiI0ViL9q5WxCwFKkWv
-C9lLqQIPNKyIx2FViUTJJ3MH7oLlTvVw
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
-IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
-cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
-MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
-bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
-DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
-WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
-Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
-HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
-z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
-SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
-AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
-KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
-AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
-BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
-VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
-ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
-ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
-/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
-A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
-k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
-iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
-2G0xffX8oRAHh84vWdw+WNs=
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIICqDCCAi2gAwIBAgIQIW4zpcvTiKRvKQe0JzzE2DAKBggqhkjOPQQDAzCBlDEL
-MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
-VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
-bGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
-RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
-VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
-bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAxIFB1
-YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
-hkjOPQIBBgUrgQQAIgNiAATXZrUb266zYO5G6ohjdTsqlG3zXxL24w+etgoUU0hS
-yNw6s8tIICYSTvqJhNTfkeQpfSgB2dsYQ2mhH7XThhbcx39nI9/fMTGDAzVwsUu3
-yBe7UcvclBfb6gk7dhLeqrWjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRlwI0l9Qy6l3eQP54u4Fr1ztXh5DAKBggqhkjOPQQD
-AwNpADBmAjEApa7jRlP4mDbjIvouKEkN7jB+M/PsP3FezFWJeJmssv3cHFwzjim5
-axfIEWi13IMHAjEAnMhE2mnCNsNUGRCFAtqdR+9B52wmnQk9922Q0QVEL7C8g5No
-8gxFSTm/mQQc0xCg
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
-BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
-c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
-MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
-R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
-VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
-JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
-fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
-jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
-wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
-fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
-VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
-CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
-7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
-8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
-ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
-ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
-2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDtjCCAp6gAwIBAgIOBcAAAQACQdAGCk3OdRAwDQYJKoZIhvcNAQEFBQAwdjEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
-BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDQgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
-Q2VudGVyIENsYXNzIDQgQ0EgSUkwHhcNMDYwMzIzMTQxMDIzWhcNMjUxMjMxMjI1
-OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
-SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQTElMCMGA1UEAxMc
-VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBALXNTJytrlG7fEjFDSmGehSt2VA9CXIgDRS2Y8b+WJ7gIV7z
-jyIZ3E6RIM1viCmis8GsKnK6i1S4QF/yqvhDhsIwXMynXX/GCEnkDjkvjhjWkd0j
-FnmA22xIHbzB3ygQY9GB493fL3l1oht48pQB5hBiecugfQLANIJ7x8CtHUzXapZ2
-W78mhEj9h/aECqqSB5lIPGG8ToVYx5ct/YFKocabEvVCUNFkPologiJw3fX64yhC
-L04y87OjNopq1mJcrPoBbbTgci6VaLTxkwzGioLSHVPqfOA/QrcSWrjN2qUGZ8uh
-d32llvCSHmcOHUJG5vnt+0dTf1cERh9GX8eu4I8CAwEAAaNCMEAwDwYDVR0TAQH/
-BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFB/quz4lGwa9pd1iBX7G
-TFq/6A9DMA0GCSqGSIb3DQEBBQUAA4IBAQBYpCubTPfkpJKknGWYGWIi/HIy6QRd
-xMRwLVpG3kxHiiW5ot3u6hKvSI3vK2fbO8w0mCr3CEf/Iq978fTr4jgCMxh1KBue
-dmWsiANy8jhHHYz1nwqIUxAUu4DlDLNdjRfuHhkcho0UZ3iMksseIUn3f9MYv5x5
-+F0IebWqak2SNmy8eesOPXmK2PajVnBd3ttPedJ60pVchidlvqDTB4FAVd0Qy+BL
-iILAkH0457+W4Ze6mqtCD9Of2J4VMxHL94J59bXAQVaS4d9VA61Iz9PyLrHHLVZM
-ZHQqMc7cdalUR6SnQnIJ5+ECpkeyBM1CE+FhDOB4OiIgohxgQoaH96Xm
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
-MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
-VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
-CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
-tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
-dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
-PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
-+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
-BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
-ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
-IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
-7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
-43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
-eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
-pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
-WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw
+PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla
+MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX
+eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW
+juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl
+ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0
+eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH
+cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg
+OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K
+mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq
+s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK
+4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP
+isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J
+89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR
+T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe
+Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5
+ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N
+vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf
+hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl
+wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g
+pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn
+uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t
+DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s
+iTTa9g3nkagQ6hed8vbs
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
-bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
-MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
-ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
-hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
-1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
-OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
-2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
-O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
-AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
-BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
-Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
-LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
-oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
-MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
-sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
+RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
+YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
+NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
+EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
+cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
+dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
+fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
+bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
+75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
+FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
+HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
+5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
+b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
+A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
+6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
+dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
+Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
+l7WdmplNsDz4SgCbZN2fOUvRJ9e4
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
-RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
-UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
-Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
-ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
-xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
-ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
-DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
-jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
-CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
-EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
-fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
-uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
-chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
-9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
-ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
-SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
-+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
-fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
-sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
-cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
-0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
-4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
-r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
-/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
-gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
+FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
+Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
+A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
+b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
+jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
+PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
+ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
+nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
+q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
+MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
+mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
+7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
+oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
+EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
+fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
+AmvZWg==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET
-MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv
-biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0
-MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw
-bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
-FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+
-+FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1
-XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w
-tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW
-q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM
-aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E
-BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3
-R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE
-ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93
-d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl
-IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0
-YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj
-b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp
-Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc
-NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP
-y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7
-R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg
-xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP
-IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX
-UKqK1drk/NAJBzewdXUh
+MIIFHjCCBAagAwIBAgIEAKA3oDANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMC
+Q1oxOjA4BgNVBAMMMUkuQ0EgLSBRdWFsaWZpZWQgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHksIDA5LzIwMDkxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBh
+dXRvcml0YSwgYS5zLjE9MDsGA1UECww0SS5DQSAtIEFjY3JlZGl0ZWQgUHJvdmlk
+ZXIgb2YgQ2VydGlmaWNhdGlvbiBTZXJ2aWNlczAeFw0wOTA5MDEwMDAwMDBaFw0x
+OTA5MDEwMDAwMDBaMIG3MQswCQYDVQQGEwJDWjE6MDgGA1UEAwwxSS5DQSAtIFF1
+YWxpZmllZCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgMDkvMjAwOTEtMCsGA1UE
+CgwkUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRhLCBhLnMuMT0wOwYDVQQL
+DDRJLkNBIC0gQWNjcmVkaXRlZCBQcm92aWRlciBvZiBDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTaEy0KC8M9l
+4lSaWHMs4+sVV1LwzyJYiIQNeCrv1HHm/YpGIdY/Z640ceankjQvIX7m23BK4OSC
+6KO8kZYA3zopOz6GFCOKV2PvLukbc+c2imF6kLHEv6qNA8WxhPbR3xKwlHDwB2yh
+Wzo7V3QVgDRG83sugqQntKYC3LnlTGbJpNP+Az72gpO9AHUn/IBhFk4ksc8lYS2L
+9GCy9CsmdKSBP78p9w8Lx7vDLqkDgt1/zBrcUWmSSb7AE/BPEeMryQV1IdI6nlGn
+BhWkXOYf6GSdayJw86btuxC7viDKNrbp44HjQRaSxnp6O3eto1x4DfiYdw/YbJFe
+7EjkxSQBywIDAQABo4IBLjCCASowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwgecGA1UdIASB3zCB3DCB2QYEVR0gADCB0DCBzQYIKwYBBQUHAgIwgcAa
+gb1UZW50byBjZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28ga3ZhbGlmaWtvdmFueSBz
+eXN0ZW1vdnkgY2VydGlmaWthdCBwb2RsZSB6YWtvbmEgYy4gMjI3LzIwMDAgU2Iu
+IHYgcGxhdG5lbSB6bmVuaS9UaGlzIGlzIHF1YWxpZmllZCBzeXN0ZW0gY2VydGlm
+aWNhdGUgYWNjb3JkaW5nIHRvIEN6ZWNoIEFjdCBOby4gMjI3LzIwMDAgQ29sbC4w
+HQYDVR0OBBYEFHnL0CPpOmdwkXRP01Hi4CD94Sj7MA0GCSqGSIb3DQEBCwUAA4IB
+AQB9laU214hYaBHPZftbDS/2dIGLWdmdSbj1OZbJ8LIPBMxYjPoEMqzAR74tw96T
+i6aWRa5WdOWaS6I/qibEKFZhJAVXX5mkx2ewGFLJ+0Go+eTxnjLOnhVF2V2s+57b
+m8c8j6/bS6Ij6DspcHEYpfjjh64hE2r0aSpZDjGzKFM6YpqsCJN8qYe2X1qmGMLQ
+wvNdjG+nPzCJOOuUEypIWt555ZDLXqS5F7ZjBjlfyDZjEfS2Es9Idok8alf563Mi
+9/o+Ba46wMYOkk3P1IlU0RqCajdbliioACKDztAqubONU1guZVzV8tuMASVzbJeL
+/GAB7ECTwe1RuKrLYtglMKI9
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
-Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
-Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
-aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
-Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
-SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
-aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
-ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
-7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
-DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
-zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
-hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
-4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
-gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
-NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
-j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
-52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
-echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
-ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
-zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
-wy39FCqQmbkHzJ8=
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
+VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
+MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
+MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
+ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
+RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
+bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
+/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
+3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
+EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
+9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
+GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
+2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
+WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
+W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
+AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
+DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
+TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
+lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
+mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
+WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
+tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
+GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
+8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXzCCA0egAwIBAgIBATANBgkqhkiG9w0BAQUFADCB0DELMAkGA1UEBhMCRVMx
+SDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMuVml0
+b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwgTWVk
+aXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6MRMw
+EQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5wZS5j
+b20wHhcNMDMwMTMwMjMwMDAwWhcNMTgwMTMwMjMwMDAwWjCB0DELMAkGA1UEBhMC
+RVMxSDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMu
+Vml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwg
+TWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6
+MRMwEQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5w
+ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1btoCXXhp3xIW
+D+Bxl8nUCxkyiazWfpt0e68t+Qt9+lZjKZSdEw2Omj4qvr+ovRmDXO3iWpWVOWDl
+3JHJjAzFCe8ZEBNDH+QNYwZHmPBaMYFOYFdbAFVHWvys152C308hcFJ6xWWGmjvl
+2eMiEl9P2nR2LWue368DCu+ak7j3gjAXaCOdP1a7Bfr+RW3X2SC5R4Xyp8iHlL5J
+PHJD/WBkLrezwzQPdACw8m9EG7q9kUwlNpL32mROujS3ZkT6mQTzJieLiE3X04s0
+uIUqVkk5MhjcHFf7al0N5CzjtTcnXYJKN2Z9EDVskk4olAdGi46eSoZXbjUOP5gk
+Ej6wVZAXAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
+MB0GA1UdDgQWBBTqVk/sPIOhFIh4gbIrBSLAB0FbQjANBgkqhkiG9w0BAQUFAAOC
+AQEAYp7mEzzhw6o5Hf5+T5kcI+t4BJyiIWy7vHlLs/G8dLYXO81aN/Mzg928eMTR
+TxxYZL8dd9uwsJ50TVfX6L0R4Dyw6wikh3fHRrat9ufXi63j5K91Ysr7aXqnF38d
+iAgHYkrwC3kuxHBb9C0KBz6h8Q45/KCyN7d37wWAq38yyhPDlaOvyoE6bdUuK5hT
+m5EYA5JmPyrhQ1moDOyueWBAjxzMEMj+OAY1H90cLv6wszsqerxRrdTOHBdv7MjB
+EIpvEEQkXUxVXAzFuuT6m2t91Lfnwfl/IvljHaVC7DlyyhRYHD6D4Rx+4QKp4tWL
+vpw6LkI+gKNJ/YdMCsRZQzEEFA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8DCCA9igAwIBAgIPBuhGJy8fCo/RhFzjafbVMA0GCSqGSIb3DQEBBQUAMDgx
+CzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXpl
+bnBlLmNvbTAeFw0wNzEyMTMxMzA4MjdaFw0zNzEyMTMwODI3MjVaMDgxCzAJBgNV
+BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXplbnBlLmNv
+bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMnTesoPHqynhugWZWqx
+whtFMnGV2f4QW8yv56V5AY+Jw8ryVXH3d753lPNypCxE2J6SmxQ6oeckkAoKVo7F
+2CaU4dlI4S0+2gpy3aOZFdqBoof0e24md4lYrdbrDLJBenNubdt6eEHpCIgSfocu
+ZhFjbFT7PJ1ywLwu/8K33Q124zrX97RovqL144FuwUZvXY3gTcZUVYkaMzEKsVe5
+o4qYw+w7NMWVQWl+dcI8IMVhulFHoCCQk6GQS/NOfIVFVJrRBSZBsLVNHTO+xAPI
+JXzBcNs79AktVCdIrC/hxKw+yMuSTFM5NyPs0wH54AlETU1kwOENWocivK0bo/4m
+tRXzp/yEGensoYi0RGmEg/OJ0XQGqcwL1sLeJ4VQJsoXuMl6h1YsGgEebL4TrRCs
+tST1OJGh1kva8bvS3ke18byB9llrzxlT6Y0Vy0rLqW9E5RtBz+GGp8rQap+8TI0G
+M1qiheWQNaBiXBZO8OOi+gMatCxxs1gs3nsL2xoP694hHwZ3BgOwye+Z/MC5TwuG
+KP7Suerj2qXDR2kS4Nvw9hmL7Xtw1wLW7YcYKCwEJEx35EiKGsY7mtQPyvp10gFA
+Wo15v4vPS8+qFsGV5K1Mij4XkdSxYuWC5YAEpAN+jb/af6IPl08M0w3719Hlcn4c
+yHf/W5oPt64FRuXxqBbsR6QXAgMBAAGjgfYwgfMwgbAGA1UdEQSBqDCBpYEPaW5m
+b0BpemVucGUuY29tpIGRMIGOMUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBB
+MDEzMzcyNjAtUk1lcmMuVml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEG
+A1UECQw6QXZkYSBkZWwgTWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEw
+IFZpdG9yaWEtR2FzdGVpejAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUHRxlDqjyJXu0kc/ksbHmvVV0bAUwDQYJKoZIhvcNAQEFBQAD
+ggIBAMeBRm8hGE+gBe/n1bqXUKJg7aWSFBpSm/nxiEqg3Hh10dUflU7F57dp5iL0
++CmoKom+z892j+Mxc50m0xwbRxYpB2iEitL7sRskPtKYGCwkjq/2e+pEFhsqxPqg
+l+nqbFik73WrAGLRne0TNtsiC7bw0fRue0aHwp28vb5CO7dz0JoqPLRbEhYArxk5
+ja2DUBzIgU+9Ag89njWW7u/kwgN8KRwCfr00J16vU9adF79XbOnQgxCvv11N75B7
+XSus7Op9ACYXzAJcY9cZGKfsK8eKPlgOiofmg59OsjQerFQJTx0CCzl+gQgVuaBp
+E8gyK+OtbBPWg50jLbJtooiGfqgNASYJQNntKE6MkyQP2/EeTXp6WuKlWPHcj1+Z
+ggwuz7LdmMySlD/5CbOlliVbN/UShUHiGUzGigjB3Bh6Dx4/glmimj4/+eAJn/3B
+kUtdyXvWton83x18hqrNA/ILUpLxYm9/h+qrdslsUMIZgq+qHfUgKGgu1fxkN0/P
+pUTEvnK0jHS0bKf68r10OEMr3q/53NjgnZ/cPcqlY0S/kqJPTIAcuxrDmkoEVU3K
+7iYLHL8CxWTTnn7S05EcS6L1HOUXHA0MUqORH5zwIe0ClG+poEnK6EOMxPQ02nwi
+o8ZmPrgbBYhdurz3vOXcFD2nhqi2WVIhA16L4wTtSyoeo09Q
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
+MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw
+ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL
+SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
+cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC
+AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk
+9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi
+8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG
+yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM
+vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE
+CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2
+J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF
+BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap
+aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl
+BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT
+2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO
+fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5
+UNkAAk/bg9ART6RCVmE6fhMy04Qfybo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
+MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
+dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
+UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
+ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
+c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
+OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
+mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
+BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
+qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
+gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
+bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
+dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
+6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
+h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
+/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
+pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
+ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
+aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
+NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
+A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
+SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
+VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
+w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
+mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
+4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
+4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
+EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
+SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
+ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
+vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
+Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
+/L7fCg0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
+MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
+Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
+YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
+CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
+b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
+HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
+WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
+1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
+u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
+99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
+M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
+BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
+cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
+gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
+ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
+aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
@@ -1479,101 +2589,129 @@
 8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN
-AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp
-dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw
-MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw
-CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ
-MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB
-SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz
-ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH
-LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP
-PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL
-2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w
-ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC
-MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk
-AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0
-AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz
-AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz
-AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f
-BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
-FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY
-P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi
-CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g
-kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95
-HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS
-na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
-qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
-TbvGRNs2yyqcjg==
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS
-QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN
-MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS
-b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49
-AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf
-TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517
-IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA
-MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4
-at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM
-6BgD56KyKA==
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
-YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
-MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
-NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
-A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
-A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
-Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
-QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
-eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
-B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
-z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
-AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
-ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
-TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
-MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
-VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
-VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
-bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
-AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
-bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
-ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
-VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
-ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
-AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
+MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
+IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
+dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
+li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
+rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
+WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
+F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
+xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
+Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
+dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
+ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
+IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
+c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
+ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
+KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
+KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
+y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
+dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
+VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
+fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
+7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
+cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
+mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
+xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
+SnQ2+Q==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
-ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
-HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
-UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
-tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
-ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
-lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
-/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
-A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
-A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
-dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
-MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
-cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
-L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
-BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
-acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
-o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
-zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
-PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
-Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
@@ -1598,153 +2736,206 @@
 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
-MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw
-ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL
-SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
-cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC
-AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk
-9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi
-8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG
-yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM
-vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE
-CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2
-J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF
-BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap
-aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl
-BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT
-2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO
-fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5
-UNkAAk/bg9ART6RCVmE6fhMy04Qfybo=
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
+MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
+IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
+bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
+RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
+zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
+bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
+MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
+VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
+OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
+tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
+q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
+EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
+VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
-RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
-dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
-YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
-NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
-EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
-cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
-c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
-dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
-fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
-bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
-75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
-FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
-HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
-5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
-b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
-A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
-6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
-TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
-dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
-Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
-l7WdmplNsDz4SgCbZN2fOUvRJ9e4
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
+MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
+dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
+WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
+VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
+9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
+DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
+Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
+QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
+xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
+A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
+kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
+Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
+Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
+JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
+RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
-EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
-MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
-cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
-dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
-pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
-b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
-IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
-lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
-AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
-VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
-ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
-BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
-AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
-U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
-bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
-+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
-bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
-uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
-XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
-ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
-fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
-BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
-cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
-HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
-CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
-3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
-6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
-HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
-EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
-Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
-Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
-DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
-5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
-Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
-gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
-aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
-izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
+MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
+Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
+5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
+3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
+vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
+8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
+zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
+3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
+FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
+Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
+ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF0zCCA7ugAwIBAgIVALhZFHE/V9+PMcAzPdLWGXojF7TrMA0GCSqGSIb3DQEB
-DQUAMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dp
-ZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBIDIwHhcNMTExMDA2
-MDgzOTU2WhcNNDYxMDA2MDgzOTU2WjCBgDELMAkGA1UEBhMCUEwxIjAgBgNVBAoT
-GVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0
-d29yayBDQSAyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvfl4+ObV
-gAxknYYblmRnPyI6HnUBfe/7XGeMycxca6mR5rlC5SBLm9qbe7mZXdmbgEvXhEAr
-J9PoujC7Pgkap0mV7ytAJMKXx6fumyXvqAoAl4Vaqp3cKcniNQfrcE1K1sGzVrih
-QTib0fsxf4/gX+GxPw+OFklg1waNGPmqJhCrKtPQ0WeNG0a+RzDVLnLRxWPa52N5
-RH5LYySJhi40PylMUosqp8DikSiJucBb+R3Z5yet/5oCl8HGUJKbAiy9qbk0WQq/
-hEr/3/6zn+vZnuCYI+yma3cWKtvMrTscpIfcRnNeGWJoRVfkkIJCu0LW8GHgwaM9
-ZqNd9BjuiMmNF0UpmTJ1AjHuKSbIawLmtWJFfzcVWiNoidQ+3k4nsPBADLxNF8tN
-orMe0AZa3faTz1d1mfX6hhpneLO/lv403L3nUlbls+V1e9dBkQXcXWnjlQ1DufyD
-ljmVe2yAWk8TcsbXfSl6RLpSpCrVQUYJIP4ioLZbMI28iQzV13D4h1L92u+sUS4H
-s07+0AnacO+Y+lbmbdu1V0vc5SwlFcieLnhO+NqcnoYsylfzGuXIkosagpZ6w7xQ
-EmnYDlpGizrrJvojybawgb5CAKT41v4wLsfSRvbljnX98sy50IdbzAYQYLuDNbde
-Z95H7JlI8aShFf6tjGKOOVVPORa5sWOd/7cCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUtqFUOQLDoD+Oirz61PgcptE6Dv0wDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBDQUAA4ICAQCdU8KBJdw1LK4K3VqbRjBWu9S0bEuG5gql
-0pKKmo3cj7TudvQDy+ubAXirKmu1uiNOMXy1LN0taWczbmNdORgS+KAoU0SHq2rE
-kpYfKqIcup3dJ/tSTbCPWujtjcNo45KgJgyHkLAD6mplKAjERnjgW7oO8DPcJ7Z+
-iD29kqSWfkGogAh71jYSvBAVmyS8q619EYkvMe340s9Tjuu0U6fnBMovpiLEEdzr
-mMkiXUFq3ApSBFu8LqB9x7aSuySg8zfRK0OozPFoeBp+b2OQe590yGvZC1X2eQM9
-g8dBQJL7dgs3JRc8rz76PFwbhvlKDD+KxF4OmPGt7s/g/SE1xzNhzKI3GEN8M+mu
-doKCB0VIO8lnbq2jheiWVs+8u/qry7dXJ40aL5nzIzM0jspTY9NXNFBPz0nBBbrF
-qId744aP+0OiEumsUewEdkzw+o+5MRPpCLckCfmgtwc2WFfPxLt+SWaVNQS2dzW4
-qVMpX5KF+FLEWk79BmE5+33QdkeSzOwrvYRu5ptFwX1isVMtnnWg58koUNflvKiq
-B3hquXS0YPOEjQPcrpHadEQNe0Kpd9YrfKHGbBNTIqkSmqX5TyhFNbCXT0ZlhcX0
-/WKiomr8NDAGft8M4HOBlslEKt4fguxscletKWSk8cYpjjVgU85r2QK+OTB14Pdc
-Y2rwQMEsjQ==
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
+MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
+TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
+b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
+M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
+UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
+Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
+rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
+pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
+j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
+KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
+/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
+cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
+1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
+px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
+MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
+2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
+v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
+wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
+CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
+vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
+Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
+Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
+eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
+FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
+7uzXLg==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1
-MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB
-IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK
-Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg
-MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH
-xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ
-FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q
-VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH
-jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l
-Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED
-o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI
-FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF
-BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW
-Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX
-cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz
-Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4
-CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId
-kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU=
+MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
+DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
+qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
+uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
+Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
+pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
+5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
+UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
+GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
+5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
+6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
+eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
+B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
+BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
+L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
+SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
+CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
+5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
+IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
+gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
+vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
+bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
+N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
+Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
+ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
+DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP
+cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW
+IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX
+xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy
+KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR
+9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az
+5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8
+6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7
+Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP
+bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt
+BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt
+XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd
+INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp
+LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8
+Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp
+gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh
+/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw
+0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A
+fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
+4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR
+1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
+QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
+94B7IWcnMFk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
@@ -1770,82 +2961,59 @@
 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB
-VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
-bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R
-dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw
-MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy
-dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52
-ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM
-EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj
-lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ
-znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH
-2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1
-k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs
-2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD
-VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
-AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG
-KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+
-8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R
-FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
-mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE
-DNuxUCAKGkq6ahq97BvIxYSazQ==
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
-Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
-LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
-MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
-gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
-YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
-b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
-9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
-zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
-OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
-2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
-oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
-KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
-m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
-MdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFHjCCBAagAwIBAgIEAKA3oDANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMC
-Q1oxOjA4BgNVBAMMMUkuQ0EgLSBRdWFsaWZpZWQgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHksIDA5LzIwMDkxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBh
-dXRvcml0YSwgYS5zLjE9MDsGA1UECww0SS5DQSAtIEFjY3JlZGl0ZWQgUHJvdmlk
-ZXIgb2YgQ2VydGlmaWNhdGlvbiBTZXJ2aWNlczAeFw0wOTA5MDEwMDAwMDBaFw0x
-OTA5MDEwMDAwMDBaMIG3MQswCQYDVQQGEwJDWjE6MDgGA1UEAwwxSS5DQSAtIFF1
-YWxpZmllZCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgMDkvMjAwOTEtMCsGA1UE
-CgwkUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRhLCBhLnMuMT0wOwYDVQQL
-DDRJLkNBIC0gQWNjcmVkaXRlZCBQcm92aWRlciBvZiBDZXJ0aWZpY2F0aW9uIFNl
-cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTaEy0KC8M9l
-4lSaWHMs4+sVV1LwzyJYiIQNeCrv1HHm/YpGIdY/Z640ceankjQvIX7m23BK4OSC
-6KO8kZYA3zopOz6GFCOKV2PvLukbc+c2imF6kLHEv6qNA8WxhPbR3xKwlHDwB2yh
-Wzo7V3QVgDRG83sugqQntKYC3LnlTGbJpNP+Az72gpO9AHUn/IBhFk4ksc8lYS2L
-9GCy9CsmdKSBP78p9w8Lx7vDLqkDgt1/zBrcUWmSSb7AE/BPEeMryQV1IdI6nlGn
-BhWkXOYf6GSdayJw86btuxC7viDKNrbp44HjQRaSxnp6O3eto1x4DfiYdw/YbJFe
-7EjkxSQBywIDAQABo4IBLjCCASowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwgecGA1UdIASB3zCB3DCB2QYEVR0gADCB0DCBzQYIKwYBBQUHAgIwgcAa
-gb1UZW50byBjZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28ga3ZhbGlmaWtvdmFueSBz
-eXN0ZW1vdnkgY2VydGlmaWthdCBwb2RsZSB6YWtvbmEgYy4gMjI3LzIwMDAgU2Iu
-IHYgcGxhdG5lbSB6bmVuaS9UaGlzIGlzIHF1YWxpZmllZCBzeXN0ZW0gY2VydGlm
-aWNhdGUgYWNjb3JkaW5nIHRvIEN6ZWNoIEFjdCBOby4gMjI3LzIwMDAgQ29sbC4w
-HQYDVR0OBBYEFHnL0CPpOmdwkXRP01Hi4CD94Sj7MA0GCSqGSIb3DQEBCwUAA4IB
-AQB9laU214hYaBHPZftbDS/2dIGLWdmdSbj1OZbJ8LIPBMxYjPoEMqzAR74tw96T
-i6aWRa5WdOWaS6I/qibEKFZhJAVXX5mkx2ewGFLJ+0Go+eTxnjLOnhVF2V2s+57b
-m8c8j6/bS6Ij6DspcHEYpfjjh64hE2r0aSpZDjGzKFM6YpqsCJN8qYe2X1qmGMLQ
-wvNdjG+nPzCJOOuUEypIWt555ZDLXqS5F7ZjBjlfyDZjEfS2Es9Idok8alf563Mi
-9/o+Ba46wMYOkk3P1IlU0RqCajdbliioACKDztAqubONU1guZVzV8tuMASVzbJeL
-/GAB7ECTwe1RuKrLYtglMKI9
+MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
+OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
+A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
+JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
+vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
+D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
+Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
+RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
+HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
+nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
+0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
+UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
+Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
+TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
+BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
+2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
+UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
+6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
+9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
+HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
+wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
+XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
+IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
+hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
+so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
@@ -1935,276 +3103,72 @@
 fyWl8kgAwKQB2j8=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
-CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
-nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
-43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
-T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
-gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
-TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
-DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
-hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
-06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
-PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
-YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
+m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
+FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
+TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
+EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
+kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
+HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
+vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
+19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
+L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
+bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
+JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
+BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
+K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
+ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
+Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
+sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
+3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
+ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
+mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
+b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
+rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
+hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
+zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
+MBr1mmz0DlP5OlvRHA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0
-MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG
-EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT
-CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK
-8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2
-98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb
-2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC
-ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi
-Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB
-o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl
-ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD
-AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL
-AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd
-foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M
-cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq
-8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp
-hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk
-Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
-AGegcQCCSA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB
-ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt
-TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1
-NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD
-VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS
-Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2
-N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH
-iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe
-YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1
-axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g
-yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD
-AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh
-ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V
-VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB
-BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
-IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs
-QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4
-ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM
-YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb
-QErNaLly7HF27FSOH4UMAWr6pjisH8SE
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
-JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
-mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
-wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
-VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
-AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
-AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
-pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
-dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
-fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
-NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
-H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
-+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
-IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
-BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
-MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
-YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
-dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
-BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
-papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
-DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
-KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
-XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIETTCCAzWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJDSDEO
-MAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0aWVzMRcwFQYDVQQDEw5BZG1pbkNBLUNELVQwMTAe
-Fw0wNjAxMjUxMzM2MTlaFw0xNjAxMjUxMjM2MTlaMG0xCzAJBgNVBAYTAkNIMQ4w
-DAYDVQQKEwVhZG1pbjERMA8GA1UECxMIU2VydmljZXMxIjAgBgNVBAsTGUNlcnRp
-ZmljYXRpb24gQXV0aG9yaXRpZXMxFzAVBgNVBAMTDkFkbWluQ0EtQ0QtVDAxMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0jQlMZmpLDhV+GNR9TAoSNle
-JgQB4xAXJELQf5/ySMfoFA4MmjKqYXQkB6MGPuQKwR9XRRSPf61vqb8YPsdjRmgp
-byHBcUd5t0N8RX6wRZUnPMW+bCCo2VqAU4XFbnlc2gHKaam0wdTtbBTXEkv0ieIH
-fxCfFxXqSsSr60IkF/2/xbrAgV/QD5yHk6Ie8feAVWwi5UtaFqtu4LiFEh2QMyxs
-Oyz1OcvKzkM2g873tyiE7jzMgZP+Ww3tibk2F9+e6ZeiB37TLOmVtvgpmrws4fiI
-rFNXEYSWBVrUTbn81U47yWzOgf5fEHP07bRV5QOCzCm99qNimsbL6CG7nT78CQID
-AQABo4H3MIH0MBIGA1UdEwEB/wQIMAYBAf8CAQAwga4GA1UdIASBpjCBozCBoAYI
-YIV0AREDFQEwgZMwSAYIKwYBBQUHAgIwPBo6VGhpcyBpcyB0aGUgQWRtaW5DQS1D
-RC1UMDEgQ2VydGlmaWNhdGUgUHJhY3RpY2UgU3RhdGVtZW50LjBHBggrBgEFBQcC
-ARY7aHR0cDovL3d3dy5wa2kuYWRtaW4uY2gvcG9saWN5L0NQU18yXzE2Xzc1Nl8x
-XzE3XzNfMjFfMS5wZGYwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQqxGkKocZV
-xgNucM6GgbOkD6oZ2zANBgkqhkiG9w0BAQUFAAOCAQEAn356bbusjI5glGXRQ1DR
-v21qQf0S4s3GHyZm7cqdOkFleM70ArBT+kOP5Nm7rlSAFyVgEkmBdOg7s9tlXClU
-yeZFnp6UEYRUcijPN8D1VaNRK6PIUObpDBQT0C+kAfxG9z4v29T0SxT4sgAdC/xQ
-Fyv58Fp9bPn7owuKwKcyCH1XSyi/Bp4XFELlLOaigBZO/w+dPBz4FcJSdZjU+BaJ
-0E3nKAjHlShO5ouBSZnaJz3p+nkw2Wyo36s6GxCK0XbkSP45iniIG4FmwwZkonYF
-ypQntHbx2oL7tUQQY0PDo8bGBMcPy/G2j+dciqZRlsnfgMy10SCzQ9MUx92xUG2V
-eg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj
-aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB
-MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx
-DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi
-C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go
-vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB
-++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy
-fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm
-vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC
-AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI
-YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290
-LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu
-LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f
-BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT
-GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w
-DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM
-Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk
-bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp
-Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD
-Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
-AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM
-vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9
-QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr
-a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn
-0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/
-RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD
-EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz
-aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w
-MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G
-A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
-Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l
-dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh
-bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq
-eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe
-r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5
-3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd
-vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l
-mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC
-wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg
-hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0
-TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
-biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg
-ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg
-dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6
-b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl
-c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0
-ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3
-dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu
-ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh
-bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo
-ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3
-Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u
-ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA
-A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ
-MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+
-NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR
-VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY
-83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3
-macqaJVmlaut74nLYKkGEsaUR+ko
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
-CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
-ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
-Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
-EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
-IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
-K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
-fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
-Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
-BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
-AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
-oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
-sycX
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFkjCCA3qgAwIBAgIBCDANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJDTjER
-MA8GA1UEChMIVW5pVHJ1c3QxGDAWBgNVBAMTD1VDQSBHbG9iYWwgUm9vdDAeFw0w
-ODAxMDEwMDAwMDBaFw0zNzEyMzEwMDAwMDBaMDoxCzAJBgNVBAYTAkNOMREwDwYD
-VQQKEwhVbmlUcnVzdDEYMBYGA1UEAxMPVUNBIEdsb2JhbCBSb290MIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2rPlBlA/9nP3xDK/RqUlYjOHsGj+p9+I
-A2N9Apb964fJ7uIIu527u+RBj8cwiQ9tJMAEbBSUgU2gDXRm8/CFr/hkGd656YGT
-0CiFmUdCSiw8OCdKzP/5bBnXtfPvm65bNAbXj6ITBpyKhELVs6OQaG2BkO5NhOxM
-cE4t3iQ5zhkAQ5N4+QiGHUPR9HK8BcBn+sBR0smFBySuOR56zUHSNqth6iur8CBV
-mTxtLRwuLnWW2HKX4AzKaXPudSsVCeCObbvaE/9GqOgADKwHLx25urnRoPeZnnRc
-GQVmMc8+KlL+b5/zub35wYH1N9ouTIElXfbZlJrTNYsgKDdfUet9Ysepk9H50DTL
-qScmLCiQkjtVY7cXDlRzq6987DqrcDOsIfsiJrOGrCOp139tywgg8q9A9f9ER3Hd
-J90TKKHqdjn5EKCgTUCkJ7JZFStsLSS3JGN490MYeg9NEePorIdCjedYcaSrbqLA
-l3y74xNLytu7awj5abQEctXDRrl36v+6++nwOgw19o8PrgaEFt2UVdTvyie3AzzF
-HCYq9TyopZWbhvGKiWf4xwxmse1Bv4KmAGg6IjTuHuvlb4l0T2qqaqhXZ1LUIGHB
-zlPL/SR/XybfoQhplqCe/klD4tPq2sTxiDEhbhzhzfN1DiBEFsx9c3Q1RSw7gdQg
-7LYJjD5IskkCAwEAAaOBojCBnzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zBj
-BgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcD
-BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF
-BwMJMB0GA1UdDgQWBBTZw9P4gJJnzF3SOqLXcaK0xDiALTANBgkqhkiG9w0BAQUF
-AAOCAgEA0Ih5ygiq9ws0oE4Jwul+NUiJcIQjL1HDKy9e21NrW3UIKlS6Mg7VxnGF
-sZdJgPaE0PC6t3GUyHlrpsVE6EKirSUtVy/m1jEp+hmJVCl+t35HNmktbjK81HXa
-QnO4TuWDQHOyXd/URHOmYgvbqm4FjMh/Rk85hZCdvBtUKayl1/7lWFZXbSyZoUkh
-1WHGjGHhdSTBAd0tGzbDLxLMC9Z4i3WA6UG5iLHKPKkWxk4V43I29tSgQYWvimVw
-TbVEEFDs7d9t5tnGwBLxSzovc+k8qe4bqi81pZufTcU0hF8mFGmzI7GJchT46U1R
-IgP/SobEHOh7eQrbRyWBfvw0hKxZuFhD5D1DCVR0wtD92e9uWfdyYJl2b/Unp7uD
-pEqB7CmB9HdL4UISVdSGKhK28FWbAS7d9qjjGcPORy/AeGEYWsdl/J1GW1fcfA67
-loMQfFUYCQSu0feLKj6g5lDWMDbX54s4U+xJRODPpN/xU3uLWrb2EZBL1nXz/gLz
-Ka/wI3J9FO2pXd96gZ6bkiL8HvgBRUGXx2sBYb4zaPKgZYRmvOAqpGjTcezHCN6j
-w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7
-OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDdjCCAl6gAwIBAgIEOhsEBTANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJE
-SzEMMAoGA1UEChMDS01EMQ8wDQYDVQQLEwZLTUQtQ0ExIzAhBgNVBAMTGktNRC1D
-QSBLdmFsaWZpY2VyZXQgUGVyc29uMB4XDTAwMTEyMTIzMjQ1OVoXDTE1MTEyMjIz
-MjQ1OVowUTELMAkGA1UEBhMCREsxDDAKBgNVBAoTA0tNRDEPMA0GA1UECxMGS01E
-LUNBMSMwIQYDVQQDExpLTUQtQ0EgS3ZhbGlmaWNlcmV0IFBlcnNvbjCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBANriF4Xd6yD7ZlBE317UBDObn+vRMVc6
-p3wNQODdEDJe2z1ncCz9NJvhoLGdOJhyg7VVPh0P2c+KZ9WI9mWOKZI2bp2WkLju
-jCcxbhTrurY3Wfc6gwLBqqFV8wWgaZKmvVWizjw9Kyi25f3yX4fOho6Qq2lvVbub
-tvVFXAd51GJ+/2Yed+a4Or2bz2RcqHS81B3pywsD4mgJR5xREv5jqPfwNP+V7bkc
-X+pfO4kVhZ/V+8MSPdQHgcV/iB3wP2mwgWyIBNc1reBidGTiz8unnWu55hcNfsvt
-LJbTs9OHhsR7naRuy+S402nDnD5vnONOFEsiHn46w+T0rtu7h6j4OvkCAwEAAaNW
-MFQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUeWLqmhI42Jxj7DifDsW+
-DlQhKD0wHwYDVR0jBBgwFoAUeWLqmhI42Jxj7DifDsW+DlQhKD0wDQYJKoZIhvcN
-AQEFBQADggEBANML/P42OuJ9aUV/0fItuIyc1JhqWvSqn5bXj+9eyEegcp8bHLHY
-42D1O+z0lNipdjYPSdMJ0wZOEUhr+150SdDQ1P/zQL8AUaLEBkRt7ZdzXPVH3PER
-qnf9IrpYBknZKfCAoVchA6Rr9WU3Sd8bMoRfMLKg8c0M8G6EPwCTcOFriSkbtvNG
-zd8r8I+WfUYIN/p8DI9JT9qfjVODnYPRMUm6KPvq27TsrGruKrqyaV94kWc8co8A
-v3zFLeCtghvUiRBdx+8Q7m5t4CkuSr0WINrqjIPFW2QrM1r82y09Fd16RkqL4LOg
-Lh6vB5KnTApv62rWdw7zWwYnjY6/vXYY1Aw=
+MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
+jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
+0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
+2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
+ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
+y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
+tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
+6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
+uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
+acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
+k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
+VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
+BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
+b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
+fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
+/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
+REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
+srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
+aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
+woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
+Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
+t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
+8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
+9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
+wSsSnqaeG8XmDtkx2Q==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
@@ -2241,327 +3205,6 @@
 I+2ksx0WckNLIOFZfsLorSa/ovc=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
-MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
-ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
-VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
-b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
-scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
-xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
-LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
-uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
-yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
-JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
-rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
-BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
-hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
-QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
-HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
-Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
-QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
-BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
-MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
-A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
-laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
-awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
-JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
-LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
-VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
-LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
-UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
-QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
-naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
-QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDczCCAlugAwIBAgIQMDAwMDk3Mzc1NzM4NjAwMDANBgkqhkiG9w0BAQUFADBV
-MQswCQYDVQQGEwJGUjETMBEGA1UEChMKQ2VydGlOb21pczEcMBoGA1UECxMTQUMg
-UmFjaW5lIC0gUm9vdCBDQTETMBEGA1UEAxMKQ2VydGlOb21pczAeFw0wMDExMDkw
-MDAwMDBaFw0xMjExMDkwMDAwMDBaMFUxCzAJBgNVBAYTAkZSMRMwEQYDVQQKEwpD
-ZXJ0aU5vbWlzMRwwGgYDVQQLExNBQyBSYWNpbmUgLSBSb290IENBMRMwEQYDVQQD
-EwpDZXJ0aU5vbWlzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8SWb
-4mS5RXB3ENSIcfrEzCj/TRUQuT1tMCU0YUfXFSgcPdWglIzCv3kvh07QoB+8xMl+
-fQHvSSduAxnNewz0GBY9rApCPKlP6CcnJr74OSVZIiWt9wLfl4wwhNhZOiikIpZp
-EdOXWqRc84P5cUlN3Lwmr1sjCWmHfTSS4cAKxfDbFLfE61etosyoFZUTQbIhb1Bf
-JL5xRXAUZudQiU42n/yAoSUrN4FLUfPQNlOe1AB81pIgX8g2ojwxDjfgqSs1JmBF
-uLKJ45uVLEenQBPmQCGjL3maV86IRmR3a9UGlgvKAk0NBdh8mrQyQvcUlLBIQBCm
-l7wppt6maQHUNEPQSwIDAQABoz8wPTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQU+F4ho6ijFeb4tRG7/kIEXU2OgnowDQYJKoZIhvcNAQEF
-BQADggEBACe9FJayK6bXkJQrilBFMh75QPdFOks9PJuo86OMUlBDZGYFTCh9Arex
-N3KYCnAEzazYIALwr7eASJJDIQMu1Q+pkx/7ACde4kP47F27M2rm+v5HnGooCLz2
-s7Fe/WUycTQqgwF5lNp03m1ce/TvovgkEZeVN5wM/7+SsZLJGDigXGeq48j2g2hn
-8OckX9Ciyo0U3/1IVeigNBisiaOlsHSZOEPBZQRiZULob+NVbXVPo8nM1OyP3aHI
-LQex1yYcCr9m93nOiZyKkur3Uedf1yMTBe+fflnPFKGYnVqvTGXCKVdHzQBfpILA
-AuaC+5ykZhSiSMf8nmL2oPMcLO7YQw4=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
-8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
-RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
-hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
-ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
-EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
-A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
-WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
-1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
-6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
-91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
-e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
-TpPDpFQUWw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDoTCCAomgAwIBAgIQKTZHquOKrIZKI1byyrdhrzANBgkqhkiG9w0BAQUFADBO
-MQswCQYDVQQGEwJ1czEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQ0wCwYDVQQL
-EwRGQkNBMRYwFAYDVQQDEw1Db21tb24gUG9saWN5MB4XDTA3MTAxNTE1NTgwMFoX
-DTI3MTAxNTE2MDgwMFowTjELMAkGA1UEBhMCdXMxGDAWBgNVBAoTD1UuUy4gR292
-ZXJubWVudDENMAsGA1UECxMERkJDQTEWMBQGA1UEAxMNQ29tbW9uIFBvbGljeTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeNvTMn5K1b+3i9L0dHbsd4
-6ZOcpN7JHP0vGzk4rEcXwH53KQA7Ax9oD81Npe53uCxiazH2+nIJfTApBnznfKM9
-hBiKHa4skqgf6F5PjY7rPxr4nApnnbBnTfAu0DDew5SwoM8uCjR/VAnTNr2kSVdS
-c+md/uRIeUYbW40y5KVIZPMiDZKdCBW/YDyD90ciJSKtKXG3d+8XyaK2lF7IMJCk
-FEhcVlcLQUwF1CpMP64Sm1kRdXAHImktLNMxzJJ+zM2kfpRHqpwJCPZLr1LoakCR
-xVW9QLHIbVeGlRfmH3O+Ry4+i0wXubklHKVSFzYIWcBCvgortFZRPBtVyYyQd+sC
-AwEAAaN7MHkwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFC9Yl9ipBZilVh/72at17wI8NjTHMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJ
-KwYBBAGCNxUCBBYEFHa3YJbdFFYprHWF03BjwbxHhhyLMA0GCSqGSIb3DQEBBQUA
-A4IBAQBgrvNIFkBypgiIybxHLCRLXaCRc+1leJDwZ5B6pb8KrbYq+Zln34PFdx80
-CTj5fp5B4Ehg/uKqXYeI6oj9XEWyyWrafaStsU+/HA2fHprA1RRzOCuKeEBuMPdi
-4c2Z/FFpZ2wR3bgQo2jeJqVW/TZsN5hs++58PGxrcD/3SDcJjwtCga1GRrgLgwb0
-Gzigf0/NC++DiYeXHIowZ9z9VKEDfgHLhUyxCynDvux84T8PCVI8L6eaSP436REG
-WOE2QYrEtr+O3c5Ks7wawM36GpnScZv6z7zyxFSjiDV2zBssRm8MtNHDYXaSdBHq
-S4CNHIkRi+xb/xfJSPzn4AYR4oRe
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
-OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
-A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
-JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
-vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
-D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
-Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
-RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
-HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
-nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
-0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
-UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
-Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
-TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
-BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
-2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
-UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
-6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
-9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
-HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
-wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
-XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
-IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
-hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
-so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
-MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
-MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
-BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
-Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
-5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
-3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
-vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
-8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
-DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
-MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
-zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
-3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
-FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
-Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
-ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJKUDEO
-MAwGA1UEChMFTEdQS0kxGjAYBgNVBAsTEUFwcGxpY2F0aW9uIENBIEcyMB4XDTA2
-MDMzMTE1MDAwMFoXDTE2MDMzMTE0NTk1OVowOTELMAkGA1UEBhMCSlAxDjAMBgNV
-BAoTBUxHUEtJMRowGAYDVQQLExFBcHBsaWNhdGlvbiBDQSBHMjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBALk1xhD422jbB8RATLAdHjbcw0H2z1UVbQh/
-XMZoVeXnV/GWUebhTXgPbkAVcDtl/hHf59PWWDU74Z8C/JRSRi6znmCbAp7JgtL2
-464JT4REtmKbAFFouDqt7GTRMkvplESDtA7OIYlrsDbAmMZLnMI+W2AqCTErLatM
-3rGg/VhWwoMdILzEhAmHe6iVl8YljoPgPpMN0cd9c6mo/BkAQC4iuHozQfV4/Vpx
-54LZSIhc7KiFhy1tgIlnGmm+EMBaju2IfT5vLDhrN85H2KIxMN5+U2Vsi4ZTQSBs
-vUilfq8AWlYSWIHR3IlZ+bXu+E2a2EQpi3mn9yKq6nxctBaIIA0CAwEAAaOBsjCB
-rzAdBgNVHQ4EFgQUf7hdjsQYa8Z9zC7prs405xdd4KEwDgYDVR0PAQH/BAQDAgEG
-MEwGA1UdHwRFMEMwQaA/oD2kOzA5MQswCQYDVQQGEwJKUDEOMAwGA1UEChMFTEdQ
-S0kxGjAYBgNVBAsTEUFwcGxpY2F0aW9uIENBIEcyMA8GA1UdEwEB/wQFMAMBAf8w
-HwYDVR0jBBgwFoAUf7hdjsQYa8Z9zC7prs405xdd4KEwDQYJKoZIhvcNAQEFBQAD
-ggEBADzYczZABkhKVBn1J0g5JaVuQue2zRvLOTS3m+xPKr535MqE/B3rmyJA1fT7
-aIdy/Eddag5SSuO1XUjGIpbmM21tq/bN18skWoyoRZ4+YYJ9lNUF8Bo1X3EvLlS1
-QQXvhg1S75yYG/EsTDrR84bTjD56L4ZFjoMyJlu/U8oOUVbcmsJaMBkNp57Vqpsg
-OWl4IfSXbdEOEUwu0xtasPmXeFwqj1Jl7kxCJcI3MA5tKzWUgwbor0U7BGanMLv5
-4CE7Y259RF06alPvERck/VSyWmxzViHJbC2XpEKzJ2EFIWNt6ii8TxpvQtyYq1XT
-HhvAkj+bweY7F1bixJhDJe62ywA=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICZzCCAdCgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJVUzEY
-MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT
-A1BLSTEcMBoGA1UEAxMTRG9EIENMQVNTIDMgUm9vdCBDQTAeFw0wMDA1MTkxMzEz
-MDBaFw0yMDA1MTQxMzEzMDBaMGExCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMu
-IEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRwwGgYDVQQD
-ExNEb0QgQ0xBU1MgMyBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQC1MP5kvurMbe2BLPd/6Rm6DmlqKOGpqcuVWB/x5pppU+CIP5HFUbljl6jmIYwT
-XjY8qFf6+HAsTGrLvzCnTBbkMlz4ErBR+BZXjS+0TfouqJToKmHUVw1Hzm4sL36Y
-Z8wACKu2lhY1woWR5VugCsdmUmLzYXWVF668KlYppeArUwIDAQABoy8wLTAdBgNV
-HQ4EFgQUbJyl8FyPbUGNxBc7kFfCD6PNbf4wDAYDVR0TBAUwAwEB/zANBgkqhkiG
-9w0BAQUFAAOBgQCvcUT5lyPMaGmMQwdBuoggsyIAQciYoFUczT9usZNcrfoYmrsc
-c2/9JEKPh59Rz76Gn+nXikhPCNlplKw/5g8tlw8ok3ZPYt//oM1h+KaGDDE0INx/
-L6j7Ob6V7jhZAmLB3mwVT+DfnbvkeXMk/WNklfdKqJkfSGWVx3u/eDLneg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFUjCCBDqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
-MAsGA1UEChMES0lTQTEuMCwGA1UECxMlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgQ2VudHJhbDEWMBQGA1UEAxMNS0lTQSBSb290Q0EgMzAeFw0wNDExMTkw
-NjM5NTFaFw0xNDExMTkwNjM5NTFaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKEwRL
-SVNBMS4wLAYDVQQLEyVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
-cmFsMRYwFAYDVQQDEw1LSVNBIFJvb3RDQSAzMIIBIDANBgkqhkiG9w0BAQEFAAOC
-AQ0AMIIBCAKCAQEA3rrtF2Wu0b1KPazbgHLMWOHn4ZPazDB6z+8Lri2nQ6u/p0LP
-CFYIpEcdffqG79gwlyY0YTyADvjU65/8IjAboW0+40zSVU4WQDfC9gdu2we1pYyW
-geKbXH6UYcjOhDyx+gDmctMJhXfp3F4hT7TkTvTiF6tQrxz/oTlYdVsSspa5jfBw
-YkhbVigqpYeRNrkeJPW5unu2UlFbF1pgBWycwubGjD756t08jP+J3kNwrB248XXN
-OMpTDUdoasY8GMq94bS+DvTQ49IT+rBRERHUQavo9DmO4TSETwuTqmo4/OXGeEeu
-dhf6oYA3BgAVCP1rI476cg2V1ktisWjC3TSbXQIBA6OCAg8wggILMB8GA1UdIwQY
-MBaAFI+B8NqmzXQ8vmb0FWtGpP4GKMyqMB0GA1UdDgQWBBSPgfDaps10PL5m9BVr
-RqT+BijMqjAOBgNVHQ8BAf8EBAMCAQYwggEuBgNVHSAEggElMIIBITCCAR0GBFUd
-IAAwggETMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LnJvb3RjYS5vci5rci9yY2Ev
-Y3BzLmh0bWwwgd4GCCsGAQUFBwICMIHRHoHOx3QAIMd4yZ3BHLKUACCs9cd4x3jJ
-ncEcx4WyyLLkACgAVABoAGkAcwAgAGMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGkA
-cwAgAGEAYwBjAHIAZQBkAGkAdABlAGQAIAB1AG4AZABlAHIAIABFAGwAZQBjAHQA
-cgBvAG4AaQBjACAAUwBpAGcAbgBhAHQAdQByAGUAIABBAGMAdAAgAG8AZgAgAHQA
-aABlACAAUgBlAHAAdQBiAGwAaQBjACAAbwBmACAASwBvAHIAZQBhACkwMwYDVR0R
-BCwwKqQoMCYxJDAiBgNVBAMMG+2VnOq1reygleuztOuztO2YuOynhO2dpeybkDAz
-BgNVHRIELDAqpCgwJjEkMCIGA1UEAwwb7ZWc6rWt7KCV67O067O07Zi47KeE7Z2l
-7JuQMA8GA1UdEwEB/wQFMAMBAf8wDAYDVR0kBAUwA4ABADANBgkqhkiG9w0BAQUF
-AAOCAQEAz9b3Dv2wjG4FFY6oXCuyWtEeV6ZeGKqCEQj8mbdbp+PI0qLT+SQ09+Pk
-rolUR9NpScmAwRHr4inH9gaLX7riXs+rw87P7pIl3J85Hg4D9N6QW6FwmVzHc07J
-pHVJeyWhn4KSjU3sYcUMMqfHODiAVToqgx2cZHm5Dac1Smjvj/8F2LpOVmHY+Epw
-mAiWk9hgxzrsX58dKzVPSBShmrtv7tIDhlPxEMcHVGJeNo7iHCsdF03m9VrvirqC
-6HfZKBF+N4dKlArJQOk1pTr7ZD7yXxZ683bXzu4/RB1Fql8RqlMcOh9SUWJUD6OQ
-Nc9Nb7rHviwJ8TX4Absk3TC8SA/u2Q==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
-MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
-RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
-gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
-KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
-QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
-XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
-LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
-RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
-jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
-6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
-mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
-Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
-WD9f
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
-d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
-dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
-RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
-MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
-VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
-L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
-Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
-A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
-ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
-Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
-R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
-hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
-IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
-MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
-dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
-EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
-MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
-28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
-VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
-DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
-5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
-ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
-Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
-UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
-+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
-Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
-ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
-hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
-HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
-+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
-YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
-L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
-ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
-IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
-HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
-DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
-PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
-5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
-glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
-FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
-pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
-xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
-tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
-jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
-fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
-OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
-d0jQ
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
 MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
 BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
 biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
@@ -2595,537 +3238,101 @@
 Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
-DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
-BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
-QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
-gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
-zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
-130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
-JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
-ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
-AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
-AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
-9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
-bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
-fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
-HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
-t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
-WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+MIIFejCCA2KgAwIBAgIJAN7E8kTzHab8MA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNVBAMTG1N3aXNzU2ln
+biBHb2xkIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzMxNDdaFw0zNzA4MDQxMzMx
+NDdaMEoxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNV
+BAMTG1N3aXNzU2lnbiBHb2xkIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAMPon8hlWp1nG8FFl7S0h0NbYWCAnvJ/XvlnRN1E+qu1
+q3f/KhlMzm/Ej0Gf4OLNcuDR1FJhQQkKvwpw++CDaWEpytsimlul5t0XlbBvhI46
+PmRaQfsbWPz9Kz6ypOasyYK8zvaV+Jd37Sb2WK6eJ+IPg+zFNljIe8/Vh6GphxoT
+Z2EBbaZpnOKQ8StoZfPosHz8gj3erdgKAAlEeROc8P5udXvCvLNZAQt8xdUt8L//
+bVfSSYHrtLNQrFv5CxUVjGn/ozkB7fzc3CeXjnuL1Wqm1uAdX80Bkeb1Ipi6LgkY
+OG8TqIHS+yE35y20YueBkLDGeVm3Z3X+vo87+jbsr63ST3Q2AeVXqyMEzEpel89+
+xu+MzJUjaY3LOMcZ9taKABQeND1v2gwLw7qX/BFLUmE+vzNnUxC/eBsJwke6Hq9Y
+9XWBf71W8etW19lpDAfpNzGwEhwy71bZvnorfL3TPbxqM006PFAQhyfHegpnU9t/
+gJvoniP6+Qg6i6GONFpIM19k05eGBxl9iJTOKnzFat+vvKmfzTqmurtU+X+P388O
+WsStmryzOndzg0yTPJBotXxQlRHIgl6UcdBBGPvJxmXszom2ziKzEVs/4J0+Gxho
+DaoDoWdZv2udvPjyZS+aQTpF2F7QNmxvOx5jtI6YTBPbIQ6fe+3qoKpxw+ujoNIl
+AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBRclwZGNKvfMMV8xQ1VcWYwtWCPnjAfBgNVHSMEGDAWgBRclwZGNKvfMMV8
+xQ1VcWYwtWCPnjANBgkqhkiG9w0BAQsFAAOCAgEAd0tN3uqFSqssJ9ZFx/FfIMFb
+YO0Hy6Iz3DbPx5TxBsfV2s/NrYQ+/xJIf0HopWZXMMQd5KcaLy1Cwe9Gc7LV9Vr9
+Dnpr0sgxow1IlldlY1UYwPzkisyYhlurDIonN/ojaFlcJtehwcK5Tiz/KV7mlAu+
+zXJPleiP9ve4Pl7Oz54RyawDKUiKqbamNLmsQP/EtnM3scd/qVHbSypHX0AkB4gG
+tySz+3/3sIsz+r8jdaNc/qplGsK+8X2BdwOBsY3XlQ16PEKYt4+pfVDh31IGmqBS
+VHiDB2FSCTdeipynxlHRXGPRhNzC29L6Wxg2fWa81CiXL3WWHIQHrIuOUxG+JCGq
+Z/LBrYic07B4Z3j101gDIApdIPG152XMDiDj1d/mLxkrhWjBBCbPj+0FU6HdBw7r
+QSbHtKksW+NpPWbAYhvAqobAN8MxBIZwOb5rXyFAQaB/5dkPOEtwX0n4hbgrLqof
+k0FD+PuydDwfS1dbt9RRoZJKzr4Qou7YFCJ7uUG9jemIqdGPAxpg/z+HiaCZJyJm
+sD5onnKIUTidEz5FbQXlRrVz7UOGsRQKHrzaDb8eJFxmjw6+of3G62m8Q3nXA3b5
+3IeZuJjEzX9tEPkQvixC/pwpTYNrCr21jsRIiv0hB6aAfR+b6au9gmFECnEnX22b
+kJ6u/zYks2gD1pWMa3M=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
-isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
-NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
-+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
-hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
-mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
-Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
-EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
-mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
-e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
-dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
+MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu
+IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw
+WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD
+ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y
+IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn
+IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+
+6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob
+jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw
+izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl
++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY
+zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP
+pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF
+KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW
+ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB
+AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0
+ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
+IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA
+A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0
+uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+
+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7
+jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/
+u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D
+YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1
+puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa
+icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG
+DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x
+kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z
+Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
-PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
-MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
-GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
-MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
-HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
-gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
-v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
-Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
-9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
-6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
-MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
-Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
-ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
-hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
-iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
-dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
-kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
-hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
-OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
-BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
-BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
-+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
-hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
-5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
-JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
-DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
-huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
-AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
-zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
-kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
-SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
-spki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
-MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
-ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
-IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
-SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
-SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
-ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
-DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
-TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
-fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
-sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
-WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
-nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
-dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
-NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
-AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
-MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
-ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
-uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
-PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
-JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
-gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
-j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
-5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
-o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
-/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
-Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
-W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
-hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEXzCCA0egAwIBAgIBATANBgkqhkiG9w0BAQUFADCB0DELMAkGA1UEBhMCRVMx
-SDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMuVml0
-b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwgTWVk
-aXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6MRMw
-EQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5wZS5j
-b20wHhcNMDMwMTMwMjMwMDAwWhcNMTgwMTMwMjMwMDAwWjCB0DELMAkGA1UEBhMC
-RVMxSDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMu
-Vml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwg
-TWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6
-MRMwEQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5w
-ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1btoCXXhp3xIW
-D+Bxl8nUCxkyiazWfpt0e68t+Qt9+lZjKZSdEw2Omj4qvr+ovRmDXO3iWpWVOWDl
-3JHJjAzFCe8ZEBNDH+QNYwZHmPBaMYFOYFdbAFVHWvys152C308hcFJ6xWWGmjvl
-2eMiEl9P2nR2LWue368DCu+ak7j3gjAXaCOdP1a7Bfr+RW3X2SC5R4Xyp8iHlL5J
-PHJD/WBkLrezwzQPdACw8m9EG7q9kUwlNpL32mROujS3ZkT6mQTzJieLiE3X04s0
-uIUqVkk5MhjcHFf7al0N5CzjtTcnXYJKN2Z9EDVskk4olAdGi46eSoZXbjUOP5gk
-Ej6wVZAXAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
-MB0GA1UdDgQWBBTqVk/sPIOhFIh4gbIrBSLAB0FbQjANBgkqhkiG9w0BAQUFAAOC
-AQEAYp7mEzzhw6o5Hf5+T5kcI+t4BJyiIWy7vHlLs/G8dLYXO81aN/Mzg928eMTR
-TxxYZL8dd9uwsJ50TVfX6L0R4Dyw6wikh3fHRrat9ufXi63j5K91Ysr7aXqnF38d
-iAgHYkrwC3kuxHBb9C0KBz6h8Q45/KCyN7d37wWAq38yyhPDlaOvyoE6bdUuK5hT
-m5EYA5JmPyrhQ1moDOyueWBAjxzMEMj+OAY1H90cLv6wszsqerxRrdTOHBdv7MjB
-EIpvEEQkXUxVXAzFuuT6m2t91Lfnwfl/IvljHaVC7DlyyhRYHD6D4Rx+4QKp4tWL
-vpw6LkI+gKNJ/YdMCsRZQzEEFA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
-MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
-MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
-dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
-UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
-ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
-c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
-OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
-mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
-BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
-qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
-gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
-bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
-dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
-6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
-h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
-/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
-wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
-pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
-vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
-ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
-IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
-IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
-bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
-9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
-H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
-LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
-/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
-rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
-WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
-exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
-sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
-seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
-4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
-BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
-lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
-7M2CYfE45k+XmCpajQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
-ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
-MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
-VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
-FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
-ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
-gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
-fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
-ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
-ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
-c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
-dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
-aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
-hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
-QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
-h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
-rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
-9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
-n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
-biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
-EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
-bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
-YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
-AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
-BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
-QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
-0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
-lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
-B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
-ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
-IhNzbM8m9Yop5w==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
-MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
-V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
-WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
-LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
-AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
-K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
-RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
-rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
-3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
-hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
-MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
-XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
-lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
-aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
-YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex
-EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj
-aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp
-Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa
-Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
-bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp
-b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj
-aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA
-utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6
-Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/
-KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA
-byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR
-k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP
-ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j
-BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC
-Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT
-FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl
-cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH
-MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv
-cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/
-0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE
-7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74
-HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56
-QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+
-A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq
-zIzvO2jHyu9PQqo=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
-BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
-Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
-OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
-SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
-VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
-tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
-uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
-XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
-8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
-5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
-kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
-Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
-JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
-Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
-GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
-ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
-au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
-hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
-dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
-gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
-MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
-UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
-NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
-dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
-dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
-38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
-KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
-DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
-qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
-JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
-PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
-BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
-jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
-eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
-ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
-vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
-qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
-IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
-i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
-O+7ETPTsJ3xCwnR8gooJybQDJbw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDOzCCAiOgAwIBAgIRANAeRlAAACmMAAAAAgAAAAIwDQYJKoZIhvcNAQEFBQAw
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYNDAeFw0wMDA5MTMwNjIyNTBaFw0yMDA5MTMwNjIyNTBa
-MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UE
-AxMORFNUIFJvb3QgQ0EgWDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCthX3OFEYY8gSeIYur0O4ypOT68HnDrjLfIutL5PZHRwQGjzCPb9PFo/ihboJ8
-RvfGhBAqpQCo47zwYEhpWm1jB+L/OE/dBBiyn98krfU2NiBKSom2J58RBeAwHGEy
-cO+lewyjVvbDDLUy4CheY059vfMjPAftCRXjqSZIolQb9FdPcAoa90mFwB7rKniE
-J7vppdrUScSS0+eBrHSUPLdvwyn4RGp+lSwbWYcbg5EpSpE0GRJdchic0YDjvIoC
-YHpe7Rkj93PYRTQyU4bhC88ck8tMqbvRYqMRqR+vobbkrj5LLCOQCHV5WEoxWh+0
-E2SpIFe7RkV++MmpIAc0h1tZAgMBAAGjMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFPCD6nPIP1ubWzdf9UyPWvf0hki9MA0GCSqGSIb3DQEBBQUAA4IBAQCE
-G85wl5eEWd7adH6XW/ikGN5salvpq/Fix6yVTzE6CrhlP5LBdkf6kx1bSPL18M45
-g0rw2zA/MWOhJ3+S6U+BE0zPGCuu8YQaZibR7snm3HiHUaZNMu5c8D0x0bcMxDjY
-AVVcHCoNiL53Q4PLW27nbY6wwG0ffFKmgV3blxrYWfuUDgGpyPwHwkfVFvz9qjaV
-mf12VJffL6W8omBPtgteb6UaT/k1oJ7YI0ldGf+ngpVbRhD+LC3cUtT6GO/BEPZu
-8YTV/hbiDH5v3khVqMIeKT6o8IuXGG7F6a6vKwP1F1FwTXf4UC/ivhme7vdUH7B/
-Vv4AEbT8dNfEeFxrkDbh
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
-aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
-MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
-VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
-fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
-TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
-fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
-1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
-kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
-A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
-ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
-dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
-Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
-HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
-pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
-jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
-xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
-dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
-MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
-Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
-iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
-/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
-jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
-HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
-sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
-gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
-KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
-AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
-URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
-H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
-I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
-iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
-f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID+TCCAuGgAwIBAgIQW1fXqEywr9nTb0ugMbTW4jANBgkqhkiG9w0BAQUFADB5
-MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
-cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xKjAoBgNVBAMTIVZpc2EgSW5m
-b3JtYXRpb24gRGVsaXZlcnkgUm9vdCBDQTAeFw0wNTA2MjcxNzQyNDJaFw0yNTA2
-MjkxNzQyNDJaMHkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQL
-EyZWaXNhIEludGVybmF0aW9uYWwgU2VydmljZSBBc3NvY2lhdGlvbjEqMCgGA1UE
-AxMhVmlzYSBJbmZvcm1hdGlvbiBEZWxpdmVyeSBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyREA4R/QkkfpLx0cYjga/EhIPZpchH0MZsRZ
-FfP6C2ITtf/Wc+MtgD4yTK0yoiXvni3d+aCtEgK3GDvkdgYrgF76ROJFZwUQjQ9l
-x42gRT05DbXvWFoy7dTglCZ9z/Tt2Cnktv9oxKgmkeHY/CyfpCBg1S8xth2JlGMR
-0ug/GMO5zANuegZOv438p5Lt5So+du2Gl+RMFQqEPwqN5uJSqAe0VtmB4gWdQ8on
-Bj2ZAM2R73QW7UW0Igt2vA4JaSiNtaAG/Y/58VXWHGgbq7rDtNK1R30X0kJV0rGA
-ib3RSwB3LpG7bOjbIucV5mQgJoVjoA1e05w6g1x/KmNTmOGRVwIDAQABo30wezAP
-BgNVHRMBAf8EBTADAQH/MDkGA1UdIAQyMDAwLgYFZ4EDAgEwJTAVBggrBgEFBQcC
-ARYJMS4yLjMuNC41MAwGCCsGAQUFBwICMAAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
-DgQWBBRPitp2/2d3I5qmgH1924h1hfeBejANBgkqhkiG9w0BAQUFAAOCAQEACUW1
-QdUHdDJydgDPmYt+telnG/Su+DPaf1cregzlN43bJaJosMP7NwjoJY/H2He4XLWb
-5rXEkl+xH1UyUwF7mtaUoxbGxEvt8hPZSTB4da2mzXgwKvXuHyzF5Qjy1hOB0/pS
-WaF9ARpVKJJ7TOJQdGKBsF2Ty4fSCLqZLgfxbqwMsd9sysXI3rDXjIhekqvbgeLz
-PqZr+pfgFhwCCLSMQWl5Ll3u7Qk9wR094DZ6jj6+JCVCRUS3HyabH4OlM0Vc2K+j
-INsF/64Or7GNtRf9HYEJvrPxHINxl3JVwhYj4ASeaO4KwhVbwtw94Tc/XrGcexDo
-c5lC3rAi4/UZqweYCw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
-ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
-MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
-VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
-ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
-dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
-OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
-8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
-Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
-hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
-6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
-DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
-AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
-bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
-ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
-qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
-iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
-0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
-sSi6
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
-MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
-U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
-NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
-ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
-ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
-DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
-8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
-+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
-X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
-K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
-1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
-A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
-zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
-YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
-bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
-DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
-L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
-eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
-xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
-VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
-WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
-BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
-Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
-OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
-SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
-VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
-Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
-Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
-1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
-ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
-Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
-XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
-Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
-JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
-Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
-irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
-TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
-g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
-95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
-S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
-MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
-AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
-ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
-7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
-kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
-mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
-KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
-6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
-4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
-oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
-UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
-AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+MIIFgTCCA2mgAwIBAgIIIj+pFyDegZQwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEoMCYGA1UEAxMfU3dpc3NTaWdu
+IFBsYXRpbnVtIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzM0MDRaFw0zNzA4MDQx
+MzM0MDRaME4xCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKDAm
+BgNVBAMTH1N3aXNzU2lnbiBQbGF0aW51bSBSb290IENBIC0gRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCUoO8TG59EIBvNxaoiu9nyUj56Wlh35o2h
+K8ncpPPksxOUAGKbHPJDUEOBfq8wNkmsGIkMGEW4PsdUbePYmllriholqba1Dbd9
+I/BffagHqfc+hi7IAU3c5jbtHeU3B2kSS+OD0QQcJPAfcHHnGe1zSG6VKxW2VuYC
+31bpm/rqpu7gwsO64MzGyHvXbzqVmzqPvlss0qmgOD7WiOGxYhOO3KswZ82oaqZj
+K4Kwy8c9Tu1y9n2rMk5lAusPmXT4HBoojA5FAJMsFJ9txxue9orce3jjtJRHHU0F
+bYR6kFSynot1woDfhzk/n/tIVAeNoCn1+WBfWnLou5ugQuAIADSjFTwT49YaawKy
+lCGjnUG8KmtOMzumlDj8PccrM7MuKwZ0rJsQb8VORfddoVYDLA1fer0e3h13kGva
+pS2KTOnfQfTnS+x9lUKfTKkJD0OIPz2T5yv0ekjaaMTdEoAxGl0kVCamJCGzTK3a
+Fwg2AlfGnIZwyXXJnnxh2HjmuegUafkcECgSXUt1ULo80GdwVVVWS/s9HNjbeU2X
+37ie2xcs1TUHuFCp9473Vv96Z0NPINnKZtY4YEvulDHWDaJIm/80aZTGNfWWiO+q
+ZsyBputMU/8ydKe2nZhXtLomqfEzM2J+OrADEVf/3G8RI60+xgrQzFS3LcKTHeXC
+pozH2O9T9wIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUVio/kFj0F1oUstcIG4VbVGpUGigwHwYDVR0jBBgwFoAUVio/
+kFj0F1oUstcIG4VbVGpUGigwDQYJKoZIhvcNAQELBQADggIBAGztiudDqHknm7jP
+hz5kOBiMEUKShjfgWMMb7gQu94TsgxBoDH94LZzCl442ThbYDuprSK1Pnl0NzA2p
+PhiFfsxomTk11tifhsEy+01lsyIUS8iFZtoX/3GRrJxWV95xLFZCv/jNDvCi0//S
+IhX70HgKfuGwWs6ON9upnueVz2PyLA3S+m/zyNX7ALf3NWcQ03tS7BAy+L/dXsmm
+gqTxsL8dLt0l5L1N8DWpkQFH+BAClFvrPusNutUdYyylLqvn4x6j7kuqX7FmAbSC
+WvlGS8fx+N8svv113ZY4mjc6bqXmMhVus5DAOYp0pZWgvg0uiXnNKVaOw15XUcQF
+bwRVj4HpTL1ZRssqvE3JHfLGTwXkyAQN925P2sM6nNLC9enGJHoUPhxCMKgCRTGp
+/FCp3NyGOA9bkz9/CE5qDSc6EHlWwxW4PgaG9tlwZ691eoviWMzGdU8yVcVsFAko
+O/KV5GreLCgHraB9Byjd1Fqj6aZ8E4yZC1J429nR3z5aQ3Z/RmBTws3ndkd8Vc20
+OWQQW5VLNV1EgyTV4C4kDMGAbmkAgAZ3CmaCEAxRbzeJV9vzTOW4ue4jZpdgt1Ld
+2Zb7uoo7oE3OXvBETJDMIU8bOphrjjGD+YMIUssZwTVr7qEVW4g/bazyNJJTpjAq
+E9fmhqhd2ULSx52peovL3+6iMcLl
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
@@ -3161,612 +3368,118 @@
 tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
-MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
-czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
-CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
-MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
-ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
-b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
-euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
-bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
-WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
-MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
-1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
-zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
-BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
-BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
-v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
-E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
-uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
-iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
-GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
+MIIFfjCCA2agAwIBAgIJAKqIsFoLsXabMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJjAkBgNVBAMTHVN3aXNzU2ln
+biBTaWx2ZXIgUm9vdCBDQSAtIEczMB4XDTA5MDgwNDEzMTkxNFoXDTM3MDgwNDEz
+MTkxNFowTDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEmMCQG
+A1UEAxMdU3dpc3NTaWduIFNpbHZlciBSb290IENBIC0gRzMwggIiMA0GCSqGSIb3
+DQEBAQUAA4ICDwAwggIKAoICAQC+h5sF5nF8Um9t7Dep6bPczF9/01DqIZsE8D2/
+vo7JpRQWMhDPmfzscK1INmckDBcy1inlSjmxN+umeAxsbxnKTvdR2hro+iE4bJWc
+L9aLzDsCm78mmxFFtrg0Wh2mVEhSyJ14cc5ISsyneIPcaKtmHncH0zYYCNfUbWD4
+8HnTMzYJkmO3BJr1p5baRa90GvyC46hbDjo/UleYfrycjMHAslrfxH7+DKZUdoN+
+ut3nKvRKNk+HZS6lujmNWWEp89OOJHCMU5sRpUcHsnUFXA2E2UTZzckmRFduAn2V
+AdSrJIbuPXD7V/qwKRTQnfLFl8sJyvHyPefYS5bpiC+eR1GKVGWYSNIS5FR3DAfm
+vluc8d0Dfo2E/L7JYtX8yTroibVfwgVSYfCcPuwuTYxykY7IQ8GiKF71gCTc4i+H
+O1MA5cvwsnyNeRmgiM14+MWKWnflBqzdSt7mcG6+r771sasOCLDboD+Uxb4Subx7
+J3m1MildrsUgI5IDe1Q5sIkiVG0S48N46jpA/aSTrOktiDzbpkdmTN/YF+0W3hrW
+10Fmvx2A8aTgZBEpXgwnBWLr5cQEYtHEnwxqVdZYOJxmD537q1SAmZzsSdaCn9pF
+1j9TBgO3/R/shn104KS06DK2qgcj+O8kQZ5jMHj0VN2O8Fo4jhJ/eMdvAlYhM864
+uK1pVQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUoYxFkwoSYwunV18ySn3hIee3PmYwHwYDVR0jBBgwFoAUoYxFkwoS
+YwunV18ySn3hIee3PmYwDQYJKoZIhvcNAQELBQADggIBAIeuYW1IOCrGHNxKLoR4
+ScAjKkW4NU3RBfq5BTPEZL3brVQWKrA+DVoo2qYagHMMxEFvr7g0tnfUW44dC4tG
+kES1s+5JGInBSzSzhzV0op5FZ+1FcWa2uaElc9fCrIj70h2na9rAWubYWWQ0l2Ug
+MTMDT86tCZ6u6cI+GHW0MyUSuwXsULpxQOK93ohGBSGEi6MrHuswMIm/EfVcRPiR
+i0tZRQswDcoMT29jvgT+we3gh/7IzVa/5dyOetTWKU6A26ubP45lByL3RM2WHy3H
+9Qm2mHD/ONxQFRGEO3+p8NgkVMgXjCsTSdaZf0XRD46/aXI3Uwf05q79Wz55uQbN
+uIF4tE2g0DW65K7/00m8Ne1jxrP846thWgW2C+T/qSq+31ROwktcaNqjMqLJTVcY
+UzRZPGaZ1zwCeKdMcdC/2/HEPOcB5gTyRPZIJjAzybEBGesC8cwh+joCMBedyF+A
+P90lrAKb4xfevcqSFNJSgVPm6vwwZzKpYvaTFxUHMV4PG2n19Km3fC2z7YREMkco
+BzuGaUWpxzaWkHJ02BKmcyPRTrm2ejrEKaFQBhG52fQmbmIIEiAW8AFXF9QFNmeX
+61H5/zMkDAUPVr/vPRxSjoreaQ9aH/DVAzFEs5LG6nWorrvHYAOImP/HBIRSkIbh
+tJOpUC/o69I2rDBgp9ADE7UK
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
-nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
-t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
-SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
-BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
-rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
-NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
-BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
-MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
-p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
-5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
-WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
-4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
-hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+MIICqDCCAi2gAwIBAgIQIW4zpcvTiKRvKQe0JzzE2DAKBggqhkjOPQQDAzCBlDEL
+MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
+VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
+bGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
+RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
+VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
+bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAxIFB1
+YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATXZrUb266zYO5G6ohjdTsqlG3zXxL24w+etgoUU0hS
+yNw6s8tIICYSTvqJhNTfkeQpfSgB2dsYQ2mhH7XThhbcx39nI9/fMTGDAzVwsUu3
+yBe7UcvclBfb6gk7dhLeqrWjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRlwI0l9Qy6l3eQP54u4Fr1ztXh5DAKBggqhkjOPQQD
+AwNpADBmAjEApa7jRlP4mDbjIvouKEkN7jB+M/PsP3FezFWJeJmssv3cHFwzjim5
+axfIEWi13IMHAjEAnMhE2mnCNsNUGRCFAtqdR+9B52wmnQk9922Q0QVEL7C8g5No
+8gxFSTm/mQQc0xCg
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
-MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
-b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
-AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
-aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
-j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
-f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
-IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
-FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
-QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
-/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
-k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
-MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
-seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
-hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
-eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
-DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
-B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
-rosot4LKGAfmt1t06SAZf7IbiVQ=
+MIID9jCCAt6gAwIBAgIQJDJ18h0v0gkz97RqytDzmDANBgkqhkiG9w0BAQsFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAx
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHOddJZKmZgiJM6kXZBxbje/SD
+6Jlz+muxNuCad6BAwoGNAcfMjL2Pffd543pMA03Z+/2HOCgs3ZqLVAjbZ/sbjP4o
+ki++t7JIp4Gh2F6Iw8w5QEFa0dzl2hCfL9oBTf0uRnz5LicKaTfukaMbasxEvxvH
+w9QRslBglwm9LiL1QYRmn81ApqkAgMEflZKf3vNI79sdd2H8f9/ulqRy0LY+/3gn
+r8uSFWkI22MQ4uaXrG7crPaizh5HmbmJtxLmodTNWRFnw2+F2EJOKL5ZVVkElauP
+N4C/DfD8HzpkMViBeNfiNfYgPym4jxZuPkjctUwH4fIa6n4KedaovetdhitNAgMB
+AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBQzQejIORIVk0jyljIuWvXalF9TYDANBgkqhkiG9w0BAQsFAAOCAQEAFeNzV7EX
+tl9JaUSm9l56Z6zS3nVJq/4lVcc6yUQVEG6/MWvL2QeTfxyFYwDjMhLgzMv7OWyP
+4lPiPEAz2aSMR+atWPuJr+PehilWNCxFuBL6RIluLRQlKCQBZdbqUqwFblYSCT3Q
+dPTXvQbKqDqNVkL6jXI+dPEDct+HG14OelWWLDi3mIXNTTNEyZSPWjEwN0ujOhKz
+5zbRIWhLLTjmU64cJVYIVgNnhJ3Gw84kYsdMNs+wBkS39V8C3dlU6S+QTnrIToNA
+DJqXPDe/v+z28LSFdyjBC8hnghAXOKK3Buqbvzr46SMHv3TgmDgVVXjucgBcGaP0
+0jPg/73RVDkpDw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
-MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx
-MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV
-BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG
-29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk
-oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk
-3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL
-qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN
-nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw
-DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG
-MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX
-ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H
-DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO
-TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv
-kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w
-zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa
+MIICqDCCAi2gAwIBAgIQNBdlEkA7t1aALYDLeVWmHjAKBggqhkjOPQQDAzCBlDEL
+MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
+VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
+bGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
+RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
+VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
+bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAyIFB1
+YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATR2UqOTA2ESlG6fO/TzPo6mrWnYxM9AeBJPvrBR8mS
+szrX/m+c95o6D/UOCgrDP8jnEhSO1dVtmCyzcTIK6yq99tdqIAtnRZzSsr9TImYJ
+XdsR8/EFM1ij4rjPfM2Cm72jQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBQ9MvM6qQyQhPmijGkGYVQvh3L+BTAKBggqhkjOPQQD
+AwNpADBmAjEAyKapr0F/tckRQhZoaUxcuCcYtpjxwH+QbYfTjEYX8D5P/OqwCMR6
+S7wIL8fip29lAjEA1lnehs5fDspU1cbQFQ78i5Ry1I4AWFPPfrFLDeVQhuuea9//
+KabYR9mglhjb8kWz
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
-rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
-OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
-xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
-7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
-aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
-SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
-ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
-AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
-R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
-JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
-Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE
-SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw
-ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU
-REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr
-2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s
-2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU
-GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj
-dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r
-TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/
-BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB
-AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv
-c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl
-ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu
-MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg
-T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud
-HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD
-VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny
-bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
-MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ
-J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG
-SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom
-JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO
-inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y
-caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB
-mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ
-YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9
-BKNDLdr8C2LqL19iUw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
-MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
-dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
-BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
-MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
-eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
-/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
-wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
-AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
-PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
-AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
-MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
-HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
-Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
-f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
-rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
-6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
-7CAFYd4=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
-BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
-cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
-MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
-Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
-thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
-cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
-L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
-NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
-X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
-m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
-Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
-EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
-KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
-6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
-OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
-VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
-ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
-AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
-661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
-am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
-ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
-PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
-3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
-SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
-3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
-ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
-StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
-Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
-jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
-ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
-MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
-LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
-RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
-WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
-Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
-AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
-eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
-zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
-WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
-/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
-MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
-ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
-cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
-WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
-Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
-IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
-UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
-TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
-BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
-kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
-AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
-sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
-I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
-J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
-VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
-03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
-NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
-AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
-E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
-/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
-DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
-GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
-tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
-AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
-WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
-9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
-gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
-2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
-LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
-4uJEvlz36hz1
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb
-BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz
-MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx
-FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g
-Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2
-fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl
-LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV
-WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF
-TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb
-5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc
-CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri
-wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ
-wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG
-m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4
-F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng
-WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0
-2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
-AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/
-0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw
-F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS
-g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj
-qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN
-h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/
-ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V
-btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj
-Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ
-8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW
-gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx
-HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD
-b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv
-b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx
-MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl
-ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0
-aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
-eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e
-eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq
-wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV
-WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO
-2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+
-H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU
-yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
-MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH
-lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB
-MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj
-YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu
-Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl
-cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k
-IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp
-ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz
-aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu
-Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw
-bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG
-SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS
-9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y
-m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv
-Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961
-kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH
-CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx
-CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp
-ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa
-QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw
-NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft
-ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu
-QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG
-qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL
-fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ
-Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4
-Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ
-54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b
-MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j
-ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej
-YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt
-A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF
-rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ
-pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB
-lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy
-YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50
-7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs
-YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6
-xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc
-unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/
-Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp
-ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42
-gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0
-jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+
-XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD
-W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/
-RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r
-MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk
-BYn8eNZcLCZDqQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
-ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
-l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
-HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
-5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
-WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
-gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
-DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
-BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
-h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
-LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
-BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
-Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
-cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
-aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
-F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
-8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
-rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
-/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
-7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
-28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
-lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
-nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
-0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
-5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
-WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
-jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
-KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
-ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
-OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
-619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
-2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
-o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
-nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
-5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
-pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
-dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
-BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
-AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
-QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
-MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
-0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
-UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
-RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
-OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
-JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
-AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
-BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
-LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
-MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
-44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
-Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
-i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
-9u6wWk5JRFRYX0KD
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
-V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
-4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
-H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
-8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
-vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
-mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
-btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
-T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
-WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
-c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
-4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
-VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
-CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
-aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
-aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
-dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
-czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
-A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
-Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
-7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
-d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
-+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
-4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
-t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
-DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
-k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
-zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
-Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
-mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
-4SVhM7JZG+Ju1zdXtg2pEto=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
-TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
-MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
-Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
-IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
-dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
-V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
-GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
-v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
-AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
-Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
-76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
-OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
-ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
-yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
-buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
-2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDyzCCArOgAwIBAgIDAOJIMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYDVQQGEwJB
-VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
-bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRgwFgYDVQQLDA9BLVRydXN0LVF1
-YWwtMDIxGDAWBgNVBAMMD0EtVHJ1c3QtUXVhbC0wMjAeFw0wNDEyMDIyMzAwMDBa
-Fw0xNDEyMDIyMzAwMDBaMIGLMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVz
-dCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
-a2VociBHbWJIMRgwFgYDVQQLDA9BLVRydXN0LVF1YWwtMDIxGDAWBgNVBAMMD0Et
-VHJ1c3QtUXVhbC0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJaR
-q9eOsFm4Ab20Hq2Z/aH86gyWa48uSUjY6eQkguHYuszr3gdcSMYZggFHQgnhfLmf
-ro/27l5rqKhWiDhWs+b+yZ1PNDhRPJy+86ycHMg9XJqErveULBSyZDdgjhSwOyrN
-ibUir/fkf+4sKzP5jjytTKJXD/uCxY4fAd9TjMEVpN3umpIS0ijpYhclYDHvzzGU
-833z5Dwhq5D8bc9jp8YSAHFJ1xzIoO1jmn3jjyjdYPnY5harJtHQL73nDQnfbtTs
-5ThT9GQLulrMgLU4WeyAWWWEMWpfVZFMJOUkmoOEer6A8e5fIAeqdxdsC+JVqpZ4
-CAKel/Arrlj1gFA//jsCAwEAAaM2MDQwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4E
-CgQIQj0rJKbBRc4wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBG
-yxFjUA2bPkXUSC2SfJ29tmrbiLKal+g6a9M8Xwd+Ejo+oYkNP6F4GfeDtAXpm7xb
-9Ly8lhdbHcpRhzCUQHJ1tBCiGdLgmhSx7TXjhhanKOdDgkdsC1T+++piuuYL72TD
-gUy2Sb1GHlJ1Nc6rvB4fpxSDAOHqGpUq9LWsc3tFkXqRqmQVtqtR77npKIFBioc6
-2jTBwDMPX3hDJDR1DSPc6BnZliaNw2IHdiMQ0mBoYeRnFdq+TyDKsjmJOOQPLzzL
-/saaw6F891+gBjLFEFquDyR73lAPJS279R3csi8WWk4ZYUC/1V8H3Ktip/J6ac8e
-qhLCbmJ81Lo92JGHz/ot
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
-DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
-ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
-VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
-mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
-IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
-mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
-XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
-dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
-jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
-BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
-DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
-9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
-Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
-ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
-R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
-NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
-NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
-ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
-BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
-Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
-4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
-KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
-rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
-94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
-sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
-gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
-kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
-vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
-O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
-AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
-9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
-eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
-0vdXcDazv/wor3ElhVsT/h5/WrQ8
+MIID9jCCAt6gAwIBAgIQZIKe/DcedF38l/+XyLH/QTANBgkqhkiG9w0BAQsFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAy
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNzOkFyGOFyz9AYxe9GPo15gRn
+V2WYKaRPyVyPDzTS+NqoE2KquB5QZ3iwFkygOakVeq7t0qLA8JA3KRgmXOgNPLZs
+ST/B4NzZS7YUGQum05bh1gnjGSYc+R9lS/kaQxwAg9bQqkmi1NvmYji6UBRDbfkx
++FYW2TgCkc/rbN27OU6Z4TBnRfHU8I3D3/7yOAchfQBeVkSz5GC9kSucq1sEcg+y
+KNlyqwUgQiWpWwNqIBDMMfAr2jUs0Pual07wgksr2F82owstr2MNHSV/oW5cYqGN
+KD6h/Bwg+AEvulWaEbAZ0shQeWsOagXXqgQ2sqPy4V93p3ec5R7c6d9qwWVdAgMB
+AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSHjCCVyJhK0daABkqQNETfHE2/sDANBgkqhkiG9w0BAQsFAAOCAQEAgY6ypWaW
+tyGltu9vI1pf24HFQqV4wWn99DzX+VxrcHIa/FqXTQCAiIiCisNxDY7FiZss7Y0L
+0nJU9X3UXENX6fOupQIR9nYrgVfdfdp0MP1UR/bgFm6mtApI5ud1Bw8pGTnOefS2
+bMVfmdUfS/rfbSw8DVSAcPCIC4DPxmiiuB1w2XaM/O6lyc+tHc+ZJVdaYkXLFmu9
+Sc2lo4xpeSWuuExsi0BmSxY/zwIa3eFsawdhanYVKZl/G92IgMG/tY9zxaaWI4Sm
+KIYkM2oBLldzJbZev4/mHWGoQClnHYebHX+bn5nNMdZUvmK7OaxoEkiRIKXLsd3+
+b/xa5IJVWa8xqQ==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIICpzCCAi2gAwIBAgIQTHm1miicdjFk9YlE0JEC3jAKBggqhkjOPQQDAzCBlDEL
@@ -3786,27 +3499,201 @@
 xcX+i93B3294n5E=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
+MIIF9jCCA96gAwIBAgIQZWNxhdNvRcaPfzH5CYeSgjANBgkqhkiG9w0BAQwFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAz
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3DrL6TbyachX7d1vb/UMPywv3
+YC6zK34Mu1PyzE5l8xm7/zUd99Opu0Attd141Kb5N+qFBXttt+YTSwZ8+3ZjjyAd
+LTgrBIXy6LDRX01KIclq2JTqHgJQpqqQB6BHIepm+QSg5oPwxPVeluInTWHDs8GM
+IrZmoQDRVin77cF/JMo9+lqUsITDx7pDHP1kDvEo+0dZ8ibhMblE+avd+76+LDfj
+rAsY0/wBovGkCjWCR0yrvYpe3xOF/CDMSFmvr0FvyyPNypOn3dVfyGQ7/wEDoApP
+LW49hL6vyDKyUymQFfewBZoKPPa5BpDJpeFdoDuw/qi2v/WJKFckOiGGceTciotB
+VeweMCRZ0cBZuHivqlp03iWAMJjtMERvIXAc2xJTDtamKGaTLB/MTzwbgcW59nhv
+0DI6CHLbaw5GF4WU87zvvPekXo7p6bVk5bdLRRIsTDe3YEMKTXEGAJQmNXQfu3o5
+XE475rgD4seTi4QsJUlF3X8jlGAfy+nN9quX92Hn+39igcjcCjBcGHzmzu/Hbh6H
+fLPpysh7avRo/IOlDFa0urKNSgrHl5fFiDAVPRAIVBVycmczM/R8t84AJ1NlziTx
+WmTnNi/yLgLCl99y6AIeoPc9tftoYAP6M6nmEm0G4amoXU48/tnnAGWsthlNe4N/
+NEfq4RhtsYsceavnnQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUOXEIAD7eyIbnkP/k/SEPziQZFvYwDQYJKoZIhvcN
+AQEMBQADggIBAFBriE1gSM5a4yLOZ3yEp80c/ekMA4w2rwqHDmquV64B0Da78v25
+c8FftaiuTKL6ScsHRhY2vePIVzh+OOS/JTNgxtw3nGO7XpgeGrKC8K6mdxGAREeh
+KcXwszrOmPC47NMOgAZ3IzBM/3lkYyJbd5NDS3Wz2ztuO0rd8ciutTeKlYg6EGhw
+OLlbcH7VQ8n8X0/l5ns27vAg7UdXEyYQXhQGDXt2B8LGLRb0rqdsD7yID08sAraj
+1yLmmUc12I2lT4ESOhF9s8wLdfMecKMbA+r6mujmLjY5zJnOOj8Mt674Q5mwk25v
+qtkPajGRu5zTtCj7g0x6c4JQZ9IOrO1gxbJdNZjPh34eWR0kvFa62qRa2MzmvB4Q
+jxuMjvPB27e+1LBbZY8WaPNWxSoZFk0PuGWHbSSDuGLc4EdhGoh7zk5//dzGDVqa
+pPO1TPbdMaboHREhMzAEYX0c4D5PjT+1ixIAWn2poQDUg+twuxj4pNIcgS23CBHI
+Jnu21OUPA0Zy1CVAHr5JXW2T8VyyO3VUaTqg7kwiuqya4gitRWMFSlI1dsQ09V4H
+Mq3cfCbRW4+t5OaqG3Wf61206MCpFXxOSgdy30bJ1JGSdVaw4e43NmUoxRXIK3bM
+bW8Zg/T92hXiQeczeUaDV/nxpbZt07zXU+fucW14qZen7iCcGRVyFT0E
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB
+BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj
+emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx
+MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg
+Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml
+6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K
+ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm
+nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo
+ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb
+eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH
+3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA
+A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg
+haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu
+GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV
+lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd
+fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw
+cH0mX548PojGyg434cDjkSXa3mHF
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
+IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
+BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
+MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
+d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
+YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
+dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
+BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
+papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
+DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
+KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
+XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
+Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
+LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
+MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
+gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
+YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
+b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
+9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
+zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
+OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
+2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
+oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
+t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
+KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
+m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
+MdRAGmI0Nj81Aa6sY6A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
+NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
+LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
+A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
+W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
+3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
+6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
+Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
+NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
+r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
+DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
+YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
+/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
+LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
+jVaMaA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIGHDCCBASgAwIBAgIES45gAzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE
@@ -3844,74 +3731,77 @@
 cbBsn0R9fFLO4El62S9eH1tqOzO20OAOK65yJIsOpSE=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
-MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
-dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
-WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
-VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
-9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
-DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
-Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
-QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
-xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
-A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
-kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
-Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
-Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
-JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
-RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
+MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
+ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
+MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
+MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
+iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
+vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
+0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
+OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
+BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
+FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
+GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
+zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
+1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
+f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
+jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
+ZetX2fNXlrtIzYE=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
-ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
-MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
-dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
-c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
-UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
-58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
-o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
-MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
-aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
-A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
-Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
-8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV
-BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt
-ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4
-MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl
-a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h
-4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk
-tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s
-tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL
-dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4
-c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um
-TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z
-+kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O
-Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW
-OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW
-fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2
-l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
-/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw
-FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+
-8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI
-6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO
-TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME
-wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY
-Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn
-xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q
-DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q
-Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t
-hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4
-7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7
-QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
@@ -3969,30 +3859,284 @@
 qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEYDCCA0igAwIBAgICATAwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCVVMx
-GDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UE
-AxMYRmVkZXJhbCBDb21tb24gUG9saWN5IENBMB4XDTEwMTIwMTE2NDUyN1oXDTMw
-MTIwMTE2NDUyN1owWTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJu
-bWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UEAxMYRmVkZXJhbCBDb21tb24gUG9s
-aWN5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2HX7NRY0WkG/
-Wq9cMAQUHK14RLXqJup1YcfNNnn4fNi9KVFmWSHjeavUeL6wLbCh1bI1FiPQzB6+
-Duir3MPJ1hLXp3JoGDG4FyKyPn66CG3G/dFYLGmgA/Aqo/Y/ISU937cyxY4nsyOl
-4FKzXZbpsLjFxZ+7xaBugkC7xScFNknWJidpDDSPzyd6KgqjQV+NHQOGgxXgVcHF
-mCye7Bpy3EjBPvmE0oSCwRvDdDa3ucc2Mnr4MrbQNq4iGDGMUHMhnv6DOzCIJOPp
-wX7e7ZjHH5IQip9bYi+dpLzVhW86/clTpyBLqtsgqyFOHQ1O5piF5asRR12dP8Qj
-wOMUBm7+nQIDAQABo4IBMDCCASwwDwYDVR0TAQH/BAUwAwEB/zCB6QYIKwYBBQUH
-AQsEgdwwgdkwPwYIKwYBBQUHMAWGM2h0dHA6Ly9odHRwLmZwa2kuZ292L2ZjcGNh
-L2NhQ2VydHNJc3N1ZWRCeWZjcGNhLnA3YzCBlQYIKwYBBQUHMAWGgYhsZGFwOi8v
-bGRhcC5mcGtpLmdvdi9jbj1GZWRlcmFsJTIwQ29tbW9uJTIwUG9saWN5JTIwQ0Es
-b3U9RlBLSSxvPVUuUy4lMjBHb3Zlcm5tZW50LGM9VVM/Y0FDZXJ0aWZpY2F0ZTti
-aW5hcnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUrQx6dVzl85jEeZgOrCj9l/TnAvwwDQYJKoZIhvcNAQELBQAD
-ggEBAI9z2uF/gLGH9uwsz9GEYx728Yi3mvIRte9UrYpuGDco71wb5O9Qt2wmGCMi
-TR0mRyDpCZzicGJxqxHPkYnos/UqoEfAFMtOQsHdDA4b8Idb7OV316rgVNdF9IU+
-7LQd3nyKf1tNnJaK0KIyn9psMQz4pO9+c+iR3Ah6cFqgr2KBWfgAdKLI3VTKQVZH
-venAT+0g3eOlCd+uKML80cgX2BLHb94u6b2akfI8WpQukSKAiaGMWMyDeiYZdQKl
-Dn0KJnNR6obLB6jI/WNaNZvSr79PMUjBhHDbNXuaGQ/lj/RqDG8z2esccKIN47lQ
-A2EC/0rskqTcLe4qNJMHtyznGI8=
+MIIFkjCCA3qgAwIBAgIBCDANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJDTjER
+MA8GA1UEChMIVW5pVHJ1c3QxGDAWBgNVBAMTD1VDQSBHbG9iYWwgUm9vdDAeFw0w
+ODAxMDEwMDAwMDBaFw0zNzEyMzEwMDAwMDBaMDoxCzAJBgNVBAYTAkNOMREwDwYD
+VQQKEwhVbmlUcnVzdDEYMBYGA1UEAxMPVUNBIEdsb2JhbCBSb290MIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2rPlBlA/9nP3xDK/RqUlYjOHsGj+p9+I
+A2N9Apb964fJ7uIIu527u+RBj8cwiQ9tJMAEbBSUgU2gDXRm8/CFr/hkGd656YGT
+0CiFmUdCSiw8OCdKzP/5bBnXtfPvm65bNAbXj6ITBpyKhELVs6OQaG2BkO5NhOxM
+cE4t3iQ5zhkAQ5N4+QiGHUPR9HK8BcBn+sBR0smFBySuOR56zUHSNqth6iur8CBV
+mTxtLRwuLnWW2HKX4AzKaXPudSsVCeCObbvaE/9GqOgADKwHLx25urnRoPeZnnRc
+GQVmMc8+KlL+b5/zub35wYH1N9ouTIElXfbZlJrTNYsgKDdfUet9Ysepk9H50DTL
+qScmLCiQkjtVY7cXDlRzq6987DqrcDOsIfsiJrOGrCOp139tywgg8q9A9f9ER3Hd
+J90TKKHqdjn5EKCgTUCkJ7JZFStsLSS3JGN490MYeg9NEePorIdCjedYcaSrbqLA
+l3y74xNLytu7awj5abQEctXDRrl36v+6++nwOgw19o8PrgaEFt2UVdTvyie3AzzF
+HCYq9TyopZWbhvGKiWf4xwxmse1Bv4KmAGg6IjTuHuvlb4l0T2qqaqhXZ1LUIGHB
+zlPL/SR/XybfoQhplqCe/klD4tPq2sTxiDEhbhzhzfN1DiBEFsx9c3Q1RSw7gdQg
+7LYJjD5IskkCAwEAAaOBojCBnzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zBj
+BgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcD
+BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF
+BwMJMB0GA1UdDgQWBBTZw9P4gJJnzF3SOqLXcaK0xDiALTANBgkqhkiG9w0BAQUF
+AAOCAgEA0Ih5ygiq9ws0oE4Jwul+NUiJcIQjL1HDKy9e21NrW3UIKlS6Mg7VxnGF
+sZdJgPaE0PC6t3GUyHlrpsVE6EKirSUtVy/m1jEp+hmJVCl+t35HNmktbjK81HXa
+QnO4TuWDQHOyXd/URHOmYgvbqm4FjMh/Rk85hZCdvBtUKayl1/7lWFZXbSyZoUkh
+1WHGjGHhdSTBAd0tGzbDLxLMC9Z4i3WA6UG5iLHKPKkWxk4V43I29tSgQYWvimVw
+TbVEEFDs7d9t5tnGwBLxSzovc+k8qe4bqi81pZufTcU0hF8mFGmzI7GJchT46U1R
+IgP/SobEHOh7eQrbRyWBfvw0hKxZuFhD5D1DCVR0wtD92e9uWfdyYJl2b/Unp7uD
+pEqB7CmB9HdL4UISVdSGKhK28FWbAS7d9qjjGcPORy/AeGEYWsdl/J1GW1fcfA67
+loMQfFUYCQSu0feLKj6g5lDWMDbX54s4U+xJRODPpN/xU3uLWrb2EZBL1nXz/gLz
+Ka/wI3J9FO2pXd96gZ6bkiL8HvgBRUGXx2sBYb4zaPKgZYRmvOAqpGjTcezHCN6j
+w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7
+OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER
+MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw
+MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu
+aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC
+XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB
+a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD
+Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx
+QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ
+th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC
+AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG
+CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD
+BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d
+SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg
+14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe
+JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU
+LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr
+A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9
++tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
+kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
+IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
+VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
+dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
+E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
+D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
+4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
+lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
+bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
+o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
+MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
+LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
+BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
+AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
+Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
+j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
+KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
+2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
+mfnGV/TJVTl4uix5yaaIK/QI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB
+rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt
+Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa
+Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV
+BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l
+dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE
+AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B
+YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9
+hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l
+L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm
+SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM
+1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
+6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw
+Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50
+aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
+AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u
+7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0
+xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ
+rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim
+eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk
+USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB
+lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt
+T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc
+BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3
+dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP
+HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO
+KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo
+5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+
+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb
+kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC
+AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov
+L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV
+HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN
+AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
+NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB
+mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU
+4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5
+81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR
+Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
+nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
+8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
+ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
+PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
+6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
+n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
+qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
+wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
+ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
+pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
+E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
+aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
+IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
+Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
+BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
+Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
+Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
+Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
+IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
+J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
+JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
+wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
+koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
+qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
+Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
+xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
+7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
+sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
+sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
+cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
+N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
+KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
+kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
+CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
+Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
+imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
+2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
+DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
+/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
+F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
+TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
@@ -4016,529 +4160,106 @@
 FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
-BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1
-c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy
-MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl
-ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm
-BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF
-5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv
-DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v
-zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT
-yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj
-dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh
-MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB
-Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI
-4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz
-dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY
-aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G
-DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
-CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH
-LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
+nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
+t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
+SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
+BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
+rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
+NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
+BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
+MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
+p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
+5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
+WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
+4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
+hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB
-BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj
-emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx
-MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
-cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg
-Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml
-6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K
-ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm
-nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo
-ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb
-eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH
-3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA
-A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg
-haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu
-GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV
-lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd
-fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw
-cH0mX548PojGyg434cDjkSXa3mHF
+MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
+vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
+ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
+IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
+IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
+bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
+9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
+H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
+LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
+/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
+rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
+WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
+exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
+DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
+sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
+seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
+4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
+lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
+7M2CYfE45k+XmCpajQ==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
-S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
-SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
-WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
-bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
-UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
-bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
-LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
-J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
-R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
-Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
-JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
-zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
-Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
-KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
-ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
-Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
-gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
-uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
-y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
+CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
+dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
+cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
+2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
+lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
+ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
+299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
+vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
+dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
+AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
+zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
+LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
+7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
+++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
-MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
-IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
-bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
-RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
-zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
-bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
-MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
-VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
-OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
-tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
-q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
-EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
-Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
-VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICqDCCAi2gAwIBAgIQNBdlEkA7t1aALYDLeVWmHjAKBggqhkjOPQQDAzCBlDEL
-MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
-VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
-bGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
-RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
-VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
-bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAyIFB1
-YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
-hkjOPQIBBgUrgQQAIgNiAATR2UqOTA2ESlG6fO/TzPo6mrWnYxM9AeBJPvrBR8mS
-szrX/m+c95o6D/UOCgrDP8jnEhSO1dVtmCyzcTIK6yq99tdqIAtnRZzSsr9TImYJ
-XdsR8/EFM1ij4rjPfM2Cm72jQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBQ9MvM6qQyQhPmijGkGYVQvh3L+BTAKBggqhkjOPQQD
-AwNpADBmAjEAyKapr0F/tckRQhZoaUxcuCcYtpjxwH+QbYfTjEYX8D5P/OqwCMR6
-S7wIL8fip29lAjEA1lnehs5fDspU1cbQFQ78i5Ry1I4AWFPPfrFLDeVQhuuea9//
-KabYR9mglhjb8kWz
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
-ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
-N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
-tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
-0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
-/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
-KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
-zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
-O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
-34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
-K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
-Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
-QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
-cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
-IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
-HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
-O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
-033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
-dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
-kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
-3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
-u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
-4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIF9jCCA96gAwIBAgIQZWNxhdNvRcaPfzH5CYeSgjANBgkqhkiG9w0BAQwFADCB
-lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
-HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
-YyBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzYwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
-BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
-eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3DrL6TbyachX7d1vb/UMPywv3
-YC6zK34Mu1PyzE5l8xm7/zUd99Opu0Attd141Kb5N+qFBXttt+YTSwZ8+3ZjjyAd
-LTgrBIXy6LDRX01KIclq2JTqHgJQpqqQB6BHIepm+QSg5oPwxPVeluInTWHDs8GM
-IrZmoQDRVin77cF/JMo9+lqUsITDx7pDHP1kDvEo+0dZ8ibhMblE+avd+76+LDfj
-rAsY0/wBovGkCjWCR0yrvYpe3xOF/CDMSFmvr0FvyyPNypOn3dVfyGQ7/wEDoApP
-LW49hL6vyDKyUymQFfewBZoKPPa5BpDJpeFdoDuw/qi2v/WJKFckOiGGceTciotB
-VeweMCRZ0cBZuHivqlp03iWAMJjtMERvIXAc2xJTDtamKGaTLB/MTzwbgcW59nhv
-0DI6CHLbaw5GF4WU87zvvPekXo7p6bVk5bdLRRIsTDe3YEMKTXEGAJQmNXQfu3o5
-XE475rgD4seTi4QsJUlF3X8jlGAfy+nN9quX92Hn+39igcjcCjBcGHzmzu/Hbh6H
-fLPpysh7avRo/IOlDFa0urKNSgrHl5fFiDAVPRAIVBVycmczM/R8t84AJ1NlziTx
-WmTnNi/yLgLCl99y6AIeoPc9tftoYAP6M6nmEm0G4amoXU48/tnnAGWsthlNe4N/
-NEfq4RhtsYsceavnnQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUOXEIAD7eyIbnkP/k/SEPziQZFvYwDQYJKoZIhvcN
-AQEMBQADggIBAFBriE1gSM5a4yLOZ3yEp80c/ekMA4w2rwqHDmquV64B0Da78v25
-c8FftaiuTKL6ScsHRhY2vePIVzh+OOS/JTNgxtw3nGO7XpgeGrKC8K6mdxGAREeh
-KcXwszrOmPC47NMOgAZ3IzBM/3lkYyJbd5NDS3Wz2ztuO0rd8ciutTeKlYg6EGhw
-OLlbcH7VQ8n8X0/l5ns27vAg7UdXEyYQXhQGDXt2B8LGLRb0rqdsD7yID08sAraj
-1yLmmUc12I2lT4ESOhF9s8wLdfMecKMbA+r6mujmLjY5zJnOOj8Mt674Q5mwk25v
-qtkPajGRu5zTtCj7g0x6c4JQZ9IOrO1gxbJdNZjPh34eWR0kvFa62qRa2MzmvB4Q
-jxuMjvPB27e+1LBbZY8WaPNWxSoZFk0PuGWHbSSDuGLc4EdhGoh7zk5//dzGDVqa
-pPO1TPbdMaboHREhMzAEYX0c4D5PjT+1ixIAWn2poQDUg+twuxj4pNIcgS23CBHI
-Jnu21OUPA0Zy1CVAHr5JXW2T8VyyO3VUaTqg7kwiuqya4gitRWMFSlI1dsQ09V4H
-Mq3cfCbRW4+t5OaqG3Wf61206MCpFXxOSgdy30bJ1JGSdVaw4e43NmUoxRXIK3bM
-bW8Zg/T92hXiQeczeUaDV/nxpbZt07zXU+fucW14qZen7iCcGRVyFT0E
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
-CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
-ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
-RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
-UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
-Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
-hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
-Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
-RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
-AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
-JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
-6pZjamVFkpUBtA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEUzCCAzugAwIBAgIDAOJDMA0GCSqGSIb3DQEBBQUAMIHPMQswCQYDVQQGEwJB
-VDGBizCBiAYDVQQKHoGAAEEALQBUAHIAdQBzAHQAIABHAGUAcwAuACAAZgD8AHIA
-IABTAGkAYwBoAGUAcgBoAGUAaQB0AHMAcwB5AHMAdABlAG0AZQAgAGkAbQAgAGUA
-bABlAGsAdAByAC4AIABEAGEAdABlAG4AdgBlAHIAawBlAGgAcgAgAEcAbQBiAEgx
-GDAWBgNVBAsTD0EtVHJ1c3QtUXVhbC0wMTEYMBYGA1UEAxMPQS1UcnVzdC1RdWFs
-LTAxMB4XDTA0MTEzMDIzMDAwMFoXDTE0MTEzMDIzMDAwMFowgc8xCzAJBgNVBAYT
-AkFUMYGLMIGIBgNVBAoegYAAQQAtAFQAcgB1AHMAdAAgAEcAZQBzAC4AIABmAPwA
-cgAgAFMAaQBjAGgAZQByAGgAZQBpAHQAcwBzAHkAcwB0AGUAbQBlACAAaQBtACAA
-ZQBsAGUAawB0AHIALgAgAEQAYQB0AGUAbgB2AGUAcgBrAGUAaAByACAARwBtAGIA
-SDEYMBYGA1UECxMPQS1UcnVzdC1RdWFsLTAxMRgwFgYDVQQDEw9BLVRydXN0LVF1
-YWwtMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmhgdxIbxTGEOH
-fXGiewI3NFldAWKFWfLofO+5I1UbvA5avt7IgsGXz/tI/f5HGUbascI0i7xG0tqV
-lA5ctQgLRqxgxHtgTkMcqsAEYdsz3LZsCdXO1QrvEBGLTSABdxiL/gSWJ6z77CSw
-x7Xg02HwxPV82cjGkSF3ENGJntuIAAnRDWn/ORHjFatNRymoMbHaOEZXSGhf7Y5F
-rrHEqGyi9E6sv784De/T1aTvskn8cWeUmDzv//omiG/a/V9KQex/61XN8OthUQVn
-X+u/liL2NKx74I2C/GgHX5B0WkPNqsSOgmlvJ/cKuT0PveUgVFDAA0oYBgcE1KDM
-lBbN0kmPAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECEs8jB2F
-6W+tMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAIUusmJzMJRiQ
-8TAHrJAOelfuWoTGcqdIv7Tys/fNl2yF2fjvHT8J01aKialFVpbVeQ2XKb1O2bHO
-QYAKgsdZ2jZ/sdL2UVFRTHmidLu6PdgWCBRhJYQELQophO9QVvfhAA0TwbESYqTz
-+nlI5Gr7CZe8f6HEmhJmCtUQsdQCufGglRh4T+tIGiNGcnyVEHZ93mSVepFr1VA2
-9CTRPteuGjA81jeAz9peYiFE1CXvxK9cJiv0BcALFLWmADCoRLzIRZhA+sAwYUmw
-M1rqVCPA3kBQvIC95tyQvNy2dG0Vs+O6PwLaNX/suSlElQ06X2l1VwMaYb4vZKFq
-N0bOhBXEVg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIJmzCCB4OgAwIBAgIBATANBgkqhkiG9w0BAQwFADCCAR4xPjA8BgNVBAMTNUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
-YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
-dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
-aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
-IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
-KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyMjE4MDgy
-MVoXDTMwMTIxNzIzNTk1OVowggEeMT4wPAYDVQQDEzVBdXRvcmlkYWQgZGUgQ2Vy
-dGlmaWNhY2lvbiBSYWl6IGRlbCBFc3RhZG8gVmVuZXpvbGFubzELMAkGA1UEBhMC
-VkUxEDAOBgNVBAcTB0NhcmFjYXMxGTAXBgNVBAgTEERpc3RyaXRvIENhcGl0YWwx
-NjA0BgNVBAoTLVNpc3RlbWEgTmFjaW9uYWwgZGUgQ2VydGlmaWNhY2lvbiBFbGVj
-dHJvbmljYTFDMEEGA1UECxM6U3VwZXJpbnRlbmRlbmNpYSBkZSBTZXJ2aWNpb3Mg
-ZGUgQ2VydGlmaWNhY2lvbiBFbGVjdHJvbmljYTElMCMGCSqGSIb3DQEJARYWYWNy
-YWl6QHN1c2NlcnRlLmdvYi52ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
-ggIBAME77xNS8ZlW47RsBeEaaRZhJoZ4rw785UAFCuPZOAVMqNS1wMYqzy95q6Gk
-UO81ER/ugiQX/KMcq/4HBn83fwdYWxPZfwBfK7BP2p/JsFgzYeFP0BXOLmvoJIzl
-Jb6FW+1MPwGBjuaZGFImWZsSmGUclb51mRYMZETh9/J5CLThR1exStxHQptwSzra
-zNFpkQY/zmj7+YZNA9yDoroVFv6sybYOZ7OxNDo7zkSLo45I7gMwtxqWZ8VkJZkC
-8+p0dX6mkhUT0QAV64Zc9HsZiH/oLhEkXjhrgZ28cF73MXIqLx1fyM4kPH1yOJi/
-R72nMwL7D+Sd6mZgI035TxuHXc2/uOwXfKrrTjaJDz8Jp6DdessOkxIgkKXRjP+F
-K3ze3n4NUIRGhGRtyvEjK95/2g02t6PeYiYVGur6ruS49n0RAaSS0/LJb6XzaAAe
-0mmO2evnEqxIKwy2mZRNPfAVW1l3wCnWiUwryBU6OsbFcFFrQm+00wOicXvOTHBM
-aiCVAVZTb9RSLyi+LJ1llzJZO3pq3IRiiBj38Nooo+2ZNbMEciSgmig7YXaUcmud
-SVQvLSL+Yw+SqawyezwZuASbp7d/0rutQ59d81zlbMt3J7yB567rT2IqIydQ8qBW
-k+fmXzghX+/FidYsh/aK+zZ7Wy68kKHuzEw1Vqkat5DGs+VzAgMBAAGjggLeMIIC
-2jASBgNVHRMBAf8ECDAGAQH/AgECMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52
-ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMB0GA1UdDgQWBBStuyIdxuDS
-Aaj9dlBSk+2YwU2u0zCCAVAGA1UdIwSCAUcwggFDgBStuyIdxuDSAaj9dlBSk+2Y
-wU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRpZmlj
-YWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAw
-DgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYD
-VQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25p
-Y2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEgZGUgU2VydmljaW9zIGRlIENl
-cnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG9w0BCQEWFmFjcmFpekBz
-dXNjZXJ0ZS5nb2IudmWCAQEwDgYDVR0PAQH/BAQDAgEGMDcGA1UdEQQwMC6CD3N1
-c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMFQGA1Ud
-HwRNMEswJKAioCCGHmhodHA6Ly93d3cuc3VzY2VydGUuZ29iLnZlL2xjcjAjoCGg
-H4YdbGRhcDovL2FjcmFpei5zdXNjZXJ0ZS5nb2IudmUwNwYIKwYBBQUHAQEEKzAp
-MCcGCCsGAQUFBzABhhtoaHRwOi8vb2NzcC5zdXNjZXJ0ZS5nb2IudmUwQAYDVR0g
-BDkwNzA1BgVghl4BAjAsMCoGCCsGAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRl
-LmdvYi52ZS9kcGMwDQYJKoZIhvcNAQEMBQADggIBAK4qy/zmZ9zBwfW3yOYtLcBT
-Oy4szJyPz7/RhNH3bPVH7HbDTGpi6JZ4YXdXMBeJE5qBF4a590Kgj8Rlnltt+Rbo
-OFQOU1UDqKuTdBsA//Zry5899fmn8jBUkg4nh09jhHHbLlaUScdz704Zz2+UVg7i
-s/r3Legxap60KzmdrmTAE9VKte1TQRgavQwVX5/2mO/J+SCas//UngI+h8SyOucq
-mjudYEgBrZaodUsagUfn/+AzFNrGLy+al+5nZeHb8JnCfLHWS0M9ZyhgoeO/czyn
-99+5G93VWNv4zfc4KiavHZKrkn8F9pg0ycIZh+OwPT/RE2zq4gTazBMlP3ACIe/p
-olkNaOEa8KvgzW96sjBZpMW49zFmyINYkcj+uaNCJrVGsXgdBmkuRGJNWFZ9r0cG
-woIaxViFBypsz045r1ESfYPlfDOavBhZ/giR/Xocm9CHkPRY2BApMMR0DUCyGETg
-Ql+L3kfdTKzuDjUp2DM9FqysQmaM81YDZufWkMhlZPfHwC7KbNougoLroa5Umeos
-bqAXWmk46SwIdWRPLLqbUpDTKooynZKpSYIkkotdgJoVZUUCY+RCO8jsVPEU6ece
-SxztNUm5UOta1OJPMwSAKRHOo3ilVb9c6lAixDdvV8MeNbqe6asM1mpCHWbJ/0rg
-5Ls9Cxx8hracyp0ev7b0
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw
-RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t
-U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx
-MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV
-BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3
-3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs
-3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4
-O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W
-igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X
-O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx
-46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU
-b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf
-5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut
-TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf
-woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID
-AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0
-dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh
-LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln
-bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY
-DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ
-sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj
-kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9
-SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL
-dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm
-WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J
-kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv
-hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C
-BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS
-Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i
-2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB
-VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3
-DscLP1I=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICmDCCAgGgAwIBAgIBDjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJVUzEY
-MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNFQ0ExFDASBgNVBAMT
-C0VDQSBSb290IENBMB4XDTA0MDYxNDEwMjAwOVoXDTQwMDYxNDEwMjAwOVowSzEL
-MAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMD
-RUNBMRQwEgYDVQQDEwtFQ0EgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEArkr2eXIS6oAKIpDkOlcQZdMGdncoygCEIU+ktqY3of5SVVXU7/it7kJ1
-EUzR4ii2vthQtbww9aAnpQxcEmXZk8eEyiGEPy+cCQMllBY+efOtKgjbQNDZ3lB9
-19qzUJwBl2BMxslU1XsJQw9SK10lPbQm4asa8E8e5zTUknZBWnECAwEAAaOBizCB
-iDAfBgNVHSMEGDAWgBT2uAQnDlYW2blj2f2hVGVBoAhILzAdBgNVHQ4EFgQU9rgE
-Jw5WFtm5Y9n9oVRlQaAISC8wDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
-Af8wJQYDVR0gBB4wHDAMBgpghkgBZQMCAQwBMAwGCmCGSAFlAwIBDAIwDQYJKoZI
-hvcNAQEFBQADgYEAHh0EQY2cZ209aBb5q0wW1ER0dc4OGzsLyqjHfaQ4TEaMmUwL
-AJRta/c4KVWLiwbODsvgJk+CaWmSL03gRW/ciVb/qDV7qh9Pyd1cOlanZTAnPog2
-i82yL3i2fK9DCC84uoxEQbgqK2jx9bIjFTwlAqITk9fGAm5mdT84IEwq1Gw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
-MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
-2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
-1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
-q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
-tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
-vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
-BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
-5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
-1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
-NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
-Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
-8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
-pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
-MrY=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw
-PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla
-MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX
-eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW
-juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl
-ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0
-eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH
-cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg
-OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K
-mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq
-s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK
-4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP
-isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J
-89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR
-T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe
-Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5
-ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N
-vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf
-hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl
-wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g
-pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn
-uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t
-DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s
-iTTa9g3nkagQ6hed8vbs
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
-VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
-cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
-BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
-VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
-0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
-ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
-A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
-aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
-flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
-6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
-L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
-1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
-MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
-QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
-arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
-Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
-FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
-P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
-9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
-uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
-9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
-A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
-OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
-+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
-KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
-DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
-H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
-I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
-5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
-3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
-Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
-MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
-D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
-OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
-fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
-IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
-oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
-/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
-rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
-3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
-7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
-yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
-qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
-hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
-xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
-SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
-HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
-emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
-AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
-7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
-DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
-F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
-a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
-Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID9jCCAt6gAwIBAgIQJDJ18h0v0gkz97RqytDzmDANBgkqhkiG9w0BAQsFADCB
-lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
-HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
-YyBDbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
-BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
-eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAx
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHOddJZKmZgiJM6kXZBxbje/SD
-6Jlz+muxNuCad6BAwoGNAcfMjL2Pffd543pMA03Z+/2HOCgs3ZqLVAjbZ/sbjP4o
-ki++t7JIp4Gh2F6Iw8w5QEFa0dzl2hCfL9oBTf0uRnz5LicKaTfukaMbasxEvxvH
-w9QRslBglwm9LiL1QYRmn81ApqkAgMEflZKf3vNI79sdd2H8f9/ulqRy0LY+/3gn
-r8uSFWkI22MQ4uaXrG7crPaizh5HmbmJtxLmodTNWRFnw2+F2EJOKL5ZVVkElauP
-N4C/DfD8HzpkMViBeNfiNfYgPym4jxZuPkjctUwH4fIa6n4KedaovetdhitNAgMB
-AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBQzQejIORIVk0jyljIuWvXalF9TYDANBgkqhkiG9w0BAQsFAAOCAQEAFeNzV7EX
-tl9JaUSm9l56Z6zS3nVJq/4lVcc6yUQVEG6/MWvL2QeTfxyFYwDjMhLgzMv7OWyP
-4lPiPEAz2aSMR+atWPuJr+PehilWNCxFuBL6RIluLRQlKCQBZdbqUqwFblYSCT3Q
-dPTXvQbKqDqNVkL6jXI+dPEDct+HG14OelWWLDi3mIXNTTNEyZSPWjEwN0ujOhKz
-5zbRIWhLLTjmU64cJVYIVgNnhJ3Gw84kYsdMNs+wBkS39V8C3dlU6S+QTnrIToNA
-DJqXPDe/v+z28LSFdyjBC8hnghAXOKK3Buqbvzr46SMHv3TgmDgVVXjucgBcGaP0
-0jPg/73RVDkpDw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
-MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
-NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
-PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
-x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
-QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
-yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
-QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
-H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
-QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
-i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
-nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
-rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
-hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
-tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
-GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
-lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
-+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
-TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
-nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
-gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
-G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
-zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
-L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
-MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
-YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
-MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
-ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
-MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
-ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
-PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
-wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
-EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
-avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
-YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
-sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
-/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
-IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
-OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
-TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
-HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
-dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
-ReYNnyicsbkqWletNw+vHX/bvZ8=
+MIID+TCCAuGgAwIBAgIQW1fXqEywr9nTb0ugMbTW4jANBgkqhkiG9w0BAQUFADB5
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xKjAoBgNVBAMTIVZpc2EgSW5m
+b3JtYXRpb24gRGVsaXZlcnkgUm9vdCBDQTAeFw0wNTA2MjcxNzQyNDJaFw0yNTA2
+MjkxNzQyNDJaMHkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQL
+EyZWaXNhIEludGVybmF0aW9uYWwgU2VydmljZSBBc3NvY2lhdGlvbjEqMCgGA1UE
+AxMhVmlzYSBJbmZvcm1hdGlvbiBEZWxpdmVyeSBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyREA4R/QkkfpLx0cYjga/EhIPZpchH0MZsRZ
+FfP6C2ITtf/Wc+MtgD4yTK0yoiXvni3d+aCtEgK3GDvkdgYrgF76ROJFZwUQjQ9l
+x42gRT05DbXvWFoy7dTglCZ9z/Tt2Cnktv9oxKgmkeHY/CyfpCBg1S8xth2JlGMR
+0ug/GMO5zANuegZOv438p5Lt5So+du2Gl+RMFQqEPwqN5uJSqAe0VtmB4gWdQ8on
+Bj2ZAM2R73QW7UW0Igt2vA4JaSiNtaAG/Y/58VXWHGgbq7rDtNK1R30X0kJV0rGA
+ib3RSwB3LpG7bOjbIucV5mQgJoVjoA1e05w6g1x/KmNTmOGRVwIDAQABo30wezAP
+BgNVHRMBAf8EBTADAQH/MDkGA1UdIAQyMDAwLgYFZ4EDAgEwJTAVBggrBgEFBQcC
+ARYJMS4yLjMuNC41MAwGCCsGAQUFBwICMAAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBRPitp2/2d3I5qmgH1924h1hfeBejANBgkqhkiG9w0BAQUFAAOCAQEACUW1
+QdUHdDJydgDPmYt+telnG/Su+DPaf1cregzlN43bJaJosMP7NwjoJY/H2He4XLWb
+5rXEkl+xH1UyUwF7mtaUoxbGxEvt8hPZSTB4da2mzXgwKvXuHyzF5Qjy1hOB0/pS
+WaF9ARpVKJJ7TOJQdGKBsF2Ty4fSCLqZLgfxbqwMsd9sysXI3rDXjIhekqvbgeLz
+PqZr+pfgFhwCCLSMQWl5Ll3u7Qk9wR094DZ6jj6+JCVCRUS3HyabH4OlM0Vc2K+j
+INsF/64Or7GNtRf9HYEJvrPxHINxl3JVwhYj4ASeaO4KwhVbwtw94Tc/XrGcexDo
+c5lC3rAi4/UZqweYCw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG
@@ -4565,344 +4286,28 @@
 UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
-TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
-MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
-ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
-ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
-9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
-hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
-tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
-BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
-SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
-OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
-cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
-7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
-/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
-eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
-u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
-7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
-DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
-dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
-YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
-OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
-zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
-VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
-hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
-ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
-awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
-OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
-coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
-okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
-t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
-1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
-SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
-MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
-EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
-BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
-xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
-87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
-2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
-WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
-0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
-A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
-pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
-ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
-aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
-hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
-hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
-dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
-P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
-iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
-xqE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
-RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
-IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
-MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
-LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
-YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
-A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
-K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
-sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
-MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
-XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
-HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
-4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
-vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
-CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
-WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
-oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
-h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
-f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
-B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
-vUxFnmG6v4SBkgPR0ml8xQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFkjCCA3qgAwIBAgIIAeDltYNno+AwDQYJKoZIhvcNAQEMBQAwZzEbMBkGA1UE
-AwwSQXBwbGUgUm9vdCBDQSAtIEcyMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0
-aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw
-HhcNMTQwNDMwMTgxMDA5WhcNMzkwNDMwMTgxMDA5WjBnMRswGQYDVQQDDBJBcHBs
-ZSBSb290IENBIC0gRzIxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCAiIwDQYJ
-KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgREkhI2imKScUcx+xuM23+TfvgHN6s
-XuI2pyT5f1BrTM65MFQn5bPW7SXmMLYFN14UIhHF6Kob0vuy0gmVOKTvKkmMXT5x
-ZgM4+xb1hYjkWpIMBDLyyED7Ul+f9sDx47pFoFDVEovy3d6RhiPw9bZyLgHaC/Yu
-OQhfGaFjQQscp5TBhsRTL3b2CtcM0YM/GlMZ81fVJ3/8E7j4ko380yhDPLVoACVd
-J2LT3VXdRCCQgzWTxb+4Gftr49wIQuavbfqeQMpOhYV4SbHXw8EwOTKrfl+q04tv
-ny0aIWhwZ7Oj8ZhBbZF8+NfbqOdfIRqMM78xdLe40fTgIvS/cjTf94FNcX1RoeKz
-8NMoFnNvzcytN31O661A4T+B/fc9Cj6i8b0xlilZ3MIZgIxbdMYs0xBTJh0UT8TU
-gWY8h2czJxQI6bR3hDRSj4n4aJgXv8O7qhOTH11UL6jHfPsNFL4VPSQ08prcdUFm
-IrQB1guvkJ4M6mL4m1k8COKWNORj3rw31OsMiANDC1CvoDTdUE0V+1ok2Az6DGOe
-HwOx4e7hqkP0ZmUoNwIx7wHHHtHMn23KVDpA287PT0aLSmWaasZobNfMmRtHsHLD
-d4/E92GcdB/O/WuhwpyUgquUoue9G7q5cDmVF8Up8zlYNPXEpMZ7YLlmQ1A/bmH8
-DvmGqmAMQ0uVAgMBAAGjQjBAMB0GA1UdDgQWBBTEmRNsGAPCe8CjoA1/coB6HHcm
-jTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwF
-AAOCAgEAUabz4vS4PZO/Lc4Pu1vhVRROTtHlznldgX/+tvCHM/jvlOV+3Gp5pxy+
-8JS3ptEwnMgNCnWefZKVfhidfsJxaXwU6s+DDuQUQp50DhDNqxq6EWGBeNjxtUVA
-eKuowM77fWM3aPbn+6/Gw0vsHzYmE1SGlHKy6gLti23kDKaQwFd1z4xCfVzmMX3z
-ybKSaUYOiPjjLUKyOKimGY3xn83uamW8GrAlvacp/fQ+onVJv57byfenHmOZ4VxG
-/5IFjPoeIPmGlFYl5bRXOJ3riGQUIUkhOb9iZqmxospvPyFgxYnURTbImHy99v6Z
-SYA7LNKmp4gDBDEZt7Y6YUX6yfIjyGNzv1aJMbDZfGKnexWoiIqrOEDCzBL/FePw
-N983csvMmOa/orz6JopxVtfnJBtIRD6e/J/JzBrsQzwBvDR4yGn1xuZW7AYJNpDr
-FEobXsmII9oDMJELuDY++ee1KG++P+w8j2Ud5cAeh6Squpj9kuNsJnfdBrRkBof0
-Tta6SqoWqPQFZ2aWuuJVecMsXUmPgEkrihLHdoBR37q9ZV0+N0djMenl9MU/S60E
-inpxLK8JQzcPqOMyT/RFtm2XNuyE9QoB6he7hY1Ck3DDUOUUi78/w0EP3SIEIwiK
-um1xRKtzCTrJ+VKACd+66eYWyi4uTLLT3OUEVLLUNIAytbwPF+E=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDtDCCApygAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJKUDEc
-MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEOMAwGA1UECxMFTVBIUFQxJjAk
-BgNVBAsTHU1QSFBUIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTAyMDMxNDA3
-NTAyNloXDTEyMDMxMzE0NTk1OVowYzELMAkGA1UEBhMCSlAxHDAaBgNVBAoTE0ph
-cGFuZXNlIEdvdmVybm1lbnQxDjAMBgNVBAsTBU1QSFBUMSYwJAYDVQQLEx1NUEhQ
-VCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAI3GUWlK9G9FVm8DhpKu5t37oxZbj6lZcFvEZY07YrYojWO657ub
-z56WE7q/PI/6Sm7i7qYE+Vp80r6thJvfmn7SS3BENrRqiapSenhooYD12jIe3iZQ
-2SXqx7WgYwyBGdQwGaYTijzbRFpgc0K8o4a99fIoHhz9J8AKqXasddMCqfJRaH30
-YJ7HnOvRYGL6HBrGhJ7X4Rzijyk9a9+3VOBsYcnIlx9iODoiYhA6r0ojuIu8/JA1
-oTTZrS0MyU/SLdFdJze2O1wnqTULXQybzJz3ad6oC/F5a69c0m92akYd9nGBrPxj
-EhucaQynC/QoCLs3aciLgioAnEJqy7i3EgUCAwEAAaNzMHEwHwYDVR0jBBgwFoAU
-YML3pLoA0h93Yngl8Gb/UgAh73owHQYDVR0OBBYEFGDC96S6ANIfd2J4JfBm/1IA
-Ie96MAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQE
-AwIABTANBgkqhkiG9w0BAQUFAAOCAQEANPR8DN66iWZBs/lSm1vOzhqRkXDLT6xL
-LvJtjPLqmE469szGyFSKzsof6y+/8YgZlOoeX1inF4ox/SH1ATnwdIIsPbXuRLjt
-axboXvBh5y2ffC3hmzJVvJ87tb6mVWQeL9VFUhNhAI0ib+9OIZVEYI/64MFkDk4e
-iWG5ts6oqIJH1V7dVZg6pQ1Tc0Ckhn6N1m1hD30S0/zoPn/20Wq6OCF3he8VJrRG
-dcW9BD/Bkesko1HKhMBDjHVrJ8cFwbnDSoo+Ki47eJWaz/cOzaSsaMVUsR5POava
-/abhhgHn/eOJdXiVslyK0DYscjsdB3aBUfwZlomxYOzG6CgjQPhJdw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG
-A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT
-BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw
-MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw
-YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj
-YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq
-rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo
-+rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN
-dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk
-KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq
-0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa
-2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g
-by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG
-EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo
-qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB
-MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs
-B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL
-nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0
-HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m
-Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i
-Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf
-SUJiOxMfFui61/0=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
-UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
-dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
-MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
-dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
-BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
-cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
-AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
-MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
-aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
-ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
-MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
-A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
-1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
-MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
-KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
-MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
-BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
-NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
-BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
-MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
-So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
-tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
-CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
-qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
-rD6ogRLQy7rQkgu2npaqBA+K
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
-MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
-TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
-b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
-M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
-UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
-Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
-rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
-pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
-j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
-KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
-/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
-cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
-1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
-px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
-/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
-MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
-eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
-2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
-v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
-wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
-CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
-vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
-Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
-Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
-eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
-FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
-7uzXLg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
-MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
-IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
-IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
-RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
-U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
-IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
-ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
-QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
-rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
-NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
-QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
-txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
-BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
-AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
-tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
-IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
-6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
-xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
-Cm26OWMohpLzGITY+9HPBVZkVw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
-BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
-aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
-BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
-Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
-MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
-BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
-em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
-ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
-B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
-D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
-Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
-q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
-k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
-fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
-dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
-ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
-zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
-rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
-U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
-Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
-XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
-Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
-HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
-GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
-77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
-+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
-vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
-FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
-yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
-AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
-y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
-NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDtTCCAp2gAwIBAgIIBhDCeat3PfIwDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UE
-BhMCQ0gxEjAQBgNVBAoTCVN3aXNzU2lnbjEyMDAGA1UEAxMpU3dpc3NTaWduIENB
-IChSU0EgSUsgTWF5IDYgMTk5OSAxODowMDo1OCkxHzAdBgkqhkiG9w0BCQEWEGNh
-QFN3aXNzU2lnbi5jb20wHhcNMDAxMTI2MjMyNzQxWhcNMzExMTI2MjMyNzQxWjB2
-MQswCQYDVQQGEwJDSDESMBAGA1UEChMJU3dpc3NTaWduMTIwMAYDVQQDEylTd2lz
-c1NpZ24gQ0EgKFJTQSBJSyBNYXkgNiAxOTk5IDE4OjAwOjU4KTEfMB0GCSqGSIb3
-DQEJARYQY2FAU3dpc3NTaWduLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAKw5fjnmNneLQlUCQG8jQLwwfbrOZoUwNX8cbNqhxK03/xUloFVgAt+S
-Te2RxNXaCAXLBPn5ZST35TLV57aLmbHCtifv3YZqaaQGvjedltIBMJihJhZ+h3LY
-SKsUb+xEJ3x5ZUf8jP+Q1g57y1s8SnBFWN/ni5NkF1Y1y31VwOi9wiOf/VISL+uu
-SC4i1CP1Kbz3BDs6Hht1GpRYCbJ/K0bc9oJSpWpT5PGONsGIawqMbJuyoDghsXQ1
-pbn2e8K64BSscGZVZTNooSGgNiHmACNJBYXiWVWrwXPF4l6SddmC3Rj0aKXjgECc
-FkHLDQcsM5JsK2ZLryTDUsQFbxVP2ikCAwEAAaNHMEUwCwYDVR0PBAQDAgEGMAwG
-A1UdEwQFMAMBAf8wHQYDVR0OBBYEFJbXcc05KtT8iLGKq1N4ae+PR34WMAkGA1Ud
-IwQCMAAwDQYJKoZIhvcNAQEFBQADggEBAKMy6W8HvZdS1fBpEUzl6Lvw50bgE1Xc
-HU1JypSBG9mhdcXZo5AlPB4sCvx9Dmfwhyrdsshc0TP2V3Vh6eQqnEF5qB4lVziT
-Bko9mW6Ot+pPnwsy4SHpx3rw6jCYnOqfUcZjWqqqRrq/3P1waz+Mn4cLMVEg3Xaz
-qYov/khvSqS0JniwjRlo2H6f/1oVUKZvP+dUhpQepfZrOqMAWZW4otp6FolyQyeU
-NN6UCRNiUKl5vTijbKwUUwfER/1Vci3M1/O1QCfttQ4vRN4Buc0xqYtGL3cd5WiO
-vWzyhlTzAI6VUdNkQhhHJSAyTpj6dmXDRzrryoFGa2PjgESxz7XBaSI=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
-MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
-ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
-MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
-MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
-AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
-iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
-vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
-0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
-OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
-BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
-FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
-GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
-zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
-1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
-f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
-jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
-ZetX2fNXlrtIzYE=
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
 -----END CERTIFICATE-----
 `
diff --git a/src/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go
index 2784ce2..d935cc4 100644
--- a/src/crypto/x509/root_darwin_test.go
+++ b/src/crypto/x509/root_darwin_test.go
@@ -16,6 +16,11 @@
 		t.Skipf("skipping on %s/%s, no system root", runtime.GOOS, runtime.GOARCH)
 	}
 
+	switch runtime.GOOS {
+	case "darwin":
+		t.Skipf("skipping on %s/%s until cgo part of golang.org/issue/16532 has been implemented.", runtime.GOOS, runtime.GOARCH)
+	}
+
 	t0 := time.Now()
 	sysRoots := systemRootsPool() // actual system roots
 	sysRootsDuration := time.Since(t0)
diff --git a/src/crypto/x509/root_windows.go b/src/crypto/x509/root_windows.go
index a936fec..92cc716 100644
--- a/src/crypto/x509/root_windows.go
+++ b/src/crypto/x509/root_windows.go
@@ -87,7 +87,7 @@
 		status := chainCtx.TrustStatus.ErrorStatus
 		switch status {
 		case syscall.CERT_TRUST_IS_NOT_TIME_VALID:
-			return CertificateInvalidError{c, Expired}
+			return CertificateInvalidError{c, Expired, ""}
 		default:
 			return UnknownAuthorityError{c, nil, nil}
 		}
@@ -125,7 +125,7 @@
 	if status.Error != 0 {
 		switch status.Error {
 		case syscall.CERT_E_EXPIRED:
-			return CertificateInvalidError{c, Expired}
+			return CertificateInvalidError{c, Expired, ""}
 		case syscall.CERT_E_CN_NO_MATCH:
 			return HostnameError{c, opts.DNSName}
 		case syscall.CERT_E_UNTRUSTEDROOT:
diff --git a/src/crypto/x509/sec1.go b/src/crypto/x509/sec1.go
index 33f376c..3008d0d 100644
--- a/src/crypto/x509/sec1.go
+++ b/src/crypto/x509/sec1.go
@@ -40,6 +40,12 @@
 		return nil, errors.New("x509: unknown elliptic curve")
 	}
 
+	return marshalECPrivateKeyWithOID(key, oid)
+}
+
+// marshalECPrivateKey marshals an EC private key into ASN.1, DER format and
+// sets the curve ID to the given OID, or omits it if OID is nil.
+func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
 	privateKeyBytes := key.D.Bytes()
 	paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
 	copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
diff --git a/src/crypto/x509/sec1_test.go b/src/crypto/x509/sec1_test.go
index 55b76d6..573c937 100644
--- a/src/crypto/x509/sec1_test.go
+++ b/src/crypto/x509/sec1_test.go
@@ -18,7 +18,7 @@
 	//   openssl ecparam -genkey -name secp384r1 -outform PEM
 	{"3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50", true},
 	// This key was generated by GnuTLS and has illegal zero-padding of the
-	// private key. See https://github.com/golang/go/issues/13699.
+	// private key. See https://golang.org/issues/13699.
 	{"3078020101042100f9f43a04b9bdc3ab01f53be6df80e7a7bc3eaf7b87fc24e630a4a0aa97633645a00a06082a8648ce3d030107a1440342000441a51bc318461b4c39a45048a16d4fc2a935b1ea7fe86e8c1fa219d6f2438f7c7fd62957d3442efb94b6a23eb0ea66dda663dc42f379cda6630b21b7888a5d3d", false},
 	// This was generated using an old version of OpenSSL and is missing a
 	// leading zero byte in the private key that should be present.
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
index 2b4f39d..9477e85 100644
--- a/src/crypto/x509/verify.go
+++ b/src/crypto/x509/verify.go
@@ -9,6 +9,8 @@
 	"errors"
 	"fmt"
 	"net"
+	"net/url"
+	"reflect"
 	"runtime"
 	"strings"
 	"time"
@@ -25,8 +27,8 @@
 	// 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.
+	// certificate has a name constraint which doesn't permit a DNS or
+	// other name (including IP address) in the leaf certificate.
 	CANotAuthorizedForThisName
 	// TooManyIntermediates results when a path length constraint is
 	// violated.
@@ -37,6 +39,24 @@
 	// NameMismatch results when the subject name of a parent certificate
 	// does not match the issuer name in the child.
 	NameMismatch
+	// NameConstraintsWithoutSANs results when a leaf certificate doesn't
+	// contain a Subject Alternative Name extension, but a CA certificate
+	// contains name constraints.
+	NameConstraintsWithoutSANs
+	// UnconstrainedName results when a CA certificate contains permitted
+	// name constraints, but leaf certificate contains a name of an
+	// unsupported or unconstrained type.
+	UnconstrainedName
+	// TooManyConstraints results when the number of comparision operations
+	// needed to check a certificate exceeds the limit set by
+	// VerifyOptions.MaxConstraintComparisions. This limit exists to
+	// prevent pathological certificates can consuming excessive amounts of
+	// CPU time to verify.
+	TooManyConstraints
+	// CANotAuthorizedForExtKeyUsage results when an intermediate or root
+	// certificate does not permit an extended key usage that is claimed by
+	// the leaf certificate.
+	CANotAuthorizedForExtKeyUsage
 )
 
 // CertificateInvalidError results when an odd error occurs. Users of this
@@ -44,6 +64,7 @@
 type CertificateInvalidError struct {
 	Cert   *Certificate
 	Reason InvalidReason
+	Detail string
 }
 
 func (e CertificateInvalidError) Error() string {
@@ -53,13 +74,19 @@
 	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"
+		return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail
+	case CANotAuthorizedForExtKeyUsage:
+		return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + e.Detail
 	case TooManyIntermediates:
 		return "x509: too many intermediates for path length constraint"
 	case IncompatibleUsage:
-		return "x509: certificate specifies an incompatible key usage"
+		return "x509: certificate specifies an incompatible key usage: " + e.Detail
 	case NameMismatch:
 		return "x509: issuer name does not match subject from issuing certificate"
+	case NameConstraintsWithoutSANs:
+		return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
+	case UnconstrainedName:
+		return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + e.Detail
 	}
 	return "x509: unknown error"
 }
@@ -156,6 +183,12 @@
 	// constraint down the chain which mirrors Windows CryptoAPI behavior,
 	// but not the spec. To accept any key usage, include ExtKeyUsageAny.
 	KeyUsages []ExtKeyUsage
+	// MaxConstraintComparisions is the maximum number of comparisons to
+	// perform when checking a given certificate's name constraints. If
+	// zero, a sensible default is used. This limit prevents pathalogical
+	// certificates from consuming excessive amounts of CPU time when
+	// validating.
+	MaxConstraintComparisions int
 }
 
 const (
@@ -164,37 +197,398 @@
 	rootCertificate
 )
 
-func matchNameConstraint(domain, constraint string) bool {
+// rfc2821Mailbox represents a “mailbox” (which is an email address to most
+// people) by breaking it into the “local” (i.e. before the '@') and “domain”
+// parts.
+type rfc2821Mailbox struct {
+	local, domain string
+}
+
+// parseRFC2821Mailbox parses an email address into local and domain parts,
+// based on the ABNF for a “Mailbox” from RFC 2821. According to
+// https://tools.ietf.org/html/rfc5280#section-4.2.1.6 that's correct for an
+// rfc822Name from a certificate: “The format of an rfc822Name is a "Mailbox"
+// as defined in https://tools.ietf.org/html/rfc2821#section-4.1.2”.
+func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
+	if len(in) == 0 {
+		return mailbox, false
+	}
+
+	localPartBytes := make([]byte, 0, len(in)/2)
+
+	if in[0] == '"' {
+		// Quoted-string = DQUOTE *qcontent DQUOTE
+		// non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
+		// qcontent = qtext / quoted-pair
+		// qtext = non-whitespace-control /
+		//         %d33 / %d35-91 / %d93-126
+		// quoted-pair = ("\" text) / obs-qp
+		// text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
+		//
+		// (Names beginning with “obs-” are the obsolete syntax from
+		// https://tools.ietf.org/html/rfc2822#section-4. Since it has
+		// been 16 years, we no longer accept that.)
+		in = in[1:]
+	QuotedString:
+		for {
+			if len(in) == 0 {
+				return mailbox, false
+			}
+			c := in[0]
+			in = in[1:]
+
+			switch {
+			case c == '"':
+				break QuotedString
+
+			case c == '\\':
+				// quoted-pair
+				if len(in) == 0 {
+					return mailbox, false
+				}
+				if in[0] == 11 ||
+					in[0] == 12 ||
+					(1 <= in[0] && in[0] <= 9) ||
+					(14 <= in[0] && in[0] <= 127) {
+					localPartBytes = append(localPartBytes, in[0])
+					in = in[1:]
+				} else {
+					return mailbox, false
+				}
+
+			case c == 11 ||
+				c == 12 ||
+				// Space (char 32) is not allowed based on the
+				// BNF, but RFC 3696 gives an example that
+				// assumes that it is. Several “verified”
+				// errata continue to argue about this point.
+				// We choose to accept it.
+				c == 32 ||
+				c == 33 ||
+				c == 127 ||
+				(1 <= c && c <= 8) ||
+				(14 <= c && c <= 31) ||
+				(35 <= c && c <= 91) ||
+				(93 <= c && c <= 126):
+				// qtext
+				localPartBytes = append(localPartBytes, c)
+
+			default:
+				return mailbox, false
+			}
+		}
+	} else {
+		// Atom ("." Atom)*
+	NextChar:
+		for len(in) > 0 {
+			// atext from https://tools.ietf.org/html/rfc2822#section-3.2.4
+			c := in[0]
+
+			switch {
+			case c == '\\':
+				// Examples given in RFC 3696 suggest that
+				// escaped characters can appear outside of a
+				// quoted string. Several “verified” errata
+				// continue to argue the point. We choose to
+				// accept it.
+				in = in[1:]
+				if len(in) == 0 {
+					return mailbox, false
+				}
+				fallthrough
+
+			case ('0' <= c && c <= '9') ||
+				('a' <= c && c <= 'z') ||
+				('A' <= c && c <= 'Z') ||
+				c == '!' || c == '#' || c == '$' || c == '%' ||
+				c == '&' || c == '\'' || c == '*' || c == '+' ||
+				c == '-' || c == '/' || c == '=' || c == '?' ||
+				c == '^' || c == '_' || c == '`' || c == '{' ||
+				c == '|' || c == '}' || c == '~' || c == '.':
+				localPartBytes = append(localPartBytes, in[0])
+				in = in[1:]
+
+			default:
+				break NextChar
+			}
+		}
+
+		if len(localPartBytes) == 0 {
+			return mailbox, false
+		}
+
+		// https://tools.ietf.org/html/rfc3696#section-3
+		// “period (".") may also appear, but may not be used to start
+		// or end the local part, nor may two or more consecutive
+		// periods appear.”
+		twoDots := []byte{'.', '.'}
+		if localPartBytes[0] == '.' ||
+			localPartBytes[len(localPartBytes)-1] == '.' ||
+			bytes.Contains(localPartBytes, twoDots) {
+			return mailbox, false
+		}
+	}
+
+	if len(in) == 0 || in[0] != '@' {
+		return mailbox, false
+	}
+	in = in[1:]
+
+	// The RFC species a format for domains, but that's known to be
+	// violated in practice so we accept that anything after an '@' is the
+	// domain part.
+	if _, ok := domainToReverseLabels(in); !ok {
+		return mailbox, false
+	}
+
+	mailbox.local = string(localPartBytes)
+	mailbox.domain = in
+	return mailbox, true
+}
+
+// domainToReverseLabels converts a textual domain name like foo.example.com to
+// the list of labels in reverse order, e.g. ["com", "example", "foo"].
+func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
+	for len(domain) > 0 {
+		if i := strings.LastIndexByte(domain, '.'); i == -1 {
+			reverseLabels = append(reverseLabels, domain)
+			domain = ""
+		} else {
+			reverseLabels = append(reverseLabels, domain[i+1:len(domain)])
+			domain = domain[:i]
+		}
+	}
+
+	if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
+		// An empty label at the end indicates an absolute value.
+		return nil, false
+	}
+
+	for _, label := range reverseLabels {
+		if len(label) == 0 {
+			// Empty labels are otherwise invalid.
+			return nil, false
+		}
+
+		for _, c := range label {
+			if c < 33 || c > 126 {
+				// Invalid character.
+				return nil, false
+			}
+		}
+	}
+
+	return reverseLabels, true
+}
+
+func matchEmailConstraint(mailbox rfc2821Mailbox, constraint string) (bool, error) {
+	// If the constraint contains an @, then it specifies an exact mailbox
+	// name.
+	if strings.Contains(constraint, "@") {
+		constraintMailbox, ok := parseRFC2821Mailbox(constraint)
+		if !ok {
+			return false, fmt.Errorf("x509: internal error: cannot parse constraint %q", constraint)
+		}
+		return mailbox.local == constraintMailbox.local && strings.EqualFold(mailbox.domain, constraintMailbox.domain), nil
+	}
+
+	// Otherwise the constraint is like a DNS constraint of the domain part
+	// of the mailbox.
+	return matchDomainConstraint(mailbox.domain, constraint)
+}
+
+func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
+	// https://tools.ietf.org/html/rfc5280#section-4.2.1.10
+	// “a uniformResourceIdentifier that does not include an authority
+	// component with a host name specified as a fully qualified domain
+	// name (e.g., if the URI either does not include an authority
+	// component or includes an authority component in which the host name
+	// is specified as an IP address), then the application MUST reject the
+	// certificate.”
+
+	host := uri.Host
+	if len(host) == 0 {
+		return false, fmt.Errorf("URI with empty host (%q) cannot be matched against constraints", uri.String())
+	}
+
+	if strings.Contains(host, ":") && !strings.HasSuffix(host, "]") {
+		var err error
+		host, _, err = net.SplitHostPort(uri.Host)
+		if err != nil {
+			return false, err
+		}
+	}
+
+	if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
+		net.ParseIP(host) != nil {
+		return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
+	}
+
+	return matchDomainConstraint(host, constraint)
+}
+
+func matchIPConstraint(ip net.IP, constraint *net.IPNet) (bool, error) {
+	if len(ip) != len(constraint.IP) {
+		return false, nil
+	}
+
+	for i := range ip {
+		if mask := constraint.Mask[i]; ip[i]&mask != constraint.IP[i]&mask {
+			return false, nil
+		}
+	}
+
+	return true, nil
+}
+
+func matchDomainConstraint(domain, constraint string) (bool, error) {
 	// The meaning of zero length constraints is not specified, but this
 	// code follows NSS and accepts them as matching everything.
 	if len(constraint) == 0 {
-		return true
+		return true, nil
 	}
 
-	if len(domain) < len(constraint) {
-		return false
+	domainLabels, ok := domainToReverseLabels(domain)
+	if !ok {
+		return false, fmt.Errorf("x509: internal error: cannot parse domain %q", domain)
 	}
 
-	prefixLen := len(domain) - len(constraint)
-	if !strings.EqualFold(domain[prefixLen:], constraint) {
-		return false
+	// RFC 5280 says that a leading period in a domain name means that at
+	// least one label must be prepended, but only for URI and email
+	// constraints, not DNS constraints. The code also supports that
+	// behaviour for DNS constraints.
+
+	mustHaveSubdomains := false
+	if constraint[0] == '.' {
+		mustHaveSubdomains = true
+		constraint = constraint[1:]
 	}
 
-	if prefixLen == 0 {
-		return true
+	constraintLabels, ok := domainToReverseLabels(constraint)
+	if !ok {
+		return false, fmt.Errorf("x509: internal error: cannot parse domain %q", constraint)
 	}
 
-	isSubdomain := domain[prefixLen-1] == '.'
-	constraintHasLeadingDot := constraint[0] == '.'
-	return isSubdomain != constraintHasLeadingDot
+	if len(domainLabels) < len(constraintLabels) ||
+		(mustHaveSubdomains && len(domainLabels) == len(constraintLabels)) {
+		return false, nil
+	}
+
+	for i, constraintLabel := range constraintLabels {
+		if !strings.EqualFold(constraintLabel, domainLabels[i]) {
+			return false, nil
+		}
+	}
+
+	return true, nil
 }
 
-// isValid performs validity checks on the c.
+// checkNameConstraints checks that c permits a child certificate to claim the
+// given name, of type nameType. The argument parsedName contains the parsed
+// form of name, suitable for passing to the match function. The total number
+// of comparisons is tracked in the given count and should not exceed the given
+// limit.
+func (c *Certificate) checkNameConstraints(count *int,
+	maxConstraintComparisons int,
+	nameType string,
+	name string,
+	parsedName interface{},
+	match func(parsedName, constraint interface{}) (match bool, err error),
+	permitted, excluded interface{}) error {
+
+	excludedValue := reflect.ValueOf(excluded)
+
+	*count += excludedValue.Len()
+	if *count > maxConstraintComparisons {
+		return CertificateInvalidError{c, TooManyConstraints, ""}
+	}
+
+	for i := 0; i < excludedValue.Len(); i++ {
+		constraint := excludedValue.Index(i).Interface()
+		match, err := match(parsedName, constraint)
+		if err != nil {
+			return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
+		}
+
+		if match {
+			return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)}
+		}
+	}
+
+	permittedValue := reflect.ValueOf(permitted)
+
+	*count += permittedValue.Len()
+	if *count > maxConstraintComparisons {
+		return CertificateInvalidError{c, TooManyConstraints, ""}
+	}
+
+	ok := true
+	for i := 0; i < permittedValue.Len(); i++ {
+		constraint := permittedValue.Index(i).Interface()
+
+		var err error
+		if ok, err = match(parsedName, constraint); err != nil {
+			return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
+		}
+
+		if ok {
+			break
+		}
+	}
+
+	if !ok {
+		return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)}
+	}
+
+	return nil
+}
+
+// ekuPermittedBy returns true iff the given extended key usage is permitted by
+// the given EKU from a certificate. Normally, this would be a simple
+// comparison plus a special case for the “any” EKU. But, in order to support
+// existing certificates, some exceptions are made.
+func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool {
+	if certEKU == ExtKeyUsageAny || eku == certEKU {
+		return true
+	}
+
+	// Some exceptions are made to support existing certificates. Firstly,
+	// the ServerAuth and SGC EKUs are treated as a group.
+	mapServerAuthEKUs := func(eku ExtKeyUsage) ExtKeyUsage {
+		if eku == ExtKeyUsageNetscapeServerGatedCrypto || eku == ExtKeyUsageMicrosoftServerGatedCrypto {
+			return ExtKeyUsageServerAuth
+		}
+		return eku
+	}
+
+	eku = mapServerAuthEKUs(eku)
+	certEKU = mapServerAuthEKUs(certEKU)
+
+	if eku == certEKU ||
+		// ServerAuth in a CA permits ClientAuth in the leaf.
+		(eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) ||
+		// Any CA may issue an OCSP responder certificate.
+		eku == ExtKeyUsageOCSPSigning ||
+		// Code-signing CAs can use Microsoft's commercial and
+		// kernel-mode EKUs.
+		((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) {
+		return true
+	}
+
+	return false
+}
+
+// isValid performs validity checks on c given that it is a candidate to append
+// to the chain in currentChain.
 func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
+	if len(c.UnhandledCriticalExtensions) > 0 {
+		return UnhandledCriticalExtension{}
+	}
+
 	if len(currentChain) > 0 {
 		child := currentChain[len(currentChain)-1]
 		if !bytes.Equal(child.RawIssuer, c.RawSubject) {
-			return CertificateInvalidError{c, NameMismatch}
+			return CertificateInvalidError{c, NameMismatch, ""}
 		}
 	}
 
@@ -203,26 +597,148 @@
 		now = time.Now()
 	}
 	if now.Before(c.NotBefore) || now.After(c.NotAfter) {
-		return CertificateInvalidError{c, Expired}
+		return CertificateInvalidError{c, Expired, ""}
 	}
 
-	if len(c.PermittedDNSDomains) > 0 {
-		ok := false
-		for _, constraint := range c.PermittedDNSDomains {
-			ok = matchNameConstraint(opts.DNSName, constraint)
-			if ok {
+	maxConstraintComparisons := opts.MaxConstraintComparisions
+	if maxConstraintComparisons == 0 {
+		maxConstraintComparisons = 250000
+	}
+	comparisonCount := 0
+
+	var leaf *Certificate
+	if certType == intermediateCertificate || certType == rootCertificate {
+		if len(currentChain) == 0 {
+			return errors.New("x509: internal error: empty chain when appending CA cert")
+		}
+		leaf = currentChain[0]
+	}
+
+	if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
+		sanExtension, ok := leaf.getSANExtension()
+		if !ok {
+			// This is the deprecated, legacy case of depending on
+			// the CN as a hostname. Chains modern enough to be
+			// using name constraints should not be depending on
+			// CNs.
+			return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""}
+		}
+
+		err := forEachSAN(sanExtension, func(tag int, data []byte) error {
+			switch tag {
+			case nameTypeEmail:
+				name := string(data)
+				mailbox, ok := parseRFC2821Mailbox(name)
+				if !ok {
+					// This certificate should not have parsed.
+					return errors.New("x509: internal error: rfc822Name SAN failed to parse")
+				}
+
+				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
+					func(parsedName, constraint interface{}) (bool, error) {
+						return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string))
+					}, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
+					return err
+				}
+
+			case nameTypeDNS:
+				name := string(data)
+				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
+					func(parsedName, constraint interface{}) (bool, error) {
+						return matchDomainConstraint(parsedName.(string), constraint.(string))
+					}, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
+					return err
+				}
+
+			case nameTypeURI:
+				name := string(data)
+				uri, err := url.Parse(name)
+				if err != nil {
+					return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name)
+				}
+
+				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri,
+					func(parsedName, constraint interface{}) (bool, error) {
+						return matchURIConstraint(parsedName.(*url.URL), constraint.(string))
+					}, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
+					return err
+				}
+
+			case nameTypeIP:
+				ip := net.IP(data)
+				if l := len(ip); l != net.IPv4len && l != net.IPv6len {
+					return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data)
+				}
+
+				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip,
+					func(parsedName, constraint interface{}) (bool, error) {
+						return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet))
+					}, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
+					return err
+				}
+
+			default:
+				// Unknown SAN types are ignored.
+			}
+
+			return nil
+		})
+
+		if err != nil {
+			return err
+		}
+	}
+
+	checkEKUs := certType == intermediateCertificate
+
+	// If no extended key usages are specified, then all are acceptable.
+	if checkEKUs && (len(c.ExtKeyUsage) == 0 && len(c.UnknownExtKeyUsage) == 0) {
+		checkEKUs = false
+	}
+
+	// If the “any” key usage is permitted, then no more checks are needed.
+	if checkEKUs {
+		for _, caEKU := range c.ExtKeyUsage {
+			comparisonCount++
+			if caEKU == ExtKeyUsageAny {
+				checkEKUs = false
 				break
 			}
 		}
-
-		if !ok {
-			return CertificateInvalidError{c, CANotAuthorizedForThisName}
-		}
 	}
 
-	for _, constraint := range c.ExcludedDNSDomains {
-		if matchNameConstraint(opts.DNSName, constraint) {
-			return CertificateInvalidError{c, CANotAuthorizedForThisName}
+	if checkEKUs {
+	NextEKU:
+		for _, eku := range leaf.ExtKeyUsage {
+			if comparisonCount > maxConstraintComparisons {
+				return CertificateInvalidError{c, TooManyConstraints, ""}
+			}
+
+			for _, caEKU := range c.ExtKeyUsage {
+				comparisonCount++
+				if ekuPermittedBy(eku, caEKU) {
+					continue NextEKU
+				}
+			}
+
+			oid, _ := oidFromExtKeyUsage(eku)
+			return CertificateInvalidError{c, CANotAuthorizedForExtKeyUsage, fmt.Sprintf("EKU not permitted: %#v", oid)}
+		}
+
+	NextUnknownEKU:
+		for _, eku := range leaf.UnknownExtKeyUsage {
+			if comparisonCount > maxConstraintComparisons {
+				return CertificateInvalidError{c, TooManyConstraints, ""}
+			}
+
+			for _, caEKU := range c.UnknownExtKeyUsage {
+				comparisonCount++
+				if caEKU.Equal(eku) {
+					continue NextUnknownEKU
+				}
+			}
+
+			return CertificateInvalidError{c, CANotAuthorizedForExtKeyUsage, fmt.Sprintf("EKU not permitted: %#v", eku)}
 		}
 	}
 
@@ -244,13 +760,13 @@
 	// encryption key could only be used for Diffie-Hellman key agreement.
 
 	if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
-		return CertificateInvalidError{c, NotAuthorizedToSign}
+		return CertificateInvalidError{c, NotAuthorizedToSign, ""}
 	}
 
 	if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
 		numIntermediates := len(currentChain) - 1
 		if numIntermediates > c.MaxPathLen {
-			return CertificateInvalidError{c, TooManyIntermediates}
+			return CertificateInvalidError{c, TooManyIntermediates, ""}
 		}
 	}
 
@@ -265,7 +781,17 @@
 // 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.
+// Name constraints in the intermediates will be applied to all names claimed
+// in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim
+// example.com if an intermediate doesn't permit it, even if example.com is not
+// the name being validated. Note that DirectoryName constraints are not
+// supported.
+//
+// Extended Key Usage values are enforced down a chain, so an intermediate or
+// root that enumerates EKUs prevents a leaf from asserting an EKU not in that
+// list.
+//
+// WARNING: this function doesn't do any revocation checking.
 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
 	// Platform-specific verification needs the ASN.1 contents so
 	// this makes the behavior consistent across platforms.
@@ -285,10 +811,6 @@
 		return c.systemVerify(&opts)
 	}
 
-	if len(c.UnhandledCriticalExtensions) > 0 {
-		return nil, UnhandledCriticalExtension{}
-	}
-
 	if opts.Roots == nil {
 		opts.Roots = systemRootsPool()
 		if opts.Roots == nil {
@@ -308,6 +830,36 @@
 		}
 	}
 
+	requestedKeyUsages := make([]ExtKeyUsage, len(opts.KeyUsages))
+	copy(requestedKeyUsages, opts.KeyUsages)
+	if len(requestedKeyUsages) == 0 {
+		requestedKeyUsages = append(requestedKeyUsages, ExtKeyUsageServerAuth)
+	}
+
+	// If no key usages are specified, then any are acceptable.
+	checkEKU := len(c.ExtKeyUsage) > 0
+
+	for _, eku := range requestedKeyUsages {
+		if eku == ExtKeyUsageAny {
+			checkEKU = false
+			break
+		}
+	}
+
+	if checkEKU {
+	NextUsage:
+		for _, eku := range requestedKeyUsages {
+			for _, leafEKU := range c.ExtKeyUsage {
+				if ekuPermittedBy(eku, leafEKU) {
+					continue NextUsage
+				}
+			}
+
+			oid, _ := oidFromExtKeyUsage(eku)
+			return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)}
+		}
+	}
+
 	var candidateChains [][]*Certificate
 	if opts.Roots.contains(c) {
 		candidateChains = append(candidateChains, []*Certificate{c})
@@ -317,30 +869,7 @@
 		}
 	}
 
-	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
+	return candidateChains, nil
 }
 
 func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
@@ -501,65 +1030,3 @@
 
 	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/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
index 335c477..bd3df47 100644
--- a/src/crypto/x509/verify_test.go
+++ b/src/crypto/x509/verify_test.go
@@ -296,6 +296,30 @@
 
 		errorCallback: expectNameConstraintsError,
 	},
+	{
+		// Test that unknown critical extensions in a leaf cause a
+		// verify error.
+		leaf:          criticalExtLeafWithExt,
+		dnsName:       "example.com",
+		intermediates: []string{criticalExtIntermediate},
+		roots:         []string{criticalExtRoot},
+		currentTime:   1486684488,
+		systemSkip:    true,
+
+		errorCallback: expectUnhandledCriticalExtension,
+	},
+	{
+		// Test that unknown critical extensions in an intermediate
+		// cause a verify error.
+		leaf:          criticalExtLeaf,
+		dnsName:       "example.com",
+		intermediates: []string{criticalExtIntermediateWithExt},
+		roots:         []string{criticalExtRoot},
+		currentTime:   1486684488,
+		systemSkip:    true,
+
+		errorCallback: expectUnhandledCriticalExtension,
+	},
 }
 
 func expectHostnameError(t *testing.T, i int, err error) (ok bool) {
@@ -379,6 +403,14 @@
 	return true
 }
 
+func expectUnhandledCriticalExtension(t *testing.T, i int, err error) (ok bool) {
+	if _, ok := err.(UnhandledCriticalExtension); !ok {
+		t.Errorf("#%d: error was not an UnhandledCriticalExtension: %s", i, err)
+		return false
+	}
+	return true
+}
+
 func certificateFromPEM(pemBytes string) (*Certificate, error) {
 	block, _ := pem.Decode([]byte(pemBytes))
 	if block == nil {
@@ -1519,22 +1551,37 @@
 
 var nameConstraintTests = []struct {
 	constraint, domain string
+	expectError        bool
 	shouldMatch        bool
 }{
-	{"", "anything.com", true},
-	{"example.com", "example.com", true},
-	{"example.com", "ExAmPle.coM", true},
-	{"example.com", "exampl1.com", false},
-	{"example.com", "www.ExAmPle.coM", true},
-	{"example.com", "notexample.com", false},
-	{".example.com", "example.com", false},
-	{".example.com", "www.example.com", true},
-	{".example.com", "www..example.com", false},
+	{"", "anything.com", false, true},
+	{"example.com", "example.com", false, true},
+	{"example.com.", "example.com", true, false},
+	{"example.com", "example.com.", true, false},
+	{"example.com", "ExAmPle.coM", false, true},
+	{"example.com", "exampl1.com", false, false},
+	{"example.com", "www.ExAmPle.coM", false, true},
+	{"example.com", "sub.www.ExAmPle.coM", false, true},
+	{"example.com", "notexample.com", false, false},
+	{".example.com", "example.com", false, false},
+	{".example.com", "www.example.com", false, true},
+	{".example.com", "www..example.com", true, false},
 }
 
 func TestNameConstraints(t *testing.T) {
 	for i, test := range nameConstraintTests {
-		result := matchNameConstraint(test.domain, test.constraint)
+		result, err := matchDomainConstraint(test.domain, test.constraint)
+
+		if err != nil && !test.expectError {
+			t.Errorf("unexpected error for test #%d: domain=%s, constraint=%s, err=%s", i, test.domain, test.constraint, err)
+			continue
+		}
+
+		if err == nil && test.expectError {
+			t.Errorf("unexpected success for test #%d: domain=%s, constraint=%s", i, test.domain, test.constraint)
+			continue
+		}
+
 		if result != test.shouldMatch {
 			t.Errorf("unexpected result for test #%d: domain=%s, constraint=%s, result=%t", i, test.domain, test.constraint, result)
 		}
@@ -1596,3 +1643,67 @@
 4R+gnfLd37FWflMHwztFbVTuNtPOljCX0LN7KcuoXYlr05RhQrmoN7fQHsrZMNLs
 8FVjHdKKu+uPstwd04Uy4BR/H2y1yerN9j/L6ZkMl98iiA==
 -----END CERTIFICATE-----`
+
+const criticalExtRoot = `-----BEGIN CERTIFICATE-----
+MIIBqzCCAVGgAwIBAgIJAJ+mI/85cXApMAoGCCqGSM49BAMCMB0xDDAKBgNVBAoT
+A09yZzENMAsGA1UEAxMEUm9vdDAeFw0xNTAxMDEwMDAwMDBaFw0yNTAxMDEwMDAw
+MDBaMB0xDDAKBgNVBAoTA09yZzENMAsGA1UEAxMEUm9vdDBZMBMGByqGSM49AgEG
+CCqGSM49AwEHA0IABJGp9joiG2QSQA+1FczEDAsWo84rFiP3GTL+n+ugcS6TyNib
+gzMsdbJgVi+a33y0SzLZxB+YvU3/4KTk8yKLC+2jejB4MA4GA1UdDwEB/wQEAwIC
+BDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB
+/zAZBgNVHQ4EEgQQQDfXAftAL7gcflQEJ4xZATAbBgNVHSMEFDASgBBAN9cB+0Av
+uBx+VAQnjFkBMAoGCCqGSM49BAMCA0gAMEUCIFeSV00fABFceWR52K+CfIgOHotY
+FizzGiLB47hGwjMuAiEA8e0um2Kr8FPQ4wmFKaTRKHMaZizCGl3m+RG5QsE1KWo=
+-----END CERTIFICATE-----`
+
+const criticalExtIntermediate = `-----BEGIN CERTIFICATE-----
+MIIBszCCAVmgAwIBAgIJAL2kcGZKpzVqMAoGCCqGSM49BAMCMB0xDDAKBgNVBAoT
+A09yZzENMAsGA1UEAxMEUm9vdDAeFw0xNTAxMDEwMDAwMDBaFw0yNTAxMDEwMDAw
+MDBaMCUxDDAKBgNVBAoTA09yZzEVMBMGA1UEAxMMSW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAESqVq92iPEq01cL4o99WiXDc5GZjpjNlzMS1n
+rk8oHcVDp4tQRRQG3F4A6dF1rn/L923ha3b0fhDLlAvXZB+7EKN6MHgwDgYDVR0P
+AQH/BAQDAgIEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMB
+Af8EBTADAQH/MBkGA1UdDgQSBBCMGmiotXbbXVd7H40UsgajMBsGA1UdIwQUMBKA
+EEA31wH7QC+4HH5UBCeMWQEwCgYIKoZIzj0EAwIDSAAwRQIhAOhhNRb6KV7h3wbE
+cdap8bojzvUcPD78fbsQPCNw1jPxAiBOeAJhlTwpKn9KHpeJphYSzydj9NqcS26Y
+xXbdbm27KQ==
+-----END CERTIFICATE-----`
+
+const criticalExtLeafWithExt = `-----BEGIN CERTIFICATE-----
+MIIBxTCCAWugAwIBAgIJAJZAUtw5ccb1MAoGCCqGSM49BAMCMCUxDDAKBgNVBAoT
+A09yZzEVMBMGA1UEAxMMSW50ZXJtZWRpYXRlMB4XDTE1MDEwMTAwMDAwMFoXDTI1
+MDEwMTAwMDAwMFowJDEMMAoGA1UEChMDT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNv
+bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABF3ABa2+B6gUyg6ayCaRQWYY/+No
+6PceLqEavZNUeVNuz7bS74Toy8I7R3bGMkMgbKpLSPlPTroAATvebTXoBaijgYQw
+gYEwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
+AjAMBgNVHRMBAf8EAjAAMBkGA1UdDgQSBBBRNtBL2vq8nCV3qVp7ycxMMBsGA1Ud
+IwQUMBKAEIwaaKi1dttdV3sfjRSyBqMwCgYDUQMEAQH/BAAwCgYIKoZIzj0EAwID
+SAAwRQIgVjy8GBgZFiagexEuDLqtGjIRJQtBcf7lYgf6XFPH1h4CIQCT6nHhGo6E
+I+crEm4P5q72AnA/Iy0m24l7OvLuXObAmg==
+-----END CERTIFICATE-----`
+
+const criticalExtIntermediateWithExt = `-----BEGIN CERTIFICATE-----
+MIIB2TCCAX6gAwIBAgIIQD3NrSZtcUUwCgYIKoZIzj0EAwIwHTEMMAoGA1UEChMD
+T3JnMQ0wCwYDVQQDEwRSb290MB4XDTE1MDEwMTAwMDAwMFoXDTI1MDEwMTAwMDAw
+MFowPTEMMAoGA1UEChMDT3JnMS0wKwYDVQQDEyRJbnRlcm1lZGlhdGUgd2l0aCBD
+cml0aWNhbCBFeHRlbnNpb24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtnmzH
+mcRm10bdDBnJE7xQEJ25cLCL5okuEphRR0Zneo6+nQZikoh+UBbtt5GV3Dms7LeP
+oF5HOplYDCd8wi/wo4GHMIGEMA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggr
+BgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQKxdv
+UuQZ6sO3XvBsxgNZ3zAbBgNVHSMEFDASgBBAN9cB+0AvuBx+VAQnjFkBMAoGA1ED
+BAEB/wQAMAoGCCqGSM49BAMCA0kAMEYCIQCQzTPd6XKex+OAPsKT/1DsoMsg8vcG
+c2qZ4Q0apT/kvgIhAKu2TnNQMIUdcO0BYQIl+Uhxc78dc9h4lO+YJB47pHGx
+-----END CERTIFICATE-----`
+
+const criticalExtLeaf = `-----BEGIN CERTIFICATE-----
+MIIBzzCCAXWgAwIBAgIJANoWFIlhCI9MMAoGCCqGSM49BAMCMD0xDDAKBgNVBAoT
+A09yZzEtMCsGA1UEAxMkSW50ZXJtZWRpYXRlIHdpdGggQ3JpdGljYWwgRXh0ZW5z
+aW9uMB4XDTE1MDEwMTAwMDAwMFoXDTI1MDEwMTAwMDAwMFowJDEMMAoGA1UEChMD
+T3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
+A0IABG1Lfh8A0Ho2UvZN5H0+ONil9c8jwtC0y0xIZftyQE+Fwr9XwqG3rV2g4M1h
+GnJa9lV9MPHg8+b85Hixm0ZSw7SjdzB1MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAZBgNVHQ4EEgQQ
+UNhY4JhezH9gQYqvDMWrWDAbBgNVHSMEFDASgBArF29S5Bnqw7de8GzGA1nfMAoG
+CCqGSM49BAMCA0gAMEUCIQClA3d4tdrDu9Eb5ZBpgyC+fU1xTZB0dKQHz6M5fPZA
+2AIgN96lM+CPGicwhN24uQI6flOsO3H0TJ5lNzBYLtnQtlc=
+-----END CERTIFICATE-----`
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index fdc7c53..86d9e82 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -27,8 +27,14 @@
 	"io"
 	"math/big"
 	"net"
+	"net/url"
 	"strconv"
+	"strings"
 	"time"
+	"unicode/utf8"
+
+	"golang_org/x/crypto/cryptobyte"
+	cryptobyte_asn1 "golang_org/x/crypto/cryptobyte/asn1"
 )
 
 // pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
@@ -194,27 +200,11 @@
 	}
 }
 
-var algoName = [...]string{
-	MD2WithRSA:       "MD2-RSA",
-	MD5WithRSA:       "MD5-RSA",
-	SHA1WithRSA:      "SHA1-RSA",
-	SHA256WithRSA:    "SHA256-RSA",
-	SHA384WithRSA:    "SHA384-RSA",
-	SHA512WithRSA:    "SHA512-RSA",
-	SHA256WithRSAPSS: "SHA256-RSAPSS",
-	SHA384WithRSAPSS: "SHA384-RSAPSS",
-	SHA512WithRSAPSS: "SHA512-RSAPSS",
-	DSAWithSHA1:      "DSA-SHA1",
-	DSAWithSHA256:    "DSA-SHA256",
-	ECDSAWithSHA1:    "ECDSA-SHA1",
-	ECDSAWithSHA256:  "ECDSA-SHA256",
-	ECDSAWithSHA384:  "ECDSA-SHA384",
-	ECDSAWithSHA512:  "ECDSA-SHA512",
-}
-
 func (algo SignatureAlgorithm) String() string {
-	if 0 < algo && int(algo) < len(algoName) {
-		return algoName[algo]
+	for _, details := range signatureAlgorithmDetails {
+		if details.algo == algo {
+			return details.name
+		}
 	}
 	return strconv.Itoa(int(algo))
 }
@@ -228,6 +218,19 @@
 	ECDSA
 )
 
+var publicKeyAlgoName = [...]string{
+	RSA:   "RSA",
+	DSA:   "DSA",
+	ECDSA: "ECDSA",
+}
+
+func (algo PublicKeyAlgorithm) String() string {
+	if 0 < algo && int(algo) < len(publicKeyAlgoName) {
+		return publicKeyAlgoName[algo]
+	}
+	return strconv.Itoa(int(algo))
+}
+
 // OIDs for signature algorithms
 //
 // pkcs-1 OBJECT IDENTIFIER ::= {
@@ -307,26 +310,27 @@
 
 var signatureAlgorithmDetails = []struct {
 	algo       SignatureAlgorithm
+	name       string
 	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},
-	{SHA1WithRSA, oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
-	{SHA256WithRSA, oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
-	{SHA384WithRSA, oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
-	{SHA512WithRSA, oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
-	{SHA256WithRSAPSS, oidSignatureRSAPSS, RSA, crypto.SHA256},
-	{SHA384WithRSAPSS, oidSignatureRSAPSS, RSA, crypto.SHA384},
-	{SHA512WithRSAPSS, oidSignatureRSAPSS, 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},
+	{MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
+	{MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5},
+	{SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
+	{SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
+	{SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
+	{SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
+	{SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
+	{SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256},
+	{SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384},
+	{SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512},
+	{DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
+	{DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
+	{ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
+	{ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
+	{ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
+	{ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
 }
 
 // pssParameters reflects the parameters in an AlgorithmIdentifier that
@@ -549,18 +553,20 @@
 // 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}
+	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}
+	oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
+	oidExtKeyUsageMicrosoftKernelCodeSigning     = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
 )
 
 // ExtKeyUsage represents an extended set of actions that are valid for a given key.
@@ -580,6 +586,8 @@
 	ExtKeyUsageOCSPSigning
 	ExtKeyUsageMicrosoftServerGatedCrypto
 	ExtKeyUsageNetscapeServerGatedCrypto
+	ExtKeyUsageMicrosoftCommercialCodeSigning
+	ExtKeyUsageMicrosoftKernelCodeSigning
 )
 
 // extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
@@ -599,6 +607,8 @@
 	{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
 	{ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
 	{ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
+	{ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
+	{ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
 }
 
 func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
@@ -700,11 +710,18 @@
 	DNSNames       []string
 	EmailAddresses []string
 	IPAddresses    []net.IP
+	URIs           []*url.URL
 
 	// Name constraints
 	PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
 	PermittedDNSDomains         []string
 	ExcludedDNSDomains          []string
+	PermittedIPRanges           []*net.IPNet
+	ExcludedIPRanges            []*net.IPNet
+	PermittedEmailAddresses     []string
+	ExcludedEmailAddresses      []string
+	PermittedURIDomains         []string
+	ExcludedURIDomains          []string
 
 	// CRL Distribution Points
 	CRLDistributionPoints []string
@@ -823,24 +840,48 @@
 	return checkSignature(algo, signed, signature, c.PublicKey)
 }
 
+func (c *Certificate) hasNameConstraints() bool {
+	for _, e := range c.Extensions {
+		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 30 {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (c *Certificate) getSANExtension() ([]byte, bool) {
+	for _, e := range c.Extensions {
+		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 17 {
+			return e.Value, true
+		}
+	}
+
+	return nil, false
+}
+
+func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey interface{}) error {
+	return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey)
+}
+
 // CheckSignature verifies that signature is a valid signature over signed from
 // a crypto.PublicKey.
 func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey) (err error) {
 	var hashType crypto.Hash
+	var pubKeyAlgo PublicKeyAlgorithm
 
-	switch algo {
-	case SHA1WithRSA, DSAWithSHA1, ECDSAWithSHA1:
-		hashType = crypto.SHA1
-	case SHA256WithRSA, SHA256WithRSAPSS, DSAWithSHA256, ECDSAWithSHA256:
-		hashType = crypto.SHA256
-	case SHA384WithRSA, SHA384WithRSAPSS, ECDSAWithSHA384:
-		hashType = crypto.SHA384
-	case SHA512WithRSA, SHA512WithRSAPSS, ECDSAWithSHA512:
-		hashType = crypto.SHA512
-	case MD2WithRSA, MD5WithRSA:
-		return InsecureAlgorithmError(algo)
-	default:
+	for _, details := range signatureAlgorithmDetails {
+		if details.algo == algo {
+			hashType = details.hash
+			pubKeyAlgo = details.pubKeyAlgo
+		}
+	}
+
+	switch hashType {
+	case crypto.Hash(0):
 		return ErrUnsupportedAlgorithm
+	case crypto.MD5:
+		return InsecureAlgorithmError(algo)
 	}
 
 	if !hashType.Available() {
@@ -853,12 +894,18 @@
 
 	switch pub := publicKey.(type) {
 	case *rsa.PublicKey:
+		if pubKeyAlgo != RSA {
+			return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+		}
 		if algo.isRSAPSS() {
 			return rsa.VerifyPSS(pub, hashType, digest, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})
 		} else {
 			return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
 		}
 	case *dsa.PublicKey:
+		if pubKeyAlgo != DSA {
+			return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+		}
 		dsaSig := new(dsaSignature)
 		if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil {
 			return err
@@ -873,6 +920,9 @@
 		}
 		return
 	case *ecdsa.PublicKey:
+		if pubKeyAlgo != ECDSA {
+			return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+		}
 		ecdsaSig := new(ecdsaSignature)
 		if rest, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
 			return err
@@ -913,15 +963,12 @@
 	// 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"`
-}
+const (
+	nameTypeEmail = 1
+	nameTypeDNS   = 2
+	nameTypeURI   = 6
+	nameTypeIP    = 7
+)
 
 // RFC 5280, 4.2.2.1
 type authorityInfoAccess struct {
@@ -937,7 +984,7 @@
 }
 
 type distributionPointName struct {
-	FullName     asn1.RawValue    `asn1:"optional,tag:0"`
+	FullName     []asn1.RawValue  `asn1:"optional,tag:0"`
 	RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
 }
 
@@ -1031,7 +1078,7 @@
 	}
 }
 
-func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
+func forEachSAN(extension []byte, callback func(tag int, data []byte) error) error {
 	// RFC 5280, 4.2.1.6
 
 	// SubjectAltName ::= GeneralNames
@@ -1049,16 +1096,14 @@
 	//      iPAddress                       [7]     OCTET STRING,
 	//      registeredID                    [8]     OBJECT IDENTIFIER }
 	var seq asn1.RawValue
-	var rest []byte
-	if rest, err = asn1.Unmarshal(value, &seq); err != nil {
-		return
+	rest, err := asn1.Unmarshal(extension, &seq)
+	if err != nil {
+		return err
 	} else if len(rest) != 0 {
-		err = errors.New("x509: trailing data after X.509 extension")
-		return
+		return errors.New("x509: trailing data after X.509 extension")
 	}
 	if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
-		err = asn1.StructuralError{Msg: "bad SAN sequence"}
-		return
+		return asn1.StructuralError{Msg: "bad SAN sequence"}
 	}
 
 	rest = seq.Bytes
@@ -1066,27 +1111,243 @@
 		var v asn1.RawValue
 		rest, err = asn1.Unmarshal(rest, &v)
 		if err != nil {
-			return
+			return err
 		}
-		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
-			}
+
+		if err := callback(v.Tag, v.Bytes); err != nil {
+			return err
 		}
 	}
 
+	return nil
+}
+
+func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
+	err = forEachSAN(value, func(tag int, data []byte) error {
+		switch tag {
+		case nameTypeEmail:
+			mailbox := string(data)
+			if _, ok := parseRFC2821Mailbox(mailbox); !ok {
+				return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
+			}
+			emailAddresses = append(emailAddresses, mailbox)
+		case nameTypeDNS:
+			domain := string(data)
+			if _, ok := domainToReverseLabels(domain); !ok {
+				return fmt.Errorf("x509: cannot parse dnsName %q", string(data))
+			}
+			dnsNames = append(dnsNames, domain)
+		case nameTypeURI:
+			uri, err := url.Parse(string(data))
+			if err != nil {
+				return fmt.Errorf("x509: cannot parse URI %q: %s", string(data), err)
+			}
+			if len(uri.Host) > 0 {
+				if _, ok := domainToReverseLabels(uri.Host); !ok {
+					return fmt.Errorf("x509: cannot parse URI %q: invalid domain", string(data))
+				}
+			}
+			uris = append(uris, uri)
+		case nameTypeIP:
+			switch len(data) {
+			case net.IPv4len, net.IPv6len:
+				ipAddresses = append(ipAddresses, data)
+			default:
+				return errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(data)))
+			}
+		}
+
+		return nil
+	})
+
 	return
 }
 
+// isValidIPMask returns true iff mask consists of zero or more 1 bits, followed by zero bits.
+func isValidIPMask(mask []byte) bool {
+	seenZero := false
+
+	for _, b := range mask {
+		if seenZero {
+			if b != 0 {
+				return false
+			}
+
+			continue
+		}
+
+		switch b {
+		case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
+			seenZero = true
+		case 0xff:
+		default:
+			return false
+		}
+	}
+
+	return true
+}
+
+func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {
+	// 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)
+
+	outer := cryptobyte.String(e.Value)
+	var toplevel, permitted, excluded cryptobyte.String
+	var havePermitted, haveExcluded bool
+	if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
+		!outer.Empty() ||
+		!toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
+		!toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
+		!toplevel.Empty() {
+		return false, errors.New("x509: invalid NameConstraints extension")
+	}
+
+	if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
+		// https://tools.ietf.org/html/rfc5280#section-4.2.1.10:
+		//   “either the permittedSubtrees field
+		//   or the excludedSubtrees MUST be
+		//   present”
+		return false, errors.New("x509: empty name constraints extension")
+	}
+
+	getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
+		for !subtrees.Empty() {
+			var seq, value cryptobyte.String
+			var tag cryptobyte_asn1.Tag
+			if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
+				!seq.ReadAnyASN1(&value, &tag) {
+				return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
+			}
+
+			var (
+				dnsTag   = cryptobyte_asn1.Tag(2).ContextSpecific()
+				emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
+				ipTag    = cryptobyte_asn1.Tag(7).ContextSpecific()
+				uriTag   = cryptobyte_asn1.Tag(6).ContextSpecific()
+			)
+
+			switch tag {
+			case dnsTag:
+				domain := string(value)
+				if err := isIA5String(domain); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				trimmedDomain := domain
+				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+					// constraints can have a leading
+					// period to exclude the domain
+					// itself, but that's not valid in a
+					// normal domain name.
+					trimmedDomain = trimmedDomain[1:]
+				}
+				if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
+				}
+				dnsNames = append(dnsNames, domain)
+
+			case ipTag:
+				l := len(value)
+				var ip, mask []byte
+
+				switch l {
+				case 8:
+					ip = value[:4]
+					mask = value[4:]
+
+				case 32:
+					ip = value[:16]
+					mask = value[16:]
+
+				default:
+					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
+				}
+
+				if !isValidIPMask(mask) {
+					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
+				}
+
+				ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
+
+			case emailTag:
+				constraint := string(value)
+				if err := isIA5String(constraint); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				// If the constraint contains an @ then
+				// it specifies an exact mailbox name.
+				if strings.Contains(constraint, "@") {
+					if _, ok := parseRFC2821Mailbox(constraint); !ok {
+						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+					}
+				} else {
+					// Otherwise it's a domain name.
+					domain := constraint
+					if len(domain) > 0 && domain[0] == '.' {
+						domain = domain[1:]
+					}
+					if _, ok := domainToReverseLabels(domain); !ok {
+						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+					}
+				}
+				emails = append(emails, constraint)
+
+			case uriTag:
+				domain := string(value)
+				if err := isIA5String(domain); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				if net.ParseIP(domain) != nil {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
+				}
+
+				trimmedDomain := domain
+				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+					// constraints can have a leading
+					// period to exclude the domain itself,
+					// but that's not valid in a normal
+					// domain name.
+					trimmedDomain = trimmedDomain[1:]
+				}
+				if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
+				}
+				uriDomains = append(uriDomains, domain)
+
+			default:
+				unhandled = true
+			}
+		}
+
+		return dnsNames, ips, emails, uriDomains, nil
+	}
+
+	if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {
+		return false, err
+	}
+	if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {
+		return false, err
+	}
+	out.PermittedDNSDomainsCritical = e.Critical
+
+	return unhandled, nil
+}
+
 func parseCertificate(in *certificate) (*Certificate, error) {
 	out := new(Certificate)
 	out.Raw = in.Raw
@@ -1166,61 +1427,22 @@
 				out.MaxPathLenZero = out.MaxPathLen == 0
 				// TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
 			case 17:
-				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(e.Value)
+				out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
 				if err != nil {
 					return nil, err
 				}
 
-				if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 {
+				if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {
 					// If we didn't parse anything then we do the critical check, below.
 					unhandled = true
 				}
 
 			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
-				if rest, err := asn1.Unmarshal(e.Value, &constraints); err != nil {
+				unhandled, err = parseNameConstraintsExtension(out, e)
+				if err != nil {
 					return nil, err
-				} else if len(rest) != 0 {
-					return nil, errors.New("x509: trailing data after X.509 NameConstraints")
 				}
 
-				getDNSNames := func(subtrees []generalSubtree, isCritical bool) (dnsNames []string, err error) {
-					for _, subtree := range subtrees {
-						if len(subtree.Name) == 0 {
-							if isCritical {
-								return nil, UnhandledCriticalExtension{}
-							}
-							continue
-						}
-						dnsNames = append(dnsNames, subtree.Name)
-					}
-
-					return dnsNames, nil
-				}
-
-				if out.PermittedDNSDomains, err = getDNSNames(constraints.Permitted, e.Critical); err != nil {
-					return out, err
-				}
-				if out.ExcludedDNSDomains, err = getDNSNames(constraints.Excluded, e.Critical); err != nil {
-					return out, err
-				}
-				out.PermittedDNSDomainsCritical = e.Critical
-
 			case 31:
 				// RFC 5280, 4.2.1.13
 
@@ -1244,20 +1466,14 @@
 
 				for _, dp := range cdp {
 					// Per RFC 5280, 4.2.1.13, one of distributionPoint or cRLIssuer may be empty.
-					if len(dp.DistributionPoint.FullName.Bytes) == 0 {
+					if len(dp.DistributionPoint.FullName) == 0 {
 						continue
 					}
 
-					var n asn1.RawValue
-					if _, err := asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n); err != nil {
-						return nil, err
-					}
-					// Trailing data after the fullName is
-					// allowed because other elements of
-					// the SEQUENCE can appear.
-
-					if n.Tag == 6 {
-						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
+					for _, fullName := range dp.DistributionPoint.FullName {
+						if fullName.Tag == 6 {
+							out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(fullName.Bytes))
+						}
 					}
 				}
 
@@ -1454,13 +1670,13 @@
 
 // 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) {
+func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) {
 	var rawValues []asn1.RawValue
 	for _, name := range dnsNames {
-		rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)})
+		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
 	}
 	for _, email := range emailAddresses {
-		rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)})
+		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
 	}
 	for _, rawIP := range ipAddresses {
 		// If possible, we always want to encode IPv4 addresses in 4 bytes.
@@ -1468,12 +1684,25 @@
 		if ip == nil {
 			ip = rawIP
 		}
-		rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip})
+		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
+	}
+	for _, uri := range uris {
+		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uri.String())})
 	}
 	return asn1.Marshal(rawValues)
 }
 
-func buildExtensions(template *Certificate, authorityKeyId []byte) (ret []pkix.Extension, err error) {
+func isIA5String(s string) error {
+	for _, r := range s {
+		if r >= utf8.RuneSelf {
+			return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
+		}
+	}
+
+	return nil
+}
+
+func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte) (ret []pkix.Extension, err error) {
 	ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
 	n := 0
 
@@ -1579,10 +1808,14 @@
 		n++
 	}
 
-	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
+	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
 		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
 		ret[n].Id = oidExtensionSubjectAltName
-		ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
+		// https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+		// “If the subject field contains an empty sequence ... then
+		// subjectAltName extension ... is marked as critical”
+		ret[n].Critical = subjectIsEmpty
+		ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
 		if err != nil {
 			return
 		}
@@ -1603,25 +1836,100 @@
 		n++
 	}
 
-	if (len(template.PermittedDNSDomains) > 0 || len(template.ExcludedDNSDomains) > 0) &&
+	if (len(template.PermittedDNSDomains) > 0 || len(template.ExcludedDNSDomains) > 0 ||
+		len(template.PermittedIPRanges) > 0 || len(template.ExcludedIPRanges) > 0 ||
+		len(template.PermittedEmailAddresses) > 0 || len(template.ExcludedEmailAddresses) > 0 ||
+		len(template.PermittedURIDomains) > 0 || len(template.ExcludedURIDomains) > 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}
-		}
-		out.Excluded = make([]generalSubtree, len(template.ExcludedDNSDomains))
-		for i, excluded := range template.ExcludedDNSDomains {
-			out.Excluded[i] = generalSubtree{Name: excluded}
+		ipAndMask := func(ipNet *net.IPNet) []byte {
+			maskedIP := ipNet.IP.Mask(ipNet.Mask)
+			ipAndMask := make([]byte, 0, len(maskedIP)+len(ipNet.Mask))
+			ipAndMask = append(ipAndMask, maskedIP...)
+			ipAndMask = append(ipAndMask, ipNet.Mask...)
+			return ipAndMask
 		}
 
-		ret[n].Value, err = asn1.Marshal(out)
+		serialiseConstraints := func(dns []string, ips []*net.IPNet, emails []string, uriDomains []string) (der []byte, err error) {
+			var b cryptobyte.Builder
+
+			for _, name := range dns {
+				if err = isIA5String(name); err != nil {
+					return nil, err
+				}
+
+				b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+					b.AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func(b *cryptobyte.Builder) {
+						b.AddBytes([]byte(name))
+					})
+				})
+			}
+
+			for _, ipNet := range ips {
+				b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+					b.AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func(b *cryptobyte.Builder) {
+						b.AddBytes(ipAndMask(ipNet))
+					})
+				})
+			}
+
+			for _, email := range emails {
+				if err = isIA5String(email); err != nil {
+					return nil, err
+				}
+
+				b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+					b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func(b *cryptobyte.Builder) {
+						b.AddBytes([]byte(email))
+					})
+				})
+			}
+
+			for _, uriDomain := range uriDomains {
+				if err = isIA5String(uriDomain); err != nil {
+					return nil, err
+				}
+
+				b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+					b.AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func(b *cryptobyte.Builder) {
+						b.AddBytes([]byte(uriDomain))
+					})
+				})
+			}
+
+			return b.Bytes()
+		}
+
+		permitted, err := serialiseConstraints(template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains)
 		if err != nil {
-			return
+			return nil, err
+		}
+
+		excluded, err := serialiseConstraints(template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains)
+		if err != nil {
+			return nil, err
+		}
+
+		var b cryptobyte.Builder
+		b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+			if len(permitted) > 0 {
+				b.AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
+					b.AddBytes(permitted)
+				})
+			}
+
+			if len(excluded) > 0 {
+				b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
+					b.AddBytes(excluded)
+				})
+			}
+		})
+
+		ret[n].Value, err = b.Bytes()
+		if err != nil {
+			return nil, err
 		}
 		n++
 	}
@@ -1632,11 +1940,11 @@
 
 		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},
+					FullName: []asn1.RawValue{
+						asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+					},
 				},
 			}
 			crlDp = append(crlDp, dp)
@@ -1732,7 +2040,11 @@
 	return
 }
 
-// CreateCertificate creates a new certificate based on a template.
+// emptyASN1Subject is the ASN.1 DER encoding of an empty Subject, which is
+// just an empty SEQUENCE.
+var emptyASN1Subject = []byte{0x30, 0}
+
+// CreateCertificate creates a new X.509v3 certificate based on a template.
 // The following members of template are used: AuthorityKeyId,
 // BasicConstraintsValid, DNSNames, ExcludedDNSDomains, ExtKeyUsage,
 // IsCA, KeyUsage, MaxPathLen, MaxPathLenZero, NotAfter, NotBefore,
@@ -1786,7 +2098,7 @@
 		authorityKeyId = parent.SubjectKeyId
 	}
 
-	extensions, err := buildExtensions(template, authorityKeyId)
+	extensions, err := buildExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId)
 	if err != nil {
 		return
 	}
@@ -1968,6 +2280,7 @@
 	DNSNames       []string
 	EmailAddresses []string
 	IPAddresses    []net.IP
+	URIs           []*url.URL
 }
 
 // These structures reflect the ASN.1 structure of X.509 certificate
@@ -2059,7 +2372,7 @@
 
 // CreateCertificateRequest creates a new certificate request based on a
 // template. The following members of template are used: Attributes, DNSNames,
-// EmailAddresses, ExtraExtensions, IPAddresses, SignatureAlgorithm, and
+// EmailAddresses, ExtraExtensions, IPAddresses, URIs, SignatureAlgorithm, and
 // Subject. The private key is the private key of the signer.
 //
 // The returned slice is the certificate request in DER encoding.
@@ -2088,9 +2401,9 @@
 
 	var extensions []pkix.Extension
 
-	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
+	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
 		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
-		sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
+		sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
 		if err != nil {
 			return nil, err
 		}
@@ -2265,7 +2578,7 @@
 
 	for _, extension := range out.Extensions {
 		if extension.Id.Equal(oidExtensionSubjectAltName) {
-			out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(extension.Value)
+			out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value)
 			if err != nil {
 				return nil, err
 			}
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 2d1acf9..7d75727 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -22,6 +22,7 @@
 	"internal/testenv"
 	"math/big"
 	"net"
+	"net/url"
 	"os/exec"
 	"reflect"
 	"runtime"
@@ -178,6 +179,125 @@
 	}
 }
 
+func TestMarshalRSAPublicKey(t *testing.T) {
+	pub := &rsa.PublicKey{
+		N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
+		E: 3,
+	}
+	derBytes := MarshalPKCS1PublicKey(pub)
+	pub2, err := ParsePKCS1PublicKey(derBytes)
+	if err != nil {
+		t.Errorf("ParsePKCS1PublicKey: %s", err)
+	}
+	if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E {
+		t.Errorf("ParsePKCS1PublicKey = %+v, want %+v", pub, pub2)
+	}
+
+	// It's never been documented that asn1.Marshal/Unmarshal on rsa.PublicKey works,
+	// but it does, and we know of code that depends on it.
+	// Lock that in, even though we'd prefer that people use MarshalPKCS1PublicKey and ParsePKCS1PublicKey.
+	derBytes2, err := asn1.Marshal(*pub)
+	if err != nil {
+		t.Errorf("Marshal(rsa.PublicKey): %v", err)
+	} else if !bytes.Equal(derBytes, derBytes2) {
+		t.Errorf("Marshal(rsa.PublicKey) = %x, want %x", derBytes2, derBytes)
+	}
+	pub3 := new(rsa.PublicKey)
+	rest, err := asn1.Unmarshal(derBytes, pub3)
+	if err != nil {
+		t.Errorf("Unmarshal(rsa.PublicKey): %v", err)
+	}
+	if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E != pub3.E {
+		t.Errorf("Unmarshal(rsa.PublicKey) = %+v, %q want %+v, %q", pub, rest, pub2, []byte(nil))
+	}
+
+	publicKeys := []struct {
+		derBytes          []byte
+		expectedErrSubstr string
+	}{
+		{
+			derBytes: []byte{
+				0x30, 6, // SEQUENCE, 6 bytes
+				0x02, 1, // INTEGER, 1 byte
+				17,
+				0x02, 1, // INTEGER, 1 byte
+				3, // 3
+			},
+		}, {
+			derBytes: []byte{
+				0x30, 6, // SEQUENCE
+				0x02, 1, // INTEGER, 1 byte
+				0xff,    // -1
+				0x02, 1, // INTEGER, 1 byte
+				3,
+			},
+			expectedErrSubstr: "zero or negative",
+		}, {
+			derBytes: []byte{
+				0x30, 6, // SEQUENCE
+				0x02, 1, // INTEGER, 1 byte
+				17,
+				0x02, 1, // INTEGER, 1 byte
+				0xff, // -1
+			},
+			expectedErrSubstr: "zero or negative",
+		}, {
+			derBytes: []byte{
+				0x30, 6, // SEQUENCE
+				0x02, 1, // INTEGER, 1 byte
+				17,
+				0x02, 1, // INTEGER, 1 byte
+				3,
+				1,
+			},
+			expectedErrSubstr: "trailing data",
+		}, {
+			derBytes: []byte{
+				0x30, 9, // SEQUENCE
+				0x02, 1, // INTEGER, 1 byte
+				17,
+				0x02, 4, // INTEGER, 4 bytes
+				0x7f, 0xff, 0xff, 0xff,
+			},
+		}, {
+			derBytes: []byte{
+				0x30, 10, // SEQUENCE
+				0x02, 1, // INTEGER, 1 byte
+				17,
+				0x02, 5, // INTEGER, 5 bytes
+				0x00, 0x80, 0x00, 0x00, 0x00,
+			},
+			// On 64-bit systems, encoding/asn1 will accept the
+			// public exponent, but ParsePKCS1PublicKey will return
+			// an error. On 32-bit systems, encoding/asn1 will
+			// return the error. The common substring of both error
+			// is the word “large”.
+			expectedErrSubstr: "large",
+		},
+	}
+
+	for i, test := range publicKeys {
+		shouldFail := len(test.expectedErrSubstr) > 0
+		pub, err := ParsePKCS1PublicKey(test.derBytes)
+		if shouldFail {
+			if err == nil {
+				t.Errorf("#%d: unexpected success, got %#v", i, pub)
+			} else if !strings.Contains(err.Error(), test.expectedErrSubstr) {
+				t.Errorf("#%d: expected error containing %q, got %s", i, test.expectedErrSubstr, err)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("#%d: unexpected failure: %s", i, err)
+				continue
+			}
+			reserialized := MarshalPKCS1PublicKey(pub)
+			if !bytes.Equal(reserialized, test.derBytes) {
+				t.Errorf("#%d: failed to reserialize: got %x, expected %x", i, reserialized, test.derBytes)
+			}
+		}
+	}
+}
+
 type matchHostnamesTest struct {
 	pattern, host string
 	ok            bool
@@ -288,6 +408,27 @@
 	}
 }
 
+func TestMismatchedSignatureAlgorithm(t *testing.T) {
+	der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM))
+	if der == nil {
+		t.Fatal("Failed to find PEM block")
+	}
+
+	cert, err := ParseCertificate(der.Bytes)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err = cert.CheckSignature(ECDSAWithSHA256, nil, nil); err == nil {
+		t.Fatal("CheckSignature unexpectedly return no error")
+	}
+
+	const expectedSubstring = " but have public key of type "
+	if !strings.Contains(err.Error(), expectedSubstring) {
+		t.Errorf("Expected error containing %q, but got %q", expectedSubstring, err)
+	}
+}
+
 var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
 	"f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
 	"20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
@@ -331,6 +472,22 @@
 	"9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
 	"36dcd585d6ace53f546f961e05af"
 
+func parseCIDR(s string) *net.IPNet {
+	_, net, err := net.ParseCIDR(s)
+	if err != nil {
+		panic(err)
+	}
+	return net
+}
+
+func parseURI(s string) *url.URL {
+	uri, err := url.Parse(s)
+	if err != nil {
+		panic(err)
+	}
+	return uri
+}
+
 func TestCreateSelfSignedCertificate(t *testing.T) {
 	random := rand.Reader
 
@@ -402,10 +559,17 @@
 			DNSNames:       []string{"test.example.com"},
 			EmailAddresses: []string{"gopher@golang.org"},
 			IPAddresses:    []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
+			URIs:           []*url.URL{parseURI("https://foo.com/wibble#foo")},
 
-			PolicyIdentifiers:   []asn1.ObjectIdentifier{[]int{1, 2, 3}},
-			PermittedDNSDomains: []string{".example.com", "example.com"},
-			ExcludedDNSDomains:  []string{"bar.example.com"},
+			PolicyIdentifiers:       []asn1.ObjectIdentifier{[]int{1, 2, 3}},
+			PermittedDNSDomains:     []string{".example.com", "example.com"},
+			ExcludedDNSDomains:      []string{"bar.example.com"},
+			PermittedIPRanges:       []*net.IPNet{parseCIDR("192.168.1.1/16"), parseCIDR("1.2.3.4/8")},
+			ExcludedIPRanges:        []*net.IPNet{parseCIDR("2001:db8::/48")},
+			PermittedEmailAddresses: []string{"foo@example.com"},
+			ExcludedEmailAddresses:  []string{".example.com", "example.com"},
+			PermittedURIDomains:     []string{".bar.com", "bar.com"},
+			ExcludedURIDomains:      []string{".bar2.com", "bar2.com"},
 
 			CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
 
@@ -447,6 +611,30 @@
 			t.Errorf("%s: failed to parse name constraint exclusions: %#v", test.name, cert.ExcludedDNSDomains)
 		}
 
+		if len(cert.PermittedIPRanges) != 2 || cert.PermittedIPRanges[0].String() != "192.168.0.0/16" || cert.PermittedIPRanges[1].String() != "1.0.0.0/8" {
+			t.Errorf("%s: failed to parse IP constraints: %#v", test.name, cert.PermittedIPRanges)
+		}
+
+		if len(cert.ExcludedIPRanges) != 1 || cert.ExcludedIPRanges[0].String() != "2001:db8::/48" {
+			t.Errorf("%s: failed to parse IP constraint exclusions: %#v", test.name, cert.ExcludedIPRanges)
+		}
+
+		if len(cert.PermittedEmailAddresses) != 1 || cert.PermittedEmailAddresses[0] != "foo@example.com" {
+			t.Errorf("%s: failed to parse permitted email addreses: %#v", test.name, cert.PermittedEmailAddresses)
+		}
+
+		if len(cert.ExcludedEmailAddresses) != 2 || cert.ExcludedEmailAddresses[0] != ".example.com" || cert.ExcludedEmailAddresses[1] != "example.com" {
+			t.Errorf("%s: failed to parse excluded email addreses: %#v", test.name, cert.ExcludedEmailAddresses)
+		}
+
+		if len(cert.PermittedURIDomains) != 2 || cert.PermittedURIDomains[0] != ".bar.com" || cert.PermittedURIDomains[1] != "bar.com" {
+			t.Errorf("%s: failed to parse permitted URIs: %#v", test.name, cert.PermittedURIDomains)
+		}
+
+		if len(cert.ExcludedURIDomains) != 2 || cert.ExcludedURIDomains[0] != ".bar2.com" || cert.ExcludedURIDomains[1] != "bar2.com" {
+			t.Errorf("%s: failed to parse excluded URIs: %#v", test.name, cert.ExcludedURIDomains)
+		}
+
 		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)
 		}
@@ -455,6 +643,14 @@
 			t.Errorf("%s: ExtraNames didn't override Country", test.name)
 		}
 
+		for _, ext := range cert.Extensions {
+			if ext.Id.Equal(oidExtensionSubjectAltName) {
+				if ext.Critical {
+					t.Fatal("SAN extension is marked critical")
+				}
+			}
+		}
+
 		found := false
 		for _, atv := range cert.Subject.Names {
 			if atv.Type.Equal([]int{2, 5, 4, 42}) {
@@ -498,6 +694,10 @@
 			t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
 		}
 
+		if len(cert.URIs) != 1 || cert.URIs[0].String() != "https://foo.com/wibble#foo" {
+			t.Errorf("%s: URIs differ from template. Got %v, want %v", test.name, cert.URIs, template.URIs)
+		}
+
 		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)
 		}
@@ -523,74 +723,6 @@
 	}
 }
 
-func TestUnknownCriticalExtension(t *testing.T) {
-	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to generate ECDSA key: %s", err)
-	}
-
-	oids := []asn1.ObjectIdentifier{
-		// This OID is in the PKIX arc, but unknown.
-		{2, 5, 29, 999999},
-		// This is a nonsense, unassigned OID.
-		{1, 2, 3, 4},
-	}
-
-	for _, oid := range oids {
-		template := Certificate{
-			SerialNumber: big.NewInt(1),
-			Subject: pkix.Name{
-				CommonName: "foo",
-			},
-			NotBefore: time.Unix(1000, 0),
-			NotAfter:  time.Now().AddDate(1, 0, 0),
-
-			BasicConstraintsValid: true,
-			IsCA: true,
-
-			KeyUsage:    KeyUsageCertSign,
-			ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth},
-
-			ExtraExtensions: []pkix.Extension{
-				{
-					Id:       oid,
-					Critical: true,
-					Value:    nil,
-				},
-			},
-		}
-
-		derBytes, err := CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
-		if err != nil {
-			t.Fatalf("failed to create certificate: %s", err)
-		}
-
-		cert, err := ParseCertificate(derBytes)
-		if err != nil {
-			t.Fatalf("Certificate with unknown critical extension was not parsed: %s", err)
-		}
-
-		roots := NewCertPool()
-		roots.AddCert(cert)
-
-		// Setting Roots ensures that Verify won't delegate to the OS
-		// library and thus the correct error should always be
-		// returned.
-		_, err = cert.Verify(VerifyOptions{Roots: roots})
-		if err == nil {
-			t.Fatal("Certificate with unknown critical extension was verified without error")
-		}
-		if _, ok := err.(UnhandledCriticalExtension); !ok {
-			t.Fatalf("Error was %#v, but wanted one of type UnhandledCriticalExtension", err)
-		}
-
-		cert.UnhandledCriticalExtensions = nil
-		if _, err = cert.Verify(VerifyOptions{Roots: roots}); err != nil {
-			t.Errorf("Certificate failed to verify after unhandled critical extensions were cleared: %s", err)
-		}
-	}
-}
-
 // Self-signed certificate using ECDSA with SHA1 & secp256r1
 var ecdsaSHA1CertPem = `
 -----BEGIN CERTIFICATE-----
@@ -1059,7 +1191,7 @@
 }
 
 func TestCertificateRequestOverrides(t *testing.T) {
-	sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil)
+	sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1116,7 +1248,7 @@
 		t.Errorf("bad attributes: %#v\n", csr.Attributes)
 	}
 
-	sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil)
+	sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1491,3 +1623,326 @@
 		t.Fatal(err)
 	}
 }
+
+const emptyNameConstraintsPEM = `
+-----BEGIN CERTIFICATE-----
+MIIC1jCCAb6gAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
+dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
+NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
+F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
+f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
+Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
+LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
+blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
+AQABoxEwDzANBgNVHR4EBjAEoAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMH
+QhP8uNCtgSHyim/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb
+6L+iJa4ElREJOi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6H
+v5SsvpYW+1XleYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6M
+LYPmRhTioROA/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOga
+nCOSyFYfGhqOANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8
+o+WoY6IsCKXV/g==
+-----END CERTIFICATE-----`
+
+func TestEmptyNameConstraints(t *testing.T) {
+	block, _ := pem.Decode([]byte(emptyNameConstraintsPEM))
+	_, err := ParseCertificate(block.Bytes)
+	if err == nil {
+		t.Fatal("unexpected success")
+	}
+
+	const expected = "empty name constraints"
+	if str := err.Error(); !strings.Contains(str, expected) {
+		t.Errorf("expected %q in error but got %q", expected, str)
+	}
+}
+
+func TestPKIXNameString(t *testing.T) {
+	pem, err := hex.DecodeString(certBytes)
+	if err != nil {
+		t.Fatal(err)
+	}
+	certs, err := ParseCertificates(pem)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tests := []struct {
+		dn   pkix.Name
+		want string
+	}{
+		{pkix.Name{
+			CommonName:         "Steve Kille",
+			Organization:       []string{"Isode Limited"},
+			OrganizationalUnit: []string{"RFCs"},
+			Locality:           []string{"Richmond"},
+			Province:           []string{"Surrey"},
+			StreetAddress:      []string{"The Square"},
+			PostalCode:         []string{"TW9 1DT"},
+			SerialNumber:       "RFC 2253",
+			Country:            []string{"GB"},
+		}, "SERIALNUMBER=RFC 2253,CN=Steve Kille,OU=RFCs,O=Isode Limited,POSTALCODE=TW9 1DT,STREET=The Square,L=Richmond,ST=Surrey,C=GB"},
+		{certs[0].Subject,
+			"CN=mail.google.com,O=Google Inc,L=Mountain View,ST=California,C=US"},
+		{pkix.Name{
+			Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "},
+			Country:      []string{"US"},
+		}, "O=\\#Google\\, Inc. \n-\\> 'Alphabet\\\"\\ ,C=US"},
+		{pkix.Name{
+			CommonName:   "foo.com",
+			Organization: []string{"Gopher Industries"},
+			ExtraNames: []pkix.AttributeTypeAndValue{
+				{Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}},
+		}, "CN=bar.com,O=Gopher Industries"},
+		{pkix.Name{
+			Locality: []string{"Gophertown"},
+			ExtraNames: []pkix.AttributeTypeAndValue{
+				{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
+		}, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"},
+	}
+
+	for i, test := range tests {
+		if got := test.dn.String(); got != test.want {
+			t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
+		}
+	}
+}
+
+func TestRDNSequenceString(t *testing.T) {
+	// Test some extra cases that get lost in pkix.Name conversions such as
+	// multi-valued attributes.
+
+	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}
+	)
+
+	tests := []struct {
+		seq  pkix.RDNSequence
+		want string
+	}{
+		{
+			seq: pkix.RDNSequence{
+				pkix.RelativeDistinguishedNameSET{
+					pkix.AttributeTypeAndValue{Type: oidCountry, Value: "US"},
+				},
+				pkix.RelativeDistinguishedNameSET{
+					pkix.AttributeTypeAndValue{Type: oidOrganization, Value: "Widget Inc."},
+				},
+				pkix.RelativeDistinguishedNameSET{
+					pkix.AttributeTypeAndValue{Type: oidOrganizationalUnit, Value: "Sales"},
+					pkix.AttributeTypeAndValue{Type: oidCommonName, Value: "J. Smith"},
+				},
+			},
+			want: "OU=Sales+CN=J. Smith,O=Widget Inc.,C=US",
+		},
+	}
+
+	for i, test := range tests {
+		if got := test.seq.String(); got != test.want {
+			t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
+		}
+	}
+}
+
+const criticalNameConstraintWithUnknownTypePEM = `
+-----BEGIN CERTIFICATE-----
+MIIC/TCCAeWgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
+dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
+NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
+F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
+f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
+Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
+LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
+blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
+AQABozgwNjA0BgNVHR4BAf8EKjAooCQwIokgIACrzQAAAAAAAAAAAAAAAP////8A
+AAAAAAAAAAAAAAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMHQhP8uNCtgSHy
+im/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb6L+iJa4ElREJ
+Oi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6Hv5SsvpYW+1Xl
+eYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6MLYPmRhTioROA
+/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOganCOSyFYfGhqO
+ANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8o+WoY6IsCKXV
+/g==
+-----END CERTIFICATE-----`
+
+func TestCriticalNameConstraintWithUnknownType(t *testing.T) {
+	block, _ := pem.Decode([]byte(criticalNameConstraintWithUnknownTypePEM))
+	cert, err := ParseCertificate(block.Bytes)
+	if err != nil {
+		t.Fatalf("unexpected parsing failure: %s", err)
+	}
+
+	if l := len(cert.UnhandledCriticalExtensions); l != 1 {
+		t.Fatalf("expected one unhandled critical extension, but found %d", l)
+	}
+}
+
+const badIPMaskPEM = `
+-----BEGIN CERTIFICATE-----
+MIICzzCCAbegAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAxMSQmFk
+IElQIG1hc2sgaXNzdWVyMB4XDTEzMDIwMTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
+FjEUMBIGA1UEAxMLQmFkIElQIG1hc2swggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDCuISVQi3csKqYk5uz7IOhY8MXkiqBaTqagihtiM997G1mJhTojcR+
+8DCg3E8OQ3ZajByhxRkwlsR4Srl5sGSwWfF/XaAHGUhWIhjBkDO7toW+EMzI8pAj
+cLwIbRlIL0AFnUTe6Z0DcIS5406Y/9MKE2oKXbf4EbVBv88mSkA74Z+lZJWFNxXn
+cx/9wq8UdyMY2vHN1Kir1/JbtrqB9wYRBjQtWSbAVZR8nTBPyRp4uvQTS2jOQh+j
+TUo1Y3O/o1xg/zRA4FEOUCla704OYRUkc8NuXHiPNNDcktr7gO8E06NVQ6n6aBGa
+OJbSst2vHA7Eiog7A2PB4wKn+GDFf+FNAgMBAAGjIDAeMBwGA1UdHgEB/wQSMBCg
+DDAKhwgBAgME//8BAKEAMA0GCSqGSIb3DQEBCwUAA4IBAQBYb7/NQwdCE/y40K2B
+IfKKb++HvCaKfAC9aAwrGWQsEWezqdl5Cqw5XWUAFjtTRm6iprVnmdvov6IlrgSV
+EQk6L96stz24vAF0MIBHSFRMoPtrqLiihLf0NOV7ztxSePQxbUJRroe/lKy+lhb7
+VeV5gmT9rFA45NzLgSznd2+dmyNcfQQD9AeeftRX4maUTeu1XFxinowtg+ZGFOKh
+E4D92uCGJxGSK72HF0/LGRhLXozmDdmPfSN2b6T/oLo942031iY46BqcI5LIVh8a
+Go4A1jOma5X6gh50Cw+kht8jM3yeNhSzXOKj7Uigjijx10z2wJu09Tyj5ahjoiwI
+pdX+
+-----END CERTIFICATE-----`
+
+func TestBadIPMask(t *testing.T) {
+	block, _ := pem.Decode([]byte(badIPMaskPEM))
+	_, err := ParseCertificate(block.Bytes)
+	if err == nil {
+		t.Fatalf("unexpected success")
+	}
+
+	const expected = "contained invalid mask"
+	if !strings.Contains(err.Error(), expected) {
+		t.Fatalf("expected %q in error but got: %s", expected, err)
+	}
+}
+
+const additionalGeneralSubtreePEM = `
+-----BEGIN CERTIFICATE-----
+MIIG4TCCBMmgAwIBAgIRALss+4rLw2Ia7tFFhxE8g5cwDQYJKoZIhvcNAQELBQAw
+bjELMAkGA1UEBhMCTkwxIDAeBgNVBAoMF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
+MT0wOwYDVQQDDDRNaW5pc3RlcmllIHZhbiBEZWZlbnNpZSBDZXJ0aWZpY2F0aWUg
+QXV0b3JpdGVpdCAtIEcyMB4XDTEzMDMwNjEyMDM0OVoXDTEzMTEzMDEyMDM1MFow
+bDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUNlcnRpUGF0aCBMTEMxIjAgBgNVBAsT
+GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxITAfBgNVBAMTGENlcnRpUGF0aCBC
+cmlkZ2UgQ0EgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLW
+4kXiRqvwBhJfN9uz12FA+P2D34MPxOt7TGXljm2plJ2CLzvaH8/ymsMdSWdJBS1M
+8FmwvNL1w3A6ZuzksJjPikAu8kY3dcp3mrkk9eCPORDAwGtfsXwZysLiuEaDWpbD
+dHOaHnI6qWU0N6OI+hNX58EjDpIGC1WQdho1tHOTPc5Hf5/hOpM/29v/wr7kySjs
+Z+7nsvkm5rNhuJNzPsLsgzVaJ5/BVyOplZy24FKM8Y43MjR4osZm+a2e0zniqw6/
+rvcjcGYabYaznZfQG1GXoyf2Vea+CCgpgUhlVafgkwEs8izl8rIpvBzXiFAgFQuG
+Ituoy92PJbDs430fA/cCAwEAAaOCAnowggJ2MEUGCCsGAQUFBwEBBDkwNzA1Bggr
+BgEFBQcwAoYpaHR0cDovL2NlcnRzLmNhLm1pbmRlZi5ubC9taW5kZWYtY2EtMi5w
+N2MwHwYDVR0jBBgwFoAUzln9WSPz2M64Rl2HYf2/KD8StmQwDwYDVR0TAQH/BAUw
+AwEB/zCB6QYDVR0gBIHhMIHeMEgGCmCEEAGHawECBQEwOjA4BggrBgEFBQcCARYs
+aHR0cDovL2Nwcy5kcC5jYS5taW5kZWYubmwvbWluZGVmLWNhLWRwLWNwcy8wSAYK
+YIQQAYdrAQIFAjA6MDgGCCsGAQUFBwIBFixodHRwOi8vY3BzLmRwLmNhLm1pbmRl
+Zi5ubC9taW5kZWYtY2EtZHAtY3BzLzBIBgpghBABh2sBAgUDMDowOAYIKwYBBQUH
+AgEWLGh0dHA6Ly9jcHMuZHAuY2EubWluZGVmLm5sL21pbmRlZi1jYS1kcC1jcHMv
+MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmxzLmNhLm1pbmRlZi5ubC9taW5k
+ZWYtY2EtMi5jcmwwDgYDVR0PAQH/BAQDAgEGMEYGA1UdHgEB/wQ8MDqhODA2pDEw
+LzELMAkGA1UEBhMCTkwxIDAeBgNVBAoTF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
+gQFjMF0GA1UdIQRWMFQwGgYKYIQQAYdrAQIFAQYMKwYBBAGBu1MBAQECMBoGCmCE
+EAGHawECBQIGDCsGAQQBgbtTAQEBAjAaBgpghBABh2sBAgUDBgwrBgEEAYG7UwEB
+AQIwHQYDVR0OBBYEFNDCjBM3M3ZKkag84ei3/aKc0d0UMA0GCSqGSIb3DQEBCwUA
+A4ICAQAQXFn9jF90/DNFf15JhoGtta/0dNInb14PMu3PAjcdrXYCDPpQZOArTUng
+5YT1WuzfmjnXiTsziT3my0r9Mxvz/btKK/lnVOMW4c2q/8sIsIPnnW5ZaRGrsANB
+dNDZkzMYmeG2Pfgvd0AQSOrpE/TVgWfu/+MMRWwX9y6VbooBR7BLv7zMuVH0WqLn
+6OMFth7fqsThlfMSzkE/RDSaU6n3wXAWT1SIqBITtccRjSUQUFm/q3xrb2cwcZA6
+8vdS4hzNd+ttS905ay31Ks4/1Wrm1bH5RhEfRSH0VSXnc0b+z+RyBbmiwtVZqzxE
+u3UQg/rAmtLDclLFEzjp8YDTIRYSLwstDbEXO/0ArdGrQm79HQ8i/3ZbP2357myW
+i15qd6gMJIgGHS4b8Hc7R1K8LQ9Gm1aLKBEWVNGZlPK/cpXThpVmoEyslN2DHCrc
+fbMbjNZpXlTMa+/b9z7Fa4X8dY8u/ELzZuJXJv5Rmqtg29eopFFYDCl0Nkh1XAjo
+QejEoHHUvYV8TThHZr6Z6Ib8CECgTehU4QvepkgDXNoNrKRZBG0JhLjkwxh2whZq
+nvWBfALC2VuNOM6C0rDY+HmhMlVt0XeqnybD9MuQALMit7Z00Cw2CIjNsBI9xBqD
+xKK9CjUb7gzRUWSpB9jGHsvpEMHOzIFhufvH2Bz1XJw+Cl7khw==
+-----END CERTIFICATE-----`
+
+func TestAdditionFieldsInGeneralSubtree(t *testing.T) {
+	// Very rarely, certificates can include additional fields in the
+	// GeneralSubtree structure. This tests that such certificates can be
+	// parsed.
+	block, _ := pem.Decode([]byte(additionalGeneralSubtreePEM))
+	if _, err := ParseCertificate(block.Bytes); err != nil {
+		t.Fatalf("failed to parse certificate: %s", err)
+	}
+}
+
+func TestEmptySubject(t *testing.T) {
+	template := Certificate{
+		SerialNumber: big.NewInt(1),
+		DNSNames:     []string{"example.com"},
+	}
+
+	derBytes, err := CreateCertificate(rand.Reader, &template, &template, &testPrivateKey.PublicKey, testPrivateKey)
+	if err != nil {
+		t.Fatalf("failed to create certificate: %s", err)
+	}
+
+	cert, err := ParseCertificate(derBytes)
+	if err != nil {
+		t.Fatalf("failed to parse certificate: %s", err)
+	}
+
+	for _, ext := range cert.Extensions {
+		if ext.Id.Equal(oidExtensionSubjectAltName) {
+			if !ext.Critical {
+				t.Fatal("SAN extension is not critical")
+			}
+			return
+		}
+	}
+
+	t.Fatal("SAN extension is missing")
+}
+
+// multipleURLsInCRLDPPEM contains two URLs in a single CRL DistributionPoint
+// structure. It is taken from https://crt.sh/?id=12721534.
+const multipleURLsInCRLDPPEM = `
+-----BEGIN CERTIFICATE-----
+MIIF4TCCBMmgAwIBAgIQc+6uFePfrahUGpXs8lhiTzANBgkqhkiG9w0BAQsFADCB
+8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
+dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
+YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
+dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
+IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
+LUFDQzAeFw0xNDA5MTgwODIxMDBaFw0zMDA5MTgwODIxMDBaMIGGMQswCQYDVQQG
+EwJFUzEzMDEGA1UECgwqQ09OU09SQ0kgQURNSU5JU1RSQUNJTyBPQkVSVEEgREUg
+Q0FUQUxVTllBMSowKAYDVQQLDCFTZXJ2ZWlzIFDDumJsaWNzIGRlIENlcnRpZmlj
+YWNpw7MxFjAUBgNVBAMMDUVDLUNpdXRhZGFuaWEwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDFkHPRZPZlXTWZ5psJhbS/Gx+bxcTpGrlVQHHtIkgGz77y
+TA7UZUFb2EQMncfbOhR0OkvQQn1aMvhObFJSR6nI+caf2D+h/m/InMl1MyH3S0Ak
+YGZZsthnyC6KxqK2A/NApncrOreh70ULkQs45aOKsi1kR1W0zE+iFN+/P19P7AkL
+Rl3bXBCVd8w+DLhcwRrkf1FCDw6cEqaFm3cGgf5cbBDMaVYAweWTxwBZAq2RbQAW
+jE7mledcYghcZa4U6bUmCBPuLOnO8KMFAvH+aRzaf3ws5/ZoOVmryyLLJVZ54peZ
+OwnP9EL4OuWzmXCjBifXR2IAblxs5JYj57tls45nAgMBAAGjggHaMIIB1jASBgNV
+HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUC2hZPofI
+oxUa4ECCIl+fHbLFNxUwHwYDVR0jBBgwFoAUoMOLRKo3pUW/l4Ba0fF4opvpXY0w
+gdYGA1UdIASBzjCByzCByAYEVR0gADCBvzAxBggrBgEFBQcCARYlaHR0cHM6Ly93
+d3cuYW9jLmNhdC9DQVRDZXJ0L1JlZ3VsYWNpbzCBiQYIKwYBBQUHAgIwfQx7QXF1
+ZXN0IGNlcnRpZmljYXQgw6lzIGVtw6hzIMO6bmljYSBpIGV4Y2x1c2l2YW1lbnQg
+YSBFbnRpdGF0cyBkZSBDZXJ0aWZpY2FjacOzLiBWZWdldSBodHRwczovL3d3dy5h
+b2MuY2F0L0NBVENlcnQvUmVndWxhY2lvMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEF
+BQcwAYYXaHR0cDovL29jc3AuY2F0Y2VydC5jYXQwYgYDVR0fBFswWTBXoFWgU4Yn
+aHR0cDovL2Vwc2NkLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JshihodHRwOi8v
+ZXBzY2QyLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JsMA0GCSqGSIb3DQEBCwUA
+A4IBAQChqFTjlAH5PyIhLjLgEs68CyNNC1+vDuZXRhy22TI83JcvGmQrZosPvVIL
+PsUXx+C06Pfqmh48Q9S89X9K8w1SdJxP/rZeGEoRiKpwvQzM4ArD9QxyC8jirxex
+3Umg9Ai/sXQ+1lBf6xw4HfUUr1WIp7pNHj0ZWLo106urqktcdeAFWme+/klis5fu
+labCSVPuT/QpwakPrtqOhRms8vgpKiXa/eLtL9ZiA28X/Mker0zlAeTA7Z7uAnp6
+oPJTlZu1Gg1ZDJueTWWsLlO+P+Wzm3MRRIbcgdRzm4mdO7ubu26SzX/aQXDhuih+
+eVxXDTCfs7GUlxnjOp5j559X/N0A
+-----END CERTIFICATE-----
+`
+
+func TestMultipleURLsInCRLDP(t *testing.T) {
+	block, _ := pem.Decode([]byte(multipleURLsInCRLDPPEM))
+	cert, err := ParseCertificate(block.Bytes)
+	if err != nil {
+		t.Fatalf("failed to parse certificate: %s", err)
+	}
+
+	want := []string{
+		"http://epscd.catcert.net/crl/ec-acc.crl",
+		"http://epscd2.catcert.net/crl/ec-acc.crl",
+	}
+	if got := cert.CRLDistributionPoints; !reflect.DeepEqual(got, want) {
+		t.Errorf("CRL distribution points = %#v, want #%v", got, want)
+	}
+}
diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go
index 4983181..b79ec3f 100644
--- a/src/database/sql/convert.go
+++ b/src/database/sql/convert.go
@@ -12,7 +12,6 @@
 	"fmt"
 	"reflect"
 	"strconv"
-	"sync"
 	"time"
 	"unicode"
 	"unicode/utf8"
@@ -38,17 +37,10 @@
 	return fmt.Errorf("name %q does not begin with a letter", name)
 }
 
-func driverNumInput(ds *driverStmt) int {
-	ds.Lock()
-	defer ds.Unlock() // in case NumInput panics
-	return ds.si.NumInput()
-}
-
 // ccChecker wraps the driver.ColumnConverter and allows it to be used
 // as if it were a NamedValueChecker. If the driver ColumnConverter
 // is not present then the NamedValueChecker will return driver.ErrSkip.
 type ccChecker struct {
-	sync.Locker
 	cci  driver.ColumnConverter
 	want int
 }
@@ -88,9 +80,7 @@
 	// same error.
 	var err error
 	arg := nv.Value
-	c.Lock()
 	nv.Value, err = c.cci.ColumnConverter(index).ConvertValue(arg)
-	c.Unlock()
 	if err != nil {
 		return err
 	}
@@ -112,7 +102,7 @@
 // Stmt.Query into driver Values.
 //
 // The statement ds may be nil, if no statement is available.
-func driverArgs(ci driver.Conn, ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) {
+func driverArgsConnLocked(ci driver.Conn, ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) {
 	nvargs := make([]driver.NamedValue, len(args))
 
 	// -1 means the driver doesn't know how to count the number of
@@ -124,8 +114,7 @@
 	var cc ccChecker
 	if ds != nil {
 		si = ds.si
-		want = driverNumInput(ds)
-		cc.Locker = ds.Locker
+		want = ds.si.NumInput()
 		cc.want = want
 	}
 
@@ -204,7 +193,7 @@
 		}
 	}
 
-	// Check the length of arguments after convertion to allow for omitted
+	// Check the length of arguments after conversion to allow for omitted
 	// arguments.
 	if want != -1 && len(nvargs) != want {
 		return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(nvargs))
@@ -234,6 +223,12 @@
 			}
 			*d = []byte(s)
 			return nil
+		case *RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = append((*d)[:0], s...)
+			return nil
 		}
 	case []byte:
 		switch d := dest.(type) {
@@ -264,6 +259,9 @@
 		}
 	case time.Time:
 		switch d := dest.(type) {
+		case *time.Time:
+			*d = s
+			return nil
 		case *string:
 			*d = s.Format(time.RFC3339Nano)
 			return nil
@@ -273,6 +271,12 @@
 			}
 			*d = []byte(s.Format(time.RFC3339Nano))
 			return nil
+		case *RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
+			return nil
 		}
 	case nil:
 		switch d := dest.(type) {
diff --git a/src/database/sql/convert_test.go b/src/database/sql/convert_test.go
index cfe52d7..b0aff7b 100644
--- a/src/database/sql/convert_test.go
+++ b/src/database/sql/convert_test.go
@@ -64,121 +64,128 @@
 	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},
+func conversionTests() []conversionTest {
+	// Return a fresh instance to test so "go test -count 2" works correctly.
+	return []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 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"},
 
-	// From time.Time:
-	{s: time.Unix(1, 0).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01Z"},
-	{s: time.Unix(1453874597, 0).In(time.FixedZone("here", -3600*8)), d: &scanstr, wantstr: "2016-01-26T22:03:17-08:00"},
-	{s: time.Unix(1, 2).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01.000000002Z"},
-	{s: time.Time{}, d: &scanstr, wantstr: "0001-01-01T00:00:00Z"},
-	{s: time.Unix(1, 2).UTC(), d: &scanbytes, wantbytes: []byte("1970-01-01T00:00:01.000000002Z")},
-	{s: time.Unix(1, 2).UTC(), d: &scaniface, wantiface: time.Unix(1, 2).UTC()},
+		// From time.Time:
+		{s: time.Unix(1, 0).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01Z"},
+		{s: time.Unix(1453874597, 0).In(time.FixedZone("here", -3600*8)), d: &scanstr, wantstr: "2016-01-26T22:03:17-08:00"},
+		{s: time.Unix(1, 2).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01.000000002Z"},
+		{s: time.Time{}, d: &scanstr, wantstr: "0001-01-01T00:00:00Z"},
+		{s: time.Unix(1, 2).UTC(), d: &scanbytes, wantbytes: []byte("1970-01-01T00:00:01.000000002Z")},
+		{s: time.Unix(1, 2).UTC(), d: &scaniface, wantiface: time.Unix(1, 2).UTC()},
 
-	// 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 []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")},
+		// To RawBytes
+		{s: nil, d: &scanraw, wantraw: nil},
+		{s: []byte("byteslice"), d: &scanraw, wantraw: RawBytes("byteslice")},
+		{s: "string", d: &scanraw, wantraw: RawBytes("string")},
+		{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")},
+		// time.Time has been placed here to check that the RawBytes slice gets
+		// correctly reset when calling time.Time.AppendFormat.
+		{s: time.Unix(2, 5).UTC(), d: &scanraw, wantraw: RawBytes("1970-01-01T00:00:02.000000005Z")},
 
-	// Strings to integers
-	{s: "255", d: &scanuint8, wantuint: 255},
-	{s: "256", d: &scanuint8, wanterr: "converting driver.Value type string (\"256\") to a uint8: value out of range"},
-	{s: "256", d: &scanuint16, wantuint: 256},
-	{s: "-1", d: &scanint, wantint: -1},
-	{s: "foo", d: &scanint, wanterr: "converting driver.Value type string (\"foo\") to a int: invalid syntax"},
+		// Strings to integers
+		{s: "255", d: &scanuint8, wantuint: 255},
+		{s: "256", d: &scanuint8, wanterr: "converting driver.Value type string (\"256\") to a uint8: value out of range"},
+		{s: "256", d: &scanuint16, wantuint: 256},
+		{s: "-1", d: &scanint, wantint: -1},
+		{s: "foo", d: &scanint, wanterr: "converting driver.Value type string (\"foo\") to a int: invalid syntax"},
 
-	// int64 to smaller integers
-	{s: int64(5), d: &scanuint8, wantuint: 5},
-	{s: int64(256), d: &scanuint8, wanterr: "converting driver.Value type int64 (\"256\") to a uint8: value out of range"},
-	{s: int64(256), d: &scanuint16, wantuint: 256},
-	{s: int64(65536), d: &scanuint16, wanterr: "converting driver.Value type int64 (\"65536\") to a uint16: value out of range"},
+		// int64 to smaller integers
+		{s: int64(5), d: &scanuint8, wantuint: 5},
+		{s: int64(256), d: &scanuint8, wanterr: "converting driver.Value type int64 (\"256\") to a uint8: value out of range"},
+		{s: int64(256), d: &scanuint16, wantuint: 256},
+		{s: int64(65536), d: &scanuint16, wanterr: "converting driver.Value type int64 (\"65536\") to a uint16: value out of range"},
 
-	// 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},
+		// 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},
+		// 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`},
+		// 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)},
+		// 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},
+		// 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)},
+		// 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)},
 
-	// To a user-defined type
-	{s: 1.5, d: new(userDefined), wantusrdef: 1.5},
-	{s: int64(123), d: new(userDefined), wantusrdef: 123},
-	{s: "1.5", d: new(userDefined), wantusrdef: 1.5},
-	{s: []byte{1, 2, 3}, d: new(userDefinedSlice), wanterr: `unsupported Scan, storing driver.Value type []uint8 into type *sql.userDefinedSlice`},
-	{s: "str", d: new(userDefinedString), wantusrstr: "str"},
+		// To a user-defined type
+		{s: 1.5, d: new(userDefined), wantusrdef: 1.5},
+		{s: int64(123), d: new(userDefined), wantusrdef: 123},
+		{s: "1.5", d: new(userDefined), wantusrdef: 1.5},
+		{s: []byte{1, 2, 3}, d: new(userDefinedSlice), wanterr: `unsupported Scan, storing driver.Value type []uint8 into type *sql.userDefinedSlice`},
+		{s: "str", d: new(userDefinedString), wantusrstr: "str"},
 
-	// Other errors
-	{s: complex(1, 2), d: &scanstr, wanterr: `unsupported Scan, storing driver.Value type complex128 into type *string`},
+		// Other errors
+		{s: complex(1, 2), d: &scanstr, wanterr: `unsupported Scan, storing driver.Value type complex128 into type *string`},
+	}
 }
 
 func intPtrValue(intptr interface{}) interface{} {
@@ -206,7 +213,7 @@
 }
 
 func TestConversions(t *testing.T) {
-	for n, ct := range conversionTests {
+	for n, ct := range conversionTests() {
 		err := convertAssign(ct.d, ct.s)
 		errstr := ""
 		if err != nil {
@@ -222,6 +229,12 @@
 		if ct.wantstr != "" && ct.wantstr != scanstr {
 			errf("want string %q, got %q", ct.wantstr, scanstr)
 		}
+		if ct.wantbytes != nil && string(ct.wantbytes) != string(scanbytes) {
+			errf("want byte %q, got %q", ct.wantbytes, scanbytes)
+		}
+		if ct.wantraw != nil && string(ct.wantraw) != string(scanraw) {
+			errf("want RawBytes %q, got %q", ct.wantraw, scanraw)
+		}
 		if ct.wantint != 0 && ct.wantint != intValue(ct.d) {
 			errf("want int %d, got %d", ct.wantint, intValue(ct.d))
 		}
@@ -341,6 +354,7 @@
 		{"float32", float32(1.5), "1.5"},
 		{"float64", float64(64), "64"},
 		{"bool", false, "false"},
+		{"time", time.Unix(2, 5).UTC(), "1970-01-01T00:00:02.000000005Z"},
 	}
 
 	buf := make(RawBytes, 10)
@@ -387,7 +401,7 @@
 	}
 }
 
-// https://github.com/golang/go/issues/13905
+// https://golang.org/issues/13905
 func TestUserDefinedBytes(t *testing.T) {
 	type userDefinedBytes []byte
 	var u userDefinedBytes
@@ -470,7 +484,7 @@
 	}
 	for i, tt := range tests {
 		ds := &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{nil}}
-		got, err := driverArgs(nil, ds, tt.args)
+		got, err := driverArgsConnLocked(nil, ds, tt.args)
 		if err != nil {
 			t.Errorf("test[%d]: %v", i, err)
 			continue
diff --git a/src/database/sql/ctxutil.go b/src/database/sql/ctxutil.go
index bd652b5..af2afd5 100644
--- a/src/database/sql/ctxutil.go
+++ b/src/database/sql/ctxutil.go
@@ -26,8 +26,8 @@
 	return si, err
 }
 
-func ctxDriverExec(ctx context.Context, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) {
-	if execerCtx, is := execer.(driver.ExecerContext); is {
+func ctxDriverExec(ctx context.Context, execerCtx driver.ExecerContext, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) {
+	if execerCtx != nil {
 		return execerCtx.ExecContext(ctx, query, nvdargs)
 	}
 	dargs, err := namedValueToValue(nvdargs)
@@ -43,10 +43,9 @@
 	return execer.Exec(query, dargs)
 }
 
-func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) {
-	if queryerCtx, is := queryer.(driver.QueryerContext); is {
-		ret, err := queryerCtx.QueryContext(ctx, query, nvdargs)
-		return ret, err
+func ctxDriverQuery(ctx context.Context, queryerCtx driver.QueryerContext, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) {
+	if queryerCtx != nil {
+		return queryerCtx.QueryContext(ctx, query, nvdargs)
 	}
 	dargs, err := namedValueToValue(nvdargs)
 	if err != nil {
@@ -107,10 +106,6 @@
 		return ciCtx.BeginTx(ctx, dopts)
 	}
 
-	if ctx.Done() == context.Background().Done() {
-		return ci.Begin()
-	}
-
 	if opts != nil {
 		// Check the transaction level. If the transaction level is non-default
 		// then return an error here as the BeginTx driver value is not supported.
@@ -125,6 +120,10 @@
 		}
 	}
 
+	if ctx.Done() == nil {
+		return ci.Begin()
+	}
+
 	txi, err := ci.Begin()
 	if err == nil {
 		select {
diff --git a/src/database/sql/driver/driver.go b/src/database/sql/driver/driver.go
index 0262ca2..1e54b4c 100644
--- a/src/database/sql/driver/driver.go
+++ b/src/database/sql/driver/driver.go
@@ -15,7 +15,8 @@
 )
 
 // Value is a value that drivers must be able to handle.
-// It is either nil or an instance of one of these types:
+// It is either nil, a type handled by a database driver's NamedValueChecker
+// interface, or an instance of one of these types:
 //
 //   int64
 //   float64
@@ -42,6 +43,10 @@
 
 // Driver is the interface that must be implemented by a database
 // driver.
+//
+// Database drivers may implement DriverContext for access
+// to contexts and to parse the name only once for a pool of connections,
+// instead of once per connection.
 type Driver interface {
 	// Open returns a new connection to the database.
 	// The name is a string in a driver-specific format.
@@ -55,6 +60,47 @@
 	Open(name string) (Conn, error)
 }
 
+// If a Driver implements DriverContext, then sql.DB will call
+// OpenConnector to obtain a Connector and then invoke
+// that Connector's Conn method to obtain each needed connection,
+// instead of invoking the Driver's Open method for each connection.
+// The two-step sequence allows drivers to parse the name just once
+// and also provides access to per-Conn contexts.
+type DriverContext interface {
+	// OpenConnector must parse the name in the same format that Driver.Open
+	// parses the name parameter.
+	OpenConnector(name string) (Connector, error)
+}
+
+// A Connector represents a driver in a fixed configuration
+// and can create any number of equivalent Conns for use
+// by multiple goroutines.
+//
+// A Connector can be passed to sql.OpenDB, to allow drivers
+// to implement their own sql.DB constructors, or returned by
+// DriverContext's OpenConnector method, to allow drivers
+// access to context and to avoid repeated parsing of driver
+// configuration.
+type Connector interface {
+	// Connect returns a connection to the database.
+	// Connect may return a cached connection (one previously
+	// closed), but doing so is unnecessary; the sql package
+	// maintains a pool of idle connections for efficient re-use.
+	//
+	// The provided context.Context is for dialing purposes only
+	// (see net.DialContext) and should not be stored or used for
+	// other purposes.
+	//
+	// The returned connection is only used by one goroutine at a
+	// time.
+	Connect(context.Context) (Conn, error)
+
+	// Driver returns the underlying Driver of the Connector,
+	// mainly to maintain compatibility with the Driver method
+	// on sql.DB.
+	Driver() Driver
+}
+
 // ErrSkip may be returned by some optional interfaces' methods to
 // indicate at runtime that the fast path is unavailable and the sql
 // package should continue as if the optional interface was not
@@ -86,22 +132,23 @@
 
 // Execer is an optional interface that may be implemented by a Conn.
 //
-// If a Conn does not implement Execer, the sql package's DB.Exec will
-// first prepare a query, execute the statement, and then close the
-// statement.
+// If a Conn implements neither ExecerContext nor Execer Execer,
+// the sql package's DB.Exec will first prepare a query, execute the statement,
+// and then close the statement.
 //
 // Exec may return ErrSkip.
 //
-// Deprecated: Drivers should implement ExecerContext instead (or additionally).
+// Deprecated: Drivers should implement ExecerContext instead.
 type Execer interface {
 	Exec(query string, args []Value) (Result, error)
 }
 
 // ExecerContext is an optional interface that may be implemented by a Conn.
 //
-// If a Conn does not implement ExecerContext, the sql package's DB.Exec will
-// first prepare a query, execute the statement, and then close the
-// statement.
+// If a Conn does not implement ExecerContext, the sql package's DB.Exec
+// will fall back to Execer; if the Conn does not implement Execer either,
+// DB.Exec will first prepare a query, execute the statement, and then
+// close the statement.
 //
 // ExecerContext may return ErrSkip.
 //
@@ -112,22 +159,23 @@
 
 // Queryer is an optional interface that may be implemented by a Conn.
 //
-// If a Conn does not implement Queryer, the sql package's DB.Query will
-// first prepare a query, execute the statement, and then close the
-// statement.
+// If a Conn implements neither QueryerContext nor Queryer,
+// the sql package's DB.Query will first prepare a query, execute the statement,
+// and then close the statement.
 //
 // Query may return ErrSkip.
 //
-// Deprecated: Drivers should implement QueryerContext instead (or additionally).
+// Deprecated: Drivers should implement QueryerContext instead.
 type Queryer interface {
 	Query(query string, args []Value) (Rows, error)
 }
 
 // QueryerContext is an optional interface that may be implemented by a Conn.
 //
-// If a Conn does not implement QueryerContext, the sql package's DB.Query will
-// first prepare a query, execute the statement, and then close the
-// statement.
+// If a Conn does not implement QueryerContext, the sql package's DB.Query
+// will fall back to Queryer; if the Conn does not implement Queryer either,
+// DB.Query will first prepare a query, execute the statement, and then
+// close the statement.
 //
 // QueryerContext may return ErrSkip.
 //
@@ -199,6 +247,18 @@
 	BeginTx(ctx context.Context, opts TxOptions) (Tx, error)
 }
 
+// SessionResetter may be implemented by Conn to allow drivers to reset the
+// session state associated with the connection and to signal a bad connection.
+type SessionResetter interface {
+	// ResetSession is called while a connection is in the connection
+	// pool. No queries will run on this connection until this method returns.
+	//
+	// If the connection is bad this should return driver.ErrBadConn to prevent
+	// the connection from being returned to the connection pool. Any other
+	// error will be discarded.
+	ResetSession(ctx context.Context) error
+}
+
 // Result is the result of a query execution.
 type Result interface {
 	// LastInsertId returns the database's auto-generated ID
@@ -319,6 +379,10 @@
 	// size as the Columns() are wide.
 	//
 	// Next should return io.EOF when there are no more rows.
+	//
+	// The dest should not be written to outside of Next. Care
+	// should be taken when closing Rows not to modify
+	// a buffer held in dest.
 	Next(dest []Value) error
 }
 
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
index 4dcd096..abb8d40 100644
--- a/src/database/sql/fakedb_test.go
+++ b/src/database/sql/fakedb_test.go
@@ -55,6 +55,32 @@
 	dbs        map[string]*fakeDB
 }
 
+type fakeConnector struct {
+	name string
+
+	waiter func(context.Context)
+}
+
+func (c *fakeConnector) Connect(context.Context) (driver.Conn, error) {
+	conn, err := fdriver.Open(c.name)
+	conn.(*fakeConn).waiter = c.waiter
+	return conn, err
+}
+
+func (c *fakeConnector) Driver() driver.Driver {
+	return fdriver
+}
+
+type fakeDriverCtx struct {
+	fakeDriver
+}
+
+var _ driver.DriverContext = &fakeDriverCtx{}
+
+func (cc *fakeDriverCtx) OpenConnector(name string) (driver.Connector, error) {
+	return &fakeConnector{name: name}, nil
+}
+
 type fakeDB struct {
 	name string
 
@@ -107,6 +133,16 @@
 	// bad connection tests; see isBad()
 	bad       bool
 	stickyBad bool
+
+	skipDirtySession bool // tests that use Conn should set this to true.
+
+	// dirtySession tests ResetSession, true if a query has executed
+	// until ResetSession is called.
+	dirtySession bool
+
+	// The waiter is called before each query. May be used in place of the "WAIT"
+	// directive.
+	waiter func(context.Context)
 }
 
 func (c *fakeConn) touchMem() {
@@ -298,6 +334,9 @@
 	if c.stickyBad {
 		return true
 	} else if c.bad {
+		if c.db == nil {
+			return false
+		}
 		// alternate between bad conn and not bad conn
 		c.db.badConn = !c.db.badConn
 		return c.db.badConn
@@ -306,6 +345,21 @@
 	}
 }
 
+func (c *fakeConn) isDirtyAndMark() bool {
+	if c.skipDirtySession {
+		return false
+	}
+	if c.currTx != nil {
+		c.dirtySession = true
+		return false
+	}
+	if c.dirtySession {
+		return true
+	}
+	c.dirtySession = true
+	return false
+}
+
 func (c *fakeConn) Begin() (driver.Tx, error) {
 	if c.isBad() {
 		return nil, driver.ErrBadConn
@@ -337,6 +391,14 @@
 	testStrictClose = t
 }
 
+func (c *fakeConn) ResetSession(ctx context.Context) error {
+	c.dirtySession = false
+	if c.isBad() {
+		return driver.ErrBadConn
+	}
+	return nil
+}
+
 func (c *fakeConn) Close() (err error) {
 	drv := fdriver.(*fakeDriver)
 	defer func() {
@@ -572,6 +634,10 @@
 		stmt.cmd = cmd
 		parts = parts[1:]
 
+		if c.waiter != nil {
+			c.waiter(ctx)
+		}
+
 		if stmt.wait > 0 {
 			wait := time.NewTimer(stmt.wait)
 			select {
@@ -662,6 +728,9 @@
 	if s.c.stickyBad || (hookExecBadConn != nil && hookExecBadConn()) {
 		return nil, driver.ErrBadConn
 	}
+	if s.c.isDirtyAndMark() {
+		return nil, errors.New("session is dirty")
+	}
 
 	err := checkSubsetTypes(s.c.db.allowAny, args)
 	if err != nil {
@@ -774,6 +843,9 @@
 	if s.c.stickyBad || (hookQueryBadConn != nil && hookQueryBadConn()) {
 		return nil, driver.ErrBadConn
 	}
+	if s.c.isDirtyAndMark() {
+		return nil, errors.New("session is dirty")
+	}
 
 	err := checkSubsetTypes(s.c.db.allowAny, args)
 	if err != nil {
@@ -943,15 +1015,11 @@
 }
 
 func (rc *rowsCursor) touchMem() {
+	rc.parentMem.touchMem()
 	rc.line++
 }
 
 func (rc *rowsCursor) Close() error {
-	if !rc.closed {
-		for _, bs := range rc.bytesClone {
-			bs[0] = 255 // first byte corrupted
-		}
-	}
 	rc.touchMem()
 	rc.parentMem.touchMem()
 	rc.closed = true
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index c609fe4..8f5588e 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -285,7 +285,7 @@
 // Example usage:
 //
 //   var outArg string
-//   _, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", Out{Dest: &outArg}))
+//   _, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", sql.Out{Dest: &outArg}))
 type Out struct {
 	_Named_Fields_Required struct{}
 
@@ -317,8 +317,7 @@
 // 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
+	connector driver.Connector
 	// numClosed is an atomic counter which represents a total number of
 	// closed connections. Stmt.openStmt checks it before cleaning closed
 	// connections in Stmt.css.
@@ -335,6 +334,7 @@
 	// It is closed during db.Close(). The close tells the connectionOpener
 	// goroutine to exit.
 	openerCh    chan struct{}
+	resetterCh  chan *driverConn
 	closed      bool
 	dep         map[finalCloser]depSet
 	lastPut     map[*driverConn]string // stacktrace of last conn's put; debug only
@@ -342,6 +342,8 @@
 	maxOpen     int                    // <= 0 means unlimited
 	maxLifetime time.Duration          // maximum amount of time a connection may be reused
 	cleanerCh   chan struct{}
+
+	stop func() // stop cancels the connection opener and the session resetter.
 }
 
 // connReuseStrategy determines how (*DB).conn returns database connections.
@@ -369,6 +371,7 @@
 	closed      bool
 	finalClosed bool // ci.Close has been called
 	openStmt    map[*driverStmt]bool
+	lastErr     error // lastError captures the result of the session resetter.
 
 	// guarded by db.mu
 	inUse      bool
@@ -377,7 +380,7 @@
 }
 
 func (dc *driverConn) releaseConn(err error) {
-	dc.db.putConn(dc, err)
+	dc.db.putConn(dc, err, true)
 }
 
 func (dc *driverConn) removeOpenStmt(ds *driverStmt) {
@@ -418,6 +421,19 @@
 	return ds, nil
 }
 
+// resetSession resets the connection session and sets the lastErr
+// that is checked before returning the connection to another query.
+//
+// resetSession assumes that the embedded mutex is locked when the connection
+// was returned to the pool. This unlocks the mutex.
+func (dc *driverConn) resetSession(ctx context.Context) {
+	defer dc.Unlock() // In case of panic.
+	if dc.closed {    // Check if the database has been closed.
+		return
+	}
+	dc.lastErr = dc.ci.(driver.SessionResetter).ResetSession(ctx)
+}
+
 // the dc.db's Mutex is held.
 func (dc *driverConn) closeDBLocked() func() error {
 	dc.Lock()
@@ -575,6 +591,52 @@
 // to block until the connectionOpener can satisfy the backlog of requests.
 var connectionRequestQueueSize = 1000000
 
+type dsnConnector struct {
+	dsn    string
+	driver driver.Driver
+}
+
+func (t dsnConnector) Connect(_ context.Context) (driver.Conn, error) {
+	return t.driver.Open(t.dsn)
+}
+
+func (t dsnConnector) Driver() driver.Driver {
+	return t.driver
+}
+
+// OpenDB opens a database using a Connector, allowing drivers to
+// bypass a string based data source name.
+//
+// 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 https://golang.org/s/sqldrivers for
+// a list of third-party drivers.
+//
+// OpenDB 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 OpenDB
+// function should be called just once. It is rarely necessary to
+// close a DB.
+func OpenDB(c driver.Connector) *DB {
+	ctx, cancel := context.WithCancel(context.Background())
+	db := &DB{
+		connector:    c,
+		openerCh:     make(chan struct{}, connectionRequestQueueSize),
+		resetterCh:   make(chan *driverConn, 50),
+		lastPut:      make(map[*driverConn]string),
+		connRequests: make(map[uint64]chan connRequest),
+		stop:         cancel,
+	}
+
+	go db.connectionOpener(ctx)
+	go db.connectionResetter(ctx)
+
+	return db
+}
+
 // 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.
@@ -599,15 +661,16 @@
 	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),
-		connRequests: make(map[uint64]chan connRequest),
+
+	if driverCtx, ok := driveri.(driver.DriverContext); ok {
+		connector, err := driverCtx.OpenConnector(dataSourceName)
+		if err != nil {
+			return nil, err
+		}
+		return OpenDB(connector), nil
 	}
-	go db.connectionOpener()
-	return db, nil
+
+	return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
 }
 
 func (db *DB) pingDC(ctx context.Context, dc *driverConn, release func(error)) error {
@@ -659,7 +722,6 @@
 		db.mu.Unlock()
 		return nil
 	}
-	close(db.openerCh)
 	if db.cleanerCh != nil {
 		close(db.cleanerCh)
 	}
@@ -680,6 +742,7 @@
 			err = err1
 		}
 	}
+	db.stop()
 	return err
 }
 
@@ -867,18 +930,40 @@
 }
 
 // Runs in a separate goroutine, opens new connections when requested.
-func (db *DB) connectionOpener() {
-	for range db.openerCh {
-		db.openNewConnection()
+func (db *DB) connectionOpener(ctx context.Context) {
+	for {
+		select {
+		case <-ctx.Done():
+			return
+		case <-db.openerCh:
+			db.openNewConnection(ctx)
+		}
+	}
+}
+
+// connectionResetter runs in a separate goroutine to reset connections async
+// to exported API.
+func (db *DB) connectionResetter(ctx context.Context) {
+	for {
+		select {
+		case <-ctx.Done():
+			close(db.resetterCh)
+			for dc := range db.resetterCh {
+				dc.Unlock()
+			}
+			return
+		case dc := <-db.resetterCh:
+			dc.resetSession(ctx)
+		}
 	}
 }
 
 // Open one new connection
-func (db *DB) openNewConnection() {
+func (db *DB) openNewConnection(ctx context.Context) {
 	// maybeOpenNewConnctions has already executed db.numOpen++ before it sent
 	// on db.openerCh. This function must execute db.numOpen-- if the
 	// connection fails or is closed before returning.
-	ci, err := db.driver.Open(db.dsn)
+	ci, err := db.connector.Connect(ctx)
 	db.mu.Lock()
 	defer db.mu.Unlock()
 	if db.closed {
@@ -953,6 +1038,14 @@
 			conn.Close()
 			return nil, driver.ErrBadConn
 		}
+		// Lock around reading lastErr to ensure the session resetter finished.
+		conn.Lock()
+		err := conn.lastErr
+		conn.Unlock()
+		if err == driver.ErrBadConn {
+			conn.Close()
+			return nil, driver.ErrBadConn
+		}
 		return conn, nil
 	}
 
@@ -978,7 +1071,7 @@
 			default:
 			case ret, ok := <-req:
 				if ok {
-					db.putConn(ret.conn, ret.err)
+					db.putConn(ret.conn, ret.err, false)
 				}
 			}
 			return nil, ctx.Err()
@@ -990,13 +1083,24 @@
 				ret.conn.Close()
 				return nil, driver.ErrBadConn
 			}
+			if ret.conn == nil {
+				return nil, ret.err
+			}
+			// Lock around reading lastErr to ensure the session resetter finished.
+			ret.conn.Lock()
+			err := ret.conn.lastErr
+			ret.conn.Unlock()
+			if err == driver.ErrBadConn {
+				ret.conn.Close()
+				return nil, driver.ErrBadConn
+			}
 			return ret.conn, ret.err
 		}
 	}
 
 	db.numOpen++ // optimistically
 	db.mu.Unlock()
-	ci, err := db.driver.Open(db.dsn)
+	ci, err := db.connector.Connect(ctx)
 	if err != nil {
 		db.mu.Lock()
 		db.numOpen-- // correct for earlier optimism
@@ -1045,7 +1149,7 @@
 
 // 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) {
+func (db *DB) putConn(dc *driverConn, err error, resetSession bool) {
 	db.mu.Lock()
 	if !dc.inUse {
 		if debugGetPut {
@@ -1076,11 +1180,40 @@
 	if putConnHook != nil {
 		putConnHook(db, dc)
 	}
+	if db.closed {
+		// Connections do not need to be reset if they will be closed.
+		// Prevents writing to resetterCh after the DB has closed.
+		resetSession = false
+	}
+	if resetSession {
+		if _, resetSession = dc.ci.(driver.SessionResetter); resetSession {
+			// Lock the driverConn here so it isn't released until
+			// the connection is reset.
+			// The lock must be taken before the connection is put into
+			// the pool to prevent it from being taken out before it is reset.
+			dc.Lock()
+		}
+	}
 	added := db.putConnDBLocked(dc, nil)
 	db.mu.Unlock()
 
 	if !added {
+		if resetSession {
+			dc.Unlock()
+		}
 		dc.Close()
+		return
+	}
+	if !resetSession {
+		return
+	}
+	select {
+	default:
+		// If the resetterCh is blocking then mark the connection
+		// as bad and continue on.
+		dc.lastErr = driver.ErrBadConn
+		dc.Unlock()
+	case db.resetterCh <- dc:
 	}
 }
 
@@ -1242,15 +1375,20 @@
 	defer func() {
 		release(err)
 	}()
-	if execer, ok := dc.ci.(driver.Execer); ok {
-		var dargs []driver.NamedValue
-		dargs, err = driverArgs(dc.ci, nil, args)
-		if err != nil {
-			return nil, err
-		}
+	execerCtx, ok := dc.ci.(driver.ExecerContext)
+	var execer driver.Execer
+	if !ok {
+		execer, ok = dc.ci.(driver.Execer)
+	}
+	if ok {
+		var nvdargs []driver.NamedValue
 		var resi driver.Result
 		withLock(dc, func() {
-			resi, err = ctxDriverExec(ctx, execer, query, dargs)
+			nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
+			if err != nil {
+				return
+			}
+			resi, err = ctxDriverExec(ctx, execerCtx, execer, query, nvdargs)
 		})
 		if err != driver.ErrSkip {
 			if err != nil {
@@ -1309,15 +1447,21 @@
 // The ctx context is from a query method and the txctx context is from an
 // optional transaction context.
 func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []interface{}) (*Rows, error) {
-	if queryer, ok := dc.ci.(driver.Queryer); ok {
-		dargs, err := driverArgs(dc.ci, nil, args)
-		if err != nil {
-			releaseConn(err)
-			return nil, err
-		}
+	queryerCtx, ok := dc.ci.(driver.QueryerContext)
+	var queryer driver.Queryer
+	if !ok {
+		queryer, ok = dc.ci.(driver.Queryer)
+	}
+	if ok {
+		var nvdargs []driver.NamedValue
 		var rowsi driver.Rows
+		var err error
 		withLock(dc, func() {
-			rowsi, err = ctxDriverQuery(ctx, queryer, query, dargs)
+			nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
+			if err != nil {
+				return
+			}
+			rowsi, err = ctxDriverQuery(ctx, queryerCtx, queryer, query, nvdargs)
 		})
 		if err != driver.ErrSkip {
 			if err != nil {
@@ -1454,11 +1598,11 @@
 
 // Driver returns the database's underlying driver.
 func (db *DB) Driver() driver.Driver {
-	return db.driver
+	return db.connector.Driver()
 }
 
 // ErrConnDone is returned by any operation that is performed on a connection
-// that has already been committed or rolled back.
+// that has already been returned to the connection pool.
 var ErrConnDone = errors.New("database/sql: connection is already closed")
 
 // Conn returns a single connection by either opening a new connection
@@ -1493,9 +1637,9 @@
 
 type releaseConn func(error)
 
-// Conn represents a single database session rather a pool of database
-// sessions. Prefer running queries from DB unless there is a specific
-// need for a continuous single database session.
+// Conn represents a single database connection rather than a pool of database
+// connections. Prefer running queries from DB unless there is a specific
+// need for a continuous single database connection.
 //
 // A Conn must call Close to return the connection to the database pool
 // and may do so concurrently with a running query.
@@ -1769,14 +1913,20 @@
 
 // Commit commits the transaction.
 func (tx *Tx) Commit() error {
-	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
-		return ErrTxDone
-	}
+	// Check context first to avoid transaction leak.
+	// If put it behind tx.done CompareAndSwap statement, we cant't ensure
+	// the consistency between tx.done and the real COMMIT operation.
 	select {
 	default:
 	case <-tx.ctx.Done():
+		if atomic.LoadInt32(&tx.done) == 1 {
+			return ErrTxDone
+		}
 		return tx.ctx.Err()
 	}
+	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
+		return ErrTxDone
+	}
 	var err error
 	withLock(tx.dc, func() {
 		err = tx.txi.Commit()
@@ -1859,6 +2009,9 @@
 //  ...
 //  res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203)
 //
+// The provided context is used for the preparation of the statement, not for the
+// execution of the statement.
+//
 // The returned statement operates within the transaction and will be closed
 // when the transaction has been committed or rolled back.
 func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
@@ -1902,11 +2055,14 @@
 		stmt.mu.Unlock()
 
 		if si == nil {
-			cs, err := stmt.prepareOnConnLocked(ctx, dc)
+			var ds *driverStmt
+			withLock(dc, func() {
+				ds, err = stmt.prepareOnConnLocked(ctx, dc)
+			})
 			if err != nil {
 				return &Stmt{stickyErr: err}
 			}
-			si = cs.si
+			si = ds.si
 		}
 		parentStmt = stmt
 	}
@@ -2098,13 +2254,20 @@
 }
 
 func resultFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...interface{}) (Result, error) {
-	dargs, err := driverArgs(ci, ds, args)
+	ds.Lock()
+	defer ds.Unlock()
+
+	dargs, err := driverArgsConnLocked(ci, ds, args)
 	if err != nil {
 		return nil, err
 	}
 
-	ds.Lock()
-	defer 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 := ds.si.NumInput(); want >= 0 && want != len(dargs) {
+		return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs))
+	}
 
 	resi, err := ctxDriverStmtExec(ctx, ds.si, dargs)
 	if err != nil {
@@ -2269,25 +2432,20 @@
 }
 
 func rowsiFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...interface{}) (driver.Rows, error) {
-	var want int
-	withLock(ds, func() {
-		want = ds.si.NumInput()
-	})
+	ds.Lock()
+	defer 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(ci, ds, args)
+	dargs, err := driverArgsConnLocked(ci, ds, args)
 	if err != nil {
 		return nil, err
 	}
 
-	ds.Lock()
-	defer 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 := ds.si.NumInput(); want >= 0 && want != len(dargs) {
+		return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs))
+	}
 
 	rowsi, err := ctxDriverStmtQuery(ctx, ds.si, dargs)
 	if err != nil {
@@ -2451,9 +2609,16 @@
 	if rs.closed {
 		return false, false
 	}
+
+	// Lock the driver connection before calling the driver interface
+	// rowsi to prevent a Tx from rolling back the connection at the same time.
+	rs.dc.Lock()
+	defer rs.dc.Unlock()
+
 	if rs.lastcols == nil {
 		rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
 	}
+
 	rs.lasterr = rs.rowsi.Next(rs.lastcols)
 	if rs.lasterr != nil {
 		// Close the connection if there is a driver error.
@@ -2503,6 +2668,12 @@
 		doClose = true
 		return false
 	}
+
+	// Lock the driver connection before calling the driver interface
+	// rowsi to prevent a Tx from rolling back the connection at the same time.
+	rs.dc.Lock()
+	defer rs.dc.Unlock()
+
 	rs.lasterr = nextResultSet.NextResultSet()
 	if rs.lasterr != nil {
 		doClose = true
@@ -2534,6 +2705,9 @@
 	if rs.rowsi == nil {
 		return nil, errors.New("sql: no Rows available")
 	}
+	rs.dc.Lock()
+	defer rs.dc.Unlock()
+
 	return rs.rowsi.Columns(), nil
 }
 
@@ -2548,7 +2722,10 @@
 	if rs.rowsi == nil {
 		return nil, errors.New("sql: no Rows available")
 	}
-	return rowsColumnInfoSetup(rs.rowsi), nil
+	rs.dc.Lock()
+	defer rs.dc.Unlock()
+
+	return rowsColumnInfoSetupConnLocked(rs.rowsi), nil
 }
 
 // ColumnType contains the name and type of a column.
@@ -2609,7 +2786,7 @@
 	return ci.databaseType
 }
 
-func rowsColumnInfoSetup(rowsi driver.Rows) []*ColumnType {
+func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType {
 	names := rowsi.Columns()
 
 	list := make([]*ColumnType, len(names))
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index c935eb4..ae6bf71 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -60,10 +60,12 @@
 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)
-	}
+	return newTestDBConnector(t, &fakeConnector{name: fakeDBName}, name)
+}
+
+func newTestDBConnector(t testing.TB, fc *fakeConnector, name string) *DB {
+	fc.name = fakeDBName
+	db := OpenDB(fc)
 	if _, err := db.Exec("WIPE"); err != nil {
 		t.Fatalf("exec wipe: %v", err)
 	}
@@ -81,6 +83,13 @@
 	return db
 }
 
+func TestOpenDB(t *testing.T) {
+	db := OpenDB(dsnConnector{dsn: fakeDBName, driver: fdriver})
+	if db.Driver() != fdriver {
+		t.Fatalf("OpenDB should return the driver of the Connector")
+	}
+}
+
 func TestDriverPanic(t *testing.T) {
 	// Test that if driver panics, database/sql does not deadlock.
 	db, err := Open("test", fakeDBName)
@@ -439,6 +448,20 @@
 	waitForFree(t, db, 5*time.Second, 0)
 }
 
+// TestUnsupportedOptions checks that the database fails when a driver that
+// doesn't implement ConnBeginTx is used with non-default options and an
+// un-cancellable context.
+func TestUnsupportedOptions(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	_, err := db.BeginTx(context.Background(), &TxOptions{
+		Isolation: LevelSerializable, ReadOnly: true,
+	})
+	if err == nil {
+		t.Fatal("expected error when using unsupported options, got nil")
+	}
+}
+
 func TestMultiResultSetQuery(t *testing.T) {
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
@@ -564,24 +587,46 @@
 	if testing.Short() {
 		t.Skip("long test")
 	}
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
 
 	max := 3
+	var saturate, saturateDone sync.WaitGroup
+	saturate.Add(max)
+	saturateDone.Add(max)
+
+	donePing := make(chan bool)
+	state := 0
+
+	// waiter will be called for all queries, including
+	// initial setup queries. The state is only assigned when no
+	// no queries are made.
+	//
+	// Only allow the first batch of queries to finish once the
+	// second batch of Ping queries have finished.
+	waiter := func(ctx context.Context) {
+		switch state {
+		case 0:
+			// Nothing. Initial database setup.
+		case 1:
+			saturate.Done()
+			select {
+			case <-ctx.Done():
+			case <-donePing:
+			}
+		case 2:
+		}
+	}
+	db := newTestDBConnector(t, &fakeConnector{waiter: waiter}, "people")
+	defer closeDB(t, db)
 
 	db.SetMaxOpenConns(max)
 
 	// First saturate the connection pool.
 	// Then start new requests for a connection that is cancelled after it is requested.
 
-	var saturate, saturateDone sync.WaitGroup
-	saturate.Add(max)
-	saturateDone.Add(max)
-
+	state = 1
 	for i := 0; i < max; i++ {
 		go func() {
-			saturate.Done()
-			rows, err := db.Query("WAIT|500ms|SELECT|people|name,photo|")
+			rows, err := db.Query("SELECT|people|name,photo|")
 			if err != nil {
 				t.Fatalf("Query: %v", err)
 			}
@@ -591,6 +636,7 @@
 	}
 
 	saturate.Wait()
+	state = 2
 
 	// Now cancel the request while it is waiting.
 	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
@@ -607,7 +653,7 @@
 			t.Fatalf("PingContext (Exhaust): %v", err)
 		}
 	}
-
+	close(donePing)
 	saturateDone.Wait()
 
 	// Now try to open a normal connection.
@@ -617,43 +663,6 @@
 	}
 }
 
-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)
@@ -705,15 +714,15 @@
 		if err != nil {
 			t.Fatalf("failed to scan values in %v", err)
 		}
-		ct++
-		if ct == 0 {
-			if values[0].(string) != "Bob" {
-				t.Errorf("Expected Bob, got %v", values[0])
+		if ct == 1 {
+			if age := *values[0].(*int32); age != 2 {
+				t.Errorf("Expected 2, got %v", age)
 			}
-			if values[1].(int) != 2 {
-				t.Errorf("Expected 2, got %v", values[1])
+			if name := *values[1].(*string); name != "Bob" {
+				t.Errorf("Expected Bob, got %v", name)
 			}
 		}
+		ct++
 	}
 	if ct != 3 {
 		t.Errorf("expected 3 rows, got %d", ct)
@@ -1311,6 +1320,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	conn.dc.ci.(*fakeConn).skipDirtySession = true
 	defer conn.Close()
 
 	var name string
@@ -1338,6 +1348,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	conn.dc.ci.(*fakeConn).skipDirtySession = true
 	defer conn.Close()
 
 	tx, err := conn.BeginTx(ctx, nil)
@@ -1658,7 +1669,7 @@
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
 
-	driver := db.driver.(*fakeDriver)
+	driver := db.Driver().(*fakeDriver)
 	opens0 := driver.openCount
 
 	var stmt *Stmt
@@ -1751,7 +1762,7 @@
 	db := newTestDB(t, "magicquery")
 	defer closeDB(t, db)
 
-	driver := db.driver.(*fakeDriver)
+	driver := db.Driver().(*fakeDriver)
 
 	// Force the number of open connections to 0 so we can get an accurate
 	// count for the test
@@ -2043,7 +2054,7 @@
 	db := newTestDB(t, "magicquery")
 	defer closeDB(t, db)
 
-	driver := db.driver.(*fakeDriver)
+	driver := db.Driver().(*fakeDriver)
 
 	// Force the number of open connections to 0 so we can get an accurate
 	// count for the test
@@ -2132,7 +2143,7 @@
 	db := newTestDB(t, "magicquery")
 	defer closeDB(t, db)
 
-	driver := db.driver.(*fakeDriver)
+	driver := db.Driver().(*fakeDriver)
 
 	driver.mu.Lock()
 	opens0 := driver.openCount
@@ -2363,7 +2374,9 @@
 			t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
 		}
 		for _, conn := range db.freeConn {
+			conn.Lock()
 			conn.ci.(*fakeConn).stickyBad = true
+			conn.Unlock()
 		}
 		return db
 	}
@@ -2453,6 +2466,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	conn.dc.ci.(*fakeConn).skipDirtySession = true
 	err = conn.Close()
 	if err != nil {
 		t.Fatal(err)
@@ -3057,7 +3071,7 @@
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
 
-	drv := db.driver.(*fakeDriver)
+	drv := db.Driver().(*fakeDriver)
 	drv.mu.Lock()
 	opens0 := drv.openCount
 	closes0 := drv.closeCount
@@ -3106,6 +3120,9 @@
 // In the test, a context is canceled while the query is in process so
 // the internal rollback will run concurrently with the explicitly called
 // Tx.Rollback.
+//
+// The addition of calling rows.Next also tests
+// Issue 21117.
 func TestIssue18429(t *testing.T) {
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
@@ -3138,6 +3155,12 @@
 			// reported.
 			rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
 			if rows != nil {
+				var name string
+				// Call Next to test Issue 21117 and check for races.
+				for rows.Next() {
+					// Scan the buffer so it is read and checked for races.
+					rows.Scan(&name)
+				}
 				rows.Close()
 			}
 			// This call will race with the context cancel rollback to complete
@@ -3217,9 +3240,8 @@
 
 	// This call will grab the connection and cancel the context
 	// after it has done so. Code after must deal with the canceled state.
-	rows, err := tx.QueryContext(ctx, "SELECT|people|name|")
+	_, err = tx.QueryContext(ctx, "SELECT|people|name|")
 	if err != nil {
-		rows.Close()
 		t.Fatalf("expected error %v but got %v", nil, err)
 	}
 
@@ -3242,6 +3264,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	conn.dc.ci.(*fakeConn).skipDirtySession = true
 	defer conn.Close()
 
 	stmt, err := conn.PrepareContext(ctx, "SELECT|people|name|")
@@ -3312,7 +3335,7 @@
 	// 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 := db.Driver().(*fakeDriver)
 	drv.waitCh = make(chan struct{}, 1)
 	drv.waitingCh = make(chan struct{}, 1)
 	var wg sync.WaitGroup
@@ -3376,7 +3399,7 @@
 	case Out:
 		switch ov := v.Dest.(type) {
 		default:
-			return errors.New("unkown NameValueCheck OUTPUT type")
+			return errors.New("unknown NameValueCheck OUTPUT type")
 		case *string:
 			*ov = "from-server"
 			nv.Value = "OUT:*string"
@@ -3466,6 +3489,141 @@
 	}
 }
 
+func TestOpenConnector(t *testing.T) {
+	Register("testctx", &fakeDriverCtx{})
+	db, err := Open("testctx", "people")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer db.Close()
+
+	if _, is := db.connector.(*fakeConnector); !is {
+		t.Fatal("not using *fakeConnector")
+	}
+}
+
+type ctxOnlyDriver struct {
+	fakeDriver
+}
+
+func (d *ctxOnlyDriver) Open(dsn string) (driver.Conn, error) {
+	conn, err := d.fakeDriver.Open(dsn)
+	if err != nil {
+		return nil, err
+	}
+	return &ctxOnlyConn{fc: conn.(*fakeConn)}, nil
+}
+
+var (
+	_ driver.Conn           = &ctxOnlyConn{}
+	_ driver.QueryerContext = &ctxOnlyConn{}
+	_ driver.ExecerContext  = &ctxOnlyConn{}
+)
+
+type ctxOnlyConn struct {
+	fc *fakeConn
+
+	queryCtxCalled bool
+	execCtxCalled  bool
+}
+
+func (c *ctxOnlyConn) Begin() (driver.Tx, error) {
+	return c.fc.Begin()
+}
+
+func (c *ctxOnlyConn) Close() error {
+	return c.fc.Close()
+}
+
+// Prepare is still part of the Conn interface, so while it isn't used
+// must be defined for compatibility.
+func (c *ctxOnlyConn) Prepare(q string) (driver.Stmt, error) {
+	panic("not used")
+}
+
+func (c *ctxOnlyConn) PrepareContext(ctx context.Context, q string) (driver.Stmt, error) {
+	return c.fc.PrepareContext(ctx, q)
+}
+
+func (c *ctxOnlyConn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Rows, error) {
+	c.queryCtxCalled = true
+	return c.fc.QueryContext(ctx, q, args)
+}
+
+func (c *ctxOnlyConn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Result, error) {
+	c.execCtxCalled = true
+	return c.fc.ExecContext(ctx, q, args)
+}
+
+// TestQueryExecContextOnly ensures drivers only need to implement QueryContext
+// and ExecContext methods.
+func TestQueryExecContextOnly(t *testing.T) {
+	// Ensure connection does not implment non-context interfaces.
+	var connType driver.Conn = &ctxOnlyConn{}
+	if _, ok := connType.(driver.Execer); ok {
+		t.Fatalf("%T must not implement driver.Execer", connType)
+	}
+	if _, ok := connType.(driver.Queryer); ok {
+		t.Fatalf("%T must not implement driver.Queryer", connType)
+	}
+
+	Register("ContextOnly", &ctxOnlyDriver{})
+	db, err := Open("ContextOnly", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer db.Close()
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	conn, err := db.Conn(ctx)
+	if err != nil {
+		t.Fatal("db.Conn", err)
+	}
+	defer conn.Close()
+	coc := conn.dc.ci.(*ctxOnlyConn)
+	coc.fc.skipDirtySession = true
+
+	_, err = conn.ExecContext(ctx, "WIPE")
+	if err != nil {
+		t.Fatal("exec wipe", err)
+	}
+
+	_, err = conn.ExecContext(ctx, "CREATE|keys|v1=string")
+	if err != nil {
+		t.Fatal("exec create", err)
+	}
+	expectedValue := "value1"
+	_, err = conn.ExecContext(ctx, "INSERT|keys|v1=?", expectedValue)
+	if err != nil {
+		t.Fatal("exec insert", err)
+	}
+	rows, err := conn.QueryContext(ctx, "SELECT|keys|v1|")
+	if err != nil {
+		t.Fatal("query select", err)
+	}
+	v1 := ""
+	for rows.Next() {
+		err = rows.Scan(&v1)
+		if err != nil {
+			t.Fatal("rows scan", err)
+		}
+	}
+	rows.Close()
+
+	if v1 != expectedValue {
+		t.Fatalf("expected %q, got %q", expectedValue, v1)
+	}
+
+	if !coc.execCtxCalled {
+		t.Error("ExecContext not called")
+	}
+	if !coc.queryCtxCalled {
+		t.Error("QueryContext not called")
+	}
+}
+
 // badConn implements a bad driver.Conn, for TestBadDriver.
 // The Exec method panics.
 type badConn struct{}
diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go
index 80bf14c..ffa61c2 100644
--- a/src/debug/dwarf/entry.go
+++ b/src/debug/dwarf/entry.go
@@ -33,13 +33,13 @@
 
 // ParseAbbrev returns the abbreviation table that starts at byte off
 // in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32, vers int) (abbrevTable, error) {
+func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
 	if m, ok := d.abbrevCache[off]; ok {
 		return m, nil
 	}
 
 	data := d.abbrev
-	if off > uint32(len(data)) {
+	if off > uint64(len(data)) {
 		data = nil
 	} else {
 		data = data[off:]
diff --git a/src/debug/dwarf/entry_test.go b/src/debug/dwarf/entry_test.go
index 58a5d57..58f3023 100644
--- a/src/debug/dwarf/entry_test.go
+++ b/src/debug/dwarf/entry_test.go
@@ -135,3 +135,63 @@
 		t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
 	}
 }
+
+func Test64Bit(t *testing.T) {
+	// I don't know how to generate a 64-bit DWARF debug
+	// compilation unit except by using XCOFF, so this is
+	// hand-written.
+	tests := []struct {
+		name string
+		info []byte
+	}{
+		{
+			"32-bit little",
+			[]byte{0x30, 0, 0, 0, // comp unit length
+				4, 0, // DWARF version 4
+				0, 0, 0, 0, // abbrev offset
+				8, // address size
+				0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+			},
+		},
+		{
+			"64-bit little",
+			[]byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+				0x30, 0, 0, 0, 0, 0, 0, 0, // comp unit length
+				4, 0, // DWARF version 4
+				0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+				8, // address size
+				0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+			},
+		},
+		{
+			"64-bit big",
+			[]byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+				0, 0, 0, 0, 0, 0, 0, 0x30, // comp unit length
+				0, 4, // DWARF version 4
+				0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+				8, // address size
+				0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0,
+			},
+		},
+	}
+
+	for _, test := range tests {
+		_, err := New(nil, nil, nil, test.info, nil, nil, nil, nil)
+		if err != nil {
+			t.Errorf("%s: %v", test.name, err)
+		}
+	}
+}
diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go
index 0e9c01c..57344d8 100644
--- a/src/debug/dwarf/open.go
+++ b/src/debug/dwarf/open.go
@@ -23,7 +23,7 @@
 	str      []byte
 
 	// parsed data
-	abbrevCache map[uint32]abbrevTable
+	abbrevCache map[uint64]abbrevTable
 	order       binary.ByteOrder
 	typeCache   map[Offset]Type
 	typeSigs    map[uint64]*typeUnit
@@ -48,17 +48,26 @@
 		pubnames:    pubnames,
 		ranges:      ranges,
 		str:         str,
-		abbrevCache: make(map[uint32]abbrevTable),
+		abbrevCache: make(map[uint64]abbrevTable),
 		typeCache:   make(map[Offset]Type),
 		typeSigs:    make(map[uint64]*typeUnit),
 	}
 
 	// Sniff .debug_info to figure out byte order.
-	// bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3).
+	// 32-bit DWARF: 4 byte length, 2 byte version.
+	// 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version.
 	if len(d.info) < 6 {
 		return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
 	}
-	x, y := d.info[4], d.info[5]
+	offset := 4
+	if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff {
+		if len(d.info) < 14 {
+			return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
+		}
+		offset = 12
+	}
+	// Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5).
+	x, y := d.info[offset], d.info[offset+1]
 	switch {
 	case x == 0 && y == 0:
 		return nil, DecodeError{"info", 4, "unsupported version 0"}
diff --git a/src/debug/dwarf/type.go b/src/debug/dwarf/type.go
index 9b39078..4352092 100644
--- a/src/debug/dwarf/type.go
+++ b/src/debug/dwarf/type.go
@@ -154,7 +154,7 @@
 	Name       string
 	Type       Type
 	ByteOffset int64
-	ByteSize   int64
+	ByteSize   int64 // usually zero; use Type.Size() for normal fields
 	BitOffset  int64 // within the ByteSize bytes at ByteOffset
 	BitSize    int64 // zero if not a bit field
 }
@@ -514,48 +514,49 @@
 		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 {
+			if kid.Tag != TagMember {
+				continue
+			}
+			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
 				}
-				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
+				f.ByteOffset = int64(b.uint())
+				if b.err != nil {
+					err = b.err
+					goto Error
 				}
-
-				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
+			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)
diff --git a/src/debug/dwarf/typeunit.go b/src/debug/dwarf/typeunit.go
index 652e02d..76b357c 100644
--- a/src/debug/dwarf/typeunit.go
+++ b/src/debug/dwarf/typeunit.go
@@ -38,16 +38,11 @@
 			b.error("unsupported DWARF version " + strconv.Itoa(vers))
 			return b.err
 		}
-		var ao uint32
+		var ao uint64
 		if !dwarf64 {
-			ao = b.uint32()
+			ao = uint64(b.uint32())
 		} else {
-			ao64 := b.uint64()
-			if ao64 != uint64(uint32(ao64)) {
-				b.error("type unit abbrev offset overflow")
-				return b.err
-			}
-			ao = uint32(ao64)
+			ao = b.uint64()
 		}
 		atable, err := d.parseAbbrev(ao, vers)
 		if err != nil {
diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go
index e45aed7..98024ca 100644
--- a/src/debug/dwarf/unit.go
+++ b/src/debug/dwarf/unit.go
@@ -61,13 +61,20 @@
 		u.base = b.off
 		var n Offset
 		n, u.is64 = b.unitLength()
+		dataOff := b.off
 		vers := b.uint16()
 		if vers != 2 && vers != 3 && vers != 4 {
 			b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
 			break
 		}
 		u.vers = int(vers)
-		atable, err := d.parseAbbrev(b.uint32(), u.vers)
+		var abbrevOff uint64
+		if u.is64 {
+			abbrevOff = b.uint64()
+		} else {
+			abbrevOff = uint64(b.uint32())
+		}
+		atable, err := d.parseAbbrev(abbrevOff, u.vers)
 		if err != nil {
 			if b.err == nil {
 				b.err = err
@@ -77,7 +84,7 @@
 		u.atable = atable
 		u.asize = int(b.uint8())
 		u.off = b.off
-		u.data = b.bytes(int(n - (2 + 4 + 1)))
+		u.data = b.bytes(int(n - (b.off - dataOff)))
 	}
 	if b.err != nil {
 		return nil, b.err
diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go
index 6e6c801..c8a4fe6 100644
--- a/src/debug/elf/elf.go
+++ b/src/debug/elf/elf.go
@@ -744,30 +744,49 @@
 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 */
+	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 */
+	R_X86_64_PC64            R_X86_64 = 24 /* PC relative 64-bit sign extended symbol value. */
+	R_X86_64_GOTOFF64        R_X86_64 = 25
+	R_X86_64_GOTPC32         R_X86_64 = 26
+	R_X86_64_GOT64           R_X86_64 = 27
+	R_X86_64_GOTPCREL64      R_X86_64 = 28
+	R_X86_64_GOTPC64         R_X86_64 = 29
+	R_X86_64_GOTPLT64        R_X86_64 = 30
+	R_X86_64_PLTOFF64        R_X86_64 = 31
+	R_X86_64_SIZE32          R_X86_64 = 32
+	R_X86_64_SIZE64          R_X86_64 = 33
+	R_X86_64_GOTPC32_TLSDESC R_X86_64 = 34
+	R_X86_64_TLSDESC_CALL    R_X86_64 = 35
+	R_X86_64_TLSDESC         R_X86_64 = 36
+	R_X86_64_IRELATIVE       R_X86_64 = 37
+	R_X86_64_RELATIVE64      R_X86_64 = 38
+	R_X86_64_PC32_BND        R_X86_64 = 39
+	R_X86_64_PLT32_BND       R_X86_64 = 40
+	R_X86_64_GOTPCRELX       R_X86_64 = 41
+	R_X86_64_REX_GOTPCRELX   R_X86_64 = 42
 )
 
 var rx86_64Strings = []intName{
@@ -795,6 +814,25 @@
 	{21, "R_X86_64_DTPOFF32"},
 	{22, "R_X86_64_GOTTPOFF"},
 	{23, "R_X86_64_TPOFF32"},
+	{24, "R_X86_64_PC64"},
+	{25, "R_X86_64_GOTOFF64"},
+	{26, "R_X86_64_GOTPC32"},
+	{27, "R_X86_64_GOT64"},
+	{28, "R_X86_64_GOTPCREL64"},
+	{29, "R_X86_64_GOTPC64"},
+	{30, "R_X86_64_GOTPLT64"},
+	{31, "R_X86_64_PLTOFF64"},
+	{32, "R_X86_64_SIZE32"},
+	{33, "R_X86_64_SIZE64"},
+	{34, "R_X86_64_GOTPC32_TLSDESC"},
+	{35, "R_X86_64_TLSDESC_CALL"},
+	{36, "R_X86_64_TLSDESC"},
+	{37, "R_X86_64_IRELATIVE"},
+	{38, "R_X86_64_RELATIVE64"},
+	{39, "R_X86_64_PC32_BND"},
+	{40, "R_X86_64_PLT32_BND"},
+	{41, "R_X86_64_GOTPCRELX"},
+	{42, "R_X86_64_REX_GOTPCRELX"},
 }
 
 func (i R_X86_64) String() string   { return stringName(uint32(i), rx86_64Strings, false) }
@@ -887,10 +925,17 @@
 	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_LD64_GOTOFF_LO15                R_AARCH64 = 310
 	R_AARCH64_ADR_GOT_PAGE                    R_AARCH64 = 311
 	R_AARCH64_LD64_GOT_LO12_NC                R_AARCH64 = 312
+	R_AARCH64_LD64_GOTPAGE_LO15               R_AARCH64 = 313
+	R_AARCH64_TLSGD_ADR_PREL21                R_AARCH64 = 512
 	R_AARCH64_TLSGD_ADR_PAGE21                R_AARCH64 = 513
 	R_AARCH64_TLSGD_ADD_LO12_NC               R_AARCH64 = 514
+	R_AARCH64_TLSGD_MOVW_G1                   R_AARCH64 = 515
+	R_AARCH64_TLSGD_MOVW_G0_NC                R_AARCH64 = 516
+	R_AARCH64_TLSLD_ADR_PREL21                R_AARCH64 = 517
+	R_AARCH64_TLSLD_ADR_PAGE21                R_AARCH64 = 518
 	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
@@ -914,6 +959,10 @@
 	R_AARCH64_TLSDESC_LDR                     R_AARCH64 = 567
 	R_AARCH64_TLSDESC_ADD                     R_AARCH64 = 568
 	R_AARCH64_TLSDESC_CALL                    R_AARCH64 = 569
+	R_AARCH64_TLSLE_LDST128_TPREL_LO12        R_AARCH64 = 570
+	R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC     R_AARCH64 = 571
+	R_AARCH64_TLSLD_LDST128_DTPREL_LO12       R_AARCH64 = 572
+	R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC    R_AARCH64 = 573
 	R_AARCH64_COPY                            R_AARCH64 = 1024
 	R_AARCH64_GLOB_DAT                        R_AARCH64 = 1025
 	R_AARCH64_JUMP_SLOT                       R_AARCH64 = 1026
@@ -1009,10 +1058,17 @@
 	{286, "R_AARCH64_LDST64_ABS_LO12_NC"},
 	{299, "R_AARCH64_LDST128_ABS_LO12_NC"},
 	{309, "R_AARCH64_GOT_LD_PREL19"},
+	{310, "R_AARCH64_LD64_GOTOFF_LO15"},
 	{311, "R_AARCH64_ADR_GOT_PAGE"},
 	{312, "R_AARCH64_LD64_GOT_LO12_NC"},
+	{313, "R_AARCH64_LD64_GOTPAGE_LO15"},
+	{512, "R_AARCH64_TLSGD_ADR_PREL21"},
 	{513, "R_AARCH64_TLSGD_ADR_PAGE21"},
 	{514, "R_AARCH64_TLSGD_ADD_LO12_NC"},
+	{515, "R_AARCH64_TLSGD_MOVW_G1"},
+	{516, "R_AARCH64_TLSGD_MOVW_G0_NC"},
+	{517, "R_AARCH64_TLSLD_ADR_PREL21"},
+	{518, "R_AARCH64_TLSLD_ADR_PAGE21"},
 	{539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"},
 	{540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"},
 	{541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"},
@@ -1036,6 +1092,10 @@
 	{567, "R_AARCH64_TLSDESC_LDR"},
 	{568, "R_AARCH64_TLSDESC_ADD"},
 	{569, "R_AARCH64_TLSDESC_CALL"},
+	{570, "R_AARCH64_TLSLE_LDST128_TPREL_LO12"},
+	{571, "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC"},
+	{572, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12"},
+	{573, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC"},
 	{1024, "R_AARCH64_COPY"},
 	{1025, "R_AARCH64_GLOB_DAT"},
 	{1026, "R_AARCH64_JUMP_SLOT"},
@@ -1122,39 +1182,150 @@
 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
+	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_TLS_DTPMOD32       R_ARM = 17
+	R_ARM_TLS_DTPOFF32       R_ARM = 18
+	R_ARM_TLS_TPOFF32        R_ARM = 19
+	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_CALL               R_ARM = 28
+	R_ARM_JUMP24             R_ARM = 29
+	R_ARM_THM_JUMP24         R_ARM = 30
+	R_ARM_BASE_ABS           R_ARM = 31
+	R_ARM_ALU_PCREL_7_0      R_ARM = 32
+	R_ARM_ALU_PCREL_15_8     R_ARM = 33
+	R_ARM_ALU_PCREL_23_15    R_ARM = 34
+	R_ARM_LDR_SBREL_11_10_NC R_ARM = 35
+	R_ARM_ALU_SBREL_19_12_NC R_ARM = 36
+	R_ARM_ALU_SBREL_27_20_CK R_ARM = 37
+	R_ARM_TARGET1            R_ARM = 38
+	R_ARM_SBREL31            R_ARM = 39
+	R_ARM_V4BX               R_ARM = 40
+	R_ARM_TARGET2            R_ARM = 41
+	R_ARM_PREL31             R_ARM = 42
+	R_ARM_MOVW_ABS_NC        R_ARM = 43
+	R_ARM_MOVT_ABS           R_ARM = 44
+	R_ARM_MOVW_PREL_NC       R_ARM = 45
+	R_ARM_MOVT_PREL          R_ARM = 46
+	R_ARM_THM_MOVW_ABS_NC    R_ARM = 47
+	R_ARM_THM_MOVT_ABS       R_ARM = 48
+	R_ARM_THM_MOVW_PREL_NC   R_ARM = 49
+	R_ARM_THM_MOVT_PREL      R_ARM = 50
+	R_ARM_THM_JUMP19         R_ARM = 51
+	R_ARM_THM_JUMP6          R_ARM = 52
+	R_ARM_THM_ALU_PREL_11_0  R_ARM = 53
+	R_ARM_THM_PC12           R_ARM = 54
+	R_ARM_ABS32_NOI          R_ARM = 55
+	R_ARM_REL32_NOI          R_ARM = 56
+	R_ARM_ALU_PC_G0_NC       R_ARM = 57
+	R_ARM_ALU_PC_G0          R_ARM = 58
+	R_ARM_ALU_PC_G1_NC       R_ARM = 59
+	R_ARM_ALU_PC_G1          R_ARM = 60
+	R_ARM_ALU_PC_G2          R_ARM = 61
+	R_ARM_LDR_PC_G1          R_ARM = 62
+	R_ARM_LDR_PC_G2          R_ARM = 63
+	R_ARM_LDRS_PC_G0         R_ARM = 64
+	R_ARM_LDRS_PC_G1         R_ARM = 65
+	R_ARM_LDRS_PC_G2         R_ARM = 66
+	R_ARM_LDC_PC_G0          R_ARM = 67
+	R_ARM_LDC_PC_G1          R_ARM = 68
+	R_ARM_LDC_PC_G2          R_ARM = 69
+	R_ARM_ALU_SB_G0_NC       R_ARM = 70
+	R_ARM_ALU_SB_G0          R_ARM = 71
+	R_ARM_ALU_SB_G1_NC       R_ARM = 72
+	R_ARM_ALU_SB_G1          R_ARM = 73
+	R_ARM_ALU_SB_G2          R_ARM = 74
+	R_ARM_LDR_SB_G0          R_ARM = 75
+	R_ARM_LDR_SB_G1          R_ARM = 76
+	R_ARM_LDR_SB_G2          R_ARM = 77
+	R_ARM_LDRS_SB_G0         R_ARM = 78
+	R_ARM_LDRS_SB_G1         R_ARM = 79
+	R_ARM_LDRS_SB_G2         R_ARM = 80
+	R_ARM_LDC_SB_G0          R_ARM = 81
+	R_ARM_LDC_SB_G1          R_ARM = 82
+	R_ARM_LDC_SB_G2          R_ARM = 83
+	R_ARM_MOVW_BREL_NC       R_ARM = 84
+	R_ARM_MOVT_BREL          R_ARM = 85
+	R_ARM_MOVW_BREL          R_ARM = 86
+	R_ARM_THM_MOVW_BREL_NC   R_ARM = 87
+	R_ARM_THM_MOVT_BREL      R_ARM = 88
+	R_ARM_THM_MOVW_BREL      R_ARM = 89
+	R_ARM_TLS_GOTDESC        R_ARM = 90
+	R_ARM_TLS_CALL           R_ARM = 91
+	R_ARM_TLS_DESCSEQ        R_ARM = 92
+	R_ARM_THM_TLS_CALL       R_ARM = 93
+	R_ARM_PLT32_ABS          R_ARM = 94
+	R_ARM_GOT_ABS            R_ARM = 95
+	R_ARM_GOT_PREL           R_ARM = 96
+	R_ARM_GOT_BREL12         R_ARM = 97
+	R_ARM_GOTOFF12           R_ARM = 98
+	R_ARM_GOTRELAX           R_ARM = 99
+	R_ARM_GNU_VTENTRY        R_ARM = 100
+	R_ARM_GNU_VTINHERIT      R_ARM = 101
+	R_ARM_THM_JUMP11         R_ARM = 102
+	R_ARM_THM_JUMP8          R_ARM = 103
+	R_ARM_TLS_GD32           R_ARM = 104
+	R_ARM_TLS_LDM32          R_ARM = 105
+	R_ARM_TLS_LDO32          R_ARM = 106
+	R_ARM_TLS_IE32           R_ARM = 107
+	R_ARM_TLS_LE32           R_ARM = 108
+	R_ARM_TLS_LDO12          R_ARM = 109
+	R_ARM_TLS_LE12           R_ARM = 110
+	R_ARM_TLS_IE12GP         R_ARM = 111
+	R_ARM_PRIVATE_0          R_ARM = 112
+	R_ARM_PRIVATE_1          R_ARM = 113
+	R_ARM_PRIVATE_2          R_ARM = 114
+	R_ARM_PRIVATE_3          R_ARM = 115
+	R_ARM_PRIVATE_4          R_ARM = 116
+	R_ARM_PRIVATE_5          R_ARM = 117
+	R_ARM_PRIVATE_6          R_ARM = 118
+	R_ARM_PRIVATE_7          R_ARM = 119
+	R_ARM_PRIVATE_8          R_ARM = 120
+	R_ARM_PRIVATE_9          R_ARM = 121
+	R_ARM_PRIVATE_10         R_ARM = 122
+	R_ARM_PRIVATE_11         R_ARM = 123
+	R_ARM_PRIVATE_12         R_ARM = 124
+	R_ARM_PRIVATE_13         R_ARM = 125
+	R_ARM_PRIVATE_14         R_ARM = 126
+	R_ARM_PRIVATE_15         R_ARM = 127
+	R_ARM_ME_TOO             R_ARM = 128
+	R_ARM_THM_TLS_DESCSEQ16  R_ARM = 129
+	R_ARM_THM_TLS_DESCSEQ32  R_ARM = 130
+	R_ARM_THM_GOT_BREL12     R_ARM = 131
+	R_ARM_THM_ALU_ABS_G0_NC  R_ARM = 132
+	R_ARM_THM_ALU_ABS_G1_NC  R_ARM = 133
+	R_ARM_THM_ALU_ABS_G2_NC  R_ARM = 134
+	R_ARM_THM_ALU_ABS_G3     R_ARM = 135
+	R_ARM_IRELATIVE          R_ARM = 160
+	R_ARM_RXPC25             R_ARM = 249
+	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{
@@ -1175,6 +1346,9 @@
 	{14, "R_ARM_THM_SWI8"},
 	{15, "R_ARM_XPC25"},
 	{16, "R_ARM_THM_XPC22"},
+	{17, "R_ARM_TLS_DTPMOD32"},
+	{18, "R_ARM_TLS_DTPOFF32"},
+	{19, "R_ARM_TLS_TPOFF32"},
 	{20, "R_ARM_COPY"},
 	{21, "R_ARM_GLOB_DAT"},
 	{22, "R_ARM_JUMP_SLOT"},
@@ -1183,8 +1357,116 @@
 	{25, "R_ARM_GOTPC"},
 	{26, "R_ARM_GOT32"},
 	{27, "R_ARM_PLT32"},
+	{28, "R_ARM_CALL"},
+	{29, "R_ARM_JUMP24"},
+	{30, "R_ARM_THM_JUMP24"},
+	{31, "R_ARM_BASE_ABS"},
+	{32, "R_ARM_ALU_PCREL_7_0"},
+	{33, "R_ARM_ALU_PCREL_15_8"},
+	{34, "R_ARM_ALU_PCREL_23_15"},
+	{35, "R_ARM_LDR_SBREL_11_10_NC"},
+	{36, "R_ARM_ALU_SBREL_19_12_NC"},
+	{37, "R_ARM_ALU_SBREL_27_20_CK"},
+	{38, "R_ARM_TARGET1"},
+	{39, "R_ARM_SBREL31"},
+	{40, "R_ARM_V4BX"},
+	{41, "R_ARM_TARGET2"},
+	{42, "R_ARM_PREL31"},
+	{43, "R_ARM_MOVW_ABS_NC"},
+	{44, "R_ARM_MOVT_ABS"},
+	{45, "R_ARM_MOVW_PREL_NC"},
+	{46, "R_ARM_MOVT_PREL"},
+	{47, "R_ARM_THM_MOVW_ABS_NC"},
+	{48, "R_ARM_THM_MOVT_ABS"},
+	{49, "R_ARM_THM_MOVW_PREL_NC"},
+	{50, "R_ARM_THM_MOVT_PREL"},
+	{51, "R_ARM_THM_JUMP19"},
+	{52, "R_ARM_THM_JUMP6"},
+	{53, "R_ARM_THM_ALU_PREL_11_0"},
+	{54, "R_ARM_THM_PC12"},
+	{55, "R_ARM_ABS32_NOI"},
+	{56, "R_ARM_REL32_NOI"},
+	{57, "R_ARM_ALU_PC_G0_NC"},
+	{58, "R_ARM_ALU_PC_G0"},
+	{59, "R_ARM_ALU_PC_G1_NC"},
+	{60, "R_ARM_ALU_PC_G1"},
+	{61, "R_ARM_ALU_PC_G2"},
+	{62, "R_ARM_LDR_PC_G1"},
+	{63, "R_ARM_LDR_PC_G2"},
+	{64, "R_ARM_LDRS_PC_G0"},
+	{65, "R_ARM_LDRS_PC_G1"},
+	{66, "R_ARM_LDRS_PC_G2"},
+	{67, "R_ARM_LDC_PC_G0"},
+	{68, "R_ARM_LDC_PC_G1"},
+	{69, "R_ARM_LDC_PC_G2"},
+	{70, "R_ARM_ALU_SB_G0_NC"},
+	{71, "R_ARM_ALU_SB_G0"},
+	{72, "R_ARM_ALU_SB_G1_NC"},
+	{73, "R_ARM_ALU_SB_G1"},
+	{74, "R_ARM_ALU_SB_G2"},
+	{75, "R_ARM_LDR_SB_G0"},
+	{76, "R_ARM_LDR_SB_G1"},
+	{77, "R_ARM_LDR_SB_G2"},
+	{78, "R_ARM_LDRS_SB_G0"},
+	{79, "R_ARM_LDRS_SB_G1"},
+	{80, "R_ARM_LDRS_SB_G2"},
+	{81, "R_ARM_LDC_SB_G0"},
+	{82, "R_ARM_LDC_SB_G1"},
+	{83, "R_ARM_LDC_SB_G2"},
+	{84, "R_ARM_MOVW_BREL_NC"},
+	{85, "R_ARM_MOVT_BREL"},
+	{86, "R_ARM_MOVW_BREL"},
+	{87, "R_ARM_THM_MOVW_BREL_NC"},
+	{88, "R_ARM_THM_MOVT_BREL"},
+	{89, "R_ARM_THM_MOVW_BREL"},
+	{90, "R_ARM_TLS_GOTDESC"},
+	{91, "R_ARM_TLS_CALL"},
+	{92, "R_ARM_TLS_DESCSEQ"},
+	{93, "R_ARM_THM_TLS_CALL"},
+	{94, "R_ARM_PLT32_ABS"},
+	{95, "R_ARM_GOT_ABS"},
+	{96, "R_ARM_GOT_PREL"},
+	{97, "R_ARM_GOT_BREL12"},
+	{98, "R_ARM_GOTOFF12"},
+	{99, "R_ARM_GOTRELAX"},
 	{100, "R_ARM_GNU_VTENTRY"},
 	{101, "R_ARM_GNU_VTINHERIT"},
+	{102, "R_ARM_THM_JUMP11"},
+	{103, "R_ARM_THM_JUMP8"},
+	{104, "R_ARM_TLS_GD32"},
+	{105, "R_ARM_TLS_LDM32"},
+	{106, "R_ARM_TLS_LDO32"},
+	{107, "R_ARM_TLS_IE32"},
+	{108, "R_ARM_TLS_LE32"},
+	{109, "R_ARM_TLS_LDO12"},
+	{110, "R_ARM_TLS_LE12"},
+	{111, "R_ARM_TLS_IE12GP"},
+	{112, "R_ARM_PRIVATE_0"},
+	{113, "R_ARM_PRIVATE_1"},
+	{114, "R_ARM_PRIVATE_2"},
+	{115, "R_ARM_PRIVATE_3"},
+	{116, "R_ARM_PRIVATE_4"},
+	{117, "R_ARM_PRIVATE_5"},
+	{118, "R_ARM_PRIVATE_6"},
+	{119, "R_ARM_PRIVATE_7"},
+	{120, "R_ARM_PRIVATE_8"},
+	{121, "R_ARM_PRIVATE_9"},
+	{122, "R_ARM_PRIVATE_10"},
+	{123, "R_ARM_PRIVATE_11"},
+	{124, "R_ARM_PRIVATE_12"},
+	{125, "R_ARM_PRIVATE_13"},
+	{126, "R_ARM_PRIVATE_14"},
+	{127, "R_ARM_PRIVATE_15"},
+	{128, "R_ARM_ME_TOO"},
+	{129, "R_ARM_THM_TLS_DESCSEQ16"},
+	{130, "R_ARM_THM_TLS_DESCSEQ32"},
+	{131, "R_ARM_THM_GOT_BREL12"},
+	{132, "R_ARM_THM_ALU_ABS_G0_NC"},
+	{133, "R_ARM_THM_ALU_ABS_G1_NC"},
+	{134, "R_ARM_THM_ALU_ABS_G2_NC"},
+	{135, "R_ARM_THM_ALU_ABS_G3"},
+	{160, "R_ARM_IRELATIVE"},
+	{249, "R_ARM_RXPC25"},
 	{250, "R_ARM_RSBREL32"},
 	{251, "R_ARM_THM_RPC22"},
 	{252, "R_ARM_RREL32"},
@@ -1200,37 +1482,48 @@
 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 */
+	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_32PLT         R_386 = 11
+	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_16            R_386 = 20
+	R_386_PC16          R_386 = 21
+	R_386_8             R_386 = 22
+	R_386_PC8           R_386 = 23
+	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 */
+	R_386_SIZE32        R_386 = 38
+	R_386_TLS_GOTDESC   R_386 = 39
+	R_386_TLS_DESC_CALL R_386 = 40
+	R_386_TLS_DESC      R_386 = 41
+	R_386_IRELATIVE     R_386 = 42
+	R_386_GOT32X        R_386 = 43
 )
 
 var r386Strings = []intName{
@@ -1245,12 +1538,17 @@
 	{8, "R_386_RELATIVE"},
 	{9, "R_386_GOTOFF"},
 	{10, "R_386_GOTPC"},
+	{11, "R_386_32PLT"},
 	{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"},
+	{20, "R_386_16"},
+	{21, "R_386_PC16"},
+	{22, "R_386_8"},
+	{23, "R_386_PC8"},
 	{24, "R_386_TLS_GD_32"},
 	{25, "R_386_TLS_GD_PUSH"},
 	{26, "R_386_TLS_GD_CALL"},
@@ -1265,6 +1563,12 @@
 	{35, "R_386_TLS_DTPMOD32"},
 	{36, "R_386_TLS_DTPOFF32"},
 	{37, "R_386_TLS_TPOFF32"},
+	{38, "R_386_SIZE32"},
+	{39, "R_386_TLS_GOTDESC"},
+	{40, "R_386_TLS_DESC_CALL"},
+	{41, "R_386_TLS_DESC"},
+	{42, "R_386_IRELATIVE"},
+	{43, "R_386_GOT32X"},
 }
 
 func (i R_386) String() string   { return stringName(uint32(i), r386Strings, false) }
@@ -1380,70 +1684,75 @@
 func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) }
 
 // Relocation types for PowerPC.
+//
+// Values that are shared by both R_PPC and R_PPC64 are prefixed with
+// R_POWERPC_ in the ELF standard. For the R_PPC type, the relevant
+// shared relocations have been renamed with the prefix R_PPC_.
+// The original name follows the value in a comment.
 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_NONE            R_PPC = 0  // R_POWERPC_NONE
+	R_PPC_ADDR32          R_PPC = 1  // R_POWERPC_ADDR32
+	R_PPC_ADDR24          R_PPC = 2  // R_POWERPC_ADDR24
+	R_PPC_ADDR16          R_PPC = 3  // R_POWERPC_ADDR16
+	R_PPC_ADDR16_LO       R_PPC = 4  // R_POWERPC_ADDR16_LO
+	R_PPC_ADDR16_HI       R_PPC = 5  // R_POWERPC_ADDR16_HI
+	R_PPC_ADDR16_HA       R_PPC = 6  // R_POWERPC_ADDR16_HA
+	R_PPC_ADDR14          R_PPC = 7  // R_POWERPC_ADDR14
+	R_PPC_ADDR14_BRTAKEN  R_PPC = 8  // R_POWERPC_ADDR14_BRTAKEN
+	R_PPC_ADDR14_BRNTAKEN R_PPC = 9  // R_POWERPC_ADDR14_BRNTAKEN
+	R_PPC_REL24           R_PPC = 10 // R_POWERPC_REL24
+	R_PPC_REL14           R_PPC = 11 // R_POWERPC_REL14
+	R_PPC_REL14_BRTAKEN   R_PPC = 12 // R_POWERPC_REL14_BRTAKEN
+	R_PPC_REL14_BRNTAKEN  R_PPC = 13 // R_POWERPC_REL14_BRNTAKEN
+	R_PPC_GOT16           R_PPC = 14 // R_POWERPC_GOT16
+	R_PPC_GOT16_LO        R_PPC = 15 // R_POWERPC_GOT16_LO
+	R_PPC_GOT16_HI        R_PPC = 16 // R_POWERPC_GOT16_HI
+	R_PPC_GOT16_HA        R_PPC = 17 // R_POWERPC_GOT16_HA
 	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_COPY            R_PPC = 19 // R_POWERPC_COPY
+	R_PPC_GLOB_DAT        R_PPC = 20 // R_POWERPC_GLOB_DAT
+	R_PPC_JMP_SLOT        R_PPC = 21 // R_POWERPC_JMP_SLOT
+	R_PPC_RELATIVE        R_PPC = 22 // R_POWERPC_RELATIVE
 	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_UADDR32         R_PPC = 24 // R_POWERPC_UADDR32
+	R_PPC_UADDR16         R_PPC = 25 // R_POWERPC_UADDR16
+	R_PPC_REL32           R_PPC = 26 // R_POWERPC_REL32
+	R_PPC_PLT32           R_PPC = 27 // R_POWERPC_PLT32
+	R_PPC_PLTREL32        R_PPC = 28 // R_POWERPC_PLTREL32
+	R_PPC_PLT16_LO        R_PPC = 29 // R_POWERPC_PLT16_LO
+	R_PPC_PLT16_HI        R_PPC = 30 // R_POWERPC_PLT16_HI
+	R_PPC_PLT16_HA        R_PPC = 31 // R_POWERPC_PLT16_HA
 	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_SECTOFF         R_PPC = 33 // R_POWERPC_SECTOFF
+	R_PPC_SECTOFF_LO      R_PPC = 34 // R_POWERPC_SECTOFF_LO
+	R_PPC_SECTOFF_HI      R_PPC = 35 // R_POWERPC_SECTOFF_HI
+	R_PPC_SECTOFF_HA      R_PPC = 36 // R_POWERPC_SECTOFF_HA
+	R_PPC_TLS             R_PPC = 67 // R_POWERPC_TLS
+	R_PPC_DTPMOD32        R_PPC = 68 // R_POWERPC_DTPMOD32
+	R_PPC_TPREL16         R_PPC = 69 // R_POWERPC_TPREL16
+	R_PPC_TPREL16_LO      R_PPC = 70 // R_POWERPC_TPREL16_LO
+	R_PPC_TPREL16_HI      R_PPC = 71 // R_POWERPC_TPREL16_HI
+	R_PPC_TPREL16_HA      R_PPC = 72 // R_POWERPC_TPREL16_HA
+	R_PPC_TPREL32         R_PPC = 73 // R_POWERPC_TPREL32
+	R_PPC_DTPREL16        R_PPC = 74 // R_POWERPC_DTPREL16
+	R_PPC_DTPREL16_LO     R_PPC = 75 // R_POWERPC_DTPREL16_LO
+	R_PPC_DTPREL16_HI     R_PPC = 76 // R_POWERPC_DTPREL16_HI
+	R_PPC_DTPREL16_HA     R_PPC = 77 // R_POWERPC_DTPREL16_HA
+	R_PPC_DTPREL32        R_PPC = 78 // R_POWERPC_DTPREL32
+	R_PPC_GOT_TLSGD16     R_PPC = 79 // R_POWERPC_GOT_TLSGD16
+	R_PPC_GOT_TLSGD16_LO  R_PPC = 80 // R_POWERPC_GOT_TLSGD16_LO
+	R_PPC_GOT_TLSGD16_HI  R_PPC = 81 // R_POWERPC_GOT_TLSGD16_HI
+	R_PPC_GOT_TLSGD16_HA  R_PPC = 82 // R_POWERPC_GOT_TLSGD16_HA
+	R_PPC_GOT_TLSLD16     R_PPC = 83 // R_POWERPC_GOT_TLSLD16
+	R_PPC_GOT_TLSLD16_LO  R_PPC = 84 // R_POWERPC_GOT_TLSLD16_LO
+	R_PPC_GOT_TLSLD16_HI  R_PPC = 85 // R_POWERPC_GOT_TLSLD16_HI
+	R_PPC_GOT_TLSLD16_HA  R_PPC = 86 // R_POWERPC_GOT_TLSLD16_HA
+	R_PPC_GOT_TPREL16     R_PPC = 87 // R_POWERPC_GOT_TPREL16
+	R_PPC_GOT_TPREL16_LO  R_PPC = 88 // R_POWERPC_GOT_TPREL16_LO
+	R_PPC_GOT_TPREL16_HI  R_PPC = 89 // R_POWERPC_GOT_TPREL16_HI
+	R_PPC_GOT_TPREL16_HA  R_PPC = 90 // R_POWERPC_GOT_TPREL16_HA
 	R_PPC_EMB_NADDR32     R_PPC = 101
 	R_PPC_EMB_NADDR16     R_PPC = 102
 	R_PPC_EMB_NADDR16_LO  R_PPC = 103
@@ -1500,7 +1809,6 @@
 	{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"},
@@ -1525,7 +1833,6 @@
 	{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"},
@@ -1548,29 +1855,34 @@
 func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
 
 // Relocation types for 64-bit PowerPC or Power Architecture processors.
+//
+// Values that are shared by both R_PPC and R_PPC64 are prefixed with
+// R_POWERPC_ in the ELF standard. For the R_PPC64 type, the relevant
+// shared relocations have been renamed with the prefix R_PPC64_.
+// The original name follows the value in a comment.
 type R_PPC64 int
 
 const (
-	R_PPC64_NONE               R_PPC64 = 0
-	R_PPC64_ADDR32             R_PPC64 = 1
-	R_PPC64_ADDR24             R_PPC64 = 2
-	R_PPC64_ADDR16             R_PPC64 = 3
-	R_PPC64_ADDR16_LO          R_PPC64 = 4
-	R_PPC64_ADDR16_HI          R_PPC64 = 5
-	R_PPC64_ADDR16_HA          R_PPC64 = 6
-	R_PPC64_ADDR14             R_PPC64 = 7
-	R_PPC64_ADDR14_BRTAKEN     R_PPC64 = 8
-	R_PPC64_ADDR14_BRNTAKEN    R_PPC64 = 9
-	R_PPC64_REL24              R_PPC64 = 10
-	R_PPC64_REL14              R_PPC64 = 11
-	R_PPC64_REL14_BRTAKEN      R_PPC64 = 12
-	R_PPC64_REL14_BRNTAKEN     R_PPC64 = 13
-	R_PPC64_GOT16              R_PPC64 = 14
-	R_PPC64_GOT16_LO           R_PPC64 = 15
-	R_PPC64_GOT16_HI           R_PPC64 = 16
-	R_PPC64_GOT16_HA           R_PPC64 = 17
-	R_PPC64_JMP_SLOT           R_PPC64 = 21
-	R_PPC64_REL32              R_PPC64 = 26
+	R_PPC64_NONE               R_PPC64 = 0  // R_POWERPC_NONE
+	R_PPC64_ADDR32             R_PPC64 = 1  // R_POWERPC_ADDR32
+	R_PPC64_ADDR24             R_PPC64 = 2  // R_POWERPC_ADDR24
+	R_PPC64_ADDR16             R_PPC64 = 3  // R_POWERPC_ADDR16
+	R_PPC64_ADDR16_LO          R_PPC64 = 4  // R_POWERPC_ADDR16_LO
+	R_PPC64_ADDR16_HI          R_PPC64 = 5  // R_POWERPC_ADDR16_HI
+	R_PPC64_ADDR16_HA          R_PPC64 = 6  // R_POWERPC_ADDR16_HA
+	R_PPC64_ADDR14             R_PPC64 = 7  // R_POWERPC_ADDR14
+	R_PPC64_ADDR14_BRTAKEN     R_PPC64 = 8  // R_POWERPC_ADDR14_BRTAKEN
+	R_PPC64_ADDR14_BRNTAKEN    R_PPC64 = 9  // R_POWERPC_ADDR14_BRNTAKEN
+	R_PPC64_REL24              R_PPC64 = 10 // R_POWERPC_REL24
+	R_PPC64_REL14              R_PPC64 = 11 // R_POWERPC_REL14
+	R_PPC64_REL14_BRTAKEN      R_PPC64 = 12 // R_POWERPC_REL14_BRTAKEN
+	R_PPC64_REL14_BRNTAKEN     R_PPC64 = 13 // R_POWERPC_REL14_BRNTAKEN
+	R_PPC64_GOT16              R_PPC64 = 14 // R_POWERPC_GOT16
+	R_PPC64_GOT16_LO           R_PPC64 = 15 // R_POWERPC_GOT16_LO
+	R_PPC64_GOT16_HI           R_PPC64 = 16 // R_POWERPC_GOT16_HI
+	R_PPC64_GOT16_HA           R_PPC64 = 17 // R_POWERPC_GOT16_HA
+	R_PPC64_JMP_SLOT           R_PPC64 = 21 // R_POWERPC_JMP_SLOT
+	R_PPC64_REL32              R_PPC64 = 26 // R_POWERPC_REL32
 	R_PPC64_ADDR64             R_PPC64 = 38
 	R_PPC64_ADDR16_HIGHER      R_PPC64 = 39
 	R_PPC64_ADDR16_HIGHERA     R_PPC64 = 40
@@ -1582,40 +1894,49 @@
 	R_PPC64_TOC16_HI           R_PPC64 = 49
 	R_PPC64_TOC16_HA           R_PPC64 = 50
 	R_PPC64_TOC                R_PPC64 = 51
+	R_PPC64_PLTGOT16           R_PPC64 = 52
+	R_PPC64_PLTGOT16_LO        R_PPC64 = 53
+	R_PPC64_PLTGOT16_HI        R_PPC64 = 54
+	R_PPC64_PLTGOT16_HA        R_PPC64 = 55
 	R_PPC64_ADDR16_DS          R_PPC64 = 56
 	R_PPC64_ADDR16_LO_DS       R_PPC64 = 57
 	R_PPC64_GOT16_DS           R_PPC64 = 58
 	R_PPC64_GOT16_LO_DS        R_PPC64 = 59
+	R_PPC64_PLT16_LO_DS        R_PPC64 = 60
+	R_PPC64_SECTOFF_DS         R_PPC64 = 61
+	R_PPC64_SECTOFF_LO_DS      R_PPC64 = 61
 	R_PPC64_TOC16_DS           R_PPC64 = 63
 	R_PPC64_TOC16_LO_DS        R_PPC64 = 64
-	R_PPC64_TLS                R_PPC64 = 67
-	R_PPC64_DTPMOD64           R_PPC64 = 68
-	R_PPC64_TPREL16            R_PPC64 = 69
-	R_PPC64_TPREL16_LO         R_PPC64 = 70
-	R_PPC64_TPREL16_HI         R_PPC64 = 71
-	R_PPC64_TPREL16_HA         R_PPC64 = 72
-	R_PPC64_TPREL64            R_PPC64 = 73
-	R_PPC64_DTPREL16           R_PPC64 = 74
-	R_PPC64_DTPREL16_LO        R_PPC64 = 75
-	R_PPC64_DTPREL16_HI        R_PPC64 = 76
-	R_PPC64_DTPREL16_HA        R_PPC64 = 77
-	R_PPC64_DTPREL64           R_PPC64 = 78
-	R_PPC64_GOT_TLSGD16        R_PPC64 = 79
-	R_PPC64_GOT_TLSGD16_LO     R_PPC64 = 80
-	R_PPC64_GOT_TLSGD16_HI     R_PPC64 = 81
-	R_PPC64_GOT_TLSGD16_HA     R_PPC64 = 82
-	R_PPC64_GOT_TLSLD16        R_PPC64 = 83
-	R_PPC64_GOT_TLSLD16_LO     R_PPC64 = 84
-	R_PPC64_GOT_TLSLD16_HI     R_PPC64 = 85
-	R_PPC64_GOT_TLSLD16_HA     R_PPC64 = 86
-	R_PPC64_GOT_TPREL16_DS     R_PPC64 = 87
-	R_PPC64_GOT_TPREL16_LO_DS  R_PPC64 = 88
-	R_PPC64_GOT_TPREL16_HI     R_PPC64 = 89
-	R_PPC64_GOT_TPREL16_HA     R_PPC64 = 90
-	R_PPC64_GOT_DTPREL16_DS    R_PPC64 = 91
-	R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92
-	R_PPC64_GOT_DTPREL16_HI    R_PPC64 = 93
-	R_PPC64_GOT_DTPREL16_HA    R_PPC64 = 94
+	R_PPC64_PLTGOT16_DS        R_PPC64 = 65
+	R_PPC64_PLTGOT_LO_DS       R_PPC64 = 66
+	R_PPC64_TLS                R_PPC64 = 67 // R_POWERPC_TLS
+	R_PPC64_DTPMOD64           R_PPC64 = 68 // R_POWERPC_DTPMOD64
+	R_PPC64_TPREL16            R_PPC64 = 69 // R_POWERPC_TPREL16
+	R_PPC64_TPREL16_LO         R_PPC64 = 70 // R_POWERPC_TPREL16_LO
+	R_PPC64_TPREL16_HI         R_PPC64 = 71 // R_POWERPC_TPREL16_HI
+	R_PPC64_TPREL16_HA         R_PPC64 = 72 // R_POWERPC_TPREL16_HA
+	R_PPC64_TPREL64            R_PPC64 = 73 // R_POWERPC_TPREL64
+	R_PPC64_DTPREL16           R_PPC64 = 74 // R_POWERPC_DTPREL16
+	R_PPC64_DTPREL16_LO        R_PPC64 = 75 // R_POWERPC_DTPREL16_LO
+	R_PPC64_DTPREL16_HI        R_PPC64 = 76 // R_POWERPC_DTPREL16_HI
+	R_PPC64_DTPREL16_HA        R_PPC64 = 77 // R_POWERPC_DTPREL16_HA
+	R_PPC64_DTPREL64           R_PPC64 = 78 // R_POWERPC_DTPREL64
+	R_PPC64_GOT_TLSGD16        R_PPC64 = 79 // R_POWERPC_GOT_TLSGD16
+	R_PPC64_GOT_TLSGD16_LO     R_PPC64 = 80 // R_POWERPC_GOT_TLSGD16_LO
+	R_PPC64_GOT_TLSGD16_HI     R_PPC64 = 81 // R_POWERPC_GOT_TLSGD16_HI
+	R_PPC64_GOT_TLSGD16_HA     R_PPC64 = 82 // R_POWERPC_GOT_TLSGD16_HA
+	R_PPC64_GOT_TLSLD16        R_PPC64 = 83 // R_POWERPC_GOT_TLSLD16
+	R_PPC64_GOT_TLSLD16_LO     R_PPC64 = 84 // R_POWERPC_GOT_TLSLD16_LO
+	R_PPC64_GOT_TLSLD16_HI     R_PPC64 = 85 // R_POWERPC_GOT_TLSLD16_HI
+	R_PPC64_GOT_TLSLD16_HA     R_PPC64 = 86 // R_POWERPC_GOT_TLSLD16_HA
+	R_PPC64_GOT_TPREL16_DS     R_PPC64 = 87 // R_POWERPC_GOT_TPREL16_DS
+	R_PPC64_GOT_TPREL16_LO_DS  R_PPC64 = 88 // R_POWERPC_GOT_TPREL16_LO_DS
+	R_PPC64_GOT_TPREL16_HI     R_PPC64 = 89 // R_POWERPC_GOT_TPREL16_HI
+	R_PPC64_GOT_TPREL16_HA     R_PPC64 = 90 // R_POWERPC_GOT_TPREL16_HA
+	R_PPC64_GOT_DTPREL16_DS    R_PPC64 = 91 // R_POWERPC_GOT_DTPREL16_DS
+	R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92 // R_POWERPC_GOT_DTPREL16_LO_DS
+	R_PPC64_GOT_DTPREL16_HI    R_PPC64 = 93 // R_POWERPC_GOT_DTPREL16_HI
+	R_PPC64_GOT_DTPREL16_HA    R_PPC64 = 94 // R_POWERPC_GOT_DTPREL16_HA
 	R_PPC64_TPREL16_DS         R_PPC64 = 95
 	R_PPC64_TPREL16_LO_DS      R_PPC64 = 96
 	R_PPC64_TPREL16_HIGHER     R_PPC64 = 97
@@ -1630,10 +1951,23 @@
 	R_PPC64_DTPREL16_HIGHESTA  R_PPC64 = 106
 	R_PPC64_TLSGD              R_PPC64 = 107
 	R_PPC64_TLSLD              R_PPC64 = 108
-	R_PPC64_REL16              R_PPC64 = 249
-	R_PPC64_REL16_LO           R_PPC64 = 250
-	R_PPC64_REL16_HI           R_PPC64 = 251
-	R_PPC64_REL16_HA           R_PPC64 = 252
+	R_PPC64_TOCSAVE            R_PPC64 = 109
+	R_PPC64_ADDR16_HIGH        R_PPC64 = 110
+	R_PPC64_ADDR16_HIGHA       R_PPC64 = 111
+	R_PPC64_TPREL16_HIGH       R_PPC64 = 112
+	R_PPC64_TPREL16_HIGHA      R_PPC64 = 113
+	R_PPC64_DTPREL16_HIGH      R_PPC64 = 114
+	R_PPC64_DTPREL16_HIGHA     R_PPC64 = 115
+	R_PPC64_REL24_NOTOC        R_PPC64 = 116
+	R_PPC64_ADDR64_LOCAL       R_PPC64 = 117
+	R_PPC64_ENTRY              R_PPC64 = 118
+	R_PPC64_REL16DX_HA         R_PPC64 = 246 // R_POWERPC_REL16DX_HA
+	R_PPC64_JMP_IREL           R_PPC64 = 247
+	R_PPC64_IRELATIVE          R_PPC64 = 248 // R_POWERPC_IRELATIVE
+	R_PPC64_REL16              R_PPC64 = 249 // R_POWERPC_REL16
+	R_PPC64_REL16_LO           R_PPC64 = 250 // R_POWERPC_REL16_LO
+	R_PPC64_REL16_HI           R_PPC64 = 251 // R_POWERPC_REL16_HI
+	R_PPC64_REL16_HA           R_PPC64 = 252 // R_POWERPC_REL16_HA
 )
 
 var rppc64Strings = []intName{
@@ -1668,12 +2002,21 @@
 	{49, "R_PPC64_TOC16_HI"},
 	{50, "R_PPC64_TOC16_HA"},
 	{51, "R_PPC64_TOC"},
+	{52, "R_PPC64_PLTGOT16"},
+	{53, "R_PPC64_PLTGOT16_LO"},
+	{54, "R_PPC64_PLTGOT16_HI"},
+	{55, "R_PPC64_PLTGOT16_HA"},
 	{56, "R_PPC64_ADDR16_DS"},
 	{57, "R_PPC64_ADDR16_LO_DS"},
 	{58, "R_PPC64_GOT16_DS"},
 	{59, "R_PPC64_GOT16_LO_DS"},
+	{60, "R_PPC64_PLT16_LO_DS"},
+	{61, "R_PPC64_SECTOFF_DS"},
+	{61, "R_PPC64_SECTOFF_LO_DS"},
 	{63, "R_PPC64_TOC16_DS"},
 	{64, "R_PPC64_TOC16_LO_DS"},
+	{65, "R_PPC64_PLTGOT16_DS"},
+	{66, "R_PPC64_PLTGOT_LO_DS"},
 	{67, "R_PPC64_TLS"},
 	{68, "R_PPC64_DTPMOD64"},
 	{69, "R_PPC64_TPREL16"},
@@ -1716,6 +2059,19 @@
 	{106, "R_PPC64_DTPREL16_HIGHESTA"},
 	{107, "R_PPC64_TLSGD"},
 	{108, "R_PPC64_TLSLD"},
+	{109, "R_PPC64_TOCSAVE"},
+	{110, "R_PPC64_ADDR16_HIGH"},
+	{111, "R_PPC64_ADDR16_HIGHA"},
+	{112, "R_PPC64_TPREL16_HIGH"},
+	{113, "R_PPC64_TPREL16_HIGHA"},
+	{114, "R_PPC64_DTPREL16_HIGH"},
+	{115, "R_PPC64_DTPREL16_HIGHA"},
+	{116, "R_PPC64_REL24_NOTOC"},
+	{117, "R_PPC64_ADDR64_LOCAL"},
+	{118, "R_PPC64_ENTRY"},
+	{246, "R_PPC64_REL16DX_HA"},
+	{247, "R_PPC64_JMP_IREL"},
+	{248, "R_PPC64_IRELATIVE"},
 	{249, "R_PPC64_REL16"},
 	{250, "R_PPC64_REL16_LO"},
 	{251, "R_PPC64_REL16_HI"},
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 8eeab65..95c0606 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -17,6 +17,17 @@
 	"strings"
 )
 
+// seekStart, seekCurrent, seekEnd are copies of
+// io.SeekStart, io.SeekCurrent, and io.SeekEnd.
+// We can't use the ones from package io because
+// we want this code to build with Go 1.4 during
+// cmd/dist bootstrap.
+const (
+	seekStart   int = 0
+	seekCurrent int = 1
+	seekEnd     int = 2
+)
+
 // TODO: error reporting detail
 
 /*
@@ -269,7 +280,7 @@
 	switch f.Class {
 	case ELFCLASS32:
 		hdr := new(Header32)
-		sr.Seek(0, io.SeekStart)
+		sr.Seek(0, seekStart)
 		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
 			return nil, err
 		}
@@ -288,7 +299,7 @@
 		shstrndx = int(hdr.Shstrndx)
 	case ELFCLASS64:
 		hdr := new(Header64)
-		sr.Seek(0, io.SeekStart)
+		sr.Seek(0, seekStart)
 		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
 			return nil, err
 		}
@@ -315,7 +326,7 @@
 	f.Progs = make([]*Prog, phnum)
 	for i := 0; i < phnum; i++ {
 		off := phoff + int64(i)*int64(phentsize)
-		sr.Seek(off, io.SeekStart)
+		sr.Seek(off, seekStart)
 		p := new(Prog)
 		switch f.Class {
 		case ELFCLASS32:
@@ -359,7 +370,7 @@
 	names := make([]uint32, shnum)
 	for i := 0; i < shnum; i++ {
 		off := shoff + int64(i)*int64(shentsize)
-		sr.Seek(off, io.SeekStart)
+		sr.Seek(off, seekStart)
 		s := new(Section)
 		switch f.Class {
 		case ELFCLASS32:
diff --git a/src/debug/elf/reader.go b/src/debug/elf/reader.go
index eab4373..a458436 100644
--- a/src/debug/elf/reader.go
+++ b/src/debug/elf/reader.go
@@ -63,11 +63,11 @@
 func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) {
 	var newOffset int64
 	switch whence {
-	case io.SeekStart:
+	case seekStart:
 		newOffset = offset
-	case io.SeekCurrent:
+	case seekCurrent:
 		newOffset = r.offset + offset
-	case io.SeekEnd:
+	case seekEnd:
 		newOffset = r.size + offset
 	default:
 		return 0, os.ErrInvalid
diff --git a/src/debug/gosym/symtab.go b/src/debug/gosym/symtab.go
index f5f9963..a995209 100644
--- a/src/debug/gosym/symtab.go
+++ b/src/debug/gosym/symtab.go
@@ -79,8 +79,8 @@
 	Entry uint64
 	*Sym
 	End       uint64
-	Params    []*Sym
-	Locals    []*Sym
+	Params    []*Sym // nil for Go 1.3 and later binaries
+	Locals    []*Sym // nil for Go 1.3 and later binaries
 	FrameSize int
 	LineTable *LineTable
 	Obj       *Obj
@@ -116,7 +116,7 @@
 // symbols decoded from the program and provides methods to translate
 // between symbols, names, and addresses.
 type Table struct {
-	Syms  []Sym
+	Syms  []Sym // nil for Go 1.3 and later binaries
 	Funcs []Func
 	Files map[string]*Obj // nil for Go 1.2 and later binaries
 	Objs  []Obj           // nil for Go 1.2 and later binaries
@@ -277,8 +277,9 @@
 	return nil
 }
 
-// NewTable decodes the Go symbol table in data,
+// NewTable decodes the Go symbol table (the ".gosymtab" section in ELF),
 // returning an in-memory representation.
+// Starting with Go 1.3, the Go symbol table no longer includes symbol data.
 func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
 	var n int
 	err := walksymtab(symtab, func(s sym) error {
diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
index 223346f..7b9e83e 100644
--- a/src/debug/macho/file.go
+++ b/src/debug/macho/file.go
@@ -94,8 +94,23 @@
 	Flags  uint32
 }
 
+// A Reloc represents a Mach-O relocation.
+type Reloc struct {
+	Addr  uint32
+	Value uint32
+	// when Scattered == false && Extern == true, Value is the symbol number.
+	// when Scattered == false && Extern == false, Value is the section number.
+	// when Scattered == true, Value is the value that this reloc refers to.
+	Type      uint8
+	Len       uint8 // 0=byte, 1=word, 2=long, 3=quad
+	Pcrel     bool
+	Extern    bool // valid if Scattered == false
+	Scattered bool
+}
+
 type Section struct {
 	SectionHeader
+	Relocs []Reloc
 
 	// Embed ReaderAt for ReadAt method.
 	// Do not embed SectionReader directly
@@ -143,6 +158,21 @@
 	IndirectSyms []uint32 // indices into Symtab.Syms
 }
 
+// A Rpath represents a Mach-O rpath command.
+type Rpath struct {
+	LoadBytes
+	Path string
+}
+
+// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
+type Symbol struct {
+	Name  string
+	Type  uint8
+	Sect  uint8
+	Desc  uint16
+	Value uint64
+}
+
 /*
  * Mach-O reader
  */
@@ -249,6 +279,20 @@
 		default:
 			f.Loads[i] = LoadBytes(cmddat)
 
+		case LoadCmdRpath:
+			var hdr RpathCmd
+			b := bytes.NewReader(cmddat)
+			if err := binary.Read(b, bo, &hdr); err != nil {
+				return nil, err
+			}
+			l := new(Rpath)
+			if hdr.Path >= uint32(len(cmddat)) {
+				return nil, &FormatError{offset, "invalid path in rpath command", hdr.Path}
+			}
+			l.Path = cstring(cmddat[hdr.Path:])
+			l.LoadBytes = LoadBytes(cmddat)
+			f.Loads[i] = l
+
 		case LoadCmdDylib:
 			var hdr DylibCmd
 			b := bytes.NewReader(cmddat)
@@ -349,7 +393,9 @@
 				sh.Reloff = sh32.Reloff
 				sh.Nreloc = sh32.Nreloc
 				sh.Flags = sh32.Flags
-				f.pushSection(sh, r)
+				if err := f.pushSection(sh, r); err != nil {
+					return nil, err
+				}
 			}
 
 		case LoadCmdSegment64:
@@ -387,7 +433,9 @@
 				sh.Reloff = sh64.Reloff
 				sh.Nreloc = sh64.Nreloc
 				sh.Flags = sh64.Flags
-				f.pushSection(sh, r)
+				if err := f.pushSection(sh, r); err != nil {
+					return nil, err
+				}
 			}
 		}
 		if s != nil {
@@ -435,10 +483,65 @@
 	return st, nil
 }
 
-func (f *File) pushSection(sh *Section, r io.ReaderAt) {
+type relocInfo struct {
+	Addr   uint32
+	Symnum uint32
+}
+
+func (f *File) pushSection(sh *Section, r io.ReaderAt) error {
 	f.Sections = append(f.Sections, sh)
 	sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
 	sh.ReaderAt = sh.sr
+
+	if sh.Nreloc > 0 {
+		reldat := make([]byte, int(sh.Nreloc)*8)
+		if _, err := r.ReadAt(reldat, int64(sh.Reloff)); err != nil {
+			return err
+		}
+		b := bytes.NewReader(reldat)
+
+		bo := f.ByteOrder
+
+		sh.Relocs = make([]Reloc, sh.Nreloc)
+		for i := range sh.Relocs {
+			rel := &sh.Relocs[i]
+
+			var ri relocInfo
+			if err := binary.Read(b, bo, &ri); err != nil {
+				return err
+			}
+
+			if ri.Addr&(1<<31) != 0 { // scattered
+				rel.Addr = ri.Addr & (1<<24 - 1)
+				rel.Type = uint8((ri.Addr >> 24) & (1<<4 - 1))
+				rel.Len = uint8((ri.Addr >> 28) & (1<<2 - 1))
+				rel.Pcrel = ri.Addr&(1<<30) != 0
+				rel.Value = ri.Symnum
+				rel.Scattered = true
+			} else {
+				switch bo {
+				case binary.LittleEndian:
+					rel.Addr = ri.Addr
+					rel.Value = ri.Symnum & (1<<24 - 1)
+					rel.Pcrel = ri.Symnum&(1<<24) != 0
+					rel.Len = uint8((ri.Symnum >> 25) & (1<<2 - 1))
+					rel.Extern = ri.Symnum&(1<<27) != 0
+					rel.Type = uint8((ri.Symnum >> 28) & (1<<4 - 1))
+				case binary.BigEndian:
+					rel.Addr = ri.Addr
+					rel.Value = ri.Symnum >> 8
+					rel.Pcrel = ri.Symnum&(1<<7) != 0
+					rel.Len = uint8((ri.Symnum >> 5) & (1<<2 - 1))
+					rel.Extern = ri.Symnum&(1<<4) != 0
+					rel.Type = uint8(ri.Symnum & (1<<4 - 1))
+				default:
+					panic("unreachable")
+				}
+			}
+		}
+	}
+
+	return nil
 }
 
 func cstring(b []byte) string {
diff --git a/src/debug/macho/file_test.go b/src/debug/macho/file_test.go
index 9ff6c5d..003c14e 100644
--- a/src/debug/macho/file_test.go
+++ b/src/debug/macho/file_test.go
@@ -10,29 +10,30 @@
 )
 
 type fileTest struct {
-	file     string
-	hdr      FileHeader
-	segments []*SegmentHeader
-	sections []*SectionHeader
+	file        string
+	hdr         FileHeader
+	loads       []interface{}
+	sections    []*SectionHeader
+	relocations map[string][]Reloc
 }
 
 var fileTests = []fileTest{
 	{
 		"testdata/gcc-386-darwin-exec",
 		FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85},
-		[]*SegmentHeader{
-			{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
-			{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
-			{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
-			{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
+		[]interface{}{
+			&SegmentHeader{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+			&SegmentHeader{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
+			&SegmentHeader{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
+			&SegmentHeader{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
+			&SegmentHeader{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
+			nil, // LC_SYMTAB
+			nil, // LC_DYSYMTAB
+			nil, // LC_LOAD_DYLINKER
+			nil, // LC_UUID
+			nil, // LC_UNIXTHREAD
+			&Dylib{nil, "/usr/lib/libgcc_s.1.dylib", 0x2, 0x10000, 0x10000},
+			&Dylib{nil, "/usr/lib/libSystem.B.dylib", 0x2, 0x6f0104, 0x10000},
 		},
 		[]*SectionHeader{
 			{"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400},
@@ -41,22 +42,23 @@
 			{"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0},
 			{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
 		},
+		nil,
 	},
 	{
 		"testdata/gcc-amd64-darwin-exec",
 		FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85},
-		[]*SegmentHeader{
-			{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
-			{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
-			{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
+		[]interface{}{
+			&SegmentHeader{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+			&SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
+			&SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
+			&SegmentHeader{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
+			nil, // LC_SYMTAB
+			nil, // LC_DYSYMTAB
+			nil, // LC_LOAD_DYLINKER
+			nil, // LC_UUID
+			nil, // LC_UNIXTHREAD
+			&Dylib{nil, "/usr/lib/libgcc_s.1.dylib", 0x2, 0x10000, 0x10000},
+			&Dylib{nil, "/usr/lib/libSystem.B.dylib", 0x2, 0x6f0104, 0x10000},
 		},
 		[]*SectionHeader{
 			{"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400},
@@ -68,15 +70,16 @@
 			{"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0},
 			{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
 		},
+		nil,
 	},
 	{
 		"testdata/gcc-amd64-darwin-exec-debug",
 		FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0},
-		[]*SegmentHeader{
-			nil,
-			{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
-			{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
-			{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
+		[]interface{}{
+			nil, // LC_UUID
+			&SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
+			&SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
+			&SegmentHeader{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
 		},
 		[]*SectionHeader{
 			{"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400},
@@ -95,6 +98,126 @@
 			{"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0},
 			{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
 		},
+		nil,
+	},
+	{
+		"testdata/clang-386-darwin-exec-with-rpath",
+		FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0x10, 0x42c, 0x1200085},
+		[]interface{}{
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_DYLD_INFO_ONLY
+			nil, // LC_SYMTAB
+			nil, // LC_DYSYMTAB
+			nil, // LC_LOAD_DYLINKER
+			nil, // LC_UUID
+			nil, // LC_VERSION_MIN_MACOSX
+			nil, // LC_SOURCE_VERSION
+			nil, // LC_MAIN
+			nil, // LC_LOAD_DYLIB
+			&Rpath{nil, "/my/rpath"},
+			nil, // LC_FUNCTION_STARTS
+			nil, // LC_DATA_IN_CODE
+		},
+		nil,
+		nil,
+	},
+	{
+		"testdata/clang-amd64-darwin-exec-with-rpath",
+		FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0x10, 0x4c8, 0x200085},
+		[]interface{}{
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_SEGMENT
+			nil, // LC_DYLD_INFO_ONLY
+			nil, // LC_SYMTAB
+			nil, // LC_DYSYMTAB
+			nil, // LC_LOAD_DYLINKER
+			nil, // LC_UUID
+			nil, // LC_VERSION_MIN_MACOSX
+			nil, // LC_SOURCE_VERSION
+			nil, // LC_MAIN
+			nil, // LC_LOAD_DYLIB
+			&Rpath{nil, "/my/rpath"},
+			nil, // LC_FUNCTION_STARTS
+			nil, // LC_DATA_IN_CODE
+		},
+		nil,
+		nil,
+	},
+	{
+		"testdata/clang-386-darwin.obj",
+		FileHeader{0xfeedface, Cpu386, 0x3, 0x1, 0x4, 0x138, 0x2000},
+		nil,
+		nil,
+		map[string][]Reloc{
+			"__text": []Reloc{
+				{
+					Addr:      0x1d,
+					Type:      uint8(GENERIC_RELOC_VANILLA),
+					Len:       2,
+					Pcrel:     true,
+					Extern:    true,
+					Value:     1,
+					Scattered: false,
+				},
+				{
+					Addr:      0xe,
+					Type:      uint8(GENERIC_RELOC_LOCAL_SECTDIFF),
+					Len:       2,
+					Pcrel:     false,
+					Value:     0x2d,
+					Scattered: true,
+				},
+				{
+					Addr:      0x0,
+					Type:      uint8(GENERIC_RELOC_PAIR),
+					Len:       2,
+					Pcrel:     false,
+					Value:     0xb,
+					Scattered: true,
+				},
+			},
+		},
+	},
+	{
+		"testdata/clang-amd64-darwin.obj",
+		FileHeader{0xfeedfacf, CpuAmd64, 0x3, 0x1, 0x4, 0x200, 0x2000},
+		nil,
+		nil,
+		map[string][]Reloc{
+			"__text": []Reloc{
+				{
+					Addr:   0x19,
+					Type:   uint8(X86_64_RELOC_BRANCH),
+					Len:    2,
+					Pcrel:  true,
+					Extern: true,
+					Value:  1,
+				},
+				{
+					Addr:   0xb,
+					Type:   uint8(X86_64_RELOC_SIGNED),
+					Len:    2,
+					Pcrel:  true,
+					Extern: false,
+					Value:  2,
+				},
+			},
+			"__compact_unwind": []Reloc{
+				{
+					Addr:   0x0,
+					Type:   uint8(X86_64_RELOC_UNSIGNED),
+					Len:    3,
+					Pcrel:  false,
+					Extern: false,
+					Value:  1,
+				},
+			},
+		},
 	},
 }
 
@@ -112,49 +235,77 @@
 			continue
 		}
 		for i, l := range f.Loads {
-			if i >= len(tt.segments) {
-				break
+			if len(l.Raw()) < 8 {
+				t.Errorf("open %s, command %d:\n\tload command %T don't have enough data\n", tt.file, i, l)
 			}
-			sh := tt.segments[i]
-			s, ok := l.(*Segment)
-			if sh == nil {
-				if ok {
-					t.Errorf("open %s, section %d: skipping %#v\n", tt.file, i, &s.SegmentHeader)
+		}
+		if tt.loads != nil {
+			for i, l := range f.Loads {
+				if i >= len(tt.loads) {
+					break
 				}
-				continue
+
+				want := tt.loads[i]
+				if want == nil {
+					continue
+				}
+
+				switch l := l.(type) {
+				case *Segment:
+					have := &l.SegmentHeader
+					if !reflect.DeepEqual(have, want) {
+						t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+					}
+				case *Dylib:
+					have := l
+					have.LoadBytes = nil
+					if !reflect.DeepEqual(have, want) {
+						t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+					}
+				case *Rpath:
+					have := l
+					have.LoadBytes = nil
+					if !reflect.DeepEqual(have, want) {
+						t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+					}
+				default:
+					t.Errorf("open %s, command %d: unknown load command\n\thave %#v\n\twant %#v\n", tt.file, i, l, want)
+				}
 			}
-			if !ok {
-				t.Errorf("open %s, section %d: not *Segment\n", tt.file, i)
-				continue
+			tn := len(tt.loads)
+			fn := len(f.Loads)
+			if tn != fn {
+				t.Errorf("open %s: len(Loads) = %d, want %d", tt.file, fn, tn)
 			}
-			have := &s.SegmentHeader
-			want := sh
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, segment %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-		tn := len(tt.segments)
-		fn := len(f.Loads)
-		if tn != fn {
-			t.Errorf("open %s: len(Loads) = %d, want %d", tt.file, fn, tn)
 		}
 
-		for i, sh := range f.Sections {
-			if i >= len(tt.sections) {
-				break
+		if tt.sections != nil {
+			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)
+				}
 			}
-			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)
 			}
 		}
-		tn = len(tt.sections)
-		fn = len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
 
+		if tt.relocations != nil {
+			for i, sh := range f.Sections {
+				have := sh.Relocs
+				want := tt.relocations[sh.Name]
+				if !reflect.DeepEqual(have, want) {
+					t.Errorf("open %s, relocations in section %d (%s):\n\thave %#v\n\twant %#v\n", tt.file, i, sh.Name, have, want)
+				}
+			}
+		}
 	}
 }
 
@@ -208,3 +359,21 @@
 		t.Errorf("OpenFat %s: got %v, want nil", filename, ff)
 	}
 }
+
+func TestRelocTypeString(t *testing.T) {
+	if X86_64_RELOC_BRANCH.String() != "X86_64_RELOC_BRANCH" {
+		t.Errorf("got %v, want %v", X86_64_RELOC_BRANCH.String(), "X86_64_RELOC_BRANCH")
+	}
+	if X86_64_RELOC_BRANCH.GoString() != "macho.X86_64_RELOC_BRANCH" {
+		t.Errorf("got %v, want %v", X86_64_RELOC_BRANCH.GoString(), "macho.X86_64_RELOC_BRANCH")
+	}
+}
+
+func TestTypeString(t *testing.T) {
+	if TypeExec.String() != "Exec" {
+		t.Errorf("got %v, want %v", TypeExec.String(), "Exec")
+	}
+	if TypeExec.GoString() != "macho.Exec" {
+		t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec")
+	}
+}
diff --git a/src/debug/macho/macho.go b/src/debug/macho/macho.go
index 40ac74e..fed8eb2 100644
--- a/src/debug/macho/macho.go
+++ b/src/debug/macho/macho.go
@@ -41,6 +41,16 @@
 	TypeBundle Type = 8
 )
 
+var typeStrings = []intName{
+	{uint32(TypeObj), "Obj"},
+	{uint32(TypeExec), "Exec"},
+	{uint32(TypeDylib), "Dylib"},
+	{uint32(TypeBundle), "Bundle"},
+}
+
+func (t Type) String() string   { return stringName(uint32(t), typeStrings, false) }
+func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) }
+
 // A Cpu is a Mach-O cpu type.
 type Cpu uint32
 
@@ -69,14 +79,15 @@
 type LoadCmd uint32
 
 const (
-	LoadCmdSegment    LoadCmd = 1
-	LoadCmdSymtab     LoadCmd = 2
-	LoadCmdThread     LoadCmd = 4
-	LoadCmdUnixThread LoadCmd = 5 // thread+stack
-	LoadCmdDysymtab   LoadCmd = 11
-	LoadCmdDylib      LoadCmd = 12
-	LoadCmdDylinker   LoadCmd = 15
-	LoadCmdSegment64  LoadCmd = 25
+	LoadCmdSegment    LoadCmd = 0x1
+	LoadCmdSymtab     LoadCmd = 0x2
+	LoadCmdThread     LoadCmd = 0x4
+	LoadCmdUnixThread LoadCmd = 0x5 // thread+stack
+	LoadCmdDysymtab   LoadCmd = 0xb
+	LoadCmdDylib      LoadCmd = 0xc // load dylib command
+	LoadCmdDylinker   LoadCmd = 0xf // id dylinker command (not load dylinker command)
+	LoadCmdSegment64  LoadCmd = 0x19
+	LoadCmdRpath      LoadCmd = 0x8000001c
 )
 
 var cmdStrings = []intName{
@@ -85,50 +96,131 @@
 	{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
 	{uint32(LoadCmdDylib), "LoadCmdDylib"},
 	{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
+	{uint32(LoadCmdRpath), "LoadCmdRpath"},
 }
 
 func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
 
-// A Segment64 is a 64-bit Mach-O segment load command.
-type Segment64 struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Name    [16]byte
-	Addr    uint64
-	Memsz   uint64
-	Offset  uint64
-	Filesz  uint64
-	Maxprot uint32
-	Prot    uint32
-	Nsect   uint32
-	Flag    uint32
-}
+type (
+	// A Segment32 is a 32-bit Mach-O segment load command.
+	Segment32 struct {
+		Cmd     LoadCmd
+		Len     uint32
+		Name    [16]byte
+		Addr    uint32
+		Memsz   uint32
+		Offset  uint32
+		Filesz  uint32
+		Maxprot uint32
+		Prot    uint32
+		Nsect   uint32
+		Flag    uint32
+	}
 
-// A Segment32 is a 32-bit Mach-O segment load command.
-type Segment32 struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Name    [16]byte
-	Addr    uint32
-	Memsz   uint32
-	Offset  uint32
-	Filesz  uint32
-	Maxprot uint32
-	Prot    uint32
-	Nsect   uint32
-	Flag    uint32
-}
+	// A Segment64 is a 64-bit Mach-O segment load command.
+	Segment64 struct {
+		Cmd     LoadCmd
+		Len     uint32
+		Name    [16]byte
+		Addr    uint64
+		Memsz   uint64
+		Offset  uint64
+		Filesz  uint64
+		Maxprot uint32
+		Prot    uint32
+		Nsect   uint32
+		Flag    uint32
+	}
 
-// A DylibCmd is a Mach-O load dynamic library command.
-type DylibCmd struct {
-	Cmd            LoadCmd
-	Len            uint32
-	Name           uint32
-	Time           uint32
-	CurrentVersion uint32
-	CompatVersion  uint32
-}
+	// A SymtabCmd is a Mach-O symbol table command.
+	SymtabCmd struct {
+		Cmd     LoadCmd
+		Len     uint32
+		Symoff  uint32
+		Nsyms   uint32
+		Stroff  uint32
+		Strsize uint32
+	}
+
+	// A DysymtabCmd is a Mach-O dynamic symbol table command.
+	DysymtabCmd struct {
+		Cmd            LoadCmd
+		Len            uint32
+		Ilocalsym      uint32
+		Nlocalsym      uint32
+		Iextdefsym     uint32
+		Nextdefsym     uint32
+		Iundefsym      uint32
+		Nundefsym      uint32
+		Tocoffset      uint32
+		Ntoc           uint32
+		Modtaboff      uint32
+		Nmodtab        uint32
+		Extrefsymoff   uint32
+		Nextrefsyms    uint32
+		Indirectsymoff uint32
+		Nindirectsyms  uint32
+		Extreloff      uint32
+		Nextrel        uint32
+		Locreloff      uint32
+		Nlocrel        uint32
+	}
+
+	// A DylibCmd is a Mach-O load dynamic library command.
+	DylibCmd struct {
+		Cmd            LoadCmd
+		Len            uint32
+		Name           uint32
+		Time           uint32
+		CurrentVersion uint32
+		CompatVersion  uint32
+	}
+
+	// A RpathCmd is a Mach-O rpath command.
+	RpathCmd struct {
+		Cmd  LoadCmd
+		Len  uint32
+		Path uint32
+	}
+
+	// A Thread is a Mach-O thread state command.
+	Thread struct {
+		Cmd  LoadCmd
+		Len  uint32
+		Type uint32
+		Data []uint32
+	}
+)
+
+const (
+	FlagNoUndefs              uint32 = 0x1
+	FlagIncrLink              uint32 = 0x2
+	FlagDyldLink              uint32 = 0x4
+	FlagBindAtLoad            uint32 = 0x8
+	FlagPrebound              uint32 = 0x10
+	FlagSplitSegs             uint32 = 0x20
+	FlagLazyInit              uint32 = 0x40
+	FlagTwoLevel              uint32 = 0x80
+	FlagForceFlat             uint32 = 0x100
+	FlagNoMultiDefs           uint32 = 0x200
+	FlagNoFixPrebinding       uint32 = 0x400
+	FlagPrebindable           uint32 = 0x800
+	FlagAllModsBound          uint32 = 0x1000
+	FlagSubsectionsViaSymbols uint32 = 0x2000
+	FlagCanonical             uint32 = 0x4000
+	FlagWeakDefines           uint32 = 0x8000
+	FlagBindsToWeak           uint32 = 0x10000
+	FlagAllowStackExecution   uint32 = 0x20000
+	FlagRootSafe              uint32 = 0x40000
+	FlagSetuidSafe            uint32 = 0x80000
+	FlagNoReexportedDylibs    uint32 = 0x100000
+	FlagPIE                   uint32 = 0x200000
+	FlagDeadStrippableDylib   uint32 = 0x400000
+	FlagHasTLVDescriptors     uint32 = 0x800000
+	FlagNoHeapExecution       uint32 = 0x1000000
+	FlagAppExtensionSafe      uint32 = 0x2000000
+)
 
 // A Section32 is a 32-bit Mach-O section header.
 type Section32 struct {
@@ -161,40 +253,6 @@
 	Reserve3 uint32
 }
 
-// A SymtabCmd is a Mach-O symbol table command.
-type SymtabCmd struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Symoff  uint32
-	Nsyms   uint32
-	Stroff  uint32
-	Strsize uint32
-}
-
-// A DysymtabCmd is a Mach-O dynamic symbol table command.
-type DysymtabCmd struct {
-	Cmd            LoadCmd
-	Len            uint32
-	Ilocalsym      uint32
-	Nlocalsym      uint32
-	Iextdefsym     uint32
-	Nextdefsym     uint32
-	Iundefsym      uint32
-	Nundefsym      uint32
-	Tocoffset      uint32
-	Ntoc           uint32
-	Modtaboff      uint32
-	Nmodtab        uint32
-	Extrefsymoff   uint32
-	Nextrefsyms    uint32
-	Indirectsymoff uint32
-	Nindirectsyms  uint32
-	Extreloff      uint32
-	Nextrel        uint32
-	Locreloff      uint32
-	Nlocrel        uint32
-}
-
 // An Nlist32 is a Mach-O 32-bit symbol table entry.
 type Nlist32 struct {
 	Name  uint32
@@ -213,23 +271,6 @@
 	Value uint64
 }
 
-// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
-type Symbol struct {
-	Name  string
-	Type  uint8
-	Sect  uint8
-	Desc  uint16
-	Value uint64
-}
-
-// A Thread is a Mach-O thread state command.
-type Thread struct {
-	Cmd  LoadCmd
-	Len  uint32
-	Type uint32
-	Data []uint32
-}
-
 // Regs386 is the Mach-O 386 register structure.
 type Regs386 struct {
 	AX    uint32
diff --git a/src/debug/macho/reloctype.go b/src/debug/macho/reloctype.go
new file mode 100644
index 0000000..496dfce
--- /dev/null
+++ b/src/debug/macho/reloctype.go
@@ -0,0 +1,72 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package macho
+
+//go:generate stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go
+
+type RelocTypeGeneric int
+
+const (
+	GENERIC_RELOC_VANILLA        RelocTypeGeneric = 0
+	GENERIC_RELOC_PAIR           RelocTypeGeneric = 1
+	GENERIC_RELOC_SECTDIFF       RelocTypeGeneric = 2
+	GENERIC_RELOC_PB_LA_PTR      RelocTypeGeneric = 3
+	GENERIC_RELOC_LOCAL_SECTDIFF RelocTypeGeneric = 4
+	GENERIC_RELOC_TLV            RelocTypeGeneric = 5
+)
+
+func (r RelocTypeGeneric) GoString() string { return "macho." + r.String() }
+
+type RelocTypeX86_64 int
+
+const (
+	X86_64_RELOC_UNSIGNED   RelocTypeX86_64 = 0
+	X86_64_RELOC_SIGNED     RelocTypeX86_64 = 1
+	X86_64_RELOC_BRANCH     RelocTypeX86_64 = 2
+	X86_64_RELOC_GOT_LOAD   RelocTypeX86_64 = 3
+	X86_64_RELOC_GOT        RelocTypeX86_64 = 4
+	X86_64_RELOC_SUBTRACTOR RelocTypeX86_64 = 5
+	X86_64_RELOC_SIGNED_1   RelocTypeX86_64 = 6
+	X86_64_RELOC_SIGNED_2   RelocTypeX86_64 = 7
+	X86_64_RELOC_SIGNED_4   RelocTypeX86_64 = 8
+	X86_64_RELOC_TLV        RelocTypeX86_64 = 9
+)
+
+func (r RelocTypeX86_64) GoString() string { return "macho." + r.String() }
+
+type RelocTypeARM int
+
+const (
+	ARM_RELOC_VANILLA        RelocTypeARM = 0
+	ARM_RELOC_PAIR           RelocTypeARM = 1
+	ARM_RELOC_SECTDIFF       RelocTypeARM = 2
+	ARM_RELOC_LOCAL_SECTDIFF RelocTypeARM = 3
+	ARM_RELOC_PB_LA_PTR      RelocTypeARM = 4
+	ARM_RELOC_BR24           RelocTypeARM = 5
+	ARM_THUMB_RELOC_BR22     RelocTypeARM = 6
+	ARM_THUMB_32BIT_BRANCH   RelocTypeARM = 7
+	ARM_RELOC_HALF           RelocTypeARM = 8
+	ARM_RELOC_HALF_SECTDIFF  RelocTypeARM = 9
+)
+
+func (r RelocTypeARM) GoString() string { return "macho." + r.String() }
+
+type RelocTypeARM64 int
+
+const (
+	ARM64_RELOC_UNSIGNED            RelocTypeARM64 = 0
+	ARM64_RELOC_SUBTRACTOR          RelocTypeARM64 = 1
+	ARM64_RELOC_BRANCH26            RelocTypeARM64 = 2
+	ARM64_RELOC_PAGE21              RelocTypeARM64 = 3
+	ARM64_RELOC_PAGEOFF12           RelocTypeARM64 = 4
+	ARM64_RELOC_GOT_LOAD_PAGE21     RelocTypeARM64 = 5
+	ARM64_RELOC_GOT_LOAD_PAGEOFF12  RelocTypeARM64 = 6
+	ARM64_RELOC_POINTER_TO_GOT      RelocTypeARM64 = 7
+	ARM64_RELOC_TLVP_LOAD_PAGE21    RelocTypeARM64 = 8
+	ARM64_RELOC_TLVP_LOAD_PAGEOFF12 RelocTypeARM64 = 9
+	ARM64_RELOC_ADDEND              RelocTypeARM64 = 10
+)
+
+func (r RelocTypeARM64) GoString() string { return "macho." + r.String() }
diff --git a/src/debug/macho/reloctype_string.go b/src/debug/macho/reloctype_string.go
new file mode 100644
index 0000000..6d5c5d8
--- /dev/null
+++ b/src/debug/macho/reloctype_string.go
@@ -0,0 +1,49 @@
+// Code generated by "stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go"; DO NOT EDIT.
+
+package macho
+
+import "fmt"
+
+const _RelocTypeGeneric_name = "GENERIC_RELOC_VANILLAGENERIC_RELOC_PAIRGENERIC_RELOC_SECTDIFFGENERIC_RELOC_PB_LA_PTRGENERIC_RELOC_LOCAL_SECTDIFFGENERIC_RELOC_TLV"
+
+var _RelocTypeGeneric_index = [...]uint8{0, 21, 39, 61, 84, 112, 129}
+
+func (i RelocTypeGeneric) String() string {
+	if i < 0 || i >= RelocTypeGeneric(len(_RelocTypeGeneric_index)-1) {
+		return fmt.Sprintf("RelocTypeGeneric(%d)", i)
+	}
+	return _RelocTypeGeneric_name[_RelocTypeGeneric_index[i]:_RelocTypeGeneric_index[i+1]]
+}
+
+const _RelocTypeX86_64_name = "X86_64_RELOC_UNSIGNEDX86_64_RELOC_SIGNEDX86_64_RELOC_BRANCHX86_64_RELOC_GOT_LOADX86_64_RELOC_GOTX86_64_RELOC_SUBTRACTORX86_64_RELOC_SIGNED_1X86_64_RELOC_SIGNED_2X86_64_RELOC_SIGNED_4X86_64_RELOC_TLV"
+
+var _RelocTypeX86_64_index = [...]uint8{0, 21, 40, 59, 80, 96, 119, 140, 161, 182, 198}
+
+func (i RelocTypeX86_64) String() string {
+	if i < 0 || i >= RelocTypeX86_64(len(_RelocTypeX86_64_index)-1) {
+		return fmt.Sprintf("RelocTypeX86_64(%d)", i)
+	}
+	return _RelocTypeX86_64_name[_RelocTypeX86_64_index[i]:_RelocTypeX86_64_index[i+1]]
+}
+
+const _RelocTypeARM_name = "ARM_RELOC_VANILLAARM_RELOC_PAIRARM_RELOC_SECTDIFFARM_RELOC_LOCAL_SECTDIFFARM_RELOC_PB_LA_PTRARM_RELOC_BR24ARM_THUMB_RELOC_BR22ARM_THUMB_32BIT_BRANCHARM_RELOC_HALFARM_RELOC_HALF_SECTDIFF"
+
+var _RelocTypeARM_index = [...]uint8{0, 17, 31, 49, 73, 92, 106, 126, 148, 162, 185}
+
+func (i RelocTypeARM) String() string {
+	if i < 0 || i >= RelocTypeARM(len(_RelocTypeARM_index)-1) {
+		return fmt.Sprintf("RelocTypeARM(%d)", i)
+	}
+	return _RelocTypeARM_name[_RelocTypeARM_index[i]:_RelocTypeARM_index[i+1]]
+}
+
+const _RelocTypeARM64_name = "ARM64_RELOC_UNSIGNEDARM64_RELOC_SUBTRACTORARM64_RELOC_BRANCH26ARM64_RELOC_PAGE21ARM64_RELOC_PAGEOFF12ARM64_RELOC_GOT_LOAD_PAGE21ARM64_RELOC_GOT_LOAD_PAGEOFF12ARM64_RELOC_POINTER_TO_GOTARM64_RELOC_TLVP_LOAD_PAGE21ARM64_RELOC_TLVP_LOAD_PAGEOFF12ARM64_RELOC_ADDEND"
+
+var _RelocTypeARM64_index = [...]uint16{0, 20, 42, 62, 80, 101, 128, 158, 184, 212, 243, 261}
+
+func (i RelocTypeARM64) String() string {
+	if i < 0 || i >= RelocTypeARM64(len(_RelocTypeARM64_index)-1) {
+		return fmt.Sprintf("RelocTypeARM64(%d)", i)
+	}
+	return _RelocTypeARM64_name[_RelocTypeARM64_index[i]:_RelocTypeARM64_index[i+1]]
+}
diff --git a/src/debug/macho/testdata/clang-386-darwin-exec-with-rpath b/src/debug/macho/testdata/clang-386-darwin-exec-with-rpath
new file mode 100644
index 0000000..a8720fe
--- /dev/null
+++ b/src/debug/macho/testdata/clang-386-darwin-exec-with-rpath
Binary files differ
diff --git a/src/debug/macho/testdata/clang-386-darwin.obj b/src/debug/macho/testdata/clang-386-darwin.obj
new file mode 100644
index 0000000..e79dc57
--- /dev/null
+++ b/src/debug/macho/testdata/clang-386-darwin.obj
Binary files differ
diff --git a/src/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath b/src/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath
new file mode 100644
index 0000000..191c768
--- /dev/null
+++ b/src/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath
Binary files differ
diff --git a/src/debug/macho/testdata/clang-amd64-darwin.obj b/src/debug/macho/testdata/clang-amd64-darwin.obj
new file mode 100644
index 0000000..23cc3c1
--- /dev/null
+++ b/src/debug/macho/testdata/clang-amd64-darwin.obj
Binary files differ
diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go
index b8e2770..26868a3 100644
--- a/src/encoding/asn1/asn1.go
+++ b/src/encoding/asn1/asn1.go
@@ -372,13 +372,32 @@
 	return
 }
 
+// NumericString
+
+// parseNumericString parses an ASN.1 NumericString from the given byte array
+// and returns it.
+func parseNumericString(bytes []byte) (ret string, err error) {
+	for _, b := range bytes {
+		if !isNumeric(b) {
+			return "", SyntaxError{"NumericString contains invalid character"}
+		}
+	}
+	return string(bytes), nil
+}
+
+// isNumeric reports whether the given b is in the ASN.1 NumericString set.
+func isNumeric(b byte) bool {
+	return '0' <= b && b <= '9' ||
+		b == ' '
+}
+
 // PrintableString
 
-// parsePrintableString parses a ASN.1 PrintableString from the given byte
+// parsePrintableString parses an 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) {
+		if !isPrintable(b, allowAsterisk, allowAmpersand) {
 			err = SyntaxError{"PrintableString contains invalid character"}
 			return
 		}
@@ -387,8 +406,21 @@
 	return
 }
 
+type asteriskFlag bool
+type ampersandFlag bool
+
+const (
+	allowAsterisk  asteriskFlag = true
+	rejectAsterisk asteriskFlag = false
+
+	allowAmpersand  ampersandFlag = true
+	rejectAmpersand ampersandFlag = false
+)
+
 // isPrintable reports whether the given b is in the ASN.1 PrintableString set.
-func isPrintable(b byte) bool {
+// If asterisk is allowAsterisk then '*' is also allowed, reflecting existing
+// practice. If ampersand is allowAmpersand then '&' is allowed as well.
+func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
 	return 'a' <= b && b <= 'z' ||
 		'A' <= b && b <= 'Z' ||
 		'0' <= b && b <= '9' ||
@@ -401,12 +433,17 @@
 		// 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 == '*'
+		(bool(asterisk) && b == '*') ||
+		// This is not technically allowed either. However, not
+		// only is it relatively common, but there are also a
+		// handful of CA certificates that contain it. At least
+		// one of which will not expire until 2027.
+		(bool(ampersand) && b == '&')
 }
 
 // IA5String
 
-// parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
+// parseIA5String parses an 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 {
@@ -421,7 +458,7 @@
 
 // T61String
 
-// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
+// parseT61String parses an 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
@@ -429,7 +466,7 @@
 
 // UTF8String
 
-// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
+// parseUTF8String parses an ASN.1 UTF8String (raw UTF-8) from the given byte
 // array and returns it.
 func parseUTF8String(bytes []byte) (ret string, err error) {
 	if !utf8.Valid(bytes) {
@@ -536,7 +573,7 @@
 // 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)
+	matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
 	if !ok {
 		err = StructuralError{"unknown Go type for slice"}
 		return
@@ -552,7 +589,7 @@
 			return
 		}
 		switch t.tag {
-		case TagIA5String, TagGeneralString, TagT61String, TagUTF8String:
+		case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString:
 			// We pretend that various other string types are
 			// PRINTABLE STRINGs so that a sequence of them can be
 			// parsed into a []string.
@@ -562,7 +599,7 @@
 			t.tag = TagUTCTime
 		}
 
-		if t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag {
+		if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
 			err = StructuralError{"sequence tag mismatch"}
 			return
 		}
@@ -617,23 +654,6 @@
 		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
@@ -651,6 +671,8 @@
 			switch t.tag {
 			case TagPrintableString:
 				result, err = parsePrintableString(innerBytes)
+			case TagNumericString:
+				result, err = parseNumericString(innerBytes)
 			case TagIA5String:
 				result, err = parseIA5String(innerBytes)
 			case TagT61String:
@@ -682,11 +704,6 @@
 		}
 		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 {
@@ -702,7 +719,9 @@
 			return
 		}
 		if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
-			if t.length > 0 {
+			if fieldType == rawValueType {
+				// The inner element should not be parsed for RawValues.
+			} else if t.length > 0 {
 				t, offset, err = parseTagAndLength(bytes, offset)
 				if err != nil {
 					return
@@ -727,6 +746,12 @@
 		}
 	}
 
+	matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
+	if !ok1 {
+		err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
+		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
@@ -734,7 +759,7 @@
 	if universalTag == TagPrintableString {
 		if t.class == ClassUniversal {
 			switch t.tag {
-			case TagIA5String, TagGeneralString, TagT61String, TagUTF8String:
+			case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString:
 				universalTag = t.tag
 			}
 		} else if params.stringType != 0 {
@@ -752,21 +777,25 @@
 		universalTag = TagSet
 	}
 
+	matchAnyClassAndTag := matchAny
 	expectedClass := ClassUniversal
 	expectedTag := universalTag
 
 	if !params.explicit && params.tag != nil {
 		expectedClass = ClassContextSpecific
 		expectedTag = *params.tag
+		matchAnyClassAndTag = false
 	}
 
 	if !params.explicit && params.application && params.tag != nil {
 		expectedClass = ClassApplication
 		expectedTag = *params.tag
+		matchAnyClassAndTag = false
 	}
 
 	// We have unwrapped any explicit tagging at this point.
-	if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
+	if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
+		(!matchAny && t.isCompound != compoundType) {
 		// Tags don't match. Again, it could be an optional element.
 		ok := setDefaultValue(v, params)
 		if ok {
@@ -785,6 +814,10 @@
 
 	// We deal with the structures defined in this package first.
 	switch fieldType {
+	case rawValueType:
+		result := RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
+		v.Set(reflect.ValueOf(result))
+		return
 	case objectIdentifierType:
 		newSlice, err1 := parseObjectIdentifier(innerBytes)
 		v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
@@ -904,6 +937,8 @@
 		switch universalTag {
 		case TagPrintableString:
 			v, err = parsePrintableString(innerBytes)
+		case TagNumericString:
+			v, err = parseNumericString(innerBytes)
 		case TagIA5String:
 			v, err = parseIA5String(innerBytes)
 		case TagT61String:
@@ -977,7 +1012,7 @@
 //
 // 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.
+// An ASN.1 PrintableString, IA5String, or NumericString 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.
@@ -992,7 +1027,7 @@
 //
 // The following tags on struct fields have special meaning to Unmarshal:
 //
-//	application specifies that a APPLICATION tag is used
+//	application specifies that an APPLICATION tag is used
 //	default:x   sets the default value for optional integer fields (only used if optional is also present)
 //	explicit    specifies that an additional, explicit tag wraps the implicit one
 //	optional    marks the field as ASN.1 OPTIONAL
diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go
index c9eda40..5e67dc5 100644
--- a/src/encoding/asn1/asn1_test.go
+++ b/src/encoding/asn1/asn1_test.go
@@ -424,6 +424,7 @@
 	{"generalized", fieldParameters{timeType: TagGeneralizedTime}},
 	{"utc", fieldParameters{timeType: TagUTCTime}},
 	{"printable", fieldParameters{stringType: TagPrintableString}},
+	{"numeric", fieldParameters{stringType: TagNumericString}},
 	{"optional", fieldParameters{optional: true}},
 	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
 	{"application", fieldParameters{application: true, tag: new(int)}},
@@ -486,6 +487,8 @@
 	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
 	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
 	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
+	// Ampersand is allowed in PrintableString due to mistakes by major CAs.
+	{[]byte{0x13, 0x05, '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}},
@@ -496,6 +499,7 @@
 	{[]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}}},
+	{[]byte{0x12, 0x0b, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '}, newString("0123456789 ")},
 }
 
 func TestUnmarshal(t *testing.T) {
@@ -1015,7 +1019,7 @@
 		t.Fatal(err)
 	}
 	if !bytes.Equal(NullBytes, marshaled) {
-		t.Errorf("Expected Marshal of NullRawValue to yeild %x, got %x", NullBytes, marshaled)
+		t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled)
 	}
 
 	unmarshaled := RawValue{}
@@ -1033,3 +1037,60 @@
 		t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled)
 	}
 }
+
+func TestExplicitTagRawValueStruct(t *testing.T) {
+	type foo struct {
+		A RawValue `asn1:"optional,explicit,tag:5"`
+		B []byte   `asn1:"optional,explicit,tag:6"`
+	}
+	before := foo{B: []byte{1, 2, 3}}
+	derBytes, err := Marshal(before)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var after foo
+	if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 {
+		t.Fatal(err)
+	}
+
+	got := fmt.Sprintf("%#v", after)
+	want := fmt.Sprintf("%#v", before)
+	if got != want {
+		t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes)
+	}
+}
+
+func TestTaggedRawValue(t *testing.T) {
+	type taggedRawValue struct {
+		A RawValue `asn1:"tag:5"`
+	}
+	type untaggedRawValue struct {
+		A RawValue
+	}
+	const isCompound = 0x20
+	const tag = 5
+
+	tests := []struct {
+		shouldMatch bool
+		derBytes    []byte
+	}{
+		{false, []byte{0x30, 3, TagInteger, 1, 1}},
+		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
+		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
+		{false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
+	}
+
+	for i, test := range tests {
+		var tagged taggedRawValue
+		if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch {
+			t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err)
+		}
+
+		// An untagged RawValue should accept anything.
+		var untagged untaggedRawValue
+		if _, err := Unmarshal(test.derBytes, &untagged); err != nil {
+			t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err)
+		}
+	}
+}
diff --git a/src/encoding/asn1/common.go b/src/encoding/asn1/common.go
index cd93b27..a6589a5 100644
--- a/src/encoding/asn1/common.go
+++ b/src/encoding/asn1/common.go
@@ -30,6 +30,7 @@
 	TagUTF8String      = 12
 	TagSequence        = 16
 	TagSet             = 17
+	TagNumericString   = 18
 	TagPrintableString = 19
 	TagT61String       = 20
 	TagIA5String       = 22
@@ -106,6 +107,8 @@
 			ret.stringType = TagIA5String
 		case part == "printable":
 			ret.stringType = TagPrintableString
+		case part == "numeric":
+			ret.stringType = TagNumericString
 		case part == "utf8":
 			ret.stringType = TagUTF8String
 		case strings.HasPrefix(part, "default:"):
@@ -136,36 +139,38 @@
 
 // Given a reflected Go type, getUniversalType returns the default tag number
 // and expected compound flag.
-func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) {
+func getUniversalType(t reflect.Type) (matchAny bool, tagNumber int, isCompound, ok bool) {
 	switch t {
+	case rawValueType:
+		return true, -1, false, true
 	case objectIdentifierType:
-		return TagOID, false, true
+		return false, TagOID, false, true
 	case bitStringType:
-		return TagBitString, false, true
+		return false, TagBitString, false, true
 	case timeType:
-		return TagUTCTime, false, true
+		return false, TagUTCTime, false, true
 	case enumeratedType:
-		return TagEnum, false, true
+		return false, TagEnum, false, true
 	case bigIntType:
-		return TagInteger, false, true
+		return false, TagInteger, false, true
 	}
 	switch t.Kind() {
 	case reflect.Bool:
-		return TagBoolean, false, true
+		return false, TagBoolean, false, true
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return TagInteger, false, true
+		return false, TagInteger, false, true
 	case reflect.Struct:
-		return TagSequence, true, true
+		return false, TagSequence, true, true
 	case reflect.Slice:
 		if t.Elem().Kind() == reflect.Uint8 {
-			return TagOctetString, false, true
+			return false, TagOctetString, false, true
 		}
 		if strings.HasSuffix(t.Name(), "SET") {
-			return TagSet, true, true
+			return false, TagSet, true, true
 		}
-		return TagSequence, true, true
+		return false, TagSequence, true, true
 	case reflect.String:
-		return TagPrintableString, false, true
+		return false, TagPrintableString, false, true
 	}
-	return 0, false, false
+	return false, 0, false, false
 }
diff --git a/src/encoding/asn1/marshal.go b/src/encoding/asn1/marshal.go
index fdadb39..3e85651 100644
--- a/src/encoding/asn1/marshal.go
+++ b/src/encoding/asn1/marshal.go
@@ -18,7 +18,7 @@
 	byteFFEncoder encoder = byteEncoder(0xff)
 )
 
-// encoder represents a ASN.1 element that is waiting to be marshaled.
+// encoder represents an ASN.1 element that is waiting to be marshaled.
 type encoder interface {
 	// Len returns the number of bytes needed to marshal this element.
 	Len() int
@@ -268,7 +268,13 @@
 
 func makePrintableString(s string) (e encoder, err error) {
 	for i := 0; i < len(s); i++ {
-		if !isPrintable(s[i]) {
+		// The asterisk is often used in PrintableString, even though
+		// it is invalid. If a PrintableString was specifically
+		// requested then the asterisk is permitted by this code.
+		// Ampersand is allowed in parsing due a handful of CA
+		// certificates, however when making new certificates
+		// it is rejected.
+		if !isPrintable(s[i], allowAsterisk, rejectAmpersand) {
 			return nil, StructuralError{"PrintableString contains invalid character"}
 		}
 	}
@@ -286,6 +292,16 @@
 	return stringEncoder(s), nil
 }
 
+func makeNumericString(s string) (e encoder, err error) {
+	for i := 0; i < len(s); i++ {
+		if !isNumeric(s[i]) {
+			return nil, StructuralError{"NumericString contains invalid character"}
+		}
+	}
+
+	return stringEncoder(s), nil
+}
+
 func makeUTF8String(s string) encoder {
 	return stringEncoder(s)
 }
@@ -503,6 +519,8 @@
 			return makeIA5String(v.String())
 		case TagPrintableString:
 			return makePrintableString(v.String())
+		case TagNumericString:
+			return makeNumericString(v.String())
 		default:
 			return makeUTF8String(v.String()), nil
 		}
@@ -556,11 +574,10 @@
 		return t, nil
 	}
 
-	tag, isCompound, ok := getUniversalType(v.Type())
-	if !ok {
+	matchAny, tag, isCompound, ok := getUniversalType(v.Type())
+	if !ok || matchAny {
 		return nil, StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())}
 	}
-	class := ClassUniversal
 
 	if params.timeType != 0 && tag != TagUTCTime {
 		return nil, StructuralError{"explicit time type given to non-time member"}
@@ -577,7 +594,7 @@
 			// 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 r >= utf8.RuneSelf || !isPrintable(byte(r), rejectAsterisk, rejectAmpersand) {
 					if !utf8.ValidString(v.String()) {
 						return nil, errors.New("asn1: string not valid UTF-8")
 					}
@@ -610,27 +627,33 @@
 
 	bodyLen := t.body.Len()
 
-	if params.explicit {
-		t.tag = bytesEncoder(appendTagAndLength(t.scratch[:0], tagAndLength{class, tag, bodyLen, isCompound}))
-
-		tt := new(taggedEncoder)
-
-		tt.body = t
-
-		tt.tag = bytesEncoder(appendTagAndLength(tt.scratch[:0], tagAndLength{
-			class:      ClassContextSpecific,
-			tag:        *params.tag,
-			length:     bodyLen + t.tag.Len(),
-			isCompound: true,
-		}))
-
-		return tt, nil
-	}
-
+	class := ClassUniversal
 	if params.tag != nil {
+		if params.application {
+			class = ClassApplication
+		} else {
+			class = ClassContextSpecific
+		}
+
+		if params.explicit {
+			t.tag = bytesEncoder(appendTagAndLength(t.scratch[:0], tagAndLength{ClassUniversal, tag, bodyLen, isCompound}))
+
+			tt := new(taggedEncoder)
+
+			tt.body = t
+
+			tt.tag = bytesEncoder(appendTagAndLength(tt.scratch[:0], tagAndLength{
+				class:      class,
+				tag:        *params.tag,
+				length:     bodyLen + t.tag.Len(),
+				isCompound: true,
+			}))
+
+			return tt, nil
+		}
+
 		// implicit tag.
 		tag = *params.tag
-		class = ClassContextSpecific
 	}
 
 	t.tag = bytesEncoder(appendTagAndLength(t.scratch[:0], tagAndLength{class, tag, bodyLen, isCompound}))
@@ -650,7 +673,13 @@
 //	utc:         causes time.Time to be marshaled as ASN.1, UTCTime values
 //	generalized: causes time.Time to be marshaled as ASN.1, GeneralizedTime values
 func Marshal(val interface{}) ([]byte, error) {
-	e, err := makeField(reflect.ValueOf(val), fieldParameters{})
+	return MarshalWithParams(val, "")
+}
+
+// MarshalWithParams allows field parameters to be specified for the
+// top-level element. The form of the params is the same as the field tags.
+func MarshalWithParams(val interface{}, params string) ([]byte, error) {
+	e, err := makeField(reflect.ValueOf(val), parseFieldParameters(params))
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/encoding/asn1/marshal_test.go b/src/encoding/asn1/marshal_test.go
index 10db1aa..4f755a1 100644
--- a/src/encoding/asn1/marshal_test.go
+++ b/src/encoding/asn1/marshal_test.go
@@ -59,6 +59,10 @@
 	A string `asn1:"printable"`
 }
 
+type genericStringTest struct {
+	A string
+}
+
 type optionalRawValueTest struct {
 	A RawValue `asn1:"optional"`
 }
@@ -71,6 +75,15 @@
 	A int `asn1:"optional,default:1"`
 }
 
+type applicationTest struct {
+	A int `asn1:"application,tag:0"`
+	B int `asn1:"application,tag:1,explicit"`
+}
+
+type numericStringTest struct {
+	A string `asn1:"numeric"`
+}
+
 type testSET []int
 
 var PST = time.FixedZone("PST", -8*60*60)
@@ -142,6 +155,9 @@
 	{optionalRawValueTest{}, "3000"},
 	{printableStringTest{"test"}, "3006130474657374"},
 	{printableStringTest{"test*"}, "30071305746573742a"},
+	{genericStringTest{"test"}, "3006130474657374"},
+	{genericStringTest{"test*"}, "30070c05746573742a"},
+	{genericStringTest{"test&"}, "30070c057465737426"},
 	{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"},
@@ -152,6 +168,8 @@
 	{defaultTest{0}, "3003020100"},
 	{defaultTest{1}, "3000"},
 	{defaultTest{2}, "3003020102"},
+	{applicationTest{1, 2}, "30084001016103020102"},
+	{numericStringTest{"1 9"}, "30051203312039"},
 }
 
 func TestMarshal(t *testing.T) {
@@ -168,6 +186,31 @@
 	}
 }
 
+type marshalWithParamsTest struct {
+	in     interface{}
+	params string
+	out    string // hex encoded
+}
+
+var marshalWithParamsTests = []marshalWithParamsTest{
+	{intStruct{10}, "set", "310302010a"},
+	{intStruct{10}, "application", "600302010a"},
+}
+
+func TestMarshalWithParams(t *testing.T) {
+	for i, test := range marshalWithParamsTests {
+		data, err := MarshalWithParams(test.in, test.params)
+		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)
+
+		}
+	}
+}
+
 type marshalErrTest struct {
 	in  interface{}
 	err string
@@ -175,6 +218,9 @@
 
 var marshalErrTests = []marshalErrTest{
 	{bigIntStruct{nil}, "empty integer"},
+	{numericStringTest{"a"}, "invalid character"},
+	{ia5StringTest{"\xb0"}, "invalid character"},
+	{printableStringTest{"!"}, "invalid character"},
 }
 
 func TestMarshalError(t *testing.T) {
diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go
index bf341b5..e72ba74 100644
--- a/src/encoding/base32/base32.go
+++ b/src/encoding/base32/base32.go
@@ -130,8 +130,19 @@
 		}
 
 		// Encode 5-bit blocks using the base32 alphabet
-		for i := 0; i < 8; i++ {
-			if len(dst) > i {
+		size := len(dst)
+		if size >= 8 {
+			// Common case, unrolled for extra performance
+			dst[0] = enc.encode[b[0]]
+			dst[1] = enc.encode[b[1]]
+			dst[2] = enc.encode[b[2]]
+			dst[3] = enc.encode[b[3]]
+			dst[4] = enc.encode[b[4]]
+			dst[5] = enc.encode[b[5]]
+			dst[6] = enc.encode[b[6]]
+			dst[7] = enc.encode[b[7]]
+		} else {
+			for i := 0; i < size; i++ {
 				dst[i] = enc.encode[b[i]]
 			}
 		}
diff --git a/src/encoding/base64/base64.go b/src/encoding/base64/base64.go
index b208f9e..9a99370 100644
--- a/src/encoding/base64/base64.go
+++ b/src/encoding/base64/base64.go
@@ -6,6 +6,7 @@
 package base64
 
 import (
+	"encoding/binary"
 	"io"
 	"strconv"
 )
@@ -269,121 +270,110 @@
 	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 or a partial quantum was encountered
-// and thus any additional data is an error.
-func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
-	si := 0
+// decodeQuantum decodes up to 4 base64 bytes. It takes for parameters
+// the destination buffer dst, the source buffer src and an index in the
+// source buffer si.
+// It returns the number of bytes read from src, the number of bytes written
+// to dst, and an error, if any.
+func (enc *Encoding) decodeQuantum(dst, src []byte, si int) (nsi, n int, err error) {
+	// Decode quantum using the base64 alphabet
+	var dbuf [4]byte
+	dinc, dlen := 3, 4
 
-	for si < len(src) && !end {
-		// Decode quantum using the base64 alphabet
-		var dbuf [4]byte
-		dinc, dlen := 3, 4
-
-		for j := 0; j < len(dbuf); j++ {
-			if len(src) == si {
-				switch {
-				case j == 0:
-					return n, false, nil
-				case j == 1, enc.padChar != NoPadding:
-					return n, false, CorruptInputError(si - j)
-				}
-				dinc, dlen, end = j-1, j, true
-				break
+	for j := 0; j < len(dbuf); j++ {
+		if len(src) == si {
+			switch {
+			case j == 0:
+				return si, 0, nil
+			case j == 1, enc.padChar != NoPadding:
+				return si, 0, CorruptInputError(si - j)
 			}
-			in := src[si]
+			dinc, dlen = j-1, j
+			break
+		}
+		in := src[si]
+		si++
+
+		out := enc.decodeMap[in]
+		if out != 0xff {
+			dbuf[j] = out
+			continue
+		}
+
+		if in == '\n' || in == '\r' {
+			j--
+			continue
+		}
+
+		if rune(in) != enc.padChar {
+			return si, 0, CorruptInputError(si - 1)
+		}
+
+		// We've reached the end and there's padding
+		switch j {
+		case 0, 1:
+			// incorrect padding
+			return si, 0, CorruptInputError(si - 1)
+		case 2:
+			// "==" is expected, the first "=" is already consumed.
+			// skip over newlines
+			for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+				si++
+			}
+			if si == len(src) {
+				// not enough padding
+				return si, 0, CorruptInputError(len(src))
+			}
+			if rune(src[si]) != enc.padChar {
+				// incorrect padding
+				return si, 0, CorruptInputError(si - 1)
+			}
 
 			si++
-
-			out := enc.decodeMap[in]
-			if out != 0xFF {
-				dbuf[j] = out
-				continue
-			}
-
-			if in == '\n' || in == '\r' {
-				j--
-				continue
-			}
-			if rune(in) == enc.padChar {
-				// We've reached the end and there's padding
-				switch j {
-				case 0, 1:
-					// incorrect padding
-					return n, false, CorruptInputError(si - 1)
-				case 2:
-					// "==" is expected, the first "=" is already consumed.
-					// skip over newlines
-					for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
-						si++
-					}
-					if si == len(src) {
-						// not enough padding
-						return n, false, CorruptInputError(len(src))
-					}
-					if rune(src[si]) != enc.padChar {
-						// incorrect padding
-						return n, false, CorruptInputError(si - 1)
-					}
-
-					si++
-				}
-				// skip over newlines
-				for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
-					si++
-				}
-				if si < len(src) {
-					// trailing garbage
-					err = CorruptInputError(si)
-				}
-				dinc, dlen, end = 3, j, true
-				break
-			}
-			return n, false, CorruptInputError(si - 1)
 		}
 
-		// Convert 4x 6bit source bytes into 3 bytes
-		val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
-		dbuf[2], dbuf[1], dbuf[0] = byte(val>>0), byte(val>>8), byte(val>>16)
-		switch dlen {
-		case 4:
-			dst[2] = dbuf[2]
-			dbuf[2] = 0
-			fallthrough
-		case 3:
-			dst[1] = dbuf[1]
-			if enc.strict && dbuf[2] != 0 {
-				return n, end, CorruptInputError(si - 1)
-			}
-			dbuf[1] = 0
-			fallthrough
-		case 2:
-			dst[0] = dbuf[0]
-			if enc.strict && (dbuf[1] != 0 || dbuf[2] != 0) {
-				return n, end, CorruptInputError(si - 2)
-			}
+		// skip over newlines
+		for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+			si++
 		}
-		dst = dst[dinc:]
-		n += dlen - 1
+		if si < len(src) {
+			// trailing garbage
+			err = CorruptInputError(si)
+		}
+		dinc, dlen = 3, j
+		break
 	}
 
-	return n, end, err
-}
+	// Convert 4x 6bit source bytes into 3 bytes
+	val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
+	dbuf[2], dbuf[1], dbuf[0] = byte(val>>0), byte(val>>8), byte(val>>16)
+	switch dlen {
+	case 4:
+		dst[2] = dbuf[2]
+		dbuf[2] = 0
+		fallthrough
+	case 3:
+		dst[1] = dbuf[1]
+		if enc.strict && dbuf[2] != 0 {
+			return si, 0, CorruptInputError(si - 1)
+		}
+		dbuf[1] = 0
+		fallthrough
+	case 2:
+		dst[0] = dbuf[0]
+		if enc.strict && (dbuf[1] != 0 || dbuf[2] != 0) {
+			return si, 0, CorruptInputError(si - 2)
+		}
+	}
+	dst = dst[dinc:]
 
-// 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) {
-	n, _, err = enc.decode(dst, src)
-	return
+	return si, dlen - 1, err
 }
 
 // DecodeString returns the bytes represented by the base64 string s.
 func (enc *Encoding) DecodeString(s string) ([]byte, error) {
 	dbuf := make([]byte, enc.DecodedLen(len(s)))
-	n, _, err := enc.decode(dbuf, []byte(s))
+	n, err := enc.Decode(dbuf, []byte(s))
 	return dbuf[:n], err
 }
 
@@ -392,7 +382,6 @@
 	readErr error // error from r.Read
 	enc     *Encoding
 	r       io.Reader
-	end     bool       // saw end of message
 	buf     [1024]byte // leftover input
 	nbuf    int
 	out     []byte // leftover decoded output
@@ -430,9 +419,8 @@
 		if d.enc.padChar == NoPadding && d.nbuf > 0 {
 			// Decode final fragment, without padding.
 			var nw int
-			nw, _, d.err = d.enc.decode(d.outbuf[:], d.buf[:d.nbuf])
+			nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:d.nbuf])
 			d.nbuf = 0
-			d.end = true
 			d.out = d.outbuf[:nw]
 			n = copy(p, d.out)
 			d.out = d.out[n:]
@@ -454,18 +442,138 @@
 	nr := d.nbuf / 4 * 4
 	nw := d.nbuf / 4 * 3
 	if nw > len(p) {
-		nw, d.end, d.err = d.enc.decode(d.outbuf[:], d.buf[:nr])
+		nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:nr])
 		d.out = d.outbuf[:nw]
 		n = copy(p, d.out)
 		d.out = d.out[n:]
 	} else {
-		n, d.end, d.err = d.enc.decode(p, d.buf[:nr])
+		n, d.err = d.enc.Decode(p, d.buf[:nr])
 	}
 	d.nbuf -= nr
 	copy(d.buf[:d.nbuf], d.buf[nr:])
 	return n, d.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) {
+	if len(src) == 0 {
+		return 0, nil
+	}
+
+	si := 0
+	ilen := len(src)
+	olen := len(dst)
+	for strconv.IntSize >= 64 && ilen-si >= 8 && olen-n >= 8 {
+		if ok := enc.decode64(dst[n:], src[si:]); ok {
+			n += 6
+			si += 8
+		} else {
+			var ninc int
+			si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+			n += ninc
+			if err != nil {
+				return n, err
+			}
+		}
+	}
+
+	for ilen-si >= 4 && olen-n >= 4 {
+		if ok := enc.decode32(dst[n:], src[si:]); ok {
+			n += 3
+			si += 4
+		} else {
+			var ninc int
+			si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+			n += ninc
+			if err != nil {
+				return n, err
+			}
+		}
+	}
+
+	for si < len(src) {
+		var ninc int
+		si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+		n += ninc
+		if err != nil {
+			return n, err
+		}
+	}
+	return n, err
+}
+
+// decode32 tries to decode 4 base64 char into 3 bytes.
+// len(dst) and len(src) must both be >= 4.
+// Returns true if decode succeeded.
+func (enc *Encoding) decode32(dst, src []byte) bool {
+	var dn, n uint32
+	if n = uint32(enc.decodeMap[src[0]]); n == 0xff {
+		return false
+	}
+	dn |= n << 26
+	if n = uint32(enc.decodeMap[src[1]]); n == 0xff {
+		return false
+	}
+	dn |= n << 20
+	if n = uint32(enc.decodeMap[src[2]]); n == 0xff {
+		return false
+	}
+	dn |= n << 14
+	if n = uint32(enc.decodeMap[src[3]]); n == 0xff {
+		return false
+	}
+	dn |= n << 8
+
+	binary.BigEndian.PutUint32(dst, dn)
+	return true
+}
+
+// decode64 tries to decode 8 base64 char into 6 bytes.
+// len(dst) and len(src) must both be >= 8.
+// Returns true if decode succeeded.
+func (enc *Encoding) decode64(dst, src []byte) bool {
+	var dn, n uint64
+	if n = uint64(enc.decodeMap[src[0]]); n == 0xff {
+		return false
+	}
+	dn |= n << 58
+	if n = uint64(enc.decodeMap[src[1]]); n == 0xff {
+		return false
+	}
+	dn |= n << 52
+	if n = uint64(enc.decodeMap[src[2]]); n == 0xff {
+		return false
+	}
+	dn |= n << 46
+	if n = uint64(enc.decodeMap[src[3]]); n == 0xff {
+		return false
+	}
+	dn |= n << 40
+	if n = uint64(enc.decodeMap[src[4]]); n == 0xff {
+		return false
+	}
+	dn |= n << 34
+	if n = uint64(enc.decodeMap[src[5]]); n == 0xff {
+		return false
+	}
+	dn |= n << 28
+	if n = uint64(enc.decodeMap[src[6]]); n == 0xff {
+		return false
+	}
+	dn |= n << 22
+	if n = uint64(enc.decodeMap[src[7]]); n == 0xff {
+		return false
+	}
+	dn |= n << 16
+
+	binary.BigEndian.PutUint64(dst, dn)
+	return true
+}
+
 type newlineFilteringReader struct {
 	wrapped io.Reader
 }
diff --git a/src/encoding/base64/base64_test.go b/src/encoding/base64/base64_test.go
index 05011fb..9f5c493 100644
--- a/src/encoding/base64/base64_test.go
+++ b/src/encoding/base64/base64_test.go
@@ -152,12 +152,9 @@
 		for _, tt := range encodingTests {
 			encoded := tt.conv(p.encoded)
 			dbuf := make([]byte, tt.enc.DecodedLen(len(encoded)))
-			count, end, err := tt.enc.decode(dbuf, []byte(encoded))
+			count, err := tt.enc.Decode(dbuf, []byte(encoded))
 			testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil))
 			testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded))
-			if len(encoded) > 0 {
-				testEqual(t, "Decode(%q) = end %v, want %v", encoded, end, len(p.decoded)%3 != 0)
-			}
 			testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded)
 
 			dbuf, err = tt.enc.DecodeString(encoded)
diff --git a/src/encoding/binary/binary_test.go b/src/encoding/binary/binary_test.go
index 0547bee..af40257 100644
--- a/src/encoding/binary/binary_test.go
+++ b/src/encoding/binary/binary_test.go
@@ -109,6 +109,7 @@
 
 var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
 var res = []int32{0x01020304, 0x05060708}
+var putbuf = []byte{0, 0, 0, 0, 0, 0, 0, 0}
 
 func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, want interface{}) {
 	if err != nil {
@@ -502,25 +503,42 @@
 }
 
 func BenchmarkPutUint16(b *testing.B) {
-	buf := [2]byte{}
 	b.SetBytes(2)
 	for i := 0; i < b.N; i++ {
-		BigEndian.PutUint16(buf[:], uint16(i))
+		BigEndian.PutUint16(putbuf[:], uint16(i))
 	}
 }
 
 func BenchmarkPutUint32(b *testing.B) {
-	buf := [4]byte{}
 	b.SetBytes(4)
 	for i := 0; i < b.N; i++ {
-		BigEndian.PutUint32(buf[:], uint32(i))
+		BigEndian.PutUint32(putbuf[:], uint32(i))
 	}
 }
 
 func BenchmarkPutUint64(b *testing.B) {
-	buf := [8]byte{}
 	b.SetBytes(8)
 	for i := 0; i < b.N; i++ {
-		BigEndian.PutUint64(buf[:], uint64(i))
+		BigEndian.PutUint64(putbuf[:], uint64(i))
+	}
+}
+func BenchmarkLittleEndianPutUint16(b *testing.B) {
+	b.SetBytes(2)
+	for i := 0; i < b.N; i++ {
+		LittleEndian.PutUint16(putbuf[:], uint16(i))
+	}
+}
+
+func BenchmarkLittleEndianPutUint32(b *testing.B) {
+	b.SetBytes(4)
+	for i := 0; i < b.N; i++ {
+		LittleEndian.PutUint32(putbuf[:], uint32(i))
+	}
+}
+
+func BenchmarkLittleEndianPutUint64(b *testing.B) {
+	b.SetBytes(8)
+	for i := 0; i < b.N; i++ {
+		LittleEndian.PutUint64(putbuf[:], uint64(i))
 	}
 }
diff --git a/src/encoding/binary/example_test.go b/src/encoding/binary/example_test.go
index a8b8dba..6f892c2 100644
--- a/src/encoding/binary/example_test.go
+++ b/src/encoding/binary/example_test.go
@@ -51,6 +51,32 @@
 	// Output: 3.141592653589793
 }
 
+func ExampleRead_multi() {
+	b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0xff, 0x01, 0x02, 0x03, 0xbe, 0xef}
+	r := bytes.NewReader(b)
+
+	var data struct {
+		PI   float64
+		Uate uint8
+		Mine [3]byte
+		Too  uint16
+	}
+
+	if err := binary.Read(r, binary.LittleEndian, &data); err != nil {
+		fmt.Println("binary.Read failed:", err)
+	}
+
+	fmt.Println(data.PI)
+	fmt.Println(data.Uate)
+	fmt.Printf("% x\n", data.Mine)
+	fmt.Println(data.Too)
+	// Output:
+	// 3.141592653589793
+	// 255
+	// 01 02 03
+	// 61374
+}
+
 func ExampleByteOrder_put() {
 	b := make([]byte, 4)
 	binary.LittleEndian.PutUint16(b[0:], 0x03e8)
diff --git a/src/encoding/csv/reader.go b/src/encoding/csv/reader.go
index a3497c8..2efc7ad 100644
--- a/src/encoding/csv/reader.go
+++ b/src/encoding/csv/reader.go
@@ -58,44 +58,67 @@
 	"fmt"
 	"io"
 	"unicode"
+	"unicode/utf8"
 )
 
 // A ParseError is returned for parsing errors.
-// The first line is 1.  The first column is 0.
+// Line numbers are 1-indexed and columns are 0-indexed.
 type ParseError struct {
-	Line   int   // Line where the error occurred
-	Column int   // Column (rune index) where the error occurred
-	Err    error // The actual error
+	StartLine int   // Line where the record starts
+	Line      int   // Line where the error occurred
+	Column    int   // Column (rune index) where the error occurred
+	Err       error // The actual error
 }
 
 func (e *ParseError) Error() string {
-	return fmt.Sprintf("line %d, column %d: %s", e.Line, e.Column, e.Err)
+	if e.Err == ErrFieldCount {
+		return fmt.Sprintf("record on line %d: %v", e.Line, e.Err)
+	}
+	if e.StartLine != e.Line {
+		return fmt.Sprintf("record on line %d; parse error on line %d, column %d: %v", e.StartLine, e.Line, e.Column, e.Err)
+	}
+	return fmt.Sprintf("parse error on line %d, column %d: %v", e.Line, e.Column, e.Err)
 }
 
-// These are the errors that can be returned in ParseError.Error
+// These are the errors that can be returned in ParseError.Err.
 var (
-	ErrTrailingComma = errors.New("extra delimiter at end of line") // no longer used
+	ErrTrailingComma = errors.New("extra delimiter at end of line") // Deprecated: No longer used.
 	ErrBareQuote     = errors.New("bare \" in non-quoted-field")
-	ErrQuote         = errors.New("extraneous \" in field")
-	ErrFieldCount    = errors.New("wrong number of fields in line")
+	ErrQuote         = errors.New("extraneous or missing \" in quoted-field")
+	ErrFieldCount    = errors.New("wrong number of fields")
 )
 
+var errInvalidDelim = errors.New("csv: invalid field or comment delimiter")
+
+func validDelim(r rune) bool {
+	return r != 0 && r != '\r' && r != '\n' && utf8.ValidRune(r) && r != utf8.RuneError
+}
+
 // A Reader reads records from a CSV-encoded file.
 //
 // As returned by NewReader, a Reader expects input conforming to RFC 4180.
 // The exported fields can be changed to customize the details before the
 // first call to Read or ReadAll.
 //
-//
+// The Reader converts all \r\n sequences in its input to plain \n,
+// including in multiline field values, so that the returned data does
+// not depend on which line-ending convention an input file uses.
 type Reader struct {
 	// Comma is the field delimiter.
 	// It is set to comma (',') by NewReader.
+	// Comma must be a valid rune and must not be \r, \n,
+	// or the Unicode replacement character (0xFFFD).
 	Comma rune
+
 	// Comment, if not 0, is the comment character. Lines beginning with the
 	// Comment character without preceding whitespace are ignored.
 	// With leading whitespace the Comment character becomes part of the
 	// field, even if TrimLeadingSpace is true.
+	// Comment must be a valid rune and must not be \r, \n,
+	// or the Unicode replacement character (0xFFFD).
+	// It must also not be equal to Comma.
 	Comment rune
+
 	// FieldsPerRecord is the number of expected fields per record.
 	// If FieldsPerRecord is positive, Read requires each record to
 	// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
@@ -103,31 +126,41 @@
 	// have the same field count. If FieldsPerRecord is negative, no check is
 	// made and records may have a variable number of fields.
 	FieldsPerRecord int
+
 	// If LazyQuotes is true, a quote may appear in an unquoted field and a
 	// non-doubled quote may appear in a quoted field.
-	LazyQuotes    bool
-	TrailingComma bool // ignored; here for backwards compatibility
+	LazyQuotes bool
+
 	// If TrimLeadingSpace is true, leading white space in a field is ignored.
 	// This is done even if the field delimiter, Comma, is white space.
 	TrimLeadingSpace bool
+
 	// ReuseRecord controls whether calls to Read may return a slice sharing
 	// the backing array of the previous call's returned slice for performance.
 	// By default, each call to Read returns newly allocated memory owned by the caller.
 	ReuseRecord bool
 
-	line   int
-	column int
-	r      *bufio.Reader
-	// lineBuffer holds the unescaped fields read by readField, one after another.
+	TrailingComma bool // Deprecated: No longer used.
+
+	r *bufio.Reader
+
+	// numLine is the current line being read in the CSV file.
+	numLine int
+
+	// rawBuffer is a line buffer only used by the readLine method.
+	rawBuffer []byte
+
+	// recordBuffer holds the unescaped fields, one after another.
 	// The fields can be accessed by using the indexes in fieldIndexes.
-	// Example: for the row `a,"b","c""d",e` lineBuffer will contain `abc"de` and
-	// fieldIndexes will contain the indexes 0, 1, 2, 5.
-	lineBuffer bytes.Buffer
-	// Indexes of fields inside lineBuffer
-	// The i'th field starts at offset fieldIndexes[i] in lineBuffer.
+	// E.g., For the row `a,"b","c""d",e`, recordBuffer will contain `abc"de`
+	// and fieldIndexes will contain the indexes [1, 2, 5, 6].
+	recordBuffer []byte
+
+	// fieldIndexes is an index of fields inside recordBuffer.
+	// The i'th field ends at offset fieldIndexes[i] in recordBuffer.
 	fieldIndexes []int
 
-	// only used when ReuseRecord == true
+	// lastRecord is a record cache and only used when ReuseRecord == true.
 	lastRecord []string
 }
 
@@ -139,15 +172,6 @@
 	}
 }
 
-// error creates a new ParseError based on err.
-func (r *Reader) error(err error) error {
-	return &ParseError{
-		Line:   r.line,
-		Column: r.column,
-		Err:    err,
-	}
-}
-
 // Read reads one record (a slice of fields) from r.
 // If the record has an unexpected number of fields,
 // Read returns the record along with the error ErrFieldCount.
@@ -163,7 +187,6 @@
 	} else {
 		record, err = r.readRecord(nil)
 	}
-
 	return record, err
 }
 
@@ -185,226 +208,192 @@
 	}
 }
 
-// readRecord reads and parses a single csv record from r.
-// Unlike parseRecord, readRecord handles FieldsPerRecord.
-// If dst has enough capacity it will be used for the returned record.
-func (r *Reader) readRecord(dst []string) (record []string, err error) {
-	for {
-		record, err = r.parseRecord(dst)
-		if record != nil {
-			break
+// readLine reads the next line (with the trailing endline).
+// If EOF is hit without a trailing endline, it will be omitted.
+// If some bytes were read, then the error is never io.EOF.
+// The result is only valid until the next call to readLine.
+func (r *Reader) readLine() ([]byte, error) {
+	line, err := r.r.ReadSlice('\n')
+	if err == bufio.ErrBufferFull {
+		r.rawBuffer = append(r.rawBuffer[:0], line...)
+		for err == bufio.ErrBufferFull {
+			line, err = r.r.ReadSlice('\n')
+			r.rawBuffer = append(r.rawBuffer, line...)
 		}
-		if err != nil {
-			return nil, err
+		line = r.rawBuffer
+	}
+	if len(line) > 0 && err == io.EOF {
+		err = nil
+		// For backwards compatibility, drop trailing \r before EOF.
+		if line[len(line)-1] == '\r' {
+			line = line[:len(line)-1]
 		}
 	}
+	r.numLine++
+	// Normalize \r\n to \n on all input lines.
+	if n := len(line); n >= 2 && line[n-2] == '\r' && line[n-1] == '\n' {
+		line[n-2] = '\n'
+		line = line[:n-1]
+	}
+	return line, err
+}
 
+// lengthNL reports the number of bytes for the trailing \n.
+func lengthNL(b []byte) int {
+	if len(b) > 0 && b[len(b)-1] == '\n' {
+		return 1
+	}
+	return 0
+}
+
+// nextRune returns the next rune in b or utf8.RuneError.
+func nextRune(b []byte) rune {
+	r, _ := utf8.DecodeRune(b)
+	return r
+}
+
+func (r *Reader) readRecord(dst []string) ([]string, error) {
+	if r.Comma == r.Comment || !validDelim(r.Comma) || (r.Comment != 0 && !validDelim(r.Comment)) {
+		return nil, errInvalidDelim
+	}
+
+	// Read line (automatically skipping past empty lines and any comments).
+	var line, fullLine []byte
+	var errRead error
+	for errRead == nil {
+		line, errRead = r.readLine()
+		if r.Comment != 0 && nextRune(line) == r.Comment {
+			line = nil
+			continue // Skip comment lines
+		}
+		if errRead == nil && len(line) == lengthNL(line) {
+			line = nil
+			continue // Skip empty lines
+		}
+		fullLine = line
+		break
+	}
+	if errRead == io.EOF {
+		return nil, errRead
+	}
+
+	// Parse each field in the record.
+	var err error
+	const quoteLen = len(`"`)
+	commaLen := utf8.RuneLen(r.Comma)
+	recLine := r.numLine // Starting line for record
+	r.recordBuffer = r.recordBuffer[:0]
+	r.fieldIndexes = r.fieldIndexes[:0]
+parseField:
+	for {
+		if r.TrimLeadingSpace {
+			line = bytes.TrimLeftFunc(line, unicode.IsSpace)
+		}
+		if len(line) == 0 || line[0] != '"' {
+			// Non-quoted string field
+			i := bytes.IndexRune(line, r.Comma)
+			field := line
+			if i >= 0 {
+				field = field[:i]
+			} else {
+				field = field[:len(field)-lengthNL(field)]
+			}
+			// Check to make sure a quote does not appear in field.
+			if !r.LazyQuotes {
+				if j := bytes.IndexByte(field, '"'); j >= 0 {
+					col := utf8.RuneCount(fullLine[:len(fullLine)-len(line[j:])])
+					err = &ParseError{StartLine: recLine, Line: r.numLine, Column: col, Err: ErrBareQuote}
+					break parseField
+				}
+			}
+			r.recordBuffer = append(r.recordBuffer, field...)
+			r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+			if i >= 0 {
+				line = line[i+commaLen:]
+				continue parseField
+			}
+			break parseField
+		} else {
+			// Quoted string field
+			line = line[quoteLen:]
+			for {
+				i := bytes.IndexByte(line, '"')
+				if i >= 0 {
+					// Hit next quote.
+					r.recordBuffer = append(r.recordBuffer, line[:i]...)
+					line = line[i+quoteLen:]
+					switch rn := nextRune(line); {
+					case rn == '"':
+						// `""` sequence (append quote).
+						r.recordBuffer = append(r.recordBuffer, '"')
+						line = line[quoteLen:]
+					case rn == r.Comma:
+						// `",` sequence (end of field).
+						line = line[commaLen:]
+						r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+						continue parseField
+					case lengthNL(line) == len(line):
+						// `"\n` sequence (end of line).
+						r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+						break parseField
+					case r.LazyQuotes:
+						// `"` sequence (bare quote).
+						r.recordBuffer = append(r.recordBuffer, '"')
+					default:
+						// `"*` sequence (invalid non-escaped quote).
+						col := utf8.RuneCount(fullLine[:len(fullLine)-len(line)-quoteLen])
+						err = &ParseError{StartLine: recLine, Line: r.numLine, Column: col, Err: ErrQuote}
+						break parseField
+					}
+				} else if len(line) > 0 {
+					// Hit end of line (copy all data so far).
+					r.recordBuffer = append(r.recordBuffer, line...)
+					if errRead != nil {
+						break parseField
+					}
+					line, errRead = r.readLine()
+					if errRead == io.EOF {
+						errRead = nil
+					}
+					fullLine = line
+				} else {
+					// Abrupt end of file (EOF or error).
+					if !r.LazyQuotes && errRead == nil {
+						col := utf8.RuneCount(fullLine)
+						err = &ParseError{StartLine: recLine, Line: r.numLine, Column: col, Err: ErrQuote}
+						break parseField
+					}
+					r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+					break parseField
+				}
+			}
+		}
+	}
+	if err == nil {
+		err = errRead
+	}
+
+	// Create a single string and create slices out of it.
+	// This pins the memory of the fields together, but allocates once.
+	str := string(r.recordBuffer) // Convert to string once to batch allocations
+	dst = dst[:0]
+	if cap(dst) < len(r.fieldIndexes) {
+		dst = make([]string, len(r.fieldIndexes))
+	}
+	dst = dst[:len(r.fieldIndexes)]
+	var preIdx int
+	for i, idx := range r.fieldIndexes {
+		dst[i] = str[preIdx:idx]
+		preIdx = idx
+	}
+
+	// Check or update the expected fields per record.
 	if r.FieldsPerRecord > 0 {
-		if len(record) != r.FieldsPerRecord {
-			r.column = 0 // report at start of record
-			return record, r.error(ErrFieldCount)
+		if len(dst) != r.FieldsPerRecord && err == nil {
+			err = &ParseError{StartLine: recLine, Line: recLine, Err: ErrFieldCount}
 		}
 	} else if r.FieldsPerRecord == 0 {
-		r.FieldsPerRecord = len(record)
+		r.FieldsPerRecord = len(dst)
 	}
-	return record, nil
-}
-
-// readRune reads one rune from r, folding \r\n to \n and keeping track
-// of how far into the line we have read.  r.column will point to the start
-// of this rune, not the end of this rune.
-func (r *Reader) readRune() (rune, error) {
-	r1, _, err := r.r.ReadRune()
-
-	// Handle \r\n here. We make the simplifying assumption that
-	// anytime \r is followed by \n that it can be folded to \n.
-	// We will not detect files which contain both \r\n and bare \n.
-	if r1 == '\r' {
-		r1, _, err = r.r.ReadRune()
-		if err == nil {
-			if r1 != '\n' {
-				r.r.UnreadRune()
-				r1 = '\r'
-			}
-		}
-	}
-	r.column++
-	return r1, err
-}
-
-// skip reads runes up to and including the rune delim or until error.
-func (r *Reader) skip(delim rune) error {
-	for {
-		r1, err := r.readRune()
-		if err != nil {
-			return err
-		}
-		if r1 == delim {
-			return nil
-		}
-	}
-}
-
-// parseRecord reads and parses a single csv record from r.
-// If dst has enough capacity it will be used for the returned fields.
-func (r *Reader) parseRecord(dst []string) (fields []string, err error) {
-	// Each record starts on a new line. We increment our line
-	// number (lines start at 1, not 0) and set column to -1
-	// so as we increment in readRune it points to the character we read.
-	r.line++
-	r.column = -1
-
-	// Peek at the first rune. If it is an error we are done.
-	// If we support comments and it is the comment character
-	// then skip to the end of line.
-
-	r1, _, err := r.r.ReadRune()
-	if err != nil {
-		return nil, err
-	}
-
-	if r.Comment != 0 && r1 == r.Comment {
-		return nil, r.skip('\n')
-	}
-	r.r.UnreadRune()
-
-	r.lineBuffer.Reset()
-	r.fieldIndexes = r.fieldIndexes[:0]
-
-	// At this point we have at least one field.
-	for {
-		idx := r.lineBuffer.Len()
-
-		haveField, delim, err := r.parseField()
-		if haveField {
-			r.fieldIndexes = append(r.fieldIndexes, idx)
-		}
-
-		if delim == '\n' || err == io.EOF {
-			if len(r.fieldIndexes) == 0 {
-				return nil, err
-			}
-			break
-		}
-
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	fieldCount := len(r.fieldIndexes)
-	// Using this approach (creating a single string and taking slices of it)
-	// means that a single reference to any of the fields will retain the whole
-	// string. The risk of a nontrivial space leak caused by this is considered
-	// minimal and a tradeoff for better performance through the combined
-	// allocations.
-	line := r.lineBuffer.String()
-
-	if cap(dst) >= fieldCount {
-		fields = dst[:fieldCount]
-	} else {
-		fields = make([]string, fieldCount)
-	}
-
-	for i, idx := range r.fieldIndexes {
-		if i == fieldCount-1 {
-			fields[i] = line[idx:]
-		} else {
-			fields[i] = line[idx:r.fieldIndexes[i+1]]
-		}
-	}
-
-	return fields, nil
-}
-
-// parseField parses the next field in the record. The read field is
-// appended to r.lineBuffer. Delim is the first character not part of the field
-// (r.Comma or '\n').
-func (r *Reader) parseField() (haveField bool, delim rune, err error) {
-	r1, err := r.readRune()
-	for err == nil && r.TrimLeadingSpace && r1 != '\n' && unicode.IsSpace(r1) {
-		r1, err = r.readRune()
-	}
-
-	if err == io.EOF && r.column != 0 {
-		return true, 0, err
-	}
-	if err != nil {
-		return false, 0, err
-	}
-
-	switch r1 {
-	case r.Comma:
-		// will check below
-
-	case '\n':
-		// We are a trailing empty field or a blank line
-		if r.column == 0 {
-			return false, r1, nil
-		}
-		return true, r1, nil
-
-	case '"':
-		// quoted field
-	Quoted:
-		for {
-			r1, err = r.readRune()
-			if err != nil {
-				if err == io.EOF {
-					if r.LazyQuotes {
-						return true, 0, err
-					}
-					return false, 0, r.error(ErrQuote)
-				}
-				return false, 0, err
-			}
-			switch r1 {
-			case '"':
-				r1, err = r.readRune()
-				if err != nil || r1 == r.Comma {
-					break Quoted
-				}
-				if r1 == '\n' {
-					return true, r1, nil
-				}
-				if r1 != '"' {
-					if !r.LazyQuotes {
-						r.column--
-						return false, 0, r.error(ErrQuote)
-					}
-					// accept the bare quote
-					r.lineBuffer.WriteRune('"')
-				}
-			case '\n':
-				r.line++
-				r.column = -1
-			}
-			r.lineBuffer.WriteRune(r1)
-		}
-
-	default:
-		// unquoted field
-		for {
-			r.lineBuffer.WriteRune(r1)
-			r1, err = r.readRune()
-			if err != nil || r1 == r.Comma {
-				break
-			}
-			if r1 == '\n' {
-				return true, r1, nil
-			}
-			if !r.LazyQuotes && r1 == '"' {
-				return false, 0, r.error(ErrBareQuote)
-			}
-		}
-	}
-
-	if err != nil {
-		if err == io.EOF {
-			return true, 0, err
-		}
-		return false, 0, err
-	}
-
-	return true, r1, nil
+	return dst, err
 }
diff --git a/src/encoding/csv/reader_test.go b/src/encoding/csv/reader_test.go
index 5ab1b61..1fc69f9 100644
--- a/src/encoding/csv/reader_test.go
+++ b/src/encoding/csv/reader_test.go
@@ -9,45 +9,38 @@
 	"reflect"
 	"strings"
 	"testing"
+	"unicode/utf8"
 )
 
-var readTests = []struct {
-	Name               string
-	Input              string
-	Output             [][]string
-	UseFieldsPerRecord bool // false (default) means FieldsPerRecord is -1
+func TestRead(t *testing.T) {
+	tests := []struct {
+		Name   string
+		Input  string
+		Output [][]string
+		Error  error
 
-	// These fields are copied into the Reader
-	Comma            rune
-	Comment          rune
-	FieldsPerRecord  int
-	LazyQuotes       bool
-	TrailingComma    bool
-	TrimLeadingSpace bool
-	ReuseRecord      bool
-
-	Error  string
-	Line   int // Expected error line if != 0
-	Column int // Expected error column if line != 0
-}{
-	{
+		// These fields are copied into the Reader
+		Comma              rune
+		Comment            rune
+		UseFieldsPerRecord bool // false (default) means FieldsPerRecord is -1
+		FieldsPerRecord    int
+		LazyQuotes         bool
+		TrimLeadingSpace   bool
+		ReuseRecord        bool
+	}{{
 		Name:   "Simple",
 		Input:  "a,b,c\n",
 		Output: [][]string{{"a", "b", "c"}},
-	},
-	{
+	}, {
 		Name:   "CRLF",
 		Input:  "a,b\r\nc,d\r\n",
 		Output: [][]string{{"a", "b"}, {"c", "d"}},
-	},
-	{
+	}, {
 		Name:   "BareCR",
 		Input:  "a,b\rc,d\r\n",
 		Output: [][]string{{"a", "b\rc", "d"}},
-	},
-	{
-		Name:               "RFC4180test",
-		UseFieldsPerRecord: true,
+	}, {
+		Name: "RFC4180test",
 		Input: `#field1,field2,field3
 "aaa","bb
 b","ccc"
@@ -60,163 +53,139 @@
 			{"a,a", `b"bb`, "ccc"},
 			{"zzz", "yyy", "xxx"},
 		},
-	},
-	{
+		UseFieldsPerRecord: true,
+		FieldsPerRecord:    0,
+	}, {
 		Name:   "NoEOLTest",
 		Input:  "a,b,c",
 		Output: [][]string{{"a", "b", "c"}},
-	},
-	{
+	}, {
 		Name:   "Semicolon",
-		Comma:  ';',
 		Input:  "a;b;c\n",
 		Output: [][]string{{"a", "b", "c"}},
-	},
-	{
+		Comma:  ';',
+	}, {
 		Name: "MultiLine",
 		Input: `"two
 line","one line","three
 line
 field"`,
 		Output: [][]string{{"two\nline", "one line", "three\nline\nfield"}},
-	},
-	{
+	}, {
 		Name:  "BlankLine",
 		Input: "a,b,c\n\nd,e,f\n\n",
 		Output: [][]string{
 			{"a", "b", "c"},
 			{"d", "e", "f"},
 		},
-	},
-	{
-		Name:               "BlankLineFieldCount",
-		Input:              "a,b,c\n\nd,e,f\n\n",
-		UseFieldsPerRecord: true,
+	}, {
+		Name:  "BlankLineFieldCount",
+		Input: "a,b,c\n\nd,e,f\n\n",
 		Output: [][]string{
 			{"a", "b", "c"},
 			{"d", "e", "f"},
 		},
-	},
-	{
+		UseFieldsPerRecord: true,
+		FieldsPerRecord:    0,
+	}, {
 		Name:             "TrimSpace",
 		Input:            " a,  b,   c\n",
-		TrimLeadingSpace: true,
 		Output:           [][]string{{"a", "b", "c"}},
-	},
-	{
+		TrimLeadingSpace: true,
+	}, {
 		Name:   "LeadingSpace",
 		Input:  " a,  b,   c\n",
 		Output: [][]string{{" a", "  b", "   c"}},
-	},
-	{
+	}, {
 		Name:    "Comment",
-		Comment: '#',
 		Input:   "#1,2,3\na,b,c\n#comment",
 		Output:  [][]string{{"a", "b", "c"}},
-	},
-	{
+		Comment: '#',
+	}, {
 		Name:   "NoComment",
 		Input:  "#1,2,3\na,b,c",
 		Output: [][]string{{"#1", "2", "3"}, {"a", "b", "c"}},
-	},
-	{
+	}, {
 		Name:       "LazyQuotes",
-		LazyQuotes: true,
 		Input:      `a "word","1"2",a","b`,
 		Output:     [][]string{{`a "word"`, `1"2`, `a"`, `b`}},
-	},
-	{
-		Name:       "BareQuotes",
 		LazyQuotes: true,
+	}, {
+		Name:       "BareQuotes",
 		Input:      `a "word","1"2",a"`,
 		Output:     [][]string{{`a "word"`, `1"2`, `a"`}},
-	},
-	{
-		Name:       "BareDoubleQuotes",
 		LazyQuotes: true,
+	}, {
+		Name:       "BareDoubleQuotes",
 		Input:      `a""b,c`,
 		Output:     [][]string{{`a""b`, `c`}},
-	},
-	{
+		LazyQuotes: true,
+	}, {
 		Name:  "BadDoubleQuotes",
 		Input: `a""b,c`,
-		Error: `bare " in non-quoted-field`, Line: 1, Column: 1,
-	},
-	{
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 1, Err: ErrBareQuote},
+	}, {
 		Name:             "TrimQuote",
 		Input:            ` "a"," b",c`,
-		TrimLeadingSpace: true,
 		Output:           [][]string{{"a", " b", "c"}},
-	},
-	{
+		TrimLeadingSpace: true,
+	}, {
 		Name:  "BadBareQuote",
 		Input: `a "word","b"`,
-		Error: `bare " in non-quoted-field`, Line: 1, Column: 2,
-	},
-	{
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 2, Err: ErrBareQuote},
+	}, {
 		Name:  "BadTrailingQuote",
 		Input: `"a word",b"`,
-		Error: `bare " in non-quoted-field`, Line: 1, Column: 10,
-	},
-	{
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 10, Err: ErrBareQuote},
+	}, {
 		Name:  "ExtraneousQuote",
 		Input: `"a "word","b"`,
-		Error: `extraneous " in field`, Line: 1, Column: 3,
-	},
-	{
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 3, Err: ErrQuote},
+	}, {
 		Name:               "BadFieldCount",
-		UseFieldsPerRecord: true,
 		Input:              "a,b,c\nd,e",
-		Error:              "wrong number of fields", Line: 2,
-	},
-	{
+		Error:              &ParseError{StartLine: 2, Line: 2, Err: ErrFieldCount},
+		UseFieldsPerRecord: true,
+		FieldsPerRecord:    0,
+	}, {
 		Name:               "BadFieldCount1",
+		Input:              `a,b,c`,
+		Error:              &ParseError{StartLine: 1, Line: 1, Err: ErrFieldCount},
 		UseFieldsPerRecord: true,
 		FieldsPerRecord:    2,
-		Input:              `a,b,c`,
-		Error:              "wrong number of fields", Line: 1,
-	},
-	{
+	}, {
 		Name:   "FieldCount",
 		Input:  "a,b,c\nd,e",
 		Output: [][]string{{"a", "b", "c"}, {"d", "e"}},
-	},
-	{
+	}, {
 		Name:   "TrailingCommaEOF",
 		Input:  "a,b,c,",
 		Output: [][]string{{"a", "b", "c", ""}},
-	},
-	{
+	}, {
 		Name:   "TrailingCommaEOL",
 		Input:  "a,b,c,\n",
 		Output: [][]string{{"a", "b", "c", ""}},
-	},
-	{
+	}, {
 		Name:             "TrailingCommaSpaceEOF",
-		TrimLeadingSpace: true,
 		Input:            "a,b,c, ",
 		Output:           [][]string{{"a", "b", "c", ""}},
-	},
-	{
-		Name:             "TrailingCommaSpaceEOL",
 		TrimLeadingSpace: true,
+	}, {
+		Name:             "TrailingCommaSpaceEOL",
 		Input:            "a,b,c, \n",
 		Output:           [][]string{{"a", "b", "c", ""}},
-	},
-	{
-		Name:             "TrailingCommaLine3",
 		TrimLeadingSpace: true,
+	}, {
+		Name:             "TrailingCommaLine3",
 		Input:            "a,b,c\nd,e,f\ng,hi,",
 		Output:           [][]string{{"a", "b", "c"}, {"d", "e", "f"}, {"g", "hi", ""}},
-	},
-	{
+		TrimLeadingSpace: true,
+	}, {
 		Name:   "NotTrailingComma3",
 		Input:  "a,b,c, \n",
 		Output: [][]string{{"a", "b", "c", " "}},
-	},
-	{
-		Name:          "CommaFieldTest",
-		TrailingComma: true,
+	}, {
+		Name: "CommaFieldTest",
 		Input: `x,y,z,w
 x,y,z,
 x,y,,
@@ -240,67 +209,201 @@
 			{"x", "", "", ""},
 			{"", "", "", ""},
 		},
-	},
-	{
-		Name:             "TrailingCommaIneffective1",
-		TrailingComma:    true,
-		TrimLeadingSpace: true,
-		Input:            "a,b,\nc,d,e",
+	}, {
+		Name:  "TrailingCommaIneffective1",
+		Input: "a,b,\nc,d,e",
 		Output: [][]string{
 			{"a", "b", ""},
 			{"c", "d", "e"},
 		},
-	},
-	{
-		Name:             "TrailingCommaIneffective2",
-		TrailingComma:    false,
 		TrimLeadingSpace: true,
-		Input:            "a,b,\nc,d,e",
-		Output: [][]string{
-			{"a", "b", ""},
-			{"c", "d", "e"},
-		},
-	},
-	{
-		Name:        "ReadAllReuseRecord",
-		ReuseRecord: true,
-		Input:       "a,b\nc,d",
+	}, {
+		Name:  "ReadAllReuseRecord",
+		Input: "a,b\nc,d",
 		Output: [][]string{
 			{"a", "b"},
 			{"c", "d"},
 		},
-	},
-}
+		ReuseRecord: true,
+	}, {
+		Name:  "StartLine1", // Issue 19019
+		Input: "a,\"b\nc\"d,e",
+		Error: &ParseError{StartLine: 1, Line: 2, Column: 1, Err: ErrQuote},
+	}, {
+		Name:  "StartLine2",
+		Input: "a,b\n\"d\n\n,e",
+		Error: &ParseError{StartLine: 2, Line: 5, Column: 0, Err: ErrQuote},
+	}, {
+		Name:  "CRLFInQuotedField", // Issue 21201
+		Input: "A,\"Hello\r\nHi\",B\r\n",
+		Output: [][]string{
+			{"A", "Hello\nHi", "B"},
+		},
+	}, {
+		Name:   "BinaryBlobField", // Issue 19410
+		Input:  "x09\x41\xb4\x1c,aktau",
+		Output: [][]string{{"x09A\xb4\x1c", "aktau"}},
+	}, {
+		Name:   "TrailingCR",
+		Input:  "field1,field2\r",
+		Output: [][]string{{"field1", "field2"}},
+	}, {
+		Name:   "QuotedTrailingCR",
+		Input:  "\"field\"\r",
+		Output: [][]string{{"field"}},
+	}, {
+		Name:  "QuotedTrailingCRCR",
+		Input: "\"field\"\r\r",
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 6, Err: ErrQuote},
+	}, {
+		Name:   "FieldCR",
+		Input:  "field\rfield\r",
+		Output: [][]string{{"field\rfield"}},
+	}, {
+		Name:   "FieldCRCR",
+		Input:  "field\r\rfield\r\r",
+		Output: [][]string{{"field\r\rfield\r"}},
+	}, {
+		Name:   "FieldCRCRLF",
+		Input:  "field\r\r\nfield\r\r\n",
+		Output: [][]string{{"field\r"}, {"field\r"}},
+	}, {
+		Name:   "FieldCRCRLFCR",
+		Input:  "field\r\r\n\rfield\r\r\n\r",
+		Output: [][]string{{"field\r"}, {"\rfield\r"}},
+	}, {
+		Name:   "FieldCRCRLFCRCR",
+		Input:  "field\r\r\n\r\rfield\r\r\n\r\r",
+		Output: [][]string{{"field\r"}, {"\r\rfield\r"}, {"\r"}},
+	}, {
+		Name:  "MultiFieldCRCRLFCRCR",
+		Input: "field1,field2\r\r\n\r\rfield1,field2\r\r\n\r\r,",
+		Output: [][]string{
+			{"field1", "field2\r"},
+			{"\r\rfield1", "field2\r"},
+			{"\r\r", ""},
+		},
+	}, {
+		Name:             "NonASCIICommaAndComment",
+		Input:            "a£b,c£ \td,e\n€ comment\n",
+		Output:           [][]string{{"a", "b,c", "d,e"}},
+		TrimLeadingSpace: true,
+		Comma:            '£',
+		Comment:          '€',
+	}, {
+		Name:    "NonASCIICommaAndCommentWithQuotes",
+		Input:   "a€\"  b,\"€ c\nλ comment\n",
+		Output:  [][]string{{"a", "  b,", " c"}},
+		Comma:   '€',
+		Comment: 'λ',
+	}, {
+		// λ and θ start with the same byte.
+		// This tests that the parser doesn't confuse such characters.
+		Name:    "NonASCIICommaConfusion",
+		Input:   "\"abθcd\"λefθgh",
+		Output:  [][]string{{"abθcd", "efθgh"}},
+		Comma:   'λ',
+		Comment: '€',
+	}, {
+		Name:    "NonASCIICommentConfusion",
+		Input:   "λ\nλ\nθ\nλ\n",
+		Output:  [][]string{{"λ"}, {"λ"}, {"λ"}},
+		Comment: 'θ',
+	}, {
+		Name:   "QuotedFieldMultipleLF",
+		Input:  "\"\n\n\n\n\"",
+		Output: [][]string{{"\n\n\n\n"}},
+	}, {
+		Name:  "MultipleCRLF",
+		Input: "\r\n\r\n\r\n\r\n",
+	}, {
+		// The implementation may read each line in several chunks if it doesn't fit entirely
+		// in the read buffer, so we should test the code to handle that condition.
+		Name:    "HugeLines",
+		Input:   strings.Repeat("#ignore\n", 10000) + strings.Repeat("@", 5000) + "," + strings.Repeat("*", 5000),
+		Output:  [][]string{{strings.Repeat("@", 5000), strings.Repeat("*", 5000)}},
+		Comment: '#',
+	}, {
+		Name:  "QuoteWithTrailingCRLF",
+		Input: "\"foo\"bar\"\r\n",
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 4, Err: ErrQuote},
+	}, {
+		Name:       "LazyQuoteWithTrailingCRLF",
+		Input:      "\"foo\"bar\"\r\n",
+		Output:     [][]string{{`foo"bar`}},
+		LazyQuotes: true,
+	}, {
+		Name:   "DoubleQuoteWithTrailingCRLF",
+		Input:  "\"foo\"\"bar\"\r\n",
+		Output: [][]string{{`foo"bar`}},
+	}, {
+		Name:   "EvenQuotes",
+		Input:  `""""""""`,
+		Output: [][]string{{`"""`}},
+	}, {
+		Name:  "OddQuotes",
+		Input: `"""""""`,
+		Error: &ParseError{StartLine: 1, Line: 1, Column: 7, Err: ErrQuote},
+	}, {
+		Name:       "LazyOddQuotes",
+		Input:      `"""""""`,
+		Output:     [][]string{{`"""`}},
+		LazyQuotes: true,
+	}, {
+		Name:  "BadComma1",
+		Comma: '\n',
+		Error: errInvalidDelim,
+	}, {
+		Name:  "BadComma2",
+		Comma: '\r',
+		Error: errInvalidDelim,
+	}, {
+		Name:  "BadComma3",
+		Comma: utf8.RuneError,
+		Error: errInvalidDelim,
+	}, {
+		Name:    "BadComment1",
+		Comment: '\n',
+		Error:   errInvalidDelim,
+	}, {
+		Name:    "BadComment2",
+		Comment: '\r',
+		Error:   errInvalidDelim,
+	}, {
+		Name:    "BadComment3",
+		Comment: utf8.RuneError,
+		Error:   errInvalidDelim,
+	}, {
+		Name:    "BadCommaComment",
+		Comma:   'X',
+		Comment: 'X',
+		Error:   errInvalidDelim,
+	}}
 
-func TestRead(t *testing.T) {
-	for _, tt := range readTests {
-		r := NewReader(strings.NewReader(tt.Input))
-		r.Comment = tt.Comment
-		if tt.UseFieldsPerRecord {
-			r.FieldsPerRecord = tt.FieldsPerRecord
-		} else {
-			r.FieldsPerRecord = -1
-		}
-		r.LazyQuotes = tt.LazyQuotes
-		r.TrailingComma = tt.TrailingComma
-		r.TrimLeadingSpace = tt.TrimLeadingSpace
-		r.ReuseRecord = tt.ReuseRecord
-		if tt.Comma != 0 {
-			r.Comma = tt.Comma
-		}
-		out, err := r.ReadAll()
-		perr, _ := err.(*ParseError)
-		if tt.Error != "" {
-			if err == nil || !strings.Contains(err.Error(), tt.Error) {
-				t.Errorf("%s: error %v, want error %q", tt.Name, err, tt.Error)
-			} else if tt.Line != 0 && (tt.Line != perr.Line || tt.Column != perr.Column) {
-				t.Errorf("%s: error at %d:%d expected %d:%d", tt.Name, perr.Line, perr.Column, tt.Line, tt.Column)
+	for _, tt := range tests {
+		t.Run(tt.Name, func(t *testing.T) {
+			r := NewReader(strings.NewReader(tt.Input))
+
+			if tt.Comma != 0 {
+				r.Comma = tt.Comma
 			}
-		} else if err != nil {
-			t.Errorf("%s: unexpected error %v", tt.Name, err)
-		} else if !reflect.DeepEqual(out, tt.Output) {
-			t.Errorf("%s: out=%q want %q", tt.Name, out, tt.Output)
-		}
+			r.Comment = tt.Comment
+			if tt.UseFieldsPerRecord {
+				r.FieldsPerRecord = tt.FieldsPerRecord
+			} else {
+				r.FieldsPerRecord = -1
+			}
+			r.LazyQuotes = tt.LazyQuotes
+			r.TrimLeadingSpace = tt.TrimLeadingSpace
+			r.ReuseRecord = tt.ReuseRecord
+
+			out, err := r.ReadAll()
+			if !reflect.DeepEqual(err, tt.Error) {
+				t.Errorf("ReadAll() error:\ngot  %v\nwant %v", err, tt.Error)
+			} else if !reflect.DeepEqual(out, tt.Output) {
+				t.Errorf("ReadAll() output:\ngot  %q\nwant %q", out, tt.Output)
+			}
+		})
 	}
 }
 
diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
index 84b7aa1..ef3594e 100644
--- a/src/encoding/csv/writer.go
+++ b/src/encoding/csv/writer.go
@@ -20,7 +20,7 @@
 //
 // Comma is the field delimiter.
 //
-// If UseCRLF is true, the Writer ends each record with \r\n instead of \n.
+// If UseCRLF is true, the Writer ends each output line 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
@@ -38,6 +38,10 @@
 // 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) error {
+	if !validDelim(w.Comma) {
+		return errInvalidDelim
+	}
+
 	for n, field := range record {
 		if n > 0 {
 			if _, err := w.w.WriteRune(w.Comma); err != nil {
diff --git a/src/encoding/gob/codec_test.go b/src/encoding/gob/codec_test.go
index eb9f306..8f7b6f3 100644
--- a/src/encoding/gob/codec_test.go
+++ b/src/encoding/gob/codec_test.go
@@ -1321,6 +1321,7 @@
 var singletons = []interface{}{
 	true,
 	7,
+	uint(10),
 	3.2,
 	"hello",
 	[3]int{11, 22, 33},
diff --git a/src/encoding/gob/debug.go b/src/encoding/gob/debug.go
index d69d36f..8f93742 100644
--- a/src/encoding/gob/debug.go
+++ b/src/encoding/gob/debug.go
@@ -594,7 +594,7 @@
 		x := deb.int64()
 		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
 	case tUint:
-		x := deb.int64()
+		x := deb.uint64()
 		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
 	case tFloat:
 		x := deb.uint64()
diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go
index 8dece42..2da913f 100644
--- a/src/encoding/gob/decode.go
+++ b/src/encoding/gob/decode.go
@@ -1038,6 +1038,8 @@
 
 // typeString returns a human-readable description of the type identified by remoteId.
 func (dec *Decoder) typeString(remoteId typeId) string {
+	typeLock.Lock()
+	defer typeLock.Unlock()
 	if t := idToType[remoteId]; t != nil {
 		// globally known type.
 		return t.string()
diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go
index 8e0b1dd..5ef0388 100644
--- a/src/encoding/gob/decoder.go
+++ b/src/encoding/gob/decoder.go
@@ -55,7 +55,7 @@
 
 // recvType loads the definition of a type.
 func (dec *Decoder) recvType(id typeId) {
-	// Have we already seen this type?  That's an error
+	// 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
@@ -99,10 +99,8 @@
 	// 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
-		}
+	if dec.err == io.EOF {
+		dec.err = io.ErrUnexpectedEOF
 	}
 }
 
diff --git a/src/encoding/gob/doc.go b/src/encoding/gob/doc.go
index db734ec..fa53431 100644
--- a/src/encoding/gob/doc.go
+++ b/src/encoding/gob/doc.go
@@ -381,7 +381,7 @@
 	07	// this value is 7 bytes long
 	ff 82	// the type number, 65 (1 byte (-FF) followed by 65<<1)
 	01	// add one to field number, yielding field 0
-	2c	// encoding of signed "22" (0x22 = 44 = 22<<1); Point.x = 22
+	2c	// encoding of signed "22" (0x2c = 44 = 22<<1); Point.x = 22
 	01	// add one to field number, yielding field 1
 	42	// encoding of signed "33" (0x42 = 66 = 33<<1); Point.y = 33
 	00	// end of structure
diff --git a/src/encoding/gob/type_test.go b/src/encoding/gob/type_test.go
index 14f25d8..934270e 100644
--- a/src/encoding/gob/type_test.go
+++ b/src/encoding/gob/type_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"reflect"
+	"sync"
 	"testing"
 )
 
@@ -218,3 +219,44 @@
 		<-c
 	}
 }
+
+// Issue 23328. Note that this test name is known to cmd/dist/test.go.
+func TestTypeRace(t *testing.T) {
+	c := make(chan bool)
+	var wg sync.WaitGroup
+	for i := 0; i < 2; i++ {
+		wg.Add(1)
+		go func(i int) {
+			defer wg.Done()
+			var buf bytes.Buffer
+			enc := NewEncoder(&buf)
+			dec := NewDecoder(&buf)
+			var x interface{}
+			switch i {
+			case 0:
+				x = &N1{}
+			case 1:
+				x = &N2{}
+			default:
+				t.Errorf("bad i %d", i)
+				return
+			}
+			m := make(map[string]string)
+			<-c
+			if err := enc.Encode(x); err != nil {
+				t.Error(err)
+				return
+			}
+			if err := enc.Encode(x); err != nil {
+				t.Error(err)
+				return
+			}
+			if err := dec.Decode(&m); err == nil {
+				t.Error("decode unexpectedly succeeded")
+				return
+			}
+		}(i)
+	}
+	close(c)
+	wg.Wait()
+}
diff --git a/src/encoding/hex/hex.go b/src/encoding/hex/hex.go
index 2768f1b..e4df6cb 100644
--- a/src/encoding/hex/hex.go
+++ b/src/encoding/hex/hex.go
@@ -31,7 +31,9 @@
 	return len(src) * 2
 }
 
-// ErrLength results from decoding an odd length slice.
+// ErrLength reports an attempt to decode an odd-length input
+// using Decode or DecodeString.
+// The stream-based Decoder returns io.ErrUnexpectedEOF instead of ErrLength.
 var ErrLength = errors.New("encoding/hex: odd length hex string")
 
 // InvalidByteError values describe errors resulting from an invalid byte in a hex string.
@@ -50,24 +52,30 @@
 //
 // Decode expects that src contain only hexadecimal
 // characters and that src should have an even length.
+// If the input is malformed, Decode returns the number
+// of bytes decoded before the error.
 func Decode(dst, src []byte) (int, error) {
-	if len(src)%2 == 1 {
-		return 0, ErrLength
-	}
-
-	for i := 0; i < len(src)/2; i++ {
+	var i int
+	for i = 0; i < len(src)/2; i++ {
 		a, ok := fromHexChar(src[i*2])
 		if !ok {
-			return 0, InvalidByteError(src[i*2])
+			return i, InvalidByteError(src[i*2])
 		}
 		b, ok := fromHexChar(src[i*2+1])
 		if !ok {
-			return 0, InvalidByteError(src[i*2+1])
+			return i, InvalidByteError(src[i*2+1])
 		}
 		dst[i] = (a << 4) | b
 	}
-
-	return len(src) / 2, nil
+	if len(src)%2 == 1 {
+		// Check for invalid char before reporting bad length,
+		// since the invalid char (if present) is an earlier problem.
+		if _, ok := fromHexChar(src[i*2]); !ok {
+			return i, InvalidByteError(src[i*2])
+		}
+		return i, ErrLength
+	}
+	return i, nil
 }
 
 // fromHexChar converts a hex character into its value and a success flag.
@@ -92,14 +100,17 @@
 }
 
 // DecodeString returns the bytes represented by the hexadecimal string s.
+//
+// DecodeString expects that src contain only hexadecimal
+// characters and that src should have an even length.
+// If the input is malformed, DecodeString returns a string
+// containing the bytes decoded before the error.
 func DecodeString(s string) ([]byte, error) {
 	src := []byte(s)
-	dst := make([]byte, DecodedLen(len(src)))
-	_, err := Decode(dst, src)
-	if err != nil {
-		return nil, err
-	}
-	return dst, nil
+	// We can use the source slice itself as the destination
+	// because the decode loop increments by one and then the 'seen' byte is not used anymore.
+	n, err := Decode(src, src)
+	return src[:n], err
 }
 
 // Dump returns a string that contains a hex dump of the given data. The format
@@ -112,6 +123,81 @@
 	return buf.String()
 }
 
+// bufferSize is the number of hexadecimal characters to buffer in encoder and decoder.
+const bufferSize = 1024
+
+type encoder struct {
+	w   io.Writer
+	err error
+	out [bufferSize]byte // output buffer
+}
+
+// NewEncoder returns an io.Writer that writes lowercase hexadecimal characters to w.
+func NewEncoder(w io.Writer) io.Writer {
+	return &encoder{w: w}
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+	for len(p) > 0 && e.err == nil {
+		chunkSize := bufferSize / 2
+		if len(p) < chunkSize {
+			chunkSize = len(p)
+		}
+
+		var written int
+		encoded := Encode(e.out[:], p[:chunkSize])
+		written, e.err = e.w.Write(e.out[:encoded])
+		n += written / 2
+		p = p[chunkSize:]
+	}
+	return n, e.err
+}
+
+type decoder struct {
+	r   io.Reader
+	err error
+	in  []byte           // input buffer (encoded form)
+	arr [bufferSize]byte // backing array for in
+}
+
+// NewDecoder returns an io.Reader that decodes hexadecimal characters from r.
+// NewDecoder expects that r contain only an even number of hexadecimal characters.
+func NewDecoder(r io.Reader) io.Reader {
+	return &decoder{r: r}
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+	// Fill internal buffer with sufficient bytes to decode
+	if len(d.in) < 2 && d.err == nil {
+		var numCopy, numRead int
+		numCopy = copy(d.arr[:], d.in) // Copies either 0 or 1 bytes
+		numRead, d.err = d.r.Read(d.arr[numCopy:])
+		d.in = d.arr[:numCopy+numRead]
+		if d.err == io.EOF && len(d.in)%2 != 0 {
+			if _, ok := fromHexChar(d.in[len(d.in)-1]); !ok {
+				d.err = InvalidByteError(d.in[len(d.in)-1])
+			} else {
+				d.err = io.ErrUnexpectedEOF
+			}
+		}
+	}
+
+	// Decode internal buffer into output buffer
+	if numAvail := len(d.in) / 2; len(p) > numAvail {
+		p = p[:numAvail]
+	}
+	numDec, err := Decode(p, d.in[:len(p)*2])
+	d.in = d.in[2*numDec:]
+	if err != nil {
+		d.in, d.err = nil, err // Decode error; discard input remainder
+	}
+
+	if len(d.in) < 2 {
+		return numDec, d.err // Only expose errors when buffer fully consumed
+	}
+	return numDec, nil
+}
+
 // Dumper returns a WriteCloser that writes a hex dump of all written data to
 // w. The format of the dump matches the output of `hexdump -C` on the command
 // line.
diff --git a/src/encoding/hex/hex_test.go b/src/encoding/hex/hex_test.go
index 64dabbd..b6bab21 100644
--- a/src/encoding/hex/hex_test.go
+++ b/src/encoding/hex/hex_test.go
@@ -7,6 +7,9 @@
 import (
 	"bytes"
 	"fmt"
+	"io"
+	"io/ioutil"
+	"strings"
 	"testing"
 )
 
@@ -75,37 +78,86 @@
 	}
 }
 
-type errTest struct {
+var errTests = []struct {
 	in  string
-	err string
+	out string
+	err error
+}{
+	{"", "", nil},
+	{"0", "", ErrLength},
+	{"zd4aa", "", InvalidByteError('z')},
+	{"d4aaz", "\xd4\xaa", InvalidByteError('z')},
+	{"30313", "01", ErrLength},
+	{"0g", "", InvalidByteError('g')},
+	{"00gg", "\x00", InvalidByteError('g')},
+	{"0\x01", "", InvalidByteError('\x01')},
+	{"ffeed", "\xff\xee", ErrLength},
 }
 
-var errTests = []errTest{
-	{"0", "encoding/hex: odd length hex string"},
-	{"0g", "encoding/hex: invalid byte: U+0067 'g'"},
-	{"00gg", "encoding/hex: invalid byte: U+0067 'g'"},
-	{"0\x01", "encoding/hex: invalid byte: U+0001"},
-}
-
-func TestInvalidErr(t *testing.T) {
-	for i, test := range errTests {
-		dst := make([]byte, DecodedLen(len(test.in)))
-		_, err := Decode(dst, []byte(test.in))
-		if err == nil {
-			t.Errorf("#%d: expected error; got none", i)
-		} else if err.Error() != test.err {
-			t.Errorf("#%d: got: %v want: %v", i, err, test.err)
+func TestDecodeErr(t *testing.T) {
+	for _, tt := range errTests {
+		out := make([]byte, len(tt.in)+10)
+		n, err := Decode(out, []byte(tt.in))
+		if string(out[:n]) != tt.out || err != tt.err {
+			t.Errorf("Decode(%q) = %q, %v, want %q, %v", tt.in, string(out[:n]), err, tt.out, tt.err)
 		}
 	}
 }
 
-func TestInvalidStringErr(t *testing.T) {
-	for i, test := range errTests {
-		_, err := DecodeString(test.in)
-		if err == nil {
-			t.Errorf("#%d: expected error; got none", i)
-		} else if err.Error() != test.err {
-			t.Errorf("#%d: got: %v want: %v", i, err, test.err)
+func TestDecodeStringErr(t *testing.T) {
+	for _, tt := range errTests {
+		out, err := DecodeString(tt.in)
+		if string(out) != tt.out || err != tt.err {
+			t.Errorf("DecodeString(%q) = %q, %v, want %q, %v", tt.in, out, err, tt.out, tt.err)
+		}
+	}
+}
+
+func TestEncoderDecoder(t *testing.T) {
+	for _, multiplier := range []int{1, 128, 192} {
+		for _, test := range encDecTests {
+			input := bytes.Repeat(test.dec, multiplier)
+			output := strings.Repeat(test.enc, multiplier)
+
+			var buf bytes.Buffer
+			enc := NewEncoder(&buf)
+			r := struct{ io.Reader }{bytes.NewReader(input)} // io.Reader only; not io.WriterTo
+			if n, err := io.CopyBuffer(enc, r, make([]byte, 7)); n != int64(len(input)) || err != nil {
+				t.Errorf("encoder.Write(%q*%d) = (%d, %v), want (%d, nil)", test.dec, multiplier, n, err, len(input))
+				continue
+			}
+
+			if encDst := buf.String(); encDst != output {
+				t.Errorf("buf(%q*%d) = %v, want %v", test.dec, multiplier, encDst, output)
+				continue
+			}
+
+			dec := NewDecoder(&buf)
+			var decBuf bytes.Buffer
+			w := struct{ io.Writer }{&decBuf} // io.Writer only; not io.ReaderFrom
+			if _, err := io.CopyBuffer(w, dec, make([]byte, 7)); err != nil || decBuf.Len() != len(input) {
+				t.Errorf("decoder.Read(%q*%d) = (%d, %v), want (%d, nil)", test.enc, multiplier, decBuf.Len(), err, len(input))
+			}
+
+			if !bytes.Equal(decBuf.Bytes(), input) {
+				t.Errorf("decBuf(%q*%d) = %v, want %v", test.dec, multiplier, decBuf.Bytes(), input)
+				continue
+			}
+		}
+	}
+}
+
+func TestDecoderErr(t *testing.T) {
+	for _, tt := range errTests {
+		dec := NewDecoder(strings.NewReader(tt.in))
+		out, err := ioutil.ReadAll(dec)
+		wantErr := tt.err
+		// Decoder is reading from stream, so it reports io.ErrUnexpectedEOF instead of ErrLength.
+		if wantErr == ErrLength {
+			wantErr = io.ErrUnexpectedEOF
+		}
+		if string(out) != tt.out || err != wantErr {
+			t.Errorf("NewDecoder(%q) = %q, %v, want %q, %v", tt.in, out, err, tt.out, wantErr)
 		}
 	}
 }
diff --git a/src/encoding/json/bench_test.go b/src/encoding/json/bench_test.go
index 85d7ae0..42439eb 100644
--- a/src/encoding/json/bench_test.go
+++ b/src/encoding/json/bench_test.go
@@ -133,6 +133,21 @@
 	b.SetBytes(int64(len(codeJSON)))
 }
 
+func BenchmarkUnicodeDecoder(b *testing.B) {
+	j := []byte(`"\uD83D\uDE01"`)
+	b.SetBytes(int64(len(j)))
+	r := bytes.NewReader(j)
+	dec := NewDecoder(r)
+	var out string
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if err := dec.Decode(&out); err != nil {
+			b.Fatal("Decode:", err)
+		}
+		r.Seek(0, 0)
+	}
+}
+
 func BenchmarkDecoderStream(b *testing.B) {
 	b.StopTimer()
 	var buf bytes.Buffer
diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go
index 420a07e..536f25d 100644
--- a/src/encoding/json/decode.go
+++ b/src/encoding/json/decode.go
@@ -44,8 +44,9 @@
 //
 // 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.
-// Unmarshal will only set exported fields of the struct.
+// preferring an exact match but also accepting a case-insensitive match. By
+// default, object keys which don't have a corresponding struct field are
+// ignored (see Decoder.DisallowUnknownFields for an alternative).
 //
 // To unmarshal JSON into an interface value,
 // Unmarshal stores one of these in the interface value:
@@ -138,7 +139,8 @@
 
 // An UnmarshalFieldError describes a JSON object key that
 // led to an unexported (and therefore unwritable) struct field.
-// (No longer used; kept for compatibility.)
+//
+// Deprecated: No longer used; kept for compatibility.
 type UnmarshalFieldError struct {
 	Key   string
 	Type  reflect.Type
@@ -274,8 +276,9 @@
 		Struct string
 		Field  string
 	}
-	savedError error
-	useNumber  bool
+	savedError            error
+	useNumber             bool
+	disallowUnknownFields bool
 }
 
 // errPhase is used for errors that should not happen unless
@@ -508,7 +511,7 @@
 	switch v.Kind() {
 	case reflect.Interface:
 		if v.NumMethod() == 0 {
-			// Decoding into nil interface?  Switch to non-reflect code.
+			// Decoding into nil interface? Switch to non-reflect code.
 			v.Set(reflect.ValueOf(d.arrayInterface()))
 			return
 		}
@@ -612,7 +615,7 @@
 	}
 	v = pv
 
-	// Decoding into nil interface?  Switch to non-reflect code.
+	// Decoding into nil interface? Switch to non-reflect code.
 	if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
 		v.Set(reflect.ValueOf(d.objectInterface()))
 		return
@@ -704,6 +707,19 @@
 				for _, i := range f.index {
 					if subv.Kind() == reflect.Ptr {
 						if subv.IsNil() {
+							// If a struct embeds a pointer to an unexported type,
+							// it is not possible to set a newly allocated value
+							// since the field is unexported.
+							//
+							// See https://golang.org/issue/21357
+							if !subv.CanSet() {
+								d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem()))
+								// Invalidate subv to ensure d.value(subv) skips over
+								// the JSON value without assigning it to subv.
+								subv = reflect.Value{}
+								destring = false
+								break
+							}
 							subv.Set(reflect.New(subv.Type().Elem()))
 						}
 						subv = subv.Elem()
@@ -712,6 +728,8 @@
 				}
 				d.errorContext.Field = f.name
 				d.errorContext.Struct = v.Type().Name()
+			} else if d.disallowUnknownFields {
+				d.saveError(fmt.Errorf("json: unknown field %q", key))
 			}
 		}
 
@@ -1143,11 +1161,21 @@
 	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
+	var r rune
+	for _, c := range s[2:6] {
+		switch {
+		case '0' <= c && c <= '9':
+			c = c - '0'
+		case 'a' <= c && c <= 'f':
+			c = c - 'a' + 10
+		case 'A' <= c && c <= 'F':
+			c = c - 'A' + 10
+		default:
+			return -1
+		}
+		r = r*16 + rune(c)
 	}
-	return rune(r)
+	return r
 }
 
 // unquote converts a quoted JSON string literal s into an actual string t.
@@ -1190,7 +1218,7 @@
 	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
+		// 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 {
diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go
index bd38ddd..34b7ec6 100644
--- a/src/encoding/json/decode_test.go
+++ b/src/encoding/json/decode_test.go
@@ -88,7 +88,7 @@
 }
 
 func (u *unmarshalerText) UnmarshalText(b []byte) error {
-	pos := bytes.Index(b, []byte(":"))
+	pos := bytes.IndexByte(b, ':')
 	if pos == -1 {
 		return errors.New("missing separator")
 	}
@@ -372,12 +372,13 @@
 }
 
 type unmarshalTest struct {
-	in        string
-	ptr       interface{}
-	out       interface{}
-	err       error
-	useNumber bool
-	golden    bool
+	in                    string
+	ptr                   interface{}
+	out                   interface{}
+	err                   error
+	useNumber             bool
+	golden                bool
+	disallowUnknownFields bool
 }
 
 type B struct {
@@ -401,6 +402,7 @@
 	{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(""), 7, "T", "X"}},
 	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
+	{in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true},
 	{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},
@@ -415,10 +417,13 @@
 
 	// Z has a "-" tag.
 	{in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},
+	{in: `{"Y": 1, "Z": 2}`, ptr: new(T), err: fmt.Errorf("json: unknown field \"Z\""), disallowUnknownFields: true},
 
 	{in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},
+	{in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true},
 	{in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},
 	{in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},
+	{in: `{"alphabet": "xyz"}`, ptr: new(U), err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true},
 
 	// syntax errors
 	{in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}},
@@ -611,9 +616,21 @@
 	},
 	{
 		in:  `{"X": 1,"Y":2}`,
+		ptr: new(S5),
+		err: fmt.Errorf("json: unknown field \"X\""),
+		disallowUnknownFields: true,
+	},
+	{
+		in:  `{"X": 1,"Y":2}`,
 		ptr: new(S10),
 		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
 	},
+	{
+		in:  `{"X": 1,"Y":2}`,
+		ptr: new(S10),
+		err: fmt.Errorf("json: unknown field \"X\""),
+		disallowUnknownFields: true,
+	},
 
 	// invalid UTF-8 is coerced to valid UTF-8.
 	{
@@ -793,6 +810,62 @@
 	{in: `{"B": "False"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "False" into bool`)},
 	{in: `{"B": "null"}`, ptr: new(B), out: B{false}},
 	{in: `{"B": "nul"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "nul" into bool`)},
+
+	// additional tests for disallowUnknownFields
+	{
+		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,
+			"Q": 18,
+			"extra": true
+		}`,
+		ptr: new(Top),
+		err: fmt.Errorf("json: unknown field \"extra\""),
+		disallowUnknownFields: true,
+	},
+	{
+		in: `{
+			"Level0": 1,
+			"Level1b": 2,
+			"Level1c": 3,
+			"x": 4,
+			"Level1a": 5,
+			"LEVEL1B": 6,
+			"e": {
+				"Level1a": 8,
+				"Level1b": 9,
+				"Level1c": 10,
+				"Level1d": 11,
+				"x": 12,
+				"extra": null
+			},
+			"Loop1": 13,
+			"Loop2": 14,
+			"X": 15,
+			"Y": 16,
+			"Z": 17,
+			"Q": 18
+		}`,
+		ptr: new(Top),
+		err: fmt.Errorf("json: unknown field \"extra\""),
+		disallowUnknownFields: true,
+	},
 }
 
 func TestMarshal(t *testing.T) {
@@ -911,6 +984,9 @@
 		if tt.useNumber {
 			dec.UseNumber()
 		}
+		if tt.disallowUnknownFields {
+			dec.DisallowUnknownFields()
+		}
 		if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) {
 			t.Errorf("#%d: %v, want %v", i, err, tt.err)
 			continue
@@ -1117,7 +1193,8 @@
 	Foo  string `json:"bar"`
 	Foo2 string `json:"bar2,dummyopt"`
 
-	IntStr int64 `json:",string"`
+	IntStr     int64   `json:",string"`
+	UintptrStr uintptr `json:",string"`
 
 	PBool    *bool
 	PInt     *int
@@ -1171,24 +1248,25 @@
 }
 
 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",
+	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,
+	UintptrStr: 44,
+	String:     "16",
 	Map: map[string]Small{
 		"17": {Tag: "tag17"},
 		"18": {Tag: "tag18"},
@@ -1250,6 +1328,7 @@
 	"bar": "foo",
 	"bar2": "foo2",
 	"IntStr": "42",
+	"UintptrStr": "44",
 	"PBool": null,
 	"PInt": null,
 	"PInt8": null,
@@ -1342,6 +1421,7 @@
 	"bar": "",
 	"bar2": "",
         "IntStr": "0",
+	"UintptrStr": "0",
 	"PBool": true,
 	"PInt": 2,
 	"PInt8": 3,
@@ -2008,3 +2088,81 @@
 		t.Fatalf("Unmarshal: %v", err)
 	}
 }
+
+// Test unmarshal behavior with regards to embedded pointers to unexported structs.
+// If unallocated, this returns an error because unmarshal cannot set the field.
+// Issue 21357.
+func TestUnmarshalEmbeddedPointerUnexported(t *testing.T) {
+	type (
+		embed1 struct{ Q int }
+		embed2 struct{ Q int }
+		embed3 struct {
+			Q int64 `json:",string"`
+		}
+		S1 struct {
+			*embed1
+			R int
+		}
+		S2 struct {
+			*embed1
+			Q int
+		}
+		S3 struct {
+			embed1
+			R int
+		}
+		S4 struct {
+			*embed1
+			embed2
+		}
+		S5 struct {
+			*embed3
+			R int
+		}
+	)
+
+	tests := []struct {
+		in  string
+		ptr interface{}
+		out interface{}
+		err error
+	}{{
+		// Error since we cannot set S1.embed1, but still able to set S1.R.
+		in:  `{"R":2,"Q":1}`,
+		ptr: new(S1),
+		out: &S1{R: 2},
+		err: fmt.Errorf("json: cannot set embedded pointer to unexported struct: json.embed1"),
+	}, {
+		// The top level Q field takes precedence.
+		in:  `{"Q":1}`,
+		ptr: new(S2),
+		out: &S2{Q: 1},
+	}, {
+		// No issue with non-pointer variant.
+		in:  `{"R":2,"Q":1}`,
+		ptr: new(S3),
+		out: &S3{embed1: embed1{Q: 1}, R: 2},
+	}, {
+		// No error since both embedded structs have field R, which annihilate each other.
+		// Thus, no attempt is made at setting S4.embed1.
+		in:  `{"R":2}`,
+		ptr: new(S4),
+		out: new(S4),
+	}, {
+		// Error since we cannot set S5.embed1, but still able to set S5.R.
+		in:  `{"R":2,"Q":1}`,
+		ptr: new(S5),
+		out: &S5{R: 2},
+		err: fmt.Errorf("json: cannot set embedded pointer to unexported struct: json.embed3"),
+	}}
+
+	for i, tt := range tests {
+		err := Unmarshal([]byte(tt.in), tt.ptr)
+		if !reflect.DeepEqual(err, tt.err) {
+			t.Errorf("#%d: %v, want %v", i, err, tt.err)
+		}
+		if !reflect.DeepEqual(tt.ptr, tt.out) {
+			t.Errorf("#%d: mismatch\ngot:  %#+v\nwant: %#+v", i, tt.ptr, tt.out)
+		}
+	}
+}
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index 0371f0a..1e45e44 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Package json implements encoding and decoding of JSON as defined in
-// RFC 4627. The mapping between JSON and Go values is described
+// RFC 7159. The mapping between JSON and Go values is described
 // in the documentation for the Marshal and Unmarshal functions.
 //
 // See "JSON and Go" for an introduction to this package:
@@ -166,6 +166,8 @@
 }
 
 // MarshalIndent is like Marshal but applies Indent to format the output.
+// Each JSON element in the output will begin on a new line beginning with prefix
+// followed by one or more copies of indent according to the indentation nesting.
 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
 	b, err := Marshal(v)
 	if err != nil {
@@ -243,8 +245,8 @@
 // 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.
+//
+// Deprecated: No longer used; kept for compatibility.
 type InvalidUTF8Error struct {
 	S string // the whole string value that caused the error
 }
@@ -871,8 +873,7 @@
 }
 
 // NOTE: keep in sync with stringBytes below.
-func (e *encodeState) string(s string, escapeHTML bool) int {
-	len0 := e.Len()
+func (e *encodeState) string(s string, escapeHTML bool) {
 	e.WriteByte('"')
 	start := 0
 	for i := 0; i < len(s); {
@@ -944,12 +945,10 @@
 		e.WriteString(s[start:])
 	}
 	e.WriteByte('"')
-	return e.Len() - len0
 }
 
 // NOTE: keep in sync with string above.
-func (e *encodeState) stringBytes(s []byte, escapeHTML bool) int {
-	len0 := e.Len()
+func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
 	e.WriteByte('"')
 	start := 0
 	for i := 0; i < len(s); {
@@ -1021,7 +1020,6 @@
 		e.Write(s[start:])
 	}
 	e.WriteByte('"')
-	return e.Len() - len0
 }
 
 // A field represents a single field found in a struct.
@@ -1093,21 +1091,19 @@
 			// Scan f.typ for fields to include.
 			for i := 0; i < f.typ.NumField(); i++ {
 				sf := f.typ.Field(i)
+				isUnexported := sf.PkgPath != ""
 				if sf.Anonymous {
 					t := sf.Type
 					if t.Kind() == reflect.Ptr {
 						t = t.Elem()
 					}
-					// If embedded, StructField.PkgPath is not a reliable
-					// indicator of whether the field is exported.
-					// See https://golang.org/issue/21122
-					if !isExported(t.Name()) && t.Kind() != reflect.Struct {
+					if isUnexported && t.Kind() != reflect.Struct {
 						// Ignore embedded fields of unexported non-struct types.
-						// Do not ignore embedded fields of unexported struct types
-						// since they may have exported fields.
 						continue
 					}
-				} else if sf.PkgPath != "" {
+					// Do not ignore embedded fields of unexported struct types
+					// since they may have exported fields.
+				} else if isUnexported {
 					// Ignore unexported non-embedded fields.
 					continue
 				}
@@ -1135,7 +1131,7 @@
 					switch ft.Kind() {
 					case reflect.Bool,
 						reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-						reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+						reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
 						reflect.Float32, reflect.Float64,
 						reflect.String:
 						quoted = true
@@ -1226,12 +1222,6 @@
 	return fields
 }
 
-// isExported reports whether the identifier is exported.
-func isExported(id string) bool {
-	r, _ := utf8.DecodeRuneInString(id)
-	return unicode.IsUpper(r)
-}
-
 // 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
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
index 3fda6a0..0f194e1 100644
--- a/src/encoding/json/encode_test.go
+++ b/src/encoding/json/encode_test.go
@@ -71,14 +71,16 @@
 }
 
 type StringTag struct {
-	BoolStr bool   `json:",string"`
-	IntStr  int64  `json:",string"`
-	StrStr  string `json:",string"`
+	BoolStr    bool    `json:",string"`
+	IntStr     int64   `json:",string"`
+	UintptrStr uintptr `json:",string"`
+	StrStr     string  `json:",string"`
 }
 
 var stringTagExpected = `{
  "BoolStr": "true",
  "IntStr": "42",
+ "UintptrStr": "44",
  "StrStr": "\"xzbit\""
 }`
 
@@ -86,6 +88,7 @@
 	var s StringTag
 	s.BoolStr = true
 	s.IntStr = 42
+	s.UintptrStr = 44
 	s.StrStr = "xzbit"
 	got, err := MarshalIndent(&s, "", " ")
 	if err != nil {
@@ -943,7 +946,7 @@
 		//
 		// The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo".
 		// This behavior was intentionally changed in Go 1.8.
-		// See https://github.com/golang/go/issues/14493#issuecomment-255857318
+		// See https://golang.org/issues/14493#issuecomment-255857318
 		{rawText, `"foo"`, true}, // Issue6458
 		{&rawText, `"foo"`, true},
 		{[]interface{}{rawText}, `["foo"]`, true},  // Issue6458
diff --git a/src/encoding/json/example_test.go b/src/encoding/json/example_test.go
index fa1846b..39b3231 100644
--- a/src/encoding/json/example_test.go
+++ b/src/encoding/json/example_test.go
@@ -36,9 +36,9 @@
 
 func ExampleUnmarshal() {
 	var jsonBlob = []byte(`[
-		{"Name": "Platypus", "Order": "Monotremata"},
-		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
-	]`)
+	{"Name": "Platypus", "Order": "Monotremata"},
+	{"Name": "Quoll",    "Order": "Dasyuromorphia"}
+]`)
 	type Animal struct {
 		Name  string
 		Order string
@@ -56,12 +56,12 @@
 // This example uses a Decoder to decode a stream of distinct JSON values.
 func ExampleDecoder() {
 	const jsonStream = `
-		{"Name": "Ed", "Text": "Knock knock."}
-		{"Name": "Sam", "Text": "Who's there?"}
-		{"Name": "Ed", "Text": "Go fmt."}
-		{"Name": "Sam", "Text": "Go fmt who?"}
-		{"Name": "Ed", "Text": "Go fmt yourself!"}
-	`
+	{"Name": "Ed", "Text": "Knock knock."}
+	{"Name": "Sam", "Text": "Who's there?"}
+	{"Name": "Ed", "Text": "Go fmt."}
+	{"Name": "Sam", "Text": "Go fmt who?"}
+	{"Name": "Ed", "Text": "Go fmt yourself!"}
+`
 	type Message struct {
 		Name, Text string
 	}
@@ -86,8 +86,8 @@
 // This example uses a Decoder to decode a stream of distinct JSON values.
 func ExampleDecoder_Token() {
 	const jsonStream = `
-		{"Message": "Hello", "Array": [1, 2, 3], "Null": null, "Number": 1.234}
-	`
+	{"Message": "Hello", "Array": [1, 2, 3], "Null": null, "Number": 1.234}
+`
 	dec := json.NewDecoder(strings.NewReader(jsonStream))
 	for {
 		t, err := dec.Token()
@@ -191,9 +191,9 @@
 	}
 
 	var j = []byte(`[
-		{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
-		{"Space": "RGB",   "Point": {"R": 98, "G": 218, "B": 255}}
-	]`)
+	{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
+	{"Space": "RGB",   "Point": {"R": 98, "G": 218, "B": 255}}
+]`)
 	var colors []Color
 	err := json.Unmarshal(j, &colors)
 	if err != nil {
@@ -273,3 +273,22 @@
 	// =	}
 	// =]
 }
+
+func ExampleMarshalIndent() {
+	data := map[string]int{
+		"a": 1,
+		"b": 2,
+	}
+
+	json, err := json.MarshalIndent(data, "<prefix>", "<indent>")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Println(string(json))
+	// Output:
+	// {
+	// <prefix><indent>"a": 1,
+	// <prefix><indent>"b": 2
+	// <prefix>}
+}
diff --git a/src/encoding/json/stream.go b/src/encoding/json/stream.go
index 95e30ce..75a4270 100644
--- a/src/encoding/json/stream.go
+++ b/src/encoding/json/stream.go
@@ -12,12 +12,13 @@
 
 // A Decoder reads and decodes JSON values from an input stream.
 type Decoder struct {
-	r     io.Reader
-	buf   []byte
-	d     decodeState
-	scanp int // start of unread data in buf
-	scan  scanner
-	err   error
+	r       io.Reader
+	buf     []byte
+	d       decodeState
+	scanp   int   // start of unread data in buf
+	scanned int64 // amount of data already scanned
+	scan    scanner
+	err     error
 
 	tokenState int
 	tokenStack []int
@@ -35,6 +36,11 @@
 // Number instead of as a float64.
 func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
 
+// DisallowUnknownFields causes the Decoder to return an error when the destination
+// is a struct and the input contains object keys which do not match any
+// non-ignored, exported fields in the destination.
+func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
+
 // Decode reads the next JSON-encoded value from its
 // input and stores it in the value pointed to by v.
 //
@@ -50,7 +56,7 @@
 	}
 
 	if !dec.tokenValueAllowed() {
-		return &SyntaxError{msg: "not at beginning of value"}
+		return &SyntaxError{msg: "not at beginning of value", Offset: dec.offset()}
 	}
 
 	// Read whole value into buffer.
@@ -135,6 +141,7 @@
 	// Make room to read more into the buffer.
 	// First slide down data already consumed.
 	if dec.scanp > 0 {
+		dec.scanned += int64(dec.scanp)
 		n := copy(dec.buf, dec.buf[dec.scanp:])
 		dec.buf = dec.buf[:n]
 		dec.scanp = 0
@@ -301,7 +308,7 @@
 			return err
 		}
 		if c != ',' {
-			return &SyntaxError{"expected comma after array element", 0}
+			return &SyntaxError{"expected comma after array element", dec.offset()}
 		}
 		dec.scanp++
 		dec.tokenState = tokenArrayValue
@@ -311,7 +318,7 @@
 			return err
 		}
 		if c != ':' {
-			return &SyntaxError{"expected colon after object key", 0}
+			return &SyntaxError{"expected colon after object key", dec.offset()}
 		}
 		dec.scanp++
 		dec.tokenState = tokenObjectValue
@@ -428,7 +435,6 @@
 				err := dec.Decode(&x)
 				dec.tokenState = old
 				if err != nil {
-					clearOffset(err)
 					return nil, err
 				}
 				dec.tokenState = tokenObjectColon
@@ -442,7 +448,6 @@
 			}
 			var x interface{}
 			if err := dec.Decode(&x); err != nil {
-				clearOffset(err)
 				return nil, err
 			}
 			return x, nil
@@ -450,12 +455,6 @@
 	}
 }
 
-func clearOffset(err error) {
-	if s, ok := err.(*SyntaxError); ok {
-		s.Offset = 0
-	}
-}
-
 func (dec *Decoder) tokenError(c byte) (Token, error) {
 	var context string
 	switch dec.tokenState {
@@ -472,7 +471,7 @@
 	case tokenObjectComma:
 		context = " after object key:value pair"
 	}
-	return nil, &SyntaxError{"invalid character " + quoteChar(c) + " " + context, 0}
+	return nil, &SyntaxError{"invalid character " + quoteChar(c) + " " + context, dec.offset()}
 }
 
 // More reports whether there is another element in the
@@ -501,19 +500,6 @@
 	}
 }
 
-/*
-TODO
-
-// EncodeToken writes the given JSON token to the stream.
-// It returns an error if the delimiters [ ] { } are not properly used.
-//
-// EncodeToken does not call Flush, because usually it is part of
-// a larger operation such as Encode, and those will call Flush when finished.
-// Callers that create an Encoder and then invoke EncodeToken directly,
-// without using Encode, need to call Flush when finished to ensure that
-// the JSON is written to the underlying writer.
-func (e *Encoder) EncodeToken(t Token) error  {
-	...
+func (dec *Decoder) offset() int64 {
+	return dec.scanned + int64(dec.scanp)
 }
-
-*/
diff --git a/src/encoding/json/stream_test.go b/src/encoding/json/stream_test.go
index d0b3ffb..83c01d1 100644
--- a/src/encoding/json/stream_test.go
+++ b/src/encoding/json/stream_test.go
@@ -342,11 +342,18 @@
 	{json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
 		Delim('['),
 		decodeThis{map[string]interface{}{"a": float64(1)}},
-		decodeThis{&SyntaxError{"expected comma after array element", 0}},
+		decodeThis{&SyntaxError{"expected comma after array element", 11}},
 	}},
-	{json: `{ "a" 1 }`, expTokens: []interface{}{
-		Delim('{'), "a",
-		decodeThis{&SyntaxError{"expected colon after object key", 0}},
+	{json: `{ "` + strings.Repeat("a", 513) + `" 1 }`, expTokens: []interface{}{
+		Delim('{'), strings.Repeat("a", 513),
+		decodeThis{&SyntaxError{"expected colon after object key", 518}},
+	}},
+	{json: `{ "\a" }`, expTokens: []interface{}{
+		Delim('{'),
+		&SyntaxError{"invalid character 'a' in string escape code", 3},
+	}},
+	{json: ` \a`, expTokens: []interface{}{
+		&SyntaxError{"invalid character '\\\\' looking for beginning of value", 1},
 	}},
 }
 
@@ -367,15 +374,15 @@
 				tk, err = dec.Token()
 			}
 			if experr, ok := etk.(error); ok {
-				if err == nil || err.Error() != experr.Error() {
-					t.Errorf("case %v: Expected error %v in %q, but was %v", ci, experr, tcase.json, err)
+				if err == nil || !reflect.DeepEqual(err, experr) {
+					t.Errorf("case %v: Expected error %#v in %q, but was %#v", ci, experr, tcase.json, err)
 				}
 				break
 			} else if err == io.EOF {
 				t.Errorf("case %v: Unexpected EOF in %q", ci, tcase.json)
 				break
 			} else if err != nil {
-				t.Errorf("case %v: Unexpected error '%v' in %q", ci, err, tcase.json)
+				t.Errorf("case %v: Unexpected error '%#v' in %q", ci, err, tcase.json)
 				break
 			}
 			if !reflect.DeepEqual(tk, etk) {
diff --git a/src/encoding/pem/example_test.go b/src/encoding/pem/example_test.go
index 900b31c..806e7bb 100644
--- a/src/encoding/pem/example_test.go
+++ b/src/encoding/pem/example_test.go
@@ -9,6 +9,7 @@
 	"encoding/pem"
 	"fmt"
 	"log"
+	"os"
 )
 
 func ExampleDecode() {
@@ -42,3 +43,23 @@
 	fmt.Printf("Got a %T, with remaining data: %q", pub, rest)
 	// Output: Got a *rsa.PublicKey, with remaining data: "and some more"
 }
+
+func ExampleEncode() {
+	block := &pem.Block{
+		Type: "MESSAGE",
+		Headers: map[string]string{
+			"Animal": "Gopher",
+		},
+		Bytes: []byte("test"),
+	}
+
+	if err := pem.Encode(os.Stdout, block); err != nil {
+		log.Fatal(err)
+	}
+	// Output:
+	// -----BEGIN MESSAGE-----
+	// Animal: Gopher
+	//
+	// dGVzdA==
+	// -----END MESSAGE-----
+}
diff --git a/src/encoding/pem/pem.go b/src/encoding/pem/pem.go
index 5e1ab90..35058c3 100644
--- a/src/encoding/pem/pem.go
+++ b/src/encoding/pem/pem.go
@@ -36,7 +36,7 @@
 // bytes) is also returned and this will always be smaller than the original
 // argument.
 func getLine(data []byte) (line, rest []byte) {
-	i := bytes.Index(data, []byte{'\n'})
+	i := bytes.IndexByte(data, '\n')
 	var j int
 	if i < 0 {
 		i = len(data)
@@ -106,7 +106,7 @@
 		}
 		line, next := getLine(rest)
 
-		i := bytes.Index(line, []byte{':'})
+		i := bytes.IndexByte(line, ':')
 		if i == -1 {
 			break
 		}
@@ -252,7 +252,18 @@
 	return err
 }
 
+// Encode writes the PEM encoding of b to out.
 func Encode(out io.Writer, b *Block) error {
+	// Check for invalid block before writing any output.
+	for k := range b.Headers {
+		if strings.Contains(k, ":") {
+			return errors.New("pem: cannot encode a header key that contains a colon")
+		}
+	}
+
+	// All errors below are relayed from underlying io.Writer,
+	// so it is now safe to write data.
+
 	if _, err := out.Write(pemStart[1:]); err != nil {
 		return err
 	}
@@ -281,9 +292,6 @@
 		// For consistency of output, write other headers sorted by key.
 		sort.Strings(h)
 		for _, k := range h {
-			if strings.Contains(k, ":") {
-				return errors.New("pem: cannot encode a header key that contains a colon")
-			}
 			if err := writeHeader(out, k, b.Headers[k]); err != nil {
 				return err
 			}
@@ -310,8 +318,15 @@
 	return err
 }
 
+// EncodeToMemory returns the PEM encoding of b.
+//
+// If b has invalid headers and cannot be encoded,
+// EncodeToMemory returns nil. If it is important to
+// report details about this error case, use Encode instead.
 func EncodeToMemory(b *Block) []byte {
 	var buf bytes.Buffer
-	Encode(&buf, b)
+	if err := Encode(&buf, b); err != nil {
+		return nil
+	}
 	return buf.Bytes()
 }
diff --git a/src/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go
index 1a1250a..6a17516 100644
--- a/src/encoding/pem/pem_test.go
+++ b/src/encoding/pem/pem_test.go
@@ -590,3 +590,17 @@
 tJQLJRZ+ItT5Irl4owSEBNLahC1j3fhQavbj9WVAfKk=
 -----END RSA PRIVATE KEY-----
 `
+
+func TestBadEncode(t *testing.T) {
+	b := &Block{Type: "BAD", Headers: map[string]string{"X:Y": "Z"}}
+	var buf bytes.Buffer
+	if err := Encode(&buf, b); err == nil {
+		t.Fatalf("Encode did not report invalid header")
+	}
+	if buf.Len() != 0 {
+		t.Fatalf("Encode wrote data before reporting invalid header")
+	}
+	if data := EncodeToMemory(b); data != nil {
+		t.Fatalf("EncodeToMemory returned non-nil data")
+	}
+}
diff --git a/src/encoding/xml/atom_test.go b/src/encoding/xml/atom_test.go
index a712843..f394dab 100644
--- a/src/encoding/xml/atom_test.go
+++ b/src/encoding/xml/atom_test.go
@@ -12,20 +12,20 @@
 	Link:    []Link{{Href: "http://example.org/"}},
 	Updated: ParseTime("2003-12-13T18:30:02Z"),
 	Author:  Person{Name: "John Doe"},
-	Id:      "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6",
+	ID:      "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6",
 
 	Entry: []Entry{
 		{
 			Title:   "Atom-Powered Robots Run Amok",
 			Link:    []Link{{Href: "http://example.org/2003/12/13/atom03"}},
-			Id:      "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
+			ID:      "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
 			Updated: ParseTime("2003-12-13T18:30:02Z"),
 			Summary: NewText("Some text."),
 		},
 	},
 }
 
-var atomXml = `` +
+var atomXML = `` +
 	`<feed xmlns="http://www.w3.org/2005/Atom" updated="2003-12-13T18:30:02Z">` +
 	`<title>Example Feed</title>` +
 	`<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>` +
diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 4c6ba8c..d393d06 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -16,7 +16,7 @@
 )
 
 const (
-	// A generic XML header suitable for use with the output of Marshal.
+	// Header is a generic XML header suitable for use with the output of Marshal.
 	// This is not automatically added to any output of this package,
 	// it is provided as a convenience.
 	Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
@@ -66,6 +66,9 @@
 // parent elements a and b. Fields that appear next to each other that name
 // the same parent will be enclosed in one XML element.
 //
+// If the XML name for a struct field is defined by both the field tag and the
+// struct's XMLName field, the names must match.
+//
 // See MarshalIndent for an example.
 //
 // Marshal will return an error if asked to marshal a channel, function, or map.
@@ -320,7 +323,7 @@
 	// (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
 	// but users should not be trying to use that one directly - that's our job.)
 	if url == xmlURL {
-		return "xml"
+		return xmlPrefix
 	}
 
 	// Need to define a new name space.
@@ -1011,7 +1014,7 @@
 	return nil
 }
 
-// A MarshalXMLError is returned when Marshal encounters a type
+// UnsupportedTypeError is returned when Marshal encounters a type
 // that cannot be converted into XML.
 type UnsupportedTypeError struct {
 	Type reflect.Type
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index 674c6b5..a0ccf44 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -583,16 +583,6 @@
 		ExpectXML: `<PresenceTest></PresenceTest>`,
 	},
 
-	// A pointer to struct{} may be used to test for an element's presence.
-	{
-		Value:     &PresenceTest{new(struct{})},
-		ExpectXML: `<PresenceTest><Exists></Exists></PresenceTest>`,
-	},
-	{
-		Value:     &PresenceTest{},
-		ExpectXML: `<PresenceTest></PresenceTest>`,
-	},
-
 	// A []byte field is only nil if the element was not found.
 	{
 		Value:         &Data{},
@@ -646,7 +636,7 @@
 	{Value: &Universe{Visible: 9.3e13}, ExpectXML: `<universe>9.3e+13</universe>`},
 	{Value: &Particle{HasMass: true}, ExpectXML: `<particle>true</particle>`},
 	{Value: &Departure{When: ParseTime("2013-01-09T00:15:00-09:00")}, ExpectXML: `<departure>2013-01-09T00:15:00-09:00</departure>`},
-	{Value: atomValue, ExpectXML: atomXml},
+	{Value: atomValue, ExpectXML: atomXML},
 	{
 		Value: &Ship{
 			Name:  "Heart of Gold",
@@ -1910,7 +1900,7 @@
 
 func BenchmarkUnmarshal(b *testing.B) {
 	b.ReportAllocs()
-	xml := []byte(atomXml)
+	xml := []byte(atomXML)
 	b.RunParallel(func(pb *testing.PB) {
 		for pb.Next() {
 			Unmarshal(xml, &Feed{})
@@ -2441,3 +2431,22 @@
 		t.Errorf("Unmarshal: expected error, got nil")
 	}
 }
+
+// Issue 20953. Crash on invalid XMLName attribute.
+
+type InvalidXMLName struct {
+	XMLName Name `xml:"error"`
+	Type    struct {
+		XMLName Name `xml:"type,attr"`
+	}
+}
+
+func TestInvalidXMLName(t *testing.T) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	if err := enc.Encode(InvalidXMLName{}); err == nil {
+		t.Error("unexpected success")
+	} else if want := "invalid tag"; !strings.Contains(err.Error(), want) {
+		t.Errorf("error %q does not contain %q", err, want)
+	}
+}
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index 000d9fb..36c7ba6 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -107,12 +107,13 @@
 // to the newly created value.
 //
 // Unmarshal maps an XML element or attribute value to a bool by
-// setting it to the boolean value represented by the string.
+// setting it to the boolean value represented by the string. Whitespace
+// is trimmed and ignored.
 //
 // Unmarshal maps an XML element or attribute value to an integer or
 // floating-point field by setting the field to the result of
 // interpreting the string value in decimal. There is no check for
-// overflow.
+// overflow. Whitespace is trimmed and ignored.
 //
 // Unmarshal maps an XML element to a Name by recording the element
 // name.
@@ -160,7 +161,7 @@
 // UnmarshalXML must consume exactly one XML element.
 // One common implementation strategy is to unmarshal into
 // a separate value with a layout matching the expected XML
-// using d.DecodeElement,  and then to copy the data from
+// using d.DecodeElement, and then to copy the data from
 // that value into the receiver.
 // Another common strategy is to use d.Token to process the
 // XML object one token at a time.
@@ -192,19 +193,19 @@
 
 // unmarshalInterface unmarshals a single XML element into val.
 // start is the opening tag of the element.
-func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
+func (d *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
 	// Record that decoder must stop at end tag corresponding to start.
-	p.pushEOF()
+	d.pushEOF()
 
-	p.unmarshalDepth++
-	err := val.UnmarshalXML(p, *start)
-	p.unmarshalDepth--
+	d.unmarshalDepth++
+	err := val.UnmarshalXML(d, *start)
+	d.unmarshalDepth--
 	if err != nil {
-		p.popEOF()
+		d.popEOF()
 		return err
 	}
 
-	if !p.popEOF() {
+	if !d.popEOF() {
 		return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local)
 	}
 
@@ -214,11 +215,11 @@
 // unmarshalTextInterface unmarshals a single XML element into val.
 // The chardata contained in the element (but not its children)
 // is passed to the text unmarshaler.
-func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler) error {
+func (d *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler) error {
 	var buf []byte
 	depth := 1
 	for depth > 0 {
-		t, err := p.Token()
+		t, err := d.Token()
 		if err != nil {
 			return err
 		}
@@ -237,7 +238,7 @@
 }
 
 // unmarshalAttr unmarshals a single XML attribute into val.
-func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
+func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
 	if val.Kind() == reflect.Ptr {
 		if val.IsNil() {
 			val.Set(reflect.New(val.Type().Elem()))
@@ -276,7 +277,7 @@
 		val.Set(reflect.Append(val, reflect.Zero(val.Type().Elem())))
 
 		// Recur to read element into slice.
-		if err := p.unmarshalAttr(val.Index(n), attr); err != nil {
+		if err := d.unmarshalAttr(val.Index(n), attr); err != nil {
 			val.SetLen(n)
 			return err
 		}
@@ -299,11 +300,11 @@
 )
 
 // Unmarshal a single XML element into val.
-func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
+func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
 	// Find start element if we need it.
 	if start == nil {
 		for {
-			tok, err := p.Token()
+			tok, err := d.Token()
 			if err != nil {
 				return err
 			}
@@ -333,24 +334,24 @@
 	if val.CanInterface() && val.Type().Implements(unmarshalerType) {
 		// This is an unmarshaler with a non-pointer receiver,
 		// so it's likely to be incorrect, but we do what we're told.
-		return p.unmarshalInterface(val.Interface().(Unmarshaler), start)
+		return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
 	}
 
 	if val.CanAddr() {
 		pv := val.Addr()
 		if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
-			return p.unmarshalInterface(pv.Interface().(Unmarshaler), start)
+			return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
 		}
 	}
 
 	if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
-		return p.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
+		return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
 	}
 
 	if val.CanAddr() {
 		pv := val.Addr()
 		if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
-			return p.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
+			return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
 		}
 	}
 
@@ -376,7 +377,7 @@
 		// TODO: For now, simply ignore the field. In the near
 		//       future we may choose to unmarshal the start
 		//       element on it, if not nil.
-		return p.Skip()
+		return d.Skip()
 
 	case reflect.Slice:
 		typ := v.Type()
@@ -392,7 +393,7 @@
 		v.Set(reflect.Append(val, reflect.Zero(v.Type().Elem())))
 
 		// Recur to read element into slice.
-		if err := p.unmarshal(v.Index(n), start); err != nil {
+		if err := d.unmarshal(v.Index(n), start); err != nil {
 			v.SetLen(n)
 			return err
 		}
@@ -445,7 +446,7 @@
 				case fAttr:
 					strv := finfo.value(sv)
 					if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
-						if err := p.unmarshalAttr(strv, a); err != nil {
+						if err := d.unmarshalAttr(strv, a); err != nil {
 							return err
 						}
 						handled = true
@@ -460,7 +461,7 @@
 			if !handled && any >= 0 {
 				finfo := &tinfo.fields[any]
 				strv := finfo.value(sv)
-				if err := p.unmarshalAttr(strv, a); err != nil {
+				if err := d.unmarshalAttr(strv, a); err != nil {
 					return err
 				}
 			}
@@ -488,11 +489,11 @@
 			case fInnerXml:
 				if !saveXML.IsValid() {
 					saveXML = finfo.value(sv)
-					if p.saved == nil {
+					if d.saved == nil {
 						saveXMLIndex = 0
-						p.saved = new(bytes.Buffer)
+						d.saved = new(bytes.Buffer)
 					} else {
-						saveXMLIndex = p.savedOffset()
+						saveXMLIndex = d.savedOffset()
 					}
 				}
 			}
@@ -505,9 +506,9 @@
 	for {
 		var savedOffset int
 		if saveXML.IsValid() {
-			savedOffset = p.savedOffset()
+			savedOffset = d.savedOffset()
 		}
-		tok, err := p.Token()
+		tok, err := d.Token()
 		if err != nil {
 			return err
 		}
@@ -515,28 +516,28 @@
 		case StartElement:
 			consumed := false
 			if sv.IsValid() {
-				consumed, err = p.unmarshalPath(tinfo, sv, nil, &t)
+				consumed, err = d.unmarshalPath(tinfo, sv, nil, &t)
 				if err != nil {
 					return err
 				}
 				if !consumed && saveAny.IsValid() {
 					consumed = true
-					if err := p.unmarshal(saveAny, &t); err != nil {
+					if err := d.unmarshal(saveAny, &t); err != nil {
 						return err
 					}
 				}
 			}
 			if !consumed {
-				if err := p.Skip(); err != nil {
+				if err := d.Skip(); err != nil {
 					return err
 				}
 			}
 
 		case EndElement:
 			if saveXML.IsValid() {
-				saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset]
+				saveXMLData = d.saved.Bytes()[saveXMLIndex:savedOffset]
 				if saveXMLIndex == 0 {
-					p.saved = nil
+					d.saved = nil
 				}
 			}
 			break Loop
@@ -614,7 +615,7 @@
 			dst.SetInt(0)
 			return nil
 		}
-		itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits())
+		itmp, err := strconv.ParseInt(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
 		if err != nil {
 			return err
 		}
@@ -624,7 +625,7 @@
 			dst.SetUint(0)
 			return nil
 		}
-		utmp, err := strconv.ParseUint(string(src), 10, dst.Type().Bits())
+		utmp, err := strconv.ParseUint(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
 		if err != nil {
 			return err
 		}
@@ -634,7 +635,7 @@
 			dst.SetFloat(0)
 			return nil
 		}
-		ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits())
+		ftmp, err := strconv.ParseFloat(strings.TrimSpace(string(src)), dst.Type().Bits())
 		if err != nil {
 			return err
 		}
@@ -666,7 +667,7 @@
 // The consumed result tells whether XML elements have been consumed
 // from the Decoder until start's matching end element, or if it's
 // still untouched because start is uninteresting for sv's fields.
-func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
+func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
 	recurse := false
 Loop:
 	for i := range tinfo.fields {
@@ -681,7 +682,7 @@
 		}
 		if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
 			// It's a perfect match, unmarshal the field.
-			return true, p.unmarshal(finfo.value(sv), start)
+			return true, d.unmarshal(finfo.value(sv), start)
 		}
 		if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
 			// It's a prefix for the field. Break and recurse
@@ -704,18 +705,18 @@
 	// prefix. Recurse and attempt to match these.
 	for {
 		var tok Token
-		tok, err = p.Token()
+		tok, err = d.Token()
 		if err != nil {
 			return true, err
 		}
 		switch t := tok.(type) {
 		case StartElement:
-			consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t)
+			consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t)
 			if err != nil {
 				return true, err
 			}
 			if !consumed2 {
-				if err := p.Skip(); err != nil {
+				if err := d.Skip(); err != nil {
 					return true, err
 				}
 			}
diff --git a/src/encoding/xml/read_test.go b/src/encoding/xml/read_test.go
index a1eb516..8c2e70f 100644
--- a/src/encoding/xml/read_test.go
+++ b/src/encoding/xml/read_test.go
@@ -83,7 +83,7 @@
 type Feed struct {
 	XMLName Name      `xml:"http://www.w3.org/2005/Atom feed"`
 	Title   string    `xml:"title"`
-	Id      string    `xml:"id"`
+	ID      string    `xml:"id"`
 	Link    []Link    `xml:"link"`
 	Updated time.Time `xml:"updated,attr"`
 	Author  Person    `xml:"author"`
@@ -92,7 +92,7 @@
 
 type Entry struct {
 	Title   string    `xml:"title"`
-	Id      string    `xml:"id"`
+	ID      string    `xml:"id"`
 	Link    []Link    `xml:"link"`
 	Updated time.Time `xml:"updated"`
 	Author  Person    `xml:"author"`
@@ -123,7 +123,7 @@
 		{Rel: "alternate", Href: "http://codereview.appspot.com/"},
 		{Rel: "self", Href: "http://codereview.appspot.com/rss/mine/rsc"},
 	},
-	Id:      "http://codereview.appspot.com/",
+	ID:      "http://codereview.appspot.com/",
 	Updated: ParseTime("2009-10-04T01:35:58+00:00"),
 	Author: Person{
 		Name:     "rietveld<>",
@@ -140,7 +140,7 @@
 				Name:     "email-address-removed",
 				InnerXML: "<name>email-address-removed</name>",
 			},
-			Id: "urn:md5:134d9179c41f806be79b3a5f7877d19a",
+			ID: "urn:md5:134d9179c41f806be79b3a5f7877d19a",
 			Summary: Text{
 				Type: "html",
 				Body: `
@@ -187,7 +187,7 @@
 				Name:     "email-address-removed",
 				InnerXML: "<name>email-address-removed</name>",
 			},
-			Id: "urn:md5:0a2a4f19bb815101f0ba2904aed7c35a",
+			ID: "urn:md5:0a2a4f19bb815101f0ba2904aed7c35a",
 			Summary: Text{
 				Type: "html",
 				Body: `
@@ -819,7 +819,7 @@
 `
 )
 
-// github.com/golang/go/issues/13417
+// golang.org/issues/13417
 func TestUnmarshalEmptyValues(t *testing.T) {
 	// Test first with a zero-valued dst.
 	v := new(Parent)
@@ -908,3 +908,174 @@
 		t.Fatalf("populated: Unmarshal:\nhave:  %#+v\nwant: %#+v", v, want)
 	}
 }
+
+type WhitespaceValuesParent struct {
+	BFalse bool
+	BTrue  bool
+	I      int
+	INeg   int
+	I8     int8
+	I8Neg  int8
+	I16    int16
+	I16Neg int16
+	I32    int32
+	I32Neg int32
+	I64    int64
+	I64Neg int64
+	UI     uint
+	UI8    uint8
+	UI16   uint16
+	UI32   uint32
+	UI64   uint64
+	F32    float32
+	F32Neg float32
+	F64    float64
+	F64Neg float64
+}
+
+const whitespaceValuesXML = `
+<WhitespaceValuesParent>
+    <BFalse>   false   </BFalse>
+    <BTrue>   true   </BTrue>
+    <I>   266703   </I>
+    <INeg>   -266703   </INeg>
+    <I8>  112  </I8>
+    <I8Neg>  -112  </I8Neg>
+    <I16>  6703  </I16>
+    <I16Neg>  -6703  </I16Neg>
+    <I32>  266703  </I32>
+    <I32Neg>  -266703  </I32Neg>
+    <I64>  266703  </I64>
+    <I64Neg>  -266703  </I64Neg>
+    <UI>   266703   </UI>
+    <UI8>  112  </UI8>
+    <UI16>  6703  </UI16>
+    <UI32>  266703  </UI32>
+    <UI64>  266703  </UI64>
+    <F32>  266.703  </F32>
+    <F32Neg>  -266.703  </F32Neg>
+    <F64>  266.703  </F64>
+    <F64Neg>  -266.703  </F64Neg>
+</WhitespaceValuesParent>
+`
+
+// golang.org/issues/22146
+func TestUnmarshalWhitespaceValues(t *testing.T) {
+	v := WhitespaceValuesParent{}
+	if err := Unmarshal([]byte(whitespaceValuesXML), &v); err != nil {
+		t.Fatalf("whitespace values: Unmarshal failed: got %v", err)
+	}
+
+	want := WhitespaceValuesParent{
+		BFalse: false,
+		BTrue:  true,
+		I:      266703,
+		INeg:   -266703,
+		I8:     112,
+		I8Neg:  -112,
+		I16:    6703,
+		I16Neg: -6703,
+		I32:    266703,
+		I32Neg: -266703,
+		I64:    266703,
+		I64Neg: -266703,
+		UI:     266703,
+		UI8:    112,
+		UI16:   6703,
+		UI32:   266703,
+		UI64:   266703,
+		F32:    266.703,
+		F32Neg: -266.703,
+		F64:    266.703,
+		F64Neg: -266.703,
+	}
+	if v != want {
+		t.Fatalf("whitespace values: Unmarshal:\nhave: %#+v\nwant: %#+v", v, want)
+	}
+}
+
+type WhitespaceAttrsParent struct {
+	BFalse bool    `xml:",attr"`
+	BTrue  bool    `xml:",attr"`
+	I      int     `xml:",attr"`
+	INeg   int     `xml:",attr"`
+	I8     int8    `xml:",attr"`
+	I8Neg  int8    `xml:",attr"`
+	I16    int16   `xml:",attr"`
+	I16Neg int16   `xml:",attr"`
+	I32    int32   `xml:",attr"`
+	I32Neg int32   `xml:",attr"`
+	I64    int64   `xml:",attr"`
+	I64Neg int64   `xml:",attr"`
+	UI     uint    `xml:",attr"`
+	UI8    uint8   `xml:",attr"`
+	UI16   uint16  `xml:",attr"`
+	UI32   uint32  `xml:",attr"`
+	UI64   uint64  `xml:",attr"`
+	F32    float32 `xml:",attr"`
+	F32Neg float32 `xml:",attr"`
+	F64    float64 `xml:",attr"`
+	F64Neg float64 `xml:",attr"`
+}
+
+const whitespaceAttrsXML = `
+<WhitespaceAttrsParent
+    BFalse="  false  "
+    BTrue="  true  "
+    I="  266703  "
+    INeg="  -266703  "
+    I8="  112  "
+    I8Neg="  -112  "
+    I16="  6703  "
+    I16Neg="  -6703  "
+    I32="  266703  "
+    I32Neg="  -266703  "
+    I64="  266703  "
+    I64Neg="  -266703  "
+    UI="  266703  "
+    UI8="  112  "
+    UI16="  6703  "
+    UI32="  266703  "
+    UI64="  266703  "
+    F32="  266.703  "
+    F32Neg="  -266.703  "
+    F64="  266.703  "
+    F64Neg="  -266.703  "
+>
+</WhitespaceAttrsParent>
+`
+
+// golang.org/issues/22146
+func TestUnmarshalWhitespaceAttrs(t *testing.T) {
+	v := WhitespaceAttrsParent{}
+	if err := Unmarshal([]byte(whitespaceAttrsXML), &v); err != nil {
+		t.Fatalf("whitespace attrs: Unmarshal failed: got %v", err)
+	}
+
+	want := WhitespaceAttrsParent{
+		BFalse: false,
+		BTrue:  true,
+		I:      266703,
+		INeg:   -266703,
+		I8:     112,
+		I8Neg:  -112,
+		I16:    6703,
+		I16Neg: -6703,
+		I32:    266703,
+		I32Neg: -266703,
+		I64:    266703,
+		I64Neg: -266703,
+		UI:     266703,
+		UI8:    112,
+		UI16:   6703,
+		UI32:   266703,
+		UI64:   266703,
+		F32:    266.703,
+		F32Neg: -266.703,
+		F64:    266.703,
+		F64Neg: -266.703,
+	}
+	if v != want {
+		t.Fatalf("whitespace attrs: Unmarshal:\nhave: %#+v\nwant: %#+v", v, want)
+	}
+}
diff --git a/src/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go
index 751caa9..48de3d7 100644
--- a/src/encoding/xml/typeinfo.go
+++ b/src/encoding/xml/typeinfo.go
@@ -40,6 +40,8 @@
 	fOmitEmpty
 
 	fMode = fElement | fAttr | fCDATA | fCharData | fInnerXml | fComment | fAny
+
+	xmlName = "XMLName"
 )
 
 var tinfoMap sync.Map // map[reflect.Type]*typeInfo
@@ -91,7 +93,7 @@
 				return nil, err
 			}
 
-			if f.Name == "XMLName" {
+			if f.Name == xmlName {
 				tinfo.xmlname = finfo
 				continue
 			}
@@ -148,7 +150,7 @@
 		case 0:
 			finfo.flags |= fElement
 		case fAttr, fCDATA, fCharData, fInnerXml, fComment, fAny, fAny | fAttr:
-			if f.Name == "XMLName" || tag != "" && mode != fAttr {
+			if f.Name == xmlName || tag != "" && mode != fAttr {
 				valid = false
 			}
 		default:
@@ -173,7 +175,7 @@
 			f.Name, typ, f.Tag.Get("xml"))
 	}
 
-	if f.Name == "XMLName" {
+	if f.Name == xmlName {
 		// The XMLName field records the XML element name. Don't
 		// process it as usual because its name should default to
 		// empty rather than to the field name.
@@ -235,11 +237,11 @@
 	}
 	for i, n := 0, typ.NumField(); i < n; i++ {
 		f := typ.Field(i)
-		if f.Name != "XMLName" {
+		if f.Name != xmlName {
 			continue
 		}
 		finfo, err := structFieldInfo(typ, &f)
-		if finfo.name != "" && err == nil {
+		if err == nil && finfo.name != "" {
 			return finfo
 		}
 		// Also consider errors as a non-existent field tag
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
index 9a3b792..f408623 100644
--- a/src/encoding/xml/xml.go
+++ b/src/encoding/xml/xml.go
@@ -60,6 +60,7 @@
 	Attr []Attr
 }
 
+// Copy creates a new copy of StartElement.
 func (e StartElement) Copy() StartElement {
 	attrs := make([]Attr, len(e.Attr))
 	copy(attrs, e.Attr)
@@ -88,12 +89,14 @@
 	return b1
 }
 
+// Copy creates a new copy of CharData.
 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
 
+// Copy creates a new copy of Comment.
 func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
 
 // A ProcInst represents an XML processing instruction of the form <?target inst?>
@@ -102,6 +105,7 @@
 	Inst   []byte
 }
 
+// Copy creates a new copy of ProcInst.
 func (p ProcInst) Copy() ProcInst {
 	p.Inst = makeCopy(p.Inst)
 	return p
@@ -111,6 +115,7 @@
 // The bytes do not include the <! and > markers.
 type Directive []byte
 
+// Copy creates a new copy of Directive.
 func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
 
 // CopyToken returns a copy of a Token.
@@ -130,6 +135,23 @@
 	return t
 }
 
+// A TokenReader is anything that can decode a stream of XML tokens, including a
+// Decoder.
+//
+// When Token encounters an error or end-of-file condition after successfully
+// reading a token, it returns the token. It may return the (non-nil) error from
+// the same call or return the error (and a nil token) from a subsequent call.
+// An instance of this general case is that a TokenReader returning a non-nil
+// token at the end of the token stream may return either io.EOF or a nil error.
+// The next Read should return nil, io.EOF.
+//
+// Implementations of Token are discouraged from returning a nil token with a
+// nil error. Callers should treat a return of nil, nil as indicating that
+// nothing happened; in particular it does not indicate EOF.
+type TokenReader interface {
+	Token() (Token, error)
+}
+
 // 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 {
@@ -185,6 +207,7 @@
 	DefaultSpace string
 
 	r              io.ByteReader
+	t              TokenReader
 	buf            bytes.Buffer
 	saved          *bytes.Buffer
 	stk            *stack
@@ -214,6 +237,22 @@
 	return d
 }
 
+// NewTokenDecoder creates a new XML parser using an underlying token stream.
+func NewTokenDecoder(t TokenReader) *Decoder {
+	// Is it already a Decoder?
+	if d, ok := t.(*Decoder); ok {
+		return d
+	}
+	d := &Decoder{
+		ns:       make(map[string]string),
+		t:        t,
+		nextByte: -1,
+		line:     1,
+		Strict:   true,
+	}
+	return d
+}
+
 // Token returns the next XML token in the input stream.
 // At the end of the input stream, Token returns nil, io.EOF.
 //
@@ -266,12 +305,12 @@
 		// to the other attribute names, so process
 		// the translations first.
 		for _, a := range t1.Attr {
-			if a.Name.Space == "xmlns" {
+			if a.Name.Space == xmlnsPrefix {
 				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" {
+			if a.Name.Space == "" && a.Name.Local == xmlnsPrefix {
 				// Default space for untagged names
 				v, ok := d.ns[""]
 				d.pushNs("", v, ok)
@@ -296,20 +335,24 @@
 	return t, err
 }
 
-const xmlURL = "http://www.w3.org/XML/1998/namespace"
+const (
+	xmlURL      = "http://www.w3.org/XML/1998/namespace"
+	xmlnsPrefix = "xmlns"
+	xmlPrefix   = "xml"
+)
 
 // 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":
+	case n.Space == xmlnsPrefix:
 		return
 	case n.Space == "" && !isElementName:
 		return
-	case n.Space == "xml":
+	case n.Space == xmlPrefix:
 		n.Space = xmlURL
-	case n.Space == "" && n.Local == "xmlns":
+	case n.Space == "" && n.Local == xmlnsPrefix:
 		return
 	}
 	if v, ok := d.ns[n.Space]; ok {
@@ -503,6 +546,9 @@
 }
 
 func (d *Decoder) rawToken() (Token, error) {
+	if d.t != nil {
+		return d.t.Token()
+	}
 	if d.err != nil {
 		return nil, d.err
 	}
@@ -786,10 +832,9 @@
 			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
 			}
+			d.ungetc(b)
+			a.Value = a.Name.Local
 		} else {
 			d.space()
 			data := d.attrval()
@@ -1027,7 +1072,6 @@
 					if d.err != nil {
 						return nil
 					}
-					ok = false
 				}
 				if b, ok = d.mustgetc(); !ok {
 					return nil
@@ -1837,15 +1881,15 @@
 }
 
 var (
-	esc_quot = []byte("&#34;") // shorter than "&quot;"
-	esc_apos = []byte("&#39;") // shorter than "&apos;"
-	esc_amp  = []byte("&amp;")
-	esc_lt   = []byte("&lt;")
-	esc_gt   = []byte("&gt;")
-	esc_tab  = []byte("&#x9;")
-	esc_nl   = []byte("&#xA;")
-	esc_cr   = []byte("&#xD;")
-	esc_fffd = []byte("\uFFFD") // Unicode replacement character
+	escQuot = []byte("&#34;") // shorter than "&quot;"
+	escApos = []byte("&#39;") // shorter than "&apos;"
+	escAmp  = []byte("&amp;")
+	escLT   = []byte("&lt;")
+	escGT   = []byte("&gt;")
+	escTab  = []byte("&#x9;")
+	escNL   = []byte("&#xA;")
+	escCR   = []byte("&#xD;")
+	escFFFD = []byte("\uFFFD") // Unicode replacement character
 )
 
 // EscapeText writes to w the properly escaped XML equivalent
@@ -1865,27 +1909,27 @@
 		i += width
 		switch r {
 		case '"':
-			esc = esc_quot
+			esc = escQuot
 		case '\'':
-			esc = esc_apos
+			esc = escApos
 		case '&':
-			esc = esc_amp
+			esc = escAmp
 		case '<':
-			esc = esc_lt
+			esc = escLT
 		case '>':
-			esc = esc_gt
+			esc = escGT
 		case '\t':
-			esc = esc_tab
+			esc = escTab
 		case '\n':
 			if !escapeNewline {
 				continue
 			}
-			esc = esc_nl
+			esc = escNL
 		case '\r':
-			esc = esc_cr
+			esc = escCR
 		default:
 			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
-				esc = esc_fffd
+				esc = escFFFD
 				break
 			}
 			continue
@@ -1914,24 +1958,24 @@
 		i += width
 		switch r {
 		case '"':
-			esc = esc_quot
+			esc = escQuot
 		case '\'':
-			esc = esc_apos
+			esc = escApos
 		case '&':
-			esc = esc_amp
+			esc = escAmp
 		case '<':
-			esc = esc_lt
+			esc = escLT
 		case '>':
-			esc = esc_gt
+			esc = escGT
 		case '\t':
-			esc = esc_tab
+			esc = escTab
 		case '\n':
-			esc = esc_nl
+			esc = escNL
 		case '\r':
-			esc = esc_cr
+			esc = escCR
 		default:
 			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
-				esc = esc_fffd
+				esc = escFFFD
 				break
 			}
 			continue
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
index dad6ed9..7a3511d 100644
--- a/src/encoding/xml/xml_test.go
+++ b/src/encoding/xml/xml_test.go
@@ -479,15 +479,15 @@
 }
 
 type item struct {
-	Field_a string
+	FieldA string
 }
 
 func TestIssue569(t *testing.T) {
-	data := `<item><Field_a>abcd</Field_a></item>`
+	data := `<item><FieldA>abcd</FieldA></item>`
 	var i item
 	err := Unmarshal([]byte(data), &i)
 
-	if err != nil || i.Field_a != "abcd" {
+	if err != nil || i.FieldA != "abcd" {
 		t.Fatal("Expecting abcd")
 	}
 }
@@ -797,3 +797,90 @@
 		}
 	}
 }
+
+func tokenMap(mapping func(t Token) Token) func(TokenReader) TokenReader {
+	return func(src TokenReader) TokenReader {
+		return mapper{
+			t: src,
+			f: mapping,
+		}
+	}
+}
+
+type mapper struct {
+	t TokenReader
+	f func(Token) Token
+}
+
+func (m mapper) Token() (Token, error) {
+	tok, err := m.t.Token()
+	if err != nil {
+		return nil, err
+	}
+	return m.f(tok), nil
+}
+
+func TestNewTokenDecoderIdempotent(t *testing.T) {
+	d := NewDecoder(strings.NewReader(`<br/>`))
+	d2 := NewTokenDecoder(d)
+	if d != d2 {
+		t.Error("NewTokenDecoder did not detect underlying Decoder")
+	}
+}
+
+func TestWrapDecoder(t *testing.T) {
+	d := NewDecoder(strings.NewReader(`<quote>[Re-enter Clown with a letter, and FABIAN]</quote>`))
+	m := tokenMap(func(t Token) Token {
+		switch tok := t.(type) {
+		case StartElement:
+			if tok.Name.Local == "quote" {
+				tok.Name.Local = "blocking"
+				return tok
+			}
+		case EndElement:
+			if tok.Name.Local == "quote" {
+				tok.Name.Local = "blocking"
+				return tok
+			}
+		}
+		return t
+	})
+
+	d = NewTokenDecoder(m(d))
+
+	o := struct {
+		XMLName  Name   `xml:"blocking"`
+		Chardata string `xml:",chardata"`
+	}{}
+
+	if err := d.Decode(&o); err != nil {
+		t.Fatal("Got unexpected error while decoding:", err)
+	}
+
+	if o.Chardata != "[Re-enter Clown with a letter, and FABIAN]" {
+		t.Fatalf("Got unexpected chardata: `%s`\n", o.Chardata)
+	}
+}
+
+type tokReader struct{}
+
+func (tokReader) Token() (Token, error) {
+	return StartElement{}, nil
+}
+
+type Failure struct{}
+
+func (Failure) UnmarshalXML(*Decoder, StartElement) error {
+	return nil
+}
+
+func TestTokenUnmarshaler(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error("Unexpected panic using custom token unmarshaler")
+		}
+	}()
+
+	d := NewTokenDecoder(tokReader{})
+	d.Decode(&Failure{})
+}
diff --git a/src/expvar/expvar.go b/src/expvar/expvar.go
index 64dae70..8290e0b 100644
--- a/src/expvar/expvar.go
+++ b/src/expvar/expvar.go
@@ -125,7 +125,17 @@
 	return b.String()
 }
 
-func (v *Map) Init() *Map { return v }
+// Init removes all keys from the map.
+func (v *Map) Init() *Map {
+	v.keysMu.Lock()
+	defer v.keysMu.Unlock()
+	v.keys = v.keys[:0]
+	v.m.Range(func(k, _ interface{}) bool {
+		v.m.Delete(k)
+		return true
+	})
+	return v
+}
 
 // updateKeys updates the sorted list of keys in v.keys.
 func (v *Map) addKey(key string) {
diff --git a/src/expvar/expvar_test.go b/src/expvar/expvar_test.go
index 7014063..728e763 100644
--- a/src/expvar/expvar_test.go
+++ b/src/expvar/expvar_test.go
@@ -161,6 +161,28 @@
 	})
 }
 
+func TestMapInit(t *testing.T) {
+	RemoveAll()
+	colors := NewMap("bike-shed-colors")
+	colors.Add("red", 1)
+	colors.Add("blue", 1)
+	colors.Add("chartreuse", 1)
+
+	n := 0
+	colors.Do(func(KeyValue) { n++ })
+	if n != 3 {
+		t.Errorf("after three Add calls with distinct keys, Do should invoke f 3 times; got %v", n)
+	}
+
+	colors.Init()
+
+	n = 0
+	colors.Do(func(KeyValue) { n++ })
+	if n != 0 {
+		t.Errorf("after Init, Do should invoke f 0 times; got %v", n)
+	}
+}
+
 func TestMapCounter(t *testing.T) {
 	RemoveAll()
 	colors := NewMap("bike-shed-colors")
diff --git a/src/flag/export_test.go b/src/flag/export_test.go
index edbe83c..838cfaf 100644
--- a/src/flag/export_test.go
+++ b/src/flag/export_test.go
@@ -8,6 +8,8 @@
 
 // Additional routines compiled into the package only during testing.
 
+var DefaultUsage = Usage
+
 // ResetForTesting clears all flag state and sets the usage function as directed.
 // After calling ResetForTesting, parse errors in flag handling will not
 // exit the program.
diff --git a/src/flag/flag.go b/src/flag/flag.go
index b166c57..edde528 100644
--- a/src/flag/flag.go
+++ b/src/flag/flag.go
@@ -43,8 +43,9 @@
 	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.
+	where * is a Unix shell wildcard, 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 "--".
@@ -71,6 +72,7 @@
 	"reflect"
 	"sort"
 	"strconv"
+	"strings"
 	"time"
 )
 
@@ -269,7 +271,9 @@
 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.
+	// a custom error handler. What happens after Usage is called depends
+	// on the ErrorHandling setting; for the command line, this defaults
+	// to ExitOnError, which exits the program after calling Usage.
 	Usage func()
 
 	name          string
@@ -305,13 +309,25 @@
 	return result
 }
 
-func (f *FlagSet) out() io.Writer {
+// Output returns the destination for usage and error messages. os.Stderr is returned if
+// output was not set or was set to nil.
+func (f *FlagSet) Output() io.Writer {
 	if f.output == nil {
 		return os.Stderr
 	}
 	return f.output
 }
 
+// Name returns the name of the flag set.
+func (f *FlagSet) Name() string {
+	return f.name
+}
+
+// ErrorHandling returns the error handling behavior of the flag set.
+func (f *FlagSet) ErrorHandling() ErrorHandling {
+	return f.errorHandling
+}
+
 // SetOutput sets the destination for usage and error messages.
 // If output is nil, os.Stderr is used.
 func (f *FlagSet) SetOutput(output io.Writer) {
@@ -397,11 +413,7 @@
 	}
 
 	switch value {
-	case "false":
-		return true
-	case "":
-		return true
-	case "0":
+	case "false", "", "0":
 		return true
 	}
 	return false
@@ -446,9 +458,9 @@
 	return
 }
 
-// PrintDefaults prints to standard error the default values of all
-// defined command-line flags in the set. See the documentation for
-// the global function PrintDefaults for more information.
+// PrintDefaults prints, to standard error unless configured otherwise, the
+// default values of all defined command-line flags in the set. See the
+// documentation for the global function PrintDefaults for more information.
 func (f *FlagSet) PrintDefaults() {
 	f.VisitAll(func(flag *Flag) {
 		s := fmt.Sprintf("  -%s", flag.Name) // Two spaces before -; see next two comments.
@@ -465,7 +477,8 @@
 			// for both 4- and 8-space tab stops.
 			s += "\n    \t"
 		}
-		s += usage
+		s += strings.Replace(usage, "\n", "\n    \t", -1)
+
 		if !isZeroValue(flag, flag.DefValue) {
 			if _, ok := flag.Value.(*stringValue); ok {
 				// put quotes on the value
@@ -474,7 +487,7 @@
 				s += fmt.Sprintf(" (default %v)", flag.DefValue)
 			}
 		}
-		fmt.Fprint(f.out(), s, "\n")
+		fmt.Fprint(f.Output(), s, "\n")
 	})
 }
 
@@ -504,9 +517,9 @@
 // defaultUsage is the default function to print a usage message.
 func (f *FlagSet) defaultUsage() {
 	if f.name == "" {
-		fmt.Fprintf(f.out(), "Usage:\n")
+		fmt.Fprintf(f.Output(), "Usage:\n")
 	} else {
-		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
+		fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
 	}
 	f.PrintDefaults()
 }
@@ -515,13 +528,17 @@
 // 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.
+// Usage prints a usage message documenting all defined command-line flags
+// to CommandLine's output, which by default is os.Stderr.
 // 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.
 // By default it prints a simple header and calls PrintDefaults; for details about the
 // format of the output and how to control it, see the documentation for PrintDefaults.
+// Custom usage functions may choose to exit the program; by default exiting
+// happens anyway as the command line's error handling strategy is set to
+// ExitOnError.
 var Usage = func() {
-	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
 	PrintDefaults()
 }
 
@@ -645,13 +662,13 @@
 }
 
 // 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.
+// 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.
+// 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)
@@ -659,7 +676,7 @@
 }
 
 // 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.
+// 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)
 }
@@ -789,7 +806,7 @@
 		} else {
 			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
 		}
-		fmt.Fprintln(f.out(), msg)
+		fmt.Fprintln(f.Output(), msg)
 		panic(msg) // Happens only if flags are declared with identical names
 	}
 	if f.formal == nil {
@@ -812,7 +829,7 @@
 // returns the error.
 func (f *FlagSet) failf(format string, a ...interface{}) error {
 	err := fmt.Errorf(format, a...)
-	fmt.Fprintln(f.out(), err)
+	fmt.Fprintln(f.Output(), err)
 	f.usage()
 	return err
 }
@@ -833,7 +850,7 @@
 		return false, nil
 	}
 	s := f.args[0]
-	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
+	if len(s) < 2 || s[0] != '-' {
 		return false, nil
 	}
 	numMinuses := 1
@@ -934,7 +951,7 @@
 	return f.parsed
 }
 
-// Parse parses the command-line flags from os.Args[1:].  Must be called
+// 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.
diff --git a/src/flag/flag_test.go b/src/flag/flag_test.go
index 02da2c7..67c409f 100644
--- a/src/flag/flag_test.go
+++ b/src/flag/flag_test.go
@@ -8,6 +8,7 @@
 	"bytes"
 	. "flag"
 	"fmt"
+	"io"
 	"os"
 	"sort"
 	"strconv"
@@ -389,8 +390,14 @@
     	a non-zero number (default 2.7)
   -G float
     	a float that defaults to zero
+  -M string
+    	a multiline
+    	help
+    	string
   -N int
     	a non-zero int (default 27)
+  -O	a flag
+    	multiline help string (default true)
   -Z int
     	an int that defaults to zero
   -maxT timeout
@@ -407,7 +414,9 @@
 	fs.String("D", "", "set relative `path` for local imports")
 	fs.Float64("F", 2.7, "a non-zero `number`")
 	fs.Float64("G", 0, "a float that defaults to zero")
+	fs.String("M", "", "a multiline\nhelp\nstring")
 	fs.Int("N", 27, "a non-zero int")
+	fs.Bool("O", true, "a flag\nmultiline help string")
 	fs.Int("Z", 0, "an int that defaults to zero")
 	fs.Duration("maxT", 0, "set `timeout` for dial")
 	fs.PrintDefaults()
@@ -432,3 +441,50 @@
 		t.Error("unexpected success setting Uint")
 	}
 }
+
+// Issue 20998: Usage should respect CommandLine.output.
+func TestUsageOutput(t *testing.T) {
+	ResetForTesting(DefaultUsage)
+	var buf bytes.Buffer
+	CommandLine.SetOutput(&buf)
+	defer func(old []string) { os.Args = old }(os.Args)
+	os.Args = []string{"app", "-i=1", "-unknown"}
+	Parse()
+	const want = "flag provided but not defined: -i\nUsage of app:\n"
+	if got := buf.String(); got != want {
+		t.Errorf("output = %q; want %q", got, want)
+	}
+}
+
+func TestGetters(t *testing.T) {
+	expectedName := "flag set"
+	expectedErrorHandling := ContinueOnError
+	expectedOutput := io.Writer(os.Stderr)
+	fs := NewFlagSet(expectedName, expectedErrorHandling)
+
+	if fs.Name() != expectedName {
+		t.Errorf("unexpected name: got %s, expected %s", fs.Name(), expectedName)
+	}
+	if fs.ErrorHandling() != expectedErrorHandling {
+		t.Errorf("unexpected ErrorHandling: got %d, expected %d", fs.ErrorHandling(), expectedErrorHandling)
+	}
+	if fs.Output() != expectedOutput {
+		t.Errorf("unexpected output: got %#v, expected %#v", fs.Output(), expectedOutput)
+	}
+
+	expectedName = "gopher"
+	expectedErrorHandling = ExitOnError
+	expectedOutput = os.Stdout
+	fs.Init(expectedName, expectedErrorHandling)
+	fs.SetOutput(expectedOutput)
+
+	if fs.Name() != expectedName {
+		t.Errorf("unexpected name: got %s, expected %s", fs.Name(), expectedName)
+	}
+	if fs.ErrorHandling() != expectedErrorHandling {
+		t.Errorf("unexpected ErrorHandling: got %d, expected %d", fs.ErrorHandling(), expectedErrorHandling)
+	}
+	if fs.Output() != expectedOutput {
+		t.Errorf("unexpected output: got %v, expected %v", fs.Output(), expectedOutput)
+	}
+}
diff --git a/src/fmt/doc.go b/src/fmt/doc.go
index 014ba06..375cdb4 100644
--- a/src/fmt/doc.go
+++ b/src/fmt/doc.go
@@ -47,6 +47,8 @@
 		%X	base 16, upper-case, two characters per byte
 	Pointer:
 		%p	base 16 notation, with leading 0x
+		The %b, %d, %o, %x and %X verbs also work with pointers,
+		formatting the value exactly as if it were an integer.
 
 	The default format for %v is:
 		bool:                    %t
@@ -79,7 +81,8 @@
 	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.
+	obtained from the next operand (preceding the one to format),
+	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.
diff --git a/src/fmt/example_test.go b/src/fmt/example_test.go
new file mode 100644
index 0000000..c77e788
--- /dev/null
+++ b/src/fmt/example_test.go
@@ -0,0 +1,29 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt_test
+
+import (
+	"fmt"
+)
+
+// Animal has a Name and an Age to represent an animal.
+type Animal struct {
+	Name string
+	Age  uint
+}
+
+// String makes Animal satisfy the Stringer interface.
+func (a Animal) String() string {
+	return fmt.Sprintf("%v (%d)", a.Name, a.Age)
+}
+
+func ExampleStringer() {
+	a := Animal{
+		Name: "Gopher",
+		Age:  2,
+	}
+	fmt.Println(a)
+	// Output: Gopher (2)
+}
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index 9bec6f3..08e46b4 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -131,6 +131,19 @@
 
 var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
 
+// Copy of io.stringWriter interface used by writeStringFormatter for type assertion.
+type stringWriter interface {
+	WriteString(s string) (n int, err error)
+}
+
+type writeStringFormatter string
+
+func (sf writeStringFormatter) Format(f State, c rune) {
+	if sw, ok := f.(stringWriter); ok {
+		sw.WriteString("***" + string(sf) + "***")
+	}
+}
+
 var fmtTests = []struct {
 	fmt string
 	val interface{}
@@ -977,6 +990,11 @@
 	// This next case seems wrong, but the docs say the Formatter wins here.
 	{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
 
+	// pp.WriteString
+	{"%s", writeStringFormatter(""), "******"},
+	{"%s", writeStringFormatter("xyz"), "***xyz***"},
+	{"%s", writeStringFormatter("⌘/⌘"), "***⌘/⌘***"},
+
 	// reflect.Value handled specially in Go 1.5, making it possible to
 	// see inside non-exported fields (which cannot be accessed with Interface()).
 	// Issue 8965.
@@ -1201,6 +1219,14 @@
 	})
 }
 
+func BenchmarkSprintfSlowParsingPath(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("%.v", nil)
+		}
+	})
+}
+
 func BenchmarkSprintfQuoteString(b *testing.B) {
 	b.RunParallel(func(pb *testing.PB) {
 		for pb.Next() {
@@ -1707,12 +1733,14 @@
 	}
 }
 
+func hideFromVet(s string) string { return s }
+
 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) // go vet should complain about this line.
+	got := Sprintf(hideFromVet("%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/fmt/print.go b/src/fmt/print.go
index 2bd88f9..98c156a 100644
--- a/src/fmt/print.go
+++ b/src/fmt/print.go
@@ -172,6 +172,13 @@
 	return len(b), nil
 }
 
+// Implement WriteString so that we can call io.WriteString
+// on a pp (through state), for efficiency.
+func (p *pp) WriteString(s string) (ret int, err error) {
+	p.buf.WriteString(s)
+	return len(s), nil
+}
+
 // These routines end in 'f' and take a format string.
 
 // Fprintf formats according to a format specifier and writes to w.
@@ -837,7 +844,7 @@
 			p.buf.WriteByte(']')
 		}
 	case reflect.Ptr:
-		// pointer to array or slice or struct?  ok at top level
+		// pointer to array or slice or struct? ok at top level
 		// but not embedded (avoid loops)
 		if depth == 0 && f.Pointer() != 0 {
 			switch a := f.Elem(); a.Kind() {
@@ -1067,8 +1074,11 @@
 			break
 		}
 
-		verb, w := utf8.DecodeRuneInString(format[i:])
-		i += w
+		verb, size := rune(format[i]), 1
+		if verb >= utf8.RuneSelf {
+			verb, size = utf8.DecodeRuneInString(format[i:])
+		}
+		i += size
 
 		switch {
 		case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
diff --git a/src/fmt/scan.go b/src/fmt/scan.go
index cd7232c..ae79e39 100644
--- a/src/fmt/scan.go
+++ b/src/fmt/scan.go
@@ -298,13 +298,6 @@
 	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.RuneScanner.
@@ -421,8 +414,10 @@
 	ssFree.Put(s)
 }
 
-// skipSpace skips spaces and maybe newlines.
-func (s *ss) skipSpace(stopAtNewline bool) {
+// 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() {
 	for {
 		r := s.getRune()
 		if r == eof {
@@ -432,9 +427,6 @@
 			continue
 		}
 		if r == '\n' {
-			if stopAtNewline {
-				break
-			}
 			if s.nlIsSpace {
 				continue
 			}
@@ -453,7 +445,7 @@
 // newlines are treated as spaces.
 func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
 	if skipSpace {
-		s.skipSpace(false)
+		s.SkipSpace()
 	}
 	// read until white space or newline
 	for {
@@ -537,7 +529,7 @@
 
 // scanBool returns the value of the boolean represented by the next token.
 func (s *ss) scanBool(verb rune) bool {
-	s.skipSpace(false)
+	s.SkipSpace()
 	s.notEOF()
 	if !s.okVerb(verb, "tv", "boolean") {
 		return false
@@ -641,7 +633,7 @@
 	if verb == 'c' {
 		return s.scanRune(bitSize)
 	}
-	s.skipSpace(false)
+	s.SkipSpace()
 	s.notEOF()
 	base, digits := s.getBase(verb)
 	haveDigits := false
@@ -674,7 +666,7 @@
 	if verb == 'c' {
 		return uint64(s.scanRune(bitSize))
 	}
-	s.skipSpace(false)
+	s.SkipSpace()
 	s.notEOF()
 	base, digits := s.getBase(verb)
 	haveDigits := false
@@ -795,7 +787,7 @@
 	if !s.okVerb(verb, floatVerbs, "complex") {
 		return 0
 	}
-	s.skipSpace(false)
+	s.SkipSpace()
 	s.notEOF()
 	sreal, simag := s.complexTokens()
 	real := s.convertFloat(sreal, n/2)
@@ -809,7 +801,7 @@
 	if !s.okVerb(verb, "svqxX", "string") {
 		return ""
 	}
-	s.skipSpace(false)
+	s.SkipSpace()
 	s.notEOF()
 	switch verb {
 	case 'q':
@@ -973,13 +965,13 @@
 	// 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.SkipSpace()
 			s.notEOF()
 			*v = float32(s.convertFloat(s.floatToken(), 32))
 		}
 	case *float64:
 		if s.okVerb(verb, floatVerbs, "float64") {
-			s.skipSpace(false)
+			s.SkipSpace()
 			s.notEOF()
 			*v = s.convertFloat(s.floatToken(), 64)
 		}
@@ -1017,7 +1009,7 @@
 				v.Index(i).SetUint(uint64(str[i]))
 			}
 		case reflect.Float32, reflect.Float64:
-			s.skipSpace(false)
+			s.SkipSpace()
 			s.notEOF()
 			v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
 		case reflect.Complex64, reflect.Complex128:
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
index 9ab7b1e..c07dd5a 100644
--- a/src/go/ast/ast.go
+++ b/src/go/ast/ast.go
@@ -356,8 +356,8 @@
 	}
 )
 
-// The direction of a channel type is indicated by one
-// of the following constants.
+// The direction of a channel type is indicated by a bit
+// mask including one or both of the following constants.
 //
 type ChanDir int
 
diff --git a/src/go/ast/import.go b/src/go/ast/import.go
index 6b27fe8..be23c7f 100644
--- a/src/go/ast/import.go
+++ b/src/go/ast/import.go
@@ -123,14 +123,14 @@
 	comments := f.Comments[cstart:cend]
 
 	// Assign each comment to the import spec preceding it.
-	importComment := map[*ImportSpec][]*CommentGroup{}
+	importComments := map[*ImportSpec][]*CommentGroup{}
 	specIndex := 0
 	for _, g := range comments {
 		for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() {
 			specIndex++
 		}
 		s := specs[specIndex].(*ImportSpec)
-		importComment[s] = append(importComment[s], g)
+		importComments[s] = append(importComments[s], g)
 	}
 
 	// Sort the import specs by import path.
@@ -138,7 +138,19 @@
 	// Reassign the import paths to have the same position sequence.
 	// Reassign each comment to abut the end of its spec.
 	// Sort the comments by new position.
-	sort.Sort(byImportSpec(specs))
+	sort.Slice(specs, func(i, j int) bool {
+		ipath := importPath(specs[i])
+		jpath := importPath(specs[j])
+		if ipath != jpath {
+			return ipath < jpath
+		}
+		iname := importName(specs[i])
+		jname := importName(specs[j])
+		if iname != jname {
+			return iname < jname
+		}
+		return importComment(specs[i]) < importComment(specs[j])
+	})
 
 	// Dedup. Thanks to our sorting, we can just consider
 	// adjacent pairs of imports.
@@ -161,38 +173,16 @@
 		}
 		s.Path.ValuePos = pos[i].Start
 		s.EndPos = pos[i].End
-		for _, g := range importComment[s] {
+		for _, g := range importComments[s] {
 			for _, c := range g.List {
 				c.Slash = pos[i].End
 			}
 		}
 	}
 
-	sort.Sort(byCommentPos(comments))
+	sort.Slice(comments, func(i, j int) bool {
+		return comments[i].Pos() < comments[j].Pos()
+	})
 
 	return specs
 }
-
-type byImportSpec []Spec // slice of *ImportSpec
-
-func (x byImportSpec) Len() int      { return len(x) }
-func (x byImportSpec) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byImportSpec) Less(i, j int) bool {
-	ipath := importPath(x[i])
-	jpath := importPath(x[j])
-	if ipath != jpath {
-		return ipath < jpath
-	}
-	iname := importName(x[i])
-	jname := importName(x[j])
-	if iname != jname {
-		return iname < jname
-	}
-	return importComment(x[i]) < importComment(x[j])
-}
-
-type byCommentPos []*CommentGroup
-
-func (x byCommentPos) Len() int           { return len(x) }
-func (x byCommentPos) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
diff --git a/src/go/build/build.go b/src/go/build/build.go
index fd89871..68fb423 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -292,7 +292,10 @@
 	// 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".
 	// NOTE: If you add to this list, also update the doc comment in doc.go.
-	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4", "go1.5", "go1.6", "go1.7", "go1.8", "go1.9"}
+	const version = 10 // go1.10
+	for i := 1; i <= version; i++ {
+		c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
+	}
 
 	env := os.Getenv("CGO_ENABLED")
 	if env == "" {
@@ -541,6 +544,7 @@
 				p.Goroot = true
 				p.ImportPath = sub
 				p.Root = ctxt.GOROOT
+				setPkga() // p.ImportPath changed
 				goto Found
 			}
 		}
@@ -568,6 +572,7 @@
 				// Record it.
 				p.ImportPath = sub
 				p.Root = root
+				setPkga() // p.ImportPath changed
 				goto Found
 			}
 		}
@@ -1195,24 +1200,25 @@
 			p = p[len(p):]
 		}
 		line = bytes.TrimSpace(line)
-		if bytes.HasPrefix(line, slashslash) {
-			if bytes.Equal(line, binaryOnlyComment) {
-				sawBinaryOnly = true
-			}
-			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 !bytes.HasPrefix(line, slashslash) {
+			continue
+		}
+		if bytes.Equal(line, binaryOnlyComment) {
+			sawBinaryOnly = true
+		}
+		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
-					}
+				}
+				if !ok {
+					allok = false
 				}
 			}
 		}
diff --git a/src/go/build/build_test.go b/src/go/build/build_test.go
index 979f76c..ac5d2c3 100644
--- a/src/go/build/build_test.go
+++ b/src/go/build/build_test.go
@@ -382,3 +382,16 @@
 		t.Fatalf("error on failed import does not mention GOROOT/src/vendor directory:\n%s", e)
 	}
 }
+
+func TestImportDirTarget(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // really must just have source
+	ctxt := Default
+	ctxt.GOPATH = ""
+	p, err := ctxt.ImportDir(filepath.Join(ctxt.GOROOT, "src/path"), 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.PkgTargetRoot == "" || p.PkgObj == "" {
+		t.Errorf("p.PkgTargetRoot == %q, p.PkgObj == %q, want non-empty", p.PkgTargetRoot, p.PkgObj)
+	}
+}
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 87abfba..07a9cd3 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -35,7 +35,7 @@
 var pkgDeps = map[string][]string{
 	// L0 is the lowest level, core, nearly unavoidable packages.
 	"errors":                  {},
-	"io":                      {"errors", "sync"},
+	"io":                      {"errors", "sync", "sync/atomic"},
 	"runtime":                 {"unsafe", "runtime/internal/atomic", "runtime/internal/sys"},
 	"runtime/internal/sys":    {},
 	"runtime/internal/atomic": {"unsafe", "runtime/internal/sys"},
@@ -101,7 +101,7 @@
 	"crypto/cipher":       {"L2", "crypto/subtle"},
 	"crypto/subtle":       {},
 	"encoding/base32":     {"L2"},
-	"encoding/base64":     {"L2"},
+	"encoding/base64":     {"L2", "encoding/binary"},
 	"encoding/binary":     {"L2", "reflect"},
 	"hash":                {"L2"}, // interfaces
 	"hash/adler32":        {"L2", "hash"},
@@ -154,12 +154,13 @@
 		"syscall",
 	},
 
-	"internal/poll": {"L0", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8"},
-	"os":            {"L1", "os", "syscall", "time", "internal/poll", "internal/syscall/windows"},
-	"path/filepath": {"L2", "os", "syscall"},
-	"io/ioutil":     {"L2", "os", "path/filepath", "time"},
-	"os/exec":       {"L2", "os", "context", "path/filepath", "syscall"},
-	"os/signal":     {"L2", "os", "syscall"},
+	"internal/poll":    {"L0", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8", "internal/syscall/windows"},
+	"internal/testlog": {"L0"},
+	"os":               {"L1", "os", "syscall", "time", "internal/poll", "internal/syscall/windows", "internal/testlog"},
+	"path/filepath":    {"L2", "os", "syscall", "internal/syscall/windows"},
+	"io/ioutil":        {"L2", "os", "path/filepath", "time"},
+	"os/exec":          {"L2", "os", "context", "path/filepath", "syscall"},
+	"os/signal":        {"L2", "os", "syscall"},
 
 	// OS enables basic operating system functionality,
 	// but not direct use of package syscall, nor os/signal.
@@ -226,7 +227,7 @@
 	"go/types":                  {"L4", "GOPARSER", "container/heap", "go/constant"},
 
 	// One of a kind.
-	"archive/tar":              {"L4", "OS", "syscall"},
+	"archive/tar":              {"L4", "OS", "syscall", "os/user"},
 	"archive/zip":              {"L4", "OS", "compress/flate"},
 	"container/heap":           {"sort"},
 	"compress/bzip2":           {"L4"},
@@ -266,11 +267,11 @@
 	"math/big":                 {"L4"},
 	"mime":                     {"L4", "OS", "syscall", "internal/syscall/windows/registry"},
 	"mime/quotedprintable":     {"L4"},
-	"net/internal/socktest":    {"L4", "OS", "syscall"},
+	"net/internal/socktest":    {"L4", "OS", "syscall", "internal/syscall/windows"},
 	"net/url":                  {"L4"},
 	"plugin":                   {"L0", "OS", "CGO"},
 	"runtime/pprof/internal/profile": {"L4", "OS", "compress/gzip", "regexp"},
-	"testing/internal/testdeps":      {"L4", "runtime/pprof", "regexp"},
+	"testing/internal/testdeps":      {"L4", "internal/testlog", "runtime/pprof", "regexp"},
 	"text/scanner":                   {"L4", "OS"},
 	"text/template/parse":            {"L4"},
 
@@ -299,6 +300,9 @@
 	// Plan 9 alone needs io/ioutil and os.
 	"os/user": {"L4", "CGO", "io/ioutil", "os", "syscall"},
 
+	// Internal package used only for testing.
+	"os/signal/internal/pty": {"CGO", "fmt", "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 L0+basic os.
@@ -377,9 +381,10 @@
 	},
 	"crypto/x509": {
 		"L4", "CRYPTO-MATH", "OS", "CGO",
-		"crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "os/user", "syscall",
+		"crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "os/user", "syscall", "net/url",
+		"golang_org/x/crypto/cryptobyte", "golang_org/x/crypto/cryptobyte/asn1",
 	},
-	"crypto/x509/pkix": {"L4", "CRYPTO-MATH"},
+	"crypto/x509/pkix": {"L4", "CRYPTO-MATH", "encoding/hex"},
 
 	// Simple net+crypto-aware packages.
 	"mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto", "mime/quotedprintable"},
diff --git a/src/go/build/doc.go b/src/go/build/doc.go
index 422e1a5..daa9a75 100644
--- a/src/go/build/doc.go
+++ b/src/go/build/doc.go
@@ -106,6 +106,7 @@
 //	- "go1.7", from Go version 1.7 onward
 //	- "go1.8", from Go version 1.8 onward
 //	- "go1.9", from Go version 1.9 onward
+//	- "go1.10", from Go version 1.10 onward
 //	- any additional words listed in ctxt.BuildTags
 //
 // If a file's name, after stripping the extension and a possible _test suffix,
diff --git a/src/go/build/zcgo.go b/src/go/build/zcgo.go
index 995e4ec..51b21ab 100644
--- a/src/go/build/zcgo.go
+++ b/src/go/build/zcgo.go
@@ -1,4 +1,4 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package build
 
@@ -34,4 +34,4 @@
 	"solaris/amd64": true,
 	"windows/386": true,
 	"windows/amd64": true,
-}
\ No newline at end of file
+}
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 5474e73..64f8eb6 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -10,7 +10,7 @@
 // values produce unknown values unless specified
 // otherwise.
 //
-package constant // import "go/constant"
+package constant
 
 import (
 	"fmt"
@@ -18,6 +18,8 @@
 	"math"
 	"math/big"
 	"strconv"
+	"strings"
+	"sync"
 	"unicode/utf8"
 )
 
@@ -67,7 +69,12 @@
 type (
 	unknownVal struct{}
 	boolVal    bool
-	stringVal  string
+	stringVal  struct {
+		// Lazy value: either a string (l,r==nil) or an addition (l,r!=nil).
+		mu   sync.Mutex
+		s    string
+		l, r *stringVal
+	}
 	int64Val   int64                    // Int values representable as an int64
 	intVal     struct{ val *big.Int }   // Int values not representable as an int64
 	ratVal     struct{ val *big.Rat }   // Float values representable as a fraction
@@ -77,7 +84,7 @@
 
 func (unknownVal) Kind() Kind { return Unknown }
 func (boolVal) Kind() Kind    { return Bool }
-func (stringVal) Kind() Kind  { return String }
+func (*stringVal) Kind() Kind { return String }
 func (int64Val) Kind() Kind   { return Int }
 func (intVal) Kind() Kind     { return Int }
 func (ratVal) Kind() Kind     { return Float }
@@ -88,9 +95,9 @@
 func (x boolVal) String() string  { return strconv.FormatBool(bool(x)) }
 
 // String returns a possibly shortened quoted form of the String value.
-func (x stringVal) String() string {
+func (x *stringVal) String() string {
 	const maxLen = 72 // a reasonable length
-	s := strconv.Quote(string(x))
+	s := strconv.Quote(x.string())
 	if utf8.RuneCountInString(s) > maxLen {
 		// The string without the enclosing quotes is greater than maxLen-2 runes
 		// long. Remove the last 3 runes (including the closing '"') by keeping
@@ -105,6 +112,60 @@
 	return s
 }
 
+// string constructs and returns the actual string literal value.
+// If x represents an addition, then it rewrites x to be a single
+// string, to speed future calls. This lazy construction avoids
+// building different string values for all subpieces of a large
+// concatenation. See golang.org/issue/23348.
+func (x *stringVal) string() string {
+	x.mu.Lock()
+	if x.l != nil {
+		x.s = strings.Join(reverse(x.appendReverse(nil)), "")
+		x.l = nil
+		x.r = nil
+	}
+	s := x.s
+	x.mu.Unlock()
+
+	return s
+}
+
+// reverse reverses x in place and returns it.
+func reverse(x []string) []string {
+	n := len(x)
+	for i := 0; i+i < n; i++ {
+		x[i], x[n-1-i] = x[n-1-i], x[i]
+	}
+	return x
+}
+
+// appendReverse appends to list all of x's subpieces, but in reverse,
+// and returns the result. Appending the reversal allows processing
+// the right side in a recursive call and the left side in a loop.
+// Because a chain like a + b + c + d + e is actually represented
+// as ((((a + b) + c) + d) + e), the left-side loop avoids deep recursion.
+// x must be locked.
+func (x *stringVal) appendReverse(list []string) []string {
+	y := x
+	for y.r != nil {
+		y.r.mu.Lock()
+		list = y.r.appendReverse(list)
+		y.r.mu.Unlock()
+
+		l := y.l
+		if y != x {
+			y.mu.Unlock()
+		}
+		l.mu.Lock()
+		y = l
+	}
+	s := y.s
+	if y != x {
+		y.mu.Unlock()
+	}
+	return append(list, s)
+}
+
 func (x int64Val) String() string { return strconv.FormatInt(int64(x), 10) }
 func (x intVal) String() string   { return x.val.String() }
 func (x ratVal) String() string   { return rtof(x).String() }
@@ -160,7 +221,7 @@
 
 func (x unknownVal) ExactString() string { return x.String() }
 func (x boolVal) ExactString() string    { return x.String() }
-func (x stringVal) ExactString() string  { return strconv.Quote(string(x)) }
+func (x *stringVal) ExactString() string { return strconv.Quote(x.string()) }
 func (x int64Val) ExactString() string   { return x.String() }
 func (x intVal) ExactString() string     { return x.String() }
 
@@ -180,7 +241,7 @@
 
 func (unknownVal) implementsValue() {}
 func (boolVal) implementsValue()    {}
-func (stringVal) implementsValue()  {}
+func (*stringVal) implementsValue() {}
 func (int64Val) implementsValue()   {}
 func (ratVal) implementsValue()     {}
 func (intVal) implementsValue()     {}
@@ -283,7 +344,7 @@
 func MakeBool(b bool) Value { return boolVal(b) }
 
 // MakeString returns the String value for s.
-func MakeString(s string) Value { return stringVal(s) }
+func MakeString(s string) Value { return &stringVal{s: s} }
 
 // MakeInt64 returns the Int value for x.
 func MakeInt64(x int64) Value { return int64Val(x) }
@@ -382,8 +443,8 @@
 // If x is Unknown, the result is "".
 func StringVal(x Value) string {
 	switch x := x.(type) {
-	case stringVal:
-		return string(x)
+	case *stringVal:
+		return x.string()
 	case unknownVal:
 		return ""
 	default:
@@ -856,7 +917,7 @@
 		return -1
 	case unknownVal:
 		return 0
-	case boolVal, stringVal:
+	case boolVal, *stringVal:
 		return 1
 	case int64Val:
 		return 2
@@ -884,7 +945,7 @@
 	// ord(x) <= ord(y)
 
 	switch x := x.(type) {
-	case boolVal, stringVal, complexVal:
+	case boolVal, *stringVal, complexVal:
 		return x, y
 
 	case int64Val:
@@ -1108,9 +1169,9 @@
 		}
 		return makeComplex(re, im)
 
-	case stringVal:
+	case *stringVal:
 		if op == token.ADD {
-			return x + y.(stringVal)
+			return &stringVal{l: x, r: y.(*stringVal)}
 		}
 	}
 
@@ -1236,21 +1297,22 @@
 			return !re || !im
 		}
 
-	case stringVal:
-		y := y.(stringVal)
+	case *stringVal:
+		xs := x.string()
+		ys := y.(*stringVal).string()
 		switch op {
 		case token.EQL:
-			return x == y
+			return xs == ys
 		case token.NEQ:
-			return x != y
+			return xs != ys
 		case token.LSS:
-			return x < y
+			return xs < ys
 		case token.LEQ:
-			return x <= y
+			return xs <= ys
 		case token.GTR:
-			return x > y
+			return xs > ys
 		case token.GEQ:
-			return x >= y
+			return xs >= ys
 		}
 	}
 
diff --git a/src/go/constant/value_test.go b/src/go/constant/value_test.go
index 954a0e0..5ec4f4c 100644
--- a/src/go/constant/value_test.go
+++ b/src/go/constant/value_test.go
@@ -5,6 +5,7 @@
 package constant
 
 import (
+	"fmt"
 	"go/token"
 	"strings"
 	"testing"
@@ -449,3 +450,23 @@
 		}
 	}
 }
+
+func BenchmarkStringAdd(b *testing.B) {
+	for size := 1; size <= 65536; size *= 4 {
+		b.Run(fmt.Sprint(size), func(b *testing.B) {
+			b.ReportAllocs()
+			n := int64(0)
+			for i := 0; i < b.N; i++ {
+				x := MakeString(strings.Repeat("x", 100))
+				y := x
+				for j := 0; j < size-1; j++ {
+					y = BinaryOp(y, token.ADD, x)
+				}
+				n += int64(len(StringVal(y)))
+			}
+			if n != int64(b.N)*int64(size)*100 {
+				b.Fatalf("bad string %d != %d", n, int64(b.N)*int64(size)*100)
+			}
+		})
+	}
+}
diff --git a/src/go/doc/example.go b/src/go/doc/example.go
index bbf8096..a89f29b 100644
--- a/src/go/doc/example.go
+++ b/src/go/doc/example.go
@@ -94,7 +94,10 @@
 		}
 		list = append(list, flist...)
 	}
-	sort.Sort(exampleByName(list))
+	// sort by name
+	sort.Slice(list, func(i, j int) bool {
+		return list[i].Name < list[j].Name
+	})
 	return list
 }
 
@@ -135,12 +138,6 @@
 	return !unicode.IsLower(rune)
 }
 
-type exampleByName []*Example
-
-func (s exampleByName) Len() int           { return len(s) }
-func (s exampleByName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s exampleByName) Less(i, j int) bool { return s[i].Name < s[j].Name }
-
 // playExample synthesizes a new *ast.File based on the provided
 // file with the provided function body as the body of main.
 func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
diff --git a/src/go/doc/exports.go b/src/go/doc/exports.go
index da9ea1f..40cbb22 100644
--- a/src/go/doc/exports.go
+++ b/src/go/doc/exports.go
@@ -200,7 +200,7 @@
 		var prevType ast.Expr
 		for _, spec := range list {
 			spec := spec.(*ast.ValueSpec)
-			if spec.Type == nil && prevType != nil {
+			if spec.Type == nil && len(spec.Values) == 0 && prevType != nil {
 				// provide current spec with an explicit type
 				spec.Type = copyConstType(prevType, spec.Pos())
 			}
diff --git a/src/go/doc/reader.go b/src/go/doc/reader.go
index 8e82353..140f587 100644
--- a/src/go/doc/reader.go
+++ b/src/go/doc/reader.go
@@ -154,6 +154,7 @@
 	imports   map[string]int
 	hasDotImp bool     // if set, package contains a dot import
 	values    []*Value // consts and vars
+	order     int      // sort order of const and var declarations (when we can't use a name)
 	types     map[string]*namedType
 	funcs     methodSet
 
@@ -256,11 +257,9 @@
 			if n, imp := baseTypeName(s.Type); !imp {
 				name = n
 			}
-		case decl.Tok == token.CONST:
-			// no type is present but we have a constant declaration;
-			// use the previous type name (w/o more type information
-			// we cannot handle the case of unnamed variables with
-			// initializer expressions except for some trivial cases)
+		case decl.Tok == token.CONST && len(s.Values) == 0:
+			// no type or value is present but we have a constant declaration;
+			// use the previous type name (possibly the empty string)
 			name = prev
 		}
 		if name != "" {
@@ -297,9 +296,15 @@
 		Doc:   decl.Doc.Text(),
 		Names: specNames(decl.Specs),
 		Decl:  decl,
-		order: len(*values),
+		order: r.order,
 	})
 	decl.Doc = nil // doc consumed - remove from AST
+
+	// Note: It's important that the order used here is global because the cleanupTypes
+	// methods may move values associated with types back into the global list. If the
+	// order is list-specific, sorting is not deterministic because the same order value
+	// may appear multiple times (was bug, found when fixing #16153).
+	r.order++
 }
 
 // fields returns a struct's fields or an interface's methods.
@@ -391,7 +396,13 @@
 			// exactly one (named or anonymous) result associated
 			// with the first type in result signature (there may
 			// be more than one result)
-			if n, imp := baseTypeName(res.Type); !imp && r.isVisible(n) {
+			factoryType := res.Type
+			if t, ok := factoryType.(*ast.ArrayType); ok && t.Len == nil {
+				// We consider functions that return slices of type T (or
+				// pointers to T) as factory functions of T.
+				factoryType = t.Elt
+			}
+			if n, imp := baseTypeName(factoryType); !imp && r.isVisible(n) {
 				if typ := r.lookupType(n); typ != nil {
 					// associate function with typ
 					typ.funcs.set(fun)
diff --git a/src/go/doc/testdata/blank.0.golden b/src/go/doc/testdata/blank.0.golden
index c2987cf..70f2929 100644
--- a/src/go/doc/testdata/blank.0.golden
+++ b/src/go/doc/testdata/blank.0.golden
@@ -21,11 +21,18 @@
 		C4	int
 	)
 
-	// Constants with an imported type that needs to be propagated. 
+	// Constants with a single type that is not propagated. 
 	const (
-		Default		os.FileMode	= 0644
-		Useless				= 0312
-		WideOpen			= 0777
+		Default		= 0644
+		Useless		= 0312
+		WideOpen	= 0777
+	)
+
+	// Constants with an imported type that is propagated. 
+	const (
+		M1	os.FileMode
+		M2
+		M3
 	)
 
 	// Package constants. 
diff --git a/src/go/doc/testdata/blank.1.golden b/src/go/doc/testdata/blank.1.golden
index ee5054a..8098cb6 100644
--- a/src/go/doc/testdata/blank.1.golden
+++ b/src/go/doc/testdata/blank.1.golden
@@ -23,14 +23,7 @@
 		C4
 	)
 
-	// Package constants. 
-	const (
-		_	int	= iota
-		I1
-		I2
-	)
-
-	// Constants with an imported type that needs to be propagated. 
+	// Constants with a single type that is not propagated. 
 	const (
 		zero		os.FileMode	= 0
 		Default				= 0644
@@ -38,6 +31,21 @@
 		WideOpen			= 0777
 	)
 
+	// Constants with an imported type that is propagated. 
+	const (
+		zero	os.FileMode	= 0
+		M1
+		M2
+		M3
+	)
+
+	// Package constants. 
+	const (
+		_	int	= iota
+		I1
+		I2
+	)
+
 	// Unexported constants counting from blank iota. See issue 9615. 
 	const (
 		_	= iota
diff --git a/src/go/doc/testdata/blank.2.golden b/src/go/doc/testdata/blank.2.golden
index c2987cf..70f2929 100644
--- a/src/go/doc/testdata/blank.2.golden
+++ b/src/go/doc/testdata/blank.2.golden
@@ -21,11 +21,18 @@
 		C4	int
 	)
 
-	// Constants with an imported type that needs to be propagated. 
+	// Constants with a single type that is not propagated. 
 	const (
-		Default		os.FileMode	= 0644
-		Useless				= 0312
-		WideOpen			= 0777
+		Default		= 0644
+		Useless		= 0312
+		WideOpen	= 0777
+	)
+
+	// Constants with an imported type that is propagated. 
+	const (
+		M1	os.FileMode
+		M2
+		M3
 	)
 
 	// Package constants. 
diff --git a/src/go/doc/testdata/blank.go b/src/go/doc/testdata/blank.go
index 419a78f..5ea6186 100644
--- a/src/go/doc/testdata/blank.go
+++ b/src/go/doc/testdata/blank.go
@@ -29,7 +29,7 @@
 	C4
 )
 
-// Constants with an imported type that needs to be propagated.
+// Constants with a single type that is not propagated.
 const (
 	zero     os.FileMode = 0
 	Default              = 0644
@@ -37,6 +37,14 @@
 	WideOpen             = 0777
 )
 
+// Constants with an imported type that is propagated.
+const (
+	zero os.FileMode = 0
+	M1
+	M2
+	M3
+)
+
 // Package constants.
 const (
 	_ int = iota
diff --git a/src/go/doc/testdata/issue16153.0.golden b/src/go/doc/testdata/issue16153.0.golden
new file mode 100644
index 0000000..189260b
--- /dev/null
+++ b/src/go/doc/testdata/issue16153.0.golden
@@ -0,0 +1,32 @@
+// 
+PACKAGE issue16153
+
+IMPORTPATH
+	testdata/issue16153
+
+FILENAMES
+	testdata/issue16153.go
+
+CONSTANTS
+	// 
+	const (
+		X3	int64	= iota
+		Y3		= 1
+	)
+
+	// 
+	const (
+		X4	int64	= iota
+		Y4
+	)
+
+	// original test case 
+	const (
+		Y1 = 256
+	)
+
+	// variations 
+	const (
+		Y2 uint8
+	)
+
diff --git a/src/go/doc/testdata/issue16153.1.golden b/src/go/doc/testdata/issue16153.1.golden
new file mode 100644
index 0000000..803df3e
--- /dev/null
+++ b/src/go/doc/testdata/issue16153.1.golden
@@ -0,0 +1,34 @@
+// 
+PACKAGE issue16153
+
+IMPORTPATH
+	testdata/issue16153
+
+FILENAMES
+	testdata/issue16153.go
+
+CONSTANTS
+	// original test case 
+	const (
+		x1	uint8	= 255
+		Y1		= 256
+	)
+
+	// variations 
+	const (
+		x2	uint8	= 255
+		Y2
+	)
+
+	// 
+	const (
+		X3	int64	= iota
+		Y3		= 1
+	)
+
+	// 
+	const (
+		X4	int64	= iota
+		Y4
+	)
+
diff --git a/src/go/doc/testdata/issue16153.2.golden b/src/go/doc/testdata/issue16153.2.golden
new file mode 100644
index 0000000..189260b
--- /dev/null
+++ b/src/go/doc/testdata/issue16153.2.golden
@@ -0,0 +1,32 @@
+// 
+PACKAGE issue16153
+
+IMPORTPATH
+	testdata/issue16153
+
+FILENAMES
+	testdata/issue16153.go
+
+CONSTANTS
+	// 
+	const (
+		X3	int64	= iota
+		Y3		= 1
+	)
+
+	// 
+	const (
+		X4	int64	= iota
+		Y4
+	)
+
+	// original test case 
+	const (
+		Y1 = 256
+	)
+
+	// variations 
+	const (
+		Y2 uint8
+	)
+
diff --git a/src/go/doc/testdata/issue16153.go b/src/go/doc/testdata/issue16153.go
new file mode 100644
index 0000000..528be42
--- /dev/null
+++ b/src/go/doc/testdata/issue16153.go
@@ -0,0 +1,27 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue16153
+
+// original test case
+const (
+	x1 uint8 = 255
+	Y1       = 256
+)
+
+// variations
+const (
+	x2 uint8 = 255
+	Y2
+)
+
+const (
+	X3 int64 = iota
+	Y3       = 1
+)
+
+const (
+	X4 int64 = iota
+	Y4
+)
diff --git a/src/go/doc/testdata/issue18063.0.golden b/src/go/doc/testdata/issue18063.0.golden
new file mode 100644
index 0000000..0afbc16
--- /dev/null
+++ b/src/go/doc/testdata/issue18063.0.golden
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+	testdata/issue18063
+
+FILENAMES
+	testdata/issue18063.go
+
+FUNCTIONS
+	// NewArray is not a factory function because arrays of type T are ...
+	func NewArray() [1]T
+
+	// NewPointerArray is not a factory function because arrays of ...
+	func NewPointerArray() [1]*T
+
+	// NewPointerSliceOfSlice is not a factory function because slices ...
+	func NewPointerSliceOfSlice() [][]*T
+
+	// NewSlice3 is not a factory function because 3 nested slices of ...
+	func NewSlice3() [][][]T
+
+	// NewSliceOfSlice is not a factory function because slices of a ...
+	func NewSliceOfSlice() [][]T
+
+
+TYPES
+	// 
+	type T struct{}
+
+	// 
+	func New() T
+
+	// 
+	func NewPointer() *T
+
+	// 
+	func NewPointerOfPointer() **T
+
+	// 
+	func NewPointerSlice() []*T
+
+	// 
+	func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.1.golden b/src/go/doc/testdata/issue18063.1.golden
new file mode 100644
index 0000000..0afbc16
--- /dev/null
+++ b/src/go/doc/testdata/issue18063.1.golden
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+	testdata/issue18063
+
+FILENAMES
+	testdata/issue18063.go
+
+FUNCTIONS
+	// NewArray is not a factory function because arrays of type T are ...
+	func NewArray() [1]T
+
+	// NewPointerArray is not a factory function because arrays of ...
+	func NewPointerArray() [1]*T
+
+	// NewPointerSliceOfSlice is not a factory function because slices ...
+	func NewPointerSliceOfSlice() [][]*T
+
+	// NewSlice3 is not a factory function because 3 nested slices of ...
+	func NewSlice3() [][][]T
+
+	// NewSliceOfSlice is not a factory function because slices of a ...
+	func NewSliceOfSlice() [][]T
+
+
+TYPES
+	// 
+	type T struct{}
+
+	// 
+	func New() T
+
+	// 
+	func NewPointer() *T
+
+	// 
+	func NewPointerOfPointer() **T
+
+	// 
+	func NewPointerSlice() []*T
+
+	// 
+	func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.2.golden b/src/go/doc/testdata/issue18063.2.golden
new file mode 100644
index 0000000..0afbc16
--- /dev/null
+++ b/src/go/doc/testdata/issue18063.2.golden
@@ -0,0 +1,45 @@
+// 
+PACKAGE issue18063
+
+IMPORTPATH
+	testdata/issue18063
+
+FILENAMES
+	testdata/issue18063.go
+
+FUNCTIONS
+	// NewArray is not a factory function because arrays of type T are ...
+	func NewArray() [1]T
+
+	// NewPointerArray is not a factory function because arrays of ...
+	func NewPointerArray() [1]*T
+
+	// NewPointerSliceOfSlice is not a factory function because slices ...
+	func NewPointerSliceOfSlice() [][]*T
+
+	// NewSlice3 is not a factory function because 3 nested slices of ...
+	func NewSlice3() [][][]T
+
+	// NewSliceOfSlice is not a factory function because slices of a ...
+	func NewSliceOfSlice() [][]T
+
+
+TYPES
+	// 
+	type T struct{}
+
+	// 
+	func New() T
+
+	// 
+	func NewPointer() *T
+
+	// 
+	func NewPointerOfPointer() **T
+
+	// 
+	func NewPointerSlice() []*T
+
+	// 
+	func NewSlice() []T
+
diff --git a/src/go/doc/testdata/issue18063.go b/src/go/doc/testdata/issue18063.go
new file mode 100644
index 0000000..1193af5
--- /dev/null
+++ b/src/go/doc/testdata/issue18063.go
@@ -0,0 +1,33 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue18063
+
+type T struct{}
+
+func New() T                   { return T{} }
+func NewPointer() *T           { return &T{} }
+func NewPointerSlice() []*T    { return []*T{&T{}} }
+func NewSlice() []T            { return []T{T{}} }
+func NewPointerOfPointer() **T { x := &T{}; return &x }
+
+// NewArray is not a factory function because arrays of type T are not
+// factory functions of type T.
+func NewArray() [1]T { return [1]T{T{}} }
+
+// NewPointerArray is not a factory function because arrays of type *T are not
+// factory functions of type T.
+func NewPointerArray() [1]*T { return [1]*T{&T{}} }
+
+// NewSliceOfSlice is not a factory function because slices of a slice of
+// type *T are not factory functions of type T.
+func NewSliceOfSlice() [][]T { return []T{[]T{}} }
+
+// NewPointerSliceOfSlice is not a factory function because slices of a
+// slice of type *T are not factory functions of type T.
+func NewPointerSliceOfSlice() [][]*T { return []*T{[]*T{}} }
+
+// NewSlice3 is not a factory function because 3 nested slices of type T
+// are not factory functions of type T.
+func NewSlice3() [][][]T { return []T{[]T{[]T{}}} }
diff --git a/src/go/format/format.go b/src/go/format/format.go
index b9cacfe..cad5958 100644
--- a/src/go/format/format.go
+++ b/src/go/format/format.go
@@ -24,8 +24,8 @@
 // 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).
+// nodes representing partial source files (for instance, 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.
@@ -79,6 +79,10 @@
 // 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.
 //
+// Caution: Tools relying on consistent formatting based on the installed
+// version of gofmt (for instance, such as for presubmit checks) should
+// execute that gofmt binary instead of calling Source.
+//
 func Source(src []byte) ([]byte, error) {
 	fset := token.NewFileSet()
 	file, sourceAdj, indentAdj, err := parse(fset, "", src, true)
diff --git a/src/go/importer/importer.go b/src/go/importer/importer.go
index fab6518..f0a1ca2 100644
--- a/src/go/importer/importer.go
+++ b/src/go/importer/importer.go
@@ -29,23 +29,25 @@
 // checker won't have access to those).
 //
 // If lookup is nil, the default package lookup mechanism for the
-// given compiler is used.
+// given compiler is used, and the resulting importer attempts
+// to resolve relative and absolute import paths to canonical
+// import path IDs before finding the imported file.
 //
-// BUG(issue13847): For does not support non-nil lookup functions.
+// If lookup is non-nil, then the returned importer calls lookup
+// each time it needs to resolve an import path. In this mode
+// the importer can only be invoked with canonical import paths
+// (not relative or absolute ones); it is assumed that the translation
+// to canonical import paths is being done by the client of the
+// importer.
 func For(compiler string, lookup Lookup) types.Importer {
 	switch compiler {
 	case "gc":
-		if lookup != nil {
-			panic("gc importer for custom import path lookup not supported (issue #13847).")
+		return &gcimports{
+			packages: make(map[string]*types.Package),
+			lookup:   lookup,
 		}
 
-		return make(gcimports)
-
 	case "gccgo":
-		if lookup != nil {
-			panic("gccgo importer for custom import path lookup not supported (issue #13847).")
-		}
-
 		var inst gccgoimporter.GccgoInstallation
 		if err := inst.InitFromDriver("gccgo"); err != nil {
 			return nil
@@ -53,6 +55,7 @@
 		return &gccgoimports{
 			packages: make(map[string]*types.Package),
 			importer: inst.GetImporter(nil, nil),
+			lookup:   lookup,
 		}
 
 	case "source":
@@ -75,17 +78,20 @@
 
 // gc importer
 
-type gcimports map[string]*types.Package
+type gcimports struct {
+	packages map[string]*types.Package
+	lookup   Lookup
+}
 
-func (m gcimports) Import(path string) (*types.Package, error) {
+func (m *gcimports) Import(path string) (*types.Package, error) {
 	return m.ImportFrom(path, "" /* no vendoring */, 0)
 }
 
-func (m gcimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) {
+func (m *gcimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) {
 	if mode != 0 {
 		panic("mode must be 0")
 	}
-	return gcimporter.Import(m, path, srcDir)
+	return gcimporter.Import(m.packages, path, srcDir, m.lookup)
 }
 
 // gccgo importer
@@ -93,6 +99,7 @@
 type gccgoimports struct {
 	packages map[string]*types.Package
 	importer gccgoimporter.Importer
+	lookup   Lookup
 }
 
 func (m *gccgoimports) Import(path string) (*types.Package, error) {
@@ -103,6 +110,5 @@
 	if mode != 0 {
 		panic("mode must be 0")
 	}
-	// TODO(gri) pass srcDir
-	return m.importer(m.packages, path)
+	return m.importer(m.packages, path, srcDir, m.lookup)
 }
diff --git a/src/go/importer/importer_test.go b/src/go/importer/importer_test.go
new file mode 100644
index 0000000..56e8313
--- /dev/null
+++ b/src/go/importer/importer_test.go
@@ -0,0 +1,68 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importer
+
+import (
+	"internal/testenv"
+	"io"
+	"os"
+	"os/exec"
+	"strings"
+	"testing"
+)
+
+func TestFor(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	const thePackage = "math/big"
+	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f={{context.Compiler}}:{{.Target}}", thePackage).CombinedOutput()
+	if err != nil {
+		t.Fatalf("go list %s: %v\n%s", thePackage, err, out)
+	}
+	target := strings.TrimSpace(string(out))
+	i := strings.Index(target, ":")
+	compiler, target := target[:i], target[i+1:]
+	if !strings.HasSuffix(target, ".a") {
+		t.Fatalf("unexpected package %s target %q (not *.a)", thePackage, target)
+	}
+
+	if compiler == "gccgo" {
+		t.Skip("golang.org/issue/22500")
+	}
+
+	t.Run("LookupDefault", func(t *testing.T) {
+		imp := For(compiler, nil)
+		pkg, err := imp.Import(thePackage)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if pkg.Path() != thePackage {
+			t.Fatalf("Path() = %q, want %q", pkg.Path(), thePackage)
+		}
+	})
+
+	t.Run("LookupCustom", func(t *testing.T) {
+		lookup := func(path string) (io.ReadCloser, error) {
+			if path != "math/bigger" {
+				t.Fatalf("lookup called with unexpected path %q", path)
+			}
+			f, err := os.Open(target)
+			if err != nil {
+				t.Fatal(err)
+			}
+			return f, nil
+		}
+		imp := For(compiler, lookup)
+		pkg, err := imp.Import("math/bigger")
+		if err != nil {
+			t.Fatal(err)
+		}
+		// Even though we open math/big.a, the import request was for math/bigger
+		// and that should be recorded in pkg.Path(), at least for the gc toolchain.
+		if pkg.Path() != "math/bigger" {
+			t.Fatalf("Path() = %q, want %q", pkg.Path(), "math/bigger")
+		}
+	})
+}
diff --git a/src/go/internal/gccgoimporter/gccgoinstallation_test.go b/src/go/internal/gccgoimporter/gccgoinstallation_test.go
index ef293ed..da4931e 100644
--- a/src/go/internal/gccgoimporter/gccgoinstallation_test.go
+++ b/src/go/internal/gccgoimporter/gccgoinstallation_test.go
@@ -62,8 +62,6 @@
 	"encoding/pem",
 	"encoding/xml",
 	"errors",
-	"exp/proxy",
-	"exp/terminal",
 	"expvar",
 	"flag",
 	"fmt",
@@ -114,8 +112,6 @@
 	"net/smtp",
 	"net/textproto",
 	"net/url",
-	"old/regexp",
-	"old/template",
 	"os/exec",
 	"os",
 	"os/signal",
@@ -152,7 +148,6 @@
 	// were compiled with gccgo.
 	if runtime.Compiler != "gccgo" {
 		t.Skip("This test needs gccgo")
-		return
 	}
 
 	var inst GccgoInstallation
@@ -166,14 +161,14 @@
 	// all packages into the same map and then each individually.
 	pkgMap := make(map[string]*types.Package)
 	for _, pkg := range importablePackages {
-		_, err = imp(pkgMap, pkg)
+		_, err = imp(pkgMap, pkg, ".", nil)
 		if err != nil {
 			t.Error(err)
 		}
 	}
 
 	for _, pkg := range importablePackages {
-		_, err = imp(make(map[string]*types.Package), pkg)
+		_, err = imp(make(map[string]*types.Package), pkg, ".", nil)
 		if err != nil {
 			t.Error(err)
 		}
diff --git a/src/go/internal/gccgoimporter/importer.go b/src/go/internal/gccgoimporter/importer.go
index a22d8fe..4654423 100644
--- a/src/go/internal/gccgoimporter/importer.go
+++ b/src/go/internal/gccgoimporter/importer.go
@@ -137,25 +137,53 @@
 // the map entry. Otherwise, the importer must load the package data for the
 // given path into a new *Package, record it in imports map, and return the
 // package.
-type Importer func(imports map[string]*types.Package, path string) (*types.Package, error)
+type Importer func(imports map[string]*types.Package, path, srcDir string, lookup func(string) (io.ReadCloser, error)) (*types.Package, error)
 
 func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Importer {
-	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
+	return func(imports map[string]*types.Package, pkgpath, srcDir string, lookup func(string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+		// TODO(gri): Use srcDir.
+		// Or not. It's possible that srcDir will fade in importance as
+		// the go command and other tools provide a translation table
+		// for relative imports (like ./foo or vendored imports).
 		if pkgpath == "unsafe" {
 			return types.Unsafe, nil
 		}
 
-		fpath, err := findExportFile(searchpaths, pkgpath)
-		if err != nil {
-			return
-		}
+		var reader io.ReadSeeker
+		var fpath string
+		if lookup != nil {
+			if p := imports[pkgpath]; p != nil && p.Complete() {
+				return p, nil
+			}
+			rc, err := lookup(pkgpath)
+			if err != nil {
+				return nil, err
+			}
+			defer rc.Close()
+			rs, ok := rc.(io.ReadSeeker)
+			if !ok {
+				return nil, fmt.Errorf("gccgo importer requires lookup to return an io.ReadSeeker, have %T", rc)
+			}
+			reader = rs
+			fpath = "<lookup " + pkgpath + ">"
+			// Take name from Name method (like on os.File) if present.
+			if n, ok := rc.(interface{ Name() string }); ok {
+				fpath = n.Name()
+			}
+		} else {
+			fpath, err = findExportFile(searchpaths, pkgpath)
+			if err != nil {
+				return nil, err
+			}
 
-		reader, closer, err := openExportFile(fpath)
-		if err != nil {
-			return
-		}
-		if closer != nil {
-			defer closer.Close()
+			r, closer, err := openExportFile(fpath)
+			if err != nil {
+				return nil, err
+			}
+			if closer != nil {
+				defer closer.Close()
+			}
+			reader = r
 		}
 
 		var magic [4]byte
diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go
index 4fca828..01ab47a 100644
--- a/src/go/internal/gccgoimporter/importer_test.go
+++ b/src/go/internal/gccgoimporter/importer_test.go
@@ -21,7 +21,7 @@
 }
 
 func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]InitData, test *importerTest) {
-	pkg, err := imp(make(map[string]*types.Package), test.pkgpath)
+	pkg, err := imp(make(map[string]*types.Package), test.pkgpath, ".", nil)
 	if err != nil {
 		t.Error(err)
 		return
@@ -102,6 +102,7 @@
 	{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
 	{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
 	{pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
+	{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
 }
 
 func TestGoxImporter(t *testing.T) {
@@ -122,7 +123,6 @@
 	// were compiled with gccgo.
 	if runtime.Compiler != "gccgo" {
 		t.Skip("This test needs gccgo")
-		return
 	}
 
 	tmpdir, err := ioutil.TempDir("", "")
diff --git a/src/go/internal/gccgoimporter/parser.go b/src/go/internal/gccgoimporter/parser.go
index 8a1ad5f..4b3d899 100644
--- a/src/go/internal/gccgoimporter/parser.go
+++ b/src/go/internal/gccgoimporter/parser.go
@@ -226,6 +226,14 @@
 // Param = Name ["..."] Type .
 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
 	name := p.parseName()
+	if p.tok == '<' && p.scanner.Peek() == 'e' {
+		// EscInfo = "<esc:" int ">" . (optional and ignored)
+		p.next()
+		p.expectKeyword("esc")
+		p.expect(':')
+		p.expect(scanner.Int)
+		p.expect('>')
+	}
 	if p.tok == '.' {
 		p.next()
 		p.expect('.')
diff --git a/src/go/internal/gccgoimporter/parser_test.go b/src/go/internal/gccgoimporter/parser_test.go
index b96486f..4a103dc 100644
--- a/src/go/internal/gccgoimporter/parser_test.go
+++ b/src/go/internal/gccgoimporter/parser_test.go
@@ -45,6 +45,11 @@
 			t.Errorf("expected full parse, stopped at %q", p.lit)
 		}
 
+		// interfaces must be explicitly completed
+		if ityp, _ := typ.(*types.Interface); ityp != nil {
+			ityp.Complete()
+		}
+
 		got := typ.String()
 		if got != test.want {
 			t.Errorf("got type %q, expected %q", got, test.want)
diff --git a/src/go/internal/gccgoimporter/testdata/escapeinfo.go b/src/go/internal/gccgoimporter/testdata/escapeinfo.go
new file mode 100644
index 0000000..103ad95
--- /dev/null
+++ b/src/go/internal/gccgoimporter/testdata/escapeinfo.go
@@ -0,0 +1,13 @@
+// Test case for escape info in export data. To compile and extract .gox file:
+// gccgo -fgo-optimize-allocs -c escapeinfo.go
+// objcopy -j .go_export escapeinfo.o escapeinfo.gox
+
+package escapeinfo
+
+type T struct{ data []byte }
+
+func NewT(data []byte) *T {
+	return &T{data}
+}
+
+func (*T) Read(p []byte) {}
diff --git a/src/go/internal/gccgoimporter/testdata/escapeinfo.gox b/src/go/internal/gccgoimporter/testdata/escapeinfo.gox
new file mode 100644
index 0000000..1db8156
--- /dev/null
+++ b/src/go/internal/gccgoimporter/testdata/escapeinfo.gox
Binary files differ
diff --git a/src/go/internal/gcimporter/bimport.go b/src/go/internal/gcimporter/bimport.go
index 2045f55..23c1d2f 100644
--- a/src/go/internal/gcimporter/bimport.go
+++ b/src/go/internal/gcimporter/bimport.go
@@ -123,7 +123,7 @@
 	// read package data
 	pkg = p.pkg()
 
-	// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
+	// read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
 	objcount := 0
 	for {
 		tag := p.tagOrIndex()
diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
index f3f90f2..2185f5b 100644
--- a/src/go/internal/gcimporter/gcimporter.go
+++ b/src/go/internal/gcimporter/gcimporter.go
@@ -11,6 +11,7 @@
 	"go/build"
 	"go/token"
 	"go/types"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -84,36 +85,60 @@
 // the corresponding package object to the packages map, and returns the object.
 // The packages map must contain all packages already imported.
 //
-func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types.Package, err error) {
-	filename, id := FindPkg(path, srcDir)
-	if filename == "" {
+func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+	var rc io.ReadCloser
+	var id string
+	if lookup != nil {
+		// With custom lookup specified, assume that caller has
+		// converted path to a canonical import path for use in the map.
 		if path == "unsafe" {
 			return types.Unsafe, nil
 		}
-		err = fmt.Errorf("can't find import: %q", id)
-		return
-	}
+		id = path
 
-	// no need to re-import if the package was imported completely before
-	if pkg = packages[id]; pkg != nil && pkg.Complete() {
-		return
-	}
+		// No need to re-import if the package was imported completely before.
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+		f, err := lookup(path)
+		if err != nil {
+			return nil, err
+		}
+		rc = f
+	} else {
+		var filename string
+		filename, id = FindPkg(path, srcDir)
+		if filename == "" {
+			if path == "unsafe" {
+				return types.Unsafe, nil
+			}
+			return nil, fmt.Errorf("can't find import: %q", id)
+		}
 
-	// open file
-	f, err := os.Open(filename)
-	if err != nil {
-		return
+		// no need to re-import if the package was imported completely before
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+
+		// open file
+		f, err := os.Open(filename)
+		if err != nil {
+			return nil, err
+		}
+		defer func() {
+			if err != nil {
+				// add file name to error
+				err = fmt.Errorf("%s: %v", filename, err)
+			}
+		}()
+		rc = f
 	}
 	defer func() {
-		f.Close()
-		if err != nil {
-			// add file name to error
-			err = fmt.Errorf("%s: %v", filename, err)
-		}
+		rc.Close()
 	}()
 
 	var hdr string
-	buf := bufio.NewReader(f)
+	buf := bufio.NewReader(rc)
 	if hdr, err = FindExportData(buf); err != nil {
 		return
 	}
diff --git a/src/go/internal/gcimporter/gcimporter_test.go b/src/go/internal/gcimporter/gcimporter_test.go
index c34f07c..56870a1 100644
--- a/src/go/internal/gcimporter/gcimporter_test.go
+++ b/src/go/internal/gcimporter/gcimporter_test.go
@@ -48,7 +48,7 @@
 
 func testPath(t *testing.T, path, srcDir string) *types.Package {
 	t0 := time.Now()
-	pkg, err := Import(make(map[string]*types.Package), path, srcDir)
+	pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil)
 	if err != nil {
 		t.Errorf("testPath(%s): %s", path, err)
 		return nil
@@ -142,7 +142,7 @@
 		pkgpath := "./" + name[:len(name)-2]
 
 		// test that export data can be imported
-		_, err := Import(make(map[string]*types.Package), pkgpath, dir)
+		_, err := Import(make(map[string]*types.Package), pkgpath, dir, nil)
 		if err != nil {
 			t.Errorf("import %q failed: %v", pkgpath, err)
 			continue
@@ -171,7 +171,7 @@
 		defer os.Remove(filename)
 
 		// test that importing the corrupted file results in an error
-		_, err = Import(make(map[string]*types.Package), pkgpath, dir)
+		_, err = Import(make(map[string]*types.Package), pkgpath, dir, nil)
 		if err == nil {
 			t.Errorf("import corrupted %q succeeded", pkgpath)
 		} else if msg := err.Error(); !strings.Contains(msg, "version skew") {
@@ -223,7 +223,7 @@
 		importPath := s[0]
 		objName := s[1]
 
-		pkg, err := Import(make(map[string]*types.Package), importPath, ".")
+		pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil)
 		if err != nil {
 			t.Error(err)
 			continue
@@ -280,7 +280,7 @@
 	}
 
 	imports := make(map[string]*types.Package)
-	_, err := Import(imports, "net/http", ".")
+	_, err := Import(imports, "net/http", ".", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -336,7 +336,7 @@
 
 	// import go/internal/gcimporter which imports go/types partially
 	imports := make(map[string]*types.Package)
-	_, err := Import(imports, "go/internal/gcimporter", ".")
+	_, err := Import(imports, "go/internal/gcimporter", ".", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -404,7 +404,7 @@
 	// The same issue occurs with vendoring.)
 	imports := make(map[string]*types.Package)
 	for i := 0; i < 3; i++ {
-		if _, err := Import(imports, "./././testdata/p", "."); err != nil {
+		if _, err := Import(imports, "./././testdata/p", ".", nil); err != nil {
 			t.Fatal(err)
 		}
 	}
@@ -458,7 +458,7 @@
 }
 
 func importPkg(t *testing.T, path string) *types.Package {
-	pkg, err := Import(make(map[string]*types.Package), path, ".")
+	pkg, err := Import(make(map[string]*types.Package), path, ".", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/go/internal/srcimporter/srcimporter.go b/src/go/internal/srcimporter/srcimporter.go
index 50cf361..b0dc8ab 100644
--- a/src/go/internal/srcimporter/srcimporter.go
+++ b/src/go/internal/srcimporter/srcimporter.go
@@ -128,19 +128,33 @@
 	}
 
 	// type-check package files
+	var firstHardErr error
 	conf := types.Config{
 		IgnoreFuncBodies: true,
 		FakeImportC:      true,
-		Importer:         p,
-		Sizes:            p.sizes,
+		// continue type-checking after the first error
+		Error: func(err error) {
+			if firstHardErr == nil && !err.(types.Error).Soft {
+				firstHardErr = err
+			}
+		},
+		Importer: p,
+		Sizes:    p.sizes,
 	}
 	pkg, err = conf.Check(bp.ImportPath, p.fset, files, nil)
 	if err != nil {
-		// Type-checking stops after the first error (types.Config.Error is not set),
-		// so the returned package is very likely incomplete. Don't return it since
-		// we don't know its condition: It's very likely unsafe to use and it's also
-		// not added to p.packages which may cause further problems (issue #20837).
-		return nil, fmt.Errorf("type-checking package %q failed (%v)", bp.ImportPath, err)
+		// If there was a hard error it is possibly unsafe
+		// to use the package as it may not be fully populated.
+		// Do not return it (see also #20837, #20855).
+		if firstHardErr != nil {
+			pkg = nil
+			err = firstHardErr // give preference to first hard error over any soft error
+		}
+		return pkg, fmt.Errorf("type-checking package %q failed (%v)", bp.ImportPath, err)
+	}
+	if firstHardErr != nil {
+		// this can only happen if we have a bug in go/types
+		panic("package is not safe yet no error was returned")
 	}
 
 	p.packages[bp.ImportPath] = pkg
diff --git a/src/go/internal/srcimporter/srcimporter_test.go b/src/go/internal/srcimporter/srcimporter_test.go
index 79921b5..356e71d 100644
--- a/src/go/internal/srcimporter/srcimporter_test.go
+++ b/src/go/internal/srcimporter/srcimporter_test.go
@@ -148,3 +148,17 @@
 		t.Errorf("got %v; want reimport error", err)
 	}
 }
+
+func TestIssue20855(t *testing.T) {
+	if !testenv.HasSrc() {
+		t.Skip("no source code available")
+	}
+
+	pkg, err := importer.ImportFrom("go/internal/srcimporter/testdata/issue20855", ".", 0)
+	if err == nil || !strings.Contains(err.Error(), "missing function body") {
+		t.Fatalf("got unexpected or no error: %v", err)
+	}
+	if pkg == nil {
+		t.Error("got no package despite no hard errors")
+	}
+}
diff --git a/src/go/internal/srcimporter/testdata/issue20855/issue20855.go b/src/go/internal/srcimporter/testdata/issue20855/issue20855.go
new file mode 100644
index 0000000..d55448b
--- /dev/null
+++ b/src/go/internal/srcimporter/testdata/issue20855/issue20855.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue20855
+
+func init() // "missing function body" is a soft error
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
index 4eaadeb..3e2ff4f 100644
--- a/src/go/printer/nodes.go
+++ b/src/go/printer/nodes.go
@@ -398,22 +398,33 @@
 			// 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
+		} else if p.isOneLineFieldList(list) {
 			// small enough - print on one line
 			// (don't use identList and ignore source line breaks)
 			p.print(lbrace, token.LBRACE, blank)
 			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)
+			if isStruct {
+				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)
 				}
-				p.expr(x)
+				if len(f.Names) > 0 {
+					p.print(blank)
+				}
+				p.expr(f.Type)
+			} else { // interface
+				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)
+				}
 			}
-			if len(f.Names) > 0 {
-				p.print(blank)
-			}
-			p.expr(f.Type)
 			p.print(blank, rbrace, token.RBRACE)
 			return
 		}
@@ -774,20 +785,35 @@
 		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)
+		// determine if we need extra blanks around ':'
+		var needsBlanks bool
+		if depth <= 1 {
+			var indexCount int
+			var hasBinaries bool
+			for _, x := range indices {
+				if x != nil {
+					indexCount++
+					if isBinary(x) {
+						hasBinaries = true
+					}
 				}
 			}
-			if y != nil {
-				p.expr0(y, depth+1)
+			if indexCount > 1 && hasBinaries {
+				needsBlanks = true
+			}
+		}
+		for i, x := range indices {
+			if i > 0 {
+				if indices[i-1] != nil && needsBlanks {
+					p.print(blank)
+				}
+				p.print(token.COLON)
+				if x != nil && needsBlanks {
+					p.print(blank)
+				}
+			}
+			if x != nil {
+				p.expr0(x, depth+1)
 			}
 		}
 		p.print(x.Rbrack, token.RBRACK)
@@ -837,7 +863,9 @@
 		if len(x.Elts) > 0 {
 			mode |= noExtraBlank
 		}
-		p.print(mode, x.Rbrace, token.RBRACE, mode)
+		// need the initial indent to print lone comments with
+		// the proper level of indentation
+		p.print(indent, unindent, mode, x.Rbrace, token.RBRACE, mode)
 		p.level--
 
 	case *ast.Ellipsis:
diff --git a/src/go/printer/testdata/comments.golden b/src/go/printer/testdata/comments.golden
index 4d92e65..e1818e5 100644
--- a/src/go/printer/testdata/comments.golden
+++ b/src/go/printer/testdata/comments.golden
@@ -728,4 +728,32 @@
 	*/
 }
 
+var _ = []T{ /* lone comment */ }
+
+var _ = []T{
+	/* lone comment */
+}
+
+var _ = []T{
+	// lone comments
+	// in composite lit
+}
+
+var _ = [][]T{
+	{
+		// lone comments
+		// in composite lit
+	},
+}
+
+// TODO: gofmt doesn't add these tabs; make it so that these golden
+// tests run the printer in a way that it's exactly like gofmt.
+
+var _ = []T{	// lone comment
+}
+
+var _ = []T{	// lone comments
+	// in composite lit
+}
+
 /* This comment is the last entry in this file. It must be printed and should be followed by a newline */
diff --git a/src/go/printer/testdata/comments.input b/src/go/printer/testdata/comments.input
index 40351ee..f3eda12 100644
--- a/src/go/printer/testdata/comments.input
+++ b/src/go/printer/testdata/comments.input
@@ -725,4 +725,32 @@
 */
 }
 
+var _ = []T{/* lone comment */}
+
+var _ = []T{
+/* lone comment */
+}
+
+var _ = []T{
+// lone comments
+// in composite lit
+}
+
+var _ = [][]T{
+	{
+		// lone comments
+		// in composite lit
+	},
+}
+
+// TODO: gofmt doesn't add these tabs; make it so that these golden
+// tests run the printer in a way that it's exactly like gofmt.
+
+var _ = []T{// lone comment
+}
+
+var _ = []T{// lone comments
+// in composite lit
+}
+
 /* This comment is the last entry in this file. It must be printed and should be followed by a newline */
diff --git a/src/go/printer/testdata/expressions.golden b/src/go/printer/testdata/expressions.golden
index cab991f..16a68c7 100644
--- a/src/go/printer/testdata/expressions.golden
+++ b/src/go/printer/testdata/expressions.golden
@@ -122,18 +122,47 @@
 // slice expressions with cap
 func _() {
 	_ = x[a:b:c]
-	_ = x[a:b : c+d]
+	_ = 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]
 	_ = 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]
+	_ = x[: b : c+d]
+	_ = x[: b+d : c]
+	_ = x[: b+d : c+d]
+}
+
+func issue22111() {
+	_ = x[:]
+
+	_ = x[:b]
+	_ = x[:b+1]
+
+	_ = x[a:]
+	_ = x[a+1:]
+
+	_ = x[a:b]
+	_ = x[a+1 : b]
+	_ = x[a : b+1]
+	_ = x[a+1 : b+1]
+
+	_ = x[:b:c]
+	_ = x[: b+1 : c]
+	_ = x[: b : c+1]
+	_ = x[: b+1 : c+1]
+
+	_ = x[a:b:c]
+	_ = x[a+1 : b : c]
+	_ = x[a : b+1 : c]
+	_ = x[a+1 : b+1 : c]
+	_ = x[a : b : c+1]
+	_ = x[a+1 : b : c+1]
+	_ = x[a : b+1 : c+1]
+	_ = x[a+1 : b+1 : c+1]
 }
 
 func _() {
@@ -261,6 +290,16 @@
 	_ = struct{ x, y, z int }{0, 1, 2}
 	_ = struct{ int }{0}
 	_ = struct{ s struct{ int } }{struct{ int }{0}}
+
+	_ = (interface{})(nil)
+	_ = (interface{ String() string })(nil)
+	_ = (interface {
+		String() string
+	})(nil)
+	_ = (interface{ fmt.Stringer })(nil)
+	_ = (interface {
+		fmt.Stringer
+	})(nil)
 }
 
 func _() {
diff --git a/src/go/printer/testdata/expressions.input b/src/go/printer/testdata/expressions.input
index 7c88042..8c523b6 100644
--- a/src/go/printer/testdata/expressions.input
+++ b/src/go/printer/testdata/expressions.input
@@ -138,6 +138,35 @@
 	_ = x[:b+d:c+d]
 }
 
+func issue22111() {
+	_ = x[:]
+
+	_ = x[:b]
+	_ = x[:b+1]
+
+	_ = x[a:]
+	_ = x[a+1:]
+
+	_ = x[a:b]
+	_ = x[a+1:b]
+	_ = x[a:b+1]
+	_ = x[a+1:b+1]
+
+	_ = x[:b:c]
+	_ = x[:b+1:c]
+	_ = x[:b:c+1]
+	_ = x[:b+1:c+1]
+
+	_ = x[a:b:c]
+	_ = x[a+1:b:c]
+	_ = x[a:b+1:c]
+	_ = x[a+1:b+1:c]
+	_ = x[a:b:c+1]
+	_ = x[a+1:b:c+1]
+	_ = x[a:b+1:c+1]
+	_ = x[a+1:b+1:c+1]
+}
+
 func _() {
 	_ = a+b
 	_ = a+b+c
@@ -266,8 +295,17 @@
 	_ = struct{ x, y, z int }{0, 1, 2}
 	_ = struct{ int }{0}
 	_ = struct{ s struct { int } }{struct{ int}{0} }
-}
 
+	_ = (interface{})(nil)
+	_ = (interface{String() string})(nil)
+	_ = (interface{
+		String()    string
+	})(nil)
+	_ = (interface{fmt.Stringer})(nil)
+	_ = (interface{
+		    fmt.Stringer
+	})(nil)
+}
 
 func _() {
 	// do not modify literals
diff --git a/src/go/printer/testdata/expressions.raw b/src/go/printer/testdata/expressions.raw
index d906062..058fded 100644
--- a/src/go/printer/testdata/expressions.raw
+++ b/src/go/printer/testdata/expressions.raw
@@ -122,18 +122,47 @@
 // slice expressions with cap
 func _() {
 	_ = x[a:b:c]
-	_ = x[a:b : c+d]
+	_ = 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]
 	_ = 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]
+	_ = x[: b : c+d]
+	_ = x[: b+d : c]
+	_ = x[: b+d : c+d]
+}
+
+func issue22111() {
+	_ = x[:]
+
+	_ = x[:b]
+	_ = x[:b+1]
+
+	_ = x[a:]
+	_ = x[a+1:]
+
+	_ = x[a:b]
+	_ = x[a+1 : b]
+	_ = x[a : b+1]
+	_ = x[a+1 : b+1]
+
+	_ = x[:b:c]
+	_ = x[: b+1 : c]
+	_ = x[: b : c+1]
+	_ = x[: b+1 : c+1]
+
+	_ = x[a:b:c]
+	_ = x[a+1 : b : c]
+	_ = x[a : b+1 : c]
+	_ = x[a+1 : b+1 : c]
+	_ = x[a : b : c+1]
+	_ = x[a+1 : b : c+1]
+	_ = x[a : b+1 : c+1]
+	_ = x[a+1 : b+1 : c+1]
 }
 
 func _() {
@@ -261,6 +290,16 @@
 	_ = struct{ x, y, z int }{0, 1, 2}
 	_ = struct{ int }{0}
 	_ = struct{ s struct{ int } }{struct{ int }{0}}
+
+	_ = (interface{})(nil)
+	_ = (interface{ String() string })(nil)
+	_ = (interface {
+		String() string
+	})(nil)
+	_ = (interface{ fmt.Stringer })(nil)
+	_ = (interface {
+		fmt.Stringer
+	})(nil)
 }
 
 func _() {
diff --git a/src/go/types/api.go b/src/go/types/api.go
index 11e7686..9908f5c 100644
--- a/src/go/types/api.go
+++ b/src/go/types/api.go
@@ -24,7 +24,7 @@
 //
 // For a tutorial, see https://golang.org/s/types-tutorial.
 //
-package types // import "go/types"
+package types
 
 import (
 	"bytes"
@@ -176,11 +176,11 @@
 	// Implicits maps nodes to their implicitly declared objects, if any.
 	// The following node and object types may appear:
 	//
-	//	node               declared object
+	//     node               declared object
 	//
-	//	*ast.ImportSpec    *PkgName for dot-imports and imports without renames
-	//	*ast.CaseClause    type-specific *Var for each type switch case clause (incl. default)
-	//      *ast.Field         anonymous parameter *Var
+	//     *ast.ImportSpec    *PkgName for imports without renames
+	//     *ast.CaseClause    type-specific *Var for each type switch case clause (incl. default)
+	//     *ast.Field         anonymous parameter *Var
 	//
 	Implicits map[ast.Node]Object
 
@@ -200,16 +200,16 @@
 	//
 	// The following node types may appear in Scopes:
 	//
-	//	*ast.File
-	//	*ast.FuncType
-	//	*ast.BlockStmt
-	//	*ast.IfStmt
-	//	*ast.SwitchStmt
-	//	*ast.TypeSwitchStmt
-	//	*ast.CaseClause
-	//	*ast.CommClause
-	//	*ast.ForStmt
-	//	*ast.RangeStmt
+	//     *ast.File
+	//     *ast.FuncType
+	//     *ast.BlockStmt
+	//     *ast.IfStmt
+	//     *ast.SwitchStmt
+	//     *ast.TypeSwitchStmt
+	//     *ast.CaseClause
+	//     *ast.CommClause
+	//     *ast.ForStmt
+	//     *ast.RangeStmt
 	//
 	Scopes map[ast.Node]*Scope
 
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index d4f3f35..1d3c325 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -87,6 +87,10 @@
 		{`package c5a; var _ = string("foo")`, `"foo"`, `string`, `"foo"`},
 		{`package c5b; var _ = string("foo")`, `string("foo")`, `string`, `"foo"`},
 		{`package c5c; type T string; var _ = T("foo")`, `T("foo")`, `c5c.T`, `"foo"`},
+		{`package c5d; var _ = string(65)`, `65`, `untyped int`, `65`},
+		{`package c5e; var _ = string('A')`, `'A'`, `untyped rune`, `65`},
+		{`package c5f; type T string; var _ = T('A')`, `'A'`, `untyped rune`, `65`},
+		{`package c5g; var s uint; var _ = string(1 << s)`, `1 << s`, `untyped int`, ``},
 
 		{`package d0; var _ = []byte("foo")`, `"foo"`, `string`, `"foo"`},
 		{`package d1; var _ = []byte(string("foo"))`, `"foo"`, `string`, `"foo"`},
@@ -114,6 +118,8 @@
 		{`package f7a; var _ complex128 = -1e-2000i`, `-1e-2000i`, `complex128`, `(0 + 0i)`},
 		{`package f6b; var _            =  1e-2000i`, `1e-2000i`, `complex128`, `(0 + 0i)`},
 		{`package f7b; var _            = -1e-2000i`, `-1e-2000i`, `complex128`, `(0 + 0i)`},
+
+		{`package g0; const (a = len([iota]int{}); b; c); const _ = c`, `c`, `int`, `2`}, // issue #22341
 	}
 
 	for _, test := range tests {
@@ -122,7 +128,7 @@
 		}
 		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
 
-		// look for constant expression
+		// look for expression
 		var expr ast.Expr
 		for e := range info.Types {
 			if ExprString(e) == test.expr {
@@ -142,9 +148,15 @@
 			continue
 		}
 
-		// check that value is correct
-		if got := tv.Value.ExactString(); got != test.val {
-			t.Errorf("package %s: got value %s; want %s", name, got, test.val)
+		// if we have a constant, check that value is correct
+		if tv.Value != nil {
+			if got := tv.Value.ExactString(); got != test.val {
+				t.Errorf("package %s: got value %s; want %s", name, got, test.val)
+			}
+		} else {
+			if test.val != "" {
+				t.Errorf("package %s: no constant found; want %s", name, test.val)
+			}
 		}
 	}
 }
@@ -257,6 +269,63 @@
 	}
 }
 
+func TestImplicitsInfo(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests = []struct {
+		src  string
+		want string
+	}{
+		{`package p2; import . "fmt"; var _ = Println`, ""},           // no Implicits entry
+		{`package p0; import local "fmt"; var _ = local.Println`, ""}, // no Implicits entry
+		{`package p1; import "fmt"; var _ = fmt.Println`, "importSpec: package fmt"},
+
+		{`package p3; func f(x interface{}) { switch x.(type) { case int: } }`, ""}, // no Implicits entry
+		{`package p4; func f(x interface{}) { switch t := x.(type) { case int: _ = t } }`, "caseClause: var t int"},
+		{`package p5; func f(x interface{}) { switch t := x.(type) { case int, uint: _ = t } }`, "caseClause: var t interface{}"},
+		{`package p6; func f(x interface{}) { switch t := x.(type) { default: _ = t } }`, "caseClause: var t interface{}"},
+
+		{`package p7; func f(x int) {}`, ""}, // no Implicits entry
+		{`package p8; func f(int) {}`, "field: var  int"},
+		{`package p9; func f() (complex64) { return 0 }`, "field: var  complex64"},
+		{`package p10; type T struct{}; func (*T) f() {}`, "field: var  *p10.T"},
+	}
+
+	for _, test := range tests {
+		info := Info{
+			Implicits: make(map[ast.Node]Object),
+		}
+		name := mustTypecheck(t, "ImplicitsInfo", test.src, &info)
+
+		// the test cases expect at most one Implicits entry
+		if len(info.Implicits) > 1 {
+			t.Errorf("package %s: %d Implicits entries found", name, len(info.Implicits))
+			continue
+		}
+
+		// extract Implicits entry, if any
+		var got string
+		for n, obj := range info.Implicits {
+			switch x := n.(type) {
+			case *ast.ImportSpec:
+				got = "importSpec"
+			case *ast.CaseClause:
+				got = "caseClause"
+			case *ast.Field:
+				got = "field"
+			default:
+				t.Fatalf("package %s: unexpected %T", name, x)
+			}
+			got += ": " + obj.String()
+		}
+
+		// verify entry
+		if got != test.want {
+			t.Errorf("package %s: got %q; want %q", name, got, test.want)
+		}
+	}
+}
+
 func predString(tv TypeAndValue) string {
 	var buf bytes.Buffer
 	pred := func(b bool, s string) {
@@ -1304,7 +1373,7 @@
 	const src = `
 package p
 
-import "foo" // should only see an error here
+import foo "go/types/thisdirectorymustnotexistotherwisethistestmayfail/foo" // should only see an error here
 
 const c = foo.C
 type T = foo.T
@@ -1324,7 +1393,7 @@
 		conf := Config{
 			Error: func(err error) {
 				// we should only see the import error
-				if errcount > 0 || !strings.Contains(err.Error(), "could not import foo") {
+				if errcount > 0 || !strings.Contains(err.Error(), "could not import") {
 					t.Errorf("for %s importer, got unexpected error: %v", compiler, err)
 				}
 				errcount++
diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go
index e5ea071..98c9e12 100644
--- a/src/go/types/assignments.go
+++ b/src/go/types/assignments.go
@@ -154,8 +154,11 @@
 	var v_used bool
 	if ident != nil {
 		if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
-			v, _ = obj.(*Var)
-			if v != nil {
+			// It's ok to mark non-local variables, but ignore variables
+			// from other packages to avoid potential race conditions with
+			// dot-imported variables.
+			if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
+				v = w
 				v_used = v.used
 			}
 		}
@@ -249,6 +252,7 @@
 	l := len(lhs)
 	get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2)
 	if get == nil {
+		check.useLHS(lhs...)
 		return // error reported by unpack
 	}
 	if l != r {
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index 596a989..6654823 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -470,15 +470,14 @@
 
 	case _Panic:
 		// panic(x)
-		T := new(Interface)
-		check.assignment(x, T, "argument to panic")
+		check.assignment(x, &emptyInterface, "argument to panic")
 		if x.mode == invalid {
 			return
 		}
 
 		x.mode = novalue
 		if check.Types != nil {
-			check.recordBuiltinType(call.Fun, makeSig(nil, T))
+			check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
 		}
 
 	case _Print, _Println:
@@ -508,7 +507,7 @@
 	case _Recover:
 		// recover() interface{}
 		x.mode = value
-		x.typ = new(Interface)
+		x.typ = &emptyInterface
 		if check.Types != nil {
 			check.recordBuiltinType(call.Fun, makeSig(x.typ))
 		}
diff --git a/src/go/types/call.go b/src/go/types/call.go
index ffd9629..8fe65e4 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -90,15 +90,52 @@
 // use type-checks each argument.
 // Useful to make sure expressions are evaluated
 // (and variables are "used") in the presence of other errors.
+// The arguments may be nil.
 func (check *Checker) use(arg ...ast.Expr) {
 	var x operand
 	for _, e := range arg {
-		if e != nil { // be safe
+		// The nil check below is necessary since certain AST fields
+		// may legally be nil (e.g., the ast.SliceExpr.High field).
+		if e != nil {
 			check.rawExpr(&x, e, nil)
 		}
 	}
 }
 
+// useLHS is like use, but doesn't "use" top-level identifiers.
+// It should be called instead of use if the arguments are
+// expressions on the lhs of an assignment.
+// The arguments must not be nil.
+func (check *Checker) useLHS(arg ...ast.Expr) {
+	var x operand
+	for _, e := range arg {
+		// If the lhs is an identifier denoting a variable v, this assignment
+		// is not a 'use' of v. Remember current value of v.used and restore
+		// after evaluating the lhs via check.rawExpr.
+		var v *Var
+		var v_used bool
+		if ident, _ := unparen(e).(*ast.Ident); ident != nil {
+			// never type-check the blank name on the lhs
+			if ident.Name == "_" {
+				continue
+			}
+			if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
+				// It's ok to mark non-local variables, but ignore variables
+				// from other packages to avoid potential race conditions with
+				// dot-imported variables.
+				if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
+					v = w
+					v_used = v.used
+				}
+			}
+		}
+		check.rawExpr(&x, e, nil)
+		if v != nil {
+			v.used = v_used // restore v.used
+		}
+	}
+}
+
 // useGetter is like use, but takes a getter instead of a list of expressions.
 // It should be called instead of use if a getter is present to avoid repeated
 // evaluation of the first argument (since the getter was likely obtained via
@@ -134,47 +171,46 @@
 // the incoming getter with that i.
 //
 func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
-	if n == 1 {
-		// possibly result of an n-valued function call or comma,ok value
-		var x0 operand
-		get(&x0, 0)
-		if x0.mode == invalid {
-			return nil, 0, false
-		}
+	if n != 1 {
+		// zero or multiple values
+		return get, n, false
+	}
+	// possibly result of an n-valued function call or comma,ok value
+	var x0 operand
+	get(&x0, 0)
+	if x0.mode == invalid {
+		return nil, 0, false
+	}
 
-		if t, ok := x0.typ.(*Tuple); ok {
-			// result of an n-valued function call
+	if t, ok := x0.typ.(*Tuple); ok {
+		// result of an n-valued function call
+		return func(x *operand, i int) {
+			x.mode = value
+			x.expr = x0.expr
+			x.typ = t.At(i).typ
+		}, t.Len(), false
+	}
+
+	if x0.mode == mapindex || x0.mode == commaok {
+		// comma-ok value
+		if allowCommaOk {
+			a := [2]Type{x0.typ, Typ[UntypedBool]}
 			return func(x *operand, i int) {
 				x.mode = value
 				x.expr = x0.expr
-				x.typ = t.At(i).typ
-			}, t.Len(), false
+				x.typ = a[i]
+			}, 2, true
 		}
-
-		if x0.mode == mapindex || x0.mode == commaok {
-			// comma-ok value
-			if allowCommaOk {
-				a := [2]Type{x0.typ, Typ[UntypedBool]}
-				return func(x *operand, i int) {
-					x.mode = value
-					x.expr = x0.expr
-					x.typ = a[i]
-				}, 2, true
-			}
-			x0.mode = value
-		}
-
-		// single value
-		return func(x *operand, i int) {
-			if i != 0 {
-				unreachable()
-			}
-			*x = x0
-		}, 1, false
+		x0.mode = value
 	}
 
-	// zero or multiple values
-	return get, n, false
+	// single value
+	return func(x *operand, i int) {
+		if i != 0 {
+			unreachable()
+		}
+		*x = x0
+	}, 1, false
 }
 
 // arguments checks argument passing for the call with the given signature.
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index 24b3365..e3ca90a 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -42,7 +42,7 @@
 )
 
 var (
-	listErrors = flag.Bool("list", false, "list errors")
+	listErrors = flag.Bool("errlist", false, "list errors")
 	testFiles  = flag.String("files", "", "space-separated list of test files")
 )
 
@@ -69,6 +69,7 @@
 	{"testdata/decls2a.src", "testdata/decls2b.src"},
 	{"testdata/decls3.src"},
 	{"testdata/decls4.src"},
+	{"testdata/decls5.src"},
 	{"testdata/const0.src"},
 	{"testdata/const1.src"},
 	{"testdata/constdecl.src"},
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 2bf1e2d..81a6583 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -46,16 +46,19 @@
 	// The conversion argument types are final. For untyped values the
 	// conversion provides the type, per the spec: "A constant may be
 	// given a type explicitly by a constant declaration or conversion,...".
-	final := x.typ
 	if isUntyped(x.typ) {
-		final = T
+		final := T
 		// - For conversions to interfaces, use the argument's default type.
 		// - For conversions of untyped constants to non-constant types, also
 		//   use the default type (e.g., []byte("foo") should report string
 		//   not []byte as type for the constant "foo").
 		// - Keep untyped nil for untyped nil arguments.
+		// - For integer to string conversions, keep the argument type.
+		//   (See also the TODO below.)
 		if IsInterface(T) || constArg && !isConstType(T) {
 			final = Default(x.typ)
+		} else if isInteger(x.typ) && isString(T) {
+			final = x.typ
 		}
 		check.updateExprType(x.expr, final, true)
 	}
@@ -63,6 +66,16 @@
 	x.typ = T
 }
 
+// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type
+// of x is fully known, but that's not the case for say string(1<<s + 1.0):
+// Here, the type of 1<<s + 1.0 will be UntypedFloat which will lead to the
+// (correct!) refusal of the conversion. But the reported error is essentially
+// "cannot convert untyped float value to string", yet the correct error (per
+// the spec) is that we cannot shift a floating-point value: 1 in 1<<s should
+// be converted to UntypedFloat because of the addition of 1.0. Fixing this
+// is tricky because we'd have to run updateExprType on the argument first.
+// (Issue #21982.)
+
 func (x *operand) convertibleTo(conf *Config, T Type) bool {
 	// "x is assignable to T"
 	if x.assignableTo(conf, T, nil) {
diff --git a/src/go/types/decl.go b/src/go/types/decl.go
index 7428f8f..9b250b3 100644
--- a/src/go/types/decl.go
+++ b/src/go/types/decl.go
@@ -111,7 +111,11 @@
 	if typ != nil {
 		t := check.typ(typ)
 		if !isConstType(t) {
-			check.errorf(typ.Pos(), "invalid constant type %s", t)
+			// don't report an error if the type is an invalid C (defined) type
+			// (issue #22090)
+			if t.Underlying() != Typ[Invalid] {
+				check.errorf(typ.Pos(), "invalid constant type %s", t)
+			}
 			obj.typ = Typ[Invalid]
 			return
 		}
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index 461f0a5..59534c7 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -402,9 +402,10 @@
 
 	case *ast.UnaryExpr:
 		// If x is a constant, the operands were constants.
-		// They don't need to be updated since they never
-		// get "materialized" into a typed value; and they
-		// will be processed at the end of the type check.
+		// The operands don't need to be updated since they
+		// never get "materialized" into a typed value. If
+		// left in the untyped map, they will be processed
+		// at the end of the type check.
 		if old.val != nil {
 			break
 		}
@@ -443,12 +444,21 @@
 	// Remove it from the map of yet untyped expressions.
 	delete(check.untyped, x)
 
-	// If x is the lhs of a shift, its final type must be integer.
-	// We already know from the shift check that it is representable
-	// as an integer if it is a constant.
-	if old.isLhs && !isInteger(typ) {
-		check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ)
-		return
+	if old.isLhs {
+		// If x is the lhs of a shift, its final type must be integer.
+		// We already know from the shift check that it is representable
+		// as an integer if it is a constant.
+		if !isInteger(typ) {
+			check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ)
+			return
+		}
+	} else if old.val != nil {
+		// If x is a constant, it must be representable as a value of typ.
+		c := operand{old.mode, x, old.typ, old.val, 0}
+		check.convertUntyped(&c, typ)
+		if c.mode == invalid {
+			return
+		}
 	}
 
 	// Everything's fine, record final type and value for x.
@@ -1020,6 +1030,15 @@
 			// Anonymous functions are considered part of the
 			// init expression/func declaration which contains
 			// them: use existing package-level declaration info.
+			//
+			// TODO(gri) We delay type-checking of regular (top-level)
+			//           function bodies until later. Why don't we do
+			//           it for closures of top-level expressions?
+			//           (We can't easily do it for local closures
+			//           because the surrounding scopes must reflect
+			//           the exact position where the closure appears
+			//           in the source; e.g., variables declared below
+			//           must not be visible).
 			check.funcBody(check.decl, "", sig, e.Body)
 			x.mode = value
 			x.typ = sig
@@ -1175,17 +1194,18 @@
 				if x.mode == constant_ {
 					duplicate := false
 					// if the key is of interface type, the type is also significant when checking for duplicates
+					xkey := keyVal(x.val)
 					if _, ok := utyp.key.Underlying().(*Interface); ok {
-						for _, vtyp := range visited[x.val] {
+						for _, vtyp := range visited[xkey] {
 							if Identical(vtyp, x.typ) {
 								duplicate = true
 								break
 							}
 						}
-						visited[x.val] = append(visited[x.val], x.typ)
+						visited[xkey] = append(visited[xkey], x.typ)
 					} else {
-						_, duplicate = visited[x.val]
-						visited[x.val] = nil
+						_, duplicate = visited[xkey]
+						visited[xkey] = nil
 					}
 					if duplicate {
 						check.errorf(x.pos(), "duplicate key %s in map literal", x.val)
@@ -1489,6 +1509,30 @@
 	return statement // avoid follow-up errors
 }
 
+func keyVal(x constant.Value) interface{} {
+	switch x.Kind() {
+	case constant.Bool:
+		return constant.BoolVal(x)
+	case constant.String:
+		return constant.StringVal(x)
+	case constant.Int:
+		if v, ok := constant.Int64Val(x); ok {
+			return v
+		}
+		if v, ok := constant.Uint64Val(x); ok {
+			return v
+		}
+	case constant.Float:
+		v, _ := constant.Float64Val(x)
+		return v
+	case constant.Complex:
+		r, _ := constant.Float64Val(constant.Real(x))
+		i, _ := constant.Float64Val(constant.Imag(x))
+		return complex(r, i)
+	}
+	return x
+}
+
 // typeAssertion checks that x.(T) is legal; xtyp must be the type of x.
 func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) {
 	method, wrongType := assertableTo(xtyp, T)
diff --git a/src/go/types/exprstring.go b/src/go/types/exprstring.go
index 370bdf3..28d605f 100644
--- a/src/go/types/exprstring.go
+++ b/src/go/types/exprstring.go
@@ -11,14 +11,18 @@
 	"go/ast"
 )
 
-// ExprString returns the (possibly simplified) string representation for x.
+// ExprString returns the (possibly shortened) string representation for x.
+// Shortened representations are suitable for user interfaces but may not
+// necessarily follow Go syntax.
 func ExprString(x ast.Expr) string {
 	var buf bytes.Buffer
 	WriteExpr(&buf, x)
 	return buf.String()
 }
 
-// WriteExpr writes the (possibly simplified) string representation for x to buf.
+// WriteExpr writes the (possibly shortened) string representation for x to buf.
+// Shortened representations are suitable for user interfaces but may not
+// necessarily follow Go syntax.
 func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
 	// The AST preserves source-level parentheses so there is
 	// no need to introduce them here to correct for different
@@ -44,12 +48,12 @@
 	case *ast.FuncLit:
 		buf.WriteByte('(')
 		WriteExpr(buf, x.Type)
-		buf.WriteString(" literal)") // simplified
+		buf.WriteString(" literal)") // shortened
 
 	case *ast.CompositeLit:
 		buf.WriteByte('(')
 		WriteExpr(buf, x.Type)
-		buf.WriteString(" literal)") // simplified
+		buf.WriteString(" literal)") // shortened
 
 	case *ast.ParenExpr:
 		buf.WriteByte('(')
diff --git a/src/go/types/hilbert_test.go b/src/go/types/hilbert_test.go
index 916d6fd..9783ce6 100644
--- a/src/go/types/hilbert_test.go
+++ b/src/go/types/hilbert_test.go
@@ -52,6 +52,8 @@
 
 	g.p(`// Code generated by: go test -run=Hilbert -H=%d -out=%q. DO NOT EDIT.
 
+// +`+`build ignore
+
 // This program tests arbitrary precision constant arithmetic
 // by generating the constant elements of a Hilbert matrix H,
 // its inverse I, and the product P = H*I. The product should
diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go
index 3884735..02af0cf 100644
--- a/src/go/types/issues_test.go
+++ b/src/go/types/issues_test.go
@@ -292,3 +292,25 @@
 	f("src1", src1)
 	f("src2", src2)
 }
+
+func TestIssue22525(t *testing.T) {
+	src := `package p; func f() { var a, b, c, d, e int }`
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	got := "\n"
+	conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
+	conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash
+	want := `
+1:27: a declared but not used
+1:30: b declared but not used
+1:33: c declared but not used
+1:36: d declared but not used
+1:39: e declared but not used
+`
+	if got != want {
+		t.Errorf("got: %swant: %s", got, want)
+	}
+}
diff --git a/src/go/types/methodset.go b/src/go/types/methodset.go
index 4f791d9..2a8b1c2 100644
--- a/src/go/types/methodset.go
+++ b/src/go/types/methodset.go
@@ -190,7 +190,10 @@
 			list = append(list, m)
 		}
 	}
-	sort.Sort(byUniqueName(list))
+	// sort by unique name
+	sort.Slice(list, func(i, j int) bool {
+		return list[i].obj.Id() < list[j].obj.Id()
+	})
 	return &MethodSet{list}
 }
 
@@ -257,10 +260,3 @@
 	_, isPtr := deref(f.typ.(*Signature).recv.typ)
 	return isPtr
 }
-
-// byUniqueName function lists can be sorted by their unique names.
-type byUniqueName []*Selection
-
-func (a byUniqueName) Len() int           { return len(a) }
-func (a byUniqueName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
-func (a byUniqueName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/src/go/types/object.go b/src/go/types/object.go
index f0bcd67..633d327 100644
--- a/src/go/types/object.go
+++ b/src/go/types/object.go
@@ -12,8 +12,6 @@
 	"go/token"
 )
 
-// TODO(gri) Document factory, accessor methods, and fields. General clean-up.
-
 // An Object describes a named language entity such as a package,
 // constant, type, variable, function (incl. methods), or label.
 // All objects implement the Object interface.
@@ -21,7 +19,7 @@
 type Object interface {
 	Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
 	Pos() token.Pos // position of object identifier in declaration
-	Pkg() *Package  // nil for objects in the Universe scope and labels
+	Pkg() *Package  // package to which this object belongs; nil for labels and objects in the Universe scope
 	Name() string   // package local object name
 	Type() Type     // object type
 	Exported() bool // reports whether the name starts with a capital letter
@@ -121,12 +119,15 @@
 }
 
 // A PkgName represents an imported Go package.
+// PkgNames don't have a type.
 type PkgName struct {
 	object
 	imported *Package
 	used     bool // set if the package was used
 }
 
+// NewPkgName returns a new PkgName object representing an imported package.
+// The remaining arguments set the attributes found with all Objects.
 func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
 	return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, token.NoPos}, imported, false}
 }
@@ -142,6 +143,8 @@
 	visited bool // for initialization cycle detection
 }
 
+// NewConst returns a new constant with value val.
+// The remaining arguments set the attributes found with all Objects.
 func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
 	return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false}
 }
@@ -154,6 +157,13 @@
 	object
 }
 
+// NewTypeName returns a new type name denoting the given typ.
+// The remaining arguments set the attributes found with all Objects.
+//
+// The typ argument may be a defined (Named) type or an alias type.
+// It may also be nil such that the returned TypeName can be used as
+// argument for NewNamed, which will set the TypeName's type as a side-
+// effect.
 func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
 	return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
 }
@@ -191,21 +201,31 @@
 	used      bool // set if the variable was used
 }
 
+// NewVar returns a new variable.
+// The arguments set the attributes found with all Objects.
 func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
 	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}}
 }
 
+// NewParam returns a new variable representing a function parameter.
 func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
 	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, used: true} // parameters are always 'used'
 }
 
+// NewField returns a new variable representing a struct field.
+// For anonymous (embedded) fields, the name is the unqualified
+// type name under which the field is accessible.
 func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var {
 	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, anonymous: anonymous, isField: true}
 }
 
+// Anonymous reports whether the variable is an anonymous field.
 func (obj *Var) Anonymous() bool { return obj.anonymous }
-func (obj *Var) IsField() bool   { return obj.isField }
-func (*Var) isDependency()       {} // a variable may be a dependency of an initialization expression
+
+// IsField reports whether the variable is a struct field.
+func (obj *Var) IsField() bool { return obj.isField }
+
+func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression
 
 // A Func represents a declared function, concrete method, or abstract
 // (interface) method. Its Type() is always a *Signature.
@@ -214,6 +234,8 @@
 	object
 }
 
+// NewFunc returns a new function with the given signature, representing
+// the function's type.
 func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
 	// don't store a nil signature
 	var typ Type
@@ -231,15 +253,19 @@
 	return buf.String()
 }
 
+// Scope returns the scope of the function's body block.
 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
-func (*Func) isDependency()     {} // a function may be a dependency of an initialization expression
+
+func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
 
 // A Label represents a declared label.
+// Labels don't have a type.
 type Label struct {
 	object
 	used bool // set if the label was used
 }
 
+// NewLabel returns a new label.
 func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
 	return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}, false}
 }
diff --git a/src/go/types/object_test.go b/src/go/types/object_test.go
index b0acdd9..9f07394 100644
--- a/src/go/types/object_test.go
+++ b/src/go/types/object_test.go
@@ -32,12 +32,12 @@
 		{NewTypeName(0, nil, "t0", nil), false}, // no type yet
 		{NewTypeName(0, pkg, "t0", nil), false}, // no type yet
 		{t1, false},                             // type name refers to named type and vice versa
-		{NewTypeName(0, nil, "t2", new(Interface)), true}, // type name refers to unnamed type
-		{NewTypeName(0, pkg, "t3", n1), true},             // type name refers to named type with different type name
-		{NewTypeName(0, nil, "t4", Typ[Int32]), true},     // type name refers to basic type with different name
-		{NewTypeName(0, nil, "int32", Typ[Int32]), false}, // type name refers to basic type with same name
-		{NewTypeName(0, pkg, "int32", Typ[Int32]), true},  // type name is declared in user-defined package (outside Universe)
-		{NewTypeName(0, nil, "rune", Typ[Rune]), true},    // type name refers to basic type rune which is an alias already
+		{NewTypeName(0, nil, "t2", &emptyInterface), true}, // type name refers to unnamed type
+		{NewTypeName(0, pkg, "t3", n1), true},              // type name refers to named type with different type name
+		{NewTypeName(0, nil, "t4", Typ[Int32]), true},      // type name refers to basic type with different name
+		{NewTypeName(0, nil, "int32", Typ[Int32]), false},  // type name refers to basic type with same name
+		{NewTypeName(0, pkg, "int32", Typ[Int32]), true},   // type name is declared in user-defined package (outside Universe)
+		{NewTypeName(0, nil, "rune", Typ[Rune]), true},     // type name refers to basic type rune which is an alias already
 	} {
 		check(test.name, test.alias)
 	}
diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go
index c3b87dd..3aa4878 100644
--- a/src/go/types/predicates.go
+++ b/src/go/types/predicates.go
@@ -110,12 +110,14 @@
 	return false
 }
 
-// Identical reports whether x and y are identical.
+// Identical reports whether x and y are identical types.
+// Receivers of Signature types are ignored.
 func Identical(x, y Type) bool {
 	return identical(x, y, true, nil)
 }
 
-// IdenticalIgnoreTags reports whether x and y are identical if tags are ignored.
+// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
+// Receivers of Signature types are ignored.
 func IdenticalIgnoreTags(x, y Type) bool {
 	return identical(x, y, false, nil)
 }
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go
index 05603b3..d03c179 100644
--- a/src/go/types/resolver.go
+++ b/src/go/types/resolver.go
@@ -111,6 +111,13 @@
 		return
 	}
 
+	// spec: "The main package must have package name main and declare
+	// a function main that takes no arguments and returns no value."
+	if ident.Name == "main" && check.pkg.name == "main" {
+		check.errorf(ident.Pos(), "cannot declare main - must be func")
+		return
+	}
+
 	check.declare(check.pkg.scope, ident, obj, token.NoPos)
 	check.objMap[obj] = d
 	obj.setOrder(uint32(len(check.objMap)))
@@ -303,7 +310,6 @@
 									// via Config.Packages - may be dot-imported in
 									// another package!)
 									check.declare(fileScope, nil, obj, token.NoPos)
-									check.recordImplicit(s, obj)
 								}
 							}
 							// add position to set of dot-import positions for this file
@@ -411,9 +417,9 @@
 					// receiver name. They will be type-checked later, with regular
 					// functions.
 					if list := d.Recv.List; len(list) > 0 {
-						typ := list[0].Type
+						typ := unparen(list[0].Type)
 						if ptr, _ := typ.(*ast.StarExpr); ptr != nil {
-							typ = ptr.X
+							typ = unparen(ptr.X)
 						}
 						if base, _ := typ.(*ast.Ident); base != nil && base.Name != "_" {
 							check.assocMethod(base.Name, obj)
diff --git a/src/go/types/scope.go b/src/go/types/scope.go
index b5d34d6..39e42d7 100644
--- a/src/go/types/scope.go
+++ b/src/go/types/scope.go
@@ -28,12 +28,13 @@
 	elems    map[string]Object // lazily allocated
 	pos, end token.Pos         // scope extent; may be invalid
 	comment  string            // for debugging only
+	isFunc   bool              // set if this is a function scope (internal use only)
 }
 
 // NewScope returns a new, empty scope contained in the given parent
 // scope, if any. The comment is for debugging only.
 func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
-	s := &Scope{parent, nil, nil, pos, end, comment}
+	s := &Scope{parent, nil, nil, pos, end, comment, false}
 	// don't add children to Universe scope!
 	if parent != nil && parent != Universe {
 		parent.children = append(parent.children, s)
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index 34029b8..ad4c51f 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -163,15 +163,17 @@
 
 	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"),
 		"bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore
-		"issue6889.go",  // gc-specific test
-		"issue7746.go",  // large constants - consumes too much memory
-		"issue11362.go", // canonical import path check
-		"issue15002.go", // uses Mmap; testTestDir should consult build tags
-		"issue16369.go", // go/types handles this correctly - not an issue
-		"issue18459.go", // go/types doesn't check validity of //go:xxx directives
-		"issue18882.go", // go/types doesn't check validity of //go:xxx directives
-		"issue20232.go", // go/types handles larger constants than gc
-		"issue20529.go", // go/types does not have constraints on stack size
+		"issue6889.go",   // gc-specific test
+		"issue7746.go",   // large constants - consumes too much memory
+		"issue11362.go",  // canonical import path check
+		"issue15002.go",  // uses Mmap; testTestDir should consult build tags
+		"issue16369.go",  // go/types handles this correctly - not an issue
+		"issue18459.go",  // go/types doesn't check validity of //go:xxx directives
+		"issue18882.go",  // go/types doesn't check validity of //go:xxx directives
+		"issue20232.go",  // go/types handles larger constants than gc
+		"issue20529.go",  // go/types does not have constraints on stack size
+		"issue22200.go",  // go/types does not have constraints on stack size
+		"issue22200b.go", // go/types does not have constraints on stack size
 	)
 }
 
diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go
index 4e423bd..5221bcc 100644
--- a/src/go/types/stmt.go
+++ b/src/go/types/stmt.go
@@ -11,6 +11,7 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	"sort"
 )
 
 func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) {
@@ -57,13 +58,25 @@
 }
 
 func (check *Checker) usage(scope *Scope) {
-	for _, obj := range scope.elems {
-		if v, _ := obj.(*Var); v != nil && !v.used {
-			check.softErrorf(v.pos, "%s declared but not used", v.name)
+	var unused []*Var
+	for _, elem := range scope.elems {
+		if v, _ := elem.(*Var); v != nil && !v.used {
+			unused = append(unused, v)
 		}
 	}
+	sort.Slice(unused, func(i, j int) bool {
+		return unused[i].pos < unused[j].pos
+	})
+	for _, v := range unused {
+		check.softErrorf(v.pos, "%s declared but not used", v.name)
+	}
+
 	for _, scope := range scope.children {
-		check.usage(scope)
+		// Don't go inside closure scopes a second time;
+		// they are handled explicitly by funcBody.
+		if !scope.isFunc {
+			check.usage(scope)
+		}
 	}
 }
 
@@ -236,15 +249,13 @@
 		}
 		// look for duplicate values
 		if val := goVal(v.val); val != nil {
-			if list := seen[val]; list != nil {
-				// look for duplicate types for a given value
-				// (quadratic algorithm, but these lists tend to be very short)
-				for _, vt := range list {
-					if Identical(v.typ, vt.typ) {
-						check.errorf(v.pos(), "duplicate case %s in expression switch", &v)
-						check.error(vt.pos, "\tprevious case") // secondary error, \t indented
-						continue L
-					}
+			// look for duplicate types for a given value
+			// (quadratic algorithm, but these lists tend to be very short)
+			for _, vt := range seen[val] {
+				if Identical(v.typ, vt.typ) {
+					check.errorf(v.pos(), "duplicate case %s in expression switch", &v)
+					check.error(vt.pos, "\tprevious case") // secondary error, \t indented
+					continue L
 				}
 			}
 			seen[val] = append(seen[val], valueType{v.pos(), v.typ})
@@ -720,6 +731,9 @@
 		// declaration, but the post statement must not."
 		if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
 			check.softErrorf(s.Pos(), "cannot declare in post statement")
+			// Don't call useLHS here because we want to use the lhs in
+			// this erroneous statement so that we don't get errors about
+			// these lhs variables being declared but not used.
 			check.use(s.Lhs...) // avoid follow-up errors
 		}
 		check.stmt(inner, s.Body)
diff --git a/src/go/types/testdata/cycles4.src b/src/go/types/testdata/cycles4.src
index 445babc..3f6304b 100644
--- a/src/go/types/testdata/cycles4.src
+++ b/src/go/types/testdata/cycles4.src
@@ -108,3 +108,15 @@
 type Event interface {
 	Target() Element
 }
+
+// Recognize issue #13895.
+
+type (
+	_ interface{ m(B1) }
+	A1 interface{ a(D1) }
+	B1 interface{ A1 }
+	C1 interface{ B1 /* ERROR issue #18395 */ }
+	D1 interface{ C1 }
+)
+
+var _ A1 = C1 /* ERROR cannot use C1 */ (nil)
\ No newline at end of file
diff --git a/src/go/types/testdata/decls2b.src b/src/go/types/testdata/decls2b.src
index e7bc394..8e82c6d 100644
--- a/src/go/types/testdata/decls2b.src
+++ b/src/go/types/testdata/decls2b.src
@@ -63,3 +63,13 @@
 func (x *(T7),) m4() {}
 func (x (*(T7)),) m5() {}
 func (x ((*((T7)))),) m6() {}
+
+// Check that methods with parenthesized receiver are actually present (issue #23130).
+var (
+	_ = T7.m1
+	_ = T7.m2
+	_ = (*T7).m3
+	_ = (*T7).m4
+	_ = (*T7).m5
+	_ = (*T7).m6
+)
\ No newline at end of file
diff --git a/src/go/types/testdata/decls5.src b/src/go/types/testdata/decls5.src
new file mode 100644
index 0000000..88d3194
--- /dev/null
+++ b/src/go/types/testdata/decls5.src
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// declarations of main
+const _, main /* ERROR "cannot declare main" */ , _ = 0, 1, 2
+type main /* ERROR "cannot declare main" */ struct{}
+var _, main /* ERROR "cannot declare main" */ int
diff --git a/src/go/types/testdata/expr3.src b/src/go/types/testdata/expr3.src
index 95d5c09..b7ab9b3 100644
--- a/src/go/types/testdata/expr3.src
+++ b/src/go/types/testdata/expr3.src
@@ -367,6 +367,10 @@
 	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
 	_ = map[interface{}]int{"a": 1, S("a"): 1}
 	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
+	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
+	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
+	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
+	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
 
 	type I interface {
 		f()
diff --git a/src/go/types/testdata/importC.src b/src/go/types/testdata/importC.src
index 31436be..f50f7f3 100644
--- a/src/go/types/testdata/importC.src
+++ b/src/go/types/testdata/importC.src
@@ -8,3 +8,28 @@
 import _ /* ERROR cannot rename import "C" */ "C"
 import foo /* ERROR cannot rename import "C" */ "C"
 import . /* ERROR cannot rename import "C" */ "C"
+
+// Test cases extracted from issue #22090.
+
+import "unsafe"
+
+const _ C.int = 0xff // no error due to invalid constant type
+
+type T struct {
+	Name    string
+	Ordinal int
+}
+
+func f(args []T) {
+	var s string
+	for i, v := range args {
+		cname := C.CString(v.Name)
+		args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s, cname)) // no error due to i not being "used"
+		C.free(unsafe.Pointer(cname))
+	}
+}
+
+type CType C.Type
+
+const _ CType = C.X // no error due to invalid constant type
+const _ = C.X
diff --git a/src/go/types/testdata/shifts.src b/src/go/types/testdata/shifts.src
index dc029fc..ca28829 100644
--- a/src/go/types/testdata/shifts.src
+++ b/src/go/types/testdata/shifts.src
@@ -345,3 +345,12 @@
 	_ = complex64 /* ERROR "must be integer" */ (0) << 3
 	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
 }
+
+func issue21727() {
+	var s uint
+	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
+	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
+	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
+	var _ = string(1 << s)
+	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
+}
diff --git a/src/go/types/testdata/vardecl.src b/src/go/types/testdata/vardecl.src
index 35f44e6..197dec2 100644
--- a/src/go/types/testdata/vardecl.src
+++ b/src/go/types/testdata/vardecl.src
@@ -151,6 +151,13 @@
 	return
 }
 
+// Unused variables in closures must lead to only one error (issue #22524).
+func _() {
+	_ = func() {
+		var x /* ERROR declared but not used */ int
+	}
+}
+
 // Invalid (unused) expressions must not lead to spurious "declared but not used errors"
 func _() {
 	var a, b, c int
diff --git a/src/go/types/type.go b/src/go/types/type.go
index a0a1238..a58684a 100644
--- a/src/go/types/type.go
+++ b/src/go/types/type.go
@@ -191,6 +191,7 @@
 func (t *Tuple) At(i int) *Var { return t.vars[i] }
 
 // A Signature represents a (non-builtin) function or method type.
+// The receiver is ignored when comparing signatures for identity.
 type Signature struct {
 	// We need to keep the scope in Signature (rather than passing it around
 	// and store it in the Func Object) because when type-checking a function
@@ -221,7 +222,7 @@
 }
 
 // Recv returns the receiver of signature s (if a method), or nil if a
-// function.
+// function. It is ignored when comparing signatures for identity.
 //
 // For an abstract method, Recv returns the enclosing interface either
 // as a *Named or an *Interface. Due to embedding, an interface may
@@ -245,10 +246,22 @@
 	allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset)
 }
 
-// NewInterface returns a new interface for the given methods and embedded types.
+// emptyInterface represents the empty (completed) interface
+var emptyInterface = Interface{allMethods: markComplete}
+
+// markComplete is used to mark an empty interface as completely
+// set up by setting the allMethods field to a non-nil empty slice.
+var markComplete = make([]*Func, 0)
+
+// NewInterface returns a new (incomplete) interface for the given methods and embedded types.
+// To compute the method set of the interface, Complete must be called.
 func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
 	typ := new(Interface)
 
+	if len(methods) == 0 && len(embeddeds) == 0 {
+		return typ
+	}
+
 	var mset objset
 	for _, m := range methods {
 		if mset.insert(m) != nil {
@@ -261,7 +274,7 @@
 	}
 	sort.Sort(byUniqueMethodName(methods))
 
-	if embeddeds == nil {
+	if embeddeds != nil {
 		sort.Sort(byUniqueTypeName(embeddeds))
 	}
 
@@ -382,6 +395,7 @@
 }
 
 // NewNamed returns a new named type for the given type name, underlying type, and associated methods.
+// If the given type name obj doesn't have a type yet, its type is set to the returned named type.
 // The underlying type must not be a *Named.
 func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
 	if _, ok := underlying.(*Named); ok {
@@ -404,7 +418,6 @@
 func (t *Named) Method(i int) *Func { return t.methods[i] }
 
 // SetUnderlying sets the underlying type and marks t as complete.
-// TODO(gri) determine if there's a better solution rather than providing this function
 func (t *Named) SetUnderlying(underlying Type) {
 	if underlying == nil {
 		panic("types.Named.SetUnderlying: underlying type must not be nil")
@@ -416,7 +429,6 @@
 }
 
 // AddMethod adds method m unless it is already in the method list.
-// TODO(gri) find a better solution instead of providing this function
 func (t *Named) AddMethod(m *Func) {
 	if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 {
 		t.methods = append(t.methods, m)
diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go
index 0f8a7ad..a9c0bfd 100644
--- a/src/go/types/typestring.go
+++ b/src/go/types/typestring.go
@@ -156,6 +156,7 @@
 		//     }
 		//
 		buf.WriteString("interface{")
+		empty := true
 		if gcCompatibilityMode {
 			// print flattened interface
 			// (useful to compare against gc-generated interfaces)
@@ -165,6 +166,7 @@
 				}
 				buf.WriteString(m.name)
 				writeSignature(buf, m.typ.(*Signature), qf, visited)
+				empty = false
 			}
 		} else {
 			// print explicit interface methods and embedded types
@@ -174,14 +176,22 @@
 				}
 				buf.WriteString(m.name)
 				writeSignature(buf, m.typ.(*Signature), qf, visited)
+				empty = false
 			}
 			for i, typ := range t.embeddeds {
 				if i > 0 || len(t.methods) > 0 {
 					buf.WriteString("; ")
 				}
 				writeType(buf, typ, qf, visited)
+				empty = false
 			}
 		}
+		if t.allMethods == nil || len(t.methods) > len(t.allMethods) {
+			if !empty {
+				buf.WriteByte(' ')
+			}
+			buf.WriteString("/* incomplete */")
+		}
 		buf.WriteByte('}')
 
 	case *Map:
diff --git a/src/go/types/typestring_test.go b/src/go/types/typestring_test.go
index b794ea8..8d4c9f0 100644
--- a/src/go/types/typestring_test.go
+++ b/src/go/types/typestring_test.go
@@ -138,6 +138,26 @@
 	}
 }
 
+func TestIncompleteInterfaces(t *testing.T) {
+	sig := NewSignature(nil, nil, nil, false)
+	for _, test := range []struct {
+		typ  *Interface
+		want string
+	}{
+		{new(Interface), "interface{/* incomplete */}"},
+		{new(Interface).Complete(), "interface{}"},
+		{NewInterface(nil, nil), "interface{/* incomplete */}"},
+		{NewInterface(nil, nil).Complete(), "interface{}"},
+		{NewInterface([]*Func{NewFunc(token.NoPos, nil, "m", sig)}, nil), "interface{m() /* incomplete */}"},
+		{NewInterface([]*Func{NewFunc(token.NoPos, nil, "m", sig)}, nil).Complete(), "interface{m()}"},
+	} {
+		got := test.typ.String()
+		if got != test.want {
+			t.Errorf("got: %s, want: %s", got, test.want)
+		}
+	}
+}
+
 func TestQualifiedTypeString(t *testing.T) {
 	p, _ := pkgFor("p.go", "package p; type T int", nil)
 	q, _ := pkgFor("q.go", "package q", nil)
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 5f1587b..92ab06b 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -86,6 +86,9 @@
 		}
 
 	case *Var:
+		// It's ok to mark non-local variables, but ignore variables
+		// from other packages to avoid potential race conditions with
+		// dot-imported variables.
 		if obj.pkg == check.pkg {
 			obj.used = true
 		}
@@ -143,6 +146,7 @@
 // funcType type-checks a function or method type.
 func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
 	scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
+	scope.isFunc = true
 	check.recordScope(ftyp, scope)
 
 	recvList, _ := check.collectParams(scope, recvPar, false)
@@ -539,6 +543,9 @@
 		}
 		iface.embeddeds = append(iface.embeddeds, named)
 		// collect embedded methods
+		if embed.allMethods == nil {
+			check.errorf(pos, "internal error: incomplete embedded interface %s (issue #18395)", named)
+		}
 		for _, m := range embed.allMethods {
 			if check.declareInSet(&mset, pos, m) {
 				iface.allMethods = append(iface.allMethods, m)
@@ -578,7 +585,11 @@
 	// claim source order in the future. Revisit.
 	sort.Sort(byUniqueTypeName(iface.embeddeds))
 
-	sort.Sort(byUniqueMethodName(iface.allMethods))
+	if iface.allMethods == nil {
+		iface.allMethods = make([]*Func, 0) // mark interface as complete
+	} else {
+		sort.Sort(byUniqueMethodName(iface.allMethods))
+	}
 }
 
 // byUniqueTypeName named type lists can be sorted by their unique type names.
diff --git a/src/go/types/universe.go b/src/go/types/universe.go
index cc3bd5a..07d7078 100644
--- a/src/go/types/universe.go
+++ b/src/go/types/universe.go
@@ -20,6 +20,12 @@
 	universeRune *Basic // int32 alias, but has name "rune"
 )
 
+// Typ contains the predeclared *Basic types indexed by their
+// corresponding BasicKind.
+//
+// The *Basic type for Typ[Byte] will have the name "uint8".
+// Use Universe.Lookup("byte").Type() to obtain the specific
+// alias basic type named "byte" (and analogous for "rune").
 var Typ = []*Basic{
 	Invalid: {Invalid, 0, "invalid type"},
 
diff --git a/src/hash/adler32/adler32.go b/src/hash/adler32/adler32.go
index 21d6a2e..e8783e4 100644
--- a/src/hash/adler32/adler32.go
+++ b/src/hash/adler32/adler32.go
@@ -12,7 +12,10 @@
 //	significant-byte first (network) order.
 package adler32
 
-import "hash"
+import (
+	"errors"
+	"hash"
+)
 
 const (
 	// mod is the largest prime that is less than 65536.
@@ -32,8 +35,11 @@
 
 func (d *digest) Reset() { *d = 1 }
 
-// New returns a new hash.Hash32 computing the Adler-32 checksum.
-// Its Sum method will lay the value out in big-endian byte order.
+// New returns a new hash.Hash32 computing the Adler-32 checksum. Its
+// Sum method will lay the value out in big-endian byte order. The
+// returned Hash32 also implements encoding.BinaryMarshaler and
+// encoding.BinaryUnmarshaler to marshal and unmarshal the internal
+// state of the hash.
 func New() hash.Hash32 {
 	d := new(digest)
 	d.Reset()
@@ -44,6 +50,44 @@
 
 func (d *digest) BlockSize() int { return 4 }
 
+const (
+	magic         = "adl\x01"
+	marshaledSize = len(magic) + 4
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	b = appendUint32(b, uint32(*d))
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("hash/adler32: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("hash/adler32: invalid hash state size")
+	}
+	*d = digest(readUint32(b[len(magic):]))
+	return nil
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	a := [4]byte{
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func readUint32(b []byte) uint32 {
+	_ = b[3]
+	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
 // Add p to the running checksum d.
 func update(d digest, p []byte) digest {
 	s1, s2 := uint32(d&0xffff), uint32(d>>16)
diff --git a/src/hash/adler32/adler32_test.go b/src/hash/adler32/adler32_test.go
index 0e9c938..6bac802 100644
--- a/src/hash/adler32/adler32_test.go
+++ b/src/hash/adler32/adler32_test.go
@@ -5,57 +5,60 @@
 package adler32
 
 import (
+	"encoding"
+	"io"
 	"strings"
 	"testing"
 )
 
 var golden = []struct {
-	out uint32
-	in  string
+	out       uint32
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }{
-	{0x00000001, ""},
-	{0x00620062, "a"},
-	{0x012600c4, "ab"},
-	{0x024d0127, "abc"},
-	{0x03d8018b, "abcd"},
-	{0x05c801f0, "abcde"},
-	{0x081e0256, "abcdef"},
-	{0x0adb02bd, "abcdefg"},
-	{0x0e000325, "abcdefgh"},
-	{0x118e038e, "abcdefghi"},
-	{0x158603f8, "abcdefghij"},
-	{0x3f090f02, "Discard medicine more than two years old."},
-	{0x46d81477, "He who has a shady past knows that nice guys finish last."},
-	{0x40ee0ee1, "I wouldn't marry him with a ten foot pole."},
-	{0x16661315, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{0x5b2e1480, "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{0x8c3c09ea, "Nepal premier won't resign."},
-	{0x45ac18fd, "For every action there is an equal and opposite government program."},
-	{0x53c61462, "His money is twice tainted: 'taint yours and 'taint mine."},
-	{0x7e511e63, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{0xe4801a6a, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{0x61b507df, "size:  a.out:  bad magic"},
-	{0xb8631171, "The major problem is with sendmail.  -Mark Horton"},
-	{0x8b5e1904, "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{0x7cc6102b, "If the enemy is within range, then so are you."},
-	{0x700318e7, "It's well we cannot hear the screams/That we create in others' dreams."},
-	{0x1e601747, "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{0xb55b0b09, "C is as portable as Stonehedge!!"},
-	{0x39111dd0, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{0x91dd304f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{0x2e5d1316, "How can you write a big system without C++?  -Paul Glick"},
-	{0xd0201df6, "'Invariant assertions' is the most elegant programming technique!  -Tom Szymanski"},
-	{0x211297c8, strings.Repeat("\xff", 5548) + "8"},
-	{0xbaa198c8, strings.Repeat("\xff", 5549) + "9"},
-	{0x553499be, strings.Repeat("\xff", 5550) + "0"},
-	{0xf0c19abe, strings.Repeat("\xff", 5551) + "1"},
-	{0x8d5c9bbe, strings.Repeat("\xff", 5552) + "2"},
-	{0x2af69cbe, strings.Repeat("\xff", 5553) + "3"},
-	{0xc9809dbe, strings.Repeat("\xff", 5554) + "4"},
-	{0x69189ebe, strings.Repeat("\xff", 5555) + "5"},
-	{0x86af0001, strings.Repeat("\x00", 1e5)},
-	{0x79660b4d, strings.Repeat("a", 1e5)},
-	{0x110588ee, strings.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1e4)},
+	{0x00000001, "", "adl\x01\x00\x00\x00\x01"},
+	{0x00620062, "a", "adl\x01\x00\x00\x00\x01"},
+	{0x012600c4, "ab", "adl\x01\x00b\x00b"},
+	{0x024d0127, "abc", "adl\x01\x00b\x00b"},
+	{0x03d8018b, "abcd", "adl\x01\x01&\x00\xc4"},
+	{0x05c801f0, "abcde", "adl\x01\x01&\x00\xc4"},
+	{0x081e0256, "abcdef", "adl\x01\x02M\x01'"},
+	{0x0adb02bd, "abcdefg", "adl\x01\x02M\x01'"},
+	{0x0e000325, "abcdefgh", "adl\x01\x03\xd8\x01\x8b"},
+	{0x118e038e, "abcdefghi", "adl\x01\x03\xd8\x01\x8b"},
+	{0x158603f8, "abcdefghij", "adl\x01\x05\xc8\x01\xf0"},
+	{0x3f090f02, "Discard medicine more than two years old.", "adl\x01NU\a\x87"},
+	{0x46d81477, "He who has a shady past knows that nice guys finish last.", "adl\x01\x89\x8e\t\xe9"},
+	{0x40ee0ee1, "I wouldn't marry him with a ten foot pole.", "adl\x01R\t\ag"},
+	{0x16661315, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "adl\x01\u007f\xbb\t\x10"},
+	{0x5b2e1480, "The days of the digital watch are numbered.  -Tom Stoppard", "adl\x01\x99:\n~"},
+	{0x8c3c09ea, "Nepal premier won't resign.", "adl\x01\"\x05\x05\x05"},
+	{0x45ac18fd, "For every action there is an equal and opposite government program.", "adl\x01\xcc\xfa\f\x00"},
+	{0x53c61462, "His money is twice tainted: 'taint yours and 'taint mine.", "adl\x01\x93\xa9\n\b"},
+	{0x7e511e63, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "adl\x01e\xf5\x10\x14"},
+	{0xe4801a6a, "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "adl\x01\xee\x00\f\xb2"},
+	{0x61b507df, "size:  a.out:  bad magic", "adl\x01\x1a\xfc\x04\x1d"},
+	{0xb8631171, "The major problem is with sendmail.  -Mark Horton", "adl\x01mi\b\xdc"},
+	{0x8b5e1904, "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "adl\x01\xe3\n\f\x9f"},
+	{0x7cc6102b, "If the enemy is within range, then so are you.", "adl\x01_\xe0\b\x1e"},
+	{0x700318e7, "It's well we cannot hear the screams/That we create in others' dreams.", "adl\x01ۘ\f\x87"},
+	{0x1e601747, "You remind me of a TV show, but that's all right: I watch it anyway.", "adl\x01\xcc}\v\x83"},
+	{0xb55b0b09, "C is as portable as Stonehedge!!", "adl\x01,^\x05\xad"},
+	{0x39111dd0, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "adl\x01M\xd1\x0e\xc8"},
+	{0x91dd304f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "adl\x01#\xd8\x17\xd7"},
+	{0x2e5d1316, "How can you write a big system without C++?  -Paul Glick", "adl\x01\x8fU\n\x0f"},
+	{0xd0201df6, "'Invariant assertions' is the most elegant programming technique!  -Tom Szymanski", "adl\x01/\x98\x0e\xc4"},
+	{0x211297c8, strings.Repeat("\xff", 5548) + "8", "adl\x01\x9a\xa6\xcb\xc1"},
+	{0xbaa198c8, strings.Repeat("\xff", 5549) + "9", "adl\x01gu\xcc\xc0"},
+	{0x553499be, strings.Repeat("\xff", 5550) + "0", "adl\x01gu\xcc\xc0"},
+	{0xf0c19abe, strings.Repeat("\xff", 5551) + "1", "adl\x015CͿ"},
+	{0x8d5c9bbe, strings.Repeat("\xff", 5552) + "2", "adl\x015CͿ"},
+	{0x2af69cbe, strings.Repeat("\xff", 5553) + "3", "adl\x01\x04\x10ξ"},
+	{0xc9809dbe, strings.Repeat("\xff", 5554) + "4", "adl\x01\x04\x10ξ"},
+	{0x69189ebe, strings.Repeat("\xff", 5555) + "5", "adl\x01\xd3\xcdϽ"},
+	{0x86af0001, strings.Repeat("\x00", 1e5), "adl\x01\xc3P\x00\x01"},
+	{0x79660b4d, strings.Repeat("a", 1e5), "adl\x01\x81k\x05\xa7"},
+	{0x110588ee, strings.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1e4), "adl\x01e\xd2\xc4p"},
 }
 
 // checksum is a slow but simple implementation of the Adler-32 checksum.
@@ -87,6 +90,38 @@
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	for _, g := range golden {
+		h := New()
+		h2 := New()
+
+		io.WriteString(h, g.in[:len(g.in)/2])
+
+		state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+		if err != nil {
+			t.Errorf("could not marshal: %v", err)
+			continue
+		}
+
+		if string(state) != g.halfState {
+			t.Errorf("checksum(%q) state = %q, want %q", g.in, state, g.halfState)
+			continue
+		}
+
+		if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+			t.Errorf("could not unmarshal: %v", err)
+			continue
+		}
+
+		io.WriteString(h, g.in[len(g.in)/2:])
+		io.WriteString(h2, g.in[len(g.in)/2:])
+
+		if h.Sum32() != h2.Sum32() {
+			t.Errorf("checksum(%q) = 0x%x != marshaled (0x%x)", g.in, h.Sum32(), h2.Sum32())
+		}
+	}
+}
+
 func BenchmarkAdler32KB(b *testing.B) {
 	b.SetBytes(1024)
 	data := make([]byte, 1024)
diff --git a/src/hash/crc32/crc32.go b/src/hash/crc32/crc32.go
index 8aa91b1..1912caa 100644
--- a/src/hash/crc32/crc32.go
+++ b/src/hash/crc32/crc32.go
@@ -13,6 +13,7 @@
 package crc32
 
 import (
+	"errors"
 	"hash"
 	"sync"
 )
@@ -138,9 +139,11 @@
 	tab *Table
 }
 
-// New creates a new hash.Hash32 computing the CRC-32 checksum
-// using the polynomial represented by the Table.
-// Its Sum method will lay the value out in big-endian byte order.
+// New creates a new hash.Hash32 computing the CRC-32 checksum using the
+// polynomial represented by the Table. Its Sum method will lay the
+// value out in big-endian byte order. The returned Hash32 also
+// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 func New(tab *Table) hash.Hash32 {
 	if tab == IEEETable {
 		ieeeOnce.Do(ieeeInit)
@@ -148,9 +151,11 @@
 	return &digest{0, tab}
 }
 
-// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum
-// using the IEEE polynomial.
-// Its Sum method will lay the value out in big-endian byte order.
+// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum using
+// the IEEE polynomial. Its Sum method will lay the value out in
+// big-endian byte order. The returned Hash32 also implements
+// encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to marshal
+// and unmarshal the internal state of the hash.
 func NewIEEE() hash.Hash32 { return New(IEEETable) }
 
 func (d *digest) Size() int { return Size }
@@ -159,6 +164,48 @@
 
 func (d *digest) Reset() { d.crc = 0 }
 
+const (
+	magic         = "crc\x01"
+	marshaledSize = len(magic) + 4 + 4
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	b = appendUint32(b, tableSum(d.tab))
+	b = appendUint32(b, d.crc)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("hash/crc32: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("hash/crc32: invalid hash state size")
+	}
+	if tableSum(d.tab) != readUint32(b[4:]) {
+		return errors.New("hash/crc32: tables do not match")
+	}
+	d.crc = readUint32(b[8:])
+	return nil
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	a := [4]byte{
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func readUint32(b []byte) uint32 {
+	_ = b[3]
+	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
 // Update returns the result of adding the bytes in p to the crc.
 func Update(crc uint32, tab *Table, p []byte) uint32 {
 	switch tab {
@@ -205,3 +252,15 @@
 	ieeeOnce.Do(ieeeInit)
 	return updateIEEE(0, data)
 }
+
+// tableSum returns the IEEE checksum of table t.
+func tableSum(t *Table) uint32 {
+	var a [1024]byte
+	b := a[:0]
+	if t != nil {
+		for _, x := range t {
+			b = appendUint32(b, x)
+		}
+	}
+	return ChecksumIEEE(b)
+}
diff --git a/src/hash/crc32/crc32_arm64.go b/src/hash/crc32/crc32_arm64.go
index 1704486..1f8779d 100644
--- a/src/hash/crc32/crc32_arm64.go
+++ b/src/hash/crc32/crc32_arm64.go
@@ -8,11 +8,12 @@
 
 package crc32
 
-func supportsCRC32() bool
+import "internal/cpu"
+
 func castagnoliUpdate(crc uint32, p []byte) uint32
 func ieeeUpdate(crc uint32, p []byte) uint32
 
-var hasCRC32 = supportsCRC32()
+var hasCRC32 = cpu.ARM64.HasCRC32
 
 func archAvailableCastagnoli() bool {
 	return hasCRC32
diff --git a/src/hash/crc32/crc32_arm64.s b/src/hash/crc32/crc32_arm64.s
index 26a86e4..53274c5 100644
--- a/src/hash/crc32/crc32_arm64.s
+++ b/src/hash/crc32/crc32_arm64.s
@@ -89,9 +89,3 @@
 done:
 	MOVWU	R9, ret+32(FP)
 	RET
-
-// func supportsCRC32() bool
-TEXT ·supportsCRC32(SB),NOSPLIT,$0-1
-	MOVB	runtime·supportCRC32(SB), R0
-	MOVB	R0, ret+0(FP)
-	RET
diff --git a/src/hash/crc32/crc32_test.go b/src/hash/crc32/crc32_test.go
index 0492f46..4bdafaf 100644
--- a/src/hash/crc32/crc32_test.go
+++ b/src/hash/crc32/crc32_test.go
@@ -5,49 +5,53 @@
 package crc32
 
 import (
+	"encoding"
 	"fmt"
 	"hash"
+	"io"
 	"math/rand"
 	"testing"
 )
 
 type test struct {
-	ieee, castagnoli uint32
-	in               string
+	ieee, castagnoli    uint32
+	in                  string
+	halfStateIEEE       string // IEEE marshaled hash state after first half of in written, used by TestGoldenMarshal
+	halfStateCastagnoli string // Castagnoli marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden = []test{
-	{0x0, 0x0, ""},
-	{0xe8b7be43, 0xc1d04330, "a"},
-	{0x9e83486d, 0xe2a22936, "ab"},
-	{0x352441c2, 0x364b3fb7, "abc"},
-	{0xed82cd11, 0x92c80a31, "abcd"},
-	{0x8587d865, 0xc450d697, "abcde"},
-	{0x4b8e39ef, 0x53bceff1, "abcdef"},
-	{0x312a6aa6, 0xe627f441, "abcdefg"},
-	{0xaeef2a50, 0xa9421b7, "abcdefgh"},
-	{0x8da988af, 0x2ddc99fc, "abcdefghi"},
-	{0x3981703a, 0xe6599437, "abcdefghij"},
-	{0x6b9cdfe7, 0xb2cc01fe, "Discard medicine more than two years old."},
-	{0xc90ef73f, 0xe28207f, "He who has a shady past knows that nice guys finish last."},
-	{0xb902341f, 0xbe93f964, "I wouldn't marry him with a ten foot pole."},
-	{0x42080e8, 0x9e3be0c3, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{0x154c6d11, 0xf505ef04, "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{0x4c418325, 0x85d3dc82, "Nepal premier won't resign."},
-	{0x33955150, 0xc5142380, "For every action there is an equal and opposite government program."},
-	{0x26216a4b, 0x75eb77dd, "His money is twice tainted: 'taint yours and 'taint mine."},
-	{0x1abbe45e, 0x91ebe9f7, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{0xc89a94f7, 0xf0b1168e, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{0xab3abe14, 0x572b74e2, "size:  a.out:  bad magic"},
-	{0xbab102b6, 0x8a58a6d5, "The major problem is with sendmail.  -Mark Horton"},
-	{0x999149d7, 0x9c426c50, "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{0x6d52a33c, 0x735400a4, "If the enemy is within range, then so are you."},
-	{0x90631e8d, 0xbec49c95, "It's well we cannot hear the screams/That we create in others' dreams."},
-	{0x78309130, 0xa95a2079, "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{0x7d0a377f, 0xde2e65c5, "C is as portable as Stonehedge!!"},
-	{0x8c79fd79, 0x297a88ed, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{0xa20b7167, 0x66ed1d8b, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{0x8e0bb443, 0xdcded527, "How can you write a big system without C++?  -Paul Glick"},
+	{0x0, 0x0, "", "crc\x01ʇ\x91M\x00\x00\x00\x00", "crc\x01wB\x84\x81\x00\x00\x00\x00"},
+	{0xe8b7be43, 0xc1d04330, "a", "crc\x01ʇ\x91M\x00\x00\x00\x00", "crc\x01wB\x84\x81\x00\x00\x00\x00"},
+	{0x9e83486d, 0xe2a22936, "ab", "crc\x01ʇ\x91M跾C", "crc\x01wB\x84\x81\xc1\xd0C0"},
+	{0x352441c2, 0x364b3fb7, "abc", "crc\x01ʇ\x91M跾C", "crc\x01wB\x84\x81\xc1\xd0C0"},
+	{0xed82cd11, 0x92c80a31, "abcd", "crc\x01ʇ\x91M\x9e\x83Hm", "crc\x01wB\x84\x81\xe2\xa2)6"},
+	{0x8587d865, 0xc450d697, "abcde", "crc\x01ʇ\x91M\x9e\x83Hm", "crc\x01wB\x84\x81\xe2\xa2)6"},
+	{0x4b8e39ef, 0x53bceff1, "abcdef", "crc\x01ʇ\x91M5$A\xc2", "crc\x01wB\x84\x816K?\xb7"},
+	{0x312a6aa6, 0xe627f441, "abcdefg", "crc\x01ʇ\x91M5$A\xc2", "crc\x01wB\x84\x816K?\xb7"},
+	{0xaeef2a50, 0xa9421b7, "abcdefgh", "crc\x01ʇ\x91M\xed\x82\xcd\x11", "crc\x01wB\x84\x81\x92\xc8\n1"},
+	{0x8da988af, 0x2ddc99fc, "abcdefghi", "crc\x01ʇ\x91M\xed\x82\xcd\x11", "crc\x01wB\x84\x81\x92\xc8\n1"},
+	{0x3981703a, 0xe6599437, "abcdefghij", "crc\x01ʇ\x91M\x85\x87\xd8e", "crc\x01wB\x84\x81\xc4P֗"},
+	{0x6b9cdfe7, 0xb2cc01fe, "Discard medicine more than two years old.", "crc\x01ʇ\x91M\xfd\xe5\xc2J", "crc\x01wB\x84\x81S\"(\xe0"},
+	{0xc90ef73f, 0xe28207f, "He who has a shady past knows that nice guys finish last.", "crc\x01ʇ\x91M\x01Nj+", "crc\x01wB\x84\x81'\xdaR\x15"},
+	{0xb902341f, 0xbe93f964, "I wouldn't marry him with a ten foot pole.", "crc\x01ʇ\x91M\x9d\x13\xce\x10", "crc\x01wB\x84\x81\xc3\xed\xabG"},
+	{0x42080e8, 0x9e3be0c3, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "crc\x01ʇ\x91M-\xed\xf7\x94", "crc\x01wB\x84\x81\xce\xceb\x81"},
+	{0x154c6d11, 0xf505ef04, "The days of the digital watch are numbered.  -Tom Stoppard", "crc\x01ʇ\x91MOa\xa5\r", "crc\x01wB\x84\x81\xd3s\x9dP"},
+	{0x4c418325, 0x85d3dc82, "Nepal premier won't resign.", "crc\x01ʇ\x91M\xa8S9\x85", "crc\x01wB\x84\x81{\x90\x8a\x14"},
+	{0x33955150, 0xc5142380, "For every action there is an equal and opposite government program.", "crc\x01ʇ\x91Ma\xe9>\x86", "crc\x01wB\x84\x81\xaa@\xc4\x1c"},
+	{0x26216a4b, 0x75eb77dd, "His money is twice tainted: 'taint yours and 'taint mine.", "crc\x01ʇ\x91M\\\x1an\x88", "crc\x01wB\x84\x81W\a8Z"},
+	{0x1abbe45e, 0x91ebe9f7, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "crc\x01ʇ\x91M\xb7\xf5\xf2\xca", "crc\x01wB\x84\x81\xc4o\x9d\x85"},
+	{0xc89a94f7, 0xf0b1168e, "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "crc\x01ʇ\x91M\x84g1\xe8", "crc\x01wB\x84\x81#\x98\f\xab"},
+	{0xab3abe14, 0x572b74e2, "size:  a.out:  bad magic", "crc\x01ʇ\x91M\x8a\x0f\xad\b", "crc\x01wB\x84\x81\x80\xc9n\xd8"},
+	{0xbab102b6, 0x8a58a6d5, "The major problem is with sendmail.  -Mark Horton", "crc\x01ʇ\x91M\a\xf0\xb3\x15", "crc\x01wB\x84\x81liS\xcc"},
+	{0x999149d7, 0x9c426c50, "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "crc\x01ʇ\x91M\x0fa\xbc.", "crc\x01wB\x84\x81\xdb͏C"},
+	{0x6d52a33c, 0x735400a4, "If the enemy is within range, then so are you.", "crc\x01ʇ\x91My\x1b\x99\xf8", "crc\x01wB\x84\x81\xaaB\x037"},
+	{0x90631e8d, 0xbec49c95, "It's well we cannot hear the screams/That we create in others' dreams.", "crc\x01ʇ\x91M\bqfY", "crc\x01wB\x84\x81\x16y\xa1\xd2"},
+	{0x78309130, 0xa95a2079, "You remind me of a TV show, but that's all right: I watch it anyway.", "crc\x01ʇ\x91M\xbdO,\xc2", "crc\x01wB\x84\x81f&\xc5\xe4"},
+	{0x7d0a377f, 0xde2e65c5, "C is as portable as Stonehedge!!", "crc\x01ʇ\x91M\xf7\xd6\x00\xd5", "crc\x01wB\x84\x81de\\\xf8"},
+	{0x8c79fd79, 0x297a88ed, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "crc\x01ʇ\x91Ml+\xb8\xa7", "crc\x01wB\x84\x81\xbf\xd6S\xdd"},
+	{0xa20b7167, 0x66ed1d8b, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "crc\x01ʇ\x91M<lR[", "crc\x01wB\x84\x81{\xaco\xb1"},
+	{0x8e0bb443, 0xdcded527, "How can you write a big system without C++?  -Paul Glick", "crc\x01ʇ\x91M\x0e\x88\x89\xed", "crc\x01wB\x84\x813\xd7C\u007f"},
 }
 
 // testGoldenIEEE verifies that the given function returns
@@ -105,6 +109,86 @@
 	})
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	t.Run("IEEE", func(t *testing.T) {
+		for _, g := range golden {
+			h := New(IEEETable)
+			h2 := New(IEEETable)
+
+			io.WriteString(h, g.in[:len(g.in)/2])
+
+			state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+			if err != nil {
+				t.Errorf("could not marshal: %v", err)
+				continue
+			}
+
+			if string(state) != g.halfStateIEEE {
+				t.Errorf("IEEE(%q) state = %q, want %q", g.in, state, g.halfStateIEEE)
+				continue
+			}
+
+			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+				t.Errorf("could not unmarshal: %v", err)
+				continue
+			}
+
+			io.WriteString(h, g.in[len(g.in)/2:])
+			io.WriteString(h2, g.in[len(g.in)/2:])
+
+			if h.Sum32() != h2.Sum32() {
+				t.Errorf("IEEE(%s) = 0x%x != marshaled 0x%x", g.in, h.Sum32(), h2.Sum32())
+			}
+		}
+	})
+	t.Run("Castagnoli", func(t *testing.T) {
+		table := MakeTable(Castagnoli)
+		for _, g := range golden {
+			h := New(table)
+			h2 := New(table)
+
+			io.WriteString(h, g.in[:len(g.in)/2])
+
+			state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+			if err != nil {
+				t.Errorf("could not marshal: %v", err)
+				continue
+			}
+
+			if string(state) != g.halfStateCastagnoli {
+				t.Errorf("Castagnoli(%q) state = %q, want %q", g.in, state, g.halfStateCastagnoli)
+				continue
+			}
+
+			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+				t.Errorf("could not unmarshal: %v", err)
+				continue
+			}
+
+			io.WriteString(h, g.in[len(g.in)/2:])
+			io.WriteString(h2, g.in[len(g.in)/2:])
+
+			if h.Sum32() != h2.Sum32() {
+				t.Errorf("Castagnoli(%s) = 0x%x != marshaled 0x%x", g.in, h.Sum32(), h2.Sum32())
+			}
+		}
+	})
+}
+
+func TestMarshalTableMismatch(t *testing.T) {
+	h1 := New(IEEETable)
+	h2 := New(MakeTable(Castagnoli))
+
+	state1, err := h1.(encoding.BinaryMarshaler).MarshalBinary()
+	if err != nil {
+		t.Errorf("could not marshal: %v", err)
+	}
+
+	if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state1); err == nil {
+		t.Errorf("no error when one was expected")
+	}
+}
+
 // TestSimple tests the slicing-by-8 algorithm.
 func TestSlicing(t *testing.T) {
 	tab := slicingMakeTable(IEEE)
diff --git a/src/hash/crc64/crc64.go b/src/hash/crc64/crc64.go
index e939c2a..3b24c24 100644
--- a/src/hash/crc64/crc64.go
+++ b/src/hash/crc64/crc64.go
@@ -7,7 +7,10 @@
 // information.
 package crc64
 
-import "hash"
+import (
+	"errors"
+	"hash"
+)
 
 // The size of a CRC-64 checksum in bytes.
 const Size = 8
@@ -77,9 +80,11 @@
 	tab *Table
 }
 
-// New creates a new hash.Hash64 computing the CRC-64 checksum
-// using the polynomial represented by the Table.
-// Its Sum method will lay the value out in big-endian byte order.
+// New creates a new hash.Hash64 computing the CRC-64 checksum using the
+// polynomial represented by the Table. Its Sum method will lay the
+// value out in big-endian byte order. The returned Hash64 also
+// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 func New(tab *Table) hash.Hash64 { return &digest{0, tab} }
 
 func (d *digest) Size() int { return Size }
@@ -88,6 +93,53 @@
 
 func (d *digest) Reset() { d.crc = 0 }
 
+const (
+	magic         = "crc\x02"
+	marshaledSize = len(magic) + 8 + 8
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	b = appendUint64(b, tableSum(d.tab))
+	b = appendUint64(b, d.crc)
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("hash/crc64: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("hash/crc64: invalid hash state size")
+	}
+	if tableSum(d.tab) != readUint64(b[4:]) {
+		return errors.New("hash/crc64: tables do not match")
+	}
+	d.crc = readUint64(b[12:])
+	return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	a := [8]byte{
+		byte(x >> 56),
+		byte(x >> 48),
+		byte(x >> 40),
+		byte(x >> 32),
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func readUint64(b []byte) uint64 {
+	_ = b[7]
+	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 update(crc uint64, tab *Table, p []byte) uint64 {
 	crc = ^crc
 	// Table comparison is somewhat expensive, so avoid it for small sizes
@@ -145,3 +197,15 @@
 // Checksum returns the CRC-64 checksum of data
 // using the polynomial represented by the Table.
 func Checksum(data []byte, tab *Table) uint64 { return update(0, tab, data) }
+
+// tableSum returns the ISO checksum of table t.
+func tableSum(t *Table) uint64 {
+	var a [2048]byte
+	b := a[:0]
+	if t != nil {
+		for _, x := range t {
+			b = appendUint64(b, x)
+		}
+	}
+	return Checksum(b, MakeTable(ISO))
+}
diff --git a/src/hash/crc64/crc64_test.go b/src/hash/crc64/crc64_test.go
index 480b150..9db05b0 100644
--- a/src/hash/crc64/crc64_test.go
+++ b/src/hash/crc64/crc64_test.go
@@ -5,49 +5,52 @@
 package crc64
 
 import (
+	"encoding"
 	"io"
 	"testing"
 )
 
 type test struct {
-	outISO  uint64
-	outECMA uint64
-	in      string
+	outISO        uint64
+	outECMA       uint64
+	in            string
+	halfStateISO  string // ISO marshaled hash state after first half of in written, used by TestGoldenMarshal
+	halfStateECMA string // ECMA marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden = []test{
-	{0x0, 0x0, ""},
-	{0x3420000000000000, 0x330284772e652b05, "a"},
-	{0x36c4200000000000, 0xbc6573200e84b046, "ab"},
-	{0x3776c42000000000, 0x2cd8094a1a277627, "abc"},
-	{0x336776c420000000, 0x3c9d28596e5960ba, "abcd"},
-	{0x32d36776c4200000, 0x40bdf58fb0895f2, "abcde"},
-	{0x3002d36776c42000, 0xd08e9f8545a700f4, "abcdef"},
-	{0x31b002d36776c420, 0xec20a3a8cc710e66, "abcdefg"},
-	{0xe21b002d36776c4, 0x67b4f30a647a0c59, "abcdefgh"},
-	{0x8b6e21b002d36776, 0x9966f6c89d56ef8e, "abcdefghi"},
-	{0x7f5b6e21b002d367, 0x32093a2ecd5773f4, "abcdefghij"},
-	{0x8ec0e7c835bf9cdf, 0x8a0825223ea6d221, "Discard medicine more than two years old."},
-	{0xc7db1759e2be5ab4, 0x8562c0ac2ab9a00d, "He who has a shady past knows that nice guys finish last."},
-	{0xfbf9d9603a6fa020, 0x3ee2a39c083f38b4, "I wouldn't marry him with a ten foot pole."},
-	{0xeafc4211a6daa0ef, 0x1f603830353e518a, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{0x3e05b21c7a4dc4da, 0x2fd681d7b2421fd, "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{0x5255866ad6ef28a6, 0x790ef2b16a745a41, "Nepal premier won't resign."},
-	{0x8a79895be1e9c361, 0x3ef8f06daccdcddf, "For every action there is an equal and opposite government program."},
-	{0x8878963a649d4916, 0x49e41b2660b106d, "His money is twice tainted: 'taint yours and 'taint mine."},
-	{0xa7b9d53ea87eb82f, 0x561cc0cfa235ac68, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{0xdb6805c0966a2f9c, 0xd4fe9ef082e69f59, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{0xf3553c65dacdadd2, 0xe3b5e46cd8d63a4d, "size:  a.out:  bad magic"},
-	{0x9d5e034087a676b9, 0x865aaf6b94f2a051, "The major problem is with sendmail.  -Mark Horton"},
-	{0xa6db2d7f8da96417, 0x7eca10d2f8136eb4, "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{0x325e00cd2fe819f9, 0xd7dd118c98e98727, "If the enemy is within range, then so are you."},
-	{0x88c6600ce58ae4c6, 0x70fb33c119c29318, "It's well we cannot hear the screams/That we create in others' dreams."},
-	{0x28c4a3f3b769e078, 0x57c891e39a97d9b7, "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{0xa698a34c9d9f1dca, 0xa1f46ba20ad06eb7, "C is as portable as Stonehedge!!"},
-	{0xf6c1e2a8c26c5cfc, 0x7ad25fafa1710407, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{0xd402559dfe9b70c, 0x73cef1666185c13f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{0xdb6efff26aa94946, 0xb41858f73c389602, "How can you write a big system without C++?  -Paul Glick"},
-	{0xe7fcf1006b503b61, 0x27db187fc15bbc72, "This is a test of the emergency broadcast system."},
+	{0x0, 0x0, "", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\x00\x00\x00\x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{0x3420000000000000, 0x330284772e652b05, "a", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\x00\x00\x00\x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{0x36c4200000000000, 0xbc6573200e84b046, "ab", "crc\x02s\xba\x84\x84\xbb\xcd]\xef4 \x00\x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee3\x02\x84w.e+\x05"},
+	{0x3776c42000000000, 0x2cd8094a1a277627, "abc", "crc\x02s\xba\x84\x84\xbb\xcd]\xef4 \x00\x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee3\x02\x84w.e+\x05"},
+	{0x336776c420000000, 0x3c9d28596e5960ba, "abcd", "crc\x02s\xba\x84\x84\xbb\xcd]\xef6\xc4 \x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee\xbces \x0e\x84\xb0F"},
+	{0x32d36776c4200000, 0x40bdf58fb0895f2, "abcde", "crc\x02s\xba\x84\x84\xbb\xcd]\xef6\xc4 \x00\x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee\xbces \x0e\x84\xb0F"},
+	{0x3002d36776c42000, 0xd08e9f8545a700f4, "abcdef", "crc\x02s\xba\x84\x84\xbb\xcd]\xef7v\xc4 \x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee,\xd8\tJ\x1a'v'"},
+	{0x31b002d36776c420, 0xec20a3a8cc710e66, "abcdefg", "crc\x02s\xba\x84\x84\xbb\xcd]\xef7v\xc4 \x00\x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee,\xd8\tJ\x1a'v'"},
+	{0xe21b002d36776c4, 0x67b4f30a647a0c59, "abcdefgh", "crc\x02s\xba\x84\x84\xbb\xcd]\xef3gv\xc4 \x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee<\x9d(YnY`\xba"},
+	{0x8b6e21b002d36776, 0x9966f6c89d56ef8e, "abcdefghi", "crc\x02s\xba\x84\x84\xbb\xcd]\xef3gv\xc4 \x00\x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee<\x9d(YnY`\xba"},
+	{0x7f5b6e21b002d367, 0x32093a2ecd5773f4, "abcdefghij", "crc\x02s\xba\x84\x84\xbb\xcd]\xef2\xd3gv\xc4 \x00\x00", "crc\x02`&\x9aR\xe1\xb7\xfee\x04\v\xdfX\xfb\b\x95\xf2"},
+	{0x8ec0e7c835bf9cdf, 0x8a0825223ea6d221, "Discard medicine more than two years old.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xc6\xc0\f\xac'\x11\x12\xd5", "crc\x02`&\x9aR\xe1\xb7\xfee\xfd%\xc0&\xa0R\xef\x95"},
+	{0xc7db1759e2be5ab4, 0x8562c0ac2ab9a00d, "He who has a shady past knows that nice guys finish last.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\t\xcb\xd15X[r\t", "crc\x02`&\x9aR\xe1\xb7\xfee\a\x02\xe8|+\xc1\x06\xe3"},
+	{0xfbf9d9603a6fa020, 0x3ee2a39c083f38b4, "I wouldn't marry him with a ten foot pole.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\x19\xc8d\xbe\x84\x14\x87_", "crc\x02`&\x9aR\xe1\xb7\xfee˷\xd3\xeeG\xdcE\x8c"},
+	{0xeafc4211a6daa0ef, 0x1f603830353e518a, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xad\x1b*\xc0\xb1\xf3i(", "crc\x02`&\x9aR\xe1\xb7\xfee\xa7\x8a\xdb\xf6\xd2R\t\x96"},
+	{0x3e05b21c7a4dc4da, 0x2fd681d7b2421fd, "The days of the digital watch are numbered.  -Tom Stoppard", "crc\x02s\xba\x84\x84\xbb\xcd]\xefv78\x1ak\x02\x8f\xff", "crc\x02`&\x9aR\xe1\xb7\xfeeT\xcbl\x10\xfb\x87K*"},
+	{0x5255866ad6ef28a6, 0x790ef2b16a745a41, "Nepal premier won't resign.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xcbf\x11R\xbfh\xde\xc9", "crc\x02`&\x9aR\xe1\xb7\xfee6\x13ُ\x06_\xbd\x9a"},
+	{0x8a79895be1e9c361, 0x3ef8f06daccdcddf, "For every action there is an equal and opposite government program.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xf3pV\x01c_Wu", "crc\x02`&\x9aR\xe1\xb7\xfee\xe7\xc6\n\b\x12FL\xa0"},
+	{0x8878963a649d4916, 0x49e41b2660b106d, "His money is twice tainted: 'taint yours and 'taint mine.", "crc\x02s\xba\x84\x84\xbb\xcd]\xefñ\xff\xf1\xe0/Δ", "crc\x02`&\x9aR\xe1\xb7\xfeeOL/\xb1\xec\xa2\x14\x87"},
+	{0xa7b9d53ea87eb82f, 0x561cc0cfa235ac68, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "crc\x02s\xba\x84\x84\xbb\xcd]\xefݸa\xe1\xb5\xf8\xb9W", "crc\x02`&\x9aR\xe1\xb7\xfee\x87)GQ\x03\xf4K\t"},
+	{0xdb6805c0966a2f9c, 0xd4fe9ef082e69f59, "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "crc\x02s\xba\x84\x84\xbb\xcd]\xefV\xba\x12\x91\x81\x1fNU", "crc\x02`&\x9aR\xe1\xb7\xfee\n\xb8\x81v?\xdeL\xcb"},
+	{0xf3553c65dacdadd2, 0xe3b5e46cd8d63a4d, "size:  a.out:  bad magic", "crc\x02s\xba\x84\x84\xbb\xcd]\xefG\xad\xbc\xb2\xa8y\xc9\xdc", "crc\x02`&\x9aR\xe1\xb7\xfee\xcc\xce\xe5\xe6\x89p\x01\xb8"},
+	{0x9d5e034087a676b9, 0x865aaf6b94f2a051, "The major problem is with sendmail.  -Mark Horton", "crc\x02s\xba\x84\x84\xbb\xcd]\uf8acn\x8aT;&\xd5", "crc\x02`&\x9aR\xe1\xb7\xfeeFf\x9c\x1f\xc9x\xbfa"},
+	{0xa6db2d7f8da96417, 0x7eca10d2f8136eb4, "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xeb\x18\xbf\xf9}\x91\xe5|", "crc\x02`&\x9aR\xe1\xb7\xfeea\x9e\x05:\xce[\xe7\x19"},
+	{0x325e00cd2fe819f9, 0xd7dd118c98e98727, "If the enemy is within range, then so are you.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef^5k\xd0Aj_{", "crc\x02`&\x9aR\xe1\xb7\xfee\v#\x99\xa8r\x83YR"},
+	{0x88c6600ce58ae4c6, 0x70fb33c119c29318, "It's well we cannot hear the screams/That we create in others' dreams.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef|\xb5\x02\xdcw\x18/\x86", "crc\x02`&\x9aR\xe1\xb7\xfee]\x9d-\xed\x8c\xf9r9"},
+	{0x28c4a3f3b769e078, 0x57c891e39a97d9b7, "You remind me of a TV show, but that's all right: I watch it anyway.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\x03\x8bd\x1c\xb0_\x16\x98", "crc\x02`&\x9aR\xe1\xb7\xfee\xafW\x98\xaa\"\xe7\xd7|"},
+	{0xa698a34c9d9f1dca, 0xa1f46ba20ad06eb7, "C is as portable as Stonehedge!!", "crc\x02s\xba\x84\x84\xbb\xcd]\xef.P\xe1I\xc6pi\xdc", "crc\x02`&\x9aR\xe1\xb7\xfee֚\x06\x01(\xc0\x1e\x8b"},
+	{0xf6c1e2a8c26c5cfc, 0x7ad25fafa1710407, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\xf7\xa04\x8a\xf2o\xe0;", "crc\x02`&\x9aR\xe1\xb7\xfee<[\xd2%\x9em\x94\x04"},
+	{0xd402559dfe9b70c, 0x73cef1666185c13f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "crc\x02s\xba\x84\x84\xbb\xcd]\xef\u007f\xae\xb9\xbaX=\x19v", "crc\x02`&\x9aR\xe1\xb7\xfee\xb2˦Y\xc5\xd0G\x03"},
+	{0xdb6efff26aa94946, 0xb41858f73c389602, "How can you write a big system without C++?  -Paul Glick", "crc\x02s\xba\x84\x84\xbb\xcd]\xefa\xed$js\xb9\xa5A", "crc\x02`&\x9aR\xe1\xb7\xfeeZm\x96\x8a\xe2\xaf\x13p"},
+	{0xe7fcf1006b503b61, 0x27db187fc15bbc72, "This is a test of the emergency broadcast system.", "crc\x02s\xba\x84\x84\xbb\xcd]\xef}\xee[q\x16\xcb\xe4\x8d", "crc\x02`&\x9aR\xe1\xb7\xfee\xb1\x93] \xeb\xa9am"},
 }
 
 func TestGolden(t *testing.T) {
@@ -72,6 +75,87 @@
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	t.Run("ISO", func(t *testing.T) {
+		table := MakeTable(ISO)
+		for _, g := range golden {
+			h := New(table)
+			h2 := New(table)
+
+			io.WriteString(h, g.in[:len(g.in)/2])
+
+			state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+			if err != nil {
+				t.Errorf("could not marshal: %v", err)
+				continue
+			}
+
+			if string(state) != g.halfStateISO {
+				t.Errorf("ISO crc64(%q) state = %q, want %q", g.in, state, g.halfStateISO)
+				continue
+			}
+
+			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+				t.Errorf("could not unmarshal: %v", err)
+				continue
+			}
+
+			io.WriteString(h, g.in[len(g.in)/2:])
+			io.WriteString(h2, g.in[len(g.in)/2:])
+
+			if h.Sum64() != h2.Sum64() {
+				t.Errorf("ISO crc64(%s) = 0x%x != marshaled (0x%x)", g.in, h.Sum64(), h2.Sum64())
+			}
+		}
+	})
+	t.Run("ECMA", func(t *testing.T) {
+		table := MakeTable(ECMA)
+		for _, g := range golden {
+			h := New(table)
+			h2 := New(table)
+
+			io.WriteString(h, g.in[:len(g.in)/2])
+
+			state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+			if err != nil {
+				t.Errorf("could not marshal: %v", err)
+				continue
+			}
+
+			if string(state) != g.halfStateECMA {
+				t.Errorf("ECMA crc64(%q) state = %q, want %q", g.in, state, g.halfStateECMA)
+				continue
+			}
+
+			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+				t.Errorf("could not unmarshal: %v", err)
+				continue
+			}
+
+			io.WriteString(h, g.in[len(g.in)/2:])
+			io.WriteString(h2, g.in[len(g.in)/2:])
+
+			if h.Sum64() != h2.Sum64() {
+				t.Errorf("ECMA crc64(%s) = 0x%x != marshaled (0x%x)", g.in, h.Sum64(), h2.Sum64())
+			}
+		}
+	})
+}
+
+func TestMarshalTableMismatch(t *testing.T) {
+	h1 := New(MakeTable(ISO))
+	h2 := New(MakeTable(ECMA))
+
+	state1, err := h1.(encoding.BinaryMarshaler).MarshalBinary()
+	if err != nil {
+		t.Errorf("could not marshal: %v", err)
+	}
+
+	if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state1); err == nil {
+		t.Errorf("no error when one was expected")
+	}
+}
+
 func bench(b *testing.B, poly uint64, size int64) {
 	b.SetBytes(size)
 	data := make([]byte, size)
diff --git a/src/hash/example_test.go b/src/hash/example_test.go
new file mode 100644
index 0000000..f07b9aa
--- /dev/null
+++ b/src/hash/example_test.go
@@ -0,0 +1,51 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package hash_test
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"encoding"
+	"fmt"
+	"log"
+)
+
+func Example_binaryMarshaler() {
+	const (
+		input1 = "The tunneling gopher digs downwards, "
+		input2 = "unaware of what he will find."
+	)
+
+	first := sha256.New()
+	first.Write([]byte(input1))
+
+	marshaler, ok := first.(encoding.BinaryMarshaler)
+	if !ok {
+		log.Fatal("first does not implement encoding.BinaryMarshaler")
+	}
+	state, err := marshaler.MarshalBinary()
+	if err != nil {
+		log.Fatal("unable to marshal hash:", err)
+	}
+
+	second := sha256.New()
+
+	unmarshaler, ok := second.(encoding.BinaryUnmarshaler)
+	if !ok {
+		log.Fatal("second does not implement encoding.BinaryUnmarshaler")
+	}
+	if err := unmarshaler.UnmarshalBinary(state); err != nil {
+		log.Fatal("unable to unmarshal hash:", err)
+	}
+
+	first.Write([]byte(input2))
+	second.Write([]byte(input2))
+
+	fmt.Printf("%x\n", first.Sum(nil))
+	fmt.Println(bytes.Equal(first.Sum(nil), second.Sum(nil)))
+	// Output:
+	// 57d51a066f3a39942649cd9a76c77e97ceab246756ff3888659e6aa5a07f4a52
+	// true
+}
diff --git a/src/hash/fnv/fnv.go b/src/hash/fnv/fnv.go
index 3d2df73..7662315 100644
--- a/src/hash/fnv/fnv.go
+++ b/src/hash/fnv/fnv.go
@@ -6,9 +6,14 @@
 // created by Glenn Fowler, Landon Curt Noll, and Phong Vo.
 // See
 // https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function.
+//
+// All the hash.Hash implementations returned by this package also
+// implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
 package fnv
 
 import (
+	"errors"
 	"hash"
 )
 
@@ -215,3 +220,163 @@
 		byte(s[1]>>56), byte(s[1]>>48), byte(s[1]>>40), byte(s[1]>>32), byte(s[1]>>24), byte(s[1]>>16), byte(s[1]>>8), byte(s[1]),
 	)
 }
+
+const (
+	magic32          = "fnv\x01"
+	magic32a         = "fnv\x02"
+	magic64          = "fnv\x03"
+	magic64a         = "fnv\x04"
+	magic128         = "fnv\x05"
+	magic128a        = "fnv\x06"
+	marshaledSize32  = len(magic32) + 4
+	marshaledSize64  = len(magic64) + 8
+	marshaledSize128 = len(magic128) + 8*2
+)
+
+func (s *sum32) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize32)
+	b = append(b, magic32...)
+	b = appendUint32(b, uint32(*s))
+	return b, nil
+}
+
+func (s *sum32a) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize32)
+	b = append(b, magic32a...)
+	b = appendUint32(b, uint32(*s))
+	return b, nil
+}
+
+func (s *sum64) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize64)
+	b = append(b, magic64...)
+	b = appendUint64(b, uint64(*s))
+	return b, nil
+
+}
+
+func (s *sum64a) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize64)
+	b = append(b, magic64a...)
+	b = appendUint64(b, uint64(*s))
+	return b, nil
+}
+
+func (s *sum128) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize128)
+	b = append(b, magic128...)
+	b = appendUint64(b, s[0])
+	b = appendUint64(b, s[1])
+	return b, nil
+}
+
+func (s *sum128a) MarshalBinary() ([]byte, error) {
+	b := make([]byte, 0, marshaledSize128)
+	b = append(b, magic128a...)
+	b = appendUint64(b, s[0])
+	b = appendUint64(b, s[1])
+	return b, nil
+}
+
+func (s *sum32) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic32) || string(b[:len(magic32)]) != magic32 {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize32 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	*s = sum32(readUint32(b[4:]))
+	return nil
+}
+
+func (s *sum32a) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic32a) || string(b[:len(magic32a)]) != magic32a {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize32 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	*s = sum32a(readUint32(b[4:]))
+	return nil
+}
+
+func (s *sum64) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic64) || string(b[:len(magic64)]) != magic64 {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize64 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	*s = sum64(readUint64(b[4:]))
+	return nil
+}
+
+func (s *sum64a) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic64a) || string(b[:len(magic64a)]) != magic64a {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize64 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	*s = sum64a(readUint64(b[4:]))
+	return nil
+}
+
+func (s *sum128) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic128) || string(b[:len(magic128)]) != magic128 {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize128 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	s[0] = readUint64(b[4:])
+	s[1] = readUint64(b[12:])
+	return nil
+}
+
+func (s *sum128a) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic128a) || string(b[:len(magic128a)]) != magic128a {
+		return errors.New("hash/fnv: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize128 {
+		return errors.New("hash/fnv: invalid hash state size")
+	}
+	s[0] = readUint64(b[4:])
+	s[1] = readUint64(b[12:])
+	return nil
+}
+
+func readUint32(b []byte) uint32 {
+	_ = b[3]
+	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	a := [4]byte{
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	a := [8]byte{
+		byte(x >> 56),
+		byte(x >> 48),
+		byte(x >> 40),
+		byte(x >> 32),
+		byte(x >> 24),
+		byte(x >> 16),
+		byte(x >> 8),
+		byte(x),
+	}
+	return append(b, a[:]...)
+}
+
+func readUint64(b []byte) uint64 {
+	_ = b[7]
+	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
+}
diff --git a/src/hash/fnv/fnv_test.go b/src/hash/fnv/fnv_test.go
index 7da15ba..7b1f7a3 100644
--- a/src/hash/fnv/fnv_test.go
+++ b/src/hash/fnv/fnv_test.go
@@ -6,56 +6,59 @@
 
 import (
 	"bytes"
+	"encoding"
 	"encoding/binary"
 	"hash"
+	"io"
 	"testing"
 )
 
 type golden struct {
-	sum  []byte
-	text string
+	out       []byte
+	in        string
+	halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
 }
 
 var golden32 = []golden{
-	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, ""},
-	{[]byte{0x05, 0x0c, 0x5d, 0x7e}, "a"},
-	{[]byte{0x70, 0x77, 0x2d, 0x38}, "ab"},
-	{[]byte{0x43, 0x9c, 0x2f, 0x4b}, "abc"},
+	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, "", "fnv\x01\x81\x1c\x9d\xc5"},
+	{[]byte{0x05, 0x0c, 0x5d, 0x7e}, "a", "fnv\x01\x81\x1c\x9d\xc5"},
+	{[]byte{0x70, 0x77, 0x2d, 0x38}, "ab", "fnv\x01\x05\f]~"},
+	{[]byte{0x43, 0x9c, 0x2f, 0x4b}, "abc", "fnv\x01\x05\f]~"},
 }
 
 var golden32a = []golden{
-	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, ""},
-	{[]byte{0xe4, 0x0c, 0x29, 0x2c}, "a"},
-	{[]byte{0x4d, 0x25, 0x05, 0xca}, "ab"},
-	{[]byte{0x1a, 0x47, 0xe9, 0x0b}, "abc"},
+	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, "", "fnv\x02\x81\x1c\x9d\xc5"},
+	{[]byte{0xe4, 0x0c, 0x29, 0x2c}, "a", "fnv\x02\x81\x1c\x9d\xc5"},
+	{[]byte{0x4d, 0x25, 0x05, 0xca}, "ab", "fnv\x02\xe4\f),"},
+	{[]byte{0x1a, 0x47, 0xe9, 0x0b}, "abc", "fnv\x02\xe4\f),"},
 }
 
 var golden64 = []golden{
-	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, ""},
-	{[]byte{0xaf, 0x63, 0xbd, 0x4c, 0x86, 0x01, 0xb7, 0xbe}, "a"},
-	{[]byte{0x08, 0x32, 0x67, 0x07, 0xb4, 0xeb, 0x37, 0xb8}, "ab"},
-	{[]byte{0xd8, 0xdc, 0xca, 0x18, 0x6b, 0xaf, 0xad, 0xcb}, "abc"},
+	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, "", "fnv\x03\xcb\xf2\x9c\xe4\x84\"#%"},
+	{[]byte{0xaf, 0x63, 0xbd, 0x4c, 0x86, 0x01, 0xb7, 0xbe}, "a", "fnv\x03\xcb\xf2\x9c\xe4\x84\"#%"},
+	{[]byte{0x08, 0x32, 0x67, 0x07, 0xb4, 0xeb, 0x37, 0xb8}, "ab", "fnv\x03\xafc\xbdL\x86\x01\xb7\xbe"},
+	{[]byte{0xd8, 0xdc, 0xca, 0x18, 0x6b, 0xaf, 0xad, 0xcb}, "abc", "fnv\x03\xafc\xbdL\x86\x01\xb7\xbe"},
 }
 
 var golden64a = []golden{
-	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, ""},
-	{[]byte{0xaf, 0x63, 0xdc, 0x4c, 0x86, 0x01, 0xec, 0x8c}, "a"},
-	{[]byte{0x08, 0x9c, 0x44, 0x07, 0xb5, 0x45, 0x98, 0x6a}, "ab"},
-	{[]byte{0xe7, 0x1f, 0xa2, 0x19, 0x05, 0x41, 0x57, 0x4b}, "abc"},
+	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, "", "fnv\x04\xcb\xf2\x9c\xe4\x84\"#%"},
+	{[]byte{0xaf, 0x63, 0xdc, 0x4c, 0x86, 0x01, 0xec, 0x8c}, "a", "fnv\x04\xcb\xf2\x9c\xe4\x84\"#%"},
+	{[]byte{0x08, 0x9c, 0x44, 0x07, 0xb5, 0x45, 0x98, 0x6a}, "ab", "fnv\x04\xafc\xdcL\x86\x01\xec\x8c"},
+	{[]byte{0xe7, 0x1f, 0xa2, 0x19, 0x05, 0x41, 0x57, 0x4b}, "abc", "fnv\x04\xafc\xdcL\x86\x01\xec\x8c"},
 }
 
 var golden128 = []golden{
-	{[]byte{0x6c, 0x62, 0x27, 0x2e, 0x07, 0xbb, 0x01, 0x42, 0x62, 0xb8, 0x21, 0x75, 0x62, 0x95, 0xc5, 0x8d}, ""},
-	{[]byte{0xd2, 0x28, 0xcb, 0x69, 0x10, 0x1a, 0x8c, 0xaf, 0x78, 0x91, 0x2b, 0x70, 0x4e, 0x4a, 0x14, 0x1e}, "a"},
-	{[]byte{0x8, 0x80, 0x94, 0x5a, 0xee, 0xab, 0x1b, 0xe9, 0x5a, 0xa0, 0x73, 0x30, 0x55, 0x26, 0xc0, 0x88}, "ab"},
-	{[]byte{0xa6, 0x8b, 0xb2, 0xa4, 0x34, 0x8b, 0x58, 0x22, 0x83, 0x6d, 0xbc, 0x78, 0xc6, 0xae, 0xe7, 0x3b}, "abc"},
+	{[]byte{0x6c, 0x62, 0x27, 0x2e, 0x07, 0xbb, 0x01, 0x42, 0x62, 0xb8, 0x21, 0x75, 0x62, 0x95, 0xc5, 0x8d}, "", "fnv\x05lb'.\a\xbb\x01Bb\xb8!ub\x95ō"},
+	{[]byte{0xd2, 0x28, 0xcb, 0x69, 0x10, 0x1a, 0x8c, 0xaf, 0x78, 0x91, 0x2b, 0x70, 0x4e, 0x4a, 0x14, 0x1e}, "a", "fnv\x05lb'.\a\xbb\x01Bb\xb8!ub\x95ō"},
+	{[]byte{0x8, 0x80, 0x94, 0x5a, 0xee, 0xab, 0x1b, 0xe9, 0x5a, 0xa0, 0x73, 0x30, 0x55, 0x26, 0xc0, 0x88}, "ab", "fnv\x05\xd2(\xcbi\x10\x1a\x8c\xafx\x91+pNJ\x14\x1e"},
+	{[]byte{0xa6, 0x8b, 0xb2, 0xa4, 0x34, 0x8b, 0x58, 0x22, 0x83, 0x6d, 0xbc, 0x78, 0xc6, 0xae, 0xe7, 0x3b}, "abc", "fnv\x05\xd2(\xcbi\x10\x1a\x8c\xafx\x91+pNJ\x14\x1e"},
 }
 
 var golden128a = []golden{
-	{[]byte{0x6c, 0x62, 0x27, 0x2e, 0x07, 0xbb, 0x01, 0x42, 0x62, 0xb8, 0x21, 0x75, 0x62, 0x95, 0xc5, 0x8d}, ""},
-	{[]byte{0xd2, 0x28, 0xcb, 0x69, 0x6f, 0x1a, 0x8c, 0xaf, 0x78, 0x91, 0x2b, 0x70, 0x4e, 0x4a, 0x89, 0x64}, "a"},
-	{[]byte{0x08, 0x80, 0x95, 0x44, 0xbb, 0xab, 0x1b, 0xe9, 0x5a, 0xa0, 0x73, 0x30, 0x55, 0xb6, 0x9a, 0x62}, "ab"},
-	{[]byte{0xa6, 0x8d, 0x62, 0x2c, 0xec, 0x8b, 0x58, 0x22, 0x83, 0x6d, 0xbc, 0x79, 0x77, 0xaf, 0x7f, 0x3b}, "abc"},
+	{[]byte{0x6c, 0x62, 0x27, 0x2e, 0x07, 0xbb, 0x01, 0x42, 0x62, 0xb8, 0x21, 0x75, 0x62, 0x95, 0xc5, 0x8d}, "", "fnv\x06lb'.\a\xbb\x01Bb\xb8!ub\x95ō"},
+	{[]byte{0xd2, 0x28, 0xcb, 0x69, 0x6f, 0x1a, 0x8c, 0xaf, 0x78, 0x91, 0x2b, 0x70, 0x4e, 0x4a, 0x89, 0x64}, "a", "fnv\x06lb'.\a\xbb\x01Bb\xb8!ub\x95ō"},
+	{[]byte{0x08, 0x80, 0x95, 0x44, 0xbb, 0xab, 0x1b, 0xe9, 0x5a, 0xa0, 0x73, 0x30, 0x55, 0xb6, 0x9a, 0x62}, "ab", "fnv\x06\xd2(\xcbio\x1a\x8c\xafx\x91+pNJ\x89d"},
+	{[]byte{0xa6, 0x8d, 0x62, 0x2c, 0xec, 0x8b, 0x58, 0x22, 0x83, 0x6d, 0xbc, 0x79, 0x77, 0xaf, 0x7f, 0x3b}, "abc", "fnv\x06\xd2(\xcbio\x1a\x8c\xafx\x91+pNJ\x89d"},
 }
 
 func TestGolden32(t *testing.T) {
@@ -85,19 +88,67 @@
 func testGolden(t *testing.T, hash hash.Hash, gold []golden) {
 	for _, g := range gold {
 		hash.Reset()
-		done, error := hash.Write([]byte(g.text))
+		done, error := hash.Write([]byte(g.in))
 		if error != nil {
 			t.Fatalf("write error: %s", error)
 		}
-		if done != len(g.text) {
-			t.Fatalf("wrote only %d out of %d bytes", done, len(g.text))
+		if done != len(g.in) {
+			t.Fatalf("wrote only %d out of %d bytes", done, len(g.in))
 		}
-		if actual := hash.Sum(nil); !bytes.Equal(g.sum, actual) {
-			t.Errorf("hash(%q) = 0x%x want 0x%x", g.text, actual, g.sum)
+		if actual := hash.Sum(nil); !bytes.Equal(g.out, actual) {
+			t.Errorf("hash(%q) = 0x%x want 0x%x", g.in, actual, g.out)
 		}
 	}
 }
 
+func TestGoldenMarshal(t *testing.T) {
+	tests := []struct {
+		name    string
+		newHash func() hash.Hash
+		gold    []golden
+	}{
+		{"32", func() hash.Hash { return New32() }, golden32},
+		{"32a", func() hash.Hash { return New32a() }, golden32a},
+		{"64", func() hash.Hash { return New64() }, golden64},
+		{"64a", func() hash.Hash { return New64a() }, golden64a},
+		{"128", func() hash.Hash { return New128() }, golden128},
+		{"128a", func() hash.Hash { return New128a() }, golden128a},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			for _, g := range tt.gold {
+				h := tt.newHash()
+				h2 := tt.newHash()
+
+				io.WriteString(h, g.in[:len(g.in)/2])
+
+				state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+				if err != nil {
+					t.Errorf("could not marshal: %v", err)
+					continue
+				}
+
+				if string(state) != g.halfState {
+					t.Errorf("checksum(%q) state = %q, want %q", g.in, state, g.halfState)
+					continue
+				}
+
+				if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
+					t.Errorf("could not unmarshal: %v", err)
+					continue
+				}
+
+				io.WriteString(h, g.in[len(g.in)/2:])
+				io.WriteString(h2, g.in[len(g.in)/2:])
+
+				if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
+					t.Errorf("hash(%q) = 0x%x != marshaled 0x%x", g.in, actual, actual2)
+				}
+			}
+		})
+	}
+}
+
 func TestIntegrity32(t *testing.T) {
 	testIntegrity(t, New32())
 }
diff --git a/src/hash/hash.go b/src/hash/hash.go
index 8d138d0..62cf6a4 100644
--- a/src/hash/hash.go
+++ b/src/hash/hash.go
@@ -8,6 +8,21 @@
 import "io"
 
 // Hash is the common interface implemented by all hash functions.
+//
+// Hash implementations in the standard library (e.g. hash/crc32 and
+// crypto/sha256) implement the encoding.BinaryMarshaler and
+// encoding.BinaryUnmarshaler interfaces. Marshaling a hash implementation
+// allows its internal state to be saved and used for additional processing
+// later, without having to re-write the data previously written to the hash.
+// The hash state may contain portions of the input in its original form,
+// which users are expected to handle for any possible security implications.
+//
+// Compatibility: Any future changes to hash or crypto packages will endeavor
+// to maintain compatibility with state encoded using previous versions.
+// That is, any released versions of the packages should be able to
+// decode data written with any previously released version,
+// subject to issues such as security fixes.
+// See the Go compatibility document for background: https://golang.org/doc/go1compat
 type Hash interface {
 	// Write (via the embedded io.Writer interface) adds more data to the running hash.
 	// It never returns an error.
diff --git a/src/hash/marshal_test.go b/src/hash/marshal_test.go
new file mode 100644
index 0000000..3091f7a
--- /dev/null
+++ b/src/hash/marshal_test.go
@@ -0,0 +1,107 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that the hashes in the standard library implement
+// BinaryMarshaler, BinaryUnmarshaler,
+// and lock in the current representations.
+
+package hash_test
+
+import (
+	"bytes"
+	"crypto/md5"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+	"encoding"
+	"encoding/hex"
+	"hash"
+	"hash/adler32"
+	"hash/crc32"
+	"hash/crc64"
+	"hash/fnv"
+	"testing"
+)
+
+func fromHex(s string) []byte {
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
+
+var marshalTests = []struct {
+	name   string
+	new    func() hash.Hash
+	golden []byte
+}{
+	{"adler32", func() hash.Hash { return adler32.New() }, fromHex("61646c01460a789d")},
+	{"crc32", func() hash.Hash { return crc32.NewIEEE() }, fromHex("63726301ca87914dc956d3e8")},
+	{"crc64", func() hash.Hash { return crc64.New(crc64.MakeTable(crc64.ISO)) }, fromHex("6372630273ba8484bbcd5def5d51c83c581695be")},
+	{"fnv32", func() hash.Hash { return fnv.New32() }, fromHex("666e760171ba3d77")},
+	{"fnv32a", func() hash.Hash { return fnv.New32a() }, fromHex("666e76027439f86f")},
+	{"fnv64", func() hash.Hash { return fnv.New64() }, fromHex("666e7603cc64e0e97692c637")},
+	{"fnv64a", func() hash.Hash { return fnv.New64a() }, fromHex("666e7604c522af9b0dede66f")},
+	{"fnv128", func() hash.Hash { return fnv.New128() }, fromHex("666e760561587a70a0f66d7981dc980e2cabbaf7")},
+	{"fnv128a", func() hash.Hash { return fnv.New128a() }, fromHex("666e7606a955802b0136cb67622b461d9f91e6ff")},
+	{"md5", md5.New, fromHex("6d643501a91b0023007aa14740a3979210b5f024c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha1", sha1.New, fromHex("736861016dad5acb4dc003952f7a0b352ee5537ec381a228c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha224", sha256.New224, fromHex("73686102f8b92fc047c9b4d82f01a6370841277b7a0d92108440178c83db855a8e66c2d9c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha256", sha256.New, fromHex("736861032bed68b99987cae48183b2b049d393d0050868e4e8ba3730e9112b08765929b7c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha384", sha512.New384, fromHex("736861046f1664d213dd802f7c47bc50637cf93592570a2b8695839148bf38341c6eacd05326452ef1cbe64d90f1ef73bb5ac7d2803565467d0ddb10c5ee3fc050f9f0c1808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha512_224", sha512.New512_224, fromHex("736861056f1a450ec15af20572d0d1ee6518104d7cbbbe79a038557af5450ed7dbd420b53b7335209e951b4d9aff401f90549b9604fa3d823fbb8581c73582a88aa84022808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha512_256", sha512.New512_256, fromHex("736861067c541f1d1a72536b1f5dad64026bcc7c508f8a2126b51f46f8b9bff63a26fee70980718031e96832e95547f4fe76160ff84076db53b4549b86354af8e17b5116808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+	{"sha512", sha512.New, fromHex("736861078e03953cd57cd6879321270afa70c5827bb5b69be59a8f0130147e94f2aedf7bdc01c56c92343ca8bd837bb7f0208f5a23e155694516b6f147099d491a30b151808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f80000000000000000000000000000f9")},
+}
+
+func TestMarshalHash(t *testing.T) {
+	for _, tt := range marshalTests {
+		t.Run(tt.name, func(t *testing.T) {
+			buf := make([]byte, 256)
+			for i := range buf {
+				buf[i] = byte(i)
+			}
+
+			h := tt.new()
+			h.Write(buf[:256])
+			sum := h.Sum(nil)
+
+			h2 := tt.new()
+			h3 := tt.new()
+			const split = 249
+			for i := 0; i < split; i++ {
+				h2.Write(buf[i : i+1])
+			}
+			h2m, ok := h2.(encoding.BinaryMarshaler)
+			if !ok {
+				t.Fatalf("Hash does not implement MarshalBinary")
+			}
+			enc, err := h2m.MarshalBinary()
+			if err != nil {
+				t.Fatalf("MarshalBinary: %v", err)
+			}
+			if !bytes.Equal(enc, tt.golden) {
+				t.Errorf("MarshalBinary = %x, want %x", enc, tt.golden)
+			}
+			h3u, ok := h3.(encoding.BinaryUnmarshaler)
+			if !ok {
+				t.Fatalf("Hash does not implement UnmarshalBinary")
+			}
+			if err := h3u.UnmarshalBinary(enc); err != nil {
+				t.Fatalf("UnmarshalBinary: %v", err)
+			}
+			h2.Write(buf[split:])
+			h3.Write(buf[split:])
+			sum2 := h2.Sum(nil)
+			sum3 := h3.Sum(nil)
+			if !bytes.Equal(sum2, sum) {
+				t.Fatalf("Sum after MarshalBinary = %x, want %x", sum2, sum)
+			}
+			if !bytes.Equal(sum3, sum) {
+				t.Fatalf("Sum after UnmarshalBinary = %x, want %x", sum3, sum)
+			}
+		})
+	}
+}
diff --git a/src/html/entity.go b/src/html/entity.go
index af8a007..dfeaf6c 100644
--- a/src/html/entity.go
+++ b/src/html/entity.go
@@ -8,7 +8,7 @@
 const longestEntityWithoutSemicolon = 6
 
 // entity is a map from HTML entity names to their values. The semicolon matters:
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/named-character-references.html
+// https://html.spec.whatwg.org/multipage/named-characters.html
 // lists both "amp" and "amp;" as two separate entries.
 //
 // Note that the HTML5 list is larger than the HTML4 list at
diff --git a/src/html/template/attr.go b/src/html/template/attr.go
index 7438f51..92d2789 100644
--- a/src/html/template/attr.go
+++ b/src/html/template/attr.go
@@ -120,6 +120,7 @@
 	"src":         contentTypeURL,
 	"srcdoc":      contentTypeHTML,
 	"srclang":     contentTypePlain,
+	"srcset":      contentTypeSrcset,
 	"start":       contentTypePlain,
 	"step":        contentTypePlain,
 	"style":       contentTypeCSS,
diff --git a/src/html/template/content.go b/src/html/template/content.go
index 2e14bd1..e7cdedc 100644
--- a/src/html/template/content.go
+++ b/src/html/template/content.go
@@ -83,6 +83,14 @@
 	// the encapsulated content should come from a trusted source,
 	// as it will be included verbatim in the template output.
 	URL string
+
+	// Srcset encapsulates a known safe srcset attribute
+	// (see http://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset).
+	//
+	// Use of this type presents a security risk:
+	// the encapsulated content should come from a trusted source,
+	// as it will be included verbatim in the template output.
+	Srcset string
 )
 
 type contentType uint8
@@ -95,6 +103,7 @@
 	contentTypeJS
 	contentTypeJSStr
 	contentTypeURL
+	contentTypeSrcset
 	// contentTypeUnsafe is used in attr.go for values that affect how
 	// embedded content and network messages are formed, vetted,
 	// or interpreted; or which credentials network messages carry.
@@ -156,6 +165,8 @@
 			return string(s), contentTypeJSStr
 		case URL:
 			return string(s), contentTypeURL
+		case Srcset:
+			return string(s), contentTypeSrcset
 		}
 	}
 	for i, arg := range args {
diff --git a/src/html/template/content_test.go b/src/html/template/content_test.go
index 0b4365c..cc092f5 100644
--- a/src/html/template/content_test.go
+++ b/src/html/template/content_test.go
@@ -19,7 +19,9 @@
 		HTMLAttr(` dir="ltr"`),
 		JS(`c && alert("Hello, World!");`),
 		JSStr(`Hello, World & O'Reilly\x21`),
-		URL(`greeting=H%69&addressee=(World)`),
+		URL(`greeting=H%69,&addressee=(World)`),
+		Srcset(`greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`),
+		URL(`,foo/,`),
 	}
 
 	// For each content sensitive escaper, see how it does on
@@ -40,6 +42,8 @@
 				`ZgotmplZ`,
 				`ZgotmplZ`,
 				`ZgotmplZ`,
+				`ZgotmplZ`,
+				`ZgotmplZ`,
 			},
 		},
 		{
@@ -53,6 +57,8 @@
 				`ZgotmplZ`,
 				`ZgotmplZ`,
 				`ZgotmplZ`,
+				`ZgotmplZ`,
+				`ZgotmplZ`,
 			},
 		},
 		{
@@ -65,7 +71,9 @@
 				` dir=&#34;ltr&#34;`,
 				`c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
 				`Hello, World &amp; O&#39;Reilly\x21`,
-				`greeting=H%69&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -79,6 +87,8 @@
 				`ZgotmplZ`,
 				`ZgotmplZ`,
 				`ZgotmplZ`,
+				`ZgotmplZ`,
+				`ZgotmplZ`,
 			},
 		},
 		{
@@ -91,7 +101,9 @@
 				`&#32;dir&#61;&#34;ltr&#34;`,
 				`c&#32;&amp;&amp;&#32;alert(&#34;Hello,&#32;World!&#34;);`,
 				`Hello,&#32;World&#32;&amp;&#32;O&#39;Reilly\x21`,
-				`greeting&#61;H%69&amp;addressee&#61;(World)`,
+				`greeting&#61;H%69,&amp;addressee&#61;(World)`,
+				`greeting&#61;H%69,&amp;addressee&#61;(World)&#32;2x,&#32;https://golang.org/favicon.ico&#32;500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -104,7 +116,9 @@
 				` dir=&#34;ltr&#34;`,
 				`c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
 				`Hello, World &amp; O&#39;Reilly\x21`,
-				`greeting=H%69&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -117,7 +131,9 @@
 				` dir=&#34;ltr&#34;`,
 				`c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
 				`Hello, World &amp; O&#39;Reilly\x21`,
-				`greeting=H%69&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -131,7 +147,9 @@
 				`c && alert("Hello, World!");`,
 				// Escape sequence not over-escaped.
 				`"Hello, World & O'Reilly\x21"`,
-				`"greeting=H%69\u0026addressee=(World)"`,
+				`"greeting=H%69,\u0026addressee=(World)"`,
+				`"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`,
+				`",foo/,"`,
 			},
 		},
 		{
@@ -145,7 +163,9 @@
 				`c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
 				// Escape sequence not over-escaped.
 				`&#34;Hello, World &amp; O&#39;Reilly\x21&#34;`,
-				`&#34;greeting=H%69\u0026addressee=(World)&#34;`,
+				`&#34;greeting=H%69,\u0026addressee=(World)&#34;`,
+				`&#34;greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w&#34;`,
+				`&#34;,foo/,&#34;`,
 			},
 		},
 		{
@@ -158,7 +178,9 @@
 				`c \x26\x26 alert(\x22Hello, World!\x22);`,
 				// Escape sequence not over-escaped.
 				`Hello, World \x26 O\x27Reilly\x21`,
-				`greeting=H%69\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
+				`,foo\/,`,
 			},
 		},
 		{
@@ -171,7 +193,9 @@
 				`c \x26\x26 alert(\x22Hello, World!\x22);`,
 				// Escape sequence not over-escaped.
 				`Hello, World \x26 O\x27Reilly\x21`,
-				`greeting=H%69\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
+				`,foo\/,`,
 			},
 		},
 		{
@@ -185,7 +209,9 @@
 				`c && alert("Hello, World!");`,
 				// Escape sequence not over-escaped.
 				`"Hello, World & O'Reilly\x21"`,
-				`"greeting=H%69\u0026addressee=(World)"`,
+				`"greeting=H%69,\u0026addressee=(World)"`,
+				`"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`,
+				`",foo/,"`,
 			},
 		},
 		{
@@ -199,7 +225,9 @@
 				` dir=&#34;ltr&#34;`,
 				`c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
 				`Hello, World &amp; O&#39;Reilly\x21`,
-				`greeting=H%69&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World)`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -212,7 +240,9 @@
 				`c \x26\x26 alert(\x22Hello, World!\x22);`,
 				// Escape sequence not over-escaped.
 				`Hello, World \x26 O\x27Reilly\x21`,
-				`greeting=H%69\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World)`,
+				`greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
+				`,foo\/,`,
 			},
 		},
 		{
@@ -225,7 +255,9 @@
 				`c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`,
 				`Hello%2c%20World%20%26%20O%27Reilly%5cx21`,
 				// Quotes and parens are escaped but %69 is not over-escaped. HTML escaping is done.
-				`greeting=H%69&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=%28World%29`,
+				`greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`,
+				`,foo/,`,
 			},
 		},
 		{
@@ -238,7 +270,113 @@
 				`c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`,
 				`Hello%2c%20World%20%26%20O%27Reilly%5cx21`,
 				// Quotes and parens are escaped but %69 is not over-escaped. HTML escaping is not done.
-				`greeting=H%69&addressee=%28World%29`,
+				`greeting=H%69,&addressee=%28World%29`,
+				`greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`,
+				`,foo/,`,
+			},
+		},
+		{
+			`<img srcset="{{.}}">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				// Commas are not esacped
+				`Hello,#ZgotmplZ`,
+				// Leading spaces are not percent escapes.
+				` dir=%22ltr%22`,
+				// Spaces after commas are not percent escaped.
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				// Metadata is not escaped.
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset={{.}}>`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				// Spaces are HTML escaped not %-escaped
+				`&#32;dir&#61;%22ltr%22`,
+				`#ZgotmplZ,&#32;World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting&#61;H%69%2c&amp;addressee&#61;%28World%29`,
+				`greeting&#61;H%69,&amp;addressee&#61;(World)&#32;2x,&#32;https://golang.org/favicon.ico&#32;500.5w`,
+				// Commas are escaped.
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset="{{.}} 2x, https://golang.org/ 500.5w">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				` dir=%22ltr%22`,
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset="http://godoc.org/ {{.}}, https://golang.org/ 500.5w">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				` dir=%22ltr%22`,
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset="http://godoc.org/?q={{.}} 2x, https://golang.org/ 500.5w">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				` dir=%22ltr%22`,
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset="http://godoc.org/ 2x, {{.}} 500.5w">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				` dir=%22ltr%22`,
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
+			},
+		},
+		{
+			`<img srcset="http://godoc.org/ 2x, https://golang.org/ {{.}}">`,
+			[]string{
+				`#ZgotmplZ`,
+				`#ZgotmplZ`,
+				`Hello,#ZgotmplZ`,
+				` dir=%22ltr%22`,
+				`#ZgotmplZ, World!%22%29;`,
+				`Hello,#ZgotmplZ`,
+				`greeting=H%69%2c&amp;addressee=%28World%29`,
+				`greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
+				`%2cfoo/%2c`,
 			},
 		},
 	}
diff --git a/src/html/template/context.go b/src/html/template/context.go
index 37a3faf..50730d3 100644
--- a/src/html/template/context.go
+++ b/src/html/template/context.go
@@ -102,6 +102,8 @@
 	stateAttr
 	// stateURL occurs inside an HTML attribute whose content is a URL.
 	stateURL
+	// stateSrcset occurs inside an HTML srcset attribute.
+	stateSrcset
 	// stateJS occurs inside an event handler or script element.
 	stateJS
 	// stateJSDqStr occurs inside a JavaScript double quoted string.
@@ -145,6 +147,7 @@
 	stateRCDATA:      "stateRCDATA",
 	stateAttr:        "stateAttr",
 	stateURL:         "stateURL",
+	stateSrcset:      "stateSrcset",
 	stateJS:          "stateJS",
 	stateJSDqStr:     "stateJSDqStr",
 	stateJSSqStr:     "stateJSSqStr",
@@ -326,6 +329,8 @@
 	attrStyle
 	// attrURL corresponds to an attribute whose value is a URL.
 	attrURL
+	// attrSrcset corresponds to a srcset attribute.
+	attrSrcset
 )
 
 var attrNames = [...]string{
@@ -334,6 +339,7 @@
 	attrScriptType: "attrScriptType",
 	attrStyle:      "attrStyle",
 	attrURL:        "attrURL",
+	attrSrcset:     "attrSrcset",
 }
 
 func (a attr) String() string {
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
index b51a370..5963194 100644
--- a/src/html/template/escape.go
+++ b/src/html/template/escape.go
@@ -71,6 +71,7 @@
 	"_html_template_jsvalescaper":    jsValEscaper,
 	"_html_template_nospaceescaper":  htmlNospaceEscaper,
 	"_html_template_rcdataescaper":   rcdataEscaper,
+	"_html_template_srcsetescaper":   srcsetFilterAndEscaper,
 	"_html_template_urlescaper":      urlEscaper,
 	"_html_template_urlfilter":       urlFilter,
 	"_html_template_urlnormalizer":   urlNormalizer,
@@ -215,6 +216,8 @@
 	case stateAttrName, stateTag:
 		c.state = stateAttrName
 		s = append(s, "_html_template_htmlnamefilter")
+	case stateSrcset:
+		s = append(s, "_html_template_srcsetescaper")
 	default:
 		if isComment(c.state) {
 			s = append(s, "_html_template_commentescaper")
@@ -280,9 +283,22 @@
 	}
 	// Rewrite the pipeline, creating the escapers in s at the end of the pipeline.
 	newCmds := make([]*parse.CommandNode, pipelineLen, pipelineLen+len(s))
-	copy(newCmds, p.Cmds)
+	insertedIdents := make(map[string]bool)
+	for i := 0; i < pipelineLen; i++ {
+		cmd := p.Cmds[i]
+		newCmds[i] = cmd
+		if idNode, ok := cmd.Args[0].(*parse.IdentifierNode); ok {
+			insertedIdents[normalizeEscFn(idNode.Ident)] = true
+		}
+	}
 	for _, name := range s {
-		newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
+		if !insertedIdents[normalizeEscFn(name)] {
+			// When two templates share an underlying parse tree via the use of
+			// AddParseTree and one template is executed after the other, this check
+			// ensures that escapers that were already inserted into the pipeline on
+			// the first escaping pass do not get inserted again.
+			newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
+		}
 	}
 	p.Cmds = newCmds
 }
@@ -317,13 +333,16 @@
 
 // escFnsEq reports whether the two escaping functions are equivalent.
 func escFnsEq(a, b string) bool {
-	if e := equivEscapers[a]; e != "" {
-		a = e
+	return normalizeEscFn(a) == normalizeEscFn(b)
+}
+
+// normalizeEscFn(a) is equal to normalizeEscFn(b) for any pair of names of
+// escaper functions a and b that are equivalent.
+func normalizeEscFn(e string) string {
+	if norm := equivEscapers[e]; norm != "" {
+		return norm
 	}
-	if e := equivEscapers[b]; e != "" {
-		b = e
-	}
-	return a == b
+	return e
 }
 
 // redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x)
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index f5a4ce1..55f808c 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -650,6 +650,12 @@
 			`<{{"script"}}>{{"doEvil()"}}</{{"script"}}>`,
 			`&lt;script>doEvil()&lt;/script>`,
 		},
+		{
+			"srcset bad URL in second position",
+			`<img srcset="{{"/not-an-image#,javascript:alert(1)"}}">`,
+			// The second URL is also filtered.
+			`<img srcset="/not-an-image#,#ZgotmplZ">`,
+		},
 	}
 
 	for _, test := range tests {
@@ -1890,3 +1896,53 @@
 		buf.Reset()
 	}
 }
+
+// Covers issue 22780.
+func TestOrphanedTemplate(t *testing.T) {
+	t1 := Must(New("foo").Parse(`<a href="{{.}}">link1</a>`))
+	t2 := Must(t1.New("foo").Parse(`bar`))
+
+	var b bytes.Buffer
+	const wantError = `template: "foo" is an incomplete or empty template`
+	if err := t1.Execute(&b, "javascript:alert(1)"); err == nil {
+		t.Fatal("expected error executing t1")
+	} else if gotError := err.Error(); gotError != wantError {
+		t.Fatalf("got t1 execution error:\n\t%s\nwant:\n\t%s", gotError, wantError)
+	}
+	b.Reset()
+	if err := t2.Execute(&b, nil); err != nil {
+		t.Fatalf("error executing t2: %s", err)
+	}
+	const want = "bar"
+	if got := b.String(); got != want {
+		t.Fatalf("t2 rendered %q, want %q", got, want)
+	}
+}
+
+// Covers issue 21844.
+func TestAliasedParseTreeDoesNotOverescape(t *testing.T) {
+	const (
+		tmplText = `{{.}}`
+		data     = `<baz>`
+		want     = `&lt;baz&gt;`
+	)
+	// Templates "foo" and "bar" both alias the same underlying parse tree.
+	tpl := Must(New("foo").Parse(tmplText))
+	if _, err := tpl.AddParseTree("bar", tpl.Tree); err != nil {
+		t.Fatalf("AddParseTree error: %v", err)
+	}
+	var b1, b2 bytes.Buffer
+	if err := tpl.ExecuteTemplate(&b1, "foo", data); err != nil {
+		t.Fatalf(`ExecuteTemplate failed for "foo": %v`, err)
+	}
+	if err := tpl.ExecuteTemplate(&b2, "bar", data); err != nil {
+		t.Fatalf(`ExecuteTemplate failed for "foo": %v`, err)
+	}
+	got1, got2 := b1.String(), b2.String()
+	if got1 != want {
+		t.Fatalf(`Template "foo" rendered %q, want %q`, got1, want)
+	}
+	if got1 != got2 {
+		t.Fatalf(`Template "foo" and "bar" rendered %q and %q respectively, expected equal values`, got1, got2)
+	}
+}
diff --git a/src/html/template/template.go b/src/html/template/template.go
index 6a661bf..4641a37 100644
--- a/src/html/template/template.go
+++ b/src/html/template/template.go
@@ -295,6 +295,10 @@
 // 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.
+//
+// If a template with the given name already exists, the new HTML template
+// will replace it. The existing template will be reset and disassociated with
+// t.
 func (t *Template) New(name string) *Template {
 	t.nameSpace.mu.Lock()
 	defer t.nameSpace.mu.Unlock()
@@ -309,6 +313,10 @@
 		nil,
 		t.nameSpace,
 	}
+	if existing, ok := tmpl.set[name]; ok {
+		emptyTmpl := New(existing.Name())
+		*existing = *emptyTmpl
+	}
 	tmpl.set[name] = tmpl
 	return tmpl
 }
diff --git a/src/html/template/transition.go b/src/html/template/transition.go
index df7ac22..c72cf1e 100644
--- a/src/html/template/transition.go
+++ b/src/html/template/transition.go
@@ -23,6 +23,7 @@
 	stateRCDATA:      tSpecialTagEnd,
 	stateAttr:        tAttr,
 	stateURL:         tURL,
+	stateSrcset:      tURL,
 	stateJS:          tJS,
 	stateJSDqStr:     tJSDelimited,
 	stateJSSqStr:     tJSDelimited,
@@ -117,6 +118,8 @@
 			attr = attrStyle
 		case contentTypeJS:
 			attr = attrScript
+		case contentTypeSrcset:
+			attr = attrSrcset
 		}
 	}
 
@@ -161,6 +164,7 @@
 	attrScriptType: stateAttr,
 	attrStyle:      stateCSS,
 	attrURL:        stateURL,
+	attrSrcset:     stateSrcset,
 }
 
 // tBeforeValue is the context transition function for stateBeforeValue.
diff --git a/src/html/template/url.go b/src/html/template/url.go
index 02123b2..69a6ff4 100644
--- a/src/html/template/url.go
+++ b/src/html/template/url.go
@@ -10,22 +10,52 @@
 	"strings"
 )
 
-// urlFilter returns its input unless it contains an unsafe protocol in which
+// urlFilter returns its input unless it contains an unsafe scheme in which
 // case it defangs the entire URL.
+//
+// Schemes that cause unintended side effects that are irreversible without user
+// interaction are considered unsafe. For example, clicking on a "javascript:"
+// link can immediately trigger JavaScript code execution.
+//
+// This filter conservatively assumes that all schemes other than the following
+// are unsafe:
+//    * http:   Navigates to a new website, and may open a new window or tab.
+//              These side effects can be reversed by navigating back to the
+//              previous website, or closing the window or tab. No irreversible
+//              changes will take place without further user interaction with
+//              the new website.
+//    * https:  Same as http.
+//    * mailto: Opens an email program and starts a new draft. This side effect
+//              is not irreversible until the user explicitly clicks send; it
+//              can be undone by closing the email program.
+//
+// To allow URLs containing other schemes to bypass this filter, developers must
+// explicitly indicate that such a URL is expected and safe by encapsulating it
+// in a template.URL value.
 func urlFilter(args ...interface{}) string {
 	s, t := stringify(args...)
 	if t == contentTypeURL {
 		return s
 	}
-	if i := strings.IndexRune(s, ':'); i >= 0 && !strings.ContainsRune(s[:i], '/') {
-		protocol := strings.ToLower(s[:i])
-		if protocol != "http" && protocol != "https" && protocol != "mailto" {
-			return "#" + filterFailsafe
-		}
+	if !isSafeUrl(s) {
+		return "#" + filterFailsafe
 	}
 	return s
 }
 
+// isSafeUrl is true if s is a relative URL or if URL has a protocol in
+// (http, https, mailto).
+func isSafeUrl(s string) bool {
+	if i := strings.IndexRune(s, ':'); i >= 0 && !strings.ContainsRune(s[:i], '/') {
+
+		protocol := s[:i]
+		if !strings.EqualFold(protocol, "http") && !strings.EqualFold(protocol, "https") && !strings.EqualFold(protocol, "mailto") {
+			return false
+		}
+	}
+	return true
+}
+
 // urlEscaper produces an output that can be embedded in a URL query.
 // The output can be embedded in an HTML attribute without further escaping.
 func urlEscaper(args ...interface{}) string {
@@ -49,6 +79,16 @@
 		norm = true
 	}
 	var b bytes.Buffer
+	if processUrlOnto(s, norm, &b) {
+		return b.String()
+	}
+	return s
+}
+
+// processUrlOnto appends a normalized URL corresponding to its input to b
+// and returns true if the appended content differs from s.
+func processUrlOnto(s string, norm bool, b *bytes.Buffer) bool {
+	b.Grow(b.Cap() + len(s) + 16)
 	written := 0
 	// The byte loop below assumes that all URLs use UTF-8 as the
 	// content-encoding. This is similar to the URI to IRI encoding scheme
@@ -94,12 +134,86 @@
 			}
 		}
 		b.WriteString(s[written:i])
-		fmt.Fprintf(&b, "%%%02x", c)
+		fmt.Fprintf(b, "%%%02x", c)
 		written = i + 1
 	}
-	if written == 0 {
-		return s
-	}
 	b.WriteString(s[written:])
+	return written != 0
+}
+
+// Filters and normalizes srcset values which are comma separated
+// URLs followed by metadata.
+func srcsetFilterAndEscaper(args ...interface{}) string {
+	s, t := stringify(args...)
+	switch t {
+	case contentTypeSrcset:
+		return s
+	case contentTypeURL:
+		// Normalizing gets rid of all HTML whitespace
+		// which separate the image URL from its metadata.
+		var b bytes.Buffer
+		if processUrlOnto(s, true, &b) {
+			s = b.String()
+		}
+		// Additionally, commas separate one source from another.
+		return strings.Replace(s, ",", "%2c", -1)
+	}
+
+	var b bytes.Buffer
+	written := 0
+	for i := 0; i < len(s); i++ {
+		if s[i] == ',' {
+			filterSrcsetElement(s, written, i, &b)
+			b.WriteString(",")
+			written = i + 1
+		}
+	}
+	filterSrcsetElement(s, written, len(s), &b)
 	return b.String()
 }
+
+// Derived from https://play.golang.org/p/Dhmj7FORT5
+const htmlSpaceAndAsciiAlnumBytes = "\x00\x36\x00\x00\x01\x00\xff\x03\xfe\xff\xff\x07\xfe\xff\xff\x07"
+
+// isHtmlSpace is true iff c is a whitespace character per
+// https://infra.spec.whatwg.org/#ascii-whitespace
+func isHtmlSpace(c byte) bool {
+	return (c <= 0x20) && 0 != (htmlSpaceAndAsciiAlnumBytes[c>>3]&(1<<uint(c&0x7)))
+}
+
+func isHtmlSpaceOrAsciiAlnum(c byte) bool {
+	return (c < 0x80) && 0 != (htmlSpaceAndAsciiAlnumBytes[c>>3]&(1<<uint(c&0x7)))
+}
+
+func filterSrcsetElement(s string, left int, right int, b *bytes.Buffer) {
+	start := left
+	for start < right && isHtmlSpace(s[start]) {
+		start += 1
+	}
+	end := right
+	for i := start; i < right; i++ {
+		if isHtmlSpace(s[i]) {
+			end = i
+			break
+		}
+	}
+	if url := s[start:end]; isSafeUrl(url) {
+		// If image metadata is only spaces or alnums then
+		// we don't need to URL normalize it.
+		metadataOk := true
+		for i := end; i < right; i++ {
+			if !isHtmlSpaceOrAsciiAlnum(s[i]) {
+				metadataOk = false
+				break
+			}
+		}
+		if metadataOk {
+			b.WriteString(s[left:start])
+			processUrlOnto(url, true, b)
+			b.WriteString(s[end:right])
+			return
+		}
+	}
+	b.WriteString("#")
+	b.WriteString(filterFailsafe)
+}
diff --git a/src/html/template/url_test.go b/src/html/template/url_test.go
index 5182e9d..75c354e 100644
--- a/src/html/template/url_test.go
+++ b/src/html/template/url_test.go
@@ -87,6 +87,51 @@
 	}
 }
 
+func TestSrcsetFilter(t *testing.T) {
+	tests := []struct {
+		name  string
+		input string
+		want  string
+	}{
+		{
+			"one ok",
+			"http://example.com/img.png",
+			"http://example.com/img.png",
+		},
+		{
+			"one ok with metadata",
+			" /img.png 200w",
+			" /img.png 200w",
+		},
+		{
+			"one bad",
+			"javascript:alert(1) 200w",
+			"#ZgotmplZ",
+		},
+		{
+			"two ok",
+			"foo.png, bar.png",
+			"foo.png, bar.png",
+		},
+		{
+			"left bad",
+			"javascript:alert(1), /foo.png",
+			"#ZgotmplZ, /foo.png",
+		},
+		{
+			"right bad",
+			"/bogus#, javascript:alert(1)",
+			"/bogus#,#ZgotmplZ",
+		},
+	}
+
+	for _, test := range tests {
+		if got := srcsetFilterAndEscaper(test.input); got != test.want {
+			t.Errorf("%s: srcsetFilterAndEscaper(%q) want %q != %q", test.name, test.input, test.want, got)
+		}
+	}
+}
+
 func BenchmarkURLEscaper(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		urlEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
@@ -110,3 +155,15 @@
 		urlNormalizer("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
 	}
 }
+
+func BenchmarkSrcsetFilter(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		srcsetFilterAndEscaper(" /foo/bar.png 200w, /baz/boo(1).png")
+	}
+}
+
+func BenchmarkSrcsetFilterNoSpecials(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		srcsetFilterAndEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
+	}
+}
diff --git a/src/image/color/color.go b/src/image/color/color.go
index 0832c59..8895839 100644
--- a/src/image/color/color.go
+++ b/src/image/color/color.go
@@ -200,7 +200,7 @@
 	if a == 0 {
 		return NRGBA{0, 0, 0, 0}
 	}
-	// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
+	// Since Color.RGBA returns an alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
 	r = (r * 0xffff) / a
 	g = (g * 0xffff) / a
 	b = (b * 0xffff) / a
@@ -218,7 +218,7 @@
 	if a == 0 {
 		return NRGBA64{0, 0, 0, 0}
 	}
-	// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
+	// Since Color.RGBA returns an alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
 	r = (r * 0xffff) / a
 	g = (g * 0xffff) / a
 	b = (b * 0xffff) / a
@@ -312,12 +312,29 @@
 //
 // x and y are both assumed to be in the range [0, 0xffff].
 func sqDiff(x, y uint32) uint32 {
-	var d uint32
-	if x > y {
-		d = x - y
-	} else {
-		d = y - x
-	}
+	// The canonical code of this function looks as follows:
+	//
+	//	var d uint32
+	//	if x > y {
+	//		d = x - y
+	//	} else {
+	//		d = y - x
+	//	}
+	//	return (d * d) >> 2
+	//
+	// Language spec guarantees the following properties of unsigned integer
+	// values operations with respect to overflow/wrap around:
+	//
+	// > For unsigned integer values, the operations +, -, *, and << are
+	// > computed modulo 2n, where n is the bit width of the unsigned
+	// > integer's type. Loosely speaking, these unsigned integer operations
+	// > discard high bits upon overflow, and programs may rely on ``wrap
+	// > around''.
+	//
+	// Considering these properties and the fact that this function is
+	// called in the hot paths (x,y loops), it is reduced to the below code
+	// which is slightly faster. See TestSqDiff for correctness check.
+	d := x - y
 	return (d * d) >> 2
 }
 
diff --git a/src/image/color/color_test.go b/src/image/color/color_test.go
new file mode 100644
index 0000000..ea66b7b
--- /dev/null
+++ b/src/image/color/color_test.go
@@ -0,0 +1,47 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package color
+
+import (
+	"testing"
+	"testing/quick"
+)
+
+func TestSqDiff(t *testing.T) {
+	// canonical sqDiff implementation
+	orig := func(x, y uint32) uint32 {
+		var d uint32
+		if x > y {
+			d = uint32(x - y)
+		} else {
+			d = uint32(y - x)
+		}
+		return (d * d) >> 2
+	}
+	testCases := []uint32{
+		0,
+		1,
+		2,
+		0x0fffd,
+		0x0fffe,
+		0x0ffff,
+		0x10000,
+		0x10001,
+		0x10002,
+		0xfffffffd,
+		0xfffffffe,
+		0xffffffff,
+	}
+	for _, x := range testCases {
+		for _, y := range testCases {
+			if got, want := sqDiff(x, y), orig(x, y); got != want {
+				t.Fatalf("sqDiff(%#x, %#x): got %d, want %d", x, y, got, want)
+			}
+		}
+	}
+	if err := quick.CheckEqual(orig, sqDiff, &quick.Config{MaxCountScale: 10}); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/src/image/draw/draw.go b/src/image/draw/draw.go
index a31dd42..977d7c5 100644
--- a/src/image/draw/draw.go
+++ b/src/image/draw/draw.go
@@ -564,12 +564,10 @@
 //
 // x and y are both assumed to be in the range [0, 0xffff].
 func sqDiff(x, y int32) uint32 {
-	var d uint32
-	if x > y {
-		d = uint32(x - y)
-	} else {
-		d = uint32(y - x)
-	}
+	// This is an optimized code relying on the overflow/wrap around
+	// properties of unsigned integers operations guaranteed by the language
+	// spec. See sqDiff from the image/color package for more details.
+	d := uint32(x - y)
 	return (d * d) >> 2
 }
 
@@ -603,6 +601,18 @@
 		quantErrorCurr = make([][4]int32, r.Dx()+2)
 		quantErrorNext = make([][4]int32, r.Dx()+2)
 	}
+	pxRGBA := func(x, y int) (r, g, b, a uint32) { return src.At(x, y).RGBA() }
+	// Fast paths for special cases to avoid excessive use of the color.Color
+	// interface which escapes to the heap but need to be discovered for
+	// each pixel on r. See also https://golang.org/issues/15759.
+	switch src0 := src.(type) {
+	case *image.RGBA:
+		pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.RGBAAt(x, y).RGBA() }
+	case *image.NRGBA:
+		pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.NRGBAAt(x, y).RGBA() }
+	case *image.YCbCr:
+		pxRGBA = func(x, y int) (r, g, b, a uint32) { return src0.YCbCrAt(x, y).RGBA() }
+	}
 
 	// Loop over each source pixel.
 	out := color.RGBA64{A: 0xffff}
@@ -610,7 +620,7 @@
 		for x := 0; x != r.Dx(); x++ {
 			// er, eg and eb are the pixel's R,G,B values plus the
 			// optional Floyd-Steinberg error.
-			sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
+			sr, sg, sb, sa := pxRGBA(sp.X+x, sp.Y+y)
 			er, eg, eb, ea := int32(sr), int32(sg), int32(sb), int32(sa)
 			if floydSteinberg {
 				er = clamp(er + quantErrorCurr[x+1][0]/16)
diff --git a/src/image/draw/draw_test.go b/src/image/draw/draw_test.go
index a58f0f4..dea51b6 100644
--- a/src/image/draw/draw_test.go
+++ b/src/image/draw/draw_test.go
@@ -10,6 +10,7 @@
 	"image/png"
 	"os"
 	"testing"
+	"testing/quick"
 )
 
 func eq(c0, c1 color.Color) bool {
@@ -467,3 +468,47 @@
 		}
 	}
 }
+
+func TestSqDiff(t *testing.T) {
+	// This test is similar to the one from the image/color package, but
+	// sqDiff in this package accepts int32 instead of uint32, so test it
+	// for appropriate input.
+
+	// canonical sqDiff implementation
+	orig := func(x, y int32) uint32 {
+		var d uint32
+		if x > y {
+			d = uint32(x - y)
+		} else {
+			d = uint32(y - x)
+		}
+		return (d * d) >> 2
+	}
+	testCases := []int32{
+		0,
+		1,
+		2,
+		0x0fffd,
+		0x0fffe,
+		0x0ffff,
+		0x10000,
+		0x10001,
+		0x10002,
+		0x7ffffffd,
+		0x7ffffffe,
+		0x7fffffff,
+		-0x7ffffffd,
+		-0x7ffffffe,
+		-0x80000000,
+	}
+	for _, x := range testCases {
+		for _, y := range testCases {
+			if got, want := sqDiff(x, y), orig(x, y); got != want {
+				t.Fatalf("sqDiff(%#x, %#x): got %d, want %d", x, y, got, want)
+			}
+		}
+	}
+	if err := quick.CheckEqual(orig, sqDiff, &quick.Config{MaxCountScale: 10}); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
index b1335e6..c1c9562 100644
--- a/src/image/gif/reader.go
+++ b/src/image/gif/reader.go
@@ -109,48 +109,114 @@
 	tmp      [1024]byte // must be at least 768 so we can read color table
 }
 
-// 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.
+// 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.
+//
+// To avoid the allocation of a bufio.Reader for the lzw Reader, blockReader
+// implements io.ReadByte and buffers blocks into the decoder's "tmp" buffer.
 type blockReader struct {
-	r     reader
-	slice []byte
-	err   error
-	tmp   [256]byte
+	d    *decoder
+	i, j uint8 // d.tmp[i:j] contains the buffered bytes
+	err  error
 }
 
-func (b *blockReader) Read(p []byte) (int, error) {
+func (b *blockReader) fill() {
 	if b.err != nil {
-		return 0, b.err
+		return
 	}
-	if len(p) == 0 {
-		return 0, nil
+	b.j, b.err = readByte(b.d.r)
+	if b.j == 0 && b.err == nil {
+		b.err = io.EOF
 	}
-	if len(b.slice) == 0 {
-		var blockLen uint8
-		blockLen, b.err = b.r.ReadByte()
+	if b.err != nil {
+		return
+	}
+
+	b.i = 0
+	b.err = readFull(b.d.r, b.d.tmp[:b.j])
+	if b.err != nil {
+		b.j = 0
+	}
+}
+
+func (b *blockReader) ReadByte() (byte, error) {
+	if b.i == b.j {
+		b.fill()
 		if b.err != nil {
 			return 0, b.err
 		}
-		if blockLen == 0 {
-			b.err = io.EOF
-			return 0, b.err
-		}
-		b.slice = b.tmp[:blockLen]
-		if b.err = readFull(b.r, b.slice); b.err != nil {
+	}
+
+	c := b.d.tmp[b.i]
+	b.i++
+	return c, nil
+}
+
+// blockReader must implement io.Reader, but its Read shouldn't ever actually
+// be called in practice. The compress/lzw package will only call ReadByte.
+func (b *blockReader) Read(p []byte) (int, error) {
+	if len(p) == 0 || b.err != nil {
+		return 0, b.err
+	}
+	if b.i == b.j {
+		b.fill()
+		if b.err != nil {
 			return 0, b.err
 		}
 	}
-	n := copy(p, b.slice)
-	b.slice = b.slice[n:]
+
+	n := copy(p, b.d.tmp[b.i:b.j])
+	b.i += uint8(n)
 	return n, nil
 }
 
+// close primarily detects whether or not a block terminator was encountered
+// after reading a sequence of data sub-blocks. It allows at most one trailing
+// sub-block worth of data. I.e., if some number of bytes exist in one sub-block
+// following the end of LZW data, the very next sub-block must be the block
+// terminator. If the very end of LZW data happened to fill one sub-block, at
+// most one more sub-block of length 1 may exist before the block-terminator.
+// These accomodations allow us to support GIFs created by less strict encoders.
+// See https://golang.org/issue/16146.
+func (b *blockReader) close() error {
+	if b.err == io.EOF {
+		// A clean block-sequence terminator was encountered while reading.
+		return nil
+	} else if b.err != nil {
+		// Some other error was encountered while reading.
+		return b.err
+	}
+
+	if b.i == b.j {
+		// We reached the end of a sub block reading LZW data. We'll allow at
+		// most one more sub block of data with a length of 1 byte.
+		b.fill()
+		if b.err == io.EOF {
+			return nil
+		} else if b.err != nil {
+			return b.err
+		} else if b.j > 1 {
+			return errTooMuch
+		}
+	}
+
+	// Part of a sub-block remains buffered. We expect that the next attempt to
+	// buffer a sub-block will reach the block terminator.
+	b.fill()
+	if b.err == io.EOF {
+		return nil
+	} else if b.err != nil {
+		return b.err
+	}
+
+	return errTooMuch
+}
+
 // decode reads a GIF image from r and stores the result in d.
-func (d *decoder) decode(r io.Reader, configOnly bool) error {
+func (d *decoder) decode(r io.Reader, configOnly, keepAllFrames bool) error {
 	// Add buffering if r does not provide ReadByte.
 	if rr, ok := r.(reader); ok {
 		d.r = rr
@@ -178,115 +244,9 @@
 			}
 
 		case sImageDescriptor:
-			m, err := d.newImageFromDescriptor()
-			if err != nil {
+			if err = d.readImageDescriptor(keepAllFrames); err != nil {
 				return err
 			}
-			useLocalColorTable := d.imageFields&fColorTable != 0
-			if useLocalColorTable {
-				m.Palette, err = d.readColorTable(d.imageFields)
-				if err != nil {
-					return err
-				}
-			} else {
-				if d.globalColorTable == nil {
-					return errors.New("gif: no color table")
-				}
-				m.Palette = d.globalColorTable
-			}
-			if d.hasTransparentIndex {
-				if !useLocalColorTable {
-					// Clone the global color table.
-					m.Palette = append(color.Palette(nil), d.globalColorTable...)
-				}
-				if ti := int(d.transparentIndex); ti < len(m.Palette) {
-					m.Palette[ti] = color.RGBA{}
-				} else {
-					// The transparentIndex is out of range, which is an error
-					// according to the spec, but Firefox and Google Chrome
-					// seem OK with this, so we enlarge the palette with
-					// transparent colors. See golang.org/issue/15059.
-					p := make(color.Palette, ti+1)
-					copy(p, m.Palette)
-					for i := len(m.Palette); i < len(p); i++ {
-						p[i] = color.RGBA{}
-					}
-					m.Palette = p
-				}
-			}
-			litWidth, err := readByte(d.r)
-			if err != nil {
-				return fmt.Errorf("gif: reading image data: %v", 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 = readFull(lzwr, m.Pix); err != nil {
-				if err != io.ErrUnexpectedEOF {
-					return fmt.Errorf("gif: reading image data: %v", err)
-				}
-				return errNotEnough
-			}
-			// In theory, both lzwr and br should be exhausted. Reading from them
-			// should yield (0, io.EOF).
-			//
-			// The spec (Appendix F - Compression), says that "An End of
-			// Information code... must be the last code output by the encoder
-			// for an image". In practice, though, giflib (a widely used C
-			// library) does not enforce this, so we also accept lzwr returning
-			// io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF
-			// before the LZW decoder saw an explicit end code), provided that
-			// the io.ReadFull call above successfully read len(m.Pix) bytes.
-			// See https://golang.org/issue/9856 for an example GIF.
-			if n, err := lzwr.Read(d.tmp[:1]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) {
-				if err != nil {
-					return fmt.Errorf("gif: reading image data: %v", err)
-				}
-				return errTooMuch
-			}
-
-			// In practice, some GIFs have an extra byte in the data sub-block
-			// stream, which we ignore. See https://golang.org/issue/16146.
-			for nExtraBytes := 0; ; {
-				n, err := br.Read(d.tmp[:2])
-				nExtraBytes += n
-				if nExtraBytes > 1 {
-					return errTooMuch
-				}
-				if err == io.EOF {
-					break
-				}
-				if err != nil {
-					return fmt.Errorf("gif: reading image data: %v", err)
-				}
-			}
-
-			// 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&fInterlace != 0 {
-				uninterlace(m)
-			}
-
-			d.image = append(d.image, m)
-			d.delay = append(d.delay, d.delayTime)
-			d.disposal = append(d.disposal, d.disposalMethod)
-			// 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 {
@@ -410,6 +370,113 @@
 	return nil
 }
 
+func (d *decoder) readImageDescriptor(keepAllFrames bool) error {
+	m, err := d.newImageFromDescriptor()
+	if err != nil {
+		return err
+	}
+	useLocalColorTable := d.imageFields&fColorTable != 0
+	if useLocalColorTable {
+		m.Palette, err = d.readColorTable(d.imageFields)
+		if err != nil {
+			return err
+		}
+	} else {
+		if d.globalColorTable == nil {
+			return errors.New("gif: no color table")
+		}
+		m.Palette = d.globalColorTable
+	}
+	if d.hasTransparentIndex {
+		if !useLocalColorTable {
+			// Clone the global color table.
+			m.Palette = append(color.Palette(nil), d.globalColorTable...)
+		}
+		if ti := int(d.transparentIndex); ti < len(m.Palette) {
+			m.Palette[ti] = color.RGBA{}
+		} else {
+			// The transparentIndex is out of range, which is an error
+			// according to the spec, but Firefox and Google Chrome
+			// seem OK with this, so we enlarge the palette with
+			// transparent colors. See golang.org/issue/15059.
+			p := make(color.Palette, ti+1)
+			copy(p, m.Palette)
+			for i := len(m.Palette); i < len(p); i++ {
+				p[i] = color.RGBA{}
+			}
+			m.Palette = p
+		}
+	}
+	litWidth, err := readByte(d.r)
+	if err != nil {
+		return fmt.Errorf("gif: reading image data: %v", 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{d: d}
+	lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth))
+	defer lzwr.Close()
+	if err = readFull(lzwr, m.Pix); err != nil {
+		if err != io.ErrUnexpectedEOF {
+			return fmt.Errorf("gif: reading image data: %v", err)
+		}
+		return errNotEnough
+	}
+	// In theory, both lzwr and br should be exhausted. Reading from them
+	// should yield (0, io.EOF).
+	//
+	// The spec (Appendix F - Compression), says that "An End of
+	// Information code... must be the last code output by the encoder
+	// for an image". In practice, though, giflib (a widely used C
+	// library) does not enforce this, so we also accept lzwr returning
+	// io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF
+	// before the LZW decoder saw an explicit end code), provided that
+	// the io.ReadFull call above successfully read len(m.Pix) bytes.
+	// See https://golang.org/issue/9856 for an example GIF.
+	if n, err := lzwr.Read(d.tmp[256:257]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) {
+		if err != nil {
+			return fmt.Errorf("gif: reading image data: %v", err)
+		}
+		return errTooMuch
+	}
+
+	// In practice, some GIFs have an extra byte in the data sub-block
+	// stream, which we ignore. See https://golang.org/issue/16146.
+	if err := br.close(); err == errTooMuch {
+		return errTooMuch
+	} else if err != nil {
+		return fmt.Errorf("gif: reading image data: %v", err)
+	}
+
+	// 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&fInterlace != 0 {
+		uninterlace(m)
+	}
+
+	if keepAllFrames || len(d.image) == 0 {
+		d.image = append(d.image, m)
+		d.delay = append(d.delay, d.delayTime)
+		d.disposal = append(d.disposal, d.disposalMethod)
+	}
+	// 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
+	return nil
+}
+
 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
 	if err := readFull(d.r, d.tmp[:9]); err != nil {
 		return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
@@ -491,7 +558,7 @@
 // image as an image.Image.
 func Decode(r io.Reader) (image.Image, error) {
 	var d decoder
-	if err := d.decode(r, false); err != nil {
+	if err := d.decode(r, false, false); err != nil {
 		return nil, err
 	}
 	return d.image[0], nil
@@ -526,7 +593,7 @@
 // and timing information.
 func DecodeAll(r io.Reader) (*GIF, error) {
 	var d decoder
-	if err := d.decode(r, false); err != nil {
+	if err := d.decode(r, false, true); err != nil {
 		return nil, err
 	}
 	gif := &GIF{
@@ -548,7 +615,7 @@
 // without decoding the entire image.
 func DecodeConfig(r io.Reader) (image.Config, error) {
 	var d decoder
-	if err := d.decode(r, true); err != nil {
+	if err := d.decode(r, true, false); err != nil {
 		return image.Config{}, err
 	}
 	return image.Config{
diff --git a/src/image/gif/reader_test.go b/src/image/gif/reader_test.go
index 51c64b7..220e8f5 100644
--- a/src/image/gif/reader_test.go
+++ b/src/image/gif/reader_test.go
@@ -9,7 +9,12 @@
 	"compress/lzw"
 	"image"
 	"image/color"
+	"image/color/palette"
+	"io"
+	"io/ioutil"
 	"reflect"
+	"runtime"
+	"runtime/debug"
 	"strings"
 	"testing"
 )
@@ -23,6 +28,9 @@
 	trailerStr = "\x3b"
 )
 
+// lzw.NewReader wants a io.ByteReader, this ensures we're compatible.
+var _ io.ByteReader = (*blockReader)(nil)
+
 // lzwEncode returns an LZW encoding (with 2-bit literals) of in.
 func lzwEncode(in []byte) []byte {
 	b := &bytes.Buffer{}
@@ -66,6 +74,9 @@
 		{2, 1, 0, nil},
 		// Two extra bytes after LZW data, but inside the same data sub-block.
 		{2, 2, 0, nil},
+		// Extra data exists in the final sub-block with LZW data, AND there is
+		// a bogus sub-block following.
+		{2, 1, 1, errTooMuch},
 	}
 	for _, tc := range testCases {
 		b := &bytes.Buffer{}
@@ -342,3 +353,50 @@
 		}
 	}
 }
+
+// See golang.org/issue/22237
+func TestDecodeMemoryConsumption(t *testing.T) {
+	const frames = 3000
+	img := image.NewPaletted(image.Rectangle{Max: image.Point{1, 1}}, palette.WebSafe)
+	hugeGIF := &GIF{
+		Image:    make([]*image.Paletted, frames),
+		Delay:    make([]int, frames),
+		Disposal: make([]byte, frames),
+	}
+	for i := 0; i < frames; i++ {
+		hugeGIF.Image[i] = img
+		hugeGIF.Delay[i] = 60
+	}
+	buf := new(bytes.Buffer)
+	if err := EncodeAll(buf, hugeGIF); err != nil {
+		t.Fatal("EncodeAll:", err)
+	}
+	s0, s1 := new(runtime.MemStats), new(runtime.MemStats)
+	runtime.GC()
+	defer debug.SetGCPercent(debug.SetGCPercent(5))
+	runtime.ReadMemStats(s0)
+	if _, err := Decode(buf); err != nil {
+		t.Fatal("Decode:", err)
+	}
+	runtime.ReadMemStats(s1)
+	if heapDiff := int64(s1.HeapAlloc - s0.HeapAlloc); heapDiff > 30<<20 {
+		t.Fatalf("Decode of %d frames increased heap by %dMB", frames, heapDiff>>20)
+	}
+}
+
+func BenchmarkDecode(b *testing.B) {
+	data, err := ioutil.ReadFile("../testdata/video-001.gif")
+	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))
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		Decode(bytes.NewReader(data))
+	}
+}
diff --git a/src/image/gif/writer.go b/src/image/gif/writer.go
index 493c754..f26af8b 100644
--- a/src/image/gif/writer.go
+++ b/src/image/gif/writer.go
@@ -70,25 +70,54 @@
 	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)
+func (b blockWriter) setup() {
+	b.e.buf[0] = 0
+}
 
-		_, b.e.err = b.e.w.Write(b.e.buf[:n+1])
-		if b.e.err != nil {
-			return 0, b.e.err
+func (b blockWriter) Flush() error {
+	return b.e.err
+}
+
+func (b blockWriter) WriteByte(c byte) error {
+	if b.e.err != nil {
+		return b.e.err
+	}
+
+	// Append c to buffered sub-block.
+	b.e.buf[0]++
+	b.e.buf[b.e.buf[0]] = c
+	if b.e.buf[0] < 255 {
+		return nil
+	}
+
+	// Flush block
+	b.e.write(b.e.buf[:256])
+	b.e.buf[0] = 0
+	return b.e.err
+}
+
+// blockWriter must be an io.Writer for lzw.NewWriter, but this is never
+// actually called.
+func (b blockWriter) Write(data []byte) (int, error) {
+	for i, c := range data {
+		if err := b.WriteByte(c); err != nil {
+			return i, err
 		}
 	}
-	return total, b.e.err
+	return len(data), nil
+}
+
+func (b blockWriter) close() {
+	// Write the block terminator (0x00), either by itself, or along with a
+	// pending sub-block.
+	if b.e.buf[0] == 0 {
+		b.e.writeByte(0)
+	} else {
+		n := uint(b.e.buf[0])
+		b.e.buf[n+1] = 0
+		b.e.write(b.e.buf[:n+2])
+	}
+	b.e.flush()
 }
 
 func (e *encoder) flush() {
@@ -171,27 +200,44 @@
 	if uint(size) >= uint(len(log2Lookup)) {
 		return 0, errors.New("gif: cannot encode color table with more than 256 entries")
 	}
-	n := log2Lookup[size]
-	for i := 0; i < n; i++ {
-		if i < len(p) {
-			c := p[i]
-			if c == nil {
-				return 0, errors.New("gif: cannot encode color table with nil entries")
-			}
-			r, g, b, _ := c.RGBA()
-			dst[3*i+0] = uint8(r >> 8)
-			dst[3*i+1] = uint8(g >> 8)
-			dst[3*i+2] = uint8(b >> 8)
+	for i, c := range p {
+		if c == nil {
+			return 0, errors.New("gif: cannot encode color table with nil entries")
+		}
+		var r, g, b uint8
+		// It is most likely that the palette is full of color.RGBAs, so they
+		// get a fast path.
+		if rgba, ok := c.(color.RGBA); ok {
+			r, g, b = rgba.R, rgba.G, rgba.B
 		} else {
-			// Pad with black.
-			dst[3*i+0] = 0x00
-			dst[3*i+1] = 0x00
-			dst[3*i+2] = 0x00
+			rr, gg, bb, _ := c.RGBA()
+			r, g, b = uint8(rr>>8), uint8(gg>>8), uint8(bb>>8)
+		}
+		dst[3*i+0] = r
+		dst[3*i+1] = g
+		dst[3*i+2] = b
+	}
+	n := log2Lookup[size]
+	if n > len(p) {
+		// Pad with black.
+		fill := dst[3*len(p) : 3*n]
+		for i := range fill {
+			fill[i] = 0
 		}
 	}
 	return 3 * n, nil
 }
 
+func (e *encoder) colorTablesMatch(localLen, transparentIndex int) bool {
+	localSize := 3 * localLen
+	if transparentIndex >= 0 {
+		trOff := 3 * transparentIndex
+		return bytes.Equal(e.globalColorTable[:trOff], e.localColorTable[:trOff]) &&
+			bytes.Equal(e.globalColorTable[trOff+3:localSize], e.localColorTable[trOff+3:localSize])
+	}
+	return bytes.Equal(e.globalColorTable[:localSize], e.localColorTable[:localSize])
+}
+
 func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte) {
 	if e.err != nil {
 		return
@@ -251,19 +297,31 @@
 	writeUint16(e.buf[7:9], uint16(b.Dy()))
 	e.write(e.buf[:9])
 
+	// To determine whether or not this frame's palette is the same as the
+	// global palette, we can check a couple things. First, do they actually
+	// point to the same []color.Color? If so, they are equal so long as the
+	// frame's palette is not longer than the global palette...
 	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
-	if ct, err := encodeColorTable(e.localColorTable[:], pm.Palette, paddedSize); err != nil {
-		if e.err == nil {
-			e.err = err
-		}
-		return
-	} else if ct != e.globalCT || !bytes.Equal(e.globalColorTable[:ct], e.localColorTable[:ct]) {
-		// Use a local color table.
-		e.writeByte(fColorTable | uint8(paddedSize))
-		e.write(e.localColorTable[:ct])
+	if gp, ok := e.g.Config.ColorModel.(color.Palette); ok && len(pm.Palette) <= len(gp) && &gp[0] == &pm.Palette[0] {
+		e.writeByte(0) // Use the global color table.
 	} else {
-		// Use the global color table.
-		e.writeByte(0)
+		ct, err := encodeColorTable(e.localColorTable[:], pm.Palette, paddedSize)
+		if err != nil {
+			if e.err == nil {
+				e.err = err
+			}
+			return
+		}
+		// This frame's palette is not the very same slice as the global
+		// palette, but it might be a copy, possibly with one value turned into
+		// transparency by DecodeAll.
+		if ct <= e.globalCT && e.colorTablesMatch(len(pm.Palette), transparentIndex) {
+			e.writeByte(0) // Use the global color table.
+		} else {
+			// Use a local color table.
+			e.writeByte(fColorTable | uint8(paddedSize))
+			e.write(e.localColorTable[:ct])
+		}
 	}
 
 	litWidth := paddedSize + 1
@@ -272,7 +330,9 @@
 	}
 	e.writeByte(uint8(litWidth)) // LZW Minimum Code Size.
 
-	lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
+	bw := blockWriter{e: e}
+	bw.setup()
+	lzww := lzw.NewWriter(bw, lzw.LSB, litWidth)
 	if dx := b.Dx(); dx == pm.Stride {
 		_, e.err = lzww.Write(pm.Pix[:dx*b.Dy()])
 		if e.err != nil {
@@ -288,8 +348,8 @@
 			}
 		}
 	}
-	lzww.Close()
-	e.writeByte(0x00) // Block Terminator.
+	lzww.Close() // flush to bw
+	bw.close()   // flush to e.w
 }
 
 // Options are the encoding parameters.
diff --git a/src/image/gif/writer_test.go b/src/image/gif/writer_test.go
index 1bba9b8..69042ec 100644
--- a/src/image/gif/writer_test.go
+++ b/src/image/gif/writer_test.go
@@ -64,6 +64,10 @@
 	return sum / n
 }
 
+// lzw.NewWriter wants an interface which is basically the same thing as gif's
+// writer interface.  This ensures we're compatible.
+var _ writer = blockWriter{}
+
 var testCase = []struct {
 	filename  string
 	tolerance int64
@@ -471,6 +475,35 @@
 	}
 }
 
+func TestColorTablesMatch(t *testing.T) {
+	const trIdx = 100
+	global := color.Palette(palette.Plan9)
+	if rgb := global[trIdx].(color.RGBA); rgb.R == 0 && rgb.G == 0 && rgb.B == 0 {
+		t.Fatalf("trIdx (%d) is already black", trIdx)
+	}
+
+	// Make a copy of the palette, substituting trIdx's slot with transparent,
+	// just like decoder.decode.
+	local := append(color.Palette(nil), global...)
+	local[trIdx] = color.RGBA{}
+
+	const testLen = 3 * 256
+	const padded = 7
+	e := new(encoder)
+	if l, err := encodeColorTable(e.globalColorTable[:], global, padded); err != nil || l != testLen {
+		t.Fatalf("Failed to encode global color table: got %d, %v; want nil, %d", l, err, testLen)
+	}
+	if l, err := encodeColorTable(e.localColorTable[:], local, padded); err != nil || l != testLen {
+		t.Fatalf("Failed to encode local color table: got %d, %v; want nil, %d", l, err, testLen)
+	}
+	if bytes.Equal(e.globalColorTable[:testLen], e.localColorTable[:testLen]) {
+		t.Fatal("Encoded color tables are equal, expected mismatch")
+	}
+	if !e.colorTablesMatch(len(local), trIdx) {
+		t.Fatal("colorTablesMatch() == false, expected true")
+	}
+}
+
 func TestEncodeCroppedSubImages(t *testing.T) {
 	// This test means to ensure that Encode honors the Bounds and Strides of
 	// images correctly when encoding.
@@ -500,8 +533,6 @@
 }
 
 func BenchmarkEncode(b *testing.B) {
-	b.StopTimer()
-
 	bo := image.Rect(0, 0, 640, 480)
 	rnd := rand.New(rand.NewSource(123))
 
@@ -523,14 +554,14 @@
 	}
 
 	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	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))
@@ -545,7 +576,8 @@
 		}
 	}
 	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Encode(ioutil.Discard, img, nil)
 	}
diff --git a/src/image/jpeg/reader_test.go b/src/image/jpeg/reader_test.go
index 7737615..a62b509 100644
--- a/src/image/jpeg/reader_test.go
+++ b/src/image/jpeg/reader_test.go
@@ -323,7 +323,6 @@
 }
 
 func benchmarkDecode(b *testing.B, filename string) {
-	b.StopTimer()
 	data, err := ioutil.ReadFile(filename)
 	if err != nil {
 		b.Fatal(err)
@@ -333,7 +332,8 @@
 		b.Fatal(err)
 	}
 	b.SetBytes(int64(cfg.Width * cfg.Height * 4))
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Decode(bytes.NewReader(data))
 	}
diff --git a/src/image/jpeg/writer_test.go b/src/image/jpeg/writer_test.go
index a6c0561..3aff742 100644
--- a/src/image/jpeg/writer_test.go
+++ b/src/image/jpeg/writer_test.go
@@ -243,7 +243,6 @@
 }
 
 func BenchmarkEncodeRGBA(b *testing.B) {
-	b.StopTimer()
 	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
 	bo := img.Bounds()
 	rnd := rand.New(rand.NewSource(123))
@@ -258,7 +257,8 @@
 		}
 	}
 	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	options := &Options{Quality: 90}
 	for i := 0; i < b.N; i++ {
 		Encode(ioutil.Discard, img, options)
@@ -266,7 +266,6 @@
 }
 
 func BenchmarkEncodeYCbCr(b *testing.B) {
-	b.StopTimer()
 	img := image.NewYCbCr(image.Rect(0, 0, 640, 480), image.YCbCrSubsampleRatio420)
 	bo := img.Bounds()
 	rnd := rand.New(rand.NewSource(123))
@@ -280,7 +279,8 @@
 		}
 	}
 	b.SetBytes(640 * 480 * 3)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	options := &Options{Quality: 90}
 	for i := 0; i < b.N; i++ {
 		Encode(ioutil.Discard, img, options)
diff --git a/src/image/png/reader.go b/src/image/png/reader.go
index 4f043a0..4fbcef8 100644
--- a/src/image/png/reader.go
+++ b/src/image/png/reader.go
@@ -157,6 +157,7 @@
 		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 {
@@ -166,6 +167,11 @@
 	if nPixels != int64(int(nPixels)) {
 		return UnsupportedError("dimension overflow")
 	}
+	// There can be up to 8 bytes per pixel, for 16 bits per channel RGBA.
+	if nPixels != (nPixels*8)/8 {
+		return UnsupportedError("dimension overflow")
+	}
+
 	d.cb = cbInvalid
 	d.depth = int(d.tmp[8])
 	switch d.depth {
diff --git a/src/image/png/reader_test.go b/src/image/png/reader_test.go
index cabf533..66bcfcb 100644
--- a/src/image/png/reader_test.go
+++ b/src/image/png/reader_test.go
@@ -589,7 +589,7 @@
 }
 
 func TestGray8Transparent(t *testing.T) {
-	// These bytes come from https://github.com/golang/go/issues/19553
+	// These bytes come from https://golang.org/issues/19553
 	m, err := Decode(bytes.NewReader([]byte{
 		0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
 		0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x85, 0x2c, 0x88,
@@ -649,21 +649,38 @@
 	}
 }
 
+func TestDimensionOverflow(t *testing.T) {
+	// These bytes come from https://golang.org/issues/22304
+	//
+	// It encodes a 2147483646 × 2147483646 (i.e. 0x7ffffffe × 0x7ffffffe)
+	// NRGBA image. The (width × height) per se doesn't overflow an int64, but
+	// (width × height × bytesPerPixel) will.
+	_, err := Decode(bytes.NewReader([]byte{
+		0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+		0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x08, 0x06, 0x00, 0x00, 0x00, 0x30, 0x57, 0xb3,
+		0xfd, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x62, 0x20, 0x12, 0x8c,
+		0x2a, 0xa4, 0xb3, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x38, 0x00, 0x15, 0x2d, 0xef,
+		0x5f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+	}))
+	if _, ok := err.(UnsupportedError); !ok {
+		t.Fatalf("Decode: got %v (of type %T), want non-nil error (of type png.UnsupportedError)", err, err)
+	}
+}
+
 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))
+	cfg, err := DecodeConfig(bytes.NewReader(data))
 	if err != nil {
 		b.Fatal(err)
 	}
 	b.SetBytes(int64(cfg.Width * cfg.Height * bytesPerPixel))
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		Decode(strings.NewReader(s))
+		Decode(bytes.NewReader(data))
 	}
 }
 
diff --git a/src/image/png/writer_test.go b/src/image/png/writer_test.go
index b1f97b1..1107ea0 100644
--- a/src/image/png/writer_test.go
+++ b/src/image/png/writer_test.go
@@ -121,10 +121,10 @@
 }
 
 func BenchmarkEncodeGray(b *testing.B) {
-	b.StopTimer()
 	img := image.NewGray(image.Rect(0, 0, 640, 480))
 	b.SetBytes(640 * 480 * 1)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Encode(ioutil.Discard, img)
 	}
@@ -143,20 +143,19 @@
 }
 
 func BenchmarkEncodeGrayWithBufferPool(b *testing.B) {
-	b.StopTimer()
 	img := image.NewGray(image.Rect(0, 0, 640, 480))
 	e := Encoder{
 		BufferPool: &pool{},
 	}
 	b.SetBytes(640 * 480 * 1)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		e.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()
@@ -169,40 +168,40 @@
 		b.Fatal("expected image to be opaque")
 	}
 	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	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()
+	b.ReportAllocs()
+	b.ResetTimer()
 	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()
+	b.ReportAllocs()
+	b.ResetTimer()
 	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()
@@ -215,20 +214,21 @@
 		b.Fatal("expected image to be opaque")
 	}
 	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
+	b.ReportAllocs()
+	b.ResetTimer()
 	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()
+	b.ReportAllocs()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Encode(ioutil.Discard, img)
 	}
diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go
index 2226b77..22fc561 100644
--- a/src/internal/cpu/cpu.go
+++ b/src/internal/cpu/cpu.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Package cpu implements processor feature detection
-// used by the Go standard libary.
+// used by the Go standard library.
 package cpu
 
 var X86 x86
@@ -15,11 +15,13 @@
 type x86 struct {
 	_            [CacheLineSize]byte
 	HasAES       bool
+	HasADX       bool
 	HasAVX       bool
 	HasAVX2      bool
 	HasBMI1      bool
 	HasBMI2      bool
 	HasERMS      bool
+	HasFMA       bool
 	HasOSXSAVE   bool
 	HasPCLMULQDQ bool
 	HasPOPCNT    bool
@@ -30,3 +32,46 @@
 	HasSSE42     bool
 	_            [CacheLineSize]byte
 }
+
+var PPC64 ppc64
+
+// For ppc64x, it is safe to check only for ISA level starting on ISA v3.00,
+// since there are no optional categories. There are some exceptions that also
+// require kernel support to work (darn, scv), so there are capability bits for
+// those as well. The minimum processor requirement is POWER8 (ISA 2.07), so we
+// maintain some of the old capability checks for optional categories for
+// safety.
+// The struct is padded to avoid false sharing.
+type ppc64 struct {
+	_          [CacheLineSize]byte
+	HasVMX     bool // Vector unit (Altivec)
+	HasDFP     bool // Decimal Floating Point unit
+	HasVSX     bool // Vector-scalar unit
+	HasHTM     bool // Hardware Transactional Memory
+	HasISEL    bool // Integer select
+	HasVCRYPTO bool // Vector cryptography
+	HasHTMNOSC bool // HTM: kernel-aborted transaction in syscalls
+	HasDARN    bool // Hardware random number generator (requires kernel enablement)
+	HasSCV     bool // Syscall vectored (requires kernel enablement)
+	IsPOWER8   bool // ISA v2.07 (POWER8)
+	IsPOWER9   bool // ISA v3.00 (POWER9)
+	_          [CacheLineSize]byte
+}
+
+var ARM64 arm64
+
+// The booleans in arm64 contain the correspondingly named cpu feature bit.
+// The struct is padded to avoid false sharing.
+type arm64 struct {
+	_          [CacheLineSize]byte
+	HasFP      bool
+	HasASIMD   bool
+	HasEVTSTRM bool
+	HasAES     bool
+	HasPMULL   bool
+	HasSHA1    bool
+	HasSHA2    bool
+	HasCRC32   bool
+	HasATOMICS bool
+	_          [CacheLineSize]byte
+}
diff --git a/src/internal/cpu/cpu_arm64.go b/src/internal/cpu/cpu_arm64.go
index 078a6c3..e1278a1 100644
--- a/src/internal/cpu/cpu_arm64.go
+++ b/src/internal/cpu/cpu_arm64.go
@@ -2,6 +2,44 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build arm64
+
 package cpu
 
-const CacheLineSize = 32
+const CacheLineSize = 64
+
+// arm64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2.
+// These are linknamed in runtime/os_linux_arm64.go and are initialized by
+// archauxv().
+var arm64_hwcap uint
+var arm64_hwcap2 uint
+
+// HWCAP/HWCAP2 bits. These are exposed by Linux.
+const (
+	_ARM64_FEATURE_HAS_FP      = (1 << 0)
+	_ARM64_FEATURE_HAS_ASIMD   = (1 << 1)
+	_ARM64_FEATURE_HAS_EVTSTRM = (1 << 2)
+	_ARM64_FEATURE_HAS_AES     = (1 << 3)
+	_ARM64_FEATURE_HAS_PMULL   = (1 << 4)
+	_ARM64_FEATURE_HAS_SHA1    = (1 << 5)
+	_ARM64_FEATURE_HAS_SHA2    = (1 << 6)
+	_ARM64_FEATURE_HAS_CRC32   = (1 << 7)
+	_ARM64_FEATURE_HAS_ATOMICS = (1 << 8)
+)
+
+func init() {
+	// HWCAP feature bits
+	ARM64.HasFP = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_FP)
+	ARM64.HasASIMD = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_ASIMD)
+	ARM64.HasEVTSTRM = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_EVTSTRM)
+	ARM64.HasAES = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_AES)
+	ARM64.HasPMULL = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_PMULL)
+	ARM64.HasSHA1 = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_SHA1)
+	ARM64.HasSHA2 = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_SHA2)
+	ARM64.HasCRC32 = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_CRC32)
+	ARM64.HasATOMICS = isSet(arm64_hwcap, _ARM64_FEATURE_HAS_ATOMICS)
+}
+
+func isSet(hwc uint, value uint) bool {
+	return hwc&value != 0
+}
diff --git a/src/internal/cpu/cpu_ppc64.go b/src/internal/cpu/cpu_ppc64.go
deleted file mode 100644
index 5b15150..0000000
--- a/src/internal/cpu/cpu_ppc64.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cpu
-
-const CacheLineSize = 128
diff --git a/src/internal/cpu/cpu_ppc64le.go b/src/internal/cpu/cpu_ppc64le.go
deleted file mode 100644
index 5b15150..0000000
--- a/src/internal/cpu/cpu_ppc64le.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cpu
-
-const CacheLineSize = 128
diff --git a/src/internal/cpu/cpu_ppc64x.go b/src/internal/cpu/cpu_ppc64x.go
new file mode 100644
index 0000000..7f09372
--- /dev/null
+++ b/src/internal/cpu/cpu_ppc64x.go
@@ -0,0 +1,54 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ppc64 ppc64le
+
+package cpu
+
+const CacheLineSize = 128
+
+// ppc64x doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2.
+// These are linknamed in runtime/os_linux_ppc64x.go and are initialized by
+// archauxv().
+var ppc64x_hwcap uint
+var ppc64x_hwcap2 uint
+
+// HWCAP/HWCAP2 bits. These are exposed by the kernel.
+const (
+	// ISA Level
+	_PPC_FEATURE2_ARCH_2_07 = 0x80000000
+	_PPC_FEATURE2_ARCH_3_00 = 0x00800000
+
+	// CPU features
+	_PPC_FEATURE_HAS_ALTIVEC     = 0x10000000
+	_PPC_FEATURE_HAS_DFP         = 0x00000400
+	_PPC_FEATURE_HAS_VSX         = 0x00000080
+	_PPC_FEATURE2_HAS_HTM        = 0x40000000
+	_PPC_FEATURE2_HAS_ISEL       = 0x08000000
+	_PPC_FEATURE2_HAS_VEC_CRYPTO = 0x02000000
+	_PPC_FEATURE2_HTM_NOSC       = 0x01000000
+	_PPC_FEATURE2_DARN           = 0x00200000
+	_PPC_FEATURE2_SCV            = 0x00100000
+)
+
+func init() {
+	// HWCAP feature bits
+	PPC64.HasVMX = isSet(ppc64x_hwcap, _PPC_FEATURE_HAS_ALTIVEC)
+	PPC64.HasDFP = isSet(ppc64x_hwcap, _PPC_FEATURE_HAS_DFP)
+	PPC64.HasVSX = isSet(ppc64x_hwcap, _PPC_FEATURE_HAS_VSX)
+
+	// HWCAP2 feature bits
+	PPC64.IsPOWER8 = isSet(ppc64x_hwcap2, _PPC_FEATURE2_ARCH_2_07)
+	PPC64.HasHTM = isSet(ppc64x_hwcap2, _PPC_FEATURE2_HAS_HTM)
+	PPC64.HasISEL = isSet(ppc64x_hwcap2, _PPC_FEATURE2_HAS_ISEL)
+	PPC64.HasVCRYPTO = isSet(ppc64x_hwcap2, _PPC_FEATURE2_HAS_VEC_CRYPTO)
+	PPC64.HasHTMNOSC = isSet(ppc64x_hwcap2, _PPC_FEATURE2_HTM_NOSC)
+	PPC64.IsPOWER9 = isSet(ppc64x_hwcap2, _PPC_FEATURE2_ARCH_3_00)
+	PPC64.HasDARN = isSet(ppc64x_hwcap2, _PPC_FEATURE2_DARN)
+	PPC64.HasSCV = isSet(ppc64x_hwcap2, _PPC_FEATURE2_SCV)
+}
+
+func isSet(hwc uint, value uint) bool {
+	return hwc&value != 0
+}
diff --git a/src/internal/cpu/cpu_test.go b/src/internal/cpu/cpu_test.go
index ab9836a..07b0243 100644
--- a/src/internal/cpu/cpu_test.go
+++ b/src/internal/cpu/cpu_test.go
@@ -25,3 +25,26 @@
 		}
 	}
 }
+
+func TestPPC64minimalFeatures(t *testing.T) {
+	if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
+		if !cpu.PPC64.IsPOWER8 {
+			t.Fatalf("IsPOWER8 expected true, got false")
+		}
+		if !cpu.PPC64.HasVMX {
+			t.Fatalf("HasVMX expected true, got false")
+		}
+		if !cpu.PPC64.HasDFP {
+			t.Fatalf("HasDFP expected true, got false")
+		}
+		if !cpu.PPC64.HasVSX {
+			t.Fatalf("HasVSX expected true, got false")
+		}
+		if !cpu.PPC64.HasISEL {
+			t.Fatalf("HasISEL expected true, got false")
+		}
+		if !cpu.PPC64.HasVCRYPTO {
+			t.Fatalf("HasVCRYPTO expected true, got false")
+		}
+	}
+}
diff --git a/src/internal/cpu/cpu_x86.go b/src/internal/cpu/cpu_x86.go
index 31e7084..34c632f 100644
--- a/src/internal/cpu/cpu_x86.go
+++ b/src/internal/cpu/cpu_x86.go
@@ -15,9 +15,9 @@
 func xgetbv() (eax, edx uint32)
 
 func init() {
-	maxId, _, _, _ := cpuid(0, 0)
+	maxID, _, _, _ := cpuid(0, 0)
 
-	if maxId < 1 {
+	if maxID < 1 {
 		return
 	}
 
@@ -27,6 +27,7 @@
 	X86.HasSSE3 = isSet(0, ecx1)
 	X86.HasPCLMULQDQ = isSet(1, ecx1)
 	X86.HasSSSE3 = isSet(9, ecx1)
+	X86.HasFMA = isSet(12, ecx1)
 	X86.HasSSE41 = isSet(19, ecx1)
 	X86.HasSSE42 = isSet(20, ecx1)
 	X86.HasPOPCNT = isSet(23, ecx1)
@@ -43,7 +44,7 @@
 
 	X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
 
-	if maxId < 7 {
+	if maxID < 7 {
 		return
 	}
 
@@ -52,6 +53,7 @@
 	X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
 	X86.HasBMI2 = isSet(8, ebx7)
 	X86.HasERMS = isSet(9, ebx7)
+	X86.HasADX = isSet(19, ebx7)
 }
 
 func isSet(bitpos uint, value uint32) bool {
diff --git a/src/internal/poll/export_windows_test.go b/src/internal/poll/export_windows_test.go
new file mode 100644
index 0000000..88ed71a
--- /dev/null
+++ b/src/internal/poll/export_windows_test.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Export guts for testing on windows.
+// Since testing imports os and os imports internal/poll,
+// the internal/poll tests can not be in package poll.
+
+package poll
+
+var (
+	LogInitFD = &logInitFD
+)
+
+func (fd *FD) IsPartOfNetpoll() bool {
+	return fd.pd.runtimeCtx != 0
+}
diff --git a/src/internal/poll/fd.go b/src/internal/poll/fd.go
index f1454db..2567746 100644
--- a/src/internal/poll/fd.go
+++ b/src/internal/poll/fd.go
@@ -21,6 +21,10 @@
 // has been closed.
 var ErrFileClosing = errors.New("use of closed file")
 
+// ErrNoDeadline is returned when a request is made to set a deadline
+// on a file type that does not use the poller.
+var ErrNoDeadline = errors.New("file type does not support deadline")
+
 // Return the appropriate closing error based on isFile.
 func errClosing(isFile bool) error {
 	if isFile {
diff --git a/src/internal/poll/fd_mutex.go b/src/internal/poll/fd_mutex.go
index 76174e5..2ba7de7 100644
--- a/src/internal/poll/fd_mutex.go
+++ b/src/internal/poll/fd_mutex.go
@@ -65,7 +65,7 @@
 }
 
 // increfAndClose sets the state of mu to closed.
-// It reports whether there is no remaining reference.
+// It returns false if the file was already closed.
 func (mu *fdMutex) increfAndClose() bool {
 	for {
 		old := atomic.LoadUint64(&mu.state)
diff --git a/src/internal/poll/fd_poll_runtime.go b/src/internal/poll/fd_poll_runtime.go
index bfbe3c7..87a01a8 100644
--- a/src/internal/poll/fd_poll_runtime.go
+++ b/src/internal/poll/fd_poll_runtime.go
@@ -147,11 +147,11 @@
 	if err := fd.incref(); err != nil {
 		return err
 	}
+	defer fd.decref()
 	if fd.pd.runtimeCtx == 0 {
-		return errors.New("file type does not support deadlines")
+		return ErrNoDeadline
 	}
 	runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
-	fd.decref()
 	return nil
 }
 
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go
index c40c701..372dc81 100644
--- a/src/internal/poll/fd_unix.go
+++ b/src/internal/poll/fd_unix.go
@@ -8,6 +8,7 @@
 
 import (
 	"io"
+	"runtime"
 	"syscall"
 )
 
@@ -26,6 +27,9 @@
 	// Writev cache.
 	iovecs *[]syscall.Iovec
 
+	// Semaphore signaled when file is closed.
+	csema uint32
+
 	// Whether this is a streaming descriptor, as opposed to a
 	// packet-based descriptor like a UDP socket. Immutable.
 	IsStream bool
@@ -36,18 +40,23 @@
 
 	// Whether this is a file rather than a network socket.
 	isFile bool
+
+	// Whether this file has been set to blocking mode.
+	isBlocking bool
 }
 
 // Init initializes the FD. The Sysfd field should already be set.
 // This can be called multiple times on a single FD.
 // The net argument is a network name from the net package (e.g., "tcp"),
 // or "file".
+// Set pollable to true if fd should be managed by runtime netpoll.
 func (fd *FD) Init(net string, pollable bool) error {
 	// We don't actually care about the various network types.
 	if net == "file" {
 		fd.isFile = true
 	}
 	if !pollable {
+		fd.isBlocking = true
 		return nil
 	}
 	return fd.pd.init(fd)
@@ -61,6 +70,7 @@
 	fd.pd.close()
 	err := CloseFunc(fd.Sysfd)
 	fd.Sysfd = -1
+	runtime_Semrelease(&fd.csema)
 	return err
 }
 
@@ -70,15 +80,27 @@
 	if !fd.fdmu.increfAndClose() {
 		return errClosing(fd.isFile)
 	}
+
 	// 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(fd.isFile).
 	fd.pd.evict()
+
 	// The call to decref will call destroy if there are no other
 	// references.
-	return fd.decref()
+	err := fd.decref()
+
+	// Wait until the descriptor is closed. If this was the only
+	// reference, it is already closed. Only wait if the file has
+	// not been set to blocking mode, as otherwise any current I/O
+	// may be blocking, and that would block the Close.
+	if !fd.isBlocking {
+		runtime_Semacquire(&fd.csema)
+	}
+
+	return err
 }
 
 // Shutdown wraps the shutdown network call.
@@ -90,6 +112,16 @@
 	return syscall.Shutdown(fd.Sysfd, how)
 }
 
+// SetBlocking puts the file into blocking mode.
+func (fd *FD) SetBlocking() error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	fd.isBlocking = true
+	return syscall.SetNonblock(fd.Sysfd, false)
+}
+
 // Darwin and FreeBSD can't read or write 2GB+ files at a time,
 // even on 64-bit systems.
 // The same is true of socket implementations on many systems.
@@ -126,6 +158,12 @@
 					continue
 				}
 			}
+
+			// On MacOS we can see EINTR here if the user
+			// pressed ^Z.  See issue #22838.
+			if runtime.GOOS == "darwin" && err == syscall.EINTR {
+				continue
+			}
 		}
 		err = fd.eofError(n, err)
 		return n, err
@@ -402,6 +440,15 @@
 	return fd.pd.waitWrite(fd.isFile)
 }
 
+// WriteOnce is for testing only. It makes a single write call.
+func (fd *FD) WriteOnce(p []byte) (int, error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, err
+	}
+	defer fd.writeUnlock()
+	return syscall.Write(fd.Sysfd, p)
+}
+
 // RawControl invokes the user-defined function f for a non-IO
 // operation.
 func (fd *FD) RawControl(f func(uintptr)) error {
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index 655f934..187908b 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -7,6 +7,7 @@
 import (
 	"errors"
 	"internal/race"
+	"internal/syscall/windows"
 	"io"
 	"runtime"
 	"sync"
@@ -31,11 +32,40 @@
 // package uses CancelIoEx API, if present, otherwise it fallback
 // to CancelIo.
 
-var (
-	canCancelIO                               bool // determines if CancelIoEx API is present
-	skipSyncNotif                             bool
-	hasLoadSetFileCompletionNotificationModes bool
-)
+var canCancelIO bool // determines if CancelIoEx API is present
+
+// This package uses SetFileCompletionNotificationModes Windows API
+// to skip calling GetQueuedCompletionStatus if an IO operation completes
+// synchronously. Unfortuently SetFileCompletionNotificationModes is not
+// available on Windows XP. Also there is a known bug where
+// SetFileCompletionNotificationModes crashes on some systems
+// (see http://support.microsoft.com/kb/2568167 for details).
+
+var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use
+
+// checkSetFileCompletionNotificationModes verifies that
+// SetFileCompletionNotificationModes Windows API is present
+// on the system and is safe to use.
+// See http://support.microsoft.com/kb/2568167 for details.
+func checkSetFileCompletionNotificationModes() {
+	err := syscall.LoadSetFileCompletionNotificationModes()
+	if err != nil {
+		return
+	}
+	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 {
+		return
+	}
+	for i := int32(0); i < n; i++ {
+		if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
+			return
+		}
+	}
+	useSetFileCompletionNotificationModes = true
+}
 
 func init() {
 	var d syscall.WSAData
@@ -44,26 +74,7 @@
 		initErr = e
 	}
 	canCancelIO = syscall.LoadCancelIoEx() == nil
-	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
-				}
-			}
-		}
-	}
+	checkSetFileCompletionNotificationModes()
 }
 
 // operation contains superset of data necessary to perform all async IO.
@@ -82,6 +93,7 @@
 	fd     *FD
 	errc   chan error
 	buf    syscall.WSABuf
+	msg    windows.WSAMsg
 	sa     syscall.Sockaddr
 	rsa    *syscall.RawSockaddrAny
 	rsan   int32
@@ -122,6 +134,22 @@
 	o.bufs = o.bufs[:0]
 }
 
+func (o *operation) InitMsg(p []byte, oob []byte) {
+	o.InitBuf(p)
+	o.msg.Buffers = &o.buf
+	o.msg.BufferCount = 1
+
+	o.msg.Name = nil
+	o.msg.Namelen = 0
+
+	o.msg.Flags = 0
+	o.msg.Control.Len = uint32(len(oob))
+	o.msg.Control.Buf = nil
+	if len(oob) != 0 {
+		o.msg.Control.Buf = &oob[0]
+	}
+}
+
 // ioSrv executes net IO requests.
 type ioSrv struct {
 	req chan ioSrvReq
@@ -278,6 +306,9 @@
 	readbyte       []byte   // buffer to hold decoding of readuint16 from utf16 to utf8
 	readbyteOffset int      // readbyte[readOffset:] is yet to be consumed with file.Read
 
+	// Semaphore signaled when file is closed.
+	csema uint32
+
 	skipSyncNotif bool
 
 	// Whether this is a streaming descriptor, as opposed to a
@@ -295,11 +326,15 @@
 	isDir bool
 }
 
+// logInitFD is set by tests to enable file descriptor initialization logging.
+var logInitFD func(net string, fd *FD, err error)
+
 // Init initializes the FD. The Sysfd field should already be set.
 // This can be called multiple times on a single FD.
 // The net argument is a network name from the net package (e.g., "tcp"),
 // or "file" or "console" or "dir".
-func (fd *FD) Init(net string) (string, error) {
+// Set pollable to true if fd should be managed by runtime netpoll.
+func (fd *FD) Init(net string, pollable bool) (string, error) {
 	if initErr != nil {
 		return "", initErr
 	}
@@ -319,7 +354,8 @@
 		return "", errors.New("internal error: unknown network type " + net)
 	}
 
-	if !fd.isFile && !fd.isConsole && !fd.isDir {
+	var err error
+	if pollable {
 		// Only call init for a network socket.
 		// This means that we don't add files to the runtime poller.
 		// Adding files to the runtime poller can confuse matters
@@ -331,16 +367,20 @@
 		// somehow call ExecIO, then ExecIO, and therefore the
 		// calling method, will return an error, because
 		// fd.pd.runtimeCtx will be 0.
-		if err := fd.pd.init(fd); err != nil {
-			return "", err
-		}
+		err = fd.pd.init(fd)
 	}
-	if hasLoadSetFileCompletionNotificationModes {
+	if logInitFD != nil {
+		logInitFD(net, fd, err)
+	}
+	if err != nil {
+		return "", err
+	}
+	if pollable && useSetFileCompletionNotificationModes {
 		// 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 && (net == "tcp" || net == "file") {
+		if net == "tcp" {
 			flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
 		}
 		err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags)
@@ -390,6 +430,7 @@
 		err = CloseFunc(fd.Sysfd)
 	}
 	fd.Sysfd = syscall.InvalidHandle
+	runtime_Semrelease(&fd.csema)
 	return err
 }
 
@@ -401,7 +442,11 @@
 	}
 	// unblock pending reader and writer
 	fd.pd.evict()
-	return fd.decref()
+	err := fd.decref()
+	// Wait until the descriptor is closed. If this was the only
+	// reference, it is already closed.
+	runtime_Semacquire(&fd.csema)
+	return err
 }
 
 // Shutdown wraps the shutdown network call.
@@ -871,3 +916,77 @@
 func (fd *FD) RawWrite(f func(uintptr) bool) error {
 	return errors.New("not implemented")
 }
+
+func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) {
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		var raw syscall.RawSockaddrInet4
+		raw.Family = syscall.AF_INET
+		p := (*[2]byte)(unsafe.Pointer(&raw.Port))
+		p[0] = byte(sa.Port >> 8)
+		p[1] = byte(sa.Port)
+		for i := 0; i < len(sa.Addr); i++ {
+			raw.Addr[i] = sa.Addr[i]
+		}
+		return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil
+	case *syscall.SockaddrInet6:
+		var raw syscall.RawSockaddrInet6
+		raw.Family = syscall.AF_INET6
+		p := (*[2]byte)(unsafe.Pointer(&raw.Port))
+		p[0] = byte(sa.Port >> 8)
+		p[1] = byte(sa.Port)
+		raw.Scope_id = sa.ZoneId
+		for i := 0; i < len(sa.Addr); i++ {
+			raw.Addr[i] = sa.Addr[i]
+		}
+		return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil
+	default:
+		return nil, 0, syscall.EWINDOWS
+	}
+}
+
+// ReadMsg wraps the WSARecvMsg network call.
+func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
+	if err := fd.readLock(); err != nil {
+		return 0, 0, 0, nil, err
+	}
+	defer fd.readUnlock()
+
+	o := &fd.rop
+	o.InitMsg(p, oob)
+	o.rsa = new(syscall.RawSockaddrAny)
+	o.msg.Name = o.rsa
+	o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+	n, err := rsrv.ExecIO(o, func(o *operation) error {
+		return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+	})
+	err = fd.eofError(n, err)
+	var sa syscall.Sockaddr
+	if err == nil {
+		sa, err = o.rsa.Sockaddr()
+	}
+	return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
+}
+
+// WriteMsg wraps the WSASendMsg network call.
+func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, 0, err
+	}
+	defer fd.writeUnlock()
+
+	o := &fd.wop
+	o.InitMsg(p, oob)
+	if sa != nil {
+		rsa, len, err := sockaddrToRaw(sa)
+		if err != nil {
+			return 0, 0, err
+		}
+		o.msg.Name = (*syscall.RawSockaddrAny)(rsa)
+		o.msg.Namelen = len
+	}
+	n, err := wsrv.ExecIO(o, func(o *operation) error {
+		return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
+	})
+	return n, int(o.msg.Control.Len), err
+}
diff --git a/src/internal/poll/fd_windows_test.go b/src/internal/poll/fd_windows_test.go
new file mode 100644
index 0000000..e3ca0e2
--- /dev/null
+++ b/src/internal/poll/fd_windows_test.go
@@ -0,0 +1,111 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poll_test
+
+import (
+	"fmt"
+	"internal/poll"
+	"os"
+	"sync"
+	"syscall"
+	"testing"
+)
+
+type loggedFD struct {
+	Net string
+	FD  *poll.FD
+	Err error
+}
+
+var (
+	logMu     sync.Mutex
+	loggedFDs map[syscall.Handle]*loggedFD
+)
+
+func logFD(net string, fd *poll.FD, err error) {
+	logMu.Lock()
+	defer logMu.Unlock()
+
+	loggedFDs[fd.Sysfd] = &loggedFD{
+		Net: net,
+		FD:  fd,
+		Err: err,
+	}
+}
+
+func init() {
+	loggedFDs = make(map[syscall.Handle]*loggedFD)
+	*poll.LogInitFD = logFD
+}
+
+func findLoggedFD(h syscall.Handle) (lfd *loggedFD, found bool) {
+	logMu.Lock()
+	defer logMu.Unlock()
+
+	lfd, found = loggedFDs[h]
+	return lfd, found
+}
+
+// checkFileIsNotPartOfNetpoll verifies that f is not managed by netpoll.
+// It returns error, if check fails.
+func checkFileIsNotPartOfNetpoll(f *os.File) error {
+	lfd, found := findLoggedFD(syscall.Handle(f.Fd()))
+	if !found {
+		return fmt.Errorf("%v fd=%v: is not found in the log", f.Name(), f.Fd())
+	}
+	if lfd.FD.IsPartOfNetpoll() {
+		return fmt.Errorf("%v fd=%v: is part of netpoll, but should not be (logged: net=%v err=%v)", f.Name(), f.Fd(), lfd.Net, lfd.Err)
+	}
+	return nil
+}
+
+func TestFileFdsAreInitialised(t *testing.T) {
+	exe, err := os.Executable()
+	if err != nil {
+		t.Fatal(err)
+	}
+	f, err := os.Open(exe)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	err = checkFileIsNotPartOfNetpoll(f)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestSerialFdsAreInitialised(t *testing.T) {
+	for _, name := range []string{"COM1", "COM2", "COM3", "COM4"} {
+		t.Run(name, func(t *testing.T) {
+			h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name),
+				syscall.GENERIC_READ|syscall.GENERIC_WRITE,
+				0,
+				nil,
+				syscall.OPEN_EXISTING,
+				syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED,
+				0)
+			if err != nil {
+				if errno, ok := err.(syscall.Errno); ok {
+					switch errno {
+					case syscall.ERROR_FILE_NOT_FOUND,
+						syscall.ERROR_ACCESS_DENIED:
+						t.Log("Skipping: ", err)
+						return
+					}
+				}
+				t.Fatal(err)
+			}
+			f := os.NewFile(uintptr(h), name)
+			defer f.Close()
+
+			err = checkFileIsNotPartOfNetpoll(f)
+			if err != nil {
+				t.Fatal(err)
+			}
+		})
+	}
+}
diff --git a/src/internal/poll/sendfile_windows.go b/src/internal/poll/sendfile_windows.go
index c1a2d6d..4a15b75 100644
--- a/src/internal/poll/sendfile_windows.go
+++ b/src/internal/poll/sendfile_windows.go
@@ -8,6 +8,15 @@
 
 // SendFile wraps the TransmitFile call.
 func SendFile(fd *FD, src syscall.Handle, n int64) (int64, error) {
+	ft, err := syscall.GetFileType(src)
+	if err != nil {
+		return 0, err
+	}
+	// TransmitFile does not work with pipes
+	if ft == syscall.FILE_TYPE_PIPE {
+		return 0, syscall.ESPIPE
+	}
+
 	if err := fd.writeLock(); err != nil {
 		return 0, err
 	}
diff --git a/src/internal/poll/sockoptip.go b/src/internal/poll/sockoptip.go
index 5d5dff6..1ee490c 100644
--- a/src/internal/poll/sockoptip.go
+++ b/src/internal/poll/sockoptip.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package poll
 
diff --git a/src/internal/singleflight/singleflight.go b/src/internal/singleflight/singleflight.go
index de81ac8..1e9960d 100644
--- a/src/internal/singleflight/singleflight.go
+++ b/src/internal/singleflight/singleflight.go
@@ -65,8 +65,10 @@
 }
 
 // DoChan is like Do but returns a channel that will receive the
-// results when they are ready.
-func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result {
+// results when they are ready. The second result is true if the function
+// will eventually be called, false if it will not (because there is
+// a pending request with this key).
+func (g *Group) DoChan(key string, fn func() (interface{}, error)) (<-chan Result, bool) {
 	ch := make(chan Result, 1)
 	g.mu.Lock()
 	if g.m == nil {
@@ -76,7 +78,7 @@
 		c.dups++
 		c.chans = append(c.chans, ch)
 		g.mu.Unlock()
-		return ch
+		return ch, false
 	}
 	c := &call{chans: []chan<- Result{ch}}
 	c.wg.Add(1)
@@ -85,7 +87,7 @@
 
 	go g.doCall(c, key, fn)
 
-	return ch
+	return ch, true
 }
 
 // doCall handles the single call for a key.
diff --git a/src/internal/syscall/windows/exec_windows_test.go b/src/internal/syscall/windows/exec_windows_test.go
new file mode 100644
index 0000000..94fd95b
--- /dev/null
+++ b/src/internal/syscall/windows/exec_windows_test.go
@@ -0,0 +1,152 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows_test
+
+import (
+	"fmt"
+	"internal/syscall/windows"
+	"os"
+	"os/exec"
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+func TestRunAtLowIntegrity(t *testing.T) {
+	if isWindowsXP(t) {
+		t.Skip("Windows XP does not support windows integrity levels")
+	}
+
+	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
+		wil, err := getProcessIntegrityLevel()
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
+			os.Exit(9)
+			return
+		}
+		fmt.Printf("%s", wil)
+		os.Exit(0)
+		return
+	}
+
+	cmd := exec.Command(os.Args[0], "-test.run=TestRunAtLowIntegrity", "--")
+	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+
+	token, err := getIntegrityLevelToken(sidWilLow)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer token.Close()
+
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		Token: token,
+	}
+
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if string(out) != sidWilLow {
+		t.Fatalf("Child process did not run as low integrity level: %s", string(out))
+	}
+}
+
+func isWindowsXP(t *testing.T) bool {
+	v, err := syscall.GetVersion()
+	if err != nil {
+		t.Fatalf("GetVersion failed: %v", err)
+	}
+	major := byte(v)
+	return major < 6
+}
+
+const (
+	sidWilLow = `S-1-16-4096`
+)
+
+func getProcessIntegrityLevel() (string, error) {
+	procToken, err := syscall.OpenCurrentProcessToken()
+	if err != nil {
+		return "", err
+	}
+	defer procToken.Close()
+
+	p, err := tokenGetInfo(procToken, syscall.TokenIntegrityLevel, 64)
+	if err != nil {
+		return "", err
+	}
+
+	tml := (*windows.TOKEN_MANDATORY_LABEL)(p)
+
+	sid := (*syscall.SID)(unsafe.Pointer(tml.Label.Sid))
+
+	return sid.String()
+}
+
+func tokenGetInfo(t syscall.Token, class uint32, initSize int) (unsafe.Pointer, error) {
+	n := uint32(initSize)
+	for {
+		b := make([]byte, n)
+		e := syscall.GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+		if e == nil {
+			return unsafe.Pointer(&b[0]), nil
+		}
+		if e != syscall.ERROR_INSUFFICIENT_BUFFER {
+			return nil, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, e
+		}
+	}
+}
+
+func getIntegrityLevelToken(wns string) (syscall.Token, error) {
+	var procToken, token syscall.Token
+
+	proc, err := syscall.GetCurrentProcess()
+	if err != nil {
+		return 0, err
+	}
+	defer syscall.CloseHandle(proc)
+
+	err = syscall.OpenProcessToken(proc,
+		syscall.TOKEN_DUPLICATE|
+			syscall.TOKEN_ADJUST_DEFAULT|
+			syscall.TOKEN_QUERY|
+			syscall.TOKEN_ASSIGN_PRIMARY,
+		&procToken)
+	if err != nil {
+		return 0, err
+	}
+	defer procToken.Close()
+
+	sid, err := syscall.StringToSid(wns)
+	if err != nil {
+		return 0, err
+	}
+
+	tml := &windows.TOKEN_MANDATORY_LABEL{}
+	tml.Label.Attributes = windows.SE_GROUP_INTEGRITY
+	tml.Label.Sid = sid
+
+	err = windows.DuplicateTokenEx(procToken, 0, nil, windows.SecurityImpersonation,
+		windows.TokenPrimary, &token)
+	if err != nil {
+		return 0, err
+	}
+
+	err = windows.SetTokenInformation(token,
+		syscall.TokenIntegrityLevel,
+		uintptr(unsafe.Pointer(tml)),
+		tml.Size())
+	if err != nil {
+		token.Close()
+		return 0, err
+	}
+	return token, nil
+}
diff --git a/src/internal/syscall/windows/mksyscall.go b/src/internal/syscall/windows/mksyscall.go
index 91fa2b3..23efb6a 100644
--- a/src/internal/syscall/windows/mksyscall.go
+++ b/src/internal/syscall/windows/mksyscall.go
@@ -4,4 +4,4 @@
 
 package windows
 
-//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go
diff --git a/src/internal/syscall/windows/psapi_windows.go b/src/internal/syscall/windows/psapi_windows.go
new file mode 100644
index 0000000..b138e65
--- /dev/null
+++ b/src/internal/syscall/windows/psapi_windows.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type PROCESS_MEMORY_COUNTERS struct {
+	CB                         uint32
+	PageFaultCount             uint32
+	PeakWorkingSetSize         uintptr
+	WorkingSetSize             uintptr
+	QuotaPeakPagedPoolUsage    uintptr
+	QuotaPagedPoolUsage        uintptr
+	QuotaPeakNonPagedPoolUsage uintptr
+	QuotaNonPagedPoolUsage     uintptr
+	PagefileUsage              uintptr
+	PeakPagefileUsage          uintptr
+}
+
+//sys	GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) = psapi.GetProcessMemoryInfo
diff --git a/src/internal/syscall/windows/security_windows.go b/src/internal/syscall/windows/security_windows.go
index 2c145e1..14ea425 100644
--- a/src/internal/syscall/windows/security_windows.go
+++ b/src/internal/syscall/windows/security_windows.go
@@ -6,6 +6,7 @@
 
 import (
 	"syscall"
+	"unsafe"
 )
 
 const (
@@ -55,3 +56,28 @@
 	}
 	return err
 }
+
+//sys DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) = advapi32.DuplicateTokenEx
+//sys SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) = advapi32.SetTokenInformation
+
+type SID_AND_ATTRIBUTES struct {
+	Sid        *syscall.SID
+	Attributes uint32
+}
+
+type TOKEN_MANDATORY_LABEL struct {
+	Label SID_AND_ATTRIBUTES
+}
+
+func (tml *TOKEN_MANDATORY_LABEL) Size() uint32 {
+	return uint32(unsafe.Sizeof(TOKEN_MANDATORY_LABEL{})) + syscall.GetLengthSid(tml.Label.Sid)
+}
+
+const SE_GROUP_INTEGRITY = 0x00000020
+
+type TokenType uint32
+
+const (
+	TokenPrimary       TokenType = 1
+	TokenImpersonation TokenType = 2
+)
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
index ec08a5a..b531f89 100644
--- a/src/internal/syscall/windows/syscall_windows.go
+++ b/src/internal/syscall/windows/syscall_windows.go
@@ -4,7 +4,11 @@
 
 package windows
 
-import "syscall"
+import (
+	"sync"
+	"syscall"
+	"unsafe"
+)
 
 const (
 	ERROR_SHARING_VIOLATION      syscall.Errno = 32
@@ -113,6 +117,112 @@
 //sys	GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
 
 const (
+	WSA_FLAG_OVERLAPPED        = 0x01
+	WSA_FLAG_NO_HANDLE_INHERIT = 0x80
+
+	WSAEMSGSIZE syscall.Errno = 10040
+
+	MSG_TRUNC  = 0x0100
+	MSG_CTRUNC = 0x0200
+
+	socket_error = uintptr(^uint32(0))
+)
+
+var WSAID_WSASENDMSG = syscall.GUID{
+	Data1: 0xa441e712,
+	Data2: 0x754f,
+	Data3: 0x43ca,
+	Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
+}
+
+var WSAID_WSARECVMSG = syscall.GUID{
+	Data1: 0xf689d7c8,
+	Data2: 0x6f1f,
+	Data3: 0x436b,
+	Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
+}
+
+var sendRecvMsgFunc struct {
+	once     sync.Once
+	sendAddr uintptr
+	recvAddr uintptr
+	err      error
+}
+
+type WSAMsg struct {
+	Name        *syscall.RawSockaddrAny
+	Namelen     int32
+	Buffers     *syscall.WSABuf
+	BufferCount uint32
+	Control     syscall.WSABuf
+	Flags       uint32
+}
+
+//sys	WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
+
+func loadWSASendRecvMsg() error {
+	sendRecvMsgFunc.once.Do(func() {
+		var s syscall.Handle
+		s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
+		if sendRecvMsgFunc.err != nil {
+			return
+		}
+		defer syscall.CloseHandle(s)
+		var n uint32
+		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
+			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
+			uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
+			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
+			uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
+			&n, nil, 0)
+		if sendRecvMsgFunc.err != nil {
+			return
+		}
+		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
+			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
+			uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
+			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
+			uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
+			&n, nil, 0)
+	})
+	return sendRecvMsgFunc.err
+}
+
+func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
+	err := loadWSASendRecvMsg()
+	if err != nil {
+		return err
+	}
+	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return err
+}
+
+func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
+	err := loadWSASendRecvMsg()
+	if err != nil {
+		return err
+	}
+	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return err
+}
+
+const (
 	ComputerNameNetBIOS                   = 0
 	ComputerNameDnsHostname               = 1
 	ComputerNameDnsDomain                 = 2
@@ -165,3 +275,19 @@
 
 //sys  NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd
 //sys  NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel
+
+const (
+	FILE_NAME_NORMALIZED = 0x0
+	FILE_NAME_OPENED     = 0x8
+
+	VOLUME_NAME_DOS  = 0x0
+	VOLUME_NAME_GUID = 0x1
+	VOLUME_NAME_NONE = 0x4
+	VOLUME_NAME_NT   = 0x2
+)
+
+//sys	GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
+
+func LoadGetFinalPathNameByHandle() error {
+	return procGetFinalPathNameByHandleW.Find()
+}
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
index 7a2ffee..bdca80c 100644
--- a/src/internal/syscall/windows/zsyscall_windows.go
+++ b/src/internal/syscall/windows/zsyscall_windows.go
@@ -38,24 +38,31 @@
 var (
 	modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
 	modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
+	modws2_32   = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
 	modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
 	modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
+	modpsapi    = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
 
-	procGetAdaptersAddresses  = modiphlpapi.NewProc("GetAdaptersAddresses")
-	procGetComputerNameExW    = modkernel32.NewProc("GetComputerNameExW")
-	procMoveFileExW           = modkernel32.NewProc("MoveFileExW")
-	procGetModuleFileNameW    = modkernel32.NewProc("GetModuleFileNameW")
-	procGetACP                = modkernel32.NewProc("GetACP")
-	procGetConsoleCP          = modkernel32.NewProc("GetConsoleCP")
-	procMultiByteToWideChar   = modkernel32.NewProc("MultiByteToWideChar")
-	procGetCurrentThread      = modkernel32.NewProc("GetCurrentThread")
-	procNetShareAdd           = modnetapi32.NewProc("NetShareAdd")
-	procNetShareDel           = modnetapi32.NewProc("NetShareDel")
-	procImpersonateSelf       = modadvapi32.NewProc("ImpersonateSelf")
-	procRevertToSelf          = modadvapi32.NewProc("RevertToSelf")
-	procOpenThreadToken       = modadvapi32.NewProc("OpenThreadToken")
-	procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
-	procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
+	procGetAdaptersAddresses      = modiphlpapi.NewProc("GetAdaptersAddresses")
+	procGetComputerNameExW        = modkernel32.NewProc("GetComputerNameExW")
+	procMoveFileExW               = modkernel32.NewProc("MoveFileExW")
+	procGetModuleFileNameW        = modkernel32.NewProc("GetModuleFileNameW")
+	procWSASocketW                = modws2_32.NewProc("WSASocketW")
+	procGetACP                    = modkernel32.NewProc("GetACP")
+	procGetConsoleCP              = modkernel32.NewProc("GetConsoleCP")
+	procMultiByteToWideChar       = modkernel32.NewProc("MultiByteToWideChar")
+	procGetCurrentThread          = modkernel32.NewProc("GetCurrentThread")
+	procNetShareAdd               = modnetapi32.NewProc("NetShareAdd")
+	procNetShareDel               = modnetapi32.NewProc("NetShareDel")
+	procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
+	procImpersonateSelf           = modadvapi32.NewProc("ImpersonateSelf")
+	procRevertToSelf              = modadvapi32.NewProc("RevertToSelf")
+	procOpenThreadToken           = modadvapi32.NewProc("OpenThreadToken")
+	procLookupPrivilegeValueW     = modadvapi32.NewProc("LookupPrivilegeValueW")
+	procAdjustTokenPrivileges     = modadvapi32.NewProc("AdjustTokenPrivileges")
+	procDuplicateTokenEx          = modadvapi32.NewProc("DuplicateTokenEx")
+	procSetTokenInformation       = modadvapi32.NewProc("SetTokenInformation")
+	procGetProcessMemoryInfo      = modpsapi.NewProc("GetProcessMemoryInfo")
 )
 
 func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
@@ -103,6 +110,19 @@
 	return
 }
 
+func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags))
+	handle = syscall.Handle(r0)
+	if handle == syscall.InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func GetACP() (acp uint32) {
 	r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
 	acp = uint32(r0)
@@ -157,6 +177,19 @@
 	return
 }
 
+func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func ImpersonateSelf(impersonationlevel uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0)
 	if r1 == 0 {
@@ -229,3 +262,39 @@
 	}
 	return
 }
+
+func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) {
+	r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go
index 1a13ac3..b3c16a8 100644
--- a/src/internal/testenv/testenv.go
+++ b/src/internal/testenv/testenv.go
@@ -33,6 +33,13 @@
 // HasGoBuild reports whether the current system can build programs with ``go build''
 // and then run them with os.StartProcess or exec.Command.
 func HasGoBuild() bool {
+	if os.Getenv("GO_GCFLAGS") != "" {
+		// It's too much work to require every caller of the go command
+		// to pass along "-gcflags="+os.Getenv("GO_GCFLAGS").
+		// For now, if $GO_GCFLAGS is set, report that we simply can't
+		// run go build.
+		return false
+	}
 	switch runtime.GOOS {
 	case "android", "nacl":
 		return false
@@ -47,7 +54,10 @@
 // MustHaveGoBuild checks that the current system can build programs with ``go build''
 // and then run them with os.StartProcess or exec.Command.
 // If not, MustHaveGoBuild calls t.Skip with an explanation.
-func MustHaveGoBuild(t *testing.T) {
+func MustHaveGoBuild(t testing.TB) {
+	if os.Getenv("GO_GCFLAGS") != "" {
+		t.Skipf("skipping test: 'go build' not compatible with setting $GO_GCFLAGS")
+	}
 	if !HasGoBuild() {
 		t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
@@ -61,7 +71,7 @@
 
 // MustHaveGoRun checks that the current system can run programs with ``go run.''
 // If not, MustHaveGoRun calls t.Skip with an explanation.
-func MustHaveGoRun(t *testing.T) {
+func MustHaveGoRun(t testing.TB) {
 	if !HasGoRun() {
 		t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
@@ -71,7 +81,7 @@
 // It is a convenience wrapper around GoTool.
 // If the tool is unavailable GoToolPath calls t.Skip.
 // If the tool should be available and isn't, GoToolPath calls t.Fatal.
-func GoToolPath(t *testing.T) string {
+func GoToolPath(t testing.TB) string {
 	MustHaveGoBuild(t)
 	path, err := GoTool()
 	if err != nil {
@@ -130,7 +140,7 @@
 // MustHaveExec checks that the current system can start new processes
 // using os.StartProcess or (more commonly) exec.Command.
 // If not, MustHaveExec calls t.Skip with an explanation.
-func MustHaveExec(t *testing.T) {
+func MustHaveExec(t testing.TB) {
 	if !HasExec() {
 		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
@@ -145,7 +155,7 @@
 // MustHaveExternalNetwork checks that the current system can use
 // external (non-localhost) networks.
 // If not, MustHaveExternalNetwork calls t.Skip with an explanation.
-func MustHaveExternalNetwork(t *testing.T) {
+func MustHaveExternalNetwork(t testing.TB) {
 	if testing.Short() {
 		t.Skipf("skipping test: no external network in -short mode")
 	}
@@ -153,8 +163,13 @@
 
 var haveCGO bool
 
+// HasCGO reports whether the current system can use cgo.
+func HasCGO() bool {
+	return haveCGO
+}
+
 // MustHaveCGO calls t.Skip if cgo is not available.
-func MustHaveCGO(t *testing.T) {
+func MustHaveCGO(t testing.TB) {
 	if !haveCGO {
 		t.Skipf("skipping test: no cgo")
 	}
@@ -168,7 +183,7 @@
 
 // MustHaveSymlink reports whether the current system can use os.Symlink.
 // If not, MustHaveSymlink calls t.Skip with an explanation.
-func MustHaveSymlink(t *testing.T) {
+func MustHaveSymlink(t testing.TB) {
 	ok, reason := hasSymlink()
 	if !ok {
 		t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason)
@@ -185,7 +200,7 @@
 
 // MustHaveLink reports whether the current system can use os.Link.
 // If not, MustHaveLink calls t.Skip with an explanation.
-func MustHaveLink(t *testing.T) {
+func MustHaveLink(t testing.TB) {
 	if !HasLink() {
 		t.Skipf("skipping test: hardlinks are not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
@@ -193,14 +208,38 @@
 
 var flaky = flag.Bool("flaky", false, "run known-flaky tests too")
 
-func SkipFlaky(t *testing.T, issue int) {
+func SkipFlaky(t testing.TB, issue int) {
+	t.Helper()
 	if !*flaky {
 		t.Skipf("skipping known flaky test without the -flaky flag; see golang.org/issue/%d", issue)
 	}
 }
 
-func SkipFlakyNet(t *testing.T) {
+func SkipFlakyNet(t testing.TB) {
+	t.Helper()
 	if v, _ := strconv.ParseBool(os.Getenv("GO_BUILDER_FLAKY_NET")); v {
 		t.Skip("skipping test on builder known to have frequent network failures")
 	}
 }
+
+// CleanCmdEnv will fill cmd.Env with the environment, excluding certain
+// variables that could modify the behavior of the Go tools such as
+// GODEBUG and GOTRACEBACK.
+func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd {
+	if cmd.Env != nil {
+		panic("environment already set")
+	}
+	for _, env := range os.Environ() {
+		// Exclude GODEBUG from the environment to prevent its output
+		// from breaking tests that are trying to parse other command output.
+		if strings.HasPrefix(env, "GODEBUG=") {
+			continue
+		}
+		// Exclude GOTRACEBACK for the same reason.
+		if strings.HasPrefix(env, "GOTRACEBACK=") {
+			continue
+		}
+		cmd.Env = append(cmd.Env, env)
+	}
+	return cmd
+}
diff --git a/src/internal/testenv/testenv_notwin.go b/src/internal/testenv/testenv_notwin.go
index d8ce6cd..3853973 100644
--- a/src/internal/testenv/testenv_notwin.go
+++ b/src/internal/testenv/testenv_notwin.go
@@ -18,3 +18,7 @@
 
 	return true, ""
 }
+
+func IsWindowsXP() bool {
+	return false
+}
diff --git a/src/internal/testenv/testenv_windows.go b/src/internal/testenv/testenv_windows.go
index eb8d6ac..4a7da5f 100644
--- a/src/internal/testenv/testenv_windows.go
+++ b/src/internal/testenv/testenv_windows.go
@@ -46,3 +46,12 @@
 
 	return false, ""
 }
+
+func IsWindowsXP() bool {
+	v, err := syscall.GetVersion()
+	if err != nil {
+		panic("GetVersion failed: " + err.Error())
+	}
+	major := byte(v)
+	return major < 6
+}
diff --git a/src/internal/testlog/log.go b/src/internal/testlog/log.go
new file mode 100644
index 0000000..3c5f780
--- /dev/null
+++ b/src/internal/testlog/log.go
@@ -0,0 +1,69 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package testlog provides a back-channel communication path
+// between tests and package os, so that cmd/go can see which
+// environment variables and files a test consults.
+package testlog
+
+import "sync/atomic"
+
+// Interface is the interface required of test loggers.
+// The os package will invoke the interface's methods to indicate that
+// it is inspecting the given environment variables or files.
+// Multiple goroutines may call these methods simultaneously.
+type Interface interface {
+	Getenv(key string)
+	Stat(file string)
+	Open(file string)
+	Chdir(dir string)
+}
+
+// logger is the current logger Interface.
+// We use an atomic.Value in case test startup
+// is racing with goroutines started during init.
+// That must not cause a race detector failure,
+// although it will still result in limited visibility
+// into exactly what those goroutines do.
+var logger atomic.Value
+
+// SetLogger sets the test logger implementation for the current process.
+// It must be called only once, at process startup.
+func SetLogger(impl Interface) {
+	if logger.Load() != nil {
+		panic("testlog: SetLogger must be called only once")
+	}
+	logger.Store(&impl)
+}
+
+// Logger returns the current test logger implementation.
+// It returns nil if there is no logger.
+func Logger() Interface {
+	impl := logger.Load()
+	if impl == nil {
+		return nil
+	}
+	return *impl.(*Interface)
+}
+
+// Getenv calls Logger().Getenv, if a logger has been set.
+func Getenv(name string) {
+	if log := Logger(); log != nil {
+		log.Getenv(name)
+	}
+}
+
+// Open calls Logger().Open, if a logger has been set.
+func Open(name string) {
+	if log := Logger(); log != nil {
+		log.Open(name)
+	}
+}
+
+// Stat calls Logger().Stat, if a logger has been set.
+func Stat(name string) {
+	if log := Logger(); log != nil {
+		log.Stat(name)
+	}
+}
diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go
index 1dd3ef1..c7954f0 100644
--- a/src/internal/trace/parser.go
+++ b/src/internal/trace/parser.go
@@ -12,11 +12,25 @@
 	"math/rand"
 	"os"
 	"os/exec"
+	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 	_ "unsafe"
 )
 
+func goCmd() string {
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
+	if _, err := os.Stat(path); err == nil {
+		return path
+	}
+	return "go"
+}
+
 // Event describes one event in the trace.
 type Event struct {
 	Off   int       // offset in input file (for debugging and error reporting)
@@ -31,7 +45,7 @@
 	SArgs []string  // event-type-specific string args
 	// linked event (can be nil), depends on event type:
 	// for GCStart: the GCStop
-	// for GCScanStart: the GCScanDone
+	// for GCSTWStart: the GCSTWDone
 	// for GCSweepStart: the GCSweepDone
 	// for GoCreate: first GoStart of the created goroutine
 	// for GoStart/GoStartLabel: the associated GoEnd, GoBlock or other blocking event
@@ -61,36 +75,44 @@
 	GCP      // depicts GC state
 )
 
+// ParseResult is the result of Parse.
+type ParseResult struct {
+	// Events is the sorted list of Events in the trace.
+	Events []*Event
+	// Stacks is the stack traces keyed by stack IDs from the trace.
+	Stacks map[uint64][]*Frame
+}
+
 // Parse parses, post-processes and verifies the trace.
-func Parse(r io.Reader, bin string) ([]*Event, error) {
-	ver, events, err := parse(r, bin)
+func Parse(r io.Reader, bin string) (ParseResult, error) {
+	ver, res, err := parse(r, bin)
 	if err != nil {
-		return nil, err
+		return ParseResult{}, err
 	}
 	if ver < 1007 && bin == "" {
-		return nil, fmt.Errorf("for traces produced by go 1.6 or below, the binary argument must be provided")
+		return ParseResult{}, fmt.Errorf("for traces produced by go 1.6 or below, the binary argument must be provided")
 	}
-	return events, nil
+	return res, nil
 }
 
 // parse parses, post-processes and verifies the trace. It returns the
 // trace version and the list of events.
-func parse(r io.Reader, bin string) (int, []*Event, error) {
+func parse(r io.Reader, bin string) (int, ParseResult, error) {
 	ver, rawEvents, strings, err := readTrace(r)
 	if err != nil {
-		return 0, nil, err
+		return 0, ParseResult{}, err
 	}
 	events, stacks, err := parseEvents(ver, rawEvents, strings)
 	if err != nil {
-		return 0, nil, err
+		return 0, ParseResult{}, err
 	}
 	events, err = removeFutile(events)
 	if err != nil {
-		return 0, nil, err
+		return 0, ParseResult{}, err
 	}
 	err = postProcessTrace(ver, events)
 	if err != nil {
-		return 0, nil, err
+		return 0, ParseResult{}, err
 	}
 	// Attach stack traces.
 	for _, ev := range events {
@@ -100,10 +122,10 @@
 	}
 	if ver < 1007 && bin != "" {
 		if err := symbolize(events, bin); err != nil {
-			return 0, nil, err
+			return 0, ParseResult{}, err
 		}
 	}
-	return ver, events, nil
+	return ver, ParseResult{Events: events, Stacks: stacks}, nil
 }
 
 // rawEvent is a helper type used during parsing.
@@ -128,7 +150,7 @@
 		return
 	}
 	switch ver {
-	case 1005, 1007, 1008, 1009:
+	case 1005, 1007, 1008, 1009, 1010:
 		// Note: When adding a new version, add canned traces
 		// from the old version to the test suite using mkcanned.bash.
 		break
@@ -270,8 +292,9 @@
 // It does analyze and verify per-event-type arguments.
 func parseEvents(ver int, rawEvents []rawEvent, strings map[uint64]string) (events []*Event, stacks map[uint64][]*Frame, err error) {
 	var ticksPerSec, lastSeq, lastTs int64
-	var lastG, timerGoid uint64
+	var lastG uint64
 	var lastP int
+	timerGoids := make(map[uint64]bool)
 	lastGs := make(map[int]uint64) // last goroutine running on P
 	stacks = make(map[uint64][]*Frame)
 	batches := make(map[int][]*Event) // events by P
@@ -308,7 +331,7 @@
 				return
 			}
 		case EvTimerGoroutine:
-			timerGoid = raw.args[0]
+			timerGoids[raw.args[0]] = true
 		case EvStack:
 			if len(raw.args) < 2 {
 				err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want at least 2, got %v",
@@ -373,7 +396,18 @@
 				if raw.typ == EvGoStartLabel {
 					e.SArgs = []string{strings[e.Args[2]]}
 				}
-			case EvGCStart, EvGCDone, EvGCScanStart, EvGCScanDone:
+			case EvGCSTWStart:
+				e.G = 0
+				switch e.Args[0] {
+				case 0:
+					e.SArgs = []string{"mark termination"}
+				case 1:
+					e.SArgs = []string{"sweep termination"}
+				default:
+					err = fmt.Errorf("unknown STW kind %d", e.Args[0])
+					return
+				}
+			case EvGCStart, EvGCDone, EvGCSTWDone:
 				e.G = 0
 			case EvGoEnd, EvGoStop, EvGoSched, EvGoPreempt,
 				EvGoSleep, EvGoBlock, EvGoBlockSend, EvGoBlockRecv,
@@ -420,7 +454,7 @@
 	for _, ev := range events {
 		ev.Ts = int64(float64(ev.Ts-minTs) * freq)
 		// Move timers and syscalls to separate fake Ps.
-		if timerGoid != 0 && ev.G == timerGoid && ev.Type == EvGoUnblock {
+		if timerGoids[ev.G] && ev.Type == EvGoUnblock {
 			ev.P = TimerP
 		}
 		if ev.Type == EvGoSysExit {
@@ -511,14 +545,14 @@
 	type pdesc struct {
 		running bool
 		g       uint64
-		evScan  *Event
+		evSTW   *Event
 		evSweep *Event
 	}
 
 	gs := make(map[uint64]gdesc)
 	ps := make(map[int]pdesc)
 	gs[0] = gdesc{state: gRunning}
-	var evGC *Event
+	var evGC, evSTW *Event
 
 	checkRunning := func(p pdesc, g gdesc, ev *Event, allowG0 bool) error {
 		name := EventDescriptions[ev.Type].Name
@@ -565,17 +599,27 @@
 			}
 			evGC.Link = ev
 			evGC = nil
-		case EvGCScanStart:
-			if p.evScan != nil {
-				return fmt.Errorf("previous scanning is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
+		case EvGCSTWStart:
+			evp := &evSTW
+			if ver < 1010 {
+				// Before 1.10, EvGCSTWStart was per-P.
+				evp = &p.evSTW
 			}
-			p.evScan = ev
-		case EvGCScanDone:
-			if p.evScan == nil {
-				return fmt.Errorf("bogus scanning end (offset %v, time %v)", ev.Off, ev.Ts)
+			if *evp != nil {
+				return fmt.Errorf("previous STW is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
 			}
-			p.evScan.Link = ev
-			p.evScan = nil
+			*evp = ev
+		case EvGCSTWDone:
+			evp := &evSTW
+			if ver < 1010 {
+				// Before 1.10, EvGCSTWDone was per-P.
+				evp = &p.evSTW
+			}
+			if *evp == nil {
+				return fmt.Errorf("bogus STW end (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			(*evp).Link = ev
+			*evp = nil
 		case EvGCSweepStart:
 			if p.evSweep != nil {
 				return fmt.Errorf("previous sweeping is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
@@ -735,7 +779,7 @@
 	}
 
 	// Start addr2line.
-	cmd := exec.Command("go", "tool", "addr2line", bin)
+	cmd := exec.Command(goCmd(), "tool", "addr2line", bin)
 	in, err := cmd.StdinPipe()
 	if err != nil {
 		return fmt.Errorf("failed to pipe addr2line stdin: %v", err)
@@ -864,6 +908,10 @@
 		if ver < 1007 {
 			narg-- // 1.7 added an additional seq arg
 		}
+	case EvGCSTWStart:
+		if ver < 1010 {
+			narg-- // 1.10 added an argument
+		}
 	}
 	return narg
 }
@@ -883,8 +931,8 @@
 	EvProcStop          = 6  // stop of P [timestamp]
 	EvGCStart           = 7  // GC start [timestamp, seq, stack id]
 	EvGCDone            = 8  // GC done [timestamp]
-	EvGCScanStart       = 9  // GC mark termination start [timestamp]
-	EvGCScanDone        = 10 // GC mark termination done [timestamp]
+	EvGCSTWStart        = 9  // GC mark termination start [timestamp, kind]
+	EvGCSTWDone         = 10 // GC mark termination done [timestamp]
 	EvGCSweepStart      = 11 // GC sweep start [timestamp, stack id]
 	EvGCSweepDone       = 12 // GC sweep done [timestamp, swept, reclaimed]
 	EvGoCreate          = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
@@ -937,8 +985,8 @@
 	EvProcStop:          {"ProcStop", 1005, false, []string{}},
 	EvGCStart:           {"GCStart", 1005, true, []string{"seq"}}, // in 1.5 format it was {}
 	EvGCDone:            {"GCDone", 1005, false, []string{}},
-	EvGCScanStart:       {"GCScanStart", 1005, false, []string{}},
-	EvGCScanDone:        {"GCScanDone", 1005, false, []string{}},
+	EvGCSTWStart:        {"GCSTWStart", 1005, false, []string{"kind"}}, // <= 1.9, args was {} (implicitly {0})
+	EvGCSTWDone:         {"GCSTWDone", 1005, false, []string{}},
 	EvGCSweepStart:      {"GCSweepStart", 1005, true, []string{}},
 	EvGCSweepDone:       {"GCSweepDone", 1005, false, []string{"swept", "reclaimed"}}, // before 1.9, format was {}
 	EvGoCreate:          {"GoCreate", 1005, true, []string{"g", "stack"}},
diff --git a/src/internal/trace/parser_test.go b/src/internal/trace/parser_test.go
index d6f580a..c9afa68 100644
--- a/src/internal/trace/parser_test.go
+++ b/src/internal/trace/parser_test.go
@@ -25,8 +25,8 @@
 		"go 1.5 trace\x00\x00\x00\x00\xc3\x0200",
 	}
 	for _, data := range tests {
-		events, err := Parse(strings.NewReader(data), "")
-		if err == nil || events != nil {
+		res, err := Parse(strings.NewReader(data), "")
+		if err == nil || res.Events != nil || res.Stacks != nil {
 			t.Fatalf("no error on input: %q", data)
 		}
 	}
diff --git a/src/internal/trace/testdata/http_1_10_good b/src/internal/trace/testdata/http_1_10_good
new file mode 100644
index 0000000..a4f2ed8
--- /dev/null
+++ b/src/internal/trace/testdata/http_1_10_good
Binary files differ
diff --git a/src/internal/trace/testdata/stress_1_10_good b/src/internal/trace/testdata/stress_1_10_good
new file mode 100644
index 0000000..19778b0
--- /dev/null
+++ b/src/internal/trace/testdata/stress_1_10_good
Binary files differ
diff --git a/src/internal/trace/testdata/stress_start_stop_1_10_good b/src/internal/trace/testdata/stress_start_stop_1_10_good
new file mode 100644
index 0000000..b908e10
--- /dev/null
+++ b/src/internal/trace/testdata/stress_start_stop_1_10_good
Binary files differ
diff --git a/src/io/example_test.go b/src/io/example_test.go
index af47853..edcd008 100644
--- a/src/io/example_test.go
+++ b/src/io/example_test.go
@@ -243,3 +243,19 @@
 	// some io.Reader stream to be read
 	// some io.Reader stream to be read
 }
+
+func ExamplePipe() {
+	r, w := io.Pipe()
+
+	go func() {
+		fmt.Fprint(w, "some text to be read\n")
+		w.Close()
+	}()
+
+	buf := new(bytes.Buffer)
+	buf.ReadFrom(r)
+	fmt.Print(buf.String())
+
+	// Output:
+	// some text to be read
+}
diff --git a/src/io/io.go b/src/io/io.go
index 28dab08..27482de 100644
--- a/src/io/io.go
+++ b/src/io/io.go
@@ -385,8 +385,16 @@
 	if rt, ok := dst.(ReaderFrom); ok {
 		return rt.ReadFrom(src)
 	}
+	size := 32 * 1024
+	if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
+		if l.N < 1 {
+			size = 1
+		} else {
+			size = int(l.N)
+		}
+	}
 	if buf == nil {
-		buf = make([]byte, 32*1024)
+		buf = make([]byte, size)
 	}
 	for {
 		nr, er := src.Read(buf)
diff --git a/src/io/io_test.go b/src/io/io_test.go
index 877e839..0e4ce61 100644
--- a/src/io/io_test.go
+++ b/src/io/io_test.go
@@ -32,6 +32,21 @@
 	}
 }
 
+func TestCopyNegative(t *testing.T) {
+	rb := new(Buffer)
+	wb := new(Buffer)
+	rb.WriteString("hello")
+	Copy(wb, &LimitedReader{R: rb, N: -1})
+	if wb.String() != "" {
+		t.Errorf("Copy on LimitedReader with N<0 copied data")
+	}
+
+	CopyN(wb, rb, -1)
+	if wb.String() != "" {
+		t.Errorf("CopyN with N<0 copied data")
+	}
+}
+
 func TestCopyBuffer(t *testing.T) {
 	rb := new(Buffer)
 	wb := new(Buffer)
@@ -156,6 +171,30 @@
 	}
 }
 
+func BenchmarkCopyNSmall(b *testing.B) {
+	bs := bytes.Repeat([]byte{0}, 512+1)
+	rd := bytes.NewReader(bs)
+	buf := new(Buffer)
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		CopyN(buf, rd, 512)
+		rd.Reset(bs)
+	}
+}
+
+func BenchmarkCopyNLarge(b *testing.B) {
+	bs := bytes.Repeat([]byte{0}, (32*1024)+1)
+	rd := bytes.NewReader(bs)
+	buf := new(Buffer)
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		CopyN(buf, rd, 32*1024)
+		rd.Reset(bs)
+	}
+}
+
 type noReadFrom struct {
 	w Writer
 }
diff --git a/src/io/ioutil/ioutil.go b/src/io/ioutil/ioutil.go
index f0da616..674b270 100644
--- a/src/io/ioutil/ioutil.go
+++ b/src/io/ioutil/ioutil.go
@@ -16,7 +16,7 @@
 // readAll reads from r until an error or EOF and returns the data it read
 // from the internal buffer allocated with a specified capacity.
 func readAll(r io.Reader, capacity int64) (b []byte, err error) {
-	buf := bytes.NewBuffer(make([]byte, 0, capacity))
+	var buf bytes.Buffer
 	// If the buffer overflows, we will get bytes.ErrTooLarge.
 	// Return that as an error. Any other panic remains.
 	defer func() {
@@ -30,6 +30,9 @@
 			panic(e)
 		}
 	}()
+	if int64(int(capacity)) == capacity {
+		buf.Grow(int(capacity))
+	}
 	_, err = buf.ReadFrom(r)
 	return buf.Bytes(), err
 }
@@ -54,20 +57,20 @@
 	defer f.Close()
 	// It's a good but not certain bet that FileInfo will tell us exactly how much to
 	// read, so let's try it but be prepared for the answer to be wrong.
-	var n int64
+	var n int64 = bytes.MinRead
 
 	if fi, err := f.Stat(); err == nil {
-		// Don't preallocate a huge buffer, just in case.
-		if size := fi.Size(); size < 1e9 {
+		// As initial capacity for readAll, use Size + a little extra in case Size
+		// is zero, and to avoid another allocation after Read has filled the
+		// buffer. The readAll call will read into its allocated internal buffer
+		// cheaply. If the size was wrong, we'll either waste some space off the end
+		// or reallocate as needed, but in the overwhelmingly common case we'll get
+		// it just right.
+		if size := fi.Size() + bytes.MinRead; size > n {
 			n = size
 		}
 	}
-	// As initial capacity for readAll, use n + a little extra in case Size is zero,
-	// and to avoid another allocation after Read has filled the buffer. The readAll
-	// call will read into its allocated internal buffer cheaply. If the size was
-	// wrong, we'll either waste some space off the end or reallocate as needed, but
-	// in the overwhelmingly common case we'll get it just right.
-	return readAll(f, n+bytes.MinRead)
+	return readAll(f, n)
 }
 
 // WriteFile writes data to a file named by filename.
diff --git a/src/io/multi.go b/src/io/multi.go
index d784846..65f9909 100644
--- a/src/io/multi.go
+++ b/src/io/multi.go
@@ -95,8 +95,18 @@
 
 // MultiWriter creates a writer that duplicates its writes to all the
 // provided writers, similar to the Unix tee(1) command.
+//
+// Each write is written to each listed writer, one at a time.
+// If a listed writer returns an error, that overall write operation
+// stops and returns the error; it does not continue down the list.
 func MultiWriter(writers ...Writer) Writer {
-	w := make([]Writer, len(writers))
-	copy(w, writers)
-	return &multiWriter{w}
+	allWriters := make([]Writer, 0, len(writers))
+	for _, w := range writers {
+		if mw, ok := w.(*multiWriter); ok {
+			allWriters = append(allWriters, mw.writers...)
+		} else {
+			allWriters = append(allWriters, w)
+		}
+	}
+	return &multiWriter{allWriters}
 }
diff --git a/src/io/multi_test.go b/src/io/multi_test.go
index 0a7eb43..9cbab4d 100644
--- a/src/io/multi_test.go
+++ b/src/io/multi_test.go
@@ -142,6 +142,55 @@
 	}
 }
 
+// writerFunc is an io.Writer implemented by the underlying func.
+type writerFunc func(p []byte) (int, error)
+
+func (f writerFunc) Write(p []byte) (int, error) {
+	return f(p)
+}
+
+// Test that MultiWriter properly flattens chained multiWriters,
+func TestMultiWriterSingleChainFlatten(t *testing.T) {
+	pc := make([]uintptr, 1000) // 1000 should fit the full stack
+	n := runtime.Callers(0, pc)
+	var myDepth = callDepth(pc[:n])
+	var writeDepth int // will contain the depth from which writerFunc.Writer was called
+	var w Writer = MultiWriter(writerFunc(func(p []byte) (int, error) {
+		n := runtime.Callers(1, pc)
+		writeDepth += callDepth(pc[:n])
+		return 0, nil
+	}))
+
+	mw := w
+	// chain a bunch of multiWriters
+	for i := 0; i < 100; i++ {
+		mw = MultiWriter(w)
+	}
+
+	mw = MultiWriter(w, mw, w, mw)
+	mw.Write(nil) // don't care about errors, just want to check the call-depth for Write
+
+	if writeDepth != 4*(myDepth+2) { // 2 should be multiWriter.Write and writerFunc.Write
+		t.Errorf("multiWriter did not flatten chained multiWriters: expected writeDepth %d, got %d",
+			4*(myDepth+2), writeDepth)
+	}
+}
+
+func TestMultiWriterError(t *testing.T) {
+	f1 := writerFunc(func(p []byte) (int, error) {
+		return len(p) / 2, ErrShortWrite
+	})
+	f2 := writerFunc(func(p []byte) (int, error) {
+		t.Errorf("MultiWriter called f2.Write")
+		return len(p), nil
+	})
+	w := MultiWriter(f1, f2)
+	n, err := w.Write(make([]byte, 100))
+	if n != 50 || err != ErrShortWrite {
+		t.Errorf("Write = %d, %v, want 50, ErrShortWrite", n, err)
+	}
+}
+
 // Test that MultiReader copies the input slice and is insulated from future modification.
 func TestMultiReaderCopy(t *testing.T) {
 	slice := []Reader{strings.NewReader("hello world")}
diff --git a/src/io/pipe.go b/src/io/pipe.go
index b6e7755..4efaf2f 100644
--- a/src/io/pipe.go
+++ b/src/io/pipe.go
@@ -10,110 +10,107 @@
 import (
 	"errors"
 	"sync"
+	"sync/atomic"
 )
 
+// atomicError is a type-safe atomic value for errors.
+// We use a struct{ error } to ensure consistent use of a concrete type.
+type atomicError struct{ v atomic.Value }
+
+func (a *atomicError) Store(err error) {
+	a.v.Store(struct{ error }{err})
+}
+func (a *atomicError) Load() error {
+	err, _ := a.v.Load().(struct{ error })
+	return err.error
+}
+
 // ErrClosedPipe is the error used for read or write operations on a closed pipe.
 var ErrClosedPipe = errors.New("io: read/write on closed pipe")
 
 // A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
 type pipe struct {
-	rl    sync.Mutex // gates readers one at a time
-	wl    sync.Mutex // gates writers one at a time
-	l     sync.Mutex // protects remaining fields
-	data  []byte     // data remaining in pending write
-	rwait sync.Cond  // waiting reader
-	wwait sync.Cond  // waiting writer
-	rerr  error      // if reader closed, error to give writes
-	werr  error      // if writer closed, error to give reads
+	wrMu sync.Mutex // Serializes Write operations
+	wrCh chan []byte
+	rdCh chan int
+
+	once sync.Once // Protects closing done
+	done chan struct{}
+	rerr atomicError
+	werr atomicError
 }
 
-func (p *pipe) read(b []byte) (n int, err error) {
-	// One reader at a time.
-	p.rl.Lock()
-	defer p.rl.Unlock()
+func (p *pipe) Read(b []byte) (n int, err error) {
+	select {
+	case <-p.done:
+		return 0, p.readCloseError()
+	default:
+	}
 
-	p.l.Lock()
-	defer p.l.Unlock()
-	for {
-		if p.rerr != nil {
-			return 0, ErrClosedPipe
-		}
-		if p.data != nil {
-			break
-		}
-		if p.werr != nil {
-			return 0, p.werr
-		}
-		p.rwait.Wait()
+	select {
+	case bw := <-p.wrCh:
+		nr := copy(b, bw)
+		p.rdCh <- nr
+		return nr, nil
+	case <-p.done:
+		return 0, p.readCloseError()
 	}
-	n = copy(b, p.data)
-	p.data = p.data[n:]
-	if len(p.data) == 0 {
-		p.data = nil
-		p.wwait.Signal()
-	}
-	return
 }
 
-var zero [0]byte
-
-func (p *pipe) write(b []byte) (n int, err error) {
-	// pipe uses nil to mean not available
-	if b == nil {
-		b = zero[:]
+func (p *pipe) readCloseError() error {
+	rerr := p.rerr.Load()
+	if werr := p.werr.Load(); rerr == nil && werr != nil {
+		return werr
 	}
-
-	// One writer at a time.
-	p.wl.Lock()
-	defer p.wl.Unlock()
-
-	p.l.Lock()
-	defer p.l.Unlock()
-	if p.werr != nil {
-		err = ErrClosedPipe
-		return
-	}
-	p.data = b
-	p.rwait.Signal()
-	for {
-		if p.data == nil {
-			break
-		}
-		if p.rerr != nil {
-			err = p.rerr
-			break
-		}
-		if p.werr != nil {
-			err = ErrClosedPipe
-			break
-		}
-		p.wwait.Wait()
-	}
-	n = len(b) - len(p.data)
-	p.data = nil // in case of rerr or werr
-	return
+	return ErrClosedPipe
 }
 
-func (p *pipe) rclose(err error) {
+func (p *pipe) CloseRead(err error) error {
 	if err == nil {
 		err = ErrClosedPipe
 	}
-	p.l.Lock()
-	defer p.l.Unlock()
-	p.rerr = err
-	p.rwait.Signal()
-	p.wwait.Signal()
+	p.rerr.Store(err)
+	p.once.Do(func() { close(p.done) })
+	return nil
 }
 
-func (p *pipe) wclose(err error) {
+func (p *pipe) Write(b []byte) (n int, err error) {
+	select {
+	case <-p.done:
+		return 0, p.writeCloseError()
+	default:
+		p.wrMu.Lock()
+		defer p.wrMu.Unlock()
+	}
+
+	for once := true; once || len(b) > 0; once = false {
+		select {
+		case p.wrCh <- b:
+			nw := <-p.rdCh
+			b = b[nw:]
+			n += nw
+		case <-p.done:
+			return n, p.writeCloseError()
+		}
+	}
+	return n, nil
+}
+
+func (p *pipe) writeCloseError() error {
+	werr := p.werr.Load()
+	if rerr := p.rerr.Load(); werr == nil && rerr != nil {
+		return rerr
+	}
+	return ErrClosedPipe
+}
+
+func (p *pipe) CloseWrite(err error) error {
 	if err == nil {
 		err = EOF
 	}
-	p.l.Lock()
-	defer p.l.Unlock()
-	p.werr = err
-	p.rwait.Signal()
-	p.wwait.Signal()
+	p.werr.Store(err)
+	p.once.Do(func() { close(p.done) })
+	return nil
 }
 
 // A PipeReader is the read half of a pipe.
@@ -127,7 +124,7 @@
 // If the write end is closed with an error, that error is
 // returned as err; otherwise err is EOF.
 func (r *PipeReader) Read(data []byte) (n int, err error) {
-	return r.p.read(data)
+	return r.p.Read(data)
 }
 
 // Close closes the reader; subsequent writes to the
@@ -139,8 +136,7 @@
 // CloseWithError closes the reader; subsequent writes
 // to the write half of the pipe will return the error err.
 func (r *PipeReader) CloseWithError(err error) error {
-	r.p.rclose(err)
-	return nil
+	return r.p.CloseRead(err)
 }
 
 // A PipeWriter is the write half of a pipe.
@@ -154,7 +150,7 @@
 // If the read end is closed with an error, that err is
 // returned as err; otherwise err is ErrClosedPipe.
 func (w *PipeWriter) Write(data []byte) (n int, err error) {
-	return w.p.write(data)
+	return w.p.Write(data)
 }
 
 // Close closes the writer; subsequent reads from the
@@ -169,8 +165,7 @@
 //
 // CloseWithError always returns nil.
 func (w *PipeWriter) CloseWithError(err error) error {
-	w.p.wclose(err)
-	return nil
+	return w.p.CloseWrite(err)
 }
 
 // Pipe creates a synchronous in-memory pipe.
@@ -189,10 +184,10 @@
 // Parallel calls to Read and parallel calls to Write are also safe:
 // the individual calls will be gated sequentially.
 func Pipe() (*PipeReader, *PipeWriter) {
-	p := new(pipe)
-	p.rwait.L = &p.l
-	p.wwait.L = &p.l
-	r := &PipeReader{p}
-	w := &PipeWriter{p}
-	return r, w
+	p := &pipe{
+		wrCh: make(chan []byte),
+		rdCh: make(chan int),
+		done: make(chan struct{}),
+	}
+	return &PipeReader{p}, &PipeWriter{p}
 }
diff --git a/src/io/pipe_test.go b/src/io/pipe_test.go
index 95930e8..f18b1c4 100644
--- a/src/io/pipe_test.go
+++ b/src/io/pipe_test.go
@@ -5,8 +5,11 @@
 package io_test
 
 import (
+	"bytes"
 	"fmt"
 	. "io"
+	"sort"
+	"strings"
 	"testing"
 	"time"
 )
@@ -312,3 +315,109 @@
 		t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe)
 	}
 }
+
+func TestPipeCloseError(t *testing.T) {
+	type testError1 struct{ error }
+	type testError2 struct{ error }
+
+	r, w := Pipe()
+	r.CloseWithError(testError1{})
+	if _, err := w.Write(nil); err != (testError1{}) {
+		t.Errorf("Write error: got %T, want testError1", err)
+	}
+	r.CloseWithError(testError2{})
+	if _, err := w.Write(nil); err != (testError2{}) {
+		t.Errorf("Write error: got %T, want testError2", err)
+	}
+
+	r, w = Pipe()
+	w.CloseWithError(testError1{})
+	if _, err := r.Read(nil); err != (testError1{}) {
+		t.Errorf("Read error: got %T, want testError1", err)
+	}
+	w.CloseWithError(testError2{})
+	if _, err := r.Read(nil); err != (testError2{}) {
+		t.Errorf("Read error: got %T, want testError2", err)
+	}
+}
+
+func TestPipeConcurrent(t *testing.T) {
+	const (
+		input    = "0123456789abcdef"
+		count    = 8
+		readSize = 2
+	)
+
+	t.Run("Write", func(t *testing.T) {
+		r, w := Pipe()
+
+		for i := 0; i < count; i++ {
+			go func() {
+				time.Sleep(time.Millisecond) // Increase probability of race
+				if n, err := w.Write([]byte(input)); n != len(input) || err != nil {
+					t.Errorf("Write() = (%d, %v); want (%d, nil)", n, err, len(input))
+				}
+			}()
+		}
+
+		buf := make([]byte, count*len(input))
+		for i := 0; i < len(buf); i += readSize {
+			if n, err := r.Read(buf[i : i+readSize]); n != readSize || err != nil {
+				t.Errorf("Read() = (%d, %v); want (%d, nil)", n, err, readSize)
+			}
+		}
+
+		// Since each Write is fully gated, if multiple Read calls were needed,
+		// the contents of Write should still appear together in the output.
+		got := string(buf)
+		want := strings.Repeat(input, count)
+		if got != want {
+			t.Errorf("got: %q; want: %q", got, want)
+		}
+	})
+
+	t.Run("Read", func(t *testing.T) {
+		r, w := Pipe()
+
+		c := make(chan []byte, count*len(input)/readSize)
+		for i := 0; i < cap(c); i++ {
+			go func() {
+				time.Sleep(time.Millisecond) // Increase probability of race
+				buf := make([]byte, readSize)
+				if n, err := r.Read(buf); n != readSize || err != nil {
+					t.Errorf("Read() = (%d, %v); want (%d, nil)", n, err, readSize)
+				}
+				c <- buf
+			}()
+		}
+
+		for i := 0; i < count; i++ {
+			if n, err := w.Write([]byte(input)); n != len(input) || err != nil {
+				t.Errorf("Write() = (%d, %v); want (%d, nil)", n, err, len(input))
+			}
+		}
+
+		// Since each read is independent, the only guarantee about the output
+		// is that it is a permutation of the input in readSized groups.
+		got := make([]byte, 0, count*len(input))
+		for i := 0; i < cap(c); i++ {
+			got = append(got, (<-c)...)
+		}
+		got = sortBytesInGroups(got, readSize)
+		want := bytes.Repeat([]byte(input), count)
+		want = sortBytesInGroups(want, readSize)
+		if string(got) != string(want) {
+			t.Errorf("got: %q; want: %q", got, want)
+		}
+	})
+}
+
+func sortBytesInGroups(b []byte, n int) []byte {
+	var groups [][]byte
+	for len(b) > 0 {
+		groups = append(groups, b[:n])
+		b = b[n:]
+	}
+	sort.Slice(groups, func(i, j int) bool { return bytes.Compare(groups[i], groups[j]) < 0 })
+	return bytes.Join(groups, nil)
+}
diff --git a/src/iostest.bash b/src/iostest.bash
index 595b675..00cc49e 100755
--- a/src/iostest.bash
+++ b/src/iostest.bash
@@ -32,11 +32,15 @@
 	# Reboot to make sure previous runs do not interfere with the current run.
 	# It is reasonably easy for a bad program leave an iOS device in an
 	# almost unusable state.
-	idevicediagnostics restart
+	IDEVARGS=
+	if [ -n "$GOIOS_DEVICE_ID" ]; then
+		IDEVARGS="-u $GOIOS_DEVICE_ID"
+	fi
+	idevicediagnostics $IDEVARGS restart
 	# Initial sleep to make sure we are restarting before we start polling.
 	sleep 30
 	# Poll until the device has restarted.
-	until idevicediagnostics diagnostics; do
+	until idevicediagnostics $IDEVARGS diagnostics; do
 		# TODO(crawshaw): replace with a test app using go_darwin_arm_exec.
 		echo "waiting for idevice to come online"
 		sleep 10
diff --git a/src/log/log.go b/src/log/log.go
index 587904b..2b7c57f 100644
--- a/src/log/log.go
+++ b/src/log/log.go
@@ -24,16 +24,16 @@
 )
 
 // These flags define which text to prefix to each log entry generated by the Logger.
+// Bits are or'ed together to control what's printed.
+// There is no control over the order they appear (the order listed
+// here) or the format they present (as described in the comments).
+// The prefix is followed by a colon only when Llongfile or Lshortfile
+// is specified.
+// For example, flags Ldate | Ltime (or LstdFlags) produce,
+//	2009/01/23 01:23:23 message
+// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
+//	2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
 const (
-	// Bits or'ed together to control what's printed.
-	// There is no control over the order they appear (the order listed
-	// here) or the format they present (as described in the comments).
-	// The prefix is followed by a colon only when Llongfile or Lshortfile
-	// is specified.
-	// For example, flags Ldate | Ltime (or LstdFlags) produce,
-	//	2009/01/23 01:23:23 message
-	// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
-	//	2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
 	Ldate         = 1 << iota     // the date in the local time zone: 2009/01/23
 	Ltime                         // the time in the local time zone: 01:23:23
 	Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
@@ -147,11 +147,7 @@
 // provided for generality, although at the moment on all pre-defined
 // paths it will be 2.
 func (l *Logger) Output(calldepth int, s string) error {
-	// Get time early if we need it.
-	var now time.Time
-	if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
-		now = time.Now()
-	}
+	now := time.Now() // get this early.
 	var file string
 	var line int
 	l.mu.Lock()
diff --git a/src/log/log_test.go b/src/log/log_test.go
index 966fdf3..adc15e7 100644
--- a/src/log/log_test.go
+++ b/src/log/log_test.go
@@ -88,6 +88,17 @@
 	}
 }
 
+func TestOutputRace(t *testing.T) {
+	var b bytes.Buffer
+	l := New(&b, "", 0)
+	for i := 0; i < 100; i++ {
+		go func() {
+			l.SetFlags(0)
+		}()
+		l.Output(0, "")
+	}
+}
+
 func TestFlagAndPrefixSetting(t *testing.T) {
 	var b bytes.Buffer
 	l := New(&b, "Test:", LstdFlags)
diff --git a/src/log/syslog/syslog_unix.go b/src/log/syslog/syslog_unix.go
index 1cdabec..6c17e1f 100644
--- a/src/log/syslog/syslog_unix.go
+++ b/src/log/syslog/syslog_unix.go
@@ -20,9 +20,7 @@
 	for _, network := range logTypes {
 		for _, path := range logPaths {
 			conn, err := net.Dial(network, path)
-			if err != nil {
-				continue
-			} else {
+			if err == nil {
 				return &netConn{conn: conn, local: true}, nil
 			}
 		}
diff --git a/src/make.bash b/src/make.bash
index 71e7531..93a5c43 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -50,6 +50,15 @@
 # PKG_CONFIG: Path to pkg-config tool. Default is "pkg-config".
 #
 # GO_DISTFLAGS: extra flags to provide to "dist bootstrap".
+# (Or just pass them to the make.bash command line.)
+#
+# GOBUILDTIMELOGFILE: If set, make.bash and all.bash write
+# timing information to this file. Useful for profiling where the
+# time goes when these scripts run.
+#
+# GOROOT_BOOTSTRAP: A working Go tree >= Go 1.4 for bootstrap.
+# If $GOROOT_BOOTSTRAP/bin/go is missing, $(go env GOROOT) is
+# tried for all "go" in $PATH. $HOME/go1.4 by default.
 
 set -e
 
@@ -60,6 +69,10 @@
 	exit 1
 fi
 
+if [ "$GOBUILDTIMELOGFILE" != "" ]; then
+	echo $(LC_TIME=C date) start make.bash >"$GOBUILDTIMELOGFILE"
+fi
+
 # Test for Windows.
 case "$(uname)" in
 *MINGW* | *WIN32* | *CYGWIN*)
@@ -116,10 +129,28 @@
 
 # Finally!  Run the build.
 
-echo '##### Building Go bootstrap tool.'
-echo cmd/dist
+verbose=false
+vflag=""
+if [ "$1" = "-v" ]; then
+	verbose=true
+	vflag=-v
+	shift
+fi
+
+export GOROOT_BOOTSTRAP=${GOROOT_BOOTSTRAP:-$HOME/go1.4}
 export GOROOT="$(cd .. && pwd)"
-GOROOT_BOOTSTRAP=${GOROOT_BOOTSTRAP:-$HOME/go1.4}
+IFS=$'\n'; for go_exe in $(type -ap go); do
+	if [ ! -x "$GOROOT_BOOTSTRAP/bin/go" ]; then
+		goroot=$(GOROOT='' "$go_exe" env GOROOT)
+		if [ "$goroot" != "$GOROOT" ]; then
+			GOROOT_BOOTSTRAP=$goroot
+		fi
+	fi
+done; unset IFS
+echo "Building Go cmd/dist using $GOROOT_BOOTSTRAP."
+if $verbose; then
+	echo cmd/dist
+fi
 if [ ! -x "$GOROOT_BOOTSTRAP/bin/go" ]; then
 	echo "ERROR: Cannot find $GOROOT_BOOTSTRAP/bin/go." >&2
 	echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
@@ -139,7 +170,9 @@
 	exit 1
 fi
 
-echo
+if $verbose; then
+	echo
+fi
 
 if [ "$1" = "--dist-tool" ]; then
 	# Stop after building dist tool.
@@ -156,40 +189,15 @@
 	buildall=""
 	shift
 fi
-./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -v # builds go_bootstrap
 
-# Delay move of dist tool to now, because bootstrap may clear tool directory.
-mv cmd/dist/dist "$GOTOOLDIR"/dist
-echo
+# Run dist bootstrap to complete make.bash.
+# Bootstrap installs a proper cmd/dist, built with the new toolchain.
+# Throw ours, built with Go 1.4, away after bootstrap.
+./cmd/dist/dist bootstrap $buildall $vflag $GO_DISTFLAGS "$@"
+rm -f ./cmd/dist/dist
 
-if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
-	echo "##### Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
-	# CC_FOR_TARGET is recorded as the default compiler for the go tool. When building for the host, however,
-	# use the host compiler, CC, from `cmd/dist/dist env` instead.
-	CC=$CC GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
-		"$GOTOOLDIR"/go_bootstrap install -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std cmd
-	echo
-fi
-
-echo "##### Building packages and commands for $GOOS/$GOARCH."
-
-old_bin_files=$(cd $GOROOT/bin && echo *)
-
-CC=$CC_FOR_TARGET "$GOTOOLDIR"/go_bootstrap install $GO_FLAGS -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std cmd
-
-# Check that there are no new files in $GOROOT/bin other than go and gofmt
-# and $GOOS_$GOARCH (a directory used when cross-compiling).
-(cd $GOROOT/bin && for f in *; do
-	if ! expr " $old_bin_files go gofmt ${GOOS}_${GOARCH} " : ".* $f " >/dev/null 2>/dev/null; then
-		echo 1>&2 "ERROR: unexpected new file in $GOROOT/bin: $f"
-		exit 1
-	fi
-done)
-
-echo
-
-rm -f "$GOTOOLDIR"/go_bootstrap
-
-if [ "$1" != "--no-banner" ]; then
-	"$GOTOOLDIR"/dist banner
-fi
+# DO NOT ADD ANY NEW CODE HERE.
+# The bootstrap+rm above are the final step of make.bash.
+# If something must be added, add it to cmd/dist's cmdbootstrap,
+# to avoid needing three copies in three different shell languages
+# (make.bash, make.bat, make.rc).
diff --git a/src/make.bat b/src/make.bat
index bf25b95..be164e8 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -41,6 +41,8 @@
 :: unless invoked with --no-local.
 if x%1==x--no-local goto nolocal
 if x%2==x--no-local goto nolocal
+if x%3==x--no-local goto nolocal
+if x%4==x--no-local goto nolocal
 setlocal
 :nolocal
 
@@ -58,12 +60,17 @@
 cd ..
 set GOROOT=%CD%
 cd src
+set vflag=
+if x%1==x-v set vflag=-v
+if x%2==x-v set vflag=-v
+if x%3==x-v set vflag=-v
+if x%4==x-v set vflag=-v
 
-echo ##### Building Go bootstrap tool.
-echo cmd/dist
 if not exist ..\bin\tool mkdir ..\bin\tool
 if "x%GOROOT_BOOTSTRAP%"=="x" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\Go1.4
 if not exist "%GOROOT_BOOTSTRAP%\bin\go.exe" goto bootstrapfail
+echo Building Go cmd/dist using %GOROOT_BOOTSTRAP%
+if x%vflag==x-v echo cmd/dist
 setlocal
 set GOROOT=%GOROOT_BOOTSTRAP%
 set GOOS=
@@ -76,51 +83,37 @@
 if errorlevel 1 goto fail
 call env.bat
 del env.bat
-echo.
+if x%vflag==x-v echo.
 
 if x%1==x--dist-tool goto copydist
 if x%2==x--dist-tool goto copydist
+if x%3==x--dist-tool goto copydist
+if x%4==x--dist-tool goto copydist
 
 set buildall=-a
 if x%1==x--no-clean set buildall=
-.\cmd\dist\dist bootstrap %buildall% -v
+if x%2==x--no-clean set buildall=
+if x%3==x--no-clean set buildall=
+if x%4==x--no-clean set buildall=
+if x%1==x--no-banner set buildall=%buildall% --no-banner
+if x%2==x--no-banner set buildall=%buildall% --no-banner
+if x%3==x--no-banner set buildall=%buildall% --no-banner
+if x%4==x--no-banner set buildall=%buildall% --no-banner
+
+:: Run dist bootstrap to complete make.bash.
+:: Bootstrap installs a proper cmd/dist, built with the new toolchain.
+:: Throw ours, built with Go 1.4, away after bootstrap.
+.\cmd\dist\dist bootstrap %vflag% %buildall% 
 if errorlevel 1 goto fail
-:: Delay move of dist tool to now, because bootstrap cleared tool directory.
-move .\cmd\dist\dist.exe "%GOTOOLDIR%\dist.exe"
-echo.
-
-if not %GOHOSTARCH% == %GOARCH% goto localbuild
-if not %GOHOSTOS% == %GOOS% goto localbuild
-goto mainbuild
-
-:localbuild
-echo ##### Building packages and commands for host, %GOHOSTOS%/%GOHOSTARCH%.
-:: CC_FOR_TARGET is recorded as the default compiler for the go tool. When building for the
-:: host, however, use the host compiler, CC, from `cmd/dist/dist env` instead.
-setlocal
-set GOOS=%GOHOSTOS%
-set GOARCH=%GOHOSTARCH%
-"%GOTOOLDIR%\go_bootstrap" install -gcflags "%GO_GCFLAGS%" -ldflags "%GO_LDFLAGS%" -v std cmd
-endlocal
-if errorlevel 1 goto fail
-echo.
-
-:mainbuild
-echo ##### Building packages and commands for %GOOS%/%GOARCH%.
-setlocal
-set CC=%CC_FOR_TARGET%
-"%GOTOOLDIR%\go_bootstrap" install -gcflags "%GO_GCFLAGS%" -ldflags "%GO_LDFLAGS%" -a -v std cmd
-endlocal
-if errorlevel 1 goto fail
-del "%GOTOOLDIR%\go_bootstrap.exe"
-echo.
-
-if x%1==x--no-banner goto nobanner
-"%GOTOOLDIR%\dist" banner
-:nobanner
-
+del .\cmd\dist\dist.exe
 goto end
 
+:: DO NOT ADD ANY NEW CODE HERE.
+:: The bootstrap+del above are the final step of make.bat.
+:: If something must be added, add it to cmd/dist's cmdbootstrap,
+:: to avoid needing three copies in three different shell languages
+:: (make.bash, make.bat, make.rc).
+
 :copydist
 mkdir "%GOTOOLDIR%" 2>NUL
 copy cmd\dist\dist.exe "%GOTOOLDIR%\"
diff --git a/src/make.rc b/src/make.rc
index ba3554c..7ae6221 100755
--- a/src/make.rc
+++ b/src/make.rc
@@ -41,21 +41,45 @@
 # Determine the host compiler toolchain.
 eval `{grep '^(CC|LD|O)=' /$objtype/mkfile}
 
-echo '##### Building Go bootstrap tool.'
-echo cmd/dist
+vflag=()
+if(~ $1 -v) {
+	vflag=(-v)
+	shift
+}
+
+
 GOROOT = `{cd .. && pwd}
 if(! ~ $#GOROOT_BOOTSTRAP 1)
 	GOROOT_BOOTSTRAP = $home/go1.4
+for(p in $path){
+	if(! test -x $GOROOT_BOOTSTRAP/bin/go){
+		if(go_exe = `{path=$p whatis go}){
+			goroot = `{GOROOT='' $go_exe env GOROOT}
+			if(! ~ $goroot $GOROOT){
+				GOROOT_BOOTSTRAP = $goroot
+			}
+		}
+	}
+}
 if(! test -x $GOROOT_BOOTSTRAP/bin/go){
 	echo 'ERROR: Cannot find '$GOROOT_BOOTSTRAP'/bin/go.' >[1=2]
 	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.' >[1=2]
 	exit bootstrap
 }
-rm -f cmd/dist/dist
+if(~ $GOROOT_BOOTSTRAP $GOROOT){
+	echo 'ERROR: $GOROOT_BOOTSTRAP must not be set to $GOROOT' >[1=2]
+	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.' >[1=2]
+	exit bootstrap
+}
+
+echo 'Building Go cmd/dist using '^$GOROOT_BOOTSTRAP
+if(~ $#vflag 1)
+	echo cmd/dist
 GOROOT=$GOROOT_BOOTSTRAP GOOS='' GOARCH='' $GOROOT_BOOTSTRAP/bin/go build -o cmd/dist/dist ./cmd/dist
 
 eval `{./cmd/dist/dist env -9}
-echo
+if(~ $#vflag 1)
+	echo
 
 if(~ $1 --dist-tool){
 	# Stop after building dist tool.
@@ -67,31 +91,18 @@
 }
 
 buildall = -a
-if(~ $1 --no-clean)
+if(~ $1 --no-clean) {
 	buildall = ()
-./cmd/dist/dist bootstrap $buildall -v # builds go_bootstrap
-# Delay move of dist tool to now, because bootstrap may clear tool directory.
-mv cmd/dist/dist $GOTOOLDIR/dist
-echo
-
-# Run only one process at a time on 9vx.
-if(~ $sysname vx32)
-	pflag = (-p 1)
-
-if(! ~ $GOHOSTARCH $GOARCH || ! ~ $GOHOSTOS $GOOS){
-	echo '##### Building packages and commands for host,' $GOHOSTOS/$GOHOSTARCH^.
-	GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH GOBIN=() \
-		$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v $pflag std cmd
-	echo
+	shift
 }
+# Run dist bootstrap to complete make.bash.
+# Bootstrap installs a proper cmd/dist, built with the new toolchain.
+# Throw ours, built with Go 1.4, away after bootstrap.
+./cmd/dist/dist bootstrap $vflag $buildall $*
+rm -f ./cmd/dist/dist
 
-echo '##### Building packages and commands for' $GOOS/$GOARCH^.
-$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v $pflag std cmd
-echo
-
-rm -f $GOTOOLDIR/go_bootstrap
-
-if(! ~ $1 --no-banner)
-	$GOTOOLDIR/dist banner
-
-status=''
+# DO NOT ADD ANY NEW CODE HERE.
+# The bootstrap+rm above are the final step of make.rc.
+# If something must be added, add it to cmd/dist's cmdbootstrap,
+# to avoid needing three copies in three different shell languages
+# (make.bash, make.bat, make.rc).
diff --git a/src/math/abs.go b/src/math/abs.go
index 924ee7c..df83add 100644
--- a/src/math/abs.go
+++ b/src/math/abs.go
@@ -10,14 +10,5 @@
 //	Abs(±Inf) = +Inf
 //	Abs(NaN) = NaN
 func Abs(x float64) float64 {
-	// TODO: once golang.org/issue/13095 is fixed, change this to:
-	// return Float64frombits(Float64bits(x) &^ (1 << 63))
-	// But for now, this generates better code and can also be inlined:
-	if x < 0 {
-		return -x
-	}
-	if x == 0 {
-		return 0 // return correctly abs(-0)
-	}
-	return x
+	return Float64frombits(Float64bits(x) &^ (1 << 63))
 }
diff --git a/src/math/all_test.go b/src/math/all_test.go
index 39a3a49..6682395 100644
--- a/src/math/all_test.go
+++ b/src/math/all_test.go
@@ -8,6 +8,7 @@
 	"fmt"
 	. "math"
 	"testing"
+	"unsafe"
 )
 
 var vf = []float64{
@@ -210,6 +211,18 @@
 	7.9630075582117758758440411e-01,
 	1.7806938696800922672994468e+00,
 }
+var erfinv = []float64{
+	4.746037673358033586786350696e-01,
+	8.559054432692110956388764172e-01,
+	-2.45427830571707336251331946e-02,
+	-4.78116683518973366268905506e-01,
+	1.479804430319470983648120853e+00,
+	2.654485787128896161882650211e-01,
+	5.027444534221520197823192493e-01,
+	2.466703532707627818954585670e-01,
+	1.632011465103005426240343116e-01,
+	-1.06672334642196900710000389e+00,
+}
 var exp = []float64{
 	1.4533071302642137507696589e+02,
 	2.2958822575694449002537581e+03,
@@ -516,6 +529,18 @@
 	8.734595415957246977711748e-01,
 	1.314075231424398637614104e+00,
 }
+var round = []float64{
+	5,
+	8,
+	Copysign(0, -1),
+	-5,
+	10,
+	3,
+	5,
+	3,
+	2,
+	-9,
+}
 var signbit = []bool{
 	false,
 	false,
@@ -941,6 +966,40 @@
 	NaN(),
 }
 
+var vferfinvSC = []float64{
+	1,
+	-1,
+	0,
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+var erfinvSC = []float64{
+	Inf(+1),
+	Inf(-1),
+	0,
+	NaN(),
+	NaN(),
+	NaN(),
+}
+
+var vferfcinvSC = []float64{
+	0,
+	2,
+	1,
+	Inf(1),
+	Inf(-1),
+	NaN(),
+}
+var erfcinvSC = []float64{
+	Inf(+1),
+	Inf(-1),
+	0,
+	NaN(),
+	NaN(),
+	NaN(),
+}
+
 var vfexpSC = []float64{
 	Inf(-1),
 	-2000,
@@ -952,6 +1011,7 @@
 	// Issue 18912
 	1.48852223e+09,
 	1.4885222e+09,
+	1,
 }
 var expSC = []float64{
 	0,
@@ -962,6 +1022,7 @@
 	Inf(1),
 	Inf(1),
 	Inf(1),
+	2.718281828459045,
 }
 
 var vfexp2SC = []float64{
@@ -1368,6 +1429,8 @@
 	{Inf(-1), 0},
 	{Inf(-1), -1024},
 	{NaN(), -1024},
+	{10, int(1) << (uint64(unsafe.Sizeof(0)-1) * 8)},
+	{10, -(int(1) << (uint64(unsafe.Sizeof(0)-1) * 8))},
 }
 var ldexpSC = []float64{
 	0,
@@ -1381,6 +1444,8 @@
 	Inf(-1),
 	Inf(-1),
 	NaN(),
+	Inf(1),
+	0,
 }
 
 var vflgammaSC = []float64{
@@ -1524,6 +1589,7 @@
 	{Inf(-1), 1},
 	{Inf(-1), 3},
 	{Inf(-1), Pi},
+	{Inf(-1), 0.5},
 	{Inf(-1), NaN()},
 
 	{-Pi, Inf(-1)},
@@ -1542,9 +1608,11 @@
 	{-1 / 2, Inf(1)},
 	{Copysign(0, -1), Inf(-1)},
 	{Copysign(0, -1), -Pi},
+	{Copysign(0, -1), -0.5},
 	{Copysign(0, -1), -3},
 	{Copysign(0, -1), 3},
 	{Copysign(0, -1), Pi},
+	{Copysign(0, -1), 0.5},
 	{Copysign(0, -1), Inf(1)},
 
 	{0, Inf(-1)},
@@ -1581,6 +1649,17 @@
 	{NaN(), 1},
 	{NaN(), Pi},
 	{NaN(), NaN()},
+
+	// Issue #7394 overflow checks
+	{2, float64(1 << 32)},
+	{2, -float64(1 << 32)},
+	{-2, float64(1<<32 + 1)},
+	{1 / 2, float64(1 << 45)},
+	{1 / 2, -float64(1 << 45)},
+	{Nextafter(1, 2), float64(1 << 63)},
+	{Nextafter(1, -2), float64(1 << 63)},
+	{Nextafter(-1, 2), float64(1 << 63)},
+	{Nextafter(-1, -2), float64(1 << 63)},
 }
 var powSC = []float64{
 	0,               // pow(-Inf, -Pi)
@@ -1590,6 +1669,7 @@
 	Inf(-1),         // pow(-Inf, 1)
 	Inf(-1),         // pow(-Inf, 3)
 	Inf(1),          // pow(-Inf, Pi)
+	Inf(1),          // pow(-Inf, 0.5)
 	NaN(),           // pow(-Inf, NaN)
 	0,               // pow(-Pi, -Inf)
 	NaN(),           // pow(-Pi, -Pi)
@@ -1606,9 +1686,11 @@
 	0,               // pow(-1/2, +Inf)
 	Inf(1),          // pow(-0, -Inf)
 	Inf(1),          // pow(-0, -Pi)
+	Inf(1),          // pow(-0, -0.5)
 	Inf(-1),         // pow(-0, -3) IEEE 754-2008
 	Copysign(0, -1), // pow(-0, 3) IEEE 754-2008
 	0,               // pow(-0, +Pi)
+	0,               // pow(-0, 0.5)
 	0,               // pow(-0, +Inf)
 	Inf(1),          // pow(+0, -Inf)
 	Inf(1),          // pow(+0, -Pi)
@@ -1642,6 +1724,17 @@
 	NaN(),           // pow(NaN, 1)
 	NaN(),           // pow(NaN, +Pi)
 	NaN(),           // pow(NaN, NaN)
+
+	// Issue #7394 overflow checks
+	Inf(1),  // pow(2, float64(1 << 32))
+	0,       // pow(2, -float64(1 << 32))
+	Inf(-1), // pow(-2, float64(1<<32 + 1))
+	0,       // pow(1/2, float64(1 << 45))
+	Inf(1),  // pow(1/2, -float64(1 << 45))
+	Inf(1),  // pow(Nextafter(1, 2), float64(1 << 63))
+	0,       // pow(Nextafter(1, -2), float64(1 << 63))
+	0,       // pow(Nextafter(-1, 2), float64(1 << 63))
+	Inf(1),  // pow(Nextafter(-1, -2), float64(1 << 63))
 }
 
 var vfpow10SC = []int{
@@ -1680,6 +1773,37 @@
 	Inf(1),   // pow10(MaxInt32)
 }
 
+var vfroundSC = [][2]float64{
+	{0, 0},
+	{1.390671161567e-309, 0}, // denormal
+	{0.49999999999999994, 0}, // 0.5-epsilon
+	{0.5, 1},
+	{0.5000000000000001, 1}, // 0.5+epsilon
+	{-1.5, -2},
+	{-2.5, -3},
+	{NaN(), NaN()},
+	{Inf(1), Inf(1)},
+	{2251799813685249.5, 2251799813685250}, // 1 bit fraction
+	{2251799813685250.5, 2251799813685251},
+	{4503599627370495.5, 4503599627370496}, // 1 bit fraction, rounding to 0 bit fraction
+	{4503599627370497, 4503599627370497},   // large integer
+}
+var vfroundEvenSC = [][2]float64{
+	{0, 0},
+	{1.390671161567e-309, 0}, // denormal
+	{0.49999999999999994, 0}, // 0.5-epsilon
+	{0.5, 0},
+	{0.5000000000000001, 1}, // 0.5+epsilon
+	{-1.5, -2},
+	{-2.5, -2},
+	{NaN(), NaN()},
+	{Inf(1), Inf(1)},
+	{2251799813685249.5, 2251799813685250}, // 1 bit fraction
+	{2251799813685250.5, 2251799813685250},
+	{4503599627370495.5, 4503599627370496}, // 1 bit fraction, rounding to 0 bit fraction
+	{4503599627370497, 4503599627370497},   // large integer
+}
+
 var vfsignbitSC = []float64{
 	Inf(-1),
 	Copysign(0, -1),
@@ -2093,6 +2217,54 @@
 	}
 }
 
+func TestErfinv(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Erfinv(a); !veryclose(erfinv[i], f) {
+			t.Errorf("Erfinv(%g) = %g, want %g", a, f, erfinv[i])
+		}
+	}
+	for i := 0; i < len(vferfinvSC); i++ {
+		if f := Erfinv(vferfinvSC[i]); !alike(erfinvSC[i], f) {
+			t.Errorf("Erfinv(%g) = %g, want %g", vferfinvSC[i], f, erfinvSC[i])
+		}
+	}
+	for x := -0.9; x <= 0.90; x += 1e-2 {
+		if f := Erf(Erfinv(x)); !close(x, f) {
+			t.Errorf("Erf(Erfinv(%g)) = %g, want %g", x, f, x)
+		}
+	}
+	for x := -0.9; x <= 0.90; x += 1e-2 {
+		if f := Erfinv(Erf(x)); !close(x, f) {
+			t.Errorf("Erfinv(Erf(%g)) = %g, want %g", x, f, x)
+		}
+	}
+}
+
+func TestErfcinv(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := 1.0 - (vf[i] / 10)
+		if f := Erfcinv(a); !veryclose(erfinv[i], f) {
+			t.Errorf("Erfcinv(%g) = %g, want %g", a, f, erfinv[i])
+		}
+	}
+	for i := 0; i < len(vferfcinvSC); i++ {
+		if f := Erfcinv(vferfcinvSC[i]); !alike(erfcinvSC[i], f) {
+			t.Errorf("Erfcinv(%g) = %g, want %g", vferfcinvSC[i], f, erfcinvSC[i])
+		}
+	}
+	for x := 0.1; x <= 1.9; x += 1e-2 {
+		if f := Erfc(Erfcinv(x)); !close(x, f) {
+			t.Errorf("Erfc(Erfcinv(%g)) = %g, want %g", x, f, x)
+		}
+	}
+	for x := 0.1; x <= 1.9; x += 1e-2 {
+		if f := Erfcinv(Erfc(x)); !close(x, f) {
+			t.Errorf("Erfcinv(Erfc(%g)) = %g, want %g", x, f, x)
+		}
+	}
+}
+
 func TestExp(t *testing.T) {
 	testExp(t, Exp, "Exp")
 	testExp(t, ExpGo, "ExpGo")
@@ -2590,6 +2762,32 @@
 	}
 }
 
+func TestRound(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Round(vf[i]); !alike(round[i], f) {
+			t.Errorf("Round(%g) = %g, want %g", vf[i], f, round[i])
+		}
+	}
+	for i := 0; i < len(vfroundSC); i++ {
+		if f := Round(vfroundSC[i][0]); !alike(vfroundSC[i][1], f) {
+			t.Errorf("Round(%g) = %g, want %g", vfroundSC[i][0], f, vfroundSC[i][1])
+		}
+	}
+}
+
+func TestRoundToEven(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := RoundToEven(vf[i]); !alike(round[i], f) {
+			t.Errorf("RoundToEven(%g) = %g, want %g", vf[i], f, round[i])
+		}
+	}
+	for i := 0; i < len(vfroundEvenSC); i++ {
+		if f := RoundToEven(vfroundEvenSC[i][0]); !alike(vfroundEvenSC[i][1], f) {
+			t.Errorf("RoundToEven(%g) = %g, want %g", vfroundEvenSC[i][0], f, vfroundEvenSC[i][1])
+		}
+	}
+}
+
 func TestSignbit(t *testing.T) {
 	for i := 0; i < len(vf); i++ {
 		if f := Signbit(vf[i]); signbit[i] != f {
@@ -2906,10 +3104,12 @@
 	GlobalF = x
 }
 
+var copysignNeg = -1.0
+
 func BenchmarkCopysign(b *testing.B) {
 	x := 0.0
 	for i := 0; i < b.N; i++ {
-		x = Copysign(.5, -1)
+		x = Copysign(.5, copysignNeg)
 	}
 	GlobalF = x
 }
@@ -2946,6 +3146,22 @@
 	GlobalF = x
 }
 
+func BenchmarkErfinv(b *testing.B) {
+	x := 0.0
+	for i := 0; i < b.N; i++ {
+		x = Erfinv(.5)
+	}
+	GlobalF = x
+}
+
+func BenchmarkErfcinv(b *testing.B) {
+	x := 0.0
+	for i := 0; i < b.N; i++ {
+		x = Erfcinv(.5)
+	}
+	GlobalF = x
+}
+
 func BenchmarkExp(b *testing.B) {
 	x := 0.0
 	for i := 0; i < b.N; i++ {
@@ -2986,10 +3202,12 @@
 	GlobalF = x
 }
 
+var absPos = .5
+
 func BenchmarkAbs(b *testing.B) {
 	x := 0.0
 	for i := 0; i < b.N; i++ {
-		x = Abs(.5)
+		x = Abs(absPos)
 	}
 	GlobalF = x
 
@@ -2998,7 +3216,7 @@
 func BenchmarkDim(b *testing.B) {
 	x := 0.0
 	for i := 0; i < b.N; i++ {
-		x = Dim(10, 3)
+		x = Dim(GlobalF, x)
 	}
 	GlobalF = x
 }
@@ -3221,6 +3439,24 @@
 	GlobalF = x
 }
 
+var roundNeg = float64(-2.5)
+
+func BenchmarkRound(b *testing.B) {
+	x := 0.0
+	for i := 0; i < b.N; i++ {
+		x = Round(roundNeg)
+	}
+	GlobalF = x
+}
+
+func BenchmarkRoundToEven(b *testing.B) {
+	x := 0.0
+	for i := 0; i < b.N; i++ {
+		x = RoundToEven(roundNeg)
+	}
+	GlobalF = x
+}
+
 func BenchmarkRemainder(b *testing.B) {
 	x := 0.0
 	for i := 0; i < b.N; i++ {
@@ -3229,10 +3465,12 @@
 	GlobalF = x
 }
 
+var signbitPos = 2.5
+
 func BenchmarkSignbit(b *testing.B) {
 	x := false
 	for i := 0; i < b.N; i++ {
-		x = Signbit(2.5)
+		x = Signbit(signbitPos)
 	}
 	GlobalB = x
 }
diff --git a/src/math/big/arith_amd64.s b/src/math/big/arith_amd64.s
index 7e50224..9a2405e 100644
--- a/src/math/big/arith_amd64.s
+++ b/src/math/big/arith_amd64.s
@@ -30,8 +30,6 @@
 // The carry bit is saved with SBBQ Rx, Rx: if the carry was set, Rx is -1, otherwise it is 0.
 // It is restored with ADDQ Rx, Rx: if Rx was -1 the carry is set, otherwise it is cleared.
 // This is faster than using rotate instructions.
-//
-// CAUTION: Note that MOVQ $0, Rx is translated to XORQ Rx, Rx which clears the carry bit!
 
 // func addVV(z, x, y []Word) (c Word)
 TEXT ·addVV(SB),NOSPLIT,$0
diff --git a/src/math/big/arith_ppc64x.s b/src/math/big/arith_ppc64x.s
index 5ed3de6..74db489 100644
--- a/src/math/big/arith_ppc64x.s
+++ b/src/math/big/arith_ppc64x.s
@@ -98,103 +98,59 @@
 
 // func mulAddVWW(z, x []Word, y, r Word) (c Word)
 TEXT ·mulAddVWW(SB), NOSPLIT, $0
-	MOVD z+0(FP), R10
-	MOVD x+24(FP), R8
-	MOVD y+48(FP), R9
-	MOVD r+56(FP), R4     // c = r
-	MOVD z_len+8(FP), R11
-	MOVD $0, R3           // i = 0
-	MOVD $8, R18
-	MOVD $1, R19
+	MOVD z+0(FP), R10	// R10 = z[]
+	MOVD x+24(FP), R8	// R8 = x[]
+	MOVD y+48(FP), R9	// R9 = y
+	MOVD r+56(FP), R4	// R4 = r = c
+	MOVD z_len+8(FP), R11	// R11 = z_len
 
-	JMP e5
+	MOVD R0, R3		// R3 will be the index register
+	CMP  R0, R11
+	MOVD R11, CTR		// Initialize loop counter
+	BEQ  done
 
-l5:
-	MULLD  R18, R3, R5
-	MOVD   (R8)(R5), R20
-	MULLD  R9, R20, R6
-	MULHDU R9, R20, R7
-	ADDC   R4, R6
+loop:
+	MOVD   (R8)(R3), R20	// x[i]
+	MULLD  R9, R20, R6	// R6 = z0 = Low-order(x[i]*y)
+	MULHDU R9, R20, R7	// R7 = z1 = High-order(x[i]*y)
+	ADDC   R4, R6		// Compute sum for z1 and z0
 	ADDZE  R7
-	MOVD   R6, (R10)(R5)
-	MOVD   R7, R4
-	ADD    R19, R3
+	MOVD   R6, (R10)(R3)	// z[i]
+	MOVD   R7, R4		// c
+	ADD    $8, R3
+	BC  16, 0, loop		// bdnz
 
-e5:
-	CMP R3, R11
-	BLT l5
-
+done:
 	MOVD R4, c+64(FP)
 	RET
 
 // func addMulVVW(z, x []Word, y Word) (c Word)
 TEXT ·addMulVVW(SB), NOSPLIT, $0
-	MOVD z+0(FP), R10
-	MOVD x+24(FP), R8
-	MOVD y+48(FP), R9
-	MOVD z_len+8(FP), R22
+	MOVD z+0(FP), R10	// R10 = z[]
+	MOVD x+24(FP), R8	// R8 = x[]
+	MOVD y+48(FP), R9	// R9 = y
+	MOVD z_len+8(FP), R22	// R22 = z_len
 
-	MOVD $0, R5   // i = 0
-	MOVD $0, R4   // c = 0
-	MOVD $8, R28
-	MOVD $-2, R23
-	AND  R22, R23 // mask the last bit of z.len
-	MOVD $2, R24
-	CMP  R23, R24
-	BGE  unrolled
-	JMP  end
-
-unrolled:
-	MOVD  $8, R19         // no (RA)(RB*8) on power
-	MULLD R5, R19
-	MOVD  (R10)(R19), R11 // R11 = z[i]
-	MOVD  (R8)(R19), R16  // R16 = x[i]
-	ADD   R28, R19, R25
-	MOVD  (R10)(R25), R17
-	MOVD  (R8)(R25), R18
-
-	MULLD  R9, R16, R12
-	MULHDU R9, R16, R14
-	MULLD  R9, R18, R6
-	MULHDU R9, R18, R7
-	ADDC   R4, R12
-	ADDZE  R14
-	ADDC   R11, R12        // z[i] = (x[i]*y) + z[i] + carry
-	ADDZE  R14             // carry = high order bits + add carry
-	MOVD   R12, (R10)(R19)
-	ADDC   R14, R6
-	ADDZE  R7
-	ADDC   R17, R6
-	ADDZE  R7
-	MOVD   R6, (R10)(R25)
-	MOVD   R7, R4
-
-	ADD R24, R5
-	CMP R5, R23
-	BLT unrolled
-	JMP end
+	MOVD R0, R3		// R3 will be the index register
+	CMP  R0, R22
+	MOVD R0, R4		// R4 = c = 0
+	MOVD R22, CTR		// Initialize loop counter
+	BEQ  done
 
 loop:
-	MOVD   $8, R19
-	MULLD  R5, R19
-	MOVD   (R10)(R19), R11
-	MOVD   (R8)(R19), R16
-	MULLD  R9, R16, R12
-	MULHDU R9, R16, R14
-	ADDC   R4, R12
-	ADDZE  R14
-	ADDC   R11, R12
-	ADDZE  R14
-	MOVD   R12, (R10)(R19)
-	MOVD   R14, R4
+	MOVD  (R8)(R3), R20	// Load x[i]
+	MOVD  (R10)(R3), R21	// Load z[i]
+	MULLD  R9, R20, R6	// R6 = Low-order(x[i]*y)
+	MULHDU R9, R20, R7	// R7 = High-order(x[i]*y)
+	ADDC   R21, R6		// R6 = z0
+	ADDZE  R7		// R7 = z1
+	ADDC   R4, R6		// R6 = z0 + c + 0
+	ADDZE  R7, R4           // c += z1
+	MOVD   R6, (R10)(R3)	// Store z[i]
+	ADD    $8, R3
+	BC  16, 0, loop		// bdnz
 
-	MOVD $1, R15
-	ADD  R15, R5
-
-end:
-	CMP R5, R22
-	BLT loop
-
+done:
 	MOVD R4, c+56(FP)
 	RET
 
diff --git a/src/math/big/calibrate_test.go b/src/math/big/calibrate_test.go
index f69ffbf..2b96e74 100644
--- a/src/math/big/calibrate_test.go
+++ b/src/math/big/calibrate_test.go
@@ -2,13 +2,20 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Calibration used to determine thresholds for using
+// different algorithms.  Ideally, this would be converted
+// to go generate to create thresholds.go
+
 // This file prints execution times for the Mul benchmark
 // given different Karatsuba thresholds. The result may be
 // used to manually fine-tune the threshold constant. The
 // results are somewhat fragile; use repeated runs to get
 // a clear picture.
 
-// Usage: go test -run=TestCalibrate -calibrate
+// Calculates lower and upper thresholds for when basicSqr
+// is faster than standard multiplication.
+
+// Usage: go test -run=TestCalibrate -v -calibrate
 
 package big
 
@@ -21,6 +28,27 @@
 
 var calibrate = flag.Bool("calibrate", false, "run calibration test")
 
+func TestCalibrate(t *testing.T) {
+	if *calibrate {
+		computeKaratsubaThresholds()
+
+		// compute basicSqrThreshold where overhead becomes negligible
+		minSqr := computeSqrThreshold(10, 30, 1, 3)
+		// compute karatsubaSqrThreshold where karatsuba is faster
+		maxSqr := computeSqrThreshold(300, 500, 10, 3)
+		if minSqr != 0 {
+			fmt.Printf("found basicSqrThreshold = %d\n", minSqr)
+		} else {
+			fmt.Println("no basicSqrThreshold found")
+		}
+		if maxSqr != 0 {
+			fmt.Printf("found karatsubaSqrThreshold = %d\n", maxSqr)
+		} else {
+			fmt.Println("no karatsubaSqrThreshold found")
+		}
+	}
+}
+
 func karatsubaLoad(b *testing.B) {
 	BenchmarkMul(b)
 }
@@ -34,7 +62,7 @@
 	return time.Duration(res.NsPerOp())
 }
 
-func computeThresholds() {
+func computeKaratsubaThresholds() {
 	fmt.Printf("Multiplication times for varying Karatsuba thresholds\n")
 	fmt.Printf("(run repeatedly for good results)\n")
 
@@ -81,8 +109,56 @@
 	}
 }
 
-func TestCalibrate(t *testing.T) {
-	if *calibrate {
-		computeThresholds()
+func measureBasicSqr(words, nruns int, enable bool) time.Duration {
+	// more runs for better statistics
+	initBasicSqr, initKaratsubaSqr := basicSqrThreshold, karatsubaSqrThreshold
+
+	if enable {
+		// set thresholds to use basicSqr at this number of words
+		basicSqrThreshold, karatsubaSqrThreshold = words-1, words+1
+	} else {
+		// set thresholds to disable basicSqr for any number of words
+		basicSqrThreshold, karatsubaSqrThreshold = -1, -1
 	}
+
+	var testval int64
+	for i := 0; i < nruns; i++ {
+		res := testing.Benchmark(func(b *testing.B) { benchmarkNatSqr(b, words) })
+		testval += res.NsPerOp()
+	}
+	testval /= int64(nruns)
+
+	basicSqrThreshold, karatsubaSqrThreshold = initBasicSqr, initKaratsubaSqr
+
+	return time.Duration(testval)
+}
+
+func computeSqrThreshold(from, to, step, nruns int) int {
+	fmt.Println("Calibrating thresholds for basicSqr via benchmarks of z.mul(x,x)")
+	fmt.Printf("Looking for a timing difference for x between %d - %d words by %d step\n", from, to, step)
+	var initPos bool
+	var threshold int
+	for i := from; i <= to; i += step {
+		baseline := measureBasicSqr(i, nruns, false)
+		testval := measureBasicSqr(i, nruns, true)
+		pos := baseline > testval
+		delta := baseline - testval
+		percent := delta * 100 / baseline
+		fmt.Printf("words = %3d deltaT = %10s (%4d%%) is basicSqr better: %v", i, delta, percent, pos)
+		if i == from {
+			initPos = pos
+		}
+		if threshold == 0 && pos != initPos {
+			threshold = i
+			fmt.Printf("  threshold  found")
+		}
+		fmt.Println()
+
+	}
+	if threshold != 0 {
+		fmt.Printf("Found threshold = %d between %d - %d\n", threshold, from, to)
+	} else {
+		fmt.Printf("Found NO threshold between %d - %d\n", from, to)
+	}
+	return threshold
 }
diff --git a/src/math/big/decimal.go b/src/math/big/decimal.go
index 2dfa032..ae9ffb5 100644
--- a/src/math/big/decimal.go
+++ b/src/math/big/decimal.go
@@ -20,7 +20,7 @@
 package big
 
 // A decimal represents an unsigned floating-point number in decimal representation.
-// The value of a non-zero decimal d is d.mant * 10**d.exp with 0.5 <= d.mant < 1,
+// The value of a non-zero decimal d is d.mant * 10**d.exp with 0.1 <= d.mant < 1,
 // with the most-significant mantissa digit at index 0. For the zero decimal, the
 // mantissa length and exponent are 0.
 // The zero value for decimal represents a ready-to-use 0.0.
diff --git a/src/math/big/float.go b/src/math/big/float.go
index 7e11f1a..c042854 100644
--- a/src/math/big/float.go
+++ b/src/math/big/float.go
@@ -415,8 +415,9 @@
 	// bits > z.prec: mantissa too large => round
 	r := uint(bits - z.prec - 1) // rounding bit position; r >= 0
 	rbit := z.mant.bit(r) & 1    // rounding bit; be safe and ensure it's a single bit
-	if sbit == 0 {
-		// TODO(gri) if rbit != 0 we don't need to compute sbit for some rounding modes (optimization)
+	// The sticky bit is only needed for rounding ToNearestEven
+	// or when the rounding bit is zero. Avoid computation otherwise.
+	if sbit == 0 && (rbit == 0 || z.mode == ToNearestEven) {
 		sbit = z.mant.sticky(r)
 	}
 	sbit &= 1 // be safe and ensure it's a single bit
@@ -1310,8 +1311,11 @@
 	// TODO(gri) Optimize this for the common case.
 
 	e := int64(x.exp) + int64(y.exp)
-	z.mant = z.mant.mul(x.mant, y.mant)
-
+	if x == y {
+		z.mant = z.mant.sqr(x.mant)
+	} else {
+		z.mant = z.mant.mul(x.mant, y.mant)
+	}
 	z.setExpAndRound(e-fnorm(z.mant), 0)
 }
 
diff --git a/src/math/big/int.go b/src/math/big/int.go
index 62f7fc5..0eda9cd 100644
--- a/src/math/big/int.go
+++ b/src/math/big/int.go
@@ -153,6 +153,11 @@
 	// x * (-y) == -(x * y)
 	// (-x) * y == -(x * y)
 	// (-x) * (-y) == x * y
+	if x == y {
+		z.abs = z.abs.sqr(x.abs)
+		z.neg = false
+		return z
+	}
 	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
@@ -324,6 +329,16 @@
 	return
 }
 
+// CmpAbs compares the absolute values of x and y and returns:
+//
+//   -1 if |x| <  |y|
+//    0 if |x| == |y|
+//   +1 if |x| >  |y|
+//
+func (x *Int) CmpAbs(y *Int) int {
+	return x.abs.cmp(y.abs)
+}
+
 // low32 returns the least significant 32 bits of x.
 func low32(x nat) uint32 {
 	if len(x) == 0 {
@@ -384,16 +399,26 @@
 // ``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.
 //
+// For bases <= 36, lower and upper case letters are considered the same:
+// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35.
+// For bases > 36, the upper case letters 'A' to 'Z' represent the digit
+// values 36 to 61.
+//
 func (z *Int) SetString(s string, base int) (*Int, bool) {
-	r := strings.NewReader(s)
+	return z.setFromScanner(strings.NewReader(s), base)
+}
+
+// setFromScanner implements SetString given an io.BytesScanner.
+// For documentation see comments of SetString.
+func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) {
 	if _, _, err := z.scan(r, base); err != nil {
 		return nil, false
 	}
-	// entire string must have been consumed
+	// entire content must have been consumed
 	if _, err := r.ReadByte(); err != io.EOF {
 		return nil, false
 	}
-	return z, true // err == io.EOF => scan consumed all of s
+	return z, true // err == io.EOF => scan consumed all content of r
 }
 
 // SetBytes interprets buf as the bytes of a big-endian unsigned
@@ -447,7 +472,7 @@
 
 // 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 x or y are not nil, GCD sets their value 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 {
@@ -461,17 +486,14 @@
 		return z
 	}
 	if x == nil && y == nil {
-		return z.binaryGCD(a, b)
+		return z.lehmerGCD(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)
@@ -484,15 +506,8 @@
 
 		temp.Set(X)
 		X.Mul(X, q)
-		X.neg = !X.neg
-		X.Add(X, lastX)
+		X.Sub(lastX, X)
 		lastX.Set(temp)
-
-		temp.Set(Y)
-		Y.Mul(Y, q)
-		Y.neg = !Y.neg
-		Y.Add(Y, lastY)
-		lastY.Set(temp)
 	}
 
 	if x != nil {
@@ -500,74 +515,139 @@
 	}
 
 	if y != nil {
-		*y = *lastY
+		// y = (z - a*x)/b
+		y.Mul(a, lastX)
+		y.Sub(A, y)
+		y.Div(y, b)
 	}
 
 	*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):
-		// must set v before u since u may be alias for a or b (was issue #11284)
-		v.Rem(a, b)
-		u.Set(b)
-	case len(a.abs) < len(b.abs):
-		v.Rem(b, a)
-		u.Set(a)
-	default:
-		v.Set(b)
-		u.Set(a)
+// lehmerGCD 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 L.
+// This implementation uses the improved condition by Collins requiring only one
+// quotient and avoiding the possibility of single Word overflow.
+// See Jebelean, "Improving the multiprecision Euclidean algorithm",
+// Design and Implementation of Symbolic Computation Systems, pp 45-58.
+func (z *Int) lehmerGCD(a, b *Int) *Int {
+	// ensure a >= b
+	if a.abs.cmp(b.abs) < 0 {
+		a, b = b, a
 	}
-	// a, b must not be used anymore (may be aliases with u)
 
-	// v might be 0 now
-	if len(v.abs) == 0 {
-		return u
-	}
-	// u > 0 && v > 0
+	// don't destroy incoming values of a and b
+	B := new(Int).Set(b) // must be set first in case b is an alias of z
+	A := z.Set(a)
 
-	// 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)
+	// temp variables for multiprecision update
 	t := new(Int)
-	if u.abs[0]&1 != 0 {
-		// u is odd
-		t.Neg(v)
-	} else {
-		t.Set(u)
-	}
+	r := new(Int)
+	s := new(Int)
+	w := new(Int)
 
-	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
+	// loop invariant A >= B
+	for len(B.abs) > 1 {
+		// initialize the digits
+		var a1, a2, u0, u1, u2, v0, v1, v2 Word
+
+		m := len(B.abs) // m >= 2
+		n := len(A.abs) // n >= m >= 2
+
+		// extract the top Word of bits from A and B
+		h := nlz(A.abs[n-1])
+		a1 = (A.abs[n-1] << h) | (A.abs[n-2] >> (_W - h))
+		// B may have implicit zero words in the high bits if the lengths differ
+		switch {
+		case n == m:
+			a2 = (B.abs[n-1] << h) | (B.abs[n-2] >> (_W - h))
+		case n == m+1:
+			a2 = (B.abs[n-2] >> (_W - h))
+		default:
+			a2 = 0
 		}
-		t.Sub(u, v)
+
+		// Since we are calculating with full words to avoid overflow,
+		// we use 'even' to track the sign of the cosequences.
+		// For even iterations: u0, v1 >= 0 && u1, v0 <= 0
+		// For odd  iterations: u0, v1 <= 0 && u1, v0 >= 0
+		// The first iteration starts with k=1 (odd).
+		even := false
+		// variables to track the cosequences
+		u0, u1, u2 = 0, 1, 0
+		v0, v1, v2 = 0, 0, 1
+
+		// Calculate the quotient and cosequences using Collins' stopping condition.
+		// Note that overflow of a Word is not possible when computing the remainder
+		// sequence and cosequences since the cosequence size is bounded by the input size.
+		// See section 4.2 of Jebelean for details.
+		for a2 >= v2 && a1-a2 >= v1+v2 {
+			q := a1 / a2
+			a1, a2 = a2, a1-q*a2
+			u0, u1, u2 = u1, u2, u1+q*u2
+			v0, v1, v2 = v1, v2, v1+q*v2
+			even = !even
+		}
+
+		// multiprecision step
+		if v0 != 0 {
+			// simulate the effect of the single precision steps using the cosequences
+			// A = u0*A + v0*B
+			// B = u1*A + v1*B
+
+			t.abs = t.abs.setWord(u0)
+			s.abs = s.abs.setWord(v0)
+			t.neg = !even
+			s.neg = even
+
+			t.Mul(A, t)
+			s.Mul(B, s)
+
+			r.abs = r.abs.setWord(u1)
+			w.abs = w.abs.setWord(v1)
+			r.neg = even
+			w.neg = !even
+
+			r.Mul(A, r)
+			w.Mul(B, w)
+
+			A.Add(t, s)
+			B.Add(r, w)
+
+		} else {
+			// single-digit calculations failed to simluate any quotients
+			// do a standard Euclidean step
+			t.Rem(A, B)
+			A, B, t = B, t, A
+		}
 	}
 
-	return z.Lsh(u, k)
+	if len(B.abs) > 0 {
+		// standard Euclidean algorithm base case for B a single Word
+		if len(A.abs) > 1 {
+			// A is longer than a single Word
+			t.Rem(A, B)
+			A, B, t = B, t, A
+		}
+		if len(B.abs) > 0 {
+			// A and B are both a single Word
+			a1, a2 := A.abs[0], B.abs[0]
+			for a2 != 0 {
+				a1, a2 = a2, a1%a2
+			}
+			A.abs[0] = a1
+		}
+	}
+	*z = *A
+	return z
 }
 
 // Rand sets z to a pseudo-random number in [0, n) and returns z.
+//
+// As this uses the math/rand package, it must not be used for
+// security-sensitive work. Use crypto/rand.Int instead.
 func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
 	z.neg = false
 	if n.neg || len(n.abs) == 0 {
@@ -659,10 +739,9 @@
 // to calculate the square root of any quadratic residue mod p quickly for 3
 // mod 4 primes.
 func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int {
-	z.Set(p)         // z = p
-	z.Add(z, intOne) // z = p + 1
-	z.Rsh(z, 2)      // z = (p + 1) / 4
-	z.Exp(x, z, p)   // z = x^z mod p
+	e := new(Int).Add(p, intOne) // e = p + 1
+	e.Rsh(e, 2)                  // e = (p + 1) / 4
+	z.Exp(x, e, p)               // z = x^e mod p
 	return z
 }
 
diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go
index 42e810b..270fec6 100644
--- a/src/math/big/int_test.go
+++ b/src/math/big/int_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"encoding/hex"
+	"fmt"
 	"math/rand"
 	"strconv"
 	"strings"
@@ -674,6 +675,37 @@
 	return x.Cmp(d) == 0
 }
 
+// euclidGCD is a reference implementation of Euclid's GCD
+// algorithm for testing against optimized algorithms.
+// Requirements: a, b > 0
+func euclidGCD(a, b *Int) *Int {
+
+	A := new(Int).Set(a)
+	B := new(Int).Set(b)
+	t := new(Int)
+
+	for len(B.abs) > 0 {
+		// A, B = B, A % B
+		t.Rem(A, B)
+		A, B, t = B, t, A
+	}
+	return A
+}
+
+func checkLehmerGcd(aBytes, bBytes []byte) bool {
+	a := new(Int).SetBytes(aBytes)
+	b := new(Int).SetBytes(bBytes)
+
+	if a.Sign() <= 0 || b.Sign() <= 0 {
+		return true // can only test positive arguments
+	}
+
+	d := new(Int).lehmerGCD(a, b)
+	d0 := euclidGCD(a, b)
+
+	return d.Cmp(d0) == 0
+}
+
 var gcdTests = []struct {
 	d, x, y, a, b string
 }{
@@ -707,38 +739,28 @@
 
 	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)
+		t.Errorf("GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, 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)
+		t.Errorf("GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, 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)
+		t.Errorf("GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, Y, y)
 	}
 
 	// check results in presence of aliasing (issue #11284)
 	a2 := new(Int).Set(a)
 	b2 := new(Int).Set(b)
-	a2.binaryGCD(a2, b2) // result is same as 1st argument
+	a2.GCD(X, Y, a2, b2) // result is same as 1st argument
 	if a2.Cmp(d) != 0 {
-		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, a2, d)
+		t.Errorf("aliased z = a GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, a2, d)
 	}
 
 	a2 = new(Int).Set(a)
 	b2 = new(Int).Set(b)
-	b2.binaryGCD(a2, b2) // result is same as 2nd argument
+	b2.GCD(X, Y, a2, b2) // result is same as 2nd argument
 	if b2.Cmp(d) != 0 {
-		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, b2, d)
+		t.Errorf("aliased z = b GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, b2, d)
 	}
 }
 
@@ -759,6 +781,10 @@
 	if err := quick.Check(checkGcd, nil); err != nil {
 		t.Error(err)
 	}
+
+	if err := quick.Check(checkLehmerGcd, nil); err != nil {
+		t.Error(err)
+	}
 }
 
 type intShiftTest struct {
@@ -903,6 +929,63 @@
 	}
 }
 
+// Entries must be sorted by value in ascending order.
+var cmpAbsTests = []string{
+	"0",
+	"1",
+	"2",
+	"10",
+	"10000000",
+	"2783678367462374683678456387645876387564783686583485",
+	"2783678367462374683678456387645876387564783686583486",
+	"32957394867987420967976567076075976570670947609750670956097509670576075067076027578341538",
+}
+
+func TestCmpAbs(t *testing.T) {
+	values := make([]*Int, len(cmpAbsTests))
+	var prev *Int
+	for i, s := range cmpAbsTests {
+		x, ok := new(Int).SetString(s, 0)
+		if !ok {
+			t.Fatalf("SetString(%s, 0) failed", s)
+		}
+		if prev != nil && prev.Cmp(x) >= 0 {
+			t.Fatal("cmpAbsTests entries not sorted in ascending order")
+		}
+		values[i] = x
+		prev = x
+	}
+
+	for i, x := range values {
+		for j, y := range values {
+			// try all combinations of signs for x, y
+			for k := 0; k < 4; k++ {
+				var a, b Int
+				a.Set(x)
+				b.Set(y)
+				if k&1 != 0 {
+					a.Neg(&a)
+				}
+				if k&2 != 0 {
+					b.Neg(&b)
+				}
+
+				got := a.CmpAbs(&b)
+				want := 0
+				switch {
+				case i > j:
+					want = 1
+				case i < j:
+					want = -1
+				}
+				if got != want {
+					t.Errorf("absCmp |%s|, |%s|: got %d; want %d", &a, &b, got, want)
+				}
+			}
+		}
+	}
+}
+
 var int64Tests = []string{
 	// int64
 	"0",
@@ -1383,6 +1466,12 @@
 		t.Errorf("ModSqrt returned inconsistent value %s", z)
 	}
 
+	// test x aliasing z
+	z = sqrtChk.ModSqrt(sqrtChk.Set(sq), mod)
+	if z != &sqrtChk || z.Cmp(sqrt) != 0 {
+		t.Errorf("ModSqrt returned inconsistent value %s", z)
+	}
+
 	// make sure we actually got a square root
 	if sqrt.Cmp(elt) == 0 {
 		return true // we found the "desired" square root
@@ -1536,6 +1625,26 @@
 	}
 }
 
+// We can't test this together with the other Exp tests above because
+// it requires a different receiver setup.
+func TestIssue22830(t *testing.T) {
+	one := new(Int).SetInt64(1)
+	base, _ := new(Int).SetString("84555555300000000000", 10)
+	mod, _ := new(Int).SetString("66666670001111111111", 10)
+	want, _ := new(Int).SetString("17888885298888888889", 10)
+
+	var tests = []int64{
+		0, 1, -1,
+	}
+
+	for _, n := range tests {
+		m := NewInt(n)
+		if got := m.Exp(base, one, mod); got.Cmp(want) != 0 {
+			t.Errorf("(%v).Exp(%s, 1, %s) = %s, want %s", n, base, mod, got, want)
+		}
+	}
+}
+
 func BenchmarkSqrt(b *testing.B) {
 	n, _ := new(Int).SetString("1"+strings.Repeat("0", 1001), 10)
 	b.ResetTimer()
@@ -1544,3 +1653,24 @@
 		t.Sqrt(n)
 	}
 }
+
+func benchmarkIntSqr(b *testing.B, nwords int) {
+	x := new(Int)
+	x.abs = rndNat(nwords)
+	t := new(Int)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		t.Mul(x, x)
+	}
+}
+
+func BenchmarkIntSqr(b *testing.B) {
+	for _, n := range sqrBenchSizes {
+		if isRaceBuilder && n > 1e3 {
+			continue
+		}
+		b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
+			benchmarkIntSqr(b, n)
+		})
+	}
+}
diff --git a/src/math/big/intconv.go b/src/math/big/intconv.go
index 91a62ce..6cca827 100644
--- a/src/math/big/intconv.go
+++ b/src/math/big/intconv.go
@@ -12,16 +12,11 @@
 	"io"
 )
 
-// TODO(gri) Should rename itoa to utoa (there's no sign). That
-// would permit the introduction of itoa which is like utoa but
-// reserves a byte for a possible sign that's passed in. That
-// would permit Int.Text to be implemented w/o the need for
-// string copy if the number is negative.
-
 // Text returns the string representation of x in the given base.
-// Base must be between 2 and 36, inclusive. The result uses the
-// lower-case letters 'a' to 'z' for digit values >= 10. No base
-// prefix (such as "0x") is added to the string.
+// Base must be between 2 and 62, inclusive. The result uses the
+// lower-case letters 'a' to 'z' for digit values 10 to 35, and
+// the upper-case letters 'A' to 'Z' for digit values 36 to 61.
+// No prefix (such as "0x") is added to the string.
 func (x *Int) Text(base int) string {
 	if x == nil {
 		return "<nil>"
diff --git a/src/math/big/intconv_test.go b/src/math/big/intconv_test.go
index 5142081..2e01ee3 100644
--- a/src/math/big/intconv_test.go
+++ b/src/math/big/intconv_test.go
@@ -56,6 +56,10 @@
 	{"-0b111", "-7", 0, -7, true},
 	{"0b1001010111", "599", 0, 0x257, true},
 	{"1001010111", "1001010111", 2, 0x257, true},
+	{"A", "a", 36, 10, true},
+	{"A", "A", 37, 36, true},
+	{"ABCXYZ", "abcxyz", 36, 623741435, true},
+	{"ABCXYZ", "ABCXYZ", 62, 33536793425, true},
 }
 
 func TestIntText(t *testing.T) {
@@ -135,8 +139,16 @@
 			}
 		}
 
-		if got := fmt.Sprintf(format(test.base), z); got != test.out {
-			t.Errorf("#%db got %s; want %s", i, got, test.out)
+		f := format(test.base)
+		got := fmt.Sprintf(f, z)
+		if f == "%d" {
+			if got != fmt.Sprintf("%d", test.val) {
+				t.Errorf("#%db got %s; want %d", i, got, test.val)
+			}
+		} else {
+			if got != test.out {
+				t.Errorf("#%dc got %s; want %s", i, got, test.out)
+			}
 		}
 	}
 }
diff --git a/src/math/big/intmarsh.go b/src/math/big/intmarsh.go
index ee1e414..c1422e2 100644
--- a/src/math/big/intmarsh.go
+++ b/src/math/big/intmarsh.go
@@ -6,7 +6,10 @@
 
 package big
 
-import "fmt"
+import (
+	"bytes"
+	"fmt"
+)
 
 // Gob codec version. Permits backward-compatible changes to the encoding.
 const intGobVersion byte = 1
@@ -52,8 +55,7 @@
 
 // UnmarshalText implements the encoding.TextUnmarshaler interface.
 func (z *Int) UnmarshalText(text []byte) error {
-	// TODO(gri): get rid of the []byte/string conversion
-	if _, ok := z.SetString(string(text), 0); !ok {
+	if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
 		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
 	}
 	return nil
diff --git a/src/math/big/nat.go b/src/math/big/nat.go
index 889eacb..3bb818f 100644
--- a/src/math/big/nat.go
+++ b/src/math/big/nat.go
@@ -249,7 +249,7 @@
 // Operands that are shorter than karatsubaThreshold are multiplied using
 // "grade school" multiplication; for longer operands the Karatsuba algorithm
 // is used.
-var karatsubaThreshold int = 40 // computed by calibrate.go
+var karatsubaThreshold = 40 // computed by calibrate_test.go
 
 // karatsuba multiplies x and y and leaves the result in z.
 // Both x and y must have the same length n and n must be a
@@ -473,6 +473,61 @@
 	return z.norm()
 }
 
+// basicSqr sets z = x*x and is asymptotically faster than basicMul
+// by about a factor of 2, but slower for small arguments due to overhead.
+// Requirements: len(x) > 0, len(z) >= 2*len(x)
+// The (non-normalized) result is placed in z[0 : 2 * len(x)].
+func basicSqr(z, x nat) {
+	n := len(x)
+	t := make(nat, 2*n)            // temporary variable to hold the products
+	z[1], z[0] = mulWW(x[0], x[0]) // the initial square
+	for i := 1; i < n; i++ {
+		d := x[i]
+		// z collects the squares x[i] * x[i]
+		z[2*i+1], z[2*i] = mulWW(d, d)
+		// t collects the products x[i] * x[j] where j < i
+		t[2*i] = addMulVVW(t[i:2*i], x[0:i], d)
+	}
+	t[2*n-1] = shlVU(t[1:2*n-1], t[1:2*n-1], 1) // double the j < i products
+	addVV(z, z, t)                              // combine the result
+}
+
+// Operands that are shorter than basicSqrThreshold are squared using
+// "grade school" multiplication; for operands longer than karatsubaSqrThreshold
+// the Karatsuba algorithm is used.
+var basicSqrThreshold = 20      // computed by calibrate_test.go
+var karatsubaSqrThreshold = 400 // computed by calibrate_test.go
+
+// z = x*x
+func (z nat) sqr(x nat) nat {
+	n := len(x)
+	switch {
+	case n == 0:
+		return z[:0]
+	case n == 1:
+		d := x[0]
+		z = z.make(2)
+		z[1], z[0] = mulWW(d, d)
+		return z.norm()
+	}
+
+	if alias(z, x) {
+		z = nil // z is an alias for x - cannot reuse
+	}
+	z = z.make(2 * n)
+
+	if n < basicSqrThreshold {
+		basicMul(z, x, x)
+		return z.norm()
+	}
+	if n < karatsubaSqrThreshold {
+		basicSqr(z, x)
+		return z.norm()
+	}
+
+	return z.mul(x, x)
+}
+
 // mulRange computes the product of all the unsigned integers in the
 // range [a, b] inclusively. If a > b (empty range), the result is 1.
 func (z nat) mulRange(a, b uint64) nat {
@@ -566,8 +621,8 @@
 	// determine if z can be reused
 	// TODO(gri) should find a better solution - this if statement
 	//           is very costly (see e.g. time pidigits -s -n 10000)
-	if alias(z, uIn) || alias(z, v) {
-		z = nil // z is an alias for uIn or v - cannot reuse
+	if alias(z, u) || alias(z, uIn) || alias(z, v) {
+		z = nil // z is an alias for u or uIn or v - cannot reuse
 	}
 	q = z.make(m + 1)
 
@@ -936,7 +991,7 @@
 	// otherwise the arguments would alias.
 	var zz, r nat
 	for j := 0; j < w; j++ {
-		zz = zz.mul(z, z)
+		zz = zz.sqr(z)
 		zz, z = z, zz
 
 		if v&mask != 0 {
@@ -956,7 +1011,7 @@
 		v = y[i]
 
 		for j := 0; j < _W; j++ {
-			zz = zz.mul(z, z)
+			zz = zz.sqr(z)
 			zz, z = z, zz
 
 			if v&mask != 0 {
@@ -989,7 +1044,7 @@
 	powers[1] = x
 	for i := 2; i < 1<<n; i += 2 {
 		p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
-		*p = p.mul(*p2, *p2)
+		*p = p.sqr(*p2)
 		zz, r = zz.div(r, *p, m)
 		*p, r = r, *p
 		*p1 = p1.mul(*p, x)
@@ -1006,22 +1061,22 @@
 				// Unrolled loop for significant performance
 				// gain. Use go test -bench=".*" in crypto/rsa
 				// to check performance before making changes.
-				zz = zz.mul(z, z)
+				zz = zz.sqr(z)
 				zz, z = z, zz
 				zz, r = zz.div(r, z, m)
 				z, r = r, z
 
-				zz = zz.mul(z, z)
+				zz = zz.sqr(z)
 				zz, z = z, zz
 				zz, r = zz.div(r, z, m)
 				z, r = r, z
 
-				zz = zz.mul(z, z)
+				zz = zz.sqr(z)
 				zz, z = z, zz
 				zz, r = zz.div(r, z, m)
 				z, r = r, z
 
-				zz = zz.mul(z, z)
+				zz = zz.sqr(z)
 				zz, z = z, zz
 				zz, r = zz.div(r, z, m)
 				z, r = r, z
diff --git a/src/math/big/nat_test.go b/src/math/big/nat_test.go
index 200a247..c25cdf0 100644
--- a/src/math/big/nat_test.go
+++ b/src/math/big/nat_test.go
@@ -619,3 +619,49 @@
 		}
 	}
 }
+
+func testBasicSqr(t *testing.T, x nat) {
+	got := make(nat, 2*len(x))
+	want := make(nat, 2*len(x))
+	basicSqr(got, x)
+	basicMul(want, x, x)
+	if got.cmp(want) != 0 {
+		t.Errorf("basicSqr(%v), got %v, want %v", x, got, want)
+	}
+}
+
+func TestBasicSqr(t *testing.T) {
+	for _, a := range prodNN {
+		if a.x != nil {
+			testBasicSqr(t, a.x)
+		}
+		if a.y != nil {
+			testBasicSqr(t, a.y)
+		}
+		if a.z != nil {
+			testBasicSqr(t, a.z)
+		}
+	}
+}
+
+func benchmarkNatSqr(b *testing.B, nwords int) {
+	x := rndNat(nwords)
+	var z nat
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		z.sqr(x)
+	}
+}
+
+var sqrBenchSizes = []int{1, 2, 3, 5, 8, 10, 20, 30, 50, 80, 100, 200, 300, 500, 800, 1000}
+
+func BenchmarkNatSqr(b *testing.B) {
+	for _, n := range sqrBenchSizes {
+		if isRaceBuilder && n > 1e3 {
+			continue
+		}
+		b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
+			benchmarkNatSqr(b, n)
+		})
+	}
+}
diff --git a/src/math/big/natconv.go b/src/math/big/natconv.go
index 25a345e..21ccbd6 100644
--- a/src/math/big/natconv.go
+++ b/src/math/big/natconv.go
@@ -15,13 +15,14 @@
 	"sync"
 )
 
-const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
+const digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-// Note: MaxBase = len(digits), but it must remain a rune constant
+// Note: MaxBase = len(digits), but it must remain an untyped rune constant
 //       for API compatibility.
 
 // MaxBase is the largest number base accepted for string conversions.
-const MaxBase = 'z' - 'a' + 10 + 1
+const MaxBase = 10 + ('z' - 'a' + 1) + ('Z' - 'A' + 1)
+const maxBaseSmall = 10 + ('z' - 'a' + 1)
 
 // maxPow returns (b**n, n) such that b**n is the largest power b**n <= _M.
 // For instance maxPow(10) == (1e19, 19) for 19 decimal digits in a 64bit Word.
@@ -59,11 +60,11 @@
 // It returns the corresponding natural number res, the actual base b,
 // a digit count, and a read or syntax error err, if any.
 //
-//	number   = [ prefix ] mantissa .
-//	prefix   = "0" [ "x" | "X" | "b" | "B" ] .
-//      mantissa = digits | digits "." [ digits ] | "." digits .
-//	digits   = digit { digit } .
-//	digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
+//     number   = [ prefix ] mantissa .
+//     prefix   = "0" [ "x" | "X" | "b" | "B" ] .
+//     mantissa = digits | digits "." [ digits ] | "." digits .
+//     digits   = digit { digit } .
+//     digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
 //
 // Unless fracOk is set, the base argument must be 0 or a value between
 // 2 and MaxBase. If fracOk is set, the base argument must be one of
@@ -80,6 +81,11 @@
 // is permitted. The result value is computed as if there were no period
 // present; and the count value is used to determine the fractional part.
 //
+// For bases <= 36, lower and upper case letters are considered the same:
+// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35.
+// For bases > 36, the upper case letters 'A' to 'Z' represent the digit
+// values 36 to 61.
+//
 // A result digit count > 0 corresponds to the number of (non-prefix) digits
 // parsed. A digit count <= 0 indicates the presence of a period (if fracOk
 // is set, only), and -count is the number of fractional digits found.
@@ -173,7 +179,11 @@
 		case 'a' <= ch && ch <= 'z':
 			d1 = Word(ch - 'a' + 10)
 		case 'A' <= ch && ch <= 'Z':
-			d1 = Word(ch - 'A' + 10)
+			if b <= maxBaseSmall {
+				d1 = Word(ch - 'A' + 10)
+			} else {
+				d1 = Word(ch - 'A' + maxBaseSmall)
+			}
 		default:
 			d1 = MaxBase + 1
 		}
@@ -469,7 +479,7 @@
 					table[0].bbb = nat(nil).expWW(bb, Word(leafSize))
 					table[0].ndigits = ndigits * leafSize
 				} else {
-					table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
+					table[i].bbb = nat(nil).sqr(table[i-1].bbb)
 					table[i].ndigits = 2 * table[i-1].ndigits
 				}
 
diff --git a/src/math/big/natconv_test.go b/src/math/big/natconv_test.go
index 898a39f..9f38bd9 100644
--- a/src/math/big/natconv_test.go
+++ b/src/math/big/natconv_test.go
@@ -13,6 +13,12 @@
 	"testing"
 )
 
+func TestMaxBase(t *testing.T) {
+	if MaxBase != len(digits) {
+		t.Fatalf("%d != %d", MaxBase, len(digits))
+	}
+}
+
 // log2 computes the integer binary logarithm of x.
 // The result is the integer n for which 2^n <= x < 2^(n+1).
 // If x == 0, the result is -1.
@@ -61,6 +67,7 @@
 	{nat{0xdeadbeef}, 16, "deadbeef"},
 	{nat{0x229be7}, 17, "1a2b3c"},
 	{nat{0x309663e6}, 32, "o9cov6"},
+	{nat{0x309663e6}, 62, "TakXI"},
 }
 
 func TestString(t *testing.T) {
@@ -110,6 +117,7 @@
 	{s: "?"},
 	{base: 10},
 	{base: 36},
+	{base: 62},
 	{s: "?", base: 10},
 	{s: "0x"},
 	{s: "345", base: 2},
@@ -124,6 +132,7 @@
 	{"0", 0, false, nil, 10, 1, true, 0},
 	{"0", 10, false, nil, 10, 1, true, 0},
 	{"0", 36, false, nil, 36, 1, true, 0},
+	{"0", 62, false, nil, 62, 1, true, 0},
 	{"1", 0, false, nat{1}, 10, 1, true, 0},
 	{"1", 10, false, nat{1}, 10, 1, true, 0},
 	{"0 ", 0, false, nil, 10, 1, true, ' '},
@@ -135,8 +144,11 @@
 	{"03271", 0, false, nat{03271}, 8, 4, true, 0},
 	{"10ab", 0, false, nat{10}, 10, 2, true, 'a'},
 	{"1234567890", 0, false, nat{1234567890}, 10, 10, true, 0},
+	{"A", 36, false, nat{10}, 36, 1, true, 0},
+	{"A", 37, false, nat{36}, 37, 1, true, 0},
 	{"xyz", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, 0},
-	{"xyz?", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, '?'},
+	{"XYZ?", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, '?'},
+	{"XYZ?", 62, false, nat{(59*62+60)*62 + 61}, 62, 3, true, '?'},
 	{"0x", 16, false, nil, 16, 1, true, 'x'},
 	{"0xdeadbeef", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
 	{"0XDEADBEEF", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
diff --git a/src/math/big/prime.go b/src/math/big/prime.go
index 3e9690e..848affb 100644
--- a/src/math/big/prime.go
+++ b/src/math/big/prime.go
@@ -108,7 +108,7 @@
 			continue
 		}
 		for j := uint(1); j < k; j++ {
-			y = y.mul(y, y)
+			y = y.sqr(y)
 			quotient, y = quotient.div(y, y, n)
 			if y.cmp(nm1) == 0 {
 				continue NextRandom
@@ -194,7 +194,7 @@
 			// If n is a non-square we expect to find a d in just a few attempts on average.
 			// After 40 attempts, take a moment to check if n is indeed a square.
 			t1 = t1.sqrt(n)
-			t1 = t1.mul(t1, t1)
+			t1 = t1.sqr(t1)
 			if t1.cmp(n) == 0 {
 				return false
 			}
@@ -259,7 +259,7 @@
 			t1 = t1.sub(t1, natP)
 			t2, vk = t2.div(vk, t1, n)
 			// V(k'+1) = V(2k+2) = V(k+1)² - 2.
-			t1 = t1.mul(vk1, vk1)
+			t1 = t1.sqr(vk1)
 			t1 = t1.add(t1, nm2)
 			t2, vk1 = t2.div(vk1, t1, n)
 		} else {
@@ -270,7 +270,7 @@
 			t1 = t1.sub(t1, natP)
 			t2, vk1 = t2.div(vk1, t1, n)
 			// V(k') = V(2k) = V(k)² - 2
-			t1 = t1.mul(vk, vk)
+			t1 = t1.sqr(vk)
 			t1 = t1.add(t1, nm2)
 			t2, vk = t2.div(vk, t1, n)
 		}
@@ -312,7 +312,7 @@
 		}
 		// k' = 2k
 		// V(k') = V(2k) = V(k)² - 2
-		t1 = t1.mul(vk, vk)
+		t1 = t1.sqr(vk)
 		t1 = t1.sub(t1, natTwo)
 		t2, vk = t2.div(vk, t1, n)
 	}
diff --git a/src/math/big/rat.go b/src/math/big/rat.go
index 56ce33d..b33fc69 100644
--- a/src/math/big/rat.go
+++ b/src/math/big/rat.go
@@ -422,7 +422,7 @@
 		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 {
+		if f := NewInt(0).lehmerGCD(&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 {
@@ -490,6 +490,13 @@
 
 // Mul sets z to the product x*y and returns z.
 func (z *Rat) Mul(x, y *Rat) *Rat {
+	if x == y {
+		// a squared Rat is positive and can't be reduced
+		z.a.neg = false
+		z.a.abs = z.a.abs.sqr(x.a.abs)
+		z.b.abs = z.b.abs.sqr(x.b.abs)
+		return z
+	}
 	z.a.Mul(&x.a, &y.a)
 	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
 	return z.norm()
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 4bc6ef7..157d8d0 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -202,6 +202,11 @@
 
 // String returns a string representation of x in the form "a/b" (even if b == 1).
 func (x *Rat) String() string {
+	return string(x.marshal())
+}
+
+// marshal implements String returning a slice of bytes
+func (x *Rat) marshal() []byte {
 	var buf []byte
 	buf = x.a.Append(buf, 10)
 	buf = append(buf, '/')
@@ -210,7 +215,7 @@
 	} else {
 		buf = append(buf, '1')
 	}
-	return string(buf)
+	return buf
 }
 
 // RatString returns a string representation of x in the form "a/b" if b != 1,
diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go
index b82e8d4..fbc7b60 100644
--- a/src/math/big/ratmarsh.go
+++ b/src/math/big/ratmarsh.go
@@ -59,8 +59,10 @@
 
 // MarshalText implements the encoding.TextMarshaler interface.
 func (x *Rat) MarshalText() (text []byte, err error) {
-	// TODO(gri): get rid of the []byte/string conversion
-	return []byte(x.RatString()), nil
+	if x.IsInt() {
+		return x.a.MarshalText()
+	}
+	return x.marshal(), nil
 }
 
 // UnmarshalText implements the encoding.TextUnmarshaler interface.
diff --git a/src/math/big/sqrt.go b/src/math/big/sqrt.go
new file mode 100644
index 0000000..00433cf
--- /dev/null
+++ b/src/math/big/sqrt.go
@@ -0,0 +1,151 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package big
+
+import "math"
+
+var (
+	half  = NewFloat(0.5)
+	two   = NewFloat(2.0)
+	three = NewFloat(3.0)
+)
+
+// Sqrt sets z to the rounded square root of x, and returns it.
+//
+// If z's precision is 0, it is changed to x's precision before the
+// operation. Rounding is performed according to z's precision and
+// rounding mode.
+//
+// The function panics if z < 0. The value of z is undefined in that
+// case.
+func (z *Float) Sqrt(x *Float) *Float {
+	if debugFloat {
+		x.validate()
+	}
+
+	if z.prec == 0 {
+		z.prec = x.prec
+	}
+
+	if x.Sign() == -1 {
+		// following IEEE754-2008 (section 7.2)
+		panic(ErrNaN{"square root of negative operand"})
+	}
+
+	// handle ±0 and +∞
+	if x.form != finite {
+		z.acc = Exact
+		z.form = x.form
+		z.neg = x.neg // IEEE754-2008 requires √±0 = ±0
+		return z
+	}
+
+	// MantExp sets the argument's precision to the receiver's, and
+	// when z.prec > x.prec this will lower z.prec. Restore it after
+	// the MantExp call.
+	prec := z.prec
+	b := x.MantExp(z)
+	z.prec = prec
+
+	// Compute √(z·2**b) as
+	//   √( z)·2**(½b)     if b is even
+	//   √(2z)·2**(⌊½b⌋)   if b > 0 is odd
+	//   √(½z)·2**(⌈½b⌉)   if b < 0 is odd
+	switch b % 2 {
+	case 0:
+		// nothing to do
+	case 1:
+		z.Mul(two, z)
+	case -1:
+		z.Mul(half, z)
+	}
+	// 0.25 <= z < 2.0
+
+	// Solving x² - z = 0 directly requires a Quo call, but it's
+	// faster for small precisions.
+	//
+	// Solving 1/x² - z = 0 avoids the Quo call and is much faster for
+	// high precisions.
+	//
+	// 128bit precision is an empirically chosen threshold.
+	if z.prec <= 128 {
+		z.sqrtDirect(z)
+	} else {
+		z.sqrtInverse(z)
+	}
+
+	// re-attach halved exponent
+	return z.SetMantExp(z, b/2)
+}
+
+// Compute √x (up to prec 128) by solving
+//   t² - x = 0
+// for t, starting with a 53 bits precision guess from math.Sqrt and
+// then using at most two iterations of Newton's method.
+func (z *Float) sqrtDirect(x *Float) {
+	// let
+	//   f(t) = t² - x
+	// then
+	//   g(t) = f(t)/f'(t) = ½(t² - x)/t
+	// and the next guess is given by
+	//   t2 = t - g(t) = ½(t² + x)/t
+	u := new(Float)
+	ng := func(t *Float) *Float {
+		u.prec = t.prec
+		u.Mul(t, t)        // u = t²
+		u.Add(u, x)        //   = t² + x
+		u.Mul(half, u)     //   = ½(t² + x)
+		return t.Quo(u, t) //   = ½(t² + x)/t
+	}
+
+	xf, _ := x.Float64()
+	sq := NewFloat(math.Sqrt(xf))
+
+	switch {
+	case z.prec > 128:
+		panic("sqrtDirect: only for z.prec <= 128")
+	case z.prec > 64:
+		sq.prec *= 2
+		sq = ng(sq)
+		fallthrough
+	default:
+		sq.prec *= 2
+		sq = ng(sq)
+	}
+
+	z.Set(sq)
+}
+
+// Compute √x (to z.prec precision) by solving
+//   1/t² - x = 0
+// for t (using Newton's method), and then inverting.
+func (z *Float) sqrtInverse(x *Float) {
+	// let
+	//   f(t) = 1/t² - x
+	// then
+	//   g(t) = f(t)/f'(t) = -½t(1 - xt²)
+	// and the next guess is given by
+	//   t2 = t - g(t) = ½t(3 - xt²)
+	u := new(Float)
+	ng := func(t *Float) *Float {
+		u.prec = t.prec
+		u.Mul(t, t)           // u = t²
+		u.Mul(x, u)           //   = xt²
+		u.Sub(three, u)       //   = 3 - xt²
+		u.Mul(t, u)           //   = t(3 - xt²)
+		return t.Mul(half, u) //   = ½t(3 - xt²)
+	}
+
+	xf, _ := x.Float64()
+	sqi := NewFloat(1 / math.Sqrt(xf))
+	for prec := z.prec + 32; sqi.prec < prec; {
+		sqi.prec *= 2
+		sqi = ng(sqi)
+	}
+	// sqi = 1/√x
+
+	// x/√x = √x
+	z.Mul(x, sqi)
+}
diff --git a/src/math/big/sqrt_test.go b/src/math/big/sqrt_test.go
new file mode 100644
index 0000000..6a412d6
--- /dev/null
+++ b/src/math/big/sqrt_test.go
@@ -0,0 +1,123 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package big
+
+import (
+	"fmt"
+	"math"
+	"math/rand"
+	"testing"
+)
+
+// TestFloatSqrt64 tests that Float.Sqrt of numbers with 53bit mantissa
+// behaves like float math.Sqrt.
+func TestFloatSqrt64(t *testing.T) {
+	for i := 0; i < 1e5; i++ {
+		r := rand.Float64()
+
+		got := new(Float).SetPrec(53)
+		got.Sqrt(NewFloat(r))
+		want := NewFloat(math.Sqrt(r))
+		if got.Cmp(want) != 0 {
+			t.Fatalf("Sqrt(%g) =\n got %g;\nwant %g", r, got, want)
+		}
+	}
+}
+
+func TestFloatSqrt(t *testing.T) {
+	for _, test := range []struct {
+		x    string
+		want string
+	}{
+		// Test values were generated on Wolfram Alpha using query
+		//   'sqrt(N) to 350 digits'
+		// 350 decimal digits give up to 1000 binary digits.
+		{"0.03125", "0.17677669529663688110021109052621225982120898442211850914708496724884155980776337985629844179095519659187673077886403712811560450698134215158051518713749197892665283324093819909447499381264409775757143376369499645074628431682460775184106467733011114982619404115381053858929018135497032545349940642599871090667456829147610370507757690729404938184321879"},
+		{"0.125", "0.35355339059327376220042218105242451964241796884423701829416993449768311961552675971259688358191039318375346155772807425623120901396268430316103037427498395785330566648187639818894998762528819551514286752738999290149256863364921550368212935466022229965238808230762107717858036270994065090699881285199742181334913658295220741015515381458809876368643757"},
+		{"0.5", "0.70710678118654752440084436210484903928483593768847403658833986899536623923105351942519376716382078636750692311545614851246241802792536860632206074854996791570661133296375279637789997525057639103028573505477998580298513726729843100736425870932044459930477616461524215435716072541988130181399762570399484362669827316590441482031030762917619752737287514"},
+		{"2.0", "1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457503"},
+		{"3.0", "1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067030299699450949989524788116555120943736485280932319023055820679748201010846749232650153123432669033228866506722546689218379712270471316603678615880190499865373798593894676503475065760507566183481296061009476021871903250831458295239598"},
+		{"4.0", "2.0"},
+
+		{"1p512", "1p256"},
+		{"4p1024", "2p512"},
+		{"9p2048", "3p1024"},
+
+		{"1p-1024", "1p-512"},
+		{"4p-2048", "2p-1024"},
+		{"9p-4096", "3p-2048"},
+	} {
+		for _, prec := range []uint{24, 53, 64, 65, 100, 128, 129, 200, 256, 400, 600, 800, 1000} {
+			x := new(Float).SetPrec(prec)
+			x.Parse(test.x, 10)
+
+			got := new(Float).SetPrec(prec).Sqrt(x)
+			want := new(Float).SetPrec(prec)
+			want.Parse(test.want, 10)
+			if got.Cmp(want) != 0 {
+				t.Errorf("prec = %d, Sqrt(%v) =\ngot  %g;\nwant %g",
+					prec, test.x, got, want)
+			}
+
+			// Square test.
+			// If got holds the square root of x to precision p, then
+			//   got = √x + k
+			// for some k such that |k| < 2**(-p). Thus,
+			//   got² = (√x + k)² = x + 2k√n + k²
+			// and the error must satisfy
+			//   err = |got² - x| ≈ | 2k√n | < 2**(-p+1)*√n
+			// Ignoring the k² term for simplicity.
+
+			// err = |got² - x|
+			// (but do intermediate steps with 32 guard digits to
+			// avoid introducing spurious rounding-related errors)
+			sq := new(Float).SetPrec(prec+32).Mul(got, got)
+			diff := new(Float).Sub(sq, x)
+			err := diff.Abs(diff).SetPrec(prec)
+
+			// maxErr = 2**(-p+1)*√x
+			one := new(Float).SetPrec(prec).SetInt64(1)
+			maxErr := new(Float).Mul(new(Float).SetMantExp(one, -int(prec)+1), got)
+
+			if err.Cmp(maxErr) >= 0 {
+				t.Errorf("prec = %d, Sqrt(%v) =\ngot err  %g;\nwant maxErr %g",
+					prec, test.x, err, maxErr)
+			}
+		}
+	}
+}
+
+func TestFloatSqrtSpecial(t *testing.T) {
+	for _, test := range []struct {
+		x    *Float
+		want *Float
+	}{
+		{NewFloat(+0), NewFloat(+0)},
+		{NewFloat(-0), NewFloat(-0)},
+		{NewFloat(math.Inf(+1)), NewFloat(math.Inf(+1))},
+	} {
+		got := new(Float).Sqrt(test.x)
+		if got.neg != test.want.neg || got.form != test.want.form {
+			t.Errorf("Sqrt(%v) = %v (neg: %v); want %v (neg: %v)",
+				test.x, got, got.neg, test.want, test.want.neg)
+		}
+	}
+
+}
+
+// Benchmarks
+
+func BenchmarkFloatSqrt(b *testing.B) {
+	for _, prec := range []uint{64, 128, 256, 1e3, 1e4, 1e5, 1e6} {
+		x := NewFloat(2)
+		z := new(Float).SetPrec(prec)
+		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
+			b.ReportAllocs()
+			for n := 0; n < b.N; n++ {
+				z.Sqrt(x)
+			}
+		})
+	}
+}
diff --git a/src/math/bits.go b/src/math/bits.go
index d85ee9c..77bcdbe 100644
--- a/src/math/bits.go
+++ b/src/math/bits.go
@@ -8,9 +8,12 @@
 	uvnan    = 0x7FF8000000000001
 	uvinf    = 0x7FF0000000000000
 	uvneginf = 0xFFF0000000000000
+	uvone    = 0x3FF0000000000000
 	mask     = 0x7FF
 	shift    = 64 - 11 - 1
 	bias     = 1023
+	signMask = 1 << 63
+	fracMask = 1<<shift - 1
 )
 
 // Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
diff --git a/src/math/bits/example_test.go b/src/math/bits/example_test.go
index a43d1f3..18e026b 100644
--- a/src/math/bits/example_test.go
+++ b/src/math/bits/example_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Code generated by go run make_examples.go. DO NOT EDIT.
+
 package bits_test
 
 import (
@@ -9,70 +11,194 @@
 	"math/bits"
 )
 
-func ExampleLeadingZeros16() {
-	fmt.Println(bits.LeadingZeros16(0))
-	fmt.Println(bits.LeadingZeros16(1))
-	fmt.Println(bits.LeadingZeros16(256))
-	fmt.Println(bits.LeadingZeros16(65535))
+func ExampleLeadingZeros8() {
+	fmt.Printf("LeadingZeros8(%08b) = %d\n", 1, bits.LeadingZeros8(1))
 	// Output:
-	// 16
-	// 15
-	// 7
-	// 0
+	// LeadingZeros8(00000001) = 7
+}
+
+func ExampleLeadingZeros16() {
+	fmt.Printf("LeadingZeros16(%016b) = %d\n", 1, bits.LeadingZeros16(1))
+	// Output:
+	// LeadingZeros16(0000000000000001) = 15
 }
 
 func ExampleLeadingZeros32() {
-	fmt.Println(bits.LeadingZeros32(0))
-	fmt.Println(bits.LeadingZeros32(1))
+	fmt.Printf("LeadingZeros32(%032b) = %d\n", 1, bits.LeadingZeros32(1))
 	// Output:
-	// 32
-	// 31
+	// LeadingZeros32(00000000000000000000000000000001) = 31
 }
 
 func ExampleLeadingZeros64() {
-	fmt.Println(bits.LeadingZeros64(0))
-	fmt.Println(bits.LeadingZeros64(1))
+	fmt.Printf("LeadingZeros64(%064b) = %d\n", 1, bits.LeadingZeros64(1))
 	// Output:
-	// 64
-	// 63
+	// LeadingZeros64(0000000000000000000000000000000000000000000000000000000000000001) = 63
 }
 
-func ExampleOnesCount() {
-	fmt.Printf("%b\n", 14)
-	fmt.Println(bits.OnesCount(14))
+func ExampleTrailingZeros8() {
+	fmt.Printf("TrailingZeros8(%08b) = %d\n", 14, bits.TrailingZeros8(14))
 	// Output:
-	// 1110
-	// 3
+	// TrailingZeros8(00001110) = 1
+}
+
+func ExampleTrailingZeros16() {
+	fmt.Printf("TrailingZeros16(%016b) = %d\n", 14, bits.TrailingZeros16(14))
+	// Output:
+	// TrailingZeros16(0000000000001110) = 1
+}
+
+func ExampleTrailingZeros32() {
+	fmt.Printf("TrailingZeros32(%032b) = %d\n", 14, bits.TrailingZeros32(14))
+	// Output:
+	// TrailingZeros32(00000000000000000000000000001110) = 1
+}
+
+func ExampleTrailingZeros64() {
+	fmt.Printf("TrailingZeros64(%064b) = %d\n", 14, bits.TrailingZeros64(14))
+	// Output:
+	// TrailingZeros64(0000000000000000000000000000000000000000000000000000000000001110) = 1
 }
 
 func ExampleOnesCount8() {
-	fmt.Printf("%b\n", 14)
-	fmt.Println(bits.OnesCount8(14))
+	fmt.Printf("OnesCount8(%08b) = %d\n", 14, bits.OnesCount8(14))
 	// Output:
-	// 1110
-	// 3
+	// OnesCount8(00001110) = 3
 }
 
 func ExampleOnesCount16() {
-	fmt.Printf("%b\n", 14)
-	fmt.Println(bits.OnesCount16(14))
+	fmt.Printf("OnesCount16(%016b) = %d\n", 14, bits.OnesCount16(14))
 	// Output:
-	// 1110
-	// 3
+	// OnesCount16(0000000000001110) = 3
 }
 
 func ExampleOnesCount32() {
-	fmt.Printf("%b\n", 14)
-	fmt.Println(bits.OnesCount32(14))
+	fmt.Printf("OnesCount32(%032b) = %d\n", 14, bits.OnesCount32(14))
 	// Output:
-	// 1110
-	// 3
+	// OnesCount32(00000000000000000000000000001110) = 3
 }
 
 func ExampleOnesCount64() {
-	fmt.Printf("%b\n", 14)
-	fmt.Println(bits.OnesCount64(14))
+	fmt.Printf("OnesCount64(%064b) = %d\n", 14, bits.OnesCount64(14))
 	// Output:
-	// 1110
-	// 3
+	// OnesCount64(0000000000000000000000000000000000000000000000000000000000001110) = 3
+}
+
+func ExampleRotateLeft8() {
+	fmt.Printf("%08b\n", 15)
+	fmt.Printf("%08b\n", bits.RotateLeft8(15, 2))
+	fmt.Printf("%08b\n", bits.RotateLeft8(15, -2))
+	// Output:
+	// 00001111
+	// 00111100
+	// 11000011
+}
+
+func ExampleRotateLeft16() {
+	fmt.Printf("%016b\n", 15)
+	fmt.Printf("%016b\n", bits.RotateLeft16(15, 2))
+	fmt.Printf("%016b\n", bits.RotateLeft16(15, -2))
+	// Output:
+	// 0000000000001111
+	// 0000000000111100
+	// 1100000000000011
+}
+
+func ExampleRotateLeft32() {
+	fmt.Printf("%032b\n", 15)
+	fmt.Printf("%032b\n", bits.RotateLeft32(15, 2))
+	fmt.Printf("%032b\n", bits.RotateLeft32(15, -2))
+	// Output:
+	// 00000000000000000000000000001111
+	// 00000000000000000000000000111100
+	// 11000000000000000000000000000011
+}
+
+func ExampleRotateLeft64() {
+	fmt.Printf("%064b\n", 15)
+	fmt.Printf("%064b\n", bits.RotateLeft64(15, 2))
+	fmt.Printf("%064b\n", bits.RotateLeft64(15, -2))
+	// Output:
+	// 0000000000000000000000000000000000000000000000000000000000001111
+	// 0000000000000000000000000000000000000000000000000000000000111100
+	// 1100000000000000000000000000000000000000000000000000000000000011
+}
+
+func ExampleReverse8() {
+	fmt.Printf("%08b\n", 19)
+	fmt.Printf("%08b\n", bits.Reverse8(19))
+	// Output:
+	// 00010011
+	// 11001000
+}
+
+func ExampleReverse16() {
+	fmt.Printf("%016b\n", 19)
+	fmt.Printf("%016b\n", bits.Reverse16(19))
+	// Output:
+	// 0000000000010011
+	// 1100100000000000
+}
+
+func ExampleReverse32() {
+	fmt.Printf("%032b\n", 19)
+	fmt.Printf("%032b\n", bits.Reverse32(19))
+	// Output:
+	// 00000000000000000000000000010011
+	// 11001000000000000000000000000000
+}
+
+func ExampleReverse64() {
+	fmt.Printf("%064b\n", 19)
+	fmt.Printf("%064b\n", bits.Reverse64(19))
+	// Output:
+	// 0000000000000000000000000000000000000000000000000000000000010011
+	// 1100100000000000000000000000000000000000000000000000000000000000
+}
+
+func ExampleReverseBytes16() {
+	fmt.Printf("%016b\n", 15)
+	fmt.Printf("%016b\n", bits.ReverseBytes16(15))
+	// Output:
+	// 0000000000001111
+	// 0000111100000000
+}
+
+func ExampleReverseBytes32() {
+	fmt.Printf("%032b\n", 15)
+	fmt.Printf("%032b\n", bits.ReverseBytes32(15))
+	// Output:
+	// 00000000000000000000000000001111
+	// 00001111000000000000000000000000
+}
+
+func ExampleReverseBytes64() {
+	fmt.Printf("%064b\n", 15)
+	fmt.Printf("%064b\n", bits.ReverseBytes64(15))
+	// Output:
+	// 0000000000000000000000000000000000000000000000000000000000001111
+	// 0000111100000000000000000000000000000000000000000000000000000000
+}
+
+func ExampleLen8() {
+	fmt.Printf("Len8(%08b) = %d\n", 8, bits.Len8(8))
+	// Output:
+	// Len8(00001000) = 4
+}
+
+func ExampleLen16() {
+	fmt.Printf("Len16(%016b) = %d\n", 8, bits.Len16(8))
+	// Output:
+	// Len16(0000000000001000) = 4
+}
+
+func ExampleLen32() {
+	fmt.Printf("Len32(%032b) = %d\n", 8, bits.Len32(8))
+	// Output:
+	// Len32(00000000000000000000000000001000) = 4
+}
+
+func ExampleLen64() {
+	fmt.Printf("Len64(%064b) = %d\n", 8, bits.Len64(8))
+	// Output:
+	// Len64(0000000000000000000000000000000000000000000000000000000000001000) = 4
 }
diff --git a/src/math/bits/make_examples.go b/src/math/bits/make_examples.go
new file mode 100644
index 0000000..cd81cd6
--- /dev/null
+++ b/src/math/bits/make_examples.go
@@ -0,0 +1,112 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// This program generates example_test.go.
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"math/bits"
+)
+
+const header = `// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by go run make_examples.go. DO NOT EDIT.
+
+package bits_test
+
+import (
+	"fmt"
+	"math/bits"
+)
+`
+
+func main() {
+	w := bytes.NewBuffer([]byte(header))
+
+	for _, e := range []struct {
+		name string
+		in   int
+		out  [4]interface{}
+		out2 [4]interface{}
+	}{
+		{
+			name: "LeadingZeros",
+			in:   1,
+			out:  [4]interface{}{bits.LeadingZeros8(1), bits.LeadingZeros16(1), bits.LeadingZeros32(1), bits.LeadingZeros64(1)},
+		},
+		{
+			name: "TrailingZeros",
+			in:   14,
+			out:  [4]interface{}{bits.TrailingZeros8(14), bits.TrailingZeros16(14), bits.TrailingZeros32(14), bits.TrailingZeros64(14)},
+		},
+		{
+			name: "OnesCount",
+			in:   14,
+			out:  [4]interface{}{bits.OnesCount8(14), bits.OnesCount16(14), bits.OnesCount32(14), bits.OnesCount64(14)},
+		},
+		{
+			name: "RotateLeft",
+			in:   15,
+			out:  [4]interface{}{bits.RotateLeft8(15, 2), bits.RotateLeft16(15, 2), bits.RotateLeft32(15, 2), bits.RotateLeft64(15, 2)},
+			out2: [4]interface{}{bits.RotateLeft8(15, -2), bits.RotateLeft16(15, -2), bits.RotateLeft32(15, -2), bits.RotateLeft64(15, -2)},
+		},
+		{
+			name: "Reverse",
+			in:   19,
+			out:  [4]interface{}{bits.Reverse8(19), bits.Reverse16(19), bits.Reverse32(19), bits.Reverse64(19)},
+		},
+		{
+			name: "ReverseBytes",
+			in:   15,
+			out:  [4]interface{}{nil, bits.ReverseBytes16(15), bits.ReverseBytes32(15), bits.ReverseBytes64(15)},
+		},
+		{
+			name: "Len",
+			in:   8,
+			out:  [4]interface{}{bits.Len8(8), bits.Len16(8), bits.Len32(8), bits.Len64(8)},
+		},
+	} {
+		for i, size := range []int{8, 16, 32, 64} {
+			if e.out[i] == nil {
+				continue // function doesn't exist
+			}
+			f := fmt.Sprintf("%s%d", e.name, size)
+			fmt.Fprintf(w, "\nfunc Example%s() {\n", f)
+			switch e.name {
+			case "RotateLeft", "Reverse", "ReverseBytes":
+				fmt.Fprintf(w, "\tfmt.Printf(\"%%0%db\\n\", %d)\n", size, e.in)
+				if e.name == "RotateLeft" {
+					fmt.Fprintf(w, "\tfmt.Printf(\"%%0%db\\n\", bits.%s(%d, 2))\n", size, f, e.in)
+					fmt.Fprintf(w, "\tfmt.Printf(\"%%0%db\\n\", bits.%s(%d, -2))\n", size, f, e.in)
+				} else {
+					fmt.Fprintf(w, "\tfmt.Printf(\"%%0%db\\n\", bits.%s(%d))\n", size, f, e.in)
+				}
+				fmt.Fprintf(w, "\t// Output:\n")
+				fmt.Fprintf(w, "\t// %0*b\n", size, e.in)
+				fmt.Fprintf(w, "\t// %0*b\n", size, e.out[i])
+				if e.name == "RotateLeft" && e.out2[i] != nil {
+					fmt.Fprintf(w, "\t// %0*b\n", size, e.out2[i])
+				}
+			default:
+				fmt.Fprintf(w, "\tfmt.Printf(\"%s(%%0%db) = %%d\\n\", %d, bits.%s(%d))\n", f, size, e.in, f, e.in)
+				fmt.Fprintf(w, "\t// Output:\n")
+				fmt.Fprintf(w, "\t// %s(%0*b) = %d\n", f, size, e.in, e.out[i])
+			}
+			fmt.Fprintf(w, "}\n")
+		}
+	}
+
+	if err := ioutil.WriteFile("example_test.go", w.Bytes(), 0666); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/src/math/cmplx/asin.go b/src/math/cmplx/asin.go
index 61880a2..062f324 100644
--- a/src/math/cmplx/asin.go
+++ b/src/math/cmplx/asin.go
@@ -49,11 +49,8 @@
 
 // Asin returns the inverse sine of x.
 func Asin(x complex128) complex128 {
-	if imag(x) == 0 {
-		if math.Abs(real(x)) > 1 {
-			return complex(math.Pi/2, 0) // DOMAIN error
-		}
-		return complex(math.Asin(real(x)), 0)
+	if imag(x) == 0 && math.Abs(real(x)) <= 1 {
+		return complex(math.Asin(real(x)), imag(x))
 	}
 	ct := complex(-imag(x), real(x)) // i * x
 	xx := x * x
@@ -65,12 +62,8 @@
 
 // Asinh returns the inverse hyperbolic sine of x.
 func Asinh(x complex128) complex128 {
-	// TODO check range
-	if imag(x) == 0 {
-		if math.Abs(real(x)) > 1 {
-			return complex(math.Pi/2, 0) // DOMAIN error
-		}
-		return complex(math.Asinh(real(x)), 0)
+	if imag(x) == 0 && math.Abs(real(x)) <= 1 {
+		return complex(math.Asinh(real(x)), imag(x))
 	}
 	xx := x * x
 	x1 := complex(1+real(xx), imag(xx)) // 1 + x*x
@@ -140,10 +133,6 @@
 
 // Atan returns the inverse tangent of x.
 func Atan(x complex128) complex128 {
-	if real(x) == 0 && imag(x) > 1 {
-		return NaN()
-	}
-
 	x2 := real(x) * real(x)
 	a := 1 - x2 - imag(x)*imag(x)
 	if a == 0 {
diff --git a/src/math/cmplx/cmath_test.go b/src/math/cmplx/cmath_test.go
index 7a5c485..8d70562 100644
--- a/src/math/cmplx/cmath_test.go
+++ b/src/math/cmplx/cmath_test.go
@@ -435,6 +435,24 @@
 	NaN(),
 }
 
+// branch cut continuity checks
+// points on each axis at |z| > 1 are checked for one-sided continuity from both the positive and negative side
+// all possible branch cuts for the elementary functions are at one of these points
+
+var zero = 0.0
+var eps = 1.0 / (1 << 53)
+
+var branchPoints = [][2]complex128{
+	{complex(2.0, zero), complex(2.0, eps)},
+	{complex(2.0, -zero), complex(2.0, -eps)},
+	{complex(-2.0, zero), complex(-2.0, eps)},
+	{complex(-2.0, -zero), complex(-2.0, -eps)},
+	{complex(zero, 2.0), complex(eps, 2.0)},
+	{complex(-zero, 2.0), complex(-eps, 2.0)},
+	{complex(zero, -2.0), complex(eps, -2.0)},
+	{complex(-zero, -2.0), complex(-eps, -2.0)},
+}
+
 // functions borrowed from pkg/math/all_test.go
 func tolerance(a, b, e float64) bool {
 	d := a - b
@@ -508,6 +526,11 @@
 			t.Errorf("Acos(%g) = %g, want %g", vcAcosSC[i], f, acosSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Acos(pt[0]), Acos(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Acos(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestAcosh(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -520,6 +543,11 @@
 			t.Errorf("Acosh(%g) = %g, want %g", vcAcoshSC[i], f, acoshSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Acosh(pt[0]), Acosh(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Acosh(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestAsin(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -532,6 +560,11 @@
 			t.Errorf("Asin(%g) = %g, want %g", vcAsinSC[i], f, asinSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Asin(pt[0]), Asin(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Asin(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestAsinh(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -544,6 +577,11 @@
 			t.Errorf("Asinh(%g) = %g, want %g", vcAsinhSC[i], f, asinhSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Asinh(pt[0]), Asinh(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Asinh(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestAtan(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -556,6 +594,11 @@
 			t.Errorf("Atan(%g) = %g, want %g", vcAtanSC[i], f, atanSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Atan(pt[0]), Atan(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Atan(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestAtanh(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -568,6 +611,11 @@
 			t.Errorf("Atanh(%g) = %g, want %g", vcAtanhSC[i], f, atanhSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Atanh(pt[0]), Atanh(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Atanh(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestConj(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -635,6 +683,11 @@
 			t.Errorf("Log(%g) = %g, want %g", vcLogSC[i], f, logSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Log(pt[0]), Log(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Log(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestLog10(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -685,6 +738,11 @@
 			t.Errorf("Pow(%g, %g) = %g, want %g", vcPowSC[i][0], vcPowSC[i][0], f, powSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Pow(pt[0], 0.1), Pow(pt[1], 0.1); !cVeryclose(f0, f1) {
+			t.Errorf("Pow(%g, 0.1) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestRect(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
@@ -733,6 +791,11 @@
 			t.Errorf("Sqrt(%g) = %g, want %g", vcSqrtSC[i], f, sqrtSC[i])
 		}
 	}
+	for _, pt := range branchPoints {
+		if f0, f1 := Sqrt(pt[0]), Sqrt(pt[1]); !cVeryclose(f0, f1) {
+			t.Errorf("Sqrt(%g) not continuous, got %g want %g", pt[0], f0, f1)
+		}
+	}
 }
 func TestTan(t *testing.T) {
 	for i := 0; i < len(vc); i++ {
diff --git a/src/math/cmplx/sqrt.go b/src/math/cmplx/sqrt.go
index 72f81e9..0fbdcde 100644
--- a/src/math/cmplx/sqrt.go
+++ b/src/math/cmplx/sqrt.go
@@ -57,13 +57,14 @@
 // The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
 func Sqrt(x complex128) complex128 {
 	if imag(x) == 0 {
+		// Ensure that imag(r) has the same sign as imag(x) for imag(x) == signed zero.
 		if real(x) == 0 {
-			return complex(0, 0)
+			return complex(0, imag(x))
 		}
 		if real(x) < 0 {
-			return complex(0, math.Sqrt(-real(x)))
+			return complex(0, math.Copysign(math.Sqrt(-real(x)), imag(x)))
 		}
-		return complex(math.Sqrt(real(x)), 0)
+		return complex(math.Sqrt(real(x)), imag(x))
 	}
 	if real(x) == 0 {
 		if imag(x) < 0 {
diff --git a/src/math/const.go b/src/math/const.go
index 20b7065..0fc8715 100644
--- a/src/math/const.go
+++ b/src/math/const.go
@@ -9,18 +9,18 @@
 
 // Mathematical constants.
 const (
-	E   = 2.71828182845904523536028747135266249775724709369995957496696763 // http://oeis.org/A001113
-	Pi  = 3.14159265358979323846264338327950288419716939937510582097494459 // http://oeis.org/A000796
-	Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // http://oeis.org/A001622
+	E   = 2.71828182845904523536028747135266249775724709369995957496696763 // https://oeis.org/A001113
+	Pi  = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796
+	Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // https://oeis.org/A001622
 
-	Sqrt2   = 1.41421356237309504880168872420969807856967187537694807317667974 // http://oeis.org/A002193
-	SqrtE   = 1.64872127070012814684865078781416357165377610071014801157507931 // http://oeis.org/A019774
-	SqrtPi  = 1.77245385090551602729816748334114518279754945612238712821380779 // http://oeis.org/A002161
-	SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // http://oeis.org/A139339
+	Sqrt2   = 1.41421356237309504880168872420969807856967187537694807317667974 // https://oeis.org/A002193
+	SqrtE   = 1.64872127070012814684865078781416357165377610071014801157507931 // https://oeis.org/A019774
+	SqrtPi  = 1.77245385090551602729816748334114518279754945612238712821380779 // https://oeis.org/A002161
+	SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // https://oeis.org/A139339
 
-	Ln2    = 0.693147180559945309417232121458176568075500134360255254120680009 // http://oeis.org/A002162
+	Ln2    = 0.693147180559945309417232121458176568075500134360255254120680009 // https://oeis.org/A002162
 	Log2E  = 1 / Ln2
-	Ln10   = 2.30258509299404568401799145468436420760110148862877297603332790 // http://oeis.org/A002392
+	Ln10   = 2.30258509299404568401799145468436420760110148862877297603332790 // https://oeis.org/A002392
 	Log10E = 1 / Ln10
 )
 
diff --git a/src/math/dim.go b/src/math/dim.go
index 1c634d4..d2e5d47 100644
--- a/src/math/dim.go
+++ b/src/math/dim.go
@@ -10,10 +10,19 @@
 //	Dim(+Inf, +Inf) = NaN
 //	Dim(-Inf, -Inf) = NaN
 //	Dim(x, NaN) = Dim(NaN, x) = NaN
-func Dim(x, y float64) float64
-
-func dim(x, y float64) float64 {
-	return max(x-y, 0)
+func Dim(x, y float64) float64 {
+	// The special cases result in NaN after the subtraction:
+	//      +Inf - +Inf = NaN
+	//      -Inf - -Inf = NaN
+	//       NaN - y    = NaN
+	//         x - NaN  = NaN
+	v := x - y
+	if v <= 0 {
+		// v is negative or 0
+		return 0
+	}
+	// v is positive or NaN
+	return v
 }
 
 // Max returns the larger of x or y.
diff --git a/src/math/dim_386.s b/src/math/dim_386.s
index 22b8abb..2ee1388 100644
--- a/src/math/dim_386.s
+++ b/src/math/dim_386.s
@@ -4,9 +4,6 @@
 
 #include "textflag.h"
 
-TEXT ·Dim(SB),NOSPLIT,$0
-	JMP ·dim(SB)
-
 TEXT ·Max(SB),NOSPLIT,$0
 	JMP ·max(SB)
 
diff --git a/src/math/dim_amd64.s b/src/math/dim_amd64.s
index 249f1b1..85c02e6 100644
--- a/src/math/dim_amd64.s
+++ b/src/math/dim_amd64.s
@@ -8,44 +8,6 @@
 #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    $PosInf, AX
-	ANDQ    DX, BX // x = |x|
-	CMPQ    AX, BX
-	JLT     isDimNaN
-	ANDQ    DX, CX // y = |y|
-	CMPQ    AX, CX
-	JLT     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)
-isDimNaN:
-	MOVQ    $NaN, AX
-	MOVQ    AX, ret+16(FP)
-	RET
-
 // func ·Max(x, y float64) float64
 TEXT ·Max(SB),NOSPLIT,$0
 	// +Inf special cases
diff --git a/src/math/dim_arm.s b/src/math/dim_arm.s
index 642e485..c6f1d87 100644
--- a/src/math/dim_arm.s
+++ b/src/math/dim_arm.s
@@ -4,9 +4,6 @@
 
 #include "textflag.h"
 
-TEXT ·Dim(SB),NOSPLIT,$0
-	B ·dim(SB)
-
 TEXT ·Min(SB),NOSPLIT,$0
 	B ·min(SB)
 
diff --git a/src/math/dim_arm64.s b/src/math/dim_arm64.s
index 4b6b592..2cb866f 100644
--- a/src/math/dim_arm64.s
+++ b/src/math/dim_arm64.s
@@ -8,35 +8,6 @@
 #define NaN    0x7FF8000000000001
 #define NegInf 0xFFF0000000000000
 
-// func Dim(x, y float64) float64
-TEXT ·Dim(SB),NOSPLIT,$0
-	// (+Inf, +Inf) special case
-	MOVD	$PosInf, R0
-	MOVD	x+0(FP), R1
-	MOVD	y+8(FP), R2
-	CMP	R0, R1
-	BNE	dim2
-	CMP	R0, R2
-	BEQ	bothInf
-dim2:	// (-Inf, -Inf) special case
-	MOVD	$NegInf, R0
-	CMP	R0, R1
-	BNE	dim3
-	CMP	R0, R2
-	BEQ	bothInf
-dim3:	// normal case
-	FMOVD	R1, F0
-	FMOVD	R2, F1
-	FMOVD	$0.0, F2
-	FSUBD	F1, F0
-	FMAXD	F0, F2, F0
-	FMOVD	F0, ret+16(FP)
-	RET
-bothInf:
-	MOVD	$NaN, R0
-	MOVD	R0, ret+16(FP)
-	RET
-
 // func ·Max(x, y float64) float64
 TEXT ·Max(SB),NOSPLIT,$0
 	// +Inf special cases
diff --git a/src/math/dim_s390x.s b/src/math/dim_s390x.s
index 503d261..74fdd75 100644
--- a/src/math/dim_s390x.s
+++ b/src/math/dim_s390x.s
@@ -10,42 +10,6 @@
 #define NaN    0x7FF8000000000001
 #define NegInf 0xFFF0000000000000
 
-// func Dim(x, y float64) float64
-TEXT ·Dim(SB),NOSPLIT,$0
-	// (+Inf, +Inf) special case
-	MOVD    x+0(FP), R2
-	MOVD    y+8(FP), R3
-	MOVD    $PosInf, R4
-	CMPUBNE R4, R2, dim2
-	CMPUBEQ R4, R3, bothInf
-dim2:	// (-Inf, -Inf) special case
-	MOVD    $NegInf, R4
-	CMPUBNE R4, R2, dim3
-	CMPUBEQ R4, R3, bothInf
-dim3:	// (NaN, x) or (x, NaN)
-	MOVD    $~(1<<63), R5
-	MOVD    $PosInf, R4
-	AND     R5, R2 // x = |x|
-	CMPUBLT R4, R2, isDimNaN
-	AND     R5, R3 // y = |y|
-	CMPUBLT R4, R3, isDimNaN
-
-	FMOVD   x+0(FP), F1
-	FMOVD   y+8(FP), F2
-	FSUB    F2, F1
-	FMOVD   $(0.0), F2
-	FCMPU   F2, F1
-	BGE     +3(PC)
-	FMOVD   F1, ret+16(FP)
-	RET
-	FMOVD   F2, ret+16(FP)
-	RET
-bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
-isDimNaN:
-	MOVD    $NaN, R4
-	MOVD    R4, ret+16(FP)
-	RET
-
 // func ·Max(x, y float64) float64
 TEXT ·Max(SB),NOSPLIT,$0
 	// +Inf special cases
diff --git a/src/math/erfinv.go b/src/math/erfinv.go
new file mode 100644
index 0000000..21b5578
--- /dev/null
+++ b/src/math/erfinv.go
@@ -0,0 +1,127 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math
+
+/*
+	Inverse of the floating-point error function.
+*/
+
+// This implementation is based on the rational approximation
+// of percentage points of normal distribution available from
+// http://www.jstor.org/stable/2347330.
+
+const (
+	// Coefficients for approximation to erf in |x| <= 0.85
+	a0 = 1.1975323115670912564578e0
+	a1 = 4.7072688112383978012285e1
+	a2 = 6.9706266534389598238465e2
+	a3 = 4.8548868893843886794648e3
+	a4 = 1.6235862515167575384252e4
+	a5 = 2.3782041382114385731252e4
+	a6 = 1.1819493347062294404278e4
+	a7 = 8.8709406962545514830200e2
+	b0 = 1.0000000000000000000e0
+	b1 = 4.2313330701600911252e1
+	b2 = 6.8718700749205790830e2
+	b3 = 5.3941960214247511077e3
+	b4 = 2.1213794301586595867e4
+	b5 = 3.9307895800092710610e4
+	b6 = 2.8729085735721942674e4
+	b7 = 5.2264952788528545610e3
+	// Coefficients for approximation to erf in 0.85 < |x| <= 1-2*exp(-25)
+	c0 = 1.42343711074968357734e0
+	c1 = 4.63033784615654529590e0
+	c2 = 5.76949722146069140550e0
+	c3 = 3.64784832476320460504e0
+	c4 = 1.27045825245236838258e0
+	c5 = 2.41780725177450611770e-1
+	c6 = 2.27238449892691845833e-2
+	c7 = 7.74545014278341407640e-4
+	d0 = 1.4142135623730950488016887e0
+	d1 = 2.9036514445419946173133295e0
+	d2 = 2.3707661626024532365971225e0
+	d3 = 9.7547832001787427186894837e-1
+	d4 = 2.0945065210512749128288442e-1
+	d5 = 2.1494160384252876777097297e-2
+	d6 = 7.7441459065157709165577218e-4
+	d7 = 1.4859850019840355905497876e-9
+	// Coefficients for approximation to erf in 1-2*exp(-25) < |x| < 1
+	e0 = 6.65790464350110377720e0
+	e1 = 5.46378491116411436990e0
+	e2 = 1.78482653991729133580e0
+	e3 = 2.96560571828504891230e-1
+	e4 = 2.65321895265761230930e-2
+	e5 = 1.24266094738807843860e-3
+	e6 = 2.71155556874348757815e-5
+	e7 = 2.01033439929228813265e-7
+	f0 = 1.414213562373095048801689e0
+	f1 = 8.482908416595164588112026e-1
+	f2 = 1.936480946950659106176712e-1
+	f3 = 2.103693768272068968719679e-2
+	f4 = 1.112800997078859844711555e-3
+	f5 = 2.611088405080593625138020e-5
+	f6 = 2.010321207683943062279931e-7
+	f7 = 2.891024605872965461538222e-15
+)
+
+// Erfinv returns the inverse error function of x.
+//
+// Special cases are:
+//	Erfinv(1) = +Inf
+//	Erfinv(-1) = -Inf
+//	Erfinv(x) = NaN if x < -1 or x > 1
+//	Erfinv(NaN) = NaN
+func Erfinv(x float64) float64 {
+	// special cases
+	if IsNaN(x) || x <= -1 || x >= 1 {
+		if x == -1 || x == 1 {
+			return Inf(int(x))
+		}
+		return NaN()
+	}
+
+	sign := false
+	if x < 0 {
+		x = -x
+		sign = true
+	}
+
+	var ans float64
+	if x <= 0.85 { // |x| <= 0.85
+		r := 0.180625 - 0.25*x*x
+		z1 := ((((((a7*r+a6)*r+a5)*r+a4)*r+a3)*r+a2)*r+a1)*r + a0
+		z2 := ((((((b7*r+b6)*r+b5)*r+b4)*r+b3)*r+b2)*r+b1)*r + b0
+		ans = (x * z1) / z2
+	} else {
+		var z1, z2 float64
+		r := Sqrt(Ln2 - Log(1.0-x))
+		if r <= 5.0 {
+			r -= 1.6
+			z1 = ((((((c7*r+c6)*r+c5)*r+c4)*r+c3)*r+c2)*r+c1)*r + c0
+			z2 = ((((((d7*r+d6)*r+d5)*r+d4)*r+d3)*r+d2)*r+d1)*r + d0
+		} else {
+			r -= 5.0
+			z1 = ((((((e7*r+e6)*r+e5)*r+e4)*r+e3)*r+e2)*r+e1)*r + e0
+			z2 = ((((((f7*r+f6)*r+f5)*r+f4)*r+f3)*r+f2)*r+f1)*r + f0
+		}
+		ans = z1 / z2
+	}
+
+	if sign {
+		return -ans
+	}
+	return ans
+}
+
+// Erfcinv returns the inverse of Erfc(x).
+//
+// Special cases are:
+//	Erfcinv(0) = +Inf
+//	Erfcinv(2) = -Inf
+//	Erfcinv(x) = NaN if x < 0 or x > 2
+//	Erfcinv(NaN) = NaN
+func Erfcinv(x float64) float64 {
+	return Erfinv(1 - x)
+}
diff --git a/src/math/example_test.go b/src/math/example_test.go
index 12e9876..feaf9d8 100644
--- a/src/math/example_test.go
+++ b/src/math/example_test.go
@@ -9,6 +9,77 @@
 	"math"
 )
 
+func ExampleAcos() {
+	fmt.Printf("%.2f", math.Acos(1))
+	// Output: 0.00
+}
+
+func ExampleAcosh() {
+	fmt.Printf("%.2f", math.Acosh(1))
+	// Output: 0.00
+}
+
+func ExampleAsin() {
+	fmt.Printf("%.2f", math.Asin(0))
+	// Output: 0.00
+}
+
+func ExampleAsinh() {
+	fmt.Printf("%.2f", math.Asinh(0))
+	// Output: 0.00
+}
+
+func ExampleAtan() {
+	fmt.Printf("%.2f", math.Atan(0))
+	// Output: 0.00
+}
+
+func ExampleAtan2() {
+	fmt.Printf("%.2f", math.Atan2(0, 0))
+	// Output: 0.00
+}
+
+func ExampleAtanh() {
+	fmt.Printf("%.2f", math.Atanh(0))
+	// Output: 0.00
+}
+
+func ExampleCos() {
+	fmt.Printf("%.2f", math.Cos(math.Pi/2))
+	// Output: 0.00
+}
+
+func ExampleCosh() {
+	fmt.Printf("%.2f", math.Cosh(0))
+	// Output: 1.00
+}
+
+func ExampleSin() {
+	fmt.Printf("%.2f", math.Sin(math.Pi))
+	// Output: 0.00
+}
+
+func ExampleSincos() {
+	sin, cos := math.Sincos(0)
+	fmt.Printf("%.2f, %.2f", sin, cos)
+	// Output: 0.00, 1.00
+}
+
+func ExampleSinh() {
+	fmt.Printf("%.2f", math.Sinh(0))
+	// Output: 0.00
+}
+
+func ExampleTan() {
+	fmt.Printf("%.2f", math.Tan(0))
+	// Output: 0.00
+}
+
+func ExampleTanh() {
+	fmt.Printf("%.2f", math.Tanh(0))
+	// Output: 0.00
+}
+
 func ExampleSqrt() {
 	const (
 		a = 3
diff --git a/src/math/exp.go b/src/math/exp.go
index 3268c98..bd4c5c9 100644
--- a/src/math/exp.go
+++ b/src/math/exp.go
@@ -44,7 +44,7 @@
 //      the interval [0,0.34658]:
 //      Write
 //          R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
-//      We use a special Remes algorithm on [0,0.34658] to generate
+//      We use a special Remez algorithm on [0,0.34658] to generate
 //      a polynomial of degree 5 to approximate R. The maximum error
 //      of this polynomial approximation is bounded by 2**-59. In
 //      other words,
@@ -175,7 +175,7 @@
 // exp1 returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2.
 func expmulti(hi, lo float64, k int) float64 {
 	const (
-		P1 = 1.66666666666666019037e-01  /* 0x3FC55555; 0x5555553E */
+		P1 = 1.66666666666666657415e-01  /* 0x3FC55555; 0x55555555 */
 		P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
 		P3 = 6.61375632143793436117e-05  /* 0x3F11566A; 0xAF25DE2C */
 		P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
diff --git a/src/math/exp_amd64.s b/src/math/exp_amd64.s
index 96f01b7..2f7fd76 100644
--- a/src/math/exp_amd64.s
+++ b/src/math/exp_amd64.s
@@ -21,18 +21,21 @@
 #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
 #define Overflow 7.09782712893384e+02
 
+DATA exprodata<>+0(SB)/8, $0.5
+DATA exprodata<>+8(SB)/8, $1.0
+DATA exprodata<>+16(SB)/8, $2.0
+DATA exprodata<>+24(SB)/8, $1.6666666666666666667e-1
+DATA exprodata<>+32(SB)/8, $4.1666666666666666667e-2
+DATA exprodata<>+40(SB)/8, $8.3333333333333333333e-3
+DATA exprodata<>+48(SB)/8, $1.3888888888888888889e-3
+DATA exprodata<>+56(SB)/8, $1.9841269841269841270e-4
+DATA exprodata<>+64(SB)/8, $2.4801587301587301587e-5
+GLOBL exprodata<>+0(SB), RODATA, $72
+
 // func Exp(x float64) float64
 TEXT ·Exp(SB),NOSPLIT,$0
 	// test bits for not-finite
@@ -52,6 +55,8 @@
 	MULSD   X0, X1
 	CVTSD2SL X1, BX // BX = exponent
 	CVTSL2SD BX, X1
+	CMPB ·useFMA(SB), $1
+	JE   avxfma
 	MOVSD   $LN2U, X2
 	MULSD   X1, X2
 	SUBSD   X2, X0
@@ -61,36 +66,37 @@
 	// reduce argument
 	MULSD   $0.0625, X0
 	// Taylor series evaluation
-	MOVSD   $T7, X1
+	MOVSD   exprodata<>+64(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T6, X1
+	ADDSD   exprodata<>+56(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T5, X1
+	ADDSD   exprodata<>+48(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T4, X1
+	ADDSD   exprodata<>+40(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T3, X1
+	ADDSD   exprodata<>+32(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T2, X1
+	ADDSD   exprodata<>+24(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T1, X1
+	ADDSD   exprodata<>+0(SB), X1
 	MULSD   X0, X1
-	ADDSD   $T0, X1
+	ADDSD   exprodata<>+8(SB), X1
 	MULSD   X1, X0
-	MOVSD   $2.0, X1
+	MOVSD   exprodata<>+16(SB), X1
 	ADDSD   X0, X1
 	MULSD   X1, X0
-	MOVSD   $2.0, X1
+	MOVSD   exprodata<>+16(SB), X1
 	ADDSD   X0, X1
 	MULSD   X1, X0
-	MOVSD   $2.0, X1
+	MOVSD   exprodata<>+16(SB), X1
 	ADDSD   X0, X1
 	MULSD   X1, X0
-	MOVSD   $2.0, X1
+	MOVSD   exprodata<>+16(SB), X1
 	ADDSD   X0, X1
 	MULSD   X1, X0
-	ADDSD   $1.0, X0
+	ADDSD exprodata<>+8(SB), X0
 	// return fr * 2**exponent
+lastStep:
 	MOVL    $0x3FF, AX // bias
 	ADDL    AX, BX
 	JLE     underflow
@@ -117,3 +123,30 @@
 notNegInf: // NaN or +Inf, return x
 	MOVQ    BX, ret+8(FP)
 	RET
+
+avxfma:
+	MOVSD   $LN2U, X2
+	VFNMADD231SD X2, X1, X0
+	MOVSD   $LN2L, X2
+	VFNMADD231SD X2, X1, X0
+	// reduce argument
+	MULSD   $0.0625, X0
+	// Taylor series evaluation
+	MOVSD   exprodata<>+64(SB), X1
+	VFMADD213SD exprodata<>+56(SB), X0, X1
+	VFMADD213SD exprodata<>+48(SB), X0, X1
+	VFMADD213SD exprodata<>+40(SB), X0, X1
+	VFMADD213SD exprodata<>+32(SB), X0, X1
+	VFMADD213SD exprodata<>+24(SB), X0, X1
+	VFMADD213SD exprodata<>+0(SB), X0, X1
+	VFMADD213SD exprodata<>+8(SB), X0, X1
+	MULSD   X1, X0
+	VADDSD exprodata<>+16(SB), X0, X1
+	MULSD   X1, X0
+	VADDSD exprodata<>+16(SB), X0, X1
+	MULSD   X1, X0
+	VADDSD exprodata<>+16(SB), X0, X1
+	MULSD   X1, X0
+	VADDSD exprodata<>+16(SB), X0, X1
+	VFMADD213SD   exprodata<>+8(SB), X1, X0
+	JMP lastStep
diff --git a/src/math/exp_asm.go b/src/math/exp_asm.go
new file mode 100644
index 0000000..421618e
--- /dev/null
+++ b/src/math/exp_asm.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 amd64p32
+
+package math
+
+import "internal/cpu"
+
+var useFMA = cpu.X86.HasAVX && cpu.X86.HasFMA
diff --git a/src/math/expm1.go b/src/math/expm1.go
index 7dd75a8..8e77398 100644
--- a/src/math/expm1.go
+++ b/src/math/expm1.go
@@ -205,33 +205,33 @@
 	r1 := 1 + hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))))
 	t := 3 - r1*hfx
 	e := hxs * ((r1 - t) / (6.0 - x*t))
-	if k != 0 {
-		e = (x*(e-c) - c)
-		e -= hxs
-		switch {
-		case k == -1:
-			return 0.5*(x-e) - 0.5
-		case k == 1:
-			if x < -0.25 {
-				return -2 * (e - (x + 0.5))
-			}
-			return 1 + 2*(x-e)
-		case k <= -2 || k > 56: // suffice to return exp(x)-1
-			y := 1 - (e - x)
-			y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
-			return y - 1
+	if k == 0 {
+		return x - (x*e - hxs) // c is 0
+	}
+	e = (x*(e-c) - c)
+	e -= hxs
+	switch {
+	case k == -1:
+		return 0.5*(x-e) - 0.5
+	case k == 1:
+		if x < -0.25 {
+			return -2 * (e - (x + 0.5))
 		}
-		if k < 20 {
-			t := Float64frombits(0x3ff0000000000000 - (0x20000000000000 >> uint(k))) // t=1-2**-k
-			y := t - (e - x)
-			y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
-			return y
-		}
-		t := Float64frombits(uint64(0x3ff-k) << 52) // 2**-k
-		y := x - (e + t)
-		y++
+		return 1 + 2*(x-e)
+	case k <= -2 || k > 56: // suffice to return exp(x)-1
+		y := 1 - (e - x)
+		y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
+		return y - 1
+	}
+	if k < 20 {
+		t := Float64frombits(0x3ff0000000000000 - (0x20000000000000 >> uint(k))) // t=1-2**-k
+		y := t - (e - x)
 		y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
 		return y
 	}
-	return x - (x*e - hxs) // c is 0
+	t = Float64frombits(uint64(0x3ff-k) << 52) // 2**-k
+	y := x - (e + t)
+	y++
+	y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
+	return y
 }
diff --git a/src/math/floor.go b/src/math/floor.go
index 9d30629..18e89ef 100644
--- a/src/math/floor.go
+++ b/src/math/floor.go
@@ -1,4 +1,4 @@
-// Copyright 2009-2010 The Go Authors. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
@@ -54,3 +54,78 @@
 	d, _ := Modf(x)
 	return d
 }
+
+// Round returns the nearest integer, rounding half away from zero.
+//
+// Special cases are:
+//	Round(±0) = ±0
+//	Round(±Inf) = ±Inf
+//	Round(NaN) = NaN
+func Round(x float64) float64 {
+	// Round is a faster implementation of:
+	//
+	// func Round(x float64) float64 {
+	//   t := Trunc(x)
+	//   if Abs(x-t) >= 0.5 {
+	//     return t + Copysign(1, x)
+	//   }
+	//   return t
+	// }
+	bits := Float64bits(x)
+	e := uint(bits>>shift) & mask
+	if e < bias {
+		// Round abs(x) < 1 including denormals.
+		bits &= signMask // +-0
+		if e == bias-1 {
+			bits |= uvone // +-1
+		}
+	} else if e < bias+shift {
+		// Round any abs(x) >= 1 containing a fractional component [0,1).
+		//
+		// Numbers with larger exponents are returned unchanged since they
+		// must be either an integer, infinity, or NaN.
+		const half = 1 << (shift - 1)
+		e -= bias
+		bits += half >> e
+		bits &^= fracMask >> e
+	}
+	return Float64frombits(bits)
+}
+
+// RoundToEven returns the nearest integer, rounding ties to even.
+//
+// Special cases are:
+//	RoundToEven(±0) = ±0
+//	RoundToEven(±Inf) = ±Inf
+//	RoundToEven(NaN) = NaN
+func RoundToEven(x float64) float64 {
+	// RoundToEven is a faster implementation of:
+	//
+	// func RoundToEven(x float64) float64 {
+	//   t := math.Trunc(x)
+	//   odd := math.Remainder(t, 2) != 0
+	//   if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) {
+	//     return t + math.Copysign(1, x)
+	//   }
+	//   return t
+	// }
+	bits := Float64bits(x)
+	e := uint(bits>>shift) & mask
+	if e >= bias {
+		// Round abs(x) >= 1.
+		// - Large numbers without fractional components, infinity, and NaN are unchanged.
+		// - Add 0.499.. or 0.5 before truncating depending on whether the truncated
+		//   number is even or odd (respectively).
+		const halfMinusULP = (1 << (shift - 1)) - 1
+		e -= bias
+		bits += (halfMinusULP + (bits>>(shift-e))&1) >> e
+		bits &^= fracMask >> e
+	} else if e == bias-1 && bits&fracMask != 0 {
+		// Round 0.5 < abs(x) < 1.
+		bits = bits&signMask | uvone // +-1
+	} else {
+		// Round abs(x) <= 0.5 including denormals.
+		bits &= signMask // +-0
+	}
+	return Float64frombits(bits)
+}
diff --git a/src/math/floor_amd64.s b/src/math/floor_amd64.s
index 678d643..4ef02eb 100644
--- a/src/math/floor_amd64.s
+++ b/src/math/floor_amd64.s
@@ -8,12 +8,6 @@
 
 // func Floor(x float64) float64
 TEXT ·Floor(SB),NOSPLIT,$0
-	CMPB    ·useSSE41(SB), $1
-	JNE     nosse4
-	ROUNDSD $1, x+0(FP), X0
-	MOVQ X0, ret+8(FP)
-	RET
-nosse4:
 	MOVQ	x+0(FP), AX
 	MOVQ	$~(1<<63), DX // sign bit mask
 	ANDQ	AX,DX // DX = |x|
@@ -36,12 +30,6 @@
 
 // func Ceil(x float64) float64
 TEXT ·Ceil(SB),NOSPLIT,$0
-	CMPB    ·useSSE41(SB), $1
-	JNE     nosse4
-	ROUNDSD $2, x+0(FP), X0
-	MOVQ X0, ret+8(FP)
-	RET
-nosse4:
 	MOVQ	x+0(FP), AX
 	MOVQ	$~(1<<63), DX // sign bit mask
 	MOVQ	AX, BX // BX = copy of x
diff --git a/src/math/modf_ppc64x.s b/src/math/modf_ppc64x.s
new file mode 100644
index 0000000..da58653
--- /dev/null
+++ b/src/math/modf_ppc64x.s
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ppc64 ppc64le
+
+#include "textflag.h"
+
+// func Modf(f float64) (int float64, frac float64)
+TEXT ·Modf(SB),NOSPLIT,$0
+	FMOVD	f+0(FP), F0
+	FRIZ	F0, F1
+	FMOVD	F1, int+8(FP)
+	FSUB	F1, F0, F2
+	FCPSGN	F2, F0, F2
+	FMOVD	F2, frac+16(FP)
+	RET
diff --git a/src/math/pow.go b/src/math/pow.go
index b3bfadf..336193b 100644
--- a/src/math/pow.go
+++ b/src/math/pow.go
@@ -43,10 +43,6 @@
 		return 1
 	case y == 1:
 		return x
-	case y == 0.5:
-		return Sqrt(x)
-	case y == -0.5:
-		return 1 / Sqrt(x)
 	case IsNaN(x) || IsNaN(y):
 		return NaN()
 	case x == 0:
@@ -81,6 +77,10 @@
 		case y > 0:
 			return Inf(1)
 		}
+	case y == 0.5:
+		return Sqrt(x)
+	case y == -0.5:
+		return 1 / Sqrt(x)
 	}
 
 	absy := y
@@ -94,7 +94,16 @@
 		return NaN()
 	}
 	if yi >= 1<<63 {
-		return Exp(y * Log(x))
+		// yi is a large even int that will lead to overflow (or underflow to 0)
+		// for all x except -1 (x == 1 was handled earlier)
+		switch {
+		case x == -1:
+			return 1
+		case (Abs(x) < 1) == (y > 0):
+			return 0
+		default:
+			return Inf(1)
+		}
 	}
 
 	// ans = a1 * 2**ae (= 1 for now).
@@ -116,6 +125,15 @@
 	// accumulate powers of two into exp.
 	x1, xe := Frexp(x)
 	for i := int64(yi); i != 0; i >>= 1 {
+		if xe < -1<<12 || 1<<12 < xe {
+			// catch xe before it overflows the left shift below
+			// Since i !=0 it has at least one bit still set, so ae will accumulate xe
+			// on at least one more iteration, ae += xe is a lower bound on ae
+			// the lower bound on ae exceeds the size of a float64 exp
+			// so the final call to Ldexp will produce under/overflow (0/Inf)
+			ae += xe
+			break
+		}
 		if i&1 == 1 {
 			a1 *= x1
 			ae += xe
diff --git a/src/math/rand/example_test.go b/src/math/rand/example_test.go
index 614eeae..aa1f2bc 100644
--- a/src/math/rand/example_test.go
+++ b/src/math/rand/example_test.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"math/rand"
 	"os"
+	"strings"
 	"text/tabwriter"
 )
 
@@ -105,3 +106,34 @@
 	// 2
 	// 0
 }
+
+func ExampleShuffle() {
+	words := strings.Fields("ink runs from the corners of my mouth")
+	rand.Shuffle(len(words), func(i, j int) {
+		words[i], words[j] = words[j], words[i]
+	})
+	fmt.Println(words)
+
+	// Output:
+	// [mouth my the of runs corners from ink]
+}
+
+func ExampleShuffle_slicesInUnison() {
+	numbers := []byte("12345")
+	letters := []byte("ABCDE")
+	// Shuffle numbers, swapping corresponding entries in letters at the same time.
+	rand.Shuffle(len(numbers), func(i, j int) {
+		numbers[i], numbers[j] = numbers[j], numbers[i]
+		letters[i], letters[j] = letters[j], letters[i]
+	})
+	for i := range numbers {
+		fmt.Printf("%c: %c\n", letters[i], numbers[i])
+	}
+
+	// Output:
+	// C: 3
+	// D: 4
+	// A: 1
+	// E: 5
+	// B: 2
+}
diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go
index fe99c94..147c92f 100644
--- a/src/math/rand/rand.go
+++ b/src/math/rand/rand.go
@@ -135,6 +135,30 @@
 	return v % n
 }
 
+// int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
+// n must be > 0, but int31n does not check this; the caller must ensure it.
+// int31n exists because Int31n is inefficient, but Go 1 compatibility
+// requires that the stream of values produced by math/rand remain unchanged.
+// int31n can thus only be used internally, by newly introduced APIs.
+//
+// For implementation details, see:
+// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction
+// https://lemire.me/blog/2016/06/30/fast-random-shuffling
+func (r *Rand) int31n(n int32) int32 {
+	v := r.Uint32()
+	prod := uint64(v) * uint64(n)
+	low := uint32(prod)
+	if low < uint32(n) {
+		thresh := uint32(-n) % uint32(n)
+		for low < thresh {
+			v = r.Uint32()
+			prod = uint64(v) * uint64(n)
+			low = uint32(prod)
+		}
+	}
+	return int32(prod >> 32)
+}
+
 // Intn returns, as an int, a non-negative pseudo-random number in [0,n).
 // It panics if n <= 0.
 func (r *Rand) Intn(n int) int {
@@ -202,6 +226,31 @@
 	return m
 }
 
+// Shuffle pseudo-randomizes the order of elements.
+// n is the number of elements. Shuffle panics if n < 0.
+// swap swaps the elements with indexes i and j.
+func (r *Rand) Shuffle(n int, swap func(i, j int)) {
+	if n < 0 {
+		panic("invalid argument to Shuffle")
+	}
+
+	// Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
+	// Shuffle really ought not be called with n that doesn't fit in 32 bits.
+	// Not only will it take a very long time, but with 2³¹! possible permutations,
+	// there's no way that any PRNG can have a big enough internal state to
+	// generate even a minuscule percentage of the possible permutations.
+	// Nevertheless, the right API signature accepts an int n, so handle it as best we can.
+	i := n - 1
+	for ; i > 1<<31-1-1; i-- {
+		j := int(r.Int63n(int64(i + 1)))
+		swap(i, j)
+	}
+	for ; i > 0; i-- {
+		j := int(r.int31n(int32(i + 1)))
+		swap(i, j)
+	}
+}
+
 // Read generates len(p) random bytes and writes them into p. It
 // always returns len(p) and a nil error.
 // Read should not be called concurrently with any other Rand method.
@@ -288,6 +337,11 @@
 // from the default Source.
 func Perm(n int) []int { return globalRand.Perm(n) }
 
+// Shuffle pseudo-randomizes the order of elements using the default Source.
+// n is the number of elements. Shuffle panics if n < 0.
+// swap swaps the elements with indexes i and j.
+func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) }
+
 // Read generates len(p) random bytes from the default Source and
 // writes them into p. It always returns len(p) and a nil error.
 // Read, unlike the Rand.Read method, is safe for concurrent use.
@@ -339,7 +393,7 @@
 	r.lk.Unlock()
 }
 
-// seedPos implements Seed for a lockedSource without a race condiiton.
+// seedPos implements Seed for a lockedSource without a race condition.
 func (r *lockedSource) seedPos(seed int64, readPos *int8) {
 	r.lk.Lock()
 	r.src.Seed(seed)
diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go
index bf509e0..e663b84 100644
--- a/src/math/rand/rand_test.go
+++ b/src/math/rand/rand_test.go
@@ -53,7 +53,7 @@
 		fmt.Println(s)
 		return errors.New(s)
 	}
-	if !nearEqual(this.stddev, expected.stddev, 0, expected.maxError) {
+	if !nearEqual(this.stddev, expected.stddev, expected.closeEnough, expected.maxError) {
 		s := fmt.Sprintf("stddev %v != %v (allowed error %v, %v)", this.stddev, expected.stddev, expected.closeEnough, expected.maxError)
 		fmt.Println(s)
 		return errors.New(s)
@@ -74,6 +74,7 @@
 }
 
 func checkSampleDistribution(t *testing.T, samples []float64, expected *statsResults) {
+	t.Helper()
 	actual := getStatsResults(samples)
 	err := actual.checkSimilarDistribution(expected)
 	if err != nil {
@@ -82,6 +83,7 @@
 }
 
 func checkSampleSliceDistributions(t *testing.T, samples []float64, nslices int, expected *statsResults) {
+	t.Helper()
 	chunk := len(samples) / nslices
 	for i := 0; i < nslices; i++ {
 		low := i * chunk
@@ -374,7 +376,7 @@
 	// Expect a uniform distribution of byte values, which lie in [0, 255].
 	var (
 		mean       = 255.0 / 2
-		stddev     = math.Sqrt(255.0 * 255.0 / 12.0)
+		stddev     = 256.0 / math.Sqrt(12.0)
 		errorScale = stddev / math.Sqrt(float64(n))
 	)
 
@@ -448,6 +450,113 @@
 	}
 }
 
+func TestShuffleSmall(t *testing.T) {
+	// Check that Shuffle allows n=0 and n=1, but that swap is never called for them.
+	r := New(NewSource(1))
+	for n := 0; n <= 1; n++ {
+		r.Shuffle(n, func(i, j int) { t.Fatalf("swap called, n=%d i=%d j=%d", n, i, j) })
+	}
+}
+
+// encodePerm converts from a permuted slice of length n, such as Perm generates, to an int in [0, n!).
+// See https://en.wikipedia.org/wiki/Lehmer_code.
+// encodePerm modifies the input slice.
+func encodePerm(s []int) int {
+	// Convert to Lehmer code.
+	for i, x := range s {
+		r := s[i+1:]
+		for j, y := range r {
+			if y > x {
+				r[j]--
+			}
+		}
+	}
+	// Convert to int in [0, n!).
+	m := 0
+	fact := 1
+	for i := len(s) - 1; i >= 0; i-- {
+		m += s[i] * fact
+		fact *= len(s) - i
+	}
+	return m
+}
+
+// TestUniformFactorial tests several ways of generating a uniform value in [0, n!).
+func TestUniformFactorial(t *testing.T) {
+	r := New(NewSource(testSeeds[0]))
+	top := 6
+	if testing.Short() {
+		top = 4
+	}
+	for n := 3; n <= top; n++ {
+		t.Run(fmt.Sprintf("n=%d", n), func(t *testing.T) {
+			// Calculate n!.
+			nfact := 1
+			for i := 2; i <= n; i++ {
+				nfact *= i
+			}
+
+			// Test a few different ways to generate a uniform distribution.
+			p := make([]int, n) // re-usable slice for Shuffle generator
+			tests := [...]struct {
+				name string
+				fn   func() int
+			}{
+				{name: "Int31n", fn: func() int { return int(r.Int31n(int32(nfact))) }},
+				{name: "int31n", fn: func() int { return int(r.int31n(int32(nfact))) }},
+				{name: "Perm", fn: func() int { return encodePerm(r.Perm(n)) }},
+				{name: "Shuffle", fn: func() int {
+					// Generate permutation using Shuffle.
+					for i := range p {
+						p[i] = i
+					}
+					r.Shuffle(n, func(i, j int) { p[i], p[j] = p[j], p[i] })
+					return encodePerm(p)
+				}},
+			}
+
+			for _, test := range tests {
+				t.Run(test.name, func(t *testing.T) {
+					// Gather chi-squared values and check that they follow
+					// the expected normal distribution given n!-1 degrees of freedom.
+					// See https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test and
+					// https://www.johndcook.com/Beautiful_Testing_ch10.pdf.
+					nsamples := 10 * nfact
+					if nsamples < 200 {
+						nsamples = 200
+					}
+					samples := make([]float64, nsamples)
+					for i := range samples {
+						// Generate some uniformly distributed values and count their occurrences.
+						const iters = 1000
+						counts := make([]int, nfact)
+						for i := 0; i < iters; i++ {
+							counts[test.fn()]++
+						}
+						// Calculate chi-squared and add to samples.
+						want := iters / float64(nfact)
+						var χ2 float64
+						for _, have := range counts {
+							err := float64(have) - want
+							χ2 += err * err
+						}
+						χ2 /= want
+						samples[i] = χ2
+					}
+
+					// Check that our samples approximate the appropriate normal distribution.
+					dof := float64(nfact - 1)
+					expected := &statsResults{mean: dof, stddev: math.Sqrt(2 * dof)}
+					errorScale := max(1.0, expected.stddev)
+					expected.closeEnough = 0.10 * errorScale
+					expected.maxError = 0.08 // TODO: What is the right value here? See issue 21211.
+					checkSampleDistribution(t, samples, expected)
+				})
+			}
+		})
+	}
+}
+
 // Benchmarks
 
 func BenchmarkInt63Threadsafe(b *testing.B) {
@@ -512,6 +621,30 @@
 	}
 }
 
+func BenchmarkPerm30ViaShuffle(b *testing.B) {
+	r := New(NewSource(1))
+	for n := b.N; n > 0; n-- {
+		p := make([]int, 30)
+		for i := range p {
+			p[i] = i
+		}
+		r.Shuffle(30, func(i, j int) { p[i], p[j] = p[j], p[i] })
+	}
+}
+
+// BenchmarkShuffleOverhead uses a minimal swap function
+// to measure just the shuffling overhead.
+func BenchmarkShuffleOverhead(b *testing.B) {
+	r := New(NewSource(1))
+	for n := b.N; n > 0; n-- {
+		r.Shuffle(52, func(i, j int) {
+			if i < 0 || i >= 52 || j < 0 || j >= 52 {
+				b.Fatalf("bad swap(%d, %d)", i, j)
+			}
+		})
+	}
+}
+
 func BenchmarkRead3(b *testing.B) {
 	r := New(NewSource(1))
 	buf := make([]byte, 3)
diff --git a/src/math/sin_s390x.s b/src/math/sin_s390x.s
index 39cc054..e2201e0 100644
--- a/src/math/sin_s390x.s
+++ b/src/math/sin_s390x.s
@@ -110,7 +110,7 @@
 	WFMDB   V1, V1, V2
 	LGDR    F3, R1
 	MOVD    $sincosxlim<>+0(SB), R2
-	WORD    $0xA7110001     //tmll  %r1,1
+	TMLL	R1, $1
 	BEQ     L6
 	FMOVD   0(R2), F0
 	WFCHDBS V0, V5, V0
@@ -134,7 +134,7 @@
 	WFMADB  V2, V0, V3, V0
 	FMOVD   0(R2), F6
 	WFMADB  V1, V4, V6, V4
-	WORD    $0xA7110002     //tmll  %r1,2
+	TMLL	R1, $2
 	WFMADB  V2, V0, V4, V0
 	MOVD    $sincosc0<>+0(SB), R1
 	FMOVD   0(R1), F2
@@ -170,7 +170,7 @@
 	FNEG    F6, F4
 	WFMADB  V2, V0, V3, V2
 	WFMDB   V4, V1, V0
-	WORD    $0xA7110002     //tmll  %r1,2
+	TMLL	R1, $2
 	WFMSDB  V0, V2, V6, V0
 	BNE     L15
 	FMOVD   F0, ret+8(FP)
@@ -261,7 +261,7 @@
 	FMOVD   0(R2), F5
 	WFMDB   V2, V2, V6
 	MOVD    $sincosxlim<>+0(SB), R2
-	WORD    $0xA7110001     //tmll %r1,1
+	TMLL	R1, $1
 	BNE     L25
 	FMOVD   0(R2), F0
 	WFCHDBS V0, V1, V0
@@ -285,7 +285,7 @@
 	WFMADB  V6, V0, V3, V0
 	FMOVD   0(R2), F1
 	WFMADB  V2, V4, V1, V4
-	WORD    $0xA7110002     //tmll %r1,2
+	TMLL	R1, $2
 	WFMADB  V6, V0, V4, V0
 	MOVD    $sincosc0<>+0(SB), R1
 	FMOVD   0(R1), F4
@@ -320,7 +320,7 @@
 	FMADD   F3, F2, F1
 	FMUL    F0, F2
 	WFMADB  V6, V4, V1, V6
-	WORD    $0xA7110002     //tmll  %r1,2
+	TMLL	R1, $2
 	FMADD   F6, F2, F0
 	BNE     L34
 	FMOVD   F0, ret+8(FP)
diff --git a/src/math/sqrt_mipsx.s b/src/math/sqrt_mipsx.s
index 1b27d49..a63ea9e 100644
--- a/src/math/sqrt_mipsx.s
+++ b/src/math/sqrt_mipsx.s
@@ -8,7 +8,11 @@
 
 // func Sqrt(x float64) float64
 TEXT ·Sqrt(SB),NOSPLIT,$0
+#ifdef GOMIPS_softfloat
+	JMP ·sqrt(SB)
+#else
 	MOVD	x+0(FP), F0
 	SQRTD	F0, F0
 	MOVD	F0, ret+8(FP)
+#endif
 	RET
diff --git a/src/math/stubs_mips64x.s b/src/math/stubs_mips64x.s
index a0e0e38..b3ffa5b 100644
--- a/src/math/stubs_mips64x.s
+++ b/src/math/stubs_mips64x.s
@@ -27,9 +27,6 @@
 TEXT ·Atanh(SB),NOSPLIT,$0
 	JMP ·atanh(SB)
 
-TEXT ·Dim(SB),NOSPLIT,$0
-	JMP ·dim(SB)
-
 TEXT ·Min(SB),NOSPLIT,$0
 	JMP ·min(SB)
 
diff --git a/src/math/stubs_mipsx.s b/src/math/stubs_mipsx.s
index e959f07..129898e 100644
--- a/src/math/stubs_mipsx.s
+++ b/src/math/stubs_mipsx.s
@@ -27,9 +27,6 @@
 TEXT ·Atanh(SB),NOSPLIT,$0
 	JMP	·atanh(SB)
 
-TEXT ·Dim(SB),NOSPLIT,$0
-	JMP	·dim(SB)
-
 TEXT ·Min(SB),NOSPLIT,$0
 	JMP	·min(SB)
 
diff --git a/src/math/stubs_ppc64x.s b/src/math/stubs_ppc64x.s
index 9d46ebf..dc5d615 100644
--- a/src/math/stubs_ppc64x.s
+++ b/src/math/stubs_ppc64x.s
@@ -27,9 +27,6 @@
 TEXT ·Atanh(SB),NOSPLIT,$0
 	BR ·atanh(SB)
 
-TEXT ·Dim(SB),NOSPLIT,$0
-	BR ·dim(SB)
-
 TEXT ·Min(SB),NOSPLIT,$0
 	BR ·min(SB)
 
@@ -72,9 +69,6 @@
 TEXT ·Log(SB),NOSPLIT,$0
 	BR ·log(SB)
 
-TEXT ·Modf(SB),NOSPLIT,$0
-	BR ·modf(SB)
-
 TEXT ·Mod(SB),NOSPLIT,$0
 	BR ·mod(SB)
 
diff --git a/src/mime/mediatype.go b/src/mime/mediatype.go
index 5557672..426d417 100644
--- a/src/mime/mediatype.go
+++ b/src/mime/mediatype.go
@@ -171,8 +171,9 @@
 	for key, pieceMap := range continuation {
 		singlePartKey := key + "*"
 		if v, ok := pieceMap[singlePartKey]; ok {
-			decv := decode2231Enc(v)
-			params[key] = decv
+			if decv, ok := decode2231Enc(v); ok {
+				params[key] = decv
+			}
 			continue
 		}
 
@@ -186,16 +187,18 @@
 				continue
 			}
 			encodedPart := simplePart + "*"
-			if v, ok := pieceMap[encodedPart]; ok {
-				valid = true
-				if n == 0 {
-					buf.WriteString(decode2231Enc(v))
-				} else {
-					decv, _ := percentHexUnescape(v)
+			v, ok := pieceMap[encodedPart]
+			if !ok {
+				break
+			}
+			valid = true
+			if n == 0 {
+				if decv, ok := decode2231Enc(v); ok {
 					buf.WriteString(decv)
 				}
 			} else {
-				break
+				decv, _ := percentHexUnescape(v)
+				buf.WriteString(decv)
 			}
 		}
 		if valid {
@@ -206,21 +209,27 @@
 	return
 }
 
-func decode2231Enc(v string) string {
+func decode2231Enc(v string) (string, bool) {
 	sv := strings.SplitN(v, "'", 3)
 	if len(sv) != 3 {
-		return ""
+		return "", false
 	}
 	// TODO: ignoring lang in sv[1] for now. If anybody needs it we'll
 	// need to decide how to expose it in the API. But I'm not sure
 	// anybody uses it in practice.
 	charset := strings.ToLower(sv[0])
+	if len(charset) == 0 {
+		return "", false
+	}
 	if charset != "us-ascii" && charset != "utf-8" {
 		// TODO: unsupported encoding
-		return ""
+		return "", false
 	}
-	encv, _ := percentHexUnescape(sv[2])
-	return encv
+	encv, err := percentHexUnescape(sv[2])
+	if err != nil {
+		return "", false
+	}
+	return encv, true
 }
 
 func isNotTokenChar(r rune) bool {
diff --git a/src/mime/mediatype_test.go b/src/mime/mediatype_test.go
index 3ba8ee1..88d742f 100644
--- a/src/mime/mediatype_test.go
+++ b/src/mime/mediatype_test.go
@@ -139,79 +139,248 @@
 
 		// Tests from http://greenbytes.de/tech/tc2231/
 		// Note: Backslash escape handling is a bit loose, like MSIE.
-		// TODO(bradfitz): add the rest of the tests from that site.
+
+		// #attonly
+		{`attachment`,
+			"attachment",
+			m()},
+		// #attonlyucase
+		{`ATTACHMENT`,
+			"attachment",
+			m()},
+		// #attwithasciifilename
+		{`attachment; filename="foo.html"`,
+			"attachment",
+			m("filename", "foo.html")},
+		// #attwithasciifilename25
+		{`attachment; filename="0000000000111111111122222"`,
+			"attachment",
+			m("filename", "0000000000111111111122222")},
+		// #attwithasciifilename35
+		{`attachment; filename="00000000001111111111222222222233333"`,
+			"attachment",
+			m("filename", "00000000001111111111222222222233333")},
+		// #attwithasciifnescapedchar
 		{`attachment; filename="f\oo.html"`,
 			"attachment",
 			m("filename", "f\\oo.html")},
+		// #attwithasciifnescapedquote
 		{`attachment; filename="\"quoting\" tested.html"`,
 			"attachment",
 			m("filename", `"quoting" tested.html`)},
+		// #attwithquotedsemicolon
 		{`attachment; filename="Here's a semicolon;.html"`,
 			"attachment",
 			m("filename", "Here's a semicolon;.html")},
+		// #attwithfilenameandextparam
+		{`attachment; foo="bar"; filename="foo.html"`,
+			"attachment",
+			m("foo", "bar", "filename", "foo.html")},
+		// #attwithfilenameandextparamescaped
 		{`attachment; foo="\"\\";filename="foo.html"`,
 			"attachment",
 			m("foo", "\"\\", "filename", "foo.html")},
+		// #attwithasciifilenameucase
+		{`attachment; FILENAME="foo.html"`,
+			"attachment",
+			m("filename", "foo.html")},
+		// #attwithasciifilenamenq
 		{`attachment; filename=foo.html`,
 			"attachment",
 			m("filename", "foo.html")},
+		// #attwithasciifilenamenqs
 		{`attachment; filename=foo.html ;`,
 			"attachment",
 			m("filename", "foo.html")},
+		// #attwithfntokensq
 		{`attachment; filename='foo.html'`,
 			"attachment",
 			m("filename", "'foo.html'")},
+		// #attwithisofnplain
+		{`attachment; filename="foo-ä.html"`,
+			"attachment",
+			m("filename", "foo-ä.html")},
+		// #attwithutf8fnplain
+		{`attachment; filename="foo-ä.html"`,
+			"attachment",
+			m("filename", "foo-ä.html")},
+		// #attwithfnrawpctenca
 		{`attachment; filename="foo-%41.html"`,
 			"attachment",
 			m("filename", "foo-%41.html")},
+		// #attwithfnusingpct
+		{`attachment; filename="50%.html"`,
+			"attachment",
+			m("filename", "50%.html")},
+		// #attwithfnrawpctencaq
 		{`attachment; filename="foo-%\41.html"`,
 			"attachment",
 			m("filename", "foo-%\\41.html")},
+		// #attwithnamepct
+		{`attachment; name="foo-%41.html"`,
+			"attachment",
+			m("name", "foo-%41.html")},
+		// #attwithfilenamepctandiso
+		{`attachment; name="ä-%41.html"`,
+			"attachment",
+			m("name", "ä-%41.html")},
+		// #attwithfnrawpctenclong
+		{`attachment; filename="foo-%c3%a4-%e2%82%ac.html"`,
+			"attachment",
+			m("filename", "foo-%c3%a4-%e2%82%ac.html")},
+		// #attwithasciifilenamews1
+		{`attachment; filename ="foo.html"`,
+			"attachment",
+			m("filename", "foo.html")},
+		// #attmissingdisposition
 		{`filename=foo.html`,
 			"", m()},
+		// #attmissingdisposition2
 		{`x=y; filename=foo.html`,
 			"", m()},
+		// #attmissingdisposition3
 		{`"foo; filename=bar;baz"; filename=qux`,
 			"", m()},
+		// #attmissingdisposition4
+		{`filename=foo.html, filename=bar.html`,
+			"", m()},
+		// #emptydisposition
+		{`; filename=foo.html`,
+			"", m()},
+		// #doublecolon
+		{`: inline; attachment; filename=foo.html`,
+			"", m()},
+		// #attandinline
 		{`inline; attachment; filename=foo.html`,
 			"", m()},
+		// #attandinline2
+		{`attachment; inline; filename=foo.html`,
+			"", m()},
+		// #attbrokenquotedfn
 		{`attachment; filename="foo.html".txt`,
 			"", m()},
+		// #attbrokenquotedfn2
 		{`attachment; filename="bar`,
 			"", m()},
+		// #attbrokenquotedfn3
+		{`attachment; filename=foo"bar;baz"qux`,
+			"", m()},
+		// #attmultinstances
+		{`attachment; filename=foo.html, attachment; filename=bar.html`,
+			"", m()},
+		// #attmissingdelim
+		{`attachment; foo=foo filename=bar`,
+			"", m()},
+		// #attmissingdelim2
+		{`attachment; filename=bar foo=foo`,
+			"", m()},
+		// #attmissingdelim3
+		{`attachment filename=bar`,
+			"", m()},
+		// #attreversed
+		{`filename=foo.html; attachment`,
+			"", m()},
+		// #attconfusedparam
+		{`attachment; xfilename=foo.html`,
+			"attachment",
+			m("xfilename", "foo.html")},
+		// #attcdate
 		{`attachment; creation-date="Wed, 12 Feb 1997 16:29:51 -0500"`,
 			"attachment",
 			m("creation-date", "Wed, 12 Feb 1997 16:29:51 -0500")},
+		// #attmdate
+		{`attachment; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"`,
+			"attachment",
+			m("modification-date", "Wed, 12 Feb 1997 16:29:51 -0500")},
+		// #dispext
 		{`foobar`, "foobar", m()},
+		// #dispextbadfn
+		{`attachment; example="filename=example.txt"`,
+			"attachment",
+			m("example", "filename=example.txt")},
+		// #attwithfn2231utf8
+		{`attachment; filename*=UTF-8''foo-%c3%a4-%e2%82%ac.html`,
+			"attachment",
+			m("filename", "foo-ä-€.html")},
+		// #attwithfn2231noc
+		{`attachment; filename*=''foo-%c3%a4-%e2%82%ac.html`,
+			"attachment",
+			m()},
+		// #attwithfn2231utf8comp
+		{`attachment; filename*=UTF-8''foo-a%cc%88.html`,
+			"attachment",
+			m("filename", "foo-ä.html")},
+		// #attwithfn2231ws2
+		{`attachment; filename*= UTF-8''foo-%c3%a4.html`,
+			"attachment",
+			m("filename", "foo-ä.html")},
+		// #attwithfn2231ws3
 		{`attachment; filename* =UTF-8''foo-%c3%a4.html`,
 			"attachment",
 			m("filename", "foo-ä.html")},
+		// #attwithfn2231quot
+		{`attachment; filename*="UTF-8''foo-%c3%a4.html"`,
+			"attachment",
+			m("filename", "foo-ä.html")},
+		// #attwithfn2231quot2
+		{`attachment; filename*="foo%20bar.html"`,
+			"attachment",
+			m()},
+		// #attwithfn2231singleqmissing
+		{`attachment; filename*=UTF-8'foo-%c3%a4.html`,
+			"attachment",
+			m()},
+		// #attwithfn2231nbadpct1
+		{`attachment; filename*=UTF-8''foo%`,
+			"attachment",
+			m()},
+		// #attwithfn2231nbadpct2
+		{`attachment; filename*=UTF-8''f%oo.html`,
+			"attachment",
+			m()},
+		// #attwithfn2231dpct
 		{`attachment; filename*=UTF-8''A-%2541.html`,
 			"attachment",
 			m("filename", "A-%41.html")},
+		// #attfncont
 		{`attachment; filename*0="foo."; filename*1="html"`,
 			"attachment",
 			m("filename", "foo.html")},
+		// #attfncontenc
 		{`attachment; filename*0*=UTF-8''foo-%c3%a4; filename*1=".html"`,
 			"attachment",
 			m("filename", "foo-ä.html")},
+		// #attfncontlz
 		{`attachment; filename*0="foo"; filename*01="bar"`,
 			"attachment",
 			m("filename", "foo")},
+		// #attfncontnc
 		{`attachment; filename*0="foo"; filename*2="bar"`,
 			"attachment",
 			m("filename", "foo")},
-		{`attachment; filename*1="foo"; filename*2="bar"`,
+		// #attfnconts1
+		{`attachment; filename*1="foo."; filename*2="html"`,
 			"attachment", m()},
+		// #attfncontord
 		{`attachment; filename*1="bar"; filename*0="foo"`,
 			"attachment",
 			m("filename", "foobar")},
+		// #attfnboth
 		{`attachment; filename="foo-ae.html"; filename*=UTF-8''foo-%c3%a4.html`,
 			"attachment",
 			m("filename", "foo-ä.html")},
+		// #attfnboth2
 		{`attachment; filename*=UTF-8''foo-%c3%a4.html; filename="foo-ae.html"`,
 			"attachment",
 			m("filename", "foo-ä.html")},
+		// #attfnboth3
+		{`attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4; filename*=ISO-8859-1''currency-sign%3d%a4`,
+			"attachment",
+			m()},
+		// #attnewandfn
+		{`attachment; foobar=x; filename="foo.html"`,
+			"attachment",
+			m("foobar", "x", "filename", "foo.html")},
 
 		// Browsers also just send UTF-8 directly without RFC 2231,
 		// at least when the source page is served with UTF-8.
@@ -265,6 +434,16 @@
 		"application/pdf", "mime: invalid media parameter"},
 	{"bogus/<script>alert</script>", "", "mime: expected token after slash"},
 	{"bogus/bogus<script>alert</script>", "", "mime: unexpected content after media subtype"},
+	// Tests from http://greenbytes.de/tech/tc2231/
+	{`"attachment"`, "attachment", "mime: no media type"},
+	{"attachment; filename=foo,bar.html", "attachment", "mime: invalid media parameter"},
+	{"attachment; ;filename=foo", "attachment", "mime: invalid media parameter"},
+	{"attachment; filename=foo bar.html", "attachment", "mime: invalid media parameter"},
+	{`attachment; filename="foo.html"; filename="bar.html"`, "attachment", "mime: duplicate parameter name"},
+	{"attachment; filename=foo[1](2).html", "attachment", "mime: invalid media parameter"},
+	{"attachment; filename=foo-ä.html", "attachment", "mime: invalid media parameter"},
+	{"attachment; filename=foo-ä.html", "attachment", "mime: invalid media parameter"},
+	{`attachment; filename *=UTF-8''foo-%c3%a4.html`, "attachment", "mime: invalid media parameter"},
 }
 
 func TestParseMediaTypeBogus(t *testing.T) {
diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go
index 832d0ad..2a4ebdd 100644
--- a/src/mime/multipart/formdata.go
+++ b/src/mime/multipart/formdata.go
@@ -58,7 +58,8 @@
 
 		var b bytes.Buffer
 
-		if filename == "" {
+		_, hasContentTypeHeader := p.Header["Content-Type"]
+		if !hasContentTypeHeader && filename == "" {
 			// value, store as string in memory
 			n, err := io.CopyN(&b, p, maxValueBytes+1)
 			if err != nil && err != io.EOF {
diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
index 979ae5c..69333d3 100644
--- a/src/mime/multipart/formdata_test.go
+++ b/src/mime/multipart/formdata_test.go
@@ -38,6 +38,23 @@
 	fd.Close()
 }
 
+func TestReadFormWithNamelessFile(t *testing.T) {
+	b := strings.NewReader(strings.Replace(messageWithFileWithoutName, "\n", "\r\n", -1))
+	r := NewReader(b, boundary)
+	f, err := r.ReadForm(25)
+	if err != nil {
+		t.Fatal("ReadForm:", err)
+	}
+	defer f.RemoveAll()
+
+	fd := testFile(t, f.File["hiddenfile"][0], "", filebContents)
+	if _, ok := fd.(sectionReadCloser); !ok {
+		t.Errorf("file has unexpected underlying type %T", fd)
+	}
+	fd.Close()
+
+}
+
 func testFile(t *testing.T, fh *FileHeader, efn, econtent string) File {
 	if fh.Filename != efn {
 		t.Errorf("filename = %q, want %q", fh.Filename, efn)
@@ -68,6 +85,15 @@
 	boundary      = `MyBoundary`
 )
 
+const messageWithFileWithoutName = `
+--MyBoundary
+Content-Disposition: form-data; name="hiddenfile"; filename=""
+Content-Type: text/plain
+
+` + filebContents + `
+--MyBoundary--
+`
+
 const message = `
 --MyBoundary
 Content-Disposition: form-data; name="filea"; filename="filea.txt"
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index d5173d6..1baa01f 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -12,7 +12,6 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
-#include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 */
@@ -95,15 +94,14 @@
 }
 
 func cgoLookupServicePort(hints *C.struct_addrinfo, network, service string) (port int, err error) {
-	s := C.CString(service)
-	// Lowercase the service name in the C-allocated memory.
-	for i := 0; i < len(service); i++ {
-		bp := (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + uintptr(i)))
-		*bp = lowerASCII(*bp)
+	cservice := make([]byte, len(service)+1)
+	copy(cservice, service)
+	// Lowercase the C service name.
+	for i, b := range cservice[:len(service)] {
+		cservice[i] = lowerASCII(b)
 	}
 	var res *C.struct_addrinfo
-	defer C.free(unsafe.Pointer(s))
-	gerrno, err := C.getaddrinfo(nil, s, hints, &res)
+	gerrno, err := C.getaddrinfo(nil, (*C.char)(unsafe.Pointer(&cservice[0])), hints, &res)
 	if gerrno != 0 {
 		switch gerrno {
 		case C.EAI_SYSTEM:
@@ -145,10 +143,10 @@
 	hints.ai_flags = cgoAddrInfoFlags
 	hints.ai_socktype = C.SOCK_STREAM
 
-	h := C.CString(name)
-	defer C.free(unsafe.Pointer(h))
+	h := make([]byte, len(name)+1)
+	copy(h, name)
 	var res *C.struct_addrinfo
-	gerrno, err := C.getaddrinfo(h, nil, &hints, &res)
+	gerrno, err := C.getaddrinfo((*C.char)(unsafe.Pointer(&h[0])), nil, &hints, &res)
 	if gerrno != 0 {
 		switch gerrno {
 		case C.EAI_SYSTEM:
diff --git a/src/net/cgo_unix_test.go b/src/net/cgo_unix_test.go
index e861c7a..b476a6d 100644
--- a/src/net/cgo_unix_test.go
+++ b/src/net/cgo_unix_test.go
@@ -13,6 +13,7 @@
 )
 
 func TestCgoLookupIP(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx := context.Background()
 	_, err, ok := cgoLookupIP(ctx, "localhost")
 	if !ok {
@@ -24,6 +25,7 @@
 }
 
 func TestCgoLookupIPWithCancel(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	_, err, ok := cgoLookupIP(ctx, "localhost")
@@ -36,6 +38,7 @@
 }
 
 func TestCgoLookupPort(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx := context.Background()
 	_, err, ok := cgoLookupPort(ctx, "tcp", "smtp")
 	if !ok {
@@ -47,6 +50,7 @@
 }
 
 func TestCgoLookupPortWithCancel(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	_, err, ok := cgoLookupPort(ctx, "tcp", "smtp")
@@ -59,6 +63,7 @@
 }
 
 func TestCgoLookupPTR(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx := context.Background()
 	_, err, ok := cgoLookupPTR(ctx, "127.0.0.1")
 	if !ok {
@@ -70,6 +75,7 @@
 }
 
 func TestCgoLookupPTRWithCancel(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	_, err, ok := cgoLookupPTR(ctx, "127.0.0.1")
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index a892bf1..b5f1dc9 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -10,6 +10,7 @@
 	"internal/poll"
 	"internal/testenv"
 	"io"
+	"os"
 	"runtime"
 	"sync"
 	"testing"
@@ -85,11 +86,6 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort()
-	if closedPortDelay > expectClosedPortDelay {
-		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
-	}
-
 	before := sw.Sockets()
 	origTestHookLookupIP := testHookLookupIP
 	defer func() { testHookLookupIP = origTestHookLookupIP }()
@@ -115,7 +111,7 @@
 	const N = 10
 	var wg sync.WaitGroup
 	wg.Add(N)
-	d := &Dialer{DualStack: true, Timeout: 100*time.Millisecond + closedPortDelay}
+	d := &Dialer{DualStack: true, Timeout: 5 * time.Second}
 	for i := 0; i < N; i++ {
 		go func() {
 			defer wg.Done()
@@ -161,6 +157,8 @@
 	// but other platforms should be instantaneous.
 	if runtime.GOOS == "windows" {
 		expected = 1500 * time.Millisecond
+	} else if runtime.GOOS == "darwin" {
+		expected = 150 * time.Millisecond
 	} else {
 		expected = 95 * time.Millisecond
 	}
@@ -637,7 +635,13 @@
 		}
 		c, err := d.Dial(tt.network, addr)
 		if err == nil && tt.error != nil || err != nil && tt.error == nil {
-			t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
+			// On Darwin this occasionally times out.
+			// We don't know why. Issue #22019.
+			if runtime.GOOS == "darwin" && tt.error == nil && os.IsTimeout(err) {
+				t.Logf("ignoring timeout error on Darwin; see https://golang.org/issue/22019")
+			} else {
+				t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
+			}
 		}
 		if err != nil {
 			if perr := parseDialError(err); perr != nil {
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index acbf6c3..9026fd8 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -479,7 +479,9 @@
 	var lastErr error
 	for _, fqdn := range conf.nameList(name) {
 		for _, qtype := range qtypes {
+			dnsWaitGroup.Add(1)
 			go func(qtype uint16) {
+				defer dnsWaitGroup.Done()
 				cname, rrs, err := r.tryOneName(ctx, conf, fqdn, qtype)
 				lane <- racer{cname, rrs, err}
 			}(qtype)
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 73b628c..295ed97 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -203,6 +203,7 @@
 
 // Issue 13705: don't try to resolve onion addresses, etc
 func TestLookupTorOnion(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	r := Resolver{PreferGo: true, Dial: fakeDNSServerSuccessful.DialContext}
 	addrs, err := r.LookupIPAddr(context.Background(), "foo.onion")
 	if err != nil {
@@ -300,6 +301,8 @@
 }
 
 func TestUpdateResolvConf(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	r := Resolver{PreferGo: true, Dial: fakeDNSServerSuccessful.DialContext}
 
 	conf, err := newResolvConfTest()
@@ -455,6 +458,8 @@
 }
 
 func TestGoLookupIPWithResolverConfig(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	fake := fakeDNSServer{func(n, s string, q *dnsMsg, _ time.Time) (*dnsMsg, error) {
 		switch s {
 		case "[2001:4860:4860::8888]:53", "8.8.8.8:53":
@@ -547,6 +552,8 @@
 
 // Test that goLookupIPOrder falls back to the host file when no DNS servers are available.
 func TestGoLookupIPOrderFallbackToFile(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	fake := fakeDNSServer{func(n, s string, q *dnsMsg, tm time.Time) (*dnsMsg, error) {
 		r := &dnsMsg{
 			dnsMsgHdr: dnsMsgHdr{
@@ -603,6 +610,8 @@
 // querying the original name instead of an error encountered
 // querying a generated name.
 func TestErrorForOriginalNameWhenSearching(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	const fqdn = "doesnotexist.domain"
 
 	conf, err := newResolvConfTest()
@@ -657,6 +666,8 @@
 
 // Issue 15434. If a name server gives a lame referral, continue to the next.
 func TestIgnoreLameReferrals(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	conf, err := newResolvConfTest()
 	if err != nil {
 		t.Fatal(err)
@@ -889,6 +900,8 @@
 
 // Issue 16865. If a name server times out, continue to the next.
 func TestRetryTimeout(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	conf, err := newResolvConfTest()
 	if err != nil {
 		t.Fatal(err)
@@ -945,6 +958,8 @@
 }
 
 func testRotate(t *testing.T, rotate bool, nameservers, wantServers []string) {
+	defer dnsWaitGroup.Wait()
+
 	conf, err := newResolvConfTest()
 	if err != nil {
 		t.Fatal(err)
@@ -1008,6 +1023,8 @@
 // Issue 17448. With StrictErrors enabled, temporary errors should make
 // LookupIP fail rather than return a partial result.
 func TestStrictErrorsLookupIP(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	conf, err := newResolvConfTest()
 	if err != nil {
 		t.Fatal(err)
@@ -1256,6 +1273,8 @@
 // Issue 17448. With StrictErrors enabled, temporary errors should make
 // LookupTXT stop walking the search list.
 func TestStrictErrorsLookupTXT(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
 	conf, err := newResolvConfTest()
 	if err != nil {
 		t.Fatal(err)
@@ -1312,3 +1331,25 @@
 		}
 	}
 }
+
+// Test for a race between uninstalling the test hooks and closing a
+// socket connection. This used to fail when testing with -race.
+func TestDNSGoroutineRace(t *testing.T) {
+	defer dnsWaitGroup.Wait()
+
+	fake := fakeDNSServer{func(n, s string, q *dnsMsg, t time.Time) (*dnsMsg, error) {
+		time.Sleep(10 * time.Microsecond)
+		return nil, poll.ErrTimeout
+	}}
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+
+	// The timeout here is less than the timeout used by the server,
+	// so the goroutine started to query the (fake) server will hang
+	// around after this test is done if we don't call dnsWaitGroup.Wait.
+	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Microsecond)
+	defer cancel()
+	_, err := r.LookupIPAddr(ctx, "where.are.they.now")
+	if err == nil {
+		t.Fatal("fake DNS lookup unexpectedly succeeded")
+	}
+}
diff --git a/src/net/fd_unix.go b/src/net/fd_unix.go
index 352010c..dd3c1ed 100644
--- a/src/net/fd_unix.go
+++ b/src/net/fd_unix.go
@@ -173,7 +173,7 @@
 				return rsa, nil
 			}
 		default:
-			return nil, os.NewSyscallError("getsockopt", err)
+			return nil, os.NewSyscallError("connect", err)
 		}
 		runtime.KeepAlive(fd)
 	}
@@ -313,7 +313,7 @@
 	// 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 {
+	if err = fd.pfd.SetBlocking(); err != nil {
 		return nil, os.NewSyscallError("setnonblock", err)
 	}
 
diff --git a/src/net/fd_windows.go b/src/net/fd_windows.go
index c2156b2..e5f8da1 100644
--- a/src/net/fd_windows.go
+++ b/src/net/fd_windows.go
@@ -52,7 +52,7 @@
 }
 
 func (fd *netFD) init() error {
-	errcall, err := fd.pfd.Init(fd.net)
+	errcall, err := fd.pfd.Init(fd.net, true)
 	if errcall != "" {
 		err = wrapSyscallError(errcall, err)
 	}
@@ -223,17 +223,21 @@
 	return netfd, nil
 }
 
+func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
+	n, oobn, flags, sa, err = fd.pfd.ReadMsg(p, oob)
+	runtime.KeepAlive(fd)
+	return n, oobn, flags, sa, wrapSyscallError("wsarecvmsg", err)
+}
+
+func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
+	n, oobn, err = fd.pfd.WriteMsg(p, oob, sa)
+	runtime.KeepAlive(fd)
+	return n, oobn, wrapSyscallError("wsasendmsg", err)
+}
+
 // Unimplemented functions.
 
 func (fd *netFD) dup() (*os.File, error) {
 	// TODO: Implement this
 	return nil, syscall.EWINDOWS
 }
-
-func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
-	return 0, 0, 0, nil, syscall.EWINDOWS
-}
-
-func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
-	return 0, 0, syscall.EWINDOWS
-}
diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go
index 4e64dce..ab8656c 100644
--- a/src/net/hook_windows.go
+++ b/src/net/hook_windows.go
@@ -5,6 +5,7 @@
 package net
 
 import (
+	"internal/syscall/windows"
 	"syscall"
 	"time"
 )
@@ -13,7 +14,8 @@
 	testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349
 
 	// Placeholders for socket system calls.
-	socketFunc  func(int, int, int) (syscall.Handle, error)  = syscall.Socket
-	connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect
-	listenFunc  func(syscall.Handle, int) error              = syscall.Listen
+	socketFunc    func(int, int, int) (syscall.Handle, error)                                                 = syscall.Socket
+	wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket
+	connectFunc   func(syscall.Handle, syscall.Sockaddr) error                                                = syscall.Connect
+	listenFunc    func(syscall.Handle, int) error                                                             = syscall.Listen
 )
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index 5d6c9cf..f850e2f 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -150,7 +150,7 @@
 
 func TestHostCacheModification(t *testing.T) {
 	// Ensure that programs can't modify the internals of the host cache.
-	// See https://github.com/golang/go/issues/14212.
+	// See https://golang.org/issues/14212.
 	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
 
 	testHookHostsPath = "testdata/ipv4-hosts"
diff --git a/src/net/http/client.go b/src/net/http/client.go
index 4c9084a..6f6024e 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -127,7 +127,10 @@
 	// authentication, or cookies.
 	//
 	// RoundTrip should not modify the request, except for
-	// consuming and closing the Request's Body.
+	// consuming and closing the Request's Body. RoundTrip may
+	// read fields of the request in a separate goroutine. Callers
+	// should not mutate the request until the Response's Body has
+	// been closed.
 	//
 	// RoundTrip must always close the body, including on errors,
 	// but depending on the implementation may do so in a separate
@@ -536,12 +539,22 @@
 				resp.closeBody()
 				return nil, uerr(fmt.Errorf("failed to parse Location header %q: %v", loc, err))
 			}
+			host := ""
+			if req.Host != "" && req.Host != req.URL.Host {
+				// If the caller specified a custom Host header and the
+				// redirect location is relative, preserve the Host header
+				// through the redirect. See issue #22233.
+				if u, _ := url.Parse(loc); u != nil && !u.IsAbs() {
+					host = req.Host
+				}
+			}
 			ireq := reqs[0]
 			req = &Request{
 				Method:   redirectMethod,
 				Response: resp,
 				URL:      u,
 				Header:   make(Header),
+				Host:     host,
 				Cancel:   ireq.Cancel,
 				ctx:      ireq.ctx,
 			}
@@ -750,7 +763,7 @@
 // with data's keys and values URL-encoded as the request body.
 //
 // The Content-Type header is set to application/x-www-form-urlencoded.
-// To set other headers, use NewRequest and DefaultClient.Do.
+// To set other headers, use NewRequest and Client.Do.
 //
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
@@ -843,16 +856,8 @@
 		// directly, we don't know their scope, so we assume
 		// it's for *.domain.com.
 
-		// TODO(bradfitz): once issue 16142 is fixed, make
-		// this code use those URL accessors, and consider
-		// "http://foo.com" and "http://foo.com:80" as
-		// equivalent?
-
-		// TODO(bradfitz): better hostname canonicalization,
-		// at least once we figure out IDNA/Punycode (issue
-		// 13835).
-		ihost := strings.ToLower(initial.Host)
-		dhost := strings.ToLower(dest.Host)
+		ihost := canonicalAddr(initial)
+		dhost := canonicalAddr(dest)
 		return isDomainOrSubdomain(dhost, ihost)
 	}
 	// All other headers are copied:
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index b9a1c31..eea3b16 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -1426,7 +1426,7 @@
 	c.Get("http://dummy.tld")
 }
 
-// Issue 4800: copy (some) headers when Client follows a redirect
+// Issue 4800: copy (some) headers when Client follows a redirect.
 func TestClientCopyHeadersOnRedirect(t *testing.T) {
 	const (
 		ua   = "some-agent/1.2"
@@ -1487,6 +1487,76 @@
 	}
 }
 
+// Issue 22233: copy host when Client follows a relative redirect.
+func TestClientCopyHostOnRedirect(t *testing.T) {
+	// Virtual hostname: should not receive any request.
+	virtual := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		t.Errorf("Virtual host received request %v", r.URL)
+		w.WriteHeader(403)
+		io.WriteString(w, "should not see this response")
+	}))
+	defer virtual.Close()
+	virtualHost := strings.TrimPrefix(virtual.URL, "http://")
+	t.Logf("Virtual host is %v", virtualHost)
+
+	// Actual hostname: should not receive any request.
+	const wantBody = "response body"
+	var tsURL string
+	var tsHost string
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		switch r.URL.Path {
+		case "/":
+			// Relative redirect.
+			if r.Host != virtualHost {
+				t.Errorf("Serving /: Request.Host = %#v; want %#v", r.Host, virtualHost)
+				w.WriteHeader(404)
+				return
+			}
+			w.Header().Set("Location", "/hop")
+			w.WriteHeader(302)
+		case "/hop":
+			// Absolute redirect.
+			if r.Host != virtualHost {
+				t.Errorf("Serving /hop: Request.Host = %#v; want %#v", r.Host, virtualHost)
+				w.WriteHeader(404)
+				return
+			}
+			w.Header().Set("Location", tsURL+"/final")
+			w.WriteHeader(302)
+		case "/final":
+			if r.Host != tsHost {
+				t.Errorf("Serving /final: Request.Host = %#v; want %#v", r.Host, tsHost)
+				w.WriteHeader(404)
+				return
+			}
+			w.WriteHeader(200)
+			io.WriteString(w, wantBody)
+		default:
+			t.Errorf("Serving unexpected path %q", r.URL.Path)
+			w.WriteHeader(404)
+		}
+	}))
+	defer ts.Close()
+	tsURL = ts.URL
+	tsHost = strings.TrimPrefix(ts.URL, "http://")
+	t.Logf("Server host is %v", tsHost)
+
+	c := ts.Client()
+	req, _ := NewRequest("GET", ts.URL, nil)
+	req.Host = virtualHost
+	resp, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		t.Fatal(resp.Status)
+	}
+	if got, err := ioutil.ReadAll(resp.Body); err != nil || string(got) != wantBody {
+		t.Errorf("body = %q; want %q", got, wantBody)
+	}
+}
+
 // Issue 17494: cookies should be altered when Client follows redirects.
 func TestClientAltersCookiesOnRedirect(t *testing.T) {
 	cookieMap := func(cs []*Cookie) map[string][]string {
@@ -1599,8 +1669,12 @@
 		{"www-authenticate", "http://foo.com/", "http://foo.com/", true},
 		{"www-authenticate", "http://foo.com/", "http://sub.foo.com/", true},
 		{"www-authenticate", "http://foo.com/", "http://notfoo.com/", false},
-		// TODO(bradfitz): make this test work, once issue 16142 is fixed:
-		// {"www-authenticate", "http://foo.com:80/", "http://foo.com/", true},
+		{"www-authenticate", "http://foo.com/", "https://foo.com/", false},
+		{"www-authenticate", "http://foo.com:80/", "http://foo.com/", true},
+		{"www-authenticate", "http://foo.com:80/", "http://sub.foo.com/", true},
+		{"www-authenticate", "http://foo.com:443/", "https://foo.com/", true},
+		{"www-authenticate", "http://foo.com:443/", "https://sub.foo.com/", true},
+		{"www-authenticate", "http://foo.com:1234/", "http://foo.com/", false},
 	}
 	for i, tt := range tests {
 		u0, err := url.Parse(tt.initialURL)
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index 8738c8f..b894be0 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -1141,27 +1141,6 @@
 	}
 }
 
-// Tests that we support bogus under-100 HTTP statuses, because we historically
-// have. This might change at some point, but not yet in Go 1.6.
-func TestBogusStatusWorks_h1(t *testing.T) { testBogusStatusWorks(t, h1Mode) }
-func TestBogusStatusWorks_h2(t *testing.T) { testBogusStatusWorks(t, h2Mode) }
-func testBogusStatusWorks(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	const code = 7
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.WriteHeader(code)
-	}))
-	defer cst.close()
-
-	res, err := cst.c.Get(cst.ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.StatusCode != code {
-		t.Errorf("StatusCode = %d; want %d", res.StatusCode, code)
-	}
-}
-
 func TestInterruptWithPanic_h1(t *testing.T)     { testInterruptWithPanic(t, h1Mode, "boom") }
 func TestInterruptWithPanic_h2(t *testing.T)     { testInterruptWithPanic(t, h2Mode, "boom") }
 func TestInterruptWithPanic_nil_h1(t *testing.T) { testInterruptWithPanic(t, h1Mode, nil) }
@@ -1408,3 +1387,96 @@
 		t.Errorf("closes = %d; want 1", closes)
 	}
 }
+
+func TestWriteHeader0_h1(t *testing.T) { testWriteHeader0(t, h1Mode) }
+func TestWriteHeader0_h2(t *testing.T) { testWriteHeader0(t, h2Mode) }
+func testWriteHeader0(t *testing.T, h2 bool) {
+	defer afterTest(t)
+	gotpanic := make(chan bool, 1)
+	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+		defer close(gotpanic)
+		defer func() {
+			if e := recover(); e != nil {
+				got := fmt.Sprintf("%T, %v", e, e)
+				want := "string, invalid WriteHeader code 0"
+				if got != want {
+					t.Errorf("unexpected panic value:\n got: %v\nwant: %v\n", got, want)
+				}
+				gotpanic <- true
+
+				// Set an explicit 503. This also tests that the WriteHeader call panics
+				// before it recorded that an explicit value was set and that bogus
+				// value wasn't stuck.
+				w.WriteHeader(503)
+			}
+		}()
+		w.WriteHeader(0)
+	}))
+	defer cst.close()
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.StatusCode != 503 {
+		t.Errorf("Response: %v %q; want 503", res.StatusCode, res.Status)
+	}
+	if !<-gotpanic {
+		t.Error("expected panic in handler")
+	}
+}
+
+// Issue 23010: don't be super strict checking WriteHeader's code if
+// it's not even valid to call WriteHeader then anyway.
+func TestWriteHeaderNoCodeCheck_h1(t *testing.T)       { testWriteHeaderAfterWrite(t, h1Mode, false) }
+func TestWriteHeaderNoCodeCheck_h1hijack(t *testing.T) { testWriteHeaderAfterWrite(t, h1Mode, true) }
+func TestWriteHeaderNoCodeCheck_h2(t *testing.T)       { testWriteHeaderAfterWrite(t, h2Mode, false) }
+func testWriteHeaderAfterWrite(t *testing.T, h2, hijack bool) {
+	setParallel(t)
+	defer afterTest(t)
+
+	var errorLog lockedBytesBuffer
+	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+		if hijack {
+			conn, _, _ := w.(Hijacker).Hijack()
+			defer conn.Close()
+			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nfoo"))
+			w.WriteHeader(0) // verify this doesn't panic if there's already output; Issue 23010
+			conn.Write([]byte("bar"))
+			return
+		}
+		io.WriteString(w, "foo")
+		w.(Flusher).Flush()
+		w.WriteHeader(0) // verify this doesn't panic if there's already output; Issue 23010
+		io.WriteString(w, "bar")
+	}), func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(&errorLog, "", 0)
+	})
+	defer cst.close()
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, want := string(body), "foobar"; got != want {
+		t.Errorf("got = %q; want %q", got, want)
+	}
+
+	// Also check the stderr output:
+	if h2 {
+		// TODO: also emit this log message for HTTP/2?
+		// We historically haven't, so don't check.
+		return
+	}
+	gotLog := strings.TrimSpace(errorLog.String())
+	wantLog := "http: multiple response.WriteHeader calls"
+	if hijack {
+		wantLog = "http: response.WriteHeader on hijacked connection"
+	}
+	if gotLog != wantLog {
+		t.Errorf("stderr output = %q; want %q", gotLog, wantLog)
+	}
+}
diff --git a/src/net/http/cookie.go b/src/net/http/cookie.go
index cf52248..38b1b36 100644
--- a/src/net/http/cookie.go
+++ b/src/net/http/cookie.go
@@ -208,7 +208,6 @@
 			continue
 		}
 		// Per-line attributes
-		parsedPairs := 0
 		for i := 0; i < len(parts); i++ {
 			parts[i] = strings.TrimSpace(parts[i])
 			if len(parts[i]) == 0 {
@@ -229,7 +228,6 @@
 				continue
 			}
 			cookies = append(cookies, &Cookie{Name: name, Value: val})
-			parsedPairs++
 		}
 	}
 	return cookies
diff --git a/src/net/http/example_test.go b/src/net/http/example_test.go
index 1774795..9de0893 100644
--- a/src/net/http/example_test.go
+++ b/src/net/http/example_test.go
@@ -5,11 +5,14 @@
 package http_test
 
 import (
+	"context"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"log"
 	"net/http"
+	"os"
+	"os/signal"
 )
 
 func ExampleHijacker() {
@@ -109,3 +112,28 @@
 		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
 	})
 }
+
+func ExampleServer_Shutdown() {
+	var srv http.Server
+
+	idleConnsClosed := make(chan struct{})
+	go func() {
+		sigint := make(chan os.Signal, 1)
+		signal.Notify(sigint, os.Interrupt)
+		<-sigint
+
+		// We received an interrupt signal, shut down.
+		if err := srv.Shutdown(context.Background()); err != nil {
+			// Error from closing listeners, or context timeout:
+			log.Printf("HTTP server Shutdown: %v", err)
+		}
+		close(idleConnsClosed)
+	}()
+
+	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
+		// Error starting or closing listener:
+		log.Printf("HTTP server ListenAndServe: %v", err)
+	}
+
+	<-idleConnsClosed
+}
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go
index 2ef145e..1825acd 100644
--- a/src/net/http/export_test.go
+++ b/src/net/http/export_test.go
@@ -63,9 +63,14 @@
 func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
 
 func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
+	ctx, cancel := context.WithCancel(context.Background())
+	go func() {
+		<-ch
+		cancel()
+	}()
 	return &timeoutHandler{
 		handler:     handler,
-		testTimeout: ch,
+		testContext: ctx,
 		// (no body)
 	}
 }
@@ -206,3 +211,9 @@
 func (r *Request) WithT(t *testing.T) *Request {
 	return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf))
 }
+
+func ExportSetH2GoawayTimeout(d time.Duration) (restore func()) {
+	old := http2goAwayTimeout
+	http2goAwayTimeout = d
+	return func() { http2goAwayTimeout = old }
+}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 5819334..ecad14a 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -98,12 +98,10 @@
 	Stat() (os.FileInfo, error)
 }
 
-func dirList(w ResponseWriter, f File) {
+func dirList(w ResponseWriter, r *Request, f File) {
 	dirs, err := f.Readdir(-1)
 	if err != nil {
-		// TODO: log err.Error() to the Server.ErrorLog, once it's possible
-		// for a handler to get at its Server via the ResponseWriter. See
-		// Issue 12438.
+		logf(r, "http: error reading directory: %v", err)
 		Error(w, "Error reading directory", StatusInternalServerError)
 		return
 	}
@@ -319,7 +317,7 @@
 		// Character values allowed in ETags.
 		case c == 0x21 || c >= 0x23 && c <= 0x7E || c >= 0x80:
 		case c == '"':
-			return string(s[:i+1]), s[i+1:]
+			return s[:i+1], s[i+1:]
 		default:
 			return "", ""
 		}
@@ -445,7 +443,7 @@
 }
 
 func checkIfRange(w ResponseWriter, r *Request, modtime time.Time) condResult {
-	if r.Method != "GET" {
+	if r.Method != "GET" && r.Method != "HEAD" {
 		return condNone
 	}
 	ir := r.Header.get("If-Range")
@@ -532,10 +530,8 @@
 	}
 
 	rangeHeader = r.Header.get("Range")
-	if rangeHeader != "" {
-		if checkIfRange(w, r, modtime) == condFalse {
-			rangeHeader = ""
-		}
+	if rangeHeader != "" && checkIfRange(w, r, modtime) == condFalse {
+		rangeHeader = ""
 	}
 	return false, rangeHeader
 }
@@ -615,7 +611,7 @@
 			return
 		}
 		w.Header().Set("Last-Modified", d.ModTime().UTC().Format(TimeFormat))
-		dirList(w, f)
+		dirList(w, r, f)
 		return
 	}
 
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index f1037c4..6ab122c 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -895,6 +895,17 @@
 			wantContentRange: "bytes 0-4/8",
 			wantLastMod:      "Wed, 25 Jun 2014 17:12:18 GMT",
 		},
+		"range_with_modtime_mismatch": {
+			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:19 GMT",
+			},
+			wantStatus:      StatusOK,
+			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),
@@ -937,8 +948,7 @@
 			reqHeader: map[string]string{
 				"If-Match": `"B"`,
 			},
-			wantStatus:      412,
-			wantContentType: "text/plain; charset=utf-8",
+			wantStatus: 412,
 		},
 		"ifmatch_fails_on_weak_etag": {
 			file:      "testdata/style.css",
@@ -946,8 +956,7 @@
 			reqHeader: map[string]string{
 				"If-Match": `W/"A"`,
 			},
-			wantStatus:      412,
-			wantContentType: "text/plain; charset=utf-8",
+			wantStatus: 412,
 		},
 		"if_unmodified_since_true": {
 			file:    "testdata/style.css",
@@ -965,9 +974,8 @@
 			reqHeader: map[string]string{
 				"If-Unmodified-Since": htmlModTime.Add(-2 * time.Second).UTC().Format(TimeFormat),
 			},
-			wantStatus:      412,
-			wantContentType: "text/plain; charset=utf-8",
-			wantLastMod:     htmlModTime.UTC().Format(TimeFormat),
+			wantStatus:  412,
+			wantLastMod: htmlModTime.UTC().Format(TimeFormat),
 		},
 	}
 	for testName, tt := range tests {
@@ -982,40 +990,46 @@
 		} else {
 			content = tt.content
 		}
+		for _, method := range []string{"GET", "HEAD"} {
+			//restore content in case it is consumed by previous method
+			if content, ok := content.(*strings.Reader); ok {
+				content.Seek(io.SeekStart, 0)
+			}
 
-		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)
-		}
+			servec <- serveParam{
+				name:        filepath.Base(tt.file),
+				content:     content,
+				modtime:     tt.modtime,
+				etag:        tt.serveETag,
+				contentType: tt.serveContentType,
+			}
+			req, err := NewRequest(method, ts.URL, nil)
+			if err != nil {
+				t.Fatal(err)
+			}
+			for k, v := range tt.reqHeader {
+				req.Header.Set(k, v)
+			}
 
-		c := ts.Client()
-		res, err := c.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("Content-Range"), tt.wantContentRange; g != e {
-			t.Errorf("test %q: content-range = %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)
+			c := ts.Client()
+			res, err := c.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 using %q: got status = %d; want %d", testName, method, res.StatusCode, tt.wantStatus)
+			}
+			if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e {
+				t.Errorf("test %q using %q: got content-type = %q, want %q", testName, method, g, e)
+			}
+			if g, e := res.Header.Get("Content-Range"), tt.wantContentRange; g != e {
+				t.Errorf("test %q using %q: got content-range = %q, want %q", testName, method, g, e)
+			}
+			if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e {
+				t.Errorf("test %q using %q: got last-modified = %q, want %q", testName, method, g, e)
+			}
 		}
 	}
 }
@@ -1126,7 +1140,7 @@
 	Post(fmt.Sprintf("http://%s/quit", ln.Addr()), "", nil)
 	child.Wait()
 
-	rx := regexp.MustCompile(`sendfile(64)?\(\d+,\s*\d+,\s*NULL,\s*\d+`)
+	rx := regexp.MustCompile(`sendfile(64)?\(`)
 	out := buf.String()
 	if !rx.MatchString(out) {
 		t.Errorf("no sendfile system call found in:\n%s", out)
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 83f1671..7a1564f 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -30,6 +30,7 @@
 	"io/ioutil"
 	"log"
 	"math"
+	mathrand "math/rand"
 	"net"
 	"net/http/httptrace"
 	"net/textproto"
@@ -988,7 +989,7 @@
 
 func (rt http2noDialH2RoundTripper) RoundTrip(req *Request) (*Response, error) {
 	res, err := rt.t.RoundTrip(req)
-	if err == http2ErrNoCachedConn {
+	if http2isNoCachedConnError(err) {
 		return nil, ErrSkipAltProtocol
 	}
 	return res, err
@@ -3909,12 +3910,15 @@
 	} else if s.TLSConfig.CipherSuites != nil {
 		// If they already provided a CipherSuite list, return
 		// an error if it has a bad order or is missing
-		// ECDHE_RSA_WITH_AES_128_GCM_SHA256.
-		const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+		// ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
 		haveRequired := false
 		sawBad := false
 		for i, cs := range s.TLSConfig.CipherSuites {
-			if cs == requiredCipher {
+			switch cs {
+			case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				// Alternative MTI cipher to not discourage ECDSA-only servers.
+				// See http://golang.org/cl/30721 for further information.
+				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
 				haveRequired = true
 			}
 			if http2isBadCipher(cs) {
@@ -3924,7 +3928,7 @@
 			}
 		}
 		if !haveRequired {
-			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
+			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.")
 		}
 	}
 
@@ -4341,7 +4345,7 @@
 	if err == nil {
 		return
 	}
-	if err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err) {
+	if err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err) || err == http2errPrefaceTimeout {
 		// Boring, expected errors.
 		sc.vlogf(format, args...)
 	} else {
@@ -4545,8 +4549,13 @@
 			}
 		}
 
-		if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
-			return
+		// Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
+		// with no error code (graceful shutdown), don't start the timer until
+		// all open streams have been completed.
+		sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
+		gracefulShutdownComplete := sc.goAwayCode == http2ErrCodeNo && sc.curOpenStreams() == 0
+		if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != http2ErrCodeNo || gracefulShutdownComplete) {
+			sc.shutDownIn(http2goAwayTimeout)
 		}
 	}
 }
@@ -4583,8 +4592,11 @@
 	}
 }
 
-// readPreface reads the ClientPreface greeting from the peer
-// or returns an error on timeout or an invalid greeting.
+var http2errPrefaceTimeout = errors.New("timeout waiting for client preface")
+
+// readPreface reads the ClientPreface greeting from the peer or
+// returns errPrefaceTimeout on timeout, or an error if the greeting
+// is invalid.
 func (sc *http2serverConn) readPreface() error {
 	errc := make(chan error, 1)
 	go func() {
@@ -4602,7 +4614,7 @@
 	defer timer.Stop()
 	select {
 	case <-timer.C:
-		return errors.New("timeout waiting for client preface")
+		return http2errPrefaceTimeout
 	case err := <-errc:
 		if err == nil {
 			if http2VerboseLogs {
@@ -4912,30 +4924,31 @@
 	sc.shutdownOnce.Do(func() { sc.sendServeMsg(http2gracefulShutdownMsg) })
 }
 
+// After sending GOAWAY, the connection will close after goAwayTimeout.
+// If we close the connection immediately after sending GOAWAY, there may
+// be unsent data in our kernel receive buffer, which will cause the kernel
+// to send a TCP RST on close() instead of a FIN. This RST will abort the
+// connection immediately, whether or not the client had received the GOAWAY.
+//
+// Ideally we should delay for at least 1 RTT + epsilon so the client has
+// a chance to read the GOAWAY and stop sending messages. Measuring RTT
+// is hard, so we approximate with 1 second. See golang.org/issue/18701.
+//
+// This is a var so it can be shorter in tests, where all requests uses the
+// loopback interface making the expected RTT very small.
+//
+// TODO: configurable?
+var http2goAwayTimeout = 1 * time.Second
+
 func (sc *http2serverConn) startGracefulShutdownInternal() {
-	sc.goAwayIn(http2ErrCodeNo, 0)
+	sc.goAway(http2ErrCodeNo)
 }
 
 func (sc *http2serverConn) goAway(code http2ErrCode) {
 	sc.serveG.check()
-	var forceCloseIn time.Duration
-	if code != http2ErrCodeNo {
-		forceCloseIn = 250 * time.Millisecond
-	} else {
-		// TODO: configurable
-		forceCloseIn = 1 * time.Second
-	}
-	sc.goAwayIn(code, forceCloseIn)
-}
-
-func (sc *http2serverConn) goAwayIn(code http2ErrCode, forceCloseIn time.Duration) {
-	sc.serveG.check()
 	if sc.inGoAway {
 		return
 	}
-	if forceCloseIn != 0 {
-		sc.shutDownIn(forceCloseIn)
-	}
 	sc.inGoAway = true
 	sc.needToSendGoAway = true
 	sc.goAwayCode = code
@@ -6004,7 +6017,7 @@
 			clen = strconv.Itoa(len(p))
 		}
 		_, hasContentType := rws.snapHeader["Content-Type"]
-		if !hasContentType && http2bodyAllowedForStatus(rws.status) {
+		if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
 			ctype = DetectContentType(p)
 		}
 		var date string
@@ -6172,6 +6185,24 @@
 	return rws.handlerHeader
 }
 
+// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
+func http2checkWriteHeaderCode(code int) {
+	// Issue 22880: require valid WriteHeader status codes.
+	// For now we only enforce that it's three digits.
+	// In the future we might block things over 599 (600 and above aren't defined
+	// at http://httpwg.org/specs/rfc7231.html#status.codes)
+	// and we might block under 200 (once we have more mature 1xx support).
+	// But for now any three digits.
+	//
+	// We used to send "HTTP/1.1 000 0" on the wire in responses but there's
+	// no equivalent bogus thing we can realistically send in HTTP/2,
+	// so we'll consistently panic instead and help people find their bugs
+	// early. (We can't return an error from WriteHeader even if we wanted to.)
+	if code < 100 || code > 999 {
+		panic(fmt.Sprintf("invalid WriteHeader code %v", code))
+	}
+}
+
 func (w *http2responseWriter) WriteHeader(code int) {
 	rws := w.rws
 	if rws == nil {
@@ -6182,6 +6213,7 @@
 
 func (rws *http2responseWriterState) writeHeader(code int) {
 	if !rws.wroteHeader {
+		http2checkWriteHeaderCode(code)
 		rws.wroteHeader = true
 		rws.status = code
 		if len(rws.handlerHeader) > 0 {
@@ -6605,7 +6637,7 @@
 
 	// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
 	// send in the initial settings frame. It is how many bytes
-	// of response headers are allow. Unlike the http2 spec, zero here
+	// of response headers are allowed. Unlike the http2 spec, zero here
 	// means to use a default limit (currently 10MB). If you actually
 	// want to advertise an ulimited value to the peer, Transport
 	// interprets the highest possible value here (0xffffffff or 1<<32-1)
@@ -6683,15 +6715,17 @@
 	goAwayDebug     string                        // goAway frame's debug data, retained as a string
 	streams         map[uint32]*http2clientStream // client-initiated
 	nextStreamID    uint32
+	pendingRequests int                       // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams
 	pings           map[[8]byte]chan struct{} // in flight ping data to notification channel
 	bw              *bufio.Writer
 	br              *bufio.Reader
 	fr              *http2Framer
 	lastActive      time.Time
 	// Settings from peer: (also guarded by mu)
-	maxFrameSize         uint32
-	maxConcurrentStreams uint32
-	initialWindowSize    uint32
+	maxFrameSize          uint32
+	maxConcurrentStreams  uint32
+	peerMaxHeaderListSize uint64
+	initialWindowSize     uint32
 
 	hbuf    bytes.Buffer // HPACK encoder writes into this
 	henc    *hpack.Encoder
@@ -6735,35 +6769,45 @@
 	resTrailer *Header // client's Response.Trailer
 }
 
-// awaitRequestCancel runs in its own goroutine and waits for the user
-// to cancel a RoundTrip request, its context to expire, or for the
-// request to be done (any way it might be removed from the cc.streams
-// map: peer reset, successful completion, TCP connection breakage,
-// etc)
-func (cs *http2clientStream) awaitRequestCancel(req *Request) {
+// awaitRequestCancel waits for the user to cancel a request or for the done
+// channel to be signaled. A non-nil error is returned only if the request was
+// canceled.
+func http2awaitRequestCancel(req *Request, done <-chan struct{}) error {
 	ctx := http2reqContext(req)
 	if req.Cancel == nil && ctx.Done() == nil {
-		return
+		return nil
 	}
 	select {
 	case <-req.Cancel:
-		cs.cancelStream()
-		cs.bufPipe.CloseWithError(http2errRequestCanceled)
+		return http2errRequestCanceled
 	case <-ctx.Done():
+		return ctx.Err()
+	case <-done:
+		return nil
+	}
+}
+
+// awaitRequestCancel waits for the user to cancel a request, its context to
+// expire, or for the request to be done (any way it might be removed from the
+// cc.streams map: peer reset, successful completion, TCP connection breakage,
+// etc). If the request is canceled, then cs will be canceled and closed.
+func (cs *http2clientStream) awaitRequestCancel(req *Request) {
+	if err := http2awaitRequestCancel(req, cs.done); err != nil {
 		cs.cancelStream()
-		cs.bufPipe.CloseWithError(ctx.Err())
-	case <-cs.done:
+		cs.bufPipe.CloseWithError(err)
 	}
 }
 
 func (cs *http2clientStream) cancelStream() {
-	cs.cc.mu.Lock()
+	cc := cs.cc
+	cc.mu.Lock()
 	didReset := cs.didReset
 	cs.didReset = true
-	cs.cc.mu.Unlock()
+	cc.mu.Unlock()
 
 	if !didReset {
-		cs.cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
+		cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
+		cc.forgetStreamID(cs.ID)
 	}
 }
 
@@ -6780,6 +6824,13 @@
 	}
 }
 
+func (cs *http2clientStream) getStartedWrite() bool {
+	cc := cs.cc
+	cc.mu.Lock()
+	defer cc.mu.Unlock()
+	return cs.startedWrite
+}
+
 func (cs *http2clientStream) abortRequestBodyWrite(err error) {
 	if err == nil {
 		panic("nil error")
@@ -6805,7 +6856,27 @@
 	return
 }
 
-var http2ErrNoCachedConn = errors.New("http2: no cached connection was available")
+// noCachedConnError is the concrete type of ErrNoCachedConn, needs to be detected
+// by net/http regardless of whether it's its bundled version (in h2_bundle.go with a rewritten type name)
+// or from a user's x/net/http2. As such, as it has a unique method name (IsHTTP2NoCachedConnError) that
+// net/http sniffs for via func isNoCachedConnError.
+type http2noCachedConnError struct{}
+
+func (http2noCachedConnError) IsHTTP2NoCachedConnError() {}
+
+func (http2noCachedConnError) Error() string { return "http2: no cached connection was available" }
+
+// isNoCachedConnError reports whether err is of type noCachedConnError
+// or its equivalent renamed type in net/http2's h2_bundle.go. Both types
+// may coexist in the same running program.
+func http2isNoCachedConnError(err error) bool {
+	_, ok := err.(interface {
+		IsHTTP2NoCachedConnError()
+	})
+	return ok
+}
+
+var http2ErrNoCachedConn error = http2noCachedConnError{}
 
 // RoundTripOpt are options for the Transport.RoundTripOpt method.
 type http2RoundTripOpt struct {
@@ -6848,17 +6919,28 @@
 	}
 
 	addr := http2authorityAddr(req.URL.Scheme, req.URL.Host)
-	for {
+	for retry := 0; ; retry++ {
 		cc, err := t.connPool().GetClientConn(req, addr)
 		if err != nil {
 			t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
 			return nil, err
 		}
 		http2traceGotConn(req, cc)
-		res, err := cc.RoundTrip(req)
-		if err != nil {
-			if req, err = http2shouldRetryRequest(req, err); err == nil {
-				continue
+		res, gotErrAfterReqBodyWrite, err := cc.roundTrip(req)
+		if err != nil && retry <= 6 {
+			if req, err = http2shouldRetryRequest(req, err, gotErrAfterReqBodyWrite); err == nil {
+				// After the first retry, do exponential backoff with 10% jitter.
+				if retry == 0 {
+					continue
+				}
+				backoff := float64(uint(1) << (uint(retry) - 1))
+				backoff += backoff * (0.1 * mathrand.Float64())
+				select {
+				case <-time.After(time.Second * time.Duration(backoff)):
+					continue
+				case <-http2reqContext(req).Done():
+					return nil, http2reqContext(req).Err()
+				}
 			}
 		}
 		if err != nil {
@@ -6879,43 +6961,50 @@
 }
 
 var (
-	http2errClientConnClosed   = errors.New("http2: client conn is closed")
-	http2errClientConnUnusable = errors.New("http2: client conn not usable")
-
-	http2errClientConnGotGoAway                 = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
-	http2errClientConnGotGoAwayAfterSomeReqBody = errors.New("http2: Transport received Server's graceful shutdown GOAWAY; some request body already written")
+	http2errClientConnClosed    = errors.New("http2: client conn is closed")
+	http2errClientConnUnusable  = errors.New("http2: client conn not usable")
+	http2errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
 )
 
 // shouldRetryRequest is called by RoundTrip when a request fails to get
 // response headers. It is always called with a non-nil error.
 // It returns either a request to retry (either the same request, or a
 // modified clone), or an error if the request can't be replayed.
-func http2shouldRetryRequest(req *Request, err error) (*Request, error) {
-	switch err {
-	default:
+func http2shouldRetryRequest(req *Request, err error, afterBodyWrite bool) (*Request, error) {
+	if !http2canRetryError(err) {
 		return nil, err
-	case http2errClientConnUnusable, http2errClientConnGotGoAway:
-		return req, nil
-	case http2errClientConnGotGoAwayAfterSomeReqBody:
-		// If the Body is nil (or http.NoBody), it's safe to reuse
-		// this request and its Body.
-		if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
-			return req, nil
-		}
-		// Otherwise we depend on the Request having its GetBody
-		// func defined.
-		getBody := http2reqGetBody(req) // Go 1.8: getBody = req.GetBody
-		if getBody == nil {
-			return nil, errors.New("http2: Transport: peer server initiated graceful shutdown after some of Request.Body was written; define Request.GetBody to avoid this error")
-		}
-		body, err := getBody()
-		if err != nil {
-			return nil, err
-		}
-		newReq := *req
-		newReq.Body = body
-		return &newReq, nil
 	}
+	if !afterBodyWrite {
+		return req, nil
+	}
+	// If the Body is nil (or http.NoBody), it's safe to reuse
+	// this request and its Body.
+	if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
+		return req, nil
+	}
+	// Otherwise we depend on the Request having its GetBody
+	// func defined.
+	getBody := http2reqGetBody(req) // Go 1.8: getBody = req.GetBody
+	if getBody == nil {
+		return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
+	}
+	body, err := getBody()
+	if err != nil {
+		return nil, err
+	}
+	newReq := *req
+	newReq.Body = body
+	return &newReq, nil
+}
+
+func http2canRetryError(err error) bool {
+	if err == http2errClientConnUnusable || err == http2errClientConnGotGoAway {
+		return true
+	}
+	if se, ok := err.(http2StreamError); ok {
+		return se.Code == http2ErrCodeRefusedStream
+	}
+	return false
 }
 
 func (t *http2Transport) dialClientConn(addr string, singleUse bool) (*http2ClientConn, error) {
@@ -6993,17 +7082,18 @@
 
 func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) {
 	cc := &http2ClientConn{
-		t:                    t,
-		tconn:                c,
-		readerDone:           make(chan struct{}),
-		nextStreamID:         1,
-		maxFrameSize:         16 << 10, // spec default
-		initialWindowSize:    65535,    // spec default
-		maxConcurrentStreams: 1000,     // "infinite", per spec. 1000 seems good enough.
-		streams:              make(map[uint32]*http2clientStream),
-		singleUse:            singleUse,
-		wantSettingsAck:      true,
-		pings:                make(map[[8]byte]chan struct{}),
+		t:                     t,
+		tconn:                 c,
+		readerDone:            make(chan struct{}),
+		nextStreamID:          1,
+		maxFrameSize:          16 << 10,           // spec default
+		initialWindowSize:     65535,              // spec default
+		maxConcurrentStreams:  1000,               // "infinite", per spec. 1000 seems good enough.
+		peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
+		streams:               make(map[uint32]*http2clientStream),
+		singleUse:             singleUse,
+		wantSettingsAck:       true,
+		pings:                 make(map[[8]byte]chan struct{}),
 	}
 	if d := t.idleConnTimeout(); d != 0 {
 		cc.idleTimeout = d
@@ -7079,6 +7169,8 @@
 	}
 }
 
+// CanTakeNewRequest reports whether the connection can take a new request,
+// meaning it has not been closed or received or sent a GOAWAY.
 func (cc *http2ClientConn) CanTakeNewRequest() bool {
 	cc.mu.Lock()
 	defer cc.mu.Unlock()
@@ -7090,8 +7182,7 @@
 		return false
 	}
 	return cc.goAway == nil && !cc.closed &&
-		int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
-		cc.nextStreamID < math.MaxInt32
+		int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32
 }
 
 // onIdleTimeout is called from a time.AfterFunc goroutine. It will
@@ -7223,8 +7314,13 @@
 }
 
 func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
+	resp, _, err := cc.roundTrip(req)
+	return resp, err
+}
+
+func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterReqBodyWrite bool, err error) {
 	if err := http2checkConnHeaders(req); err != nil {
-		return nil, err
+		return nil, false, err
 	}
 	if cc.idleTimer != nil {
 		cc.idleTimer.Stop()
@@ -7232,15 +7328,14 @@
 
 	trailers, err := http2commaSeparatedTrailers(req)
 	if err != nil {
-		return nil, err
+		return nil, false, err
 	}
 	hasTrailers := trailers != ""
 
 	cc.mu.Lock()
-	cc.lastActive = time.Now()
-	if cc.closed || !cc.canTakeNewRequestLocked() {
+	if err := cc.awaitOpenSlotForRequest(req); err != nil {
 		cc.mu.Unlock()
-		return nil, http2errClientConnUnusable
+		return nil, false, err
 	}
 
 	body := req.Body
@@ -7274,7 +7369,7 @@
 	hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
 	if err != nil {
 		cc.mu.Unlock()
-		return nil, err
+		return nil, false, err
 	}
 
 	cs := cc.newStream()
@@ -7286,7 +7381,7 @@
 
 	cc.wmu.Lock()
 	endStream := !hasBody && !hasTrailers
-	werr := cc.writeHeaders(cs.ID, endStream, hdrs)
+	werr := cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs)
 	cc.wmu.Unlock()
 	http2traceWroteHeaders(cs.trace)
 	cc.mu.Unlock()
@@ -7300,7 +7395,7 @@
 		// Don't bother sending a RST_STREAM (our write already failed;
 		// no need to keep writing)
 		http2traceWroteRequest(cs.trace, werr)
-		return nil, werr
+		return nil, false, werr
 	}
 
 	var respHeaderTimer <-chan time.Time
@@ -7319,7 +7414,7 @@
 	bodyWritten := false
 	ctx := http2reqContext(req)
 
-	handleReadLoopResponse := func(re http2resAndError) (*Response, error) {
+	handleReadLoopResponse := func(re http2resAndError) (*Response, bool, error) {
 		res := re.res
 		if re.err != nil || res.StatusCode > 299 {
 			// On error or status code 3xx, 4xx, 5xx, etc abort any
@@ -7335,19 +7430,12 @@
 			cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
 		}
 		if re.err != nil {
-			if re.err == http2errClientConnGotGoAway {
-				cc.mu.Lock()
-				if cs.startedWrite {
-					re.err = http2errClientConnGotGoAwayAfterSomeReqBody
-				}
-				cc.mu.Unlock()
-			}
 			cc.forgetStreamID(cs.ID)
-			return nil, re.err
+			return nil, cs.getStartedWrite(), re.err
 		}
 		res.Request = req
 		res.TLS = cc.tlsState
-		return res, nil
+		return res, false, nil
 	}
 
 	for {
@@ -7355,37 +7443,37 @@
 		case re := <-readLoopResCh:
 			return handleReadLoopResponse(re)
 		case <-respHeaderTimer:
-			cc.forgetStreamID(cs.ID)
 			if !hasBody || bodyWritten {
 				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
 			}
-			return nil, http2errTimeout
+			cc.forgetStreamID(cs.ID)
+			return nil, cs.getStartedWrite(), http2errTimeout
 		case <-ctx.Done():
-			cc.forgetStreamID(cs.ID)
 			if !hasBody || bodyWritten {
 				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
 			}
-			return nil, ctx.Err()
+			cc.forgetStreamID(cs.ID)
+			return nil, cs.getStartedWrite(), ctx.Err()
 		case <-req.Cancel:
-			cc.forgetStreamID(cs.ID)
 			if !hasBody || bodyWritten {
 				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
 			}
-			return nil, http2errRequestCanceled
+			cc.forgetStreamID(cs.ID)
+			return nil, cs.getStartedWrite(), http2errRequestCanceled
 		case <-cs.peerReset:
 			// processResetStream already removed the
 			// stream from the streams map; no need for
 			// forgetStreamID.
-			return nil, cs.resetErr
+			return nil, cs.getStartedWrite(), cs.resetErr
 		case err := <-bodyWriter.resc:
 			// Prefer the read loop's response, if available. Issue 16102.
 			select {
@@ -7394,7 +7482,7 @@
 			default:
 			}
 			if err != nil {
-				return nil, err
+				return nil, cs.getStartedWrite(), err
 			}
 			bodyWritten = true
 			if d := cc.responseHeaderTimeout(); d != 0 {
@@ -7406,14 +7494,52 @@
 	}
 }
 
+// awaitOpenSlotForRequest waits until len(streams) < maxConcurrentStreams.
+// Must hold cc.mu.
+func (cc *http2ClientConn) awaitOpenSlotForRequest(req *Request) error {
+	var waitingForConn chan struct{}
+	var waitingForConnErr error // guarded by cc.mu
+	for {
+		cc.lastActive = time.Now()
+		if cc.closed || !cc.canTakeNewRequestLocked() {
+			return http2errClientConnUnusable
+		}
+		if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
+			if waitingForConn != nil {
+				close(waitingForConn)
+			}
+			return nil
+		}
+		// Unfortunately, we cannot wait on a condition variable and channel at
+		// the same time, so instead, we spin up a goroutine to check if the
+		// request is canceled while we wait for a slot to open in the connection.
+		if waitingForConn == nil {
+			waitingForConn = make(chan struct{})
+			go func() {
+				if err := http2awaitRequestCancel(req, waitingForConn); err != nil {
+					cc.mu.Lock()
+					waitingForConnErr = err
+					cc.cond.Broadcast()
+					cc.mu.Unlock()
+				}
+			}()
+		}
+		cc.pendingRequests++
+		cc.cond.Wait()
+		cc.pendingRequests--
+		if waitingForConnErr != nil {
+			return waitingForConnErr
+		}
+	}
+}
+
 // requires cc.wmu be held
-func (cc *http2ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
+func (cc *http2ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error {
 	first := true // first frame written (HEADERS is first, then CONTINUATION)
-	frameSize := int(cc.maxFrameSize)
 	for len(hdrs) > 0 && cc.werr == nil {
 		chunk := hdrs
-		if len(chunk) > frameSize {
-			chunk = chunk[:frameSize]
+		if len(chunk) > maxFrameSize {
+			chunk = chunk[:maxFrameSize]
 		}
 		hdrs = hdrs[len(chunk):]
 		endHeaders := len(hdrs) == 0
@@ -7521,17 +7647,26 @@
 	var trls []byte
 	if hasTrailers {
 		cc.mu.Lock()
-		defer cc.mu.Unlock()
-		trls = cc.encodeTrailers(req)
+		trls, err = cc.encodeTrailers(req)
+		cc.mu.Unlock()
+		if err != nil {
+			cc.writeStreamReset(cs.ID, http2ErrCodeInternal, err)
+			cc.forgetStreamID(cs.ID)
+			return err
+		}
 	}
 
+	cc.mu.Lock()
+	maxFrameSize := int(cc.maxFrameSize)
+	cc.mu.Unlock()
+
 	cc.wmu.Lock()
 	defer cc.wmu.Unlock()
 
 	// Two ways to send END_STREAM: either with trailers, or
 	// with an empty DATA frame.
 	if len(trls) > 0 {
-		err = cc.writeHeaders(cs.ID, true, trls)
+		err = cc.writeHeaders(cs.ID, true, maxFrameSize, trls)
 	} else {
 		err = cc.fr.WriteData(cs.ID, true, nil)
 	}
@@ -7625,62 +7760,86 @@
 		}
 	}
 
-	// 8.1.2.3 Request Pseudo-Header Fields
-	// The :path pseudo-header field includes the path and query parts of the
-	// target URI (the path-absolute production and optionally a '?' character
-	// followed by the query production (see Sections 3.3 and 3.4 of
-	// [RFC3986]).
-	cc.writeHeader(":authority", host)
-	cc.writeHeader(":method", req.Method)
-	if req.Method != "CONNECT" {
-		cc.writeHeader(":path", path)
-		cc.writeHeader(":scheme", req.URL.Scheme)
-	}
-	if trailers != "" {
-		cc.writeHeader("trailer", trailers)
+	enumerateHeaders := func(f func(name, value string)) {
+		// 8.1.2.3 Request Pseudo-Header Fields
+		// The :path pseudo-header field includes the path and query parts of the
+		// target URI (the path-absolute production and optionally a '?' character
+		// followed by the query production (see Sections 3.3 and 3.4 of
+		// [RFC3986]).
+		f(":authority", host)
+		f(":method", req.Method)
+		if req.Method != "CONNECT" {
+			f(":path", path)
+			f(":scheme", req.URL.Scheme)
+		}
+		if trailers != "" {
+			f("trailer", trailers)
+		}
+
+		var didUA bool
+		for k, vv := range req.Header {
+			if strings.EqualFold(k, "host") || strings.EqualFold(k, "content-length") {
+				// Host is :authority, already sent.
+				// Content-Length is automatic, set below.
+				continue
+			} else if strings.EqualFold(k, "connection") || strings.EqualFold(k, "proxy-connection") ||
+				strings.EqualFold(k, "transfer-encoding") || strings.EqualFold(k, "upgrade") ||
+				strings.EqualFold(k, "keep-alive") {
+				// Per 8.1.2.2 Connection-Specific Header
+				// Fields, don't send connection-specific
+				// fields. We have already checked if any
+				// are error-worthy so just ignore the rest.
+				continue
+			} else if strings.EqualFold(k, "user-agent") {
+				// Match Go's http1 behavior: at most one
+				// User-Agent. If set to nil or empty string,
+				// then omit it. Otherwise if not mentioned,
+				// include the default (below).
+				didUA = true
+				if len(vv) < 1 {
+					continue
+				}
+				vv = vv[:1]
+				if vv[0] == "" {
+					continue
+				}
+
+			}
+
+			for _, v := range vv {
+				f(k, v)
+			}
+		}
+		if http2shouldSendReqContentLength(req.Method, contentLength) {
+			f("content-length", strconv.FormatInt(contentLength, 10))
+		}
+		if addGzipHeader {
+			f("accept-encoding", "gzip")
+		}
+		if !didUA {
+			f("user-agent", http2defaultUserAgent)
+		}
 	}
 
-	var didUA bool
-	for k, vv := range req.Header {
-		lowKey := strings.ToLower(k)
-		switch lowKey {
-		case "host", "content-length":
-			// Host is :authority, already sent.
-			// Content-Length is automatic, set below.
-			continue
-		case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive":
-			// Per 8.1.2.2 Connection-Specific Header
-			// Fields, don't send connection-specific
-			// fields. We have already checked if any
-			// are error-worthy so just ignore the rest.
-			continue
-		case "user-agent":
-			// Match Go's http1 behavior: at most one
-			// User-Agent. If set to nil or empty string,
-			// then omit it. Otherwise if not mentioned,
-			// include the default (below).
-			didUA = true
-			if len(vv) < 1 {
-				continue
-			}
-			vv = vv[:1]
-			if vv[0] == "" {
-				continue
-			}
-		}
-		for _, v := range vv {
-			cc.writeHeader(lowKey, v)
-		}
+	// Do a first pass over the headers counting bytes to ensure
+	// we don't exceed cc.peerMaxHeaderListSize. This is done as a
+	// separate pass before encoding the headers to prevent
+	// modifying the hpack state.
+	hlSize := uint64(0)
+	enumerateHeaders(func(name, value string) {
+		hf := hpack.HeaderField{Name: name, Value: value}
+		hlSize += uint64(hf.Size())
+	})
+
+	if hlSize > cc.peerMaxHeaderListSize {
+		return nil, http2errRequestHeaderListSize
 	}
-	if http2shouldSendReqContentLength(req.Method, contentLength) {
-		cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10))
-	}
-	if addGzipHeader {
-		cc.writeHeader("accept-encoding", "gzip")
-	}
-	if !didUA {
-		cc.writeHeader("user-agent", http2defaultUserAgent)
-	}
+
+	// Header list size is ok. Write the headers.
+	enumerateHeaders(func(name, value string) {
+		cc.writeHeader(strings.ToLower(name), value)
+	})
+
 	return cc.hbuf.Bytes(), nil
 }
 
@@ -7707,17 +7866,29 @@
 }
 
 // requires cc.mu be held.
-func (cc *http2ClientConn) encodeTrailers(req *Request) []byte {
+func (cc *http2ClientConn) encodeTrailers(req *Request) ([]byte, error) {
 	cc.hbuf.Reset()
+
+	hlSize := uint64(0)
 	for k, vv := range req.Trailer {
-		// Transfer-Encoding, etc.. have already been filter at the
+		for _, v := range vv {
+			hf := hpack.HeaderField{Name: k, Value: v}
+			hlSize += uint64(hf.Size())
+		}
+	}
+	if hlSize > cc.peerMaxHeaderListSize {
+		return nil, http2errRequestHeaderListSize
+	}
+
+	for k, vv := range req.Trailer {
+		// Transfer-Encoding, etc.. have already been filtered at the
 		// start of RoundTrip
 		lowKey := strings.ToLower(k)
 		for _, v := range vv {
 			cc.writeHeader(lowKey, v)
 		}
 	}
-	return cc.hbuf.Bytes()
+	return cc.hbuf.Bytes(), nil
 }
 
 func (cc *http2ClientConn) writeHeader(name, value string) {
@@ -7765,7 +7936,9 @@
 			cc.idleTimer.Reset(cc.idleTimeout)
 		}
 		close(cs.done)
-		cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
+		// Wake up checkResetOrDone via clientStream.awaitFlowControl and
+		// wake up RoundTrip if there is a pending request.
+		cc.cond.Broadcast()
 	}
 	return cs
 }
@@ -7773,17 +7946,12 @@
 // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
 type http2clientConnReadLoop struct {
 	cc            *http2ClientConn
-	activeRes     map[uint32]*http2clientStream // keyed by streamID
 	closeWhenIdle bool
 }
 
 // readLoop runs in its own goroutine and reads and dispatches frames.
 func (cc *http2ClientConn) readLoop() {
-	rl := &http2clientConnReadLoop{
-		cc:        cc,
-		activeRes: make(map[uint32]*http2clientStream),
-	}
-
+	rl := &http2clientConnReadLoop{cc: cc}
 	defer rl.cleanup()
 	cc.readerErr = rl.run()
 	if ce, ok := cc.readerErr.(http2ConnectionError); ok {
@@ -7838,10 +8006,8 @@
 	} else if err == io.EOF {
 		err = io.ErrUnexpectedEOF
 	}
-	for _, cs := range rl.activeRes {
-		cs.bufPipe.CloseWithError(err)
-	}
 	for _, cs := range cc.streams {
+		cs.bufPipe.CloseWithError(err) // no-op if already closed
 		select {
 		case cs.resc <- http2resAndError{err: err}:
 		default:
@@ -7864,8 +8030,9 @@
 			cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
 		}
 		if se, ok := err.(http2StreamError); ok {
-			if cs := cc.streamByID(se.StreamID, true /*ended; remove it*/); cs != nil {
+			if cs := cc.streamByID(se.StreamID, false); cs != nil {
 				cs.cc.writeStreamReset(cs.ID, se.Code, err)
+				cs.cc.forgetStreamID(cs.ID)
 				if se.Cause == nil {
 					se.Cause = cc.fr.errDetail
 				}
@@ -7918,7 +8085,7 @@
 			}
 			return err
 		}
-		if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
+		if rl.closeWhenIdle && gotReply && maybeIdle {
 			cc.closeIfIdle()
 		}
 	}
@@ -7926,13 +8093,31 @@
 
 func (rl *http2clientConnReadLoop) processHeaders(f *http2MetaHeadersFrame) error {
 	cc := rl.cc
-	cs := cc.streamByID(f.StreamID, f.StreamEnded())
+	cs := cc.streamByID(f.StreamID, false)
 	if cs == nil {
 		// We'd get here if we canceled a request while the
 		// server had its response still in flight. So if this
 		// was just something we canceled, ignore it.
 		return nil
 	}
+	if f.StreamEnded() {
+		// Issue 20521: If the stream has ended, streamByID() causes
+		// clientStream.done to be closed, which causes the request's bodyWriter
+		// to be closed with an errStreamClosed, which may be received by
+		// clientConn.RoundTrip before the result of processing these headers.
+		// Deferring stream closure allows the header processing to occur first.
+		// clientConn.RoundTrip may still receive the bodyWriter error first, but
+		// the fix for issue 16102 prioritises any response.
+		//
+		// Issue 22413: If there is no request body, we should close the
+		// stream before writing to cs.resc so that the stream is closed
+		// immediately once RoundTrip returns.
+		if cs.req.Body != nil {
+			defer cc.forgetStreamID(f.StreamID)
+		} else {
+			cc.forgetStreamID(f.StreamID)
+		}
+	}
 	if !cs.firstByte {
 		if cs.trace != nil {
 			// TODO(bradfitz): move first response byte earlier,
@@ -7956,6 +8141,7 @@
 		}
 		// Any other error type is a stream error.
 		cs.cc.writeStreamReset(f.StreamID, http2ErrCodeProtocol, err)
+		cc.forgetStreamID(cs.ID)
 		cs.resc <- http2resAndError{err: err}
 		return nil // return nil from process* funcs to keep conn alive
 	}
@@ -7963,9 +8149,6 @@
 		// (nil, nil) special case. See handleResponse docs.
 		return nil
 	}
-	if res.Body != http2noBody {
-		rl.activeRes[cs.ID] = cs
-	}
 	cs.resTrailer = &res.Trailer
 	cs.resc <- http2resAndError{res: res}
 	return nil
@@ -7985,11 +8168,11 @@
 
 	status := f.PseudoValue("status")
 	if status == "" {
-		return nil, errors.New("missing status pseudo header")
+		return nil, errors.New("malformed response from server: missing status pseudo header")
 	}
 	statusCode, err := strconv.Atoi(status)
 	if err != nil {
-		return nil, errors.New("malformed non-numeric status pseudo header")
+		return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
 	}
 
 	if statusCode == 100 {
@@ -8187,6 +8370,7 @@
 	}
 
 	cs.bufPipe.BreakWithError(http2errClosedResponseBody)
+	cc.forgetStreamID(cs.ID)
 	return nil
 }
 
@@ -8221,7 +8405,23 @@
 		}
 		return nil
 	}
+	if !cs.firstByte {
+		cc.logf("protocol error: received DATA before a HEADERS frame")
+		rl.endStreamError(cs, http2StreamError{
+			StreamID: f.StreamID,
+			Code:     http2ErrCodeProtocol,
+		})
+		return nil
+	}
 	if f.Length > 0 {
+		if cs.req.Method == "HEAD" && len(data) > 0 {
+			cc.logf("protocol error: received DATA on a HEAD request")
+			rl.endStreamError(cs, http2StreamError{
+				StreamID: f.StreamID,
+				Code:     http2ErrCodeProtocol,
+			})
+			return nil
+		}
 		// Check connection-level flow control.
 		cc.mu.Lock()
 		if cs.inflow.available() >= int32(f.Length) {
@@ -8283,11 +8483,10 @@
 		err = io.EOF
 		code = cs.copyTrailers
 	}
-	cs.bufPipe.closeWithErrorAndCode(err, code)
-	delete(rl.activeRes, cs.ID)
 	if http2isConnectionCloseRequest(cs.req) {
 		rl.closeWhenIdle = true
 	}
+	cs.bufPipe.closeWithErrorAndCode(err, code)
 
 	select {
 	case cs.resc <- http2resAndError{err: err}:
@@ -8335,6 +8534,8 @@
 			cc.maxFrameSize = s.Val
 		case http2SettingMaxConcurrentStreams:
 			cc.maxConcurrentStreams = s.Val
+		case http2SettingMaxHeaderListSize:
+			cc.peerMaxHeaderListSize = uint64(s.Val)
 		case http2SettingInitialWindowSize:
 			// Values above the maximum flow-control
 			// window size of 2^31-1 MUST be treated as a
@@ -8412,7 +8613,6 @@
 		cs.bufPipe.CloseWithError(err)
 		cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
 	}
-	delete(rl.activeRes, cs.ID)
 	return nil
 }
 
@@ -8501,6 +8701,7 @@
 
 var (
 	http2errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
+	http2errRequestHeaderListSize  = errors.New("http2: request header list larger than peer's advertised limit")
 	http2errPseudoTrailers         = errors.New("http2: invalid pseudo header in trailers")
 )
 
@@ -8726,11 +8927,7 @@
 
 func (p *http2writeGoAway) writeFrame(ctx http2writeContext) error {
 	err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
-	if p.code != 0 {
-		ctx.Flush() // ignore error: we're hanging up on them anyway
-		time.Sleep(50 * time.Millisecond)
-		ctx.CloseConn()
-	}
+	ctx.Flush() // ignore error: we're hanging up on them anyway
 	return err
 }
 
diff --git a/src/net/http/header.go b/src/net/http/header.go
index 8321692..622ad28 100644
--- a/src/net/http/header.go
+++ b/src/net/http/header.go
@@ -156,6 +156,7 @@
 			v = textproto.TrimString(v)
 			for _, s := range []string{kv.key, ": ", v, "\r\n"} {
 				if _, err := ws.WriteString(s); err != nil {
+					headerSorterPool.Put(sorter)
 					return err
 				}
 			}
diff --git a/src/net/http/httputil/dump_test.go b/src/net/http/httputil/dump_test.go
index f881020..5703a7f 100644
--- a/src/net/http/httputil/dump_test.go
+++ b/src/net/http/httputil/dump_test.go
@@ -27,7 +27,6 @@
 }
 
 var dumpTests = []dumpTest{
-
 	// HTTP/1.1 => chunked coding; body; empty trailer
 	{
 		Req: http.Request{
@@ -214,7 +213,6 @@
 				t.Fatalf("Test %d: unsupported Body of %T", i, tt.Body)
 			}
 		}
-		setBody()
 		if tt.Req.Header == nil {
 			tt.Req.Header = make(http.Header)
 		}
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 0d514f5..b96bb21 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -169,15 +169,7 @@
 	p.Director(outreq)
 	outreq.Close = false
 
-	// Remove hop-by-hop headers listed in the "Connection" header.
-	// See RFC 2616, section 14.10.
-	if c := outreq.Header.Get("Connection"); c != "" {
-		for _, f := range strings.Split(c, ",") {
-			if f = strings.TrimSpace(f); f != "" {
-				outreq.Header.Del(f)
-			}
-		}
-	}
+	removeConnectionHeaders(outreq.Header)
 
 	// Remove hop-by-hop headers to the backend. Especially
 	// important is "Connection" because we want a persistent
@@ -205,15 +197,7 @@
 		return
 	}
 
-	// Remove hop-by-hop headers listed in the
-	// "Connection" header of the response.
-	if c := res.Header.Get("Connection"); c != "" {
-		for _, f := range strings.Split(c, ",") {
-			if f = strings.TrimSpace(f); f != "" {
-				res.Header.Del(f)
-			}
-		}
-	}
+	removeConnectionHeaders(res.Header)
 
 	for _, h := range hopHeaders {
 		res.Header.Del(h)
@@ -223,6 +207,7 @@
 		if err := p.ModifyResponse(res); err != nil {
 			p.logf("http: proxy error: %v", err)
 			rw.WriteHeader(http.StatusBadGateway)
+			res.Body.Close()
 			return
 		}
 	}
@@ -265,6 +250,18 @@
 	}
 }
 
+// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
+// See RFC 2616, section 14.10.
+func removeConnectionHeaders(h http.Header) {
+	if c := h.Get("Connection"); c != "" {
+		for _, f := range strings.Split(c, ",") {
+			if f = strings.TrimSpace(f); f != "" {
+				h.Del(f)
+			}
+		}
+	}
+}
+
 func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) {
 	if p.FlushInterval != 0 {
 		if wf, ok := dst.(writeFlusher); ok {
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 37a9992..2232042 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -769,3 +769,47 @@
 func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
 	return fn(req)
 }
+
+func TestModifyResponseClosesBody(t *testing.T) {
+	req, _ := http.NewRequest("GET", "http://foo.tld/", nil)
+	req.RemoteAddr = "1.2.3.4:56789"
+	closeCheck := new(checkCloser)
+	logBuf := new(bytes.Buffer)
+	outErr := errors.New("ModifyResponse error")
+	rp := &ReverseProxy{
+		Director: func(req *http.Request) {},
+		Transport: &staticTransport{&http.Response{
+			StatusCode: 200,
+			Body:       closeCheck,
+		}},
+		ErrorLog: log.New(logBuf, "", 0),
+		ModifyResponse: func(*http.Response) error {
+			return outErr
+		},
+	}
+	rec := httptest.NewRecorder()
+	rp.ServeHTTP(rec, req)
+	res := rec.Result()
+	if g, e := res.StatusCode, http.StatusBadGateway; g != e {
+		t.Errorf("got res.StatusCode %d; expected %d", g, e)
+	}
+	if !closeCheck.closed {
+		t.Errorf("body should have been closed")
+	}
+	if g, e := logBuf.String(), outErr.Error(); !strings.Contains(g, e) {
+		t.Errorf("ErrorLog %q does not contain %q", g, e)
+	}
+}
+
+type checkCloser struct {
+	closed bool
+}
+
+func (cc *checkCloser) Close() error {
+	cc.closed = true
+	return nil
+}
+
+func (cc *checkCloser) Read(b []byte) (int, error) {
+	return len(b), nil
+}
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 12c7599..21992d6 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -69,11 +69,11 @@
 )
 
 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))
-	http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
+	http.HandleFunc("/debug/pprof/", Index)
+	http.HandleFunc("/debug/pprof/cmdline", Cmdline)
+	http.HandleFunc("/debug/pprof/profile", Profile)
+	http.HandleFunc("/debug/pprof/symbol", Symbol)
+	http.HandleFunc("/debug/pprof/trace", Trace)
 }
 
 // Cmdline responds with the running program's
diff --git a/src/net/http/readrequest_test.go b/src/net/http/readrequest_test.go
index 28a148b..22a9c2e 100644
--- a/src/net/http/readrequest_test.go
+++ b/src/net/http/readrequest_test.go
@@ -454,6 +454,14 @@
 	{"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
 Host: foo
 Content-Length: 5`)},
+
+	// golang.org/issue/22464
+	{"leading_space_in_header", reqBytes(`HEAD / HTTP/1.1
+ Host: foo
+Content-Length: 5`)},
+	{"leading_tab_in_header", reqBytes(`HEAD / HTTP/1.1
+\tHost: foo
+Content-Length: 5`)},
 }
 
 func TestReadRequest_Bad(t *testing.T) {
diff --git a/src/net/http/request.go b/src/net/http/request.go
index 13f367c..c9642e5 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -98,6 +98,10 @@
 type Request struct {
 	// Method specifies the HTTP method (GET, POST, PUT, etc.).
 	// For client requests an empty string means GET.
+	//
+	// Go's HTTP client does not support sending a request with
+	// the CONNECT method. See the documentation on Transport for
+	// details.
 	Method string
 
 	// URL specifies either the URI being requested (for server
@@ -490,8 +494,8 @@
 
 // extraHeaders may be nil
 // waitForContinue may be nil
-func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {
-	trace := httptrace.ContextClientTrace(req.Context())
+func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {
+	trace := httptrace.ContextClientTrace(r.Context())
 	if trace != nil && trace.WroteRequest != nil {
 		defer func() {
 			trace.WroteRequest(httptrace.WroteRequestInfo{
@@ -504,12 +508,12 @@
 	// is not given, use the host from the request URL.
 	//
 	// Clean the host, in case it arrives with unexpected stuff in it.
-	host := cleanHost(req.Host)
+	host := cleanHost(r.Host)
 	if host == "" {
-		if req.URL == nil {
+		if r.URL == nil {
 			return errMissingHost
 		}
-		host = cleanHost(req.URL.Host)
+		host = cleanHost(r.URL.Host)
 	}
 
 	// According to RFC 6874, an HTTP client, proxy, or other
@@ -517,10 +521,10 @@
 	// to an outgoing URI.
 	host = removeZone(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 == "" {
+	ruri := r.URL.RequestURI()
+	if usingProxy && r.URL.Scheme != "" && r.URL.Opaque == "" {
+		ruri = r.URL.Scheme + "://" + host + ruri
+	} else if r.Method == "CONNECT" && r.URL.Path == "" {
 		// CONNECT requests normally give just the host and port, not a full URL.
 		ruri = host
 	}
@@ -536,7 +540,7 @@
 		w = bw
 	}
 
-	_, err = fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
+	_, err = fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(r.Method, "GET"), ruri)
 	if err != nil {
 		return err
 	}
@@ -550,8 +554,8 @@
 	// Use the defaultUserAgent unless the Header contains one, which
 	// may be blank to not send the header.
 	userAgent := defaultUserAgent
-	if _, ok := req.Header["User-Agent"]; ok {
-		userAgent = req.Header.Get("User-Agent")
+	if _, ok := r.Header["User-Agent"]; ok {
+		userAgent = r.Header.Get("User-Agent")
 	}
 	if userAgent != "" {
 		_, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
@@ -561,7 +565,7 @@
 	}
 
 	// Process Body,ContentLength,Close,Trailer
-	tw, err := newTransferWriter(req)
+	tw, err := newTransferWriter(r)
 	if err != nil {
 		return err
 	}
@@ -570,7 +574,7 @@
 		return err
 	}
 
-	err = req.Header.WriteSubset(w, reqWriteExcludeHeader)
+	err = r.Header.WriteSubset(w, reqWriteExcludeHeader)
 	if err != nil {
 		return err
 	}
@@ -603,7 +607,7 @@
 			trace.Wait100Continue()
 		}
 		if !waitForContinue() {
-			req.closeBody()
+			r.closeBody()
 			return nil
 		}
 	}
diff --git a/src/net/http/response.go b/src/net/http/response.go
index 0357b60..a91efcf 100644
--- a/src/net/http/response.go
+++ b/src/net/http/response.go
@@ -27,6 +27,9 @@
 
 // Response represents the response from an HTTP request.
 //
+// The Client and Transport return Responses from servers once
+// the response headers have been received. The response body
+// is streamed on demand as the Body field is read.
 type Response struct {
 	Status     string // e.g. "200 OK"
 	StatusCode int    // e.g. 200
@@ -47,13 +50,16 @@
 
 	// Body represents the response body.
 	//
+	// The response body is streamed on demand as the Body field
+	// is read. If the network connection fails or the server
+	// terminates the response, Body.Read calls return an error.
+	//
 	// The http Client and Transport guarantee that Body is always
 	// non-nil, even on responses without a body or responses with
 	// a zero-length body. It is the caller's responsibility to
-	// close Body. The default HTTP client's Transport does not
-	// attempt to reuse HTTP/1.0 or HTTP/1.1 TCP connections
-	// ("keep-alive") unless the Body is read to completion and is
-	// closed.
+	// close Body. The default HTTP client's Transport may not
+	// reuse HTTP/1.x "keep-alive" TCP connections if the Body is
+	// not read to completion and closed.
 	//
 	// The Body is automatically dechunked if the server replied
 	// with a "chunked" Transfer-Encoding.
diff --git a/src/net/http/response_test.go b/src/net/http/response_test.go
index f1a50bd..1ea1961 100644
--- a/src/net/http/response_test.go
+++ b/src/net/http/response_test.go
@@ -816,7 +816,6 @@
 	type testCase struct {
 		name    string // optional, defaults to in
 		in      string
-		header  Header
 		wantErr interface{} // nil, err value, or string substring
 	}
 
@@ -842,22 +841,21 @@
 		}
 	}
 
-	contentLength := func(status, body string, wantErr interface{}, header Header) testCase {
+	contentLength := func(status, body string, wantErr interface{}) testCase {
 		return testCase{
 			name:    fmt.Sprintf("status %q %q", status, body),
 			in:      fmt.Sprintf("HTTP/1.1 %s\r\n%s", status, body),
 			wantErr: wantErr,
-			header:  header,
 		}
 	}
 
 	errMultiCL := "message cannot contain multiple Content-Length headers"
 
 	tests := []testCase{
-		{"", "", nil, io.ErrUnexpectedEOF},
-		{"", "HTTP/1.1 301 Moved Permanently\r\nFoo: bar", nil, io.ErrUnexpectedEOF},
-		{"", "HTTP/1.1", nil, "malformed HTTP response"},
-		{"", "HTTP/2.0", nil, "malformed HTTP response"},
+		{"", "", io.ErrUnexpectedEOF},
+		{"", "HTTP/1.1 301 Moved Permanently\r\nFoo: bar", io.ErrUnexpectedEOF},
+		{"", "HTTP/1.1", "malformed HTTP response"},
+		{"", "HTTP/2.0", "malformed HTTP response"},
 		status("20X Unknown", true),
 		status("abcd Unknown", true),
 		status("二百/两百 OK", true),
@@ -883,18 +881,22 @@
 		version("HTTP/1", true),
 		version("http/1.1", true),
 
-		contentLength("200 OK", "Content-Length: 10\r\nContent-Length: 7\r\n\r\nGopher hey\r\n", errMultiCL, nil),
-		contentLength("200 OK", "Content-Length: 7\r\nContent-Length: 7\r\n\r\nGophers\r\n", nil, Header{"Content-Length": {"7"}}),
-		contentLength("201 OK", "Content-Length: 0\r\nContent-Length: 7\r\n\r\nGophers\r\n", errMultiCL, nil),
-		contentLength("300 OK", "Content-Length: 0\r\nContent-Length: 0 \r\n\r\nGophers\r\n", nil, Header{"Content-Length": {"0"}}),
-		contentLength("200 OK", "Content-Length:\r\nContent-Length:\r\n\r\nGophers\r\n", nil, nil),
-		contentLength("206 OK", "Content-Length:\r\nContent-Length: 0 \r\nConnection: close\r\n\r\nGophers\r\n", errMultiCL, nil),
+		contentLength("200 OK", "Content-Length: 10\r\nContent-Length: 7\r\n\r\nGopher hey\r\n", errMultiCL),
+		contentLength("200 OK", "Content-Length: 7\r\nContent-Length: 7\r\n\r\nGophers\r\n", nil),
+		contentLength("201 OK", "Content-Length: 0\r\nContent-Length: 7\r\n\r\nGophers\r\n", errMultiCL),
+		contentLength("300 OK", "Content-Length: 0\r\nContent-Length: 0 \r\n\r\nGophers\r\n", nil),
+		contentLength("200 OK", "Content-Length:\r\nContent-Length:\r\n\r\nGophers\r\n", nil),
+		contentLength("206 OK", "Content-Length:\r\nContent-Length: 0 \r\nConnection: close\r\n\r\nGophers\r\n", errMultiCL),
 
 		// multiple content-length headers for 204 and 304 should still be checked
-		contentLength("204 OK", "Content-Length: 7\r\nContent-Length: 8\r\n\r\n", errMultiCL, nil),
-		contentLength("204 OK", "Content-Length: 3\r\nContent-Length: 3\r\n\r\n", nil, nil),
-		contentLength("304 OK", "Content-Length: 880\r\nContent-Length: 1\r\n\r\n", errMultiCL, nil),
-		contentLength("304 OK", "Content-Length: 961\r\nContent-Length: 961\r\n\r\n", nil, nil),
+		contentLength("204 OK", "Content-Length: 7\r\nContent-Length: 8\r\n\r\n", errMultiCL),
+		contentLength("204 OK", "Content-Length: 3\r\nContent-Length: 3\r\n\r\n", nil),
+		contentLength("304 OK", "Content-Length: 880\r\nContent-Length: 1\r\n\r\n", errMultiCL),
+		contentLength("304 OK", "Content-Length: 961\r\nContent-Length: 961\r\n\r\n", nil),
+
+		// golang.org/issue/22464
+		{"leading space in header", "HTTP/1.1 200 OK\r\n Content-type: text/html\r\nFoo: bar\r\n\r\n", "malformed MIME"},
+		{"leading tab in header", "HTTP/1.1 200 OK\r\n\tContent-type: text/html\r\nFoo: bar\r\n\r\n", "malformed MIME"},
 	}
 
 	for i, tt := range tests {
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 7137599..9cbfe87 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -461,6 +461,126 @@
 	}
 }
 
+// Test that the special cased "/route" redirect
+// implicitly created by a registered "/route/"
+// properly sets the query string in the redirect URL.
+// See Issue 17841.
+func TestServeWithSlashRedirectKeepsQueryString(t *testing.T) {
+	setParallel(t)
+	defer afterTest(t)
+
+	writeBackQuery := func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "%s", r.URL.RawQuery)
+	}
+
+	mux := NewServeMux()
+	mux.HandleFunc("/testOne", writeBackQuery)
+	mux.HandleFunc("/testTwo/", writeBackQuery)
+	mux.HandleFunc("/testThree", writeBackQuery)
+	mux.HandleFunc("/testThree/", func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "%s:bar", r.URL.RawQuery)
+	})
+
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	tests := [...]struct {
+		path     string
+		method   string
+		want     string
+		statusOk bool
+	}{
+		0: {"/testOne?this=that", "GET", "this=that", true},
+		1: {"/testTwo?foo=bar", "GET", "foo=bar", true},
+		2: {"/testTwo?a=1&b=2&a=3", "GET", "a=1&b=2&a=3", true},
+		3: {"/testTwo?", "GET", "", true},
+		4: {"/testThree?foo", "GET", "foo", true},
+		5: {"/testThree/?foo", "GET", "foo:bar", true},
+		6: {"/testThree?foo", "CONNECT", "foo", true},
+		7: {"/testThree/?foo", "CONNECT", "foo:bar", true},
+
+		// canonicalization or not
+		8: {"/testOne/foo/..?foo", "GET", "foo", true},
+		9: {"/testOne/foo/..?foo", "CONNECT", "404 page not found\n", false},
+	}
+
+	for i, tt := range tests {
+		req, _ := NewRequest(tt.method, ts.URL+tt.path, nil)
+		res, err := ts.Client().Do(req)
+		if err != nil {
+			continue
+		}
+		slurp, _ := ioutil.ReadAll(res.Body)
+		res.Body.Close()
+		if !tt.statusOk {
+			if got, want := res.StatusCode, 404; got != want {
+				t.Errorf("#%d: Status = %d; want = %d", i, got, want)
+			}
+		}
+		if got, want := string(slurp), tt.want; got != want {
+			t.Errorf("#%d: Body = %q; want = %q", i, got, want)
+		}
+	}
+}
+
+func TestServeWithSlashRedirectForHostPatterns(t *testing.T) {
+	setParallel(t)
+	defer afterTest(t)
+
+	mux := NewServeMux()
+	mux.Handle("example.com/pkg/foo/", stringHandler("example.com/pkg/foo/"))
+	mux.Handle("example.com/pkg/bar", stringHandler("example.com/pkg/bar"))
+	mux.Handle("example.com/pkg/bar/", stringHandler("example.com/pkg/bar/"))
+	mux.Handle("example.com:3000/pkg/connect/", stringHandler("example.com:3000/pkg/connect/"))
+	mux.Handle("example.com:9000/", stringHandler("example.com:9000/"))
+	mux.Handle("/pkg/baz/", stringHandler("/pkg/baz/"))
+
+	tests := []struct {
+		method string
+		url    string
+		code   int
+		loc    string
+		want   string
+	}{
+		{"GET", "http://example.com/", 404, "", ""},
+		{"GET", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""},
+		{"GET", "http://example.com/pkg/bar", 200, "", "example.com/pkg/bar"},
+		{"GET", "http://example.com/pkg/bar/", 200, "", "example.com/pkg/bar/"},
+		{"GET", "http://example.com/pkg/baz", 301, "/pkg/baz/", ""},
+		{"GET", "http://example.com:3000/pkg/foo", 301, "/pkg/foo/", ""},
+		{"CONNECT", "http://example.com/", 404, "", ""},
+		{"CONNECT", "http://example.com:3000/", 404, "", ""},
+		{"CONNECT", "http://example.com:9000/", 200, "", "example.com:9000/"},
+		{"CONNECT", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""},
+		{"CONNECT", "http://example.com:3000/pkg/foo", 404, "", ""},
+		{"CONNECT", "http://example.com:3000/pkg/baz", 301, "/pkg/baz/", ""},
+		{"CONNECT", "http://example.com:3000/pkg/connect", 301, "/pkg/connect/", ""},
+	}
+
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	for i, tt := range tests {
+		req, _ := NewRequest(tt.method, tt.url, nil)
+		w := httptest.NewRecorder()
+		mux.ServeHTTP(w, req)
+
+		if got, want := w.Code, tt.code; got != want {
+			t.Errorf("#%d: Status = %d; want = %d", i, got, want)
+		}
+
+		if tt.code == 301 {
+			if got, want := w.HeaderMap.Get("Location"), tt.loc; got != want {
+				t.Errorf("#%d: Location = %q; want = %q", i, got, want)
+			}
+		} else {
+			if got, want := w.HeaderMap.Get("Result"), tt.want; got != want {
+				t.Errorf("#%d: Result = %q; want = %q", i, got, want)
+			}
+		}
+	}
+}
+
 func BenchmarkServeMux(b *testing.B) {
 
 	type test struct {
@@ -624,12 +744,8 @@
 		req = req.WithContext(ctx)
 
 		r, err := c.Do(req)
-		select {
-		case <-ctx.Done():
-			if ctx.Err() == context.DeadlineExceeded {
-				t.Fatalf("http2 Get #%d response timed out", i)
-			}
-		default:
+		if ctx.Err() == context.DeadlineExceeded {
+			t.Fatalf("http2 Get #%d response timed out", i)
 		}
 		if err != nil {
 			t.Fatalf("http2 Get #%d: %v", i, err)
@@ -2376,6 +2492,14 @@
 	}
 }
 
+// https://golang.org/issues/22084
+func TestTimeoutHandlerPanicRecovery(t *testing.T) {
+	wrapper := func(h Handler) Handler {
+		return TimeoutHandler(h, time.Second, "")
+	}
+	testHandlerPanic(t, false, false, wrapper, "intentional death for testing")
+}
+
 func TestRedirectBadPath(t *testing.T) {
 	// This used to crash. It's not valid input (bad path), but it
 	// shouldn't crash.
@@ -2436,6 +2560,37 @@
 	}
 }
 
+// Test that Content-Type header is set for GET and HEAD requests.
+func TestRedirectContentTypeAndBody(t *testing.T) {
+	var tests = []struct {
+		method   string
+		wantCT   string
+		wantBody string
+	}{
+		{MethodGet, "text/html; charset=utf-8", "<a href=\"/foo\">Found</a>.\n\n"},
+		{MethodHead, "text/html; charset=utf-8", ""},
+		{MethodPost, "", ""},
+		{MethodDelete, "", ""},
+		{"foo", "", ""},
+	}
+	for _, tt := range tests {
+		req := httptest.NewRequest(tt.method, "http://example.com/qux/", nil)
+		rec := httptest.NewRecorder()
+		Redirect(rec, req, "/foo", 302)
+		if got, want := rec.Header().Get("Content-Type"), tt.wantCT; got != want {
+			t.Errorf("Redirect(%q) generated Content-Type header %q; want %q", tt.method, got, want)
+		}
+		resp := rec.Result()
+		body, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if got, want := string(body), tt.wantBody; got != want {
+			t.Errorf("Redirect(%q) generated Body %q; want %q", tt.method, got, want)
+		}
+	}
+}
+
 // 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
@@ -2489,22 +2644,22 @@
 	}
 }
 
-func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil) }
-func TestHandlerPanicNil_h2(t *testing.T) { testHandlerPanic(t, false, h2Mode, nil) }
+func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil, nil) }
+func TestHandlerPanicNil_h2(t *testing.T) { testHandlerPanic(t, false, h2Mode, nil, nil) }
 
 func TestHandlerPanic_h1(t *testing.T) {
-	testHandlerPanic(t, false, h1Mode, "intentional death for testing")
+	testHandlerPanic(t, false, h1Mode, nil, "intentional death for testing")
 }
 func TestHandlerPanic_h2(t *testing.T) {
-	testHandlerPanic(t, false, h2Mode, "intentional death for testing")
+	testHandlerPanic(t, false, h2Mode, nil, "intentional death for testing")
 }
 
 func TestHandlerPanicWithHijack(t *testing.T) {
 	// Only testing HTTP/1, and our http2 server doesn't support hijacking.
-	testHandlerPanic(t, true, h1Mode, "intentional death for testing")
+	testHandlerPanic(t, true, h1Mode, nil, "intentional death for testing")
 }
 
-func testHandlerPanic(t *testing.T, withHijack, h2 bool, panicValue interface{}) {
+func testHandlerPanic(t *testing.T, withHijack, h2 bool, wrapper func(Handler) Handler, 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
@@ -2527,7 +2682,7 @@
 	defer log.SetOutput(os.Stderr)
 	defer pw.Close()
 
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	var handler Handler = HandlerFunc(func(w ResponseWriter, r *Request) {
 		if withHijack {
 			rwc, _, err := w.(Hijacker).Hijack()
 			if err != nil {
@@ -2536,7 +2691,11 @@
 			defer rwc.Close()
 		}
 		panic(panicValue)
-	}))
+	})
+	if wrapper != nil {
+		handler = wrapper(handler)
+	}
+	cst := newClientServerTest(t, h2, handler)
 	defer cst.close()
 
 	// Do a blocking read on the log output pipe so its logging
@@ -2691,15 +2850,28 @@
 		req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
 	}
 	res, err := cst.c.Do(req)
-	if err != nil {
+	if res != nil {
+		defer res.Body.Close()
+	}
+	if h2 {
+		// In HTTP/2, the result depends on a race. If the client has received the
+		// server's SETTINGS before RoundTrip starts sending the request, then RoundTrip
+		// will fail with an error. Otherwise, the client should receive a 431 from the
+		// server.
+		if err == nil && res.StatusCode != 431 {
+			t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status)
+		}
+	} else {
+		// In HTTP/1, we expect a 431 from the server.
 		// 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 != 431 {
-		t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status)
+		if err != nil {
+			t.Fatalf("Do: %v", err)
+		}
+		if res.StatusCode != 431 {
+			t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status)
+		}
 	}
 }
 
@@ -3325,9 +3497,6 @@
 			handler: func(rw ResponseWriter, r *Request) {
 			},
 			check: func(got string) error {
-				if !strings.Contains(got, "Content-Type: text/plain") {
-					return errors.New("wrong content-type; want text/plain")
-				}
 				if !strings.Contains(got, "Content-Length: 0") {
 					return errors.New("want 0 content-length")
 				}
@@ -5336,7 +5505,11 @@
 func TestServerKeepAlivesEnabled_h1(t *testing.T) { testServerKeepAlivesEnabled(t, h1Mode) }
 func TestServerKeepAlivesEnabled_h2(t *testing.T) { testServerKeepAlivesEnabled(t, h2Mode) }
 func testServerKeepAlivesEnabled(t *testing.T, h2 bool) {
-	setParallel(t)
+	if h2 {
+		restore := ExportSetH2GoawayTimeout(10 * time.Millisecond)
+		defer restore()
+	}
+	// Not parallel: messes with global variable. (http2goAwayTimeout)
 	defer afterTest(t)
 	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "%v", r.RemoteAddr)
@@ -5363,32 +5536,54 @@
 func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) {
 	setParallel(t)
 	defer afterTest(t)
-	const timeout = 250 * time.Millisecond
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		select {
-		case <-time.After(2 * timeout):
-			fmt.Fprint(w, "ok")
-		case <-r.Context().Done():
-			fmt.Fprint(w, r.Context().Err())
+	runTimeSensitiveTest(t, []time.Duration{
+		10 * time.Millisecond,
+		50 * time.Millisecond,
+		250 * time.Millisecond,
+		time.Second,
+		2 * time.Second,
+	}, func(t *testing.T, timeout time.Duration) error {
+		ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+			select {
+			case <-time.After(2 * timeout):
+				fmt.Fprint(w, "ok")
+			case <-r.Context().Done():
+				fmt.Fprint(w, r.Context().Err())
+			}
+		}))
+		ts.Config.ReadTimeout = timeout
+		ts.Start()
+		defer ts.Close()
+
+		c := ts.Client()
+
+		res, err := c.Get(ts.URL)
+		if err != nil {
+			return fmt.Errorf("Get: %v", err)
 		}
-	}))
-	ts.Config.ReadTimeout = timeout
-	ts.Start()
-	defer ts.Close()
+		slurp, err := ioutil.ReadAll(res.Body)
+		res.Body.Close()
+		if err != nil {
+			return fmt.Errorf("Body ReadAll: %v", err)
+		}
+		if string(slurp) != "ok" {
+			return fmt.Errorf("got: %q, want ok", slurp)
+		}
+		return nil
+	})
+}
 
-	c := ts.Client()
-
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	slurp, err := ioutil.ReadAll(res.Body)
-	res.Body.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(slurp) != "ok" {
-		t.Fatalf("Got: %q, want ok", slurp)
+// runTimeSensitiveTest runs test with the provided durations until one passes.
+// If they all fail, t.Fatal is called with the last one's duration and error value.
+func runTimeSensitiveTest(t *testing.T, durations []time.Duration, test func(t *testing.T, d time.Duration) error) {
+	for i, d := range durations {
+		err := test(t, d)
+		if err == nil {
+			return
+		}
+		if i == len(durations)-1 {
+			t.Fatalf("failed with duration %v: %v", d, err)
+		}
 	}
 }
 
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 2fa8ab2..57e1b5d 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -132,12 +132,20 @@
 	// possible to maximize compatibility.
 	Write([]byte) (int, error)
 
-	// WriteHeader sends an HTTP response header with status code.
+	// WriteHeader sends an HTTP response header with the provided
+	// 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 provided code must be a valid HTTP 1xx-5xx status code.
+	// Only one header may be written. Go does not currently
+	// support sending user-defined 1xx informational headers,
+	// with the exception of 100-continue response header that the
+	// Server sends automatically when the Request.Body is read.
+	WriteHeader(statusCode int)
 }
 
 // The Flusher interface is implemented by ResponseWriters that allow
@@ -179,7 +187,7 @@
 	// The returned bufio.Reader may contain unprocessed buffered
 	// data from the client.
 	//
-	// After a call to Hijack, the original Request.Body should
+	// After a call to Hijack, the original Request.Body must
 	// not be used.
 	Hijack() (net.Conn, *bufio.ReadWriter, error)
 }
@@ -729,6 +737,9 @@
 	cr.lock()
 	if cr.inRead {
 		cr.unlock()
+		if cr.conn.hijacked() {
+			panic("invalid Body.Read call. After hijacked, the original Request must not be used")
+		}
 		panic("invalid concurrent Body.Read call")
 	}
 	if cr.hitReadLimit() {
@@ -1043,6 +1054,23 @@
 // well read them)
 const maxPostHandlerReadBytes = 256 << 10
 
+func checkWriteHeaderCode(code int) {
+	// Issue 22880: require valid WriteHeader status codes.
+	// For now we only enforce that it's three digits.
+	// In the future we might block things over 599 (600 and above aren't defined
+	// at http://httpwg.org/specs/rfc7231.html#status.codes)
+	// and we might block under 200 (once we have more mature 1xx support).
+	// But for now any three digits.
+	//
+	// We used to send "HTTP/1.1 000 0" on the wire in responses but there's
+	// no equivalent bogus thing we can realistically send in HTTP/2,
+	// so we'll consistently panic instead and help people find their bugs
+	// early. (We can't return an error from WriteHeader even if we wanted to.)
+	if code < 100 || code > 999 {
+		panic(fmt.Sprintf("invalid WriteHeader code %v", code))
+	}
+}
+
 func (w *response) WriteHeader(code int) {
 	if w.conn.hijacked() {
 		w.conn.server.logf("http: response.WriteHeader on hijacked connection")
@@ -1052,6 +1080,7 @@
 		w.conn.server.logf("http: multiple response.WriteHeader calls")
 		return
 	}
+	checkWriteHeaderCode(code)
 	w.wroteHeader = true
 	w.status = code
 
@@ -1210,7 +1239,7 @@
 		}
 	}
 
-	// Check for a explicit (and valid) Content-Length header.
+	// Check for an explicit (and valid) Content-Length header.
 	hasCL := w.contentLength != -1
 
 	if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
@@ -1308,7 +1337,7 @@
 	if bodyAllowedForStatus(code) {
 		// If no content type, apply sniffing algorithm to body.
 		_, haveType := header["Content-Type"]
-		if !haveType && !hasTE {
+		if !haveType && !hasTE && len(p) > 0 {
 			setHeader.contentType = DetectContentType(p)
 		}
 	} else {
@@ -1337,7 +1366,7 @@
 	} 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
+		// 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,
@@ -2014,6 +2043,9 @@
 	}
 
 	w.Header().Set("Location", hexEscapeNonASCII(url))
+	if r.Method == "GET" || r.Method == "HEAD" {
+		w.Header().Set("Content-Type", "text/html; charset=utf-8")
+	}
 	w.WriteHeader(code)
 
 	// RFC 2616 recommends that a short note "SHOULD" be included in the
@@ -2105,9 +2137,8 @@
 }
 
 type muxEntry struct {
-	explicit bool
-	h        Handler
-	pattern  string
+	h       Handler
+	pattern string
 }
 
 // NewServeMux allocates and returns a new ServeMux.
@@ -2185,6 +2216,44 @@
 	return
 }
 
+// redirectToPathSlash determines if the given path needs appending "/" to it.
+// This occurs when a handler for path + "/" was already registered, but
+// not for path itself. If the path needs appending to, it creates a new
+// URL, setting the path to u.Path + "/" and returning true to indicate so.
+func (mux *ServeMux) redirectToPathSlash(host, path string, u *url.URL) (*url.URL, bool) {
+	if !mux.shouldRedirect(host, path) {
+		return u, false
+	}
+	path = path + "/"
+	u = &url.URL{Path: path, RawQuery: u.RawQuery}
+	return u, true
+}
+
+// shouldRedirect reports whether the given path and host should be redirected to
+// path+"/". This should happen if a handler is registered for path+"/" but
+// not path -- see comments at ServeMux.
+func (mux *ServeMux) shouldRedirect(host, path string) bool {
+	p := []string{path, host + path}
+
+	for _, c := range p {
+		if _, exist := mux.m[c]; exist {
+			return false
+		}
+	}
+
+	n := len(path)
+	if n == 0 {
+		return false
+	}
+	for _, c := range p {
+		if _, exist := mux.m[c+"/"]; exist {
+			return path[n-1] != '/'
+		}
+	}
+
+	return false
+}
+
 // 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
@@ -2204,6 +2273,13 @@
 
 	// CONNECT requests are not canonicalized.
 	if r.Method == "CONNECT" {
+		// If r.URL.Path is /tree and its handler is not registered,
+		// the /tree -> /tree/ redirect applies to CONNECT requests
+		// but the path canonicalization does not.
+		if u, ok := mux.redirectToPathSlash(r.URL.Host, r.URL.Path, r.URL); ok {
+			return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
+		}
+
 		return mux.handler(r.Host, r.URL.Path)
 	}
 
@@ -2211,6 +2287,13 @@
 	// before passing to mux.handler.
 	host := stripHostPort(r.Host)
 	path := cleanPath(r.URL.Path)
+
+	// If the given path is /tree and its handler is not registered,
+	// redirect for /tree/.
+	if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok {
+		return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
+	}
+
 	if path != r.URL.Path {
 		_, pattern = mux.handler(host, path)
 		url := *r.URL
@@ -2261,40 +2344,23 @@
 	defer mux.mu.Unlock()
 
 	if pattern == "" {
-		panic("http: invalid pattern " + pattern)
+		panic("http: invalid pattern")
 	}
 	if handler == nil {
 		panic("http: nil handler")
 	}
-	if mux.m[pattern].explicit {
+	if _, exist := mux.m[pattern]; exist {
 		panic("http: multiple registrations for " + pattern)
 	}
 
 	if mux.m == nil {
 		mux.m = make(map[string]muxEntry)
 	}
-	mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
+	mux.m[pattern] = muxEntry{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, "/"):]
-		}
-		url := &url.URL{Path: path}
-		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
-	}
 }
 
 // HandleFunc registers the handler function for the given pattern.
@@ -2323,7 +2389,7 @@
 	return srv.Serve(l)
 }
 
-// Serve accepts incoming HTTPS connections on the listener l,
+// ServeTLS accepts incoming HTTPS 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.
 //
@@ -2341,9 +2407,17 @@
 // 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
-	TLSConfig *tls.Config // optional TLS config, used by ServeTLS and ListenAndServeTLS
+	Addr    string  // TCP address to listen on, ":http" if empty
+	Handler Handler // handler to invoke, http.DefaultServeMux if nil
+
+	// TLSConfig optionally provides a TLS configuration for use
+	// by ServeTLS and ListenAndServeTLS. Note that this value is
+	// cloned by ServeTLS and ListenAndServeTLS, so it's not
+	// possible to modify the configuration with methods like
+	// tls.Config.SetSessionTicketKeys. To use
+	// SetSessionTicketKeys, use Server.Serve with a TLS Listener
+	// instead.
+	TLSConfig *tls.Config
 
 	// ReadTimeout is the maximum duration for reading the entire
 	// request, including the body.
@@ -2396,9 +2470,9 @@
 	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.
+	// connections, unexpected behavior from handlers, and
+	// underlying FileSystem errors.
+	// If nil, logging is done via the log package's standard logger.
 	ErrorLog *log.Logger
 
 	disableKeepAlives int32     // accessed atomically.
@@ -2483,7 +2557,8 @@
 // Shutdown does not attempt to close nor wait for hijacked
 // connections such as WebSockets. The caller of Shutdown should
 // separately notify such long-lived connections of shutdown and wait
-// for them to close, if desired.
+// for them to close, if desired. See RegisterOnShutdown for a way to
+// register shutdown notification functions.
 func (srv *Server) Shutdown(ctx context.Context) error {
 	atomic.AddInt32(&srv.inShutdown, 1)
 	defer atomic.AddInt32(&srv.inShutdown, -1)
@@ -2732,7 +2807,7 @@
 // server's certificate, any intermediates, and the CA's certificate.
 //
 // For HTTP/2 support, srv.TLSConfig should be initialized to the
-// provided listener's TLS Config before calling Serve. If
+// provided listener's TLS Config before calling ServeTLS. If
 // srv.TLSConfig is non-nil and doesn't include the string "h2" in
 // Config.NextProtos, HTTP/2 support is not enabled.
 //
@@ -2849,6 +2924,18 @@
 	}
 }
 
+// logf prints to the ErrorLog of the *Server associated with request r
+// via ServerContextKey. If there's no associated server, or if ErrorLog
+// is nil, logging is done via the log package's standard logger.
+func logf(r *Request, format string, args ...interface{}) {
+	s, _ := r.Context().Value(ServerContextKey).(*Server)
+	if s != nil && 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.
@@ -2940,6 +3027,8 @@
 		return err
 	}
 
+	defer ln.Close()
+
 	return srv.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, certFile, keyFile)
 }
 
@@ -3015,9 +3104,9 @@
 	body    string
 	dt      time.Duration
 
-	// When set, no timer will be created and this channel will
+	// When set, no context will be created and this context will
 	// be used instead.
-	testTimeout <-chan time.Time
+	testContext context.Context
 }
 
 func (h *timeoutHandler) errorBody() string {
@@ -3028,22 +3117,31 @@
 }
 
 func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	var t *time.Timer
-	timeout := h.testTimeout
-	if timeout == nil {
-		t = time.NewTimer(h.dt)
-		timeout = t.C
+	ctx := h.testContext
+	if ctx == nil {
+		var cancelCtx context.CancelFunc
+		ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
+		defer cancelCtx()
 	}
+	r = r.WithContext(ctx)
 	done := make(chan struct{})
 	tw := &timeoutWriter{
 		w: w,
 		h: make(Header),
 	}
+	panicChan := make(chan interface{}, 1)
 	go func() {
+		defer func() {
+			if p := recover(); p != nil {
+				panicChan <- p
+			}
+		}()
 		h.handler.ServeHTTP(tw, r)
 		close(done)
 	}()
 	select {
+	case p := <-panicChan:
+		panic(p)
 	case <-done:
 		tw.mu.Lock()
 		defer tw.mu.Unlock()
@@ -3056,10 +3154,7 @@
 		}
 		w.WriteHeader(tw.code)
 		w.Write(tw.wbuf.Bytes())
-		if t != nil {
-			t.Stop()
-		}
-	case <-timeout:
+	case <-ctx.Done():
 		tw.mu.Lock()
 		defer tw.mu.Unlock()
 		w.WriteHeader(StatusServiceUnavailable)
@@ -3095,6 +3190,7 @@
 }
 
 func (tw *timeoutWriter) WriteHeader(code int) {
+	checkWriteHeaderCode(code)
 	tw.mu.Lock()
 	defer tw.mu.Unlock()
 	if tw.timedOut || tw.wroteHeader {
@@ -3116,10 +3212,10 @@
 	*net.TCPListener
 }
 
-func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
+func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
 	tc, err := ln.AcceptTCP()
 	if err != nil {
-		return
+		return nil, err
 	}
 	tc.SetKeepAlive(true)
 	tc.SetKeepAlivePeriod(3 * time.Minute)
diff --git a/src/net/http/sniff.go b/src/net/http/sniff.go
index ecc65e4..365a36c 100644
--- a/src/net/http/sniff.go
+++ b/src/net/http/sniff.go
@@ -91,6 +91,7 @@
 		ct:   "image/webp",
 	},
 	&exactSig{[]byte("\x00\x00\x01\x00"), "image/vnd.microsoft.icon"},
+
 	&maskedSig{
 		mask: []byte("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"),
 		pat:  []byte("RIFF\x00\x00\x00\x00WAVE"),
@@ -126,6 +127,20 @@
 		pat:  []byte("RIFF\x00\x00\x00\x00AVI "),
 		ct:   "video/avi",
 	},
+
+	// Fonts
+	&maskedSig{
+		// 34 NULL bytes followed by the string "LP"
+		pat: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x50"),
+		// 34 NULL bytes followed by \xF\xF
+		mask: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"),
+		ct:   "application/vnd.ms-fontobject",
+	},
+	&exactSig{[]byte("\x00\x01\x00\x00"), "application/font-ttf"},
+	&exactSig{[]byte("OTTO"), "application/font-off"},
+	&exactSig{[]byte("ttcf"), "application/font-cff"},
+	&exactSig{[]byte("wOFF"), "application/font-woff"},
+
 	&exactSig{[]byte("\x1A\x45\xDF\xA3"), "video/webm"},
 	&exactSig{[]byte("\x52\x61\x72\x20\x1A\x07\x00"), "application/x-rar-compressed"},
 	&exactSig{[]byte("\x50\x4B\x03\x04"), "application/zip"},
diff --git a/src/net/http/sniff_test.go b/src/net/http/sniff_test.go
index 24f1298..bf1f6be 100644
--- a/src/net/http/sniff_test.go
+++ b/src/net/http/sniff_test.go
@@ -55,6 +55,17 @@
 	{"MP4 video", []byte("\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42isom<\x06t\xbfmdat"), "video/mp4"},
 	{"AVI video #1", []byte("RIFF,O\n\x00AVI LISTÀ"), "video/avi"},
 	{"AVI video #2", []byte("RIFF,\n\x00\x00AVI LISTÀ"), "video/avi"},
+
+	// Font types.
+	// {"MS.FontObject", []byte("\x00\x00")},
+	{"TTF sample  I", []byte("\x00\x01\x00\x00\x00\x17\x01\x00\x00\x04\x01\x60\x4f"), "application/font-ttf"},
+	{"TTF sample II", []byte("\x00\x01\x00\x00\x00\x0e\x00\x80\x00\x03\x00\x60\x46"), "application/font-ttf"},
+
+	{"OTTO sample  I", []byte("\x4f\x54\x54\x4f\x00\x0e\x00\x80\x00\x03\x00\x60\x42\x41\x53\x45"), "application/font-off"},
+
+	{"woff sample  I", []byte("\x77\x4f\x46\x46\x00\x01\x00\x00\x00\x00\x30\x54\x00\x0d\x00\x00"), "application/font-woff"},
+	// Woff2 is not yet recognized, change this test once mime-sniff working group adds woff2
+	{"woff2 not recognized", []byte("\x77\x4f\x46\x32\x00\x01\x00\x00\x00"), "application/octet-stream"},
 }
 
 func TestDetectContentType(t *testing.T) {
@@ -88,8 +99,17 @@
 			t.Errorf("%v: %v", tt.desc, err)
 			continue
 		}
-		if ct := resp.Header.Get("Content-Type"); ct != tt.contentType {
-			t.Errorf("%v: Content-Type = %q, want %q", tt.desc, ct, tt.contentType)
+		// DetectContentType is defined to return
+		// text/plain; charset=utf-8 for an empty body,
+		// but as of Go 1.10 the HTTP server has been changed
+		// to return no content-type at all for an empty body.
+		// Adjust the expectation here.
+		wantContentType := tt.contentType
+		if len(tt.data) == 0 {
+			wantContentType = ""
+		}
+		if ct := resp.Header.Get("Content-Type"); ct != wantContentType {
+			t.Errorf("%v: Content-Type = %q, want %q", tt.desc, ct, wantContentType)
 		}
 		data, err := ioutil.ReadAll(resp.Body)
 		if err != nil {
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index 8faff2d..a400a6a 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -497,7 +497,7 @@
 	// or close connection when finished, since multipart is not supported yet
 	switch {
 	case chunked(t.TransferEncoding):
-		if noResponseBodyExpected(t.RequestMethod) {
+		if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) {
 			t.Body = NoBody
 		} else {
 			t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
@@ -663,9 +663,8 @@
 			return -1, err
 		}
 		return n, nil
-	} else {
-		header.Del("Content-Length")
 	}
+	header.Del("Content-Length")
 
 	if isRequest {
 		// RFC 2616 neither explicitly permits nor forbids an
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 6a89392..7ef8f01 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -73,6 +73,15 @@
 // and how the Transport is configured. The DefaultTransport supports HTTP/2.
 // To explicitly enable HTTP/2 on a transport, use golang.org/x/net/http2
 // and call ConfigureTransport. See the package docs for more about HTTP/2.
+//
+// The Transport will send CONNECT requests to a proxy for its own use
+// when processing HTTPS requests, but Transport should generally not
+// be used to send a CONNECT request. That is, the Request passed to
+// the RoundTrip method should not have a Method of "CONNECT", as Go's
+// HTTP/1.x implementation does not support full-duplex request bodies
+// being written while the response body is streamed. Go's HTTP/2
+// implementation does support full duplex, but many CONNECT proxies speak
+// HTTP/1.x.
 type Transport struct {
 	idleMu     sync.Mutex
 	wantIdle   bool                                // user has requested to close all idle conns
@@ -443,7 +452,7 @@
 // HTTP request on a new connection. The non-nil input error is the
 // error from roundTrip.
 func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
-	if err == http2ErrNoCachedConn {
+	if http2isNoCachedConnError(err) {
 		// Issue 16582: if the user started a bunch of
 		// requests at once, they can all pick the same conn
 		// and violate the server's max concurrent streams.
@@ -646,9 +655,14 @@
 	errTooManyIdleHost    = errors.New("http: putIdleConn: too many idle connections for host")
 	errCloseIdleConns     = errors.New("http: CloseIdleConnections called")
 	errReadLoopExiting    = errors.New("http: persistConn.readLoop exiting")
-	errServerClosedIdle   = errors.New("http: server closed idle connection")
 	errIdleConnTimeout    = errors.New("http: idle connection timeout")
 	errNotCachingH2Conn   = errors.New("http: not caching alternate protocol's connections")
+
+	// errServerClosedIdle is not seen by users for idempotent requests, but may be
+	// seen by a user if the server shuts down an idle connection and sends its FIN
+	// in flight with already-written POST body bytes from the client.
+	// See https://github.com/golang/go/issues/19943#issuecomment-355607646
+	errServerClosedIdle = errors.New("http: server closed idle connection")
 )
 
 // transportReadFromServerError is used by Transport.readLoop when the
@@ -1016,6 +1030,69 @@
 	}
 }
 
+// The connect method and the transport can both specify a TLS
+// Host name.  The transport's name takes precedence if present.
+func chooseTLSHost(cm connectMethod, t *Transport) string {
+	tlsHost := ""
+	if t.TLSClientConfig != nil {
+		tlsHost = t.TLSClientConfig.ServerName
+	}
+	if tlsHost == "" {
+		tlsHost = cm.tlsHost()
+	}
+	return tlsHost
+}
+
+// Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS
+// tunnel, this function establishes a nested TLS session inside the encrypted channel.
+// The remote endpoint's name may be overridden by TLSClientConfig.ServerName.
+func (pconn *persistConn) addTLS(name string, trace *httptrace.ClientTrace) error {
+	// Initiate TLS and check remote host name against certificate.
+	cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
+	if cfg.ServerName == "" {
+		cfg.ServerName = name
+	}
+	plainConn := pconn.conn
+	tlsConn := tls.Client(plainConn, cfg)
+	errc := make(chan error, 2)
+	var timer *time.Timer // for canceling TLS handshake
+	if d := pconn.t.TLSHandshakeTimeout; d != 0 {
+		timer = time.AfterFunc(d, func() {
+			errc <- tlsHandshakeTimeoutError{}
+		})
+	}
+	go func() {
+		if trace != nil && trace.TLSHandshakeStart != nil {
+			trace.TLSHandshakeStart()
+		}
+		err := tlsConn.Handshake()
+		if timer != nil {
+			timer.Stop()
+		}
+		errc <- err
+	}()
+	if err := <-errc; err != nil {
+		plainConn.Close()
+		if trace != nil && trace.TLSHandshakeDone != nil {
+			trace.TLSHandshakeDone(tls.ConnectionState{}, err)
+		}
+		return err
+	}
+	if !cfg.InsecureSkipVerify {
+		if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
+			plainConn.Close()
+			return err
+		}
+	}
+	cs := tlsConn.ConnectionState()
+	if trace != nil && trace.TLSHandshakeDone != nil {
+		trace.TLSHandshakeDone(cs, nil)
+	}
+	pconn.tlsState = &cs
+	pconn.conn = tlsConn
+	return nil
+}
+
 func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (*persistConn, error) {
 	pconn := &persistConn{
 		t:             t,
@@ -1027,15 +1104,21 @@
 		writeLoopDone: make(chan struct{}),
 	}
 	trace := httptrace.ContextClientTrace(ctx)
-	tlsDial := t.DialTLS != nil && cm.targetScheme == "https" && cm.proxyURL == nil
-	if tlsDial {
+	wrapErr := func(err error) error {
+		if cm.proxyURL != nil {
+			// Return a typed error, per Issue 16997
+			return &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err}
+		}
+		return err
+	}
+	if cm.scheme() == "https" && t.DialTLS != nil {
 		var err error
 		pconn.conn, err = t.DialTLS("tcp", cm.addr())
 		if err != nil {
-			return nil, err
+			return nil, wrapErr(err)
 		}
 		if pconn.conn == nil {
-			return nil, errors.New("net/http: Transport.DialTLS returned (nil, nil)")
+			return nil, wrapErr(errors.New("net/http: Transport.DialTLS returned (nil, nil)"))
 		}
 		if tc, ok := pconn.conn.(*tls.Conn); ok {
 			// Handshake here, in case DialTLS didn't. TLSNextProto below
@@ -1059,13 +1142,18 @@
 	} else {
 		conn, err := t.dial(ctx, "tcp", cm.addr())
 		if err != nil {
-			if cm.proxyURL != nil {
-				// Return a typed error, per Issue 16997:
-				err = &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err}
-			}
-			return nil, err
+			return nil, wrapErr(err)
 		}
 		pconn.conn = conn
+		if cm.scheme() == "https" {
+			var firstTLSHost string
+			if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
+				return nil, wrapErr(err)
+			}
+			if err = pconn.addTLS(firstTLSHost, trace); err != nil {
+				return nil, wrapErr(err)
+			}
+		}
 	}
 
 	// Proxy setup.
@@ -1125,54 +1213,17 @@
 		if resp.StatusCode != 200 {
 			f := strings.SplitN(resp.Status, " ", 2)
 			conn.Close()
+			if len(f) < 2 {
+				return nil, errors.New("unknown status code")
+			}
 			return nil, errors.New(f[1])
 		}
 	}
 
-	if cm.targetScheme == "https" && !tlsDial {
-		// Initiate TLS and check remote host name against certificate.
-		cfg := cloneTLSConfig(t.TLSClientConfig)
-		if cfg.ServerName == "" {
-			cfg.ServerName = cm.tlsHost()
-		}
-		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() {
-			if trace != nil && trace.TLSHandshakeStart != nil {
-				trace.TLSHandshakeStart()
-			}
-			err := tlsConn.Handshake()
-			if timer != nil {
-				timer.Stop()
-			}
-			errc <- err
-		}()
-		if err := <-errc; err != nil {
-			plainConn.Close()
-			if trace != nil && trace.TLSHandshakeDone != nil {
-				trace.TLSHandshakeDone(tls.ConnectionState{}, err)
-			}
+	if cm.proxyURL != nil && cm.targetScheme == "https" {
+		if err := pconn.addTLS(cm.tlsHost(), trace); err != nil {
 			return nil, err
 		}
-		if !cfg.InsecureSkipVerify {
-			if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
-				plainConn.Close()
-				return nil, err
-			}
-		}
-		cs := tlsConn.ConnectionState()
-		if trace != nil && trace.TLSHandshakeDone != nil {
-			trace.TLSHandshakeDone(cs, nil)
-		}
-		pconn.tlsState = &cs
-		pconn.conn = tlsConn
 	}
 
 	if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" {
@@ -1224,8 +1275,8 @@
 		}
 	}
 
-	no_proxy := noProxyEnv.Get()
-	if no_proxy == "*" {
+	noProxy := noProxyEnv.Get()
+	if noProxy == "*" {
 		return false
 	}
 
@@ -1234,7 +1285,7 @@
 		addr = addr[:strings.LastIndex(addr, ":")]
 	}
 
-	for _, p := range strings.Split(no_proxy, ",") {
+	for _, p := range strings.Split(noProxy, ",") {
 		p = strings.ToLower(strings.TrimSpace(p))
 		if len(p) == 0 {
 			continue
@@ -1266,21 +1317,24 @@
 //
 // 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
-// socks5://proxy.com|http|foo.com   socks5 to proxy, then http to foo.com
-// socks5://proxy.com|https|foo.com  socks5 to proxy, then https to foo.com
-//
-// Note: no support to https to the proxy yet.
+//	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
+//	socks5://proxy.com|http|foo.com   socks5 to proxy, then http to foo.com
+//	socks5://proxy.com|https|foo.com  socks5 to proxy, then https to foo.com
+//	https://proxy.com|https|foo.com   https to proxy, then CONNECT to foo.com
+//	https://proxy.com|http            https to proxy, http to anywhere after that
 //
 type connectMethod struct {
 	proxyURL     *url.URL // nil for no proxy, else full proxy URL
 	targetScheme string   // "http" or "https"
-	targetAddr   string   // Not used if http proxy + http targetScheme (4th example in table)
+	// If proxyURL specifies an http or https proxy, and targetScheme is http (not https),
+	// then targetAddr is not included in the connect method key, because the socket can
+	// be reused for different targetAddr values.
+	targetAddr string
 }
 
 func (cm *connectMethod) key() connectMethodKey {
@@ -1288,7 +1342,7 @@
 	targetAddr := cm.targetAddr
 	if cm.proxyURL != nil {
 		proxyStr = cm.proxyURL.String()
-		if strings.HasPrefix(cm.proxyURL.Scheme, "http") && cm.targetScheme == "http" {
+		if (cm.proxyURL.Scheme == "http" || cm.proxyURL.Scheme == "https") && cm.targetScheme == "http" {
 			targetAddr = ""
 		}
 	}
@@ -1299,6 +1353,14 @@
 	}
 }
 
+// scheme returns the first hop scheme: http, https, or socks5
+func (cm *connectMethod) scheme() string {
+	if cm.proxyURL != nil {
+		return cm.proxyURL.Scheme
+	}
+	return cm.targetScheme
+}
+
 // addr returns the first hop "host:port" to which we need to TCP connect.
 func (cm *connectMethod) addr() string {
 	if cm.proxyURL != nil {
@@ -1616,6 +1678,7 @@
 			body: resp.Body,
 			earlyCloseFn: func() error {
 				waitForBodyRead <- false
+				<-eofc // will be closed by deferred call at the end of the function
 				return nil
 
 			},
@@ -2021,8 +2084,8 @@
 // a t.Logf func. See export_test.go's Request.WithT method.
 type tLogKey struct{}
 
-func (r *transportRequest) logf(format string, args ...interface{}) {
-	if logf, ok := r.Request.Context().Value(tLogKey{}).(func(string, ...interface{})); ok {
+func (tr *transportRequest) logf(format string, args ...interface{}) {
+	if logf, ok := tr.Request.Context().Value(tLogKey{}).(func(string, ...interface{})); ok {
 		logf(time.Now().Format(time.RFC3339Nano)+": "+format, args...)
 	}
 }
diff --git a/src/net/http/transport_internal_test.go b/src/net/http/transport_internal_test.go
index 594bf6e..a5f29c9 100644
--- a/src/net/http/transport_internal_test.go
+++ b/src/net/http/transport_internal_test.go
@@ -96,6 +96,12 @@
 	return req
 }
 
+// issue22091Error acts like a golang.org/x/net/http2.ErrNoCachedConn.
+type issue22091Error struct{}
+
+func (issue22091Error) IsHTTP2NoCachedConnError() {}
+func (issue22091Error) Error() string             { return "issue22091Error" }
+
 func TestTransportShouldRetryRequest(t *testing.T) {
 	tests := []struct {
 		pc  *persistConn
@@ -123,36 +129,42 @@
 			want: true,
 		},
 		3: {
+			pc:   nil,
+			req:  nil,
+			err:  issue22091Error{}, // like an external http2ErrNoCachedConn
+			want: true,
+		},
+		4: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequest("POST"),
 			err:  errMissingHost,
 			want: false,
 		},
-		4: {
+		5: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequest("POST"),
 			err:  transportReadFromServerError{},
 			want: false,
 		},
-		5: {
+		6: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequest("GET"),
 			err:  transportReadFromServerError{},
 			want: true,
 		},
-		6: {
+		7: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequest("GET"),
 			err:  errServerClosedIdle,
 			want: true,
 		},
-		7: {
+		8: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequestWithBody("POST"),
 			err:  nothingWrittenError{},
 			want: true,
 		},
-		8: {
+		9: {
 			pc:   &persistConn{reused: true},
 			req:  dummyRequestWithBodyNoGetBody("POST"),
 			err:  nothingWrittenError{},
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 27b55dc..5588077 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -124,6 +124,34 @@
 	}
 }
 
+func TestReuseRequest(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Write([]byte("{}"))
+	}))
+	defer ts.Close()
+
+	c := ts.Client()
+	req, _ := NewRequest("GET", ts.URL, nil)
+	res, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = res.Body.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	res, err = c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = res.Body.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 // 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) {
@@ -933,14 +961,10 @@
 func TestSocks5Proxy(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()
 	l := newLocalListener(t)
 	defer l.Close()
-	go func() {
-		defer close(ch)
+	defer close(ch)
+	proxy := func(t *testing.T) {
 		s, err := l.Accept()
 		if err != nil {
 			t.Errorf("socks5 proxy Accept(): %v", err)
@@ -975,7 +999,8 @@
 		case 4:
 			ipLen = 16
 		default:
-			t.Fatalf("socks5 proxy second read: unexpected address type %v", buf[4])
+			t.Errorf("socks5 proxy second read: unexpected address type %v", buf[4])
+			return
 		}
 		if _, err := io.ReadFull(s, buf[4:ipLen+6]); err != nil {
 			t.Errorf("socks5 proxy address read: %v", err)
@@ -988,71 +1013,196 @@
 			t.Errorf("socks5 proxy connect write: %v", err)
 			return
 		}
-		done := make(chan struct{})
-		srv := &Server{Handler: HandlerFunc(func(w ResponseWriter, r *Request) {
-			done <- struct{}{}
-		})}
-		srv.Serve(&oneConnListener{conn: s})
-		<-done
-		srv.Shutdown(context.Background())
 		ch <- fmt.Sprintf("proxy for %s:%d", ip, port)
-	}()
+
+		// Implement proxying.
+		targetHost := net.JoinHostPort(ip.String(), strconv.Itoa(int(port)))
+		targetConn, err := net.Dial("tcp", targetHost)
+		if err != nil {
+			t.Errorf("net.Dial failed")
+			return
+		}
+		go io.Copy(targetConn, s)
+		io.Copy(s, targetConn) // Wait for the client to close the socket.
+		targetConn.Close()
+	}
 
 	pu, err := url.Parse("socks5://" + l.Addr().String())
 	if err != nil {
 		t.Fatal(err)
 	}
-	c := ts.Client()
-	c.Transport.(*Transport).Proxy = ProxyURL(pu)
-	if _, err := c.Head(ts.URL); err != nil {
-		t.Error(err)
-	}
-	var got string
-	select {
-	case got = <-ch:
-	case <-time.After(5 * time.Second):
-		t.Fatal("timeout connecting to socks5 proxy")
-	}
-	tsu, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	want := "proxy for " + tsu.Host
-	if got != want {
-		t.Errorf("got %q, want %q", got, want)
+
+	sentinelHeader := "X-Sentinel"
+	sentinelValue := "12345"
+	h := HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set(sentinelHeader, sentinelValue)
+	})
+	for _, useTLS := range []bool{false, true} {
+		t.Run(fmt.Sprintf("useTLS=%v", useTLS), func(t *testing.T) {
+			var ts *httptest.Server
+			if useTLS {
+				ts = httptest.NewTLSServer(h)
+			} else {
+				ts = httptest.NewServer(h)
+			}
+			go proxy(t)
+			c := ts.Client()
+			c.Transport.(*Transport).Proxy = ProxyURL(pu)
+			r, err := c.Head(ts.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if r.Header.Get(sentinelHeader) != sentinelValue {
+				t.Errorf("Failed to retrieve sentinel value")
+			}
+			var got string
+			select {
+			case got = <-ch:
+			case <-time.After(5 * time.Second):
+				t.Fatal("timeout connecting to socks5 proxy")
+			}
+			ts.Close()
+			tsu, err := url.Parse(ts.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+			want := "proxy for " + tsu.Host
+			if got != want {
+				t.Errorf("got %q, want %q", got, want)
+			}
+		})
 	}
 }
 
 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()
+	testCases := []struct{ httpsSite, httpsProxy bool }{
+		{false, false},
+		{false, true},
+		{true, false},
+		{true, true},
+	}
+	for _, testCase := range testCases {
+		httpsSite := testCase.httpsSite
+		httpsProxy := testCase.httpsProxy
+		t.Run(fmt.Sprintf("httpsSite=%v, httpsProxy=%v", httpsSite, httpsProxy), func(t *testing.T) {
+			siteCh := make(chan *Request, 1)
+			h1 := HandlerFunc(func(w ResponseWriter, r *Request) {
+				siteCh <- r
+			})
+			proxyCh := make(chan *Request, 1)
+			h2 := HandlerFunc(func(w ResponseWriter, r *Request) {
+				proxyCh <- r
+				// Implement an entire CONNECT proxy
+				if r.Method == "CONNECT" {
+					hijacker, ok := w.(Hijacker)
+					if !ok {
+						t.Errorf("hijack not allowed")
+						return
+					}
+					clientConn, _, err := hijacker.Hijack()
+					if err != nil {
+						t.Errorf("hijacking failed")
+						return
+					}
+					res := &Response{
+						StatusCode: StatusOK,
+						Proto:      "HTTP/1.1",
+						ProtoMajor: 1,
+						ProtoMinor: 1,
+						Header:     make(Header),
+					}
 
-	pu, err := url.Parse(proxy.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	c := ts.Client()
-	c.Transport.(*Transport).Proxy = ProxyURL(pu)
-	if _, err := c.Head(ts.URL); err != nil {
-		t.Error(err)
-	}
-	var got string
-	select {
-	case got = <-ch:
-	case <-time.After(5 * time.Second):
-		t.Fatal("timeout connecting to http proxy")
-	}
-	want := "proxy for " + ts.URL + "/"
-	if got != want {
-		t.Errorf("got %q, want %q", got, want)
+					targetConn, err := net.Dial("tcp", r.URL.Host)
+					if err != nil {
+						t.Errorf("net.Dial(%q) failed: %v", r.URL.Host, err)
+						return
+					}
+
+					if err := res.Write(clientConn); err != nil {
+						t.Errorf("Writing 200 OK failed: %v", err)
+						return
+					}
+
+					go io.Copy(targetConn, clientConn)
+					go func() {
+						io.Copy(clientConn, targetConn)
+						targetConn.Close()
+					}()
+				}
+			})
+			var ts *httptest.Server
+			if httpsSite {
+				ts = httptest.NewTLSServer(h1)
+			} else {
+				ts = httptest.NewServer(h1)
+			}
+			var proxy *httptest.Server
+			if httpsProxy {
+				proxy = httptest.NewTLSServer(h2)
+			} else {
+				proxy = httptest.NewServer(h2)
+			}
+
+			pu, err := url.Parse(proxy.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// If neither server is HTTPS or both are, then c may be derived from either.
+			// If only one server is HTTPS, c must be derived from that server in order
+			// to ensure that it is configured to use the fake root CA from testcert.go.
+			c := proxy.Client()
+			if httpsSite {
+				c = ts.Client()
+			}
+
+			c.Transport.(*Transport).Proxy = ProxyURL(pu)
+			if _, err := c.Head(ts.URL); err != nil {
+				t.Error(err)
+			}
+			var got *Request
+			select {
+			case got = <-proxyCh:
+			case <-time.After(5 * time.Second):
+				t.Fatal("timeout connecting to http proxy")
+			}
+			c.Transport.(*Transport).CloseIdleConnections()
+			ts.Close()
+			proxy.Close()
+			if httpsSite {
+				// First message should be a CONNECT, asking for a socket to the real server,
+				if got.Method != "CONNECT" {
+					t.Errorf("Wrong method for secure proxying: %q", got.Method)
+				}
+				gotHost := got.URL.Host
+				pu, err := url.Parse(ts.URL)
+				if err != nil {
+					t.Fatal("Invalid site URL")
+				}
+				if wantHost := pu.Host; gotHost != wantHost {
+					t.Errorf("Got CONNECT host %q, want %q", gotHost, wantHost)
+				}
+
+				// The next message on the channel should be from the site's server.
+				next := <-siteCh
+				if next.Method != "HEAD" {
+					t.Errorf("Wrong method at destination: %s", next.Method)
+				}
+				if nextURL := next.URL.String(); nextURL != "/" {
+					t.Errorf("Wrong URL at destination: %s", nextURL)
+				}
+			} else {
+				if got.Method != "HEAD" {
+					t.Errorf("Wrong method for destination: %q", got.Method)
+				}
+				gotURL := got.URL.String()
+				wantURL := ts.URL + "/"
+				if gotURL != wantURL {
+					t.Errorf("Got URL %q, want %q", gotURL, wantURL)
+				}
+			}
+		})
 	}
 }
 
@@ -4118,3 +4268,100 @@
 	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
 	0x00, 0x00,
 }
+
+// Ensure that a missing status doesn't make the server panic
+// See Issue https://golang.org/issues/21701
+func TestMissingStatusNoPanic(t *testing.T) {
+	t.Parallel()
+
+	const want = "unknown status code"
+
+	ln := newLocalListener(t)
+	addr := ln.Addr().String()
+	shutdown := make(chan bool, 1)
+	done := make(chan bool)
+	fullAddrURL := fmt.Sprintf("http://%s", addr)
+	raw := "HTTP/1.1 400\r\n" +
+		"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
+		"Content-Type: text/html; charset=utf-8\r\n" +
+		"Content-Length: 10\r\n" +
+		"Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT\r\n" +
+		"Vary: Accept-Encoding\r\n\r\n" +
+		"Aloha Olaa"
+
+	go func() {
+		defer func() {
+			ln.Close()
+			close(done)
+		}()
+
+		conn, _ := ln.Accept()
+		if conn != nil {
+			io.WriteString(conn, raw)
+			ioutil.ReadAll(conn)
+			conn.Close()
+		}
+	}()
+
+	proxyURL, err := url.Parse(fullAddrURL)
+	if err != nil {
+		t.Fatalf("proxyURL: %v", err)
+	}
+
+	tr := &Transport{Proxy: ProxyURL(proxyURL)}
+
+	req, _ := NewRequest("GET", "https://golang.org/", nil)
+	res, err, panicked := doFetchCheckPanic(tr, req)
+	if panicked {
+		t.Error("panicked, expecting an error")
+	}
+	if res != nil && res.Body != nil {
+		io.Copy(ioutil.Discard, res.Body)
+		res.Body.Close()
+	}
+
+	if err == nil || !strings.Contains(err.Error(), want) {
+		t.Errorf("got=%v want=%q", err, want)
+	}
+
+	close(shutdown)
+	<-done
+}
+
+func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
+	defer func() {
+		if r := recover(); r != nil {
+			panicked = true
+		}
+	}()
+	res, err = tr.RoundTrip(req)
+	return
+}
+
+// Issue 22330: do not allow the response body to be read when the status code
+// forbids a response body.
+func TestNoBodyOnChunked304Response(t *testing.T) {
+	defer afterTest(t)
+	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		conn, buf, _ := w.(Hijacker).Hijack()
+		buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
+		buf.Flush()
+		conn.Close()
+	}))
+	defer cst.close()
+
+	// Our test server above is sending back bogus data after the
+	// response (the "0\r\n\r\n" part), which causes the Transport
+	// code to log spam. Disable keep-alives so we never even try
+	// to reuse the connection.
+	cst.tr.DisableKeepAlives = true
+
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if res.Body != NoBody {
+		t.Errorf("Unexpected body on 304 response")
+	}
+}
diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go
index 2e3d2bc..8c1c862 100644
--- a/src/net/internal/socktest/sys_windows.go
+++ b/src/net/internal/socktest/sys_windows.go
@@ -4,7 +4,10 @@
 
 package socktest
 
-import "syscall"
+import (
+	"internal/syscall/windows"
+	"syscall"
+)
 
 // Socket wraps syscall.Socket.
 func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) {
@@ -38,6 +41,38 @@
 	return s, nil
 }
 
+// WSASocket wraps syscall.WSASocket.
+func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) {
+	sw.once.Do(sw.init)
+
+	so := &Status{Cookie: cookie(int(family), int(sotype), int(proto))}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterSocket]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return syscall.InvalidHandle, err
+	}
+	s, so.Err = windows.WSASocket(family, sotype, proto, protinfo, group, flags)
+	if err = af.apply(so); err != nil {
+		if so.Err == nil {
+			syscall.Closesocket(s)
+		}
+		return syscall.InvalidHandle, err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).OpenFailed++
+		return syscall.InvalidHandle, so.Err
+	}
+	nso := sw.addLocked(s, int(family), int(sotype), int(proto))
+	sw.stats.getLocked(nso.Cookie).Opened++
+	return s, nil
+}
+
 // Closesocket wraps syscall.Closesocket.
 func (sw *Switch) Closesocket(s syscall.Handle) (err error) {
 	so := sw.sockso(s)
diff --git a/src/net/iprawsock.go b/src/net/iprawsock.go
index c4b54f0..72cbc39 100644
--- a/src/net/iprawsock.go
+++ b/src/net/iprawsock.go
@@ -21,7 +21,7 @@
 // change the behavior of these methods; use Read or ReadMsgIP
 // instead.
 
-// BUG(mikio): On NaCl, Plan 9 and Windows, the ReadMsgIP and
+// BUG(mikio): On NaCl and Plan 9, the ReadMsgIP and
 // WriteMsgIP methods of IPConn are not implemented.
 
 // BUG(mikio): On Windows, the File method of IPConn is not
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go
index d659bf0..8372aaa 100644
--- a/src/net/ipsock_posix.go
+++ b/src/net/ipsock_posix.go
@@ -24,7 +24,7 @@
 // general. Unfortunately, we need to run on kernels built without
 // IPv6 support too. So probe the kernel to figure it out.
 func (p *ipStackCapabilities) probe() {
-	s, err := socketFunc(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+	s, err := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
 	switch err {
 	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
 	case nil:
@@ -48,7 +48,7 @@
 		probes = probes[:1]
 	}
 	for i := range probes {
-		s, err := socketFunc(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		s, err := sysSocket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
 		if err != nil {
 			continue
 		}
diff --git a/src/net/listen_test.go b/src/net/listen_test.go
index 21ad446..96624f9 100644
--- a/src/net/listen_test.go
+++ b/src/net/listen_test.go
@@ -13,6 +13,7 @@
 	"runtime"
 	"syscall"
 	"testing"
+	"time"
 )
 
 func (ln *TCPListener) port() string {
@@ -696,3 +697,35 @@
 	}
 	return false, nil
 }
+
+// Issue 21856.
+func TestClosingListener(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	addr := ln.Addr()
+
+	go func() {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}()
+
+	// Let the goroutine start. We don't sleep long: if the
+	// goroutine doesn't start, the test will pass without really
+	// testing anything, which is OK.
+	time.Sleep(time.Millisecond)
+
+	ln.Close()
+
+	ln2, err := Listen("tcp", addr.String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	ln2.Close()
+}
diff --git a/src/net/lookup.go b/src/net/lookup.go
index c9f3270..85e4729 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -8,6 +8,7 @@
 	"context"
 	"internal/nettrace"
 	"internal/singleflight"
+	"sync"
 )
 
 // protocols contains minimal mappings between internet protocol
@@ -53,6 +54,10 @@
 	},
 }
 
+// dnsWaitGroup can be used by tests to wait for all DNS goroutines to
+// complete. This avoids races on the test hooks.
+var dnsWaitGroup sync.WaitGroup
+
 const maxProtoLength = len("RSVP-E2E-IGNORE") + 10 // with room to grow
 
 func lookupProtocolMap(name string) (int, error) {
@@ -189,9 +194,14 @@
 		resolverFunc = alt
 	}
 
-	ch := lookupGroup.DoChan(host, func() (interface{}, error) {
+	dnsWaitGroup.Add(1)
+	ch, called := lookupGroup.DoChan(host, func() (interface{}, error) {
+		defer dnsWaitGroup.Done()
 		return testHookLookupIP(ctx, resolverFunc, host)
 	})
+	if !called {
+		dnsWaitGroup.Done()
+	}
 
 	select {
 	case <-ctx.Done():
diff --git a/src/net/lookup_plan9.go b/src/net/lookup_plan9.go
index f81e220..1037b81 100644
--- a/src/net/lookup_plan9.go
+++ b/src/net/lookup_plan9.go
@@ -198,7 +198,7 @@
 func (*Resolver) lookupCNAME(ctx context.Context, name string) (cname string, err error) {
 	lines, err := queryDNS(ctx, name, "cname")
 	if err != nil {
-		if stringsHasSuffix(err.Error(), "dns failure") {
+		if stringsHasSuffix(err.Error(), "dns failure") || stringsHasSuffix(err.Error(), "resource does not exist; negrcode 0") {
 			cname = name + "."
 			err = nil
 		}
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index 68a7abe..bfb8725 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -9,7 +9,9 @@
 	"context"
 	"fmt"
 	"internal/testenv"
+	"reflect"
 	"runtime"
+	"sort"
 	"strings"
 	"testing"
 	"time"
@@ -103,6 +105,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGmailMXTests {
 		mxs, err := LookupMX(tt.name)
 		if err != nil {
@@ -135,6 +139,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGmailNSTests {
 		nss, err := LookupNS(tt.name)
 		if err != nil {
@@ -168,6 +174,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGmailTXTTests {
 		txts, err := LookupTXT(tt.name)
 		if err != nil {
@@ -203,6 +211,8 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGooglePublicDNSAddrTests {
 		names, err := LookupAddr(tt.addr)
 		if err != nil {
@@ -224,6 +234,8 @@
 		t.Skip("IPv6 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	addrs, err := LookupHost("localhost")
 	if err != nil {
 		t.Fatal(err)
@@ -260,6 +272,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupCNAMETests {
 		cname, err := LookupCNAME(tt.name)
 		if err != nil {
@@ -287,6 +301,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGoogleHostTests {
 		addrs, err := LookupHost(tt.name)
 		if err != nil {
@@ -303,6 +319,30 @@
 	}
 }
 
+func TestLookupLongTXT(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; see https://golang.org/issue/22857")
+	}
+	if testenv.Builder() == "" {
+		testenv.MustHaveExternalNetwork(t)
+	}
+
+	defer dnsWaitGroup.Wait()
+
+	txts, err := LookupTXT("golang.rsc.io")
+	if err != nil {
+		t.Fatal(err)
+	}
+	sort.Strings(txts)
+	want := []string{
+		strings.Repeat("abcdefghijklmnopqrstuvwxyABCDEFGHJIKLMNOPQRSTUVWXY", 10),
+		"gophers rule",
+	}
+	if !reflect.DeepEqual(txts, want) {
+		t.Fatalf("LookupTXT golang.rsc.io incorrect\nhave %q\nwant %q", txts, want)
+	}
+}
+
 var lookupGoogleIPTests = []struct {
 	name string
 }{
@@ -319,6 +359,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for _, tt := range lookupGoogleIPTests {
 		ips, err := LookupIP(tt.name)
 		if err != nil {
@@ -354,6 +396,7 @@
 }
 
 func TestReverseAddress(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	for i, tt := range revAddrTests {
 		a, err := reverseaddr(tt.Addr)
 		if len(tt.ErrPrefix) > 0 && err == nil {
@@ -377,6 +420,8 @@
 		t.Skip("test disabled; use -dnsflood to enable")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	var N = 5000
 	if runtime.GOOS == "darwin" {
 		// On Darwin this test consumes kernel threads much
@@ -458,6 +503,8 @@
 		testenv.MustHaveExternalNetwork(t)
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	for i, fn := range []func() func(){forceGoDNS, forceCgoDNS} {
 		fixup := fn()
 		if fixup == nil {
@@ -503,6 +550,8 @@
 		t.Skip("IPv4 is required")
 	}
 
+	defer dnsWaitGroup.Wait()
+
 	if fixup := forceGoDNS(); fixup != nil {
 		testDots(t, "go")
 		fixup()
@@ -723,6 +772,9 @@
 	if runtime.GOOS == "nacl" {
 		t.Skip("skip on nacl")
 	}
+
+	defer dnsWaitGroup.Wait()
+
 	if fixup := forceGoDNS(); fixup != nil {
 		defer fixup()
 	}
diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go
index 0036d89..ac1f9b4 100644
--- a/src/net/lookup_windows.go
+++ b/src/net/lookup_windows.go
@@ -279,10 +279,11 @@
 	txts := make([]string, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_TEXT, name) {
 		d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0]))
+		s := ""
 		for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount] {
-			s := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:])
-			txts = append(txts, s)
+			s += syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:])
 		}
+		txts = append(txts, s)
 	}
 	return txts, nil
 }
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 45a995e..4f3184f 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -10,10 +10,10 @@
 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.
 	* No unicode normalization is performed.
+	* The special characters ()[]:;@\, are allowed to appear unquoted in names.
 */
 package mail
 
@@ -190,7 +190,7 @@
 	// Add quotes if needed
 	quoteLocal := false
 	for i, r := range local {
-		if isAtext(r, false) {
+		if isAtext(r, false, false) {
 			continue
 		}
 		if r == '.' {
@@ -247,13 +247,15 @@
 	var list []*Address
 	for {
 		p.skipSpace()
-		addr, err := p.parseAddress()
+		addrs, err := p.parseAddress(true)
 		if err != nil {
 			return nil, err
 		}
-		list = append(list, addr)
+		list = append(list, addrs...)
 
-		p.skipSpace()
+		if !p.skipCFWS() {
+			return nil, errors.New("mail: misformatted parenthetical comment")
+		}
 		if p.empty() {
 			break
 		}
@@ -265,36 +267,55 @@
 }
 
 func (p *addrParser) parseSingleAddress() (*Address, error) {
-	addr, err := p.parseAddress()
+	addrs, err := p.parseAddress(true)
 	if err != nil {
 		return nil, err
 	}
-	p.skipSpace()
+	if !p.skipCFWS() {
+		return nil, errors.New("mail: misformatted parenthetical comment")
+	}
 	if !p.empty() {
 		return nil, fmt.Errorf("mail: expected single address, got %q", p.s)
 	}
-	return addr, nil
+	if len(addrs) == 0 {
+		return nil, errors.New("mail: empty group")
+	}
+	if len(addrs) > 1 {
+		return nil, errors.New("mail: group with multiple addresses")
+	}
+	return addrs[0], nil
 }
 
 // parseAddress parses a single RFC 5322 address at the start of p.
-func (p *addrParser) parseAddress() (addr *Address, err error) {
+func (p *addrParser) parseAddress(handleGroup bool) ([]*Address, error) {
 	debug.Printf("parseAddress: %q", p.s)
 	p.skipSpace()
 	if p.empty() {
 		return nil, errors.New("mail: no address")
 	}
 
-	// address = name-addr / addr-spec
-	// TODO(dsymonds): Support parsing group address.
+	// address = mailbox / group
+	// mailbox = name-addr / addr-spec
+	// group = display-name ":" [group-list] ";" [CFWS]
 
 	// 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{
+		var displayName string
+		p.skipSpace()
+		if !p.empty() && p.peek() == '(' {
+			displayName, err = p.consumeDisplayNameComment()
+			if err != nil {
+				return nil, err
+			}
+		}
+
+		return []*Address{{
+			Name:    displayName,
 			Address: spec,
-		}, err
+		}}, err
 	}
 	debug.Printf("parseAddress: not an addr-spec: %v", err)
 	debug.Printf("parseAddress: state is now %q", p.s)
@@ -309,8 +330,13 @@
 	}
 	debug.Printf("parseAddress: displayName=%q", displayName)
 
-	// angle-addr = "<" addr-spec ">"
 	p.skipSpace()
+	if handleGroup {
+		if p.consume(':') {
+			return p.consumeGroupList()
+		}
+	}
+	// angle-addr = "<" addr-spec ">"
 	if !p.consume('<') {
 		return nil, errors.New("mail: no angle-addr")
 	}
@@ -323,10 +349,42 @@
 	}
 	debug.Printf("parseAddress: spec=%q", spec)
 
-	return &Address{
+	return []*Address{{
 		Name:    displayName,
 		Address: spec,
-	}, nil
+	}}, nil
+}
+
+func (p *addrParser) consumeGroupList() ([]*Address, error) {
+	var group []*Address
+	// handle empty group.
+	p.skipSpace()
+	if p.consume(';') {
+		p.skipCFWS()
+		return group, nil
+	}
+
+	for {
+		p.skipSpace()
+		// embedded groups not allowed.
+		addrs, err := p.parseAddress(false)
+		if err != nil {
+			return nil, err
+		}
+		group = append(group, addrs...)
+
+		if !p.skipCFWS() {
+			return nil, errors.New("mail: misformatted parenthetical comment")
+		}
+		if p.consume(';') {
+			p.skipCFWS()
+			break
+		}
+		if !p.consume(',') {
+			return nil, errors.New("mail: expected comma")
+		}
+	}
+	return group, nil
 }
 
 // consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
@@ -482,20 +540,20 @@
 
 // consumeAtom parses an RFC 5322 atom at the start of p.
 // If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
-// If permissive is true, consumeAtom will not fail on
-// leading/trailing/double dots in the atom (see golang.org/issue/4938).
+// If permissive is true, consumeAtom will not fail on:
+// - leading/trailing/double dots in the atom (see golang.org/issue/4938)
+// - special characters (RFC 5322 3.2.3) except '<', '>', ':' and '"' (see golang.org/issue/21018)
 func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
 	i := 0
 
 Loop:
 	for {
 		r, size := utf8.DecodeRuneInString(p.s[i:])
-
 		switch {
 		case size == 1 && r == utf8.RuneError:
 			return "", fmt.Errorf("mail: invalid utf-8 in address: %q", p.s)
 
-		case size == 0 || !isAtext(r, dot):
+		case size == 0 || !isAtext(r, dot, permissive):
 			break Loop
 
 		default:
@@ -522,6 +580,30 @@
 	return atom, nil
 }
 
+func (p *addrParser) consumeDisplayNameComment() (string, error) {
+	if !p.consume('(') {
+		return "", errors.New("mail: comment does not start with (")
+	}
+	comment, ok := p.consumeComment()
+	if !ok {
+		return "", errors.New("mail: misformatted parenthetical comment")
+	}
+
+	// TODO(stapelberg): parse quoted-string within comment
+	words := strings.FieldsFunc(comment, func(r rune) bool { return r == ' ' || r == '\t' })
+	for idx, word := range words {
+		decoded, isEncoded, err := p.decodeRFC2047Word(word)
+		if err != nil {
+			return "", err
+		}
+		if isEncoded {
+			words[idx] = decoded
+		}
+	}
+
+	return strings.Join(words, " "), nil
+}
+
 func (p *addrParser) consume(c byte) bool {
 	if p.empty() || p.peek() != c {
 		return false
@@ -547,6 +629,51 @@
 	return len(p.s)
 }
 
+// skipCFWS skips CFWS as defined in RFC5322.
+func (p *addrParser) skipCFWS() bool {
+	p.skipSpace()
+
+	for {
+		if !p.consume('(') {
+			break
+		}
+
+		if _, ok := p.consumeComment(); !ok {
+			return false
+		}
+
+		p.skipSpace()
+	}
+
+	return true
+}
+
+func (p *addrParser) consumeComment() (string, bool) {
+	// '(' already consumed.
+	depth := 1
+
+	var comment string
+	for {
+		if p.empty() || depth == 0 {
+			break
+		}
+
+		if p.peek() == '\\' && p.len() > 1 {
+			p.s = p.s[1:]
+		} else if p.peek() == '(' {
+			depth++
+		} else if p.peek() == ')' {
+			depth--
+		}
+		if depth > 0 {
+			comment += p.s[:1]
+		}
+		p.s = p.s[1:]
+	}
+
+	return comment, depth == 0
+}
+
 func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
 	if p.dec != nil {
 		word, err = p.dec.Decode(s)
@@ -580,12 +707,18 @@
 
 // isAtext reports whether r is an RFC 5322 atext character.
 // If dot is true, period is included.
-func isAtext(r rune, dot bool) bool {
+// If permissive is true, RFC 5322 3.2.3 specials is included,
+// except '<', '>', ':' and '"'.
+func isAtext(r rune, dot, permissive bool) bool {
 	switch r {
 	case '.':
 		return dot
 
-	case '(', ')', '<', '>', '[', ']', ':', ';', '@', '\\', ',', '"': // RFC 5322 3.2.3. specials
+	// RFC 5322 3.2.3. specials
+	case '(', ')', '[', ']', ';', '@', '\\', ',':
+		return permissive
+
+	case '<', '>', '"', ':':
 		return false
 	}
 	return isVchar(r)
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
index 2106a0b..b19da52 100644
--- a/src/net/mail/message_test.go
+++ b/src/net/mail/message_test.go
@@ -129,14 +129,21 @@
 		text        string
 		wantErrText string
 	}{
-		0: {"=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown@gmail.com>", "charset not supported"},
-		1: {"a@gmail.com b@gmail.com", "expected single address"},
-		2: {string([]byte{0xed, 0xa0, 0x80}) + " <micro@example.net>", "invalid utf-8 in address"},
-		3: {"\"" + string([]byte{0xed, 0xa0, 0x80}) + "\" <half-surrogate@example.com>", "invalid utf-8 in quoted-string"},
-		4: {"\"\\" + string([]byte{0x80}) + "\" <escaped-invalid-unicode@example.net>", "invalid utf-8 in quoted-string"},
-		5: {"\"\x00\" <null@example.net>", "bad character in quoted-string"},
-		6: {"\"\\\x00\" <escaped-null@example.net>", "bad character in quoted-string"},
-		7: {"John Doe", "no angle-addr"},
+		0:  {"=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown@gmail.com>", "charset not supported"},
+		1:  {"a@gmail.com b@gmail.com", "expected single address"},
+		2:  {string([]byte{0xed, 0xa0, 0x80}) + " <micro@example.net>", "invalid utf-8 in address"},
+		3:  {"\"" + string([]byte{0xed, 0xa0, 0x80}) + "\" <half-surrogate@example.com>", "invalid utf-8 in quoted-string"},
+		4:  {"\"\\" + string([]byte{0x80}) + "\" <escaped-invalid-unicode@example.net>", "invalid utf-8 in quoted-string"},
+		5:  {"\"\x00\" <null@example.net>", "bad character in quoted-string"},
+		6:  {"\"\\\x00\" <escaped-null@example.net>", "bad character in quoted-string"},
+		7:  {"John Doe", "no angle-addr"},
+		8:  {`<jdoe#machine.example>`, "missing @ in addr-spec"},
+		9:  {`John <middle> Doe <jdoe@machine.example>`, "missing @ in addr-spec"},
+		10: {"cfws@example.com (", "misformatted parenthetical comment"},
+		11: {"empty group: ;", "empty group"},
+		12: {"root group: embed group: null@example.com;", "no angle-addr"},
+		13: {"group not closed: null@example.com", "expected comma"},
+		14: {"group: first@example.com, second@example.com;", "group with multiple addresses"},
 	}
 
 	for i, tc := range mustErrTestCases {
@@ -176,6 +183,34 @@
 			}},
 		},
 		{
+			`"John (middle) Doe" <jdoe@machine.example>`,
+			[]*Address{{
+				Name:    "John (middle) Doe",
+				Address: "jdoe@machine.example",
+			}},
+		},
+		{
+			`John (middle) Doe <jdoe@machine.example>`,
+			[]*Address{{
+				Name:    "John (middle) Doe",
+				Address: "jdoe@machine.example",
+			}},
+		},
+		{
+			`John !@M@! Doe <jdoe@machine.example>`,
+			[]*Address{{
+				Name:    "John !@M@! Doe",
+				Address: "jdoe@machine.example",
+			}},
+		},
+		{
+			`"John <middle> Doe" <jdoe@machine.example>`,
+			[]*Address{{
+				Name:    "John <middle> Doe",
+				Address: "jdoe@machine.example",
+			}},
+		},
+		{
 			`Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
 			[]*Address{
 				{
@@ -203,9 +238,62 @@
 				},
 			},
 		},
+		// RFC 5322, Appendix A.6.1
+		{
+			`Joe Q. Public <john.q.public@example.com>`,
+			[]*Address{{
+				Name:    "Joe Q. Public",
+				Address: "john.q.public@example.com",
+			}},
+		},
 		// RFC 5322, Appendix A.1.3
-		// TODO(dsymonds): Group addresses.
-
+		{
+			`group1: groupaddr1@example.com;`,
+			[]*Address{
+				{
+					Name:    "",
+					Address: "groupaddr1@example.com",
+				},
+			},
+		},
+		{
+			`empty group: ;`,
+			[]*Address(nil),
+		},
+		{
+			`A Group:Ed Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;`,
+			[]*Address{
+				{
+					Name:    "Ed Jones",
+					Address: "c@a.test",
+				},
+				{
+					Name:    "",
+					Address: "joe@where.test",
+				},
+				{
+					Name:    "John",
+					Address: "jdoe@one.test",
+				},
+			},
+		},
+		{
+			`Group1: <addr1@example.com>;, Group 2: addr2@example.com;, John <addr3@example.com>`,
+			[]*Address{
+				{
+					Name:    "",
+					Address: "addr1@example.com",
+				},
+				{
+					Name:    "",
+					Address: "addr2@example.com",
+				},
+				{
+					Name:    "John",
+					Address: "addr3@example.com",
+				},
+			},
+		},
 		// RFC 2047 "Q"-encoded ISO-8859-1 address.
 		{
 			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`,
@@ -336,6 +424,89 @@
 				},
 			},
 		},
+		// CFWS
+		{
+			`<cfws@example.com> (CFWS (cfws))  (another comment)`,
+			[]*Address{
+				{
+					Name:    "",
+					Address: "cfws@example.com",
+				},
+			},
+		},
+		{
+			`<cfws@example.com> ()  (another comment), <cfws2@example.com> (another)`,
+			[]*Address{
+				{
+					Name:    "",
+					Address: "cfws@example.com",
+				},
+				{
+					Name:    "",
+					Address: "cfws2@example.com",
+				},
+			},
+		},
+		// Comment as display name
+		{
+			`john@example.com (John Doe)`,
+			[]*Address{
+				{
+					Name:    "John Doe",
+					Address: "john@example.com",
+				},
+			},
+		},
+		// Comment and display name
+		{
+			`John Doe <john@example.com> (Joey)`,
+			[]*Address{
+				{
+					Name:    "John Doe",
+					Address: "john@example.com",
+				},
+			},
+		},
+		// Comment as display name, no space
+		{
+			`john@example.com(John Doe)`,
+			[]*Address{
+				{
+					Name:    "John Doe",
+					Address: "john@example.com",
+				},
+			},
+		},
+		// Comment as display name, Q-encoded
+		{
+			`asjo@example.com (Adam =?utf-8?Q?Sj=C3=B8gren?=)`,
+			[]*Address{
+				{
+					Name:    "Adam Sjøgren",
+					Address: "asjo@example.com",
+				},
+			},
+		},
+		// Comment as display name, Q-encoded and tab-separated
+		{
+			`asjo@example.com (Adam	=?utf-8?Q?Sj=C3=B8gren?=)`,
+			[]*Address{
+				{
+					Name:    "Adam Sjøgren",
+					Address: "asjo@example.com",
+				},
+			},
+		},
+		// Nested comment as display name, Q-encoded
+		{
+			`asjo@example.com (Adam =?utf-8?Q?Sj=C3=B8gren?= (Debian))`,
+			[]*Address{
+				{
+					Name:    "Adam Sjøgren (Debian)",
+					Address: "asjo@example.com",
+				},
+			},
+		},
 	}
 	for _, test := range tests {
 		if len(test.exp) == 1 {
diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go
index f38a3a0..07f21b7 100644
--- a/src/net/main_windows_test.go
+++ b/src/net/main_windows_test.go
@@ -9,6 +9,7 @@
 var (
 	// Placeholders for saving original socket system calls.
 	origSocket      = socketFunc
+	origWSASocket   = wsaSocketFunc
 	origClosesocket = poll.CloseFunc
 	origConnect     = connectFunc
 	origConnectEx   = poll.ConnectExFunc
@@ -18,6 +19,7 @@
 
 func installTestHooks() {
 	socketFunc = sw.Socket
+	wsaSocketFunc = sw.WSASocket
 	poll.CloseFunc = sw.Closesocket
 	connectFunc = sw.Connect
 	poll.ConnectExFunc = sw.ConnectEx
@@ -27,6 +29,7 @@
 
 func uninstallTestHooks() {
 	socketFunc = origSocket
+	wsaSocketFunc = origWSASocket
 	poll.CloseFunc = origClosesocket
 	connectFunc = origConnect
 	poll.ConnectExFunc = origConnectEx
diff --git a/src/net/net.go b/src/net/net.go
index 91ec048..3ad9103 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -288,6 +288,8 @@
 // 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.
+//
+// On Unix systems this will cause the SetDeadline methods to stop working.
 func (c *conn) File() (f *os.File, err error) {
 	f, err = c.fd.dup()
 	if err != nil {
diff --git a/src/net/net_windows_test.go b/src/net/net_windows_test.go
index 0441612..db211e9 100644
--- a/src/net/net_windows_test.go
+++ b/src/net/net_windows_test.go
@@ -608,15 +608,34 @@
 	}
 	processGroup()
 
+	dups := make(map[string][]string)
+	for name, addr := range want {
+		if _, ok := dups[addr]; !ok {
+			dups[addr] = make([]string, 0)
+		}
+		dups[addr] = append(dups[addr], name)
+	}
+
+nextWant:
 	for name, wantAddr := range want {
-		haveAddr, ok := have[name]
-		if !ok {
-			t.Errorf("getmac lists %q, but it could not be found among Go interfaces %v", name, have)
+		if haveAddr, ok := have[name]; ok {
+			if haveAddr != wantAddr {
+				t.Errorf("unexpected MAC address for %q - %v, want %v", name, haveAddr, wantAddr)
+			}
 			continue
 		}
-		if haveAddr != wantAddr {
-			t.Errorf("unexpected MAC address for %q - %v, want %v", name, haveAddr, wantAddr)
-			continue
+		// We could not find the interface in getmac output by name.
+		// But sometimes getmac lists many interface names
+		// for the same MAC address. If that is the case here,
+		// and we can match at least one of those names,
+		// let's ignore the other names.
+		if dupNames, ok := dups[wantAddr]; ok && len(dupNames) > 1 {
+			for _, dupName := range dupNames {
+				if haveAddr, ok := have[dupName]; ok && haveAddr == wantAddr {
+					continue nextWant
+				}
+			}
 		}
+		t.Errorf("getmac lists %q, but it could not be found among Go interfaces %v", name, have)
 	}
 }
diff --git a/src/net/netgo_unix_test.go b/src/net/netgo_unix_test.go
index 47901b0..f2244ea 100644
--- a/src/net/netgo_unix_test.go
+++ b/src/net/netgo_unix_test.go
@@ -13,6 +13,7 @@
 )
 
 func TestGoLookupIP(t *testing.T) {
+	defer dnsWaitGroup.Wait()
 	host := "localhost"
 	ctx := context.Background()
 	_, err, ok := cgoLookupIP(ctx, host)
diff --git a/src/net/parse.go b/src/net/parse.go
index 5826984..e356cb1 100644
--- a/src/net/parse.go
+++ b/src/net/parse.go
@@ -69,7 +69,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return &file{fd, make([]byte, 0, os.Getpagesize()), false}, nil
+	return &file{fd, make([]byte, 0, 64*1024), false}, nil
 }
 
 func stat(name string) (mtime time.Time, size int64, err error) {
diff --git a/src/net/pipe.go b/src/net/pipe.go
index 37e552f..9177fc4 100644
--- a/src/net/pipe.go
+++ b/src/net/pipe.go
@@ -5,63 +5,239 @@
 package net
 
 import (
-	"errors"
 	"io"
+	"sync"
 	"time"
 )
 
+// pipeDeadline is an abstraction for handling timeouts.
+type pipeDeadline struct {
+	mu     sync.Mutex // Guards timer and cancel
+	timer  *time.Timer
+	cancel chan struct{} // Must be non-nil
+}
+
+func makePipeDeadline() pipeDeadline {
+	return pipeDeadline{cancel: make(chan struct{})}
+}
+
+// set sets the point in time when the deadline will time out.
+// A timeout event is signaled by closing the channel returned by waiter.
+// Once a timeout has occurred, the deadline can be refreshed by specifying a
+// t value in the future.
+//
+// A zero value for t prevents timeout.
+func (d *pipeDeadline) set(t time.Time) {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+
+	if d.timer != nil && !d.timer.Stop() {
+		<-d.cancel // Wait for the timer callback to finish and close cancel
+	}
+	d.timer = nil
+
+	// Time is zero, then there is no deadline.
+	closed := isClosedChan(d.cancel)
+	if t.IsZero() {
+		if closed {
+			d.cancel = make(chan struct{})
+		}
+		return
+	}
+
+	// Time in the future, setup a timer to cancel in the future.
+	if dur := time.Until(t); dur > 0 {
+		if closed {
+			d.cancel = make(chan struct{})
+		}
+		d.timer = time.AfterFunc(dur, func() {
+			close(d.cancel)
+		})
+		return
+	}
+
+	// Time in the past, so close immediately.
+	if !closed {
+		close(d.cancel)
+	}
+}
+
+// wait returns a channel that is closed when the deadline is exceeded.
+func (d *pipeDeadline) wait() chan struct{} {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+	return d.cancel
+}
+
+func isClosedChan(c <-chan struct{}) bool {
+	select {
+	case <-c:
+		return true
+	default:
+		return false
+	}
+}
+
+type timeoutError struct{}
+
+func (timeoutError) Error() string   { return "deadline exceeded" }
+func (timeoutError) Timeout() bool   { return true }
+func (timeoutError) Temporary() bool { return true }
+
+type pipeAddr struct{}
+
+func (pipeAddr) Network() string { return "pipe" }
+func (pipeAddr) String() string  { return "pipe" }
+
+type pipe struct {
+	wrMu sync.Mutex // Serialize Write operations
+
+	// Used by local Read to interact with remote Write.
+	// Successful receive on rdRx is always followed by send on rdTx.
+	rdRx <-chan []byte
+	rdTx chan<- int
+
+	// Used by local Write to interact with remote Read.
+	// Successful send on wrTx is always followed by receive on wrRx.
+	wrTx chan<- []byte
+	wrRx <-chan int
+
+	once       sync.Once // Protects closing localDone
+	localDone  chan struct{}
+	remoteDone <-chan struct{}
+
+	readDeadline  pipeDeadline
+	writeDeadline pipeDeadline
+}
+
 // Pipe creates a synchronous, in-memory, full duplex
 // network connection; both ends implement the Conn interface.
 // Reads on one end are matched with writes on the other,
 // copying data directly between the two; there is no internal
 // buffering.
 func Pipe() (Conn, Conn) {
-	r1, w1 := io.Pipe()
-	r2, w2 := io.Pipe()
+	cb1 := make(chan []byte)
+	cb2 := make(chan []byte)
+	cn1 := make(chan int)
+	cn2 := make(chan int)
+	done1 := make(chan struct{})
+	done2 := make(chan struct{})
 
-	return &pipe{r1, w2}, &pipe{r2, w1}
-}
-
-type pipe struct {
-	*io.PipeReader
-	*io.PipeWriter
-}
-
-type pipeAddr int
-
-func (pipeAddr) Network() string {
-	return "pipe"
-}
-
-func (pipeAddr) String() string {
-	return "pipe"
-}
-
-func (p *pipe) Close() error {
-	err := p.PipeReader.Close()
-	err1 := p.PipeWriter.Close()
-	if err == nil {
-		err = err1
+	p1 := &pipe{
+		rdRx: cb1, rdTx: cn1,
+		wrTx: cb2, wrRx: cn2,
+		localDone: done1, remoteDone: done2,
+		readDeadline:  makePipeDeadline(),
+		writeDeadline: makePipeDeadline(),
 	}
-	return err
+	p2 := &pipe{
+		rdRx: cb2, rdTx: cn2,
+		wrTx: cb1, wrRx: cn1,
+		localDone: done2, remoteDone: done1,
+		readDeadline:  makePipeDeadline(),
+		writeDeadline: makePipeDeadline(),
+	}
+	return p1, p2
 }
 
-func (p *pipe) LocalAddr() Addr {
-	return pipeAddr(0)
+func (*pipe) LocalAddr() Addr  { return pipeAddr{} }
+func (*pipe) RemoteAddr() Addr { return pipeAddr{} }
+
+func (p *pipe) Read(b []byte) (int, error) {
+	n, err := p.read(b)
+	if err != nil && err != io.EOF && err != io.ErrClosedPipe {
+		err = &OpError{Op: "read", Net: "pipe", Err: err}
+	}
+	return n, err
 }
 
-func (p *pipe) RemoteAddr() Addr {
-	return pipeAddr(0)
+func (p *pipe) read(b []byte) (n int, err error) {
+	switch {
+	case isClosedChan(p.localDone):
+		return 0, io.ErrClosedPipe
+	case isClosedChan(p.remoteDone):
+		return 0, io.EOF
+	case isClosedChan(p.readDeadline.wait()):
+		return 0, timeoutError{}
+	}
+
+	select {
+	case bw := <-p.rdRx:
+		nr := copy(b, bw)
+		p.rdTx <- nr
+		return nr, nil
+	case <-p.localDone:
+		return 0, io.ErrClosedPipe
+	case <-p.remoteDone:
+		return 0, io.EOF
+	case <-p.readDeadline.wait():
+		return 0, timeoutError{}
+	}
+}
+
+func (p *pipe) Write(b []byte) (int, error) {
+	n, err := p.write(b)
+	if err != nil && err != io.ErrClosedPipe {
+		err = &OpError{Op: "write", Net: "pipe", Err: err}
+	}
+	return n, err
+}
+
+func (p *pipe) write(b []byte) (n int, err error) {
+	switch {
+	case isClosedChan(p.localDone):
+		return 0, io.ErrClosedPipe
+	case isClosedChan(p.remoteDone):
+		return 0, io.ErrClosedPipe
+	case isClosedChan(p.writeDeadline.wait()):
+		return 0, timeoutError{}
+	}
+
+	p.wrMu.Lock() // Ensure entirety of b is written together
+	defer p.wrMu.Unlock()
+	for once := true; once || len(b) > 0; once = false {
+		select {
+		case p.wrTx <- b:
+			nw := <-p.wrRx
+			b = b[nw:]
+			n += nw
+		case <-p.localDone:
+			return n, io.ErrClosedPipe
+		case <-p.remoteDone:
+			return n, io.ErrClosedPipe
+		case <-p.writeDeadline.wait():
+			return n, timeoutError{}
+		}
+	}
+	return n, nil
 }
 
 func (p *pipe) SetDeadline(t time.Time) error {
-	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
+	if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
+		return io.ErrClosedPipe
+	}
+	p.readDeadline.set(t)
+	p.writeDeadline.set(t)
+	return nil
 }
 
 func (p *pipe) SetReadDeadline(t time.Time) error {
-	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
+	if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
+		return io.ErrClosedPipe
+	}
+	p.readDeadline.set(t)
+	return nil
 }
 
 func (p *pipe) SetWriteDeadline(t time.Time) error {
-	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
+	if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
+		return io.ErrClosedPipe
+	}
+	p.writeDeadline.set(t)
+	return nil
+}
+
+func (p *pipe) Close() error {
+	p.once.Do(func() { close(p.localDone) })
+	return nil
 }
diff --git a/src/net/pipe_test.go b/src/net/pipe_test.go
index e3172d8..84a71b7 100644
--- a/src/net/pipe_test.go
+++ b/src/net/pipe_test.go
@@ -2,54 +2,48 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package net
+package net_test
 
 import (
-	"bytes"
 	"io"
+	"net"
 	"testing"
+	"time"
+
+	"golang_org/x/net/nettest"
 )
 
-func checkPipeWrite(t *testing.T, w io.Writer, data []byte, c chan int) {
-	n, err := w.Write(data)
-	if err != nil {
-		t.Error(err)
-	}
-	if n != len(data) {
-		t.Errorf("short write: %d != %d", n, len(data))
-	}
-	c <- 0
-}
-
-func checkPipeRead(t *testing.T, r io.Reader, data []byte, wantErr error) {
-	buf := make([]byte, len(data)+10)
-	n, err := r.Read(buf)
-	if err != wantErr {
-		t.Error(err)
-		return
-	}
-	if n != len(data) || !bytes.Equal(buf[0:n], data) {
-		t.Errorf("bad read: got %q", buf[0:n])
-		return
-	}
-}
-
-// TestPipe tests a simple read/write/close sequence.
-// Assumes that the underlying io.Pipe implementation
-// is solid and we're just testing the net wrapping.
 func TestPipe(t *testing.T) {
-	c := make(chan int)
-	cli, srv := Pipe()
-	go checkPipeWrite(t, cli, []byte("hello, world"), c)
-	checkPipeRead(t, srv, []byte("hello, world"), nil)
-	<-c
-	go checkPipeWrite(t, srv, []byte("line 2"), c)
-	checkPipeRead(t, cli, []byte("line 2"), nil)
-	<-c
-	go checkPipeWrite(t, cli, []byte("a third line"), c)
-	checkPipeRead(t, srv, []byte("a third line"), nil)
-	<-c
-	go srv.Close()
-	checkPipeRead(t, cli, nil, io.EOF)
-	cli.Close()
+	nettest.TestConn(t, func() (c1, c2 net.Conn, stop func(), err error) {
+		c1, c2 = net.Pipe()
+		stop = func() {
+			c1.Close()
+			c2.Close()
+		}
+		return
+	})
+}
+
+func TestPipeCloseError(t *testing.T) {
+	c1, c2 := net.Pipe()
+	c1.Close()
+
+	if _, err := c1.Read(nil); err != io.ErrClosedPipe {
+		t.Errorf("c1.Read() = %v, want io.ErrClosedPipe", err)
+	}
+	if _, err := c1.Write(nil); err != io.ErrClosedPipe {
+		t.Errorf("c1.Write() = %v, want io.ErrClosedPipe", err)
+	}
+	if err := c1.SetDeadline(time.Time{}); err != io.ErrClosedPipe {
+		t.Errorf("c1.SetDeadline() = %v, want io.ErrClosedPipe", err)
+	}
+	if _, err := c2.Read(nil); err != io.EOF {
+		t.Errorf("c2.Read() = %v, want io.EOF", err)
+	}
+	if _, err := c2.Write(nil); err != io.ErrClosedPipe {
+		t.Errorf("c2.Write() = %v, want io.ErrClosedPipe", err)
+	}
+	if err := c2.SetDeadline(time.Time{}); err != io.ErrClosedPipe {
+		t.Errorf("c2.SetDeadline() = %v, want io.ErrClosedPipe", err)
+	}
 }
diff --git a/src/net/platform_test.go b/src/net/platform_test.go
index 5841ca3..8e7d915 100644
--- a/src/net/platform_test.go
+++ b/src/net/platform_test.go
@@ -43,9 +43,12 @@
 	case "unixpacket":
 		switch runtime.GOOS {
 		case "android", "darwin", "nacl", "plan9", "windows":
-			fallthrough
-		case "freebsd": // FreeBSD 8 and below don't support unixpacket
 			return false
+		case "netbsd":
+			// It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown.
+			if runtime.GOARCH == "386" {
+				return false
+			}
 		}
 	}
 	switch ss[0] {
@@ -149,12 +152,19 @@
 	return true
 }
 
-var condFatalf = func() func(*testing.T, string, ...interface{}) {
-	// A few APIs, File, Read/WriteMsg{UDP,IP}, are not
-	// implemented yet on both Plan 9 and Windows.
+func condFatalf(t *testing.T, network string, format string, args ...interface{}) {
+	t.Helper()
+	// A few APIs like File and Read/WriteMsg{UDP,IP} are not
+	// fully implemented yet on Plan 9 and Windows.
 	switch runtime.GOOS {
-	case "plan9", "windows":
-		return (*testing.T).Logf
+	case "windows":
+		if network == "file+net" {
+			t.Logf(format, args...)
+			return
+		}
+	case "plan9":
+		t.Logf(format, args...)
+		return
 	}
-	return (*testing.T).Fatalf
-}()
+	t.Fatalf(format, args...)
+}
diff --git a/src/net/port.go b/src/net/port.go
index 8e1321a..32e7628 100644
--- a/src/net/port.go
+++ b/src/net/port.go
@@ -4,12 +4,12 @@
 
 package net
 
-// parsePort parses service as a decimal interger and returns the
+// parsePort parses service as a decimal integer and returns the
 // corresponding value as port. It is the caller's responsibility to
 // parse service as a non-decimal integer when needsLookup is true.
 //
 // Some system resolvers will return a valid port number when given a number
-// over 65536 (see https://github.com/golang/go/issues/11715). Alas, the parser
+// over 65536 (see https://golang.org/issues/11715). Alas, the parser
 // can't bail early on numbers > 65536. Therefore reasonably large/small
 // numbers are parsed in full and rejected if invalid.
 func parsePort(service string) (port int, needsLookup bool) {
diff --git a/src/net/protoconn_test.go b/src/net/protoconn_test.go
index 23589d3..def8d65 100644
--- a/src/net/protoconn_test.go
+++ b/src/net/protoconn_test.go
@@ -8,6 +8,7 @@
 package net
 
 import (
+	"internal/testenv"
 	"os"
 	"runtime"
 	"testing"
@@ -54,7 +55,7 @@
 	}
 
 	if f, err := ln.File(); err != nil {
-		condFatalf(t, "%v", err)
+		condFatalf(t, "file+net", "%v", err)
 	} else {
 		f.Close()
 	}
@@ -138,15 +139,19 @@
 	if _, _, err := c.ReadFromUDP(rb); err != nil {
 		t.Fatal(err)
 	}
-	if _, _, err := c.WriteMsgUDP(wb, nil, c.LocalAddr().(*UDPAddr)); err != nil {
-		condFatalf(t, "%v", err)
-	}
-	if _, _, _, _, err := c.ReadMsgUDP(rb, nil); err != nil {
-		condFatalf(t, "%v", err)
+	if testenv.IsWindowsXP() {
+		t.Log("skipping broken test on Windows XP (see golang.org/issue/23072)")
+	} else {
+		if _, _, err := c.WriteMsgUDP(wb, nil, c.LocalAddr().(*UDPAddr)); err != nil {
+			condFatalf(t, c.LocalAddr().Network(), "%v", err)
+		}
+		if _, _, _, _, err := c.ReadMsgUDP(rb, nil); err != nil {
+			condFatalf(t, c.LocalAddr().Network(), "%v", err)
+		}
 	}
 
 	if f, err := c.File(); err != nil {
-		condFatalf(t, "%v", err)
+		condFatalf(t, "file+net", "%v", err)
 	} else {
 		f.Close()
 	}
@@ -184,7 +189,7 @@
 	c.SetWriteBuffer(2048)
 
 	if f, err := c.File(); err != nil {
-		condFatalf(t, "%v", err)
+		condFatalf(t, "file+net", "%v", err)
 	} else {
 		f.Close()
 	}
diff --git a/src/net/rawconn.go b/src/net/rawconn.go
index d67be64..2399c9f 100644
--- a/src/net/rawconn.go
+++ b/src/net/rawconn.go
@@ -60,3 +60,19 @@
 func newRawConn(fd *netFD) (*rawConn, error) {
 	return &rawConn{fd: fd}, nil
 }
+
+type rawListener struct {
+	rawConn
+}
+
+func (l *rawListener) Read(func(uintptr) bool) error {
+	return syscall.EINVAL
+}
+
+func (l *rawListener) Write(func(uintptr) bool) error {
+	return syscall.EINVAL
+}
+
+func newRawListener(fd *netFD) (*rawListener, error) {
+	return &rawListener{rawConn{fd: fd}}, nil
+}
diff --git a/src/net/rawconn_unix_test.go b/src/net/rawconn_unix_test.go
index 294249b..913ad86 100644
--- a/src/net/rawconn_unix_test.go
+++ b/src/net/rawconn_unix_test.go
@@ -92,3 +92,53 @@
 		t.Fatal("should fail")
 	}
 }
+
+func TestRawConnListener(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	cc, err := ln.(*TCPListener).SyscallConn()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	called := false
+	op := func(uintptr) bool {
+		called = true
+		return true
+	}
+
+	err = cc.Write(op)
+	if err == nil {
+		t.Error("Write should return an error")
+	}
+	if called {
+		t.Error("Write shouldn't call op")
+	}
+
+	called = false
+	err = cc.Read(op)
+	if err == nil {
+		t.Error("Read should return an error")
+	}
+	if called {
+		t.Error("Read shouldn't call op")
+	}
+
+	var operr error
+	fn := func(s uintptr) {
+		_, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR)
+	}
+	err = cc.Control(fn)
+	if err != nil || operr != nil {
+		t.Fatal(err, operr)
+	}
+	ln.Close()
+	err = cc.Control(fn)
+	if err == nil {
+		t.Fatal("Control after Close should fail")
+	}
+}
diff --git a/src/net/rawconn_windows_test.go b/src/net/rawconn_windows_test.go
index 5fb6de7..2ee12c3 100644
--- a/src/net/rawconn_windows_test.go
+++ b/src/net/rawconn_windows_test.go
@@ -7,6 +7,7 @@
 import (
 	"syscall"
 	"testing"
+	"unsafe"
 )
 
 func TestRawConn(t *testing.T) {
@@ -34,3 +35,55 @@
 		t.Fatal("should fail")
 	}
 }
+
+func TestRawConnListener(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	cc, err := ln.(*TCPListener).SyscallConn()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	called := false
+	op := func(uintptr) bool {
+		called = true
+		return true
+	}
+
+	err = cc.Write(op)
+	if err == nil {
+		t.Error("Write should return an error")
+	}
+	if called {
+		t.Error("Write shouldn't call op")
+	}
+
+	called = false
+	err = cc.Read(op)
+	if err == nil {
+		t.Error("Read should return an error")
+	}
+	if called {
+		t.Error("Read shouldn't call op")
+	}
+
+	var operr error
+	fn := func(s uintptr) {
+		var v, l int32
+		l = int32(unsafe.Sizeof(v))
+		operr = syscall.Getsockopt(syscall.Handle(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, (*byte)(unsafe.Pointer(&v)), &l)
+	}
+	err = cc.Control(fn)
+	if err != nil || operr != nil {
+		t.Fatal(err, operr)
+	}
+	ln.Close()
+	err = cc.Control(fn)
+	if err == nil {
+		t.Fatal("Control after Close should fail")
+	}
+}
diff --git a/src/net/rpc/server.go b/src/net/rpc/server.go
index 29aae7e..96e6973 100644
--- a/src/net/rpc/server.go
+++ b/src/net/rpc/server.go
@@ -296,7 +296,7 @@
 		// Method needs three ins: receiver, *args, *reply.
 		if mtype.NumIn() != 3 {
 			if reportErr {
-				log.Println("method", mname, "has wrong number of ins:", mtype.NumIn())
+				log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
 			}
 			continue
 		}
@@ -304,7 +304,7 @@
 		argType := mtype.In(1)
 		if !isExportedOrBuiltinType(argType) {
 			if reportErr {
-				log.Println(mname, "argument type not exported:", argType)
+				log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
 			}
 			continue
 		}
@@ -312,28 +312,28 @@
 		replyType := mtype.In(2)
 		if replyType.Kind() != reflect.Ptr {
 			if reportErr {
-				log.Println("method", mname, "reply type not a pointer:", replyType)
+				log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
 			}
 			continue
 		}
 		// Reply type must be exported.
 		if !isExportedOrBuiltinType(replyType) {
 			if reportErr {
-				log.Println("method", mname, "reply type not exported:", replyType)
+				log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
 			}
 			continue
 		}
 		// Method needs one out.
 		if mtype.NumOut() != 1 {
 			if reportErr {
-				log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
+				log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, 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")
+				log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
 			}
 			continue
 		}
@@ -372,7 +372,10 @@
 	return n
 }
 
-func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+	if wg != nil {
+		defer wg.Done()
+	}
 	mtype.Lock()
 	mtype.numCalls++
 	mtype.Unlock()
@@ -456,6 +459,7 @@
 // decode requests and encode responses.
 func (server *Server) ServeCodec(codec ServerCodec) {
 	sending := new(sync.Mutex)
+	wg := new(sync.WaitGroup)
 	for {
 		service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
 		if err != nil {
@@ -472,8 +476,12 @@
 			}
 			continue
 		}
-		go service.call(server, sending, mtype, req, argv, replyv, codec)
+		wg.Add(1)
+		go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
 	}
+	// We've seen that there are no more requests.
+	// Wait for responses to be sent before closing codec.
+	wg.Wait()
 	codec.Close()
 }
 
@@ -493,7 +501,7 @@
 		}
 		return err
 	}
-	service.call(server, sending, mtype, req, argv, replyv, codec)
+	service.call(server, sending, nil, mtype, req, argv, replyv, codec)
 	return nil
 }
 
diff --git a/src/net/rpc/server_test.go b/src/net/rpc/server_test.go
index fb97f82..e5d7fe0 100644
--- a/src/net/rpc/server_test.go
+++ b/src/net/rpc/server_test.go
@@ -75,6 +75,11 @@
 	panic("ERROR")
 }
 
+func (t *Arith) SleepMilli(args *Args, reply *Reply) error {
+	time.Sleep(time.Duration(args.A) * time.Millisecond)
+	return nil
+}
+
 type hidden int
 
 func (t *hidden) Exported(args Args, reply *Reply) error {
@@ -693,6 +698,53 @@
 	newServer.Accept(l)
 }
 
+func TestShutdown(t *testing.T) {
+	var l net.Listener
+	l, _ = listenTCP()
+	ch := make(chan net.Conn, 1)
+	go func() {
+		defer l.Close()
+		c, err := l.Accept()
+		if err != nil {
+			t.Error(err)
+		}
+		ch <- c
+	}()
+	c, err := net.Dial("tcp", l.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	c1 := <-ch
+	if c1 == nil {
+		t.Fatal(err)
+	}
+
+	newServer := NewServer()
+	newServer.Register(new(Arith))
+	go newServer.ServeConn(c1)
+
+	args := &Args{7, 8}
+	reply := new(Reply)
+	client := NewClient(c)
+	err = client.Call("Arith.Add", args, reply)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// On an unloaded system 10ms is usually enough to fail 100% of the time
+	// with a broken server. On a loaded system, a broken server might incorrectly
+	// be reported as passing, but we're OK with that kind of flakiness.
+	// If the code is correct, this test will never fail, regardless of timeout.
+	args.A = 10 // 10 ms
+	done := make(chan *Call, 1)
+	call := client.Go("Arith.SleepMilli", args, reply, done)
+	c.(*net.TCPConn).CloseWrite()
+	<-done
+	if call.Error != nil {
+		t.Fatal(err)
+	}
+}
+
 func benchmarkEndToEnd(dial func() (*Client, error), b *testing.B) {
 	once.Do(startServer)
 	client, err := dial()
diff --git a/src/net/smtp/auth.go b/src/net/smtp/auth.go
index 3f1339e..fd1a472 100644
--- a/src/net/smtp/auth.go
+++ b/src/net/smtp/auth.go
@@ -44,26 +44,29 @@
 }
 
 // PlainAuth returns an Auth that implements the PLAIN authentication
-// mechanism as defined in RFC 4616.
-// The returned Auth uses the given username and password to authenticate
-// on TLS connections to host and act as identity. Usually identity will be
-// left blank to act as username.
+// mechanism as defined in RFC 4616. The returned Auth uses the given
+// username and password to authenticate to host and act as identity.
+// Usually identity should be the empty string, to act as username.
+//
+// PlainAuth will only send the credentials if the connection is using TLS
+// or is connected to localhost. Otherwise authentication will fail with an
+// error, without sending the credentials.
 func PlainAuth(identity, username, password, host string) Auth {
 	return &plainAuth{identity, username, password, host}
 }
 
+func isLocalhost(name string) bool {
+	return name == "localhost" || name == "127.0.0.1" || name == "::1"
+}
+
 func (a *plainAuth) Start(server *ServerInfo) (string, []byte, error) {
-	if !server.TLS {
-		advertised := false
-		for _, mechanism := range server.Auth {
-			if mechanism == "PLAIN" {
-				advertised = true
-				break
-			}
-		}
-		if !advertised {
-			return "", nil, errors.New("unencrypted connection")
-		}
+	// Must have TLS, or else localhost server.
+	// Note: If TLS is not true, then we can't trust ANYTHING in ServerInfo.
+	// In particular, it doesn't matter if the server advertises PLAIN auth.
+	// That might just be the attacker saying
+	// "it's ok, you can trust me with your password."
+	if !server.TLS && !isLocalhost(server.Name) {
+		return "", nil, errors.New("unencrypted connection")
 	}
 	if server.Name != a.host {
 		return "", nil, errors.New("wrong host name")
diff --git a/src/net/smtp/smtp.go b/src/net/smtp/smtp.go
index 28472e4..cf699e6 100644
--- a/src/net/smtp/smtp.go
+++ b/src/net/smtp/smtp.go
@@ -67,6 +67,7 @@
 		return nil, err
 	}
 	c := &Client{Text: text, conn: conn, serverName: host, localName: "localhost"}
+	_, c.tls = conn.(*tls.Conn)
 	return c, nil
 }
 
@@ -93,6 +94,9 @@
 // automatically otherwise. If Hello is called, it must be called before
 // any of the other methods.
 func (c *Client) Hello(localName string) error {
+	if err := validateLine(localName); err != nil {
+		return err
+	}
 	if c.didHello {
 		return errors.New("smtp: Hello called after other methods")
 	}
@@ -179,6 +183,9 @@
 // does not necessarily indicate an invalid address. Many servers
 // will not verify addresses for security reasons.
 func (c *Client) Verify(addr string) error {
+	if err := validateLine(addr); err != nil {
+		return err
+	}
 	if err := c.hello(); err != nil {
 		return err
 	}
@@ -237,6 +244,9 @@
 // parameter.
 // This initiates a mail transaction and is followed by one or more Rcpt calls.
 func (c *Client) Mail(from string) error {
+	if err := validateLine(from); err != nil {
+		return err
+	}
 	if err := c.hello(); err != nil {
 		return err
 	}
@@ -254,6 +264,9 @@
 // A call to Rcpt must be preceded by a call to Mail and may be followed by
 // a Data call or another Rcpt call.
 func (c *Client) Rcpt(to string) error {
+	if err := validateLine(to); err != nil {
+		return err
+	}
 	_, _, err := c.cmd(25, "RCPT TO:<%s>", to)
 	return err
 }
@@ -304,6 +317,14 @@
 // functionality. Higher-level packages exist outside of the standard
 // library.
 func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
+	if err := validateLine(from); err != nil {
+		return err
+	}
+	for _, recp := range to {
+		if err := validateLine(recp); err != nil {
+			return err
+		}
+	}
 	c, err := Dial(addr)
 	if err != nil {
 		return err
@@ -377,6 +398,16 @@
 	return err
 }
 
+// Noop sends the NOOP command to the server. It does nothing but check
+// that the connection to the server is okay.
+func (c *Client) Noop() error {
+	if err := c.hello(); err != nil {
+		return err
+	}
+	_, _, err := c.cmd(250, "NOOP")
+	return err
+}
+
 // Quit sends the QUIT command and closes the connection to the server.
 func (c *Client) Quit() error {
 	if err := c.hello(); err != nil {
@@ -388,3 +419,11 @@
 	}
 	return c.Text.Close()
 }
+
+// validateLine checks to see if a line has CR or LF as per RFC 5321
+func validateLine(line string) error {
+	if strings.ContainsAny(line, "\n\r") {
+		return errors.New("smtp: A line must not contain CR or LF")
+	}
+	return nil
+}
diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
index 9dbe3eb..d489922 100644
--- a/src/net/smtp/smtp_test.go
+++ b/src/net/smtp/smtp_test.go
@@ -62,29 +62,41 @@
 }
 
 func TestAuthPlain(t *testing.T) {
-	auth := PlainAuth("foo", "bar", "baz", "servername")
 
 	tests := []struct {
-		server *ServerInfo
-		err    string
+		authName string
+		server   *ServerInfo
+		err      string
 	}{
 		{
-			server: &ServerInfo{Name: "servername", TLS: true},
+			authName: "servername",
+			server:   &ServerInfo{Name: "servername", TLS: true},
 		},
 		{
-			// Okay; explicitly advertised by server.
-			server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
+			// OK to use PlainAuth on localhost without TLS
+			authName: "localhost",
+			server:   &ServerInfo{Name: "localhost", TLS: false},
 		},
 		{
-			server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
-			err:    "unencrypted connection",
+			// NOT OK on non-localhost, even if server says PLAIN is OK.
+			// (We don't know that the server is the real server.)
+			authName: "servername",
+			server:   &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
+			err:      "unencrypted connection",
 		},
 		{
-			server: &ServerInfo{Name: "attacker", TLS: true},
-			err:    "wrong host name",
+			authName: "servername",
+			server:   &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
+			err:      "unencrypted connection",
+		},
+		{
+			authName: "servername",
+			server:   &ServerInfo{Name: "attacker", TLS: true},
+			err:      "wrong host name",
 		},
 	}
 	for i, tt := range tests {
+		auth := PlainAuth("foo", "bar", "baz", tt.authName)
 		_, _, err := auth.Start(tt.server)
 		got := ""
 		if err != nil {
@@ -182,6 +194,9 @@
 	if err := c.Verify("user1@gmail.com"); err == nil {
 		t.Fatalf("First VRFY: expected no verification")
 	}
+	if err := c.Verify("user2@gmail.com>\r\nDATA\r\nAnother injected message body\r\n.\r\nQUIT\r\n"); err == nil {
+		t.Fatalf("VRFY should have failed due to a message injection attempt")
+	}
 	if err := c.Verify("user2@gmail.com"); err != nil {
 		t.Fatalf("Second VRFY: expected verification, got %s", err)
 	}
@@ -193,6 +208,12 @@
 		t.Fatalf("AUTH failed: %s", err)
 	}
 
+	if err := c.Rcpt("golang-nuts@googlegroups.com>\r\nDATA\r\nInjected message body\r\n.\r\nQUIT\r\n"); err == nil {
+		t.Fatalf("RCPT should have failed due to a message injection attempt")
+	}
+	if err := c.Mail("user@gmail.com>\r\nDATA\r\nAnother injected message body\r\n.\r\nQUIT\r\n"); err == nil {
+		t.Fatalf("MAIL should have failed due to a message injection attempt")
+	}
 	if err := c.Mail("user@gmail.com"); err != nil {
 		t.Fatalf("MAIL failed: %s", err)
 	}
@@ -352,6 +373,53 @@
 QUIT
 `
 
+func TestNewClientWithTLS(t *testing.T) {
+	cert, err := tls.X509KeyPair(localhostCert, localhostKey)
+	if err != nil {
+		t.Fatalf("loadcert: %v", err)
+	}
+
+	config := tls.Config{Certificates: []tls.Certificate{cert}}
+
+	ln, err := tls.Listen("tcp", "127.0.0.1:0", &config)
+	if err != nil {
+		ln, err = tls.Listen("tcp", "[::1]:0", &config)
+		if err != nil {
+			t.Fatalf("server: listen: %v", err)
+		}
+	}
+
+	go func() {
+		conn, err := ln.Accept()
+		if err != nil {
+			t.Errorf("server: accept: %v", err)
+			return
+		}
+		defer conn.Close()
+
+		_, err = conn.Write([]byte("220 SIGNS\r\n"))
+		if err != nil {
+			t.Errorf("server: write: %v", err)
+			return
+		}
+	}()
+
+	config.InsecureSkipVerify = true
+	conn, err := tls.Dial("tcp", ln.Addr().String(), &config)
+	if err != nil {
+		t.Fatalf("client: dial: %v", err)
+	}
+	defer conn.Close()
+
+	client, err := NewClient(conn, ln.Addr().String())
+	if err != nil {
+		t.Fatalf("smtp: newclient: %v", err)
+	}
+	if !client.tls {
+		t.Errorf("client.tls Got: %t Expected: %t", client.tls, true)
+	}
+}
+
 func TestHello(t *testing.T) {
 
 	if len(helloServer) != len(helloClient) {
@@ -375,6 +443,10 @@
 
 		switch i {
 		case 0:
+			err = c.Hello("hostinjection>\n\rDATA\r\nInjected message body\r\n.\r\nQUIT\r\n")
+			if err == nil {
+				t.Errorf("Expected Hello to be rejected due to a message injection attempt")
+			}
 			err = c.Hello("customhost")
 		case 1:
 			err = c.StartTLS(nil)
@@ -406,6 +478,8 @@
 					t.Errorf("Want error, got none")
 				}
 			}
+		case 9:
+			err = c.Noop()
 		default:
 			t.Fatalf("Unhandled command")
 		}
@@ -438,6 +512,7 @@
 	"250 Reset ok\n",
 	"221 Goodbye\n",
 	"250 Sender ok\n",
+	"250 ok\n",
 }
 
 var baseHelloClient = `EHLO customhost
@@ -454,6 +529,7 @@
 	"RSET\n",
 	"QUIT\n",
 	"VRFY test@example.com\n",
+	"NOOP\n",
 }
 
 func TestSendMail(t *testing.T) {
@@ -506,6 +582,16 @@
 		}
 	}(strings.Split(server, "\r\n"))
 
+	err = SendMail(l.Addr().String(), nil, "test@example.com", []string{"other@example.com>\n\rDATA\r\nInjected message body\r\n.\r\nQUIT\r\n"}, []byte(strings.Replace(`From: test@example.com
+To: other@example.com
+Subject: SendMail test
+
+SendMail is working for me.
+`, "\n", "\r\n", -1)))
+	if err == nil {
+		t.Errorf("Expected SendMail to be rejected due to a message injection attempt")
+	}
+
 	err = SendMail(l.Addr().String(), nil, "test@example.com", []string{"other@example.com"}, []byte(strings.Replace(`From: test@example.com
 To: other@example.com
 Subject: SendMail test
diff --git a/src/net/sock_bsd.go b/src/net/sock_bsd.go
index 4e0e9e0..516e557 100644
--- a/src/net/sock_bsd.go
+++ b/src/net/sock_bsd.go
@@ -17,8 +17,10 @@
 		err error
 	)
 	switch runtime.GOOS {
-	case "darwin", "freebsd":
+	case "darwin":
 		n, err = syscall.SysctlUint32("kern.ipc.somaxconn")
+	case "freebsd":
+		n, err = syscall.SysctlUint32("kern.ipc.soacceptqueue")
 	case "netbsd":
 		// NOTE: NetBSD has no somaxconn-like kernel state so far
 	case "openbsd":
diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go
index 89a3ca4..fa11c7a 100644
--- a/src/net/sock_windows.go
+++ b/src/net/sock_windows.go
@@ -5,6 +5,7 @@
 package net
 
 import (
+	"internal/syscall/windows"
 	"os"
 	"syscall"
 )
@@ -16,9 +17,19 @@
 }
 
 func sysSocket(family, sotype, proto int) (syscall.Handle, error) {
+	s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto),
+		nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT)
+	if err == nil {
+		return s, nil
+	}
+	// WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some
+	// old versions of Windows, see
+	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx
+	// for details. Just use syscall.Socket, if windows.WSASocket failed.
+
 	// See ../syscall/exec_unix.go for description of ForkLock.
 	syscall.ForkLock.RLock()
-	s, err := socketFunc(family, sotype, proto)
+	s, err = socketFunc(family, sotype, proto)
 	if err == nil {
 		syscall.CloseOnExec(s)
 	}
diff --git a/src/net/sockoptip_bsd.go b/src/net/sockoptip_bsd.go
deleted file mode 100644
index b11f3a4..0000000
--- a/src/net/sockoptip_bsd.go
+++ /dev/null
@@ -1,30 +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
-
-package net
-
-import (
-	"runtime"
-	"syscall"
-)
-
-func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
-	ip, err := interfaceToIPv4Addr(ifi)
-	if err != nil {
-		return wrapSyscallError("setsockopt", err)
-	}
-	var a [4]byte
-	copy(a[:], ip.To4())
-	err = fd.pfd.SetsockoptInet4Addr(syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a)
-	runtime.KeepAlive(fd)
-	return wrapSyscallError("setsockopt", err)
-}
-
-func setIPv4MulticastLoopback(fd *netFD, v bool) error {
-	err := fd.pfd.SetsockoptByte(syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v)))
-	runtime.KeepAlive(fd)
-	return wrapSyscallError("setsockopt", err)
-}
diff --git a/src/net/sockoptip_bsdvar.go b/src/net/sockoptip_bsdvar.go
new file mode 100644
index 0000000..9560101
--- /dev/null
+++ b/src/net/sockoptip_bsdvar.go
@@ -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.
+
+// +build darwin dragonfly freebsd netbsd openbsd solaris
+
+package net
+
+import (
+	"runtime"
+	"syscall"
+)
+
+func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
+	ip, err := interfaceToIPv4Addr(ifi)
+	if err != nil {
+		return wrapSyscallError("setsockopt", err)
+	}
+	var a [4]byte
+	copy(a[:], ip.To4())
+	err = fd.pfd.SetsockoptInet4Addr(syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a)
+	runtime.KeepAlive(fd)
+	return wrapSyscallError("setsockopt", err)
+}
+
+func setIPv4MulticastLoopback(fd *netFD, v bool) error {
+	err := fd.pfd.SetsockoptByte(syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v)))
+	runtime.KeepAlive(fd)
+	return wrapSyscallError("setsockopt", err)
+}
diff --git a/src/net/sockoptip_posix.go b/src/net/sockoptip_posix.go
index 4e10f2a..5d3077e 100644
--- a/src/net/sockoptip_posix.go
+++ b/src/net/sockoptip_posix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
 
diff --git a/src/net/sockoptip_stub.go b/src/net/sockoptip_stub.go
index f698687..fc20a9f 100644
--- a/src/net/sockoptip_stub.go
+++ b/src/net/sockoptip_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build nacl solaris
+// +build nacl
 
 package net
 
diff --git a/src/net/tcpsock.go b/src/net/tcpsock.go
index e957aa3..9528140 100644
--- a/src/net/tcpsock.go
+++ b/src/net/tcpsock.go
@@ -225,6 +225,18 @@
 	fd *netFD
 }
 
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+//
+// The returned RawConn only supports calling Control. Read and
+// Write return an error.
+func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
+	if !l.ok() {
+		return nil, syscall.EINVAL
+	}
+	return newRawListener(l.fd)
+}
+
 // AcceptTCP accepts the next incoming call and returns the new
 // connection.
 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
diff --git a/src/net/tcpsock_test.go b/src/net/tcpsock_test.go
index 09f6516..b85ffa6 100644
--- a/src/net/tcpsock_test.go
+++ b/src/net/tcpsock_test.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"internal/testenv"
 	"io"
+	"os"
 	"reflect"
 	"runtime"
 	"sync"
@@ -722,3 +723,74 @@
 		})
 	}
 }
+
+func TestCopyPipeIntoTCP(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	errc := make(chan error, 1)
+	defer func() {
+		if err := <-errc; err != nil {
+			t.Error(err)
+		}
+	}()
+	go func() {
+		c, err := ln.Accept()
+		if err != nil {
+			errc <- err
+			return
+		}
+		defer c.Close()
+
+		buf := make([]byte, 100)
+		n, err := io.ReadFull(c, buf)
+		if err != io.ErrUnexpectedEOF || n != 2 {
+			errc <- fmt.Errorf("got err=%q n=%v; want err=%q n=2", err, n, io.ErrUnexpectedEOF)
+			return
+		}
+
+		errc <- nil
+	}()
+
+	c, err := Dial("tcp", ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+
+	errc2 := make(chan error, 1)
+	defer func() {
+		if err := <-errc2; err != nil {
+			t.Error(err)
+		}
+	}()
+
+	defer w.Close()
+
+	go func() {
+		_, err := io.Copy(c, r)
+		errc2 <- err
+	}()
+
+	// Split write into 2 packets. That makes Windows TransmitFile
+	// drop second packet.
+	packet := make([]byte, 1)
+	_, err = w.Write(packet)
+	if err != nil {
+		t.Fatal(err)
+	}
+	time.Sleep(100 * time.Millisecond)
+	_, err = w.Write(packet)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
index e07d1d6..8c3a052 100644
--- a/src/net/textproto/reader.go
+++ b/src/net/textproto/reader.go
@@ -476,15 +476,25 @@
 	}
 
 	m := make(MIMEHeader, hint)
+
+	// The first line cannot start with a leading space.
+	if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
+		line, err := r.readLineSlice()
+		if err != nil {
+			return m, err
+		}
+		return m, ProtocolError("malformed MIME header initial line: " + string(line))
+	}
+
 	for {
 		kv, err := r.readContinuedLineSlice()
 		if len(kv) == 0 {
 			return m, err
 		}
 
-		// Key ends at first colon; should not have spaces but
-		// they appear in the wild, violating specs, so we
-		// remove them if present.
+		// Key ends at first colon; should not have trailing spaces
+		// but they appear in the wild, violating specs, so we remove
+		// them if present.
 		i := bytes.IndexByte(kv, ':')
 		if i < 0 {
 			return m, ProtocolError("malformed MIME header line: " + string(kv))
diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
index 6cd98ed..f1c56b4 100644
--- a/src/net/textproto/reader_test.go
+++ b/src/net/textproto/reader_test.go
@@ -211,6 +211,24 @@
 	}
 }
 
+func TestReadMIMEHeaderMalformed(t *testing.T) {
+	inputs := []string{
+		"No colon first line\r\nFoo: foo\r\n\r\n",
+		" No colon first line with leading space\r\nFoo: foo\r\n\r\n",
+		"\tNo colon first line with leading tab\r\nFoo: foo\r\n\r\n",
+		" First: line with leading space\r\nFoo: foo\r\n\r\n",
+		"\tFirst: line with leading tab\r\nFoo: foo\r\n\r\n",
+		"Foo: foo\r\nNo colon second line\r\n\r\n",
+	}
+
+	for _, input := range inputs {
+		r := reader(input)
+		if m, err := r.ReadMIMEHeader(); err == nil {
+			t.Errorf("ReadMIMEHeader(%q) = %v, %v; want nil, err", input, m, err)
+		}
+	}
+}
+
 // Test that continued lines are properly trimmed. Issue 11204.
 func TestReadMIMEHeaderTrimContinued(t *testing.T) {
 	// In this header, \n and \r\n terminated lines are mixed on purpose.
diff --git a/src/net/udpsock.go b/src/net/udpsock.go
index 2c0f74f..158265f 100644
--- a/src/net/udpsock.go
+++ b/src/net/udpsock.go
@@ -9,7 +9,7 @@
 	"syscall"
 )
 
-// BUG(mikio): On NaCl, Plan 9 and Windows, the ReadMsgUDP and
+// BUG(mikio): On NaCl and Plan 9, the ReadMsgUDP and
 // WriteMsgUDP methods of UDPConn are not implemented.
 
 // BUG(mikio): On Windows, the File method of UDPConn is not
diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go
index 6d4974e..769576c 100644
--- a/src/net/udpsock_test.go
+++ b/src/net/udpsock_test.go
@@ -161,8 +161,13 @@
 	}
 	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
 	switch runtime.GOOS {
-	case "nacl", "windows": // see golang.org/issue/9252
+	case "nacl": // see golang.org/issue/9252
 		t.Skipf("not implemented yet on %s", runtime.GOOS)
+	case "windows":
+		if testenv.IsWindowsXP() {
+			t.Log("skipping broken test on Windows XP (see golang.org/issue/23072)")
+			return
+		}
 	default:
 		if err != nil {
 			t.Fatal(err)
@@ -204,8 +209,13 @@
 	}
 	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
 	switch runtime.GOOS {
-	case "nacl", "windows": // see golang.org/issue/9252
+	case "nacl": // see golang.org/issue/9252
 		t.Skipf("not implemented yet on %s", runtime.GOOS)
+	case "windows":
+		if testenv.IsWindowsXP() {
+			t.Log("skipping broken test on Windows XP (see golang.org/issue/23072)")
+			return
+		}
 	default:
 		if err != nil {
 			t.Fatal(err)
diff --git a/src/net/unixsock.go b/src/net/unixsock.go
index 057940a..20326da 100644
--- a/src/net/unixsock.go
+++ b/src/net/unixsock.go
@@ -219,6 +219,18 @@
 
 func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
 
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+//
+// The returned RawConn only supports calling Control. Read and
+// Write return an error.
+func (l *UnixListener) SyscallConn() (syscall.RawConn, error) {
+	if !l.ok() {
+		return nil, syscall.EINVAL
+	}
+	return newRawListener(l.fd)
+}
+
 // AcceptUnix accepts the next incoming call and returns the new
 // connection.
 func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
diff --git a/src/net/unixsock_linux_test.go b/src/net/unixsock_linux_test.go
new file mode 100644
index 0000000..d04007c
--- /dev/null
+++ b/src/net/unixsock_linux_test.go
@@ -0,0 +1,104 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"bytes"
+	"reflect"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestUnixgramAutobind(t *testing.T) {
+	laddr := &UnixAddr{Name: "", Net: "unixgram"}
+	c1, err := ListenUnixgram("unixgram", laddr)
+	if err != nil {
+		t.Fatal(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.Fatal(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) {
+	laddr := &UnixAddr{Name: "", Net: "unix"}
+	ln, err := ListenUnix("unix", laddr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ln.Close()
+}
+
+func TestUnixgramLinuxAbstractLongName(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("abstract unix socket long name test")
+	}
+
+	// Create an abstract socket name whose length is exactly
+	// the maximum RawSockkaddrUnix Path len
+	rsu := syscall.RawSockaddrUnix{}
+	addrBytes := make([]byte, len(rsu.Path))
+	copy(addrBytes, "@abstract_test")
+	addr := string(addrBytes)
+
+	la, err := ResolveUnixAddr("unixgram", addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	c, err := ListenUnixgram("unixgram", la)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	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.Error(err)
+			return
+		}
+		defer syscall.Close(s)
+		rsa := &syscall.SockaddrUnix{Name: addr}
+		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
+			t.Error(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.Fatal(err)
+	}
+	if from != nil {
+		t.Fatalf("unexpected peer address: %v", from)
+	}
+	if !bytes.Equal(b[:n], data[:]) {
+		t.Fatalf("got %v; want %v", b[:n], data[:])
+	}
+}
diff --git a/src/net/unixsock_test.go b/src/net/unixsock_test.go
index 489a29b..3e5c8bc 100644
--- a/src/net/unixsock_test.go
+++ b/src/net/unixsock_test.go
@@ -170,51 +170,6 @@
 	}
 }
 
-func TestUnixgramAutobind(t *testing.T) {
-	if runtime.GOOS != "linux" {
-		t.Skip("autobind is linux only")
-	}
-
-	laddr := &UnixAddr{Name: "", Net: "unixgram"}
-	c1, err := ListenUnixgram("unixgram", laddr)
-	if err != nil {
-		t.Fatal(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.Fatal(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("autobind is linux only")
-	}
-
-	laddr := &UnixAddr{Name: "", Net: "unix"}
-	ln, err := ListenUnix("unix", laddr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	ln.Close()
-}
-
 func TestUnixgramWrite(t *testing.T) {
 	if !testableNetwork("unixgram") {
 		t.Skip("unixgram test")
diff --git a/src/net/url/example_test.go b/src/net/url/example_test.go
index d352c55..d8eb6dc 100644
--- a/src/net/url/example_test.go
+++ b/src/net/url/example_test.go
@@ -81,6 +81,16 @@
 	// {"x":["1"], "y":["2", "3"], "z":[""]}
 }
 
+func ExampleURL_EscapedPath() {
+	u, err := url.Parse("http://example.com/path with spaces")
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(u.EscapedPath())
+	// Output:
+	// /path%20with%20spaces
+}
+
 func ExampleURL_Hostname() {
 	u, err := url.Parse("https://example.org:8000/path")
 	if err != nil {
@@ -97,6 +107,104 @@
 	// 2001:0db8:85a3:0000:0000:8a2e:0370:7334
 }
 
+func ExampleURL_IsAbs() {
+	u := url.URL{Host: "example.com", Path: "foo"}
+	fmt.Println(u.IsAbs())
+	u.Scheme = "http"
+	fmt.Println(u.IsAbs())
+	// Output:
+	// false
+	// true
+}
+
+func ExampleURL_MarshalBinary() {
+	u, _ := url.Parse("https://example.org")
+	b, err := u.MarshalBinary()
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("%s\n", b)
+	// Output:
+	// https://example.org
+}
+
+func ExampleURL_Parse() {
+	u, err := url.Parse("https://example.org")
+	if err != nil {
+		log.Fatal(err)
+	}
+	rel, err := u.Parse("/foo")
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(rel)
+	_, err = u.Parse(":foo")
+	if _, ok := err.(*url.Error); !ok {
+		log.Fatal(err)
+	}
+	// Output:
+	// https://example.org/foo
+}
+
+func ExampleURL_Port() {
+	u, err := url.Parse("https://example.org")
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(u.Port())
+	u, err = url.Parse("https://example.org:8080")
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(u.Port())
+	// Output:
+	//
+	// 8080
+}
+
+func ExampleURL_Query() {
+	u, err := url.Parse("https://example.org/?a=1&a=2&b=&=3&&&&")
+	if err != nil {
+		log.Fatal(err)
+	}
+	q := u.Query()
+	fmt.Println(q["a"])
+	fmt.Println(q.Get("b"))
+	fmt.Println(q.Get(""))
+	// Output:
+	// [1 2]
+	//
+	// 3
+}
+
+func ExampleURL_String() {
+	u := &url.URL{
+		Scheme:   "https",
+		User:     url.UserPassword("me", "pass"),
+		Host:     "example.com",
+		Path:     "foo/bar",
+		RawQuery: "x=1&y=2",
+		Fragment: "anchor",
+	}
+	fmt.Println(u.String())
+	u.Opaque = "opaque"
+	fmt.Println(u.String())
+	// Output:
+	// https://me:pass@example.com/foo/bar?x=1&y=2#anchor
+	// https:opaque?x=1&y=2#anchor
+}
+
+func ExampleURL_UnmarshalBinary() {
+	u := &url.URL{}
+	err := u.UnmarshalBinary([]byte("https://example.org/foo"))
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("%s\n", u)
+	// Output:
+	// https://example.org/foo
+}
+
 func ExampleURL_RequestURI() {
 	u, err := url.Parse("https://example.org/path?foo=bar")
 	if err != nil {
diff --git a/src/net/url/url.go b/src/net/url/url.go
index 2ac2472..3e12179 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -163,18 +163,23 @@
 	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.
+// QueryUnescape does the inverse transformation of QueryEscape,
+// converting each 3-byte encoded substring of the form "%AB" into the
+// hex-decoded byte 0xAB. It also converts '+' 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)
 }
 
-// PathUnescape does the inverse transformation of PathEscape, converting
-// %AB into the byte 0xAB. It returns an error if any % is not followed by
-// two hexadecimal digits.
+// PathUnescape does the inverse transformation of PathEscape,
+// converting each 3-byte encoded substring of the form "%AB" into the
+// hex-decoded byte 0xAB. It also converts '+' into ' ' (space).
+// It returns an error if any % is not followed by two hexadecimal
+// digits.
 //
-// PathUnescape is identical to QueryUnescape except that it does not unescape '+' to ' ' (space).
+// PathUnescape is identical to QueryUnescape except that it does not
+// unescape '+' to ' ' (space).
 func PathUnescape(s string) (string, error) {
 	return unescape(s, encodePathSegment)
 }
@@ -367,17 +372,26 @@
 
 // Username returns the username.
 func (u *Userinfo) Username() string {
+	if u == nil {
+		return ""
+	}
 	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 == nil {
+		return "", false
+	}
 	return u.password, u.passwordSet
 }
 
 // String returns the encoded userinfo information in the standard form
 // of "username[:password]".
 func (u *Userinfo) String() string {
+	if u == nil {
+		return ""
+	}
 	s := escape(u.username, encodeUserPassword)
 	if u.passwordSet {
 		s += ":" + escape(u.password, encodeUserPassword)
@@ -427,7 +441,11 @@
 }
 
 // Parse parses rawurl into a URL structure.
-// The rawurl may be relative or absolute.
+//
+// The rawurl may be relative (a path, without a host) or absolute
+// (starting with a scheme). Trying to parse a hostname and path
+// without a scheme is invalid but may not necessarily return an
+// error, due to parsing ambiguities.
 func Parse(rawurl string) (*URL, error) {
 	// Cut off #frag
 	u, frag := split(rawurl, "#", true)
@@ -545,6 +563,9 @@
 		return nil, host, nil
 	}
 	userinfo := authority[:i]
+	if !validUserinfo(userinfo) {
+		return nil, "", errors.New("net/url: invalid userinfo")
+	}
 	if !strings.Contains(userinfo, ":") {
 		if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
 			return nil, "", err
@@ -726,7 +747,9 @@
 		buf.WriteString(u.Opaque)
 	} else {
 		if u.Scheme != "" || u.Host != "" || u.User != nil {
-			buf.WriteString("//")
+			if u.Host != "" || u.Path != "" || u.User != nil {
+				buf.WriteString("//")
+			}
 			if ui := u.User; ui != nil {
 				buf.WriteString(ui.String())
 				buf.WriteByte('@')
@@ -909,7 +932,7 @@
 		// Add final slash to the joined path.
 		dst = append(dst, "")
 	}
-	return "/" + strings.TrimLeft(strings.Join(dst, "/"), "/")
+	return "/" + strings.TrimPrefix(strings.Join(dst, "/"), "/")
 }
 
 // IsAbs reports whether the URL is absolute.
@@ -953,12 +976,10 @@
 		url.Path = ""
 		return &url
 	}
-	if ref.Path == "" {
-		if ref.RawQuery == "" {
-			url.RawQuery = u.RawQuery
-			if ref.Fragment == "" {
-				url.Fragment = u.Fragment
-			}
+	if ref.Path == "" && ref.RawQuery == "" {
+		url.RawQuery = u.RawQuery
+		if ref.Fragment == "" {
+			url.Fragment = u.Fragment
 		}
 	}
 	// The "abs_path" or "rel_path" cases.
@@ -1051,3 +1072,33 @@
 	*u = *u1
 	return nil
 }
+
+// validUserinfo reports whether s is a valid userinfo string per RFC 3986
+// Section 3.2.1:
+//     userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )
+//     unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
+//     sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
+//                   / "*" / "+" / "," / ";" / "="
+//
+// It doesn't validate pct-encoded. The caller does that via func unescape.
+func validUserinfo(s string) bool {
+	for _, r := range s {
+		if 'A' <= r && r <= 'Z' {
+			continue
+		}
+		if 'a' <= r && r <= 'z' {
+			continue
+		}
+		if '0' <= r && r <= '9' {
+			continue
+		}
+		switch r {
+		case '-', '.', '_', ':', '~', '!', '$', '&', '\'',
+			'(', ')', '*', '+', ',', ';', '=', '%', '@':
+			continue
+		default:
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
index 6c3bb21..f2d311a 100644
--- a/src/net/url/url_test.go
+++ b/src/net/url/url_test.go
@@ -568,6 +568,28 @@
 		},
 		"",
 	},
+	// test we can roundtrip magnet url
+	// fix issue https://golang.org/issue/20054
+	{
+		"magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a&dn",
+		&URL{
+			Scheme:   "magnet",
+			Host:     "",
+			Path:     "",
+			RawQuery: "xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a&dn",
+		},
+		"magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a&dn",
+	},
+	{
+		"mailto:?subject=hi",
+		&URL{
+			Scheme:   "mailto",
+			Host:     "",
+			Path:     "",
+			RawQuery: "subject=hi",
+		},
+		"mailto:?subject=hi",
+	},
 }
 
 // more useful string for debugging than fmt's struct printer
@@ -1010,6 +1032,10 @@
 	{"http://foo.com/bar?a=b", "/baz?", "http://foo.com/baz?"},
 	{"http://foo.com/bar?a=b", "/baz?c=d", "http://foo.com/baz?c=d"},
 
+	// Multiple slashes
+	{"http://foo.com/bar", "http://foo.com//baz", "http://foo.com//baz"},
+	{"http://foo.com/bar", "http://foo.com///baz/quux", "http://foo.com///baz/quux"},
+
 	// Scheme-relative
 	{"https://foo.com/bar?a=b", "//bar.com/quux", "https://bar.com/quux"},
 
@@ -1683,3 +1709,36 @@
 		t.Errorf("json decoded to: %s\nwant: %s\n", u1, u)
 	}
 }
+
+func TestNilUser(t *testing.T) {
+	defer func() {
+		if v := recover(); v != nil {
+			t.Fatalf("unexpected panic: %v", v)
+		}
+	}()
+
+	u, err := Parse("http://foo.com/")
+
+	if err != nil {
+		t.Fatalf("parse err: %v", err)
+	}
+
+	if v := u.User.Username(); v != "" {
+		t.Fatalf("expected empty username, got %s", v)
+	}
+
+	if v, ok := u.User.Password(); v != "" || ok {
+		t.Fatalf("expected empty password, got %s (%v)", v, ok)
+	}
+
+	if v := u.User.String(); v != "" {
+		t.Fatalf("expected empty string, got %s", v)
+	}
+}
+
+func TestInvalidUserPassword(t *testing.T) {
+	_, err := Parse("http://us\ner:pass\nword@foo.com/")
+	if got, wantsub := fmt.Sprint(err), "net/url: invalid userinfo"; !strings.Contains(got, wantsub) {
+		t.Errorf("error = %q; want substring %q", got, wantsub)
+	}
+}
diff --git a/src/net/write_unix_test.go b/src/net/write_unix_test.go
new file mode 100644
index 0000000..6d8cb6a
--- /dev/null
+++ b/src/net/write_unix_test.go
@@ -0,0 +1,66 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"bytes"
+	"syscall"
+	"testing"
+	"time"
+)
+
+// Test that a client can't trigger an endless loop of write system
+// calls on the server by shutting down the write side on the client.
+// Possibility raised in the discussion of https://golang.org/cl/71973.
+func TestEndlessWrite(t *testing.T) {
+	t.Parallel()
+	c := make(chan bool)
+	server := func(cs *TCPConn) error {
+		cs.CloseWrite()
+		<-c
+		return nil
+	}
+	client := func(ss *TCPConn) error {
+		// Tell the server to return when we return.
+		defer close(c)
+
+		// Loop writing to the server. The server is not reading
+		// anything, so this will eventually block, and then time out.
+		b := bytes.Repeat([]byte{'a'}, 8192)
+		cagain := 0
+		for {
+			n, err := ss.conn.fd.pfd.WriteOnce(b)
+			if n > 0 {
+				cagain = 0
+			}
+			switch err {
+			case nil:
+			case syscall.EAGAIN:
+				if cagain == 0 {
+					// We've written enough data to
+					// start blocking. Set a deadline
+					// so that we will stop.
+					ss.SetWriteDeadline(time.Now().Add(5 * time.Millisecond))
+				}
+				cagain++
+				if cagain > 20 {
+					t.Error("looping on EAGAIN")
+					return nil
+				}
+				if err = ss.conn.fd.pfd.WaitWrite(); err != nil {
+					t.Logf("client WaitWrite: %v", err)
+					return nil
+				}
+			default:
+				// We expect to eventually get an error.
+				t.Logf("client WriteOnce: %v", err)
+				return nil
+			}
+		}
+	}
+	withTCPConnPair(t, client, server)
+}
diff --git a/src/os/env.go b/src/os/env.go
index a03b8f6..4e0171f 100644
--- a/src/os/env.go
+++ b/src/os/env.go
@@ -6,7 +6,10 @@
 
 package os
 
-import "syscall"
+import (
+	"internal/testlog"
+	"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).
@@ -78,6 +81,7 @@
 // It returns the value, which will be empty if the variable is not present.
 // To distinguish between an empty value and an unset value, use LookupEnv.
 func Getenv(key string) string {
+	testlog.Getenv(key)
 	v, _ := syscall.Getenv(key)
 	return v
 }
@@ -88,6 +92,7 @@
 // Otherwise the returned value will be empty and the boolean will
 // be false.
 func LookupEnv(key string) (string, bool) {
+	testlog.Getenv(key)
 	return syscall.Getenv(key)
 }
 
diff --git a/src/os/env_test.go b/src/os/env_test.go
index e5749f0..16f1945 100644
--- a/src/os/env_test.go
+++ b/src/os/env_test.go
@@ -134,7 +134,7 @@
 	if err != nil {
 		t.Fatalf("failed to release smallpox virus")
 	}
-	value, ok = LookupEnv(smallpox)
+	_, ok = LookupEnv(smallpox)
 	if !ok {
 		t.Errorf("smallpox release failed; world remains safe but LookupEnv is broken")
 	}
diff --git a/src/os/error.go b/src/os/error.go
index 7235bfb..b4242a4 100644
--- a/src/os/error.go
+++ b/src/os/error.go
@@ -6,6 +6,7 @@
 
 import (
 	"errors"
+	"internal/poll"
 )
 
 // Portable analogs of some common system call errors.
@@ -15,8 +16,13 @@
 	ErrExist      = errors.New("file already exists")
 	ErrNotExist   = errors.New("file does not exist")
 	ErrClosed     = errors.New("file already closed")
+	ErrNoDeadline = poll.ErrNoDeadline
 )
 
+type timeout interface {
+	Timeout() bool
+}
+
 // PathError records an error and the operation and file path that caused it.
 type PathError struct {
 	Op   string
@@ -26,6 +32,12 @@
 
 func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
 
+// Timeout reports whether this error represents a timeout.
+func (e *PathError) Timeout() bool {
+	t, ok := e.Err.(timeout)
+	return ok && t.Timeout()
+}
+
 // SyscallError records an error from a specific system call.
 type SyscallError struct {
 	Syscall string
@@ -34,6 +46,12 @@
 
 func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
 
+// Timeout reports whether this error represents a timeout.
+func (e *SyscallError) Timeout() bool {
+	t, ok := e.Err.(timeout)
+	return ok && t.Timeout()
+}
+
 // NewSyscallError returns, as an error, a new SyscallError
 // with the given system call name and error details.
 // As a convenience, if err is nil, NewSyscallError returns nil.
@@ -65,6 +83,13 @@
 	return isPermission(err)
 }
 
+// IsTimeout returns a boolean indicating whether the error is known
+// to report that a timeout occurred.
+func IsTimeout(err error) bool {
+	terr, ok := underlyingError(err).(timeout)
+	return ok && terr.Timeout()
+}
+
 // underlyingError returns the underlying error for known os error types.
 func underlyingError(err error) error {
 	switch err := err.(type) {
diff --git a/src/os/error_plan9.go b/src/os/error_plan9.go
index a673439..b82bf0d 100644
--- a/src/os/error_plan9.go
+++ b/src/os/error_plan9.go
@@ -5,7 +5,7 @@
 package os
 
 func isExist(err error) bool {
-	return checkErrMessageContent(err, " exists")
+	return checkErrMessageContent(err, "exists", "is a directory")
 }
 
 func isNotExist(err error) bool {
diff --git a/src/os/exec.go b/src/os/exec.go
index 8a53e5d..a7f8710 100644
--- a/src/os/exec.go
+++ b/src/os/exec.go
@@ -5,6 +5,7 @@
 package os
 
 import (
+	"internal/testlog"
 	"runtime"
 	"sync"
 	"sync/atomic"
@@ -84,13 +85,20 @@
 }
 
 // StartProcess starts a new process with the program, arguments and attributes
-// specified by name, argv and attr.
+// specified by name, argv and attr. The argv slice will become os.Args in the
+// new process, so it normally starts with the program name.
+//
+// If the calling goroutine has locked the operating system thread
+// with runtime.LockOSThread and modified any inheritable OS-level
+// thread state (for example, Linux or Plan 9 name spaces), the new
+// process will inherit the caller's thread state.
 //
 // StartProcess is a low-level interface. The os/exec package provides
 // higher-level interfaces.
 //
 // If there is an error, it will be of type *PathError.
 func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
+	testlog.Open(name)
 	return startProcess(name, argv, attr)
 }
 
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
index 893d8ee..5ef9540 100644
--- a/src/os/exec/exec.go
+++ b/src/os/exec/exec.go
@@ -77,9 +77,12 @@
 	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
@@ -92,8 +95,16 @@
 	// If either is nil, Run connects the corresponding file descriptor
 	// to the null device (os.DevNull).
 	//
-	// If Stdout and Stderr are the same writer, and have a type that can be compared with ==,
-	// at most one goroutine at a time will call Write.
+	// If either is an *os.File, the corresponding output from the process
+	// is connected directly to that file.
+	//
+	// Otherwise, during the execution of the command a separate goroutine
+	// reads from the process over a pipe and delivers that data to the
+	// corresponding Writer. In this case, Wait does not complete until the
+	// goroutine reaches EOF or encounters an error.
+	//
+	// If Stdout and Stderr are the same writer, and have a type that can
+	// be compared with ==, at most one goroutine at a time will call Write.
 	Stdout io.Writer
 	Stderr io.Writer
 
@@ -190,7 +201,7 @@
 }
 
 // skipStdinCopyError optionally specifies a function which reports
-// whether the provided the stdin copy error should be ignored.
+// whether the provided stdin copy error should be ignored.
 // It is non-nil everywhere but Plan 9, which lacks EPIPE. See exec_posix.go.
 var skipStdinCopyError func(error) bool
 
@@ -282,6 +293,11 @@
 //
 // If the command starts but does not complete successfully, the error is of
 // type *ExitError. Other error types may be returned for other situations.
+//
+// If the calling goroutine has locked the operating system thread
+// with runtime.LockOSThread and modified any inheritable OS-level
+// thread state (for example, Linux or Plan 9 name spaces), the new
+// process will inherit the caller's thread state.
 func (c *Cmd) Run() error {
 	if err := c.Start(); err != nil {
 		return err
@@ -429,9 +445,8 @@
 // error is of type *ExitError. Other error types may be
 // returned for I/O problems.
 //
-// If c.Stdin is not an *os.File, Wait also waits for the I/O loop
-// copying from c.Stdin into the process's standard input
-// to complete.
+// If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits
+// for the respective I/O loop copying to or from the process to complete.
 //
 // Wait releases any resources associated with the Cmd.
 func (c *Cmd) Wait() error {
@@ -527,16 +542,15 @@
 	c.Stdin = pr
 	c.closeAfterStart = append(c.closeAfterStart, pr)
 	wc := &closeOnce{File: pw}
-	c.closeAfterWait = append(c.closeAfterWait, closerFunc(wc.safeClose))
+	c.closeAfterWait = append(c.closeAfterWait, wc)
 	return wc, nil
 }
 
 type closeOnce struct {
 	*os.File
 
-	writers sync.RWMutex // coordinate safeClose and Write
-	once    sync.Once
-	err     error
+	once sync.Once
+	err  error
 }
 
 func (c *closeOnce) Close() error {
@@ -548,55 +562,6 @@
 	c.err = c.File.Close()
 }
 
-type closerFunc func() error
-
-func (f closerFunc) Close() error { return f() }
-
-// safeClose closes c being careful not to race with any calls to c.Write.
-// See golang.org/issue/9307 and TestEchoFileRace in exec_test.go.
-// In theory other calls could also be excluded (by writing appropriate
-// wrappers like c.Write's implementation below), but since c is most
-// commonly used as a WriteCloser, Write is the main one to worry about.
-// See also #7970, for which this is a partial fix for this specific instance.
-// The idea is that we return a WriteCloser, and so the caller can be
-// relied upon not to call Write and Close simultaneously, but it's less
-// obvious that cmd.Wait calls Close and that the caller must not call
-// Write and cmd.Wait simultaneously. In fact that seems too onerous.
-// So we change the use of Close in cmd.Wait to use safeClose, which will
-// synchronize with any Write.
-//
-// It's important that we know this won't block forever waiting for the
-// operations being excluded. At the point where this is called,
-// the invoked command has exited and the parent copy of the read side
-// of the pipe has also been closed, so there should really be no read side
-// of the pipe left. Any active writes should return very shortly with an EPIPE,
-// making it reasonable to wait for them.
-// Technically it is possible that the child forked a sub-process or otherwise
-// handed off the read side of the pipe before exiting and the current holder
-// is not reading from the pipe, and the pipe is full, in which case the close here
-// might block waiting for the write to complete. That's probably OK.
-// It's a small enough problem to be outweighed by eliminating the race here.
-func (c *closeOnce) safeClose() error {
-	c.writers.Lock()
-	err := c.Close()
-	c.writers.Unlock()
-	return err
-}
-
-func (c *closeOnce) Write(b []byte) (int, error) {
-	c.writers.RLock()
-	n, err := c.File.Write(b)
-	c.writers.RUnlock()
-	return n, err
-}
-
-func (c *closeOnce) WriteString(s string) (int, error) {
-	c.writers.RLock()
-	n, err := c.File.WriteString(s)
-	c.writers.RUnlock()
-	return n, err
-}
-
 // StdoutPipe returns a pipe that will be connected to the command's
 // standard output when the command starts.
 //
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 0132906..d29ae69 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -401,9 +401,15 @@
 
 // basefds returns the number of expected file descriptors
 // to be present in a process at start.
-// stdin, stdout, stderr, epoll/kqueue
+// stdin, stdout, stderr, epoll/kqueue, maybe testlog
 func basefds() uintptr {
-	return os.Stderr.Fd() + 1
+	n := os.Stderr.Fd() + 1
+	for _, arg := range os.Args {
+		if strings.HasPrefix(arg, "-test.testlogfile=") {
+			n++
+		}
+	}
+	return n
 }
 
 func closeUnexpectedFds(t *testing.T, m string) {
@@ -999,6 +1005,9 @@
 }
 
 func TestContextCancel(t *testing.T) {
+	if testenv.Builder() == "windows-386-xp" {
+		t.Skipf("known to fail on Windows XP. Issue 17245")
+	}
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	c := helperCommandContext(t, ctx, "cat")
diff --git a/src/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
index 96a22d8..d1c9046 100644
--- a/src/os/exec/lp_windows_test.go
+++ b/src/os/exec/lp_windows_test.go
@@ -2,13 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package exec
+// Use an external test to avoid os/exec -> internal/testenv -> os/exec
+// circular dependency.
+
+package exec_test
 
 import (
 	"fmt"
+	"internal/testenv"
 	"io"
 	"io/ioutil"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -63,7 +68,7 @@
 }
 
 func (test lookPathTest) runProg(t *testing.T, env []string, args ...string) (string, error) {
-	cmd := Command(args[0], args[1:]...)
+	cmd := exec.Command(args[0], args[1:]...)
 	cmd.Env = env
 	cmd.Dir = test.rootDir
 	args[0] = filepath.Base(args[0])
@@ -346,7 +351,7 @@
 }
 
 func (test commandTest) runOne(rootDir string, env []string, dir, arg0 string) error {
-	cmd := Command(os.Args[0], "-test.run=TestHelperProcess", "--", "exec", dir, arg0)
+	cmd := exec.Command(os.Args[0], "-test.run=TestHelperProcess", "--", "exec", dir, arg0)
 	cmd.Dir = rootDir
 	cmd.Env = env
 	output, err := cmd.CombinedOutput()
@@ -532,7 +537,7 @@
 		t.Fatalf("failed to execute template: %v", err)
 	}
 	outname := name + ".exe"
-	cmd := Command("go", "build", "-o", outname, srcname)
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", outname, srcname)
 	cmd.Dir = dir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/os/exec_plan9.go b/src/os/exec_plan9.go
index 676be36..6b4d28c 100644
--- a/src/os/exec_plan9.go
+++ b/src/os/exec_plan9.go
@@ -11,9 +11,10 @@
 	"time"
 )
 
-// The only signal values guaranteed to be present on all systems
-// are Interrupt (send the process an interrupt) and Kill (force
-// the process to exit).
+// The only signal values guaranteed to be present in the os package
+// on all systems are Interrupt (send the process an interrupt) and
+// Kill (force the process to exit). Interrupt is not implemented on
+// Windows; using it with os.Process.Signal will return an error.
 var (
 	Interrupt Signal = syscall.Note("interrupt")
 	Kill      Signal = syscall.Note("kill")
diff --git a/src/os/exec_posix.go b/src/os/exec_posix.go
index 3cf38b6..fb220c8 100644
--- a/src/os/exec_posix.go
+++ b/src/os/exec_posix.go
@@ -10,9 +10,10 @@
 	"syscall"
 )
 
-// The only signal values guaranteed to be present on all systems
-// are Interrupt (send the process an interrupt) and Kill (force
-// the process to exit).
+// The only signal values guaranteed to be present in the os package
+// on all systems are Interrupt (send the process an interrupt) and
+// Kill (force the process to exit). Interrupt is not implemented on
+// Windows; using it with os.Process.Signal will return an error.
 var (
 	Interrupt Signal = syscall.SIGINT
 	Kill      Signal = syscall.SIGKILL
diff --git a/src/os/executable_test.go b/src/os/executable_test.go
index 7800844..4a9a883 100644
--- a/src/os/executable_test.go
+++ b/src/os/executable_test.go
@@ -17,7 +17,7 @@
 const executable_EnvVar = "OSTEST_OUTPUT_EXECPATH"
 
 func TestExecutable(t *testing.T) {
-	testenv.MustHaveExec(t) // will also execlude nacl, which doesn't support Executable anyway
+	testenv.MustHaveExec(t) // will also exclude nacl, which doesn't support Executable anyway
 	ep, err := os.Executable()
 	if err != nil {
 		t.Fatalf("Executable failed: %v", err)
diff --git a/src/os/file.go b/src/os/file.go
index 4b4d8fb..c667421 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -39,8 +39,10 @@
 import (
 	"errors"
 	"internal/poll"
+	"internal/testlog"
 	"io"
 	"syscall"
+	"time"
 )
 
 // Name returns the name of the file as presented to Open.
@@ -61,12 +63,14 @@
 // Flags to OpenFile wrapping those of the underlying system. Not all
 // flags may be implemented on a given system.
 const (
+	// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
 	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.
+	// The remaining values may be or'ed in to control behavior.
 	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_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.
 )
@@ -204,7 +208,8 @@
 	return f.Write([]byte(s))
 }
 
-// Mkdir creates a new directory with the specified name and permission bits.
+// Mkdir creates a new directory with the specified name and permission
+// bits (before umask).
 // If there is an error, it will be of type *PathError.
 func Mkdir(name string, perm FileMode) error {
 	e := syscall.Mkdir(fixLongPath(name), syscallMode(perm))
@@ -225,8 +230,15 @@
 // If there is an error, it will be of type *PathError.
 func Chdir(dir string) error {
 	if e := syscall.Chdir(dir); e != nil {
+		testlog.Open(dir) // observe likely non-existent directory
 		return &PathError{"chdir", dir, e}
 	}
+	if log := testlog.Logger(); log != nil {
+		wd, err := Getwd()
+		if err == nil {
+			log.Chdir(wd)
+		}
+	}
 	return nil
 }
 
@@ -247,6 +259,16 @@
 	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
 }
 
+// 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 (before umask), 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, error) {
+	testlog.Open(name)
+	return openFileNolog(name, flag, perm)
+}
+
 // lstat is overridden in tests.
 var lstat = Lstat
 
@@ -316,3 +338,47 @@
 // 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 { return f.chmod(mode) }
+
+// SetDeadline sets the read and write deadlines for a File.
+// It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
+//
+// Only some kinds of files support setting a deadline. Calls to SetDeadline
+// for files that do not support deadlines will return ErrNoDeadline.
+// On most systems ordinary files do not support deadlines, but pipes do.
+//
+// A deadline is an absolute time after which I/O operations fail with an
+// error instead of blocking. The deadline applies to all future and pending
+// I/O, not just the immediately following call to Read or Write.
+// After a deadline has been exceeded, the connection can be refreshed
+// by setting a deadline in the future.
+//
+// An error returned after a timeout fails will implement the
+// Timeout method, and calling the Timeout method will return true.
+// The PathError and SyscallError types implement the Timeout method.
+// In general, call IsTimeout to test whether an error indicates a timeout.
+//
+// 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.
+func (f *File) SetDeadline(t time.Time) error {
+	return f.setDeadline(t)
+}
+
+// SetReadDeadline sets the deadline for future Read calls and any
+// currently-blocked Read call.
+// A zero value for t means Read will not time out.
+// Not all files support setting deadlines; see SetDeadline.
+func (f *File) SetReadDeadline(t time.Time) error {
+	return f.setReadDeadline(t)
+}
+
+// SetWriteDeadline sets the deadline for any future Write calls and any
+// currently-blocked Write call.
+// 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.
+// Not all files support setting deadlines; see SetDeadline.
+func (f *File) SetWriteDeadline(t time.Time) error {
+	return f.setWriteDeadline(t)
+}
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
index 0f4a736..7e28178 100644
--- a/src/os/file_plan9.go
+++ b/src/os/file_plan9.go
@@ -5,6 +5,7 @@
 package os
 
 import (
+	"internal/poll"
 	"io"
 	"runtime"
 	"syscall"
@@ -28,6 +29,7 @@
 
 // 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.
+// On Unix systems this will cause the SetDeadline methods to stop working.
 func (f *File) Fd() uintptr {
 	if f == nil {
 		return ^(uintptr(0))
@@ -77,12 +79,8 @@
 	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, error) {
+// openFileNolog is the Plan 9 implementation of OpenFile.
+func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 	var (
 		fd     int
 		e      error
@@ -491,6 +489,30 @@
 	return nil
 }
 
+// setDeadline sets the read and write deadline.
+func (f *File) setDeadline(time.Time) error {
+	if err := f.checkValid("SetDeadline"); err != nil {
+		return err
+	}
+	return poll.ErrNoDeadline
+}
+
+// setReadDeadline sets the read deadline.
+func (f *File) setReadDeadline(time.Time) error {
+	if err := f.checkValid("SetReadDeadline"); err != nil {
+		return err
+	}
+	return poll.ErrNoDeadline
+}
+
+// setWriteDeadline sets the write deadline.
+func (f *File) setWriteDeadline(time.Time) error {
+	if err := f.checkValid("SetWriteDeadline"); err != nil {
+		return err
+	}
+	return poll.ErrNoDeadline
+}
+
 // checkValid checks whether f is valid for use.
 // If not, it returns an appropriate error, perhaps incorporating the operation name op.
 func (f *File) checkValid(op string) error {
diff --git a/src/os/file_posix.go b/src/os/file_posix.go
index f38d43e..36f7b90 100644
--- a/src/os/file_posix.go
+++ b/src/os/file_posix.go
@@ -159,6 +159,30 @@
 	return nil
 }
 
+// setDeadline sets the read and write deadline.
+func (f *File) setDeadline(t time.Time) error {
+	if err := f.checkValid("SetDeadline"); err != nil {
+		return err
+	}
+	return f.pfd.SetDeadline(t)
+}
+
+// setReadDeadline sets the read deadline.
+func (f *File) setReadDeadline(t time.Time) error {
+	if err := f.checkValid("SetReadDeadline"); err != nil {
+		return err
+	}
+	return f.pfd.SetReadDeadline(t)
+}
+
+// setWriteDeadline sets the write deadline.
+func (f *File) setWriteDeadline(t time.Time) error {
+	if err := f.checkValid("SetWriteDeadline"); err != nil {
+		return err
+	}
+	return f.pfd.SetWriteDeadline(t)
+}
+
 // checkValid checks whether f is valid for use.
 // If not, it returns an appropriate error, perhaps incorporating the operation name op.
 func (f *File) checkValid(op string) error {
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index 8b600d8..8c95f49 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -45,14 +45,16 @@
 // can overwrite this data, which could cause the finalizer
 // to close the wrong file descriptor.
 type file struct {
-	pfd      poll.FD
-	name     string
-	dirinfo  *dirInfo // nil unless directory being read
-	nonblock bool     // whether we set nonblocking mode
+	pfd         poll.FD
+	name        string
+	dirinfo     *dirInfo // nil unless directory being read
+	nonblock    bool     // whether we set nonblocking mode
+	stdoutOrErr bool     // whether this is stdout or stderr
 }
 
 // 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.
+// On Unix systems this will cause the SetDeadline methods to stop working.
 func (f *File) Fd() uintptr {
 	if f == nil {
 		return ^(uintptr(0))
@@ -64,7 +66,7 @@
 	// opened in blocking mode. The File will continue to work,
 	// but any blocking operation will tie up a thread.
 	if f.nonblock {
-		syscall.SetNonblock(f.pfd.Sysfd, false)
+		f.pfd.SetBlocking()
 	}
 
 	return uintptr(f.pfd.Sysfd)
@@ -74,12 +76,22 @@
 // name. The returned value will be nil if fd is not a valid file
 // descriptor.
 func NewFile(fd uintptr, name string) *File {
-	return newFile(fd, name, false)
+	return newFile(fd, name, kindNewFile)
 }
 
-// newFile is like NewFile, but if pollable is true it tries to add the
-// file to the runtime poller.
-func newFile(fd uintptr, name string, pollable bool) *File {
+// newFileKind describes the kind of file to newFile.
+type newFileKind int
+
+const (
+	kindNewFile newFileKind = iota
+	kindOpenFile
+	kindPipe
+)
+
+// newFile is like NewFile, but if called from OpenFile or Pipe
+// (as passed in the kind parameter) it tries to add the file to
+// the runtime poller.
+func newFile(fd uintptr, name string, kind newFileKind) *File {
 	fdi := int(fd)
 	if fdi < 0 {
 		return nil
@@ -90,16 +102,18 @@
 			IsStream:      true,
 			ZeroReadIsEOF: true,
 		},
-		name: name,
+		name:        name,
+		stdoutOrErr: fdi == 1 || fdi == 2,
 	}}
 
 	// Don't try to use kqueue with regular files on FreeBSD.
 	// It crashes the system unpredictably while running all.bash.
 	// Issue 19093.
-	if runtime.GOOS == "freebsd" {
-		pollable = false
+	if runtime.GOOS == "freebsd" && kind == kindOpenFile {
+		kind = kindNewFile
 	}
 
+	pollable := kind == kindOpenFile || kind == kindPipe
 	if err := f.pfd.Init("file", pollable); err != nil {
 		// An error here indicates a failure to register
 		// with the netpoll system. That can happen for
@@ -130,7 +144,7 @@
 // output or standard error. See the SIGPIPE docs in os/signal, and
 // issue 11845.
 func epipecheck(file *File, e error) {
-	if e == syscall.EPIPE && (file.pfd.Sysfd == 1 || file.pfd.Sysfd == 2) {
+	if e == syscall.EPIPE && file.stdoutOrErr {
 		sigpipe()
 	}
 }
@@ -139,12 +153,8 @@
 // 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, error) {
+// openFileNolog is the Unix implementation of OpenFile.
+func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 	chmod := false
 	if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
 		if _, err := Stat(name); IsNotExist(err) {
@@ -181,7 +191,7 @@
 		syscall.CloseOnExec(r)
 	}
 
-	return newFile(uintptr(r), name, true), nil
+	return newFile(uintptr(r), name, kindOpenFile), nil
 }
 
 // Close closes the File, rendering it unusable for I/O.
diff --git a/src/os/file_windows.go b/src/os/file_windows.go
index 93b6c13..be19fe2 100644
--- a/src/os/file_windows.go
+++ b/src/os/file_windows.go
@@ -25,6 +25,7 @@
 
 // Fd returns the Windows handle referencing the open file.
 // The handle is valid only until f.Close is called or f is garbage collected.
+// On Unix systems this will cause the SetDeadline methods to stop working.
 func (file *File) Fd() uintptr {
 	if file == nil {
 		return uintptr(syscall.InvalidHandle)
@@ -54,7 +55,7 @@
 
 	// Ignore initialization errors.
 	// Assume any problems will show up in later I/O.
-	f.pfd.Init(kind)
+	f.pfd.Init(kind, false)
 
 	return f
 }
@@ -147,12 +148,8 @@
 	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, error) {
+// openFileNolog is the Windows implementation of OpenFile.
+func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 	if name == "" {
 		return nil, &PathError{"open", name, syscall.ENOENT}
 	}
@@ -310,18 +307,10 @@
 // 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:])
+	e := syscall.CreatePipe(&p[0], &p[1], nil, 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(p[0], "|0", "file"), newFile(p[1], "|1", "file"), nil
 }
 
diff --git a/src/os/getwd.go b/src/os/getwd.go
index 4c3c0d9..6d25466 100644
--- a/src/os/getwd.go
+++ b/src/os/getwd.go
@@ -24,19 +24,19 @@
 // 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" {
+	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
 		return syscall.Getwd()
 	}
 
 	// Clumsy but widespread kludge:
 	// if $PWD is set and matches ".", use it.
-	dot, err := Stat(".")
+	dot, err := statNolog(".")
 	if err != nil {
 		return "", err
 	}
 	dir = Getenv("PWD")
 	if len(dir) > 0 && dir[0] == '/' {
-		d, err := Stat(dir)
+		d, err := statNolog(dir)
 		if err == nil && SameFile(dot, d) {
 			return dir, nil
 		}
@@ -56,7 +56,7 @@
 	dir = getwdCache.dir
 	getwdCache.Unlock()
 	if len(dir) > 0 {
-		d, err := Stat(dir)
+		d, err := statNolog(dir)
 		if err == nil && SameFile(dot, d) {
 			return dir, nil
 		}
@@ -64,7 +64,7 @@
 
 	// Root is a special case because it has no parent
 	// and ends in a slash.
-	root, err := Stat("/")
+	root, err := statNolog("/")
 	if err != nil {
 		// Can't stat root - no hope.
 		return "", err
@@ -81,7 +81,7 @@
 		if len(parent) >= 1024 { // Sanity check
 			return "", syscall.ENAMETOOLONG
 		}
-		fd, err := Open(parent)
+		fd, err := openFileNolog(parent, O_RDONLY, 0)
 		if err != nil {
 			return "", err
 		}
@@ -93,7 +93,7 @@
 				return "", err
 			}
 			for _, name := range names {
-				d, _ := Lstat(parent + "/" + name)
+				d, _ := lstatNolog(parent + "/" + name)
 				if SameFile(d, dot) {
 					dir = "/" + name + dir
 					goto Found
diff --git a/src/os/os_test.go b/src/os/os_test.go
index dbe4ff8..5739dc2 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -721,6 +721,27 @@
 	if !SameFile(tostat, fromstat) {
 		t.Errorf("link %q, %q did not create hard link", to, from)
 	}
+	// We should not be able to perform the same Link() a second time
+	err = Link(to, from)
+	switch err := err.(type) {
+	case *LinkError:
+		if err.Op != "link" {
+			t.Errorf("Link(%q, %q) err.Op = %q; want %q", to, from, err.Op, "link")
+		}
+		if err.Old != to {
+			t.Errorf("Link(%q, %q) err.Old = %q; want %q", to, from, err.Old, to)
+		}
+		if err.New != from {
+			t.Errorf("Link(%q, %q) err.New = %q; want %q", to, from, err.New, from)
+		}
+		if !IsExist(err.Err) {
+			t.Errorf("Link(%q, %q) err.Err = %q; want %q", to, from, err.Err, "file exists error")
+		}
+	case nil:
+		t.Errorf("link %q, %q: expected error, got nil", from, to)
+	default:
+		t.Errorf("link %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err)
+	}
 }
 
 // chtmpdir changes the working directory to a new temporary directory and
@@ -1014,9 +1035,14 @@
 		dir = Getenv("SystemRoot")
 		args = []string{"/c", "cd"}
 	default:
-		cmd = "/bin/pwd"
+		var err error
+		cmd, err = osexec.LookPath("pwd")
+		if err != nil {
+			t.Fatalf("Can't find pwd: %v", err)
+		}
 		dir = "/"
 		args = []string{}
+		t.Logf("Testing with %v", cmd)
 	}
 	cmddir, cmdbase := filepath.Split(cmd)
 	args = append([]string{cmdbase}, args...)
@@ -1164,9 +1190,14 @@
 			// the contents are accessed; also, it is set
 			// whenever mtime is set.
 		case "netbsd":
-			t.Logf("AccessTime didn't go backwards; was=%d, after=%d (Ignoring. See NetBSD issue golang.org/issue/19293)", at, pat)
+			mounts, _ := ioutil.ReadFile("/proc/mounts")
+			if strings.Contains(string(mounts), "noatime") {
+				t.Logf("AccessTime didn't go backwards, but see a filesystem mounted noatime; ignoring. Issue 19293.")
+			} else {
+				t.Logf("AccessTime didn't go backwards; was=%v, after=%v (Ignoring on NetBSD, assuming noatime, Issue 19293)", at, pat)
+			}
 		default:
-			t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
+			t.Errorf("AccessTime didn't go backwards; was=%v, after=%v", at, pat)
 		}
 	}
 
@@ -1213,9 +1244,9 @@
 			if mode == 0 {
 				err = Chdir(d)
 			} else {
-				fd1, err := Open(d)
-				if err != nil {
-					t.Errorf("Open %s: %s", d, err)
+				fd1, err1 := Open(d)
+				if err1 != nil {
+					t.Errorf("Open %s: %s", d, err1)
 					continue
 				}
 				err = fd1.Chdir()
@@ -1331,14 +1362,26 @@
 		{-1, io.SeekEnd, int64(len(data)) - 1},
 		{1 << 33, io.SeekStart, 1 << 33},
 		{1 << 33, io.SeekEnd, 1<<33 + int64(len(data))},
+
+		// Issue 21681, Windows 4G-1, etc:
+		{1<<32 - 1, io.SeekStart, 1<<32 - 1},
+		{0, io.SeekCurrent, 1<<32 - 1},
+		{2<<32 - 1, io.SeekStart, 2<<32 - 1},
+		{0, io.SeekCurrent, 2<<32 - 1},
 	}
 	for i, tt := range tests {
+		if runtime.GOOS == "nacl" && tt.out > 1<<30 {
+			t.Logf("skipping test case #%d on nacl; https://golang.org/issue/21728", i)
+			continue
+		}
 		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.
-				// https://golang.org/issue/91
-				break
+			if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 && runtime.GOOS == "linux" {
+				mounts, _ := ioutil.ReadFile("/proc/mounts")
+				if strings.Contains(string(mounts), "reiserfs") {
+					// Reiserfs rejects the big seeks.
+					t.Skipf("skipping test known to fail on reiserfs; https://golang.org/issue/91")
+				}
 			}
 			t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
 		}
@@ -2200,22 +2243,24 @@
 
 	defer debug.SetMaxThreads(debug.SetMaxThreads(threads / 2))
 
-	var wg sync.WaitGroup
-	wg.Add(threads)
-	c := make(chan bool, threads)
+	creading := make(chan bool, threads)
+	cdone := make(chan bool, threads)
 	for i := 0; i < threads; i++ {
 		go func(i int) {
-			defer wg.Done()
 			var b [1]byte
-			c <- true
+			creading <- true
 			if _, err := r[i].Read(b[:]); err != nil {
 				t.Error(err)
 			}
+			if err := r[i].Close(); err != nil {
+				t.Error(err)
+			}
+			cdone <- true
 		}(i)
 	}
 
 	for i := 0; i < threads; i++ {
-		<-c
+		<-creading
 	}
 
 	// If we are still alive, it means that the 100 goroutines did
@@ -2228,14 +2273,7 @@
 		if err := w[i].Close(); err != nil {
 			t.Error(err)
 		}
-	}
-
-	wg.Wait()
-
-	for i := 0; i < threads; i++ {
-		if err := r[i].Close(); err != nil {
-			t.Error(err)
-		}
+		<-cdone
 	}
 }
 
diff --git a/src/os/os_unix_test.go b/src/os/os_unix_test.go
index e239835..56c885c 100644
--- a/src/os/os_unix_test.go
+++ b/src/os/os_unix_test.go
@@ -36,11 +36,6 @@
 }
 
 func TestChown(t *testing.T) {
-	// Chown is not supported under windows or Plan 9.
-	// Plan9 provides a native ChownPlan9 version instead.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		t.Skipf("%s does not support syscall.Chown", runtime.GOOS)
-	}
 	// Use TempDir() to make sure we're on a local file system,
 	// so that the group ids returned by Getgroups will be allowed
 	// on the file. On NFS, the Getgroups groups are
@@ -84,10 +79,6 @@
 }
 
 func TestFileChown(t *testing.T) {
-	// Fchown is not supported under windows or Plan 9.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		t.Skipf("%s does not support syscall.Fchown", runtime.GOOS)
-	}
 	// Use TempDir() to make sure we're on a local file system,
 	// so that the group ids returned by Getgroups will be allowed
 	// on the file. On NFS, the Getgroups groups are
@@ -131,10 +122,6 @@
 }
 
 func TestLchown(t *testing.T) {
-	// Lchown is not supported under windows or Plan 9.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		t.Skipf("%s does not support syscall.Lchown", runtime.GOOS)
-	}
 	// Use TempDir() to make sure we're on a local file system,
 	// so that the group ids returned by Getgroups will be allowed
 	// on the file. On NFS, the Getgroups groups are
diff --git a/src/os/os_windows_test.go b/src/os/os_windows_test.go
index 04c4a4a..47e2611 100644
--- a/src/os/os_windows_test.go
+++ b/src/os/os_windows_test.go
@@ -520,10 +520,17 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	if got != target {
 		t.Errorf(`os.Readlink("%s"): got %v, want %v`, link, got, target)
 	}
+
+	got, err = filepath.EvalSymlinks(link)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got != target {
+		t.Errorf(`filepath.EvalSymlinks("%s"): got %v, want %v`, link, got, target)
+	}
 }
 
 func TestStartProcessAttr(t *testing.T) {
@@ -811,7 +818,7 @@
 	}
 
 	exe := filepath.Join(tmpdir, "main.exe")
-	cmd := osexec.Command("go", "build", "-o", exe, src)
+	cmd := osexec.Command(testenv.GoToolPath(t), "build", "-o", exe, src)
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/os/path.go b/src/os/path.go
index 146d7b6..eb996e5 100644
--- a/src/os/path.go
+++ b/src/os/path.go
@@ -6,13 +6,14 @@
 
 import (
 	"io"
+	"runtime"
 	"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
+// The permission bits perm (before umask) are used for all
 // directories that MkdirAll creates.
 // If path is already a directory, MkdirAll does nothing
 // and returns nil.
@@ -97,6 +98,11 @@
 	// Remove contents & return first error.
 	err = nil
 	for {
+		if err == nil && (runtime.GOOS == "plan9" || runtime.GOOS == "nacl") {
+			// Reset read offset after removing directory entries.
+			// See golang.org/issue/22572.
+			fd.Seek(0, 0)
+		}
 		names, err1 := fd.Readdirnames(100)
 		for _, name := range names {
 			err1 := RemoveAll(path + string(PathSeparator) + name)
diff --git a/src/os/path_test.go b/src/os/path_test.go
index 6f5bfa5..f58c7e7 100644
--- a/src/os/path_test.go
+++ b/src/os/path_test.go
@@ -5,6 +5,7 @@
 package os_test
 
 import (
+	"fmt"
 	"internal/testenv"
 	"io/ioutil"
 	. "os"
@@ -169,6 +170,36 @@
 	}
 }
 
+// Test RemoveAll on a large directory.
+func TestRemoveAllLarge(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+
+	tmpDir := TempDir()
+	// Work directory.
+	path := tmpDir + "/_TestRemoveAllLarge_"
+
+	// Make directory with 1000 files and remove.
+	if err := MkdirAll(path, 0777); err != nil {
+		t.Fatalf("MkdirAll %q: %s", path, err)
+	}
+	for i := 0; i < 1000; i++ {
+		fpath := fmt.Sprintf("%s/file%d", path, i)
+		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: %s", path, err)
+	}
+	if _, err := Lstat(path); err == nil {
+		t.Fatalf("Lstat %q succeeded after RemoveAll", path)
+	}
+}
+
 func TestMkdirAllWithSymlink(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
diff --git a/src/os/pipe_bsd.go b/src/os/pipe_bsd.go
index ffd201c..d16c2a6 100644
--- a/src/os/pipe_bsd.go
+++ b/src/os/pipe_bsd.go
@@ -24,5 +24,5 @@
 	syscall.CloseOnExec(p[1])
 	syscall.ForkLock.RUnlock()
 
-	return newFile(uintptr(p[0]), "|0", true), newFile(uintptr(p[1]), "|1", true), nil
+	return newFile(uintptr(p[0]), "|0", kindPipe), newFile(uintptr(p[1]), "|1", kindPipe), nil
 }
diff --git a/src/os/pipe_freebsd.go b/src/os/pipe_freebsd.go
index ea6622c..93bd869 100644
--- a/src/os/pipe_freebsd.go
+++ b/src/os/pipe_freebsd.go
@@ -13,22 +13,8 @@
 
 	e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
 	if e != nil {
-		// Fallback support for FreeBSD 9, which lacks Pipe2.
-		//
-		// TODO: remove this for Go 1.10 when FreeBSD 9
-		// is removed (Issue 19072).
-
-		// 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 nil, nil, NewSyscallError("pipe", e)
 	}
 
-	return newFile(uintptr(p[0]), "|0", true), newFile(uintptr(p[1]), "|1", true), nil
+	return newFile(uintptr(p[0]), "|0", kindPipe), newFile(uintptr(p[1]), "|1", kindPipe), nil
 }
diff --git a/src/os/pipe_linux.go b/src/os/pipe_linux.go
index 96f2ce9..acd7b88 100644
--- a/src/os/pipe_linux.go
+++ b/src/os/pipe_linux.go
@@ -29,5 +29,5 @@
 		return nil, nil, NewSyscallError("pipe2", e)
 	}
 
-	return newFile(uintptr(p[0]), "|0", true), newFile(uintptr(p[1]), "|1", true), nil
+	return newFile(uintptr(p[0]), "|0", kindPipe), newFile(uintptr(p[1]), "|1", kindPipe), nil
 }
diff --git a/src/os/pipe_test.go b/src/os/pipe_test.go
index 9d79d84..aad6c27 100644
--- a/src/os/pipe_test.go
+++ b/src/os/pipe_test.go
@@ -10,6 +10,7 @@
 import (
 	"fmt"
 	"internal/testenv"
+	"io"
 	"io/ioutil"
 	"os"
 	osexec "os/exec"
@@ -17,6 +18,7 @@
 	"runtime"
 	"strconv"
 	"strings"
+	"sync"
 	"syscall"
 	"testing"
 	"time"
@@ -220,3 +222,86 @@
 		t.Errorf("child process failed: %v", err)
 	}
 }
+
+func TestCloseWithBlockingReadByNewFile(t *testing.T) {
+	var p [2]int
+	err := syscall.Pipe(p[:])
+	if err != nil {
+		t.Fatal(err)
+	}
+	// os.NewFile returns a blocking mode file.
+	testCloseWithBlockingRead(t, os.NewFile(uintptr(p[0]), "reader"), os.NewFile(uintptr(p[1]), "writer"))
+}
+
+func TestCloseWithBlockingReadByFd(t *testing.T) {
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Calling Fd will put the file into blocking mode.
+	_ = r.Fd()
+	testCloseWithBlockingRead(t, r, w)
+}
+
+// Test that we don't let a blocking read prevent a close.
+func testCloseWithBlockingRead(t *testing.T, r, w *os.File) {
+	defer r.Close()
+	defer w.Close()
+
+	c1, c2 := make(chan bool), make(chan bool)
+	var wg sync.WaitGroup
+
+	wg.Add(1)
+	go func(c chan bool) {
+		defer wg.Done()
+		// Give the other goroutine a chance to enter the Read
+		// or Write call. This is sloppy but the test will
+		// pass even if we close before the read/write.
+		time.Sleep(20 * time.Millisecond)
+
+		if err := r.Close(); err != nil {
+			t.Error(err)
+		}
+		close(c)
+	}(c1)
+
+	wg.Add(1)
+	go func(c chan bool) {
+		defer wg.Done()
+		var b [1]byte
+		_, err := r.Read(b[:])
+		close(c)
+		if err == nil {
+			t.Error("I/O on closed pipe unexpectedly succeeded")
+		}
+		if err != io.EOF {
+			t.Errorf("got %v, expected io.EOF", err)
+		}
+	}(c2)
+
+	for c1 != nil || c2 != nil {
+		select {
+		case <-c1:
+			c1 = nil
+			// r.Close has completed, but the blocking Read
+			// is hanging. Close the writer to unblock it.
+			w.Close()
+		case <-c2:
+			c2 = nil
+		case <-time.After(1 * time.Second):
+			switch {
+			case c1 != nil && c2 != nil:
+				t.Error("timed out waiting for Read and Close")
+				w.Close()
+			case c1 != nil:
+				t.Error("timed out waiting for Close")
+			case c2 != nil:
+				t.Error("timed out waiting for Read")
+			default:
+				t.Error("impossible case")
+			}
+		}
+	}
+
+	wg.Wait()
+}
diff --git a/src/os/signal/example_test.go b/src/os/signal/example_test.go
index 5dfbe5f..ecefc75 100644
--- a/src/os/signal/example_test.go
+++ b/src/os/signal/example_test.go
@@ -21,3 +21,18 @@
 	s := <-c
 	fmt.Println("Got signal:", s)
 }
+
+func ExampleNotify_allSignals() {
+	// Set up channel on which to send signal notifications.
+	// We must use a buffered channel or risk missing the signal
+	// if we're not ready to receive when the signal is sent.
+	c := make(chan os.Signal, 1)
+
+	// Passing no signals to Notify means that
+	// all signals will be sent to the channel.
+	signal.Notify(c)
+
+	// Block until any signal is received.
+	s := <-c
+	fmt.Println("Got signal:", s)
+}
diff --git a/src/os/signal/internal/pty/pty.go b/src/os/signal/internal/pty/pty.go
new file mode 100644
index 0000000..c4c1567
--- /dev/null
+++ b/src/os/signal/internal/pty/pty.go
@@ -0,0 +1,57 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux,!android netbsd openbsd
+// +build cgo
+
+// Package pty is a simple pseudo-terminal package for Unix systems,
+// implemented by calling C functions via cgo.
+// This is only used for testing the os/signal package.
+package pty
+
+/*
+#define _XOPEN_SOURCE 600
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+*/
+import "C"
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+)
+
+type PtyError struct {
+	FuncName    string
+	ErrorString string
+	Errno       syscall.Errno
+}
+
+func ptyError(name string, err error) *PtyError {
+	return &PtyError{name, err.Error(), err.(syscall.Errno)}
+}
+
+func (e *PtyError) Error() string {
+	return fmt.Sprintf("%s: %s", e.FuncName, e.ErrorString)
+}
+
+// Open returns a master pty and the name of the linked slave tty.
+func Open() (master *os.File, slave string, err error) {
+	m, err := C.posix_openpt(C.O_RDWR)
+	if err != nil {
+		return nil, "", ptyError("posix_openpt", err)
+	}
+	if _, err := C.grantpt(m); err != nil {
+		C.close(m)
+		return nil, "", ptyError("grantpt", err)
+	}
+	if _, err := C.unlockpt(m); err != nil {
+		C.close(m)
+		return nil, "", ptyError("unlockpt", err)
+	}
+	slave = C.GoString(C.ptsname(m))
+	return os.NewFile(uintptr(m), "pty-master"), slave, nil
+}
diff --git a/src/os/signal/signal_cgo_test.go b/src/os/signal/signal_cgo_test.go
new file mode 100644
index 0000000..84a2a08
--- /dev/null
+++ b/src/os/signal/signal_cgo_test.go
@@ -0,0 +1,232 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux,!android netbsd openbsd
+// +build cgo
+
+// Note that this test does not work on Solaris: issue #22849.
+// Don't run the test on Android because at least some versions of the
+// C library do not define the posix_openpt function.
+
+package signal_test
+
+import (
+	"bufio"
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"os/signal/internal/pty"
+	"strconv"
+	"strings"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestTerminalSignal(t *testing.T) {
+	const enteringRead = "test program entering read"
+	if os.Getenv("GO_TEST_TERMINAL_SIGNALS") != "" {
+		var b [1]byte
+		fmt.Println(enteringRead)
+		n, err := os.Stdin.Read(b[:])
+		if n == 1 {
+			if b[0] == '\n' {
+				// This is what we expect
+				fmt.Println("read newline")
+			} else {
+				fmt.Printf("read 1 byte: %q\n", b)
+			}
+		} else {
+			fmt.Printf("read %d bytes\n", n)
+		}
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+		os.Exit(0)
+	}
+
+	t.Parallel()
+
+	// The test requires a shell that uses job control.
+	bash, err := exec.LookPath("bash")
+	if err != nil {
+		t.Skipf("could not find bash: %v", err)
+	}
+
+	scale := 1
+	if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
+		if sc, err := strconv.Atoi(s); err == nil {
+			scale = sc
+		}
+	}
+	pause := time.Duration(scale) * 10 * time.Millisecond
+	wait := time.Duration(scale) * 5 * time.Second
+
+	// The test only fails when using a "slow device," in this
+	// case a pseudo-terminal.
+
+	master, sname, err := pty.Open()
+	if err != nil {
+		ptyErr := err.(*pty.PtyError)
+		if ptyErr.FuncName == "posix_openpt" && ptyErr.Errno == syscall.EACCES {
+			t.Skip("posix_openpt failed with EACCES, assuming chroot and skipping")
+		}
+		t.Fatal(err)
+	}
+	defer master.Close()
+	slave, err := os.OpenFile(sname, os.O_RDWR, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer slave.Close()
+
+	// Start an interactive shell.
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	cmd := exec.CommandContext(ctx, bash, "--norc", "--noprofile", "-i")
+	cmd.Stdin = slave
+	cmd.Stdout = slave
+	cmd.Stderr = slave
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		Setsid:  true,
+		Setctty: true,
+		Ctty:    int(slave.Fd()),
+	}
+
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := slave.Close(); err != nil {
+		t.Errorf("closing slave: %v", err)
+	}
+
+	progReady := make(chan bool)
+	sawPrompt := make(chan bool, 10)
+	const prompt = "prompt> "
+
+	// Read data from master in the background.
+	go func() {
+		input := bufio.NewReader(master)
+		var line, handled []byte
+		for {
+			b, err := input.ReadByte()
+			if err != nil {
+				if len(line) > 0 || len(handled) > 0 {
+					t.Logf("%q", append(handled, line...))
+				}
+				if perr, ok := err.(*os.PathError); ok {
+					err = perr.Err
+				}
+				// EOF means master is closed.
+				// EIO means child process is done.
+				// "file already closed" means deferred close of master has happened.
+				if err != io.EOF && err != syscall.EIO && !strings.Contains(err.Error(), "file already closed") {
+					t.Logf("error reading from master: %v", err)
+				}
+				return
+			}
+
+			line = append(line, b)
+
+			if b == '\n' {
+				t.Logf("%q", append(handled, line...))
+				line = nil
+				handled = nil
+				continue
+			}
+
+			if bytes.Contains(line, []byte(enteringRead)) {
+				close(progReady)
+				handled = append(handled, line...)
+				line = nil
+			} else if bytes.Contains(line, []byte(prompt)) && !bytes.Contains(line, []byte("PS1=")) {
+				sawPrompt <- true
+				handled = append(handled, line...)
+				line = nil
+			}
+		}
+	}()
+
+	// Set the bash prompt so that we can see it.
+	if _, err := master.Write([]byte("PS1='" + prompt + "'\n")); err != nil {
+		t.Fatalf("setting prompt: %v", err)
+	}
+	select {
+	case <-sawPrompt:
+	case <-time.After(wait):
+		t.Fatal("timed out waiting for shell prompt")
+	}
+
+	// Start a small program that reads from stdin
+	// (namely the code at the top of this function).
+	if _, err := master.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil {
+		t.Fatal(err)
+	}
+
+	// Wait for the program to print that it is starting.
+	select {
+	case <-progReady:
+	case <-time.After(wait):
+		t.Fatal("timed out waiting for program to start")
+	}
+
+	// Give the program time to enter the read call.
+	// It doesn't matter much if we occasionally don't wait long enough;
+	// we won't be testing what we want to test, but the overall test
+	// will pass.
+	time.Sleep(pause)
+
+	// Send a ^Z to stop the program.
+	if _, err := master.Write([]byte{26}); err != nil {
+		t.Fatalf("writing ^Z to pty: %v", err)
+	}
+
+	// Wait for the program to stop and return to the shell.
+	select {
+	case <-sawPrompt:
+	case <-time.After(wait):
+		t.Fatal("timed out waiting for shell prompt")
+	}
+
+	// Restart the stopped program.
+	if _, err := master.Write([]byte("fg\n")); err != nil {
+		t.Fatalf("writing %q to pty: %v", "fg", err)
+	}
+
+	// Give the process time to restart.
+	// This is potentially racy: if the process does not restart
+	// quickly enough then the byte we send will go to bash rather
+	// than the program. Unfortunately there isn't anything we can
+	// look for to know that the program is running again.
+	// bash will print the program name, but that happens before it
+	// restarts the program.
+	time.Sleep(10 * pause)
+
+	// Write some data for the program to read,
+	// which should cause it to exit.
+	if _, err := master.Write([]byte{'\n'}); err != nil {
+		t.Fatalf("writing %q to pty: %v", "\n", err)
+	}
+
+	// Wait for the program to exit.
+	select {
+	case <-sawPrompt:
+	case <-time.After(wait):
+		t.Fatal("timed out waiting for shell prompt")
+	}
+
+	// Exit the shell with the program's exit status.
+	if _, err := master.Write([]byte("exit $?\n")); err != nil {
+		t.Fatalf("writing %q to pty: %v", "exit", err)
+	}
+
+	if err = cmd.Wait(); err != nil {
+		t.Errorf("subprogram failed: %v", err)
+	}
+}
diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go
index dea2add..e4df8af 100644
--- a/src/os/signal/signal_test.go
+++ b/src/os/signal/signal_test.go
@@ -321,7 +321,9 @@
 		cmd.Env = append(os.Environ(), "GO_TEST_ATOMIC_STOP=1")
 		out, err := cmd.CombinedOutput()
 		if err == nil {
-			t.Logf("iteration %d: output %s", i, out)
+			if len(out) > 0 {
+				t.Logf("iteration %d: output %s", i, out)
+			}
 		} else {
 			t.Logf("iteration %d: exit status %q: output: %s", i, err, out)
 		}
@@ -378,7 +380,7 @@
 		case <-cs:
 		case <-time.After(1 * time.Second):
 			if !printed {
-				fmt.Print("lost signal on iterations:")
+				fmt.Print("lost signal on tries:")
 				printed = true
 			}
 			fmt.Printf(" %d", i)
diff --git a/src/os/stat.go b/src/os/stat.go
new file mode 100644
index 0000000..af66838
--- /dev/null
+++ b/src/os/stat.go
@@ -0,0 +1,23 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import "internal/testlog"
+
+// Stat returns a FileInfo describing the named file.
+// If there is an error, it will be of type *PathError.
+func Stat(name string) (FileInfo, error) {
+	testlog.Stat(name)
+	return statNolog(name)
+}
+
+// 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) (FileInfo, error) {
+	testlog.Stat(name)
+	return lstatNolog(name)
+}
diff --git a/src/os/stat_plan9.go b/src/os/stat_plan9.go
index 274d0d8..8057fd4 100644
--- a/src/os/stat_plan9.go
+++ b/src/os/stat_plan9.go
@@ -86,9 +86,8 @@
 	return nil, &PathError{"stat", name, err}
 }
 
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (FileInfo, error) {
+// statNolog implements Stat for Plan 9.
+func statNolog(name string) (FileInfo, error) {
 	d, err := dirstat(name)
 	if err != nil {
 		return nil, err
@@ -96,12 +95,9 @@
 	return fileInfoFromStat(d), 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) (FileInfo, error) {
-	return Stat(name)
+// lstatNolog implements Lstat for Plan 9.
+func lstatNolog(name string) (FileInfo, error) {
+	return statNolog(name)
 }
 
 // For testing.
diff --git a/src/os/stat_unix.go b/src/os/stat_unix.go
index 1dd5714..b584171 100644
--- a/src/os/stat_unix.go
+++ b/src/os/stat_unix.go
@@ -25,9 +25,8 @@
 	return &fs, nil
 }
 
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (FileInfo, error) {
+// statNolog stats a file with no test logging.
+func statNolog(name string) (FileInfo, error) {
 	var fs fileStat
 	err := syscall.Stat(name, &fs.sys)
 	if err != nil {
@@ -37,11 +36,8 @@
 	return &fs, 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) (FileInfo, error) {
+// lstatNolog lstats a file with no test logging.
+func lstatNolog(name string) (FileInfo, error) {
 	var fs fileStat
 	err := syscall.Lstat(name, &fs.sys)
 	if err != nil {
diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go
index e7a4e0d..5ec5642 100644
--- a/src/os/stat_windows.go
+++ b/src/os/stat_windows.go
@@ -56,9 +56,8 @@
 	}, 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) (FileInfo, error) {
+// statNolog implements Stat for Windows.
+func statNolog(name string) (FileInfo, error) {
 	if len(name) == 0 {
 		return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
 	}
@@ -69,7 +68,7 @@
 	if err != nil {
 		return nil, &PathError{"Stat", name, err}
 	}
-	// Apparently (see https://github.com/golang/go/issues/19922#issuecomment-300031421)
+	// Apparently (see https://golang.org/issues/19922#issuecomment-300031421)
 	// GetFileAttributesEx is fastest approach to get file info.
 	// It does not work for symlinks. But symlinks are rare,
 	// so try GetFileAttributesEx first.
@@ -156,11 +155,8 @@
 	}, 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) (FileInfo, error) {
+// lstatNolog implements Lstat for Windows.
+func lstatNolog(name string) (FileInfo, error) {
 	if len(name) == 0 {
 		return nil, &PathError{"Lstat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
 	}
diff --git a/src/os/sys_freebsd.go b/src/os/sys_freebsd.go
index 273c2df..3ec49fa 100644
--- a/src/os/sys_freebsd.go
+++ b/src/os/sys_freebsd.go
@@ -4,20 +4,7 @@
 
 package os
 
-import "syscall"
-
 // supportsCloseOnExec reports whether the platform supports the
 // O_CLOEXEC flag.
-var supportsCloseOnExec bool
-
-func init() {
-	osrel, err := syscall.SysctlUint32("kern.osreldate")
-	if err != nil {
-		return
-	}
-	// The O_CLOEXEC flag was introduced in FreeBSD 8.3.
-	// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
-	if osrel >= 803000 {
-		supportsCloseOnExec = true
-	}
-}
+// The O_CLOEXEC flag was introduced in FreeBSD 8.3.
+const supportsCloseOnExec bool = true
diff --git a/src/os/sys_windows.go b/src/os/sys_windows.go
index f6da88c..72ad90b 100644
--- a/src/os/sys_windows.go
+++ b/src/os/sys_windows.go
@@ -24,7 +24,7 @@
 			return "", NewSyscallError("ComputerNameEx", err)
 		}
 
-		// If we received a ERROR_MORE_DATA, but n doesn't get larger,
+		// If we received an ERROR_MORE_DATA, but n doesn't get larger,
 		// something has gone wrong and we may be in an infinite loop
 		if n <= uint32(len(b)) {
 			return "", NewSyscallError("ComputerNameEx", err)
diff --git a/src/os/timeout_test.go b/src/os/timeout_test.go
new file mode 100644
index 0000000..6f47ed0
--- /dev/null
+++ b/src/os/timeout_test.go
@@ -0,0 +1,589 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !nacl
+// +build !plan9
+// +build !windows
+
+package os_test
+
+import (
+	"fmt"
+	"internal/poll"
+	"io"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"runtime"
+	"sync"
+	"testing"
+	"time"
+)
+
+func TestNonpollableDeadline(t *testing.T) {
+	// On BSD systems regular files seem to be pollable,
+	// so just run this test on Linux.
+	if runtime.GOOS != "linux" {
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	f, err := ioutil.TempFile("", "ostest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(f.Name())
+	defer f.Close()
+	deadline := time.Now().Add(10 * time.Second)
+	if err := f.SetDeadline(deadline); err != os.ErrNoDeadline {
+		t.Errorf("SetDeadline on file returned %v, wanted %v", err, os.ErrNoDeadline)
+	}
+	if err := f.SetReadDeadline(deadline); err != os.ErrNoDeadline {
+		t.Errorf("SetReadDeadline on file returned %v, wanted %v", err, os.ErrNoDeadline)
+	}
+	if err := f.SetWriteDeadline(deadline); err != os.ErrNoDeadline {
+		t.Errorf("SetWriteDeadline on file returned %v, wanted %v", err, os.ErrNoDeadline)
+	}
+}
+
+// noDeadline is a zero time.Time value, which cancels a deadline.
+var noDeadline time.Time
+
+var readTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that read deadlines work, even if there's data ready
+	// to be read.
+	{-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+
+	{50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+}
+
+func TestReadTimeout(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	if _, err := w.Write([]byte("READ TIMEOUT TEST")); err != nil {
+		t.Fatal(err)
+	}
+
+	for i, tt := range readTimeoutTests {
+		if err := r.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		var b [1]byte
+		for j, xerr := range tt.xerrs {
+			for {
+				n, err := r.Read(b[:])
+				if xerr != nil {
+					if !os.IsTimeout(err) {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				if n != 0 {
+					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
+				}
+				break
+			}
+		}
+	}
+}
+
+func TestReadTimeoutMustNotReturn(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	max := time.NewTimer(100 * time.Millisecond)
+	defer max.Stop()
+	ch := make(chan error)
+	go func() {
+		if err := r.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := r.SetWriteDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := r.SetReadDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		var b [1]byte
+		_, err := r.Read(b[:])
+		ch <- err
+	}()
+
+	select {
+	case err := <-ch:
+		t.Fatalf("expected Read to not return, but it returned with %v", err)
+	case <-max.C:
+		w.Close()
+		err := <-ch // wait for tester goroutine to stop
+		if os.IsTimeout(err) {
+			t.Fatal(err)
+		}
+	}
+}
+
+var writeTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that write deadlines work, even if there's buffer
+	// space available to write.
+	{-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+
+	{10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+}
+
+func TestWriteTimeout(t *testing.T) {
+	t.Parallel()
+
+	for i, tt := range writeTimeoutTests {
+		t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
+			r, w, err := os.Pipe()
+			if err != nil {
+				t.Fatal(err)
+			}
+			defer r.Close()
+			defer w.Close()
+
+			if err := w.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
+				t.Fatalf("%v", err)
+			}
+			for j, xerr := range tt.xerrs {
+				for {
+					n, err := w.Write([]byte("WRITE TIMEOUT TEST"))
+					if xerr != nil {
+						if !os.IsTimeout(err) {
+							t.Fatalf("%d: %v", j, err)
+						}
+					}
+					if err == nil {
+						time.Sleep(tt.timeout / 3)
+						continue
+					}
+					if n != 0 {
+						t.Fatalf("%d: wrote %d; want 0", j, n)
+					}
+					break
+				}
+			}
+		})
+	}
+}
+
+func TestWriteTimeoutMustNotReturn(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	max := time.NewTimer(100 * time.Millisecond)
+	defer max.Stop()
+	ch := make(chan error)
+	go func() {
+		if err := w.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := w.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := w.SetWriteDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		var b [1]byte
+		for {
+			if _, err := w.Write(b[:]); err != nil {
+				ch <- err
+				break
+			}
+		}
+	}()
+
+	select {
+	case err := <-ch:
+		t.Fatalf("expected Write to not return, but it returned with %v", err)
+	case <-max.C:
+		r.Close()
+		err := <-ch // wait for tester goroutine to stop
+		if os.IsTimeout(err) {
+			t.Fatal(err)
+		}
+	}
+}
+
+func timeoutReader(r *os.File, d, min, max time.Duration, ch chan<- error) {
+	var err error
+	defer func() { ch <- err }()
+
+	t0 := time.Now()
+	if err = r.SetReadDeadline(time.Now().Add(d)); err != nil {
+		return
+	}
+	b := make([]byte, 256)
+	var n int
+	n, err = r.Read(b)
+	t1 := time.Now()
+	if n != 0 || err == nil || !os.IsTimeout(err) {
+		err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
+		return
+	}
+	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
+		err = fmt.Errorf("Read took %s; expected %s", dt, d)
+		return
+	}
+}
+
+func TestReadTimeoutFluctuation(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	max := time.NewTimer(time.Second)
+	defer max.Stop()
+	ch := make(chan error)
+	go timeoutReader(r, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
+
+	select {
+	case <-max.C:
+		t.Fatal("Read took over 1s; expected 0.1s")
+	case err := <-ch:
+		if !os.IsTimeout(err) {
+			t.Fatal(err)
+		}
+	}
+}
+
+func timeoutWriter(w *os.File, d, min, max time.Duration, ch chan<- error) {
+	var err error
+	defer func() { ch <- err }()
+
+	t0 := time.Now()
+	if err = w.SetWriteDeadline(time.Now().Add(d)); err != nil {
+		return
+	}
+	var n int
+	for {
+		n, err = w.Write([]byte("TIMEOUT WRITER"))
+		if err != nil {
+			break
+		}
+	}
+	t1 := time.Now()
+	if err == nil || !os.IsTimeout(err) {
+		err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
+		return
+	}
+	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
+		err = fmt.Errorf("Write took %s; expected %s", dt, d)
+		return
+	}
+}
+
+func TestWriteTimeoutFluctuation(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	d := time.Second
+	max := time.NewTimer(d)
+	defer max.Stop()
+	ch := make(chan error)
+	go timeoutWriter(w, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
+
+	select {
+	case <-max.C:
+		t.Fatalf("Write took over %v; expected 0.1s", d)
+	case err := <-ch:
+		if !os.IsTimeout(err) {
+			t.Fatal(err)
+		}
+	}
+}
+
+func TestVariousDeadlines(t *testing.T) {
+	t.Parallel()
+	testVariousDeadlines(t)
+}
+
+func TestVariousDeadlines1Proc(t *testing.T) {
+	// Cannot use t.Parallel - modifies global GOMAXPROCS.
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+	testVariousDeadlines(t)
+}
+
+func TestVariousDeadlines4Proc(t *testing.T) {
+	// Cannot use t.Parallel - modifies global GOMAXPROCS.
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	testVariousDeadlines(t)
+}
+
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (int, error) {
+	for i := range p {
+		p[i] = byte(b)
+	}
+	return len(p), nil
+}
+
+func testVariousDeadlines(t *testing.T) {
+	type result struct {
+		n   int64
+		err error
+		d   time.Duration
+	}
+
+	handler := func(w *os.File, pasvch chan result) {
+		// The writer, with no timeouts of its own,
+		// sending bytes to clients as fast as it can.
+		t0 := time.Now()
+		n, err := io.Copy(w, neverEnding('a'))
+		dt := time.Since(t0)
+		pasvch <- result{n, err, dt}
+	}
+
+	for _, timeout := range []time.Duration{
+		1 * time.Nanosecond,
+		2 * time.Nanosecond,
+		5 * time.Nanosecond,
+		50 * time.Nanosecond,
+		100 * time.Nanosecond,
+		200 * time.Nanosecond,
+		500 * time.Nanosecond,
+		750 * time.Nanosecond,
+		1 * time.Microsecond,
+		5 * time.Microsecond,
+		25 * time.Microsecond,
+		250 * time.Microsecond,
+		500 * time.Microsecond,
+		1 * time.Millisecond,
+		5 * time.Millisecond,
+		100 * time.Millisecond,
+		250 * time.Millisecond,
+		500 * time.Millisecond,
+		1 * time.Second,
+	} {
+		numRuns := 3
+		if testing.Short() {
+			numRuns = 1
+			if timeout > 500*time.Microsecond {
+				continue
+			}
+		}
+		for run := 0; run < numRuns; run++ {
+			t.Run(fmt.Sprintf("%v-%d", timeout, run+1), func(t *testing.T) {
+				r, w, err := os.Pipe()
+				if err != nil {
+					t.Fatal(err)
+				}
+				defer r.Close()
+				defer w.Close()
+
+				pasvch := make(chan result)
+				go handler(w, pasvch)
+
+				tooLong := 5 * time.Second
+				max := time.NewTimer(tooLong)
+				defer max.Stop()
+				actvch := make(chan result)
+				go func() {
+					t0 := time.Now()
+					if err := r.SetDeadline(t0.Add(timeout)); err != nil {
+						t.Error(err)
+					}
+					n, err := io.Copy(ioutil.Discard, r)
+					dt := time.Since(t0)
+					r.Close()
+					actvch <- result{n, err, dt}
+				}()
+
+				select {
+				case res := <-actvch:
+					if os.IsTimeout(res.err) {
+						t.Logf("good client timeout after %v, reading %d bytes", res.d, res.n)
+					} else {
+						t.Fatalf("client Copy = %d, %v; want timeout", res.n, res.err)
+					}
+				case <-max.C:
+					t.Fatalf("timeout (%v) waiting for client to timeout (%v) reading", tooLong, timeout)
+				}
+
+				select {
+				case res := <-pasvch:
+					t.Logf("writer in %v wrote %d: %v", res.d, res.n, res.err)
+				case <-max.C:
+					t.Fatalf("timeout waiting for writer to finish writing")
+				}
+			})
+		}
+	}
+}
+
+func TestReadWriteDeadlineRace(t *testing.T) {
+	t.Parallel()
+
+	N := 1000
+	if testing.Short() {
+		N = 50
+	}
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	var wg sync.WaitGroup
+	wg.Add(3)
+	go func() {
+		defer wg.Done()
+		tic := time.NewTicker(2 * time.Microsecond)
+		defer tic.Stop()
+		for i := 0; i < N; i++ {
+			if err := r.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
+				break
+			}
+			if err := w.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
+				break
+			}
+			<-tic.C
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		var b [1]byte
+		for i := 0; i < N; i++ {
+			_, err := r.Read(b[:])
+			if err != nil && !os.IsTimeout(err) {
+				t.Error("Read returned non-timeout error", err)
+			}
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		var b [1]byte
+		for i := 0; i < N; i++ {
+			_, err := w.Write(b[:])
+			if err != nil && !os.IsTimeout(err) {
+				t.Error("Write returned non-timeout error", err)
+			}
+		}
+	}()
+	wg.Wait() // wait for tester goroutine to stop
+}
+
+// TestRacyRead tests that it is safe to mutate the input Read buffer
+// immediately after cancelation has occurred.
+func TestRacyRead(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	var wg sync.WaitGroup
+	defer wg.Wait()
+
+	go io.Copy(w, rand.New(rand.NewSource(0)))
+
+	r.SetReadDeadline(time.Now().Add(time.Millisecond))
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			b1 := make([]byte, 1024)
+			b2 := make([]byte, 1024)
+			for j := 0; j < 100; j++ {
+				_, err := r.Read(b1)
+				copy(b1, b2) // Mutate b1 to trigger potential race
+				if err != nil {
+					if !os.IsTimeout(err) {
+						t.Error(err)
+					}
+					r.SetReadDeadline(time.Now().Add(time.Millisecond))
+				}
+			}
+		}()
+	}
+}
+
+// TestRacyWrite tests that it is safe to mutate the input Write buffer
+// immediately after cancelation has occurred.
+func TestRacyWrite(t *testing.T) {
+	t.Parallel()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	defer w.Close()
+
+	var wg sync.WaitGroup
+	defer wg.Wait()
+
+	go io.Copy(ioutil.Discard, r)
+
+	w.SetWriteDeadline(time.Now().Add(time.Millisecond))
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			b1 := make([]byte, 1024)
+			b2 := make([]byte, 1024)
+			for j := 0; j < 100; j++ {
+				_, err := w.Write(b1)
+				copy(b1, b2) // Mutate b1 to trigger potential race
+				if err != nil {
+					if !os.IsTimeout(err) {
+						t.Error(err)
+					}
+					w.SetWriteDeadline(time.Now().Add(time.Millisecond))
+				}
+			}
+		}()
+	}
+}
diff --git a/src/os/user/cgo_lookup_unix.go b/src/os/user/cgo_lookup_unix.go
index 58ecf32..987a2d8 100644
--- a/src/os/user/cgo_lookup_unix.go
+++ b/src/os/user/cgo_lookup_unix.go
@@ -52,8 +52,8 @@
 func lookupUser(username string) (*User, error) {
 	var pwd C.struct_passwd
 	var result *C.struct_passwd
-	nameC := C.CString(username)
-	defer C.free(unsafe.Pointer(nameC))
+	nameC := make([]byte, len(username)+1)
+	copy(nameC, username)
 
 	buf := alloc(userBuffer)
 	defer buf.free()
@@ -63,7 +63,7 @@
 		// passing a size_t to getpwnam_r, because for unknown
 		// reasons passing a size_t to getpwnam_r doesn't work on
 		// Solaris.
-		return syscall.Errno(C.mygetpwnam_r(nameC,
+		return syscall.Errno(C.mygetpwnam_r((*C.char)(unsafe.Pointer(&nameC[0])),
 			&pwd,
 			(*C.char)(buf.ptr),
 			C.size_t(buf.size),
@@ -114,8 +114,8 @@
 
 func buildUser(pwd *C.struct_passwd) *User {
 	u := &User{
-		Uid:      strconv.Itoa(int(pwd.pw_uid)),
-		Gid:      strconv.Itoa(int(pwd.pw_gid)),
+		Uid:      strconv.FormatUint(uint64(pwd.pw_uid), 10),
+		Gid:      strconv.FormatUint(uint64(pwd.pw_gid), 10),
 		Username: C.GoString(pwd.pw_name),
 		Name:     C.GoString(pwd.pw_gecos),
 		HomeDir:  C.GoString(pwd.pw_dir),
@@ -140,11 +140,11 @@
 
 	buf := alloc(groupBuffer)
 	defer buf.free()
-	cname := C.CString(groupname)
-	defer C.free(unsafe.Pointer(cname))
+	cname := make([]byte, len(groupname)+1)
+	copy(cname, groupname)
 
 	err := retryWithBuffer(buf, func() syscall.Errno {
-		return syscall.Errno(C.mygetgrnam_r(cname,
+		return syscall.Errno(C.mygetgrnam_r((*C.char)(unsafe.Pointer(&cname[0])),
 			&grp,
 			(*C.char)(buf.ptr),
 			C.size_t(buf.size),
@@ -269,3 +269,11 @@
 func isSizeReasonable(sz int64) bool {
 	return sz > 0 && sz <= maxBufferSize
 }
+
+// Because we can't use cgo in tests:
+func structPasswdForNegativeTest() C.struct_passwd {
+	sp := C.struct_passwd{}
+	sp.pw_uid = 1<<32 - 2
+	sp.pw_gid = 1<<32 - 3
+	return sp
+}
diff --git a/src/os/user/cgo_unix_test.go b/src/os/user/cgo_unix_test.go
new file mode 100644
index 0000000..6741118
--- /dev/null
+++ b/src/os/user/cgo_unix_test.go
@@ -0,0 +1,24 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
+// +build cgo
+
+package user
+
+import (
+	"testing"
+)
+
+// Issue 22739
+func TestNegativeUid(t *testing.T) {
+	sp := structPasswdForNegativeTest()
+	u := buildUser(&sp)
+	if g, w := u.Uid, "4294967294"; g != w {
+		t.Errorf("Uid = %q; want %q", g, w)
+	}
+	if g, w := u.Gid, "4294967293"; g != w {
+		t.Errorf("Gid = %q; want %q", g, w)
+	}
+}
diff --git a/src/os/user/getgrouplist_darwin.go b/src/os/user/getgrouplist_darwin.go
index 54a2da3..935c6de 100644
--- a/src/os/user/getgrouplist_darwin.go
+++ b/src/os/user/getgrouplist_darwin.go
@@ -23,7 +23,30 @@
 }
 */
 import "C"
+import (
+	"fmt"
+	"unsafe"
+)
 
 func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int {
 	return C.mygetgrouplist(name, userGID, gids, n)
 }
+
+// groupRetry retries getGroupList with an increasingly large size for n. The
+// result is stored in gids.
+func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error {
+	*n = C.int(256 * 2)
+	for {
+		*gids = make([]C.gid_t, *n)
+		rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
+		if rv >= 0 {
+			// n is set correctly
+			break
+		}
+		if *n > maxGroups {
+			return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
+		}
+		*n = *n * C.int(2)
+	}
+	return nil
+}
diff --git a/src/os/user/getgrouplist_unix.go b/src/os/user/getgrouplist_unix.go
index 14da7c0..8ad5128 100644
--- a/src/os/user/getgrouplist_unix.go
+++ b/src/os/user/getgrouplist_unix.go
@@ -16,7 +16,26 @@
 }
 */
 import "C"
+import (
+	"fmt"
+	"unsafe"
+)
 
 func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int {
 	return C.mygetgrouplist(name, userGID, gids, n)
 }
+
+// groupRetry retries getGroupList with much larger size for n. The result is
+// stored in gids.
+func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error {
+	// More than initial buffer, but now n contains the correct size.
+	if *n > maxGroups {
+		return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
+	}
+	*gids = make([]C.gid_t, *n)
+	rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
+	if rv == -1 {
+		return fmt.Errorf("user: list groups for %s failed", username)
+	}
+	return nil
+}
diff --git a/src/os/user/listgroups_unix.go b/src/os/user/listgroups_unix.go
index db952c6..44f4ae1 100644
--- a/src/os/user/listgroups_unix.go
+++ b/src/os/user/listgroups_unix.go
@@ -15,32 +15,28 @@
 /*
 #include <unistd.h>
 #include <sys/types.h>
-#include <stdlib.h>
 */
 import "C"
 
+const maxGroups = 2048
+
 func listGroups(u *User) ([]string, error) {
 	ug, err := strconv.Atoi(u.Gid)
 	if err != nil {
 		return nil, fmt.Errorf("user: list groups for %s: invalid gid %q", u.Username, u.Gid)
 	}
 	userGID := C.gid_t(ug)
-	nameC := C.CString(u.Username)
-	defer C.free(unsafe.Pointer(nameC))
+	nameC := make([]byte, len(u.Username)+1)
+	copy(nameC, u.Username)
 
 	n := C.int(256)
 	gidsC := make([]C.gid_t, n)
-	rv := getGroupList(nameC, userGID, &gidsC[0], &n)
+	rv := getGroupList((*C.char)(unsafe.Pointer(&nameC[0])), userGID, &gidsC[0], &n)
 	if rv == -1 {
-		// More than initial buffer, but now n contains the correct size.
-		const maxGroups = 2048
-		if n > maxGroups {
-			return nil, fmt.Errorf("user: list groups for %s: member of more than %d groups", u.Username, maxGroups)
-		}
-		gidsC = make([]C.gid_t, n)
-		rv := getGroupList(nameC, userGID, &gidsC[0], &n)
-		if rv == -1 {
-			return nil, fmt.Errorf("user: list groups for %s failed (changed groups?)", u.Username)
+		// Mac is the only Unix that does not set n properly when rv == -1, so
+		// we need to use different logic for Mac vs. the other OS's.
+		if err := groupRetry(u.Username, nameC, userGID, &gidsC, &n); err != nil {
+			return nil, err
 		}
 	}
 	gidsC = gidsC[:n]
diff --git a/src/os/wait_wait6.go b/src/os/wait_wait6.go
index b309811..891f242 100644
--- a/src/os/wait_wait6.go
+++ b/src/os/wait_wait6.go
@@ -30,11 +30,6 @@
 	}
 	runtime.KeepAlive(p)
 	if errno != 0 {
-		// The wait6 system call is supported only on FreeBSD
-		// 9.3 and above, so it may return an ENOSYS error.
-		if errno == syscall.ENOSYS {
-			return false, nil
-		}
 		return false, NewSyscallError("wait6", errno)
 	}
 	return true, nil
diff --git a/src/path/example_test.go b/src/path/example_test.go
index 07f9de3..d962e3d 100644
--- a/src/path/example_test.go
+++ b/src/path/example_test.go
@@ -47,11 +47,15 @@
 func ExampleDir() {
 	fmt.Println(path.Dir("/a/b/c"))
 	fmt.Println(path.Dir("a/b/c"))
+	fmt.Println(path.Dir("/a/"))
+	fmt.Println(path.Dir("a/"))
 	fmt.Println(path.Dir("/"))
 	fmt.Println(path.Dir(""))
 	// Output:
 	// /a/b
 	// a/b
+	// /a
+	// a
 	// /
 	// .
 }
diff --git a/src/path/filepath/example_test.go b/src/path/filepath/example_test.go
new file mode 100644
index 0000000..a1d680e
--- /dev/null
+++ b/src/path/filepath/example_test.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath_test
+
+import (
+	"fmt"
+	"path/filepath"
+)
+
+func ExampleExt() {
+	fmt.Printf("No dots: %q\n", filepath.Ext("index"))
+	fmt.Printf("One dot: %q\n", filepath.Ext("index.js"))
+	fmt.Printf("Two dots: %q\n", filepath.Ext("main.test.js"))
+	// Output:
+	// No dots: ""
+	// One dot: ".js"
+	// Two dots: ".js"
+}
diff --git a/src/path/filepath/example_unix_test.go b/src/path/filepath/example_unix_test.go
index cd8233c..40bc547 100644
--- a/src/path/filepath/example_unix_test.go
+++ b/src/path/filepath/example_unix_test.go
@@ -8,6 +8,7 @@
 
 import (
 	"fmt"
+	"os"
 	"path/filepath"
 )
 
@@ -79,3 +80,24 @@
 	// a/b/c
 	// a/b/c
 }
+func ExampleWalk() {
+	dir := "dir/to/walk"
+	subDirToSkip := "skip" // dir/to/walk/skip
+
+	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", dir, err)
+			return err
+		}
+		if info.IsDir() && info.Name() == subDirToSkip {
+			fmt.Printf("skipping a dir without errors: %+v \n", info.Name())
+			return filepath.SkipDir
+		}
+		fmt.Printf("visited file: %q\n", path)
+		return nil
+	})
+
+	if err != nil {
+		fmt.Printf("error walking the path %q: %v\n", dir, err)
+	}
+}
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go
index c242143..87f8faf 100644
--- a/src/path/filepath/path.go
+++ b/src/path/filepath/path.go
@@ -351,23 +351,23 @@
 
 var lstat = os.Lstat // for testing
 
-// walk recursively descends path, calling w.
+// walk recursively descends path, calling walkFn.
 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
+		return walkFn(path, info, nil)
 	}
 
 	names, err := readDirNames(path)
-	if err != nil {
-		return walkFn(path, info, err)
+	err1 := walkFn(path, info, err)
+	// If err != nil, walk can't walk into this directory.
+	// err1 != nil means walkFn want walk to skip this directory or stop walking.
+	// Therefore, if one of err and err1 isn't nil, walk will return.
+	if err != nil || err1 != nil {
+		// The caller's behavior is controlled by the return value, which is decided
+		// by walkFn. walkFn may ignore err and return nil.
+		// If walkFn returns SkipDir, it will be handled by the caller.
+		// So walk should return whatever walkFn returns.
+		return err1
 	}
 
 	for _, name := range names {
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index 315f61e..3ebd3fb 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -389,6 +389,12 @@
 // If clear is true, any incoming error is cleared before return. The errors
 // are always accumulated, though.
 func mark(info os.FileInfo, err error, errors *[]error, clear bool) error {
+	name := info.Name()
+	walkTree(tree, tree.name, func(path string, n *Node) {
+		if n.name == name {
+			n.mark++
+		}
+	})
 	if err != nil {
 		*errors = append(*errors, err)
 		if clear {
@@ -396,12 +402,6 @@
 		}
 		return err
 	}
-	name := info.Name()
-	walkTree(tree, tree.name, func(path string, n *Node) {
-		if n.name == name {
-			n.mark++
-		}
-	})
 	return nil
 }
 
@@ -771,24 +771,50 @@
 	{"test/linkabs", "/"},
 }
 
-// findEvalSymlinksTestDirsDest searches testDirs
-// for matching path and returns correspondent dest.
-func findEvalSymlinksTestDirsDest(t *testing.T, testDirs []EvalSymlinksTest, path string) string {
-	for _, d := range testDirs {
-		if d.path == path {
-			return d.dest
-		}
-	}
-	t.Fatalf("did not find %q in testDirs slice", path)
-	return ""
-}
-
 // 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, path, want string) {
+	have, err := filepath.EvalSymlinks(path)
+	if err != nil {
+		t.Errorf("EvalSymlinks(%q) error: %v", path, err)
+		return
+	}
+	if filepath.Clean(have) != filepath.Clean(want) {
+		t.Errorf("EvalSymlinks(%q) returns %q, want %q", path, have, want)
+	}
+}
+
+func testEvalSymlinksAfterChdir(t *testing.T, wd, path, want string) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		err := os.Chdir(cwd)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}()
+
+	err = os.Chdir(wd)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	have, err := filepath.EvalSymlinks(path)
+	if err != nil {
+		t.Errorf("EvalSymlinks(%q) in %q directory error: %v", path, wd, err)
+		return
+	}
+	if filepath.Clean(have) != filepath.Clean(want) {
+		t.Errorf("EvalSymlinks(%q) in %q directory returns %q, want %q", path, wd, have, want)
+	}
+}
+
 func TestEvalSymlinks(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
@@ -805,22 +831,8 @@
 		t.Fatal("eval symlink for tmp dir:", err)
 	}
 
-	tests := EvalSymlinksTests
-	testdirs := EvalSymlinksTestDirs
-	if runtime.GOOS == "windows" {
-		if len(tmpDir) < 3 {
-			t.Fatalf("tmpDir path %q is too short", tmpDir)
-		}
-		if tmpDir[1] != ':' {
-			t.Fatalf("tmpDir path %q must have drive letter in it", tmpDir)
-		}
-		newtest := EvalSymlinksTest{"test/linkabswin", tmpDir[:3]}
-		tests = append(tests, newtest)
-		testdirs = append(testdirs, newtest)
-	}
-
 	// Create the symlink farm using relative paths.
-	for _, d := range testdirs {
+	for _, d := range EvalSymlinksTestDirs {
 		var err error
 		path := simpleJoin(tmpDir, d.path)
 		if d.dest == "" {
@@ -833,135 +845,37 @@
 		}
 	}
 
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-
 	// 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
+	for _, test := range EvalSymlinksTests {
+		path := simpleJoin(tmpDir, test.path)
+
+		dest := simpleJoin(tmpDir, test.dest)
+		if filepath.IsAbs(test.dest) || os.IsPathSeparator(test.dest[0]) {
+			dest = test.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("EvalSymlinks(%q)=%q, want %q", path, p, dest)
-		}
+		testEvalSymlinks(t, path, dest)
 
 		// test EvalSymlinks(".")
-		func() {
-			defer func() {
-				err := os.Chdir(wd)
-				if err != nil {
-					t.Fatal(err)
-				}
-			}()
-
-			err := os.Chdir(path)
-			if err != nil {
-				t.Error(err)
-				return
-			}
-			p, err := filepath.EvalSymlinks(".")
-			if err != nil {
-				t.Errorf(`EvalSymlinks(".") in %q directory error: %v`, d.path, err)
-				return
-			}
-			if p == "." {
-				return
-			}
-			want := filepath.Clean(findEvalSymlinksTestDirsDest(t, testdirs, d.path))
-			if p == want {
-				return
-			}
-			t.Errorf(`EvalSymlinks(".") in %q directory returns %q, want "." or %q`, d.path, p, want)
-		}()
+		testEvalSymlinksAfterChdir(t, path, ".", ".")
 
 		// test EvalSymlinks("C:.") on Windows
 		if runtime.GOOS == "windows" {
-			func() {
-				defer func() {
-					err := os.Chdir(wd)
-					if err != nil {
-						t.Fatal(err)
-					}
-				}()
-
-				err := os.Chdir(path)
-				if err != nil {
-					t.Error(err)
-					return
-				}
-
-				volDot := filepath.VolumeName(tmpDir) + "."
-
-				p, err := filepath.EvalSymlinks(volDot)
-				if err != nil {
-					t.Errorf(`EvalSymlinks("%s") in %q directory error: %v`, volDot, d.path, err)
-					return
-				}
-				if p == volDot {
-					return
-				}
-				want := filepath.Clean(findEvalSymlinksTestDirsDest(t, testdirs, d.path))
-				if p == want {
-					return
-				}
-				t.Errorf(`EvalSymlinks("%s") in %q directory returns %q, want %q or %q`, volDot, d.path, p, volDot, want)
-			}()
+			volDot := filepath.VolumeName(tmpDir) + "."
+			testEvalSymlinksAfterChdir(t, path, volDot, volDot)
 		}
 
 		// test EvalSymlinks(".."+path)
-		func() {
-			defer func() {
-				err := os.Chdir(wd)
-				if err != nil {
-					t.Fatal(err)
-				}
-			}()
+		dotdotPath := simpleJoin("..", test.dest)
+		if filepath.IsAbs(test.dest) || os.IsPathSeparator(test.dest[0]) {
+			dotdotPath = test.dest
+		}
+		testEvalSymlinksAfterChdir(t,
+			simpleJoin(tmpDir, "test"),
+			simpleJoin("..", test.path),
+			dotdotPath)
 
-			err := os.Chdir(simpleJoin(tmpDir, "test"))
-			if err != nil {
-				t.Error(err)
-				return
-			}
-
-			path := simpleJoin("..", d.path)
-			dest := simpleJoin("..", 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("EvalSymlinks(%q)=%q, want %q", path, p, dest)
-			}
-		}()
-
-		// test EvalSymlinks where parameter is relative path
-		func() {
-			defer func() {
-				err := os.Chdir(wd)
-				if err != nil {
-					t.Fatal(err)
-				}
-			}()
-
-			err := os.Chdir(tmpDir)
-			if err != nil {
-				t.Error(err)
-				return
-			}
-			if p, err := filepath.EvalSymlinks(d.path); err != nil {
-				t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
-			} else if filepath.Clean(p) != filepath.Clean(d.dest) {
-				t.Errorf("EvalSymlinks(%q)=%q, want %q", d.path, p, d.dest)
-			}
-		}()
+		// test EvalSymlinks(p) where p is relative path
+		testEvalSymlinksAfterChdir(t, tmpDir, test.path, test.dest)
 	}
 }
 
diff --git a/src/path/filepath/path_windows.go b/src/path/filepath/path_windows.go
index 0d8b620..0354255 100644
--- a/src/path/filepath/path_windows.go
+++ b/src/path/filepath/path_windows.go
@@ -100,9 +100,7 @@
 
 	// Remove quotes.
 	for i, s := range list {
-		if strings.Contains(s, `"`) {
-			list[i] = strings.Replace(s, `"`, ``, -1)
-		}
+		list[i] = strings.Replace(s, `"`, ``, -1)
 	}
 
 	return list
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
index d759a83..2ec5f5e 100644
--- a/src/path/filepath/path_windows_test.go
+++ b/src/path/filepath/path_windows_test.go
@@ -100,6 +100,64 @@
 	}
 }
 
+func TestWindowsEvalSymlinks(t *testing.T) {
+	testenv.MustHaveSymlink(t)
+
+	tmpDir, err := ioutil.TempDir("", "TestWindowsEvalSymlinks")
+	if err != nil {
+		t.Fatal(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(err)
+	}
+
+	if len(tmpDir) < 3 {
+		t.Fatalf("tmpDir path %q is too short", tmpDir)
+	}
+	if tmpDir[1] != ':' {
+		t.Fatalf("tmpDir path %q must have drive letter in it", tmpDir)
+	}
+	test := EvalSymlinksTest{"test/linkabswin", tmpDir[:3]}
+
+	// Create the symlink farm using relative paths.
+	testdirs := append(EvalSymlinksTestDirs, test)
+	for _, d := range testdirs {
+		var err error
+		path := simpleJoin(tmpDir, d.path)
+		if d.dest == "" {
+			err = os.Mkdir(path, 0755)
+		} else {
+			err = os.Symlink(d.dest, path)
+		}
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	path := simpleJoin(tmpDir, test.path)
+
+	testEvalSymlinks(t, path, test.dest)
+
+	testEvalSymlinksAfterChdir(t, path, ".", test.dest)
+
+	testEvalSymlinksAfterChdir(t,
+		path,
+		filepath.VolumeName(tmpDir)+".",
+		test.dest)
+
+	testEvalSymlinksAfterChdir(t,
+		simpleJoin(tmpDir, "test"),
+		simpleJoin("..", test.path),
+		test.dest)
+
+	testEvalSymlinksAfterChdir(t, tmpDir, test.path, test.dest)
+}
+
 // TestEvalSymlinksCanonicalNames verify that EvalSymlinks
 // returns "canonical" path names on windows.
 func TestEvalSymlinksCanonicalNames(t *testing.T) {
@@ -458,3 +516,37 @@
 	testenv.MustHaveSymlink(t)
 	testWalkMklink(t, "D")
 }
+
+func TestNTNamespaceSymlink(t *testing.T) {
+	output, _ := exec.Command("cmd", "/c", "mklink", "/?").Output()
+	if !strings.Contains(string(output), " /J ") {
+		t.Skip("skipping test because mklink command does not support junctions")
+	}
+
+	tmpdir, err := ioutil.TempDir("", "TestNTNamespaceSymlink")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	vol := filepath.VolumeName(tmpdir)
+	output, err = exec.Command("cmd", "/c", "mountvol", vol, "/L").CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to run mountvol %v /L: %v %q", vol, err, output)
+	}
+	target := strings.Trim(string(output), " \n\r")
+
+	link := filepath.Join(tmpdir, "link")
+	output, err = exec.Command("cmd", "/c", "mklink", "/J", link, target).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to run mklink %v %v: %v %q", link, target, err, output)
+	}
+
+	got, err := filepath.EvalSymlinks(link)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want := vol + `\`; got != want {
+		t.Errorf(`EvalSymlinks(%q): got %q, want %q`, link, got, want)
+	}
+}
diff --git a/src/path/filepath/symlink_windows.go b/src/path/filepath/symlink_windows.go
index f771fe3..78cde4a 100644
--- a/src/path/filepath/symlink_windows.go
+++ b/src/path/filepath/symlink_windows.go
@@ -5,6 +5,9 @@
 package filepath
 
 import (
+	"errors"
+	"internal/syscall/windows"
+	"os"
 	"strings"
 	"syscall"
 )
@@ -106,10 +109,100 @@
 	return volume + normPath, nil
 }
 
-func evalSymlinks(path string) (string, error) {
-	path, err := walkSymlinks(path)
+// evalSymlinksUsingGetFinalPathNameByHandle uses Windows
+// GetFinalPathNameByHandle API to retrieve the final
+// path for the specified file.
+func evalSymlinksUsingGetFinalPathNameByHandle(path string) (string, error) {
+	err := windows.LoadGetFinalPathNameByHandle()
+	if err != nil {
+		// we must be using old version of Windows
+		return "", err
+	}
+
+	if path == "" {
+		return path, nil
+	}
+
+	// Use Windows I/O manager to dereference the symbolic link, as per
+	// https://blogs.msdn.microsoft.com/oldnewthing/20100212-00/?p=14963/
+	p, err := syscall.UTF16PtrFromString(path)
 	if err != nil {
 		return "", err
 	}
-	return toNorm(path, normBase)
+	h, err := syscall.CreateFile(p, 0, 0, nil,
+		syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if err != nil {
+		return "", err
+	}
+	defer syscall.CloseHandle(h)
+
+	buf := make([]uint16, 100)
+	for {
+		n, err := windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), windows.VOLUME_NAME_DOS)
+		if err != nil {
+			return "", err
+		}
+		if n < uint32(len(buf)) {
+			break
+		}
+		buf = make([]uint16, n)
+	}
+	s := syscall.UTF16ToString(buf)
+	if len(s) > 4 && s[:4] == `\\?\` {
+		s = s[4:]
+		if len(s) > 3 && s[:3] == `UNC` {
+			// return path like \\server\share\...
+			return `\` + s[3:], nil
+		}
+		return s, nil
+	}
+	return "", errors.New("GetFinalPathNameByHandle returned unexpected path=" + s)
+}
+
+func samefile(path1, path2 string) bool {
+	fi1, err := os.Lstat(path1)
+	if err != nil {
+		return false
+	}
+	fi2, err := os.Lstat(path2)
+	if err != nil {
+		return false
+	}
+	return os.SameFile(fi1, fi2)
+}
+
+func evalSymlinks(path string) (string, error) {
+	newpath, err := walkSymlinks(path)
+	if err != nil {
+		newpath2, err2 := evalSymlinksUsingGetFinalPathNameByHandle(path)
+		if err2 == nil {
+			return toNorm(newpath2, normBase)
+		}
+		return "", err
+	}
+	newpath, err = toNorm(newpath, normBase)
+	if err != nil {
+		newpath2, err2 := evalSymlinksUsingGetFinalPathNameByHandle(path)
+		if err2 == nil {
+			return toNorm(newpath2, normBase)
+		}
+		return "", err
+	}
+	if strings.ToUpper(newpath) == strings.ToUpper(path) {
+		// walkSymlinks did not actually walk any symlinks,
+		// so we don't need to try GetFinalPathNameByHandle.
+		return newpath, nil
+	}
+	newpath2, err2 := evalSymlinksUsingGetFinalPathNameByHandle(path)
+	if err2 != nil {
+		return newpath, nil
+	}
+	newpath2, err2 = toNorm(newpath2, normBase)
+	if err2 != nil {
+		return newpath, nil
+	}
+	if samefile(newpath, newpath2) {
+		return newpath, nil
+	}
+	return newpath2, nil
 }
diff --git a/src/plugin/plugin.go b/src/plugin/plugin.go
index c774465..5506e95 100644
--- a/src/plugin/plugin.go
+++ b/src/plugin/plugin.go
@@ -13,13 +13,14 @@
 // already part of the program are called. The main function is not run.
 // A plugin is only initialized once, and cannot be closed.
 //
-// The plugin support is currently incomplete, only supports Linux,
-// and has known bugs. Please report any issues.
+// Currently plugins are only supported on Linux and macOS.
+// Please report any issues.
 package plugin
 
 // Plugin is a loaded Go plugin.
 type Plugin struct {
 	pluginpath string
+	err        string        // set if plugin failed to load
 	loaded     chan struct{} // closed when loaded
 	syms       map[string]interface{}
 }
diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go
index 3237598..47f2b29 100644
--- a/src/plugin/plugin_dlopen.go
+++ b/src/plugin/plugin_dlopen.go
@@ -49,75 +49,50 @@
 	return -1
 }
 
-// pathToPrefix converts raw string to the prefix that will be used in the symbol
-// table. If modifying, modify the version in internal/obj/sym.go as well.
-func pathToPrefix(s string) string {
-	slash := lastIndexByte(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)
-}
-
 func open(name string) (*Plugin, error) {
-	cPath := (*C.char)(C.malloc(C.PATH_MAX + 1))
-	defer C.free(unsafe.Pointer(cPath))
-
-	cRelName := C.CString(name)
-	defer C.free(unsafe.Pointer(cRelName))
-	if C.realpath(cRelName, cPath) == nil {
-		return nil, errors.New("plugin.Open(" + name + "): realpath failed")
+	cPath := make([]byte, C.PATH_MAX+1)
+	cRelName := make([]byte, len(name)+1)
+	copy(cRelName, name)
+	if C.realpath(
+		(*C.char)(unsafe.Pointer(&cRelName[0])),
+		(*C.char)(unsafe.Pointer(&cPath[0]))) == nil {
+		return nil, errors.New(`plugin.Open("` + name + `"): realpath failed`)
 	}
 
-	filepath := C.GoString(cPath)
+	filepath := C.GoString((*C.char)(unsafe.Pointer(&cPath[0])))
 
 	pluginsMu.Lock()
 	if p := plugins[filepath]; p != nil {
 		pluginsMu.Unlock()
+		if p.err != "" {
+			return nil, errors.New(`plugin.Open("` + name + `"): ` + p.err + ` (previous failure)`)
+		}
 		<-p.loaded
 		return p, nil
 	}
 	var cErr *C.char
-	h := C.pluginOpen(cPath, &cErr)
+	h := C.pluginOpen((*C.char)(unsafe.Pointer(&cPath[0])), &cErr)
 	if h == 0 {
 		pluginsMu.Unlock()
-		return nil, errors.New("plugin.Open: " + C.GoString(cErr))
+		return nil, errors.New(`plugin.Open("` + name + `"): ` + C.GoString(cErr))
 	}
 	// TODO(crawshaw): look for plugin note, confirm it is a Go plugin
 	// and it was built with the correct toolchain.
 	if len(name) > 3 && name[len(name)-3:] == ".so" {
 		name = name[:len(name)-3]
 	}
-
-	pluginpath, syms, mismatchpkg := lastmoduleinit()
-	if mismatchpkg != "" {
-		pluginsMu.Unlock()
-		return nil, errors.New("plugin.Open: plugin was built with a different version of package " + mismatchpkg)
-	}
 	if plugins == nil {
 		plugins = make(map[string]*Plugin)
 	}
+	pluginpath, syms, errstr := lastmoduleinit()
+	if errstr != "" {
+		plugins[filepath] = &Plugin{
+			pluginpath: pluginpath,
+			err:        errstr,
+		}
+		pluginsMu.Unlock()
+		return nil, errors.New(`plugin.Open("` + name + `"): ` + errstr)
+	}
 	// This function can be called from the init function of a plugin.
 	// Drop a placeholder in the map so subsequent opens can wait on it.
 	p := &Plugin{
@@ -127,9 +102,11 @@
 	plugins[filepath] = p
 	pluginsMu.Unlock()
 
-	initStr := C.CString(pluginpath + ".init")
-	initFuncPC := C.pluginLookup(h, initStr, &cErr)
-	C.free(unsafe.Pointer(initStr))
+	initStr := make([]byte, len(pluginpath)+6)
+	copy(initStr, pluginpath)
+	copy(initStr[len(pluginpath):], ".init")
+
+	initFuncPC := C.pluginLookup(h, (*C.char)(unsafe.Pointer(&initStr[0])), &cErr)
 	if initFuncPC != nil {
 		initFuncP := &initFuncPC
 		initFunc := *(*func())(unsafe.Pointer(&initFuncP))
@@ -144,11 +121,14 @@
 			delete(syms, symName)
 			symName = symName[1:]
 		}
-		cname := C.CString(pathToPrefix(pluginpath) + "." + symName)
-		p := C.pluginLookup(h, cname, &cErr)
-		C.free(unsafe.Pointer(cname))
+
+		fullName := pluginpath + "." + symName
+		cname := make([]byte, len(fullName)+1)
+		copy(cname, fullName)
+
+		p := C.pluginLookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
 		if p == nil {
-			return nil, errors.New("plugin.Open: could not find symbol " + symName + ": " + C.GoString(cErr))
+			return nil, errors.New(`plugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + C.GoString(cErr))
 		}
 		valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&sym))
 		if isFunc {
@@ -179,4 +159,4 @@
 )
 
 // lastmoduleinit is defined in package runtime
-func lastmoduleinit() (pluginpath string, syms map[string]interface{}, mismatchpkg string)
+func lastmoduleinit() (pluginpath string, syms map[string]interface{}, errstr string)
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 5a5c91b..e51d19e 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -19,6 +19,7 @@
 	"strconv"
 	"strings"
 	"sync"
+	"sync/atomic"
 	"testing"
 	"time"
 	"unicode"
@@ -321,6 +322,89 @@
 	}
 }
 
+func TestCanSetField(t *testing.T) {
+	type embed struct{ x, X int }
+	type Embed struct{ x, X int }
+	type S1 struct {
+		embed
+		x, X int
+	}
+	type S2 struct {
+		*embed
+		x, X int
+	}
+	type S3 struct {
+		Embed
+		x, X int
+	}
+	type S4 struct {
+		*Embed
+		x, X int
+	}
+
+	type testCase struct {
+		index  []int
+		canSet bool
+	}
+	tests := []struct {
+		val   Value
+		cases []testCase
+	}{{
+		val: ValueOf(&S1{}),
+		cases: []testCase{
+			{[]int{0}, false},
+			{[]int{0, 0}, false},
+			{[]int{0, 1}, true},
+			{[]int{1}, false},
+			{[]int{2}, true},
+		},
+	}, {
+		val: ValueOf(&S2{embed: &embed{}}),
+		cases: []testCase{
+			{[]int{0}, false},
+			{[]int{0, 0}, false},
+			{[]int{0, 1}, true},
+			{[]int{1}, false},
+			{[]int{2}, true},
+		},
+	}, {
+		val: ValueOf(&S3{}),
+		cases: []testCase{
+			{[]int{0}, true},
+			{[]int{0, 0}, false},
+			{[]int{0, 1}, true},
+			{[]int{1}, false},
+			{[]int{2}, true},
+		},
+	}, {
+		val: ValueOf(&S4{Embed: &Embed{}}),
+		cases: []testCase{
+			{[]int{0}, true},
+			{[]int{0, 0}, false},
+			{[]int{0, 1}, true},
+			{[]int{1}, false},
+			{[]int{2}, true},
+		},
+	}}
+
+	for _, tt := range tests {
+		t.Run(tt.val.Type().Name(), func(t *testing.T) {
+			for _, tc := range tt.cases {
+				f := tt.val
+				for _, i := range tc.index {
+					if f.Kind() == Ptr {
+						f = f.Elem()
+					}
+					f = f.Field(i)
+				}
+				if got := f.CanSet(); got != tc.canSet {
+					t.Errorf("CanSet() = %v, want %v", got, tc.canSet)
+				}
+			}
+		})
+	}
+}
+
 var _i = 7
 
 var valueToStringTests = []pair{
@@ -584,6 +668,47 @@
 	}
 }
 
+func TestCopyString(t *testing.T) {
+	t.Run("Slice", func(t *testing.T) {
+		s := bytes.Repeat([]byte{'_'}, 8)
+		val := ValueOf(s)
+
+		n := Copy(val, ValueOf(""))
+		if expecting := []byte("________"); n != 0 || !bytes.Equal(s, expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s, expecting)
+		}
+
+		n = Copy(val, ValueOf("hello"))
+		if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s, expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s, expecting)
+		}
+
+		n = Copy(val, ValueOf("helloworld"))
+		if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s, expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s, expecting)
+		}
+	})
+	t.Run("Array", func(t *testing.T) {
+		s := [...]byte{'_', '_', '_', '_', '_', '_', '_', '_'}
+		val := ValueOf(&s).Elem()
+
+		n := Copy(val, ValueOf(""))
+		if expecting := []byte("________"); n != 0 || !bytes.Equal(s[:], expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s[:], expecting)
+		}
+
+		n = Copy(val, ValueOf("hello"))
+		if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s[:], expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s[:], expecting)
+		}
+
+		n = Copy(val, ValueOf("helloworld"))
+		if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s[:], expecting) {
+			t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s[:], expecting)
+		}
+	})
+}
+
 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}
@@ -1506,6 +1631,15 @@
 	}
 }
 
+func TestCallConvert(t *testing.T) {
+	v := ValueOf(new(io.ReadWriter)).Elem()
+	f := ValueOf(func(r io.Reader) io.Reader { return r })
+	out := f.Call([]Value{v})
+	if len(out) != 1 || out[0].Type() != TypeOf(new(io.Reader)).Elem() || !out[0].IsNil() {
+		t.Errorf("expected [nil], got %v", out)
+	}
+}
+
 type emptyStruct struct{}
 
 type nonEmptyStruct struct {
@@ -1546,6 +1680,30 @@
 	}
 }
 
+func TestCallReturnsEmpty(t *testing.T) {
+	// Issue 21717: past-the-end pointer write in Call with
+	// nonzero-sized frame and zero-sized return value.
+	runtime.GC()
+	var finalized uint32
+	f := func() (emptyStruct, *int) {
+		i := new(int)
+		runtime.SetFinalizer(i, func(*int) { atomic.StoreUint32(&finalized, 1) })
+		return emptyStruct{}, i
+	}
+	v := ValueOf(f).Call(nil)[0] // out[0] should not alias out[1]'s memory, so the finalizer should run.
+	timeout := time.After(5 * time.Second)
+	for atomic.LoadUint32(&finalized) == 0 {
+		select {
+		case <-timeout:
+			t.Fatal("finalizer did not run")
+		default:
+		}
+		runtime.Gosched()
+		runtime.GC()
+	}
+	runtime.KeepAlive(v)
+}
+
 func BenchmarkCall(b *testing.B) {
 	fv := ValueOf(func(a, b string) {})
 	b.ReportAllocs()
@@ -2357,10 +2515,13 @@
 }
 
 func TestFieldPkgPath(t *testing.T) {
+	type x int
 	typ := TypeOf(struct {
 		Exported   string
 		unexported string
 		OtherPkgFields
+		int // issue 21702
+		*x  // issue 21122
 	}{})
 
 	type pkgpathTest struct {
@@ -2387,6 +2548,8 @@
 		{[]int{2}, "", true},              // OtherPkgFields
 		{[]int{2, 0}, "", false},          // OtherExported
 		{[]int{2, 1}, "reflect", false},   // otherUnexported
+		{[]int{3}, "reflect_test", true},  // int
+		{[]int{4}, "reflect_test", true},  // *x
 	})
 
 	type localOtherPkgFields OtherPkgFields
@@ -3111,7 +3274,7 @@
 	i := timp(0)
 	v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}})
 	ok(func() { call(v.Field(0).Method(0)) })         // .t0.W
-	ok(func() { call(v.Field(0).Elem().Method(0)) })  // .t0.W
+	bad(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W
 	bad(func() { call(v.Field(0).Method(1)) })        // .t0.w
 	bad(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w
 	ok(func() { call(v.Field(1).Method(0)) })         // .T1.Y
@@ -3129,10 +3292,10 @@
 	bad(func() { call(v.Field(3).Method(1)) })        // .NamedT1.y
 	bad(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y
 
-	ok(func() { call(v.Field(4).Field(0).Method(0)) })        // .NamedT2.T1.Y
-	ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W
-	ok(func() { call(v.Field(4).Field(1).Method(0)) })        // .NamedT2.t0.W
-	ok(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W
+	ok(func() { call(v.Field(4).Field(0).Method(0)) })         // .NamedT2.T1.Y
+	ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) })  // .NamedT2.T1.W
+	ok(func() { call(v.Field(4).Field(1).Method(0)) })         // .NamedT2.t0.W
+	bad(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W
 
 	bad(func() { call(v.Field(5).Method(0)) })        // .namedT0.W
 	bad(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W
@@ -5521,6 +5684,25 @@
 	MakeFunc(typ, f).Call([]Value{ValueOf(10)})
 }
 
+type UnExportedFirst int
+
+func (i UnExportedFirst) ΦExported()  {}
+func (i UnExportedFirst) unexported() {}
+
+// Issue 21177
+func TestMethodByNameUnExportedFirst(t *testing.T) {
+	defer func() {
+		if recover() != nil {
+			t.Errorf("should not panic")
+		}
+	}()
+	typ := TypeOf(UnExportedFirst(0))
+	m, _ := typ.MethodByName("ΦExported")
+	if m.Name != "ΦExported" {
+		t.Errorf("got %s, expected ΦExported", m.Name)
+	}
+}
+
 // Issue 18635 (method version).
 type KeepMethodLive struct{}
 
@@ -6255,3 +6437,37 @@
 		t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
 	}
 }
+
+func TestIssue22031(t *testing.T) {
+	type s []struct{ C int }
+
+	type t1 struct{ s }
+	type t2 struct{ f s }
+
+	tests := []Value{
+		ValueOf(t1{s{{}}}).Field(0).Index(0).Field(0),
+		ValueOf(t2{s{{}}}).Field(0).Index(0).Field(0),
+	}
+
+	for i, test := range tests {
+		if test.CanSet() {
+			t.Errorf("%d: CanSet: got true, want false", i)
+		}
+	}
+}
+
+type NonExportedFirst int
+
+func (i NonExportedFirst) ΦExported()       {}
+func (i NonExportedFirst) nonexported() int { panic("wrong") }
+
+func TestIssue22073(t *testing.T) {
+	m := ValueOf(NonExportedFirst(0)).Method(0)
+
+	if got := m.Type().NumOut(); got != 0 {
+		t.Errorf("NumOut: got %v, want 0", got)
+	}
+
+	// Shouldn't panic.
+	m.Call(nil)
+}
diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go
index ffd1104..14a6981 100644
--- a/src/reflect/export_test.go
+++ b/src/reflect/export_test.go
@@ -93,7 +93,7 @@
 	}
 	m := ut.methods()[0]
 	mname := t.(*rtype).nameOff(m.name)
-	if *mname.data(0)&(1<<2) == 0 {
+	if *mname.data(0, "name flag field")&(1<<2) == 0 {
 		panic("method name does not have pkgPath *string")
 	}
 	return mname.bytes
@@ -111,7 +111,7 @@
 }
 
 func ResolveReflectName(s string) {
-	resolveReflectName(newName(s, "", "", false))
+	resolveReflectName(newName(s, "", false))
 }
 
 type Buffer struct {
diff --git a/src/reflect/swapper.go b/src/reflect/swapper.go
index 5441cb0..bf77b68 100644
--- a/src/reflect/swapper.go
+++ b/src/reflect/swapper.go
@@ -65,8 +65,8 @@
 		if uint(i) >= uint(s.Len) || uint(j) >= uint(s.Len) {
 			panic("reflect: slice index out of range")
 		}
-		val1 := arrayAt(s.Data, i, size)
-		val2 := arrayAt(s.Data, j, size)
+		val1 := arrayAt(s.Data, i, size, "i < s.Len")
+		val2 := arrayAt(s.Data, j, size, "j < s.Len")
 		typedmemmove(typ, tmp, val1)
 		typedmemmove(typ, val1, val2)
 		typedmemmove(typ, val2, tmp)
diff --git a/src/reflect/type.go b/src/reflect/type.go
index cbf4f73..171fc07 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -32,7 +32,8 @@
 // calling kind-specific methods. Calling a method
 // inappropriate to the kind of type causes a run-time panic.
 //
-// Type values are comparable, such as with the == operator.
+// Type values are comparable, such as with the == operator,
+// so they can be used as map keys.
 // Two Type values are equal if they represent identical types.
 type Type interface {
 	// Methods applicable to all types.
@@ -212,7 +213,7 @@
 // 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.
+// See https://golang.org/issue/4876 for more details.
 
 /*
  * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
@@ -468,8 +469,8 @@
 	bytes *byte
 }
 
-func (n name) data(off int) *byte {
-	return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off)))
+func (n name) data(off int, whySafe string) *byte {
+	return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
 }
 
 func (n name) isExported() bool {
@@ -477,15 +478,15 @@
 }
 
 func (n name) nameLen() int {
-	return int(uint16(*n.data(1))<<8 | uint16(*n.data(2)))
+	return int(uint16(*n.data(1, "name len field"))<<8 | uint16(*n.data(2, "name len field")))
 }
 
 func (n name) tagLen() int {
-	if *n.data(0)&(1<<1) == 0 {
+	if *n.data(0, "name flag field")&(1<<1) == 0 {
 		return 0
 	}
 	off := 3 + n.nameLen()
-	return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1)))
+	return int(uint16(*n.data(off, "name taglen field"))<<8 | uint16(*n.data(off+1, "name taglen field")))
 }
 
 func (n name) name() (s string) {
@@ -507,13 +508,13 @@
 	}
 	nl := n.nameLen()
 	hdr := (*stringHeader)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(3 + nl + 2))
+	hdr.Data = unsafe.Pointer(n.data(3+nl+2, "non-empty string"))
 	hdr.Len = tl
 	return s
 }
 
 func (n name) pkgPath() string {
-	if n.bytes == nil || *n.data(0)&(1<<2) == 0 {
+	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
 		return ""
 	}
 	off := 3 + n.nameLen()
@@ -521,7 +522,9 @@
 		off += 2 + tl
 	}
 	var nameOff int32
-	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off)))[:])
+	// Note that this field may not be aligned in memory,
+	// so we cannot use a direct int32 assignment here.
+	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
 	pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
 	return pkgPathName.name()
 }
@@ -531,7 +534,7 @@
 	return (n + a - 1) &^ (a - 1)
 }
 
-func newName(n, tag, pkgPath string, exported bool) name {
+func newName(n, tag string, exported bool) name {
 	if len(n) > 1<<16-1 {
 		panic("reflect.nameFrom: name too long: " + n)
 	}
@@ -548,9 +551,6 @@
 		l += 2 + len(tag)
 		bits |= 1 << 1
 	}
-	if pkgPath != "" {
-		bits |= 1 << 2
-	}
 
 	b := make([]byte, l)
 	b[0] = bits
@@ -564,10 +564,6 @@
 		copy(tb[2:], tag)
 	}
 
-	if pkgPath != "" {
-		panic("reflect: creating a name with a package path is not supported")
-	}
-
 	return name{bytes: &b[0]}
 }
 
@@ -637,7 +633,10 @@
 }
 
 func (t *uncommonType) methods() []method {
-	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff)))[:t.mcount:t.mcount]
+	if t.mcount == 0 {
+		return nil
+	}
+	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
 }
 
 // resolveNameOff resolves a name offset from a base pointer.
@@ -878,11 +877,15 @@
 		return Method{}, false
 	}
 	utmethods := ut.methods()
+	var eidx int
 	for i := 0; i < int(ut.mcount); i++ {
 		p := utmethods[i]
 		pname := t.nameOff(p.name)
-		if pname.isExported() && pname.name() == name {
-			return t.Method(i), true
+		if pname.isExported() {
+			if pname.name() == name {
+				return t.Method(eidx), true
+			}
+			eidx++
 		}
 	}
 	return Method{}, false
@@ -1048,7 +1051,10 @@
 	if t.tflag&tflagUncommon != 0 {
 		uadd += unsafe.Sizeof(uncommonType{})
 	}
-	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd))[:t.inCount]
+	if t.inCount == 0 {
+		return nil
+	}
+	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount]
 }
 
 func (t *funcType) out() []*rtype {
@@ -1057,10 +1063,20 @@
 		uadd += unsafe.Sizeof(uncommonType{})
 	}
 	outCount := t.outCount & (1<<15 - 1)
-	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd))[t.inCount : t.inCount+outCount]
+	if outCount == 0 {
+		return nil
+	}
+	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount]
 }
 
-func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
+// add returns p+x.
+//
+// The whySafe string is ignored, so that the function still inlines
+// as efficiently as p+x, but all call sites should use the string to
+// record why the addition is safe, which is to say why the addition
+// does not cause x to advance to the very end of p's allocation
+// and therefore point incorrectly at the next block in memory.
+func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
 	return unsafe.Pointer(uintptr(p) + x)
 }
 
@@ -1219,10 +1235,7 @@
 	f.Name = p.name.name()
 	f.Anonymous = p.anon()
 	if !p.name.isExported() {
-		f.PkgPath = p.name.pkgPath()
-		if f.PkgPath == "" {
-			f.PkgPath = t.pkgPath.name()
-		}
+		f.PkgPath = t.pkgPath.name()
 	}
 	if tag := p.name.tag(); tag != "" {
 		f.Tag = StructTag(tag)
@@ -1436,7 +1449,7 @@
 	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
 	pp := *prototype
 
-	pp.str = resolveReflectName(newName(s, "", "", false))
+	pp.str = resolveReflectName(newName(s, "", false))
 	pp.ptrToThis = 0
 
 	// For the type structures linked into the binary, the
@@ -1680,6 +1693,9 @@
 		if len(t.fields) != len(v.fields) {
 			return false
 		}
+		if t.pkgPath.name() != v.pkgPath.name() {
+			return false
+		}
 		for i := range t.fields {
 			tf := &t.fields[i]
 			vf := &v.fields[i]
@@ -1695,19 +1711,6 @@
 			if tf.offsetAnon != vf.offsetAnon {
 				return false
 			}
-			if !tf.name.isExported() {
-				tp := tf.name.pkgPath()
-				if tp == "" {
-					tp = t.pkgPath.name()
-				}
-				vp := vf.name.pkgPath()
-				if vp == "" {
-					vp = v.pkgPath.name()
-				}
-				if tp != vp {
-					return false
-				}
-			}
 		}
 		return true
 	}
@@ -1737,7 +1740,7 @@
 func typelinks() (sections []unsafe.Pointer, offset [][]int32)
 
 func rtypeOff(section unsafe.Pointer, off int32) *rtype {
-	return (*rtype)(add(section, uintptr(off)))
+	return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0"))
 }
 
 // typesByString returns the subslice of typelinks() whose elements have
@@ -1849,7 +1852,7 @@
 	ch := *prototype
 	ch.tflag = 0
 	ch.dir = uintptr(dir)
-	ch.str = resolveReflectName(newName(s, "", "", false))
+	ch.str = resolveReflectName(newName(s, "", false))
 	ch.hash = fnv1(typ.hash, 'c', byte(dir))
 	ch.elem = typ
 
@@ -1892,7 +1895,7 @@
 	// Make a map type.
 	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
 	mt := **(**mapType)(unsafe.Pointer(&imap))
-	mt.str = resolveReflectName(newName(s, "", "", false))
+	mt.str = resolveReflectName(newName(s, "", false))
 	mt.tflag = 0
 	mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
 	mt.key = ktyp
@@ -2060,7 +2063,7 @@
 	}
 
 	// Populate the remaining fields of ft and store in cache.
-	ft.str = resolveReflectName(newName(str, "", "", false))
+	ft.str = resolveReflectName(newName(str, "", false))
 	ft.ptrToThis = 0
 	return addToCache(&ft.rtype)
 }
@@ -2255,7 +2258,7 @@
 		b.align = 8
 	}
 	s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
-	b.str = resolveReflectName(newName(s, "", "", false))
+	b.str = resolveReflectName(newName(s, "", false))
 	return b
 }
 
@@ -2285,7 +2288,7 @@
 	prototype := *(**sliceType)(unsafe.Pointer(&islice))
 	slice := *prototype
 	slice.tflag = 0
-	slice.str = resolveReflectName(newName(s, "", "", false))
+	slice.str = resolveReflectName(newName(s, "", false))
 	slice.hash = fnv1(typ.hash, '[')
 	slice.elem = typ
 	slice.ptrToThis = 0
@@ -2684,7 +2687,7 @@
 		}
 	}
 
-	typ.str = resolveReflectName(newName(str, "", "", false))
+	typ.str = resolveReflectName(newName(str, "", false))
 	typ.tflag = 0
 	typ.hash = hash
 	typ.size = size
@@ -2763,7 +2766,7 @@
 		typ.alg.hash = func(p unsafe.Pointer, seed uintptr) uintptr {
 			o := seed
 			for _, ft := range typ.fields {
-				pi := unsafe.Pointer(uintptr(p) + ft.offset())
+				pi := add(p, ft.offset(), "&x.field safe")
 				o = ft.typ.alg.hash(pi, o)
 			}
 			return o
@@ -2773,8 +2776,8 @@
 	if comparable {
 		typ.alg.equal = func(p, q unsafe.Pointer) bool {
 			for _, ft := range typ.fields {
-				pi := unsafe.Pointer(uintptr(p) + ft.offset())
-				qi := unsafe.Pointer(uintptr(q) + ft.offset())
+				pi := add(p, ft.offset(), "&x.field safe")
+				qi := add(q, ft.offset(), "&x.field safe")
 				if !ft.typ.alg.equal(pi, qi) {
 					return false
 				}
@@ -2813,7 +2816,7 @@
 
 	resolveReflectType(field.Type.common()) // install in runtime
 	return structField{
-		name:       newName(field.Name, string(field.Tag), "", true),
+		name:       newName(field.Name, string(field.Tag), true),
 		typ:        field.Type.common(),
 		offsetAnon: offsetAnon,
 	}
@@ -2877,7 +2880,7 @@
 	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
 	array := *prototype
 	array.tflag = 0
-	array.str = resolveReflectName(newName(s, "", "", false))
+	array.str = resolveReflectName(newName(s, "", false))
 	array.hash = fnv1(typ.hash, '[')
 	for n := uint32(count); n > 0; n >>= 8 {
 		array.hash = fnv1(array.hash, byte(n))
@@ -2988,8 +2991,8 @@
 		eequal := ealg.equal
 		array.alg.equal = func(p, q unsafe.Pointer) bool {
 			for i := 0; i < count; i++ {
-				pi := arrayAt(p, i, esize)
-				qi := arrayAt(q, i, esize)
+				pi := arrayAt(p, i, esize, "i < count")
+				qi := arrayAt(q, i, esize, "i < count")
 				if !eequal(pi, qi) {
 					return false
 				}
@@ -3003,7 +3006,7 @@
 		array.alg.hash = func(ptr unsafe.Pointer, seed uintptr) uintptr {
 			o := seed
 			for i := 0; i < count; i++ {
-				o = ehash(arrayAt(ptr, i, esize), o)
+				o = ehash(arrayAt(ptr, i, esize, "i < count"), o)
 			}
 			return o
 		}
@@ -3130,7 +3133,7 @@
 	} else {
 		s = "funcargs(" + t.String() + ")"
 	}
-	x.str = resolveReflectName(newName(s, "", "", false))
+	x.str = resolveReflectName(newName(s, "", false))
 
 	// cache result for future callers
 	framePool = &sync.Pool{New: func() interface{} {
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 8488e8d..c76a954 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -80,6 +80,13 @@
 	return Kind(f & flagKindMask)
 }
 
+func (f flag) ro() flag {
+	if f&flagRO != 0 {
+		return flagStickyRO
+	}
+	return 0
+}
+
 // pointer returns the underlying pointer represented by v.
 // v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
 func (v Value) pointer() unsafe.Pointer {
@@ -176,16 +183,15 @@
 	word unsafe.Pointer
 }
 
-// nonEmptyInterface is the header for a interface value with methods.
+// nonEmptyInterface is the header for an interface value with methods.
 type nonEmptyInterface struct {
 	// see ../runtime/iface.go:/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
+		ityp *rtype // static interface type
+		typ  *rtype // dynamic concrete type
+		hash uint32 // copy of typ.hash
+		_    [4]byte
+		fun  [100000]unsafe.Pointer // method table
 	}
 	word unsafe.Pointer
 }
@@ -238,7 +244,7 @@
 	if v.flag&flagAddr == 0 {
 		panic("reflect.Value.Addr of unaddressable value")
 	}
-	return Value{v.typ.ptrTo(), v.ptr, (v.flag & flagRO) | flag(Ptr)}
+	return Value{v.typ.ptrTo(), v.ptr, v.flag.ro() | flag(Ptr)}
 }
 
 // Bool returns v's underlying value.
@@ -420,7 +426,14 @@
 		a := uintptr(targ.align)
 		off = (off + a - 1) &^ (a - 1)
 		n := targ.size
-		addr := unsafe.Pointer(uintptr(args) + off)
+		if n == 0 {
+			// Not safe to compute args+off pointing at 0 bytes,
+			// because that might point beyond the end of the frame,
+			// but we still need to call assignTo to check assignability.
+			v.assignTo("reflect.Value.Call", targ, nil)
+			continue
+		}
+		addr := add(args, off, "n > 0")
 		v = v.assignTo("reflect.Value.Call", targ, addr)
 		if v.flag&flagIndir != 0 {
 			typedmemmove(targ, addr, v.ptr)
@@ -456,8 +469,14 @@
 			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}
+			if tv.Size() != 0 {
+				fl := flagIndir | flag(tv.Kind())
+				ret[i] = Value{tv.common(), add(args, off, "tv.Size() != 0"), fl}
+			} else {
+				// For zero-sized return value, args+off may point to the next object.
+				// In this case, return the zero value instead.
+				ret[i] = Zero(tv)
+			}
 			off += tv.Size()
 		}
 	}
@@ -487,7 +506,6 @@
 	in := make([]Value, 0, int(ftyp.inCount))
 	for _, typ := range ftyp.in() {
 		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.
@@ -495,10 +513,12 @@
 			// 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)
-			typedmemmove(typ, v.ptr, addr)
+			if typ.size > 0 {
+				typedmemmove(typ, v.ptr, add(ptr, off, "typ.size > 0"))
+			}
 			v.flag |= flagIndir
 		} else {
-			v.ptr = *(*unsafe.Pointer)(addr)
+			v.ptr = *(*unsafe.Pointer)(add(ptr, off, "1-ptr"))
 		}
 		in = append(in, v)
 		off += typ.size
@@ -529,7 +549,10 @@
 					" returned value obtained from unexported field")
 			}
 			off += -off & uintptr(typ.align-1)
-			addr := unsafe.Pointer(uintptr(ptr) + off)
+			if typ.size == 0 {
+				continue
+			}
+			addr := add(ptr, off, "typ.size > 0")
 			if v.flag&flagIndir != 0 {
 				typedmemmove(typ, addr, v.ptr)
 			} else {
@@ -572,11 +595,11 @@
 		t = tt.typeOff(m.typ)
 	} else {
 		rcvrtype = v.typ
-		ut := v.typ.uncommon()
-		if ut == nil || uint(i) >= uint(ut.mcount) {
+		ms := v.typ.exportedMethods()
+		if uint(i) >= uint(len(ms)) {
 			panic("reflect: internal error: invalid method index")
 		}
-		m := ut.methods()[i]
+		m := ms[i]
 		if !v.typ.nameOff(m.name).isExported() {
 			panic("reflect: " + op + " of unexported method")
 		}
@@ -633,7 +656,7 @@
 	// Avoid constructing out-of-bounds pointers if there are no args.
 	storeRcvr(rcvr, args)
 	if argSize-ptrSize > 0 {
-		typedmemmovepartial(frametype, unsafe.Pointer(uintptr(args)+ptrSize), frame, ptrSize, argSize-ptrSize)
+		typedmemmovepartial(frametype, add(args, ptrSize, "argSize > ptrSize"), frame, ptrSize, argSize-ptrSize)
 	}
 
 	// Call.
@@ -651,8 +674,8 @@
 			callerRetOffset = align(argSize-ptrSize, 8)
 		}
 		typedmemmovepartial(frametype,
-			unsafe.Pointer(uintptr(frame)+callerRetOffset),
-			unsafe.Pointer(uintptr(args)+retOffset),
+			add(frame, callerRetOffset, "frametype.size > retOffset"),
+			add(args, retOffset, "frametype.size > retOffset"),
 			retOffset,
 			frametype.size-retOffset)
 	}
@@ -731,7 +754,7 @@
 		}
 		x := unpackEface(eface)
 		if x.flag != 0 {
-			x.flag |= v.flag & flagRO
+			x.flag |= v.flag.ro()
 		}
 		return x
 	case Ptr:
@@ -779,8 +802,8 @@
 	// 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 have field.offset = 0,
-	// so v.ptr + field.offset is still okay.
-	ptr := unsafe.Pointer(uintptr(v.ptr) + field.offset())
+	// so v.ptr + field.offset is still the correct address.
+	ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
 	return Value{typ, ptr, fl}
 }
 
@@ -858,9 +881,9 @@
 		// 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
+		// so v.ptr + offset is still the correct address.
+		val := add(v.ptr, offset, "same as &v[i], i < tt.len")
+		fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind()) // bits same as overall array
 		return Value{typ, val, fl}
 
 	case Slice:
@@ -872,8 +895,8 @@
 		}
 		tt := (*sliceType)(unsafe.Pointer(v.typ))
 		typ := tt.elem
-		val := arrayAt(s.Data, i, typ.size)
-		fl := flagAddr | flagIndir | v.flag&flagRO | flag(typ.Kind())
+		val := arrayAt(s.Data, i, typ.size, "i < s.Len")
+		fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
 		return Value{typ, val, fl}
 
 	case String:
@@ -881,8 +904,8 @@
 		if uint(i) >= uint(s.Len) {
 			panic("reflect: string index out of range")
 		}
-		p := arrayAt(s.Data, i, 1)
-		fl := v.flag&flagRO | flag(Uint8) | flagIndir
+		p := arrayAt(s.Data, i, 1, "i < s.Len")
+		fl := v.flag.ro() | flag(Uint8) | flagIndir
 		return Value{uint8Type, p, fl}
 	}
 	panic(&ValueError{"reflect.Value.Index", v.kind()})
@@ -1060,17 +1083,16 @@
 		return Value{}
 	}
 	typ := tt.elem
-	fl := (v.flag | key.flag) & flagRO
+	fl := (v.flag | key.flag).ro()
 	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)
-		typedmemmove(typ, c, e)
-		return Value{typ, c, fl | flagIndir}
-	} else {
+	if !ifaceIndir(typ) {
 		return Value{typ, *(*unsafe.Pointer)(e), fl}
 	}
+	// Copy result so future changes to the map
+	// won't change the underlying value.
+	c := unsafe_New(typ)
+	typedmemmove(typ, c, e)
+	return Value{typ, c, fl | flagIndir}
 }
 
 // MapKeys returns a slice containing all the keys present in the map,
@@ -1082,7 +1104,7 @@
 	tt := (*mapType)(unsafe.Pointer(v.typ))
 	keyType := tt.key
 
-	fl := v.flag&flagRO | flag(keyType.Kind())
+	fl := v.flag.ro() | flag(keyType.Kind())
 
 	m := v.pointer()
 	mlen := int(0)
@@ -1564,7 +1586,10 @@
 		if i < 0 || j < i || j > s.Len {
 			panic("reflect.Value.Slice: string slice index out of bounds")
 		}
-		t := stringHeader{arrayAt(s.Data, i, 1), j - i}
+		var t stringHeader
+		if i < s.Len {
+			t = stringHeader{arrayAt(s.Data, i, 1, "i < s.Len"), j - i}
+		}
 		return Value{v.typ, unsafe.Pointer(&t), v.flag}
 	}
 
@@ -1580,13 +1605,13 @@
 	s.Len = j - i
 	s.Cap = cap - i
 	if cap-i > 0 {
-		s.Data = arrayAt(base, i, typ.elem.Size())
+		s.Data = arrayAt(base, i, typ.elem.Size(), "i < cap")
 	} else {
 		// do not advance pointer, to avoid pointing beyond end of slice
 		s.Data = base
 	}
 
-	fl := v.flag&flagRO | flagIndir | flag(Slice)
+	fl := v.flag.ro() | flagIndir | flag(Slice)
 	return Value{typ.common(), unsafe.Pointer(&x), fl}
 }
 
@@ -1632,13 +1657,13 @@
 	s.Len = j - i
 	s.Cap = k - i
 	if k-i > 0 {
-		s.Data = arrayAt(base, i, typ.elem.Size())
+		s.Data = arrayAt(base, i, typ.elem.Size(), "i < k <= cap")
 	} else {
 		// do not advance pointer, to avoid pointing beyond end of slice
 		s.Data = base
 	}
 
-	fl := v.flag&flagRO | flagIndir | flag(Slice)
+	fl := v.flag.ro() | flagIndir | flag(Slice)
 	return Value{typ.common(), unsafe.Pointer(&x), fl}
 }
 
@@ -1705,11 +1730,11 @@
 		return v.typ.typeOff(m.typ)
 	}
 	// Method on concrete type.
-	ut := v.typ.uncommon()
-	if ut == nil || uint(i) >= uint(ut.mcount) {
+	ms := v.typ.exportedMethods()
+	if uint(i) >= uint(len(ms)) {
 		panic("reflect: internal error: invalid method index")
 	}
-	m := ut.methods()[i]
+	m := ms[i]
 	return v.typ.typeOff(m.mtyp)
 }
 
@@ -1791,10 +1816,15 @@
 	}
 }
 
-// arrayAt returns the i-th element of p, a C-array whose elements are
-// eltSize wide (in bytes).
-func arrayAt(p unsafe.Pointer, i int, eltSize uintptr) unsafe.Pointer {
-	return unsafe.Pointer(uintptr(p) + uintptr(i)*eltSize)
+// arrayAt returns the i-th element of p,
+// an array whose elements are eltSize bytes wide.
+// The array pointed at by p must have at least i+1 elements:
+// it is invalid (but impossible to check here) to pass i >= len,
+// because then the result will point outside the array.
+// whySafe must explain why i < len. (Passing "i < len" is fine;
+// the benefit is to surface this assumption at the call site.)
+func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
+	return add(p, uintptr(i)*eltSize, "i < len")
 }
 
 // grow grows the slice s so that it can hold extra more values, allocating
@@ -1852,6 +1882,8 @@
 // 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.
+//
+// As a special case, src can have kind String if the element type of dst is kind Uint8.
 func Copy(dst, src Value) int {
 	dk := dst.kind()
 	if dk != Array && dk != Slice {
@@ -1863,14 +1895,20 @@
 	dst.mustBeExported()
 
 	sk := src.kind()
+	var stringCopy bool
 	if sk != Array && sk != Slice {
-		panic(&ValueError{"reflect.Copy", sk})
+		stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
+		if !stringCopy {
+			panic(&ValueError{"reflect.Copy", sk})
+		}
 	}
 	src.mustBeExported()
 
 	de := dst.typ.Elem()
-	se := src.typ.Elem()
-	typesMustMatch("reflect.Copy", de, se)
+	if !stringCopy {
+		se := src.typ.Elem()
+		typesMustMatch("reflect.Copy", de, se)
+	}
 
 	var ds, ss sliceHeader
 	if dk == Array {
@@ -1884,8 +1922,13 @@
 		ss.Data = src.ptr
 		ss.Len = src.Len()
 		ss.Cap = ss.Len
-	} else {
+	} else if sk == Slice {
 		ss = *(*sliceHeader)(src.ptr)
+	} else {
+		sh := *(*stringHeader)(src.ptr)
+		ss.Data = sh.Data
+		ss.Len = sh.Len
+		ss.Cap = sh.Len
 	}
 
 	return typedslicecopy(de.common(), ds, ss)
@@ -2073,7 +2116,7 @@
 	if typ.ChanDir() != BothDir {
 		panic("reflect.MakeChan: unidirectional channel type")
 	}
-	ch := makechan(typ.(*rtype), uint64(buffer))
+	ch := makechan(typ.(*rtype), buffer)
 	return Value{typ.common(), ch, flag(Chan)}
 }
 
@@ -2165,7 +2208,7 @@
 	case directlyAssignable(dst, v.typ):
 		// Overwrite type so that they match.
 		// Same memory layout, so no harm done.
-		fl := v.flag & (flagRO | flagAddr | flagIndir)
+		fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
 		fl |= flag(dst.Kind())
 		return Value{dst, v.ptr, fl}
 
@@ -2173,6 +2216,12 @@
 		if target == nil {
 			target = unsafe_New(dst)
 		}
+		if v.Kind() == Interface && v.IsNil() {
+			// A nil ReadWriter passed to nil Reader is OK,
+			// but using ifaceE2I below will panic.
+			// Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
+			return Value{dst, nil, flag(Interface)}
+		}
 		x := valueInterface(v, false)
 		if dst.NumMethod() == 0 {
 			*(*interface{})(target) = x
@@ -2357,72 +2406,72 @@
 
 // convertOp: intXX -> [u]intXX
 func cvtInt(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(v.Int()), t)
+	return makeInt(v.flag.ro(), uint64(v.Int()), t)
 }
 
 // convertOp: uintXX -> [u]intXX
 func cvtUint(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, v.Uint(), t)
+	return makeInt(v.flag.ro(), v.Uint(), t)
 }
 
 // convertOp: floatXX -> intXX
 func cvtFloatInt(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(int64(v.Float())), t)
+	return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
 }
 
 // convertOp: floatXX -> uintXX
 func cvtFloatUint(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(v.Float()), t)
+	return makeInt(v.flag.ro(), uint64(v.Float()), t)
 }
 
 // convertOp: intXX -> floatXX
 func cvtIntFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, float64(v.Int()), t)
+	return makeFloat(v.flag.ro(), float64(v.Int()), t)
 }
 
 // convertOp: uintXX -> floatXX
 func cvtUintFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, float64(v.Uint()), t)
+	return makeFloat(v.flag.ro(), float64(v.Uint()), t)
 }
 
 // convertOp: floatXX -> floatXX
 func cvtFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, v.Float(), t)
+	return makeFloat(v.flag.ro(), v.Float(), t)
 }
 
 // convertOp: complexXX -> complexXX
 func cvtComplex(v Value, t Type) Value {
-	return makeComplex(v.flag&flagRO, v.Complex(), t)
+	return makeComplex(v.flag.ro(), v.Complex(), t)
 }
 
 // convertOp: intXX -> string
 func cvtIntString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Int()), t)
+	return makeString(v.flag.ro(), string(v.Int()), t)
 }
 
 // convertOp: uintXX -> string
 func cvtUintString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Uint()), t)
+	return makeString(v.flag.ro(), string(v.Uint()), t)
 }
 
 // convertOp: []byte -> string
 func cvtBytesString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Bytes()), t)
+	return makeString(v.flag.ro(), string(v.Bytes()), t)
 }
 
 // convertOp: string -> []byte
 func cvtStringBytes(v Value, t Type) Value {
-	return makeBytes(v.flag&flagRO, []byte(v.String()), t)
+	return makeBytes(v.flag.ro(), []byte(v.String()), t)
 }
 
 // convertOp: []rune -> string
 func cvtRunesString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.runes()), t)
+	return makeString(v.flag.ro(), string(v.runes()), t)
 }
 
 // convertOp: string -> []rune
 func cvtStringRunes(v Value, t Type) Value {
-	return makeRunes(v.flag&flagRO, []rune(v.String()), t)
+	return makeRunes(v.flag.ro(), []rune(v.String()), t)
 }
 
 // convertOp: direct copy
@@ -2437,7 +2486,7 @@
 		ptr = c
 		f &^= flagAddr
 	}
-	return Value{t, ptr, v.flag&flagRO | f} // v.flag&flagRO|f == f?
+	return Value{t, ptr, v.flag.ro() | f} // v.flag.ro()|f == f?
 }
 
 // convertOp: concrete -> interface
@@ -2449,14 +2498,14 @@
 	} else {
 		ifaceE2I(typ.(*rtype), x, target)
 	}
-	return Value{typ.common(), target, v.flag&flagRO | flagIndir | flag(Interface)}
+	return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
 }
 
 // convertOp: interface -> interface
 func cvtI2I(v Value, typ Type) Value {
 	if v.IsNil() {
 		ret := Zero(typ)
-		ret.flag |= v.flag & flagRO
+		ret.flag |= v.flag.ro()
 		return ret
 	}
 	return cvtT2I(v.Elem(), typ)
@@ -2481,7 +2530,7 @@
 //go:noescape
 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
 
-func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
+func makechan(typ *rtype, size int) (ch unsafe.Pointer)
 func makemap(t *rtype, cap int) (m unsafe.Pointer)
 
 //go:noescape
diff --git a/src/regexp/backtrack.go b/src/regexp/backtrack.go
index 29f624b..440bf7f 100644
--- a/src/regexp/backtrack.go
+++ b/src/regexp/backtrack.go
@@ -20,7 +20,7 @@
 // the instruction pc and the position in the input.
 type job struct {
 	pc  uint32
-	arg int
+	arg bool
 	pos int
 }
 
@@ -114,18 +114,12 @@
 
 // push pushes (pc, pos, arg) onto the job stack if it should be
 // visited.
-func (b *bitState) push(pc uint32, pos int, arg int) {
-	if b.prog.Inst[pc].Op == syntax.InstFail {
-		return
+func (b *bitState) push(pc uint32, pos int, arg bool) {
+	// Only check shouldVisit when arg is false.
+	// When arg is true, we are continuing a previous visit.
+	if b.prog.Inst[pc].Op != syntax.InstFail && (arg || b.shouldVisit(pc, pos)) {
+		b.jobs = append(b.jobs, job{pc: pc, arg: arg, pos: pos})
 	}
-
-	// Only check shouldVisit when arg == 0.
-	// When arg > 0, we are continuing a previous visit.
-	if arg == 0 && !b.shouldVisit(pc, pos) {
-		return
-	}
-
-	b.jobs = append(b.jobs, job{pc: pc, arg: arg, pos: pos})
 }
 
 // tryBacktrack runs a backtracking search starting at pos.
@@ -133,7 +127,7 @@
 	longest := m.re.longest
 	m.matched = false
 
-	b.push(pc, pos, 0)
+	b.push(pc, pos, false)
 	for len(b.jobs) > 0 {
 		l := len(b.jobs) - 1
 		// Pop job off the stack.
@@ -165,38 +159,36 @@
 			panic("unexpected InstFail")
 		case syntax.InstAlt:
 			// Cannot just
-			//   b.push(inst.Out, pos, 0)
-			//   b.push(inst.Arg, pos, 0)
+			//   b.push(inst.Out, pos, false)
+			//   b.push(inst.Arg, pos, false)
 			// If during the processing of inst.Out, we encounter
 			// inst.Arg via another path, we want to process it then.
 			// Pushing it here will inhibit that. Instead, re-push
-			// inst with arg==1 as a reminder to push inst.Arg out
+			// inst with arg==true as a reminder to push inst.Arg out
 			// later.
-			switch arg {
-			case 0:
-				b.push(pc, pos, 1)
-				pc = inst.Out
-				goto CheckAndLoop
-			case 1:
+			if arg {
 				// Finished inst.Out; try inst.Arg.
-				arg = 0
+				arg = false
 				pc = inst.Arg
 				goto CheckAndLoop
+			} else {
+				b.push(pc, pos, true)
+				pc = inst.Out
+				goto CheckAndLoop
 			}
-			panic("bad arg in InstAlt")
 
 		case syntax.InstAltMatch:
 			// One opcode consumes runes; the other leads to match.
 			switch b.prog.Inst[inst.Out].Op {
 			case syntax.InstRune, syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
 				// inst.Arg is the match.
-				b.push(inst.Arg, pos, 0)
+				b.push(inst.Arg, pos, false)
 				pc = inst.Arg
 				pos = b.end
 				goto CheckAndLoop
 			}
 			// inst.Out is the match - non-greedy
-			b.push(inst.Out, b.end, 0)
+			b.push(inst.Out, b.end, false)
 			pc = inst.Out
 			goto CheckAndLoop
 
@@ -237,22 +229,19 @@
 			goto CheckAndLoop
 
 		case syntax.InstCapture:
-			switch arg {
-			case 0:
+			if arg {
+				// Finished inst.Out; restore the old value.
+				b.cap[inst.Arg] = pos
+				continue
+			} else {
 				if 0 <= inst.Arg && inst.Arg < uint32(len(b.cap)) {
 					// Capture pos to register, but save old value.
-					b.push(pc, b.cap[inst.Arg], 1) // come back when we're done.
+					b.push(pc, b.cap[inst.Arg], true) // come back when we're done.
 					b.cap[inst.Arg] = pos
 				}
 				pc = inst.Out
 				goto CheckAndLoop
-			case 1:
-				// Finished inst.Out; restore the old value.
-				b.cap[inst.Arg] = pos
-				continue
-
 			}
-			panic("bad arg in InstCapture")
 
 		case syntax.InstEmptyWidth:
 			if syntax.EmptyOp(inst.Arg)&^i.context(pos) != 0 {
diff --git a/src/regexp/example_test.go b/src/regexp/example_test.go
index 2ac92d4..0bf1f6b 100644
--- a/src/regexp/example_test.go
+++ b/src/regexp/example_test.go
@@ -179,3 +179,67 @@
 	// [pizza]
 	// [pi a]
 }
+
+func ExampleRegexp_Expand() {
+	content := []byte(`
+	# comment line
+	option1: value1
+	option2: value2
+
+	# another comment line
+	option3: value3
+`)
+
+	// Regex pattern captures "key: value" pair from the content.
+	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)
+
+	// Template to convert "key: value" to "key=value" by
+	// referencing the values captured by the regex pattern.
+	template := []byte("$key=$value\n")
+
+	result := []byte{}
+
+	// For each match of the regex in the content.
+	for _, submatches := range pattern.FindAllSubmatchIndex(content, -1) {
+		// Apply the captured submatches to the template and append the output
+		// to the result.
+		result = pattern.Expand(result, template, content, submatches)
+	}
+	fmt.Println(string(result))
+	// Output:
+	// option1=value1
+	// option2=value2
+	// option3=value3
+}
+
+func ExampleRegexp_ExpandString() {
+	content := `
+	# comment line
+	option1: value1
+	option2: value2
+
+	# another comment line
+	option3: value3
+`
+
+	// Regex pattern captures "key: value" pair from the content.
+	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)
+
+	// Template to convert "key: value" to "key=value" by
+	// referencing the values captured by the regex pattern.
+	template := "$key=$value\n"
+
+	result := []byte{}
+
+	// For each match of the regex in the content.
+	for _, submatches := range pattern.FindAllStringSubmatchIndex(content, -1) {
+		// Apply the captured submatches to the template and append the output
+		// to the result.
+		result = pattern.ExpandString(result, template, content, submatches)
+	}
+	fmt.Println(string(result))
+	// Output:
+	// option1=value1
+	// option2=value2
+	// option3=value3
+}
diff --git a/src/regexp/exec.go b/src/regexp/exec.go
index f8fe7b5..84cb3e6 100644
--- a/src/regexp/exec.go
+++ b/src/regexp/exec.go
@@ -16,7 +16,7 @@
 	dense  []entry
 }
 
-// A entry is an entry on a queue.
+// An entry is an entry on a queue.
 // It holds both the instruction pc and the actual thread.
 // Some queue entries are just place holders so that the machine
 // knows it has considered that pc. Such entries have t == nil.
@@ -338,15 +338,14 @@
 	if pos == 0 && syntax.EmptyOp(inst.Arg)&^flag == 0 &&
 		len(m.re.prefix) > 0 && i.canCheckPrefix() {
 		// Match requires literal prefix; fast search for it.
-		if i.hasPrefix(m.re) {
-			pos += len(m.re.prefix)
-			r, width = i.step(pos)
-			r1, width1 = i.step(pos + width)
-			flag = i.context(pos)
-			pc = int(m.re.prefixEnd)
-		} else {
+		if !i.hasPrefix(m.re) {
 			return m.matched
 		}
+		pos += len(m.re.prefix)
+		r, width = i.step(pos)
+		r1, width1 = i.step(pos + width)
+		flag = i.context(pos)
+		pc = int(m.re.prefixEnd)
 	}
 	for {
 		inst = m.op.Inst[pc]
diff --git a/src/regexp/syntax/prog.go b/src/regexp/syntax/prog.go
index c32ae8d..6c56371 100644
--- a/src/regexp/syntax/prog.go
+++ b/src/regexp/syntax/prog.go
@@ -247,15 +247,6 @@
 	return noMatch
 }
 
-// As per re2's Prog::IsWordChar. Determines whether rune is an ASCII word char.
-// Since we act on runes, it would be easy to support Unicode here.
-func wordRune(r rune) bool {
-	return r == '_' ||
-		('A' <= r && r <= 'Z') ||
-		('a' <= r && r <= 'z') ||
-		('0' <= r && r <= '9')
-}
-
 // MatchEmptyWidth reports whether the instruction matches
 // an empty string between the runes before and after.
 // It should only be called when i.Op == InstEmptyWidth.
@@ -270,9 +261,9 @@
 	case EmptyEndText:
 		return after == -1
 	case EmptyWordBoundary:
-		return wordRune(before) != wordRune(after)
+		return IsWordChar(before) != IsWordChar(after)
 	case EmptyNoWordBoundary:
-		return wordRune(before) == wordRune(after)
+		return IsWordChar(before) == IsWordChar(after)
 	}
 	panic("unknown empty width arg")
 }
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index 8d388da..89125f4 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -47,26 +47,25 @@
 func memhash0(p unsafe.Pointer, h uintptr) uintptr {
 	return h
 }
+
 func memhash8(p unsafe.Pointer, h uintptr) uintptr {
 	return memhash(p, h, 1)
 }
+
 func memhash16(p unsafe.Pointer, h uintptr) uintptr {
 	return memhash(p, h, 2)
 }
-func memhash32(p unsafe.Pointer, h uintptr) uintptr {
-	return memhash(p, h, 4)
-}
-func memhash64(p unsafe.Pointer, h uintptr) uintptr {
-	return memhash(p, h, 8)
-}
+
 func memhash128(p unsafe.Pointer, h uintptr) uintptr {
 	return memhash(p, h, 16)
 }
 
-// memhash_varlen is defined in assembly because it needs access
-// to the closure. It appears here to provide an argument
-// signature for the assembly routine.
-func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr
+//go:nosplit
+func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr {
+	ptr := getclosureptr()
+	size := *(*uintptr)(unsafe.Pointer(ptr + unsafe.Sizeof(h)))
+	return memhash(p, h, size)
+}
 
 var algarray = [alg_max]typeAlg{
 	alg_NOEQ:     {nil, nil},
diff --git a/src/runtime/append_test.go b/src/runtime/append_test.go
index 6bd8f3b..ef1e812 100644
--- a/src/runtime/append_test.go
+++ b/src/runtime/append_test.go
@@ -18,42 +18,52 @@
 	}
 }
 
-func BenchmarkGrowSliceBytes(b *testing.B) {
-	b.StopTimer()
-	var x = make([]byte, 9)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		_ = append([]byte(nil), x...)
-	}
-}
+type (
+	struct24 struct{ a, b, c int64 }
+	struct32 struct{ a, b, c, d int64 }
+	struct40 struct{ a, b, c, d, e int64 }
+)
 
-func BenchmarkGrowSliceInts(b *testing.B) {
-	b.StopTimer()
-	var x = make([]int, 9)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		_ = append([]int(nil), x...)
-	}
-}
+func BenchmarkGrowSlice(b *testing.B) {
+	b.Run("Byte", func(b *testing.B) {
+		x := make([]byte, 9)
+		for i := 0; i < b.N; i++ {
+			_ = append([]byte(nil), x...)
+		}
+	})
+	b.Run("Int", func(b *testing.B) {
+		x := make([]int, 9)
+		for i := 0; i < b.N; i++ {
+			_ = append([]int(nil), x...)
+		}
+	})
+	b.Run("Ptr", func(b *testing.B) {
+		x := make([]*byte, 9)
+		for i := 0; i < b.N; i++ {
+			_ = append([]*byte(nil), x...)
+		}
+	})
+	b.Run("Struct", func(b *testing.B) {
+		b.Run("24", func(b *testing.B) {
+			x := make([]struct24, 9)
+			for i := 0; i < b.N; i++ {
+				_ = append([]struct24(nil), x...)
+			}
+		})
+		b.Run("32", func(b *testing.B) {
+			x := make([]struct32, 9)
+			for i := 0; i < b.N; i++ {
+				_ = append([]struct32(nil), x...)
+			}
+		})
+		b.Run("40", func(b *testing.B) {
+			x := make([]struct40, 9)
+			for i := 0; i < b.N; i++ {
+				_ = append([]struct40(nil), x...)
+			}
+		})
 
-func BenchmarkGrowSlicePtr(b *testing.B) {
-	b.StopTimer()
-	var x = make([]*byte, 9)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		_ = append([]*byte(nil), x...)
-	}
-}
-
-type struct24 struct{ a, b, c int64 }
-
-func BenchmarkGrowSliceStruct24Bytes(b *testing.B) {
-	b.StopTimer()
-	var x = make([]struct24, 9)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		_ = append([]struct24(nil), x...)
-	}
+	})
 }
 
 func BenchmarkAppend(b *testing.B) {
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index 5bbf286..80a1451 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -7,10 +7,93 @@
 #include "funcdata.h"
 #include "textflag.h"
 
+// _rt0_386 is common startup code for most 386 systems when using
+// internal linking. This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program. The stack holds the
+// number of arguments and the C-style argv.
+TEXT _rt0_386(SB),NOSPLIT,$8
+	MOVL	8(SP), AX	// argc
+	LEAL	12(SP), BX	// argv
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	JMP	runtime·rt0_go(SB)
+
+// _rt0_386_lib is common startup code for most 386 systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed on the stack following the
+// usual C ABI.
+TEXT _rt0_386_lib(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	PUSHL	BX
+	PUSHL	SI
+	PUSHL	DI
+
+	MOVL	8(BP), AX
+	MOVL	AX, _rt0_386_lib_argc<>(SB)
+	MOVL	12(BP), AX
+	MOVL	AX, _rt0_386_lib_argv<>(SB)
+
+	// Synchronous initialization.
+	CALL	runtime·libpreinit(SB)
+
+	SUBL	$8, SP
+
+	// Create a new thread to do the runtime initialization.
+	MOVL	_cgo_sys_thread_create(SB), AX
+	TESTL	AX, AX
+	JZ	nocgo
+
+	// Align stack to call C function.
+	// We moved SP to BP above, but BP was clobbered by the libpreinit call.
+	MOVL	SP, BP
+	ANDL	$~15, SP
+
+	MOVL	$_rt0_386_lib_go(SB), BX
+	MOVL	BX, 0(SP)
+	MOVL	$0, 4(SP)
+
+	CALL	AX
+
+	MOVL	BP, SP
+
+	JMP	restore
+
+nocgo:
+	MOVL	$0x800000, 0(SP)                    // stacksize = 8192KB
+	MOVL	$_rt0_386_lib_go(SB), AX
+	MOVL	AX, 4(SP)                           // fn
+	CALL	runtime·newosproc0(SB)
+
+restore:
+	ADDL	$8, SP
+	POPL	DI
+	POPL	SI
+	POPL	BX
+	POPL	BP
+	RET
+
+// _rt0_386_lib_go initializes the Go runtime.
+// This is started in a separate thread by _rt0_386_lib.
+TEXT _rt0_386_lib_go(SB),NOSPLIT,$8
+	MOVL	_rt0_386_lib_argc<>(SB), AX
+	MOVL	AX, 0(SP)
+	MOVL	_rt0_386_lib_argv<>(SB), AX
+	MOVL	AX, 4(SP)
+	JMP	runtime·rt0_go(SB)
+
+DATA _rt0_386_lib_argc<>(SB)/4, $0
+GLOBL _rt0_386_lib_argc<>(SB),NOPTR, $4
+DATA _rt0_386_lib_argv<>(SB)/4, $0
+GLOBL _rt0_386_lib_argv<>(SB),NOPTR, $4
+
 TEXT runtime·rt0_go(SB),NOSPLIT,$0
-	// copy arguments forward on an even stack
-	MOVL	argc+0(FP), AX
-	MOVL	argv+4(FP), BX
+	// Copy arguments forward on an even stack.
+	// Users of this function jump to it, they don't call it.
+	MOVL	0(SP), AX
+	MOVL	4(SP), BX
 	SUBL	$128, SP		// plenty of scratch
 	ANDL	$~15, SP
 	MOVL	AX, 120(SP)		// save argc, argv away
@@ -279,18 +362,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $8-4
 	MOVL	buf+0(FP), BX		// gobuf
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVL	gobuf_ctxt(BX), DX
-	TESTL	DX, DX
-	JZ	nilctxt
-	LEAL	gobuf_ctxt(BX), AX
-	MOVL	AX, 0(SP)
-	MOVL	$0, 4(SP)
-	CALL	runtime·writebarrierptr_prewrite(SB)
-	MOVL	buf+0(FP), BX
-
-nilctxt:
 	MOVL	gobuf_g(BX), DX
 	MOVL	0(DX), CX		// make sure g != nil
 	get_tls(CX)
@@ -403,11 +474,12 @@
 	RET
 
 noswitch:
-	// already on system stack, just call directly
+	// already on system stack; tail call the function
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVL	DI, DX
 	MOVL	0(DI), DI
-	CALL	DI
-	RET
+	JMP	DI
 
 /*
  * support for morestack
@@ -453,7 +525,7 @@
 	MOVL	SI, (g_sched+gobuf_g)(SI)
 	LEAL	4(SP), AX	// f's SP
 	MOVL	AX, (g_sched+gobuf_sp)(SI)
-	// newstack will fill gobuf.ctxt.
+	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
 
 	// Call newstack on m->g0's stack.
 	MOVL	m_g0(BX), BP
@@ -461,10 +533,8 @@
 	MOVL	(g_sched+gobuf_sp)(BP), AX
 	MOVL	-4(AX), BX	// fault if CALL would, before smashing SP
 	MOVL	AX, SP
-	PUSHL	DX	// ctxt argument
 	CALL	runtime·newstack(SB)
 	MOVL	$0, 0x1003	// crash if newstack returns
-	POPL	DX	// keep balance check happy
 	RET
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
@@ -849,12 +919,6 @@
 	INT	$3
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$4-8
-	MOVL	argp+0(FP),AX		// addr of first arg
-	MOVL	-4(AX),AX		// get calling pc
-	MOVL	AX, ret+4(FP)
-	RET
-
 // func cputicks() int64
 TEXT runtime·cputicks(SB),NOSPLIT,$0-8
 	CMPB	runtime·support_sse2(SB), $1
@@ -885,23 +949,6 @@
 TEXT runtime·emptyfunc(SB),0,$0-0
 	RET
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVL	p+0(FP), AX
-	MOVL	h+4(FP), BX
-	MOVL	4(DX), CX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	MOVL	CX, 8(SP)
-	CALL	runtime·memhash(SB)
-	MOVL	12(SP), AX
-	MOVL	AX, ret+8(FP)
-	RET
-
 // hash function using AES hardware instructions
 TEXT runtime·aeshash(SB),NOSPLIT,$0-16
 	MOVL	p+0(FP), AX	// ptr to data
@@ -1323,23 +1370,6 @@
 	MOVB    $1, ret+8(FP)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-17
-	MOVL	s1_base+0(FP), SI
-	MOVL	s2_base+8(FP), DI
-	CMPL	SI, DI
-	JEQ	same
-	MOVL	s1_len+4(FP), BX
-	LEAL	ret+16(FP), AX
-	JMP	runtime·memeqbody(SB)
-same:
-	MOVB	$1, ret+16(FP)
-	RET
-
 TEXT bytes·Equal(SB),NOSPLIT,$0-25
 	MOVL	a_len+4(FP), BX
 	MOVL	b_len+16(FP), CX
@@ -1637,19 +1667,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	BYTE	$0x90	// NOP
 
-// Prefetching doesn't seem to help.
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
-	RET
-
 // Add a module's moduledata to the linked list of moduledata objects. This
 // is called from .init_array by a function generated in the linker and so
 // follows the platform ABI wrt register preservation -- it only touches AX,
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 6405be9..576a61c 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -7,6 +7,83 @@
 #include "funcdata.h"
 #include "textflag.h"
 
+// _rt0_amd64 is common startup code for most amd64 systems when using
+// internal linking. This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program. The stack holds the
+// number of arguments and the C-style argv.
+TEXT _rt0_amd64(SB),NOSPLIT,$-8
+	MOVQ	0(SP), DI	// argc
+	LEAQ	8(SP), SI	// argv
+	JMP	runtime·rt0_go(SB)
+
+// main is common startup code for most amd64 systems when using
+// external linking. The C startup code will call the symbol "main"
+// passing argc and argv in the usual C ABI registers DI and SI.
+TEXT main(SB),NOSPLIT,$-8
+	JMP	runtime·rt0_go(SB)
+
+// _rt0_amd64_lib is common startup code for most amd64 systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed in the usual C ABI registers
+// DI and SI.
+TEXT _rt0_amd64_lib(SB),NOSPLIT,$0x50
+	// Align stack per ELF ABI requirements.
+	MOVQ	SP, AX
+	ANDQ	$~15, SP
+	// Save C ABI callee-saved registers, as caller may need them.
+	MOVQ	BX, 0x10(SP)
+	MOVQ	BP, 0x18(SP)
+	MOVQ	R12, 0x20(SP)
+	MOVQ	R13, 0x28(SP)
+	MOVQ	R14, 0x30(SP)
+	MOVQ	R15, 0x38(SP)
+	MOVQ	AX, 0x40(SP)
+
+	MOVQ	DI, _rt0_amd64_lib_argc<>(SB)
+	MOVQ	SI, _rt0_amd64_lib_argv<>(SB)
+
+	// Synchronous initialization.
+	CALL	runtime·libpreinit(SB)
+
+	// Create a new thread to finish Go runtime initialization.
+	MOVQ	_cgo_sys_thread_create(SB), AX
+	TESTQ	AX, AX
+	JZ	nocgo
+	MOVQ	$_rt0_amd64_lib_go(SB), DI
+	MOVQ	$0, SI
+	CALL	AX
+	JMP	restore
+
+nocgo:
+	MOVQ	$0x800000, 0(SP)		// stacksize
+	MOVQ	$_rt0_amd64_lib_go(SB), AX
+	MOVQ	AX, 8(SP)			// fn
+	CALL	runtime·newosproc0(SB)
+
+restore:
+	MOVQ	0x10(SP), BX
+	MOVQ	0x18(SP), BP
+	MOVQ	0x20(SP), R12
+	MOVQ	0x28(SP), R13
+	MOVQ	0x30(SP), R14
+	MOVQ	0x38(SP), R15
+	MOVQ	0x40(SP), SP
+	RET
+
+// _rt0_amd64_lib_go initializes the Go runtime.
+// This is started in a separate thread by _rt0_amd64_lib.
+TEXT _rt0_amd64_lib_go(SB),NOSPLIT,$0
+	MOVQ	_rt0_amd64_lib_argc<>(SB), DI
+	MOVQ	_rt0_amd64_lib_argv<>(SB), SI
+	JMP	runtime·rt0_go(SB)
+
+DATA _rt0_amd64_lib_argc<>(SB)/8, $0
+GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
+DATA _rt0_amd64_lib_argv<>(SB)/8, $0
+GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
+
 TEXT runtime·rt0_go(SB),NOSPLIT,$0
 	// copy arguments forward on an even stack
 	MOVQ	DI, AX		// argc
@@ -227,18 +304,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $16-8
 	MOVQ	buf+0(FP), BX		// gobuf
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVQ	gobuf_ctxt(BX), AX
-	TESTQ	AX, AX
-	JZ	nilctxt
-	LEAQ	gobuf_ctxt(BX), AX
-	MOVQ	AX, 0(SP)
-	MOVQ	$0, 8(SP)
-	CALL	runtime·writebarrierptr_prewrite(SB)
-	MOVQ	buf+0(FP), BX
-
-nilctxt:
 	MOVQ	gobuf_g(BX), DX
 	MOVQ	0(DX), CX		// make sure g != nil
 	get_tls(CX)
@@ -354,11 +419,12 @@
 	RET
 
 noswitch:
-	// already on m stack, just call directly
+	// already on m stack; tail call the function
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVQ	DI, DX
 	MOVQ	0(DI), DI
-	CALL	DI
-	RET
+	JMP	DI
 
 /*
  * support for morestack
@@ -405,16 +471,14 @@
 	LEAQ	8(SP), AX // f's SP
 	MOVQ	AX, (g_sched+gobuf_sp)(SI)
 	MOVQ	BP, (g_sched+gobuf_bp)(SI)
-	// newstack will fill gobuf.ctxt.
+	MOVQ	DX, (g_sched+gobuf_ctxt)(SI)
 
 	// Call newstack on m->g0's stack.
 	MOVQ	m_g0(BX), BX
 	MOVQ	BX, g(CX)
 	MOVQ	(g_sched+gobuf_sp)(BX), SP
-	PUSHQ	DX	// ctxt argument
 	CALL	runtime·newstack(SB)
 	MOVQ	$0, 0x1003	// crash if newstack returns
-	POPQ	DX	// keep balance check happy
 	RET
 
 // morestack but not preserving ctxt.
@@ -833,12 +897,6 @@
 	INT	$3
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
-	MOVQ	argp+0(FP),AX		// addr of first arg
-	MOVQ	-8(AX),AX		// get calling pc
-	MOVQ	AX, ret+8(FP)
-	RET
-
 // func cputicks() int64
 TEXT runtime·cputicks(SB),NOSPLIT,$0-0
 	CMPB	runtime·lfenceBeforeRdtsc(SB), $1
@@ -854,23 +912,6 @@
 	MOVQ	AX, ret+0(FP)
 	RET
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$32-24
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVQ	p+0(FP), AX
-	MOVQ	h+8(FP), BX
-	MOVQ	8(DX), CX
-	MOVQ	AX, 0(SP)
-	MOVQ	BX, 8(SP)
-	MOVQ	CX, 16(SP)
-	CALL	runtime·memhash(SB)
-	MOVQ	24(SP), AX
-	MOVQ	AX, ret+16(FP)
-	RET
-
 // hash function using AES hardware instructions
 TEXT runtime·aeshash(SB),NOSPLIT,$0-32
 	MOVQ	p+0(FP), AX	// ptr to data
@@ -1343,23 +1384,6 @@
 	MOVB	$1, ret+16(FP)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-33
-	MOVQ	s1_base+0(FP), SI
-	MOVQ	s2_base+16(FP), DI
-	CMPQ	SI, DI
-	JEQ	eq
-	MOVQ	s1_len+8(FP), BX
-	LEAQ	ret+32(FP), AX
-	JMP	runtime·memeqbody(SB)
-eq:
-	MOVB	$1, ret+32(FP)
-	RET
-
 // a in SI
 // b in DI
 // count in BX
@@ -2339,26 +2363,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	BYTE	$0x90	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
-	MOVQ	addr+0(FP), AX
-	PREFETCHT0	(AX)
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
-	MOVQ	addr+0(FP), AX
-	PREFETCHT1	(AX)
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
-	MOVQ	addr+0(FP), AX
-	PREFETCHT2	(AX)
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
-	MOVQ	addr+0(FP), AX
-	PREFETCHNTA	(AX)
-	RET
-
 // This is called from .init_array and follows the platform, not Go, ABI.
 TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
 	PUSHQ	R15 // The access to global variables below implicitly uses R15, which is callee-save
@@ -2367,3 +2371,87 @@
 	MOVQ	DI, runtime·lastmoduledatap(SB)
 	POPQ	R15
 	RET
+
+// gcWriteBarrier performs a heap pointer write and informs the GC.
+//
+// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
+// - DI is the destination of the write
+// - AX is the value being written at DI
+// It clobbers FLAGS. It does not clobber any general-purpose registers,
+// but may clobber others (e.g., SSE registers).
+TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$120
+	// Save the registers clobbered by the fast path. This is slightly
+	// faster than having the caller spill these.
+	MOVQ	R14, 104(SP)
+	MOVQ	R13, 112(SP)
+	// TODO: Consider passing g.m.p in as an argument so they can be shared
+	// across a sequence of write barriers.
+	get_tls(R13)
+	MOVQ	g(R13), R13
+	MOVQ	g_m(R13), R13
+	MOVQ	m_p(R13), R13
+	MOVQ	(p_wbBuf+wbBuf_next)(R13), R14
+	// Increment wbBuf.next position.
+	LEAQ	16(R14), R14
+	MOVQ	R14, (p_wbBuf+wbBuf_next)(R13)
+	CMPQ	R14, (p_wbBuf+wbBuf_end)(R13)
+	// Record the write.
+	MOVQ	AX, -16(R14)	// Record value
+	MOVQ	(DI), R13	// TODO: This turns bad writes into bad reads.
+	MOVQ	R13, -8(R14)	// Record *slot
+	// Is the buffer full? (flags set in CMPQ above)
+	JEQ	flush
+ret:
+	MOVQ	104(SP), R14
+	MOVQ	112(SP), R13
+	// Do the write.
+	MOVQ	AX, (DI)
+	RET
+
+flush:
+	// Save all general purpose registers since these could be
+	// clobbered by wbBufFlush and were not saved by the caller.
+	// It is possible for wbBufFlush to clobber other registers
+	// (e.g., SSE registers), but the compiler takes care of saving
+	// those in the caller if necessary. This strikes a balance
+	// with registers that are likely to be used.
+	//
+	// We don't have type information for these, but all code under
+	// here is NOSPLIT, so nothing will observe these.
+	//
+	// TODO: We could strike a different balance; e.g., saving X0
+	// and not saving GP registers that are less likely to be used.
+	MOVQ	DI, 0(SP)	// Also first argument to wbBufFlush
+	MOVQ	AX, 8(SP)	// Also second argument to wbBufFlush
+	MOVQ	BX, 16(SP)
+	MOVQ	CX, 24(SP)
+	MOVQ	DX, 32(SP)
+	// DI already saved
+	MOVQ	SI, 40(SP)
+	MOVQ	BP, 48(SP)
+	MOVQ	R8, 56(SP)
+	MOVQ	R9, 64(SP)
+	MOVQ	R10, 72(SP)
+	MOVQ	R11, 80(SP)
+	MOVQ	R12, 88(SP)
+	// R13 already saved
+	// R14 already saved
+	MOVQ	R15, 96(SP)
+
+	// This takes arguments DI and AX
+	CALL	runtime·wbBufFlush(SB)
+
+	MOVQ	0(SP), DI
+	MOVQ	8(SP), AX
+	MOVQ	16(SP), BX
+	MOVQ	24(SP), CX
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), SI
+	MOVQ	48(SP), BP
+	MOVQ	56(SP), R8
+	MOVQ	64(SP), R9
+	MOVQ	72(SP), R10
+	MOVQ	80(SP), R11
+	MOVQ	88(SP), R12
+	MOVQ	96(SP), R15
+	JMP	ret
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
index 6367b3f..7fee79a 100644
--- a/src/runtime/asm_amd64p32.s
+++ b/src/runtime/asm_amd64p32.s
@@ -198,18 +198,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $8-4
 	MOVL	buf+0(FP), BX		// gobuf
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVL	gobuf_ctxt(BX), DX
-	TESTL	DX, DX
-	JZ	nilctxt
-	LEAL	gobuf_ctxt(BX), AX
-	MOVL	AX, 0(SP)
-	MOVL	$0, 4(SP)
-	CALL	runtime·writebarrierptr_prewrite(SB)
-	MOVL	buf+0(FP), BX
-
-nilctxt:
 	MOVL	gobuf_g(BX), DX
 	MOVL	0(DX), CX		// make sure g != nil
 	get_tls(CX)
@@ -318,10 +306,11 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVL	DI, DX
 	MOVL	0(DI), DI
-	CALL	DI
-	RET
+	JMP	DI
 
 /*
  * support for morestack
@@ -368,16 +357,14 @@
 	MOVL	SI, (g_sched+gobuf_g)(SI)
 	LEAL	8(SP), AX // f's SP
 	MOVL	AX, (g_sched+gobuf_sp)(SI)
-	// newstack will fill gobuf.ctxt.
+	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
-	PUSHQ	DX	// ctxt argument
 	CALL	runtime·newstack(SB)
 	MOVL	$0, 0x1003	// crash if newstack returns
-	POPQ	DX	// keep balance check happy
 	RET
 
 // morestack trampolines
@@ -559,30 +546,6 @@
 	MOVL	0, AX
 	RET
 
-TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-8
-	MOVL	ptr+0(FP), DI
-	MOVL	n+4(FP), CX
-	MOVQ	CX, BX
-	ANDQ	$3, BX
-	SHRQ	$2, CX
-	MOVQ	$0, AX
-	CLD
-	REP
-	STOSL
-	MOVQ	BX, CX
-	REP
-	STOSB
-	// Note: we zero only 4 bytes at a time so that the tail is at most
-	// 3 bytes. That guarantees that we aren't zeroing pointers with STOSB.
-	// See issue 13160.
-	RET
-
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-12
-	MOVL	argp+0(FP),AX		// addr of first arg
-	MOVL	-8(AX),AX		// get calling pc
-	MOVL	AX, ret+8(FP)
-	RET
-
 // int64 runtime·cputicks(void)
 TEXT runtime·cputicks(SB),NOSPLIT,$0-0
 	RDTSC
@@ -591,23 +554,6 @@
 	MOVQ	AX, ret+0(FP)
 	RET
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$24-12
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVL	p+0(FP), AX
-	MOVL	h+4(FP), BX
-	MOVL	4(DX), CX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	MOVL	CX, 8(SP)
-	CALL	runtime·memhash(SB)
-	MOVL	16(SP), AX
-	MOVL	AX, ret+8(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
@@ -658,24 +604,6 @@
 	MOVB    $1, ret+8(FP)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-17
-	MOVL	s1_base+0(FP), SI
-	MOVL	s2_base+8(FP), DI
-	CMPL	SI, DI
-	JEQ	same
-	MOVL	s1_len+4(FP), BX
-	CALL	runtime·memeqbody(SB)
-	MOVB	AX, ret+16(FP)
-	RET
-same:
-	MOVB	$1, ret+16(FP)
-	RET
-
 // a in SI
 // b in DI
 // count in BX
@@ -1042,27 +970,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	BYTE	$0x90	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
-	MOVL	addr+0(FP), AX
-	PREFETCHT0	(AX)
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
-	MOVL	addr+0(FP), AX
-	PREFETCHT1	(AX)
-	RET
-
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
-	MOVL	addr+0(FP), AX
-	PREFETCHT2	(AX)
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
-	MOVL	addr+0(FP), AX
-	PREFETCHNTA	(AX)
-	RET
-
 TEXT ·checkASM(SB),NOSPLIT,$0-1
 	MOVB	$1, ret+0(FP)
 	RET
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 09b6759..306984e 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -7,14 +7,112 @@
 #include "funcdata.h"
 #include "textflag.h"
 
+// _rt0_arm is common startup code for most ARM systems when using
+// internal linking. This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program. The stack holds the
+// number of arguments and the C-style argv.
+TEXT _rt0_arm(SB),NOSPLIT,$-4
+	MOVW	(R13), R0	// argc
+	MOVW	$4(R13), R1		// argv
+	B	runtime·rt0_go(SB)
+
+// main is common startup code for most ARM systems when using
+// external linking. The C startup code will call the symbol "main"
+// passing argc and argv in the usual C ABI registers R0 and R1.
+TEXT main(SB),NOSPLIT,$-4
+	B	runtime·rt0_go(SB)
+
+// _rt0_arm_lib is common startup code for most ARM systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed in the usual C ABI registers
+// R0 and R1.
+TEXT _rt0_arm_lib(SB),NOSPLIT,$104
+	// Preserve callee-save registers. Raspberry Pi's dlopen(), for example,
+	// actually cares that R11 is preserved.
+	MOVW	R4, 12(R13)
+	MOVW	R5, 16(R13)
+	MOVW	R6, 20(R13)
+	MOVW	R7, 24(R13)
+	MOVW	R8, 28(R13)
+	MOVW	R11, 32(R13)
+
+	// Skip floating point registers on GOARM < 6.
+	MOVB    runtime·goarm(SB), R11
+	CMP	$6, R11
+	BLT	skipfpsave
+	MOVD	F8, (32+8*1)(R13)
+	MOVD	F9, (32+8*2)(R13)
+	MOVD	F10, (32+8*3)(R13)
+	MOVD	F11, (32+8*4)(R13)
+	MOVD	F12, (32+8*5)(R13)
+	MOVD	F13, (32+8*6)(R13)
+	MOVD	F14, (32+8*7)(R13)
+	MOVD	F15, (32+8*8)(R13)
+skipfpsave:
+	// Save argc/argv.
+	MOVW	R0, _rt0_arm_lib_argc<>(SB)
+	MOVW	R1, _rt0_arm_lib_argv<>(SB)
+
+	// Synchronous initialization.
+	CALL	runtime·libpreinit(SB)
+
+	// Create a new thread to do the runtime initialization.
+	MOVW	_cgo_sys_thread_create(SB), R2
+	CMP	$0, R2
+	BEQ	nocgo
+	MOVW	$_rt0_arm_lib_go<>(SB), R0
+	MOVW	$0, R1
+	BL	(R2)
+	B	rr
+nocgo:
+	MOVW	$0x800000, R0                     // stacksize = 8192KB
+	MOVW	$_rt0_arm_lib_go<>(SB), R1  // fn
+	MOVW	R0, 4(R13)
+	MOVW	R1, 8(R13)
+	BL	runtime·newosproc0(SB)
+rr:
+	// Restore callee-save registers and return.
+	MOVB    runtime·goarm(SB), R11
+	CMP	$6, R11
+	BLT	skipfprest
+	MOVD	(32+8*1)(R13), F8
+	MOVD	(32+8*2)(R13), F9
+	MOVD	(32+8*3)(R13), F10
+	MOVD	(32+8*4)(R13), F11
+	MOVD	(32+8*5)(R13), F12
+	MOVD	(32+8*6)(R13), F13
+	MOVD	(32+8*7)(R13), F14
+	MOVD	(32+8*8)(R13), F15
+skipfprest:
+	MOVW	12(R13), R4
+	MOVW	16(R13), R5
+	MOVW	20(R13), R6
+	MOVW	24(R13), R7
+	MOVW	28(R13), R8
+	MOVW	32(R13), R11
+	RET
+
+// _rt0_arm_lib_go initializes the Go runtime.
+// This is started in a separate thread by _rt0_arm_lib.
+TEXT _rt0_arm_lib_go<>(SB),NOSPLIT,$8
+	MOVW	_rt0_arm_lib_argc<>(SB), R0
+	MOVW	_rt0_arm_lib_argv<>(SB), R1
+	B	runtime·rt0_go(SB)
+
+DATA _rt0_arm_lib_argc<>(SB)/4,$0
+GLOBL _rt0_arm_lib_argc<>(SB),NOPTR,$4
+DATA _rt0_arm_lib_argv<>(SB)/4,$0
+GLOBL _rt0_arm_lib_argv<>(SB),NOPTR,$4
+
 // using frame size $-4 means do not save LR on stack.
+// argc is in R0, argv is in R1.
 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
@@ -129,19 +227,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB),NOSPLIT,$8-4
 	MOVW	buf+0(FP), R1
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVW	gobuf_ctxt(R1), R0
-	CMP	$0, R0
-	B.EQ	nilctxt
-	MOVW	$gobuf_ctxt(R1), R0
-	MOVW	R0, 4(R13)
-	MOVW	$0, R0
-	MOVW	R0, 8(R13)
-	BL	runtime·writebarrierptr_prewrite(SB)
-	MOVW	buf+0(FP), R1
-
-nilctxt:
 	MOVW	gobuf_g(R1), R0
 	BL	setg<>(SB)
 
@@ -273,10 +358,12 @@
 	RET
 
 noswitch:
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVW	R0, R7
 	MOVW	0(R0), R0
-	BL	(R0)
-	RET
+	MOVW.P	4(R13), R14	// restore LR
+	B	(R0)
 
 /*
  * support for morestack
@@ -314,7 +401,7 @@
 	MOVW	R13, (g_sched+gobuf_sp)(g)
 	MOVW	LR, (g_sched+gobuf_pc)(g)
 	MOVW	R3, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVW	R7, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's caller.
@@ -328,8 +415,7 @@
 	BL	setg<>(SB)
 	MOVW	(g_sched+gobuf_sp)(g), R13
 	MOVW	$0, R0
-	MOVW.W	R0, -8(R13)	// create a call frame on g0
-	MOVW	R7, 4(R13)	// ctxt argument
+	MOVW.W  R0, -4(R13)	// create a call frame on g0 (saved LR)
 	BL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -677,9 +763,9 @@
 	MOVW	g, R0
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$4-8
-	MOVW	8(R13), R0		// LR saved by caller
-	MOVW	R0, ret+4(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
+	MOVW	0(R13), R0		// LR saved by caller
+	MOVW	R0, ret+0(FP)
 	RET
 
 TEXT runtime·emptyfunc(SB),0,$0-0
@@ -719,23 +805,6 @@
 	MOVW	$0, R0
 	MOVW	(R0), R1
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVW	p+0(FP), R0
-	MOVW	h+4(FP), R1
-	MOVW	4(R7), R2
-	MOVW	R0, 4(R13)
-	MOVW	R1, 8(R13)
-	MOVW	R2, 12(R13)
-	BL	runtime·memhash(SB)
-	MOVW	16(R13), R0
-	MOVW	R0, ret+8(FP)
-	RET
-
 // memequal(p, q unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$-4-13
 	MOVW	a+0(FP), R1
@@ -830,31 +899,6 @@
 	MOVW	R0, (R7)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
-	MOVW	s1_base+0(FP), R2
-	MOVW	s2_base+8(FP), R3
-	MOVW	$1, R8
-	MOVB	R8, ret+16(FP)
-	CMP	R2, R3
-	RET.EQ
-	MOVW	s1_len+4(FP), R0
-	ADD	R2, R0, R6
-loop:
-	CMP	R2, R6
-	RET.EQ
-	MOVBU.P	1(R2), R4
-	MOVBU.P	1(R3), R5
-	CMP	R4, R5
-	BEQ	loop
-	MOVW	$0, R8
-	MOVB	R8, ret+16(FP)
-	RET
-
 // TODO: share code with memequal?
 TEXT bytes·Equal(SB),NOSPLIT,$0-25
 	MOVW	a_len+4(FP), R1
@@ -973,18 +1017,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	MOVW	R0, R0	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
-	RET
-
 // x -> x/1000000, x%1000000, called from Go with args, results on stack.
 TEXT runtime·usplit(SB),NOSPLIT,$0-12
 	MOVW	x+0(FP), R0
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index 30ecec7..9bf0646 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -122,18 +122,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $24-8
 	MOVD	buf+0(FP), R5
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVD	gobuf_ctxt(R5), R0
-	CMP	$0, R0
-	BEQ	nilctxt
-	MOVD	$gobuf_ctxt(R5), R0
-	MOVD	R0, 8(RSP)
-	MOVD	ZR, 16(RSP)
-	BL	runtime·writebarrierptr_prewrite(SB)
-	MOVD	buf+0(FP), R5
-
-nilctxt:
 	MOVD	gobuf_g(R5), g
 	BL	runtime·save_g(SB)
 
@@ -251,9 +239,11 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVD	0(R26), R3	// code pointer
-	BL	(R3)
-	RET
+	MOVD.P	16(RSP), R30	// restore LR
+	B	(R3)
 
 /*
  * support for morestack
@@ -289,7 +279,7 @@
 	MOVD	R0, (g_sched+gobuf_sp)(g)
 	MOVD	LR, (g_sched+gobuf_pc)(g)
 	MOVD	R3, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVD	R26, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's callers.
@@ -303,8 +293,7 @@
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R0
 	MOVD	R0, RSP
-	MOVD.W	$0, -16(RSP)	// create a call frame on g0
-	MOVD	R26, 8(RSP)	// ctxt argument
+	MOVD.W	$0, -16(RSP)	// create a call frame on g0 (saved LR; keep 16-aligned)
 	BL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -368,16 +357,26 @@
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
 	MOVD	arg+16(FP), R3;			\
-	MOVWU	argsize+24(FP), R4;			\
-	MOVD	RSP, R5;				\
-	ADD	$(8-1), R5;			\
-	SUB	$1, R3;				\
-	ADD	R5, R4;				\
-	CMP	R5, R4;				\
-	BEQ	4(PC);				\
-	MOVBU.W	1(R3), R6;			\
-	MOVBU.W	R6, 1(R5);			\
-	B	-4(PC);				\
+	MOVWU	argsize+24(FP), R4;		\
+	ADD	$8, RSP, R5;			\
+	BIC	$0xf, R4, R6;			\
+	CBZ	R6, 6(PC);			\
+	/* if R6=(argsize&~15) != 0 */		\
+	ADD	R6, R5, R6;			\
+	/* copy 16 bytes a time */		\
+	LDP.P	16(R3), (R7, R8);		\
+	STP.P	(R7, R8), 16(R5);		\
+	CMP	R5, R6;				\
+	BNE	-3(PC);				\
+	AND	$0xf, R4, R6;			\
+	CBZ	R6, 6(PC);			\
+	/* if R6=(argsize&15) != 0 */		\
+	ADD	R6, R5, R6;			\
+	/* copy 1 byte a time for the rest */	\
+	MOVBU.P	1(R3), R7;			\
+	MOVBU.P	R7, 1(R5);			\
+	CMP	R5, R6;				\
+	BNE	-3(PC);				\
 	/* call function */			\
 	MOVD	f+8(FP), R26;			\
 	MOVD	(R26), R0;			\
@@ -704,52 +703,27 @@
 	MOVD	savedR27-8(SP), R27
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
-	MOVD	16(RSP), R0		// LR saved by caller
-	MOVD	R0, ret+8(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-8
+	MOVD	0(RSP), R0		// LR saved by caller
+	MOVD	R0, ret+0(FP)
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT,$-8-0
 	B	(ZR)
 	UNDEF
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVD	p+0(FP), R3
-	MOVD	h+8(FP), R4
-	MOVD	8(R26), R5
-	MOVD	R3, 8(RSP)
-	MOVD	R4, 16(RSP)
-	MOVD	R5, 24(RSP)
-	BL	runtime·memhash(SB)
-	MOVD	32(RSP), R3
-	MOVD	R3, ret+16(FP)
-	RET
-
-// memequal(p, q unsafe.Pointer, size uintptr) bool
+// memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$-8-25
-	MOVD	a+0(FP), R1
+	MOVD	size+16(FP), R1
+	// short path to handle 0-byte case
+	CBZ	R1, equal
+	MOVD	a+0(FP), R0
 	MOVD	b+8(FP), R2
-	MOVD	size+16(FP), R3
-	ADD	R1, R3, R6
+	MOVD	$ret+24(FP), R8
+	B	runtime·memeqbody<>(SB)
+equal:
 	MOVD	$1, R0
 	MOVB	R0, ret+24(FP)
-	CMP	R1, R2
-	BEQ	done
-loop:
-	CMP	R1, R6
-	BEQ	done
-	MOVBU.P	1(R1), R4
-	MOVBU.P	1(R2), R5
-	CMP	R4, R5
-	BEQ	loop
-
-	MOVB	$0, ret+24(FP)
-done:
 	RET
 
 // memequal_varlen(a, b unsafe.Pointer) bool
@@ -823,103 +797,235 @@
 	MOVD	R4, (R7)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-33
-	MOVD	s1_base+0(FP), R0
-	MOVD	s1_len+8(FP), R1
-	MOVD	s2_base+16(FP), R2
-	ADD	R0, R1		// end
-loop:
-	CMP	R0, R1
-	BEQ	equal		// reaches the end
-	MOVBU.P	1(R0), R4
-	MOVBU.P	1(R2), R5
-	CMP	R4, R5
-	BEQ	loop
-notequal:
-	MOVB	ZR, ret+32(FP)
-	RET
-equal:
-	MOVD	$1, R0
-	MOVB	R0, ret+32(FP)
-	RET
-
 //
 // functions for other packages
 //
 TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
 	MOVD	b+0(FP), R0
-	MOVD	b_len+8(FP), R1
-	MOVBU	c+24(FP), R2	// byte to find
-	MOVD	R0, R4		// store base for later
-	ADD	R0, R1		// end
-loop:
-	CMP	R0, R1
-	BEQ	notfound
-	MOVBU.P	1(R0), R3
-	CMP	R2, R3
-	BNE	loop
-
-	SUB	$1, R0		// R0 will be one beyond the position we want
-	SUB	R4, R0		// remove base
-	MOVD	R0, ret+32(FP)
-	RET
-
-notfound:
-	MOVD	$-1, R0
-	MOVD	R0, ret+32(FP)
-	RET
+	MOVD	b_len+8(FP), R2
+	MOVBU	c+24(FP), R1
+	MOVD	$ret+32(FP), R8
+	B	runtime·indexbytebody<>(SB)
 
 TEXT strings·IndexByte(SB),NOSPLIT,$0-32
 	MOVD	s+0(FP), R0
-	MOVD	s_len+8(FP), R1
-	MOVBU	c+16(FP), R2	// byte to find
-	MOVD	R0, R4		// store base for later
-	ADD	R0, R1		// end
+	MOVD	s_len+8(FP), R2
+	MOVBU	c+16(FP), R1
+	MOVD	$ret+24(FP), R8
+	B	runtime·indexbytebody<>(SB)
+
+// input:
+//   R0: data
+//   R1: byte to search
+//   R2: data len
+//   R8: address to put result
+TEXT runtime·indexbytebody<>(SB),NOSPLIT,$0
+	// Core algorithm:
+	// For each 32-byte chunk we calculate a 64-bit syndrome value,
+	// with two bits per byte. For each tuple, bit 0 is set if the
+	// relevant byte matched the requested character and bit 1 is
+	// not used (faster than using a 32bit syndrome). Since the bits
+	// in the syndrome reflect exactly the order in which things occur
+	// in the original string, counting trailing zeros allows to
+	// identify exactly which byte has matched.
+
+	CBZ	R2, fail
+	MOVD	R0, R11
+	// Magic constant 0x40100401 allows us to identify
+	// which lane matches the requested byte.
+	// 0x40100401 = ((1<<0) + (4<<8) + (16<<16) + (64<<24))
+	// Different bytes have different bit masks (i.e: 1, 4, 16, 64)
+	MOVD	$0x40100401, R5
+	VMOV	R1, V0.B16
+	// Work with aligned 32-byte chunks
+	BIC	$0x1f, R0, R3
+	VMOV	R5, V5.S4
+	ANDS	$0x1f, R0, R9
+	AND	$0x1f, R2, R10
+	BEQ	loop
+
+	// Input string is not 32-byte aligned. We calculate the
+	// syndrome value for the aligned 32 bytes block containing
+	// the first bytes and mask off the irrelevant part.
+	VLD1.P	(R3), [V1.B16, V2.B16]
+	SUB	$0x20, R9, R4
+	ADDS	R4, R2, R2
+	VCMEQ	V0.B16, V1.B16, V3.B16
+	VCMEQ	V0.B16, V2.B16, V4.B16
+	VAND	V5.B16, V3.B16, V3.B16
+	VAND	V5.B16, V4.B16, V4.B16
+	VADDP	V4.B16, V3.B16, V6.B16 // 256->128
+	VADDP	V6.B16, V6.B16, V6.B16 // 128->64
+	VMOV	V6.D[0], R6
+	// Clear the irrelevant lower bits
+	LSL	$1, R9, R4
+	LSR	R4, R6, R6
+	LSL	R4, R6, R6
+	// The first block can also be the last
+	BLS	masklast
+	// Have we found something already?
+	CBNZ	R6, tail
+
 loop:
-	CMP	R0, R1
-	BEQ	notfound
-	MOVBU.P	1(R0), R3
-	CMP	R2, R3
-	BNE	loop
+	VLD1.P	(R3), [V1.B16, V2.B16]
+	SUBS	$0x20, R2, R2
+	VCMEQ	V0.B16, V1.B16, V3.B16
+	VCMEQ	V0.B16, V2.B16, V4.B16
+	// If we're out of data we finish regardless of the result
+	BLS	end
+	// Use a fast check for the termination condition
+	VORR	V4.B16, V3.B16, V6.B16
+	VADDP	V6.D2, V6.D2, V6.D2
+	VMOV	V6.D[0], R6
+	// We're not out of data, loop if we haven't found the character
+	CBZ	R6, loop
 
-	SUB	$1, R0		// R0 will be one beyond the position we want
-	SUB	R4, R0		// remove base
-	MOVD	R0, ret+24(FP)
+end:
+	// Termination condition found, let's calculate the syndrome value
+	VAND	V5.B16, V3.B16, V3.B16
+	VAND	V5.B16, V4.B16, V4.B16
+	VADDP	V4.B16, V3.B16, V6.B16
+	VADDP	V6.B16, V6.B16, V6.B16
+	VMOV	V6.D[0], R6
+	// Only do the clear for the last possible block with less than 32 bytes
+	// Condition flags come from SUBS in the loop
+	BHS	tail
+
+masklast:
+	// Clear the irrelevant upper bits
+	ADD	R9, R10, R4
+	AND	$0x1f, R4, R4
+	SUB	$0x20, R4, R4
+	NEG	R4<<1, R4
+	LSL	R4, R6, R6
+	LSR	R4, R6, R6
+
+tail:
+	// Check that we have found a character
+	CBZ	R6, fail
+	// Count the trailing zeros using bit reversing
+	RBIT	R6, R6
+	// Compensate the last post-increment
+	SUB	$0x20, R3, R3
+	// And count the leading zeros
+	CLZ	R6, R6
+	// R6 is twice the offset into the fragment
+	ADD	R6>>1, R3, R0
+	// Compute the offset result
+	SUB	R11, R0, R0
+	MOVD	R0, (R8)
 	RET
 
-notfound:
+fail:
 	MOVD	$-1, R0
-	MOVD	R0, ret+24(FP)
+	MOVD	R0, (R8)
 	RET
 
-// TODO: share code with memequal?
+// Equal(a, b []byte) bool
 TEXT bytes·Equal(SB),NOSPLIT,$0-49
 	MOVD	a_len+8(FP), R1
 	MOVD	b_len+32(FP), R3
-	CMP	R1, R3		// unequal lengths are not equal
-	BNE	notequal
+	CMP	R1, R3
+	// unequal lengths are not equal
+	BNE	not_equal
+	// short path to handle 0-byte case
+	CBZ	R1, equal
 	MOVD	a+0(FP), R0
 	MOVD	b+24(FP), R2
-	ADD	R0, R1		// end
-loop:
-	CMP	R0, R1
-	BEQ	equal		// reaches the end
-	MOVBU.P	1(R0), R4
-	MOVBU.P	1(R2), R5
-	CMP	R4, R5
-	BEQ	loop
-notequal:
-	MOVB	ZR, ret+48(FP)
-	RET
+	MOVD	$ret+48(FP), R8
+	B	runtime·memeqbody<>(SB)
 equal:
 	MOVD	$1, R0
 	MOVB	R0, ret+48(FP)
 	RET
+not_equal:
+	MOVB	ZR, ret+48(FP)
+	RET
+
+// input:
+// R0: pointer a
+// R1: data len
+// R2: pointer b
+// R8: address to put result
+TEXT runtime·memeqbody<>(SB),NOSPLIT,$0
+	CMP	$1, R1
+	// handle 1-byte special case for better performance
+	BEQ	one
+	CMP	$16, R1
+	// handle specially if length < 16
+	BLO	tail
+	BIC	$0x3f, R1, R3
+	CBZ	R3, chunk16
+	// work with 64-byte chunks
+	ADD	R3, R0, R6	// end of chunks
+chunk64_loop:
+	VLD1.P	(R0), [V0.D2, V1.D2, V2.D2, V3.D2]
+	VLD1.P	(R2), [V4.D2, V5.D2, V6.D2, V7.D2]
+	VCMEQ	V0.D2, V4.D2, V8.D2
+	VCMEQ	V1.D2, V5.D2, V9.D2
+	VCMEQ	V2.D2, V6.D2, V10.D2
+	VCMEQ	V3.D2, V7.D2, V11.D2
+	VAND	V8.B16, V9.B16, V8.B16
+	VAND	V8.B16, V10.B16, V8.B16
+	VAND	V8.B16, V11.B16, V8.B16
+	CMP	R0, R6
+	VMOV	V8.D[0], R4
+	VMOV	V8.D[1], R5
+	CBZ	R4, not_equal
+	CBZ	R5, not_equal
+	BNE	chunk64_loop
+	AND	$0x3f, R1, R1
+	CBZ	R1, equal
+chunk16:
+	// work with 16-byte chunks
+	BIC	$0xf, R1, R3
+	CBZ	R3, tail
+	ADD	R3, R0, R6	// end of chunks
+chunk16_loop:
+	VLD1.P	(R0), [V0.D2]
+	VLD1.P	(R2), [V1.D2]
+	VCMEQ	V0.D2, V1.D2, V2.D2
+	CMP	R0, R6
+	VMOV	V2.D[0], R4
+	VMOV	V2.D[1], R5
+	CBZ	R4, not_equal
+	CBZ	R5, not_equal
+	BNE	chunk16_loop
+	AND	$0xf, R1, R1
+	CBZ	R1, equal
+tail:
+	// special compare of tail with length < 16
+	TBZ	$3, R1, lt_8
+	MOVD.P	8(R0), R4
+	MOVD.P	8(R2), R5
+	CMP	R4, R5
+	BNE	not_equal
+lt_8:
+	TBZ	$2, R1, lt_4
+	MOVWU.P	4(R0), R4
+	MOVWU.P	4(R2), R5
+	CMP	R4, R5
+	BNE	not_equal
+lt_4:
+	TBZ	$1, R1, lt_2
+	MOVHU.P	2(R0), R4
+	MOVHU.P	2(R2), R5
+	CMP	R4, R5
+	BNE	not_equal
+lt_2:
+	TBZ     $0, R1, equal
+one:
+	MOVBU	(R0), R4
+	MOVBU	(R2), R5
+	CMP	R4, R5
+	BNE	not_equal
+equal:
+	MOVD	$1, R0
+	MOVB	R0, (R8)
+	RET
+not_equal:
+	MOVB	ZR, (R8)
+	RET
 
 TEXT runtime·return0(SB), NOSPLIT, $0
 	MOVW	$0, R0
@@ -931,19 +1037,6 @@
 	MOVD	R0, R0	// NOP
 	BL	runtime·goexit1(SB)	// does not return
 
-// TODO(aram): use PRFM here.
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
-	RET
-
 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
 	RET
 
diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s
index 57d4578..12cea00 100644
--- a/src/runtime/asm_mips64x.s
+++ b/src/runtime/asm_mips64x.s
@@ -108,17 +108,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $16-8
 	MOVV	buf+0(FP), R3
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVV	gobuf_ctxt(R3), R1
-	BEQ	R1, nilctxt
-	MOVV	$gobuf_ctxt(R3), R1
-	MOVV	R1, 8(R29)
-	MOVV	R0, 16(R29)
-	JAL	runtime·writebarrierptr_prewrite(SB)
-	MOVV	buf+0(FP), R3
-
-nilctxt:
 	MOVV	gobuf_g(R3), g	// make sure g is not nil
 	JAL	runtime·save_g(SB)
 
@@ -225,9 +214,12 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVV	0(REGCTXT), R4	// code pointer
-	JAL	(R4)
-	RET
+	MOVV	0(R29), R31	// restore LR
+	ADDV	$8, R29
+	JMP	(R4)
 
 /*
  * support for morestack
@@ -260,7 +252,7 @@
 	MOVV	R29, (g_sched+gobuf_sp)(g)
 	MOVV	R31, (g_sched+gobuf_pc)(g)
 	MOVV	R3, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVV	REGCTXT, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's caller.
@@ -273,9 +265,8 @@
 	JAL	runtime·save_g(SB)
 	MOVV	(g_sched+gobuf_sp)(g), R29
 	// Create a stack frame on g0 to call newstack.
-	MOVV	R0, -16(R29)	// Zero saved LR in frame
-	ADDV	$-16, R29
-	MOVV	REGCTXT, 8(R29)	// ctxt argument
+	MOVV	R0, -8(R29)	// Zero saved LR in frame
+	ADDV	$-8, R29
 	JAL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -616,32 +607,15 @@
 	JAL	runtime·save_g(SB)
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
-	MOVV	16(R29), R1		// LR saved by caller
-	MOVV	R1, ret+8(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-8
+	MOVV	0(R29), R1		// LR saved by caller
+	MOVV	R1, ret+0(FP)
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT,$-8-0
 	MOVW	(R0), R0
 	UNDEF
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVV	p+0(FP), R1
-	MOVV	h+8(FP), R2
-	MOVV	8(REGCTXT), R3
-	MOVV	R1, 8(R29)
-	MOVV	R2, 16(R29)
-	MOVV	R3, 24(R29)
-	JAL	runtime·memhash(SB)
-	MOVV	32(R29), R1
-	MOVV	R1, ret+16(FP)
-	RET
-
 // AES hashing not implemented for mips64
 TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
 	MOVW	(R0), R1
@@ -696,31 +670,6 @@
 	MOVB	R1, ret+16(FP)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-33
-	MOVV	s1_base+0(FP), R1
-	MOVV	s2_base+16(FP), R2
-	MOVV	$1, R3
-	MOVB	R3, ret+32(FP)
-	BNE	R1, R2, 2(PC)
-	RET
-	MOVV	s1_len+8(FP), R3
-	ADDV	R1, R3, R4
-loop:
-	BNE	R1, R4, 2(PC)
-	RET
-	MOVBU	(R1), R6
-	ADDV	$1, R1
-	MOVBU	(R2), R7
-	ADDV	$1, R2
-	BEQ	R6, R7, loop
-	MOVB	R0, ret+32(FP)
-	RET
-
 // TODO: share code with memequal?
 TEXT bytes·Equal(SB),NOSPLIT,$0-49
 	MOVV	a_len+8(FP), R3
@@ -823,18 +772,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	NOR	R0, R0	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
-	RET
-
 TEXT ·checkASM(SB),NOSPLIT,$0-1
 	MOVW	$1, R1
 	MOVB	R1, ret+0(FP)
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s
index 536c315..bba6a95 100644
--- a/src/runtime/asm_mipsx.s
+++ b/src/runtime/asm_mipsx.s
@@ -109,17 +109,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB),NOSPLIT,$8-4
 	MOVW	buf+0(FP), R3
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVW	gobuf_ctxt(R3), R1
-	BEQ	R1, nilctxt
-	MOVW	$gobuf_ctxt(R3), R1
-	MOVW	R1, 4(R29)
-	MOVW	R0, 8(R29)
-	JAL	runtime·writebarrierptr_prewrite(SB)
-	MOVW	buf+0(FP), R3
-
-nilctxt:
 	MOVW	gobuf_g(R3), g	// make sure g is not nil
 	JAL	runtime·save_g(SB)
 
@@ -226,9 +215,12 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVW	0(REGCTXT), R4	// code pointer
-	JAL	(R4)
-	RET
+	MOVW	0(R29), R31	// restore LR
+	ADD	$4, R29
+	JMP	(R4)
 
 /*
  * support for morestack
@@ -261,7 +253,7 @@
 	MOVW	R29, (g_sched+gobuf_sp)(g)
 	MOVW	R31, (g_sched+gobuf_pc)(g)
 	MOVW	R3, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVW	REGCTXT, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's caller.
@@ -274,9 +266,8 @@
 	JAL	runtime·save_g(SB)
 	MOVW	(g_sched+gobuf_sp)(g), R29
 	// Create a stack frame on g0 to call newstack.
-	MOVW	R0, -8(R29)	// Zero saved LR in frame
-	ADDU	$-8, R29
-	MOVW	REGCTXT, 4(R29)	// ctxt argument
+	MOVW	R0, -4(R29)	// Zero saved LR in frame
+	ADDU	$-4, R29
 	JAL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -619,31 +610,14 @@
 	JAL	runtime·save_g(SB)
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$4-8
-	MOVW	8(R29), R1	// LR saved by caller
-	MOVW	R1, ret+4(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
+	MOVW	0(R29), R1	// LR saved by caller
+	MOVW	R1, ret+0(FP)
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT,$0-0
 	UNDEF
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVW	p+0(FP), R1
-	MOVW	h+4(FP), R2
-	MOVW	4(REGCTXT), R3
-	MOVW	R1, 4(R29)
-	MOVW	R2, 8(R29)
-	MOVW	R3, 12(R29)
-	JAL	runtime·memhash(SB)
-	MOVW	16(R29), R1
-	MOVW	R1, ret+8(FP)
-	RET
-
 // Not implemented.
 TEXT runtime·aeshash(SB),NOSPLIT,$0
 	UNDEF
@@ -712,31 +686,6 @@
 	MOVB	R1, ret+8(FP)
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-17
-	MOVW	s1_base+0(FP), R1
-	MOVW	s2_base+8(FP), R2
-	MOVW	$1, R3
-	MOVBU	R3, ret+16(FP)
-	BNE	R1, R2, 2(PC)
-	RET
-	MOVW	s1_len+4(FP), R3
-	ADDU	R1, R3, R4
-loop:
-	BNE	R1, R4, 2(PC)
-	RET
-	MOVBU	(R1), R6
-	ADDU	$1, R1
-	MOVBU	(R2), R7
-	ADDU	$1, R2
-	BEQ	R6, R7, loop
-	MOVB	R0, ret+16(FP)
-	RET
-
 TEXT bytes·Equal(SB),NOSPLIT,$0-25
 	MOVW	a_len+4(FP), R3
 	MOVW	b_len+16(FP), R4
@@ -903,18 +852,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	NOR	R0, R0	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
-	RET
-
 TEXT ·checkASM(SB),NOSPLIT,$0-1
 	MOVW	$1, R1
 	MOVB	R1, ret+0(FP)
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 616861e..e02ca16 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -133,18 +133,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $16-8
 	MOVD	buf+0(FP), R5
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVD	gobuf_ctxt(R5), R3
-	CMP	R0, R3
-	BEQ	nilctxt
-	MOVD	$gobuf_ctxt(R5), R3
-	MOVD	R3, FIXED_FRAME+0(R1)
-	MOVD	R0, FIXED_FRAME+8(R1)
-	BL	runtime·writebarrierptr_prewrite(SB)
-	MOVD	buf+0(FP), R5
-
-nilctxt:
 	MOVD	gobuf_g(R5), g	// make sure g is not nil
 	BL	runtime·save_g(SB)
 
@@ -277,6 +265,9 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// On other arches we do a tail call here, but it appears to be
+	// impossible to tail call a function pointer in shared mode on
+	// ppc64 because the caller is responsible for restoring the TOC.
 	MOVD	0(R11), R12	// code pointer
 	MOVD	R12, CTR
 	BL	(CTR)
@@ -317,7 +308,7 @@
 	MOVD	LR, R8
 	MOVD	R8, (g_sched+gobuf_pc)(g)
 	MOVD	R5, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVD	R11, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's caller.
@@ -329,8 +320,7 @@
 	MOVD	m_g0(R7), g
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R1
-	MOVDU   R0, -(FIXED_FRAME+8)(R1)	// create a call frame on g0
-	MOVD	R11, FIXED_FRAME+0(R1)	// ctxt argument
+	MOVDU   R0, -(FIXED_FRAME+0)(R1)	// create a call frame on g0
 	BL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -714,9 +704,9 @@
 	MOVD	R4, LR
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
-	MOVD	FIXED_FRAME+8(R1), R3		// LR saved by caller
-	MOVD	R3, ret+8(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT|NOFRAME,$0-8
+	MOVD	0(R1), R3		// LR saved by caller
+	MOVD	R3, ret+0(FP)
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
@@ -738,23 +728,6 @@
 	MOVD	R3, ret+0(FP)
 	RET
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVD	p+0(FP), R3
-	MOVD	h+8(FP), R4
-	MOVD	8(R11), R5
-	MOVD	R3, FIXED_FRAME+0(R1)
-	MOVD	R4, FIXED_FRAME+8(R1)
-	MOVD	R5, FIXED_FRAME+16(R1)
-	BL	runtime·memhash(SB)
-	MOVD	FIXED_FRAME+24(R1), R3
-	MOVD	R3, ret+16(FP)
-	RET
-
 // AES hashing not implemented for ppc64
 TEXT runtime·aeshash(SB),NOSPLIT|NOFRAME,$0-0
 	MOVW	(R0), R1
@@ -1074,24 +1047,6 @@
 	MOVD    $1, R9
 	RET
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT,$0-33
-	MOVD    s1_base+0(FP), R3
-	MOVD    s2_base+16(FP), R4
-	MOVD    $1, R5
-	MOVB    R5, ret+32(FP)
-	CMP     R3, R4
-	BNE     2(PC)
-	RET
-	MOVD    s1_len+8(FP), R5
-	BL      runtime·memeqbody(SB)
-	MOVB    R9, ret+32(FP)
-	RET
-
 TEXT bytes·Equal(SB),NOSPLIT,$0-49
 	MOVD	a_len+8(FP), R4
 	MOVD	b_len+32(FP), R5
@@ -1129,24 +1084,17 @@
 
 TEXT runtime·indexbytebody<>(SB),NOSPLIT|NOFRAME,$0-0
 	DCBT	(R3)		// Prepare cache line.
-	MOVD	R3,R10		// Save base address for calculating the index later.
+	MOVD	R3,R17		// Save base address for calculating the index later.
 	RLDICR	$0,R3,$60,R8	// Align address to doubleword boundary in R8.
 	RLDIMI	$8,R5,$48,R5	// Replicating the byte across the register.
-
-	// Calculate last acceptable address and check for possible overflow
-	// using a saturated add.
-	// Overflows set last acceptable address to 0xffffffffffffffff.
-	ADD	R4,R3,R7
-	SUBC	R3,R7,R6
-	SUBE	R0,R0,R9
-	MOVW	R9,R6
-	OR	R6,R7,R7
+	ADD	R4,R3,R7	// Last acceptable address in R7.
 
 	RLDIMI	$16,R5,$32,R5
 	CMPU	R4,$32		// Check if it's a small string (<32 bytes). Those will be processed differently.
 	MOVD	$-1,R9
-	WORD $0x54661EB8	// Calculate padding in R6 (rlwinm r6,r3,3,26,28).
+	WORD	$0x54661EB8	// Calculate padding in R6 (rlwinm r6,r3,3,26,28).
 	RLDIMI	$32,R5,$0,R5
+	MOVD	R7,R10		// Save last acceptable address in R10 for later.
 	ADD	$-1,R7,R7
 #ifdef GOARCH_ppc64le
 	SLD	R6,R9,R9	// Prepare mask for Little Endian
@@ -1155,56 +1103,142 @@
 #endif
 	BLE	small_string	// Jump to the small string case if it's <32 bytes.
 
-	// Case for length >32 bytes
+	// If we are 64-byte aligned, branch to qw_align just to get the auxiliary values
+	// in V0, V1 and V10, then branch to the preloop.
+	ANDCC	$63,R3,R11
+	BEQ	CR0,qw_align
+	RLDICL	$0,R3,$61,R11
+
 	MOVD	0(R8),R12	// Load one doubleword from the aligned address in R8.
 	CMPB	R12,R5,R3	// Check for a match.
 	AND	R9,R3,R3	// Mask bytes below s_base
-	RLDICL	$0,R7,$61,R4	// length-1
+	RLDICL	$0,R7,$61,R6	// length-1
 	RLDICR	$0,R7,$60,R7	// Last doubleword in R7
 	CMPU	R3,$0,CR7	// If we have a match, jump to the final computation
 	BNE	CR7,done
+	ADD	$8,R8,R8
+	ADD	$-8,R4,R4
+	ADD	R4,R11,R4
 
-	// Check for doubleword alignment and jump to the loop setup if aligned.
-	MOVFL	R8,CR7
-	BC	12,28,loop_setup
+	// Check for quadword alignment
+	ANDCC	$15,R8,R11
+	BEQ	CR0,qw_align
 
-	// Not aligned, so handle the second doubleword
-	MOVDU	8(R8),R12
+	// Not aligned, so handle the next doubleword
+	MOVD	0(R8),R12
 	CMPB	R12,R5,R3
 	CMPU	R3,$0,CR7
 	BNE	CR7,done
+	ADD	$8,R8,R8
+	ADD	$-8,R4,R4
 
-loop_setup:
-	// We are now aligned to a 16-byte boundary. We will load two doublewords
-	// per loop iteration. The last doubleword is in R7, so our loop counter
-	// starts at (R7-R8)/16.
-	SUB	R8,R7,R6
-	SRD	$4,R6,R6
-	MOVD	R6,CTR
+	// Either quadword aligned or 64-byte at this point. We can use LVX.
+qw_align:
 
-	// Note: when we have an align directive, align this loop to 32 bytes so
-	// it fits in a single icache sector.
+	// Set up auxiliary data for the vectorized algorithm.
+	VSPLTISB  $0,V0		// Replicate 0 across V0
+	VSPLTISB  $3,V10	// Use V10 as control for VBPERMQ
+	MTVRD	  R5,V1
+	LVSL	  (R0+R0),V11
+	VSLB	  V11,V10,V10
+	VSPLTB	  $7,V1,V1	// Replicate byte across V1
+	CMPU	  R4, $64	// If len <= 64, don't use the vectorized loop
+	BLE	  tail
+
+	// We will load 4 quardwords per iteration in the loop, so check for
+	// 64-byte alignment. If 64-byte aligned, then branch to the preloop.
+	ANDCC	  $63,R8,R11
+	BEQ	  CR0,preloop
+
+	// Not 64-byte aligned. Load one quadword at a time until aligned.
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6		// Check for byte in V4
+	BNE	    CR6,found_qw_align
+	ADD	    $16,R8,R8
+	ADD	    $-16,R4,R4
+
+	ANDCC	    $63,R8,R11
+	BEQ	    CR0,preloop
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6		// Check for byte in V4
+	BNE	    CR6,found_qw_align
+	ADD	    $16,R8,R8
+	ADD	    $-16,R4,R4
+
+	ANDCC	    $63,R8,R11
+	BEQ	    CR0,preloop
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6		// Check for byte in V4
+	BNE	    CR6,found_qw_align
+	ADD	    $-16,R4,R4
+	ADD	    $16,R8,R8
+
+	// 64-byte aligned. Prepare for the main loop.
+preloop:
+	CMPU	R4,$64
+	BLE	tail	      // If len <= 64, don't use the vectorized loop
+
+	// We are now aligned to a 64-byte boundary. We will load 4 quadwords
+	// per loop iteration. The last doubleword is in R10, so our loop counter
+	// starts at (R10-R8)/64.
+	SUB	R8,R10,R6
+	SRD	$6,R6,R9      // Loop counter in R9
+	MOVD	R9,CTR
+
+	MOVD	$16,R11      // Load offsets for the vector loads
+	MOVD	$32,R9
+	MOVD	$48,R7
+
+	// Main loop we will load 64 bytes per iteration
 loop:
-	// Load two doublewords, then compare and merge in a single register. We
-	// will check two doublewords per iteration, then find out which of them
-	// contains the byte later. This speeds up the search.
-	MOVD	8(R8),R12
-	MOVDU	16(R8),R11
-	CMPB	R12,R5,R3
-	CMPB	R11,R5,R9
-	OR	R3,R9,R6
-	CMPU	R6,$0,CR7
-	BNE	CR7,found
-	BC	16,0,loop
+	LVX	    (R8+R0),V2	      // Load 4 16-byte vectors
+	LVX	    (R11+R8),V3
+	LVX	    (R9+R8),V4
+	LVX	    (R7+R8),V5
+	VCMPEQUB    V1,V2,V6	      // Look for byte in each vector
+	VCMPEQUB    V1,V3,V7
+	VCMPEQUB    V1,V4,V8
+	VCMPEQUB    V1,V5,V9
+	VOR	    V6,V7,V11	      // Compress the result in a single vector
+	VOR	    V8,V9,V12
+	VOR	    V11,V12,V11
+	VCMPEQUBCC  V0,V11,V11	      // Check for byte
+	BGE	    CR6,found
+	ADD	    $64,R8,R8
+	BC	    16,0,loop	      // bdnz loop
 
-	// Counter zeroed, but we may have another doubleword to read
-	CMPU	R8,R7
-	BEQ	notfound
+	// Handle the tailing bytes or R4 <= 64
+	RLDICL	$0,R6,$58,R4
+tail:
+	CMPU	    R4,$0
+	BEQ	    notfound
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6
+	BNE	    CR6,found_qw_align
+	ADD	    $16,R8,R8
+	CMPU	    R4,$16,CR6
+	BLE	    CR6,notfound
+	ADD	    $-16,R4,R4
 
-	MOVDU	8(R8),R12
-	CMPB	R12,R5,R3
-	CMPU	R3,$0,CR6
-	BNE	CR6,done
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6
+	BNE	    CR6,found_qw_align
+	ADD	    $16,R8,R8
+	CMPU	    R4,$16,CR6
+	BLE	    CR6,notfound
+	ADD	    $-16,R4,R4
+
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6
+	BNE	    CR6,found_qw_align
+	ADD	    $16,R8,R8
+	CMPU	    R4,$16,CR6
+	BLE	    CR6,notfound
+	ADD	    $-16,R4,R4
+
+	LVX	    (R8+R0),V4
+	VCMPEQUBCC  V1,V4,V6
+	BNE	    CR6,found_qw_align
 
 notfound:
 	MOVD	$-1,R3
@@ -1212,15 +1246,68 @@
 	RET
 
 found:
-	// One of the doublewords from the loop contains the byte we are looking
-	// for. Check the first doubleword and adjust the address if found.
-	CMPU	R3,$0,CR6
-	ADD	$-8,R8,R8
-	BNE	CR6,done
+	// We will now compress the results into a single doubleword,
+	// so it can be moved to a GPR for the final index calculation.
 
-	// Not found, so it must be in the second doubleword of the merged pair.
-	MOVD	R9,R3
-	ADD	$8,R8,R8
+	// The bytes in V6-V9 are either 0x00 or 0xFF. So, permute the
+	// first bit of each byte into bits 48-63.
+	VBPERMQ	  V6,V10,V6
+	VBPERMQ	  V7,V10,V7
+	VBPERMQ	  V8,V10,V8
+	VBPERMQ	  V9,V10,V9
+
+	// Shift each 16-bit component into its correct position for
+	// merging into a single doubleword.
+#ifdef GOARCH_ppc64le
+	VSLDOI	  $2,V7,V7,V7
+	VSLDOI	  $4,V8,V8,V8
+	VSLDOI	  $6,V9,V9,V9
+#else
+	VSLDOI	  $6,V6,V6,V6
+	VSLDOI	  $4,V7,V7,V7
+	VSLDOI	  $2,V8,V8,V8
+#endif
+
+	// Merge V6-V9 into a single doubleword and move to a GPR.
+	VOR	V6,V7,V11
+	VOR	V8,V9,V4
+	VOR	V4,V11,V4
+	MFVRD	V4,R3
+
+#ifdef GOARCH_ppc64le
+	ADD	  $-1,R3,R11
+	ANDN	  R3,R11,R11
+	POPCNTD	  R11,R11	// Count trailing zeros (Little Endian).
+#else
+	CNTLZD	R3,R11		// Count leading zeros (Big Endian).
+#endif
+	ADD	R8,R11,R3	// Calculate byte address
+
+return:
+	SUB	R17,R3
+	MOVD	R3,(R14)
+	RET
+
+found_qw_align:
+	// Use the same algorithm as above. Compress the result into
+	// a single doubleword and move it to a GPR for the final
+	// calculation.
+	VBPERMQ	  V6,V10,V6
+
+#ifdef GOARCH_ppc64le
+	MFVRD	  V6,R3
+	ADD	  $-1,R3,R11
+	ANDN	  R3,R11,R11
+	POPCNTD	  R11,R11
+#else
+	VSLDOI	  $6,V6,V6,V6
+	MFVRD	  V6,R3
+	CNTLZD	  R3,R11
+#endif
+	ADD	  R8,R11,R3
+	CMPU	  R11,R4
+	BLT	  return
+	BR	  notfound
 
 done:
 	// At this point, R3 has 0xFF in the same position as the byte we are
@@ -1236,17 +1323,10 @@
 	CMPU	R8,R7		// Check if we are at the last doubleword.
 	SRD	$3,R11		// Convert trailing zeros to bytes.
 	ADD	R11,R8,R3
-	CMPU	R11,R4,CR7	// If at the last doubleword, check the byte offset.
+	CMPU	R11,R6,CR7	// If at the last doubleword, check the byte offset.
 	BNE	return
 	BLE	CR7,return
-	MOVD	$-1,R3
-	MOVD	R3,(R14)
-	RET
-
-return:
-	SUB	R10,R3		// Calculate index.
-	MOVD	R3,(R14)
-	RET
+	BR	notfound
 
 small_string:
 	// We unroll this loop for better performance.
@@ -1257,9 +1337,9 @@
 	CMPB	R12,R5,R3	// Check for a match.
 	AND	R9,R3,R3	// Mask bytes below s_base.
 	CMPU	R3,$0,CR7	// If we have a match, jump to the final computation.
-	RLDICL	$0,R7,$61,R4	// length-1
+	RLDICL	$0,R7,$61,R6	// length-1
 	RLDICR	$0,R7,$60,R7	// Last doubleword in R7.
-        CMPU	R8,R7
+	CMPU	R8,R7
 	BNE	CR7,done
 	BEQ	notfound	// Hit length.
 
@@ -1287,34 +1367,70 @@
 	MOVDU	8(R8),R12
 	CMPB	R12,R5,R3
 	CMPU	R3,$0,CR6
-	CMPU	R8,R7
 	BNE	CR6,done
 	BR	notfound
 
 TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40
 	MOVD	s1_base+0(FP), R5
-	MOVD	s1_len+8(FP), R3
 	MOVD	s2_base+16(FP), R6
+	MOVD	s1_len+8(FP), R3
+	CMP	R5,R6,CR7
 	MOVD	s2_len+24(FP), R4
 	MOVD	$ret+32(FP), R7
+	CMP	R3,R4,CR6
+	BEQ	CR7,equal
+
+notequal:
 #ifdef	GOARCH_ppc64le
 	BR	cmpbodyLE<>(SB)
 #else
 	BR      cmpbodyBE<>(SB)
 #endif
 
+equal:
+	BEQ	CR6,done
+	MOVD	$1, R8
+	BGT	CR6,greater
+	NEG	R8
+
+greater:
+	MOVD	R8, (R7)
+	RET
+
+done:
+	MOVD	$0, (R7)
+	RET
+
 TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
 	MOVD	s1+0(FP), R5
-	MOVD	s1+8(FP), R3
 	MOVD	s2+24(FP), R6
+	MOVD	s1+8(FP), R3
+	CMP	R5,R6,CR7
 	MOVD	s2+32(FP), R4
 	MOVD	$ret+48(FP), R7
+	CMP	R3,R4,CR6
+	BEQ	CR7,equal
+
 #ifdef	GOARCH_ppc64le
 	BR	cmpbodyLE<>(SB)
 #else
 	BR      cmpbodyBE<>(SB)
 #endif
 
+equal:
+	BEQ	CR6,done
+	MOVD	$1, R8
+	BGT	CR6,greater
+	NEG	R8
+
+greater:
+	MOVD	R8, (R7)
+	RET
+
+done:
+	MOVD	$0, (R7)
+	RET
+
 TEXT runtime·return0(SB), NOSPLIT, $0
 	MOVW	$0, R3
 	RET
@@ -1353,18 +1469,6 @@
 	// traceback from goexit1 must hit code range of goexit
 	MOVD	R0, R0	// NOP
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
-	RET
-
 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
 	RET
 
diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
index 20e740b..6b71830 100644
--- a/src/runtime/asm_s390x.s
+++ b/src/runtime/asm_s390x.s
@@ -7,6 +7,83 @@
 #include "funcdata.h"
 #include "textflag.h"
 
+// _rt0_s390x_lib is common startup code for s390x systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed in the usual C ABI registers
+// R2 and R3.
+TEXT _rt0_s390x_lib(SB), NOSPLIT|NOFRAME, $0
+	STMG	R6, R15, 48(R15)
+	MOVD	R2, _rt0_s390x_lib_argc<>(SB)
+	MOVD	R3, _rt0_s390x_lib_argv<>(SB)
+
+	// Save R6-R15 in the register save area of the calling function.
+	STMG	R6, R15, 48(R15)
+
+	// Allocate 80 bytes on the stack.
+	MOVD	$-80(R15), R15
+
+	// Save F8-F15 in our stack frame.
+	FMOVD	F8, 16(R15)
+	FMOVD	F9, 24(R15)
+	FMOVD	F10, 32(R15)
+	FMOVD	F11, 40(R15)
+	FMOVD	F12, 48(R15)
+	FMOVD	F13, 56(R15)
+	FMOVD	F14, 64(R15)
+	FMOVD	F15, 72(R15)
+
+	// Synchronous initialization.
+	MOVD	$runtime·libpreinit(SB), R1
+	BL	R1
+
+	// Create a new thread to finish Go runtime initialization.
+	MOVD	_cgo_sys_thread_create(SB), R1
+	CMP	R1, $0
+	BEQ	nocgo
+	MOVD	$_rt0_s390x_lib_go(SB), R2
+	MOVD	$0, R3
+	BL	R1
+	BR	restore
+
+nocgo:
+	MOVD	$0x800000, R1              // stacksize
+	MOVD	R1, 0(R15)
+	MOVD	$_rt0_s390x_lib_go(SB), R1
+	MOVD	R1, 8(R15)                 // fn
+	MOVD	$runtime·newosproc(SB), R1
+	BL	R1
+
+restore:
+	// Restore F8-F15 from our stack frame.
+	FMOVD	16(R15), F8
+	FMOVD	24(R15), F9
+	FMOVD	32(R15), F10
+	FMOVD	40(R15), F11
+	FMOVD	48(R15), F12
+	FMOVD	56(R15), F13
+	FMOVD	64(R15), F14
+	FMOVD	72(R15), F15
+	MOVD	$80(R15), R15
+
+	// Restore R6-R15.
+	LMG	48(R15), R6, R15
+	RET
+
+// _rt0_s390x_lib_go initializes the Go runtime.
+// This is started in a separate thread by _rt0_s390x_lib.
+TEXT _rt0_s390x_lib_go(SB), NOSPLIT|NOFRAME, $0
+	MOVD	_rt0_s390x_lib_argc<>(SB), R2
+	MOVD	_rt0_s390x_lib_argv<>(SB), R3
+	MOVD	$runtime·rt0_go(SB), R1
+	BR	R1
+
+DATA _rt0_s390x_lib_argc<>(SB)/8, $0
+GLOBL _rt0_s390x_lib_argc<>(SB), NOPTR, $8
+DATA _rt0_s90x_lib_argv<>(SB)/8, $0
+GLOBL _rt0_s390x_lib_argv<>(SB), NOPTR, $8
+
 TEXT runtime·rt0_go(SB),NOSPLIT,$0
 	// R2 = argc; R3 = argv; R11 = temp; R13 = g; R15 = stack pointer
 	// C TLS base pointer in AR0:AR1
@@ -116,17 +193,6 @@
 // restore state from Gobuf; longjmp
 TEXT runtime·gogo(SB), NOSPLIT, $16-8
 	MOVD	buf+0(FP), R5
-
-	// If ctxt is not nil, invoke deletion barrier before overwriting.
-	MOVD	gobuf_ctxt(R5), R1
-	CMPBEQ	R1, $0, nilctxt
-	MOVD	$gobuf_ctxt(R5), R1
-	MOVD	R1, 8(R15)
-	MOVD	R0, 16(R15)
-	BL	runtime·writebarrierptr_prewrite(SB)
-	MOVD	buf+0(FP), R5
-
-nilctxt:
 	MOVD	gobuf_g(R5), g	// make sure g is not nil
 	BL	runtime·save_g(SB)
 
@@ -235,9 +301,12 @@
 
 noswitch:
 	// already on m stack, just call directly
+	// Using a tail call here cleans up tracebacks since we won't stop
+	// at an intermediate systemstack.
 	MOVD	0(R12), R3	// code pointer
-	BL	(R3)
-	RET
+	MOVD	0(R15), LR	// restore LR
+	ADD	$8, R15
+	BR	(R3)
 
 /*
  * support for morestack
@@ -272,7 +341,7 @@
 	MOVD	LR, R8
 	MOVD	R8, (g_sched+gobuf_pc)(g)
 	MOVD	R5, (g_sched+gobuf_lr)(g)
-	// newstack will fill gobuf.ctxt.
+	MOVD	R12, (g_sched+gobuf_ctxt)(g)
 
 	// Called from f.
 	// Set m->morebuf to f's caller.
@@ -285,9 +354,8 @@
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R15
 	// Create a stack frame on g0 to call newstack.
-	MOVD	$0, -16(R15)	// Zero saved LR in frame
-	SUB	$16, R15
-	MOVD	R12, 8(R15)	// ctxt argument
+	MOVD	$0, -8(R15)	// Zero saved LR in frame
+	SUB	$8, R15
 	BL	runtime·newstack(SB)
 
 	// Not reached, but make sure the return PC from the call to newstack
@@ -656,9 +724,9 @@
 	MOVD	R1, LR
 	RET
 
-TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
-	MOVD	16(R15), R3		// LR saved by caller
-	MOVD	R3, ret+8(FP)
+TEXT runtime·getcallerpc(SB),NOSPLIT|NOFRAME,$0-8
+	MOVD	0(R15), R3		// LR saved by caller
+	MOVD	R3, ret+0(FP)
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
@@ -678,23 +746,6 @@
 	MOVD	R3, ret+0(FP)
 	RET
 
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
-	GO_ARGS
-	NO_LOCAL_POINTERS
-	MOVD	p+0(FP), R3
-	MOVD	h+8(FP), R4
-	MOVD	8(R12), R5
-	MOVD	R3, 8(R15)
-	MOVD	R4, 16(R15)
-	MOVD	R5, 24(R15)
-	BL	runtime·memhash(SB)
-	MOVD	32(R15), R3
-	MOVD	R3, ret+16(FP)
-	RET
-
 // AES hashing not implemented for s390x
 TEXT runtime·aeshash(SB),NOSPLIT|NOFRAME,$0-0
 	MOVW	(R0), R15
@@ -721,18 +772,6 @@
 	LA	ret+16(FP), R7
 	BR	runtime·memeqbody(SB)
 
-// eqstring tests whether two strings are equal.
-// The compiler guarantees that strings passed
-// to eqstring have equal length.
-// See runtime_test.go:eqstring_generic for
-// equivalent Go code.
-TEXT runtime·eqstring(SB),NOSPLIT|NOFRAME,$0-33
-	MOVD	s1_base+0(FP), R3
-	MOVD	s1_len+8(FP), R6
-	MOVD	s2_base+16(FP), R5
-	LA	ret+32(FP), R7
-	BR	runtime·memeqbody(SB)
-
 TEXT bytes·Equal(SB),NOSPLIT|NOFRAME,$0-49
 	MOVD	a_len+8(FP), R2
 	MOVD	b_len+32(FP), R6
@@ -949,23 +988,12 @@
 	// traceback from goexit1 must hit code range of goexit
 	BYTE $0x07; BYTE $0x00; // 2-byte nop
 
-TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
-	RET
-
-TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
-	RET
-
 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
 	RET
 
 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
-	SYNC
+        // Stores are already ordered on s390x, so this is just a
+        // compile barrier.
 	RET
 
 TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40
diff --git a/src/runtime/cgo/asm_386.s b/src/runtime/cgo/asm_386.s
index dc8897d..7293c20 100644
--- a/src/runtime/cgo/asm_386.s
+++ b/src/runtime/cgo/asm_386.s
@@ -7,26 +7,23 @@
 // Called by C code generated by cmd/cgo.
 // func crosscall2(fn func(a unsafe.Pointer, n int32, ctxt uintptr), a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls fn with three arguments.
-TEXT crosscall2(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-	
-	SUBL	$12, SP
-	MOVL	20(BP), AX
+TEXT crosscall2(SB),NOSPLIT,$28-16
+	MOVL BP, 24(SP)
+	MOVL BX, 20(SP)
+	MOVL SI, 16(SP)
+	MOVL DI, 12(SP)
+
+	MOVL	ctxt+12(FP), AX
 	MOVL	AX, 8(SP)
-	MOVL	16(BP), AX
+	MOVL	n+8(FP), AX
 	MOVL	AX, 4(SP)
-	MOVL	12(BP), AX
+	MOVL	a+4(FP), AX
 	MOVL	AX, 0(SP)
-	MOVL	8(BP), AX
+	MOVL	fn+0(FP), AX
 	CALL	AX
-	ADDL	$12, SP
-	
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
+
+	MOVL 12(SP), DI
+	MOVL 16(SP), SI
+	MOVL 20(SP), BX
+	MOVL 24(SP), BP
 	RET
diff --git a/src/runtime/cgo/asm_amd64.s b/src/runtime/cgo/asm_amd64.s
index 541bd9e..0e33fc4 100644
--- a/src/runtime/cgo/asm_amd64.s
+++ b/src/runtime/cgo/asm_amd64.s
@@ -7,14 +7,12 @@
 // Called by C code generated by cmd/cgo.
 // func crosscall2(fn func(a unsafe.Pointer, n int32, ctxt uintptr), a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls fn with three arguments.
-TEXT crosscall2(SB),NOSPLIT,$0
 #ifndef GOOS_windows
-	SUBQ	$0x58, SP	/* keeps stack pointer 32-byte aligned */
+TEXT crosscall2(SB),NOSPLIT,$0x50-0 /* keeps stack pointer 32-byte aligned */
 #else
-	SUBQ	$0x118, SP	/* also need to save xmm6 - xmm15 */
+TEXT crosscall2(SB),NOSPLIT,$0x110-0 /* also need to save xmm6 - xmm15 */
 #endif
 	MOVQ	BX, 0x18(SP)
-	MOVQ	BP, 0x20(SP)
 	MOVQ	R12, 0x28(SP)
 	MOVQ	R13, 0x30(SP)
 	MOVQ	R14, 0x38(SP)
@@ -62,15 +60,9 @@
 #endif
 
 	MOVQ	0x18(SP), BX
-	MOVQ	0x20(SP), BP
 	MOVQ	0x28(SP), R12
 	MOVQ	0x30(SP), R13
 	MOVQ	0x38(SP), R14
 	MOVQ	0x40(SP), R15
 	
-#ifndef GOOS_windows
-	ADDQ	$0x58, SP
-#else
-	ADDQ	$0x118, SP
-#endif
 	RET
diff --git a/src/runtime/cgo/asm_mipsx.s b/src/runtime/cgo/asm_mipsx.s
index dd16af6..2483bdd 100644
--- a/src/runtime/cgo/asm_mipsx.s
+++ b/src/runtime/cgo/asm_mipsx.s
@@ -20,7 +20,11 @@
 
 	// Space for 9 caller-saved GPR + LR + 6 caller-saved FPR.
 	// O32 ABI allows us to smash 16 bytes argument area of caller frame.
+#ifndef GOMIPS_softfloat
 	SUBU	$(4*14+8*6-16), R29
+#else
+	SUBU	$(4*14-16), R29	// For soft-float, no FPR.
+#endif
 	MOVW	R5, (4*1)(R29)
 	MOVW	R6, (4*2)(R29)
 	MOVW	R7, (4*3)(R29)
@@ -34,14 +38,14 @@
 	MOVW	R23, (4*11)(R29)
 	MOVW	g, (4*12)(R29)
 	MOVW	R31, (4*13)(R29)
-
+#ifndef GOMIPS_softfloat
 	MOVD	F20, (4*14)(R29)
 	MOVD	F22, (4*14+8*1)(R29)
 	MOVD	F24, (4*14+8*2)(R29)
 	MOVD	F26, (4*14+8*3)(R29)
 	MOVD	F28, (4*14+8*4)(R29)
 	MOVD	F30, (4*14+8*5)(R29)
-
+#endif
 	JAL	runtime·load_g(SB)
 	JAL	(R4)
 
@@ -55,7 +59,7 @@
 	MOVW	(4*11)(R29), R23
 	MOVW	(4*12)(R29), g
 	MOVW	(4*13)(R29), R31
-
+#ifndef GOMIPS_softfloat
 	MOVD	(4*14)(R29), F20
 	MOVD	(4*14+8*1)(R29), F22
 	MOVD	(4*14+8*2)(R29), F24
@@ -64,4 +68,7 @@
 	MOVD	(4*14+8*5)(R29), F30
 
 	ADDU	$(4*14+8*6-16), R29
+#else
+	ADDU	$(4*14-16), R29
+#endif
 	RET
diff --git a/src/runtime/cgo/gcc_android_386.c b/src/runtime/cgo/gcc_android_386.c
index 23a15f1..28f553c 100644
--- a/src/runtime/cgo/gcc_android_386.c
+++ b/src/runtime/cgo/gcc_android_386.c
@@ -36,7 +36,7 @@
 	 */
 	ntofree = 0;
 	for(;;) {
-		if(pthread_key_create(&k, nil) < 0) {
+		if(pthread_key_create(&k, nil) != 0) {
 			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
 			abort();
 		}
@@ -77,7 +77,10 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	pthread_setspecific(k1, (void*)ts.g);
+	if (pthread_setspecific(k1, (void*)ts.g) != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_setspecific failed\n");
+		abort();
+	}
 
 	crosscall_386(ts.fn);
 	return nil;
diff --git a/src/runtime/cgo/gcc_android_amd64.c b/src/runtime/cgo/gcc_android_amd64.c
index e006c49..6f92d90 100644
--- a/src/runtime/cgo/gcc_android_amd64.c
+++ b/src/runtime/cgo/gcc_android_amd64.c
@@ -41,7 +41,7 @@
 	 */
 	ntofree = 0;
 	for(;;) {
-		if(pthread_key_create(&k, nil) < 0) {
+		if(pthread_key_create(&k, nil) != 0) {
 			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
 			abort();
 		}
@@ -82,7 +82,10 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	pthread_setspecific(k1, (void*)ts.g);
+	if (pthread_setspecific(k1, (void*)ts.g) != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_setspecific failed\n");
+		abort();
+	}
 
 	crosscall_amd64(ts.fn);
 	return nil;
diff --git a/src/runtime/cgo/gcc_darwin_386.c b/src/runtime/cgo/gcc_darwin_386.c
index 4ab3267..7d3c55c 100644
--- a/src/runtime/cgo/gcc_darwin_386.c
+++ b/src/runtime/cgo/gcc_darwin_386.c
@@ -39,8 +39,8 @@
 	 *
 	 * 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
+	 * Known to src/cmd/link/internal/ld/sym.go:/0x468
+	 * and to src/runtime/sys_darwin_386.s:/0x468
 	 *
 	 * This is truly disgusting and a bit fragile, but taking care
 	 * of it here protects the rest of the system from damage.
@@ -64,7 +64,7 @@
 	 */
 	ntofree = 0;
 	for(;;) {
-		if(pthread_key_create(&k, nil) < 0) {
+		if(pthread_key_create(&k, nil) != 0) {
 			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
 			abort();
 		}
@@ -142,7 +142,10 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	pthread_setspecific(k1, (void*)ts.g);
+	if (pthread_setspecific(k1, (void*)ts.g) != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_setspecific failed\n");
+		abort();
+	}
 
 	crosscall_386(ts.fn);
 	return nil;
diff --git a/src/runtime/cgo/gcc_darwin_amd64.c b/src/runtime/cgo/gcc_darwin_amd64.c
index 181d0ab..c57608c 100644
--- a/src/runtime/cgo/gcc_darwin_amd64.c
+++ b/src/runtime/cgo/gcc_darwin_amd64.c
@@ -28,14 +28,14 @@
 	 *
 	 * 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
+	 * Known to src/cmd/link/internal/ld/sym.go:/0x8a0
+	 * and to src/runtime/sys_darwin_amd64.s:/0x8a0
 	 *
 	 * As disgusting as on the 386; same justification.
 	 */
 	ntofree = 0;
 	for(;;) {
-		if(pthread_key_create(&k, nil) < 0) {
+		if(pthread_key_create(&k, nil) != 0) {
 			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
 			abort();
 		}
@@ -113,7 +113,10 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	pthread_setspecific(k1, (void*)ts.g);
+	if (pthread_setspecific(k1, (void*)ts.g) != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_setspecific failed\n");
+		abort();
+	}
 
 	crosscall_amd64(ts.fn);
 	return nil;
diff --git a/src/runtime/cgo/gcc_libinit.c b/src/runtime/cgo/gcc_libinit.c
index 31594ad..3dc5bde 100644
--- a/src/runtime/cgo/gcc_libinit.c
+++ b/src/runtime/cgo/gcc_libinit.c
@@ -98,6 +98,10 @@
 
 	for (tries = 0; tries < 20; tries++) {
 		err = pthread_create(thread, attr, pfn, arg);
+		if (err == 0) {
+			pthread_detach(*thread);
+			return 0;
+		}
 		if (err != EAGAIN) {
 			return err;
 		}
diff --git a/src/runtime/cgo/gcc_mipsx.S b/src/runtime/cgo/gcc_mipsx.S
index c51c36a..54f4b82 100644
--- a/src/runtime/cgo/gcc_mipsx.S
+++ b/src/runtime/cgo/gcc_mipsx.S
@@ -14,8 +14,11 @@
 .globl crosscall1
 .set noat
 crosscall1:
+#ifndef __mips_soft_float
 	addiu	$29, $29, -88
-
+#else
+	addiu	$29, $29, -40 // For soft-float, no need to make room for FP registers
+#endif
 	sw	$31, 0($29)
 	sw	$16, 4($29)
 	sw	$17, 8($29)
@@ -27,14 +30,14 @@
 	sw	$23, 32($29)
 	sw	$30, 36($29)
 
+#ifndef __mips_soft_float
 	sdc1	$f20, 40($29)
 	sdc1	$f22, 48($29)
 	sdc1	$f24, 56($29)
 	sdc1	$f26, 64($29)
 	sdc1	$f28, 72($29)
 	sdc1	$f30, 80($29)
-
-
+#endif
 	move	$20, $4 // save R4
 	move	$4, $6
 	jalr	$5	// call setg_gcc
@@ -49,16 +52,20 @@
 	lw	$22, 28($29)
 	lw	$23, 32($29)
 	lw	$30, 36($29)
+#ifndef __mips_soft_float
 	ldc1	$f20, 40($29)
 	ldc1	$f22, 48($29)
 	ldc1	$f24, 56($29)
 	ldc1	$f26, 64($29)
 	ldc1	$f28, 72($29)
 	ldc1	$f30, 80($29)
-
+#endif
 	lw	$31, 0($29)
-
+#ifndef __mips_soft_float
 	addiu	$29, $29, 88
+#else
+	addiu	$29, $29, 40
+#endif
 	jr	$31
 
 .set at
diff --git a/src/runtime/cgo/gcc_mmap.c b/src/runtime/cgo/gcc_mmap.c
index 29acd3c..5cf6bdf 100644
--- a/src/runtime/cgo/gcc_mmap.c
+++ b/src/runtime/cgo/gcc_mmap.c
@@ -11,7 +11,7 @@
 
 #include "libcgo.h"
 
-void *
+uintptr_t
 x_cgo_mmap(void *addr, uintptr_t length, int32_t prot, int32_t flags, int32_t fd, uint32_t offset) {
 	void *p;
 
@@ -20,9 +20,9 @@
 	_cgo_tsan_release();
 	if (p == MAP_FAILED) {
 		/* This is what the Go code expects on failure.  */
-		p = (void *) (uintptr_t) errno;
+		return (uintptr_t)errno;
 	}
-	return p;
+	return (uintptr_t)p;
 }
 
 void
diff --git a/src/runtime/cgo/gcc_signal2_darwin_armx.c b/src/runtime/cgo/gcc_signal2_darwin_armx.c
new file mode 100644
index 0000000..54b7e32
--- /dev/null
+++ b/src/runtime/cgo/gcc_signal2_darwin_armx.c
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build lldb
+// +build darwin
+// +build arm arm64
+
+// Used by gcc_signal_darwin_armx.c when doing the test build during cgo.
+// We hope that for real binaries the definition provided by Go will take precedence
+// and the linker will drop this .o file altogether, which is why this definition
+// is all by itself in its own file.
+void __attribute__((weak)) xx_cgo_panicmem(void) {}
diff --git a/src/runtime/cgo/gcc_signal_darwin_armx.c b/src/runtime/cgo/gcc_signal_darwin_armx.c
index a2d520b..3ab1d8b 100644
--- a/src/runtime/cgo/gcc_signal_darwin_armx.c
+++ b/src/runtime/cgo/gcc_signal_darwin_armx.c
@@ -39,7 +39,8 @@
 #include "libcgo.h"
 #include "libcgo_unix.h"
 
-uintptr_t x_cgo_panicmem;
+void xx_cgo_panicmem(void);
+uintptr_t x_cgo_panicmem = (uintptr_t)xx_cgo_panicmem;
 
 static pthread_mutex_t mach_exception_handler_port_set_mu;
 static mach_port_t mach_exception_handler_port_set = MACH_PORT_NULL;
diff --git a/src/runtime/cgo/gcc_signal_darwin_lldb.c b/src/runtime/cgo/gcc_signal_darwin_lldb.c
index 12cc388..54d91f6 100644
--- a/src/runtime/cgo/gcc_signal_darwin_lldb.c
+++ b/src/runtime/cgo/gcc_signal_darwin_lldb.c
@@ -8,7 +8,5 @@
 
 #include <stdint.h>
 
-uintptr_t x_cgo_panicmem;
-
 void darwin_arm_init_thread_exception_port() {}
 void darwin_arm_init_mach_exception_handler() {}
diff --git a/src/runtime/cgo/gcc_util.c b/src/runtime/cgo/gcc_util.c
index 2d5382a..3fcb48c 100644
--- a/src/runtime/cgo/gcc_util.c
+++ b/src/runtime/cgo/gcc_util.c
@@ -29,6 +29,10 @@
 
 #include <string.h>
 
+char x_cgo_yield_strncpy_src = 0;
+char x_cgo_yield_strncpy_dst = 0;
+size_t x_cgo_yield_strncpy_n = 0;
+
 /*
 Stub for allowing libc interceptors to execute.
 
@@ -50,9 +54,14 @@
 
 	So we choose strncpy(_, _, 0): it requires an extra header,
 	but it's standard and should be very efficient.
+
+	GCC 7 has an unfortunate habit of optimizing out strncpy calls (see
+	https://golang.org/issue/21196), so the arguments here need to be global
+	variables with external linkage in order to ensure that the call traps all the
+	way down into libc.
 	*/
-	char nothing = 0;
-	strncpy(&nothing, &nothing, 0);
+	strncpy(&x_cgo_yield_strncpy_dst, &x_cgo_yield_strncpy_src,
+	        x_cgo_yield_strncpy_n);
 }
 
 void(* const _cgo_yield)() = &x_cgo_yield;
diff --git a/src/runtime/cgo/signal_darwin_arm.s b/src/runtime/cgo/signal_darwin_arm.s
index ee5c3d3..f886e4b 100644
--- a/src/runtime/cgo/signal_darwin_arm.s
+++ b/src/runtime/cgo/signal_darwin_arm.s
@@ -4,13 +4,13 @@
 
 #include "textflag.h"
 
-// panicmem is the entrypoint for SIGSEGV as intercepted via a
+// xx_cgo_panicmem is the entrypoint for SIGSEGV as intercepted via a
 // mach thread port as EXC_BAD_ACCESS. As the segfault may have happened
-// in C code, we first need to load_g then call panicmem.
+// in C code, we first need to load_g then call xx_cgo_panicmem.
 //
 //	R1 - LR at moment of fault
 //	R2 - PC at moment of fault
-TEXT ·panicmem(SB),NOSPLIT,$-4
+TEXT xx_cgo_panicmem(SB),NOSPLIT,$-4
 	// If in external C code, we need to load the g register.
 	BL  runtime·load_g(SB)
 	CMP $0, g
diff --git a/src/runtime/cgo/signal_darwin_arm64.s b/src/runtime/cgo/signal_darwin_arm64.s
index 75aefd4..17781cf 100644
--- a/src/runtime/cgo/signal_darwin_arm64.s
+++ b/src/runtime/cgo/signal_darwin_arm64.s
@@ -4,13 +4,13 @@
 
 #include "textflag.h"
 
-// panicmem is the entrypoint for SIGSEGV as intercepted via a
+// xx_cgo_panicmem is the entrypoint for SIGSEGV as intercepted via a
 // mach thread port as EXC_BAD_ACCESS. As the segfault may have happened
-// in C code, we first need to load_g then call panicmem.
+// in C code, we first need to load_g then call xx_cgo_panicmem.
 //
 //	R1 - LR at moment of fault
 //	R2 - PC at moment of fault
-TEXT ·panicmem(SB),NOSPLIT,$-8
+TEXT xx_cgo_panicmem(SB),NOSPLIT,$-8
 	// If in external C code, we need to load the g register.
 	BL  runtime·load_g(SB)
 	CMP $0, g
diff --git a/src/runtime/cgo/signal_darwin_armx.go b/src/runtime/cgo/signal_darwin_armx.go
index 9f6741e..9f4b462 100644
--- a/src/runtime/cgo/signal_darwin_armx.go
+++ b/src/runtime/cgo/signal_darwin_armx.go
@@ -7,29 +7,7 @@
 
 package cgo
 
-import "unsafe"
+import _ "unsafe"
 
-//go:cgo_import_static x_cgo_panicmem
-//go:linkname x_cgo_panicmem x_cgo_panicmem
-var x_cgo_panicmem uintptr
-
-// use a pointer to avoid relocation of external symbol in __TEXT
-// make linker happy
-var _cgo_panicmem = &x_cgo_panicmem
-
-// TODO(crawshaw): move this into x_cgo_init, it will not run until
-// runtime has finished loading, which may be after its use.
-func init() {
-	*_cgo_panicmem = funcPC(panicmem)
-}
-
-func funcPC(f interface{}) uintptr {
-	var ptrSize = unsafe.Sizeof(uintptr(0))
-	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
-}
-
-func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
-	return unsafe.Pointer(uintptr(p) + x)
-}
-
-func panicmem()
+//go:cgo_export_static xx_cgo_panicmem xx_cgo_panicmem
+func xx_cgo_panicmem()
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index aa531b9..b7c70c6 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -20,19 +20,21 @@
 //go:linkname _cgo_munmap _cgo_munmap
 var _cgo_munmap unsafe.Pointer
 
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
 	if _cgo_mmap != nil {
 		// Make ret a uintptr so that writing to it in the
 		// function literal does not trigger a write barrier.
 		// A write barrier here could break because of the way
 		// that mmap uses the same value both as a pointer and
 		// an errno value.
-		// TODO: Fix mmap to return two values.
 		var ret uintptr
 		systemstack(func() {
 			ret = callCgoMmap(addr, n, prot, flags, fd, off)
 		})
-		return unsafe.Pointer(ret)
+		if ret < 4096 {
+			return nil, int(ret)
+		}
+		return unsafe.Pointer(ret), 0
 	}
 	return sysMmap(addr, n, prot, flags, fd, off)
 }
@@ -46,7 +48,7 @@
 }
 
 // sysMmap calls the mmap system call. It is implemented in assembly.
-func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
 
 // callCgoMmap calls the mmap function in the runtime/cgo package
 // using the GCC calling convention. It is implemented in assembly.
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 755269e..02c4cb3 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -8,9 +8,9 @@
 // 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.cgocall (below) 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
@@ -104,13 +104,9 @@
 		racereleasemerge(unsafe.Pointer(&racecgosync))
 	}
 
-	// Lock g to m to ensure we stay on the same stack if we do a
-	// cgo callback. In case of panic, unwindm calls endcgo.
-	lockOSThread()
 	mp := getg().m
 	mp.ncgocall++
 	mp.ncgo++
-	mp.incgo = true
 
 	// Reset traceback.
 	mp.cgoCallers[0] = 0
@@ -130,7 +126,14 @@
 	// and then re-enter the "system call" reusing the PC and SP
 	// saved by entersyscall here.
 	entersyscall(0)
+
+	mp.incgo = true
 	errno := asmcgocall(fn, arg)
+
+	// Call endcgo before exitsyscall because exitsyscall may
+	// reschedule us on to a different M.
+	endcgo(mp)
+
 	exitsyscall(0)
 
 	// From the garbage collector's perspective, time can move
@@ -145,8 +148,8 @@
 	// GC by forcing them to stay live across this time warp.
 	KeepAlive(fn)
 	KeepAlive(arg)
+	KeepAlive(mp)
 
-	endcgo(mp)
 	return errno
 }
 
@@ -158,8 +161,6 @@
 	if raceenabled {
 		raceacquire(unsafe.Pointer(&racecgosync))
 	}
-
-	unlockOSThread() // invalidates mp
 }
 
 // Call from C back to Go.
@@ -171,6 +172,12 @@
 		exit(2)
 	}
 
+	// The call from C is on gp.m's g0 stack, so we must ensure
+	// that we stay on that M. We have to do this before calling
+	// exitsyscall, since it would otherwise be free to move us to
+	// a different M. The call to unlockOSThread is in unwindm.
+	lockOSThread()
+
 	// Save current syscall parameters, so m.syscall can be
 	// used again if callback decide to make syscall.
 	syscall := gp.m.syscall
@@ -186,6 +193,10 @@
 
 	cgocallbackg1(ctxt)
 
+	// At this point unlockOSThread has been called.
+	// The following code must not change to a different m.
+	// This is enforced by checking incgo in the schedule function.
+
 	gp.m.incgo = true
 	// going back to cgo call
 	reentersyscall(savedpc, uintptr(savedsp))
@@ -321,32 +332,35 @@
 }
 
 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:
-		throw("unwindm not implemented")
-	case "386", "amd64", "arm", "ppc64", "ppc64le", "mips64", "mips64le", "s390x", "mips", "mipsle":
-		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + sys.MinFrameSize))
-	case "arm64":
-		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
+	if *restore {
+		// 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:
+			throw("unwindm not implemented")
+		case "386", "amd64", "arm", "ppc64", "ppc64le", "mips64", "mips64le", "s390x", "mips", "mipsle":
+			sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + sys.MinFrameSize))
+		case "arm64":
+			sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
+		}
+
+		// Call endcgo to do the accounting that cgocall will not have a
+		// chance to do during an unwind.
+		//
+		// In the case where a Go call originates from C, ncgo is 0
+		// and there is no matching cgocall to end.
+		if mp.ncgo > 0 {
+			endcgo(mp)
+		}
+
+		releasem(mp)
 	}
 
-	// Call endcgo to do the accounting that cgocall will not have a
-	// chance to do during an unwind.
-	//
-	// In the case where a a Go call originates from C, ncgo is 0
-	// and there is no matching cgocall to end.
-	if mp.ncgo > 0 {
-		endcgo(mp)
-	}
-
-	releasem(mp)
+	// Undo the call to lockOSThread in cgocallbackg.
+	// We must still stay on the same m.
+	unlockOSThread()
 }
 
 // called from assembly
@@ -580,10 +594,8 @@
 				// No more possible pointers.
 				break
 			}
-			if hbits.isPointer() {
-				if cgoIsGoPointer(*(*unsafe.Pointer)(unsafe.Pointer(base + i))) {
-					panic(errorString(msg))
-				}
+			if hbits.isPointer() && cgoIsGoPointer(*(*unsafe.Pointer)(unsafe.Pointer(base + i))) {
+				panic(errorString(msg))
 			}
 			hbits = hbits.next()
 		}
diff --git a/src/runtime/cgocheck.go b/src/runtime/cgocheck.go
index 61aaa0a..ea1ab97 100644
--- a/src/runtime/cgocheck.go
+++ b/src/runtime/cgocheck.go
@@ -16,6 +16,10 @@
 
 // cgoCheckWriteBarrier is called whenever a pointer is stored into memory.
 // It throws if the program is storing a Go pointer into non-Go memory.
+//
+// This is called from the write barrier, so its entire call tree must
+// be nosplit.
+//
 //go:nosplit
 //go:nowritebarrier
 func cgoCheckWriteBarrier(dst *uintptr, src uintptr) {
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index 6294678..41ae803 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -55,11 +55,19 @@
 }
 
 //go:linkname reflect_makechan reflect.makechan
-func reflect_makechan(t *chantype, size int64) *hchan {
+func reflect_makechan(t *chantype, size int) *hchan {
 	return makechan(t, size)
 }
 
-func makechan(t *chantype, size int64) *hchan {
+func makechan64(t *chantype, size int64) *hchan {
+	if int64(int(size)) != size {
+		panic(plainError("makechan: size out of range"))
+	}
+
+	return makechan(t, int(size))
+}
+
+func makechan(t *chantype, size int) *hchan {
 	elem := t.elem
 
 	// compiler checks this but be safe.
@@ -69,29 +77,33 @@
 	if hchanSize%maxAlign != 0 || elem.align > maxAlign {
 		throw("makechan: bad alignment")
 	}
-	if size < 0 || int64(uintptr(size)) != size || (elem.size > 0 && uintptr(size) > (_MaxMem-hchanSize)/elem.size) {
+
+	if size < 0 || uintptr(size) > maxSliceCap(elem.size) || uintptr(size)*elem.size > _MaxMem-hchanSize {
 		panic(plainError("makechan: size out of range"))
 	}
 
+	// Hchan does not contain pointers interesting for GC when elements stored in buf do not contain pointers.
+	// 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.
 	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.
+	switch {
+	case size == 0 || elem.size == 0:
+		// Queue or element size is zero.
+		c = (*hchan)(mallocgc(hchanSize, nil, true))
+		// Race detector uses this location for synchronization.
+		c.buf = unsafe.Pointer(c)
+	case elem.kind&kindNoPointers != 0:
+		// Elements do not contain pointers.
+		// Allocate hchan and buf in one call.
 		c = (*hchan)(mallocgc(hchanSize+uintptr(size)*elem.size, nil, true))
-		if size > 0 && elem.size != 0 {
-			c.buf = add(unsafe.Pointer(c), hchanSize)
-		} else {
-			// race detector uses this location for synchronization
-			// Also prevents us from pointing beyond the allocation (see issue 9401).
-			c.buf = unsafe.Pointer(c)
-		}
-	} else {
+		c.buf = add(unsafe.Pointer(c), hchanSize)
+	default:
+		// Elements contain pointers.
 		c = new(hchan)
-		c.buf = newarray(elem, int(size))
+		c.buf = mallocgc(uintptr(size)*elem.size, elem, true)
 	}
+
 	c.elemsize = uint16(elem.size)
 	c.elemtype = elem
 	c.dataqsiz = uint(size)
@@ -110,7 +122,7 @@
 // entry point for c <- x from compiled code
 //go:nosplit
 func chansend1(c *hchan, elem unsafe.Pointer) {
-	chansend(c, elem, true, getcallerpc(unsafe.Pointer(&c)))
+	chansend(c, elem, true, getcallerpc())
 }
 
 /*
@@ -214,7 +226,7 @@
 	mysg.elem = ep
 	mysg.waitlink = nil
 	mysg.g = gp
-	mysg.selectdone = nil
+	mysg.isSelect = false
 	mysg.c = c
 	gp.waiting = mysg
 	gp.param = nil
@@ -322,7 +334,7 @@
 	}
 
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&c))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan))
 		racerelease(unsafe.Pointer(c))
 	}
@@ -499,7 +511,7 @@
 	mysg.waitlink = nil
 	gp.waiting = mysg
 	mysg.g = gp
-	mysg.selectdone = nil
+	mysg.isSelect = false
 	mysg.c = c
 	gp.param = nil
 	c.recvq.enqueue(mysg)
@@ -594,7 +606,7 @@
 //	}
 //
 func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
-	return chansend(c, elem, false, getcallerpc(unsafe.Pointer(&c)))
+	return chansend(c, elem, false, getcallerpc())
 }
 
 // compiler implements
@@ -644,7 +656,7 @@
 
 //go:linkname reflect_chansend reflect.chansend
 func reflect_chansend(c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
-	return chansend(c, elem, !nb, getcallerpc(unsafe.Pointer(&c)))
+	return chansend(c, elem, !nb, getcallerpc())
 }
 
 //go:linkname reflect_chanrecv reflect.chanrecv
@@ -703,10 +715,16 @@
 			sgp.next = nil // mark as removed (see dequeueSudog)
 		}
 
-		// 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 || !atomic.Cas(sgp.selectdone, 0, 1) {
+		// if a goroutine was put on this queue because of a
+		// select, there is a small window between the goroutine
+		// being woken up by a different case and it grabbing the
+		// channel locks. Once it has the lock
+		// it removes itself from the queue, so we won't see it after that.
+		// We use a flag in the G struct to tell us when someone
+		// else has won the race to signal this goroutine but the goroutine
+		// hasn't removed itself from the queue yet.
+		if sgp.isSelect {
+			if !atomic.Cas(&sgp.g.selectDone, 0, 1) {
 				continue
 			}
 		}
diff --git a/src/runtime/chan_test.go b/src/runtime/chan_test.go
index a75fa1b..b6188f5 100644
--- a/src/runtime/chan_test.go
+++ b/src/runtime/chan_test.go
@@ -5,6 +5,8 @@
 package runtime_test
 
 import (
+	"internal/testenv"
+	"math"
 	"runtime"
 	"sync"
 	"sync/atomic"
@@ -430,6 +432,65 @@
 	wg.Wait()
 }
 
+func TestSelectFairness(t *testing.T) {
+	const trials = 10000
+	if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" {
+		testenv.SkipFlaky(t, 22047)
+	}
+	c1 := make(chan byte, trials+1)
+	c2 := make(chan byte, trials+1)
+	for i := 0; i < trials+1; i++ {
+		c1 <- 1
+		c2 <- 2
+	}
+	c3 := make(chan byte)
+	c4 := make(chan byte)
+	out := make(chan byte)
+	done := make(chan byte)
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		for {
+			var b byte
+			select {
+			case b = <-c3:
+			case b = <-c4:
+			case b = <-c1:
+			case b = <-c2:
+			}
+			select {
+			case out <- b:
+			case <-done:
+				return
+			}
+		}
+	}()
+	cnt1, cnt2 := 0, 0
+	for i := 0; i < trials; i++ {
+		switch b := <-out; b {
+		case 1:
+			cnt1++
+		case 2:
+			cnt2++
+		default:
+			t.Fatalf("unexpected value %d on channel", b)
+		}
+	}
+	// If the select in the goroutine is fair,
+	// cnt1 and cnt2 should be about the same value.
+	// With 10,000 trials, the expected margin of error at
+	// a confidence level of five nines is 4.4172 / (2 * Sqrt(10000)).
+	r := float64(cnt1) / trials
+	e := math.Abs(r - 0.5)
+	t.Log(cnt1, cnt2, r, e)
+	if e > 4.4172/(2*math.Sqrt(trials)) {
+		t.Errorf("unfair select: in %d trials, results were %d, %d", trials, cnt1, cnt2)
+	}
+	close(done)
+	wg.Wait()
+}
+
 func TestChanSendInterface(t *testing.T) {
 	type mt struct{}
 	m := &mt{}
@@ -669,6 +730,55 @@
 	<-ready2
 }
 
+type struct0 struct{}
+
+func BenchmarkMakeChan(b *testing.B) {
+	b.Run("Byte", func(b *testing.B) {
+		var x chan byte
+		for i := 0; i < b.N; i++ {
+			x = make(chan byte, 8)
+		}
+		close(x)
+	})
+	b.Run("Int", func(b *testing.B) {
+		var x chan int
+		for i := 0; i < b.N; i++ {
+			x = make(chan int, 8)
+		}
+		close(x)
+	})
+	b.Run("Ptr", func(b *testing.B) {
+		var x chan *byte
+		for i := 0; i < b.N; i++ {
+			x = make(chan *byte, 8)
+		}
+		close(x)
+	})
+	b.Run("Struct", func(b *testing.B) {
+		b.Run("0", func(b *testing.B) {
+			var x chan struct0
+			for i := 0; i < b.N; i++ {
+				x = make(chan struct0, 8)
+			}
+			close(x)
+		})
+		b.Run("32", func(b *testing.B) {
+			var x chan struct32
+			for i := 0; i < b.N; i++ {
+				x = make(chan struct32, 8)
+			}
+			close(x)
+		})
+		b.Run("40", func(b *testing.B) {
+			var x chan struct40
+			for i := 0; i < b.N; i++ {
+				x = make(chan struct40, 8)
+			}
+			close(x)
+		})
+	})
+}
+
 func BenchmarkChanNonblocking(b *testing.B) {
 	myc := make(chan int)
 	b.RunParallel(func(pb *testing.PB) {
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
index fb841a9..e00dcb1 100644
--- a/src/runtime/cpuprof.go
+++ b/src/runtime/cpuprof.go
@@ -160,6 +160,7 @@
 			funcPC(_ExternalCode) + sys.PCQuantum,
 		}
 		cpuprof.log.write(nil, 0, hdr[:], lostStk[:])
+		p.lostExtra = 0
 	}
 }
 
diff --git a/src/runtime/cputicks.go b/src/runtime/cputicks.go
index ccc3947..de97d5b 100644
--- a/src/runtime/cputicks.go
+++ b/src/runtime/cputicks.go
@@ -11,6 +11,6 @@
 
 package runtime
 
-// careful: cputicks is not guaranteed to be monotonic!  In particular, we have
+// 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
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index a5cbbad..3b9fedc 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -13,6 +13,7 @@
 	"os"
 	"os/exec"
 	"runtime"
+	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -113,7 +114,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
 	if err != nil {
 		t.Fatalf("exit status: %v\n%s", err, got)
 	}
@@ -136,7 +137,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
 	if err != nil {
 		t.Fatalf("exit status: %v\n%s", err, got)
 	}
@@ -203,14 +204,14 @@
 	const tries = 10
 	var tot1, tot2 time.Duration
 	for i := 0; i < tries; i++ {
-		cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))
+		cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
 		cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
 
 		start := time.Now()
 		cmd.Run()
 		d1 := time.Since(start)
 
-		cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
+		cmd = testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
 		cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
 
 		start = time.Now()
@@ -251,7 +252,7 @@
 
 func TestCgoCrashTraceback(t *testing.T) {
 	t.Parallel()
-	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+	if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
 		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
 	got := runTestProg(t, "testprogcgo", "CrashTraceback")
@@ -273,7 +274,7 @@
 
 func testCgoPprof(t *testing.T, buildArg, runArg string) {
 	t.Parallel()
-	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+	if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
 		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
 	testenv.MustHaveGoRun(t)
@@ -283,7 +284,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, runArg)).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, runArg)).CombinedOutput()
 	if err != nil {
 		if testenv.Builder() == "linux-amd64-alpine" {
 			// See Issue 18243 and Issue 19938.
@@ -295,7 +296,7 @@
 	defer os.Remove(fn)
 
 	for try := 0; try < 2; try++ {
-		cmd := testEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-top", "-nodecount=1"))
+		cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-top", "-nodecount=1"))
 		// Check that pprof works both with and without explicit executable on command line.
 		if try == 0 {
 			cmd.Args = append(cmd.Args, exe, fn)
@@ -330,7 +331,7 @@
 }
 
 func TestCgoPprofPIE(t *testing.T) {
-	testCgoPprof(t, "-ldflags=-extldflags=-pie", "CgoPprof")
+	testCgoPprof(t, "-buildmode=pie", "CgoPprof")
 }
 
 func TestCgoPprofThread(t *testing.T) {
@@ -359,7 +360,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -388,7 +389,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput()
 	if err != nil {
 		t.Logf("%s\n", got)
 		t.Fatal(err)
@@ -411,3 +412,93 @@
 		t.Errorf("expected %q got %v", want, got)
 	}
 }
+
+func TestCatchPanic(t *testing.T) {
+	t.Parallel()
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no signals on %s", runtime.GOOS)
+	case "darwin":
+		if runtime.GOARCH == "amd64" {
+			t.Skipf("crash() on darwin/amd64 doesn't raise SIGABRT")
+		}
+	}
+
+	testenv.MustHaveGoRun(t)
+
+	exe, err := buildTestProg(t, "testprogcgo")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, early := range []bool{true, false} {
+		cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCatchPanic"))
+		// Make sure a panic results in a crash.
+		cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
+		if early {
+			// Tell testprogcgo to install an early signal handler for SIGABRT
+			cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1")
+		}
+		if out, err := cmd.CombinedOutput(); err != nil {
+			t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
+		}
+	}
+}
+
+func TestCgoLockOSThreadExit(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	t.Parallel()
+	testLockOSThreadExit(t, "testprogcgo")
+}
+
+func TestWindowsStackMemoryCgo(t *testing.T) {
+	if runtime.GOOS != "windows" {
+		t.Skip("skipping windows specific test")
+	}
+	testenv.SkipFlaky(t, 22575)
+	o := runTestProg(t, "testprogcgo", "StackMemory")
+	stackUsage, err := strconv.Atoi(o)
+	if err != nil {
+		t.Fatalf("Failed to read stack usage: %v", err)
+	}
+	if expected, got := 100<<10, stackUsage; got > expected {
+		t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got)
+	}
+}
+
+func TestSigStackSwapping(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no sigaltstack on %s", runtime.GOOS)
+	}
+	t.Parallel()
+	got := runTestProg(t, "testprogcgo", "SigStack")
+	want := "OK\n"
+	if got != want {
+		t.Errorf("expected %q got %v", want, got)
+	}
+}
+
+func TestCgoTracebackSigpanic(t *testing.T) {
+	// Test unwinding over a sigpanic in C code without a C
+	// symbolizer. See issue #23576.
+	if runtime.GOOS == "windows" {
+		// On Windows if we get an exception in C code, we let
+		// the Windows exception handler unwind it, rather
+		// than injecting a sigpanic.
+		t.Skip("no sigpanic in C on windows")
+	}
+	t.Parallel()
+	got := runTestProg(t, "testprogcgo", "TracebackSigpanic")
+	want := "runtime.sigpanic"
+	if !strings.Contains(got, want) {
+		t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
+	}
+	nowant := "unexpected return pc"
+	if strings.Contains(got, nowant) {
+		t.Fatalf("failure incorrectly contains %q. output:\n%s\n", nowant, got)
+	}
+}
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index 7753809..0254ebd 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -32,25 +32,6 @@
 	os.Exit(status)
 }
 
-func testEnv(cmd *exec.Cmd) *exec.Cmd {
-	if cmd.Env != nil {
-		panic("environment already set")
-	}
-	for _, env := range os.Environ() {
-		// Exclude GODEBUG from the environment to prevent its output
-		// from breaking tests that are trying to parse other command output.
-		if strings.HasPrefix(env, "GODEBUG=") {
-			continue
-		}
-		// Exclude GOTRACEBACK for the same reason.
-		if strings.HasPrefix(env, "GOTRACEBACK=") {
-			continue
-		}
-		cmd.Env = append(cmd.Env, env)
-	}
-	return cmd
-}
-
 var testprog struct {
 	sync.Mutex
 	dir    string
@@ -62,7 +43,11 @@
 	err error
 }
 
-func runTestProg(t *testing.T, binary, name string) string {
+func runTestProg(t *testing.T, binary, name string, env ...string) string {
+	if *flagQuick {
+		t.Skip("-quick")
+	}
+
 	testenv.MustHaveGoBuild(t)
 
 	exe, err := buildTestProg(t, binary)
@@ -70,7 +55,11 @@
 		t.Fatal(err)
 	}
 
-	cmd := testEnv(exec.Command(exe, name))
+	cmd := testenv.CleanCmdEnv(exec.Command(exe, name))
+	cmd.Env = append(cmd.Env, env...)
+	if testing.Short() {
+		cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
+	}
 	var b bytes.Buffer
 	cmd.Stdout = &b
 	cmd.Stderr = &b
@@ -111,6 +100,10 @@
 }
 
 func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) {
+	if *flagQuick {
+		t.Skip("-quick")
+	}
+
 	checkStaleRuntime(t)
 
 	testprog.Lock()
@@ -139,7 +132,7 @@
 	exe := filepath.Join(testprog.dir, name+".exe")
 	cmd := exec.Command(testenv.GoToolPath(t), append([]string{"build", "-o", exe}, flags...)...)
 	cmd.Dir = "testdata/" + binary
-	out, err := testEnv(cmd).CombinedOutput()
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		target.err = fmt.Errorf("building %s %v: %v\n%s", binary, flags, err, out)
 		testprog.target[name] = target
@@ -158,14 +151,14 @@
 func checkStaleRuntime(t *testing.T) {
 	staleRuntimeOnce.Do(func() {
 		// 'go run' uses the installed copy of runtime.a, which may be out of date.
-		out, err := testEnv(exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Stale}}", "runtime")).CombinedOutput()
+		out, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "list", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "-f", "{{.Stale}}", "runtime")).CombinedOutput()
 		if err != nil {
 			staleRuntimeErr = fmt.Errorf("failed to execute 'go list': %v\n%v", err, string(out))
 			return
 		}
 		if string(out) != "false\n" {
 			t.Logf("go list -f {{.Stale}} runtime:\n%s", out)
-			out, err := testEnv(exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.StaleReason}}", "runtime")).CombinedOutput()
+			out, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "list", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "-f", "{{.StaleReason}}", "runtime")).CombinedOutput()
 			if err != nil {
 				t.Logf("go list -f {{.StaleReason}} failed: %v", err)
 			}
@@ -468,7 +461,7 @@
 		t.Fatal(err)
 	}
 
-	got, err := testEnv(exec.Command(exe, "MemProf")).CombinedOutput()
+	got, err := testenv.CleanCmdEnv(exec.Command(exe, "MemProf")).CombinedOutput()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -476,7 +469,7 @@
 	defer os.Remove(fn)
 
 	for try := 0; try < 2; try++ {
-		cmd := testEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-alloc_space", "-top"))
+		cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-alloc_space", "-top"))
 		// Check that pprof works both with and without explicit executable on command line.
 		if try == 0 {
 			cmd.Args = append(cmd.Args, exe, fn)
@@ -586,7 +579,7 @@
 	const tries = 10
 retry:
 	for i := 0; i < tries; i++ {
-		got, err := testEnv(exec.Command(exe, "PanicRace")).CombinedOutput()
+		got, err := testenv.CleanCmdEnv(exec.Command(exe, "PanicRace")).CombinedOutput()
 		if err == nil {
 			t.Logf("try %d: program exited successfully, should have failed", i+1)
 			continue
@@ -614,3 +607,17 @@
 	}
 	t.Errorf("test ran %d times without producing expected output", tries)
 }
+
+func TestBadTraceback(t *testing.T) {
+	output := runTestProg(t, "testprog", "BadTraceback")
+	for _, want := range []string{
+		"runtime: unexpected return pc",
+		"called from 0xbad",
+		"00000bad",    // Smashed LR in hex dump
+		"<main.badLR", // Symbolization in hex dump (badLR1 or badLR2)
+	} {
+		if !strings.Contains(output, want) {
+			t.Errorf("output does not contain %q:\n%s", want, output)
+		}
+	}
+}
diff --git a/src/runtime/crash_unix_test.go b/src/runtime/crash_unix_test.go
index cbaa1f6..af9e643 100644
--- a/src/runtime/crash_unix_test.go
+++ b/src/runtime/crash_unix_test.go
@@ -65,13 +65,13 @@
 
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
 	cmd.Dir = dir
-	out, err := testEnv(cmd).CombinedOutput()
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("building source: %v\n%s", err, out)
 	}
 
 	cmd = exec.Command(filepath.Join(dir, "a.exe"))
-	cmd = testEnv(cmd)
+	cmd = testenv.CleanCmdEnv(cmd)
 	cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
 
 	// Set GOGC=off. Because of golang.org/issue/10958, the tight
@@ -184,7 +184,7 @@
 
 	t.Parallel()
 	cmd := exec.Command(os.Args[0], "testPanicSystemstackInternal")
-	cmd = testEnv(cmd)
+	cmd = testenv.CleanCmdEnv(cmd)
 	cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
 	pr, pw, err := os.Pipe()
 	if err != nil {
@@ -249,7 +249,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	err = testEnv(exec.Command(exe, "SignalExitStatus")).Run()
+	err = testenv.CleanCmdEnv(exec.Command(exe, "SignalExitStatus")).Run()
 	if err == nil {
 		t.Error("test program succeeded unexpectedly")
 	} else if ee, ok := err.(*exec.ExitError); !ok {
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
index 0e798fc..feacfb6 100644
--- a/src/runtime/debug.go
+++ b/src/runtime/debug.go
@@ -15,9 +15,6 @@
 // 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)
diff --git a/src/runtime/defs1_netbsd_386.go b/src/runtime/defs1_netbsd_386.go
index 66f07ce..c26f417 100644
--- a/src/runtime/defs1_netbsd_386.go
+++ b/src/runtime/defs1_netbsd_386.go
@@ -79,6 +79,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = 0x0
 	_EVFILT_WRITE = 0x1
 )
diff --git a/src/runtime/defs1_netbsd_amd64.go b/src/runtime/defs1_netbsd_amd64.go
index 9e31471..0704cd4 100644
--- a/src/runtime/defs1_netbsd_amd64.go
+++ b/src/runtime/defs1_netbsd_amd64.go
@@ -79,6 +79,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = 0x0
 	_EVFILT_WRITE = 0x1
 )
diff --git a/src/runtime/defs1_netbsd_arm.go b/src/runtime/defs1_netbsd_arm.go
index db8e4c6..d2a13ad 100644
--- a/src/runtime/defs1_netbsd_arm.go
+++ b/src/runtime/defs1_netbsd_arm.go
@@ -79,6 +79,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = 0x0
 	_EVFILT_WRITE = 0x1
 )
diff --git a/src/runtime/defs_darwin.go b/src/runtime/defs_darwin.go
index 78df4e7..f7d65e7 100644
--- a/src/runtime/defs_darwin.go
+++ b/src/runtime/defs_darwin.go
@@ -139,6 +139,7 @@
 	EV_CLEAR     = C.EV_CLEAR
 	EV_RECEIPT   = C.EV_RECEIPT
 	EV_ERROR     = C.EV_ERROR
+	EV_EOF       = C.EV_EOF
 	EVFILT_READ  = C.EVFILT_READ
 	EVFILT_WRITE = C.EVFILT_WRITE
 )
diff --git a/src/runtime/defs_darwin_386.go b/src/runtime/defs_darwin_386.go
index 1a5967b..f6dbcc5 100644
--- a/src/runtime/defs_darwin_386.go
+++ b/src/runtime/defs_darwin_386.go
@@ -118,6 +118,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_darwin_amd64.go b/src/runtime/defs_darwin_amd64.go
index a4ab090..245fe15 100644
--- a/src/runtime/defs_darwin_amd64.go
+++ b/src/runtime/defs_darwin_amd64.go
@@ -118,6 +118,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_darwin_arm.go b/src/runtime/defs_darwin_arm.go
index 3f8dbbf..f89aee6 100644
--- a/src/runtime/defs_darwin_arm.go
+++ b/src/runtime/defs_darwin_arm.go
@@ -120,6 +120,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_darwin_arm64.go b/src/runtime/defs_darwin_arm64.go
index c25a41b..a0ca7f1 100644
--- a/src/runtime/defs_darwin_arm64.go
+++ b/src/runtime/defs_darwin_arm64.go
@@ -118,6 +118,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_dragonfly.go b/src/runtime/defs_dragonfly.go
index ed00be0..95014fe 100644
--- a/src/runtime/defs_dragonfly.go
+++ b/src/runtime/defs_dragonfly.go
@@ -103,6 +103,7 @@
 	EV_DELETE    = C.EV_DELETE
 	EV_CLEAR     = C.EV_CLEAR
 	EV_ERROR     = C.EV_ERROR
+	EV_EOF       = C.EV_EOF
 	EVFILT_READ  = C.EVFILT_READ
 	EVFILT_WRITE = C.EVFILT_WRITE
 )
diff --git a/src/runtime/defs_dragonfly_amd64.go b/src/runtime/defs_dragonfly_amd64.go
index fc70103..c30da80 100644
--- a/src/runtime/defs_dragonfly_amd64.go
+++ b/src/runtime/defs_dragonfly_amd64.go
@@ -82,6 +82,7 @@
 	_EV_DELETE    = 0x2
 	_EV_CLEAR     = 0x20
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_freebsd.go b/src/runtime/defs_freebsd.go
index 0a11d09..9d55111 100644
--- a/src/runtime/defs_freebsd.go
+++ b/src/runtime/defs_freebsd.go
@@ -125,6 +125,7 @@
 	EV_CLEAR     = C.EV_CLEAR
 	EV_RECEIPT   = C.EV_RECEIPT
 	EV_ERROR     = C.EV_ERROR
+	EV_EOF       = C.EV_EOF
 	EVFILT_READ  = C.EVFILT_READ
 	EVFILT_WRITE = C.EVFILT_WRITE
 )
diff --git a/src/runtime/defs_freebsd_386.go b/src/runtime/defs_freebsd_386.go
index 92b0550..49bcbb1 100644
--- a/src/runtime/defs_freebsd_386.go
+++ b/src/runtime/defs_freebsd_386.go
@@ -95,6 +95,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_freebsd_amd64.go b/src/runtime/defs_freebsd_amd64.go
index 645e205..0e1c675 100644
--- a/src/runtime/defs_freebsd_amd64.go
+++ b/src/runtime/defs_freebsd_amd64.go
@@ -95,6 +95,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_freebsd_arm.go b/src/runtime/defs_freebsd_arm.go
index c8a198f..71684fe 100644
--- a/src/runtime/defs_freebsd_arm.go
+++ b/src/runtime/defs_freebsd_arm.go
@@ -95,6 +95,7 @@
 	_EV_CLEAR     = 0x20
 	_EV_RECEIPT   = 0x40
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_netbsd.go b/src/runtime/defs_netbsd.go
index 56db1f0..41aa07a 100644
--- a/src/runtime/defs_netbsd.go
+++ b/src/runtime/defs_netbsd.go
@@ -105,6 +105,7 @@
 	EV_CLEAR     = C.EV_CLEAR
 	EV_RECEIPT   = 0
 	EV_ERROR     = C.EV_ERROR
+	EV_EOF       = C.EV_EOF
 	EVFILT_READ  = C.EVFILT_READ
 	EVFILT_WRITE = C.EVFILT_WRITE
 )
diff --git a/src/runtime/defs_openbsd.go b/src/runtime/defs_openbsd.go
index 7e72150..9ff13df 100644
--- a/src/runtime/defs_openbsd.go
+++ b/src/runtime/defs_openbsd.go
@@ -100,6 +100,7 @@
 	EV_DELETE    = C.EV_DELETE
 	EV_CLEAR     = C.EV_CLEAR
 	EV_ERROR     = C.EV_ERROR
+	EV_EOF       = C.EV_EOF
 	EVFILT_READ  = C.EVFILT_READ
 	EVFILT_WRITE = C.EVFILT_WRITE
 )
diff --git a/src/runtime/defs_openbsd_386.go b/src/runtime/defs_openbsd_386.go
index ce08111..1185530 100644
--- a/src/runtime/defs_openbsd_386.go
+++ b/src/runtime/defs_openbsd_386.go
@@ -80,6 +80,7 @@
 	_EV_DELETE    = 0x2
 	_EV_CLEAR     = 0x20
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_openbsd_amd64.go b/src/runtime/defs_openbsd_amd64.go
index ea07098..4bb8eac 100644
--- a/src/runtime/defs_openbsd_amd64.go
+++ b/src/runtime/defs_openbsd_amd64.go
@@ -80,6 +80,7 @@
 	_EV_DELETE    = 0x2
 	_EV_CLEAR     = 0x20
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
index b0fb639..38b77c9 100644
--- a/src/runtime/defs_openbsd_arm.go
+++ b/src/runtime/defs_openbsd_arm.go
@@ -80,6 +80,7 @@
 	_EV_DELETE    = 0x2
 	_EV_CLEAR     = 0x20
 	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
 	_EVFILT_READ  = -0x1
 	_EVFILT_WRITE = -0x2
 )
diff --git a/src/runtime/duff_amd64.s b/src/runtime/duff_amd64.s
index a1112a4..44dc75d 100644
--- a/src/runtime/duff_amd64.s
+++ b/src/runtime/duff_amd64.s
@@ -9,97 +9,97 @@
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	MOVUPS	X0,(DI)
 	MOVUPS	X0,16(DI)
 	MOVUPS	X0,32(DI)
 	MOVUPS	X0,48(DI)
-	ADDQ	$64,DI
+	LEAQ	64(DI),DI
 
 	RET
 
diff --git a/src/runtime/duff_arm64.s b/src/runtime/duff_arm64.s
index 60a0e26..21619ff 100644
--- a/src/runtime/duff_arm64.s
+++ b/src/runtime/duff_arm64.s
@@ -5,134 +5,70 @@
 #include "textflag.h"
 
 TEXT runtime·duffzero(SB), NOSPLIT, $-8-0
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
-	MOVD.W	ZR, 8(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP.P	(ZR, ZR), 16(R16)
+	STP	(ZR, ZR), (R16)
 	RET
 
 TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
diff --git a/src/runtime/error.go b/src/runtime/error.go
index eafcc9b..6048272 100644
--- a/src/runtime/error.go
+++ b/src/runtime/error.go
@@ -72,8 +72,7 @@
 	return e._type.string()
 }
 
-// For calling from C.
-// Prints an argument passed to panic.
+// printany prints an argument passed to panic.
 func printany(i interface{}) {
 	switch v := i.(type) {
 	case nil:
@@ -126,34 +125,31 @@
 //go:linkname stringsIndexByte strings.IndexByte
 func stringsIndexByte(s string, c byte) int
 
-// called from generated code
+// panicwrap generates a panic for a call to a wrapped value method
+// with a nil pointer receiver.
+//
+// It is called from the generated wrapper code.
 func panicwrap() {
-	pc := make([]uintptr, 1)
-	n := Callers(2, pc)
-	if n == 0 {
-		throw("panicwrap: Callers failed")
-	}
-	frames := CallersFrames(pc)
-	frame, _ := frames.Next()
-	name := frame.Function
+	pc := getcallerpc()
+	name := funcname(findfunc(pc))
 	// name is something like "main.(*T).F".
 	// We want to extract pkg ("main"), typ ("T"), and meth ("F").
 	// Do it by finding the parens.
 	i := stringsIndexByte(name, '(')
 	if i < 0 {
-		throw("panicwrap: no ( in " + frame.Function)
+		throw("panicwrap: no ( in " + name)
 	}
 	pkg := name[:i-1]
 	if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
-		throw("panicwrap: unexpected string after package name: " + frame.Function)
+		throw("panicwrap: unexpected string after package name: " + name)
 	}
 	name = name[i+2:]
 	i = stringsIndexByte(name, ')')
 	if i < 0 {
-		throw("panicwrap: no ) in " + frame.Function)
+		throw("panicwrap: no ) in " + name)
 	}
 	if i+2 >= len(name) || name[i:i+2] != ")." {
-		throw("panicwrap: unexpected string after type name: " + frame.Function)
+		throw("panicwrap: unexpected string after type name: " + name)
 	}
 	typ := name[:i]
 	meth := name[i+2:]
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index c929bd4..385c569 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -152,12 +152,19 @@
 	}
 }
 
-var StringHash = stringHash
-var BytesHash = bytesHash
-var Int32Hash = int32Hash
-var Int64Hash = int64Hash
-var EfaceHash = efaceHash
-var IfaceHash = ifaceHash
+var (
+	StringHash = stringHash
+	BytesHash  = bytesHash
+	Int32Hash  = int32Hash
+	Int64Hash  = int64Hash
+	MemHash    = memhash
+	MemHash32  = memhash32
+	MemHash64  = memhash64
+	EfaceHash  = efaceHash
+	IfaceHash  = ifaceHash
+)
+
+var UseAeshash = &useAeshash
 
 func MemclrBytes(b []byte) {
 	s := (*slice)(unsafe.Pointer(&b))
@@ -369,3 +376,40 @@
 func (rw *RWMutex) Unlock() {
 	rw.rw.unlock()
 }
+
+func MapBucketsCount(m map[int]int) int {
+	h := *(**hmap)(unsafe.Pointer(&m))
+	return 1 << h.B
+}
+
+func MapBucketsPointerIsNil(m map[int]int) bool {
+	h := *(**hmap)(unsafe.Pointer(&m))
+	return h.buckets == nil
+}
+
+func LockOSCounts() (external, internal uint32) {
+	g := getg()
+	if g.m.lockedExt+g.m.lockedInt == 0 {
+		if g.lockedm != 0 {
+			panic("lockedm on non-locked goroutine")
+		}
+	} else {
+		if g.lockedm == 0 {
+			panic("nil lockedm on locked goroutine")
+		}
+	}
+	return g.m.lockedExt, g.m.lockedInt
+}
+
+//go:noinline
+func TracebackSystemstack(stk []uintptr, i int) int {
+	if i == 0 {
+		pc, sp := getcallerpc(), getcallersp(unsafe.Pointer(&stk))
+		return gentraceback(pc, sp, 0, getg(), 0, &stk[0], len(stk), nil, nil, _TraceJumpStack)
+	}
+	n := 0
+	systemstack(func() {
+		n = TracebackSystemstack(stk, i-1)
+	})
+	return n
+}
diff --git a/src/runtime/extern.go b/src/runtime/extern.go
index 6e6c674..2c20e0d 100644
--- a/src/runtime/extern.go
+++ b/src/runtime/extern.go
@@ -178,11 +178,11 @@
 	// We asked for one extra, so skip that one. If this is sigpanic,
 	// stepping over this frame will set up state in Frames so the
 	// next frame is correct.
-	callers, _, ok = stackExpander.next(callers)
+	callers, _, ok = stackExpander.next(callers, true)
 	if !ok {
 		return
 	}
-	_, frame, _ := stackExpander.next(callers)
+	_, frame, _ := stackExpander.next(callers, true)
 	pc = frame.PC
 	file = frame.File
 	line = frame.Line
@@ -212,8 +212,8 @@
 	return callers(skip, pc)
 }
 
-// GOROOT returns the root of the Go tree.
-// It uses the GOROOT environment variable, if set,
+// GOROOT returns the root of the Go tree. It uses the
+// GOROOT environment variable, if set at process start,
 // or else the root used during the Go build.
 func GOROOT() string {
 	s := gogetenv("GOROOT")
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
index 03acc8a..1b1db25 100644
--- a/src/runtime/gc_test.go
+++ b/src/runtime/gc_test.go
@@ -10,6 +10,7 @@
 	"reflect"
 	"runtime"
 	"runtime/debug"
+	"sync/atomic"
 	"testing"
 	"time"
 	"unsafe"
@@ -170,7 +171,7 @@
 	// slack if things are slow.
 	var numGCs uint32
 	const want = 2
-	for i := 0; i < 20 && numGCs < want; i++ {
+	for i := 0; i < 200 && numGCs < want; i++ {
 		time.Sleep(5 * time.Millisecond)
 
 		// Test that periodic GC actually happened.
@@ -499,3 +500,142 @@
 
 	hugeSink = nil
 }
+
+func TestUserForcedGC(t *testing.T) {
+	// Test that runtime.GC() triggers a GC even if GOGC=off.
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
+
+	var ms1, ms2 runtime.MemStats
+	runtime.ReadMemStats(&ms1)
+	runtime.GC()
+	runtime.ReadMemStats(&ms2)
+	if ms1.NumGC == ms2.NumGC {
+		t.Fatalf("runtime.GC() did not trigger GC")
+	}
+	if ms1.NumForcedGC == ms2.NumForcedGC {
+		t.Fatalf("runtime.GC() was not accounted in NumForcedGC")
+	}
+}
+
+func writeBarrierBenchmark(b *testing.B, f func()) {
+	runtime.GC()
+	var ms runtime.MemStats
+	runtime.ReadMemStats(&ms)
+	//b.Logf("heap size: %d MB", ms.HeapAlloc>>20)
+
+	// Keep GC running continuously during the benchmark, which in
+	// turn keeps the write barrier on continuously.
+	var stop uint32
+	done := make(chan bool)
+	go func() {
+		for atomic.LoadUint32(&stop) == 0 {
+			runtime.GC()
+		}
+		close(done)
+	}()
+	defer func() {
+		atomic.StoreUint32(&stop, 1)
+		<-done
+	}()
+
+	b.ResetTimer()
+	f()
+	b.StopTimer()
+}
+
+func BenchmarkWriteBarrier(b *testing.B) {
+	if runtime.GOMAXPROCS(-1) < 2 {
+		// We don't want GC to take our time.
+		b.Skip("need GOMAXPROCS >= 2")
+	}
+
+	// Construct a large tree both so the GC runs for a while and
+	// so we have a data structure to manipulate the pointers of.
+	type node struct {
+		l, r *node
+	}
+	var wbRoots []*node
+	var mkTree func(level int) *node
+	mkTree = func(level int) *node {
+		if level == 0 {
+			return nil
+		}
+		n := &node{mkTree(level - 1), mkTree(level - 1)}
+		if level == 10 {
+			// Seed GC with enough early pointers so it
+			// doesn't accidentally switch to mark 2 when
+			// it only has the top of the tree.
+			wbRoots = append(wbRoots, n)
+		}
+		return n
+	}
+	const depth = 22 // 64 MB
+	root := mkTree(22)
+
+	writeBarrierBenchmark(b, func() {
+		var stack [depth]*node
+		tos := -1
+
+		// There are two write barriers per iteration, so i+=2.
+		for i := 0; i < b.N; i += 2 {
+			if tos == -1 {
+				stack[0] = root
+				tos = 0
+			}
+
+			// Perform one step of reversing the tree.
+			n := stack[tos]
+			if n.l == nil {
+				tos--
+			} else {
+				n.l, n.r = n.r, n.l
+				stack[tos] = n.l
+				stack[tos+1] = n.r
+				tos++
+			}
+
+			if i%(1<<12) == 0 {
+				// Avoid non-preemptible loops (see issue #10958).
+				runtime.Gosched()
+			}
+		}
+	})
+
+	runtime.KeepAlive(wbRoots)
+}
+
+func BenchmarkBulkWriteBarrier(b *testing.B) {
+	if runtime.GOMAXPROCS(-1) < 2 {
+		// We don't want GC to take our time.
+		b.Skip("need GOMAXPROCS >= 2")
+	}
+
+	// Construct a large set of objects we can copy around.
+	const heapSize = 64 << 20
+	type obj [16]*byte
+	ptrs := make([]*obj, heapSize/unsafe.Sizeof(obj{}))
+	for i := range ptrs {
+		ptrs[i] = new(obj)
+	}
+
+	writeBarrierBenchmark(b, func() {
+		const blockSize = 1024
+		var pos int
+		for i := 0; i < b.N; i += blockSize {
+			// Rotate block.
+			block := ptrs[pos : pos+blockSize]
+			first := block[0]
+			copy(block, block[1:])
+			block[blockSize-1] = first
+
+			pos += blockSize
+			if pos+blockSize > len(ptrs) {
+				pos = 0
+			}
+
+			runtime.Gosched()
+		}
+	})
+
+	runtime.KeepAlive(ptrs)
+}
diff --git a/src/runtime/hash32.go b/src/runtime/hash32.go
index be59076..5574923 100644
--- a/src/runtime/hash32.go
+++ b/src/runtime/hash32.go
@@ -81,6 +81,32 @@
 	return uintptr(h)
 }
 
+func memhash32(p unsafe.Pointer, seed uintptr) uintptr {
+	h := uint32(seed + 4*hashkey[0])
+	h ^= readUnaligned32(p)
+	h = rotl_15(h*m1) * m2
+	h ^= h >> 17
+	h *= m3
+	h ^= h >> 13
+	h *= m4
+	h ^= h >> 16
+	return uintptr(h)
+}
+
+func memhash64(p unsafe.Pointer, seed uintptr) uintptr {
+	h := uint32(seed + 8*hashkey[0])
+	h ^= readUnaligned32(p)
+	h = rotl_15(h*m1) * m2
+	h ^= readUnaligned32(add(p, 4))
+	h = rotl_15(h*m1) * m2
+	h ^= h >> 17
+	h *= m3
+	h ^= h >> 13
+	h *= m4
+	h ^= h >> 16
+	return uintptr(h)
+}
+
 // Note: in order to get the compiler to issue rotl instructions, we
 // need to constant fold the shift amount by hand.
 // TODO: convince the compiler to issue rotl instructions after inlining.
diff --git a/src/runtime/hash64.go b/src/runtime/hash64.go
index d61f114..3cf3f46 100644
--- a/src/runtime/hash64.go
+++ b/src/runtime/hash64.go
@@ -81,6 +81,28 @@
 	return uintptr(h)
 }
 
+func memhash32(p unsafe.Pointer, seed uintptr) uintptr {
+	h := uint64(seed + 4*hashkey[0])
+	v := uint64(readUnaligned32(p))
+	h ^= v
+	h ^= v << 32
+	h = rotl_31(h*m1) * m2
+	h ^= h >> 29
+	h *= m3
+	h ^= h >> 32
+	return uintptr(h)
+}
+
+func memhash64(p unsafe.Pointer, seed uintptr) uintptr {
+	h := uint64(seed + 8*hashkey[0])
+	h ^= uint64(readUnaligned32(p)) | uint64(readUnaligned32(add(p, 4)))<<32
+	h = rotl_31(h*m1) * m2
+	h ^= h >> 29
+	h *= m3
+	h ^= h >> 32
+	return uintptr(h)
+}
+
 // Note: in order to get the compiler to issue rotl instructions, we
 // need to constant fold the shift amount by hand.
 // TODO: convince the compiler to issue rotl instructions after inlining.
diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go
index a6f3cdb..1400579 100644
--- a/src/runtime/hash_test.go
+++ b/src/runtime/hash_test.go
@@ -14,6 +14,40 @@
 	"unsafe"
 )
 
+func TestMemHash32Equality(t *testing.T) {
+	if *UseAeshash {
+		t.Skip("skipping since AES hash implementation is used")
+	}
+	var b [4]byte
+	r := rand.New(rand.NewSource(1234))
+	seed := uintptr(r.Uint64())
+	for i := 0; i < 100; i++ {
+		randBytes(r, b[:])
+		got := MemHash32(unsafe.Pointer(&b), seed)
+		want := MemHash(unsafe.Pointer(&b), seed, 4)
+		if got != want {
+			t.Errorf("MemHash32(%x, %v) = %v; want %v", b, seed, got, want)
+		}
+	}
+}
+
+func TestMemHash64Equality(t *testing.T) {
+	if *UseAeshash {
+		t.Skip("skipping since AES hash implementation is used")
+	}
+	var b [8]byte
+	r := rand.New(rand.NewSource(1234))
+	seed := uintptr(r.Uint64())
+	for i := 0; i < 100; i++ {
+		randBytes(r, b[:])
+		got := MemHash64(unsafe.Pointer(&b), seed)
+		want := MemHash(unsafe.Pointer(&b), seed, 8)
+		if got != want {
+			t.Errorf("MemHash64(%x, %v) = %v; want %v", b, seed, got, want)
+		}
+	}
+}
+
 // 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.
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go
index 11ce0cb..dee5dd5 100644
--- a/src/runtime/hashmap.go
+++ b/src/runtime/hashmap.go
@@ -64,8 +64,10 @@
 	bucketCntBits = 3
 	bucketCnt     = 1 << bucketCntBits
 
-	// Maximum average load of a bucket that triggers growth.
-	loadFactor = 6.5
+	// Maximum average load of a bucket that triggers growth is 6.5.
+	// Represent as loadFactorNum/loadFactDen, to allow integer math.
+	loadFactorNum = 13
+	loadFactorDen = 2
 
 	// Maximum key or value size to keep inline (instead of mallocing per element).
 	// Must fit in a uint8.
@@ -124,12 +126,13 @@
 	// If both key and value do not contain pointers and are inline, then we mark bucket
 	// type as containing no pointers. This avoids scanning such maps.
 	// However, bmap.overflow is a pointer. In order to keep overflow buckets
-	// alive, we store pointers to all overflow buckets in hmap.overflow.
-	// Overflow is used only if key and value do not contain pointers.
-	// overflow[0] contains overflow buckets for hmap.buckets.
-	// overflow[1] contains overflow buckets for hmap.oldbuckets.
+	// alive, we store pointers to all overflow buckets in hmap.overflow and h.map.oldoverflow.
+	// overflow and oldoverflow are only used if key and value do not contain pointers.
+	// overflow contains overflow buckets for hmap.buckets.
+	// oldoverflow contains overflow buckets for hmap.oldbuckets.
 	// The indirection allows to store a pointer to the slice in hiter.
-	overflow [2]*[]*bmap
+	overflow    *[]*bmap
+	oldoverflow *[]*bmap
 
 	// nextOverflow holds a pointer to a free overflow bucket.
 	nextOverflow *bmap
@@ -158,7 +161,8 @@
 	h           *hmap
 	buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
 	bptr        *bmap          // current bucket
-	overflow    [2]*[]*bmap    // keeps overflow buckets alive
+	overflow    *[]*bmap       // keeps overflow buckets of hmap.buckets alive
+	oldoverflow *[]*bmap       // keeps overflow buckets of hmap.oldbuckets alive
 	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
@@ -168,6 +172,28 @@
 	checkBucket uintptr
 }
 
+// bucketShift returns 1<<b, optimized for code generation.
+func bucketShift(b uint8) uintptr {
+	if sys.GoarchAmd64|sys.GoarchAmd64p32|sys.Goarch386 != 0 {
+		b &= sys.PtrSize*8 - 1 // help x86 archs remove shift overflow checks
+	}
+	return uintptr(1) << b
+}
+
+// bucketMask returns 1<<b - 1, optimized for code generation.
+func bucketMask(b uint8) uintptr {
+	return bucketShift(b) - 1
+}
+
+// tophash calculates the tophash value for hash.
+func tophash(hash uintptr) uint8 {
+	top := uint8(hash >> (sys.PtrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	return top
+}
+
 func evacuated(b *bmap) bool {
 	h := b.tophash[0]
 	return h > empty && h < minTopHash
@@ -181,6 +207,10 @@
 	*(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-sys.PtrSize)) = ovf
 }
 
+func (b *bmap) keys() unsafe.Pointer {
+	return add(unsafe.Pointer(b), dataOffset)
+}
+
 // incrnoverflow increments h.noverflow.
 // noverflow counts the number of overflow buckets.
 // This is used to trigger same-size map growth.
@@ -229,7 +259,7 @@
 	h.incrnoverflow()
 	if t.bucket.kind&kindNoPointers != 0 {
 		h.createOverflow()
-		*h.extra.overflow[0] = append(*h.extra.overflow[0], ovf)
+		*h.extra.overflow = append(*h.extra.overflow, ovf)
 	}
 	b.setoverflow(t, ovf)
 	return ovf
@@ -239,96 +269,68 @@
 	if h.extra == nil {
 		h.extra = new(mapextra)
 	}
-	if h.extra.overflow[0] == nil {
-		h.extra.overflow[0] = new([]*bmap)
+	if h.extra.overflow == nil {
+		h.extra.overflow = new([]*bmap)
 	}
 }
 
-// makemap implements a Go map creation make(map[k]v, hint)
+func makemap64(t *maptype, hint int64, h *hmap) *hmap {
+	if int64(int(hint)) != hint {
+		hint = 0
+	}
+	return makemap(t, int(hint), h)
+}
+
+// makehmap_small implements Go map creation for make(map[k]v) and
+// make(map[k]v, hint) when hint is known to be at most bucketCnt
+// at compile time and the map needs to be allocated on the heap.
+func makemap_small() *hmap {
+	h := new(hmap)
+	h.hash0 = fastrand()
+	return h
+}
+
+// makemap implements Go map creation for make(map[k]v, hint).
 // If the compiler has determined that the map or the first bucket
 // can be created on the stack, h and/or bucket may be non-nil.
 // If h != nil, the map can be created directly in h.
-// If bucket != nil, bucket can be used as the first bucket.
-func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
-	if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != t.hmap.size {
+// If h.buckets != nil, bucket pointed to can be used as the first bucket.
+func makemap(t *maptype, hint int, h *hmap) *hmap {
+	// The size of hmap should be 48 bytes on 64 bit
+	// and 28 bytes on 32 bit platforms.
+	if sz := unsafe.Sizeof(hmap{}); sz != 8+5*sys.PtrSize {
 		println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
 		throw("bad hmap size")
 	}
 
-	if hint < 0 || hint > int64(maxSliceCap(t.bucket.size)) {
+	if hint < 0 || hint > int(maxSliceCap(t.bucket.size)) {
 		hint = 0
 	}
 
-	if !ismapkey(t.key) {
-		throw("runtime.makemap: unsupported map key type")
-	}
-
-	// check compiler's and reflect's math
-	if t.key.size > maxKeySize && (!t.indirectkey || t.keysize != uint8(sys.PtrSize)) ||
-		t.key.size <= maxKeySize && (t.indirectkey || t.keysize != uint8(t.key.size)) {
-		throw("key size wrong")
-	}
-	if t.elem.size > maxValueSize && (!t.indirectvalue || t.valuesize != uint8(sys.PtrSize)) ||
-		t.elem.size <= maxValueSize && (t.indirectvalue || t.valuesize != uint8(t.elem.size)) {
-		throw("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 {
-		throw("key align too big")
-	}
-	if t.elem.align > bucketCnt {
-		throw("value align too big")
-	}
-	if t.key.size%uintptr(t.key.align) != 0 {
-		throw("key size not a multiple of key align")
-	}
-	if t.elem.size%uintptr(t.elem.align) != 0 {
-		throw("value size not a multiple of value align")
-	}
-	if bucketCnt < 8 {
-		throw("bucketsize too small for proper alignment")
-	}
-	if dataOffset%uintptr(t.key.align) != 0 {
-		throw("need padding in bucket (key)")
-	}
-	if dataOffset%uintptr(t.elem.align) != 0 {
-		throw("need padding in bucket (value)")
-	}
-
-	// find size parameter which will hold the requested # of elements
-	B := uint8(0)
-	for ; overLoadFactor(hint, 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.
-	buckets := bucket
-	var extra *mapextra
-	if B != 0 {
-		var nextOverflow *bmap
-		buckets, nextOverflow = makeBucketArray(t, B)
-		if nextOverflow != nil {
-			extra = new(mapextra)
-			extra.nextOverflow = nextOverflow
-		}
-	}
-
 	// initialize Hmap
 	if h == nil {
 		h = (*hmap)(newobject(t.hmap))
 	}
-	h.count = 0
-	h.B = B
-	h.extra = extra
-	h.flags = 0
 	h.hash0 = fastrand()
-	h.buckets = buckets
-	h.oldbuckets = nil
-	h.nevacuate = 0
-	h.noverflow = 0
+
+	// find size parameter which will hold the requested # of elements
+	B := uint8(0)
+	for overLoadFactor(hint, B) {
+		B++
+	}
+	h.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.
+	if h.B != 0 {
+		var nextOverflow *bmap
+		h.buckets, nextOverflow = makeBucketArray(t, h.B)
+		if nextOverflow != nil {
+			h.extra = new(mapextra)
+			h.extra.nextOverflow = nextOverflow
+		}
+	}
 
 	return h
 }
@@ -340,7 +342,7 @@
 // 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))
+		callerpc := getcallerpc()
 		pc := funcPC(mapaccess1)
 		racereadpc(unsafe.Pointer(h), callerpc, pc)
 		raceReadObjectPC(t.key, key, callerpc, pc)
@@ -356,7 +358,7 @@
 	}
 	alg := t.key.alg
 	hash := alg.hash(key, uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
+	m := bucketMask(h.B)
 	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
@@ -368,11 +370,8 @@
 			b = oldb
 		}
 	}
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
+	top := tophash(hash)
+	for ; b != nil; b = b.overflow(t) {
 		for i := uintptr(0); i < bucketCnt; i++ {
 			if b.tophash[i] != top {
 				continue
@@ -389,16 +388,13 @@
 				return v
 			}
 		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0])
-		}
 	}
+	return unsafe.Pointer(&zeroVal[0])
 }
 
 func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		pc := funcPC(mapaccess2)
 		racereadpc(unsafe.Pointer(h), callerpc, pc)
 		raceReadObjectPC(t.key, key, callerpc, pc)
@@ -414,7 +410,7 @@
 	}
 	alg := t.key.alg
 	hash := alg.hash(key, uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
+	m := bucketMask(h.B)
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
@@ -426,11 +422,8 @@
 			b = oldb
 		}
 	}
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
+	top := tophash(hash)
+	for ; b != nil; b = b.overflow(t) {
 		for i := uintptr(0); i < bucketCnt; i++ {
 			if b.tophash[i] != top {
 				continue
@@ -447,11 +440,8 @@
 				return v, true
 			}
 		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0]), false
-		}
 	}
+	return unsafe.Pointer(&zeroVal[0]), false
 }
 
 // returns both key and value. Used by map iterator
@@ -461,7 +451,7 @@
 	}
 	alg := t.key.alg
 	hash := alg.hash(key, uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
+	m := bucketMask(h.B)
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
@@ -473,11 +463,8 @@
 			b = oldb
 		}
 	}
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
+	top := tophash(hash)
+	for ; b != nil; b = b.overflow(t) {
 		for i := uintptr(0); i < bucketCnt; i++ {
 			if b.tophash[i] != top {
 				continue
@@ -494,11 +481,8 @@
 				return k, v
 			}
 		}
-		b = b.overflow(t)
-		if b == nil {
-			return nil, nil
-		}
 	}
+	return nil, nil
 }
 
 func mapaccess1_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) unsafe.Pointer {
@@ -523,7 +507,7 @@
 		panic(plainError("assignment to entry in nil map"))
 	}
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		pc := funcPC(mapassign)
 		racewritepc(unsafe.Pointer(h), callerpc, pc)
 		raceReadObjectPC(t.key, key, callerpc, pc)
@@ -542,19 +526,16 @@
 	h.flags |= hashWriting
 
 	if h.buckets == nil {
-		h.buckets = newarray(t.bucket, 1)
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
 	}
 
 again:
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
 		growWork(t, h, bucket)
 	}
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
+	top := tophash(hash)
 
 	var inserti *uint8
 	var insertk unsafe.Pointer
@@ -594,7 +575,7 @@
 
 	// If we hit the max load factor or we have too many overflow buckets,
 	// and we're not already in the middle of growing, start growing.
-	if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
 		hashGrow(t, h)
 		goto again // Growing the table invalidates everything, so try again
 	}
@@ -634,7 +615,7 @@
 
 func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		pc := funcPC(mapdelete)
 		racewritepc(unsafe.Pointer(h), callerpc, pc)
 		raceReadObjectPC(t.key, key, callerpc, pc)
@@ -656,16 +637,14 @@
 	// in which case we have not actually done a write (delete).
 	h.flags |= hashWriting
 
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
 		growWork(t, h, bucket)
 	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
+	b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
+	top := tophash(hash)
+search:
+	for ; b != nil; b = b.overflow(t) {
 		for i := uintptr(0); i < bucketCnt; i++ {
 			if b.tophash[i] != top {
 				continue
@@ -678,53 +657,44 @@
 			if !alg.equal(key, k2) {
 				continue
 			}
+			// Only clear key if there are pointers in it.
 			if t.indirectkey {
 				*(*unsafe.Pointer)(k) = nil
-			} else {
-				typedmemclr(t.key, k)
+			} else if t.key.kind&kindNoPointers == 0 {
+				memclrHasPointers(k, t.key.size)
 			}
-			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
-			if t.indirectvalue {
-				*(*unsafe.Pointer)(v) = nil
-			} else {
-				typedmemclr(t.elem, v)
+			// Only clear value if there are pointers in it.
+			if t.indirectvalue || t.elem.kind&kindNoPointers == 0 {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				if t.indirectvalue {
+					*(*unsafe.Pointer)(v) = nil
+				} else {
+					memclrHasPointers(v, t.elem.size)
+				}
 			}
 			b.tophash[i] = empty
 			h.count--
-			goto done
-		}
-		b = b.overflow(t)
-		if b == nil {
-			goto done
+			break search
 		}
 	}
 
-done:
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
 	h.flags &^= hashWriting
 }
 
+// mapiterinit initializes the hiter struct used for ranging over maps.
+// The hiter struct pointed to by 'it' is allocated on the stack
+// by the compilers order pass or on the heap by reflect_mapiterinit.
+// Both need to have zeroed hiter since the struct contains pointers.
 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
-	it.overflow[0] = nil
-	it.overflow[1] = nil
-
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiterinit))
 	}
 
 	if h == nil || h.count == 0 {
-		it.key = nil
-		it.value = nil
 		return
 	}
 
@@ -744,6 +714,7 @@
 		// while we are iterating.
 		h.createOverflow()
 		it.overflow = h.extra.overflow
+		it.oldoverflow = h.extra.oldoverflow
 	}
 
 	// decide where to start
@@ -751,16 +722,14 @@
 	if h.B > 31-bucketCntBits {
 		r += uintptr(fastrand()) << 31
 	}
-	it.startBucket = r & (uintptr(1)<<h.B - 1)
+	it.startBucket = r & bucketMask(h.B)
 	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().
+	// Can run concurrently with another mapiterinit().
 	if old := h.flags; old&(iterator|oldIterator) != iterator|oldIterator {
 		atomic.Or8(&h.flags, iterator|oldIterator)
 	}
@@ -771,7 +740,7 @@
 func mapiternext(it *hiter) {
 	h := it.h
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&it))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiternext))
 	}
 	if h.flags&hashWriting != 0 {
@@ -810,7 +779,7 @@
 			checkBucket = noCheck
 		}
 		bucket++
-		if bucket == uintptr(1)<<it.B {
+		if bucket == bucketShift(it.B) {
 			bucket = 0
 			it.wrapped = true
 		}
@@ -818,90 +787,75 @@
 	}
 	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 && !h.sameSizeGrow() {
-				// Special case: iterator was started during a grow to a larger size
-				// 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 t.reflexivekey || alg.equal(k2, k2) {
-					// If the item in the oldbucket is not destined for
-					// the current new bucket in the iteration, skip it.
-					hash := alg.hash(k2, 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 t.reflexivekey || alg.equal(k2, k2) {
-					// 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
-			if it.bptr != b { // avoid unnecessary write barrier; see issue 14921
-				it.bptr = b
-			}
-			it.i = i + 1
-			it.checkBucket = checkBucket
-			return
+		if b.tophash[offi] == empty || b.tophash[offi] == evacuatedEmpty {
+			continue
 		}
+		k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
+		if t.indirectkey {
+			k = *((*unsafe.Pointer)(k))
+		}
+		v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize))
+		if checkBucket != noCheck && !h.sameSizeGrow() {
+			// Special case: iterator was started during a grow to a larger size
+			// 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).
+			if t.reflexivekey || alg.equal(k, k) {
+				// If the item in the oldbucket is not destined for
+				// the current new bucket in the iteration, skip it.
+				hash := alg.hash(k, uintptr(h.hash0))
+				if hash&bucketMask(it.B) != 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) ||
+			!(t.reflexivekey || alg.equal(k, k)) {
+			// This is the golden data, we can return it.
+			// OR
+			// key!=key, so 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.
+			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.
+			// 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, k)
+			if rk == nil {
+				continue // key has been deleted
+			}
+			it.key = rk
+			it.value = rv
+		}
+		it.bucket = bucket
+		if it.bptr != b { // avoid unnecessary write barrier; see issue 14921
+			it.bptr = b
+		}
+		it.i = i + 1
+		it.checkBucket = checkBucket
+		return
 	}
 	b = b.overflow(t)
 	i = 0
@@ -909,7 +863,7 @@
 }
 
 func makeBucketArray(t *maptype, b uint8) (buckets unsafe.Pointer, nextOverflow *bmap) {
-	base := uintptr(1 << b)
+	base := bucketShift(b)
 	nbuckets := base
 	// For small b, overflow buckets are unlikely.
 	// Avoid the overhead of the calculation.
@@ -917,7 +871,7 @@
 		// Add on the estimated number of overflow buckets
 		// required to insert the median number of elements
 		// used with this value of b.
-		nbuckets += 1 << (b - 4)
+		nbuckets += bucketShift(b - 4)
 		sz := t.bucket.size * nbuckets
 		up := roundupsize(sz)
 		if up != sz {
@@ -943,7 +897,7 @@
 	// Otherwise, there are too many overflow buckets,
 	// so keep the same number of buckets and "grow" laterally.
 	bigger := uint8(1)
-	if !overLoadFactor(int64(h.count), h.B) {
+	if !overLoadFactor(h.count+1, h.B) {
 		bigger = 0
 		h.flags |= sameSizeGrow
 	}
@@ -962,13 +916,13 @@
 	h.nevacuate = 0
 	h.noverflow = 0
 
-	if h.extra != nil && h.extra.overflow[0] != nil {
+	if h.extra != nil && h.extra.overflow != nil {
 		// Promote current overflow buckets to the old generation.
-		if h.extra.overflow[1] != nil {
-			throw("overflow is not nil")
+		if h.extra.oldoverflow != nil {
+			throw("oldoverflow is not nil")
 		}
-		h.extra.overflow[1] = h.extra.overflow[0]
-		h.extra.overflow[0] = nil
+		h.extra.oldoverflow = h.extra.overflow
+		h.extra.overflow = nil
 	}
 	if nextOverflow != nil {
 		if h.extra == nil {
@@ -982,9 +936,8 @@
 }
 
 // overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor.
-func overLoadFactor(count int64, B uint8) bool {
-	// TODO: rewrite to use integer math and comparison?
-	return count >= bucketCnt && float32(count) >= loadFactor*float32((uint64(1)<<B))
+func overLoadFactor(count int, B uint8) bool {
+	return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
 }
 
 // tooManyOverflowBuckets reports whether noverflow buckets is too many for a map with 1<<B buckets.
@@ -995,10 +948,11 @@
 	// If the threshold is too high, maps that grow and shrink can hold on to lots of unused memory.
 	// "too many" means (approximately) as many overflow buckets as regular buckets.
 	// See incrnoverflow for more details.
-	if B < 16 {
-		return noverflow >= uint16(1)<<B
+	if B > 15 {
+		B = 15
 	}
-	return noverflow >= 1<<15
+	// The compiler doesn't see here that B < 16; mask B to generate shorter shift code.
+	return noverflow >= uint16(1)<<(B&15)
 }
 
 // growing reports whether h is growing. The growth may be to the same size or bigger.
@@ -1017,7 +971,7 @@
 	if !h.sameSizeGrow() {
 		oldB--
 	}
-	return uintptr(1) << oldB
+	return bucketShift(oldB)
 }
 
 // oldbucketmask provides a mask that can be applied to calculate n % noldbuckets().
@@ -1041,32 +995,37 @@
 	return evacuated(b)
 }
 
+// evacDst is an evacuation destination.
+type evacDst struct {
+	b *bmap          // current destination bucket
+	i int            // key/val index into b
+	k unsafe.Pointer // pointer to current key storage
+	v unsafe.Pointer // pointer to current value storage
+}
+
 func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
 	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
 	newbit := h.noldbuckets()
-	alg := 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.)
 
-		var (
-			x, y   *bmap          // current low/high buckets in new map
-			xi, yi int            // key/val indices into x and y
-			xk, yk unsafe.Pointer // pointers to current x and y key storage
-			xv, yv unsafe.Pointer // pointers to current x and y value storage
-		)
-		x = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
-		xi = 0
-		xk = add(unsafe.Pointer(x), dataOffset)
-		xv = add(xk, bucketCnt*uintptr(t.keysize))
+		// xy contains the x and y (low and high) evacuation destinations.
+		var xy [2]evacDst
+		x := &xy[0]
+		x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
+		x.k = add(unsafe.Pointer(x.b), dataOffset)
+		x.v = add(x.k, bucketCnt*uintptr(t.keysize))
+
 		if !h.sameSizeGrow() {
 			// Only calculate y pointers if we're growing bigger.
 			// Otherwise GC can see bad pointers.
-			y = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
-			yi = 0
-			yk = add(unsafe.Pointer(y), dataOffset)
-			yv = add(yk, bucketCnt*uintptr(t.keysize))
+			y := &xy[1]
+			y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
+			y.k = add(unsafe.Pointer(y.b), dataOffset)
+			y.v = add(y.k, bucketCnt*uintptr(t.keysize))
 		}
+
 		for ; b != nil; b = b.overflow(t) {
 			k := add(unsafe.Pointer(b), dataOffset)
 			v := add(k, bucketCnt*uintptr(t.keysize))
@@ -1083,122 +1042,102 @@
 				if t.indirectkey {
 					k2 = *((*unsafe.Pointer)(k2))
 				}
-				useX := true
+				var useY uint8
 				if !h.sameSizeGrow() {
 					// 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(h.hash0))
-					if h.flags&iterator != 0 {
-						if !t.reflexivekey && !alg.equal(k2, k2) {
-							// 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 >> (sys.PtrSize*8 - 8))
-							if top < minTopHash {
-								top += minTopHash
-							}
+					hash := t.key.alg.hash(k2, uintptr(h.hash0))
+					if h.flags&iterator != 0 && !t.reflexivekey && !t.key.alg.equal(k2, k2) {
+						// 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.
+						useY = top & 1
+						top = tophash(hash)
+					} else {
+						if hash&newbit != 0 {
+							useY = 1
 						}
 					}
-					useX = hash&newbit == 0
 				}
-				if useX {
-					b.tophash[i] = evacuatedX
-					if xi == bucketCnt {
-						newx := h.newoverflow(t, x)
-						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 {
-						typedmemmove(t.key, xk, k) // copy value
-					}
-					if t.indirectvalue {
-						*(*unsafe.Pointer)(xv) = *(*unsafe.Pointer)(v)
-					} else {
-						typedmemmove(t.elem, xv, v)
-					}
-					xi++
-					xk = add(xk, uintptr(t.keysize))
-					xv = add(xv, uintptr(t.valuesize))
+
+				if evacuatedX+1 != evacuatedY {
+					throw("bad evacuatedN")
+				}
+
+				b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY
+				dst := &xy[useY]                 // evacuation destination
+
+				if dst.i == bucketCnt {
+					dst.b = h.newoverflow(t, dst.b)
+					dst.i = 0
+					dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+					dst.v = add(dst.k, bucketCnt*uintptr(t.keysize))
+				}
+				dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+				if t.indirectkey {
+					*(*unsafe.Pointer)(dst.k) = k2 // copy pointer
 				} else {
-					b.tophash[i] = evacuatedY
-					if yi == bucketCnt {
-						newy := h.newoverflow(t, y)
-						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 {
-						typedmemmove(t.key, yk, k)
-					}
-					if t.indirectvalue {
-						*(*unsafe.Pointer)(yv) = *(*unsafe.Pointer)(v)
-					} else {
-						typedmemmove(t.elem, yv, v)
-					}
-					yi++
-					yk = add(yk, uintptr(t.keysize))
-					yv = add(yv, uintptr(t.valuesize))
+					typedmemmove(t.key, dst.k, k) // copy value
 				}
+				if t.indirectvalue {
+					*(*unsafe.Pointer)(dst.v) = *(*unsafe.Pointer)(v)
+				} else {
+					typedmemmove(t.elem, dst.v, v)
+				}
+				dst.i++
+				// These updates might push these pointers past the end of the
+				// key or value arrays.  That's ok, as we have the overflow pointer
+				// at the end of the bucket to protect against pointing past the
+				// end of the bucket.
+				dst.k = add(dst.k, uintptr(t.keysize))
+				dst.v = add(dst.v, 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)))
+		if h.flags&oldIterator == 0 && t.bucket.kind&kindNoPointers == 0 {
+			b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
 			// Preserve b.tophash because the evacuation
 			// state is maintained there.
-			if t.bucket.kind&kindNoPointers == 0 {
-				memclrHasPointers(add(unsafe.Pointer(b), dataOffset), uintptr(t.bucketsize)-dataOffset)
-			} else {
-				memclrNoHeapPointers(add(unsafe.Pointer(b), dataOffset), uintptr(t.bucketsize)-dataOffset)
-			}
+			ptr := add(b, dataOffset)
+			n := uintptr(t.bucketsize) - dataOffset
+			memclrHasPointers(ptr, n)
 		}
 	}
 
-	// Advance evacuation mark
 	if oldbucket == h.nevacuate {
-		h.nevacuate = oldbucket + 1
-		// Experiments suggest that 1024 is overkill by at least an order of magnitude.
-		// Put it in there as a safeguard anyway, to ensure O(1) behavior.
-		stop := h.nevacuate + 1024
-		if stop > newbit {
-			stop = newbit
+		advanceEvacuationMark(h, t, newbit)
+	}
+}
+
+func advanceEvacuationMark(h *hmap, t *maptype, newbit uintptr) {
+	h.nevacuate++
+	// Experiments suggest that 1024 is overkill by at least an order of magnitude.
+	// Put it in there as a safeguard anyway, to ensure O(1) behavior.
+	stop := h.nevacuate + 1024
+	if stop > newbit {
+		stop = newbit
+	}
+	for h.nevacuate != stop && bucketEvacuated(t, h, h.nevacuate) {
+		h.nevacuate++
+	}
+	if h.nevacuate == newbit { // newbit == # of oldbuckets
+		// Growing is all done. Free old main bucket array.
+		h.oldbuckets = nil
+		// Can discard old overflow buckets as well.
+		// If they are still referenced by an iterator,
+		// then the iterator holds a pointers to the slice.
+		if h.extra != nil {
+			h.extra.oldoverflow = nil
 		}
-		for h.nevacuate != stop && bucketEvacuated(t, h, h.nevacuate) {
-			h.nevacuate++
-		}
-		if h.nevacuate == newbit { // newbit == # of oldbuckets
-			// Growing is all done. Free old main bucket array.
-			h.oldbuckets = nil
-			// Can discard old overflow buckets as well.
-			// If they are still referenced by an iterator,
-			// then the iterator holds a pointers to the slice.
-			if h.extra != nil {
-				h.extra.overflow[1] = nil
-			}
-			h.flags &^= sameSizeGrow
-		}
+		h.flags &^= sameSizeGrow
 	}
 }
 
@@ -1210,7 +1149,45 @@
 
 //go:linkname reflect_makemap reflect.makemap
 func reflect_makemap(t *maptype, cap int) *hmap {
-	return makemap(t, int64(cap), nil, nil)
+	// Check invariants and reflects math.
+	if sz := unsafe.Sizeof(hmap{}); sz != t.hmap.size {
+		println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
+		throw("bad hmap size")
+	}
+	if !ismapkey(t.key) {
+		throw("runtime.reflect_makemap: unsupported map key type")
+	}
+	if t.key.size > maxKeySize && (!t.indirectkey || t.keysize != uint8(sys.PtrSize)) ||
+		t.key.size <= maxKeySize && (t.indirectkey || t.keysize != uint8(t.key.size)) {
+		throw("key size wrong")
+	}
+	if t.elem.size > maxValueSize && (!t.indirectvalue || t.valuesize != uint8(sys.PtrSize)) ||
+		t.elem.size <= maxValueSize && (t.indirectvalue || t.valuesize != uint8(t.elem.size)) {
+		throw("value size wrong")
+	}
+	if t.key.align > bucketCnt {
+		throw("key align too big")
+	}
+	if t.elem.align > bucketCnt {
+		throw("value align too big")
+	}
+	if t.key.size%uintptr(t.key.align) != 0 {
+		throw("key size not a multiple of key align")
+	}
+	if t.elem.size%uintptr(t.elem.align) != 0 {
+		throw("value size not a multiple of value align")
+	}
+	if bucketCnt < 8 {
+		throw("bucketsize too small for proper alignment")
+	}
+	if dataOffset%uintptr(t.key.align) != 0 {
+		throw("need padding in bucket (key)")
+	}
+	if dataOffset%uintptr(t.elem.align) != 0 {
+		throw("need padding in bucket (value)")
+	}
+
+	return makemap(t, cap, nil)
 }
 
 //go:linkname reflect_mapaccess reflect.mapaccess
@@ -1257,7 +1234,7 @@
 		return 0
 	}
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&h))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(reflect_maplen))
 	}
 	return h.count
diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go
index 67b9787..2de3814 100644
--- a/src/runtime/hashmap_fast.go
+++ b/src/runtime/hashmap_fast.go
@@ -11,7 +11,7 @@
 
 func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast32))
 	}
 	if h == nil || h.count == 0 {
@@ -26,7 +26,7 @@
 		b = (*bmap)(h.buckets)
 	} else {
 		hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
+		m := bucketMask(h.B)
 		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 		if c := h.oldbuckets; c != nil {
 			if !h.sameSizeGrow() {
@@ -39,28 +39,19 @@
 			}
 		}
 	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
-			if k != key {
-				continue
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+			if *(*uint32)(k) == key && b.tophash[i] != empty {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
 			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0])
 		}
 	}
+	return unsafe.Pointer(&zeroVal[0])
 }
 
 func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast32))
 	}
 	if h == nil || h.count == 0 {
@@ -75,7 +66,7 @@
 		b = (*bmap)(h.buckets)
 	} else {
 		hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
+		m := bucketMask(h.B)
 		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 		if c := h.oldbuckets; c != nil {
 			if !h.sameSizeGrow() {
@@ -88,28 +79,19 @@
 			}
 		}
 	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
-			if k != key {
-				continue
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+			if *(*uint32)(k) == key && b.tophash[i] != empty {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)), true
 			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[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(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0]), false
 		}
 	}
+	return unsafe.Pointer(&zeroVal[0]), false
 }
 
 func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
 	}
 	if h == nil || h.count == 0 {
@@ -124,7 +106,7 @@
 		b = (*bmap)(h.buckets)
 	} else {
 		hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
+		m := bucketMask(h.B)
 		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 		if c := h.oldbuckets; c != nil {
 			if !h.sameSizeGrow() {
@@ -137,28 +119,19 @@
 			}
 		}
 	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
-			if k != key {
-				continue
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+			if *(*uint64)(k) == key && b.tophash[i] != empty {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
 			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0])
 		}
 	}
+	return unsafe.Pointer(&zeroVal[0])
 }
 
 func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast64))
 	}
 	if h == nil || h.count == 0 {
@@ -173,7 +146,7 @@
 		b = (*bmap)(h.buckets)
 	} else {
 		hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
+		m := bucketMask(h.B)
 		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 		if c := h.oldbuckets; c != nil {
 			if !h.sameSizeGrow() {
@@ -186,28 +159,19 @@
 			}
 		}
 	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
-			if k != key {
-				continue
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+			if *(*uint64)(k) == key && b.tophash[i] != empty {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)), true
 			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[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(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0]), false
 		}
 	}
+	return unsafe.Pointer(&zeroVal[0]), false
 }
 
 func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_faststr))
 	}
 	if h == nil || h.count == 0 {
@@ -222,13 +186,9 @@
 		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.tophash[i] without the bounds check
-				if x == empty {
-					continue
-				}
-				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-				if k.len != key.len {
+			for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+				k := (*stringStruct)(kptr)
+				if k.len != key.len || b.tophash[i] == empty {
 					continue
 				}
 				if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
@@ -239,13 +199,9 @@
 		}
 		// 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.tophash[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-			if k.len != key.len {
+		for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+			k := (*stringStruct)(kptr)
+			if k.len != key.len || b.tophash[i] == empty {
 				continue
 			}
 			if k.str == key.str {
@@ -275,7 +231,7 @@
 	}
 dohash:
 	hash := t.key.alg.hash(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
+	m := bucketMask(h.B)
 	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
@@ -287,34 +243,24 @@
 			b = oldb
 		}
 	}
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[i] without the bounds check
-			if x != top {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-			if k.len != key.len {
+	top := tophash(hash)
+	for ; b != nil; b = b.overflow(t) {
+		for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+			k := (*stringStruct)(kptr)
+			if k.len != key.len || b.tophash[i] != top {
 				continue
 			}
 			if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
 				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*sys.PtrSize+i*uintptr(t.valuesize))
 			}
 		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0])
-		}
 	}
+	return unsafe.Pointer(&zeroVal[0])
 }
 
 func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_faststr))
 	}
 	if h == nil || h.count == 0 {
@@ -329,13 +275,9 @@
 		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.tophash[i] without the bounds check
-				if x == empty {
-					continue
-				}
-				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-				if k.len != key.len {
+			for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+				k := (*stringStruct)(kptr)
+				if k.len != key.len || b.tophash[i] == empty {
 					continue
 				}
 				if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
@@ -346,13 +288,9 @@
 		}
 		// 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.tophash[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-			if k.len != key.len {
+		for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+			k := (*stringStruct)(kptr)
+			if k.len != key.len || b.tophash[i] == empty {
 				continue
 			}
 			if k.str == key.str {
@@ -382,7 +320,7 @@
 	}
 dohash:
 	hash := t.key.alg.hash(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
+	m := bucketMask(h.B)
 	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
@@ -394,29 +332,19 @@
 			b = oldb
 		}
 	}
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.tophash[i] without the bounds check
-			if x != top {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-			if k.len != key.len {
+	top := tophash(hash)
+	for ; b != nil; b = b.overflow(t) {
+		for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+			k := (*stringStruct)(kptr)
+			if k.len != key.len || b.tophash[i] != top {
 				continue
 			}
 			if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
 				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*sys.PtrSize+i*uintptr(t.valuesize)), true
 			}
 		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(&zeroVal[0]), false
-		}
 	}
+	return unsafe.Pointer(&zeroVal[0]), false
 }
 
 func mapassign_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
@@ -424,7 +352,7 @@
 		panic(plainError("assignment to entry in nil map"))
 	}
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_fast32))
 	}
 	if h.flags&hashWriting != 0 {
@@ -436,30 +364,26 @@
 	h.flags |= hashWriting
 
 	if h.buckets == nil {
-		h.buckets = newarray(t.bucket, 1)
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
 	}
 
 again:
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_fast32(t, h, bucket)
 	}
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
 
-	var inserti *uint8
+	var insertb *bmap
+	var inserti uintptr
 	var insertk unsafe.Pointer
-	var val 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*4)
-					val = add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
+			if b.tophash[i] == empty {
+				if insertb == nil {
+					inserti = i
+					insertb = b
 				}
 				continue
 			}
@@ -467,7 +391,8 @@
 			if k != key {
 				continue
 			}
-			val = add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
+			inserti = i
+			insertb = b
 			goto done
 		}
 		ovf := b.overflow(t)
@@ -481,25 +406,112 @@
 
 	// If we hit the max load factor or we have too many overflow buckets,
 	// and we're not already in the middle of growing, start growing.
-	if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
 		hashGrow(t, h)
 		goto again // Growing the table invalidates everything, so try again
 	}
 
-	if inserti == nil {
+	if insertb == nil {
 		// all current buckets are full, allocate a new one.
-		newb := h.newoverflow(t, b)
-		inserti = &newb.tophash[0]
-		insertk = add(unsafe.Pointer(newb), dataOffset)
-		val = add(insertk, bucketCnt*4)
+		insertb = h.newoverflow(t, b)
+		inserti = 0 // not necessary, but avoids needlessly spilling inserti
 	}
+	insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
 
-	// store new key/value at insert position
-	typedmemmove(t.key, insertk, unsafe.Pointer(&key))
-	*inserti = top
+	insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
+	// store new key at insert position
+	*(*uint32)(insertk) = key
+
 	h.count++
 
 done:
+	val := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.valuesize))
+	if h.flags&hashWriting == 0 {
+		throw("concurrent map writes")
+	}
+	h.flags &^= hashWriting
+	return val
+}
+
+func mapassign_fast32ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+	if h == nil {
+		panic(plainError("assignment to entry in nil map"))
+	}
+	if raceenabled {
+		callerpc := getcallerpc()
+		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_fast32))
+	}
+	if h.flags&hashWriting != 0 {
+		throw("concurrent map writes")
+	}
+	hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+	// Set hashWriting after calling alg.hash for consistency with mapassign.
+	h.flags |= hashWriting
+
+	if h.buckets == nil {
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
+	}
+
+again:
+	bucket := hash & bucketMask(h.B)
+	if h.growing() {
+		growWork_fast32(t, h, bucket)
+	}
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
+
+	var insertb *bmap
+	var inserti uintptr
+	var insertk unsafe.Pointer
+
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] == empty {
+				if insertb == nil {
+					inserti = i
+					insertb = b
+				}
+				continue
+			}
+			k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*4)))
+			if k != key {
+				continue
+			}
+			inserti = i
+			insertb = b
+			goto done
+		}
+		ovf := b.overflow(t)
+		if ovf == nil {
+			break
+		}
+		b = ovf
+	}
+
+	// Did not find mapping for key. Allocate new cell & add entry.
+
+	// If we hit the max load factor or we have too many overflow buckets,
+	// and we're not already in the middle of growing, start growing.
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+		hashGrow(t, h)
+		goto again // Growing the table invalidates everything, so try again
+	}
+
+	if insertb == nil {
+		// all current buckets are full, allocate a new one.
+		insertb = h.newoverflow(t, b)
+		inserti = 0 // not necessary, but avoids needlessly spilling inserti
+	}
+	insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+	insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
+	// store new key at insert position
+	*(*unsafe.Pointer)(insertk) = key
+
+	h.count++
+
+done:
+	val := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.valuesize))
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
@@ -512,7 +524,7 @@
 		panic(plainError("assignment to entry in nil map"))
 	}
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_fast64))
 	}
 	if h.flags&hashWriting != 0 {
@@ -524,30 +536,26 @@
 	h.flags |= hashWriting
 
 	if h.buckets == nil {
-		h.buckets = newarray(t.bucket, 1)
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
 	}
 
 again:
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_fast64(t, h, bucket)
 	}
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
 
-	var inserti *uint8
+	var insertb *bmap
+	var inserti uintptr
 	var insertk unsafe.Pointer
-	var val 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*8)
-					val = add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
+			if b.tophash[i] == empty {
+				if insertb == nil {
+					insertb = b
+					inserti = i
 				}
 				continue
 			}
@@ -555,7 +563,8 @@
 			if k != key {
 				continue
 			}
-			val = add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
+			insertb = b
+			inserti = i
 			goto done
 		}
 		ovf := b.overflow(t)
@@ -569,25 +578,26 @@
 
 	// If we hit the max load factor or we have too many overflow buckets,
 	// and we're not already in the middle of growing, start growing.
-	if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
 		hashGrow(t, h)
 		goto again // Growing the table invalidates everything, so try again
 	}
 
-	if inserti == nil {
+	if insertb == nil {
 		// all current buckets are full, allocate a new one.
-		newb := h.newoverflow(t, b)
-		inserti = &newb.tophash[0]
-		insertk = add(unsafe.Pointer(newb), dataOffset)
-		val = add(insertk, bucketCnt*8)
+		insertb = h.newoverflow(t, b)
+		inserti = 0 // not necessary, but avoids needlessly spilling inserti
 	}
+	insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
 
-	// store new key/value at insert position
-	typedmemmove(t.key, insertk, unsafe.Pointer(&key))
-	*inserti = top
+	insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
+	// store new key at insert position
+	*(*uint64)(insertk) = key
+
 	h.count++
 
 done:
+	val := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.valuesize))
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
@@ -595,48 +605,131 @@
 	return val
 }
 
-func mapassign_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
+func mapassign_fast64ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
 	if h == nil {
 		panic(plainError("assignment to entry in nil map"))
 	}
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_faststr))
+		callerpc := getcallerpc()
+		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_fast64))
 	}
 	if h.flags&hashWriting != 0 {
 		throw("concurrent map writes")
 	}
-	key := stringStructOf(&ky)
-	hash := t.key.alg.hash(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
+	hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
 
 	// Set hashWriting after calling alg.hash for consistency with mapassign.
 	h.flags |= hashWriting
 
 	if h.buckets == nil {
-		h.buckets = newarray(t.bucket, 1)
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
 	}
 
 again:
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_fast64(t, h, bucket)
 	}
 	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
+
+	var insertb *bmap
+	var inserti uintptr
+	var insertk unsafe.Pointer
+
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] == empty {
+				if insertb == nil {
+					insertb = b
+					inserti = i
+				}
+				continue
+			}
+			k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*8)))
+			if k != key {
+				continue
+			}
+			insertb = b
+			inserti = i
+			goto done
+		}
+		ovf := b.overflow(t)
+		if ovf == nil {
+			break
+		}
+		b = ovf
 	}
 
-	var inserti *uint8
+	// Did not find mapping for key. Allocate new cell & add entry.
+
+	// If we hit the max load factor or we have too many overflow buckets,
+	// and we're not already in the middle of growing, start growing.
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+		hashGrow(t, h)
+		goto again // Growing the table invalidates everything, so try again
+	}
+
+	if insertb == nil {
+		// all current buckets are full, allocate a new one.
+		insertb = h.newoverflow(t, b)
+		inserti = 0 // not necessary, but avoids needlessly spilling inserti
+	}
+	insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+	insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
+	// store new key at insert position
+	*(*unsafe.Pointer)(insertk) = key
+
+	h.count++
+
+done:
+	val := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.valuesize))
+	if h.flags&hashWriting == 0 {
+		throw("concurrent map writes")
+	}
+	h.flags &^= hashWriting
+	return val
+}
+
+func mapassign_faststr(t *maptype, h *hmap, s string) unsafe.Pointer {
+	if h == nil {
+		panic(plainError("assignment to entry in nil map"))
+	}
+	if raceenabled {
+		callerpc := getcallerpc()
+		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapassign_faststr))
+	}
+	if h.flags&hashWriting != 0 {
+		throw("concurrent map writes")
+	}
+	key := stringStructOf(&s)
+	hash := t.key.alg.hash(noescape(unsafe.Pointer(&s)), uintptr(h.hash0))
+
+	// Set hashWriting after calling alg.hash for consistency with mapassign.
+	h.flags |= hashWriting
+
+	if h.buckets == nil {
+		h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
+	}
+
+again:
+	bucket := hash & bucketMask(h.B)
+	if h.growing() {
+		growWork_faststr(t, h, bucket)
+	}
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
+	top := tophash(hash)
+
+	var insertb *bmap
+	var inserti uintptr
 	var insertk unsafe.Pointer
-	var val 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))
-					val = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				if b.tophash[i] == empty && insertb == nil {
+					insertb = b
+					inserti = i
 				}
 				continue
 			}
@@ -648,7 +741,8 @@
 				continue
 			}
 			// already have a mapping for key. Update it.
-			val = add(unsafe.Pointer(b), dataOffset+bucketCnt*2*sys.PtrSize+i*uintptr(t.valuesize))
+			inserti = i
+			insertb = b
 			goto done
 		}
 		ovf := b.overflow(t)
@@ -662,25 +756,25 @@
 
 	// If we hit the max load factor or we have too many overflow buckets,
 	// and we're not already in the middle of growing, start growing.
-	if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+	if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
 		hashGrow(t, h)
 		goto again // Growing the table invalidates everything, so try again
 	}
 
-	if inserti == nil {
+	if insertb == nil {
 		// all current buckets are full, allocate a new one.
-		newb := h.newoverflow(t, b)
-		inserti = &newb.tophash[0]
-		insertk = add(unsafe.Pointer(newb), dataOffset)
-		val = add(insertk, bucketCnt*2*sys.PtrSize)
+		insertb = h.newoverflow(t, b)
+		inserti = 0 // not necessary, but avoids needlessly spilling inserti
 	}
+	insertb.tophash[inserti&(bucketCnt-1)] = top // mask inserti to avoid bounds checks
 
-	// store new key/value at insert position
+	insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*2*sys.PtrSize)
+	// store new key at insert position
 	*((*stringStruct)(insertk)) = *key
-	*inserti = top
 	h.count++
 
 done:
+	val := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*2*sys.PtrSize+inserti*uintptr(t.valuesize))
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
@@ -690,7 +784,7 @@
 
 func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapdelete_fast32))
 	}
 	if h == nil || h.count == 0 {
@@ -705,38 +799,32 @@
 	// Set hashWriting after calling alg.hash for consistency with mapdelete
 	h.flags |= hashWriting
 
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_fast32(t, h, bucket)
 	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
+	b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
+search:
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+			if key != *(*uint32)(k) || b.tophash[i] == empty {
 				continue
 			}
-			k := (*uint32)(add(unsafe.Pointer(b), dataOffset+i*4))
-			if key != *k {
-				continue
+			// Only clear key if there are pointers in it.
+			if t.key.kind&kindNoPointers == 0 {
+				memclrHasPointers(k, t.key.size)
 			}
-			typedmemclr(t.key, unsafe.Pointer(k))
-			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*4 + i*uintptr(t.valuesize))
-			typedmemclr(t.elem, v)
+			// Only clear value if there are pointers in it.
+			if t.elem.kind&kindNoPointers == 0 {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
+				memclrHasPointers(v, t.elem.size)
+			}
 			b.tophash[i] = empty
 			h.count--
-			goto done
-		}
-		b = b.overflow(t)
-		if b == nil {
-			goto done
+			break search
 		}
 	}
 
-done:
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
@@ -745,7 +833,7 @@
 
 func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapdelete_fast64))
 	}
 	if h == nil || h.count == 0 {
@@ -760,38 +848,32 @@
 	// Set hashWriting after calling alg.hash for consistency with mapdelete
 	h.flags |= hashWriting
 
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_fast64(t, h, bucket)
 	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
+	b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
+search:
+	for ; b != nil; b = b.overflow(t) {
+		for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+			if key != *(*uint64)(k) || b.tophash[i] == empty {
 				continue
 			}
-			k := (*uint64)(add(unsafe.Pointer(b), dataOffset+i*8))
-			if key != *k {
-				continue
+			// Only clear key if there are pointers in it.
+			if t.key.kind&kindNoPointers == 0 {
+				memclrHasPointers(k, t.key.size)
 			}
-			typedmemclr(t.key, unsafe.Pointer(k))
-			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*8 + i*uintptr(t.valuesize))
-			typedmemclr(t.elem, v)
+			// Only clear value if there are pointers in it.
+			if t.elem.kind&kindNoPointers == 0 {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
+				memclrHasPointers(v, t.elem.size)
+			}
 			b.tophash[i] = empty
 			h.count--
-			goto done
-		}
-		b = b.overflow(t)
-		if b == nil {
-			goto done
+			break search
 		}
 	}
 
-done:
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
@@ -800,7 +882,7 @@
 
 func mapdelete_faststr(t *maptype, h *hmap, ky string) {
 	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
+		callerpc := getcallerpc()
 		racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapdelete_faststr))
 	}
 	if h == nil || h.count == 0 {
@@ -816,43 +898,340 @@
 	// Set hashWriting after calling alg.hash for consistency with mapdelete
 	h.flags |= hashWriting
 
-	bucket := hash & (uintptr(1)<<h.B - 1)
+	bucket := hash & bucketMask(h.B)
 	if h.growing() {
-		growWork(t, h, bucket)
+		growWork_faststr(t, h, bucket)
 	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (sys.PtrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
-			if k.len != key.len {
+	b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
+	top := tophash(hash)
+search:
+	for ; b != nil; b = b.overflow(t) {
+		for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
+			k := (*stringStruct)(kptr)
+			if k.len != key.len || b.tophash[i] != top {
 				continue
 			}
 			if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
 				continue
 			}
-			typedmemclr(t.key, unsafe.Pointer(k))
-			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*2*sys.PtrSize + i*uintptr(t.valuesize))
-			typedmemclr(t.elem, v)
+			// Clear key's pointer.
+			k.str = nil
+			// Only clear value if there are pointers in it.
+			if t.elem.kind&kindNoPointers == 0 {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*2*sys.PtrSize+i*uintptr(t.valuesize))
+				memclrHasPointers(v, t.elem.size)
+			}
 			b.tophash[i] = empty
 			h.count--
-			goto done
-		}
-		b = b.overflow(t)
-		if b == nil {
-			goto done
+			break search
 		}
 	}
 
-done:
 	if h.flags&hashWriting == 0 {
 		throw("concurrent map writes")
 	}
 	h.flags &^= hashWriting
 }
+
+func growWork_fast32(t *maptype, h *hmap, bucket uintptr) {
+	// make sure we evacuate the oldbucket corresponding
+	// to the bucket we're about to use
+	evacuate_fast32(t, h, bucket&h.oldbucketmask())
+
+	// evacuate one more oldbucket to make progress on growing
+	if h.growing() {
+		evacuate_fast32(t, h, h.nevacuate)
+	}
+}
+
+func evacuate_fast32(t *maptype, h *hmap, oldbucket uintptr) {
+	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+	newbit := h.noldbuckets()
+	if !evacuated(b) {
+		// TODO: reuse overflow buckets instead of using new ones, if there
+		// is no iterator using the old buckets.  (If !oldIterator.)
+
+		// xy contains the x and y (low and high) evacuation destinations.
+		var xy [2]evacDst
+		x := &xy[0]
+		x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
+		x.k = add(unsafe.Pointer(x.b), dataOffset)
+		x.v = add(x.k, bucketCnt*4)
+
+		if !h.sameSizeGrow() {
+			// Only calculate y pointers if we're growing bigger.
+			// Otherwise GC can see bad pointers.
+			y := &xy[1]
+			y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
+			y.k = add(unsafe.Pointer(y.b), dataOffset)
+			y.v = add(y.k, bucketCnt*4)
+		}
+
+		for ; b != nil; b = b.overflow(t) {
+			k := add(unsafe.Pointer(b), dataOffset)
+			v := add(k, bucketCnt*4)
+			for i := 0; i < bucketCnt; i, k, v = i+1, add(k, 4), add(v, uintptr(t.valuesize)) {
+				top := b.tophash[i]
+				if top == empty {
+					b.tophash[i] = evacuatedEmpty
+					continue
+				}
+				if top < minTopHash {
+					throw("bad map state")
+				}
+				var useY uint8
+				if !h.sameSizeGrow() {
+					// Compute hash to make our evacuation decision (whether we need
+					// to send this key/value to bucket x or bucket y).
+					hash := t.key.alg.hash(k, uintptr(h.hash0))
+					if hash&newbit != 0 {
+						useY = 1
+					}
+				}
+
+				b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+				dst := &xy[useY]                 // evacuation destination
+
+				if dst.i == bucketCnt {
+					dst.b = h.newoverflow(t, dst.b)
+					dst.i = 0
+					dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+					dst.v = add(dst.k, bucketCnt*4)
+				}
+				dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+				// Copy key.
+				if sys.PtrSize == 4 && t.key.kind&kindNoPointers == 0 && writeBarrier.enabled {
+					writebarrierptr((*uintptr)(dst.k), *(*uintptr)(k))
+				} else {
+					*(*uint32)(dst.k) = *(*uint32)(k)
+				}
+
+				typedmemmove(t.elem, dst.v, v)
+				dst.i++
+				// These updates might push these pointers past the end of the
+				// key or value arrays.  That's ok, as we have the overflow pointer
+				// at the end of the bucket to protect against pointing past the
+				// end of the bucket.
+				dst.k = add(dst.k, 4)
+				dst.v = add(dst.v, uintptr(t.valuesize))
+			}
+		}
+		// Unlink the overflow buckets & clear key/value to help GC.
+		if h.flags&oldIterator == 0 && t.bucket.kind&kindNoPointers == 0 {
+			b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
+			// Preserve b.tophash because the evacuation
+			// state is maintained there.
+			ptr := add(b, dataOffset)
+			n := uintptr(t.bucketsize) - dataOffset
+			memclrHasPointers(ptr, n)
+		}
+	}
+
+	if oldbucket == h.nevacuate {
+		advanceEvacuationMark(h, t, newbit)
+	}
+}
+
+func growWork_fast64(t *maptype, h *hmap, bucket uintptr) {
+	// make sure we evacuate the oldbucket corresponding
+	// to the bucket we're about to use
+	evacuate_fast64(t, h, bucket&h.oldbucketmask())
+
+	// evacuate one more oldbucket to make progress on growing
+	if h.growing() {
+		evacuate_fast64(t, h, h.nevacuate)
+	}
+}
+
+func evacuate_fast64(t *maptype, h *hmap, oldbucket uintptr) {
+	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+	newbit := h.noldbuckets()
+	if !evacuated(b) {
+		// TODO: reuse overflow buckets instead of using new ones, if there
+		// is no iterator using the old buckets.  (If !oldIterator.)
+
+		// xy contains the x and y (low and high) evacuation destinations.
+		var xy [2]evacDst
+		x := &xy[0]
+		x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
+		x.k = add(unsafe.Pointer(x.b), dataOffset)
+		x.v = add(x.k, bucketCnt*8)
+
+		if !h.sameSizeGrow() {
+			// Only calculate y pointers if we're growing bigger.
+			// Otherwise GC can see bad pointers.
+			y := &xy[1]
+			y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
+			y.k = add(unsafe.Pointer(y.b), dataOffset)
+			y.v = add(y.k, bucketCnt*8)
+		}
+
+		for ; b != nil; b = b.overflow(t) {
+			k := add(unsafe.Pointer(b), dataOffset)
+			v := add(k, bucketCnt*8)
+			for i := 0; i < bucketCnt; i, k, v = i+1, add(k, 8), add(v, uintptr(t.valuesize)) {
+				top := b.tophash[i]
+				if top == empty {
+					b.tophash[i] = evacuatedEmpty
+					continue
+				}
+				if top < minTopHash {
+					throw("bad map state")
+				}
+				var useY uint8
+				if !h.sameSizeGrow() {
+					// Compute hash to make our evacuation decision (whether we need
+					// to send this key/value to bucket x or bucket y).
+					hash := t.key.alg.hash(k, uintptr(h.hash0))
+					if hash&newbit != 0 {
+						useY = 1
+					}
+				}
+
+				b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+				dst := &xy[useY]                 // evacuation destination
+
+				if dst.i == bucketCnt {
+					dst.b = h.newoverflow(t, dst.b)
+					dst.i = 0
+					dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+					dst.v = add(dst.k, bucketCnt*8)
+				}
+				dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+				// Copy key.
+				if t.key.kind&kindNoPointers == 0 && writeBarrier.enabled {
+					if sys.PtrSize == 8 {
+						writebarrierptr((*uintptr)(dst.k), *(*uintptr)(k))
+					} else {
+						// There are three ways to squeeze at least one 32 bit pointer into 64 bits.
+						// Give up and call typedmemmove.
+						typedmemmove(t.key, dst.k, k)
+					}
+				} else {
+					*(*uint64)(dst.k) = *(*uint64)(k)
+				}
+
+				typedmemmove(t.elem, dst.v, v)
+				dst.i++
+				// These updates might push these pointers past the end of the
+				// key or value arrays.  That's ok, as we have the overflow pointer
+				// at the end of the bucket to protect against pointing past the
+				// end of the bucket.
+				dst.k = add(dst.k, 8)
+				dst.v = add(dst.v, uintptr(t.valuesize))
+			}
+		}
+		// Unlink the overflow buckets & clear key/value to help GC.
+		if h.flags&oldIterator == 0 && t.bucket.kind&kindNoPointers == 0 {
+			b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
+			// Preserve b.tophash because the evacuation
+			// state is maintained there.
+			ptr := add(b, dataOffset)
+			n := uintptr(t.bucketsize) - dataOffset
+			memclrHasPointers(ptr, n)
+		}
+	}
+
+	if oldbucket == h.nevacuate {
+		advanceEvacuationMark(h, t, newbit)
+	}
+}
+
+func growWork_faststr(t *maptype, h *hmap, bucket uintptr) {
+	// make sure we evacuate the oldbucket corresponding
+	// to the bucket we're about to use
+	evacuate_faststr(t, h, bucket&h.oldbucketmask())
+
+	// evacuate one more oldbucket to make progress on growing
+	if h.growing() {
+		evacuate_faststr(t, h, h.nevacuate)
+	}
+}
+
+func evacuate_faststr(t *maptype, h *hmap, oldbucket uintptr) {
+	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+	newbit := h.noldbuckets()
+	if !evacuated(b) {
+		// TODO: reuse overflow buckets instead of using new ones, if there
+		// is no iterator using the old buckets.  (If !oldIterator.)
+
+		// xy contains the x and y (low and high) evacuation destinations.
+		var xy [2]evacDst
+		x := &xy[0]
+		x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
+		x.k = add(unsafe.Pointer(x.b), dataOffset)
+		x.v = add(x.k, bucketCnt*2*sys.PtrSize)
+
+		if !h.sameSizeGrow() {
+			// Only calculate y pointers if we're growing bigger.
+			// Otherwise GC can see bad pointers.
+			y := &xy[1]
+			y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
+			y.k = add(unsafe.Pointer(y.b), dataOffset)
+			y.v = add(y.k, bucketCnt*2*sys.PtrSize)
+		}
+
+		for ; b != nil; b = b.overflow(t) {
+			k := add(unsafe.Pointer(b), dataOffset)
+			v := add(k, bucketCnt*2*sys.PtrSize)
+			for i := 0; i < bucketCnt; i, k, v = i+1, add(k, 2*sys.PtrSize), add(v, uintptr(t.valuesize)) {
+				top := b.tophash[i]
+				if top == empty {
+					b.tophash[i] = evacuatedEmpty
+					continue
+				}
+				if top < minTopHash {
+					throw("bad map state")
+				}
+				var useY uint8
+				if !h.sameSizeGrow() {
+					// Compute hash to make our evacuation decision (whether we need
+					// to send this key/value to bucket x or bucket y).
+					hash := t.key.alg.hash(k, uintptr(h.hash0))
+					if hash&newbit != 0 {
+						useY = 1
+					}
+				}
+
+				b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+				dst := &xy[useY]                 // evacuation destination
+
+				if dst.i == bucketCnt {
+					dst.b = h.newoverflow(t, dst.b)
+					dst.i = 0
+					dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+					dst.v = add(dst.k, bucketCnt*2*sys.PtrSize)
+				}
+				dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+				// Copy key.
+				*(*string)(dst.k) = *(*string)(k)
+
+				typedmemmove(t.elem, dst.v, v)
+				dst.i++
+				// These updates might push these pointers past the end of the
+				// key or value arrays.  That's ok, as we have the overflow pointer
+				// at the end of the bucket to protect against pointing past the
+				// end of the bucket.
+				dst.k = add(dst.k, 2*sys.PtrSize)
+				dst.v = add(dst.v, uintptr(t.valuesize))
+			}
+		}
+		// Unlink the overflow buckets & clear key/value to help GC.
+		// Unlink the overflow buckets & clear key/value to help GC.
+		if h.flags&oldIterator == 0 && t.bucket.kind&kindNoPointers == 0 {
+			b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
+			// Preserve b.tophash because the evacuation
+			// state is maintained there.
+			ptr := add(b, dataOffset)
+			n := uintptr(t.bucketsize) - dataOffset
+			memclrHasPointers(ptr, n)
+		}
+	}
+
+	if oldbucket == h.nevacuate {
+		advanceEvacuationMark(h, t, newbit)
+	}
+}
diff --git a/src/runtime/heapdump.go b/src/runtime/heapdump.go
index 35f6124..2b51758 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -200,7 +200,6 @@
 
 // dump an object
 func dumpobj(obj unsafe.Pointer, size uintptr, bv bitvector) {
-	dumpbvtypes(&bv, obj)
 	dumpint(tagObject)
 	dumpint(uint64(uintptr(obj)))
 	dumpmemrange(obj, size)
@@ -261,14 +260,9 @@
 	}
 	stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
 
-	// Dump any types we will need to resolve Efaces.
-	if child.args.n >= 0 {
-		dumpbvtypes(&child.args, unsafe.Pointer(s.sp+child.argoff))
-	}
 	var bv bitvector
 	if stkmap != nil && stkmap.n > 0 {
 		bv = stackmapdata(stkmap, pcdata)
-		dumpbvtypes(&bv, unsafe.Pointer(s.varp-uintptr(bv.n*sys.PtrSize)))
 	} else {
 		bv.n = -1
 	}
@@ -423,14 +417,12 @@
 func dumproots() {
 	// TODO(mwhudson): dump datamask etc from all objects
 	// data segment
-	dumpbvtypes(&firstmoduledata.gcdatamask, unsafe.Pointer(firstmoduledata.data))
 	dumpint(tagData)
 	dumpint(uint64(firstmoduledata.data))
 	dumpmemrange(unsafe.Pointer(firstmoduledata.data), firstmoduledata.edata-firstmoduledata.data)
 	dumpfields(firstmoduledata.gcdatamask)
 
 	// bss segment
-	dumpbvtypes(&firstmoduledata.gcbssmask, unsafe.Pointer(firstmoduledata.bss))
 	dumpint(tagBSS)
 	dumpint(uint64(firstmoduledata.bss))
 	dumpmemrange(unsafe.Pointer(firstmoduledata.bss), firstmoduledata.ebss-firstmoduledata.bss)
@@ -677,16 +669,6 @@
 	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.
-// TODO(rsc, khr): Delete - no longer possible.
-
-// Dump all the types that appear in the type field of
-// any Eface described by this bit vector.
-func dumpbvtypes(bv *bitvector, base unsafe.Pointer) {
-}
-
 func makeheapobjbv(p uintptr, size uintptr) bitvector {
 	// Extend the temp buffer if necessary.
 	nptr := size / sys.PtrSize
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
index 58ed61e..7c5d3a0 100644
--- a/src/runtime/iface.go
+++ b/src/runtime/iface.go
@@ -10,21 +10,24 @@
 	"unsafe"
 )
 
-const (
-	hashSize = 1009
-)
+const itabInitSize = 512
 
 var (
-	ifaceLock mutex // lock for accessing hash
-	hash      [hashSize]*itab
+	itabLock      mutex                               // lock for accessing itab table
+	itabTable     = &itabTableInit                    // pointer to current table
+	itabTableInit = itabTableType{size: itabInitSize} // starter table
 )
 
-func itabhash(inter *interfacetype, typ *_type) uint32 {
+//Note: change the formula in the mallocgc call in itabAdd if you change these fields.
+type itabTableType struct {
+	size    uintptr             // length of entries array. Always a power of 2.
+	count   uintptr             // current number of filled entries.
+	entries [itabInitSize]*itab // really [size] large
+}
+
+func itabHashFunc(inter *interfacetype, typ *_type) uintptr {
 	// compiler has provided some good hash codes for us.
-	h := inter.typ.hash
-	h += 17 * typ.hash
-	// TODO(rsc): h += 23 * x.mhash ?
-	return h % hashSize
+	return uintptr(inter.typ.hash ^ typ.hash)
 }
 
 func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
@@ -41,50 +44,137 @@
 		panic(&TypeAssertionError{"", typ.string(), inter.typ.string(), name.name()})
 	}
 
-	h := itabhash(inter, typ)
-
-	// 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)(atomic.Loadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link {
-			if m.inter == inter && m._type == typ {
-				if m.bad {
-					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 try
-						// adding the itab again, which will throw an error.
-						additab(m, locked != 0, false)
-					}
-					m = nil
-				}
-				if locked != 0 {
-					unlock(&ifaceLock)
-				}
-				return m
-			}
-		}
+
+	// First, look in the existing table to see if we can find the itab we need.
+	// This is by far the most common case, so do it without locks.
+	// Use atomic to ensure we see any previous writes done by the thread
+	// that updates the itabTable field (with atomic.Storep in itabAdd).
+	t := (*itabTableType)(atomic.Loadp(unsafe.Pointer(&itabTable)))
+	if m = t.find(inter, typ); m != nil {
+		goto finish
 	}
 
+	// Not found.  Grab the lock and try again.
+	lock(&itabLock)
+	if m = itabTable.find(inter, typ); m != nil {
+		unlock(&itabLock)
+		goto finish
+	}
+
+	// Entry doesn't exist yet. Make a new entry & add it.
 	m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
 	m.inter = inter
 	m._type = typ
-	additab(m, true, canfail)
-	unlock(&ifaceLock)
-	if m.bad {
+	m.init()
+	itabAdd(m)
+	unlock(&itabLock)
+finish:
+	if m.fun[0] != 0 {
+		return m
+	}
+	if canfail {
 		return nil
 	}
-	return m
+	// 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 initialize
+	// the itab again to get the missing function name.
+	panic(&TypeAssertionError{concreteString: typ.string(), assertedString: inter.typ.string(), missingMethod: m.init()})
 }
 
-func additab(m *itab, locked, canfail bool) {
+// find finds the given interface/type pair in t.
+// Returns nil if the given interface/type pair isn't present.
+func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
+	// Implemented using quadratic probing.
+	// Probe sequence is h(i) = h0 + i*(i+1)/2 mod 2^k.
+	// We're guaranteed to hit all table entries using this probe sequence.
+	mask := t.size - 1
+	h := itabHashFunc(inter, typ) & mask
+	for i := uintptr(1); ; i++ {
+		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
+		// Use atomic read here so if we see m != nil, we also see
+		// the initializations of the fields of m.
+		// m := *p
+		m := (*itab)(atomic.Loadp(unsafe.Pointer(p)))
+		if m == nil {
+			return nil
+		}
+		if m.inter == inter && m._type == typ {
+			return m
+		}
+		h += i
+		h &= mask
+	}
+}
+
+// itabAdd adds the given itab to the itab hash table.
+// itabLock must be held.
+func itabAdd(m *itab) {
+	t := itabTable
+	if t.count >= 3*(t.size/4) { // 75% load factor
+		// Grow hash table.
+		// t2 = new(itabTableType) + some additional entries
+		// We lie and tell malloc we want pointer-free memory because
+		// all the pointed-to values are not in the heap.
+		t2 := (*itabTableType)(mallocgc((2+2*t.size)*sys.PtrSize, nil, true))
+		t2.size = t.size * 2
+
+		// Copy over entries.
+		// Note: while copying, other threads may look for an itab and
+		// fail to find it. That's ok, they will then try to get the itab lock
+		// and as a consequence wait until this copying is complete.
+		iterate_itabs(t2.add)
+		if t2.count != t.count {
+			throw("mismatched count during itab table copy")
+		}
+		// Publish new hash table. Use an atomic write: see comment in getitab.
+		atomicstorep(unsafe.Pointer(&itabTable), unsafe.Pointer(t2))
+		// Adopt the new table as our own.
+		t = itabTable
+		// Note: the old table can be GC'ed here.
+	}
+	t.add(m)
+}
+
+// add adds the given itab to itab table t.
+// itabLock must be held.
+func (t *itabTableType) add(m *itab) {
+	// See comment in find about the probe sequence.
+	// Insert new itab in the first empty spot in the probe sequence.
+	mask := t.size - 1
+	h := itabHashFunc(m.inter, m._type) & mask
+	for i := uintptr(1); ; i++ {
+		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
+		m2 := *p
+		if m2 == m {
+			// A given itab may be used in more than one module
+			// and thanks to the way global symbol resolution works, the
+			// pointed-to itab may already have been inserted into the
+			// global 'hash'.
+			return
+		}
+		if m2 == nil {
+			// Use atomic write here so if a reader sees m, it also
+			// sees the correctly initialized fields of m.
+			// NoWB is ok because m is not in heap memory.
+			// *p = m
+			atomic.StorepNoWB(unsafe.Pointer(p), unsafe.Pointer(m))
+			t.count++
+			return
+		}
+		h += i
+		h &= mask
+	}
+}
+
+// init fills in the m.fun array with all the code pointers for
+// the m.inter/m._type pair. If the type does not implement the interface,
+// it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
+// It is ok to call this multiple times on the same m, even concurrently.
+func (m *itab) init() string {
 	inter := m.inter
 	typ := m._type
 	x := typ.uncommon()
@@ -97,6 +187,7 @@
 	nt := int(x.mcount)
 	xmhdr := (*[1 << 16]method)(add(unsafe.Pointer(x), uintptr(x.moff)))[:nt:nt]
 	j := 0
+imethods:
 	for k := 0; k < ni; k++ {
 		i := &inter.mhdr[k]
 		itype := inter.typ.typeOff(i.ityp)
@@ -119,45 +210,26 @@
 						ifn := typ.textOff(t.ifn)
 						*(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[0]), uintptr(k)*sys.PtrSize)) = ifn
 					}
-					goto nextimethod
+					continue imethods
 				}
 			}
 		}
 		// didn't find method
-		if !canfail {
-			if locked {
-				unlock(&ifaceLock)
-			}
-			panic(&TypeAssertionError{"", typ.string(), inter.typ.string(), iname})
-		}
-		m.bad = true
-		break
-	nextimethod:
+		m.fun[0] = 0
+		return iname
 	}
-	if !locked {
-		throw("invalid itab locking")
-	}
-	h := itabhash(inter, typ)
-	m.link = hash[h]
-	m.inhash = true
-	atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
+	m.hash = typ.hash
+	return ""
 }
 
 func itabsinit() {
-	lock(&ifaceLock)
+	lock(&itabLock)
 	for _, md := range activeModules() {
 		for _, i := range md.itablinks {
-			// itablinks is a slice of pointers to the itabs used in this
-			// module. A given itab may be used in more than one module
-			// and thanks to the way global symbol resolution works, the
-			// pointed-to itab may already have been inserted into the
-			// global 'hash'.
-			if !i.inhash {
-				additab(i, true, false)
-			}
+			itabAdd(i)
 		}
 	}
-	unlock(&ifaceLock)
+	unlock(&itabLock)
 }
 
 // panicdottypeE is called when doing an e.(T) conversion and the conversion fails.
@@ -200,7 +272,7 @@
 
 func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -216,7 +288,7 @@
 
 func convT2E16(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E16))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E16))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -235,7 +307,7 @@
 
 func convT2E32(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E32))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E32))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -254,7 +326,7 @@
 
 func convT2E64(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E64))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E64))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -273,7 +345,7 @@
 
 func convT2Estring(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2Estring))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Estring))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -292,7 +364,7 @@
 
 func convT2Eslice(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2Eslice))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Eslice))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -311,7 +383,7 @@
 
 func convT2Enoptr(t *_type, elem unsafe.Pointer) (e eface) {
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2Enoptr))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Enoptr))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -326,7 +398,7 @@
 func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -341,7 +413,7 @@
 func convT2I16(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I16))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I16))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -361,7 +433,7 @@
 func convT2I32(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I32))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I32))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -381,7 +453,7 @@
 func convT2I64(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I64))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I64))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -401,7 +473,7 @@
 func convT2Istring(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2Istring))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Istring))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -421,7 +493,7 @@
 func convT2Islice(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2Islice))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Islice))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -441,7 +513,7 @@
 func convT2Inoptr(tab *itab, elem unsafe.Pointer) (i iface) {
 	t := tab._type
 	if raceenabled {
-		raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2Inoptr))
+		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Inoptr))
 	}
 	if msanenabled {
 		msanread(elem, t.size)
@@ -533,9 +605,13 @@
 }
 
 func iterate_itabs(fn func(*itab)) {
-	for _, h := range &hash {
-		for ; h != nil; h = h.link {
-			fn(h)
+	// Note: only runs during stop the world or with itabLock held,
+	// so no other locks/atomics needed.
+	t := itabTable
+	for i := uintptr(0); i < t.size; i++ {
+		m := *(**itab)(add(unsafe.Pointer(&t.entries), i*sys.PtrSize))
+		if m != nil {
+			fn(m)
 		}
 	}
 }
diff --git a/src/runtime/internal/atomic/atomic_test.go b/src/runtime/internal/atomic/atomic_test.go
index 879a82f..b697aa8 100644
--- a/src/runtime/internal/atomic/atomic_test.go
+++ b/src/runtime/internal/atomic/atomic_test.go
@@ -52,7 +52,7 @@
 // Tests that xadduintptr correctly updates 64-bit values. The place where
 // we actually do so is mstats.go, functions mSysStat{Inc,Dec}.
 func TestXadduintptrOnUint64(t *testing.T) {
-	if sys.BigEndian != 0 {
+	if sys.BigEndian {
 		// On big endian architectures, we never use xadduintptr to update
 		// 64-bit values and hence we skip the test.  (Note that functions
 		// mSysStat{Inc,Dec} in mstats.go have explicit checks for
diff --git a/src/runtime/internal/sys/arch_386.go b/src/runtime/internal/sys/arch_386.go
index 61d6722..5fb1fba 100644
--- a/src/runtime/internal/sys/arch_386.go
+++ b/src/runtime/internal/sys/arch_386.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = I386
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 64
 	DefaultPhysPageSize = GoosNacl*65536 + (1-GoosNacl)*4096 // 4k normally; 64k on NaCl
 	PCQuantum           = 1
diff --git a/src/runtime/internal/sys/arch_amd64.go b/src/runtime/internal/sys/arch_amd64.go
index 1f2114a..2f32bc4 100644
--- a/src/runtime/internal/sys/arch_amd64.go
+++ b/src/runtime/internal/sys/arch_amd64.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = AMD64
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 64
 	DefaultPhysPageSize = 4096
 	PCQuantum           = 1
diff --git a/src/runtime/internal/sys/arch_amd64p32.go b/src/runtime/internal/sys/arch_amd64p32.go
index 0779855..c560907 100644
--- a/src/runtime/internal/sys/arch_amd64p32.go
+++ b/src/runtime/internal/sys/arch_amd64p32.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = AMD64
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 64
 	DefaultPhysPageSize = 65536*GoosNacl + 4096*(1-GoosNacl)
 	PCQuantum           = 1
diff --git a/src/runtime/internal/sys/arch_arm.go b/src/runtime/internal/sys/arch_arm.go
index 899010b..f383d82 100644
--- a/src/runtime/internal/sys/arch_arm.go
+++ b/src/runtime/internal/sys/arch_arm.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = ARM
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 32
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_arm64.go b/src/runtime/internal/sys/arch_arm64.go
index 2d57dda..cb83ecc 100644
--- a/src/runtime/internal/sys/arch_arm64.go
+++ b/src/runtime/internal/sys/arch_arm64.go
@@ -6,8 +6,8 @@
 
 const (
 	ArchFamily          = ARM64
-	BigEndian           = 0
-	CacheLineSize       = 32
+	BigEndian           = false
+	CacheLineSize       = 64
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
 	Int64Align          = 8
diff --git a/src/runtime/internal/sys/arch_mips.go b/src/runtime/internal/sys/arch_mips.go
index 65fc4f8..e12f32d 100644
--- a/src/runtime/internal/sys/arch_mips.go
+++ b/src/runtime/internal/sys/arch_mips.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = MIPS
-	BigEndian           = 1
+	BigEndian           = true
 	CacheLineSize       = 32
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_mips64.go b/src/runtime/internal/sys/arch_mips64.go
index 0f6de74..973ec10 100644
--- a/src/runtime/internal/sys/arch_mips64.go
+++ b/src/runtime/internal/sys/arch_mips64.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = MIPS64
-	BigEndian           = 1
+	BigEndian           = true
 	CacheLineSize       = 32
 	DefaultPhysPageSize = 16384
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_mips64le.go b/src/runtime/internal/sys/arch_mips64le.go
index 4ced35b..e96d962 100644
--- a/src/runtime/internal/sys/arch_mips64le.go
+++ b/src/runtime/internal/sys/arch_mips64le.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = MIPS64
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 32
 	DefaultPhysPageSize = 16384
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_mipsle.go b/src/runtime/internal/sys/arch_mipsle.go
index 33e9764..25742ae 100644
--- a/src/runtime/internal/sys/arch_mipsle.go
+++ b/src/runtime/internal/sys/arch_mipsle.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = MIPS
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 32
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_ppc64.go b/src/runtime/internal/sys/arch_ppc64.go
index 80595ee..a538bbd 100644
--- a/src/runtime/internal/sys/arch_ppc64.go
+++ b/src/runtime/internal/sys/arch_ppc64.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = PPC64
-	BigEndian           = 1
+	BigEndian           = true
 	CacheLineSize       = 128
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_ppc64le.go b/src/runtime/internal/sys/arch_ppc64le.go
index f68e777..aa50689 100644
--- a/src/runtime/internal/sys/arch_ppc64le.go
+++ b/src/runtime/internal/sys/arch_ppc64le.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = PPC64
-	BigEndian           = 0
+	BigEndian           = false
 	CacheLineSize       = 128
 	DefaultPhysPageSize = 65536
 	PCQuantum           = 4
diff --git a/src/runtime/internal/sys/arch_s390x.go b/src/runtime/internal/sys/arch_s390x.go
index 4ec4bf8..e42c420 100644
--- a/src/runtime/internal/sys/arch_s390x.go
+++ b/src/runtime/internal/sys/arch_s390x.go
@@ -6,7 +6,7 @@
 
 const (
 	ArchFamily          = S390X
-	BigEndian           = 1
+	BigEndian           = true
 	CacheLineSize       = 256
 	DefaultPhysPageSize = 4096
 	PCQuantum           = 2
diff --git a/src/runtime/internal/sys/gengoos.go b/src/runtime/internal/sys/gengoos.go
index 4c45c0a..d078921 100644
--- a/src/runtime/internal/sys/gengoos.go
+++ b/src/runtime/internal/sys/gengoos.go
@@ -30,14 +30,14 @@
 		if strings.HasPrefix(line, goosPrefix) {
 			text, err := strconv.Unquote(strings.TrimPrefix(line, goosPrefix))
 			if err != nil {
-				log.Fatalf("parsing goosList %#q: %v", strings.TrimPrefix(line, goosPrefix), err)
+				log.Fatalf("parsing goosList: %v", err)
 			}
 			gooses = strings.Fields(text)
 		}
 		if strings.HasPrefix(line, goarchPrefix) {
 			text, err := strconv.Unquote(strings.TrimPrefix(line, goarchPrefix))
 			if err != nil {
-				log.Fatal("parsing goarchList: %v", err)
+				log.Fatalf("parsing goarchList: %v", err)
 			}
 			goarches = strings.Fields(text)
 		}
@@ -45,10 +45,11 @@
 
 	for _, target := range gooses {
 		var buf bytes.Buffer
-		fmt.Fprintf(&buf, "// generated by gengoos.go using 'go generate'\n\n")
+		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
 		if target == "linux" {
-			fmt.Fprintf(&buf, "// +build !android\n\n") // must explicitly exclude android for linux
+			fmt.Fprintf(&buf, "// +build !android\n") // must explicitly exclude android for linux
 		}
+		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
 		fmt.Fprintf(&buf, "package sys\n\n")
 		fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target)
 		for _, goos := range gooses {
@@ -66,7 +67,8 @@
 
 	for _, target := range goarches {
 		var buf bytes.Buffer
-		fmt.Fprintf(&buf, "// generated by gengoos.go using 'go generate'\n\n")
+		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
+		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
 		fmt.Fprintf(&buf, "package sys\n\n")
 		fmt.Fprintf(&buf, "const GOARCH = `%s`\n\n", target)
 		for _, goarch := range goarches {
diff --git a/src/runtime/internal/sys/stubs.go b/src/runtime/internal/sys/stubs.go
index 0a94502..5328023 100644
--- a/src/runtime/internal/sys/stubs.go
+++ b/src/runtime/internal/sys/stubs.go
@@ -9,3 +9,5 @@
 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
 const SpAlign = 1*(1-GoarchArm64) + 16*GoarchArm64 // SP alignment: 1 normally, 16 for ARM64
+
+var DefaultGoroot string // set at link time
diff --git a/src/runtime/internal/sys/sys.go b/src/runtime/internal/sys/sys.go
index 586a763..9d9ac45 100644
--- a/src/runtime/internal/sys/sys.go
+++ b/src/runtime/internal/sys/sys.go
@@ -6,9 +6,9 @@
 // constants used by the runtime.
 package sys
 
-// The next line makes 'go generate' write the zgen_*.go files with
+// The next line makes 'go generate' write the zgo*.go files with
 // per-OS and per-arch information, including constants
-// named goos_$GOOS and goarch_$GOARCH for every
+// named Goos$GOOS and Goarch$GOARCH for every
 // known GOOS and GOARCH. The constant is 1 on the
 // current system, 0 otherwise; multiplying by them is
 // useful for defining GOOS- or GOARCH-specific constants.
diff --git a/src/runtime/internal/sys/zgoarch_386.go b/src/runtime/internal/sys/zgoarch_386.go
index 3bcf83b..b07abbe 100644
--- a/src/runtime/internal/sys/zgoarch_386.go
+++ b/src/runtime/internal/sys/zgoarch_386.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build 386
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_amd64.go b/src/runtime/internal/sys/zgoarch_amd64.go
index 699f191..bfdcb00 100644
--- a/src/runtime/internal/sys/zgoarch_amd64.go
+++ b/src/runtime/internal/sys/zgoarch_amd64.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build amd64
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_amd64p32.go b/src/runtime/internal/sys/zgoarch_amd64p32.go
index cc2d658..b61617d 100644
--- a/src/runtime/internal/sys/zgoarch_amd64p32.go
+++ b/src/runtime/internal/sys/zgoarch_amd64p32.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build amd64p32
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_arm.go b/src/runtime/internal/sys/zgoarch_arm.go
index a5fd789..79595d5 100644
--- a/src/runtime/internal/sys/zgoarch_arm.go
+++ b/src/runtime/internal/sys/zgoarch_arm.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build arm
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_arm64.go b/src/runtime/internal/sys/zgoarch_arm64.go
index 084d2c7..c839b8f 100644
--- a/src/runtime/internal/sys/zgoarch_arm64.go
+++ b/src/runtime/internal/sys/zgoarch_arm64.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build arm64
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_arm64be.go b/src/runtime/internal/sys/zgoarch_arm64be.go
new file mode 100644
index 0000000..58b4ef1
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_arm64be.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build arm64be
+
+package sys
+
+const GOARCH = `arm64be`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 1
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_armbe.go b/src/runtime/internal/sys/zgoarch_armbe.go
new file mode 100644
index 0000000..e9e2c31
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_armbe.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build armbe
+
+package sys
+
+const GOARCH = `armbe`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 1
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips.go b/src/runtime/internal/sys/zgoarch_mips.go
index 2f733d2..b0bf4ff 100644
--- a/src/runtime/internal/sys/zgoarch_mips.go
+++ b/src/runtime/internal/sys/zgoarch_mips.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mips
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_mips64.go b/src/runtime/internal/sys/zgoarch_mips64.go
index 2ad62bd..093e88c 100644
--- a/src/runtime/internal/sys/zgoarch_mips64.go
+++ b/src/runtime/internal/sys/zgoarch_mips64.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mips64
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_mips64le.go b/src/runtime/internal/sys/zgoarch_mips64le.go
index 047c8b4..3bad7cf 100644
--- a/src/runtime/internal/sys/zgoarch_mips64le.go
+++ b/src/runtime/internal/sys/zgoarch_mips64le.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mips64le
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_mips64p32.go b/src/runtime/internal/sys/zgoarch_mips64p32.go
new file mode 100644
index 0000000..c5f69fc
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_mips64p32.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mips64p32
+
+package sys
+
+const GOARCH = `mips64p32`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 1
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips64p32le.go b/src/runtime/internal/sys/zgoarch_mips64p32le.go
new file mode 100644
index 0000000..014ef84
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_mips64p32le.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mips64p32le
+
+package sys
+
+const GOARCH = `mips64p32le`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 1
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mipsle.go b/src/runtime/internal/sys/zgoarch_mipsle.go
index 95f3d5a..75814be 100644
--- a/src/runtime/internal/sys/zgoarch_mipsle.go
+++ b/src/runtime/internal/sys/zgoarch_mipsle.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build mipsle
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_ppc.go b/src/runtime/internal/sys/zgoarch_ppc.go
new file mode 100644
index 0000000..2a891b8
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_ppc.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build ppc
+
+package sys
+
+const GOARCH = `ppc`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 1
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_ppc64.go b/src/runtime/internal/sys/zgoarch_ppc64.go
index 748b5b5..847db4b 100644
--- a/src/runtime/internal/sys/zgoarch_ppc64.go
+++ b/src/runtime/internal/sys/zgoarch_ppc64.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build ppc64
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_ppc64le.go b/src/runtime/internal/sys/zgoarch_ppc64le.go
index d3dcba4..5195797 100644
--- a/src/runtime/internal/sys/zgoarch_ppc64le.go
+++ b/src/runtime/internal/sys/zgoarch_ppc64le.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build ppc64le
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_s390.go b/src/runtime/internal/sys/zgoarch_s390.go
new file mode 100644
index 0000000..cd215da
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_s390.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build s390
+
+package sys
+
+const GOARCH = `s390`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 1
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_s390x.go b/src/runtime/internal/sys/zgoarch_s390x.go
index 1ead5d5..b9368ff 100644
--- a/src/runtime/internal/sys/zgoarch_s390x.go
+++ b/src/runtime/internal/sys/zgoarch_s390x.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build s390x
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoarch_sparc.go b/src/runtime/internal/sys/zgoarch_sparc.go
new file mode 100644
index 0000000..e9afe01
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_sparc.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build sparc
+
+package sys
+
+const GOARCH = `sparc`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 1
+const GoarchSparc64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_sparc64.go b/src/runtime/internal/sys/zgoarch_sparc64.go
new file mode 100644
index 0000000..b6004ef
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_sparc64.go
@@ -0,0 +1,28 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build sparc64
+
+package sys
+
+const GOARCH = `sparc64`
+
+const Goarch386 = 0
+const GoarchAmd64 = 0
+const GoarchAmd64p32 = 0
+const GoarchArm = 0
+const GoarchArmbe = 0
+const GoarchArm64 = 0
+const GoarchArm64be = 0
+const GoarchPpc64 = 0
+const GoarchPpc64le = 0
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 1
diff --git a/src/runtime/internal/sys/zgoos_android.go b/src/runtime/internal/sys/zgoos_android.go
index 6503b15..01ebe75 100644
--- a/src/runtime/internal/sys/zgoos_android.go
+++ b/src/runtime/internal/sys/zgoos_android.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build android
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_darwin.go b/src/runtime/internal/sys/zgoos_darwin.go
index 6a28598..1303d71 100644
--- a/src/runtime/internal/sys/zgoos_darwin.go
+++ b/src/runtime/internal/sys/zgoos_darwin.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build darwin
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_dragonfly.go b/src/runtime/internal/sys/zgoos_dragonfly.go
index 886ac26..64325c7 100644
--- a/src/runtime/internal/sys/zgoos_dragonfly.go
+++ b/src/runtime/internal/sys/zgoos_dragonfly.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build dragonfly
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_freebsd.go b/src/runtime/internal/sys/zgoos_freebsd.go
index 0bf2403..3744971 100644
--- a/src/runtime/internal/sys/zgoos_freebsd.go
+++ b/src/runtime/internal/sys/zgoos_freebsd.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build freebsd
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_linux.go b/src/runtime/internal/sys/zgoos_linux.go
index c8664db..c726465 100644
--- a/src/runtime/internal/sys/zgoos_linux.go
+++ b/src/runtime/internal/sys/zgoos_linux.go
@@ -1,6 +1,7 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
 // +build !android
+// +build linux
 
 package sys
 
@@ -17,3 +18,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_nacl.go b/src/runtime/internal/sys/zgoos_nacl.go
index 0541226..53b394c 100644
--- a/src/runtime/internal/sys/zgoos_nacl.go
+++ b/src/runtime/internal/sys/zgoos_nacl.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build nacl
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_netbsd.go b/src/runtime/internal/sys/zgoos_netbsd.go
index 5c509a1..8bfdf45 100644
--- a/src/runtime/internal/sys/zgoos_netbsd.go
+++ b/src/runtime/internal/sys/zgoos_netbsd.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build netbsd
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_openbsd.go b/src/runtime/internal/sys/zgoos_openbsd.go
index dc43157..fc6acb7 100644
--- a/src/runtime/internal/sys/zgoos_openbsd.go
+++ b/src/runtime/internal/sys/zgoos_openbsd.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build openbsd
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_plan9.go b/src/runtime/internal/sys/zgoos_plan9.go
index 4b0934f..75baeb3 100644
--- a/src/runtime/internal/sys/zgoos_plan9.go
+++ b/src/runtime/internal/sys/zgoos_plan9.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build plan9
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 1
 const GoosSolaris = 0
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_solaris.go b/src/runtime/internal/sys/zgoos_solaris.go
index 42511a3..c18f34f 100644
--- a/src/runtime/internal/sys/zgoos_solaris.go
+++ b/src/runtime/internal/sys/zgoos_solaris.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build solaris
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 1
 const GoosWindows = 0
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_windows.go b/src/runtime/internal/sys/zgoos_windows.go
index d77f62c..b9f0d4e 100644
--- a/src/runtime/internal/sys/zgoos_windows.go
+++ b/src/runtime/internal/sys/zgoos_windows.go
@@ -1,4 +1,6 @@
-// generated by gengoos.go using 'go generate'
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build windows
 
 package sys
 
@@ -15,3 +17,4 @@
 const GoosPlan9 = 0
 const GoosSolaris = 0
 const GoosWindows = 1
+const GoosZos = 0
diff --git a/src/runtime/internal/sys/zgoos_zos.go b/src/runtime/internal/sys/zgoos_zos.go
new file mode 100644
index 0000000..2563ebe
--- /dev/null
+++ b/src/runtime/internal/sys/zgoos_zos.go
@@ -0,0 +1,20 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+// +build zos
+
+package sys
+
+const GOOS = `zos`
+
+const GoosAndroid = 0
+const GoosDarwin = 0
+const GoosDragonfly = 0
+const GoosFreebsd = 0
+const GoosLinux = 0
+const GoosNacl = 0
+const GoosNetbsd = 0
+const GoosOpenbsd = 0
+const GoosPlan9 = 0
+const GoosSolaris = 0
+const GoosWindows = 0
+const GoosZos = 1
diff --git a/src/runtime/internal/sys/zversion.go b/src/runtime/internal/sys/zversion.go
index b28d5ed..3c54824 100644
--- a/src/runtime/internal/sys/zversion.go
+++ b/src/runtime/internal/sys/zversion.go
@@ -1,9 +1,7 @@
-// auto generated by go tool dist
+// Code generated by go tool dist; DO NOT EDIT.
 
 package sys
 
-const DefaultGoroot = `./prebuilts/go/darwin-x86`
-const TheVersion = `go1.9`
+const TheVersion = `go1.10`
 const Goexperiment = ``
 const StackGuardMultiplier = 1
-
diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go
index 5b0169d..b41f805 100644
--- a/src/runtime/lock_sema.go
+++ b/src/runtime/lock_sema.go
@@ -71,7 +71,7 @@
 			// for this lock, chained through m->nextwaitm.
 			// Queue this M.
 			for {
-				gp.m.nextwaitm = v &^ locked
+				gp.m.nextwaitm = muintptr(v &^ locked)
 				if atomic.Casuintptr(&l.key, v, uintptr(unsafe.Pointer(gp.m))|locked) {
 					break
 				}
@@ -103,8 +103,8 @@
 		} else {
 			// Other M's are waiting for the lock.
 			// Dequeue an M.
-			mp = (*m)(unsafe.Pointer(v &^ locked))
-			if atomic.Casuintptr(&l.key, v, mp.nextwaitm) {
+			mp = muintptr(v &^ locked).ptr()
+			if atomic.Casuintptr(&l.key, v, uintptr(mp.nextwaitm)) {
 				// Dequeued an M.  Wake it.
 				semawakeup(mp)
 				break
@@ -140,7 +140,7 @@
 	case v == 0:
 		// Nothing was waiting. Done.
 	case v == locked:
-		// Two notewakeups!  Not allowed.
+		// Two notewakeups! Not allowed.
 		throw("notewakeup - double wakeup")
 	default:
 		// Must be the waiting m. Wake it up.
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 0ebd2c0..72b8f40 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -529,9 +529,8 @@
 			}
 			s.allocCache >>= uint(theBit + 1)
 			s.freeindex = freeidx
-			v := gclinkptr(result*s.elemsize + s.base())
 			s.allocCount++
-			return v
+			return gclinkptr(result*s.elemsize + s.base())
 		}
 	}
 	return 0
@@ -847,6 +846,9 @@
 
 // newarray allocates an array of n elements of type typ.
 func newarray(typ *_type, n int) unsafe.Pointer {
+	if n == 1 {
+		return mallocgc(typ.size, typ, true)
+	}
 	if n < 0 || uintptr(n) > maxSliceCap(typ.size) {
 		panic(plainError("runtime: allocation size out of range"))
 	}
@@ -863,11 +865,13 @@
 	mProf_Malloc(x, size)
 }
 
-// nextSample returns the next sampling point for heap profiling.
-// It produces a random variable with a geometric distribution and
-// mean MemProfileRate. This is done by generating a uniformly
-// distributed random number and applying the cumulative distribution
-// function for an exponential.
+// nextSample returns the next sampling point for heap profiling. The goal is
+// to sample allocations on average every MemProfileRate bytes, but with a
+// completely random distribution over the allocation timeline; this
+// corresponds to a Poisson process with parameter MemProfileRate. In Poisson
+// processes, the distance between two samples follows the exponential
+// distribution (exp(MemProfileRate)), so the best return value is a random
+// number taken from an exponential distribution whose mean is MemProfileRate.
 func nextSample() int32 {
 	if GOOS == "plan9" {
 		// Plan 9 doesn't support floating point in note handler.
@@ -876,25 +880,29 @@
 		}
 	}
 
-	period := MemProfileRate
+	return fastexprand(MemProfileRate)
+}
 
-	// make nextSample not overflow. Maximum possible step is
-	// -ln(1/(1<<kRandomBitCount)) * period, approximately 20 * period.
+// fastexprand returns a random number from an exponential distribution with
+// the specified mean.
+func fastexprand(mean int) int32 {
+	// Avoid overflow. Maximum possible step is
+	// -ln(1/(1<<randomBitCount)) * mean, approximately 20 * mean.
 	switch {
-	case period > 0x7000000:
-		period = 0x7000000
-	case period == 0:
+	case mean > 0x7000000:
+		mean = 0x7000000
+	case mean == 0:
 		return 0
 	}
 
-	// Let m be the sample rate,
-	// the probability distribution function is m*exp(-mx), so the CDF is
-	// p = 1 - exp(-mx), so
-	// q = 1 - p == exp(-mx)
-	// log_e(q) = -mx
-	// -log_e(q)/m = x
-	// x = -log_e(q) * period
-	// x = log_2(q) * (-log_e(2)) * period    ; Using log_2 for efficiency
+	// Take a random sample of the exponential distribution exp(-mean*x).
+	// The probability distribution function is mean*exp(-mean*x), so the CDF is
+	// p = 1 - exp(-mean*x), so
+	// q = 1 - p == exp(-mean*x)
+	// log_e(q) = -mean*x
+	// -log_e(q)/mean = x
+	// x = -log_e(q) * mean
+	// x = log_2(q) * (-log_e(2)) * mean    ; Using log_2 for efficiency
 	const randomBitCount = 26
 	q := fastrand()%(1<<randomBitCount) + 1
 	qlog := fastlog2(float64(q)) - randomBitCount
@@ -902,7 +910,7 @@
 		qlog = 0
 	}
 	const minusLog2 = -0.6931471805599453 // -ln(2)
-	return int32(qlog*(minusLog2*float64(period))) + 1
+	return int32(qlog*(minusLog2*float64(mean))) + 1
 }
 
 // nextSampleNoFP is similar to nextSample, but uses older,
@@ -920,7 +928,7 @@
 }
 
 type persistentAlloc struct {
-	base unsafe.Pointer
+	base *notInHeap
 	off  uintptr
 }
 
@@ -937,17 +945,17 @@
 //
 // Consider marking persistentalloc'd types go:notinheap.
 func persistentalloc(size, align uintptr, sysStat *uint64) unsafe.Pointer {
-	var p unsafe.Pointer
+	var p *notInHeap
 	systemstack(func() {
 		p = persistentalloc1(size, align, sysStat)
 	})
-	return p
+	return unsafe.Pointer(p)
 }
 
 // Must run on system stack because stack growth can (re)invoke it.
 // See issue 9174.
 //go:systemstack
-func persistentalloc1(size, align uintptr, sysStat *uint64) unsafe.Pointer {
+func persistentalloc1(size, align uintptr, sysStat *uint64) *notInHeap {
 	const (
 		chunk    = 256 << 10
 		maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
@@ -968,7 +976,7 @@
 	}
 
 	if size >= maxBlock {
-		return sysAlloc(size, sysStat)
+		return (*notInHeap)(sysAlloc(size, sysStat))
 	}
 
 	mp := acquirem()
@@ -981,7 +989,7 @@
 	}
 	persistent.off = round(persistent.off, align)
 	if persistent.off+size > chunk || persistent.base == nil {
-		persistent.base = sysAlloc(chunk, &memstats.other_sys)
+		persistent.base = (*notInHeap)(sysAlloc(chunk, &memstats.other_sys))
 		if persistent.base == nil {
 			if persistent == &globalAlloc.persistentAlloc {
 				unlock(&globalAlloc.mutex)
@@ -990,7 +998,7 @@
 		}
 		persistent.off = 0
 	}
-	p := add(persistent.base, persistent.off)
+	p := persistent.base.add(persistent.off)
 	persistent.off += size
 	releasem(mp)
 	if persistent == &globalAlloc.persistentAlloc {
@@ -1003,3 +1011,19 @@
 	}
 	return p
 }
+
+// notInHeap is off-heap memory allocated by a lower-level allocator
+// like sysAlloc or persistentAlloc.
+//
+// In general, it's better to use real types marked as go:notinheap,
+// but this serves as a generic type for situations where that isn't
+// possible (like in the allocators).
+//
+// TODO: Use this as the return type of sysAlloc, persistentAlloc, etc?
+//
+//go:notinheap
+type notInHeap struct{}
+
+func (p *notInHeap) add(bytes uintptr) *notInHeap {
+	return (*notInHeap)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + bytes))
+}
diff --git a/src/runtime/malloc_test.go b/src/runtime/malloc_test.go
index d9487ee..93aa56d 100644
--- a/src/runtime/malloc_test.go
+++ b/src/runtime/malloc_test.go
@@ -46,9 +46,6 @@
 	}
 	// Of the uint fields, HeapReleased, HeapIdle can be 0.
 	// PauseTotalNs can be 0 if timer resolution is poor.
-	//
-	// TODO: Test that GCCPUFraction is <= 0.99. This currently
-	// fails on windows/386. (Issue #19319)
 	fields := map[string][]func(interface{}) error{
 		"Alloc": {nz, le(1e10)}, "TotalAlloc": {nz, le(1e11)}, "Sys": {nz, le(1e10)},
 		"Lookups": {nz, le(1e10)}, "Mallocs": {nz, le(1e10)}, "Frees": {nz, le(1e10)},
@@ -61,7 +58,7 @@
 		"NextGC": {nz, le(1e10)}, "LastGC": {nz},
 		"PauseTotalNs": {le(1e11)}, "PauseNs": nil, "PauseEnd": nil,
 		"NumGC": {nz, le(1e9)}, "NumForcedGC": {nz, le(1e9)},
-		"GCCPUFraction": nil, "EnableGC": {eq(true)}, "DebugGC": {eq(false)},
+		"GCCPUFraction": {le(0.99)}, "EnableGC": {eq(true)}, "DebugGC": {eq(false)},
 		"BySize": nil,
 	}
 
diff --git a/src/runtime/map_test.go b/src/runtime/map_test.go
index 81f05a0..6ed655d 100644
--- a/src/runtime/map_test.go
+++ b/src/runtime/map_test.go
@@ -244,7 +244,7 @@
 	numGrowStep := 250
 	numReader := 16
 	if testing.Short() {
-		numLoop, numGrowStep = 2, 500
+		numLoop, numGrowStep = 2, 100
 	}
 	for i := 0; i < numLoop; i++ {
 		m := make(map[int]int, 0)
@@ -596,6 +596,134 @@
 	}
 }
 
+var mapSink map[int]int
+
+var mapBucketTests = [...]struct {
+	n        int // n is the number of map elements
+	noescape int // number of expected buckets for non-escaping map
+	escape   int // number of expected buckets for escaping map
+}{
+	{-(1 << 30), 1, 1},
+	{-1, 1, 1},
+	{0, 1, 1},
+	{1, 1, 1},
+	{8, 1, 1},
+	{9, 2, 2},
+	{13, 2, 2},
+	{14, 4, 4},
+	{26, 4, 4},
+}
+
+func TestMapBuckets(t *testing.T) {
+	// Test that maps of different sizes have the right number of buckets.
+	// Non-escaping maps with small buckets (like map[int]int) never
+	// have a nil bucket pointer due to starting with preallocated buckets
+	// on the stack. Escaping maps start with a non-nil bucket pointer if
+	// hint size is above bucketCnt and thereby have more than one bucket.
+	// These tests depend on bucketCnt and loadFactor* in hashmap.go.
+	t.Run("mapliteral", func(t *testing.T) {
+		for _, tt := range mapBucketTests {
+			localMap := map[int]int{}
+			if runtime.MapBucketsPointerIsNil(localMap) {
+				t.Errorf("no escape: buckets pointer is nil for non-escaping map")
+			}
+			for i := 0; i < tt.n; i++ {
+				localMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(localMap); got != tt.noescape {
+				t.Errorf("no escape: n=%d want %d buckets, got %d", tt.n, tt.noescape, got)
+			}
+			escapingMap := map[int]int{}
+			if count := runtime.MapBucketsCount(escapingMap); count > 1 && runtime.MapBucketsPointerIsNil(escapingMap) {
+				t.Errorf("escape: buckets pointer is nil for n=%d buckets", count)
+			}
+			for i := 0; i < tt.n; i++ {
+				escapingMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(escapingMap); got != tt.escape {
+				t.Errorf("escape n=%d want %d buckets, got %d", tt.n, tt.escape, got)
+			}
+			mapSink = escapingMap
+		}
+	})
+	t.Run("nohint", func(t *testing.T) {
+		for _, tt := range mapBucketTests {
+			localMap := make(map[int]int)
+			if runtime.MapBucketsPointerIsNil(localMap) {
+				t.Errorf("no escape: buckets pointer is nil for non-escaping map")
+			}
+			for i := 0; i < tt.n; i++ {
+				localMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(localMap); got != tt.noescape {
+				t.Errorf("no escape: n=%d want %d buckets, got %d", tt.n, tt.noescape, got)
+			}
+			escapingMap := make(map[int]int)
+			if count := runtime.MapBucketsCount(escapingMap); count > 1 && runtime.MapBucketsPointerIsNil(escapingMap) {
+				t.Errorf("escape: buckets pointer is nil for n=%d buckets", count)
+			}
+			for i := 0; i < tt.n; i++ {
+				escapingMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(escapingMap); got != tt.escape {
+				t.Errorf("escape: n=%d want %d buckets, got %d", tt.n, tt.escape, got)
+			}
+			mapSink = escapingMap
+		}
+	})
+	t.Run("makemap", func(t *testing.T) {
+		for _, tt := range mapBucketTests {
+			localMap := make(map[int]int, tt.n)
+			if runtime.MapBucketsPointerIsNil(localMap) {
+				t.Errorf("no escape: buckets pointer is nil for non-escaping map")
+			}
+			for i := 0; i < tt.n; i++ {
+				localMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(localMap); got != tt.noescape {
+				t.Errorf("no escape: n=%d want %d buckets, got %d", tt.n, tt.noescape, got)
+			}
+			escapingMap := make(map[int]int, tt.n)
+			if count := runtime.MapBucketsCount(escapingMap); count > 1 && runtime.MapBucketsPointerIsNil(escapingMap) {
+				t.Errorf("escape: buckets pointer is nil for n=%d buckets", count)
+			}
+			for i := 0; i < tt.n; i++ {
+				escapingMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(escapingMap); got != tt.escape {
+				t.Errorf("escape: n=%d want %d buckets, got %d", tt.n, tt.escape, got)
+			}
+			mapSink = escapingMap
+		}
+	})
+	t.Run("makemap64", func(t *testing.T) {
+		for _, tt := range mapBucketTests {
+			localMap := make(map[int]int, int64(tt.n))
+			if runtime.MapBucketsPointerIsNil(localMap) {
+				t.Errorf("no escape: buckets pointer is nil for non-escaping map")
+			}
+			for i := 0; i < tt.n; i++ {
+				localMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(localMap); got != tt.noescape {
+				t.Errorf("no escape: n=%d want %d buckets, got %d", tt.n, tt.noescape, got)
+			}
+			escapingMap := make(map[int]int, tt.n)
+			if count := runtime.MapBucketsCount(escapingMap); count > 1 && runtime.MapBucketsPointerIsNil(escapingMap) {
+				t.Errorf("escape: buckets pointer is nil for n=%d buckets", count)
+			}
+			for i := 0; i < tt.n; i++ {
+				escapingMap[i] = i
+			}
+			if got := runtime.MapBucketsCount(escapingMap); got != tt.escape {
+				t.Errorf("escape: n=%d want %d buckets, got %d", tt.n, tt.escape, got)
+			}
+			mapSink = escapingMap
+		}
+	})
+
+}
+
 func benchmarkMapPop(b *testing.B, n int) {
 	m := map[int]int{}
 	for i := 0; i < b.N; i++ {
@@ -617,14 +745,38 @@
 func BenchmarkMapPop1000(b *testing.B)  { benchmarkMapPop(b, 1000) }
 func BenchmarkMapPop10000(b *testing.B) { benchmarkMapPop(b, 10000) }
 
+var testNonEscapingMapVariable int = 8
+
 func TestNonEscapingMap(t *testing.T) {
 	n := testing.AllocsPerRun(1000, func() {
+		m := map[int]int{}
+		m[0] = 0
+	})
+	if n != 0 {
+		t.Fatalf("mapliteral: want 0 allocs, got %v", n)
+	}
+	n = testing.AllocsPerRun(1000, func() {
 		m := make(map[int]int)
 		m[0] = 0
 	})
 	if n != 0 {
-		t.Fatalf("want 0 allocs, got %v", n)
+		t.Fatalf("no hint: want 0 allocs, got %v", n)
 	}
+	n = testing.AllocsPerRun(1000, func() {
+		m := make(map[int]int, 8)
+		m[0] = 0
+	})
+	if n != 0 {
+		t.Fatalf("with small hint: want 0 allocs, got %v", n)
+	}
+	n = testing.AllocsPerRun(1000, func() {
+		m := make(map[int]int, testNonEscapingMapVariable)
+		m[0] = 0
+	})
+	if n != 0 {
+		t.Fatalf("with variable hint: want 0 allocs, got %v", n)
+	}
+
 }
 
 func benchmarkMapAssignInt32(b *testing.B, n int) {
@@ -635,12 +787,16 @@
 }
 
 func benchmarkMapDeleteInt32(b *testing.B, n int) {
-	a := make(map[int32]int)
-	for i := 0; i < n*b.N; i++ {
-		a[int32(i)] = i
-	}
+	a := make(map[int32]int, n)
 	b.ResetTimer()
-	for i := 0; i < n*b.N; i = i + n {
+	for i := 0; i < b.N; i++ {
+		if len(a) == 0 {
+			b.StopTimer()
+			for j := i; j < i+n; j++ {
+				a[int32(j)] = j
+			}
+			b.StartTimer()
+		}
 		delete(a, int32(i))
 	}
 }
@@ -653,12 +809,16 @@
 }
 
 func benchmarkMapDeleteInt64(b *testing.B, n int) {
-	a := make(map[int64]int)
-	for i := 0; i < n*b.N; i++ {
-		a[int64(i)] = i
-	}
+	a := make(map[int64]int, n)
 	b.ResetTimer()
-	for i := 0; i < n*b.N; i = i + n {
+	for i := 0; i < b.N; i++ {
+		if len(a) == 0 {
+			b.StopTimer()
+			for j := i; j < i+n; j++ {
+				a[int64(j)] = j
+			}
+			b.StartTimer()
+		}
 		delete(a, int64(i))
 	}
 }
@@ -676,17 +836,23 @@
 }
 
 func benchmarkMapDeleteStr(b *testing.B, n int) {
-	k := make([]string, n*b.N)
-	for i := 0; i < n*b.N; i++ {
-		k[i] = strconv.Itoa(i)
+	i2s := make([]string, n)
+	for i := 0; i < n; i++ {
+		i2s[i] = strconv.Itoa(i)
 	}
-	a := make(map[string]int)
-	for i := 0; i < n*b.N; i++ {
-		a[k[i]] = i
-	}
+	a := make(map[string]int, n)
 	b.ResetTimer()
-	for i := 0; i < n*b.N; i = i + n {
-		delete(a, k[i])
+	k := 0
+	for i := 0; i < b.N; i++ {
+		if len(a) == 0 {
+			b.StopTimer()
+			for j := 0; j < n; j++ {
+				a[i2s[j]] = j
+			}
+			k = i
+			b.StartTimer()
+		}
+		delete(a, i2s[i-k])
 	}
 }
 
@@ -705,7 +871,7 @@
 }
 
 func BenchmarkMapDelete(b *testing.B) {
-	b.Run("Int32", runWith(benchmarkMapDeleteInt32, 1, 2, 4))
-	b.Run("Int64", runWith(benchmarkMapDeleteInt64, 1, 2, 4))
-	b.Run("Str", runWith(benchmarkMapDeleteStr, 1, 2, 4))
+	b.Run("Int32", runWith(benchmarkMapDeleteInt32, 100, 1000, 10000))
+	b.Run("Int64", runWith(benchmarkMapDeleteInt64, 100, 1000, 10000))
+	b.Run("Str", runWith(benchmarkMapDeleteStr, 100, 1000, 10000))
 }
diff --git a/src/runtime/mbarrier.go b/src/runtime/mbarrier.go
index 3713c50..e28bdb8 100644
--- a/src/runtime/mbarrier.go
+++ b/src/runtime/mbarrier.go
@@ -182,6 +182,8 @@
 func writebarrierptr_prewrite1(dst *uintptr, src uintptr) {
 	mp := acquirem()
 	if mp.inwb || mp.dying > 0 {
+		// We explicitly allow write barriers in startpanic_m,
+		// since we're going down anyway. Ignore them here.
 		releasem(mp)
 		return
 	}
@@ -237,6 +239,10 @@
 
 // typedmemmove copies a value of type t to dst from src.
 // Must be nosplit, see #16026.
+//
+// TODO: Perfect for go:nosplitrec since we can't have a safe point
+// anywhere in the bulk barrier or memmove.
+//
 //go:nosplit
 func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
 	if typ.kind&kindNoPointers == 0 {
@@ -258,8 +264,8 @@
 //go:linkname reflect_typedmemmove reflect.typedmemmove
 func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
 	if raceenabled {
-		raceWriteObjectPC(typ, dst, getcallerpc(unsafe.Pointer(&typ)), funcPC(reflect_typedmemmove))
-		raceReadObjectPC(typ, src, getcallerpc(unsafe.Pointer(&typ)), funcPC(reflect_typedmemmove))
+		raceWriteObjectPC(typ, dst, getcallerpc(), funcPC(reflect_typedmemmove))
+		raceReadObjectPC(typ, src, getcallerpc(), funcPC(reflect_typedmemmove))
 	}
 	if msanenabled {
 		msanwrite(dst, typ.size)
@@ -320,8 +326,12 @@
 	dstp := dst.array
 	srcp := src.array
 
+	// The compiler emits calls to typedslicecopy before
+	// instrumentation runs, so unlike the other copying and
+	// assignment operations, it's not instrumented in the calling
+	// code and needs its own instrumentation.
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&typ))
+		callerpc := getcallerpc()
 		pc := funcPC(slicecopy)
 		racewriterangepc(dstp, uintptr(n)*typ.size, callerpc, pc)
 		racereadrangepc(srcp, uintptr(n)*typ.size, callerpc, pc)
@@ -339,41 +349,13 @@
 	// compiler only emits calls to typedslicecopy for types with pointers,
 	// and growslice and reflect_typedslicecopy check for pointers
 	// before calling typedslicecopy.
-	if !writeBarrier.needed {
-		memmove(dstp, srcp, uintptr(n)*typ.size)
-		return n
+	size := uintptr(n) * typ.size
+	if writeBarrier.needed {
+		bulkBarrierPreWrite(uintptr(dstp), uintptr(srcp), size)
 	}
-
-	systemstack(func() {
-		if uintptr(srcp) < uintptr(dstp) && uintptr(srcp)+uintptr(n)*typ.size > uintptr(dstp) {
-			// Overlap with src before dst.
-			// Copy backward, being careful not to move dstp/srcp
-			// out of the array they point into.
-			dstp = add(dstp, uintptr(n-1)*typ.size)
-			srcp = add(srcp, uintptr(n-1)*typ.size)
-			i := 0
-			for {
-				typedmemmove(typ, dstp, srcp)
-				if i++; i >= n {
-					break
-				}
-				dstp = add(dstp, -typ.size)
-				srcp = add(srcp, -typ.size)
-			}
-		} else {
-			// Copy forward, being careful not to move dstp/srcp
-			// out of the array they point into.
-			i := 0
-			for {
-				typedmemmove(typ, dstp, srcp)
-				if i++; i >= n {
-					break
-				}
-				dstp = add(dstp, typ.size)
-				srcp = add(srcp, typ.size)
-			}
-		}
-	})
+	// See typedmemmove for a discussion of the race between the
+	// barrier and memmove.
+	memmove(dstp, srcp, size)
 	return n
 }
 
@@ -390,7 +372,7 @@
 
 		size := uintptr(n) * elemType.size
 		if raceenabled {
-			callerpc := getcallerpc(unsafe.Pointer(&elemType))
+			callerpc := getcallerpc()
 			pc := funcPC(reflect_typedslicecopy)
 			racewriterangepc(dst.array, size, callerpc, pc)
 			racereadrangepc(src.array, size, callerpc, pc)
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index 2a9f1b8..3a88f17 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -449,11 +449,6 @@
 	return
 }
 
-// prefetch the bits.
-func (h heapBits) prefetch() {
-	prefetchnta(uintptr(unsafe.Pointer((h.bitp))))
-}
-
 // next returns the heapBits describing the next pointer-sized word in memory.
 // That is, if h describes address p, h.next() describes p+ptrSize.
 // Note that next does not modify h. The caller must record the result.
@@ -480,6 +475,9 @@
 // The caller can test morePointers and isPointer by &-ing with bitScan and bitPointer.
 // The result includes in its higher bits the bits for subsequent words
 // described by the same bitmap byte.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
 func (h heapBits) bits() uint32 {
 	// The (shift & 31) eliminates a test and conditional branch
 	// from the generated code.
@@ -528,12 +526,13 @@
 	atomic.Or8(h.bitp, bitScan<<(heapBitsShift+h.shift))
 }
 
-// bulkBarrierPreWrite executes writebarrierptr_prewrite1
+// bulkBarrierPreWrite executes a write barrier
 // for every pointer slot in the memory range [src, src+size),
 // using pointer/scalar information from [dst, dst+size).
 // This executes the write barriers necessary before a memmove.
 // src, dst, and size must be pointer-aligned.
 // The range [dst, dst+size) must lie within a single object.
+// It does not perform the actual writes.
 //
 // As a special case, src == 0 indicates that this is being used for a
 // memclr. bulkBarrierPreWrite will pass 0 for the src of each write
@@ -583,12 +582,15 @@
 		return
 	}
 
+	buf := &getg().m.p.ptr().wbBuf
 	h := heapBitsForAddr(dst)
 	if src == 0 {
 		for i := uintptr(0); i < size; i += sys.PtrSize {
 			if h.isPointer() {
 				dstx := (*uintptr)(unsafe.Pointer(dst + i))
-				writebarrierptr_prewrite1(dstx, 0)
+				if !buf.putFast(*dstx, 0) {
+					wbBufFlush(nil, 0)
+				}
 			}
 			h = h.next()
 		}
@@ -597,7 +599,9 @@
 			if h.isPointer() {
 				dstx := (*uintptr)(unsafe.Pointer(dst + i))
 				srcx := (*uintptr)(unsafe.Pointer(src + i))
-				writebarrierptr_prewrite1(dstx, *srcx)
+				if !buf.putFast(*dstx, *srcx) {
+					wbBufFlush(nil, 0)
+				}
 			}
 			h = h.next()
 		}
@@ -617,6 +621,7 @@
 	bits = addb(bits, word/8)
 	mask := uint8(1) << (word % 8)
 
+	buf := &getg().m.p.ptr().wbBuf
 	for i := uintptr(0); i < size; i += sys.PtrSize {
 		if mask == 0 {
 			bits = addb(bits, 1)
@@ -630,10 +635,14 @@
 		if *bits&mask != 0 {
 			dstx := (*uintptr)(unsafe.Pointer(dst + i))
 			if src == 0 {
-				writebarrierptr_prewrite1(dstx, 0)
+				if !buf.putFast(*dstx, 0) {
+					wbBufFlush(nil, 0)
+				}
 			} else {
 				srcx := (*uintptr)(unsafe.Pointer(src + i))
-				writebarrierptr_prewrite1(dstx, *srcx)
+				if !buf.putFast(*dstx, *srcx) {
+					wbBufFlush(nil, 0)
+				}
 			}
 		}
 		mask <<= 1
diff --git a/src/runtime/mcache.go b/src/runtime/mcache.go
index 96fb273..6c24650 100644
--- a/src/runtime/mcache.go
+++ b/src/runtime/mcache.go
@@ -104,7 +104,7 @@
 
 // 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.
-func (c *mcache) refill(spc spanClass) *mspan {
+func (c *mcache) refill(spc spanClass) {
 	_g_ := getg()
 
 	_g_.m.locks++
@@ -131,7 +131,6 @@
 
 	c.alloc[spc] = s
 	_g_.m.locks--
-	return s
 }
 
 func (c *mcache) releaseAll() {
diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go
index e0d2347..23872b9 100644
--- a/src/runtime/mem_bsd.go
+++ b/src/runtime/mem_bsd.go
@@ -15,8 +15,8 @@
 // which prevents us from allocating more stack.
 //go:nosplit
 func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
-	v := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(v) < 4096 {
+	v, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
 		return nil
 	}
 	mSysStatInc(sysStat, n)
@@ -51,8 +51,8 @@
 		return v
 	}
 
-	p := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) < 4096 {
+	p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
 		return nil
 	}
 	*reserved = true
@@ -76,22 +76,22 @@
 			// to do this - we do not on other platforms.
 			flags |= _MAP_FIXED
 		}
-		p := mmap(v, n, _PROT_READ|_PROT_WRITE, flags, -1, 0)
-		if uintptr(p) == _ENOMEM || (GOOS == "solaris" && uintptr(p) == _sunosEAGAIN) {
+		p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, flags, -1, 0)
+		if err == _ENOMEM || (GOOS == "solaris" && err == _sunosEAGAIN) {
 			throw("runtime: out of memory")
 		}
-		if p != v {
-			print("runtime: address space conflict: map(", v, ") = ", p, "\n")
+		if p != v || err != 0 {
+			print("runtime: address space conflict: map(", v, ") = ", p, "(err ", err, ")\n")
 			throw("runtime: address space conflict")
 		}
 		return
 	}
 
-	p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) == _ENOMEM || (GOOS == "solaris" && uintptr(p) == _sunosEAGAIN) {
+	p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+	if err == _ENOMEM || (GOOS == "solaris" && err == _sunosEAGAIN) {
 		throw("runtime: out of memory")
 	}
-	if p != v {
+	if p != v || err != 0 {
 		throw("runtime: cannot map pages in arena address space")
 	}
 }
diff --git a/src/runtime/mem_darwin.go b/src/runtime/mem_darwin.go
index 3f1c4d7..e41452a 100644
--- a/src/runtime/mem_darwin.go
+++ b/src/runtime/mem_darwin.go
@@ -10,8 +10,8 @@
 // which prevents us from allocating more stack.
 //go:nosplit
 func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
-	v := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(v) < 4096 {
+	v, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
 		return nil
 	}
 	mSysStatInc(sysStat, n)
@@ -40,8 +40,8 @@
 
 func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
 	*reserved = true
-	p := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) < 4096 {
+	p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
 		return nil
 	}
 	return p
@@ -53,11 +53,11 @@
 
 func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
 	mSysStatInc(sysStat, n)
-	p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) == _ENOMEM {
+	p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+	if err == _ENOMEM {
 		throw("runtime: out of memory")
 	}
-	if p != v {
+	if p != v || err != 0 {
 		throw("runtime: cannot map pages in arena address space")
 	}
 }
diff --git a/src/runtime/mem_linux.go b/src/runtime/mem_linux.go
index 094658d..16f4443 100644
--- a/src/runtime/mem_linux.go
+++ b/src/runtime/mem_linux.go
@@ -41,30 +41,30 @@
 	return true
 }
 
-func mmap_fixed(v unsafe.Pointer, n uintptr, prot, flags, fd int32, offset uint32) unsafe.Pointer {
-	p := mmap(v, n, prot, flags, fd, offset)
+func mmap_fixed(v unsafe.Pointer, n uintptr, prot, flags, fd int32, offset uint32) (unsafe.Pointer, int) {
+	p, err := mmap(v, n, prot, flags, fd, offset)
 	// On some systems, mmap ignores v without
 	// MAP_FIXED, so retry if the address space is free.
 	if p != v && addrspace_free(v, n) {
-		if uintptr(p) > 4096 {
+		if err == 0 {
 			munmap(p, n)
 		}
-		p = mmap(v, n, prot, flags|_MAP_FIXED, fd, offset)
+		p, err = mmap(v, n, prot, flags|_MAP_FIXED, fd, offset)
 	}
-	return p
+	return p, err
 }
 
 // Don't split the stack as this method may be invoked without a valid G, which
 // prevents us from allocating more stack.
 //go:nosplit
 func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
-	p := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) < 4096 {
-		if uintptr(p) == _EACCES {
+	p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
+		if err == _EACCES {
 			print("runtime: mmap: access denied\n")
 			exit(2)
 		}
-		if uintptr(p) == _EAGAIN {
+		if err == _EAGAIN {
 			print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
 			exit(2)
 		}
@@ -186,9 +186,9 @@
 	// if we can reserve at least 64K and check the assumption in SysMap.
 	// Only user-mode Linux (UML) rejects these requests.
 	if sys.PtrSize == 8 && uint64(n) > 1<<32 {
-		p := mmap_fixed(v, 64<<10, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-		if p != v {
-			if uintptr(p) >= 4096 {
+		p, err := mmap_fixed(v, 64<<10, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+		if p != v || err != 0 {
+			if err == 0 {
 				munmap(p, 64<<10)
 			}
 			return nil
@@ -198,8 +198,8 @@
 		return v
 	}
 
-	p := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) < 4096 {
+	p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+	if err != 0 {
 		return nil
 	}
 	*reserved = true
@@ -211,22 +211,22 @@
 
 	// 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 uintptr(p) == _ENOMEM {
+		p, err := mmap_fixed(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+		if err == _ENOMEM {
 			throw("runtime: out of memory")
 		}
-		if p != v {
-			print("runtime: address space conflict: map(", v, ") = ", p, "\n")
+		if p != v || err != 0 {
+			print("runtime: address space conflict: map(", v, ") = ", p, " (err ", err, ")\n")
 			throw("runtime: address space conflict")
 		}
 		return
 	}
 
-	p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
-	if uintptr(p) == _ENOMEM {
+	p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+	if err == _ENOMEM {
 		throw("runtime: out of memory")
 	}
-	if p != v {
+	if p != v || err != 0 {
 		throw("runtime: cannot map pages in arena address space")
 	}
 }
diff --git a/src/runtime/memclr_amd64p32.s b/src/runtime/memclr_amd64p32.s
new file mode 100644
index 0000000..26171bf
--- /dev/null
+++ b/src/runtime/memclr_amd64p32.s
@@ -0,0 +1,23 @@
+// Copyright 2009 The Go Authors. 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·memclrNoHeapPointers(SB),NOSPLIT,$0-8
+	MOVL	ptr+0(FP), DI
+	MOVL	n+4(FP), CX
+	MOVQ	CX, BX
+	ANDQ	$3, BX
+	SHRQ	$2, CX
+	MOVQ	$0, AX
+	CLD
+	REP
+	STOSL
+	MOVQ	BX, CX
+	REP
+	STOSB
+	// Note: we zero only 4 bytes at a time so that the tail is at most
+	// 3 bytes. That guarantees that we aren't zeroing pointers with STOSB.
+	// See issue 13160.
+	RET
diff --git a/src/runtime/memclr_arm64.s b/src/runtime/memclr_arm64.s
index 9d756bc..bf954e0 100644
--- a/src/runtime/memclr_arm64.s
+++ b/src/runtime/memclr_arm64.s
@@ -6,32 +6,54 @@
 
 // void runtime·memclrNoHeapPointers(void*, uintptr)
 TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
-	MOVD	ptr+0(FP), R3
-	MOVD	n+8(FP), R4
-	// TODO(mwhudson): this is written this way to avoid tickling
-	// warnings from addpool when written as AND $7, R4, R6 (see
-	// https://golang.org/issue/12708)
-	AND	$~7, R4, R5	// R5 is N&~7
-	SUB	R5, R4, R6	// R6 is N&7
+	MOVD	ptr+0(FP), R0
+	MOVD	n+8(FP), R1
+	// If size is less than 16 bytes, use tail_zero to zero what remains
+	CMP	$16, R1
+	BLT	tail_zero
+	// Get buffer offset into 16 byte aligned address for better performance
+	ANDS	$15, R0, ZR
+	BNE	unaligned_to_16
+aligned_to_16:
+	LSR	$4, R1, R2
+zero_by_16:
+	STP.P	(ZR, ZR), 16(R0)
+	SUBS	$1, R2, R2
+	BNE	zero_by_16
 
-	CMP	$0, R5
-	BEQ	nowords
+	ANDS	$15, R1, R1
+	BEQ	ending
 
-	ADD	R3, R5, R5
+	// Zero buffer with size=R1 < 16
+tail_zero:
+	TBZ	$3, R1, tail_zero_4
+	MOVD.P	ZR, 8(R0)
 
-wordloop: // TODO: Optimize for unaligned ptr.
-	MOVD.P	$0, 8(R3)
-	CMP	R3, R5
-	BNE	wordloop
-nowords:
-        CMP	$0, R6
-        BEQ	done
+tail_zero_4:
+	TBZ	$2, R1, tail_zero_2
+	MOVW.P	ZR, 4(R0)
 
-	ADD	R3, R6, R6
+tail_zero_2:
+	TBZ	$1, R1, tail_zero_1
+	MOVH.P	ZR, 2(R0)
 
-byteloop:
-	MOVBU.P	$0, 1(R3)
-	CMP	R3, R6
-	BNE	byteloop
-done:
+tail_zero_1:
+	TBZ	$0, R1, ending
+	MOVB	ZR, (R0)
+
+ending:
 	RET
+
+unaligned_to_16:
+	MOVD	R0, R2
+head_loop:
+	MOVBU.P	ZR, 1(R0)
+	ANDS	$15, R0, ZR
+	BNE	head_loop
+	// Adjust length for what remains
+	SUB	R2, R0, R3
+	SUB	R3, R1
+	// If size is less than 16 bytes, use tail_zero to zero what remains
+	CMP	$16, R1
+	BLT	tail_zero
+	B	aligned_to_16
diff --git a/src/runtime/memmove_nacl_amd64p32.s b/src/runtime/memmove_amd64p32.s
similarity index 100%
rename from src/runtime/memmove_nacl_amd64p32.s
rename to src/runtime/memmove_amd64p32.s
diff --git a/src/runtime/memmove_test.go b/src/runtime/memmove_test.go
index 74b8753..62de604 100644
--- a/src/runtime/memmove_test.go
+++ b/src/runtime/memmove_test.go
@@ -9,6 +9,7 @@
 	"encoding/binary"
 	"fmt"
 	"internal/race"
+	"internal/testenv"
 	. "runtime"
 	"testing"
 )
@@ -88,6 +89,10 @@
 }
 
 func TestMemmoveLarge0x180000(t *testing.T) {
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skip("-short")
+	}
+
 	t.Parallel()
 	if race.Enabled {
 		t.Skip("skipping large memmove test under race detector")
@@ -96,6 +101,10 @@
 }
 
 func TestMemmoveOverlapLarge0x120000(t *testing.T) {
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skip("-short")
+	}
+
 	t.Parallel()
 	if race.Enabled {
 		t.Skip("skipping large memmove test under race detector")
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index a8729b1..c11a6f1 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -461,11 +461,7 @@
 	return
 }
 
-// Mark KeepAlive as noinline so that the current compiler will ensure
-// that the argument is alive at the point of the function call.
-// If it were inlined, it would disappear, and there would be nothing
-// keeping the argument alive. Perhaps a future compiler will recognize
-// runtime.KeepAlive specially and do something more efficient.
+// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
 //go:noinline
 
 // KeepAlive marks its argument as currently reachable.
@@ -487,4 +483,11 @@
 // Without the KeepAlive call, the finalizer could run at the start of
 // syscall.Read, closing the file descriptor before syscall.Read makes
 // the actual system call.
-func KeepAlive(interface{}) {}
+func KeepAlive(x interface{}) {
+	// Introduce a use of x that the compiler can't eliminate.
+	// This makes sure x is alive on entry. We need x to be alive
+	// on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
+	if cgoAlwaysFalse {
+		println(x)
+	}
+}
diff --git a/src/runtime/mfinal_test.go b/src/runtime/mfinal_test.go
index e9e3601..3ca8d31 100644
--- a/src/runtime/mfinal_test.go
+++ b/src/runtime/mfinal_test.go
@@ -241,3 +241,24 @@
 	Foo2 = &Object2{}
 	Foo1 = &Object1{}
 )
+
+func TestDeferKeepAlive(t *testing.T) {
+	if *flagQuick {
+		t.Skip("-quick")
+	}
+
+	// See issue 21402.
+	t.Parallel()
+	type T *int // needs to be a pointer base type to avoid tinyalloc and its never-finalized behavior.
+	x := new(T)
+	finRun := false
+	runtime.SetFinalizer(x, func(x *T) {
+		finRun = true
+	})
+	defer runtime.KeepAlive(x)
+	runtime.GC()
+	time.Sleep(time.Second)
+	if finRun {
+		t.Errorf("finalizer ran prematurely")
+	}
+}
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 111fa78..ab90c28 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -230,6 +230,24 @@
 	// Update pacing in response to gcpercent change.
 	gcSetTriggerRatio(memstats.triggerRatio)
 	unlock(&mheap_.lock)
+
+	// If we just disabled GC, wait for any concurrent GC to
+	// finish so we always return with no GC running.
+	if in < 0 {
+		// Disable phase transitions.
+		lock(&work.sweepWaiters.lock)
+		if gcphase == _GCmark {
+			// GC is active. Wait until we reach sweeping.
+			gp := getg()
+			gp.schedlink = work.sweepWaiters.head
+			work.sweepWaiters.head.set(gp)
+			goparkunlock(&work.sweepWaiters.lock, "wait for GC cycle", traceEvGoBlock, 1)
+		} else {
+			// GC isn't active.
+			unlock(&work.sweepWaiters.lock)
+		}
+	}
+
 	return out
 }
 
@@ -299,10 +317,10 @@
 
 	// gcMarkWorkerFractionalMode indicates that a P is currently
 	// running the "fractional" mark worker. The fractional worker
-	// is necessary when GOMAXPROCS*gcGoalUtilization is not an
-	// integer. The fractional worker should run until it is
+	// is necessary when GOMAXPROCS*gcBackgroundUtilization is not
+	// an integer. The fractional worker should run until it is
 	// preempted and will be scheduled to pick up the fractional
-	// part of GOMAXPROCS*gcGoalUtilization.
+	// part of GOMAXPROCS*gcBackgroundUtilization.
 	gcMarkWorkerFractionalMode
 
 	// gcMarkWorkerIdleMode indicates that a P is running the mark
@@ -396,23 +414,18 @@
 	assistBytesPerWork float64
 
 	// fractionalUtilizationGoal is the fraction of wall clock
-	// time that should be spent in the fractional mark worker.
-	// For example, if the overall mark utilization goal is 25%
-	// and GOMAXPROCS is 6, one P will be a dedicated mark worker
-	// and this will be set to 0.5 so that 50% of the time some P
-	// is in a fractional mark worker. This is computed at the
-	// beginning of each cycle.
+	// time that should be spent in the fractional mark worker on
+	// each P that isn't running a dedicated worker.
+	//
+	// For example, if the utilization goal is 25% and there are
+	// no dedicated workers, this will be 0.25. If there goal is
+	// 25%, there is one dedicated worker, and GOMAXPROCS is 5,
+	// this will be 0.05 to make up the missing 5%.
+	//
+	// If this is zero, no fractional workers are needed.
 	fractionalUtilizationGoal float64
 
 	_ [sys.CacheLineSize]byte
-
-	// fractionalMarkWorkersNeeded is the number of fractional
-	// mark workers that need to be started. This is either 0 or
-	// 1. This is potentially updated atomically at every
-	// scheduling point (hence it gets its own cache line).
-	fractionalMarkWorkersNeeded int64
-
-	_ [sys.CacheLineSize]byte
 }
 
 // startCycle resets the GC controller's state and computes estimates
@@ -453,23 +466,33 @@
 		memstats.next_gc = memstats.heap_live + 1024*1024
 	}
 
-	// Compute the total mark utilization goal and divide it among
-	// dedicated and fractional workers.
-	totalUtilizationGoal := float64(gomaxprocs) * gcGoalUtilization
-	c.dedicatedMarkWorkersNeeded = int64(totalUtilizationGoal)
-	c.fractionalUtilizationGoal = totalUtilizationGoal - float64(c.dedicatedMarkWorkersNeeded)
-	if c.fractionalUtilizationGoal > 0 {
-		c.fractionalMarkWorkersNeeded = 1
+	// Compute the background mark utilization goal. In general,
+	// this may not come out exactly. We round the number of
+	// dedicated workers so that the utilization is closest to
+	// 25%. For small GOMAXPROCS, this would introduce too much
+	// error, so we add fractional workers in that case.
+	totalUtilizationGoal := float64(gomaxprocs) * gcBackgroundUtilization
+	c.dedicatedMarkWorkersNeeded = int64(totalUtilizationGoal + 0.5)
+	utilError := float64(c.dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1
+	const maxUtilError = 0.3
+	if utilError < -maxUtilError || utilError > maxUtilError {
+		// Rounding put us more than 30% off our goal. With
+		// gcBackgroundUtilization of 25%, this happens for
+		// GOMAXPROCS<=3 or GOMAXPROCS=6. Enable fractional
+		// workers to compensate.
+		if float64(c.dedicatedMarkWorkersNeeded) > totalUtilizationGoal {
+			// Too many dedicated workers.
+			c.dedicatedMarkWorkersNeeded--
+		}
+		c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(c.dedicatedMarkWorkersNeeded)) / float64(gomaxprocs)
 	} else {
-		c.fractionalMarkWorkersNeeded = 0
+		c.fractionalUtilizationGoal = 0
 	}
 
 	// Clear per-P state
-	for _, p := range &allp {
-		if p == nil {
-			break
-		}
+	for _, p := range allp {
 		p.gcAssistTime = 0
+		p.gcFractionalMarkTime = 0
 	}
 
 	// Compute initial values for controls that are updated
@@ -482,7 +505,7 @@
 			work.initialHeapLive>>20, "->",
 			memstats.next_gc>>20, " MB)",
 			" workers=", c.dedicatedMarkWorkersNeeded,
-			"+", c.fractionalMarkWorkersNeeded, "\n")
+			"+", c.fractionalUtilizationGoal, "\n")
 	}
 }
 
@@ -495,47 +518,73 @@
 // is when assists are enabled and the necessary statistics are
 // available).
 func (c *gcControllerState) revise() {
-	// Compute the expected scan work remaining.
+	gcpercent := gcpercent
+	if gcpercent < 0 {
+		// If GC is disabled but we're running a forced GC,
+		// act like GOGC is huge for the below calculations.
+		gcpercent = 100000
+	}
+	live := atomic.Load64(&memstats.heap_live)
+
+	var heapGoal, scanWorkExpected int64
+	if live <= memstats.next_gc {
+		// We're under the soft goal. Pace GC to complete at
+		// next_gc assuming the heap is in steady-state.
+		heapGoal = int64(memstats.next_gc)
+
+		// Compute the expected scan work remaining.
+		//
+		// This is estimated based on the expected
+		// steady-state scannable heap. For example, with
+		// GOGC=100, only half of the scannable heap is
+		// expected to be live, so that's what we target.
+		//
+		// (This is a float calculation to avoid overflowing on
+		// 100*heap_scan.)
+		scanWorkExpected = int64(float64(memstats.heap_scan) * 100 / float64(100+gcpercent))
+	} else {
+		// We're past the soft goal. Pace GC so that in the
+		// worst case it will complete by the hard goal.
+		const maxOvershoot = 1.1
+		heapGoal = int64(float64(memstats.next_gc) * maxOvershoot)
+
+		// Compute the upper bound on the scan work remaining.
+		scanWorkExpected = int64(memstats.heap_scan)
+	}
+
+	// Compute the remaining scan work estimate.
 	//
 	// Note that we currently count allocations during GC as both
 	// scannable heap (heap_scan) and scan work completed
-	// (scanWork), so this difference won't be changed by
-	// allocations during GC.
-	//
-	// This particular estimate is a strict upper bound on the
-	// possible remaining scan work for the current heap.
-	// You might consider dividing this by 2 (or by
-	// (100+GOGC)/100) to counter this over-estimation, but
-	// benchmarks show that this has almost no effect on mean
-	// mutator utilization, heap size, or assist time and it
-	// introduces the danger of under-estimating and letting the
-	// mutator outpace the garbage collector.
-	scanWorkExpected := int64(memstats.heap_scan) - c.scanWork
-	if scanWorkExpected < 1000 {
+	// (scanWork), so allocation will change this difference will
+	// slowly in the soft regime and not at all in the hard
+	// regime.
+	scanWorkRemaining := scanWorkExpected - c.scanWork
+	if scanWorkRemaining < 1000 {
 		// We set a somewhat arbitrary lower bound on
 		// remaining scan work since if we aim a little high,
 		// we can miss by a little.
 		//
 		// We *do* need to enforce that this is at least 1,
 		// since marking is racy and double-scanning objects
-		// may legitimately make the expected scan work
-		// negative.
-		scanWorkExpected = 1000
+		// may legitimately make the remaining scan work
+		// negative, even in the hard goal regime.
+		scanWorkRemaining = 1000
 	}
 
 	// Compute the heap distance remaining.
-	heapDistance := int64(memstats.next_gc) - int64(atomic.Load64(&memstats.heap_live))
-	if heapDistance <= 0 {
+	heapRemaining := heapGoal - int64(live)
+	if heapRemaining <= 0 {
 		// This shouldn't happen, but if it does, avoid
 		// dividing by zero or setting the assist negative.
-		heapDistance = 1
+		heapRemaining = 1
 	}
 
 	// Compute the mutator assist ratio so by the time the mutator
 	// allocates the remaining heap bytes up to next_gc, it will
 	// have done (or stolen) the remaining amount of scan work.
-	c.assistWorkPerByte = float64(scanWorkExpected) / float64(heapDistance)
-	c.assistBytesPerWork = float64(heapDistance) / float64(scanWorkExpected)
+	c.assistWorkPerByte = float64(scanWorkRemaining) / float64(heapRemaining)
+	c.assistBytesPerWork = float64(heapRemaining) / float64(scanWorkRemaining)
 }
 
 // endCycle computes the trigger ratio for the next cycle.
@@ -569,7 +618,7 @@
 	assistDuration := nanotime() - c.markStartTime
 
 	// Assume background mark hit its utilization goal.
-	utilization := gcGoalUtilization
+	utilization := gcBackgroundUtilization
 	// Add assist utilization; avoid divide by zero.
 	if assistDuration > 0 {
 		utilization += float64(c.assistTime) / float64(assistDuration*int64(gomaxprocs))
@@ -688,51 +737,20 @@
 		// This P is now dedicated to marking until the end of
 		// the concurrent mark phase.
 		_p_.gcMarkWorkerMode = gcMarkWorkerDedicatedMode
+	} else if c.fractionalUtilizationGoal == 0 {
+		// No need for fractional workers.
+		return nil
 	} else {
-		if !decIfPositive(&c.fractionalMarkWorkersNeeded) {
-			// No more workers are need right now.
+		// Is this P behind on the fractional utilization
+		// goal?
+		//
+		// This should be kept in sync with pollFractionalWorkerExit.
+		delta := nanotime() - gcController.markStartTime
+		if delta > 0 && float64(_p_.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
+			// Nope. No need to run a fractional worker.
 			return nil
 		}
-
-		// This P has picked the token for the fractional worker.
-		// Is the GC currently under or at the utilization goal?
-		// If so, do more work.
-		//
-		// We used to check whether doing one time slice of work
-		// would remain under the utilization goal, but that has the
-		// effect of delaying work until the mutator has run for
-		// enough time slices to pay for the work. During those time
-		// slices, write barriers are enabled, so the mutator is running slower.
-		// Now instead we do the work whenever we're under or at the
-		// utilization work and pay for it by letting the mutator run later.
-		// This doesn't change the overall utilization averages, but it
-		// front loads the GC work so that the GC finishes earlier and
-		// write barriers can be turned off sooner, effectively giving
-		// the mutator a faster machine.
-		//
-		// The old, slower behavior can be restored by setting
-		//	gcForcePreemptNS = forcePreemptNS.
-		const gcForcePreemptNS = 0
-
-		// TODO(austin): We could fast path this and basically
-		// eliminate contention on c.fractionalMarkWorkersNeeded by
-		// precomputing the minimum time at which it's worth
-		// next scheduling the fractional worker. Then Ps
-		// don't have to fight in the window where we've
-		// passed that deadline and no one has started the
-		// worker yet.
-		//
-		// TODO(austin): Shorter preemption interval for mark
-		// worker to improve fairness and give this
-		// finer-grained control over schedule?
-		now := nanotime() - gcController.markStartTime
-		then := now + gcForcePreemptNS
-		timeUsed := c.fractionalMarkTime + gcForcePreemptNS
-		if then > 0 && float64(timeUsed)/float64(then) > c.fractionalUtilizationGoal {
-			// Nope, we'd overshoot the utilization goal
-			atomic.Xaddint64(&c.fractionalMarkWorkersNeeded, +1)
-			return nil
-		}
+		// Run a fractional worker.
 		_p_.gcMarkWorkerMode = gcMarkWorkerFractionalMode
 	}
 
@@ -745,6 +763,24 @@
 	return gp
 }
 
+// pollFractionalWorkerExit returns true if a fractional mark worker
+// should self-preempt. It assumes it is called from the fractional
+// worker.
+func pollFractionalWorkerExit() bool {
+	// This should be kept in sync with the fractional worker
+	// scheduler logic in findRunnableGCWorker.
+	now := nanotime()
+	delta := now - gcController.markStartTime
+	if delta <= 0 {
+		return true
+	}
+	p := getg().m.p.ptr()
+	selfTime := p.gcFractionalMarkTime + (now - p.gcMarkWorkerStartTime)
+	// Add some slack to the utilization goal so that the
+	// fractional worker isn't behind again the instant it exits.
+	return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal
+}
+
 // gcSetTriggerRatio sets the trigger ratio and updates everything
 // derived from it: the absolute trigger, the heap goal, mark pacing,
 // and sweep pacing.
@@ -859,9 +895,22 @@
 	}
 }
 
-// gcGoalUtilization is the goal CPU utilization for background
+// gcGoalUtilization is the goal CPU utilization for
 // marking as a fraction of GOMAXPROCS.
-const gcGoalUtilization = 0.25
+const gcGoalUtilization = 0.30
+
+// gcBackgroundUtilization is the fixed CPU utilization for background
+// marking. It must be <= gcGoalUtilization. The difference between
+// gcGoalUtilization and gcBackgroundUtilization will be made up by
+// mark assists. The scheduler will aim to use within 50% of this
+// goal.
+//
+// Setting this to < gcGoalUtilization avoids saturating the trigger
+// feedback controller when there are no assists, which allows it to
+// better control CPU and heap growth. However, the larger the gap,
+// the more mutator assists are expected to happen, which impact
+// mutator latency.
+const gcBackgroundUtilization = 0.25
 
 // gcCreditSlack is the amount of scan work credit that can can
 // accumulate locally before updating gcController.scanWork and,
@@ -1158,7 +1207,7 @@
 	if t.kind == gcTriggerAlways {
 		return true
 	}
-	if gcphase != _GCoff || gcpercent < 0 {
+	if gcphase != _GCoff {
 		return false
 	}
 	switch t.kind {
@@ -1169,6 +1218,9 @@
 		// own write.
 		return memstats.heap_live >= memstats.gc_trigger
 	case gcTriggerTime:
+		if gcpercent < 0 {
+			return false
+		}
 		lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
 		return lastgc != 0 && t.now-lastgc > forcegcperiod
 	case gcTriggerCycle:
@@ -1235,7 +1287,7 @@
 		}
 	}
 
-	// Ok, we're doing it!  Stop everybody else
+	// Ok, we're doing it! Stop everybody else
 	semacquire(&worldsema)
 
 	if trace.enabled {
@@ -1248,7 +1300,12 @@
 
 	gcResetMarkState()
 
-	work.stwprocs, work.maxprocs = gcprocs(), gomaxprocs
+	work.stwprocs, work.maxprocs = gomaxprocs, gomaxprocs
+	if work.stwprocs > ncpu {
+		// This is used to compute CPU time of the STW phases,
+		// so it can't be more than ncpu, even if GOMAXPROCS is.
+		work.stwprocs = ncpu
+	}
 	work.heap0 = atomic.Load64(&memstats.heap_live)
 	work.pauseNS = 0
 	work.mode = mode
@@ -1256,6 +1313,9 @@
 	now := nanotime()
 	work.tSweepTerm = now
 	work.pauseStart = now
+	if trace.enabled {
+		traceGCSTWStart(1)
+	}
 	systemstack(stopTheWorldWithSema)
 	// Finish sweep before we start concurrent scan.
 	systemstack(func() {
@@ -1308,11 +1368,17 @@
 		gcController.markStartTime = now
 
 		// Concurrent mark.
-		systemstack(startTheWorldWithSema)
-		now = nanotime()
+		systemstack(func() {
+			now = startTheWorldWithSema(trace.enabled)
+		})
 		work.pauseNS += now - work.pauseStart
 		work.tMark = now
 	} else {
+		if trace.enabled {
+			// Switch to mark termination STW.
+			traceGCSTWDone()
+			traceGCSTWStart(0)
+		}
 		t := nanotime()
 		work.tMark, work.tMarkTerm = t, t
 		work.heapGoal = work.heap0
@@ -1355,7 +1421,8 @@
 	// TODO(austin): Should dedicated workers keep an eye on this
 	// and exit gcDrain promptly?
 	atomic.Xaddint64(&gcController.dedicatedMarkWorkersNeeded, -0xffffffff)
-	atomic.Xaddint64(&gcController.fractionalMarkWorkersNeeded, -0xffffffff)
+	prevFractionalGoal := gcController.fractionalUtilizationGoal
+	gcController.fractionalUtilizationGoal = 0
 
 	if !gcBlackenPromptly {
 		// Transition from mark 1 to mark 2.
@@ -1382,6 +1449,7 @@
 			// workers have exited their loop so we can
 			// start new mark 2 workers.
 			forEachP(func(_p_ *p) {
+				wbBufFlush1(_p_)
 				_p_.gcw.dispose()
 			})
 		})
@@ -1398,7 +1466,7 @@
 
 		// Now we can start up mark 2 workers.
 		atomic.Xaddint64(&gcController.dedicatedMarkWorkersNeeded, 0xffffffff)
-		atomic.Xaddint64(&gcController.fractionalMarkWorkersNeeded, 0xffffffff)
+		gcController.fractionalUtilizationGoal = prevFractionalGoal
 
 		incnwait := atomic.Xadd(&work.nwait, +1)
 		if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
@@ -1413,6 +1481,9 @@
 		work.tMarkTerm = now
 		work.pauseStart = now
 		getg().m.preemptoff = "gcing"
+		if trace.enabled {
+			traceGCSTWStart(0)
+		}
 		systemstack(stopTheWorldWithSema)
 		// The gcphase is _GCmark, it will transition to _GCmarktermination
 		// below. The important thing is that the wb remains active until
@@ -1573,7 +1644,7 @@
 	// so events don't leak into the wrong cycle.
 	mProf_NextCycle()
 
-	systemstack(startTheWorldWithSema)
+	systemstack(func() { startTheWorldWithSema(true) })
 
 	// Flush the heap profile so we can start a new cycle next GC.
 	// This is relatively expensive, so we don't do it with the
@@ -1647,10 +1718,7 @@
 func gcBgMarkStartWorkers() {
 	// Background marking is performed by per-P G's. Ensure that
 	// each P has a background GC G.
-	for _, p := range &allp {
-		if p == nil || p.status == _Pdead {
-			break
-		}
+	for _, p := range allp {
 		if p.gcBgMarkWorker == 0 {
 			go gcBgMarkWorker(p)
 			notetsleepg(&work.bgMarkReady, -1)
@@ -1750,6 +1818,7 @@
 		}
 
 		startTime := nanotime()
+		_p_.gcMarkWorkerStartTime = startTime
 
 		decnwait := atomic.Xadd(&work.nwait, -1)
 		if decnwait == work.nproc {
@@ -1791,7 +1860,7 @@
 				// without preemption.
 				gcDrain(&_p_.gcw, gcDrainNoBlock|gcDrainFlushBgCredit)
 			case gcMarkWorkerFractionalMode:
-				gcDrain(&_p_.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit)
+				gcDrain(&_p_.gcw, gcDrainFractional|gcDrainUntilPreempt|gcDrainFlushBgCredit)
 			case gcMarkWorkerIdleMode:
 				gcDrain(&_p_.gcw, gcDrainIdle|gcDrainUntilPreempt|gcDrainFlushBgCredit)
 			}
@@ -1816,7 +1885,7 @@
 			atomic.Xaddint64(&gcController.dedicatedMarkWorkersNeeded, 1)
 		case gcMarkWorkerFractionalMode:
 			atomic.Xaddint64(&gcController.fractionalMarkTime, duration)
-			atomic.Xaddint64(&gcController.fractionalMarkWorkersNeeded, 1)
+			atomic.Xaddint64(&_p_.gcFractionalMarkTime, duration)
 		case gcMarkWorkerIdleMode:
 			atomic.Xaddint64(&gcController.idleMarkTime, duration)
 		}
@@ -1914,10 +1983,6 @@
 		work.helperDrainBlock = true
 	}
 
-	if trace.enabled {
-		traceGCScanStart()
-	}
-
 	if work.nproc > 1 {
 		noteclear(&work.alldone)
 		helpgc(int32(work.nproc))
@@ -1951,8 +2016,8 @@
 
 	// Double-check that all gcWork caches are empty. This should
 	// be ensured by mark 2 before we enter mark termination.
-	for i := 0; i < int(gomaxprocs); i++ {
-		gcw := &allp[i].gcw
+	for _, p := range allp {
+		gcw := &p.gcw
 		if !gcw.empty() {
 			throw("P has cached GC work at end of mark termination")
 		}
@@ -1961,10 +2026,6 @@
 		}
 	}
 
-	if trace.enabled {
-		traceGCScanDone()
-	}
-
 	cachestats()
 
 	// Update the marked heap stat.
@@ -2094,18 +2155,19 @@
 	unlock(&sched.deferlock)
 }
 
-// Timing
-
-//go:nowritebarrier
+// gchelper runs mark termination tasks on Ps other than the P
+// coordinating mark termination.
+//
+// The caller is responsible for ensuring that this has a P to run on,
+// even though it's running during STW. Because of this, it's allowed
+// to have write barriers.
+//
+//go:yeswritebarrierrec
 func gchelper() {
 	_g_ := getg()
 	_g_.m.traceback = 2
 	gchelperstart()
 
-	if trace.enabled {
-		traceGCScanStart()
-	}
-
 	// Parallel mark over GC roots and heap
 	if gcphase == _GCmarktermination {
 		gcw := &_g_.m.p.ptr().gcw
@@ -2117,10 +2179,6 @@
 		gcw.dispose()
 	}
 
-	if trace.enabled {
-		traceGCScanDone()
-	}
-
 	nproc := atomic.Load(&work.nproc) // work.nproc can change right after we increment work.ndone
 	if atomic.Xadd(&work.ndone, +1) == nproc-1 {
 		notewakeup(&work.alldone)
@@ -2139,6 +2197,8 @@
 	}
 }
 
+// Timing
+
 // itoaDiv formats val/(10**dec) into buf.
 func itoaDiv(buf []byte, val uint64, dec int) []byte {
 	i := len(buf) - 1
diff --git a/src/runtime/mgclarge.go b/src/runtime/mgclarge.go
index 757e88d..fe437bf 100644
--- a/src/runtime/mgclarge.go
+++ b/src/runtime/mgclarge.go
@@ -164,11 +164,10 @@
 	}
 }
 
-func (root *mTreap) removeNode(t *treapNode) *mspan {
+func (root *mTreap) removeNode(t *treapNode) {
 	if t.spanKey.npages != t.npagesKey {
 		throw("span and treap node npages do not match")
 	}
-	result := t.spanKey
 
 	// Rotate t down to be leaf of tree for removal, respecting priorities.
 	for t.right != nil || t.left != nil {
@@ -192,7 +191,6 @@
 	t.spanKey = nil
 	t.npagesKey = 0
 	mheap_.treapalloc.free(unsafe.Pointer(t))
-	return result
 }
 
 // remove searches for, finds, removes from the treap, and returns the smallest
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 9029d19..5664390 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -34,13 +34,13 @@
 	// span base.
 	maxObletBytes = 128 << 10
 
-	// idleCheckThreshold specifies how many units of work to do
-	// between run queue checks in an idle worker. Assuming a scan
+	// drainCheckThreshold specifies how many units of work to do
+	// between self-preemption checks in gcDrain. Assuming a scan
 	// rate of 1 MB/ms, this is ~100 µs. Lower values have higher
 	// overhead in the scan loop (the scheduler check may perform
 	// a syscall, so its overhead is nontrivial). Higher values
 	// make the system less responsive to incoming work.
-	idleCheckThreshold = 100000
+	drainCheckThreshold = 100000
 )
 
 // gcMarkRootPrepare queues root scanning jobs (stacks, globals, and
@@ -770,6 +770,13 @@
 		shrinkstack(gp)
 	}
 
+	// Scan the saved context register. This is effectively a live
+	// register that gets moved back and forth between the
+	// register and sched.ctxt without a write barrier.
+	if gp.sched.ctxt != nil {
+		scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), sys.PtrSize, &oneptrmask[0], gcw)
+	}
+
 	// Scan the stack.
 	var cache pcvalueCache
 	scanframe := func(frame *stkframe, unused unsafe.Pointer) bool {
@@ -861,6 +868,7 @@
 	gcDrainNoBlock
 	gcDrainFlushBgCredit
 	gcDrainIdle
+	gcDrainFractional
 
 	// gcDrainBlock means neither gcDrainUntilPreempt or
 	// gcDrainNoBlock. It is the default, but callers should use
@@ -877,6 +885,10 @@
 // If flags&gcDrainIdle != 0, gcDrain returns when there is other work
 // to do. This implies gcDrainNoBlock.
 //
+// If flags&gcDrainFractional != 0, gcDrain self-preempts when
+// pollFractionalWorkerExit() returns true. This implies
+// gcDrainNoBlock.
+//
 // If flags&gcDrainNoBlock != 0, gcDrain returns as soon as it is
 // unable to get more work. Otherwise, it will block until all
 // blocking calls are blocked in gcDrain.
@@ -893,14 +905,24 @@
 
 	gp := getg().m.curg
 	preemptible := flags&gcDrainUntilPreempt != 0
-	blocking := flags&(gcDrainUntilPreempt|gcDrainIdle|gcDrainNoBlock) == 0
+	blocking := flags&(gcDrainUntilPreempt|gcDrainIdle|gcDrainFractional|gcDrainNoBlock) == 0
 	flushBgCredit := flags&gcDrainFlushBgCredit != 0
 	idle := flags&gcDrainIdle != 0
 
 	initScanWork := gcw.scanWork
-	// idleCheck is the scan work at which to perform the next
-	// idle check with the scheduler.
-	idleCheck := initScanWork + idleCheckThreshold
+
+	// checkWork is the scan work before performing the next
+	// self-preempt check.
+	checkWork := int64(1<<63 - 1)
+	var check func() bool
+	if flags&(gcDrainIdle|gcDrainFractional) != 0 {
+		checkWork = initScanWork + drainCheckThreshold
+		if idle {
+			check = pollWork
+		} else if flags&gcDrainFractional != 0 {
+			check = pollFractionalWorkerExit
+		}
+	}
 
 	// Drain root marking jobs.
 	if work.markrootNext < work.markrootJobs {
@@ -910,7 +932,7 @@
 				break
 			}
 			markroot(gcw, job)
-			if idle && pollWork() {
+			if check != nil && check() {
 				goto done
 			}
 		}
@@ -951,12 +973,12 @@
 				gcFlushBgCredit(gcw.scanWork - initScanWork)
 				initScanWork = 0
 			}
-			idleCheck -= gcw.scanWork
+			checkWork -= gcw.scanWork
 			gcw.scanWork = 0
 
-			if idle && idleCheck <= 0 {
-				idleCheck += idleCheckThreshold
-				if pollWork() {
+			if checkWork <= 0 {
+				checkWork += drainCheckThreshold
+				if check != nil && check() {
 					break
 				}
 			}
@@ -1212,6 +1234,9 @@
 // obj is the start of an object with mark mbits.
 // If it isn't already marked, mark it and enqueue into gcw.
 // base and off are for debugging only and could be removed.
+//
+// See also wbBufFlush1, which partially duplicates this logic.
+//
 //go:nowritebarrierrec
 func greyobject(obj, base, off uintptr, hbits heapBits, span *mspan, gcw *gcWork, objIndex uintptr) {
 	// obj should be start of allocation, and so must be at least pointer-aligned.
@@ -1356,10 +1381,7 @@
 //
 // The world must be stopped.
 func gcMarkTinyAllocs() {
-	for _, p := range &allp {
-		if p == nil || p.status == _Pdead {
-			break
-		}
+	for _, p := range allp {
 		c := p.mcache
 		if c == nil || c.tiny == 0 {
 			continue
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index 461679b..c6634fc 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -85,6 +85,13 @@
 	scanWork int64
 }
 
+// Most of the methods of gcWork are go:nowritebarrierrec because the
+// write barrier itself can invoke gcWork methods but the methods are
+// not generally re-entrant. Hence, if a gcWork method invoked the
+// write barrier while the gcWork was in an inconsistent state, and
+// the write barrier in turn invoked a gcWork method, it could
+// permanently corrupt the gcWork.
+
 func (w *gcWork) init() {
 	w.wbuf1 = getempty()
 	wbuf2 := trygetfull()
@@ -96,7 +103,7 @@
 
 // put enqueues a pointer for the garbage collector to trace.
 // obj must point to the beginning of a heap object or an oblet.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) put(obj uintptr) {
 	flushed := false
 	wbuf := w.wbuf1
@@ -129,7 +136,7 @@
 
 // putFast does a put and returns true if it can be done quickly
 // otherwise it returns false and the caller needs to call put.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) putFast(obj uintptr) bool {
 	wbuf := w.wbuf1
 	if wbuf == nil {
@@ -143,12 +150,45 @@
 	return true
 }
 
+// putBatch performs a put on every pointer in obj. See put for
+// constraints on these pointers.
+//
+//go:nowritebarrierrec
+func (w *gcWork) putBatch(obj []uintptr) {
+	if len(obj) == 0 {
+		return
+	}
+
+	flushed := false
+	wbuf := w.wbuf1
+	if wbuf == nil {
+		w.init()
+		wbuf = w.wbuf1
+	}
+
+	for len(obj) > 0 {
+		for wbuf.nobj == len(wbuf.obj) {
+			putfull(wbuf)
+			w.wbuf1, w.wbuf2 = w.wbuf2, getempty()
+			wbuf = w.wbuf1
+			flushed = true
+		}
+		n := copy(wbuf.obj[wbuf.nobj:], obj)
+		wbuf.nobj += n
+		obj = obj[n:]
+	}
+
+	if flushed && gcphase == _GCmark {
+		gcController.enlistWorker()
+	}
+}
+
 // tryGet dequeues a pointer for the garbage collector to trace.
 //
 // If there are no pointers remaining in this gcWork or in the global
 // queue, tryGet returns 0.  Note that there may still be pointers in
 // other gcWork instances or other caches.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) tryGet() uintptr {
 	wbuf := w.wbuf1
 	if wbuf == nil {
@@ -177,7 +217,7 @@
 // tryGetFast dequeues a pointer for the garbage collector to trace
 // if one is readily available. Otherwise it returns 0 and
 // the caller is expected to call tryGet().
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) tryGetFast() uintptr {
 	wbuf := w.wbuf1
 	if wbuf == nil {
@@ -194,7 +234,7 @@
 // get dequeues a pointer for the garbage collector to trace, blocking
 // if necessary to ensure all pointers from all queues and caches have
 // been retrieved.  get returns 0 if there are no pointers remaining.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) get() uintptr {
 	wbuf := w.wbuf1
 	if wbuf == nil {
@@ -228,7 +268,7 @@
 // GC can inspect them. This helps reduce the mutator's
 // ability to hide pointers during the concurrent mark phase.
 //
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) dispose() {
 	if wbuf := w.wbuf1; wbuf != nil {
 		if wbuf.nobj == 0 {
@@ -262,7 +302,7 @@
 
 // balance moves some work that's cached in this gcWork back on the
 // global queue.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) balance() {
 	if w.wbuf1 == nil {
 		return
@@ -282,7 +322,7 @@
 }
 
 // empty returns true if w has no mark work available.
-//go:nowritebarrier
+//go:nowritebarrierrec
 func (w *gcWork) empty() bool {
 	return w.wbuf1 == nil || (w.wbuf1.nobj == 0 && w.wbuf2.nobj == 0)
 }
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 893587e..12cf29a 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -56,6 +56,12 @@
 	// Internal pages map to an arbitrary span.
 	// For pages that have never been allocated, spans entries are nil.
 	//
+	// Modifications are protected by mheap.lock. Reads can be
+	// performed without locking, but ONLY from indexes that are
+	// known to contain in-use or stack spans. This means there
+	// must not be a safe-point between establishing that an
+	// address is live and looking it up in the spans array.
+	//
 	// This is backed by a reserved region of the address space so
 	// it can grow without moving. The memory up to len(spans) is
 	// mapped. cap(spans) indicates the total reserved memory.
@@ -154,6 +160,8 @@
 	specialfinalizeralloc fixalloc // allocator for specialfinalizer*
 	specialprofilealloc   fixalloc // allocator for specialprofile*
 	speciallock           mutex    // lock for special record allocators.
+
+	unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF
 }
 
 var mheap_ mheap
@@ -311,6 +319,17 @@
 	return
 }
 
+// recordspan adds a newly allocated span to h.allspans.
+//
+// This only happens the first time a span is allocated from
+// mheap.spanalloc (it is not called when a span is reused).
+//
+// Write barriers are disallowed here because it can be called from
+// gcWork when allocating new workbufs. However, because it's an
+// indirect call from the fixalloc initializer, the compiler can't see
+// this.
+//
+//go:nowritebarrierrec
 func recordspan(vh unsafe.Pointer, p unsafe.Pointer) {
 	h := (*mheap)(vh)
 	s := (*mspan)(p)
@@ -331,12 +350,13 @@
 			copy(new, h.allspans)
 		}
 		oldAllspans := h.allspans
-		h.allspans = new
+		*(*notInHeapSlice)(unsafe.Pointer(&h.allspans)) = *(*notInHeapSlice)(unsafe.Pointer(&new))
 		if len(oldAllspans) != 0 {
 			sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys)
 		}
 	}
-	h.allspans = append(h.allspans, s)
+	h.allspans = h.allspans[:len(h.allspans)+1]
+	h.allspans[len(h.allspans)-1] = s
 }
 
 // A spanClass represents the size class and noscan-ness of a span.
@@ -857,7 +877,7 @@
 // Large spans have a minimum size of 1MByte. The maximum number of large spans to support
 // 1TBytes is 1 million, experimentation using random sizes indicates that the depth of
 // the tree is less that 2x that of a perfectly balanced tree. For 1TByte can be referenced
-// by a perfectly balanced tree with a a depth of 20. Twice that is an acceptable 40.
+// by a perfectly balanced tree with a depth of 20. Twice that is an acceptable 40.
 func (h *mheap) isLargeSpan(npages uintptr) bool {
 	return npages >= uintptr(len(h.free))
 }
@@ -1123,34 +1143,35 @@
 
 	var sumreleased uintptr
 	for s := list.first; s != nil; s = s.next {
-		if (now-uint64(s.unusedsince)) > limit && s.npreleased != s.npages {
-			start := s.base()
-			end := start + s.npages<<_PageShift
-			if physPageSize > _PageSize {
-				// We can only release pages in
-				// physPageSize blocks, so round start
-				// and end in. (Otherwise, madvise
-				// will round them *out* and release
-				// more memory than we want.)
-				start = (start + physPageSize - 1) &^ (physPageSize - 1)
-				end &^= physPageSize - 1
-				if end <= start {
-					// start and end don't span a
-					// whole physical page.
-					continue
-				}
-			}
-			len := end - start
-
-			released := len - (s.npreleased << _PageShift)
-			if physPageSize > _PageSize && released == 0 {
+		if (now-uint64(s.unusedsince)) <= limit || s.npreleased == s.npages {
+			continue
+		}
+		start := s.base()
+		end := start + s.npages<<_PageShift
+		if physPageSize > _PageSize {
+			// We can only release pages in
+			// physPageSize blocks, so round start
+			// and end in. (Otherwise, madvise
+			// will round them *out* and release
+			// more memory than we want.)
+			start = (start + physPageSize - 1) &^ (physPageSize - 1)
+			end &^= physPageSize - 1
+			if end <= start {
+				// start and end don't span a
+				// whole physical page.
 				continue
 			}
-			memstats.heap_released += uint64(released)
-			sumreleased += released
-			s.npreleased = len >> _PageShift
-			sysUnused(unsafe.Pointer(start), len)
 		}
+		len := end - start
+
+		released := len - (s.npreleased << _PageShift)
+		if physPageSize > _PageSize && released == 0 {
+			continue
+		}
+		memstats.heap_released += uint64(released)
+		sumreleased += released
+		s.npreleased = len >> _PageShift
+		sysUnused(unsafe.Pointer(start), len)
 	}
 	return sumreleased
 }
diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go
index d15f1f7..fb7cbc2 100644
--- a/src/runtime/mkduff.go
+++ b/src/runtime/mkduff.go
@@ -70,7 +70,7 @@
 		fmt.Fprintln(w, "\tMOVUPS\tX0,16(DI)")
 		fmt.Fprintln(w, "\tMOVUPS\tX0,32(DI)")
 		fmt.Fprintln(w, "\tMOVUPS\tX0,48(DI)")
-		fmt.Fprintln(w, "\tADDQ\t$64,DI")
+		fmt.Fprintln(w, "\tLEAQ\t64(DI),DI") // We use lea instead of add, to avoid clobbering flags
 		fmt.Fprintln(w)
 	}
 	fmt.Fprintln(w, "\tRET")
@@ -151,12 +151,13 @@
 
 func zeroARM64(w io.Writer) {
 	// ZR: always zero
-	// R16 (aka REGRT1): ptr to memory to be zeroed - 8
+	// R16 (aka REGRT1): ptr to memory to be zeroed
 	// On return, R16 points to the last zeroed dword.
 	fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT, $-8-0")
-	for i := 0; i < 128; i++ {
-		fmt.Fprintln(w, "\tMOVD.W\tZR, 8(R16)")
+	for i := 0; i < 63; i++ {
+		fmt.Fprintln(w, "\tSTP.P\t(ZR, ZR), 16(R16)")
 	}
+	fmt.Fprintln(w, "\tSTP\t(ZR, ZR), (R16)")
 	fmt.Fprintln(w, "\tRET")
 }
 
diff --git a/src/runtime/mksizeclasses.go b/src/runtime/mksizeclasses.go
index 0cb2b33..b146dbc 100644
--- a/src/runtime/mksizeclasses.go
+++ b/src/runtime/mksizeclasses.go
@@ -24,8 +24,8 @@
 // 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.
+// For really small sizes, alignment constraints force the
+// overhead higher.
 
 package main
 
@@ -242,15 +242,18 @@
 }
 
 func printComment(w io.Writer, classes []class) {
-	fmt.Fprintf(w, "// %-5s  %-9s  %-10s  %-7s  %-11s\n", "class", "bytes/obj", "bytes/span", "objects", "waste bytes")
+	fmt.Fprintf(w, "// %-5s  %-9s  %-10s  %-7s  %-10s  %-9s\n", "class", "bytes/obj", "bytes/span", "objects", "tail waste", "max waste")
+	prevSize := 0
 	for i, c := range classes {
 		if i == 0 {
 			continue
 		}
 		spanSize := c.npages * pageSize
 		objects := spanSize / c.size
-		waste := spanSize - c.size*(spanSize/c.size)
-		fmt.Fprintf(w, "// %5d  %9d  %10d  %7d  %11d\n", i, c.size, spanSize, objects, waste)
+		tailWaste := spanSize - c.size*(spanSize/c.size)
+		maxWaste := float64((c.size-prevSize-1)*objects+tailWaste) / float64(spanSize)
+		prevSize = c.size
+		fmt.Fprintf(w, "// %5d  %9d  %10d  %7d  %10d  %8.2f%%\n", i, c.size, spanSize, objects, tailWaste, 100*maxWaste)
 	}
 	fmt.Fprintf(w, "\n")
 }
diff --git a/src/runtime/mmap.go b/src/runtime/mmap.go
index 62f3780..e1333c6 100644
--- a/src/runtime/mmap.go
+++ b/src/runtime/mmap.go
@@ -16,7 +16,8 @@
 // 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.
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+// The err result is an OS error code such as ENOMEM.
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
 
 // munmap calls the munmap system call. It is implemented in assembly.
 func munmap(addr unsafe.Pointer, n uintptr)
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go
index 2bd09b6..259473c 100644
--- a/src/runtime/mprof.go
+++ b/src/runtime/mprof.go
@@ -596,7 +596,7 @@
 	r.AllocObjects = int64(mp.active.allocs)
 	r.FreeObjects = int64(mp.active.frees)
 	if raceenabled {
-		racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(unsafe.Pointer(&r)), funcPC(MemProfile))
+		racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), funcPC(MemProfile))
 	}
 	if msanenabled {
 		msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
@@ -644,7 +644,7 @@
 			r.Count = bp.count
 			r.Cycles = bp.cycles
 			if raceenabled {
-				racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(unsafe.Pointer(&p)), funcPC(BlockProfile))
+				racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), funcPC(BlockProfile))
 			}
 			if msanenabled {
 				msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
@@ -741,7 +741,7 @@
 
 		// Save current goroutine.
 		sp := getcallersp(unsafe.Pointer(&p))
-		pc := getcallerpc(unsafe.Pointer(&p))
+		pc := getcallerpc()
 		systemstack(func() {
 			saveg(pc, sp, gp, &r[0])
 		})
@@ -786,7 +786,7 @@
 	if len(buf) > 0 {
 		gp := getg()
 		sp := getcallersp(unsafe.Pointer(&buf))
-		pc := getcallerpc(unsafe.Pointer(&buf))
+		pc := getcallerpc()
 		systemstack(func() {
 			g0 := getg()
 			// Force traceback=1 to override GOTRACEBACK setting,
@@ -826,7 +826,7 @@
 	}
 	if gp.m.curg == nil || gp == gp.m.curg {
 		goroutineheader(gp)
-		pc := getcallerpc(unsafe.Pointer(&p))
+		pc := getcallerpc()
 		sp := getcallersp(unsafe.Pointer(&p))
 		systemstack(func() {
 			traceback(pc, sp, 0, gp)
@@ -846,7 +846,7 @@
 	gp.m.traceback = 2
 	print("tracefree(", p, ", ", hex(size), ")\n")
 	goroutineheader(gp)
-	pc := getcallerpc(unsafe.Pointer(&p))
+	pc := getcallerpc()
 	sp := getcallersp(unsafe.Pointer(&p))
 	systemstack(func() {
 		traceback(pc, sp, 0, gp)
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index 1cb44a1..e6f2f00 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -262,7 +262,7 @@
 	// can only be used for other objects of roughly the same
 	// size.
 	//
-	// HeapInuse minus HeapAlloc esimates the amount of memory
+	// HeapInuse minus HeapAlloc estimates the amount of memory
 	// that has been dedicated to particular size classes, but is
 	// not currently being used. This is an upper bound on
 	// fragmentation, but in general this memory can be reused
@@ -589,12 +589,13 @@
 	memstats.heap_objects = memstats.nmalloc - memstats.nfree
 }
 
+// cachestats flushes all mcache stats.
+//
+// The world must be stopped.
+//
 //go:nowritebarrier
 func cachestats() {
-	for _, p := range &allp {
-		if p == nil {
-			break
-		}
+	for _, p := range allp {
 		c := p.mcache
 		if c == nil {
 			continue
@@ -610,9 +611,6 @@
 //go:nowritebarrier
 func flushmcache(i int) {
 	p := allp[i]
-	if p == nil {
-		return
-	}
 	c := p.mcache
 	if c == nil {
 		return
@@ -666,7 +664,7 @@
 // overflow errors.
 //go:nosplit
 func mSysStatInc(sysStat *uint64, n uintptr) {
-	if sys.BigEndian != 0 {
+	if sys.BigEndian {
 		atomic.Xadd64(sysStat, int64(n))
 		return
 	}
@@ -680,7 +678,7 @@
 // mSysStatInc apply.
 //go:nosplit
 func mSysStatDec(sysStat *uint64, n uintptr) {
-	if sys.BigEndian != 0 {
+	if sys.BigEndian {
 		atomic.Xadd64(sysStat, -int64(n))
 		return
 	}
diff --git a/src/runtime/mwbbuf.go b/src/runtime/mwbbuf.go
new file mode 100644
index 0000000..4a2d1ad
--- /dev/null
+++ b/src/runtime/mwbbuf.go
@@ -0,0 +1,260 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This implements the write barrier buffer. The write barrier itself
+// is gcWriteBarrier and is implemented in assembly.
+//
+// The write barrier has a fast path and a slow path. The fast path
+// simply enqueues to a per-P write barrier buffer. It's written in
+// assembly and doesn't clobber any general purpose registers, so it
+// doesn't have the usual overheads of a Go call.
+//
+// When the buffer fills up, the write barrier invokes the slow path
+// (wbBufFlush) to flush the buffer to the GC work queues. In this
+// path, since the compiler didn't spill registers, we spill *all*
+// registers and disallow any GC safe points that could observe the
+// stack frame (since we don't know the types of the spilled
+// registers).
+
+package runtime
+
+import (
+	"runtime/internal/sys"
+	"unsafe"
+)
+
+// testSmallBuf forces a small write barrier buffer to stress write
+// barrier flushing.
+const testSmallBuf = false
+
+// wbBuf is a per-P buffer of pointers queued by the write barrier.
+// This buffer is flushed to the GC workbufs when it fills up and on
+// various GC transitions.
+//
+// This is closely related to a "sequential store buffer" (SSB),
+// except that SSBs are usually used for maintaining remembered sets,
+// while this is used for marking.
+type wbBuf struct {
+	// next points to the next slot in buf. It must not be a
+	// pointer type because it can point past the end of buf and
+	// must be updated without write barriers.
+	//
+	// This is a pointer rather than an index to optimize the
+	// write barrier assembly.
+	next uintptr
+
+	// end points to just past the end of buf. It must not be a
+	// pointer type because it points past the end of buf and must
+	// be updated without write barriers.
+	end uintptr
+
+	// buf stores a series of pointers to execute write barriers
+	// on. This must be a multiple of wbBufEntryPointers because
+	// the write barrier only checks for overflow once per entry.
+	buf [wbBufEntryPointers * wbBufEntries]uintptr
+}
+
+const (
+	// wbBufEntries is the number of write barriers between
+	// flushes of the write barrier buffer.
+	//
+	// This trades latency for throughput amortization. Higher
+	// values amortize flushing overhead more, but increase the
+	// latency of flushing. Higher values also increase the cache
+	// footprint of the buffer.
+	//
+	// TODO: What is the latency cost of this? Tune this value.
+	wbBufEntries = 256
+
+	// wbBufEntryPointers is the number of pointers added to the
+	// buffer by each write barrier.
+	wbBufEntryPointers = 2
+)
+
+// reset empties b by resetting its next and end pointers.
+func (b *wbBuf) reset() {
+	start := uintptr(unsafe.Pointer(&b.buf[0]))
+	b.next = start
+	if gcBlackenPromptly || writeBarrier.cgo {
+		// Effectively disable the buffer by forcing a flush
+		// on every barrier.
+		b.end = uintptr(unsafe.Pointer(&b.buf[wbBufEntryPointers]))
+	} else if testSmallBuf {
+		// For testing, allow two barriers in the buffer. If
+		// we only did one, then barriers of non-heap pointers
+		// would be no-ops. This lets us combine a buffered
+		// barrier with a flush at a later time.
+		b.end = uintptr(unsafe.Pointer(&b.buf[2*wbBufEntryPointers]))
+	} else {
+		b.end = start + uintptr(len(b.buf))*unsafe.Sizeof(b.buf[0])
+	}
+
+	if (b.end-b.next)%(wbBufEntryPointers*unsafe.Sizeof(b.buf[0])) != 0 {
+		throw("bad write barrier buffer bounds")
+	}
+}
+
+// discard resets b's next pointer, but not its end pointer.
+//
+// This must be nosplit because it's called by wbBufFlush.
+//
+//go:nosplit
+func (b *wbBuf) discard() {
+	b.next = uintptr(unsafe.Pointer(&b.buf[0]))
+}
+
+// putFast adds old and new to the write barrier buffer and returns
+// false if a flush is necessary. Callers should use this as:
+//
+//     buf := &getg().m.p.ptr().wbBuf
+//     if !buf.putFast(old, new) {
+//         wbBufFlush(...)
+//     }
+//
+// The arguments to wbBufFlush depend on whether the caller is doing
+// its own cgo pointer checks. If it is, then this can be
+// wbBufFlush(nil, 0). Otherwise, it must pass the slot address and
+// new.
+//
+// Since buf is a per-P resource, the caller must ensure there are no
+// preemption points while buf is in use.
+//
+// It must be nowritebarrierrec to because write barriers here would
+// corrupt the write barrier buffer. It (and everything it calls, if
+// it called anything) has to be nosplit to avoid scheduling on to a
+// different P and a different buffer.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func (b *wbBuf) putFast(old, new uintptr) bool {
+	p := (*[2]uintptr)(unsafe.Pointer(b.next))
+	p[0] = old
+	p[1] = new
+	b.next += 2 * sys.PtrSize
+	return b.next != b.end
+}
+
+// wbBufFlush flushes the current P's write barrier buffer to the GC
+// workbufs. It is passed the slot and value of the write barrier that
+// caused the flush so that it can implement cgocheck.
+//
+// This must not have write barriers because it is part of the write
+// barrier implementation.
+//
+// This and everything it calls must be nosplit because 1) the stack
+// contains untyped slots from gcWriteBarrier and 2) there must not be
+// a GC safe point between the write barrier test in the caller and
+// flushing the buffer.
+//
+// TODO: A "go:nosplitrec" annotation would be perfect for this.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func wbBufFlush(dst *uintptr, src uintptr) {
+	// Note: Every possible return from this function must reset
+	// the buffer's next pointer to prevent buffer overflow.
+
+	if getg().m.dying > 0 {
+		// We're going down. Not much point in write barriers
+		// and this way we can allow write barriers in the
+		// panic path.
+		getg().m.p.ptr().wbBuf.discard()
+		return
+	}
+
+	if writeBarrier.cgo && dst != nil {
+		// This must be called from the stack that did the
+		// write. It's nosplit all the way down.
+		cgoCheckWriteBarrier(dst, src)
+		if !writeBarrier.needed {
+			// We were only called for cgocheck.
+			getg().m.p.ptr().wbBuf.discard()
+			return
+		}
+	}
+
+	// Switch to the system stack so we don't have to worry about
+	// the untyped stack slots or safe points.
+	systemstack(func() {
+		wbBufFlush1(getg().m.p.ptr())
+	})
+}
+
+// wbBufFlush1 flushes p's write barrier buffer to the GC work queue.
+//
+// This must not have write barriers because it is part of the write
+// barrier implementation, so this may lead to infinite loops or
+// buffer corruption.
+//
+// This must be non-preemptible because it uses the P's workbuf.
+//
+//go:nowritebarrierrec
+//go:systemstack
+func wbBufFlush1(_p_ *p) {
+	// Get the buffered pointers.
+	start := uintptr(unsafe.Pointer(&_p_.wbBuf.buf[0]))
+	n := (_p_.wbBuf.next - start) / unsafe.Sizeof(_p_.wbBuf.buf[0])
+	ptrs := _p_.wbBuf.buf[:n]
+
+	// Reset the buffer.
+	_p_.wbBuf.reset()
+
+	if useCheckmark {
+		// Slow path for checkmark mode.
+		for _, ptr := range ptrs {
+			shade(ptr)
+		}
+		return
+	}
+
+	// Mark all of the pointers in the buffer and record only the
+	// pointers we greyed. We use the buffer itself to temporarily
+	// record greyed pointers.
+	//
+	// TODO: Should scanobject/scanblock just stuff pointers into
+	// the wbBuf? Then this would become the sole greying path.
+	gcw := &_p_.gcw
+	pos := 0
+	arenaStart := mheap_.arena_start
+	for _, ptr := range ptrs {
+		if ptr < arenaStart {
+			// nil pointers are very common, especially
+			// for the "old" values. Filter out these and
+			// other "obvious" non-heap pointers ASAP.
+			//
+			// TODO: Should we filter out nils in the fast
+			// path to reduce the rate of flushes?
+			continue
+		}
+		// TODO: This doesn't use hbits, so calling
+		// heapBitsForObject seems a little silly. We could
+		// easily separate this out since heapBitsForObject
+		// just calls heapBitsForAddr(obj) to get hbits.
+		obj, _, span, objIndex := heapBitsForObject(ptr, 0, 0)
+		if obj == 0 {
+			continue
+		}
+		// TODO: Consider making two passes where the first
+		// just prefetches the mark bits.
+		mbits := span.markBitsForIndex(objIndex)
+		if mbits.isMarked() {
+			continue
+		}
+		mbits.setMarked()
+		if span.spanclass.noscan() {
+			gcw.bytesMarked += uint64(span.elemsize)
+			continue
+		}
+		ptrs[pos] = obj
+		pos++
+	}
+
+	// Enqueue the greyed objects.
+	gcw.putBatch(ptrs[:pos])
+	if gcphase == _GCmarktermination || gcBlackenPromptly {
+		// Ps aren't allowed to cache work during mark
+		// termination.
+		gcw.dispose()
+	}
+}
diff --git a/src/runtime/netpoll_kqueue.go b/src/runtime/netpoll_kqueue.go
index 71de98b..4d5d1a4 100644
--- a/src/runtime/netpoll_kqueue.go
+++ b/src/runtime/netpoll_kqueue.go
@@ -88,10 +88,23 @@
 	for i := 0; i < int(n); i++ {
 		ev := &events[i]
 		var mode int32
-		if ev.filter == _EVFILT_READ {
+		switch ev.filter {
+		case _EVFILT_READ:
 			mode += 'r'
-		}
-		if ev.filter == _EVFILT_WRITE {
+
+			// On some systems when the read end of a pipe
+			// is closed the write end will not get a
+			// _EVFILT_WRITE event, but will get a
+			// _EVFILT_READ event with EV_EOF set.
+			// Note that setting 'w' here just means that we
+			// will wake up a goroutine waiting to write;
+			// that goroutine will try the write again,
+			// and the appropriate thing will happen based
+			// on what that write returns (success, EPIPE, EAGAIN).
+			if ev.flags&_EV_EOF != 0 {
+				mode += 'w'
+			}
+		case _EVFILT_WRITE:
 			mode += 'w'
 		}
 		if mode != 0 {
diff --git a/src/runtime/netpoll_windows.go b/src/runtime/netpoll_windows.go
index 79dafb0..134071f 100644
--- a/src/runtime/netpoll_windows.go
+++ b/src/runtime/netpoll_windows.go
@@ -47,7 +47,7 @@
 
 func netpollopen(fd uintptr, pd *pollDesc) int32 {
 	if stdcall4(_CreateIoCompletionPort, fd, iocphandle, 0, 0) == 0 {
-		return -int32(getlasterror())
+		return int32(getlasterror())
 	}
 	return 0
 }
diff --git a/src/runtime/os3_plan9.go b/src/runtime/os3_plan9.go
index 5d4b5a6..0b313d7 100644
--- a/src/runtime/os3_plan9.go
+++ b/src/runtime/os3_plan9.go
@@ -45,6 +45,11 @@
 			break
 		}
 	}
+	if flags&_SigPanic != 0 && gp.throwsplit {
+		// We can't safely sigpanic because it may grow the
+		// stack. Abort in the signal handler instead.
+		flags = (flags &^ _SigPanic) | _SigThrow
+	}
 	if flags&_SigGoExit != 0 {
 		exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
 	}
@@ -153,3 +158,6 @@
 	// TODO: Enable profiling interrupts.
 	getg().m.profilehz = hz
 }
+
+// gsignalStack is unused on Plan 9.
+type gsignalStack struct{}
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 067fb3b..c53f613 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -181,6 +181,12 @@
 	}
 }
 
+func exitThread(wait *uint32) {
+	// We should never reach exitThread on Solaris because we let
+	// libc clean up threads.
+	throw("exitThread")
+}
+
 var urandom_dev = []byte("/dev/urandom\x00")
 
 //go:nosplit
@@ -396,12 +402,12 @@
 }
 
 //go:nosplit
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
 	p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
 	if p == ^uintptr(0) {
-		return unsafe.Pointer(err)
+		return nil, int(err)
 	}
-	return unsafe.Pointer(p)
+	return unsafe.Pointer(p), 0
 }
 
 //go:nosplit
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 1528167..580dffa 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -11,6 +11,8 @@
 	waitsema uint32 // semaphore for parking on locks
 }
 
+var darwinVersion int
+
 func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
 func bsdthread_register() int32
 
@@ -50,16 +52,35 @@
 	// can look at the environment first.
 
 	ncpu = getncpu()
-
 	physPageSize = getPageSize()
+	darwinVersion = getDarwinVersion()
 }
 
 const (
-	_CTL_HW      = 6
-	_HW_NCPU     = 3
-	_HW_PAGESIZE = 7
+	_CTL_KERN       = 1
+	_CTL_HW         = 6
+	_KERN_OSRELEASE = 2
+	_HW_NCPU        = 3
+	_HW_PAGESIZE    = 7
 )
 
+func getDarwinVersion() int {
+	// Use sysctl to fetch kern.osrelease
+	mib := [2]uint32{_CTL_KERN, _KERN_OSRELEASE}
+	var out [32]byte
+	nout := unsafe.Sizeof(out)
+	ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+	if ret >= 0 {
+		ver := 0
+		for i := 0; i < int(nout) && out[i] >= '0' && out[i] <= '9'; i++ {
+			ver *= 10
+			ver += int(out[i] - '0')
+		}
+		return ver
+	}
+	return 17 // should not happen: default to a newish version
+}
+
 func getncpu() int32 {
 	// Use sysctl to fetch hw.ncpu.
 	mib := [2]uint32{_CTL_HW, _HW_NCPU}
@@ -135,7 +156,7 @@
 // not safe to use after initialization as it does not pass an M as fnarg.
 //
 //go:nosplit
-func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) {
+func newosproc0(stacksize uintptr, fn uintptr) {
 	stack := sysAlloc(stacksize, &memstats.stacks_sys)
 	if stack == nil {
 		write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
@@ -145,7 +166,7 @@
 
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	errno := bsdthread_create(stk, fn, fnarg)
+	errno := bsdthread_create(stk, nil, fn)
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 
 	if errno < 0 {
@@ -188,7 +209,11 @@
 // Called from dropm to undo the effect of an minit.
 //go:nosplit
 func unminit() {
-	unminitSignals()
+	// The alternate signal stack is buggy on arm and arm64.
+	// See minit.
+	if GOARCH != "arm" && GOARCH != "arm64" {
+		unminitSignals()
+	}
 }
 
 // Mach IPC, to get at semaphores
diff --git a/src/runtime/os_darwin_arm64.go b/src/runtime/os_darwin_arm64.go
index 01285af..8de132d 100644
--- a/src/runtime/os_darwin_arm64.go
+++ b/src/runtime/os_darwin_arm64.go
@@ -4,8 +4,6 @@
 
 package runtime
 
-var supportCRC32 = false
-
 //go:nosplit
 func cputicks() int64 {
 	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().
diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go
index 7c989de..31708e2 100644
--- a/src/runtime/os_freebsd.go
+++ b/src/runtime/os_freebsd.go
@@ -69,15 +69,19 @@
 }
 
 const (
-	_CPU_SETSIZE_MAX = 32 // Limited by _MaxGomaxprocs(256) in runtime2.go.
 	_CPU_CURRENT_PID = -1 // Current process ID.
 )
 
 //go:noescape
 func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
 
+//go:systemstack
 func getncpu() int32 {
-	var mask [_CPU_SETSIZE_MAX]byte
+	// Use a large buffer for the CPU mask. We're on the system
+	// stack, so this is fine, and we can't allocate memory for a
+	// dynamically-sized buffer at this point.
+	const maxCPUs = 64 * 1024
+	var mask [maxCPUs / 8]byte
 	var mib [_CTL_MAXNAME]uint32
 
 	// According to FreeBSD's /usr/src/sys/kern/kern_cpuset.c,
@@ -99,21 +103,20 @@
 		return 1
 	}
 
-	size := maxcpus / _NBBY
-	ptrsize := uint32(unsafe.Sizeof(uintptr(0)))
-	if size < ptrsize {
-		size = ptrsize
+	maskSize := int(maxcpus+7) / 8
+	if maskSize < sys.PtrSize {
+		maskSize = sys.PtrSize
 	}
-	if size > _CPU_SETSIZE_MAX {
-		return 1
+	if maskSize > len(mask) {
+		maskSize = len(mask)
 	}
 
 	if cpuset_getaffinity(_CPU_LEVEL_WHICH, _CPU_WHICH_PID, _CPU_CURRENT_PID,
-		int(size), (*byte)(unsafe.Pointer(&mask[0]))) != 0 {
+		maskSize, (*byte)(unsafe.Pointer(&mask[0]))) != 0 {
 		return 1
 	}
 	n := int32(0)
-	for _, v := range mask[:size] {
+	for _, v := range mask[:maskSize] {
 		for v != 0 {
 			n += int32(v & 1)
 			v >>= 1
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 7889973..98e7f52 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -89,13 +89,13 @@
 	// buffers, but we don't have a dynamic memory allocator at the
 	// moment, so that's a bit tricky and seems like overkill.
 	const maxCPUs = 64 * 1024
-	var buf [maxCPUs / (sys.PtrSize * 8)]uintptr
+	var buf [maxCPUs / 8]byte
 	r := sched_getaffinity(0, unsafe.Sizeof(buf), &buf[0])
 	if r < 0 {
 		return 1
 	}
 	n := int32(0)
-	for _, v := range buf[:r/sys.PtrSize] {
+	for _, v := range buf[:r] {
 		for v != 0 {
 			n += int32(v & 1)
 			v >>= 1
@@ -193,6 +193,8 @@
 
 var procAuxv = []byte("/proc/self/auxv\x00")
 
+func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
+
 func sysargs(argc int32, argv **byte) {
 	n := argc + 1
 
@@ -206,45 +208,46 @@
 
 	// now argv+n is auxv
 	auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
-	if sysauxv(auxv[:]) == 0 {
-		// In some situations we don't get a loader-provided
-		// auxv, such as when loaded as a library on Android.
-		// Fall back to /proc/self/auxv.
-		fd := open(&procAuxv[0], 0 /* O_RDONLY */, 0)
-		if fd < 0 {
-			// On Android, /proc/self/auxv might be unreadable (issue 9229), so we fallback to
-			// try using mincore to detect the physical page size.
-			// mincore should return EINVAL when address is not a multiple of system page size.
-			const size = 256 << 10 // size of memory region to allocate
-			p := mmap(nil, size, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
-			if uintptr(p) < 4096 {
-				return
-			}
-			var n uintptr
-			for n = 4 << 10; n < size; n <<= 1 {
-				err := mincore(unsafe.Pointer(uintptr(p)+n), 1, &addrspace_vec[0])
-				if err == 0 {
-					physPageSize = n
-					break
-				}
-			}
-			if physPageSize == 0 {
-				physPageSize = size
-			}
-			munmap(p, size)
-			return
-		}
-		var buf [128]uintptr
-		n := read(fd, noescape(unsafe.Pointer(&buf[0])), int32(unsafe.Sizeof(buf)))
-		closefd(fd)
-		if n < 0 {
-			return
-		}
-		// Make sure buf is terminated, even if we didn't read
-		// the whole file.
-		buf[len(buf)-2] = _AT_NULL
-		sysauxv(buf[:])
+	if sysauxv(auxv[:]) != 0 {
+		return
 	}
+	// In some situations we don't get a loader-provided
+	// auxv, such as when loaded as a library on Android.
+	// Fall back to /proc/self/auxv.
+	fd := open(&procAuxv[0], 0 /* O_RDONLY */, 0)
+	if fd < 0 {
+		// On Android, /proc/self/auxv might be unreadable (issue 9229), so we fallback to
+		// try using mincore to detect the physical page size.
+		// mincore should return EINVAL when address is not a multiple of system page size.
+		const size = 256 << 10 // size of memory region to allocate
+		p, err := mmap(nil, size, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+		if err != 0 {
+			return
+		}
+		var n uintptr
+		for n = 4 << 10; n < size; n <<= 1 {
+			err := mincore(unsafe.Pointer(uintptr(p)+n), 1, &addrspace_vec[0])
+			if err == 0 {
+				physPageSize = n
+				break
+			}
+		}
+		if physPageSize == 0 {
+			physPageSize = size
+		}
+		munmap(p, size)
+		return
+	}
+	var buf [128]uintptr
+	n = read(fd, noescape(unsafe.Pointer(&buf[0])), int32(unsafe.Sizeof(buf)))
+	closefd(fd)
+	if n < 0 {
+		return
+	}
+	// Make sure buf is terminated, even if we didn't read
+	// the whole file.
+	buf[len(buf)-2] = _AT_NULL
+	sysauxv(buf[:])
 }
 
 func sysauxv(auxv []uintptr) int {
@@ -382,7 +385,7 @@
 func raiseproc(sig uint32)
 
 //go:noescape
-func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
+func sched_getaffinity(pid, len uintptr, buf *byte) int32
 func osyield()
 
 //go:nosplit
diff --git a/src/runtime/os_linux_arm64.go b/src/runtime/os_linux_arm64.go
index 986a341..96827e7 100644
--- a/src/runtime/os_linux_arm64.go
+++ b/src/runtime/os_linux_arm64.go
@@ -2,14 +2,22 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build arm64
+
 package runtime
 
-const (
-	_ARM64_FEATURE_HAS_CRC32 = 0x80
-)
+// For go:linkname
+import _ "unsafe"
 
 var randomNumber uint32
-var supportCRC32 bool
+
+// arm64 doesn't have a 'cpuid' instruction equivalent and relies on
+// HWCAP/HWCAP2 bits for hardware capabilities.
+
+//go:linkname cpu_hwcap internal/cpu.arm64_hwcap
+//go:linkname cpu_hwcap2 internal/cpu.arm64_hwcap2
+var cpu_hwcap uint
+var cpu_hwcap2 uint
 
 func archauxv(tag, val uintptr) {
 	switch tag {
@@ -20,7 +28,9 @@
 		randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
 			uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
 	case _AT_HWCAP:
-		supportCRC32 = val&_ARM64_FEATURE_HAS_CRC32 != 0
+		cpu_hwcap = uint(val)
+	case _AT_HWCAP2:
+		cpu_hwcap2 = uint(val)
 	}
 }
 
diff --git a/src/runtime/os_linux_noauxv.go b/src/runtime/os_linux_noauxv.go
index 5e9f031..db6e5a0 100644
--- a/src/runtime/os_linux_noauxv.go
+++ b/src/runtime/os_linux_noauxv.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!arm,!arm64,!mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
+// +build !386,!amd64,!arm,!arm64,!mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
 
 package runtime
 
diff --git a/src/runtime/os_linux_ppc64x.go b/src/runtime/os_linux_ppc64x.go
index b0da98b..e37bfc4 100644
--- a/src/runtime/os_linux_ppc64x.go
+++ b/src/runtime/os_linux_ppc64x.go
@@ -6,55 +6,22 @@
 
 package runtime
 
-import (
-	"runtime/internal/sys"
-)
+// For go:linkname
+import _ "unsafe"
 
-const (
-	// ISA level
-	// Go currently requires POWER5 as a minimum for ppc64, so we need
-	// to check for ISA 2.03 and beyond.
-	_PPC_FEATURE_POWER5_PLUS = 0x00020000 // ISA 2.03 (POWER5+)
-	_PPC_FEATURE_ARCH_2_05   = 0x00001000 // ISA 2.05 (POWER6)
-	_PPC_FEATURE_POWER6_EXT  = 0x00000200 // mffgpr/mftgpr extension (POWER6x)
-	_PPC_FEATURE_ARCH_2_06   = 0x00000100 // ISA 2.06 (POWER7)
-	_PPC_FEATURE2_ARCH_2_07  = 0x80000000 // ISA 2.07 (POWER8)
+// ppc64x doesn't have a 'cpuid' instruction equivalent and relies on
+// HWCAP/HWCAP2 bits for hardware capabilities.
 
-	// Standalone capabilities
-	_PPC_FEATURE_HAS_ALTIVEC = 0x10000000 // SIMD/Vector unit
-	_PPC_FEATURE_HAS_VSX     = 0x00000080 // Vector scalar unit
-)
-
-type facilities struct {
-	_         [sys.CacheLineSize]byte
-	isPOWER5x bool // ISA 2.03
-	isPOWER6  bool // ISA 2.05
-	isPOWER6x bool // ISA 2.05 + mffgpr/mftgpr extension
-	isPOWER7  bool // ISA 2.06
-	isPOWER8  bool // ISA 2.07
-	hasVMX    bool // Vector unit
-	hasVSX    bool // Vector scalar unit
-	_         [sys.CacheLineSize]byte
-}
-
-// cpu can be tested at runtime in go assembler code to check for
-// a certain ISA level or hardware capability, for example:
-//	  ·cpu+facilities_hasVSX(SB) for checking the availability of VSX
-//	  or
-//	  ·cpu+facilities_isPOWER7(SB) for checking if the processor implements
-//	  ISA 2.06 instructions.
-var cpu facilities
+//go:linkname cpu_hwcap internal/cpu.ppc64x_hwcap
+//go:linkname cpu_hwcap2 internal/cpu.ppc64x_hwcap2
+var cpu_hwcap uint
+var cpu_hwcap2 uint
 
 func archauxv(tag, val uintptr) {
 	switch tag {
 	case _AT_HWCAP:
-		cpu.isPOWER5x = val&_PPC_FEATURE_POWER5_PLUS != 0
-		cpu.isPOWER6 = val&_PPC_FEATURE_ARCH_2_05 != 0
-		cpu.isPOWER6x = val&_PPC_FEATURE_POWER6_EXT != 0
-		cpu.isPOWER7 = val&_PPC_FEATURE_ARCH_2_06 != 0
-		cpu.hasVMX = val&_PPC_FEATURE_HAS_ALTIVEC != 0
-		cpu.hasVSX = val&_PPC_FEATURE_HAS_VSX != 0
+		cpu_hwcap = uint(val)
 	case _AT_HWCAP2:
-		cpu.isPOWER8 = val&_PPC_FEATURE2_ARCH_2_07 != 0
+		cpu_hwcap2 = uint(val)
 	}
 }
diff --git a/src/runtime/os_nacl.go b/src/runtime/os_nacl.go
index 18e6ce6..6830da4 100644
--- a/src/runtime/os_nacl.go
+++ b/src/runtime/os_nacl.go
@@ -33,7 +33,7 @@
 //go:noescape
 func nacl_nanosleep(ts, extra *timespec) int32
 func nanotime() int64
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
 func exit(code int32)
 func osyield()
 
@@ -168,6 +168,9 @@
 	}
 }
 
+//go:noescape
+func exitThread(wait *uint32)
+
 //go:nosplit
 func semacreate(mp *m) {
 	if mp.waitsema != 0 {
@@ -285,6 +288,9 @@
 func sigignore(uint32)                                    {}
 func closeonexec(int32)                                   {}
 
+// gsignalStack is unused on nacl.
+type gsignalStack struct{}
+
 var writelock uint32 // test-and-set spin lock for write
 
 /*
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
index c26c3c9..3778969 100644
--- a/src/runtime/os_netbsd.go
+++ b/src/runtime/os_netbsd.go
@@ -21,6 +21,9 @@
 	_UC_SIGMASK = 0x01
 	_UC_CPU     = 0x04
 
+	// From <sys/lwp.h>
+	_LWP_DETACHED = 0x00000040
+
 	_EAGAIN = 35
 )
 
@@ -55,7 +58,7 @@
 func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
 
 //go:noescape
-func lwp_park(abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
+func lwp_park(clockid, flags int32, ts *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
 
 //go:noescape
 func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
@@ -73,6 +76,9 @@
 	_CLOCK_VIRTUAL   = 1
 	_CLOCK_PROF      = 2
 	_CLOCK_MONOTONIC = 3
+
+	_TIMER_RELTIME = 0
+	_TIMER_ABSTIME = 1
 )
 
 var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
@@ -116,10 +122,9 @@
 
 	// Compute sleep deadline.
 	var tsp *timespec
+	var ts timespec
 	if ns >= 0 {
-		var ts timespec
 		var nsec int32
-		ns += nanotime()
 		ts.set_sec(timediv(ns, 1000000000, &nsec))
 		ts.set_nsec(nsec)
 		tsp = &ts
@@ -135,9 +140,18 @@
 		}
 
 		// Sleep until unparked by semawakeup or timeout.
-		ret := lwp_park(tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
+		ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
 		if ret == _ETIMEDOUT {
 			return -1
+		} else if ret == _EINTR && ns >= 0 {
+			// Avoid sleeping forever if we keep getting
+			// interrupted (for example by the profiling
+			// timer). It would be if tsp upon return had the
+			// remaining time to sleep, but this is good enough.
+			var nsec int32
+			ns /= 2
+			ts.set_sec(timediv(ns, 1000000000, &nsec))
+			ts.set_nsec(nsec)
 		}
 	}
 }
@@ -182,7 +196,7 @@
 
 	lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, funcPC(netbsdMstart))
 
-	ret := lwp_create(unsafe.Pointer(&uc), 0, unsafe.Pointer(&mp.procid))
+	ret := lwp_create(unsafe.Pointer(&uc), _LWP_DETACHED, unsafe.Pointer(&mp.procid))
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if ret < 0 {
 		print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 45e881a..32fdabb 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -393,7 +393,7 @@
 }
 
 //go:nosplit
-func exit(e int) {
+func exit(e int32) {
 	var status []byte
 	if e == 0 {
 		status = emptystatus
@@ -421,6 +421,12 @@
 	}
 }
 
+func exitThread(wait *uint32) {
+	// We should never reach exitThread on Plan 9 because we let
+	// the OS clean up threads.
+	throw("exitThread")
+}
+
 //go:nosplit
 func semacreate(mp *m) {
 }
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 233cc16..7aeadd9 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -623,7 +623,7 @@
 func newosproc(mp *m, stk unsafe.Pointer) {
 	const _STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000
 	// stackSize must match SizeOfStackReserve in cmd/link/internal/ld/pe.go.
-	const stackSize = 0x00200000*_64bit + 0x00020000*(1-_64bit)
+	const stackSize = 0x00200000*_64bit + 0x00100000*(1-_64bit)
 	thandle := stdcall6(_CreateThread, 0, stackSize,
 		funcPC(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
 		_STACK_SIZE_PARAM_IS_A_RESERVATION, 0)
@@ -640,6 +640,9 @@
 		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
 		throw("runtime.newosproc")
 	}
+
+	// Close thandle to avoid leaking the thread object if it exits.
+	stdcall1(_CloseHandle, thandle)
 }
 
 // Used by the C library build mode. On Linux this function would allocate a
@@ -651,6 +654,12 @@
 	newosproc(mp, stk)
 }
 
+func exitThread(wait *uint32) {
+	// We should never reach exitThread on Windows because we let
+	// the OS clean up threads.
+	throw("exitThread")
+}
+
 // Called to initialize a new m (including the bootstrap m).
 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
 func mpreinit(mp *m) {
@@ -701,7 +710,7 @@
 	if mp.profilehz != 0 {
 		// leave pc/sp for cpu profiler
 		mp.libcallg.set(gp)
-		mp.libcallpc = getcallerpc(unsafe.Pointer(&fn))
+		mp.libcallpc = getcallerpc()
 		// sp must be the last, because once async cpu profiler finds
 		// all three values to be non-zero, it will use them
 		mp.libcallsp = getcallersp(unsafe.Pointer(&fn))
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 43bfdd7..c51948b 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -83,7 +83,7 @@
 	// Until the copy completes, we can only call nosplit routines.
 	sp := getcallersp(unsafe.Pointer(&siz))
 	argp := uintptr(unsafe.Pointer(&fn)) + unsafe.Sizeof(fn)
-	callerpc := getcallerpc(unsafe.Pointer(&siz))
+	callerpc := getcallerpc()
 
 	d := newdefer(siz)
 	if d._panic != nil {
@@ -244,36 +244,47 @@
 		freedeferfn()
 	}
 	sc := deferclass(uintptr(d.siz))
-	if sc < uintptr(len(p{}.deferpool)) {
-		pp := getg().m.p.ptr()
-		if len(pp.deferpool[sc]) == cap(pp.deferpool[sc]) {
-			// Transfer half of local cache to the central cache.
-			//
-			// Take this slow path on the system stack so
-			// we don't grow freedefer's stack.
-			systemstack(func() {
-				var first, last *_defer
-				for len(pp.deferpool[sc]) > cap(pp.deferpool[sc])/2 {
-					n := len(pp.deferpool[sc])
-					d := pp.deferpool[sc][n-1]
-					pp.deferpool[sc][n-1] = nil
-					pp.deferpool[sc] = pp.deferpool[sc][:n-1]
-					if first == nil {
-						first = d
-					} else {
-						last.link = d
-					}
-					last = d
-				}
-				lock(&sched.deferlock)
-				last.link = sched.deferpool[sc]
-				sched.deferpool[sc] = first
-				unlock(&sched.deferlock)
-			})
-		}
-		*d = _defer{}
-		pp.deferpool[sc] = append(pp.deferpool[sc], d)
+	if sc >= uintptr(len(p{}.deferpool)) {
+		return
 	}
+	pp := getg().m.p.ptr()
+	if len(pp.deferpool[sc]) == cap(pp.deferpool[sc]) {
+		// Transfer half of local cache to the central cache.
+		//
+		// Take this slow path on the system stack so
+		// we don't grow freedefer's stack.
+		systemstack(func() {
+			var first, last *_defer
+			for len(pp.deferpool[sc]) > cap(pp.deferpool[sc])/2 {
+				n := len(pp.deferpool[sc])
+				d := pp.deferpool[sc][n-1]
+				pp.deferpool[sc][n-1] = nil
+				pp.deferpool[sc] = pp.deferpool[sc][:n-1]
+				if first == nil {
+					first = d
+				} else {
+					last.link = d
+				}
+				last = d
+			}
+			lock(&sched.deferlock)
+			last.link = sched.deferpool[sc]
+			sched.deferpool[sc] = first
+			unlock(&sched.deferlock)
+		})
+	}
+
+	// These lines used to be simply `*d = _defer{}` but that
+	// started causing a nosplit stack overflow via typedmemmove.
+	d.siz = 0
+	d.started = false
+	d.sp = 0
+	d.pc = 0
+	d.fn = nil
+	d._panic = nil
+	d.link = nil
+
+	pp.deferpool[sc] = append(pp.deferpool[sc], d)
 }
 
 // Separate function so that it can split stack.
@@ -336,7 +347,7 @@
 
 // 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.
+// is not a panic, 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,
@@ -397,12 +408,15 @@
 }
 
 // Print all currently active panics. Used when crashing.
+// Should only be called after preprintpanics.
 func printpanics(p *_panic) {
 	if p.link != nil {
 		printpanics(p.link)
 		print("\t")
 	}
 	print("panic: ")
+	// Because of preprintpanics, p.arg cannot be an error or
+	// stringer, so this won't call into user code.
 	printany(p.arg)
 	if p.recovered {
 		print(" [recovered]")
@@ -580,7 +594,7 @@
 
 //go:nosplit
 func dopanic(unused int) {
-	pc := getcallerpc(unsafe.Pointer(&unused))
+	pc := getcallerpc()
 	sp := getcallersp(unsafe.Pointer(&unused))
 	gp := getg()
 	systemstack(func() {
@@ -643,14 +657,22 @@
 	gogo(&gp.sched)
 }
 
+// startpanic_m prepares for an unrecoverable panic.
+//
+// It can have write barriers because the write barrier explicitly
+// ignores writes once dying > 0.
+//
+//go:yeswritebarrierrec
 func startpanic_m() {
 	_g_ := getg()
 	if mheap_.cachealloc.size == 0 { // very early
 		print("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 = allocmcache()
 	}
+	// Disallow malloc during an unrecoverable panic. A panic
+	// could happen in a signal handler, or in a throw, or inside
+	// malloc itself. We want to catch if an allocation ever does
+	// happen (even if we're not in one of these situations).
+	_g_.m.mallocing++
 
 	switch _g_.m.dying {
 	case 0:
@@ -679,7 +701,7 @@
 		exit(4)
 		fallthrough
 	default:
-		// Can't even print!  Just exit.
+		// Can't even print! Just exit.
 		exit(5)
 	}
 }
@@ -735,6 +757,9 @@
 	exit(2)
 }
 
+// canpanic returns false if a signal should throw instead of
+// panicking.
+//
 //go:nosplit
 func canpanic(gp *g) bool {
 	// Note that g is m->gsignal, different from gp.
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 682caac..5e05be7 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -7,22 +7,29 @@
 import "unsafe"
 
 //go:linkname plugin_lastmoduleinit plugin.lastmoduleinit
-func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatchpkg string) {
-	md := firstmoduledata.next
+func plugin_lastmoduleinit() (path string, syms map[string]interface{}, errstr string) {
+	var md *moduledata
+	for pmd := firstmoduledata.next; pmd != nil; pmd = pmd.next {
+		if pmd.bad {
+			md = nil // we only want the last module
+			continue
+		}
+		md = pmd
+	}
 	if md == nil {
 		throw("runtime: no plugin module data")
 	}
-	for md.next != nil {
-		md = md.next
+	if md.pluginpath == "" {
+		throw("runtime: plugin has empty pluginpath")
 	}
 	if md.typemap != nil {
-		throw("runtime: plugin already initialized")
+		return "", nil, "plugin already loaded"
 	}
 
 	for _, pmd := range activeModules() {
 		if pmd.pluginpath == md.pluginpath {
-			println("plugin: plugin", md.pluginpath, "already loaded")
-			throw("plugin: plugin already loaded")
+			md.bad = true
+			return "", nil, "plugin already loaded"
 		}
 
 		if inRange(pmd.text, pmd.etext, md.text, md.etext) ||
@@ -43,7 +50,8 @@
 	}
 	for _, pkghash := range md.pkghashes {
 		if pkghash.linktimehash != *pkghash.runtimehash {
-			return "", nil, pkghash.modulename
+			md.bad = true
+			return "", nil, "plugin was built with a different version of package " + pkghash.modulename
 		}
 	}
 
@@ -54,13 +62,11 @@
 	pluginftabverify(md)
 	moduledataverify1(md)
 
-	lock(&ifaceLock)
+	lock(&itabLock)
 	for _, i := range md.itablinks {
-		if !i.inhash {
-			additab(i, true, false)
-		}
+		itabAdd(i)
 	}
-	unlock(&ifaceLock)
+	unlock(&itabLock)
 
 	// Build a map of symbol names to symbols. Here in the runtime
 	// we fill out the first word of the interface, the type. We
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
index 21ea25c..b7e5a1f 100644
--- a/src/runtime/pprof/pprof.go
+++ b/src/runtime/pprof/pprof.go
@@ -18,7 +18,7 @@
 // To add equivalent profiling support to a standalone program, add
 // code like the following to your main function:
 //
-//    var cpuprofile = flag.String("cpuprofile", "", "write cpu profile `file`")
+//    var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
 //    var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
 //
 //    func main() {
@@ -319,7 +319,15 @@
 	p.mu.Unlock()
 
 	// Map order is non-deterministic; make output deterministic.
-	sort.Sort(stackProfile(all))
+	sort.Slice(all, func(i, j int) bool {
+		t, u := all[i], all[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)
+	})
 
 	return printCountProfile(w, debug, p.name, stackProfile(all))
 }
@@ -328,16 +336,6 @@
 
 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:
@@ -348,6 +346,43 @@
 	Stack(i int) []uintptr
 }
 
+// printCountCycleProfile outputs block profile records (for block or mutex profiles)
+// as the pprof-proto format output. Translations from cycle count to time duration
+// are done because The proto expects count and time (nanoseconds) instead of count
+// and the number of cycles for block, contention profiles.
+// Possible 'scaler' functions are scaleBlockProfile and scaleMutexProfile.
+func printCountCycleProfile(w io.Writer, countName, cycleName string, scaler func(int64, float64) (int64, float64), records []runtime.BlockProfileRecord) error {
+	// Output profile in protobuf form.
+	b := newProfileBuilder(w)
+	b.pbValueType(tagProfile_PeriodType, countName, "count")
+	b.pb.int64Opt(tagProfile_Period, 1)
+	b.pbValueType(tagProfile_SampleType, countName, "count")
+	b.pbValueType(tagProfile_SampleType, cycleName, "nanoseconds")
+
+	cpuGHz := float64(runtime_cyclesPerSecond()) / 1e9
+
+	values := []int64{0, 0}
+	var locs []uint64
+	for _, r := range records {
+		count, nanosec := scaler(r.Count, float64(r.Cycles)/cpuGHz)
+		values[0] = count
+		values[1] = int64(nanosec)
+		locs = locs[:0]
+		for _, addr := range r.Stack() {
+			// For count profiles, all stack addresses are
+			// return PCs, which is what locForPC expects.
+			l := b.locForPC(addr)
+			if l == 0 { // runtime.goexit
+				continue
+			}
+			locs = append(locs, l)
+		}
+		b.pbSample(values, locs, nil)
+	}
+	b.build()
+	return nil
+}
+
 // printCountProfile prints a countProfile at the specified debug level.
 // The profile will be in compressed proto format unless debug is nonzero.
 func printCountProfile(w io.Writer, debug int, name string, p countProfile) error {
@@ -476,6 +511,14 @@
 
 // writeHeap writes the current runtime heap profile to w.
 func writeHeap(w io.Writer, debug int) error {
+	var memStats *runtime.MemStats
+	if debug != 0 {
+		// Read mem stats first, so that our other allocations
+		// do not appear in the statistics.
+		memStats = new(runtime.MemStats)
+		runtime.ReadMemStats(memStats)
+	}
+
 	// 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
@@ -538,8 +581,7 @@
 
 	// Print memstats information too.
 	// Pprof will ignore, but useful for people
-	s := new(runtime.MemStats)
-	runtime.ReadMemStats(s)
+	s := memStats
 	fmt.Fprintf(w, "\n# runtime.MemStats\n")
 	fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
 	fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
@@ -765,14 +807,14 @@
 
 	sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
 
-	b := bufio.NewWriter(w)
-	var tw *tabwriter.Writer
-	w = b
-	if debug > 0 {
-		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
-		w = tw
+	if debug <= 0 {
+		return printCountCycleProfile(w, "contentions", "delay", scaleBlockProfile, p)
 	}
 
+	b := bufio.NewWriter(w)
+	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 {
@@ -793,6 +835,14 @@
 	return b.Flush()
 }
 
+func scaleBlockProfile(cnt int64, ns float64) (int64, float64) {
+	// Do nothing.
+	// The current way of block profile sampling makes it
+	// hard to compute the unsampled number. The legacy block
+	// profile parse doesn't attempt to scale or unsample.
+	return cnt, ns
+}
+
 // writeMutex writes the current mutex profile to w.
 func writeMutex(w io.Writer, debug int) error {
 	// TODO(pjw): too much common code with writeBlock. FIX!
@@ -809,14 +859,14 @@
 
 	sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
 
-	b := bufio.NewWriter(w)
-	var tw *tabwriter.Writer
-	w = b
-	if debug > 0 {
-		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
-		w = tw
+	if debug <= 0 {
+		return printCountCycleProfile(w, "contentions", "delay", scaleMutexProfile, p)
 	}
 
+	b := bufio.NewWriter(w)
+	tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+	w = tw
+
 	fmt.Fprintf(w, "--- mutex:\n")
 	fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond())
 	fmt.Fprintf(w, "sampling period=%d\n", runtime.SetMutexProfileFraction(-1))
@@ -838,4 +888,9 @@
 	return b.Flush()
 }
 
+func scaleMutexProfile(cnt int64, ns float64) (int64, float64) {
+	period := runtime.SetMutexProfileFraction(-1)
+	return cnt * int64(period), ns * float64(period)
+}
+
 func runtime_cyclesPerSecond() int64
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 955964c..96fcfc9 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -26,16 +26,18 @@
 	"time"
 )
 
-func cpuHogger(f func() int, dur time.Duration) {
+func cpuHogger(f func(x int) int, y *int, dur time.Duration) {
 	// We only need to get one 100 Hz clock tick, so we've got
 	// a large 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 testing period.
 	t0 := time.Now()
+	accum := *y
 	for i := 0; i < 500 || time.Since(t0) < dur; i++ {
-		f()
+		accum = f(accum)
 	}
+	*y = accum
 }
 
 var (
@@ -46,8 +48,8 @@
 // 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() int {
-	foo := salt1
+func cpuHog1(x int) int {
+	foo := x
 	for i := 0; i < 1e5; i++ {
 		if foo > 0 {
 			foo *= foo
@@ -58,8 +60,8 @@
 	return foo
 }
 
-func cpuHog2() int {
-	foo := salt2
+func cpuHog2(x int) int {
+	foo := x
 	for i := 0; i < 1e5; i++ {
 		if foo > 0 {
 			foo *= foo
@@ -72,7 +74,7 @@
 
 func TestCPUProfile(t *testing.T) {
 	testCPUProfile(t, []string{"runtime/pprof.cpuHog1"}, func(dur time.Duration) {
-		cpuHogger(cpuHog1, dur)
+		cpuHogger(cpuHog1, &salt1, dur)
 	})
 }
 
@@ -81,29 +83,29 @@
 	testCPUProfile(t, []string{"runtime/pprof.cpuHog1", "runtime/pprof.cpuHog2"}, func(dur time.Duration) {
 		c := make(chan int)
 		go func() {
-			cpuHogger(cpuHog1, dur)
+			cpuHogger(cpuHog1, &salt1, dur)
 			c <- 1
 		}()
-		cpuHogger(cpuHog2, dur)
+		cpuHogger(cpuHog2, &salt2, dur)
 		<-c
 	})
 }
 
 func TestCPUProfileInlining(t *testing.T) {
 	testCPUProfile(t, []string{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}, func(dur time.Duration) {
-		cpuHogger(inlinedCaller, dur)
+		cpuHogger(inlinedCaller, &salt1, dur)
 	})
 }
 
-func inlinedCaller() int {
-	inlinedCallee()
-	return 0
+func inlinedCaller(x int) int {
+	x = inlinedCallee(x)
+	return x
 }
 
-func inlinedCallee() {
+func inlinedCallee(x int) int {
 	// We could just use cpuHog1, but for loops prevent inlining
 	// right now. :(
-	foo := salt1
+	foo := x
 	i := 0
 loop:
 	if foo > 0 {
@@ -114,7 +116,7 @@
 	if i++; i < 1e5 {
 		goto loop
 	}
-	salt1 = foo
+	return foo
 }
 
 func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Location, map[string][]string)) {
@@ -177,9 +179,9 @@
 		}
 	}
 
-	if badOS[runtime.GOOS] {
+	switch runtime.GOOS {
+	case "darwin", "dragonfly", "netbsd", "solaris":
 		t.Skipf("ignoring failure on %s; see golang.org/issue/13841", runtime.GOOS)
-		return
 	}
 	// Ignore the failure if the tests are running in a QEMU-based emulator,
 	// QEMU is not perfect at emulating everything.
@@ -187,7 +189,6 @@
 	// IN_QEMU=1 indicates that the tests are running in QEMU. See issue 9605.
 	if os.Getenv("IN_QEMU") == "1" {
 		t.Skip("ignore the failure in QEMU; see golang.org/issue/9605")
-		return
 	}
 	t.FailNow()
 }
@@ -394,59 +395,107 @@
 	})
 }
 
-// Operating systems that are expected to fail the tests. See issue 13841.
-var badOS = map[string]bool{
-	"darwin":    true,
-	"netbsd":    true,
-	"plan9":     true,
-	"dragonfly": true,
-	"solaris":   true,
-}
-
 func TestBlockProfile(t *testing.T) {
 	type TestCase struct {
 		name string
 		f    func()
+		stk  []string
 		re   string
 	}
 	tests := [...]TestCase{
-		{"chan recv", blockChanRecv, `
+		{
+			name: "chan recv",
+			f:    blockChanRecv,
+			stk: []string{
+				"runtime.chanrecv1",
+				"runtime/pprof.blockChanRecv",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	runtime\.chanrecv1\+0x[0-9a-f]+	.*/src/runtime/chan.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockChanRecv\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"chan send", blockChanSend, `
+		{
+			name: "chan send",
+			f:    blockChanSend,
+			stk: []string{
+				"runtime.chansend1",
+				"runtime/pprof.blockChanSend",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	runtime\.chansend1\+0x[0-9a-f]+	.*/src/runtime/chan.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockChanSend\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"chan close", blockChanClose, `
+		{
+			name: "chan close",
+			f:    blockChanClose,
+			stk: []string{
+				"runtime.chanrecv1",
+				"runtime/pprof.blockChanClose",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	runtime\.chanrecv1\+0x[0-9a-f]+	.*/src/runtime/chan.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockChanClose\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"select recv async", blockSelectRecvAsync, `
+		{
+			name: "select recv async",
+			f:    blockSelectRecvAsync,
+			stk: []string{
+				"runtime.selectgo",
+				"runtime/pprof.blockSelectRecvAsync",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	runtime\.selectgo\+0x[0-9a-f]+	.*/src/runtime/select.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockSelectRecvAsync\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"select send sync", blockSelectSendSync, `
+		{
+			name: "select send sync",
+			f:    blockSelectSendSync,
+			stk: []string{
+				"runtime.selectgo",
+				"runtime/pprof.blockSelectSendSync",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	runtime\.selectgo\+0x[0-9a-f]+	.*/src/runtime/select.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockSelectSendSync\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"mutex", blockMutex, `
+		{
+			name: "mutex",
+			f:    blockMutex,
+			stk: []string{
+				"sync.(*Mutex).Lock",
+				"runtime/pprof.blockMutex",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	sync\.\(\*Mutex\)\.Lock\+0x[0-9a-f]+	.*/src/sync/mutex\.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockMutex\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.TestBlockProfile\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
 `},
-		{"cond", blockCond, `
+		{
+			name: "cond",
+			f:    blockCond,
+			stk: []string{
+				"sync.(*Cond).Wait",
+				"runtime/pprof.blockCond",
+				"runtime/pprof.TestBlockProfile",
+			},
+			re: `
 [0-9]+ [0-9]+ @( 0x[[:xdigit:]]+)+
 #	0x[0-9a-f]+	sync\.\(\*Cond\)\.Wait\+0x[0-9a-f]+	.*/src/sync/cond\.go:[0-9]+
 #	0x[0-9a-f]+	runtime/pprof\.blockCond\+0x[0-9a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
@@ -454,28 +503,84 @@
 `},
 	}
 
+	// Generate block profile
 	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)
+	t.Run("debug=1", func(t *testing.T) {
+		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)
+		}
+
+		if strings.HasSuffix(prof, "#\t0x0\n\n") {
+			t.Errorf("Useless 0 suffix:\n%v", prof)
+		}
+
+		for _, test := range tests {
+			if !regexp.MustCompile(strings.Replace(test.re, "\t", "\t+", -1)).MatchString(prof) {
+				t.Errorf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
+			}
+		}
+	})
+
+	t.Run("proto", func(t *testing.T) {
+		// proto format
+		var w bytes.Buffer
+		Lookup("block").WriteTo(&w, 0)
+		p, err := profile.Parse(&w)
+		if err != nil {
+			t.Fatalf("failed to parse profile: %v", err)
+		}
+		t.Logf("parsed proto: %s", p)
+		if err := p.CheckValid(); err != nil {
+			t.Fatalf("invalid profile: %v", err)
+		}
+
+		stks := stacks(p)
+		for _, test := range tests {
+			if !containsStack(stks, test.stk) {
+				t.Errorf("No matching stack entry for %v, want %+v", test.name, test.stk)
+			}
+		}
+	})
+
+}
+
+func stacks(p *profile.Profile) (res [][]string) {
+	for _, s := range p.Sample {
+		var stk []string
+		for _, l := range s.Location {
+			for _, line := range l.Line {
+				stk = append(stk, line.Function.Name)
+			}
+		}
+		res = append(res, stk)
 	}
+	return res
+}
 
-	if strings.HasSuffix(prof, "#\t0x0\n\n") {
-		t.Errorf("Useless 0 suffix:\n%v", prof)
-	}
-
-	for _, test := range tests {
-		if !regexp.MustCompile(strings.Replace(test.re, "\t", "\t+", -1)).MatchString(prof) {
-			t.Fatalf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
+func containsStack(got [][]string, want []string) bool {
+	for _, stk := range got {
+		if len(stk) < len(want) {
+			continue
+		}
+		for i, f := range want {
+			if f != stk[i] {
+				break
+			}
+			if i == len(want)-1 {
+				return true
+			}
 		}
 	}
+	return false
 }
 
 const blockDelay = 10 * time.Millisecond
@@ -567,6 +672,8 @@
 }
 
 func TestMutexProfile(t *testing.T) {
+	// Generate mutex profile
+
 	old := runtime.SetMutexProfileFraction(1)
 	defer runtime.SetMutexProfileFraction(old)
 	if old != 0 {
@@ -575,31 +682,57 @@
 
 	blockMutex()
 
-	var w bytes.Buffer
-	Lookup("mutex").WriteTo(&w, 1)
-	prof := w.String()
+	t.Run("debug=1", func(t *testing.T) {
+		var w bytes.Buffer
+		Lookup("mutex").WriteTo(&w, 1)
+		prof := w.String()
+		t.Logf("received profile: %v", prof)
 
-	if !strings.HasPrefix(prof, "--- mutex:\ncycles/second=") {
-		t.Errorf("Bad profile header:\n%v", prof)
-	}
-	prof = strings.Trim(prof, "\n")
-	lines := strings.Split(prof, "\n")
-	if len(lines) != 6 {
-		t.Errorf("expected 6 lines, got %d %q\n%s", len(lines), prof, prof)
-	}
-	if len(lines) < 6 {
-		return
-	}
-	// checking that the line is like "35258904 1 @ 0x48288d 0x47cd28 0x458931"
-	r2 := `^\d+ 1 @(?: 0x[[:xdigit:]]+)+`
-	//r2 := "^[0-9]+ 1 @ 0x[0-9a-f x]+$"
-	if ok, err := regexp.MatchString(r2, lines[3]); err != nil || !ok {
-		t.Errorf("%q didn't match %q", lines[3], r2)
-	}
-	r3 := "^#.*runtime/pprof.blockMutex.*$"
-	if ok, err := regexp.MatchString(r3, lines[5]); err != nil || !ok {
-		t.Errorf("%q didn't match %q", lines[5], r3)
-	}
+		if !strings.HasPrefix(prof, "--- mutex:\ncycles/second=") {
+			t.Errorf("Bad profile header:\n%v", prof)
+		}
+		prof = strings.Trim(prof, "\n")
+		lines := strings.Split(prof, "\n")
+		if len(lines) != 6 {
+			t.Errorf("expected 6 lines, got %d %q\n%s", len(lines), prof, prof)
+		}
+		if len(lines) < 6 {
+			return
+		}
+		// checking that the line is like "35258904 1 @ 0x48288d 0x47cd28 0x458931"
+		r2 := `^\d+ 1 @(?: 0x[[:xdigit:]]+)+`
+		//r2 := "^[0-9]+ 1 @ 0x[0-9a-f x]+$"
+		if ok, err := regexp.MatchString(r2, lines[3]); err != nil || !ok {
+			t.Errorf("%q didn't match %q", lines[3], r2)
+		}
+		r3 := "^#.*runtime/pprof.blockMutex.*$"
+		if ok, err := regexp.MatchString(r3, lines[5]); err != nil || !ok {
+			t.Errorf("%q didn't match %q", lines[5], r3)
+		}
+		t.Logf(prof)
+	})
+	t.Run("proto", func(t *testing.T) {
+		// proto format
+		var w bytes.Buffer
+		Lookup("mutex").WriteTo(&w, 0)
+		p, err := profile.Parse(&w)
+		if err != nil {
+			t.Fatalf("failed to parse profile: %v", err)
+		}
+		t.Logf("parsed proto: %s", p)
+		if err := p.CheckValid(); err != nil {
+			t.Fatalf("invalid profile: %v", err)
+		}
+
+		stks := stacks(p)
+		for _, want := range [][]string{
+			{"sync.(*Mutex).Unlock", "runtime/pprof.blockMutex.func1"},
+		} {
+			if !containsStack(stks, want) {
+				t.Errorf("No matching stack entry for %+v", want)
+			}
+		}
+	})
 }
 
 func func1(c chan int) { <-c }
@@ -712,7 +845,7 @@
 func TestCPUProfileLabel(t *testing.T) {
 	testCPUProfile(t, []string{"runtime/pprof.cpuHogger;key=value"}, func(dur time.Duration) {
 		Do(context.Background(), Labels("key", "value"), func(context.Context) {
-			cpuHogger(cpuHog1, dur)
+			cpuHogger(cpuHog1, &salt1, dur)
 		})
 	})
 }
@@ -725,14 +858,15 @@
 		start := time.Now()
 		var wg sync.WaitGroup
 		for time.Since(start) < dur {
+			var salts [10]int
 			for i := 0; i < 10; i++ {
 				wg.Add(1)
-				go func() {
+				go func(j int) {
 					Do(context.Background(), Labels("key", "value"), func(context.Context) {
-						cpuHogger(cpuHog1, time.Millisecond)
+						cpuHogger(cpuHog1, &salts[j], time.Millisecond)
 					})
 					wg.Done()
-				}()
+				}(i)
 			}
 			wg.Wait()
 		}
diff --git a/src/runtime/print.go b/src/runtime/print.go
index 8fa3d39..7b2e4f4 100644
--- a/src/runtime/print.go
+++ b/src/runtime/print.go
@@ -6,6 +6,7 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -56,7 +57,7 @@
 
 // The compiler emits calls to printlock and printunlock around
 // the multiple calls that implement a single Go print or println
-// statement. Some of the print helpers (printsp, for example)
+// statement. Some of the print helpers (printslice, for example)
 // call print recursively. There is also the problem of a crash
 // happening during the print routines and needing to acquire
 // the print lock to print information about the crash.
@@ -98,31 +99,31 @@
 }
 
 func printsp() {
-	print(" ")
+	printstring(" ")
 }
 
 func printnl() {
-	print("\n")
+	printstring("\n")
 }
 
 func printbool(v bool) {
 	if v {
-		print("true")
+		printstring("true")
 	} else {
-		print("false")
+		printstring("false")
 	}
 }
 
 func printfloat(v float64) {
 	switch {
 	case v != v:
-		print("NaN")
+		printstring("NaN")
 		return
 	case v+v == v && v > 0:
-		print("+Inf")
+		printstring("+Inf")
 		return
 	case v+v == v && v < 0:
-		print("-Inf")
+		printstring("-Inf")
 		return
 	}
 
@@ -204,7 +205,7 @@
 
 func printint(v int64) {
 	if v < 0 {
-		print("-")
+		printstring("-")
 		v = -v
 	}
 	printuint(uint64(v))
@@ -249,3 +250,55 @@
 func printiface(i iface) {
 	print("(", i.tab, ",", i.data, ")")
 }
+
+// hexdumpWords prints a word-oriented hex dump of [p, end).
+//
+// If mark != nil, it will be called with each printed word's address
+// and should return a character mark to appear just before that
+// word's value. It can return 0 to indicate no mark.
+func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
+	p1 := func(x uintptr) {
+		var buf [2 * sys.PtrSize]byte
+		for i := len(buf) - 1; i >= 0; i-- {
+			if x&0xF < 10 {
+				buf[i] = byte(x&0xF) + '0'
+			} else {
+				buf[i] = byte(x&0xF) - 10 + 'a'
+			}
+			x >>= 4
+		}
+		gwrite(buf[:])
+	}
+
+	printlock()
+	var markbuf [1]byte
+	markbuf[0] = ' '
+	for i := uintptr(0); p+i < end; i += sys.PtrSize {
+		if i%16 == 0 {
+			if i != 0 {
+				println()
+			}
+			p1(p + i)
+			print(": ")
+		}
+
+		if mark != nil {
+			markbuf[0] = mark(p + i)
+			if markbuf[0] == 0 {
+				markbuf[0] = ' '
+			}
+		}
+		gwrite(markbuf[:])
+		val := *(*uintptr)(unsafe.Pointer(p + i))
+		p1(val)
+		print(" ")
+
+		// Can we symbolize val?
+		fn := findfunc(val)
+		if fn.valid() {
+			print("<", funcname(fn), "+", val-fn.entry, "> ")
+		}
+	}
+	println()
+	printunlock()
+}
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index ed333bb..2e958f7 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -96,6 +96,9 @@
 //go:linkname main_main main.main
 func main_main()
 
+// mainStarted indicates that the main M has started.
+var mainStarted bool
+
 // runtimeInitTime is the nanotime() at which the runtime started.
 var runtimeInitTime int64
 
@@ -119,8 +122,8 @@
 		maxstacksize = 250000000
 	}
 
-	// Record when the world started.
-	runtimeInitTime = nanotime()
+	// Allow newproc to start new Ms.
+	mainStarted = true
 
 	systemstack(func() {
 		newm(sysmon, nil)
@@ -139,6 +142,9 @@
 	}
 
 	runtime_init() // must be before defer
+	if nanotime() == 0 {
+		throw("nanotime returning zero")
+	}
 
 	// Defer unlock so that runtime.Goexit during init does the unlock too.
 	needUnlock := true
@@ -148,6 +154,10 @@
 		}
 	}()
 
+	// Record when the world started. Must be after runtime_init
+	// because nanotime on some platforms depends on startNano.
+	runtimeInitTime = nanotime()
+
 	gcenable()
 
 	main_init_done = make(chan bool)
@@ -166,6 +176,9 @@
 		if _cgo_notify_runtime_init_done == nil {
 			throw("_cgo_notify_runtime_init_done missing")
 		}
+		// Start the template thread in case we enter Go from
+		// a C-created thread and need to create a new thread.
+		startTemplateThread()
 		cgocall(_cgo_notify_runtime_init_done, nil)
 	}
 
@@ -242,9 +255,10 @@
 	}
 }
 
+//go:nosplit
+
 // Gosched yields the processor, allowing other goroutines to run. It does not
 // suspend the current goroutine, so execution resumes automatically.
-//go:nosplit
 func Gosched() {
 	mcall(gosched_m)
 }
@@ -332,8 +346,8 @@
 	if s.elem != nil {
 		throw("runtime: sudog with non-nil elem")
 	}
-	if s.selectdone != nil {
-		throw("runtime: sudog with non-nil selectdone")
+	if s.isSelect {
+		throw("runtime: sudog with non-false isSelect")
 	}
 	if s.next != nil {
 		throw("runtime: sudog with non-nil next")
@@ -422,7 +436,7 @@
 
 func lockedOSThread() bool {
 	gp := getg()
-	return gp.lockedm != nil && gp.m.lockedg != nil
+	return gp.lockedm != 0 && gp.m.lockedg != 0
 }
 
 var (
@@ -488,13 +502,21 @@
 	if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
 		procs = n
 	}
-	if procs > _MaxGomaxprocs {
-		procs = _MaxGomaxprocs
-	}
 	if procresize(procs) != nil {
 		throw("unknown runnable goroutine during bootstrap")
 	}
 
+	// For cgocheck > 1, we turn on the write barrier at all times
+	// and check all pointer writes. We can't do this until after
+	// procresize because the write barrier needs a P.
+	if debug.cgocheck > 1 {
+		writeBarrier.cgo = true
+		writeBarrier.enabled = true
+		for _, p := range allp {
+			p.wbBuf.reset()
+		}
+	}
+
 	if buildVersion == "" {
 		// Condition should never trigger. This code just serves
 		// to ensure runtime·buildVersion is kept in the resulting binary.
@@ -510,7 +532,7 @@
 
 func checkmcount() {
 	// sched lock is held
-	if sched.mcount > sched.maxmcount {
+	if mcount() > sched.maxmcount {
 		print("runtime: program exceeds ", sched.maxmcount, "-thread limit\n")
 		throw("thread exhaustion")
 	}
@@ -524,15 +546,20 @@
 		callers(1, mp.createstack[:])
 	}
 
-	mp.fastrand = 0x49f6428a + uint32(mp.id) + uint32(cputicks())
-	if mp.fastrand == 0 {
-		mp.fastrand = 0x49f6428a
+	lock(&sched.lock)
+	if sched.mnext+1 < sched.mnext {
+		throw("runtime: thread ID overflow")
+	}
+	mp.id = sched.mnext
+	sched.mnext++
+	checkmcount()
+
+	mp.fastrand[0] = 1597334677 * uint32(mp.id)
+	mp.fastrand[1] = uint32(cputicks())
+	if mp.fastrand[0]|mp.fastrand[1] == 0 {
+		mp.fastrand[1] = 1
 	}
 
-	lock(&sched.lock)
-	mp.id = sched.mcount
-	sched.mcount++
-	checkmcount()
 	mpreinit(mp)
 	if mp.gsignal != nil {
 		mp.gsignal.stackguard1 = mp.gsignal.stack.lo + _StackGuard
@@ -755,8 +782,10 @@
 		// _Grunning or _Grunning|_Gscan; either way,
 		// we own gp.gcscanvalid, so it's safe to read.
 		// gp.gcscanvalid must not be true when we are running.
-		print("runtime: casgstatus ", hex(oldval), "->", hex(newval), " gp.status=", hex(gp.atomicstatus), " gp.gcscanvalid=true\n")
-		throw("casgstatus")
+		systemstack(func() {
+			print("runtime: casgstatus ", hex(oldval), "->", hex(newval), " gp.status=", hex(gp.atomicstatus), " gp.gcscanvalid=true\n")
+			throw("casgstatus")
+		})
 	}
 
 	// See http://golang.org/cl/21503 for justification of the yield delay.
@@ -941,7 +970,7 @@
 
 // startTheWorld undoes the effects of stopTheWorld.
 func startTheWorld() {
-	systemstack(startTheWorldWithSema)
+	systemstack(func() { startTheWorldWithSema(false) })
 	// worldsema must be held over startTheWorldWithSema to ensure
 	// gomaxprocs cannot change while worldsema is held.
 	semrelease(&worldsema)
@@ -991,8 +1020,7 @@
 	_g_.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic.
 	sched.stopwait--
 	// try to retake all P's in Psyscall status
-	for i := 0; i < int(gomaxprocs); i++ {
-		p := allp[i]
+	for _, p := range allp {
 		s := p.status
 		if s == _Psyscall && atomic.Cas(&p.status, s, _Pgcstop) {
 			if trace.enabled {
@@ -1032,8 +1060,7 @@
 	if sched.stopwait != 0 {
 		bad = "stopTheWorld: not stopped (stopwait != 0)"
 	} else {
-		for i := 0; i < int(gomaxprocs); i++ {
-			p := allp[i]
+		for _, p := range allp {
 			if p.status != _Pgcstop {
 				bad = "stopTheWorld: not stopped (status != _Pgcstop)"
 			}
@@ -1057,12 +1084,14 @@
 	_g_.m.helpgc = -1
 }
 
-func startTheWorldWithSema() {
+func startTheWorldWithSema(emitTraceEvent bool) int64 {
 	_g_ := getg()
 
-	_g_.m.locks++        // disable preemption because it can be holding p in a local var
-	gp := netpoll(false) // non-blocking
-	injectglist(gp)
+	_g_.m.locks++ // disable preemption because it can be holding p in a local var
+	if netpollinited() {
+		gp := netpoll(false) // non-blocking
+		injectglist(gp)
+	}
 	add := needaddgcproc()
 	lock(&sched.lock)
 
@@ -1097,6 +1126,12 @@
 		}
 	}
 
+	// Capture start-the-world time before doing clean-up tasks.
+	startTime := nanotime()
+	if emitTraceEvent {
+		traceGCSTWDone()
+	}
+
 	// Wakeup an additional proc in case we have excessive runnable goroutines
 	// in local queues or in the global queue. If we don't, the proc will park itself.
 	// If we have lots of excessive work, resetspinning will unpark additional procs as necessary.
@@ -1118,14 +1153,25 @@
 	if _g_.m.locks == 0 && _g_.preempt { // restore the preemption request in case we've cleared it in newstack
 		_g_.stackguard0 = stackPreempt
 	}
+
+	return startTime
 }
 
 // Called to start an M.
+//
+// This must not split the stack because we may not even have stack
+// bounds set up yet.
+//
+// May run during STW (because it doesn't have a P yet), so write
+// barriers are not allowed.
+//
 //go:nosplit
+//go:nowritebarrierrec
 func mstart() {
 	_g_ := getg()
 
-	if _g_.stack.lo == 0 {
+	osStack := _g_.stack.lo == 0
+	if osStack {
 		// Initialize stack bounds from system stack.
 		// Cgo may have left stack size in stack.hi.
 		size := _g_.stack.hi
@@ -1139,33 +1185,37 @@
 	// both Go and C functions with stack growth prologues.
 	_g_.stackguard0 = _g_.stack.lo + _StackGuard
 	_g_.stackguard1 = _g_.stackguard0
-	mstart1()
+	mstart1(0)
+
+	// Exit this thread.
+	if GOOS == "windows" || GOOS == "solaris" || GOOS == "plan9" {
+		// Window, Solaris and Plan 9 always system-allocate
+		// the stack, but put it in _g_.stack before mstart,
+		// so the logic above hasn't set osStack yet.
+		osStack = true
+	}
+	mexit(osStack)
 }
 
-func mstart1() {
+func mstart1(dummy int32) {
 	_g_ := getg()
 
 	if _g_ != _g_.m.g0 {
 		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.
-	gosave(&_g_.m.g0.sched)
-	_g_.m.g0.sched.pc = ^uintptr(0) // make sure it is never used
+	// Record the caller for use as the top of stack in mcall and
+	// for terminating the thread.
+	// We're never coming back to mstart1 after we call schedule,
+	// so other calls can reuse the current frame.
+	save(getcallerpc(), getcallersp(unsafe.Pointer(&dummy)))
 	asminit()
 	minit()
 
 	// Install signal handlers; after minit so that minit can
 	// prepare the thread to be able to handle the signals.
 	if _g_.m == &m0 {
-		// Create an extra M for callbacks on threads not created by Go.
-		if iscgo && !cgoHasExtraM {
-			cgoHasExtraM = true
-			newextram()
-		}
-		initsig(false)
+		mstartm0()
 	}
 
 	if fn := _g_.m.mstartfn; fn != nil {
@@ -1182,6 +1232,114 @@
 	schedule()
 }
 
+// mstartm0 implements part of mstart1 that only runs on the m0.
+//
+// Write barriers are allowed here because we know the GC can't be
+// running yet, so they'll be no-ops.
+//
+//go:yeswritebarrierrec
+func mstartm0() {
+	// Create an extra M for callbacks on threads not created by Go.
+	if iscgo && !cgoHasExtraM {
+		cgoHasExtraM = true
+		newextram()
+	}
+	initsig(false)
+}
+
+// mexit tears down and exits the current thread.
+//
+// Don't call this directly to exit the thread, since it must run at
+// the top of the thread stack. Instead, use gogo(&_g_.m.g0.sched) to
+// unwind the stack to the point that exits the thread.
+//
+// It is entered with m.p != nil, so write barriers are allowed. It
+// will release the P before exiting.
+//
+//go:yeswritebarrierrec
+func mexit(osStack bool) {
+	g := getg()
+	m := g.m
+
+	if m == &m0 {
+		// This is the main thread. Just wedge it.
+		//
+		// On Linux, exiting the main thread puts the process
+		// into a non-waitable zombie state. On Plan 9,
+		// exiting the main thread unblocks wait even though
+		// other threads are still running. On Solaris we can
+		// neither exitThread nor return from mstart. Other
+		// bad things probably happen on other platforms.
+		//
+		// We could try to clean up this M more before wedging
+		// it, but that complicates signal handling.
+		handoffp(releasep())
+		lock(&sched.lock)
+		sched.nmfreed++
+		checkdead()
+		unlock(&sched.lock)
+		notesleep(&m.park)
+		throw("locked m0 woke up")
+	}
+
+	sigblock()
+	unminit()
+
+	// Free the gsignal stack.
+	if m.gsignal != nil {
+		stackfree(m.gsignal.stack)
+	}
+
+	// Remove m from allm.
+	lock(&sched.lock)
+	for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink {
+		if *pprev == m {
+			*pprev = m.alllink
+			goto found
+		}
+	}
+	throw("m not found in allm")
+found:
+	if !osStack {
+		// Delay reaping m until it's done with the stack.
+		//
+		// If this is using an OS stack, the OS will free it
+		// so there's no need for reaping.
+		atomic.Store(&m.freeWait, 1)
+		// Put m on the free list, though it will not be reaped until
+		// freeWait is 0. Note that the free list must not be linked
+		// through alllink because some functions walk allm without
+		// locking, so may be using alllink.
+		m.freelink = sched.freem
+		sched.freem = m
+	}
+	unlock(&sched.lock)
+
+	// Release the P.
+	handoffp(releasep())
+	// After this point we must not have write barriers.
+
+	// Invoke the deadlock detector. This must happen after
+	// handoffp because it may have started a new M to take our
+	// P's work.
+	lock(&sched.lock)
+	sched.nmfreed++
+	checkdead()
+	unlock(&sched.lock)
+
+	if osStack {
+		// Return from mstart and let the system thread
+		// library free the g0 stack and terminate the thread.
+		return
+	}
+
+	// mstart is the thread's entry point, so there's nothing to
+	// return to. Exit the thread directly. exitThread will clear
+	// m.freeWait when it's done with the stack and the m can be
+	// reaped.
+	exitThread(&m.freeWait)
+}
+
 // forEachP calls fn(p) for every P p when p reaches a GC safe point.
 // If a P is currently executing code, this will bring the P to a GC
 // safe point and execute fn on that P. If the P is not executing code
@@ -1205,7 +1363,7 @@
 	sched.safePointFn = fn
 
 	// Ask all Ps to run the safe point function.
-	for _, p := range allp[:gomaxprocs] {
+	for _, p := range allp {
 		if p != _p_ {
 			atomic.Store(&p.runSafePointFn, 1)
 		}
@@ -1233,8 +1391,7 @@
 
 	// Force Ps currently in _Psyscall into _Pidle and hand them
 	// off to induce safe point function execution.
-	for i := 0; i < int(gomaxprocs); i++ {
-		p := allp[i]
+	for _, p := range allp {
 		s := p.status
 		if s == _Psyscall && p.runSafePointFn == 1 && atomic.Cas(&p.status, s, _Pidle) {
 			if trace.enabled {
@@ -1263,8 +1420,7 @@
 	if sched.safePointWait != 0 {
 		throw("forEachP: not done")
 	}
-	for i := 0; i < int(gomaxprocs); i++ {
-		p := allp[i]
+	for _, p := range allp {
 		if p.runSafePointFn != 0 {
 			throw("forEachP: P did not run fn")
 		}
@@ -1329,6 +1485,27 @@
 	if _g_.m.p == 0 {
 		acquirep(_p_) // temporarily borrow p for mallocs in this function
 	}
+
+	// Release the free M list. We need to do this somewhere and
+	// this may free up a stack we can use.
+	if sched.freem != nil {
+		lock(&sched.lock)
+		var newList *m
+		for freem := sched.freem; freem != nil; {
+			if freem.freeWait != 0 {
+				next := freem.freelink
+				freem.freelink = newList
+				newList = freem
+				freem = next
+				continue
+			}
+			stackfree(freem.g0.stack)
+			freem = freem.freelink
+		}
+		sched.freem = newList
+		unlock(&sched.lock)
+	}
+
 	mp := new(m)
 	mp.mstartfn = fn
 	mcommoninit(mp)
@@ -1488,9 +1665,9 @@
 	casgstatus(gp, _Gidle, _Gdead)
 	gp.m = mp
 	mp.curg = gp
-	mp.locked = _LockInternal
-	mp.lockedg = gp
-	gp.lockedm = mp
+	mp.lockedInt++
+	mp.lockedg.set(gp)
+	gp.lockedm.set(mp)
 	gp.goid = int64(atomic.Xadd64(&sched.goidgen, 1))
 	if raceenabled {
 		gp.racectx = racegostart(funcPC(newextram) + sys.PCQuantum)
@@ -1619,6 +1796,27 @@
 // around exec'ing while creating/destroying threads.  See issue #19546.
 var execLock rwmutex
 
+// newmHandoff contains a list of m structures that need new OS threads.
+// This is used by newm in situations where newm itself can't safely
+// start an OS thread.
+var newmHandoff struct {
+	lock mutex
+
+	// newm points to a list of M structures that need new OS
+	// threads. The list is linked through m.schedlink.
+	newm muintptr
+
+	// waiting indicates that wake needs to be notified when an m
+	// is put on the list.
+	waiting bool
+	wake    note
+
+	// haveTemplateThread indicates that the templateThread has
+	// been started. This is not protected by lock. Use cas to set
+	// to 1.
+	haveTemplateThread uint32
+}
+
 // Create a new m. It will start off with a call to fn, or else the scheduler.
 // fn needs to be static and not a heap allocated closure.
 // May run with m.p==nil, so write barriers are not allowed.
@@ -1627,6 +1825,35 @@
 	mp := allocm(_p_, fn)
 	mp.nextp.set(_p_)
 	mp.sigmask = initSigmask
+	if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" {
+		// We're on a locked M or a thread that may have been
+		// started by C. The kernel state of this thread may
+		// be strange (the user may have locked it for that
+		// purpose). We don't want to clone that into another
+		// thread. Instead, ask a known-good thread to create
+		// the thread for us.
+		//
+		// This is disabled on Plan 9. See golang.org/issue/22227.
+		//
+		// TODO: This may be unnecessary on Windows, which
+		// doesn't model thread creation off fork.
+		lock(&newmHandoff.lock)
+		if newmHandoff.haveTemplateThread == 0 {
+			throw("on a locked thread with no template thread")
+		}
+		mp.schedlink = newmHandoff.newm
+		newmHandoff.newm.set(mp)
+		if newmHandoff.waiting {
+			newmHandoff.waiting = false
+			notewakeup(&newmHandoff.wake)
+		}
+		unlock(&newmHandoff.lock)
+		return
+	}
+	newm1(mp)
+}
+
+func newm1(mp *m) {
 	if iscgo {
 		var ts cgothreadstart
 		if _cgo_thread_start == nil {
@@ -1648,6 +1875,56 @@
 	execLock.runlock()
 }
 
+// startTemplateThread starts the template thread if it is not already
+// running.
+//
+// The calling thread must itself be in a known-good state.
+func startTemplateThread() {
+	if !atomic.Cas(&newmHandoff.haveTemplateThread, 0, 1) {
+		return
+	}
+	newm(templateThread, nil)
+}
+
+// tmeplateThread is a thread in a known-good state that exists solely
+// to start new threads in known-good states when the calling thread
+// may not be a a good state.
+//
+// Many programs never need this, so templateThread is started lazily
+// when we first enter a state that might lead to running on a thread
+// in an unknown state.
+//
+// templateThread runs on an M without a P, so it must not have write
+// barriers.
+//
+//go:nowritebarrierrec
+func templateThread() {
+	lock(&sched.lock)
+	sched.nmsys++
+	checkdead()
+	unlock(&sched.lock)
+
+	for {
+		lock(&newmHandoff.lock)
+		for newmHandoff.newm != 0 {
+			newm := newmHandoff.newm.ptr()
+			newmHandoff.newm = 0
+			unlock(&newmHandoff.lock)
+			for newm != nil {
+				next := newm.schedlink.ptr()
+				newm.schedlink = 0
+				newm1(newm)
+				newm = next
+			}
+			lock(&newmHandoff.lock)
+		}
+		newmHandoff.waiting = true
+		noteclear(&newmHandoff.wake)
+		unlock(&newmHandoff.lock)
+		notesleep(&newmHandoff.wake)
+	}
+}
+
 // Stops execution of the current m until new work is available.
 // Returns with acquired P.
 func stopm() {
@@ -1670,7 +1947,9 @@
 	notesleep(&_g_.m.park)
 	noteclear(&_g_.m.park)
 	if _g_.m.helpgc != 0 {
+		// helpgc() set _g_.m.p and _g_.m.mcache, so we have a P.
 		gchelper()
+		// Undo the effects of helpgc().
 		_g_.m.helpgc = 0
 		_g_.m.mcache = nil
 		_g_.m.p = 0
@@ -1804,7 +2083,7 @@
 func stoplockedm() {
 	_g_ := getg()
 
-	if _g_.m.lockedg == nil || _g_.m.lockedg.lockedm != _g_.m {
+	if _g_.m.lockedg == 0 || _g_.m.lockedg.ptr().lockedm.ptr() != _g_.m {
 		throw("stoplockedm: inconsistent locking")
 	}
 	if _g_.m.p != 0 {
@@ -1816,7 +2095,7 @@
 	// Wait until another thread schedules lockedg again.
 	notesleep(&_g_.m.park)
 	noteclear(&_g_.m.park)
-	status := readgstatus(_g_.m.lockedg)
+	status := readgstatus(_g_.m.lockedg.ptr())
 	if status&^_Gscan != _Grunnable {
 		print("runtime:stoplockedm: g is not Grunnable or Gscanrunnable\n")
 		dumpgstatus(_g_)
@@ -1832,7 +2111,7 @@
 func startlockedm(gp *g) {
 	_g_ := getg()
 
-	mp := gp.lockedm
+	mp := gp.lockedm.ptr()
 	if mp == _g_.m {
 		throw("startlockedm: locked to me")
 	}
@@ -1958,11 +2237,12 @@
 
 	// Poll network.
 	// This netpoll is only an optimization before we resort to stealing.
-	// We can safely skip it if there a thread blocked in netpoll already.
-	// If there is any kind of logical race with that blocked thread
-	// (e.g. it has already returned from netpoll, but does not set lastpoll yet),
-	// this thread will do blocking netpoll below anyway.
-	if netpollinited() && sched.lastpoll != 0 {
+	// We can safely skip it if there are no waiters or a thread is blocked
+	// in netpoll already. If there is any kind of logical race with that
+	// blocked thread (e.g. it has already returned from netpoll, but does
+	// not set lastpoll yet), this thread will do blocking netpoll below
+	// anyway.
+	if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Load64(&sched.lastpoll) != 0 {
 		if gp := netpoll(false); gp != nil { // non-blocking
 			// netpoll returns list of goroutines linked by schedlink.
 			injectglist(gp.schedlink.ptr())
@@ -2019,6 +2299,12 @@
 		return gp, false
 	}
 
+	// Before we drop our P, make a snapshot of the allp slice,
+	// which can change underfoot once we no longer block
+	// safe-points. We don't need to snapshot the contents because
+	// everything up to cap(allp) is immutable.
+	allpSnapshot := allp
+
 	// return P and block
 	lock(&sched.lock)
 	if sched.gcwaiting != 0 || _p_.runSafePointFn != 0 {
@@ -2058,9 +2344,8 @@
 	}
 
 	// check all runqueues once again
-	for i := 0; i < int(gomaxprocs); i++ {
-		_p_ := allp[i]
-		if _p_ != nil && !runqempty(_p_) {
+	for _, _p_ := range allpSnapshot {
+		if !runqempty(_p_) {
 			lock(&sched.lock)
 			_p_ = pidleget()
 			unlock(&sched.lock)
@@ -2199,9 +2484,15 @@
 		throw("schedule: holding locks")
 	}
 
-	if _g_.m.lockedg != nil {
+	if _g_.m.lockedg != 0 {
 		stoplockedm()
-		execute(_g_.m.lockedg, false) // Never returns.
+		execute(_g_.m.lockedg.ptr(), false) // Never returns.
+	}
+
+	// We should not schedule away from a g that is executing a cgo call,
+	// since the cgo call is using the m's g0 stack.
+	if _g_.m.incgo {
+		throw("schedule: in cgo")
 	}
 
 top:
@@ -2252,7 +2543,7 @@
 		resetspinning()
 	}
 
-	if gp.lockedm != nil {
+	if gp.lockedm != 0 {
 		// Hands off own p to the locked m,
 		// then blocks waiting for a new p.
 		startlockedm(gp)
@@ -2371,8 +2662,9 @@
 		atomic.Xadd(&sched.ngsys, -1)
 	}
 	gp.m = nil
-	gp.lockedm = nil
-	_g_.m.lockedg = nil
+	locked := gp.lockedm != 0
+	gp.lockedm = 0
+	_g_.m.lockedg = 0
 	gp.paniconfault = false
 	gp._defer = nil // should be true already but just in case.
 	gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data.
@@ -2382,17 +2674,37 @@
 	gp.labels = nil
 	gp.timer = nil
 
+	if gcBlackenEnabled != 0 && gp.gcAssistBytes > 0 {
+		// Flush assist credit to the global pool. This gives
+		// better information to pacing if the application is
+		// rapidly creating an exiting goroutines.
+		scanCredit := int64(gcController.assistWorkPerByte * float64(gp.gcAssistBytes))
+		atomic.Xaddint64(&gcController.bgScanCredit, scanCredit)
+		gp.gcAssistBytes = 0
+	}
+
 	// Note that gp's stack scan is now "valid" because it has no
 	// stack.
 	gp.gcscanvalid = true
 	dropg()
 
-	if _g_.m.locked&^_LockExternal != 0 {
-		print("invalid m->locked = ", _g_.m.locked, "\n")
+	if _g_.m.lockedInt != 0 {
+		print("invalid m->lockedInt = ", _g_.m.lockedInt, "\n")
 		throw("internal lockOSThread error")
 	}
-	_g_.m.locked = 0
+	_g_.m.lockedExt = 0
 	gfput(_g_.m.p.ptr(), gp)
+	if locked {
+		// The goroutine may have locked this thread because
+		// it put it in an unusual kernel state. Kill it
+		// rather than returning it to the thread pool.
+
+		// Return to mstart, which will release the P and exit
+		// the thread.
+		if GOOS != "plan9" { // See golang.org/issue/22227.
+			gogo(&_g_.m.g0.sched)
+		}
+	}
 	schedule()
 }
 
@@ -2522,7 +2834,7 @@
 // Standard syscall entry used by the go syscall library and normal cgo calls.
 //go:nosplit
 func entersyscall(dummy int32) {
-	reentersyscall(getcallerpc(unsafe.Pointer(&dummy)), getcallersp(unsafe.Pointer(&dummy)))
+	reentersyscall(getcallerpc(), getcallersp(unsafe.Pointer(&dummy)))
 }
 
 func entersyscall_sysmon() {
@@ -2565,7 +2877,7 @@
 	_g_.m.p.ptr().syscalltick++
 
 	// Leave SP around for GC and traceback.
-	pc := getcallerpc(unsafe.Pointer(&dummy))
+	pc := getcallerpc()
 	sp := getcallersp(unsafe.Pointer(&dummy))
 	save(pc, sp)
 	_g_.syscallsp = _g_.sched.sp
@@ -2590,7 +2902,7 @@
 	systemstack(entersyscallblock_handoff)
 
 	// Resave for traceback during blocked call.
-	save(getcallerpc(unsafe.Pointer(&dummy)), getcallersp(unsafe.Pointer(&dummy)))
+	save(getcallerpc(), getcallersp(unsafe.Pointer(&dummy)))
 
 	_g_.m.locks--
 }
@@ -2629,7 +2941,9 @@
 	oldp := _g_.m.p.ptr()
 	if exitsyscallfast() {
 		if _g_.m.mcache == nil {
-			throw("lost mcache")
+			systemstack(func() {
+				throw("lost mcache")
+			})
 		}
 		if trace.enabled {
 			if oldp != _g_.m.p.ptr() || _g_.m.syscalltick != _g_.m.p.ptr().syscalltick {
@@ -2676,7 +2990,9 @@
 	mcall(exitsyscall0)
 
 	if _g_.m.mcache == nil {
-		throw("lost mcache")
+		systemstack(func() {
+			throw("lost mcache")
+		})
 	}
 
 	// Scheduler returned, so we're allowed to run now.
@@ -2800,7 +3116,7 @@
 		acquirep(_p_)
 		execute(gp, false) // Never returns.
 	}
-	if _g_.m.lockedg != nil {
+	if _g_.m.lockedg != 0 {
 		// Wait until another thread schedules gp and so m again.
 		stoplockedm()
 		execute(gp, false) // Never returns.
@@ -2918,17 +3234,16 @@
 //go:nosplit
 func newproc(siz int32, fn *funcval) {
 	argp := add(unsafe.Pointer(&fn), sys.PtrSize)
-	pc := getcallerpc(unsafe.Pointer(&siz))
+	pc := getcallerpc()
 	systemstack(func() {
-		newproc1(fn, (*uint8)(argp), siz, 0, pc)
+		newproc1(fn, (*uint8)(argp), siz, pc)
 	})
 }
 
 // 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.
-func newproc1(fn *funcval, argp *uint8, narg int32, nret int32, callerpc uintptr) *g {
+// at argp. 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.
+func newproc1(fn *funcval, argp *uint8, narg int32, callerpc uintptr) {
 	_g_ := getg()
 
 	if fn == nil {
@@ -2936,7 +3251,7 @@
 		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 := narg
 	siz = (siz + 7) &^ 7
 
 	// We could allocate a larger initial stack if necessary.
@@ -3024,14 +3339,13 @@
 	}
 	runqput(_p_, newg, true)
 
-	if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 && runtimeInitTime != 0 {
+	if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 && mainStarted {
 		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.
@@ -3150,23 +3464,41 @@
 //go:nosplit
 func dolockOSThread() {
 	_g_ := getg()
-	_g_.m.lockedg = _g_
-	_g_.lockedm = _g_.m
+	_g_.m.lockedg.set(_g_)
+	_g_.lockedm.set(_g_.m)
 }
 
 //go:nosplit
 
 // 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.
+// The calling goroutine will always execute in that thread,
+// and no other goroutine will execute in it,
+// until the calling goroutine has made as many calls to
+// UnlockOSThread as to LockOSThread.
+// If the calling goroutine exits without unlocking the thread,
+// the thread will be terminated.
+//
+// A goroutine should call LockOSThread before calling OS services or
+// non-Go library functions that depend on per-thread state.
 func LockOSThread() {
-	getg().m.locked |= _LockExternal
+	if atomic.Load(&newmHandoff.haveTemplateThread) == 0 && GOOS != "plan9" {
+		// If we need to start a new thread from the locked
+		// thread, we need the template thread. Start it now
+		// while we're in a known-good state.
+		startTemplateThread()
+	}
+	_g_ := getg()
+	_g_.m.lockedExt++
+	if _g_.m.lockedExt == 0 {
+		_g_.m.lockedExt--
+		panic("LockOSThread nesting overflow")
+	}
 	dolockOSThread()
 }
 
 //go:nosplit
 func lockOSThread() {
-	getg().m.locked += _LockInternal
+	getg().m.lockedInt++
 	dolockOSThread()
 }
 
@@ -3176,29 +3508,43 @@
 //go:nosplit
 func dounlockOSThread() {
 	_g_ := getg()
-	if _g_.m.locked != 0 {
+	if _g_.m.lockedInt != 0 || _g_.m.lockedExt != 0 {
 		return
 	}
-	_g_.m.lockedg = nil
-	_g_.lockedm = nil
+	_g_.m.lockedg = 0
+	_g_.lockedm = 0
 }
 
 //go:nosplit
 
-// UnlockOSThread unwires the calling goroutine from its fixed operating system thread.
-// If the calling goroutine has not called LockOSThread, UnlockOSThread is a no-op.
+// UnlockOSThread undoes an earlier call to LockOSThread.
+// If this drops the number of active LockOSThread calls on the
+// calling goroutine to zero, it unwires the calling goroutine from
+// its fixed operating system thread.
+// If there are no active LockOSThread calls, this is a no-op.
+//
+// Before calling UnlockOSThread, the caller must ensure that the OS
+// thread is suitable for running other goroutines. If the caller made
+// any permanent changes to the state of the thread that would affect
+// other goroutines, it should not call this function and thus leave
+// the goroutine locked to the OS thread until the goroutine (and
+// hence the thread) exits.
 func UnlockOSThread() {
-	getg().m.locked &^= _LockExternal
+	_g_ := getg()
+	if _g_.m.lockedExt == 0 {
+		return
+	}
+	_g_.m.lockedExt--
 	dounlockOSThread()
 }
 
 //go:nosplit
 func unlockOSThread() {
 	_g_ := getg()
-	if _g_.m.locked < _LockInternal {
+	if _g_.m.lockedInt == 0 {
 		systemstack(badunlockosthread)
 	}
-	_g_.m.locked -= _LockInternal
+	_g_.m.lockedInt--
 	dounlockOSThread()
 }
 
@@ -3208,10 +3554,7 @@
 
 func gcount() int32 {
 	n := int32(allglen) - sched.ngfree - int32(atomic.Load(&sched.ngsys))
-	for _, _p_ := range &allp {
-		if _p_ == nil {
-			break
-		}
+	for _, _p_ := range allp {
 		n -= _p_.gfreecnt
 	}
 
@@ -3224,7 +3567,7 @@
 }
 
 func mcount() int32 {
-	return sched.mcount
+	return int32(sched.mnext - sched.nmfreed)
 }
 
 var prof struct {
@@ -3506,7 +3849,7 @@
 // Returns list of Ps with local work, they need to be scheduled by the caller.
 func procresize(nprocs int32) *p {
 	old := gomaxprocs
-	if old < 0 || old > _MaxGomaxprocs || nprocs <= 0 || nprocs > _MaxGomaxprocs {
+	if old < 0 || nprocs <= 0 {
 		throw("procresize: invalid arg")
 	}
 	if trace.enabled {
@@ -3520,6 +3863,23 @@
 	}
 	sched.procresizetime = now
 
+	// Grow allp if necessary.
+	if nprocs > int32(len(allp)) {
+		// Synchronize with retake, which could be running
+		// concurrently since it doesn't run on a P.
+		lock(&allpLock)
+		if nprocs <= int32(cap(allp)) {
+			allp = allp[:nprocs]
+		} else {
+			nallp := make([]*p, nprocs)
+			// Copy everything up to allp's cap so we
+			// never lose old allocated Ps.
+			copy(nallp, allp[:cap(allp)])
+			allp = nallp
+		}
+		unlock(&allpLock)
+	}
+
 	// initialize new P's
 	for i := int32(0); i < nprocs; i++ {
 		pp := allp[i]
@@ -3531,6 +3891,7 @@
 			for i := range pp.deferpool {
 				pp.deferpool[i] = pp.deferpoolbuf[i][:0]
 			}
+			pp.wbBuf.reset()
 			atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp))
 		}
 		if pp.mcache == nil {
@@ -3556,13 +3917,11 @@
 	// free unused P's
 	for i := nprocs; i < old; i++ {
 		p := allp[i]
-		if trace.enabled {
-			if p == getg().m.p.ptr() {
-				// moving to p[0], pretend that we were descheduled
-				// and then scheduled again to keep the trace sane.
-				traceGoSched()
-				traceProcStop(p)
-			}
+		if trace.enabled && p == getg().m.p.ptr() {
+			// moving to p[0], pretend that we were descheduled
+			// and then scheduled again to keep the trace sane.
+			traceGoSched()
+			traceProcStop(p)
 		}
 		// move all runnable goroutines to the global queue
 		for p.runqhead != p.runqtail {
@@ -3588,6 +3947,11 @@
 			// world is stopped.
 			p.gcBgMarkWorker.set(nil)
 		}
+		// Flush p's write barrier buffer.
+		if gcphase != _GCoff {
+			wbBufFlush1(p)
+			p.gcw.dispose()
+		}
 		for i := range p.sudogbuf {
 			p.sudogbuf[i] = nil
 		}
@@ -3606,10 +3970,18 @@
 			raceprocdestroy(p.racectx)
 			p.racectx = 0
 		}
+		p.gcAssistTime = 0
 		p.status = _Pdead
 		// can't free P itself because it can be referenced by an M in syscall
 	}
 
+	// Trim allp.
+	if int32(len(allp)) != nprocs {
+		lock(&allpLock)
+		allp = allp[:nprocs]
+		unlock(&allpLock)
+	}
+
 	_g_ := getg()
 	if _g_.m.p != 0 && _g_.m.p.ptr().id < nprocs {
 		// continue to use the current P
@@ -3681,7 +4053,7 @@
 		throw("acquirep: already in go")
 	}
 	if _p_.m != 0 || _p_.status != _Pidle {
-		id := int32(0)
+		id := int64(0)
 		if _p_.m != 0 {
 			id = _p_.m.ptr().id
 		}
@@ -3726,6 +4098,7 @@
 
 // Check for deadlock situation.
 // The check is based on number of running M's, if 0 -> deadlock.
+// sched.lock must be held.
 func checkdead() {
 	// For -buildmode=c-shared or -buildmode=c-archive it's OK if
 	// there are no running goroutines. The calling program is
@@ -3742,13 +4115,12 @@
 		return
 	}
 
-	// -1 for sysmon
-	run := sched.mcount - sched.nmidle - sched.nmidlelocked - 1
+	run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys
 	if run > 0 {
 		return
 	}
 	if run < 0 {
-		print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", sched.mcount, "\n")
+		print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", mcount(), " nmsys=", sched.nmsys, "\n")
 		throw("checkdead: inconsistent counts")
 	}
 
@@ -3811,6 +4183,11 @@
 //
 //go:nowritebarrierrec
 func sysmon() {
+	lock(&sched.lock)
+	sched.nmsys++
+	checkdead()
+	unlock(&sched.lock)
+
 	// If a heap span goes unused for 5 minutes after a garbage collection,
 	// we hand it back to the operating system.
 	scavengelimit := int64(5 * 60 * 1e9)
@@ -3850,15 +4227,11 @@
 				}
 				shouldRelax := true
 				if osRelaxMinNS > 0 {
-					lock(&timers.lock)
-					if timers.sleeping {
-						now := nanotime()
-						next := timers.sleepUntil
-						if next-now < osRelaxMinNS {
-							shouldRelax = false
-						}
+					next := timeSleepUntil()
+					now := nanotime()
+					if next-now < osRelaxMinNS {
+						shouldRelax = false
 					}
-					unlock(&timers.lock)
 				}
 				if shouldRelax {
 					osRelax(true)
@@ -3882,7 +4255,7 @@
 		// poll network if not polled for more than 10ms
 		lastpoll := int64(atomic.Load64(&sched.lastpoll))
 		now := nanotime()
-		if lastpoll != 0 && lastpoll+10*1000*1000 < now {
+		if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now {
 			atomic.Cas64(&sched.lastpoll, uint64(lastpoll), uint64(now))
 			gp := netpoll(false) // non-blocking - returns list of goroutines
 			if gp != nil {
@@ -3939,9 +4312,17 @@
 
 func retake(now int64) uint32 {
 	n := 0
-	for i := int32(0); i < gomaxprocs; i++ {
+	// Prevent allp slice changes. This lock will be completely
+	// uncontended unless we're already stopping the world.
+	lock(&allpLock)
+	// We can't use a range loop over allp because we may
+	// temporarily drop the allpLock. Hence, we need to re-fetch
+	// allp each time around the loop.
+	for i := 0; i < len(allp); i++ {
 		_p_ := allp[i]
 		if _p_ == nil {
+			// This can happen if procresize has grown
+			// allp but not yet created new Ps.
 			continue
 		}
 		pd := &_p_.sysmontick
@@ -3960,6 +4341,8 @@
 			if runqempty(_p_) && atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) > 0 && pd.syscallwhen+10*1000*1000 > now {
 				continue
 			}
+			// Drop allpLock so we can take sched.lock.
+			unlock(&allpLock)
 			// 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,
@@ -3975,6 +4358,7 @@
 				handoffp(_p_)
 			}
 			incidlelocked(1)
+			lock(&allpLock)
 		} else if s == _Prunning {
 			// Preempt G if it's running for too long.
 			t := int64(_p_.schedtick)
@@ -3989,6 +4373,7 @@
 			preemptone(_p_)
 		}
 	}
+	unlock(&allpLock)
 	return uint32(n)
 }
 
@@ -3999,9 +4384,8 @@
 // Returns true if preemption request was issued to at least one goroutine.
 func preemptall() bool {
 	res := false
-	for i := int32(0); i < gomaxprocs; i++ {
-		_p_ := allp[i]
-		if _p_ == nil || _p_.status != _Prunning {
+	for _, _p_ := range allp {
+		if _p_.status != _Prunning {
 			continue
 		}
 		if preemptone(_p_) {
@@ -4050,23 +4434,19 @@
 	}
 
 	lock(&sched.lock)
-	print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle, " threads=", sched.mcount, " spinningthreads=", sched.nmspinning, " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
+	print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle, " threads=", mcount(), " spinningthreads=", sched.nmspinning, " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
 	if detailed {
 		print(" gcwaiting=", sched.gcwaiting, " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait, "\n")
 	}
 	// We must be careful while reading data from P's, M's and G's.
 	// Even if we hold schedlock, most data can be changed concurrently.
 	// E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
-	for i := int32(0); i < gomaxprocs; i++ {
-		_p_ := allp[i]
-		if _p_ == nil {
-			continue
-		}
+	for i, _p_ := range allp {
 		mp := _p_.m.ptr()
 		h := atomic.Load(&_p_.runqhead)
 		t := atomic.Load(&_p_.runqtail)
 		if detailed {
-			id := int32(-1)
+			id := int64(-1)
 			if mp != nil {
 				id = mp.id
 			}
@@ -4079,7 +4459,7 @@
 				print("[")
 			}
 			print(t - h)
-			if i == gomaxprocs-1 {
+			if i == len(allp)-1 {
 				print("]\n")
 			}
 		}
@@ -4093,7 +4473,7 @@
 	for mp := allm; mp != nil; mp = mp.alllink {
 		_p_ := mp.p.ptr()
 		gp := mp.curg
-		lockedg := mp.lockedg
+		lockedg := mp.lockedg.ptr()
 		id1 := int32(-1)
 		if _p_ != nil {
 			id1 = _p_.id
@@ -4113,12 +4493,12 @@
 	for gi := 0; gi < len(allgs); gi++ {
 		gp := allgs[gi]
 		mp := gp.m
-		lockedm := gp.lockedm
-		id1 := int32(-1)
+		lockedm := gp.lockedm.ptr()
+		id1 := int64(-1)
 		if mp != nil {
 			id1 = mp.id
 		}
-		id2 := int32(-1)
+		id2 := int64(-1)
 		if lockedm != nil {
 			id2 = lockedm.id
 		}
@@ -4400,22 +4780,25 @@
 			if stealRunNextG {
 				// Try to steal from _p_.runnext.
 				if next := _p_.runnext; next != 0 {
-					// Sleep to ensure that _p_ isn't about to run the g we
-					// are about to steal.
-					// The important use case here is when the g running on _p_
-					// ready()s another g and then almost immediately blocks.
-					// Instead of stealing runnext in this window, back off
-					// to give _p_ a chance to schedule runnext. This will avoid
-					// thrashing gs between different Ps.
-					// A sync chan send/recv takes ~50ns as of time of writing,
-					// so 3us gives ~50x overshoot.
-					if GOOS != "windows" {
-						usleep(3)
-					} else {
-						// On windows system timer granularity is 1-15ms,
-						// which is way too much for this optimization.
-						// So just yield.
-						osyield()
+					if _p_.status == _Prunning {
+						// Sleep to ensure that _p_ isn't about to run the g
+						// we are about to steal.
+						// The important use case here is when the g running
+						// on _p_ ready()s another g and then almost
+						// immediately blocks. Instead of stealing runnext
+						// in this window, back off to give _p_ a chance to
+						// schedule runnext. This will avoid thrashing gs
+						// between different Ps.
+						// A sync chan send/recv takes ~50ns as of time of
+						// writing, so 3us gives ~50x overshoot.
+						if GOOS != "windows" {
+							usleep(3)
+						} else {
+							// On windows system timer granularity is
+							// 1-15ms, which is way too much for this
+							// optimization. So just yield.
+							osyield()
+						}
 					}
 					if !_p_.runnext.cas(next, 0) {
 						continue
diff --git a/src/runtime/proc_test.go b/src/runtime/proc_test.go
index 90a6cab..2ece829 100644
--- a/src/runtime/proc_test.go
+++ b/src/runtime/proc_test.go
@@ -655,6 +655,116 @@
 	_ = sum
 }
 
+func benchmarkWakeupParallel(b *testing.B, spin func(time.Duration)) {
+	if runtime.GOMAXPROCS(0) == 1 {
+		b.Skip("skipping: GOMAXPROCS=1")
+	}
+
+	wakeDelay := 5 * time.Microsecond
+	for _, delay := range []time.Duration{
+		0,
+		1 * time.Microsecond,
+		2 * time.Microsecond,
+		5 * time.Microsecond,
+		10 * time.Microsecond,
+		20 * time.Microsecond,
+		50 * time.Microsecond,
+		100 * time.Microsecond,
+	} {
+		b.Run(delay.String(), func(b *testing.B) {
+			if b.N == 0 {
+				return
+			}
+			// Start two goroutines, which alternate between being
+			// sender and receiver in the following protocol:
+			//
+			// - The receiver spins for `delay` and then does a
+			// blocking receive on a channel.
+			//
+			// - The sender spins for `delay+wakeDelay` and then
+			// sends to the same channel. (The addition of
+			// `wakeDelay` improves the probability that the
+			// receiver will be blocking when the send occurs when
+			// the goroutines execute in parallel.)
+			//
+			// In each iteration of the benchmark, each goroutine
+			// acts once as sender and once as receiver, so each
+			// goroutine spins for delay twice.
+			//
+			// BenchmarkWakeupParallel is used to estimate how
+			// efficiently the scheduler parallelizes goroutines in
+			// the presence of blocking:
+			//
+			// - If both goroutines are executed on the same core,
+			// an increase in delay by N will increase the time per
+			// iteration by 4*N, because all 4 delays are
+			// serialized.
+			//
+			// - Otherwise, an increase in delay by N will increase
+			// the time per iteration by 2*N, and the time per
+			// iteration is 2 * (runtime overhead + chan
+			// send/receive pair + delay + wakeDelay). This allows
+			// the runtime overhead, including the time it takes
+			// for the unblocked goroutine to be scheduled, to be
+			// estimated.
+			ping, pong := make(chan struct{}), make(chan struct{})
+			start := make(chan struct{})
+			done := make(chan struct{})
+			go func() {
+				<-start
+				for i := 0; i < b.N; i++ {
+					// sender
+					spin(delay + wakeDelay)
+					ping <- struct{}{}
+					// receiver
+					spin(delay)
+					<-pong
+				}
+				done <- struct{}{}
+			}()
+			go func() {
+				for i := 0; i < b.N; i++ {
+					// receiver
+					spin(delay)
+					<-ping
+					// sender
+					spin(delay + wakeDelay)
+					pong <- struct{}{}
+				}
+				done <- struct{}{}
+			}()
+			b.ResetTimer()
+			start <- struct{}{}
+			<-done
+			<-done
+		})
+	}
+}
+
+func BenchmarkWakeupParallelSpinning(b *testing.B) {
+	benchmarkWakeupParallel(b, func(d time.Duration) {
+		end := time.Now().Add(d)
+		for time.Now().Before(end) {
+			// do nothing
+		}
+	})
+}
+
+// sysNanosleep is defined by OS-specific files (such as runtime_linux_test.go)
+// to sleep for the given duration. If nil, dependent tests are skipped.
+// The implementation should invoke a blocking system call and not
+// call time.Sleep, which would deschedule the goroutine.
+var sysNanosleep func(d time.Duration)
+
+func BenchmarkWakeupParallelSyscall(b *testing.B) {
+	if sysNanosleep == nil {
+		b.Skipf("skipping on %v; sysNanosleep not defined", runtime.GOOS)
+	}
+	benchmarkWakeupParallel(b, func(d time.Duration) {
+		sysNanosleep(d)
+	})
+}
+
 type Matrix [][]float64
 
 func BenchmarkMatmult(b *testing.B) {
@@ -722,3 +832,44 @@
 func TestStealOrder(t *testing.T) {
 	runtime.RunStealOrderTest()
 }
+
+func TestLockOSThreadNesting(t *testing.T) {
+	go func() {
+		e, i := runtime.LockOSCounts()
+		if e != 0 || i != 0 {
+			t.Errorf("want locked counts 0, 0; got %d, %d", e, i)
+			return
+		}
+		runtime.LockOSThread()
+		runtime.LockOSThread()
+		runtime.UnlockOSThread()
+		e, i = runtime.LockOSCounts()
+		if e != 1 || i != 0 {
+			t.Errorf("want locked counts 1, 0; got %d, %d", e, i)
+			return
+		}
+		runtime.UnlockOSThread()
+		e, i = runtime.LockOSCounts()
+		if e != 0 || i != 0 {
+			t.Errorf("want locked counts 0, 0; got %d, %d", e, i)
+			return
+		}
+	}()
+}
+
+func TestLockOSThreadExit(t *testing.T) {
+	testLockOSThreadExit(t, "testprog")
+}
+
+func testLockOSThreadExit(t *testing.T, prog string) {
+	output := runTestProg(t, prog, "LockOSThreadMain", "GOMAXPROCS=1")
+	want := "OK\n"
+	if output != want {
+		t.Errorf("want %s, got %s\n", want, output)
+	}
+
+	output = runTestProg(t, prog, "LockOSThreadAlt")
+	if output != want {
+		t.Errorf("want %s, got %s\n", want, output)
+	}
+}
diff --git a/src/runtime/race.go b/src/runtime/race.go
index 49495cc..2f5713d 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -4,14 +4,14 @@
 
 // +build race
 
-// Public race detection API, present iff build with -race.
-
 package runtime
 
 import (
 	"unsafe"
 )
 
+// Public race detection API, present iff build with -race.
+
 func RaceRead(addr unsafe.Pointer)
 func RaceWrite(addr unsafe.Pointer)
 func RaceReadRange(addr unsafe.Pointer, len int)
@@ -23,7 +23,69 @@
 	return int(n)
 }
 
-// private interface for the runtime
+//go:nosplit
+
+// RaceAcquire/RaceRelease/RaceReleaseMerge establish happens-before relations
+// between goroutines. These inform the race detector about actual synchronization
+// that it can't see for some reason (e.g. synchronization within RaceDisable/RaceEnable
+// sections of code).
+// RaceAcquire establishes a happens-before relation with the preceding
+// RaceReleaseMerge on addr up to and including the last RaceRelease on addr.
+// In terms of the C memory model (C11 §5.1.2.4, §7.17.3),
+// RaceAcquire is equivalent to atomic_load(memory_order_acquire).
+func RaceAcquire(addr unsafe.Pointer) {
+	raceacquire(addr)
+}
+
+//go:nosplit
+
+// RaceRelease performs a release operation on addr that
+// can synchronize with a later RaceAcquire on addr.
+//
+// In terms of the C memory model, RaceRelease is equivalent to
+// atomic_store(memory_order_release).
+func RaceRelease(addr unsafe.Pointer) {
+	racerelease(addr)
+}
+
+//go:nosplit
+
+// RaceReleaseMerge is like RaceRelease, but also establishes a happens-before
+// relation with the preceding RaceRelease or RaceReleaseMerge on addr.
+//
+// In terms of the C memory model, RaceReleaseMerge is equivalent to
+// atomic_exchange(memory_order_release).
+func RaceReleaseMerge(addr unsafe.Pointer) {
+	racereleasemerge(addr)
+}
+
+//go:nosplit
+
+// RaceDisable disables handling of race synchronization events in the current goroutine.
+// Handling is re-enabled with RaceEnable. RaceDisable/RaceEnable can be nested.
+// Non-synchronization events (memory accesses, function entry/exit) still affect
+// the race detector.
+func RaceDisable() {
+	_g_ := getg()
+	if _g_.raceignore == 0 {
+		racecall(&__tsan_go_ignore_sync_begin, _g_.racectx, 0, 0, 0)
+	}
+	_g_.raceignore++
+}
+
+//go:nosplit
+
+// RaceEnable re-enables handling of race events in the current goroutine.
+func RaceEnable() {
+	_g_ := getg()
+	_g_.raceignore--
+	if _g_.raceignore == 0 {
+		racecall(&__tsan_go_ignore_sync_end, _g_.racectx, 0, 0, 0)
+	}
+}
+
+// Private interface for the runtime.
+
 const raceenabled = true
 
 // For all functions accepting callerpc and pc,
@@ -433,43 +495,3 @@
 func racefingo() {
 	racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
 }
-
-//go:nosplit
-
-func RaceAcquire(addr unsafe.Pointer) {
-	raceacquire(addr)
-}
-
-//go:nosplit
-
-func RaceRelease(addr unsafe.Pointer) {
-	racerelease(addr)
-}
-
-//go:nosplit
-
-func RaceReleaseMerge(addr unsafe.Pointer) {
-	racereleasemerge(addr)
-}
-
-//go:nosplit
-
-// RaceDisable disables handling of race events in the current goroutine.
-func RaceDisable() {
-	_g_ := getg()
-	if _g_.raceignore == 0 {
-		racecall(&__tsan_go_ignore_sync_begin, _g_.racectx, 0, 0, 0)
-	}
-	_g_.raceignore++
-}
-
-//go:nosplit
-
-// RaceEnable re-enables handling of race events in the current goroutine.
-func RaceEnable() {
-	_g_ := getg()
-	_g_.raceignore--
-	if _g_.raceignore == 0 {
-		racecall(&__tsan_go_ignore_sync_end, _g_.racectx, 0, 0, 0)
-	}
-}
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index 13dfc33..adf9ce8 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -19,6 +19,16 @@
 )
 
 func TestOutput(t *testing.T) {
+	pkgdir, err := ioutil.TempDir("", "go-build-race-output")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(pkgdir)
+	out, err := exec.Command(testenv.GoToolPath(t), "install", "-race", "-pkgdir="+pkgdir, "-gcflags=all=-l", "testing").CombinedOutput()
+	if err != nil {
+		t.Fatalf("go install -race: %v\n%s", err, out)
+	}
+
 	for _, test := range tests {
 		if test.goos != "" && test.goos != runtime.GOOS {
 			t.Logf("test %v runs only on %v, skipping: ", test.name, test.goos)
@@ -47,7 +57,7 @@
 			t.Fatalf("failed to close file: %v", err)
 		}
 		// Pass -l to the compiler to test stack traces.
-		cmd := exec.Command(testenv.GoToolPath(t), test.run, "-race", "-gcflags=-l", src)
+		cmd := exec.Command(testenv.GoToolPath(t), test.run, "-race", "-pkgdir="+pkgdir, "-gcflags=all=-l", src)
 		// GODEBUG spoils program output, GOMAXPROCS makes it flaky.
 		for _, env := range os.Environ() {
 			if strings.HasPrefix(env, "GODEBUG=") ||
@@ -175,6 +185,7 @@
 func TestFail(t *testing.T) {
 	done := make(chan bool)
 	x := 0
+	_ = x
 	go func() {
 		x = 42
 		done <- true
@@ -186,7 +197,7 @@
 `, `
 ==================
 --- FAIL: TestFail \(0...s\)
-.*main_test.go:13: true
+.*main_test.go:14: true
 .*testing.go:.*: race detected during execution of test
 FAIL`},
 
@@ -253,7 +264,7 @@
   main\.goCallback\(\)
       .*/main\.go:27 \+0x[0-9,a-f]+
   main._cgoexpwrap_[0-9a-z]+_goCallback\(\)
-      .*/_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
+      .*_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
 
 Goroutine [0-9] \(running\) created at:
   runtime\.newextram\(\)
@@ -265,6 +276,7 @@
 func TestFail(t *testing.T) {
 	done := make(chan bool)
 	x := 0
+	_ = x
 	go func() {
 		x = 42
 		done <- true
diff --git a/src/runtime/race/testdata/atomic_test.go b/src/runtime/race/testdata/atomic_test.go
index 232744b..769c8d7 100644
--- a/src/runtime/race/testdata/atomic_test.go
+++ b/src/runtime/race/testdata/atomic_test.go
@@ -14,6 +14,7 @@
 
 func TestNoRaceAtomicAddInt64(t *testing.T) {
 	var x1, x2 int8
+	_ = x1 + x2
 	var s int64
 	ch := make(chan bool, 2)
 	go func() {
@@ -36,6 +37,7 @@
 
 func TestRaceAtomicAddInt64(t *testing.T) {
 	var x1, x2 int8
+	_ = x1 + x2
 	var s int64
 	ch := make(chan bool, 2)
 	go func() {
@@ -58,6 +60,7 @@
 
 func TestNoRaceAtomicAddInt32(t *testing.T) {
 	var x1, x2 int8
+	_ = x1 + x2
 	var s int32
 	ch := make(chan bool, 2)
 	go func() {
@@ -80,6 +83,7 @@
 
 func TestNoRaceAtomicLoadAddInt32(t *testing.T) {
 	var x int64
+	_ = x
 	var s int32
 	go func() {
 		x = 2
@@ -93,6 +97,7 @@
 
 func TestNoRaceAtomicLoadStoreInt32(t *testing.T) {
 	var x int64
+	_ = x
 	var s int32
 	go func() {
 		x = 2
@@ -106,6 +111,7 @@
 
 func TestNoRaceAtomicStoreCASInt32(t *testing.T) {
 	var x int64
+	_ = x
 	var s int32
 	go func() {
 		x = 2
@@ -119,6 +125,7 @@
 
 func TestNoRaceAtomicCASLoadInt32(t *testing.T) {
 	var x int64
+	_ = x
 	var s int32
 	go func() {
 		x = 2
@@ -134,6 +141,7 @@
 
 func TestNoRaceAtomicCASCASInt32(t *testing.T) {
 	var x int64
+	_ = x
 	var s int32
 	go func() {
 		x = 2
@@ -149,6 +157,7 @@
 
 func TestNoRaceAtomicCASCASInt32_2(t *testing.T) {
 	var x1, x2 int8
+	_ = x1 + x2
 	var s int32
 	ch := make(chan bool, 2)
 	go func() {
@@ -171,6 +180,7 @@
 
 func TestNoRaceAtomicLoadInt64(t *testing.T) {
 	var x int32
+	_ = x
 	var s int64
 	go func() {
 		x = 2
@@ -184,6 +194,7 @@
 
 func TestNoRaceAtomicCASCASUInt64(t *testing.T) {
 	var x int64
+	_ = x
 	var s uint64
 	go func() {
 		x = 2
@@ -199,6 +210,7 @@
 
 func TestNoRaceAtomicLoadStorePointer(t *testing.T) {
 	var x int64
+	_ = x
 	var s unsafe.Pointer
 	var y int = 2
 	var p unsafe.Pointer = unsafe.Pointer(&y)
@@ -214,6 +226,7 @@
 
 func TestNoRaceAtomicStoreCASUint64(t *testing.T) {
 	var x int64
+	_ = x
 	var s uint64
 	go func() {
 		x = 2
diff --git a/src/runtime/race/testdata/chan_test.go b/src/runtime/race/testdata/chan_test.go
index 4491916..7f349c4 100644
--- a/src/runtime/race/testdata/chan_test.go
+++ b/src/runtime/race/testdata/chan_test.go
@@ -12,6 +12,7 @@
 
 func TestNoRaceChanSync(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		v = 1
@@ -23,6 +24,7 @@
 
 func TestNoRaceChanSyncRev(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		c <- 0
@@ -34,6 +36,7 @@
 
 func TestNoRaceChanAsync(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -45,6 +48,7 @@
 
 func TestRaceChanAsyncRev(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		c <- 0
@@ -56,6 +60,7 @@
 
 func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -72,6 +77,7 @@
 
 func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -83,6 +89,7 @@
 
 func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -95,6 +102,7 @@
 
 func TestNoRaceChanSyncCloseRecv(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		v = 1
@@ -111,6 +119,7 @@
 
 func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		v = 1
@@ -122,6 +131,7 @@
 
 func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		v = 1
@@ -134,6 +144,7 @@
 
 func TestRaceChanSyncCloseSend(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int)
 	go func() {
 		v = 1
@@ -150,6 +161,7 @@
 
 func TestRaceChanAsyncCloseSend(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -170,6 +182,7 @@
 	compl := make(chan bool, 2)
 	v1 := 0
 	v2 := 0
+	_ = v1 + v2
 	c := make(chan int)
 	go func() {
 		defer func() {
@@ -197,6 +210,7 @@
 
 func TestRaceChanSendLen(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	go func() {
 		v = 1
@@ -210,6 +224,7 @@
 
 func TestRaceChanRecvLen(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	c <- 1
 	go func() {
@@ -226,6 +241,7 @@
 	compl := make(chan bool, 2)
 	v1 := 0
 	v2 := 0
+	_ = v1 + v2
 	c := make(chan int, 1)
 	go func() {
 		v1 = 1
@@ -264,6 +280,7 @@
 func TestRaceChanWrongSend(t *testing.T) {
 	v1 := 0
 	v2 := 0
+	_ = v1 + v2
 	c := make(chan int, 2)
 	go func() {
 		v1 = 1
@@ -284,6 +301,7 @@
 func TestRaceChanWrongClose(t *testing.T) {
 	v1 := 0
 	v2 := 0
+	_ = v1 + v2
 	c := make(chan int, 1)
 	done := make(chan bool)
 	go func() {
@@ -561,6 +579,7 @@
 
 func TestRaceChanCloseLen(t *testing.T) {
 	v := 0
+	_ = v
 	c := make(chan int, 10)
 	c <- 0
 	go func() {
@@ -587,6 +606,7 @@
 	done := make(chan struct{})
 	mtx := make(chan struct{}, 1)
 	data := 0
+	_ = data
 	go func() {
 		mtx <- struct{}{}
 		data = 42
@@ -604,6 +624,7 @@
 	mtx := make(chan struct{}, 1)
 	aux := make(chan bool)
 	data := 0
+	_ = data
 	go func() {
 		select {
 		case mtx <- struct{}{}:
@@ -632,6 +653,7 @@
 	done := make(chan struct{})
 	mtx := make(chan bool, 2)
 	data := 0
+	_ = data
 	go func() {
 		mtx <- true
 		data = 42
diff --git a/src/runtime/race/testdata/finalizer_test.go b/src/runtime/race/testdata/finalizer_test.go
index 222cbf6..3ac33d2 100644
--- a/src/runtime/race/testdata/finalizer_test.go
+++ b/src/runtime/race/testdata/finalizer_test.go
@@ -53,6 +53,7 @@
 func TestRaceFin(t *testing.T) {
 	c := make(chan bool)
 	y := 0
+	_ = y
 	go func() {
 		x := new(string)
 		runtime.SetFinalizer(x, func(x *string) {
diff --git a/src/runtime/race/testdata/map_test.go b/src/runtime/race/testdata/map_test.go
index a8d8148..88e735e 100644
--- a/src/runtime/race/testdata/map_test.go
+++ b/src/runtime/race/testdata/map_test.go
@@ -130,6 +130,7 @@
 func TestRaceMapVariable(t *testing.T) {
 	ch := make(chan bool, 1)
 	m := make(map[int]int)
+	_ = m
 	go func() {
 		m = make(map[int]int)
 		ch <- true
@@ -230,6 +231,7 @@
 	conns[1] = []int{0}
 	ch := make(chan bool, 1)
 	var err error
+	_ = err
 	go func() {
 		conns[1][0], err = connect()
 		ch <- true
diff --git a/src/runtime/race/testdata/mop_test.go b/src/runtime/race/testdata/mop_test.go
index c96acb9..5d25ed4 100644
--- a/src/runtime/race/testdata/mop_test.go
+++ b/src/runtime/race/testdata/mop_test.go
@@ -60,6 +60,7 @@
 
 func TestRaceIntRWClosures(t *testing.T) {
 	var x, y int
+	_ = y
 	ch := make(chan int, 2)
 
 	go func() {
@@ -76,6 +77,7 @@
 
 func TestNoRaceIntRWClosures(t *testing.T) {
 	var x, y int
+	_ = y
 	ch := make(chan int, 1)
 
 	go func() {
@@ -93,6 +95,7 @@
 
 func TestRaceInt32RWClosures(t *testing.T) {
 	var x, y int32
+	_ = y
 	ch := make(chan bool, 2)
 
 	go func() {
@@ -168,6 +171,7 @@
 
 func TestRaceCaseBody(t *testing.T) {
 	var x, y int
+	_ = y
 	ch := make(chan int, 2)
 
 	go func() {
@@ -189,6 +193,7 @@
 
 func TestNoRaceCaseFallthrough(t *testing.T) {
 	var x, y, z int
+	_ = y
 	ch := make(chan int, 2)
 	z = 1
 
@@ -210,6 +215,7 @@
 
 func TestRaceCaseFallthrough(t *testing.T) {
 	var x, y, z int
+	_ = y
 	ch := make(chan int, 2)
 	z = 1
 
@@ -323,6 +329,7 @@
 	const N = 2
 	var a [N]int
 	var x, y int
+	_ = x + y
 	done := make(chan bool, N)
 	for i, v := range a {
 		go func(i int) {
@@ -433,6 +440,7 @@
 
 func TestRacePlus(t *testing.T) {
 	var x, y, z int
+	_ = y
 	ch := make(chan int, 2)
 
 	go func() {
@@ -449,6 +457,7 @@
 
 func TestRacePlus2(t *testing.T) {
 	var x, y, z int
+	_ = y
 	ch := make(chan int, 2)
 
 	go func() {
@@ -465,6 +474,7 @@
 
 func TestNoRacePlus(t *testing.T) {
 	var x, y, z, f int
+	_ = x + y + f
 	ch := make(chan int, 2)
 
 	go func() {
@@ -481,6 +491,7 @@
 
 func TestRaceComplement(t *testing.T) {
 	var x, y, z int
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -497,6 +508,7 @@
 
 func TestRaceDiv(t *testing.T) {
 	var x, y, z int
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -513,6 +525,7 @@
 
 func TestRaceDivConst(t *testing.T) {
 	var x, y, z uint32
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -529,6 +542,7 @@
 
 func TestRaceMod(t *testing.T) {
 	var x, y, z int
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -545,6 +559,7 @@
 
 func TestRaceModConst(t *testing.T) {
 	var x, y, z int
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -561,6 +576,7 @@
 
 func TestRaceRotate(t *testing.T) {
 	var x, y, z uint32
+	_ = x
 	ch := make(chan int, 2)
 
 	go func() {
@@ -932,6 +948,7 @@
 
 func TestRaceFuncVariableWW(t *testing.T) {
 	var f func(x int) int
+	_ = f
 	ch := make(chan bool, 1)
 	go func() {
 		f = func(x int) int {
@@ -948,6 +965,7 @@
 // This one should not belong to mop_test
 func TestRacePanic(t *testing.T) {
 	var x int
+	_ = x
 	var zero int = 0
 	ch := make(chan bool, 2)
 	go func() {
@@ -1284,6 +1302,7 @@
 	ch := make(chan bool, 1)
 	var mu sync.Mutex
 	x := 0
+	_ = x
 	go func() {
 		mu.Lock()
 		x = 42
@@ -1812,6 +1831,7 @@
 	c := make(chan bool, 1)
 	var mu sync.Mutex
 	x := 0
+	_ = x
 	go func() {
 		x = func() int { // Write of x must be under the mutex.
 			mu.Lock()
@@ -2042,6 +2062,7 @@
 	const P = 4
 	const N = 1e6
 	var tinySink *byte
+	_ = tinySink
 	done := make(chan bool)
 	for p := 0; p < P; p++ {
 		go func() {
diff --git a/src/runtime/race/testdata/mutex_test.go b/src/runtime/race/testdata/mutex_test.go
index 3cf03ae..cbed2d3 100644
--- a/src/runtime/race/testdata/mutex_test.go
+++ b/src/runtime/race/testdata/mutex_test.go
@@ -13,6 +13,7 @@
 func TestNoRaceMutex(t *testing.T) {
 	var mu sync.Mutex
 	var x int16 = 0
+	_ = x
 	ch := make(chan bool, 2)
 	go func() {
 		mu.Lock()
@@ -33,6 +34,7 @@
 func TestRaceMutex(t *testing.T) {
 	var mu sync.Mutex
 	var x int16 = 0
+	_ = x
 	ch := make(chan bool, 2)
 	go func() {
 		x = 1
@@ -54,6 +56,7 @@
 	var mu1 sync.Mutex
 	var mu2 sync.Mutex
 	var x int8 = 0
+	_ = x
 	ch := make(chan bool, 2)
 	go func() {
 		mu1.Lock()
@@ -74,6 +77,7 @@
 func TestNoRaceMutexPureHappensBefore(t *testing.T) {
 	var mu sync.Mutex
 	var x int16 = 0
+	_ = x
 	ch := make(chan bool, 2)
 	go func() {
 		x = 1
@@ -96,6 +100,7 @@
 	var mu sync.Mutex
 	ch := make(chan bool, 2)
 	x := 0
+	_ = x
 	mu.Lock()
 	go func() {
 		x = 1
diff --git a/src/runtime/race/testdata/rwmutex_test.go b/src/runtime/race/testdata/rwmutex_test.go
index 7ac829d..39219e5 100644
--- a/src/runtime/race/testdata/rwmutex_test.go
+++ b/src/runtime/race/testdata/rwmutex_test.go
@@ -14,6 +14,7 @@
 	var mu1 sync.Mutex
 	var mu2 sync.RWMutex
 	var x int16 = 0
+	_ = x
 	ch := make(chan bool, 2)
 	go func() {
 		mu1.Lock()
@@ -34,6 +35,7 @@
 func TestNoRaceRWMutex(t *testing.T) {
 	var mu sync.RWMutex
 	var x, y int64 = 0, 1
+	_ = y
 	ch := make(chan bool, 2)
 	go func() {
 		mu.Lock()
diff --git a/src/runtime/race/testdata/select_test.go b/src/runtime/race/testdata/select_test.go
index 9969f47..3827867 100644
--- a/src/runtime/race/testdata/select_test.go
+++ b/src/runtime/race/testdata/select_test.go
@@ -11,6 +11,7 @@
 
 func TestNoRaceSelect1(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool)
 	c := make(chan bool)
 	c1 := make(chan bool)
@@ -36,6 +37,7 @@
 
 func TestNoRaceSelect2(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool)
 	c := make(chan bool)
 	c1 := make(chan bool)
@@ -55,6 +57,7 @@
 
 func TestNoRaceSelect3(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool)
 	c := make(chan bool, 10)
 	c1 := make(chan bool)
@@ -112,6 +115,7 @@
 func TestNoRaceSelect5(t *testing.T) {
 	test := func(sel, needSched bool) {
 		var x int
+		_ = x
 		ch := make(chan bool)
 		c1 := make(chan bool)
 
@@ -158,6 +162,7 @@
 
 func TestRaceSelect1(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool, 2)
 	c := make(chan bool)
 	c1 := make(chan bool)
@@ -182,6 +187,7 @@
 
 func TestRaceSelect2(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool)
 	c := make(chan bool)
 	c1 := make(chan bool)
@@ -200,6 +206,7 @@
 
 func TestRaceSelect3(t *testing.T) {
 	var x int
+	_ = x
 	compl := make(chan bool)
 	c := make(chan bool)
 	c1 := make(chan bool)
diff --git a/src/runtime/race/testdata/sync_test.go b/src/runtime/race/testdata/sync_test.go
index d48680d..2b2d95d 100644
--- a/src/runtime/race/testdata/sync_test.go
+++ b/src/runtime/race/testdata/sync_test.go
@@ -12,6 +12,7 @@
 
 func TestNoRaceCond(t *testing.T) {
 	x := 0
+	_ = x
 	condition := 0
 	var mu sync.Mutex
 	cond := sync.NewCond(&mu)
@@ -35,6 +36,7 @@
 	var mu sync.Mutex
 	cond := sync.NewCond(&mu)
 	x := 0
+	_ = x
 	condition := 0
 	go func() {
 		time.Sleep(10 * time.Millisecond) // Enter cond.Wait loop
@@ -67,6 +69,7 @@
 	allDone := make(chan bool, N)
 
 	var x int
+	_ = x
 
 	var f, g, h func()
 	f = func() {
@@ -133,6 +136,7 @@
 func TestNoRaceAfterFunc3(t *testing.T) {
 	c := make(chan bool, 1)
 	x := 0
+	_ = x
 	time.AfterFunc(1e7, func() {
 		x = 1
 		c <- true
@@ -143,6 +147,7 @@
 func TestRaceAfterFunc3(t *testing.T) {
 	c := make(chan bool, 2)
 	x := 0
+	_ = x
 	time.AfterFunc(1e7, func() {
 		x = 1
 		c <- true
@@ -161,6 +166,7 @@
 // comprehensible.
 func TestRaceGoroutineCreationStack(t *testing.T) {
 	var x int
+	_ = x
 	var ch = make(chan bool, 1)
 
 	f1 := func() {
diff --git a/src/runtime/race/testdata/waitgroup_test.go b/src/runtime/race/testdata/waitgroup_test.go
index ff152b0..1693373 100644
--- a/src/runtime/race/testdata/waitgroup_test.go
+++ b/src/runtime/race/testdata/waitgroup_test.go
@@ -13,6 +13,7 @@
 
 func TestNoRaceWaitGroup(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	n := 1
 	for i := 0; i < n; i++ {
@@ -28,6 +29,7 @@
 
 func TestRaceWaitGroup(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	n := 2
 	for i := 0; i < n; i++ {
@@ -43,6 +45,7 @@
 
 func TestNoRaceWaitGroup2(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	wg.Add(1)
 	go func() {
@@ -56,6 +59,7 @@
 // incrementing counter in Add and locking wg's mutex
 func TestRaceWaitGroupAsMutex(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	c := make(chan bool, 2)
 	go func() {
@@ -82,6 +86,7 @@
 func TestRaceWaitGroupWrongWait(t *testing.T) {
 	c := make(chan bool, 2)
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	go func() {
 		wg.Add(1)
@@ -187,6 +192,7 @@
 // Correct usage but still a race
 func TestRaceWaitGroup2(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	wg.Add(2)
 	go func() {
@@ -202,6 +208,7 @@
 
 func TestNoRaceWaitGroupPanicRecover(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	defer func() {
 		err := recover()
@@ -219,6 +226,7 @@
 // Is it possible to get a race by synchronization via panic?
 func TestNoRaceWaitGroupPanicRecover2(t *testing.T) {
 	var x int
+	_ = x
 	var wg sync.WaitGroup
 	ch := make(chan bool, 1)
 	var f func() = func() {
diff --git a/src/runtime/rt0_android_386.s b/src/runtime/rt0_android_386.s
index 9d20fc8..3a1b06b 100644
--- a/src/runtime/rt0_android_386.s
+++ b/src/runtime/rt0_android_386.s
@@ -4,18 +4,13 @@
 
 #include "textflag.h"
 
-TEXT _rt0_386_android(SB),NOSPLIT,$8
-	MOVL	8(SP), AX  // argc
-	LEAL	12(SP), BX  // argv
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
+TEXT _rt0_386_android(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
 
 TEXT _rt0_386_android_lib(SB),NOSPLIT,$0
 	PUSHL	$_rt0_386_android_argv(SB)  // argv
 	PUSHL	$1  // argc
-	CALL	_rt0_386_linux_lib(SB)
+	CALL	_rt0_386_lib(SB)
 	POPL	AX
 	POPL	AX
 	RET
diff --git a/src/runtime/rt0_android_amd64.s b/src/runtime/rt0_android_amd64.s
index 6420c9f..6bda3bf 100644
--- a/src/runtime/rt0_android_amd64.s
+++ b/src/runtime/rt0_android_amd64.s
@@ -5,16 +5,12 @@
 #include "textflag.h"
 
 TEXT _rt0_amd64_android(SB),NOSPLIT,$-8
-	MOVQ	0(SP), DI // argc
-	LEAQ	8(SP), SI // argv
-	MOVQ	$main(SB), AX
-	JMP	AX
+	JMP	_rt0_amd64(SB)
 
 TEXT _rt0_amd64_android_lib(SB),NOSPLIT,$0
 	MOVQ	$1, DI // argc
 	MOVQ	$_rt0_amd64_android_argv(SB), SI  // argv
-	MOVQ	$_rt0_amd64_linux_lib(SB), AX
-	JMP	AX
+	JMP	_rt0_amd64_lib(SB)
 
 DATA _rt0_amd64_android_argv+0x00(SB)/8,$_rt0_amd64_android_argv0(SB)
 DATA _rt0_amd64_android_argv+0x08(SB)/8,$0 // end argv
diff --git a/src/runtime/rt0_android_arm.s b/src/runtime/rt0_android_arm.s
index 189e290..1246238 100644
--- a/src/runtime/rt0_android_arm.s
+++ b/src/runtime/rt0_android_arm.s
@@ -10,13 +10,10 @@
 	MOVW		$_rt0_arm_linux1(SB), R4
 	B		(R4)
 
-// When building with -buildmode=c-shared, this symbol is called when the shared
-// library is loaded.
 TEXT _rt0_arm_android_lib(SB),NOSPLIT,$0
 	MOVW	$1, R0                          // argc
 	MOVW	$_rt0_arm_android_argv(SB), R1  // **argv
-	BL _rt0_arm_linux_lib(SB)
-	RET
+	B	_rt0_arm_lib(SB)
 
 DATA _rt0_arm_android_argv+0x00(SB)/4,$_rt0_arm_android_argv0(SB)
 DATA _rt0_arm_android_argv+0x04(SB)/4,$0 // end argv
diff --git a/src/runtime/rt0_darwin_386.s b/src/runtime/rt0_darwin_386.s
index 6b404db..a8d3a79 100644
--- a/src/runtime/rt0_darwin_386.s
+++ b/src/runtime/rt0_darwin_386.s
@@ -4,72 +4,14 @@
 
 #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 _rt0_386_darwin(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
 
-// With -buildmode=c-archive, this symbol is called from a global constructor.
 TEXT _rt0_386_darwin_lib(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-
-	MOVL	8(BP), AX
-	MOVL	AX, _rt0_386_darwin_lib_argc<>(SB)
-	MOVL	12(BP), AX
-	MOVL	AX, _rt0_386_darwin_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVL	$runtime·libpreinit(SB), AX
-	CALL	AX
-
-	SUBL	$12, SP
-
-	// Create a new thread to do the runtime initialization and return.
-	MOVL	_cgo_sys_thread_create(SB), AX
-	TESTL	AX, AX
-	JZ	nocgo
-	MOVL	$_rt0_386_darwin_lib_go(SB), BX
-	MOVL	BX, 0(SP)
-	MOVL	$0, 4(SP)
-	CALL	AX
-	JMP     restore
-
-nocgo:
-	MOVL	$0x800000, 0(SP)               // stacksize = 8192KB
-	MOVL	$_rt0_386_darwin_lib_go(SB), AX
-	MOVL	AX, 4(SP)                      // fn
-	MOVL	$0, 8(SP)                      // fnarg
-	MOVL	$runtime·newosproc0(SB), AX
-	CALL	AX
-
-restore:
-	ADDL	$12, SP
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
-	RET
-
-TEXT _rt0_386_darwin_lib_go(SB),NOSPLIT,$12
-	MOVL	_rt0_386_darwin_lib_argc<>(SB), AX
-	MOVL	AX, 0(SP)
-	MOVL	_rt0_386_darwin_lib_argv<>(SB), AX
-	MOVL	AX, 4(SP)
-	MOVL	$runtime·rt0_go(SB), AX
-	CALL	AX
-	RET
-
-DATA _rt0_386_darwin_lib_argc<>(SB)/4, $0
-GLOBL _rt0_386_darwin_lib_argc<>(SB),NOPTR, $4
-DATA _rt0_386_darwin_lib_argv<>(SB)/4, $0
-GLOBL _rt0_386_darwin_lib_argv<>(SB),NOPTR, $4
+	JMP	_rt0_386_lib(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_darwin_amd64.s b/src/runtime/rt0_darwin_amd64.s
index 655e77a..ed804d4 100644
--- a/src/runtime/rt0_darwin_amd64.s
+++ b/src/runtime/rt0_darwin_amd64.s
@@ -5,75 +5,9 @@
 #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
+	JMP	_rt0_amd64(SB)
 
 // When linking with -shared, this symbol is called when the shared library
 // is loaded.
-TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$0x58
-	// Align stack. We don't know whether Go is adding a frame pointer here or not.
-	MOVQ	SP, R8
-	SUBQ	$16, R8
-	ANDQ	$~15, R8
-	XCHGQ	SP, R8
-
-	MOVQ	R8, 0x48(SP)
-	MOVQ	BX, 0x18(SP)
-	MOVQ	BP, 0x20(SP)
-	MOVQ	R12, 0x28(SP)
-	MOVQ	R13, 0x30(SP)
-	MOVQ	R14, 0x38(SP)
-	MOVQ	R15, 0x40(SP)
-
-	MOVQ	DI, _rt0_amd64_darwin_lib_argc<>(SB)
-	MOVQ	SI, _rt0_amd64_darwin_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVQ	$runtime·libpreinit(SB), AX
-	CALL	AX
-
-	// Create a new thread to do the runtime initialization and return.
-	MOVQ	_cgo_sys_thread_create(SB), AX
-	TESTQ	AX, AX
-	JZ	nocgo
-	MOVQ	$_rt0_amd64_darwin_lib_go(SB), DI
-	MOVQ	$0, SI
-	CALL	AX
-	JMP	restore
-
-nocgo:
-	MOVQ	$8388608, 0(SP)                    // stacksize
-	MOVQ	$_rt0_amd64_darwin_lib_go(SB), AX
-	MOVQ	AX, 8(SP)                          // fn
-	MOVQ	$0, 16(SP)                         // fnarg
-	MOVQ	$runtime·newosproc0(SB), AX
-	CALL	AX
-
-restore:
-	MOVQ	0x18(SP), BX
-	MOVQ	0x20(SP), BP
-	MOVQ	0x28(SP), R12
-	MOVQ	0x30(SP), R13
-	MOVQ	0x38(SP), R14
-	MOVQ	0x40(SP), R15
-	
-	MOVQ	0x48(SP), R8
-	MOVQ	R8, SP
-	RET
-
-TEXT _rt0_amd64_darwin_lib_go(SB),NOSPLIT,$0
-	MOVQ	_rt0_amd64_darwin_lib_argc<>(SB), DI
-	MOVQ	_rt0_amd64_darwin_lib_argv<>(SB), SI
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
-
-DATA _rt0_amd64_darwin_lib_argc<>(SB)/8, $0
-GLOBL _rt0_amd64_darwin_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_amd64_darwin_lib_argv<>(SB)/8, $0
-GLOBL _rt0_amd64_darwin_lib_argv<>(SB),NOPTR, $8
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_darwin_arm.s b/src/runtime/rt0_darwin_arm.s
index 526d88f..71fbe5f 100644
--- a/src/runtime/rt0_darwin_arm.s
+++ b/src/runtime/rt0_darwin_arm.s
@@ -4,94 +4,8 @@
 
 #include "textflag.h"
 
-TEXT _rt0_arm_darwin(SB),7,$-4
-	// prepare arguments for main (_rt0_go)
-	MOVW	(R13), R0	// argc
-	MOVW	$4(R13), R1		// argv
-	MOVW	$main(SB), R4
-	B		(R4)
+TEXT _rt0_arm_darwin(SB),7,$0
+	B	_rt0_asm(SB)
 
-// When linking with -buildmode=c-archive or -buildmode=c-shared,
-// this symbol is called from a global initialization function.
-//
-// Note that all currently shipping darwin/arm platforms require
-// cgo and do not support c-shared.
-TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$104
-	// Preserve callee-save registers.
-	MOVW    R4, 12(R13)
-	MOVW    R5, 16(R13)
-	MOVW    R6, 20(R13)
-	MOVW    R7, 24(R13)
-	MOVW    R8, 28(R13)
-	MOVW    R11, 32(R13)
-
-	MOVD	F8, (32+8*1)(R13)
-	MOVD	F9, (32+8*2)(R13)
-	MOVD	F10, (32+8*3)(R13)
-	MOVD	F11, (32+8*4)(R13)
-	MOVD	F12, (32+8*5)(R13)
-	MOVD	F13, (32+8*6)(R13)
-	MOVD	F14, (32+8*7)(R13)
-	MOVD	F15, (32+8*8)(R13)
-
-	MOVW  R0, _rt0_arm_darwin_lib_argc<>(SB)
-	MOVW  R1, _rt0_arm_darwin_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVW	$runtime·libpreinit(SB), R3
-	CALL	(R3)
-
-	// Create a new thread to do the runtime initialization and return.
-	MOVW  _cgo_sys_thread_create(SB), R3
-	CMP   $0, R3
-	B.EQ  nocgo
-	MOVW  $_rt0_arm_darwin_lib_go(SB), R0
-	MOVW  $0, R1
-	BL    (R3)
-	B rr
-nocgo:
-	MOVW  $0x400000, R0
-	MOVW  R0, (R13) // stacksize
-	MOVW  $_rt0_arm_darwin_lib_go(SB), R0
-	MOVW  R0, 4(R13) // fn
-	MOVW  $0, R0
-	MOVW  R0, 8(R13) // fnarg
-	MOVW  $runtime·newosproc0(SB), R3
-	BL    (R3)
-rr:
-	// Restore callee-save registers and return.
-	MOVW    12(R13), R4
-	MOVW    16(R13), R5
-	MOVW    20(R13), R6
-	MOVW    24(R13), R7
-	MOVW    28(R13), R8
-	MOVW    32(R13), R11
-	MOVD	(32+8*1)(R13), F8
-	MOVD	(32+8*2)(R13), F9
-	MOVD	(32+8*3)(R13), F10
-	MOVD	(32+8*4)(R13), F11
-	MOVD	(32+8*5)(R13), F12
-	MOVD	(32+8*6)(R13), F13
-	MOVD	(32+8*7)(R13), F14
-	MOVD	(32+8*8)(R13), F15
-	RET
-
-
-TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0
-	MOVW  _rt0_arm_darwin_lib_argc<>(SB), R0
-	MOVW  _rt0_arm_darwin_lib_argv<>(SB), R1
-	MOVW  R0,  (R13)
-	MOVW  R1, 4(R13)
-	MOVW  $runtime·rt0_go(SB), R4
-	B     (R4)
-
-DATA  _rt0_arm_darwin_lib_argc<>(SB)/4, $0
-GLOBL _rt0_arm_darwin_lib_argc<>(SB),NOPTR, $4
-DATA  _rt0_arm_darwin_lib_argv<>(SB)/4, $0
-GLOBL _rt0_arm_darwin_lib_argv<>(SB),NOPTR, $4
-
-TEXT main(SB),NOSPLIT,$-8
-	// save argc and argv onto stack
-	MOVM.DB.W [R0-R1], (R13)
-	MOVW	$runtime·rt0_go(SB), R4
-	B		(R4)
+TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
+	B	_rt0_arm_lib(SB)
diff --git a/src/runtime/rt0_dragonfly_amd64.s b/src/runtime/rt0_dragonfly_amd64.s
index fb56618..e76f9b9 100644
--- a/src/runtime/rt0_dragonfly_amd64.s
+++ b/src/runtime/rt0_dragonfly_amd64.s
@@ -4,12 +4,11 @@
 
 #include "textflag.h"
 
+// On Dragonfly argc/argv are passed in DI, not SP, so we can't use _rt0_amd64.
 TEXT _rt0_amd64_dragonfly(SB),NOSPLIT,$-8
 	LEAQ	8(DI), SI // argv
 	MOVQ	0(DI), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
+	JMP	runtime·rt0_go(SB)
 
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_dragonfly_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_freebsd_386.s b/src/runtime/rt0_freebsd_386.s
index cd7a915..1808059 100644
--- a/src/runtime/rt0_freebsd_386.s
+++ b/src/runtime/rt0_freebsd_386.s
@@ -4,13 +4,14 @@
 
 #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 _rt0_386_freebsd(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
+
+TEXT _rt0_386_freebsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_386_lib(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_freebsd_amd64.s b/src/runtime/rt0_freebsd_amd64.s
index 7989f7c..ccc48f6 100644
--- a/src/runtime/rt0_freebsd_amd64.s
+++ b/src/runtime/rt0_freebsd_amd64.s
@@ -4,12 +4,11 @@
 
 #include "textflag.h"
 
+// On FreeBSD argc/argv are passed in DI, not SP, so we can't use _rt0_amd64.
 TEXT _rt0_amd64_freebsd(SB),NOSPLIT,$-8
 	LEAQ	8(DI), SI // argv
 	MOVQ	0(DI), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
+	JMP	runtime·rt0_go(SB)
 
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_freebsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_freebsd_arm.s b/src/runtime/rt0_freebsd_arm.s
index e1bb13d..62ecd9a 100644
--- a/src/runtime/rt0_freebsd_arm.s
+++ b/src/runtime/rt0_freebsd_arm.s
@@ -4,13 +4,8 @@
 
 #include "textflag.h"
 
-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 _rt0_arm_freebsd(SB),NOSPLIT,$0
+	B	_rt0_arm(SB)
 
-TEXT main(SB),NOSPLIT,$-4
-	MOVM.DB.W [R0-R1], (R13)
-	MOVW	$runtime·rt0_go(SB), R4
-	B	(R4)
+TEXT _rt0_arm_freebsd_lib(SB),NOSPLIT,$0
+	B	_rt0_arm_lib(SB)
diff --git a/src/runtime/rt0_linux_386.s b/src/runtime/rt0_linux_386.s
index 23bfc98..325066f 100644
--- a/src/runtime/rt0_linux_386.s
+++ b/src/runtime/rt0_linux_386.s
@@ -4,72 +4,14 @@
 
 #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	main(SB)
-	INT	$3
+TEXT _rt0_386_linux(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
 
-// When building with -buildmode=c-shared, this symbol is called when the shared
-// library is loaded.
 TEXT _rt0_386_linux_lib(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-
-	MOVL	8(BP), AX
-	MOVL	AX, _rt0_386_linux_lib_argc<>(SB)
-	MOVL	12(BP), AX
-	MOVL	AX, _rt0_386_linux_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVL	$runtime·libpreinit(SB), AX
-	CALL	AX
-
-	SUBL	$8, SP
-
-	// Create a new thread to do the runtime initialization.
-	MOVL	_cgo_sys_thread_create(SB), AX
-	TESTL	AX, AX
-	JZ	nocgo
-	MOVL	$_rt0_386_linux_lib_go(SB), BX
-	MOVL	BX, 0(SP)
-	MOVL	$0, 4(SP)
-	CALL	AX
-	JMP	restore
-
-nocgo:
-	MOVL	$0x800000, 0(SP)                    // stacksize = 8192KB
-	MOVL	$_rt0_386_linux_lib_go(SB), AX
-	MOVL	AX, 4(SP)                           // fn
-	MOVL	$runtime·newosproc0(SB), AX
-	CALL	AX
-
-restore:
-	ADDL	$8, SP
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
-	RET
-
-TEXT _rt0_386_linux_lib_go(SB),NOSPLIT,$12
-	MOVL	_rt0_386_linux_lib_argc<>(SB), AX
-	MOVL	AX, 0(SP)
-	MOVL	_rt0_386_linux_lib_argv<>(SB), AX
-	MOVL	AX, 4(SP)
-	MOVL	$runtime·rt0_go(SB), AX
-	CALL	AX
-	RET
-
-DATA _rt0_386_linux_lib_argc<>(SB)/4, $0
-GLOBL _rt0_386_linux_lib_argc<>(SB),NOPTR, $4
-DATA _rt0_386_linux_lib_argv<>(SB)/4, $0
-GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4
+	JMP	_rt0_386_lib(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_linux_amd64.s b/src/runtime/rt0_linux_amd64.s
index ced471f..94ff709 100644
--- a/src/runtime/rt0_linux_amd64.s
+++ b/src/runtime/rt0_linux_amd64.s
@@ -5,70 +5,7 @@
 #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
+	JMP	_rt0_amd64(SB)
 
-// When building with -buildmode=c-shared, this symbol is called when the shared
-// library is loaded.
-// Note: This function calls external C code, which might required 16-byte stack
-// alignment after cmd/internal/obj applies its transformations.
-TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x50
-	MOVQ	SP, AX
-	ANDQ	$-16, SP
-	MOVQ	BX, 0x10(SP)
-	MOVQ	BP, 0x18(SP)
-	MOVQ	R12, 0x20(SP)
-	MOVQ	R13, 0x28(SP)
-	MOVQ	R14, 0x30(SP)
-	MOVQ	R15, 0x38(SP)
-	MOVQ	AX, 0x40(SP)
-
-	MOVQ	DI, _rt0_amd64_linux_lib_argc<>(SB)
-	MOVQ	SI, _rt0_amd64_linux_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVQ	$runtime·libpreinit(SB), AX
-	CALL	AX
-
-	// Create a new thread to do the runtime initialization and return.
-	MOVQ	_cgo_sys_thread_create(SB), AX
-	TESTQ	AX, AX
-	JZ	nocgo
-	MOVQ	$_rt0_amd64_linux_lib_go(SB), DI
-	MOVQ	$0, SI
-	CALL	AX
-	JMP	restore
-
-nocgo:
-	MOVQ	$8388608, 0(SP)                    // stacksize
-	MOVQ	$_rt0_amd64_linux_lib_go(SB), AX
-	MOVQ	AX, 8(SP)                          // fn
-	MOVQ	$runtime·newosproc0(SB), AX
-	CALL	AX
-
-restore:
-	MOVQ	0x10(SP), BX
-	MOVQ	0x18(SP), BP
-	MOVQ	0x20(SP), R12
-	MOVQ	0x28(SP), R13
-	MOVQ	0x30(SP), R14
-	MOVQ	0x38(SP), R15
-	MOVQ	0x40(SP), SP
-	RET
-
-TEXT _rt0_amd64_linux_lib_go(SB),NOSPLIT,$0
-	MOVQ	_rt0_amd64_linux_lib_argc<>(SB), DI
-	MOVQ	_rt0_amd64_linux_lib_argv<>(SB), SI
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
-
-DATA _rt0_amd64_linux_lib_argc<>(SB)/8, $0
-GLOBL _rt0_amd64_linux_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_amd64_linux_lib_argv<>(SB)/8, $0
-GLOBL _rt0_amd64_linux_lib_argv<>(SB),NOPTR, $8
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_linux_arm.s b/src/runtime/rt0_linux_arm.s
index 597e642..ba4ca2b 100644
--- a/src/runtime/rt0_linux_arm.s
+++ b/src/runtime/rt0_linux_arm.s
@@ -12,158 +12,22 @@
 
 // When building with -buildmode=c-shared, this symbol is called when the shared
 // library is loaded.
-TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$104
-	// Preserve callee-save registers. Raspberry Pi's dlopen(), for example,
-	// actually cares that R11 is preserved.
-	MOVW	R4, 12(R13)
-	MOVW	R5, 16(R13)
-	MOVW	R6, 20(R13)
-	MOVW	R7, 24(R13)
-	MOVW	R8, 28(R13)
-	MOVW	R11, 32(R13)
-
-	// Skip floating point registers on GOARM < 6.
-	MOVB    runtime·goarm(SB), R11
-	CMP $6, R11
-	BLT skipfpsave
-	MOVD	F8, (32+8*1)(R13)
-	MOVD	F9, (32+8*2)(R13)
-	MOVD	F10, (32+8*3)(R13)
-	MOVD	F11, (32+8*4)(R13)
-	MOVD	F12, (32+8*5)(R13)
-	MOVD	F13, (32+8*6)(R13)
-	MOVD	F14, (32+8*7)(R13)
-	MOVD	F15, (32+8*8)(R13)
-skipfpsave:
-	// Save argc/argv.
-	MOVW	R0, _rt0_arm_linux_lib_argc<>(SB)
-	MOVW	R1, _rt0_arm_linux_lib_argv<>(SB)
-
-	// Synchronous initialization.
-	MOVW	$runtime·libpreinit(SB), R2
-	CALL	(R2)
-
-	// Create a new thread to do the runtime initialization.
-	MOVW	_cgo_sys_thread_create(SB), R2
-	CMP	$0, R2
-	BEQ	nocgo
-	MOVW	$_rt0_arm_linux_lib_go<>(SB), R0
-	MOVW	$0, R1
-	BL	(R2)
-	B	rr
-nocgo:
-	MOVW	$0x800000, R0                     // stacksize = 8192KB
-	MOVW	$_rt0_arm_linux_lib_go<>(SB), R1  // fn
-	MOVW	R0, 4(R13)
-	MOVW	R1, 8(R13)
-	BL	runtime·newosproc0(SB)
-rr:
-	// Restore callee-save registers and return.
-	MOVB    runtime·goarm(SB), R11
-	CMP $6, R11
-	BLT skipfprest
-	MOVD	(32+8*1)(R13), F8
-	MOVD	(32+8*2)(R13), F9
-	MOVD	(32+8*3)(R13), F10
-	MOVD	(32+8*4)(R13), F11
-	MOVD	(32+8*5)(R13), F12
-	MOVD	(32+8*6)(R13), F13
-	MOVD	(32+8*7)(R13), F14
-	MOVD	(32+8*8)(R13), F15
-skipfprest:
-	MOVW	12(R13), R4
-	MOVW	16(R13), R5
-	MOVW	20(R13), R6
-	MOVW	24(R13), R7
-	MOVW	28(R13), R8
-	MOVW	32(R13), R11
-	RET
-
-TEXT _rt0_arm_linux_lib_go<>(SB),NOSPLIT,$8
-	MOVW	_rt0_arm_linux_lib_argc<>(SB), R0
-	MOVW	_rt0_arm_linux_lib_argv<>(SB), R1
-	MOVW	R0, 0(R13)
-	MOVW	R1, 4(R13)
-	B	runtime·rt0_go(SB)
-
-DATA _rt0_arm_linux_lib_argc<>(SB)/4,$0
-GLOBL _rt0_arm_linux_lib_argc<>(SB),NOPTR,$4
-DATA _rt0_arm_linux_lib_argv<>(SB)/4,$0
-GLOBL _rt0_arm_linux_lib_argv<>(SB),NOPTR,$4
+TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$0
+	B	_rt0_arm_lib(SB)
 
 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
+	// 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.
+	// If you get a SIGILL here, you have the wrong kernel.
 
-	// Save argc and argv
+	// Save argc and argv (syscall will clobber at least R0).
 	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
 
+	MOVM.IA.W (R13), [R0-R1]
 	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, R15, R4 // R15 is hardware PC
-	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_linux_ppc64le.s b/src/runtime/rt0_linux_ppc64le.s
index 81b9913..73b9ae3 100644
--- a/src/runtime/rt0_linux_ppc64le.s
+++ b/src/runtime/rt0_linux_ppc64le.s
@@ -2,6 +2,7 @@
 #include "textflag.h"
 
 TEXT _rt0_ppc64le_linux(SB),NOSPLIT,$0
+	XOR R0, R0	  // Make sure R0 is zero before _main
 	BR _main<>(SB)
 
 TEXT _rt0_ppc64le_linux_lib(SB),NOSPLIT,$-8
@@ -10,7 +11,6 @@
 	MOVD	R0, 16(R1) // Save LR in caller's frame.
 	MOVW	CR, R0     // Save CR in caller's frame
 	MOVD	R0, 8(R1)
-	MOVD	R2, 24(R1) // Save TOC in caller's frame.
 	MOVDU	R1, -320(R1) // Allocate frame.
 	
 	// Preserve callee-save registers.
@@ -121,7 +121,6 @@
 	FMOVD	304(R1), F31
 
 	ADD	$320, R1
-	MOVD	24(R1), R2
 	MOVD	8(R1), R0
 	MOVFL	R0, $0xff
 	MOVD	16(R1), R0
diff --git a/src/runtime/rt0_linux_s390x.s b/src/runtime/rt0_linux_s390x.s
index aedd6c7..4b62c5a 100644
--- a/src/runtime/rt0_linux_s390x.s
+++ b/src/runtime/rt0_linux_s390x.s
@@ -4,17 +4,20 @@
 
 #include "textflag.h"
 
-TEXT _rt0_s390x_linux(SB),NOSPLIT|NOFRAME,$0
+TEXT _rt0_s390x_linux(SB), NOSPLIT|NOFRAME, $0
 	// In a statically linked binary, the stack contains argc,
 	// argv as argc string pointers followed by a NULL, envv as a
 	// sequence of string pointers followed by a NULL, and auxv.
 	// There is no TLS base pointer.
-	//
-	// TODO: Support dynamic linking entry point
-	MOVD 0(R15), R2 // argc
-	ADD $8, R15, R3 // argv
-	BR main(SB)
 
-TEXT main(SB),NOSPLIT|NOFRAME,$0
-	MOVD	$runtime·rt0_go(SB), R11
-	BR	R11
+	MOVD 0(R15), R2  // argc
+	ADD  $8, R15, R3 // argv
+	BR   main(SB)
+
+TEXT _rt0_s390x_linux_lib(SB), NOSPLIT, $0
+	MOVD $_rt0_s390x_lib(SB), R1
+	BR   R1
+
+TEXT main(SB), NOSPLIT|NOFRAME, $0
+	MOVD $runtime·rt0_go(SB), R1
+	BR   R1
diff --git a/src/runtime/rt0_nacl_386.s b/src/runtime/rt0_nacl_386.s
index d4ba063..4c99002 100644
--- a/src/runtime/rt0_nacl_386.s
+++ b/src/runtime/rt0_nacl_386.s
@@ -15,8 +15,10 @@
 	LEAL	argv+16(FP), BX
 	MOVL	AX, 0(SP)
 	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
+	JMP	runtime·rt0_go(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_nacl_arm.s b/src/runtime/rt0_nacl_arm.s
index eadb478..2be8a07 100644
--- a/src/runtime/rt0_nacl_arm.s
+++ b/src/runtime/rt0_nacl_arm.s
@@ -13,8 +13,4 @@
 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
index 70b8532..cefc04a 100644
--- a/src/runtime/rt0_netbsd_386.s
+++ b/src/runtime/rt0_netbsd_386.s
@@ -4,13 +4,14 @@
 
 #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 _rt0_386_netbsd(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
+
+TEXT _rt0_386_netbsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_386_lib(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_netbsd_amd64.s b/src/runtime/rt0_netbsd_amd64.s
index fad5661..77c7187 100644
--- a/src/runtime/rt0_netbsd_amd64.s
+++ b/src/runtime/rt0_netbsd_amd64.s
@@ -5,11 +5,7 @@
 #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
+	JMP	_rt0_amd64(SB)
 
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_netbsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_netbsd_arm.s b/src/runtime/rt0_netbsd_arm.s
index 2cb1182..503c32a 100644
--- a/src/runtime/rt0_netbsd_arm.s
+++ b/src/runtime/rt0_netbsd_arm.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-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)
+TEXT _rt0_arm_netbsd(SB),NOSPLIT,$0
+	B	_rt0_arm(SB)
+
+TEXT _rt0_arm_netbsd_lib(SB),NOSPLIT,$0
+	B	_rt0_arm_lib(SB)
diff --git a/src/runtime/rt0_openbsd_386.s b/src/runtime/rt0_openbsd_386.s
index f25d2e1..959f4d6 100644
--- a/src/runtime/rt0_openbsd_386.s
+++ b/src/runtime/rt0_openbsd_386.s
@@ -4,13 +4,14 @@
 
 #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 _rt0_386_openbsd(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
+
+TEXT _rt0_386_openbsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_386_lib(SB)
 
 TEXT main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_openbsd_amd64.s b/src/runtime/rt0_openbsd_amd64.s
index 58fe666..c2f3f23 100644
--- a/src/runtime/rt0_openbsd_amd64.s
+++ b/src/runtime/rt0_openbsd_amd64.s
@@ -5,11 +5,7 @@
 #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
+	JMP	_rt0_amd64(SB)
 
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_openbsd_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_openbsd_arm.s b/src/runtime/rt0_openbsd_arm.s
index 6207e55..3511c96 100644
--- a/src/runtime/rt0_openbsd_arm.s
+++ b/src/runtime/rt0_openbsd_arm.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-TEXT _rt0_arm_openbsd(SB),NOSPLIT,$-4
-	MOVW	(R13), R0		// argc
-	MOVW	$4(R13), R1		// argv
-	MOVM.DB.W [R0-R1], (R13)
-	B	runtime·rt0_go(SB)
+TEXT _rt0_arm_openbsd(SB),NOSPLIT,$0
+	B	_rt0_arm(SB)
+
+TEXT _rt0_arm_openbsd_lib(SB),NOSPLIT,$0
+	B	_rt0_arm_lib(SB)
diff --git a/src/runtime/rt0_plan9_386.s b/src/runtime/rt0_plan9_386.s
index cbbf245..6471615 100644
--- a/src/runtime/rt0_plan9_386.s
+++ b/src/runtime/rt0_plan9_386.s
@@ -14,7 +14,7 @@
 	MOVL	AX, 0(SP)
 	LEAL	inargv+0(FP), AX
 	MOVL	AX, 4(SP)
-	CALL	runtime·rt0_go(SB)
+	JMP	runtime·rt0_go(SB)
 
 GLOBL _tos(SB), NOPTR, $4
 GLOBL _privates(SB), NOPTR, $4
diff --git a/src/runtime/rt0_plan9_arm.s b/src/runtime/rt0_plan9_arm.s
index 2a35e4e..d6174a4 100644
--- a/src/runtime/rt0_plan9_arm.s
+++ b/src/runtime/rt0_plan9_arm.s
@@ -10,8 +10,6 @@
 	MOVW	R0, _tos(SB)
 	MOVW	0(R13), R0
 	MOVW	$4(R13), R1
-	MOVW.W	R1, -4(R13)
-	MOVW.W	R0, -4(R13)
 	B	runtime·rt0_go(SB)
 
 GLOBL _tos(SB), NOPTR, $4
diff --git a/src/runtime/rt0_solaris_amd64.s b/src/runtime/rt0_solaris_amd64.s
index e2d1e71..5c46ded 100644
--- a/src/runtime/rt0_solaris_amd64.s
+++ b/src/runtime/rt0_solaris_amd64.s
@@ -5,11 +5,7 @@
 #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
+	JMP	_rt0_amd64(SB)
 
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
+TEXT _rt0_amd64_solaris_lib(SB),NOSPLIT,$0
+	JMP	_rt0_amd64_lib(SB)
diff --git a/src/runtime/rt0_windows_386.s b/src/runtime/rt0_windows_386.s
index b9407a9..fa39edd 100644
--- a/src/runtime/rt0_windows_386.s
+++ b/src/runtime/rt0_windows_386.s
@@ -4,13 +4,8 @@
 
 #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 _rt0_386_windows(SB),NOSPLIT,$0
+	JMP	_rt0_386(SB)
 
 // When building with -buildmode=(c-shared or c-archive), this
 // symbol is called. For dynamic libraries it is called when the
@@ -41,10 +36,12 @@
 	RET
 
 TEXT _rt0_386_windows_lib_go(SB),NOSPLIT,$0
-	MOVL  $0, DI
-	MOVL	$0, SI
-	MOVL	$runtime·rt0_go(SB), AX
-	JMP	AX
+	PUSHL	$0
+	PUSHL	$0
+	JMP	runtime·rt0_go(SB)
 
 TEXT _main(SB),NOSPLIT,$0
+	// Remove the return address from the stack.
+	// rt0_go doesn't expect it to be there.
+	ADDL	$4, SP
 	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_windows_amd64.s b/src/runtime/rt0_windows_amd64.s
index 2f73b37..1604711 100644
--- a/src/runtime/rt0_windows_amd64.s
+++ b/src/runtime/rt0_windows_amd64.s
@@ -7,10 +7,7 @@
 #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
+	JMP	_rt0_amd64(SB)
 
 // When building with -buildmode=(c-shared or c-archive), this
 // symbol is called. For dynamic libraries it is called when the
@@ -42,7 +39,3 @@
 	MOVQ	$0, SI
 	MOVQ	$runtime·rt0_go(SB), AX
 	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$runtime·rt0_go(SB), AX
-	JMP	AX
diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go
index 1318bab..5e05086 100644
--- a/src/runtime/runtime-gdb_test.go
+++ b/src/runtime/runtime-gdb_test.go
@@ -22,11 +22,15 @@
 
 func checkGdbEnvironment(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
-	if runtime.GOOS == "darwin" {
+	switch runtime.GOOS {
+	case "darwin":
 		t.Skip("gdb does not work on darwin")
-	}
-	if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64" {
-		t.Skip("skipping gdb tests on linux/ppc64; see golang.org/issue/17366")
+	case "netbsd":
+		t.Skip("gdb does not work with threads on NetBSD; see golang.org/issue/22893 and gnats.netbsd.org/52548")
+	case "linux":
+		if runtime.GOARCH == "ppc64" {
+			t.Skip("skipping gdb tests on linux/ppc64; see golang.org/issue/17366")
+		}
 	}
 	if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
 		t.Skip("gdb test can fail with GOROOT_FINAL pending")
@@ -76,7 +80,7 @@
 import "runtime"
 var gslice []string
 func main() {
-	mapvar := make(map[string]string,5)
+	mapvar := make(map[string]string, 13)
 	mapvar["abc"] = "def"
 	mapvar["ghi"] = "jkl"
 	strvar := "abc"
@@ -84,7 +88,7 @@
 	slicevar := make([]string, 0, 16)
 	slicevar = append(slicevar, mapvar["abc"])
 	fmt.Println("hi") // line 13
-	_ = ptrvar
+	runtime.KeepAlive(ptrvar)
 	gslice = slicevar
 	runtime.KeepAlive(mapvar)
 }
@@ -106,8 +110,8 @@
 		t.Skip("skipping because cgo is not enabled")
 	}
 
-	t.Parallel()
 	checkGdbEnvironment(t)
+	t.Parallel()
 	checkGdbVersion(t)
 	checkGdbPython(t)
 
@@ -132,7 +136,7 @@
 
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
 	cmd.Dir = dir
-	out, err := testEnv(cmd).CombinedOutput()
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("building source %v\n%s", err, out)
 	}
@@ -198,8 +202,10 @@
 		t.Fatalf("info goroutines failed: %s", bl)
 	}
 
-	printMapvarRe := regexp.MustCompile(`\Q = map[string]string = {["abc"] = "def", ["ghi"] = "jkl"}\E$`)
-	if bl := blocks["print mapvar"]; !printMapvarRe.MatchString(bl) {
+	printMapvarRe1 := regexp.MustCompile(`\Q = map[string]string = {["abc"] = "def", ["ghi"] = "jkl"}\E$`)
+	printMapvarRe2 := regexp.MustCompile(`\Q = map[string]string = {["ghi"] = "jkl", ["abc"] = "def"}\E$`)
+	if bl := blocks["print mapvar"]; !printMapvarRe1.MatchString(bl) &&
+		!printMapvarRe2.MatchString(bl) {
 		t.Fatalf("print mapvar failed: %s", bl)
 	}
 
@@ -212,7 +218,7 @@
 	// a collection of scalar vars holding the fields. In such cases
 	// the DWARF variable location expression should be of the
 	// form "var.field" and not just "field".
-	infoLocalsRe := regexp.MustCompile(`^slicevar.len = `)
+	infoLocalsRe := regexp.MustCompile(`.*\sslicevar.cap = `)
 	if bl := blocks["info locals"]; !infoLocalsRe.MatchString(bl) {
 		t.Fatalf("info locals failed: %s", bl)
 	}
@@ -260,8 +266,8 @@
 		testenv.SkipFlaky(t, 15603)
 	}
 
-	t.Parallel()
 	checkGdbEnvironment(t)
+	t.Parallel()
 	checkGdbVersion(t)
 
 	dir, err := ioutil.TempDir("", "go-build")
@@ -278,7 +284,7 @@
 	}
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
 	cmd.Dir = dir
-	out, err := testEnv(cmd).CombinedOutput()
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("building source %v\n%s", err, out)
 	}
@@ -330,8 +336,8 @@
 // TestGdbAutotmpTypes ensures that types of autotmp variables appear in .debug_info
 // See bug #17830.
 func TestGdbAutotmpTypes(t *testing.T) {
-	t.Parallel()
 	checkGdbEnvironment(t)
+	t.Parallel()
 	checkGdbVersion(t)
 
 	dir, err := ioutil.TempDir("", "go-build")
@@ -346,9 +352,9 @@
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-N -l", "-o", "a.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=all=-N -l", "-o", "a.exe")
 	cmd.Dir = dir
-	out, err := testEnv(cmd).CombinedOutput()
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("building source %v\n%s", err, out)
 	}
@@ -381,3 +387,62 @@
 		}
 	}
 }
+
+const constsSource = `
+package main
+
+const aConstant int = 42
+const largeConstant uint64 = ^uint64(0)
+const minusOne int64 = -1
+
+func main() {
+	println("hello world")
+}
+`
+
+func TestGdbConst(t *testing.T) {
+	checkGdbEnvironment(t)
+	t.Parallel()
+	checkGdbVersion(t)
+
+	dir, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("failed to create temp directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	// Build the source code.
+	src := filepath.Join(dir, "main.go")
+	err = ioutil.WriteFile(src, []byte(constsSource), 0644)
+	if err != nil {
+		t.Fatalf("failed to create file: %v", err)
+	}
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=all=-N -l", "-o", "a.exe")
+	cmd.Dir = dir
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("building source %v\n%s", err, out)
+	}
+
+	// Execute gdb commands.
+	args := []string{"-nx", "-batch",
+		"-ex", "set startup-with-shell off",
+		"-ex", "break main.main",
+		"-ex", "run",
+		"-ex", "print main.aConstant",
+		"-ex", "print main.largeConstant",
+		"-ex", "print main.minusOne",
+		"-ex", "print 'runtime._MSpanInUse'",
+		"-ex", "print 'runtime._PageSize'",
+		filepath.Join(dir, "a.exe"),
+	}
+	got, _ := exec.Command("gdb", args...).CombinedOutput()
+
+	sgot := strings.Replace(string(got), "\r\n", "\n", -1)
+
+	t.Logf("output %q", sgot)
+
+	if !strings.Contains(sgot, "\n$1 = 42\n$2 = 18446744073709551615\n$3 = -1\n$4 = 1 '\\001'\n$5 = 8192") {
+		t.Fatalf("output mismatch")
+	}
+}
diff --git a/src/runtime/runtime-lldb_test.go b/src/runtime/runtime-lldb_test.go
index 98bc906..9a28705 100644
--- a/src/runtime/runtime-lldb_test.go
+++ b/src/runtime/runtime-lldb_test.go
@@ -5,11 +5,7 @@
 package runtime_test
 
 import (
-	"debug/elf"
-	"debug/macho"
-	"encoding/binary"
 	"internal/testenv"
-	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -158,7 +154,7 @@
 		t.Fatalf("failed to create file: %v", err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-N -l", "-o", "a.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=all=-N -l", "-o", "a.exe")
 	cmd.Dir = dir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -182,81 +178,3 @@
 		t.Fatalf("Unexpected lldb output:\n%s", got)
 	}
 }
-
-// Check that aranges are valid even when lldb isn't installed.
-func TestDwarfAranges(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	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")
-	err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
-	if err != nil {
-		t.Fatalf("failed to create file: %v", err)
-	}
-
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
-	cmd.Dir = dir
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("building source %v\n%s", err, out)
-	}
-
-	filename := filepath.Join(dir, "a.exe")
-	if f, err := elf.Open(filename); err == nil {
-		sect := f.Section(".debug_aranges")
-		if sect == nil {
-			t.Fatal("Missing aranges section")
-		}
-		verifyAranges(t, f.ByteOrder, sect.Open())
-	} else if f, err := macho.Open(filename); err == nil {
-		sect := f.Section("__debug_aranges")
-		if sect == nil {
-			t.Fatal("Missing aranges section")
-		}
-		verifyAranges(t, f.ByteOrder, sect.Open())
-	} else {
-		t.Skip("Not an elf or macho binary.")
-	}
-}
-
-func verifyAranges(t *testing.T, byteorder binary.ByteOrder, data io.ReadSeeker) {
-	var header struct {
-		UnitLength  uint32 // does not include the UnitLength field
-		Version     uint16
-		Offset      uint32
-		AddressSize uint8
-		SegmentSize uint8
-	}
-	for {
-		offset, err := data.Seek(0, io.SeekCurrent)
-		if err != nil {
-			t.Fatalf("Seek error: %v", err)
-		}
-		if err = binary.Read(data, byteorder, &header); err == io.EOF {
-			return
-		} else if err != nil {
-			t.Fatalf("Error reading arange header: %v", err)
-		}
-		tupleSize := int64(header.SegmentSize) + 2*int64(header.AddressSize)
-		lastTupleOffset := offset + int64(header.UnitLength) + 4 - tupleSize
-		if lastTupleOffset%tupleSize != 0 {
-			t.Fatalf("Invalid arange length %d, (addr %d, seg %d)", header.UnitLength, header.AddressSize, header.SegmentSize)
-		}
-		if _, err = data.Seek(lastTupleOffset, io.SeekStart); err != nil {
-			t.Fatalf("Seek error: %v", err)
-		}
-		buf := make([]byte, tupleSize)
-		if n, err := data.Read(buf); err != nil || int64(n) < tupleSize {
-			t.Fatalf("Read error: %v", err)
-		}
-		for _, val := range buf {
-			if val != 0 {
-				t.Fatalf("Invalid terminator")
-			}
-		}
-	}
-}
diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go
index d8fe2f4..33ecc26 100644
--- a/src/runtime/runtime.go
+++ b/src/runtime/runtime.go
@@ -57,3 +57,9 @@
 
 //go:linkname os_runtime_args os.runtime_args
 func os_runtime_args() []string { return append([]string{}, argslice...) }
+
+//go:linkname syscall_Exit syscall.Exit
+//go:nosplit
+func syscall_Exit(code int) {
+	exit(int32(code))
+}
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index c073348..0971e0c 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -99,10 +99,6 @@
 func testAtomic64() {
 	test_z64 = 42
 	test_x64 = 0
-	prefetcht0(uintptr(unsafe.Pointer(&test_z64)))
-	prefetcht1(uintptr(unsafe.Pointer(&test_z64)))
-	prefetcht2(uintptr(unsafe.Pointer(&test_z64)))
-	prefetchnta(uintptr(unsafe.Pointer(&test_z64)))
 	if atomic.Cas64(&test_z64, test_x64, 1) {
 		throw("cas64 failed")
 	}
@@ -390,13 +386,6 @@
 
 	setTraceback(gogetenv("GOTRACEBACK"))
 	traceback_env = traceback_cache
-
-	// For cgocheck > 1, we turn on the write barrier at all times
-	// and check all pointer writes.
-	if debug.cgocheck > 1 {
-		writeBarrier.cgo = true
-		writeBarrier.enabled = true
-	}
 }
 
 //go:linkname setTraceback runtime/debug.SetTraceback
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 6871d9c..556f13d 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -169,9 +169,13 @@
 // a word that is completely ignored by the GC than to have one for which
 // only a few updates are ignored.
 //
-// Gs, Ms, and Ps are always reachable via true pointers in the
-// allgs, allm, and allp lists or (during allocation before they reach those lists)
+// Gs and Ps are always reachable via true pointers in the
+// allgs and allp lists or (during allocation before they reach those lists)
 // from stack variables.
+//
+// Ms are always reachable via true pointers either from allm or
+// freem. Unlike Gs and Ps we do free Ms, so it's important that
+// nothing ever hold an muintptr across a safe point.
 
 // A guintptr holds a goroutine pointer, but typed as a uintptr
 // to bypass write barriers. It is used in the Gobuf goroutine state
@@ -221,6 +225,15 @@
 //go:nosplit
 func (pp *puintptr) set(p *p) { *pp = puintptr(unsafe.Pointer(p)) }
 
+// muintptr is a *m that is not tracked by the garbage collector.
+//
+// Because we do free Ms, there are some additional constrains on
+// muintptrs:
+//
+// 1. Never hold an muintptr locally across a safe point.
+//
+// 2. Any muintptr in the heap must be owned by the M itself so it can
+//    ensure it is not in use when the last true *m is released.
 type muintptr uintptr
 
 //go:nosplit
@@ -241,17 +254,19 @@
 	// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
 	//
 	// ctxt is unusual with respect to GC: it may be a
-	// heap-allocated funcval so write require a write barrier,
-	// but gobuf needs to be cleared from assembly. We take
-	// advantage of the fact that the only path that uses a
-	// non-nil ctxt is morestack. As a result, gogo is the only
-	// place where it may not already be nil, so gogo uses an
-	// explicit write barrier. Everywhere else that resets the
-	// gobuf asserts that ctxt is already nil.
+	// heap-allocated funcval, so GC needs to track it, but it
+	// needs to be set and cleared from assembly, where it's
+	// difficult to have write barriers. However, ctxt is really a
+	// saved, live register, and we only ever exchange it between
+	// the real register and the gobuf. Hence, we treat it as a
+	// root during stack scanning, which means assembly that saves
+	// and restores it doesn't need write barriers. It's still
+	// typed as a pointer so that any other writes from Go get
+	// write barriers.
 	sp   uintptr
 	pc   uintptr
 	g    guintptr
-	ctxt unsafe.Pointer // this has to be a pointer so that gc scans it
+	ctxt unsafe.Pointer
 	ret  sys.Uintreg
 	lr   uintptr
 	bp   uintptr // for GOEXPERIMENT=framepointer
@@ -272,11 +287,14 @@
 	// channel this sudog is blocking on. shrinkstack depends on
 	// this for sudogs involved in channel ops.
 
-	g          *g
-	selectdone *uint32 // CAS to 1 to win select race (may point to stack)
-	next       *sudog
-	prev       *sudog
-	elem       unsafe.Pointer // data element (may point to stack)
+	g *g
+
+	// isSelect indicates g is participating in a select, so
+	// g.selectDone must be CAS'd to win the wake-up race.
+	isSelect bool
+	next     *sudog
+	prev     *sudog
+	elem     unsafe.Pointer // data element (may point to stack)
 
 	// The following fields are never accessed concurrently.
 	// For channels, waitlink is only accessed by g.
@@ -354,7 +372,7 @@
 	sysexitticks   int64    // cputicks when syscall has returned (for tracing)
 	traceseq       uint64   // trace event sequencer
 	tracelastp     puintptr // last P emitted an event for this goroutine
-	lockedm        *m
+	lockedm        muintptr
 	sig            uint32
 	writebuf       []byte
 	sigcode0       uintptr
@@ -367,6 +385,7 @@
 	cgoCtxt        []uintptr      // cgo traceback context
 	labels         unsafe.Pointer // profiler labels
 	timer          *timer         // cached timer for time.Sleep
+	selectDone     uint32         // are we participating in a select and did someone win the race?
 
 	// Per-G GC state
 
@@ -386,16 +405,17 @@
 	divmod  uint32 // div/mod denominator for arm - known to liblink
 
 	// Fields not known to debuggers.
-	procid        uint64     // for debuggers, but offset not hard-coded
-	gsignal       *g         // signal-handling g
-	sigmask       sigset     // storage for saved signal mask
-	tls           [6]uintptr // thread-local storage (for x86 extern register)
+	procid        uint64       // for debuggers, but offset not hard-coded
+	gsignal       *g           // signal-handling g
+	goSigStack    gsignalStack // Go-allocated signal handling stack
+	sigmask       sigset       // storage for saved signal mask
+	tls           [6]uintptr   // thread-local storage (for x86 extern register)
 	mstartfn      func()
 	curg          *g       // current running goroutine
 	caughtsig     guintptr // goroutine running during fatal signal
 	p             puintptr // attached p for executing go code (nil if not executing go code)
 	nextp         puintptr
-	id            int32
+	id            int64
 	mallocing     int32
 	throwing      int32
 	preemptoff    string // if != "", keep curg running on this m
@@ -409,8 +429,11 @@
 	inwb          bool // m is executing a write barrier
 	newSigstack   bool // minit on C thread called sigaltstack
 	printlock     int8
-	incgo         bool // m is executing a cgo call
-	fastrand      uint32
+	incgo         bool   // m is executing a cgo call
+	freeWait      uint32 // if == 0, safe to free g0 and delete m (atomic)
+	fastrand      [2]uint32
+	needextram    bool
+	traceback     uint8
 	ncgocall      uint64      // number of cgo calls in total
 	ncgo          int32       // number of cgo calls currently in progress
 	cgoCallersUse uint32      // if non-zero, cgoCallers in use temporarily
@@ -419,15 +442,14 @@
 	alllink       *m // on allm
 	schedlink     muintptr
 	mcache        *mcache
-	lockedg       *g
-	createstack   [32]uintptr // stack that created this thread.
-	freglo        [16]uint32  // d[i] lsb and f[i]
-	freghi        [16]uint32  // d[i] msb and f[i+16]
-	fflag         uint32      // floating point compare flags
-	locked        uint32      // tracking for lockosthread
-	nextwaitm     uintptr     // next m waiting for lock
-	needextram    bool
-	traceback     uint8
+	lockedg       guintptr
+	createstack   [32]uintptr    // stack that created this thread.
+	freglo        [16]uint32     // d[i] lsb and f[i]
+	freghi        [16]uint32     // d[i] msb and f[i+16]
+	fflag         uint32         // floating point compare flags
+	lockedExt     uint32         // tracking for external LockOSThread
+	lockedInt     uint32         // tracking for internal lockOSThread
+	nextwaitm     muintptr       // next m waiting for lock
 	waitunlockf   unsafe.Pointer // todo go func(*g, unsafe.pointer) bool
 	waitlock      unsafe.Pointer
 	waittraceev   byte
@@ -435,6 +457,7 @@
 	startingtrace bool
 	syscalltick   uint32
 	thread        uintptr // thread handle
+	freelink      *m      // on sched.freem
 
 	// these are here because they are too large to be on the stack
 	// of low-level NOSPLIT functions.
@@ -502,26 +525,30 @@
 	palloc persistentAlloc // per-P to avoid mutex
 
 	// Per-P GC state
-	gcAssistTime     int64 // Nanoseconds in assistAlloc
-	gcBgMarkWorker   guintptr
-	gcMarkWorkerMode gcMarkWorkerMode
+	gcAssistTime         int64 // Nanoseconds in assistAlloc
+	gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker
+	gcBgMarkWorker       guintptr
+	gcMarkWorkerMode     gcMarkWorkerMode
+
+	// gcMarkWorkerStartTime is the nanotime() at which this mark
+	// worker started.
+	gcMarkWorkerStartTime int64
 
 	// gcw is this P's GC work buffer cache. The work buffer is
 	// filled by write barriers, drained by mutator assists, and
 	// disposed on certain GC state transitions.
 	gcw gcWork
 
+	// wbBuf is this P's GC write barrier buffer.
+	//
+	// TODO: Consider caching this in the running G.
+	wbBuf wbBuf
+
 	runSafePointFn uint32 // if 1, run sched.safePointFn at next safe point
 
 	pad [sys.CacheLineSize]byte
 }
 
-const (
-	// The max value of GOMAXPROCS.
-	// There are no fundamental restrictions on the value.
-	_MaxGomaxprocs = 1 << 10
-)
-
 type schedt struct {
 	// accessed atomically. keep at top to ensure alignment on 32-bit systems.
 	goidgen  uint64
@@ -529,11 +556,16 @@
 
 	lock mutex
 
+	// When increasing nmidle, nmidlelocked, nmsys, or nmfreed, be
+	// sure to call checkdead().
+
 	midle        muintptr // idle m's waiting for work
 	nmidle       int32    // number of idle m's waiting for work
 	nmidlelocked int32    // number of locked m's waiting for work
-	mcount       int32    // number of m's that have been created
+	mnext        int64    // number of m's that have been created and next M ID
 	maxmcount    int32    // maximum number of m's allowed (or die)
+	nmsys        int32    // number of system m's not counted for deadlock
+	nmfreed      int64    // cumulative number of freed m's
 
 	ngsys uint32 // number of system goroutines; updated atomically
 
@@ -560,6 +592,10 @@
 	deferlock mutex
 	deferpool [5]*_defer
 
+	// freem is the list of m's waiting to be freed when their
+	// m.exited is set. Linked through m.freelink.
+	freem *m
+
 	gcwaiting  uint32 // gc is waiting to run
 	stopwait   int32
 	stopnote   note
@@ -578,18 +614,7 @@
 	totaltime      int64 // ∫gomaxprocs dt up to procresizetime
 }
 
-// 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.locked 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.
-const (
-	_LockExternal = 1
-	_LockInternal = 2
-)
-
+// Values for the flags field of a sigTabT.
 const (
 	_SigNotify   = 1 << iota // let signal.Notify have signal, even if from kernel
 	_SigKill                 // if signal.Notify doesn't take it, exit quietly
@@ -598,7 +623,8 @@
 	_SigDefault              // if the signal isn't explicitly requested, don't monitor it
 	_SigGoExit               // cause all runtime procs to exit (only used on Plan 9).
 	_SigSetStack             // add SA_ONSTACK to libc handler
-	_SigUnblock              // unblocked in minit
+	_SigUnblock              // always unblock; see blockableSig
+	_SigIgn                  // _SIG_DFL action is to ignore the signal
 )
 
 // Layout of in-memory per-function information prepared by linker
@@ -624,14 +650,11 @@
 // Needs to be in sync with
 // ../cmd/compile/internal/gc/reflect.go:/^func.dumptypestructs.
 type itab struct {
-	inter  *interfacetype
-	_type  *_type
-	link   *itab
-	hash   uint32 // copy of _type.hash. Used for type switches.
-	bad    bool   // type does not implement interface
-	inhash bool   // has this itab been added to hash?
-	unused [2]byte
-	fun    [1]uintptr // variable sized
+	inter *interfacetype
+	_type *_type
+	hash  uint32 // copy of _type.hash. Used for type switches.
+	_     [4]byte
+	fun   [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
 }
 
 // Lock-free stack node.
@@ -672,7 +695,8 @@
 	}
 }
 
-// deferred subroutine calls
+// A _defer holds an entry on the list of deferred calls.
+// If you add a field here, add code to clear it in freedefer.
 type _defer struct {
 	siz     int32
 	started bool
@@ -716,15 +740,15 @@
 const _TracebackMaxFrames = 100
 
 var (
-	emptystring string
-	allglen     uintptr
-	allm        *m
-	allp        [_MaxGomaxprocs + 1]*p
-	gomaxprocs  int32
-	ncpu        int32
-	forcegc     forcegcstate
-	sched       schedt
-	newprocs    int32
+	allglen    uintptr
+	allm       *m
+	allp       []*p  // len(allp) == gomaxprocs; may change at safe points, otherwise immutable
+	allpLock   mutex // Protects P-less reads of allp and all writes
+	gomaxprocs int32
+	ncpu       int32
+	forcegc    forcegcstate
+	sched      schedt
+	newprocs   int32
 
 	// Information about what cpu features are available.
 	// Set on startup in asm_{386,amd64,amd64p32}.s.
diff --git a/src/runtime/runtime_linux_test.go b/src/runtime/runtime_linux_test.go
index 2b6daec..6123972 100644
--- a/src/runtime/runtime_linux_test.go
+++ b/src/runtime/runtime_linux_test.go
@@ -8,6 +8,7 @@
 	. "runtime"
 	"syscall"
 	"testing"
+	"time"
 	"unsafe"
 )
 
@@ -21,6 +22,17 @@
 	// for how it is used in init (must be on main thread).
 	pid, tid = syscall.Getpid(), syscall.Gettid()
 	LockOSThread()
+
+	sysNanosleep = func(d time.Duration) {
+		// Invoke a blocking syscall directly; calling time.Sleep()
+		// would deschedule the goroutine instead.
+		ts := syscall.NsecToTimespec(d.Nanoseconds())
+		for {
+			if err := syscall.Nanosleep(&ts, &ts); err != syscall.EINTR {
+				return
+			}
+		}
+	}
 }
 
 func TestLockOSThread(t *testing.T) {
diff --git a/src/runtime/runtime_mmap_test.go b/src/runtime/runtime_mmap_test.go
index 2eca6b9..57c38bc 100644
--- a/src/runtime/runtime_mmap_test.go
+++ b/src/runtime/runtime_mmap_test.go
@@ -16,16 +16,10 @@
 // what the code in mem_bsd.go, mem_darwin.go, and mem_linux.go expects.
 // See the uses of ENOMEM in sysMap in those files.
 func TestMmapErrorSign(t *testing.T) {
-	p := runtime.Mmap(nil, ^uintptr(0)&^(runtime.GetPhysPageSize()-1), 0, runtime.MAP_ANON|runtime.MAP_PRIVATE, -1, 0)
+	p, err := runtime.Mmap(nil, ^uintptr(0)&^(runtime.GetPhysPageSize()-1), 0, runtime.MAP_ANON|runtime.MAP_PRIVATE, -1, 0)
 
-	// The runtime.mmap function is nosplit, but t.Errorf is not.
-	// Reset the pointer so that we don't get an "invalid stack
-	// pointer" error from t.Errorf if we call it.
-	v := uintptr(p)
-	p = nil
-
-	if v != runtime.ENOMEM {
-		t.Errorf("mmap = %v, want %v", v, runtime.ENOMEM)
+	if p != nil || err != runtime.ENOMEM {
+		t.Errorf("mmap = %v, %v, want nil, %v", p, err, runtime.ENOMEM)
 	}
 }
 
@@ -35,20 +29,20 @@
 	ps := runtime.GetPhysPageSize()
 
 	// Get a region of memory to play with. This should be page-aligned.
-	b := uintptr(runtime.Mmap(nil, 2*ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE, -1, 0))
-	if b < 4096 {
-		t.Fatalf("Mmap: %v", b)
+	b, err := runtime.Mmap(nil, 2*ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE, -1, 0)
+	if err != 0 {
+		t.Fatalf("Mmap: %v", err)
 	}
 
 	// Mmap should fail at a half page into the buffer.
-	err := uintptr(runtime.Mmap(unsafe.Pointer(uintptr(b)+ps/2), ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE|runtime.MAP_FIXED, -1, 0))
-	if err >= 4096 {
+	_, err = runtime.Mmap(unsafe.Pointer(uintptr(b)+ps/2), ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE|runtime.MAP_FIXED, -1, 0)
+	if err == 0 {
 		t.Errorf("Mmap should have failed with half-page alignment %d, but succeeded: %v", ps/2, err)
 	}
 
 	// Mmap should succeed at a full page into the buffer.
-	err = uintptr(runtime.Mmap(unsafe.Pointer(uintptr(b)+ps), ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE|runtime.MAP_FIXED, -1, 0))
-	if err < 4096 {
+	_, err = runtime.Mmap(unsafe.Pointer(uintptr(b)+ps), ps, 0, runtime.MAP_ANON|runtime.MAP_PRIVATE|runtime.MAP_FIXED, -1, 0)
+	if err != 0 {
 		t.Errorf("Mmap at full-page alignment %d failed: %v", ps, err)
 	}
 }
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
index e9bc256..d5b6b3a 100644
--- a/src/runtime/runtime_test.go
+++ b/src/runtime/runtime_test.go
@@ -5,6 +5,7 @@
 package runtime_test
 
 import (
+	"flag"
 	"io"
 	. "runtime"
 	"runtime/debug"
@@ -13,6 +14,8 @@
 	"unsafe"
 )
 
+var flagQuick = flag.Bool("quick", false, "skip slow tests, for second run in all.bash")
+
 func init() {
 	// We're testing the runtime, so make tracebacks show things
 	// in the runtime. This only raises the level, so it won't
@@ -196,9 +199,9 @@
 }
 
 func TestEqString(t *testing.T) {
-	// This isn't really an exhaustive test of eqstring, it's
+	// This isn't really an exhaustive test of == on strings, it's
 	// just a convenient way of documenting (via eqstring_generic)
-	// what eqstring does.
+	// what == does.
 	s := []string{
 		"",
 		"a",
@@ -213,7 +216,7 @@
 			x := s1 == s2
 			y := eqstring_generic(s1, s2)
 			if x != y {
-				t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
+				t.Errorf(`("%s" == "%s") = %t, want %t`, s1, s2, x, y)
 			}
 		}
 	}
diff --git a/src/runtime/rwmutex.go b/src/runtime/rwmutex.go
index 7eeb559..a6da4c9 100644
--- a/src/runtime/rwmutex.go
+++ b/src/runtime/rwmutex.go
@@ -10,7 +10,7 @@
 
 // This is a copy of sync/rwmutex.go rewritten to work in the runtime.
 
-// An rwmutex is a reader/writer mutual exclusion lock.
+// A rwmutex is a reader/writer mutual exclusion lock.
 // The lock can be held by an arbitrary number of readers or a single writer.
 // This is a variant of sync.RWMutex, for the runtime package.
 // Like mutex, rwmutex blocks the calling M.
diff --git a/src/runtime/rwmutex_test.go b/src/runtime/rwmutex_test.go
index a69eca1..872b3b0 100644
--- a/src/runtime/rwmutex_test.go
+++ b/src/runtime/rwmutex_test.go
@@ -12,6 +12,7 @@
 import (
 	"fmt"
 	. "runtime"
+	"runtime/debug"
 	"sync/atomic"
 	"testing"
 )
@@ -47,6 +48,10 @@
 
 func TestParallelRWMutexReaders(t *testing.T) {
 	defer GOMAXPROCS(GOMAXPROCS(-1))
+	// If runtime triggers a forced GC during this test then it will deadlock,
+	// since the goroutines can't be stopped/preempted.
+	// Disable GC for this test (see issue #10958).
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
 	doTestParallelReaders(1)
 	doTestParallelReaders(3)
 	doTestParallelReaders(4)
diff --git a/src/runtime/select.go b/src/runtime/select.go
index 715cee8..b59c096 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -73,7 +73,7 @@
 }
 
 func selectsend(sel *hselect, c *hchan, elem unsafe.Pointer) {
-	pc := getcallerpc(unsafe.Pointer(&sel))
+	pc := getcallerpc()
 	i := sel.ncase
 	if i >= sel.tcase {
 		throw("selectsend: too many cases")
@@ -94,7 +94,7 @@
 }
 
 func selectrecv(sel *hselect, c *hchan, elem unsafe.Pointer, received *bool) {
-	pc := getcallerpc(unsafe.Pointer(&sel))
+	pc := getcallerpc()
 	i := sel.ncase
 	if i >= sel.tcase {
 		throw("selectrecv: too many cases")
@@ -116,7 +116,7 @@
 }
 
 func selectdefault(sel *hselect) {
-	pc := getcallerpc(unsafe.Pointer(&sel))
+	pc := getcallerpc()
 	i := sel.ncase
 	if i >= sel.tcase {
 		throw("selectdefault: too many cases")
@@ -286,7 +286,6 @@
 
 	var (
 		gp     *g
-		done   uint32
 		sg     *sudog
 		c      *hchan
 		k      *scase
@@ -353,7 +352,6 @@
 
 	// pass 2 - enqueue on all chans
 	gp = getg()
-	done = 0
 	if gp.waiting != nil {
 		throw("gp.waiting != nil")
 	}
@@ -367,8 +365,7 @@
 		c = cas.c
 		sg := acquireSudog()
 		sg.g = gp
-		// Note: selectdone is adjusted for stack copies in stack1.go:adjustsudogs
-		sg.selectdone = (*uint32)(noescape(unsafe.Pointer(&done)))
+		sg.isSelect = true
 		// No stack splits between assigning elem and enqueuing
 		// sg on gp.waiting where copystack can find it.
 		sg.elem = cas.elem
@@ -394,62 +391,9 @@
 	gp.param = nil
 	gopark(selparkcommit, nil, "select", traceEvGoBlockSelect, 1)
 
-	// While we were asleep, some goroutine came along and completed
-	// one of the cases in the select and woke us up (called ready).
-	// As part of that process, the goroutine did a cas on done above
-	// (aka *sg.selectdone for all queued sg) to win the right to
-	// complete the select. Now done = 1.
-	//
-	// If we copy (grow) our own stack, we will update the
-	// selectdone pointers inside the gp.waiting sudog list to point
-	// at the new stack. Another goroutine attempting to
-	// complete one of our (still linked in) select cases might
-	// see the new selectdone pointer (pointing at the new stack)
-	// before the new stack has real data; if the new stack has done = 0
-	// (before the old values are copied over), the goroutine might
-	// do a cas via sg.selectdone and incorrectly believe that it has
-	// won the right to complete the select, executing a second
-	// communication and attempting to wake us (call ready) again.
-	//
-	// Then things break.
-	//
-	// The best break is that the goroutine doing ready sees the
-	// _Gcopystack status and throws, as in #17007.
-	// A worse break would be for us to continue on, start running real code,
-	// block in a semaphore acquisition (sema.go), and have the other
-	// goroutine wake us up without having really acquired the semaphore.
-	// That would result in the goroutine spuriously running and then
-	// queue up another spurious wakeup when the semaphore really is ready.
-	// In general the situation can cascade until something notices the
-	// problem and causes a crash.
-	//
-	// A stack shrink does not have this problem, because it locks
-	// all the channels that are involved first, blocking out the
-	// possibility of a cas on selectdone.
-	//
-	// A stack growth before gopark above does not have this
-	// problem, because we hold those channel locks (released by
-	// selparkcommit).
-	//
-	// A stack growth after sellock below does not have this
-	// problem, because again we hold those channel locks.
-	//
-	// The only problem is a stack growth during sellock.
-	// To keep that from happening, run sellock on the system stack.
-	//
-	// It might be that we could avoid this if copystack copied the
-	// stack before calling adjustsudogs. In that case,
-	// syncadjustsudogs would need to recopy the tiny part that
-	// it copies today, resulting in a little bit of extra copying.
-	//
-	// An even better fix, not for the week before a release candidate,
-	// would be to put space in every sudog and make selectdone
-	// point at (say) the space in the first sudog.
+	sellock(scases, lockorder)
 
-	systemstack(func() {
-		sellock(scases, lockorder)
-	})
-
+	gp.selectDone = 0
 	sg = (*sudog)(gp.param)
 	gp.param = nil
 
@@ -462,7 +406,7 @@
 	sglist = gp.waiting
 	// Clear all elem before unlinking from gp.waiting.
 	for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
-		sg1.selectdone = nil
+		sg1.isSelect = false
 		sg1.elem = nil
 		sg1.c = nil
 	}
@@ -513,10 +457,8 @@
 		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 cas.kind == caseRecv && cas.receivedp != nil {
+		*cas.receivedp = true
 	}
 
 	if raceenabled {
diff --git a/src/runtime/sema.go b/src/runtime/sema.go
index 8715e07..d5ea14d 100644
--- a/src/runtime/sema.go
+++ b/src/runtime/sema.go
@@ -275,7 +275,10 @@
 	// on the ticket: s.ticket <= both s.prev.ticket and s.next.ticket.
 	// https://en.wikipedia.org/wiki/Treap
 	// http://faculty.washington.edu/aragon/pubs/rst89.pdf
-	s.ticket = fastrand()
+	//
+	// s.ticket compared with zero in couple of places, therefore set lowest bit.
+	// It will not affect treap's quality noticeably.
+	s.ticket = fastrand() | 1
 	s.parent = last
 	*pt = s
 
diff --git a/src/runtime/signal_darwin.go b/src/runtime/signal_darwin.go
index 0c5481a..8090fb2 100644
--- a/src/runtime/signal_darwin.go
+++ b/src/runtime/signal_darwin.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/* 0 */ {0, "SIGNONE: no trap"},
 	/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -26,20 +21,20 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
-	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
+	/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
 	/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
-	/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
-	/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+	/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
 	/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
 	/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
 }
diff --git a/src/runtime/signal_darwin_arm.go b/src/runtime/signal_darwin_arm.go
index c88b90c..9a5d3ac 100644
--- a/src/runtime/signal_darwin_arm.go
+++ b/src/runtime/signal_darwin_arm.go
@@ -36,7 +36,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().pc }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().cpsr }
-func (c *sigctxt) fault() uint32   { return c.info.si_addr }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.info.si_addr) }
 func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
 func (c *sigctxt) trap() uint32    { return 0 }
 func (c *sigctxt) error() uint32   { return 0 }
diff --git a/src/runtime/signal_darwin_arm64.go b/src/runtime/signal_darwin_arm64.go
index b14b9f1..41b8fca 100644
--- a/src/runtime/signal_darwin_arm64.go
+++ b/src/runtime/signal_darwin_arm64.go
@@ -52,7 +52,7 @@
 //go:nowritebarrierrec
 func (c *sigctxt) pc() uint64 { return c.regs().pc }
 
-func (c *sigctxt) fault() uint64 { return uint64(uintptr(unsafe.Pointer(c.info.si_addr))) }
+func (c *sigctxt) fault() uintptr { return uintptr(unsafe.Pointer(c.info.si_addr)) }
 
 func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
 func (c *sigctxt) sigaddr() uint64 { return uint64(uintptr(unsafe.Pointer(c.info.si_addr))) }
diff --git a/src/runtime/signal_dragonfly.go b/src/runtime/signal_dragonfly.go
index 8e9ce17..f2b26e7 100644
--- a/src/runtime/signal_dragonfly.go
+++ b/src/runtime/signal_dragonfly.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/* 0 */ {0, "SIGNONE: no trap"},
 	/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -26,20 +21,20 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
-	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
+	/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
 	/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
-	/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
-	/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+	/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
 	/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
 	/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
 	/* 32 */ {_SigNotify, "SIGTHR: reserved"},
diff --git a/src/runtime/signal_freebsd.go b/src/runtime/signal_freebsd.go
index 7ce7217..2812c69 100644
--- a/src/runtime/signal_freebsd.go
+++ b/src/runtime/signal_freebsd.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/* 0 */ {0, "SIGNONE: no trap"},
 	/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -26,20 +21,20 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
-	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
+	/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
 	/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
-	/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
-	/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+	/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
 	/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
 	/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
 	/* 32 */ {_SigNotify, "SIGTHR: reserved"},
diff --git a/src/runtime/signal_freebsd_arm.go b/src/runtime/signal_freebsd_arm.go
index 9601370..2135c1e 100644
--- a/src/runtime/signal_freebsd_arm.go
+++ b/src/runtime/signal_freebsd_arm.go
@@ -36,7 +36,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().__gregs[15] }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().__gregs[16] }
-func (c *sigctxt) fault() uint32   { return uint32(c.info.si_addr) }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.info.si_addr) }
 func (c *sigctxt) trap() uint32    { return 0 }
 func (c *sigctxt) error() uint32   { return 0 }
 func (c *sigctxt) oldmask() uint32 { return 0 }
diff --git a/src/runtime/signal_linux_arm.go b/src/runtime/signal_linux_arm.go
index 06a57b8..876b505 100644
--- a/src/runtime/signal_linux_arm.go
+++ b/src/runtime/signal_linux_arm.go
@@ -39,7 +39,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().pc }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().cpsr }
-func (c *sigctxt) fault() uint32   { return c.regs().fault_address }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.regs().fault_address) }
 func (c *sigctxt) trap() uint32    { return c.regs().trap_no }
 func (c *sigctxt) error() uint32   { return c.regs().error_code }
 func (c *sigctxt) oldmask() uint32 { return c.regs().oldmask }
diff --git a/src/runtime/signal_linux_arm64.go b/src/runtime/signal_linux_arm64.go
index f3d4d38..2075f25 100644
--- a/src/runtime/signal_linux_arm64.go
+++ b/src/runtime/signal_linux_arm64.go
@@ -56,7 +56,7 @@
 func (c *sigctxt) pc() uint64 { return c.regs().pc }
 
 func (c *sigctxt) pstate() uint64 { return c.regs().pstate }
-func (c *sigctxt) fault() uint64  { return c.regs().fault_address }
+func (c *sigctxt) fault() uintptr { return uintptr(c.regs().fault_address) }
 
 func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
 func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
diff --git a/src/runtime/signal_linux_mips64x.go b/src/runtime/signal_linux_mips64x.go
index 9e0cf42..b608197 100644
--- a/src/runtime/signal_linux_mips64x.go
+++ b/src/runtime/signal_linux_mips64x.go
@@ -66,6 +66,7 @@
 func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
 func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
 
+func (c *sigctxt) set_r28(x uint64)  { c.regs().sc_regs[28] = x }
 func (c *sigctxt) set_r30(x uint64)  { c.regs().sc_regs[30] = x }
 func (c *sigctxt) set_pc(x uint64)   { c.regs().sc_pc = x }
 func (c *sigctxt) set_sp(x uint64)   { c.regs().sc_regs[29] = x }
diff --git a/src/runtime/signal_linux_ppc64x.go b/src/runtime/signal_linux_ppc64x.go
index b6831bc..97cb26d 100644
--- a/src/runtime/signal_linux_ppc64x.go
+++ b/src/runtime/signal_linux_ppc64x.go
@@ -67,7 +67,7 @@
 
 func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
 func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
-func (c *sigctxt) fault() uint64   { return c.regs().dar }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.regs().dar) }
 
 func (c *sigctxt) set_r0(x uint64)   { c.regs().gpr[0] = x }
 func (c *sigctxt) set_r12(x uint64)  { c.regs().gpr[12] = x }
diff --git a/src/runtime/signal_mips64x.go b/src/runtime/signal_mips64x.go
index 9546a5a..35b356c 100644
--- a/src/runtime/signal_mips64x.go
+++ b/src/runtime/signal_mips64x.go
@@ -89,6 +89,8 @@
 	}
 
 	// In case we are panicking from external C code
+	sigpanicPC := uint64(funcPC(sigpanic))
+	c.set_r28(sigpanicPC >> 32 << 32) // RSB register
 	c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
-	c.set_pc(uint64(funcPC(sigpanic)))
+	c.set_pc(sigpanicPC)
 }
diff --git a/src/runtime/signal_nacl.go b/src/runtime/signal_nacl.go
index 4793075..ad321d8 100644
--- a/src/runtime/signal_nacl.go
+++ b/src/runtime/signal_nacl.go
@@ -26,13 +26,13 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
 	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
diff --git a/src/runtime/signal_nacl_arm.go b/src/runtime/signal_nacl_arm.go
index 959dbfb..b831232 100644
--- a/src/runtime/signal_nacl_arm.go
+++ b/src/runtime/signal_nacl_arm.go
@@ -36,7 +36,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().pc }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().cpsr }
-func (c *sigctxt) fault() uint32   { return ^uint32(0) }
+func (c *sigctxt) fault() uintptr  { return ^uintptr(0) }
 func (c *sigctxt) trap() uint32    { return ^uint32(0) }
 func (c *sigctxt) error() uint32   { return ^uint32(0) }
 func (c *sigctxt) oldmask() uint32 { return ^uint32(0) }
diff --git a/src/runtime/signal_netbsd.go b/src/runtime/signal_netbsd.go
index 30a3b8e..ca51084 100644
--- a/src/runtime/signal_netbsd.go
+++ b/src/runtime/signal_netbsd.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/*  0 */ {0, "SIGNONE: no trap"},
 	/*  1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -26,20 +21,20 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
-	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
+	/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
 	/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
-	/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
-	/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+	/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
 	/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
 	/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
 	/* 32 */ {_SigNotify, "SIGTHR: reserved"},
diff --git a/src/runtime/signal_netbsd_arm.go b/src/runtime/signal_netbsd_arm.go
index 64cfffa..fdb3078 100644
--- a/src/runtime/signal_netbsd_arm.go
+++ b/src/runtime/signal_netbsd_arm.go
@@ -36,7 +36,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().__gregs[_REG_R15] }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().__gregs[_REG_CPSR] }
-func (c *sigctxt) fault() uint32   { return uint32(c.info._reason) }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.info._reason) }
 func (c *sigctxt) trap() uint32    { return 0 }
 func (c *sigctxt) error() uint32   { return 0 }
 func (c *sigctxt) oldmask() uint32 { return 0 }
diff --git a/src/runtime/signal_openbsd.go b/src/runtime/signal_openbsd.go
index 30a3b8e..99c601c 100644
--- a/src/runtime/signal_openbsd.go
+++ b/src/runtime/signal_openbsd.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/*  0 */ {0, "SIGNONE: no trap"},
 	/*  1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -26,13 +21,13 @@
 	/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
-	/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 17 */ {0, "SIGSTOP: stop"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
-	/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
+	/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
 	/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
diff --git a/src/runtime/signal_openbsd_arm.go b/src/runtime/signal_openbsd_arm.go
index 66aea93..97bb13b 100644
--- a/src/runtime/signal_openbsd_arm.go
+++ b/src/runtime/signal_openbsd_arm.go
@@ -38,7 +38,7 @@
 func (c *sigctxt) pc() uint32 { return c.regs().sc_pc }
 
 func (c *sigctxt) cpsr() uint32    { return c.regs().sc_spsr }
-func (c *sigctxt) fault() uint32   { return c.sigaddr() }
+func (c *sigctxt) fault() uintptr  { return uintptr(c.sigaddr()) }
 func (c *sigctxt) trap() uint32    { return 0 }
 func (c *sigctxt) error() uint32   { return 0 }
 func (c *sigctxt) oldmask() uint32 { return 0 }
diff --git a/src/runtime/signal_sighandler.go b/src/runtime/signal_sighandler.go
index b2e15a6..bf2237c 100644
--- a/src/runtime/signal_sighandler.go
+++ b/src/runtime/signal_sighandler.go
@@ -38,6 +38,11 @@
 	if sig < uint32(len(sigtable)) {
 		flags = sigtable[sig].flags
 	}
+	if flags&_SigPanic != 0 && gp.throwsplit {
+		// We can't safely sigpanic because it may grow the
+		// stack. Abort in the signal handler instead.
+		flags = (flags &^ _SigPanic) | _SigThrow
+	}
 	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
 		// The signal is going to cause a panic.
 		// Arrange the stack so that it looks like the point
@@ -88,9 +93,9 @@
 	}
 
 	print("PC=", hex(c.sigpc()), " m=", _g_.m.id, " sigcode=", c.sigcode(), "\n")
-	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+	if _g_.m.lockedg != 0 && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
 		print("signal arrived during cgo execution\n")
-		gp = _g_.m.lockedg
+		gp = _g_.m.lockedg.ptr()
 	}
 	print("\n")
 
@@ -111,7 +116,7 @@
 
 	if docrash {
 		crashing++
-		if crashing < sched.mcount-int32(extraMCount) {
+		if crashing < mcount()-int32(extraMCount) {
 			// There are other m's that need to dump their stacks.
 			// Relay SIGQUIT to the next m by sending it to the current process.
 			// All m's that have already received SIGQUIT have signal masks blocking
diff --git a/src/runtime/signal_solaris.go b/src/runtime/signal_solaris.go
index c931c22..a8eeeee 100644
--- a/src/runtime/signal_solaris.go
+++ b/src/runtime/signal_solaris.go
@@ -4,11 +4,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/* 0 */ {0, "SIGNONE: no trap"},
 	/* 1 */ {_SigNotify + _SigKill, "SIGHUP: hangup"},
@@ -28,16 +23,16 @@
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: software termination signal from kill"},
 	/* 16 */ {_SigNotify, "SIGUSR1: user defined signal 1"},
 	/* 17 */ {_SigNotify, "SIGUSR2: user defined signal 2"},
-	/* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status change alias (POSIX)"},
+	/* 18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status change alias (POSIX)"},
 	/* 19 */ {_SigNotify, "SIGPWR: power-fail restart"},
-	/* 20 */ {_SigNotify, "SIGWINCH: window size change"},
-	/* 21 */ {_SigNotify, "SIGURG: urgent socket condition"},
+	/* 20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/* 21 */ {_SigNotify + _SigIgn, "SIGURG: urgent socket condition"},
 	/* 22 */ {_SigNotify, "SIGPOLL: pollable event occurred"},
 	/* 23 */ {0, "SIGSTOP: stop (cannot be caught or ignored)"},
-	/* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: user stop requested from tty"},
-	/* 25 */ {_SigNotify + _SigDefault, "SIGCONT: stopped process has been continued"},
-	/* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background tty read attempted"},
-	/* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background tty write attempted"},
+	/* 24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: user stop requested from tty"},
+	/* 25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: stopped process has been continued"},
+	/* 26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background tty read attempted"},
+	/* 27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background tty write attempted"},
 	/* 28 */ {_SigNotify, "SIGVTALRM: virtual timer expired"},
 	/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling timer expired"},
 	/* 30 */ {_SigNotify, "SIGXCPU: exceeded cpu limit"},
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 539b165..78649c5 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -8,10 +8,19 @@
 
 import (
 	"runtime/internal/atomic"
-	"runtime/internal/sys"
 	"unsafe"
 )
 
+// sigTabT is the type of an entry in the global sigtable array.
+// sigtable is inherently system dependent, and appears in OS-specific files,
+// but sigTabT is the same for all Unixy systems.
+// The sigtable array is indexed by a system signal number to get the flags
+// and printable name of each signal.
+type sigTabT struct {
+	flags int32
+	name  string
+}
+
 //go:linkname os_sigpipe os.sigpipe
 func os_sigpipe() {
 	systemstack(sigpipe)
@@ -266,6 +275,12 @@
 // sigtrampgo is called from the signal handler function, sigtramp,
 // written in assembly code.
 // This is called by the signal handler, and the world may be stopped.
+//
+// It must be nosplit because getg() is still the G that was running
+// (if any) when the signal was delivered, but it's (usually) called
+// on the gsignal stack. Until this switches the G to gsignal, the
+// stack bounds check won't work.
+//
 //go:nosplit
 //go:nowritebarrierrec
 func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
@@ -345,6 +360,12 @@
 // the signal handler. The effect is that the program will act as
 // though the function that got the signal simply called sigpanic
 // instead.
+//
+// This must NOT be nosplit because the linker doesn't know where
+// sigpanic calls can be injected.
+//
+// The signal handler must not inject a call to sigpanic if
+// getg().throwsplit, since sigpanic may need to grow the stack.
 func sigpanic() {
 	g := getg()
 	if !canpanic(g) {
@@ -395,8 +416,9 @@
 //go:nosplit
 //go:nowritebarrierrec
 func dieFromSignal(sig uint32) {
-	setsig(sig, _SIG_DFL)
 	unblocksig(sig)
+	// Mark the signal as unhandled to ensure it is forwarded.
+	atomic.Store(&handlingSig[sig], 0)
 	raise(sig)
 
 	// That should have killed us. On some systems, though, raise
@@ -408,6 +430,22 @@
 	osyield()
 	osyield()
 
+	// If that didn't work, try _SIG_DFL.
+	setsig(sig, _SIG_DFL)
+	raise(sig)
+
+	osyield()
+	osyield()
+	osyield()
+
+	// On Darwin we may still fail to die, because raise sends the
+	// signal to the whole process rather than just the current thread,
+	// and osyield just sleeps briefly rather than letting all other
+	// threads run. See issue 20315. Sleep longer.
+	if GOOS == "darwin" {
+		usleep(100)
+	}
+
 	// If we are still somehow running, just exit with the wrong status.
 	exit(2)
 }
@@ -474,7 +512,7 @@
 		// 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 sys.PtrSize == 8 {
+		if GOARCH == "amd64" {
 			return
 		}
 	}
@@ -502,7 +540,7 @@
 		// mask accordingly.
 		sigBlocked := sigset_all
 		for i := range sigtable {
-			if sigtable[i].flags&_SigUnblock != 0 {
+			if !blockableSig(uint32(i)) {
 				sigdelset(&sigBlocked, i)
 			}
 		}
@@ -514,7 +552,7 @@
 					sigdelset(&sigBlocked, int(sig))
 				}
 			case sig := <-disableSigChan:
-				if sig > 0 {
+				if sig > 0 && blockableSig(sig) {
 					sigaddset(&sigBlocked, int(sig))
 				}
 			}
@@ -578,17 +616,23 @@
 		return false
 	}
 	fwdFn := atomic.Loaduintptr(&fwdSig[sig])
+	flags := sigtable[sig].flags
 
-	if !signalsOK {
-		// The only way we can get here is if we are in a
-		// library or archive, we installed a signal handler
-		// at program startup, but the Go runtime has not yet
-		// been initialized.
-		if fwdFn == _SIG_DFL {
-			dieFromSignal(sig)
-		} else {
-			sigfwd(fwdFn, sig, info, ctx)
+	// If we aren't handling the signal, forward it.
+	if atomic.Load(&handlingSig[sig]) == 0 || !signalsOK {
+		// If the signal is ignored, doing nothing is the same as forwarding.
+		if fwdFn == _SIG_IGN || (fwdFn == _SIG_DFL && flags&_SigIgn != 0) {
+			return true
 		}
+		// We are not handling the signal and there is no other handler to forward to.
+		// Crash with the default behavior.
+		if fwdFn == _SIG_DFL {
+			setsig(sig, _SIG_DFL)
+			dieFromSignal(sig)
+			return false
+		}
+
+		sigfwd(fwdFn, sig, info, ctx)
 		return true
 	}
 
@@ -597,18 +641,6 @@
 		return false
 	}
 
-	// If we aren't handling the signal, forward it.
-	// Really if we aren't handling the signal, we shouldn't get here,
-	// but on Darwin setsigstack can lead us here because it sets
-	// the sa_tramp field. The sa_tramp field is not returned by
-	// sigaction, so the fix for that is non-obvious.
-	if atomic.Load(&handlingSig[sig]) == 0 {
-		sigfwd(fwdFn, sig, info, ctx)
-		return true
-	}
-
-	flags := sigtable[sig].flags
-
 	c := &sigctxt{info, ctx}
 	// Only forward synchronous signals and SIGPIPE.
 	// Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
@@ -702,7 +734,7 @@
 		signalstack(&_g_.m.gsignal.stack)
 		_g_.m.newSigstack = true
 	} else {
-		setGsignalStack(&st, nil)
+		setGsignalStack(&st, &_g_.m.goSigStack)
 		_g_.m.newSigstack = false
 	}
 }
@@ -718,7 +750,7 @@
 func minitSignalMask() {
 	nmask := getg().m.sigmask
 	for i := range sigtable {
-		if sigtable[i].flags&_SigUnblock != 0 {
+		if !blockableSig(uint32(i)) {
 			sigdelset(&nmask, i)
 		}
 	}
@@ -732,9 +764,36 @@
 	if getg().m.newSigstack {
 		st := stackt{ss_flags: _SS_DISABLE}
 		sigaltstack(&st, nil)
+	} else {
+		// We got the signal stack from someone else. Restore
+		// the Go-allocated stack in case this M gets reused
+		// for another thread (e.g., it's an extram). Also, on
+		// Android, libc allocates a signal stack for all
+		// threads, so it's important to restore the Go stack
+		// even on Go-created threads so we can free it.
+		restoreGsignalStack(&getg().m.goSigStack)
 	}
 }
 
+// blockableSig returns whether sig may be blocked by the signal mask.
+// We never want to block the signals marked _SigUnblock;
+// these are the synchronous signals that turn into a Go panic.
+// In a Go program--not a c-archive/c-shared--we never want to block
+// the signals marked _SigKill or _SigThrow, as otherwise it's possible
+// for all running threads to block them and delay their delivery until
+// we start a new thread. When linked into a C program we let the C code
+// decide on the disposition of those signals.
+func blockableSig(sig uint32) bool {
+	flags := sigtable[sig].flags
+	if flags&_SigUnblock != 0 {
+		return false
+	}
+	if isarchive || islibrary {
+		return true
+	}
+	return flags&(_SigKill|_SigThrow) == 0
+}
+
 // gsignalStack saves the fields of the gsignal stack changed by
 // setGsignalStack.
 type gsignalStack struct {
diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
index 73bd5b5..518aac3 100644
--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -71,6 +71,12 @@
 		return _EXCEPTION_CONTINUE_SEARCH
 	}
 
+	if gp.throwsplit {
+		// We can't safely sigpanic because it may grow the
+		// stack. Let it fall through.
+		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
@@ -126,11 +132,11 @@
 	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
 
 	print("PC=", hex(r.ip()), "\n")
-	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+	if _g_.m.lockedg != 0 && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
 		if iscgo {
 			print("signal arrived during external code execution\n")
 		}
-		gp = _g_.m.lockedg
+		gp = _g_.m.lockedg.ptr()
 	}
 	print("\n")
 
@@ -223,3 +229,6 @@
 	// It's okay to leave this empty for now: if crash returns
 	// the ordinary exit-after-panic happens.
 }
+
+// gsignalStack is unused on Windows.
+type gsignalStack struct{}
diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go
index 236bb29..9833162 100644
--- a/src/runtime/sigqueue.go
+++ b/src/runtime/sigqueue.go
@@ -45,13 +45,14 @@
 // as there is no connection between handling a signal and receiving one,
 // but atomic instructions should minimize it.
 var sig struct {
-	note    note
-	mask    [(_NSIG + 31) / 32]uint32
-	wanted  [(_NSIG + 31) / 32]uint32
-	ignored [(_NSIG + 31) / 32]uint32
-	recv    [(_NSIG + 31) / 32]uint32
-	state   uint32
-	inuse   bool
+	note       note
+	mask       [(_NSIG + 31) / 32]uint32
+	wanted     [(_NSIG + 31) / 32]uint32
+	ignored    [(_NSIG + 31) / 32]uint32
+	recv       [(_NSIG + 31) / 32]uint32
+	state      uint32
+	delivering uint32
+	inuse      bool
 }
 
 const (
@@ -60,15 +61,20 @@
 	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.
+// sigsend delivers a signal from sighandler to the internal signal delivery queue.
+// It reports whether the signal was sent. If not, the caller typically crashes the program.
+// It runs from the signal handler, so it's limited in what it can do.
 func sigsend(s uint32) bool {
 	bit := uint32(1) << uint(s&31)
 	if !sig.inuse || s >= uint32(32*len(sig.wanted)) {
 		return false
 	}
 
+	atomic.Xadd(&sig.delivering, 1)
+	// We are running in the signal handler; defer is not available.
+
 	if w := atomic.Load(&sig.wanted[s/32]); w&bit == 0 {
+		atomic.Xadd(&sig.delivering, -1)
 		return false
 	}
 
@@ -76,6 +82,7 @@
 	for {
 		mask := sig.mask[s/32]
 		if mask&bit != 0 {
+			atomic.Xadd(&sig.delivering, -1)
 			return true // signal already in queue
 		}
 		if atomic.Cas(&sig.mask[s/32], mask, mask|bit) {
@@ -104,6 +111,7 @@
 		}
 	}
 
+	atomic.Xadd(&sig.delivering, -1)
 	return true
 }
 
@@ -155,6 +163,15 @@
 // by the os/signal package.
 //go:linkname signalWaitUntilIdle os/signal.signalWaitUntilIdle
 func signalWaitUntilIdle() {
+	// Although the signals we care about have been removed from
+	// sig.wanted, it is possible that another thread has received
+	// a signal, has read from sig.wanted, is now updating sig.mask,
+	// and has not yet woken up the processor thread. We need to wait
+	// until all current signal deliveries have completed.
+	for atomic.Load(&sig.delivering) != 0 {
+		Gosched()
+	}
+
 	// Although WaitUntilIdle seems like the right name for this
 	// function, the state we are looking for is sigReceiving, not
 	// sigIdle.  The sigIdle state is really more like sigProcessing.
diff --git a/src/runtime/sigtab_linux_generic.go b/src/runtime/sigtab_linux_generic.go
index 874148e..b26040b 100644
--- a/src/runtime/sigtab_linux_generic.go
+++ b/src/runtime/sigtab_linux_generic.go
@@ -10,11 +10,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/* 0 */ {0, "SIGNONE: no trap"},
 	/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -33,18 +28,18 @@
 	/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
 	/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
 	/* 16 */ {_SigThrow + _SigUnblock, "SIGSTKFLT: stack fault"},
-	/* 17 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
-	/* 18 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
+	/* 17 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
+	/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"},
 	/* 19 */ {0, "SIGSTOP: stop, unblockable"},
-	/* 20 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
-	/* 23 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/* 20 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
+	/* 23 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
 	/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
 	/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
-	/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
+	/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
 	/* 29 */ {_SigNotify, "SIGIO: i/o now possible"},
 	/* 30 */ {_SigNotify, "SIGPWR: power failure restart"},
 	/* 31 */ {_SigThrow, "SIGSYS: bad system call"},
diff --git a/src/runtime/sigtab_linux_mipsx.go b/src/runtime/sigtab_linux_mipsx.go
index 8d9fb06..81dd231 100644
--- a/src/runtime/sigtab_linux_mipsx.go
+++ b/src/runtime/sigtab_linux_mipsx.go
@@ -7,11 +7,6 @@
 
 package runtime
 
-type sigTabT struct {
-	flags int32
-	name  string
-}
-
 var sigtable = [...]sigTabT{
 	/*  0 */ {0, "SIGNONE: no trap"},
 	/*  1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
@@ -31,16 +26,16 @@
 	/*  15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
 	/*  16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
 	/*  17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
-	/*  18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
+	/*  18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
 	/*  19 */ {_SigNotify, "SIGPWR: power failure restart"},
-	/*  20 */ {_SigNotify, "SIGWINCH: window size change"},
-	/*  21 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+	/*  20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
+	/*  21 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
 	/*  22 */ {_SigNotify, "SIGIO: i/o now possible"},
 	/*  23 */ {0, "SIGSTOP: stop, unblockable"},
-	/*  24 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
-	/*  25 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
-	/*  26 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
-	/*  27 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+	/*  24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
+	/*  25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"},
+	/*  26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
+	/*  27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
 	/*  28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
 	/*  29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
 	/*  30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
diff --git a/src/runtime/sizeclasses.go b/src/runtime/sizeclasses.go
index 5366564..9e17b00 100644
--- a/src/runtime/sizeclasses.go
+++ b/src/runtime/sizeclasses.go
@@ -3,73 +3,73 @@
 
 package runtime
 
-// class  bytes/obj  bytes/span  objects  waste bytes
-//     1          8        8192     1024            0
-//     2         16        8192      512            0
-//     3         32        8192      256            0
-//     4         48        8192      170           32
-//     5         64        8192      128            0
-//     6         80        8192      102           32
-//     7         96        8192       85           32
-//     8        112        8192       73           16
-//     9        128        8192       64            0
-//    10        144        8192       56          128
-//    11        160        8192       51           32
-//    12        176        8192       46           96
-//    13        192        8192       42          128
-//    14        208        8192       39           80
-//    15        224        8192       36          128
-//    16        240        8192       34           32
-//    17        256        8192       32            0
-//    18        288        8192       28          128
-//    19        320        8192       25          192
-//    20        352        8192       23           96
-//    21        384        8192       21          128
-//    22        416        8192       19          288
-//    23        448        8192       18          128
-//    24        480        8192       17           32
-//    25        512        8192       16            0
-//    26        576        8192       14          128
-//    27        640        8192       12          512
-//    28        704        8192       11          448
-//    29        768        8192       10          512
-//    30        896        8192        9          128
-//    31       1024        8192        8            0
-//    32       1152        8192        7          128
-//    33       1280        8192        6          512
-//    34       1408       16384       11          896
-//    35       1536        8192        5          512
-//    36       1792       16384        9          256
-//    37       2048        8192        4            0
-//    38       2304       16384        7          256
-//    39       2688        8192        3          128
-//    40       3072       24576        8            0
-//    41       3200       16384        5          384
-//    42       3456       24576        7          384
-//    43       4096        8192        2            0
-//    44       4864       24576        5          256
-//    45       5376       16384        3          256
-//    46       6144       24576        4            0
-//    47       6528       32768        5          128
-//    48       6784       40960        6          256
-//    49       6912       49152        7          768
-//    50       8192        8192        1            0
-//    51       9472       57344        6          512
-//    52       9728       49152        5          512
-//    53      10240       40960        4            0
-//    54      10880       32768        3          128
-//    55      12288       24576        2            0
-//    56      13568       40960        3          256
-//    57      14336       57344        4            0
-//    58      16384       16384        1            0
-//    59      18432       73728        4            0
-//    60      19072       57344        3          128
-//    61      20480       40960        2            0
-//    62      21760       65536        3          256
-//    63      24576       24576        1            0
-//    64      27264       81920        3          128
-//    65      28672       57344        2            0
-//    66      32768       32768        1            0
+// class  bytes/obj  bytes/span  objects  tail waste  max waste
+//     1          8        8192     1024           0     87.50%
+//     2         16        8192      512           0     43.75%
+//     3         32        8192      256           0     46.88%
+//     4         48        8192      170          32     31.52%
+//     5         64        8192      128           0     23.44%
+//     6         80        8192      102          32     19.07%
+//     7         96        8192       85          32     15.95%
+//     8        112        8192       73          16     13.56%
+//     9        128        8192       64           0     11.72%
+//    10        144        8192       56         128     11.82%
+//    11        160        8192       51          32      9.73%
+//    12        176        8192       46          96      9.59%
+//    13        192        8192       42         128      9.25%
+//    14        208        8192       39          80      8.12%
+//    15        224        8192       36         128      8.15%
+//    16        240        8192       34          32      6.62%
+//    17        256        8192       32           0      5.86%
+//    18        288        8192       28         128     12.16%
+//    19        320        8192       25         192     11.80%
+//    20        352        8192       23          96      9.88%
+//    21        384        8192       21         128      9.51%
+//    22        416        8192       19         288     10.71%
+//    23        448        8192       18         128      8.37%
+//    24        480        8192       17          32      6.82%
+//    25        512        8192       16           0      6.05%
+//    26        576        8192       14         128     12.33%
+//    27        640        8192       12         512     15.48%
+//    28        704        8192       11         448     13.93%
+//    29        768        8192       10         512     13.94%
+//    30        896        8192        9         128     15.52%
+//    31       1024        8192        8           0     12.40%
+//    32       1152        8192        7         128     12.41%
+//    33       1280        8192        6         512     15.55%
+//    34       1408       16384       11         896     14.00%
+//    35       1536        8192        5         512     14.00%
+//    36       1792       16384        9         256     15.57%
+//    37       2048        8192        4           0     12.45%
+//    38       2304       16384        7         256     12.46%
+//    39       2688        8192        3         128     15.59%
+//    40       3072       24576        8           0     12.47%
+//    41       3200       16384        5         384      6.22%
+//    42       3456       24576        7         384      8.83%
+//    43       4096        8192        2           0     15.60%
+//    44       4864       24576        5         256     16.65%
+//    45       5376       16384        3         256     10.92%
+//    46       6144       24576        4           0     12.48%
+//    47       6528       32768        5         128      6.23%
+//    48       6784       40960        6         256      4.36%
+//    49       6912       49152        7         768      3.37%
+//    50       8192        8192        1           0     15.61%
+//    51       9472       57344        6         512     14.28%
+//    52       9728       49152        5         512      3.64%
+//    53      10240       40960        4           0      4.99%
+//    54      10880       32768        3         128      6.24%
+//    55      12288       24576        2           0     11.45%
+//    56      13568       40960        3         256      9.99%
+//    57      14336       57344        4           0      5.35%
+//    58      16384       16384        1           0     12.49%
+//    59      18432       73728        4           0     11.11%
+//    60      19072       57344        3         128      3.57%
+//    61      20480       40960        2           0      6.87%
+//    62      21760       65536        3         256      6.25%
+//    63      24576       24576        1           0     11.45%
+//    64      27264       81920        3         128     10.00%
+//    65      28672       57344        2           0      4.91%
+//    66      32768       32768        1           0     12.50%
 
 const (
 	_MaxSmallSize   = 32768
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index 0f49df1..351fec0 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -14,6 +14,13 @@
 	cap   int
 }
 
+// An notInHeapSlice is a slice backed by go:notinheap memory.
+type notInHeapSlice struct {
+	array *notInHeap
+	len   int
+	cap   int
+}
+
 // maxElems is a lookup table containing the maximum capacity for a slice.
 // The index is the size of the slice element.
 var maxElems = [...]uintptr{
@@ -81,7 +88,7 @@
 // The SSA backend might prefer the new length or to return only ptr/cap and save stack space.
 func growslice(et *_type, old slice, cap int) slice {
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&et))
+		callerpc := getcallerpc()
 		racereadrangepc(old.array, uintptr(old.len*int(et.size)), callerpc, funcPC(growslice))
 	}
 	if msanenabled {
@@ -105,12 +112,20 @@
 		if old.len < 1024 {
 			newcap = doublecap
 		} else {
-			for newcap < cap {
+			// Check 0 < newcap to detect overflow
+			// and prevent an infinite loop.
+			for 0 < newcap && newcap < cap {
 				newcap += newcap / 4
 			}
+			// Set newcap to the requested cap when
+			// the newcap calculation overflowed.
+			if newcap <= 0 {
+				newcap = cap
+			}
 		}
 	}
 
+	var overflow bool
 	var lenmem, newlenmem, capmem uintptr
 	const ptrSize = unsafe.Sizeof((*byte)(nil))
 	switch et.size {
@@ -118,20 +133,37 @@
 		lenmem = uintptr(old.len)
 		newlenmem = uintptr(cap)
 		capmem = roundupsize(uintptr(newcap))
+		overflow = uintptr(newcap) > _MaxMem
 		newcap = int(capmem)
 	case ptrSize:
 		lenmem = uintptr(old.len) * ptrSize
 		newlenmem = uintptr(cap) * ptrSize
 		capmem = roundupsize(uintptr(newcap) * ptrSize)
+		overflow = uintptr(newcap) > _MaxMem/ptrSize
 		newcap = int(capmem / ptrSize)
 	default:
 		lenmem = uintptr(old.len) * et.size
 		newlenmem = uintptr(cap) * et.size
 		capmem = roundupsize(uintptr(newcap) * et.size)
+		overflow = uintptr(newcap) > maxSliceCap(et.size)
 		newcap = int(capmem / et.size)
 	}
 
-	if cap < old.cap || uintptr(newcap) > maxSliceCap(et.size) {
+	// The check of overflow (uintptr(newcap) > maxSliceCap(et.size))
+	// in addition to capmem > _MaxMem is needed to prevent an overflow
+	// which can be used to trigger a segfault on 32bit architectures
+	// with this example program:
+	//
+	// type T [1<<27 + 1]int64
+	//
+	// var d T
+	// var s []T
+	//
+	// func main() {
+	//   s = append(s, d, d, d, d)
+	//   print(len(s), "\n")
+	// }
+	if cap < old.cap || overflow || capmem > _MaxMem {
 		panic(errorString("growslice: cap out of range"))
 	}
 
@@ -172,7 +204,7 @@
 	}
 
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&to))
+		callerpc := getcallerpc()
 		pc := funcPC(slicecopy)
 		racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
 		racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
@@ -203,7 +235,7 @@
 	}
 
 	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&to))
+		callerpc := getcallerpc()
 		pc := funcPC(slicestringcopy)
 		racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
 	}
diff --git a/src/runtime/softfloat64.go b/src/runtime/softfloat64.go
index 1678e8f..8fde0fe 100644
--- a/src/runtime/softfloat64.go
+++ b/src/runtime/softfloat64.go
@@ -483,3 +483,115 @@
 
 	return q1*b + q0, (un21*b + un0 - q0*v) >> s
 }
+
+func fadd32(x, y uint32) uint32 {
+	return f64to32(fadd64(f32to64(x), f32to64(y)))
+}
+
+func fmul32(x, y uint32) uint32 {
+	return f64to32(fmul64(f32to64(x), f32to64(y)))
+}
+
+func fdiv32(x, y uint32) uint32 {
+	return f64to32(fdiv64(f32to64(x), f32to64(y)))
+}
+
+func feq32(x, y uint32) bool {
+	cmp, nan := fcmp64(f32to64(x), f32to64(y))
+	return cmp == 0 && !nan
+}
+
+func fgt32(x, y uint32) bool {
+	cmp, nan := fcmp64(f32to64(x), f32to64(y))
+	return cmp >= 1 && !nan
+}
+
+func fge32(x, y uint32) bool {
+	cmp, nan := fcmp64(f32to64(x), f32to64(y))
+	return cmp >= 0 && !nan
+}
+
+func feq64(x, y uint64) bool {
+	cmp, nan := fcmp64(x, y)
+	return cmp == 0 && !nan
+}
+
+func fgt64(x, y uint64) bool {
+	cmp, nan := fcmp64(x, y)
+	return cmp >= 1 && !nan
+}
+
+func fge64(x, y uint64) bool {
+	cmp, nan := fcmp64(x, y)
+	return cmp >= 0 && !nan
+}
+
+func fint32to32(x int32) uint32 {
+	return f64to32(fintto64(int64(x)))
+}
+
+func fint32to64(x int32) uint64 {
+	return fintto64(int64(x))
+}
+
+func fint64to32(x int64) uint32 {
+	return f64to32(fintto64(x))
+}
+
+func fint64to64(x int64) uint64 {
+	return fintto64(x)
+}
+
+func f32toint32(x uint32) int32 {
+	val, _ := f64toint(f32to64(x))
+	return int32(val)
+}
+
+func f32toint64(x uint32) int64 {
+	val, _ := f64toint(f32to64(x))
+	return val
+}
+
+func f64toint32(x uint64) int32 {
+	val, _ := f64toint(x)
+	return int32(val)
+}
+
+func f64toint64(x uint64) int64 {
+	val, _ := f64toint(x)
+	return val
+}
+
+func f64touint64(x float64) uint64 {
+	if x < float64(1<<63) {
+		return uint64(int64(x))
+	}
+	y := x - float64(1<<63)
+	z := uint64(int64(y))
+	return z | (1 << 63)
+}
+
+func f32touint64(x float32) uint64 {
+	if x < float32(1<<63) {
+		return uint64(int64(x))
+	}
+	y := x - float32(1<<63)
+	z := uint64(int64(y))
+	return z | (1 << 63)
+}
+
+func fuint64to64(x uint64) float64 {
+	if int64(x) >= 0 {
+		return float64(int64(x))
+	}
+	// See ../cmd/compile/internal/gc/ssa.go:uint64Tofloat
+	y := x & 1
+	z := x >> 1
+	z = z | y
+	r := float64(int64(z))
+	return r + r
+}
+
+func fuint64to32(x uint64) float32 {
+	return float32(fuint64to64(x))
+}
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 525d0b1..6149838 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -578,29 +578,30 @@
 		if stackDebug >= 4 {
 			print("        ", add(scanp, i*sys.PtrSize), ":", ptrnames[ptrbit(&bv, i)], ":", hex(*(*uintptr)(add(scanp, i*sys.PtrSize))), " # ", i, " ", bv.bytedata[i/8], "\n")
 		}
-		if ptrbit(&bv, i) == 1 {
-			pp := (*uintptr)(add(scanp, i*sys.PtrSize))
-		retry:
-			p := *pp
-			if f.valid() && 0 < p && p < minLegalPointer && debug.invalidptr != 0 {
-				// Looks like a junk value in a pointer slot.
-				// Live analysis wrong?
-				getg().m.traceback = 2
-				print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n")
-				throw("invalid pointer found on stack")
+		if ptrbit(&bv, i) != 1 {
+			continue
+		}
+		pp := (*uintptr)(add(scanp, i*sys.PtrSize))
+	retry:
+		p := *pp
+		if f.valid() && 0 < p && p < minLegalPointer && debug.invalidptr != 0 {
+			// Looks like a junk value in a pointer slot.
+			// Live analysis wrong?
+			getg().m.traceback = 2
+			print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n")
+			throw("invalid pointer found on stack")
+		}
+		if minp <= p && p < maxp {
+			if stackDebug >= 3 {
+				print("adjust ptr ", hex(p), " ", funcname(f), "\n")
 			}
-			if minp <= p && p < maxp {
-				if stackDebug >= 3 {
-					print("adjust ptr ", hex(p), " ", funcname(f), "\n")
+			if useCAS {
+				ppu := (*unsafe.Pointer)(unsafe.Pointer(pp))
+				if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) {
+					goto retry
 				}
-				if useCAS {
-					ppu := (*unsafe.Pointer)(unsafe.Pointer(pp))
-					if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) {
-						goto retry
-					}
-				} else {
-					*pp = p + delta
-				}
+			} else {
+				*pp = p + delta
 			}
 		}
 	}
@@ -751,7 +752,6 @@
 	// might be in the stack.
 	for s := gp.waiting; s != nil; s = s.waitlink {
 		adjustpointer(adjinfo, unsafe.Pointer(&s.elem))
-		adjustpointer(adjinfo, unsafe.Pointer(&s.selectdone))
 	}
 }
 
@@ -768,10 +768,6 @@
 		if stk.lo <= p && p < stk.hi && p > sghi {
 			sghi = p
 		}
-		p = uintptr(unsafe.Pointer(sg.selectdone)) + unsafe.Sizeof(sg.selectdone)
-		if stk.lo <= p && p < stk.hi && p > sghi {
-			sghi = p
-		}
 	}
 	return sghi
 }
@@ -917,9 +913,12 @@
 // 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.
 //
-// ctxt is the value of the context register on morestack. newstack
-// will write it to g.sched.ctxt.
-func newstack(ctxt unsafe.Pointer) {
+// This must be nowritebarrierrec because it can be called as part of
+// stack growth from other nowritebarrierrec functions, but the
+// compiler doesn't check this.
+//
+//go:nowritebarrierrec
+func newstack() {
 	thisg := getg()
 	// TODO: double check all gp. shouldn't be getg().
 	if thisg.m.morebuf.g.ptr().stackguard0 == stackFork {
@@ -933,19 +932,24 @@
 	}
 
 	gp := thisg.m.curg
-	// Write ctxt to gp.sched. We do this here instead of in
-	// morestack so it has the necessary write barrier.
-	gp.sched.ctxt = ctxt
 
 	if thisg.m.curg.throwsplit {
 		// Update syscallsp, syscallpc in case traceback uses them.
 		morebuf := thisg.m.morebuf
 		gp.syscallsp = morebuf.sp
 		gp.syscallpc = morebuf.pc
-		print("runtime: newstack sp=", hex(gp.sched.sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
+		pcname, pcoff := "(unknown)", uintptr(0)
+		f := findfunc(gp.sched.pc)
+		if f.valid() {
+			pcname = funcname(f)
+			pcoff = gp.sched.pc - f.entry
+		}
+		print("runtime: newstack at ", pcname, "+", hex(pcoff),
+			" sp=", hex(gp.sched.sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
 			"\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n",
 			"\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n")
 
+		thisg.m.traceback = 2 // Include runtime frames
 		traceback(morebuf.pc, morebuf.sp, morebuf.lr, gp)
 		throw("runtime: stack split at bad time")
 	}
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go
index 25e8f77..0fed241 100644
--- a/src/runtime/stack_test.go
+++ b/src/runtime/stack_test.go
@@ -5,6 +5,9 @@
 package runtime_test
 
 import (
+	"bytes"
+	"fmt"
+	"reflect"
 	. "runtime"
 	"strings"
 	"sync"
@@ -78,10 +81,13 @@
 	var wg sync.WaitGroup
 
 	// in a normal goroutine
+	var growDuration time.Duration // For debugging failures
 	wg.Add(1)
 	go func() {
 		defer wg.Done()
-		growStack()
+		start := time.Now()
+		growStack(nil)
+		growDuration = time.Since(start)
 	}()
 	wg.Wait()
 
@@ -90,7 +96,7 @@
 	go func() {
 		defer wg.Done()
 		LockOSThread()
-		growStack()
+		growStack(nil)
 		UnlockOSThread()
 	}()
 	wg.Wait()
@@ -100,12 +106,14 @@
 	go func() {
 		defer wg.Done()
 		done := make(chan bool)
-		var started uint32
+		var startTime time.Time
+		var started, progress uint32
 		go func() {
 			s := new(string)
 			SetFinalizer(s, func(ss *string) {
+				startTime = time.Now()
 				atomic.StoreUint32(&started, 1)
-				growStack()
+				growStack(&progress)
 				done <- true
 			})
 			s = nil
@@ -118,7 +126,10 @@
 		case <-time.After(20 * time.Second):
 			if atomic.LoadUint32(&started) == 0 {
 				t.Log("finalizer did not start")
+			} else {
+				t.Logf("finalizer started %s ago and finished %d iterations", time.Since(startTime), atomic.LoadUint32(&progress))
 			}
+			t.Log("first growStack took", growDuration)
 			t.Error("finalizer did not run")
 			return
 		}
@@ -131,7 +142,7 @@
 //	growStack()
 //}
 
-func growStack() {
+func growStack(progress *uint32) {
 	n := 1 << 10
 	if testing.Short() {
 		n = 1 << 8
@@ -142,6 +153,9 @@
 		if x != i+1 {
 			panic("stack is corrupted")
 		}
+		if progress != nil {
+			atomic.StoreUint32(progress, uint32(i))
+		}
 	}
 	GC()
 }
@@ -231,7 +245,7 @@
 		}
 	}()
 	defer set(&y, 42)
-	growStack()
+	growStack(nil)
 }
 
 type bigBuf [4 * 1024]byte
@@ -627,3 +641,169 @@
 	}
 	return 1 + count1(n-1)
 }
+
+type structWithMethod struct{}
+
+func (s structWithMethod) caller() string {
+	_, file, line, ok := Caller(1)
+	if !ok {
+		panic("Caller failed")
+	}
+	return fmt.Sprintf("%s:%d", file, line)
+}
+
+func (s structWithMethod) callers() []uintptr {
+	pc := make([]uintptr, 16)
+	return pc[:Callers(0, pc)]
+}
+
+func (s structWithMethod) stack() string {
+	buf := make([]byte, 4<<10)
+	return string(buf[:Stack(buf, false)])
+}
+
+func (s structWithMethod) nop() {}
+
+func TestStackWrapperCaller(t *testing.T) {
+	var d structWithMethod
+	// Force the compiler to construct a wrapper method.
+	wrapper := (*structWithMethod).caller
+	// Check that the wrapper doesn't affect the stack trace.
+	if dc, ic := d.caller(), wrapper(&d); dc != ic {
+		t.Fatalf("direct caller %q != indirect caller %q", dc, ic)
+	}
+}
+
+func TestStackWrapperCallers(t *testing.T) {
+	var d structWithMethod
+	wrapper := (*structWithMethod).callers
+	// Check that <autogenerated> doesn't appear in the stack trace.
+	pcs := wrapper(&d)
+	frames := CallersFrames(pcs)
+	for {
+		fr, more := frames.Next()
+		if fr.File == "<autogenerated>" {
+			t.Fatalf("<autogenerated> appears in stack trace: %+v", fr)
+		}
+		if !more {
+			break
+		}
+	}
+}
+
+func TestStackWrapperStack(t *testing.T) {
+	var d structWithMethod
+	wrapper := (*structWithMethod).stack
+	// Check that <autogenerated> doesn't appear in the stack trace.
+	stk := wrapper(&d)
+	if strings.Contains(stk, "<autogenerated>") {
+		t.Fatalf("<autogenerated> appears in stack trace:\n%s", stk)
+	}
+}
+
+type I interface {
+	M()
+}
+
+func TestStackWrapperStackPanic(t *testing.T) {
+	t.Run("sigpanic", func(t *testing.T) {
+		// nil calls to interface methods cause a sigpanic.
+		testStackWrapperPanic(t, func() { I.M(nil) }, "runtime_test.I.M")
+	})
+	t.Run("panicwrap", func(t *testing.T) {
+		// Nil calls to value method wrappers call panicwrap.
+		wrapper := (*structWithMethod).nop
+		testStackWrapperPanic(t, func() { wrapper(nil) }, "runtime_test.(*structWithMethod).nop")
+	})
+}
+
+func testStackWrapperPanic(t *testing.T, cb func(), expect string) {
+	// Test that the stack trace from a panicking wrapper includes
+	// the wrapper, even though elide these when they don't panic.
+	t.Run("CallersFrames", func(t *testing.T) {
+		defer func() {
+			err := recover()
+			if err == nil {
+				t.Fatalf("expected panic")
+			}
+			pcs := make([]uintptr, 10)
+			n := Callers(0, pcs)
+			frames := CallersFrames(pcs[:n])
+			for {
+				frame, more := frames.Next()
+				t.Log(frame.Function)
+				if frame.Function == expect {
+					return
+				}
+				if !more {
+					break
+				}
+			}
+			t.Fatalf("panicking wrapper %s missing from stack trace", expect)
+		}()
+		cb()
+	})
+	t.Run("Stack", func(t *testing.T) {
+		defer func() {
+			err := recover()
+			if err == nil {
+				t.Fatalf("expected panic")
+			}
+			buf := make([]byte, 4<<10)
+			stk := string(buf[:Stack(buf, false)])
+			if !strings.Contains(stk, "\n"+expect) {
+				t.Fatalf("panicking wrapper %s missing from stack trace:\n%s", expect, stk)
+			}
+		}()
+		cb()
+	})
+}
+
+func TestCallersFromWrapper(t *testing.T) {
+	// Test that invoking CallersFrames on a stack where the first
+	// PC is an autogenerated wrapper keeps the wrapper in the
+	// trace. Normally we elide these, assuming that the wrapper
+	// calls the thing you actually wanted to see, but in this
+	// case we need to keep it.
+	pc := reflect.ValueOf(I.M).Pointer()
+	frames := CallersFrames([]uintptr{pc})
+	frame, more := frames.Next()
+	if frame.Function != "runtime_test.I.M" {
+		t.Fatalf("want function %s, got %s", "runtime_test.I.M", frame.Function)
+	}
+	if more {
+		t.Fatalf("want 1 frame, got > 1")
+	}
+}
+
+func TestTracebackSystemstack(t *testing.T) {
+	if GOARCH == "ppc64" || GOARCH == "ppc64le" {
+		t.Skip("systemstack tail call not implemented on ppc64x")
+	}
+
+	// Test that profiles correctly jump over systemstack,
+	// including nested systemstack calls.
+	pcs := make([]uintptr, 20)
+	pcs = pcs[:TracebackSystemstack(pcs, 5)]
+	// Check that runtime.TracebackSystemstack appears five times
+	// and that we see TestTracebackSystemstack.
+	countIn, countOut := 0, 0
+	frames := CallersFrames(pcs)
+	var tb bytes.Buffer
+	for {
+		frame, more := frames.Next()
+		fmt.Fprintf(&tb, "\n%s+0x%x %s:%d", frame.Function, frame.PC-frame.Entry, frame.File, frame.Line)
+		switch frame.Function {
+		case "runtime.TracebackSystemstack":
+			countIn++
+		case "runtime_test.TestTracebackSystemstack":
+			countOut++
+		}
+		if !more {
+			break
+		}
+	}
+	if countIn != 5 || countOut != 1 {
+		t.Fatalf("expected 5 calls to TracebackSystemstack and 1 call to TestTracebackSystemstack, got:%s", tb.String())
+	}
+}
diff --git a/src/runtime/string.go b/src/runtime/string.go
index 0ccc81e..22be091 100644
--- a/src/runtime/string.go
+++ b/src/runtime/string.go
@@ -80,7 +80,7 @@
 	if raceenabled {
 		racereadrangepc(unsafe.Pointer(&b[0]),
 			uintptr(l),
-			getcallerpc(unsafe.Pointer(&buf)),
+			getcallerpc(),
 			funcPC(slicebytetostring))
 	}
 	if msanenabled {
@@ -134,7 +134,7 @@
 	if raceenabled && len(b) > 0 {
 		racereadrangepc(unsafe.Pointer(&b[0]),
 			uintptr(len(b)),
-			getcallerpc(unsafe.Pointer(&b)),
+			getcallerpc(),
 			funcPC(slicebytetostringtmp))
 	}
 	if msanenabled && len(b) > 0 {
@@ -183,7 +183,7 @@
 	if raceenabled && len(a) > 0 {
 		racereadrangepc(unsafe.Pointer(&a[0]),
 			uintptr(len(a))*unsafe.Sizeof(a[0]),
-			getcallerpc(unsafe.Pointer(&buf)),
+			getcallerpc(),
 			funcPC(slicerunetostring))
 	}
 	if msanenabled && len(a) > 0 {
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index c4f32a8..e830641 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -4,10 +4,7 @@
 
 package runtime
 
-import (
-	"runtime/internal/sys"
-	"unsafe"
-)
+import "unsafe"
 
 // Should be a built-in for unsafe.Pointer?
 //go:nosplit
@@ -91,16 +88,21 @@
 }
 
 // exported value for testing
-var hashLoad = loadFactor
+var hashLoad = float32(loadFactorNum) / float32(loadFactorDen)
 
 //go:nosplit
 func fastrand() uint32 {
 	mp := getg().m
-	fr := mp.fastrand
-	mx := uint32(int32(fr)>>31) & 0xa8888eef
-	fr = fr<<1 ^ mx
-	mp.fastrand = fr
-	return fr
+	// Implement xorshift64+: 2 32-bit xorshift sequences added together.
+	// Shift triplet [17,7,16] was calculated as indicated in Marsaglia's
+	// Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
+	// This generator passes the SmallCrush suite, part of TestU01 framework:
+	// http://simul.iro.umontreal.ca/testu01/tu01.html
+	s1, s0 := mp.fastrand[0], mp.fastrand[1]
+	s1 ^= s1 << 17
+	s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
+	mp.fastrand[0], mp.fastrand[1] = s0, s1
+	return s0 + s1
 }
 
 //go:nosplit
@@ -131,11 +133,9 @@
 func cgocallback(fn, frame unsafe.Pointer, framesize, ctxt uintptr)
 func gogo(buf *gobuf)
 func gosave(buf *gobuf)
-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 breakpoint()
@@ -194,14 +194,16 @@
 
 // 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.
+// argp must be a pointer to the caller's first function argument.
 // The implementation may or may not use argp, depending on
-// the architecture.
+// the architecture. The implementation may be a compiler
+// intrinsic; there is not necessarily code implementing this
+// on every platform.
 //
 // For example:
 //
 //	func f(arg1, arg2, arg3 int) {
-//		pc := getcallerpc(unsafe.Pointer(&arg1))
+//		pc := getcallerpc()
 //		sp := getcallersp(unsafe.Pointer(&arg1))
 //	}
 //
@@ -221,12 +223,26 @@
 // immediately and can only be passed to nosplit functions.
 
 //go:noescape
-func getcallerpc(argp unsafe.Pointer) uintptr
+func getcallerpc() uintptr
 
-//go:nosplit
-func getcallersp(argp unsafe.Pointer) uintptr {
-	return uintptr(argp) - sys.MinFrameSize
-}
+//go:noescape
+func getcallersp(argp unsafe.Pointer) uintptr // implemented as an intrinsic on all platforms
+
+// getclosureptr returns the pointer to the current closure.
+// getclosureptr can only be used in an assignment statement
+// at the entry of a function. Moreover, go:nosplit directive
+// must be specified at the declaration of caller function,
+// so that the function prolog does not clobber the closure register.
+// for example:
+//
+//	//go:nosplit
+//	func f(arg1, arg2, arg3 int) {
+//		dx := getclosureptr()
+//	}
+//
+// The compiler rewrites calls to this function into instructions that fetch the
+// pointer from a well-known register (DX on x86 architecture, etc.) directly.
+func getclosureptr() uintptr
 
 //go:noescape
 func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -276,11 +292,6 @@
 
 func systemstack_switch()
 
-func prefetcht0(addr uintptr)
-func prefetcht1(addr uintptr)
-func prefetcht2(addr uintptr)
-func prefetchnta(addr uintptr)
-
 // 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)
@@ -290,7 +301,6 @@
 func checkASM() bool
 
 func memequal_varlen(a, b unsafe.Pointer) bool
-func eqstring(s1, s2 string) bool
 
 // bool2int returns 0 if x is false or 1 if x is true.
 func bool2int(x bool) int {
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
index 8390d8f..ae5ccd3 100644
--- a/src/runtime/stubs2.go
+++ b/src/runtime/stubs2.go
@@ -25,3 +25,9 @@
 func open(name *byte, mode, perm int32) int32
 
 func madvise(addr unsafe.Pointer, n uintptr, flags int32)
+
+// exitThread terminates the current thread, writing *wait = 0 when
+// the stack is safe to reclaim.
+//
+//go:noescape
+func exitThread(wait *uint32)
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index e1b41ca..bdf98b9 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -19,6 +19,11 @@
 	// stackExpander expands callers into a sequence of Frames,
 	// tracking the necessary state across PCs.
 	stackExpander stackExpander
+
+	// elideWrapper indicates that, if the next frame is an
+	// autogenerated wrapper function, it should be elided from
+	// the stack.
+	elideWrapper bool
 }
 
 // Frame is the information returned by Frames for each call frame.
@@ -112,12 +117,14 @@
 // Next returns frame information for the next caller.
 // If more is false, there are no more callers (the Frame value is valid).
 func (ci *Frames) Next() (frame Frame, more bool) {
-	ci.callers, frame, more = ci.stackExpander.next(ci.callers)
+	ci.callers, frame, more = ci.stackExpander.next(ci.callers, ci.elideWrapper)
+	ci.elideWrapper = elideWrapperCalling(frame.Function)
 	return
 }
 
-func (se *stackExpander) next(callers []uintptr) (ncallers []uintptr, frame Frame, more bool) {
+func (se *stackExpander) next(callers []uintptr, elideWrapper bool) (ncallers []uintptr, frame Frame, more bool) {
 	ncallers = callers
+again:
 	if !se.pcExpander.more {
 		// Expand the next PC.
 		if len(ncallers) == 0 {
@@ -144,6 +151,13 @@
 	}
 
 	frame = se.pcExpander.next()
+	if elideWrapper && frame.File == "<autogenerated>" {
+		// Ignore autogenerated functions such as pointer
+		// method forwarding functions. These are an
+		// implementation detail that doesn't reflect the
+		// source code.
+		goto again
+	}
 	return ncallers, frame, se.pcExpander.more || len(ncallers) > 0
 }
 
@@ -338,8 +352,8 @@
 // moduledata records information about the layout of the executable
 // image. It is written by the linker. Any changes here must be
 // matched changes to the code in cmd/internal/ld/symtab.go:symtab.
-// moduledata is stored in read-only memory; none of the pointers here
-// are visible to the garbage collector.
+// moduledata is stored in statically allocated non-pointer memory;
+// none of the pointers here are visible to the garbage collector.
 type moduledata struct {
 	pclntable    []byte
 	ftab         []functab
@@ -367,10 +381,14 @@
 	modulename   string
 	modulehashes []modulehash
 
+	hasmain uint8 // 1 if module contains the main function, 0 otherwise
+
 	gcdatamask, gcbssmask bitvector
 
 	typemap map[typeOff]*_type // offset to *_rtype in previous module
 
+	bad bool // module failed to load and should be ignored
+
 	next *moduledata
 }
 
@@ -403,7 +421,7 @@
 
 var firstmoduledata moduledata  // linker symbol
 var lastmoduledatap *moduledata // linker symbol
-var modulesSlice unsafe.Pointer // see activeModules
+var modulesSlice *[]*moduledata // see activeModules
 
 // activeModules returns a slice of active modules.
 //
@@ -443,6 +461,9 @@
 func modulesinit() {
 	modules := new([]*moduledata)
 	for md := &firstmoduledata; md != nil; md = md.next {
+		if md.bad {
+			continue
+		}
 		*modules = append(*modules, md)
 		if md.gcdatamask == (bitvector{}) {
 			md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), md.edata-md.data)
@@ -459,9 +480,8 @@
 	// contains the main function.
 	//
 	// See Issue #18729.
-	mainText := funcPC(main_main)
 	for i, md := range *modules {
-		if md.text <= mainText && mainText <= md.etext {
+		if md.hasmain != 0 {
 			(*modules)[0] = md
 			(*modules)[i] = &firstmoduledata
 			break
@@ -521,7 +541,6 @@
 
 	// ftab is lookup table for function by program counter.
 	nftab := len(datap.ftab) - 1
-	var pcCache pcvalueCache
 	for i := 0; i < nftab; i++ {
 		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
 		if datap.ftab[i].entry > datap.ftab[i+1].entry {
@@ -537,30 +556,6 @@
 			}
 			throw("invalid runtime symbol table")
 		}
-
-		if debugPcln || nftab-i < 5 {
-			// Check a PC near but not at the very end.
-			// The very end might be just padding that is not covered by the tables.
-			// No architecture rounds function entries to more than 16 bytes,
-			// but if one came along we'd need to subtract more here.
-			// But don't use the next PC if it corresponds to a foreign object chunk
-			// (no pcln table, f2.pcln == 0). That chunk might have an alignment
-			// more than 16 bytes.
-			f := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
-			end := f.entry
-			if i+1 < nftab {
-				f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
-				if f2.pcln != 0 {
-					end = f2.entry - 16
-					if end < f.entry {
-						end = f.entry
-					}
-				}
-			}
-			pcvalue(f, f.pcfile, end, &pcCache, true)
-			pcvalue(f, f.pcln, end, &pcCache, true)
-			pcvalue(f, f.pcsp, end, &pcCache, true)
-		}
 	}
 
 	if datap.minpc != datap.ftab[0].entry ||
diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s
index 5c62bfd..ccd901a 100644
--- a/src/runtime/sys_darwin_386.s
+++ b/src/runtime/sys_darwin_386.s
@@ -19,13 +19,39 @@
 
 // Exit this OS thread (like pthread_exit, which eventually
 // calls __bsdthread_terminate).
-TEXT runtime·exit1(SB),NOSPLIT,$0
+TEXT exit1<>(SB),NOSPLIT,$16-0
+	// __bsdthread_terminate takes 4 word-size arguments.
+	// Set them all to 0. (None are an exit status.)
+	MOVL	$0, 0(SP)
+	MOVL	$0, 4(SP)
+	MOVL	$0, 8(SP)
+	MOVL	$0, 12(SP)
 	MOVL	$361, AX
 	INT	$0x80
 	JAE 2(PC)
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
+GLOBL exitStack<>(SB),RODATA,$(4*4)
+DATA exitStack<>+0x00(SB)/4, $0
+DATA exitStack<>+0x04(SB)/4, $0
+DATA exitStack<>+0x08(SB)/4, $0
+DATA exitStack<>+0x0c(SB)/4, $0
+
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	// __bsdthread_terminate takes 4 arguments, which it expects
+	// on the stack. They should all be 0, so switch over to a
+	// fake stack of 0s. It won't write to the stack.
+	MOVL	$exitStack<>(SB), SP
+	MOVL	$361, AX	// __bsdthread_terminate
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	JMP	0(PC)
+
 TEXT runtime·open(SB),NOSPLIT,$0
 	MOVL	$5, AX
 	INT	$0x80
@@ -77,7 +103,13 @@
 TEXT runtime·mmap(SB),NOSPLIT,$0
 	MOVL	$197, AX
 	INT	$0x80
-	MOVL	AX, ret+24(FP)
+	JAE	ok
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·madvise(SB),NOSPLIT,$0
@@ -394,7 +426,7 @@
 	MOVL	BX, m_procid(DX)	// m->procid = thread port (for debuggers)
 	CALL	runtime·stackcheck(SB)		// smashes AX
 	CALL	CX	// fn()
-	CALL	runtime·exit1(SB)
+	CALL	exit1<>(SB)
 	RET
 
 // func bsdthread_register() int32
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index a8dc700..ab57843 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -25,13 +25,26 @@
 
 // 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
+TEXT exit1<>(SB),NOSPLIT,$0
+	// Because of exitThread below, this must not use the stack.
+	// __bsdthread_terminate takes 4 word-size arguments.
+	// Set them all to 0. (None are an exit status.)
+	MOVL	$0, DI
+	MOVL	$0, SI
+	MOVL	$0, DX
+	MOVL	$0, R10
 	MOVL	$(0x2000000+361), AX	// syscall entry
 	SYSCALL
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	JMP	exit1<>(SB)
+
 TEXT runtime·open(SB),NOSPLIT,$0
 	MOVQ	name+0(FP), DI		// arg 1 pathname
 	MOVL	mode+8(FP), SI		// arg 2 flags
@@ -107,15 +120,22 @@
 	RET
 
 // OS X comm page time offsets
-// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
+// https://opensource.apple.com/source/xnu/xnu-4570.1.46/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
+#define	gtod_generation	0x6c  // obsolete since Darwin v17 (High Sierra)
+#define	gtod_ns_base	0x70  // obsolete since Darwin v17 (High Sierra)
+#define	gtod_sec_base	0x78  // obsolete since Darwin v17 (High Sierra)
+
+#define	v17_gtod_ns_base	0xd0
+#define	v17_gtod_sec_ofs	0xd8
+#define	v17_gtod_frac_ofs	0xe0
+#define	v17_gtod_scale		0xe8
+#define	v17_gtod_tkspersec	0xf0
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
 	MOVQ	$0x7fffffe00000, BP	/* comm page base */
@@ -151,6 +171,75 @@
 	// are used in the systime fallback, as the timeval address
 	// filled in by the system call.
 	MOVQ	$0x7fffffe00000, BP	/* comm page base */
+	CMPQ	runtime·darwinVersion(SB), $17
+	JB		legacy /* sierra and older */
+
+	// This is the new code, for macOS High Sierra (Darwin v17) and newer.
+v17:
+	// Loop trying to take a consistent snapshot
+	// of the time parameters.
+timeloop17:
+	MOVQ 	v17_gtod_ns_base(BP), R12
+
+	MOVL	nt_generation(BP), CX
+	TESTL	CX, CX
+	JZ		timeloop17
+	RDTSC
+	MOVQ	nt_tsc_base(BP), SI
+	MOVL	nt_scale(BP), DI
+	MOVQ	nt_ns_base(BP), BX
+	CMPL	nt_generation(BP), CX
+	JNE		timeloop17
+
+	MOVQ 	v17_gtod_sec_ofs(BP), R8
+	MOVQ 	v17_gtod_frac_ofs(BP), R9
+	MOVQ 	v17_gtod_scale(BP), R10
+	MOVQ 	v17_gtod_tkspersec(BP), R11
+	CMPQ 	v17_gtod_ns_base(BP), R12
+	JNE 	timeloop17
+
+	// Compute monotonic time
+	//	mono = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
+	// The multiply and shift extracts the top 64 bits of the 96-bit product.
+	SHLQ	$32, DX
+	ADDQ	DX, AX
+	SUBQ	SI, AX
+	MULQ	DI
+	SHRQ	$32, AX:DX
+	ADDQ	BX, AX
+
+	// Subtract startNano base to return the monotonic runtime timer
+	// which is an offset from process boot.
+	MOVQ	AX, BX
+	MOVQ	runtime·startNano(SB), CX
+	SUBQ	CX, BX
+	MOVQ	BX, monotonic+16(FP)
+
+	// Now compute the 128-bit wall time:
+	//  wall = ((mono - gtod_ns_base) * gtod_scale) + gtod_offs
+	// The parameters are updated every second, so if we found them
+	// outdated (that is, more than one second is passed from the ns base),
+	// fallback to the syscall.
+	TESTQ	R12, R12
+	JZ		systime
+	SUBQ	R12, AX
+	CMPQ	R11, AX
+	JB		systime
+	MULQ 	R10
+	ADDQ	R9, AX
+	ADCQ	R8, DX
+
+	// Convert the 128-bit wall time into (sec,nsec).
+	// High part (seconds) is already good to go, while low part
+	// (fraction of seconds) must be converted to nanoseconds.
+	MOVQ	DX, sec+0(FP)
+	MOVQ 	$1000000000, CX
+	MULQ	CX
+	MOVQ	DX, nsec+8(FP)
+	RET
+
+	// This is the legacy code needed for macOS Sierra (Darwin v16) and older.
+legacy:
 	// Loop trying to take a consistent snapshot
 	// of the time parameters.
 timeloop:
@@ -283,7 +372,13 @@
 	MOVL	off+28(FP), R9		// arg 6 offset
 	MOVL	$(0x2000000+197), AX	// syscall entry
 	SYSCALL
-	MOVQ	AX, ret+32(FP)
+	JCC	ok
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
@@ -375,7 +470,7 @@
 	MOVQ	CX, g_m(AX)
 	CALL	runtime·stackcheck(SB)	// smashes AX, CX
 	CALL	DX	// fn
-	CALL	runtime·exit1(SB)
+	CALL	exit1<>(SB)
 	RET
 
 // func bsdthread_register() int32
diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s
index ea559b5..1ad904f 100644
--- a/src/runtime/sys_darwin_arm.s
+++ b/src/runtime/sys_darwin_arm.s
@@ -19,7 +19,6 @@
 #define	SYS_mmap           197
 #define	SYS_munmap         73
 #define	SYS_madvise        75
-#define	SYS_mincore        78
 #define	SYS_gettimeofday   116
 #define	SYS_kill           37
 #define	SYS_getpid         20
@@ -90,13 +89,32 @@
 
 // Exit this OS thread (like pthread_exit, which eventually
 // calls __bsdthread_terminate).
-TEXT runtime·exit1(SB),NOSPLIT,$0
+TEXT exit1<>(SB),NOSPLIT,$0
+	// Because of exitThread below, this must not use the stack.
+	// __bsdthread_terminate takes 4 word-size arguments.
+	// Set them all to 0. (None are an exit status.)
+	MOVW	$0, R0
+	MOVW	$0, R1
+	MOVW	$0, R2
+	MOVW	$0, R3
 	MOVW	$SYS_bsdthread_terminate, R12
 	SWI	$0x80
 	MOVW	$1234, R0
 	MOVW	$1003, R1
 	MOVW	R0, (R1)	// fail hard
 
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVW	wait+0(FP), R0
+	// We're done using the stack.
+	MOVW	$0, R2
+storeloop:
+	LDREX	(R0), R4          // loads R4
+	STREX	R2, (R0), R1      // stores R2
+	CMP	$0, R1
+	BNE	storeloop
+	JMP	exit1<>(SB)
+
 TEXT runtime·raise(SB),NOSPLIT,$0
 	// Ideally we'd send the signal to the current thread,
 	// not the whole process, but that's too hard on OS X.
@@ -122,7 +140,14 @@
 	MOVW	$0, R6 // off_t is uint64_t
 	MOVW	$SYS_mmap, R12
 	SWI	$0x80
-	MOVW	R0, ret+24(FP)
+	MOVW	$0, R1
+	BCC     ok
+	MOVW	R1, p+24(FP)
+	MOVW	R0, err+28(FP)
+	RET
+ok:
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
@@ -150,15 +175,6 @@
 	SWI	$0x80
 	RET
 
-TEXT runtime·mincore(SB),NOSPLIT,$0
-	MOVW	addr+0(FP), R0
-	MOVW	n+4(FP), R1
-	MOVW	dst+8(FP), R2
-	MOVW	$SYS_mincore, R12
-	SWI	$0x80
-	MOVW	R0, ret+12(FP)
-	RET
-
 TEXT runtime·walltime(SB), 7, $32
 	MOVW	$8(R13), R0  // timeval
 	MOVW	$0, R1  // zone
@@ -380,7 +396,7 @@
 	EOR     R12, R12
 	WORD    $0xeee1ca10 // fmxr	fpscr, ip
 	BL      (R2) // fn
-	BL      runtime·exit1(SB)
+	BL      exit1<>(SB)
 	RET
 
 // int32 bsdthread_register(void)
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index 0e91d5b..5663af5 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -19,7 +19,6 @@
 #define	SYS_mmap           197
 #define	SYS_munmap         73
 #define	SYS_madvise        75
-#define	SYS_mincore        78
 #define	SYS_gettimeofday   116
 #define	SYS_kill           37
 #define	SYS_getpid         20
@@ -90,13 +89,28 @@
 
 // Exit this OS thread (like pthread_exit, which eventually
 // calls __bsdthread_terminate).
-TEXT runtime·exit1(SB),NOSPLIT,$0
+TEXT exit1<>(SB),NOSPLIT,$0
+	// Because of exitThread below, this must not use the stack.
+	// __bsdthread_terminate takes 4 word-size arguments.
+	// Set them all to 0. (None are an exit status.)
+	MOVW	$0, R0
+	MOVW	$0, R1
+	MOVW	$0, R2
+	MOVW	$0, R3
 	MOVW	$SYS_bsdthread_terminate, R16
 	SVC	$0x80
 	MOVD	$1234, R0
 	MOVD	$1003, R1
 	MOVD	R0, (R1)	// fail hard
 
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVD	wait+0(FP), R0
+	// We're done using the stack.
+	MOVW	$0, R1
+	STLRW	R1, (R0)
+	JMP	exit1<>(SB)
+
 TEXT runtime·raise(SB),NOSPLIT,$0
 	// Ideally we'd send the signal to the current thread,
 	// not the whole process, but that's too hard on OS X.
@@ -121,7 +135,13 @@
 	MOVW	off+28(FP), R5
 	MOVW	$SYS_mmap, R16
 	SVC	$0x80
-	MOVD	R0, ret+32(FP)
+	BCC	ok
+	MOVD	$0, p+32(FP)
+	MOVD	R0, err+40(FP)
+	RET
+ok:
+	MOVD	R0, p+32(FP)
+	MOVD	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_dragonfly_amd64.s b/src/runtime/sys_dragonfly_amd64.s
index f355268..813f1f4 100644
--- a/src/runtime/sys_dragonfly_amd64.s
+++ b/src/runtime/sys_dragonfly_amd64.s
@@ -64,12 +64,18 @@
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVL	code+0(FP), DI		// arg 1 exit status
-	MOVL	$431, AX
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	MOVL	$0x10000, DI	// arg 1 how - EXTEXIT_LWP
+	MOVL	$0, SI		// arg 2 status
+	MOVL	$0, DX		// arg 3 addr
+	MOVL	$494, AX	// extexit
 	SYSCALL
 	MOVL	$0xf1, 0xf1  // crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVQ	name+0(FP), DI		// arg 1 pathname
@@ -236,8 +242,15 @@
 	MOVQ	$0, R9			// arg 6 - pad
 	MOVL	$197, AX
 	SYSCALL
+	JCC	ok
 	ADDQ	$16, SP
-	MOVQ	AX, ret+32(FP)
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	ADDQ	$16, SP
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_freebsd_386.s b/src/runtime/sys_freebsd_386.s
index 0f5df21..bef8e32 100644
--- a/src/runtime/sys_freebsd_386.s
+++ b/src/runtime/sys_freebsd_386.s
@@ -52,12 +52,23 @@
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-4
-	MOVL	$431, AX
+GLOBL exitStack<>(SB),RODATA,$8
+DATA exitStack<>+0x00(SB)/4, $0
+DATA exitStack<>+0x04(SB)/4, $0
+
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	// thr_exit takes a single pointer argument, which it expects
+	// on the stack. We want to pass 0, so switch over to a fake
+	// stack of 0s. It won't write to the stack.
+	MOVL	$exitStack<>(SB), SP
+	MOVL	$431, AX	// thr_exit
 	INT	$0x80
-	JAE	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-4
 	MOVL	$5, AX
@@ -138,7 +149,13 @@
 	STOSL
 	MOVL	$477, AX
 	INT	$0x80
-	MOVL	AX, ret+24(FP)
+	JAE	ok
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-4
diff --git a/src/runtime/sys_freebsd_amd64.s b/src/runtime/sys_freebsd_amd64.s
index 5d072a9..7499931 100644
--- a/src/runtime/sys_freebsd_amd64.s
+++ b/src/runtime/sys_freebsd_amd64.s
@@ -54,12 +54,16 @@
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVL	code+0(FP), DI		// arg 1 exit status
-	MOVL	$431, AX
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	MOVL	$0, DI		// arg 1 long *state
+	MOVL	$431, AX	// thr_exit
 	SYSCALL
 	MOVL	$0xf1, 0xf1  // crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVQ	name+0(FP), DI		// arg 1 pathname
@@ -229,7 +233,13 @@
 	MOVL	off+28(FP), R9		// arg 6 offset
 	MOVL	$477, AX
 	SYSCALL
-	MOVQ	AX, ret+32(FP)
+	JCC	ok
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_freebsd_arm.s b/src/runtime/sys_freebsd_arm.s
index 2851587..3f52864 100644
--- a/src/runtime/sys_freebsd_arm.s
+++ b/src/runtime/sys_freebsd_arm.s
@@ -82,13 +82,22 @@
 	MOVW.CS R8, (R8)
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVW code+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
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVW	wait+0(FP), R0
+	// We're done using the stack.
+	MOVW	$0, R2
+storeloop:
+	LDREX	(R0), R4          // loads R4
+	STREX	R2, (R0), R1      // stores R2
+	CMP	$0, R1
+	BNE	storeloop
+	MOVW	$0, R0		// arg 1 long *state
+	MOVW	$SYS_thr_exit, R7
+	SWI	$0
+	MOVW.CS	$0, R8 // crash on syscall failure
+	MOVW.CS	R8, (R8)
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVW name+0(FP), R0	// arg 1 name
@@ -249,8 +258,11 @@
 	MOVW $SYS_mmap, R7
 	SWI $0
 	SUB $4, R13
-	// TODO(dfc) error checking ?
-	MOVW	R0, ret+24(FP)
+	MOVW $0, R1
+	MOVW.CS R0, R1		// if failed, put in R1
+	MOVW.CS $0, R0
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index a3baeba..bc3b8db 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -24,22 +24,70 @@
 //#define INVOKE_SYSCALL	CALL	0x10(GS) // non-portable
 #define INVOKE_SYSCALL	INT	$0x80
 
+#define SYS_exit		1
+#define SYS_read		3
+#define SYS_write		4
+#define SYS_open		5
+#define SYS_close		6
+#define SYS_getpid		20
+#define SYS_access		33
+#define SYS_kill		37
+#define SYS_brk 		45
+#define SYS_fcntl		55
+#define SYS_munmap		91
+#define SYS_socketcall		102
+#define SYS_setittimer		104
+#define SYS_clone		120
+#define SYS_sched_yield 	158
+#define SYS_rt_sigreturn	173
+#define SYS_rt_sigaction	174
+#define SYS_rt_sigprocmask	175
+#define SYS_sigaltstack 	186
+#define SYS_ugetrlimit		191
+#define SYS_mmap2		192
+#define SYS_mincore		218
+#define SYS_madvise		219
+#define SYS_gettid		224
+#define SYS_tkill		238
+#define SYS_futex		240
+#define SYS_sched_getaffinity	242
+#define SYS_set_thread_area	243
+#define SYS_exit_group		252
+#define SYS_epoll_create	254
+#define SYS_epoll_ctl		255
+#define SYS_epoll_wait		256
+#define SYS_clock_gettime	265
+#define SYS_pselect6		308
+#define SYS_epoll_create1	329
+
 TEXT runtime·exit(SB),NOSPLIT,$0
-	MOVL	$252, AX	// syscall number
+	MOVL	$SYS_exit_group, AX
 	MOVL	code+0(FP), BX
 	INVOKE_SYSCALL
 	INT $3	// not reached
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL	$1, AX	// exit - exit the current os thread
+TEXT exit1<>(SB),NOSPLIT,$0
+	MOVL	$SYS_exit, AX
 	MOVL	code+0(FP), BX
 	INVOKE_SYSCALL
 	INT $3	// not reached
 	RET
 
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	MOVL	$1, AX	// exit (just this thread)
+	MOVL	$0, BX	// exit code
+	INT	$0x80	// no stack; must not use CALL
+	// We may not even have a stack any more.
+	INT	$3
+	JMP	0(PC)
+
 TEXT runtime·open(SB),NOSPLIT,$0
-	MOVL	$5, AX		// syscall - open
+	MOVL	$SYS_open, AX
 	MOVL	name+0(FP), BX
 	MOVL	mode+4(FP), CX
 	MOVL	perm+8(FP), DX
@@ -51,7 +99,7 @@
 	RET
 
 TEXT runtime·closefd(SB),NOSPLIT,$0
-	MOVL	$6, AX		// syscall - close
+	MOVL	$SYS_close, AX
 	MOVL	fd+0(FP), BX
 	INVOKE_SYSCALL
 	CMPL	AX, $0xfffff001
@@ -61,7 +109,7 @@
 	RET
 
 TEXT runtime·write(SB),NOSPLIT,$0
-	MOVL	$4, AX		// syscall - write
+	MOVL	$SYS_write, AX
 	MOVL	fd+0(FP), BX
 	MOVL	p+4(FP), CX
 	MOVL	n+8(FP), DX
@@ -73,7 +121,7 @@
 	RET
 
 TEXT runtime·read(SB),NOSPLIT,$0
-	MOVL	$3, AX		// syscall - read
+	MOVL	$SYS_read, AX
 	MOVL	fd+0(FP), BX
 	MOVL	p+4(FP), CX
 	MOVL	n+8(FP), DX
@@ -85,7 +133,7 @@
 	RET
 
 TEXT runtime·getrlimit(SB),NOSPLIT,$0
-	MOVL	$191, AX		// syscall - ugetrlimit
+	MOVL	$SYS_ugetrlimit, AX
 	MOVL	kind+0(FP), BX
 	MOVL	limit+4(FP), CX
 	INVOKE_SYSCALL
@@ -103,7 +151,7 @@
 	MOVL	AX, 4(SP)
 
 	// pselect6(0, 0, 0, 0, &ts, 0)
-	MOVL	$308, AX
+	MOVL	$SYS_pselect6, AX
 	MOVL	$0, BX
 	MOVL	$0, CX
 	MOVL	$0, DX
@@ -114,31 +162,31 @@
 	RET
 
 TEXT runtime·gettid(SB),NOSPLIT,$0-4
-	MOVL	$224, AX	// syscall - gettid
+	MOVL	$SYS_gettid, AX
 	INVOKE_SYSCALL
 	MOVL	AX, ret+0(FP)
 	RET
 
 TEXT runtime·raise(SB),NOSPLIT,$12
-	MOVL	$224, AX	// syscall - gettid
+	MOVL	$SYS_gettid, AX
 	INVOKE_SYSCALL
 	MOVL	AX, BX	// arg 1 tid
 	MOVL	sig+0(FP), CX	// arg 2 signal
-	MOVL	$238, AX	// syscall - tkill
+	MOVL	$SYS_tkill, AX
 	INVOKE_SYSCALL
 	RET
 
 TEXT runtime·raiseproc(SB),NOSPLIT,$12
-	MOVL	$20, AX	// syscall - getpid
+	MOVL	$SYS_getpid, AX
 	INVOKE_SYSCALL
 	MOVL	AX, BX	// arg 1 pid
 	MOVL	sig+0(FP), CX	// arg 2 signal
-	MOVL	$37, AX	// syscall - kill
+	MOVL	$SYS_kill, AX
 	INVOKE_SYSCALL
 	RET
 
 TEXT runtime·setitimer(SB),NOSPLIT,$0-12
-	MOVL	$104, AX			// syscall - setitimer
+	MOVL	$SYS_setittimer, AX
 	MOVL	mode+0(FP), BX
 	MOVL	new+4(FP), CX
 	MOVL	old+8(FP), DX
@@ -146,7 +194,7 @@
 	RET
 
 TEXT runtime·mincore(SB),NOSPLIT,$0-16
-	MOVL	$218, AX			// syscall - mincore
+	MOVL	$SYS_mincore, AX
 	MOVL	addr+0(FP), BX
 	MOVL	n+4(FP), CX
 	MOVL	dst+8(FP), DX
@@ -155,15 +203,56 @@
 	RET
 
 // func walltime() (sec int64, nsec int32)
-TEXT runtime·walltime(SB), NOSPLIT, $32
-	MOVL	$265, AX			// syscall - clock_gettime
+TEXT runtime·walltime(SB), NOSPLIT, $0-12
+	// We don't know how much stack space the VDSO code will need,
+	// so switch to g0.
+
+	MOVL	SP, BP	// Save old SP; BP unchanged by C code.
+
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), CX
+	MOVL	m_curg(CX), DX
+
+	CMPL	AX, DX		// Only switch if on curg.
+	JNE	noswitch
+
+	MOVL	m_g0(CX), DX
+	MOVL	(g_sched+gobuf_sp)(DX), SP	// Set SP to g0 stack
+
+noswitch:
+	SUBL	$16, SP		// Space for results
+	ANDL	$~15, SP	// Align for C code
+
+	// Stack layout, depending on call path:
+	//  x(SP)   vDSO            INVOKE_SYSCALL
+	//    12    ts.tv_nsec      ts.tv_nsec
+	//     8    ts.tv_sec       ts.tv_sec
+	//     4    &ts             -
+	//     0    CLOCK_<id>      -
+
+	MOVL	runtime·__vdso_clock_gettime_sym(SB), AX
+	CMPL	AX, $0
+	JEQ	fallback
+
+	LEAL	8(SP), BX	// &ts (struct timespec)
+	MOVL	BX, 4(SP)
+	MOVL	$0, 0(SP)	// CLOCK_REALTIME
+	CALL	AX
+	JMP finish
+
+fallback:
+	MOVL	$SYS_clock_gettime, AX
 	MOVL	$0, BX		// CLOCK_REALTIME
 	LEAL	8(SP), CX
-	MOVL	$0, DX
 	INVOKE_SYSCALL
+
+finish:
 	MOVL	8(SP), AX	// sec
 	MOVL	12(SP), BX	// nsec
 
+	MOVL	BP, SP		// Restore real SP
+
 	// sec is in AX, nsec in BX
 	MOVL	AX, sec_lo+0(FP)
 	MOVL	$0, sec_hi+4(FP)
@@ -172,15 +261,48 @@
 
 // int64 nanotime(void) so really
 // void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$265, AX			// syscall - clock_gettime
+TEXT runtime·nanotime(SB), NOSPLIT, $0-8
+	// Switch to g0 stack. See comment above in runtime·walltime.
+
+	MOVL	SP, BP	// Save old SP; BP unchanged by C code.
+
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), CX
+	MOVL	m_curg(CX), DX
+
+	CMPL	AX, DX		// Only switch if on curg.
+	JNE	noswitch
+
+	MOVL	m_g0(CX), DX
+	MOVL	(g_sched+gobuf_sp)(DX), SP	// Set SP to g0 stack
+
+noswitch:
+	SUBL	$16, SP		// Space for results
+	ANDL	$~15, SP	// Align for C code
+
+	MOVL	runtime·__vdso_clock_gettime_sym(SB), AX
+	CMPL	AX, $0
+	JEQ	fallback
+
+	LEAL	8(SP), BX	// &ts (struct timespec)
+	MOVL	BX, 4(SP)
+	MOVL	$1, 0(SP)	// CLOCK_MONOTONIC
+	CALL	AX
+	JMP finish
+
+fallback:
+	MOVL	$SYS_clock_gettime, AX
 	MOVL	$1, BX		// CLOCK_MONOTONIC
 	LEAL	8(SP), CX
-	MOVL	$0, DX
 	INVOKE_SYSCALL
+
+finish:
 	MOVL	8(SP), AX	// sec
 	MOVL	12(SP), BX	// nsec
 
+	MOVL	BP, SP		// Restore real SP
+
 	// sec is in AX, nsec in BX
 	// convert to DX:AX nsec
 	MOVL	$1000000000, CX
@@ -193,7 +315,7 @@
 	RET
 
 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
-	MOVL	$175, AX		// syscall entry
+	MOVL	$SYS_rt_sigprocmask, AX
 	MOVL	how+0(FP), BX
 	MOVL	new+4(FP), CX
 	MOVL	old+8(FP), DX
@@ -205,7 +327,7 @@
 	RET
 
 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
-	MOVL	$174, AX		// syscall - rt_sigaction
+	MOVL	$SYS_rt_sigaction, AX
 	MOVL	sig+0(FP), BX
 	MOVL	new+4(FP), CX
 	MOVL	old+8(FP), DX
@@ -258,7 +380,7 @@
 	JMP	runtime·sigtramp(SB)
 
 TEXT runtime·sigreturn(SB),NOSPLIT,$0
-	MOVL	$173, AX	// rt_sigreturn
+	MOVL	$SYS_rt_sigreturn, AX
 	// Sigreturn expects same SP as signal handler,
 	// so cannot CALL 0x10(GS) here.
 	INT	$0x80
@@ -266,7 +388,7 @@
 	RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVL	$192, AX	// mmap2
+	MOVL	$SYS_mmap2, AX
 	MOVL	addr+0(FP), BX
 	MOVL	n+4(FP), CX
 	MOVL	prot+8(FP), DX
@@ -276,14 +398,19 @@
 	SHRL	$12, BP
 	INVOKE_SYSCALL
 	CMPL	AX, $0xfffff001
-	JLS	3(PC)
+	JLS	ok
 	NOTL	AX
 	INCL	AX
-	MOVL	AX, ret+24(FP)
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVL	$91, AX	// munmap
+	MOVL	$SYS_munmap, AX
 	MOVL	addr+0(FP), BX
 	MOVL	n+4(FP), CX
 	INVOKE_SYSCALL
@@ -293,7 +420,7 @@
 	RET
 
 TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVL	$219, AX	// madvise
+	MOVL	$SYS_madvise, AX
 	MOVL	addr+0(FP), BX
 	MOVL	n+4(FP), CX
 	MOVL	flags+8(FP), DX
@@ -304,7 +431,7 @@
 // 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	$SYS_futex, AX
 	MOVL	addr+0(FP), BX
 	MOVL	op+4(FP), CX
 	MOVL	val+8(FP), DX
@@ -317,7 +444,7 @@
 
 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
 TEXT runtime·clone(SB),NOSPLIT,$0
-	MOVL	$120, AX	// clone
+	MOVL	$SYS_clone, AX
 	MOVL	flags+0(FP), BX
 	MOVL	stk+4(FP), CX
 	MOVL	$0, DX	// parent tid ptr
@@ -351,7 +478,7 @@
 	INT	$3
 
 	// Initialize AX to Linux tid
-	MOVL	$224, AX
+	MOVL	$SYS_gettid, AX
 	INVOKE_SYSCALL
 
 	MOVL	0(SP), BX	    // m
@@ -396,11 +523,11 @@
 
 nog:
 	CALL	SI	// fn()
-	CALL	runtime·exit1(SB)
+	CALL	exit1<>(SB)
 	MOVL	$0x1234, 0x1005
 
 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVL	$186, AX	// sigaltstack
+	MOVL	$SYS_sigaltstack, AX
 	MOVL	new+0(FP), BX
 	MOVL	old+4(FP), CX
 	INVOKE_SYSCALL
@@ -483,7 +610,7 @@
 
 	// call set_thread_area
 	MOVL	AX, BX	// user_desc
-	MOVL	$243, AX	// syscall - set_thread_area
+	MOVL	$SYS_set_thread_area, AX
 	// We can't call this via 0x10(GS) because this is called from setldt0 to set that up.
 	INT     $0x80
 
@@ -509,12 +636,12 @@
 	RET
 
 TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$158, AX
+	MOVL	$SYS_sched_yield, AX
 	INVOKE_SYSCALL
 	RET
 
 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
-	MOVL	$242, AX		// syscall - sched_getaffinity
+	MOVL	$SYS_sched_getaffinity, AX
 	MOVL	pid+0(FP), BX
 	MOVL	len+4(FP), CX
 	MOVL	buf+8(FP), DX
@@ -524,7 +651,7 @@
 
 // int32 runtime·epollcreate(int32 size);
 TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVL    $254, AX
+	MOVL    $SYS_epoll_create, AX
 	MOVL	size+0(FP), BX
 	INVOKE_SYSCALL
 	MOVL	AX, ret+4(FP)
@@ -532,7 +659,7 @@
 
 // int32 runtime·epollcreate1(int32 flags);
 TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVL    $329, AX
+	MOVL    $SYS_epoll_create1, AX
 	MOVL	flags+0(FP), BX
 	INVOKE_SYSCALL
 	MOVL	AX, ret+4(FP)
@@ -540,7 +667,7 @@
 
 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
 TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVL	$255, AX
+	MOVL	$SYS_epoll_ctl, AX
 	MOVL	epfd+0(FP), BX
 	MOVL	op+4(FP), CX
 	MOVL	fd+8(FP), DX
@@ -551,7 +678,7 @@
 
 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
 TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVL	$256, AX
+	MOVL	$SYS_epoll_wait, AX
 	MOVL	epfd+0(FP), BX
 	MOVL	ev+4(FP), CX
 	MOVL	nev+8(FP), DX
@@ -562,7 +689,7 @@
 
 // void runtime·closeonexec(int32 fd);
 TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	$55, AX  // fcntl
+	MOVL	$SYS_fcntl, AX
 	MOVL	fd+0(FP), BX  // fd
 	MOVL	$2, CX  // F_SETFD
 	MOVL	$1, DX  // FD_CLOEXEC
@@ -571,7 +698,7 @@
 
 // int access(const char *name, int mode)
 TEXT runtime·access(SB),NOSPLIT,$0
-	MOVL	$33, AX  // syscall - access
+	MOVL	$SYS_access, AX
 	MOVL	name+0(FP), BX
 	MOVL	mode+4(FP), CX
 	INVOKE_SYSCALL
@@ -582,7 +709,7 @@
 TEXT runtime·connect(SB),NOSPLIT,$0-16
 	// connect is implemented as socketcall(NR_socket, 3, *(rest of args))
 	// stack already should have fd, addr, addrlen.
-	MOVL	$102, AX  // syscall - socketcall
+	MOVL	$SYS_socketcall, AX
 	MOVL	$3, BX  // connect
 	LEAL	fd+0(FP), CX
 	INVOKE_SYSCALL
@@ -593,7 +720,7 @@
 TEXT runtime·socket(SB),NOSPLIT,$0-16
 	// socket is implemented as socketcall(NR_socket, 1, *(rest of args))
 	// stack already should have domain, type, protocol.
-	MOVL	$102, AX  // syscall - socketcall
+	MOVL	$SYS_socketcall, AX
 	MOVL	$1, BX  // socket
 	LEAL	domain+0(FP), CX
 	INVOKE_SYSCALL
@@ -603,7 +730,7 @@
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
 	// Implemented as brk(NULL).
-	MOVL	$45, AX  // syscall - brk
+	MOVL	$SYS_brk, AX
 	MOVL	$0, BX  // NULL
 	INVOKE_SYSCALL
 	MOVL	AX, ret+0(FP)
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index e0dc3e1..5a94bda 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -10,23 +10,65 @@
 #include "go_tls.h"
 #include "textflag.h"
 
+#define SYS_read		0
+#define SYS_write		1
+#define SYS_open		2
+#define SYS_close		3
+#define SYS_mmap		9
+#define SYS_munmap		11
+#define SYS_brk 		12
+#define SYS_rt_sigaction	13
+#define SYS_rt_sigprocmask	14
+#define SYS_rt_sigreturn	15
+#define SYS_access		21
+#define SYS_sched_yield 	24
+#define SYS_mincore		27
+#define SYS_madvise		28
+#define SYS_setittimer		38
+#define SYS_getpid		39
+#define SYS_socket		41
+#define SYS_connect		42
+#define SYS_clone		56
+#define SYS_exit		60
+#define SYS_kill		62
+#define SYS_fcntl		72
+#define SYS_getrlimit		97
+#define SYS_sigaltstack 	131
+#define SYS_arch_prctl		158
+#define SYS_gettid		186
+#define SYS_tkill		200
+#define SYS_futex		202
+#define SYS_sched_getaffinity	204
+#define SYS_epoll_create	213
+#define SYS_exit_group		231
+#define SYS_epoll_wait		232
+#define SYS_epoll_ctl		233
+#define SYS_pselect6		270
+#define SYS_epoll_create1	291
+
 TEXT runtime·exit(SB),NOSPLIT,$0-4
 	MOVL	code+0(FP), DI
-	MOVL	$231, AX	// exitgroup - force all os threads to exit
+	MOVL	$SYS_exit_group, AX
 	SYSCALL
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$0-4
-	MOVL	code+0(FP), DI
-	MOVL	$60, AX	// exit - exit the current os thread
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	MOVL	$0, DI	// exit code
+	MOVL	$SYS_exit, AX
 	SYSCALL
-	RET
+	// We may not even have a stack any more.
+	INT	$3
+	JMP	0(PC)
 
 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
+	MOVL	$SYS_open, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -36,7 +78,7 @@
 
 TEXT runtime·closefd(SB),NOSPLIT,$0-12
 	MOVL	fd+0(FP), DI
-	MOVL	$3, AX			// syscall entry
+	MOVL	$SYS_close, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -48,7 +90,7 @@
 	MOVQ	fd+0(FP), DI
 	MOVQ	p+8(FP), SI
 	MOVL	n+16(FP), DX
-	MOVL	$1, AX			// syscall entry
+	MOVL	$SYS_write, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -60,7 +102,7 @@
 	MOVL	fd+0(FP), DI
 	MOVQ	p+8(FP), SI
 	MOVL	n+16(FP), DX
-	MOVL	$0, AX			// syscall entry
+	MOVL	$SYS_read, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -71,7 +113,7 @@
 TEXT runtime·getrlimit(SB),NOSPLIT,$0-20
 	MOVL	kind+0(FP), DI
 	MOVQ	limit+8(FP), SI
-	MOVL	$97, AX			// syscall entry
+	MOVL	$SYS_getrlimit, AX
 	SYSCALL
 	MOVL	AX, ret+16(FP)
 	RET
@@ -93,31 +135,31 @@
 	MOVL	$0, R10
 	MOVQ	SP, R8
 	MOVL	$0, R9
-	MOVL	$270, AX
+	MOVL	$SYS_pselect6, AX
 	SYSCALL
 	RET
 
 TEXT runtime·gettid(SB),NOSPLIT,$0-4
-	MOVL	$186, AX	// syscall - gettid
+	MOVL	$SYS_gettid, AX
 	SYSCALL
 	MOVL	AX, ret+0(FP)
 	RET
 
 TEXT runtime·raise(SB),NOSPLIT,$0
-	MOVL	$186, AX	// syscall - gettid
+	MOVL	$SYS_gettid, AX
 	SYSCALL
 	MOVL	AX, DI	// arg 1 tid
 	MOVL	sig+0(FP), SI	// arg 2
-	MOVL	$200, AX	// syscall - tkill
+	MOVL	$SYS_tkill, AX
 	SYSCALL
 	RET
 
 TEXT runtime·raiseproc(SB),NOSPLIT,$0
-	MOVL	$39, AX	// syscall - getpid
+	MOVL	$SYS_getpid, AX
 	SYSCALL
 	MOVL	AX, DI	// arg 1 pid
 	MOVL	sig+0(FP), SI	// arg 2
-	MOVL	$62, AX	// syscall - kill
+	MOVL	$SYS_kill, AX
 	SYSCALL
 	RET
 
@@ -125,7 +167,7 @@
 	MOVL	mode+0(FP), DI
 	MOVQ	new+8(FP), SI
 	MOVQ	old+16(FP), DX
-	MOVL	$38, AX			// syscall entry
+	MOVL	$SYS_setittimer, AX
 	SYSCALL
 	RET
 
@@ -133,17 +175,37 @@
 	MOVQ	addr+0(FP), DI
 	MOVQ	n+8(FP), SI
 	MOVQ	dst+16(FP), DX
-	MOVL	$27, AX			// syscall entry
+	MOVL	$SYS_mincore, AX
 	SYSCALL
 	MOVL	AX, ret+24(FP)
 	RET
 
 // func walltime() (sec int64, nsec int32)
-TEXT runtime·walltime(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!
+TEXT runtime·walltime(SB),NOSPLIT,$0-12
+	// We don't know how much stack space the VDSO code will need,
+	// so switch to g0.
+	// In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n
+	// and hardening can use a full page of stack space in gettime_sym
+	// due to stack probes inserted to avoid stack/heap collisions.
+	// See issue #20427.
+
+	MOVQ	SP, BP	// Save old SP; BP unchanged by C code.
+
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), CX
+	MOVQ	m_curg(CX), DX
+
+	CMPQ	AX, DX		// Only switch if on curg.
+	JNE	noswitch
+
+	MOVQ	m_g0(CX), DX
+	MOVQ	(g_sched+gobuf_sp)(DX), SP	// Set SP to g0 stack
+
+noswitch:
+	SUBQ	$16, SP		// Space for results
+	ANDQ	$~15, SP	// Align for C code
+
 	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
 	CMPQ	AX, $0
 	JEQ	fallback
@@ -152,6 +214,7 @@
 	CALL	AX
 	MOVQ	0(SP), AX	// sec
 	MOVQ	8(SP), DX	// nsec
+	MOVQ	BP, SP		// Restore real SP
 	MOVQ	AX, sec+0(FP)
 	MOVL	DX, nsec+8(FP)
 	RET
@@ -163,13 +226,31 @@
 	MOVQ	0(SP), AX	// sec
 	MOVL	8(SP), DX	// usec
 	IMULQ	$1000, DX
+	MOVQ	BP, SP		// Restore real SP
 	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.
+TEXT runtime·nanotime(SB),NOSPLIT,$0-8
+	// Switch to g0 stack. See comment above in runtime·walltime.
+
+	MOVQ	SP, BP	// Save old SP; BX unchanged by C code.
+
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), CX
+	MOVQ	m_curg(CX), DX
+
+	CMPQ	AX, DX		// Only switch if on curg.
+	JNE	noswitch
+
+	MOVQ	m_g0(CX), DX
+	MOVQ	(g_sched+gobuf_sp)(DX), SP	// Set SP to g0 stack
+
+noswitch:
+	SUBQ	$16, SP		// Space for results
+	ANDQ	$~15, SP	// Align for C code
+
 	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
 	CMPQ	AX, $0
 	JEQ	fallback
@@ -178,6 +259,7 @@
 	CALL	AX
 	MOVQ	0(SP), AX	// sec
 	MOVQ	8(SP), DX	// nsec
+	MOVQ	BP, SP		// Restore real SP
 	// sec is in AX, nsec in DX
 	// return nsec in AX
 	IMULQ	$1000000000, AX
@@ -191,6 +273,7 @@
 	CALL	AX
 	MOVQ	0(SP), AX	// sec
 	MOVL	8(SP), DX	// usec
+	MOVQ	BP, SP		// Restore real SP
 	IMULQ	$1000, DX
 	// sec is in AX, nsec in DX
 	// return nsec in AX
@@ -204,7 +287,7 @@
 	MOVQ	new+8(FP), SI
 	MOVQ	old+16(FP), DX
 	MOVL	size+24(FP), R10
-	MOVL	$14, AX			// syscall entry
+	MOVL	$SYS_rt_sigprocmask, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -216,7 +299,7 @@
 	MOVQ	new+8(FP), SI
 	MOVQ	old+16(FP), DX
 	MOVQ	size+24(FP), R10
-	MOVL	$13, AX			// syscall entry
+	MOVL	$SYS_rt_sigaction, AX
 	SYSCALL
 	MOVL	AX, ret+32(FP)
 	RET
@@ -354,7 +437,7 @@
 // The code that cares about the precise instructions used is:
 // https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup
 TEXT runtime·sigreturn(SB),NOSPLIT,$0
-	MOVQ	$15, AX	// rt_sigreturn
+	MOVQ	$SYS_rt_sigreturn, AX
 	SYSCALL
 	INT $3	// not reached
 
@@ -366,13 +449,18 @@
 	MOVL	fd+24(FP), R8
 	MOVL	off+28(FP), R9
 
-	MOVL	$9, AX			// mmap
+	MOVL	$SYS_mmap, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
-	JLS	3(PC)
+	JLS	ok
 	NOTQ	AX
 	INCQ	AX
-	MOVQ	AX, ret+32(FP)
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 // Call the function stored in _cgo_mmap using the GCC calling convention.
@@ -396,7 +484,7 @@
 TEXT runtime·sysMunmap(SB),NOSPLIT,$0
 	MOVQ	addr+0(FP), DI
 	MOVQ	n+8(FP), SI
-	MOVQ	$11, AX	// munmap
+	MOVQ	$SYS_munmap, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -420,7 +508,7 @@
 	MOVQ	addr+0(FP), DI
 	MOVQ	n+8(FP), SI
 	MOVL	flags+16(FP), DX
-	MOVQ	$28, AX	// madvise
+	MOVQ	$SYS_madvise, AX
 	SYSCALL
 	// ignore failure - maybe pages are locked
 	RET
@@ -434,7 +522,7 @@
 	MOVQ	ts+16(FP), R10
 	MOVQ	addr2+24(FP), R8
 	MOVL	val3+32(FP), R9
-	MOVL	$202, AX
+	MOVL	$SYS_futex, AX
 	SYSCALL
 	MOVL	AX, ret+40(FP)
 	RET
@@ -452,7 +540,7 @@
 	MOVQ	gp+24(FP), R9
 	MOVQ	fn+32(FP), R12
 
-	MOVL	$56, AX
+	MOVL	$SYS_clone, AX
 	SYSCALL
 
 	// In parent, return.
@@ -471,7 +559,7 @@
 	JEQ	nog
 
 	// Initialize m->procid to Linux tid
-	MOVL	$186, AX	// gettid
+	MOVL	$SYS_gettid, AX
 	SYSCALL
 	MOVQ	AX, m_procid(R8)
 
@@ -491,14 +579,14 @@
 
 	// It shouldn't return. If it does, exit that thread.
 	MOVL	$111, DI
-	MOVL	$60, AX
+	MOVL	$SYS_exit, AX
 	SYSCALL
 	JMP	-3(PC)	// keep exiting
 
 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
 	MOVQ	new+0(FP), DI
 	MOVQ	old+8(FP), SI
-	MOVQ	$131, AX
+	MOVQ	$SYS_sigaltstack, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -517,7 +605,7 @@
 #endif
 	MOVQ	DI, SI
 	MOVQ	$0x1002, DI	// ARCH_SET_FS
-	MOVQ	$158, AX	// arch_prctl
+	MOVQ	$SYS_arch_prctl, AX
 	SYSCALL
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	2(PC)
@@ -525,7 +613,7 @@
 	RET
 
 TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$24, AX
+	MOVL	$SYS_sched_yield, AX
 	SYSCALL
 	RET
 
@@ -533,7 +621,7 @@
 	MOVQ	pid+0(FP), DI
 	MOVQ	len+8(FP), SI
 	MOVQ	buf+16(FP), DX
-	MOVL	$204, AX			// syscall entry
+	MOVL	$SYS_sched_getaffinity, AX
 	SYSCALL
 	MOVL	AX, ret+24(FP)
 	RET
@@ -541,7 +629,7 @@
 // int32 runtime·epollcreate(int32 size);
 TEXT runtime·epollcreate(SB),NOSPLIT,$0
 	MOVL    size+0(FP), DI
-	MOVL    $213, AX                        // syscall entry
+	MOVL    $SYS_epoll_create, AX
 	SYSCALL
 	MOVL	AX, ret+8(FP)
 	RET
@@ -549,7 +637,7 @@
 // int32 runtime·epollcreate1(int32 flags);
 TEXT runtime·epollcreate1(SB),NOSPLIT,$0
 	MOVL	flags+0(FP), DI
-	MOVL	$291, AX			// syscall entry
+	MOVL	$SYS_epoll_create1, AX
 	SYSCALL
 	MOVL	AX, ret+8(FP)
 	RET
@@ -560,7 +648,7 @@
 	MOVL	op+4(FP), SI
 	MOVL	fd+8(FP), DX
 	MOVQ	ev+16(FP), R10
-	MOVL	$233, AX			// syscall entry
+	MOVL	$SYS_epoll_ctl, AX
 	SYSCALL
 	MOVL	AX, ret+24(FP)
 	RET
@@ -571,7 +659,7 @@
 	MOVQ	ev+8(FP), SI
 	MOVL	nev+16(FP), DX
 	MOVL	timeout+20(FP), R10
-	MOVL	$232, AX			// syscall entry
+	MOVL	$SYS_epoll_wait, AX
 	SYSCALL
 	MOVL	AX, ret+24(FP)
 	RET
@@ -581,7 +669,7 @@
 	MOVL    fd+0(FP), DI  // fd
 	MOVQ    $2, SI  // F_SETFD
 	MOVQ    $1, DX  // FD_CLOEXEC
-	MOVL	$72, AX  // fcntl
+	MOVL	$SYS_fcntl, AX
 	SYSCALL
 	RET
 
@@ -590,7 +678,7 @@
 TEXT runtime·access(SB),NOSPLIT,$0
 	MOVQ	name+0(FP), DI
 	MOVL	mode+8(FP), SI
-	MOVL	$21, AX  // syscall entry
+	MOVL	$SYS_access, AX
 	SYSCALL
 	MOVL	AX, ret+16(FP)
 	RET
@@ -600,7 +688,7 @@
 	MOVL	fd+0(FP), DI
 	MOVQ	addr+8(FP), SI
 	MOVL	len+16(FP), DX
-	MOVL	$42, AX  // syscall entry
+	MOVL	$SYS_connect, AX
 	SYSCALL
 	MOVL	AX, ret+24(FP)
 	RET
@@ -610,7 +698,7 @@
 	MOVL	domain+0(FP), DI
 	MOVL	typ+4(FP), SI
 	MOVL	prot+8(FP), DX
-	MOVL	$41, AX  // syscall entry
+	MOVL	$SYS_socket, AX
 	SYSCALL
 	MOVL	AX, ret+16(FP)
 	RET
@@ -619,7 +707,7 @@
 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
 	// Implemented as brk(NULL).
 	MOVQ	$0, DI
-	MOVL	$12, AX  // syscall entry
+	MOVL	$SYS_brk, AX
 	SYSCALL
 	MOVQ	AX, ret+0(FP)
 	RET
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index 64beed8..794f9b3 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -114,7 +114,7 @@
 	MOVW	$1002, R1
 	MOVW	R0, (R1)	// fail hard
 
-TEXT runtime·exit1(SB),NOSPLIT,$-4
+TEXT exit1<>(SB),NOSPLIT,$-4
 	MOVW	code+0(FP), R0
 	MOVW	$SYS_exit, R7
 	SWI	$0
@@ -122,6 +122,22 @@
 	MOVW	$1003, R1
 	MOVW	R0, (R1)	// fail hard
 
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$-4-4
+	MOVW	wait+0(FP), R0
+	// We're done using the stack.
+	// Alas, there's no reliable way to make this write atomic
+	// without potentially using the stack. So it goes.
+	MOVW	$0, R1
+	MOVW	R1, (R0)
+	MOVW	$0, R0	// exit code
+	MOVW	$SYS_exit, R7
+	SWI	$0
+	MOVW	$1234, R0
+	MOVW	$1004, R1
+	MOVW	R0, (R1)	// fail hard
+	JMP	0(PC)
+
 TEXT runtime·gettid(SB),NOSPLIT,$0-4
 	MOVW	$SYS_gettid, R7
 	SWI	$0
@@ -157,8 +173,12 @@
 	SWI	$0
 	MOVW	$0xfffff001, R6
 	CMP		R6, R0
+	MOVW	$0, R1
 	RSB.HI	$0, R0
-	MOVW	R0, ret+24(FP)
+	MOVW.HI	R0, R1		// if error, put in R1
+	MOVW.HI	$0, R0
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
@@ -317,7 +337,7 @@
 	SUB	$16, R13 // restore the stack pointer to avoid memory corruption
 	MOVW	$0, R0
 	MOVW	R0, 4(R13)
-	BL	runtime·exit1(SB)
+	BL	exit1<>(SB)
 
 	MOVW	$1234, R0
 	MOVW	$1005, R1
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index e921f99..758e685 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -54,11 +54,16 @@
 	SVC
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8-4
-	MOVW	code+0(FP), R0
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$-8-8
+	MOVD	wait+0(FP), R0
+	// We're done using the stack.
+	MOVW	$0, R1
+	STLRW	R1, (R0)
+	MOVW	$0, R0	// exit code
 	MOVD	$SYS_exit, R8
 	SVC
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8-20
 	MOVD	$AT_FDCWD, R0
@@ -273,9 +278,14 @@
 	MOVD	$SYS_mmap, R8
 	SVC
 	CMN	$4095, R0
-	BCC	2(PC)
+	BCC	ok
 	NEG	R0,R0
-	MOVD	R0, ret+32(FP)
+	MOVD	$0, p+32(FP)
+	MOVD	R0, err+40(FP)
+	RET
+ok:
+	MOVD	R0, p+32(FP)
+	MOVD	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-8
diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s
index 27de7b0..7402ae2 100644
--- a/src/runtime/sys_linux_mips64x.s
+++ b/src/runtime/sys_linux_mips64x.s
@@ -53,11 +53,18 @@
 	SYSCALL
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8-4
-	MOVW	code+0(FP), R4
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$-8-8
+	MOVV	wait+0(FP), R1
+	// We're done using the stack.
+	MOVW	$0, R2
+	SYNC
+	MOVW	R2, (R1)
+	SYNC
+	MOVW	$0, R4	// exit code
 	MOVV	$SYS_exit, R2
 	SYSCALL
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8-20
 	MOVV	name+0(FP), R4
@@ -262,7 +269,13 @@
 
 	MOVV	$SYS_mmap, R2
 	SYSCALL
-	MOVV	R2, ret+32(FP)
+	BEQ	R7, ok
+	MOVV	$0, p+32(FP)
+	MOVV	R2, err+40(FP)
+	RET
+ok:
+	MOVV	R2, p+32(FP)
+	MOVV	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-8
diff --git a/src/runtime/sys_linux_mipsx.s b/src/runtime/sys_linux_mipsx.s
index 39bd731..6bd0267 100644
--- a/src/runtime/sys_linux_mipsx.s
+++ b/src/runtime/sys_linux_mipsx.s
@@ -54,12 +54,19 @@
 	UNDEF
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$0-4
-	MOVW	code+0(FP), R4
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVW	wait+0(FP), R1
+	// We're done using the stack.
+	MOVW	$0, R2
+	SYNC
+	MOVW	R2, (R1)
+	SYNC
+	MOVW	$0, R4	// exit code
 	MOVW	$SYS_exit, R2
 	SYSCALL
 	UNDEF
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$0-16
 	MOVW	name+0(FP), R4
@@ -272,7 +279,7 @@
 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
 	JMP	runtime·sigtramp(SB)
 
-TEXT runtime·mmap(SB),NOSPLIT,$20-28
+TEXT runtime·mmap(SB),NOSPLIT,$20-32
 	MOVW	addr+0(FP), R4
 	MOVW	n+4(FP), R5
 	MOVW	prot+8(FP), R6
@@ -284,7 +291,13 @@
 
 	MOVW	$SYS_mmap, R2
 	SYSCALL
-	MOVW	R2, ret+24(FP)
+	BEQ	R7, ok
+	MOVW	$0, p+24(FP)
+	MOVW	R2, err+28(FP)
+	RET
+ok:
+	MOVW	R2, p+24(FP)
+	MOVW	$0, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0-8
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 2b2aa61..9b45f94 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -54,10 +54,16 @@
 	SYSCALL	$SYS_exit_group
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT|NOFRAME,$0-4
-	MOVW	code+0(FP), R3
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
+	MOVD	wait+0(FP), R1
+	// We're done using the stack.
+	MOVW	$0, R2
+	SYNC
+	MOVW	R2, (R1)
+	MOVW	$0, R3	// exit code
 	SYSCALL	$SYS_exit
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
 	MOVD	name+0(FP), R3
@@ -244,7 +250,96 @@
 
 #ifdef GOARCH_ppc64le
 // ppc64le doesn't need function descriptors
-TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
+	// The stack unwinder, presumably written in C, may not be able to
+	// handle Go frame correctly. So, this function is NOFRAME, and we
+	// we save/restore LR manually.
+	MOVD	LR, R10
+
+	// We're coming from C code, initialize essential registers.
+	CALL	runtime·reginit(SB)
+
+	// If no traceback function, do usual sigtramp.
+	MOVD	runtime·cgoTraceback(SB), R6
+	CMP	$0, R6
+	BEQ	sigtramp
+
+	// If no traceback support function, which means that
+	// runtime/cgo was not linked in, do usual sigtramp.
+	MOVD	_cgo_callers(SB), R6
+	CMP	$0, R6
+	BEQ	sigtramp
+
+	// Set up g register.
+	CALL	runtime·load_g(SB)
+
+	// Figure out if we are currently in a cgo call.
+	// If not, just do usual sigtramp.
+	CMP	$0, g
+	BEQ	sigtrampnog // g == nil
+	MOVD	g_m(g), R6
+	CMP	$0, R6
+	BEQ	sigtramp    // g.m == nil
+	MOVW	m_ncgo(R6), R7
+	CMPW	$0, R7
+	BEQ	sigtramp    // g.m.ncgo = 0
+	MOVD	m_curg(R6), R7
+	CMP	$0, R7
+	BEQ	sigtramp    // g.m.curg == nil
+	MOVD	g_syscallsp(R7), R7
+	CMP	$0, R7
+	BEQ	sigtramp    // g.m.curg.syscallsp == 0
+	MOVD	m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
+	CMP	$0, R7
+	BEQ	sigtramp    // g.m.cgoCallers == nil
+	MOVW	m_cgoCallersUse(R6), R8
+	CMPW	$0, R8
+	BNE	sigtramp    // g.m.cgoCallersUse != 0
+
+	// Jump to a function in runtime/cgo.
+	// That function, written in C, will call the user's traceback
+	// function with proper unwind info, and will then call back here.
+	// The first three arguments, and the fifth, are already in registers.
+	// Set the two remaining arguments now.
+	MOVD	runtime·cgoTraceback(SB), R6
+	MOVD	$runtime·sigtramp(SB), R8
+	MOVD	_cgo_callers(SB), R12
+	MOVD	R12, CTR
+	MOVD	R10, LR // restore LR
+	JMP	(CTR)
+
+sigtramp:
+	MOVD	R10, LR // restore LR
+	JMP	runtime·sigtramp(SB)
+
+sigtrampnog:
+	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
+	// stack trace.
+	CMPW	R3, $27 // 27 == SIGPROF
+	BNE	sigtramp
+
+	// Lock sigprofCallersUse (cas from 0 to 1).
+	MOVW	$1, R7
+	MOVD	$runtime·sigprofCallersUse(SB), R8
+	SYNC
+	LWAR    (R8), R6
+	CMPW    $0, R6
+	BNE     sigtramp
+	STWCCC  R7, (R8)
+	BNE     -4(PC)
+	ISYNC
+
+	// Jump to the traceback function in runtime/cgo.
+	// It will call back to sigprofNonGo, which will ignore the
+	// arguments passed in registers.
+	// First three arguments to traceback function are in registers already.
+	MOVD	runtime·cgoTraceback(SB), R6
+	MOVD	$runtime·sigprofCallers(SB), R7
+	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R8
+	MOVD	_cgo_callers(SB), R12
+	MOVD	R12, CTR
+	MOVD	R10, LR // restore LR
+	JMP	(CTR)
 #else
 // function descriptor for the real sigtramp
 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
@@ -252,10 +347,14 @@
 	DWORD	$0
 	DWORD	$0
 TEXT runtime·_cgoSigtramp(SB),NOSPLIT,$0
+	JMP	runtime·sigtramp(SB)
 #endif
-	MOVD	$runtime·sigtramp(SB), R12
-	MOVD	R12, CTR
-	JMP	(CTR)
+
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
+	// We're coming from C code, set up essential register, then call sigprofNonGo.
+	CALL	runtime·reginit(SB)
+	CALL	runtime·sigprofNonGo(SB)
+	RET
 
 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
 	MOVD	addr+0(FP), R3
@@ -266,7 +365,13 @@
 	MOVW	off+28(FP), R8
 
 	SYSCALL	$SYS_mmap
-	MOVD	R3, ret+32(FP)
+	BVC	ok
+	MOVD	$0, p+32(FP)
+	MOVD	R3, err+40(FP)
+	RET
+ok:
+	MOVD	R3, p+32(FP)
+	MOVD	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index b8099e2..72b0244 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -49,11 +49,16 @@
 	SYSCALL
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT|NOFRAME,$0-4
-	MOVW	code+0(FP), R2
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
+	MOVD	wait+0(FP), R1
+	// We're done using the stack.
+	MOVW	$0, R2
+	MOVW	R2, (R1)
+	MOVW	$0, R2	// exit code
 	MOVW	$SYS_exit, R1
 	SYSCALL
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
 	MOVD	name+0(FP), R2
@@ -246,7 +251,7 @@
 	BR	runtime·sigtramp(SB)
 
 // func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
-TEXT runtime·mmap(SB),NOSPLIT,$48-40
+TEXT runtime·mmap(SB),NOSPLIT,$48-48
 	MOVD	addr+0(FP), R2
 	MOVD	n+8(FP), R3
 	MOVW	prot+16(FP), R4
@@ -267,9 +272,14 @@
 	MOVW	$SYS_mmap, R1
 	SYSCALL
 	MOVD	$-4095, R3
-	CMPUBLT	R2, R3, 2(PC)
+	CMPUBLT	R2, R3, ok
 	NEG	R2
-	MOVD	R2, ret+32(FP)
+	MOVD	$0, p+32(FP)
+	MOVD	R2, err+40(FP)
+	RET
+ok:
+	MOVD	R2, p+32(FP)
+	MOVD	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
diff --git a/src/runtime/sys_nacl_386.s b/src/runtime/sys_nacl_386.s
index d945453..cdc8ff1 100644
--- a/src/runtime/sys_nacl_386.s
+++ b/src/runtime/sys_nacl_386.s
@@ -16,11 +16,13 @@
 	NACL_SYSCALL(SYS_exit)
 	JMP 0(PC)
 
-TEXT runtime·exit1(SB),NOSPLIT,$4
-	MOVL code+0(FP), AX
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$4-4
+	MOVL wait+0(FP), AX
+	// SYS_thread_exit will clear *wait when the stack is free.
 	MOVL AX, 0(SP)
 	NACL_SYSCALL(SYS_thread_exit)
-	RET
+	JMP 0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$12
 	MOVL name+0(FP), AX
@@ -228,9 +230,14 @@
 	MOVL	AX, 20(SP)
 	NACL_SYSCALL(SYS_mmap)
 	CMPL	AX, $-4095
-	JNA	2(PC)
+	JNA	ok
 	NEGL	AX
-	MOVL	AX, ret+24(FP)
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·walltime(SB),NOSPLIT,$20
diff --git a/src/runtime/sys_nacl_amd64p32.s b/src/runtime/sys_nacl_amd64p32.s
index 2a39983..ff4c2e7 100644
--- a/src/runtime/sys_nacl_amd64p32.s
+++ b/src/runtime/sys_nacl_amd64p32.s
@@ -19,10 +19,12 @@
 	NACL_SYSCALL(SYS_exit)
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL code+0(FP), DI
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL wait+0(FP), DI
+	// SYS_thread_exit will clear *wait when the stack is free.
 	NACL_SYSCALL(SYS_thread_exit)
-	RET
+	JMP 0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$0
 	MOVL name+0(FP), DI
@@ -237,9 +239,14 @@
 	MOVL SP, R9
 	NACL_SYSCALL(SYS_mmap)
 	CMPL AX, $-4095
-	JNA 2(PC)
+	JNA ok
 	NEGL AX
-	MOVL	AX, ret+24(FP)
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·walltime(SB),NOSPLIT,$16
diff --git a/src/runtime/sys_nacl_arm.s b/src/runtime/sys_nacl_arm.s
index 6a6ef4e..6e01fe4 100644
--- a/src/runtime/sys_nacl_arm.s
+++ b/src/runtime/sys_nacl_arm.s
@@ -15,10 +15,12 @@
 	NACL_SYSCALL(SYS_exit)
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVW	code+0(FP), R0
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$4-4
+	MOVW wait+0(FP), R0
+	// SYS_thread_exit will clear *wait when the stack is free.
 	NACL_SYSCALL(SYS_thread_exit)
-	RET
+	JMP 0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$0
 	MOVW	name+0(FP), R0
@@ -192,8 +194,12 @@
 	NACL_SYSCALL(SYS_mmap)
 	MOVM.IA.W (R13), [R4, R5]
 	CMP	$-4095, R0
+	MOVW	$0, R1
 	RSB.HI	$0, R0
-	MOVW	R0, ret+24(FP)
+	MOVW.HI	R0, R1		// if error, put in R1
+	MOVW.HI	$0, R0
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·walltime(SB),NOSPLIT,$16
diff --git a/src/runtime/sys_netbsd_386.s b/src/runtime/sys_netbsd_386.s
index 742193c..4042ab4 100644
--- a/src/runtime/sys_netbsd_386.s
+++ b/src/runtime/sys_netbsd_386.s
@@ -17,12 +17,15 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-4
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
 	MOVL	$310, AX		// sys__lwp_exit
 	INT	$0x80
-	JAE	2(PC)
 	MOVL	$0xf1, 0xf1		// crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-4
 	MOVL	$5, AX
@@ -113,7 +116,13 @@
 	STOSL
 	MOVL	$197, AX		// sys_mmap
 	INT	$0x80
-	MOVL	AX, ret+24(FP)
+	JAE	ok
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-4
@@ -155,7 +164,7 @@
 // void nanotime(int64 *nsec)
 TEXT runtime·nanotime(SB),NOSPLIT,$32
 	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)		// arg 1 - clock_id
+	MOVL	$3, 4(SP)		// arg 1 - clock_id CLOCK_MONOTONIC
 	MOVL	BX, 8(SP)		// arg 2 - tp
 	MOVL	$427, AX		// sys_clock_gettime
 	INT	$0x80
@@ -298,7 +307,7 @@
 	// Call fn
 	CALL	SI
 
-	CALL	runtime·exit1(SB)
+	// fn should never return
 	MOVL	$0x1234, 0x1005
 	RET
 
@@ -337,9 +346,9 @@
 	RET
 
 TEXT runtime·lwp_park(SB),NOSPLIT,$-4
-	MOVL	$434, AX		// sys__lwp_park
+	MOVL	$478, AX		// sys__lwp_park
 	INT	$0x80
-	MOVL	AX, ret+16(FP)
+	MOVL	AX, ret+24(FP)
 	RET
 
 TEXT runtime·lwp_unpark(SB),NOSPLIT,$-4
@@ -366,10 +375,12 @@
 	MOVSL				// arg 6 - newlen
 	MOVL	$202, AX		// sys___sysctl
 	INT	$0x80
-	JCC	3(PC)
+	JAE	4(PC)
 	NEGL	AX
+	MOVL	AX, ret+24(FP)
 	RET
 	MOVL	$0, AX
+	MOVL	AX, ret+24(FP)
 	RET
 
 GLOBL runtime·tlsoffset(SB),NOPTR,$4
diff --git a/src/runtime/sys_netbsd_amd64.s b/src/runtime/sys_netbsd_amd64.s
index c632a0b..11b9c1b 100644
--- a/src/runtime/sys_netbsd_amd64.s
+++ b/src/runtime/sys_netbsd_amd64.s
@@ -48,13 +48,15 @@
 	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
+	MOVL	clockid+0(FP), DI		// arg 1 - clockid
+	MOVL	flags+4(FP), SI			// arg 2 - flags
+	MOVQ	ts+8(FP), DX			// arg 3 - ts
+	MOVL	unpark+16(FP), R10		// arg 4 - unpark
+	MOVQ	hint+24(FP), R8			// arg 5 - hint
+	MOVQ	unparkhint+32(FP), R9		// arg 6 - unparkhint
+	MOVL	$478, AX			// sys__lwp_park
 	SYSCALL
-	MOVL	AX, ret+32(FP)
+	MOVL	AX, ret+40(FP)
 	RET
 
 TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
@@ -79,11 +81,15 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
 	MOVL	$310, AX		// sys__lwp_exit
 	SYSCALL
 	MOVL	$0xf1, 0xf1		// crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVQ	name+0(FP), DI		// arg 1 pathname
@@ -184,7 +190,7 @@
 	RET
 
 TEXT runtime·nanotime(SB),NOSPLIT,$32
-	MOVQ	$0, DI			// arg 1 - clock_id
+	MOVQ	$3, DI			// arg 1 - clock_id CLOCK_MONOTONIC
 	LEAQ	8(SP), SI		// arg 2 - tp
 	MOVL	$427, AX		// sys_clock_gettime
 	SYSCALL
@@ -286,8 +292,15 @@
 	MOVQ	$0, R9			// arg 6 - pad
 	MOVL	$197, AX		// sys_mmap
 	SYSCALL
+	JCC	ok
 	ADDQ	$16, SP
-	MOVQ	AX, ret+32(FP)
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	ADDQ	$16, SP
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_netbsd_arm.s b/src/runtime/sys_netbsd_arm.s
index 789b12e..7d2e290 100644
--- a/src/runtime/sys_netbsd_arm.s
+++ b/src/runtime/sys_netbsd_arm.s
@@ -18,12 +18,21 @@
 	MOVW.CS R8, (R8)
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-4
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVW wait+0(FP), R0
+	// We're done using the stack.
+	MOVW $0, R2
+storeloop:
+	LDREX (R0), R4          // loads R4
+	STREX R2, (R0), R1      // stores R2
+	CMP $0, R1
+	BNE storeloop
 	SWI $0xa00136	// sys__lwp_exit
 	MOVW $1, R8	// crash
 	MOVW R8, (R8)
-	RET
-	
+	JMP 0(PC)
+
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVW name+0(FP), R0
 	MOVW mode+4(FP), R1
@@ -71,13 +80,17 @@
 	SWI $0xa0015e	// sys_sched_yield
 	RET
 
-TEXT runtime·lwp_park(SB),NOSPLIT,$0
-	MOVW abstime+0(FP), R0	// arg 1 - abstime
-	MOVW unpark+4(FP), R1	// arg 2 - unpark
-	MOVW hint+8(FP), R2	// arg 3 - hint
-	MOVW unparkhint+12(FP), R3	// arg 4 - unparkhint
-	SWI $0xa001b2	// sys__lwp_park
-	MOVW	R0, ret+16(FP)
+TEXT runtime·lwp_park(SB),NOSPLIT,$8
+	MOVW clockid+0(FP), R0		// arg 1 - clock_id
+	MOVW flags+4(FP), R1		// arg 2 - flags
+	MOVW ts+8(FP), R2		// arg 3 - ts
+	MOVW unpark+12(FP), R3		// arg 4 - unpark
+	MOVW hint+16(FP), R4		// arg 5 - hint
+	MOVW R4, 4(R13)
+	MOVW unparkhint+20(FP), R5	// arg 6 - unparkhint
+	MOVW R5, 8(R13)
+	SWI $0xa001de			// sys__lwp_park
+	MOVW	R0, ret+24(FP)
 	RET
 
 TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
@@ -155,7 +168,7 @@
 // int64 nanotime(void) so really
 // void nanotime(int64 *nsec)
 TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVW $0, R0 // CLOCK_REALTIME
+	MOVW $3, R0 // CLOCK_MONOTONIC
 	MOVW $8(R13), R1
 	SWI $0xa001ab	// clock_gettime
 
@@ -255,7 +268,11 @@
 	ADD $4, R13 // pass arg 5 and arg 6 on stack
 	SWI $0xa000c5	// sys_mmap
 	SUB $4, R13
-	MOVW	R0, ret+24(FP)
+	MOVW	$0, R1
+	MOVW.CS R0, R1	// if error, move to R1
+	MOVW.CS $0, R0
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_openbsd_386.s b/src/runtime/sys_openbsd_386.s
index fb2a688..475a937 100644
--- a/src/runtime/sys_openbsd_386.s
+++ b/src/runtime/sys_openbsd_386.s
@@ -19,14 +19,21 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$8
-	MOVL	$0, 0(SP)
-	MOVL	$0, 4(SP)		// arg 1 - notdead
+GLOBL exitStack<>(SB),RODATA,$8
+DATA exitStack<>+0x00(SB)/4, $0
+DATA exitStack<>+0x04(SB)/4, $0
+
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVL	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
+	// sys__lwp_exit takes 1 argument, which it expects on the stack.
+	MOVL	$exitStack<>(SB), SP
 	MOVL	$302, AX		// sys___threxit
 	INT	$0x80
-	JAE	2(PC)
 	MOVL	$0xf1, 0xf1		// crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-4
 	MOVL	$5, AX
@@ -118,7 +125,13 @@
 	STOSL
 	MOVL	$197, AX		// sys_mmap
 	INT	$0x80
-	MOVL	AX, ret+24(FP)
+	JAE	ok
+	MOVL	$0, p+24(FP)
+	MOVL	AX, err+28(FP)
+	RET
+ok:
+	MOVL	AX, p+24(FP)
+	MOVL	$0, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-4
@@ -308,7 +321,7 @@
 	// Call fn.
 	CALL	SI
 
-	CALL	runtime·exit1(SB)
+	// fn should never return.
 	MOVL	$0x1234, 0x1005
 	RET
 
diff --git a/src/runtime/sys_openbsd_amd64.s b/src/runtime/sys_openbsd_amd64.s
index 9a52e5d..658f2c4 100644
--- a/src/runtime/sys_openbsd_amd64.s
+++ b/src/runtime/sys_openbsd_amd64.s
@@ -88,12 +88,16 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-8
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+	MOVQ	wait+0(FP), AX
+	// We're done using the stack.
+	MOVL	$0, (AX)
 	MOVQ	$0, DI			// arg 1 - notdead
 	MOVL	$302, AX		// sys___threxit
 	SYSCALL
 	MOVL	$0xf1, 0xf1		// crash
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-8
 	MOVQ	name+0(FP), DI		// arg 1 pathname
@@ -278,8 +282,15 @@
 	MOVQ	$0, R9			// arg 6 - pad
 	MOVL	$197, AX
 	SYSCALL
+	JCC	ok
 	ADDQ	$16, SP
-	MOVQ	AX, ret+32(FP)
+	MOVQ	$0, p+32(FP)
+	MOVQ	AX, err+40(FP)
+	RET
+ok:
+	ADDQ	$16, SP
+	MOVQ	AX, p+32(FP)
+	MOVQ	$0, err+40(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_openbsd_arm.s b/src/runtime/sys_openbsd_arm.s
index 93a5d5b..ea75386 100644
--- a/src/runtime/sys_openbsd_arm.s
+++ b/src/runtime/sys_openbsd_arm.s
@@ -22,13 +22,22 @@
 	MOVW.CS	R8, (R8)
 	RET
 
-TEXT runtime·exit1(SB),NOSPLIT,$-4
+// func exitThread(wait *uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-4
+	MOVW	wait+0(FP), R0
+	// We're done using the stack.
+	MOVW	$0, R2
+storeloop:
+	LDREX	(R0), R4          // loads R4
+	STREX	R2, (R0), R1      // stores R2
+	CMP	$0, R1
+	BNE	storeloop
 	MOVW	$0, R0			// arg 1 - notdead
 	MOVW	$302, R12		// sys___threxit
 	SWI	$0
 	MOVW.CS	$1, R8			// crash on syscall failure
 	MOVW.CS	R8, (R8)
-	RET
+	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-4
 	MOVW	name+0(FP), R0		// arg 1 - path
@@ -120,7 +129,11 @@
 	MOVW	$197, R12		// sys_mmap
 	SWI	$0
 	SUB	$4, R13
-	MOVW	R0, ret+24(FP)
+	MOVW	$0, R1
+	MOVW.CS	R0, R1			// if error, move to R1
+	MOVW.CS $0, R0
+	MOVW	R0, p+24(FP)
+	MOVW	R1, err+28(FP)
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$0
@@ -269,7 +282,7 @@
 	// Call fn.
 	BL	(R6)
 
-	BL	runtime·exit1(SB)
+	// fn should never return.
 	MOVW	$2, R8			// crash if reached
 	MOVW	R8, (R8)
 	RET
diff --git a/src/runtime/sys_plan9_386.s b/src/runtime/sys_plan9_386.s
index 688bd23..47dcb8d 100644
--- a/src/runtime/sys_plan9_386.s
+++ b/src/runtime/sys_plan9_386.s
@@ -139,7 +139,7 @@
 	MOVL	AX, ret+4(FP)
 	RET
 
-TEXT runtime·tstart_plan9(SB),NOSPLIT,$0
+TEXT runtime·tstart_plan9(SB),NOSPLIT,$4
 	MOVL	newm+0(FP), CX
 	MOVL	m_g0(CX), DX
 
@@ -163,8 +163,10 @@
 	CALL	runtime·stackcheck(SB)	// smashes AX, CX
 	CALL	runtime·mstart(SB)
 
-	MOVL	$0x1234, 0x1234		// not reached
-	RET
+	// Exit the thread.
+	MOVL	$0, 0(SP)
+	CALL	runtime·exits(SB)
+	JMP	0(PC)
 
 // void sigtramp(void *ureg, int8 *note)
 TEXT runtime·sigtramp(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_plan9_amd64.s b/src/runtime/sys_plan9_amd64.s
index d7bd92c..8077d6d 100644
--- a/src/runtime/sys_plan9_amd64.s
+++ b/src/runtime/sys_plan9_amd64.s
@@ -136,7 +136,7 @@
 	MOVL	AX, ret+8(FP)
 	RET
 
-TEXT runtime·tstart_plan9(SB),NOSPLIT,$0
+TEXT runtime·tstart_plan9(SB),NOSPLIT,$8
 	MOVQ	newm+0(FP), CX
 	MOVQ	m_g0(CX), DX
 
@@ -160,8 +160,10 @@
 	CALL	runtime·stackcheck(SB)	// smashes AX, CX
 	CALL	runtime·mstart(SB)
 
-	MOVQ	$0x1234, 0x1234		// not reached
-	RET
+	// Exit the thread.
+	MOVQ	$0, 0(SP)
+	CALL	runtime·exits(SB)
+	JMP	0(PC)
 
 // This is needed by asm_amd64.s
 TEXT runtime·settls(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_plan9_arm.s b/src/runtime/sys_plan9_arm.s
index 94a6f63..efaf603 100644
--- a/src/runtime/sys_plan9_arm.s
+++ b/src/runtime/sys_plan9_arm.s
@@ -207,7 +207,7 @@
 	RET
 
 //func tstart_plan9(newm *m)
-TEXT runtime·tstart_plan9(SB),NOSPLIT,$0-4
+TEXT runtime·tstart_plan9(SB),NOSPLIT,$4-4
 	MOVW	newm+0(FP), R1
 	MOVW	m_g0(R1), g
 
@@ -226,9 +226,11 @@
 
 	BL	runtime·mstart(SB)
 
-	MOVW	$0x1234, R0
-	MOVW	R0, 0(R0)		// not reached
-	RET
+	// Exit the thread.
+	MOVW	$0, R0
+	MOVW	R0, 4(R13)
+	CALL	runtime·exits(SB)
+	JMP	0(PC)
 
 //func sigtramp(ureg, note unsafe.Pointer)
 TEXT runtime·sigtramp(SB),NOSPLIT,$0-8
diff --git a/src/runtime/sys_solaris_amd64.s b/src/runtime/sys_solaris_amd64.s
index aeb2e2c..2b6daba 100644
--- a/src/runtime/sys_solaris_amd64.s
+++ b/src/runtime/sys_solaris_amd64.s
@@ -183,9 +183,6 @@
 	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.
 
@@ -223,19 +220,11 @@
 	MOVL	0(R10), R10
 	MOVQ	R10, 160(SP)
 
-	MOVQ	g(BX), R10
-	// g = m->gsignal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-
-	// TODO: If current SP is not in gsignal.stack, then adjust.
-
 	// prepare call
 	MOVQ	DI, 0(SP)
 	MOVQ	SI, 8(SP)
 	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-	CALL	runtime·sighandler(SB)
+	CALL	runtime·sigtrampgo(SB)
 
 	get_tls(BX)
 	MOVQ	g(BX), BP
@@ -273,10 +262,6 @@
 	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
diff --git a/src/runtime/sys_x86.go b/src/runtime/sys_x86.go
index 7e4e273..2b4ed8b 100644
--- a/src/runtime/sys_x86.go
+++ b/src/runtime/sys_x86.go
@@ -11,7 +11,7 @@
 	"unsafe"
 )
 
-// adjust Gobuf as it if executed a call to fn with context ctxt
+// adjust Gobuf as if it executed a call to fn with context ctxt
 // and then did an immediate gosave.
 func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
 	sp := buf.sp
diff --git a/src/runtime/syscall_solaris.go b/src/runtime/syscall_solaris.go
index 6c9dbe2..ee227ea 100644
--- a/src/runtime/syscall_solaris.go
+++ b/src/runtime/syscall_solaris.go
@@ -174,19 +174,9 @@
 }
 
 // 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.
+// but it doesn't work.
 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
+	panic("RawSyscall not available on Solaris")
 }
 
 //go:nosplit
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index ca8ea8b..134d4db 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -93,6 +93,8 @@
 //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
 //go:nosplit
 func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 
 	if useLoadLibraryEx {
@@ -126,6 +128,8 @@
 //go:linkname syscall_loadlibrary syscall.loadlibrary
 //go:nosplit
 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = getLoadLibrary()
 	c.n = 1
@@ -141,6 +145,8 @@
 //go:linkname syscall_getprocaddress syscall.getprocaddress
 //go:nosplit
 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = getGetProcAddress()
 	c.n = 2
@@ -156,6 +162,8 @@
 //go:linkname syscall_Syscall syscall.Syscall
 //go:nosplit
 func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
@@ -167,6 +175,8 @@
 //go:linkname syscall_Syscall6 syscall.Syscall6
 //go:nosplit
 func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
@@ -178,6 +188,8 @@
 //go:linkname syscall_Syscall9 syscall.Syscall9
 //go:nosplit
 func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
@@ -189,6 +201,8 @@
 //go:linkname syscall_Syscall12 syscall.Syscall12
 //go:nosplit
 func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
@@ -200,6 +214,8 @@
 //go:linkname syscall_Syscall15 syscall.Syscall15
 //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) {
+	lockOSThread()
+	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
@@ -207,9 +223,3 @@
 	cgocall(asmstdcallAddr, unsafe.Pointer(c))
 	return c.r1, c.r2, c.err
 }
-
-//go:linkname syscall_exit syscall.Exit
-//go:nosplit
-func syscall_exit(code int) {
-	exit(int32(code))
-}
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index 3da154d..dfde12a 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -15,6 +15,7 @@
 	"os/exec"
 	"path/filepath"
 	"runtime"
+	"strconv"
 	"strings"
 	"syscall"
 	"testing"
@@ -537,6 +538,17 @@
 	cmd.CombinedOutput()
 }
 
+func TestWindowsStackMemory(t *testing.T) {
+	o := runTestProg(t, "testprog", "StackMemory")
+	stackUsage, err := strconv.Atoi(o)
+	if err != nil {
+		t.Fatalf("Failed to read stack usage: %v", err)
+	}
+	if expected, got := 100<<10, stackUsage; got > expected {
+		t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got)
+	}
+}
+
 var used byte
 
 func use(buf []byte) {
@@ -1043,7 +1055,7 @@
 	}
 
 	exe := filepath.Join(tmpdir, "main.exe")
-	cmd := exec.Command("go", "build", "-o", exe, src)
+	cmd := exec.Command(testenv.GoToolPath(b), "build", "-o", exe, src)
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/runtime/testdata/testprog/badtraceback.go b/src/runtime/testdata/testprog/badtraceback.go
new file mode 100644
index 0000000..d558adc
--- /dev/null
+++ b/src/runtime/testdata/testprog/badtraceback.go
@@ -0,0 +1,47 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"runtime"
+	"runtime/debug"
+	"unsafe"
+)
+
+func init() {
+	register("BadTraceback", BadTraceback)
+}
+
+func BadTraceback() {
+	// Disable GC to prevent traceback at unexpected time.
+	debug.SetGCPercent(-1)
+
+	// Run badLR1 on its own stack to minimize the stack size and
+	// exercise the stack bounds logic in the hex dump.
+	go badLR1()
+	select {}
+}
+
+//go:noinline
+func badLR1() {
+	// We need two frames on LR machines because we'll smash this
+	// frame's saved LR.
+	badLR2(0)
+}
+
+//go:noinline
+func badLR2(arg int) {
+	// Smash the return PC or saved LR.
+	lrOff := unsafe.Sizeof(uintptr(0))
+	if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
+		lrOff = 32 // FIXED_FRAME or sys.MinFrameSize
+	}
+	lrPtr := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&arg)) - lrOff))
+	*lrPtr = 0xbad
+
+	// Print a backtrace. This should include diagnostics for the
+	// bad return PC and a hex dump.
+	panic("backtrace")
+}
diff --git a/src/runtime/testdata/testprog/gettid.go b/src/runtime/testdata/testprog/gettid.go
new file mode 100644
index 0000000..1b3e29a
--- /dev/null
+++ b/src/runtime/testdata/testprog/gettid.go
@@ -0,0 +1,29 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"syscall"
+)
+
+func gettid() int {
+	return syscall.Gettid()
+}
+
+func tidExists(tid int) (exists, supported bool) {
+	stat, err := ioutil.ReadFile(fmt.Sprintf("/proc/self/task/%d/stat", tid))
+	if os.IsNotExist(err) {
+		return false, true
+	}
+	// Check if it's a zombie thread.
+	state := bytes.Fields(stat)[2]
+	return !(len(state) == 1 && state[0] == 'Z'), true
+}
diff --git a/src/runtime/testdata/testprog/gettid_none.go b/src/runtime/testdata/testprog/gettid_none.go
new file mode 100644
index 0000000..036db87
--- /dev/null
+++ b/src/runtime/testdata/testprog/gettid_none.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !linux
+
+package main
+
+func gettid() int {
+	return 0
+}
+
+func tidExists(tid int) (exists, supported bool) {
+	return false, false
+}
diff --git a/src/runtime/testdata/testprog/lockosthread.go b/src/runtime/testdata/testprog/lockosthread.go
new file mode 100644
index 0000000..88c0d12
--- /dev/null
+++ b/src/runtime/testdata/testprog/lockosthread.go
@@ -0,0 +1,94 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"os"
+	"runtime"
+	"time"
+)
+
+var mainTID int
+
+func init() {
+	registerInit("LockOSThreadMain", func() {
+		// init is guaranteed to run on the main thread.
+		mainTID = gettid()
+	})
+	register("LockOSThreadMain", LockOSThreadMain)
+
+	registerInit("LockOSThreadAlt", func() {
+		// Lock the OS thread now so main runs on the main thread.
+		runtime.LockOSThread()
+	})
+	register("LockOSThreadAlt", LockOSThreadAlt)
+}
+
+func LockOSThreadMain() {
+	// gettid only works on Linux, so on other platforms this just
+	// checks that the runtime doesn't do anything terrible.
+
+	// This requires GOMAXPROCS=1 from the beginning to reliably
+	// start a goroutine on the main thread.
+	if runtime.GOMAXPROCS(-1) != 1 {
+		println("requires GOMAXPROCS=1")
+		os.Exit(1)
+	}
+
+	ready := make(chan bool, 1)
+	go func() {
+		// Because GOMAXPROCS=1, this *should* be on the main
+		// thread. Stay there.
+		runtime.LockOSThread()
+		if mainTID != 0 && gettid() != mainTID {
+			println("failed to start goroutine on main thread")
+			os.Exit(1)
+		}
+		// Exit with the thread locked, which should exit the
+		// main thread.
+		ready <- true
+	}()
+	<-ready
+	time.Sleep(1 * time.Millisecond)
+	// Check that this goroutine is still running on a different
+	// thread.
+	if mainTID != 0 && gettid() == mainTID {
+		println("goroutine migrated to locked thread")
+		os.Exit(1)
+	}
+	println("OK")
+}
+
+func LockOSThreadAlt() {
+	// This is running locked to the main OS thread.
+
+	var subTID int
+	ready := make(chan bool, 1)
+	go func() {
+		// This goroutine must be running on a new thread.
+		runtime.LockOSThread()
+		subTID = gettid()
+		ready <- true
+		// Exit with the thread locked.
+	}()
+	<-ready
+	runtime.UnlockOSThread()
+	for i := 0; i < 100; i++ {
+		time.Sleep(1 * time.Millisecond)
+		// Check that this goroutine is running on a different thread.
+		if subTID != 0 && gettid() == subTID {
+			println("locked thread reused")
+			os.Exit(1)
+		}
+		exists, supported := tidExists(subTID)
+		if !supported || !exists {
+			goto ok
+		}
+	}
+	println("sub thread", subTID, "still running")
+	return
+ok:
+	println("OK")
+}
diff --git a/src/runtime/testdata/testprog/syscall_windows.go b/src/runtime/testdata/testprog/syscall_windows.go
index 6e6782e..b4b6644 100644
--- a/src/runtime/testdata/testprog/syscall_windows.go
+++ b/src/runtime/testdata/testprog/syscall_windows.go
@@ -4,11 +4,18 @@
 
 package main
 
-import "syscall"
+import (
+	"internal/syscall/windows"
+	"runtime"
+	"sync"
+	"syscall"
+	"unsafe"
+)
 
 func init() {
 	register("RaiseException", RaiseException)
 	register("ZeroDivisionException", ZeroDivisionException)
+	register("StackMemory", StackMemory)
 }
 
 func RaiseException() {
@@ -25,3 +32,39 @@
 	z := x / y
 	println(z)
 }
+
+func getPagefileUsage() (uintptr, error) {
+	p, err := syscall.GetCurrentProcess()
+	if err != nil {
+		return 0, err
+	}
+	var m windows.PROCESS_MEMORY_COUNTERS
+	err = windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
+	if err != nil {
+		return 0, err
+	}
+	return m.PagefileUsage, nil
+}
+
+func StackMemory() {
+	mem1, err := getPagefileUsage()
+	if err != nil {
+		panic(err)
+	}
+	const threadCount = 100
+	var wg sync.WaitGroup
+	for i := 0; i < threadCount; i++ {
+		wg.Add(1)
+		go func() {
+			runtime.LockOSThread()
+			wg.Done()
+			select {}
+		}()
+	}
+	wg.Wait()
+	mem2, err := getPagefileUsage()
+	if err != nil {
+		panic(err)
+	}
+	print((mem2 - mem1) / threadCount)
+}
diff --git a/src/runtime/testdata/testprogcgo/callback.go b/src/runtime/testdata/testprogcgo/callback.go
index 7d9d68d..be0409f 100644
--- a/src/runtime/testdata/testprogcgo/callback.go
+++ b/src/runtime/testdata/testprogcgo/callback.go
@@ -29,6 +29,7 @@
 
 import (
 	"fmt"
+	"os"
 	"runtime"
 )
 
@@ -63,7 +64,10 @@
 }
 
 func CgoCallbackGC() {
-	const P = 100
+	P := 100
+	if os.Getenv("RUNTIME_TESTING_SHORT") != "" {
+		P = 10
+	}
 	done := make(chan bool)
 	// allocate a bunch of stack frames and spray them with pointers
 	for i := 0; i < P; i++ {
diff --git a/src/runtime/testdata/testprogcgo/catchpanic.go b/src/runtime/testdata/testprogcgo/catchpanic.go
new file mode 100644
index 0000000..55a606d
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/catchpanic.go
@@ -0,0 +1,46 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9,!windows
+
+package main
+
+/*
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void abrthandler(int signum) {
+	if (signum == SIGABRT) {
+		exit(0);  // success
+	}
+}
+
+void registerAbortHandler() {
+	struct sigaction act;
+	memset(&act, 0, sizeof act);
+	act.sa_handler = abrthandler;
+	sigaction(SIGABRT, &act, NULL);
+}
+
+static void __attribute__ ((constructor)) sigsetup(void) {
+	if (getenv("CGOCATCHPANIC_EARLY_HANDLER") == NULL)
+		return;
+	registerAbortHandler();
+}
+*/
+import "C"
+import "os"
+
+func init() {
+	register("CgoCatchPanic", CgoCatchPanic)
+}
+
+// Test that the SIGABRT raised by panic can be caught by an early signal handler.
+func CgoCatchPanic() {
+	if _, ok := os.LookupEnv("CGOCATCHPANIC_EARLY_HANDLER"); !ok {
+		C.registerAbortHandler()
+	}
+	panic("catch me")
+}
diff --git a/src/runtime/testdata/testprogcgo/cgo.go b/src/runtime/testdata/testprogcgo/cgo.go
index 209524a..a587db3 100644
--- a/src/runtime/testdata/testprogcgo/cgo.go
+++ b/src/runtime/testdata/testprogcgo/cgo.go
@@ -52,7 +52,11 @@
 	time.Sleep(time.Millisecond)
 	start := time.Now()
 	var times []time.Duration
-	for i := 0; i < 64; i++ {
+	n := 64
+	if os.Getenv("RUNTIME_TEST_SHORT") != "" {
+		n = 16
+	}
+	for i := 0; i < n; i++ {
 		go func() {
 			runtime.LockOSThread()
 			select {}
diff --git a/src/runtime/testdata/testprogcgo/lockosthread.c b/src/runtime/testdata/testprogcgo/lockosthread.c
new file mode 100644
index 0000000..b10cc4f
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/lockosthread.c
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9,!windows
+
+#include <stdint.h>
+
+uint32_t threadExited;
+
+void setExited(void *x) {
+	__sync_fetch_and_add(&threadExited, 1);
+}
diff --git a/src/runtime/testdata/testprogcgo/lockosthread.go b/src/runtime/testdata/testprogcgo/lockosthread.go
new file mode 100644
index 0000000..36423d9
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/lockosthread.go
@@ -0,0 +1,111 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9,!windows
+
+package main
+
+import (
+	"os"
+	"runtime"
+	"sync/atomic"
+	"time"
+	"unsafe"
+)
+
+/*
+#include <pthread.h>
+#include <stdint.h>
+
+extern uint32_t threadExited;
+
+void setExited(void *x);
+*/
+import "C"
+
+var mainThread C.pthread_t
+
+func init() {
+	registerInit("LockOSThreadMain", func() {
+		// init is guaranteed to run on the main thread.
+		mainThread = C.pthread_self()
+	})
+	register("LockOSThreadMain", LockOSThreadMain)
+
+	registerInit("LockOSThreadAlt", func() {
+		// Lock the OS thread now so main runs on the main thread.
+		runtime.LockOSThread()
+	})
+	register("LockOSThreadAlt", LockOSThreadAlt)
+}
+
+func LockOSThreadMain() {
+	// This requires GOMAXPROCS=1 from the beginning to reliably
+	// start a goroutine on the main thread.
+	if runtime.GOMAXPROCS(-1) != 1 {
+		println("requires GOMAXPROCS=1")
+		os.Exit(1)
+	}
+
+	ready := make(chan bool, 1)
+	go func() {
+		// Because GOMAXPROCS=1, this *should* be on the main
+		// thread. Stay there.
+		runtime.LockOSThread()
+		self := C.pthread_self()
+		if C.pthread_equal(mainThread, self) == 0 {
+			println("failed to start goroutine on main thread")
+			os.Exit(1)
+		}
+		// Exit with the thread locked, which should exit the
+		// main thread.
+		ready <- true
+	}()
+	<-ready
+	time.Sleep(1 * time.Millisecond)
+	// Check that this goroutine is still running on a different
+	// thread.
+	self := C.pthread_self()
+	if C.pthread_equal(mainThread, self) != 0 {
+		println("goroutine migrated to locked thread")
+		os.Exit(1)
+	}
+	println("OK")
+}
+
+func LockOSThreadAlt() {
+	// This is running locked to the main OS thread.
+
+	var subThread C.pthread_t
+	ready := make(chan bool, 1)
+	C.threadExited = 0
+	go func() {
+		// This goroutine must be running on a new thread.
+		runtime.LockOSThread()
+		subThread = C.pthread_self()
+		// Register a pthread destructor so we can tell this
+		// thread has exited.
+		var key C.pthread_key_t
+		C.pthread_key_create(&key, (*[0]byte)(unsafe.Pointer(C.setExited)))
+		C.pthread_setspecific(key, unsafe.Pointer(new(int)))
+		ready <- true
+		// Exit with the thread locked.
+	}()
+	<-ready
+	for i := 0; i < 100; i++ {
+		time.Sleep(1 * time.Millisecond)
+		// Check that this goroutine is running on a different thread.
+		self := C.pthread_self()
+		if C.pthread_equal(subThread, self) != 0 {
+			println("locked thread reused")
+			os.Exit(1)
+		}
+		if atomic.LoadUint32((*uint32)(&C.threadExited)) != 0 {
+			println("OK")
+			return
+		}
+	}
+	println("sub thread still running")
+	os.Exit(1)
+}
diff --git a/src/runtime/testdata/testprogcgo/sigpanic.go b/src/runtime/testdata/testprogcgo/sigpanic.go
new file mode 100644
index 0000000..cb46030
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/sigpanic.go
@@ -0,0 +1,28 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This program will crash.
+// We want to test unwinding from sigpanic into C code (without a C symbolizer).
+
+/*
+#cgo CFLAGS: -O0
+
+char *pnil;
+
+static int f1(void) {
+	*pnil = 0;
+	return 0;
+}
+*/
+import "C"
+
+func init() {
+	register("TracebackSigpanic", TracebackSigpanic)
+}
+
+func TracebackSigpanic() {
+	C.f1()
+}
diff --git a/src/runtime/testdata/testprogcgo/sigstack.go b/src/runtime/testdata/testprogcgo/sigstack.go
new file mode 100644
index 0000000..492dfef
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/sigstack.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9,!windows
+
+// Test handling of Go-allocated signal stacks when calling from
+// C-created threads with and without signal stacks. (See issue
+// #22930.)
+
+package main
+
+/*
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+extern void SigStackCallback();
+
+static void* WithSigStack(void* arg __attribute__((unused))) {
+	// Set up an alternate system stack.
+	void* base = mmap(0, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+	if (base == MAP_FAILED) {
+		perror("mmap failed");
+		abort();
+	}
+	stack_t st = {}, ost = {};
+	st.ss_sp = (char*)base;
+	st.ss_flags = 0;
+	st.ss_size = SIGSTKSZ;
+	if (sigaltstack(&st, &ost) < 0) {
+		perror("sigaltstack failed");
+		abort();
+	}
+
+	// Call Go.
+	SigStackCallback();
+
+	// Disable signal stack and protect it so we can detect reuse.
+	if (ost.ss_flags & SS_DISABLE) {
+		// Darwin libsystem has a bug where it checks ss_size
+		// even if SS_DISABLE is set. (The kernel gets it right.)
+		ost.ss_size = SIGSTKSZ;
+	}
+	if (sigaltstack(&ost, NULL) < 0) {
+		perror("sigaltstack restore failed");
+		abort();
+	}
+	mprotect(base, SIGSTKSZ, PROT_NONE);
+	return NULL;
+}
+
+static void* WithoutSigStack(void* arg __attribute__((unused))) {
+	SigStackCallback();
+	return NULL;
+}
+
+static void DoThread(int sigstack) {
+	pthread_t tid;
+	if (sigstack) {
+		pthread_create(&tid, NULL, WithSigStack, NULL);
+	} else {
+		pthread_create(&tid, NULL, WithoutSigStack, NULL);
+	}
+	pthread_join(tid, NULL);
+}
+*/
+import "C"
+
+func init() {
+	register("SigStack", SigStack)
+}
+
+func SigStack() {
+	C.DoThread(0)
+	C.DoThread(1)
+	C.DoThread(0)
+	C.DoThread(1)
+	println("OK")
+}
+
+var BadPtr *int
+
+//export SigStackCallback
+func SigStackCallback() {
+	// Cause the Go signal handler to run.
+	defer func() { recover() }()
+	*BadPtr = 42
+}
diff --git a/src/runtime/testdata/testprogcgo/stack_windows.go b/src/runtime/testdata/testprogcgo/stack_windows.go
new file mode 100644
index 0000000..846297a
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/stack_windows.go
@@ -0,0 +1,54 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "C"
+import (
+	"internal/syscall/windows"
+	"runtime"
+	"sync"
+	"syscall"
+	"unsafe"
+)
+
+func init() {
+	register("StackMemory", StackMemory)
+}
+
+func getPagefileUsage() (uintptr, error) {
+	p, err := syscall.GetCurrentProcess()
+	if err != nil {
+		return 0, err
+	}
+	var m windows.PROCESS_MEMORY_COUNTERS
+	err = windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
+	if err != nil {
+		return 0, err
+	}
+	return m.PagefileUsage, nil
+}
+
+func StackMemory() {
+	mem1, err := getPagefileUsage()
+	if err != nil {
+		panic(err)
+	}
+	const threadCount = 100
+	var wg sync.WaitGroup
+	for i := 0; i < threadCount; i++ {
+		wg.Add(1)
+		go func() {
+			runtime.LockOSThread()
+			wg.Done()
+			select {}
+		}()
+	}
+	wg.Wait()
+	mem2, err := getPagefileUsage()
+	if err != nil {
+		panic(err)
+	}
+	print((mem2 - mem1) / threadCount)
+}
diff --git a/src/runtime/time.go b/src/runtime/time.go
index abf200d..3ac60f3 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -6,14 +6,18 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"runtime/internal/sys"
+	"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
+	tb *timersBucket // the bucket the timer lives in
+	i  int           // heap index
 
 	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
 	// each time calling f(arg, now) in the timer goroutine, so f must be
@@ -25,7 +29,38 @@
 	seq    uintptr
 }
 
-var timers struct {
+// timersLen is the length of timers array.
+//
+// Ideally, this would be set to GOMAXPROCS, but that would require
+// dynamic reallocation
+//
+// The current value is a compromise between memory usage and performance
+// that should cover the majority of GOMAXPROCS values used in the wild.
+const timersLen = 64
+
+// timers contains "per-P" timer heaps.
+//
+// Timers are queued into timersBucket associated with the current P,
+// so each P may work with its own timers independently of other P instances.
+//
+// Each timersBucket may be associated with multiple P
+// if GOMAXPROCS > timersLen.
+var timers [timersLen]struct {
+	timersBucket
+
+	// The padding should eliminate false sharing
+	// between timersBucket values.
+	pad [sys.CacheLineSize - unsafe.Sizeof(timersBucket{})%sys.CacheLineSize]byte
+}
+
+func (t *timer) assignBucket() *timersBucket {
+	id := uint8(getg().m.p.ptr().id) % timersLen
+	t.tb = &timers[id].timersBucket
+	return t.tb
+}
+
+//go:notinheap
+type timersBucket struct {
 	lock         mutex
 	gp           *g
 	created      bool
@@ -51,18 +86,20 @@
 		return
 	}
 
-	t := getg().timer
+	gp := getg()
+	t := gp.timer
 	if t == nil {
 		t = new(timer)
-		getg().timer = t
+		gp.timer = t
 	}
 	*t = timer{}
 	t.when = nanotime() + ns
 	t.f = goroutineReady
-	t.arg = getg()
-	lock(&timers.lock)
-	addtimerLocked(t)
-	goparkunlock(&timers.lock, "sleep", traceEvGoSleep, 2)
+	t.arg = gp
+	tb := t.assignBucket()
+	lock(&tb.lock)
+	tb.addtimerLocked(t)
+	goparkunlock(&tb.lock, "sleep", traceEvGoSleep, 2)
 }
 
 // startTimer adds t to the timer heap.
@@ -89,87 +126,95 @@
 }
 
 func addtimer(t *timer) {
-	lock(&timers.lock)
-	addtimerLocked(t)
-	unlock(&timers.lock)
+	tb := t.assignBucket()
+	lock(&tb.lock)
+	tb.addtimerLocked(t)
+	unlock(&tb.lock)
 }
 
 // Add a timer to the heap and start or kick timerproc if the new timer is
 // earlier than any of the others.
 // Timers are locked.
-func addtimerLocked(t *timer) {
+func (tb *timersBucket) 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)
+	t.i = len(tb.t)
+	tb.t = append(tb.t, t)
+	siftupTimer(tb.t, t.i)
 	if t.i == 0 {
 		// siftup moved to top: new earliest deadline.
-		if timers.sleeping {
-			timers.sleeping = false
-			notewakeup(&timers.waitnote)
+		if tb.sleeping {
+			tb.sleeping = false
+			notewakeup(&tb.waitnote)
 		}
-		if timers.rescheduling {
-			timers.rescheduling = false
-			goready(timers.gp, 0)
+		if tb.rescheduling {
+			tb.rescheduling = false
+			goready(tb.gp, 0)
 		}
 	}
-	if !timers.created {
-		timers.created = true
-		go timerproc()
+	if !tb.created {
+		tb.created = true
+		go timerproc(tb)
 	}
 }
 
 // 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
+	if t.tb == nil {
+		// t.tb can be nil if the user created a timer
+		// directly, without invoking startTimer e.g
+		//    time.Ticker{C: c}
+		// In this case, return early without any deletion.
+		// See Issue 21874.
+		return false
+	}
 
-	lock(&timers.lock)
+	tb := t.tb
+
+	lock(&tb.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)
+	last := len(tb.t) - 1
+	if i < 0 || i > last || tb.t[i] != t {
+		unlock(&tb.lock)
 		return false
 	}
 	if i != last {
-		timers.t[i] = timers.t[last]
-		timers.t[i].i = i
+		tb.t[i] = tb.t[last]
+		tb.t[i].i = i
 	}
-	timers.t[last] = nil
-	timers.t = timers.t[:last]
+	tb.t[last] = nil
+	tb.t = tb.t[:last]
 	if i != last {
-		siftupTimer(i)
-		siftdownTimer(i)
+		siftupTimer(tb.t, i)
+		siftdownTimer(tb.t, i)
 	}
-	unlock(&timers.lock)
+	unlock(&tb.lock)
 	return true
 }
 
 // Timerproc runs the time-driven events.
-// It sleeps until the next event in the timers heap.
+// It sleeps until the next event in the tb heap.
 // If addtimer inserts a new earlier event, it wakes timerproc early.
-func timerproc() {
-	timers.gp = getg()
+func timerproc(tb *timersBucket) {
+	tb.gp = getg()
 	for {
-		lock(&timers.lock)
-		timers.sleeping = false
+		lock(&tb.lock)
+		tb.sleeping = false
 		now := nanotime()
 		delta := int64(-1)
 		for {
-			if len(timers.t) == 0 {
+			if len(tb.t) == 0 {
 				delta = -1
 				break
 			}
-			t := timers.t[0]
+			t := tb.t[0]
 			delta = t.when - now
 			if delta > 0 {
 				break
@@ -177,43 +222,43 @@
 			if t.period > 0 {
 				// leave in heap but adjust next time to fire
 				t.when += t.period * (1 + -delta/t.period)
-				siftdownTimer(0)
+				siftdownTimer(tb.t, 0)
 			} else {
 				// remove from heap
-				last := len(timers.t) - 1
+				last := len(tb.t) - 1
 				if last > 0 {
-					timers.t[0] = timers.t[last]
-					timers.t[0].i = 0
+					tb.t[0] = tb.t[last]
+					tb.t[0].i = 0
 				}
-				timers.t[last] = nil
-				timers.t = timers.t[:last]
+				tb.t[last] = nil
+				tb.t = tb.t[:last]
 				if last > 0 {
-					siftdownTimer(0)
+					siftdownTimer(tb.t, 0)
 				}
 				t.i = -1 // mark as removed
 			}
 			f := t.f
 			arg := t.arg
 			seq := t.seq
-			unlock(&timers.lock)
+			unlock(&tb.lock)
 			if raceenabled {
 				raceacquire(unsafe.Pointer(t))
 			}
 			f(arg, seq)
-			lock(&timers.lock)
+			lock(&tb.lock)
 		}
 		if delta < 0 || faketime > 0 {
 			// No timers left - put goroutine to sleep.
-			timers.rescheduling = true
-			goparkunlock(&timers.lock, "timer goroutine (idle)", traceEvGoBlock, 1)
+			tb.rescheduling = true
+			goparkunlock(&tb.lock, "timer goroutine (idle)", traceEvGoBlock, 1)
 			continue
 		}
 		// At least one timer pending. Sleep until then.
-		timers.sleeping = true
-		timers.sleepUntil = now + delta
-		noteclear(&timers.waitnote)
-		unlock(&timers.lock)
-		notetsleepg(&timers.waitnote, delta)
+		tb.sleeping = true
+		tb.sleepUntil = now + delta
+		noteclear(&tb.waitnote)
+		unlock(&tb.lock)
+		notetsleepg(&tb.waitnote, delta)
 	}
 }
 
@@ -222,28 +267,67 @@
 		return nil
 	}
 
-	lock(&timers.lock)
-	if !timers.created || len(timers.t) == 0 {
-		unlock(&timers.lock)
+	for i := range timers {
+		lock(&timers[i].lock)
+	}
+	gp := timejumpLocked()
+	for i := range timers {
+		unlock(&timers[i].lock)
+	}
+
+	return gp
+}
+
+func timejumpLocked() *g {
+	// Determine a timer bucket with minimum when.
+	var minT *timer
+	for i := range timers {
+		tb := &timers[i]
+		if !tb.created || len(tb.t) == 0 {
+			continue
+		}
+		t := tb.t[0]
+		if minT == nil || t.when < minT.when {
+			minT = t
+		}
+	}
+	if minT == nil || minT.when <= faketime {
 		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
-		}
+	faketime = minT.when
+	tb := minT.tb
+	if !tb.rescheduling {
+		return nil
 	}
-	unlock(&timers.lock)
-	return gp
+	tb.rescheduling = false
+	return tb.gp
+}
+
+func timeSleepUntil() int64 {
+	next := int64(1<<63 - 1)
+
+	// Determine minimum sleepUntil across all the timer buckets.
+	//
+	// The function can not return a precise answer,
+	// as another timer may pop in as soon as timers have been unlocked.
+	// So lock the timers one by one instead of all at once.
+	for i := range timers {
+		tb := &timers[i]
+
+		lock(&tb.lock)
+		if tb.sleeping && tb.sleepUntil < next {
+			next = tb.sleepUntil
+		}
+		unlock(&tb.lock)
+	}
+
+	return next
 }
 
 // Heap maintenance algorithms.
 
-func siftupTimer(i int) {
-	t := timers.t
+func siftupTimer(t []*timer, i int) {
 	when := t[i].when
 	tmp := t[i]
 	for i > 0 {
@@ -253,14 +337,15 @@
 		}
 		t[i] = t[p]
 		t[i].i = i
-		t[p] = tmp
-		t[p].i = p
 		i = p
 	}
+	if tmp != t[i] {
+		t[i] = tmp
+		t[i].i = i
+	}
 }
 
-func siftdownTimer(i int) {
-	t := timers.t
+func siftdownTimer(t []*timer, i int) {
 	n := len(t)
 	when := t[i].when
 	tmp := t[i]
@@ -291,10 +376,12 @@
 		}
 		t[i] = t[c]
 		t[i].i = i
-		t[c] = tmp
-		t[c].i = c
 		i = c
 	}
+	if tmp != t[i] {
+		t[i] = tmp
+		t[i].i = i
+	}
 }
 
 // Entry points for net, time to call nanotime.
@@ -309,4 +396,10 @@
 	return nanotime()
 }
 
-var startNano int64 = nanotime()
+// Monotonic times are reported as offsets from startNano.
+// We initialize startNano to nanotime() - 1 so that on systems where
+// monotonic time resolution is fairly low (e.g. Windows 2008
+// which appears to have a default resolution of 15ms),
+// we avoid ever reporting a nanotime of 0.
+// (Callers may want to use 0 as "time not set".)
+var startNano int64 = nanotime() - 1
diff --git a/src/runtime/trace.go b/src/runtime/trace.go
index 826dc9a..fab7976 100644
--- a/src/runtime/trace.go
+++ b/src/runtime/trace.go
@@ -28,8 +28,8 @@
 	traceEvProcStop          = 6  // stop of P [timestamp]
 	traceEvGCStart           = 7  // GC start [timestamp, seq, stack id]
 	traceEvGCDone            = 8  // GC done [timestamp]
-	traceEvGCScanStart       = 9  // GC mark termination start [timestamp]
-	traceEvGCScanDone        = 10 // GC mark termination done [timestamp]
+	traceEvGCSTWStart        = 9  // GC STW start [timestamp, kind]
+	traceEvGCSTWDone         = 10 // GC STW done [timestamp]
 	traceEvGCSweepStart      = 11 // GC sweep start [timestamp, stack id]
 	traceEvGCSweepDone       = 12 // GC sweep done [timestamp, swept, reclaimed]
 	traceEvGoCreate          = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
@@ -235,21 +235,21 @@
 	trace.timeStart = nanotime()
 	trace.headerWritten = false
 	trace.footerWritten = false
-	trace.strings = make(map[string]uint64)
+
+	// string to id mapping
+	//  0 : reserved for an empty string
+	//  remaining: other strings registered by traceString
 	trace.stringSeq = 0
+	trace.strings = make(map[string]uint64)
+
 	trace.seqGC = 0
 	_g_.m.startingtrace = false
 	trace.enabled = true
 
 	// Register runtime goroutine labels.
 	_, pid, bufp := traceAcquireBuffer()
-	buf := (*bufp).ptr()
-	if buf == nil {
-		buf = traceFlush(0).ptr()
-		(*bufp).set(buf)
-	}
 	for i, label := range gcMarkWorkerModeStrings[:] {
-		trace.markWorkerLabels[i], buf = traceString(buf, label)
+		trace.markWorkerLabels[i], bufp = traceString(bufp, pid, label)
 	}
 	traceReleaseBuffer(pid)
 
@@ -277,10 +277,9 @@
 
 	traceGoSched()
 
-	for _, p := range &allp {
-		if p == nil {
-			break
-		}
+	// Loop over all allocated Ps because dead Ps may still have
+	// trace buffers.
+	for _, p := range allp[:cap(allp)] {
 		buf := p.tracebuf
 		if buf != 0 {
 			traceFullQueue(buf)
@@ -320,10 +319,7 @@
 
 	// The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
 	lock(&trace.lock)
-	for _, p := range &allp {
-		if p == nil {
-			break
-		}
+	for _, p := range allp[:cap(allp)] {
 		if p.tracebuf != 0 {
 			throw("trace: non-empty trace buffer in proc")
 		}
@@ -382,7 +378,7 @@
 		trace.headerWritten = true
 		trace.lockOwner = nil
 		unlock(&trace.lock)
-		return []byte("go 1.9 trace\x00\x00\x00\x00")
+		return []byte("go 1.10 trace\x00\x00\x00")
 	}
 	// Wait for new data.
 	if trace.fullHead == 0 && !trace.shutdown {
@@ -408,9 +404,12 @@
 		var data []byte
 		data = append(data, traceEvFrequency|0<<traceArgCountShift)
 		data = traceAppend(data, uint64(freq))
-		if timers.gp != nil {
-			data = append(data, traceEvTimerGoroutine|0<<traceArgCountShift)
-			data = traceAppend(data, uint64(timers.gp.goid))
+		for i := range timers {
+			tb := &timers[i]
+			if tb.gp != nil {
+				data = append(data, traceEvTimerGoroutine|0<<traceArgCountShift)
+				data = traceAppend(data, uint64(tb.gp.goid))
+			}
 		}
 		// This will emit a bunch of full buffers, we will pick them up
 		// on the next iteration.
@@ -514,18 +513,12 @@
 	buf := (*bufp).ptr()
 	const maxSize = 2 + 5*traceBytesPerNumber // event type, length, sequence, timestamp, stack id and two add params
 	if buf == nil || len(buf.arr)-buf.pos < maxSize {
-		buf = traceFlush(traceBufPtrOf(buf)).ptr()
+		buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
 		(*bufp).set(buf)
 	}
 
 	ticks := uint64(cputicks()) / traceTickDiv
 	tickDiff := ticks - buf.lastTicks
-	if buf.pos == 0 {
-		buf.byte(traceEvBatch | 1<<traceArgCountShift)
-		buf.varint(uint64(pid))
-		buf.varint(ticks)
-		tickDiff = 0
-	}
 	buf.lastTicks = ticks
 	narg := byte(len(args))
 	if skip >= 0 {
@@ -603,7 +596,7 @@
 }
 
 // traceFlush puts buf onto stack of full buffers and returns an empty buffer.
-func traceFlush(buf traceBufPtr) traceBufPtr {
+func traceFlush(buf traceBufPtr, pid int32) traceBufPtr {
 	owner := trace.lockOwner
 	dolock := owner == nil || owner != getg().m.curg
 	if dolock {
@@ -624,34 +617,51 @@
 	bufp := buf.ptr()
 	bufp.link.set(nil)
 	bufp.pos = 0
-	bufp.lastTicks = 0
+
+	// initialize the buffer for a new batch
+	ticks := uint64(cputicks()) / traceTickDiv
+	bufp.lastTicks = ticks
+	bufp.byte(traceEvBatch | 1<<traceArgCountShift)
+	bufp.varint(uint64(pid))
+	bufp.varint(ticks)
+
 	if dolock {
 		unlock(&trace.lock)
 	}
 	return buf
 }
 
-func traceString(buf *traceBuf, s string) (uint64, *traceBuf) {
+// traceString adds a string to the trace.strings and returns the id.
+func traceString(bufp *traceBufPtr, pid int32, s string) (uint64, *traceBufPtr) {
 	if s == "" {
-		return 0, buf
+		return 0, bufp
 	}
 	if id, ok := trace.strings[s]; ok {
-		return id, buf
+		return id, bufp
 	}
 
 	trace.stringSeq++
 	id := trace.stringSeq
 	trace.strings[s] = id
 
+	// memory allocation in above may trigger tracing and
+	// cause *bufp changes. Following code now works with *bufp,
+	// so there must be no memory allocation or any activities
+	// that causes tracing after this point.
+
+	buf := (*bufp).ptr()
 	size := 1 + 2*traceBytesPerNumber + len(s)
-	if len(buf.arr)-buf.pos < size {
-		buf = traceFlush(traceBufPtrOf(buf)).ptr()
+	if buf == nil || len(buf.arr)-buf.pos < size {
+		buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+		(*bufp).set(buf)
 	}
 	buf.byte(traceEvString)
 	buf.varint(id)
 	buf.varint(uint64(len(s)))
 	buf.pos += copy(buf.arr[buf.pos:], s)
-	return id, buf
+
+	(*bufp).set(buf)
+	return id, bufp
 }
 
 // traceAppend appends v to buf in little-endian-base-128 encoding.
@@ -781,7 +791,7 @@
 // releases all memory and resets state.
 func (tab *traceStackTable) dump() {
 	var tmp [(2 + 4*traceStackSize) * traceBytesPerNumber]byte
-	buf := traceFlush(0).ptr()
+	bufp := traceFlush(0, 0)
 	for _, stk := range tab.tab {
 		stk := stk.ptr()
 		for ; stk != nil; stk = stk.link.ptr() {
@@ -791,7 +801,7 @@
 			tmpbuf = traceAppend(tmpbuf, uint64(len(frames)))
 			for _, f := range frames {
 				var frame traceFrame
-				frame, buf = traceFrameForPC(buf, f)
+				frame, bufp = traceFrameForPC(bufp, 0, f)
 				tmpbuf = traceAppend(tmpbuf, uint64(f.PC))
 				tmpbuf = traceAppend(tmpbuf, uint64(frame.funcID))
 				tmpbuf = traceAppend(tmpbuf, uint64(frame.fileID))
@@ -799,9 +809,10 @@
 			}
 			// Now copy to the buffer.
 			size := 1 + traceBytesPerNumber + len(tmpbuf)
-			if len(buf.arr)-buf.pos < size {
-				buf = traceFlush(traceBufPtrOf(buf)).ptr()
+			if buf := bufp.ptr(); len(buf.arr)-buf.pos < size {
+				bufp = traceFlush(bufp, 0)
 			}
+			buf := bufp.ptr()
 			buf.byte(traceEvStack | 3<<traceArgCountShift)
 			buf.varint(uint64(len(tmpbuf)))
 			buf.pos += copy(buf.arr[buf.pos:], tmpbuf)
@@ -809,7 +820,7 @@
 	}
 
 	lock(&trace.lock)
-	traceFullQueue(traceBufPtrOf(buf))
+	traceFullQueue(bufp)
 	unlock(&trace.lock)
 
 	tab.mem.drop()
@@ -822,7 +833,10 @@
 	line   uint64
 }
 
-func traceFrameForPC(buf *traceBuf, f Frame) (traceFrame, *traceBuf) {
+// traceFrameForPC records the frame information.
+// It may allocate memory.
+func traceFrameForPC(buf traceBufPtr, pid int32, f Frame) (traceFrame, traceBufPtr) {
+	bufp := &buf
 	var frame traceFrame
 
 	fn := f.Function
@@ -830,14 +844,14 @@
 	if len(fn) > maxLen {
 		fn = fn[len(fn)-maxLen:]
 	}
-	frame.funcID, buf = traceString(buf, fn)
+	frame.funcID, bufp = traceString(bufp, pid, fn)
 	frame.line = uint64(f.Line)
 	file := f.File
 	if len(file) > maxLen {
 		file = file[len(file)-maxLen:]
 	}
-	frame.fileID, buf = traceString(buf, file)
-	return frame, buf
+	frame.fileID, bufp = traceString(bufp, pid, file)
+	return frame, (*bufp)
 }
 
 // traceAlloc is a non-thread-safe region allocator.
@@ -924,12 +938,12 @@
 	traceEvent(traceEvGCDone, -1)
 }
 
-func traceGCScanStart() {
-	traceEvent(traceEvGCScanStart, -1)
+func traceGCSTWStart(kind int) {
+	traceEvent(traceEvGCSTWStart, -1, uint64(kind))
 }
 
-func traceGCScanDone() {
-	traceEvent(traceEvGCScanDone, -1)
+func traceGCSTWDone() {
+	traceEvent(traceEvGCSTWDone, -1)
 }
 
 // traceGCSweepStart prepares to trace a sweep loop. This does not
diff --git a/src/runtime/trace/example_test.go b/src/runtime/trace/example_test.go
new file mode 100644
index 0000000..ba96a82
--- /dev/null
+++ b/src/runtime/trace/example_test.go
@@ -0,0 +1,39 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package trace_test
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"runtime/trace"
+)
+
+// Example demonstrates the use of the trace package to trace
+// the execution of a Go program. The trace output will be
+// written to the file trace.out
+func Example() {
+	f, err := os.Create("trace.out")
+	if err != nil {
+		log.Fatalf("failed to create trace output file: %v", err)
+	}
+	defer func() {
+		if err := f.Close(); err != nil {
+			log.Fatalf("failed to close trace file: %v", err)
+		}
+	}()
+
+	if err := trace.Start(f); err != nil {
+		log.Fatalf("failed to start trace: %v", err)
+	}
+	defer trace.Stop()
+
+	// your program here
+	RunMyProgram()
+}
+
+func RunMyProgram() {
+	fmt.Printf("this function will be traced")
+}
diff --git a/src/runtime/trace/trace.go b/src/runtime/trace/trace.go
index 7cbb8a6..439f998 100644
--- a/src/runtime/trace/trace.go
+++ b/src/runtime/trace/trace.go
@@ -2,13 +2,36 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Go execution tracer.
-// The tracer captures a wide range of execution events like goroutine
-// creation/blocking/unblocking, syscall enter/exit/block, GC-related events,
-// changes of heap size, processor start/stop, etc and writes them to an io.Writer
-// in a compact form. A precise nanosecond-precision timestamp and a stack
-// trace is captured for most events. A trace can be analyzed later with
-// 'go tool trace' command.
+// Package trace contains facilities for programs to generate trace
+// for Go execution tracer.
+//
+// The execution trace captures a wide range of execution events such as
+// goroutine creation/blocking/unblocking, syscall enter/exit/block,
+// GC-related events, changes of heap size, processor start/stop, etc.
+// A precise nanosecond-precision timestamp and a stack trace is
+// captured for most events. The generated trace can be interpreted
+// using `go tool trace`.
+//
+// Tracing a Go program
+//
+// Support for tracing tests and benchmarks built with the standard
+// testing package is built into `go test`. For example, the following
+// command runs the test in the current directory and writes the trace
+// file (trace.out).
+//
+//    go test -trace=test.out
+//
+// This runtime/trace package provides APIs to add equivalent tracing
+// support to a standalone program. See the Example that demonstrates
+// how to use this API to enable tracing.
+//
+// There is also a standard HTTP interface to profiling data. Adding the
+// following line will install handlers under the /debug/pprof/trace URL
+// to download live profiles:
+//
+//     import _ "net/http/pprof"
+//
+// See the net/http/pprof package for more details.
 package trace
 
 import (
diff --git a/src/runtime/trace/trace_test.go b/src/runtime/trace/trace_test.go
index c5f64fc..997d486 100644
--- a/src/runtime/trace/trace_test.go
+++ b/src/runtime/trace/trace_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"flag"
+	"internal/race"
 	"internal/trace"
 	"io"
 	"io/ioutil"
@@ -14,6 +15,7 @@
 	"os"
 	"runtime"
 	. "runtime/trace"
+	"strconv"
 	"sync"
 	"testing"
 	"time"
@@ -23,6 +25,61 @@
 	saveTraces = flag.Bool("savetraces", false, "save traces collected by tests")
 )
 
+// TestEventBatch tests Flush calls that happen during Start
+// don't produce corrupted traces.
+func TestEventBatch(t *testing.T) {
+	if race.Enabled {
+		t.Skip("skipping in race mode")
+	}
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	// During Start, bunch of records are written to reflect the current
+	// snapshot of the program, including state of each goroutines.
+	// And some string constants are written to the trace to aid trace
+	// parsing. This test checks Flush of the buffer occurred during
+	// this process doesn't cause corrupted traces.
+	// When a Flush is called during Start is complicated
+	// so we test with a range of number of goroutines hoping that one
+	// of them triggers Flush.
+	// This range was chosen to fill up a ~64KB buffer with traceEvGoCreate
+	// and traceEvGoWaiting events (12~13bytes per goroutine).
+	for g := 4950; g < 5050; g++ {
+		n := g
+		t.Run("G="+strconv.Itoa(n), func(t *testing.T) {
+			var wg sync.WaitGroup
+			wg.Add(n)
+
+			in := make(chan bool, 1000)
+			for i := 0; i < n; i++ {
+				go func() {
+					<-in
+					wg.Done()
+				}()
+			}
+			buf := new(bytes.Buffer)
+			if err := Start(buf); err != nil {
+				t.Fatalf("failed to start tracing: %v", err)
+			}
+
+			for i := 0; i < n; i++ {
+				in <- true
+			}
+			wg.Wait()
+			Stop()
+
+			_, err := trace.Parse(buf, "")
+			if err == trace.ErrTimeOrder {
+				t.Skipf("skipping trace: %v", err)
+			}
+
+			if err != nil {
+				t.Fatalf("failed to parse trace: %v", err)
+			}
+		})
+	}
+}
+
 func TestTraceStartStop(t *testing.T) {
 	buf := new(bytes.Buffer)
 	if err := Start(buf); err != nil {
@@ -70,20 +127,20 @@
 }
 
 func parseTrace(t *testing.T, r io.Reader) ([]*trace.Event, map[uint64]*trace.GDesc) {
-	events, err := trace.Parse(r, "")
+	res, err := trace.Parse(r, "")
 	if err == trace.ErrTimeOrder {
 		t.Skipf("skipping trace: %v", err)
 	}
 	if err != nil {
 		t.Fatalf("failed to parse trace: %v", err)
 	}
-	gs := trace.GoroutineStats(events)
+	gs := trace.GoroutineStats(res.Events)
 	for goid := range gs {
 		// We don't do any particular checks on the result at the moment.
 		// But still check that RelatedGoroutines does not crash, hang, etc.
-		_ = trace.RelatedGoroutines(events, goid)
+		_ = trace.RelatedGoroutines(res.Events, goid)
 	}
-	return events, gs
+	return res.Events, gs
 }
 
 func testBrokenTimestamps(t *testing.T, data []byte) {
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index c74d438..747176c 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -43,6 +43,7 @@
 	morestackPC          uintptr
 	mstartPC             uintptr
 	rt0_goPC             uintptr
+	asmcgocallPC         uintptr
 	sigpanicPC           uintptr
 	runfinqPC            uintptr
 	bgsweepPC            uintptr
@@ -70,6 +71,7 @@
 	morestackPC = funcPC(morestack)
 	mstartPC = funcPC(mstart)
 	rt0_goPC = funcPC(rt0_go)
+	asmcgocallPC = funcPC(asmcgocall)
 	sigpanicPC = funcPC(sigpanic)
 	runfinqPC = funcPC(runfinq)
 	bgsweepPC = funcPC(bgsweep)
@@ -184,6 +186,7 @@
 	cgoCtxt := gp.cgoCtxt
 	printing := pcbuf == nil && callback == nil
 	_defer := gp._defer
+	elideWrapper := false
 
 	for _defer != nil && _defer.sp == _NoArgs {
 		_defer = _defer.link
@@ -203,8 +206,11 @@
 
 	f := findfunc(frame.pc)
 	if !f.valid() {
-		if callback != nil {
+		if callback != nil || printing {
 			print("runtime: unknown pc ", hex(frame.pc), "\n")
+			tracebackHexdump(gp.stack, &frame, 0)
+		}
+		if callback != nil {
 			throw("unknown pc")
 		}
 		return 0
@@ -247,7 +253,7 @@
 			}
 		}
 		var flr funcInfo
-		if topofstack(f) {
+		if topofstack(f, gp.m != nil && gp == gp.m.g0) {
 			frame.lr = 0
 			flr = funcInfo{}
 		} else if usesLR && f.entry == jmpdeferPC {
@@ -280,8 +286,19 @@
 				// 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 {
+				doPrint := printing
+				if doPrint && gp.m.incgo {
+					// We can inject sigpanic
+					// calls directly into C code,
+					// in which case we'll see a C
+					// return PC. Don't complain.
+					doPrint = false
+				}
+				if callback != nil || doPrint {
 					print("runtime: unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n")
+					tracebackHexdump(gp.stack, &frame, lrPtr)
+				}
+				if callback != nil {
 					throw("unknown caller pc")
 				}
 			}
@@ -386,8 +403,15 @@
 		}
 
 		if printing {
-			// assume skip=0 for printing
-			if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0) {
+			// assume skip=0 for printing.
+			//
+			// Never elide wrappers if we haven't printed
+			// any frames. And don't elide wrappers that
+			// called panic rather than the wrapped
+			// function. Otherwise, leave them out.
+			name := funcname(f)
+			nextElideWrapper := elideWrapperCalling(name)
+			if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, elideWrapper && nprint != 0) {
 				// Print during crash.
 				//	main(0x1, 0x2, 0x3)
 				//		/home/rsc/go/src/runtime/x.go:23 +0xf
@@ -411,7 +435,6 @@
 						ix = inltree[ix].parent
 					}
 				}
-				name := funcname(f)
 				if name == "runtime.gopanic" {
 					name = "panic"
 				}
@@ -438,6 +461,7 @@
 				print("\n")
 				nprint++
 			}
+			elideWrapper = nextElideWrapper
 		}
 		n++
 
@@ -647,7 +671,7 @@
 	// Show what created goroutine, except main goroutine (goid 1).
 	pc := gp.gopc
 	f := findfunc(pc)
-	if f.valid() && showframe(f, gp, false) && gp.goid != 1 {
+	if f.valid() && showframe(f, gp, false, false) && gp.goid != 1 {
 		print("created by ", funcname(f), "\n")
 		tracepc := pc // back up to CALL instruction for funcline.
 		if pc > f.entry {
@@ -714,7 +738,7 @@
 
 func callers(skip int, pcbuf []uintptr) int {
 	sp := getcallersp(unsafe.Pointer(&skip))
-	pc := getcallerpc(unsafe.Pointer(&skip))
+	pc := getcallerpc()
 	gp := getg()
 	var n int
 	systemstack(func() {
@@ -727,12 +751,28 @@
 	return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0)
 }
 
-func showframe(f funcInfo, gp *g, firstFrame bool) bool {
+func showframe(f funcInfo, gp *g, firstFrame, elideWrapper bool) bool {
 	g := getg()
 	if g.m.throwing > 0 && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig.ptr()) {
 		return true
 	}
 	level, _, _ := gotraceback()
+	if level > 1 {
+		// Show all frames.
+		return true
+	}
+
+	if !f.valid() {
+		return false
+	}
+
+	if elideWrapper {
+		file, _ := funcline(f, f.entry)
+		if file == "<autogenerated>" {
+			return false
+		}
+	}
+
 	name := funcname(f)
 
 	// Special case: always show runtime.gopanic frame
@@ -744,7 +784,7 @@
 		return true
 	}
 
-	return level > 1 || f.valid() && contains(name, ".") && (!hasprefix(name, "runtime.") || isExportedRuntime(name))
+	return contains(name, ".") && (!hasprefix(name, "runtime.") || isExportedRuntime(name))
 }
 
 // isExportedRuntime reports whether name is an exported runtime function.
@@ -754,6 +794,14 @@
 	return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
 }
 
+// elideWrapperCalling returns whether a wrapper function that called
+// function "name" should be elided from stack traces.
+func elideWrapperCalling(name string) bool {
+	// If the wrapper called a panic function instead of the
+	// wrapped function, we want to include it in stacks.
+	return !(name == "runtime.gopanic" || name == "runtime.sigpanic" || name == "runtime.panicwrap")
+}
+
 var gStatusStrings = [...]string{
 	_Gidle:      "idle",
 	_Grunnable:  "runnable",
@@ -795,7 +843,7 @@
 	if waitfor >= 1 {
 		print(", ", waitfor, " minutes")
 	}
-	if gp.lockedm != nil {
+	if gp.lockedm != 0 {
 		print(", locked to thread")
 	}
 	print("]:\n")
@@ -834,15 +882,68 @@
 	unlock(&allglock)
 }
 
+// tracebackHexdump hexdumps part of stk around frame.sp and frame.fp
+// for debugging purposes. If the address bad is included in the
+// hexdumped range, it will mark it as well.
+func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
+	const expand = 32 * sys.PtrSize
+	const maxExpand = 256 * sys.PtrSize
+	// Start around frame.sp.
+	lo, hi := frame.sp, frame.sp
+	// Expand to include frame.fp.
+	if frame.fp != 0 && frame.fp < lo {
+		lo = frame.fp
+	}
+	if frame.fp != 0 && frame.fp > hi {
+		hi = frame.fp
+	}
+	// Expand a bit more.
+	lo, hi = lo-expand, hi+expand
+	// But don't go too far from frame.sp.
+	if lo < frame.sp-maxExpand {
+		lo = frame.sp - maxExpand
+	}
+	if hi > frame.sp+maxExpand {
+		hi = frame.sp + maxExpand
+	}
+	// And don't go outside the stack bounds.
+	if lo < stk.lo {
+		lo = stk.lo
+	}
+	if hi > stk.hi {
+		hi = stk.hi
+	}
+
+	// Print the hex dump.
+	print("stack: frame={sp:", hex(frame.sp), ", fp:", hex(frame.fp), "} stack=[", hex(stk.lo), ",", hex(stk.hi), ")\n")
+	hexdumpWords(lo, hi, func(p uintptr) byte {
+		switch p {
+		case frame.fp:
+			return '>'
+		case frame.sp:
+			return '<'
+		case bad:
+			return '!'
+		}
+		return 0
+	})
+}
+
 // Does f mark the top of a goroutine stack?
-func topofstack(f funcInfo) bool {
+func topofstack(f funcInfo, g0 bool) bool {
 	pc := f.entry
 	return pc == goexitPC ||
 		pc == mstartPC ||
 		pc == mcallPC ||
 		pc == morestackPC ||
 		pc == rt0_goPC ||
-		externalthreadhandlerp != 0 && pc == externalthreadhandlerp
+		externalthreadhandlerp != 0 && pc == externalthreadhandlerp ||
+		// asmcgocall is TOS on the system stack because it
+		// switches to the system stack, but in this case we
+		// can come back to the regular stack and still want
+		// to be able to unwind through the call that appeared
+		// on the regular stack.
+		(g0 && pc == asmcgocallPC)
 }
 
 // isSystemGoroutine reports whether the goroutine g must be omitted in
diff --git a/src/runtime/type.go b/src/runtime/type.go
index bf54d54..b3df335 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -655,15 +655,15 @@
 		if len(st.fields) != len(sv.fields) {
 			return false
 		}
+		if st.pkgPath.name() != sv.pkgPath.name() {
+			return false
+		}
 		for i := range st.fields {
 			tf := &st.fields[i]
 			vf := &sv.fields[i]
 			if tf.name.name() != vf.name.name() {
 				return false
 			}
-			if tf.name.pkgPath() != vf.name.pkgPath() {
-				return false
-			}
 			if !typesEqual(tf.typ, vf.typ, seen) {
 				return false
 			}
diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go
new file mode 100644
index 0000000..61872e3
--- /dev/null
+++ b/src/runtime/vdso_linux.go
@@ -0,0 +1,281 @@
+// 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 linux
+// +build 386 amd64
+
+package runtime
+
+import "unsafe"
+
+// 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/tools/testing/selftests/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
+
+const (
+	_AT_SYSINFO_EHDR = 33
+
+	_PT_LOAD    = 1 /* Loadable program segment */
+	_PT_DYNAMIC = 2 /* Dynamic linking information */
+
+	_DT_NULL     = 0          /* Marks end of dynamic section */
+	_DT_HASH     = 4          /* Dynamic symbol hash table */
+	_DT_STRTAB   = 5          /* Address of string table */
+	_DT_SYMTAB   = 6          /* Address of symbol table */
+	_DT_GNU_HASH = 0x6ffffef5 /* GNU-style dynamic symbol hash table */
+	_DT_VERSYM   = 0x6ffffff0
+	_DT_VERDEF   = 0x6ffffffc
+
+	_VER_FLG_BASE = 0x1 /* Version definition of file itself */
+
+	_SHN_UNDEF = 0 /* Undefined section */
+
+	_SHT_DYNSYM = 11 /* Dynamic linker symbol table */
+
+	_STT_FUNC = 2 /* Symbol is a code object */
+
+	_STB_GLOBAL = 1 /* Global symbol */
+	_STB_WEAK   = 2 /* Weak symbol */
+
+	_EI_NIDENT = 16
+
+	// Maximum indices for the array types used when traversing the vDSO ELF structures.
+	// Computed from architecture-specific max provided by vdso_linux_*.go
+	vdsoSymTabSize     = vdsoArrayMax / unsafe.Sizeof(elfSym{})
+	vdsoDynSize        = vdsoArrayMax / unsafe.Sizeof(elfDyn{})
+	vdsoSymStringsSize = vdsoArrayMax     // byte
+	vdsoVerSymSize     = vdsoArrayMax / 2 // uint16
+	vdsoHashSize       = vdsoArrayMax / 4 // uint32
+
+	// vdsoBloomSizeScale is a scaling factor for gnuhash tables which are uint32 indexed,
+	// but contain uintptrs
+	vdsoBloomSizeScale = unsafe.Sizeof(uintptr(0)) / 4 // uint32
+)
+
+/* How to extract and insert information held in the st_info field.  */
+func _ELF_ST_BIND(val byte) byte { return val >> 4 }
+func _ELF_ST_TYPE(val byte) byte { return val & 0xf }
+
+type symbol_key struct {
+	name     string
+	sym_hash uint32
+	gnu_hash uint32
+	ptr      *uintptr
+}
+
+type version_key struct {
+	version  string
+	ver_hash uint32
+}
+
+type vdso_info struct {
+	valid bool
+
+	/* Load information */
+	load_addr   uintptr
+	load_offset uintptr /* load_addr - recorded vaddr */
+
+	/* Symbol table */
+	symtab     *[vdsoSymTabSize]elfSym
+	symstrings *[vdsoSymStringsSize]byte
+	chain      []uint32
+	bucket     []uint32
+	symOff     uint32
+	isGNUHash  bool
+
+	/* Version table */
+	versym *[vdsoVerSymSize]uint16
+	verdef *elfVerdef
+}
+
+var linux26 = version_key{"LINUX_2.6", 0x3ae75f6}
+
+// see vdso_linux_*.go for sym_keys[] and __vdso_* vars
+
+func vdso_init_from_sysinfo_ehdr(info *vdso_info, hdr *elfEhdr) {
+	info.valid = false
+	info.load_addr = uintptr(unsafe.Pointer(hdr))
+
+	pt := unsafe.Pointer(info.load_addr + uintptr(hdr.e_phoff))
+
+	// We need two things from the segment table: the load offset
+	// and the dynamic table.
+	var found_vaddr bool
+	var dyn *[vdsoDynSize]elfDyn
+	for i := uint16(0); i < hdr.e_phnum; i++ {
+		pt := (*elfPhdr)(add(pt, uintptr(i)*unsafe.Sizeof(elfPhdr{})))
+		switch pt.p_type {
+		case _PT_LOAD:
+			if !found_vaddr {
+				found_vaddr = true
+				info.load_offset = info.load_addr + uintptr(pt.p_offset-pt.p_vaddr)
+			}
+
+		case _PT_DYNAMIC:
+			dyn = (*[vdsoDynSize]elfDyn)(unsafe.Pointer(info.load_addr + uintptr(pt.p_offset)))
+		}
+	}
+
+	if !found_vaddr || dyn == nil {
+		return // Failed
+	}
+
+	// Fish out the useful bits of the dynamic table.
+
+	var hash, gnuhash *[vdsoHashSize]uint32
+	info.symstrings = nil
+	info.symtab = nil
+	info.versym = nil
+	info.verdef = nil
+	for i := 0; dyn[i].d_tag != _DT_NULL; i++ {
+		dt := &dyn[i]
+		p := info.load_offset + uintptr(dt.d_val)
+		switch dt.d_tag {
+		case _DT_STRTAB:
+			info.symstrings = (*[vdsoSymStringsSize]byte)(unsafe.Pointer(p))
+		case _DT_SYMTAB:
+			info.symtab = (*[vdsoSymTabSize]elfSym)(unsafe.Pointer(p))
+		case _DT_HASH:
+			hash = (*[vdsoHashSize]uint32)(unsafe.Pointer(p))
+		case _DT_GNU_HASH:
+			gnuhash = (*[vdsoHashSize]uint32)(unsafe.Pointer(p))
+		case _DT_VERSYM:
+			info.versym = (*[vdsoVerSymSize]uint16)(unsafe.Pointer(p))
+		case _DT_VERDEF:
+			info.verdef = (*elfVerdef)(unsafe.Pointer(p))
+		}
+	}
+
+	if info.symstrings == nil || info.symtab == nil || (hash == nil && gnuhash == nil) {
+		return // Failed
+	}
+
+	if info.verdef == nil {
+		info.versym = nil
+	}
+
+	if gnuhash != nil {
+		// Parse the GNU hash table header.
+		nbucket := gnuhash[0]
+		info.symOff = gnuhash[1]
+		bloomSize := gnuhash[2]
+		info.bucket = gnuhash[4+bloomSize*uint32(vdsoBloomSizeScale):][:nbucket]
+		info.chain = gnuhash[4+bloomSize*uint32(vdsoBloomSizeScale)+nbucket:]
+		info.isGNUHash = true
+	} else {
+		// Parse the hash table header.
+		nbucket := hash[0]
+		nchain := hash[1]
+		info.bucket = hash[2 : 2+nbucket]
+		info.chain = hash[2+nbucket : 2+nbucket+nchain]
+	}
+
+	// That's all we need.
+	info.valid = true
+}
+
+func vdso_find_version(info *vdso_info, ver *version_key) int32 {
+	if !info.valid {
+		return 0
+	}
+
+	def := info.verdef
+	for {
+		if def.vd_flags&_VER_FLG_BASE == 0 {
+			aux := (*elfVerdaux)(add(unsafe.Pointer(def), uintptr(def.vd_aux)))
+			if def.vd_hash == ver.ver_hash && ver.version == gostringnocopy(&info.symstrings[aux.vda_name]) {
+				return int32(def.vd_ndx & 0x7fff)
+			}
+		}
+
+		if def.vd_next == 0 {
+			break
+		}
+		def = (*elfVerdef)(add(unsafe.Pointer(def), uintptr(def.vd_next)))
+	}
+
+	return -1 // cannot match any version
+}
+
+func vdso_parse_symbols(info *vdso_info, version int32) {
+	if !info.valid {
+		return
+	}
+
+	apply := func(symIndex uint32, k symbol_key) bool {
+		sym := &info.symtab[symIndex]
+		typ := _ELF_ST_TYPE(sym.st_info)
+		bind := _ELF_ST_BIND(sym.st_info)
+		if typ != _STT_FUNC || bind != _STB_GLOBAL && bind != _STB_WEAK || sym.st_shndx == _SHN_UNDEF {
+			return false
+		}
+		if k.name != gostringnocopy(&info.symstrings[sym.st_name]) {
+			return false
+		}
+
+		// Check symbol version.
+		if info.versym != nil && version != 0 && int32(info.versym[symIndex]&0x7fff) != version {
+			return false
+		}
+
+		*k.ptr = info.load_offset + uintptr(sym.st_value)
+		return true
+	}
+
+	if !info.isGNUHash {
+		// Old-style DT_HASH table.
+		for _, k := range sym_keys {
+			for chain := info.bucket[k.sym_hash%uint32(len(info.bucket))]; chain != 0; chain = info.chain[chain] {
+				if apply(chain, k) {
+					break
+				}
+			}
+		}
+		return
+	}
+
+	// New-style DT_GNU_HASH table.
+	for _, k := range sym_keys {
+		symIndex := info.bucket[k.gnu_hash%uint32(len(info.bucket))]
+		if symIndex < info.symOff {
+			continue
+		}
+		for ; ; symIndex++ {
+			hash := info.chain[symIndex-info.symOff]
+			if hash|1 == k.gnu_hash|1 {
+				// Found a hash match.
+				if apply(symIndex, k) {
+					break
+				}
+			}
+			if hash&1 != 0 {
+				// End of chain.
+				break
+			}
+		}
+	}
+}
+
+func archauxv(tag, val uintptr) {
+	switch tag {
+	case _AT_SYSINFO_EHDR:
+		if val == 0 {
+			// Something went wrong
+			return
+		}
+		var info vdso_info
+		// TODO(rsc): I don't understand why the compiler thinks info escapes
+		// when passed to the three functions below.
+		info1 := (*vdso_info)(noescape(unsafe.Pointer(&info)))
+		vdso_init_from_sysinfo_ehdr(info1, (*elfEhdr)(unsafe.Pointer(val)))
+		vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
+	}
+}
diff --git a/src/runtime/vdso_linux_386.go b/src/runtime/vdso_linux_386.go
new file mode 100644
index 0000000..74ad953
--- /dev/null
+++ b/src/runtime/vdso_linux_386.go
@@ -0,0 +1,93 @@
+// 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
+
+// ELF32 structure definitions for use by the Linux vDSO loader
+
+type elfSym struct {
+	st_name  uint32
+	st_value uint32
+	st_size  uint32
+	st_info  byte
+	st_other byte
+	st_shndx uint16
+}
+
+type elfVerdef struct {
+	vd_version uint16 /* Version revision */
+	vd_flags   uint16 /* Version information */
+	vd_ndx     uint16 /* Version Index */
+	vd_cnt     uint16 /* Number of associated aux entries */
+	vd_hash    uint32 /* Version name hash value */
+	vd_aux     uint32 /* Offset in bytes to verdaux array */
+	vd_next    uint32 /* Offset in bytes to next verdef entry */
+}
+
+type elfEhdr struct {
+	e_ident     [_EI_NIDENT]byte /* Magic number and other info */
+	e_type      uint16           /* Object file type */
+	e_machine   uint16           /* Architecture */
+	e_version   uint32           /* Object file version */
+	e_entry     uint32           /* Entry point virtual address */
+	e_phoff     uint32           /* Program header table file offset */
+	e_shoff     uint32           /* Section header table file offset */
+	e_flags     uint32           /* Processor-specific flags */
+	e_ehsize    uint16           /* ELF header size in bytes */
+	e_phentsize uint16           /* Program header table entry size */
+	e_phnum     uint16           /* Program header table entry count */
+	e_shentsize uint16           /* Section header table entry size */
+	e_shnum     uint16           /* Section header table entry count */
+	e_shstrndx  uint16           /* Section header string table index */
+}
+
+type elfPhdr struct {
+	p_type   uint32 /* Segment type */
+	p_offset uint32 /* Segment file offset */
+	p_vaddr  uint32 /* Segment virtual address */
+	p_paddr  uint32 /* Segment physical address */
+	p_filesz uint32 /* Segment size in file */
+	p_memsz  uint32 /* Segment size in memory */
+	p_flags  uint32 /* Segment flags */
+	p_align  uint32 /* Segment alignment */
+}
+
+type elfShdr struct {
+	sh_name      uint32 /* Section name (string tbl index) */
+	sh_type      uint32 /* Section type */
+	sh_flags     uint32 /* Section flags */
+	sh_addr      uint32 /* Section virtual addr at execution */
+	sh_offset    uint32 /* Section file offset */
+	sh_size      uint32 /* Section size in bytes */
+	sh_link      uint32 /* Link to another section */
+	sh_info      uint32 /* Additional section information */
+	sh_addralign uint32 /* Section alignment */
+	sh_entsize   uint32 /* Entry size if section holds table */
+}
+
+type elfDyn struct {
+	d_tag int32  /* Dynamic entry type */
+	d_val uint32 /* Integer value */
+}
+
+type elfVerdaux struct {
+	vda_name uint32 /* Version or dependency names */
+	vda_next uint32 /* Offset in bytes to next verdaux entry */
+}
+
+const (
+	// vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
+	// See cmd/compile/internal/x86/galign.go arch.MAXWIDTH initialization, but must also
+	// be constrained to max +ve int.
+	vdsoArrayMax = 1<<31 - 1
+)
+
+var sym_keys = []symbol_key{
+	{"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318, &__vdso_clock_gettime_sym},
+}
+
+// initialize to fall back to syscall
+var (
+	__vdso_clock_gettime_sym uintptr = 0
+)
diff --git a/src/runtime/vdso_linux_amd64.go b/src/runtime/vdso_linux_amd64.go
index 8a970df..0bbe5c2 100644
--- a/src/runtime/vdso_linux_amd64.go
+++ b/src/runtime/vdso_linux_amd64.go
@@ -4,51 +4,9 @@
 
 package runtime
 
-import "unsafe"
+// ELF64 structure definitions for use by the Linux vDSO loader
 
-// 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
-
-const (
-	_AT_SYSINFO_EHDR = 33
-
-	_PT_LOAD    = 1 /* Loadable program segment */
-	_PT_DYNAMIC = 2 /* Dynamic linking information */
-
-	_DT_NULL   = 0 /* Marks end of dynamic section */
-	_DT_HASH   = 4 /* Dynamic symbol hash table */
-	_DT_STRTAB = 5 /* Address of string table */
-	_DT_SYMTAB = 6 /* Address of symbol table */
-	_DT_VERSYM = 0x6ffffff0
-	_DT_VERDEF = 0x6ffffffc
-
-	_VER_FLG_BASE = 0x1 /* Version definition of file itself */
-
-	_SHN_UNDEF = 0 /* Undefined section */
-
-	_SHT_DYNSYM = 11 /* Dynamic linker symbol table */
-
-	_STT_FUNC = 2 /* Symbol is a code object */
-
-	_STB_GLOBAL = 1 /* Global symbol */
-	_STB_WEAK   = 2 /* Weak symbol */
-
-	_EI_NIDENT = 16
-)
-
-/* How to extract and insert information held in the st_info field.  */
-func _ELF64_ST_BIND(val byte) byte { return val >> 4 }
-func _ELF64_ST_TYPE(val byte) byte { return val & 0xf }
-
-type elf64Sym struct {
+type elfSym struct {
 	st_name  uint32
 	st_info  byte
 	st_other byte
@@ -57,7 +15,7 @@
 	st_size  uint64
 }
 
-type elf64Verdef struct {
+type elfVerdef struct {
 	vd_version uint16 /* Version revision */
 	vd_flags   uint16 /* Version information */
 	vd_ndx     uint16 /* Version Index */
@@ -67,7 +25,7 @@
 	vd_next    uint32 /* Offset in bytes to next verdef entry */
 }
 
-type elf64Ehdr struct {
+type elfEhdr struct {
 	e_ident     [_EI_NIDENT]byte /* Magic number and other info */
 	e_type      uint16           /* Object file type */
 	e_machine   uint16           /* Architecture */
@@ -84,7 +42,7 @@
 	e_shstrndx  uint16           /* Section header string table index */
 }
 
-type elf64Phdr struct {
+type elfPhdr struct {
 	p_type   uint32 /* Segment type */
 	p_flags  uint32 /* Segment flags */
 	p_offset uint64 /* Segment file offset */
@@ -95,7 +53,7 @@
 	p_align  uint64 /* Segment alignment */
 }
 
-type elf64Shdr struct {
+type elfShdr struct {
 	sh_name      uint32 /* Section name (string tbl index) */
 	sh_type      uint32 /* Section type */
 	sh_flags     uint64 /* Section flags */
@@ -108,56 +66,26 @@
 	sh_entsize   uint64 /* Entry size if section holds table */
 }
 
-type elf64Dyn struct {
+type elfDyn struct {
 	d_tag int64  /* Dynamic entry type */
 	d_val uint64 /* Integer value */
 }
 
-type elf64Verdaux struct {
+type elfVerdaux struct {
 	vda_name uint32 /* Version or dependency names */
 	vda_next uint32 /* Offset in bytes to next verdaux entry */
 }
 
-type elf64Auxv struct {
-	a_type uint64 /* Entry type */
-	a_val  uint64 /* Integer value */
-}
-
-type symbol_key struct {
-	name     string
-	sym_hash uint32
-	ptr      *uintptr
-}
-
-type version_key struct {
-	version  string
-	ver_hash uint32
-}
-
-type vdso_info struct {
-	valid bool
-
-	/* Load information */
-	load_addr   uintptr
-	load_offset uintptr /* load_addr - recorded vaddr */
-
-	/* Symbol table */
-	symtab     *[1 << 32]elf64Sym
-	symstrings *[1 << 32]byte
-	chain      []uint32
-	bucket     []uint32
-
-	/* Version table */
-	versym *[1 << 32]uint16
-	verdef *elf64Verdef
-}
-
-var linux26 = version_key{"LINUX_2.6", 0x3ae75f6}
+const (
+	// vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
+	// See cmd/compile/internal/amd64/galign.go arch.MAXWIDTH initialization.
+	vdsoArrayMax = 1<<50 - 1
+)
 
 var sym_keys = []symbol_key{
-	{"__vdso_time", 0xa33c485, &__vdso_time_sym},
-	{"__vdso_gettimeofday", 0x315ca59, &__vdso_gettimeofday_sym},
-	{"__vdso_clock_gettime", 0xd35ec75, &__vdso_clock_gettime_sym},
+	{"__vdso_time", 0xa33c485, 0x821e8e0d, &__vdso_time_sym},
+	{"__vdso_gettimeofday", 0x315ca59, 0xb01bca00, &__vdso_gettimeofday_sym},
+	{"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318, &__vdso_clock_gettime_sym},
 }
 
 // initialize with vsyscall fallbacks
@@ -166,141 +94,3 @@
 	__vdso_gettimeofday_sym  uintptr = 0xffffffffff600000
 	__vdso_clock_gettime_sym uintptr = 0
 )
-
-func vdso_init_from_sysinfo_ehdr(info *vdso_info, hdr *elf64Ehdr) {
-	info.valid = false
-	info.load_addr = uintptr(unsafe.Pointer(hdr))
-
-	pt := unsafe.Pointer(info.load_addr + uintptr(hdr.e_phoff))
-
-	// We need two things from the segment table: the load offset
-	// and the dynamic table.
-	var found_vaddr bool
-	var dyn *[1 << 20]elf64Dyn
-	for i := uint16(0); i < hdr.e_phnum; i++ {
-		pt := (*elf64Phdr)(add(pt, uintptr(i)*unsafe.Sizeof(elf64Phdr{})))
-		switch pt.p_type {
-		case _PT_LOAD:
-			if !found_vaddr {
-				found_vaddr = true
-				info.load_offset = info.load_addr + uintptr(pt.p_offset-pt.p_vaddr)
-			}
-
-		case _PT_DYNAMIC:
-			dyn = (*[1 << 20]elf64Dyn)(unsafe.Pointer(info.load_addr + uintptr(pt.p_offset)))
-		}
-	}
-
-	if !found_vaddr || dyn == nil {
-		return // Failed
-	}
-
-	// Fish out the useful bits of the dynamic table.
-
-	var hash *[1 << 30]uint32
-	hash = nil
-	info.symstrings = nil
-	info.symtab = nil
-	info.versym = nil
-	info.verdef = nil
-	for i := 0; dyn[i].d_tag != _DT_NULL; i++ {
-		dt := &dyn[i]
-		p := info.load_offset + uintptr(dt.d_val)
-		switch dt.d_tag {
-		case _DT_STRTAB:
-			info.symstrings = (*[1 << 32]byte)(unsafe.Pointer(p))
-		case _DT_SYMTAB:
-			info.symtab = (*[1 << 32]elf64Sym)(unsafe.Pointer(p))
-		case _DT_HASH:
-			hash = (*[1 << 30]uint32)(unsafe.Pointer(p))
-		case _DT_VERSYM:
-			info.versym = (*[1 << 32]uint16)(unsafe.Pointer(p))
-		case _DT_VERDEF:
-			info.verdef = (*elf64Verdef)(unsafe.Pointer(p))
-		}
-	}
-
-	if info.symstrings == nil || info.symtab == nil || hash == nil {
-		return // Failed
-	}
-
-	if info.verdef == nil {
-		info.versym = nil
-	}
-
-	// Parse the hash table header.
-	nbucket := hash[0]
-	nchain := hash[1]
-	info.bucket = hash[2 : 2+nbucket]
-	info.chain = hash[2+nbucket : 2+nbucket+nchain]
-
-	// That's all we need.
-	info.valid = true
-}
-
-func vdso_find_version(info *vdso_info, ver *version_key) int32 {
-	if !info.valid {
-		return 0
-	}
-
-	def := info.verdef
-	for {
-		if def.vd_flags&_VER_FLG_BASE == 0 {
-			aux := (*elf64Verdaux)(add(unsafe.Pointer(def), uintptr(def.vd_aux)))
-			if def.vd_hash == ver.ver_hash && ver.version == gostringnocopy(&info.symstrings[aux.vda_name]) {
-				return int32(def.vd_ndx & 0x7fff)
-			}
-		}
-
-		if def.vd_next == 0 {
-			break
-		}
-		def = (*elf64Verdef)(add(unsafe.Pointer(def), uintptr(def.vd_next)))
-	}
-
-	return -1 // cannot match any version
-}
-
-func vdso_parse_symbols(info *vdso_info, version int32) {
-	if !info.valid {
-		return
-	}
-
-	for _, k := range sym_keys {
-		for chain := info.bucket[k.sym_hash%uint32(len(info.bucket))]; chain != 0; chain = info.chain[chain] {
-			sym := &info.symtab[chain]
-			typ := _ELF64_ST_TYPE(sym.st_info)
-			bind := _ELF64_ST_BIND(sym.st_info)
-			if typ != _STT_FUNC || bind != _STB_GLOBAL && bind != _STB_WEAK || sym.st_shndx == _SHN_UNDEF {
-				continue
-			}
-			if k.name != gostringnocopy(&info.symstrings[sym.st_name]) {
-				continue
-			}
-
-			// Check symbol version.
-			if info.versym != nil && version != 0 && int32(info.versym[chain]&0x7fff) != version {
-				continue
-			}
-
-			*k.ptr = info.load_offset + uintptr(sym.st_value)
-			break
-		}
-	}
-}
-
-func archauxv(tag, val uintptr) {
-	switch tag {
-	case _AT_SYSINFO_EHDR:
-		if val == 0 {
-			// Something went wrong
-			return
-		}
-		var info vdso_info
-		// TODO(rsc): I don't understand why the compiler thinks info escapes
-		// when passed to the three functions below.
-		info1 := (*vdso_info)(noescape(unsafe.Pointer(&info)))
-		vdso_init_from_sysinfo_ehdr(info1, (*elf64Ehdr)(unsafe.Pointer(val)))
-		vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
-	}
-}
diff --git a/src/runtime/vdso_linux_test.go b/src/runtime/vdso_linux_test.go
new file mode 100644
index 0000000..f507ee9
--- /dev/null
+++ b/src/runtime/vdso_linux_test.go
@@ -0,0 +1,63 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build 386 amd64
+
+package runtime_test
+
+import (
+	"testing"
+	"time"
+	_ "unsafe"
+)
+
+// These tests are a little risky because they overwrite the __vdso_clock_gettime_sym value.
+// It's normally initialized at startup and remains unchanged after that.
+
+//go:linkname __vdso_clock_gettime_sym runtime.__vdso_clock_gettime_sym
+var __vdso_clock_gettime_sym uintptr
+
+func TestClockVDSOAndFallbackPaths(t *testing.T) {
+	// Check that we can call walltime() and nanotime() with and without their (1st) fast-paths.
+	// This just checks that fast and fallback paths can be called, rather than testing their
+	// results.
+	//
+	// Call them indirectly via time.Now(), so we don't need auxiliary .s files to allow us to
+	// use go:linkname to refer to the functions directly.
+
+	save := __vdso_clock_gettime_sym
+	if save == 0 {
+		t.Log("__vdso_clock_gettime symbol not found; fallback path will be used by default")
+	}
+
+	// Call with fast-path enabled (if vDSO symbol found at startup)
+	time.Now()
+
+	// Call with fast-path disabled
+	__vdso_clock_gettime_sym = 0
+	time.Now()
+	__vdso_clock_gettime_sym = save
+}
+
+func BenchmarkClockVDSOAndFallbackPaths(b *testing.B) {
+	run := func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			// Call via time.Now() - see comment in test above.
+			time.Now()
+		}
+	}
+
+	save := __vdso_clock_gettime_sym
+	b.Run("vDSO", run)
+	__vdso_clock_gettime_sym = 0
+	b.Run("Fallback", run)
+	__vdso_clock_gettime_sym = save
+}
+
+func BenchmarkTimeNow(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		time.Now()
+	}
+}
diff --git a/src/sort/example_interface_test.go b/src/sort/example_interface_test.go
index 442204e..72d3017 100644
--- a/src/sort/example_interface_test.go
+++ b/src/sort/example_interface_test.go
@@ -35,10 +35,24 @@
 	}
 
 	fmt.Println(people)
+	// There are two ways to sort a slice. First, one can define
+	// a set of methods for the slice type, as with ByAge, and
+	// call sort.Sort. In this first example we use that technique.
 	sort.Sort(ByAge(people))
 	fmt.Println(people)
 
+	// The other way is to use sort.Slice with a custom Less
+	// function, which can be provided as a closure. In this
+	// case no methods are needed. (And if they exist, they
+	// are ignored.) Here we re-sort in reverse order: compare
+	// the closure with ByAge.Less.
+	sort.Slice(people, func(i, j int) bool {
+		return people[i].Age > people[j].Age
+	})
+	fmt.Println(people)
+
 	// Output:
 	// [Bob: 31 John: 42 Michael: 17 Jenny: 26]
 	// [Michael: 17 Jenny: 26 Bob: 31 John: 42]
+	// [John: 42 Bob: 31 Jenny: 26 Michael: 17]
 }
diff --git a/src/sort/example_keys_test.go b/src/sort/example_keys_test.go
index a8e47e4..648f919 100644
--- a/src/sort/example_keys_test.go
+++ b/src/sort/example_keys_test.go
@@ -73,7 +73,7 @@
 		return p1.distance < p2.distance
 	}
 	decreasingDistance := func(p1, p2 *Planet) bool {
-		return !distance(p1, p2)
+		return distance(p2, p1)
 	}
 
 	// Sort the planets by the various criteria.
diff --git a/src/sort/example_multi_test.go b/src/sort/example_multi_test.go
index 40d1215..de6ec14 100644
--- a/src/sort/example_multi_test.go
+++ b/src/sort/example_multi_test.go
@@ -49,10 +49,11 @@
 }
 
 // Less is part of sort.Interface. It is implemented by looping along the
-// less functions until it finds a comparison that is either Less or
-// !Less. Note that it can call the less functions twice per call. We
-// could change the functions to return -1, 0, 1 and reduce the
-// number of calls for greater efficiency: an exercise for the reader.
+// less functions until it finds a comparison that discriminates between
+// the two items (one is less than the other). Note that it can call the
+// less functions twice per call. We could change the functions to return
+// -1, 0, 1 and reduce the number of calls for greater efficiency: an
+// exercise for the reader.
 func (ms *multiSorter) Less(i, j int) bool {
 	p, q := &ms.changes[i], &ms.changes[j]
 	// Try all but the last comparison.
diff --git a/src/sort/example_test.go b/src/sort/example_test.go
index f8d8491..1f85dbc 100644
--- a/src/sort/example_test.go
+++ b/src/sort/example_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"math"
 	"sort"
 )
 
@@ -16,6 +17,49 @@
 	// Output: [1 2 3 4 5 6]
 }
 
+func ExampleIntsAreSorted() {
+	s := []int{1, 2, 3, 4, 5, 6} // sorted ascending
+	fmt.Println(sort.IntsAreSorted(s))
+
+	s = []int{6, 5, 4, 3, 2, 1} // sorted descending
+	fmt.Println(sort.IntsAreSorted(s))
+
+	s = []int{3, 2, 4, 1, 5} // unsorted
+	fmt.Println(sort.IntsAreSorted(s))
+
+	// Output: true
+	// false
+	// false
+}
+
+func ExampleFloat64s() {
+	s := []float64{5.2, -1.3, 0.7, -3.8, 2.6} // unsorted
+	sort.Float64s(s)
+	fmt.Println(s)
+
+	s = []float64{math.Inf(1), math.NaN(), math.Inf(-1), 0.0} // unsorted
+	sort.Float64s(s)
+	fmt.Println(s)
+
+	// Output: [-3.8 -1.3 0.7 2.6 5.2]
+	// [NaN -Inf 0 +Inf]
+}
+
+func ExampleFloat64sAreSorted() {
+	s := []float64{0.7, 1.3, 2.6, 3.8, 5.2} // sorted ascending
+	fmt.Println(sort.Float64sAreSorted(s))
+
+	s = []float64{5.2, 3.8, 2.6, 1.3, 0.7} // sorted descending
+	fmt.Println(sort.Float64sAreSorted(s))
+
+	s = []float64{5.2, 1.3, 0.7, 3.8, 2.6} // unsorted
+	fmt.Println(sort.Float64sAreSorted(s))
+
+	// Output: true
+	// false
+	// false
+}
+
 func ExampleReverse() {
 	s := []int{5, 2, 6, 3, 1, 4} // unsorted
 	sort.Sort(sort.Reverse(sort.IntSlice(s)))
diff --git a/src/sort/slice.go b/src/sort/slice.go
new file mode 100644
index 0000000..206f121
--- /dev/null
+++ b/src/sort/slice.go
@@ -0,0 +1,46 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !compiler_bootstrap go1.8
+
+package sort
+
+import "reflect"
+
+// Slice sorts the provided slice given the provided less function.
+//
+// The sort is not guaranteed to be stable. For a stable sort, use
+// SliceStable.
+//
+// The function panics if the provided interface is not a slice.
+func Slice(slice interface{}, less func(i, j int) bool) {
+	rv := reflect.ValueOf(slice)
+	swap := reflect.Swapper(slice)
+	length := rv.Len()
+	quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
+}
+
+// SliceStable sorts the provided slice given the provided less
+// function while keeping the original order of equal elements.
+//
+// The function panics if the provided interface is not a slice.
+func SliceStable(slice interface{}, less func(i, j int) bool) {
+	rv := reflect.ValueOf(slice)
+	swap := reflect.Swapper(slice)
+	stable_func(lessSwap{less, swap}, rv.Len())
+}
+
+// SliceIsSorted tests whether a slice is sorted.
+//
+// The function panics if the provided interface is not a slice.
+func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
+	rv := reflect.ValueOf(slice)
+	n := rv.Len()
+	for i := n - 1; i > 0; i-- {
+		if less(i, i-1) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/sort/sort.go b/src/sort/sort.go
index 081b700..a7304af 100644
--- a/src/sort/sort.go
+++ b/src/sort/sort.go
@@ -8,8 +8,6 @@
 // collections.
 package sort
 
-import "reflect"
-
 // A type, typically a collection, that satisfies sort.Interface can be
 // sorted by the routines in this package. The methods require that the
 // elements of the collection be enumerated by an integer index.
@@ -238,43 +236,6 @@
 	Swap func(i, j int)
 }
 
-// Slice sorts the provided slice given the provided less function.
-//
-// The sort is not guaranteed to be stable. For a stable sort, use
-// SliceStable.
-//
-// The function panics if the provided interface is not a slice.
-func Slice(slice interface{}, less func(i, j int) bool) {
-	rv := reflect.ValueOf(slice)
-	swap := reflect.Swapper(slice)
-	length := rv.Len()
-	quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
-}
-
-// SliceStable sorts the provided slice given the provided less
-// function while keeping the original order of equal elements.
-//
-// The function panics if the provided interface is not a slice.
-func SliceStable(slice interface{}, less func(i, j int) bool) {
-	rv := reflect.ValueOf(slice)
-	swap := reflect.Swapper(slice)
-	stable_func(lessSwap{less, swap}, rv.Len())
-}
-
-// SliceIsSorted tests whether a slice is sorted.
-//
-// The function panics if the provided interface is not a slice.
-func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
-	rv := reflect.ValueOf(slice)
-	n := rv.Len()
-	for i := n - 1; i > 0; i-- {
-		if less(i, i-1) {
-			return false
-		}
-	}
-	return true
-}
-
 type reverse struct {
 	// This embedded Interface permits Reverse to use the methods of
 	// another Interface implementation.
diff --git a/src/sort/sort_test.go b/src/sort/sort_test.go
index 45713a2..092135e 100644
--- a/src/sort/sort_test.go
+++ b/src/sort/sort_test.go
@@ -458,49 +458,69 @@
 // This is based on the "antiquicksort" implementation by M. Douglas McIlroy.
 // See http://www.cs.dartmouth.edu/~doug/mdmspe.pdf for more info.
 type adversaryTestingData struct {
-	data      []int
-	keys      map[int]int
-	candidate int
+	t         *testing.T
+	data      []int // item values, initialized to special gas value and changed by Less
+	maxcmp    int   // number of comparisons allowed
+	ncmp      int   // number of comparisons (calls to Less)
+	nsolid    int   // number of elements that have been set to non-gas values
+	candidate int   // guess at current pivot
+	gas       int   // special value for unset elements, higher than everything else
 }
 
 func (d *adversaryTestingData) Len() int { return len(d.data) }
 
 func (d *adversaryTestingData) Less(i, j int) bool {
-	if _, present := d.keys[i]; !present {
-		if _, present := d.keys[j]; !present {
-			if i == d.candidate {
-				d.keys[i] = len(d.keys)
-			} else {
-				d.keys[j] = len(d.keys)
-			}
+	if d.ncmp >= d.maxcmp {
+		d.t.Fatalf("used %d comparisons sorting adversary data with size %d", d.ncmp, len(d.data))
+	}
+	d.ncmp++
+
+	if d.data[i] == d.gas && d.data[j] == d.gas {
+		if i == d.candidate {
+			// freeze i
+			d.data[i] = d.nsolid
+			d.nsolid++
+		} else {
+			// freeze j
+			d.data[j] = d.nsolid
+			d.nsolid++
 		}
 	}
 
-	if _, present := d.keys[i]; !present {
+	if d.data[i] == d.gas {
 		d.candidate = i
-		return false
-	}
-	if _, present := d.keys[j]; !present {
+	} else if d.data[j] == d.gas {
 		d.candidate = j
-		return true
 	}
 
-	return d.keys[i] >= d.keys[j]
+	return d.data[i] < d.data[j]
 }
 
 func (d *adversaryTestingData) Swap(i, j int) {
 	d.data[i], d.data[j] = d.data[j], d.data[i]
 }
 
-func TestAdversary(t *testing.T) {
-	const size = 100
+func newAdversaryTestingData(t *testing.T, size int, maxcmp int) *adversaryTestingData {
+	gas := size - 1
 	data := make([]int, size)
 	for i := 0; i < size; i++ {
-		data[i] = i
+		data[i] = gas
 	}
+	return &adversaryTestingData{t: t, data: data, maxcmp: maxcmp, gas: gas}
+}
 
-	d := &adversaryTestingData{data, make(map[int]int), 0}
+func TestAdversary(t *testing.T) {
+	const size = 10000            // large enough to distinguish between O(n^2) and O(n*log(n))
+	maxcmp := size * lg(size) * 4 // the factor 4 was found by trial and error
+	d := newAdversaryTestingData(t, size, maxcmp)
 	Sort(d) // This should degenerate to heapsort.
+	// Check data is fully populated and sorted.
+	for i, v := range d.data {
+		if v != i {
+			t.Errorf("adversary data not fully sorted")
+			t.FailNow()
+		}
+	}
 }
 
 func TestStableInts(t *testing.T) {
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
index 66df149..bebed04 100644
--- a/src/strconv/atoi.go
+++ b/src/strconv/atoi.go
@@ -16,7 +16,7 @@
 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)
+	Err  error  // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
 }
 
 func (e *NumError) Error() string {
@@ -31,6 +31,14 @@
 	return &NumError{fn, str, ErrRange}
 }
 
+func baseError(fn, str string, base int) *NumError {
+	return &NumError{fn, str, errors.New("invalid base " + Itoa(base))}
+}
+
+func bitSizeError(fn, str string, bitSize int) *NumError {
+	return &NumError{fn, str, errors.New("invalid bit size " + Itoa(bitSize))}
+}
+
 const intSize = 32 << (^uint(0) >> 63)
 
 // IntSize is the size in bits of an int or uint value.
@@ -40,20 +48,14 @@
 
 // ParseUint is like ParseInt but for unsigned numbers.
 func ParseUint(s string, base int, bitSize int) (uint64, error) {
-	var n uint64
-	var err error
-	var cutoff, maxVal uint64
+	const fnParseUint = "ParseUint"
 
-	if bitSize == 0 {
-		bitSize = int(IntSize)
+	if len(s) == 0 {
+		return 0, syntaxError(fnParseUint, s)
 	}
 
-	i := 0
+	s0 := s
 	switch {
-	case len(s) < 1:
-		err = ErrSyntax
-		goto Error
-
 	case 2 <= base && base <= 36:
 		// valid base; nothing to do
 
@@ -62,25 +64,30 @@
 		switch {
 		case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
 			if len(s) < 3 {
-				err = ErrSyntax
-				goto Error
+				return 0, syntaxError(fnParseUint, s0)
 			}
 			base = 16
-			i = 2
+			s = s[2:]
 		case s[0] == '0':
 			base = 8
-			i = 1
+			s = s[1:]
 		default:
 			base = 10
 		}
 
 	default:
-		err = errors.New("invalid base " + Itoa(base))
-		goto Error
+		return 0, baseError(fnParseUint, s0, base)
+	}
+
+	if bitSize == 0 {
+		bitSize = int(IntSize)
+	} else if bitSize < 0 || bitSize > 64 {
+		return 0, bitSizeError(fnParseUint, s0, bitSize)
 	}
 
 	// Cutoff is the smallest number such that cutoff*base > maxUint64.
 	// Use compile-time constants for common cases.
+	var cutoff uint64
 	switch base {
 	case 10:
 		cutoff = maxUint64/10 + 1
@@ -90,61 +97,54 @@
 		cutoff = maxUint64/uint64(base) + 1
 	}
 
-	maxVal = 1<<uint(bitSize) - 1
+	maxVal := uint64(1)<<uint(bitSize) - 1
 
-	for ; i < len(s); i++ {
-		var v byte
-		d := s[i]
+	var n uint64
+	for _, c := range []byte(s) {
+		var d byte
 		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
+		case '0' <= c && c <= '9':
+			d = c - '0'
+		case 'a' <= c && c <= 'z':
+			d = c - 'a' + 10
+		case 'A' <= c && c <= 'Z':
+			d = c - 'A' + 10
 		default:
-			n = 0
-			err = ErrSyntax
-			goto Error
+			return 0, syntaxError(fnParseUint, s0)
 		}
-		if v >= byte(base) {
-			n = 0
-			err = ErrSyntax
-			goto Error
+
+		if d >= byte(base) {
+			return 0, syntaxError(fnParseUint, s0)
 		}
 
 		if n >= cutoff {
 			// n*base overflows
-			n = maxUint64
-			err = ErrRange
-			goto Error
+			return maxVal, rangeError(fnParseUint, s0)
 		}
 		n *= uint64(base)
 
-		n1 := n + uint64(v)
+		n1 := n + uint64(d)
 		if n1 < n || n1 > maxVal {
 			// n+v overflows
-			n = maxUint64
-			err = ErrRange
-			goto Error
+			return maxVal, rangeError(fnParseUint, s0)
 		}
 		n = n1
 	}
 
 	return n, nil
-
-Error:
-	return n, &NumError{"ParseUint", s, 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.
+// ParseInt interprets a string s in the given base (0, 2 to 36) and
+// bit size (0 to 64) 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.
+// For bases 1, below 0 or above 36 an error is returned.
 //
 // 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.
+// For a bitSize below 0 or above 64 an error is returned.
 //
 // The errors that ParseInt returns have concrete type *NumError
 // and include err.Num = s. If s is empty or contains invalid
@@ -156,10 +156,6 @@
 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)
@@ -183,6 +179,11 @@
 		err.(*NumError).Num = s0
 		return 0, err
 	}
+
+	if bitSize == 0 {
+		bitSize = int(IntSize)
+	}
+
 	cutoff := uint64(1 << uint(bitSize-1))
 	if !neg && un >= cutoff {
 		return int64(cutoff - 1), rangeError(fnParseInt, s0)
@@ -200,6 +201,34 @@
 // Atoi returns the result of ParseInt(s, 10, 0) converted to type int.
 func Atoi(s string) (int, error) {
 	const fnAtoi = "Atoi"
+
+	sLen := len(s)
+	if intSize == 32 && (0 < sLen && sLen < 10) ||
+		intSize == 64 && (0 < sLen && sLen < 19) {
+		// Fast path for small integers that fit int type.
+		s0 := s
+		if s[0] == '-' || s[0] == '+' {
+			s = s[1:]
+			if len(s) < 1 {
+				return 0, &NumError{fnAtoi, s0, ErrSyntax}
+			}
+		}
+
+		n := 0
+		for _, ch := range []byte(s) {
+			ch -= '0'
+			if ch > 9 {
+				return 0, &NumError{fnAtoi, s0, ErrSyntax}
+			}
+			n = n*10 + int(ch)
+		}
+		if s0[0] == '-' {
+			n = -n
+		}
+		return n, nil
+	}
+
+	// Slow path for invalid or big integers.
 	i64, err := ParseInt(s, 10, 0)
 	if nerr, ok := err.(*NumError); ok {
 		nerr.Func = fnAtoi
diff --git a/src/strconv/atoi_test.go b/src/strconv/atoi_test.go
index d608505..e2f505a 100644
--- a/src/strconv/atoi_test.go
+++ b/src/strconv/atoi_test.go
@@ -6,18 +6,19 @@
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
 	. "strconv"
 	"testing"
 )
 
-type atoui64Test struct {
+type parseUint64Test struct {
 	in  string
 	out uint64
 	err error
 }
 
-var atoui64tests = []atoui64Test{
+var parseUint64Tests = []parseUint64Test{
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
 	{"1", 1, nil},
@@ -30,38 +31,45 @@
 	{"18446744073709551620", 1<<64 - 1, ErrRange},
 }
 
-var btoui64tests = []atoui64Test{
-	{"", 0, ErrSyntax},
-	{"0", 0, nil},
-	{"0x", 0, ErrSyntax},
-	{"0X", 0, ErrSyntax},
-	{"1", 1, nil},
-	{"12345", 12345, nil},
-	{"012345", 012345, nil},
-	{"0x12345", 0x12345, nil},
-	{"0X12345", 0x12345, nil},
-	{"12345x", 0, ErrSyntax},
-	{"0xabcdefg123", 0, ErrSyntax},
-	{"123456789abc", 0, ErrSyntax},
-	{"98765432100", 98765432100, nil},
-	{"18446744073709551615", 1<<64 - 1, nil},
-	{"18446744073709551616", 1<<64 - 1, ErrRange},
-	{"18446744073709551620", 1<<64 - 1, ErrRange},
-	{"0xFFFFFFFFFFFFFFFF", 1<<64 - 1, nil},
-	{"0x10000000000000000", 1<<64 - 1, ErrRange},
-	{"01777777777777777777777", 1<<64 - 1, nil},
-	{"01777777777777777777778", 0, ErrSyntax},
-	{"02000000000000000000000", 1<<64 - 1, ErrRange},
-	{"0200000000000000000000", 1 << 61, nil},
+type parseUint64BaseTest struct {
+	in   string
+	base int
+	out  uint64
+	err  error
 }
 
-type atoi64Test struct {
+var parseUint64BaseTests = []parseUint64BaseTest{
+	{"", 0, 0, ErrSyntax},
+	{"0", 0, 0, nil},
+	{"0x", 0, 0, ErrSyntax},
+	{"0X", 0, 0, ErrSyntax},
+	{"1", 0, 1, nil},
+	{"12345", 0, 12345, nil},
+	{"012345", 0, 012345, nil},
+	{"0x12345", 0, 0x12345, nil},
+	{"0X12345", 0, 0x12345, nil},
+	{"12345x", 0, 0, ErrSyntax},
+	{"0xabcdefg123", 0, 0, ErrSyntax},
+	{"123456789abc", 0, 0, ErrSyntax},
+	{"98765432100", 0, 98765432100, nil},
+	{"18446744073709551615", 0, 1<<64 - 1, nil},
+	{"18446744073709551616", 0, 1<<64 - 1, ErrRange},
+	{"18446744073709551620", 0, 1<<64 - 1, ErrRange},
+	{"0xFFFFFFFFFFFFFFFF", 0, 1<<64 - 1, nil},
+	{"0x10000000000000000", 0, 1<<64 - 1, ErrRange},
+	{"01777777777777777777777", 0, 1<<64 - 1, nil},
+	{"01777777777777777777778", 0, 0, ErrSyntax},
+	{"02000000000000000000000", 0, 1<<64 - 1, ErrRange},
+	{"0200000000000000000000", 0, 1 << 61, nil},
+}
+
+type parseInt64Test struct {
 	in  string
 	out int64
 	err error
 }
 
-var atoi64tests = []atoi64Test{
+var parseInt64Tests = []parseInt64Test{
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
 	{"-0", 0, nil},
@@ -81,14 +89,14 @@
 	{"-9223372036854775809", -1 << 63, ErrRange},
 }
 
-type btoi64Test struct {
+type parseInt64BaseTest struct {
 	in   string
 	base int
 	out  int64
 	err  error
 }
 
-var btoi64tests = []btoi64Test{
+var parseInt64BaseTests = []parseInt64BaseTest{
 	{"", 0, 0, ErrSyntax},
 	{"0", 0, 0, nil},
 	{"-0", 0, 0, nil},
@@ -138,13 +146,13 @@
 	{"7fffffffffffffff", 16, 1<<63 - 1, nil},
 }
 
-type atoui32Test struct {
+type parseUint32Test struct {
 	in  string
 	out uint32
 	err error
 }
 
-var atoui32tests = []atoui32Test{
+var parseUint32Tests = []parseUint32Test{
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
 	{"1", 1, nil},
@@ -156,13 +164,13 @@
 	{"4294967296", 1<<32 - 1, ErrRange},
 }
 
-type atoi32Test struct {
+type parseInt32Test struct {
 	in  string
 	out int32
 	err error
 }
 
-var atoi32tests = []atoi32Test{
+var parseInt32Tests = []parseInt32Test{
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
 	{"-0", 0, nil},
@@ -195,86 +203,108 @@
 }
 
 func init() {
-	// The atoi routines return NumErrors wrapping
+	// The parse routines return NumErrors wrapping
 	// the error and the string. Convert the tables above.
-	for i := range atoui64tests {
-		test := &atoui64tests[i]
+	for i := range parseUint64Tests {
+		test := &parseUint64Tests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseUint", test.in, test.err}
 		}
 	}
-	for i := range btoui64tests {
-		test := &btoui64tests[i]
+	for i := range parseUint64BaseTests {
+		test := &parseUint64BaseTests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseUint", test.in, test.err}
 		}
 	}
-	for i := range atoi64tests {
-		test := &atoi64tests[i]
+	for i := range parseInt64Tests {
+		test := &parseInt64Tests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseInt", test.in, test.err}
 		}
 	}
-	for i := range btoi64tests {
-		test := &btoi64tests[i]
+	for i := range parseInt64BaseTests {
+		test := &parseInt64BaseTests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseInt", test.in, test.err}
 		}
 	}
-	for i := range atoui32tests {
-		test := &atoui32tests[i]
+	for i := range parseUint32Tests {
+		test := &parseUint32Tests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseUint", test.in, test.err}
 		}
 	}
-	for i := range atoi32tests {
-		test := &atoi32tests[i]
+	for i := range parseInt32Tests {
+		test := &parseInt32Tests[i]
 		if test.err != nil {
 			test.err = &NumError{"ParseInt", test.in, test.err}
 		}
 	}
 }
 
+func TestParseUint32(t *testing.T) {
+	for i := range parseUint32Tests {
+		test := &parseUint32Tests[i]
+		out, err := ParseUint(test.in, 10, 32)
+		if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+			t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
+				test.in, out, err, test.out, test.err)
+		}
+	}
+}
+
 func TestParseUint64(t *testing.T) {
-	for i := range atoui64tests {
-		test := &atoui64tests[i]
+	for i := range parseUint64Tests {
+		test := &parseUint64Tests[i]
 		out, err := ParseUint(test.in, 10, 64)
 		if test.out != out || !reflect.DeepEqual(test.err, err) {
-			t.Errorf("Atoui64(%q) = %v, %v want %v, %v",
+			t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
 				test.in, out, err, test.out, test.err)
 		}
 	}
 }
 
 func TestParseUint64Base(t *testing.T) {
-	for i := range btoui64tests {
-		test := &btoui64tests[i]
-		out, err := ParseUint(test.in, 0, 64)
+	for i := range parseUint64BaseTests {
+		test := &parseUint64BaseTests[i]
+		out, err := ParseUint(test.in, test.base, 64)
 		if test.out != out || !reflect.DeepEqual(test.err, err) {
-			t.Errorf("ParseUint(%q) = %v, %v want %v, %v",
+			t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
+				test.in, test.base, out, err, test.out, test.err)
+		}
+	}
+}
+
+func TestParseInt32(t *testing.T) {
+	for i := range parseInt32Tests {
+		test := &parseInt32Tests[i]
+		out, err := ParseInt(test.in, 10, 32)
+		if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+			t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
 				test.in, out, err, test.out, test.err)
 		}
 	}
 }
 
 func TestParseInt64(t *testing.T) {
-	for i := range atoi64tests {
-		test := &atoi64tests[i]
+	for i := range parseInt64Tests {
+		test := &parseInt64Tests[i]
 		out, err := ParseInt(test.in, 10, 64)
 		if test.out != out || !reflect.DeepEqual(test.err, err) {
-			t.Errorf("Atoi64(%q) = %v, %v want %v, %v",
+			t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
 				test.in, out, err, test.out, test.err)
 		}
 	}
 }
 
 func TestParseInt64Base(t *testing.T) {
-	for i := range btoi64tests {
-		test := &btoi64tests[i]
+	for i := range parseInt64BaseTests {
+		test := &parseInt64BaseTests[i]
 		out, err := ParseInt(test.in, test.base, 64)
 		if test.out != out || !reflect.DeepEqual(test.err, err) {
-			t.Errorf("ParseInt(%q) = %v, %v want %v, %v",
-				test.in, out, err, test.out, test.err)
+			t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
+				test.in, test.base, out, err, test.out, test.err)
 		}
 	}
 }
@@ -282,20 +312,20 @@
 func TestParseUint(t *testing.T) {
 	switch IntSize {
 	case 32:
-		for i := range atoui32tests {
-			test := &atoui32tests[i]
+		for i := range parseUint32Tests {
+			test := &parseUint32Tests[i]
 			out, err := ParseUint(test.in, 10, 0)
-			if test.out != uint32(out) || !reflect.DeepEqual(test.err, err) {
-				t.Errorf("Atoui(%q) = %v, %v want %v, %v",
+			if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+				t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
 					test.in, out, err, test.out, test.err)
 			}
 		}
 	case 64:
-		for i := range atoui64tests {
-			test := &atoui64tests[i]
+		for i := range parseUint64Tests {
+			test := &parseUint64Tests[i]
 			out, err := ParseUint(test.in, 10, 0)
-			if test.out != uint64(out) || !reflect.DeepEqual(test.err, err) {
-				t.Errorf("Atoui(%q) = %v, %v want %v, %v",
+			if test.out != out || !reflect.DeepEqual(test.err, err) {
+				t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
 					test.in, out, err, test.out, test.err)
 			}
 		}
@@ -305,26 +335,138 @@
 func TestParseInt(t *testing.T) {
 	switch IntSize {
 	case 32:
-		for i := range atoi32tests {
-			test := &atoi32tests[i]
+		for i := range parseInt32Tests {
+			test := &parseInt32Tests[i]
 			out, err := ParseInt(test.in, 10, 0)
-			if test.out != int32(out) || !reflect.DeepEqual(test.err, err) {
-				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+			if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+				t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
 					test.in, out, err, test.out, test.err)
 			}
 		}
 	case 64:
-		for i := range atoi64tests {
-			test := &atoi64tests[i]
+		for i := range parseInt64Tests {
+			test := &parseInt64Tests[i]
 			out, err := ParseInt(test.in, 10, 0)
-			if test.out != int64(out) || !reflect.DeepEqual(test.err, err) {
-				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+			if test.out != out || !reflect.DeepEqual(test.err, err) {
+				t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
 					test.in, out, err, test.out, test.err)
 			}
 		}
 	}
 }
 
+func TestAtoi(t *testing.T) {
+	switch IntSize {
+	case 32:
+		for i := range parseInt32Tests {
+			test := &parseInt32Tests[i]
+			out, err := Atoi(test.in)
+			var testErr error
+			if test.err != nil {
+				testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+			}
+			if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
+				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+					test.in, out, err, test.out, testErr)
+			}
+		}
+	case 64:
+		for i := range parseInt64Tests {
+			test := &parseInt64Tests[i]
+			out, err := Atoi(test.in)
+			var testErr error
+			if test.err != nil {
+				testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+			}
+			if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
+				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+					test.in, out, err, test.out, testErr)
+			}
+		}
+	}
+}
+
+func bitSizeErrStub(name string, bitSize int) error {
+	return BitSizeError(name, "0", bitSize)
+}
+
+func baseErrStub(name string, base int) error {
+	return BaseError(name, "0", base)
+}
+
+func noErrStub(name string, arg int) error {
+	return nil
+}
+
+type parseErrorTest struct {
+	arg     int
+	errStub func(name string, arg int) error
+}
+
+var parseBitSizeTests = []parseErrorTest{
+	{-1, bitSizeErrStub},
+	{0, noErrStub},
+	{64, noErrStub},
+	{65, bitSizeErrStub},
+}
+
+var parseBaseTests = []parseErrorTest{
+	{-1, baseErrStub},
+	{0, noErrStub},
+	{1, baseErrStub},
+	{2, noErrStub},
+	{36, noErrStub},
+	{37, baseErrStub},
+}
+
+func TestParseIntBitSize(t *testing.T) {
+	for i := range parseBitSizeTests {
+		test := &parseBitSizeTests[i]
+		testErr := test.errStub("ParseInt", test.arg)
+		_, err := ParseInt("0", 0, test.arg)
+		if !reflect.DeepEqual(testErr, err) {
+			t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
+				test.arg, err, testErr)
+		}
+	}
+}
+
+func TestParseUintBitSize(t *testing.T) {
+	for i := range parseBitSizeTests {
+		test := &parseBitSizeTests[i]
+		testErr := test.errStub("ParseUint", test.arg)
+		_, err := ParseUint("0", 0, test.arg)
+		if !reflect.DeepEqual(testErr, err) {
+			t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
+				test.arg, err, testErr)
+		}
+	}
+}
+
+func TestParseIntBase(t *testing.T) {
+	for i := range parseBaseTests {
+		test := &parseBaseTests[i]
+		testErr := test.errStub("ParseInt", test.arg)
+		_, err := ParseInt("0", test.arg, 0)
+		if !reflect.DeepEqual(testErr, err) {
+			t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
+				test.arg, err, testErr)
+		}
+	}
+}
+
+func TestParseUintBase(t *testing.T) {
+	for i := range parseBaseTests {
+		test := &parseBaseTests[i]
+		testErr := test.errStub("ParseUint", test.arg)
+		_, err := ParseUint("0", test.arg, 0)
+		if !reflect.DeepEqual(testErr, err) {
+			t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
+				test.arg, err, testErr)
+		}
+	}
+}
+
 func TestNumError(t *testing.T) {
 	for _, test := range numErrorTests {
 		err := &NumError{
@@ -338,26 +480,67 @@
 	}
 }
 
+func BenchmarkParseInt(b *testing.B) {
+	b.Run("Pos", func(b *testing.B) {
+		benchmarkParseInt(b, 1)
+	})
+	b.Run("Neg", func(b *testing.B) {
+		benchmarkParseInt(b, -1)
+	})
+}
+
+type benchCase struct {
+	name string
+	num  int64
+}
+
+func benchmarkParseInt(b *testing.B, neg int) {
+	cases := []benchCase{
+		{"7bit", 1<<7 - 1},
+		{"26bit", 1<<26 - 1},
+		{"31bit", 1<<31 - 1},
+		{"56bit", 1<<56 - 1},
+		{"63bit", 1<<63 - 1},
+	}
+	for _, cs := range cases {
+		b.Run(cs.name, func(b *testing.B) {
+			s := fmt.Sprintf("%d", cs.num*int64(neg))
+			for i := 0; i < b.N; i++ {
+				out, _ := ParseInt(s, 10, 64)
+				BenchSink += int(out)
+			}
+		})
+	}
+}
+
 func BenchmarkAtoi(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		ParseInt("12345678", 10, 0)
-	}
+	b.Run("Pos", func(b *testing.B) {
+		benchmarkAtoi(b, 1)
+	})
+	b.Run("Neg", func(b *testing.B) {
+		benchmarkAtoi(b, -1)
+	})
 }
 
-func BenchmarkAtoiNeg(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		ParseInt("-12345678", 10, 0)
+func benchmarkAtoi(b *testing.B, neg int) {
+	cases := []benchCase{
+		{"7bit", 1<<7 - 1},
+		{"26bit", 1<<26 - 1},
+		{"31bit", 1<<31 - 1},
 	}
-}
-
-func BenchmarkAtoi64(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		ParseInt("12345678901234", 10, 64)
+	if IntSize == 64 {
+		cases = append(cases, []benchCase{
+			{"56bit", 1<<56 - 1},
+			{"63bit", 1<<63 - 1},
+		}...)
 	}
-}
-
-func BenchmarkAtoi64Neg(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		ParseInt("-12345678901234", 10, 64)
+	for _, cs := range cases {
+		b.Run(cs.name, func(b *testing.B) {
+			s := fmt.Sprintf("%d", cs.num*int64(neg))
+			for i := 0; i < b.N; i++ {
+				out, _ := Atoi(s)
+				BenchSink += out
+			}
+		})
 	}
 }
diff --git a/src/strconv/export_test.go b/src/strconv/export_test.go
new file mode 100644
index 0000000..8c03a7f
--- /dev/null
+++ b/src/strconv/export_test.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv
+
+var (
+	BitSizeError = bitSizeError
+	BaseError    = baseError
+)
diff --git a/src/strconv/extfloat.go b/src/strconv/extfloat.go
index 7033e96..7f17bc6 100644
--- a/src/strconv/extfloat.go
+++ b/src/strconv/extfloat.go
@@ -641,7 +641,7 @@
 // adjustLastDigit modifies d = x-currentDiff*ε, to get closest to
 // d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε.
 // It assumes that a decimal digit is worth ulpDecimal*ε, and that
-// all data is known with a error estimate of ulpBinary*ε.
+// all data is known with an error estimate of ulpBinary*ε.
 func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
 	if ulpDecimal < 2*ulpBinary {
 		// Approximation is too wide.
diff --git a/src/strconv/isprint.go b/src/strconv/isprint.go
index a30d8d8..5837142 100644
--- a/src/strconv/isprint.go
+++ b/src/strconv/isprint.go
@@ -7,7 +7,7 @@
 
 package strconv
 
-// (462+139+82)*2 + (378)*4 = 2878 bytes
+// (456+140+86)*2 + (396)*4 = 2948 bytes
 
 var isPrint16 = []uint16{
 	0x0020, 0x007e,
@@ -25,7 +25,7 @@
 	0x07c0, 0x07fa,
 	0x0800, 0x082d,
 	0x0830, 0x085b,
-	0x085e, 0x085e,
+	0x085e, 0x086a,
 	0x08a0, 0x08bd,
 	0x08d4, 0x098c,
 	0x098f, 0x0990,
@@ -36,7 +36,7 @@
 	0x09cb, 0x09ce,
 	0x09d7, 0x09d7,
 	0x09dc, 0x09e3,
-	0x09e6, 0x09fb,
+	0x09e6, 0x09fd,
 	0x0a01, 0x0a0a,
 	0x0a0f, 0x0a10,
 	0x0a13, 0x0a39,
@@ -51,8 +51,7 @@
 	0x0ad0, 0x0ad0,
 	0x0ae0, 0x0ae3,
 	0x0ae6, 0x0af1,
-	0x0af9, 0x0af9,
-	0x0b01, 0x0b0c,
+	0x0af9, 0x0b0c,
 	0x0b0f, 0x0b10,
 	0x0b13, 0x0b39,
 	0x0b3c, 0x0b44,
@@ -82,8 +81,7 @@
 	0x0cd5, 0x0cd6,
 	0x0cde, 0x0ce3,
 	0x0ce6, 0x0cf2,
-	0x0d01, 0x0d3a,
-	0x0d3d, 0x0d4f,
+	0x0d00, 0x0d4f,
 	0x0d54, 0x0d63,
 	0x0d66, 0x0d7f,
 	0x0d82, 0x0d96,
@@ -154,8 +152,7 @@
 	0x1c4d, 0x1c88,
 	0x1cc0, 0x1cc7,
 	0x1cd0, 0x1cf9,
-	0x1d00, 0x1df5,
-	0x1dfb, 0x1f15,
+	0x1d00, 0x1f15,
 	0x1f18, 0x1f1d,
 	0x1f20, 0x1f45,
 	0x1f48, 0x1f4d,
@@ -167,7 +164,7 @@
 	0x2030, 0x205e,
 	0x2070, 0x2071,
 	0x2074, 0x209c,
-	0x20a0, 0x20be,
+	0x20a0, 0x20bf,
 	0x20d0, 0x20f0,
 	0x2100, 0x218b,
 	0x2190, 0x2426,
@@ -175,7 +172,7 @@
 	0x2460, 0x2b73,
 	0x2b76, 0x2b95,
 	0x2b98, 0x2bb9,
-	0x2bbd, 0x2bd1,
+	0x2bbd, 0x2bd2,
 	0x2bec, 0x2bef,
 	0x2c00, 0x2cf3,
 	0x2cf9, 0x2d27,
@@ -183,17 +180,17 @@
 	0x2d30, 0x2d67,
 	0x2d6f, 0x2d70,
 	0x2d7f, 0x2d96,
-	0x2da0, 0x2e44,
+	0x2da0, 0x2e49,
 	0x2e80, 0x2ef3,
 	0x2f00, 0x2fd5,
 	0x2ff0, 0x2ffb,
 	0x3001, 0x3096,
 	0x3099, 0x30ff,
-	0x3105, 0x312d,
+	0x3105, 0x312e,
 	0x3131, 0x31ba,
 	0x31c0, 0x31e3,
 	0x31f0, 0x4db5,
-	0x4dc0, 0x9fd5,
+	0x4dc0, 0x9fea,
 	0xa000, 0xa48c,
 	0xa490, 0xa4c6,
 	0xa4d0, 0xa62b,
@@ -254,6 +251,7 @@
 	0x0590,
 	0x06dd,
 	0x083f,
+	0x085f,
 	0x08b5,
 	0x08e2,
 	0x0984,
@@ -275,6 +273,7 @@
 	0x0ab4,
 	0x0ac6,
 	0x0aca,
+	0x0b00,
 	0x0b04,
 	0x0b29,
 	0x0b31,
@@ -341,7 +340,7 @@
 	0x1771,
 	0x191f,
 	0x1a5f,
-	0x1cf7,
+	0x1dfa,
 	0x1f58,
 	0x1f5a,
 	0x1f5c,
@@ -351,7 +350,6 @@
 	0x1fdc,
 	0x1ff5,
 	0x208f,
-	0x23ff,
 	0x2bc9,
 	0x2c2f,
 	0x2c5f,
@@ -398,7 +396,7 @@
 	0x0102a0, 0x0102d0,
 	0x0102e0, 0x0102fb,
 	0x010300, 0x010323,
-	0x010330, 0x01034a,
+	0x01032d, 0x01034a,
 	0x010350, 0x01037a,
 	0x010380, 0x0103c3,
 	0x0103c8, 0x0103d5,
@@ -481,11 +479,17 @@
 	0x011730, 0x01173f,
 	0x0118a0, 0x0118f2,
 	0x0118ff, 0x0118ff,
+	0x011a00, 0x011a47,
+	0x011a50, 0x011a83,
+	0x011a86, 0x011aa2,
 	0x011ac0, 0x011af8,
 	0x011c00, 0x011c45,
 	0x011c50, 0x011c6c,
 	0x011c70, 0x011c8f,
 	0x011c92, 0x011cb6,
+	0x011d00, 0x011d36,
+	0x011d3a, 0x011d47,
+	0x011d50, 0x011d59,
 	0x012000, 0x012399,
 	0x012400, 0x012474,
 	0x012480, 0x012543,
@@ -502,10 +506,11 @@
 	0x016f00, 0x016f44,
 	0x016f50, 0x016f7e,
 	0x016f8f, 0x016f9f,
-	0x016fe0, 0x016fe0,
+	0x016fe0, 0x016fe1,
 	0x017000, 0x0187ec,
 	0x018800, 0x018af2,
-	0x01b000, 0x01b001,
+	0x01b000, 0x01b11e,
+	0x01b170, 0x01b2fb,
 	0x01bc00, 0x01bc6a,
 	0x01bc70, 0x01bc7c,
 	0x01bc80, 0x01bc88,
@@ -553,9 +558,10 @@
 	0x01f210, 0x01f23b,
 	0x01f240, 0x01f248,
 	0x01f250, 0x01f251,
-	0x01f300, 0x01f6d2,
+	0x01f260, 0x01f265,
+	0x01f300, 0x01f6d4,
 	0x01f6e0, 0x01f6ec,
-	0x01f6f0, 0x01f6f6,
+	0x01f6f0, 0x01f6f8,
 	0x01f700, 0x01f773,
 	0x01f780, 0x01f7d4,
 	0x01f800, 0x01f80b,
@@ -563,16 +569,17 @@
 	0x01f850, 0x01f859,
 	0x01f860, 0x01f887,
 	0x01f890, 0x01f8ad,
-	0x01f910, 0x01f927,
-	0x01f930, 0x01f930,
-	0x01f933, 0x01f94b,
-	0x01f950, 0x01f95e,
-	0x01f980, 0x01f991,
+	0x01f900, 0x01f90b,
+	0x01f910, 0x01f94c,
+	0x01f950, 0x01f96b,
+	0x01f980, 0x01f997,
 	0x01f9c0, 0x01f9c0,
+	0x01f9d0, 0x01f9e6,
 	0x020000, 0x02a6d6,
 	0x02a700, 0x02b734,
 	0x02b740, 0x02b81d,
 	0x02b820, 0x02cea1,
+	0x02ceb0, 0x02ebe0,
 	0x02f800, 0x02fa1d,
 	0x0e0100, 0x0e01ef,
 }
@@ -605,9 +612,14 @@
 	0x1334,
 	0x145a,
 	0x145c,
+	0x1a9d,
 	0x1c09,
 	0x1c37,
 	0x1ca8,
+	0x1d07,
+	0x1d0a,
+	0x1d3b,
+	0x1d3e,
 	0x246f,
 	0x6a5f,
 	0x6b5a,
@@ -658,7 +670,6 @@
 	0xf0c0,
 	0xf0d0,
 	0xf12f,
-	0xf91f,
 	0xf93f,
 }
 
diff --git a/src/strconv/quote.go b/src/strconv/quote.go
index db57065..156a510 100644
--- a/src/strconv/quote.go
+++ b/src/strconv/quote.go
@@ -381,7 +381,7 @@
 		return "", ErrSyntax
 	}
 
-	// Is it trivial?  Avoid allocation.
+	// Is it trivial? Avoid allocation.
 	if !contains(s, '\\') && !contains(s, quote) {
 		switch quote {
 		case '"':
diff --git a/src/strings/builder.go b/src/strings/builder.go
new file mode 100644
index 0000000..ac58f34
--- /dev/null
+++ b/src/strings/builder.go
@@ -0,0 +1,119 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings
+
+import (
+	"unicode/utf8"
+	"unsafe"
+)
+
+// A Builder is used to efficiently build a string using Write methods.
+// It minimizes memory copying. The zero value is ready to use.
+// Do not copy a non-zero Builder.
+type Builder struct {
+	addr *Builder // of receiver, to detect copies by value
+	buf  []byte
+}
+
+// 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 zero instructions.
+// USE CAREFULLY!
+// This was copied from the runtime; see issues 23382 and 7921.
+//go:nosplit
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+	x := uintptr(p)
+	return unsafe.Pointer(x ^ 0)
+}
+
+func (b *Builder) copyCheck() {
+	if b.addr == nil {
+		// This hack works around a failing of Go's escape analysis
+		// that was causing b to escape and be heap allocated.
+		// See issue 23382.
+		// TODO: once issue 7921 is fixed, this should be reverted to
+		// just "b.addr = b".
+		b.addr = (*Builder)(noescape(unsafe.Pointer(b)))
+	} else if b.addr != b {
+		panic("strings: illegal use of non-zero Builder copied by value")
+	}
+}
+
+// String returns the accumulated string.
+func (b *Builder) String() string {
+	return *(*string)(unsafe.Pointer(&b.buf))
+}
+
+// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
+func (b *Builder) Len() int { return len(b.buf) }
+
+// Reset resets the Builder to be empty.
+func (b *Builder) Reset() {
+	b.addr = nil
+	b.buf = nil
+}
+
+// grow copies the buffer to a new, larger buffer so that there are at least n
+// bytes of capacity beyond len(b.buf).
+func (b *Builder) grow(n int) {
+	buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
+	copy(buf, b.buf)
+	b.buf = buf
+}
+
+// Grow grows b's capacity, if necessary, to guarantee space for
+// another n bytes. After Grow(n), at least n bytes can be written to b
+// without another allocation. If n is negative, Grow panics.
+func (b *Builder) Grow(n int) {
+	b.copyCheck()
+	if n < 0 {
+		panic("strings.Builder.Grow: negative count")
+	}
+	if cap(b.buf)-len(b.buf) < n {
+		b.grow(n)
+	}
+}
+
+// Write appends the contents of p to b's buffer.
+// Write always returns len(p), nil.
+func (b *Builder) Write(p []byte) (int, error) {
+	b.copyCheck()
+	b.buf = append(b.buf, p...)
+	return len(p), nil
+}
+
+// WriteByte appends the byte c to b's buffer.
+// The returned error is always nil.
+func (b *Builder) WriteByte(c byte) error {
+	b.copyCheck()
+	b.buf = append(b.buf, c)
+	return nil
+}
+
+// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
+// It returns the length of r and a nil error.
+func (b *Builder) WriteRune(r rune) (int, error) {
+	b.copyCheck()
+	if r < utf8.RuneSelf {
+		b.buf = append(b.buf, byte(r))
+		return 1, nil
+	}
+	l := len(b.buf)
+	if cap(b.buf)-l < utf8.UTFMax {
+		b.grow(utf8.UTFMax)
+	}
+	n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
+	b.buf = b.buf[:l+n]
+	return n, nil
+}
+
+// WriteString appends the contents of s to b's buffer.
+// It returns the length of s and a nil error.
+func (b *Builder) WriteString(s string) (int, error) {
+	b.copyCheck()
+	b.buf = append(b.buf, s...)
+	return len(s), nil
+}
diff --git a/src/strings/builder_test.go b/src/strings/builder_test.go
new file mode 100644
index 0000000..ecbaeaa
--- /dev/null
+++ b/src/strings/builder_test.go
@@ -0,0 +1,304 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings_test
+
+import (
+	"bytes"
+	"runtime"
+	. "strings"
+	"testing"
+)
+
+func check(t *testing.T, b *Builder, want string) {
+	t.Helper()
+	got := b.String()
+	if got != want {
+		t.Errorf("String: got %#q; want %#q", got, want)
+		return
+	}
+	if n := b.Len(); n != len(got) {
+		t.Errorf("Len: got %d; but len(String()) is %d", n, len(got))
+	}
+}
+
+func TestBuilder(t *testing.T) {
+	var b Builder
+	check(t, &b, "")
+	n, err := b.WriteString("hello")
+	if err != nil || n != 5 {
+		t.Errorf("WriteString: got %d,%s; want 5,nil", n, err)
+	}
+	check(t, &b, "hello")
+	if err = b.WriteByte(' '); err != nil {
+		t.Errorf("WriteByte: %s", err)
+	}
+	check(t, &b, "hello ")
+	n, err = b.WriteString("world")
+	if err != nil || n != 5 {
+		t.Errorf("WriteString: got %d,%s; want 5,nil", n, err)
+	}
+	check(t, &b, "hello world")
+}
+
+func TestBuilderString(t *testing.T) {
+	var b Builder
+	b.WriteString("alpha")
+	check(t, &b, "alpha")
+	s1 := b.String()
+	b.WriteString("beta")
+	check(t, &b, "alphabeta")
+	s2 := b.String()
+	b.WriteString("gamma")
+	check(t, &b, "alphabetagamma")
+	s3 := b.String()
+
+	// Check that subsequent operations didn't change the returned strings.
+	if want := "alpha"; s1 != want {
+		t.Errorf("first String result is now %q; want %q", s1, want)
+	}
+	if want := "alphabeta"; s2 != want {
+		t.Errorf("second String result is now %q; want %q", s2, want)
+	}
+	if want := "alphabetagamma"; s3 != want {
+		t.Errorf("third String result is now %q; want %q", s3, want)
+	}
+}
+
+func TestBuilderReset(t *testing.T) {
+	var b Builder
+	check(t, &b, "")
+	b.WriteString("aaa")
+	s := b.String()
+	check(t, &b, "aaa")
+	b.Reset()
+	check(t, &b, "")
+
+	// Ensure that writing after Reset doesn't alter
+	// previously returned strings.
+	b.WriteString("bbb")
+	check(t, &b, "bbb")
+	if want := "aaa"; s != want {
+		t.Errorf("previous String result changed after Reset: got %q; want %q", s, want)
+	}
+}
+
+func TestBuilderGrow(t *testing.T) {
+	for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
+		var b Builder
+		b.Grow(growLen)
+		p := bytes.Repeat([]byte{'a'}, growLen)
+		allocs := numAllocs(func() { b.Write(p) })
+		if allocs > 0 {
+			t.Errorf("growLen=%d: allocation occurred during write", growLen)
+		}
+		if b.String() != string(p) {
+			t.Errorf("growLen=%d: bad data written after Grow", growLen)
+		}
+	}
+}
+
+func TestBuilderWrite2(t *testing.T) {
+	const s0 = "hello 世界"
+	for _, tt := range []struct {
+		name string
+		fn   func(b *Builder) (int, error)
+		n    int
+		want string
+	}{
+		{
+			"Write",
+			func(b *Builder) (int, error) { return b.Write([]byte(s0)) },
+			len(s0),
+			s0,
+		},
+		{
+			"WriteRune",
+			func(b *Builder) (int, error) { return b.WriteRune('a') },
+			1,
+			"a",
+		},
+		{
+			"WriteRuneWide",
+			func(b *Builder) (int, error) { return b.WriteRune('世') },
+			3,
+			"世",
+		},
+		{
+			"WriteString",
+			func(b *Builder) (int, error) { return b.WriteString(s0) },
+			len(s0),
+			s0,
+		},
+	} {
+		t.Run(tt.name, func(t *testing.T) {
+			var b Builder
+			n, err := tt.fn(&b)
+			if err != nil {
+				t.Fatalf("first call: got %s", err)
+			}
+			if n != tt.n {
+				t.Errorf("first call: got n=%d; want %d", n, tt.n)
+			}
+			check(t, &b, tt.want)
+
+			n, err = tt.fn(&b)
+			if err != nil {
+				t.Fatalf("second call: got %s", err)
+			}
+			if n != tt.n {
+				t.Errorf("second call: got n=%d; want %d", n, tt.n)
+			}
+			check(t, &b, tt.want+tt.want)
+		})
+	}
+}
+
+func TestBuilderWriteByte(t *testing.T) {
+	var b Builder
+	if err := b.WriteByte('a'); err != nil {
+		t.Error(err)
+	}
+	if err := b.WriteByte(0); err != nil {
+		t.Error(err)
+	}
+	check(t, &b, "a\x00")
+}
+
+func TestBuilderAllocs(t *testing.T) {
+	var b Builder
+	b.Grow(5)
+	var s string
+	allocs := numAllocs(func() {
+		b.WriteString("hello")
+		s = b.String()
+	})
+	if want := "hello"; s != want {
+		t.Errorf("String: got %#q; want %#q", s, want)
+	}
+	if allocs > 0 {
+		t.Fatalf("got %d alloc(s); want 0", allocs)
+	}
+
+	// Issue 23382; verify that copyCheck doesn't force the
+	// Builder to escape and be heap allocated.
+	n := testing.AllocsPerRun(10000, func() {
+		var b Builder
+		b.Grow(5)
+		b.WriteString("abcde")
+		_ = b.String()
+	})
+	if n != 1 {
+		t.Errorf("Builder allocs = %v; want 1", n)
+	}
+}
+
+func numAllocs(fn func()) uint64 {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+	var m1, m2 runtime.MemStats
+	runtime.ReadMemStats(&m1)
+	fn()
+	runtime.ReadMemStats(&m2)
+	return m2.Mallocs - m1.Mallocs
+}
+
+func TestBuilderCopyPanic(t *testing.T) {
+	tests := []struct {
+		name      string
+		fn        func()
+		wantPanic bool
+	}{
+		{
+			name:      "String",
+			wantPanic: false,
+			fn: func() {
+				var a Builder
+				a.WriteByte('x')
+				b := a
+				_ = b.String() // appease vet
+			},
+		},
+		{
+			name:      "Len",
+			wantPanic: false,
+			fn: func() {
+				var a Builder
+				a.WriteByte('x')
+				b := a
+				b.Len()
+			},
+		},
+		{
+			name:      "Reset",
+			wantPanic: false,
+			fn: func() {
+				var a Builder
+				a.WriteByte('x')
+				b := a
+				b.Reset()
+				b.WriteByte('y')
+			},
+		},
+		{
+			name:      "Write",
+			wantPanic: true,
+			fn: func() {
+				var a Builder
+				a.Write([]byte("x"))
+				b := a
+				b.Write([]byte("y"))
+			},
+		},
+		{
+			name:      "WriteByte",
+			wantPanic: true,
+			fn: func() {
+				var a Builder
+				a.WriteByte('x')
+				b := a
+				b.WriteByte('y')
+			},
+		},
+		{
+			name:      "WriteString",
+			wantPanic: true,
+			fn: func() {
+				var a Builder
+				a.WriteString("x")
+				b := a
+				b.WriteString("y")
+			},
+		},
+		{
+			name:      "WriteRune",
+			wantPanic: true,
+			fn: func() {
+				var a Builder
+				a.WriteRune('x')
+				b := a
+				b.WriteRune('y')
+			},
+		},
+		{
+			name:      "Grow",
+			wantPanic: true,
+			fn: func() {
+				var a Builder
+				a.Grow(1)
+				b := a
+				b.Grow(2)
+			},
+		},
+	}
+	for _, tt := range tests {
+		didPanic := make(chan bool)
+		go func() {
+			defer func() { didPanic <- recover() != nil }()
+			tt.fn()
+		}()
+		if got := <-didPanic; got != tt.wantPanic {
+			t.Errorf("%s: panicked = %v; want %v", tt.name, got, tt.wantPanic)
+		}
+	}
+}
diff --git a/src/strings/example_test.go b/src/strings/example_test.go
index e962152..607e4a0 100644
--- a/src/strings/example_test.go
+++ b/src/strings/example_test.go
@@ -166,6 +166,26 @@
 	// -1
 }
 
+func ExampleLastIndexByte() {
+	fmt.Println(strings.LastIndexByte("Hello, world", 'l'))
+	fmt.Println(strings.LastIndexByte("Hello, world", 'o'))
+	fmt.Println(strings.LastIndexByte("Hello, world", 'x'))
+	// Output:
+	// 10
+	// 8
+	// -1
+}
+
+func ExampleLastIndexFunc() {
+	fmt.Println(strings.LastIndexFunc("go 123", unicode.IsNumber))
+	fmt.Println(strings.LastIndexFunc("123 go", unicode.IsNumber))
+	fmt.Println(strings.LastIndexFunc("go", unicode.IsNumber))
+	// Output:
+	// 5
+	// 2
+	// -1
+}
+
 func ExampleJoin() {
 	s := []string{"foo", "bar", "baz"}
 	fmt.Println(strings.Join(s, ", "))
@@ -229,17 +249,10 @@
 	// ХЛЕБ
 }
 
-func ExampleTrim() {
-	fmt.Printf("[%q]", strings.Trim(" !!! Achtung! Achtung! !!! ", "! "))
-	// Output: ["Achtung! Achtung"]
-}
-
-func ExampleTrimFunc() {
-	f := func(c rune) bool {
-		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
-	}
-	fmt.Printf("[%q]", strings.TrimFunc("  Achtung1! Achtung2,...", f))
-	// Output: ["Achtung1! Achtung2"]
+func ExampleToTitleSpecial() {
+	fmt.Println(strings.ToTitleSpecial(unicode.TurkishCase, "dünyanın ilk borsa yapısı Aizonai kabul edilir"))
+	// Output:
+	// DÜNYANIN İLK BORSA YAPISI AİZONAİ KABUL EDİLİR
 }
 
 func ExampleMap() {
@@ -256,11 +269,6 @@
 	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
 }
 
-func ExampleTrimSpace() {
-	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
-	// Output: a lone gopher
-}
-
 func ExampleNewReplacer() {
 	r := strings.NewReplacer("<", "&lt;", ">", "&gt;")
 	fmt.Println(r.Replace("This is <b>HTML</b>!"))
@@ -272,23 +280,85 @@
 	// Output: GOPHER
 }
 
+func ExampleToUpperSpecial() {
+	fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "örnek iş"))
+	// Output: ÖRNEK İŞ
+}
+
 func ExampleToLower() {
 	fmt.Println(strings.ToLower("Gopher"))
 	// Output: gopher
 }
 
-func ExampleTrimSuffix() {
-	var s = "Hello, goodbye, etc!"
-	s = strings.TrimSuffix(s, "goodbye, etc!")
-	s = strings.TrimSuffix(s, "planet")
-	fmt.Print(s, "world!")
-	// Output: Hello, world!
+func ExampleToLowerSpecial() {
+	fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "Önnek İş"))
+	// Output: önnek iş
+}
+
+func ExampleTrim() {
+	fmt.Print(strings.Trim("¡¡¡Hello, Gophers!!!", "!¡"))
+	// Output: Hello, Gophers
+}
+
+func ExampleTrimSpace() {
+	fmt.Println(strings.TrimSpace(" \t\n Hello, Gophers \n\t\r\n"))
+	// Output: Hello, Gophers
 }
 
 func ExampleTrimPrefix() {
-	var s = "Goodbye,, world!"
-	s = strings.TrimPrefix(s, "Goodbye,")
-	s = strings.TrimPrefix(s, "Howdy,")
-	fmt.Print("Hello" + s)
-	// Output: Hello, world!
+	var s = "¡¡¡Hello, Gophers!!!"
+	s = strings.TrimPrefix(s, "¡¡¡Hello, ")
+	s = strings.TrimPrefix(s, "¡¡¡Howdy, ")
+	fmt.Print(s)
+	// Output: Gophers!!!
+}
+
+func ExampleTrimSuffix() {
+	var s = "¡¡¡Hello, Gophers!!!"
+	s = strings.TrimSuffix(s, ", Gophers!!!")
+	s = strings.TrimSuffix(s, ", Marmots!!!")
+	fmt.Print(s)
+	// Output: ¡¡¡Hello
+}
+
+func ExampleTrimFunc() {
+	fmt.Print(strings.TrimFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
+		return !unicode.IsLetter(r) && !unicode.IsNumber(r)
+	}))
+	// Output: Hello, Gophers
+}
+
+func ExampleTrimLeft() {
+	fmt.Print(strings.TrimLeft("¡¡¡Hello, Gophers!!!", "!¡"))
+	// Output: Hello, Gophers!!!
+}
+
+func ExampleTrimLeftFunc() {
+	fmt.Print(strings.TrimLeftFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
+		return !unicode.IsLetter(r) && !unicode.IsNumber(r)
+	}))
+	// Output: Hello, Gophers!!!
+}
+
+func ExampleTrimRight() {
+	fmt.Print(strings.TrimRight("¡¡¡Hello, Gophers!!!", "!¡"))
+	// Output: ¡¡¡Hello, Gophers
+}
+
+func ExampleTrimRightFunc() {
+	fmt.Print(strings.TrimRightFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
+		return !unicode.IsLetter(r) && !unicode.IsNumber(r)
+	}))
+	// Output: ¡¡¡Hello, Gophers
+}
+
+func ExampleBuilder() {
+	var b strings.Builder
+	for i := 3; i >= 1; i-- {
+		fmt.Fprintf(&b, "%d...", i)
+	}
+	b.WriteString("ignition")
+	fmt.Println(b.String())
+
+	// Output: 3...2...1...ignition
 }
diff --git a/src/strings/strings.go b/src/strings/strings.go
index 0c836c0..02c0320 100644
--- a/src/strings/strings.go
+++ b/src/strings/strings.go
@@ -166,23 +166,25 @@
 // 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 {
-		if len(s) > 8 {
-			if as, isASCII := makeASCIISet(chars); isASCII {
-				for i := 0; i < len(s); i++ {
-					if as.contains(s[i]) {
-						return i
-					}
-				}
-				return -1
-			}
-		}
-		for i, c := range s {
-			for _, m := range chars {
-				if c == m {
+	if chars == "" {
+		// Avoid scanning all of s.
+		return -1
+	}
+	if len(s) > 8 {
+		if as, isASCII := makeASCIISet(chars); isASCII {
+			for i := 0; i < len(s); i++ {
+				if as.contains(s[i]) {
 					return i
 				}
 			}
+			return -1
+		}
+	}
+	for i, c := range s {
+		for _, m := range chars {
+			if c == m {
+				return i
+			}
 		}
 	}
 	return -1
@@ -192,25 +194,27 @@
 // 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 {
-		if len(s) > 8 {
-			if as, isASCII := makeASCIISet(chars); isASCII {
-				for i := len(s) - 1; i >= 0; i-- {
-					if as.contains(s[i]) {
-						return i
-					}
-				}
-				return -1
-			}
-		}
-		for i := len(s); i > 0; {
-			r, size := utf8.DecodeLastRuneInString(s[:i])
-			i -= size
-			for _, c := range chars {
-				if r == c {
+	if chars == "" {
+		// Avoid scanning all of s.
+		return -1
+	}
+	if len(s) > 8 {
+		if as, isASCII := makeASCIISet(chars); isASCII {
+			for i := len(s) - 1; i >= 0; i-- {
+				if as.contains(s[i]) {
 					return i
 				}
 			}
+			return -1
+		}
+	}
+	for i := len(s); i > 0; {
+		r, size := utf8.DecodeLastRuneInString(s[:i])
+		i -= size
+		for _, c := range chars {
+			if r == c {
+				return i
+			}
 		}
 	}
 	return -1
@@ -310,8 +314,8 @@
 var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 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.
+// characters, as defined by unicode.IsSpace, returning a slice of substrings of s or an
+// empty slice if s contains only white space.
 func Fields(s string) []string {
 	// First count the fields.
 	// This is an exact count if s is ASCII, otherwise it is an approximation.
@@ -358,67 +362,7 @@
 	}
 
 	// Some runes in the input string are not ASCII.
-	// Same general approach as in the ASCII path but
-	// uses DecodeRuneInString and unicode.IsSpace if
-	// a non-ASCII rune needs to be decoded and checked
-	// if it corresponds to a space.
-	a := make([]string, 0, n)
-	fieldStart := 0
-	i := 0
-	// Skip spaces in the front of the input.
-	for i < len(s) {
-		if c := s[i]; c < utf8.RuneSelf {
-			if asciiSpace[c] == 0 {
-				break
-			}
-			i++
-		} else {
-			r, w := utf8.DecodeRuneInString(s[i:])
-			if !unicode.IsSpace(r) {
-				break
-			}
-			i += w
-		}
-	}
-	fieldStart = i
-	for i < len(s) {
-		if c := s[i]; c < utf8.RuneSelf {
-			if asciiSpace[c] == 0 {
-				i++
-				continue
-			}
-			a = append(a, s[fieldStart:i])
-			i++
-		} else {
-			r, w := utf8.DecodeRuneInString(s[i:])
-			if !unicode.IsSpace(r) {
-				i += w
-				continue
-			}
-			a = append(a, s[fieldStart:i])
-			i += w
-		}
-		// Skip spaces in between fields.
-		for i < len(s) {
-			if c := s[i]; c < utf8.RuneSelf {
-				if asciiSpace[c] == 0 {
-					break
-				}
-				i++
-			} else {
-				r, w := utf8.DecodeRuneInString(s[i:])
-				if !unicode.IsSpace(r) {
-					break
-				}
-				i += w
-			}
-		}
-		fieldStart = i
-	}
-	if fieldStart < len(s) { // Last field might end at EOF.
-		a = append(a, s[fieldStart:])
-	}
-	return a
+	return FieldsFunc(s, unicode.IsSpace)
 }
 
 // FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
@@ -427,35 +371,42 @@
 // 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++
+	// A span is used to record a slice of s of the form s[start:end].
+	// The start index is inclusive and the end index is exclusive.
+	type span struct {
+		start int
+		end   int
+	}
+	spans := make([]span, 0, 32)
+
+	// Find the field start and end indices.
+	wasField := false
+	fromIndex := 0
+	for i, rune := range s {
+		if f(rune) {
+			if wasField {
+				spans = append(spans, span{start: fromIndex, end: i})
+				wasField = false
+			}
+		} else {
+			if !wasField {
+				fromIndex = i
+				wasField = true
+			}
 		}
 	}
 
-	// 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
-		}
+	// Last field might end at EOF.
+	if wasField {
+		spans = append(spans, span{fromIndex, len(s)})
 	}
-	if fieldStart >= 0 { // Last field might end at EOF.
-		a[na] = s[fieldStart:]
+
+	// Create strings from recorded field indices.
+	a := make([]string, len(spans))
+	for i, span := range spans {
+		a[i] = s[span.start:span.end]
 	}
+
 	return a
 }
 
@@ -599,10 +550,62 @@
 }
 
 // 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) }
+func ToUpper(s string) string {
+	isASCII, hasLower := true, false
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if c >= utf8.RuneSelf {
+			isASCII = false
+			break
+		}
+		hasLower = hasLower || (c >= 'a' && c <= 'z')
+	}
+
+	if isASCII { // optimize for ASCII-only strings.
+		if !hasLower {
+			return s
+		}
+		b := make([]byte, len(s))
+		for i := 0; i < len(s); i++ {
+			c := s[i]
+			if c >= 'a' && c <= 'z' {
+				c -= 'a' - 'A'
+			}
+			b[i] = c
+		}
+		return string(b)
+	}
+	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) }
+func ToLower(s string) string {
+	isASCII, hasUpper := true, false
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if c >= utf8.RuneSelf {
+			isASCII = false
+			break
+		}
+		hasUpper = hasUpper || (c >= 'A' && c <= 'Z')
+	}
+
+	if isASCII { // optimize for ASCII-only strings.
+		if !hasUpper {
+			return s
+		}
+		b := make([]byte, len(s))
+		for i := 0; i < len(s); i++ {
+			c := s[i]
+			if c >= 'A' && c <= 'Z' {
+				c += 'a' - 'A'
+			}
+			b[i] = c
+		}
+		return string(b)
+	}
+	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) }
@@ -923,3 +926,27 @@
 	// One string is empty. Are both?
 	return s == t
 }
+
+func indexRabinKarp(s, substr string) int {
+	// Rabin-Karp search
+	hashss, pow := hashStr(substr)
+	n := len(substr)
+	var h uint32
+	for i := 0; i < n; i++ {
+		h = h*primeRK + uint32(s[i])
+	}
+	if h == hashss && s[:n] == substr {
+		return 0
+	}
+	for i := n; i < len(s); {
+		h *= primeRK
+		h += uint32(s[i])
+		h -= pow * uint32(s[i-n])
+		i++
+		if h == hashss && s[i-n:i] == substr {
+			return i - n
+		}
+	}
+	return -1
+
+}
diff --git a/src/strings/strings_amd64.go b/src/strings/strings_amd64.go
index a9c01bb..68a1d01 100644
--- a/src/strings/strings_amd64.go
+++ b/src/strings/strings_amd64.go
@@ -75,25 +75,7 @@
 		}
 		return -1
 	}
-	// Rabin-Karp search
-	hashss, pow := hashStr(substr)
-	var h uint32
-	for i := 0; i < n; i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	if h == hashss && s[:n] == substr {
-		return 0
-	}
-	for i := n; i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-n])
-		i++
-		if h == hashss && s[i-n:i] == substr {
-			return i - n
-		}
-	}
-	return -1
+	return indexRabinKarp(s, substr)
 }
 
 // Count counts the number of non-overlapping instances of substr in s.
diff --git a/src/strings/strings_generic.go b/src/strings/strings_generic.go
index 5429a74..b2af48b 100644
--- a/src/strings/strings_generic.go
+++ b/src/strings/strings_generic.go
@@ -25,22 +25,30 @@
 	case n > len(s):
 		return -1
 	}
-	// Rabin-Karp search
-	hashss, pow := hashStr(substr)
-	var h uint32
-	for i := 0; i < n; i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	if h == hashss && s[:n] == substr {
-		return 0
-	}
-	for i := n; i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-n])
+	c := substr[0]
+	i := 0
+	t := s[:len(s)-n+1]
+	fails := 0
+	for i < len(t) {
+		if t[i] != c {
+			o := IndexByte(t[i:], c)
+			if o < 0 {
+				return -1
+			}
+			i += o
+		}
+		if s[i:i+n] == substr {
+			return i
+		}
 		i++
-		if h == hashss && s[i-n:i] == substr {
-			return i - n
+		fails++
+		if fails >= 4+i>>4 && i < len(t) {
+			// See comment in ../bytes/bytes_generic.go.
+			j := indexRabinKarp(s[i:], substr)
+			if j < 0 {
+				return -1
+			}
+			return i + j
 		}
 	}
 	return -1
diff --git a/src/strings/strings_s390x.go b/src/strings/strings_s390x.go
index ccf2da6..67c8e17 100644
--- a/src/strings/strings_s390x.go
+++ b/src/strings/strings_s390x.go
@@ -76,25 +76,7 @@
 		}
 		return -1
 	}
-	// Rabin-Karp search
-	hashss, pow := hashStr(substr)
-	var h uint32
-	for i := 0; i < n; i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	if h == hashss && s[:n] == substr {
-		return 0
-	}
-	for i := n; i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-n])
-		i++
-		if h == hashss && s[i-n:i] == substr {
-			return i - n
-		}
-	}
-	return -1
+	return indexRabinKarp(s, substr)
 }
 
 // Count counts the number of non-overlapping instances of substr in s.
diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go
index 869be9c..d8fcb62 100644
--- a/src/strings/strings_test.go
+++ b/src/strings/strings_test.go
@@ -125,6 +125,9 @@
 	{"xx012345678901234567890123456789012345678901234567890123456789012"[:41], "0123456789012345678901234567890123456789", -1},
 	{"xx012345678901234567890123456789012345678901234567890123456789012", "0123456789012345678901234567890123456xxx", -1},
 	{"xx0123456789012345678901234567890123456789012345678901234567890120123456789012345678901234567890123456xxx", "0123456789012345678901234567890123456xxx", 65},
+	// test fallback to Rabin-Karp.
+	{"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22},
+	{"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1},
 }
 
 var lastIndexTests = []IndexTest{
@@ -518,9 +521,12 @@
 
 var upperTests = []StringTest{
 	{"", ""},
+	{"ONLYUPPER", "ONLYUPPER"},
 	{"abc", "ABC"},
 	{"AbC123", "ABC123"},
 	{"azAZ09_", "AZAZ09_"},
+	{"longStrinGwitHmixofsmaLLandcAps", "LONGSTRINGWITHMIXOFSMALLANDCAPS"},
+	{"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", "LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS"},
 	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
 }
 
@@ -529,6 +535,8 @@
 	{"abc", "abc"},
 	{"AbC123", "abc123"},
 	{"azAZ09_", "azaz09_"},
+	{"longStrinGwitHmixofsmaLLandcAps", "longstringwithmixofsmallandcaps"},
+	{"LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS", "long\u0250string\u0250with\u0250nonascii\u0250chars"},
 	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
 }
 
@@ -648,6 +656,32 @@
 
 func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
 
+func BenchmarkToUpper(b *testing.B) {
+	for _, tc := range upperTests {
+		b.Run(tc.in, func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				actual := ToUpper(tc.in)
+				if actual != tc.out {
+					b.Errorf("ToUpper(%q) = %q; want %q", tc.in, actual, tc.out)
+				}
+			}
+		})
+	}
+}
+
+func BenchmarkToLower(b *testing.B) {
+	for _, tc := range lowerTests {
+		b.Run(tc.in, func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				actual := ToLower(tc.in)
+				if actual != tc.out {
+					b.Errorf("ToLower(%q) = %q; want %q", tc.in, actual, tc.out)
+				}
+			}
+		})
+	}
+}
+
 func BenchmarkMapNoChanges(b *testing.B) {
 	identity := func(r rune) rune {
 		return r
@@ -1610,3 +1644,15 @@
 		}
 	}
 }
+
+func BenchmarkIndexPeriodic(b *testing.B) {
+	key := "aa"
+	for _, skip := range [...]int{2, 4, 8, 16, 32, 64} {
+		b.Run(fmt.Sprintf("IndexPeriodic%d", skip), func(b *testing.B) {
+			s := Repeat("a"+Repeat(" ", skip-1), 1<<16/skip)
+			for i := 0; i < b.N; i++ {
+				Index(s, key)
+			}
+		})
+	}
+}
diff --git a/src/sync/atomic/asm_darwin_arm.s b/src/sync/atomic/asm_darwin_arm.s
index c643360..2268229 100644
--- a/src/sync/atomic/asm_darwin_arm.s
+++ b/src/sync/atomic/asm_darwin_arm.s
@@ -6,6 +6,12 @@
 
 // Darwin/ARM atomic operations.
 
+#define DMB_ISHST_7 \
+    WORD    $0xf57ff05a // dmb ishst
+
+#define DMB_ISH_7 \
+    WORD    $0xf57ff05b // dmb ish
+
 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
 	B ·CompareAndSwapUint32(SB)
 
@@ -58,9 +64,11 @@
 	MOVW addr+0(FP), R1
 load32loop:
 	LDREX (R1), R2		// loads R2
+	DMB_ISHST_7
 	STREX R2, (R1), R0	// stores R2
 	CMP $0, R0
 	BNE load32loop
+	DMB_ISH_7
 	MOVW R2, val+4(FP)
 	RET
 
@@ -84,9 +92,11 @@
 	MOVW val+4(FP), R2
 storeloop:
 	LDREX (R1), R4		// loads R4
+	DMB_ISHST_7
 	STREX R2, (R1), R0	// stores R2
 	CMP $0, R0
 	BNE storeloop
+	DMB_ISH_7
 	RET
 
 TEXT ·StoreInt64(SB),NOSPLIT,$0
diff --git a/src/sync/atomic/atomic_test.go b/src/sync/atomic/atomic_test.go
index 17baccb..39c40c6 100644
--- a/src/sync/atomic/atomic_test.go
+++ b/src/sync/atomic/atomic_test.go
@@ -30,7 +30,7 @@
 	magic64 = 0xdeddeadbeefbeef
 )
 
-// Do the 64-bit functions panic?  If so, don't bother testing.
+// Do the 64-bit functions panic? If so, don't bother testing.
 var test64err = func() (err interface{}) {
 	defer func() {
 		err = recover()
@@ -772,10 +772,8 @@
 	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")
 	}
 }
 
@@ -923,10 +921,8 @@
 	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")
 	}
 }
 
diff --git a/src/sync/atomic/value.go b/src/sync/atomic/value.go
index 1fc1f68..eab7e70 100644
--- a/src/sync/atomic/value.go
+++ b/src/sync/atomic/value.go
@@ -14,8 +14,6 @@
 //
 // A Value must not be copied after first use.
 type Value struct {
-	noCopy noCopy
-
 	v interface{}
 }
 
@@ -86,13 +84,3 @@
 // Disable/enable preemption, implemented in runtime.
 func runtime_procPin()
 func runtime_procUnpin()
-
-// noCopy may be embedded into structs which must not be copied
-// after the first use.
-//
-// See https://github.com/golang/go/issues/8005#issuecomment-190753527
-// for details.
-type noCopy struct{}
-
-// Lock is a no-op used by -copylocks checker from `go vet`.
-func (*noCopy) Lock() {}
diff --git a/src/sync/cond.go b/src/sync/cond.go
index 14e2f6b..3dcbf1c 100644
--- a/src/sync/cond.go
+++ b/src/sync/cond.go
@@ -89,7 +89,7 @@
 // noCopy may be embedded into structs which must not be copied
 // after the first use.
 //
-// See https://github.com/golang/go/issues/8005#issuecomment-190753527
+// See https://golang.org/issues/8005#issuecomment-190753527
 // for details.
 type noCopy struct{}
 
diff --git a/src/sync/map.go b/src/sync/map.go
index 083f4a5..c4a0dc4 100644
--- a/src/sync/map.go
+++ b/src/sync/map.go
@@ -9,20 +9,21 @@
 	"unsafe"
 )
 
-// Map is a concurrent map with amortized-constant-time loads, stores, and deletes.
-// It is safe for multiple goroutines to call a Map's methods concurrently.
+// Map is like a Go map[interface{}]interface{} but is safe for concurrent use
+// by multiple goroutines without additional locking or coordination.
+// Loads, stores, and deletes run in amortized constant time.
 //
-// It is optimized for use in concurrent loops with keys that are
-// stable over time, and either few steady-state stores, or stores
-// localized to one goroutine per key.
+// The Map type is specialized. Most code should use a plain Go map instead,
+// with separate locking or coordination, for better type safety and to make it
+// easier to maintain other invariants along with the map content.
 //
-// For use cases that do not share these attributes, it will likely have
-// comparable or worse performance and worse type safety than an ordinary
-// map paired with a read-write mutex.
+// The Map type is optimized for two common use cases: (1) when the entry for a given
+// key is only ever written once but read many times, as in caches that only grow,
+// or (2) when multiple goroutines read, write, and overwrite entries for disjoint
+// sets of keys. In these two cases, use of a Map may significantly reduce lock
+// contention compared to a Go map paired with a separate Mutex or RWMutex.
 //
-// The zero Map is valid and empty.
-//
-// A Map must not be copied after first use.
+// The zero Map is empty and ready for use. A Map must not be copied after first use.
 type Map struct {
 	mu Mutex
 
diff --git a/src/sync/mutex.go b/src/sync/mutex.go
index 1232c62..4c5582c 100644
--- a/src/sync/mutex.go
+++ b/src/sync/mutex.go
@@ -118,7 +118,7 @@
 			// The goroutine has been woken from sleep,
 			// so we need to reset the flag in either case.
 			if new&mutexWoken == 0 {
-				panic("sync: inconsistent mutex state")
+				throw("sync: inconsistent mutex state")
 			}
 			new &^= mutexWoken
 		}
@@ -140,7 +140,7 @@
 				// inconsistent state: mutexLocked is not set and we are still
 				// accounted as waiter. Fix that.
 				if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 {
-					panic("sync: inconsistent mutex state")
+					throw("sync: inconsistent mutex state")
 				}
 				delta := int32(mutexLocked - 1<<mutexWaiterShift)
 				if !starving || old>>mutexWaiterShift == 1 {
@@ -181,7 +181,7 @@
 	// Fast path: drop lock bit.
 	new := atomic.AddInt32(&m.state, -mutexLocked)
 	if (new+mutexLocked)&mutexLocked == 0 {
-		panic("sync: unlock of unlocked mutex")
+		throw("sync: unlock of unlocked mutex")
 	}
 	if new&mutexStarving == 0 {
 		old := new
diff --git a/src/sync/mutex_test.go b/src/sync/mutex_test.go
index 784471d..5214684 100644
--- a/src/sync/mutex_test.go
+++ b/src/sync/mutex_test.go
@@ -155,7 +155,10 @@
 	if len(os.Args) == 3 && os.Args[1] == "TESTMISUSE" {
 		for _, test := range misuseTests {
 			if test.name == os.Args[2] {
-				test.f()
+				func() {
+					defer func() { recover() }()
+					test.f()
+				}()
 				fmt.Printf("test completed\n")
 				os.Exit(0)
 			}
diff --git a/src/sync/rwmutex.go b/src/sync/rwmutex.go
index cb2dfe1..4e9e819 100644
--- a/src/sync/rwmutex.go
+++ b/src/sync/rwmutex.go
@@ -13,11 +13,11 @@
 // There is a modified copy of this file in runtime/rwmutex.go.
 // If you make any changes here, see if you should make them there.
 
-// An RWMutex is a reader/writer mutual exclusion lock.
+// A RWMutex is a reader/writer mutual exclusion lock.
 // The lock can be held by an arbitrary number of readers or a single writer.
 // The zero value for a RWMutex is an unlocked mutex.
 //
-// An RWMutex must not be copied after first use.
+// A RWMutex must not be copied after first use.
 //
 // If a goroutine holds a RWMutex for reading and another goroutine might
 // call Lock, no goroutine should expect to be able to acquire a read lock
@@ -108,7 +108,7 @@
 // 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
+// goroutine. One goroutine may RLock (Lock) a RWMutex and then
 // arrange for another goroutine to RUnlock (Unlock) it.
 func (rw *RWMutex) Unlock() {
 	if race.Enabled {
diff --git a/src/sync/waitgroup.go b/src/sync/waitgroup.go
index f266f7c..2fa7c3e 100644
--- a/src/sync/waitgroup.go
+++ b/src/sync/waitgroup.go
@@ -63,13 +63,11 @@
 	state := atomic.AddUint64(statep, uint64(delta)<<32)
 	v := int32(state >> 32)
 	w := uint32(state)
-	if race.Enabled {
-		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.
-			race.Read(unsafe.Pointer(&wg.sema))
-		}
+	if race.Enabled && delta > 0 && v == int32(delta) {
+		// The first increment must be synchronized with Wait.
+		// Need to model this as a read, because there can be
+		// several concurrent wg.counter transitions from 0.
+		race.Read(unsafe.Pointer(&wg.sema))
 	}
 	if v < 0 {
 		panic("sync: negative WaitGroup counter")
diff --git a/src/syscall/asm_plan9_386.s b/src/syscall/asm_plan9_386.s
index 047ae59..2e7db8c 100644
--- a/src/syscall/asm_plan9_386.s
+++ b/src/syscall/asm_plan9_386.s
@@ -38,7 +38,7 @@
 	JMP	copyresult3
 	
 ok3:
-	LEAL	runtime·emptystring(SB), SI	
+	LEAL	·emptystring(SB), SI
 	
 copyresult3:
 	LEAL	err+24(FP), DI
@@ -76,7 +76,7 @@
 	JMP	copyresult4
 	
 ok4:
-	LEAL	runtime·emptystring(SB), SI
+	LEAL	·emptystring(SB), SI
 	
 copyresult4:
 	LEAL	err+36(FP), DI
@@ -143,7 +143,7 @@
 	JMP	copyresult6
 	
 ok6:
-	LEAL	runtime·emptystring(SB), SI
+	LEAL	·emptystring(SB), SI
 	
 copyresult6:
 	LEAL	err+28(FP), DI
@@ -152,12 +152,3 @@
 	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
index 8405023..da93afa 100644
--- a/src/syscall/asm_plan9_amd64.s
+++ b/src/syscall/asm_plan9_amd64.s
@@ -37,7 +37,7 @@
 	JMP	copyresult3
 	
 ok3:
-	LEAQ	runtime·emptystring(SB), SI	
+	LEAQ	·emptystring(SB), SI
 	
 copyresult3:
 	LEAQ	err+48(FP), DI
@@ -75,7 +75,7 @@
 	JMP	copyresult4
 	
 ok4:
-	LEAQ	runtime·emptystring(SB), SI
+	LEAQ	·emptystring(SB), SI
 	
 copyresult4:
 	LEAQ	err+72(FP), DI
@@ -141,7 +141,7 @@
 	JMP	copyresult6
 	
 ok6:
-	LEAQ	runtime·emptystring(SB), SI
+	LEAQ	·emptystring(SB), SI
 	
 copyresult6:
 	LEAQ	err+40(FP), DI
@@ -150,12 +150,3 @@
 	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_plan9_arm.s b/src/syscall/asm_plan9_arm.s
index 2a338a0..4972597 100644
--- a/src/syscall/asm_plan9_arm.s
+++ b/src/syscall/asm_plan9_arm.s
@@ -10,7 +10,7 @@
 // System call support for plan9 on arm
 
 TEXT	sysresult<>(SB),NOSPLIT,$12
-	MOVW	$runtime·emptystring+0(SB), R2
+	MOVW	$·emptystring+0(SB), R2
 	CMP		$-1, R0
 	B.NE	ok
 	MOVW	R1, save-4(SP)
@@ -88,12 +88,3 @@
 	MOVW	$err+28(FP), R1
 	BL		sysresult<>(SB)
 	RET
-
-//func exit(code int)
-// Import runtime·exit for cleanly exiting.
-TEXT ·exit(SB),NOSPLIT,$4-4
-	NO_LOCAL_POINTERS
-	MOVW	code+0(FP), R0
-	MOVW	R0, e-4(SP)
-	BL		runtime·exit(SB)
-	RET
diff --git a/src/syscall/creds_test.go b/src/syscall/creds_test.go
index 7c6ab1d..524689a 100644
--- a/src/syscall/creds_test.go
+++ b/src/syscall/creds_test.go
@@ -19,101 +19,116 @@
 // sockets. The SO_PASSCRED socket option is enabled on the sending
 // socket for this to work.
 func TestSCMCredentials(t *testing.T) {
-	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
-	if err != nil {
-		t.Fatalf("Socketpair: %v", err)
-	}
-	defer syscall.Close(fds[0])
-	defer syscall.Close(fds[1])
-
-	err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
-	if err != nil {
-		t.Fatalf("SetsockoptInt: %v", err)
+	socketTypeTests := []struct {
+		socketType int
+		dataLen    int
+	}{
+		{
+			syscall.SOCK_STREAM,
+			1,
+		}, {
+			syscall.SOCK_DGRAM,
+			0,
+		},
 	}
 
-	srvFile := os.NewFile(uintptr(fds[0]), "server")
-	defer srvFile.Close()
-	srv, err := net.FileConn(srvFile)
-	if err != nil {
-		t.Errorf("FileConn: %v", err)
-		return
-	}
-	defer srv.Close()
+	for _, tt := range socketTypeTests {
+		fds, err := syscall.Socketpair(syscall.AF_LOCAL, tt.socketType, 0)
+		if err != nil {
+			t.Fatalf("Socketpair: %v", err)
+		}
+		defer syscall.Close(fds[0])
+		defer syscall.Close(fds[1])
 
-	cliFile := os.NewFile(uintptr(fds[1]), "client")
-	defer cliFile.Close()
-	cli, err := net.FileConn(cliFile)
-	if err != nil {
-		t.Errorf("FileConn: %v", err)
-		return
-	}
-	defer cli.Close()
+		err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
+		if err != nil {
+			t.Fatalf("SetsockoptInt: %v", err)
+		}
 
-	var ucred syscall.Ucred
-	if os.Getuid() != 0 {
+		srvFile := os.NewFile(uintptr(fds[0]), "server")
+		defer srvFile.Close()
+		srv, err := net.FileConn(srvFile)
+		if err != nil {
+			t.Errorf("FileConn: %v", err)
+			return
+		}
+		defer srv.Close()
+
+		cliFile := os.NewFile(uintptr(fds[1]), "client")
+		defer cliFile.Close()
+		cli, err := net.FileConn(cliFile)
+		if err != nil {
+			t.Errorf("FileConn: %v", err)
+			return
+		}
+		defer cli.Close()
+
+		var ucred syscall.Ucred
+		if os.Getuid() != 0 {
+			ucred.Pid = int32(os.Getpid())
+			ucred.Uid = 0
+			ucred.Gid = 0
+			oob := syscall.UnixCredentials(&ucred)
+			_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+			if op, ok := err.(*net.OpError); ok {
+				err = op.Err
+			}
+			if sys, ok := err.(*os.SyscallError); ok {
+				err = sys.Err
+			}
+			if err != syscall.EPERM {
+				t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
+			}
+		}
+
 		ucred.Pid = int32(os.Getpid())
-		ucred.Uid = 0
-		ucred.Gid = 0
+		ucred.Uid = uint32(os.Getuid())
+		ucred.Gid = uint32(os.Getgid())
 		oob := syscall.UnixCredentials(&ucred)
-		_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
-		if op, ok := err.(*net.OpError); ok {
-			err = op.Err
+
+		// On SOCK_STREAM, this is internally going to send a dummy byte
+		n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+		if err != nil {
+			t.Fatalf("WriteMsgUnix: %v", err)
 		}
-		if sys, ok := err.(*os.SyscallError); ok {
-			err = sys.Err
+		if n != 0 {
+			t.Fatalf("WriteMsgUnix n = %d, want 0", n)
 		}
-		if err != syscall.EPERM {
-			t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
+		if oobn != len(oob) {
+			t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
 		}
-	}
 
-	ucred.Pid = int32(os.Getpid())
-	ucred.Uid = uint32(os.Getuid())
-	ucred.Gid = uint32(os.Getgid())
-	oob := syscall.UnixCredentials(&ucred)
+		oob2 := make([]byte, 10*len(oob))
+		n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
+		if err != nil {
+			t.Fatalf("ReadMsgUnix: %v", err)
+		}
+		if flags != 0 {
+			t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
+		}
+		if n != tt.dataLen {
+			t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
+		}
+		if oobn2 != oobn {
+			// without SO_PASSCRED set on the socket, ReadMsgUnix will
+			// return zero oob bytes
+			t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
+		}
+		oob2 = oob2[:oobn2]
+		if !bytes.Equal(oob, oob2) {
+			t.Fatal("ReadMsgUnix oob bytes don't match")
+		}
 
-	// this is going to send a dummy byte
-	n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
-	if err != nil {
-		t.Fatalf("WriteMsgUnix: %v", err)
-	}
-	if n != 0 {
-		t.Fatalf("WriteMsgUnix n = %d, want 0", n)
-	}
-	if oobn != len(oob) {
-		t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
-	}
-
-	oob2 := make([]byte, 10*len(oob))
-	n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
-	if err != nil {
-		t.Fatalf("ReadMsgUnix: %v", err)
-	}
-	if flags != 0 {
-		t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
-	}
-	if n != 1 {
-		t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
-	}
-	if oobn2 != oobn {
-		// without SO_PASSCRED set on the socket, ReadMsgUnix will
-		// return zero oob bytes
-		t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
-	}
-	oob2 = oob2[:oobn2]
-	if !bytes.Equal(oob, oob2) {
-		t.Fatal("ReadMsgUnix oob bytes don't match")
-	}
-
-	scm, err := syscall.ParseSocketControlMessage(oob2)
-	if err != nil {
-		t.Fatalf("ParseSocketControlMessage: %v", err)
-	}
-	newUcred, err := syscall.ParseUnixCredentials(&scm[0])
-	if err != nil {
-		t.Fatalf("ParseUnixCredentials: %v", err)
-	}
-	if *newUcred != ucred {
-		t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
+		scm, err := syscall.ParseSocketControlMessage(oob2)
+		if err != nil {
+			t.Fatalf("ParseSocketControlMessage: %v", err)
+		}
+		newUcred, err := syscall.ParseUnixCredentials(&scm[0])
+		if err != nil {
+			t.Fatalf("ParseUnixCredentials: %v", err)
+		}
+		if *newUcred != ucred {
+			t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
+		}
 	}
 }
diff --git a/src/syscall/exec_freebsd.go b/src/syscall/exec_freebsd.go
index 4ed32c0..1654b4b 100644
--- a/src/syscall/exec_freebsd.go
+++ b/src/syscall/exec_freebsd.go
@@ -5,21 +5,5 @@
 package syscall
 
 func forkExecPipe(p []int) error {
-	err := Pipe2(p, O_CLOEXEC)
-	if err == nil {
-		return nil
-	}
-
-	// FreeBSD 9 fallback.
-	// TODO: remove this for Go 1.10 per Issue 19072
-	err = Pipe(p)
-	if err != nil {
-		return err
-	}
-	_, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
-	if err != nil {
-		return err
-	}
-	_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
-	return err
+	return Pipe2(p, O_CLOEXEC)
 }
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index fd87b86..bfbe2b3 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -199,14 +199,6 @@
 		}
 	}
 
-	// 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)
@@ -402,6 +394,16 @@
 		}
 	}
 
+	// Enable tracing if requested.
+	// Do this right before exec so that we don't unnecessarily trace the runtime
+	// setting up after the fork. See issue #21428.
+	if sys.Ptrace {
+		_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
 	// Time to exec.
 	_, _, err1 = RawSyscall(SYS_EXECVE,
 		uintptr(unsafe.Pointer(argv0)),
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index 114deec..17df8f4 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -23,6 +23,24 @@
 	"unsafe"
 )
 
+func isDocker() bool {
+	_, err := os.Stat("/.dockerenv")
+	return err == nil
+}
+
+func isLXC() bool {
+	return os.Getenv("container") == "lxc"
+}
+
+func skipInContainer(t *testing.T) {
+	if isDocker() {
+		t.Skip("skip this test in Docker container")
+	}
+	if isLXC() {
+		t.Skip("skip this test in LXC container")
+	}
+}
+
 // Check if we are in a chroot by checking if the inode of / is
 // different from 2 (there is no better test available to non-root on
 // linux).
@@ -35,6 +53,7 @@
 }
 
 func checkUserNS(t *testing.T) {
+	skipInContainer(t)
 	if _, err := os.Stat("/proc/self/ns/user"); err != nil {
 		if os.IsNotExist(err) {
 			t.Skip("kernel doesn't support user namespaces")
@@ -114,7 +133,7 @@
 	if os.Getuid() != 0 {
 		t.Skip("skipping root only test")
 	}
-	testNEWUSERRemap(t, 0, 0, false)
+	testNEWUSERRemap(t, 0, 0, true)
 }
 
 func TestCloneNEWUSERAndRemapNoRootDisableSetgroups(t *testing.T) {
@@ -147,6 +166,7 @@
 }
 
 func TestUnshare(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -293,6 +313,7 @@
 
 // Test for Issue 38471: unshare fails because systemd has forced / to be shared
 func TestUnshareMountNameSpace(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -342,6 +363,7 @@
 
 // Test for Issue 20103: unshare fails when chroot is used
 func TestUnshareMountNameSpaceChroot(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -477,6 +499,7 @@
 }
 
 func TestAmbientCaps(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
index cafce1e..91b0e84 100644
--- a/src/syscall/exec_windows.go
+++ b/src/syscall/exec_windows.go
@@ -222,6 +222,7 @@
 	HideWindow    bool
 	CmdLine       string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
 	CreationFlags uint32
+	Token         Token // if set, runs new process in the security context represented by the token
 }
 
 var zeroProcAttr ProcAttr
@@ -321,7 +322,11 @@
 	pi := new(ProcessInformation)
 
 	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT
-	err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+	if sys.Token != 0 {
+		err = CreateProcessAsUser(sys.Token, argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+	} else {
+		err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+	}
 	if err != nil {
 		return 0, 0, err
 	}
diff --git a/src/syscall/fs_nacl.go b/src/syscall/fs_nacl.go
index cbd9539..33334dc 100644
--- a/src/syscall/fs_nacl.go
+++ b/src/syscall/fs_nacl.go
@@ -625,6 +625,8 @@
 
 func Link(path, link string) error {
 	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
 	ip, _, err := fs.namei(path, false)
 	if err != nil {
 		return err
@@ -636,12 +638,18 @@
 	if ip.Mode&S_IFMT == S_IFDIR {
 		return EPERM
 	}
+	_, _, err = fs.dirlookup(dp, elem)
+	if err == nil {
+		return EEXIST
+	}
 	fs.dirlink(dp, elem, ip)
 	return nil
 }
 
 func Rename(from, to string) error {
 	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
 	fdp, felem, err := fs.namei(from, true)
 	if err != nil {
 		return err
diff --git a/src/syscall/mkall.sh b/src/syscall/mkall.sh
index a7549ac..4e68fb2 100755
--- a/src/syscall/mkall.sh
+++ b/src/syscall/mkall.sh
@@ -131,12 +131,6 @@
 	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"
diff --git a/src/syscall/mksyscall_windows.go b/src/syscall/mksyscall_windows.go
index 37e4a07..e7c8664 100644
--- a/src/syscall/mksyscall_windows.go
+++ b/src/syscall/mksyscall_windows.go
@@ -614,7 +614,7 @@
 }
 
 // ParseFiles parses files listed in fs and extracts all syscall
-// functions listed in  sys comments. It returns source files
+// functions listed in sys comments. It returns source files
 // and functions collection *Source if successful.
 func ParseFiles(fs []string) (*Source, error) {
 	src := &Source{
diff --git a/src/syscall/net_nacl.go b/src/syscall/net_nacl.go
index b019cbf..409a7a4 100644
--- a/src/syscall/net_nacl.go
+++ b/src/syscall/net_nacl.go
@@ -16,11 +16,13 @@
 )
 
 // Interface to timers implemented in package runtime.
-// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
+// Must be in sync with ../runtime/time.go:/^type timer
 // Really for use by package time, but we cannot import time here.
 
 type runtimeTimer struct {
-	i      int
+	tb uintptr
+	i  int
+
 	when   int64
 	period int64
 	f      func(interface{}, uintptr) // NOTE: must not be closure
@@ -49,13 +51,14 @@
 }
 
 func (t *timer) stop() {
+	if t.r.f == nil {
+		return
+	}
 	stopTimer(&t.r)
 }
 
 func (t *timer) reset(q *queue, deadline int64) {
-	if t.r.f != nil {
-		t.stop()
-	}
+	t.stop()
 	if deadline == 0 {
 		return
 	}
diff --git a/src/syscall/syscall.go b/src/syscall/syscall.go
index 7db994b..01ba648 100644
--- a/src/syscall/syscall.go
+++ b/src/syscall/syscall.go
@@ -80,22 +80,29 @@
 // See mksyscall.pl.
 var _zero uintptr
 
+// Unix returns ts as the number of seconds and nanoseconds elapsed since the
+// Unix epoch.
 func (ts *Timespec) Unix() (sec int64, nsec int64) {
 	return int64(ts.Sec), int64(ts.Nsec)
 }
 
+// Unix returns tv as the number of seconds and nanoseconds elapsed since the
+// Unix epoch.
 func (tv *Timeval) Unix() (sec int64, nsec int64) {
 	return int64(tv.Sec), int64(tv.Usec) * 1000
 }
 
+// Nano returns ts as the number of nanoseconds elapsed since the Unix epoch.
 func (ts *Timespec) Nano() int64 {
 	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
 }
 
+// Nano returns tv as the number of nanoseconds elapsed since the Unix epoch.
 func (tv *Timeval) Nano() int64 {
 	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
 }
 
-// Getpagesize is provided by the runtime.
+// Getpagesize and Exit are provided by the runtime.
 
 func Getpagesize() int
+func Exit(code int)
diff --git a/src/syscall/syscall_bsd.go b/src/syscall/syscall_bsd.go
index 9370dd4..d141a7d 100644
--- a/src/syscall/syscall_bsd.go
+++ b/src/syscall/syscall_bsd.go
@@ -507,11 +507,18 @@
 }
 
 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
 	}
+	// Darwin setattrlist can set nanosecond timestamps
+	err := setattrlistTimes(path, ts)
+	if err != ENOSYS {
+		return err
+	}
+	err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+	if err != ENOSYS {
+		return err
+	}
 	// Not as efficient as it could be because Timespec and
 	// Timeval have different types in the different OSes
 	tv := [2]Timeval{
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index a1c360d..cf21ec4 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -93,6 +93,8 @@
 
 const (
 	attrBitMapCount = 5
+	attrCmnModtime  = 0x00000400
+	attrCmnAcctime  = 0x00001000
 	attrCmnFullpath = 0x08000000
 )
 
@@ -186,6 +188,39 @@
 	return
 }
 
+func setattrlistTimes(path string, times []Timespec) error {
+	_p0, err := BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+
+	var attrList attrList
+	attrList.bitmapCount = attrBitMapCount
+	attrList.CommonAttr = attrCmnModtime | attrCmnAcctime
+
+	// order is mtime, atime: the opposite of Chtimes
+	attributes := [2]Timespec{times[1], times[0]}
+	const options = 0
+	_, _, e1 := Syscall6(
+		SYS_SETATTRLIST,
+		uintptr(unsafe.Pointer(_p0)),
+		uintptr(unsafe.Pointer(&attrList)),
+		uintptr(unsafe.Pointer(&attributes)),
+		uintptr(unsafe.Sizeof(attributes)),
+		uintptr(options),
+		0,
+	)
+	if e1 != 0 {
+		return e1
+	}
+	return nil
+}
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) error {
+	// Darwin doesn't support SYS_UTIMENSAT
+	return ENOSYS
+}
+
 /*
  * Wrapped
  */
@@ -208,7 +243,6 @@
 //sys	Dup(fd int) (nfd int, err error)
 //sys	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)
diff --git a/src/syscall/syscall_dragonfly.go b/src/syscall/syscall_dragonfly.go
index 7d4fa4d..fead9d9 100644
--- a/src/syscall/syscall_dragonfly.go
+++ b/src/syscall/syscall_dragonfly.go
@@ -125,6 +125,11 @@
 	return
 }
 
+func setattrlistTimes(path string, times []Timespec) error {
+	// used on Darwin for UtimesNano
+	return ENOSYS
+}
+
 /*
  * Exposed directly
  */
@@ -138,7 +143,6 @@
 //sys	Close(fd int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
 //sys	Dup2(from int, to 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)
@@ -211,6 +215,7 @@
 //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
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 
 /*
  * Unimplemented
diff --git a/src/syscall/syscall_freebsd.go b/src/syscall/syscall_freebsd.go
index 64c881a..5fb9655 100644
--- a/src/syscall/syscall_freebsd.go
+++ b/src/syscall/syscall_freebsd.go
@@ -66,15 +66,8 @@
 	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 }
 
-//sysnb pipe() (r int, w int, err error)
-
 func Pipe(p []int) error {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	var err error
-	p[0], p[1], err = pipe()
-	return err
+	return Pipe2(p, 0)
 }
 
 //sysnb pipe2(p *[2]_C_int, flags int) (err error)
@@ -134,6 +127,11 @@
 	return
 }
 
+func setattrlistTimes(path string, times []Timespec) error {
+	// used on Darwin for UtimesNano
+	return ENOSYS
+}
+
 /*
  * Exposed directly
  */
@@ -147,7 +145,6 @@
 //sys	Close(fd int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
 //sys	Dup2(from int, to 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)
@@ -222,6 +219,7 @@
 //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
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 
 /*
  * Unimplemented
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index 8099a5f..d2cb7c1 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -96,13 +96,13 @@
 	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
-//sys	utimensat(dirfd int, path string, times *[2]Timespec) (err error)
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (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])))
+	err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
 	if err != ENOSYS {
 		return err
 	}
@@ -126,8 +126,7 @@
 	if err != nil {
 		return err
 	}
-	err = futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-	return err
+	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
 func Futimes(fd int, tv []Timeval) (err error) {
@@ -295,7 +294,10 @@
 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	name := sa.Name
 	n := len(name)
-	if n >= len(sa.raw.Path) {
+	if n > len(sa.raw.Path) {
+		return nil, 0, EINVAL
+	}
+	if n == len(sa.raw.Path) && name[0] != '@' {
 		return nil, 0, EINVAL
 	}
 	sa.raw.Family = AF_UNIX
@@ -532,17 +534,22 @@
 	msg.Namelen = uint32(SizeofSockaddrAny)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
 	if len(oob) > 0 {
+		var sockType int
+		sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+		if err != nil {
+			return
+		}
 		// receive at least one normal byte
-		if len(p) == 0 {
+		if sockType != SOCK_DGRAM && len(p) == 0 {
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
@@ -575,21 +582,26 @@
 		}
 	}
 	var msg Msghdr
-	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Name = (*byte)(ptr)
 	msg.Namelen = uint32(salen)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
 	if len(oob) > 0 {
+		var sockType int
+		sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+		if err != nil {
+			return 0, err
+		}
 		// send at least one normal byte
-		if len(p) == 0 {
+		if sockType != SOCK_DGRAM && len(p) == 0 {
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
@@ -788,8 +800,7 @@
 	if err != nil {
 		return err
 	}
-	err = mount(source, target, fstype, flags, datap)
-	return err
+	return mount(source, target, fstype, flags, datap)
 }
 
 // Sendto
@@ -810,7 +821,6 @@
 //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)
@@ -821,7 +831,7 @@
 //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_getdents
+//sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
 //sysnb	Getpgid(pid int) (pgid int, err error)
 
 func Getpgrp() (pid int) {
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index 2c5d9a3..13b9e2e 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -11,7 +11,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS32
 )
 
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
index eaba868..4b4aa6d 100644
--- a/src/syscall/syscall_linux_amd64.go
+++ b/src/syscall/syscall_linux_amd64.go
@@ -6,7 +6,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index 5c652b2..5ccab9b 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -8,7 +8,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS32
 )
 
diff --git a/src/syscall/syscall_linux_arm64.go b/src/syscall/syscall_linux_arm64.go
index 4e81673..27c351d 100644
--- a/src/syscall/syscall_linux_arm64.go
+++ b/src/syscall/syscall_linux_arm64.go
@@ -6,7 +6,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP3
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
@@ -24,7 +23,6 @@
 //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_PSELECT6
 //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)
@@ -69,6 +67,17 @@
 //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)
 
+type sigset_t struct {
+	X__val [16]uint64
+}
+
+//sys	pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) = SYS_PSELECT6
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
+	return pselect(nfd, r, w, e, &ts, nil)
+}
+
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 //sysnb	Time(t *Time_t) (tt Time_t, err error)
 
diff --git a/src/syscall/syscall_linux_mips64x.go b/src/syscall/syscall_linux_mips64x.go
index 671cfe6..d9eba62 100644
--- a/src/syscall/syscall_linux_mips64x.go
+++ b/src/syscall/syscall_linux_mips64x.go
@@ -8,14 +8,7 @@
 package syscall
 
 const (
-	_SYS_dup = SYS_DUP2
-
-	// Linux introduced getdents64 syscall for N64 ABI only in 3.10
-	// (May 21 2013, rev dec33abaafc89bcbd78f85fad0513170415a26d5),
-	// to support older kernels, we have to use getdents for mips64.
-	// Also note that struct dirent is different for these two.
-	// Lookup linux_dirent{,64} in kernel source code for details.
-	_SYS_getdents  = SYS_GETDENTS
+	_SYS_dup       = SYS_DUP2
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
@@ -34,7 +27,6 @@
 //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_PSELECT6
 //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)
@@ -66,6 +58,17 @@
 //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)
 
+type sigset_t struct {
+	X__val [16]uint64
+}
+
+//sys	pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) = SYS_PSELECT6
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
+	return pselect(nfd, r, w, e, &ts, nil)
+}
+
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 
 func Time(t *Time_t) (tt Time_t, err error) {
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index 1da265d..92785e1 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -11,7 +11,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
diff --git a/src/syscall/syscall_linux_ppc64x.go b/src/syscall/syscall_linux_ppc64x.go
index 53086f9..f743b77 100644
--- a/src/syscall/syscall_linux_ppc64x.go
+++ b/src/syscall/syscall_linux_ppc64x.go
@@ -9,7 +9,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
@@ -32,7 +31,7 @@
 //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	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
 //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)
diff --git a/src/syscall/syscall_linux_s390x.go b/src/syscall/syscall_linux_s390x.go
index 8f3bbfc..6bd9744 100644
--- a/src/syscall/syscall_linux_s390x.go
+++ b/src/syscall/syscall_linux_s390x.go
@@ -8,7 +8,6 @@
 
 const (
 	_SYS_dup       = SYS_DUP2
-	_SYS_getdents  = SYS_GETDENTS64
 	_SYS_setgroups = SYS_SETGROUPS
 )
 
diff --git a/src/syscall/syscall_nacl.go b/src/syscall/syscall_nacl.go
index 3247505..1102cd6 100644
--- a/src/syscall/syscall_nacl.go
+++ b/src/syscall/syscall_nacl.go
@@ -10,7 +10,6 @@
 )
 
 //sys	naclClose(fd int) (err error) = sys_close
-//sys	Exit(code int) (err error)
 //sys	naclFstat(fd int, stat *Stat_t) (err error) = sys_fstat
 //sys	naclRead(fd int, b []byte) (n int, err error) = sys_read
 //sys	naclSeek(fd int, off *int64, whence int) (err error) = sys_lseek
diff --git a/src/syscall/syscall_netbsd.go b/src/syscall/syscall_netbsd.go
index f2e1694..c645b13 100644
--- a/src/syscall/syscall_netbsd.go
+++ b/src/syscall/syscall_netbsd.go
@@ -121,6 +121,11 @@
 	return -1, ENOSYS
 }
 
+func setattrlistTimes(path string, times []Timespec) error {
+	// used on Darwin for UtimesNano
+	return ENOSYS
+}
+
 /*
  * Exposed directly
  */
@@ -134,7 +139,6 @@
 //sys	Close(fd int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
 //sys	Dup2(from int, to 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)
@@ -202,6 +206,7 @@
 //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
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 
 /*
  * Unimplemented
diff --git a/src/syscall/syscall_openbsd.go b/src/syscall/syscall_openbsd.go
index bd25fbf..a43d88b 100644
--- a/src/syscall/syscall_openbsd.go
+++ b/src/syscall/syscall_openbsd.go
@@ -99,6 +99,11 @@
 	return
 }
 
+func setattrlistTimes(path string, times []Timespec) error {
+	// used on Darwin for UtimesNano
+	return ENOSYS
+}
+
 /*
  * Exposed directly
  */
@@ -112,7 +117,6 @@
 //sys	Close(fd int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
 //sys	Dup2(from int, to 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)
@@ -183,6 +187,7 @@
 //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
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 
 /*
  * Unimplemented
@@ -278,6 +283,5 @@
 // thrsleep
 // thrwakeup
 // unlinkat
-// utimensat
 // vfork
 // writev
diff --git a/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go
index b7a0d54..12b61ee 100644
--- a/src/syscall/syscall_plan9.go
+++ b/src/syscall/syscall_plan9.go
@@ -31,6 +31,8 @@
 	return e == EBUSY || e == ETIMEDOUT
 }
 
+var emptystring string
+
 // A Note is a string describing a process note.
 // It implements the os.Signal interface.
 type Note string
@@ -83,11 +85,6 @@
 	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
 
diff --git a/src/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go
index 636de92..73ac127 100644
--- a/src/syscall/syscall_solaris.go
+++ b/src/syscall/syscall_solaris.go
@@ -270,16 +270,11 @@
 	return name, err
 }
 
-func UtimesNano(path string, ts []Timespec) (err error) {
+func UtimesNano(path string, ts []Timespec) error {
 	if len(ts) != 2 {
 		return EINVAL
 	}
-	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])))
+	return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
 }
 
 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
@@ -441,7 +436,6 @@
 //sys	Chroot(path string) (err error)
 //sys	Close(fd int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
-//sys	Exit(code int)
 //sys	Fchdir(fd int) (err error)
 //sys	Fchmod(fd int, mode uint32) (err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
@@ -510,6 +504,7 @@
 //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
 //sys	getexecname() (path unsafe.Pointer, err error) = libc.getexecname
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 
 func Getexecname() (path string, err error) {
 	ptr, err := getexecname()
diff --git a/src/syscall/syscall_unix_test.go b/src/syscall/syscall_unix_test.go
index b1fe78d..637aece 100644
--- a/src/syscall/syscall_unix_test.go
+++ b/src/syscall/syscall_unix_test.go
@@ -180,6 +180,9 @@
 		uc.Close()
 	})
 	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
+	if err != nil {
+		t.Fatalf("ReadMsgUnix: %v", err)
+	}
 	closeUnix.Stop()
 
 	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index 4619ce2..9026fcd 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -169,6 +169,7 @@
 //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	CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW
 //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)
@@ -236,9 +237,6 @@
 
 // syscall interface implementation for other packages
 
-// Implemented in ../runtime/syscall_windows.go.
-func Exit(code int)
-
 func makeInheritSa() *SecurityAttributes {
 	var sa SecurityAttributes
 	sa.Length = uint32(unsafe.Sizeof(sa))
@@ -334,6 +332,27 @@
 
 var ioSync int64
 
+var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx")
+
+const ptrSize = unsafe.Sizeof(uintptr(0))
+
+// setFilePointerEx calls SetFilePointerEx.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365542(v=vs.85).aspx
+func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error {
+	var e1 Errno
+	if ptrSize == 8 {
+		_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
+	} else {
+		// distToMove is a LARGE_INTEGER:
+		// https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx
+		_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0)
+	}
+	if e1 != 0 {
+		return errnoErr(e1)
+	}
+	return nil
+}
+
 func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
 	var w uint32
 	switch whence {
@@ -344,18 +363,13 @@
 	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, ESPIPE
 	}
-	rlo, e := SetFilePointer(fd, lo, &hi, w)
-	if e != nil {
-		return 0, e
-	}
-	return int64(hi)<<32 + int64(rlo), nil
+	err = setFilePointerEx(fd, offset, &newoffset, w)
+	return
 }
 
 func Close(fd Handle) (err error) {
diff --git a/src/syscall/types_darwin.go b/src/syscall/types_darwin.go
index a043071..d8218d6 100644
--- a/src/syscall/types_darwin.go
+++ b/src/syscall/types_darwin.go
@@ -238,6 +238,12 @@
 
 type BpfHdr C.struct_bpf_hdr
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/types_dragonfly.go b/src/syscall/types_dragonfly.go
index fb7fd1b..5728d67 100644
--- a/src/syscall/types_dragonfly.go
+++ b/src/syscall/types_dragonfly.go
@@ -237,6 +237,12 @@
 
 type BpfHdr C.struct_bpf_hdr
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/types_freebsd.go b/src/syscall/types_freebsd.go
index 68a6931..6f8670a 100644
--- a/src/syscall/types_freebsd.go
+++ b/src/syscall/types_freebsd.go
@@ -337,6 +337,12 @@
 
 type BpfZbufHeader C.struct_bpf_zbuf_header
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/types_netbsd.go b/src/syscall/types_netbsd.go
index 04354a3..37c5fa9 100644
--- a/src/syscall/types_netbsd.go
+++ b/src/syscall/types_netbsd.go
@@ -223,6 +223,12 @@
 
 type BpfTimeval C.struct_bpf_timeval
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/types_openbsd.go b/src/syscall/types_openbsd.go
index e6d1ea7..29d6feb 100644
--- a/src/syscall/types_openbsd.go
+++ b/src/syscall/types_openbsd.go
@@ -239,6 +239,12 @@
 
 type BpfTimeval C.struct_bpf_timeval
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/types_solaris.go b/src/syscall/types_solaris.go
index 7246434..a219a43 100644
--- a/src/syscall/types_solaris.go
+++ b/src/syscall/types_solaris.go
@@ -224,6 +224,12 @@
 
 type BpfHdr C.struct_bpf_hdr
 
+// Misc
+
+const (
+	_AT_FDCWD = C.AT_FDCWD
+)
+
 // Terminal handling
 
 type Termios C.struct_termios
diff --git a/src/syscall/ztypes_windows.go b/src/syscall/types_windows.go
similarity index 100%
rename from src/syscall/ztypes_windows.go
rename to src/syscall/types_windows.go
diff --git a/src/syscall/ztypes_windows_386.go b/src/syscall/types_windows_386.go
similarity index 100%
rename from src/syscall/ztypes_windows_386.go
rename to src/syscall/types_windows_386.go
diff --git a/src/syscall/ztypes_windows_amd64.go b/src/syscall/types_windows_amd64.go
similarity index 100%
rename from src/syscall/ztypes_windows_amd64.go
rename to src/syscall/types_windows_amd64.go
diff --git a/src/syscall/zsyscall_darwin_386.go b/src/syscall/zsyscall_darwin_386.go
index 200407e..fe9129a 100644
--- a/src/syscall/zsyscall_darwin_386.go
+++ b/src/syscall/zsyscall_darwin_386.go
@@ -444,13 +444,6 @@
 
 // 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 {
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
index 1303f62..3a08ad3 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -444,13 +444,6 @@
 
 // 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 {
diff --git a/src/syscall/zsyscall_darwin_arm.go b/src/syscall/zsyscall_darwin_arm.go
index 8b63729..c845cfa 100644
--- a/src/syscall/zsyscall_darwin_arm.go
+++ b/src/syscall/zsyscall_darwin_arm.go
@@ -444,13 +444,6 @@
 
 // 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 {
diff --git a/src/syscall/zsyscall_darwin_arm64.go b/src/syscall/zsyscall_darwin_arm64.go
index 73a834c..66ffa33 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -444,13 +444,6 @@
 
 // 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 {
diff --git a/src/syscall/zsyscall_dragonfly_amd64.go b/src/syscall/zsyscall_dragonfly_amd64.go
index 7a21510..5eca951 100644
--- a/src/syscall/zsyscall_dragonfly_amd64.go
+++ b/src/syscall/zsyscall_dragonfly_amd64.go
@@ -438,13 +438,6 @@
 
 // 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 {
@@ -1298,3 +1291,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_386.go b/src/syscall/zsyscall_freebsd_386.go
index 63061b2..4ada995 100644
--- a/src/syscall/zsyscall_freebsd_386.go
+++ b/src/syscall/zsyscall_freebsd_386.go
@@ -261,18 +261,6 @@
 
 // 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 = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func pipe2(p *[2]_C_int, flags int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
@@ -414,13 +402,6 @@
 
 // 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 {
@@ -1308,3 +1289,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_amd64.go b/src/syscall/zsyscall_freebsd_amd64.go
index 8120980..5bbc5c4 100644
--- a/src/syscall/zsyscall_freebsd_amd64.go
+++ b/src/syscall/zsyscall_freebsd_amd64.go
@@ -261,18 +261,6 @@
 
 // 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 = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func pipe2(p *[2]_C_int, flags int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
@@ -414,13 +402,6 @@
 
 // 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 {
@@ -1308,3 +1289,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_arm.go b/src/syscall/zsyscall_freebsd_arm.go
index f6c44c7..011ac0e 100644
--- a/src/syscall/zsyscall_freebsd_arm.go
+++ b/src/syscall/zsyscall_freebsd_arm.go
@@ -261,18 +261,6 @@
 
 // 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 = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func pipe2(p *[2]_C_int, flags int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
@@ -414,13 +402,6 @@
 
 // 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 {
@@ -1308,3 +1289,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_386.go b/src/syscall/zsyscall_linux_386.go
index 3536bb7..86f8ec1 100644
--- a/src/syscall/zsyscall_linux_386.go
+++ b/src/syscall/zsyscall_linux_386.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_amd64.go b/src/syscall/zsyscall_linux_amd64.go
index 92bcd09..6545d1a 100644
--- a/src/syscall/zsyscall_linux_amd64.go
+++ b/src/syscall/zsyscall_linux_amd64.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_arm.go b/src/syscall/zsyscall_linux_arm.go
index 8131899..0f0464b 100644
--- a/src/syscall/zsyscall_linux_arm.go
+++ b/src/syscall/zsyscall_linux_arm.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_arm64.go b/src/syscall/zsyscall_linux_arm64.go
index 7dffb75..27470ac 100644
--- a/src/syscall/zsyscall_linux_arm64.go
+++ b/src/syscall/zsyscall_linux_arm64.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1314,17 +1307,6 @@
 
 // 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_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func 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)
@@ -1657,6 +1639,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Gettimeofday(tv *Timeval) (err error) {
 	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mips.go b/src/syscall/zsyscall_linux_mips.go
index f1297bf..6b26f7b 100644
--- a/src/syscall/zsyscall_linux_mips.go
+++ b/src/syscall/zsyscall_linux_mips.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_mips64.go b/src/syscall/zsyscall_linux_mips64.go
index 901bafd..00a8f7f 100644
--- a/src/syscall/zsyscall_linux_mips64.go
+++ b/src/syscall/zsyscall_linux_mips64.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1325,17 +1318,6 @@
 
 // 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_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func 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)
@@ -1668,6 +1650,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Gettimeofday(tv *Timeval) (err error) {
 	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mips64le.go b/src/syscall/zsyscall_linux_mips64le.go
index 5af854b..97a68ff 100644
--- a/src/syscall/zsyscall_linux_mips64le.go
+++ b/src/syscall/zsyscall_linux_mips64le.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1325,17 +1318,6 @@
 
 // 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_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func 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)
@@ -1668,6 +1650,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Gettimeofday(tv *Timeval) (err error) {
 	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mipsle.go b/src/syscall/zsyscall_linux_mipsle.go
index b2fcb91..face54b 100644
--- a/src/syscall/zsyscall_linux_mipsle.go
+++ b/src/syscall/zsyscall_linux_mipsle.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_ppc64.go b/src/syscall/zsyscall_linux_ppc64.go
index 51ef5ae..7df49c7 100644
--- a/src/syscall/zsyscall_linux_ppc64.go
+++ b/src/syscall/zsyscall_linux_ppc64.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1371,7 +1364,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := 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 = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_ppc64le.go b/src/syscall/zsyscall_linux_ppc64le.go
index 9ef2118..f073f7d 100644
--- a/src/syscall/zsyscall_linux_ppc64le.go
+++ b/src/syscall/zsyscall_linux_ppc64le.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1371,7 +1364,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := 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 = errnoErr(e1)
diff --git a/src/syscall/zsyscall_linux_s390x.go b/src/syscall/zsyscall_linux_s390x.go
index abc2c4b..689f2f4 100644
--- a/src/syscall/zsyscall_linux_s390x.go
+++ b/src/syscall/zsyscall_linux_s390x.go
@@ -117,13 +117,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -356,13 +356,6 @@
 
 // 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)
@@ -486,7 +479,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
diff --git a/src/syscall/zsyscall_nacl_386.go b/src/syscall/zsyscall_nacl_386.go
index b66ec69..1feab57 100644
--- a/src/syscall/zsyscall_nacl_386.go
+++ b/src/syscall/zsyscall_nacl_386.go
@@ -19,16 +19,6 @@
 
 // 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 = errnoErr(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 {
diff --git a/src/syscall/zsyscall_nacl_amd64p32.go b/src/syscall/zsyscall_nacl_amd64p32.go
index e74931b..880fa45 100644
--- a/src/syscall/zsyscall_nacl_amd64p32.go
+++ b/src/syscall/zsyscall_nacl_amd64p32.go
@@ -19,16 +19,6 @@
 
 // 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 = errnoErr(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 {
diff --git a/src/syscall/zsyscall_nacl_arm.go b/src/syscall/zsyscall_nacl_arm.go
index 4a1ca38..4c852c5 100644
--- a/src/syscall/zsyscall_nacl_arm.go
+++ b/src/syscall/zsyscall_nacl_arm.go
@@ -19,16 +19,6 @@
 
 // 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 = errnoErr(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 {
diff --git a/src/syscall/zsyscall_netbsd_386.go b/src/syscall/zsyscall_netbsd_386.go
index ec32d9c..b6313d5 100644
--- a/src/syscall/zsyscall_netbsd_386.go
+++ b/src/syscall/zsyscall_netbsd_386.go
@@ -421,13 +421,6 @@
 
 // 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 {
@@ -1224,3 +1217,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_netbsd_amd64.go b/src/syscall/zsyscall_netbsd_amd64.go
index 8845202..3455828 100644
--- a/src/syscall/zsyscall_netbsd_amd64.go
+++ b/src/syscall/zsyscall_netbsd_amd64.go
@@ -421,13 +421,6 @@
 
 // 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 {
@@ -1224,3 +1217,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_netbsd_arm.go b/src/syscall/zsyscall_netbsd_arm.go
index 70df9b4..438cfdb 100644
--- a/src/syscall/zsyscall_netbsd_arm.go
+++ b/src/syscall/zsyscall_netbsd_arm.go
@@ -1,4 +1,4 @@
-// mksyscall.pl -l32 -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
+// mksyscall.pl -l32 -netbsd -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
 
 // +build netbsd,arm
@@ -421,13 +421,6 @@
 
 // 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 {
@@ -1224,3 +1217,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_openbsd_386.go b/src/syscall/zsyscall_openbsd_386.go
index 2a5542f..af97f3a 100644
--- a/src/syscall/zsyscall_openbsd_386.go
+++ b/src/syscall/zsyscall_openbsd_386.go
@@ -419,13 +419,6 @@
 
 // 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 {
@@ -1262,3 +1255,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_openbsd_amd64.go b/src/syscall/zsyscall_openbsd_amd64.go
index 9c6a39d..728ad6b 100644
--- a/src/syscall/zsyscall_openbsd_amd64.go
+++ b/src/syscall/zsyscall_openbsd_amd64.go
@@ -419,13 +419,6 @@
 
 // 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 {
@@ -1262,3 +1255,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_openbsd_arm.go b/src/syscall/zsyscall_openbsd_arm.go
index 1ddd238..9998a83 100644
--- a/src/syscall/zsyscall_openbsd_arm.go
+++ b/src/syscall/zsyscall_openbsd_arm.go
@@ -419,13 +419,6 @@
 
 // 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 {
@@ -1262,3 +1255,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_solaris_amd64.go b/src/syscall/zsyscall_solaris_amd64.go
index fbc815d..4bb8318 100644
--- a/src/syscall/zsyscall_solaris_amd64.go
+++ b/src/syscall/zsyscall_solaris_amd64.go
@@ -21,7 +21,6 @@
 //go:cgo_import_dynamic libc_Chroot chroot "libc.so"
 //go:cgo_import_dynamic libc_Close close "libc.so"
 //go:cgo_import_dynamic libc_Dup dup "libc.so"
-//go:cgo_import_dynamic libc_Exit exit "libc.so"
 //go:cgo_import_dynamic libc_Fchdir fchdir "libc.so"
 //go:cgo_import_dynamic libc_Fchmod fchmod "libc.so"
 //go:cgo_import_dynamic libc_Fchown fchown "libc.so"
@@ -90,6 +89,7 @@
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
 //go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so"
 //go:cgo_import_dynamic libc_getexecname getexecname "libc.so"
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
 
 //go:linkname libc_Getcwd libc_Getcwd
 //go:linkname libc_getgroups libc_getgroups
@@ -105,7 +105,6 @@
 //go:linkname libc_Chroot libc_Chroot
 //go:linkname libc_Close libc_Close
 //go:linkname libc_Dup libc_Dup
-//go:linkname libc_Exit libc_Exit
 //go:linkname libc_Fchdir libc_Fchdir
 //go:linkname libc_Fchmod libc_Fchmod
 //go:linkname libc_Fchown libc_Fchown
@@ -174,6 +173,7 @@
 //go:linkname libc_recvfrom libc_recvfrom
 //go:linkname libc___xnet_recvmsg libc___xnet_recvmsg
 //go:linkname libc_getexecname libc_getexecname
+//go:linkname libc_utimensat libc_utimensat
 
 type libcFunc uintptr
 
@@ -192,7 +192,6 @@
 	libc_Chroot,
 	libc_Close,
 	libc_Dup,
-	libc_Exit,
 	libc_Fchdir,
 	libc_Fchmod,
 	libc_Fchown,
@@ -260,7 +259,8 @@
 	libc_setsockopt,
 	libc_recvfrom,
 	libc___xnet_recvmsg,
-	libc_getexecname libcFunc
+	libc_getexecname,
+	libc_utimensat libcFunc
 )
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -410,11 +410,6 @@
 	return
 }
 
-func Exit(code int) {
-	sysvicall6(uintptr(unsafe.Pointer(&libc_Exit)), 1, uintptr(code), 0, 0, 0, 0, 0)
-	return
-}
-
 func Fchdir(fd int) (err error) {
 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_Fchdir)), 1, uintptr(fd), 0, 0, 0, 0, 0)
 	if e1 != 0 {
@@ -1084,3 +1079,16 @@
 	}
 	return
 }
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_utimensat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
index 2283c79..1626c30 100644
--- a/src/syscall/zsyscall_windows.go
+++ b/src/syscall/zsyscall_windows.go
@@ -80,6 +80,7 @@
 	procCancelIo                           = modkernel32.NewProc("CancelIo")
 	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
 	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
+	procCreateProcessAsUserW               = modadvapi32.NewProc("CreateProcessAsUserW")
 	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
 	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
 	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
@@ -616,6 +617,24 @@
 	return
 }
 
+func CreateProcessAsUser(token Token, 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(procCreateProcessAsUserW.Addr(), 11, uintptr(token), 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)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
 func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
 	var _p0 uint32
 	if inheritHandle {
diff --git a/src/syscall/zsysnum_dragonfly_amd64.go b/src/syscall/zsysnum_dragonfly_amd64.go
index 3c2e342..bc535f2 100644
--- a/src/syscall/zsysnum_dragonfly_amd64.go
+++ b/src/syscall/zsysnum_dragonfly_amd64.go
@@ -301,5 +301,6 @@
 	SYS_LPATHCONF              = 533 // { int lpathconf(char *path, int name); }
 	SYS_VMM_GUEST_CTL          = 534 // { int vmm_guest_ctl(int op, struct vmm_guest_options *options); }
 	SYS_VMM_GUEST_SYNC_ADDR    = 535 // { int vmm_guest_sync_addr(long *dstaddr, long *srcaddr); }
+	SYS_UTIMENSAT              = 539 // { int utimensat(int fd, const char *path, const struct timespec *ts, int flags); }
 	SYS_ACCEPT4                = 541 // { int accept4(int s, caddr_t name, int *anamelen, int flags); }
 )
diff --git a/src/syscall/zsysnum_freebsd_386.go b/src/syscall/zsysnum_freebsd_386.go
index 5e47217..d0e403a 100644
--- a/src/syscall/zsysnum_freebsd_386.go
+++ b/src/syscall/zsysnum_freebsd_386.go
@@ -347,4 +347,5 @@
 	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
 )
diff --git a/src/syscall/zsysnum_freebsd_amd64.go b/src/syscall/zsysnum_freebsd_amd64.go
index df8928c..2fa4d21 100644
--- a/src/syscall/zsysnum_freebsd_amd64.go
+++ b/src/syscall/zsysnum_freebsd_amd64.go
@@ -347,4 +347,5 @@
 	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
 )
diff --git a/src/syscall/zsysnum_freebsd_arm.go b/src/syscall/zsysnum_freebsd_arm.go
index f670a59..d2caa8f 100644
--- a/src/syscall/zsysnum_freebsd_arm.go
+++ b/src/syscall/zsysnum_freebsd_arm.go
@@ -347,4 +347,5 @@
 	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
 )
diff --git a/src/syscall/ztypes_darwin_386.go b/src/syscall/ztypes_darwin_386.go
index 7298d02..e2cf12f 100644
--- a/src/syscall/ztypes_darwin_386.go
+++ b/src/syscall/ztypes_darwin_386.go
@@ -437,6 +437,10 @@
 	Pad_cgo_0 [2]byte
 }
 
+const (
+	_AT_FDCWD = -0x2
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_darwin_amd64.go b/src/syscall/ztypes_darwin_amd64.go
index ec95d51..bbd5bec 100644
--- a/src/syscall/ztypes_darwin_amd64.go
+++ b/src/syscall/ztypes_darwin_amd64.go
@@ -446,6 +446,10 @@
 	Pad_cgo_0 [2]byte
 }
 
+const (
+	_AT_FDCWD = -0x2
+)
+
 type Termios struct {
 	Iflag     uint64
 	Oflag     uint64
diff --git a/src/syscall/ztypes_darwin_arm.go b/src/syscall/ztypes_darwin_arm.go
index 91c4470..ca77479 100644
--- a/src/syscall/ztypes_darwin_arm.go
+++ b/src/syscall/ztypes_darwin_arm.go
@@ -438,6 +438,10 @@
 	Pad_cgo_0 [2]byte
 }
 
+const (
+	_AT_FDCWD = -0x2
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_darwin_arm64.go b/src/syscall/ztypes_darwin_arm64.go
index 1d65cfd..e9c8549 100644
--- a/src/syscall/ztypes_darwin_arm64.go
+++ b/src/syscall/ztypes_darwin_arm64.go
@@ -446,6 +446,10 @@
 	Pad_cgo_0 [2]byte
 }
 
+const (
+	_AT_FDCWD = -0x2
+)
+
 type Termios struct {
 	Iflag     uint64
 	Oflag     uint64
diff --git a/src/syscall/ztypes_dragonfly_amd64.go b/src/syscall/ztypes_dragonfly_amd64.go
index 00120d0..dbbd29a 100644
--- a/src/syscall/ztypes_dragonfly_amd64.go
+++ b/src/syscall/ztypes_dragonfly_amd64.go
@@ -432,6 +432,10 @@
 	Pad_cgo_0 [6]byte
 }
 
+const (
+	_AT_FDCWD = 0xfffafdcd
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_freebsd_386.go b/src/syscall/ztypes_freebsd_386.go
index d972fb6..c23bacf 100644
--- a/src/syscall/ztypes_freebsd_386.go
+++ b/src/syscall/ztypes_freebsd_386.go
@@ -483,6 +483,10 @@
 	X_bzh_pad  [5]uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_freebsd_amd64.go b/src/syscall/ztypes_freebsd_amd64.go
index 0a5a10b..1e5822f 100644
--- a/src/syscall/ztypes_freebsd_amd64.go
+++ b/src/syscall/ztypes_freebsd_amd64.go
@@ -486,6 +486,10 @@
 	X_bzh_pad  [5]uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_freebsd_arm.go b/src/syscall/ztypes_freebsd_arm.go
index 5d7acd5..f65a929 100644
--- a/src/syscall/ztypes_freebsd_arm.go
+++ b/src/syscall/ztypes_freebsd_arm.go
@@ -486,6 +486,10 @@
 	X_bzh_pad  [5]uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_linux_mips64.go b/src/syscall/ztypes_linux_mips64.go
index 925afb9..8c5a0d1 100644
--- a/src/syscall/ztypes_linux_mips64.go
+++ b/src/syscall/ztypes_linux_mips64.go
@@ -130,15 +130,12 @@
 	Spare   [5]int64
 }
 
-// Note: on mips64, we're using the getdents syscall,
-// so the Dirent struct is different.
-
 type Dirent struct {
 	Ino       uint64
 	Off       int64
 	Reclen    uint16
-	Name      [256]int8
 	Type      uint8
+	Name      [256]int8
 	Pad_cgo_0 [5]byte
 }
 
diff --git a/src/syscall/ztypes_linux_mips64le.go b/src/syscall/ztypes_linux_mips64le.go
index 925afb9..8c5a0d1 100644
--- a/src/syscall/ztypes_linux_mips64le.go
+++ b/src/syscall/ztypes_linux_mips64le.go
@@ -130,15 +130,12 @@
 	Spare   [5]int64
 }
 
-// Note: on mips64, we're using the getdents syscall,
-// so the Dirent struct is different.
-
 type Dirent struct {
 	Ino       uint64
 	Off       int64
 	Reclen    uint16
-	Name      [256]int8
 	Type      uint8
+	Name      [256]int8
 	Pad_cgo_0 [5]byte
 }
 
diff --git a/src/syscall/ztypes_linux_ppc64.go b/src/syscall/ztypes_linux_ppc64.go
index de817f5..087a70d 100644
--- a/src/syscall/ztypes_linux_ppc64.go
+++ b/src/syscall/ztypes_linux_ppc64.go
@@ -600,7 +600,7 @@
 const (
 	IUCLC  = 0x1000
 	OLCUC  = 0x4
-	TCGETS = 0x403c7413
-	TCSETS = 0x803c7414
+	TCGETS = 0x402c7413
+	TCSETS = 0x802c7414
 	XCASE  = 0x4000
 )
diff --git a/src/syscall/ztypes_linux_ppc64le.go b/src/syscall/ztypes_linux_ppc64le.go
index e75d8e3..8412bdd 100644
--- a/src/syscall/ztypes_linux_ppc64le.go
+++ b/src/syscall/ztypes_linux_ppc64le.go
@@ -600,7 +600,7 @@
 const (
 	IUCLC  = 0x1000
 	OLCUC  = 0x4
-	TCGETS = 0x403c7413
-	TCSETS = 0x803c7414
+	TCGETS = 0x402c7413
+	TCSETS = 0x802c7414
 	XCASE  = 0x4000
 )
diff --git a/src/syscall/ztypes_netbsd_386.go b/src/syscall/ztypes_netbsd_386.go
index 1752c6c..c8afb98 100644
--- a/src/syscall/ztypes_netbsd_386.go
+++ b/src/syscall/ztypes_netbsd_386.go
@@ -372,6 +372,10 @@
 	Usec int32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_netbsd_amd64.go b/src/syscall/ztypes_netbsd_amd64.go
index b8d4b0b..9336fc1 100644
--- a/src/syscall/ztypes_netbsd_amd64.go
+++ b/src/syscall/ztypes_netbsd_amd64.go
@@ -379,6 +379,10 @@
 	Usec int64
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_netbsd_arm.go b/src/syscall/ztypes_netbsd_arm.go
index c21d875..0e4fe4a 100644
--- a/src/syscall/ztypes_netbsd_arm.go
+++ b/src/syscall/ztypes_netbsd_arm.go
@@ -377,6 +377,10 @@
 	Usec int32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_openbsd_386.go b/src/syscall/ztypes_openbsd_386.go
index 0376d3a..05e79d8 100644
--- a/src/syscall/ztypes_openbsd_386.go
+++ b/src/syscall/ztypes_openbsd_386.go
@@ -430,6 +430,10 @@
 	Usec uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_openbsd_amd64.go b/src/syscall/ztypes_openbsd_amd64.go
index bf23626..8bd169c 100644
--- a/src/syscall/ztypes_openbsd_amd64.go
+++ b/src/syscall/ztypes_openbsd_amd64.go
@@ -437,6 +437,10 @@
 	Usec uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_openbsd_arm.go b/src/syscall/ztypes_openbsd_arm.go
index e1d8938..0c30259 100644
--- a/src/syscall/ztypes_openbsd_arm.go
+++ b/src/syscall/ztypes_openbsd_arm.go
@@ -423,6 +423,10 @@
 	Usec uint32
 }
 
+const (
+	_AT_FDCWD = -0x64
+)
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32
diff --git a/src/syscall/ztypes_solaris_amd64.go b/src/syscall/ztypes_solaris_amd64.go
index 4cf07ed..12307ab 100644
--- a/src/syscall/ztypes_solaris_amd64.go
+++ b/src/syscall/ztypes_solaris_amd64.go
@@ -358,6 +358,10 @@
 	Pad_cgo_0 [2]byte
 }
 
+const (
+	_AT_FDCWD = 0xffd19553
+)
+
 type Termios struct {
 	Iflag     uint32
 	Oflag     uint32
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index 84005aa..4d569b7 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -86,7 +86,7 @@
 // want to measure.
 func (b *B) StopTimer() {
 	if b.timerOn {
-		b.duration += time.Now().Sub(b.start)
+		b.duration += time.Since(b.start)
 		runtime.ReadMemStats(&memStats)
 		b.netAllocs += memStats.Mallocs - b.startAllocs
 		b.netBytes += memStats.TotalAlloc - b.startBytes
@@ -238,7 +238,7 @@
 
 // run executes the benchmark in a separate goroutine, including all of its
 // subbenchmarks. b must not have subbenchmarks.
-func (b *B) run() BenchmarkResult {
+func (b *B) run() {
 	labelsOnce.Do(func() {
 		fmt.Fprintf(b.w, "goos: %s\n", runtime.GOOS)
 		fmt.Fprintf(b.w, "goarch: %s\n", runtime.GOARCH)
@@ -253,7 +253,6 @@
 		// Running func Benchmark.
 		b.doBench()
 	}
-	return b.result
 }
 
 func (b *B) doBench() BenchmarkResult {
@@ -427,44 +426,46 @@
 // processBench runs bench b for the configured CPU counts and prints the results.
 func (ctx *benchContext) processBench(b *B) {
 	for i, procs := range cpuList {
-		runtime.GOMAXPROCS(procs)
-		benchName := benchmarkName(b.name, procs)
-		fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
-		// Recompute the running time for all but the first iteration.
-		if i > 0 {
-			b = &B{
-				common: common{
-					signal: make(chan bool),
-					name:   b.name,
-					w:      b.w,
-					chatty: b.chatty,
-				},
-				benchFunc: b.benchFunc,
-				benchTime: b.benchTime,
+		for j := uint(0); j < *count; j++ {
+			runtime.GOMAXPROCS(procs)
+			benchName := benchmarkName(b.name, procs)
+			fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
+			// Recompute the running time for all but the first iteration.
+			if i > 0 || j > 0 {
+				b = &B{
+					common: common{
+						signal: make(chan bool),
+						name:   b.name,
+						w:      b.w,
+						chatty: b.chatty,
+					},
+					benchFunc: b.benchFunc,
+					benchTime: b.benchTime,
+				}
+				b.run1()
 			}
-			b.run1()
-		}
-		r := b.doBench()
-		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.Fprintf(b.w, "--- FAIL: %s\n%s", benchName, b.output)
-			continue
-		}
-		results := r.String()
-		if *benchmarkMemory || b.showAllocResult {
-			results += "\t" + r.MemString()
-		}
-		fmt.Fprintln(b.w, 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.Fprintf(b.w, "--- 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)
+			r := b.doBench()
+			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.Fprintf(b.w, "--- FAIL: %s\n%s", benchName, b.output)
+				continue
+			}
+			results := r.String()
+			if *benchmarkMemory || b.showAllocResult {
+				results += "\t" + r.MemString()
+			}
+			fmt.Fprintln(b.w, 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.Fprintf(b.w, "--- 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)
+			}
 		}
 	}
 }
@@ -474,9 +475,6 @@
 //
 // A subbenchmark is like any other benchmark. A benchmark that calls Run at
 // least once will not be measured itself and will be called once with N=1.
-//
-// Run may be called simultaneously from multiple goroutines, but all such
-// calls must return before the outer benchmark function for b returns.
 func (b *B) Run(name string, f func(b *B)) bool {
 	// Since b has subbenchmarks, we will no longer run it as a benchmark itself.
 	// Release the lock and acquire it on exit to ensure locks stay paired.
diff --git a/src/testing/example.go b/src/testing/example.go
index e5bce7a..b995550 100644
--- a/src/testing/example.go
+++ b/src/testing/example.go
@@ -87,7 +87,7 @@
 
 	// Clean up in a deferred call so we can recover if the example panics.
 	defer func() {
-		dstr := fmtDuration(time.Now().Sub(start))
+		dstr := fmtDuration(time.Since(start))
 
 		// Close pipe, restore stdout, get output.
 		w.Close()
diff --git a/src/testing/internal/testdeps/deps.go b/src/testing/internal/testdeps/deps.go
index 042f696..4986898 100644
--- a/src/testing/internal/testdeps/deps.go
+++ b/src/testing/internal/testdeps/deps.go
@@ -11,9 +11,13 @@
 package testdeps
 
 import (
+	"bufio"
+	"internal/testlog"
 	"io"
 	"regexp"
 	"runtime/pprof"
+	"strings"
+	"sync"
 )
 
 // TestDeps is an implementation of the testing.testDeps interface,
@@ -56,3 +60,69 @@
 func (TestDeps) ImportPath() string {
 	return ImportPath
 }
+
+// testLog implements testlog.Interface, logging actions by package os.
+type testLog struct {
+	mu  sync.Mutex
+	w   *bufio.Writer
+	set bool
+}
+
+func (l *testLog) Getenv(key string) {
+	l.add("getenv", key)
+}
+
+func (l *testLog) Open(name string) {
+	l.add("open", name)
+}
+
+func (l *testLog) Stat(name string) {
+	l.add("stat", name)
+}
+
+func (l *testLog) Chdir(name string) {
+	l.add("chdir", name)
+}
+
+// add adds the (op, name) pair to the test log.
+func (l *testLog) add(op, name string) {
+	if strings.Contains(name, "\n") || name == "" {
+		return
+	}
+
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.w == nil {
+		return
+	}
+	l.w.WriteString(op)
+	l.w.WriteByte(' ')
+	l.w.WriteString(name)
+	l.w.WriteByte('\n')
+}
+
+var log testLog
+var didSetLogger bool
+
+func (TestDeps) StartTestLog(w io.Writer) {
+	log.mu.Lock()
+	log.w = bufio.NewWriter(w)
+	if !log.set {
+		// Tests that define TestMain and then run m.Run multiple times
+		// will call StartTestLog/StopTestLog multiple times.
+		// Checking log.set avoids calling testlog.SetLogger multiple times
+		// (which will panic) and also avoids writing the header multiple times.
+		log.set = true
+		testlog.SetLogger(&log)
+		log.w.WriteString("# test log\n") // known to cmd/go/internal/test/test.go
+	}
+	log.mu.Unlock()
+}
+
+func (TestDeps) StopTestLog() error {
+	log.mu.Lock()
+	defer log.mu.Unlock()
+	err := log.w.Flush()
+	log.w = nil
+	return err
+}
diff --git a/src/testing/iotest/logger.go b/src/testing/iotest/logger.go
index 0aec15c..99548dc 100644
--- a/src/testing/iotest/logger.go
+++ b/src/testing/iotest/logger.go
@@ -47,7 +47,7 @@
 }
 
 // NewReadLogger returns a reader that behaves like r except
-// that it logs (using log.Print) each read to standard error,
+// that it logs (using log.Printf) each read to standard error,
 // printing the prefix and the hexadecimal data read.
 func NewReadLogger(prefix string, r io.Reader) io.Reader {
 	return &readLogger{prefix, r}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 3585af3..f56dbf8 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -6,8 +6,8 @@
 // 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.
+// where Xxx does not start with a lowercase letter. The function name
+// serves to identify the test routine.
 //
 // Within these functions, use the Error, Fail or related methods to signal failure.
 //
@@ -242,6 +242,9 @@
 	// full test of the package.
 	short = flag.Bool("test.short", false, "run smaller test suite to save time")
 
+	// The failfast flag requests that test execution stop after the first test failure.
+	failFast = flag.Bool("test.failfast", false, "do not start new tests after the first test failure")
+
 	// 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
@@ -252,7 +255,7 @@
 	chatty               = flag.Bool("test.v", false, "verbose: print additional output")
 	count                = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
 	coverProfile         = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
-	matchList            = flag.String("test.list", "", "list tests, examples, and benchmarch maching `regexp` then exit")
+	matchList            = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
 	match                = flag.String("test.run", "", "run only tests and examples matching `regexp`")
 	memProfile           = flag.String("test.memprofile", "", "write a memory profile to `file`")
 	memProfileRate       = flag.Int("test.memprofilerate", 0, "set memory profiling `rate` (see runtime.MemProfileRate)")
@@ -262,13 +265,17 @@
 	mutexProfile         = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
 	mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
 	traceFile            = flag.String("test.trace", "", "write an execution trace to `file`")
-	timeout              = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (0 means unlimited)")
+	timeout              = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
 	cpuListStr           = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
 	parallel             = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
+	testlog              = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)")
 
 	haveExamples bool // are there examples?
 
-	cpuList []int
+	cpuList     []int
+	testlogFile *os.File
+
+	numFailed uint32 // number of test failures
 )
 
 // common holds the elements common between T and B and
@@ -512,7 +519,9 @@
 	return failed || c.raceErrors+race.Errors() > 0
 }
 
-// FailNow marks the function as having failed and stops its execution.
+// FailNow marks the function as having failed and stops its execution
+// by calling runtime.Goexit (which then runs all deferred calls in the
+// current goroutine).
 // 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
@@ -600,7 +609,8 @@
 	c.SkipNow()
 }
 
-// SkipNow marks the test as having been skipped and stops its execution.
+// SkipNow marks the test as having been skipped and stops its execution
+// by calling runtime.Goexit.
 // If a test fails (see Error, Errorf, Fail) and is then skipped,
 // it is still considered to have failed.
 // Execution will continue at the next test or benchmark. See also FailNow.
@@ -673,9 +683,30 @@
 	t.parent.sub = append(t.parent.sub, t)
 	t.raceErrors += race.Errors()
 
+	if t.chatty {
+		// Print directly to root's io.Writer so there is no delay.
+		root := t.parent
+		for ; root.parent != nil; root = root.parent {
+		}
+		root.mu.Lock()
+		fmt.Fprintf(root.w, "=== PAUSE %s\n", t.name)
+		root.mu.Unlock()
+	}
+
 	t.signal <- true   // Release calling test.
 	<-t.parent.barrier // Wait for the parent test to complete.
 	t.context.waitParallel()
+
+	if t.chatty {
+		// Print directly to root's io.Writer so there is no delay.
+		root := t.parent
+		for ; root.parent != nil; root = root.parent {
+		}
+		root.mu.Lock()
+		fmt.Fprintf(root.w, "=== CONT  %s\n", t.name)
+		root.mu.Unlock()
+	}
+
 	t.start = time.Now()
 	t.raceErrors += -race.Errors()
 }
@@ -699,7 +730,7 @@
 			t.Errorf("race detected during execution of test")
 		}
 
-		t.duration += time.Now().Sub(t.start)
+		t.duration += time.Since(t.start)
 		// If the test panicked, print any test output before dying.
 		err := recover()
 		if !t.finished && err == nil {
@@ -744,19 +775,23 @@
 	t.start = time.Now()
 	t.raceErrors = -race.Errors()
 	fn(t)
+
+	if t.failed {
+		atomic.AddUint32(&numFailed, 1)
+	}
 	t.finished = true
 }
 
-// Run runs f as a subtest of t called name. It reports whether f succeeded. Run
-// runs f in a separate goroutine and will block until all its parallel subtests
-// have completed.
+// Run runs f as a subtest of t called name. It runs f in a separate goroutine
+// and blocks until f returns or calls t.Parallel to become a parallel test.
+// Run reports whether f succeeded (or at least did not fail before calling t.Parallel).
 //
 // Run may be called simultaneously from multiple goroutines, but all such calls
 // must return before the outer test function for t returns.
 func (t *T) Run(name string, f func(t *T)) bool {
 	atomic.StoreInt32(&t.hasSub, 1)
 	testName, ok, _ := t.context.match.fullName(&t.common, name)
-	if !ok {
+	if !ok || shouldFailFast() {
 		return true
 	}
 	t = &T{
@@ -857,6 +892,8 @@
 func (f matchStringOnly) WriteHeapProfile(w io.Writer) error          { return errMain }
 func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return errMain }
 func (f matchStringOnly) ImportPath() string                          { return "" }
+func (f matchStringOnly) StartTestLog(io.Writer)                      {}
+func (f matchStringOnly) StopTestLog() error                          { return errMain }
 
 // Main is an internal function, part of the implementation of the "go test" command.
 // It was exported because it is cross-package and predates "internal" packages.
@@ -874,6 +911,11 @@
 	tests      []InternalTest
 	benchmarks []InternalBenchmark
 	examples   []InternalExample
+
+	timer     *time.Timer
+	afterOnce sync.Once
+
+	numRun int
 }
 
 // testDeps is an internal interface of functionality that is
@@ -881,12 +923,14 @@
 // The canonical implementation of this interface is
 // testing/internal/testdeps's TestDeps.
 type testDeps interface {
+	ImportPath() string
 	MatchString(pat, str string) (bool, error)
 	StartCPUProfile(io.Writer) error
 	StopCPUProfile()
+	StartTestLog(io.Writer)
+	StopTestLog() error
 	WriteHeapProfile(io.Writer) error
 	WriteProfileTo(string, io.Writer, int) error
-	ImportPath() string
 }
 
 // MainStart is meant for use by tests generated by 'go test'.
@@ -903,11 +947,23 @@
 
 // Run runs the tests. It returns an exit code to pass to os.Exit.
 func (m *M) Run() int {
+	// Count the number of calls to m.Run.
+	// We only ever expected 1, but we didn't enforce that,
+	// and now there are tests in the wild that call m.Run multiple times.
+	// Sigh. golang.org/issue/23129.
+	m.numRun++
+
 	// TestMain may have already called flag.Parse.
 	if !flag.Parsed() {
 		flag.Parse()
 	}
 
+	if *parallel < 1 {
+		fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
+		flag.Usage()
+		return 2
+	}
+
 	if len(*matchList) != 0 {
 		listTests(m.deps.MatchString, m.tests, m.benchmarks, m.examples)
 		return 0
@@ -916,22 +972,21 @@
 	parseCpuList()
 
 	m.before()
-	startAlarm()
+	defer m.after()
+	m.startAlarm()
 	haveExamples = len(m.examples) > 0
 	testRan, testOk := runTests(m.deps.MatchString, m.tests)
 	exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
-	stopAlarm()
+	m.stopAlarm()
 	if !testRan && !exampleRan && *matchBenchmarks == "" {
 		fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
 	}
 	if !testOk || !exampleOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 {
 		fmt.Println("FAIL")
-		m.after()
 		return 1
 	}
 
 	fmt.Println("PASS")
-	m.after()
 	return 0
 }
 
@@ -989,27 +1044,32 @@
 	ok = true
 	for _, procs := range cpuList {
 		runtime.GOMAXPROCS(procs)
-		ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run"))
-		t := &T{
-			common: common{
-				signal:  make(chan bool),
-				barrier: make(chan bool),
-				w:       os.Stdout,
-				chatty:  *chatty,
-			},
-			context: ctx,
-		}
-		tRunner(t, func(t *T) {
-			for _, test := range tests {
-				t.Run(test.Name, test.F)
+		for i := uint(0); i < *count; i++ {
+			if shouldFailFast() {
+				break
 			}
-			// Run catching the signal rather than the tRunner as a separate
-			// goroutine to avoid adding a goroutine during the sequential
-			// phase as this pollutes the stacktrace output when aborting.
-			go func() { <-t.signal }()
-		})
-		ok = ok && !t.Failed()
-		ran = ran || t.ran
+			ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run"))
+			t := &T{
+				common: common{
+					signal:  make(chan bool),
+					barrier: make(chan bool),
+					w:       os.Stdout,
+					chatty:  *chatty,
+				},
+				context: ctx,
+			}
+			tRunner(t, func(t *T) {
+				for _, test := range tests {
+					t.Run(test.Name, test.F)
+				}
+				// Run catching the signal rather than the tRunner as a separate
+				// goroutine to avoid adding a goroutine during the sequential
+				// phase as this pollutes the stacktrace output when aborting.
+				go func() { <-t.signal }()
+			})
+			ok = ok && !t.Failed()
+			ran = ran || t.ran
+		}
 	}
 	return ran, ok
 }
@@ -1055,10 +1115,46 @@
 		fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
 		os.Exit(2)
 	}
+	if *testlog != "" {
+		// Note: Not using toOutputDir.
+		// This file is for use by cmd/go, not users.
+		var f *os.File
+		var err error
+		if m.numRun == 1 {
+			f, err = os.Create(*testlog)
+		} else {
+			f, err = os.OpenFile(*testlog, os.O_WRONLY, 0)
+			if err == nil {
+				f.Seek(0, io.SeekEnd)
+			}
+		}
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+			os.Exit(2)
+		}
+		m.deps.StartTestLog(f)
+		testlogFile = f
+	}
 }
 
 // after runs after all testing.
 func (m *M) after() {
+	m.afterOnce.Do(func() {
+		m.writeProfiles()
+	})
+}
+
+func (m *M) writeProfiles() {
+	if *testlog != "" {
+		if err := m.deps.StopTestLog(); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
+			os.Exit(2)
+		}
+		if err := testlogFile.Close(); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
+			os.Exit(2)
+		}
+	}
 	if *cpuProfile != "" {
 		m.deps.StopCPUProfile() // flushes profile to disk
 	}
@@ -1135,12 +1231,11 @@
 	return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
 }
 
-var timer *time.Timer
-
 // startAlarm starts an alarm if requested.
-func startAlarm() {
+func (m *M) startAlarm() {
 	if *timeout > 0 {
-		timer = time.AfterFunc(*timeout, func() {
+		m.timer = time.AfterFunc(*timeout, func() {
+			m.after()
 			debug.SetTraceback("all")
 			panic(fmt.Sprintf("test timed out after %v", *timeout))
 		})
@@ -1148,9 +1243,9 @@
 }
 
 // stopAlarm turns off the alarm.
-func stopAlarm() {
+func (m *M) stopAlarm() {
 	if *timeout > 0 {
-		timer.Stop()
+		m.timer.Stop()
 	}
 }
 
@@ -1165,13 +1260,13 @@
 			fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
 			os.Exit(1)
 		}
-		for i := uint(0); i < *count; i++ {
-			cpuList = append(cpuList, cpu)
-		}
+		cpuList = append(cpuList, cpu)
 	}
 	if cpuList == nil {
-		for i := uint(0); i < *count; i++ {
-			cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
-		}
+		cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
 	}
 }
+
+func shouldFailFast() bool {
+	return *failFast && atomic.LoadUint32(&numFailed) > 0
+}
diff --git a/src/text/tabwriter/tabwriter.go b/src/text/tabwriter/tabwriter.go
index 752c9b8..ae6c7a2 100644
--- a/src/text/tabwriter/tabwriter.go
+++ b/src/text/tabwriter/tabwriter.go
@@ -333,52 +333,52 @@
 	for this := line0; this < line1; this++ {
 		line := b.lines[this]
 
-		if column < len(line)-1 {
-			// cell exists in this column => this line
-			// has more cells than the previous line
-			// (the last cell per line is ignored because cells are
-			// tab-terminated; the last cell per line describes the
-			// text before the newline/formfeed and does not belong
-			// to a column)
-
-			// print unprinted lines until beginning of block
-			pos = b.writeLines(pos, line0, this)
-			line0 = this
-
-			// column block begin
-			width := b.minwidth // minimal column width
-			discardable := true // true if all cells in this column are empty and "soft"
-			for ; this < line1; this++ {
-				line = b.lines[this]
-				if column < len(line)-1 {
-					// cell exists in this column
-					c := line[column]
-					// update width
-					if w := c.width + b.padding; w > width {
-						width = w
-					}
-					// update discardable
-					if c.width > 0 || c.htab {
-						discardable = false
-					}
-				} else {
-					break
-				}
-			}
-			// column block end
-
-			// discard empty columns if necessary
-			if discardable && b.flags&DiscardEmptyColumns != 0 {
-				width = 0
-			}
-
-			// format and print all columns to the right of this column
-			// (we know the widths of this column and all columns to the left)
-			b.widths = append(b.widths, width) // push width
-			pos = b.format(pos, line0, this)
-			b.widths = b.widths[0 : len(b.widths)-1] // pop width
-			line0 = this
+		if column >= len(line)-1 {
+			continue
 		}
+		// cell exists in this column => this line
+		// has more cells than the previous line
+		// (the last cell per line is ignored because cells are
+		// tab-terminated; the last cell per line describes the
+		// text before the newline/formfeed and does not belong
+		// to a column)
+
+		// print unprinted lines until beginning of block
+		pos = b.writeLines(pos, line0, this)
+		line0 = this
+
+		// column block begin
+		width := b.minwidth // minimal column width
+		discardable := true // true if all cells in this column are empty and "soft"
+		for ; this < line1; this++ {
+			line = b.lines[this]
+			if column >= len(line)-1 {
+				break
+			}
+			// cell exists in this column
+			c := line[column]
+			// update width
+			if w := c.width + b.padding; w > width {
+				width = w
+			}
+			// update discardable
+			if c.width > 0 || c.htab {
+				discardable = false
+			}
+		}
+		// column block end
+
+		// discard empty columns if necessary
+		if discardable && b.flags&DiscardEmptyColumns != 0 {
+			width = 0
+		}
+
+		// format and print all columns to the right of this column
+		// (we know the widths of this column and all columns to the left)
+		b.widths = append(b.widths, width) // push width
+		pos = b.format(pos, line0, this)
+		b.widths = b.widths[0 : len(b.widths)-1] // pop width
+		line0 = this
 	}
 
 	// print unprinted lines until end
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index e54a579..83c38cd 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -79,10 +79,7 @@
 // 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
+	return strings.Replace(str, "%", "%%", -1)
 }
 
 // TODO: It would be nice if ExecError was more broken down, but
@@ -930,29 +927,6 @@
 	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 {
@@ -960,13 +934,21 @@
 	}
 	switch v[0].Kind() {
 	case reflect.Float32, reflect.Float64:
-		sort.Sort(rvFloats{v})
+		sort.Slice(v, func(i, j int) bool {
+			return v[i].Float() < v[j].Float()
+		})
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		sort.Sort(rvInts{v})
+		sort.Slice(v, func(i, j int) bool {
+			return v[i].Int() < v[j].Int()
+		})
 	case reflect.String:
-		sort.Sort(rvStrings{v})
+		sort.Slice(v, func(i, j int) bool {
+			return v[i].String() < v[j].String()
+		})
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		sort.Sort(rvUints{v})
+		sort.Slice(v, func(i, j int) bool {
+			return v[i].Uint() < v[j].Uint()
+		})
 	}
 	return v
 }
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index 9f7e637..d0cda6b 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -44,6 +44,12 @@
 	MSIEmpty map[string]int
 	MXI      map[interface{}]int
 	MII      map[int]int
+	MI32S    map[int32]string
+	MI64S    map[int64]string
+	MUI32S   map[uint32]string
+	MUI64S   map[uint64]string
+	MI8S     map[int8]string
+	MUI8S    map[uint8]string
 	SMSI     []map[string]int
 	// Empty interfaces; used to see if we can dig inside one.
 	Empty0 interface{} // nil
@@ -124,6 +130,12 @@
 	MSIone: map[string]int{"one": 1},
 	MXI:    map[interface{}]int{"one": 1},
 	MII:    map[int]int{1: 1},
+	MI32S:  map[int32]string{1: "one", 2: "two"},
+	MI64S:  map[int64]string{2: "i642", 3: "i643"},
+	MUI32S: map[uint32]string{2: "u322", 3: "u323"},
+	MUI64S: map[uint64]string{2: "ui642", 3: "ui643"},
+	MI8S:   map[int8]string{2: "i82", 3: "i83"},
+	MUI8S:  map[uint8]string{2: "u82", 3: "u83"},
 	SMSI: []map[string]int{
 		{"one": 1, "two": 2},
 		{"eleven": 11, "twelve": 12},
@@ -448,6 +460,11 @@
 	{"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
 	{"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
 	{"nil[1]", "{{index nil 1}}", "", tVal, false},
+	{"map MI64S", "{{index .MI64S 2}}", "i642", tVal, true},
+	{"map MI32S", "{{index .MI32S 2}}", "two", tVal, true},
+	{"map MUI64S", "{{index .MUI64S 3}}", "ui643", tVal, true},
+	{"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true},
+	{"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true},
 
 	// Len.
 	{"slice", "{{len .SI}}", "3", tVal, true},
diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
index 9107431..abddfa1 100644
--- a/src/text/template/funcs.go
+++ b/src/text/template/funcs.go
@@ -139,10 +139,24 @@
 		}
 		value = reflect.Zero(argType)
 	}
-	if !value.Type().AssignableTo(argType) {
-		return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
+	if value.Type().AssignableTo(argType) {
+		return value, nil
 	}
-	return value, nil
+	if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {
+		value = value.Convert(argType)
+		return value, nil
+	}
+	return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
+}
+
+func intLike(typ reflect.Kind) bool {
+	switch typ {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return true
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return true
+	}
+	return false
 }
 
 // Indexing.
diff --git a/src/text/template/multi_test.go b/src/text/template/multi_test.go
index 5d8c08f..5769470 100644
--- a/src/text/template/multi_test.go
+++ b/src/text/template/multi_test.go
@@ -247,6 +247,9 @@
 		t.Fatal(err)
 	}
 	added, err := root.AddParseTree("c", tree["c"])
+	if err != nil {
+		t.Fatal(err)
+	}
 	// Execute.
 	var b bytes.Buffer
 	err = added.ExecuteTemplate(&b, "a", 0)
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
index 6fbf36d..e112cb7 100644
--- a/src/text/template/parse/lex.go
+++ b/src/text/template/parse/lex.go
@@ -110,11 +110,9 @@
 	input      string    // the string being scanned
 	leftDelim  string    // start of action
 	rightDelim string    // end of action
-	state      stateFn   // the next lexing function to enter
 	pos        Pos       // current position in the input
 	start      Pos       // start position of this item
 	width      Pos       // width of last rune read from input
-	lastPos    Pos       // position of most recent item returned by nextItem
 	items      chan item // channel of scanned items
 	parenDepth int       // nesting depth of ( ) exprs
 	line       int       // 1+number of newlines seen
@@ -164,6 +162,7 @@
 
 // ignore skips over the pending input before this point.
 func (l *lexer) ignore() {
+	l.line += strings.Count(l.input[l.start:l.pos], "\n")
 	l.start = l.pos
 }
 
@@ -193,9 +192,7 @@
 // nextItem returns the next item from the input.
 // Called by the parser, not in the lexing goroutine.
 func (l *lexer) nextItem() item {
-	item := <-l.items
-	l.lastPos = item.pos
-	return item
+	return <-l.items
 }
 
 // drain drains the output so the lexing goroutine will exit.
@@ -227,8 +224,8 @@
 
 // run runs the state machine for the lexer.
 func (l *lexer) run() {
-	for l.state = lexText; l.state != nil; {
-		l.state = l.state(l)
+	for state := lexText; state != nil; {
+		state = state(l)
 	}
 	close(l.items)
 }
@@ -281,10 +278,9 @@
 		return true, false
 	}
 	// The right delim might have the marker before.
-	if strings.HasPrefix(l.input[l.pos:], rightTrimMarker) {
-		if strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) {
-			return true, true
-		}
+	if strings.HasPrefix(l.input[l.pos:], rightTrimMarker) &&
+		strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) {
+		return true, true
 	}
 	return false, false
 }
diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
index 2c73bb6..cb01cd9 100644
--- a/src/text/template/parse/lex_test.go
+++ b/src/text/template/parse/lex_test.go
@@ -404,6 +404,9 @@
 		if checkPos && i1[k].pos != i2[k].pos {
 			return false
 		}
+		if checkPos && i1[k].line != i2[k].line {
+			return false
+		}
 	}
 	return true
 }
@@ -452,7 +455,7 @@
 }
 
 var lexPosTests = []lexTest{
-	{"empty", "", []item{tEOF}},
+	{"empty", "", []item{{itemEOF, 0, "", 1}}},
 	{"punctuation", "{{,@%#}}", []item{
 		{itemLeftDelim, 0, "{{", 1},
 		{itemChar, 2, ",", 1},
@@ -470,6 +473,24 @@
 		{itemText, 13, "xyz", 1},
 		{itemEOF, 16, "", 1},
 	}},
+	{"trimafter", "{{x -}}\n{{y}}", []item{
+		{itemLeftDelim, 0, "{{", 1},
+		{itemIdentifier, 2, "x", 1},
+		{itemRightDelim, 5, "}}", 1},
+		{itemLeftDelim, 8, "{{", 2},
+		{itemIdentifier, 10, "y", 2},
+		{itemRightDelim, 11, "}}", 2},
+		{itemEOF, 13, "", 2},
+	}},
+	{"trimbefore", "{{x}}\n{{- y}}", []item{
+		{itemLeftDelim, 0, "{{", 1},
+		{itemIdentifier, 2, "x", 1},
+		{itemRightDelim, 3, "}}", 1},
+		{itemLeftDelim, 6, "{{", 2},
+		{itemIdentifier, 10, "y", 2},
+		{itemRightDelim, 11, "}}", 2},
+		{itemEOF, 13, "", 2},
+	}},
 }
 
 // The other tests don't check position, to make the test cases easier to construct.
@@ -485,7 +506,8 @@
 					if !equal(items[i:i+1], test.items[i:i+1], true) {
 						i1 := items[i]
 						i2 := test.items[i]
-						t.Errorf("\t#%d: got {%v %d %q} expected  {%v %d %q}", i, i1.typ, i1.pos, i1.val, i2.typ, i2.pos, i2.val)
+						t.Errorf("\t#%d: got {%v %d %q %d} expected {%v %d %q %d}",
+							i, i1.typ, i1.pos, i1.val, i1.line, i2.typ, i2.pos, i2.val, i2.line)
 					}
 				}
 			}
diff --git a/src/time/example_test.go b/src/time/example_test.go
index aeb63ca..8c64506 100644
--- a/src/time/example_test.go
+++ b/src/time/example_test.go
@@ -18,6 +18,112 @@
 	fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
 }
 
+func ExampleDuration_Round() {
+	d, err := time.ParseDuration("1h15m30.918273645s")
+	if err != nil {
+		panic(err)
+	}
+
+	round := []time.Duration{
+		time.Nanosecond,
+		time.Microsecond,
+		time.Millisecond,
+		time.Second,
+		2 * time.Second,
+		time.Minute,
+		10 * time.Minute,
+		time.Hour,
+	}
+
+	for _, r := range round {
+		fmt.Printf("d.Round(%6s) = %s\n", r, d.Round(r).String())
+	}
+	// Output:
+	// d.Round(   1ns) = 1h15m30.918273645s
+	// d.Round(   1µs) = 1h15m30.918274s
+	// d.Round(   1ms) = 1h15m30.918s
+	// d.Round(    1s) = 1h15m31s
+	// d.Round(    2s) = 1h15m30s
+	// d.Round(  1m0s) = 1h16m0s
+	// d.Round( 10m0s) = 1h20m0s
+	// d.Round(1h0m0s) = 1h0m0s
+}
+
+func ExampleDuration_String() {
+	t1 := time.Date(2016, time.August, 15, 0, 0, 0, 0, time.UTC)
+	t2 := time.Date(2017, time.February, 16, 0, 0, 0, 0, time.UTC)
+	fmt.Println(t2.Sub(t1).String())
+	// Output: 4440h0m0s
+}
+
+func ExampleDuration_Truncate() {
+	d, err := time.ParseDuration("1h15m30.918273645s")
+	if err != nil {
+		panic(err)
+	}
+
+	trunc := []time.Duration{
+		time.Nanosecond,
+		time.Microsecond,
+		time.Millisecond,
+		time.Second,
+		2 * time.Second,
+		time.Minute,
+		10 * time.Minute,
+		time.Hour,
+	}
+
+	for _, t := range trunc {
+		fmt.Printf("t.Truncate(%6s) = %s\n", t, d.Truncate(t).String())
+	}
+	// Output:
+	// t.Truncate(   1ns) = 1h15m30.918273645s
+	// t.Truncate(   1µs) = 1h15m30.918273s
+	// t.Truncate(   1ms) = 1h15m30.918s
+	// t.Truncate(    1s) = 1h15m30s
+	// t.Truncate(    2s) = 1h15m30s
+	// t.Truncate(  1m0s) = 1h15m0s
+	// t.Truncate( 10m0s) = 1h10m0s
+	// t.Truncate(1h0m0s) = 1h0m0s
+}
+
+func ExampleParseDuration() {
+	hours, _ := time.ParseDuration("10h")
+	complex, _ := time.ParseDuration("1h10m10s")
+
+	fmt.Println(hours)
+	fmt.Println(complex)
+	fmt.Printf("there are %.0f seconds in %v\n", complex.Seconds(), complex)
+	// Output:
+	// 10h0m0s
+	// 1h10m10s
+	// there are 4210 seconds in 1h10m10s
+}
+
+func ExampleDuration_Hours() {
+	h, _ := time.ParseDuration("4h30m")
+	fmt.Printf("I've got %.1f hours of work left.", h.Hours())
+	// Output: I've got 4.5 hours of work left.
+}
+
+func ExampleDuration_Minutes() {
+	m, _ := time.ParseDuration("1h30m")
+	fmt.Printf("The movie is %.0f minutes long.", m.Minutes())
+	// Output: The movie is 90 minutes long.
+}
+
+func ExampleDuration_Nanoseconds() {
+	ns, _ := time.ParseDuration("1000ns")
+	fmt.Printf("one microsecond has %d nanoseconds.", ns.Nanoseconds())
+	// Output: one microsecond has 1000 nanoseconds.
+}
+
+func ExampleDuration_Seconds() {
+	m, _ := time.ParseDuration("1m30s")
+	fmt.Printf("take off in t-%.0f seconds.", m.Seconds())
+	// Output: take off in t-90 seconds.
+}
+
 var c chan int
 
 func handle(int) {}
@@ -57,6 +163,25 @@
 	// Output: Go launched at 2009-11-10 15:00:00 -0800 PST
 }
 
+func ExampleNewTicker() {
+	ticker := time.NewTicker(time.Second)
+	defer ticker.Stop()
+	done := make(chan bool)
+	go func() {
+		time.Sleep(10 * time.Second)
+		done <- true
+	}()
+	for {
+		select {
+		case <-done:
+			fmt.Println("Done!")
+			return
+		case t := <-ticker.C:
+			fmt.Println("Current time: ", t)
+		}
+	}
+}
+
 func ExampleTime_Format() {
 	// Parse a time value from a string in the standard Unix format.
 	t, err := time.Parse(time.UnixDate, "Sat Mar  7 11:06:39 PST 2015")
@@ -113,10 +238,10 @@
 	// value.
 	do("No pad", "<2>", "<7>")
 
-	// An underscore represents a zero pad, if required.
+	// An underscore represents a space pad, if the date only has one digit.
 	do("Spaces", "<_2>", "< 7>")
 
-	// Similarly, a 0 indicates zero padding.
+	// A "0" indicates zero padding for single-digit values.
 	do("Zeros", "<02>", "<07>")
 
 	// If the value is already the right width, padding is not used.
@@ -175,7 +300,7 @@
 }
 
 func ExampleParse() {
-	// See the example for time.Format for a thorough description of how
+	// See the example for Time.Format for a thorough description of how
 	// to define the layout string to parse a time.Time value; Parse and
 	// Format use the same model to describe their input and output.
 
@@ -192,9 +317,25 @@
 	t, _ = time.Parse(shortForm, "2013-Feb-03")
 	fmt.Println(t)
 
+	// Some valid layouts are invalid time values, due to format specifiers
+	// such as _ for space padding and Z for zone information.
+	// For example the RFC3339 layout 2006-01-02T15:04:05Z07:00
+	// contains both Z and a time zone offset in order to handle both valid options:
+	// 2006-01-02T15:04:05Z
+	// 2006-01-02T15:04:05+07:00
+	t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
+	fmt.Println(t)
+	t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
+	fmt.Println(t)
+	_, err := time.Parse(time.RFC3339, time.RFC3339)
+	fmt.Println("error", err) // Returns an error as the layout is not a valid time value
+
 	// Output:
 	// 2013-02-03 19:54:00 -0800 PST
 	// 2013-02-03 00:00:00 +0000 UTC
+	// 2006-01-02 15:04:05 +0000 UTC
+	// 2006-01-02 15:04:05 +0700 +0700
+	// error parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00
 }
 
 func ExampleParseInLocation() {
@@ -214,6 +355,24 @@
 	// 2012-07-09 00:00:00 +0200 CEST
 }
 
+func ExampleTime_Unix() {
+	// 1 billion seconds of Unix, three ways.
+	fmt.Println(time.Unix(1e9, 0).UTC())     // 1e9 seconds
+	fmt.Println(time.Unix(0, 1e18).UTC())    // 1e18 nanoseconds
+	fmt.Println(time.Unix(2e9, -1e18).UTC()) // 2e9 seconds - 1e18 nanoseconds
+
+	t := time.Date(2001, time.September, 9, 1, 46, 40, 0, time.UTC)
+	fmt.Println(t.Unix())     // seconds since 1970
+	fmt.Println(t.UnixNano()) // nanoseconds since 1970
+
+	// Output:
+	// 2001-09-09 01:46:40 +0000 UTC
+	// 2001-09-09 01:46:40 +0000 UTC
+	// 2001-09-09 01:46:40 +0000 UTC
+	// 1000000000
+	// 1000000000000000000
+}
+
 func ExampleTime_Round() {
 	t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
 	round := []time.Duration{
@@ -269,3 +428,173 @@
 	// t.Truncate( 1m0s) = 12:15:00
 	// t.Truncate(10m0s) = 12:10:00
 }
+
+func ExampleLocation() {
+	// China doesn't have daylight saving. It uses a fixed 8 hour offset from UTC.
+	secondsEastOfUTC := int((8 * time.Hour).Seconds())
+	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
+
+	// If the system has a timezone database present, it's possible to load a location
+	// from that, e.g.:
+	//    newYork, err := time.LoadLocation("America/New_York")
+
+	// Creating a time requires a location. Common locations are time.Local and time.UTC.
+	timeInUTC := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
+	sameTimeInBeijing := time.Date(2009, 1, 1, 20, 0, 0, 0, beijing)
+
+	// Although the UTC clock time is 1200 and the Beijing clock time is 2000, Beijing is
+	// 8 hours ahead so the two dates actually represent the same instant.
+	timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)
+	fmt.Println(timesAreEqual)
+
+	// Output:
+	// true
+}
+
+func ExampleTime_Add() {
+	start := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
+	afterTenSeconds := start.Add(time.Second * 10)
+	afterTenMinutes := start.Add(time.Minute * 10)
+	afterTenHours := start.Add(time.Hour * 10)
+	afterTenDays := start.Add(time.Hour * 24 * 10)
+
+	fmt.Printf("start = %v\n", start)
+	fmt.Printf("start.Add(time.Second * 10) = %v\n", afterTenSeconds)
+	fmt.Printf("start.Add(time.Minute * 10) = %v\n", afterTenMinutes)
+	fmt.Printf("start.Add(time.Hour * 10) = %v\n", afterTenHours)
+	fmt.Printf("start.Add(time.Hour * 24 * 10) = %v\n", afterTenDays)
+
+	// Output:
+	// start = 2009-01-01 12:00:00 +0000 UTC
+	// start.Add(time.Second * 10) = 2009-01-01 12:00:10 +0000 UTC
+	// start.Add(time.Minute * 10) = 2009-01-01 12:10:00 +0000 UTC
+	// start.Add(time.Hour * 10) = 2009-01-01 22:00:00 +0000 UTC
+	// start.Add(time.Hour * 24 * 10) = 2009-01-11 12:00:00 +0000 UTC
+}
+
+func ExampleTime_AddDate() {
+	start := time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
+	oneDayLater := start.AddDate(0, 0, 1)
+	oneMonthLater := start.AddDate(0, 1, 0)
+	oneYearLater := start.AddDate(1, 0, 0)
+
+	fmt.Printf("oneDayLater: start.AddDate(0, 0, 1) = %v\n", oneDayLater)
+	fmt.Printf("oneMonthLater: start.AddDate(0, 1, 0) = %v\n", oneMonthLater)
+	fmt.Printf("oneYearLater: start.AddDate(1, 0, 0) = %v\n", oneYearLater)
+
+	// Output:
+	// oneDayLater: start.AddDate(0, 0, 1) = 2009-01-02 00:00:00 +0000 UTC
+	// oneMonthLater: start.AddDate(0, 1, 0) = 2009-02-01 00:00:00 +0000 UTC
+	// oneYearLater: start.AddDate(1, 0, 0) = 2010-01-01 00:00:00 +0000 UTC
+}
+
+func ExampleTime_After() {
+	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
+	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)
+
+	isYear3000AfterYear2000 := year3000.After(year2000) // True
+	isYear2000AfterYear3000 := year2000.After(year3000) // False
+
+	fmt.Printf("year3000.After(year2000) = %v\n", isYear3000AfterYear2000)
+	fmt.Printf("year2000.After(year3000) = %v\n", isYear2000AfterYear3000)
+
+	// Output:
+	// year3000.After(year2000) = true
+	// year2000.After(year3000) = false
+}
+
+func ExampleTime_Before() {
+	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
+	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)
+
+	isYear2000BeforeYear3000 := year2000.Before(year3000) // True
+	isYear3000BeforeYear2000 := year3000.Before(year2000) // False
+
+	fmt.Printf("year2000.Before(year3000) = %v\n", isYear2000BeforeYear3000)
+	fmt.Printf("year3000.Before(year2000) = %v\n", isYear3000BeforeYear2000)
+
+	// Output:
+	// year2000.Before(year3000) = true
+	// year3000.Before(year2000) = false
+}
+
+func ExampleTime_Date() {
+	d := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
+	year, month, day := d.Date()
+
+	fmt.Printf("year = %v\n", year)
+	fmt.Printf("month = %v\n", month)
+	fmt.Printf("day = %v\n", day)
+
+	// Output:
+	// year = 2000
+	// month = February
+	// day = 1
+}
+
+func ExampleTime_Day() {
+	d := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
+	day := d.Day()
+
+	fmt.Printf("day = %v\n", day)
+
+	// Output:
+	// day = 1
+}
+
+func ExampleTime_Equal() {
+	secondsEastOfUTC := int((8 * time.Hour).Seconds())
+	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
+
+	// Unlike the equal operator, Equal is aware that d1 and d2 are the
+	// same instant but in different time zones.
+	d1 := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
+	d2 := time.Date(2000, 2, 1, 20, 30, 0, 0, beijing)
+
+	datesEqualUsingEqualOperator := d1 == d2
+	datesEqualUsingFunction := d1.Equal(d2)
+
+	fmt.Printf("datesEqualUsingEqualOperator = %v\n", datesEqualUsingEqualOperator)
+	fmt.Printf("datesEqualUsingFunction = %v\n", datesEqualUsingFunction)
+
+	// Output:
+	// datesEqualUsingEqualOperator = false
+	// datesEqualUsingFunction = true
+}
+
+func ExampleTime_String() {
+	timeWithNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 15, time.UTC)
+	withNanoseconds := timeWithNanoseconds.String()
+
+	timeWithoutNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 0, time.UTC)
+	withoutNanoseconds := timeWithoutNanoseconds.String()
+
+	fmt.Printf("withNanoseconds = %v\n", string(withNanoseconds))
+	fmt.Printf("withoutNanoseconds = %v\n", string(withoutNanoseconds))
+
+	// Output:
+	// withNanoseconds = 2000-02-01 12:13:14.000000015 +0000 UTC
+	// withoutNanoseconds = 2000-02-01 12:13:14 +0000 UTC
+}
+
+func ExampleTime_Sub() {
+	start := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
+	end := time.Date(2000, 1, 1, 12, 0, 0, 0, time.UTC)
+
+	difference := end.Sub(start)
+	fmt.Printf("difference = %v\n", difference)
+
+	// Output:
+	// difference = 12h0m0s
+}
+
+func ExampleTime_AppendFormat() {
+	t := time.Date(2017, time.November, 4, 11, 0, 0, 0, time.UTC)
+	text := []byte("Time: ")
+
+	text = t.AppendFormat(text, time.Kitchen)
+	fmt.Println(string(text))
+
+	// Output:
+	// Time: 11:00AM
+}
diff --git a/src/time/export_android_test.go b/src/time/export_android_test.go
index fa6a058..f80e7da 100644
--- a/src/time/export_android_test.go
+++ b/src/time/export_android_test.go
@@ -5,8 +5,8 @@
 package time
 
 func ForceAndroidTzdataForTest(tzdata bool) {
-	tzdataPaths = origTzdataPaths
+	forceZipFileForTesting(false)
 	if tzdata {
-		tzdataPaths = tzdataPaths[:1]
+		zoneSources = zoneSources[:len(zoneSources)-1]
 	}
 }
diff --git a/src/time/export_test.go b/src/time/export_test.go
index 4c08ab1..ae24ceb 100644
--- a/src/time/export_test.go
+++ b/src/time/export_test.go
@@ -34,4 +34,5 @@
 	GetMono                = (*Time).mono
 	ErrLocation            = errLocation
 	ReadFile               = readFile
+	LoadTzinfo             = loadTzinfo
 )
diff --git a/src/time/export_windows_test.go b/src/time/export_windows_test.go
index 6fd4509..cc9d6dd 100644
--- a/src/time/export_windows_test.go
+++ b/src/time/export_windows_test.go
@@ -4,9 +4,14 @@
 
 package time
 
-func ForceAusForTesting() {
+func ForceAusFromTZIForTesting() {
 	ResetLocalOnceForTest()
-	localOnce.Do(initAusTestingZone)
+	localOnce.Do(func() { initLocalFromTZI(&aus) })
+}
+
+func ForceUSPacificFromTZIForTesting() {
+	ResetLocalOnceForTest()
+	localOnce.Do(func() { initLocalFromTZI(&usPacific) })
 }
 
 func ToEnglishName(stdname, dstname string) (string, error) {
diff --git a/src/time/format.go b/src/time/format.go
index 8c16e87..a60474f 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -6,7 +6,7 @@
 
 import "errors"
 
-// These are predefined layouts for use in Time.Format and Time.Parse.
+// 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,
@@ -18,6 +18,9 @@
 // reference time looks like so that the Format and Parse methods can apply
 // the same transformation to a general time value.
 //
+// Some valid layouts are invalid time values for time.Parse, due to formats
+// such as _ for space padding and Z for zone information.
+//
 // 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.
@@ -49,7 +52,7 @@
 // time is echoed verbatim during Format and expected to appear verbatim
 // in the input to Parse.
 //
-// The executable example for time.Format demonstrates the working
+// The executable example for Time.Format demonstrates the working
 // of the layout string in detail and is a good reference.
 //
 // Note that the RFC822, RFC850, and RFC1123 formats should be applied
@@ -58,7 +61,7 @@
 // use of "GMT" in that case.
 // In general RFC1123Z should be used instead of RFC1123 for servers
 // that insist on that format, and RFC3339 should be preferred for new protocols.
-// RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
+// RFC3339, RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
 // when used with time.Parse they do not accept all the time formats
 // permitted by the RFCs.
 // The RFC3339Nano format removes trailing zeros from the seconds field
@@ -289,7 +292,6 @@
 }
 
 var shortMonthNames = []string{
-	"---",
 	"Jan",
 	"Feb",
 	"Mar",
@@ -305,7 +307,6 @@
 }
 
 var longMonthNames = []string{
-	"---",
 	"January",
 	"February",
 	"March",
@@ -732,7 +733,7 @@
 }
 
 // Parse parses a formatted string and returns the time value it represents.
-// The layout  defines the format by showing how the reference time,
+// 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
@@ -743,7 +744,7 @@
 // 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.
-// Also, the executable example for time.Format demonstrates the working
+// Also, the executable example for Time.Format demonstrates the working
 // of the layout string in detail and is a good reference.
 //
 // Elements omitted from the value are assumed to be zero or, when
@@ -841,8 +842,10 @@
 			year, err = atoi(p)
 		case stdMonth:
 			month, value, err = lookup(shortMonthNames, value)
+			month++
 		case stdLongMonth:
 			month, value, err = lookup(longMonthNames, value)
+			month++
 		case stdNumMonth, stdZeroMonth:
 			month, value, err = getnum(value, std == stdZeroMonth)
 			if month <= 0 || 12 < month {
@@ -1071,7 +1074,7 @@
 		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.unixSec())
+		offset, ok := local.lookupName(zoneName, t.unixSec())
 		if ok {
 			t.addSec(-int64(offset))
 			t.setLoc(local)
diff --git a/src/time/format_test.go b/src/time/format_test.go
index 710de59..6d27f46 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -465,6 +465,9 @@
 	{RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`},
 	// invalid second followed by optional fractional seconds
 	{RFC3339, "2010-02-04T21:00:67.012345678-08:00", "second out of range"},
+	// issue 21113
+	{"_2 Jan 06 15:04 MST", "4 --- 00 00:00 GMT", "cannot parse"},
+	{"_2 January 06 15:04 MST", "4 --- 00 00:00 GMT", "cannot parse"},
 }
 
 func TestParseErrors(t *testing.T) {
diff --git a/src/time/genzabbrs.go b/src/time/genzabbrs.go
index 824a67f..e062cc2 100644
--- a/src/time/genzabbrs.go
+++ b/src/time/genzabbrs.go
@@ -52,12 +52,6 @@
 	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 {
@@ -70,7 +64,7 @@
 	Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"`
 }
 
-func readWindowsZones() (zones, error) {
+func readWindowsZones() ([]*zone, error) {
 	r, err := http.Get(wzURL)
 	if err != nil {
 		return nil, err
@@ -87,7 +81,7 @@
 	if err != nil {
 		return nil, err
 	}
-	zs := make(zones, 0)
+	zs := make([]*zone, 0)
 	for _, z := range sd.Zones {
 		if z.Territory != "001" {
 			// to avoid dups. I don't know why.
@@ -114,10 +108,12 @@
 	if err != nil {
 		log.Fatal(err)
 	}
-	sort.Sort(zs)
+	sort.Slice(zs, func(i, j int) bool {
+		return zs[i].UnixName < zs[j].UnixName
+	})
 	var v = struct {
 		URL string
-		Zs  zones
+		Zs  []*zone
 	}{
 		wzURL,
 		zs,
diff --git a/src/time/internal_test.go b/src/time/internal_test.go
index edd523b..76d5524 100644
--- a/src/time/internal_test.go
+++ b/src/time/internal_test.go
@@ -9,6 +9,25 @@
 	ForceUSPacificForTesting()
 }
 
+func initTestingZone() {
+	z, err := loadLocation("America/Los_Angeles", zoneSources[len(zoneSources)-1:])
+	if err != nil {
+		panic("cannot load America/Los_Angeles for testing: " + err.Error())
+	}
+	z.name = "Local"
+	localLoc = *z
+}
+
+var OrigZoneSources = zoneSources
+
+func forceZipFileForTesting(zipOnly bool) {
+	zoneSources = make([]string, len(OrigZoneSources))
+	copy(zoneSources, OrigZoneSources)
+	if zipOnly {
+		zoneSources = zoneSources[len(zoneSources)-1:]
+	}
+}
+
 var Interrupt = interrupt
 var DaysIn = daysIn
 
diff --git a/src/time/sleep.go b/src/time/sleep.go
index 4b01404..b8c81b4 100644
--- a/src/time/sleep.go
+++ b/src/time/sleep.go
@@ -14,7 +14,9 @@
 // Interface to timers implemented in package runtime.
 // Must be in sync with ../runtime/time.go:/^type timer
 type runtimeTimer struct {
-	i      int
+	tb uintptr
+	i  int
+
 	when   int64
 	period int64
 	f      func(interface{}, uintptr) // NOTE: must not be closure
diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go
index 9b4a3cc..9af39c0 100644
--- a/src/time/sleep_test.go
+++ b/src/time/sleep_test.go
@@ -82,21 +82,36 @@
 }
 
 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()
 
+	// Create equal number of garbage timers on each P before starting
+	// the benchmark.
+	var wg sync.WaitGroup
+	garbageAll := make([][]*Timer, runtime.GOMAXPROCS(0))
+	for i := range garbageAll {
+		wg.Add(1)
+		go func(i int) {
+			defer wg.Done()
+			garbage := make([]*Timer, 1<<15)
+			for j := range garbage {
+				garbage[j] = AfterFunc(Hour, nil)
+			}
+			garbageAll[i] = garbage
+		}(i)
+	}
+	wg.Wait()
+
+	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()
+
+	for _, garbage := range garbageAll {
+		for _, t := range garbage {
+			t.Stop()
+		}
 	}
 }
 
@@ -158,6 +173,30 @@
 	})
 }
 
+func BenchmarkReset(b *testing.B) {
+	benchmark(b, func(n int) {
+		t := NewTimer(Hour)
+		for i := 0; i < n; i++ {
+			t.Reset(Hour)
+		}
+		t.Stop()
+	})
+}
+
+func BenchmarkSleep(b *testing.B) {
+	benchmark(b, func(n int) {
+		var wg sync.WaitGroup
+		wg.Add(n)
+		for i := 0; i < n; i++ {
+			go func() {
+				Sleep(Nanosecond)
+				wg.Done()
+			}()
+		}
+		wg.Wait()
+	})
+}
+
 func TestAfter(t *testing.T) {
 	const delay = 100 * Millisecond
 	start := Now()
diff --git a/src/time/sys_plan9.go b/src/time/sys_plan9.go
index 9086a6e..b7fba08 100644
--- a/src/time/sys_plan9.go
+++ b/src/time/sys_plan9.go
@@ -16,36 +16,6 @@
 	// cannot predict pid, don't want to kill group
 }
 
-// readFile reads and returns the content of the named file.
-// It is a trivial implementation of ioutil.ReadFile, reimplemented
-// here to avoid depending on io/ioutil or os.
-// It returns an error if name exceeds maxFileSize bytes.
-func readFile(name string) ([]byte, error) {
-	f, err := syscall.Open(name, syscall.O_RDONLY)
-	if err != nil {
-		return nil, err
-	}
-	defer syscall.Close(f)
-	var (
-		buf [4096]byte
-		ret []byte
-		n   int
-	)
-	for {
-		n, err = syscall.Read(f, buf[:])
-		if n > 0 {
-			ret = append(ret, buf[:n]...)
-		}
-		if n == 0 || err != nil {
-			break
-		}
-		if len(ret) > maxFileSize {
-			return nil, fileSizeError(name)
-		}
-	}
-	return ret, err
-}
-
 func open(name string) (uintptr, error) {
 	fd, err := syscall.Open(name, syscall.O_RDONLY)
 	if err != nil {
@@ -54,6 +24,10 @@
 	return uintptr(fd), nil
 }
 
+func read(fd uintptr, buf []byte) (int, error) {
+	return syscall.Read(int(fd), buf)
+}
+
 func closefd(fd uintptr) {
 	syscall.Close(int(fd))
 }
diff --git a/src/time/sys_unix.go b/src/time/sys_unix.go
index d4db8f9..0ef597f 100644
--- a/src/time/sys_unix.go
+++ b/src/time/sys_unix.go
@@ -16,36 +16,6 @@
 	syscall.Kill(syscall.Getpid(), syscall.SIGCHLD)
 }
 
-// readFile reads and returns the content of the named file.
-// It is a trivial implementation of ioutil.ReadFile, reimplemented
-// here to avoid depending on io/ioutil or os.
-// It returns an error if name exceeds maxFileSize bytes.
-func readFile(name string) ([]byte, error) {
-	f, err := syscall.Open(name, syscall.O_RDONLY, 0)
-	if err != nil {
-		return nil, err
-	}
-	defer syscall.Close(f)
-	var (
-		buf [4096]byte
-		ret []byte
-		n   int
-	)
-	for {
-		n, err = syscall.Read(f, buf[:])
-		if n > 0 {
-			ret = append(ret, buf[:n]...)
-		}
-		if n == 0 || err != nil {
-			break
-		}
-		if len(ret) > maxFileSize {
-			return nil, fileSizeError(name)
-		}
-	}
-	return ret, err
-}
-
 func open(name string) (uintptr, error) {
 	fd, err := syscall.Open(name, syscall.O_RDONLY, 0)
 	if err != nil {
@@ -54,6 +24,10 @@
 	return uintptr(fd), nil
 }
 
+func read(fd uintptr, buf []byte) (int, error) {
+	return syscall.Read(int(fd), buf)
+}
+
 func closefd(fd uintptr) {
 	syscall.Close(int(fd))
 }
@@ -78,5 +52,3 @@
 	}
 	return nil
 }
-
-func isNotExist(err error) bool { return err == syscall.ENOENT }
diff --git a/src/time/sys_windows.go b/src/time/sys_windows.go
index 9e38165..481aea5 100644
--- a/src/time/sys_windows.go
+++ b/src/time/sys_windows.go
@@ -13,36 +13,6 @@
 func interrupt() {
 }
 
-// readFile reads and returns the content of the named file.
-// It is a trivial implementation of ioutil.ReadFile, reimplemented
-// here to avoid depending on io/ioutil or os.
-// It returns an error if name exceeds maxFileSize bytes.
-func readFile(name string) ([]byte, error) {
-	f, err := syscall.Open(name, syscall.O_RDONLY, 0)
-	if err != nil {
-		return nil, err
-	}
-	defer syscall.Close(f)
-	var (
-		buf [4096]byte
-		ret []byte
-		n   int
-	)
-	for {
-		n, err = syscall.Read(f, buf[:])
-		if n > 0 {
-			ret = append(ret, buf[:n]...)
-		}
-		if n == 0 || err != nil {
-			break
-		}
-		if len(ret) > maxFileSize {
-			return nil, fileSizeError(name)
-		}
-	}
-	return ret, err
-}
-
 func open(name string) (uintptr, error) {
 	fd, err := syscall.Open(name, syscall.O_RDONLY, 0)
 	if err != nil {
@@ -51,6 +21,10 @@
 	return uintptr(fd), nil
 }
 
+func read(fd uintptr, buf []byte) (int, error) {
+	return syscall.Read(syscall.Handle(fd), buf)
+}
+
 func closefd(fd uintptr) {
 	syscall.Close(syscall.Handle(fd))
 }
diff --git a/src/time/tick_test.go b/src/time/tick_test.go
index 2ab77f6..dd17aab 100644
--- a/src/time/tick_test.go
+++ b/src/time/tick_test.go
@@ -35,6 +35,13 @@
 	}
 }
 
+// Issue 21874
+func TestTickerStopWithDirectInitialization(t *testing.T) {
+	c := make(chan Time)
+	tk := &Ticker{C: c}
+	tk.Stop()
+}
+
 // Test that a bug tearing down a ticker has been fixed. This routine should not deadlock.
 func TestTeardown(t *testing.T) {
 	Delta := 100 * Millisecond
@@ -67,12 +74,11 @@
 }
 
 func BenchmarkTicker(b *testing.B) {
-	ticker := NewTicker(1)
-	b.ResetTimer()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		<-ticker.C
-	}
-	b.StopTimer()
-	ticker.Stop()
+	benchmark(b, func(n int) {
+		ticker := NewTicker(Nanosecond)
+		for i := 0; i < n; i++ {
+			<-ticker.C
+		}
+		ticker.Stop()
+	})
 }
diff --git a/src/time/time.go b/src/time/time.go
index 8a29eef..9390968 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -98,6 +98,11 @@
 // change the instant in time being denoted and therefore does not affect the
 // computations described in earlier paragraphs.
 //
+// In addition to the required “wall clock” reading, a Time may contain an optional
+// reading of the current process's monotonic clock, to provide additional precision
+// for comparison or subtraction.
+// See the “Monotonic Clocks” section in the package documentation for details.
+//
 // Note that the Go == operator compares not just the time instant but also the
 // Location and the monotonic clock reading. Therefore, Time values should not
 // be used as map or database keys without first guaranteeing that the
@@ -108,11 +113,6 @@
 // correctly handles the case when only one of its arguments has a monotonic
 // clock reading.
 //
-// In addition to the required “wall clock” reading, a Time may contain an optional
-// reading of the current process's monotonic clock, to provide additional precision
-// for comparison or subtraction.
-// See the “Monotonic Clocks” section in the package documentation for details.
-//
 type Time struct {
 	// wall and ext encode the wall time seconds, wall time nanoseconds,
 	// and optional monotonic clock reading in nanoseconds.
@@ -722,7 +722,7 @@
 }
 
 // fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
-// tail of buf, omitting trailing zeros. it omits the decimal
+// 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) {
@@ -1383,7 +1383,7 @@
 }
 
 // Truncate returns the result of rounding t down to a multiple of d (since the zero time).
-// If d <= 0, Truncate returns t unchanged.
+// If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged.
 //
 // Truncate operates on the time as an absolute duration since the
 // zero time; it does not operate on the presentation form of the
@@ -1400,7 +1400,7 @@
 
 // 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.
+// If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged.
 //
 // Round operates on the time as an absolute duration since the
 // zero time; it does not operate on the presentation form of the
diff --git a/src/time/time_test.go b/src/time/time_test.go
index dba8e0d..fd464c0 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -575,6 +575,7 @@
 	{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
+	{2012, 12, 24, 0, 0, 0, 0, Local, 1356336000},  // Leap year
 
 	// 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
@@ -1202,8 +1203,8 @@
 }
 
 func TestDefaultLoc(t *testing.T) {
-	//This test verifyes that all Time's methods behaves identical if loc is set
-	//as nil or UTC
+	// Verify that all of Time's methods behave identically if loc is set to
+	// nil or UTC.
 	for _, tt := range defaultLocTests {
 		t1 := Time{}
 		t2 := Time{}.UTC()
diff --git a/src/time/zoneinfo.go b/src/time/zoneinfo.go
index f4d4df9..96ff8d3 100644
--- a/src/time/zoneinfo.go
+++ b/src/time/zoneinfo.go
@@ -223,7 +223,7 @@
 // lookupName returns information about the time zone with
 // the given name (such as "EST") at the given pseudo-Unix time
 // (what the given time of day would be in UTC).
-func (l *Location) lookupName(name string, unix int64) (offset int, isDST bool, ok bool) {
+func (l *Location) lookupName(name string, unix int64) (offset int, ok bool) {
 	l = l.get()
 
 	// First try for a zone with the right name that was actually
@@ -235,9 +235,9 @@
 	for i := range l.zone {
 		zone := &l.zone[i]
 		if zone.name == name {
-			nam, offset, isDST, _, _ := l.lookup(unix - int64(zone.offset))
+			nam, offset, _, _, _ := l.lookup(unix - int64(zone.offset))
 			if nam == zone.name {
-				return offset, isDST, true
+				return offset, true
 			}
 		}
 	}
@@ -246,7 +246,7 @@
 	for i := range l.zone {
 		zone := &l.zone[i]
 		if zone.name == name {
-			return zone.offset, zone.isDST, true
+			return zone.offset, true
 		}
 	}
 
@@ -292,13 +292,14 @@
 		env, _ := syscall.Getenv("ZONEINFO")
 		zoneinfo = &env
 	})
-	if zoneinfo != nil && *zoneinfo != "" {
-		if z, err := loadZoneFile(*zoneinfo, name); err == nil {
-			z.name = name
-			return z, nil
+	if *zoneinfo != "" {
+		if zoneData, err := loadTzinfoFromDirOrZip(*zoneinfo, name); err == nil {
+			if z, err := LoadLocationFromTZData(name, zoneData); err == nil {
+				return z, nil
+			}
 		}
 	}
-	return loadLocation(name)
+	return loadLocation(name, zoneSources)
 }
 
 // containsDotDot reports whether s contains "..".
diff --git a/src/time/zoneinfo_android.go b/src/time/zoneinfo_android.go
index 695a8ad..65e0975 100644
--- a/src/time/zoneinfo_android.go
+++ b/src/time/zoneinfo_android.go
@@ -13,62 +13,22 @@
 	"runtime"
 )
 
-var tzdataPaths = []string{
+var zoneSources = []string{
 	"/system/usr/share/zoneinfo/tzdata",
 	"/data/misc/zoneinfo/current/tzdata",
 	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
 }
 
-var origTzdataPaths = tzdataPaths
-
-func forceZipFileForTesting(zipOnly bool) {
-	tzdataPaths = make([]string, len(origTzdataPaths))
-	copy(tzdataPaths, origTzdataPaths)
-	if zipOnly {
-		for i := 0; i < len(tzdataPaths)-1; i++ {
-			tzdataPaths[i] = "/XXXNOEXIST"
-		}
-	}
-}
-
-func initTestingZone() {
-	z, err := loadLocation("America/Los_Angeles")
-	if err != nil {
-		panic("cannot load America/Los_Angeles for testing: " + err.Error())
-	}
-	z.name = "Local"
-	localLoc = *z
-}
-
 func initLocal() {
 	// TODO(elias.naur): getprop persist.sys.timezone
 	localLoc = *UTC
 }
 
-func loadLocation(name string) (*Location, error) {
-	var firstErr error
-	for _, path := range tzdataPaths {
-		var z *Location
-		var err error
-		if len(path) > 4 && path[len(path)-4:] == ".zip" {
-			z, err = loadZoneZip(path, name)
-		} else {
-			z, err = loadTzdataFile(path, name)
-		}
-		if err == nil {
-			z.name = name
-			return z, nil
-		} else if firstErr == nil && !isNotExist(err) {
-			firstErr = err
-		}
-	}
-	if firstErr != nil {
-		return nil, firstErr
-	}
-	return nil, errors.New("unknown time zone " + name)
+func init() {
+	loadTzinfoFromTzdata = androidLoadTzinfoFromTzdata
 }
 
-func loadTzdataFile(file, name string) (*Location, error) {
+func androidLoadTzinfoFromTzdata(file, name string) ([]byte, error) {
 	const (
 		headersize = 12 + 3*4
 		namesize   = 40
@@ -87,11 +47,11 @@
 	if err := preadn(fd, buf, 0); err != nil {
 		return nil, errors.New("corrupt tzdata file " + file)
 	}
-	d := data{buf, false}
+	d := dataIO{buf, false}
 	if magic := d.read(6); string(magic) != "tzdata" {
 		return nil, errors.New("corrupt tzdata file " + file)
 	}
-	d = data{buf[12:], false}
+	d = dataIO{buf[12:], false}
 	indexOff, _ := d.big4()
 	dataOff, _ := d.big4()
 	indexSize := dataOff - indexOff
@@ -106,14 +66,14 @@
 		if string(entry[:len(name)]) != name {
 			continue
 		}
-		d := data{entry[namesize:], false}
+		d := dataIO{entry[namesize:], false}
 		off, _ := d.big4()
 		size, _ := d.big4()
 		buf := make([]byte, size)
 		if err := preadn(fd, buf, int(off+dataOff)); err != nil {
 			return nil, errors.New("corrupt tzdata file " + file)
 		}
-		return loadZoneData(buf)
+		return buf, nil
 	}
 	return nil, errors.New("cannot find " + name + " in tzdata file " + file)
 }
diff --git a/src/time/zoneinfo_ios.go b/src/time/zoneinfo_ios.go
index f09166c..6d7f975 100644
--- a/src/time/zoneinfo_ios.go
+++ b/src/time/zoneinfo_ios.go
@@ -9,43 +9,23 @@
 
 import "syscall"
 
-var zoneFile string
+var zoneSources = []string{
+	getZipParent() + "/zoneinfo.zip",
+}
 
-func init() {
+func getZipParent() string {
 	wd, err := syscall.Getwd()
 	if err != nil {
-		return
+		return "/XXXNOEXIST"
 	}
 
 	// The working directory at initialization is the root of the
 	// app bundle: "/private/.../bundlename.app". That's where we
 	// keep zoneinfo.zip.
-	zoneFile = wd + "/zoneinfo.zip"
-}
-
-func forceZipFileForTesting(zipOnly bool) {
-	// On iOS we only have the zip file.
-}
-
-func initTestingZone() {
-	z, err := loadZoneFile(zoneFile, "America/Los_Angeles")
-	if err != nil {
-		panic("cannot load America/Los_Angeles for testing: " + err.Error())
-	}
-	z.name = "Local"
-	localLoc = *z
+	return wd
 }
 
 func initLocal() {
 	// TODO(crawshaw): [NSTimeZone localTimeZone]
 	localLoc = *UTC
 }
-
-func loadLocation(name string) (*Location, error) {
-	z, err := loadZoneFile(zoneFile, name)
-	if err != nil {
-		return nil, err
-	}
-	z.name = name
-	return z, nil
-}
diff --git a/src/time/zoneinfo_plan9.go b/src/time/zoneinfo_plan9.go
index 26637a1..4ae718c 100644
--- a/src/time/zoneinfo_plan9.go
+++ b/src/time/zoneinfo_plan9.go
@@ -11,6 +11,10 @@
 	"syscall"
 )
 
+var zoneSources = []string{
+	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
+}
+
 func isSpace(r rune) bool {
 	return r == ' ' || r == '\t' || r == '\n'
 }
@@ -118,15 +122,6 @@
 	return loadZoneDataPlan9(string(b))
 }
 
-func initTestingZone() {
-	z, err := loadLocation("America/Los_Angeles")
-	if err != nil {
-		panic("cannot load America/Los_Angeles for testing: " + err.Error())
-	}
-	z.name = "Local"
-	localLoc = *z
-}
-
 func initLocal() {
 	t, ok := syscall.Getenv("timezone")
 	if ok {
@@ -145,16 +140,3 @@
 	// Fall back to UTC.
 	localLoc.name = "UTC"
 }
-
-func loadLocation(name string) (*Location, error) {
-	z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", name)
-	if err != nil {
-		return nil, err
-	}
-	z.name = name
-	return z, nil
-}
-
-func forceZipFileForTesting(zipOnly bool) {
-	// We only use the zip file anyway.
-}
diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
index b0cd9da..839b37a 100644
--- a/src/time/zoneinfo_read.go
+++ b/src/time/zoneinfo_read.go
@@ -9,7 +9,10 @@
 
 package time
 
-import "errors"
+import (
+	"errors"
+	"syscall"
+)
 
 // maxFileSize is the max permitted size of files read by readFile.
 // As reference, the zoneinfo.zip distributed by Go is ~350 KB,
@@ -30,12 +33,12 @@
 )
 
 // Simple I/O interface to binary blob of data.
-type data struct {
+type dataIO struct {
 	p     []byte
 	error bool
 }
 
-func (d *data) read(n int) []byte {
+func (d *dataIO) read(n int) []byte {
 	if len(d.p) < n {
 		d.p = nil
 		d.error = true
@@ -46,7 +49,7 @@
 	return p
 }
 
-func (d *data) big4() (n uint32, ok bool) {
+func (d *dataIO) big4() (n uint32, ok bool) {
 	p := d.read(4)
 	if len(p) < 4 {
 		d.error = true
@@ -55,7 +58,7 @@
 	return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true
 }
 
-func (d *data) byte() (n byte, ok bool) {
+func (d *dataIO) byte() (n byte, ok bool) {
 	p := d.read(1)
 	if len(p) < 1 {
 		d.error = true
@@ -76,8 +79,12 @@
 
 var badData = errors.New("malformed time zone information")
 
-func loadZoneData(bytes []byte) (l *Location, err error) {
-	d := data{bytes, false}
+// LoadLocationFromTZData returns a Location with the given name
+// initialized from the IANA Time Zone database-formatted data.
+// The data should be in the format of a standard IANA time zone file
+// (for example, the content of /etc/localtime on Unix systems).
+func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+	d := dataIO{data, false}
 
 	// 4-byte magic "TZif"
 	if magic := d.read(4); string(magic) != "TZif" {
@@ -115,13 +122,13 @@
 	}
 
 	// Transition times.
-	txtimes := data{d.read(n[NTime] * 4), false}
+	txtimes := dataIO{d.read(n[NTime] * 4), false}
 
 	// Time zone indices for transition times.
 	txzones := d.read(n[NTime])
 
 	// Zone info structures
-	zonedata := data{d.read(n[NZone] * 6), false}
+	zonedata := dataIO{d.read(n[NZone] * 6), false}
 
 	// Time zone abbreviations.
 	abbrev := d.read(n[NChar])
@@ -195,7 +202,7 @@
 	}
 
 	// Committed to succeed.
-	l = &Location{zone: zone, tx: tx}
+	l := &Location{zone: zone, tx: tx, name: name}
 
 	// Fill in the cache with information about right now,
 	// since that will be the most common lookup.
@@ -214,18 +221,16 @@
 	return l, nil
 }
 
-func loadZoneFile(dir, name string) (l *Location, err error) {
+// loadTzinfoFromDirOrZip returns the contents of the file with the given name
+// in dir. dir can either be an uncompressed zip file, or a directory.
+func loadTzinfoFromDirOrZip(dir, name string) ([]byte, error) {
 	if len(dir) > 4 && dir[len(dir)-4:] == ".zip" {
-		return loadZoneZip(dir, name)
+		return loadTzinfoFromZip(dir, name)
 	}
 	if dir != "" {
 		name = dir + "/" + name
 	}
-	buf, err := readFile(name)
-	if err != nil {
-		return
-	}
-	return loadZoneData(buf)
+	return readFile(name)
 }
 
 // There are 500+ zoneinfo files. Rather than distribute them all
@@ -252,7 +257,9 @@
 	return int(b[0]) | int(b[1])<<8
 }
 
-func loadZoneZip(zipfile, name string) (l *Location, err error) {
+// loadTzinfoFromZip returns the contents of the file with the given name
+// in the given uncompressed zip file.
+func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
 	fd, err := open(zipfile)
 	if err != nil {
 		return nil, errors.New("open " + zipfile + ": " + err.Error())
@@ -354,8 +361,76 @@
 			return nil, errors.New("corrupt zip file " + zipfile)
 		}
 
-		return loadZoneData(buf)
+		return buf, nil
 	}
 
 	return nil, errors.New("cannot find " + name + " in zip file " + zipfile)
 }
+
+// loadTzinfoFromTzdata returns the time zone information of the time zone
+// with the given name, from a tzdata database file as they are typically
+// found on android.
+var loadTzinfoFromTzdata func(file, name string) ([]byte, error)
+
+// loadTzinfo returns the time zone information of the time zone
+// with the given name, from a given source. A source may be a
+// timezone database directory, tzdata database file or an uncompressed
+// zip file, containing the contents of such a directory.
+func loadTzinfo(name string, source string) ([]byte, error) {
+	if len(source) >= 6 && source[len(source)-6:] == "tzdata" {
+		return loadTzinfoFromTzdata(source, name)
+	}
+	return loadTzinfoFromDirOrZip(source, name)
+}
+
+// loadLocation returns the Location with the given name from one of
+// the specified sources. See loadTzinfo for a list of supported sources.
+// The first timezone data matching the given name that is successfully loaded
+// and parsed is returned as a Location.
+func loadLocation(name string, sources []string) (z *Location, firstErr error) {
+	for _, source := range sources {
+		var zoneData, err = loadTzinfo(name, source)
+		if err == nil {
+			if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
+				return z, nil
+			}
+		}
+		if firstErr == nil && err != syscall.ENOENT {
+			firstErr = err
+		}
+	}
+	if firstErr != nil {
+		return nil, firstErr
+	}
+	return nil, errors.New("unknown time zone " + name)
+}
+
+// readFile reads and returns the content of the named file.
+// It is a trivial implementation of ioutil.ReadFile, reimplemented
+// here to avoid depending on io/ioutil or os.
+// It returns an error if name exceeds maxFileSize bytes.
+func readFile(name string) ([]byte, error) {
+	f, err := open(name)
+	if err != nil {
+		return nil, err
+	}
+	defer closefd(f)
+	var (
+		buf [4096]byte
+		ret []byte
+		n   int
+	)
+	for {
+		n, err = read(f, buf[:])
+		if n > 0 {
+			ret = append(ret, buf[:n]...)
+		}
+		if n == 0 || err != nil {
+			break
+		}
+		if len(ret) > maxFileSize {
+			return nil, fileSizeError(name)
+		}
+	}
+	return ret, err
+}
diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
index 452262f..7a55d4f 100644
--- a/src/time/zoneinfo_test.go
+++ b/src/time/zoneinfo_test.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"os"
+	"reflect"
 	"testing"
 	"time"
 )
@@ -116,3 +117,27 @@
 		t.Errorf(`invalid UTC location name: got %q want "UTC"`, time.UTC)
 	}
 }
+
+func TestLoadLocationFromTZData(t *testing.T) {
+	time.ForceZipFileForTesting(true)
+	defer time.ForceZipFileForTesting(false)
+
+	const locationName = "Asia/Jerusalem"
+	reference, err := time.LoadLocation(locationName)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tzinfo, err := time.LoadTzinfo(locationName, time.OrigZoneSources[len(time.OrigZoneSources)-1])
+	if err != nil {
+		t.Fatal(err)
+	}
+	sample, err := time.LoadLocationFromTZData(locationName, tzinfo)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !reflect.DeepEqual(reference, sample) {
+		t.Errorf("return values of LoadLocationFromTZData and LoadLocation don't match")
+	}
+}
diff --git a/src/time/zoneinfo_unix.go b/src/time/zoneinfo_unix.go
index bbf263a..88313aa 100644
--- a/src/time/zoneinfo_unix.go
+++ b/src/time/zoneinfo_unix.go
@@ -12,41 +12,19 @@
 package time
 
 import (
-	"errors"
 	"runtime"
 	"syscall"
 )
 
-func initTestingZone() {
-	z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", "America/Los_Angeles")
-	if err != nil {
-		panic("cannot load America/Los_Angeles for testing: " + err.Error())
-	}
-	z.name = "Local"
-	localLoc = *z
-}
-
 // Many systems use /usr/share/zoneinfo, Solaris 2 has
 // /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
-var zoneDirs = []string{
+var zoneSources = []string{
 	"/usr/share/zoneinfo/",
 	"/usr/share/lib/zoneinfo/",
 	"/usr/lib/locale/TZ/",
 	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
 }
 
-var origZoneDirs = zoneDirs
-
-func forceZipFileForTesting(zipOnly bool) {
-	zoneDirs = make([]string, len(origZoneDirs))
-	copy(zoneDirs, origZoneDirs)
-	if zipOnly {
-		for i := 0; i < len(zoneDirs)-1; i++ {
-			zoneDirs[i] = "/XXXNOEXIST"
-		}
-	}
-}
-
 func initLocal() {
 	// consult $TZ to find the time zone to use.
 	// no $TZ means use the system default /etc/localtime.
@@ -56,14 +34,14 @@
 	tz, ok := syscall.Getenv("TZ")
 	switch {
 	case !ok:
-		z, err := loadZoneFile("", "/etc/localtime")
+		z, err := loadLocation("localtime", []string{"/etc/"})
 		if err == nil {
 			localLoc = *z
 			localLoc.name = "Local"
 			return
 		}
 	case tz != "" && tz != "UTC":
-		if z, err := loadLocation(tz); err == nil {
+		if z, err := loadLocation(tz, zoneSources); err == nil {
 			localLoc = *z
 			return
 		}
@@ -72,19 +50,3 @@
 	// Fall back to UTC.
 	localLoc.name = "UTC"
 }
-
-func loadLocation(name string) (*Location, error) {
-	var firstErr error
-	for _, zoneDir := range zoneDirs {
-		if z, err := loadZoneFile(zoneDir, name); err == nil {
-			z.name = name
-			return z, nil
-		} else if firstErr == nil && !isNotExist(err) {
-			firstErr = err
-		}
-	}
-	if firstErr != nil {
-		return nil, firstErr
-	}
-	return nil, errors.New("unknown time zone " + name)
-}
diff --git a/src/time/zoneinfo_windows.go b/src/time/zoneinfo_windows.go
index c201f4b..2b69d06 100644
--- a/src/time/zoneinfo_windows.go
+++ b/src/time/zoneinfo_windows.go
@@ -11,6 +11,10 @@
 	"syscall"
 )
 
+var zoneSources = []string{
+	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
+}
+
 // TODO(rsc): Fall back to copy of zoneinfo files.
 
 // BUG(brainman,rsc): On Windows, the operating system does not provide complete
@@ -228,14 +232,6 @@
 	DaylightBias: -60,
 }
 
-func initTestingZone() {
-	initLocalFromTZI(&usPacific)
-}
-
-func initAusTestingZone() {
-	initLocalFromTZI(&aus)
-}
-
 func initLocal() {
 	var i syscall.Timezoneinformation
 	if _, err := syscall.GetTimeZoneInformation(&i); err != nil {
@@ -244,16 +240,3 @@
 	}
 	initLocalFromTZI(&i)
 }
-
-func loadLocation(name string) (*Location, error) {
-	z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name)
-	if err != nil {
-		return nil, err
-	}
-	z.name = name
-	return z, nil
-}
-
-func forceZipFileForTesting(zipOnly bool) {
-	// We only use the zip file anyway.
-}
diff --git a/src/time/zoneinfo_windows_test.go b/src/time/zoneinfo_windows_test.go
index cf3b428..d0f2a44 100644
--- a/src/time/zoneinfo_windows_test.go
+++ b/src/time/zoneinfo_windows_test.go
@@ -31,14 +31,14 @@
 	}
 }
 
-func TestLocalZoneAbbr(t *testing.T) {
-	ResetLocalOnceForTest() // reset the Once to trigger the race
+func TestUSPacificZoneAbbr(t *testing.T) {
+	ForceUSPacificFromTZIForTesting() // reset the Once to trigger the race
 	defer ForceUSPacificForTesting()
 	testZoneAbbr(t)
 }
 
 func TestAusZoneAbbr(t *testing.T) {
-	ForceAusForTesting()
+	ForceAusFromTZIForTesting()
 	defer ForceUSPacificForTesting()
 	testZoneAbbr(t)
 }
diff --git a/src/unicode/letter.go b/src/unicode/letter.go
index 90b0b41..4d9fc67 100644
--- a/src/unicode/letter.go
+++ b/src/unicode/letter.go
@@ -97,7 +97,7 @@
 				return false
 			}
 			if r <= range_.Hi {
-				return (r-range_.Lo)%range_.Stride == 0
+				return range_.Stride == 1 || (r-range_.Lo)%range_.Stride == 0
 			}
 		}
 		return false
@@ -110,7 +110,7 @@
 		m := lo + (hi-lo)/2
 		range_ := &ranges[m]
 		if range_.Lo <= r && r <= range_.Hi {
-			return (r-range_.Lo)%range_.Stride == 0
+			return range_.Stride == 1 || (r-range_.Lo)%range_.Stride == 0
 		}
 		if r < range_.Lo {
 			hi = m
@@ -130,7 +130,7 @@
 				return false
 			}
 			if r <= range_.Hi {
-				return (r-range_.Lo)%range_.Stride == 0
+				return range_.Stride == 1 || (r-range_.Lo)%range_.Stride == 0
 			}
 		}
 		return false
@@ -143,7 +143,7 @@
 		m := lo + (hi-lo)/2
 		range_ := ranges[m]
 		if range_.Lo <= r && r <= range_.Hi {
-			return (r-range_.Lo)%range_.Stride == 0
+			return range_.Stride == 1 || (r-range_.Lo)%range_.Stride == 0
 		}
 		if r < range_.Lo {
 			hi = m
diff --git a/src/unicode/maketables.go b/src/unicode/maketables.go
index 42864b4..9a92a01 100644
--- a/src/unicode/maketables.go
+++ b/src/unicode/maketables.go
@@ -41,10 +41,17 @@
 	flushOutput()
 }
 
+func defaultVersion() string {
+	if v := os.Getenv("UNICODE_VERSION"); v != "" {
+		return v
+	}
+	return unicode.Version
+}
+
 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/9.0.0/ucd/",
+	"http://www.unicode.org/Public/"+defaultVersion()+"/ucd/",
 	"URL of Unicode database directory")
 var tablelist = flag.String("tables",
 	"all",
@@ -1125,12 +1132,6 @@
 	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)
@@ -1177,7 +1178,9 @@
 		if orb == nil {
 			continue
 		}
-		sort.Sort(runeSlice(orb))
+		sort.Slice(orb, func(i, j int) bool {
+			return orb[i] < orb[j]
+		})
 		c := orb[len(orb)-1]
 		for _, d := range orb {
 			chars[c].caseOrbit = d
diff --git a/src/unicode/script_test.go b/src/unicode/script_test.go
index 1fe4581..7d760fc 100644
--- a/src/unicode/script_test.go
+++ b/src/unicode/script_test.go
@@ -14,8 +14,13 @@
 	script string
 }
 
-// Hand-chosen tests from Unicode 5.1.0, 6.0.0, 6.2.0, 6.3.0, 7.0.0 and 8.0.0
+// Hand-chosen tests from Unicode 5.1.0, 6.0.0, 6.2.0, 6.3.0, 7.0.0, 8.0.0,
+// 9.0.0, 10.0.0.
 // mostly to discover when new scripts and categories arise.
+// If this tests fails, add the missing scripts to the test and add entries
+// of the form
+//     pkg unicode, var <new script> *RangeTable
+// to api/next.txt.
 var inTest = []T{
 	{0x11711, "Ahom"},
 	{0x1e900, "Adlam"},
@@ -92,6 +97,7 @@
 	{0x0843, "Mandaic"},
 	{0x10ac8, "Manichaean"},
 	{0x11cB6, "Marchen"},
+	{0x11d59, "Masaram_Gondi"},
 	{0xabd0, "Meetei_Mayek"},
 	{0x1e800, "Mende_Kikakui"},
 	{0x1099f, "Meroitic_Hieroglyphs"},
@@ -106,6 +112,7 @@
 	{0x11400, "Newa"},
 	{0x19c3, "New_Tai_Lue"},
 	{0x07f8, "Nko"},
+	{0x1b170, "Nushu"},
 	{0x169b, "Ogham"},
 	{0x1c6a, "Ol_Chiki"},
 	{0x10C80, "Old_Hungarian"},
@@ -134,6 +141,7 @@
 	{0x1D920, "SignWriting"},
 	{0x0dbd, "Sinhala"},
 	{0x110d0, "Sora_Sompeng"},
+	{0x11a99, "Soyombo"},
 	{0x1ba3, "Sundanese"},
 	{0xa803, "Syloti_Nagri"},
 	{0x070f, "Syriac"},
@@ -155,6 +163,7 @@
 	{0xa60e, "Vai"},
 	{0x118ff, "Warang_Citi"},
 	{0xa216, "Yi"},
+	{0x11a0a, "Zanabazar_Square"},
 }
 
 var outTest = []T{ // not really worth being thorough
@@ -229,6 +238,7 @@
 	{0x06DD, "Prepended_Concatenation_Mark"},
 	{0x300D, "Quotation_Mark"},
 	{0x2EF3, "Radical"},
+	{0x1f1ff, "Regional_Indicator"},
 	{0x061F, "STerm"}, // Deprecated alias of Sentence_Terminal
 	{0x061F, "Sentence_Terminal"},
 	{0x2071, "Soft_Dotted"},
diff --git a/src/unicode/tables.go b/src/unicode/tables.go
index 9032336..dd2f70b 100644
--- a/src/unicode/tables.go
+++ b/src/unicode/tables.go
@@ -4,12 +4,12 @@
 
 // Code generated by maketables; DO NOT EDIT.
 // To regenerate, run:
-//	maketables --tables=all --data=http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/9.0.0/ucd/CaseFolding.txt
+//	maketables --tables=all --data=http://www.unicode.org/Public/10.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/10.0.0/ucd/CaseFolding.txt
 
 package unicode
 
 // Version is the Unicode edition from which the tables are derived.
-const Version = "9.0.0"
+const Version = "10.0.0"
 
 // Categories is the set of Unicode category tables.
 var Categories = map[string]*RangeTable{
@@ -172,6 +172,7 @@
 		{0x081a, 0x0824, 10},
 		{0x0828, 0x0840, 24},
 		{0x0841, 0x0858, 1},
+		{0x0860, 0x086a, 1},
 		{0x08a0, 0x08b4, 1},
 		{0x08b6, 0x08bd, 1},
 		{0x0904, 0x0939, 1},
@@ -188,7 +189,8 @@
 		{0x09dc, 0x09dd, 1},
 		{0x09df, 0x09e1, 1},
 		{0x09f0, 0x09f1, 1},
-		{0x0a05, 0x0a0a, 1},
+		{0x09fc, 0x0a05, 9},
+		{0x0a06, 0x0a0a, 1},
 		{0x0a0f, 0x0a10, 1},
 		{0x0a13, 0x0a28, 1},
 		{0x0a2a, 0x0a30, 1},
@@ -403,12 +405,12 @@
 		{0x309d, 0x309f, 1},
 		{0x30a1, 0x30fa, 1},
 		{0x30fc, 0x30ff, 1},
-		{0x3105, 0x312d, 1},
+		{0x3105, 0x312e, 1},
 		{0x3131, 0x318e, 1},
 		{0x31a0, 0x31ba, 1},
 		{0x31f0, 0x31ff, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fd5, 1},
+		{0x4e00, 0x9fea, 1},
 		{0xa000, 0xa48c, 1},
 		{0xa4d0, 0xa4fd, 1},
 		{0xa500, 0xa60c, 1},
@@ -498,7 +500,7 @@
 		{0x10280, 0x1029c, 1},
 		{0x102a0, 0x102d0, 1},
 		{0x10300, 0x1031f, 1},
-		{0x10330, 0x10340, 1},
+		{0x1032d, 0x10340, 1},
 		{0x10342, 0x10349, 1},
 		{0x10350, 0x10375, 1},
 		{0x10380, 0x1039d, 1},
@@ -578,13 +580,21 @@
 		{0x11681, 0x116aa, 1},
 		{0x11700, 0x11719, 1},
 		{0x118a0, 0x118df, 1},
-		{0x118ff, 0x11ac0, 449},
-		{0x11ac1, 0x11af8, 1},
+		{0x118ff, 0x11a00, 257},
+		{0x11a0b, 0x11a32, 1},
+		{0x11a3a, 0x11a50, 22},
+		{0x11a5c, 0x11a83, 1},
+		{0x11a86, 0x11a89, 1},
+		{0x11ac0, 0x11af8, 1},
 		{0x11c00, 0x11c08, 1},
 		{0x11c0a, 0x11c2e, 1},
 		{0x11c40, 0x11c72, 50},
 		{0x11c73, 0x11c8f, 1},
-		{0x12000, 0x12399, 1},
+		{0x11d00, 0x11d06, 1},
+		{0x11d08, 0x11d09, 1},
+		{0x11d0b, 0x11d30, 1},
+		{0x11d46, 0x12000, 698},
+		{0x12001, 0x12399, 1},
 		{0x12480, 0x12543, 1},
 		{0x13000, 0x1342e, 1},
 		{0x14400, 0x14646, 1},
@@ -598,10 +608,11 @@
 		{0x16f00, 0x16f44, 1},
 		{0x16f50, 0x16f93, 67},
 		{0x16f94, 0x16f9f, 1},
-		{0x16fe0, 0x17000, 32},
-		{0x17001, 0x187ec, 1},
+		{0x16fe0, 0x16fe1, 1},
+		{0x17000, 0x187ec, 1},
 		{0x18800, 0x18af2, 1},
-		{0x1b000, 0x1b001, 1},
+		{0x1b000, 0x1b11e, 1},
+		{0x1b170, 0x1b2fb, 1},
 		{0x1bc00, 0x1bc6a, 1},
 		{0x1bc70, 0x1bc7c, 1},
 		{0x1bc80, 0x1bc88, 1},
@@ -666,6 +677,7 @@
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
 		{0x2b820, 0x2cea1, 1},
+		{0x2ceb0, 0x2ebe0, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 	LatinOffset: 6,
@@ -876,7 +888,7 @@
 		{0x16b40, 0x16b40, 1},
 		{0x16b41, 0x16b43, 1},
 		{0x16f93, 0x16f9f, 1},
-		{0x16fe0, 0x16fe0, 1},
+		{0x16fe0, 0x16fe1, 1},
 	},
 }
 
@@ -902,6 +914,7 @@
 		{0x07cb, 0x07ea, 1},
 		{0x0800, 0x0815, 1},
 		{0x0840, 0x0858, 1},
+		{0x0860, 0x086a, 1},
 		{0x08a0, 0x08b4, 1},
 		{0x08b6, 0x08bd, 1},
 		{0x0904, 0x0939, 1},
@@ -918,7 +931,8 @@
 		{0x09dc, 0x09dd, 1},
 		{0x09df, 0x09e1, 1},
 		{0x09f0, 0x09f1, 1},
-		{0x0a05, 0x0a0a, 1},
+		{0x09fc, 0x0a05, 9},
+		{0x0a06, 0x0a0a, 1},
 		{0x0a0f, 0x0a10, 1},
 		{0x0a13, 0x0a28, 1},
 		{0x0a2a, 0x0a30, 1},
@@ -1086,12 +1100,12 @@
 		{0x309f, 0x30a1, 2},
 		{0x30a2, 0x30fa, 1},
 		{0x30ff, 0x3105, 6},
-		{0x3106, 0x312d, 1},
+		{0x3106, 0x312e, 1},
 		{0x3131, 0x318e, 1},
 		{0x31a0, 0x31ba, 1},
 		{0x31f0, 0x31ff, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fd5, 1},
+		{0x4e00, 0x9fea, 1},
 		{0xa000, 0xa014, 1},
 		{0xa016, 0xa48c, 1},
 		{0xa4d0, 0xa4f7, 1},
@@ -1174,7 +1188,7 @@
 		{0x10280, 0x1029c, 1},
 		{0x102a0, 0x102d0, 1},
 		{0x10300, 0x1031f, 1},
-		{0x10330, 0x10340, 1},
+		{0x1032d, 0x10340, 1},
 		{0x10342, 0x10349, 1},
 		{0x10350, 0x10375, 1},
 		{0x10380, 0x1039d, 1},
@@ -1249,13 +1263,21 @@
 		{0x11644, 0x11680, 60},
 		{0x11681, 0x116aa, 1},
 		{0x11700, 0x11719, 1},
-		{0x118ff, 0x11ac0, 449},
-		{0x11ac1, 0x11af8, 1},
+		{0x118ff, 0x11a00, 257},
+		{0x11a0b, 0x11a32, 1},
+		{0x11a3a, 0x11a50, 22},
+		{0x11a5c, 0x11a83, 1},
+		{0x11a86, 0x11a89, 1},
+		{0x11ac0, 0x11af8, 1},
 		{0x11c00, 0x11c08, 1},
 		{0x11c0a, 0x11c2e, 1},
 		{0x11c40, 0x11c72, 50},
 		{0x11c73, 0x11c8f, 1},
-		{0x12000, 0x12399, 1},
+		{0x11d00, 0x11d06, 1},
+		{0x11d08, 0x11d09, 1},
+		{0x11d0b, 0x11d30, 1},
+		{0x11d46, 0x12000, 698},
+		{0x12001, 0x12399, 1},
 		{0x12480, 0x12543, 1},
 		{0x13000, 0x1342e, 1},
 		{0x14400, 0x14646, 1},
@@ -1269,7 +1291,8 @@
 		{0x16f50, 0x17000, 176},
 		{0x17001, 0x187ec, 1},
 		{0x18800, 0x18af2, 1},
-		{0x1b000, 0x1b001, 1},
+		{0x1b000, 0x1b11e, 1},
+		{0x1b170, 0x1b2fb, 1},
 		{0x1bc00, 0x1bc6a, 1},
 		{0x1bc70, 0x1bc7c, 1},
 		{0x1bc80, 0x1bc88, 1},
@@ -1303,6 +1326,7 @@
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
 		{0x2b820, 0x2cea1, 1},
+		{0x2ceb0, 0x2ebe0, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 	LatinOffset: 1,
@@ -1516,6 +1540,7 @@
 		{0x0ac7, 0x0ac9, 1},
 		{0x0acb, 0x0acd, 1},
 		{0x0ae2, 0x0ae3, 1},
+		{0x0afa, 0x0aff, 1},
 		{0x0b01, 0x0b03, 1},
 		{0x0b3c, 0x0b3e, 2},
 		{0x0b3f, 0x0b44, 1},
@@ -1541,7 +1566,8 @@
 		{0x0cca, 0x0ccd, 1},
 		{0x0cd5, 0x0cd6, 1},
 		{0x0ce2, 0x0ce3, 1},
-		{0x0d01, 0x0d03, 1},
+		{0x0d00, 0x0d03, 1},
+		{0x0d3b, 0x0d3c, 1},
 		{0x0d3e, 0x0d44, 1},
 		{0x0d46, 0x0d48, 1},
 		{0x0d4a, 0x0d4d, 1},
@@ -1604,8 +1630,8 @@
 		{0x1cd4, 0x1ce8, 1},
 		{0x1ced, 0x1cf2, 5},
 		{0x1cf3, 0x1cf4, 1},
-		{0x1cf8, 0x1cf9, 1},
-		{0x1dc0, 0x1df5, 1},
+		{0x1cf7, 0x1cf9, 1},
+		{0x1dc0, 0x1df9, 1},
 		{0x1dfb, 0x1dff, 1},
 		{0x20d0, 0x20f0, 1},
 		{0x2cef, 0x2cf1, 1},
@@ -1684,11 +1710,22 @@
 		{0x11630, 0x11640, 1},
 		{0x116ab, 0x116b7, 1},
 		{0x1171d, 0x1172b, 1},
+		{0x11a01, 0x11a0a, 1},
+		{0x11a33, 0x11a39, 1},
+		{0x11a3b, 0x11a3e, 1},
+		{0x11a47, 0x11a51, 10},
+		{0x11a52, 0x11a5b, 1},
+		{0x11a8a, 0x11a99, 1},
 		{0x11c2f, 0x11c36, 1},
 		{0x11c38, 0x11c3f, 1},
 		{0x11c92, 0x11ca7, 1},
 		{0x11ca9, 0x11cb6, 1},
-		{0x16af0, 0x16af4, 1},
+		{0x11d31, 0x11d36, 1},
+		{0x11d3a, 0x11d3c, 2},
+		{0x11d3d, 0x11d3f, 2},
+		{0x11d40, 0x11d45, 1},
+		{0x11d47, 0x16af0, 19881},
+		{0x16af1, 0x16af4, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f51, 0x16f7e, 1},
 		{0x16f8f, 0x16f92, 1},
@@ -1794,11 +1831,12 @@
 		{0x1c25, 0x1c2b, 1},
 		{0x1c34, 0x1c35, 1},
 		{0x1ce1, 0x1cf2, 17},
-		{0x1cf3, 0x302e, 4923},
-		{0x302f, 0xa823, 30708},
-		{0xa824, 0xa827, 3},
-		{0xa880, 0xa881, 1},
-		{0xa8b4, 0xa8c3, 1},
+		{0x1cf3, 0x1cf7, 4},
+		{0x302e, 0x302f, 1},
+		{0xa823, 0xa824, 1},
+		{0xa827, 0xa880, 89},
+		{0xa881, 0xa8b4, 51},
+		{0xa8b5, 0xa8c3, 1},
 		{0xa952, 0xa953, 1},
 		{0xa983, 0xa9b4, 49},
 		{0xa9b5, 0xa9ba, 5},
@@ -1849,6 +1887,9 @@
 		{0x116ae, 0x116af, 1},
 		{0x116b6, 0x11720, 106},
 		{0x11721, 0x11726, 5},
+		{0x11a07, 0x11a08, 1},
+		{0x11a39, 0x11a57, 30},
+		{0x11a58, 0x11a97, 63},
 		{0x11c2f, 0x11c3e, 15},
 		{0x11ca9, 0x11cb1, 8},
 		{0x11cb4, 0x16f51, 21149},
@@ -1914,9 +1955,11 @@
 		{0x0ac2, 0x0ac5, 1},
 		{0x0ac7, 0x0ac8, 1},
 		{0x0acd, 0x0ae2, 21},
-		{0x0ae3, 0x0b01, 30},
-		{0x0b3c, 0x0b3f, 3},
-		{0x0b41, 0x0b44, 1},
+		{0x0ae3, 0x0afa, 23},
+		{0x0afb, 0x0aff, 1},
+		{0x0b01, 0x0b3c, 59},
+		{0x0b3f, 0x0b41, 2},
+		{0x0b42, 0x0b44, 1},
 		{0x0b4d, 0x0b56, 9},
 		{0x0b62, 0x0b63, 1},
 		{0x0b82, 0x0bc0, 62},
@@ -1930,8 +1973,9 @@
 		{0x0cbf, 0x0cc6, 7},
 		{0x0ccc, 0x0ccd, 1},
 		{0x0ce2, 0x0ce3, 1},
-		{0x0d01, 0x0d41, 64},
-		{0x0d42, 0x0d44, 1},
+		{0x0d00, 0x0d01, 1},
+		{0x0d3b, 0x0d3c, 1},
+		{0x0d41, 0x0d44, 1},
 		{0x0d4d, 0x0d62, 21},
 		{0x0d63, 0x0dca, 103},
 		{0x0dd2, 0x0dd4, 1},
@@ -2004,7 +2048,7 @@
 		{0x1ce2, 0x1ce8, 1},
 		{0x1ced, 0x1cf4, 7},
 		{0x1cf8, 0x1cf9, 1},
-		{0x1dc0, 0x1df5, 1},
+		{0x1dc0, 0x1df9, 1},
 		{0x1dfb, 0x1dff, 1},
 		{0x20d0, 0x20dc, 1},
 		{0x20e1, 0x20e5, 4},
@@ -2093,6 +2137,15 @@
 		{0x1171e, 0x1171f, 1},
 		{0x11722, 0x11725, 1},
 		{0x11727, 0x1172b, 1},
+		{0x11a01, 0x11a06, 1},
+		{0x11a09, 0x11a0a, 1},
+		{0x11a33, 0x11a38, 1},
+		{0x11a3b, 0x11a3e, 1},
+		{0x11a47, 0x11a51, 10},
+		{0x11a52, 0x11a56, 1},
+		{0x11a59, 0x11a5b, 1},
+		{0x11a8a, 0x11a96, 1},
+		{0x11a98, 0x11a99, 1},
 		{0x11c30, 0x11c36, 1},
 		{0x11c38, 0x11c3d, 1},
 		{0x11c3f, 0x11c92, 83},
@@ -2100,7 +2153,12 @@
 		{0x11caa, 0x11cb0, 1},
 		{0x11cb2, 0x11cb3, 1},
 		{0x11cb5, 0x11cb6, 1},
-		{0x16af0, 0x16af4, 1},
+		{0x11d31, 0x11d36, 1},
+		{0x11d3a, 0x11d3c, 2},
+		{0x11d3d, 0x11d3f, 2},
+		{0x11d40, 0x11d45, 1},
+		{0x11d47, 0x16af0, 19881},
+		{0x16af1, 0x16af4, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f8f, 0x16f92, 1},
 		{0x1bc9d, 0x1bc9e, 1},
@@ -2233,6 +2291,7 @@
 		{0x11730, 0x1173b, 1},
 		{0x118e0, 0x118f2, 1},
 		{0x11c50, 0x11c6c, 1},
+		{0x11d50, 0x11d59, 1},
 		{0x12400, 0x1246e, 1},
 		{0x16a60, 0x16a69, 1},
 		{0x16b50, 0x16b59, 1},
@@ -2300,6 +2359,7 @@
 		{0x11730, 0x11739, 1},
 		{0x118e0, 0x118e9, 1},
 		{0x11c50, 0x11c59, 1},
+		{0x11d50, 0x11d59, 1},
 		{0x16a60, 0x16a69, 1},
 		{0x16b50, 0x16b59, 1},
 		{0x1d7ce, 0x1d7ff, 1},
@@ -2423,10 +2483,10 @@
 		{0x0830, 0x083e, 1},
 		{0x085e, 0x0964, 262},
 		{0x0965, 0x0970, 11},
-		{0x0af0, 0x0df4, 772},
-		{0x0e4f, 0x0e5a, 11},
-		{0x0e5b, 0x0f04, 169},
-		{0x0f05, 0x0f12, 1},
+		{0x09fd, 0x0af0, 243},
+		{0x0df4, 0x0e4f, 91},
+		{0x0e5a, 0x0e5b, 1},
+		{0x0f04, 0x0f12, 1},
 		{0x0f14, 0x0f3a, 38},
 		{0x0f3b, 0x0f3d, 1},
 		{0x0f85, 0x0fd0, 75},
@@ -2471,7 +2531,7 @@
 		{0x2cfe, 0x2cff, 1},
 		{0x2d70, 0x2e00, 144},
 		{0x2e01, 0x2e2e, 1},
-		{0x2e30, 0x2e44, 1},
+		{0x2e30, 0x2e49, 1},
 		{0x3001, 0x3003, 1},
 		{0x3008, 0x3011, 1},
 		{0x3014, 0x301f, 1},
@@ -2535,6 +2595,9 @@
 		{0x11641, 0x11643, 1},
 		{0x11660, 0x1166c, 1},
 		{0x1173c, 0x1173e, 1},
+		{0x11a3f, 0x11a46, 1},
+		{0x11a9a, 0x11a9c, 1},
+		{0x11a9e, 0x11aa2, 1},
 		{0x11c41, 0x11c45, 1},
 		{0x11c70, 0x11c71, 1},
 		{0x12470, 0x12474, 1},
@@ -2650,10 +2713,10 @@
 		{0x0830, 0x083e, 1},
 		{0x085e, 0x0964, 262},
 		{0x0965, 0x0970, 11},
-		{0x0af0, 0x0df4, 772},
-		{0x0e4f, 0x0e5a, 11},
-		{0x0e5b, 0x0f04, 169},
-		{0x0f05, 0x0f12, 1},
+		{0x09fd, 0x0af0, 243},
+		{0x0df4, 0x0e4f, 91},
+		{0x0e5a, 0x0e5b, 1},
+		{0x0f04, 0x0f12, 1},
 		{0x0f14, 0x0f85, 113},
 		{0x0fd0, 0x0fd4, 1},
 		{0x0fd9, 0x0fda, 1},
@@ -2699,8 +2762,8 @@
 		{0x2e30, 0x2e39, 1},
 		{0x2e3c, 0x2e3f, 1},
 		{0x2e41, 0x2e43, 2},
-		{0x2e44, 0x3001, 445},
-		{0x3002, 0x3003, 1},
+		{0x2e44, 0x2e49, 1},
+		{0x3001, 0x3003, 1},
 		{0x303d, 0x30fb, 190},
 		{0xa4fe, 0xa4ff, 1},
 		{0xa60d, 0xa60f, 1},
@@ -2763,6 +2826,9 @@
 		{0x11641, 0x11643, 1},
 		{0x11660, 0x1166c, 1},
 		{0x1173c, 0x1173e, 1},
+		{0x11a3f, 0x11a46, 1},
+		{0x11a9a, 0x11a9c, 1},
+		{0x11a9e, 0x11aa2, 1},
 		{0x11c41, 0x11c45, 1},
 		{0x11c70, 0x11c71, 1},
 		{0x12470, 0x12474, 1},
@@ -2863,7 +2929,7 @@
 		{0x2044, 0x2052, 14},
 		{0x207a, 0x207c, 1},
 		{0x208a, 0x208c, 1},
-		{0x20a0, 0x20be, 1},
+		{0x20a0, 0x20bf, 1},
 		{0x2100, 0x2101, 1},
 		{0x2103, 0x2106, 1},
 		{0x2108, 0x2109, 1},
@@ -2879,8 +2945,7 @@
 		{0x218b, 0x2190, 5},
 		{0x2191, 0x2307, 1},
 		{0x230c, 0x2328, 1},
-		{0x232b, 0x23fe, 1},
-		{0x2400, 0x2426, 1},
+		{0x232b, 0x2426, 1},
 		{0x2440, 0x244a, 1},
 		{0x249c, 0x24e9, 1},
 		{0x2500, 0x2767, 1},
@@ -2893,7 +2958,7 @@
 		{0x2b76, 0x2b95, 1},
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
-		{0x2bca, 0x2bd1, 1},
+		{0x2bca, 0x2bd2, 1},
 		{0x2bec, 0x2bef, 1},
 		{0x2ce5, 0x2cea, 1},
 		{0x2e80, 0x2e99, 1},
@@ -2982,9 +3047,10 @@
 		{0x1f210, 0x1f23b, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f6d2, 1},
+		{0x1f260, 0x1f265, 1},
+		{0x1f300, 0x1f6d4, 1},
 		{0x1f6e0, 0x1f6ec, 1},
-		{0x1f6f0, 0x1f6f6, 1},
+		{0x1f6f0, 0x1f6f8, 1},
 		{0x1f700, 0x1f773, 1},
 		{0x1f780, 0x1f7d4, 1},
 		{0x1f800, 0x1f80b, 1},
@@ -2992,14 +3058,13 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
-		{0x1f910, 0x1f91e, 1},
-		{0x1f920, 0x1f927, 1},
-		{0x1f930, 0x1f933, 3},
-		{0x1f934, 0x1f93e, 1},
-		{0x1f940, 0x1f94b, 1},
-		{0x1f950, 0x1f95e, 1},
-		{0x1f980, 0x1f991, 1},
-		{0x1f9c0, 0x1f9c0, 1},
+		{0x1f900, 0x1f90b, 1},
+		{0x1f910, 0x1f93e, 1},
+		{0x1f940, 0x1f94c, 1},
+		{0x1f950, 0x1f96b, 1},
+		{0x1f980, 0x1f997, 1},
+		{0x1f9c0, 0x1f9d0, 16},
+		{0x1f9d1, 0x1f9e6, 1},
 	},
 	LatinOffset: 10,
 }
@@ -3013,7 +3078,7 @@
 		{0x09fb, 0x0af1, 246},
 		{0x0bf9, 0x0e3f, 582},
 		{0x17db, 0x20a0, 2245},
-		{0x20a1, 0x20be, 1},
+		{0x20a1, 0x20bf, 1},
 		{0xa838, 0xfdfc, 21956},
 		{0xfe69, 0xff04, 155},
 		{0xffe0, 0xffe1, 1},
@@ -3167,8 +3232,7 @@
 		{0x232b, 0x237b, 1},
 		{0x237d, 0x239a, 1},
 		{0x23b4, 0x23db, 1},
-		{0x23e2, 0x23fe, 1},
-		{0x2400, 0x2426, 1},
+		{0x23e2, 0x2426, 1},
 		{0x2440, 0x244a, 1},
 		{0x249c, 0x24e9, 1},
 		{0x2500, 0x25b6, 1},
@@ -3184,7 +3248,7 @@
 		{0x2b76, 0x2b95, 1},
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
-		{0x2bca, 0x2bd1, 1},
+		{0x2bca, 0x2bd2, 1},
 		{0x2bec, 0x2bef, 1},
 		{0x2ce5, 0x2cea, 1},
 		{0x2e80, 0x2e99, 1},
@@ -3256,10 +3320,11 @@
 		{0x1f210, 0x1f23b, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
+		{0x1f260, 0x1f265, 1},
 		{0x1f300, 0x1f3fa, 1},
-		{0x1f400, 0x1f6d2, 1},
+		{0x1f400, 0x1f6d4, 1},
 		{0x1f6e0, 0x1f6ec, 1},
-		{0x1f6f0, 0x1f6f6, 1},
+		{0x1f6f0, 0x1f6f8, 1},
 		{0x1f700, 0x1f773, 1},
 		{0x1f780, 0x1f7d4, 1},
 		{0x1f800, 0x1f80b, 1},
@@ -3267,14 +3332,13 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
-		{0x1f910, 0x1f91e, 1},
-		{0x1f920, 0x1f927, 1},
-		{0x1f930, 0x1f933, 3},
-		{0x1f934, 0x1f93e, 1},
-		{0x1f940, 0x1f94b, 1},
-		{0x1f950, 0x1f95e, 1},
-		{0x1f980, 0x1f991, 1},
-		{0x1f9c0, 0x1f9c0, 1},
+		{0x1f900, 0x1f90b, 1},
+		{0x1f910, 0x1f93e, 1},
+		{0x1f940, 0x1f94c, 1},
+		{0x1f950, 0x1f96b, 1},
+		{0x1f980, 0x1f997, 1},
+		{0x1f9c0, 0x1f9d0, 16},
+		{0x1f9d1, 0x1f9e6, 1},
 	},
 	LatinOffset: 2,
 }
@@ -3366,7 +3430,7 @@
 )
 
 // Generated by running
-//	maketables --scripts=all --url=http://www.unicode.org/Public/9.0.0/ucd/
+//	maketables --scripts=all --url=http://www.unicode.org/Public/10.0.0/ucd/
 // DO NOT EDIT
 
 // Scripts is the set of Unicode script tables.
@@ -3445,6 +3509,7 @@
 	"Mandaic":                Mandaic,
 	"Manichaean":             Manichaean,
 	"Marchen":                Marchen,
+	"Masaram_Gondi":          Masaram_Gondi,
 	"Meetei_Mayek":           Meetei_Mayek,
 	"Mende_Kikakui":          Mende_Kikakui,
 	"Meroitic_Cursive":       Meroitic_Cursive,
@@ -3459,6 +3524,7 @@
 	"New_Tai_Lue":            New_Tai_Lue,
 	"Newa":                   Newa,
 	"Nko":                    Nko,
+	"Nushu":                  Nushu,
 	"Ogham":                  Ogham,
 	"Ol_Chiki":               Ol_Chiki,
 	"Old_Hungarian":          Old_Hungarian,
@@ -3487,6 +3553,7 @@
 	"SignWriting":            SignWriting,
 	"Sinhala":                Sinhala,
 	"Sora_Sompeng":           Sora_Sompeng,
+	"Soyombo":                Soyombo,
 	"Sundanese":              Sundanese,
 	"Syloti_Nagri":           Syloti_Nagri,
 	"Syriac":                 Syriac,
@@ -3508,6 +3575,7 @@
 	"Vai":                    Vai,
 	"Warang_Citi":            Warang_Citi,
 	"Yi":                     Yi,
+	"Zanabazar_Square":       Zanabazar_Square,
 }
 
 var _Adlam = &RangeTable{
@@ -3540,6 +3608,7 @@
 		{0x0600, 0x0604, 1},
 		{0x0606, 0x060b, 1},
 		{0x060d, 0x061a, 1},
+		{0x061c, 0x061c, 1},
 		{0x061e, 0x061e, 1},
 		{0x0620, 0x063f, 1},
 		{0x0641, 0x064a, 1},
@@ -3663,7 +3732,7 @@
 		{0x09d7, 0x09d7, 1},
 		{0x09dc, 0x09dd, 1},
 		{0x09df, 0x09e3, 1},
-		{0x09e6, 0x09fb, 1},
+		{0x09e6, 0x09fd, 1},
 	},
 }
 
@@ -3680,7 +3749,7 @@
 var _Bopomofo = &RangeTable{
 	R16: []Range16{
 		{0x02ea, 0x02eb, 1},
-		{0x3105, 0x312d, 1},
+		{0x3105, 0x312e, 1},
 		{0x31a0, 0x31ba, 1},
 	},
 }
@@ -3779,7 +3848,7 @@
 		{0x0589, 0x0589, 1},
 		{0x0605, 0x0605, 1},
 		{0x060c, 0x060c, 1},
-		{0x061b, 0x061c, 1},
+		{0x061b, 0x061b, 1},
 		{0x061f, 0x061f, 1},
 		{0x0640, 0x0640, 1},
 		{0x06dd, 0x06dd, 1},
@@ -3796,30 +3865,29 @@
 		{0x1ce1, 0x1ce1, 1},
 		{0x1ce9, 0x1cec, 1},
 		{0x1cee, 0x1cf3, 1},
-		{0x1cf5, 0x1cf6, 1},
+		{0x1cf5, 0x1cf7, 1},
 		{0x2000, 0x200b, 1},
 		{0x200e, 0x2064, 1},
 		{0x2066, 0x2070, 1},
 		{0x2074, 0x207e, 1},
 		{0x2080, 0x208e, 1},
-		{0x20a0, 0x20be, 1},
+		{0x20a0, 0x20bf, 1},
 		{0x2100, 0x2125, 1},
 		{0x2127, 0x2129, 1},
 		{0x212c, 0x2131, 1},
 		{0x2133, 0x214d, 1},
 		{0x214f, 0x215f, 1},
 		{0x2189, 0x218b, 1},
-		{0x2190, 0x23fe, 1},
-		{0x2400, 0x2426, 1},
+		{0x2190, 0x2426, 1},
 		{0x2440, 0x244a, 1},
 		{0x2460, 0x27ff, 1},
 		{0x2900, 0x2b73, 1},
 		{0x2b76, 0x2b95, 1},
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
-		{0x2bca, 0x2bd1, 1},
+		{0x2bca, 0x2bd2, 1},
 		{0x2bec, 0x2bef, 1},
-		{0x2e00, 0x2e44, 1},
+		{0x2e00, 0x2e49, 1},
 		{0x2ff0, 0x2ffb, 1},
 		{0x3000, 0x3004, 1},
 		{0x3006, 0x3006, 1},
@@ -3909,9 +3977,10 @@
 		{0x1f210, 0x1f23b, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f6d2, 1},
+		{0x1f260, 0x1f265, 1},
+		{0x1f300, 0x1f6d4, 1},
 		{0x1f6e0, 0x1f6ec, 1},
-		{0x1f6f0, 0x1f6f6, 1},
+		{0x1f6f0, 0x1f6f8, 1},
 		{0x1f700, 0x1f773, 1},
 		{0x1f780, 0x1f7d4, 1},
 		{0x1f800, 0x1f80b, 1},
@@ -3919,14 +3988,13 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
-		{0x1f910, 0x1f91e, 1},
-		{0x1f920, 0x1f927, 1},
-		{0x1f930, 0x1f930, 1},
-		{0x1f933, 0x1f93e, 1},
-		{0x1f940, 0x1f94b, 1},
-		{0x1f950, 0x1f95e, 1},
-		{0x1f980, 0x1f991, 1},
+		{0x1f900, 0x1f90b, 1},
+		{0x1f910, 0x1f93e, 1},
+		{0x1f940, 0x1f94c, 1},
+		{0x1f950, 0x1f96b, 1},
+		{0x1f980, 0x1f997, 1},
 		{0x1f9c0, 0x1f9c0, 1},
+		{0x1f9d0, 0x1f9e6, 1},
 		{0xe0001, 0xe0001, 1},
 		{0xe0020, 0xe007f, 1},
 	},
@@ -4167,7 +4235,7 @@
 		{0x0ad0, 0x0ad0, 1},
 		{0x0ae0, 0x0ae3, 1},
 		{0x0ae6, 0x0af1, 1},
-		{0x0af9, 0x0af9, 1},
+		{0x0af9, 0x0aff, 1},
 	},
 }
 
@@ -4202,7 +4270,7 @@
 		{0x3021, 0x3029, 1},
 		{0x3038, 0x303b, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fd5, 1},
+		{0x4e00, 0x9fea, 1},
 		{0xf900, 0xfa6d, 1},
 		{0xfa70, 0xfad9, 1},
 	},
@@ -4211,6 +4279,7 @@
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
 		{0x2b820, 0x2cea1, 1},
+		{0x2ceb0, 0x2ebe0, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 }
@@ -4269,7 +4338,7 @@
 		{0x309d, 0x309f, 1},
 	},
 	R32: []Range32{
-		{0x1b001, 0x1b001, 1},
+		{0x1b001, 0x1b11e, 1},
 		{0x1f200, 0x1f200, 1},
 	},
 }
@@ -4296,7 +4365,7 @@
 		{0x1ced, 0x1ced, 1},
 		{0x1cf4, 0x1cf4, 1},
 		{0x1cf8, 0x1cf9, 1},
-		{0x1dc0, 0x1df5, 1},
+		{0x1dc0, 0x1df9, 1},
 		{0x1dfb, 0x1dff, 1},
 		{0x200c, 0x200d, 1},
 		{0x20d0, 0x20f0, 1},
@@ -4557,11 +4626,10 @@
 
 var _Malayalam = &RangeTable{
 	R16: []Range16{
-		{0x0d01, 0x0d03, 1},
+		{0x0d00, 0x0d03, 1},
 		{0x0d05, 0x0d0c, 1},
 		{0x0d0e, 0x0d10, 1},
-		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d44, 1},
+		{0x0d12, 0x0d44, 1},
 		{0x0d46, 0x0d48, 1},
 		{0x0d4a, 0x0d4f, 1},
 		{0x0d54, 0x0d63, 1},
@@ -4593,6 +4661,19 @@
 	},
 }
 
+var _Masaram_Gondi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11d00, 0x11d06, 1},
+		{0x11d08, 0x11d09, 1},
+		{0x11d0b, 0x11d36, 1},
+		{0x11d3a, 0x11d3a, 1},
+		{0x11d3c, 0x11d3d, 1},
+		{0x11d3f, 0x11d47, 1},
+		{0x11d50, 0x11d59, 1},
+	},
+}
+
 var _Meetei_Mayek = &RangeTable{
 	R16: []Range16{
 		{0xaae0, 0xaaf6, 1},
@@ -4716,6 +4797,14 @@
 	},
 }
 
+var _Nushu = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x16fe1, 0x16fe1, 1},
+		{0x1b170, 0x1b2fb, 1},
+	},
+}
+
 var _Ogham = &RangeTable{
 	R16: []Range16{
 		{0x1680, 0x169c, 1},
@@ -4741,6 +4830,7 @@
 	R16: []Range16{},
 	R32: []Range32{
 		{0x10300, 0x10323, 1},
+		{0x1032d, 0x1032f, 1},
 	},
 }
 
@@ -4951,6 +5041,15 @@
 	},
 }
 
+var _Soyombo = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11a50, 0x11a83, 1},
+		{0x11a86, 0x11a9c, 1},
+		{0x11a9e, 0x11aa2, 1},
+	},
+}
+
 var _Sundanese = &RangeTable{
 	R16: []Range16{
 		{0x1b80, 0x1bbf, 1},
@@ -4969,6 +5068,7 @@
 		{0x0700, 0x070d, 1},
 		{0x070f, 0x074a, 1},
 		{0x074d, 0x074f, 1},
+		{0x0860, 0x086a, 1},
 	},
 }
 
@@ -5137,6 +5237,13 @@
 	},
 }
 
+var _Zanabazar_Square = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11a00, 0x11a47, 1},
+	},
+}
+
 // These variables have type *RangeTable.
 var (
 	Adlam                  = _Adlam                  // Adlam is the set of Unicode characters in script Adlam.
@@ -5213,6 +5320,7 @@
 	Mandaic                = _Mandaic                // Mandaic is the set of Unicode characters in script Mandaic.
 	Manichaean             = _Manichaean             // Manichaean is the set of Unicode characters in script Manichaean.
 	Marchen                = _Marchen                // Marchen is the set of Unicode characters in script Marchen.
+	Masaram_Gondi          = _Masaram_Gondi          // Masaram_Gondi is the set of Unicode characters in script Masaram_Gondi.
 	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.
@@ -5227,6 +5335,7 @@
 	New_Tai_Lue            = _New_Tai_Lue            // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
 	Newa                   = _Newa                   // Newa is the set of Unicode characters in script Newa.
 	Nko                    = _Nko                    // Nko is the set of Unicode characters in script Nko.
+	Nushu                  = _Nushu                  // Nushu is the set of Unicode characters in script Nushu.
 	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_Hungarian          = _Old_Hungarian          // Old_Hungarian is the set of Unicode characters in script Old_Hungarian.
@@ -5255,6 +5364,7 @@
 	SignWriting            = _SignWriting            // SignWriting is the set of Unicode characters in script SignWriting.
 	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.
+	Soyombo                = _Soyombo                // Soyombo is the set of Unicode characters in script Soyombo.
 	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.
@@ -5276,10 +5386,11 @@
 	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.
+	Zanabazar_Square       = _Zanabazar_Square       // Zanabazar_Square is the set of Unicode characters in script Zanabazar_Square.
 )
 
 // Generated by running
-//	maketables --props=all --url=http://www.unicode.org/Public/9.0.0/ucd/
+//	maketables --props=all --url=http://www.unicode.org/Public/10.0.0/ucd/
 // DO NOT EDIT
 
 // Properties is the set of Unicode property tables.
@@ -5311,6 +5422,7 @@
 	"Prepended_Concatenation_Mark":       Prepended_Concatenation_Mark,
 	"Quotation_Mark":                     Quotation_Mark,
 	"Radical":                            Radical,
+	"Regional_Indicator":                 Regional_Indicator,
 	"Sentence_Terminal":                  Sentence_Terminal,
 	"STerm":                              Sentence_Terminal,
 	"Soft_Dotted":                        Soft_Dotted,
@@ -5421,12 +5533,14 @@
 		{0x0a4d, 0x0a4d, 1},
 		{0x0abc, 0x0abc, 1},
 		{0x0acd, 0x0acd, 1},
+		{0x0afd, 0x0aff, 1},
 		{0x0b3c, 0x0b3c, 1},
 		{0x0b4d, 0x0b4d, 1},
 		{0x0bcd, 0x0bcd, 1},
 		{0x0c4d, 0x0c4d, 1},
 		{0x0cbc, 0x0cbc, 1},
 		{0x0ccd, 0x0ccd, 1},
+		{0x0d3b, 0x0d3c, 1},
 		{0x0d4d, 0x0d4d, 1},
 		{0x0dca, 0x0dca, 1},
 		{0x0e47, 0x0e4c, 1},
@@ -5460,10 +5574,10 @@
 		{0x1cd0, 0x1ce8, 1},
 		{0x1ced, 0x1ced, 1},
 		{0x1cf4, 0x1cf4, 1},
-		{0x1cf8, 0x1cf9, 1},
+		{0x1cf7, 0x1cf9, 1},
 		{0x1d2c, 0x1d6a, 1},
 		{0x1dc4, 0x1dcf, 1},
-		{0x1df5, 0x1df5, 1},
+		{0x1df5, 0x1df9, 1},
 		{0x1dfd, 0x1dff, 1},
 		{0x1fbd, 0x1fbd, 1},
 		{0x1fbf, 0x1fc1, 1},
@@ -5525,7 +5639,12 @@
 		{0x1163f, 0x1163f, 1},
 		{0x116b6, 0x116b7, 1},
 		{0x1172b, 0x1172b, 1},
+		{0x11a34, 0x11a34, 1},
+		{0x11a47, 0x11a47, 1},
+		{0x11a99, 0x11a99, 1},
 		{0x11c3f, 0x11c3f, 1},
+		{0x11d42, 0x11d42, 1},
+		{0x11d44, 0x11d45, 1},
 		{0x16af0, 0x16af4, 1},
 		{0x16f8f, 0x16f9f, 1},
 		{0x1d167, 0x1d169, 1},
@@ -5569,8 +5688,9 @@
 	R32: []Range32{
 		{0x1135d, 0x1135d, 1},
 		{0x115c6, 0x115c8, 1},
+		{0x11a98, 0x11a98, 1},
 		{0x16b42, 0x16b43, 1},
-		{0x16fe0, 0x16fe0, 1},
+		{0x16fe0, 0x16fe1, 1},
 		{0x1e944, 0x1e946, 1},
 	},
 	LatinOffset: 1,
@@ -5623,17 +5743,19 @@
 		{0x3021, 0x3029, 1},
 		{0x3038, 0x303a, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fd5, 1},
+		{0x4e00, 0x9fea, 1},
 		{0xf900, 0xfa6d, 1},
 		{0xfa70, 0xfad9, 1},
 	},
 	R32: []Range32{
 		{0x17000, 0x187ec, 1},
 		{0x18800, 0x18af2, 1},
+		{0x1b170, 0x1b2fb, 1},
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
 		{0x2b820, 0x2cea1, 1},
+		{0x2ceb0, 0x2ebe0, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 }
@@ -5730,6 +5852,7 @@
 		{0x0ac7, 0x0ac9, 1},
 		{0x0acb, 0x0acc, 1},
 		{0x0ae2, 0x0ae3, 1},
+		{0x0afa, 0x0afc, 1},
 		{0x0b01, 0x0b03, 1},
 		{0x0b3e, 0x0b44, 1},
 		{0x0b47, 0x0b48, 1},
@@ -5753,7 +5876,7 @@
 		{0x0cca, 0x0ccc, 1},
 		{0x0cd5, 0x0cd6, 1},
 		{0x0ce2, 0x0ce3, 1},
-		{0x0d01, 0x0d03, 1},
+		{0x0d00, 0x0d03, 1},
 		{0x0d3e, 0x0d44, 1},
 		{0x0d46, 0x0d48, 1},
 		{0x0d4a, 0x0d4c, 1},
@@ -5863,10 +5986,21 @@
 		{0x11640, 0x11640, 1},
 		{0x116ab, 0x116b5, 1},
 		{0x1171d, 0x1172a, 1},
+		{0x11a01, 0x11a0a, 1},
+		{0x11a35, 0x11a39, 1},
+		{0x11a3b, 0x11a3e, 1},
+		{0x11a51, 0x11a5b, 1},
+		{0x11a8a, 0x11a97, 1},
 		{0x11c2f, 0x11c36, 1},
 		{0x11c38, 0x11c3e, 1},
 		{0x11c92, 0x11ca7, 1},
 		{0x11ca9, 0x11cb6, 1},
+		{0x11d31, 0x11d36, 1},
+		{0x11d3a, 0x11d3a, 1},
+		{0x11d3c, 0x11d3d, 1},
+		{0x11d3f, 0x11d41, 1},
+		{0x11d43, 0x11d43, 1},
+		{0x11d47, 0x11d47, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f51, 0x16f7e, 1},
 		{0x1bc9e, 0x1bc9e, 1},
@@ -6213,6 +6347,13 @@
 	},
 }
 
+var _Regional_Indicator = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x1f1e6, 0x1f1ff, 1},
+	},
+}
+
 var _Sentence_Terminal = &RangeTable{
 	R16: []Range16{
 		{0x0021, 0x0021, 1},
@@ -6276,6 +6417,8 @@
 		{0x115c9, 0x115d7, 1},
 		{0x11641, 0x11642, 1},
 		{0x1173c, 0x1173e, 1},
+		{0x11a42, 0x11a43, 1},
+		{0x11a9b, 0x11a9c, 1},
 		{0x11c41, 0x11c42, 1},
 		{0x16a6e, 0x16a6f, 1},
 		{0x16af5, 0x16af5, 1},
@@ -6415,6 +6558,9 @@
 		{0x115c9, 0x115d7, 1},
 		{0x11641, 0x11642, 1},
 		{0x1173c, 0x1173e, 1},
+		{0x11a42, 0x11a43, 1},
+		{0x11a9b, 0x11a9c, 1},
+		{0x11aa1, 0x11aa2, 1},
 		{0x11c41, 0x11c43, 1},
 		{0x11c71, 0x11c71, 1},
 		{0x12470, 0x12474, 1},
@@ -6431,7 +6577,7 @@
 var _Unified_Ideograph = &RangeTable{
 	R16: []Range16{
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fd5, 1},
+		{0x4e00, 0x9fea, 1},
 		{0xfa0e, 0xfa0f, 1},
 		{0xfa11, 0xfa11, 1},
 		{0xfa13, 0xfa14, 1},
@@ -6445,6 +6591,7 @@
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
 		{0x2b820, 0x2cea1, 1},
+		{0x2ceb0, 0x2ebe0, 1},
 	},
 }
 
@@ -6503,6 +6650,7 @@
 	Prepended_Concatenation_Mark       = _Prepended_Concatenation_Mark       // Prepended_Concatenation_Mark is the set of Unicode characters with property Prepended_Concatenation_Mark.
 	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.
+	Regional_Indicator                 = _Regional_Indicator                 // Regional_Indicator is the set of Unicode characters with property Regional_Indicator.
 	STerm                              = _Sentence_Terminal                  // STerm is an alias for Sentence_Terminal.
 	Sentence_Terminal                  = _Sentence_Terminal                  // Sentence_Terminal is the set of Unicode characters with property Sentence_Terminal.
 	Soft_Dotted                        = _Soft_Dotted                        // Soft_Dotted is the set of Unicode characters with property Soft_Dotted.
@@ -6513,7 +6661,7 @@
 )
 
 // Generated by running
-//	maketables --data=http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/9.0.0/ucd/CaseFolding.txt
+//	maketables --data=http://www.unicode.org/Public/10.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/10.0.0/ucd/CaseFolding.txt
 // DO NOT EDIT
 
 // CaseRanges is the table describing case mappings for all letters with
@@ -7612,7 +7760,7 @@
 	},
 }
 
-// Range entries: 3576 16-bit, 1454 32-bit, 5030 total.
-// Range bytes: 21456 16-bit, 17448 32-bit, 38904 total.
+// Range entries: 3587 16-bit, 1554 32-bit, 5141 total.
+// Range bytes: 21522 16-bit, 18648 32-bit, 40170 total.
 
 // Fold orbit bytes: 88 pairs, 352 bytes
diff --git a/src/unicode/utf8/utf8.go b/src/unicode/utf8/utf8.go
index 6ccd464..db845ab 100644
--- a/src/unicode/utf8/utf8.go
+++ b/src/unicode/utf8/utf8.go
@@ -110,12 +110,10 @@
 	}
 	// Must be short or invalid.
 	accept := acceptRanges[x>>4]
-	if n > 1 {
-		if c := p[1]; c < accept.lo || accept.hi < c {
-			return true
-		} else if n > 2 && (p[2] < locb || hicb < p[2]) {
-			return true
-		}
+	if n > 1 && (p[1] < accept.lo || accept.hi < p[1]) {
+		return true
+	} else if n > 2 && (p[2] < locb || hicb < p[2]) {
+		return true
 	}
 	return false
 }
@@ -132,12 +130,10 @@
 	}
 	// Must be short or invalid.
 	accept := acceptRanges[x>>4]
-	if n > 1 {
-		if c := s[1]; c < accept.lo || accept.hi < c {
-			return true
-		} else if n > 2 && (s[2] < locb || hicb < s[2]) {
-			return true
-		}
+	if n > 1 && (s[1] < accept.lo || accept.hi < s[1]) {
+		return true
+	} else if n > 2 && (s[2] < locb || hicb < s[2]) {
+		return true
 	}
 	return false
 }
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index 859ca4f..ffe406e 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -176,7 +176,7 @@
 // Sizeof takes an expression x of any type and returns the size in bytes
 // of a hypothetical variable v as if v was declared via var v = x.
 // The size does not include any memory possibly referenced by x.
-// For instance, if x is a slice,  Sizeof returns the size of the slice
+// For instance, if x is a slice, Sizeof returns the size of the slice
 // descriptor, not the size of the memory referenced by the slice.
 func Sizeof(x ArbitraryType) uintptr
 
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/asn1.go b/src/vendor/golang_org/x/crypto/cryptobyte/asn1.go
new file mode 100644
index 0000000..225a49f
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/asn1.go
@@ -0,0 +1,732 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	encoding_asn1 "encoding/asn1"
+	"fmt"
+	"math/big"
+	"reflect"
+	"time"
+
+	"golang_org/x/crypto/cryptobyte/asn1"
+)
+
+// This file contains ASN.1-related methods for String and Builder.
+
+// Builder
+
+// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Int64(v int64) {
+	b.addASN1Signed(asn1.INTEGER, v)
+}
+
+// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
+func (b *Builder) AddASN1Enum(v int64) {
+	b.addASN1Signed(asn1.ENUM, v)
+}
+
+func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) {
+	b.AddASN1(tag, func(c *Builder) {
+		length := 1
+		for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
+			length++
+		}
+
+		for ; length > 0; length-- {
+			i := v >> uint((length-1)*8) & 0xff
+			c.AddUint8(uint8(i))
+		}
+	})
+}
+
+// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Uint64(v uint64) {
+	b.AddASN1(asn1.INTEGER, func(c *Builder) {
+		length := 1
+		for i := v; i >= 0x80; i >>= 8 {
+			length++
+		}
+
+		for ; length > 0; length-- {
+			i := v >> uint((length-1)*8) & 0xff
+			c.AddUint8(uint8(i))
+		}
+	})
+}
+
+// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1BigInt(n *big.Int) {
+	if b.err != nil {
+		return
+	}
+
+	b.AddASN1(asn1.INTEGER, func(c *Builder) {
+		if n.Sign() < 0 {
+			// A negative number has to be converted to two's-complement form. So we
+			// invert and subtract 1. 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 bytes[0]&0x80 == 0 {
+				c.add(0xff)
+			}
+			c.add(bytes...)
+		} else if n.Sign() == 0 {
+			c.add(0)
+		} else {
+			bytes := n.Bytes()
+			if bytes[0]&0x80 != 0 {
+				c.add(0)
+			}
+			c.add(bytes...)
+		}
+	})
+}
+
+// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
+func (b *Builder) AddASN1OctetString(bytes []byte) {
+	b.AddASN1(asn1.OCTET_STRING, func(c *Builder) {
+		c.AddBytes(bytes)
+	})
+}
+
+const generalizedTimeFormatStr = "20060102150405Z0700"
+
+// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME.
+func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
+	if t.Year() < 0 || t.Year() > 9999 {
+		b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
+		return
+	}
+	b.AddASN1(asn1.GeneralizedTime, func(c *Builder) {
+		c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
+	})
+}
+
+// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
+// support BIT STRINGs that are not a whole number of bytes.
+func (b *Builder) AddASN1BitString(data []byte) {
+	b.AddASN1(asn1.BIT_STRING, func(b *Builder) {
+		b.AddUint8(0)
+		b.AddBytes(data)
+	})
+}
+
+func (b *Builder) addBase128Int(n int64) {
+	var length int
+	if n == 0 {
+		length = 1
+	} else {
+		for i := n; i > 0; i >>= 7 {
+			length++
+		}
+	}
+
+	for i := length - 1; i >= 0; i-- {
+		o := byte(n >> uint(i*7))
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+
+		b.add(o)
+	}
+}
+
+func isValidOID(oid encoding_asn1.ObjectIdentifier) bool {
+	if len(oid) < 2 {
+		return false
+	}
+
+	if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) {
+		return false
+	}
+
+	for _, v := range oid {
+		if v < 0 {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) {
+	b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) {
+		if !isValidOID(oid) {
+			b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid)
+			return
+		}
+
+		b.addBase128Int(int64(oid[0])*40 + int64(oid[1]))
+		for _, v := range oid[2:] {
+			b.addBase128Int(int64(v))
+		}
+	})
+}
+
+func (b *Builder) AddASN1Boolean(v bool) {
+	b.AddASN1(asn1.BOOLEAN, func(b *Builder) {
+		if v {
+			b.AddUint8(0xff)
+		} else {
+			b.AddUint8(0)
+		}
+	})
+}
+
+func (b *Builder) AddASN1NULL() {
+	b.add(uint8(asn1.NULL), 0)
+}
+
+// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if
+// successful or records an error if one occurred.
+func (b *Builder) MarshalASN1(v interface{}) {
+	// NOTE(martinkr): This is somewhat of a hack to allow propagation of
+	// encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
+	// value embedded into a struct, its tag information is lost.
+	if b.err != nil {
+		return
+	}
+	bytes, err := encoding_asn1.Marshal(v)
+	if err != nil {
+		b.err = err
+		return
+	}
+	b.AddBytes(bytes)
+}
+
+// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag.
+// Tags greater than 30 are not supported and result in an error (i.e.
+// low-tag-number form only). The child builder passed to the
+// BuilderContinuation can be used to build the content of the ASN.1 object.
+func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
+	if b.err != nil {
+		return
+	}
+	// Identifiers with the low five bits set indicate high-tag-number format
+	// (two or more octets), which we don't support.
+	if tag&0x1f == 0x1f {
+		b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
+		return
+	}
+	b.AddUint8(uint8(tag))
+	b.addLengthPrefixed(1, true, f)
+}
+
+// String
+
+func (s *String) ReadASN1Boolean(out *bool) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 {
+		return false
+	}
+
+	switch bytes[0] {
+	case 0:
+		*out = false
+	case 0xff:
+		*out = true
+	default:
+		return false
+	}
+
+	return true
+}
+
+var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
+
+// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
+// not point to an integer or to a big.Int, it panics. It returns true on
+// success and false on error.
+func (s *String) ReadASN1Integer(out interface{}) bool {
+	if reflect.TypeOf(out).Kind() != reflect.Ptr {
+		panic("out is not a pointer")
+	}
+	switch reflect.ValueOf(out).Elem().Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		var i int64
+		if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
+			return false
+		}
+		reflect.ValueOf(out).Elem().SetInt(i)
+		return true
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		var u uint64
+		if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
+			return false
+		}
+		reflect.ValueOf(out).Elem().SetUint(u)
+		return true
+	case reflect.Struct:
+		if reflect.TypeOf(out).Elem() == bigIntType {
+			return s.readASN1BigInt(out.(*big.Int))
+		}
+	}
+	panic("out does not point to an integer type")
+}
+
+func checkASN1Integer(bytes []byte) bool {
+	if len(bytes) == 0 {
+		// An INTEGER is encoded with at least one octet.
+		return false
+	}
+	if len(bytes) == 1 {
+		return true
+	}
+	if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
+		// Value is not minimally encoded.
+		return false
+	}
+	return true
+}
+
+var bigOne = big.NewInt(1)
+
+func (s *String) readASN1BigInt(out *big.Int) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+		return false
+	}
+	if bytes[0]&0x80 == 0x80 {
+		// Negative number.
+		neg := make([]byte, len(bytes))
+		for i, b := range bytes {
+			neg[i] = ^b
+		}
+		out.SetBytes(neg)
+		out.Add(out, bigOne)
+		out.Neg(out)
+	} else {
+		out.SetBytes(bytes)
+	}
+	return true
+}
+
+func (s *String) readASN1Int64(out *int64) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
+		return false
+	}
+	return true
+}
+
+func asn1Signed(out *int64, n []byte) bool {
+	length := len(n)
+	if length > 8 {
+		return false
+	}
+	for i := 0; i < length; i++ {
+		*out <<= 8
+		*out |= int64(n[i])
+	}
+	// Shift up and down in order to sign extend the result.
+	*out <<= 64 - uint8(length)*8
+	*out >>= 64 - uint8(length)*8
+	return true
+}
+
+func (s *String) readASN1Uint64(out *uint64) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
+		return false
+	}
+	return true
+}
+
+func asn1Unsigned(out *uint64, n []byte) bool {
+	length := len(n)
+	if length > 9 || length == 9 && n[0] != 0 {
+		// Too large for uint64.
+		return false
+	}
+	if n[0]&0x80 != 0 {
+		// Negative number.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		*out <<= 8
+		*out |= uint64(n[i])
+	}
+	return true
+}
+
+// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It returns
+// true on success and false on error.
+func (s *String) ReadASN1Enum(out *int) bool {
+	var bytes String
+	var i int64
+	if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
+		return false
+	}
+	if int64(int(i)) != i {
+		return false
+	}
+	*out = int(i)
+	return true
+}
+
+func (s *String) readBase128Int(out *int) bool {
+	ret := 0
+	for i := 0; len(*s) > 0; i++ {
+		if i == 4 {
+			return false
+		}
+		ret <<= 7
+		b := s.read(1)[0]
+		ret |= int(b & 0x7f)
+		if b&0x80 == 0 {
+			*out = ret
+			return true
+		}
+	}
+	return false // truncated
+}
+
+// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
+// advances. It returns true on success and false on error.
+func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
+		return false
+	}
+
+	// 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.
+	components := 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.
+	var v int
+	if !bytes.readBase128Int(&v) {
+		return false
+	}
+	if v < 80 {
+		components[0] = v / 40
+		components[1] = v % 40
+	} else {
+		components[0] = 2
+		components[1] = v - 80
+	}
+
+	i := 2
+	for ; len(bytes) > 0; i++ {
+		if !bytes.readBase128Int(&v) {
+			return false
+		}
+		components[i] = v
+	}
+	*out = components[:i]
+	return true
+}
+
+// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
+// advances. It returns true on success and false on error.
+func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
+		return false
+	}
+	t := string(bytes)
+	res, err := time.Parse(generalizedTimeFormatStr, t)
+	if err != nil {
+		return false
+	}
+	if serialized := res.Format(generalizedTimeFormatStr); serialized != t {
+		return false
+	}
+	*out = res
+	return true
+}
+
+// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It
+// returns true on success and false on error.
+func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
+		return false
+	}
+
+	paddingBits := uint8(bytes[0])
+	bytes = bytes[1:]
+	if paddingBits > 7 ||
+		len(bytes) == 0 && paddingBits != 0 ||
+		len(bytes) > 0 && bytes[len(bytes)-1]&(1<<paddingBits-1) != 0 {
+		return false
+	}
+
+	out.BitLength = len(bytes)*8 - int(paddingBits)
+	out.Bytes = bytes
+	return true
+}
+
+// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
+// an error if the BIT STRING is not a whole number of bytes. This function
+// returns true on success and false on error.
+func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
+		return false
+	}
+
+	paddingBits := uint8(bytes[0])
+	if paddingBits != 0 {
+		return false
+	}
+	*out = bytes[1:]
+	return true
+}
+
+// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It returns true on success and false on error.
+func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
+	return s.ReadASN1((*String)(out), tag)
+}
+
+// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It returns true on success and false on error.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
+	var t asn1.Tag
+	if !s.ReadAnyASN1(out, &t) || t != tag {
+		return false
+	}
+	return true
+}
+
+// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It returns true on success and false on error.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
+	var t asn1.Tag
+	if !s.ReadAnyASN1Element(out, &t) || t != tag {
+		return false
+	}
+	return true
+}
+
+// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, sets outTag to its tag, and advances. It
+// returns true on success and false on error.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
+	return s.readASN1(out, outTag, true /* skip header */)
+}
+
+// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
+// (including tag and length bytes) into out, sets outTag to is tag, and
+// advances. It returns true on success and false on error.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
+	return s.readASN1(out, outTag, false /* include header */)
+}
+
+// PeekASN1Tag returns true if the next ASN.1 value on the string starts with
+// the given tag.
+func (s String) PeekASN1Tag(tag asn1.Tag) bool {
+	if len(s) == 0 {
+		return false
+	}
+	return asn1.Tag(s[0]) == tag
+}
+
+// SkipASN1 reads and discards an ASN.1 element with the given tag.
+func (s *String) SkipASN1(tag asn1.Tag) bool {
+	var unused String
+	return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
+// element (not including tag and length bytes) tagged with the given tag into
+// out. It stores whether an element with the tag was found in outPresent,
+// unless outPresent is nil. It returns true on success and false on error.
+func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
+	present := s.PeekASN1Tag(tag)
+	if outPresent != nil {
+		*outPresent = present
+	}
+	if present && !s.ReadASN1(out, tag) {
+		return false
+	}
+	return true
+}
+
+// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
+// else leaves s unchanged.
+func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
+	if !s.PeekASN1Tag(tag) {
+		return true
+	}
+	var unused String
+	return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
+// explicitly tagged with tag into out and advances. If no element with a
+// matching tag is present, it writes defaultValue into out instead. If out
+// does not point to an integer or to a big.Int, it panics. It returns true on
+// success and false on error.
+func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
+	if reflect.TypeOf(out).Kind() != reflect.Ptr {
+		panic("out is not a pointer")
+	}
+	var present bool
+	var i String
+	if !s.ReadOptionalASN1(&i, &present, tag) {
+		return false
+	}
+	if !present {
+		switch reflect.ValueOf(out).Elem().Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
+		case reflect.Struct:
+			if reflect.TypeOf(out).Elem() != bigIntType {
+				panic("invalid integer type")
+			}
+			if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
+				reflect.TypeOf(defaultValue).Elem() != bigIntType {
+				panic("out points to big.Int, but defaultValue does not")
+			}
+			out.(*big.Int).Set(defaultValue.(*big.Int))
+		default:
+			panic("invalid integer type")
+		}
+		return true
+	}
+	if !i.ReadASN1Integer(out) || !i.Empty() {
+		return false
+	}
+	return true
+}
+
+// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
+// explicitly tagged with tag into out and advances. If no element with a
+// matching tag is present, it writes defaultValue into out instead. It returns
+// true on success and false on error.
+func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
+	var present bool
+	var child String
+	if !s.ReadOptionalASN1(&child, &present, tag) {
+		return false
+	}
+	if outPresent != nil {
+		*outPresent = present
+	}
+	if present {
+		var oct String
+		if !child.ReadASN1(&oct, asn1.OCTET_STRING) || !child.Empty() {
+			return false
+		}
+		*out = oct
+	} else {
+		*out = nil
+	}
+	return true
+}
+
+// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
+// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
+func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
+	var present bool
+	var child String
+	if !s.ReadOptionalASN1(&child, &present, asn1.BOOLEAN) {
+		return false
+	}
+
+	if !present {
+		*out = defaultValue
+		return true
+	}
+
+	return s.ReadASN1Boolean(out)
+}
+
+func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
+	if len(*s) < 2 {
+		return false
+	}
+	tag, lenByte := (*s)[0], (*s)[1]
+
+	if tag&0x1f == 0x1f {
+		// ITU-T X.690 section 8.1.2
+		//
+		// An identifier octet with a tag part of 0x1f indicates a high-tag-number
+		// form identifier with two or more octets. We only support tags less than
+		// 31 (i.e. low-tag-number form, single octet identifier).
+		return false
+	}
+
+	if outTag != nil {
+		*outTag = asn1.Tag(tag)
+	}
+
+	// ITU-T X.690 section 8.1.3
+	//
+	// Bit 8 of the first length byte indicates whether the length is short- or
+	// long-form.
+	var length, headerLen uint32 // length includes headerLen
+	if lenByte&0x80 == 0 {
+		// Short-form length (section 8.1.3.4), encoded in bits 1-7.
+		length = uint32(lenByte) + 2
+		headerLen = 2
+	} else {
+		// Long-form length (section 8.1.3.5). Bits 1-7 encode the number of octets
+		// used to encode the length.
+		lenLen := lenByte & 0x7f
+		var len32 uint32
+
+		if lenLen == 0 || lenLen > 4 || len(*s) < int(2+lenLen) {
+			return false
+		}
+
+		lenBytes := String((*s)[2 : 2+lenLen])
+		if !lenBytes.readUnsigned(&len32, int(lenLen)) {
+			return false
+		}
+
+		// ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+		// with the minimum number of octets.
+		if len32 < 128 {
+			// Length should have used short-form encoding.
+			return false
+		}
+		if len32>>((lenLen-1)*8) == 0 {
+			// Leading octet is 0. Length should have been at least one byte shorter.
+			return false
+		}
+
+		headerLen = 2 + uint32(lenLen)
+		if headerLen+len32 < len32 {
+			// Overflow.
+			return false
+		}
+		length = headerLen + len32
+	}
+
+	if uint32(int(length)) != length || !s.ReadBytes((*[]byte)(out), int(length)) {
+		return false
+	}
+	if skipHeader && !out.Skip(int(headerLen)) {
+		panic("cryptobyte: internal error")
+	}
+
+	return true
+}
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/asn1/asn1.go b/src/vendor/golang_org/x/crypto/cryptobyte/asn1/asn1.go
new file mode 100644
index 0000000..cda8e3e
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/asn1/asn1.go
@@ -0,0 +1,46 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package asn1 contains supporting types for parsing and building ASN.1
+// messages with the cryptobyte package.
+package asn1 // import "golang.org/x/crypto/cryptobyte/asn1"
+
+// Tag represents an ASN.1 identifier octet, consisting of a tag number
+// (indicating a type) and class (such as context-specific or constructed).
+//
+// Methods in the cryptobyte package only support the low-tag-number form, i.e.
+// a single identifier octet with bits 7-8 encoding the class and bits 1-6
+// encoding the tag number.
+type Tag uint8
+
+const (
+	classConstructed     = 0x20
+	classContextSpecific = 0x80
+)
+
+// Constructed returns t with the constructed class bit set.
+func (t Tag) Constructed() Tag { return t | classConstructed }
+
+// ContextSpecific returns t with the context-specific class bit set.
+func (t Tag) ContextSpecific() Tag { return t | classContextSpecific }
+
+// The following is a list of standard tag and class combinations.
+const (
+	BOOLEAN           = Tag(1)
+	INTEGER           = Tag(2)
+	BIT_STRING        = Tag(3)
+	OCTET_STRING      = Tag(4)
+	NULL              = Tag(5)
+	OBJECT_IDENTIFIER = Tag(6)
+	ENUM              = Tag(10)
+	UTF8String        = Tag(12)
+	SEQUENCE          = Tag(16 | classConstructed)
+	SET               = Tag(17 | classConstructed)
+	PrintableString   = Tag(19)
+	T61String         = Tag(20)
+	IA5String         = Tag(22)
+	UTCTime           = Tag(23)
+	GeneralizedTime   = Tag(24)
+	GeneralString     = Tag(27)
+)
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/asn1_test.go b/src/vendor/golang_org/x/crypto/cryptobyte/asn1_test.go
new file mode 100644
index 0000000..59e562d
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/asn1_test.go
@@ -0,0 +1,300 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	"bytes"
+	encoding_asn1 "encoding/asn1"
+	"math/big"
+	"reflect"
+	"testing"
+	"time"
+
+	"golang_org/x/crypto/cryptobyte/asn1"
+)
+
+type readASN1Test struct {
+	name string
+	in   []byte
+	tag  asn1.Tag
+	ok   bool
+	out  interface{}
+}
+
+var readASN1TestData = []readASN1Test{
+	{"valid", []byte{0x30, 2, 1, 2}, 0x30, true, []byte{1, 2}},
+	{"truncated", []byte{0x30, 3, 1, 2}, 0x30, false, nil},
+	{"zero length of length", []byte{0x30, 0x80}, 0x30, false, nil},
+	{"invalid long form length", []byte{0x30, 0x81, 1, 1}, 0x30, false, nil},
+	{"non-minimal length", append([]byte{0x30, 0x82, 0, 0x80}, make([]byte, 0x80)...), 0x30, false, nil},
+	{"invalid tag", []byte{0xa1, 3, 0x4, 1, 1}, 31, false, nil},
+	{"high tag", []byte{0x1f, 0x81, 0x80, 0x01, 2, 1, 2}, 0xff /* actually 0x4001, but tag is uint8 */, false, nil},
+}
+
+func TestReadASN1(t *testing.T) {
+	for _, test := range readASN1TestData {
+		t.Run(test.name, func(t *testing.T) {
+			var in, out String = test.in, nil
+			ok := in.ReadASN1(&out, test.tag)
+			if ok != test.ok || ok && !bytes.Equal(out, test.out.([]byte)) {
+				t.Errorf("in.ReadASN1() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
+			}
+		})
+	}
+}
+
+func TestReadASN1Optional(t *testing.T) {
+	var empty String
+	var present bool
+	ok := empty.ReadOptionalASN1(nil, &present, 0xa0)
+	if !ok || present {
+		t.Errorf("empty.ReadOptionalASN1() = %v, want true; present = %v want false", ok, present)
+	}
+
+	var in, out String = []byte{0xa1, 3, 0x4, 1, 1}, nil
+	ok = in.ReadOptionalASN1(&out, &present, 0xa0)
+	if !ok || present {
+		t.Errorf("in.ReadOptionalASN1() = %v, want true, present = %v, want false", ok, present)
+	}
+	ok = in.ReadOptionalASN1(&out, &present, 0xa1)
+	wantBytes := []byte{4, 1, 1}
+	if !ok || !present || !bytes.Equal(out, wantBytes) {
+		t.Errorf("in.ReadOptionalASN1() = %v, want true; present = %v, want true; out = %v, want = %v", ok, present, out, wantBytes)
+	}
+}
+
+var optionalOctetStringTestData = []struct {
+	readASN1Test
+	present bool
+}{
+	{readASN1Test{"empty", []byte{}, 0xa0, true, []byte{}}, false},
+	{readASN1Test{"invalid", []byte{0xa1, 3, 0x4, 2, 1}, 0xa1, false, []byte{}}, true},
+	{readASN1Test{"missing", []byte{0xa1, 3, 0x4, 1, 1}, 0xa0, true, []byte{}}, false},
+	{readASN1Test{"present", []byte{0xa1, 3, 0x4, 1, 1}, 0xa1, true, []byte{1}}, true},
+}
+
+func TestReadASN1OptionalOctetString(t *testing.T) {
+	for _, test := range optionalOctetStringTestData {
+		t.Run(test.name, func(t *testing.T) {
+			in := String(test.in)
+			var out []byte
+			var present bool
+			ok := in.ReadOptionalASN1OctetString(&out, &present, test.tag)
+			if ok != test.ok || present != test.present || !bytes.Equal(out, test.out.([]byte)) {
+				t.Errorf("in.ReadOptionalASN1OctetString() = %v, want %v; present = %v want %v; out = %v, want %v", ok, test.ok, present, test.present, out, test.out)
+			}
+		})
+	}
+}
+
+const defaultInt = -1
+
+var optionalIntTestData = []readASN1Test{
+	{"empty", []byte{}, 0xa0, true, defaultInt},
+	{"invalid", []byte{0xa1, 3, 0x2, 2, 127}, 0xa1, false, 0},
+	{"missing", []byte{0xa1, 3, 0x2, 1, 127}, 0xa0, true, defaultInt},
+	{"present", []byte{0xa1, 3, 0x2, 1, 42}, 0xa1, true, 42},
+}
+
+func TestReadASN1OptionalInteger(t *testing.T) {
+	for _, test := range optionalIntTestData {
+		t.Run(test.name, func(t *testing.T) {
+			in := String(test.in)
+			var out int
+			ok := in.ReadOptionalASN1Integer(&out, test.tag, defaultInt)
+			if ok != test.ok || ok && out != test.out.(int) {
+				t.Errorf("in.ReadOptionalASN1Integer() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
+			}
+		})
+	}
+}
+
+func TestReadASN1IntegerSigned(t *testing.T) {
+	testData64 := []struct {
+		in  []byte
+		out int64
+	}{
+		{[]byte{2, 3, 128, 0, 0}, -0x800000},
+		{[]byte{2, 2, 255, 0}, -256},
+		{[]byte{2, 2, 255, 127}, -129},
+		{[]byte{2, 1, 128}, -128},
+		{[]byte{2, 1, 255}, -1},
+		{[]byte{2, 1, 0}, 0},
+		{[]byte{2, 1, 1}, 1},
+		{[]byte{2, 1, 2}, 2},
+		{[]byte{2, 1, 127}, 127},
+		{[]byte{2, 2, 0, 128}, 128},
+		{[]byte{2, 2, 1, 0}, 256},
+		{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
+	}
+	for i, test := range testData64 {
+		in := String(test.in)
+		var out int64
+		ok := in.ReadASN1Integer(&out)
+		if !ok || out != test.out {
+			t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
+		}
+	}
+
+	// Repeat the same cases, reading into a big.Int.
+	t.Run("big.Int", func(t *testing.T) {
+		for i, test := range testData64 {
+			in := String(test.in)
+			var out big.Int
+			ok := in.ReadASN1Integer(&out)
+			if !ok || out.Int64() != test.out {
+				t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out.Int64(), test.out)
+			}
+		}
+	})
+}
+
+func TestReadASN1IntegerUnsigned(t *testing.T) {
+	testData := []struct {
+		in  []byte
+		out uint64
+	}{
+		{[]byte{2, 1, 0}, 0},
+		{[]byte{2, 1, 1}, 1},
+		{[]byte{2, 1, 2}, 2},
+		{[]byte{2, 1, 127}, 127},
+		{[]byte{2, 2, 0, 128}, 128},
+		{[]byte{2, 2, 1, 0}, 256},
+		{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
+		{[]byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}, 0x7fffffffffffffff},
+		{[]byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}, 0x8000000000000000},
+		{[]byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}, 0xffffffffffffffff},
+	}
+	for i, test := range testData {
+		in := String(test.in)
+		var out uint64
+		ok := in.ReadASN1Integer(&out)
+		if !ok || out != test.out {
+			t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
+		}
+	}
+}
+
+func TestReadASN1IntegerInvalid(t *testing.T) {
+	testData := []String{
+		[]byte{3, 1, 0}, // invalid tag
+		// truncated
+		[]byte{2, 1},
+		[]byte{2, 2, 0},
+		// not minimally encoded
+		[]byte{2, 2, 0, 1},
+		[]byte{2, 2, 0xff, 0xff},
+	}
+
+	for i, test := range testData {
+		var out int64
+		if test.ReadASN1Integer(&out) {
+			t.Errorf("#%d: in.ReadASN1Integer() = true, want false (out = %d)", i, out)
+		}
+	}
+}
+
+func TestASN1ObjectIdentifier(t *testing.T) {
+	testData := []struct {
+		in  []byte
+		ok  bool
+		out []int
+	}{
+		{[]byte{}, false, []int{}},
+		{[]byte{6, 0}, false, []int{}},
+		{[]byte{5, 1, 85}, false, []int{2, 5}},
+		{[]byte{6, 1, 85}, true, []int{2, 5}},
+		{[]byte{6, 2, 85, 0x02}, true, []int{2, 5, 2}},
+		{[]byte{6, 4, 85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
+		{[]byte{6, 3, 0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
+		{[]byte{6, 7, 85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
+	}
+
+	for i, test := range testData {
+		in := String(test.in)
+		var out encoding_asn1.ObjectIdentifier
+		ok := in.ReadASN1ObjectIdentifier(&out)
+		if ok != test.ok || ok && !out.Equal(test.out) {
+			t.Errorf("#%d: in.ReadASN1ObjectIdentifier() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
+			continue
+		}
+
+		var b Builder
+		b.AddASN1ObjectIdentifier(out)
+		result, err := b.Bytes()
+		if builderOk := err == nil; test.ok != builderOk {
+			t.Errorf("#%d: error from Builder.Bytes: %s", i, err)
+			continue
+		}
+		if test.ok && !bytes.Equal(result, test.in) {
+			t.Errorf("#%d: reserialisation didn't match, got %x, want %x", i, result, test.in)
+			continue
+		}
+	}
+}
+
+func TestReadASN1GeneralizedTime(t *testing.T) {
+	testData := []struct {
+		in  string
+		ok  bool
+		out time.Time
+	}{
+		{"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))},
+		/* These are invalid times. However, the time package normalises times
+		 * and they were accepted in some versions. See #11134. */
+		{"00000100000000Z", false, time.Time{}},
+		{"20101302030405Z", false, time.Time{}},
+		{"20100002030405Z", false, time.Time{}},
+		{"20100100030405Z", false, time.Time{}},
+		{"20100132030405Z", false, time.Time{}},
+		{"20100231030405Z", false, time.Time{}},
+		{"20100102240405Z", false, time.Time{}},
+		{"20100102036005Z", false, time.Time{}},
+		{"20100102030460Z", false, time.Time{}},
+		{"-20100102030410Z", false, time.Time{}},
+		{"2010-0102030410Z", false, time.Time{}},
+		{"2010-0002030410Z", false, time.Time{}},
+		{"201001-02030410Z", false, time.Time{}},
+		{"20100102-030410Z", false, time.Time{}},
+		{"2010010203-0410Z", false, time.Time{}},
+		{"201001020304-10Z", false, time.Time{}},
+	}
+	for i, test := range testData {
+		in := String(append([]byte{byte(asn1.GeneralizedTime), byte(len(test.in))}, test.in...))
+		var out time.Time
+		ok := in.ReadASN1GeneralizedTime(&out)
+		if ok != test.ok || ok && !reflect.DeepEqual(out, test.out) {
+			t.Errorf("#%d: in.ReadASN1GeneralizedTime() = %v, want %v; out = %q, want %q", i, ok, test.ok, out, test.out)
+		}
+	}
+}
+
+func TestReadASN1BitString(t *testing.T) {
+	testData := []struct {
+		in  []byte
+		ok  bool
+		out encoding_asn1.BitString
+	}{
+		{[]byte{}, false, encoding_asn1.BitString{}},
+		{[]byte{0x00}, true, encoding_asn1.BitString{}},
+		{[]byte{0x07, 0x00}, true, encoding_asn1.BitString{Bytes: []byte{0}, BitLength: 1}},
+		{[]byte{0x07, 0x01}, false, encoding_asn1.BitString{}},
+		{[]byte{0x07, 0x40}, false, encoding_asn1.BitString{}},
+		{[]byte{0x08, 0x00}, false, encoding_asn1.BitString{}},
+		{[]byte{0xff}, false, encoding_asn1.BitString{}},
+		{[]byte{0xfe, 0x00}, false, encoding_asn1.BitString{}},
+	}
+	for i, test := range testData {
+		in := String(append([]byte{3, byte(len(test.in))}, test.in...))
+		var out encoding_asn1.BitString
+		ok := in.ReadASN1BitString(&out)
+		if ok != test.ok || ok && (!bytes.Equal(out.Bytes, test.out.Bytes) || out.BitLength != test.out.BitLength) {
+			t.Errorf("#%d: in.ReadASN1BitString() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
+		}
+	}
+}
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/builder.go b/src/vendor/golang_org/x/crypto/cryptobyte/builder.go
new file mode 100644
index 0000000..29b4c76
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/builder.go
@@ -0,0 +1,309 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	"errors"
+	"fmt"
+)
+
+// A Builder builds byte strings from fixed-length and length-prefixed values.
+// Builders either allocate space as needed, or are ‘fixed’, which means that
+// they write into a given buffer and produce an error if it's exhausted.
+//
+// The zero value is a usable Builder that allocates space as needed.
+//
+// Simple values are marshaled and appended to a Builder using methods on the
+// Builder. Length-prefixed values are marshaled by providing a
+// BuilderContinuation, which is a function that writes the inner contents of
+// the value to a given Builder. See the documentation for BuilderContinuation
+// for details.
+type Builder struct {
+	err            error
+	result         []byte
+	fixedSize      bool
+	child          *Builder
+	offset         int
+	pendingLenLen  int
+	pendingIsASN1  bool
+	inContinuation *bool
+}
+
+// NewBuilder creates a Builder that appends its output to the given buffer.
+// Like append(), the slice will be reallocated if its capacity is exceeded.
+// Use Bytes to get the final buffer.
+func NewBuilder(buffer []byte) *Builder {
+	return &Builder{
+		result: buffer,
+	}
+}
+
+// NewFixedBuilder creates a Builder that appends its output into the given
+// buffer. This builder does not reallocate the output buffer. Writes that
+// would exceed the buffer's capacity are treated as an error.
+func NewFixedBuilder(buffer []byte) *Builder {
+	return &Builder{
+		result:    buffer,
+		fixedSize: true,
+	}
+}
+
+// Bytes returns the bytes written by the builder or an error if one has
+// occurred during during building.
+func (b *Builder) Bytes() ([]byte, error) {
+	if b.err != nil {
+		return nil, b.err
+	}
+	return b.result[b.offset:], nil
+}
+
+// BytesOrPanic returns the bytes written by the builder or panics if an error
+// has occurred during building.
+func (b *Builder) BytesOrPanic() []byte {
+	if b.err != nil {
+		panic(b.err)
+	}
+	return b.result[b.offset:]
+}
+
+// AddUint8 appends an 8-bit value to the byte string.
+func (b *Builder) AddUint8(v uint8) {
+	b.add(byte(v))
+}
+
+// AddUint16 appends a big-endian, 16-bit value to the byte string.
+func (b *Builder) AddUint16(v uint16) {
+	b.add(byte(v>>8), byte(v))
+}
+
+// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest
+// byte of the 32-bit input value is silently truncated.
+func (b *Builder) AddUint24(v uint32) {
+	b.add(byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint32 appends a big-endian, 32-bit value to the byte string.
+func (b *Builder) AddUint32(v uint32) {
+	b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddBytes appends a sequence of bytes to the byte string.
+func (b *Builder) AddBytes(v []byte) {
+	b.add(v...)
+}
+
+// BuilderContinuation is continuation-passing interface for building
+// length-prefixed byte sequences. Builder methods for length-prefixed
+// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
+// supplied to them. The child builder passed to the continuation can be used
+// to build the content of the length-prefixed sequence. For example:
+//
+//   parent := cryptobyte.NewBuilder()
+//   parent.AddUint8LengthPrefixed(func (child *Builder) {
+//     child.AddUint8(42)
+//     child.AddUint8LengthPrefixed(func (grandchild *Builder) {
+//       grandchild.AddUint8(5)
+//     })
+//   })
+//
+// It is an error to write more bytes to the child than allowed by the reserved
+// length prefix. After the continuation returns, the child must be considered
+// invalid, i.e. users must not store any copies or references of the child
+// that outlive the continuation.
+//
+// If the continuation panics with a value of type BuildError then the inner
+// error will be returned as the error from Bytes. If the child panics
+// otherwise then Bytes will repanic with the same value.
+type BuilderContinuation func(child *Builder)
+
+// BuildError wraps an error. If a BuilderContinuation panics with this value,
+// the panic will be recovered and the inner error will be returned from
+// Builder.Bytes.
+type BuildError struct {
+	Err error
+}
+
+// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
+func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(1, false, f)
+}
+
+// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence.
+func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(2, false, f)
+}
+
+// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence.
+func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(3, false, f)
+}
+
+// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence.
+func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(4, false, f)
+}
+
+func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) {
+	if !*b.inContinuation {
+		*b.inContinuation = true
+
+		defer func() {
+			*b.inContinuation = false
+
+			r := recover()
+			if r == nil {
+				return
+			}
+
+			if buildError, ok := r.(BuildError); ok {
+				b.err = buildError.Err
+			} else {
+				panic(r)
+			}
+		}()
+	}
+
+	f(arg)
+}
+
+func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
+	// Subsequent writes can be ignored if the builder has encountered an error.
+	if b.err != nil {
+		return
+	}
+
+	offset := len(b.result)
+	b.add(make([]byte, lenLen)...)
+
+	if b.inContinuation == nil {
+		b.inContinuation = new(bool)
+	}
+
+	b.child = &Builder{
+		result:         b.result,
+		fixedSize:      b.fixedSize,
+		offset:         offset,
+		pendingLenLen:  lenLen,
+		pendingIsASN1:  isASN1,
+		inContinuation: b.inContinuation,
+	}
+
+	b.callContinuation(f, b.child)
+	b.flushChild()
+	if b.child != nil {
+		panic("cryptobyte: internal error")
+	}
+}
+
+func (b *Builder) flushChild() {
+	if b.child == nil {
+		return
+	}
+	b.child.flushChild()
+	child := b.child
+	b.child = nil
+
+	if child.err != nil {
+		b.err = child.err
+		return
+	}
+
+	length := len(child.result) - child.pendingLenLen - child.offset
+
+	if length < 0 {
+		panic("cryptobyte: internal error") // result unexpectedly shrunk
+	}
+
+	if child.pendingIsASN1 {
+		// For ASN.1, we reserved a single byte for the length. If that turned out
+		// to be incorrect, we have to move the contents along in order to make
+		// space.
+		if child.pendingLenLen != 1 {
+			panic("cryptobyte: internal error")
+		}
+		var lenLen, lenByte uint8
+		if int64(length) > 0xfffffffe {
+			b.err = errors.New("pending ASN.1 child too long")
+			return
+		} else if length > 0xffffff {
+			lenLen = 5
+			lenByte = 0x80 | 4
+		} else if length > 0xffff {
+			lenLen = 4
+			lenByte = 0x80 | 3
+		} else if length > 0xff {
+			lenLen = 3
+			lenByte = 0x80 | 2
+		} else if length > 0x7f {
+			lenLen = 2
+			lenByte = 0x80 | 1
+		} else {
+			lenLen = 1
+			lenByte = uint8(length)
+			length = 0
+		}
+
+		// Insert the initial length byte, make space for successive length bytes,
+		// and adjust the offset.
+		child.result[child.offset] = lenByte
+		extraBytes := int(lenLen - 1)
+		if extraBytes != 0 {
+			child.add(make([]byte, extraBytes)...)
+			childStart := child.offset + child.pendingLenLen
+			copy(child.result[childStart+extraBytes:], child.result[childStart:])
+		}
+		child.offset++
+		child.pendingLenLen = extraBytes
+	}
+
+	l := length
+	for i := child.pendingLenLen - 1; i >= 0; i-- {
+		child.result[child.offset+i] = uint8(l)
+		l >>= 8
+	}
+	if l != 0 {
+		b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen)
+		return
+	}
+
+	if !b.fixedSize {
+		b.result = child.result // In case child reallocated result.
+	}
+}
+
+func (b *Builder) add(bytes ...byte) {
+	if b.err != nil {
+		return
+	}
+	if b.child != nil {
+		panic("attempted write while child is pending")
+	}
+	if len(b.result)+len(bytes) < len(bytes) {
+		b.err = errors.New("cryptobyte: length overflow")
+	}
+	if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) {
+		b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer")
+		return
+	}
+	b.result = append(b.result, bytes...)
+}
+
+// A MarshalingValue marshals itself into a Builder.
+type MarshalingValue interface {
+	// Marshal is called by Builder.AddValue. It receives a pointer to a builder
+	// to marshal itself into. It may return an error that occurred during
+	// marshaling, such as unset or invalid values.
+	Marshal(b *Builder) error
+}
+
+// AddValue calls Marshal on v, passing a pointer to the builder to append to.
+// If Marshal returns an error, it is set on the Builder so that subsequent
+// appends don't have an effect.
+func (b *Builder) AddValue(v MarshalingValue) {
+	err := v.Marshal(b)
+	if err != nil {
+		b.err = err
+	}
+}
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/cryptobyte_test.go b/src/vendor/golang_org/x/crypto/cryptobyte/cryptobyte_test.go
new file mode 100644
index 0000000..f294dd5
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/cryptobyte_test.go
@@ -0,0 +1,428 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"testing"
+)
+
+func builderBytesEq(b *Builder, want ...byte) error {
+	got := b.BytesOrPanic()
+	if !bytes.Equal(got, want) {
+		return fmt.Errorf("Bytes() = %v, want %v", got, want)
+	}
+	return nil
+}
+
+func TestContinuationError(t *testing.T) {
+	const errorStr = "TestContinuationError"
+	var b Builder
+	b.AddUint8LengthPrefixed(func(b *Builder) {
+		b.AddUint8(1)
+		panic(BuildError{Err: errors.New(errorStr)})
+	})
+
+	ret, err := b.Bytes()
+	if ret != nil {
+		t.Error("expected nil result")
+	}
+	if err == nil {
+		t.Fatal("unexpected nil error")
+	}
+	if s := err.Error(); s != errorStr {
+		t.Errorf("expected error %q, got %v", errorStr, s)
+	}
+}
+
+func TestContinuationNonError(t *testing.T) {
+	defer func() {
+		recover()
+	}()
+
+	var b Builder
+	b.AddUint8LengthPrefixed(func(b *Builder) {
+		b.AddUint8(1)
+		panic(1)
+	})
+
+	t.Error("Builder did not panic")
+}
+
+func TestGeneratedPanic(t *testing.T) {
+	defer func() {
+		recover()
+	}()
+
+	var b Builder
+	b.AddUint8LengthPrefixed(func(b *Builder) {
+		var p *byte
+		*p = 0
+	})
+
+	t.Error("Builder did not panic")
+}
+
+func TestBytes(t *testing.T) {
+	var b Builder
+	v := []byte("foobarbaz")
+	b.AddBytes(v[0:3])
+	b.AddBytes(v[3:4])
+	b.AddBytes(v[4:9])
+	if err := builderBytesEq(&b, v...); err != nil {
+		t.Error(err)
+	}
+	s := String(b.BytesOrPanic())
+	for _, w := range []string{"foo", "bar", "baz"} {
+		var got []byte
+		if !s.ReadBytes(&got, 3) {
+			t.Errorf("ReadBytes() = false, want true (w = %v)", w)
+		}
+		want := []byte(w)
+		if !bytes.Equal(got, want) {
+			t.Errorf("ReadBytes(): got = %v, want %v", got, want)
+		}
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUint8(t *testing.T) {
+	var b Builder
+	b.AddUint8(42)
+	if err := builderBytesEq(&b, 42); err != nil {
+		t.Error(err)
+	}
+
+	var s String = b.BytesOrPanic()
+	var v uint8
+	if !s.ReadUint8(&v) {
+		t.Error("ReadUint8() = false, want true")
+	}
+	if v != 42 {
+		t.Errorf("v = %d, want 42", v)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUint16(t *testing.T) {
+	var b Builder
+	b.AddUint16(65534)
+	if err := builderBytesEq(&b, 255, 254); err != nil {
+		t.Error(err)
+	}
+	var s String = b.BytesOrPanic()
+	var v uint16
+	if !s.ReadUint16(&v) {
+		t.Error("ReadUint16() == false, want true")
+	}
+	if v != 65534 {
+		t.Errorf("v = %d, want 65534", v)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUint24(t *testing.T) {
+	var b Builder
+	b.AddUint24(0xfffefd)
+	if err := builderBytesEq(&b, 255, 254, 253); err != nil {
+		t.Error(err)
+	}
+
+	var s String = b.BytesOrPanic()
+	var v uint32
+	if !s.ReadUint24(&v) {
+		t.Error("ReadUint8() = false, want true")
+	}
+	if v != 0xfffefd {
+		t.Errorf("v = %d, want fffefd", v)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUint24Truncation(t *testing.T) {
+	var b Builder
+	b.AddUint24(0x10111213)
+	if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestUint32(t *testing.T) {
+	var b Builder
+	b.AddUint32(0xfffefdfc)
+	if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil {
+		t.Error(err)
+	}
+
+	var s String = b.BytesOrPanic()
+	var v uint32
+	if !s.ReadUint32(&v) {
+		t.Error("ReadUint8() = false, want true")
+	}
+	if v != 0xfffefdfc {
+		t.Errorf("v = %x, want fffefdfc", v)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUMultiple(t *testing.T) {
+	var b Builder
+	b.AddUint8(23)
+	b.AddUint32(0xfffefdfc)
+	b.AddUint16(42)
+	if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil {
+		t.Error(err)
+	}
+
+	var s String = b.BytesOrPanic()
+	var (
+		x uint8
+		y uint32
+		z uint16
+	)
+	if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) {
+		t.Error("ReadUint8() = false, want true")
+	}
+	if x != 23 || y != 0xfffefdfc || z != 42 {
+		t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+}
+
+func TestUint8LengthPrefixedSimple(t *testing.T) {
+	var b Builder
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8(23)
+		c.AddUint8(42)
+	})
+	if err := builderBytesEq(&b, 2, 23, 42); err != nil {
+		t.Error(err)
+	}
+
+	var base, child String = b.BytesOrPanic(), nil
+	var x, y uint8
+	if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) ||
+		!child.ReadUint8(&y) {
+		t.Error("parsing failed")
+	}
+	if x != 23 || y != 42 {
+		t.Errorf("want x, y == 23, 42; got %d, %d", x, y)
+	}
+	if len(base) != 0 {
+		t.Errorf("len(base) = %d, want 0", len(base))
+	}
+	if len(child) != 0 {
+		t.Errorf("len(child) = %d, want 0", len(child))
+	}
+}
+
+func TestUint8LengthPrefixedMulti(t *testing.T) {
+	var b Builder
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8(23)
+		c.AddUint8(42)
+	})
+	b.AddUint8(5)
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8(123)
+		c.AddUint8(234)
+	})
+	if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil {
+		t.Error(err)
+	}
+
+	var s, child String = b.BytesOrPanic(), nil
+	var u, v, w, x, y uint8
+	if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) ||
+		!s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) {
+		t.Error("parsing failed")
+	}
+	if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 {
+		t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234",
+			u, v, w, x, y)
+	}
+	if len(s) != 0 {
+		t.Errorf("len(s) = %d, want 0", len(s))
+	}
+	if len(child) != 0 {
+		t.Errorf("len(child) = %d, want 0", len(child))
+	}
+}
+
+func TestUint8LengthPrefixedNested(t *testing.T) {
+	var b Builder
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8(5)
+		c.AddUint8LengthPrefixed(func(d *Builder) {
+			d.AddUint8(23)
+			d.AddUint8(42)
+		})
+		c.AddUint8(123)
+	})
+	if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil {
+		t.Error(err)
+	}
+
+	var base, child1, child2 String = b.BytesOrPanic(), nil, nil
+	var u, v, w, x uint8
+	if !base.ReadUint8LengthPrefixed(&child1) {
+		t.Error("parsing base failed")
+	}
+	if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) {
+		t.Error("parsing child1 failed")
+	}
+	if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) {
+		t.Error("parsing child2 failed")
+	}
+	if u != 5 || v != 23 || w != 42 || x != 123 {
+		t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123",
+			u, v, w, x)
+	}
+	if len(base) != 0 {
+		t.Errorf("len(base) = %d, want 0", len(base))
+	}
+	if len(child1) != 0 {
+		t.Errorf("len(child1) = %d, want 0", len(child1))
+	}
+	if len(base) != 0 {
+		t.Errorf("len(child2) = %d, want 0", len(child2))
+	}
+}
+
+func TestPreallocatedBuffer(t *testing.T) {
+	var buf [5]byte
+	b := NewBuilder(buf[0:0])
+	b.AddUint8(1)
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8(3)
+		c.AddUint8(4)
+	})
+	b.AddUint16(1286) // Outgrow buf by one byte.
+	want := []byte{1, 2, 3, 4, 0}
+	if !bytes.Equal(buf[:], want) {
+		t.Errorf("buf = %v want %v", buf, want)
+	}
+	if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestWriteWithPendingChild(t *testing.T) {
+	var b Builder
+	b.AddUint8LengthPrefixed(func(c *Builder) {
+		c.AddUint8LengthPrefixed(func(d *Builder) {
+			defer func() {
+				if recover() == nil {
+					t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
+				}
+			}()
+			c.AddUint8(2) // panics
+
+			defer func() {
+				if recover() == nil {
+					t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
+				}
+			}()
+			b.AddUint8(2) // panics
+		})
+
+		defer func() {
+			if recover() == nil {
+				t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
+			}
+		}()
+		b.AddUint8(2) // panics
+	})
+}
+
+// ASN.1
+
+func TestASN1Int64(t *testing.T) {
+	tests := []struct {
+		in   int64
+		want []byte
+	}{
+		{-0x800000, []byte{2, 3, 128, 0, 0}},
+		{-256, []byte{2, 2, 255, 0}},
+		{-129, []byte{2, 2, 255, 127}},
+		{-128, []byte{2, 1, 128}},
+		{-1, []byte{2, 1, 255}},
+		{0, []byte{2, 1, 0}},
+		{1, []byte{2, 1, 1}},
+		{2, []byte{2, 1, 2}},
+		{127, []byte{2, 1, 127}},
+		{128, []byte{2, 2, 0, 128}},
+		{256, []byte{2, 2, 1, 0}},
+		{0x800000, []byte{2, 4, 0, 128, 0, 0}},
+	}
+	for i, tt := range tests {
+		var b Builder
+		b.AddASN1Int64(tt.in)
+		if err := builderBytesEq(&b, tt.want...); err != nil {
+			t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
+		}
+
+		var n int64
+		s := String(b.BytesOrPanic())
+		ok := s.ReadASN1Integer(&n)
+		if !ok || n != tt.in {
+			t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
+				ok, n, tt.in, i)
+		}
+		if len(s) != 0 {
+			t.Errorf("len(s) = %d, want 0", len(s))
+		}
+	}
+}
+
+func TestASN1Uint64(t *testing.T) {
+	tests := []struct {
+		in   uint64
+		want []byte
+	}{
+		{0, []byte{2, 1, 0}},
+		{1, []byte{2, 1, 1}},
+		{2, []byte{2, 1, 2}},
+		{127, []byte{2, 1, 127}},
+		{128, []byte{2, 2, 0, 128}},
+		{256, []byte{2, 2, 1, 0}},
+		{0x800000, []byte{2, 4, 0, 128, 0, 0}},
+		{0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}},
+		{0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}},
+		{0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
+	}
+	for i, tt := range tests {
+		var b Builder
+		b.AddASN1Uint64(tt.in)
+		if err := builderBytesEq(&b, tt.want...); err != nil {
+			t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
+		}
+
+		var n uint64
+		s := String(b.BytesOrPanic())
+		ok := s.ReadASN1Integer(&n)
+		if !ok || n != tt.in {
+			t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
+				ok, n, tt.in, i)
+		}
+		if len(s) != 0 {
+			t.Errorf("len(s) = %d, want 0", len(s))
+		}
+	}
+}
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/example_test.go b/src/vendor/golang_org/x/crypto/cryptobyte/example_test.go
new file mode 100644
index 0000000..056c230
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/example_test.go
@@ -0,0 +1,154 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte_test
+
+import (
+	"errors"
+	"fmt"
+
+	"golang_org/x/crypto/cryptobyte"
+	"golang_org/x/crypto/cryptobyte/asn1"
+)
+
+func ExampleString_lengthPrefixed() {
+	// This is an example of parsing length-prefixed data (as found in, for
+	// example, TLS). Imagine a 16-bit prefixed series of 8-bit prefixed
+	// strings.
+
+	input := cryptobyte.String([]byte{0, 12, 5, 'h', 'e', 'l', 'l', 'o', 5, 'w', 'o', 'r', 'l', 'd'})
+	var result []string
+
+	var values cryptobyte.String
+	if !input.ReadUint16LengthPrefixed(&values) ||
+		!input.Empty() {
+		panic("bad format")
+	}
+
+	for !values.Empty() {
+		var value cryptobyte.String
+		if !values.ReadUint8LengthPrefixed(&value) {
+			panic("bad format")
+		}
+
+		result = append(result, string(value))
+	}
+
+	// Output: []string{"hello", "world"}
+	fmt.Printf("%#v\n", result)
+}
+
+func ExampleString_aSN1() {
+	// This is an example of parsing ASN.1 data that looks like:
+	//    Foo ::= SEQUENCE {
+	//      version [6] INTEGER DEFAULT 0
+	//      data OCTET STRING
+	//    }
+
+	input := cryptobyte.String([]byte{0x30, 12, 0xa6, 3, 2, 1, 2, 4, 5, 'h', 'e', 'l', 'l', 'o'})
+
+	var (
+		version                   int64
+		data, inner, versionBytes cryptobyte.String
+		haveVersion               bool
+	)
+	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+		!input.Empty() ||
+		!inner.ReadOptionalASN1(&versionBytes, &haveVersion, asn1.Tag(6).Constructed().ContextSpecific()) ||
+		(haveVersion && !versionBytes.ReadASN1Integer(&version)) ||
+		(haveVersion && !versionBytes.Empty()) ||
+		!inner.ReadASN1(&data, asn1.OCTET_STRING) ||
+		!inner.Empty() {
+		panic("bad format")
+	}
+
+	// Output: haveVersion: true, version: 2, data: hello
+	fmt.Printf("haveVersion: %t, version: %d, data: %s\n", haveVersion, version, string(data))
+}
+
+func ExampleBuilder_aSN1() {
+	// This is an example of building ASN.1 data that looks like:
+	//    Foo ::= SEQUENCE {
+	//      version [6] INTEGER DEFAULT 0
+	//      data OCTET STRING
+	//    }
+
+	version := int64(2)
+	data := []byte("hello")
+	const defaultVersion = 0
+
+	var b cryptobyte.Builder
+	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+		if version != defaultVersion {
+			b.AddASN1(asn1.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
+				b.AddASN1Int64(version)
+			})
+		}
+		b.AddASN1OctetString(data)
+	})
+
+	result, err := b.Bytes()
+	if err != nil {
+		panic(err)
+	}
+
+	// Output: 300ca603020102040568656c6c6f
+	fmt.Printf("%x\n", result)
+}
+
+func ExampleBuilder_lengthPrefixed() {
+	// This is an example of building length-prefixed data (as found in,
+	// for example, TLS). Imagine a 16-bit prefixed series of 8-bit
+	// prefixed strings.
+	input := []string{"hello", "world"}
+
+	var b cryptobyte.Builder
+	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+		for _, value := range input {
+			b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+				b.AddBytes([]byte(value))
+			})
+		}
+	})
+
+	result, err := b.Bytes()
+	if err != nil {
+		panic(err)
+	}
+
+	// Output: 000c0568656c6c6f05776f726c64
+	fmt.Printf("%x\n", result)
+}
+
+func ExampleBuilder_lengthPrefixOverflow() {
+	// Writing more data that can be expressed by the length prefix results
+	// in an error from Bytes().
+
+	tooLarge := make([]byte, 256)
+
+	var b cryptobyte.Builder
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(tooLarge)
+	})
+
+	result, err := b.Bytes()
+	fmt.Printf("len=%d err=%s\n", len(result), err)
+
+	// Output: len=0 err=cryptobyte: pending child length 256 exceeds 1-byte length prefix
+}
+
+func ExampleBuilderContinuation_errorHandling() {
+	var b cryptobyte.Builder
+	// Continuations that panic with a BuildError will cause Bytes to
+	// return the inner error.
+	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddUint32(0)
+		panic(cryptobyte.BuildError{Err: errors.New("example error")})
+	})
+
+	result, err := b.Bytes()
+	fmt.Printf("len=%d err=%s\n", len(result), err)
+
+	// Output: len=0 err=example error
+}
diff --git a/src/vendor/golang_org/x/crypto/cryptobyte/string.go b/src/vendor/golang_org/x/crypto/cryptobyte/string.go
new file mode 100644
index 0000000..7636fb9
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/cryptobyte/string.go
@@ -0,0 +1,167 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cryptobyte contains types that help with parsing and constructing
+// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage
+// contains useful ASN.1 constants.)
+//
+// The String type is for parsing. It wraps a []byte slice and provides helper
+// functions for consuming structures, value by value.
+//
+// The Builder type is for constructing messages. It providers helper functions
+// for appending values and also for appending length-prefixed submessages –
+// without having to worry about calculating the length prefix ahead of time.
+//
+// See the documentation and examples for the Builder and String types to get
+// started.
+package cryptobyte // import "golang.org/x/crypto/cryptobyte"
+
+// String represents a string of bytes. It provides methods for parsing
+// fixed-length and length-prefixed values from it.
+type String []byte
+
+// read advances a String by n bytes and returns them. If less than n bytes
+// remain, it returns nil.
+func (s *String) read(n int) []byte {
+	if len(*s) < n {
+		return nil
+	}
+	v := (*s)[:n]
+	*s = (*s)[n:]
+	return v
+}
+
+// Skip advances the String by n byte and reports whether it was successful.
+func (s *String) Skip(n int) bool {
+	return s.read(n) != nil
+}
+
+// ReadUint8 decodes an 8-bit value into out and advances over it. It
+// returns true on success and false on error.
+func (s *String) ReadUint8(out *uint8) bool {
+	v := s.read(1)
+	if v == nil {
+		return false
+	}
+	*out = uint8(v[0])
+	return true
+}
+
+// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
+// It returns true on success and false on error.
+func (s *String) ReadUint16(out *uint16) bool {
+	v := s.read(2)
+	if v == nil {
+		return false
+	}
+	*out = uint16(v[0])<<8 | uint16(v[1])
+	return true
+}
+
+// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
+// It returns true on success and false on error.
+func (s *String) ReadUint24(out *uint32) bool {
+	v := s.read(3)
+	if v == nil {
+		return false
+	}
+	*out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2])
+	return true
+}
+
+// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
+// It returns true on success and false on error.
+func (s *String) ReadUint32(out *uint32) bool {
+	v := s.read(4)
+	if v == nil {
+		return false
+	}
+	*out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3])
+	return true
+}
+
+func (s *String) readUnsigned(out *uint32, length int) bool {
+	v := s.read(length)
+	if v == nil {
+		return false
+	}
+	var result uint32
+	for i := 0; i < length; i++ {
+		result <<= 8
+		result |= uint32(v[i])
+	}
+	*out = result
+	return true
+}
+
+func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
+	lenBytes := s.read(lenLen)
+	if lenBytes == nil {
+		return false
+	}
+	var length uint32
+	for _, b := range lenBytes {
+		length = length << 8
+		length = length | uint32(b)
+	}
+	if int(length) < 0 {
+		// This currently cannot overflow because we read uint24 at most, but check
+		// anyway in case that changes in the future.
+		return false
+	}
+	v := s.read(int(length))
+	if v == nil {
+		return false
+	}
+	*outChild = v
+	return true
+}
+
+// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
+// into out and advances over it. It returns true on success and false on
+// error.
+func (s *String) ReadUint8LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(1, out)
+}
+
+// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
+// length-prefixed value into out and advances over it. It returns true on
+// success and false on error.
+func (s *String) ReadUint16LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(2, out)
+}
+
+// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
+// length-prefixed value into out and advances over it. It returns true on
+// success and false on error.
+func (s *String) ReadUint24LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(3, out)
+}
+
+// ReadBytes reads n bytes into out and advances over them. It returns true on
+// success and false and error.
+func (s *String) ReadBytes(out *[]byte, n int) bool {
+	v := s.read(n)
+	if v == nil {
+		return false
+	}
+	*out = v
+	return true
+}
+
+// CopyBytes copies len(out) bytes into out and advances over them. It returns
+// true on success and false on error.
+func (s *String) CopyBytes(out []byte) bool {
+	n := len(out)
+	v := s.read(n)
+	if v == nil {
+		return false
+	}
+	return copy(out, v) == n
+}
+
+// Empty reports whether the string does not contain any bytes.
+func (s String) Empty() bool {
+	return len(s) == 0
+}
diff --git a/src/vendor/golang_org/x/net/idna/idna.go b/src/vendor/golang_org/x/net/idna/idna.go
index e8307f9..9fd0334 100644
--- a/src/vendor/golang_org/x/net/idna/idna.go
+++ b/src/vendor/golang_org/x/net/idna/idna.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -21,6 +21,7 @@
 	"unicode/utf8"
 
 	"golang_org/x/text/secure/bidirule"
+	"golang_org/x/text/unicode/bidi"
 	"golang_org/x/text/unicode/norm"
 )
 
@@ -67,6 +68,15 @@
 	return func(o *options) { o.verifyDNSLength = verify }
 }
 
+// RemoveLeadingDots removes leading label separators. Leading runes that map to
+// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
+//
+// This is the behavior suggested by the UTS #46 and is adopted by some
+// browsers.
+func RemoveLeadingDots(remove bool) Option {
+	return func(o *options) { o.removeLeadingDots = remove }
+}
+
 // ValidateLabels sets whether to check the mandatory label validation criteria
 // as defined in Section 5.4 of RFC 5891. This includes testing for correct use
 // of hyphens ('-'), normalization, validity of runes, and the context rules.
@@ -83,7 +93,7 @@
 	}
 }
 
-// StrictDomainName limits the set of permissable ASCII characters to those
+// StrictDomainName limits the set of permissible ASCII characters to those
 // allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
 // hyphen). This is set by default for MapForLookup and ValidateForRegistration.
 //
@@ -137,10 +147,11 @@
 }
 
 type options struct {
-	transitional    bool
-	useSTD3Rules    bool
-	validateLabels  bool
-	verifyDNSLength bool
+	transitional      bool
+	useSTD3Rules      bool
+	validateLabels    bool
+	verifyDNSLength   bool
+	removeLeadingDots bool
 
 	trie *idnaTrie
 
@@ -149,14 +160,14 @@
 
 	// mapping implements a validation and mapping step as defined in RFC 5895
 	// or UTS 46, tailored to, for example, domain registration or lookup.
-	mapping func(p *Profile, s string) (string, error)
+	mapping func(p *Profile, s string) (mapped string, isBidi bool, err error)
 
 	// bidirule, if specified, checks whether s conforms to the Bidi Rule
 	// defined in RFC 5893.
 	bidirule func(s string) bool
 }
 
-// A Profile defines the configuration of a IDNA mapper.
+// A Profile defines the configuration of an IDNA mapper.
 type Profile struct {
 	options
 }
@@ -289,12 +300,16 @@
 // see http://www.unicode.org/reports/tr46.
 func (p *Profile) process(s string, toASCII bool) (string, error) {
 	var err error
+	var isBidi bool
 	if p.mapping != nil {
-		s, err = p.mapping(p, s)
+		s, isBidi, err = p.mapping(p, s)
 	}
 	// Remove leading empty labels.
-	for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
+	if p.removeLeadingDots {
+		for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
+		}
 	}
+	// TODO: allow for a quick check of the tables data.
 	// It seems like we should only create this error on ToASCII, but the
 	// UTS 46 conformance tests suggests we should always check this.
 	if err == nil && p.verifyDNSLength && s == "" {
@@ -320,6 +335,7 @@
 				// Spec says keep the old label.
 				continue
 			}
+			isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
 			labels.set(u)
 			if err == nil && p.validateLabels {
 				err = p.fromPuny(p, u)
@@ -334,6 +350,14 @@
 			err = p.validateLabel(label)
 		}
 	}
+	if isBidi && p.bidirule != nil && err == nil {
+		for labels.reset(); !labels.done(); labels.next() {
+			if !p.bidirule(labels.label()) {
+				err = &labelError{s, "B"}
+				break
+			}
+		}
+	}
 	if toASCII {
 		for labels.reset(); !labels.done(); labels.next() {
 			label := labels.label()
@@ -365,41 +389,77 @@
 	return s, err
 }
 
-func normalize(p *Profile, s string) (string, error) {
-	return norm.NFC.String(s), nil
+func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) {
+	// TODO: consider first doing a quick check to see if any of these checks
+	// need to be done. This will make it slower in the general case, but
+	// faster in the common case.
+	mapped = norm.NFC.String(s)
+	isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft
+	return mapped, isBidi, nil
 }
 
-func validateRegistration(p *Profile, s string) (string, error) {
+func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) {
+	// TODO: filter need for normalization in loop below.
 	if !norm.NFC.IsNormalString(s) {
-		return s, &labelError{s, "V1"}
+		return s, false, &labelError{s, "V1"}
 	}
-	var err error
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
-		i += sz
+		if sz == 0 {
+			return s, bidi, runeError(utf8.RuneError)
+		}
+		bidi = bidi || info(v).isBidi(s[i:])
 		// Copy bytes not copied so far.
 		switch p.simplify(info(v).category()) {
 		// TODO: handle the NV8 defined in the Unicode idna data set to allow
 		// for strict conformance to IDNA2008.
 		case valid, deviation:
 		case disallowed, mapped, unknown, ignored:
-			if err == nil {
-				r, _ := utf8.DecodeRuneInString(s[i:])
-				err = runeError(r)
-			}
+			r, _ := utf8.DecodeRuneInString(s[i:])
+			return s, bidi, runeError(r)
 		}
+		i += sz
 	}
-	return s, err
+	return s, bidi, nil
 }
 
-func validateAndMap(p *Profile, s string) (string, error) {
+func (c info) isBidi(s string) bool {
+	if !c.isMapped() {
+		return c&attributesMask == rtl
+	}
+	// TODO: also store bidi info for mapped data. This is possible, but a bit
+	// cumbersome and not for the common case.
+	p, _ := bidi.LookupString(s)
+	switch p.Class() {
+	case bidi.R, bidi.AL, bidi.AN:
+		return true
+	}
+	return false
+}
+
+func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) {
 	var (
-		err error
-		b   []byte
-		k   int
+		b []byte
+		k int
 	)
+	// combinedInfoBits contains the or-ed bits of all runes. We use this
+	// to derive the mayNeedNorm bit later. This may trigger normalization
+	// overeagerly, but it will not do so in the common case. The end result
+	// is another 10% saving on BenchmarkProfile for the common case.
+	var combinedInfoBits info
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
+		if sz == 0 {
+			b = append(b, s[k:i]...)
+			b = append(b, "\ufffd"...)
+			k = len(s)
+			if err == nil {
+				err = runeError(utf8.RuneError)
+			}
+			break
+		}
+		combinedInfoBits |= info(v)
+		bidi = bidi || info(v).isBidi(s[i:])
 		start := i
 		i += sz
 		// Copy bytes not copied so far.
@@ -408,7 +468,7 @@
 			continue
 		case disallowed:
 			if err == nil {
-				r, _ := utf8.DecodeRuneInString(s[i:])
+				r, _ := utf8.DecodeRuneInString(s[start:])
 				err = runeError(r)
 			}
 			continue
@@ -426,7 +486,9 @@
 	}
 	if k == 0 {
 		// No changes so far.
-		s = norm.NFC.String(s)
+		if combinedInfoBits&mayNeedNorm != 0 {
+			s = norm.NFC.String(s)
+		}
 	} else {
 		b = append(b, s[k:]...)
 		if norm.NFC.QuickSpan(b) != len(b) {
@@ -435,7 +497,7 @@
 		// TODO: the punycode converters require strings as input.
 		s = string(b)
 	}
-	return s, err
+	return s, bidi, err
 }
 
 // A labelIter allows iterating over domain name labels.
@@ -530,8 +592,13 @@
 	if !norm.NFC.IsNormalString(s) {
 		return &labelError{s, "V1"}
 	}
+	// TODO: detect whether string may have to be normalized in the following
+	// loop.
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
+		if sz == 0 {
+			return runeError(utf8.RuneError)
+		}
 		if c := p.simplify(info(v).category()); c != valid && c != deviation {
 			return &labelError{s, "V6"}
 		}
@@ -604,16 +671,13 @@
 
 // validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
 // already implicitly satisfied by the overall implementation.
-func (p *Profile) validateLabel(s string) error {
+func (p *Profile) validateLabel(s string) (err error) {
 	if s == "" {
 		if p.verifyDNSLength {
 			return &labelError{s, "A4"}
 		}
 		return nil
 	}
-	if p.bidirule != nil && !p.bidirule(s) {
-		return &labelError{s, "B"}
-	}
 	if !p.validateLabels {
 		return nil
 	}
diff --git a/src/vendor/golang_org/x/net/idna/punycode.go b/src/vendor/golang_org/x/net/idna/punycode.go
index fab9229..02c7d59 100644
--- a/src/vendor/golang_org/x/net/idna/punycode.go
+++ b/src/vendor/golang_org/x/net/idna/punycode.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/net/idna/tables.go b/src/vendor/golang_org/x/net/idna/tables.go
index d57a3e2..a470c5a 100644
--- a/src/vendor/golang_org/x/net/idna/tables.go
+++ b/src/vendor/golang_org/x/net/idna/tables.go
@@ -1,11 +1,11 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Code generated by running "go generate" in golang_org/x/text. DO NOT EDIT.
 
 package idna
 
 // UnicodeVersion is the Unicode version from which the tables in this package are derived.
-const UnicodeVersion = "9.0.0"
+const UnicodeVersion = "10.0.0"
 
 var mappings string = "" + // Size: 8176 bytes
 	"\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" +
@@ -546,7 +546,7 @@
 	return 0
 }
 
-// idnaTrie. Total size: 28496 bytes (27.83 KiB). Checksum: 43288b883596640e.
+// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd.
 type idnaTrie struct{}
 
 func newIdnaTrie(i int) *idnaTrie {
@@ -556,17 +556,17 @@
 // lookupValue determines the type of block n and looks up the value for b.
 func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {
 	switch {
-	case n < 123:
+	case n < 125:
 		return uint16(idnaValues[n<<6+uint32(b)])
 	default:
-		n -= 123
+		n -= 125
 		return uint16(idnaSparse.lookup(n, b))
 	}
 }
 
-// idnaValues: 125 blocks, 8000 entries, 16000 bytes
+// idnaValues: 127 blocks, 8128 entries, 16256 bytes
 // The third block is the zero block.
-var idnaValues = [8000]uint16{
+var idnaValues = [8128]uint16{
 	// Block 0x0, offset 0x0
 	0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,
 	0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,
@@ -677,14 +677,14 @@
 	0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,
 	0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,
 	// Block 0xa, offset 0x280
-	0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x1308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,
-	0x286: 0x1308, 0x287: 0x1308, 0x288: 0x1308, 0x289: 0x1308, 0x28a: 0x1308, 0x28b: 0x1308,
-	0x28c: 0x1308, 0x28d: 0x1308, 0x28e: 0x1308, 0x28f: 0x13c0, 0x290: 0x1308, 0x291: 0x1308,
-	0x292: 0x1308, 0x293: 0x1308, 0x294: 0x1308, 0x295: 0x1308, 0x296: 0x1308, 0x297: 0x1308,
-	0x298: 0x1308, 0x299: 0x1308, 0x29a: 0x1308, 0x29b: 0x1308, 0x29c: 0x1308, 0x29d: 0x1308,
-	0x29e: 0x1308, 0x29f: 0x1308, 0x2a0: 0x1308, 0x2a1: 0x1308, 0x2a2: 0x1308, 0x2a3: 0x1308,
-	0x2a4: 0x1308, 0x2a5: 0x1308, 0x2a6: 0x1308, 0x2a7: 0x1308, 0x2a8: 0x1308, 0x2a9: 0x1308,
-	0x2aa: 0x1308, 0x2ab: 0x1308, 0x2ac: 0x1308, 0x2ad: 0x1308, 0x2ae: 0x1308, 0x2af: 0x1308,
+	0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,
+	0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,
+	0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,
+	0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,
+	0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,
+	0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,
+	0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,
+	0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,
 	0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,
 	0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,
 	0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,
@@ -725,8 +725,8 @@
 	0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,
 	0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,
 	// Block 0xe, offset 0x380
-	0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x1308, 0x384: 0x1308, 0x385: 0x1308,
-	0x386: 0x1308, 0x387: 0x1308, 0x388: 0x1318, 0x389: 0x1318, 0x38a: 0xe00d, 0x38b: 0x0008,
+	0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,
+	0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,
 	0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,
 	0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,
 	0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,
@@ -761,129 +761,129 @@
 	0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,
 	0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,
 	// Block 0x11, offset 0x440
-	0x440: 0x0040, 0x441: 0x0040, 0x442: 0x0040, 0x443: 0x0040, 0x444: 0x0040, 0x445: 0x0040,
-	0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0018, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0018,
-	0x44c: 0x0018, 0x44d: 0x0018, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x1308, 0x451: 0x1308,
-	0x452: 0x1308, 0x453: 0x1308, 0x454: 0x1308, 0x455: 0x1308, 0x456: 0x1308, 0x457: 0x1308,
-	0x458: 0x1308, 0x459: 0x1308, 0x45a: 0x1308, 0x45b: 0x0018, 0x45c: 0x0340, 0x45d: 0x0040,
-	0x45e: 0x0018, 0x45f: 0x0018, 0x460: 0x0208, 0x461: 0x0008, 0x462: 0x0408, 0x463: 0x0408,
-	0x464: 0x0408, 0x465: 0x0408, 0x466: 0x0208, 0x467: 0x0408, 0x468: 0x0208, 0x469: 0x0408,
-	0x46a: 0x0208, 0x46b: 0x0208, 0x46c: 0x0208, 0x46d: 0x0208, 0x46e: 0x0208, 0x46f: 0x0408,
-	0x470: 0x0408, 0x471: 0x0408, 0x472: 0x0408, 0x473: 0x0208, 0x474: 0x0208, 0x475: 0x0208,
-	0x476: 0x0208, 0x477: 0x0208, 0x478: 0x0208, 0x479: 0x0208, 0x47a: 0x0208, 0x47b: 0x0208,
-	0x47c: 0x0208, 0x47d: 0x0208, 0x47e: 0x0208, 0x47f: 0x0208,
+	0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,
+	0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,
+	0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,
+	0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,
+	0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,
+	0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,
+	0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,
+	0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,
+	0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,
+	0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,
+	0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,
 	// Block 0x12, offset 0x480
-	0x480: 0x0408, 0x481: 0x0208, 0x482: 0x0208, 0x483: 0x0408, 0x484: 0x0408, 0x485: 0x0408,
-	0x486: 0x0408, 0x487: 0x0408, 0x488: 0x0408, 0x489: 0x0408, 0x48a: 0x0408, 0x48b: 0x0408,
-	0x48c: 0x0208, 0x48d: 0x0408, 0x48e: 0x0208, 0x48f: 0x0408, 0x490: 0x0208, 0x491: 0x0208,
-	0x492: 0x0408, 0x493: 0x0408, 0x494: 0x0018, 0x495: 0x0408, 0x496: 0x1308, 0x497: 0x1308,
-	0x498: 0x1308, 0x499: 0x1308, 0x49a: 0x1308, 0x49b: 0x1308, 0x49c: 0x1308, 0x49d: 0x0040,
-	0x49e: 0x0018, 0x49f: 0x1308, 0x4a0: 0x1308, 0x4a1: 0x1308, 0x4a2: 0x1308, 0x4a3: 0x1308,
-	0x4a4: 0x1308, 0x4a5: 0x0008, 0x4a6: 0x0008, 0x4a7: 0x1308, 0x4a8: 0x1308, 0x4a9: 0x0018,
-	0x4aa: 0x1308, 0x4ab: 0x1308, 0x4ac: 0x1308, 0x4ad: 0x1308, 0x4ae: 0x0408, 0x4af: 0x0408,
-	0x4b0: 0x0008, 0x4b1: 0x0008, 0x4b2: 0x0008, 0x4b3: 0x0008, 0x4b4: 0x0008, 0x4b5: 0x0008,
-	0x4b6: 0x0008, 0x4b7: 0x0008, 0x4b8: 0x0008, 0x4b9: 0x0008, 0x4ba: 0x0208, 0x4bb: 0x0208,
-	0x4bc: 0x0208, 0x4bd: 0x0008, 0x4be: 0x0008, 0x4bf: 0x0208,
+	0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,
+	0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,
+	0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,
+	0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,
+	0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,
+	0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,
+	0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,
+	0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,
+	0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,
+	0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,
+	0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,
 	// Block 0x13, offset 0x4c0
-	0x4c0: 0x0018, 0x4c1: 0x0018, 0x4c2: 0x0018, 0x4c3: 0x0018, 0x4c4: 0x0018, 0x4c5: 0x0018,
-	0x4c6: 0x0018, 0x4c7: 0x0018, 0x4c8: 0x0018, 0x4c9: 0x0018, 0x4ca: 0x0018, 0x4cb: 0x0018,
-	0x4cc: 0x0018, 0x4cd: 0x0018, 0x4ce: 0x0040, 0x4cf: 0x0340, 0x4d0: 0x0408, 0x4d1: 0x1308,
-	0x4d2: 0x0208, 0x4d3: 0x0208, 0x4d4: 0x0208, 0x4d5: 0x0408, 0x4d6: 0x0408, 0x4d7: 0x0408,
-	0x4d8: 0x0408, 0x4d9: 0x0408, 0x4da: 0x0208, 0x4db: 0x0208, 0x4dc: 0x0208, 0x4dd: 0x0208,
-	0x4de: 0x0408, 0x4df: 0x0208, 0x4e0: 0x0208, 0x4e1: 0x0208, 0x4e2: 0x0208, 0x4e3: 0x0208,
-	0x4e4: 0x0208, 0x4e5: 0x0208, 0x4e6: 0x0208, 0x4e7: 0x0208, 0x4e8: 0x0408, 0x4e9: 0x0208,
-	0x4ea: 0x0408, 0x4eb: 0x0208, 0x4ec: 0x0408, 0x4ed: 0x0208, 0x4ee: 0x0208, 0x4ef: 0x0408,
-	0x4f0: 0x1308, 0x4f1: 0x1308, 0x4f2: 0x1308, 0x4f3: 0x1308, 0x4f4: 0x1308, 0x4f5: 0x1308,
-	0x4f6: 0x1308, 0x4f7: 0x1308, 0x4f8: 0x1308, 0x4f9: 0x1308, 0x4fa: 0x1308, 0x4fb: 0x1308,
-	0x4fc: 0x1308, 0x4fd: 0x1308, 0x4fe: 0x1308, 0x4ff: 0x1308,
+	0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,
+	0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,
+	0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,
+	0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,
+	0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,
+	0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,
+	0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,
+	0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,
+	0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,
+	0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,
+	0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,
 	// Block 0x14, offset 0x500
-	0x500: 0x1008, 0x501: 0x1308, 0x502: 0x1308, 0x503: 0x1308, 0x504: 0x1308, 0x505: 0x1308,
-	0x506: 0x1308, 0x507: 0x1308, 0x508: 0x1308, 0x509: 0x1008, 0x50a: 0x1008, 0x50b: 0x1008,
-	0x50c: 0x1008, 0x50d: 0x1b08, 0x50e: 0x1008, 0x50f: 0x1008, 0x510: 0x0008, 0x511: 0x1308,
-	0x512: 0x1308, 0x513: 0x1308, 0x514: 0x1308, 0x515: 0x1308, 0x516: 0x1308, 0x517: 0x1308,
-	0x518: 0x04c9, 0x519: 0x0501, 0x51a: 0x0539, 0x51b: 0x0571, 0x51c: 0x05a9, 0x51d: 0x05e1,
-	0x51e: 0x0619, 0x51f: 0x0651, 0x520: 0x0008, 0x521: 0x0008, 0x522: 0x1308, 0x523: 0x1308,
-	0x524: 0x0018, 0x525: 0x0018, 0x526: 0x0008, 0x527: 0x0008, 0x528: 0x0008, 0x529: 0x0008,
-	0x52a: 0x0008, 0x52b: 0x0008, 0x52c: 0x0008, 0x52d: 0x0008, 0x52e: 0x0008, 0x52f: 0x0008,
-	0x530: 0x0018, 0x531: 0x0008, 0x532: 0x0008, 0x533: 0x0008, 0x534: 0x0008, 0x535: 0x0008,
-	0x536: 0x0008, 0x537: 0x0008, 0x538: 0x0008, 0x539: 0x0008, 0x53a: 0x0008, 0x53b: 0x0008,
-	0x53c: 0x0008, 0x53d: 0x0008, 0x53e: 0x0008, 0x53f: 0x0008,
+	0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,
+	0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,
+	0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,
+	0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,
+	0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,
+	0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,
+	0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,
+	0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,
+	0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,
+	0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,
+	0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,
 	// Block 0x15, offset 0x540
-	0x540: 0x0008, 0x541: 0x1308, 0x542: 0x1008, 0x543: 0x1008, 0x544: 0x0040, 0x545: 0x0008,
-	0x546: 0x0008, 0x547: 0x0008, 0x548: 0x0008, 0x549: 0x0008, 0x54a: 0x0008, 0x54b: 0x0008,
-	0x54c: 0x0008, 0x54d: 0x0040, 0x54e: 0x0040, 0x54f: 0x0008, 0x550: 0x0008, 0x551: 0x0040,
-	0x552: 0x0040, 0x553: 0x0008, 0x554: 0x0008, 0x555: 0x0008, 0x556: 0x0008, 0x557: 0x0008,
-	0x558: 0x0008, 0x559: 0x0008, 0x55a: 0x0008, 0x55b: 0x0008, 0x55c: 0x0008, 0x55d: 0x0008,
-	0x55e: 0x0008, 0x55f: 0x0008, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x0008, 0x563: 0x0008,
-	0x564: 0x0008, 0x565: 0x0008, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0040,
-	0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008,
-	0x570: 0x0008, 0x571: 0x0040, 0x572: 0x0008, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
-	0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0040, 0x57b: 0x0040,
-	0x57c: 0x1308, 0x57d: 0x0008, 0x57e: 0x1008, 0x57f: 0x1008,
+	0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,
+	0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,
+	0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,
+	0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,
+	0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,
+	0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,
+	0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,
+	0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,
+	0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
+	0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,
+	0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,
 	// Block 0x16, offset 0x580
-	0x580: 0x1008, 0x581: 0x1308, 0x582: 0x1308, 0x583: 0x1308, 0x584: 0x1308, 0x585: 0x0040,
-	0x586: 0x0040, 0x587: 0x1008, 0x588: 0x1008, 0x589: 0x0040, 0x58a: 0x0040, 0x58b: 0x1008,
-	0x58c: 0x1008, 0x58d: 0x1b08, 0x58e: 0x0008, 0x58f: 0x0040, 0x590: 0x0040, 0x591: 0x0040,
-	0x592: 0x0040, 0x593: 0x0040, 0x594: 0x0040, 0x595: 0x0040, 0x596: 0x0040, 0x597: 0x1008,
-	0x598: 0x0040, 0x599: 0x0040, 0x59a: 0x0040, 0x59b: 0x0040, 0x59c: 0x0689, 0x59d: 0x06c1,
-	0x59e: 0x0040, 0x59f: 0x06f9, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x1308, 0x5a3: 0x1308,
-	0x5a4: 0x0040, 0x5a5: 0x0040, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
+	0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,
+	0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,
+	0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,
+	0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,
+	0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,
+	0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,
+	0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
 	0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,
-	0x5b0: 0x0008, 0x5b1: 0x0008, 0x5b2: 0x0018, 0x5b3: 0x0018, 0x5b4: 0x0018, 0x5b5: 0x0018,
-	0x5b6: 0x0018, 0x5b7: 0x0018, 0x5b8: 0x0018, 0x5b9: 0x0018, 0x5ba: 0x0018, 0x5bb: 0x0018,
-	0x5bc: 0x0040, 0x5bd: 0x0040, 0x5be: 0x0040, 0x5bf: 0x0040,
+	0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,
+	0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,
+	0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,
 	// Block 0x17, offset 0x5c0
-	0x5c0: 0x0040, 0x5c1: 0x1308, 0x5c2: 0x1308, 0x5c3: 0x1008, 0x5c4: 0x0040, 0x5c5: 0x0008,
-	0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0040,
-	0x5cc: 0x0040, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
+	0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,
+	0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,
+	0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
 	0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,
 	0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,
 	0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,
 	0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,
 	0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,
-	0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0731, 0x5f4: 0x0040, 0x5f5: 0x0008,
-	0x5f6: 0x0769, 0x5f7: 0x0040, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
-	0x5fc: 0x1308, 0x5fd: 0x0040, 0x5fe: 0x1008, 0x5ff: 0x1008,
+	0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,
+	0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
+	0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,
 	// Block 0x18, offset 0x600
-	0x600: 0x1008, 0x601: 0x1308, 0x602: 0x1308, 0x603: 0x0040, 0x604: 0x0040, 0x605: 0x0040,
-	0x606: 0x0040, 0x607: 0x1308, 0x608: 0x1308, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x1308,
-	0x60c: 0x1308, 0x60d: 0x1b08, 0x60e: 0x0040, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x1308,
-	0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x0040,
-	0x618: 0x0040, 0x619: 0x07a1, 0x61a: 0x07d9, 0x61b: 0x0811, 0x61c: 0x0008, 0x61d: 0x0040,
-	0x61e: 0x0849, 0x61f: 0x0040, 0x620: 0x0040, 0x621: 0x0040, 0x622: 0x0040, 0x623: 0x0040,
+	0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,
+	0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,
+	0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,
+	0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,
+	0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,
+	0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,
 	0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,
 	0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,
-	0x630: 0x1308, 0x631: 0x1308, 0x632: 0x0008, 0x633: 0x0008, 0x634: 0x0008, 0x635: 0x1308,
-	0x636: 0x0040, 0x637: 0x0040, 0x638: 0x0040, 0x639: 0x0040, 0x63a: 0x0040, 0x63b: 0x0040,
-	0x63c: 0x0040, 0x63d: 0x0040, 0x63e: 0x0040, 0x63f: 0x0040,
+	0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,
+	0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,
+	0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040,
 	// Block 0x19, offset 0x640
-	0x640: 0x0040, 0x641: 0x1308, 0x642: 0x1308, 0x643: 0x1008, 0x644: 0x0040, 0x645: 0x0008,
-	0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0008,
-	0x64c: 0x0008, 0x64d: 0x0008, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0008,
+	0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,
+	0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,
+	0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,
 	0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,
 	0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,
 	0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,
 	0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,
 	0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,
-	0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0040, 0x675: 0x0008,
-	0x676: 0x0008, 0x677: 0x0008, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
-	0x67c: 0x1308, 0x67d: 0x0008, 0x67e: 0x1008, 0x67f: 0x1008,
+	0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,
+	0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
+	0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,
 	// Block 0x1a, offset 0x680
-	0x680: 0x1008, 0x681: 0x1308, 0x682: 0x1308, 0x683: 0x1308, 0x684: 0x1308, 0x685: 0x1308,
-	0x686: 0x0040, 0x687: 0x1308, 0x688: 0x1308, 0x689: 0x1008, 0x68a: 0x0040, 0x68b: 0x1008,
-	0x68c: 0x1008, 0x68d: 0x1b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0008, 0x691: 0x0040,
+	0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,
+	0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,
+	0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,
 	0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,
-	0x698: 0x0040, 0x699: 0x0040, 0x69a: 0x0040, 0x69b: 0x0040, 0x69c: 0x0040, 0x69d: 0x0040,
-	0x69e: 0x0040, 0x69f: 0x0040, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x1308, 0x6a3: 0x1308,
+	0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,
+	0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,
 	0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,
 	0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,
-	0x6b0: 0x0018, 0x6b1: 0x0018, 0x6b2: 0x0040, 0x6b3: 0x0040, 0x6b4: 0x0040, 0x6b5: 0x0040,
-	0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040,
+	0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,
+	0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,
 	0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,
 	// Block 0x1b, offset 0x6c0
-	0x6c0: 0x0040, 0x6c1: 0x1308, 0x6c2: 0x1008, 0x6c3: 0x1008, 0x6c4: 0x0040, 0x6c5: 0x0008,
+	0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,
 	0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,
-	0x6cc: 0x0008, 0x6cd: 0x0040, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0040,
+	0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,
 	0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,
 	0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,
 	0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,
@@ -891,1457 +891,1490 @@
 	0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,
 	0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,
 	0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,
-	0x6fc: 0x1308, 0x6fd: 0x0008, 0x6fe: 0x1008, 0x6ff: 0x1308,
+	0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,
 	// Block 0x1c, offset 0x700
-	0x700: 0x1008, 0x701: 0x1308, 0x702: 0x1308, 0x703: 0x1308, 0x704: 0x1308, 0x705: 0x0040,
-	0x706: 0x0040, 0x707: 0x1008, 0x708: 0x1008, 0x709: 0x0040, 0x70a: 0x0040, 0x70b: 0x1008,
-	0x70c: 0x1008, 0x70d: 0x1b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0040, 0x711: 0x0040,
-	0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x1308, 0x717: 0x1008,
-	0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0881, 0x71d: 0x08b9,
-	0x71e: 0x0040, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x1308, 0x723: 0x1308,
+	0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,
+	0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,
+	0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,
+	0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,
+	0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,
+	0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,
 	0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,
 	0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,
-	0x730: 0x0018, 0x731: 0x0008, 0x732: 0x0018, 0x733: 0x0018, 0x734: 0x0018, 0x735: 0x0018,
-	0x736: 0x0018, 0x737: 0x0018, 0x738: 0x0040, 0x739: 0x0040, 0x73a: 0x0040, 0x73b: 0x0040,
-	0x73c: 0x0040, 0x73d: 0x0040, 0x73e: 0x0040, 0x73f: 0x0040,
+	0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,
+	0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,
+	0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,
 	// Block 0x1d, offset 0x740
-	0x740: 0x0040, 0x741: 0x0040, 0x742: 0x1308, 0x743: 0x0008, 0x744: 0x0040, 0x745: 0x0008,
-	0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0040,
-	0x74c: 0x0040, 0x74d: 0x0040, 0x74e: 0x0008, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
-	0x752: 0x0008, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0040, 0x757: 0x0040,
-	0x758: 0x0040, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0040, 0x75c: 0x0008, 0x75d: 0x0040,
-	0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0040, 0x761: 0x0040, 0x762: 0x0040, 0x763: 0x0008,
-	0x764: 0x0008, 0x765: 0x0040, 0x766: 0x0040, 0x767: 0x0040, 0x768: 0x0008, 0x769: 0x0008,
-	0x76a: 0x0008, 0x76b: 0x0040, 0x76c: 0x0040, 0x76d: 0x0040, 0x76e: 0x0008, 0x76f: 0x0008,
-	0x770: 0x0008, 0x771: 0x0008, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0008, 0x775: 0x0008,
+	0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,
+	0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,
+	0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
+	0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,
+	0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,
+	0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,
+	0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,
+	0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,
+	0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,
 	0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,
-	0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x1008, 0x77f: 0x1008,
+	0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,
 	// Block 0x1e, offset 0x780
-	0x780: 0x1308, 0x781: 0x1008, 0x782: 0x1008, 0x783: 0x1008, 0x784: 0x1008, 0x785: 0x0040,
-	0x786: 0x1308, 0x787: 0x1308, 0x788: 0x1308, 0x789: 0x0040, 0x78a: 0x1308, 0x78b: 0x1308,
-	0x78c: 0x1308, 0x78d: 0x1b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
-	0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x1308, 0x796: 0x1308, 0x797: 0x0040,
-	0x798: 0x0008, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0040, 0x79d: 0x0040,
-	0x79e: 0x0040, 0x79f: 0x0040, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x1308, 0x7a3: 0x1308,
+	0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,
+	0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,
+	0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
+	0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,
+	0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,
+	0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,
 	0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,
 	0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,
-	0x7b0: 0x0040, 0x7b1: 0x0040, 0x7b2: 0x0040, 0x7b3: 0x0040, 0x7b4: 0x0040, 0x7b5: 0x0040,
-	0x7b6: 0x0040, 0x7b7: 0x0040, 0x7b8: 0x0018, 0x7b9: 0x0018, 0x7ba: 0x0018, 0x7bb: 0x0018,
-	0x7bc: 0x0018, 0x7bd: 0x0018, 0x7be: 0x0018, 0x7bf: 0x0018,
+	0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,
+	0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,
+	0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,
 	// Block 0x1f, offset 0x7c0
-	0x7c0: 0x0008, 0x7c1: 0x1308, 0x7c2: 0x1008, 0x7c3: 0x1008, 0x7c4: 0x0040, 0x7c5: 0x0008,
-	0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0008,
-	0x7cc: 0x0008, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
-	0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0008, 0x7d7: 0x0008,
-	0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0008, 0x7dc: 0x0008, 0x7dd: 0x0008,
-	0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x0008, 0x7e3: 0x0008,
-	0x7e4: 0x0008, 0x7e5: 0x0008, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0040,
-	0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008,
-	0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0040, 0x7f5: 0x0008,
+	0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,
+	0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,
+	0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
+	0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,
+	0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,
+	0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,
+	0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,
+	0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,
+	0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,
 	0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,
-	0x7fc: 0x1308, 0x7fd: 0x0008, 0x7fe: 0x1008, 0x7ff: 0x1308,
+	0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,
 	// Block 0x20, offset 0x800
-	0x800: 0x1008, 0x801: 0x1008, 0x802: 0x1008, 0x803: 0x1008, 0x804: 0x1008, 0x805: 0x0040,
-	0x806: 0x1308, 0x807: 0x1008, 0x808: 0x1008, 0x809: 0x0040, 0x80a: 0x1008, 0x80b: 0x1008,
-	0x80c: 0x1308, 0x80d: 0x1b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
-	0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x1008, 0x816: 0x1008, 0x817: 0x0040,
-	0x818: 0x0040, 0x819: 0x0040, 0x81a: 0x0040, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
-	0x81e: 0x0008, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x1308, 0x823: 0x1308,
+	0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,
+	0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,
+	0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
+	0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,
+	0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
+	0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,
 	0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,
 	0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,
-	0x830: 0x0040, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
-	0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0040, 0x839: 0x0040, 0x83a: 0x0040, 0x83b: 0x0040,
-	0x83c: 0x0040, 0x83d: 0x0040, 0x83e: 0x0040, 0x83f: 0x0040,
+	0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
+	0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,
+	0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,
 	// Block 0x21, offset 0x840
-	0x840: 0x1008, 0x841: 0x1308, 0x842: 0x1308, 0x843: 0x1308, 0x844: 0x1308, 0x845: 0x0040,
-	0x846: 0x1008, 0x847: 0x1008, 0x848: 0x1008, 0x849: 0x0040, 0x84a: 0x1008, 0x84b: 0x1008,
-	0x84c: 0x1008, 0x84d: 0x1b08, 0x84e: 0x0008, 0x84f: 0x0018, 0x850: 0x0040, 0x851: 0x0040,
-	0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x1008,
-	0x858: 0x0018, 0x859: 0x0018, 0x85a: 0x0018, 0x85b: 0x0018, 0x85c: 0x0018, 0x85d: 0x0018,
-	0x85e: 0x0018, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x1308, 0x863: 0x1308,
-	0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008,
+	0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008,
+	0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,
+	0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,
+	0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,
+	0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,
+	0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,
+	0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,
 	0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,
-	0x870: 0x0018, 0x871: 0x0018, 0x872: 0x0018, 0x873: 0x0018, 0x874: 0x0018, 0x875: 0x0018,
-	0x876: 0x0018, 0x877: 0x0018, 0x878: 0x0018, 0x879: 0x0018, 0x87a: 0x0008, 0x87b: 0x0008,
-	0x87c: 0x0008, 0x87d: 0x0008, 0x87e: 0x0008, 0x87f: 0x0008,
+	0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,
+	0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,
+	0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,
 	// Block 0x22, offset 0x880
-	0x880: 0x0040, 0x881: 0x0008, 0x882: 0x0008, 0x883: 0x0040, 0x884: 0x0008, 0x885: 0x0040,
-	0x886: 0x0040, 0x887: 0x0008, 0x888: 0x0008, 0x889: 0x0040, 0x88a: 0x0008, 0x88b: 0x0040,
-	0x88c: 0x0040, 0x88d: 0x0008, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
-	0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x0008,
-	0x898: 0x0040, 0x899: 0x0008, 0x89a: 0x0008, 0x89b: 0x0008, 0x89c: 0x0008, 0x89d: 0x0008,
-	0x89e: 0x0008, 0x89f: 0x0008, 0x8a0: 0x0040, 0x8a1: 0x0008, 0x8a2: 0x0008, 0x8a3: 0x0008,
-	0x8a4: 0x0040, 0x8a5: 0x0008, 0x8a6: 0x0040, 0x8a7: 0x0008, 0x8a8: 0x0040, 0x8a9: 0x0040,
-	0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0040, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
-	0x8b0: 0x0008, 0x8b1: 0x1308, 0x8b2: 0x0008, 0x8b3: 0x0929, 0x8b4: 0x1308, 0x8b5: 0x1308,
-	0x8b6: 0x1308, 0x8b7: 0x1308, 0x8b8: 0x1308, 0x8b9: 0x1308, 0x8ba: 0x0040, 0x8bb: 0x1308,
-	0x8bc: 0x1308, 0x8bd: 0x0008, 0x8be: 0x0040, 0x8bf: 0x0040,
+	0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,
+	0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,
+	0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
+	0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,
+	0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,
+	0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,
+	0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,
+	0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
+	0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,
+	0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,
+	0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,
 	// Block 0x23, offset 0x8c0
-	0x8c0: 0x0008, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x09d1, 0x8c4: 0x0008, 0x8c5: 0x0008,
-	0x8c6: 0x0008, 0x8c7: 0x0008, 0x8c8: 0x0040, 0x8c9: 0x0008, 0x8ca: 0x0008, 0x8cb: 0x0008,
-	0x8cc: 0x0008, 0x8cd: 0x0a09, 0x8ce: 0x0008, 0x8cf: 0x0008, 0x8d0: 0x0008, 0x8d1: 0x0008,
-	0x8d2: 0x0a41, 0x8d3: 0x0008, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0a79,
-	0x8d8: 0x0008, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0ab1, 0x8dd: 0x0008,
-	0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008,
-	0x8e4: 0x0008, 0x8e5: 0x0008, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0ae9,
-	0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0040, 0x8ee: 0x0040, 0x8ef: 0x0040,
-	0x8f0: 0x0040, 0x8f1: 0x1308, 0x8f2: 0x1308, 0x8f3: 0x0b21, 0x8f4: 0x1308, 0x8f5: 0x0b59,
-	0x8f6: 0x0b91, 0x8f7: 0x0bc9, 0x8f8: 0x0c19, 0x8f9: 0x0c51, 0x8fa: 0x1308, 0x8fb: 0x1308,
-	0x8fc: 0x1308, 0x8fd: 0x1308, 0x8fe: 0x1308, 0x8ff: 0x1008,
+	0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,
+	0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,
+	0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,
+	0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,
+	0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,
+	0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,
+	0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,
+	0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,
+	0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,
+	0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,
+	0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,
 	// Block 0x24, offset 0x900
-	0x900: 0x1308, 0x901: 0x0ca1, 0x902: 0x1308, 0x903: 0x1308, 0x904: 0x1b08, 0x905: 0x0018,
-	0x906: 0x1308, 0x907: 0x1308, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008,
-	0x90c: 0x0008, 0x90d: 0x1308, 0x90e: 0x1308, 0x90f: 0x1308, 0x910: 0x1308, 0x911: 0x1308,
-	0x912: 0x1308, 0x913: 0x0cd9, 0x914: 0x1308, 0x915: 0x1308, 0x916: 0x1308, 0x917: 0x1308,
-	0x918: 0x0040, 0x919: 0x1308, 0x91a: 0x1308, 0x91b: 0x1308, 0x91c: 0x1308, 0x91d: 0x0d11,
-	0x91e: 0x1308, 0x91f: 0x1308, 0x920: 0x1308, 0x921: 0x1308, 0x922: 0x0d49, 0x923: 0x1308,
-	0x924: 0x1308, 0x925: 0x1308, 0x926: 0x1308, 0x927: 0x0d81, 0x928: 0x1308, 0x929: 0x1308,
-	0x92a: 0x1308, 0x92b: 0x1308, 0x92c: 0x0db9, 0x92d: 0x1308, 0x92e: 0x1308, 0x92f: 0x1308,
-	0x930: 0x1308, 0x931: 0x1308, 0x932: 0x1308, 0x933: 0x1308, 0x934: 0x1308, 0x935: 0x1308,
-	0x936: 0x1308, 0x937: 0x1308, 0x938: 0x1308, 0x939: 0x0df1, 0x93a: 0x1308, 0x93b: 0x1308,
-	0x93c: 0x1308, 0x93d: 0x0040, 0x93e: 0x0018, 0x93f: 0x0018,
+	0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,
+	0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040,
+	0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040,
+	0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,
+	0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,
+	0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,
+	0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040,
+	0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,
+	0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,
+	0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308,
+	0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,
 	// Block 0x25, offset 0x940
-	0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0008, 0x944: 0x0008, 0x945: 0x0008,
-	0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
-	0x94c: 0x0008, 0x94d: 0x0008, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
-	0x952: 0x0008, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0008,
-	0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0008, 0x95d: 0x0008,
+	0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,
+	0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
+	0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
+	0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,
+	0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,
 	0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,
-	0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0008,
-	0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0039, 0x96d: 0x0ed1, 0x96e: 0x0ee9, 0x96f: 0x0008,
-	0x970: 0x0ef9, 0x971: 0x0f09, 0x972: 0x0f19, 0x973: 0x0f31, 0x974: 0x0249, 0x975: 0x0f41,
-	0x976: 0x0259, 0x977: 0x0f51, 0x978: 0x0359, 0x979: 0x0f61, 0x97a: 0x0f71, 0x97b: 0x0008,
-	0x97c: 0x00d9, 0x97d: 0x0f81, 0x97e: 0x0f99, 0x97f: 0x0269,
+	0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,
+	0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,
+	0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,
+	0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,
+	0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,
 	// Block 0x26, offset 0x980
-	0x980: 0x0fa9, 0x981: 0x0fb9, 0x982: 0x0279, 0x983: 0x0039, 0x984: 0x0fc9, 0x985: 0x0fe1,
-	0x986: 0x059d, 0x987: 0x0ee9, 0x988: 0x0ef9, 0x989: 0x0f09, 0x98a: 0x0ff9, 0x98b: 0x1011,
-	0x98c: 0x1029, 0x98d: 0x0f31, 0x98e: 0x0008, 0x98f: 0x0f51, 0x990: 0x0f61, 0x991: 0x1041,
-	0x992: 0x00d9, 0x993: 0x1059, 0x994: 0x05b5, 0x995: 0x05b5, 0x996: 0x0f99, 0x997: 0x0fa9,
-	0x998: 0x0fb9, 0x999: 0x059d, 0x99a: 0x1071, 0x99b: 0x1089, 0x99c: 0x05cd, 0x99d: 0x1099,
-	0x99e: 0x10b1, 0x99f: 0x10c9, 0x9a0: 0x10e1, 0x9a1: 0x10f9, 0x9a2: 0x0f41, 0x9a3: 0x0269,
-	0x9a4: 0x0fb9, 0x9a5: 0x1089, 0x9a6: 0x1099, 0x9a7: 0x10b1, 0x9a8: 0x1111, 0x9a9: 0x10e1,
-	0x9aa: 0x10f9, 0x9ab: 0x0008, 0x9ac: 0x0008, 0x9ad: 0x0008, 0x9ae: 0x0008, 0x9af: 0x0008,
-	0x9b0: 0x0008, 0x9b1: 0x0008, 0x9b2: 0x0008, 0x9b3: 0x0008, 0x9b4: 0x0008, 0x9b5: 0x0008,
-	0x9b6: 0x0008, 0x9b7: 0x0008, 0x9b8: 0x1129, 0x9b9: 0x0008, 0x9ba: 0x0008, 0x9bb: 0x0008,
-	0x9bc: 0x0008, 0x9bd: 0x0008, 0x9be: 0x0008, 0x9bf: 0x0008,
+	0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,
+	0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,
+	0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,
+	0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,
+	0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,
+	0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,
+	0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,
+	0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,
+	0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,
+	0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,
+	0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,
 	// Block 0x27, offset 0x9c0
 	0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,
 	0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,
 	0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,
 	0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,
-	0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x1141, 0x9dc: 0x1159, 0x9dd: 0x1169,
-	0x9de: 0x1181, 0x9df: 0x1029, 0x9e0: 0x1199, 0x9e1: 0x11a9, 0x9e2: 0x11c1, 0x9e3: 0x11d9,
-	0x9e4: 0x11f1, 0x9e5: 0x1209, 0x9e6: 0x1221, 0x9e7: 0x05e5, 0x9e8: 0x1239, 0x9e9: 0x1251,
-	0x9ea: 0xe17d, 0x9eb: 0x1269, 0x9ec: 0x1281, 0x9ed: 0x1299, 0x9ee: 0x12b1, 0x9ef: 0x12c9,
-	0x9f0: 0x12e1, 0x9f1: 0x12f9, 0x9f2: 0x1311, 0x9f3: 0x1329, 0x9f4: 0x1341, 0x9f5: 0x1359,
-	0x9f6: 0x1371, 0x9f7: 0x1389, 0x9f8: 0x05fd, 0x9f9: 0x13a1, 0x9fa: 0x13b9, 0x9fb: 0x13d1,
-	0x9fc: 0x13e1, 0x9fd: 0x13f9, 0x9fe: 0x1411, 0x9ff: 0x1429,
+	0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,
+	0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,
+	0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,
+	0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,
+	0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,
+	0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,
+	0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,
 	// Block 0x28, offset 0xa00
-	0xa00: 0xe00d, 0xa01: 0x0008, 0xa02: 0xe00d, 0xa03: 0x0008, 0xa04: 0xe00d, 0xa05: 0x0008,
-	0xa06: 0xe00d, 0xa07: 0x0008, 0xa08: 0xe00d, 0xa09: 0x0008, 0xa0a: 0xe00d, 0xa0b: 0x0008,
-	0xa0c: 0xe00d, 0xa0d: 0x0008, 0xa0e: 0xe00d, 0xa0f: 0x0008, 0xa10: 0xe00d, 0xa11: 0x0008,
-	0xa12: 0xe00d, 0xa13: 0x0008, 0xa14: 0xe00d, 0xa15: 0x0008, 0xa16: 0xe00d, 0xa17: 0x0008,
-	0xa18: 0xe00d, 0xa19: 0x0008, 0xa1a: 0xe00d, 0xa1b: 0x0008, 0xa1c: 0xe00d, 0xa1d: 0x0008,
-	0xa1e: 0xe00d, 0xa1f: 0x0008, 0xa20: 0xe00d, 0xa21: 0x0008, 0xa22: 0xe00d, 0xa23: 0x0008,
-	0xa24: 0xe00d, 0xa25: 0x0008, 0xa26: 0xe00d, 0xa27: 0x0008, 0xa28: 0xe00d, 0xa29: 0x0008,
-	0xa2a: 0xe00d, 0xa2b: 0x0008, 0xa2c: 0xe00d, 0xa2d: 0x0008, 0xa2e: 0xe00d, 0xa2f: 0x0008,
-	0xa30: 0xe00d, 0xa31: 0x0008, 0xa32: 0xe00d, 0xa33: 0x0008, 0xa34: 0xe00d, 0xa35: 0x0008,
-	0xa36: 0xe00d, 0xa37: 0x0008, 0xa38: 0xe00d, 0xa39: 0x0008, 0xa3a: 0xe00d, 0xa3b: 0x0008,
-	0xa3c: 0xe00d, 0xa3d: 0x0008, 0xa3e: 0xe00d, 0xa3f: 0x0008,
+	0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,
+	0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,
+	0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,
+	0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9,
+	0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099,
+	0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,
+	0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,
+	0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,
+	0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,
+	0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,
+	0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,
 	// Block 0x29, offset 0xa40
-	0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008,
-	0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008,
-	0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008,
-	0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
-	0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0615, 0xa5b: 0x0635, 0xa5c: 0x0008, 0xa5d: 0x0008,
-	0xa5e: 0x1441, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008,
-	0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008,
-	0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008,
-	0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008,
-	0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008,
-	0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008,
+	0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,
+	0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,
+	0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,
+	0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
+	0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,
+	0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,
+	0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251,
+	0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,
+	0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,
+	0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,
+	0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,
 	// Block 0x2a, offset 0xa80
-	0xa80: 0x0008, 0xa81: 0x0008, 0xa82: 0x0008, 0xa83: 0x0008, 0xa84: 0x0008, 0xa85: 0x0008,
-	0xa86: 0x0040, 0xa87: 0x0040, 0xa88: 0xe045, 0xa89: 0xe045, 0xa8a: 0xe045, 0xa8b: 0xe045,
-	0xa8c: 0xe045, 0xa8d: 0xe045, 0xa8e: 0x0040, 0xa8f: 0x0040, 0xa90: 0x0008, 0xa91: 0x0008,
-	0xa92: 0x0008, 0xa93: 0x0008, 0xa94: 0x0008, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008,
-	0xa98: 0x0040, 0xa99: 0xe045, 0xa9a: 0x0040, 0xa9b: 0xe045, 0xa9c: 0x0040, 0xa9d: 0xe045,
-	0xa9e: 0x0040, 0xa9f: 0xe045, 0xaa0: 0x0008, 0xaa1: 0x0008, 0xaa2: 0x0008, 0xaa3: 0x0008,
-	0xaa4: 0x0008, 0xaa5: 0x0008, 0xaa6: 0x0008, 0xaa7: 0x0008, 0xaa8: 0xe045, 0xaa9: 0xe045,
-	0xaaa: 0xe045, 0xaab: 0xe045, 0xaac: 0xe045, 0xaad: 0xe045, 0xaae: 0xe045, 0xaaf: 0xe045,
-	0xab0: 0x0008, 0xab1: 0x1459, 0xab2: 0x0008, 0xab3: 0x1471, 0xab4: 0x0008, 0xab5: 0x1489,
-	0xab6: 0x0008, 0xab7: 0x14a1, 0xab8: 0x0008, 0xab9: 0x14b9, 0xaba: 0x0008, 0xabb: 0x14d1,
-	0xabc: 0x0008, 0xabd: 0x14e9, 0xabe: 0x0040, 0xabf: 0x0040,
+	0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,
+	0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,
+	0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,
+	0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,
+	0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,
+	0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,
+	0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,
+	0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,
+	0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,
+	0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,
+	0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,
 	// Block 0x2b, offset 0xac0
-	0xac0: 0x1501, 0xac1: 0x1531, 0xac2: 0x1561, 0xac3: 0x1591, 0xac4: 0x15c1, 0xac5: 0x15f1,
-	0xac6: 0x1621, 0xac7: 0x1651, 0xac8: 0x1501, 0xac9: 0x1531, 0xaca: 0x1561, 0xacb: 0x1591,
-	0xacc: 0x15c1, 0xacd: 0x15f1, 0xace: 0x1621, 0xacf: 0x1651, 0xad0: 0x1681, 0xad1: 0x16b1,
-	0xad2: 0x16e1, 0xad3: 0x1711, 0xad4: 0x1741, 0xad5: 0x1771, 0xad6: 0x17a1, 0xad7: 0x17d1,
-	0xad8: 0x1681, 0xad9: 0x16b1, 0xada: 0x16e1, 0xadb: 0x1711, 0xadc: 0x1741, 0xadd: 0x1771,
-	0xade: 0x17a1, 0xadf: 0x17d1, 0xae0: 0x1801, 0xae1: 0x1831, 0xae2: 0x1861, 0xae3: 0x1891,
-	0xae4: 0x18c1, 0xae5: 0x18f1, 0xae6: 0x1921, 0xae7: 0x1951, 0xae8: 0x1801, 0xae9: 0x1831,
-	0xaea: 0x1861, 0xaeb: 0x1891, 0xaec: 0x18c1, 0xaed: 0x18f1, 0xaee: 0x1921, 0xaef: 0x1951,
-	0xaf0: 0x0008, 0xaf1: 0x0008, 0xaf2: 0x1981, 0xaf3: 0x19b1, 0xaf4: 0x19d9, 0xaf5: 0x0040,
-	0xaf6: 0x0008, 0xaf7: 0x1a01, 0xaf8: 0xe045, 0xaf9: 0xe045, 0xafa: 0x064d, 0xafb: 0x1459,
-	0xafc: 0x19b1, 0xafd: 0x0666, 0xafe: 0x1a31, 0xaff: 0x0686,
+	0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,
+	0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,
+	0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,
+	0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,
+	0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008,
+	0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,
+	0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,
+	0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,
+	0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,
+	0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,
+	0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,
 	// Block 0x2c, offset 0xb00
-	0xb00: 0x06a6, 0xb01: 0x1a4a, 0xb02: 0x1a79, 0xb03: 0x1aa9, 0xb04: 0x1ad1, 0xb05: 0x0040,
-	0xb06: 0x0008, 0xb07: 0x1af9, 0xb08: 0x06c5, 0xb09: 0x1471, 0xb0a: 0x06dd, 0xb0b: 0x1489,
-	0xb0c: 0x1aa9, 0xb0d: 0x1b2a, 0xb0e: 0x1b5a, 0xb0f: 0x1b8a, 0xb10: 0x0008, 0xb11: 0x0008,
-	0xb12: 0x0008, 0xb13: 0x1bb9, 0xb14: 0x0040, 0xb15: 0x0040, 0xb16: 0x0008, 0xb17: 0x0008,
-	0xb18: 0xe045, 0xb19: 0xe045, 0xb1a: 0x06f5, 0xb1b: 0x14a1, 0xb1c: 0x0040, 0xb1d: 0x1bd2,
-	0xb1e: 0x1c02, 0xb1f: 0x1c32, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x1c61,
+	0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,
+	0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,
+	0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,
+	0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,
+	0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,
+	0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,
 	0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,
-	0xb2a: 0x070d, 0xb2b: 0x14d1, 0xb2c: 0xe04d, 0xb2d: 0x1c7a, 0xb2e: 0x03d2, 0xb2f: 0x1caa,
-	0xb30: 0x0040, 0xb31: 0x0040, 0xb32: 0x1cb9, 0xb33: 0x1ce9, 0xb34: 0x1d11, 0xb35: 0x0040,
-	0xb36: 0x0008, 0xb37: 0x1d39, 0xb38: 0x0725, 0xb39: 0x14b9, 0xb3a: 0x0515, 0xb3b: 0x14e9,
-	0xb3c: 0x1ce9, 0xb3d: 0x073e, 0xb3e: 0x075e, 0xb3f: 0x0040,
+	0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,
+	0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,
+	0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,
+	0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,
 	// Block 0x2d, offset 0xb40
-	0xb40: 0x000a, 0xb41: 0x000a, 0xb42: 0x000a, 0xb43: 0x000a, 0xb44: 0x000a, 0xb45: 0x000a,
-	0xb46: 0x000a, 0xb47: 0x000a, 0xb48: 0x000a, 0xb49: 0x000a, 0xb4a: 0x000a, 0xb4b: 0x03c0,
-	0xb4c: 0x0003, 0xb4d: 0x0003, 0xb4e: 0x0340, 0xb4f: 0x0340, 0xb50: 0x0018, 0xb51: 0xe00d,
-	0xb52: 0x0018, 0xb53: 0x0018, 0xb54: 0x0018, 0xb55: 0x0018, 0xb56: 0x0018, 0xb57: 0x077e,
-	0xb58: 0x0018, 0xb59: 0x0018, 0xb5a: 0x0018, 0xb5b: 0x0018, 0xb5c: 0x0018, 0xb5d: 0x0018,
-	0xb5e: 0x0018, 0xb5f: 0x0018, 0xb60: 0x0018, 0xb61: 0x0018, 0xb62: 0x0018, 0xb63: 0x0018,
-	0xb64: 0x0040, 0xb65: 0x0040, 0xb66: 0x0040, 0xb67: 0x0018, 0xb68: 0x0040, 0xb69: 0x0040,
-	0xb6a: 0x0340, 0xb6b: 0x0340, 0xb6c: 0x0340, 0xb6d: 0x0340, 0xb6e: 0x0340, 0xb6f: 0x000a,
-	0xb70: 0x0018, 0xb71: 0x0018, 0xb72: 0x0018, 0xb73: 0x1d69, 0xb74: 0x1da1, 0xb75: 0x0018,
-	0xb76: 0x1df1, 0xb77: 0x1e29, 0xb78: 0x0018, 0xb79: 0x0018, 0xb7a: 0x0018, 0xb7b: 0x0018,
-	0xb7c: 0x1e7a, 0xb7d: 0x0018, 0xb7e: 0x079e, 0xb7f: 0x0018,
+	0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,
+	0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,
+	0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,
+	0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,
+	0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,
+	0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,
+	0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,
+	0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,
+	0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,
+	0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459,
+	0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686,
 	// Block 0x2e, offset 0xb80
-	0xb80: 0x0018, 0xb81: 0x0018, 0xb82: 0x0018, 0xb83: 0x0018, 0xb84: 0x0018, 0xb85: 0x0018,
-	0xb86: 0x0018, 0xb87: 0x1e92, 0xb88: 0x1eaa, 0xb89: 0x1ec2, 0xb8a: 0x0018, 0xb8b: 0x0018,
-	0xb8c: 0x0018, 0xb8d: 0x0018, 0xb8e: 0x0018, 0xb8f: 0x0018, 0xb90: 0x0018, 0xb91: 0x0018,
-	0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x1ed9,
-	0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018,
-	0xb9e: 0x0018, 0xb9f: 0x000a, 0xba0: 0x03c0, 0xba1: 0x0340, 0xba2: 0x0340, 0xba3: 0x0340,
-	0xba4: 0x03c0, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0040, 0xba8: 0x0040, 0xba9: 0x0040,
-	0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x0340,
-	0xbb0: 0x1f41, 0xbb1: 0x0f41, 0xbb2: 0x0040, 0xbb3: 0x0040, 0xbb4: 0x1f51, 0xbb5: 0x1f61,
-	0xbb6: 0x1f71, 0xbb7: 0x1f81, 0xbb8: 0x1f91, 0xbb9: 0x1fa1, 0xbba: 0x1fb2, 0xbbb: 0x07bd,
-	0xbbc: 0x1fc2, 0xbbd: 0x1fd2, 0xbbe: 0x1fe2, 0xbbf: 0x0f71,
+	0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,
+	0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489,
+	0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,
+	0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,
+	0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,
+	0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,
+	0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,
+	0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,
+	0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,
+	0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,
+	0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040,
 	// Block 0x2f, offset 0xbc0
-	0xbc0: 0x1f41, 0xbc1: 0x00c9, 0xbc2: 0x0069, 0xbc3: 0x0079, 0xbc4: 0x1f51, 0xbc5: 0x1f61,
-	0xbc6: 0x1f71, 0xbc7: 0x1f81, 0xbc8: 0x1f91, 0xbc9: 0x1fa1, 0xbca: 0x1fb2, 0xbcb: 0x07d5,
-	0xbcc: 0x1fc2, 0xbcd: 0x1fd2, 0xbce: 0x1fe2, 0xbcf: 0x0040, 0xbd0: 0x0039, 0xbd1: 0x0f09,
-	0xbd2: 0x00d9, 0xbd3: 0x0369, 0xbd4: 0x0ff9, 0xbd5: 0x0249, 0xbd6: 0x0f51, 0xbd7: 0x0359,
-	0xbd8: 0x0f61, 0xbd9: 0x0f71, 0xbda: 0x0f99, 0xbdb: 0x01d9, 0xbdc: 0x0fa9, 0xbdd: 0x0040,
-	0xbde: 0x0040, 0xbdf: 0x0040, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
-	0xbe4: 0x0018, 0xbe5: 0x0018, 0xbe6: 0x0018, 0xbe7: 0x0018, 0xbe8: 0x1ff1, 0xbe9: 0x0018,
-	0xbea: 0x0018, 0xbeb: 0x0018, 0xbec: 0x0018, 0xbed: 0x0018, 0xbee: 0x0018, 0xbef: 0x0018,
-	0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0018, 0xbf4: 0x0018, 0xbf5: 0x0018,
-	0xbf6: 0x0018, 0xbf7: 0x0018, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
-	0xbfc: 0x0018, 0xbfd: 0x0018, 0xbfe: 0x0018, 0xbff: 0x0040,
+	0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,
+	0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,
+	0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,
+	0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e,
+	0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,
+	0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
+	0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,
+	0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,
+	0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,
+	0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
+	0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018,
 	// Block 0x30, offset 0xc00
-	0xc00: 0x07ee, 0xc01: 0x080e, 0xc02: 0x1159, 0xc03: 0x082d, 0xc04: 0x0018, 0xc05: 0x084e,
-	0xc06: 0x086e, 0xc07: 0x1011, 0xc08: 0x0018, 0xc09: 0x088d, 0xc0a: 0x0f31, 0xc0b: 0x0249,
-	0xc0c: 0x0249, 0xc0d: 0x0249, 0xc0e: 0x0249, 0xc0f: 0x2009, 0xc10: 0x0f41, 0xc11: 0x0f41,
-	0xc12: 0x0359, 0xc13: 0x0359, 0xc14: 0x0018, 0xc15: 0x0f71, 0xc16: 0x2021, 0xc17: 0x0018,
-	0xc18: 0x0018, 0xc19: 0x0f99, 0xc1a: 0x2039, 0xc1b: 0x0269, 0xc1c: 0x0269, 0xc1d: 0x0269,
-	0xc1e: 0x0018, 0xc1f: 0x0018, 0xc20: 0x2049, 0xc21: 0x08ad, 0xc22: 0x2061, 0xc23: 0x0018,
-	0xc24: 0x13d1, 0xc25: 0x0018, 0xc26: 0x2079, 0xc27: 0x0018, 0xc28: 0x13d1, 0xc29: 0x0018,
-	0xc2a: 0x0f51, 0xc2b: 0x2091, 0xc2c: 0x0ee9, 0xc2d: 0x1159, 0xc2e: 0x0018, 0xc2f: 0x0f09,
-	0xc30: 0x0f09, 0xc31: 0x1199, 0xc32: 0x0040, 0xc33: 0x0f61, 0xc34: 0x00d9, 0xc35: 0x20a9,
-	0xc36: 0x20c1, 0xc37: 0x20d9, 0xc38: 0x20f1, 0xc39: 0x0f41, 0xc3a: 0x0018, 0xc3b: 0x08cd,
-	0xc3c: 0x2109, 0xc3d: 0x10b1, 0xc3e: 0x10b1, 0xc3f: 0x2109,
+	0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,
+	0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,
+	0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,
+	0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,
+	0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,
+	0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,
+	0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,
+	0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,
+	0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,
+	0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd,
+	0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,
 	// Block 0x31, offset 0xc40
-	0xc40: 0x08ed, 0xc41: 0x0018, 0xc42: 0x0018, 0xc43: 0x0018, 0xc44: 0x0018, 0xc45: 0x0ef9,
-	0xc46: 0x0ef9, 0xc47: 0x0f09, 0xc48: 0x0f41, 0xc49: 0x0259, 0xc4a: 0x0018, 0xc4b: 0x0018,
-	0xc4c: 0x0018, 0xc4d: 0x0018, 0xc4e: 0x0008, 0xc4f: 0x0018, 0xc50: 0x2121, 0xc51: 0x2151,
-	0xc52: 0x2181, 0xc53: 0x21b9, 0xc54: 0x21e9, 0xc55: 0x2219, 0xc56: 0x2249, 0xc57: 0x2279,
-	0xc58: 0x22a9, 0xc59: 0x22d9, 0xc5a: 0x2309, 0xc5b: 0x2339, 0xc5c: 0x2369, 0xc5d: 0x2399,
-	0xc5e: 0x23c9, 0xc5f: 0x23f9, 0xc60: 0x0f41, 0xc61: 0x2421, 0xc62: 0x0905, 0xc63: 0x2439,
-	0xc64: 0x1089, 0xc65: 0x2451, 0xc66: 0x0925, 0xc67: 0x2469, 0xc68: 0x2491, 0xc69: 0x0369,
-	0xc6a: 0x24a9, 0xc6b: 0x0945, 0xc6c: 0x0359, 0xc6d: 0x1159, 0xc6e: 0x0ef9, 0xc6f: 0x0f61,
-	0xc70: 0x0f41, 0xc71: 0x2421, 0xc72: 0x0965, 0xc73: 0x2439, 0xc74: 0x1089, 0xc75: 0x2451,
-	0xc76: 0x0985, 0xc77: 0x2469, 0xc78: 0x2491, 0xc79: 0x0369, 0xc7a: 0x24a9, 0xc7b: 0x09a5,
-	0xc7c: 0x0359, 0xc7d: 0x1159, 0xc7e: 0x0ef9, 0xc7f: 0x0f61,
+	0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,
+	0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5,
+	0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,
+	0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,
+	0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,
+	0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,
+	0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,
+	0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,
+	0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,
+	0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,
+	0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,
 	// Block 0x32, offset 0xc80
-	0xc80: 0x0018, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0018,
-	0xc86: 0x0018, 0xc87: 0x0018, 0xc88: 0x0018, 0xc89: 0x0018, 0xc8a: 0x0018, 0xc8b: 0x0040,
-	0xc8c: 0x0040, 0xc8d: 0x0040, 0xc8e: 0x0040, 0xc8f: 0x0040, 0xc90: 0x0040, 0xc91: 0x0040,
-	0xc92: 0x0040, 0xc93: 0x0040, 0xc94: 0x0040, 0xc95: 0x0040, 0xc96: 0x0040, 0xc97: 0x0040,
-	0xc98: 0x0040, 0xc99: 0x0040, 0xc9a: 0x0040, 0xc9b: 0x0040, 0xc9c: 0x0040, 0xc9d: 0x0040,
-	0xc9e: 0x0040, 0xc9f: 0x0040, 0xca0: 0x00c9, 0xca1: 0x0069, 0xca2: 0x0079, 0xca3: 0x1f51,
-	0xca4: 0x1f61, 0xca5: 0x1f71, 0xca6: 0x1f81, 0xca7: 0x1f91, 0xca8: 0x1fa1, 0xca9: 0x2601,
-	0xcaa: 0x2619, 0xcab: 0x2631, 0xcac: 0x2649, 0xcad: 0x2661, 0xcae: 0x2679, 0xcaf: 0x2691,
-	0xcb0: 0x26a9, 0xcb1: 0x26c1, 0xcb2: 0x26d9, 0xcb3: 0x26f1, 0xcb4: 0x0a06, 0xcb5: 0x0a26,
-	0xcb6: 0x0a46, 0xcb7: 0x0a66, 0xcb8: 0x0a86, 0xcb9: 0x0aa6, 0xcba: 0x0ac6, 0xcbb: 0x0ae6,
-	0xcbc: 0x0b06, 0xcbd: 0x270a, 0xcbe: 0x2732, 0xcbf: 0x275a,
+	0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e,
+	0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249,
+	0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,
+	0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,
+	0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,
+	0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018,
+	0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,
+	0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,
+	0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,
+	0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd,
+	0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,
 	// Block 0x33, offset 0xcc0
-	0xcc0: 0x2782, 0xcc1: 0x27aa, 0xcc2: 0x27d2, 0xcc3: 0x27fa, 0xcc4: 0x2822, 0xcc5: 0x284a,
-	0xcc6: 0x2872, 0xcc7: 0x289a, 0xcc8: 0x0040, 0xcc9: 0x0040, 0xcca: 0x0040, 0xccb: 0x0040,
-	0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040,
-	0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040,
-	0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0b26, 0xcdd: 0x0b46,
-	0xcde: 0x0b66, 0xcdf: 0x0b86, 0xce0: 0x0ba6, 0xce1: 0x0bc6, 0xce2: 0x0be6, 0xce3: 0x0c06,
-	0xce4: 0x0c26, 0xce5: 0x0c46, 0xce6: 0x0c66, 0xce7: 0x0c86, 0xce8: 0x0ca6, 0xce9: 0x0cc6,
-	0xcea: 0x0ce6, 0xceb: 0x0d06, 0xcec: 0x0d26, 0xced: 0x0d46, 0xcee: 0x0d66, 0xcef: 0x0d86,
-	0xcf0: 0x0da6, 0xcf1: 0x0dc6, 0xcf2: 0x0de6, 0xcf3: 0x0e06, 0xcf4: 0x0e26, 0xcf5: 0x0e46,
-	0xcf6: 0x0039, 0xcf7: 0x0ee9, 0xcf8: 0x1159, 0xcf9: 0x0ef9, 0xcfa: 0x0f09, 0xcfb: 0x1199,
-	0xcfc: 0x0f31, 0xcfd: 0x0249, 0xcfe: 0x0f41, 0xcff: 0x0259,
+	0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,
+	0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,
+	0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,
+	0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,
+	0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,
+	0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439,
+	0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,
+	0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,
+	0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,
+	0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5,
+	0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,
 	// Block 0x34, offset 0xd00
-	0xd00: 0x0f51, 0xd01: 0x0359, 0xd02: 0x0f61, 0xd03: 0x0f71, 0xd04: 0x00d9, 0xd05: 0x0f99,
-	0xd06: 0x2039, 0xd07: 0x0269, 0xd08: 0x01d9, 0xd09: 0x0fa9, 0xd0a: 0x0fb9, 0xd0b: 0x1089,
-	0xd0c: 0x0279, 0xd0d: 0x0369, 0xd0e: 0x0289, 0xd0f: 0x13d1, 0xd10: 0x0039, 0xd11: 0x0ee9,
-	0xd12: 0x1159, 0xd13: 0x0ef9, 0xd14: 0x0f09, 0xd15: 0x1199, 0xd16: 0x0f31, 0xd17: 0x0249,
-	0xd18: 0x0f41, 0xd19: 0x0259, 0xd1a: 0x0f51, 0xd1b: 0x0359, 0xd1c: 0x0f61, 0xd1d: 0x0f71,
-	0xd1e: 0x00d9, 0xd1f: 0x0f99, 0xd20: 0x2039, 0xd21: 0x0269, 0xd22: 0x01d9, 0xd23: 0x0fa9,
-	0xd24: 0x0fb9, 0xd25: 0x1089, 0xd26: 0x0279, 0xd27: 0x0369, 0xd28: 0x0289, 0xd29: 0x13d1,
-	0xd2a: 0x1f41, 0xd2b: 0x0018, 0xd2c: 0x0018, 0xd2d: 0x0018, 0xd2e: 0x0018, 0xd2f: 0x0018,
-	0xd30: 0x0018, 0xd31: 0x0018, 0xd32: 0x0018, 0xd33: 0x0018, 0xd34: 0x0018, 0xd35: 0x0018,
-	0xd36: 0x0018, 0xd37: 0x0018, 0xd38: 0x0018, 0xd39: 0x0018, 0xd3a: 0x0018, 0xd3b: 0x0018,
-	0xd3c: 0x0018, 0xd3d: 0x0018, 0xd3e: 0x0018, 0xd3f: 0x0018,
+	0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,
+	0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,
+	0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,
+	0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,
+	0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,
+	0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,
+	0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,
+	0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,
+	0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26,
+	0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6,
+	0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,
 	// Block 0x35, offset 0xd40
-	0xd40: 0x0008, 0xd41: 0x0008, 0xd42: 0x0008, 0xd43: 0x0008, 0xd44: 0x0008, 0xd45: 0x0008,
-	0xd46: 0x0008, 0xd47: 0x0008, 0xd48: 0x0008, 0xd49: 0x0008, 0xd4a: 0x0008, 0xd4b: 0x0008,
-	0xd4c: 0x0008, 0xd4d: 0x0008, 0xd4e: 0x0008, 0xd4f: 0x0008, 0xd50: 0x0008, 0xd51: 0x0008,
-	0xd52: 0x0008, 0xd53: 0x0008, 0xd54: 0x0008, 0xd55: 0x0008, 0xd56: 0x0008, 0xd57: 0x0008,
-	0xd58: 0x0008, 0xd59: 0x0008, 0xd5a: 0x0008, 0xd5b: 0x0008, 0xd5c: 0x0008, 0xd5d: 0x0008,
-	0xd5e: 0x0008, 0xd5f: 0x0040, 0xd60: 0xe00d, 0xd61: 0x0008, 0xd62: 0x2971, 0xd63: 0x0ebd,
-	0xd64: 0x2989, 0xd65: 0x0008, 0xd66: 0x0008, 0xd67: 0xe07d, 0xd68: 0x0008, 0xd69: 0xe01d,
-	0xd6a: 0x0008, 0xd6b: 0xe03d, 0xd6c: 0x0008, 0xd6d: 0x0fe1, 0xd6e: 0x1281, 0xd6f: 0x0fc9,
-	0xd70: 0x1141, 0xd71: 0x0008, 0xd72: 0xe00d, 0xd73: 0x0008, 0xd74: 0x0008, 0xd75: 0xe01d,
-	0xd76: 0x0008, 0xd77: 0x0008, 0xd78: 0x0008, 0xd79: 0x0008, 0xd7a: 0x0008, 0xd7b: 0x0008,
-	0xd7c: 0x0259, 0xd7d: 0x1089, 0xd7e: 0x29a1, 0xd7f: 0x29b9,
+	0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,
+	0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,
+	0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,
+	0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,
+	0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46,
+	0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06,
+	0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6,
+	0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86,
+	0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46,
+	0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,
+	0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,
 	// Block 0x36, offset 0xd80
-	0xd80: 0xe00d, 0xd81: 0x0008, 0xd82: 0xe00d, 0xd83: 0x0008, 0xd84: 0xe00d, 0xd85: 0x0008,
-	0xd86: 0xe00d, 0xd87: 0x0008, 0xd88: 0xe00d, 0xd89: 0x0008, 0xd8a: 0xe00d, 0xd8b: 0x0008,
-	0xd8c: 0xe00d, 0xd8d: 0x0008, 0xd8e: 0xe00d, 0xd8f: 0x0008, 0xd90: 0xe00d, 0xd91: 0x0008,
-	0xd92: 0xe00d, 0xd93: 0x0008, 0xd94: 0xe00d, 0xd95: 0x0008, 0xd96: 0xe00d, 0xd97: 0x0008,
-	0xd98: 0xe00d, 0xd99: 0x0008, 0xd9a: 0xe00d, 0xd9b: 0x0008, 0xd9c: 0xe00d, 0xd9d: 0x0008,
-	0xd9e: 0xe00d, 0xd9f: 0x0008, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0xe00d, 0xda3: 0x0008,
-	0xda4: 0x0008, 0xda5: 0x0018, 0xda6: 0x0018, 0xda7: 0x0018, 0xda8: 0x0018, 0xda9: 0x0018,
-	0xdaa: 0x0018, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0xe01d, 0xdae: 0x0008, 0xdaf: 0x1308,
-	0xdb0: 0x1308, 0xdb1: 0x1308, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0040, 0xdb5: 0x0040,
-	0xdb6: 0x0040, 0xdb7: 0x0040, 0xdb8: 0x0040, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
+	0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,
+	0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,
+	0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,
+	0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,
+	0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,
+	0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,
+	0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,
+	0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,
+	0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,
+	0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
 	0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,
 	// Block 0x37, offset 0xdc0
-	0xdc0: 0x26fd, 0xdc1: 0x271d, 0xdc2: 0x273d, 0xdc3: 0x275d, 0xdc4: 0x277d, 0xdc5: 0x279d,
-	0xdc6: 0x27bd, 0xdc7: 0x27dd, 0xdc8: 0x27fd, 0xdc9: 0x281d, 0xdca: 0x283d, 0xdcb: 0x285d,
-	0xdcc: 0x287d, 0xdcd: 0x289d, 0xdce: 0x28bd, 0xdcf: 0x28dd, 0xdd0: 0x28fd, 0xdd1: 0x291d,
-	0xdd2: 0x293d, 0xdd3: 0x295d, 0xdd4: 0x297d, 0xdd5: 0x299d, 0xdd6: 0x0040, 0xdd7: 0x0040,
-	0xdd8: 0x0040, 0xdd9: 0x0040, 0xdda: 0x0040, 0xddb: 0x0040, 0xddc: 0x0040, 0xddd: 0x0040,
-	0xdde: 0x0040, 0xddf: 0x0040, 0xde0: 0x0040, 0xde1: 0x0040, 0xde2: 0x0040, 0xde3: 0x0040,
-	0xde4: 0x0040, 0xde5: 0x0040, 0xde6: 0x0040, 0xde7: 0x0040, 0xde8: 0x0040, 0xde9: 0x0040,
-	0xdea: 0x0040, 0xdeb: 0x0040, 0xdec: 0x0040, 0xded: 0x0040, 0xdee: 0x0040, 0xdef: 0x0040,
-	0xdf0: 0x0040, 0xdf1: 0x0040, 0xdf2: 0x0040, 0xdf3: 0x0040, 0xdf4: 0x0040, 0xdf5: 0x0040,
-	0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0040, 0xdfa: 0x0040, 0xdfb: 0x0040,
-	0xdfc: 0x0040, 0xdfd: 0x0040, 0xdfe: 0x0040, 0xdff: 0x0040,
+	0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,
+	0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,
+	0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,
+	0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,
+	0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,
+	0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd,
+	0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,
+	0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,
+	0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,
+	0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,
+	0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,
 	// Block 0x38, offset 0xe00
-	0xe00: 0x000a, 0xe01: 0x0018, 0xe02: 0x29d1, 0xe03: 0x0018, 0xe04: 0x0018, 0xe05: 0x0008,
-	0xe06: 0x0008, 0xe07: 0x0008, 0xe08: 0x0018, 0xe09: 0x0018, 0xe0a: 0x0018, 0xe0b: 0x0018,
-	0xe0c: 0x0018, 0xe0d: 0x0018, 0xe0e: 0x0018, 0xe0f: 0x0018, 0xe10: 0x0018, 0xe11: 0x0018,
-	0xe12: 0x0018, 0xe13: 0x0018, 0xe14: 0x0018, 0xe15: 0x0018, 0xe16: 0x0018, 0xe17: 0x0018,
-	0xe18: 0x0018, 0xe19: 0x0018, 0xe1a: 0x0018, 0xe1b: 0x0018, 0xe1c: 0x0018, 0xe1d: 0x0018,
-	0xe1e: 0x0018, 0xe1f: 0x0018, 0xe20: 0x0018, 0xe21: 0x0018, 0xe22: 0x0018, 0xe23: 0x0018,
-	0xe24: 0x0018, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
-	0xe2a: 0x1308, 0xe2b: 0x1308, 0xe2c: 0x1308, 0xe2d: 0x1308, 0xe2e: 0x1018, 0xe2f: 0x1018,
-	0xe30: 0x0018, 0xe31: 0x0018, 0xe32: 0x0018, 0xe33: 0x0018, 0xe34: 0x0018, 0xe35: 0x0018,
-	0xe36: 0xe125, 0xe37: 0x0018, 0xe38: 0x29bd, 0xe39: 0x29dd, 0xe3a: 0x29fd, 0xe3b: 0x0018,
-	0xe3c: 0x0008, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
+	0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,
+	0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,
+	0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,
+	0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,
+	0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,
+	0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,
+	0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
+	0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,
+	0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,
+	0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,
+	0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
 	// Block 0x39, offset 0xe40
-	0xe40: 0x2b3d, 0xe41: 0x2b5d, 0xe42: 0x2b7d, 0xe43: 0x2b9d, 0xe44: 0x2bbd, 0xe45: 0x2bdd,
-	0xe46: 0x2bdd, 0xe47: 0x2bdd, 0xe48: 0x2bfd, 0xe49: 0x2bfd, 0xe4a: 0x2bfd, 0xe4b: 0x2bfd,
-	0xe4c: 0x2c1d, 0xe4d: 0x2c1d, 0xe4e: 0x2c1d, 0xe4f: 0x2c3d, 0xe50: 0x2c5d, 0xe51: 0x2c5d,
-	0xe52: 0x2a7d, 0xe53: 0x2a7d, 0xe54: 0x2c5d, 0xe55: 0x2c5d, 0xe56: 0x2c7d, 0xe57: 0x2c7d,
-	0xe58: 0x2c5d, 0xe59: 0x2c5d, 0xe5a: 0x2a7d, 0xe5b: 0x2a7d, 0xe5c: 0x2c5d, 0xe5d: 0x2c5d,
-	0xe5e: 0x2c3d, 0xe5f: 0x2c3d, 0xe60: 0x2c9d, 0xe61: 0x2c9d, 0xe62: 0x2cbd, 0xe63: 0x2cbd,
-	0xe64: 0x0040, 0xe65: 0x2cdd, 0xe66: 0x2cfd, 0xe67: 0x2d1d, 0xe68: 0x2d1d, 0xe69: 0x2d3d,
-	0xe6a: 0x2d5d, 0xe6b: 0x2d7d, 0xe6c: 0x2d9d, 0xe6d: 0x2dbd, 0xe6e: 0x2ddd, 0xe6f: 0x2dfd,
-	0xe70: 0x2e1d, 0xe71: 0x2e3d, 0xe72: 0x2e3d, 0xe73: 0x2e5d, 0xe74: 0x2e7d, 0xe75: 0x2e7d,
-	0xe76: 0x2e9d, 0xe77: 0x2ebd, 0xe78: 0x2e5d, 0xe79: 0x2edd, 0xe7a: 0x2efd, 0xe7b: 0x2edd,
-	0xe7c: 0x2e5d, 0xe7d: 0x2f1d, 0xe7e: 0x2f3d, 0xe7f: 0x2f5d,
+	0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d,
+	0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d,
+	0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d,
+	0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040,
+	0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,
+	0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,
+	0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,
+	0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,
+	0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,
+	0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,
+	0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,
 	// Block 0x3a, offset 0xe80
-	0xe80: 0x2f7d, 0xe81: 0x2f9d, 0xe82: 0x2cfd, 0xe83: 0x2cdd, 0xe84: 0x2fbd, 0xe85: 0x2fdd,
-	0xe86: 0x2ffd, 0xe87: 0x301d, 0xe88: 0x303d, 0xe89: 0x305d, 0xe8a: 0x307d, 0xe8b: 0x309d,
-	0xe8c: 0x30bd, 0xe8d: 0x30dd, 0xe8e: 0x30fd, 0xe8f: 0x0040, 0xe90: 0x0018, 0xe91: 0x0018,
-	0xe92: 0x311d, 0xe93: 0x313d, 0xe94: 0x315d, 0xe95: 0x317d, 0xe96: 0x319d, 0xe97: 0x31bd,
-	0xe98: 0x31dd, 0xe99: 0x31fd, 0xe9a: 0x321d, 0xe9b: 0x323d, 0xe9c: 0x315d, 0xe9d: 0x325d,
-	0xe9e: 0x327d, 0xe9f: 0x329d, 0xea0: 0x0008, 0xea1: 0x0008, 0xea2: 0x0008, 0xea3: 0x0008,
-	0xea4: 0x0008, 0xea5: 0x0008, 0xea6: 0x0008, 0xea7: 0x0008, 0xea8: 0x0008, 0xea9: 0x0008,
-	0xeaa: 0x0008, 0xeab: 0x0008, 0xeac: 0x0008, 0xead: 0x0008, 0xeae: 0x0008, 0xeaf: 0x0008,
-	0xeb0: 0x0008, 0xeb1: 0x0008, 0xeb2: 0x0008, 0xeb3: 0x0008, 0xeb4: 0x0008, 0xeb5: 0x0008,
-	0xeb6: 0x0008, 0xeb7: 0x0008, 0xeb8: 0x0008, 0xeb9: 0x0008, 0xeba: 0x0008, 0xebb: 0x0040,
-	0xebc: 0x0040, 0xebd: 0x0040, 0xebe: 0x0040, 0xebf: 0x0040,
+	0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,
+	0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,
+	0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,
+	0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,
+	0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,
+	0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,
+	0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,
+	0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,
+	0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,
+	0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018,
+	0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,
 	// Block 0x3b, offset 0xec0
-	0xec0: 0x36a2, 0xec1: 0x36d2, 0xec2: 0x3702, 0xec3: 0x3732, 0xec4: 0x32bd, 0xec5: 0x32dd,
-	0xec6: 0x32fd, 0xec7: 0x331d, 0xec8: 0x0018, 0xec9: 0x0018, 0xeca: 0x0018, 0xecb: 0x0018,
-	0xecc: 0x0018, 0xecd: 0x0018, 0xece: 0x0018, 0xecf: 0x0018, 0xed0: 0x333d, 0xed1: 0x3761,
-	0xed2: 0x3779, 0xed3: 0x3791, 0xed4: 0x37a9, 0xed5: 0x37c1, 0xed6: 0x37d9, 0xed7: 0x37f1,
-	0xed8: 0x3809, 0xed9: 0x3821, 0xeda: 0x3839, 0xedb: 0x3851, 0xedc: 0x3869, 0xedd: 0x3881,
-	0xede: 0x3899, 0xedf: 0x38b1, 0xee0: 0x335d, 0xee1: 0x337d, 0xee2: 0x339d, 0xee3: 0x33bd,
-	0xee4: 0x33dd, 0xee5: 0x33dd, 0xee6: 0x33fd, 0xee7: 0x341d, 0xee8: 0x343d, 0xee9: 0x345d,
-	0xeea: 0x347d, 0xeeb: 0x349d, 0xeec: 0x34bd, 0xeed: 0x34dd, 0xeee: 0x34fd, 0xeef: 0x351d,
-	0xef0: 0x353d, 0xef1: 0x355d, 0xef2: 0x357d, 0xef3: 0x359d, 0xef4: 0x35bd, 0xef5: 0x35dd,
-	0xef6: 0x35fd, 0xef7: 0x361d, 0xef8: 0x363d, 0xef9: 0x365d, 0xefa: 0x367d, 0xefb: 0x369d,
-	0xefc: 0x38c9, 0xefd: 0x3901, 0xefe: 0x36bd, 0xeff: 0x0018,
+	0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd,
+	0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd,
+	0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d,
+	0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d,
+	0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d,
+	0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd,
+	0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d,
+	0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd,
+	0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d,
+	0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd,
+	0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d,
 	// Block 0x3c, offset 0xf00
-	0xf00: 0x36dd, 0xf01: 0x36fd, 0xf02: 0x371d, 0xf03: 0x373d, 0xf04: 0x375d, 0xf05: 0x377d,
-	0xf06: 0x379d, 0xf07: 0x37bd, 0xf08: 0x37dd, 0xf09: 0x37fd, 0xf0a: 0x381d, 0xf0b: 0x383d,
-	0xf0c: 0x385d, 0xf0d: 0x387d, 0xf0e: 0x389d, 0xf0f: 0x38bd, 0xf10: 0x38dd, 0xf11: 0x38fd,
-	0xf12: 0x391d, 0xf13: 0x393d, 0xf14: 0x395d, 0xf15: 0x397d, 0xf16: 0x399d, 0xf17: 0x39bd,
-	0xf18: 0x39dd, 0xf19: 0x39fd, 0xf1a: 0x3a1d, 0xf1b: 0x3a3d, 0xf1c: 0x3a5d, 0xf1d: 0x3a7d,
-	0xf1e: 0x3a9d, 0xf1f: 0x3abd, 0xf20: 0x3add, 0xf21: 0x3afd, 0xf22: 0x3b1d, 0xf23: 0x3b3d,
-	0xf24: 0x3b5d, 0xf25: 0x3b7d, 0xf26: 0x127d, 0xf27: 0x3b9d, 0xf28: 0x3bbd, 0xf29: 0x3bdd,
-	0xf2a: 0x3bfd, 0xf2b: 0x3c1d, 0xf2c: 0x3c3d, 0xf2d: 0x3c5d, 0xf2e: 0x239d, 0xf2f: 0x3c7d,
-	0xf30: 0x3c9d, 0xf31: 0x3939, 0xf32: 0x3951, 0xf33: 0x3969, 0xf34: 0x3981, 0xf35: 0x3999,
-	0xf36: 0x39b1, 0xf37: 0x39c9, 0xf38: 0x39e1, 0xf39: 0x39f9, 0xf3a: 0x3a11, 0xf3b: 0x3a29,
-	0xf3c: 0x3a41, 0xf3d: 0x3a59, 0xf3e: 0x3a71, 0xf3f: 0x3a89,
+	0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd,
+	0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d,
+	0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,
+	0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd,
+	0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d,
+	0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,
+	0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,
+	0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,
+	0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,
+	0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,
+	0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,
 	// Block 0x3d, offset 0xf40
-	0xf40: 0x3aa1, 0xf41: 0x3ac9, 0xf42: 0x3af1, 0xf43: 0x3b19, 0xf44: 0x3b41, 0xf45: 0x3b69,
-	0xf46: 0x3b91, 0xf47: 0x3bb9, 0xf48: 0x3be1, 0xf49: 0x3c09, 0xf4a: 0x3c39, 0xf4b: 0x3c69,
-	0xf4c: 0x3c99, 0xf4d: 0x3cbd, 0xf4e: 0x3cb1, 0xf4f: 0x3cdd, 0xf50: 0x3cfd, 0xf51: 0x3d15,
-	0xf52: 0x3d2d, 0xf53: 0x3d45, 0xf54: 0x3d5d, 0xf55: 0x3d5d, 0xf56: 0x3d45, 0xf57: 0x3d75,
-	0xf58: 0x07bd, 0xf59: 0x3d8d, 0xf5a: 0x3da5, 0xf5b: 0x3dbd, 0xf5c: 0x3dd5, 0xf5d: 0x3ded,
-	0xf5e: 0x3e05, 0xf5f: 0x3e1d, 0xf60: 0x3e35, 0xf61: 0x3e4d, 0xf62: 0x3e65, 0xf63: 0x3e7d,
-	0xf64: 0x3e95, 0xf65: 0x3e95, 0xf66: 0x3ead, 0xf67: 0x3ead, 0xf68: 0x3ec5, 0xf69: 0x3ec5,
-	0xf6a: 0x3edd, 0xf6b: 0x3ef5, 0xf6c: 0x3f0d, 0xf6d: 0x3f25, 0xf6e: 0x3f3d, 0xf6f: 0x3f3d,
-	0xf70: 0x3f55, 0xf71: 0x3f55, 0xf72: 0x3f55, 0xf73: 0x3f6d, 0xf74: 0x3f85, 0xf75: 0x3f9d,
-	0xf76: 0x3fb5, 0xf77: 0x3f9d, 0xf78: 0x3fcd, 0xf79: 0x3fe5, 0xf7a: 0x3f6d, 0xf7b: 0x3ffd,
-	0xf7c: 0x4015, 0xf7d: 0x4015, 0xf7e: 0x4015, 0xf7f: 0x0040,
+	0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd,
+	0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,
+	0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761,
+	0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,
+	0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,
+	0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd,
+	0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d,
+	0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d,
+	0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd,
+	0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d,
+	0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018,
 	// Block 0x3e, offset 0xf80
-	0xf80: 0x3cc9, 0xf81: 0x3d31, 0xf82: 0x3d99, 0xf83: 0x3e01, 0xf84: 0x3e51, 0xf85: 0x3eb9,
-	0xf86: 0x3f09, 0xf87: 0x3f59, 0xf88: 0x3fd9, 0xf89: 0x4041, 0xf8a: 0x4091, 0xf8b: 0x40e1,
-	0xf8c: 0x4131, 0xf8d: 0x4199, 0xf8e: 0x4201, 0xf8f: 0x4251, 0xf90: 0x42a1, 0xf91: 0x42d9,
-	0xf92: 0x4329, 0xf93: 0x4391, 0xf94: 0x43f9, 0xf95: 0x4431, 0xf96: 0x44b1, 0xf97: 0x4549,
-	0xf98: 0x45c9, 0xf99: 0x4619, 0xf9a: 0x4699, 0xf9b: 0x4719, 0xf9c: 0x4781, 0xf9d: 0x47d1,
-	0xf9e: 0x4821, 0xf9f: 0x4871, 0xfa0: 0x48d9, 0xfa1: 0x4959, 0xfa2: 0x49c1, 0xfa3: 0x4a11,
-	0xfa4: 0x4a61, 0xfa5: 0x4ab1, 0xfa6: 0x4ae9, 0xfa7: 0x4b21, 0xfa8: 0x4b59, 0xfa9: 0x4b91,
-	0xfaa: 0x4be1, 0xfab: 0x4c31, 0xfac: 0x4cb1, 0xfad: 0x4d01, 0xfae: 0x4d69, 0xfaf: 0x4de9,
-	0xfb0: 0x4e39, 0xfb1: 0x4e71, 0xfb2: 0x4ea9, 0xfb3: 0x4f29, 0xfb4: 0x4f91, 0xfb5: 0x5011,
-	0xfb6: 0x5061, 0xfb7: 0x50e1, 0xfb8: 0x5119, 0xfb9: 0x5169, 0xfba: 0x51b9, 0xfbb: 0x5209,
-	0xfbc: 0x5259, 0xfbd: 0x52a9, 0xfbe: 0x5311, 0xfbf: 0x5361,
+	0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d,
+	0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d,
+	0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd,
+	0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd,
+	0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d,
+	0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d,
+	0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd,
+	0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d,
+	0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,
+	0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,
+	0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,
 	// Block 0x3f, offset 0xfc0
-	0xfc0: 0x5399, 0xfc1: 0x53e9, 0xfc2: 0x5439, 0xfc3: 0x5489, 0xfc4: 0x54f1, 0xfc5: 0x5541,
-	0xfc6: 0x5591, 0xfc7: 0x55e1, 0xfc8: 0x5661, 0xfc9: 0x56c9, 0xfca: 0x5701, 0xfcb: 0x5781,
-	0xfcc: 0x57b9, 0xfcd: 0x5821, 0xfce: 0x5889, 0xfcf: 0x58d9, 0xfd0: 0x5929, 0xfd1: 0x5979,
-	0xfd2: 0x59e1, 0xfd3: 0x5a19, 0xfd4: 0x5a69, 0xfd5: 0x5ad1, 0xfd6: 0x5b09, 0xfd7: 0x5b89,
-	0xfd8: 0x5bd9, 0xfd9: 0x5c01, 0xfda: 0x5c29, 0xfdb: 0x5c51, 0xfdc: 0x5c79, 0xfdd: 0x5ca1,
-	0xfde: 0x5cc9, 0xfdf: 0x5cf1, 0xfe0: 0x5d19, 0xfe1: 0x5d41, 0xfe2: 0x5d69, 0xfe3: 0x5d99,
-	0xfe4: 0x5dc9, 0xfe5: 0x5df9, 0xfe6: 0x5e29, 0xfe7: 0x5e59, 0xfe8: 0x5e89, 0xfe9: 0x5eb9,
-	0xfea: 0x5ee9, 0xfeb: 0x5f19, 0xfec: 0x5f49, 0xfed: 0x5f79, 0xfee: 0x5fa9, 0xfef: 0x5fd9,
-	0xff0: 0x6009, 0xff1: 0x402d, 0xff2: 0x6039, 0xff3: 0x6051, 0xff4: 0x404d, 0xff5: 0x6069,
-	0xff6: 0x6081, 0xff7: 0x6099, 0xff8: 0x406d, 0xff9: 0x406d, 0xffa: 0x60b1, 0xffb: 0x60c9,
-	0xffc: 0x6101, 0xffd: 0x6139, 0xffe: 0x6171, 0xfff: 0x61a9,
+	0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,
+	0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,
+	0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15,
+	0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75,
+	0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded,
+	0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d,
+	0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5,
+	0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d,
+	0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d,
+	0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd,
+	0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040,
 	// Block 0x40, offset 0x1000
-	0x1000: 0x6211, 0x1001: 0x6229, 0x1002: 0x408d, 0x1003: 0x6241, 0x1004: 0x6259, 0x1005: 0x6271,
-	0x1006: 0x6289, 0x1007: 0x62a1, 0x1008: 0x40ad, 0x1009: 0x62b9, 0x100a: 0x62e1, 0x100b: 0x62f9,
-	0x100c: 0x40cd, 0x100d: 0x40cd, 0x100e: 0x6311, 0x100f: 0x6329, 0x1010: 0x6341, 0x1011: 0x40ed,
-	0x1012: 0x410d, 0x1013: 0x412d, 0x1014: 0x414d, 0x1015: 0x416d, 0x1016: 0x6359, 0x1017: 0x6371,
-	0x1018: 0x6389, 0x1019: 0x63a1, 0x101a: 0x63b9, 0x101b: 0x418d, 0x101c: 0x63d1, 0x101d: 0x63e9,
-	0x101e: 0x6401, 0x101f: 0x41ad, 0x1020: 0x41cd, 0x1021: 0x6419, 0x1022: 0x41ed, 0x1023: 0x420d,
-	0x1024: 0x422d, 0x1025: 0x6431, 0x1026: 0x424d, 0x1027: 0x6449, 0x1028: 0x6479, 0x1029: 0x6211,
-	0x102a: 0x426d, 0x102b: 0x428d, 0x102c: 0x42ad, 0x102d: 0x42cd, 0x102e: 0x64b1, 0x102f: 0x64f1,
-	0x1030: 0x6539, 0x1031: 0x6551, 0x1032: 0x42ed, 0x1033: 0x6569, 0x1034: 0x6581, 0x1035: 0x6599,
-	0x1036: 0x430d, 0x1037: 0x65b1, 0x1038: 0x65c9, 0x1039: 0x65b1, 0x103a: 0x65e1, 0x103b: 0x65f9,
-	0x103c: 0x432d, 0x103d: 0x6611, 0x103e: 0x6629, 0x103f: 0x6611,
+	0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,
+	0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,
+	0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,
+	0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,
+	0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,
+	0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,
+	0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,
+	0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,
+	0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,
+	0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,
+	0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,
 	// Block 0x41, offset 0x1040
-	0x1040: 0x434d, 0x1041: 0x436d, 0x1042: 0x0040, 0x1043: 0x6641, 0x1044: 0x6659, 0x1045: 0x6671,
-	0x1046: 0x6689, 0x1047: 0x0040, 0x1048: 0x66c1, 0x1049: 0x66d9, 0x104a: 0x66f1, 0x104b: 0x6709,
-	0x104c: 0x6721, 0x104d: 0x6739, 0x104e: 0x6401, 0x104f: 0x6751, 0x1050: 0x6769, 0x1051: 0x6781,
-	0x1052: 0x438d, 0x1053: 0x6799, 0x1054: 0x6289, 0x1055: 0x43ad, 0x1056: 0x43cd, 0x1057: 0x67b1,
-	0x1058: 0x0040, 0x1059: 0x43ed, 0x105a: 0x67c9, 0x105b: 0x67e1, 0x105c: 0x67f9, 0x105d: 0x6811,
-	0x105e: 0x6829, 0x105f: 0x6859, 0x1060: 0x6889, 0x1061: 0x68b1, 0x1062: 0x68d9, 0x1063: 0x6901,
-	0x1064: 0x6929, 0x1065: 0x6951, 0x1066: 0x6979, 0x1067: 0x69a1, 0x1068: 0x69c9, 0x1069: 0x69f1,
-	0x106a: 0x6a21, 0x106b: 0x6a51, 0x106c: 0x6a81, 0x106d: 0x6ab1, 0x106e: 0x6ae1, 0x106f: 0x6b11,
-	0x1070: 0x6b41, 0x1071: 0x6b71, 0x1072: 0x6ba1, 0x1073: 0x6bd1, 0x1074: 0x6c01, 0x1075: 0x6c31,
-	0x1076: 0x6c61, 0x1077: 0x6c91, 0x1078: 0x6cc1, 0x1079: 0x6cf1, 0x107a: 0x6d21, 0x107b: 0x6d51,
-	0x107c: 0x6d81, 0x107d: 0x6db1, 0x107e: 0x6de1, 0x107f: 0x440d,
+	0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,
+	0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,
+	0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,
+	0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,
+	0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,
+	0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,
+	0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,
+	0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,
+	0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069,
+	0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9,
+	0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,
 	// Block 0x42, offset 0x1080
-	0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008,
-	0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008,
-	0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008,
-	0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008,
-	0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008,
-	0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008,
-	0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008,
-	0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x1308,
-	0x10b0: 0x1318, 0x10b1: 0x1318, 0x10b2: 0x1318, 0x10b3: 0x0018, 0x10b4: 0x1308, 0x10b5: 0x1308,
-	0x10b6: 0x1308, 0x10b7: 0x1308, 0x10b8: 0x1308, 0x10b9: 0x1308, 0x10ba: 0x1308, 0x10bb: 0x1308,
-	0x10bc: 0x1308, 0x10bd: 0x1308, 0x10be: 0x0018, 0x10bf: 0x0008,
+	0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,
+	0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,
+	0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed,
+	0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371,
+	0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9,
+	0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d,
+	0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,
+	0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1,
+	0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,
+	0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,
+	0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,
 	// Block 0x43, offset 0x10c0
-	0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,
-	0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,
-	0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,
-	0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,
-	0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x0ea1, 0x10dd: 0x6e11,
-	0x10de: 0x1308, 0x10df: 0x1308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008,
-	0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008,
-	0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008,
-	0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008,
-	0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008,
-	0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008,
+	0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,
+	0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,
+	0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,
+	0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1,
+	0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,
+	0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,
+	0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,
+	0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,
+	0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,
+	0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,
+	0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d,
 	// Block 0x44, offset 0x1100
-	0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018,
-	0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018,
-	0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018,
-	0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008,
-	0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008,
-	0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008,
+	0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,
+	0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,
+	0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,
+	0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,
+	0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,
+	0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,
 	0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,
-	0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008,
-	0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008,
-	0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008,
-	0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008,
+	0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,
+	0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,
+	0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,
+	0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,
 	// Block 0x45, offset 0x1140
 	0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,
 	0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,
 	0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,
 	0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,
-	0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008,
-	0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008,
-	0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,
-	0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,
-	0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
-	0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d,
-	0x117c: 0x0008, 0x117d: 0x442d, 0x117e: 0xe00d, 0x117f: 0x0008,
+	0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,
+	0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,
+	0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,
+	0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,
+	0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
+	0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,
+	0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,
 	// Block 0x46, offset 0x1180
-	0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,
-	0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d,
-	0x118c: 0x0008, 0x118d: 0x11d9, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,
-	0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,
-	0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,
-	0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,
+	0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,
+	0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,
+	0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,
+	0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,
+	0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,
+	0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,
 	0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,
-	0x11aa: 0x6e29, 0x11ab: 0x1029, 0x11ac: 0x11c1, 0x11ad: 0x6e41, 0x11ae: 0x1221, 0x11af: 0x0040,
-	0x11b0: 0x6e59, 0x11b1: 0x6e71, 0x11b2: 0x1239, 0x11b3: 0x444d, 0x11b4: 0xe00d, 0x11b5: 0x0008,
-	0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0x0040, 0x11b9: 0x0040, 0x11ba: 0x0040, 0x11bb: 0x0040,
-	0x11bc: 0x0040, 0x11bd: 0x0040, 0x11be: 0x0040, 0x11bf: 0x0040,
+	0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,
+	0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,
+	0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,
+	0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,
 	// Block 0x47, offset 0x11c0
-	0x11c0: 0x64d5, 0x11c1: 0x64f5, 0x11c2: 0x6515, 0x11c3: 0x6535, 0x11c4: 0x6555, 0x11c5: 0x6575,
-	0x11c6: 0x6595, 0x11c7: 0x65b5, 0x11c8: 0x65d5, 0x11c9: 0x65f5, 0x11ca: 0x6615, 0x11cb: 0x6635,
-	0x11cc: 0x6655, 0x11cd: 0x6675, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x6695, 0x11d1: 0x0008,
-	0x11d2: 0x66b5, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x66d5, 0x11d6: 0x66f5, 0x11d7: 0x6715,
-	0x11d8: 0x6735, 0x11d9: 0x6755, 0x11da: 0x6775, 0x11db: 0x6795, 0x11dc: 0x67b5, 0x11dd: 0x67d5,
-	0x11de: 0x67f5, 0x11df: 0x0008, 0x11e0: 0x6815, 0x11e1: 0x0008, 0x11e2: 0x6835, 0x11e3: 0x0008,
-	0x11e4: 0x0008, 0x11e5: 0x6855, 0x11e6: 0x6875, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008,
-	0x11ea: 0x6895, 0x11eb: 0x68b5, 0x11ec: 0x68d5, 0x11ed: 0x68f5, 0x11ee: 0x6915, 0x11ef: 0x6935,
-	0x11f0: 0x6955, 0x11f1: 0x6975, 0x11f2: 0x6995, 0x11f3: 0x69b5, 0x11f4: 0x69d5, 0x11f5: 0x69f5,
-	0x11f6: 0x6a15, 0x11f7: 0x6a35, 0x11f8: 0x6a55, 0x11f9: 0x6a75, 0x11fa: 0x6a95, 0x11fb: 0x6ab5,
-	0x11fc: 0x6ad5, 0x11fd: 0x6af5, 0x11fe: 0x6b15, 0x11ff: 0x6b35,
+	0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,
+	0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,
+	0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,
+	0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,
+	0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,
+	0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,
+	0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,
+	0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,
+	0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,
+	0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,
+	0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008,
 	// Block 0x48, offset 0x1200
-	0x1200: 0x7a95, 0x1201: 0x7ab5, 0x1202: 0x7ad5, 0x1203: 0x7af5, 0x1204: 0x7b15, 0x1205: 0x7b35,
-	0x1206: 0x7b55, 0x1207: 0x7b75, 0x1208: 0x7b95, 0x1209: 0x7bb5, 0x120a: 0x7bd5, 0x120b: 0x7bf5,
-	0x120c: 0x7c15, 0x120d: 0x7c35, 0x120e: 0x7c55, 0x120f: 0x6ec9, 0x1210: 0x6ef1, 0x1211: 0x6f19,
-	0x1212: 0x7c75, 0x1213: 0x7c95, 0x1214: 0x7cb5, 0x1215: 0x6f41, 0x1216: 0x6f69, 0x1217: 0x6f91,
-	0x1218: 0x7cd5, 0x1219: 0x7cf5, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,
-	0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,
-	0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,
-	0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,
-	0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040,
-	0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,
+	0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,
+	0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,
+	0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,
+	0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,
+	0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,
+	0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,
+	0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,
+	0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040,
+	0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008,
+	0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,
 	0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,
 	// Block 0x49, offset 0x1240
-	0x1240: 0x6fb9, 0x1241: 0x6fd1, 0x1242: 0x6fe9, 0x1243: 0x7d15, 0x1244: 0x7d35, 0x1245: 0x7001,
-	0x1246: 0x7001, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040,
-	0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040,
-	0x1252: 0x0040, 0x1253: 0x7019, 0x1254: 0x7041, 0x1255: 0x7069, 0x1256: 0x7091, 0x1257: 0x70b9,
-	0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x70e1,
-	0x125e: 0x1308, 0x125f: 0x7109, 0x1260: 0x7131, 0x1261: 0x20a9, 0x1262: 0x20f1, 0x1263: 0x7149,
-	0x1264: 0x7161, 0x1265: 0x7179, 0x1266: 0x7191, 0x1267: 0x71a9, 0x1268: 0x71c1, 0x1269: 0x1fb2,
-	0x126a: 0x71d9, 0x126b: 0x7201, 0x126c: 0x7229, 0x126d: 0x7261, 0x126e: 0x7299, 0x126f: 0x72c1,
-	0x1270: 0x72e9, 0x1271: 0x7311, 0x1272: 0x7339, 0x1273: 0x7361, 0x1274: 0x7389, 0x1275: 0x73b1,
-	0x1276: 0x73d9, 0x1277: 0x0040, 0x1278: 0x7401, 0x1279: 0x7429, 0x127a: 0x7451, 0x127b: 0x7479,
-	0x127c: 0x74a1, 0x127d: 0x0040, 0x127e: 0x74c9, 0x127f: 0x0040,
+	0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575,
+	0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635,
+	0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008,
+	0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715,
+	0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5,
+	0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008,
+	0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,
+	0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935,
+	0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5,
+	0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5,
+	0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35,
 	// Block 0x4a, offset 0x1280
-	0x1280: 0x74f1, 0x1281: 0x7519, 0x1282: 0x0040, 0x1283: 0x7541, 0x1284: 0x7569, 0x1285: 0x0040,
-	0x1286: 0x7591, 0x1287: 0x75b9, 0x1288: 0x75e1, 0x1289: 0x7609, 0x128a: 0x7631, 0x128b: 0x7659,
-	0x128c: 0x7681, 0x128d: 0x76a9, 0x128e: 0x76d1, 0x128f: 0x76f9, 0x1290: 0x7721, 0x1291: 0x7721,
-	0x1292: 0x7739, 0x1293: 0x7739, 0x1294: 0x7739, 0x1295: 0x7739, 0x1296: 0x7751, 0x1297: 0x7751,
-	0x1298: 0x7751, 0x1299: 0x7751, 0x129a: 0x7769, 0x129b: 0x7769, 0x129c: 0x7769, 0x129d: 0x7769,
-	0x129e: 0x7781, 0x129f: 0x7781, 0x12a0: 0x7781, 0x12a1: 0x7781, 0x12a2: 0x7799, 0x12a3: 0x7799,
-	0x12a4: 0x7799, 0x12a5: 0x7799, 0x12a6: 0x77b1, 0x12a7: 0x77b1, 0x12a8: 0x77b1, 0x12a9: 0x77b1,
-	0x12aa: 0x77c9, 0x12ab: 0x77c9, 0x12ac: 0x77c9, 0x12ad: 0x77c9, 0x12ae: 0x77e1, 0x12af: 0x77e1,
-	0x12b0: 0x77e1, 0x12b1: 0x77e1, 0x12b2: 0x77f9, 0x12b3: 0x77f9, 0x12b4: 0x77f9, 0x12b5: 0x77f9,
-	0x12b6: 0x7811, 0x12b7: 0x7811, 0x12b8: 0x7811, 0x12b9: 0x7811, 0x12ba: 0x7829, 0x12bb: 0x7829,
-	0x12bc: 0x7829, 0x12bd: 0x7829, 0x12be: 0x7841, 0x12bf: 0x7841,
+	0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35,
+	0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5,
+	0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,
+	0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,
+	0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,
+	0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,
+	0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,
+	0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,
+	0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,
+	0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,
+	0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,
 	// Block 0x4b, offset 0x12c0
-	0x12c0: 0x7841, 0x12c1: 0x7841, 0x12c2: 0x7859, 0x12c3: 0x7859, 0x12c4: 0x7871, 0x12c5: 0x7871,
-	0x12c6: 0x7889, 0x12c7: 0x7889, 0x12c8: 0x78a1, 0x12c9: 0x78a1, 0x12ca: 0x78b9, 0x12cb: 0x78b9,
-	0x12cc: 0x78d1, 0x12cd: 0x78d1, 0x12ce: 0x78e9, 0x12cf: 0x78e9, 0x12d0: 0x78e9, 0x12d1: 0x78e9,
-	0x12d2: 0x7901, 0x12d3: 0x7901, 0x12d4: 0x7901, 0x12d5: 0x7901, 0x12d6: 0x7919, 0x12d7: 0x7919,
-	0x12d8: 0x7919, 0x12d9: 0x7919, 0x12da: 0x7931, 0x12db: 0x7931, 0x12dc: 0x7931, 0x12dd: 0x7931,
-	0x12de: 0x7949, 0x12df: 0x7949, 0x12e0: 0x7961, 0x12e1: 0x7961, 0x12e2: 0x7961, 0x12e3: 0x7961,
-	0x12e4: 0x7979, 0x12e5: 0x7979, 0x12e6: 0x7991, 0x12e7: 0x7991, 0x12e8: 0x7991, 0x12e9: 0x7991,
-	0x12ea: 0x79a9, 0x12eb: 0x79a9, 0x12ec: 0x79a9, 0x12ed: 0x79a9, 0x12ee: 0x79c1, 0x12ef: 0x79c1,
-	0x12f0: 0x79d9, 0x12f1: 0x79d9, 0x12f2: 0x0018, 0x12f3: 0x0018, 0x12f4: 0x0018, 0x12f5: 0x0018,
-	0x12f6: 0x0018, 0x12f7: 0x0018, 0x12f8: 0x0018, 0x12f9: 0x0018, 0x12fa: 0x0018, 0x12fb: 0x0018,
-	0x12fc: 0x0018, 0x12fd: 0x0018, 0x12fe: 0x0018, 0x12ff: 0x0018,
+	0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001,
+	0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,
+	0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,
+	0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,
+	0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,
+	0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,
+	0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,
+	0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,
+	0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,
+	0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,
+	0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,
 	// Block 0x4c, offset 0x1300
-	0x1300: 0x0018, 0x1301: 0x0018, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040,
-	0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040,
-	0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040,
-	0x1312: 0x0040, 0x1313: 0x79f1, 0x1314: 0x79f1, 0x1315: 0x79f1, 0x1316: 0x79f1, 0x1317: 0x7a09,
-	0x1318: 0x7a09, 0x1319: 0x7a21, 0x131a: 0x7a21, 0x131b: 0x7a39, 0x131c: 0x7a39, 0x131d: 0x0479,
-	0x131e: 0x7a51, 0x131f: 0x7a51, 0x1320: 0x7a69, 0x1321: 0x7a69, 0x1322: 0x7a81, 0x1323: 0x7a81,
-	0x1324: 0x7a99, 0x1325: 0x7a99, 0x1326: 0x7a99, 0x1327: 0x7a99, 0x1328: 0x7ab1, 0x1329: 0x7ab1,
-	0x132a: 0x7ac9, 0x132b: 0x7ac9, 0x132c: 0x7af1, 0x132d: 0x7af1, 0x132e: 0x7b19, 0x132f: 0x7b19,
-	0x1330: 0x7b41, 0x1331: 0x7b41, 0x1332: 0x7b69, 0x1333: 0x7b69, 0x1334: 0x7b91, 0x1335: 0x7b91,
-	0x1336: 0x7bb9, 0x1337: 0x7bb9, 0x1338: 0x7bb9, 0x1339: 0x7be1, 0x133a: 0x7be1, 0x133b: 0x7be1,
-	0x133c: 0x7c09, 0x133d: 0x7c09, 0x133e: 0x7c09, 0x133f: 0x7c09,
+	0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,
+	0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,
+	0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,
+	0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,
+	0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,
+	0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,
+	0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,
+	0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,
+	0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,
+	0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,
+	0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,
 	// Block 0x4d, offset 0x1340
-	0x1340: 0x85f9, 0x1341: 0x8621, 0x1342: 0x8649, 0x1343: 0x8671, 0x1344: 0x8699, 0x1345: 0x86c1,
-	0x1346: 0x86e9, 0x1347: 0x8711, 0x1348: 0x8739, 0x1349: 0x8761, 0x134a: 0x8789, 0x134b: 0x87b1,
-	0x134c: 0x87d9, 0x134d: 0x8801, 0x134e: 0x8829, 0x134f: 0x8851, 0x1350: 0x8879, 0x1351: 0x88a1,
-	0x1352: 0x88c9, 0x1353: 0x88f1, 0x1354: 0x8919, 0x1355: 0x8941, 0x1356: 0x8969, 0x1357: 0x8991,
-	0x1358: 0x89b9, 0x1359: 0x89e1, 0x135a: 0x8a09, 0x135b: 0x8a31, 0x135c: 0x8a59, 0x135d: 0x8a81,
-	0x135e: 0x8aaa, 0x135f: 0x8ada, 0x1360: 0x8b0a, 0x1361: 0x8b3a, 0x1362: 0x8b6a, 0x1363: 0x8b9a,
-	0x1364: 0x8bc9, 0x1365: 0x8bf1, 0x1366: 0x7c71, 0x1367: 0x8c19, 0x1368: 0x7be1, 0x1369: 0x7c99,
-	0x136a: 0x8c41, 0x136b: 0x8c69, 0x136c: 0x7d39, 0x136d: 0x8c91, 0x136e: 0x7d61, 0x136f: 0x7d89,
-	0x1370: 0x8cb9, 0x1371: 0x8ce1, 0x1372: 0x7e29, 0x1373: 0x8d09, 0x1374: 0x7e51, 0x1375: 0x7e79,
-	0x1376: 0x8d31, 0x1377: 0x8d59, 0x1378: 0x7ec9, 0x1379: 0x8d81, 0x137a: 0x7ef1, 0x137b: 0x7f19,
-	0x137c: 0x83a1, 0x137d: 0x83c9, 0x137e: 0x8441, 0x137f: 0x8469,
+	0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,
+	0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,
+	0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,
+	0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,
+	0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,
+	0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,
+	0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,
+	0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,
+	0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,
+	0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,
+	0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,
 	// Block 0x4e, offset 0x1380
-	0x1380: 0x8491, 0x1381: 0x8531, 0x1382: 0x8559, 0x1383: 0x8581, 0x1384: 0x85a9, 0x1385: 0x8649,
-	0x1386: 0x8671, 0x1387: 0x8699, 0x1388: 0x8da9, 0x1389: 0x8739, 0x138a: 0x8dd1, 0x138b: 0x8df9,
-	0x138c: 0x8829, 0x138d: 0x8e21, 0x138e: 0x8851, 0x138f: 0x8879, 0x1390: 0x8a81, 0x1391: 0x8e49,
-	0x1392: 0x8e71, 0x1393: 0x89b9, 0x1394: 0x8e99, 0x1395: 0x89e1, 0x1396: 0x8a09, 0x1397: 0x7c21,
-	0x1398: 0x7c49, 0x1399: 0x8ec1, 0x139a: 0x7c71, 0x139b: 0x8ee9, 0x139c: 0x7cc1, 0x139d: 0x7ce9,
-	0x139e: 0x7d11, 0x139f: 0x7d39, 0x13a0: 0x8f11, 0x13a1: 0x7db1, 0x13a2: 0x7dd9, 0x13a3: 0x7e01,
-	0x13a4: 0x7e29, 0x13a5: 0x8f39, 0x13a6: 0x7ec9, 0x13a7: 0x7f41, 0x13a8: 0x7f69, 0x13a9: 0x7f91,
-	0x13aa: 0x7fb9, 0x13ab: 0x7fe1, 0x13ac: 0x8031, 0x13ad: 0x8059, 0x13ae: 0x8081, 0x13af: 0x80a9,
-	0x13b0: 0x80d1, 0x13b1: 0x80f9, 0x13b2: 0x8f61, 0x13b3: 0x8121, 0x13b4: 0x8149, 0x13b5: 0x8171,
-	0x13b6: 0x8199, 0x13b7: 0x81c1, 0x13b8: 0x81e9, 0x13b9: 0x8239, 0x13ba: 0x8261, 0x13bb: 0x8289,
-	0x13bc: 0x82b1, 0x13bd: 0x82d9, 0x13be: 0x8301, 0x13bf: 0x8329,
+	0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,
+	0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,
+	0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,
+	0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,
+	0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,
+	0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,
+	0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,
+	0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,
+	0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,
+	0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,
+	0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,
 	// Block 0x4f, offset 0x13c0
-	0x13c0: 0x8351, 0x13c1: 0x8379, 0x13c2: 0x83f1, 0x13c3: 0x8419, 0x13c4: 0x84b9, 0x13c5: 0x84e1,
-	0x13c6: 0x8509, 0x13c7: 0x8531, 0x13c8: 0x8559, 0x13c9: 0x85d1, 0x13ca: 0x85f9, 0x13cb: 0x8621,
-	0x13cc: 0x8649, 0x13cd: 0x8f89, 0x13ce: 0x86c1, 0x13cf: 0x86e9, 0x13d0: 0x8711, 0x13d1: 0x8739,
-	0x13d2: 0x87b1, 0x13d3: 0x87d9, 0x13d4: 0x8801, 0x13d5: 0x8829, 0x13d6: 0x8fb1, 0x13d7: 0x88a1,
-	0x13d8: 0x88c9, 0x13d9: 0x8fd9, 0x13da: 0x8941, 0x13db: 0x8969, 0x13dc: 0x8991, 0x13dd: 0x89b9,
-	0x13de: 0x9001, 0x13df: 0x7c71, 0x13e0: 0x8ee9, 0x13e1: 0x7d39, 0x13e2: 0x8f11, 0x13e3: 0x7e29,
-	0x13e4: 0x8f39, 0x13e5: 0x7ec9, 0x13e6: 0x9029, 0x13e7: 0x80d1, 0x13e8: 0x9051, 0x13e9: 0x9079,
-	0x13ea: 0x90a1, 0x13eb: 0x8531, 0x13ec: 0x8559, 0x13ed: 0x8649, 0x13ee: 0x8829, 0x13ef: 0x8fb1,
-	0x13f0: 0x89b9, 0x13f1: 0x9001, 0x13f2: 0x90c9, 0x13f3: 0x9101, 0x13f4: 0x9139, 0x13f5: 0x9171,
-	0x13f6: 0x9199, 0x13f7: 0x91c1, 0x13f8: 0x91e9, 0x13f9: 0x9211, 0x13fa: 0x9239, 0x13fb: 0x9261,
-	0x13fc: 0x9289, 0x13fd: 0x92b1, 0x13fe: 0x92d9, 0x13ff: 0x9301,
+	0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,
+	0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,
+	0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,
+	0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,
+	0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,
+	0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,
+	0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,
+	0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,
+	0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,
+	0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,
+	0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,
 	// Block 0x50, offset 0x1400
-	0x1400: 0x9329, 0x1401: 0x9351, 0x1402: 0x9379, 0x1403: 0x93a1, 0x1404: 0x93c9, 0x1405: 0x93f1,
-	0x1406: 0x9419, 0x1407: 0x9441, 0x1408: 0x9469, 0x1409: 0x9491, 0x140a: 0x94b9, 0x140b: 0x94e1,
-	0x140c: 0x9079, 0x140d: 0x9509, 0x140e: 0x9531, 0x140f: 0x9559, 0x1410: 0x9581, 0x1411: 0x9171,
-	0x1412: 0x9199, 0x1413: 0x91c1, 0x1414: 0x91e9, 0x1415: 0x9211, 0x1416: 0x9239, 0x1417: 0x9261,
-	0x1418: 0x9289, 0x1419: 0x92b1, 0x141a: 0x92d9, 0x141b: 0x9301, 0x141c: 0x9329, 0x141d: 0x9351,
-	0x141e: 0x9379, 0x141f: 0x93a1, 0x1420: 0x93c9, 0x1421: 0x93f1, 0x1422: 0x9419, 0x1423: 0x9441,
-	0x1424: 0x9469, 0x1425: 0x9491, 0x1426: 0x94b9, 0x1427: 0x94e1, 0x1428: 0x9079, 0x1429: 0x9509,
-	0x142a: 0x9531, 0x142b: 0x9559, 0x142c: 0x9581, 0x142d: 0x9491, 0x142e: 0x94b9, 0x142f: 0x94e1,
-	0x1430: 0x9079, 0x1431: 0x9051, 0x1432: 0x90a1, 0x1433: 0x8211, 0x1434: 0x8059, 0x1435: 0x8081,
-	0x1436: 0x80a9, 0x1437: 0x9491, 0x1438: 0x94b9, 0x1439: 0x94e1, 0x143a: 0x8211, 0x143b: 0x8239,
-	0x143c: 0x95a9, 0x143d: 0x95a9, 0x143e: 0x0018, 0x143f: 0x0018,
+	0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,
+	0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,
+	0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,
+	0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,
+	0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,
+	0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,
+	0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,
+	0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,
+	0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,
+	0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,
+	0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,
 	// Block 0x51, offset 0x1440
-	0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040,
-	0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040,
-	0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x95d1, 0x1451: 0x9609,
-	0x1452: 0x9609, 0x1453: 0x9641, 0x1454: 0x9679, 0x1455: 0x96b1, 0x1456: 0x96e9, 0x1457: 0x9721,
-	0x1458: 0x9759, 0x1459: 0x9759, 0x145a: 0x9791, 0x145b: 0x97c9, 0x145c: 0x9801, 0x145d: 0x9839,
-	0x145e: 0x9871, 0x145f: 0x98a9, 0x1460: 0x98a9, 0x1461: 0x98e1, 0x1462: 0x9919, 0x1463: 0x9919,
-	0x1464: 0x9951, 0x1465: 0x9951, 0x1466: 0x9989, 0x1467: 0x99c1, 0x1468: 0x99c1, 0x1469: 0x99f9,
-	0x146a: 0x9a31, 0x146b: 0x9a31, 0x146c: 0x9a69, 0x146d: 0x9a69, 0x146e: 0x9aa1, 0x146f: 0x9ad9,
-	0x1470: 0x9ad9, 0x1471: 0x9b11, 0x1472: 0x9b11, 0x1473: 0x9b49, 0x1474: 0x9b81, 0x1475: 0x9bb9,
-	0x1476: 0x9bf1, 0x1477: 0x9bf1, 0x1478: 0x9c29, 0x1479: 0x9c61, 0x147a: 0x9c99, 0x147b: 0x9cd1,
-	0x147c: 0x9d09, 0x147d: 0x9d09, 0x147e: 0x9d41, 0x147f: 0x9d79,
+	0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,
+	0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,
+	0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,
+	0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,
+	0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,
+	0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,
+	0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,
+	0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,
+	0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,
+	0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,
+	0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,
 	// Block 0x52, offset 0x1480
-	0x1480: 0xa949, 0x1481: 0xa981, 0x1482: 0xa9b9, 0x1483: 0xa8a1, 0x1484: 0x9bb9, 0x1485: 0x9989,
-	0x1486: 0xa9f1, 0x1487: 0xaa29, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,
-	0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040,
-	0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040,
-	0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040,
-	0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040,
-	0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040,
-	0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040,
-	0x14b0: 0xaa61, 0x14b1: 0xaa99, 0x14b2: 0xaad1, 0x14b3: 0xab19, 0x14b4: 0xab61, 0x14b5: 0xaba9,
-	0x14b6: 0xabf1, 0x14b7: 0xac39, 0x14b8: 0xac81, 0x14b9: 0xacc9, 0x14ba: 0xad02, 0x14bb: 0xae12,
-	0x14bc: 0xae91, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040,
+	0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,
+	0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,
+	0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,
+	0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,
+	0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,
+	0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,
+	0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,
+	0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,
+	0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,
+	0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,
+	0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,
 	// Block 0x53, offset 0x14c0
-	0x14c0: 0x13c0, 0x14c1: 0x13c0, 0x14c2: 0x13c0, 0x14c3: 0x13c0, 0x14c4: 0x13c0, 0x14c5: 0x13c0,
-	0x14c6: 0x13c0, 0x14c7: 0x13c0, 0x14c8: 0x13c0, 0x14c9: 0x13c0, 0x14ca: 0x13c0, 0x14cb: 0x13c0,
-	0x14cc: 0x13c0, 0x14cd: 0x13c0, 0x14ce: 0x13c0, 0x14cf: 0x13c0, 0x14d0: 0xaeda, 0x14d1: 0x7d55,
-	0x14d2: 0x0040, 0x14d3: 0xaeea, 0x14d4: 0x03c2, 0x14d5: 0xaefa, 0x14d6: 0xaf0a, 0x14d7: 0x7d75,
-	0x14d8: 0x7d95, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,
-	0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x1308, 0x14e1: 0x1308, 0x14e2: 0x1308, 0x14e3: 0x1308,
-	0x14e4: 0x1308, 0x14e5: 0x1308, 0x14e6: 0x1308, 0x14e7: 0x1308, 0x14e8: 0x1308, 0x14e9: 0x1308,
-	0x14ea: 0x1308, 0x14eb: 0x1308, 0x14ec: 0x1308, 0x14ed: 0x1308, 0x14ee: 0x1308, 0x14ef: 0x1308,
-	0x14f0: 0x0040, 0x14f1: 0x7db5, 0x14f2: 0x7dd5, 0x14f3: 0xaf1a, 0x14f4: 0xaf1a, 0x14f5: 0x1fd2,
-	0x14f6: 0x1fe2, 0x14f7: 0xaf2a, 0x14f8: 0xaf3a, 0x14f9: 0x7df5, 0x14fa: 0x7e15, 0x14fb: 0x7e35,
-	0x14fc: 0x7df5, 0x14fd: 0x7e55, 0x14fe: 0x7e75, 0x14ff: 0x7e55,
+	0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,
+	0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,
+	0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,
+	0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,
+	0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,
+	0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,
+	0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,
+	0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,
+	0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,
+	0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,
+	0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,
 	// Block 0x54, offset 0x1500
-	0x1500: 0x7e95, 0x1501: 0x7eb5, 0x1502: 0x7ed5, 0x1503: 0x7eb5, 0x1504: 0x7ef5, 0x1505: 0x0018,
-	0x1506: 0x0018, 0x1507: 0xaf4a, 0x1508: 0xaf5a, 0x1509: 0x7f16, 0x150a: 0x7f36, 0x150b: 0x7f56,
-	0x150c: 0x7f76, 0x150d: 0xaf1a, 0x150e: 0xaf1a, 0x150f: 0xaf1a, 0x1510: 0xaeda, 0x1511: 0x7f95,
-	0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x03c2, 0x1515: 0xaeea, 0x1516: 0xaf0a, 0x1517: 0xaefa,
-	0x1518: 0x7fb5, 0x1519: 0x1fd2, 0x151a: 0x1fe2, 0x151b: 0xaf2a, 0x151c: 0xaf3a, 0x151d: 0x7e95,
-	0x151e: 0x7ef5, 0x151f: 0xaf6a, 0x1520: 0xaf7a, 0x1521: 0xaf8a, 0x1522: 0x1fb2, 0x1523: 0xaf99,
-	0x1524: 0xafaa, 0x1525: 0xafba, 0x1526: 0x1fc2, 0x1527: 0x0040, 0x1528: 0xafca, 0x1529: 0xafda,
-	0x152a: 0xafea, 0x152b: 0xaffa, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
-	0x1530: 0x7fd6, 0x1531: 0xb009, 0x1532: 0x7ff6, 0x1533: 0x0008, 0x1534: 0x8016, 0x1535: 0x0040,
-	0x1536: 0x8036, 0x1537: 0xb031, 0x1538: 0x8056, 0x1539: 0xb059, 0x153a: 0x8076, 0x153b: 0xb081,
-	0x153c: 0x8096, 0x153d: 0xb0a9, 0x153e: 0x80b6, 0x153f: 0xb0d1,
+	0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,
+	0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,
+	0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,
+	0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,
+	0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,
+	0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,
+	0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,
+	0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
+	0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,
+	0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,
+	0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,
 	// Block 0x55, offset 0x1540
-	0x1540: 0xb0f9, 0x1541: 0xb111, 0x1542: 0xb111, 0x1543: 0xb129, 0x1544: 0xb129, 0x1545: 0xb141,
-	0x1546: 0xb141, 0x1547: 0xb159, 0x1548: 0xb159, 0x1549: 0xb171, 0x154a: 0xb171, 0x154b: 0xb171,
-	0x154c: 0xb171, 0x154d: 0xb189, 0x154e: 0xb189, 0x154f: 0xb1a1, 0x1550: 0xb1a1, 0x1551: 0xb1a1,
-	0x1552: 0xb1a1, 0x1553: 0xb1b9, 0x1554: 0xb1b9, 0x1555: 0xb1d1, 0x1556: 0xb1d1, 0x1557: 0xb1d1,
-	0x1558: 0xb1d1, 0x1559: 0xb1e9, 0x155a: 0xb1e9, 0x155b: 0xb1e9, 0x155c: 0xb1e9, 0x155d: 0xb201,
-	0x155e: 0xb201, 0x155f: 0xb201, 0x1560: 0xb201, 0x1561: 0xb219, 0x1562: 0xb219, 0x1563: 0xb219,
-	0x1564: 0xb219, 0x1565: 0xb231, 0x1566: 0xb231, 0x1567: 0xb231, 0x1568: 0xb231, 0x1569: 0xb249,
-	0x156a: 0xb249, 0x156b: 0xb261, 0x156c: 0xb261, 0x156d: 0xb279, 0x156e: 0xb279, 0x156f: 0xb291,
-	0x1570: 0xb291, 0x1571: 0xb2a9, 0x1572: 0xb2a9, 0x1573: 0xb2a9, 0x1574: 0xb2a9, 0x1575: 0xb2c1,
-	0x1576: 0xb2c1, 0x1577: 0xb2c1, 0x1578: 0xb2c1, 0x1579: 0xb2d9, 0x157a: 0xb2d9, 0x157b: 0xb2d9,
-	0x157c: 0xb2d9, 0x157d: 0xb2f1, 0x157e: 0xb2f1, 0x157f: 0xb2f1,
+	0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,
+	0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,
+	0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55,
+	0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75,
+	0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,
+	0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,
+	0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,
+	0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,
+	0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,
+	0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35,
+	0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55,
 	// Block 0x56, offset 0x1580
-	0x1580: 0xb2f1, 0x1581: 0xb309, 0x1582: 0xb309, 0x1583: 0xb309, 0x1584: 0xb309, 0x1585: 0xb321,
-	0x1586: 0xb321, 0x1587: 0xb321, 0x1588: 0xb321, 0x1589: 0xb339, 0x158a: 0xb339, 0x158b: 0xb339,
-	0x158c: 0xb339, 0x158d: 0xb351, 0x158e: 0xb351, 0x158f: 0xb351, 0x1590: 0xb351, 0x1591: 0xb369,
-	0x1592: 0xb369, 0x1593: 0xb369, 0x1594: 0xb369, 0x1595: 0xb381, 0x1596: 0xb381, 0x1597: 0xb381,
-	0x1598: 0xb381, 0x1599: 0xb399, 0x159a: 0xb399, 0x159b: 0xb399, 0x159c: 0xb399, 0x159d: 0xb3b1,
-	0x159e: 0xb3b1, 0x159f: 0xb3b1, 0x15a0: 0xb3b1, 0x15a1: 0xb3c9, 0x15a2: 0xb3c9, 0x15a3: 0xb3c9,
-	0x15a4: 0xb3c9, 0x15a5: 0xb3e1, 0x15a6: 0xb3e1, 0x15a7: 0xb3e1, 0x15a8: 0xb3e1, 0x15a9: 0xb3f9,
-	0x15aa: 0xb3f9, 0x15ab: 0xb3f9, 0x15ac: 0xb3f9, 0x15ad: 0xb411, 0x15ae: 0xb411, 0x15af: 0x7ab1,
-	0x15b0: 0x7ab1, 0x15b1: 0xb429, 0x15b2: 0xb429, 0x15b3: 0xb429, 0x15b4: 0xb429, 0x15b5: 0xb441,
-	0x15b6: 0xb441, 0x15b7: 0xb469, 0x15b8: 0xb469, 0x15b9: 0xb491, 0x15ba: 0xb491, 0x15bb: 0xb4b9,
-	0x15bc: 0xb4b9, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0,
+	0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018,
+	0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56,
+	0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95,
+	0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,
+	0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95,
+	0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,
+	0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,
+	0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,
+	0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040,
+	0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081,
+	0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1,
 	// Block 0x57, offset 0x15c0
-	0x15c0: 0x0040, 0x15c1: 0xaefa, 0x15c2: 0xb4e2, 0x15c3: 0xaf6a, 0x15c4: 0xafda, 0x15c5: 0xafea,
-	0x15c6: 0xaf7a, 0x15c7: 0xb4f2, 0x15c8: 0x1fd2, 0x15c9: 0x1fe2, 0x15ca: 0xaf8a, 0x15cb: 0x1fb2,
-	0x15cc: 0xaeda, 0x15cd: 0xaf99, 0x15ce: 0x29d1, 0x15cf: 0xb502, 0x15d0: 0x1f41, 0x15d1: 0x00c9,
-	0x15d2: 0x0069, 0x15d3: 0x0079, 0x15d4: 0x1f51, 0x15d5: 0x1f61, 0x15d6: 0x1f71, 0x15d7: 0x1f81,
-	0x15d8: 0x1f91, 0x15d9: 0x1fa1, 0x15da: 0xaeea, 0x15db: 0x03c2, 0x15dc: 0xafaa, 0x15dd: 0x1fc2,
-	0x15de: 0xafba, 0x15df: 0xaf0a, 0x15e0: 0xaffa, 0x15e1: 0x0039, 0x15e2: 0x0ee9, 0x15e3: 0x1159,
-	0x15e4: 0x0ef9, 0x15e5: 0x0f09, 0x15e6: 0x1199, 0x15e7: 0x0f31, 0x15e8: 0x0249, 0x15e9: 0x0f41,
-	0x15ea: 0x0259, 0x15eb: 0x0f51, 0x15ec: 0x0359, 0x15ed: 0x0f61, 0x15ee: 0x0f71, 0x15ef: 0x00d9,
-	0x15f0: 0x0f99, 0x15f1: 0x2039, 0x15f2: 0x0269, 0x15f3: 0x01d9, 0x15f4: 0x0fa9, 0x15f5: 0x0fb9,
-	0x15f6: 0x1089, 0x15f7: 0x0279, 0x15f8: 0x0369, 0x15f9: 0x0289, 0x15fa: 0x13d1, 0x15fb: 0xaf4a,
-	0x15fc: 0xafca, 0x15fd: 0xaf5a, 0x15fe: 0xb512, 0x15ff: 0xaf1a,
+	0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,
+	0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,
+	0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,
+	0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,
+	0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,
+	0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,
+	0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,
+	0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,
+	0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,
+	0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,
+	0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,
 	// Block 0x58, offset 0x1600
-	0x1600: 0x1caa, 0x1601: 0x0039, 0x1602: 0x0ee9, 0x1603: 0x1159, 0x1604: 0x0ef9, 0x1605: 0x0f09,
-	0x1606: 0x1199, 0x1607: 0x0f31, 0x1608: 0x0249, 0x1609: 0x0f41, 0x160a: 0x0259, 0x160b: 0x0f51,
-	0x160c: 0x0359, 0x160d: 0x0f61, 0x160e: 0x0f71, 0x160f: 0x00d9, 0x1610: 0x0f99, 0x1611: 0x2039,
-	0x1612: 0x0269, 0x1613: 0x01d9, 0x1614: 0x0fa9, 0x1615: 0x0fb9, 0x1616: 0x1089, 0x1617: 0x0279,
-	0x1618: 0x0369, 0x1619: 0x0289, 0x161a: 0x13d1, 0x161b: 0xaf2a, 0x161c: 0xb522, 0x161d: 0xaf3a,
-	0x161e: 0xb532, 0x161f: 0x80d5, 0x1620: 0x80f5, 0x1621: 0x29d1, 0x1622: 0x8115, 0x1623: 0x8115,
-	0x1624: 0x8135, 0x1625: 0x8155, 0x1626: 0x8175, 0x1627: 0x8195, 0x1628: 0x81b5, 0x1629: 0x81d5,
-	0x162a: 0x81f5, 0x162b: 0x8215, 0x162c: 0x8235, 0x162d: 0x8255, 0x162e: 0x8275, 0x162f: 0x8295,
-	0x1630: 0x82b5, 0x1631: 0x82d5, 0x1632: 0x82f5, 0x1633: 0x8315, 0x1634: 0x8335, 0x1635: 0x8355,
-	0x1636: 0x8375, 0x1637: 0x8395, 0x1638: 0x83b5, 0x1639: 0x83d5, 0x163a: 0x83f5, 0x163b: 0x8415,
-	0x163c: 0x81b5, 0x163d: 0x8435, 0x163e: 0x8455, 0x163f: 0x8215,
+	0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,
+	0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,
+	0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,
+	0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,
+	0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,
+	0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,
+	0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,
+	0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,
+	0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,
+	0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,
+	0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,
 	// Block 0x59, offset 0x1640
-	0x1640: 0x8475, 0x1641: 0x8495, 0x1642: 0x84b5, 0x1643: 0x84d5, 0x1644: 0x84f5, 0x1645: 0x8515,
-	0x1646: 0x8535, 0x1647: 0x8555, 0x1648: 0x84d5, 0x1649: 0x8575, 0x164a: 0x84d5, 0x164b: 0x8595,
-	0x164c: 0x8595, 0x164d: 0x85b5, 0x164e: 0x85b5, 0x164f: 0x85d5, 0x1650: 0x8515, 0x1651: 0x85f5,
-	0x1652: 0x8615, 0x1653: 0x85f5, 0x1654: 0x8635, 0x1655: 0x8615, 0x1656: 0x8655, 0x1657: 0x8655,
-	0x1658: 0x8675, 0x1659: 0x8675, 0x165a: 0x8695, 0x165b: 0x8695, 0x165c: 0x8615, 0x165d: 0x8115,
-	0x165e: 0x86b5, 0x165f: 0x86d5, 0x1660: 0x0040, 0x1661: 0x86f5, 0x1662: 0x8715, 0x1663: 0x8735,
-	0x1664: 0x8755, 0x1665: 0x8735, 0x1666: 0x8775, 0x1667: 0x8795, 0x1668: 0x87b5, 0x1669: 0x87b5,
-	0x166a: 0x87d5, 0x166b: 0x87d5, 0x166c: 0x87f5, 0x166d: 0x87f5, 0x166e: 0x87d5, 0x166f: 0x87d5,
-	0x1670: 0x8815, 0x1671: 0x8835, 0x1672: 0x8855, 0x1673: 0x8875, 0x1674: 0x8895, 0x1675: 0x88b5,
-	0x1676: 0x88b5, 0x1677: 0x88b5, 0x1678: 0x88d5, 0x1679: 0x88d5, 0x167a: 0x88d5, 0x167b: 0x88d5,
-	0x167c: 0x87b5, 0x167d: 0x87b5, 0x167e: 0x87b5, 0x167f: 0x0040,
+	0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,
+	0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,
+	0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,
+	0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,
+	0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,
+	0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,
+	0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,
+	0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,
+	0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,
+	0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,
+	0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,
 	// Block 0x5a, offset 0x1680
-	0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x8715, 0x1683: 0x86f5, 0x1684: 0x88f5, 0x1685: 0x86f5,
-	0x1686: 0x8715, 0x1687: 0x86f5, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x8915, 0x168b: 0x8715,
-	0x168c: 0x8935, 0x168d: 0x88f5, 0x168e: 0x8935, 0x168f: 0x8715, 0x1690: 0x0040, 0x1691: 0x0040,
-	0x1692: 0x8955, 0x1693: 0x8975, 0x1694: 0x8875, 0x1695: 0x8935, 0x1696: 0x88f5, 0x1697: 0x8935,
-	0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x8995, 0x169b: 0x89b5, 0x169c: 0x8995, 0x169d: 0x0040,
-	0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0xb541, 0x16a1: 0xb559, 0x16a2: 0xb571, 0x16a3: 0x89d6,
-	0x16a4: 0xb589, 0x16a5: 0xb5a1, 0x16a6: 0x89f5, 0x16a7: 0x0040, 0x16a8: 0x8a15, 0x16a9: 0x8a35,
-	0x16aa: 0x8a55, 0x16ab: 0x8a35, 0x16ac: 0x8a75, 0x16ad: 0x8a95, 0x16ae: 0x8ab5, 0x16af: 0x0040,
-	0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040,
-	0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340,
-	0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040,
+	0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,
+	0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,
+	0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,
+	0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,
+	0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,
+	0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115,
+	0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5,
+	0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295,
+	0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355,
+	0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415,
+	0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215,
 	// Block 0x5b, offset 0x16c0
-	0x16c0: 0x0208, 0x16c1: 0x0208, 0x16c2: 0x0208, 0x16c3: 0x0208, 0x16c4: 0x0208, 0x16c5: 0x0408,
-	0x16c6: 0x0008, 0x16c7: 0x0408, 0x16c8: 0x0018, 0x16c9: 0x0408, 0x16ca: 0x0408, 0x16cb: 0x0008,
-	0x16cc: 0x0008, 0x16cd: 0x0108, 0x16ce: 0x0408, 0x16cf: 0x0408, 0x16d0: 0x0408, 0x16d1: 0x0408,
-	0x16d2: 0x0408, 0x16d3: 0x0208, 0x16d4: 0x0208, 0x16d5: 0x0208, 0x16d6: 0x0208, 0x16d7: 0x0108,
-	0x16d8: 0x0208, 0x16d9: 0x0208, 0x16da: 0x0208, 0x16db: 0x0208, 0x16dc: 0x0208, 0x16dd: 0x0408,
-	0x16de: 0x0208, 0x16df: 0x0208, 0x16e0: 0x0208, 0x16e1: 0x0408, 0x16e2: 0x0008, 0x16e3: 0x0008,
-	0x16e4: 0x0408, 0x16e5: 0x1308, 0x16e6: 0x1308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040,
-	0x16ea: 0x0040, 0x16eb: 0x0218, 0x16ec: 0x0218, 0x16ed: 0x0218, 0x16ee: 0x0218, 0x16ef: 0x0418,
-	0x16f0: 0x0018, 0x16f1: 0x0018, 0x16f2: 0x0018, 0x16f3: 0x0018, 0x16f4: 0x0018, 0x16f5: 0x0018,
-	0x16f6: 0x0018, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040,
-	0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,
+	0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515,
+	0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595,
+	0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5,
+	0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655,
+	0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115,
+	0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735,
+	0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5,
+	0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5,
+	0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5,
+	0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5,
+	0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040,
 	// Block 0x5c, offset 0x1700
-	0x1700: 0x0208, 0x1701: 0x0408, 0x1702: 0x0208, 0x1703: 0x0408, 0x1704: 0x0408, 0x1705: 0x0408,
-	0x1706: 0x0208, 0x1707: 0x0208, 0x1708: 0x0208, 0x1709: 0x0408, 0x170a: 0x0208, 0x170b: 0x0208,
-	0x170c: 0x0408, 0x170d: 0x0208, 0x170e: 0x0408, 0x170f: 0x0408, 0x1710: 0x0208, 0x1711: 0x0408,
-	0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040,
-	0x1718: 0x0040, 0x1719: 0x0018, 0x171a: 0x0018, 0x171b: 0x0018, 0x171c: 0x0018, 0x171d: 0x0040,
-	0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040,
-	0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0418,
-	0x172a: 0x0418, 0x172b: 0x0418, 0x172c: 0x0418, 0x172d: 0x0218, 0x172e: 0x0218, 0x172f: 0x0018,
+	0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5,
+	0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715,
+	0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040,
+	0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935,
+	0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040,
+	0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6,
+	0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35,
+	0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040,
 	0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,
-	0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,
+	0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,
 	0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,
 	// Block 0x5d, offset 0x1740
-	0x1740: 0x1308, 0x1741: 0x1308, 0x1742: 0x1008, 0x1743: 0x1008, 0x1744: 0x0040, 0x1745: 0x0008,
-	0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,
-	0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040,
-	0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,
-	0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,
-	0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,
-	0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040,
-	0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008,
-	0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008,
-	0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x0040,
-	0x177c: 0x1308, 0x177d: 0x0008, 0x177e: 0x1008, 0x177f: 0x1008,
+	0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,
+	0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,
+	0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,
+	0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,
+	0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,
+	0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,
+	0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,
+	0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,
+	0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,
+	0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,
+	0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,
 	// Block 0x5e, offset 0x1780
-	0x1780: 0x1308, 0x1781: 0x1008, 0x1782: 0x1008, 0x1783: 0x1008, 0x1784: 0x1008, 0x1785: 0x0040,
-	0x1786: 0x0040, 0x1787: 0x1008, 0x1788: 0x1008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x1008,
-	0x178c: 0x1008, 0x178d: 0x1808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040,
-	0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x1008,
-	0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008,
-	0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x1008, 0x17a3: 0x1008,
-	0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x1308, 0x17a7: 0x1308, 0x17a8: 0x1308, 0x17a9: 0x1308,
-	0x17aa: 0x1308, 0x17ab: 0x1308, 0x17ac: 0x1308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040,
-	0x17b0: 0x1308, 0x17b1: 0x1308, 0x17b2: 0x1308, 0x17b3: 0x1308, 0x17b4: 0x1308, 0x17b5: 0x0040,
+	0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,
+	0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,
+	0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,
+	0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,
+	0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,
+	0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,
+	0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,
+	0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,
+	0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,
 	0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,
 	0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,
 	// Block 0x5f, offset 0x17c0
-	0x17c0: 0x0039, 0x17c1: 0x0ee9, 0x17c2: 0x1159, 0x17c3: 0x0ef9, 0x17c4: 0x0f09, 0x17c5: 0x1199,
-	0x17c6: 0x0f31, 0x17c7: 0x0249, 0x17c8: 0x0f41, 0x17c9: 0x0259, 0x17ca: 0x0f51, 0x17cb: 0x0359,
-	0x17cc: 0x0f61, 0x17cd: 0x0f71, 0x17ce: 0x00d9, 0x17cf: 0x0f99, 0x17d0: 0x2039, 0x17d1: 0x0269,
-	0x17d2: 0x01d9, 0x17d3: 0x0fa9, 0x17d4: 0x0fb9, 0x17d5: 0x1089, 0x17d6: 0x0279, 0x17d7: 0x0369,
-	0x17d8: 0x0289, 0x17d9: 0x13d1, 0x17da: 0x0039, 0x17db: 0x0ee9, 0x17dc: 0x1159, 0x17dd: 0x0ef9,
-	0x17de: 0x0f09, 0x17df: 0x1199, 0x17e0: 0x0f31, 0x17e1: 0x0249, 0x17e2: 0x0f41, 0x17e3: 0x0259,
-	0x17e4: 0x0f51, 0x17e5: 0x0359, 0x17e6: 0x0f61, 0x17e7: 0x0f71, 0x17e8: 0x00d9, 0x17e9: 0x0f99,
-	0x17ea: 0x2039, 0x17eb: 0x0269, 0x17ec: 0x01d9, 0x17ed: 0x0fa9, 0x17ee: 0x0fb9, 0x17ef: 0x1089,
-	0x17f0: 0x0279, 0x17f1: 0x0369, 0x17f2: 0x0289, 0x17f3: 0x13d1, 0x17f4: 0x0039, 0x17f5: 0x0ee9,
-	0x17f6: 0x1159, 0x17f7: 0x0ef9, 0x17f8: 0x0f09, 0x17f9: 0x1199, 0x17fa: 0x0f31, 0x17fb: 0x0249,
-	0x17fc: 0x0f41, 0x17fd: 0x0259, 0x17fe: 0x0f51, 0x17ff: 0x0359,
+	0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,
+	0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,
+	0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,
+	0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,
+	0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,
+	0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,
+	0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,
+	0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,
+	0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,
+	0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040,
+	0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,
 	// Block 0x60, offset 0x1800
-	0x1800: 0x0f61, 0x1801: 0x0f71, 0x1802: 0x00d9, 0x1803: 0x0f99, 0x1804: 0x2039, 0x1805: 0x0269,
-	0x1806: 0x01d9, 0x1807: 0x0fa9, 0x1808: 0x0fb9, 0x1809: 0x1089, 0x180a: 0x0279, 0x180b: 0x0369,
-	0x180c: 0x0289, 0x180d: 0x13d1, 0x180e: 0x0039, 0x180f: 0x0ee9, 0x1810: 0x1159, 0x1811: 0x0ef9,
-	0x1812: 0x0f09, 0x1813: 0x1199, 0x1814: 0x0f31, 0x1815: 0x0040, 0x1816: 0x0f41, 0x1817: 0x0259,
-	0x1818: 0x0f51, 0x1819: 0x0359, 0x181a: 0x0f61, 0x181b: 0x0f71, 0x181c: 0x00d9, 0x181d: 0x0f99,
-	0x181e: 0x2039, 0x181f: 0x0269, 0x1820: 0x01d9, 0x1821: 0x0fa9, 0x1822: 0x0fb9, 0x1823: 0x1089,
-	0x1824: 0x0279, 0x1825: 0x0369, 0x1826: 0x0289, 0x1827: 0x13d1, 0x1828: 0x0039, 0x1829: 0x0ee9,
-	0x182a: 0x1159, 0x182b: 0x0ef9, 0x182c: 0x0f09, 0x182d: 0x1199, 0x182e: 0x0f31, 0x182f: 0x0249,
-	0x1830: 0x0f41, 0x1831: 0x0259, 0x1832: 0x0f51, 0x1833: 0x0359, 0x1834: 0x0f61, 0x1835: 0x0f71,
-	0x1836: 0x00d9, 0x1837: 0x0f99, 0x1838: 0x2039, 0x1839: 0x0269, 0x183a: 0x01d9, 0x183b: 0x0fa9,
-	0x183c: 0x0fb9, 0x183d: 0x1089, 0x183e: 0x0279, 0x183f: 0x0369,
+	0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,
+	0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,
+	0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,
+	0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,
+	0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,
+	0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,
+	0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,
+	0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,
+	0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,
+	0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,
+	0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,
 	// Block 0x61, offset 0x1840
-	0x1840: 0x0289, 0x1841: 0x13d1, 0x1842: 0x0039, 0x1843: 0x0ee9, 0x1844: 0x1159, 0x1845: 0x0ef9,
-	0x1846: 0x0f09, 0x1847: 0x1199, 0x1848: 0x0f31, 0x1849: 0x0249, 0x184a: 0x0f41, 0x184b: 0x0259,
-	0x184c: 0x0f51, 0x184d: 0x0359, 0x184e: 0x0f61, 0x184f: 0x0f71, 0x1850: 0x00d9, 0x1851: 0x0f99,
-	0x1852: 0x2039, 0x1853: 0x0269, 0x1854: 0x01d9, 0x1855: 0x0fa9, 0x1856: 0x0fb9, 0x1857: 0x1089,
-	0x1858: 0x0279, 0x1859: 0x0369, 0x185a: 0x0289, 0x185b: 0x13d1, 0x185c: 0x0039, 0x185d: 0x0040,
-	0x185e: 0x1159, 0x185f: 0x0ef9, 0x1860: 0x0040, 0x1861: 0x0040, 0x1862: 0x0f31, 0x1863: 0x0040,
-	0x1864: 0x0040, 0x1865: 0x0259, 0x1866: 0x0f51, 0x1867: 0x0040, 0x1868: 0x0040, 0x1869: 0x0f71,
-	0x186a: 0x00d9, 0x186b: 0x0f99, 0x186c: 0x2039, 0x186d: 0x0040, 0x186e: 0x01d9, 0x186f: 0x0fa9,
-	0x1870: 0x0fb9, 0x1871: 0x1089, 0x1872: 0x0279, 0x1873: 0x0369, 0x1874: 0x0289, 0x1875: 0x13d1,
-	0x1876: 0x0039, 0x1877: 0x0ee9, 0x1878: 0x1159, 0x1879: 0x0ef9, 0x187a: 0x0040, 0x187b: 0x1199,
-	0x187c: 0x0040, 0x187d: 0x0249, 0x187e: 0x0f41, 0x187f: 0x0259,
+	0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,
+	0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,
+	0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,
+	0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,
+	0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,
+	0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,
+	0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,
+	0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,
+	0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,
+	0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,
+	0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,
 	// Block 0x62, offset 0x1880
-	0x1880: 0x0f51, 0x1881: 0x0359, 0x1882: 0x0f61, 0x1883: 0x0f71, 0x1884: 0x0040, 0x1885: 0x0f99,
-	0x1886: 0x2039, 0x1887: 0x0269, 0x1888: 0x01d9, 0x1889: 0x0fa9, 0x188a: 0x0fb9, 0x188b: 0x1089,
-	0x188c: 0x0279, 0x188d: 0x0369, 0x188e: 0x0289, 0x188f: 0x13d1, 0x1890: 0x0039, 0x1891: 0x0ee9,
-	0x1892: 0x1159, 0x1893: 0x0ef9, 0x1894: 0x0f09, 0x1895: 0x1199, 0x1896: 0x0f31, 0x1897: 0x0249,
-	0x1898: 0x0f41, 0x1899: 0x0259, 0x189a: 0x0f51, 0x189b: 0x0359, 0x189c: 0x0f61, 0x189d: 0x0f71,
-	0x189e: 0x00d9, 0x189f: 0x0f99, 0x18a0: 0x2039, 0x18a1: 0x0269, 0x18a2: 0x01d9, 0x18a3: 0x0fa9,
-	0x18a4: 0x0fb9, 0x18a5: 0x1089, 0x18a6: 0x0279, 0x18a7: 0x0369, 0x18a8: 0x0289, 0x18a9: 0x13d1,
-	0x18aa: 0x0039, 0x18ab: 0x0ee9, 0x18ac: 0x1159, 0x18ad: 0x0ef9, 0x18ae: 0x0f09, 0x18af: 0x1199,
-	0x18b0: 0x0f31, 0x18b1: 0x0249, 0x18b2: 0x0f41, 0x18b3: 0x0259, 0x18b4: 0x0f51, 0x18b5: 0x0359,
-	0x18b6: 0x0f61, 0x18b7: 0x0f71, 0x18b8: 0x00d9, 0x18b9: 0x0f99, 0x18ba: 0x2039, 0x18bb: 0x0269,
-	0x18bc: 0x01d9, 0x18bd: 0x0fa9, 0x18be: 0x0fb9, 0x18bf: 0x1089,
+	0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,
+	0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,
+	0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,
+	0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,
+	0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,
+	0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,
+	0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,
+	0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,
+	0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,
+	0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,
+	0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,
 	// Block 0x63, offset 0x18c0
-	0x18c0: 0x0279, 0x18c1: 0x0369, 0x18c2: 0x0289, 0x18c3: 0x13d1, 0x18c4: 0x0039, 0x18c5: 0x0ee9,
-	0x18c6: 0x0040, 0x18c7: 0x0ef9, 0x18c8: 0x0f09, 0x18c9: 0x1199, 0x18ca: 0x0f31, 0x18cb: 0x0040,
-	0x18cc: 0x0040, 0x18cd: 0x0259, 0x18ce: 0x0f51, 0x18cf: 0x0359, 0x18d0: 0x0f61, 0x18d1: 0x0f71,
-	0x18d2: 0x00d9, 0x18d3: 0x0f99, 0x18d4: 0x2039, 0x18d5: 0x0040, 0x18d6: 0x01d9, 0x18d7: 0x0fa9,
-	0x18d8: 0x0fb9, 0x18d9: 0x1089, 0x18da: 0x0279, 0x18db: 0x0369, 0x18dc: 0x0289, 0x18dd: 0x0040,
-	0x18de: 0x0039, 0x18df: 0x0ee9, 0x18e0: 0x1159, 0x18e1: 0x0ef9, 0x18e2: 0x0f09, 0x18e3: 0x1199,
-	0x18e4: 0x0f31, 0x18e5: 0x0249, 0x18e6: 0x0f41, 0x18e7: 0x0259, 0x18e8: 0x0f51, 0x18e9: 0x0359,
-	0x18ea: 0x0f61, 0x18eb: 0x0f71, 0x18ec: 0x00d9, 0x18ed: 0x0f99, 0x18ee: 0x2039, 0x18ef: 0x0269,
-	0x18f0: 0x01d9, 0x18f1: 0x0fa9, 0x18f2: 0x0fb9, 0x18f3: 0x1089, 0x18f4: 0x0279, 0x18f5: 0x0369,
-	0x18f6: 0x0289, 0x18f7: 0x13d1, 0x18f8: 0x0039, 0x18f9: 0x0ee9, 0x18fa: 0x0040, 0x18fb: 0x0ef9,
-	0x18fc: 0x0f09, 0x18fd: 0x1199, 0x18fe: 0x0f31, 0x18ff: 0x0040,
+	0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,
+	0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,
+	0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,
+	0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,
+	0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,
+	0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,
+	0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,
+	0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,
+	0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,
+	0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,
+	0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,
 	// Block 0x64, offset 0x1900
-	0x1900: 0x0f41, 0x1901: 0x0259, 0x1902: 0x0f51, 0x1903: 0x0359, 0x1904: 0x0f61, 0x1905: 0x0040,
-	0x1906: 0x00d9, 0x1907: 0x0040, 0x1908: 0x0040, 0x1909: 0x0040, 0x190a: 0x01d9, 0x190b: 0x0fa9,
-	0x190c: 0x0fb9, 0x190d: 0x1089, 0x190e: 0x0279, 0x190f: 0x0369, 0x1910: 0x0289, 0x1911: 0x0040,
-	0x1912: 0x0039, 0x1913: 0x0ee9, 0x1914: 0x1159, 0x1915: 0x0ef9, 0x1916: 0x0f09, 0x1917: 0x1199,
-	0x1918: 0x0f31, 0x1919: 0x0249, 0x191a: 0x0f41, 0x191b: 0x0259, 0x191c: 0x0f51, 0x191d: 0x0359,
-	0x191e: 0x0f61, 0x191f: 0x0f71, 0x1920: 0x00d9, 0x1921: 0x0f99, 0x1922: 0x2039, 0x1923: 0x0269,
-	0x1924: 0x01d9, 0x1925: 0x0fa9, 0x1926: 0x0fb9, 0x1927: 0x1089, 0x1928: 0x0279, 0x1929: 0x0369,
-	0x192a: 0x0289, 0x192b: 0x13d1, 0x192c: 0x0039, 0x192d: 0x0ee9, 0x192e: 0x1159, 0x192f: 0x0ef9,
-	0x1930: 0x0f09, 0x1931: 0x1199, 0x1932: 0x0f31, 0x1933: 0x0249, 0x1934: 0x0f41, 0x1935: 0x0259,
-	0x1936: 0x0f51, 0x1937: 0x0359, 0x1938: 0x0f61, 0x1939: 0x0f71, 0x193a: 0x00d9, 0x193b: 0x0f99,
-	0x193c: 0x2039, 0x193d: 0x0269, 0x193e: 0x01d9, 0x193f: 0x0fa9,
+	0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,
+	0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,
+	0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,
+	0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,
+	0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,
+	0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,
+	0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,
+	0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,
+	0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,
+	0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,
+	0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,
 	// Block 0x65, offset 0x1940
-	0x1940: 0x0fb9, 0x1941: 0x1089, 0x1942: 0x0279, 0x1943: 0x0369, 0x1944: 0x0289, 0x1945: 0x13d1,
-	0x1946: 0x0039, 0x1947: 0x0ee9, 0x1948: 0x1159, 0x1949: 0x0ef9, 0x194a: 0x0f09, 0x194b: 0x1199,
-	0x194c: 0x0f31, 0x194d: 0x0249, 0x194e: 0x0f41, 0x194f: 0x0259, 0x1950: 0x0f51, 0x1951: 0x0359,
-	0x1952: 0x0f61, 0x1953: 0x0f71, 0x1954: 0x00d9, 0x1955: 0x0f99, 0x1956: 0x2039, 0x1957: 0x0269,
-	0x1958: 0x01d9, 0x1959: 0x0fa9, 0x195a: 0x0fb9, 0x195b: 0x1089, 0x195c: 0x0279, 0x195d: 0x0369,
-	0x195e: 0x0289, 0x195f: 0x13d1, 0x1960: 0x0039, 0x1961: 0x0ee9, 0x1962: 0x1159, 0x1963: 0x0ef9,
-	0x1964: 0x0f09, 0x1965: 0x1199, 0x1966: 0x0f31, 0x1967: 0x0249, 0x1968: 0x0f41, 0x1969: 0x0259,
-	0x196a: 0x0f51, 0x196b: 0x0359, 0x196c: 0x0f61, 0x196d: 0x0f71, 0x196e: 0x00d9, 0x196f: 0x0f99,
-	0x1970: 0x2039, 0x1971: 0x0269, 0x1972: 0x01d9, 0x1973: 0x0fa9, 0x1974: 0x0fb9, 0x1975: 0x1089,
-	0x1976: 0x0279, 0x1977: 0x0369, 0x1978: 0x0289, 0x1979: 0x13d1, 0x197a: 0x0039, 0x197b: 0x0ee9,
-	0x197c: 0x1159, 0x197d: 0x0ef9, 0x197e: 0x0f09, 0x197f: 0x1199,
+	0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,
+	0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,
+	0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,
+	0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,
+	0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,
+	0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,
+	0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,
+	0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,
+	0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,
+	0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,
+	0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,
 	// Block 0x66, offset 0x1980
-	0x1980: 0x0f31, 0x1981: 0x0249, 0x1982: 0x0f41, 0x1983: 0x0259, 0x1984: 0x0f51, 0x1985: 0x0359,
-	0x1986: 0x0f61, 0x1987: 0x0f71, 0x1988: 0x00d9, 0x1989: 0x0f99, 0x198a: 0x2039, 0x198b: 0x0269,
-	0x198c: 0x01d9, 0x198d: 0x0fa9, 0x198e: 0x0fb9, 0x198f: 0x1089, 0x1990: 0x0279, 0x1991: 0x0369,
-	0x1992: 0x0289, 0x1993: 0x13d1, 0x1994: 0x0039, 0x1995: 0x0ee9, 0x1996: 0x1159, 0x1997: 0x0ef9,
-	0x1998: 0x0f09, 0x1999: 0x1199, 0x199a: 0x0f31, 0x199b: 0x0249, 0x199c: 0x0f41, 0x199d: 0x0259,
-	0x199e: 0x0f51, 0x199f: 0x0359, 0x19a0: 0x0f61, 0x19a1: 0x0f71, 0x19a2: 0x00d9, 0x19a3: 0x0f99,
-	0x19a4: 0x2039, 0x19a5: 0x0269, 0x19a6: 0x01d9, 0x19a7: 0x0fa9, 0x19a8: 0x0fb9, 0x19a9: 0x1089,
-	0x19aa: 0x0279, 0x19ab: 0x0369, 0x19ac: 0x0289, 0x19ad: 0x13d1, 0x19ae: 0x0039, 0x19af: 0x0ee9,
-	0x19b0: 0x1159, 0x19b1: 0x0ef9, 0x19b2: 0x0f09, 0x19b3: 0x1199, 0x19b4: 0x0f31, 0x19b5: 0x0249,
-	0x19b6: 0x0f41, 0x19b7: 0x0259, 0x19b8: 0x0f51, 0x19b9: 0x0359, 0x19ba: 0x0f61, 0x19bb: 0x0f71,
-	0x19bc: 0x00d9, 0x19bd: 0x0f99, 0x19be: 0x2039, 0x19bf: 0x0269,
+	0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,
+	0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,
+	0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,
+	0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,
+	0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,
+	0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,
+	0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,
+	0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,
+	0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,
+	0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,
+	0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,
 	// Block 0x67, offset 0x19c0
-	0x19c0: 0x01d9, 0x19c1: 0x0fa9, 0x19c2: 0x0fb9, 0x19c3: 0x1089, 0x19c4: 0x0279, 0x19c5: 0x0369,
-	0x19c6: 0x0289, 0x19c7: 0x13d1, 0x19c8: 0x0039, 0x19c9: 0x0ee9, 0x19ca: 0x1159, 0x19cb: 0x0ef9,
-	0x19cc: 0x0f09, 0x19cd: 0x1199, 0x19ce: 0x0f31, 0x19cf: 0x0249, 0x19d0: 0x0f41, 0x19d1: 0x0259,
-	0x19d2: 0x0f51, 0x19d3: 0x0359, 0x19d4: 0x0f61, 0x19d5: 0x0f71, 0x19d6: 0x00d9, 0x19d7: 0x0f99,
-	0x19d8: 0x2039, 0x19d9: 0x0269, 0x19da: 0x01d9, 0x19db: 0x0fa9, 0x19dc: 0x0fb9, 0x19dd: 0x1089,
-	0x19de: 0x0279, 0x19df: 0x0369, 0x19e0: 0x0289, 0x19e1: 0x13d1, 0x19e2: 0x0039, 0x19e3: 0x0ee9,
-	0x19e4: 0x1159, 0x19e5: 0x0ef9, 0x19e6: 0x0f09, 0x19e7: 0x1199, 0x19e8: 0x0f31, 0x19e9: 0x0249,
-	0x19ea: 0x0f41, 0x19eb: 0x0259, 0x19ec: 0x0f51, 0x19ed: 0x0359, 0x19ee: 0x0f61, 0x19ef: 0x0f71,
-	0x19f0: 0x00d9, 0x19f1: 0x0f99, 0x19f2: 0x2039, 0x19f3: 0x0269, 0x19f4: 0x01d9, 0x19f5: 0x0fa9,
-	0x19f6: 0x0fb9, 0x19f7: 0x1089, 0x19f8: 0x0279, 0x19f9: 0x0369, 0x19fa: 0x0289, 0x19fb: 0x13d1,
-	0x19fc: 0x0039, 0x19fd: 0x0ee9, 0x19fe: 0x1159, 0x19ff: 0x0ef9,
+	0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,
+	0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,
+	0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,
+	0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,
+	0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,
+	0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,
+	0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,
+	0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,
+	0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,
+	0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,
+	0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,
 	// Block 0x68, offset 0x1a00
-	0x1a00: 0x0f09, 0x1a01: 0x1199, 0x1a02: 0x0f31, 0x1a03: 0x0249, 0x1a04: 0x0f41, 0x1a05: 0x0259,
-	0x1a06: 0x0f51, 0x1a07: 0x0359, 0x1a08: 0x0f61, 0x1a09: 0x0f71, 0x1a0a: 0x00d9, 0x1a0b: 0x0f99,
-	0x1a0c: 0x2039, 0x1a0d: 0x0269, 0x1a0e: 0x01d9, 0x1a0f: 0x0fa9, 0x1a10: 0x0fb9, 0x1a11: 0x1089,
-	0x1a12: 0x0279, 0x1a13: 0x0369, 0x1a14: 0x0289, 0x1a15: 0x13d1, 0x1a16: 0x0039, 0x1a17: 0x0ee9,
-	0x1a18: 0x1159, 0x1a19: 0x0ef9, 0x1a1a: 0x0f09, 0x1a1b: 0x1199, 0x1a1c: 0x0f31, 0x1a1d: 0x0249,
-	0x1a1e: 0x0f41, 0x1a1f: 0x0259, 0x1a20: 0x0f51, 0x1a21: 0x0359, 0x1a22: 0x0f61, 0x1a23: 0x0f71,
-	0x1a24: 0x00d9, 0x1a25: 0x0f99, 0x1a26: 0x2039, 0x1a27: 0x0269, 0x1a28: 0x01d9, 0x1a29: 0x0fa9,
-	0x1a2a: 0x0fb9, 0x1a2b: 0x1089, 0x1a2c: 0x0279, 0x1a2d: 0x0369, 0x1a2e: 0x0289, 0x1a2f: 0x13d1,
-	0x1a30: 0x0039, 0x1a31: 0x0ee9, 0x1a32: 0x1159, 0x1a33: 0x0ef9, 0x1a34: 0x0f09, 0x1a35: 0x1199,
-	0x1a36: 0x0f31, 0x1a37: 0x0249, 0x1a38: 0x0f41, 0x1a39: 0x0259, 0x1a3a: 0x0f51, 0x1a3b: 0x0359,
-	0x1a3c: 0x0f61, 0x1a3d: 0x0f71, 0x1a3e: 0x00d9, 0x1a3f: 0x0f99,
+	0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,
+	0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,
+	0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,
+	0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,
+	0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,
+	0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,
+	0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,
+	0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,
+	0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,
+	0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,
+	0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,
 	// Block 0x69, offset 0x1a40
-	0x1a40: 0x2039, 0x1a41: 0x0269, 0x1a42: 0x01d9, 0x1a43: 0x0fa9, 0x1a44: 0x0fb9, 0x1a45: 0x1089,
-	0x1a46: 0x0279, 0x1a47: 0x0369, 0x1a48: 0x0289, 0x1a49: 0x13d1, 0x1a4a: 0x0039, 0x1a4b: 0x0ee9,
-	0x1a4c: 0x1159, 0x1a4d: 0x0ef9, 0x1a4e: 0x0f09, 0x1a4f: 0x1199, 0x1a50: 0x0f31, 0x1a51: 0x0249,
-	0x1a52: 0x0f41, 0x1a53: 0x0259, 0x1a54: 0x0f51, 0x1a55: 0x0359, 0x1a56: 0x0f61, 0x1a57: 0x0f71,
-	0x1a58: 0x00d9, 0x1a59: 0x0f99, 0x1a5a: 0x2039, 0x1a5b: 0x0269, 0x1a5c: 0x01d9, 0x1a5d: 0x0fa9,
-	0x1a5e: 0x0fb9, 0x1a5f: 0x1089, 0x1a60: 0x0279, 0x1a61: 0x0369, 0x1a62: 0x0289, 0x1a63: 0x13d1,
-	0x1a64: 0xba81, 0x1a65: 0xba99, 0x1a66: 0x0040, 0x1a67: 0x0040, 0x1a68: 0xbab1, 0x1a69: 0x1099,
-	0x1a6a: 0x10b1, 0x1a6b: 0x10c9, 0x1a6c: 0xbac9, 0x1a6d: 0xbae1, 0x1a6e: 0xbaf9, 0x1a6f: 0x1429,
-	0x1a70: 0x1a31, 0x1a71: 0xbb11, 0x1a72: 0xbb29, 0x1a73: 0xbb41, 0x1a74: 0xbb59, 0x1a75: 0xbb71,
-	0x1a76: 0xbb89, 0x1a77: 0x2109, 0x1a78: 0x1111, 0x1a79: 0x1429, 0x1a7a: 0xbba1, 0x1a7b: 0xbbb9,
-	0x1a7c: 0xbbd1, 0x1a7d: 0x10e1, 0x1a7e: 0x10f9, 0x1a7f: 0xbbe9,
+	0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,
+	0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,
+	0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,
+	0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,
+	0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,
+	0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,
+	0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,
+	0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,
+	0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,
+	0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,
+	0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,
 	// Block 0x6a, offset 0x1a80
-	0x1a80: 0x2079, 0x1a81: 0xbc01, 0x1a82: 0xbab1, 0x1a83: 0x1099, 0x1a84: 0x10b1, 0x1a85: 0x10c9,
-	0x1a86: 0xbac9, 0x1a87: 0xbae1, 0x1a88: 0xbaf9, 0x1a89: 0x1429, 0x1a8a: 0x1a31, 0x1a8b: 0xbb11,
-	0x1a8c: 0xbb29, 0x1a8d: 0xbb41, 0x1a8e: 0xbb59, 0x1a8f: 0xbb71, 0x1a90: 0xbb89, 0x1a91: 0x2109,
-	0x1a92: 0x1111, 0x1a93: 0xbba1, 0x1a94: 0xbba1, 0x1a95: 0xbbb9, 0x1a96: 0xbbd1, 0x1a97: 0x10e1,
-	0x1a98: 0x10f9, 0x1a99: 0xbbe9, 0x1a9a: 0x2079, 0x1a9b: 0xbc21, 0x1a9c: 0xbac9, 0x1a9d: 0x1429,
-	0x1a9e: 0xbb11, 0x1a9f: 0x10e1, 0x1aa0: 0x1111, 0x1aa1: 0x2109, 0x1aa2: 0xbab1, 0x1aa3: 0x1099,
-	0x1aa4: 0x10b1, 0x1aa5: 0x10c9, 0x1aa6: 0xbac9, 0x1aa7: 0xbae1, 0x1aa8: 0xbaf9, 0x1aa9: 0x1429,
-	0x1aaa: 0x1a31, 0x1aab: 0xbb11, 0x1aac: 0xbb29, 0x1aad: 0xbb41, 0x1aae: 0xbb59, 0x1aaf: 0xbb71,
-	0x1ab0: 0xbb89, 0x1ab1: 0x2109, 0x1ab2: 0x1111, 0x1ab3: 0x1429, 0x1ab4: 0xbba1, 0x1ab5: 0xbbb9,
-	0x1ab6: 0xbbd1, 0x1ab7: 0x10e1, 0x1ab8: 0x10f9, 0x1ab9: 0xbbe9, 0x1aba: 0x2079, 0x1abb: 0xbc01,
-	0x1abc: 0xbab1, 0x1abd: 0x1099, 0x1abe: 0x10b1, 0x1abf: 0x10c9,
+	0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,
+	0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,
+	0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,
+	0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,
+	0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,
+	0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,
+	0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,
+	0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,
+	0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,
+	0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,
+	0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,
 	// Block 0x6b, offset 0x1ac0
-	0x1ac0: 0xbac9, 0x1ac1: 0xbae1, 0x1ac2: 0xbaf9, 0x1ac3: 0x1429, 0x1ac4: 0x1a31, 0x1ac5: 0xbb11,
-	0x1ac6: 0xbb29, 0x1ac7: 0xbb41, 0x1ac8: 0xbb59, 0x1ac9: 0xbb71, 0x1aca: 0xbb89, 0x1acb: 0x2109,
-	0x1acc: 0x1111, 0x1acd: 0xbba1, 0x1ace: 0xbba1, 0x1acf: 0xbbb9, 0x1ad0: 0xbbd1, 0x1ad1: 0x10e1,
-	0x1ad2: 0x10f9, 0x1ad3: 0xbbe9, 0x1ad4: 0x2079, 0x1ad5: 0xbc21, 0x1ad6: 0xbac9, 0x1ad7: 0x1429,
-	0x1ad8: 0xbb11, 0x1ad9: 0x10e1, 0x1ada: 0x1111, 0x1adb: 0x2109, 0x1adc: 0xbab1, 0x1add: 0x1099,
-	0x1ade: 0x10b1, 0x1adf: 0x10c9, 0x1ae0: 0xbac9, 0x1ae1: 0xbae1, 0x1ae2: 0xbaf9, 0x1ae3: 0x1429,
-	0x1ae4: 0x1a31, 0x1ae5: 0xbb11, 0x1ae6: 0xbb29, 0x1ae7: 0xbb41, 0x1ae8: 0xbb59, 0x1ae9: 0xbb71,
-	0x1aea: 0xbb89, 0x1aeb: 0x2109, 0x1aec: 0x1111, 0x1aed: 0x1429, 0x1aee: 0xbba1, 0x1aef: 0xbbb9,
-	0x1af0: 0xbbd1, 0x1af1: 0x10e1, 0x1af2: 0x10f9, 0x1af3: 0xbbe9, 0x1af4: 0x2079, 0x1af5: 0xbc01,
-	0x1af6: 0xbab1, 0x1af7: 0x1099, 0x1af8: 0x10b1, 0x1af9: 0x10c9, 0x1afa: 0xbac9, 0x1afb: 0xbae1,
-	0x1afc: 0xbaf9, 0x1afd: 0x1429, 0x1afe: 0x1a31, 0x1aff: 0xbb11,
+	0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,
+	0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,
+	0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,
+	0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,
+	0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,
+	0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,
+	0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,
+	0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,
+	0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,
+	0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,
+	0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,
 	// Block 0x6c, offset 0x1b00
-	0x1b00: 0xbb29, 0x1b01: 0xbb41, 0x1b02: 0xbb59, 0x1b03: 0xbb71, 0x1b04: 0xbb89, 0x1b05: 0x2109,
-	0x1b06: 0x1111, 0x1b07: 0xbba1, 0x1b08: 0xbba1, 0x1b09: 0xbbb9, 0x1b0a: 0xbbd1, 0x1b0b: 0x10e1,
-	0x1b0c: 0x10f9, 0x1b0d: 0xbbe9, 0x1b0e: 0x2079, 0x1b0f: 0xbc21, 0x1b10: 0xbac9, 0x1b11: 0x1429,
-	0x1b12: 0xbb11, 0x1b13: 0x10e1, 0x1b14: 0x1111, 0x1b15: 0x2109, 0x1b16: 0xbab1, 0x1b17: 0x1099,
-	0x1b18: 0x10b1, 0x1b19: 0x10c9, 0x1b1a: 0xbac9, 0x1b1b: 0xbae1, 0x1b1c: 0xbaf9, 0x1b1d: 0x1429,
-	0x1b1e: 0x1a31, 0x1b1f: 0xbb11, 0x1b20: 0xbb29, 0x1b21: 0xbb41, 0x1b22: 0xbb59, 0x1b23: 0xbb71,
-	0x1b24: 0xbb89, 0x1b25: 0x2109, 0x1b26: 0x1111, 0x1b27: 0x1429, 0x1b28: 0xbba1, 0x1b29: 0xbbb9,
-	0x1b2a: 0xbbd1, 0x1b2b: 0x10e1, 0x1b2c: 0x10f9, 0x1b2d: 0xbbe9, 0x1b2e: 0x2079, 0x1b2f: 0xbc01,
-	0x1b30: 0xbab1, 0x1b31: 0x1099, 0x1b32: 0x10b1, 0x1b33: 0x10c9, 0x1b34: 0xbac9, 0x1b35: 0xbae1,
-	0x1b36: 0xbaf9, 0x1b37: 0x1429, 0x1b38: 0x1a31, 0x1b39: 0xbb11, 0x1b3a: 0xbb29, 0x1b3b: 0xbb41,
-	0x1b3c: 0xbb59, 0x1b3d: 0xbb71, 0x1b3e: 0xbb89, 0x1b3f: 0x2109,
+	0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,
+	0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,
+	0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,
+	0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,
+	0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,
+	0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,
+	0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,
+	0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,
+	0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,
+	0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,
+	0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,
 	// Block 0x6d, offset 0x1b40
-	0x1b40: 0x1111, 0x1b41: 0xbba1, 0x1b42: 0xbba1, 0x1b43: 0xbbb9, 0x1b44: 0xbbd1, 0x1b45: 0x10e1,
-	0x1b46: 0x10f9, 0x1b47: 0xbbe9, 0x1b48: 0x2079, 0x1b49: 0xbc21, 0x1b4a: 0xbac9, 0x1b4b: 0x1429,
-	0x1b4c: 0xbb11, 0x1b4d: 0x10e1, 0x1b4e: 0x1111, 0x1b4f: 0x2109, 0x1b50: 0xbab1, 0x1b51: 0x1099,
-	0x1b52: 0x10b1, 0x1b53: 0x10c9, 0x1b54: 0xbac9, 0x1b55: 0xbae1, 0x1b56: 0xbaf9, 0x1b57: 0x1429,
-	0x1b58: 0x1a31, 0x1b59: 0xbb11, 0x1b5a: 0xbb29, 0x1b5b: 0xbb41, 0x1b5c: 0xbb59, 0x1b5d: 0xbb71,
-	0x1b5e: 0xbb89, 0x1b5f: 0x2109, 0x1b60: 0x1111, 0x1b61: 0x1429, 0x1b62: 0xbba1, 0x1b63: 0xbbb9,
-	0x1b64: 0xbbd1, 0x1b65: 0x10e1, 0x1b66: 0x10f9, 0x1b67: 0xbbe9, 0x1b68: 0x2079, 0x1b69: 0xbc01,
-	0x1b6a: 0xbab1, 0x1b6b: 0x1099, 0x1b6c: 0x10b1, 0x1b6d: 0x10c9, 0x1b6e: 0xbac9, 0x1b6f: 0xbae1,
-	0x1b70: 0xbaf9, 0x1b71: 0x1429, 0x1b72: 0x1a31, 0x1b73: 0xbb11, 0x1b74: 0xbb29, 0x1b75: 0xbb41,
-	0x1b76: 0xbb59, 0x1b77: 0xbb71, 0x1b78: 0xbb89, 0x1b79: 0x2109, 0x1b7a: 0x1111, 0x1b7b: 0xbba1,
-	0x1b7c: 0xbba1, 0x1b7d: 0xbbb9, 0x1b7e: 0xbbd1, 0x1b7f: 0x10e1,
+	0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,
+	0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,
+	0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,
+	0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,
+	0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,
+	0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,
+	0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,
+	0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,
+	0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,
+	0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,
+	0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,
 	// Block 0x6e, offset 0x1b80
-	0x1b80: 0x10f9, 0x1b81: 0xbbe9, 0x1b82: 0x2079, 0x1b83: 0xbc21, 0x1b84: 0xbac9, 0x1b85: 0x1429,
-	0x1b86: 0xbb11, 0x1b87: 0x10e1, 0x1b88: 0x1111, 0x1b89: 0x2109, 0x1b8a: 0xbc41, 0x1b8b: 0xbc41,
-	0x1b8c: 0x0040, 0x1b8d: 0x0040, 0x1b8e: 0x1f41, 0x1b8f: 0x00c9, 0x1b90: 0x0069, 0x1b91: 0x0079,
-	0x1b92: 0x1f51, 0x1b93: 0x1f61, 0x1b94: 0x1f71, 0x1b95: 0x1f81, 0x1b96: 0x1f91, 0x1b97: 0x1fa1,
-	0x1b98: 0x1f41, 0x1b99: 0x00c9, 0x1b9a: 0x0069, 0x1b9b: 0x0079, 0x1b9c: 0x1f51, 0x1b9d: 0x1f61,
-	0x1b9e: 0x1f71, 0x1b9f: 0x1f81, 0x1ba0: 0x1f91, 0x1ba1: 0x1fa1, 0x1ba2: 0x1f41, 0x1ba3: 0x00c9,
-	0x1ba4: 0x0069, 0x1ba5: 0x0079, 0x1ba6: 0x1f51, 0x1ba7: 0x1f61, 0x1ba8: 0x1f71, 0x1ba9: 0x1f81,
-	0x1baa: 0x1f91, 0x1bab: 0x1fa1, 0x1bac: 0x1f41, 0x1bad: 0x00c9, 0x1bae: 0x0069, 0x1baf: 0x0079,
-	0x1bb0: 0x1f51, 0x1bb1: 0x1f61, 0x1bb2: 0x1f71, 0x1bb3: 0x1f81, 0x1bb4: 0x1f91, 0x1bb5: 0x1fa1,
-	0x1bb6: 0x1f41, 0x1bb7: 0x00c9, 0x1bb8: 0x0069, 0x1bb9: 0x0079, 0x1bba: 0x1f51, 0x1bbb: 0x1f61,
-	0x1bbc: 0x1f71, 0x1bbd: 0x1f81, 0x1bbe: 0x1f91, 0x1bbf: 0x1fa1,
+	0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,
+	0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,
+	0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,
+	0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,
+	0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,
+	0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,
+	0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,
+	0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,
+	0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,
+	0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,
+	0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,
 	// Block 0x6f, offset 0x1bc0
-	0x1bc0: 0xe115, 0x1bc1: 0xe115, 0x1bc2: 0xe135, 0x1bc3: 0xe135, 0x1bc4: 0xe115, 0x1bc5: 0xe115,
-	0x1bc6: 0xe175, 0x1bc7: 0xe175, 0x1bc8: 0xe115, 0x1bc9: 0xe115, 0x1bca: 0xe135, 0x1bcb: 0xe135,
-	0x1bcc: 0xe115, 0x1bcd: 0xe115, 0x1bce: 0xe1f5, 0x1bcf: 0xe1f5, 0x1bd0: 0xe115, 0x1bd1: 0xe115,
-	0x1bd2: 0xe135, 0x1bd3: 0xe135, 0x1bd4: 0xe115, 0x1bd5: 0xe115, 0x1bd6: 0xe175, 0x1bd7: 0xe175,
-	0x1bd8: 0xe115, 0x1bd9: 0xe115, 0x1bda: 0xe135, 0x1bdb: 0xe135, 0x1bdc: 0xe115, 0x1bdd: 0xe115,
-	0x1bde: 0x8b05, 0x1bdf: 0x8b05, 0x1be0: 0x04b5, 0x1be1: 0x04b5, 0x1be2: 0x0208, 0x1be3: 0x0208,
-	0x1be4: 0x0208, 0x1be5: 0x0208, 0x1be6: 0x0208, 0x1be7: 0x0208, 0x1be8: 0x0208, 0x1be9: 0x0208,
-	0x1bea: 0x0208, 0x1beb: 0x0208, 0x1bec: 0x0208, 0x1bed: 0x0208, 0x1bee: 0x0208, 0x1bef: 0x0208,
-	0x1bf0: 0x0208, 0x1bf1: 0x0208, 0x1bf2: 0x0208, 0x1bf3: 0x0208, 0x1bf4: 0x0208, 0x1bf5: 0x0208,
-	0x1bf6: 0x0208, 0x1bf7: 0x0208, 0x1bf8: 0x0208, 0x1bf9: 0x0208, 0x1bfa: 0x0208, 0x1bfb: 0x0208,
-	0x1bfc: 0x0208, 0x1bfd: 0x0208, 0x1bfe: 0x0208, 0x1bff: 0x0208,
+	0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,
+	0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,
+	0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,
+	0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,
+	0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,
+	0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,
+	0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,
+	0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,
+	0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,
+	0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,
+	0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,
 	// Block 0x70, offset 0x1c00
-	0x1c00: 0xb189, 0x1c01: 0xb1a1, 0x1c02: 0xb201, 0x1c03: 0xb249, 0x1c04: 0x0040, 0x1c05: 0xb411,
-	0x1c06: 0xb291, 0x1c07: 0xb219, 0x1c08: 0xb309, 0x1c09: 0xb429, 0x1c0a: 0xb399, 0x1c0b: 0xb3b1,
-	0x1c0c: 0xb3c9, 0x1c0d: 0xb3e1, 0x1c0e: 0xb2a9, 0x1c0f: 0xb339, 0x1c10: 0xb369, 0x1c11: 0xb2d9,
-	0x1c12: 0xb381, 0x1c13: 0xb279, 0x1c14: 0xb2c1, 0x1c15: 0xb1d1, 0x1c16: 0xb1e9, 0x1c17: 0xb231,
-	0x1c18: 0xb261, 0x1c19: 0xb2f1, 0x1c1a: 0xb321, 0x1c1b: 0xb351, 0x1c1c: 0xbc59, 0x1c1d: 0x7949,
-	0x1c1e: 0xbc71, 0x1c1f: 0xbc89, 0x1c20: 0x0040, 0x1c21: 0xb1a1, 0x1c22: 0xb201, 0x1c23: 0x0040,
-	0x1c24: 0xb3f9, 0x1c25: 0x0040, 0x1c26: 0x0040, 0x1c27: 0xb219, 0x1c28: 0x0040, 0x1c29: 0xb429,
-	0x1c2a: 0xb399, 0x1c2b: 0xb3b1, 0x1c2c: 0xb3c9, 0x1c2d: 0xb3e1, 0x1c2e: 0xb2a9, 0x1c2f: 0xb339,
-	0x1c30: 0xb369, 0x1c31: 0xb2d9, 0x1c32: 0xb381, 0x1c33: 0x0040, 0x1c34: 0xb2c1, 0x1c35: 0xb1d1,
-	0x1c36: 0xb1e9, 0x1c37: 0xb231, 0x1c38: 0x0040, 0x1c39: 0xb2f1, 0x1c3a: 0x0040, 0x1c3b: 0xb351,
-	0x1c3c: 0x0040, 0x1c3d: 0x0040, 0x1c3e: 0x0040, 0x1c3f: 0x0040,
+	0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,
+	0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,
+	0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,
+	0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,
+	0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,
+	0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,
+	0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,
+	0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,
+	0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,
+	0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,
+	0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,
 	// Block 0x71, offset 0x1c40
-	0x1c40: 0x0040, 0x1c41: 0x0040, 0x1c42: 0xb201, 0x1c43: 0x0040, 0x1c44: 0x0040, 0x1c45: 0x0040,
-	0x1c46: 0x0040, 0x1c47: 0xb219, 0x1c48: 0x0040, 0x1c49: 0xb429, 0x1c4a: 0x0040, 0x1c4b: 0xb3b1,
-	0x1c4c: 0x0040, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0x0040, 0x1c51: 0xb2d9,
-	0x1c52: 0xb381, 0x1c53: 0x0040, 0x1c54: 0xb2c1, 0x1c55: 0x0040, 0x1c56: 0x0040, 0x1c57: 0xb231,
-	0x1c58: 0x0040, 0x1c59: 0xb2f1, 0x1c5a: 0x0040, 0x1c5b: 0xb351, 0x1c5c: 0x0040, 0x1c5d: 0x7949,
-	0x1c5e: 0x0040, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040,
-	0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0xb309, 0x1c69: 0xb429,
-	0x1c6a: 0xb399, 0x1c6b: 0x0040, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339,
-	0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1,
-	0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0xb321, 0x1c7b: 0xb351,
-	0x1c7c: 0xbc59, 0x1c7d: 0x0040, 0x1c7e: 0xbc71, 0x1c7f: 0x0040,
+	0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,
+	0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,
+	0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,
+	0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,
+	0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,
+	0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,
+	0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,
+	0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,
+	0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,
+	0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,
+	0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,
 	// Block 0x72, offset 0x1c80
-	0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0xb3f9, 0x1c85: 0xb411,
-	0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1,
+	0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,
+	0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,
 	0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,
 	0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,
-	0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x0040,
-	0x1c9e: 0x0040, 0x1c9f: 0x0040, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0xb249,
-	0x1ca4: 0x0040, 0x1ca5: 0xb411, 0x1ca6: 0xb291, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429,
-	0x1caa: 0x0040, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,
-	0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0xb279, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,
-	0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0xb261, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351,
+	0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,
+	0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,
+	0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,
+	0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,
+	0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,
+	0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,
 	0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,
 	// Block 0x73, offset 0x1cc0
-	0x1cc0: 0x0040, 0x1cc1: 0xbca2, 0x1cc2: 0xbcba, 0x1cc3: 0xbcd2, 0x1cc4: 0xbcea, 0x1cc5: 0xbd02,
-	0x1cc6: 0xbd1a, 0x1cc7: 0xbd32, 0x1cc8: 0xbd4a, 0x1cc9: 0xbd62, 0x1cca: 0xbd7a, 0x1ccb: 0x0018,
-	0x1ccc: 0x0018, 0x1ccd: 0x0040, 0x1cce: 0x0040, 0x1ccf: 0x0040, 0x1cd0: 0xbd92, 0x1cd1: 0xbdb2,
-	0x1cd2: 0xbdd2, 0x1cd3: 0xbdf2, 0x1cd4: 0xbe12, 0x1cd5: 0xbe32, 0x1cd6: 0xbe52, 0x1cd7: 0xbe72,
-	0x1cd8: 0xbe92, 0x1cd9: 0xbeb2, 0x1cda: 0xbed2, 0x1cdb: 0xbef2, 0x1cdc: 0xbf12, 0x1cdd: 0xbf32,
-	0x1cde: 0xbf52, 0x1cdf: 0xbf72, 0x1ce0: 0xbf92, 0x1ce1: 0xbfb2, 0x1ce2: 0xbfd2, 0x1ce3: 0xbff2,
-	0x1ce4: 0xc012, 0x1ce5: 0xc032, 0x1ce6: 0xc052, 0x1ce7: 0xc072, 0x1ce8: 0xc092, 0x1ce9: 0xc0b2,
-	0x1cea: 0xc0d1, 0x1ceb: 0x1159, 0x1cec: 0x0269, 0x1ced: 0x6671, 0x1cee: 0xc111, 0x1cef: 0x0040,
-	0x1cf0: 0x0039, 0x1cf1: 0x0ee9, 0x1cf2: 0x1159, 0x1cf3: 0x0ef9, 0x1cf4: 0x0f09, 0x1cf5: 0x1199,
-	0x1cf6: 0x0f31, 0x1cf7: 0x0249, 0x1cf8: 0x0f41, 0x1cf9: 0x0259, 0x1cfa: 0x0f51, 0x1cfb: 0x0359,
-	0x1cfc: 0x0f61, 0x1cfd: 0x0f71, 0x1cfe: 0x00d9, 0x1cff: 0x0f99,
+	0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,
+	0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,
+	0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,
+	0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,
+	0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,
+	0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,
+	0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,
+	0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,
+	0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,
+	0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,
+	0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,
 	// Block 0x74, offset 0x1d00
-	0x1d00: 0x2039, 0x1d01: 0x0269, 0x1d02: 0x01d9, 0x1d03: 0x0fa9, 0x1d04: 0x0fb9, 0x1d05: 0x1089,
-	0x1d06: 0x0279, 0x1d07: 0x0369, 0x1d08: 0x0289, 0x1d09: 0x13d1, 0x1d0a: 0xc129, 0x1d0b: 0x65b1,
-	0x1d0c: 0xc141, 0x1d0d: 0x1441, 0x1d0e: 0xc159, 0x1d0f: 0xc179, 0x1d10: 0x0018, 0x1d11: 0x0018,
-	0x1d12: 0x0018, 0x1d13: 0x0018, 0x1d14: 0x0018, 0x1d15: 0x0018, 0x1d16: 0x0018, 0x1d17: 0x0018,
-	0x1d18: 0x0018, 0x1d19: 0x0018, 0x1d1a: 0x0018, 0x1d1b: 0x0018, 0x1d1c: 0x0018, 0x1d1d: 0x0018,
-	0x1d1e: 0x0018, 0x1d1f: 0x0018, 0x1d20: 0x0018, 0x1d21: 0x0018, 0x1d22: 0x0018, 0x1d23: 0x0018,
-	0x1d24: 0x0018, 0x1d25: 0x0018, 0x1d26: 0x0018, 0x1d27: 0x0018, 0x1d28: 0x0018, 0x1d29: 0x0018,
-	0x1d2a: 0xc191, 0x1d2b: 0xc1a9, 0x1d2c: 0x0040, 0x1d2d: 0x0040, 0x1d2e: 0x0040, 0x1d2f: 0x0040,
-	0x1d30: 0x0018, 0x1d31: 0x0018, 0x1d32: 0x0018, 0x1d33: 0x0018, 0x1d34: 0x0018, 0x1d35: 0x0018,
-	0x1d36: 0x0018, 0x1d37: 0x0018, 0x1d38: 0x0018, 0x1d39: 0x0018, 0x1d3a: 0x0018, 0x1d3b: 0x0018,
-	0x1d3c: 0x0018, 0x1d3d: 0x0018, 0x1d3e: 0x0018, 0x1d3f: 0x0018,
+	0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,
+	0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,
+	0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,
+	0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,
+	0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,
+	0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,
+	0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,
+	0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,
+	0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,
+	0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,
+	0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,
 	// Block 0x75, offset 0x1d40
-	0x1d40: 0xc1d9, 0x1d41: 0xc211, 0x1d42: 0xc249, 0x1d43: 0x0040, 0x1d44: 0x0040, 0x1d45: 0x0040,
-	0x1d46: 0x0040, 0x1d47: 0x0040, 0x1d48: 0x0040, 0x1d49: 0x0040, 0x1d4a: 0x0040, 0x1d4b: 0x0040,
-	0x1d4c: 0x0040, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xc269, 0x1d51: 0xc289,
-	0x1d52: 0xc2a9, 0x1d53: 0xc2c9, 0x1d54: 0xc2e9, 0x1d55: 0xc309, 0x1d56: 0xc329, 0x1d57: 0xc349,
-	0x1d58: 0xc369, 0x1d59: 0xc389, 0x1d5a: 0xc3a9, 0x1d5b: 0xc3c9, 0x1d5c: 0xc3e9, 0x1d5d: 0xc409,
-	0x1d5e: 0xc429, 0x1d5f: 0xc449, 0x1d60: 0xc469, 0x1d61: 0xc489, 0x1d62: 0xc4a9, 0x1d63: 0xc4c9,
-	0x1d64: 0xc4e9, 0x1d65: 0xc509, 0x1d66: 0xc529, 0x1d67: 0xc549, 0x1d68: 0xc569, 0x1d69: 0xc589,
-	0x1d6a: 0xc5a9, 0x1d6b: 0xc5c9, 0x1d6c: 0xc5e9, 0x1d6d: 0xc609, 0x1d6e: 0xc629, 0x1d6f: 0xc649,
-	0x1d70: 0xc669, 0x1d71: 0xc689, 0x1d72: 0xc6a9, 0x1d73: 0xc6c9, 0x1d74: 0xc6e9, 0x1d75: 0xc709,
-	0x1d76: 0xc729, 0x1d77: 0xc749, 0x1d78: 0xc769, 0x1d79: 0xc789, 0x1d7a: 0xc7a9, 0x1d7b: 0xc7c9,
-	0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040,
+	0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,
+	0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,
+	0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,
+	0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,
+	0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,
+	0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,
+	0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,
+	0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040,
+	0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,
+	0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,
+	0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,
 	// Block 0x76, offset 0x1d80
-	0x1d80: 0xcaf9, 0x1d81: 0xcb19, 0x1d82: 0xcb39, 0x1d83: 0x8b1d, 0x1d84: 0xcb59, 0x1d85: 0xcb79,
-	0x1d86: 0xcb99, 0x1d87: 0xcbb9, 0x1d88: 0xcbd9, 0x1d89: 0xcbf9, 0x1d8a: 0xcc19, 0x1d8b: 0xcc39,
-	0x1d8c: 0xcc59, 0x1d8d: 0x8b3d, 0x1d8e: 0xcc79, 0x1d8f: 0xcc99, 0x1d90: 0xccb9, 0x1d91: 0xccd9,
-	0x1d92: 0x8b5d, 0x1d93: 0xccf9, 0x1d94: 0xcd19, 0x1d95: 0xc429, 0x1d96: 0x8b7d, 0x1d97: 0xcd39,
-	0x1d98: 0xcd59, 0x1d99: 0xcd79, 0x1d9a: 0xcd99, 0x1d9b: 0xcdb9, 0x1d9c: 0x8b9d, 0x1d9d: 0xcdd9,
-	0x1d9e: 0xcdf9, 0x1d9f: 0xce19, 0x1da0: 0xce39, 0x1da1: 0xce59, 0x1da2: 0xc789, 0x1da3: 0xce79,
-	0x1da4: 0xce99, 0x1da5: 0xceb9, 0x1da6: 0xced9, 0x1da7: 0xcef9, 0x1da8: 0xcf19, 0x1da9: 0xcf39,
-	0x1daa: 0xcf59, 0x1dab: 0xcf79, 0x1dac: 0xcf99, 0x1dad: 0xcfb9, 0x1dae: 0xcfd9, 0x1daf: 0xcff9,
-	0x1db0: 0xd019, 0x1db1: 0xd039, 0x1db2: 0xd039, 0x1db3: 0xd039, 0x1db4: 0x8bbd, 0x1db5: 0xd059,
-	0x1db6: 0xd079, 0x1db7: 0xd099, 0x1db8: 0x8bdd, 0x1db9: 0xd0b9, 0x1dba: 0xd0d9, 0x1dbb: 0xd0f9,
-	0x1dbc: 0xd119, 0x1dbd: 0xd139, 0x1dbe: 0xd159, 0x1dbf: 0xd179,
+	0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,
+	0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,
+	0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,
+	0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,
+	0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,
+	0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,
+	0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,
+	0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,
+	0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,
+	0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,
+	0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,
 	// Block 0x77, offset 0x1dc0
-	0x1dc0: 0xd199, 0x1dc1: 0xd1b9, 0x1dc2: 0xd1d9, 0x1dc3: 0xd1f9, 0x1dc4: 0xd219, 0x1dc5: 0xd239,
-	0x1dc6: 0xd239, 0x1dc7: 0xd259, 0x1dc8: 0xd279, 0x1dc9: 0xd299, 0x1dca: 0xd2b9, 0x1dcb: 0xd2d9,
-	0x1dcc: 0xd2f9, 0x1dcd: 0xd319, 0x1dce: 0xd339, 0x1dcf: 0xd359, 0x1dd0: 0xd379, 0x1dd1: 0xd399,
-	0x1dd2: 0xd3b9, 0x1dd3: 0xd3d9, 0x1dd4: 0xd3f9, 0x1dd5: 0xd419, 0x1dd6: 0xd439, 0x1dd7: 0xd459,
-	0x1dd8: 0xd479, 0x1dd9: 0x8bfd, 0x1dda: 0xd499, 0x1ddb: 0xd4b9, 0x1ddc: 0xd4d9, 0x1ddd: 0xc309,
-	0x1dde: 0xd4f9, 0x1ddf: 0xd519, 0x1de0: 0x8c1d, 0x1de1: 0x8c3d, 0x1de2: 0xd539, 0x1de3: 0xd559,
-	0x1de4: 0xd579, 0x1de5: 0xd599, 0x1de6: 0xd5b9, 0x1de7: 0xd5d9, 0x1de8: 0x0040, 0x1de9: 0xd5f9,
-	0x1dea: 0xd619, 0x1deb: 0xd619, 0x1dec: 0x8c5d, 0x1ded: 0xd639, 0x1dee: 0xd659, 0x1def: 0xd679,
-	0x1df0: 0xd699, 0x1df1: 0x8c7d, 0x1df2: 0xd6b9, 0x1df3: 0xd6d9, 0x1df4: 0x0040, 0x1df5: 0xd6f9,
-	0x1df6: 0xd719, 0x1df7: 0xd739, 0x1df8: 0xd759, 0x1df9: 0xd779, 0x1dfa: 0xd799, 0x1dfb: 0x8c9d,
-	0x1dfc: 0xd7b9, 0x1dfd: 0x8cbd, 0x1dfe: 0xd7d9, 0x1dff: 0xd7f9,
+	0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,
+	0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,
+	0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289,
+	0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349,
+	0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409,
+	0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9,
+	0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589,
+	0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649,
+	0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709,
+	0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9,
+	0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,
 	// Block 0x78, offset 0x1e00
-	0x1e00: 0xd819, 0x1e01: 0xd839, 0x1e02: 0xd859, 0x1e03: 0xd879, 0x1e04: 0xd899, 0x1e05: 0xd8b9,
-	0x1e06: 0xd8d9, 0x1e07: 0xd8f9, 0x1e08: 0xd919, 0x1e09: 0x8cdd, 0x1e0a: 0xd939, 0x1e0b: 0xd959,
-	0x1e0c: 0xd979, 0x1e0d: 0xd999, 0x1e0e: 0xd9b9, 0x1e0f: 0x8cfd, 0x1e10: 0xd9d9, 0x1e11: 0x8d1d,
-	0x1e12: 0x8d3d, 0x1e13: 0xd9f9, 0x1e14: 0xda19, 0x1e15: 0xda19, 0x1e16: 0xda39, 0x1e17: 0x8d5d,
-	0x1e18: 0x8d7d, 0x1e19: 0xda59, 0x1e1a: 0xda79, 0x1e1b: 0xda99, 0x1e1c: 0xdab9, 0x1e1d: 0xdad9,
-	0x1e1e: 0xdaf9, 0x1e1f: 0xdb19, 0x1e20: 0xdb39, 0x1e21: 0xdb59, 0x1e22: 0xdb79, 0x1e23: 0xdb99,
-	0x1e24: 0x8d9d, 0x1e25: 0xdbb9, 0x1e26: 0xdbd9, 0x1e27: 0xdbf9, 0x1e28: 0xdc19, 0x1e29: 0xdbf9,
-	0x1e2a: 0xdc39, 0x1e2b: 0xdc59, 0x1e2c: 0xdc79, 0x1e2d: 0xdc99, 0x1e2e: 0xdcb9, 0x1e2f: 0xdcd9,
-	0x1e30: 0xdcf9, 0x1e31: 0xdd19, 0x1e32: 0xdd39, 0x1e33: 0xdd59, 0x1e34: 0xdd79, 0x1e35: 0xdd99,
-	0x1e36: 0xddb9, 0x1e37: 0xddd9, 0x1e38: 0x8dbd, 0x1e39: 0xddf9, 0x1e3a: 0xde19, 0x1e3b: 0xde39,
-	0x1e3c: 0xde59, 0x1e3d: 0xde79, 0x1e3e: 0x8ddd, 0x1e3f: 0xde99,
+	0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79,
+	0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39,
+	0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9,
+	0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39,
+	0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9,
+	0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79,
+	0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39,
+	0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9,
+	0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059,
+	0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9,
+	0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179,
 	// Block 0x79, offset 0x1e40
-	0x1e40: 0xe599, 0x1e41: 0xe5b9, 0x1e42: 0xe5d9, 0x1e43: 0xe5f9, 0x1e44: 0xe619, 0x1e45: 0xe639,
-	0x1e46: 0x8efd, 0x1e47: 0xe659, 0x1e48: 0xe679, 0x1e49: 0xe699, 0x1e4a: 0xe6b9, 0x1e4b: 0xe6d9,
-	0x1e4c: 0xe6f9, 0x1e4d: 0x8f1d, 0x1e4e: 0xe719, 0x1e4f: 0xe739, 0x1e50: 0x8f3d, 0x1e51: 0x8f5d,
-	0x1e52: 0xe759, 0x1e53: 0xe779, 0x1e54: 0xe799, 0x1e55: 0xe7b9, 0x1e56: 0xe7d9, 0x1e57: 0xe7f9,
-	0x1e58: 0xe819, 0x1e59: 0xe839, 0x1e5a: 0xe859, 0x1e5b: 0x8f7d, 0x1e5c: 0xe879, 0x1e5d: 0x8f9d,
-	0x1e5e: 0xe899, 0x1e5f: 0x0040, 0x1e60: 0xe8b9, 0x1e61: 0xe8d9, 0x1e62: 0xe8f9, 0x1e63: 0x8fbd,
-	0x1e64: 0xe919, 0x1e65: 0xe939, 0x1e66: 0x8fdd, 0x1e67: 0x8ffd, 0x1e68: 0xe959, 0x1e69: 0xe979,
-	0x1e6a: 0xe999, 0x1e6b: 0xe9b9, 0x1e6c: 0xe9d9, 0x1e6d: 0xe9d9, 0x1e6e: 0xe9f9, 0x1e6f: 0xea19,
-	0x1e70: 0xea39, 0x1e71: 0xea59, 0x1e72: 0xea79, 0x1e73: 0xea99, 0x1e74: 0xeab9, 0x1e75: 0x901d,
-	0x1e76: 0xead9, 0x1e77: 0x903d, 0x1e78: 0xeaf9, 0x1e79: 0x905d, 0x1e7a: 0xeb19, 0x1e7b: 0x907d,
-	0x1e7c: 0x909d, 0x1e7d: 0x90bd, 0x1e7e: 0xeb39, 0x1e7f: 0xeb59,
+	0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239,
+	0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9,
+	0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399,
+	0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459,
+	0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309,
+	0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559,
+	0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9,
+	0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679,
+	0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9,
+	0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d,
+	0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9,
 	// Block 0x7a, offset 0x1e80
-	0x1e80: 0xeb79, 0x1e81: 0x90dd, 0x1e82: 0x90fd, 0x1e83: 0x911d, 0x1e84: 0x913d, 0x1e85: 0xeb99,
-	0x1e86: 0xebb9, 0x1e87: 0xebb9, 0x1e88: 0xebd9, 0x1e89: 0xebf9, 0x1e8a: 0xec19, 0x1e8b: 0xec39,
-	0x1e8c: 0xec59, 0x1e8d: 0x915d, 0x1e8e: 0xec79, 0x1e8f: 0xec99, 0x1e90: 0xecb9, 0x1e91: 0xecd9,
-	0x1e92: 0x917d, 0x1e93: 0xecf9, 0x1e94: 0x919d, 0x1e95: 0x91bd, 0x1e96: 0xed19, 0x1e97: 0xed39,
-	0x1e98: 0xed59, 0x1e99: 0xed79, 0x1e9a: 0xed99, 0x1e9b: 0xedb9, 0x1e9c: 0x91dd, 0x1e9d: 0x91fd,
-	0x1e9e: 0x921d, 0x1e9f: 0x0040, 0x1ea0: 0xedd9, 0x1ea1: 0x923d, 0x1ea2: 0xedf9, 0x1ea3: 0xee19,
-	0x1ea4: 0xee39, 0x1ea5: 0x925d, 0x1ea6: 0xee59, 0x1ea7: 0xee79, 0x1ea8: 0xee99, 0x1ea9: 0xeeb9,
-	0x1eaa: 0xeed9, 0x1eab: 0x927d, 0x1eac: 0xeef9, 0x1ead: 0xef19, 0x1eae: 0xef39, 0x1eaf: 0xef59,
-	0x1eb0: 0xef79, 0x1eb1: 0xef99, 0x1eb2: 0x929d, 0x1eb3: 0x92bd, 0x1eb4: 0xefb9, 0x1eb5: 0x92dd,
-	0x1eb6: 0xefd9, 0x1eb7: 0x92fd, 0x1eb8: 0xeff9, 0x1eb9: 0xf019, 0x1eba: 0xf039, 0x1ebb: 0x931d,
-	0x1ebc: 0x933d, 0x1ebd: 0xf059, 0x1ebe: 0x935d, 0x1ebf: 0xf079,
+	0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9,
+	0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959,
+	0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d,
+	0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d,
+	0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9,
+	0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99,
+	0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9,
+	0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9,
+	0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99,
+	0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39,
+	0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99,
 	// Block 0x7b, offset 0x1ec0
-	0x1ec0: 0xf6b9, 0x1ec1: 0xf6d9, 0x1ec2: 0xf6f9, 0x1ec3: 0xf719, 0x1ec4: 0xf739, 0x1ec5: 0x951d,
-	0x1ec6: 0xf759, 0x1ec7: 0xf779, 0x1ec8: 0xf799, 0x1ec9: 0xf7b9, 0x1eca: 0xf7d9, 0x1ecb: 0x953d,
-	0x1ecc: 0x955d, 0x1ecd: 0xf7f9, 0x1ece: 0xf819, 0x1ecf: 0xf839, 0x1ed0: 0xf859, 0x1ed1: 0xf879,
-	0x1ed2: 0xf899, 0x1ed3: 0x957d, 0x1ed4: 0xf8b9, 0x1ed5: 0xf8d9, 0x1ed6: 0xf8f9, 0x1ed7: 0xf919,
-	0x1ed8: 0x959d, 0x1ed9: 0x95bd, 0x1eda: 0xf939, 0x1edb: 0xf959, 0x1edc: 0xf979, 0x1edd: 0x95dd,
-	0x1ede: 0xf999, 0x1edf: 0xf9b9, 0x1ee0: 0x6815, 0x1ee1: 0x95fd, 0x1ee2: 0xf9d9, 0x1ee3: 0xf9f9,
-	0x1ee4: 0xfa19, 0x1ee5: 0x961d, 0x1ee6: 0xfa39, 0x1ee7: 0xfa59, 0x1ee8: 0xfa79, 0x1ee9: 0xfa99,
-	0x1eea: 0xfab9, 0x1eeb: 0xfad9, 0x1eec: 0xfaf9, 0x1eed: 0x963d, 0x1eee: 0xfb19, 0x1eef: 0xfb39,
-	0x1ef0: 0xfb59, 0x1ef1: 0x965d, 0x1ef2: 0xfb79, 0x1ef3: 0xfb99, 0x1ef4: 0xfbb9, 0x1ef5: 0xfbd9,
-	0x1ef6: 0x7b35, 0x1ef7: 0x967d, 0x1ef8: 0xfbf9, 0x1ef9: 0xfc19, 0x1efa: 0xfc39, 0x1efb: 0x969d,
-	0x1efc: 0xfc59, 0x1efd: 0x96bd, 0x1efe: 0xfc79, 0x1eff: 0xfc79,
+	0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639,
+	0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9,
+	0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d,
+	0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9,
+	0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d,
+	0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd,
+	0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979,
+	0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19,
+	0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d,
+	0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d,
+	0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59,
 	// Block 0x7c, offset 0x1f00
-	0x1f00: 0xfc99, 0x1f01: 0x96dd, 0x1f02: 0xfcb9, 0x1f03: 0xfcd9, 0x1f04: 0xfcf9, 0x1f05: 0xfd19,
-	0x1f06: 0xfd39, 0x1f07: 0xfd59, 0x1f08: 0xfd79, 0x1f09: 0x96fd, 0x1f0a: 0xfd99, 0x1f0b: 0xfdb9,
-	0x1f0c: 0xfdd9, 0x1f0d: 0xfdf9, 0x1f0e: 0xfe19, 0x1f0f: 0xfe39, 0x1f10: 0x971d, 0x1f11: 0xfe59,
-	0x1f12: 0x973d, 0x1f13: 0x975d, 0x1f14: 0x977d, 0x1f15: 0xfe79, 0x1f16: 0xfe99, 0x1f17: 0xfeb9,
-	0x1f18: 0xfed9, 0x1f19: 0xfef9, 0x1f1a: 0xff19, 0x1f1b: 0xff39, 0x1f1c: 0xff59, 0x1f1d: 0x979d,
-	0x1f1e: 0x0040, 0x1f1f: 0x0040, 0x1f20: 0x0040, 0x1f21: 0x0040, 0x1f22: 0x0040, 0x1f23: 0x0040,
-	0x1f24: 0x0040, 0x1f25: 0x0040, 0x1f26: 0x0040, 0x1f27: 0x0040, 0x1f28: 0x0040, 0x1f29: 0x0040,
-	0x1f2a: 0x0040, 0x1f2b: 0x0040, 0x1f2c: 0x0040, 0x1f2d: 0x0040, 0x1f2e: 0x0040, 0x1f2f: 0x0040,
-	0x1f30: 0x0040, 0x1f31: 0x0040, 0x1f32: 0x0040, 0x1f33: 0x0040, 0x1f34: 0x0040, 0x1f35: 0x0040,
-	0x1f36: 0x0040, 0x1f37: 0x0040, 0x1f38: 0x0040, 0x1f39: 0x0040, 0x1f3a: 0x0040, 0x1f3b: 0x0040,
-	0x1f3c: 0x0040, 0x1f3d: 0x0040, 0x1f3e: 0x0040, 0x1f3f: 0x0040,
+	0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99,
+	0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39,
+	0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9,
+	0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39,
+	0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd,
+	0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19,
+	0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9,
+	0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59,
+	0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd,
+	0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d,
+	0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079,
+	// Block 0x7d, offset 0x1f40
+	0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d,
+	0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d,
+	0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879,
+	0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919,
+	0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd,
+	0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9,
+	0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99,
+	0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39,
+	0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9,
+	0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d,
+	0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79,
+	// Block 0x7e, offset 0x1f80
+	0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19,
+	0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9,
+	0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59,
+	0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9,
+	0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d,
+	0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,
+	0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,
+	0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,
+	0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,
+	0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,
+	0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,
 }
 
-// idnaIndex: 35 blocks, 2240 entries, 4480 bytes
+// idnaIndex: 36 blocks, 2304 entries, 4608 bytes
 // Block 0 is the zero block.
-var idnaIndex = [2240]uint16{
+var idnaIndex = [2304]uint16{
 	// Block 0x0, offset 0x0
 	// Block 0x1, offset 0x40
 	// Block 0x2, offset 0x80
 	// Block 0x3, offset 0xc0
-	0xc2: 0x01, 0xc3: 0x7b, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
-	0xc8: 0x06, 0xc9: 0x7c, 0xca: 0x7d, 0xcb: 0x07, 0xcc: 0x7e, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
-	0xd0: 0x7f, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x80, 0xd6: 0x81, 0xd7: 0x82,
-	0xd8: 0x0f, 0xd9: 0x83, 0xda: 0x84, 0xdb: 0x10, 0xdc: 0x11, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87,
+	0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
+	0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
+	0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,
+	0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,
 	0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,
 	0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,
-	0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20,
+	0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,
 	// Block 0x4, offset 0x100
-	0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x12, 0x126: 0x13, 0x127: 0x14,
-	0x128: 0x15, 0x129: 0x16, 0x12a: 0x17, 0x12b: 0x18, 0x12c: 0x19, 0x12d: 0x1a, 0x12e: 0x1b, 0x12f: 0x8d,
-	0x130: 0x8e, 0x131: 0x1c, 0x132: 0x1d, 0x133: 0x1e, 0x134: 0x8f, 0x135: 0x1f, 0x136: 0x90, 0x137: 0x91,
-	0x138: 0x92, 0x139: 0x93, 0x13a: 0x20, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x21, 0x13e: 0x22, 0x13f: 0x96,
+	0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,
+	0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,
+	0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,
+	0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,
 	// Block 0x5, offset 0x140
-	0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9b, 0x147: 0x9b,
-	0x148: 0x9d, 0x149: 0x9e, 0x14a: 0x9f, 0x14b: 0xa0, 0x14c: 0xa1, 0x14d: 0xa2, 0x14e: 0xa3, 0x14f: 0xa4,
-	0x150: 0xa5, 0x151: 0x9d, 0x152: 0x9d, 0x153: 0x9d, 0x154: 0x9d, 0x155: 0x9d, 0x156: 0x9d, 0x157: 0x9d,
-	0x158: 0x9d, 0x159: 0xa6, 0x15a: 0xa7, 0x15b: 0xa8, 0x15c: 0xa9, 0x15d: 0xaa, 0x15e: 0xab, 0x15f: 0xac,
-	0x160: 0xad, 0x161: 0xae, 0x162: 0xaf, 0x163: 0xb0, 0x164: 0xb1, 0x165: 0xb2, 0x166: 0xb3, 0x167: 0xb4,
-	0x168: 0xb5, 0x169: 0xb6, 0x16a: 0xb7, 0x16b: 0xb8, 0x16c: 0xb9, 0x16d: 0xba, 0x16e: 0xbb, 0x16f: 0xbc,
-	0x170: 0xbd, 0x171: 0xbe, 0x172: 0xbf, 0x173: 0xc0, 0x174: 0x23, 0x175: 0x24, 0x176: 0x25, 0x177: 0xc1,
-	0x178: 0x26, 0x179: 0x26, 0x17a: 0x27, 0x17b: 0x26, 0x17c: 0xc2, 0x17d: 0x28, 0x17e: 0x29, 0x17f: 0x2a,
+	0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,
+	0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,
+	0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,
+	0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,
+	0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,
+	0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,
+	0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,
+	0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,
 	// Block 0x6, offset 0x180
-	0x180: 0x2b, 0x181: 0x2c, 0x182: 0x2d, 0x183: 0xc3, 0x184: 0x2e, 0x185: 0x2f, 0x186: 0xc4, 0x187: 0x9b,
-	0x188: 0xc5, 0x189: 0xc6, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc7, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xc8,
-	0x190: 0xc9, 0x191: 0x30, 0x192: 0x31, 0x193: 0x32, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,
+	0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,
+	0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,
+	0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,
 	0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,
 	0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,
-	0x1a8: 0xca, 0x1a9: 0xcb, 0x1aa: 0x9b, 0x1ab: 0xcc, 0x1ac: 0x9b, 0x1ad: 0xcd, 0x1ae: 0xce, 0x1af: 0xcf,
-	0x1b0: 0xd0, 0x1b1: 0x33, 0x1b2: 0x26, 0x1b3: 0x34, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4,
-	0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x35,
+	0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0,
+	0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,
+	0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,
 	// Block 0x7, offset 0x1c0
-	0x1c0: 0x36, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x37, 0x1c6: 0x38, 0x1c7: 0xe0,
-	0x1c8: 0xe1, 0x1c9: 0x39, 0x1ca: 0x3a, 0x1cb: 0x3b, 0x1cc: 0x3c, 0x1cd: 0x3d, 0x1ce: 0x3e, 0x1cf: 0x3f,
-	0x1d0: 0x9d, 0x1d1: 0x9d, 0x1d2: 0x9d, 0x1d3: 0x9d, 0x1d4: 0x9d, 0x1d5: 0x9d, 0x1d6: 0x9d, 0x1d7: 0x9d,
-	0x1d8: 0x9d, 0x1d9: 0x9d, 0x1da: 0x9d, 0x1db: 0x9d, 0x1dc: 0x9d, 0x1dd: 0x9d, 0x1de: 0x9d, 0x1df: 0x9d,
-	0x1e0: 0x9d, 0x1e1: 0x9d, 0x1e2: 0x9d, 0x1e3: 0x9d, 0x1e4: 0x9d, 0x1e5: 0x9d, 0x1e6: 0x9d, 0x1e7: 0x9d,
-	0x1e8: 0x9d, 0x1e9: 0x9d, 0x1ea: 0x9d, 0x1eb: 0x9d, 0x1ec: 0x9d, 0x1ed: 0x9d, 0x1ee: 0x9d, 0x1ef: 0x9d,
-	0x1f0: 0x9d, 0x1f1: 0x9d, 0x1f2: 0x9d, 0x1f3: 0x9d, 0x1f4: 0x9d, 0x1f5: 0x9d, 0x1f6: 0x9d, 0x1f7: 0x9d,
-	0x1f8: 0x9d, 0x1f9: 0x9d, 0x1fa: 0x9d, 0x1fb: 0x9d, 0x1fc: 0x9d, 0x1fd: 0x9d, 0x1fe: 0x9d, 0x1ff: 0x9d,
+	0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,
+	0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,
+	0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,
+	0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,
+	0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,
+	0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,
+	0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,
+	0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,
 	// Block 0x8, offset 0x200
-	0x200: 0x9d, 0x201: 0x9d, 0x202: 0x9d, 0x203: 0x9d, 0x204: 0x9d, 0x205: 0x9d, 0x206: 0x9d, 0x207: 0x9d,
-	0x208: 0x9d, 0x209: 0x9d, 0x20a: 0x9d, 0x20b: 0x9d, 0x20c: 0x9d, 0x20d: 0x9d, 0x20e: 0x9d, 0x20f: 0x9d,
-	0x210: 0x9d, 0x211: 0x9d, 0x212: 0x9d, 0x213: 0x9d, 0x214: 0x9d, 0x215: 0x9d, 0x216: 0x9d, 0x217: 0x9d,
-	0x218: 0x9d, 0x219: 0x9d, 0x21a: 0x9d, 0x21b: 0x9d, 0x21c: 0x9d, 0x21d: 0x9d, 0x21e: 0x9d, 0x21f: 0x9d,
-	0x220: 0x9d, 0x221: 0x9d, 0x222: 0x9d, 0x223: 0x9d, 0x224: 0x9d, 0x225: 0x9d, 0x226: 0x9d, 0x227: 0x9d,
-	0x228: 0x9d, 0x229: 0x9d, 0x22a: 0x9d, 0x22b: 0x9d, 0x22c: 0x9d, 0x22d: 0x9d, 0x22e: 0x9d, 0x22f: 0x9d,
-	0x230: 0x9d, 0x231: 0x9d, 0x232: 0x9d, 0x233: 0x9d, 0x234: 0x9d, 0x235: 0x9d, 0x236: 0xb0, 0x237: 0x9b,
-	0x238: 0x9d, 0x239: 0x9d, 0x23a: 0x9d, 0x23b: 0x9d, 0x23c: 0x9d, 0x23d: 0x9d, 0x23e: 0x9d, 0x23f: 0x9d,
+	0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,
+	0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,
+	0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,
+	0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,
+	0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,
+	0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,
+	0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,
+	0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,
 	// Block 0x9, offset 0x240
-	0x240: 0x9d, 0x241: 0x9d, 0x242: 0x9d, 0x243: 0x9d, 0x244: 0x9d, 0x245: 0x9d, 0x246: 0x9d, 0x247: 0x9d,
-	0x248: 0x9d, 0x249: 0x9d, 0x24a: 0x9d, 0x24b: 0x9d, 0x24c: 0x9d, 0x24d: 0x9d, 0x24e: 0x9d, 0x24f: 0x9d,
-	0x250: 0x9d, 0x251: 0x9d, 0x252: 0x9d, 0x253: 0x9d, 0x254: 0x9d, 0x255: 0x9d, 0x256: 0x9d, 0x257: 0x9d,
-	0x258: 0x9d, 0x259: 0x9d, 0x25a: 0x9d, 0x25b: 0x9d, 0x25c: 0x9d, 0x25d: 0x9d, 0x25e: 0x9d, 0x25f: 0x9d,
-	0x260: 0x9d, 0x261: 0x9d, 0x262: 0x9d, 0x263: 0x9d, 0x264: 0x9d, 0x265: 0x9d, 0x266: 0x9d, 0x267: 0x9d,
-	0x268: 0x9d, 0x269: 0x9d, 0x26a: 0x9d, 0x26b: 0x9d, 0x26c: 0x9d, 0x26d: 0x9d, 0x26e: 0x9d, 0x26f: 0x9d,
-	0x270: 0x9d, 0x271: 0x9d, 0x272: 0x9d, 0x273: 0x9d, 0x274: 0x9d, 0x275: 0x9d, 0x276: 0x9d, 0x277: 0x9d,
-	0x278: 0x9d, 0x279: 0x9d, 0x27a: 0x9d, 0x27b: 0x9d, 0x27c: 0x9d, 0x27d: 0x9d, 0x27e: 0x9d, 0x27f: 0x9d,
+	0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,
+	0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,
+	0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,
+	0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,
+	0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,
+	0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,
+	0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,
+	0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,
 	// Block 0xa, offset 0x280
-	0x280: 0x9d, 0x281: 0x9d, 0x282: 0x9d, 0x283: 0x9d, 0x284: 0x9d, 0x285: 0x9d, 0x286: 0x9d, 0x287: 0x9d,
-	0x288: 0x9d, 0x289: 0x9d, 0x28a: 0x9d, 0x28b: 0x9d, 0x28c: 0x9d, 0x28d: 0x9d, 0x28e: 0x9d, 0x28f: 0x9d,
-	0x290: 0x9d, 0x291: 0x9d, 0x292: 0x9d, 0x293: 0x9d, 0x294: 0x9d, 0x295: 0x9d, 0x296: 0x9d, 0x297: 0x9d,
-	0x298: 0x9d, 0x299: 0x9d, 0x29a: 0x9d, 0x29b: 0x9d, 0x29c: 0x9d, 0x29d: 0x9d, 0x29e: 0x9d, 0x29f: 0x9d,
-	0x2a0: 0x9d, 0x2a1: 0x9d, 0x2a2: 0x9d, 0x2a3: 0x9d, 0x2a4: 0x9d, 0x2a5: 0x9d, 0x2a6: 0x9d, 0x2a7: 0x9d,
-	0x2a8: 0x9d, 0x2a9: 0x9d, 0x2aa: 0x9d, 0x2ab: 0x9d, 0x2ac: 0x9d, 0x2ad: 0x9d, 0x2ae: 0x9d, 0x2af: 0x9d,
-	0x2b0: 0x9d, 0x2b1: 0x9d, 0x2b2: 0x9d, 0x2b3: 0x9d, 0x2b4: 0x9d, 0x2b5: 0x9d, 0x2b6: 0x9d, 0x2b7: 0x9d,
-	0x2b8: 0x9d, 0x2b9: 0x9d, 0x2ba: 0x9d, 0x2bb: 0x9d, 0x2bc: 0x9d, 0x2bd: 0x9d, 0x2be: 0x9d, 0x2bf: 0xe2,
+	0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,
+	0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,
+	0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,
+	0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,
+	0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,
+	0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,
+	0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,
+	0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3,
 	// Block 0xb, offset 0x2c0
-	0x2c0: 0x9d, 0x2c1: 0x9d, 0x2c2: 0x9d, 0x2c3: 0x9d, 0x2c4: 0x9d, 0x2c5: 0x9d, 0x2c6: 0x9d, 0x2c7: 0x9d,
-	0x2c8: 0x9d, 0x2c9: 0x9d, 0x2ca: 0x9d, 0x2cb: 0x9d, 0x2cc: 0x9d, 0x2cd: 0x9d, 0x2ce: 0x9d, 0x2cf: 0x9d,
-	0x2d0: 0x9d, 0x2d1: 0x9d, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9d, 0x2d5: 0x9d, 0x2d6: 0x9d, 0x2d7: 0x9d,
-	0x2d8: 0xe5, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe6, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xe7,
-	0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef,
-	0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7,
-	0x2f0: 0x9d, 0x2f1: 0x9d, 0x2f2: 0x9d, 0x2f3: 0x9d, 0x2f4: 0x9d, 0x2f5: 0x9d, 0x2f6: 0x9d, 0x2f7: 0x9d,
-	0x2f8: 0x9d, 0x2f9: 0x9d, 0x2fa: 0x9d, 0x2fb: 0x9d, 0x2fc: 0x9d, 0x2fd: 0x9d, 0x2fe: 0x9d, 0x2ff: 0x9d,
+	0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,
+	0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,
+	0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,
+	0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8,
+	0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0,
+	0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8,
+	0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,
+	0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,
 	// Block 0xc, offset 0x300
-	0x300: 0x9d, 0x301: 0x9d, 0x302: 0x9d, 0x303: 0x9d, 0x304: 0x9d, 0x305: 0x9d, 0x306: 0x9d, 0x307: 0x9d,
-	0x308: 0x9d, 0x309: 0x9d, 0x30a: 0x9d, 0x30b: 0x9d, 0x30c: 0x9d, 0x30d: 0x9d, 0x30e: 0x9d, 0x30f: 0x9d,
-	0x310: 0x9d, 0x311: 0x9d, 0x312: 0x9d, 0x313: 0x9d, 0x314: 0x9d, 0x315: 0x9d, 0x316: 0x9d, 0x317: 0x9d,
-	0x318: 0x9d, 0x319: 0x9d, 0x31a: 0x9d, 0x31b: 0x9d, 0x31c: 0x9d, 0x31d: 0x9d, 0x31e: 0xf8, 0x31f: 0xf9,
+	0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,
+	0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,
+	0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,
+	0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa,
 	// Block 0xd, offset 0x340
-	0x340: 0xb8, 0x341: 0xb8, 0x342: 0xb8, 0x343: 0xb8, 0x344: 0xb8, 0x345: 0xb8, 0x346: 0xb8, 0x347: 0xb8,
-	0x348: 0xb8, 0x349: 0xb8, 0x34a: 0xb8, 0x34b: 0xb8, 0x34c: 0xb8, 0x34d: 0xb8, 0x34e: 0xb8, 0x34f: 0xb8,
-	0x350: 0xb8, 0x351: 0xb8, 0x352: 0xb8, 0x353: 0xb8, 0x354: 0xb8, 0x355: 0xb8, 0x356: 0xb8, 0x357: 0xb8,
-	0x358: 0xb8, 0x359: 0xb8, 0x35a: 0xb8, 0x35b: 0xb8, 0x35c: 0xb8, 0x35d: 0xb8, 0x35e: 0xb8, 0x35f: 0xb8,
-	0x360: 0xb8, 0x361: 0xb8, 0x362: 0xb8, 0x363: 0xb8, 0x364: 0xb8, 0x365: 0xb8, 0x366: 0xb8, 0x367: 0xb8,
-	0x368: 0xb8, 0x369: 0xb8, 0x36a: 0xb8, 0x36b: 0xb8, 0x36c: 0xb8, 0x36d: 0xb8, 0x36e: 0xb8, 0x36f: 0xb8,
-	0x370: 0xb8, 0x371: 0xb8, 0x372: 0xb8, 0x373: 0xb8, 0x374: 0xb8, 0x375: 0xb8, 0x376: 0xb8, 0x377: 0xb8,
-	0x378: 0xb8, 0x379: 0xb8, 0x37a: 0xb8, 0x37b: 0xb8, 0x37c: 0xb8, 0x37d: 0xb8, 0x37e: 0xb8, 0x37f: 0xb8,
+	0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,
+	0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,
+	0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,
+	0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,
+	0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,
+	0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,
+	0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,
+	0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,
 	// Block 0xe, offset 0x380
-	0x380: 0xb8, 0x381: 0xb8, 0x382: 0xb8, 0x383: 0xb8, 0x384: 0xb8, 0x385: 0xb8, 0x386: 0xb8, 0x387: 0xb8,
-	0x388: 0xb8, 0x389: 0xb8, 0x38a: 0xb8, 0x38b: 0xb8, 0x38c: 0xb8, 0x38d: 0xb8, 0x38e: 0xb8, 0x38f: 0xb8,
-	0x390: 0xb8, 0x391: 0xb8, 0x392: 0xb8, 0x393: 0xb8, 0x394: 0xb8, 0x395: 0xb8, 0x396: 0xb8, 0x397: 0xb8,
-	0x398: 0xb8, 0x399: 0xb8, 0x39a: 0xb8, 0x39b: 0xb8, 0x39c: 0xb8, 0x39d: 0xb8, 0x39e: 0xb8, 0x39f: 0xb8,
-	0x3a0: 0xb8, 0x3a1: 0xb8, 0x3a2: 0xb8, 0x3a3: 0xb8, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd,
-	0x3a8: 0x45, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a,
-	0x3b0: 0x100, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x101, 0x3b7: 0x50,
-	0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58,
+	0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,
+	0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,
+	0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,
+	0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,
+	0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe,
+	0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,
+	0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52,
+	0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,
 	// Block 0xf, offset 0x3c0
-	0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9d, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107,
-	0x3c8: 0xb8, 0x3c9: 0xb8, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d,
-	0x3d0: 0x10e, 0x3d1: 0x9d, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xb8, 0x3d7: 0xb8,
-	0x3d8: 0x9d, 0x3d9: 0x9d, 0x3da: 0x9d, 0x3db: 0x9d, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xb8, 0x3df: 0xb8,
-	0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xb8, 0x3e6: 0x11a, 0x3e7: 0x11b,
-	0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x59, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5a, 0x3ef: 0xb8,
-	0x3f0: 0x9d, 0x3f1: 0x121, 0x3f2: 0x122, 0x3f3: 0x123, 0x3f4: 0xb8, 0x3f5: 0xb8, 0x3f6: 0xb8, 0x3f7: 0xb8,
-	0x3f8: 0xb8, 0x3f9: 0x124, 0x3fa: 0xb8, 0x3fb: 0xb8, 0x3fc: 0xb8, 0x3fd: 0xb8, 0x3fe: 0xb8, 0x3ff: 0xb8,
+	0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108,
+	0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e,
+	0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba,
+	0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba,
+	0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c,
+	0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba,
+	0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,
+	0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba,
 	// Block 0x10, offset 0x400
-	0x400: 0x125, 0x401: 0x126, 0x402: 0x127, 0x403: 0x128, 0x404: 0x129, 0x405: 0x12a, 0x406: 0x12b, 0x407: 0x12c,
-	0x408: 0x12d, 0x409: 0xb8, 0x40a: 0x12e, 0x40b: 0x12f, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xb8, 0x40f: 0xb8,
-	0x410: 0x130, 0x411: 0x131, 0x412: 0x132, 0x413: 0x133, 0x414: 0xb8, 0x415: 0xb8, 0x416: 0x134, 0x417: 0x135,
-	0x418: 0x136, 0x419: 0x137, 0x41a: 0x138, 0x41b: 0x139, 0x41c: 0x13a, 0x41d: 0xb8, 0x41e: 0xb8, 0x41f: 0xb8,
-	0x420: 0xb8, 0x421: 0xb8, 0x422: 0x13b, 0x423: 0x13c, 0x424: 0xb8, 0x425: 0xb8, 0x426: 0xb8, 0x427: 0xb8,
-	0x428: 0xb8, 0x429: 0xb8, 0x42a: 0xb8, 0x42b: 0x13d, 0x42c: 0xb8, 0x42d: 0xb8, 0x42e: 0xb8, 0x42f: 0xb8,
-	0x430: 0x13e, 0x431: 0x13f, 0x432: 0x140, 0x433: 0xb8, 0x434: 0xb8, 0x435: 0xb8, 0x436: 0xb8, 0x437: 0xb8,
-	0x438: 0xb8, 0x439: 0xb8, 0x43a: 0xb8, 0x43b: 0xb8, 0x43c: 0xb8, 0x43d: 0xb8, 0x43e: 0xb8, 0x43f: 0xb8,
+	0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e,
+	0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,
+	0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137,
+	0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,
+	0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba,
+	0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,
+	0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba,
+	0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba,
 	// Block 0x11, offset 0x440
-	0x440: 0x9d, 0x441: 0x9d, 0x442: 0x9d, 0x443: 0x9d, 0x444: 0x9d, 0x445: 0x9d, 0x446: 0x9d, 0x447: 0x9d,
-	0x448: 0x9d, 0x449: 0x9d, 0x44a: 0x9d, 0x44b: 0x9d, 0x44c: 0x9d, 0x44d: 0x9d, 0x44e: 0x141, 0x44f: 0xb8,
-	0x450: 0x9b, 0x451: 0x142, 0x452: 0x9d, 0x453: 0x9d, 0x454: 0x9d, 0x455: 0x143, 0x456: 0xb8, 0x457: 0xb8,
-	0x458: 0xb8, 0x459: 0xb8, 0x45a: 0xb8, 0x45b: 0xb8, 0x45c: 0xb8, 0x45d: 0xb8, 0x45e: 0xb8, 0x45f: 0xb8,
-	0x460: 0xb8, 0x461: 0xb8, 0x462: 0xb8, 0x463: 0xb8, 0x464: 0xb8, 0x465: 0xb8, 0x466: 0xb8, 0x467: 0xb8,
-	0x468: 0xb8, 0x469: 0xb8, 0x46a: 0xb8, 0x46b: 0xb8, 0x46c: 0xb8, 0x46d: 0xb8, 0x46e: 0xb8, 0x46f: 0xb8,
-	0x470: 0xb8, 0x471: 0xb8, 0x472: 0xb8, 0x473: 0xb8, 0x474: 0xb8, 0x475: 0xb8, 0x476: 0xb8, 0x477: 0xb8,
-	0x478: 0xb8, 0x479: 0xb8, 0x47a: 0xb8, 0x47b: 0xb8, 0x47c: 0xb8, 0x47d: 0xb8, 0x47e: 0xb8, 0x47f: 0xb8,
+	0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,
+	0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba,
+	0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba,
+	0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,
+	0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,
+	0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,
+	0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,
+	0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,
 	// Block 0x12, offset 0x480
-	0x480: 0x9d, 0x481: 0x9d, 0x482: 0x9d, 0x483: 0x9d, 0x484: 0x9d, 0x485: 0x9d, 0x486: 0x9d, 0x487: 0x9d,
-	0x488: 0x9d, 0x489: 0x9d, 0x48a: 0x9d, 0x48b: 0x9d, 0x48c: 0x9d, 0x48d: 0x9d, 0x48e: 0x9d, 0x48f: 0x9d,
-	0x490: 0x144, 0x491: 0xb8, 0x492: 0xb8, 0x493: 0xb8, 0x494: 0xb8, 0x495: 0xb8, 0x496: 0xb8, 0x497: 0xb8,
-	0x498: 0xb8, 0x499: 0xb8, 0x49a: 0xb8, 0x49b: 0xb8, 0x49c: 0xb8, 0x49d: 0xb8, 0x49e: 0xb8, 0x49f: 0xb8,
-	0x4a0: 0xb8, 0x4a1: 0xb8, 0x4a2: 0xb8, 0x4a3: 0xb8, 0x4a4: 0xb8, 0x4a5: 0xb8, 0x4a6: 0xb8, 0x4a7: 0xb8,
-	0x4a8: 0xb8, 0x4a9: 0xb8, 0x4aa: 0xb8, 0x4ab: 0xb8, 0x4ac: 0xb8, 0x4ad: 0xb8, 0x4ae: 0xb8, 0x4af: 0xb8,
-	0x4b0: 0xb8, 0x4b1: 0xb8, 0x4b2: 0xb8, 0x4b3: 0xb8, 0x4b4: 0xb8, 0x4b5: 0xb8, 0x4b6: 0xb8, 0x4b7: 0xb8,
-	0x4b8: 0xb8, 0x4b9: 0xb8, 0x4ba: 0xb8, 0x4bb: 0xb8, 0x4bc: 0xb8, 0x4bd: 0xb8, 0x4be: 0xb8, 0x4bf: 0xb8,
+	0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,
+	0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,
+	0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,
+	0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,
+	0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,
+	0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,
+	0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,
+	0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,
 	// Block 0x13, offset 0x4c0
-	0x4c0: 0xb8, 0x4c1: 0xb8, 0x4c2: 0xb8, 0x4c3: 0xb8, 0x4c4: 0xb8, 0x4c5: 0xb8, 0x4c6: 0xb8, 0x4c7: 0xb8,
-	0x4c8: 0xb8, 0x4c9: 0xb8, 0x4ca: 0xb8, 0x4cb: 0xb8, 0x4cc: 0xb8, 0x4cd: 0xb8, 0x4ce: 0xb8, 0x4cf: 0xb8,
-	0x4d0: 0x9d, 0x4d1: 0x9d, 0x4d2: 0x9d, 0x4d3: 0x9d, 0x4d4: 0x9d, 0x4d5: 0x9d, 0x4d6: 0x9d, 0x4d7: 0x9d,
-	0x4d8: 0x9d, 0x4d9: 0x145, 0x4da: 0xb8, 0x4db: 0xb8, 0x4dc: 0xb8, 0x4dd: 0xb8, 0x4de: 0xb8, 0x4df: 0xb8,
-	0x4e0: 0xb8, 0x4e1: 0xb8, 0x4e2: 0xb8, 0x4e3: 0xb8, 0x4e4: 0xb8, 0x4e5: 0xb8, 0x4e6: 0xb8, 0x4e7: 0xb8,
-	0x4e8: 0xb8, 0x4e9: 0xb8, 0x4ea: 0xb8, 0x4eb: 0xb8, 0x4ec: 0xb8, 0x4ed: 0xb8, 0x4ee: 0xb8, 0x4ef: 0xb8,
-	0x4f0: 0xb8, 0x4f1: 0xb8, 0x4f2: 0xb8, 0x4f3: 0xb8, 0x4f4: 0xb8, 0x4f5: 0xb8, 0x4f6: 0xb8, 0x4f7: 0xb8,
-	0x4f8: 0xb8, 0x4f9: 0xb8, 0x4fa: 0xb8, 0x4fb: 0xb8, 0x4fc: 0xb8, 0x4fd: 0xb8, 0x4fe: 0xb8, 0x4ff: 0xb8,
+	0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,
+	0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,
+	0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,
+	0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,
+	0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,
+	0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,
+	0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,
+	0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,
 	// Block 0x14, offset 0x500
-	0x500: 0xb8, 0x501: 0xb8, 0x502: 0xb8, 0x503: 0xb8, 0x504: 0xb8, 0x505: 0xb8, 0x506: 0xb8, 0x507: 0xb8,
-	0x508: 0xb8, 0x509: 0xb8, 0x50a: 0xb8, 0x50b: 0xb8, 0x50c: 0xb8, 0x50d: 0xb8, 0x50e: 0xb8, 0x50f: 0xb8,
-	0x510: 0xb8, 0x511: 0xb8, 0x512: 0xb8, 0x513: 0xb8, 0x514: 0xb8, 0x515: 0xb8, 0x516: 0xb8, 0x517: 0xb8,
-	0x518: 0xb8, 0x519: 0xb8, 0x51a: 0xb8, 0x51b: 0xb8, 0x51c: 0xb8, 0x51d: 0xb8, 0x51e: 0xb8, 0x51f: 0xb8,
-	0x520: 0x9d, 0x521: 0x9d, 0x522: 0x9d, 0x523: 0x9d, 0x524: 0x9d, 0x525: 0x9d, 0x526: 0x9d, 0x527: 0x9d,
-	0x528: 0x13d, 0x529: 0x146, 0x52a: 0xb8, 0x52b: 0x147, 0x52c: 0x148, 0x52d: 0x149, 0x52e: 0x14a, 0x52f: 0xb8,
-	0x530: 0xb8, 0x531: 0xb8, 0x532: 0xb8, 0x533: 0xb8, 0x534: 0xb8, 0x535: 0xb8, 0x536: 0xb8, 0x537: 0xb8,
-	0x538: 0xb8, 0x539: 0xb8, 0x53a: 0xb8, 0x53b: 0xb8, 0x53c: 0x9d, 0x53d: 0x14b, 0x53e: 0x14c, 0x53f: 0x14d,
+	0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,
+	0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,
+	0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,
+	0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,
+	0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,
+	0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba,
+	0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,
+	0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154,
 	// Block 0x15, offset 0x540
-	0x540: 0x9d, 0x541: 0x9d, 0x542: 0x9d, 0x543: 0x9d, 0x544: 0x9d, 0x545: 0x9d, 0x546: 0x9d, 0x547: 0x9d,
-	0x548: 0x9d, 0x549: 0x9d, 0x54a: 0x9d, 0x54b: 0x9d, 0x54c: 0x9d, 0x54d: 0x9d, 0x54e: 0x9d, 0x54f: 0x9d,
-	0x550: 0x9d, 0x551: 0x9d, 0x552: 0x9d, 0x553: 0x9d, 0x554: 0x9d, 0x555: 0x9d, 0x556: 0x9d, 0x557: 0x9d,
-	0x558: 0x9d, 0x559: 0x9d, 0x55a: 0x9d, 0x55b: 0x9d, 0x55c: 0x9d, 0x55d: 0x9d, 0x55e: 0x9d, 0x55f: 0x14e,
-	0x560: 0x9d, 0x561: 0x9d, 0x562: 0x9d, 0x563: 0x9d, 0x564: 0x9d, 0x565: 0x9d, 0x566: 0x9d, 0x567: 0x9d,
-	0x568: 0x9d, 0x569: 0x9d, 0x56a: 0x9d, 0x56b: 0x14f, 0x56c: 0xb8, 0x56d: 0xb8, 0x56e: 0xb8, 0x56f: 0xb8,
-	0x570: 0xb8, 0x571: 0xb8, 0x572: 0xb8, 0x573: 0xb8, 0x574: 0xb8, 0x575: 0xb8, 0x576: 0xb8, 0x577: 0xb8,
-	0x578: 0xb8, 0x579: 0xb8, 0x57a: 0xb8, 0x57b: 0xb8, 0x57c: 0xb8, 0x57d: 0xb8, 0x57e: 0xb8, 0x57f: 0xb8,
+	0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,
+	0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,
+	0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,
+	0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155,
+	0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,
+	0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,
+	0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,
+	0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,
 	// Block 0x16, offset 0x580
-	0x580: 0x150, 0x581: 0xb8, 0x582: 0xb8, 0x583: 0xb8, 0x584: 0xb8, 0x585: 0xb8, 0x586: 0xb8, 0x587: 0xb8,
-	0x588: 0xb8, 0x589: 0xb8, 0x58a: 0xb8, 0x58b: 0xb8, 0x58c: 0xb8, 0x58d: 0xb8, 0x58e: 0xb8, 0x58f: 0xb8,
-	0x590: 0xb8, 0x591: 0xb8, 0x592: 0xb8, 0x593: 0xb8, 0x594: 0xb8, 0x595: 0xb8, 0x596: 0xb8, 0x597: 0xb8,
-	0x598: 0xb8, 0x599: 0xb8, 0x59a: 0xb8, 0x59b: 0xb8, 0x59c: 0xb8, 0x59d: 0xb8, 0x59e: 0xb8, 0x59f: 0xb8,
-	0x5a0: 0xb8, 0x5a1: 0xb8, 0x5a2: 0xb8, 0x5a3: 0xb8, 0x5a4: 0xb8, 0x5a5: 0xb8, 0x5a6: 0xb8, 0x5a7: 0xb8,
-	0x5a8: 0xb8, 0x5a9: 0xb8, 0x5aa: 0xb8, 0x5ab: 0xb8, 0x5ac: 0xb8, 0x5ad: 0xb8, 0x5ae: 0xb8, 0x5af: 0xb8,
-	0x5b0: 0x9d, 0x5b1: 0x151, 0x5b2: 0x152, 0x5b3: 0xb8, 0x5b4: 0xb8, 0x5b5: 0xb8, 0x5b6: 0xb8, 0x5b7: 0xb8,
-	0x5b8: 0xb8, 0x5b9: 0xb8, 0x5ba: 0xb8, 0x5bb: 0xb8, 0x5bc: 0xb8, 0x5bd: 0xb8, 0x5be: 0xb8, 0x5bf: 0xb8,
+	0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f,
+	0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,
+	0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,
+	0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,
+	0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,
+	0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,
+	0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,
+	0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,
 	// Block 0x17, offset 0x5c0
-	0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x153, 0x5c4: 0x154, 0x5c5: 0x155, 0x5c6: 0x156, 0x5c7: 0x157,
-	0x5c8: 0x9b, 0x5c9: 0x158, 0x5ca: 0xb8, 0x5cb: 0xb8, 0x5cc: 0x9b, 0x5cd: 0x159, 0x5ce: 0xb8, 0x5cf: 0xb8,
-	0x5d0: 0x5d, 0x5d1: 0x5e, 0x5d2: 0x5f, 0x5d3: 0x60, 0x5d4: 0x61, 0x5d5: 0x62, 0x5d6: 0x63, 0x5d7: 0x64,
-	0x5d8: 0x65, 0x5d9: 0x66, 0x5da: 0x67, 0x5db: 0x68, 0x5dc: 0x69, 0x5dd: 0x6a, 0x5de: 0x6b, 0x5df: 0x6c,
+	0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160,
+	0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba,
+	0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,
+	0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,
 	0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,
-	0x5e8: 0x15a, 0x5e9: 0x15b, 0x5ea: 0x15c, 0x5eb: 0xb8, 0x5ec: 0xb8, 0x5ed: 0xb8, 0x5ee: 0xb8, 0x5ef: 0xb8,
-	0x5f0: 0xb8, 0x5f1: 0xb8, 0x5f2: 0xb8, 0x5f3: 0xb8, 0x5f4: 0xb8, 0x5f5: 0xb8, 0x5f6: 0xb8, 0x5f7: 0xb8,
-	0x5f8: 0xb8, 0x5f9: 0xb8, 0x5fa: 0xb8, 0x5fb: 0xb8, 0x5fc: 0xb8, 0x5fd: 0xb8, 0x5fe: 0xb8, 0x5ff: 0xb8,
+	0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,
+	0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,
+	0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,
 	// Block 0x18, offset 0x600
-	0x600: 0x15d, 0x601: 0xb8, 0x602: 0xb8, 0x603: 0xb8, 0x604: 0xb8, 0x605: 0xb8, 0x606: 0xb8, 0x607: 0xb8,
-	0x608: 0xb8, 0x609: 0xb8, 0x60a: 0xb8, 0x60b: 0xb8, 0x60c: 0xb8, 0x60d: 0xb8, 0x60e: 0xb8, 0x60f: 0xb8,
-	0x610: 0xb8, 0x611: 0xb8, 0x612: 0xb8, 0x613: 0xb8, 0x614: 0xb8, 0x615: 0xb8, 0x616: 0xb8, 0x617: 0xb8,
-	0x618: 0xb8, 0x619: 0xb8, 0x61a: 0xb8, 0x61b: 0xb8, 0x61c: 0xb8, 0x61d: 0xb8, 0x61e: 0xb8, 0x61f: 0xb8,
-	0x620: 0x9d, 0x621: 0x9d, 0x622: 0x9d, 0x623: 0x15e, 0x624: 0x6d, 0x625: 0x15f, 0x626: 0xb8, 0x627: 0xb8,
-	0x628: 0xb8, 0x629: 0xb8, 0x62a: 0xb8, 0x62b: 0xb8, 0x62c: 0xb8, 0x62d: 0xb8, 0x62e: 0xb8, 0x62f: 0xb8,
-	0x630: 0xb8, 0x631: 0xb8, 0x632: 0xb8, 0x633: 0xb8, 0x634: 0xb8, 0x635: 0xb8, 0x636: 0xb8, 0x637: 0xb8,
-	0x638: 0x6e, 0x639: 0x6f, 0x63a: 0x70, 0x63b: 0x160, 0x63c: 0xb8, 0x63d: 0xb8, 0x63e: 0xb8, 0x63f: 0xb8,
+	0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba,
+	0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,
+	0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,
+	0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,
+	0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba,
+	0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,
+	0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,
+	0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,
 	// Block 0x19, offset 0x640
-	0x640: 0x161, 0x641: 0x9b, 0x642: 0x162, 0x643: 0x163, 0x644: 0x71, 0x645: 0x72, 0x646: 0x164, 0x647: 0x165,
-	0x648: 0x73, 0x649: 0x166, 0x64a: 0xb8, 0x64b: 0xb8, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,
+	0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e,
+	0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,
 	0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,
-	0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x167, 0x65c: 0x9b, 0x65d: 0x168, 0x65e: 0x9b, 0x65f: 0x169,
-	0x660: 0x16a, 0x661: 0x16b, 0x662: 0x16c, 0x663: 0xb8, 0x664: 0x16d, 0x665: 0x16e, 0x666: 0x16f, 0x667: 0x170,
-	0x668: 0xb8, 0x669: 0xb8, 0x66a: 0xb8, 0x66b: 0xb8, 0x66c: 0xb8, 0x66d: 0xb8, 0x66e: 0xb8, 0x66f: 0xb8,
-	0x670: 0xb8, 0x671: 0xb8, 0x672: 0xb8, 0x673: 0xb8, 0x674: 0xb8, 0x675: 0xb8, 0x676: 0xb8, 0x677: 0xb8,
-	0x678: 0xb8, 0x679: 0xb8, 0x67a: 0xb8, 0x67b: 0xb8, 0x67c: 0xb8, 0x67d: 0xb8, 0x67e: 0xb8, 0x67f: 0xb8,
+	0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172,
+	0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179,
+	0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,
+	0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,
+	0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,
 	// Block 0x1a, offset 0x680
-	0x680: 0x9d, 0x681: 0x9d, 0x682: 0x9d, 0x683: 0x9d, 0x684: 0x9d, 0x685: 0x9d, 0x686: 0x9d, 0x687: 0x9d,
-	0x688: 0x9d, 0x689: 0x9d, 0x68a: 0x9d, 0x68b: 0x9d, 0x68c: 0x9d, 0x68d: 0x9d, 0x68e: 0x9d, 0x68f: 0x9d,
-	0x690: 0x9d, 0x691: 0x9d, 0x692: 0x9d, 0x693: 0x9d, 0x694: 0x9d, 0x695: 0x9d, 0x696: 0x9d, 0x697: 0x9d,
-	0x698: 0x9d, 0x699: 0x9d, 0x69a: 0x9d, 0x69b: 0x171, 0x69c: 0x9d, 0x69d: 0x9d, 0x69e: 0x9d, 0x69f: 0x9d,
-	0x6a0: 0x9d, 0x6a1: 0x9d, 0x6a2: 0x9d, 0x6a3: 0x9d, 0x6a4: 0x9d, 0x6a5: 0x9d, 0x6a6: 0x9d, 0x6a7: 0x9d,
-	0x6a8: 0x9d, 0x6a9: 0x9d, 0x6aa: 0x9d, 0x6ab: 0x9d, 0x6ac: 0x9d, 0x6ad: 0x9d, 0x6ae: 0x9d, 0x6af: 0x9d,
-	0x6b0: 0x9d, 0x6b1: 0x9d, 0x6b2: 0x9d, 0x6b3: 0x9d, 0x6b4: 0x9d, 0x6b5: 0x9d, 0x6b6: 0x9d, 0x6b7: 0x9d,
-	0x6b8: 0x9d, 0x6b9: 0x9d, 0x6ba: 0x9d, 0x6bb: 0x9d, 0x6bc: 0x9d, 0x6bd: 0x9d, 0x6be: 0x9d, 0x6bf: 0x9d,
+	0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,
+	0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,
+	0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,
+	0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,
+	0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,
+	0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,
+	0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,
+	0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,
 	// Block 0x1b, offset 0x6c0
-	0x6c0: 0x9d, 0x6c1: 0x9d, 0x6c2: 0x9d, 0x6c3: 0x9d, 0x6c4: 0x9d, 0x6c5: 0x9d, 0x6c6: 0x9d, 0x6c7: 0x9d,
-	0x6c8: 0x9d, 0x6c9: 0x9d, 0x6ca: 0x9d, 0x6cb: 0x9d, 0x6cc: 0x9d, 0x6cd: 0x9d, 0x6ce: 0x9d, 0x6cf: 0x9d,
-	0x6d0: 0x9d, 0x6d1: 0x9d, 0x6d2: 0x9d, 0x6d3: 0x9d, 0x6d4: 0x9d, 0x6d5: 0x9d, 0x6d6: 0x9d, 0x6d7: 0x9d,
-	0x6d8: 0x9d, 0x6d9: 0x9d, 0x6da: 0x9d, 0x6db: 0x9d, 0x6dc: 0x172, 0x6dd: 0x9d, 0x6de: 0x9d, 0x6df: 0x9d,
-	0x6e0: 0x173, 0x6e1: 0x9d, 0x6e2: 0x9d, 0x6e3: 0x9d, 0x6e4: 0x9d, 0x6e5: 0x9d, 0x6e6: 0x9d, 0x6e7: 0x9d,
-	0x6e8: 0x9d, 0x6e9: 0x9d, 0x6ea: 0x9d, 0x6eb: 0x9d, 0x6ec: 0x9d, 0x6ed: 0x9d, 0x6ee: 0x9d, 0x6ef: 0x9d,
-	0x6f0: 0x9d, 0x6f1: 0x9d, 0x6f2: 0x9d, 0x6f3: 0x9d, 0x6f4: 0x9d, 0x6f5: 0x9d, 0x6f6: 0x9d, 0x6f7: 0x9d,
-	0x6f8: 0x9d, 0x6f9: 0x9d, 0x6fa: 0x9d, 0x6fb: 0x9d, 0x6fc: 0x9d, 0x6fd: 0x9d, 0x6fe: 0x9d, 0x6ff: 0x9d,
+	0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,
+	0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,
+	0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,
+	0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,
+	0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,
+	0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,
+	0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,
+	0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,
 	// Block 0x1c, offset 0x700
-	0x700: 0x9d, 0x701: 0x9d, 0x702: 0x9d, 0x703: 0x9d, 0x704: 0x9d, 0x705: 0x9d, 0x706: 0x9d, 0x707: 0x9d,
-	0x708: 0x9d, 0x709: 0x9d, 0x70a: 0x9d, 0x70b: 0x9d, 0x70c: 0x9d, 0x70d: 0x9d, 0x70e: 0x9d, 0x70f: 0x9d,
-	0x710: 0x9d, 0x711: 0x9d, 0x712: 0x9d, 0x713: 0x9d, 0x714: 0x9d, 0x715: 0x9d, 0x716: 0x9d, 0x717: 0x9d,
-	0x718: 0x9d, 0x719: 0x9d, 0x71a: 0x9d, 0x71b: 0x9d, 0x71c: 0x9d, 0x71d: 0x9d, 0x71e: 0x9d, 0x71f: 0x9d,
-	0x720: 0x9d, 0x721: 0x9d, 0x722: 0x9d, 0x723: 0x9d, 0x724: 0x9d, 0x725: 0x9d, 0x726: 0x9d, 0x727: 0x9d,
-	0x728: 0x9d, 0x729: 0x9d, 0x72a: 0x9d, 0x72b: 0x9d, 0x72c: 0x9d, 0x72d: 0x9d, 0x72e: 0x9d, 0x72f: 0x9d,
-	0x730: 0x9d, 0x731: 0x9d, 0x732: 0x9d, 0x733: 0x9d, 0x734: 0x9d, 0x735: 0x9d, 0x736: 0x9d, 0x737: 0x9d,
-	0x738: 0x9d, 0x739: 0x9d, 0x73a: 0x174, 0x73b: 0xb8, 0x73c: 0xb8, 0x73d: 0xb8, 0x73e: 0xb8, 0x73f: 0xb8,
+	0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,
+	0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,
+	0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,
+	0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,
+	0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,
+	0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,
+	0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,
+	0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,
 	// Block 0x1d, offset 0x740
-	0x740: 0xb8, 0x741: 0xb8, 0x742: 0xb8, 0x743: 0xb8, 0x744: 0xb8, 0x745: 0xb8, 0x746: 0xb8, 0x747: 0xb8,
-	0x748: 0xb8, 0x749: 0xb8, 0x74a: 0xb8, 0x74b: 0xb8, 0x74c: 0xb8, 0x74d: 0xb8, 0x74e: 0xb8, 0x74f: 0xb8,
-	0x750: 0xb8, 0x751: 0xb8, 0x752: 0xb8, 0x753: 0xb8, 0x754: 0xb8, 0x755: 0xb8, 0x756: 0xb8, 0x757: 0xb8,
-	0x758: 0xb8, 0x759: 0xb8, 0x75a: 0xb8, 0x75b: 0xb8, 0x75c: 0xb8, 0x75d: 0xb8, 0x75e: 0xb8, 0x75f: 0xb8,
-	0x760: 0x74, 0x761: 0x75, 0x762: 0x76, 0x763: 0x175, 0x764: 0x77, 0x765: 0x78, 0x766: 0x176, 0x767: 0x79,
-	0x768: 0x7a, 0x769: 0xb8, 0x76a: 0xb8, 0x76b: 0xb8, 0x76c: 0xb8, 0x76d: 0xb8, 0x76e: 0xb8, 0x76f: 0xb8,
-	0x770: 0xb8, 0x771: 0xb8, 0x772: 0xb8, 0x773: 0xb8, 0x774: 0xb8, 0x775: 0xb8, 0x776: 0xb8, 0x777: 0xb8,
-	0x778: 0xb8, 0x779: 0xb8, 0x77a: 0xb8, 0x77b: 0xb8, 0x77c: 0xb8, 0x77d: 0xb8, 0x77e: 0xb8, 0x77f: 0xb8,
+	0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,
+	0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,
+	0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,
+	0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,
+	0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,
+	0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e,
+	0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,
+	0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,
 	// Block 0x1e, offset 0x780
-	0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07,
-	0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17,
-	0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07,
-	0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b,
-	0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b,
-	0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b,
+	0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,
+	0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,
+	0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,
+	0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,
+	0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b,
+	0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,
+	0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,
+	0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,
 	// Block 0x1f, offset 0x7c0
-	0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b,
-	0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b,
-	0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b,
-	0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b,
-	0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b,
-	0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b,
+	0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,
+	0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,
+	0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,
+	0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,
 	0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,
 	0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,
 	// Block 0x20, offset 0x800
-	0x800: 0x177, 0x801: 0x178, 0x802: 0xb8, 0x803: 0xb8, 0x804: 0x179, 0x805: 0x179, 0x806: 0x179, 0x807: 0x17a,
-	0x808: 0xb8, 0x809: 0xb8, 0x80a: 0xb8, 0x80b: 0xb8, 0x80c: 0xb8, 0x80d: 0xb8, 0x80e: 0xb8, 0x80f: 0xb8,
-	0x810: 0xb8, 0x811: 0xb8, 0x812: 0xb8, 0x813: 0xb8, 0x814: 0xb8, 0x815: 0xb8, 0x816: 0xb8, 0x817: 0xb8,
-	0x818: 0xb8, 0x819: 0xb8, 0x81a: 0xb8, 0x81b: 0xb8, 0x81c: 0xb8, 0x81d: 0xb8, 0x81e: 0xb8, 0x81f: 0xb8,
-	0x820: 0xb8, 0x821: 0xb8, 0x822: 0xb8, 0x823: 0xb8, 0x824: 0xb8, 0x825: 0xb8, 0x826: 0xb8, 0x827: 0xb8,
-	0x828: 0xb8, 0x829: 0xb8, 0x82a: 0xb8, 0x82b: 0xb8, 0x82c: 0xb8, 0x82d: 0xb8, 0x82e: 0xb8, 0x82f: 0xb8,
-	0x830: 0xb8, 0x831: 0xb8, 0x832: 0xb8, 0x833: 0xb8, 0x834: 0xb8, 0x835: 0xb8, 0x836: 0xb8, 0x837: 0xb8,
-	0x838: 0xb8, 0x839: 0xb8, 0x83a: 0xb8, 0x83b: 0xb8, 0x83c: 0xb8, 0x83d: 0xb8, 0x83e: 0xb8, 0x83f: 0xb8,
+	0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,
+	0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,
+	0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,
+	0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,
+	0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,
+	0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,
+	0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,
+	0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,
 	// Block 0x21, offset 0x840
-	0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,
-	0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,
-	0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,
-	0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,
-	0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,
-	0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,
-	0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,
-	0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,
+	0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184,
+	0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,
+	0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,
+	0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,
+	0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,
+	0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,
+	0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,
+	0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,
 	// Block 0x22, offset 0x880
 	0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,
 	0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,
+	0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,
+	0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,
+	0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,
+	0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,
+	0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,
+	0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,
+	// Block 0x23, offset 0x8c0
+	0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,
+	0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,
 }
 
-// idnaSparseOffset: 256 entries, 512 bytes
-var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x5c, 0x60, 0x6f, 0x74, 0x7b, 0x87, 0x95, 0xa3, 0xa8, 0xb1, 0xc1, 0xcf, 0xdc, 0xe8, 0xf9, 0x103, 0x10a, 0x117, 0x128, 0x12f, 0x13a, 0x149, 0x157, 0x161, 0x163, 0x167, 0x169, 0x175, 0x180, 0x188, 0x18e, 0x194, 0x199, 0x19e, 0x1a1, 0x1a5, 0x1ab, 0x1b0, 0x1bc, 0x1c6, 0x1cc, 0x1dd, 0x1e7, 0x1ea, 0x1f2, 0x1f5, 0x202, 0x20a, 0x20e, 0x215, 0x21d, 0x22d, 0x239, 0x23b, 0x245, 0x251, 0x25d, 0x269, 0x271, 0x276, 0x280, 0x291, 0x295, 0x2a0, 0x2a4, 0x2ad, 0x2b5, 0x2bb, 0x2c0, 0x2c3, 0x2c6, 0x2ca, 0x2d0, 0x2d4, 0x2d8, 0x2de, 0x2e5, 0x2eb, 0x2f3, 0x2fa, 0x305, 0x30f, 0x313, 0x316, 0x31c, 0x320, 0x322, 0x325, 0x327, 0x32a, 0x334, 0x337, 0x346, 0x34a, 0x34f, 0x352, 0x356, 0x35b, 0x360, 0x366, 0x36c, 0x37b, 0x381, 0x385, 0x394, 0x399, 0x3a1, 0x3ab, 0x3b6, 0x3be, 0x3cf, 0x3d8, 0x3e8, 0x3f5, 0x3ff, 0x404, 0x411, 0x415, 0x41a, 0x41c, 0x420, 0x422, 0x426, 0x42f, 0x435, 0x439, 0x449, 0x453, 0x458, 0x45b, 0x461, 0x468, 0x46d, 0x471, 0x477, 0x47c, 0x485, 0x48a, 0x490, 0x497, 0x49e, 0x4a5, 0x4a9, 0x4ae, 0x4b1, 0x4b6, 0x4c2, 0x4c8, 0x4cd, 0x4d4, 0x4dc, 0x4e1, 0x4e5, 0x4f5, 0x4fc, 0x500, 0x504, 0x50b, 0x50e, 0x511, 0x515, 0x519, 0x51f, 0x528, 0x534, 0x53b, 0x544, 0x54c, 0x553, 0x561, 0x56e, 0x57b, 0x584, 0x588, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5e5, 0x5ea, 0x5ed, 0x5f7, 0x600, 0x60c, 0x60f, 0x614, 0x617, 0x61a, 0x61d, 0x624, 0x62b, 0x62f, 0x63a, 0x63d, 0x643, 0x648, 0x64c, 0x64f, 0x652, 0x655, 0x65a, 0x664, 0x667, 0x66b, 0x67a, 0x686, 0x68a, 0x68f, 0x694, 0x698, 0x69d, 0x6a6, 0x6b1, 0x6b7, 0x6bf, 0x6c3, 0x6c7, 0x6cd, 0x6d3, 0x6d8, 0x6db, 0x6e9, 0x6f0, 0x6f3, 0x6f6, 0x6fa, 0x700, 0x705, 0x70f, 0x714, 0x717, 0x71a, 0x71d, 0x720, 0x724, 0x727, 0x737, 0x748, 0x74d, 0x74f, 0x751}
+// idnaSparseOffset: 264 entries, 528 bytes
+var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778}
 
-// idnaSparseValues: 1876 entries, 7504 bytes
-var idnaSparseValues = [1876]valueRange{
+// idnaSparseValues: 1915 entries, 7660 bytes
+var idnaSparseValues = [1915]valueRange{
 	// Block 0x0, offset 0x0
 	{value: 0x0000, lo: 0x07},
 	{value: 0xe105, lo: 0x80, hi: 0x96},
@@ -2384,7 +2417,7 @@
 	{value: 0x0008, lo: 0xb9, hi: 0xbf},
 	// Block 0x3, offset 0x25
 	{value: 0x0000, lo: 0x01},
-	{value: 0x1308, lo: 0x80, hi: 0xbf},
+	{value: 0x3308, lo: 0x80, hi: 0xbf},
 	// Block 0x4, offset 0x27
 	{value: 0x0000, lo: 0x04},
 	{value: 0x03f5, lo: 0x80, hi: 0x8f},
@@ -2409,155 +2442,123 @@
 	{value: 0x0040, lo: 0x8b, hi: 0x8c},
 	{value: 0x0018, lo: 0x8d, hi: 0x8f},
 	{value: 0x0040, lo: 0x90, hi: 0x90},
-	{value: 0x1308, lo: 0x91, hi: 0xbd},
-	{value: 0x0018, lo: 0xbe, hi: 0xbe},
-	{value: 0x1308, lo: 0xbf, hi: 0xbf},
+	{value: 0x3308, lo: 0x91, hi: 0xbd},
+	{value: 0x0818, lo: 0xbe, hi: 0xbe},
+	{value: 0x3308, lo: 0xbf, hi: 0xbf},
 	// Block 0x7, offset 0x3f
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x0018, lo: 0x80, hi: 0x80},
-	{value: 0x1308, lo: 0x81, hi: 0x82},
-	{value: 0x0018, lo: 0x83, hi: 0x83},
-	{value: 0x1308, lo: 0x84, hi: 0x85},
-	{value: 0x0018, lo: 0x86, hi: 0x86},
-	{value: 0x1308, lo: 0x87, hi: 0x87},
+	{value: 0x0818, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x81, hi: 0x82},
+	{value: 0x0818, lo: 0x83, hi: 0x83},
+	{value: 0x3308, lo: 0x84, hi: 0x85},
+	{value: 0x0818, lo: 0x86, hi: 0x86},
+	{value: 0x3308, lo: 0x87, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
-	{value: 0x0008, lo: 0x90, hi: 0xaa},
+	{value: 0x0808, lo: 0x90, hi: 0xaa},
 	{value: 0x0040, lo: 0xab, hi: 0xaf},
-	{value: 0x0008, lo: 0xb0, hi: 0xb4},
+	{value: 0x0808, lo: 0xb0, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
 	// Block 0x8, offset 0x4b
-	{value: 0x0000, lo: 0x10},
-	{value: 0x0018, lo: 0x80, hi: 0x80},
-	{value: 0x0208, lo: 0x81, hi: 0x87},
-	{value: 0x0408, lo: 0x88, hi: 0x88},
-	{value: 0x0208, lo: 0x89, hi: 0x8a},
-	{value: 0x1308, lo: 0x8b, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xa9},
-	{value: 0x0018, lo: 0xaa, hi: 0xad},
-	{value: 0x0208, lo: 0xae, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb0},
-	{value: 0x0408, lo: 0xb1, hi: 0xb3},
-	{value: 0x0008, lo: 0xb4, hi: 0xb4},
-	{value: 0x0429, lo: 0xb5, hi: 0xb5},
-	{value: 0x0451, lo: 0xb6, hi: 0xb6},
-	{value: 0x0479, lo: 0xb7, hi: 0xb7},
-	{value: 0x04a1, lo: 0xb8, hi: 0xb8},
-	{value: 0x0208, lo: 0xb9, hi: 0xbf},
-	// Block 0x9, offset 0x5c
 	{value: 0x0000, lo: 0x03},
-	{value: 0x0208, lo: 0x80, hi: 0x87},
-	{value: 0x0408, lo: 0x88, hi: 0x99},
-	{value: 0x0208, lo: 0x9a, hi: 0xbf},
-	// Block 0xa, offset 0x60
+	{value: 0x0a08, lo: 0x80, hi: 0x87},
+	{value: 0x0c08, lo: 0x88, hi: 0x99},
+	{value: 0x0a08, lo: 0x9a, hi: 0xbf},
+	// Block 0x9, offset 0x4f
 	{value: 0x0000, lo: 0x0e},
-	{value: 0x1308, lo: 0x80, hi: 0x8a},
+	{value: 0x3308, lo: 0x80, hi: 0x8a},
 	{value: 0x0040, lo: 0x8b, hi: 0x8c},
-	{value: 0x0408, lo: 0x8d, hi: 0x8d},
-	{value: 0x0208, lo: 0x8e, hi: 0x98},
-	{value: 0x0408, lo: 0x99, hi: 0x9b},
-	{value: 0x0208, lo: 0x9c, hi: 0xaa},
-	{value: 0x0408, lo: 0xab, hi: 0xac},
-	{value: 0x0208, lo: 0xad, hi: 0xb0},
-	{value: 0x0408, lo: 0xb1, hi: 0xb1},
-	{value: 0x0208, lo: 0xb2, hi: 0xb2},
-	{value: 0x0408, lo: 0xb3, hi: 0xb4},
-	{value: 0x0208, lo: 0xb5, hi: 0xb7},
-	{value: 0x0408, lo: 0xb8, hi: 0xb9},
-	{value: 0x0208, lo: 0xba, hi: 0xbf},
-	// Block 0xb, offset 0x6f
+	{value: 0x0c08, lo: 0x8d, hi: 0x8d},
+	{value: 0x0a08, lo: 0x8e, hi: 0x98},
+	{value: 0x0c08, lo: 0x99, hi: 0x9b},
+	{value: 0x0a08, lo: 0x9c, hi: 0xaa},
+	{value: 0x0c08, lo: 0xab, hi: 0xac},
+	{value: 0x0a08, lo: 0xad, hi: 0xb0},
+	{value: 0x0c08, lo: 0xb1, hi: 0xb1},
+	{value: 0x0a08, lo: 0xb2, hi: 0xb2},
+	{value: 0x0c08, lo: 0xb3, hi: 0xb4},
+	{value: 0x0a08, lo: 0xb5, hi: 0xb7},
+	{value: 0x0c08, lo: 0xb8, hi: 0xb9},
+	{value: 0x0a08, lo: 0xba, hi: 0xbf},
+	// Block 0xa, offset 0x5e
 	{value: 0x0000, lo: 0x04},
-	{value: 0x0008, lo: 0x80, hi: 0xa5},
-	{value: 0x1308, lo: 0xa6, hi: 0xb0},
-	{value: 0x0008, lo: 0xb1, hi: 0xb1},
+	{value: 0x0808, lo: 0x80, hi: 0xa5},
+	{value: 0x3308, lo: 0xa6, hi: 0xb0},
+	{value: 0x0808, lo: 0xb1, hi: 0xb1},
 	{value: 0x0040, lo: 0xb2, hi: 0xbf},
-	// Block 0xc, offset 0x74
-	{value: 0x0000, lo: 0x06},
-	{value: 0x0008, lo: 0x80, hi: 0x89},
-	{value: 0x0208, lo: 0x8a, hi: 0xaa},
-	{value: 0x1308, lo: 0xab, hi: 0xb3},
-	{value: 0x0008, lo: 0xb4, hi: 0xb5},
-	{value: 0x0018, lo: 0xb6, hi: 0xba},
+	// Block 0xb, offset 0x63
+	{value: 0x0000, lo: 0x07},
+	{value: 0x0808, lo: 0x80, hi: 0x89},
+	{value: 0x0a08, lo: 0x8a, hi: 0xaa},
+	{value: 0x3308, lo: 0xab, hi: 0xb3},
+	{value: 0x0808, lo: 0xb4, hi: 0xb5},
+	{value: 0x0018, lo: 0xb6, hi: 0xb9},
+	{value: 0x0818, lo: 0xba, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbf},
-	// Block 0xd, offset 0x7b
+	// Block 0xc, offset 0x6b
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x0008, lo: 0x80, hi: 0x95},
-	{value: 0x1308, lo: 0x96, hi: 0x99},
-	{value: 0x0008, lo: 0x9a, hi: 0x9a},
-	{value: 0x1308, lo: 0x9b, hi: 0xa3},
-	{value: 0x0008, lo: 0xa4, hi: 0xa4},
-	{value: 0x1308, lo: 0xa5, hi: 0xa7},
-	{value: 0x0008, lo: 0xa8, hi: 0xa8},
-	{value: 0x1308, lo: 0xa9, hi: 0xad},
+	{value: 0x0808, lo: 0x80, hi: 0x95},
+	{value: 0x3308, lo: 0x96, hi: 0x99},
+	{value: 0x0808, lo: 0x9a, hi: 0x9a},
+	{value: 0x3308, lo: 0x9b, hi: 0xa3},
+	{value: 0x0808, lo: 0xa4, hi: 0xa4},
+	{value: 0x3308, lo: 0xa5, hi: 0xa7},
+	{value: 0x0808, lo: 0xa8, hi: 0xa8},
+	{value: 0x3308, lo: 0xa9, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
-	{value: 0x0018, lo: 0xb0, hi: 0xbe},
+	{value: 0x0818, lo: 0xb0, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xe, offset 0x87
-	{value: 0x0000, lo: 0x0d},
-	{value: 0x0408, lo: 0x80, hi: 0x80},
-	{value: 0x0208, lo: 0x81, hi: 0x85},
-	{value: 0x0408, lo: 0x86, hi: 0x87},
-	{value: 0x0208, lo: 0x88, hi: 0x88},
-	{value: 0x0408, lo: 0x89, hi: 0x89},
-	{value: 0x0208, lo: 0x8a, hi: 0x93},
-	{value: 0x0408, lo: 0x94, hi: 0x94},
-	{value: 0x0208, lo: 0x95, hi: 0x95},
-	{value: 0x0008, lo: 0x96, hi: 0x98},
-	{value: 0x1308, lo: 0x99, hi: 0x9b},
-	{value: 0x0040, lo: 0x9c, hi: 0x9d},
-	{value: 0x0018, lo: 0x9e, hi: 0x9e},
-	{value: 0x0040, lo: 0x9f, hi: 0xbf},
-	// Block 0xf, offset 0x95
+	// Block 0xd, offset 0x77
 	{value: 0x0000, lo: 0x0d},
 	{value: 0x0040, lo: 0x80, hi: 0x9f},
-	{value: 0x0208, lo: 0xa0, hi: 0xa9},
-	{value: 0x0408, lo: 0xaa, hi: 0xac},
-	{value: 0x0008, lo: 0xad, hi: 0xad},
-	{value: 0x0408, lo: 0xae, hi: 0xae},
-	{value: 0x0208, lo: 0xaf, hi: 0xb0},
-	{value: 0x0408, lo: 0xb1, hi: 0xb2},
-	{value: 0x0208, lo: 0xb3, hi: 0xb4},
+	{value: 0x0a08, lo: 0xa0, hi: 0xa9},
+	{value: 0x0c08, lo: 0xaa, hi: 0xac},
+	{value: 0x0808, lo: 0xad, hi: 0xad},
+	{value: 0x0c08, lo: 0xae, hi: 0xae},
+	{value: 0x0a08, lo: 0xaf, hi: 0xb0},
+	{value: 0x0c08, lo: 0xb1, hi: 0xb2},
+	{value: 0x0a08, lo: 0xb3, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xb5},
-	{value: 0x0208, lo: 0xb6, hi: 0xb8},
-	{value: 0x0408, lo: 0xb9, hi: 0xb9},
-	{value: 0x0208, lo: 0xba, hi: 0xbd},
+	{value: 0x0a08, lo: 0xb6, hi: 0xb8},
+	{value: 0x0c08, lo: 0xb9, hi: 0xb9},
+	{value: 0x0a08, lo: 0xba, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbf},
-	// Block 0x10, offset 0xa3
+	// Block 0xe, offset 0x85
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0040, lo: 0x80, hi: 0x93},
-	{value: 0x1308, lo: 0x94, hi: 0xa1},
-	{value: 0x0040, lo: 0xa2, hi: 0xa2},
-	{value: 0x1308, lo: 0xa3, hi: 0xbf},
-	// Block 0x11, offset 0xa8
+	{value: 0x3308, lo: 0x94, hi: 0xa1},
+	{value: 0x0840, lo: 0xa2, hi: 0xa2},
+	{value: 0x3308, lo: 0xa3, hi: 0xbf},
+	// Block 0xf, offset 0x8a
 	{value: 0x0000, lo: 0x08},
-	{value: 0x1308, lo: 0x80, hi: 0x82},
-	{value: 0x1008, lo: 0x83, hi: 0x83},
+	{value: 0x3308, lo: 0x80, hi: 0x82},
+	{value: 0x3008, lo: 0x83, hi: 0x83},
 	{value: 0x0008, lo: 0x84, hi: 0xb9},
-	{value: 0x1308, lo: 0xba, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbb},
-	{value: 0x1308, lo: 0xbc, hi: 0xbc},
+	{value: 0x3308, lo: 0xba, hi: 0xba},
+	{value: 0x3008, lo: 0xbb, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbf},
-	// Block 0x12, offset 0xb1
+	{value: 0x3008, lo: 0xbe, hi: 0xbf},
+	// Block 0x10, offset 0x93
 	{value: 0x0000, lo: 0x0f},
-	{value: 0x1308, lo: 0x80, hi: 0x80},
-	{value: 0x1008, lo: 0x81, hi: 0x82},
+	{value: 0x3308, lo: 0x80, hi: 0x80},
+	{value: 0x3008, lo: 0x81, hi: 0x82},
 	{value: 0x0040, lo: 0x83, hi: 0x85},
-	{value: 0x1008, lo: 0x86, hi: 0x88},
+	{value: 0x3008, lo: 0x86, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
-	{value: 0x1008, lo: 0x8a, hi: 0x8c},
-	{value: 0x1b08, lo: 0x8d, hi: 0x8d},
+	{value: 0x3008, lo: 0x8a, hi: 0x8c},
+	{value: 0x3b08, lo: 0x8d, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x90},
 	{value: 0x0040, lo: 0x91, hi: 0x96},
-	{value: 0x1008, lo: 0x97, hi: 0x97},
+	{value: 0x3008, lo: 0x97, hi: 0x97},
 	{value: 0x0040, lo: 0x98, hi: 0xa5},
 	{value: 0x0008, lo: 0xa6, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbf},
-	// Block 0x13, offset 0xc1
+	// Block 0x11, offset 0xa3
 	{value: 0x0000, lo: 0x0d},
-	{value: 0x1308, lo: 0x80, hi: 0x80},
-	{value: 0x1008, lo: 0x81, hi: 0x83},
+	{value: 0x3308, lo: 0x80, hi: 0x80},
+	{value: 0x3008, lo: 0x81, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x84},
 	{value: 0x0008, lo: 0x85, hi: 0x8c},
 	{value: 0x0040, lo: 0x8d, hi: 0x8d},
@@ -2568,25 +2569,24 @@
 	{value: 0x0008, lo: 0xaa, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbd},
-	{value: 0x1308, lo: 0xbe, hi: 0xbf},
-	// Block 0x14, offset 0xcf
-	{value: 0x0000, lo: 0x0c},
-	{value: 0x0040, lo: 0x80, hi: 0x80},
-	{value: 0x1308, lo: 0x81, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x83},
+	{value: 0x3308, lo: 0xbe, hi: 0xbf},
+	// Block 0x12, offset 0xb1
+	{value: 0x0000, lo: 0x0b},
+	{value: 0x3308, lo: 0x80, hi: 0x81},
+	{value: 0x3008, lo: 0x82, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x84},
 	{value: 0x0008, lo: 0x85, hi: 0x8c},
 	{value: 0x0040, lo: 0x8d, hi: 0x8d},
 	{value: 0x0008, lo: 0x8e, hi: 0x90},
 	{value: 0x0040, lo: 0x91, hi: 0x91},
 	{value: 0x0008, lo: 0x92, hi: 0xba},
-	{value: 0x0040, lo: 0xbb, hi: 0xbc},
+	{value: 0x3b08, lo: 0xbb, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbf},
-	// Block 0x15, offset 0xdc
+	{value: 0x3008, lo: 0xbe, hi: 0xbf},
+	// Block 0x13, offset 0xbd
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0040, lo: 0x80, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x83},
+	{value: 0x3008, lo: 0x82, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x84},
 	{value: 0x0008, lo: 0x85, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x99},
@@ -2596,50 +2596,50 @@
 	{value: 0x0040, lo: 0xbc, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbf},
-	// Block 0x16, offset 0xe8
+	// Block 0x14, offset 0xc9
 	{value: 0x0000, lo: 0x10},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x89},
-	{value: 0x1b08, lo: 0x8a, hi: 0x8a},
+	{value: 0x3b08, lo: 0x8a, hi: 0x8a},
 	{value: 0x0040, lo: 0x8b, hi: 0x8e},
-	{value: 0x1008, lo: 0x8f, hi: 0x91},
-	{value: 0x1308, lo: 0x92, hi: 0x94},
+	{value: 0x3008, lo: 0x8f, hi: 0x91},
+	{value: 0x3308, lo: 0x92, hi: 0x94},
 	{value: 0x0040, lo: 0x95, hi: 0x95},
-	{value: 0x1308, lo: 0x96, hi: 0x96},
+	{value: 0x3308, lo: 0x96, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x97},
-	{value: 0x1008, lo: 0x98, hi: 0x9f},
+	{value: 0x3008, lo: 0x98, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xa5},
 	{value: 0x0008, lo: 0xa6, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xb1},
-	{value: 0x1008, lo: 0xb2, hi: 0xb3},
+	{value: 0x3008, lo: 0xb2, hi: 0xb3},
 	{value: 0x0018, lo: 0xb4, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
-	// Block 0x17, offset 0xf9
+	// Block 0x15, offset 0xda
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0xb0},
-	{value: 0x1308, lo: 0xb1, hi: 0xb1},
+	{value: 0x3308, lo: 0xb1, hi: 0xb1},
 	{value: 0x0008, lo: 0xb2, hi: 0xb2},
 	{value: 0x08f1, lo: 0xb3, hi: 0xb3},
-	{value: 0x1308, lo: 0xb4, hi: 0xb9},
-	{value: 0x1b08, lo: 0xba, hi: 0xba},
+	{value: 0x3308, lo: 0xb4, hi: 0xb9},
+	{value: 0x3b08, lo: 0xba, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbe},
 	{value: 0x0018, lo: 0xbf, hi: 0xbf},
-	// Block 0x18, offset 0x103
+	// Block 0x16, offset 0xe4
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
-	{value: 0x1308, lo: 0x87, hi: 0x8e},
+	{value: 0x3308, lo: 0x87, hi: 0x8e},
 	{value: 0x0018, lo: 0x8f, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0018, lo: 0x9a, hi: 0x9b},
 	{value: 0x0040, lo: 0x9c, hi: 0xbf},
-	// Block 0x19, offset 0x10a
+	// Block 0x17, offset 0xeb
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0008, lo: 0x80, hi: 0x84},
 	{value: 0x0040, lo: 0x85, hi: 0x85},
 	{value: 0x0008, lo: 0x86, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x87},
-	{value: 0x1308, lo: 0x88, hi: 0x8d},
+	{value: 0x3308, lo: 0x88, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9b},
@@ -2647,76 +2647,76 @@
 	{value: 0x0999, lo: 0x9d, hi: 0x9d},
 	{value: 0x0008, lo: 0x9e, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xbf},
-	// Block 0x1a, offset 0x117
+	// Block 0x18, offset 0xf8
 	{value: 0x0000, lo: 0x10},
 	{value: 0x0008, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x8a},
 	{value: 0x0008, lo: 0x8b, hi: 0x8b},
 	{value: 0xe03d, lo: 0x8c, hi: 0x8c},
 	{value: 0x0018, lo: 0x8d, hi: 0x97},
-	{value: 0x1308, lo: 0x98, hi: 0x99},
+	{value: 0x3308, lo: 0x98, hi: 0x99},
 	{value: 0x0018, lo: 0x9a, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xa9},
 	{value: 0x0018, lo: 0xaa, hi: 0xb4},
-	{value: 0x1308, lo: 0xb5, hi: 0xb5},
+	{value: 0x3308, lo: 0xb5, hi: 0xb5},
 	{value: 0x0018, lo: 0xb6, hi: 0xb6},
-	{value: 0x1308, lo: 0xb7, hi: 0xb7},
+	{value: 0x3308, lo: 0xb7, hi: 0xb7},
 	{value: 0x0018, lo: 0xb8, hi: 0xb8},
-	{value: 0x1308, lo: 0xb9, hi: 0xb9},
+	{value: 0x3308, lo: 0xb9, hi: 0xb9},
 	{value: 0x0018, lo: 0xba, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbf},
-	// Block 0x1b, offset 0x128
+	{value: 0x3008, lo: 0xbe, hi: 0xbf},
+	// Block 0x19, offset 0x109
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0018, lo: 0x80, hi: 0x85},
-	{value: 0x1308, lo: 0x86, hi: 0x86},
+	{value: 0x3308, lo: 0x86, hi: 0x86},
 	{value: 0x0018, lo: 0x87, hi: 0x8c},
 	{value: 0x0040, lo: 0x8d, hi: 0x8d},
 	{value: 0x0018, lo: 0x8e, hi: 0x9a},
 	{value: 0x0040, lo: 0x9b, hi: 0xbf},
-	// Block 0x1c, offset 0x12f
+	// Block 0x1a, offset 0x110
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x0008, lo: 0x80, hi: 0xaa},
-	{value: 0x1008, lo: 0xab, hi: 0xac},
-	{value: 0x1308, lo: 0xad, hi: 0xb0},
-	{value: 0x1008, lo: 0xb1, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb7},
-	{value: 0x1008, lo: 0xb8, hi: 0xb8},
-	{value: 0x1b08, lo: 0xb9, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbc},
-	{value: 0x1308, lo: 0xbd, hi: 0xbe},
+	{value: 0x3008, lo: 0xab, hi: 0xac},
+	{value: 0x3308, lo: 0xad, hi: 0xb0},
+	{value: 0x3008, lo: 0xb1, hi: 0xb1},
+	{value: 0x3308, lo: 0xb2, hi: 0xb7},
+	{value: 0x3008, lo: 0xb8, hi: 0xb8},
+	{value: 0x3b08, lo: 0xb9, hi: 0xba},
+	{value: 0x3008, lo: 0xbb, hi: 0xbc},
+	{value: 0x3308, lo: 0xbd, hi: 0xbe},
 	{value: 0x0008, lo: 0xbf, hi: 0xbf},
-	// Block 0x1d, offset 0x13a
+	// Block 0x1b, offset 0x11b
 	{value: 0x0000, lo: 0x0e},
 	{value: 0x0008, lo: 0x80, hi: 0x89},
 	{value: 0x0018, lo: 0x8a, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x95},
-	{value: 0x1008, lo: 0x96, hi: 0x97},
-	{value: 0x1308, lo: 0x98, hi: 0x99},
+	{value: 0x3008, lo: 0x96, hi: 0x97},
+	{value: 0x3308, lo: 0x98, hi: 0x99},
 	{value: 0x0008, lo: 0x9a, hi: 0x9d},
-	{value: 0x1308, lo: 0x9e, hi: 0xa0},
+	{value: 0x3308, lo: 0x9e, hi: 0xa0},
 	{value: 0x0008, lo: 0xa1, hi: 0xa1},
-	{value: 0x1008, lo: 0xa2, hi: 0xa4},
+	{value: 0x3008, lo: 0xa2, hi: 0xa4},
 	{value: 0x0008, lo: 0xa5, hi: 0xa6},
-	{value: 0x1008, lo: 0xa7, hi: 0xad},
+	{value: 0x3008, lo: 0xa7, hi: 0xad},
 	{value: 0x0008, lo: 0xae, hi: 0xb0},
-	{value: 0x1308, lo: 0xb1, hi: 0xb4},
+	{value: 0x3308, lo: 0xb1, hi: 0xb4},
 	{value: 0x0008, lo: 0xb5, hi: 0xbf},
-	// Block 0x1e, offset 0x149
+	// Block 0x1c, offset 0x12a
 	{value: 0x0000, lo: 0x0d},
 	{value: 0x0008, lo: 0x80, hi: 0x81},
-	{value: 0x1308, lo: 0x82, hi: 0x82},
-	{value: 0x1008, lo: 0x83, hi: 0x84},
-	{value: 0x1308, lo: 0x85, hi: 0x86},
-	{value: 0x1008, lo: 0x87, hi: 0x8c},
-	{value: 0x1308, lo: 0x8d, hi: 0x8d},
+	{value: 0x3308, lo: 0x82, hi: 0x82},
+	{value: 0x3008, lo: 0x83, hi: 0x84},
+	{value: 0x3308, lo: 0x85, hi: 0x86},
+	{value: 0x3008, lo: 0x87, hi: 0x8c},
+	{value: 0x3308, lo: 0x8d, hi: 0x8d},
 	{value: 0x0008, lo: 0x8e, hi: 0x8e},
-	{value: 0x1008, lo: 0x8f, hi: 0x8f},
+	{value: 0x3008, lo: 0x8f, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
-	{value: 0x1008, lo: 0x9a, hi: 0x9c},
-	{value: 0x1308, lo: 0x9d, hi: 0x9d},
+	{value: 0x3008, lo: 0x9a, hi: 0x9c},
+	{value: 0x3308, lo: 0x9d, hi: 0x9d},
 	{value: 0x0018, lo: 0x9e, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xbf},
-	// Block 0x1f, offset 0x157
+	// Block 0x1d, offset 0x138
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0040, lo: 0x80, hi: 0x86},
 	{value: 0x055d, lo: 0x87, hi: 0x87},
@@ -2727,18 +2727,27 @@
 	{value: 0x0018, lo: 0xbb, hi: 0xbb},
 	{value: 0xe105, lo: 0xbc, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbf},
-	// Block 0x20, offset 0x161
+	// Block 0x1e, offset 0x142
 	{value: 0x0000, lo: 0x01},
 	{value: 0x0018, lo: 0x80, hi: 0xbf},
-	// Block 0x21, offset 0x163
-	{value: 0x0000, lo: 0x03},
+	// Block 0x1f, offset 0x144
+	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0xa0},
-	{value: 0x0018, lo: 0xa1, hi: 0xbf},
-	// Block 0x22, offset 0x167
+	{value: 0x2018, lo: 0xa1, hi: 0xb5},
+	{value: 0x0018, lo: 0xb6, hi: 0xbf},
+	// Block 0x20, offset 0x149
+	{value: 0x0000, lo: 0x02},
+	{value: 0x0018, lo: 0x80, hi: 0xa7},
+	{value: 0x2018, lo: 0xa8, hi: 0xbf},
+	// Block 0x21, offset 0x14c
+	{value: 0x0000, lo: 0x02},
+	{value: 0x2018, lo: 0x80, hi: 0x82},
+	{value: 0x0018, lo: 0x83, hi: 0xbf},
+	// Block 0x22, offset 0x14f
 	{value: 0x0000, lo: 0x01},
 	{value: 0x0008, lo: 0x80, hi: 0xbf},
-	// Block 0x23, offset 0x169
+	// Block 0x23, offset 0x151
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
@@ -2751,7 +2760,7 @@
 	{value: 0x0008, lo: 0x9a, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x24, offset 0x175
+	// Block 0x24, offset 0x15d
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x0008, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
@@ -2763,7 +2772,7 @@
 	{value: 0x0040, lo: 0xb6, hi: 0xb7},
 	{value: 0x0008, lo: 0xb8, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0x25, offset 0x180
+	// Block 0x25, offset 0x168
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0x80},
 	{value: 0x0040, lo: 0x81, hi: 0x81},
@@ -2772,146 +2781,146 @@
 	{value: 0x0008, lo: 0x88, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x97},
 	{value: 0x0008, lo: 0x98, hi: 0xbf},
-	// Block 0x26, offset 0x188
+	// Block 0x26, offset 0x170
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0x90},
 	{value: 0x0040, lo: 0x91, hi: 0x91},
 	{value: 0x0008, lo: 0x92, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0x97},
 	{value: 0x0008, lo: 0x98, hi: 0xbf},
-	// Block 0x27, offset 0x18e
+	// Block 0x27, offset 0x176
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0x9a},
 	{value: 0x0040, lo: 0x9b, hi: 0x9c},
-	{value: 0x1308, lo: 0x9d, hi: 0x9f},
+	{value: 0x3308, lo: 0x9d, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbf},
-	// Block 0x28, offset 0x194
+	// Block 0x28, offset 0x17c
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x29, offset 0x199
+	// Block 0x29, offset 0x181
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xb7},
 	{value: 0xe045, lo: 0xb8, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbf},
-	// Block 0x2a, offset 0x19e
+	// Block 0x2a, offset 0x186
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0018, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0xbf},
-	// Block 0x2b, offset 0x1a1
+	// Block 0x2b, offset 0x189
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xac},
 	{value: 0x0018, lo: 0xad, hi: 0xae},
 	{value: 0x0008, lo: 0xaf, hi: 0xbf},
-	// Block 0x2c, offset 0x1a5
+	// Block 0x2c, offset 0x18d
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0x9a},
 	{value: 0x0018, lo: 0x9b, hi: 0x9c},
 	{value: 0x0040, lo: 0x9d, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x2d, offset 0x1ab
+	// Block 0x2d, offset 0x193
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xaa},
 	{value: 0x0018, lo: 0xab, hi: 0xb0},
 	{value: 0x0008, lo: 0xb1, hi: 0xb8},
 	{value: 0x0040, lo: 0xb9, hi: 0xbf},
-	// Block 0x2e, offset 0x1b0
+	// Block 0x2e, offset 0x198
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0x8c},
 	{value: 0x0040, lo: 0x8d, hi: 0x8d},
 	{value: 0x0008, lo: 0x8e, hi: 0x91},
-	{value: 0x1308, lo: 0x92, hi: 0x93},
-	{value: 0x1b08, lo: 0x94, hi: 0x94},
+	{value: 0x3308, lo: 0x92, hi: 0x93},
+	{value: 0x3b08, lo: 0x94, hi: 0x94},
 	{value: 0x0040, lo: 0x95, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb3},
-	{value: 0x1b08, lo: 0xb4, hi: 0xb4},
+	{value: 0x3308, lo: 0xb2, hi: 0xb3},
+	{value: 0x3b08, lo: 0xb4, hi: 0xb4},
 	{value: 0x0018, lo: 0xb5, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0x2f, offset 0x1bc
+	// Block 0x2f, offset 0x1a4
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x91},
-	{value: 0x1308, lo: 0x92, hi: 0x93},
+	{value: 0x3308, lo: 0x92, hi: 0x93},
 	{value: 0x0040, lo: 0x94, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xac},
 	{value: 0x0040, lo: 0xad, hi: 0xad},
 	{value: 0x0008, lo: 0xae, hi: 0xb0},
 	{value: 0x0040, lo: 0xb1, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb3},
+	{value: 0x3308, lo: 0xb2, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xbf},
-	// Block 0x30, offset 0x1c6
+	// Block 0x30, offset 0x1ae
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0xb3},
-	{value: 0x1340, lo: 0xb4, hi: 0xb5},
-	{value: 0x1008, lo: 0xb6, hi: 0xb6},
-	{value: 0x1308, lo: 0xb7, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbf},
-	// Block 0x31, offset 0x1cc
+	{value: 0x3340, lo: 0xb4, hi: 0xb5},
+	{value: 0x3008, lo: 0xb6, hi: 0xb6},
+	{value: 0x3308, lo: 0xb7, hi: 0xbd},
+	{value: 0x3008, lo: 0xbe, hi: 0xbf},
+	// Block 0x31, offset 0x1b4
 	{value: 0x0000, lo: 0x10},
-	{value: 0x1008, lo: 0x80, hi: 0x85},
-	{value: 0x1308, lo: 0x86, hi: 0x86},
-	{value: 0x1008, lo: 0x87, hi: 0x88},
-	{value: 0x1308, lo: 0x89, hi: 0x91},
-	{value: 0x1b08, lo: 0x92, hi: 0x92},
-	{value: 0x1308, lo: 0x93, hi: 0x93},
+	{value: 0x3008, lo: 0x80, hi: 0x85},
+	{value: 0x3308, lo: 0x86, hi: 0x86},
+	{value: 0x3008, lo: 0x87, hi: 0x88},
+	{value: 0x3308, lo: 0x89, hi: 0x91},
+	{value: 0x3b08, lo: 0x92, hi: 0x92},
+	{value: 0x3308, lo: 0x93, hi: 0x93},
 	{value: 0x0018, lo: 0x94, hi: 0x96},
 	{value: 0x0008, lo: 0x97, hi: 0x97},
 	{value: 0x0018, lo: 0x98, hi: 0x9b},
 	{value: 0x0008, lo: 0x9c, hi: 0x9c},
-	{value: 0x1308, lo: 0x9d, hi: 0x9d},
+	{value: 0x3308, lo: 0x9d, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xa9},
 	{value: 0x0040, lo: 0xaa, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0x32, offset 0x1dd
+	// Block 0x32, offset 0x1c5
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0018, lo: 0x80, hi: 0x85},
 	{value: 0x0040, lo: 0x86, hi: 0x86},
 	{value: 0x0218, lo: 0x87, hi: 0x87},
 	{value: 0x0018, lo: 0x88, hi: 0x8a},
-	{value: 0x13c0, lo: 0x8b, hi: 0x8d},
+	{value: 0x33c0, lo: 0x8b, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9f},
 	{value: 0x0208, lo: 0xa0, hi: 0xbf},
-	// Block 0x33, offset 0x1e7
+	// Block 0x33, offset 0x1cf
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0208, lo: 0x80, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbf},
-	// Block 0x34, offset 0x1ea
+	// Block 0x34, offset 0x1d2
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0x84},
-	{value: 0x1308, lo: 0x85, hi: 0x86},
+	{value: 0x3308, lo: 0x85, hi: 0x86},
 	{value: 0x0208, lo: 0x87, hi: 0xa8},
-	{value: 0x1308, lo: 0xa9, hi: 0xa9},
+	{value: 0x3308, lo: 0xa9, hi: 0xa9},
 	{value: 0x0208, lo: 0xaa, hi: 0xaa},
 	{value: 0x0040, lo: 0xab, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x35, offset 0x1f2
+	// Block 0x35, offset 0x1da
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xbf},
-	// Block 0x36, offset 0x1f5
+	// Block 0x36, offset 0x1dd
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0008, lo: 0x80, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0x9f},
-	{value: 0x1308, lo: 0xa0, hi: 0xa2},
-	{value: 0x1008, lo: 0xa3, hi: 0xa6},
-	{value: 0x1308, lo: 0xa7, hi: 0xa8},
-	{value: 0x1008, lo: 0xa9, hi: 0xab},
+	{value: 0x3308, lo: 0xa0, hi: 0xa2},
+	{value: 0x3008, lo: 0xa3, hi: 0xa6},
+	{value: 0x3308, lo: 0xa7, hi: 0xa8},
+	{value: 0x3008, lo: 0xa9, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xaf},
-	{value: 0x1008, lo: 0xb0, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb2},
-	{value: 0x1008, lo: 0xb3, hi: 0xb8},
-	{value: 0x1308, lo: 0xb9, hi: 0xbb},
+	{value: 0x3008, lo: 0xb0, hi: 0xb1},
+	{value: 0x3308, lo: 0xb2, hi: 0xb2},
+	{value: 0x3008, lo: 0xb3, hi: 0xb8},
+	{value: 0x3308, lo: 0xb9, hi: 0xbb},
 	{value: 0x0040, lo: 0xbc, hi: 0xbf},
-	// Block 0x37, offset 0x202
+	// Block 0x37, offset 0x1ea
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0018, lo: 0x80, hi: 0x80},
 	{value: 0x0040, lo: 0x81, hi: 0x83},
@@ -2920,12 +2929,12 @@
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
-	// Block 0x38, offset 0x20a
+	// Block 0x38, offset 0x1f2
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x39, offset 0x20e
+	// Block 0x39, offset 0x1f6
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0008, lo: 0x80, hi: 0x89},
 	{value: 0x0040, lo: 0x8a, hi: 0x8f},
@@ -2933,33 +2942,33 @@
 	{value: 0x0028, lo: 0x9a, hi: 0x9a},
 	{value: 0x0040, lo: 0x9b, hi: 0x9d},
 	{value: 0x0018, lo: 0x9e, hi: 0xbf},
-	// Block 0x3a, offset 0x215
+	// Block 0x3a, offset 0x1fd
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0x96},
-	{value: 0x1308, lo: 0x97, hi: 0x98},
-	{value: 0x1008, lo: 0x99, hi: 0x9a},
-	{value: 0x1308, lo: 0x9b, hi: 0x9b},
+	{value: 0x3308, lo: 0x97, hi: 0x98},
+	{value: 0x3008, lo: 0x99, hi: 0x9a},
+	{value: 0x3308, lo: 0x9b, hi: 0x9b},
 	{value: 0x0040, lo: 0x9c, hi: 0x9d},
 	{value: 0x0018, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x3b, offset 0x21d
+	// Block 0x3b, offset 0x205
 	{value: 0x0000, lo: 0x0f},
 	{value: 0x0008, lo: 0x80, hi: 0x94},
-	{value: 0x1008, lo: 0x95, hi: 0x95},
-	{value: 0x1308, lo: 0x96, hi: 0x96},
-	{value: 0x1008, lo: 0x97, hi: 0x97},
-	{value: 0x1308, lo: 0x98, hi: 0x9e},
+	{value: 0x3008, lo: 0x95, hi: 0x95},
+	{value: 0x3308, lo: 0x96, hi: 0x96},
+	{value: 0x3008, lo: 0x97, hi: 0x97},
+	{value: 0x3308, lo: 0x98, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0x9f},
-	{value: 0x1b08, lo: 0xa0, hi: 0xa0},
-	{value: 0x1008, lo: 0xa1, hi: 0xa1},
-	{value: 0x1308, lo: 0xa2, hi: 0xa2},
-	{value: 0x1008, lo: 0xa3, hi: 0xa4},
-	{value: 0x1308, lo: 0xa5, hi: 0xac},
-	{value: 0x1008, lo: 0xad, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xbc},
+	{value: 0x3b08, lo: 0xa0, hi: 0xa0},
+	{value: 0x3008, lo: 0xa1, hi: 0xa1},
+	{value: 0x3308, lo: 0xa2, hi: 0xa2},
+	{value: 0x3008, lo: 0xa3, hi: 0xa4},
+	{value: 0x3308, lo: 0xa5, hi: 0xac},
+	{value: 0x3008, lo: 0xad, hi: 0xb2},
+	{value: 0x3308, lo: 0xb3, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbe},
-	{value: 0x1308, lo: 0xbf, hi: 0xbf},
-	// Block 0x3c, offset 0x22d
+	{value: 0x3308, lo: 0xbf, hi: 0xbf},
+	// Block 0x3c, offset 0x215
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0x89},
 	{value: 0x0040, lo: 0x8a, hi: 0x8f},
@@ -2969,78 +2978,78 @@
 	{value: 0x0008, lo: 0xa7, hi: 0xa7},
 	{value: 0x0018, lo: 0xa8, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xbd},
-	{value: 0x1318, lo: 0xbe, hi: 0xbe},
+	{value: 0x3308, lo: 0xb0, hi: 0xbd},
+	{value: 0x3318, lo: 0xbe, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0x3d, offset 0x239
+	// Block 0x3d, offset 0x221
 	{value: 0x0000, lo: 0x01},
 	{value: 0x0040, lo: 0x80, hi: 0xbf},
-	// Block 0x3e, offset 0x23b
+	// Block 0x3e, offset 0x223
 	{value: 0x0000, lo: 0x09},
-	{value: 0x1308, lo: 0x80, hi: 0x83},
-	{value: 0x1008, lo: 0x84, hi: 0x84},
+	{value: 0x3308, lo: 0x80, hi: 0x83},
+	{value: 0x3008, lo: 0x84, hi: 0x84},
 	{value: 0x0008, lo: 0x85, hi: 0xb3},
-	{value: 0x1308, lo: 0xb4, hi: 0xb4},
-	{value: 0x1008, lo: 0xb5, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbb},
-	{value: 0x1308, lo: 0xbc, hi: 0xbc},
-	{value: 0x1008, lo: 0xbd, hi: 0xbf},
-	// Block 0x3f, offset 0x245
+	{value: 0x3308, lo: 0xb4, hi: 0xb4},
+	{value: 0x3008, lo: 0xb5, hi: 0xb5},
+	{value: 0x3308, lo: 0xb6, hi: 0xba},
+	{value: 0x3008, lo: 0xbb, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbc},
+	{value: 0x3008, lo: 0xbd, hi: 0xbf},
+	// Block 0x3f, offset 0x22d
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x1008, lo: 0x80, hi: 0x81},
-	{value: 0x1308, lo: 0x82, hi: 0x82},
-	{value: 0x1008, lo: 0x83, hi: 0x83},
-	{value: 0x1808, lo: 0x84, hi: 0x84},
+	{value: 0x3008, lo: 0x80, hi: 0x81},
+	{value: 0x3308, lo: 0x82, hi: 0x82},
+	{value: 0x3008, lo: 0x83, hi: 0x83},
+	{value: 0x3808, lo: 0x84, hi: 0x84},
 	{value: 0x0008, lo: 0x85, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0018, lo: 0x9a, hi: 0xaa},
-	{value: 0x1308, lo: 0xab, hi: 0xb3},
+	{value: 0x3308, lo: 0xab, hi: 0xb3},
 	{value: 0x0018, lo: 0xb4, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbf},
-	// Block 0x40, offset 0x251
+	// Block 0x40, offset 0x239
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x1308, lo: 0x80, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x80, hi: 0x81},
+	{value: 0x3008, lo: 0x82, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0xa0},
-	{value: 0x1008, lo: 0xa1, hi: 0xa1},
-	{value: 0x1308, lo: 0xa2, hi: 0xa5},
-	{value: 0x1008, lo: 0xa6, hi: 0xa7},
-	{value: 0x1308, lo: 0xa8, hi: 0xa9},
-	{value: 0x1808, lo: 0xaa, hi: 0xaa},
-	{value: 0x1b08, lo: 0xab, hi: 0xab},
-	{value: 0x1308, lo: 0xac, hi: 0xad},
+	{value: 0x3008, lo: 0xa1, hi: 0xa1},
+	{value: 0x3308, lo: 0xa2, hi: 0xa5},
+	{value: 0x3008, lo: 0xa6, hi: 0xa7},
+	{value: 0x3308, lo: 0xa8, hi: 0xa9},
+	{value: 0x3808, lo: 0xaa, hi: 0xaa},
+	{value: 0x3b08, lo: 0xab, hi: 0xab},
+	{value: 0x3308, lo: 0xac, hi: 0xad},
 	{value: 0x0008, lo: 0xae, hi: 0xbf},
-	// Block 0x41, offset 0x25d
+	// Block 0x41, offset 0x245
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0xa5},
-	{value: 0x1308, lo: 0xa6, hi: 0xa6},
-	{value: 0x1008, lo: 0xa7, hi: 0xa7},
-	{value: 0x1308, lo: 0xa8, hi: 0xa9},
-	{value: 0x1008, lo: 0xaa, hi: 0xac},
-	{value: 0x1308, lo: 0xad, hi: 0xad},
-	{value: 0x1008, lo: 0xae, hi: 0xae},
-	{value: 0x1308, lo: 0xaf, hi: 0xb1},
-	{value: 0x1808, lo: 0xb2, hi: 0xb3},
+	{value: 0x3308, lo: 0xa6, hi: 0xa6},
+	{value: 0x3008, lo: 0xa7, hi: 0xa7},
+	{value: 0x3308, lo: 0xa8, hi: 0xa9},
+	{value: 0x3008, lo: 0xaa, hi: 0xac},
+	{value: 0x3308, lo: 0xad, hi: 0xad},
+	{value: 0x3008, lo: 0xae, hi: 0xae},
+	{value: 0x3308, lo: 0xaf, hi: 0xb1},
+	{value: 0x3808, lo: 0xb2, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xbb},
 	{value: 0x0018, lo: 0xbc, hi: 0xbf},
-	// Block 0x42, offset 0x269
+	// Block 0x42, offset 0x251
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0xa3},
-	{value: 0x1008, lo: 0xa4, hi: 0xab},
-	{value: 0x1308, lo: 0xac, hi: 0xb3},
-	{value: 0x1008, lo: 0xb4, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xb7},
+	{value: 0x3008, lo: 0xa4, hi: 0xab},
+	{value: 0x3308, lo: 0xac, hi: 0xb3},
+	{value: 0x3008, lo: 0xb4, hi: 0xb5},
+	{value: 0x3308, lo: 0xb6, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xba},
 	{value: 0x0018, lo: 0xbb, hi: 0xbf},
-	// Block 0x43, offset 0x271
+	// Block 0x43, offset 0x259
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x89},
 	{value: 0x0040, lo: 0x8a, hi: 0x8c},
 	{value: 0x0008, lo: 0x8d, hi: 0xbd},
 	{value: 0x0018, lo: 0xbe, hi: 0xbf},
-	// Block 0x44, offset 0x276
+	// Block 0x44, offset 0x25e
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0e29, lo: 0x80, hi: 0x80},
 	{value: 0x0e41, lo: 0x81, hi: 0x81},
@@ -3051,30 +3060,30 @@
 	{value: 0x0eb9, lo: 0x87, hi: 0x87},
 	{value: 0x057d, lo: 0x88, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0xbf},
-	// Block 0x45, offset 0x280
+	// Block 0x45, offset 0x268
 	{value: 0x0000, lo: 0x10},
 	{value: 0x0018, lo: 0x80, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
-	{value: 0x1308, lo: 0x90, hi: 0x92},
+	{value: 0x3308, lo: 0x90, hi: 0x92},
 	{value: 0x0018, lo: 0x93, hi: 0x93},
-	{value: 0x1308, lo: 0x94, hi: 0xa0},
-	{value: 0x1008, lo: 0xa1, hi: 0xa1},
-	{value: 0x1308, lo: 0xa2, hi: 0xa8},
+	{value: 0x3308, lo: 0x94, hi: 0xa0},
+	{value: 0x3008, lo: 0xa1, hi: 0xa1},
+	{value: 0x3308, lo: 0xa2, hi: 0xa8},
 	{value: 0x0008, lo: 0xa9, hi: 0xac},
-	{value: 0x1308, lo: 0xad, hi: 0xad},
+	{value: 0x3308, lo: 0xad, hi: 0xad},
 	{value: 0x0008, lo: 0xae, hi: 0xb1},
-	{value: 0x1008, lo: 0xb2, hi: 0xb3},
-	{value: 0x1308, lo: 0xb4, hi: 0xb4},
+	{value: 0x3008, lo: 0xb2, hi: 0xb3},
+	{value: 0x3308, lo: 0xb4, hi: 0xb4},
 	{value: 0x0008, lo: 0xb5, hi: 0xb6},
-	{value: 0x0040, lo: 0xb7, hi: 0xb7},
-	{value: 0x1308, lo: 0xb8, hi: 0xb9},
+	{value: 0x3008, lo: 0xb7, hi: 0xb7},
+	{value: 0x3308, lo: 0xb8, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0x46, offset 0x291
+	// Block 0x46, offset 0x279
 	{value: 0x0000, lo: 0x03},
-	{value: 0x1308, lo: 0x80, hi: 0xb5},
-	{value: 0x0040, lo: 0xb6, hi: 0xba},
-	{value: 0x1308, lo: 0xbb, hi: 0xbf},
-	// Block 0x47, offset 0x295
+	{value: 0x3308, lo: 0x80, hi: 0xb9},
+	{value: 0x0040, lo: 0xba, hi: 0xba},
+	{value: 0x3308, lo: 0xbb, hi: 0xbf},
+	// Block 0x47, offset 0x27d
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x0008, lo: 0x80, hi: 0x87},
 	{value: 0xe045, lo: 0x88, hi: 0x8f},
@@ -3086,12 +3095,12 @@
 	{value: 0xe045, lo: 0xa8, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb7},
 	{value: 0xe045, lo: 0xb8, hi: 0xbf},
-	// Block 0x48, offset 0x2a0
+	// Block 0x48, offset 0x288
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0040, lo: 0x80, hi: 0x8f},
-	{value: 0x1318, lo: 0x90, hi: 0xb0},
+	{value: 0x3318, lo: 0x90, hi: 0xb0},
 	{value: 0x0040, lo: 0xb1, hi: 0xbf},
-	// Block 0x49, offset 0x2a4
+	// Block 0x49, offset 0x28c
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0018, lo: 0x80, hi: 0x82},
 	{value: 0x0040, lo: 0x83, hi: 0x83},
@@ -3101,7 +3110,7 @@
 	{value: 0x0018, lo: 0x8a, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0xbf},
-	// Block 0x4a, offset 0x2ad
+	// Block 0x4a, offset 0x295
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0018, lo: 0x80, hi: 0xab},
 	{value: 0x24f1, lo: 0xac, hi: 0xac},
@@ -3110,72 +3119,68 @@
 	{value: 0x2579, lo: 0xaf, hi: 0xaf},
 	{value: 0x25b1, lo: 0xb0, hi: 0xb0},
 	{value: 0x0018, lo: 0xb1, hi: 0xbf},
-	// Block 0x4b, offset 0x2b5
+	// Block 0x4b, offset 0x29d
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x9f},
 	{value: 0x0080, lo: 0xa0, hi: 0xa0},
 	{value: 0x0018, lo: 0xa1, hi: 0xad},
 	{value: 0x0080, lo: 0xae, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xbf},
-	// Block 0x4c, offset 0x2bb
+	// Block 0x4c, offset 0x2a3
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0xa8},
 	{value: 0x09c5, lo: 0xa9, hi: 0xa9},
 	{value: 0x09e5, lo: 0xaa, hi: 0xaa},
 	{value: 0x0018, lo: 0xab, hi: 0xbf},
-	// Block 0x4d, offset 0x2c0
-	{value: 0x0000, lo: 0x02},
-	{value: 0x0018, lo: 0x80, hi: 0xbe},
-	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0x4e, offset 0x2c3
+	// Block 0x4d, offset 0x2a8
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0018, lo: 0x80, hi: 0xa6},
 	{value: 0x0040, lo: 0xa7, hi: 0xbf},
-	// Block 0x4f, offset 0x2c6
+	// Block 0x4e, offset 0x2ab
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0x8b},
 	{value: 0x28c1, lo: 0x8c, hi: 0x8c},
 	{value: 0x0018, lo: 0x8d, hi: 0xbf},
-	// Block 0x50, offset 0x2ca
+	// Block 0x4f, offset 0x2af
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0xb3},
 	{value: 0x0e66, lo: 0xb4, hi: 0xb4},
 	{value: 0x292a, lo: 0xb5, hi: 0xb5},
 	{value: 0x0e86, lo: 0xb6, hi: 0xb6},
 	{value: 0x0018, lo: 0xb7, hi: 0xbf},
-	// Block 0x51, offset 0x2d0
+	// Block 0x50, offset 0x2b5
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0x9b},
 	{value: 0x2941, lo: 0x9c, hi: 0x9c},
 	{value: 0x0018, lo: 0x9d, hi: 0xbf},
-	// Block 0x52, offset 0x2d4
+	// Block 0x51, offset 0x2b9
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xb5},
 	{value: 0x0018, lo: 0xb6, hi: 0xbf},
-	// Block 0x53, offset 0x2d8
+	// Block 0x52, offset 0x2bd
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0x97},
 	{value: 0x0018, lo: 0x98, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbc},
 	{value: 0x0018, lo: 0xbd, hi: 0xbf},
-	// Block 0x54, offset 0x2de
+	// Block 0x53, offset 0x2c3
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0018, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
-	{value: 0x0018, lo: 0x8a, hi: 0x91},
-	{value: 0x0040, lo: 0x92, hi: 0xab},
+	{value: 0x0018, lo: 0x8a, hi: 0x92},
+	{value: 0x0040, lo: 0x93, hi: 0xab},
 	{value: 0x0018, lo: 0xac, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
-	// Block 0x55, offset 0x2e5
+	// Block 0x54, offset 0x2ca
 	{value: 0x0000, lo: 0x05},
 	{value: 0xe185, lo: 0x80, hi: 0x8f},
 	{value: 0x03f5, lo: 0x90, hi: 0x9f},
 	{value: 0x0ea5, lo: 0xa0, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x56, offset 0x2eb
+	// Block 0x55, offset 0x2d0
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0xa5},
 	{value: 0x0040, lo: 0xa6, hi: 0xa6},
@@ -3184,15 +3189,15 @@
 	{value: 0x0008, lo: 0xad, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x57, offset 0x2f3
+	// Block 0x56, offset 0x2d8
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0008, lo: 0x80, hi: 0xa7},
 	{value: 0x0040, lo: 0xa8, hi: 0xae},
 	{value: 0xe075, lo: 0xaf, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb0},
 	{value: 0x0040, lo: 0xb1, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0x58, offset 0x2fa
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0x57, offset 0x2df
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x0008, lo: 0x80, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x9f},
@@ -3204,7 +3209,7 @@
 	{value: 0x0040, lo: 0xb7, hi: 0xb7},
 	{value: 0x0008, lo: 0xb8, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0x59, offset 0x305
+	// Block 0x58, offset 0x2ea
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x87},
@@ -3214,62 +3219,62 @@
 	{value: 0x0040, lo: 0x97, hi: 0x97},
 	{value: 0x0008, lo: 0x98, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0x9f},
-	{value: 0x1308, lo: 0xa0, hi: 0xbf},
-	// Block 0x5a, offset 0x30f
+	{value: 0x3308, lo: 0xa0, hi: 0xbf},
+	// Block 0x59, offset 0x2f4
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xae},
 	{value: 0x0008, lo: 0xaf, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xbf},
-	// Block 0x5b, offset 0x313
+	// Block 0x5a, offset 0x2f8
 	{value: 0x0000, lo: 0x02},
-	{value: 0x0018, lo: 0x80, hi: 0x84},
-	{value: 0x0040, lo: 0x85, hi: 0xbf},
-	// Block 0x5c, offset 0x316
+	{value: 0x0018, lo: 0x80, hi: 0x89},
+	{value: 0x0040, lo: 0x8a, hi: 0xbf},
+	// Block 0x5b, offset 0x2fb
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9a},
 	{value: 0x0018, lo: 0x9b, hi: 0x9e},
 	{value: 0x0edd, lo: 0x9f, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xbf},
-	// Block 0x5d, offset 0x31c
+	// Block 0x5c, offset 0x301
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xb2},
 	{value: 0x0efd, lo: 0xb3, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xbf},
-	// Block 0x5e, offset 0x320
+	// Block 0x5d, offset 0x305
 	{value: 0x0020, lo: 0x01},
 	{value: 0x0f1d, lo: 0x80, hi: 0xbf},
-	// Block 0x5f, offset 0x322
+	// Block 0x5e, offset 0x307
 	{value: 0x0020, lo: 0x02},
 	{value: 0x171d, lo: 0x80, hi: 0x8f},
 	{value: 0x18fd, lo: 0x90, hi: 0xbf},
-	// Block 0x60, offset 0x325
+	// Block 0x5f, offset 0x30a
 	{value: 0x0020, lo: 0x01},
 	{value: 0x1efd, lo: 0x80, hi: 0xbf},
-	// Block 0x61, offset 0x327
+	// Block 0x60, offset 0x30c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0xbf},
-	// Block 0x62, offset 0x32a
+	// Block 0x61, offset 0x30f
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x98},
-	{value: 0x1308, lo: 0x99, hi: 0x9a},
+	{value: 0x3308, lo: 0x99, hi: 0x9a},
 	{value: 0x29e2, lo: 0x9b, hi: 0x9b},
 	{value: 0x2a0a, lo: 0x9c, hi: 0x9c},
 	{value: 0x0008, lo: 0x9d, hi: 0x9e},
 	{value: 0x2a31, lo: 0x9f, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xa0},
 	{value: 0x0008, lo: 0xa1, hi: 0xbf},
-	// Block 0x63, offset 0x334
+	// Block 0x62, offset 0x319
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xbe},
 	{value: 0x2a69, lo: 0xbf, hi: 0xbf},
-	// Block 0x64, offset 0x337
+	// Block 0x63, offset 0x31c
 	{value: 0x0000, lo: 0x0e},
 	{value: 0x0040, lo: 0x80, hi: 0x84},
-	{value: 0x0008, lo: 0x85, hi: 0xad},
-	{value: 0x0040, lo: 0xae, hi: 0xb0},
+	{value: 0x0008, lo: 0x85, hi: 0xae},
+	{value: 0x0040, lo: 0xaf, hi: 0xb0},
 	{value: 0x2a1d, lo: 0xb1, hi: 0xb1},
 	{value: 0x2a3d, lo: 0xb2, hi: 0xb2},
 	{value: 0x2a5d, lo: 0xb3, hi: 0xb3},
@@ -3281,150 +3286,150 @@
 	{value: 0x2afd, lo: 0xba, hi: 0xbb},
 	{value: 0x2b1d, lo: 0xbc, hi: 0xbd},
 	{value: 0x2afd, lo: 0xbe, hi: 0xbf},
-	// Block 0x65, offset 0x346
+	// Block 0x64, offset 0x32b
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xa3},
 	{value: 0x0040, lo: 0xa4, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x66, offset 0x34a
+	// Block 0x65, offset 0x32f
 	{value: 0x0030, lo: 0x04},
 	{value: 0x2aa2, lo: 0x80, hi: 0x9d},
 	{value: 0x305a, lo: 0x9e, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0x9f},
 	{value: 0x30a2, lo: 0xa0, hi: 0xbf},
-	// Block 0x67, offset 0x34f
+	// Block 0x66, offset 0x334
 	{value: 0x0000, lo: 0x02},
-	{value: 0x0008, lo: 0x80, hi: 0x95},
-	{value: 0x0040, lo: 0x96, hi: 0xbf},
-	// Block 0x68, offset 0x352
+	{value: 0x0008, lo: 0x80, hi: 0xaa},
+	{value: 0x0040, lo: 0xab, hi: 0xbf},
+	// Block 0x67, offset 0x337
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0x8c},
 	{value: 0x0040, lo: 0x8d, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0xbf},
-	// Block 0x69, offset 0x356
+	// Block 0x68, offset 0x33b
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0xbd},
 	{value: 0x0018, lo: 0xbe, hi: 0xbf},
-	// Block 0x6a, offset 0x35b
+	// Block 0x69, offset 0x340
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x8c},
 	{value: 0x0018, lo: 0x8d, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xbf},
-	// Block 0x6b, offset 0x360
+	// Block 0x6a, offset 0x345
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0xa5},
 	{value: 0x0018, lo: 0xa6, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb1},
+	{value: 0x3308, lo: 0xb0, hi: 0xb1},
 	{value: 0x0018, lo: 0xb2, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbf},
-	// Block 0x6c, offset 0x366
+	// Block 0x6b, offset 0x34b
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0040, lo: 0x80, hi: 0xb6},
 	{value: 0x0008, lo: 0xb7, hi: 0xb7},
 	{value: 0x2009, lo: 0xb8, hi: 0xb8},
 	{value: 0x6e89, lo: 0xb9, hi: 0xb9},
 	{value: 0x0008, lo: 0xba, hi: 0xbf},
-	// Block 0x6d, offset 0x36c
+	// Block 0x6c, offset 0x351
 	{value: 0x0000, lo: 0x0e},
 	{value: 0x0008, lo: 0x80, hi: 0x81},
-	{value: 0x1308, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x82, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0x85},
-	{value: 0x1b08, lo: 0x86, hi: 0x86},
+	{value: 0x3b08, lo: 0x86, hi: 0x86},
 	{value: 0x0008, lo: 0x87, hi: 0x8a},
-	{value: 0x1308, lo: 0x8b, hi: 0x8b},
+	{value: 0x3308, lo: 0x8b, hi: 0x8b},
 	{value: 0x0008, lo: 0x8c, hi: 0xa2},
-	{value: 0x1008, lo: 0xa3, hi: 0xa4},
-	{value: 0x1308, lo: 0xa5, hi: 0xa6},
-	{value: 0x1008, lo: 0xa7, hi: 0xa7},
+	{value: 0x3008, lo: 0xa3, hi: 0xa4},
+	{value: 0x3308, lo: 0xa5, hi: 0xa6},
+	{value: 0x3008, lo: 0xa7, hi: 0xa7},
 	{value: 0x0018, lo: 0xa8, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0x6e, offset 0x37b
+	// Block 0x6d, offset 0x360
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0208, lo: 0x80, hi: 0xb1},
 	{value: 0x0108, lo: 0xb2, hi: 0xb2},
 	{value: 0x0008, lo: 0xb3, hi: 0xb3},
 	{value: 0x0018, lo: 0xb4, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbf},
-	// Block 0x6f, offset 0x381
+	// Block 0x6e, offset 0x366
 	{value: 0x0000, lo: 0x03},
-	{value: 0x1008, lo: 0x80, hi: 0x81},
+	{value: 0x3008, lo: 0x80, hi: 0x81},
 	{value: 0x0008, lo: 0x82, hi: 0xb3},
-	{value: 0x1008, lo: 0xb4, hi: 0xbf},
-	// Block 0x70, offset 0x385
+	{value: 0x3008, lo: 0xb4, hi: 0xbf},
+	// Block 0x6f, offset 0x36a
 	{value: 0x0000, lo: 0x0e},
-	{value: 0x1008, lo: 0x80, hi: 0x83},
-	{value: 0x1b08, lo: 0x84, hi: 0x84},
-	{value: 0x1308, lo: 0x85, hi: 0x85},
+	{value: 0x3008, lo: 0x80, hi: 0x83},
+	{value: 0x3b08, lo: 0x84, hi: 0x84},
+	{value: 0x3308, lo: 0x85, hi: 0x85},
 	{value: 0x0040, lo: 0x86, hi: 0x8d},
 	{value: 0x0018, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9f},
-	{value: 0x1308, lo: 0xa0, hi: 0xb1},
+	{value: 0x3308, lo: 0xa0, hi: 0xb1},
 	{value: 0x0008, lo: 0xb2, hi: 0xb7},
 	{value: 0x0018, lo: 0xb8, hi: 0xba},
 	{value: 0x0008, lo: 0xbb, hi: 0xbb},
 	{value: 0x0018, lo: 0xbc, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbf},
-	// Block 0x71, offset 0x394
+	// Block 0x70, offset 0x379
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xa5},
-	{value: 0x1308, lo: 0xa6, hi: 0xad},
+	{value: 0x3308, lo: 0xa6, hi: 0xad},
 	{value: 0x0018, lo: 0xae, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x72, offset 0x399
+	// Block 0x71, offset 0x37e
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
-	{value: 0x1308, lo: 0x87, hi: 0x91},
-	{value: 0x1008, lo: 0x92, hi: 0x92},
-	{value: 0x1808, lo: 0x93, hi: 0x93},
+	{value: 0x3308, lo: 0x87, hi: 0x91},
+	{value: 0x3008, lo: 0x92, hi: 0x92},
+	{value: 0x3808, lo: 0x93, hi: 0x93},
 	{value: 0x0040, lo: 0x94, hi: 0x9e},
 	{value: 0x0018, lo: 0x9f, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbf},
-	// Block 0x73, offset 0x3a1
+	// Block 0x72, offset 0x386
 	{value: 0x0000, lo: 0x09},
-	{value: 0x1308, lo: 0x80, hi: 0x82},
-	{value: 0x1008, lo: 0x83, hi: 0x83},
+	{value: 0x3308, lo: 0x80, hi: 0x82},
+	{value: 0x3008, lo: 0x83, hi: 0x83},
 	{value: 0x0008, lo: 0x84, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xb3},
-	{value: 0x1008, lo: 0xb4, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xb9},
-	{value: 0x1008, lo: 0xba, hi: 0xbb},
-	{value: 0x1308, lo: 0xbc, hi: 0xbc},
-	{value: 0x1008, lo: 0xbd, hi: 0xbf},
-	// Block 0x74, offset 0x3ab
+	{value: 0x3308, lo: 0xb3, hi: 0xb3},
+	{value: 0x3008, lo: 0xb4, hi: 0xb5},
+	{value: 0x3308, lo: 0xb6, hi: 0xb9},
+	{value: 0x3008, lo: 0xba, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbc},
+	{value: 0x3008, lo: 0xbd, hi: 0xbf},
+	// Block 0x73, offset 0x390
 	{value: 0x0000, lo: 0x0a},
-	{value: 0x1808, lo: 0x80, hi: 0x80},
+	{value: 0x3808, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8e},
 	{value: 0x0008, lo: 0x8f, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9d},
 	{value: 0x0018, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xa4},
-	{value: 0x1308, lo: 0xa5, hi: 0xa5},
+	{value: 0x3308, lo: 0xa5, hi: 0xa5},
 	{value: 0x0008, lo: 0xa6, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0x75, offset 0x3b6
+	// Block 0x74, offset 0x39b
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0xa8},
-	{value: 0x1308, lo: 0xa9, hi: 0xae},
-	{value: 0x1008, lo: 0xaf, hi: 0xb0},
-	{value: 0x1308, lo: 0xb1, hi: 0xb2},
-	{value: 0x1008, lo: 0xb3, hi: 0xb4},
-	{value: 0x1308, lo: 0xb5, hi: 0xb6},
+	{value: 0x3308, lo: 0xa9, hi: 0xae},
+	{value: 0x3008, lo: 0xaf, hi: 0xb0},
+	{value: 0x3308, lo: 0xb1, hi: 0xb2},
+	{value: 0x3008, lo: 0xb3, hi: 0xb4},
+	{value: 0x3308, lo: 0xb5, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0x76, offset 0x3be
+	// Block 0x75, offset 0x3a3
 	{value: 0x0000, lo: 0x10},
 	{value: 0x0008, lo: 0x80, hi: 0x82},
-	{value: 0x1308, lo: 0x83, hi: 0x83},
+	{value: 0x3308, lo: 0x83, hi: 0x83},
 	{value: 0x0008, lo: 0x84, hi: 0x8b},
-	{value: 0x1308, lo: 0x8c, hi: 0x8c},
-	{value: 0x1008, lo: 0x8d, hi: 0x8d},
+	{value: 0x3308, lo: 0x8c, hi: 0x8c},
+	{value: 0x3008, lo: 0x8d, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9b},
@@ -3432,38 +3437,38 @@
 	{value: 0x0008, lo: 0xa0, hi: 0xb6},
 	{value: 0x0018, lo: 0xb7, hi: 0xb9},
 	{value: 0x0008, lo: 0xba, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbb},
-	{value: 0x1308, lo: 0xbc, hi: 0xbc},
-	{value: 0x1008, lo: 0xbd, hi: 0xbd},
+	{value: 0x3008, lo: 0xbb, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbc},
+	{value: 0x3008, lo: 0xbd, hi: 0xbd},
 	{value: 0x0008, lo: 0xbe, hi: 0xbf},
-	// Block 0x77, offset 0x3cf
+	// Block 0x76, offset 0x3b4
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0008, lo: 0x80, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb0},
+	{value: 0x3308, lo: 0xb0, hi: 0xb0},
 	{value: 0x0008, lo: 0xb1, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb4},
+	{value: 0x3308, lo: 0xb2, hi: 0xb4},
 	{value: 0x0008, lo: 0xb5, hi: 0xb6},
-	{value: 0x1308, lo: 0xb7, hi: 0xb8},
+	{value: 0x3308, lo: 0xb7, hi: 0xb8},
 	{value: 0x0008, lo: 0xb9, hi: 0xbd},
-	{value: 0x1308, lo: 0xbe, hi: 0xbf},
-	// Block 0x78, offset 0x3d8
+	{value: 0x3308, lo: 0xbe, hi: 0xbf},
+	// Block 0x77, offset 0x3bd
 	{value: 0x0000, lo: 0x0f},
 	{value: 0x0008, lo: 0x80, hi: 0x80},
-	{value: 0x1308, lo: 0x81, hi: 0x81},
+	{value: 0x3308, lo: 0x81, hi: 0x81},
 	{value: 0x0008, lo: 0x82, hi: 0x82},
 	{value: 0x0040, lo: 0x83, hi: 0x9a},
 	{value: 0x0008, lo: 0x9b, hi: 0x9d},
 	{value: 0x0018, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xaa},
-	{value: 0x1008, lo: 0xab, hi: 0xab},
-	{value: 0x1308, lo: 0xac, hi: 0xad},
-	{value: 0x1008, lo: 0xae, hi: 0xaf},
+	{value: 0x3008, lo: 0xab, hi: 0xab},
+	{value: 0x3308, lo: 0xac, hi: 0xad},
+	{value: 0x3008, lo: 0xae, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb1},
 	{value: 0x0008, lo: 0xb2, hi: 0xb4},
-	{value: 0x1008, lo: 0xb5, hi: 0xb5},
-	{value: 0x1b08, lo: 0xb6, hi: 0xb6},
+	{value: 0x3008, lo: 0xb5, hi: 0xb5},
+	{value: 0x3b08, lo: 0xb6, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0x79, offset 0x3e8
+	// Block 0x78, offset 0x3cd
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0x86},
@@ -3477,7 +3482,7 @@
 	{value: 0x0008, lo: 0xa8, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x7a, offset 0x3f5
+	// Block 0x79, offset 0x3da
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x9a},
 	{value: 0x0018, lo: 0x9b, hi: 0x9b},
@@ -3488,54 +3493,54 @@
 	{value: 0x0008, lo: 0xa0, hi: 0xa5},
 	{value: 0x0040, lo: 0xa6, hi: 0xaf},
 	{value: 0x4495, lo: 0xb0, hi: 0xbf},
-	// Block 0x7b, offset 0x3ff
+	// Block 0x7a, offset 0x3e4
 	{value: 0x0000, lo: 0x04},
 	{value: 0x44b5, lo: 0x80, hi: 0x8f},
 	{value: 0x44d5, lo: 0x90, hi: 0x9f},
 	{value: 0x44f5, lo: 0xa0, hi: 0xaf},
 	{value: 0x44d5, lo: 0xb0, hi: 0xbf},
-	// Block 0x7c, offset 0x404
+	// Block 0x7b, offset 0x3e9
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0008, lo: 0x80, hi: 0xa2},
-	{value: 0x1008, lo: 0xa3, hi: 0xa4},
-	{value: 0x1308, lo: 0xa5, hi: 0xa5},
-	{value: 0x1008, lo: 0xa6, hi: 0xa7},
-	{value: 0x1308, lo: 0xa8, hi: 0xa8},
-	{value: 0x1008, lo: 0xa9, hi: 0xaa},
+	{value: 0x3008, lo: 0xa3, hi: 0xa4},
+	{value: 0x3308, lo: 0xa5, hi: 0xa5},
+	{value: 0x3008, lo: 0xa6, hi: 0xa7},
+	{value: 0x3308, lo: 0xa8, hi: 0xa8},
+	{value: 0x3008, lo: 0xa9, hi: 0xaa},
 	{value: 0x0018, lo: 0xab, hi: 0xab},
-	{value: 0x1008, lo: 0xac, hi: 0xac},
-	{value: 0x1b08, lo: 0xad, hi: 0xad},
+	{value: 0x3008, lo: 0xac, hi: 0xac},
+	{value: 0x3b08, lo: 0xad, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0x7d, offset 0x411
+	// Block 0x7c, offset 0x3f6
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xa3},
 	{value: 0x0040, lo: 0xa4, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xbf},
-	// Block 0x7e, offset 0x415
+	// Block 0x7d, offset 0x3fa
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x8a},
 	{value: 0x0018, lo: 0x8b, hi: 0xbb},
 	{value: 0x0040, lo: 0xbc, hi: 0xbf},
-	// Block 0x7f, offset 0x41a
+	// Block 0x7e, offset 0x3ff
 	{value: 0x0020, lo: 0x01},
 	{value: 0x4515, lo: 0x80, hi: 0xbf},
-	// Block 0x80, offset 0x41c
+	// Block 0x7f, offset 0x401
 	{value: 0x0020, lo: 0x03},
 	{value: 0x4d15, lo: 0x80, hi: 0x94},
 	{value: 0x4ad5, lo: 0x95, hi: 0x95},
 	{value: 0x4fb5, lo: 0x96, hi: 0xbf},
-	// Block 0x81, offset 0x420
+	// Block 0x80, offset 0x405
 	{value: 0x0020, lo: 0x01},
 	{value: 0x54f5, lo: 0x80, hi: 0xbf},
-	// Block 0x82, offset 0x422
+	// Block 0x81, offset 0x407
 	{value: 0x0020, lo: 0x03},
 	{value: 0x5cf5, lo: 0x80, hi: 0x84},
 	{value: 0x5655, lo: 0x85, hi: 0x85},
 	{value: 0x5d95, lo: 0x86, hi: 0xbf},
-	// Block 0x83, offset 0x426
+	// Block 0x82, offset 0x40b
 	{value: 0x0020, lo: 0x08},
 	{value: 0x6b55, lo: 0x80, hi: 0x8f},
 	{value: 0x6d15, lo: 0x90, hi: 0x90},
@@ -3545,19 +3550,19 @@
 	{value: 0x0040, lo: 0xae, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xaf},
 	{value: 0x70d5, lo: 0xb0, hi: 0xbf},
-	// Block 0x84, offset 0x42f
+	// Block 0x83, offset 0x414
 	{value: 0x0020, lo: 0x05},
 	{value: 0x72d5, lo: 0x80, hi: 0xad},
 	{value: 0x6535, lo: 0xae, hi: 0xae},
 	{value: 0x7895, lo: 0xaf, hi: 0xb5},
 	{value: 0x6f55, lo: 0xb6, hi: 0xb6},
 	{value: 0x7975, lo: 0xb7, hi: 0xbf},
-	// Block 0x85, offset 0x435
+	// Block 0x84, offset 0x41a
 	{value: 0x0028, lo: 0x03},
 	{value: 0x7c21, lo: 0x80, hi: 0x82},
 	{value: 0x7be1, lo: 0x83, hi: 0x83},
 	{value: 0x7c99, lo: 0x84, hi: 0xbf},
-	// Block 0x86, offset 0x439
+	// Block 0x85, offset 0x41e
 	{value: 0x0038, lo: 0x0f},
 	{value: 0x9db1, lo: 0x80, hi: 0x83},
 	{value: 0x9e59, lo: 0x84, hi: 0x85},
@@ -3574,7 +3579,7 @@
 	{value: 0xa869, lo: 0xbc, hi: 0xbc},
 	{value: 0xa7f9, lo: 0xbd, hi: 0xbd},
 	{value: 0xa8d9, lo: 0xbe, hi: 0xbf},
-	// Block 0x87, offset 0x449
+	// Block 0x86, offset 0x42e
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x8c},
@@ -3585,24 +3590,24 @@
 	{value: 0x0008, lo: 0xbc, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbe},
 	{value: 0x0008, lo: 0xbf, hi: 0xbf},
-	// Block 0x88, offset 0x453
+	// Block 0x87, offset 0x438
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0xbf},
-	// Block 0x89, offset 0x458
+	// Block 0x88, offset 0x43d
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbf},
-	// Block 0x8a, offset 0x45b
+	// Block 0x89, offset 0x440
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x82},
 	{value: 0x0040, lo: 0x83, hi: 0x86},
 	{value: 0x0018, lo: 0x87, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xb6},
 	{value: 0x0018, lo: 0xb7, hi: 0xbf},
-	// Block 0x8b, offset 0x461
+	// Block 0x8a, offset 0x446
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0018, lo: 0x80, hi: 0x8e},
 	{value: 0x0040, lo: 0x8f, hi: 0x8f},
@@ -3610,31 +3615,31 @@
 	{value: 0x0040, lo: 0x9c, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xa0},
 	{value: 0x0040, lo: 0xa1, hi: 0xbf},
-	// Block 0x8c, offset 0x468
+	// Block 0x8b, offset 0x44d
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0040, lo: 0x80, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0xbc},
-	{value: 0x1308, lo: 0xbd, hi: 0xbd},
+	{value: 0x3308, lo: 0xbd, hi: 0xbd},
 	{value: 0x0040, lo: 0xbe, hi: 0xbf},
-	// Block 0x8d, offset 0x46d
+	// Block 0x8c, offset 0x452
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0x9c},
 	{value: 0x0040, lo: 0x9d, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x8e, offset 0x471
+	// Block 0x8d, offset 0x456
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0x90},
 	{value: 0x0040, lo: 0x91, hi: 0x9f},
-	{value: 0x1308, lo: 0xa0, hi: 0xa0},
+	{value: 0x3308, lo: 0xa0, hi: 0xa0},
 	{value: 0x0018, lo: 0xa1, hi: 0xbb},
 	{value: 0x0040, lo: 0xbc, hi: 0xbf},
-	// Block 0x8f, offset 0x477
+	// Block 0x8e, offset 0x45c
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xa3},
-	{value: 0x0040, lo: 0xa4, hi: 0xaf},
-	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x90, offset 0x47c
+	{value: 0x0040, lo: 0xa4, hi: 0xac},
+	{value: 0x0008, lo: 0xad, hi: 0xbf},
+	// Block 0x8f, offset 0x461
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0008, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x81},
@@ -3642,22 +3647,22 @@
 	{value: 0x0018, lo: 0x8a, hi: 0x8a},
 	{value: 0x0040, lo: 0x8b, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xba},
+	{value: 0x3308, lo: 0xb6, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbf},
-	// Block 0x91, offset 0x485
+	// Block 0x90, offset 0x46a
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0x9e},
 	{value: 0x0018, lo: 0x9f, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0x92, offset 0x48a
+	// Block 0x91, offset 0x46f
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x87},
 	{value: 0x0008, lo: 0x88, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0xbf},
-	// Block 0x93, offset 0x490
+	// Block 0x92, offset 0x475
 	{value: 0x0000, lo: 0x06},
 	{value: 0xe145, lo: 0x80, hi: 0x87},
 	{value: 0xe1c5, lo: 0x88, hi: 0x8f},
@@ -3665,7 +3670,7 @@
 	{value: 0x8ad5, lo: 0x98, hi: 0x9f},
 	{value: 0x8aed, lo: 0xa0, hi: 0xa7},
 	{value: 0x0008, lo: 0xa8, hi: 0xbf},
-	// Block 0x94, offset 0x497
+	// Block 0x93, offset 0x47c
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0008, lo: 0x80, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0x9f},
@@ -3673,7 +3678,7 @@
 	{value: 0x0040, lo: 0xaa, hi: 0xaf},
 	{value: 0x8aed, lo: 0xb0, hi: 0xb7},
 	{value: 0x8ad5, lo: 0xb8, hi: 0xbf},
-	// Block 0x95, offset 0x49e
+	// Block 0x94, offset 0x483
 	{value: 0x0000, lo: 0x06},
 	{value: 0xe145, lo: 0x80, hi: 0x87},
 	{value: 0xe1c5, lo: 0x88, hi: 0x8f},
@@ -3681,173 +3686,176 @@
 	{value: 0x0040, lo: 0x94, hi: 0x97},
 	{value: 0x0008, lo: 0x98, hi: 0xbb},
 	{value: 0x0040, lo: 0xbc, hi: 0xbf},
-	// Block 0x96, offset 0x4a5
+	// Block 0x95, offset 0x48a
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xa7},
 	{value: 0x0040, lo: 0xa8, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0x97, offset 0x4a9
+	// Block 0x96, offset 0x48e
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xa3},
 	{value: 0x0040, lo: 0xa4, hi: 0xae},
 	{value: 0x0018, lo: 0xaf, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
-	// Block 0x98, offset 0x4ae
+	// Block 0x97, offset 0x493
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0x99, offset 0x4b1
+	// Block 0x98, offset 0x496
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xa7},
 	{value: 0x0040, lo: 0xa8, hi: 0xbf},
-	// Block 0x9a, offset 0x4b6
+	// Block 0x99, offset 0x49b
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x0008, lo: 0x80, hi: 0x85},
+	{value: 0x0808, lo: 0x80, hi: 0x85},
 	{value: 0x0040, lo: 0x86, hi: 0x87},
-	{value: 0x0008, lo: 0x88, hi: 0x88},
+	{value: 0x0808, lo: 0x88, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
-	{value: 0x0008, lo: 0x8a, hi: 0xb5},
+	{value: 0x0808, lo: 0x8a, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xb6},
-	{value: 0x0008, lo: 0xb7, hi: 0xb8},
+	{value: 0x0808, lo: 0xb7, hi: 0xb8},
 	{value: 0x0040, lo: 0xb9, hi: 0xbb},
-	{value: 0x0008, lo: 0xbc, hi: 0xbc},
+	{value: 0x0808, lo: 0xbc, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbe},
-	{value: 0x0008, lo: 0xbf, hi: 0xbf},
-	// Block 0x9b, offset 0x4c2
+	{value: 0x0808, lo: 0xbf, hi: 0xbf},
+	// Block 0x9a, offset 0x4a7
 	{value: 0x0000, lo: 0x05},
-	{value: 0x0008, lo: 0x80, hi: 0x95},
+	{value: 0x0808, lo: 0x80, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0x96},
-	{value: 0x0018, lo: 0x97, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xb6},
-	{value: 0x0018, lo: 0xb7, hi: 0xbf},
-	// Block 0x9c, offset 0x4c8
+	{value: 0x0818, lo: 0x97, hi: 0x9f},
+	{value: 0x0808, lo: 0xa0, hi: 0xb6},
+	{value: 0x0818, lo: 0xb7, hi: 0xbf},
+	// Block 0x9b, offset 0x4ad
 	{value: 0x0000, lo: 0x04},
-	{value: 0x0008, lo: 0x80, hi: 0x9e},
+	{value: 0x0808, lo: 0x80, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0xa6},
-	{value: 0x0018, lo: 0xa7, hi: 0xaf},
+	{value: 0x0818, lo: 0xa7, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
-	// Block 0x9d, offset 0x4cd
+	// Block 0x9c, offset 0x4b2
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0040, lo: 0x80, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xb2},
+	{value: 0x0808, lo: 0xa0, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xb3},
-	{value: 0x0008, lo: 0xb4, hi: 0xb5},
+	{value: 0x0808, lo: 0xb4, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xba},
-	{value: 0x0018, lo: 0xbb, hi: 0xbf},
-	// Block 0x9e, offset 0x4d4
+	{value: 0x0818, lo: 0xbb, hi: 0xbf},
+	// Block 0x9d, offset 0x4b9
 	{value: 0x0000, lo: 0x07},
-	{value: 0x0008, lo: 0x80, hi: 0x95},
-	{value: 0x0018, lo: 0x96, hi: 0x9b},
+	{value: 0x0808, lo: 0x80, hi: 0x95},
+	{value: 0x0818, lo: 0x96, hi: 0x9b},
 	{value: 0x0040, lo: 0x9c, hi: 0x9e},
 	{value: 0x0018, lo: 0x9f, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xb9},
+	{value: 0x0808, lo: 0xa0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbe},
-	{value: 0x0018, lo: 0xbf, hi: 0xbf},
-	// Block 0x9f, offset 0x4dc
+	{value: 0x0818, lo: 0xbf, hi: 0xbf},
+	// Block 0x9e, offset 0x4c1
 	{value: 0x0000, lo: 0x04},
-	{value: 0x0008, lo: 0x80, hi: 0xb7},
+	{value: 0x0808, lo: 0x80, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbb},
-	{value: 0x0018, lo: 0xbc, hi: 0xbd},
-	{value: 0x0008, lo: 0xbe, hi: 0xbf},
-	// Block 0xa0, offset 0x4e1
+	{value: 0x0818, lo: 0xbc, hi: 0xbd},
+	{value: 0x0808, lo: 0xbe, hi: 0xbf},
+	// Block 0x9f, offset 0x4c6
 	{value: 0x0000, lo: 0x03},
-	{value: 0x0018, lo: 0x80, hi: 0x8f},
+	{value: 0x0818, lo: 0x80, hi: 0x8f},
 	{value: 0x0040, lo: 0x90, hi: 0x91},
-	{value: 0x0018, lo: 0x92, hi: 0xbf},
-	// Block 0xa1, offset 0x4e5
+	{value: 0x0818, lo: 0x92, hi: 0xbf},
+	// Block 0xa0, offset 0x4ca
 	{value: 0x0000, lo: 0x0f},
-	{value: 0x0008, lo: 0x80, hi: 0x80},
-	{value: 0x1308, lo: 0x81, hi: 0x83},
+	{value: 0x0808, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x81, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x84},
-	{value: 0x1308, lo: 0x85, hi: 0x86},
+	{value: 0x3308, lo: 0x85, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x8b},
-	{value: 0x1308, lo: 0x8c, hi: 0x8f},
-	{value: 0x0008, lo: 0x90, hi: 0x93},
+	{value: 0x3308, lo: 0x8c, hi: 0x8f},
+	{value: 0x0808, lo: 0x90, hi: 0x93},
 	{value: 0x0040, lo: 0x94, hi: 0x94},
-	{value: 0x0008, lo: 0x95, hi: 0x97},
+	{value: 0x0808, lo: 0x95, hi: 0x97},
 	{value: 0x0040, lo: 0x98, hi: 0x98},
-	{value: 0x0008, lo: 0x99, hi: 0xb3},
+	{value: 0x0808, lo: 0x99, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xb7},
-	{value: 0x1308, lo: 0xb8, hi: 0xba},
+	{value: 0x3308, lo: 0xb8, hi: 0xba},
 	{value: 0x0040, lo: 0xbb, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0xa2, offset 0x4f5
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0xa1, offset 0x4da
 	{value: 0x0000, lo: 0x06},
-	{value: 0x0018, lo: 0x80, hi: 0x87},
+	{value: 0x0818, lo: 0x80, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
-	{value: 0x0018, lo: 0x90, hi: 0x98},
+	{value: 0x0818, lo: 0x90, hi: 0x98},
 	{value: 0x0040, lo: 0x99, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xbc},
-	{value: 0x0018, lo: 0xbd, hi: 0xbf},
-	// Block 0xa3, offset 0x4fc
+	{value: 0x0808, lo: 0xa0, hi: 0xbc},
+	{value: 0x0818, lo: 0xbd, hi: 0xbf},
+	// Block 0xa2, offset 0x4e1
 	{value: 0x0000, lo: 0x03},
-	{value: 0x0008, lo: 0x80, hi: 0x9c},
-	{value: 0x0018, lo: 0x9d, hi: 0x9f},
+	{value: 0x0808, lo: 0x80, hi: 0x9c},
+	{value: 0x0818, lo: 0x9d, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xbf},
-	// Block 0xa4, offset 0x500
+	// Block 0xa3, offset 0x4e5
 	{value: 0x0000, lo: 0x03},
-	{value: 0x0008, lo: 0x80, hi: 0xb5},
+	{value: 0x0808, lo: 0x80, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xb8},
 	{value: 0x0018, lo: 0xb9, hi: 0xbf},
-	// Block 0xa5, offset 0x504
+	// Block 0xa4, offset 0x4e9
 	{value: 0x0000, lo: 0x06},
-	{value: 0x0008, lo: 0x80, hi: 0x95},
+	{value: 0x0808, lo: 0x80, hi: 0x95},
 	{value: 0x0040, lo: 0x96, hi: 0x97},
-	{value: 0x0018, lo: 0x98, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xb2},
+	{value: 0x0818, lo: 0x98, hi: 0x9f},
+	{value: 0x0808, lo: 0xa0, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xb7},
-	{value: 0x0018, lo: 0xb8, hi: 0xbf},
-	// Block 0xa6, offset 0x50b
+	{value: 0x0818, lo: 0xb8, hi: 0xbf},
+	// Block 0xa5, offset 0x4f0
+	{value: 0x0000, lo: 0x01},
+	{value: 0x0808, lo: 0x80, hi: 0xbf},
+	// Block 0xa6, offset 0x4f2
 	{value: 0x0000, lo: 0x02},
-	{value: 0x0008, lo: 0x80, hi: 0x88},
+	{value: 0x0808, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0xbf},
-	// Block 0xa7, offset 0x50e
+	// Block 0xa7, offset 0x4f5
 	{value: 0x0000, lo: 0x02},
 	{value: 0x03dd, lo: 0x80, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xbf},
-	// Block 0xa8, offset 0x511
+	// Block 0xa8, offset 0x4f8
 	{value: 0x0000, lo: 0x03},
-	{value: 0x0008, lo: 0x80, hi: 0xb2},
+	{value: 0x0808, lo: 0x80, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xb9},
-	{value: 0x0018, lo: 0xba, hi: 0xbf},
-	// Block 0xa9, offset 0x515
+	{value: 0x0818, lo: 0xba, hi: 0xbf},
+	// Block 0xa9, offset 0x4fc
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0040, lo: 0x80, hi: 0x9f},
-	{value: 0x0018, lo: 0xa0, hi: 0xbe},
+	{value: 0x0818, lo: 0xa0, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xaa, offset 0x519
+	// Block 0xaa, offset 0x500
 	{value: 0x0000, lo: 0x05},
-	{value: 0x1008, lo: 0x80, hi: 0x80},
-	{value: 0x1308, lo: 0x81, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x82},
+	{value: 0x3008, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x81, hi: 0x81},
+	{value: 0x3008, lo: 0x82, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0xb7},
-	{value: 0x1308, lo: 0xb8, hi: 0xbf},
-	// Block 0xab, offset 0x51f
+	{value: 0x3308, lo: 0xb8, hi: 0xbf},
+	// Block 0xab, offset 0x506
 	{value: 0x0000, lo: 0x08},
-	{value: 0x1308, lo: 0x80, hi: 0x85},
-	{value: 0x1b08, lo: 0x86, hi: 0x86},
+	{value: 0x3308, lo: 0x80, hi: 0x85},
+	{value: 0x3b08, lo: 0x86, hi: 0x86},
 	{value: 0x0018, lo: 0x87, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x91},
 	{value: 0x0018, lo: 0x92, hi: 0xa5},
 	{value: 0x0008, lo: 0xa6, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0xac, offset 0x528
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0xac, offset 0x50f
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x1308, lo: 0x80, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x80, hi: 0x81},
+	{value: 0x3008, lo: 0x82, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0xaf},
-	{value: 0x1008, lo: 0xb0, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xb6},
-	{value: 0x1008, lo: 0xb7, hi: 0xb8},
-	{value: 0x1b08, lo: 0xb9, hi: 0xb9},
-	{value: 0x1308, lo: 0xba, hi: 0xba},
+	{value: 0x3008, lo: 0xb0, hi: 0xb2},
+	{value: 0x3308, lo: 0xb3, hi: 0xb6},
+	{value: 0x3008, lo: 0xb7, hi: 0xb8},
+	{value: 0x3b08, lo: 0xb9, hi: 0xb9},
+	{value: 0x3308, lo: 0xba, hi: 0xba},
 	{value: 0x0018, lo: 0xbb, hi: 0xbc},
 	{value: 0x0340, lo: 0xbd, hi: 0xbd},
 	{value: 0x0018, lo: 0xbe, hi: 0xbf},
-	// Block 0xad, offset 0x534
+	// Block 0xad, offset 0x51b
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0018, lo: 0x80, hi: 0x81},
 	{value: 0x0040, lo: 0x82, hi: 0x8f},
@@ -3855,39 +3863,39 @@
 	{value: 0x0040, lo: 0xa9, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0xae, offset 0x53b
+	// Block 0xae, offset 0x522
 	{value: 0x0000, lo: 0x08},
-	{value: 0x1308, lo: 0x80, hi: 0x82},
+	{value: 0x3308, lo: 0x80, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0xa6},
-	{value: 0x1308, lo: 0xa7, hi: 0xab},
-	{value: 0x1008, lo: 0xac, hi: 0xac},
-	{value: 0x1308, lo: 0xad, hi: 0xb2},
-	{value: 0x1b08, lo: 0xb3, hi: 0xb4},
+	{value: 0x3308, lo: 0xa7, hi: 0xab},
+	{value: 0x3008, lo: 0xac, hi: 0xac},
+	{value: 0x3308, lo: 0xad, hi: 0xb2},
+	{value: 0x3b08, lo: 0xb3, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xb5},
 	{value: 0x0008, lo: 0xb6, hi: 0xbf},
-	// Block 0xaf, offset 0x544
+	// Block 0xaf, offset 0x52b
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0018, lo: 0x80, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xb3},
+	{value: 0x3308, lo: 0xb3, hi: 0xb3},
 	{value: 0x0018, lo: 0xb4, hi: 0xb5},
 	{value: 0x0008, lo: 0xb6, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0xb0, offset 0x54c
+	// Block 0xb0, offset 0x533
 	{value: 0x0000, lo: 0x06},
-	{value: 0x1308, lo: 0x80, hi: 0x81},
-	{value: 0x1008, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x80, hi: 0x81},
+	{value: 0x3008, lo: 0x82, hi: 0x82},
 	{value: 0x0008, lo: 0x83, hi: 0xb2},
-	{value: 0x1008, lo: 0xb3, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xbe},
-	{value: 0x1008, lo: 0xbf, hi: 0xbf},
-	// Block 0xb1, offset 0x553
+	{value: 0x3008, lo: 0xb3, hi: 0xb5},
+	{value: 0x3308, lo: 0xb6, hi: 0xbe},
+	{value: 0x3008, lo: 0xbf, hi: 0xbf},
+	// Block 0xb1, offset 0x53a
 	{value: 0x0000, lo: 0x0d},
-	{value: 0x1808, lo: 0x80, hi: 0x80},
+	{value: 0x3808, lo: 0x80, hi: 0x80},
 	{value: 0x0008, lo: 0x81, hi: 0x84},
 	{value: 0x0018, lo: 0x85, hi: 0x89},
-	{value: 0x1308, lo: 0x8a, hi: 0x8c},
+	{value: 0x3308, lo: 0x8a, hi: 0x8c},
 	{value: 0x0018, lo: 0x8d, hi: 0x8d},
 	{value: 0x0040, lo: 0x8e, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x9a},
@@ -3897,21 +3905,21 @@
 	{value: 0x0040, lo: 0xa0, hi: 0xa0},
 	{value: 0x0018, lo: 0xa1, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
-	// Block 0xb2, offset 0x561
+	// Block 0xb2, offset 0x548
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0008, lo: 0x80, hi: 0x91},
 	{value: 0x0040, lo: 0x92, hi: 0x92},
 	{value: 0x0008, lo: 0x93, hi: 0xab},
-	{value: 0x1008, lo: 0xac, hi: 0xae},
-	{value: 0x1308, lo: 0xaf, hi: 0xb1},
-	{value: 0x1008, lo: 0xb2, hi: 0xb3},
-	{value: 0x1308, lo: 0xb4, hi: 0xb4},
-	{value: 0x1808, lo: 0xb5, hi: 0xb5},
-	{value: 0x1308, lo: 0xb6, hi: 0xb7},
+	{value: 0x3008, lo: 0xac, hi: 0xae},
+	{value: 0x3308, lo: 0xaf, hi: 0xb1},
+	{value: 0x3008, lo: 0xb2, hi: 0xb3},
+	{value: 0x3308, lo: 0xb4, hi: 0xb4},
+	{value: 0x3808, lo: 0xb5, hi: 0xb5},
+	{value: 0x3308, lo: 0xb6, hi: 0xb7},
 	{value: 0x0018, lo: 0xb8, hi: 0xbd},
-	{value: 0x1308, lo: 0xbe, hi: 0xbe},
+	{value: 0x3308, lo: 0xbe, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xb3, offset 0x56e
+	// Block 0xb3, offset 0x555
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x87},
@@ -3925,28 +3933,28 @@
 	{value: 0x0018, lo: 0xa9, hi: 0xa9},
 	{value: 0x0040, lo: 0xaa, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbf},
-	// Block 0xb4, offset 0x57b
+	// Block 0xb4, offset 0x562
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0008, lo: 0x80, hi: 0x9e},
-	{value: 0x1308, lo: 0x9f, hi: 0x9f},
-	{value: 0x1008, lo: 0xa0, hi: 0xa2},
-	{value: 0x1308, lo: 0xa3, hi: 0xa9},
-	{value: 0x1b08, lo: 0xaa, hi: 0xaa},
+	{value: 0x3308, lo: 0x9f, hi: 0x9f},
+	{value: 0x3008, lo: 0xa0, hi: 0xa2},
+	{value: 0x3308, lo: 0xa3, hi: 0xa9},
+	{value: 0x3b08, lo: 0xaa, hi: 0xaa},
 	{value: 0x0040, lo: 0xab, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb9},
 	{value: 0x0040, lo: 0xba, hi: 0xbf},
-	// Block 0xb5, offset 0x584
+	// Block 0xb5, offset 0x56b
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xb4},
-	{value: 0x1008, lo: 0xb5, hi: 0xb7},
-	{value: 0x1308, lo: 0xb8, hi: 0xbf},
-	// Block 0xb6, offset 0x588
+	{value: 0x3008, lo: 0xb5, hi: 0xb7},
+	{value: 0x3308, lo: 0xb8, hi: 0xbf},
+	// Block 0xb6, offset 0x56f
 	{value: 0x0000, lo: 0x0d},
-	{value: 0x1008, lo: 0x80, hi: 0x81},
-	{value: 0x1b08, lo: 0x82, hi: 0x82},
-	{value: 0x1308, lo: 0x83, hi: 0x84},
-	{value: 0x1008, lo: 0x85, hi: 0x85},
-	{value: 0x1308, lo: 0x86, hi: 0x86},
+	{value: 0x3008, lo: 0x80, hi: 0x81},
+	{value: 0x3b08, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x83, hi: 0x84},
+	{value: 0x3008, lo: 0x85, hi: 0x85},
+	{value: 0x3308, lo: 0x86, hi: 0x86},
 	{value: 0x0008, lo: 0x87, hi: 0x8a},
 	{value: 0x0018, lo: 0x8b, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
@@ -3955,56 +3963,56 @@
 	{value: 0x0040, lo: 0x9c, hi: 0x9c},
 	{value: 0x0018, lo: 0x9d, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0xbf},
-	// Block 0xb7, offset 0x596
+	// Block 0xb7, offset 0x57d
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0xaf},
-	{value: 0x1008, lo: 0xb0, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xb8},
-	{value: 0x1008, lo: 0xb9, hi: 0xb9},
-	{value: 0x1308, lo: 0xba, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbe},
-	{value: 0x1308, lo: 0xbf, hi: 0xbf},
-	// Block 0xb8, offset 0x59e
+	{value: 0x3008, lo: 0xb0, hi: 0xb2},
+	{value: 0x3308, lo: 0xb3, hi: 0xb8},
+	{value: 0x3008, lo: 0xb9, hi: 0xb9},
+	{value: 0x3308, lo: 0xba, hi: 0xba},
+	{value: 0x3008, lo: 0xbb, hi: 0xbe},
+	{value: 0x3308, lo: 0xbf, hi: 0xbf},
+	// Block 0xb8, offset 0x585
 	{value: 0x0000, lo: 0x0a},
-	{value: 0x1308, lo: 0x80, hi: 0x80},
-	{value: 0x1008, lo: 0x81, hi: 0x81},
-	{value: 0x1b08, lo: 0x82, hi: 0x82},
-	{value: 0x1308, lo: 0x83, hi: 0x83},
+	{value: 0x3308, lo: 0x80, hi: 0x80},
+	{value: 0x3008, lo: 0x81, hi: 0x81},
+	{value: 0x3b08, lo: 0x82, hi: 0x82},
+	{value: 0x3308, lo: 0x83, hi: 0x83},
 	{value: 0x0008, lo: 0x84, hi: 0x85},
 	{value: 0x0018, lo: 0x86, hi: 0x86},
 	{value: 0x0008, lo: 0x87, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0xbf},
-	// Block 0xb9, offset 0x5a9
+	// Block 0xb9, offset 0x590
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0008, lo: 0x80, hi: 0xae},
-	{value: 0x1008, lo: 0xaf, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb5},
+	{value: 0x3008, lo: 0xaf, hi: 0xb1},
+	{value: 0x3308, lo: 0xb2, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xb7},
-	{value: 0x1008, lo: 0xb8, hi: 0xbb},
-	{value: 0x1308, lo: 0xbc, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0xba, offset 0x5b2
+	{value: 0x3008, lo: 0xb8, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbd},
+	{value: 0x3008, lo: 0xbe, hi: 0xbe},
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0xba, offset 0x599
 	{value: 0x0000, lo: 0x05},
-	{value: 0x1308, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x97},
 	{value: 0x0008, lo: 0x98, hi: 0x9b},
-	{value: 0x1308, lo: 0x9c, hi: 0x9d},
+	{value: 0x3308, lo: 0x9c, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0xbf},
-	// Block 0xbb, offset 0x5b8
+	// Block 0xbb, offset 0x59f
 	{value: 0x0000, lo: 0x07},
 	{value: 0x0008, lo: 0x80, hi: 0xaf},
-	{value: 0x1008, lo: 0xb0, hi: 0xb2},
-	{value: 0x1308, lo: 0xb3, hi: 0xba},
-	{value: 0x1008, lo: 0xbb, hi: 0xbc},
-	{value: 0x1308, lo: 0xbd, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0xbc, offset 0x5c0
+	{value: 0x3008, lo: 0xb0, hi: 0xb2},
+	{value: 0x3308, lo: 0xb3, hi: 0xba},
+	{value: 0x3008, lo: 0xbb, hi: 0xbc},
+	{value: 0x3308, lo: 0xbd, hi: 0xbd},
+	{value: 0x3008, lo: 0xbe, hi: 0xbe},
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0xbc, offset 0x5a7
 	{value: 0x0000, lo: 0x08},
-	{value: 0x1308, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x83},
 	{value: 0x0008, lo: 0x84, hi: 0x84},
 	{value: 0x0040, lo: 0x85, hi: 0x8f},
@@ -4012,60 +4020,97 @@
 	{value: 0x0040, lo: 0x9a, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xac},
 	{value: 0x0040, lo: 0xad, hi: 0xbf},
-	// Block 0xbd, offset 0x5c9
+	// Block 0xbd, offset 0x5b0
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0xaa},
-	{value: 0x1308, lo: 0xab, hi: 0xab},
-	{value: 0x1008, lo: 0xac, hi: 0xac},
-	{value: 0x1308, lo: 0xad, hi: 0xad},
-	{value: 0x1008, lo: 0xae, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb5},
-	{value: 0x1808, lo: 0xb6, hi: 0xb6},
-	{value: 0x1308, lo: 0xb7, hi: 0xb7},
+	{value: 0x3308, lo: 0xab, hi: 0xab},
+	{value: 0x3008, lo: 0xac, hi: 0xac},
+	{value: 0x3308, lo: 0xad, hi: 0xad},
+	{value: 0x3008, lo: 0xae, hi: 0xaf},
+	{value: 0x3308, lo: 0xb0, hi: 0xb5},
+	{value: 0x3808, lo: 0xb6, hi: 0xb6},
+	{value: 0x3308, lo: 0xb7, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbf},
-	// Block 0xbe, offset 0x5d3
+	// Block 0xbe, offset 0x5ba
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x89},
 	{value: 0x0040, lo: 0x8a, hi: 0xbf},
-	// Block 0xbf, offset 0x5d6
+	// Block 0xbf, offset 0x5bd
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9c},
-	{value: 0x1308, lo: 0x9d, hi: 0x9f},
-	{value: 0x1008, lo: 0xa0, hi: 0xa1},
-	{value: 0x1308, lo: 0xa2, hi: 0xa5},
-	{value: 0x1008, lo: 0xa6, hi: 0xa6},
-	{value: 0x1308, lo: 0xa7, hi: 0xaa},
-	{value: 0x1b08, lo: 0xab, hi: 0xab},
+	{value: 0x3308, lo: 0x9d, hi: 0x9f},
+	{value: 0x3008, lo: 0xa0, hi: 0xa1},
+	{value: 0x3308, lo: 0xa2, hi: 0xa5},
+	{value: 0x3008, lo: 0xa6, hi: 0xa6},
+	{value: 0x3308, lo: 0xa7, hi: 0xaa},
+	{value: 0x3b08, lo: 0xab, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xb9},
 	{value: 0x0018, lo: 0xba, hi: 0xbf},
-	// Block 0xc0, offset 0x5e2
+	// Block 0xc0, offset 0x5c9
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0040, lo: 0x80, hi: 0x9f},
 	{value: 0x049d, lo: 0xa0, hi: 0xbf},
-	// Block 0xc1, offset 0x5e5
+	// Block 0xc1, offset 0x5cc
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xa9},
 	{value: 0x0018, lo: 0xaa, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xbe},
 	{value: 0x0008, lo: 0xbf, hi: 0xbf},
-	// Block 0xc2, offset 0x5ea
+	// Block 0xc2, offset 0x5d1
+	{value: 0x0000, lo: 0x0c},
+	{value: 0x0008, lo: 0x80, hi: 0x80},
+	{value: 0x3308, lo: 0x81, hi: 0x86},
+	{value: 0x3008, lo: 0x87, hi: 0x88},
+	{value: 0x3308, lo: 0x89, hi: 0x8a},
+	{value: 0x0008, lo: 0x8b, hi: 0xb2},
+	{value: 0x3308, lo: 0xb3, hi: 0xb3},
+	{value: 0x3b08, lo: 0xb4, hi: 0xb4},
+	{value: 0x3308, lo: 0xb5, hi: 0xb8},
+	{value: 0x3008, lo: 0xb9, hi: 0xb9},
+	{value: 0x0008, lo: 0xba, hi: 0xba},
+	{value: 0x3308, lo: 0xbb, hi: 0xbe},
+	{value: 0x0018, lo: 0xbf, hi: 0xbf},
+	// Block 0xc3, offset 0x5de
+	{value: 0x0000, lo: 0x08},
+	{value: 0x0018, lo: 0x80, hi: 0x86},
+	{value: 0x3b08, lo: 0x87, hi: 0x87},
+	{value: 0x0040, lo: 0x88, hi: 0x8f},
+	{value: 0x0008, lo: 0x90, hi: 0x90},
+	{value: 0x3308, lo: 0x91, hi: 0x96},
+	{value: 0x3008, lo: 0x97, hi: 0x98},
+	{value: 0x3308, lo: 0x99, hi: 0x9b},
+	{value: 0x0008, lo: 0x9c, hi: 0xbf},
+	// Block 0xc4, offset 0x5e7
+	{value: 0x0000, lo: 0x0b},
+	{value: 0x0008, lo: 0x80, hi: 0x83},
+	{value: 0x0040, lo: 0x84, hi: 0x85},
+	{value: 0x0008, lo: 0x86, hi: 0x89},
+	{value: 0x3308, lo: 0x8a, hi: 0x96},
+	{value: 0x3008, lo: 0x97, hi: 0x97},
+	{value: 0x3308, lo: 0x98, hi: 0x98},
+	{value: 0x3b08, lo: 0x99, hi: 0x99},
+	{value: 0x0018, lo: 0x9a, hi: 0x9c},
+	{value: 0x0040, lo: 0x9d, hi: 0x9d},
+	{value: 0x0018, lo: 0x9e, hi: 0xa2},
+	{value: 0x0040, lo: 0xa3, hi: 0xbf},
+	// Block 0xc5, offset 0x5f3
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xb8},
 	{value: 0x0040, lo: 0xb9, hi: 0xbf},
-	// Block 0xc3, offset 0x5ed
+	// Block 0xc6, offset 0x5f6
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x89},
 	{value: 0x0008, lo: 0x8a, hi: 0xae},
-	{value: 0x1008, lo: 0xaf, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb6},
+	{value: 0x3008, lo: 0xaf, hi: 0xaf},
+	{value: 0x3308, lo: 0xb0, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xb7},
-	{value: 0x1308, lo: 0xb8, hi: 0xbd},
-	{value: 0x1008, lo: 0xbe, hi: 0xbe},
-	{value: 0x1b08, lo: 0xbf, hi: 0xbf},
-	// Block 0xc4, offset 0x5f7
+	{value: 0x3308, lo: 0xb8, hi: 0xbd},
+	{value: 0x3008, lo: 0xbe, hi: 0xbe},
+	{value: 0x3b08, lo: 0xbf, hi: 0xbf},
+	// Block 0xc7, offset 0x600
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0008, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x85},
@@ -4075,42 +4120,65 @@
 	{value: 0x0040, lo: 0xad, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb1},
 	{value: 0x0008, lo: 0xb2, hi: 0xbf},
-	// Block 0xc5, offset 0x600
+	// Block 0xc8, offset 0x609
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x0008, lo: 0x80, hi: 0x8f},
 	{value: 0x0040, lo: 0x90, hi: 0x91},
-	{value: 0x1308, lo: 0x92, hi: 0xa7},
+	{value: 0x3308, lo: 0x92, hi: 0xa7},
 	{value: 0x0040, lo: 0xa8, hi: 0xa8},
-	{value: 0x1008, lo: 0xa9, hi: 0xa9},
-	{value: 0x1308, lo: 0xaa, hi: 0xb0},
-	{value: 0x1008, lo: 0xb1, hi: 0xb1},
-	{value: 0x1308, lo: 0xb2, hi: 0xb3},
-	{value: 0x1008, lo: 0xb4, hi: 0xb4},
-	{value: 0x1308, lo: 0xb5, hi: 0xb6},
+	{value: 0x3008, lo: 0xa9, hi: 0xa9},
+	{value: 0x3308, lo: 0xaa, hi: 0xb0},
+	{value: 0x3008, lo: 0xb1, hi: 0xb1},
+	{value: 0x3308, lo: 0xb2, hi: 0xb3},
+	{value: 0x3008, lo: 0xb4, hi: 0xb4},
+	{value: 0x3308, lo: 0xb5, hi: 0xb6},
 	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0xc6, offset 0x60c
+	// Block 0xc9, offset 0x615
+	{value: 0x0000, lo: 0x0c},
+	{value: 0x0008, lo: 0x80, hi: 0x86},
+	{value: 0x0040, lo: 0x87, hi: 0x87},
+	{value: 0x0008, lo: 0x88, hi: 0x89},
+	{value: 0x0040, lo: 0x8a, hi: 0x8a},
+	{value: 0x0008, lo: 0x8b, hi: 0xb0},
+	{value: 0x3308, lo: 0xb1, hi: 0xb6},
+	{value: 0x0040, lo: 0xb7, hi: 0xb9},
+	{value: 0x3308, lo: 0xba, hi: 0xba},
+	{value: 0x0040, lo: 0xbb, hi: 0xbb},
+	{value: 0x3308, lo: 0xbc, hi: 0xbd},
+	{value: 0x0040, lo: 0xbe, hi: 0xbe},
+	{value: 0x3308, lo: 0xbf, hi: 0xbf},
+	// Block 0xca, offset 0x622
+	{value: 0x0000, lo: 0x07},
+	{value: 0x3308, lo: 0x80, hi: 0x83},
+	{value: 0x3b08, lo: 0x84, hi: 0x85},
+	{value: 0x0008, lo: 0x86, hi: 0x86},
+	{value: 0x3308, lo: 0x87, hi: 0x87},
+	{value: 0x0040, lo: 0x88, hi: 0x8f},
+	{value: 0x0008, lo: 0x90, hi: 0x99},
+	{value: 0x0040, lo: 0x9a, hi: 0xbf},
+	// Block 0xcb, offset 0x62a
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0xbf},
-	// Block 0xc7, offset 0x60f
+	// Block 0xcc, offset 0x62d
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
-	// Block 0xc8, offset 0x614
+	// Block 0xcd, offset 0x632
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x83},
 	{value: 0x0040, lo: 0x84, hi: 0xbf},
-	// Block 0xc9, offset 0x617
+	// Block 0xce, offset 0x635
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xbf},
-	// Block 0xca, offset 0x61a
+	// Block 0xcf, offset 0x638
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0xbf},
-	// Block 0xcb, offset 0x61d
+	// Block 0xd0, offset 0x63b
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0008, lo: 0x80, hi: 0x9e},
 	{value: 0x0040, lo: 0x9f, hi: 0x9f},
@@ -4118,20 +4186,20 @@
 	{value: 0x0040, lo: 0xaa, hi: 0xad},
 	{value: 0x0018, lo: 0xae, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
-	// Block 0xcc, offset 0x624
+	// Block 0xd1, offset 0x642
 	{value: 0x0000, lo: 0x06},
 	{value: 0x0040, lo: 0x80, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb4},
+	{value: 0x3308, lo: 0xb0, hi: 0xb4},
 	{value: 0x0018, lo: 0xb5, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xbf},
-	// Block 0xcd, offset 0x62b
+	// Block 0xd2, offset 0x649
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xaf},
-	{value: 0x1308, lo: 0xb0, hi: 0xb6},
+	{value: 0x3308, lo: 0xb0, hi: 0xb6},
 	{value: 0x0018, lo: 0xb7, hi: 0xbf},
-	// Block 0xce, offset 0x62f
+	// Block 0xd3, offset 0x64d
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x0008, lo: 0x80, hi: 0x83},
 	{value: 0x0018, lo: 0x84, hi: 0x85},
@@ -4143,67 +4211,75 @@
 	{value: 0x0008, lo: 0xa3, hi: 0xb7},
 	{value: 0x0040, lo: 0xb8, hi: 0xbc},
 	{value: 0x0008, lo: 0xbd, hi: 0xbf},
-	// Block 0xcf, offset 0x63a
+	// Block 0xd4, offset 0x658
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x8f},
 	{value: 0x0040, lo: 0x90, hi: 0xbf},
-	// Block 0xd0, offset 0x63d
+	// Block 0xd5, offset 0x65b
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0008, lo: 0x80, hi: 0x84},
 	{value: 0x0040, lo: 0x85, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x90},
-	{value: 0x1008, lo: 0x91, hi: 0xbe},
+	{value: 0x3008, lo: 0x91, hi: 0xbe},
 	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xd1, offset 0x643
+	// Block 0xd6, offset 0x661
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0040, lo: 0x80, hi: 0x8e},
-	{value: 0x1308, lo: 0x8f, hi: 0x92},
+	{value: 0x3308, lo: 0x8f, hi: 0x92},
 	{value: 0x0008, lo: 0x93, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xbf},
-	// Block 0xd2, offset 0x648
+	// Block 0xd7, offset 0x666
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0040, lo: 0x80, hi: 0x9f},
-	{value: 0x0008, lo: 0xa0, hi: 0xa0},
-	{value: 0x0040, lo: 0xa1, hi: 0xbf},
-	// Block 0xd3, offset 0x64c
+	{value: 0x0008, lo: 0xa0, hi: 0xa1},
+	{value: 0x0040, lo: 0xa2, hi: 0xbf},
+	// Block 0xd8, offset 0x66a
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xac},
 	{value: 0x0040, lo: 0xad, hi: 0xbf},
-	// Block 0xd4, offset 0x64f
+	// Block 0xd9, offset 0x66d
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xb2},
 	{value: 0x0040, lo: 0xb3, hi: 0xbf},
-	// Block 0xd5, offset 0x652
+	// Block 0xda, offset 0x670
 	{value: 0x0000, lo: 0x02},
-	{value: 0x0008, lo: 0x80, hi: 0x81},
-	{value: 0x0040, lo: 0x82, hi: 0xbf},
-	// Block 0xd6, offset 0x655
+	{value: 0x0008, lo: 0x80, hi: 0x9e},
+	{value: 0x0040, lo: 0x9f, hi: 0xbf},
+	// Block 0xdb, offset 0x673
+	{value: 0x0000, lo: 0x02},
+	{value: 0x0040, lo: 0x80, hi: 0xaf},
+	{value: 0x0008, lo: 0xb0, hi: 0xbf},
+	// Block 0xdc, offset 0x676
+	{value: 0x0000, lo: 0x02},
+	{value: 0x0008, lo: 0x80, hi: 0xbb},
+	{value: 0x0040, lo: 0xbc, hi: 0xbf},
+	// Block 0xdd, offset 0x679
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0008, lo: 0x80, hi: 0xaa},
 	{value: 0x0040, lo: 0xab, hi: 0xaf},
 	{value: 0x0008, lo: 0xb0, hi: 0xbc},
 	{value: 0x0040, lo: 0xbd, hi: 0xbf},
-	// Block 0xd7, offset 0x65a
+	// Block 0xde, offset 0x67e
 	{value: 0x0000, lo: 0x09},
 	{value: 0x0008, lo: 0x80, hi: 0x88},
 	{value: 0x0040, lo: 0x89, hi: 0x8f},
 	{value: 0x0008, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9b},
 	{value: 0x0018, lo: 0x9c, hi: 0x9c},
-	{value: 0x1308, lo: 0x9d, hi: 0x9e},
+	{value: 0x3308, lo: 0x9d, hi: 0x9e},
 	{value: 0x0018, lo: 0x9f, hi: 0x9f},
 	{value: 0x03c0, lo: 0xa0, hi: 0xa3},
 	{value: 0x0040, lo: 0xa4, hi: 0xbf},
-	// Block 0xd8, offset 0x664
+	// Block 0xdf, offset 0x688
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0018, lo: 0x80, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xbf},
-	// Block 0xd9, offset 0x667
+	// Block 0xe0, offset 0x68b
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xa6},
 	{value: 0x0040, lo: 0xa7, hi: 0xa8},
 	{value: 0x0018, lo: 0xa9, hi: 0xbf},
-	// Block 0xda, offset 0x66b
+	// Block 0xe1, offset 0x68f
 	{value: 0x0000, lo: 0x0e},
 	{value: 0x0018, lo: 0x80, hi: 0x9d},
 	{value: 0xb5b9, lo: 0x9e, hi: 0x9e},
@@ -4213,127 +4289,127 @@
 	{value: 0xb719, lo: 0xa2, hi: 0xa2},
 	{value: 0xb781, lo: 0xa3, hi: 0xa3},
 	{value: 0xb7e9, lo: 0xa4, hi: 0xa4},
-	{value: 0x1018, lo: 0xa5, hi: 0xa6},
-	{value: 0x1318, lo: 0xa7, hi: 0xa9},
+	{value: 0x3018, lo: 0xa5, hi: 0xa6},
+	{value: 0x3318, lo: 0xa7, hi: 0xa9},
 	{value: 0x0018, lo: 0xaa, hi: 0xac},
-	{value: 0x1018, lo: 0xad, hi: 0xb2},
+	{value: 0x3018, lo: 0xad, hi: 0xb2},
 	{value: 0x0340, lo: 0xb3, hi: 0xba},
-	{value: 0x1318, lo: 0xbb, hi: 0xbf},
-	// Block 0xdb, offset 0x67a
+	{value: 0x3318, lo: 0xbb, hi: 0xbf},
+	// Block 0xe2, offset 0x69e
 	{value: 0x0000, lo: 0x0b},
-	{value: 0x1318, lo: 0x80, hi: 0x82},
+	{value: 0x3318, lo: 0x80, hi: 0x82},
 	{value: 0x0018, lo: 0x83, hi: 0x84},
-	{value: 0x1318, lo: 0x85, hi: 0x8b},
+	{value: 0x3318, lo: 0x85, hi: 0x8b},
 	{value: 0x0018, lo: 0x8c, hi: 0xa9},
-	{value: 0x1318, lo: 0xaa, hi: 0xad},
+	{value: 0x3318, lo: 0xaa, hi: 0xad},
 	{value: 0x0018, lo: 0xae, hi: 0xba},
 	{value: 0xb851, lo: 0xbb, hi: 0xbb},
 	{value: 0xb899, lo: 0xbc, hi: 0xbc},
 	{value: 0xb8e1, lo: 0xbd, hi: 0xbd},
 	{value: 0xb949, lo: 0xbe, hi: 0xbe},
 	{value: 0xb9b1, lo: 0xbf, hi: 0xbf},
-	// Block 0xdc, offset 0x686
+	// Block 0xe3, offset 0x6aa
 	{value: 0x0000, lo: 0x03},
 	{value: 0xba19, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0xa8},
 	{value: 0x0040, lo: 0xa9, hi: 0xbf},
-	// Block 0xdd, offset 0x68a
+	// Block 0xe4, offset 0x6ae
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x81},
-	{value: 0x1318, lo: 0x82, hi: 0x84},
+	{value: 0x3318, lo: 0x82, hi: 0x84},
 	{value: 0x0018, lo: 0x85, hi: 0x85},
 	{value: 0x0040, lo: 0x86, hi: 0xbf},
-	// Block 0xde, offset 0x68f
+	// Block 0xe5, offset 0x6b3
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xb1},
 	{value: 0x0040, lo: 0xb2, hi: 0xbf},
-	// Block 0xdf, offset 0x694
+	// Block 0xe6, offset 0x6b8
 	{value: 0x0000, lo: 0x03},
-	{value: 0x1308, lo: 0x80, hi: 0xb6},
+	{value: 0x3308, lo: 0x80, hi: 0xb6},
 	{value: 0x0018, lo: 0xb7, hi: 0xba},
-	{value: 0x1308, lo: 0xbb, hi: 0xbf},
-	// Block 0xe0, offset 0x698
+	{value: 0x3308, lo: 0xbb, hi: 0xbf},
+	// Block 0xe7, offset 0x6bc
 	{value: 0x0000, lo: 0x04},
-	{value: 0x1308, lo: 0x80, hi: 0xac},
+	{value: 0x3308, lo: 0x80, hi: 0xac},
 	{value: 0x0018, lo: 0xad, hi: 0xb4},
-	{value: 0x1308, lo: 0xb5, hi: 0xb5},
+	{value: 0x3308, lo: 0xb5, hi: 0xb5},
 	{value: 0x0018, lo: 0xb6, hi: 0xbf},
-	// Block 0xe1, offset 0x69d
+	// Block 0xe8, offset 0x6c1
 	{value: 0x0000, lo: 0x08},
 	{value: 0x0018, lo: 0x80, hi: 0x83},
-	{value: 0x1308, lo: 0x84, hi: 0x84},
+	{value: 0x3308, lo: 0x84, hi: 0x84},
 	{value: 0x0018, lo: 0x85, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x9a},
-	{value: 0x1308, lo: 0x9b, hi: 0x9f},
+	{value: 0x3308, lo: 0x9b, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xa0},
-	{value: 0x1308, lo: 0xa1, hi: 0xaf},
+	{value: 0x3308, lo: 0xa1, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
-	// Block 0xe2, offset 0x6a6
+	// Block 0xe9, offset 0x6ca
 	{value: 0x0000, lo: 0x0a},
-	{value: 0x1308, lo: 0x80, hi: 0x86},
+	{value: 0x3308, lo: 0x80, hi: 0x86},
 	{value: 0x0040, lo: 0x87, hi: 0x87},
-	{value: 0x1308, lo: 0x88, hi: 0x98},
+	{value: 0x3308, lo: 0x88, hi: 0x98},
 	{value: 0x0040, lo: 0x99, hi: 0x9a},
-	{value: 0x1308, lo: 0x9b, hi: 0xa1},
+	{value: 0x3308, lo: 0x9b, hi: 0xa1},
 	{value: 0x0040, lo: 0xa2, hi: 0xa2},
-	{value: 0x1308, lo: 0xa3, hi: 0xa4},
+	{value: 0x3308, lo: 0xa3, hi: 0xa4},
 	{value: 0x0040, lo: 0xa5, hi: 0xa5},
-	{value: 0x1308, lo: 0xa6, hi: 0xaa},
+	{value: 0x3308, lo: 0xa6, hi: 0xaa},
 	{value: 0x0040, lo: 0xab, hi: 0xbf},
-	// Block 0xe3, offset 0x6b1
+	// Block 0xea, offset 0x6d5
 	{value: 0x0000, lo: 0x05},
-	{value: 0x0008, lo: 0x80, hi: 0x84},
+	{value: 0x0808, lo: 0x80, hi: 0x84},
 	{value: 0x0040, lo: 0x85, hi: 0x86},
-	{value: 0x0018, lo: 0x87, hi: 0x8f},
-	{value: 0x1308, lo: 0x90, hi: 0x96},
+	{value: 0x0818, lo: 0x87, hi: 0x8f},
+	{value: 0x3308, lo: 0x90, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0xbf},
-	// Block 0xe4, offset 0x6b7
+	// Block 0xeb, offset 0x6db
 	{value: 0x0000, lo: 0x07},
-	{value: 0x0208, lo: 0x80, hi: 0x83},
-	{value: 0x1308, lo: 0x84, hi: 0x8a},
+	{value: 0x0a08, lo: 0x80, hi: 0x83},
+	{value: 0x3308, lo: 0x84, hi: 0x8a},
 	{value: 0x0040, lo: 0x8b, hi: 0x8f},
-	{value: 0x0008, lo: 0x90, hi: 0x99},
+	{value: 0x0808, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9d},
-	{value: 0x0018, lo: 0x9e, hi: 0x9f},
+	{value: 0x0818, lo: 0x9e, hi: 0x9f},
 	{value: 0x0040, lo: 0xa0, hi: 0xbf},
-	// Block 0xe5, offset 0x6bf
+	// Block 0xec, offset 0x6e3
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0040, lo: 0x80, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xb1},
 	{value: 0x0040, lo: 0xb2, hi: 0xbf},
-	// Block 0xe6, offset 0x6c3
+	// Block 0xed, offset 0x6e7
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0xab},
 	{value: 0x0040, lo: 0xac, hi: 0xaf},
 	{value: 0x0018, lo: 0xb0, hi: 0xbf},
-	// Block 0xe7, offset 0x6c7
+	// Block 0xee, offset 0x6eb
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x93},
 	{value: 0x0040, lo: 0x94, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xae},
 	{value: 0x0040, lo: 0xaf, hi: 0xb0},
 	{value: 0x0018, lo: 0xb1, hi: 0xbf},
-	// Block 0xe8, offset 0x6cd
+	// Block 0xef, offset 0x6f1
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0018, lo: 0x81, hi: 0x8f},
 	{value: 0x0040, lo: 0x90, hi: 0x90},
 	{value: 0x0018, lo: 0x91, hi: 0xb5},
 	{value: 0x0040, lo: 0xb6, hi: 0xbf},
-	// Block 0xe9, offset 0x6d3
+	// Block 0xf0, offset 0x6f7
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x8f},
 	{value: 0xc1c1, lo: 0x90, hi: 0x90},
 	{value: 0x0018, lo: 0x91, hi: 0xac},
 	{value: 0x0040, lo: 0xad, hi: 0xbf},
-	// Block 0xea, offset 0x6d8
+	// Block 0xf1, offset 0x6fc
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0040, lo: 0x80, hi: 0xa5},
 	{value: 0x0018, lo: 0xa6, hi: 0xbf},
-	// Block 0xeb, offset 0x6db
-	{value: 0x0000, lo: 0x0d},
+	// Block 0xf2, offset 0x6ff
+	{value: 0x0000, lo: 0x0f},
 	{value: 0xc7e9, lo: 0x80, hi: 0x80},
 	{value: 0xc839, lo: 0x81, hi: 0x81},
 	{value: 0xc889, lo: 0x82, hi: 0x82},
@@ -4346,84 +4422,88 @@
 	{value: 0x0040, lo: 0x89, hi: 0x8f},
 	{value: 0xcab9, lo: 0x90, hi: 0x90},
 	{value: 0xcad9, lo: 0x91, hi: 0x91},
-	{value: 0x0040, lo: 0x92, hi: 0xbf},
-	// Block 0xec, offset 0x6e9
+	{value: 0x0040, lo: 0x92, hi: 0x9f},
+	{value: 0x0018, lo: 0xa0, hi: 0xa5},
+	{value: 0x0040, lo: 0xa6, hi: 0xbf},
+	// Block 0xf3, offset 0x70f
 	{value: 0x0000, lo: 0x06},
-	{value: 0x0018, lo: 0x80, hi: 0x92},
-	{value: 0x0040, lo: 0x93, hi: 0x9f},
+	{value: 0x0018, lo: 0x80, hi: 0x94},
+	{value: 0x0040, lo: 0x95, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xac},
 	{value: 0x0040, lo: 0xad, hi: 0xaf},
-	{value: 0x0018, lo: 0xb0, hi: 0xb6},
-	{value: 0x0040, lo: 0xb7, hi: 0xbf},
-	// Block 0xed, offset 0x6f0
+	{value: 0x0018, lo: 0xb0, hi: 0xb8},
+	{value: 0x0040, lo: 0xb9, hi: 0xbf},
+	// Block 0xf4, offset 0x716
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0018, lo: 0x80, hi: 0xb3},
 	{value: 0x0040, lo: 0xb4, hi: 0xbf},
-	// Block 0xee, offset 0x6f3
+	// Block 0xf5, offset 0x719
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0018, lo: 0x80, hi: 0x94},
 	{value: 0x0040, lo: 0x95, hi: 0xbf},
-	// Block 0xef, offset 0x6f6
+	// Block 0xf6, offset 0x71c
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0018, lo: 0x80, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0xbf},
-	// Block 0xf0, offset 0x6fa
+	// Block 0xf7, offset 0x720
 	{value: 0x0000, lo: 0x05},
 	{value: 0x0018, lo: 0x80, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0x99},
 	{value: 0x0040, lo: 0x9a, hi: 0x9f},
 	{value: 0x0018, lo: 0xa0, hi: 0xbf},
-	// Block 0xf1, offset 0x700
+	// Block 0xf8, offset 0x726
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x87},
 	{value: 0x0040, lo: 0x88, hi: 0x8f},
 	{value: 0x0018, lo: 0x90, hi: 0xad},
 	{value: 0x0040, lo: 0xae, hi: 0xbf},
-	// Block 0xf2, offset 0x705
-	{value: 0x0000, lo: 0x09},
-	{value: 0x0040, lo: 0x80, hi: 0x8f},
-	{value: 0x0018, lo: 0x90, hi: 0x9e},
-	{value: 0x0040, lo: 0x9f, hi: 0x9f},
-	{value: 0x0018, lo: 0xa0, hi: 0xa7},
-	{value: 0x0040, lo: 0xa8, hi: 0xaf},
-	{value: 0x0018, lo: 0xb0, hi: 0xb0},
-	{value: 0x0040, lo: 0xb1, hi: 0xb2},
-	{value: 0x0018, lo: 0xb3, hi: 0xbe},
-	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xf3, offset 0x70f
+	// Block 0xf9, offset 0x72b
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x8b},
 	{value: 0x0040, lo: 0x8c, hi: 0x8f},
-	{value: 0x0018, lo: 0x90, hi: 0x9e},
-	{value: 0x0040, lo: 0x9f, hi: 0xbf},
-	// Block 0xf4, offset 0x714
+	{value: 0x0018, lo: 0x90, hi: 0xbe},
+	{value: 0x0040, lo: 0xbf, hi: 0xbf},
+	// Block 0xfa, offset 0x730
+	{value: 0x0000, lo: 0x04},
+	{value: 0x0018, lo: 0x80, hi: 0x8c},
+	{value: 0x0040, lo: 0x8d, hi: 0x8f},
+	{value: 0x0018, lo: 0x90, hi: 0xab},
+	{value: 0x0040, lo: 0xac, hi: 0xbf},
+	// Block 0xfb, offset 0x735
 	{value: 0x0000, lo: 0x02},
-	{value: 0x0018, lo: 0x80, hi: 0x91},
-	{value: 0x0040, lo: 0x92, hi: 0xbf},
-	// Block 0xf5, offset 0x717
-	{value: 0x0000, lo: 0x02},
+	{value: 0x0018, lo: 0x80, hi: 0x97},
+	{value: 0x0040, lo: 0x98, hi: 0xbf},
+	// Block 0xfc, offset 0x738
+	{value: 0x0000, lo: 0x04},
 	{value: 0x0018, lo: 0x80, hi: 0x80},
-	{value: 0x0040, lo: 0x81, hi: 0xbf},
-	// Block 0xf6, offset 0x71a
+	{value: 0x0040, lo: 0x81, hi: 0x8f},
+	{value: 0x0018, lo: 0x90, hi: 0xa6},
+	{value: 0x0040, lo: 0xa7, hi: 0xbf},
+	// Block 0xfd, offset 0x73d
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0x96},
 	{value: 0x0040, lo: 0x97, hi: 0xbf},
-	// Block 0xf7, offset 0x71d
+	// Block 0xfe, offset 0x740
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0008, lo: 0x80, hi: 0xb4},
 	{value: 0x0040, lo: 0xb5, hi: 0xbf},
-	// Block 0xf8, offset 0x720
+	// Block 0xff, offset 0x743
 	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0x9d},
 	{value: 0x0040, lo: 0x9e, hi: 0x9f},
 	{value: 0x0008, lo: 0xa0, hi: 0xbf},
-	// Block 0xf9, offset 0x724
-	{value: 0x0000, lo: 0x02},
+	// Block 0x100, offset 0x747
+	{value: 0x0000, lo: 0x03},
 	{value: 0x0008, lo: 0x80, hi: 0xa1},
-	{value: 0x0040, lo: 0xa2, hi: 0xbf},
-	// Block 0xfa, offset 0x727
+	{value: 0x0040, lo: 0xa2, hi: 0xaf},
+	{value: 0x0008, lo: 0xb0, hi: 0xbf},
+	// Block 0x101, offset 0x74b
+	{value: 0x0000, lo: 0x02},
+	{value: 0x0008, lo: 0x80, hi: 0xa0},
+	{value: 0x0040, lo: 0xa1, hi: 0xbf},
+	// Block 0x102, offset 0x74e
 	{value: 0x0020, lo: 0x0f},
 	{value: 0xdeb9, lo: 0x80, hi: 0x89},
 	{value: 0x8dfd, lo: 0x8a, hi: 0x8a},
@@ -4440,7 +4520,7 @@
 	{value: 0xe4f9, lo: 0xba, hi: 0xba},
 	{value: 0x8edd, lo: 0xbb, hi: 0xbb},
 	{value: 0xe519, lo: 0xbc, hi: 0xbf},
-	// Block 0xfb, offset 0x737
+	// Block 0x103, offset 0x75e
 	{value: 0x0020, lo: 0x10},
 	{value: 0x937d, lo: 0x80, hi: 0x80},
 	{value: 0xf099, lo: 0x81, hi: 0x86},
@@ -4457,23 +4537,23 @@
 	{value: 0xf4d9, lo: 0xae, hi: 0xaf},
 	{value: 0x94dd, lo: 0xb0, hi: 0xb1},
 	{value: 0xf519, lo: 0xb2, hi: 0xbe},
-	{value: 0x0040, lo: 0xbf, hi: 0xbf},
-	// Block 0xfc, offset 0x748
+	{value: 0x2040, lo: 0xbf, hi: 0xbf},
+	// Block 0x104, offset 0x76f
 	{value: 0x0000, lo: 0x04},
 	{value: 0x0040, lo: 0x80, hi: 0x80},
 	{value: 0x0340, lo: 0x81, hi: 0x81},
 	{value: 0x0040, lo: 0x82, hi: 0x9f},
 	{value: 0x0340, lo: 0xa0, hi: 0xbf},
-	// Block 0xfd, offset 0x74d
+	// Block 0x105, offset 0x774
 	{value: 0x0000, lo: 0x01},
 	{value: 0x0340, lo: 0x80, hi: 0xbf},
-	// Block 0xfe, offset 0x74f
+	// Block 0x106, offset 0x776
 	{value: 0x0000, lo: 0x01},
-	{value: 0x13c0, lo: 0x80, hi: 0xbf},
-	// Block 0xff, offset 0x751
+	{value: 0x33c0, lo: 0x80, hi: 0xbf},
+	// Block 0x107, offset 0x778
 	{value: 0x0000, lo: 0x02},
-	{value: 0x13c0, lo: 0x80, hi: 0xaf},
+	{value: 0x33c0, lo: 0x80, hi: 0xaf},
 	{value: 0x0040, lo: 0xb0, hi: 0xbf},
 }
 
-// Total table size 41559 bytes (40KiB); checksum: F4A1FA4E
+// Total table size 42115 bytes (41KiB); checksum: F4A1FA4E
diff --git a/src/vendor/golang_org/x/net/idna/trie.go b/src/vendor/golang_org/x/net/idna/trie.go
index 000fb97..c4ef847 100644
--- a/src/vendor/golang_org/x/net/idna/trie.go
+++ b/src/vendor/golang_org/x/net/idna/trie.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/net/idna/trieval.go b/src/vendor/golang_org/x/net/idna/trieval.go
index cd88e4d..5f4e5f2 100644
--- a/src/vendor/golang_org/x/net/idna/trieval.go
+++ b/src/vendor/golang_org/x/net/idna/trieval.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Code generated by running "go generate" in golang_org/x/text. DO NOT EDIT.
 
@@ -28,9 +28,9 @@
 //       15..3  index into xor or mapping table
 //     }
 //   } else {
-//       15..13 unused
-//           12 modifier (including virama)
-//           11 virama modifier
+//       15..14 unused
+//       13     mayNeedNorm
+//       12..11 attributes
 //       10..8  joining type
 //        7..3  category type
 //   }
@@ -51,15 +51,20 @@
 	joinShift = 8
 	joinMask  = 0x07
 
-	viramaModifier = 0x0800
+	// Attributes
+	attributesMask = 0x1800
+	viramaModifier = 0x1800
 	modifier       = 0x1000
+	rtl            = 0x0800
+
+	mayNeedNorm = 0x2000
 )
 
 // A category corresponds to a category defined in the IDNA mapping table.
 type category uint16
 
 const (
-	unknown              category = 0 // not defined currently in unicode.
+	unknown              category = 0 // not currently defined in unicode.
 	mapped               category = 1
 	disallowedSTD3Mapped category = 2
 	deviation            category = 3
@@ -112,5 +117,5 @@
 }
 
 func (c info) isViramaModifier() bool {
-	return c&(viramaModifier|catSmallMask) == viramaModifier
+	return c&(attributesMask|catSmallMask) == viramaModifier
 }
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_bsd.go b/src/vendor/golang_org/x/net/internal/nettest/helper_bsd.go
new file mode 100644
index 0000000..a6e433b
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_bsd.go
@@ -0,0 +1,53 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package nettest
+
+import (
+	"runtime"
+	"strconv"
+	"strings"
+	"syscall"
+)
+
+var darwinVersion int
+
+func init() {
+	if runtime.GOOS == "darwin" {
+		// See http://support.apple.com/kb/HT1633.
+		s, err := syscall.Sysctl("kern.osrelease")
+		if err != nil {
+			return
+		}
+		ss := strings.Split(s, ".")
+		if len(ss) == 0 {
+			return
+		}
+		darwinVersion, _ = strconv.Atoi(ss[0])
+	}
+}
+
+func supportsIPv6MulticastDeliveryOnLoopback() bool {
+	switch runtime.GOOS {
+	case "freebsd":
+		// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
+		// Even after the fix, it looks like the latest
+		// kernels don't deliver link-local scoped multicast
+		// packets correctly.
+		return false
+	case "darwin":
+		return !causesIPv6Crash()
+	default:
+		return true
+	}
+}
+
+func causesIPv6Crash() bool {
+	// We see some kernel crash when running IPv6 with IP-level
+	// options on Darwin kernel version 12 or below.
+	// See golang.org/issues/17015.
+	return darwinVersion < 13
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_nobsd.go b/src/vendor/golang_org/x/net/internal/nettest/helper_nobsd.go
new file mode 100644
index 0000000..bc7da5e
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_nobsd.go
@@ -0,0 +1,15 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux solaris
+
+package nettest
+
+func supportsIPv6MulticastDeliveryOnLoopback() bool {
+	return true
+}
+
+func causesIPv6Crash() bool {
+	return false
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_posix.go b/src/vendor/golang_org/x/net/internal/nettest/helper_posix.go
new file mode 100644
index 0000000..963ed99
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_posix.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.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package nettest
+
+import (
+	"os"
+	"syscall"
+)
+
+func protocolNotSupported(err error) bool {
+	switch err := err.(type) {
+	case syscall.Errno:
+		switch err {
+		case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
+			return true
+		}
+	case *os.SyscallError:
+		switch err := err.Err.(type) {
+		case syscall.Errno:
+			switch err {
+			case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
+				return true
+			}
+		}
+	}
+	return false
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_stub.go b/src/vendor/golang_org/x/net/internal/nettest/helper_stub.go
new file mode 100644
index 0000000..ea61b6f
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_stub.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.
+
+// +build nacl plan9
+
+package nettest
+
+import (
+	"fmt"
+	"runtime"
+)
+
+func maxOpenFiles() int {
+	return defaultMaxOpenFiles
+}
+
+func supportsRawIPSocket() (string, bool) {
+	return fmt.Sprintf("not supported on %s", runtime.GOOS), false
+}
+
+func supportsIPv6MulticastDeliveryOnLoopback() bool {
+	return false
+}
+
+func causesIPv6Crash() bool {
+	return false
+}
+
+func protocolNotSupported(err error) bool {
+	return false
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_unix.go b/src/vendor/golang_org/x/net/internal/nettest/helper_unix.go
new file mode 100644
index 0000000..ed13e44
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_unix.go
@@ -0,0 +1,29 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package nettest
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"syscall"
+)
+
+func maxOpenFiles() int {
+	var rlim syscall.Rlimit
+	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
+		return defaultMaxOpenFiles
+	}
+	return int(rlim.Cur)
+}
+
+func supportsRawIPSocket() (string, bool) {
+	if os.Getuid() != 0 {
+		return fmt.Sprintf("must be root on %s", runtime.GOOS), false
+	}
+	return "", true
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/helper_windows.go b/src/vendor/golang_org/x/net/internal/nettest/helper_windows.go
new file mode 100644
index 0000000..3dcb727
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/helper_windows.go
@@ -0,0 +1,42 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package nettest
+
+import (
+	"fmt"
+	"runtime"
+	"syscall"
+)
+
+func maxOpenFiles() int {
+	return 4 * defaultMaxOpenFiles /* actually it's 16581375 */
+}
+
+func supportsRawIPSocket() (string, bool) {
+	// 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 fmt.Sprintf("no access to raw socket allowed on %s", runtime.GOOS), false
+	}
+	if err != nil {
+		return err.Error(), false
+	}
+	syscall.Closesocket(s)
+	return "", true
+}
+
+func supportsIPv6MulticastDeliveryOnLoopback() bool {
+	return true
+}
+
+func causesIPv6Crash() bool {
+	return false
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/interface.go b/src/vendor/golang_org/x/net/internal/nettest/interface.go
new file mode 100644
index 0000000..8e6333a
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/interface.go
@@ -0,0 +1,94 @@
+// 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 nettest
+
+import "net"
+
+// IsMulticastCapable reports whether ifi is an IP multicast-capable
+// network interface. Network must be "ip", "ip4" or "ip6".
+func IsMulticastCapable(network string, ifi *net.Interface) (net.IP, bool) {
+	switch network {
+	case "ip", "ip4", "ip6":
+	default:
+		return nil, false
+	}
+	if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
+		return nil, false
+	}
+	return hasRoutableIP(network, ifi)
+}
+
+// RoutedInterface returns a network interface that can route IP
+// traffic and satisfies flags. It returns nil when an appropriate
+// network interface is not found. Network must be "ip", "ip4" or
+// "ip6".
+func RoutedInterface(network string, flags net.Flags) *net.Interface {
+	switch network {
+	case "ip", "ip4", "ip6":
+	default:
+		return nil
+	}
+	ift, err := net.Interfaces()
+	if err != nil {
+		return nil
+	}
+	for _, ifi := range ift {
+		if ifi.Flags&flags != flags {
+			continue
+		}
+		if _, ok := hasRoutableIP(network, &ifi); !ok {
+			continue
+		}
+		return &ifi
+	}
+	return nil
+}
+
+func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) {
+	ifat, err := ifi.Addrs()
+	if err != nil {
+		return nil, false
+	}
+	for _, ifa := range ifat {
+		switch ifa := ifa.(type) {
+		case *net.IPAddr:
+			if ip := routableIP(network, ifa.IP); ip != nil {
+				return ip, true
+			}
+		case *net.IPNet:
+			if ip := routableIP(network, ifa.IP); ip != nil {
+				return ip, true
+			}
+		}
+	}
+	return nil, false
+}
+
+func routableIP(network string, ip net.IP) net.IP {
+	if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() {
+		return nil
+	}
+	switch network {
+	case "ip4":
+		if ip := ip.To4(); ip != nil {
+			return ip
+		}
+	case "ip6":
+		if ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation
+			return nil
+		}
+		if ip := ip.To16(); ip != nil && ip.To4() == nil {
+			return ip
+		}
+	default:
+		if ip := ip.To4(); ip != nil {
+			return ip
+		}
+		if ip := ip.To16(); ip != nil {
+			return ip
+		}
+	}
+	return nil
+}
diff --git a/src/vendor/golang_org/x/net/internal/nettest/rlimit.go b/src/vendor/golang_org/x/net/internal/nettest/rlimit.go
new file mode 100644
index 0000000..bb34aec
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/rlimit.go
@@ -0,0 +1,11 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package nettest
+
+const defaultMaxOpenFiles = 256
+
+// MaxOpenFiles returns the maximum number of open files for the
+// caller's process.
+func MaxOpenFiles() int { return maxOpenFiles() }
diff --git a/src/vendor/golang_org/x/net/internal/nettest/stack.go b/src/vendor/golang_org/x/net/internal/nettest/stack.go
new file mode 100644
index 0000000..06f4e09
--- /dev/null
+++ b/src/vendor/golang_org/x/net/internal/nettest/stack.go
@@ -0,0 +1,152 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package nettest provides utilities for network testing.
+package nettest // import "golang.org/x/net/internal/nettest"
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net"
+	"os"
+	"runtime"
+)
+
+var (
+	supportsIPv4 bool
+	supportsIPv6 bool
+)
+
+func init() {
+	if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
+		ln.Close()
+		supportsIPv4 = true
+	}
+	if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
+		ln.Close()
+		supportsIPv6 = true
+	}
+}
+
+// SupportsIPv4 reports whether the platform supports IPv4 networking
+// functionality.
+func SupportsIPv4() bool { return supportsIPv4 }
+
+// SupportsIPv6 reports whether the platform supports IPv6 networking
+// functionality.
+func SupportsIPv6() bool { return supportsIPv6 }
+
+// SupportsRawIPSocket reports whether the platform supports raw IP
+// sockets.
+func SupportsRawIPSocket() (string, bool) {
+	return supportsRawIPSocket()
+}
+
+// SupportsIPv6MulticastDeliveryOnLoopback reports whether the
+// platform supports IPv6 multicast packet delivery on software
+// loopback interface.
+func SupportsIPv6MulticastDeliveryOnLoopback() bool {
+	return supportsIPv6MulticastDeliveryOnLoopback()
+}
+
+// ProtocolNotSupported reports whether err is a protocol not
+// supported error.
+func ProtocolNotSupported(err error) bool {
+	return protocolNotSupported(err)
+}
+
+// TestableNetwork reports whether network is testable on the current
+// platform configuration.
+func TestableNetwork(network string) bool {
+	// This is based on logic from standard library's
+	// net/platform_test.go.
+	switch network {
+	case "unix", "unixgram":
+		switch runtime.GOOS {
+		case "android", "nacl", "plan9", "windows":
+			return false
+		}
+		if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+			return false
+		}
+	case "unixpacket":
+		switch runtime.GOOS {
+		case "android", "darwin", "freebsd", "nacl", "plan9", "windows":
+			return false
+		case "netbsd":
+			// It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown.
+			if runtime.GOARCH == "386" {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// NewLocalListener returns a listener which listens to a loopback IP
+// address or local file system path.
+// Network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
+func NewLocalListener(network string) (net.Listener, error) {
+	switch network {
+	case "tcp":
+		if supportsIPv4 {
+			if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
+				return ln, nil
+			}
+		}
+		if supportsIPv6 {
+			return net.Listen("tcp6", "[::1]:0")
+		}
+	case "tcp4":
+		if supportsIPv4 {
+			return net.Listen("tcp4", "127.0.0.1:0")
+		}
+	case "tcp6":
+		if supportsIPv6 {
+			return net.Listen("tcp6", "[::1]:0")
+		}
+	case "unix", "unixpacket":
+		return net.Listen(network, localPath())
+	}
+	return nil, fmt.Errorf("%s is not supported", network)
+}
+
+// NewLocalPacketListener returns a packet listener which listens to a
+// loopback IP address or local file system path.
+// Network must be "udp", "udp4", "udp6" or "unixgram".
+func NewLocalPacketListener(network string) (net.PacketConn, error) {
+	switch network {
+	case "udp":
+		if supportsIPv4 {
+			if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
+				return c, nil
+			}
+		}
+		if supportsIPv6 {
+			return net.ListenPacket("udp6", "[::1]:0")
+		}
+	case "udp4":
+		if supportsIPv4 {
+			return net.ListenPacket("udp4", "127.0.0.1:0")
+		}
+	case "udp6":
+		if supportsIPv6 {
+			return net.ListenPacket("udp6", "[::1]:0")
+		}
+	case "unixgram":
+		return net.ListenPacket(network, localPath())
+	}
+	return nil, fmt.Errorf("%s is not supported", network)
+}
+
+func localPath() string {
+	f, err := ioutil.TempFile("", "nettest")
+	if err != nil {
+		panic(err)
+	}
+	path := f.Name()
+	f.Close()
+	os.Remove(path)
+	return path
+}
diff --git a/src/vendor/golang_org/x/net/nettest/conntest_test.go b/src/vendor/golang_org/x/net/nettest/conntest_test.go
index 23bd69f..ae8426a 100644
--- a/src/vendor/golang_org/x/net/nettest/conntest_test.go
+++ b/src/vendor/golang_org/x/net/nettest/conntest_test.go
@@ -7,64 +7,14 @@
 package nettest
 
 import (
-	"fmt"
-	"io/ioutil"
 	"net"
 	"os"
 	"runtime"
 	"testing"
+
+	"golang_org/x/net/internal/nettest"
 )
 
-// testUnixAddr uses ioutil.TempFile to get a name that is unique.
-// It also uses /tmp directory in case it is prohibited to create UNIX
-// sockets in TMPDIR.
-func testUnixAddr() string {
-	f, err := ioutil.TempFile("", "go-nettest")
-	if err != nil {
-		panic(err)
-	}
-	addr := f.Name()
-	f.Close()
-	os.Remove(addr)
-	return addr
-}
-
-// testableNetwork reports whether network is testable on the current
-// platform configuration.
-// This is based on logic from standard library's net/platform_test.go.
-func testableNetwork(network string) bool {
-	switch network {
-	case "unix":
-		switch runtime.GOOS {
-		case "android", "nacl", "plan9", "windows":
-			return false
-		}
-		if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
-			return false
-		}
-	case "unixpacket":
-		switch runtime.GOOS {
-		case "android", "darwin", "nacl", "plan9", "windows", "freebsd":
-			return false
-		}
-	}
-	return true
-}
-
-func newLocalListener(network string) (net.Listener, error) {
-	switch network {
-	case "tcp":
-		ln, err := net.Listen("tcp", "127.0.0.1:0")
-		if err != nil {
-			ln, err = net.Listen("tcp6", "[::1]:0")
-		}
-		return ln, err
-	case "unix", "unixpacket":
-		return net.Listen(network, testUnixAddr())
-	}
-	return nil, fmt.Errorf("%s is not supported", network)
-}
-
 func TestTestConn(t *testing.T) {
 	tests := []struct{ name, network string }{
 		{"TCP", "tcp"},
@@ -74,12 +24,12 @@
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if !testableNetwork(tt.network) {
+			if !nettest.TestableNetwork(tt.network) {
 				t.Skipf("not supported on %s", runtime.GOOS)
 			}
 
 			mp := func() (c1, c2 net.Conn, stop func(), err error) {
-				ln, err := newLocalListener(tt.network)
+				ln, err := nettest.NewLocalListener(tt.network)
 				if err != nil {
 					return nil, nil, nil, err
 				}
diff --git a/src/vendor/golang_org/x/net/route/defs_openbsd.go b/src/vendor/golang_org/x/net/route/defs_openbsd.go
index 0f66d36..173bb5d 100644
--- a/src/vendor/golang_org/x/net/route/defs_openbsd.go
+++ b/src/vendor/golang_org/x/net/route/defs_openbsd.go
@@ -69,6 +69,9 @@
 	sysRTM_IFINFO     = C.RTM_IFINFO
 	sysRTM_IFANNOUNCE = C.RTM_IFANNOUNCE
 	sysRTM_DESYNC     = C.RTM_DESYNC
+	sysRTM_INVALIDATE = C.RTM_INVALIDATE
+	sysRTM_BFD        = C.RTM_BFD
+	sysRTM_PROPOSAL   = C.RTM_PROPOSAL
 
 	sysRTA_DST     = C.RTA_DST
 	sysRTA_GATEWAY = C.RTA_GATEWAY
@@ -81,6 +84,10 @@
 	sysRTA_SRC     = C.RTA_SRC
 	sysRTA_SRCMASK = C.RTA_SRCMASK
 	sysRTA_LABEL   = C.RTA_LABEL
+	sysRTA_BFD     = C.RTA_BFD
+	sysRTA_DNS     = C.RTA_DNS
+	sysRTA_STATIC  = C.RTA_STATIC
+	sysRTA_SEARCH  = C.RTA_SEARCH
 
 	sysRTAX_DST     = C.RTAX_DST
 	sysRTAX_GATEWAY = C.RTAX_GATEWAY
@@ -93,6 +100,10 @@
 	sysRTAX_SRC     = C.RTAX_SRC
 	sysRTAX_SRCMASK = C.RTAX_SRCMASK
 	sysRTAX_LABEL   = C.RTAX_LABEL
+	sysRTAX_BFD     = C.RTAX_BFD
+	sysRTAX_DNS     = C.RTAX_DNS
+	sysRTAX_STATIC  = C.RTAX_STATIC
+	sysRTAX_SEARCH  = C.RTAX_SEARCH
 	sysRTAX_MAX     = C.RTAX_MAX
 )
 
diff --git a/src/vendor/golang_org/x/net/route/route_classic.go b/src/vendor/golang_org/x/net/route/route_classic.go
index 61b2bb4..02fa688 100644
--- a/src/vendor/golang_org/x/net/route/route_classic.go
+++ b/src/vendor/golang_org/x/net/route/route_classic.go
@@ -6,7 +6,10 @@
 
 package route
 
-import "syscall"
+import (
+	"runtime"
+	"syscall"
+)
 
 func (m *RouteMessage) marshal() ([]byte, error) {
 	w, ok := wireFormats[m.Type]
@@ -14,6 +17,11 @@
 		return nil, errUnsupportedMessage
 	}
 	l := w.bodyOff + addrsSpace(m.Addrs)
+	if runtime.GOOS == "darwin" {
+		// Fix stray pointer writes on macOS.
+		// See golang.org/issue/22456.
+		l += 1024
+	}
 	b := make([]byte, l)
 	nativeEndian.PutUint16(b[:2], uint16(l))
 	if m.Version == 0 {
diff --git a/src/vendor/golang_org/x/net/route/route_test.go b/src/vendor/golang_org/x/net/route/route_test.go
index 63fd8c5..61bd174 100644
--- a/src/vendor/golang_org/x/net/route/route_test.go
+++ b/src/vendor/golang_org/x/net/route/route_test.go
@@ -74,6 +74,10 @@
 	"df:mpls1-n:tag-o:src", // mpls1 for dragonfly, tag for netbsd, src for openbsd
 	"df:mpls2-o:srcmask",   // mpls2 for dragonfly, srcmask for openbsd
 	"df:mpls3-o:label",     // mpls3 for dragonfly, label for openbsd
+	"o:bfd",                // bfd for openbsd
+	"o:dns",                // dns for openbsd
+	"o:static",             // static for openbsd
+	"o:search",             // search for openbsd
 }
 
 func (attrs addrAttrs) String() string {
diff --git a/src/vendor/golang_org/x/net/route/sys_darwin.go b/src/vendor/golang_org/x/net/route/sys_darwin.go
index e742c91..d2daf5c 100644
--- a/src/vendor/golang_org/x/net/route/sys_darwin.go
+++ b/src/vendor/golang_org/x/net/route/sys_darwin.go
@@ -13,7 +13,7 @@
 	}
 }
 
-// A RouteMetrics represents route metrics.
+// RouteMetrics represents route metrics.
 type RouteMetrics struct {
 	PathMTU int // path maximum transmission unit
 }
@@ -30,7 +30,7 @@
 	}
 }
 
-// A InterfaceMetrics represents interface metrics.
+// InterfaceMetrics represents interface metrics.
 type InterfaceMetrics struct {
 	Type int // interface type
 	MTU  int // maximum transmission unit
diff --git a/src/vendor/golang_org/x/net/route/sys_dragonfly.go b/src/vendor/golang_org/x/net/route/sys_dragonfly.go
index b175cb1..0c14bc2 100644
--- a/src/vendor/golang_org/x/net/route/sys_dragonfly.go
+++ b/src/vendor/golang_org/x/net/route/sys_dragonfly.go
@@ -8,7 +8,7 @@
 
 func (typ RIBType) parseable() bool { return true }
 
-// A RouteMetrics represents route metrics.
+// RouteMetrics represents route metrics.
 type RouteMetrics struct {
 	PathMTU int // path maximum transmission unit
 }
@@ -25,7 +25,7 @@
 	}
 }
 
-// A InterfaceMetrics represents interface metrics.
+// InterfaceMetrics represents interface metrics.
 type InterfaceMetrics struct {
 	Type int // interface type
 	MTU  int // maximum transmission unit
diff --git a/src/vendor/golang_org/x/net/route/sys_freebsd.go b/src/vendor/golang_org/x/net/route/sys_freebsd.go
index 010d4ae..89ba1c4 100644
--- a/src/vendor/golang_org/x/net/route/sys_freebsd.go
+++ b/src/vendor/golang_org/x/net/route/sys_freebsd.go
@@ -11,7 +11,7 @@
 
 func (typ RIBType) parseable() bool { return true }
 
-// A RouteMetrics represents route metrics.
+// RouteMetrics represents route metrics.
 type RouteMetrics struct {
 	PathMTU int // path maximum transmission unit
 }
@@ -35,7 +35,7 @@
 	}
 }
 
-// A InterfaceMetrics represents interface metrics.
+// InterfaceMetrics represents interface metrics.
 type InterfaceMetrics struct {
 	Type int // interface type
 	MTU  int // maximum transmission unit
diff --git a/src/vendor/golang_org/x/net/route/sys_netbsd.go b/src/vendor/golang_org/x/net/route/sys_netbsd.go
index b4e3301..02f71d5 100644
--- a/src/vendor/golang_org/x/net/route/sys_netbsd.go
+++ b/src/vendor/golang_org/x/net/route/sys_netbsd.go
@@ -6,7 +6,7 @@
 
 func (typ RIBType) parseable() bool { return true }
 
-// A RouteMetrics represents route metrics.
+// RouteMetrics represents route metrics.
 type RouteMetrics struct {
 	PathMTU int // path maximum transmission unit
 }
@@ -23,7 +23,7 @@
 	}
 }
 
-// A InterfaceMetrics represents interface metrics.
+// RouteMetrics represents route metrics.
 type InterfaceMetrics struct {
 	Type int // interface type
 	MTU  int // maximum transmission unit
diff --git a/src/vendor/golang_org/x/net/route/sys_openbsd.go b/src/vendor/golang_org/x/net/route/sys_openbsd.go
index 8798dc4..c5674e8 100644
--- a/src/vendor/golang_org/x/net/route/sys_openbsd.go
+++ b/src/vendor/golang_org/x/net/route/sys_openbsd.go
@@ -15,7 +15,7 @@
 	}
 }
 
-// A RouteMetrics represents route metrics.
+// RouteMetrics represents route metrics.
 type RouteMetrics struct {
 	PathMTU int // path maximum transmission unit
 }
@@ -32,7 +32,7 @@
 	}
 }
 
-// A InterfaceMetrics represents interface metrics.
+// InterfaceMetrics represents interface metrics.
 type InterfaceMetrics struct {
 	Type int // interface type
 	MTU  int // maximum transmission unit
@@ -75,5 +75,6 @@
 		sysRTM_DELADDR:    ifam,
 		sysRTM_IFINFO:     ifm,
 		sysRTM_IFANNOUNCE: ifanm,
+		sysRTM_DESYNC:     rtm,
 	}
 }
diff --git a/src/vendor/golang_org/x/net/route/zsys_openbsd.go b/src/vendor/golang_org/x/net/route/zsys_openbsd.go
index f5a1ff9..db8c8ef 100644
--- a/src/vendor/golang_org/x/net/route/zsys_openbsd.go
+++ b/src/vendor/golang_org/x/net/route/zsys_openbsd.go
@@ -54,6 +54,9 @@
 	sysRTM_IFINFO     = 0xe
 	sysRTM_IFANNOUNCE = 0xf
 	sysRTM_DESYNC     = 0x10
+	sysRTM_INVALIDATE = 0x11
+	sysRTM_BFD        = 0x12
+	sysRTM_PROPOSAL   = 0x13
 
 	sysRTA_DST     = 0x1
 	sysRTA_GATEWAY = 0x2
@@ -66,6 +69,10 @@
 	sysRTA_SRC     = 0x100
 	sysRTA_SRCMASK = 0x200
 	sysRTA_LABEL   = 0x400
+	sysRTA_BFD     = 0x800
+	sysRTA_DNS     = 0x1000
+	sysRTA_STATIC  = 0x2000
+	sysRTA_SEARCH  = 0x4000
 
 	sysRTAX_DST     = 0x0
 	sysRTAX_GATEWAY = 0x1
@@ -78,7 +85,11 @@
 	sysRTAX_SRC     = 0x8
 	sysRTAX_SRCMASK = 0x9
 	sysRTAX_LABEL   = 0xa
-	sysRTAX_MAX     = 0xb
+	sysRTAX_BFD     = 0xb
+	sysRTAX_DNS     = 0xc
+	sysRTAX_STATIC  = 0xd
+	sysRTAX_SEARCH  = 0xe
+	sysRTAX_MAX     = 0xf
 )
 
 const (
diff --git a/src/vendor/golang_org/x/text/secure/bidirule/bidirule.go b/src/vendor/golang_org/x/text/secure/bidirule/bidirule.go
index 9f9594e..c3ca2bc 100644
--- a/src/vendor/golang_org/x/text/secure/bidirule/bidirule.go
+++ b/src/vendor/golang_org/x/text/secure/bidirule/bidirule.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -157,6 +157,7 @@
 		e, sz := bidi.LookupString(s[i:])
 		if sz == 0 {
 			i++
+			continue
 		}
 		c := e.Class()
 		if c == bidi.R || c == bidi.AL || c == bidi.AN {
@@ -205,9 +206,6 @@
 }
 
 func (t *Transformer) isFinal() bool {
-	if !t.isRTL() {
-		return true
-	}
 	return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
 }
 
diff --git a/src/vendor/golang_org/x/text/secure/doc.go b/src/vendor/golang_org/x/text/secure/doc.go
index 4912b9b..5eb60b9 100644
--- a/src/vendor/golang_org/x/text/secure/doc.go
+++ b/src/vendor/golang_org/x/text/secure/doc.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/transform/transform.go b/src/vendor/golang_org/x/text/transform/transform.go
index 2a1b190..9ddfa80 100644
--- a/src/vendor/golang_org/x/text/transform/transform.go
+++ b/src/vendor/golang_org/x/text/transform/transform.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/bidi.go b/src/vendor/golang_org/x/text/unicode/bidi/bidi.go
index 4c9735e..e691ae8 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/bidi.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/bidi.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/bracket.go b/src/vendor/golang_org/x/text/unicode/bidi/bracket.go
index f08a93d..0784e79 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/bracket.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/bracket.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/core.go b/src/vendor/golang_org/x/text/unicode/bidi/core.go
index a352ad6..9a934b8 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/core.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/core.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/prop.go b/src/vendor/golang_org/x/text/unicode/bidi/prop.go
index ed191c2..878b8c4 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/prop.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/prop.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/tables.go b/src/vendor/golang_org/x/text/unicode/bidi/tables.go
index 1245315..fb2229e 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/tables.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/tables.go
@@ -1,11 +1,11 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Code generated by running "go generate" in golang_org/x/text. DO NOT EDIT.
 
 package bidi
 
 // UnicodeVersion is the Unicode version from which the tables in this package are derived.
-const UnicodeVersion = "9.0.0"
+const UnicodeVersion = "10.0.0"
 
 // xorMasks contains masks to be xor-ed with brackets to get the reverse
 // version.
@@ -183,7 +183,7 @@
 	return 0
 }
 
-// bidiTrie. Total size: 15744 bytes (15.38 KiB). Checksum: b4c3b70954803b86.
+// bidiTrie. Total size: 16128 bytes (15.75 KiB). Checksum: 8122d83e461996f.
 type bidiTrie struct{}
 
 func newBidiTrie(i int) *bidiTrie {
@@ -198,9 +198,9 @@
 	}
 }
 
-// bidiValues: 222 blocks, 14208 entries, 14208 bytes
+// bidiValues: 228 blocks, 14592 entries, 14592 bytes
 // The third block is the zero block.
-var bidiValues = [14208]uint8{
+var bidiValues = [14592]uint8{
 	// Block 0x0, offset 0x0
 	0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b,
 	0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008,
@@ -417,9 +417,9 @@
 	0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001,
 	0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001,
 	0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001,
-	0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x0001, 0x5e1: 0x0001, 0x5e2: 0x0001, 0x5e3: 0x0001,
-	0x5e4: 0x0001, 0x5e5: 0x0001, 0x5e6: 0x0001, 0x5e7: 0x0001, 0x5e8: 0x0001, 0x5e9: 0x0001,
-	0x5ea: 0x0001, 0x5eb: 0x0001, 0x5ec: 0x0001, 0x5ed: 0x0001, 0x5ee: 0x0001, 0x5ef: 0x0001,
+	0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d,
+	0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d,
+	0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d,
 	0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001,
 	0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001,
 	0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001,
@@ -480,6 +480,8 @@
 	0x80d: 0x000c,
 	0x822: 0x000c, 0x823: 0x000c,
 	0x831: 0x0004,
+	0x83a: 0x000c, 0x83b: 0x000c,
+	0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c,
 	// Block 0x21, offset 0x840
 	0x841: 0x000c,
 	0x87c: 0x000c, 0x87f: 0x000c,
@@ -510,7 +512,9 @@
 	0x9cc: 0x000c, 0x9cd: 0x000c,
 	0x9e2: 0x000c, 0x9e3: 0x000c,
 	// Block 0x28, offset 0xa00
-	0xa01: 0x000c,
+	0xa00: 0x000c, 0xa01: 0x000c,
+	0xa3b: 0x000c,
+	0xa3c: 0x000c,
 	// Block 0x29, offset 0xa40
 	0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c,
 	0xa4d: 0x000c,
@@ -677,7 +681,7 @@
 	0x1324: 0x000c, 0x1325: 0x000c, 0x1326: 0x000c, 0x1327: 0x000c, 0x1328: 0x000c, 0x1329: 0x000c,
 	0x132a: 0x000c, 0x132b: 0x000c, 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c,
 	0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, 0x1334: 0x000c, 0x1335: 0x000c,
-	0x133b: 0x000c,
+	0x1336: 0x000c, 0x1337: 0x000c, 0x1338: 0x000c, 0x1339: 0x000c, 0x133b: 0x000c,
 	0x133c: 0x000c, 0x133d: 0x000c, 0x133e: 0x000c, 0x133f: 0x000c,
 	// Block 0x4d, offset 0x1340
 	0x137d: 0x000a, 0x137f: 0x000a,
@@ -815,36 +819,36 @@
 	0x16d2: 0x000a, 0x16d3: 0x000a, 0x16d4: 0x000a, 0x16d5: 0x000a, 0x16d6: 0x000a, 0x16d7: 0x000a,
 	0x16d8: 0x000a, 0x16d9: 0x000a, 0x16da: 0x000a, 0x16db: 0x000a, 0x16dc: 0x000a, 0x16dd: 0x000a,
 	0x16de: 0x000a, 0x16df: 0x000a, 0x16e0: 0x000a, 0x16e1: 0x000a, 0x16e2: 0x000a, 0x16e3: 0x000a,
-	0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a, 0x16e7: 0x000a, 0x16e8: 0x000a, 0x16e9: 0x000a,
-	0x16ea: 0x000a, 0x16eb: 0x000a, 0x16ec: 0x000a, 0x16ed: 0x000a, 0x16ee: 0x000a, 0x16ef: 0x000a,
-	0x16f0: 0x000a, 0x16f1: 0x000a, 0x16f2: 0x000a, 0x16f3: 0x000a, 0x16f4: 0x000a, 0x16f5: 0x000a,
-	0x16f6: 0x000a, 0x16f7: 0x000a, 0x16f8: 0x000a, 0x16f9: 0x000a, 0x16fa: 0x000a, 0x16fb: 0x000a,
-	0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a,
+	0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a,
 	// Block 0x5c, offset 0x1700
 	0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a,
-	0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, 0x170b: 0x000a,
-	0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a,
-	0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1715: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a,
-	0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a,
-	0x171e: 0x000a, 0x171f: 0x000a, 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a,
-	0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a,
+	0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a,
+	0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a,
+	0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a,
+	0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a,
+	0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a,
+	0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a,
+	0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a,
 	// Block 0x5d, offset 0x1740
 	0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a,
-	0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a,
-	0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a,
-	0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a, 0x1767: 0x000a, 0x1768: 0x000a, 0x1769: 0x000a,
-	0x176a: 0x000a, 0x176b: 0x000a, 0x176c: 0x000a, 0x176d: 0x000a, 0x176e: 0x000a, 0x176f: 0x000a,
-	0x1770: 0x000a, 0x1771: 0x000a, 0x1772: 0x000a, 0x1773: 0x000a, 0x1774: 0x000a, 0x1775: 0x000a,
-	0x1776: 0x000a, 0x1777: 0x000a, 0x1778: 0x000a, 0x1779: 0x000a, 0x177a: 0x000a, 0x177b: 0x000a,
-	0x177c: 0x000a, 0x177d: 0x000a, 0x177e: 0x000a, 0x177f: 0x000a,
+	0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x0002, 0x1749: 0x0002, 0x174a: 0x0002, 0x174b: 0x0002,
+	0x174c: 0x0002, 0x174d: 0x0002, 0x174e: 0x0002, 0x174f: 0x0002, 0x1750: 0x0002, 0x1751: 0x0002,
+	0x1752: 0x0002, 0x1753: 0x0002, 0x1754: 0x0002, 0x1755: 0x0002, 0x1756: 0x0002, 0x1757: 0x0002,
+	0x1758: 0x0002, 0x1759: 0x0002, 0x175a: 0x0002, 0x175b: 0x0002,
 	// Block 0x5e, offset 0x1780
-	0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a,
-	0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x0002, 0x1789: 0x0002, 0x178a: 0x0002, 0x178b: 0x0002,
-	0x178c: 0x0002, 0x178d: 0x0002, 0x178e: 0x0002, 0x178f: 0x0002, 0x1790: 0x0002, 0x1791: 0x0002,
-	0x1792: 0x0002, 0x1793: 0x0002, 0x1794: 0x0002, 0x1795: 0x0002, 0x1796: 0x0002, 0x1797: 0x0002,
-	0x1798: 0x0002, 0x1799: 0x0002, 0x179a: 0x0002, 0x179b: 0x0002,
+	0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a,
+	0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a,
+	0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a,
+	0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a,
 	// Block 0x5f, offset 0x17c0
-	0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ec: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a,
+	0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a,
+	0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x000a, 0x17c9: 0x000a, 0x17ca: 0x000a, 0x17cb: 0x000a,
+	0x17cc: 0x000a, 0x17cd: 0x000a, 0x17ce: 0x000a, 0x17cf: 0x000a, 0x17d0: 0x000a, 0x17d1: 0x000a,
+	0x17d2: 0x000a, 0x17d3: 0x000a, 0x17d4: 0x000a, 0x17d5: 0x000a, 0x17d6: 0x000a, 0x17d7: 0x000a,
+	0x17d8: 0x000a, 0x17d9: 0x000a, 0x17da: 0x000a, 0x17db: 0x000a, 0x17dc: 0x000a, 0x17dd: 0x000a,
+	0x17de: 0x000a, 0x17df: 0x000a, 0x17e0: 0x000a, 0x17e1: 0x000a, 0x17e2: 0x000a, 0x17e3: 0x000a,
+	0x17e4: 0x000a, 0x17e5: 0x000a, 0x17e6: 0x000a, 0x17e7: 0x000a, 0x17e8: 0x000a, 0x17e9: 0x000a,
+	0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a,
 	0x17f0: 0x000a, 0x17f1: 0x000a, 0x17f2: 0x000a, 0x17f3: 0x000a, 0x17f4: 0x000a, 0x17f5: 0x000a,
 	0x17f6: 0x000a, 0x17f7: 0x000a, 0x17f8: 0x000a, 0x17f9: 0x000a, 0x17fa: 0x000a, 0x17fb: 0x000a,
 	0x17fc: 0x000a, 0x17fd: 0x000a, 0x17fe: 0x000a, 0x17ff: 0x000a,
@@ -855,282 +859,284 @@
 	0x1812: 0x000a, 0x1813: 0x000a, 0x1814: 0x000a, 0x1815: 0x000a, 0x1816: 0x000a, 0x1817: 0x000a,
 	0x1818: 0x000a, 0x1819: 0x000a, 0x181a: 0x000a, 0x181b: 0x000a, 0x181c: 0x000a, 0x181d: 0x000a,
 	0x181e: 0x000a, 0x181f: 0x000a, 0x1820: 0x000a, 0x1821: 0x000a, 0x1822: 0x000a, 0x1823: 0x000a,
-	0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x000a, 0x1829: 0x000a,
-	0x182a: 0x000a, 0x182b: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a,
-	0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a,
+	0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x003a, 0x1829: 0x002a,
+	0x182a: 0x003a, 0x182b: 0x002a, 0x182c: 0x003a, 0x182d: 0x002a, 0x182e: 0x003a, 0x182f: 0x002a,
+	0x1830: 0x003a, 0x1831: 0x002a, 0x1832: 0x003a, 0x1833: 0x002a, 0x1834: 0x003a, 0x1835: 0x002a,
 	0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a,
 	0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a,
 	// Block 0x61, offset 0x1840
-	0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x000a,
-	0x1846: 0x000a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a,
+	0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x009a,
+	0x1846: 0x008a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a,
 	0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a,
 	0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a,
 	0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a,
 	0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a,
-	0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x000a, 0x1867: 0x000a, 0x1868: 0x003a, 0x1869: 0x002a,
+	0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x003a, 0x1867: 0x002a, 0x1868: 0x003a, 0x1869: 0x002a,
 	0x186a: 0x003a, 0x186b: 0x002a, 0x186c: 0x003a, 0x186d: 0x002a, 0x186e: 0x003a, 0x186f: 0x002a,
-	0x1870: 0x003a, 0x1871: 0x002a, 0x1872: 0x003a, 0x1873: 0x002a, 0x1874: 0x003a, 0x1875: 0x002a,
+	0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a,
 	0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a,
 	0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a,
 	// Block 0x62, offset 0x1880
-	0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x000a, 0x1884: 0x000a, 0x1885: 0x009a,
-	0x1886: 0x008a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a,
-	0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a,
-	0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a,
-	0x1898: 0x000a, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a,
+	0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x007a, 0x1884: 0x006a, 0x1885: 0x009a,
+	0x1886: 0x008a, 0x1887: 0x00ba, 0x1888: 0x00aa, 0x1889: 0x009a, 0x188a: 0x008a, 0x188b: 0x007a,
+	0x188c: 0x006a, 0x188d: 0x00da, 0x188e: 0x002a, 0x188f: 0x003a, 0x1890: 0x00ca, 0x1891: 0x009a,
+	0x1892: 0x008a, 0x1893: 0x007a, 0x1894: 0x006a, 0x1895: 0x009a, 0x1896: 0x008a, 0x1897: 0x00ba,
+	0x1898: 0x00aa, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a,
 	0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a,
-	0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x003a, 0x18a7: 0x002a, 0x18a8: 0x003a, 0x18a9: 0x002a,
-	0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a,
+	0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x000a, 0x18a9: 0x000a,
+	0x18aa: 0x000a, 0x18ab: 0x000a, 0x18ac: 0x000a, 0x18ad: 0x000a, 0x18ae: 0x000a, 0x18af: 0x000a,
 	0x18b0: 0x000a, 0x18b1: 0x000a, 0x18b2: 0x000a, 0x18b3: 0x000a, 0x18b4: 0x000a, 0x18b5: 0x000a,
 	0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a,
 	0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a,
 	// Block 0x63, offset 0x18c0
-	0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x007a, 0x18c4: 0x006a, 0x18c5: 0x009a,
-	0x18c6: 0x008a, 0x18c7: 0x00ba, 0x18c8: 0x00aa, 0x18c9: 0x009a, 0x18ca: 0x008a, 0x18cb: 0x007a,
-	0x18cc: 0x006a, 0x18cd: 0x00da, 0x18ce: 0x002a, 0x18cf: 0x003a, 0x18d0: 0x00ca, 0x18d1: 0x009a,
-	0x18d2: 0x008a, 0x18d3: 0x007a, 0x18d4: 0x006a, 0x18d5: 0x009a, 0x18d6: 0x008a, 0x18d7: 0x00ba,
-	0x18d8: 0x00aa, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a,
+	0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x000a,
+	0x18c6: 0x000a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a,
+	0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a,
+	0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a,
+	0x18d8: 0x003a, 0x18d9: 0x002a, 0x18da: 0x003a, 0x18db: 0x002a, 0x18dc: 0x000a, 0x18dd: 0x000a,
 	0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a,
 	0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x000a, 0x18e7: 0x000a, 0x18e8: 0x000a, 0x18e9: 0x000a,
 	0x18ea: 0x000a, 0x18eb: 0x000a, 0x18ec: 0x000a, 0x18ed: 0x000a, 0x18ee: 0x000a, 0x18ef: 0x000a,
 	0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a,
 	0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a,
-	0x18fc: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a,
+	0x18fc: 0x003a, 0x18fd: 0x002a, 0x18fe: 0x000a, 0x18ff: 0x000a,
 	// Block 0x64, offset 0x1900
 	0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x000a, 0x1904: 0x000a, 0x1905: 0x000a,
 	0x1906: 0x000a, 0x1907: 0x000a, 0x1908: 0x000a, 0x1909: 0x000a, 0x190a: 0x000a, 0x190b: 0x000a,
 	0x190c: 0x000a, 0x190d: 0x000a, 0x190e: 0x000a, 0x190f: 0x000a, 0x1910: 0x000a, 0x1911: 0x000a,
 	0x1912: 0x000a, 0x1913: 0x000a, 0x1914: 0x000a, 0x1915: 0x000a, 0x1916: 0x000a, 0x1917: 0x000a,
-	0x1918: 0x003a, 0x1919: 0x002a, 0x191a: 0x003a, 0x191b: 0x002a, 0x191c: 0x000a, 0x191d: 0x000a,
+	0x1918: 0x000a, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a,
 	0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a,
 	0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a,
 	0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a,
-	0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, 0x1934: 0x000a, 0x1935: 0x000a,
+	0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a,
 	0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a,
-	0x193c: 0x003a, 0x193d: 0x002a, 0x193e: 0x000a, 0x193f: 0x000a,
+	0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a,
 	// Block 0x65, offset 0x1940
 	0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a,
 	0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a,
 	0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a,
-	0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, 0x1956: 0x000a, 0x1957: 0x000a,
+	0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a,
 	0x1958: 0x000a, 0x1959: 0x000a, 0x195a: 0x000a, 0x195b: 0x000a, 0x195c: 0x000a, 0x195d: 0x000a,
 	0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a,
 	0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a,
 	0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a,
-	0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a,
-	0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a,
-	0x197c: 0x000a, 0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a,
+	0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a,
+	0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a,
+	0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a,
 	// Block 0x66, offset 0x1980
 	0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a,
-	0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a,
+	0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a,
 	0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a,
-	0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a,
-	0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a,
-	0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a,
-	0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a,
-	0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a,
-	0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a, 0x19b4: 0x000a, 0x19b5: 0x000a,
-	0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a,
-	0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a,
+	0x1992: 0x000a,
+	0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a,
 	// Block 0x67, offset 0x19c0
-	0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a,
-	0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a,
-	0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a,
-	0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a,
+	0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a,
+	0x19ea: 0x000a, 0x19ef: 0x000c,
+	0x19f0: 0x000c, 0x19f1: 0x000c,
+	0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a,
+	0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a,
 	// Block 0x68, offset 0x1a00
-	0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a,
-	0x1a2a: 0x000a, 0x1a2f: 0x000c,
-	0x1a30: 0x000c, 0x1a31: 0x000c,
-	0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a,
-	0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a,
+	0x1a3f: 0x000c,
 	// Block 0x69, offset 0x1a40
-	0x1a7f: 0x000c,
+	0x1a60: 0x000c, 0x1a61: 0x000c, 0x1a62: 0x000c, 0x1a63: 0x000c,
+	0x1a64: 0x000c, 0x1a65: 0x000c, 0x1a66: 0x000c, 0x1a67: 0x000c, 0x1a68: 0x000c, 0x1a69: 0x000c,
+	0x1a6a: 0x000c, 0x1a6b: 0x000c, 0x1a6c: 0x000c, 0x1a6d: 0x000c, 0x1a6e: 0x000c, 0x1a6f: 0x000c,
+	0x1a70: 0x000c, 0x1a71: 0x000c, 0x1a72: 0x000c, 0x1a73: 0x000c, 0x1a74: 0x000c, 0x1a75: 0x000c,
+	0x1a76: 0x000c, 0x1a77: 0x000c, 0x1a78: 0x000c, 0x1a79: 0x000c, 0x1a7a: 0x000c, 0x1a7b: 0x000c,
+	0x1a7c: 0x000c, 0x1a7d: 0x000c, 0x1a7e: 0x000c, 0x1a7f: 0x000c,
 	// Block 0x6a, offset 0x1a80
-	0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c,
-	0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c,
-	0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c,
-	0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c,
-	0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c,
-	0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c,
+	0x1a80: 0x000a, 0x1a81: 0x000a, 0x1a82: 0x000a, 0x1a83: 0x000a, 0x1a84: 0x000a, 0x1a85: 0x000a,
+	0x1a86: 0x000a, 0x1a87: 0x000a, 0x1a88: 0x000a, 0x1a89: 0x000a, 0x1a8a: 0x000a, 0x1a8b: 0x000a,
+	0x1a8c: 0x000a, 0x1a8d: 0x000a, 0x1a8e: 0x000a, 0x1a8f: 0x000a, 0x1a90: 0x000a, 0x1a91: 0x000a,
+	0x1a92: 0x000a, 0x1a93: 0x000a, 0x1a94: 0x000a, 0x1a95: 0x000a, 0x1a96: 0x000a, 0x1a97: 0x000a,
+	0x1a98: 0x000a, 0x1a99: 0x000a, 0x1a9a: 0x000a, 0x1a9b: 0x000a, 0x1a9c: 0x000a, 0x1a9d: 0x000a,
+	0x1a9e: 0x000a, 0x1a9f: 0x000a, 0x1aa0: 0x000a, 0x1aa1: 0x000a, 0x1aa2: 0x003a, 0x1aa3: 0x002a,
+	0x1aa4: 0x003a, 0x1aa5: 0x002a, 0x1aa6: 0x003a, 0x1aa7: 0x002a, 0x1aa8: 0x003a, 0x1aa9: 0x002a,
+	0x1aaa: 0x000a, 0x1aab: 0x000a, 0x1aac: 0x000a, 0x1aad: 0x000a, 0x1aae: 0x000a, 0x1aaf: 0x000a,
+	0x1ab0: 0x000a, 0x1ab1: 0x000a, 0x1ab2: 0x000a, 0x1ab3: 0x000a, 0x1ab4: 0x000a, 0x1ab5: 0x000a,
+	0x1ab6: 0x000a, 0x1ab7: 0x000a, 0x1ab8: 0x000a, 0x1ab9: 0x000a, 0x1aba: 0x000a, 0x1abb: 0x000a,
+	0x1abc: 0x000a, 0x1abd: 0x000a, 0x1abe: 0x000a, 0x1abf: 0x000a,
 	// Block 0x6b, offset 0x1ac0
 	0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a,
-	0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a,
-	0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a,
-	0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a,
-	0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a,
-	0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a,
-	0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a,
-	0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a,
-	0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a,
-	0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a,
-	0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a,
+	0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a,
 	// Block 0x6c, offset 0x1b00
-	0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a,
+	0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a,
+	0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a,
+	0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a,
+	0x1b12: 0x000a, 0x1b13: 0x000a, 0x1b14: 0x000a, 0x1b15: 0x000a, 0x1b16: 0x000a, 0x1b17: 0x000a,
+	0x1b18: 0x000a, 0x1b19: 0x000a, 0x1b1b: 0x000a, 0x1b1c: 0x000a, 0x1b1d: 0x000a,
+	0x1b1e: 0x000a, 0x1b1f: 0x000a, 0x1b20: 0x000a, 0x1b21: 0x000a, 0x1b22: 0x000a, 0x1b23: 0x000a,
+	0x1b24: 0x000a, 0x1b25: 0x000a, 0x1b26: 0x000a, 0x1b27: 0x000a, 0x1b28: 0x000a, 0x1b29: 0x000a,
+	0x1b2a: 0x000a, 0x1b2b: 0x000a, 0x1b2c: 0x000a, 0x1b2d: 0x000a, 0x1b2e: 0x000a, 0x1b2f: 0x000a,
+	0x1b30: 0x000a, 0x1b31: 0x000a, 0x1b32: 0x000a, 0x1b33: 0x000a, 0x1b34: 0x000a, 0x1b35: 0x000a,
+	0x1b36: 0x000a, 0x1b37: 0x000a, 0x1b38: 0x000a, 0x1b39: 0x000a, 0x1b3a: 0x000a, 0x1b3b: 0x000a,
+	0x1b3c: 0x000a, 0x1b3d: 0x000a, 0x1b3e: 0x000a, 0x1b3f: 0x000a,
 	// Block 0x6d, offset 0x1b40
 	0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a,
 	0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a,
 	0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a,
 	0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a,
-	0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a,
+	0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5a: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a,
 	0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a,
 	0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a,
 	0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a,
-	0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a,
-	0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a,
-	0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a,
+	0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a,
 	// Block 0x6e, offset 0x1b80
 	0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a,
 	0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a,
 	0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a,
-	0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a,
-	0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a,
-	0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a,
-	0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a,
-	0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a,
-	0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a,
+	0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a,
+	0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a, 0x1bb4: 0x000a, 0x1bb5: 0x000a,
+	0x1bb6: 0x000a, 0x1bb7: 0x000a, 0x1bb8: 0x000a, 0x1bb9: 0x000a, 0x1bba: 0x000a, 0x1bbb: 0x000a,
 	// Block 0x6f, offset 0x1bc0
-	0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a,
-	0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a,
-	0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a,
-	0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a,
-	0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a,
-	0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a,
+	0x1bc0: 0x0009, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a,
+	0x1bc8: 0x003a, 0x1bc9: 0x002a, 0x1bca: 0x003a, 0x1bcb: 0x002a,
+	0x1bcc: 0x003a, 0x1bcd: 0x002a, 0x1bce: 0x003a, 0x1bcf: 0x002a, 0x1bd0: 0x003a, 0x1bd1: 0x002a,
+	0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x003a, 0x1bd5: 0x002a, 0x1bd6: 0x003a, 0x1bd7: 0x002a,
+	0x1bd8: 0x003a, 0x1bd9: 0x002a, 0x1bda: 0x003a, 0x1bdb: 0x002a, 0x1bdc: 0x000a, 0x1bdd: 0x000a,
+	0x1bde: 0x000a, 0x1bdf: 0x000a, 0x1be0: 0x000a,
+	0x1bea: 0x000c, 0x1beb: 0x000c, 0x1bec: 0x000c, 0x1bed: 0x000c,
+	0x1bf0: 0x000a,
+	0x1bf6: 0x000a, 0x1bf7: 0x000a,
+	0x1bfd: 0x000a, 0x1bfe: 0x000a, 0x1bff: 0x000a,
 	// Block 0x70, offset 0x1c00
-	0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a,
-	0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a,
-	0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a,
-	0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a,
-	0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a,
-	0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a,
-	0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c,
-	0x1c30: 0x000a,
-	0x1c36: 0x000a, 0x1c37: 0x000a,
-	0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a,
+	0x1c19: 0x000c, 0x1c1a: 0x000c, 0x1c1b: 0x000a, 0x1c1c: 0x000a,
+	0x1c20: 0x000a,
 	// Block 0x71, offset 0x1c40
-	0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a,
-	0x1c60: 0x000a,
+	0x1c7b: 0x000a,
 	// Block 0x72, offset 0x1c80
-	0x1cbb: 0x000a,
+	0x1c80: 0x000a, 0x1c81: 0x000a, 0x1c82: 0x000a, 0x1c83: 0x000a, 0x1c84: 0x000a, 0x1c85: 0x000a,
+	0x1c86: 0x000a, 0x1c87: 0x000a, 0x1c88: 0x000a, 0x1c89: 0x000a, 0x1c8a: 0x000a, 0x1c8b: 0x000a,
+	0x1c8c: 0x000a, 0x1c8d: 0x000a, 0x1c8e: 0x000a, 0x1c8f: 0x000a, 0x1c90: 0x000a, 0x1c91: 0x000a,
+	0x1c92: 0x000a, 0x1c93: 0x000a, 0x1c94: 0x000a, 0x1c95: 0x000a, 0x1c96: 0x000a, 0x1c97: 0x000a,
+	0x1c98: 0x000a, 0x1c99: 0x000a, 0x1c9a: 0x000a, 0x1c9b: 0x000a, 0x1c9c: 0x000a, 0x1c9d: 0x000a,
+	0x1c9e: 0x000a, 0x1c9f: 0x000a, 0x1ca0: 0x000a, 0x1ca1: 0x000a, 0x1ca2: 0x000a, 0x1ca3: 0x000a,
 	// Block 0x73, offset 0x1cc0
-	0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a,
-	0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a,
-	0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 0x1cd0: 0x000a, 0x1cd1: 0x000a,
-	0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a,
-	0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a,
-	0x1cde: 0x000a, 0x1cdf: 0x000a, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a,
+	0x1cdd: 0x000a,
+	0x1cde: 0x000a,
 	// Block 0x74, offset 0x1d00
-	0x1d1d: 0x000a,
-	0x1d1e: 0x000a,
+	0x1d10: 0x000a, 0x1d11: 0x000a,
+	0x1d12: 0x000a, 0x1d13: 0x000a, 0x1d14: 0x000a, 0x1d15: 0x000a, 0x1d16: 0x000a, 0x1d17: 0x000a,
+	0x1d18: 0x000a, 0x1d19: 0x000a, 0x1d1a: 0x000a, 0x1d1b: 0x000a, 0x1d1c: 0x000a, 0x1d1d: 0x000a,
+	0x1d1e: 0x000a, 0x1d1f: 0x000a,
+	0x1d3c: 0x000a, 0x1d3d: 0x000a, 0x1d3e: 0x000a,
 	// Block 0x75, offset 0x1d40
-	0x1d50: 0x000a, 0x1d51: 0x000a,
-	0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a,
-	0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a,
-	0x1d5e: 0x000a, 0x1d5f: 0x000a,
-	0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a,
+	0x1d71: 0x000a, 0x1d72: 0x000a, 0x1d73: 0x000a, 0x1d74: 0x000a, 0x1d75: 0x000a,
+	0x1d76: 0x000a, 0x1d77: 0x000a, 0x1d78: 0x000a, 0x1d79: 0x000a, 0x1d7a: 0x000a, 0x1d7b: 0x000a,
+	0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a, 0x1d7f: 0x000a,
 	// Block 0x76, offset 0x1d80
-	0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a,
-	0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a,
-	0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a,
+	0x1d8c: 0x000a, 0x1d8d: 0x000a, 0x1d8e: 0x000a, 0x1d8f: 0x000a,
 	// Block 0x77, offset 0x1dc0
-	0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a,
+	0x1df7: 0x000a, 0x1df8: 0x000a, 0x1df9: 0x000a, 0x1dfa: 0x000a,
 	// Block 0x78, offset 0x1e00
-	0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a,
+	0x1e1e: 0x000a, 0x1e1f: 0x000a,
+	0x1e3f: 0x000a,
 	// Block 0x79, offset 0x1e40
-	0x1e5e: 0x000a, 0x1e5f: 0x000a,
-	0x1e7f: 0x000a,
+	0x1e50: 0x000a, 0x1e51: 0x000a,
+	0x1e52: 0x000a, 0x1e53: 0x000a, 0x1e54: 0x000a, 0x1e55: 0x000a, 0x1e56: 0x000a, 0x1e57: 0x000a,
+	0x1e58: 0x000a, 0x1e59: 0x000a, 0x1e5a: 0x000a, 0x1e5b: 0x000a, 0x1e5c: 0x000a, 0x1e5d: 0x000a,
+	0x1e5e: 0x000a, 0x1e5f: 0x000a, 0x1e60: 0x000a, 0x1e61: 0x000a, 0x1e62: 0x000a, 0x1e63: 0x000a,
+	0x1e64: 0x000a, 0x1e65: 0x000a, 0x1e66: 0x000a, 0x1e67: 0x000a, 0x1e68: 0x000a, 0x1e69: 0x000a,
+	0x1e6a: 0x000a, 0x1e6b: 0x000a, 0x1e6c: 0x000a, 0x1e6d: 0x000a, 0x1e6e: 0x000a, 0x1e6f: 0x000a,
+	0x1e70: 0x000a, 0x1e71: 0x000a, 0x1e72: 0x000a, 0x1e73: 0x000a, 0x1e74: 0x000a, 0x1e75: 0x000a,
+	0x1e76: 0x000a, 0x1e77: 0x000a, 0x1e78: 0x000a, 0x1e79: 0x000a, 0x1e7a: 0x000a, 0x1e7b: 0x000a,
+	0x1e7c: 0x000a, 0x1e7d: 0x000a, 0x1e7e: 0x000a, 0x1e7f: 0x000a,
 	// Block 0x7a, offset 0x1e80
-	0x1e90: 0x000a, 0x1e91: 0x000a,
-	0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a,
-	0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a,
-	0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a,
-	0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a,
-	0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a,
-	0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a,
-	0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a,
-	0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a,
+	0x1e80: 0x000a, 0x1e81: 0x000a, 0x1e82: 0x000a, 0x1e83: 0x000a, 0x1e84: 0x000a, 0x1e85: 0x000a,
+	0x1e86: 0x000a,
 	// Block 0x7b, offset 0x1ec0
-	0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a,
-	0x1ec6: 0x000a,
+	0x1ecd: 0x000a, 0x1ece: 0x000a, 0x1ecf: 0x000a,
 	// Block 0x7c, offset 0x1f00
-	0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a,
+	0x1f2f: 0x000c,
+	0x1f30: 0x000c, 0x1f31: 0x000c, 0x1f32: 0x000c, 0x1f33: 0x000a, 0x1f34: 0x000c, 0x1f35: 0x000c,
+	0x1f36: 0x000c, 0x1f37: 0x000c, 0x1f38: 0x000c, 0x1f39: 0x000c, 0x1f3a: 0x000c, 0x1f3b: 0x000c,
+	0x1f3c: 0x000c, 0x1f3d: 0x000c, 0x1f3e: 0x000a, 0x1f3f: 0x000a,
 	// Block 0x7d, offset 0x1f40
-	0x1f6f: 0x000c,
-	0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c,
-	0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c,
-	0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a,
+	0x1f5e: 0x000c, 0x1f5f: 0x000c,
 	// Block 0x7e, offset 0x1f80
-	0x1f9e: 0x000c, 0x1f9f: 0x000c,
+	0x1fb0: 0x000c, 0x1fb1: 0x000c,
 	// Block 0x7f, offset 0x1fc0
-	0x1ff0: 0x000c, 0x1ff1: 0x000c,
+	0x1fc0: 0x000a, 0x1fc1: 0x000a, 0x1fc2: 0x000a, 0x1fc3: 0x000a, 0x1fc4: 0x000a, 0x1fc5: 0x000a,
+	0x1fc6: 0x000a, 0x1fc7: 0x000a, 0x1fc8: 0x000a, 0x1fc9: 0x000a, 0x1fca: 0x000a, 0x1fcb: 0x000a,
+	0x1fcc: 0x000a, 0x1fcd: 0x000a, 0x1fce: 0x000a, 0x1fcf: 0x000a, 0x1fd0: 0x000a, 0x1fd1: 0x000a,
+	0x1fd2: 0x000a, 0x1fd3: 0x000a, 0x1fd4: 0x000a, 0x1fd5: 0x000a, 0x1fd6: 0x000a, 0x1fd7: 0x000a,
+	0x1fd8: 0x000a, 0x1fd9: 0x000a, 0x1fda: 0x000a, 0x1fdb: 0x000a, 0x1fdc: 0x000a, 0x1fdd: 0x000a,
+	0x1fde: 0x000a, 0x1fdf: 0x000a, 0x1fe0: 0x000a, 0x1fe1: 0x000a,
 	// Block 0x80, offset 0x2000
-	0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a,
-	0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a,
-	0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a,
-	0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a,
-	0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a,
-	0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a,
+	0x2008: 0x000a,
 	// Block 0x81, offset 0x2040
-	0x2048: 0x000a,
+	0x2042: 0x000c,
+	0x2046: 0x000c, 0x204b: 0x000c,
+	0x2065: 0x000c, 0x2066: 0x000c, 0x2068: 0x000a, 0x2069: 0x000a,
+	0x206a: 0x000a, 0x206b: 0x000a,
+	0x2078: 0x0004, 0x2079: 0x0004,
 	// Block 0x82, offset 0x2080
-	0x2082: 0x000c,
-	0x2086: 0x000c, 0x208b: 0x000c,
-	0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a,
-	0x20aa: 0x000a, 0x20ab: 0x000a,
-	0x20b8: 0x0004, 0x20b9: 0x0004,
+	0x20b4: 0x000a, 0x20b5: 0x000a,
+	0x20b6: 0x000a, 0x20b7: 0x000a,
 	// Block 0x83, offset 0x20c0
-	0x20f4: 0x000a, 0x20f5: 0x000a,
-	0x20f6: 0x000a, 0x20f7: 0x000a,
+	0x20c4: 0x000c, 0x20c5: 0x000c,
+	0x20e0: 0x000c, 0x20e1: 0x000c, 0x20e2: 0x000c, 0x20e3: 0x000c,
+	0x20e4: 0x000c, 0x20e5: 0x000c, 0x20e6: 0x000c, 0x20e7: 0x000c, 0x20e8: 0x000c, 0x20e9: 0x000c,
+	0x20ea: 0x000c, 0x20eb: 0x000c, 0x20ec: 0x000c, 0x20ed: 0x000c, 0x20ee: 0x000c, 0x20ef: 0x000c,
+	0x20f0: 0x000c, 0x20f1: 0x000c,
 	// Block 0x84, offset 0x2100
-	0x2104: 0x000c, 0x2105: 0x000c,
-	0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c,
-	0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c,
-	0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c,
-	0x2130: 0x000c, 0x2131: 0x000c,
+	0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c,
+	0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c,
 	// Block 0x85, offset 0x2140
-	0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c,
-	0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c,
+	0x2147: 0x000c, 0x2148: 0x000c, 0x2149: 0x000c, 0x214a: 0x000c, 0x214b: 0x000c,
+	0x214c: 0x000c, 0x214d: 0x000c, 0x214e: 0x000c, 0x214f: 0x000c, 0x2150: 0x000c, 0x2151: 0x000c,
 	// Block 0x86, offset 0x2180
-	0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c,
-	0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c,
+	0x2180: 0x000c, 0x2181: 0x000c, 0x2182: 0x000c,
+	0x21b3: 0x000c,
+	0x21b6: 0x000c, 0x21b7: 0x000c, 0x21b8: 0x000c, 0x21b9: 0x000c,
+	0x21bc: 0x000c,
 	// Block 0x87, offset 0x21c0
-	0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c,
-	0x21f3: 0x000c,
-	0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c,
-	0x21fc: 0x000c,
+	0x21e5: 0x000c,
 	// Block 0x88, offset 0x2200
-	0x2225: 0x000c,
+	0x2229: 0x000c,
+	0x222a: 0x000c, 0x222b: 0x000c, 0x222c: 0x000c, 0x222d: 0x000c, 0x222e: 0x000c,
+	0x2231: 0x000c, 0x2232: 0x000c, 0x2235: 0x000c,
+	0x2236: 0x000c,
 	// Block 0x89, offset 0x2240
-	0x2269: 0x000c,
-	0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c,
-	0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c,
-	0x2276: 0x000c,
+	0x2243: 0x000c,
+	0x224c: 0x000c,
+	0x227c: 0x000c,
 	// Block 0x8a, offset 0x2280
-	0x2283: 0x000c,
-	0x228c: 0x000c,
-	0x22bc: 0x000c,
+	0x22b0: 0x000c, 0x22b2: 0x000c, 0x22b3: 0x000c, 0x22b4: 0x000c,
+	0x22b7: 0x000c, 0x22b8: 0x000c,
+	0x22be: 0x000c, 0x22bf: 0x000c,
 	// Block 0x8b, offset 0x22c0
-	0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c,
-	0x22f7: 0x000c, 0x22f8: 0x000c,
-	0x22fe: 0x000c, 0x22ff: 0x000c,
+	0x22c1: 0x000c,
+	0x22ec: 0x000c, 0x22ed: 0x000c,
+	0x22f6: 0x000c,
 	// Block 0x8c, offset 0x2300
-	0x2301: 0x000c,
-	0x232c: 0x000c, 0x232d: 0x000c,
-	0x2336: 0x000c,
+	0x2325: 0x000c, 0x2328: 0x000c,
+	0x232d: 0x000c,
 	// Block 0x8d, offset 0x2340
-	0x2365: 0x000c, 0x2368: 0x000c,
-	0x236d: 0x000c,
+	0x235d: 0x0001,
+	0x235e: 0x000c, 0x235f: 0x0001, 0x2360: 0x0001, 0x2361: 0x0001, 0x2362: 0x0001, 0x2363: 0x0001,
+	0x2364: 0x0001, 0x2365: 0x0001, 0x2366: 0x0001, 0x2367: 0x0001, 0x2368: 0x0001, 0x2369: 0x0003,
+	0x236a: 0x0001, 0x236b: 0x0001, 0x236c: 0x0001, 0x236d: 0x0001, 0x236e: 0x0001, 0x236f: 0x0001,
+	0x2370: 0x0001, 0x2371: 0x0001, 0x2372: 0x0001, 0x2373: 0x0001, 0x2374: 0x0001, 0x2375: 0x0001,
+	0x2376: 0x0001, 0x2377: 0x0001, 0x2378: 0x0001, 0x2379: 0x0001, 0x237a: 0x0001, 0x237b: 0x0001,
+	0x237c: 0x0001, 0x237d: 0x0001, 0x237e: 0x0001, 0x237f: 0x0001,
 	// Block 0x8e, offset 0x2380
-	0x239d: 0x0001,
-	0x239e: 0x000c, 0x239f: 0x0001, 0x23a0: 0x0001, 0x23a1: 0x0001, 0x23a2: 0x0001, 0x23a3: 0x0001,
-	0x23a4: 0x0001, 0x23a5: 0x0001, 0x23a6: 0x0001, 0x23a7: 0x0001, 0x23a8: 0x0001, 0x23a9: 0x0003,
-	0x23aa: 0x0001, 0x23ab: 0x0001, 0x23ac: 0x0001, 0x23ad: 0x0001, 0x23ae: 0x0001, 0x23af: 0x0001,
-	0x23b0: 0x0001, 0x23b1: 0x0001, 0x23b2: 0x0001, 0x23b3: 0x0001, 0x23b4: 0x0001, 0x23b5: 0x0001,
-	0x23b6: 0x0001, 0x23b7: 0x0001, 0x23b8: 0x0001, 0x23b9: 0x0001, 0x23ba: 0x0001, 0x23bb: 0x0001,
-	0x23bc: 0x0001, 0x23bd: 0x0001, 0x23be: 0x0001, 0x23bf: 0x0001,
+	0x2380: 0x0001, 0x2381: 0x0001, 0x2382: 0x0001, 0x2383: 0x0001, 0x2384: 0x0001, 0x2385: 0x0001,
+	0x2386: 0x0001, 0x2387: 0x0001, 0x2388: 0x0001, 0x2389: 0x0001, 0x238a: 0x0001, 0x238b: 0x0001,
+	0x238c: 0x0001, 0x238d: 0x0001, 0x238e: 0x0001, 0x238f: 0x0001, 0x2390: 0x000d, 0x2391: 0x000d,
+	0x2392: 0x000d, 0x2393: 0x000d, 0x2394: 0x000d, 0x2395: 0x000d, 0x2396: 0x000d, 0x2397: 0x000d,
+	0x2398: 0x000d, 0x2399: 0x000d, 0x239a: 0x000d, 0x239b: 0x000d, 0x239c: 0x000d, 0x239d: 0x000d,
+	0x239e: 0x000d, 0x239f: 0x000d, 0x23a0: 0x000d, 0x23a1: 0x000d, 0x23a2: 0x000d, 0x23a3: 0x000d,
+	0x23a4: 0x000d, 0x23a5: 0x000d, 0x23a6: 0x000d, 0x23a7: 0x000d, 0x23a8: 0x000d, 0x23a9: 0x000d,
+	0x23aa: 0x000d, 0x23ab: 0x000d, 0x23ac: 0x000d, 0x23ad: 0x000d, 0x23ae: 0x000d, 0x23af: 0x000d,
+	0x23b0: 0x000d, 0x23b1: 0x000d, 0x23b2: 0x000d, 0x23b3: 0x000d, 0x23b4: 0x000d, 0x23b5: 0x000d,
+	0x23b6: 0x000d, 0x23b7: 0x000d, 0x23b8: 0x000d, 0x23b9: 0x000d, 0x23ba: 0x000d, 0x23bb: 0x000d,
+	0x23bc: 0x000d, 0x23bd: 0x000d, 0x23be: 0x000d, 0x23bf: 0x000d,
 	// Block 0x8f, offset 0x23c0
-	0x23c0: 0x0001, 0x23c1: 0x0001, 0x23c2: 0x0001, 0x23c3: 0x0001, 0x23c4: 0x0001, 0x23c5: 0x0001,
-	0x23c6: 0x0001, 0x23c7: 0x0001, 0x23c8: 0x0001, 0x23c9: 0x0001, 0x23ca: 0x0001, 0x23cb: 0x0001,
-	0x23cc: 0x0001, 0x23cd: 0x0001, 0x23ce: 0x0001, 0x23cf: 0x0001, 0x23d0: 0x000d, 0x23d1: 0x000d,
+	0x23c0: 0x000d, 0x23c1: 0x000d, 0x23c2: 0x000d, 0x23c3: 0x000d, 0x23c4: 0x000d, 0x23c5: 0x000d,
+	0x23c6: 0x000d, 0x23c7: 0x000d, 0x23c8: 0x000d, 0x23c9: 0x000d, 0x23ca: 0x000d, 0x23cb: 0x000d,
+	0x23cc: 0x000d, 0x23cd: 0x000d, 0x23ce: 0x000d, 0x23cf: 0x000d, 0x23d0: 0x000d, 0x23d1: 0x000d,
 	0x23d2: 0x000d, 0x23d3: 0x000d, 0x23d4: 0x000d, 0x23d5: 0x000d, 0x23d6: 0x000d, 0x23d7: 0x000d,
 	0x23d8: 0x000d, 0x23d9: 0x000d, 0x23da: 0x000d, 0x23db: 0x000d, 0x23dc: 0x000d, 0x23dd: 0x000d,
 	0x23de: 0x000d, 0x23df: 0x000d, 0x23e0: 0x000d, 0x23e1: 0x000d, 0x23e2: 0x000d, 0x23e3: 0x000d,
@@ -1138,143 +1144,143 @@
 	0x23ea: 0x000d, 0x23eb: 0x000d, 0x23ec: 0x000d, 0x23ed: 0x000d, 0x23ee: 0x000d, 0x23ef: 0x000d,
 	0x23f0: 0x000d, 0x23f1: 0x000d, 0x23f2: 0x000d, 0x23f3: 0x000d, 0x23f4: 0x000d, 0x23f5: 0x000d,
 	0x23f6: 0x000d, 0x23f7: 0x000d, 0x23f8: 0x000d, 0x23f9: 0x000d, 0x23fa: 0x000d, 0x23fb: 0x000d,
-	0x23fc: 0x000d, 0x23fd: 0x000d, 0x23fe: 0x000d, 0x23ff: 0x000d,
+	0x23fc: 0x000d, 0x23fd: 0x000d, 0x23fe: 0x000a, 0x23ff: 0x000a,
 	// Block 0x90, offset 0x2400
 	0x2400: 0x000d, 0x2401: 0x000d, 0x2402: 0x000d, 0x2403: 0x000d, 0x2404: 0x000d, 0x2405: 0x000d,
 	0x2406: 0x000d, 0x2407: 0x000d, 0x2408: 0x000d, 0x2409: 0x000d, 0x240a: 0x000d, 0x240b: 0x000d,
-	0x240c: 0x000d, 0x240d: 0x000d, 0x240e: 0x000d, 0x240f: 0x000d, 0x2410: 0x000d, 0x2411: 0x000d,
-	0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d,
-	0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d,
-	0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d,
-	0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d,
-	0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d,
+	0x240c: 0x000d, 0x240d: 0x000d, 0x240e: 0x000d, 0x240f: 0x000d, 0x2410: 0x000b, 0x2411: 0x000b,
+	0x2412: 0x000b, 0x2413: 0x000b, 0x2414: 0x000b, 0x2415: 0x000b, 0x2416: 0x000b, 0x2417: 0x000b,
+	0x2418: 0x000b, 0x2419: 0x000b, 0x241a: 0x000b, 0x241b: 0x000b, 0x241c: 0x000b, 0x241d: 0x000b,
+	0x241e: 0x000b, 0x241f: 0x000b, 0x2420: 0x000b, 0x2421: 0x000b, 0x2422: 0x000b, 0x2423: 0x000b,
+	0x2424: 0x000b, 0x2425: 0x000b, 0x2426: 0x000b, 0x2427: 0x000b, 0x2428: 0x000b, 0x2429: 0x000b,
+	0x242a: 0x000b, 0x242b: 0x000b, 0x242c: 0x000b, 0x242d: 0x000b, 0x242e: 0x000b, 0x242f: 0x000b,
 	0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d,
 	0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d,
-	0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000a, 0x243f: 0x000a,
+	0x243c: 0x000d, 0x243d: 0x000a, 0x243e: 0x000d, 0x243f: 0x000d,
 	// Block 0x91, offset 0x2440
-	0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d,
-	0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d,
-	0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000b, 0x2451: 0x000b,
-	0x2452: 0x000b, 0x2453: 0x000b, 0x2454: 0x000b, 0x2455: 0x000b, 0x2456: 0x000b, 0x2457: 0x000b,
-	0x2458: 0x000b, 0x2459: 0x000b, 0x245a: 0x000b, 0x245b: 0x000b, 0x245c: 0x000b, 0x245d: 0x000b,
-	0x245e: 0x000b, 0x245f: 0x000b, 0x2460: 0x000b, 0x2461: 0x000b, 0x2462: 0x000b, 0x2463: 0x000b,
-	0x2464: 0x000b, 0x2465: 0x000b, 0x2466: 0x000b, 0x2467: 0x000b, 0x2468: 0x000b, 0x2469: 0x000b,
-	0x246a: 0x000b, 0x246b: 0x000b, 0x246c: 0x000b, 0x246d: 0x000b, 0x246e: 0x000b, 0x246f: 0x000b,
-	0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d,
-	0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d,
-	0x247c: 0x000d, 0x247d: 0x000a, 0x247e: 0x000d, 0x247f: 0x000d,
+	0x2440: 0x000c, 0x2441: 0x000c, 0x2442: 0x000c, 0x2443: 0x000c, 0x2444: 0x000c, 0x2445: 0x000c,
+	0x2446: 0x000c, 0x2447: 0x000c, 0x2448: 0x000c, 0x2449: 0x000c, 0x244a: 0x000c, 0x244b: 0x000c,
+	0x244c: 0x000c, 0x244d: 0x000c, 0x244e: 0x000c, 0x244f: 0x000c, 0x2450: 0x000a, 0x2451: 0x000a,
+	0x2452: 0x000a, 0x2453: 0x000a, 0x2454: 0x000a, 0x2455: 0x000a, 0x2456: 0x000a, 0x2457: 0x000a,
+	0x2458: 0x000a, 0x2459: 0x000a,
+	0x2460: 0x000c, 0x2461: 0x000c, 0x2462: 0x000c, 0x2463: 0x000c,
+	0x2464: 0x000c, 0x2465: 0x000c, 0x2466: 0x000c, 0x2467: 0x000c, 0x2468: 0x000c, 0x2469: 0x000c,
+	0x246a: 0x000c, 0x246b: 0x000c, 0x246c: 0x000c, 0x246d: 0x000c, 0x246e: 0x000c, 0x246f: 0x000c,
+	0x2470: 0x000a, 0x2471: 0x000a, 0x2472: 0x000a, 0x2473: 0x000a, 0x2474: 0x000a, 0x2475: 0x000a,
+	0x2476: 0x000a, 0x2477: 0x000a, 0x2478: 0x000a, 0x2479: 0x000a, 0x247a: 0x000a, 0x247b: 0x000a,
+	0x247c: 0x000a, 0x247d: 0x000a, 0x247e: 0x000a, 0x247f: 0x000a,
 	// Block 0x92, offset 0x2480
-	0x2480: 0x000c, 0x2481: 0x000c, 0x2482: 0x000c, 0x2483: 0x000c, 0x2484: 0x000c, 0x2485: 0x000c,
-	0x2486: 0x000c, 0x2487: 0x000c, 0x2488: 0x000c, 0x2489: 0x000c, 0x248a: 0x000c, 0x248b: 0x000c,
-	0x248c: 0x000c, 0x248d: 0x000c, 0x248e: 0x000c, 0x248f: 0x000c, 0x2490: 0x000a, 0x2491: 0x000a,
-	0x2492: 0x000a, 0x2493: 0x000a, 0x2494: 0x000a, 0x2495: 0x000a, 0x2496: 0x000a, 0x2497: 0x000a,
-	0x2498: 0x000a, 0x2499: 0x000a,
-	0x24a0: 0x000c, 0x24a1: 0x000c, 0x24a2: 0x000c, 0x24a3: 0x000c,
-	0x24a4: 0x000c, 0x24a5: 0x000c, 0x24a6: 0x000c, 0x24a7: 0x000c, 0x24a8: 0x000c, 0x24a9: 0x000c,
-	0x24aa: 0x000c, 0x24ab: 0x000c, 0x24ac: 0x000c, 0x24ad: 0x000c, 0x24ae: 0x000c, 0x24af: 0x000c,
-	0x24b0: 0x000a, 0x24b1: 0x000a, 0x24b2: 0x000a, 0x24b3: 0x000a, 0x24b4: 0x000a, 0x24b5: 0x000a,
-	0x24b6: 0x000a, 0x24b7: 0x000a, 0x24b8: 0x000a, 0x24b9: 0x000a, 0x24ba: 0x000a, 0x24bb: 0x000a,
-	0x24bc: 0x000a, 0x24bd: 0x000a, 0x24be: 0x000a, 0x24bf: 0x000a,
+	0x2480: 0x000a, 0x2481: 0x000a, 0x2482: 0x000a, 0x2483: 0x000a, 0x2484: 0x000a, 0x2485: 0x000a,
+	0x2486: 0x000a, 0x2487: 0x000a, 0x2488: 0x000a, 0x2489: 0x000a, 0x248a: 0x000a, 0x248b: 0x000a,
+	0x248c: 0x000a, 0x248d: 0x000a, 0x248e: 0x000a, 0x248f: 0x000a, 0x2490: 0x0006, 0x2491: 0x000a,
+	0x2492: 0x0006, 0x2494: 0x000a, 0x2495: 0x0006, 0x2496: 0x000a, 0x2497: 0x000a,
+	0x2498: 0x000a, 0x2499: 0x009a, 0x249a: 0x008a, 0x249b: 0x007a, 0x249c: 0x006a, 0x249d: 0x009a,
+	0x249e: 0x008a, 0x249f: 0x0004, 0x24a0: 0x000a, 0x24a1: 0x000a, 0x24a2: 0x0003, 0x24a3: 0x0003,
+	0x24a4: 0x000a, 0x24a5: 0x000a, 0x24a6: 0x000a, 0x24a8: 0x000a, 0x24a9: 0x0004,
+	0x24aa: 0x0004, 0x24ab: 0x000a,
+	0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d,
+	0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d,
+	0x24bc: 0x000d, 0x24bd: 0x000d, 0x24be: 0x000d, 0x24bf: 0x000d,
 	// Block 0x93, offset 0x24c0
-	0x24c0: 0x000a, 0x24c1: 0x000a, 0x24c2: 0x000a, 0x24c3: 0x000a, 0x24c4: 0x000a, 0x24c5: 0x000a,
-	0x24c6: 0x000a, 0x24c7: 0x000a, 0x24c8: 0x000a, 0x24c9: 0x000a, 0x24ca: 0x000a, 0x24cb: 0x000a,
-	0x24cc: 0x000a, 0x24cd: 0x000a, 0x24ce: 0x000a, 0x24cf: 0x000a, 0x24d0: 0x0006, 0x24d1: 0x000a,
-	0x24d2: 0x0006, 0x24d4: 0x000a, 0x24d5: 0x0006, 0x24d6: 0x000a, 0x24d7: 0x000a,
-	0x24d8: 0x000a, 0x24d9: 0x009a, 0x24da: 0x008a, 0x24db: 0x007a, 0x24dc: 0x006a, 0x24dd: 0x009a,
-	0x24de: 0x008a, 0x24df: 0x0004, 0x24e0: 0x000a, 0x24e1: 0x000a, 0x24e2: 0x0003, 0x24e3: 0x0003,
-	0x24e4: 0x000a, 0x24e5: 0x000a, 0x24e6: 0x000a, 0x24e8: 0x000a, 0x24e9: 0x0004,
-	0x24ea: 0x0004, 0x24eb: 0x000a,
+	0x24c0: 0x000d, 0x24c1: 0x000d, 0x24c2: 0x000d, 0x24c3: 0x000d, 0x24c4: 0x000d, 0x24c5: 0x000d,
+	0x24c6: 0x000d, 0x24c7: 0x000d, 0x24c8: 0x000d, 0x24c9: 0x000d, 0x24ca: 0x000d, 0x24cb: 0x000d,
+	0x24cc: 0x000d, 0x24cd: 0x000d, 0x24ce: 0x000d, 0x24cf: 0x000d, 0x24d0: 0x000d, 0x24d1: 0x000d,
+	0x24d2: 0x000d, 0x24d3: 0x000d, 0x24d4: 0x000d, 0x24d5: 0x000d, 0x24d6: 0x000d, 0x24d7: 0x000d,
+	0x24d8: 0x000d, 0x24d9: 0x000d, 0x24da: 0x000d, 0x24db: 0x000d, 0x24dc: 0x000d, 0x24dd: 0x000d,
+	0x24de: 0x000d, 0x24df: 0x000d, 0x24e0: 0x000d, 0x24e1: 0x000d, 0x24e2: 0x000d, 0x24e3: 0x000d,
+	0x24e4: 0x000d, 0x24e5: 0x000d, 0x24e6: 0x000d, 0x24e7: 0x000d, 0x24e8: 0x000d, 0x24e9: 0x000d,
+	0x24ea: 0x000d, 0x24eb: 0x000d, 0x24ec: 0x000d, 0x24ed: 0x000d, 0x24ee: 0x000d, 0x24ef: 0x000d,
 	0x24f0: 0x000d, 0x24f1: 0x000d, 0x24f2: 0x000d, 0x24f3: 0x000d, 0x24f4: 0x000d, 0x24f5: 0x000d,
 	0x24f6: 0x000d, 0x24f7: 0x000d, 0x24f8: 0x000d, 0x24f9: 0x000d, 0x24fa: 0x000d, 0x24fb: 0x000d,
-	0x24fc: 0x000d, 0x24fd: 0x000d, 0x24fe: 0x000d, 0x24ff: 0x000d,
+	0x24fc: 0x000d, 0x24fd: 0x000d, 0x24fe: 0x000d, 0x24ff: 0x000b,
 	// Block 0x94, offset 0x2500
-	0x2500: 0x000d, 0x2501: 0x000d, 0x2502: 0x000d, 0x2503: 0x000d, 0x2504: 0x000d, 0x2505: 0x000d,
-	0x2506: 0x000d, 0x2507: 0x000d, 0x2508: 0x000d, 0x2509: 0x000d, 0x250a: 0x000d, 0x250b: 0x000d,
-	0x250c: 0x000d, 0x250d: 0x000d, 0x250e: 0x000d, 0x250f: 0x000d, 0x2510: 0x000d, 0x2511: 0x000d,
-	0x2512: 0x000d, 0x2513: 0x000d, 0x2514: 0x000d, 0x2515: 0x000d, 0x2516: 0x000d, 0x2517: 0x000d,
-	0x2518: 0x000d, 0x2519: 0x000d, 0x251a: 0x000d, 0x251b: 0x000d, 0x251c: 0x000d, 0x251d: 0x000d,
-	0x251e: 0x000d, 0x251f: 0x000d, 0x2520: 0x000d, 0x2521: 0x000d, 0x2522: 0x000d, 0x2523: 0x000d,
-	0x2524: 0x000d, 0x2525: 0x000d, 0x2526: 0x000d, 0x2527: 0x000d, 0x2528: 0x000d, 0x2529: 0x000d,
-	0x252a: 0x000d, 0x252b: 0x000d, 0x252c: 0x000d, 0x252d: 0x000d, 0x252e: 0x000d, 0x252f: 0x000d,
-	0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d,
-	0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d,
-	0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000b,
+	0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x0004, 0x2504: 0x0004, 0x2505: 0x0004,
+	0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x003a, 0x2509: 0x002a, 0x250a: 0x000a, 0x250b: 0x0003,
+	0x250c: 0x0006, 0x250d: 0x0003, 0x250e: 0x0006, 0x250f: 0x0006, 0x2510: 0x0002, 0x2511: 0x0002,
+	0x2512: 0x0002, 0x2513: 0x0002, 0x2514: 0x0002, 0x2515: 0x0002, 0x2516: 0x0002, 0x2517: 0x0002,
+	0x2518: 0x0002, 0x2519: 0x0002, 0x251a: 0x0006, 0x251b: 0x000a, 0x251c: 0x000a, 0x251d: 0x000a,
+	0x251e: 0x000a, 0x251f: 0x000a, 0x2520: 0x000a,
+	0x253b: 0x005a,
+	0x253c: 0x000a, 0x253d: 0x004a, 0x253e: 0x000a, 0x253f: 0x000a,
 	// Block 0x95, offset 0x2540
-	0x2541: 0x000a, 0x2542: 0x000a, 0x2543: 0x0004, 0x2544: 0x0004, 0x2545: 0x0004,
-	0x2546: 0x000a, 0x2547: 0x000a, 0x2548: 0x003a, 0x2549: 0x002a, 0x254a: 0x000a, 0x254b: 0x0003,
-	0x254c: 0x0006, 0x254d: 0x0003, 0x254e: 0x0006, 0x254f: 0x0006, 0x2550: 0x0002, 0x2551: 0x0002,
-	0x2552: 0x0002, 0x2553: 0x0002, 0x2554: 0x0002, 0x2555: 0x0002, 0x2556: 0x0002, 0x2557: 0x0002,
-	0x2558: 0x0002, 0x2559: 0x0002, 0x255a: 0x0006, 0x255b: 0x000a, 0x255c: 0x000a, 0x255d: 0x000a,
-	0x255e: 0x000a, 0x255f: 0x000a, 0x2560: 0x000a,
-	0x257b: 0x005a,
-	0x257c: 0x000a, 0x257d: 0x004a, 0x257e: 0x000a, 0x257f: 0x000a,
+	0x2540: 0x000a,
+	0x255b: 0x005a, 0x255c: 0x000a, 0x255d: 0x004a,
+	0x255e: 0x000a, 0x255f: 0x00fa, 0x2560: 0x00ea, 0x2561: 0x000a, 0x2562: 0x003a, 0x2563: 0x002a,
+	0x2564: 0x000a, 0x2565: 0x000a,
 	// Block 0x96, offset 0x2580
-	0x2580: 0x000a,
-	0x259b: 0x005a, 0x259c: 0x000a, 0x259d: 0x004a,
-	0x259e: 0x000a, 0x259f: 0x00fa, 0x25a0: 0x00ea, 0x25a1: 0x000a, 0x25a2: 0x003a, 0x25a3: 0x002a,
-	0x25a4: 0x000a, 0x25a5: 0x000a,
+	0x25a0: 0x0004, 0x25a1: 0x0004, 0x25a2: 0x000a, 0x25a3: 0x000a,
+	0x25a4: 0x000a, 0x25a5: 0x0004, 0x25a6: 0x0004, 0x25a8: 0x000a, 0x25a9: 0x000a,
+	0x25aa: 0x000a, 0x25ab: 0x000a, 0x25ac: 0x000a, 0x25ad: 0x000a, 0x25ae: 0x000a,
+	0x25b0: 0x000b, 0x25b1: 0x000b, 0x25b2: 0x000b, 0x25b3: 0x000b, 0x25b4: 0x000b, 0x25b5: 0x000b,
+	0x25b6: 0x000b, 0x25b7: 0x000b, 0x25b8: 0x000b, 0x25b9: 0x000a, 0x25ba: 0x000a, 0x25bb: 0x000a,
+	0x25bc: 0x000a, 0x25bd: 0x000a, 0x25be: 0x000b, 0x25bf: 0x000b,
 	// Block 0x97, offset 0x25c0
-	0x25e0: 0x0004, 0x25e1: 0x0004, 0x25e2: 0x000a, 0x25e3: 0x000a,
-	0x25e4: 0x000a, 0x25e5: 0x0004, 0x25e6: 0x0004, 0x25e8: 0x000a, 0x25e9: 0x000a,
-	0x25ea: 0x000a, 0x25eb: 0x000a, 0x25ec: 0x000a, 0x25ed: 0x000a, 0x25ee: 0x000a,
-	0x25f0: 0x000b, 0x25f1: 0x000b, 0x25f2: 0x000b, 0x25f3: 0x000b, 0x25f4: 0x000b, 0x25f5: 0x000b,
-	0x25f6: 0x000b, 0x25f7: 0x000b, 0x25f8: 0x000b, 0x25f9: 0x000a, 0x25fa: 0x000a, 0x25fb: 0x000a,
-	0x25fc: 0x000a, 0x25fd: 0x000a, 0x25fe: 0x000b, 0x25ff: 0x000b,
+	0x25c1: 0x000a,
 	// Block 0x98, offset 0x2600
-	0x2601: 0x000a,
+	0x2600: 0x000a, 0x2601: 0x000a, 0x2602: 0x000a, 0x2603: 0x000a, 0x2604: 0x000a, 0x2605: 0x000a,
+	0x2606: 0x000a, 0x2607: 0x000a, 0x2608: 0x000a, 0x2609: 0x000a, 0x260a: 0x000a, 0x260b: 0x000a,
+	0x260c: 0x000a, 0x2610: 0x000a, 0x2611: 0x000a,
+	0x2612: 0x000a, 0x2613: 0x000a, 0x2614: 0x000a, 0x2615: 0x000a, 0x2616: 0x000a, 0x2617: 0x000a,
+	0x2618: 0x000a, 0x2619: 0x000a, 0x261a: 0x000a, 0x261b: 0x000a,
+	0x2620: 0x000a,
 	// Block 0x99, offset 0x2640
-	0x2640: 0x000a, 0x2641: 0x000a, 0x2642: 0x000a, 0x2643: 0x000a, 0x2644: 0x000a, 0x2645: 0x000a,
-	0x2646: 0x000a, 0x2647: 0x000a, 0x2648: 0x000a, 0x2649: 0x000a, 0x264a: 0x000a, 0x264b: 0x000a,
-	0x264c: 0x000a, 0x2650: 0x000a, 0x2651: 0x000a,
-	0x2652: 0x000a, 0x2653: 0x000a, 0x2654: 0x000a, 0x2655: 0x000a, 0x2656: 0x000a, 0x2657: 0x000a,
-	0x2658: 0x000a, 0x2659: 0x000a, 0x265a: 0x000a, 0x265b: 0x000a,
-	0x2660: 0x000a,
+	0x267d: 0x000c,
 	// Block 0x9a, offset 0x2680
-	0x26bd: 0x000c,
+	0x26a0: 0x000c, 0x26a1: 0x0002, 0x26a2: 0x0002, 0x26a3: 0x0002,
+	0x26a4: 0x0002, 0x26a5: 0x0002, 0x26a6: 0x0002, 0x26a7: 0x0002, 0x26a8: 0x0002, 0x26a9: 0x0002,
+	0x26aa: 0x0002, 0x26ab: 0x0002, 0x26ac: 0x0002, 0x26ad: 0x0002, 0x26ae: 0x0002, 0x26af: 0x0002,
+	0x26b0: 0x0002, 0x26b1: 0x0002, 0x26b2: 0x0002, 0x26b3: 0x0002, 0x26b4: 0x0002, 0x26b5: 0x0002,
+	0x26b6: 0x0002, 0x26b7: 0x0002, 0x26b8: 0x0002, 0x26b9: 0x0002, 0x26ba: 0x0002, 0x26bb: 0x0002,
 	// Block 0x9b, offset 0x26c0
-	0x26e0: 0x000c, 0x26e1: 0x0002, 0x26e2: 0x0002, 0x26e3: 0x0002,
-	0x26e4: 0x0002, 0x26e5: 0x0002, 0x26e6: 0x0002, 0x26e7: 0x0002, 0x26e8: 0x0002, 0x26e9: 0x0002,
-	0x26ea: 0x0002, 0x26eb: 0x0002, 0x26ec: 0x0002, 0x26ed: 0x0002, 0x26ee: 0x0002, 0x26ef: 0x0002,
-	0x26f0: 0x0002, 0x26f1: 0x0002, 0x26f2: 0x0002, 0x26f3: 0x0002, 0x26f4: 0x0002, 0x26f5: 0x0002,
-	0x26f6: 0x0002, 0x26f7: 0x0002, 0x26f8: 0x0002, 0x26f9: 0x0002, 0x26fa: 0x0002, 0x26fb: 0x0002,
+	0x26f6: 0x000c, 0x26f7: 0x000c, 0x26f8: 0x000c, 0x26f9: 0x000c, 0x26fa: 0x000c,
 	// Block 0x9c, offset 0x2700
-	0x2736: 0x000c, 0x2737: 0x000c, 0x2738: 0x000c, 0x2739: 0x000c, 0x273a: 0x000c,
+	0x2700: 0x0001, 0x2701: 0x0001, 0x2702: 0x0001, 0x2703: 0x0001, 0x2704: 0x0001, 0x2705: 0x0001,
+	0x2706: 0x0001, 0x2707: 0x0001, 0x2708: 0x0001, 0x2709: 0x0001, 0x270a: 0x0001, 0x270b: 0x0001,
+	0x270c: 0x0001, 0x270d: 0x0001, 0x270e: 0x0001, 0x270f: 0x0001, 0x2710: 0x0001, 0x2711: 0x0001,
+	0x2712: 0x0001, 0x2713: 0x0001, 0x2714: 0x0001, 0x2715: 0x0001, 0x2716: 0x0001, 0x2717: 0x0001,
+	0x2718: 0x0001, 0x2719: 0x0001, 0x271a: 0x0001, 0x271b: 0x0001, 0x271c: 0x0001, 0x271d: 0x0001,
+	0x271e: 0x0001, 0x271f: 0x0001, 0x2720: 0x0001, 0x2721: 0x0001, 0x2722: 0x0001, 0x2723: 0x0001,
+	0x2724: 0x0001, 0x2725: 0x0001, 0x2726: 0x0001, 0x2727: 0x0001, 0x2728: 0x0001, 0x2729: 0x0001,
+	0x272a: 0x0001, 0x272b: 0x0001, 0x272c: 0x0001, 0x272d: 0x0001, 0x272e: 0x0001, 0x272f: 0x0001,
+	0x2730: 0x0001, 0x2731: 0x0001, 0x2732: 0x0001, 0x2733: 0x0001, 0x2734: 0x0001, 0x2735: 0x0001,
+	0x2736: 0x0001, 0x2737: 0x0001, 0x2738: 0x0001, 0x2739: 0x0001, 0x273a: 0x0001, 0x273b: 0x0001,
+	0x273c: 0x0001, 0x273d: 0x0001, 0x273e: 0x0001, 0x273f: 0x0001,
 	// Block 0x9d, offset 0x2740
 	0x2740: 0x0001, 0x2741: 0x0001, 0x2742: 0x0001, 0x2743: 0x0001, 0x2744: 0x0001, 0x2745: 0x0001,
 	0x2746: 0x0001, 0x2747: 0x0001, 0x2748: 0x0001, 0x2749: 0x0001, 0x274a: 0x0001, 0x274b: 0x0001,
 	0x274c: 0x0001, 0x274d: 0x0001, 0x274e: 0x0001, 0x274f: 0x0001, 0x2750: 0x0001, 0x2751: 0x0001,
 	0x2752: 0x0001, 0x2753: 0x0001, 0x2754: 0x0001, 0x2755: 0x0001, 0x2756: 0x0001, 0x2757: 0x0001,
 	0x2758: 0x0001, 0x2759: 0x0001, 0x275a: 0x0001, 0x275b: 0x0001, 0x275c: 0x0001, 0x275d: 0x0001,
-	0x275e: 0x0001, 0x275f: 0x0001, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001,
+	0x275e: 0x0001, 0x275f: 0x000a, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001,
 	0x2764: 0x0001, 0x2765: 0x0001, 0x2766: 0x0001, 0x2767: 0x0001, 0x2768: 0x0001, 0x2769: 0x0001,
 	0x276a: 0x0001, 0x276b: 0x0001, 0x276c: 0x0001, 0x276d: 0x0001, 0x276e: 0x0001, 0x276f: 0x0001,
 	0x2770: 0x0001, 0x2771: 0x0001, 0x2772: 0x0001, 0x2773: 0x0001, 0x2774: 0x0001, 0x2775: 0x0001,
 	0x2776: 0x0001, 0x2777: 0x0001, 0x2778: 0x0001, 0x2779: 0x0001, 0x277a: 0x0001, 0x277b: 0x0001,
 	0x277c: 0x0001, 0x277d: 0x0001, 0x277e: 0x0001, 0x277f: 0x0001,
 	// Block 0x9e, offset 0x2780
-	0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001,
-	0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001,
-	0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001,
+	0x2780: 0x0001, 0x2781: 0x000c, 0x2782: 0x000c, 0x2783: 0x000c, 0x2784: 0x0001, 0x2785: 0x000c,
+	0x2786: 0x000c, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001,
+	0x278c: 0x000c, 0x278d: 0x000c, 0x278e: 0x000c, 0x278f: 0x000c, 0x2790: 0x0001, 0x2791: 0x0001,
 	0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001,
 	0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001,
-	0x279e: 0x0001, 0x279f: 0x000a, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001,
+	0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001,
 	0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001,
 	0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001,
 	0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001,
-	0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001,
-	0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001,
+	0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x000c, 0x27b9: 0x000c, 0x27ba: 0x000c, 0x27bb: 0x0001,
+	0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x000c,
 	// Block 0x9f, offset 0x27c0
-	0x27c0: 0x0001, 0x27c1: 0x000c, 0x27c2: 0x000c, 0x27c3: 0x000c, 0x27c4: 0x0001, 0x27c5: 0x000c,
-	0x27c6: 0x000c, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001,
-	0x27cc: 0x000c, 0x27cd: 0x000c, 0x27ce: 0x000c, 0x27cf: 0x000c, 0x27d0: 0x0001, 0x27d1: 0x0001,
+	0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001,
+	0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001,
+	0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001,
 	0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001,
 	0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001,
 	0x27de: 0x0001, 0x27df: 0x0001, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001,
-	0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001,
+	0x27e4: 0x0001, 0x27e5: 0x000c, 0x27e6: 0x000c, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001,
 	0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001,
 	0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001,
-	0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x000c, 0x27f9: 0x000c, 0x27fa: 0x000c, 0x27fb: 0x0001,
-	0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x000c,
+	0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001,
+	0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001,
 	// Block 0xa0, offset 0x2800
 	0x2800: 0x0001, 0x2801: 0x0001, 0x2802: 0x0001, 0x2803: 0x0001, 0x2804: 0x0001, 0x2805: 0x0001,
 	0x2806: 0x0001, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001,
@@ -1282,382 +1288,409 @@
 	0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001,
 	0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001,
 	0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001,
-	0x2824: 0x0001, 0x2825: 0x000c, 0x2826: 0x000c, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001,
+	0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001,
 	0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001,
 	0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001,
-	0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x0001, 0x2839: 0x0001, 0x283a: 0x0001, 0x283b: 0x0001,
-	0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x0001,
+	0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x0001, 0x2839: 0x000a, 0x283a: 0x000a, 0x283b: 0x000a,
+	0x283c: 0x000a, 0x283d: 0x000a, 0x283e: 0x000a, 0x283f: 0x000a,
 	// Block 0xa1, offset 0x2840
 	0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001,
 	0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001,
 	0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001,
 	0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001,
 	0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001,
-	0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001,
-	0x2864: 0x0001, 0x2865: 0x0001, 0x2866: 0x0001, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001,
-	0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001,
-	0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001,
-	0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x000a, 0x287a: 0x000a, 0x287b: 0x000a,
-	0x287c: 0x000a, 0x287d: 0x000a, 0x287e: 0x000a, 0x287f: 0x000a,
+	0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0005, 0x2861: 0x0005, 0x2862: 0x0005, 0x2863: 0x0005,
+	0x2864: 0x0005, 0x2865: 0x0005, 0x2866: 0x0005, 0x2867: 0x0005, 0x2868: 0x0005, 0x2869: 0x0005,
+	0x286a: 0x0005, 0x286b: 0x0005, 0x286c: 0x0005, 0x286d: 0x0005, 0x286e: 0x0005, 0x286f: 0x0005,
+	0x2870: 0x0005, 0x2871: 0x0005, 0x2872: 0x0005, 0x2873: 0x0005, 0x2874: 0x0005, 0x2875: 0x0005,
+	0x2876: 0x0005, 0x2877: 0x0005, 0x2878: 0x0005, 0x2879: 0x0005, 0x287a: 0x0005, 0x287b: 0x0005,
+	0x287c: 0x0005, 0x287d: 0x0005, 0x287e: 0x0005, 0x287f: 0x0001,
 	// Block 0xa2, offset 0x2880
-	0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001,
-	0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001,
-	0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001,
-	0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001,
-	0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001,
-	0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0005, 0x28a1: 0x0005, 0x28a2: 0x0005, 0x28a3: 0x0005,
-	0x28a4: 0x0005, 0x28a5: 0x0005, 0x28a6: 0x0005, 0x28a7: 0x0005, 0x28a8: 0x0005, 0x28a9: 0x0005,
-	0x28aa: 0x0005, 0x28ab: 0x0005, 0x28ac: 0x0005, 0x28ad: 0x0005, 0x28ae: 0x0005, 0x28af: 0x0005,
-	0x28b0: 0x0005, 0x28b1: 0x0005, 0x28b2: 0x0005, 0x28b3: 0x0005, 0x28b4: 0x0005, 0x28b5: 0x0005,
-	0x28b6: 0x0005, 0x28b7: 0x0005, 0x28b8: 0x0005, 0x28b9: 0x0005, 0x28ba: 0x0005, 0x28bb: 0x0005,
-	0x28bc: 0x0005, 0x28bd: 0x0005, 0x28be: 0x0005, 0x28bf: 0x0001,
+	0x2881: 0x000c,
+	0x28b8: 0x000c, 0x28b9: 0x000c, 0x28ba: 0x000c, 0x28bb: 0x000c,
+	0x28bc: 0x000c, 0x28bd: 0x000c, 0x28be: 0x000c, 0x28bf: 0x000c,
 	// Block 0xa3, offset 0x28c0
-	0x28c1: 0x000c,
-	0x28f8: 0x000c, 0x28f9: 0x000c, 0x28fa: 0x000c, 0x28fb: 0x000c,
-	0x28fc: 0x000c, 0x28fd: 0x000c, 0x28fe: 0x000c, 0x28ff: 0x000c,
+	0x28c0: 0x000c, 0x28c1: 0x000c, 0x28c2: 0x000c, 0x28c3: 0x000c, 0x28c4: 0x000c, 0x28c5: 0x000c,
+	0x28c6: 0x000c,
+	0x28d2: 0x000a, 0x28d3: 0x000a, 0x28d4: 0x000a, 0x28d5: 0x000a, 0x28d6: 0x000a, 0x28d7: 0x000a,
+	0x28d8: 0x000a, 0x28d9: 0x000a, 0x28da: 0x000a, 0x28db: 0x000a, 0x28dc: 0x000a, 0x28dd: 0x000a,
+	0x28de: 0x000a, 0x28df: 0x000a, 0x28e0: 0x000a, 0x28e1: 0x000a, 0x28e2: 0x000a, 0x28e3: 0x000a,
+	0x28e4: 0x000a, 0x28e5: 0x000a,
+	0x28ff: 0x000c,
 	// Block 0xa4, offset 0x2900
-	0x2900: 0x000c, 0x2901: 0x000c, 0x2902: 0x000c, 0x2903: 0x000c, 0x2904: 0x000c, 0x2905: 0x000c,
-	0x2906: 0x000c,
-	0x2912: 0x000a, 0x2913: 0x000a, 0x2914: 0x000a, 0x2915: 0x000a, 0x2916: 0x000a, 0x2917: 0x000a,
-	0x2918: 0x000a, 0x2919: 0x000a, 0x291a: 0x000a, 0x291b: 0x000a, 0x291c: 0x000a, 0x291d: 0x000a,
-	0x291e: 0x000a, 0x291f: 0x000a, 0x2920: 0x000a, 0x2921: 0x000a, 0x2922: 0x000a, 0x2923: 0x000a,
-	0x2924: 0x000a, 0x2925: 0x000a,
-	0x293f: 0x000c,
+	0x2900: 0x000c, 0x2901: 0x000c,
+	0x2933: 0x000c, 0x2934: 0x000c, 0x2935: 0x000c,
+	0x2936: 0x000c, 0x2939: 0x000c, 0x293a: 0x000c,
 	// Block 0xa5, offset 0x2940
-	0x2940: 0x000c, 0x2941: 0x000c,
-	0x2973: 0x000c, 0x2974: 0x000c, 0x2975: 0x000c,
-	0x2976: 0x000c, 0x2979: 0x000c, 0x297a: 0x000c,
+	0x2940: 0x000c, 0x2941: 0x000c, 0x2942: 0x000c,
+	0x2967: 0x000c, 0x2968: 0x000c, 0x2969: 0x000c,
+	0x296a: 0x000c, 0x296b: 0x000c, 0x296d: 0x000c, 0x296e: 0x000c, 0x296f: 0x000c,
+	0x2970: 0x000c, 0x2971: 0x000c, 0x2972: 0x000c, 0x2973: 0x000c, 0x2974: 0x000c,
 	// Block 0xa6, offset 0x2980
-	0x2980: 0x000c, 0x2981: 0x000c, 0x2982: 0x000c,
-	0x29a7: 0x000c, 0x29a8: 0x000c, 0x29a9: 0x000c,
-	0x29aa: 0x000c, 0x29ab: 0x000c, 0x29ad: 0x000c, 0x29ae: 0x000c, 0x29af: 0x000c,
-	0x29b0: 0x000c, 0x29b1: 0x000c, 0x29b2: 0x000c, 0x29b3: 0x000c, 0x29b4: 0x000c,
+	0x29b3: 0x000c,
 	// Block 0xa7, offset 0x29c0
-	0x29f3: 0x000c,
+	0x29c0: 0x000c, 0x29c1: 0x000c,
+	0x29f6: 0x000c, 0x29f7: 0x000c, 0x29f8: 0x000c, 0x29f9: 0x000c, 0x29fa: 0x000c, 0x29fb: 0x000c,
+	0x29fc: 0x000c, 0x29fd: 0x000c, 0x29fe: 0x000c,
 	// Block 0xa8, offset 0x2a00
-	0x2a00: 0x000c, 0x2a01: 0x000c,
-	0x2a36: 0x000c, 0x2a37: 0x000c, 0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c,
-	0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c,
+	0x2a0a: 0x000c, 0x2a0b: 0x000c,
+	0x2a0c: 0x000c,
 	// Block 0xa9, offset 0x2a40
-	0x2a4a: 0x000c, 0x2a4b: 0x000c,
-	0x2a4c: 0x000c,
+	0x2a6f: 0x000c,
+	0x2a70: 0x000c, 0x2a71: 0x000c, 0x2a74: 0x000c,
+	0x2a76: 0x000c, 0x2a77: 0x000c,
+	0x2a7e: 0x000c,
 	// Block 0xaa, offset 0x2a80
-	0x2aaf: 0x000c,
-	0x2ab0: 0x000c, 0x2ab1: 0x000c, 0x2ab4: 0x000c,
-	0x2ab6: 0x000c, 0x2ab7: 0x000c,
-	0x2abe: 0x000c,
+	0x2a9f: 0x000c, 0x2aa3: 0x000c,
+	0x2aa4: 0x000c, 0x2aa5: 0x000c, 0x2aa6: 0x000c, 0x2aa7: 0x000c, 0x2aa8: 0x000c, 0x2aa9: 0x000c,
+	0x2aaa: 0x000c,
 	// Block 0xab, offset 0x2ac0
-	0x2adf: 0x000c, 0x2ae3: 0x000c,
-	0x2ae4: 0x000c, 0x2ae5: 0x000c, 0x2ae6: 0x000c, 0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c,
-	0x2aea: 0x000c,
+	0x2ac0: 0x000c, 0x2ac1: 0x000c,
+	0x2afc: 0x000c,
 	// Block 0xac, offset 0x2b00
-	0x2b00: 0x000c, 0x2b01: 0x000c,
-	0x2b3c: 0x000c,
+	0x2b00: 0x000c,
+	0x2b26: 0x000c, 0x2b27: 0x000c, 0x2b28: 0x000c, 0x2b29: 0x000c,
+	0x2b2a: 0x000c, 0x2b2b: 0x000c, 0x2b2c: 0x000c,
+	0x2b30: 0x000c, 0x2b31: 0x000c, 0x2b32: 0x000c, 0x2b33: 0x000c, 0x2b34: 0x000c,
 	// Block 0xad, offset 0x2b40
-	0x2b40: 0x000c,
-	0x2b66: 0x000c, 0x2b67: 0x000c, 0x2b68: 0x000c, 0x2b69: 0x000c,
-	0x2b6a: 0x000c, 0x2b6b: 0x000c, 0x2b6c: 0x000c,
-	0x2b70: 0x000c, 0x2b71: 0x000c, 0x2b72: 0x000c, 0x2b73: 0x000c, 0x2b74: 0x000c,
+	0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c,
+	0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c, 0x2b7f: 0x000c,
 	// Block 0xae, offset 0x2b80
-	0x2bb8: 0x000c, 0x2bb9: 0x000c, 0x2bba: 0x000c, 0x2bbb: 0x000c,
-	0x2bbc: 0x000c, 0x2bbd: 0x000c, 0x2bbe: 0x000c, 0x2bbf: 0x000c,
+	0x2b82: 0x000c, 0x2b83: 0x000c, 0x2b84: 0x000c,
+	0x2b86: 0x000c,
 	// Block 0xaf, offset 0x2bc0
-	0x2bc2: 0x000c, 0x2bc3: 0x000c, 0x2bc4: 0x000c,
-	0x2bc6: 0x000c,
+	0x2bf3: 0x000c, 0x2bf4: 0x000c, 0x2bf5: 0x000c,
+	0x2bf6: 0x000c, 0x2bf7: 0x000c, 0x2bf8: 0x000c, 0x2bfa: 0x000c,
+	0x2bff: 0x000c,
 	// Block 0xb0, offset 0x2c00
-	0x2c33: 0x000c, 0x2c34: 0x000c, 0x2c35: 0x000c,
-	0x2c36: 0x000c, 0x2c37: 0x000c, 0x2c38: 0x000c, 0x2c3a: 0x000c,
-	0x2c3f: 0x000c,
+	0x2c00: 0x000c, 0x2c02: 0x000c, 0x2c03: 0x000c,
 	// Block 0xb1, offset 0x2c40
-	0x2c40: 0x000c, 0x2c42: 0x000c, 0x2c43: 0x000c,
+	0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c, 0x2c75: 0x000c,
+	0x2c7c: 0x000c, 0x2c7d: 0x000c, 0x2c7f: 0x000c,
 	// Block 0xb2, offset 0x2c80
-	0x2cb2: 0x000c, 0x2cb3: 0x000c, 0x2cb4: 0x000c, 0x2cb5: 0x000c,
-	0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbf: 0x000c,
+	0x2c80: 0x000c,
+	0x2c9c: 0x000c, 0x2c9d: 0x000c,
 	// Block 0xb3, offset 0x2cc0
-	0x2cc0: 0x000c,
-	0x2cdc: 0x000c, 0x2cdd: 0x000c,
+	0x2cf3: 0x000c, 0x2cf4: 0x000c, 0x2cf5: 0x000c,
+	0x2cf6: 0x000c, 0x2cf7: 0x000c, 0x2cf8: 0x000c, 0x2cf9: 0x000c, 0x2cfa: 0x000c,
+	0x2cfd: 0x000c, 0x2cff: 0x000c,
 	// Block 0xb4, offset 0x2d00
-	0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c,
-	0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d39: 0x000c, 0x2d3a: 0x000c,
-	0x2d3d: 0x000c, 0x2d3f: 0x000c,
+	0x2d00: 0x000c,
+	0x2d20: 0x000a, 0x2d21: 0x000a, 0x2d22: 0x000a, 0x2d23: 0x000a,
+	0x2d24: 0x000a, 0x2d25: 0x000a, 0x2d26: 0x000a, 0x2d27: 0x000a, 0x2d28: 0x000a, 0x2d29: 0x000a,
+	0x2d2a: 0x000a, 0x2d2b: 0x000a, 0x2d2c: 0x000a,
 	// Block 0xb5, offset 0x2d40
-	0x2d40: 0x000c,
-	0x2d60: 0x000a, 0x2d61: 0x000a, 0x2d62: 0x000a, 0x2d63: 0x000a,
-	0x2d64: 0x000a, 0x2d65: 0x000a, 0x2d66: 0x000a, 0x2d67: 0x000a, 0x2d68: 0x000a, 0x2d69: 0x000a,
-	0x2d6a: 0x000a, 0x2d6b: 0x000a, 0x2d6c: 0x000a,
+	0x2d6b: 0x000c, 0x2d6d: 0x000c,
+	0x2d70: 0x000c, 0x2d71: 0x000c, 0x2d72: 0x000c, 0x2d73: 0x000c, 0x2d74: 0x000c, 0x2d75: 0x000c,
+	0x2d77: 0x000c,
 	// Block 0xb6, offset 0x2d80
-	0x2dab: 0x000c, 0x2dad: 0x000c,
-	0x2db0: 0x000c, 0x2db1: 0x000c, 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c,
-	0x2db7: 0x000c,
+	0x2d9d: 0x000c,
+	0x2d9e: 0x000c, 0x2d9f: 0x000c, 0x2da2: 0x000c, 0x2da3: 0x000c,
+	0x2da4: 0x000c, 0x2da5: 0x000c, 0x2da7: 0x000c, 0x2da8: 0x000c, 0x2da9: 0x000c,
+	0x2daa: 0x000c, 0x2dab: 0x000c,
 	// Block 0xb7, offset 0x2dc0
-	0x2ddd: 0x000c,
-	0x2dde: 0x000c, 0x2ddf: 0x000c, 0x2de2: 0x000c, 0x2de3: 0x000c,
-	0x2de4: 0x000c, 0x2de5: 0x000c, 0x2de7: 0x000c, 0x2de8: 0x000c, 0x2de9: 0x000c,
-	0x2dea: 0x000c, 0x2deb: 0x000c,
+	0x2dc1: 0x000c, 0x2dc2: 0x000c, 0x2dc3: 0x000c, 0x2dc4: 0x000c, 0x2dc5: 0x000c,
+	0x2dc6: 0x000c, 0x2dc9: 0x000c, 0x2dca: 0x000c,
+	0x2df3: 0x000c, 0x2df4: 0x000c, 0x2df5: 0x000c,
+	0x2df6: 0x000c, 0x2df7: 0x000c, 0x2df8: 0x000c, 0x2dfb: 0x000c,
+	0x2dfc: 0x000c, 0x2dfd: 0x000c, 0x2dfe: 0x000c,
 	// Block 0xb8, offset 0x2e00
-	0x2e30: 0x000c, 0x2e31: 0x000c, 0x2e32: 0x000c, 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c,
-	0x2e36: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c, 0x2e3b: 0x000c,
-	0x2e3c: 0x000c, 0x2e3d: 0x000c,
+	0x2e07: 0x000c,
+	0x2e11: 0x000c,
+	0x2e12: 0x000c, 0x2e13: 0x000c, 0x2e14: 0x000c, 0x2e15: 0x000c, 0x2e16: 0x000c,
+	0x2e19: 0x000c, 0x2e1a: 0x000c, 0x2e1b: 0x000c,
 	// Block 0xb9, offset 0x2e40
-	0x2e52: 0x000c, 0x2e53: 0x000c, 0x2e54: 0x000c, 0x2e55: 0x000c, 0x2e56: 0x000c, 0x2e57: 0x000c,
-	0x2e58: 0x000c, 0x2e59: 0x000c, 0x2e5a: 0x000c, 0x2e5b: 0x000c, 0x2e5c: 0x000c, 0x2e5d: 0x000c,
-	0x2e5e: 0x000c, 0x2e5f: 0x000c, 0x2e60: 0x000c, 0x2e61: 0x000c, 0x2e62: 0x000c, 0x2e63: 0x000c,
-	0x2e64: 0x000c, 0x2e65: 0x000c, 0x2e66: 0x000c, 0x2e67: 0x000c,
-	0x2e6a: 0x000c, 0x2e6b: 0x000c, 0x2e6c: 0x000c, 0x2e6d: 0x000c, 0x2e6e: 0x000c, 0x2e6f: 0x000c,
-	0x2e70: 0x000c, 0x2e72: 0x000c, 0x2e73: 0x000c, 0x2e75: 0x000c,
-	0x2e76: 0x000c,
+	0x2e4a: 0x000c, 0x2e4b: 0x000c,
+	0x2e4c: 0x000c, 0x2e4d: 0x000c, 0x2e4e: 0x000c, 0x2e4f: 0x000c, 0x2e50: 0x000c, 0x2e51: 0x000c,
+	0x2e52: 0x000c, 0x2e53: 0x000c, 0x2e54: 0x000c, 0x2e55: 0x000c, 0x2e56: 0x000c,
+	0x2e58: 0x000c, 0x2e59: 0x000c,
 	// Block 0xba, offset 0x2e80
-	0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c,
+	0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c,
+	0x2eb6: 0x000c, 0x2eb8: 0x000c, 0x2eb9: 0x000c, 0x2eba: 0x000c, 0x2ebb: 0x000c,
+	0x2ebc: 0x000c, 0x2ebd: 0x000c,
 	// Block 0xbb, offset 0x2ec0
-	0x2ef0: 0x000c, 0x2ef1: 0x000c, 0x2ef2: 0x000c, 0x2ef3: 0x000c, 0x2ef4: 0x000c, 0x2ef5: 0x000c,
+	0x2ed2: 0x000c, 0x2ed3: 0x000c, 0x2ed4: 0x000c, 0x2ed5: 0x000c, 0x2ed6: 0x000c, 0x2ed7: 0x000c,
+	0x2ed8: 0x000c, 0x2ed9: 0x000c, 0x2eda: 0x000c, 0x2edb: 0x000c, 0x2edc: 0x000c, 0x2edd: 0x000c,
+	0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee0: 0x000c, 0x2ee1: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c,
+	0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee6: 0x000c, 0x2ee7: 0x000c,
+	0x2eea: 0x000c, 0x2eeb: 0x000c, 0x2eec: 0x000c, 0x2eed: 0x000c, 0x2eee: 0x000c, 0x2eef: 0x000c,
+	0x2ef0: 0x000c, 0x2ef2: 0x000c, 0x2ef3: 0x000c, 0x2ef5: 0x000c,
 	0x2ef6: 0x000c,
 	// Block 0xbc, offset 0x2f00
-	0x2f0f: 0x000c, 0x2f10: 0x000c, 0x2f11: 0x000c,
-	0x2f12: 0x000c,
+	0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c,
+	0x2f36: 0x000c, 0x2f3a: 0x000c,
+	0x2f3c: 0x000c, 0x2f3d: 0x000c, 0x2f3f: 0x000c,
 	// Block 0xbd, offset 0x2f40
-	0x2f5d: 0x000c,
-	0x2f5e: 0x000c, 0x2f60: 0x000b, 0x2f61: 0x000b, 0x2f62: 0x000b, 0x2f63: 0x000b,
+	0x2f40: 0x000c, 0x2f41: 0x000c, 0x2f42: 0x000c, 0x2f43: 0x000c, 0x2f44: 0x000c, 0x2f45: 0x000c,
+	0x2f47: 0x000c,
 	// Block 0xbe, offset 0x2f80
-	0x2fa7: 0x000c, 0x2fa8: 0x000c, 0x2fa9: 0x000c,
-	0x2fb3: 0x000b, 0x2fb4: 0x000b, 0x2fb5: 0x000b,
-	0x2fb6: 0x000b, 0x2fb7: 0x000b, 0x2fb8: 0x000b, 0x2fb9: 0x000b, 0x2fba: 0x000b, 0x2fbb: 0x000c,
-	0x2fbc: 0x000c, 0x2fbd: 0x000c, 0x2fbe: 0x000c, 0x2fbf: 0x000c,
+	0x2fb0: 0x000c, 0x2fb1: 0x000c, 0x2fb2: 0x000c, 0x2fb3: 0x000c, 0x2fb4: 0x000c,
 	// Block 0xbf, offset 0x2fc0
-	0x2fc0: 0x000c, 0x2fc1: 0x000c, 0x2fc2: 0x000c, 0x2fc5: 0x000c,
-	0x2fc6: 0x000c, 0x2fc7: 0x000c, 0x2fc8: 0x000c, 0x2fc9: 0x000c, 0x2fca: 0x000c, 0x2fcb: 0x000c,
-	0x2fea: 0x000c, 0x2feb: 0x000c, 0x2fec: 0x000c, 0x2fed: 0x000c,
+	0x2ff0: 0x000c, 0x2ff1: 0x000c, 0x2ff2: 0x000c, 0x2ff3: 0x000c, 0x2ff4: 0x000c, 0x2ff5: 0x000c,
+	0x2ff6: 0x000c,
 	// Block 0xc0, offset 0x3000
-	0x3000: 0x000a, 0x3001: 0x000a, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000a,
+	0x300f: 0x000c, 0x3010: 0x000c, 0x3011: 0x000c,
+	0x3012: 0x000c,
 	// Block 0xc1, offset 0x3040
-	0x3040: 0x000a, 0x3041: 0x000a, 0x3042: 0x000a, 0x3043: 0x000a, 0x3044: 0x000a, 0x3045: 0x000a,
-	0x3046: 0x000a, 0x3047: 0x000a, 0x3048: 0x000a, 0x3049: 0x000a, 0x304a: 0x000a, 0x304b: 0x000a,
-	0x304c: 0x000a, 0x304d: 0x000a, 0x304e: 0x000a, 0x304f: 0x000a, 0x3050: 0x000a, 0x3051: 0x000a,
-	0x3052: 0x000a, 0x3053: 0x000a, 0x3054: 0x000a, 0x3055: 0x000a, 0x3056: 0x000a,
+	0x305d: 0x000c,
+	0x305e: 0x000c, 0x3060: 0x000b, 0x3061: 0x000b, 0x3062: 0x000b, 0x3063: 0x000b,
 	// Block 0xc2, offset 0x3080
-	0x309b: 0x000a,
+	0x30a7: 0x000c, 0x30a8: 0x000c, 0x30a9: 0x000c,
+	0x30b3: 0x000b, 0x30b4: 0x000b, 0x30b5: 0x000b,
+	0x30b6: 0x000b, 0x30b7: 0x000b, 0x30b8: 0x000b, 0x30b9: 0x000b, 0x30ba: 0x000b, 0x30bb: 0x000c,
+	0x30bc: 0x000c, 0x30bd: 0x000c, 0x30be: 0x000c, 0x30bf: 0x000c,
 	// Block 0xc3, offset 0x30c0
-	0x30d5: 0x000a,
+	0x30c0: 0x000c, 0x30c1: 0x000c, 0x30c2: 0x000c, 0x30c5: 0x000c,
+	0x30c6: 0x000c, 0x30c7: 0x000c, 0x30c8: 0x000c, 0x30c9: 0x000c, 0x30ca: 0x000c, 0x30cb: 0x000c,
+	0x30ea: 0x000c, 0x30eb: 0x000c, 0x30ec: 0x000c, 0x30ed: 0x000c,
 	// Block 0xc4, offset 0x3100
-	0x310f: 0x000a,
+	0x3100: 0x000a, 0x3101: 0x000a, 0x3102: 0x000c, 0x3103: 0x000c, 0x3104: 0x000c, 0x3105: 0x000a,
 	// Block 0xc5, offset 0x3140
-	0x3149: 0x000a,
+	0x3140: 0x000a, 0x3141: 0x000a, 0x3142: 0x000a, 0x3143: 0x000a, 0x3144: 0x000a, 0x3145: 0x000a,
+	0x3146: 0x000a, 0x3147: 0x000a, 0x3148: 0x000a, 0x3149: 0x000a, 0x314a: 0x000a, 0x314b: 0x000a,
+	0x314c: 0x000a, 0x314d: 0x000a, 0x314e: 0x000a, 0x314f: 0x000a, 0x3150: 0x000a, 0x3151: 0x000a,
+	0x3152: 0x000a, 0x3153: 0x000a, 0x3154: 0x000a, 0x3155: 0x000a, 0x3156: 0x000a,
 	// Block 0xc6, offset 0x3180
-	0x3183: 0x000a,
-	0x318e: 0x0002, 0x318f: 0x0002, 0x3190: 0x0002, 0x3191: 0x0002,
-	0x3192: 0x0002, 0x3193: 0x0002, 0x3194: 0x0002, 0x3195: 0x0002, 0x3196: 0x0002, 0x3197: 0x0002,
-	0x3198: 0x0002, 0x3199: 0x0002, 0x319a: 0x0002, 0x319b: 0x0002, 0x319c: 0x0002, 0x319d: 0x0002,
-	0x319e: 0x0002, 0x319f: 0x0002, 0x31a0: 0x0002, 0x31a1: 0x0002, 0x31a2: 0x0002, 0x31a3: 0x0002,
-	0x31a4: 0x0002, 0x31a5: 0x0002, 0x31a6: 0x0002, 0x31a7: 0x0002, 0x31a8: 0x0002, 0x31a9: 0x0002,
-	0x31aa: 0x0002, 0x31ab: 0x0002, 0x31ac: 0x0002, 0x31ad: 0x0002, 0x31ae: 0x0002, 0x31af: 0x0002,
-	0x31b0: 0x0002, 0x31b1: 0x0002, 0x31b2: 0x0002, 0x31b3: 0x0002, 0x31b4: 0x0002, 0x31b5: 0x0002,
-	0x31b6: 0x0002, 0x31b7: 0x0002, 0x31b8: 0x0002, 0x31b9: 0x0002, 0x31ba: 0x0002, 0x31bb: 0x0002,
-	0x31bc: 0x0002, 0x31bd: 0x0002, 0x31be: 0x0002, 0x31bf: 0x0002,
+	0x319b: 0x000a,
 	// Block 0xc7, offset 0x31c0
-	0x31c0: 0x000c, 0x31c1: 0x000c, 0x31c2: 0x000c, 0x31c3: 0x000c, 0x31c4: 0x000c, 0x31c5: 0x000c,
-	0x31c6: 0x000c, 0x31c7: 0x000c, 0x31c8: 0x000c, 0x31c9: 0x000c, 0x31ca: 0x000c, 0x31cb: 0x000c,
-	0x31cc: 0x000c, 0x31cd: 0x000c, 0x31ce: 0x000c, 0x31cf: 0x000c, 0x31d0: 0x000c, 0x31d1: 0x000c,
-	0x31d2: 0x000c, 0x31d3: 0x000c, 0x31d4: 0x000c, 0x31d5: 0x000c, 0x31d6: 0x000c, 0x31d7: 0x000c,
-	0x31d8: 0x000c, 0x31d9: 0x000c, 0x31da: 0x000c, 0x31db: 0x000c, 0x31dc: 0x000c, 0x31dd: 0x000c,
-	0x31de: 0x000c, 0x31df: 0x000c, 0x31e0: 0x000c, 0x31e1: 0x000c, 0x31e2: 0x000c, 0x31e3: 0x000c,
-	0x31e4: 0x000c, 0x31e5: 0x000c, 0x31e6: 0x000c, 0x31e7: 0x000c, 0x31e8: 0x000c, 0x31e9: 0x000c,
-	0x31ea: 0x000c, 0x31eb: 0x000c, 0x31ec: 0x000c, 0x31ed: 0x000c, 0x31ee: 0x000c, 0x31ef: 0x000c,
-	0x31f0: 0x000c, 0x31f1: 0x000c, 0x31f2: 0x000c, 0x31f3: 0x000c, 0x31f4: 0x000c, 0x31f5: 0x000c,
-	0x31f6: 0x000c, 0x31fb: 0x000c,
-	0x31fc: 0x000c, 0x31fd: 0x000c, 0x31fe: 0x000c, 0x31ff: 0x000c,
+	0x31d5: 0x000a,
 	// Block 0xc8, offset 0x3200
-	0x3200: 0x000c, 0x3201: 0x000c, 0x3202: 0x000c, 0x3203: 0x000c, 0x3204: 0x000c, 0x3205: 0x000c,
-	0x3206: 0x000c, 0x3207: 0x000c, 0x3208: 0x000c, 0x3209: 0x000c, 0x320a: 0x000c, 0x320b: 0x000c,
-	0x320c: 0x000c, 0x320d: 0x000c, 0x320e: 0x000c, 0x320f: 0x000c, 0x3210: 0x000c, 0x3211: 0x000c,
-	0x3212: 0x000c, 0x3213: 0x000c, 0x3214: 0x000c, 0x3215: 0x000c, 0x3216: 0x000c, 0x3217: 0x000c,
-	0x3218: 0x000c, 0x3219: 0x000c, 0x321a: 0x000c, 0x321b: 0x000c, 0x321c: 0x000c, 0x321d: 0x000c,
-	0x321e: 0x000c, 0x321f: 0x000c, 0x3220: 0x000c, 0x3221: 0x000c, 0x3222: 0x000c, 0x3223: 0x000c,
-	0x3224: 0x000c, 0x3225: 0x000c, 0x3226: 0x000c, 0x3227: 0x000c, 0x3228: 0x000c, 0x3229: 0x000c,
-	0x322a: 0x000c, 0x322b: 0x000c, 0x322c: 0x000c,
-	0x3235: 0x000c,
+	0x320f: 0x000a,
 	// Block 0xc9, offset 0x3240
-	0x3244: 0x000c,
-	0x325b: 0x000c, 0x325c: 0x000c, 0x325d: 0x000c,
-	0x325e: 0x000c, 0x325f: 0x000c, 0x3261: 0x000c, 0x3262: 0x000c, 0x3263: 0x000c,
-	0x3264: 0x000c, 0x3265: 0x000c, 0x3266: 0x000c, 0x3267: 0x000c, 0x3268: 0x000c, 0x3269: 0x000c,
-	0x326a: 0x000c, 0x326b: 0x000c, 0x326c: 0x000c, 0x326d: 0x000c, 0x326e: 0x000c, 0x326f: 0x000c,
+	0x3249: 0x000a,
 	// Block 0xca, offset 0x3280
-	0x3280: 0x000c, 0x3281: 0x000c, 0x3282: 0x000c, 0x3283: 0x000c, 0x3284: 0x000c, 0x3285: 0x000c,
-	0x3286: 0x000c, 0x3288: 0x000c, 0x3289: 0x000c, 0x328a: 0x000c, 0x328b: 0x000c,
-	0x328c: 0x000c, 0x328d: 0x000c, 0x328e: 0x000c, 0x328f: 0x000c, 0x3290: 0x000c, 0x3291: 0x000c,
-	0x3292: 0x000c, 0x3293: 0x000c, 0x3294: 0x000c, 0x3295: 0x000c, 0x3296: 0x000c, 0x3297: 0x000c,
-	0x3298: 0x000c, 0x329b: 0x000c, 0x329c: 0x000c, 0x329d: 0x000c,
-	0x329e: 0x000c, 0x329f: 0x000c, 0x32a0: 0x000c, 0x32a1: 0x000c, 0x32a3: 0x000c,
-	0x32a4: 0x000c, 0x32a6: 0x000c, 0x32a7: 0x000c, 0x32a8: 0x000c, 0x32a9: 0x000c,
-	0x32aa: 0x000c,
+	0x3283: 0x000a,
+	0x328e: 0x0002, 0x328f: 0x0002, 0x3290: 0x0002, 0x3291: 0x0002,
+	0x3292: 0x0002, 0x3293: 0x0002, 0x3294: 0x0002, 0x3295: 0x0002, 0x3296: 0x0002, 0x3297: 0x0002,
+	0x3298: 0x0002, 0x3299: 0x0002, 0x329a: 0x0002, 0x329b: 0x0002, 0x329c: 0x0002, 0x329d: 0x0002,
+	0x329e: 0x0002, 0x329f: 0x0002, 0x32a0: 0x0002, 0x32a1: 0x0002, 0x32a2: 0x0002, 0x32a3: 0x0002,
+	0x32a4: 0x0002, 0x32a5: 0x0002, 0x32a6: 0x0002, 0x32a7: 0x0002, 0x32a8: 0x0002, 0x32a9: 0x0002,
+	0x32aa: 0x0002, 0x32ab: 0x0002, 0x32ac: 0x0002, 0x32ad: 0x0002, 0x32ae: 0x0002, 0x32af: 0x0002,
+	0x32b0: 0x0002, 0x32b1: 0x0002, 0x32b2: 0x0002, 0x32b3: 0x0002, 0x32b4: 0x0002, 0x32b5: 0x0002,
+	0x32b6: 0x0002, 0x32b7: 0x0002, 0x32b8: 0x0002, 0x32b9: 0x0002, 0x32ba: 0x0002, 0x32bb: 0x0002,
+	0x32bc: 0x0002, 0x32bd: 0x0002, 0x32be: 0x0002, 0x32bf: 0x0002,
 	// Block 0xcb, offset 0x32c0
-	0x32c0: 0x0001, 0x32c1: 0x0001, 0x32c2: 0x0001, 0x32c3: 0x0001, 0x32c4: 0x0001, 0x32c5: 0x0001,
-	0x32c6: 0x0001, 0x32c7: 0x0001, 0x32c8: 0x0001, 0x32c9: 0x0001, 0x32ca: 0x0001, 0x32cb: 0x0001,
-	0x32cc: 0x0001, 0x32cd: 0x0001, 0x32ce: 0x0001, 0x32cf: 0x0001, 0x32d0: 0x000c, 0x32d1: 0x000c,
-	0x32d2: 0x000c, 0x32d3: 0x000c, 0x32d4: 0x000c, 0x32d5: 0x000c, 0x32d6: 0x000c, 0x32d7: 0x0001,
-	0x32d8: 0x0001, 0x32d9: 0x0001, 0x32da: 0x0001, 0x32db: 0x0001, 0x32dc: 0x0001, 0x32dd: 0x0001,
-	0x32de: 0x0001, 0x32df: 0x0001, 0x32e0: 0x0001, 0x32e1: 0x0001, 0x32e2: 0x0001, 0x32e3: 0x0001,
-	0x32e4: 0x0001, 0x32e5: 0x0001, 0x32e6: 0x0001, 0x32e7: 0x0001, 0x32e8: 0x0001, 0x32e9: 0x0001,
-	0x32ea: 0x0001, 0x32eb: 0x0001, 0x32ec: 0x0001, 0x32ed: 0x0001, 0x32ee: 0x0001, 0x32ef: 0x0001,
-	0x32f0: 0x0001, 0x32f1: 0x0001, 0x32f2: 0x0001, 0x32f3: 0x0001, 0x32f4: 0x0001, 0x32f5: 0x0001,
-	0x32f6: 0x0001, 0x32f7: 0x0001, 0x32f8: 0x0001, 0x32f9: 0x0001, 0x32fa: 0x0001, 0x32fb: 0x0001,
-	0x32fc: 0x0001, 0x32fd: 0x0001, 0x32fe: 0x0001, 0x32ff: 0x0001,
+	0x32c0: 0x000c, 0x32c1: 0x000c, 0x32c2: 0x000c, 0x32c3: 0x000c, 0x32c4: 0x000c, 0x32c5: 0x000c,
+	0x32c6: 0x000c, 0x32c7: 0x000c, 0x32c8: 0x000c, 0x32c9: 0x000c, 0x32ca: 0x000c, 0x32cb: 0x000c,
+	0x32cc: 0x000c, 0x32cd: 0x000c, 0x32ce: 0x000c, 0x32cf: 0x000c, 0x32d0: 0x000c, 0x32d1: 0x000c,
+	0x32d2: 0x000c, 0x32d3: 0x000c, 0x32d4: 0x000c, 0x32d5: 0x000c, 0x32d6: 0x000c, 0x32d7: 0x000c,
+	0x32d8: 0x000c, 0x32d9: 0x000c, 0x32da: 0x000c, 0x32db: 0x000c, 0x32dc: 0x000c, 0x32dd: 0x000c,
+	0x32de: 0x000c, 0x32df: 0x000c, 0x32e0: 0x000c, 0x32e1: 0x000c, 0x32e2: 0x000c, 0x32e3: 0x000c,
+	0x32e4: 0x000c, 0x32e5: 0x000c, 0x32e6: 0x000c, 0x32e7: 0x000c, 0x32e8: 0x000c, 0x32e9: 0x000c,
+	0x32ea: 0x000c, 0x32eb: 0x000c, 0x32ec: 0x000c, 0x32ed: 0x000c, 0x32ee: 0x000c, 0x32ef: 0x000c,
+	0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c,
+	0x32f6: 0x000c, 0x32fb: 0x000c,
+	0x32fc: 0x000c, 0x32fd: 0x000c, 0x32fe: 0x000c, 0x32ff: 0x000c,
 	// Block 0xcc, offset 0x3300
-	0x3300: 0x0001, 0x3301: 0x0001, 0x3302: 0x0001, 0x3303: 0x0001, 0x3304: 0x000c, 0x3305: 0x000c,
-	0x3306: 0x000c, 0x3307: 0x000c, 0x3308: 0x000c, 0x3309: 0x000c, 0x330a: 0x000c, 0x330b: 0x0001,
-	0x330c: 0x0001, 0x330d: 0x0001, 0x330e: 0x0001, 0x330f: 0x0001, 0x3310: 0x0001, 0x3311: 0x0001,
-	0x3312: 0x0001, 0x3313: 0x0001, 0x3314: 0x0001, 0x3315: 0x0001, 0x3316: 0x0001, 0x3317: 0x0001,
-	0x3318: 0x0001, 0x3319: 0x0001, 0x331a: 0x0001, 0x331b: 0x0001, 0x331c: 0x0001, 0x331d: 0x0001,
-	0x331e: 0x0001, 0x331f: 0x0001, 0x3320: 0x0001, 0x3321: 0x0001, 0x3322: 0x0001, 0x3323: 0x0001,
-	0x3324: 0x0001, 0x3325: 0x0001, 0x3326: 0x0001, 0x3327: 0x0001, 0x3328: 0x0001, 0x3329: 0x0001,
-	0x332a: 0x0001, 0x332b: 0x0001, 0x332c: 0x0001, 0x332d: 0x0001, 0x332e: 0x0001, 0x332f: 0x0001,
-	0x3330: 0x0001, 0x3331: 0x0001, 0x3332: 0x0001, 0x3333: 0x0001, 0x3334: 0x0001, 0x3335: 0x0001,
-	0x3336: 0x0001, 0x3337: 0x0001, 0x3338: 0x0001, 0x3339: 0x0001, 0x333a: 0x0001, 0x333b: 0x0001,
-	0x333c: 0x0001, 0x333d: 0x0001, 0x333e: 0x0001, 0x333f: 0x0001,
+	0x3300: 0x000c, 0x3301: 0x000c, 0x3302: 0x000c, 0x3303: 0x000c, 0x3304: 0x000c, 0x3305: 0x000c,
+	0x3306: 0x000c, 0x3307: 0x000c, 0x3308: 0x000c, 0x3309: 0x000c, 0x330a: 0x000c, 0x330b: 0x000c,
+	0x330c: 0x000c, 0x330d: 0x000c, 0x330e: 0x000c, 0x330f: 0x000c, 0x3310: 0x000c, 0x3311: 0x000c,
+	0x3312: 0x000c, 0x3313: 0x000c, 0x3314: 0x000c, 0x3315: 0x000c, 0x3316: 0x000c, 0x3317: 0x000c,
+	0x3318: 0x000c, 0x3319: 0x000c, 0x331a: 0x000c, 0x331b: 0x000c, 0x331c: 0x000c, 0x331d: 0x000c,
+	0x331e: 0x000c, 0x331f: 0x000c, 0x3320: 0x000c, 0x3321: 0x000c, 0x3322: 0x000c, 0x3323: 0x000c,
+	0x3324: 0x000c, 0x3325: 0x000c, 0x3326: 0x000c, 0x3327: 0x000c, 0x3328: 0x000c, 0x3329: 0x000c,
+	0x332a: 0x000c, 0x332b: 0x000c, 0x332c: 0x000c,
+	0x3335: 0x000c,
 	// Block 0xcd, offset 0x3340
-	0x3340: 0x000d, 0x3341: 0x000d, 0x3342: 0x000d, 0x3343: 0x000d, 0x3344: 0x000d, 0x3345: 0x000d,
-	0x3346: 0x000d, 0x3347: 0x000d, 0x3348: 0x000d, 0x3349: 0x000d, 0x334a: 0x000d, 0x334b: 0x000d,
-	0x334c: 0x000d, 0x334d: 0x000d, 0x334e: 0x000d, 0x334f: 0x000d, 0x3350: 0x000d, 0x3351: 0x000d,
-	0x3352: 0x000d, 0x3353: 0x000d, 0x3354: 0x000d, 0x3355: 0x000d, 0x3356: 0x000d, 0x3357: 0x000d,
-	0x3358: 0x000d, 0x3359: 0x000d, 0x335a: 0x000d, 0x335b: 0x000d, 0x335c: 0x000d, 0x335d: 0x000d,
-	0x335e: 0x000d, 0x335f: 0x000d, 0x3360: 0x000d, 0x3361: 0x000d, 0x3362: 0x000d, 0x3363: 0x000d,
-	0x3364: 0x000d, 0x3365: 0x000d, 0x3366: 0x000d, 0x3367: 0x000d, 0x3368: 0x000d, 0x3369: 0x000d,
-	0x336a: 0x000d, 0x336b: 0x000d, 0x336c: 0x000d, 0x336d: 0x000d, 0x336e: 0x000d, 0x336f: 0x000d,
-	0x3370: 0x000a, 0x3371: 0x000a, 0x3372: 0x000d, 0x3373: 0x000d, 0x3374: 0x000d, 0x3375: 0x000d,
-	0x3376: 0x000d, 0x3377: 0x000d, 0x3378: 0x000d, 0x3379: 0x000d, 0x337a: 0x000d, 0x337b: 0x000d,
-	0x337c: 0x000d, 0x337d: 0x000d, 0x337e: 0x000d, 0x337f: 0x000d,
+	0x3344: 0x000c,
+	0x335b: 0x000c, 0x335c: 0x000c, 0x335d: 0x000c,
+	0x335e: 0x000c, 0x335f: 0x000c, 0x3361: 0x000c, 0x3362: 0x000c, 0x3363: 0x000c,
+	0x3364: 0x000c, 0x3365: 0x000c, 0x3366: 0x000c, 0x3367: 0x000c, 0x3368: 0x000c, 0x3369: 0x000c,
+	0x336a: 0x000c, 0x336b: 0x000c, 0x336c: 0x000c, 0x336d: 0x000c, 0x336e: 0x000c, 0x336f: 0x000c,
 	// Block 0xce, offset 0x3380
-	0x3380: 0x000a, 0x3381: 0x000a, 0x3382: 0x000a, 0x3383: 0x000a, 0x3384: 0x000a, 0x3385: 0x000a,
-	0x3386: 0x000a, 0x3387: 0x000a, 0x3388: 0x000a, 0x3389: 0x000a, 0x338a: 0x000a, 0x338b: 0x000a,
-	0x338c: 0x000a, 0x338d: 0x000a, 0x338e: 0x000a, 0x338f: 0x000a, 0x3390: 0x000a, 0x3391: 0x000a,
-	0x3392: 0x000a, 0x3393: 0x000a, 0x3394: 0x000a, 0x3395: 0x000a, 0x3396: 0x000a, 0x3397: 0x000a,
-	0x3398: 0x000a, 0x3399: 0x000a, 0x339a: 0x000a, 0x339b: 0x000a, 0x339c: 0x000a, 0x339d: 0x000a,
-	0x339e: 0x000a, 0x339f: 0x000a, 0x33a0: 0x000a, 0x33a1: 0x000a, 0x33a2: 0x000a, 0x33a3: 0x000a,
-	0x33a4: 0x000a, 0x33a5: 0x000a, 0x33a6: 0x000a, 0x33a7: 0x000a, 0x33a8: 0x000a, 0x33a9: 0x000a,
-	0x33aa: 0x000a, 0x33ab: 0x000a,
-	0x33b0: 0x000a, 0x33b1: 0x000a, 0x33b2: 0x000a, 0x33b3: 0x000a, 0x33b4: 0x000a, 0x33b5: 0x000a,
-	0x33b6: 0x000a, 0x33b7: 0x000a, 0x33b8: 0x000a, 0x33b9: 0x000a, 0x33ba: 0x000a, 0x33bb: 0x000a,
-	0x33bc: 0x000a, 0x33bd: 0x000a, 0x33be: 0x000a, 0x33bf: 0x000a,
+	0x3380: 0x000c, 0x3381: 0x000c, 0x3382: 0x000c, 0x3383: 0x000c, 0x3384: 0x000c, 0x3385: 0x000c,
+	0x3386: 0x000c, 0x3388: 0x000c, 0x3389: 0x000c, 0x338a: 0x000c, 0x338b: 0x000c,
+	0x338c: 0x000c, 0x338d: 0x000c, 0x338e: 0x000c, 0x338f: 0x000c, 0x3390: 0x000c, 0x3391: 0x000c,
+	0x3392: 0x000c, 0x3393: 0x000c, 0x3394: 0x000c, 0x3395: 0x000c, 0x3396: 0x000c, 0x3397: 0x000c,
+	0x3398: 0x000c, 0x339b: 0x000c, 0x339c: 0x000c, 0x339d: 0x000c,
+	0x339e: 0x000c, 0x339f: 0x000c, 0x33a0: 0x000c, 0x33a1: 0x000c, 0x33a3: 0x000c,
+	0x33a4: 0x000c, 0x33a6: 0x000c, 0x33a7: 0x000c, 0x33a8: 0x000c, 0x33a9: 0x000c,
+	0x33aa: 0x000c,
 	// Block 0xcf, offset 0x33c0
-	0x33c0: 0x000a, 0x33c1: 0x000a, 0x33c2: 0x000a, 0x33c3: 0x000a, 0x33c4: 0x000a, 0x33c5: 0x000a,
-	0x33c6: 0x000a, 0x33c7: 0x000a, 0x33c8: 0x000a, 0x33c9: 0x000a, 0x33ca: 0x000a, 0x33cb: 0x000a,
-	0x33cc: 0x000a, 0x33cd: 0x000a, 0x33ce: 0x000a, 0x33cf: 0x000a, 0x33d0: 0x000a, 0x33d1: 0x000a,
-	0x33d2: 0x000a, 0x33d3: 0x000a,
-	0x33e0: 0x000a, 0x33e1: 0x000a, 0x33e2: 0x000a, 0x33e3: 0x000a,
-	0x33e4: 0x000a, 0x33e5: 0x000a, 0x33e6: 0x000a, 0x33e7: 0x000a, 0x33e8: 0x000a, 0x33e9: 0x000a,
-	0x33ea: 0x000a, 0x33eb: 0x000a, 0x33ec: 0x000a, 0x33ed: 0x000a, 0x33ee: 0x000a,
-	0x33f1: 0x000a, 0x33f2: 0x000a, 0x33f3: 0x000a, 0x33f4: 0x000a, 0x33f5: 0x000a,
-	0x33f6: 0x000a, 0x33f7: 0x000a, 0x33f8: 0x000a, 0x33f9: 0x000a, 0x33fa: 0x000a, 0x33fb: 0x000a,
-	0x33fc: 0x000a, 0x33fd: 0x000a, 0x33fe: 0x000a, 0x33ff: 0x000a,
+	0x33c0: 0x0001, 0x33c1: 0x0001, 0x33c2: 0x0001, 0x33c3: 0x0001, 0x33c4: 0x0001, 0x33c5: 0x0001,
+	0x33c6: 0x0001, 0x33c7: 0x0001, 0x33c8: 0x0001, 0x33c9: 0x0001, 0x33ca: 0x0001, 0x33cb: 0x0001,
+	0x33cc: 0x0001, 0x33cd: 0x0001, 0x33ce: 0x0001, 0x33cf: 0x0001, 0x33d0: 0x000c, 0x33d1: 0x000c,
+	0x33d2: 0x000c, 0x33d3: 0x000c, 0x33d4: 0x000c, 0x33d5: 0x000c, 0x33d6: 0x000c, 0x33d7: 0x0001,
+	0x33d8: 0x0001, 0x33d9: 0x0001, 0x33da: 0x0001, 0x33db: 0x0001, 0x33dc: 0x0001, 0x33dd: 0x0001,
+	0x33de: 0x0001, 0x33df: 0x0001, 0x33e0: 0x0001, 0x33e1: 0x0001, 0x33e2: 0x0001, 0x33e3: 0x0001,
+	0x33e4: 0x0001, 0x33e5: 0x0001, 0x33e6: 0x0001, 0x33e7: 0x0001, 0x33e8: 0x0001, 0x33e9: 0x0001,
+	0x33ea: 0x0001, 0x33eb: 0x0001, 0x33ec: 0x0001, 0x33ed: 0x0001, 0x33ee: 0x0001, 0x33ef: 0x0001,
+	0x33f0: 0x0001, 0x33f1: 0x0001, 0x33f2: 0x0001, 0x33f3: 0x0001, 0x33f4: 0x0001, 0x33f5: 0x0001,
+	0x33f6: 0x0001, 0x33f7: 0x0001, 0x33f8: 0x0001, 0x33f9: 0x0001, 0x33fa: 0x0001, 0x33fb: 0x0001,
+	0x33fc: 0x0001, 0x33fd: 0x0001, 0x33fe: 0x0001, 0x33ff: 0x0001,
 	// Block 0xd0, offset 0x3400
-	0x3401: 0x000a, 0x3402: 0x000a, 0x3403: 0x000a, 0x3404: 0x000a, 0x3405: 0x000a,
-	0x3406: 0x000a, 0x3407: 0x000a, 0x3408: 0x000a, 0x3409: 0x000a, 0x340a: 0x000a, 0x340b: 0x000a,
-	0x340c: 0x000a, 0x340d: 0x000a, 0x340e: 0x000a, 0x340f: 0x000a, 0x3411: 0x000a,
-	0x3412: 0x000a, 0x3413: 0x000a, 0x3414: 0x000a, 0x3415: 0x000a, 0x3416: 0x000a, 0x3417: 0x000a,
-	0x3418: 0x000a, 0x3419: 0x000a, 0x341a: 0x000a, 0x341b: 0x000a, 0x341c: 0x000a, 0x341d: 0x000a,
-	0x341e: 0x000a, 0x341f: 0x000a, 0x3420: 0x000a, 0x3421: 0x000a, 0x3422: 0x000a, 0x3423: 0x000a,
-	0x3424: 0x000a, 0x3425: 0x000a, 0x3426: 0x000a, 0x3427: 0x000a, 0x3428: 0x000a, 0x3429: 0x000a,
-	0x342a: 0x000a, 0x342b: 0x000a, 0x342c: 0x000a, 0x342d: 0x000a, 0x342e: 0x000a, 0x342f: 0x000a,
-	0x3430: 0x000a, 0x3431: 0x000a, 0x3432: 0x000a, 0x3433: 0x000a, 0x3434: 0x000a, 0x3435: 0x000a,
+	0x3400: 0x0001, 0x3401: 0x0001, 0x3402: 0x0001, 0x3403: 0x0001, 0x3404: 0x000c, 0x3405: 0x000c,
+	0x3406: 0x000c, 0x3407: 0x000c, 0x3408: 0x000c, 0x3409: 0x000c, 0x340a: 0x000c, 0x340b: 0x0001,
+	0x340c: 0x0001, 0x340d: 0x0001, 0x340e: 0x0001, 0x340f: 0x0001, 0x3410: 0x0001, 0x3411: 0x0001,
+	0x3412: 0x0001, 0x3413: 0x0001, 0x3414: 0x0001, 0x3415: 0x0001, 0x3416: 0x0001, 0x3417: 0x0001,
+	0x3418: 0x0001, 0x3419: 0x0001, 0x341a: 0x0001, 0x341b: 0x0001, 0x341c: 0x0001, 0x341d: 0x0001,
+	0x341e: 0x0001, 0x341f: 0x0001, 0x3420: 0x0001, 0x3421: 0x0001, 0x3422: 0x0001, 0x3423: 0x0001,
+	0x3424: 0x0001, 0x3425: 0x0001, 0x3426: 0x0001, 0x3427: 0x0001, 0x3428: 0x0001, 0x3429: 0x0001,
+	0x342a: 0x0001, 0x342b: 0x0001, 0x342c: 0x0001, 0x342d: 0x0001, 0x342e: 0x0001, 0x342f: 0x0001,
+	0x3430: 0x0001, 0x3431: 0x0001, 0x3432: 0x0001, 0x3433: 0x0001, 0x3434: 0x0001, 0x3435: 0x0001,
+	0x3436: 0x0001, 0x3437: 0x0001, 0x3438: 0x0001, 0x3439: 0x0001, 0x343a: 0x0001, 0x343b: 0x0001,
+	0x343c: 0x0001, 0x343d: 0x0001, 0x343e: 0x0001, 0x343f: 0x0001,
 	// Block 0xd1, offset 0x3440
-	0x3440: 0x0002, 0x3441: 0x0002, 0x3442: 0x0002, 0x3443: 0x0002, 0x3444: 0x0002, 0x3445: 0x0002,
-	0x3446: 0x0002, 0x3447: 0x0002, 0x3448: 0x0002, 0x3449: 0x0002, 0x344a: 0x0002, 0x344b: 0x000a,
-	0x344c: 0x000a,
+	0x3440: 0x000d, 0x3441: 0x000d, 0x3442: 0x000d, 0x3443: 0x000d, 0x3444: 0x000d, 0x3445: 0x000d,
+	0x3446: 0x000d, 0x3447: 0x000d, 0x3448: 0x000d, 0x3449: 0x000d, 0x344a: 0x000d, 0x344b: 0x000d,
+	0x344c: 0x000d, 0x344d: 0x000d, 0x344e: 0x000d, 0x344f: 0x000d, 0x3450: 0x000d, 0x3451: 0x000d,
+	0x3452: 0x000d, 0x3453: 0x000d, 0x3454: 0x000d, 0x3455: 0x000d, 0x3456: 0x000d, 0x3457: 0x000d,
+	0x3458: 0x000d, 0x3459: 0x000d, 0x345a: 0x000d, 0x345b: 0x000d, 0x345c: 0x000d, 0x345d: 0x000d,
+	0x345e: 0x000d, 0x345f: 0x000d, 0x3460: 0x000d, 0x3461: 0x000d, 0x3462: 0x000d, 0x3463: 0x000d,
+	0x3464: 0x000d, 0x3465: 0x000d, 0x3466: 0x000d, 0x3467: 0x000d, 0x3468: 0x000d, 0x3469: 0x000d,
+	0x346a: 0x000d, 0x346b: 0x000d, 0x346c: 0x000d, 0x346d: 0x000d, 0x346e: 0x000d, 0x346f: 0x000d,
+	0x3470: 0x000a, 0x3471: 0x000a, 0x3472: 0x000d, 0x3473: 0x000d, 0x3474: 0x000d, 0x3475: 0x000d,
+	0x3476: 0x000d, 0x3477: 0x000d, 0x3478: 0x000d, 0x3479: 0x000d, 0x347a: 0x000d, 0x347b: 0x000d,
+	0x347c: 0x000d, 0x347d: 0x000d, 0x347e: 0x000d, 0x347f: 0x000d,
 	// Block 0xd2, offset 0x3480
+	0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000a, 0x3483: 0x000a, 0x3484: 0x000a, 0x3485: 0x000a,
+	0x3486: 0x000a, 0x3487: 0x000a, 0x3488: 0x000a, 0x3489: 0x000a, 0x348a: 0x000a, 0x348b: 0x000a,
+	0x348c: 0x000a, 0x348d: 0x000a, 0x348e: 0x000a, 0x348f: 0x000a, 0x3490: 0x000a, 0x3491: 0x000a,
+	0x3492: 0x000a, 0x3493: 0x000a, 0x3494: 0x000a, 0x3495: 0x000a, 0x3496: 0x000a, 0x3497: 0x000a,
+	0x3498: 0x000a, 0x3499: 0x000a, 0x349a: 0x000a, 0x349b: 0x000a, 0x349c: 0x000a, 0x349d: 0x000a,
+	0x349e: 0x000a, 0x349f: 0x000a, 0x34a0: 0x000a, 0x34a1: 0x000a, 0x34a2: 0x000a, 0x34a3: 0x000a,
+	0x34a4: 0x000a, 0x34a5: 0x000a, 0x34a6: 0x000a, 0x34a7: 0x000a, 0x34a8: 0x000a, 0x34a9: 0x000a,
 	0x34aa: 0x000a, 0x34ab: 0x000a,
+	0x34b0: 0x000a, 0x34b1: 0x000a, 0x34b2: 0x000a, 0x34b3: 0x000a, 0x34b4: 0x000a, 0x34b5: 0x000a,
+	0x34b6: 0x000a, 0x34b7: 0x000a, 0x34b8: 0x000a, 0x34b9: 0x000a, 0x34ba: 0x000a, 0x34bb: 0x000a,
+	0x34bc: 0x000a, 0x34bd: 0x000a, 0x34be: 0x000a, 0x34bf: 0x000a,
 	// Block 0xd3, offset 0x34c0
 	0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a,
 	0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a,
 	0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a,
-	0x34d2: 0x000a,
+	0x34d2: 0x000a, 0x34d3: 0x000a,
 	0x34e0: 0x000a, 0x34e1: 0x000a, 0x34e2: 0x000a, 0x34e3: 0x000a,
 	0x34e4: 0x000a, 0x34e5: 0x000a, 0x34e6: 0x000a, 0x34e7: 0x000a, 0x34e8: 0x000a, 0x34e9: 0x000a,
-	0x34ea: 0x000a, 0x34eb: 0x000a, 0x34ec: 0x000a,
-	0x34f0: 0x000a, 0x34f1: 0x000a, 0x34f2: 0x000a, 0x34f3: 0x000a, 0x34f4: 0x000a, 0x34f5: 0x000a,
-	0x34f6: 0x000a,
+	0x34ea: 0x000a, 0x34eb: 0x000a, 0x34ec: 0x000a, 0x34ed: 0x000a, 0x34ee: 0x000a,
+	0x34f1: 0x000a, 0x34f2: 0x000a, 0x34f3: 0x000a, 0x34f4: 0x000a, 0x34f5: 0x000a,
+	0x34f6: 0x000a, 0x34f7: 0x000a, 0x34f8: 0x000a, 0x34f9: 0x000a, 0x34fa: 0x000a, 0x34fb: 0x000a,
+	0x34fc: 0x000a, 0x34fd: 0x000a, 0x34fe: 0x000a, 0x34ff: 0x000a,
 	// Block 0xd4, offset 0x3500
-	0x3500: 0x000a, 0x3501: 0x000a, 0x3502: 0x000a, 0x3503: 0x000a, 0x3504: 0x000a, 0x3505: 0x000a,
+	0x3501: 0x000a, 0x3502: 0x000a, 0x3503: 0x000a, 0x3504: 0x000a, 0x3505: 0x000a,
 	0x3506: 0x000a, 0x3507: 0x000a, 0x3508: 0x000a, 0x3509: 0x000a, 0x350a: 0x000a, 0x350b: 0x000a,
-	0x350c: 0x000a, 0x350d: 0x000a, 0x350e: 0x000a, 0x350f: 0x000a, 0x3510: 0x000a, 0x3511: 0x000a,
-	0x3512: 0x000a, 0x3513: 0x000a, 0x3514: 0x000a,
+	0x350c: 0x000a, 0x350d: 0x000a, 0x350e: 0x000a, 0x350f: 0x000a, 0x3511: 0x000a,
+	0x3512: 0x000a, 0x3513: 0x000a, 0x3514: 0x000a, 0x3515: 0x000a, 0x3516: 0x000a, 0x3517: 0x000a,
+	0x3518: 0x000a, 0x3519: 0x000a, 0x351a: 0x000a, 0x351b: 0x000a, 0x351c: 0x000a, 0x351d: 0x000a,
+	0x351e: 0x000a, 0x351f: 0x000a, 0x3520: 0x000a, 0x3521: 0x000a, 0x3522: 0x000a, 0x3523: 0x000a,
+	0x3524: 0x000a, 0x3525: 0x000a, 0x3526: 0x000a, 0x3527: 0x000a, 0x3528: 0x000a, 0x3529: 0x000a,
+	0x352a: 0x000a, 0x352b: 0x000a, 0x352c: 0x000a, 0x352d: 0x000a, 0x352e: 0x000a, 0x352f: 0x000a,
+	0x3530: 0x000a, 0x3531: 0x000a, 0x3532: 0x000a, 0x3533: 0x000a, 0x3534: 0x000a, 0x3535: 0x000a,
 	// Block 0xd5, offset 0x3540
-	0x3540: 0x000a, 0x3541: 0x000a, 0x3542: 0x000a, 0x3543: 0x000a, 0x3544: 0x000a, 0x3545: 0x000a,
-	0x3546: 0x000a, 0x3547: 0x000a, 0x3548: 0x000a, 0x3549: 0x000a, 0x354a: 0x000a, 0x354b: 0x000a,
-	0x3550: 0x000a, 0x3551: 0x000a,
-	0x3552: 0x000a, 0x3553: 0x000a, 0x3554: 0x000a, 0x3555: 0x000a, 0x3556: 0x000a, 0x3557: 0x000a,
-	0x3558: 0x000a, 0x3559: 0x000a, 0x355a: 0x000a, 0x355b: 0x000a, 0x355c: 0x000a, 0x355d: 0x000a,
-	0x355e: 0x000a, 0x355f: 0x000a, 0x3560: 0x000a, 0x3561: 0x000a, 0x3562: 0x000a, 0x3563: 0x000a,
-	0x3564: 0x000a, 0x3565: 0x000a, 0x3566: 0x000a, 0x3567: 0x000a, 0x3568: 0x000a, 0x3569: 0x000a,
-	0x356a: 0x000a, 0x356b: 0x000a, 0x356c: 0x000a, 0x356d: 0x000a, 0x356e: 0x000a, 0x356f: 0x000a,
-	0x3570: 0x000a, 0x3571: 0x000a, 0x3572: 0x000a, 0x3573: 0x000a, 0x3574: 0x000a, 0x3575: 0x000a,
-	0x3576: 0x000a, 0x3577: 0x000a, 0x3578: 0x000a, 0x3579: 0x000a, 0x357a: 0x000a, 0x357b: 0x000a,
-	0x357c: 0x000a, 0x357d: 0x000a, 0x357e: 0x000a, 0x357f: 0x000a,
+	0x3540: 0x0002, 0x3541: 0x0002, 0x3542: 0x0002, 0x3543: 0x0002, 0x3544: 0x0002, 0x3545: 0x0002,
+	0x3546: 0x0002, 0x3547: 0x0002, 0x3548: 0x0002, 0x3549: 0x0002, 0x354a: 0x0002, 0x354b: 0x000a,
+	0x354c: 0x000a,
 	// Block 0xd6, offset 0x3580
-	0x3580: 0x000a, 0x3581: 0x000a, 0x3582: 0x000a, 0x3583: 0x000a, 0x3584: 0x000a, 0x3585: 0x000a,
-	0x3586: 0x000a, 0x3587: 0x000a,
-	0x3590: 0x000a, 0x3591: 0x000a,
-	0x3592: 0x000a, 0x3593: 0x000a, 0x3594: 0x000a, 0x3595: 0x000a, 0x3596: 0x000a, 0x3597: 0x000a,
-	0x3598: 0x000a, 0x3599: 0x000a,
-	0x35a0: 0x000a, 0x35a1: 0x000a, 0x35a2: 0x000a, 0x35a3: 0x000a,
-	0x35a4: 0x000a, 0x35a5: 0x000a, 0x35a6: 0x000a, 0x35a7: 0x000a, 0x35a8: 0x000a, 0x35a9: 0x000a,
-	0x35aa: 0x000a, 0x35ab: 0x000a, 0x35ac: 0x000a, 0x35ad: 0x000a, 0x35ae: 0x000a, 0x35af: 0x000a,
-	0x35b0: 0x000a, 0x35b1: 0x000a, 0x35b2: 0x000a, 0x35b3: 0x000a, 0x35b4: 0x000a, 0x35b5: 0x000a,
-	0x35b6: 0x000a, 0x35b7: 0x000a, 0x35b8: 0x000a, 0x35b9: 0x000a, 0x35ba: 0x000a, 0x35bb: 0x000a,
-	0x35bc: 0x000a, 0x35bd: 0x000a, 0x35be: 0x000a, 0x35bf: 0x000a,
+	0x35aa: 0x000a, 0x35ab: 0x000a,
 	// Block 0xd7, offset 0x35c0
-	0x35c0: 0x000a, 0x35c1: 0x000a, 0x35c2: 0x000a, 0x35c3: 0x000a, 0x35c4: 0x000a, 0x35c5: 0x000a,
-	0x35c6: 0x000a, 0x35c7: 0x000a,
-	0x35d0: 0x000a, 0x35d1: 0x000a,
-	0x35d2: 0x000a, 0x35d3: 0x000a, 0x35d4: 0x000a, 0x35d5: 0x000a, 0x35d6: 0x000a, 0x35d7: 0x000a,
-	0x35d8: 0x000a, 0x35d9: 0x000a, 0x35da: 0x000a, 0x35db: 0x000a, 0x35dc: 0x000a, 0x35dd: 0x000a,
-	0x35de: 0x000a, 0x35df: 0x000a, 0x35e0: 0x000a, 0x35e1: 0x000a, 0x35e2: 0x000a, 0x35e3: 0x000a,
-	0x35e4: 0x000a, 0x35e5: 0x000a, 0x35e6: 0x000a, 0x35e7: 0x000a, 0x35e8: 0x000a, 0x35e9: 0x000a,
-	0x35ea: 0x000a, 0x35eb: 0x000a, 0x35ec: 0x000a, 0x35ed: 0x000a,
+	0x35e0: 0x000a, 0x35e1: 0x000a, 0x35e2: 0x000a, 0x35e3: 0x000a,
+	0x35e4: 0x000a, 0x35e5: 0x000a,
 	// Block 0xd8, offset 0x3600
-	0x3610: 0x000a, 0x3611: 0x000a,
-	0x3612: 0x000a, 0x3613: 0x000a, 0x3614: 0x000a, 0x3615: 0x000a, 0x3616: 0x000a, 0x3617: 0x000a,
-	0x3618: 0x000a, 0x3619: 0x000a, 0x361a: 0x000a, 0x361b: 0x000a, 0x361c: 0x000a, 0x361d: 0x000a,
-	0x361e: 0x000a, 0x3620: 0x000a, 0x3621: 0x000a, 0x3622: 0x000a, 0x3623: 0x000a,
-	0x3624: 0x000a, 0x3625: 0x000a, 0x3626: 0x000a, 0x3627: 0x000a,
-	0x3630: 0x000a, 0x3633: 0x000a, 0x3634: 0x000a, 0x3635: 0x000a,
-	0x3636: 0x000a, 0x3637: 0x000a, 0x3638: 0x000a, 0x3639: 0x000a, 0x363a: 0x000a, 0x363b: 0x000a,
-	0x363c: 0x000a, 0x363d: 0x000a, 0x363e: 0x000a,
+	0x3600: 0x000a, 0x3601: 0x000a, 0x3602: 0x000a, 0x3603: 0x000a, 0x3604: 0x000a, 0x3605: 0x000a,
+	0x3606: 0x000a, 0x3607: 0x000a, 0x3608: 0x000a, 0x3609: 0x000a, 0x360a: 0x000a, 0x360b: 0x000a,
+	0x360c: 0x000a, 0x360d: 0x000a, 0x360e: 0x000a, 0x360f: 0x000a, 0x3610: 0x000a, 0x3611: 0x000a,
+	0x3612: 0x000a, 0x3613: 0x000a, 0x3614: 0x000a,
+	0x3620: 0x000a, 0x3621: 0x000a, 0x3622: 0x000a, 0x3623: 0x000a,
+	0x3624: 0x000a, 0x3625: 0x000a, 0x3626: 0x000a, 0x3627: 0x000a, 0x3628: 0x000a, 0x3629: 0x000a,
+	0x362a: 0x000a, 0x362b: 0x000a, 0x362c: 0x000a,
+	0x3630: 0x000a, 0x3631: 0x000a, 0x3632: 0x000a, 0x3633: 0x000a, 0x3634: 0x000a, 0x3635: 0x000a,
+	0x3636: 0x000a, 0x3637: 0x000a, 0x3638: 0x000a,
 	// Block 0xd9, offset 0x3640
 	0x3640: 0x000a, 0x3641: 0x000a, 0x3642: 0x000a, 0x3643: 0x000a, 0x3644: 0x000a, 0x3645: 0x000a,
 	0x3646: 0x000a, 0x3647: 0x000a, 0x3648: 0x000a, 0x3649: 0x000a, 0x364a: 0x000a, 0x364b: 0x000a,
-	0x3650: 0x000a, 0x3651: 0x000a,
-	0x3652: 0x000a, 0x3653: 0x000a, 0x3654: 0x000a, 0x3655: 0x000a, 0x3656: 0x000a, 0x3657: 0x000a,
-	0x3658: 0x000a, 0x3659: 0x000a, 0x365a: 0x000a, 0x365b: 0x000a, 0x365c: 0x000a, 0x365d: 0x000a,
-	0x365e: 0x000a,
+	0x364c: 0x000a, 0x364d: 0x000a, 0x364e: 0x000a, 0x364f: 0x000a, 0x3650: 0x000a, 0x3651: 0x000a,
+	0x3652: 0x000a, 0x3653: 0x000a, 0x3654: 0x000a,
 	// Block 0xda, offset 0x3680
 	0x3680: 0x000a, 0x3681: 0x000a, 0x3682: 0x000a, 0x3683: 0x000a, 0x3684: 0x000a, 0x3685: 0x000a,
 	0x3686: 0x000a, 0x3687: 0x000a, 0x3688: 0x000a, 0x3689: 0x000a, 0x368a: 0x000a, 0x368b: 0x000a,
-	0x368c: 0x000a, 0x368d: 0x000a, 0x368e: 0x000a, 0x368f: 0x000a, 0x3690: 0x000a, 0x3691: 0x000a,
+	0x3690: 0x000a, 0x3691: 0x000a,
+	0x3692: 0x000a, 0x3693: 0x000a, 0x3694: 0x000a, 0x3695: 0x000a, 0x3696: 0x000a, 0x3697: 0x000a,
+	0x3698: 0x000a, 0x3699: 0x000a, 0x369a: 0x000a, 0x369b: 0x000a, 0x369c: 0x000a, 0x369d: 0x000a,
+	0x369e: 0x000a, 0x369f: 0x000a, 0x36a0: 0x000a, 0x36a1: 0x000a, 0x36a2: 0x000a, 0x36a3: 0x000a,
+	0x36a4: 0x000a, 0x36a5: 0x000a, 0x36a6: 0x000a, 0x36a7: 0x000a, 0x36a8: 0x000a, 0x36a9: 0x000a,
+	0x36aa: 0x000a, 0x36ab: 0x000a, 0x36ac: 0x000a, 0x36ad: 0x000a, 0x36ae: 0x000a, 0x36af: 0x000a,
+	0x36b0: 0x000a, 0x36b1: 0x000a, 0x36b2: 0x000a, 0x36b3: 0x000a, 0x36b4: 0x000a, 0x36b5: 0x000a,
+	0x36b6: 0x000a, 0x36b7: 0x000a, 0x36b8: 0x000a, 0x36b9: 0x000a, 0x36ba: 0x000a, 0x36bb: 0x000a,
+	0x36bc: 0x000a, 0x36bd: 0x000a, 0x36be: 0x000a, 0x36bf: 0x000a,
 	// Block 0xdb, offset 0x36c0
-	0x36fe: 0x000b, 0x36ff: 0x000b,
+	0x36c0: 0x000a, 0x36c1: 0x000a, 0x36c2: 0x000a, 0x36c3: 0x000a, 0x36c4: 0x000a, 0x36c5: 0x000a,
+	0x36c6: 0x000a, 0x36c7: 0x000a,
+	0x36d0: 0x000a, 0x36d1: 0x000a,
+	0x36d2: 0x000a, 0x36d3: 0x000a, 0x36d4: 0x000a, 0x36d5: 0x000a, 0x36d6: 0x000a, 0x36d7: 0x000a,
+	0x36d8: 0x000a, 0x36d9: 0x000a,
+	0x36e0: 0x000a, 0x36e1: 0x000a, 0x36e2: 0x000a, 0x36e3: 0x000a,
+	0x36e4: 0x000a, 0x36e5: 0x000a, 0x36e6: 0x000a, 0x36e7: 0x000a, 0x36e8: 0x000a, 0x36e9: 0x000a,
+	0x36ea: 0x000a, 0x36eb: 0x000a, 0x36ec: 0x000a, 0x36ed: 0x000a, 0x36ee: 0x000a, 0x36ef: 0x000a,
+	0x36f0: 0x000a, 0x36f1: 0x000a, 0x36f2: 0x000a, 0x36f3: 0x000a, 0x36f4: 0x000a, 0x36f5: 0x000a,
+	0x36f6: 0x000a, 0x36f7: 0x000a, 0x36f8: 0x000a, 0x36f9: 0x000a, 0x36fa: 0x000a, 0x36fb: 0x000a,
+	0x36fc: 0x000a, 0x36fd: 0x000a, 0x36fe: 0x000a, 0x36ff: 0x000a,
 	// Block 0xdc, offset 0x3700
-	0x3700: 0x000b, 0x3701: 0x000b, 0x3702: 0x000b, 0x3703: 0x000b, 0x3704: 0x000b, 0x3705: 0x000b,
-	0x3706: 0x000b, 0x3707: 0x000b, 0x3708: 0x000b, 0x3709: 0x000b, 0x370a: 0x000b, 0x370b: 0x000b,
-	0x370c: 0x000b, 0x370d: 0x000b, 0x370e: 0x000b, 0x370f: 0x000b, 0x3710: 0x000b, 0x3711: 0x000b,
-	0x3712: 0x000b, 0x3713: 0x000b, 0x3714: 0x000b, 0x3715: 0x000b, 0x3716: 0x000b, 0x3717: 0x000b,
-	0x3718: 0x000b, 0x3719: 0x000b, 0x371a: 0x000b, 0x371b: 0x000b, 0x371c: 0x000b, 0x371d: 0x000b,
-	0x371e: 0x000b, 0x371f: 0x000b, 0x3720: 0x000b, 0x3721: 0x000b, 0x3722: 0x000b, 0x3723: 0x000b,
-	0x3724: 0x000b, 0x3725: 0x000b, 0x3726: 0x000b, 0x3727: 0x000b, 0x3728: 0x000b, 0x3729: 0x000b,
-	0x372a: 0x000b, 0x372b: 0x000b, 0x372c: 0x000b, 0x372d: 0x000b, 0x372e: 0x000b, 0x372f: 0x000b,
-	0x3730: 0x000b, 0x3731: 0x000b, 0x3732: 0x000b, 0x3733: 0x000b, 0x3734: 0x000b, 0x3735: 0x000b,
-	0x3736: 0x000b, 0x3737: 0x000b, 0x3738: 0x000b, 0x3739: 0x000b, 0x373a: 0x000b, 0x373b: 0x000b,
-	0x373c: 0x000b, 0x373d: 0x000b, 0x373e: 0x000b, 0x373f: 0x000b,
+	0x3700: 0x000a, 0x3701: 0x000a, 0x3702: 0x000a, 0x3703: 0x000a, 0x3704: 0x000a, 0x3705: 0x000a,
+	0x3706: 0x000a, 0x3707: 0x000a,
+	0x3710: 0x000a, 0x3711: 0x000a,
+	0x3712: 0x000a, 0x3713: 0x000a, 0x3714: 0x000a, 0x3715: 0x000a, 0x3716: 0x000a, 0x3717: 0x000a,
+	0x3718: 0x000a, 0x3719: 0x000a, 0x371a: 0x000a, 0x371b: 0x000a, 0x371c: 0x000a, 0x371d: 0x000a,
+	0x371e: 0x000a, 0x371f: 0x000a, 0x3720: 0x000a, 0x3721: 0x000a, 0x3722: 0x000a, 0x3723: 0x000a,
+	0x3724: 0x000a, 0x3725: 0x000a, 0x3726: 0x000a, 0x3727: 0x000a, 0x3728: 0x000a, 0x3729: 0x000a,
+	0x372a: 0x000a, 0x372b: 0x000a, 0x372c: 0x000a, 0x372d: 0x000a,
 	// Block 0xdd, offset 0x3740
-	0x3740: 0x000c, 0x3741: 0x000c, 0x3742: 0x000c, 0x3743: 0x000c, 0x3744: 0x000c, 0x3745: 0x000c,
-	0x3746: 0x000c, 0x3747: 0x000c, 0x3748: 0x000c, 0x3749: 0x000c, 0x374a: 0x000c, 0x374b: 0x000c,
-	0x374c: 0x000c, 0x374d: 0x000c, 0x374e: 0x000c, 0x374f: 0x000c, 0x3750: 0x000c, 0x3751: 0x000c,
-	0x3752: 0x000c, 0x3753: 0x000c, 0x3754: 0x000c, 0x3755: 0x000c, 0x3756: 0x000c, 0x3757: 0x000c,
-	0x3758: 0x000c, 0x3759: 0x000c, 0x375a: 0x000c, 0x375b: 0x000c, 0x375c: 0x000c, 0x375d: 0x000c,
-	0x375e: 0x000c, 0x375f: 0x000c, 0x3760: 0x000c, 0x3761: 0x000c, 0x3762: 0x000c, 0x3763: 0x000c,
-	0x3764: 0x000c, 0x3765: 0x000c, 0x3766: 0x000c, 0x3767: 0x000c, 0x3768: 0x000c, 0x3769: 0x000c,
-	0x376a: 0x000c, 0x376b: 0x000c, 0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c,
-	0x3770: 0x000b, 0x3771: 0x000b, 0x3772: 0x000b, 0x3773: 0x000b, 0x3774: 0x000b, 0x3775: 0x000b,
-	0x3776: 0x000b, 0x3777: 0x000b, 0x3778: 0x000b, 0x3779: 0x000b, 0x377a: 0x000b, 0x377b: 0x000b,
-	0x377c: 0x000b, 0x377d: 0x000b, 0x377e: 0x000b, 0x377f: 0x000b,
+	0x3740: 0x000a, 0x3741: 0x000a, 0x3742: 0x000a, 0x3743: 0x000a, 0x3744: 0x000a, 0x3745: 0x000a,
+	0x3746: 0x000a, 0x3747: 0x000a, 0x3748: 0x000a, 0x3749: 0x000a, 0x374a: 0x000a, 0x374b: 0x000a,
+	0x3750: 0x000a, 0x3751: 0x000a,
+	0x3752: 0x000a, 0x3753: 0x000a, 0x3754: 0x000a, 0x3755: 0x000a, 0x3756: 0x000a, 0x3757: 0x000a,
+	0x3758: 0x000a, 0x3759: 0x000a, 0x375a: 0x000a, 0x375b: 0x000a, 0x375c: 0x000a, 0x375d: 0x000a,
+	0x375e: 0x000a, 0x375f: 0x000a, 0x3760: 0x000a, 0x3761: 0x000a, 0x3762: 0x000a, 0x3763: 0x000a,
+	0x3764: 0x000a, 0x3765: 0x000a, 0x3766: 0x000a, 0x3767: 0x000a, 0x3768: 0x000a, 0x3769: 0x000a,
+	0x376a: 0x000a, 0x376b: 0x000a, 0x376c: 0x000a, 0x376d: 0x000a, 0x376e: 0x000a, 0x376f: 0x000a,
+	0x3770: 0x000a, 0x3771: 0x000a, 0x3772: 0x000a, 0x3773: 0x000a, 0x3774: 0x000a, 0x3775: 0x000a,
+	0x3776: 0x000a, 0x3777: 0x000a, 0x3778: 0x000a, 0x3779: 0x000a, 0x377a: 0x000a, 0x377b: 0x000a,
+	0x377c: 0x000a, 0x377d: 0x000a, 0x377e: 0x000a,
+	// Block 0xde, offset 0x3780
+	0x3780: 0x000a, 0x3781: 0x000a, 0x3782: 0x000a, 0x3783: 0x000a, 0x3784: 0x000a, 0x3785: 0x000a,
+	0x3786: 0x000a, 0x3787: 0x000a, 0x3788: 0x000a, 0x3789: 0x000a, 0x378a: 0x000a, 0x378b: 0x000a,
+	0x378c: 0x000a, 0x3790: 0x000a, 0x3791: 0x000a,
+	0x3792: 0x000a, 0x3793: 0x000a, 0x3794: 0x000a, 0x3795: 0x000a, 0x3796: 0x000a, 0x3797: 0x000a,
+	0x3798: 0x000a, 0x3799: 0x000a, 0x379a: 0x000a, 0x379b: 0x000a, 0x379c: 0x000a, 0x379d: 0x000a,
+	0x379e: 0x000a, 0x379f: 0x000a, 0x37a0: 0x000a, 0x37a1: 0x000a, 0x37a2: 0x000a, 0x37a3: 0x000a,
+	0x37a4: 0x000a, 0x37a5: 0x000a, 0x37a6: 0x000a, 0x37a7: 0x000a, 0x37a8: 0x000a, 0x37a9: 0x000a,
+	0x37aa: 0x000a, 0x37ab: 0x000a,
+	// Block 0xdf, offset 0x37c0
+	0x37c0: 0x000a, 0x37c1: 0x000a, 0x37c2: 0x000a, 0x37c3: 0x000a, 0x37c4: 0x000a, 0x37c5: 0x000a,
+	0x37c6: 0x000a, 0x37c7: 0x000a, 0x37c8: 0x000a, 0x37c9: 0x000a, 0x37ca: 0x000a, 0x37cb: 0x000a,
+	0x37cc: 0x000a, 0x37cd: 0x000a, 0x37ce: 0x000a, 0x37cf: 0x000a, 0x37d0: 0x000a, 0x37d1: 0x000a,
+	0x37d2: 0x000a, 0x37d3: 0x000a, 0x37d4: 0x000a, 0x37d5: 0x000a, 0x37d6: 0x000a, 0x37d7: 0x000a,
+	// Block 0xe0, offset 0x3800
+	0x3800: 0x000a,
+	0x3810: 0x000a, 0x3811: 0x000a,
+	0x3812: 0x000a, 0x3813: 0x000a, 0x3814: 0x000a, 0x3815: 0x000a, 0x3816: 0x000a, 0x3817: 0x000a,
+	0x3818: 0x000a, 0x3819: 0x000a, 0x381a: 0x000a, 0x381b: 0x000a, 0x381c: 0x000a, 0x381d: 0x000a,
+	0x381e: 0x000a, 0x381f: 0x000a, 0x3820: 0x000a, 0x3821: 0x000a, 0x3822: 0x000a, 0x3823: 0x000a,
+	0x3824: 0x000a, 0x3825: 0x000a, 0x3826: 0x000a,
+	// Block 0xe1, offset 0x3840
+	0x387e: 0x000b, 0x387f: 0x000b,
+	// Block 0xe2, offset 0x3880
+	0x3880: 0x000b, 0x3881: 0x000b, 0x3882: 0x000b, 0x3883: 0x000b, 0x3884: 0x000b, 0x3885: 0x000b,
+	0x3886: 0x000b, 0x3887: 0x000b, 0x3888: 0x000b, 0x3889: 0x000b, 0x388a: 0x000b, 0x388b: 0x000b,
+	0x388c: 0x000b, 0x388d: 0x000b, 0x388e: 0x000b, 0x388f: 0x000b, 0x3890: 0x000b, 0x3891: 0x000b,
+	0x3892: 0x000b, 0x3893: 0x000b, 0x3894: 0x000b, 0x3895: 0x000b, 0x3896: 0x000b, 0x3897: 0x000b,
+	0x3898: 0x000b, 0x3899: 0x000b, 0x389a: 0x000b, 0x389b: 0x000b, 0x389c: 0x000b, 0x389d: 0x000b,
+	0x389e: 0x000b, 0x389f: 0x000b, 0x38a0: 0x000b, 0x38a1: 0x000b, 0x38a2: 0x000b, 0x38a3: 0x000b,
+	0x38a4: 0x000b, 0x38a5: 0x000b, 0x38a6: 0x000b, 0x38a7: 0x000b, 0x38a8: 0x000b, 0x38a9: 0x000b,
+	0x38aa: 0x000b, 0x38ab: 0x000b, 0x38ac: 0x000b, 0x38ad: 0x000b, 0x38ae: 0x000b, 0x38af: 0x000b,
+	0x38b0: 0x000b, 0x38b1: 0x000b, 0x38b2: 0x000b, 0x38b3: 0x000b, 0x38b4: 0x000b, 0x38b5: 0x000b,
+	0x38b6: 0x000b, 0x38b7: 0x000b, 0x38b8: 0x000b, 0x38b9: 0x000b, 0x38ba: 0x000b, 0x38bb: 0x000b,
+	0x38bc: 0x000b, 0x38bd: 0x000b, 0x38be: 0x000b, 0x38bf: 0x000b,
+	// Block 0xe3, offset 0x38c0
+	0x38c0: 0x000c, 0x38c1: 0x000c, 0x38c2: 0x000c, 0x38c3: 0x000c, 0x38c4: 0x000c, 0x38c5: 0x000c,
+	0x38c6: 0x000c, 0x38c7: 0x000c, 0x38c8: 0x000c, 0x38c9: 0x000c, 0x38ca: 0x000c, 0x38cb: 0x000c,
+	0x38cc: 0x000c, 0x38cd: 0x000c, 0x38ce: 0x000c, 0x38cf: 0x000c, 0x38d0: 0x000c, 0x38d1: 0x000c,
+	0x38d2: 0x000c, 0x38d3: 0x000c, 0x38d4: 0x000c, 0x38d5: 0x000c, 0x38d6: 0x000c, 0x38d7: 0x000c,
+	0x38d8: 0x000c, 0x38d9: 0x000c, 0x38da: 0x000c, 0x38db: 0x000c, 0x38dc: 0x000c, 0x38dd: 0x000c,
+	0x38de: 0x000c, 0x38df: 0x000c, 0x38e0: 0x000c, 0x38e1: 0x000c, 0x38e2: 0x000c, 0x38e3: 0x000c,
+	0x38e4: 0x000c, 0x38e5: 0x000c, 0x38e6: 0x000c, 0x38e7: 0x000c, 0x38e8: 0x000c, 0x38e9: 0x000c,
+	0x38ea: 0x000c, 0x38eb: 0x000c, 0x38ec: 0x000c, 0x38ed: 0x000c, 0x38ee: 0x000c, 0x38ef: 0x000c,
+	0x38f0: 0x000b, 0x38f1: 0x000b, 0x38f2: 0x000b, 0x38f3: 0x000b, 0x38f4: 0x000b, 0x38f5: 0x000b,
+	0x38f6: 0x000b, 0x38f7: 0x000b, 0x38f8: 0x000b, 0x38f9: 0x000b, 0x38fa: 0x000b, 0x38fb: 0x000b,
+	0x38fc: 0x000b, 0x38fd: 0x000b, 0x38fe: 0x000b, 0x38ff: 0x000b,
 }
 
 // bidiIndex: 24 blocks, 1536 entries, 1536 bytes
@@ -1690,65 +1723,66 @@
 	0x17e: 0x4b, 0x17f: 0x4c,
 	// Block 0x6, offset 0x180
 	0x180: 0x4d, 0x181: 0x4e, 0x182: 0x4f, 0x183: 0x50, 0x184: 0x51, 0x185: 0x52, 0x186: 0x53, 0x187: 0x54,
-	0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x59,
-	0x190: 0x5a, 0x191: 0x5b, 0x192: 0x5c, 0x193: 0x5d, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54,
-	0x198: 0x54, 0x199: 0x54, 0x19a: 0x5e, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5f, 0x19e: 0x54, 0x19f: 0x60,
-	0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x61, 0x1a7: 0x62,
-	0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x63, 0x1ae: 0x64, 0x1af: 0x65,
-	0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68,
-	0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6d,
+	0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x54,
+	0x190: 0x59, 0x191: 0x5a, 0x192: 0x5b, 0x193: 0x5c, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54,
+	0x198: 0x54, 0x199: 0x54, 0x19a: 0x5d, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5e, 0x19e: 0x54, 0x19f: 0x5f,
+	0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x60, 0x1a7: 0x61,
+	0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x62, 0x1ae: 0x63, 0x1af: 0x64,
+	0x1b3: 0x65, 0x1b5: 0x66, 0x1b7: 0x67,
+	0x1b8: 0x68, 0x1b9: 0x69, 0x1ba: 0x6a, 0x1bb: 0x6b, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6c,
 	// Block 0x7, offset 0x1c0
-	0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71,
-	0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77,
+	0x1c0: 0x6d, 0x1c2: 0x6e, 0x1c3: 0x6f, 0x1c7: 0x70,
+	0x1c8: 0x71, 0x1c9: 0x72, 0x1ca: 0x73, 0x1cb: 0x74, 0x1cd: 0x75, 0x1cf: 0x76,
 	// Block 0x8, offset 0x200
 	0x237: 0x54,
 	// Block 0x9, offset 0x240
-	0x252: 0x78, 0x253: 0x79,
-	0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f,
-	0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86,
-	0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26f: 0x8b,
+	0x252: 0x77, 0x253: 0x78,
+	0x258: 0x79, 0x259: 0x7a, 0x25a: 0x7b, 0x25b: 0x7c, 0x25c: 0x7d, 0x25e: 0x7e,
+	0x260: 0x7f, 0x261: 0x80, 0x263: 0x81, 0x264: 0x82, 0x265: 0x83, 0x266: 0x84, 0x267: 0x85,
+	0x268: 0x86, 0x269: 0x87, 0x26a: 0x88, 0x26b: 0x89, 0x26f: 0x8a,
 	// Block 0xa, offset 0x280
-	0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x0e, 0x2af: 0x0e,
-	0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8e, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8f,
-	0x2b8: 0x90, 0x2b9: 0x91, 0x2ba: 0x0e, 0x2bb: 0x92, 0x2bc: 0x93, 0x2bd: 0x94, 0x2bf: 0x95,
+	0x2ac: 0x8b, 0x2ad: 0x8c, 0x2ae: 0x0e, 0x2af: 0x0e,
+	0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8d, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8e,
+	0x2b8: 0x8f, 0x2b9: 0x90, 0x2ba: 0x0e, 0x2bb: 0x91, 0x2bc: 0x92, 0x2bd: 0x93, 0x2bf: 0x94,
 	// Block 0xb, offset 0x2c0
-	0x2c4: 0x96, 0x2c5: 0x54, 0x2c6: 0x97, 0x2c7: 0x98,
-	0x2cb: 0x99, 0x2cd: 0x9a,
-	0x2e0: 0x9b, 0x2e1: 0x9b, 0x2e2: 0x9b, 0x2e3: 0x9b, 0x2e4: 0x9c, 0x2e5: 0x9b, 0x2e6: 0x9b, 0x2e7: 0x9b,
-	0x2e8: 0x9d, 0x2e9: 0x9b, 0x2ea: 0x9b, 0x2eb: 0x9e, 0x2ec: 0x9f, 0x2ed: 0x9b, 0x2ee: 0x9b, 0x2ef: 0x9b,
-	0x2f0: 0x9b, 0x2f1: 0x9b, 0x2f2: 0x9b, 0x2f3: 0x9b, 0x2f4: 0x9b, 0x2f5: 0x9b, 0x2f6: 0x9b, 0x2f7: 0x9b,
-	0x2f8: 0x9b, 0x2f9: 0xa0, 0x2fa: 0x9b, 0x2fb: 0x9b, 0x2fc: 0x9b, 0x2fd: 0x9b, 0x2fe: 0x9b, 0x2ff: 0x9b,
+	0x2c4: 0x95, 0x2c5: 0x54, 0x2c6: 0x96, 0x2c7: 0x97,
+	0x2cb: 0x98, 0x2cd: 0x99,
+	0x2e0: 0x9a, 0x2e1: 0x9a, 0x2e2: 0x9a, 0x2e3: 0x9a, 0x2e4: 0x9b, 0x2e5: 0x9a, 0x2e6: 0x9a, 0x2e7: 0x9a,
+	0x2e8: 0x9c, 0x2e9: 0x9a, 0x2ea: 0x9a, 0x2eb: 0x9d, 0x2ec: 0x9e, 0x2ed: 0x9a, 0x2ee: 0x9a, 0x2ef: 0x9a,
+	0x2f0: 0x9a, 0x2f1: 0x9a, 0x2f2: 0x9a, 0x2f3: 0x9a, 0x2f4: 0x9a, 0x2f5: 0x9a, 0x2f6: 0x9a, 0x2f7: 0x9a,
+	0x2f8: 0x9a, 0x2f9: 0x9f, 0x2fa: 0x9a, 0x2fb: 0x9a, 0x2fc: 0x9a, 0x2fd: 0x9a, 0x2fe: 0x9a, 0x2ff: 0x9a,
 	// Block 0xc, offset 0x300
-	0x300: 0xa1, 0x301: 0xa2, 0x302: 0xa3, 0x304: 0xa4, 0x305: 0xa5, 0x306: 0xa6, 0x307: 0xa7,
-	0x308: 0xa8, 0x30b: 0xa9, 0x30c: 0xaa, 0x30d: 0xab,
-	0x310: 0xac, 0x311: 0xad, 0x312: 0xae, 0x313: 0xaf, 0x316: 0xb0, 0x317: 0xb1,
-	0x318: 0xb2, 0x319: 0xb3, 0x31a: 0xb4, 0x31c: 0xb5,
-	0x330: 0xb6, 0x332: 0xb7,
+	0x300: 0xa0, 0x301: 0xa1, 0x302: 0xa2, 0x304: 0xa3, 0x305: 0xa4, 0x306: 0xa5, 0x307: 0xa6,
+	0x308: 0xa7, 0x30b: 0xa8, 0x30c: 0xa9, 0x30d: 0xaa,
+	0x310: 0xab, 0x311: 0xac, 0x312: 0xad, 0x313: 0xae, 0x316: 0xaf, 0x317: 0xb0,
+	0x318: 0xb1, 0x319: 0xb2, 0x31a: 0xb3, 0x31c: 0xb4,
+	0x328: 0xb5, 0x329: 0xb6, 0x32a: 0xb7,
+	0x330: 0xb8, 0x332: 0xb9, 0x334: 0xba, 0x335: 0xbb,
 	// Block 0xd, offset 0x340
-	0x36b: 0xb8, 0x36c: 0xb9,
-	0x37e: 0xba,
+	0x36b: 0xbc, 0x36c: 0xbd,
+	0x37e: 0xbe,
 	// Block 0xe, offset 0x380
-	0x3b2: 0xbb,
+	0x3b2: 0xbf,
 	// Block 0xf, offset 0x3c0
-	0x3c5: 0xbc, 0x3c6: 0xbd,
-	0x3c8: 0x54, 0x3c9: 0xbe, 0x3cc: 0x54, 0x3cd: 0xbf,
-	0x3db: 0xc0, 0x3dc: 0xc1, 0x3dd: 0xc2, 0x3de: 0xc3, 0x3df: 0xc4,
-	0x3e8: 0xc5, 0x3e9: 0xc6, 0x3ea: 0xc7,
+	0x3c5: 0xc0, 0x3c6: 0xc1,
+	0x3c8: 0x54, 0x3c9: 0xc2, 0x3cc: 0x54, 0x3cd: 0xc3,
+	0x3db: 0xc4, 0x3dc: 0xc5, 0x3dd: 0xc6, 0x3de: 0xc7, 0x3df: 0xc8,
+	0x3e8: 0xc9, 0x3e9: 0xca, 0x3ea: 0xcb,
 	// Block 0x10, offset 0x400
-	0x400: 0xc8,
-	0x420: 0x9b, 0x421: 0x9b, 0x422: 0x9b, 0x423: 0xc9, 0x424: 0x9b, 0x425: 0xca, 0x426: 0x9b, 0x427: 0x9b,
-	0x428: 0x9b, 0x429: 0x9b, 0x42a: 0x9b, 0x42b: 0x9b, 0x42c: 0x9b, 0x42d: 0x9b, 0x42e: 0x9b, 0x42f: 0x9b,
-	0x430: 0x9b, 0x431: 0x9b, 0x432: 0x9b, 0x433: 0x9b, 0x434: 0x9b, 0x435: 0x9b, 0x436: 0x9b, 0x437: 0x9b,
-	0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xcb, 0x43c: 0x9b, 0x43d: 0x9b, 0x43e: 0x9b, 0x43f: 0x9b,
+	0x400: 0xcc,
+	0x420: 0x9a, 0x421: 0x9a, 0x422: 0x9a, 0x423: 0xcd, 0x424: 0x9a, 0x425: 0xce, 0x426: 0x9a, 0x427: 0x9a,
+	0x428: 0x9a, 0x429: 0x9a, 0x42a: 0x9a, 0x42b: 0x9a, 0x42c: 0x9a, 0x42d: 0x9a, 0x42e: 0x9a, 0x42f: 0x9a,
+	0x430: 0x9a, 0x431: 0x9a, 0x432: 0x9a, 0x433: 0x9a, 0x434: 0x9a, 0x435: 0x9a, 0x436: 0x9a, 0x437: 0x9a,
+	0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xcf, 0x43c: 0x9a, 0x43d: 0x9a, 0x43e: 0x9a, 0x43f: 0x9a,
 	// Block 0x11, offset 0x440
-	0x440: 0xcc, 0x441: 0x54, 0x442: 0xcd, 0x443: 0xce, 0x444: 0xcf, 0x445: 0xd0,
-	0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54,
+	0x440: 0xd0, 0x441: 0x54, 0x442: 0xd1, 0x443: 0xd2, 0x444: 0xd3, 0x445: 0xd4,
+	0x449: 0xd5, 0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54,
 	0x450: 0x54, 0x451: 0x54, 0x452: 0x54, 0x453: 0x54, 0x454: 0x54, 0x455: 0x54, 0x456: 0x54, 0x457: 0x54,
-	0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xd1, 0x45c: 0x54, 0x45d: 0x6c, 0x45e: 0x54, 0x45f: 0xd2,
-	0x460: 0xd3, 0x461: 0xd4, 0x462: 0xd5, 0x464: 0xd6, 0x465: 0xd7, 0x466: 0xd8, 0x467: 0x36,
-	0x47f: 0xd9,
+	0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xd6, 0x45c: 0x54, 0x45d: 0x6b, 0x45e: 0x54, 0x45f: 0xd7,
+	0x460: 0xd8, 0x461: 0xd9, 0x462: 0xda, 0x464: 0xdb, 0x465: 0xdc, 0x466: 0xdd, 0x467: 0xde,
+	0x47f: 0xdf,
 	// Block 0x12, offset 0x480
-	0x4bf: 0xd9,
+	0x4bf: 0xdf,
 	// Block 0x13, offset 0x4c0
 	0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b,
 	0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f,
@@ -1760,14 +1794,14 @@
 	0x52f: 0x10,
 	0x53f: 0x10,
 	// Block 0x15, offset 0x540
-	0x540: 0xda, 0x541: 0xda, 0x542: 0xda, 0x543: 0xda, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xdb,
-	0x548: 0xda, 0x549: 0xda, 0x54a: 0xda, 0x54b: 0xda, 0x54c: 0xda, 0x54d: 0xda, 0x54e: 0xda, 0x54f: 0xda,
-	0x550: 0xda, 0x551: 0xda, 0x552: 0xda, 0x553: 0xda, 0x554: 0xda, 0x555: 0xda, 0x556: 0xda, 0x557: 0xda,
-	0x558: 0xda, 0x559: 0xda, 0x55a: 0xda, 0x55b: 0xda, 0x55c: 0xda, 0x55d: 0xda, 0x55e: 0xda, 0x55f: 0xda,
-	0x560: 0xda, 0x561: 0xda, 0x562: 0xda, 0x563: 0xda, 0x564: 0xda, 0x565: 0xda, 0x566: 0xda, 0x567: 0xda,
-	0x568: 0xda, 0x569: 0xda, 0x56a: 0xda, 0x56b: 0xda, 0x56c: 0xda, 0x56d: 0xda, 0x56e: 0xda, 0x56f: 0xda,
-	0x570: 0xda, 0x571: 0xda, 0x572: 0xda, 0x573: 0xda, 0x574: 0xda, 0x575: 0xda, 0x576: 0xda, 0x577: 0xda,
-	0x578: 0xda, 0x579: 0xda, 0x57a: 0xda, 0x57b: 0xda, 0x57c: 0xda, 0x57d: 0xda, 0x57e: 0xda, 0x57f: 0xda,
+	0x540: 0xe0, 0x541: 0xe0, 0x542: 0xe0, 0x543: 0xe0, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xe1,
+	0x548: 0xe0, 0x549: 0xe0, 0x54a: 0xe0, 0x54b: 0xe0, 0x54c: 0xe0, 0x54d: 0xe0, 0x54e: 0xe0, 0x54f: 0xe0,
+	0x550: 0xe0, 0x551: 0xe0, 0x552: 0xe0, 0x553: 0xe0, 0x554: 0xe0, 0x555: 0xe0, 0x556: 0xe0, 0x557: 0xe0,
+	0x558: 0xe0, 0x559: 0xe0, 0x55a: 0xe0, 0x55b: 0xe0, 0x55c: 0xe0, 0x55d: 0xe0, 0x55e: 0xe0, 0x55f: 0xe0,
+	0x560: 0xe0, 0x561: 0xe0, 0x562: 0xe0, 0x563: 0xe0, 0x564: 0xe0, 0x565: 0xe0, 0x566: 0xe0, 0x567: 0xe0,
+	0x568: 0xe0, 0x569: 0xe0, 0x56a: 0xe0, 0x56b: 0xe0, 0x56c: 0xe0, 0x56d: 0xe0, 0x56e: 0xe0, 0x56f: 0xe0,
+	0x570: 0xe0, 0x571: 0xe0, 0x572: 0xe0, 0x573: 0xe0, 0x574: 0xe0, 0x575: 0xe0, 0x576: 0xe0, 0x577: 0xe0,
+	0x578: 0xe0, 0x579: 0xe0, 0x57a: 0xe0, 0x57b: 0xe0, 0x57c: 0xe0, 0x57d: 0xe0, 0x57e: 0xe0, 0x57f: 0xe0,
 	// Block 0x16, offset 0x580
 	0x58f: 0x10,
 	0x59f: 0x10,
@@ -1778,4 +1812,4 @@
 	0x5cf: 0x10,
 }
 
-// Total table size 15800 bytes (15KiB); checksum: F50EF68C
+// Total table size 16184 bytes (15KiB); checksum: F50EF68C
diff --git a/src/vendor/golang_org/x/text/unicode/bidi/trieval.go b/src/vendor/golang_org/x/text/unicode/bidi/trieval.go
index a825fde..c3f0e21 100644
--- a/src/vendor/golang_org/x/text/unicode/bidi/trieval.go
+++ b/src/vendor/golang_org/x/text/unicode/bidi/trieval.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Code generated by running "go generate" in golang_org/x/text. DO NOT EDIT.
 
diff --git a/src/vendor/golang_org/x/text/unicode/doc.go b/src/vendor/golang_org/x/text/unicode/doc.go
index 36b462a..55a6775 100644
--- a/src/vendor/golang_org/x/text/unicode/doc.go
+++ b/src/vendor/golang_org/x/text/unicode/doc.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/norm/composition.go b/src/vendor/golang_org/x/text/unicode/norm/composition.go
index 7380b05..80287d2 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/composition.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/composition.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -35,17 +35,9 @@
 // streamSafe implements the policy of when a CGJ should be inserted.
 type streamSafe uint8
 
-// mkStreamSafe is a shorthand for declaring a streamSafe var and calling
-// first on it.
-func mkStreamSafe(p Properties) streamSafe {
-	return streamSafe(p.nTrailingNonStarters())
-}
-
-// first inserts the first rune of a segment.
+// first inserts the first rune of a segment. It is a faster version of next if
+// it is known p represents the first rune in a segment.
 func (ss *streamSafe) first(p Properties) {
-	if *ss != 0 {
-		panic("!= 0")
-	}
 	*ss = streamSafe(p.nTrailingNonStarters())
 }
 
@@ -68,7 +60,7 @@
 	// be a non-starter. Note that it always hold that if nLead > 0 then
 	// nLead == nTrail.
 	if n == 0 {
-		*ss = 0
+		*ss = streamSafe(p.nTrailingNonStarters())
 		return ssStarter
 	}
 	return ssSuccess
@@ -144,7 +136,6 @@
 func (rb *reorderBuffer) reset() {
 	rb.nrune = 0
 	rb.nbyte = 0
-	rb.ss = 0
 }
 
 func (rb *reorderBuffer) doFlush() bool {
@@ -259,6 +250,9 @@
 // It flushes the buffer on each new segment start.
 func (rb *reorderBuffer) insertDecomposed(dcomp []byte) insertErr {
 	rb.tmpBytes.setBytes(dcomp)
+	// As the streamSafe accounting already handles the counting for modifiers,
+	// we don't have to call next. However, we do need to keep the accounting
+	// intact when flushing the buffer.
 	for i := 0; i < len(dcomp); {
 		info := rb.f.info(rb.tmpBytes, i)
 		if info.BoundaryBefore() && rb.nrune > 0 && !rb.doFlush() {
diff --git a/src/vendor/golang_org/x/text/unicode/norm/forminfo.go b/src/vendor/golang_org/x/text/unicode/norm/forminfo.go
index f3e2930..6455840 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/forminfo.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/forminfo.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/norm/input.go b/src/vendor/golang_org/x/text/unicode/norm/input.go
index 202bde1..315f6fc 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/input.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/input.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -92,16 +92,20 @@
 }
 
 func (in *input) hangul(p int) (r rune) {
+	var size int
 	if in.bytes == nil {
 		if !isHangulString(in.str[p:]) {
 			return 0
 		}
-		r, _ = utf8.DecodeRuneInString(in.str[p:])
+		r, size = utf8.DecodeRuneInString(in.str[p:])
 	} else {
 		if !isHangul(in.bytes[p:]) {
 			return 0
 		}
-		r, _ = utf8.DecodeRune(in.bytes[p:])
+		r, size = utf8.DecodeRune(in.bytes[p:])
+	}
+	if size != hangulUTF8Size {
+		return 0
 	}
 	return r
 }
diff --git a/src/vendor/golang_org/x/text/unicode/norm/iter.go b/src/vendor/golang_org/x/text/unicode/norm/iter.go
index c0cf949..d0ae6cb 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/iter.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/iter.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -43,6 +43,7 @@
 	i.next = i.rb.f.nextMain
 	i.asciiF = nextASCIIBytes
 	i.info = i.rb.f.info(i.rb.src, i.p)
+	i.rb.ss.first(i.info)
 }
 
 // InitString initializes i to iterate over src after normalizing it to Form f.
@@ -58,11 +59,12 @@
 	i.next = i.rb.f.nextMain
 	i.asciiF = nextASCIIString
 	i.info = i.rb.f.info(i.rb.src, i.p)
+	i.rb.ss.first(i.info)
 }
 
 // Seek sets the segment to be returned by the next call to Next to start
 // at position p.  It is the responsibility of the caller to set p to the
-// start of a UTF8 rune.
+// start of a segment.
 func (i *Iter) Seek(offset int64, whence int) (int64, error) {
 	var abs int64
 	switch whence {
@@ -86,6 +88,7 @@
 	i.multiSeg = nil
 	i.next = i.rb.f.nextMain
 	i.info = i.rb.f.info(i.rb.src, i.p)
+	i.rb.ss.first(i.info)
 	return abs, nil
 }
 
@@ -163,6 +166,7 @@
 	if next >= i.rb.nsrc {
 		i.setDone()
 	} else if i.rb.src.hangul(next) == 0 {
+		i.rb.ss.next(i.info)
 		i.info = i.rb.f.info(i.rb.src, i.p)
 		i.next = i.rb.f.nextMain
 		return i.next(i)
@@ -206,12 +210,10 @@
 		if info.BoundaryBefore() {
 			i.rb.compose()
 			seg := i.buf[:i.rb.flushCopy(i.buf[:])]
-			i.rb.ss.first(info)
 			i.rb.insertUnsafe(input{bytes: d}, j, info)
 			i.multiSeg = d[j+int(info.size):]
 			return seg
 		}
-		i.rb.ss.next(info)
 		i.rb.insertUnsafe(input{bytes: d}, j, info)
 		j += int(info.size)
 	}
@@ -224,9 +226,9 @@
 func nextDecomposed(i *Iter) (next []byte) {
 	outp := 0
 	inCopyStart, outCopyStart := i.p, 0
-	ss := mkStreamSafe(i.info)
 	for {
 		if sz := int(i.info.size); sz <= 1 {
+			i.rb.ss = 0
 			p := i.p
 			i.p++ // ASCII or illegal byte.  Either way, advance by 1.
 			if i.p >= i.rb.nsrc {
@@ -245,6 +247,8 @@
 			p := outp + len(d)
 			if outp > 0 {
 				i.rb.src.copySlice(i.buf[outCopyStart:], inCopyStart, i.p)
+				// TODO: this condition should not be possible, but we leave it
+				// in for defensive purposes.
 				if p > len(i.buf) {
 					return i.buf[:outp]
 				}
@@ -268,7 +272,7 @@
 			} else {
 				i.info = i.rb.f.info(i.rb.src, i.p)
 			}
-			switch ss.next(i.info) {
+			switch i.rb.ss.next(i.info) {
 			case ssOverflow:
 				i.next = nextCGJDecompose
 				fallthrough
@@ -311,7 +315,7 @@
 		}
 		prevCC := i.info.tccc
 		i.info = i.rb.f.info(i.rb.src, i.p)
-		if v := ss.next(i.info); v == ssStarter {
+		if v := i.rb.ss.next(i.info); v == ssStarter {
 			break
 		} else if v == ssOverflow {
 			i.next = nextCGJDecompose
@@ -337,10 +341,6 @@
 
 func doNormDecomposed(i *Iter) []byte {
 	for {
-		if s := i.rb.ss.next(i.info); s == ssOverflow {
-			i.next = nextCGJDecompose
-			break
-		}
 		i.rb.insertUnsafe(i.rb.src, i.p, i.info)
 		if i.p += int(i.info.size); i.p >= i.rb.nsrc {
 			i.setDone()
@@ -350,6 +350,10 @@
 		if i.info.ccc == 0 {
 			break
 		}
+		if s := i.rb.ss.next(i.info); s == ssOverflow {
+			i.next = nextCGJDecompose
+			break
+		}
 	}
 	// new segment or too many combining characters: exit normalization
 	return i.buf[:i.rb.flushCopy(i.buf[:])]
@@ -359,6 +363,7 @@
 	i.rb.ss = 0
 	i.rb.insertCGJ()
 	i.next = nextDecomposed
+	i.rb.ss.first(i.info)
 	buf := doNormDecomposed(i)
 	return buf
 }
@@ -367,7 +372,6 @@
 func nextComposed(i *Iter) []byte {
 	outp, startp := 0, i.p
 	var prevCC uint8
-	ss := mkStreamSafe(i.info)
 	for {
 		if !i.info.isYesC() {
 			goto doNorm
@@ -387,11 +391,12 @@
 			i.setDone()
 			break
 		} else if i.rb.src._byte(i.p) < utf8.RuneSelf {
+			i.rb.ss = 0
 			i.next = i.asciiF
 			break
 		}
 		i.info = i.rb.f.info(i.rb.src, i.p)
-		if v := ss.next(i.info); v == ssStarter {
+		if v := i.rb.ss.next(i.info); v == ssStarter {
 			break
 		} else if v == ssOverflow {
 			i.next = nextCGJCompose
@@ -403,8 +408,10 @@
 	}
 	return i.returnSlice(startp, i.p)
 doNorm:
+	// reset to start position
 	i.p = startp
 	i.info = i.rb.f.info(i.rb.src, i.p)
+	i.rb.ss.first(i.info)
 	if i.info.multiSegment() {
 		d := i.info.Decomposition()
 		info := i.rb.f.info(input{bytes: d}, 0)
diff --git a/src/vendor/golang_org/x/text/unicode/norm/normalize.go b/src/vendor/golang_org/x/text/unicode/norm/normalize.go
index 4427ee3..4de4ed6 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/normalize.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/normalize.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -324,7 +324,6 @@
 		// have an overflow for runes that are starters (e.g. with U+FF9E).
 		switch ss.next(info) {
 		case ssStarter:
-			ss.first(info)
 			lastSegStart = i
 		case ssOverflow:
 			return lastSegStart, false
@@ -441,6 +440,8 @@
 			}
 			return -1
 		}
+		// TODO: Using streamSafe to determine the boundary isn't the same as
+		// using BoundaryBefore. Determine which should be used.
 		if s := ss.next(info); s != ssSuccess {
 			return i
 		}
@@ -505,15 +506,14 @@
 	if info.size == 0 {
 		return 0
 	}
-	if rb.nrune > 0 {
-		if s := rb.ss.next(info); s == ssStarter {
-			goto end
-		} else if s == ssOverflow {
-			rb.insertCGJ()
+	if s := rb.ss.next(info); s == ssStarter {
+		// TODO: this could be removed if we don't support merging.
+		if rb.nrune > 0 {
 			goto end
 		}
-	} else {
-		rb.ss.first(info)
+	} else if s == ssOverflow {
+		rb.insertCGJ()
+		goto end
 	}
 	if err := rb.insertFlush(rb.src, sp, info); err != iSuccess {
 		return int(err)
diff --git a/src/vendor/golang_org/x/text/unicode/norm/readwriter.go b/src/vendor/golang_org/x/text/unicode/norm/readwriter.go
index 482ac85..068ab57 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/readwriter.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/readwriter.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/vendor/golang_org/x/text/unicode/norm/tables.go b/src/vendor/golang_org/x/text/unicode/norm/tables.go
index ac99519..d646683 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/tables.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/tables.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Code generated by running "go generate" in golang_org/x/text. DO NOT EDIT.
 
@@ -6,7 +6,7 @@
 
 const (
 	// Version is the Unicode edition from which the tables are derived.
-	Version = "9.0.0"
+	Version = "10.0.0"
 
 	// MaxTransformChunkSize indicates the maximum number of bytes that Transform
 	// may need to write atomically for any Form. Making a destination buffer at
@@ -2898,7 +2898,7 @@
 	return 0
 }
 
-// nfcTrie. Total size: 10332 bytes (10.09 KiB). Checksum: 51cc525b297fc970.
+// nfcTrie. Total size: 10442 bytes (10.20 KiB). Checksum: 4ba400a9d8208e03.
 type nfcTrie struct{}
 
 func newNfcTrie(i int) *nfcTrie {
@@ -2908,17 +2908,17 @@
 // lookupValue determines the type of block n and looks up the value for b.
 func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 {
 	switch {
-	case n < 44:
+	case n < 45:
 		return uint16(nfcValues[n<<6+uint32(b)])
 	default:
-		n -= 44
+		n -= 45
 		return uint16(nfcSparse.lookup(n, b))
 	}
 }
 
-// nfcValues: 46 blocks, 2944 entries, 5888 bytes
+// nfcValues: 47 blocks, 3008 entries, 6016 bytes
 // The third block is the zero block.
-var nfcValues = [2944]uint16{
+var nfcValues = [3008]uint16{
 	// Block 0x0, offset 0x0
 	0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
 	// Block 0x1, offset 0x40
@@ -3075,341 +3075,353 @@
 	0x3fa: 0xa000, 0x3fb: 0x2d56,
 	0x3fc: 0xa000, 0x3fd: 0x2d5e, 0x3fe: 0xa000, 0x3ff: 0xa000,
 	// Block 0x10, offset 0x400
-	0x400: 0x2f97, 0x401: 0x32a3, 0x402: 0x2fa1, 0x403: 0x32ad, 0x404: 0x2fa6, 0x405: 0x32b2,
-	0x406: 0x2fab, 0x407: 0x32b7, 0x408: 0x38cc, 0x409: 0x3a5b, 0x40a: 0x2fc4, 0x40b: 0x32d0,
-	0x40c: 0x2fce, 0x40d: 0x32da, 0x40e: 0x2fdd, 0x40f: 0x32e9, 0x410: 0x2fd3, 0x411: 0x32df,
-	0x412: 0x2fd8, 0x413: 0x32e4, 0x414: 0x38ef, 0x415: 0x3a7e, 0x416: 0x38f6, 0x417: 0x3a85,
-	0x418: 0x3019, 0x419: 0x3325, 0x41a: 0x301e, 0x41b: 0x332a, 0x41c: 0x3904, 0x41d: 0x3a93,
-	0x41e: 0x3023, 0x41f: 0x332f, 0x420: 0x3032, 0x421: 0x333e, 0x422: 0x3050, 0x423: 0x335c,
-	0x424: 0x305f, 0x425: 0x336b, 0x426: 0x3055, 0x427: 0x3361, 0x428: 0x3064, 0x429: 0x3370,
-	0x42a: 0x3069, 0x42b: 0x3375, 0x42c: 0x30af, 0x42d: 0x33bb, 0x42e: 0x390b, 0x42f: 0x3a9a,
-	0x430: 0x30b9, 0x431: 0x33ca, 0x432: 0x30c3, 0x433: 0x33d4, 0x434: 0x30cd, 0x435: 0x33de,
-	0x436: 0x46c4, 0x437: 0x4755, 0x438: 0x3912, 0x439: 0x3aa1, 0x43a: 0x30e6, 0x43b: 0x33f7,
-	0x43c: 0x30e1, 0x43d: 0x33f2, 0x43e: 0x30eb, 0x43f: 0x33fc,
+	0x400: 0x8132, 0x401: 0x8132, 0x402: 0x812d, 0x403: 0x8132, 0x404: 0x8132, 0x405: 0x8132,
+	0x406: 0x8132, 0x407: 0x8132, 0x408: 0x8132, 0x409: 0x8132, 0x40a: 0x812d, 0x40b: 0x8132,
+	0x40c: 0x8132, 0x40d: 0x8135, 0x40e: 0x812a, 0x40f: 0x812d, 0x410: 0x8129, 0x411: 0x8132,
+	0x412: 0x8132, 0x413: 0x8132, 0x414: 0x8132, 0x415: 0x8132, 0x416: 0x8132, 0x417: 0x8132,
+	0x418: 0x8132, 0x419: 0x8132, 0x41a: 0x8132, 0x41b: 0x8132, 0x41c: 0x8132, 0x41d: 0x8132,
+	0x41e: 0x8132, 0x41f: 0x8132, 0x420: 0x8132, 0x421: 0x8132, 0x422: 0x8132, 0x423: 0x8132,
+	0x424: 0x8132, 0x425: 0x8132, 0x426: 0x8132, 0x427: 0x8132, 0x428: 0x8132, 0x429: 0x8132,
+	0x42a: 0x8132, 0x42b: 0x8132, 0x42c: 0x8132, 0x42d: 0x8132, 0x42e: 0x8132, 0x42f: 0x8132,
+	0x430: 0x8132, 0x431: 0x8132, 0x432: 0x8132, 0x433: 0x8132, 0x434: 0x8132, 0x435: 0x8132,
+	0x436: 0x8133, 0x437: 0x8131, 0x438: 0x8131, 0x439: 0x812d, 0x43b: 0x8132,
+	0x43c: 0x8134, 0x43d: 0x812d, 0x43e: 0x8132, 0x43f: 0x812d,
 	// Block 0x11, offset 0x440
-	0x440: 0x30f0, 0x441: 0x3401, 0x442: 0x30f5, 0x443: 0x3406, 0x444: 0x3109, 0x445: 0x341a,
-	0x446: 0x3113, 0x447: 0x3424, 0x448: 0x3122, 0x449: 0x3433, 0x44a: 0x311d, 0x44b: 0x342e,
-	0x44c: 0x3935, 0x44d: 0x3ac4, 0x44e: 0x3943, 0x44f: 0x3ad2, 0x450: 0x394a, 0x451: 0x3ad9,
-	0x452: 0x3951, 0x453: 0x3ae0, 0x454: 0x314f, 0x455: 0x3460, 0x456: 0x3154, 0x457: 0x3465,
-	0x458: 0x315e, 0x459: 0x346f, 0x45a: 0x46f1, 0x45b: 0x4782, 0x45c: 0x3997, 0x45d: 0x3b26,
-	0x45e: 0x3177, 0x45f: 0x3488, 0x460: 0x3181, 0x461: 0x3492, 0x462: 0x4700, 0x463: 0x4791,
-	0x464: 0x399e, 0x465: 0x3b2d, 0x466: 0x39a5, 0x467: 0x3b34, 0x468: 0x39ac, 0x469: 0x3b3b,
-	0x46a: 0x3190, 0x46b: 0x34a1, 0x46c: 0x319a, 0x46d: 0x34b0, 0x46e: 0x31ae, 0x46f: 0x34c4,
-	0x470: 0x31a9, 0x471: 0x34bf, 0x472: 0x31ea, 0x473: 0x3500, 0x474: 0x31f9, 0x475: 0x350f,
-	0x476: 0x31f4, 0x477: 0x350a, 0x478: 0x39b3, 0x479: 0x3b42, 0x47a: 0x39ba, 0x47b: 0x3b49,
-	0x47c: 0x31fe, 0x47d: 0x3514, 0x47e: 0x3203, 0x47f: 0x3519,
+	0x440: 0x2f97, 0x441: 0x32a3, 0x442: 0x2fa1, 0x443: 0x32ad, 0x444: 0x2fa6, 0x445: 0x32b2,
+	0x446: 0x2fab, 0x447: 0x32b7, 0x448: 0x38cc, 0x449: 0x3a5b, 0x44a: 0x2fc4, 0x44b: 0x32d0,
+	0x44c: 0x2fce, 0x44d: 0x32da, 0x44e: 0x2fdd, 0x44f: 0x32e9, 0x450: 0x2fd3, 0x451: 0x32df,
+	0x452: 0x2fd8, 0x453: 0x32e4, 0x454: 0x38ef, 0x455: 0x3a7e, 0x456: 0x38f6, 0x457: 0x3a85,
+	0x458: 0x3019, 0x459: 0x3325, 0x45a: 0x301e, 0x45b: 0x332a, 0x45c: 0x3904, 0x45d: 0x3a93,
+	0x45e: 0x3023, 0x45f: 0x332f, 0x460: 0x3032, 0x461: 0x333e, 0x462: 0x3050, 0x463: 0x335c,
+	0x464: 0x305f, 0x465: 0x336b, 0x466: 0x3055, 0x467: 0x3361, 0x468: 0x3064, 0x469: 0x3370,
+	0x46a: 0x3069, 0x46b: 0x3375, 0x46c: 0x30af, 0x46d: 0x33bb, 0x46e: 0x390b, 0x46f: 0x3a9a,
+	0x470: 0x30b9, 0x471: 0x33ca, 0x472: 0x30c3, 0x473: 0x33d4, 0x474: 0x30cd, 0x475: 0x33de,
+	0x476: 0x46c4, 0x477: 0x4755, 0x478: 0x3912, 0x479: 0x3aa1, 0x47a: 0x30e6, 0x47b: 0x33f7,
+	0x47c: 0x30e1, 0x47d: 0x33f2, 0x47e: 0x30eb, 0x47f: 0x33fc,
 	// Block 0x12, offset 0x480
-	0x480: 0x3208, 0x481: 0x351e, 0x482: 0x320d, 0x483: 0x3523, 0x484: 0x321c, 0x485: 0x3532,
-	0x486: 0x3217, 0x487: 0x352d, 0x488: 0x3221, 0x489: 0x353c, 0x48a: 0x3226, 0x48b: 0x3541,
-	0x48c: 0x322b, 0x48d: 0x3546, 0x48e: 0x3249, 0x48f: 0x3564, 0x490: 0x3262, 0x491: 0x3582,
-	0x492: 0x3271, 0x493: 0x3591, 0x494: 0x3276, 0x495: 0x3596, 0x496: 0x337a, 0x497: 0x34a6,
-	0x498: 0x3537, 0x499: 0x3573, 0x49b: 0x35d1,
-	0x4a0: 0x46a1, 0x4a1: 0x4732, 0x4a2: 0x2f83, 0x4a3: 0x328f,
-	0x4a4: 0x3878, 0x4a5: 0x3a07, 0x4a6: 0x3871, 0x4a7: 0x3a00, 0x4a8: 0x3886, 0x4a9: 0x3a15,
-	0x4aa: 0x387f, 0x4ab: 0x3a0e, 0x4ac: 0x38be, 0x4ad: 0x3a4d, 0x4ae: 0x3894, 0x4af: 0x3a23,
-	0x4b0: 0x388d, 0x4b1: 0x3a1c, 0x4b2: 0x38a2, 0x4b3: 0x3a31, 0x4b4: 0x389b, 0x4b5: 0x3a2a,
-	0x4b6: 0x38c5, 0x4b7: 0x3a54, 0x4b8: 0x46b5, 0x4b9: 0x4746, 0x4ba: 0x3000, 0x4bb: 0x330c,
-	0x4bc: 0x2fec, 0x4bd: 0x32f8, 0x4be: 0x38da, 0x4bf: 0x3a69,
+	0x480: 0x30f0, 0x481: 0x3401, 0x482: 0x30f5, 0x483: 0x3406, 0x484: 0x3109, 0x485: 0x341a,
+	0x486: 0x3113, 0x487: 0x3424, 0x488: 0x3122, 0x489: 0x3433, 0x48a: 0x311d, 0x48b: 0x342e,
+	0x48c: 0x3935, 0x48d: 0x3ac4, 0x48e: 0x3943, 0x48f: 0x3ad2, 0x490: 0x394a, 0x491: 0x3ad9,
+	0x492: 0x3951, 0x493: 0x3ae0, 0x494: 0x314f, 0x495: 0x3460, 0x496: 0x3154, 0x497: 0x3465,
+	0x498: 0x315e, 0x499: 0x346f, 0x49a: 0x46f1, 0x49b: 0x4782, 0x49c: 0x3997, 0x49d: 0x3b26,
+	0x49e: 0x3177, 0x49f: 0x3488, 0x4a0: 0x3181, 0x4a1: 0x3492, 0x4a2: 0x4700, 0x4a3: 0x4791,
+	0x4a4: 0x399e, 0x4a5: 0x3b2d, 0x4a6: 0x39a5, 0x4a7: 0x3b34, 0x4a8: 0x39ac, 0x4a9: 0x3b3b,
+	0x4aa: 0x3190, 0x4ab: 0x34a1, 0x4ac: 0x319a, 0x4ad: 0x34b0, 0x4ae: 0x31ae, 0x4af: 0x34c4,
+	0x4b0: 0x31a9, 0x4b1: 0x34bf, 0x4b2: 0x31ea, 0x4b3: 0x3500, 0x4b4: 0x31f9, 0x4b5: 0x350f,
+	0x4b6: 0x31f4, 0x4b7: 0x350a, 0x4b8: 0x39b3, 0x4b9: 0x3b42, 0x4ba: 0x39ba, 0x4bb: 0x3b49,
+	0x4bc: 0x31fe, 0x4bd: 0x3514, 0x4be: 0x3203, 0x4bf: 0x3519,
 	// Block 0x13, offset 0x4c0
-	0x4c0: 0x38d3, 0x4c1: 0x3a62, 0x4c2: 0x38e8, 0x4c3: 0x3a77, 0x4c4: 0x38e1, 0x4c5: 0x3a70,
-	0x4c6: 0x38fd, 0x4c7: 0x3a8c, 0x4c8: 0x3091, 0x4c9: 0x339d, 0x4ca: 0x30a5, 0x4cb: 0x33b1,
-	0x4cc: 0x46e7, 0x4cd: 0x4778, 0x4ce: 0x3136, 0x4cf: 0x3447, 0x4d0: 0x3920, 0x4d1: 0x3aaf,
-	0x4d2: 0x3919, 0x4d3: 0x3aa8, 0x4d4: 0x392e, 0x4d5: 0x3abd, 0x4d6: 0x3927, 0x4d7: 0x3ab6,
-	0x4d8: 0x3989, 0x4d9: 0x3b18, 0x4da: 0x396d, 0x4db: 0x3afc, 0x4dc: 0x3966, 0x4dd: 0x3af5,
-	0x4de: 0x397b, 0x4df: 0x3b0a, 0x4e0: 0x3974, 0x4e1: 0x3b03, 0x4e2: 0x3982, 0x4e3: 0x3b11,
-	0x4e4: 0x31e5, 0x4e5: 0x34fb, 0x4e6: 0x31c7, 0x4e7: 0x34dd, 0x4e8: 0x39e4, 0x4e9: 0x3b73,
-	0x4ea: 0x39dd, 0x4eb: 0x3b6c, 0x4ec: 0x39f2, 0x4ed: 0x3b81, 0x4ee: 0x39eb, 0x4ef: 0x3b7a,
-	0x4f0: 0x39f9, 0x4f1: 0x3b88, 0x4f2: 0x3230, 0x4f3: 0x354b, 0x4f4: 0x3258, 0x4f5: 0x3578,
-	0x4f6: 0x3253, 0x4f7: 0x356e, 0x4f8: 0x323f, 0x4f9: 0x355a,
+	0x4c0: 0x3208, 0x4c1: 0x351e, 0x4c2: 0x320d, 0x4c3: 0x3523, 0x4c4: 0x321c, 0x4c5: 0x3532,
+	0x4c6: 0x3217, 0x4c7: 0x352d, 0x4c8: 0x3221, 0x4c9: 0x353c, 0x4ca: 0x3226, 0x4cb: 0x3541,
+	0x4cc: 0x322b, 0x4cd: 0x3546, 0x4ce: 0x3249, 0x4cf: 0x3564, 0x4d0: 0x3262, 0x4d1: 0x3582,
+	0x4d2: 0x3271, 0x4d3: 0x3591, 0x4d4: 0x3276, 0x4d5: 0x3596, 0x4d6: 0x337a, 0x4d7: 0x34a6,
+	0x4d8: 0x3537, 0x4d9: 0x3573, 0x4db: 0x35d1,
+	0x4e0: 0x46a1, 0x4e1: 0x4732, 0x4e2: 0x2f83, 0x4e3: 0x328f,
+	0x4e4: 0x3878, 0x4e5: 0x3a07, 0x4e6: 0x3871, 0x4e7: 0x3a00, 0x4e8: 0x3886, 0x4e9: 0x3a15,
+	0x4ea: 0x387f, 0x4eb: 0x3a0e, 0x4ec: 0x38be, 0x4ed: 0x3a4d, 0x4ee: 0x3894, 0x4ef: 0x3a23,
+	0x4f0: 0x388d, 0x4f1: 0x3a1c, 0x4f2: 0x38a2, 0x4f3: 0x3a31, 0x4f4: 0x389b, 0x4f5: 0x3a2a,
+	0x4f6: 0x38c5, 0x4f7: 0x3a54, 0x4f8: 0x46b5, 0x4f9: 0x4746, 0x4fa: 0x3000, 0x4fb: 0x330c,
+	0x4fc: 0x2fec, 0x4fd: 0x32f8, 0x4fe: 0x38da, 0x4ff: 0x3a69,
 	// Block 0x14, offset 0x500
-	0x500: 0x4804, 0x501: 0x480a, 0x502: 0x491e, 0x503: 0x4936, 0x504: 0x4926, 0x505: 0x493e,
-	0x506: 0x492e, 0x507: 0x4946, 0x508: 0x47aa, 0x509: 0x47b0, 0x50a: 0x488e, 0x50b: 0x48a6,
-	0x50c: 0x4896, 0x50d: 0x48ae, 0x50e: 0x489e, 0x50f: 0x48b6, 0x510: 0x4816, 0x511: 0x481c,
-	0x512: 0x3db8, 0x513: 0x3dc8, 0x514: 0x3dc0, 0x515: 0x3dd0,
-	0x518: 0x47b6, 0x519: 0x47bc, 0x51a: 0x3ce8, 0x51b: 0x3cf8, 0x51c: 0x3cf0, 0x51d: 0x3d00,
-	0x520: 0x482e, 0x521: 0x4834, 0x522: 0x494e, 0x523: 0x4966,
-	0x524: 0x4956, 0x525: 0x496e, 0x526: 0x495e, 0x527: 0x4976, 0x528: 0x47c2, 0x529: 0x47c8,
-	0x52a: 0x48be, 0x52b: 0x48d6, 0x52c: 0x48c6, 0x52d: 0x48de, 0x52e: 0x48ce, 0x52f: 0x48e6,
-	0x530: 0x4846, 0x531: 0x484c, 0x532: 0x3e18, 0x533: 0x3e30, 0x534: 0x3e20, 0x535: 0x3e38,
-	0x536: 0x3e28, 0x537: 0x3e40, 0x538: 0x47ce, 0x539: 0x47d4, 0x53a: 0x3d18, 0x53b: 0x3d30,
-	0x53c: 0x3d20, 0x53d: 0x3d38, 0x53e: 0x3d28, 0x53f: 0x3d40,
+	0x500: 0x38d3, 0x501: 0x3a62, 0x502: 0x38e8, 0x503: 0x3a77, 0x504: 0x38e1, 0x505: 0x3a70,
+	0x506: 0x38fd, 0x507: 0x3a8c, 0x508: 0x3091, 0x509: 0x339d, 0x50a: 0x30a5, 0x50b: 0x33b1,
+	0x50c: 0x46e7, 0x50d: 0x4778, 0x50e: 0x3136, 0x50f: 0x3447, 0x510: 0x3920, 0x511: 0x3aaf,
+	0x512: 0x3919, 0x513: 0x3aa8, 0x514: 0x392e, 0x515: 0x3abd, 0x516: 0x3927, 0x517: 0x3ab6,
+	0x518: 0x3989, 0x519: 0x3b18, 0x51a: 0x396d, 0x51b: 0x3afc, 0x51c: 0x3966, 0x51d: 0x3af5,
+	0x51e: 0x397b, 0x51f: 0x3b0a, 0x520: 0x3974, 0x521: 0x3b03, 0x522: 0x3982, 0x523: 0x3b11,
+	0x524: 0x31e5, 0x525: 0x34fb, 0x526: 0x31c7, 0x527: 0x34dd, 0x528: 0x39e4, 0x529: 0x3b73,
+	0x52a: 0x39dd, 0x52b: 0x3b6c, 0x52c: 0x39f2, 0x52d: 0x3b81, 0x52e: 0x39eb, 0x52f: 0x3b7a,
+	0x530: 0x39f9, 0x531: 0x3b88, 0x532: 0x3230, 0x533: 0x354b, 0x534: 0x3258, 0x535: 0x3578,
+	0x536: 0x3253, 0x537: 0x356e, 0x538: 0x323f, 0x539: 0x355a,
 	// Block 0x15, offset 0x540
-	0x540: 0x4852, 0x541: 0x4858, 0x542: 0x3e48, 0x543: 0x3e58, 0x544: 0x3e50, 0x545: 0x3e60,
-	0x548: 0x47da, 0x549: 0x47e0, 0x54a: 0x3d48, 0x54b: 0x3d58,
-	0x54c: 0x3d50, 0x54d: 0x3d60, 0x550: 0x4864, 0x551: 0x486a,
-	0x552: 0x3e80, 0x553: 0x3e98, 0x554: 0x3e88, 0x555: 0x3ea0, 0x556: 0x3e90, 0x557: 0x3ea8,
-	0x559: 0x47e6, 0x55b: 0x3d68, 0x55d: 0x3d70,
-	0x55f: 0x3d78, 0x560: 0x487c, 0x561: 0x4882, 0x562: 0x497e, 0x563: 0x4996,
-	0x564: 0x4986, 0x565: 0x499e, 0x566: 0x498e, 0x567: 0x49a6, 0x568: 0x47ec, 0x569: 0x47f2,
-	0x56a: 0x48ee, 0x56b: 0x4906, 0x56c: 0x48f6, 0x56d: 0x490e, 0x56e: 0x48fe, 0x56f: 0x4916,
-	0x570: 0x47f8, 0x571: 0x431e, 0x572: 0x3691, 0x573: 0x4324, 0x574: 0x4822, 0x575: 0x432a,
-	0x576: 0x36a3, 0x577: 0x4330, 0x578: 0x36c1, 0x579: 0x4336, 0x57a: 0x36d9, 0x57b: 0x433c,
-	0x57c: 0x4870, 0x57d: 0x4342,
+	0x540: 0x4804, 0x541: 0x480a, 0x542: 0x491e, 0x543: 0x4936, 0x544: 0x4926, 0x545: 0x493e,
+	0x546: 0x492e, 0x547: 0x4946, 0x548: 0x47aa, 0x549: 0x47b0, 0x54a: 0x488e, 0x54b: 0x48a6,
+	0x54c: 0x4896, 0x54d: 0x48ae, 0x54e: 0x489e, 0x54f: 0x48b6, 0x550: 0x4816, 0x551: 0x481c,
+	0x552: 0x3db8, 0x553: 0x3dc8, 0x554: 0x3dc0, 0x555: 0x3dd0,
+	0x558: 0x47b6, 0x559: 0x47bc, 0x55a: 0x3ce8, 0x55b: 0x3cf8, 0x55c: 0x3cf0, 0x55d: 0x3d00,
+	0x560: 0x482e, 0x561: 0x4834, 0x562: 0x494e, 0x563: 0x4966,
+	0x564: 0x4956, 0x565: 0x496e, 0x566: 0x495e, 0x567: 0x4976, 0x568: 0x47c2, 0x569: 0x47c8,
+	0x56a: 0x48be, 0x56b: 0x48d6, 0x56c: 0x48c6, 0x56d: 0x48de, 0x56e: 0x48ce, 0x56f: 0x48e6,
+	0x570: 0x4846, 0x571: 0x484c, 0x572: 0x3e18, 0x573: 0x3e30, 0x574: 0x3e20, 0x575: 0x3e38,
+	0x576: 0x3e28, 0x577: 0x3e40, 0x578: 0x47ce, 0x579: 0x47d4, 0x57a: 0x3d18, 0x57b: 0x3d30,
+	0x57c: 0x3d20, 0x57d: 0x3d38, 0x57e: 0x3d28, 0x57f: 0x3d40,
 	// Block 0x16, offset 0x580
-	0x580: 0x3da0, 0x581: 0x3da8, 0x582: 0x4184, 0x583: 0x41a2, 0x584: 0x418e, 0x585: 0x41ac,
-	0x586: 0x4198, 0x587: 0x41b6, 0x588: 0x3cd8, 0x589: 0x3ce0, 0x58a: 0x40d0, 0x58b: 0x40ee,
-	0x58c: 0x40da, 0x58d: 0x40f8, 0x58e: 0x40e4, 0x58f: 0x4102, 0x590: 0x3de8, 0x591: 0x3df0,
-	0x592: 0x41c0, 0x593: 0x41de, 0x594: 0x41ca, 0x595: 0x41e8, 0x596: 0x41d4, 0x597: 0x41f2,
-	0x598: 0x3d08, 0x599: 0x3d10, 0x59a: 0x410c, 0x59b: 0x412a, 0x59c: 0x4116, 0x59d: 0x4134,
-	0x59e: 0x4120, 0x59f: 0x413e, 0x5a0: 0x3ec0, 0x5a1: 0x3ec8, 0x5a2: 0x41fc, 0x5a3: 0x421a,
-	0x5a4: 0x4206, 0x5a5: 0x4224, 0x5a6: 0x4210, 0x5a7: 0x422e, 0x5a8: 0x3d80, 0x5a9: 0x3d88,
-	0x5aa: 0x4148, 0x5ab: 0x4166, 0x5ac: 0x4152, 0x5ad: 0x4170, 0x5ae: 0x415c, 0x5af: 0x417a,
-	0x5b0: 0x3685, 0x5b1: 0x367f, 0x5b2: 0x3d90, 0x5b3: 0x368b, 0x5b4: 0x3d98,
-	0x5b6: 0x4810, 0x5b7: 0x3db0, 0x5b8: 0x35f5, 0x5b9: 0x35ef, 0x5ba: 0x35e3, 0x5bb: 0x42ee,
-	0x5bc: 0x35fb, 0x5bd: 0x8100, 0x5be: 0x01d3, 0x5bf: 0xa100,
+	0x580: 0x4852, 0x581: 0x4858, 0x582: 0x3e48, 0x583: 0x3e58, 0x584: 0x3e50, 0x585: 0x3e60,
+	0x588: 0x47da, 0x589: 0x47e0, 0x58a: 0x3d48, 0x58b: 0x3d58,
+	0x58c: 0x3d50, 0x58d: 0x3d60, 0x590: 0x4864, 0x591: 0x486a,
+	0x592: 0x3e80, 0x593: 0x3e98, 0x594: 0x3e88, 0x595: 0x3ea0, 0x596: 0x3e90, 0x597: 0x3ea8,
+	0x599: 0x47e6, 0x59b: 0x3d68, 0x59d: 0x3d70,
+	0x59f: 0x3d78, 0x5a0: 0x487c, 0x5a1: 0x4882, 0x5a2: 0x497e, 0x5a3: 0x4996,
+	0x5a4: 0x4986, 0x5a5: 0x499e, 0x5a6: 0x498e, 0x5a7: 0x49a6, 0x5a8: 0x47ec, 0x5a9: 0x47f2,
+	0x5aa: 0x48ee, 0x5ab: 0x4906, 0x5ac: 0x48f6, 0x5ad: 0x490e, 0x5ae: 0x48fe, 0x5af: 0x4916,
+	0x5b0: 0x47f8, 0x5b1: 0x431e, 0x5b2: 0x3691, 0x5b3: 0x4324, 0x5b4: 0x4822, 0x5b5: 0x432a,
+	0x5b6: 0x36a3, 0x5b7: 0x4330, 0x5b8: 0x36c1, 0x5b9: 0x4336, 0x5ba: 0x36d9, 0x5bb: 0x433c,
+	0x5bc: 0x4870, 0x5bd: 0x4342,
 	// Block 0x17, offset 0x5c0
-	0x5c0: 0x8100, 0x5c1: 0x35a7, 0x5c2: 0x3dd8, 0x5c3: 0x369d, 0x5c4: 0x3de0,
-	0x5c6: 0x483a, 0x5c7: 0x3df8, 0x5c8: 0x3601, 0x5c9: 0x42f4, 0x5ca: 0x360d, 0x5cb: 0x42fa,
-	0x5cc: 0x3619, 0x5cd: 0x3b8f, 0x5ce: 0x3b96, 0x5cf: 0x3b9d, 0x5d0: 0x36b5, 0x5d1: 0x36af,
-	0x5d2: 0x3e00, 0x5d3: 0x44e4, 0x5d6: 0x36bb, 0x5d7: 0x3e10,
-	0x5d8: 0x3631, 0x5d9: 0x362b, 0x5da: 0x361f, 0x5db: 0x4300, 0x5dd: 0x3ba4,
-	0x5de: 0x3bab, 0x5df: 0x3bb2, 0x5e0: 0x36eb, 0x5e1: 0x36e5, 0x5e2: 0x3e68, 0x5e3: 0x44ec,
-	0x5e4: 0x36cd, 0x5e5: 0x36d3, 0x5e6: 0x36f1, 0x5e7: 0x3e78, 0x5e8: 0x3661, 0x5e9: 0x365b,
-	0x5ea: 0x364f, 0x5eb: 0x430c, 0x5ec: 0x3649, 0x5ed: 0x359b, 0x5ee: 0x42e8, 0x5ef: 0x0081,
-	0x5f2: 0x3eb0, 0x5f3: 0x36f7, 0x5f4: 0x3eb8,
-	0x5f6: 0x4888, 0x5f7: 0x3ed0, 0x5f8: 0x363d, 0x5f9: 0x4306, 0x5fa: 0x366d, 0x5fb: 0x4318,
-	0x5fc: 0x3679, 0x5fd: 0x4256, 0x5fe: 0xa100,
+	0x5c0: 0x3da0, 0x5c1: 0x3da8, 0x5c2: 0x4184, 0x5c3: 0x41a2, 0x5c4: 0x418e, 0x5c5: 0x41ac,
+	0x5c6: 0x4198, 0x5c7: 0x41b6, 0x5c8: 0x3cd8, 0x5c9: 0x3ce0, 0x5ca: 0x40d0, 0x5cb: 0x40ee,
+	0x5cc: 0x40da, 0x5cd: 0x40f8, 0x5ce: 0x40e4, 0x5cf: 0x4102, 0x5d0: 0x3de8, 0x5d1: 0x3df0,
+	0x5d2: 0x41c0, 0x5d3: 0x41de, 0x5d4: 0x41ca, 0x5d5: 0x41e8, 0x5d6: 0x41d4, 0x5d7: 0x41f2,
+	0x5d8: 0x3d08, 0x5d9: 0x3d10, 0x5da: 0x410c, 0x5db: 0x412a, 0x5dc: 0x4116, 0x5dd: 0x4134,
+	0x5de: 0x4120, 0x5df: 0x413e, 0x5e0: 0x3ec0, 0x5e1: 0x3ec8, 0x5e2: 0x41fc, 0x5e3: 0x421a,
+	0x5e4: 0x4206, 0x5e5: 0x4224, 0x5e6: 0x4210, 0x5e7: 0x422e, 0x5e8: 0x3d80, 0x5e9: 0x3d88,
+	0x5ea: 0x4148, 0x5eb: 0x4166, 0x5ec: 0x4152, 0x5ed: 0x4170, 0x5ee: 0x415c, 0x5ef: 0x417a,
+	0x5f0: 0x3685, 0x5f1: 0x367f, 0x5f2: 0x3d90, 0x5f3: 0x368b, 0x5f4: 0x3d98,
+	0x5f6: 0x4810, 0x5f7: 0x3db0, 0x5f8: 0x35f5, 0x5f9: 0x35ef, 0x5fa: 0x35e3, 0x5fb: 0x42ee,
+	0x5fc: 0x35fb, 0x5fd: 0x8100, 0x5fe: 0x01d3, 0x5ff: 0xa100,
 	// Block 0x18, offset 0x600
-	0x601: 0x3c06, 0x603: 0xa000, 0x604: 0x3c0d, 0x605: 0xa000,
-	0x607: 0x3c14, 0x608: 0xa000, 0x609: 0x3c1b,
-	0x60d: 0xa000,
-	0x620: 0x2f65, 0x621: 0xa000, 0x622: 0x3c29,
-	0x624: 0xa000, 0x625: 0xa000,
-	0x62d: 0x3c22, 0x62e: 0x2f60, 0x62f: 0x2f6a,
-	0x630: 0x3c30, 0x631: 0x3c37, 0x632: 0xa000, 0x633: 0xa000, 0x634: 0x3c3e, 0x635: 0x3c45,
-	0x636: 0xa000, 0x637: 0xa000, 0x638: 0x3c4c, 0x639: 0x3c53, 0x63a: 0xa000, 0x63b: 0xa000,
-	0x63c: 0xa000, 0x63d: 0xa000,
+	0x600: 0x8100, 0x601: 0x35a7, 0x602: 0x3dd8, 0x603: 0x369d, 0x604: 0x3de0,
+	0x606: 0x483a, 0x607: 0x3df8, 0x608: 0x3601, 0x609: 0x42f4, 0x60a: 0x360d, 0x60b: 0x42fa,
+	0x60c: 0x3619, 0x60d: 0x3b8f, 0x60e: 0x3b96, 0x60f: 0x3b9d, 0x610: 0x36b5, 0x611: 0x36af,
+	0x612: 0x3e00, 0x613: 0x44e4, 0x616: 0x36bb, 0x617: 0x3e10,
+	0x618: 0x3631, 0x619: 0x362b, 0x61a: 0x361f, 0x61b: 0x4300, 0x61d: 0x3ba4,
+	0x61e: 0x3bab, 0x61f: 0x3bb2, 0x620: 0x36eb, 0x621: 0x36e5, 0x622: 0x3e68, 0x623: 0x44ec,
+	0x624: 0x36cd, 0x625: 0x36d3, 0x626: 0x36f1, 0x627: 0x3e78, 0x628: 0x3661, 0x629: 0x365b,
+	0x62a: 0x364f, 0x62b: 0x430c, 0x62c: 0x3649, 0x62d: 0x359b, 0x62e: 0x42e8, 0x62f: 0x0081,
+	0x632: 0x3eb0, 0x633: 0x36f7, 0x634: 0x3eb8,
+	0x636: 0x4888, 0x637: 0x3ed0, 0x638: 0x363d, 0x639: 0x4306, 0x63a: 0x366d, 0x63b: 0x4318,
+	0x63c: 0x3679, 0x63d: 0x4256, 0x63e: 0xa100,
 	// Block 0x19, offset 0x640
-	0x640: 0x3c5a, 0x641: 0x3c61, 0x642: 0xa000, 0x643: 0xa000, 0x644: 0x3c76, 0x645: 0x3c7d,
-	0x646: 0xa000, 0x647: 0xa000, 0x648: 0x3c84, 0x649: 0x3c8b,
-	0x651: 0xa000,
-	0x652: 0xa000,
-	0x662: 0xa000,
-	0x668: 0xa000, 0x669: 0xa000,
-	0x66b: 0xa000, 0x66c: 0x3ca0, 0x66d: 0x3ca7, 0x66e: 0x3cae, 0x66f: 0x3cb5,
-	0x672: 0xa000, 0x673: 0xa000, 0x674: 0xa000, 0x675: 0xa000,
+	0x641: 0x3c06, 0x643: 0xa000, 0x644: 0x3c0d, 0x645: 0xa000,
+	0x647: 0x3c14, 0x648: 0xa000, 0x649: 0x3c1b,
+	0x64d: 0xa000,
+	0x660: 0x2f65, 0x661: 0xa000, 0x662: 0x3c29,
+	0x664: 0xa000, 0x665: 0xa000,
+	0x66d: 0x3c22, 0x66e: 0x2f60, 0x66f: 0x2f6a,
+	0x670: 0x3c30, 0x671: 0x3c37, 0x672: 0xa000, 0x673: 0xa000, 0x674: 0x3c3e, 0x675: 0x3c45,
+	0x676: 0xa000, 0x677: 0xa000, 0x678: 0x3c4c, 0x679: 0x3c53, 0x67a: 0xa000, 0x67b: 0xa000,
+	0x67c: 0xa000, 0x67d: 0xa000,
 	// Block 0x1a, offset 0x680
-	0x686: 0xa000, 0x68b: 0xa000,
-	0x68c: 0x3f08, 0x68d: 0xa000, 0x68e: 0x3f10, 0x68f: 0xa000, 0x690: 0x3f18, 0x691: 0xa000,
-	0x692: 0x3f20, 0x693: 0xa000, 0x694: 0x3f28, 0x695: 0xa000, 0x696: 0x3f30, 0x697: 0xa000,
-	0x698: 0x3f38, 0x699: 0xa000, 0x69a: 0x3f40, 0x69b: 0xa000, 0x69c: 0x3f48, 0x69d: 0xa000,
-	0x69e: 0x3f50, 0x69f: 0xa000, 0x6a0: 0x3f58, 0x6a1: 0xa000, 0x6a2: 0x3f60,
-	0x6a4: 0xa000, 0x6a5: 0x3f68, 0x6a6: 0xa000, 0x6a7: 0x3f70, 0x6a8: 0xa000, 0x6a9: 0x3f78,
-	0x6af: 0xa000,
-	0x6b0: 0x3f80, 0x6b1: 0x3f88, 0x6b2: 0xa000, 0x6b3: 0x3f90, 0x6b4: 0x3f98, 0x6b5: 0xa000,
-	0x6b6: 0x3fa0, 0x6b7: 0x3fa8, 0x6b8: 0xa000, 0x6b9: 0x3fb0, 0x6ba: 0x3fb8, 0x6bb: 0xa000,
-	0x6bc: 0x3fc0, 0x6bd: 0x3fc8,
+	0x680: 0x3c5a, 0x681: 0x3c61, 0x682: 0xa000, 0x683: 0xa000, 0x684: 0x3c76, 0x685: 0x3c7d,
+	0x686: 0xa000, 0x687: 0xa000, 0x688: 0x3c84, 0x689: 0x3c8b,
+	0x691: 0xa000,
+	0x692: 0xa000,
+	0x6a2: 0xa000,
+	0x6a8: 0xa000, 0x6a9: 0xa000,
+	0x6ab: 0xa000, 0x6ac: 0x3ca0, 0x6ad: 0x3ca7, 0x6ae: 0x3cae, 0x6af: 0x3cb5,
+	0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0xa000, 0x6b5: 0xa000,
 	// Block 0x1b, offset 0x6c0
-	0x6d4: 0x3f00,
-	0x6d9: 0x9903, 0x6da: 0x9903, 0x6db: 0x8100, 0x6dc: 0x8100, 0x6dd: 0xa000,
-	0x6de: 0x3fd0,
-	0x6e6: 0xa000,
-	0x6eb: 0xa000, 0x6ec: 0x3fe0, 0x6ed: 0xa000, 0x6ee: 0x3fe8, 0x6ef: 0xa000,
-	0x6f0: 0x3ff0, 0x6f1: 0xa000, 0x6f2: 0x3ff8, 0x6f3: 0xa000, 0x6f4: 0x4000, 0x6f5: 0xa000,
-	0x6f6: 0x4008, 0x6f7: 0xa000, 0x6f8: 0x4010, 0x6f9: 0xa000, 0x6fa: 0x4018, 0x6fb: 0xa000,
-	0x6fc: 0x4020, 0x6fd: 0xa000, 0x6fe: 0x4028, 0x6ff: 0xa000,
+	0x6c6: 0xa000, 0x6cb: 0xa000,
+	0x6cc: 0x3f08, 0x6cd: 0xa000, 0x6ce: 0x3f10, 0x6cf: 0xa000, 0x6d0: 0x3f18, 0x6d1: 0xa000,
+	0x6d2: 0x3f20, 0x6d3: 0xa000, 0x6d4: 0x3f28, 0x6d5: 0xa000, 0x6d6: 0x3f30, 0x6d7: 0xa000,
+	0x6d8: 0x3f38, 0x6d9: 0xa000, 0x6da: 0x3f40, 0x6db: 0xa000, 0x6dc: 0x3f48, 0x6dd: 0xa000,
+	0x6de: 0x3f50, 0x6df: 0xa000, 0x6e0: 0x3f58, 0x6e1: 0xa000, 0x6e2: 0x3f60,
+	0x6e4: 0xa000, 0x6e5: 0x3f68, 0x6e6: 0xa000, 0x6e7: 0x3f70, 0x6e8: 0xa000, 0x6e9: 0x3f78,
+	0x6ef: 0xa000,
+	0x6f0: 0x3f80, 0x6f1: 0x3f88, 0x6f2: 0xa000, 0x6f3: 0x3f90, 0x6f4: 0x3f98, 0x6f5: 0xa000,
+	0x6f6: 0x3fa0, 0x6f7: 0x3fa8, 0x6f8: 0xa000, 0x6f9: 0x3fb0, 0x6fa: 0x3fb8, 0x6fb: 0xa000,
+	0x6fc: 0x3fc0, 0x6fd: 0x3fc8,
 	// Block 0x1c, offset 0x700
-	0x700: 0x4030, 0x701: 0xa000, 0x702: 0x4038, 0x704: 0xa000, 0x705: 0x4040,
-	0x706: 0xa000, 0x707: 0x4048, 0x708: 0xa000, 0x709: 0x4050,
-	0x70f: 0xa000, 0x710: 0x4058, 0x711: 0x4060,
-	0x712: 0xa000, 0x713: 0x4068, 0x714: 0x4070, 0x715: 0xa000, 0x716: 0x4078, 0x717: 0x4080,
-	0x718: 0xa000, 0x719: 0x4088, 0x71a: 0x4090, 0x71b: 0xa000, 0x71c: 0x4098, 0x71d: 0x40a0,
-	0x72f: 0xa000,
-	0x730: 0xa000, 0x731: 0xa000, 0x732: 0xa000, 0x734: 0x3fd8,
-	0x737: 0x40a8, 0x738: 0x40b0, 0x739: 0x40b8, 0x73a: 0x40c0,
-	0x73d: 0xa000, 0x73e: 0x40c8,
+	0x714: 0x3f00,
+	0x719: 0x9903, 0x71a: 0x9903, 0x71b: 0x8100, 0x71c: 0x8100, 0x71d: 0xa000,
+	0x71e: 0x3fd0,
+	0x726: 0xa000,
+	0x72b: 0xa000, 0x72c: 0x3fe0, 0x72d: 0xa000, 0x72e: 0x3fe8, 0x72f: 0xa000,
+	0x730: 0x3ff0, 0x731: 0xa000, 0x732: 0x3ff8, 0x733: 0xa000, 0x734: 0x4000, 0x735: 0xa000,
+	0x736: 0x4008, 0x737: 0xa000, 0x738: 0x4010, 0x739: 0xa000, 0x73a: 0x4018, 0x73b: 0xa000,
+	0x73c: 0x4020, 0x73d: 0xa000, 0x73e: 0x4028, 0x73f: 0xa000,
 	// Block 0x1d, offset 0x740
-	0x740: 0x1377, 0x741: 0x0cfb, 0x742: 0x13d3, 0x743: 0x139f, 0x744: 0x0e57, 0x745: 0x06eb,
-	0x746: 0x08df, 0x747: 0x162b, 0x748: 0x162b, 0x749: 0x0a0b, 0x74a: 0x145f, 0x74b: 0x0943,
-	0x74c: 0x0a07, 0x74d: 0x0bef, 0x74e: 0x0fcf, 0x74f: 0x115f, 0x750: 0x1297, 0x751: 0x12d3,
-	0x752: 0x1307, 0x753: 0x141b, 0x754: 0x0d73, 0x755: 0x0dff, 0x756: 0x0eab, 0x757: 0x0f43,
-	0x758: 0x125f, 0x759: 0x1447, 0x75a: 0x1573, 0x75b: 0x070f, 0x75c: 0x08b3, 0x75d: 0x0d87,
-	0x75e: 0x0ecf, 0x75f: 0x1293, 0x760: 0x15c3, 0x761: 0x0ab3, 0x762: 0x0e77, 0x763: 0x1283,
-	0x764: 0x1317, 0x765: 0x0c23, 0x766: 0x11bb, 0x767: 0x12df, 0x768: 0x0b1f, 0x769: 0x0d0f,
-	0x76a: 0x0e17, 0x76b: 0x0f1b, 0x76c: 0x1427, 0x76d: 0x074f, 0x76e: 0x07e7, 0x76f: 0x0853,
-	0x770: 0x0c8b, 0x771: 0x0d7f, 0x772: 0x0ecb, 0x773: 0x0fef, 0x774: 0x1177, 0x775: 0x128b,
-	0x776: 0x12a3, 0x777: 0x13c7, 0x778: 0x14ef, 0x779: 0x15a3, 0x77a: 0x15bf, 0x77b: 0x102b,
-	0x77c: 0x106b, 0x77d: 0x1123, 0x77e: 0x1243, 0x77f: 0x147b,
+	0x740: 0x4030, 0x741: 0xa000, 0x742: 0x4038, 0x744: 0xa000, 0x745: 0x4040,
+	0x746: 0xa000, 0x747: 0x4048, 0x748: 0xa000, 0x749: 0x4050,
+	0x74f: 0xa000, 0x750: 0x4058, 0x751: 0x4060,
+	0x752: 0xa000, 0x753: 0x4068, 0x754: 0x4070, 0x755: 0xa000, 0x756: 0x4078, 0x757: 0x4080,
+	0x758: 0xa000, 0x759: 0x4088, 0x75a: 0x4090, 0x75b: 0xa000, 0x75c: 0x4098, 0x75d: 0x40a0,
+	0x76f: 0xa000,
+	0x770: 0xa000, 0x771: 0xa000, 0x772: 0xa000, 0x774: 0x3fd8,
+	0x777: 0x40a8, 0x778: 0x40b0, 0x779: 0x40b8, 0x77a: 0x40c0,
+	0x77d: 0xa000, 0x77e: 0x40c8,
 	// Block 0x1e, offset 0x780
-	0x780: 0x15cb, 0x781: 0x134b, 0x782: 0x09c7, 0x783: 0x0b3b, 0x784: 0x10db, 0x785: 0x119b,
-	0x786: 0x0eff, 0x787: 0x1033, 0x788: 0x1397, 0x789: 0x14e7, 0x78a: 0x09c3, 0x78b: 0x0a8f,
-	0x78c: 0x0d77, 0x78d: 0x0e2b, 0x78e: 0x0e5f, 0x78f: 0x1113, 0x790: 0x113b, 0x791: 0x14a7,
-	0x792: 0x084f, 0x793: 0x11a7, 0x794: 0x07f3, 0x795: 0x07ef, 0x796: 0x1097, 0x797: 0x1127,
-	0x798: 0x125b, 0x799: 0x14af, 0x79a: 0x1367, 0x79b: 0x0c27, 0x79c: 0x0d73, 0x79d: 0x1357,
-	0x79e: 0x06f7, 0x79f: 0x0a63, 0x7a0: 0x0b93, 0x7a1: 0x0f2f, 0x7a2: 0x0faf, 0x7a3: 0x0873,
-	0x7a4: 0x103b, 0x7a5: 0x075f, 0x7a6: 0x0b77, 0x7a7: 0x06d7, 0x7a8: 0x0deb, 0x7a9: 0x0ca3,
-	0x7aa: 0x110f, 0x7ab: 0x08c7, 0x7ac: 0x09b3, 0x7ad: 0x0ffb, 0x7ae: 0x1263, 0x7af: 0x133b,
-	0x7b0: 0x0db7, 0x7b1: 0x13f7, 0x7b2: 0x0de3, 0x7b3: 0x0c37, 0x7b4: 0x121b, 0x7b5: 0x0c57,
-	0x7b6: 0x0fab, 0x7b7: 0x072b, 0x7b8: 0x07a7, 0x7b9: 0x07eb, 0x7ba: 0x0d53, 0x7bb: 0x10fb,
-	0x7bc: 0x11f3, 0x7bd: 0x1347, 0x7be: 0x145b, 0x7bf: 0x085b,
+	0x780: 0x1377, 0x781: 0x0cfb, 0x782: 0x13d3, 0x783: 0x139f, 0x784: 0x0e57, 0x785: 0x06eb,
+	0x786: 0x08df, 0x787: 0x162b, 0x788: 0x162b, 0x789: 0x0a0b, 0x78a: 0x145f, 0x78b: 0x0943,
+	0x78c: 0x0a07, 0x78d: 0x0bef, 0x78e: 0x0fcf, 0x78f: 0x115f, 0x790: 0x1297, 0x791: 0x12d3,
+	0x792: 0x1307, 0x793: 0x141b, 0x794: 0x0d73, 0x795: 0x0dff, 0x796: 0x0eab, 0x797: 0x0f43,
+	0x798: 0x125f, 0x799: 0x1447, 0x79a: 0x1573, 0x79b: 0x070f, 0x79c: 0x08b3, 0x79d: 0x0d87,
+	0x79e: 0x0ecf, 0x79f: 0x1293, 0x7a0: 0x15c3, 0x7a1: 0x0ab3, 0x7a2: 0x0e77, 0x7a3: 0x1283,
+	0x7a4: 0x1317, 0x7a5: 0x0c23, 0x7a6: 0x11bb, 0x7a7: 0x12df, 0x7a8: 0x0b1f, 0x7a9: 0x0d0f,
+	0x7aa: 0x0e17, 0x7ab: 0x0f1b, 0x7ac: 0x1427, 0x7ad: 0x074f, 0x7ae: 0x07e7, 0x7af: 0x0853,
+	0x7b0: 0x0c8b, 0x7b1: 0x0d7f, 0x7b2: 0x0ecb, 0x7b3: 0x0fef, 0x7b4: 0x1177, 0x7b5: 0x128b,
+	0x7b6: 0x12a3, 0x7b7: 0x13c7, 0x7b8: 0x14ef, 0x7b9: 0x15a3, 0x7ba: 0x15bf, 0x7bb: 0x102b,
+	0x7bc: 0x106b, 0x7bd: 0x1123, 0x7be: 0x1243, 0x7bf: 0x147b,
 	// Block 0x1f, offset 0x7c0
-	0x7c0: 0x090f, 0x7c1: 0x0a17, 0x7c2: 0x0b2f, 0x7c3: 0x0cbf, 0x7c4: 0x0e7b, 0x7c5: 0x103f,
-	0x7c6: 0x1497, 0x7c7: 0x157b, 0x7c8: 0x15cf, 0x7c9: 0x15e7, 0x7ca: 0x0837, 0x7cb: 0x0cf3,
-	0x7cc: 0x0da3, 0x7cd: 0x13eb, 0x7ce: 0x0afb, 0x7cf: 0x0bd7, 0x7d0: 0x0bf3, 0x7d1: 0x0c83,
-	0x7d2: 0x0e6b, 0x7d3: 0x0eb7, 0x7d4: 0x0f67, 0x7d5: 0x108b, 0x7d6: 0x112f, 0x7d7: 0x1193,
-	0x7d8: 0x13db, 0x7d9: 0x126b, 0x7da: 0x1403, 0x7db: 0x147f, 0x7dc: 0x080f, 0x7dd: 0x083b,
-	0x7de: 0x0923, 0x7df: 0x0ea7, 0x7e0: 0x12f3, 0x7e1: 0x133b, 0x7e2: 0x0b1b, 0x7e3: 0x0b8b,
-	0x7e4: 0x0c4f, 0x7e5: 0x0daf, 0x7e6: 0x10d7, 0x7e7: 0x0f23, 0x7e8: 0x073b, 0x7e9: 0x097f,
-	0x7ea: 0x0a63, 0x7eb: 0x0ac7, 0x7ec: 0x0b97, 0x7ed: 0x0f3f, 0x7ee: 0x0f5b, 0x7ef: 0x116b,
-	0x7f0: 0x118b, 0x7f1: 0x1463, 0x7f2: 0x14e3, 0x7f3: 0x14f3, 0x7f4: 0x152f, 0x7f5: 0x0753,
-	0x7f6: 0x107f, 0x7f7: 0x144f, 0x7f8: 0x14cb, 0x7f9: 0x0baf, 0x7fa: 0x0717, 0x7fb: 0x0777,
-	0x7fc: 0x0a67, 0x7fd: 0x0a87, 0x7fe: 0x0caf, 0x7ff: 0x0d73,
+	0x7c0: 0x15cb, 0x7c1: 0x134b, 0x7c2: 0x09c7, 0x7c3: 0x0b3b, 0x7c4: 0x10db, 0x7c5: 0x119b,
+	0x7c6: 0x0eff, 0x7c7: 0x1033, 0x7c8: 0x1397, 0x7c9: 0x14e7, 0x7ca: 0x09c3, 0x7cb: 0x0a8f,
+	0x7cc: 0x0d77, 0x7cd: 0x0e2b, 0x7ce: 0x0e5f, 0x7cf: 0x1113, 0x7d0: 0x113b, 0x7d1: 0x14a7,
+	0x7d2: 0x084f, 0x7d3: 0x11a7, 0x7d4: 0x07f3, 0x7d5: 0x07ef, 0x7d6: 0x1097, 0x7d7: 0x1127,
+	0x7d8: 0x125b, 0x7d9: 0x14af, 0x7da: 0x1367, 0x7db: 0x0c27, 0x7dc: 0x0d73, 0x7dd: 0x1357,
+	0x7de: 0x06f7, 0x7df: 0x0a63, 0x7e0: 0x0b93, 0x7e1: 0x0f2f, 0x7e2: 0x0faf, 0x7e3: 0x0873,
+	0x7e4: 0x103b, 0x7e5: 0x075f, 0x7e6: 0x0b77, 0x7e7: 0x06d7, 0x7e8: 0x0deb, 0x7e9: 0x0ca3,
+	0x7ea: 0x110f, 0x7eb: 0x08c7, 0x7ec: 0x09b3, 0x7ed: 0x0ffb, 0x7ee: 0x1263, 0x7ef: 0x133b,
+	0x7f0: 0x0db7, 0x7f1: 0x13f7, 0x7f2: 0x0de3, 0x7f3: 0x0c37, 0x7f4: 0x121b, 0x7f5: 0x0c57,
+	0x7f6: 0x0fab, 0x7f7: 0x072b, 0x7f8: 0x07a7, 0x7f9: 0x07eb, 0x7fa: 0x0d53, 0x7fb: 0x10fb,
+	0x7fc: 0x11f3, 0x7fd: 0x1347, 0x7fe: 0x145b, 0x7ff: 0x085b,
 	// Block 0x20, offset 0x800
-	0x800: 0x0ec3, 0x801: 0x0fcb, 0x802: 0x1277, 0x803: 0x1417, 0x804: 0x1623, 0x805: 0x0ce3,
-	0x806: 0x14a3, 0x807: 0x0833, 0x808: 0x0d2f, 0x809: 0x0d3b, 0x80a: 0x0e0f, 0x80b: 0x0e47,
-	0x80c: 0x0f4b, 0x80d: 0x0fa7, 0x80e: 0x1027, 0x80f: 0x110b, 0x810: 0x153b, 0x811: 0x07af,
-	0x812: 0x0c03, 0x813: 0x14b3, 0x814: 0x0767, 0x815: 0x0aab, 0x816: 0x0e2f, 0x817: 0x13df,
-	0x818: 0x0b67, 0x819: 0x0bb7, 0x81a: 0x0d43, 0x81b: 0x0f2f, 0x81c: 0x14bb, 0x81d: 0x0817,
-	0x81e: 0x08ff, 0x81f: 0x0a97, 0x820: 0x0cd3, 0x821: 0x0d1f, 0x822: 0x0d5f, 0x823: 0x0df3,
-	0x824: 0x0f47, 0x825: 0x0fbb, 0x826: 0x1157, 0x827: 0x12f7, 0x828: 0x1303, 0x829: 0x1457,
-	0x82a: 0x14d7, 0x82b: 0x0883, 0x82c: 0x0e4b, 0x82d: 0x0903, 0x82e: 0x0ec7, 0x82f: 0x0f6b,
-	0x830: 0x1287, 0x831: 0x14bf, 0x832: 0x15ab, 0x833: 0x15d3, 0x834: 0x0d37, 0x835: 0x0e27,
-	0x836: 0x11c3, 0x837: 0x10b7, 0x838: 0x10c3, 0x839: 0x10e7, 0x83a: 0x0f17, 0x83b: 0x0e9f,
-	0x83c: 0x1363, 0x83d: 0x0733, 0x83e: 0x122b, 0x83f: 0x081b,
+	0x800: 0x090f, 0x801: 0x0a17, 0x802: 0x0b2f, 0x803: 0x0cbf, 0x804: 0x0e7b, 0x805: 0x103f,
+	0x806: 0x1497, 0x807: 0x157b, 0x808: 0x15cf, 0x809: 0x15e7, 0x80a: 0x0837, 0x80b: 0x0cf3,
+	0x80c: 0x0da3, 0x80d: 0x13eb, 0x80e: 0x0afb, 0x80f: 0x0bd7, 0x810: 0x0bf3, 0x811: 0x0c83,
+	0x812: 0x0e6b, 0x813: 0x0eb7, 0x814: 0x0f67, 0x815: 0x108b, 0x816: 0x112f, 0x817: 0x1193,
+	0x818: 0x13db, 0x819: 0x126b, 0x81a: 0x1403, 0x81b: 0x147f, 0x81c: 0x080f, 0x81d: 0x083b,
+	0x81e: 0x0923, 0x81f: 0x0ea7, 0x820: 0x12f3, 0x821: 0x133b, 0x822: 0x0b1b, 0x823: 0x0b8b,
+	0x824: 0x0c4f, 0x825: 0x0daf, 0x826: 0x10d7, 0x827: 0x0f23, 0x828: 0x073b, 0x829: 0x097f,
+	0x82a: 0x0a63, 0x82b: 0x0ac7, 0x82c: 0x0b97, 0x82d: 0x0f3f, 0x82e: 0x0f5b, 0x82f: 0x116b,
+	0x830: 0x118b, 0x831: 0x1463, 0x832: 0x14e3, 0x833: 0x14f3, 0x834: 0x152f, 0x835: 0x0753,
+	0x836: 0x107f, 0x837: 0x144f, 0x838: 0x14cb, 0x839: 0x0baf, 0x83a: 0x0717, 0x83b: 0x0777,
+	0x83c: 0x0a67, 0x83d: 0x0a87, 0x83e: 0x0caf, 0x83f: 0x0d73,
 	// Block 0x21, offset 0x840
-	0x840: 0x080b, 0x841: 0x0b0b, 0x842: 0x0c2b, 0x843: 0x10f3, 0x844: 0x0a53, 0x845: 0x0e03,
-	0x846: 0x0cef, 0x847: 0x13e7, 0x848: 0x12e7, 0x849: 0x14ab, 0x84a: 0x1323, 0x84b: 0x0b27,
-	0x84c: 0x0787, 0x84d: 0x095b, 0x850: 0x09af,
-	0x852: 0x0cdf, 0x855: 0x07f7, 0x856: 0x0f1f, 0x857: 0x0fe3,
-	0x858: 0x1047, 0x859: 0x1063, 0x85a: 0x1067, 0x85b: 0x107b, 0x85c: 0x14fb, 0x85d: 0x10eb,
-	0x85e: 0x116f, 0x860: 0x128f, 0x862: 0x1353,
-	0x865: 0x1407, 0x866: 0x1433,
-	0x86a: 0x154f, 0x86b: 0x1553, 0x86c: 0x1557, 0x86d: 0x15bb, 0x86e: 0x142b, 0x86f: 0x14c7,
-	0x870: 0x0757, 0x871: 0x077b, 0x872: 0x078f, 0x873: 0x084b, 0x874: 0x0857, 0x875: 0x0897,
-	0x876: 0x094b, 0x877: 0x0967, 0x878: 0x096f, 0x879: 0x09ab, 0x87a: 0x09b7, 0x87b: 0x0a93,
-	0x87c: 0x0a9b, 0x87d: 0x0ba3, 0x87e: 0x0bcb, 0x87f: 0x0bd3,
+	0x840: 0x0ec3, 0x841: 0x0fcb, 0x842: 0x1277, 0x843: 0x1417, 0x844: 0x1623, 0x845: 0x0ce3,
+	0x846: 0x14a3, 0x847: 0x0833, 0x848: 0x0d2f, 0x849: 0x0d3b, 0x84a: 0x0e0f, 0x84b: 0x0e47,
+	0x84c: 0x0f4b, 0x84d: 0x0fa7, 0x84e: 0x1027, 0x84f: 0x110b, 0x850: 0x153b, 0x851: 0x07af,
+	0x852: 0x0c03, 0x853: 0x14b3, 0x854: 0x0767, 0x855: 0x0aab, 0x856: 0x0e2f, 0x857: 0x13df,
+	0x858: 0x0b67, 0x859: 0x0bb7, 0x85a: 0x0d43, 0x85b: 0x0f2f, 0x85c: 0x14bb, 0x85d: 0x0817,
+	0x85e: 0x08ff, 0x85f: 0x0a97, 0x860: 0x0cd3, 0x861: 0x0d1f, 0x862: 0x0d5f, 0x863: 0x0df3,
+	0x864: 0x0f47, 0x865: 0x0fbb, 0x866: 0x1157, 0x867: 0x12f7, 0x868: 0x1303, 0x869: 0x1457,
+	0x86a: 0x14d7, 0x86b: 0x0883, 0x86c: 0x0e4b, 0x86d: 0x0903, 0x86e: 0x0ec7, 0x86f: 0x0f6b,
+	0x870: 0x1287, 0x871: 0x14bf, 0x872: 0x15ab, 0x873: 0x15d3, 0x874: 0x0d37, 0x875: 0x0e27,
+	0x876: 0x11c3, 0x877: 0x10b7, 0x878: 0x10c3, 0x879: 0x10e7, 0x87a: 0x0f17, 0x87b: 0x0e9f,
+	0x87c: 0x1363, 0x87d: 0x0733, 0x87e: 0x122b, 0x87f: 0x081b,
 	// Block 0x22, offset 0x880
-	0x880: 0x0beb, 0x881: 0x0c97, 0x882: 0x0cc7, 0x883: 0x0ce7, 0x884: 0x0d57, 0x885: 0x0e1b,
-	0x886: 0x0e37, 0x887: 0x0e67, 0x888: 0x0ebb, 0x889: 0x0edb, 0x88a: 0x0f4f, 0x88b: 0x102f,
-	0x88c: 0x104b, 0x88d: 0x1053, 0x88e: 0x104f, 0x88f: 0x1057, 0x890: 0x105b, 0x891: 0x105f,
-	0x892: 0x1073, 0x893: 0x1077, 0x894: 0x109b, 0x895: 0x10af, 0x896: 0x10cb, 0x897: 0x112f,
-	0x898: 0x1137, 0x899: 0x113f, 0x89a: 0x1153, 0x89b: 0x117b, 0x89c: 0x11cb, 0x89d: 0x11ff,
-	0x89e: 0x11ff, 0x89f: 0x1267, 0x8a0: 0x130f, 0x8a1: 0x1327, 0x8a2: 0x135b, 0x8a3: 0x135f,
-	0x8a4: 0x13a3, 0x8a5: 0x13a7, 0x8a6: 0x13ff, 0x8a7: 0x1407, 0x8a8: 0x14db, 0x8a9: 0x151f,
-	0x8aa: 0x1537, 0x8ab: 0x0b9b, 0x8ac: 0x171e, 0x8ad: 0x11e3,
-	0x8b0: 0x06df, 0x8b1: 0x07e3, 0x8b2: 0x07a3, 0x8b3: 0x074b, 0x8b4: 0x078b, 0x8b5: 0x07b7,
-	0x8b6: 0x0847, 0x8b7: 0x0863, 0x8b8: 0x094b, 0x8b9: 0x0937, 0x8ba: 0x0947, 0x8bb: 0x0963,
-	0x8bc: 0x09af, 0x8bd: 0x09bf, 0x8be: 0x0a03, 0x8bf: 0x0a0f,
+	0x880: 0x080b, 0x881: 0x0b0b, 0x882: 0x0c2b, 0x883: 0x10f3, 0x884: 0x0a53, 0x885: 0x0e03,
+	0x886: 0x0cef, 0x887: 0x13e7, 0x888: 0x12e7, 0x889: 0x14ab, 0x88a: 0x1323, 0x88b: 0x0b27,
+	0x88c: 0x0787, 0x88d: 0x095b, 0x890: 0x09af,
+	0x892: 0x0cdf, 0x895: 0x07f7, 0x896: 0x0f1f, 0x897: 0x0fe3,
+	0x898: 0x1047, 0x899: 0x1063, 0x89a: 0x1067, 0x89b: 0x107b, 0x89c: 0x14fb, 0x89d: 0x10eb,
+	0x89e: 0x116f, 0x8a0: 0x128f, 0x8a2: 0x1353,
+	0x8a5: 0x1407, 0x8a6: 0x1433,
+	0x8aa: 0x154f, 0x8ab: 0x1553, 0x8ac: 0x1557, 0x8ad: 0x15bb, 0x8ae: 0x142b, 0x8af: 0x14c7,
+	0x8b0: 0x0757, 0x8b1: 0x077b, 0x8b2: 0x078f, 0x8b3: 0x084b, 0x8b4: 0x0857, 0x8b5: 0x0897,
+	0x8b6: 0x094b, 0x8b7: 0x0967, 0x8b8: 0x096f, 0x8b9: 0x09ab, 0x8ba: 0x09b7, 0x8bb: 0x0a93,
+	0x8bc: 0x0a9b, 0x8bd: 0x0ba3, 0x8be: 0x0bcb, 0x8bf: 0x0bd3,
 	// Block 0x23, offset 0x8c0
-	0x8c0: 0x0a2b, 0x8c1: 0x0a3b, 0x8c2: 0x0b23, 0x8c3: 0x0b2b, 0x8c4: 0x0b5b, 0x8c5: 0x0b7b,
-	0x8c6: 0x0bab, 0x8c7: 0x0bc3, 0x8c8: 0x0bb3, 0x8c9: 0x0bd3, 0x8ca: 0x0bc7, 0x8cb: 0x0beb,
-	0x8cc: 0x0c07, 0x8cd: 0x0c5f, 0x8ce: 0x0c6b, 0x8cf: 0x0c73, 0x8d0: 0x0c9b, 0x8d1: 0x0cdf,
-	0x8d2: 0x0d0f, 0x8d3: 0x0d13, 0x8d4: 0x0d27, 0x8d5: 0x0da7, 0x8d6: 0x0db7, 0x8d7: 0x0e0f,
-	0x8d8: 0x0e5b, 0x8d9: 0x0e53, 0x8da: 0x0e67, 0x8db: 0x0e83, 0x8dc: 0x0ebb, 0x8dd: 0x1013,
-	0x8de: 0x0edf, 0x8df: 0x0f13, 0x8e0: 0x0f1f, 0x8e1: 0x0f5f, 0x8e2: 0x0f7b, 0x8e3: 0x0f9f,
-	0x8e4: 0x0fc3, 0x8e5: 0x0fc7, 0x8e6: 0x0fe3, 0x8e7: 0x0fe7, 0x8e8: 0x0ff7, 0x8e9: 0x100b,
-	0x8ea: 0x1007, 0x8eb: 0x1037, 0x8ec: 0x10b3, 0x8ed: 0x10cb, 0x8ee: 0x10e3, 0x8ef: 0x111b,
-	0x8f0: 0x112f, 0x8f1: 0x114b, 0x8f2: 0x117b, 0x8f3: 0x122f, 0x8f4: 0x1257, 0x8f5: 0x12cb,
-	0x8f6: 0x1313, 0x8f7: 0x131f, 0x8f8: 0x1327, 0x8f9: 0x133f, 0x8fa: 0x1353, 0x8fb: 0x1343,
-	0x8fc: 0x135b, 0x8fd: 0x1357, 0x8fe: 0x134f, 0x8ff: 0x135f,
+	0x8c0: 0x0beb, 0x8c1: 0x0c97, 0x8c2: 0x0cc7, 0x8c3: 0x0ce7, 0x8c4: 0x0d57, 0x8c5: 0x0e1b,
+	0x8c6: 0x0e37, 0x8c7: 0x0e67, 0x8c8: 0x0ebb, 0x8c9: 0x0edb, 0x8ca: 0x0f4f, 0x8cb: 0x102f,
+	0x8cc: 0x104b, 0x8cd: 0x1053, 0x8ce: 0x104f, 0x8cf: 0x1057, 0x8d0: 0x105b, 0x8d1: 0x105f,
+	0x8d2: 0x1073, 0x8d3: 0x1077, 0x8d4: 0x109b, 0x8d5: 0x10af, 0x8d6: 0x10cb, 0x8d7: 0x112f,
+	0x8d8: 0x1137, 0x8d9: 0x113f, 0x8da: 0x1153, 0x8db: 0x117b, 0x8dc: 0x11cb, 0x8dd: 0x11ff,
+	0x8de: 0x11ff, 0x8df: 0x1267, 0x8e0: 0x130f, 0x8e1: 0x1327, 0x8e2: 0x135b, 0x8e3: 0x135f,
+	0x8e4: 0x13a3, 0x8e5: 0x13a7, 0x8e6: 0x13ff, 0x8e7: 0x1407, 0x8e8: 0x14db, 0x8e9: 0x151f,
+	0x8ea: 0x1537, 0x8eb: 0x0b9b, 0x8ec: 0x171e, 0x8ed: 0x11e3,
+	0x8f0: 0x06df, 0x8f1: 0x07e3, 0x8f2: 0x07a3, 0x8f3: 0x074b, 0x8f4: 0x078b, 0x8f5: 0x07b7,
+	0x8f6: 0x0847, 0x8f7: 0x0863, 0x8f8: 0x094b, 0x8f9: 0x0937, 0x8fa: 0x0947, 0x8fb: 0x0963,
+	0x8fc: 0x09af, 0x8fd: 0x09bf, 0x8fe: 0x0a03, 0x8ff: 0x0a0f,
 	// Block 0x24, offset 0x900
-	0x900: 0x136b, 0x901: 0x13a7, 0x902: 0x13e3, 0x903: 0x1413, 0x904: 0x144b, 0x905: 0x146b,
-	0x906: 0x14b7, 0x907: 0x14db, 0x908: 0x14fb, 0x909: 0x150f, 0x90a: 0x151f, 0x90b: 0x152b,
-	0x90c: 0x1537, 0x90d: 0x158b, 0x90e: 0x162b, 0x90f: 0x16b5, 0x910: 0x16b0, 0x911: 0x16e2,
-	0x912: 0x0607, 0x913: 0x062f, 0x914: 0x0633, 0x915: 0x1764, 0x916: 0x1791, 0x917: 0x1809,
-	0x918: 0x1617, 0x919: 0x1627,
+	0x900: 0x0a2b, 0x901: 0x0a3b, 0x902: 0x0b23, 0x903: 0x0b2b, 0x904: 0x0b5b, 0x905: 0x0b7b,
+	0x906: 0x0bab, 0x907: 0x0bc3, 0x908: 0x0bb3, 0x909: 0x0bd3, 0x90a: 0x0bc7, 0x90b: 0x0beb,
+	0x90c: 0x0c07, 0x90d: 0x0c5f, 0x90e: 0x0c6b, 0x90f: 0x0c73, 0x910: 0x0c9b, 0x911: 0x0cdf,
+	0x912: 0x0d0f, 0x913: 0x0d13, 0x914: 0x0d27, 0x915: 0x0da7, 0x916: 0x0db7, 0x917: 0x0e0f,
+	0x918: 0x0e5b, 0x919: 0x0e53, 0x91a: 0x0e67, 0x91b: 0x0e83, 0x91c: 0x0ebb, 0x91d: 0x1013,
+	0x91e: 0x0edf, 0x91f: 0x0f13, 0x920: 0x0f1f, 0x921: 0x0f5f, 0x922: 0x0f7b, 0x923: 0x0f9f,
+	0x924: 0x0fc3, 0x925: 0x0fc7, 0x926: 0x0fe3, 0x927: 0x0fe7, 0x928: 0x0ff7, 0x929: 0x100b,
+	0x92a: 0x1007, 0x92b: 0x1037, 0x92c: 0x10b3, 0x92d: 0x10cb, 0x92e: 0x10e3, 0x92f: 0x111b,
+	0x930: 0x112f, 0x931: 0x114b, 0x932: 0x117b, 0x933: 0x122f, 0x934: 0x1257, 0x935: 0x12cb,
+	0x936: 0x1313, 0x937: 0x131f, 0x938: 0x1327, 0x939: 0x133f, 0x93a: 0x1353, 0x93b: 0x1343,
+	0x93c: 0x135b, 0x93d: 0x1357, 0x93e: 0x134f, 0x93f: 0x135f,
 	// Block 0x25, offset 0x940
-	0x940: 0x06fb, 0x941: 0x06f3, 0x942: 0x0703, 0x943: 0x1647, 0x944: 0x0747, 0x945: 0x0757,
-	0x946: 0x075b, 0x947: 0x0763, 0x948: 0x076b, 0x949: 0x076f, 0x94a: 0x077b, 0x94b: 0x0773,
-	0x94c: 0x05b3, 0x94d: 0x165b, 0x94e: 0x078f, 0x94f: 0x0793, 0x950: 0x0797, 0x951: 0x07b3,
-	0x952: 0x164c, 0x953: 0x05b7, 0x954: 0x079f, 0x955: 0x07bf, 0x956: 0x1656, 0x957: 0x07cf,
-	0x958: 0x07d7, 0x959: 0x0737, 0x95a: 0x07df, 0x95b: 0x07e3, 0x95c: 0x1831, 0x95d: 0x07ff,
-	0x95e: 0x0807, 0x95f: 0x05bf, 0x960: 0x081f, 0x961: 0x0823, 0x962: 0x082b, 0x963: 0x082f,
-	0x964: 0x05c3, 0x965: 0x0847, 0x966: 0x084b, 0x967: 0x0857, 0x968: 0x0863, 0x969: 0x0867,
-	0x96a: 0x086b, 0x96b: 0x0873, 0x96c: 0x0893, 0x96d: 0x0897, 0x96e: 0x089f, 0x96f: 0x08af,
-	0x970: 0x08b7, 0x971: 0x08bb, 0x972: 0x08bb, 0x973: 0x08bb, 0x974: 0x166a, 0x975: 0x0e93,
-	0x976: 0x08cf, 0x977: 0x08d7, 0x978: 0x166f, 0x979: 0x08e3, 0x97a: 0x08eb, 0x97b: 0x08f3,
-	0x97c: 0x091b, 0x97d: 0x0907, 0x97e: 0x0913, 0x97f: 0x0917,
+	0x940: 0x136b, 0x941: 0x13a7, 0x942: 0x13e3, 0x943: 0x1413, 0x944: 0x144b, 0x945: 0x146b,
+	0x946: 0x14b7, 0x947: 0x14db, 0x948: 0x14fb, 0x949: 0x150f, 0x94a: 0x151f, 0x94b: 0x152b,
+	0x94c: 0x1537, 0x94d: 0x158b, 0x94e: 0x162b, 0x94f: 0x16b5, 0x950: 0x16b0, 0x951: 0x16e2,
+	0x952: 0x0607, 0x953: 0x062f, 0x954: 0x0633, 0x955: 0x1764, 0x956: 0x1791, 0x957: 0x1809,
+	0x958: 0x1617, 0x959: 0x1627,
 	// Block 0x26, offset 0x980
-	0x980: 0x091f, 0x981: 0x0927, 0x982: 0x092b, 0x983: 0x0933, 0x984: 0x093b, 0x985: 0x093f,
-	0x986: 0x093f, 0x987: 0x0947, 0x988: 0x094f, 0x989: 0x0953, 0x98a: 0x095f, 0x98b: 0x0983,
-	0x98c: 0x0967, 0x98d: 0x0987, 0x98e: 0x096b, 0x98f: 0x0973, 0x990: 0x080b, 0x991: 0x09cf,
-	0x992: 0x0997, 0x993: 0x099b, 0x994: 0x099f, 0x995: 0x0993, 0x996: 0x09a7, 0x997: 0x09a3,
-	0x998: 0x09bb, 0x999: 0x1674, 0x99a: 0x09d7, 0x99b: 0x09db, 0x99c: 0x09e3, 0x99d: 0x09ef,
-	0x99e: 0x09f7, 0x99f: 0x0a13, 0x9a0: 0x1679, 0x9a1: 0x167e, 0x9a2: 0x0a1f, 0x9a3: 0x0a23,
-	0x9a4: 0x0a27, 0x9a5: 0x0a1b, 0x9a6: 0x0a2f, 0x9a7: 0x05c7, 0x9a8: 0x05cb, 0x9a9: 0x0a37,
-	0x9aa: 0x0a3f, 0x9ab: 0x0a3f, 0x9ac: 0x1683, 0x9ad: 0x0a5b, 0x9ae: 0x0a5f, 0x9af: 0x0a63,
-	0x9b0: 0x0a6b, 0x9b1: 0x1688, 0x9b2: 0x0a73, 0x9b3: 0x0a77, 0x9b4: 0x0b4f, 0x9b5: 0x0a7f,
-	0x9b6: 0x05cf, 0x9b7: 0x0a8b, 0x9b8: 0x0a9b, 0x9b9: 0x0aa7, 0x9ba: 0x0aa3, 0x9bb: 0x1692,
-	0x9bc: 0x0aaf, 0x9bd: 0x1697, 0x9be: 0x0abb, 0x9bf: 0x0ab7,
+	0x980: 0x06fb, 0x981: 0x06f3, 0x982: 0x0703, 0x983: 0x1647, 0x984: 0x0747, 0x985: 0x0757,
+	0x986: 0x075b, 0x987: 0x0763, 0x988: 0x076b, 0x989: 0x076f, 0x98a: 0x077b, 0x98b: 0x0773,
+	0x98c: 0x05b3, 0x98d: 0x165b, 0x98e: 0x078f, 0x98f: 0x0793, 0x990: 0x0797, 0x991: 0x07b3,
+	0x992: 0x164c, 0x993: 0x05b7, 0x994: 0x079f, 0x995: 0x07bf, 0x996: 0x1656, 0x997: 0x07cf,
+	0x998: 0x07d7, 0x999: 0x0737, 0x99a: 0x07df, 0x99b: 0x07e3, 0x99c: 0x1831, 0x99d: 0x07ff,
+	0x99e: 0x0807, 0x99f: 0x05bf, 0x9a0: 0x081f, 0x9a1: 0x0823, 0x9a2: 0x082b, 0x9a3: 0x082f,
+	0x9a4: 0x05c3, 0x9a5: 0x0847, 0x9a6: 0x084b, 0x9a7: 0x0857, 0x9a8: 0x0863, 0x9a9: 0x0867,
+	0x9aa: 0x086b, 0x9ab: 0x0873, 0x9ac: 0x0893, 0x9ad: 0x0897, 0x9ae: 0x089f, 0x9af: 0x08af,
+	0x9b0: 0x08b7, 0x9b1: 0x08bb, 0x9b2: 0x08bb, 0x9b3: 0x08bb, 0x9b4: 0x166a, 0x9b5: 0x0e93,
+	0x9b6: 0x08cf, 0x9b7: 0x08d7, 0x9b8: 0x166f, 0x9b9: 0x08e3, 0x9ba: 0x08eb, 0x9bb: 0x08f3,
+	0x9bc: 0x091b, 0x9bd: 0x0907, 0x9be: 0x0913, 0x9bf: 0x0917,
 	// Block 0x27, offset 0x9c0
-	0x9c0: 0x0abf, 0x9c1: 0x0acf, 0x9c2: 0x0ad3, 0x9c3: 0x05d3, 0x9c4: 0x0ae3, 0x9c5: 0x0aeb,
-	0x9c6: 0x0aef, 0x9c7: 0x0af3, 0x9c8: 0x05d7, 0x9c9: 0x169c, 0x9ca: 0x05db, 0x9cb: 0x0b0f,
-	0x9cc: 0x0b13, 0x9cd: 0x0b17, 0x9ce: 0x0b1f, 0x9cf: 0x1863, 0x9d0: 0x0b37, 0x9d1: 0x16a6,
-	0x9d2: 0x16a6, 0x9d3: 0x11d7, 0x9d4: 0x0b47, 0x9d5: 0x0b47, 0x9d6: 0x05df, 0x9d7: 0x16c9,
-	0x9d8: 0x179b, 0x9d9: 0x0b57, 0x9da: 0x0b5f, 0x9db: 0x05e3, 0x9dc: 0x0b73, 0x9dd: 0x0b83,
-	0x9de: 0x0b87, 0x9df: 0x0b8f, 0x9e0: 0x0b9f, 0x9e1: 0x05eb, 0x9e2: 0x05e7, 0x9e3: 0x0ba3,
-	0x9e4: 0x16ab, 0x9e5: 0x0ba7, 0x9e6: 0x0bbb, 0x9e7: 0x0bbf, 0x9e8: 0x0bc3, 0x9e9: 0x0bbf,
-	0x9ea: 0x0bcf, 0x9eb: 0x0bd3, 0x9ec: 0x0be3, 0x9ed: 0x0bdb, 0x9ee: 0x0bdf, 0x9ef: 0x0be7,
-	0x9f0: 0x0beb, 0x9f1: 0x0bef, 0x9f2: 0x0bfb, 0x9f3: 0x0bff, 0x9f4: 0x0c17, 0x9f5: 0x0c1f,
-	0x9f6: 0x0c2f, 0x9f7: 0x0c43, 0x9f8: 0x16ba, 0x9f9: 0x0c3f, 0x9fa: 0x0c33, 0x9fb: 0x0c4b,
-	0x9fc: 0x0c53, 0x9fd: 0x0c67, 0x9fe: 0x16bf, 0x9ff: 0x0c6f,
+	0x9c0: 0x091f, 0x9c1: 0x0927, 0x9c2: 0x092b, 0x9c3: 0x0933, 0x9c4: 0x093b, 0x9c5: 0x093f,
+	0x9c6: 0x093f, 0x9c7: 0x0947, 0x9c8: 0x094f, 0x9c9: 0x0953, 0x9ca: 0x095f, 0x9cb: 0x0983,
+	0x9cc: 0x0967, 0x9cd: 0x0987, 0x9ce: 0x096b, 0x9cf: 0x0973, 0x9d0: 0x080b, 0x9d1: 0x09cf,
+	0x9d2: 0x0997, 0x9d3: 0x099b, 0x9d4: 0x099f, 0x9d5: 0x0993, 0x9d6: 0x09a7, 0x9d7: 0x09a3,
+	0x9d8: 0x09bb, 0x9d9: 0x1674, 0x9da: 0x09d7, 0x9db: 0x09db, 0x9dc: 0x09e3, 0x9dd: 0x09ef,
+	0x9de: 0x09f7, 0x9df: 0x0a13, 0x9e0: 0x1679, 0x9e1: 0x167e, 0x9e2: 0x0a1f, 0x9e3: 0x0a23,
+	0x9e4: 0x0a27, 0x9e5: 0x0a1b, 0x9e6: 0x0a2f, 0x9e7: 0x05c7, 0x9e8: 0x05cb, 0x9e9: 0x0a37,
+	0x9ea: 0x0a3f, 0x9eb: 0x0a3f, 0x9ec: 0x1683, 0x9ed: 0x0a5b, 0x9ee: 0x0a5f, 0x9ef: 0x0a63,
+	0x9f0: 0x0a6b, 0x9f1: 0x1688, 0x9f2: 0x0a73, 0x9f3: 0x0a77, 0x9f4: 0x0b4f, 0x9f5: 0x0a7f,
+	0x9f6: 0x05cf, 0x9f7: 0x0a8b, 0x9f8: 0x0a9b, 0x9f9: 0x0aa7, 0x9fa: 0x0aa3, 0x9fb: 0x1692,
+	0x9fc: 0x0aaf, 0x9fd: 0x1697, 0x9fe: 0x0abb, 0x9ff: 0x0ab7,
 	// Block 0x28, offset 0xa00
-	0xa00: 0x0c63, 0xa01: 0x0c5b, 0xa02: 0x05ef, 0xa03: 0x0c77, 0xa04: 0x0c7f, 0xa05: 0x0c87,
-	0xa06: 0x0c7b, 0xa07: 0x05f3, 0xa08: 0x0c97, 0xa09: 0x0c9f, 0xa0a: 0x16c4, 0xa0b: 0x0ccb,
-	0xa0c: 0x0cff, 0xa0d: 0x0cdb, 0xa0e: 0x05ff, 0xa0f: 0x0ce7, 0xa10: 0x05fb, 0xa11: 0x05f7,
-	0xa12: 0x07c3, 0xa13: 0x07c7, 0xa14: 0x0d03, 0xa15: 0x0ceb, 0xa16: 0x11ab, 0xa17: 0x0663,
-	0xa18: 0x0d0f, 0xa19: 0x0d13, 0xa1a: 0x0d17, 0xa1b: 0x0d2b, 0xa1c: 0x0d23, 0xa1d: 0x16dd,
-	0xa1e: 0x0603, 0xa1f: 0x0d3f, 0xa20: 0x0d33, 0xa21: 0x0d4f, 0xa22: 0x0d57, 0xa23: 0x16e7,
-	0xa24: 0x0d5b, 0xa25: 0x0d47, 0xa26: 0x0d63, 0xa27: 0x0607, 0xa28: 0x0d67, 0xa29: 0x0d6b,
-	0xa2a: 0x0d6f, 0xa2b: 0x0d7b, 0xa2c: 0x16ec, 0xa2d: 0x0d83, 0xa2e: 0x060b, 0xa2f: 0x0d8f,
-	0xa30: 0x16f1, 0xa31: 0x0d93, 0xa32: 0x060f, 0xa33: 0x0d9f, 0xa34: 0x0dab, 0xa35: 0x0db7,
-	0xa36: 0x0dbb, 0xa37: 0x16f6, 0xa38: 0x168d, 0xa39: 0x16fb, 0xa3a: 0x0ddb, 0xa3b: 0x1700,
-	0xa3c: 0x0de7, 0xa3d: 0x0def, 0xa3e: 0x0ddf, 0xa3f: 0x0dfb,
+	0xa00: 0x0abf, 0xa01: 0x0acf, 0xa02: 0x0ad3, 0xa03: 0x05d3, 0xa04: 0x0ae3, 0xa05: 0x0aeb,
+	0xa06: 0x0aef, 0xa07: 0x0af3, 0xa08: 0x05d7, 0xa09: 0x169c, 0xa0a: 0x05db, 0xa0b: 0x0b0f,
+	0xa0c: 0x0b13, 0xa0d: 0x0b17, 0xa0e: 0x0b1f, 0xa0f: 0x1863, 0xa10: 0x0b37, 0xa11: 0x16a6,
+	0xa12: 0x16a6, 0xa13: 0x11d7, 0xa14: 0x0b47, 0xa15: 0x0b47, 0xa16: 0x05df, 0xa17: 0x16c9,
+	0xa18: 0x179b, 0xa19: 0x0b57, 0xa1a: 0x0b5f, 0xa1b: 0x05e3, 0xa1c: 0x0b73, 0xa1d: 0x0b83,
+	0xa1e: 0x0b87, 0xa1f: 0x0b8f, 0xa20: 0x0b9f, 0xa21: 0x05eb, 0xa22: 0x05e7, 0xa23: 0x0ba3,
+	0xa24: 0x16ab, 0xa25: 0x0ba7, 0xa26: 0x0bbb, 0xa27: 0x0bbf, 0xa28: 0x0bc3, 0xa29: 0x0bbf,
+	0xa2a: 0x0bcf, 0xa2b: 0x0bd3, 0xa2c: 0x0be3, 0xa2d: 0x0bdb, 0xa2e: 0x0bdf, 0xa2f: 0x0be7,
+	0xa30: 0x0beb, 0xa31: 0x0bef, 0xa32: 0x0bfb, 0xa33: 0x0bff, 0xa34: 0x0c17, 0xa35: 0x0c1f,
+	0xa36: 0x0c2f, 0xa37: 0x0c43, 0xa38: 0x16ba, 0xa39: 0x0c3f, 0xa3a: 0x0c33, 0xa3b: 0x0c4b,
+	0xa3c: 0x0c53, 0xa3d: 0x0c67, 0xa3e: 0x16bf, 0xa3f: 0x0c6f,
 	// Block 0x29, offset 0xa40
-	0xa40: 0x0e0b, 0xa41: 0x0e1b, 0xa42: 0x0e0f, 0xa43: 0x0e13, 0xa44: 0x0e1f, 0xa45: 0x0e23,
-	0xa46: 0x1705, 0xa47: 0x0e07, 0xa48: 0x0e3b, 0xa49: 0x0e3f, 0xa4a: 0x0613, 0xa4b: 0x0e53,
-	0xa4c: 0x0e4f, 0xa4d: 0x170a, 0xa4e: 0x0e33, 0xa4f: 0x0e6f, 0xa50: 0x170f, 0xa51: 0x1714,
-	0xa52: 0x0e73, 0xa53: 0x0e87, 0xa54: 0x0e83, 0xa55: 0x0e7f, 0xa56: 0x0617, 0xa57: 0x0e8b,
-	0xa58: 0x0e9b, 0xa59: 0x0e97, 0xa5a: 0x0ea3, 0xa5b: 0x1651, 0xa5c: 0x0eb3, 0xa5d: 0x1719,
-	0xa5e: 0x0ebf, 0xa5f: 0x1723, 0xa60: 0x0ed3, 0xa61: 0x0edf, 0xa62: 0x0ef3, 0xa63: 0x1728,
-	0xa64: 0x0f07, 0xa65: 0x0f0b, 0xa66: 0x172d, 0xa67: 0x1732, 0xa68: 0x0f27, 0xa69: 0x0f37,
-	0xa6a: 0x061b, 0xa6b: 0x0f3b, 0xa6c: 0x061f, 0xa6d: 0x061f, 0xa6e: 0x0f53, 0xa6f: 0x0f57,
-	0xa70: 0x0f5f, 0xa71: 0x0f63, 0xa72: 0x0f6f, 0xa73: 0x0623, 0xa74: 0x0f87, 0xa75: 0x1737,
-	0xa76: 0x0fa3, 0xa77: 0x173c, 0xa78: 0x0faf, 0xa79: 0x16a1, 0xa7a: 0x0fbf, 0xa7b: 0x1741,
-	0xa7c: 0x1746, 0xa7d: 0x174b, 0xa7e: 0x0627, 0xa7f: 0x062b,
+	0xa40: 0x0c63, 0xa41: 0x0c5b, 0xa42: 0x05ef, 0xa43: 0x0c77, 0xa44: 0x0c7f, 0xa45: 0x0c87,
+	0xa46: 0x0c7b, 0xa47: 0x05f3, 0xa48: 0x0c97, 0xa49: 0x0c9f, 0xa4a: 0x16c4, 0xa4b: 0x0ccb,
+	0xa4c: 0x0cff, 0xa4d: 0x0cdb, 0xa4e: 0x05ff, 0xa4f: 0x0ce7, 0xa50: 0x05fb, 0xa51: 0x05f7,
+	0xa52: 0x07c3, 0xa53: 0x07c7, 0xa54: 0x0d03, 0xa55: 0x0ceb, 0xa56: 0x11ab, 0xa57: 0x0663,
+	0xa58: 0x0d0f, 0xa59: 0x0d13, 0xa5a: 0x0d17, 0xa5b: 0x0d2b, 0xa5c: 0x0d23, 0xa5d: 0x16dd,
+	0xa5e: 0x0603, 0xa5f: 0x0d3f, 0xa60: 0x0d33, 0xa61: 0x0d4f, 0xa62: 0x0d57, 0xa63: 0x16e7,
+	0xa64: 0x0d5b, 0xa65: 0x0d47, 0xa66: 0x0d63, 0xa67: 0x0607, 0xa68: 0x0d67, 0xa69: 0x0d6b,
+	0xa6a: 0x0d6f, 0xa6b: 0x0d7b, 0xa6c: 0x16ec, 0xa6d: 0x0d83, 0xa6e: 0x060b, 0xa6f: 0x0d8f,
+	0xa70: 0x16f1, 0xa71: 0x0d93, 0xa72: 0x060f, 0xa73: 0x0d9f, 0xa74: 0x0dab, 0xa75: 0x0db7,
+	0xa76: 0x0dbb, 0xa77: 0x16f6, 0xa78: 0x168d, 0xa79: 0x16fb, 0xa7a: 0x0ddb, 0xa7b: 0x1700,
+	0xa7c: 0x0de7, 0xa7d: 0x0def, 0xa7e: 0x0ddf, 0xa7f: 0x0dfb,
 	// Block 0x2a, offset 0xa80
-	0xa80: 0x0ff7, 0xa81: 0x1755, 0xa82: 0x1750, 0xa83: 0x175a, 0xa84: 0x175f, 0xa85: 0x0fff,
-	0xa86: 0x1003, 0xa87: 0x1003, 0xa88: 0x100b, 0xa89: 0x0633, 0xa8a: 0x100f, 0xa8b: 0x0637,
-	0xa8c: 0x063b, 0xa8d: 0x1769, 0xa8e: 0x1023, 0xa8f: 0x102b, 0xa90: 0x1037, 0xa91: 0x063f,
-	0xa92: 0x176e, 0xa93: 0x105b, 0xa94: 0x1773, 0xa95: 0x1778, 0xa96: 0x107b, 0xa97: 0x1093,
-	0xa98: 0x0643, 0xa99: 0x109b, 0xa9a: 0x109f, 0xa9b: 0x10a3, 0xa9c: 0x177d, 0xa9d: 0x1782,
-	0xa9e: 0x1782, 0xa9f: 0x10bb, 0xaa0: 0x0647, 0xaa1: 0x1787, 0xaa2: 0x10cf, 0xaa3: 0x10d3,
-	0xaa4: 0x064b, 0xaa5: 0x178c, 0xaa6: 0x10ef, 0xaa7: 0x064f, 0xaa8: 0x10ff, 0xaa9: 0x10f7,
-	0xaaa: 0x1107, 0xaab: 0x1796, 0xaac: 0x111f, 0xaad: 0x0653, 0xaae: 0x112b, 0xaaf: 0x1133,
-	0xab0: 0x1143, 0xab1: 0x0657, 0xab2: 0x17a0, 0xab3: 0x17a5, 0xab4: 0x065b, 0xab5: 0x17aa,
-	0xab6: 0x115b, 0xab7: 0x17af, 0xab8: 0x1167, 0xab9: 0x1173, 0xaba: 0x117b, 0xabb: 0x17b4,
-	0xabc: 0x17b9, 0xabd: 0x118f, 0xabe: 0x17be, 0xabf: 0x1197,
+	0xa80: 0x0e0b, 0xa81: 0x0e1b, 0xa82: 0x0e0f, 0xa83: 0x0e13, 0xa84: 0x0e1f, 0xa85: 0x0e23,
+	0xa86: 0x1705, 0xa87: 0x0e07, 0xa88: 0x0e3b, 0xa89: 0x0e3f, 0xa8a: 0x0613, 0xa8b: 0x0e53,
+	0xa8c: 0x0e4f, 0xa8d: 0x170a, 0xa8e: 0x0e33, 0xa8f: 0x0e6f, 0xa90: 0x170f, 0xa91: 0x1714,
+	0xa92: 0x0e73, 0xa93: 0x0e87, 0xa94: 0x0e83, 0xa95: 0x0e7f, 0xa96: 0x0617, 0xa97: 0x0e8b,
+	0xa98: 0x0e9b, 0xa99: 0x0e97, 0xa9a: 0x0ea3, 0xa9b: 0x1651, 0xa9c: 0x0eb3, 0xa9d: 0x1719,
+	0xa9e: 0x0ebf, 0xa9f: 0x1723, 0xaa0: 0x0ed3, 0xaa1: 0x0edf, 0xaa2: 0x0ef3, 0xaa3: 0x1728,
+	0xaa4: 0x0f07, 0xaa5: 0x0f0b, 0xaa6: 0x172d, 0xaa7: 0x1732, 0xaa8: 0x0f27, 0xaa9: 0x0f37,
+	0xaaa: 0x061b, 0xaab: 0x0f3b, 0xaac: 0x061f, 0xaad: 0x061f, 0xaae: 0x0f53, 0xaaf: 0x0f57,
+	0xab0: 0x0f5f, 0xab1: 0x0f63, 0xab2: 0x0f6f, 0xab3: 0x0623, 0xab4: 0x0f87, 0xab5: 0x1737,
+	0xab6: 0x0fa3, 0xab7: 0x173c, 0xab8: 0x0faf, 0xab9: 0x16a1, 0xaba: 0x0fbf, 0xabb: 0x1741,
+	0xabc: 0x1746, 0xabd: 0x174b, 0xabe: 0x0627, 0xabf: 0x062b,
 	// Block 0x2b, offset 0xac0
-	0xac0: 0x16ce, 0xac1: 0x065f, 0xac2: 0x11af, 0xac3: 0x11b3, 0xac4: 0x0667, 0xac5: 0x11b7,
-	0xac6: 0x0a33, 0xac7: 0x17c3, 0xac8: 0x17c8, 0xac9: 0x16d3, 0xaca: 0x16d8, 0xacb: 0x11d7,
-	0xacc: 0x11db, 0xacd: 0x13f3, 0xace: 0x066b, 0xacf: 0x1207, 0xad0: 0x1203, 0xad1: 0x120b,
-	0xad2: 0x083f, 0xad3: 0x120f, 0xad4: 0x1213, 0xad5: 0x1217, 0xad6: 0x121f, 0xad7: 0x17cd,
-	0xad8: 0x121b, 0xad9: 0x1223, 0xada: 0x1237, 0xadb: 0x123b, 0xadc: 0x1227, 0xadd: 0x123f,
-	0xade: 0x1253, 0xadf: 0x1267, 0xae0: 0x1233, 0xae1: 0x1247, 0xae2: 0x124b, 0xae3: 0x124f,
-	0xae4: 0x17d2, 0xae5: 0x17dc, 0xae6: 0x17d7, 0xae7: 0x066f, 0xae8: 0x126f, 0xae9: 0x1273,
-	0xaea: 0x127b, 0xaeb: 0x17f0, 0xaec: 0x127f, 0xaed: 0x17e1, 0xaee: 0x0673, 0xaef: 0x0677,
-	0xaf0: 0x17e6, 0xaf1: 0x17eb, 0xaf2: 0x067b, 0xaf3: 0x129f, 0xaf4: 0x12a3, 0xaf5: 0x12a7,
-	0xaf6: 0x12ab, 0xaf7: 0x12b7, 0xaf8: 0x12b3, 0xaf9: 0x12bf, 0xafa: 0x12bb, 0xafb: 0x12cb,
-	0xafc: 0x12c3, 0xafd: 0x12c7, 0xafe: 0x12cf, 0xaff: 0x067f,
+	0xac0: 0x0ff7, 0xac1: 0x1755, 0xac2: 0x1750, 0xac3: 0x175a, 0xac4: 0x175f, 0xac5: 0x0fff,
+	0xac6: 0x1003, 0xac7: 0x1003, 0xac8: 0x100b, 0xac9: 0x0633, 0xaca: 0x100f, 0xacb: 0x0637,
+	0xacc: 0x063b, 0xacd: 0x1769, 0xace: 0x1023, 0xacf: 0x102b, 0xad0: 0x1037, 0xad1: 0x063f,
+	0xad2: 0x176e, 0xad3: 0x105b, 0xad4: 0x1773, 0xad5: 0x1778, 0xad6: 0x107b, 0xad7: 0x1093,
+	0xad8: 0x0643, 0xad9: 0x109b, 0xada: 0x109f, 0xadb: 0x10a3, 0xadc: 0x177d, 0xadd: 0x1782,
+	0xade: 0x1782, 0xadf: 0x10bb, 0xae0: 0x0647, 0xae1: 0x1787, 0xae2: 0x10cf, 0xae3: 0x10d3,
+	0xae4: 0x064b, 0xae5: 0x178c, 0xae6: 0x10ef, 0xae7: 0x064f, 0xae8: 0x10ff, 0xae9: 0x10f7,
+	0xaea: 0x1107, 0xaeb: 0x1796, 0xaec: 0x111f, 0xaed: 0x0653, 0xaee: 0x112b, 0xaef: 0x1133,
+	0xaf0: 0x1143, 0xaf1: 0x0657, 0xaf2: 0x17a0, 0xaf3: 0x17a5, 0xaf4: 0x065b, 0xaf5: 0x17aa,
+	0xaf6: 0x115b, 0xaf7: 0x17af, 0xaf8: 0x1167, 0xaf9: 0x1173, 0xafa: 0x117b, 0xafb: 0x17b4,
+	0xafc: 0x17b9, 0xafd: 0x118f, 0xafe: 0x17be, 0xaff: 0x1197,
 	// Block 0x2c, offset 0xb00
-	0xb00: 0x12d7, 0xb01: 0x12db, 0xb02: 0x0683, 0xb03: 0x12eb, 0xb04: 0x12ef, 0xb05: 0x17f5,
-	0xb06: 0x12fb, 0xb07: 0x12ff, 0xb08: 0x0687, 0xb09: 0x130b, 0xb0a: 0x05bb, 0xb0b: 0x17fa,
-	0xb0c: 0x17ff, 0xb0d: 0x068b, 0xb0e: 0x068f, 0xb0f: 0x1337, 0xb10: 0x134f, 0xb11: 0x136b,
-	0xb12: 0x137b, 0xb13: 0x1804, 0xb14: 0x138f, 0xb15: 0x1393, 0xb16: 0x13ab, 0xb17: 0x13b7,
-	0xb18: 0x180e, 0xb19: 0x1660, 0xb1a: 0x13c3, 0xb1b: 0x13bf, 0xb1c: 0x13cb, 0xb1d: 0x1665,
-	0xb1e: 0x13d7, 0xb1f: 0x13e3, 0xb20: 0x1813, 0xb21: 0x1818, 0xb22: 0x1423, 0xb23: 0x142f,
-	0xb24: 0x1437, 0xb25: 0x181d, 0xb26: 0x143b, 0xb27: 0x1467, 0xb28: 0x1473, 0xb29: 0x1477,
-	0xb2a: 0x146f, 0xb2b: 0x1483, 0xb2c: 0x1487, 0xb2d: 0x1822, 0xb2e: 0x1493, 0xb2f: 0x0693,
-	0xb30: 0x149b, 0xb31: 0x1827, 0xb32: 0x0697, 0xb33: 0x14d3, 0xb34: 0x0ac3, 0xb35: 0x14eb,
-	0xb36: 0x182c, 0xb37: 0x1836, 0xb38: 0x069b, 0xb39: 0x069f, 0xb3a: 0x1513, 0xb3b: 0x183b,
-	0xb3c: 0x06a3, 0xb3d: 0x1840, 0xb3e: 0x152b, 0xb3f: 0x152b,
+	0xb00: 0x16ce, 0xb01: 0x065f, 0xb02: 0x11af, 0xb03: 0x11b3, 0xb04: 0x0667, 0xb05: 0x11b7,
+	0xb06: 0x0a33, 0xb07: 0x17c3, 0xb08: 0x17c8, 0xb09: 0x16d3, 0xb0a: 0x16d8, 0xb0b: 0x11d7,
+	0xb0c: 0x11db, 0xb0d: 0x13f3, 0xb0e: 0x066b, 0xb0f: 0x1207, 0xb10: 0x1203, 0xb11: 0x120b,
+	0xb12: 0x083f, 0xb13: 0x120f, 0xb14: 0x1213, 0xb15: 0x1217, 0xb16: 0x121f, 0xb17: 0x17cd,
+	0xb18: 0x121b, 0xb19: 0x1223, 0xb1a: 0x1237, 0xb1b: 0x123b, 0xb1c: 0x1227, 0xb1d: 0x123f,
+	0xb1e: 0x1253, 0xb1f: 0x1267, 0xb20: 0x1233, 0xb21: 0x1247, 0xb22: 0x124b, 0xb23: 0x124f,
+	0xb24: 0x17d2, 0xb25: 0x17dc, 0xb26: 0x17d7, 0xb27: 0x066f, 0xb28: 0x126f, 0xb29: 0x1273,
+	0xb2a: 0x127b, 0xb2b: 0x17f0, 0xb2c: 0x127f, 0xb2d: 0x17e1, 0xb2e: 0x0673, 0xb2f: 0x0677,
+	0xb30: 0x17e6, 0xb31: 0x17eb, 0xb32: 0x067b, 0xb33: 0x129f, 0xb34: 0x12a3, 0xb35: 0x12a7,
+	0xb36: 0x12ab, 0xb37: 0x12b7, 0xb38: 0x12b3, 0xb39: 0x12bf, 0xb3a: 0x12bb, 0xb3b: 0x12cb,
+	0xb3c: 0x12c3, 0xb3d: 0x12c7, 0xb3e: 0x12cf, 0xb3f: 0x067f,
 	// Block 0x2d, offset 0xb40
-	0xb40: 0x1533, 0xb41: 0x1845, 0xb42: 0x154b, 0xb43: 0x06a7, 0xb44: 0x155b, 0xb45: 0x1567,
-	0xb46: 0x156f, 0xb47: 0x1577, 0xb48: 0x06ab, 0xb49: 0x184a, 0xb4a: 0x158b, 0xb4b: 0x15a7,
-	0xb4c: 0x15b3, 0xb4d: 0x06af, 0xb4e: 0x06b3, 0xb4f: 0x15b7, 0xb50: 0x184f, 0xb51: 0x06b7,
-	0xb52: 0x1854, 0xb53: 0x1859, 0xb54: 0x185e, 0xb55: 0x15db, 0xb56: 0x06bb, 0xb57: 0x15ef,
-	0xb58: 0x15f7, 0xb59: 0x15fb, 0xb5a: 0x1603, 0xb5b: 0x160b, 0xb5c: 0x1613, 0xb5d: 0x1868,
+	0xb40: 0x12d7, 0xb41: 0x12db, 0xb42: 0x0683, 0xb43: 0x12eb, 0xb44: 0x12ef, 0xb45: 0x17f5,
+	0xb46: 0x12fb, 0xb47: 0x12ff, 0xb48: 0x0687, 0xb49: 0x130b, 0xb4a: 0x05bb, 0xb4b: 0x17fa,
+	0xb4c: 0x17ff, 0xb4d: 0x068b, 0xb4e: 0x068f, 0xb4f: 0x1337, 0xb50: 0x134f, 0xb51: 0x136b,
+	0xb52: 0x137b, 0xb53: 0x1804, 0xb54: 0x138f, 0xb55: 0x1393, 0xb56: 0x13ab, 0xb57: 0x13b7,
+	0xb58: 0x180e, 0xb59: 0x1660, 0xb5a: 0x13c3, 0xb5b: 0x13bf, 0xb5c: 0x13cb, 0xb5d: 0x1665,
+	0xb5e: 0x13d7, 0xb5f: 0x13e3, 0xb60: 0x1813, 0xb61: 0x1818, 0xb62: 0x1423, 0xb63: 0x142f,
+	0xb64: 0x1437, 0xb65: 0x181d, 0xb66: 0x143b, 0xb67: 0x1467, 0xb68: 0x1473, 0xb69: 0x1477,
+	0xb6a: 0x146f, 0xb6b: 0x1483, 0xb6c: 0x1487, 0xb6d: 0x1822, 0xb6e: 0x1493, 0xb6f: 0x0693,
+	0xb70: 0x149b, 0xb71: 0x1827, 0xb72: 0x0697, 0xb73: 0x14d3, 0xb74: 0x0ac3, 0xb75: 0x14eb,
+	0xb76: 0x182c, 0xb77: 0x1836, 0xb78: 0x069b, 0xb79: 0x069f, 0xb7a: 0x1513, 0xb7b: 0x183b,
+	0xb7c: 0x06a3, 0xb7d: 0x1840, 0xb7e: 0x152b, 0xb7f: 0x152b,
+	// Block 0x2e, offset 0xb80
+	0xb80: 0x1533, 0xb81: 0x1845, 0xb82: 0x154b, 0xb83: 0x06a7, 0xb84: 0x155b, 0xb85: 0x1567,
+	0xb86: 0x156f, 0xb87: 0x1577, 0xb88: 0x06ab, 0xb89: 0x184a, 0xb8a: 0x158b, 0xb8b: 0x15a7,
+	0xb8c: 0x15b3, 0xb8d: 0x06af, 0xb8e: 0x06b3, 0xb8f: 0x15b7, 0xb90: 0x184f, 0xb91: 0x06b7,
+	0xb92: 0x1854, 0xb93: 0x1859, 0xb94: 0x185e, 0xb95: 0x15db, 0xb96: 0x06bb, 0xb97: 0x15ef,
+	0xb98: 0x15f7, 0xb99: 0x15fb, 0xb9a: 0x1603, 0xb9b: 0x160b, 0xb9c: 0x1613, 0xb9d: 0x1868,
 }
 
 // nfcIndex: 22 blocks, 1408 entries, 1408 bytes
@@ -3419,33 +3431,33 @@
 	// Block 0x1, offset 0x40
 	// Block 0x2, offset 0x80
 	// Block 0x3, offset 0xc0
-	0xc2: 0x2c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2d, 0xc7: 0x04,
-	0xc8: 0x05, 0xca: 0x2e, 0xcb: 0x2f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x30,
-	0xd0: 0x09, 0xd1: 0x31, 0xd2: 0x32, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x33,
-	0xd8: 0x34, 0xd9: 0x0c, 0xdb: 0x35, 0xdc: 0x36, 0xdd: 0x37, 0xdf: 0x38,
+	0xc2: 0x2d, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2e, 0xc7: 0x04,
+	0xc8: 0x05, 0xca: 0x2f, 0xcb: 0x30, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x31,
+	0xd0: 0x09, 0xd1: 0x32, 0xd2: 0x33, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x34,
+	0xd8: 0x35, 0xd9: 0x0c, 0xdb: 0x36, 0xdc: 0x37, 0xdd: 0x38, 0xdf: 0x39,
 	0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
 	0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
 	0xf0: 0x13,
 	// Block 0x4, offset 0x100
-	0x120: 0x39, 0x121: 0x3a, 0x123: 0x3b, 0x124: 0x3c, 0x125: 0x3d, 0x126: 0x3e, 0x127: 0x3f,
-	0x128: 0x40, 0x129: 0x41, 0x12a: 0x42, 0x12b: 0x43, 0x12c: 0x3e, 0x12d: 0x44, 0x12e: 0x45, 0x12f: 0x46,
-	0x131: 0x47, 0x132: 0x48, 0x133: 0x49, 0x134: 0x4a, 0x135: 0x4b, 0x137: 0x4c,
-	0x138: 0x4d, 0x139: 0x4e, 0x13a: 0x4f, 0x13b: 0x50, 0x13c: 0x51, 0x13d: 0x52, 0x13e: 0x53, 0x13f: 0x54,
+	0x120: 0x3a, 0x121: 0x3b, 0x123: 0x3c, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40,
+	0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47,
+	0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d,
+	0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55,
 	// Block 0x5, offset 0x140
-	0x140: 0x55, 0x142: 0x56, 0x144: 0x57, 0x145: 0x58, 0x146: 0x59, 0x147: 0x5a,
-	0x14d: 0x5b,
-	0x15c: 0x5c, 0x15f: 0x5d,
-	0x162: 0x5e, 0x164: 0x5f,
-	0x168: 0x60, 0x169: 0x61, 0x16a: 0x62, 0x16c: 0x0d, 0x16d: 0x63, 0x16e: 0x64, 0x16f: 0x65,
-	0x170: 0x66, 0x173: 0x67, 0x177: 0x68,
-	0x178: 0x0e, 0x179: 0x0f, 0x17a: 0x10, 0x17b: 0x11, 0x17c: 0x12, 0x17d: 0x13, 0x17e: 0x14, 0x17f: 0x15,
+	0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b,
+	0x14d: 0x5c,
+	0x15c: 0x5d, 0x15f: 0x5e,
+	0x162: 0x5f, 0x164: 0x60,
+	0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16c: 0x0d, 0x16d: 0x64, 0x16e: 0x65, 0x16f: 0x66,
+	0x170: 0x67, 0x173: 0x68, 0x177: 0x0e,
+	0x178: 0x0f, 0x179: 0x10, 0x17a: 0x11, 0x17b: 0x12, 0x17c: 0x13, 0x17d: 0x14, 0x17e: 0x15, 0x17f: 0x16,
 	// Block 0x6, offset 0x180
 	0x180: 0x69, 0x183: 0x6a, 0x184: 0x6b, 0x186: 0x6c, 0x187: 0x6d,
-	0x188: 0x6e, 0x189: 0x16, 0x18a: 0x17, 0x18b: 0x6f, 0x18c: 0x70,
+	0x188: 0x6e, 0x189: 0x17, 0x18a: 0x18, 0x18b: 0x6f, 0x18c: 0x70,
 	0x1ab: 0x71,
 	0x1b3: 0x72, 0x1b5: 0x73, 0x1b7: 0x74,
 	// Block 0x7, offset 0x1c0
-	0x1c0: 0x75, 0x1c1: 0x18, 0x1c2: 0x19, 0x1c3: 0x1a, 0x1c4: 0x76, 0x1c5: 0x77,
+	0x1c0: 0x75, 0x1c1: 0x19, 0x1c2: 0x1a, 0x1c3: 0x1b, 0x1c4: 0x76, 0x1c5: 0x77,
 	0x1c9: 0x78, 0x1cc: 0x79, 0x1cd: 0x7a,
 	// Block 0x8, offset 0x200
 	0x219: 0x7b, 0x21a: 0x7c, 0x21b: 0x7d,
@@ -3477,8 +3489,8 @@
 	0x2d0: 0x8d, 0x2d1: 0x87, 0x2d2: 0x88, 0x2d3: 0x89, 0x2d4: 0x8a, 0x2d5: 0x8b, 0x2d6: 0x8c, 0x2d7: 0x8d,
 	0x2d8: 0x87, 0x2d9: 0x88, 0x2da: 0x89, 0x2db: 0x8a, 0x2dc: 0x8b, 0x2dd: 0x8c, 0x2de: 0x8e,
 	// Block 0xc, offset 0x300
-	0x324: 0x1b, 0x325: 0x1c, 0x326: 0x1d, 0x327: 0x1e,
-	0x328: 0x1f, 0x329: 0x20, 0x32a: 0x21, 0x32b: 0x22, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91,
+	0x324: 0x1c, 0x325: 0x1d, 0x326: 0x1e, 0x327: 0x1f,
+	0x328: 0x20, 0x329: 0x21, 0x32a: 0x22, 0x32b: 0x23, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91,
 	0x331: 0x92, 0x332: 0x93, 0x333: 0x94, 0x334: 0x95,
 	0x338: 0x96, 0x339: 0x97, 0x33a: 0x98, 0x33b: 0x99, 0x33e: 0x9a, 0x33f: 0x9b,
 	// Block 0xd, offset 0x340
@@ -3487,36 +3499,37 @@
 	0x368: 0x9f, 0x36b: 0xa0,
 	// Block 0xe, offset 0x380
 	0x381: 0xa1, 0x382: 0xa2, 0x384: 0xa3, 0x385: 0x82, 0x387: 0xa4,
-	0x388: 0xa5, 0x38b: 0xa6, 0x38c: 0x3e, 0x38d: 0xa7,
+	0x388: 0xa5, 0x38b: 0xa6, 0x38c: 0x3f, 0x38d: 0xa7,
 	0x391: 0xa8, 0x392: 0xa9, 0x393: 0xaa, 0x396: 0xab, 0x397: 0xac,
 	0x398: 0x73, 0x39a: 0xad, 0x39c: 0xae,
-	0x3b0: 0x73,
+	0x3a8: 0xaf, 0x3a9: 0xb0, 0x3aa: 0xb1,
+	0x3b0: 0x73, 0x3b5: 0xb2,
 	// Block 0xf, offset 0x3c0
-	0x3eb: 0xaf, 0x3ec: 0xb0,
+	0x3eb: 0xb3, 0x3ec: 0xb4,
 	// Block 0x10, offset 0x400
-	0x432: 0xb1,
+	0x432: 0xb5,
 	// Block 0x11, offset 0x440
-	0x445: 0xb2, 0x446: 0xb3, 0x447: 0xb4,
-	0x449: 0xb5,
+	0x445: 0xb6, 0x446: 0xb7, 0x447: 0xb8,
+	0x449: 0xb9,
 	// Block 0x12, offset 0x480
-	0x480: 0xb6,
-	0x4a3: 0xb7, 0x4a5: 0xb8,
+	0x480: 0xba,
+	0x4a3: 0xbb, 0x4a5: 0xbc,
 	// Block 0x13, offset 0x4c0
-	0x4c8: 0xb9,
+	0x4c8: 0xbd,
 	// Block 0x14, offset 0x500
-	0x520: 0x23, 0x521: 0x24, 0x522: 0x25, 0x523: 0x26, 0x524: 0x27, 0x525: 0x28, 0x526: 0x29, 0x527: 0x2a,
-	0x528: 0x2b,
+	0x520: 0x24, 0x521: 0x25, 0x522: 0x26, 0x523: 0x27, 0x524: 0x28, 0x525: 0x29, 0x526: 0x2a, 0x527: 0x2b,
+	0x528: 0x2c,
 	// Block 0x15, offset 0x540
 	0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
 	0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
 	0x56f: 0x12,
 }
 
-// nfcSparseOffset: 142 entries, 284 bytes
-var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x62, 0x67, 0x69, 0x7a, 0x82, 0x89, 0x8c, 0x93, 0x97, 0x9b, 0x9d, 0x9f, 0xa8, 0xac, 0xb3, 0xb8, 0xbb, 0xc5, 0xc7, 0xce, 0xd6, 0xd9, 0xdb, 0xdd, 0xdf, 0xe4, 0xf5, 0x101, 0x103, 0x109, 0x10b, 0x10d, 0x10f, 0x111, 0x113, 0x115, 0x118, 0x11b, 0x11d, 0x120, 0x123, 0x127, 0x12c, 0x135, 0x137, 0x13a, 0x13c, 0x147, 0x157, 0x15b, 0x169, 0x16c, 0x172, 0x178, 0x183, 0x187, 0x189, 0x18b, 0x18d, 0x18f, 0x191, 0x197, 0x19b, 0x19d, 0x19f, 0x1a7, 0x1ab, 0x1ae, 0x1b0, 0x1b2, 0x1b4, 0x1b7, 0x1b9, 0x1bb, 0x1bd, 0x1bf, 0x1c5, 0x1c8, 0x1ca, 0x1d1, 0x1d7, 0x1dd, 0x1e5, 0x1eb, 0x1f1, 0x1f7, 0x1fb, 0x209, 0x212, 0x215, 0x218, 0x21a, 0x21d, 0x21f, 0x223, 0x228, 0x22a, 0x22c, 0x231, 0x237, 0x239, 0x23b, 0x23d, 0x243, 0x246, 0x249, 0x251, 0x258, 0x25b, 0x25e, 0x260, 0x268, 0x26b, 0x272, 0x275, 0x27b, 0x27d, 0x280, 0x282, 0x284, 0x286, 0x288, 0x295, 0x29f, 0x2a1, 0x2a3, 0x2a9, 0x2ab, 0x2ae}
+// nfcSparseOffset: 145 entries, 290 bytes
+var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x62, 0x67, 0x69, 0x7a, 0x82, 0x89, 0x8c, 0x93, 0x97, 0x9b, 0x9d, 0x9f, 0xa8, 0xac, 0xb3, 0xb8, 0xbb, 0xc5, 0xc8, 0xcf, 0xd7, 0xda, 0xdc, 0xde, 0xe0, 0xe5, 0xf6, 0x102, 0x104, 0x10a, 0x10c, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x119, 0x11c, 0x11e, 0x121, 0x124, 0x128, 0x12d, 0x136, 0x138, 0x13b, 0x13d, 0x148, 0x14c, 0x15a, 0x15d, 0x163, 0x169, 0x174, 0x178, 0x17a, 0x17c, 0x17e, 0x180, 0x182, 0x188, 0x18c, 0x18e, 0x190, 0x198, 0x19c, 0x19f, 0x1a1, 0x1a3, 0x1a5, 0x1a8, 0x1aa, 0x1ac, 0x1ae, 0x1b0, 0x1b6, 0x1b9, 0x1bb, 0x1c2, 0x1c8, 0x1ce, 0x1d6, 0x1dc, 0x1e2, 0x1e8, 0x1ec, 0x1fa, 0x203, 0x206, 0x209, 0x20b, 0x20e, 0x210, 0x214, 0x219, 0x21b, 0x21d, 0x222, 0x228, 0x22a, 0x22c, 0x22e, 0x234, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x259, 0x25c, 0x263, 0x266, 0x26c, 0x26e, 0x271, 0x273, 0x275, 0x277, 0x279, 0x27c, 0x27e, 0x280, 0x282, 0x28f, 0x299, 0x29b, 0x29d, 0x2a3, 0x2a5, 0x2a8}
 
-// nfcSparseValues: 688 entries, 2752 bytes
-var nfcSparseValues = [688]valueRange{
+// nfcSparseValues: 682 entries, 2728 bytes
+var nfcSparseValues = [682]valueRange{
 	// Block 0x0, offset 0x0
 	{value: 0x0000, lo: 0x04},
 	{value: 0xa100, lo: 0xa8, hi: 0xa8},
@@ -3745,9 +3758,10 @@
 	{value: 0x8104, lo: 0x8d, hi: 0x8d},
 	{value: 0x9900, lo: 0x95, hi: 0x96},
 	// Block 0x1e, offset 0xc5
-	{value: 0x0000, lo: 0x01},
+	{value: 0x0000, lo: 0x02},
+	{value: 0x8104, lo: 0xbb, hi: 0xbc},
 	{value: 0x9900, lo: 0xbe, hi: 0xbe},
-	// Block 0x1f, offset 0xc7
+	// Block 0x1f, offset 0xc8
 	{value: 0x0000, lo: 0x06},
 	{value: 0xa000, lo: 0x86, hi: 0x87},
 	{value: 0x2cfe, lo: 0x8a, hi: 0x8a},
@@ -3755,7 +3769,7 @@
 	{value: 0x2d06, lo: 0x8c, hi: 0x8c},
 	{value: 0x8104, lo: 0x8d, hi: 0x8d},
 	{value: 0x9900, lo: 0x97, hi: 0x97},
-	// Block 0x20, offset 0xce
+	// Block 0x20, offset 0xcf
 	{value: 0x6bea, lo: 0x07},
 	{value: 0x9904, lo: 0x8a, hi: 0x8a},
 	{value: 0x9900, lo: 0x8f, hi: 0x8f},
@@ -3764,26 +3778,26 @@
 	{value: 0x2f58, lo: 0x9c, hi: 0x9c},
 	{value: 0x2de3, lo: 0x9d, hi: 0x9d},
 	{value: 0x2d16, lo: 0x9e, hi: 0x9f},
-	// Block 0x21, offset 0xd6
+	// Block 0x21, offset 0xd7
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8122, lo: 0xb8, hi: 0xb9},
 	{value: 0x8104, lo: 0xba, hi: 0xba},
-	// Block 0x22, offset 0xd9
+	// Block 0x22, offset 0xda
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8123, lo: 0x88, hi: 0x8b},
-	// Block 0x23, offset 0xdb
+	// Block 0x23, offset 0xdc
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8124, lo: 0xb8, hi: 0xb9},
-	// Block 0x24, offset 0xdd
+	// Block 0x24, offset 0xde
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8125, lo: 0x88, hi: 0x8b},
-	// Block 0x25, offset 0xdf
+	// Block 0x25, offset 0xe0
 	{value: 0x0000, lo: 0x04},
 	{value: 0x812d, lo: 0x98, hi: 0x99},
 	{value: 0x812d, lo: 0xb5, hi: 0xb5},
 	{value: 0x812d, lo: 0xb7, hi: 0xb7},
 	{value: 0x812b, lo: 0xb9, hi: 0xb9},
-	// Block 0x26, offset 0xe4
+	// Block 0x26, offset 0xe5
 	{value: 0x0000, lo: 0x10},
 	{value: 0x2644, lo: 0x83, hi: 0x83},
 	{value: 0x264b, lo: 0x8d, hi: 0x8d},
@@ -3801,7 +3815,7 @@
 	{value: 0x45bc, lo: 0xb8, hi: 0xb8},
 	{value: 0x8200, lo: 0xb9, hi: 0xb9},
 	{value: 0x8127, lo: 0xba, hi: 0xbd},
-	// Block 0x27, offset 0xf5
+	// Block 0x27, offset 0xf6
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x8127, lo: 0x80, hi: 0x80},
 	{value: 0x4a96, lo: 0x81, hi: 0x81},
@@ -3814,65 +3828,65 @@
 	{value: 0x2683, lo: 0xa7, hi: 0xa7},
 	{value: 0x268a, lo: 0xac, hi: 0xac},
 	{value: 0x2667, lo: 0xb9, hi: 0xb9},
-	// Block 0x28, offset 0x101
+	// Block 0x28, offset 0x102
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x86, hi: 0x86},
-	// Block 0x29, offset 0x103
+	// Block 0x29, offset 0x104
 	{value: 0x0000, lo: 0x05},
 	{value: 0xa000, lo: 0xa5, hi: 0xa5},
 	{value: 0x2d1e, lo: 0xa6, hi: 0xa6},
 	{value: 0x9900, lo: 0xae, hi: 0xae},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
 	{value: 0x8104, lo: 0xb9, hi: 0xba},
-	// Block 0x2a, offset 0x109
+	// Block 0x2a, offset 0x10a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x8d, hi: 0x8d},
-	// Block 0x2b, offset 0x10b
+	// Block 0x2b, offset 0x10c
 	{value: 0x0000, lo: 0x01},
 	{value: 0xa000, lo: 0x80, hi: 0x92},
-	// Block 0x2c, offset 0x10d
+	// Block 0x2c, offset 0x10e
 	{value: 0x0000, lo: 0x01},
 	{value: 0xb900, lo: 0xa1, hi: 0xb5},
-	// Block 0x2d, offset 0x10f
+	// Block 0x2d, offset 0x110
 	{value: 0x0000, lo: 0x01},
 	{value: 0x9900, lo: 0xa8, hi: 0xbf},
-	// Block 0x2e, offset 0x111
+	// Block 0x2e, offset 0x112
 	{value: 0x0000, lo: 0x01},
 	{value: 0x9900, lo: 0x80, hi: 0x82},
-	// Block 0x2f, offset 0x113
+	// Block 0x2f, offset 0x114
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0x9d, hi: 0x9f},
-	// Block 0x30, offset 0x115
+	// Block 0x30, offset 0x116
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x94, hi: 0x94},
 	{value: 0x8104, lo: 0xb4, hi: 0xb4},
-	// Block 0x31, offset 0x118
+	// Block 0x31, offset 0x119
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x92, hi: 0x92},
 	{value: 0x8132, lo: 0x9d, hi: 0x9d},
-	// Block 0x32, offset 0x11b
+	// Block 0x32, offset 0x11c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8131, lo: 0xa9, hi: 0xa9},
-	// Block 0x33, offset 0x11d
+	// Block 0x33, offset 0x11e
 	{value: 0x0004, lo: 0x02},
 	{value: 0x812e, lo: 0xb9, hi: 0xba},
 	{value: 0x812d, lo: 0xbb, hi: 0xbb},
-	// Block 0x34, offset 0x120
+	// Block 0x34, offset 0x121
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x97, hi: 0x97},
 	{value: 0x812d, lo: 0x98, hi: 0x98},
-	// Block 0x35, offset 0x123
+	// Block 0x35, offset 0x124
 	{value: 0x0000, lo: 0x03},
 	{value: 0x8104, lo: 0xa0, hi: 0xa0},
 	{value: 0x8132, lo: 0xb5, hi: 0xbc},
 	{value: 0x812d, lo: 0xbf, hi: 0xbf},
-	// Block 0x36, offset 0x127
+	// Block 0x36, offset 0x128
 	{value: 0x0000, lo: 0x04},
 	{value: 0x8132, lo: 0xb0, hi: 0xb4},
 	{value: 0x812d, lo: 0xb5, hi: 0xba},
 	{value: 0x8132, lo: 0xbb, hi: 0xbc},
 	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	// Block 0x37, offset 0x12c
+	// Block 0x37, offset 0x12d
 	{value: 0x0000, lo: 0x08},
 	{value: 0x2d66, lo: 0x80, hi: 0x80},
 	{value: 0x2d6e, lo: 0x81, hi: 0x81},
@@ -3882,17 +3896,17 @@
 	{value: 0x8132, lo: 0xab, hi: 0xab},
 	{value: 0x812d, lo: 0xac, hi: 0xac},
 	{value: 0x8132, lo: 0xad, hi: 0xb3},
-	// Block 0x38, offset 0x135
+	// Block 0x38, offset 0x136
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xaa, hi: 0xab},
-	// Block 0x39, offset 0x137
+	// Block 0x39, offset 0x138
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8102, lo: 0xa6, hi: 0xa6},
 	{value: 0x8104, lo: 0xb2, hi: 0xb3},
-	// Block 0x3a, offset 0x13a
+	// Block 0x3a, offset 0x13b
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
-	// Block 0x3b, offset 0x13c
+	// Block 0x3b, offset 0x13d
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x8132, lo: 0x90, hi: 0x92},
 	{value: 0x8101, lo: 0x94, hi: 0x94},
@@ -3904,29 +3918,12 @@
 	{value: 0x812d, lo: 0xad, hi: 0xad},
 	{value: 0x8132, lo: 0xb4, hi: 0xb4},
 	{value: 0x8132, lo: 0xb8, hi: 0xb9},
-	// Block 0x3c, offset 0x147
-	{value: 0x0000, lo: 0x0f},
-	{value: 0x8132, lo: 0x80, hi: 0x81},
-	{value: 0x812d, lo: 0x82, hi: 0x82},
-	{value: 0x8132, lo: 0x83, hi: 0x89},
-	{value: 0x812d, lo: 0x8a, hi: 0x8a},
-	{value: 0x8132, lo: 0x8b, hi: 0x8c},
-	{value: 0x8135, lo: 0x8d, hi: 0x8d},
-	{value: 0x812a, lo: 0x8e, hi: 0x8e},
-	{value: 0x812d, lo: 0x8f, hi: 0x8f},
-	{value: 0x8129, lo: 0x90, hi: 0x90},
-	{value: 0x8132, lo: 0x91, hi: 0xb5},
-	{value: 0x8132, lo: 0xbb, hi: 0xbb},
-	{value: 0x8134, lo: 0xbc, hi: 0xbc},
-	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	{value: 0x8132, lo: 0xbe, hi: 0xbe},
-	{value: 0x812d, lo: 0xbf, hi: 0xbf},
-	// Block 0x3d, offset 0x157
+	// Block 0x3c, offset 0x148
 	{value: 0x0004, lo: 0x03},
 	{value: 0x0433, lo: 0x80, hi: 0x81},
 	{value: 0x8100, lo: 0x97, hi: 0x97},
 	{value: 0x8100, lo: 0xbe, hi: 0xbe},
-	// Block 0x3e, offset 0x15b
+	// Block 0x3d, offset 0x14c
 	{value: 0x0000, lo: 0x0d},
 	{value: 0x8132, lo: 0x90, hi: 0x91},
 	{value: 0x8101, lo: 0x92, hi: 0x93},
@@ -3941,25 +3938,25 @@
 	{value: 0x8101, lo: 0xaa, hi: 0xab},
 	{value: 0x812d, lo: 0xac, hi: 0xaf},
 	{value: 0x8132, lo: 0xb0, hi: 0xb0},
-	// Block 0x3f, offset 0x169
+	// Block 0x3e, offset 0x15a
 	{value: 0x427b, lo: 0x02},
 	{value: 0x01b8, lo: 0xa6, hi: 0xa6},
 	{value: 0x0057, lo: 0xaa, hi: 0xab},
-	// Block 0x40, offset 0x16c
+	// Block 0x3f, offset 0x15d
 	{value: 0x0007, lo: 0x05},
 	{value: 0xa000, lo: 0x90, hi: 0x90},
 	{value: 0xa000, lo: 0x92, hi: 0x92},
 	{value: 0xa000, lo: 0x94, hi: 0x94},
 	{value: 0x3bb9, lo: 0x9a, hi: 0x9b},
 	{value: 0x3bc7, lo: 0xae, hi: 0xae},
-	// Block 0x41, offset 0x172
+	// Block 0x40, offset 0x163
 	{value: 0x000e, lo: 0x05},
 	{value: 0x3bce, lo: 0x8d, hi: 0x8e},
 	{value: 0x3bd5, lo: 0x8f, hi: 0x8f},
 	{value: 0xa000, lo: 0x90, hi: 0x90},
 	{value: 0xa000, lo: 0x92, hi: 0x92},
 	{value: 0xa000, lo: 0x94, hi: 0x94},
-	// Block 0x42, offset 0x178
+	// Block 0x41, offset 0x169
 	{value: 0x6408, lo: 0x0a},
 	{value: 0xa000, lo: 0x83, hi: 0x83},
 	{value: 0x3be3, lo: 0x84, hi: 0x84},
@@ -3971,45 +3968,45 @@
 	{value: 0x3bf8, lo: 0xa4, hi: 0xa5},
 	{value: 0x3bff, lo: 0xa6, hi: 0xa6},
 	{value: 0xa000, lo: 0xbc, hi: 0xbc},
-	// Block 0x43, offset 0x183
+	// Block 0x42, offset 0x174
 	{value: 0x0007, lo: 0x03},
 	{value: 0x3c68, lo: 0xa0, hi: 0xa1},
 	{value: 0x3c92, lo: 0xa2, hi: 0xa3},
 	{value: 0x3cbc, lo: 0xaa, hi: 0xad},
-	// Block 0x44, offset 0x187
+	// Block 0x43, offset 0x178
 	{value: 0x0004, lo: 0x01},
 	{value: 0x048b, lo: 0xa9, hi: 0xaa},
-	// Block 0x45, offset 0x189
+	// Block 0x44, offset 0x17a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x44dd, lo: 0x9c, hi: 0x9c},
-	// Block 0x46, offset 0x18b
+	// Block 0x45, offset 0x17c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xaf, hi: 0xb1},
-	// Block 0x47, offset 0x18d
+	// Block 0x46, offset 0x17e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x48, offset 0x18f
+	// Block 0x47, offset 0x180
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xa0, hi: 0xbf},
-	// Block 0x49, offset 0x191
+	// Block 0x48, offset 0x182
 	{value: 0x0000, lo: 0x05},
 	{value: 0x812c, lo: 0xaa, hi: 0xaa},
 	{value: 0x8131, lo: 0xab, hi: 0xab},
 	{value: 0x8133, lo: 0xac, hi: 0xac},
 	{value: 0x812e, lo: 0xad, hi: 0xad},
 	{value: 0x812f, lo: 0xae, hi: 0xaf},
-	// Block 0x4a, offset 0x197
+	// Block 0x49, offset 0x188
 	{value: 0x0000, lo: 0x03},
 	{value: 0x4a9f, lo: 0xb3, hi: 0xb3},
 	{value: 0x4a9f, lo: 0xb5, hi: 0xb6},
 	{value: 0x4a9f, lo: 0xba, hi: 0xbf},
-	// Block 0x4b, offset 0x19b
+	// Block 0x4a, offset 0x18c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x4a9f, lo: 0x8f, hi: 0xa3},
-	// Block 0x4c, offset 0x19d
+	// Block 0x4b, offset 0x18e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0xae, hi: 0xbe},
-	// Block 0x4d, offset 0x19f
+	// Block 0x4c, offset 0x190
 	{value: 0x0000, lo: 0x07},
 	{value: 0x8100, lo: 0x84, hi: 0x84},
 	{value: 0x8100, lo: 0x87, hi: 0x87},
@@ -4018,55 +4015,55 @@
 	{value: 0x8100, lo: 0xa1, hi: 0xa1},
 	{value: 0x8100, lo: 0xb2, hi: 0xb2},
 	{value: 0x8100, lo: 0xbb, hi: 0xbb},
-	// Block 0x4e, offset 0x1a7
+	// Block 0x4d, offset 0x198
 	{value: 0x0000, lo: 0x03},
 	{value: 0x8100, lo: 0x80, hi: 0x80},
 	{value: 0x8100, lo: 0x8b, hi: 0x8b},
 	{value: 0x8100, lo: 0x8e, hi: 0x8e},
-	// Block 0x4f, offset 0x1ab
+	// Block 0x4e, offset 0x19c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0xaf, hi: 0xaf},
 	{value: 0x8132, lo: 0xb4, hi: 0xbd},
-	// Block 0x50, offset 0x1ae
+	// Block 0x4f, offset 0x19f
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0x9e, hi: 0x9f},
-	// Block 0x51, offset 0x1b0
+	// Block 0x50, offset 0x1a1
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb0, hi: 0xb1},
-	// Block 0x52, offset 0x1b2
+	// Block 0x51, offset 0x1a3
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x86, hi: 0x86},
-	// Block 0x53, offset 0x1b4
+	// Block 0x52, offset 0x1a5
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x84, hi: 0x84},
 	{value: 0x8132, lo: 0xa0, hi: 0xb1},
-	// Block 0x54, offset 0x1b7
+	// Block 0x53, offset 0x1a8
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xab, hi: 0xad},
-	// Block 0x55, offset 0x1b9
+	// Block 0x54, offset 0x1aa
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x93, hi: 0x93},
-	// Block 0x56, offset 0x1bb
+	// Block 0x55, offset 0x1ac
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0xb3, hi: 0xb3},
-	// Block 0x57, offset 0x1bd
+	// Block 0x56, offset 0x1ae
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x80, hi: 0x80},
-	// Block 0x58, offset 0x1bf
+	// Block 0x57, offset 0x1b0
 	{value: 0x0000, lo: 0x05},
 	{value: 0x8132, lo: 0xb0, hi: 0xb0},
 	{value: 0x8132, lo: 0xb2, hi: 0xb3},
 	{value: 0x812d, lo: 0xb4, hi: 0xb4},
 	{value: 0x8132, lo: 0xb7, hi: 0xb8},
 	{value: 0x8132, lo: 0xbe, hi: 0xbf},
-	// Block 0x59, offset 0x1c5
+	// Block 0x58, offset 0x1b6
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x81, hi: 0x81},
 	{value: 0x8104, lo: 0xb6, hi: 0xb6},
-	// Block 0x5a, offset 0x1c8
+	// Block 0x59, offset 0x1b9
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xad, hi: 0xad},
-	// Block 0x5b, offset 0x1ca
+	// Block 0x5a, offset 0x1bb
 	{value: 0x0000, lo: 0x06},
 	{value: 0xe500, lo: 0x80, hi: 0x80},
 	{value: 0xc600, lo: 0x81, hi: 0x9b},
@@ -4074,21 +4071,21 @@
 	{value: 0xc600, lo: 0x9d, hi: 0xb7},
 	{value: 0xe500, lo: 0xb8, hi: 0xb8},
 	{value: 0xc600, lo: 0xb9, hi: 0xbf},
-	// Block 0x5c, offset 0x1d1
+	// Block 0x5b, offset 0x1c2
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x93},
 	{value: 0xe500, lo: 0x94, hi: 0x94},
 	{value: 0xc600, lo: 0x95, hi: 0xaf},
 	{value: 0xe500, lo: 0xb0, hi: 0xb0},
 	{value: 0xc600, lo: 0xb1, hi: 0xbf},
-	// Block 0x5d, offset 0x1d7
+	// Block 0x5c, offset 0x1c8
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x8b},
 	{value: 0xe500, lo: 0x8c, hi: 0x8c},
 	{value: 0xc600, lo: 0x8d, hi: 0xa7},
 	{value: 0xe500, lo: 0xa8, hi: 0xa8},
 	{value: 0xc600, lo: 0xa9, hi: 0xbf},
-	// Block 0x5e, offset 0x1dd
+	// Block 0x5d, offset 0x1ce
 	{value: 0x0000, lo: 0x07},
 	{value: 0xc600, lo: 0x80, hi: 0x83},
 	{value: 0xe500, lo: 0x84, hi: 0x84},
@@ -4097,33 +4094,33 @@
 	{value: 0xc600, lo: 0xa1, hi: 0xbb},
 	{value: 0xe500, lo: 0xbc, hi: 0xbc},
 	{value: 0xc600, lo: 0xbd, hi: 0xbf},
-	// Block 0x5f, offset 0x1e5
+	// Block 0x5e, offset 0x1d6
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x97},
 	{value: 0xe500, lo: 0x98, hi: 0x98},
 	{value: 0xc600, lo: 0x99, hi: 0xb3},
 	{value: 0xe500, lo: 0xb4, hi: 0xb4},
 	{value: 0xc600, lo: 0xb5, hi: 0xbf},
-	// Block 0x60, offset 0x1eb
+	// Block 0x5f, offset 0x1dc
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x8f},
 	{value: 0xe500, lo: 0x90, hi: 0x90},
 	{value: 0xc600, lo: 0x91, hi: 0xab},
 	{value: 0xe500, lo: 0xac, hi: 0xac},
 	{value: 0xc600, lo: 0xad, hi: 0xbf},
-	// Block 0x61, offset 0x1f1
+	// Block 0x60, offset 0x1e2
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x87},
 	{value: 0xe500, lo: 0x88, hi: 0x88},
 	{value: 0xc600, lo: 0x89, hi: 0xa3},
 	{value: 0xe500, lo: 0xa4, hi: 0xa4},
 	{value: 0xc600, lo: 0xa5, hi: 0xbf},
-	// Block 0x62, offset 0x1f7
+	// Block 0x61, offset 0x1e8
 	{value: 0x0000, lo: 0x03},
 	{value: 0xc600, lo: 0x80, hi: 0x87},
 	{value: 0xe500, lo: 0x88, hi: 0x88},
 	{value: 0xc600, lo: 0x89, hi: 0xa3},
-	// Block 0x63, offset 0x1fb
+	// Block 0x62, offset 0x1ec
 	{value: 0x0006, lo: 0x0d},
 	{value: 0x4390, lo: 0x9d, hi: 0x9d},
 	{value: 0x8115, lo: 0x9e, hi: 0x9e},
@@ -4138,7 +4135,7 @@
 	{value: 0x4396, lo: 0xb9, hi: 0xbb},
 	{value: 0x43ae, lo: 0xbc, hi: 0xbc},
 	{value: 0x43b4, lo: 0xbe, hi: 0xbe},
-	// Block 0x64, offset 0x209
+	// Block 0x63, offset 0x1fa
 	{value: 0x0006, lo: 0x08},
 	{value: 0x43ba, lo: 0x80, hi: 0x81},
 	{value: 0x43c6, lo: 0x83, hi: 0x84},
@@ -4148,79 +4145,79 @@
 	{value: 0x4360, lo: 0x8c, hi: 0x8c},
 	{value: 0x43a8, lo: 0x8d, hi: 0x8d},
 	{value: 0x43d2, lo: 0x8e, hi: 0x8e},
-	// Block 0x65, offset 0x212
+	// Block 0x64, offset 0x203
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8100, lo: 0xa4, hi: 0xa5},
 	{value: 0x8100, lo: 0xb0, hi: 0xb1},
-	// Block 0x66, offset 0x215
+	// Block 0x65, offset 0x206
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8100, lo: 0x9b, hi: 0x9d},
 	{value: 0x8200, lo: 0x9e, hi: 0xa3},
-	// Block 0x67, offset 0x218
+	// Block 0x66, offset 0x209
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0x90, hi: 0x90},
-	// Block 0x68, offset 0x21a
+	// Block 0x67, offset 0x20b
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8100, lo: 0x99, hi: 0x99},
 	{value: 0x8200, lo: 0xb2, hi: 0xb4},
-	// Block 0x69, offset 0x21d
+	// Block 0x68, offset 0x20e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0xbc, hi: 0xbd},
-	// Block 0x6a, offset 0x21f
+	// Block 0x69, offset 0x210
 	{value: 0x0000, lo: 0x03},
 	{value: 0x8132, lo: 0xa0, hi: 0xa6},
 	{value: 0x812d, lo: 0xa7, hi: 0xad},
 	{value: 0x8132, lo: 0xae, hi: 0xaf},
-	// Block 0x6b, offset 0x223
+	// Block 0x6a, offset 0x214
 	{value: 0x0000, lo: 0x04},
 	{value: 0x8100, lo: 0x89, hi: 0x8c},
 	{value: 0x8100, lo: 0xb0, hi: 0xb2},
 	{value: 0x8100, lo: 0xb4, hi: 0xb4},
 	{value: 0x8100, lo: 0xb6, hi: 0xbf},
-	// Block 0x6c, offset 0x228
+	// Block 0x6b, offset 0x219
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0x81, hi: 0x8c},
-	// Block 0x6d, offset 0x22a
+	// Block 0x6c, offset 0x21b
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0xb5, hi: 0xba},
-	// Block 0x6e, offset 0x22c
+	// Block 0x6d, offset 0x21d
 	{value: 0x0000, lo: 0x04},
 	{value: 0x4a9f, lo: 0x9e, hi: 0x9f},
 	{value: 0x4a9f, lo: 0xa3, hi: 0xa3},
 	{value: 0x4a9f, lo: 0xa5, hi: 0xa6},
 	{value: 0x4a9f, lo: 0xaa, hi: 0xaf},
-	// Block 0x6f, offset 0x231
+	// Block 0x6e, offset 0x222
 	{value: 0x0000, lo: 0x05},
 	{value: 0x4a9f, lo: 0x82, hi: 0x87},
 	{value: 0x4a9f, lo: 0x8a, hi: 0x8f},
 	{value: 0x4a9f, lo: 0x92, hi: 0x97},
 	{value: 0x4a9f, lo: 0x9a, hi: 0x9c},
 	{value: 0x8100, lo: 0xa3, hi: 0xa3},
-	// Block 0x70, offset 0x237
+	// Block 0x6f, offset 0x228
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	// Block 0x71, offset 0x239
+	// Block 0x70, offset 0x22a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xa0, hi: 0xa0},
-	// Block 0x72, offset 0x23b
+	// Block 0x71, offset 0x22c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb6, hi: 0xba},
-	// Block 0x73, offset 0x23d
+	// Block 0x72, offset 0x22e
 	{value: 0x002c, lo: 0x05},
 	{value: 0x812d, lo: 0x8d, hi: 0x8d},
 	{value: 0x8132, lo: 0x8f, hi: 0x8f},
 	{value: 0x8132, lo: 0xb8, hi: 0xb8},
 	{value: 0x8101, lo: 0xb9, hi: 0xba},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x74, offset 0x243
+	// Block 0x73, offset 0x234
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0xa5, hi: 0xa5},
 	{value: 0x812d, lo: 0xa6, hi: 0xa6},
-	// Block 0x75, offset 0x246
+	// Block 0x74, offset 0x237
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x86, hi: 0x86},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x76, offset 0x249
+	// Block 0x75, offset 0x23a
 	{value: 0x17fe, lo: 0x07},
 	{value: 0xa000, lo: 0x99, hi: 0x99},
 	{value: 0x4238, lo: 0x9a, hi: 0x9a},
@@ -4229,7 +4226,7 @@
 	{value: 0xa000, lo: 0xa5, hi: 0xa5},
 	{value: 0x424c, lo: 0xab, hi: 0xab},
 	{value: 0x8104, lo: 0xb9, hi: 0xba},
-	// Block 0x77, offset 0x251
+	// Block 0x76, offset 0x242
 	{value: 0x0000, lo: 0x06},
 	{value: 0x8132, lo: 0x80, hi: 0x82},
 	{value: 0x9900, lo: 0xa7, hi: 0xa7},
@@ -4237,18 +4234,18 @@
 	{value: 0x2d88, lo: 0xaf, hi: 0xaf},
 	{value: 0xa000, lo: 0xb1, hi: 0xb2},
 	{value: 0x8104, lo: 0xb3, hi: 0xb4},
-	// Block 0x78, offset 0x258
+	// Block 0x77, offset 0x249
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x80, hi: 0x80},
 	{value: 0x8102, lo: 0x8a, hi: 0x8a},
-	// Block 0x79, offset 0x25b
+	// Block 0x78, offset 0x24c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0xb5, hi: 0xb5},
 	{value: 0x8102, lo: 0xb6, hi: 0xb6},
-	// Block 0x7a, offset 0x25e
+	// Block 0x79, offset 0x24f
 	{value: 0x0002, lo: 0x01},
 	{value: 0x8102, lo: 0xa9, hi: 0xaa},
-	// Block 0x7b, offset 0x260
+	// Block 0x7a, offset 0x251
 	{value: 0x0000, lo: 0x07},
 	{value: 0xa000, lo: 0x87, hi: 0x87},
 	{value: 0x2d92, lo: 0x8b, hi: 0x8b},
@@ -4257,11 +4254,11 @@
 	{value: 0x9900, lo: 0x97, hi: 0x97},
 	{value: 0x8132, lo: 0xa6, hi: 0xac},
 	{value: 0x8132, lo: 0xb0, hi: 0xb4},
-	// Block 0x7c, offset 0x268
+	// Block 0x7b, offset 0x259
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x82, hi: 0x82},
 	{value: 0x8102, lo: 0x86, hi: 0x86},
-	// Block 0x7d, offset 0x26b
+	// Block 0x7c, offset 0x25c
 	{value: 0x6b5a, lo: 0x06},
 	{value: 0x9900, lo: 0xb0, hi: 0xb0},
 	{value: 0xa000, lo: 0xb9, hi: 0xb9},
@@ -4269,37 +4266,50 @@
 	{value: 0x2db0, lo: 0xbb, hi: 0xbb},
 	{value: 0x2da6, lo: 0xbc, hi: 0xbd},
 	{value: 0x2dba, lo: 0xbe, hi: 0xbe},
-	// Block 0x7e, offset 0x272
+	// Block 0x7d, offset 0x263
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x82, hi: 0x82},
 	{value: 0x8102, lo: 0x83, hi: 0x83},
-	// Block 0x7f, offset 0x275
+	// Block 0x7e, offset 0x266
 	{value: 0x0000, lo: 0x05},
 	{value: 0x9900, lo: 0xaf, hi: 0xaf},
 	{value: 0xa000, lo: 0xb8, hi: 0xb9},
 	{value: 0x2dc4, lo: 0xba, hi: 0xba},
 	{value: 0x2dce, lo: 0xbb, hi: 0xbb},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x80, offset 0x27b
+	// Block 0x7f, offset 0x26c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0x80, hi: 0x80},
-	// Block 0x81, offset 0x27d
+	// Block 0x80, offset 0x26e
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0xb6, hi: 0xb6},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
-	// Block 0x82, offset 0x280
+	// Block 0x81, offset 0x271
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xab, hi: 0xab},
-	// Block 0x83, offset 0x282
+	// Block 0x82, offset 0x273
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0xb4, hi: 0xb4},
+	// Block 0x83, offset 0x275
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0x87, hi: 0x87},
+	// Block 0x84, offset 0x277
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0x99, hi: 0x99},
+	// Block 0x85, offset 0x279
+	{value: 0x0000, lo: 0x02},
+	{value: 0x8102, lo: 0x82, hi: 0x82},
+	{value: 0x8104, lo: 0x84, hi: 0x85},
+	// Block 0x86, offset 0x27c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8101, lo: 0xb0, hi: 0xb4},
-	// Block 0x84, offset 0x284
+	// Block 0x87, offset 0x27e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb0, hi: 0xb6},
-	// Block 0x85, offset 0x286
+	// Block 0x88, offset 0x280
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8101, lo: 0x9e, hi: 0x9e},
-	// Block 0x86, offset 0x288
+	// Block 0x89, offset 0x282
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x45cc, lo: 0x9e, hi: 0x9e},
 	{value: 0x45d6, lo: 0x9f, hi: 0x9f},
@@ -4313,7 +4323,7 @@
 	{value: 0x8130, lo: 0xad, hi: 0xad},
 	{value: 0x812b, lo: 0xae, hi: 0xb2},
 	{value: 0x812d, lo: 0xbb, hi: 0xbf},
-	// Block 0x87, offset 0x295
+	// Block 0x8a, offset 0x28f
 	{value: 0x0000, lo: 0x09},
 	{value: 0x812d, lo: 0x80, hi: 0x82},
 	{value: 0x8132, lo: 0x85, hi: 0x89},
@@ -4324,27 +4334,27 @@
 	{value: 0x4650, lo: 0xbd, hi: 0xbd},
 	{value: 0x466c, lo: 0xbe, hi: 0xbe},
 	{value: 0x465e, lo: 0xbf, hi: 0xbf},
-	// Block 0x88, offset 0x29f
+	// Block 0x8b, offset 0x299
 	{value: 0x0000, lo: 0x01},
 	{value: 0x467a, lo: 0x80, hi: 0x80},
-	// Block 0x89, offset 0x2a1
+	// Block 0x8c, offset 0x29b
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0x82, hi: 0x84},
-	// Block 0x8a, offset 0x2a3
+	// Block 0x8d, offset 0x29d
 	{value: 0x0000, lo: 0x05},
 	{value: 0x8132, lo: 0x80, hi: 0x86},
 	{value: 0x8132, lo: 0x88, hi: 0x98},
 	{value: 0x8132, lo: 0x9b, hi: 0xa1},
 	{value: 0x8132, lo: 0xa3, hi: 0xa4},
 	{value: 0x8132, lo: 0xa6, hi: 0xaa},
-	// Block 0x8b, offset 0x2a9
+	// Block 0x8e, offset 0x2a3
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x90, hi: 0x96},
-	// Block 0x8c, offset 0x2ab
+	// Block 0x8f, offset 0x2a5
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x84, hi: 0x89},
 	{value: 0x8102, lo: 0x8a, hi: 0x8a},
-	// Block 0x8d, offset 0x2ae
+	// Block 0x90, offset 0x2a8
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8100, lo: 0x93, hi: 0x93},
 }
@@ -4519,7 +4529,7 @@
 	return 0
 }
 
-// nfkcTrie. Total size: 16994 bytes (16.60 KiB). Checksum: c3ed54ee046f3c46.
+// nfkcTrie. Total size: 17104 bytes (16.70 KiB). Checksum: d985061cf5307b35.
 type nfkcTrie struct{}
 
 func newNfkcTrie(i int) *nfkcTrie {
@@ -4529,17 +4539,17 @@
 // lookupValue determines the type of block n and looks up the value for b.
 func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 {
 	switch {
-	case n < 90:
+	case n < 91:
 		return uint16(nfkcValues[n<<6+uint32(b)])
 	default:
-		n -= 90
+		n -= 91
 		return uint16(nfkcSparse.lookup(n, b))
 	}
 }
 
-// nfkcValues: 92 blocks, 5888 entries, 11776 bytes
+// nfkcValues: 93 blocks, 5952 entries, 11904 bytes
 // The third block is the zero block.
-var nfkcValues = [5888]uint16{
+var nfkcValues = [5952]uint16{
 	// Block 0x0, offset 0x0
 	0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
 	// Block 0x1, offset 0x40
@@ -4723,824 +4733,836 @@
 	0x4b6: 0x0152, 0x4b7: 0x0155, 0x4b8: 0x041f, 0x4b9: 0x0158, 0x4ba: 0x015b, 0x4bb: 0x00b5,
 	0x4bc: 0x015e, 0x4bd: 0x0161, 0x4be: 0x0164, 0x4bf: 0x01d0,
 	// Block 0x13, offset 0x4c0
-	0x4c0: 0x2f97, 0x4c1: 0x32a3, 0x4c2: 0x2fa1, 0x4c3: 0x32ad, 0x4c4: 0x2fa6, 0x4c5: 0x32b2,
-	0x4c6: 0x2fab, 0x4c7: 0x32b7, 0x4c8: 0x38cc, 0x4c9: 0x3a5b, 0x4ca: 0x2fc4, 0x4cb: 0x32d0,
-	0x4cc: 0x2fce, 0x4cd: 0x32da, 0x4ce: 0x2fdd, 0x4cf: 0x32e9, 0x4d0: 0x2fd3, 0x4d1: 0x32df,
-	0x4d2: 0x2fd8, 0x4d3: 0x32e4, 0x4d4: 0x38ef, 0x4d5: 0x3a7e, 0x4d6: 0x38f6, 0x4d7: 0x3a85,
-	0x4d8: 0x3019, 0x4d9: 0x3325, 0x4da: 0x301e, 0x4db: 0x332a, 0x4dc: 0x3904, 0x4dd: 0x3a93,
-	0x4de: 0x3023, 0x4df: 0x332f, 0x4e0: 0x3032, 0x4e1: 0x333e, 0x4e2: 0x3050, 0x4e3: 0x335c,
-	0x4e4: 0x305f, 0x4e5: 0x336b, 0x4e6: 0x3055, 0x4e7: 0x3361, 0x4e8: 0x3064, 0x4e9: 0x3370,
-	0x4ea: 0x3069, 0x4eb: 0x3375, 0x4ec: 0x30af, 0x4ed: 0x33bb, 0x4ee: 0x390b, 0x4ef: 0x3a9a,
-	0x4f0: 0x30b9, 0x4f1: 0x33ca, 0x4f2: 0x30c3, 0x4f3: 0x33d4, 0x4f4: 0x30cd, 0x4f5: 0x33de,
-	0x4f6: 0x46c4, 0x4f7: 0x4755, 0x4f8: 0x3912, 0x4f9: 0x3aa1, 0x4fa: 0x30e6, 0x4fb: 0x33f7,
-	0x4fc: 0x30e1, 0x4fd: 0x33f2, 0x4fe: 0x30eb, 0x4ff: 0x33fc,
+	0x4c0: 0x8132, 0x4c1: 0x8132, 0x4c2: 0x812d, 0x4c3: 0x8132, 0x4c4: 0x8132, 0x4c5: 0x8132,
+	0x4c6: 0x8132, 0x4c7: 0x8132, 0x4c8: 0x8132, 0x4c9: 0x8132, 0x4ca: 0x812d, 0x4cb: 0x8132,
+	0x4cc: 0x8132, 0x4cd: 0x8135, 0x4ce: 0x812a, 0x4cf: 0x812d, 0x4d0: 0x8129, 0x4d1: 0x8132,
+	0x4d2: 0x8132, 0x4d3: 0x8132, 0x4d4: 0x8132, 0x4d5: 0x8132, 0x4d6: 0x8132, 0x4d7: 0x8132,
+	0x4d8: 0x8132, 0x4d9: 0x8132, 0x4da: 0x8132, 0x4db: 0x8132, 0x4dc: 0x8132, 0x4dd: 0x8132,
+	0x4de: 0x8132, 0x4df: 0x8132, 0x4e0: 0x8132, 0x4e1: 0x8132, 0x4e2: 0x8132, 0x4e3: 0x8132,
+	0x4e4: 0x8132, 0x4e5: 0x8132, 0x4e6: 0x8132, 0x4e7: 0x8132, 0x4e8: 0x8132, 0x4e9: 0x8132,
+	0x4ea: 0x8132, 0x4eb: 0x8132, 0x4ec: 0x8132, 0x4ed: 0x8132, 0x4ee: 0x8132, 0x4ef: 0x8132,
+	0x4f0: 0x8132, 0x4f1: 0x8132, 0x4f2: 0x8132, 0x4f3: 0x8132, 0x4f4: 0x8132, 0x4f5: 0x8132,
+	0x4f6: 0x8133, 0x4f7: 0x8131, 0x4f8: 0x8131, 0x4f9: 0x812d, 0x4fb: 0x8132,
+	0x4fc: 0x8134, 0x4fd: 0x812d, 0x4fe: 0x8132, 0x4ff: 0x812d,
 	// Block 0x14, offset 0x500
-	0x500: 0x30f0, 0x501: 0x3401, 0x502: 0x30f5, 0x503: 0x3406, 0x504: 0x3109, 0x505: 0x341a,
-	0x506: 0x3113, 0x507: 0x3424, 0x508: 0x3122, 0x509: 0x3433, 0x50a: 0x311d, 0x50b: 0x342e,
-	0x50c: 0x3935, 0x50d: 0x3ac4, 0x50e: 0x3943, 0x50f: 0x3ad2, 0x510: 0x394a, 0x511: 0x3ad9,
-	0x512: 0x3951, 0x513: 0x3ae0, 0x514: 0x314f, 0x515: 0x3460, 0x516: 0x3154, 0x517: 0x3465,
-	0x518: 0x315e, 0x519: 0x346f, 0x51a: 0x46f1, 0x51b: 0x4782, 0x51c: 0x3997, 0x51d: 0x3b26,
-	0x51e: 0x3177, 0x51f: 0x3488, 0x520: 0x3181, 0x521: 0x3492, 0x522: 0x4700, 0x523: 0x4791,
-	0x524: 0x399e, 0x525: 0x3b2d, 0x526: 0x39a5, 0x527: 0x3b34, 0x528: 0x39ac, 0x529: 0x3b3b,
-	0x52a: 0x3190, 0x52b: 0x34a1, 0x52c: 0x319a, 0x52d: 0x34b0, 0x52e: 0x31ae, 0x52f: 0x34c4,
-	0x530: 0x31a9, 0x531: 0x34bf, 0x532: 0x31ea, 0x533: 0x3500, 0x534: 0x31f9, 0x535: 0x350f,
-	0x536: 0x31f4, 0x537: 0x350a, 0x538: 0x39b3, 0x539: 0x3b42, 0x53a: 0x39ba, 0x53b: 0x3b49,
-	0x53c: 0x31fe, 0x53d: 0x3514, 0x53e: 0x3203, 0x53f: 0x3519,
+	0x500: 0x2f97, 0x501: 0x32a3, 0x502: 0x2fa1, 0x503: 0x32ad, 0x504: 0x2fa6, 0x505: 0x32b2,
+	0x506: 0x2fab, 0x507: 0x32b7, 0x508: 0x38cc, 0x509: 0x3a5b, 0x50a: 0x2fc4, 0x50b: 0x32d0,
+	0x50c: 0x2fce, 0x50d: 0x32da, 0x50e: 0x2fdd, 0x50f: 0x32e9, 0x510: 0x2fd3, 0x511: 0x32df,
+	0x512: 0x2fd8, 0x513: 0x32e4, 0x514: 0x38ef, 0x515: 0x3a7e, 0x516: 0x38f6, 0x517: 0x3a85,
+	0x518: 0x3019, 0x519: 0x3325, 0x51a: 0x301e, 0x51b: 0x332a, 0x51c: 0x3904, 0x51d: 0x3a93,
+	0x51e: 0x3023, 0x51f: 0x332f, 0x520: 0x3032, 0x521: 0x333e, 0x522: 0x3050, 0x523: 0x335c,
+	0x524: 0x305f, 0x525: 0x336b, 0x526: 0x3055, 0x527: 0x3361, 0x528: 0x3064, 0x529: 0x3370,
+	0x52a: 0x3069, 0x52b: 0x3375, 0x52c: 0x30af, 0x52d: 0x33bb, 0x52e: 0x390b, 0x52f: 0x3a9a,
+	0x530: 0x30b9, 0x531: 0x33ca, 0x532: 0x30c3, 0x533: 0x33d4, 0x534: 0x30cd, 0x535: 0x33de,
+	0x536: 0x46c4, 0x537: 0x4755, 0x538: 0x3912, 0x539: 0x3aa1, 0x53a: 0x30e6, 0x53b: 0x33f7,
+	0x53c: 0x30e1, 0x53d: 0x33f2, 0x53e: 0x30eb, 0x53f: 0x33fc,
 	// Block 0x15, offset 0x540
-	0x540: 0x3208, 0x541: 0x351e, 0x542: 0x320d, 0x543: 0x3523, 0x544: 0x321c, 0x545: 0x3532,
-	0x546: 0x3217, 0x547: 0x352d, 0x548: 0x3221, 0x549: 0x353c, 0x54a: 0x3226, 0x54b: 0x3541,
-	0x54c: 0x322b, 0x54d: 0x3546, 0x54e: 0x3249, 0x54f: 0x3564, 0x550: 0x3262, 0x551: 0x3582,
-	0x552: 0x3271, 0x553: 0x3591, 0x554: 0x3276, 0x555: 0x3596, 0x556: 0x337a, 0x557: 0x34a6,
-	0x558: 0x3537, 0x559: 0x3573, 0x55a: 0x1be0, 0x55b: 0x42d7,
-	0x560: 0x46a1, 0x561: 0x4732, 0x562: 0x2f83, 0x563: 0x328f,
-	0x564: 0x3878, 0x565: 0x3a07, 0x566: 0x3871, 0x567: 0x3a00, 0x568: 0x3886, 0x569: 0x3a15,
-	0x56a: 0x387f, 0x56b: 0x3a0e, 0x56c: 0x38be, 0x56d: 0x3a4d, 0x56e: 0x3894, 0x56f: 0x3a23,
-	0x570: 0x388d, 0x571: 0x3a1c, 0x572: 0x38a2, 0x573: 0x3a31, 0x574: 0x389b, 0x575: 0x3a2a,
-	0x576: 0x38c5, 0x577: 0x3a54, 0x578: 0x46b5, 0x579: 0x4746, 0x57a: 0x3000, 0x57b: 0x330c,
-	0x57c: 0x2fec, 0x57d: 0x32f8, 0x57e: 0x38da, 0x57f: 0x3a69,
+	0x540: 0x30f0, 0x541: 0x3401, 0x542: 0x30f5, 0x543: 0x3406, 0x544: 0x3109, 0x545: 0x341a,
+	0x546: 0x3113, 0x547: 0x3424, 0x548: 0x3122, 0x549: 0x3433, 0x54a: 0x311d, 0x54b: 0x342e,
+	0x54c: 0x3935, 0x54d: 0x3ac4, 0x54e: 0x3943, 0x54f: 0x3ad2, 0x550: 0x394a, 0x551: 0x3ad9,
+	0x552: 0x3951, 0x553: 0x3ae0, 0x554: 0x314f, 0x555: 0x3460, 0x556: 0x3154, 0x557: 0x3465,
+	0x558: 0x315e, 0x559: 0x346f, 0x55a: 0x46f1, 0x55b: 0x4782, 0x55c: 0x3997, 0x55d: 0x3b26,
+	0x55e: 0x3177, 0x55f: 0x3488, 0x560: 0x3181, 0x561: 0x3492, 0x562: 0x4700, 0x563: 0x4791,
+	0x564: 0x399e, 0x565: 0x3b2d, 0x566: 0x39a5, 0x567: 0x3b34, 0x568: 0x39ac, 0x569: 0x3b3b,
+	0x56a: 0x3190, 0x56b: 0x34a1, 0x56c: 0x319a, 0x56d: 0x34b0, 0x56e: 0x31ae, 0x56f: 0x34c4,
+	0x570: 0x31a9, 0x571: 0x34bf, 0x572: 0x31ea, 0x573: 0x3500, 0x574: 0x31f9, 0x575: 0x350f,
+	0x576: 0x31f4, 0x577: 0x350a, 0x578: 0x39b3, 0x579: 0x3b42, 0x57a: 0x39ba, 0x57b: 0x3b49,
+	0x57c: 0x31fe, 0x57d: 0x3514, 0x57e: 0x3203, 0x57f: 0x3519,
 	// Block 0x16, offset 0x580
-	0x580: 0x38d3, 0x581: 0x3a62, 0x582: 0x38e8, 0x583: 0x3a77, 0x584: 0x38e1, 0x585: 0x3a70,
-	0x586: 0x38fd, 0x587: 0x3a8c, 0x588: 0x3091, 0x589: 0x339d, 0x58a: 0x30a5, 0x58b: 0x33b1,
-	0x58c: 0x46e7, 0x58d: 0x4778, 0x58e: 0x3136, 0x58f: 0x3447, 0x590: 0x3920, 0x591: 0x3aaf,
-	0x592: 0x3919, 0x593: 0x3aa8, 0x594: 0x392e, 0x595: 0x3abd, 0x596: 0x3927, 0x597: 0x3ab6,
-	0x598: 0x3989, 0x599: 0x3b18, 0x59a: 0x396d, 0x59b: 0x3afc, 0x59c: 0x3966, 0x59d: 0x3af5,
-	0x59e: 0x397b, 0x59f: 0x3b0a, 0x5a0: 0x3974, 0x5a1: 0x3b03, 0x5a2: 0x3982, 0x5a3: 0x3b11,
-	0x5a4: 0x31e5, 0x5a5: 0x34fb, 0x5a6: 0x31c7, 0x5a7: 0x34dd, 0x5a8: 0x39e4, 0x5a9: 0x3b73,
-	0x5aa: 0x39dd, 0x5ab: 0x3b6c, 0x5ac: 0x39f2, 0x5ad: 0x3b81, 0x5ae: 0x39eb, 0x5af: 0x3b7a,
-	0x5b0: 0x39f9, 0x5b1: 0x3b88, 0x5b2: 0x3230, 0x5b3: 0x354b, 0x5b4: 0x3258, 0x5b5: 0x3578,
-	0x5b6: 0x3253, 0x5b7: 0x356e, 0x5b8: 0x323f, 0x5b9: 0x355a,
+	0x580: 0x3208, 0x581: 0x351e, 0x582: 0x320d, 0x583: 0x3523, 0x584: 0x321c, 0x585: 0x3532,
+	0x586: 0x3217, 0x587: 0x352d, 0x588: 0x3221, 0x589: 0x353c, 0x58a: 0x3226, 0x58b: 0x3541,
+	0x58c: 0x322b, 0x58d: 0x3546, 0x58e: 0x3249, 0x58f: 0x3564, 0x590: 0x3262, 0x591: 0x3582,
+	0x592: 0x3271, 0x593: 0x3591, 0x594: 0x3276, 0x595: 0x3596, 0x596: 0x337a, 0x597: 0x34a6,
+	0x598: 0x3537, 0x599: 0x3573, 0x59a: 0x1be0, 0x59b: 0x42d7,
+	0x5a0: 0x46a1, 0x5a1: 0x4732, 0x5a2: 0x2f83, 0x5a3: 0x328f,
+	0x5a4: 0x3878, 0x5a5: 0x3a07, 0x5a6: 0x3871, 0x5a7: 0x3a00, 0x5a8: 0x3886, 0x5a9: 0x3a15,
+	0x5aa: 0x387f, 0x5ab: 0x3a0e, 0x5ac: 0x38be, 0x5ad: 0x3a4d, 0x5ae: 0x3894, 0x5af: 0x3a23,
+	0x5b0: 0x388d, 0x5b1: 0x3a1c, 0x5b2: 0x38a2, 0x5b3: 0x3a31, 0x5b4: 0x389b, 0x5b5: 0x3a2a,
+	0x5b6: 0x38c5, 0x5b7: 0x3a54, 0x5b8: 0x46b5, 0x5b9: 0x4746, 0x5ba: 0x3000, 0x5bb: 0x330c,
+	0x5bc: 0x2fec, 0x5bd: 0x32f8, 0x5be: 0x38da, 0x5bf: 0x3a69,
 	// Block 0x17, offset 0x5c0
-	0x5c0: 0x4804, 0x5c1: 0x480a, 0x5c2: 0x491e, 0x5c3: 0x4936, 0x5c4: 0x4926, 0x5c5: 0x493e,
-	0x5c6: 0x492e, 0x5c7: 0x4946, 0x5c8: 0x47aa, 0x5c9: 0x47b0, 0x5ca: 0x488e, 0x5cb: 0x48a6,
-	0x5cc: 0x4896, 0x5cd: 0x48ae, 0x5ce: 0x489e, 0x5cf: 0x48b6, 0x5d0: 0x4816, 0x5d1: 0x481c,
-	0x5d2: 0x3db8, 0x5d3: 0x3dc8, 0x5d4: 0x3dc0, 0x5d5: 0x3dd0,
-	0x5d8: 0x47b6, 0x5d9: 0x47bc, 0x5da: 0x3ce8, 0x5db: 0x3cf8, 0x5dc: 0x3cf0, 0x5dd: 0x3d00,
-	0x5e0: 0x482e, 0x5e1: 0x4834, 0x5e2: 0x494e, 0x5e3: 0x4966,
-	0x5e4: 0x4956, 0x5e5: 0x496e, 0x5e6: 0x495e, 0x5e7: 0x4976, 0x5e8: 0x47c2, 0x5e9: 0x47c8,
-	0x5ea: 0x48be, 0x5eb: 0x48d6, 0x5ec: 0x48c6, 0x5ed: 0x48de, 0x5ee: 0x48ce, 0x5ef: 0x48e6,
-	0x5f0: 0x4846, 0x5f1: 0x484c, 0x5f2: 0x3e18, 0x5f3: 0x3e30, 0x5f4: 0x3e20, 0x5f5: 0x3e38,
-	0x5f6: 0x3e28, 0x5f7: 0x3e40, 0x5f8: 0x47ce, 0x5f9: 0x47d4, 0x5fa: 0x3d18, 0x5fb: 0x3d30,
-	0x5fc: 0x3d20, 0x5fd: 0x3d38, 0x5fe: 0x3d28, 0x5ff: 0x3d40,
+	0x5c0: 0x38d3, 0x5c1: 0x3a62, 0x5c2: 0x38e8, 0x5c3: 0x3a77, 0x5c4: 0x38e1, 0x5c5: 0x3a70,
+	0x5c6: 0x38fd, 0x5c7: 0x3a8c, 0x5c8: 0x3091, 0x5c9: 0x339d, 0x5ca: 0x30a5, 0x5cb: 0x33b1,
+	0x5cc: 0x46e7, 0x5cd: 0x4778, 0x5ce: 0x3136, 0x5cf: 0x3447, 0x5d0: 0x3920, 0x5d1: 0x3aaf,
+	0x5d2: 0x3919, 0x5d3: 0x3aa8, 0x5d4: 0x392e, 0x5d5: 0x3abd, 0x5d6: 0x3927, 0x5d7: 0x3ab6,
+	0x5d8: 0x3989, 0x5d9: 0x3b18, 0x5da: 0x396d, 0x5db: 0x3afc, 0x5dc: 0x3966, 0x5dd: 0x3af5,
+	0x5de: 0x397b, 0x5df: 0x3b0a, 0x5e0: 0x3974, 0x5e1: 0x3b03, 0x5e2: 0x3982, 0x5e3: 0x3b11,
+	0x5e4: 0x31e5, 0x5e5: 0x34fb, 0x5e6: 0x31c7, 0x5e7: 0x34dd, 0x5e8: 0x39e4, 0x5e9: 0x3b73,
+	0x5ea: 0x39dd, 0x5eb: 0x3b6c, 0x5ec: 0x39f2, 0x5ed: 0x3b81, 0x5ee: 0x39eb, 0x5ef: 0x3b7a,
+	0x5f0: 0x39f9, 0x5f1: 0x3b88, 0x5f2: 0x3230, 0x5f3: 0x354b, 0x5f4: 0x3258, 0x5f5: 0x3578,
+	0x5f6: 0x3253, 0x5f7: 0x356e, 0x5f8: 0x323f, 0x5f9: 0x355a,
 	// Block 0x18, offset 0x600
-	0x600: 0x4852, 0x601: 0x4858, 0x602: 0x3e48, 0x603: 0x3e58, 0x604: 0x3e50, 0x605: 0x3e60,
-	0x608: 0x47da, 0x609: 0x47e0, 0x60a: 0x3d48, 0x60b: 0x3d58,
-	0x60c: 0x3d50, 0x60d: 0x3d60, 0x610: 0x4864, 0x611: 0x486a,
-	0x612: 0x3e80, 0x613: 0x3e98, 0x614: 0x3e88, 0x615: 0x3ea0, 0x616: 0x3e90, 0x617: 0x3ea8,
-	0x619: 0x47e6, 0x61b: 0x3d68, 0x61d: 0x3d70,
-	0x61f: 0x3d78, 0x620: 0x487c, 0x621: 0x4882, 0x622: 0x497e, 0x623: 0x4996,
-	0x624: 0x4986, 0x625: 0x499e, 0x626: 0x498e, 0x627: 0x49a6, 0x628: 0x47ec, 0x629: 0x47f2,
-	0x62a: 0x48ee, 0x62b: 0x4906, 0x62c: 0x48f6, 0x62d: 0x490e, 0x62e: 0x48fe, 0x62f: 0x4916,
-	0x630: 0x47f8, 0x631: 0x431e, 0x632: 0x3691, 0x633: 0x4324, 0x634: 0x4822, 0x635: 0x432a,
-	0x636: 0x36a3, 0x637: 0x4330, 0x638: 0x36c1, 0x639: 0x4336, 0x63a: 0x36d9, 0x63b: 0x433c,
-	0x63c: 0x4870, 0x63d: 0x4342,
+	0x600: 0x4804, 0x601: 0x480a, 0x602: 0x491e, 0x603: 0x4936, 0x604: 0x4926, 0x605: 0x493e,
+	0x606: 0x492e, 0x607: 0x4946, 0x608: 0x47aa, 0x609: 0x47b0, 0x60a: 0x488e, 0x60b: 0x48a6,
+	0x60c: 0x4896, 0x60d: 0x48ae, 0x60e: 0x489e, 0x60f: 0x48b6, 0x610: 0x4816, 0x611: 0x481c,
+	0x612: 0x3db8, 0x613: 0x3dc8, 0x614: 0x3dc0, 0x615: 0x3dd0,
+	0x618: 0x47b6, 0x619: 0x47bc, 0x61a: 0x3ce8, 0x61b: 0x3cf8, 0x61c: 0x3cf0, 0x61d: 0x3d00,
+	0x620: 0x482e, 0x621: 0x4834, 0x622: 0x494e, 0x623: 0x4966,
+	0x624: 0x4956, 0x625: 0x496e, 0x626: 0x495e, 0x627: 0x4976, 0x628: 0x47c2, 0x629: 0x47c8,
+	0x62a: 0x48be, 0x62b: 0x48d6, 0x62c: 0x48c6, 0x62d: 0x48de, 0x62e: 0x48ce, 0x62f: 0x48e6,
+	0x630: 0x4846, 0x631: 0x484c, 0x632: 0x3e18, 0x633: 0x3e30, 0x634: 0x3e20, 0x635: 0x3e38,
+	0x636: 0x3e28, 0x637: 0x3e40, 0x638: 0x47ce, 0x639: 0x47d4, 0x63a: 0x3d18, 0x63b: 0x3d30,
+	0x63c: 0x3d20, 0x63d: 0x3d38, 0x63e: 0x3d28, 0x63f: 0x3d40,
 	// Block 0x19, offset 0x640
-	0x640: 0x3da0, 0x641: 0x3da8, 0x642: 0x4184, 0x643: 0x41a2, 0x644: 0x418e, 0x645: 0x41ac,
-	0x646: 0x4198, 0x647: 0x41b6, 0x648: 0x3cd8, 0x649: 0x3ce0, 0x64a: 0x40d0, 0x64b: 0x40ee,
-	0x64c: 0x40da, 0x64d: 0x40f8, 0x64e: 0x40e4, 0x64f: 0x4102, 0x650: 0x3de8, 0x651: 0x3df0,
-	0x652: 0x41c0, 0x653: 0x41de, 0x654: 0x41ca, 0x655: 0x41e8, 0x656: 0x41d4, 0x657: 0x41f2,
-	0x658: 0x3d08, 0x659: 0x3d10, 0x65a: 0x410c, 0x65b: 0x412a, 0x65c: 0x4116, 0x65d: 0x4134,
-	0x65e: 0x4120, 0x65f: 0x413e, 0x660: 0x3ec0, 0x661: 0x3ec8, 0x662: 0x41fc, 0x663: 0x421a,
-	0x664: 0x4206, 0x665: 0x4224, 0x666: 0x4210, 0x667: 0x422e, 0x668: 0x3d80, 0x669: 0x3d88,
-	0x66a: 0x4148, 0x66b: 0x4166, 0x66c: 0x4152, 0x66d: 0x4170, 0x66e: 0x415c, 0x66f: 0x417a,
-	0x670: 0x3685, 0x671: 0x367f, 0x672: 0x3d90, 0x673: 0x368b, 0x674: 0x3d98,
-	0x676: 0x4810, 0x677: 0x3db0, 0x678: 0x35f5, 0x679: 0x35ef, 0x67a: 0x35e3, 0x67b: 0x42ee,
-	0x67c: 0x35fb, 0x67d: 0x4287, 0x67e: 0x01d3, 0x67f: 0x4287,
+	0x640: 0x4852, 0x641: 0x4858, 0x642: 0x3e48, 0x643: 0x3e58, 0x644: 0x3e50, 0x645: 0x3e60,
+	0x648: 0x47da, 0x649: 0x47e0, 0x64a: 0x3d48, 0x64b: 0x3d58,
+	0x64c: 0x3d50, 0x64d: 0x3d60, 0x650: 0x4864, 0x651: 0x486a,
+	0x652: 0x3e80, 0x653: 0x3e98, 0x654: 0x3e88, 0x655: 0x3ea0, 0x656: 0x3e90, 0x657: 0x3ea8,
+	0x659: 0x47e6, 0x65b: 0x3d68, 0x65d: 0x3d70,
+	0x65f: 0x3d78, 0x660: 0x487c, 0x661: 0x4882, 0x662: 0x497e, 0x663: 0x4996,
+	0x664: 0x4986, 0x665: 0x499e, 0x666: 0x498e, 0x667: 0x49a6, 0x668: 0x47ec, 0x669: 0x47f2,
+	0x66a: 0x48ee, 0x66b: 0x4906, 0x66c: 0x48f6, 0x66d: 0x490e, 0x66e: 0x48fe, 0x66f: 0x4916,
+	0x670: 0x47f8, 0x671: 0x431e, 0x672: 0x3691, 0x673: 0x4324, 0x674: 0x4822, 0x675: 0x432a,
+	0x676: 0x36a3, 0x677: 0x4330, 0x678: 0x36c1, 0x679: 0x4336, 0x67a: 0x36d9, 0x67b: 0x433c,
+	0x67c: 0x4870, 0x67d: 0x4342,
 	// Block 0x1a, offset 0x680
-	0x680: 0x42a0, 0x681: 0x4482, 0x682: 0x3dd8, 0x683: 0x369d, 0x684: 0x3de0,
-	0x686: 0x483a, 0x687: 0x3df8, 0x688: 0x3601, 0x689: 0x42f4, 0x68a: 0x360d, 0x68b: 0x42fa,
-	0x68c: 0x3619, 0x68d: 0x4489, 0x68e: 0x4490, 0x68f: 0x4497, 0x690: 0x36b5, 0x691: 0x36af,
-	0x692: 0x3e00, 0x693: 0x44e4, 0x696: 0x36bb, 0x697: 0x3e10,
-	0x698: 0x3631, 0x699: 0x362b, 0x69a: 0x361f, 0x69b: 0x4300, 0x69d: 0x449e,
-	0x69e: 0x44a5, 0x69f: 0x44ac, 0x6a0: 0x36eb, 0x6a1: 0x36e5, 0x6a2: 0x3e68, 0x6a3: 0x44ec,
-	0x6a4: 0x36cd, 0x6a5: 0x36d3, 0x6a6: 0x36f1, 0x6a7: 0x3e78, 0x6a8: 0x3661, 0x6a9: 0x365b,
-	0x6aa: 0x364f, 0x6ab: 0x430c, 0x6ac: 0x3649, 0x6ad: 0x4474, 0x6ae: 0x447b, 0x6af: 0x0081,
-	0x6b2: 0x3eb0, 0x6b3: 0x36f7, 0x6b4: 0x3eb8,
-	0x6b6: 0x4888, 0x6b7: 0x3ed0, 0x6b8: 0x363d, 0x6b9: 0x4306, 0x6ba: 0x366d, 0x6bb: 0x4318,
-	0x6bc: 0x3679, 0x6bd: 0x425a, 0x6be: 0x428c,
+	0x680: 0x3da0, 0x681: 0x3da8, 0x682: 0x4184, 0x683: 0x41a2, 0x684: 0x418e, 0x685: 0x41ac,
+	0x686: 0x4198, 0x687: 0x41b6, 0x688: 0x3cd8, 0x689: 0x3ce0, 0x68a: 0x40d0, 0x68b: 0x40ee,
+	0x68c: 0x40da, 0x68d: 0x40f8, 0x68e: 0x40e4, 0x68f: 0x4102, 0x690: 0x3de8, 0x691: 0x3df0,
+	0x692: 0x41c0, 0x693: 0x41de, 0x694: 0x41ca, 0x695: 0x41e8, 0x696: 0x41d4, 0x697: 0x41f2,
+	0x698: 0x3d08, 0x699: 0x3d10, 0x69a: 0x410c, 0x69b: 0x412a, 0x69c: 0x4116, 0x69d: 0x4134,
+	0x69e: 0x4120, 0x69f: 0x413e, 0x6a0: 0x3ec0, 0x6a1: 0x3ec8, 0x6a2: 0x41fc, 0x6a3: 0x421a,
+	0x6a4: 0x4206, 0x6a5: 0x4224, 0x6a6: 0x4210, 0x6a7: 0x422e, 0x6a8: 0x3d80, 0x6a9: 0x3d88,
+	0x6aa: 0x4148, 0x6ab: 0x4166, 0x6ac: 0x4152, 0x6ad: 0x4170, 0x6ae: 0x415c, 0x6af: 0x417a,
+	0x6b0: 0x3685, 0x6b1: 0x367f, 0x6b2: 0x3d90, 0x6b3: 0x368b, 0x6b4: 0x3d98,
+	0x6b6: 0x4810, 0x6b7: 0x3db0, 0x6b8: 0x35f5, 0x6b9: 0x35ef, 0x6ba: 0x35e3, 0x6bb: 0x42ee,
+	0x6bc: 0x35fb, 0x6bd: 0x4287, 0x6be: 0x01d3, 0x6bf: 0x4287,
 	// Block 0x1b, offset 0x6c0
-	0x6c0: 0x1bd8, 0x6c1: 0x1bdc, 0x6c2: 0x0047, 0x6c3: 0x1c54, 0x6c5: 0x1be8,
-	0x6c6: 0x1bec, 0x6c7: 0x00e9, 0x6c9: 0x1c58, 0x6ca: 0x008f, 0x6cb: 0x0051,
-	0x6cc: 0x0051, 0x6cd: 0x0051, 0x6ce: 0x0091, 0x6cf: 0x00da, 0x6d0: 0x0053, 0x6d1: 0x0053,
-	0x6d2: 0x0059, 0x6d3: 0x0099, 0x6d5: 0x005d, 0x6d6: 0x198d,
-	0x6d9: 0x0061, 0x6da: 0x0063, 0x6db: 0x0065, 0x6dc: 0x0065, 0x6dd: 0x0065,
-	0x6e0: 0x199f, 0x6e1: 0x1bc8, 0x6e2: 0x19a8,
-	0x6e4: 0x0075, 0x6e6: 0x01b8, 0x6e8: 0x0075,
-	0x6ea: 0x0057, 0x6eb: 0x42d2, 0x6ec: 0x0045, 0x6ed: 0x0047, 0x6ef: 0x008b,
-	0x6f0: 0x004b, 0x6f1: 0x004d, 0x6f3: 0x005b, 0x6f4: 0x009f, 0x6f5: 0x0215,
-	0x6f6: 0x0218, 0x6f7: 0x021b, 0x6f8: 0x021e, 0x6f9: 0x0093, 0x6fb: 0x1b98,
-	0x6fc: 0x01e8, 0x6fd: 0x01c1, 0x6fe: 0x0179, 0x6ff: 0x01a0,
+	0x6c0: 0x42a0, 0x6c1: 0x4482, 0x6c2: 0x3dd8, 0x6c3: 0x369d, 0x6c4: 0x3de0,
+	0x6c6: 0x483a, 0x6c7: 0x3df8, 0x6c8: 0x3601, 0x6c9: 0x42f4, 0x6ca: 0x360d, 0x6cb: 0x42fa,
+	0x6cc: 0x3619, 0x6cd: 0x4489, 0x6ce: 0x4490, 0x6cf: 0x4497, 0x6d0: 0x36b5, 0x6d1: 0x36af,
+	0x6d2: 0x3e00, 0x6d3: 0x44e4, 0x6d6: 0x36bb, 0x6d7: 0x3e10,
+	0x6d8: 0x3631, 0x6d9: 0x362b, 0x6da: 0x361f, 0x6db: 0x4300, 0x6dd: 0x449e,
+	0x6de: 0x44a5, 0x6df: 0x44ac, 0x6e0: 0x36eb, 0x6e1: 0x36e5, 0x6e2: 0x3e68, 0x6e3: 0x44ec,
+	0x6e4: 0x36cd, 0x6e5: 0x36d3, 0x6e6: 0x36f1, 0x6e7: 0x3e78, 0x6e8: 0x3661, 0x6e9: 0x365b,
+	0x6ea: 0x364f, 0x6eb: 0x430c, 0x6ec: 0x3649, 0x6ed: 0x4474, 0x6ee: 0x447b, 0x6ef: 0x0081,
+	0x6f2: 0x3eb0, 0x6f3: 0x36f7, 0x6f4: 0x3eb8,
+	0x6f6: 0x4888, 0x6f7: 0x3ed0, 0x6f8: 0x363d, 0x6f9: 0x4306, 0x6fa: 0x366d, 0x6fb: 0x4318,
+	0x6fc: 0x3679, 0x6fd: 0x425a, 0x6fe: 0x428c,
 	// Block 0x1c, offset 0x700
-	0x700: 0x0463, 0x705: 0x0049,
-	0x706: 0x0089, 0x707: 0x008b, 0x708: 0x0093, 0x709: 0x0095,
-	0x710: 0x222e, 0x711: 0x223a,
-	0x712: 0x22ee, 0x713: 0x2216, 0x714: 0x229a, 0x715: 0x2222, 0x716: 0x22a0, 0x717: 0x22b8,
-	0x718: 0x22c4, 0x719: 0x2228, 0x71a: 0x22ca, 0x71b: 0x2234, 0x71c: 0x22be, 0x71d: 0x22d0,
-	0x71e: 0x22d6, 0x71f: 0x1cbc, 0x720: 0x0053, 0x721: 0x195a, 0x722: 0x1ba4, 0x723: 0x1963,
-	0x724: 0x006d, 0x725: 0x19ab, 0x726: 0x1bd0, 0x727: 0x1d48, 0x728: 0x1966, 0x729: 0x0071,
-	0x72a: 0x19b7, 0x72b: 0x1bd4, 0x72c: 0x0059, 0x72d: 0x0047, 0x72e: 0x0049, 0x72f: 0x005b,
-	0x730: 0x0093, 0x731: 0x19e4, 0x732: 0x1c18, 0x733: 0x19ed, 0x734: 0x00ad, 0x735: 0x1a62,
-	0x736: 0x1c4c, 0x737: 0x1d5c, 0x738: 0x19f0, 0x739: 0x00b1, 0x73a: 0x1a65, 0x73b: 0x1c50,
-	0x73c: 0x0099, 0x73d: 0x0087, 0x73e: 0x0089, 0x73f: 0x009b,
+	0x700: 0x1bd8, 0x701: 0x1bdc, 0x702: 0x0047, 0x703: 0x1c54, 0x705: 0x1be8,
+	0x706: 0x1bec, 0x707: 0x00e9, 0x709: 0x1c58, 0x70a: 0x008f, 0x70b: 0x0051,
+	0x70c: 0x0051, 0x70d: 0x0051, 0x70e: 0x0091, 0x70f: 0x00da, 0x710: 0x0053, 0x711: 0x0053,
+	0x712: 0x0059, 0x713: 0x0099, 0x715: 0x005d, 0x716: 0x198d,
+	0x719: 0x0061, 0x71a: 0x0063, 0x71b: 0x0065, 0x71c: 0x0065, 0x71d: 0x0065,
+	0x720: 0x199f, 0x721: 0x1bc8, 0x722: 0x19a8,
+	0x724: 0x0075, 0x726: 0x01b8, 0x728: 0x0075,
+	0x72a: 0x0057, 0x72b: 0x42d2, 0x72c: 0x0045, 0x72d: 0x0047, 0x72f: 0x008b,
+	0x730: 0x004b, 0x731: 0x004d, 0x733: 0x005b, 0x734: 0x009f, 0x735: 0x0215,
+	0x736: 0x0218, 0x737: 0x021b, 0x738: 0x021e, 0x739: 0x0093, 0x73b: 0x1b98,
+	0x73c: 0x01e8, 0x73d: 0x01c1, 0x73e: 0x0179, 0x73f: 0x01a0,
 	// Block 0x1d, offset 0x740
-	0x741: 0x3c06, 0x743: 0xa000, 0x744: 0x3c0d, 0x745: 0xa000,
-	0x747: 0x3c14, 0x748: 0xa000, 0x749: 0x3c1b,
-	0x74d: 0xa000,
-	0x760: 0x2f65, 0x761: 0xa000, 0x762: 0x3c29,
-	0x764: 0xa000, 0x765: 0xa000,
-	0x76d: 0x3c22, 0x76e: 0x2f60, 0x76f: 0x2f6a,
-	0x770: 0x3c30, 0x771: 0x3c37, 0x772: 0xa000, 0x773: 0xa000, 0x774: 0x3c3e, 0x775: 0x3c45,
-	0x776: 0xa000, 0x777: 0xa000, 0x778: 0x3c4c, 0x779: 0x3c53, 0x77a: 0xa000, 0x77b: 0xa000,
-	0x77c: 0xa000, 0x77d: 0xa000,
+	0x740: 0x0463, 0x745: 0x0049,
+	0x746: 0x0089, 0x747: 0x008b, 0x748: 0x0093, 0x749: 0x0095,
+	0x750: 0x222e, 0x751: 0x223a,
+	0x752: 0x22ee, 0x753: 0x2216, 0x754: 0x229a, 0x755: 0x2222, 0x756: 0x22a0, 0x757: 0x22b8,
+	0x758: 0x22c4, 0x759: 0x2228, 0x75a: 0x22ca, 0x75b: 0x2234, 0x75c: 0x22be, 0x75d: 0x22d0,
+	0x75e: 0x22d6, 0x75f: 0x1cbc, 0x760: 0x0053, 0x761: 0x195a, 0x762: 0x1ba4, 0x763: 0x1963,
+	0x764: 0x006d, 0x765: 0x19ab, 0x766: 0x1bd0, 0x767: 0x1d48, 0x768: 0x1966, 0x769: 0x0071,
+	0x76a: 0x19b7, 0x76b: 0x1bd4, 0x76c: 0x0059, 0x76d: 0x0047, 0x76e: 0x0049, 0x76f: 0x005b,
+	0x770: 0x0093, 0x771: 0x19e4, 0x772: 0x1c18, 0x773: 0x19ed, 0x774: 0x00ad, 0x775: 0x1a62,
+	0x776: 0x1c4c, 0x777: 0x1d5c, 0x778: 0x19f0, 0x779: 0x00b1, 0x77a: 0x1a65, 0x77b: 0x1c50,
+	0x77c: 0x0099, 0x77d: 0x0087, 0x77e: 0x0089, 0x77f: 0x009b,
 	// Block 0x1e, offset 0x780
-	0x780: 0x3c5a, 0x781: 0x3c61, 0x782: 0xa000, 0x783: 0xa000, 0x784: 0x3c76, 0x785: 0x3c7d,
-	0x786: 0xa000, 0x787: 0xa000, 0x788: 0x3c84, 0x789: 0x3c8b,
-	0x791: 0xa000,
-	0x792: 0xa000,
-	0x7a2: 0xa000,
-	0x7a8: 0xa000, 0x7a9: 0xa000,
-	0x7ab: 0xa000, 0x7ac: 0x3ca0, 0x7ad: 0x3ca7, 0x7ae: 0x3cae, 0x7af: 0x3cb5,
-	0x7b2: 0xa000, 0x7b3: 0xa000, 0x7b4: 0xa000, 0x7b5: 0xa000,
+	0x781: 0x3c06, 0x783: 0xa000, 0x784: 0x3c0d, 0x785: 0xa000,
+	0x787: 0x3c14, 0x788: 0xa000, 0x789: 0x3c1b,
+	0x78d: 0xa000,
+	0x7a0: 0x2f65, 0x7a1: 0xa000, 0x7a2: 0x3c29,
+	0x7a4: 0xa000, 0x7a5: 0xa000,
+	0x7ad: 0x3c22, 0x7ae: 0x2f60, 0x7af: 0x2f6a,
+	0x7b0: 0x3c30, 0x7b1: 0x3c37, 0x7b2: 0xa000, 0x7b3: 0xa000, 0x7b4: 0x3c3e, 0x7b5: 0x3c45,
+	0x7b6: 0xa000, 0x7b7: 0xa000, 0x7b8: 0x3c4c, 0x7b9: 0x3c53, 0x7ba: 0xa000, 0x7bb: 0xa000,
+	0x7bc: 0xa000, 0x7bd: 0xa000,
 	// Block 0x1f, offset 0x7c0
-	0x7e0: 0x0023, 0x7e1: 0x0025, 0x7e2: 0x0027, 0x7e3: 0x0029,
-	0x7e4: 0x002b, 0x7e5: 0x002d, 0x7e6: 0x002f, 0x7e7: 0x0031, 0x7e8: 0x0033, 0x7e9: 0x1882,
-	0x7ea: 0x1885, 0x7eb: 0x1888, 0x7ec: 0x188b, 0x7ed: 0x188e, 0x7ee: 0x1891, 0x7ef: 0x1894,
-	0x7f0: 0x1897, 0x7f1: 0x189a, 0x7f2: 0x189d, 0x7f3: 0x18a6, 0x7f4: 0x1a68, 0x7f5: 0x1a6c,
-	0x7f6: 0x1a70, 0x7f7: 0x1a74, 0x7f8: 0x1a78, 0x7f9: 0x1a7c, 0x7fa: 0x1a80, 0x7fb: 0x1a84,
-	0x7fc: 0x1a88, 0x7fd: 0x1c80, 0x7fe: 0x1c85, 0x7ff: 0x1c8a,
+	0x7c0: 0x3c5a, 0x7c1: 0x3c61, 0x7c2: 0xa000, 0x7c3: 0xa000, 0x7c4: 0x3c76, 0x7c5: 0x3c7d,
+	0x7c6: 0xa000, 0x7c7: 0xa000, 0x7c8: 0x3c84, 0x7c9: 0x3c8b,
+	0x7d1: 0xa000,
+	0x7d2: 0xa000,
+	0x7e2: 0xa000,
+	0x7e8: 0xa000, 0x7e9: 0xa000,
+	0x7eb: 0xa000, 0x7ec: 0x3ca0, 0x7ed: 0x3ca7, 0x7ee: 0x3cae, 0x7ef: 0x3cb5,
+	0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0xa000, 0x7f5: 0xa000,
 	// Block 0x20, offset 0x800
-	0x800: 0x1c8f, 0x801: 0x1c94, 0x802: 0x1c99, 0x803: 0x1c9e, 0x804: 0x1ca3, 0x805: 0x1ca8,
-	0x806: 0x1cad, 0x807: 0x1cb2, 0x808: 0x187f, 0x809: 0x18a3, 0x80a: 0x18c7, 0x80b: 0x18eb,
-	0x80c: 0x190f, 0x80d: 0x1918, 0x80e: 0x191e, 0x80f: 0x1924, 0x810: 0x192a, 0x811: 0x1b60,
-	0x812: 0x1b64, 0x813: 0x1b68, 0x814: 0x1b6c, 0x815: 0x1b70, 0x816: 0x1b74, 0x817: 0x1b78,
-	0x818: 0x1b7c, 0x819: 0x1b80, 0x81a: 0x1b84, 0x81b: 0x1b88, 0x81c: 0x1af4, 0x81d: 0x1af8,
-	0x81e: 0x1afc, 0x81f: 0x1b00, 0x820: 0x1b04, 0x821: 0x1b08, 0x822: 0x1b0c, 0x823: 0x1b10,
-	0x824: 0x1b14, 0x825: 0x1b18, 0x826: 0x1b1c, 0x827: 0x1b20, 0x828: 0x1b24, 0x829: 0x1b28,
-	0x82a: 0x1b2c, 0x82b: 0x1b30, 0x82c: 0x1b34, 0x82d: 0x1b38, 0x82e: 0x1b3c, 0x82f: 0x1b40,
-	0x830: 0x1b44, 0x831: 0x1b48, 0x832: 0x1b4c, 0x833: 0x1b50, 0x834: 0x1b54, 0x835: 0x1b58,
-	0x836: 0x0043, 0x837: 0x0045, 0x838: 0x0047, 0x839: 0x0049, 0x83a: 0x004b, 0x83b: 0x004d,
-	0x83c: 0x004f, 0x83d: 0x0051, 0x83e: 0x0053, 0x83f: 0x0055,
+	0x820: 0x0023, 0x821: 0x0025, 0x822: 0x0027, 0x823: 0x0029,
+	0x824: 0x002b, 0x825: 0x002d, 0x826: 0x002f, 0x827: 0x0031, 0x828: 0x0033, 0x829: 0x1882,
+	0x82a: 0x1885, 0x82b: 0x1888, 0x82c: 0x188b, 0x82d: 0x188e, 0x82e: 0x1891, 0x82f: 0x1894,
+	0x830: 0x1897, 0x831: 0x189a, 0x832: 0x189d, 0x833: 0x18a6, 0x834: 0x1a68, 0x835: 0x1a6c,
+	0x836: 0x1a70, 0x837: 0x1a74, 0x838: 0x1a78, 0x839: 0x1a7c, 0x83a: 0x1a80, 0x83b: 0x1a84,
+	0x83c: 0x1a88, 0x83d: 0x1c80, 0x83e: 0x1c85, 0x83f: 0x1c8a,
 	// Block 0x21, offset 0x840
-	0x840: 0x06bf, 0x841: 0x06e3, 0x842: 0x06ef, 0x843: 0x06ff, 0x844: 0x0707, 0x845: 0x0713,
-	0x846: 0x071b, 0x847: 0x0723, 0x848: 0x072f, 0x849: 0x0783, 0x84a: 0x079b, 0x84b: 0x07ab,
-	0x84c: 0x07bb, 0x84d: 0x07cb, 0x84e: 0x07db, 0x84f: 0x07fb, 0x850: 0x07ff, 0x851: 0x0803,
-	0x852: 0x0837, 0x853: 0x085f, 0x854: 0x086f, 0x855: 0x0877, 0x856: 0x087b, 0x857: 0x0887,
-	0x858: 0x08a3, 0x859: 0x08a7, 0x85a: 0x08bf, 0x85b: 0x08c3, 0x85c: 0x08cb, 0x85d: 0x08db,
-	0x85e: 0x0977, 0x85f: 0x098b, 0x860: 0x09cb, 0x861: 0x09df, 0x862: 0x09e7, 0x863: 0x09eb,
-	0x864: 0x09fb, 0x865: 0x0a17, 0x866: 0x0a43, 0x867: 0x0a4f, 0x868: 0x0a6f, 0x869: 0x0a7b,
-	0x86a: 0x0a7f, 0x86b: 0x0a83, 0x86c: 0x0a9b, 0x86d: 0x0a9f, 0x86e: 0x0acb, 0x86f: 0x0ad7,
-	0x870: 0x0adf, 0x871: 0x0ae7, 0x872: 0x0af7, 0x873: 0x0aff, 0x874: 0x0b07, 0x875: 0x0b33,
-	0x876: 0x0b37, 0x877: 0x0b3f, 0x878: 0x0b43, 0x879: 0x0b4b, 0x87a: 0x0b53, 0x87b: 0x0b63,
-	0x87c: 0x0b7f, 0x87d: 0x0bf7, 0x87e: 0x0c0b, 0x87f: 0x0c0f,
+	0x840: 0x1c8f, 0x841: 0x1c94, 0x842: 0x1c99, 0x843: 0x1c9e, 0x844: 0x1ca3, 0x845: 0x1ca8,
+	0x846: 0x1cad, 0x847: 0x1cb2, 0x848: 0x187f, 0x849: 0x18a3, 0x84a: 0x18c7, 0x84b: 0x18eb,
+	0x84c: 0x190f, 0x84d: 0x1918, 0x84e: 0x191e, 0x84f: 0x1924, 0x850: 0x192a, 0x851: 0x1b60,
+	0x852: 0x1b64, 0x853: 0x1b68, 0x854: 0x1b6c, 0x855: 0x1b70, 0x856: 0x1b74, 0x857: 0x1b78,
+	0x858: 0x1b7c, 0x859: 0x1b80, 0x85a: 0x1b84, 0x85b: 0x1b88, 0x85c: 0x1af4, 0x85d: 0x1af8,
+	0x85e: 0x1afc, 0x85f: 0x1b00, 0x860: 0x1b04, 0x861: 0x1b08, 0x862: 0x1b0c, 0x863: 0x1b10,
+	0x864: 0x1b14, 0x865: 0x1b18, 0x866: 0x1b1c, 0x867: 0x1b20, 0x868: 0x1b24, 0x869: 0x1b28,
+	0x86a: 0x1b2c, 0x86b: 0x1b30, 0x86c: 0x1b34, 0x86d: 0x1b38, 0x86e: 0x1b3c, 0x86f: 0x1b40,
+	0x870: 0x1b44, 0x871: 0x1b48, 0x872: 0x1b4c, 0x873: 0x1b50, 0x874: 0x1b54, 0x875: 0x1b58,
+	0x876: 0x0043, 0x877: 0x0045, 0x878: 0x0047, 0x879: 0x0049, 0x87a: 0x004b, 0x87b: 0x004d,
+	0x87c: 0x004f, 0x87d: 0x0051, 0x87e: 0x0053, 0x87f: 0x0055,
 	// Block 0x22, offset 0x880
-	0x880: 0x0c8f, 0x881: 0x0c93, 0x882: 0x0ca7, 0x883: 0x0cab, 0x884: 0x0cb3, 0x885: 0x0cbb,
-	0x886: 0x0cc3, 0x887: 0x0ccf, 0x888: 0x0cf7, 0x889: 0x0d07, 0x88a: 0x0d1b, 0x88b: 0x0d8b,
-	0x88c: 0x0d97, 0x88d: 0x0da7, 0x88e: 0x0db3, 0x88f: 0x0dbf, 0x890: 0x0dc7, 0x891: 0x0dcb,
-	0x892: 0x0dcf, 0x893: 0x0dd3, 0x894: 0x0dd7, 0x895: 0x0e8f, 0x896: 0x0ed7, 0x897: 0x0ee3,
-	0x898: 0x0ee7, 0x899: 0x0eeb, 0x89a: 0x0eef, 0x89b: 0x0ef7, 0x89c: 0x0efb, 0x89d: 0x0f0f,
-	0x89e: 0x0f2b, 0x89f: 0x0f33, 0x8a0: 0x0f73, 0x8a1: 0x0f77, 0x8a2: 0x0f7f, 0x8a3: 0x0f83,
-	0x8a4: 0x0f8b, 0x8a5: 0x0f8f, 0x8a6: 0x0fb3, 0x8a7: 0x0fb7, 0x8a8: 0x0fd3, 0x8a9: 0x0fd7,
-	0x8aa: 0x0fdb, 0x8ab: 0x0fdf, 0x8ac: 0x0ff3, 0x8ad: 0x1017, 0x8ae: 0x101b, 0x8af: 0x101f,
-	0x8b0: 0x1043, 0x8b1: 0x1083, 0x8b2: 0x1087, 0x8b3: 0x10a7, 0x8b4: 0x10b7, 0x8b5: 0x10bf,
-	0x8b6: 0x10df, 0x8b7: 0x1103, 0x8b8: 0x1147, 0x8b9: 0x114f, 0x8ba: 0x1163, 0x8bb: 0x116f,
-	0x8bc: 0x1177, 0x8bd: 0x117f, 0x8be: 0x1183, 0x8bf: 0x1187,
+	0x880: 0x06bf, 0x881: 0x06e3, 0x882: 0x06ef, 0x883: 0x06ff, 0x884: 0x0707, 0x885: 0x0713,
+	0x886: 0x071b, 0x887: 0x0723, 0x888: 0x072f, 0x889: 0x0783, 0x88a: 0x079b, 0x88b: 0x07ab,
+	0x88c: 0x07bb, 0x88d: 0x07cb, 0x88e: 0x07db, 0x88f: 0x07fb, 0x890: 0x07ff, 0x891: 0x0803,
+	0x892: 0x0837, 0x893: 0x085f, 0x894: 0x086f, 0x895: 0x0877, 0x896: 0x087b, 0x897: 0x0887,
+	0x898: 0x08a3, 0x899: 0x08a7, 0x89a: 0x08bf, 0x89b: 0x08c3, 0x89c: 0x08cb, 0x89d: 0x08db,
+	0x89e: 0x0977, 0x89f: 0x098b, 0x8a0: 0x09cb, 0x8a1: 0x09df, 0x8a2: 0x09e7, 0x8a3: 0x09eb,
+	0x8a4: 0x09fb, 0x8a5: 0x0a17, 0x8a6: 0x0a43, 0x8a7: 0x0a4f, 0x8a8: 0x0a6f, 0x8a9: 0x0a7b,
+	0x8aa: 0x0a7f, 0x8ab: 0x0a83, 0x8ac: 0x0a9b, 0x8ad: 0x0a9f, 0x8ae: 0x0acb, 0x8af: 0x0ad7,
+	0x8b0: 0x0adf, 0x8b1: 0x0ae7, 0x8b2: 0x0af7, 0x8b3: 0x0aff, 0x8b4: 0x0b07, 0x8b5: 0x0b33,
+	0x8b6: 0x0b37, 0x8b7: 0x0b3f, 0x8b8: 0x0b43, 0x8b9: 0x0b4b, 0x8ba: 0x0b53, 0x8bb: 0x0b63,
+	0x8bc: 0x0b7f, 0x8bd: 0x0bf7, 0x8be: 0x0c0b, 0x8bf: 0x0c0f,
 	// Block 0x23, offset 0x8c0
-	0x8c0: 0x119f, 0x8c1: 0x11a3, 0x8c2: 0x11bf, 0x8c3: 0x11c7, 0x8c4: 0x11cf, 0x8c5: 0x11d3,
-	0x8c6: 0x11df, 0x8c7: 0x11e7, 0x8c8: 0x11eb, 0x8c9: 0x11ef, 0x8ca: 0x11f7, 0x8cb: 0x11fb,
-	0x8cc: 0x129b, 0x8cd: 0x12af, 0x8ce: 0x12e3, 0x8cf: 0x12e7, 0x8d0: 0x12ef, 0x8d1: 0x131b,
-	0x8d2: 0x1323, 0x8d3: 0x132b, 0x8d4: 0x1333, 0x8d5: 0x136f, 0x8d6: 0x1373, 0x8d7: 0x137b,
-	0x8d8: 0x137f, 0x8d9: 0x1383, 0x8da: 0x13af, 0x8db: 0x13b3, 0x8dc: 0x13bb, 0x8dd: 0x13cf,
-	0x8de: 0x13d3, 0x8df: 0x13ef, 0x8e0: 0x13f7, 0x8e1: 0x13fb, 0x8e2: 0x141f, 0x8e3: 0x143f,
-	0x8e4: 0x1453, 0x8e5: 0x1457, 0x8e6: 0x145f, 0x8e7: 0x148b, 0x8e8: 0x148f, 0x8e9: 0x149f,
-	0x8ea: 0x14c3, 0x8eb: 0x14cf, 0x8ec: 0x14df, 0x8ed: 0x14f7, 0x8ee: 0x14ff, 0x8ef: 0x1503,
-	0x8f0: 0x1507, 0x8f1: 0x150b, 0x8f2: 0x1517, 0x8f3: 0x151b, 0x8f4: 0x1523, 0x8f5: 0x153f,
-	0x8f6: 0x1543, 0x8f7: 0x1547, 0x8f8: 0x155f, 0x8f9: 0x1563, 0x8fa: 0x156b, 0x8fb: 0x157f,
-	0x8fc: 0x1583, 0x8fd: 0x1587, 0x8fe: 0x158f, 0x8ff: 0x1593,
+	0x8c0: 0x0c8f, 0x8c1: 0x0c93, 0x8c2: 0x0ca7, 0x8c3: 0x0cab, 0x8c4: 0x0cb3, 0x8c5: 0x0cbb,
+	0x8c6: 0x0cc3, 0x8c7: 0x0ccf, 0x8c8: 0x0cf7, 0x8c9: 0x0d07, 0x8ca: 0x0d1b, 0x8cb: 0x0d8b,
+	0x8cc: 0x0d97, 0x8cd: 0x0da7, 0x8ce: 0x0db3, 0x8cf: 0x0dbf, 0x8d0: 0x0dc7, 0x8d1: 0x0dcb,
+	0x8d2: 0x0dcf, 0x8d3: 0x0dd3, 0x8d4: 0x0dd7, 0x8d5: 0x0e8f, 0x8d6: 0x0ed7, 0x8d7: 0x0ee3,
+	0x8d8: 0x0ee7, 0x8d9: 0x0eeb, 0x8da: 0x0eef, 0x8db: 0x0ef7, 0x8dc: 0x0efb, 0x8dd: 0x0f0f,
+	0x8de: 0x0f2b, 0x8df: 0x0f33, 0x8e0: 0x0f73, 0x8e1: 0x0f77, 0x8e2: 0x0f7f, 0x8e3: 0x0f83,
+	0x8e4: 0x0f8b, 0x8e5: 0x0f8f, 0x8e6: 0x0fb3, 0x8e7: 0x0fb7, 0x8e8: 0x0fd3, 0x8e9: 0x0fd7,
+	0x8ea: 0x0fdb, 0x8eb: 0x0fdf, 0x8ec: 0x0ff3, 0x8ed: 0x1017, 0x8ee: 0x101b, 0x8ef: 0x101f,
+	0x8f0: 0x1043, 0x8f1: 0x1083, 0x8f2: 0x1087, 0x8f3: 0x10a7, 0x8f4: 0x10b7, 0x8f5: 0x10bf,
+	0x8f6: 0x10df, 0x8f7: 0x1103, 0x8f8: 0x1147, 0x8f9: 0x114f, 0x8fa: 0x1163, 0x8fb: 0x116f,
+	0x8fc: 0x1177, 0x8fd: 0x117f, 0x8fe: 0x1183, 0x8ff: 0x1187,
 	// Block 0x24, offset 0x900
-	0x906: 0xa000, 0x90b: 0xa000,
-	0x90c: 0x3f08, 0x90d: 0xa000, 0x90e: 0x3f10, 0x90f: 0xa000, 0x910: 0x3f18, 0x911: 0xa000,
-	0x912: 0x3f20, 0x913: 0xa000, 0x914: 0x3f28, 0x915: 0xa000, 0x916: 0x3f30, 0x917: 0xa000,
-	0x918: 0x3f38, 0x919: 0xa000, 0x91a: 0x3f40, 0x91b: 0xa000, 0x91c: 0x3f48, 0x91d: 0xa000,
-	0x91e: 0x3f50, 0x91f: 0xa000, 0x920: 0x3f58, 0x921: 0xa000, 0x922: 0x3f60,
-	0x924: 0xa000, 0x925: 0x3f68, 0x926: 0xa000, 0x927: 0x3f70, 0x928: 0xa000, 0x929: 0x3f78,
-	0x92f: 0xa000,
-	0x930: 0x3f80, 0x931: 0x3f88, 0x932: 0xa000, 0x933: 0x3f90, 0x934: 0x3f98, 0x935: 0xa000,
-	0x936: 0x3fa0, 0x937: 0x3fa8, 0x938: 0xa000, 0x939: 0x3fb0, 0x93a: 0x3fb8, 0x93b: 0xa000,
-	0x93c: 0x3fc0, 0x93d: 0x3fc8,
+	0x900: 0x119f, 0x901: 0x11a3, 0x902: 0x11bf, 0x903: 0x11c7, 0x904: 0x11cf, 0x905: 0x11d3,
+	0x906: 0x11df, 0x907: 0x11e7, 0x908: 0x11eb, 0x909: 0x11ef, 0x90a: 0x11f7, 0x90b: 0x11fb,
+	0x90c: 0x129b, 0x90d: 0x12af, 0x90e: 0x12e3, 0x90f: 0x12e7, 0x910: 0x12ef, 0x911: 0x131b,
+	0x912: 0x1323, 0x913: 0x132b, 0x914: 0x1333, 0x915: 0x136f, 0x916: 0x1373, 0x917: 0x137b,
+	0x918: 0x137f, 0x919: 0x1383, 0x91a: 0x13af, 0x91b: 0x13b3, 0x91c: 0x13bb, 0x91d: 0x13cf,
+	0x91e: 0x13d3, 0x91f: 0x13ef, 0x920: 0x13f7, 0x921: 0x13fb, 0x922: 0x141f, 0x923: 0x143f,
+	0x924: 0x1453, 0x925: 0x1457, 0x926: 0x145f, 0x927: 0x148b, 0x928: 0x148f, 0x929: 0x149f,
+	0x92a: 0x14c3, 0x92b: 0x14cf, 0x92c: 0x14df, 0x92d: 0x14f7, 0x92e: 0x14ff, 0x92f: 0x1503,
+	0x930: 0x1507, 0x931: 0x150b, 0x932: 0x1517, 0x933: 0x151b, 0x934: 0x1523, 0x935: 0x153f,
+	0x936: 0x1543, 0x937: 0x1547, 0x938: 0x155f, 0x939: 0x1563, 0x93a: 0x156b, 0x93b: 0x157f,
+	0x93c: 0x1583, 0x93d: 0x1587, 0x93e: 0x158f, 0x93f: 0x1593,
 	// Block 0x25, offset 0x940
-	0x954: 0x3f00,
-	0x959: 0x9903, 0x95a: 0x9903, 0x95b: 0x42dc, 0x95c: 0x42e2, 0x95d: 0xa000,
-	0x95e: 0x3fd0, 0x95f: 0x26b4,
-	0x966: 0xa000,
-	0x96b: 0xa000, 0x96c: 0x3fe0, 0x96d: 0xa000, 0x96e: 0x3fe8, 0x96f: 0xa000,
-	0x970: 0x3ff0, 0x971: 0xa000, 0x972: 0x3ff8, 0x973: 0xa000, 0x974: 0x4000, 0x975: 0xa000,
-	0x976: 0x4008, 0x977: 0xa000, 0x978: 0x4010, 0x979: 0xa000, 0x97a: 0x4018, 0x97b: 0xa000,
-	0x97c: 0x4020, 0x97d: 0xa000, 0x97e: 0x4028, 0x97f: 0xa000,
+	0x946: 0xa000, 0x94b: 0xa000,
+	0x94c: 0x3f08, 0x94d: 0xa000, 0x94e: 0x3f10, 0x94f: 0xa000, 0x950: 0x3f18, 0x951: 0xa000,
+	0x952: 0x3f20, 0x953: 0xa000, 0x954: 0x3f28, 0x955: 0xa000, 0x956: 0x3f30, 0x957: 0xa000,
+	0x958: 0x3f38, 0x959: 0xa000, 0x95a: 0x3f40, 0x95b: 0xa000, 0x95c: 0x3f48, 0x95d: 0xa000,
+	0x95e: 0x3f50, 0x95f: 0xa000, 0x960: 0x3f58, 0x961: 0xa000, 0x962: 0x3f60,
+	0x964: 0xa000, 0x965: 0x3f68, 0x966: 0xa000, 0x967: 0x3f70, 0x968: 0xa000, 0x969: 0x3f78,
+	0x96f: 0xa000,
+	0x970: 0x3f80, 0x971: 0x3f88, 0x972: 0xa000, 0x973: 0x3f90, 0x974: 0x3f98, 0x975: 0xa000,
+	0x976: 0x3fa0, 0x977: 0x3fa8, 0x978: 0xa000, 0x979: 0x3fb0, 0x97a: 0x3fb8, 0x97b: 0xa000,
+	0x97c: 0x3fc0, 0x97d: 0x3fc8,
 	// Block 0x26, offset 0x980
-	0x980: 0x4030, 0x981: 0xa000, 0x982: 0x4038, 0x984: 0xa000, 0x985: 0x4040,
-	0x986: 0xa000, 0x987: 0x4048, 0x988: 0xa000, 0x989: 0x4050,
-	0x98f: 0xa000, 0x990: 0x4058, 0x991: 0x4060,
-	0x992: 0xa000, 0x993: 0x4068, 0x994: 0x4070, 0x995: 0xa000, 0x996: 0x4078, 0x997: 0x4080,
-	0x998: 0xa000, 0x999: 0x4088, 0x99a: 0x4090, 0x99b: 0xa000, 0x99c: 0x4098, 0x99d: 0x40a0,
-	0x9af: 0xa000,
-	0x9b0: 0xa000, 0x9b1: 0xa000, 0x9b2: 0xa000, 0x9b4: 0x3fd8,
-	0x9b7: 0x40a8, 0x9b8: 0x40b0, 0x9b9: 0x40b8, 0x9ba: 0x40c0,
-	0x9bd: 0xa000, 0x9be: 0x40c8, 0x9bf: 0x26c9,
+	0x994: 0x3f00,
+	0x999: 0x9903, 0x99a: 0x9903, 0x99b: 0x42dc, 0x99c: 0x42e2, 0x99d: 0xa000,
+	0x99e: 0x3fd0, 0x99f: 0x26b4,
+	0x9a6: 0xa000,
+	0x9ab: 0xa000, 0x9ac: 0x3fe0, 0x9ad: 0xa000, 0x9ae: 0x3fe8, 0x9af: 0xa000,
+	0x9b0: 0x3ff0, 0x9b1: 0xa000, 0x9b2: 0x3ff8, 0x9b3: 0xa000, 0x9b4: 0x4000, 0x9b5: 0xa000,
+	0x9b6: 0x4008, 0x9b7: 0xa000, 0x9b8: 0x4010, 0x9b9: 0xa000, 0x9ba: 0x4018, 0x9bb: 0xa000,
+	0x9bc: 0x4020, 0x9bd: 0xa000, 0x9be: 0x4028, 0x9bf: 0xa000,
 	// Block 0x27, offset 0x9c0
-	0x9c0: 0x0367, 0x9c1: 0x032b, 0x9c2: 0x032f, 0x9c3: 0x0333, 0x9c4: 0x037b, 0x9c5: 0x0337,
-	0x9c6: 0x033b, 0x9c7: 0x033f, 0x9c8: 0x0343, 0x9c9: 0x0347, 0x9ca: 0x034b, 0x9cb: 0x034f,
-	0x9cc: 0x0353, 0x9cd: 0x0357, 0x9ce: 0x035b, 0x9cf: 0x49bd, 0x9d0: 0x49c3, 0x9d1: 0x49c9,
-	0x9d2: 0x49cf, 0x9d3: 0x49d5, 0x9d4: 0x49db, 0x9d5: 0x49e1, 0x9d6: 0x49e7, 0x9d7: 0x49ed,
-	0x9d8: 0x49f3, 0x9d9: 0x49f9, 0x9da: 0x49ff, 0x9db: 0x4a05, 0x9dc: 0x4a0b, 0x9dd: 0x4a11,
-	0x9de: 0x4a17, 0x9df: 0x4a1d, 0x9e0: 0x4a23, 0x9e1: 0x4a29, 0x9e2: 0x4a2f, 0x9e3: 0x4a35,
-	0x9e4: 0x03c3, 0x9e5: 0x035f, 0x9e6: 0x0363, 0x9e7: 0x03e7, 0x9e8: 0x03eb, 0x9e9: 0x03ef,
-	0x9ea: 0x03f3, 0x9eb: 0x03f7, 0x9ec: 0x03fb, 0x9ed: 0x03ff, 0x9ee: 0x036b, 0x9ef: 0x0403,
-	0x9f0: 0x0407, 0x9f1: 0x036f, 0x9f2: 0x0373, 0x9f3: 0x0377, 0x9f4: 0x037f, 0x9f5: 0x0383,
-	0x9f6: 0x0387, 0x9f7: 0x038b, 0x9f8: 0x038f, 0x9f9: 0x0393, 0x9fa: 0x0397, 0x9fb: 0x039b,
-	0x9fc: 0x039f, 0x9fd: 0x03a3, 0x9fe: 0x03a7, 0x9ff: 0x03ab,
+	0x9c0: 0x4030, 0x9c1: 0xa000, 0x9c2: 0x4038, 0x9c4: 0xa000, 0x9c5: 0x4040,
+	0x9c6: 0xa000, 0x9c7: 0x4048, 0x9c8: 0xa000, 0x9c9: 0x4050,
+	0x9cf: 0xa000, 0x9d0: 0x4058, 0x9d1: 0x4060,
+	0x9d2: 0xa000, 0x9d3: 0x4068, 0x9d4: 0x4070, 0x9d5: 0xa000, 0x9d6: 0x4078, 0x9d7: 0x4080,
+	0x9d8: 0xa000, 0x9d9: 0x4088, 0x9da: 0x4090, 0x9db: 0xa000, 0x9dc: 0x4098, 0x9dd: 0x40a0,
+	0x9ef: 0xa000,
+	0x9f0: 0xa000, 0x9f1: 0xa000, 0x9f2: 0xa000, 0x9f4: 0x3fd8,
+	0x9f7: 0x40a8, 0x9f8: 0x40b0, 0x9f9: 0x40b8, 0x9fa: 0x40c0,
+	0x9fd: 0xa000, 0x9fe: 0x40c8, 0x9ff: 0x26c9,
 	// Block 0x28, offset 0xa00
-	0xa00: 0x03af, 0xa01: 0x03b3, 0xa02: 0x040b, 0xa03: 0x040f, 0xa04: 0x03b7, 0xa05: 0x03bb,
-	0xa06: 0x03bf, 0xa07: 0x03c7, 0xa08: 0x03cb, 0xa09: 0x03cf, 0xa0a: 0x03d3, 0xa0b: 0x03d7,
-	0xa0c: 0x03db, 0xa0d: 0x03df, 0xa0e: 0x03e3,
-	0xa12: 0x06bf, 0xa13: 0x071b, 0xa14: 0x06cb, 0xa15: 0x097b, 0xa16: 0x06cf, 0xa17: 0x06e7,
-	0xa18: 0x06d3, 0xa19: 0x0f93, 0xa1a: 0x0707, 0xa1b: 0x06db, 0xa1c: 0x06c3, 0xa1d: 0x09ff,
-	0xa1e: 0x098f, 0xa1f: 0x072f,
+	0xa00: 0x0367, 0xa01: 0x032b, 0xa02: 0x032f, 0xa03: 0x0333, 0xa04: 0x037b, 0xa05: 0x0337,
+	0xa06: 0x033b, 0xa07: 0x033f, 0xa08: 0x0343, 0xa09: 0x0347, 0xa0a: 0x034b, 0xa0b: 0x034f,
+	0xa0c: 0x0353, 0xa0d: 0x0357, 0xa0e: 0x035b, 0xa0f: 0x49bd, 0xa10: 0x49c3, 0xa11: 0x49c9,
+	0xa12: 0x49cf, 0xa13: 0x49d5, 0xa14: 0x49db, 0xa15: 0x49e1, 0xa16: 0x49e7, 0xa17: 0x49ed,
+	0xa18: 0x49f3, 0xa19: 0x49f9, 0xa1a: 0x49ff, 0xa1b: 0x4a05, 0xa1c: 0x4a0b, 0xa1d: 0x4a11,
+	0xa1e: 0x4a17, 0xa1f: 0x4a1d, 0xa20: 0x4a23, 0xa21: 0x4a29, 0xa22: 0x4a2f, 0xa23: 0x4a35,
+	0xa24: 0x03c3, 0xa25: 0x035f, 0xa26: 0x0363, 0xa27: 0x03e7, 0xa28: 0x03eb, 0xa29: 0x03ef,
+	0xa2a: 0x03f3, 0xa2b: 0x03f7, 0xa2c: 0x03fb, 0xa2d: 0x03ff, 0xa2e: 0x036b, 0xa2f: 0x0403,
+	0xa30: 0x0407, 0xa31: 0x036f, 0xa32: 0x0373, 0xa33: 0x0377, 0xa34: 0x037f, 0xa35: 0x0383,
+	0xa36: 0x0387, 0xa37: 0x038b, 0xa38: 0x038f, 0xa39: 0x0393, 0xa3a: 0x0397, 0xa3b: 0x039b,
+	0xa3c: 0x039f, 0xa3d: 0x03a3, 0xa3e: 0x03a7, 0xa3f: 0x03ab,
 	// Block 0x29, offset 0xa40
-	0xa40: 0x2054, 0xa41: 0x205a, 0xa42: 0x2060, 0xa43: 0x2066, 0xa44: 0x206c, 0xa45: 0x2072,
-	0xa46: 0x2078, 0xa47: 0x207e, 0xa48: 0x2084, 0xa49: 0x208a, 0xa4a: 0x2090, 0xa4b: 0x2096,
-	0xa4c: 0x209c, 0xa4d: 0x20a2, 0xa4e: 0x2726, 0xa4f: 0x272f, 0xa50: 0x2738, 0xa51: 0x2741,
-	0xa52: 0x274a, 0xa53: 0x2753, 0xa54: 0x275c, 0xa55: 0x2765, 0xa56: 0x276e, 0xa57: 0x2780,
-	0xa58: 0x2789, 0xa59: 0x2792, 0xa5a: 0x279b, 0xa5b: 0x27a4, 0xa5c: 0x2777, 0xa5d: 0x2bac,
-	0xa5e: 0x2aed, 0xa60: 0x20a8, 0xa61: 0x20c0, 0xa62: 0x20b4, 0xa63: 0x2108,
-	0xa64: 0x20c6, 0xa65: 0x20e4, 0xa66: 0x20ae, 0xa67: 0x20de, 0xa68: 0x20ba, 0xa69: 0x20f0,
-	0xa6a: 0x2120, 0xa6b: 0x213e, 0xa6c: 0x2138, 0xa6d: 0x212c, 0xa6e: 0x217a, 0xa6f: 0x210e,
-	0xa70: 0x211a, 0xa71: 0x2132, 0xa72: 0x2126, 0xa73: 0x2150, 0xa74: 0x20fc, 0xa75: 0x2144,
-	0xa76: 0x216e, 0xa77: 0x2156, 0xa78: 0x20ea, 0xa79: 0x20cc, 0xa7a: 0x2102, 0xa7b: 0x2114,
-	0xa7c: 0x214a, 0xa7d: 0x20d2, 0xa7e: 0x2174, 0xa7f: 0x20f6,
+	0xa40: 0x03af, 0xa41: 0x03b3, 0xa42: 0x040b, 0xa43: 0x040f, 0xa44: 0x03b7, 0xa45: 0x03bb,
+	0xa46: 0x03bf, 0xa47: 0x03c7, 0xa48: 0x03cb, 0xa49: 0x03cf, 0xa4a: 0x03d3, 0xa4b: 0x03d7,
+	0xa4c: 0x03db, 0xa4d: 0x03df, 0xa4e: 0x03e3,
+	0xa52: 0x06bf, 0xa53: 0x071b, 0xa54: 0x06cb, 0xa55: 0x097b, 0xa56: 0x06cf, 0xa57: 0x06e7,
+	0xa58: 0x06d3, 0xa59: 0x0f93, 0xa5a: 0x0707, 0xa5b: 0x06db, 0xa5c: 0x06c3, 0xa5d: 0x09ff,
+	0xa5e: 0x098f, 0xa5f: 0x072f,
 	// Block 0x2a, offset 0xa80
-	0xa80: 0x215c, 0xa81: 0x20d8, 0xa82: 0x2162, 0xa83: 0x2168, 0xa84: 0x092f, 0xa85: 0x0b03,
-	0xa86: 0x0ca7, 0xa87: 0x10c7,
-	0xa90: 0x1bc4, 0xa91: 0x18a9,
-	0xa92: 0x18ac, 0xa93: 0x18af, 0xa94: 0x18b2, 0xa95: 0x18b5, 0xa96: 0x18b8, 0xa97: 0x18bb,
-	0xa98: 0x18be, 0xa99: 0x18c1, 0xa9a: 0x18ca, 0xa9b: 0x18cd, 0xa9c: 0x18d0, 0xa9d: 0x18d3,
-	0xa9e: 0x18d6, 0xa9f: 0x18d9, 0xaa0: 0x0313, 0xaa1: 0x031b, 0xaa2: 0x031f, 0xaa3: 0x0327,
-	0xaa4: 0x032b, 0xaa5: 0x032f, 0xaa6: 0x0337, 0xaa7: 0x033f, 0xaa8: 0x0343, 0xaa9: 0x034b,
-	0xaaa: 0x034f, 0xaab: 0x0353, 0xaac: 0x0357, 0xaad: 0x035b, 0xaae: 0x2e18, 0xaaf: 0x2e20,
-	0xab0: 0x2e28, 0xab1: 0x2e30, 0xab2: 0x2e38, 0xab3: 0x2e40, 0xab4: 0x2e48, 0xab5: 0x2e50,
-	0xab6: 0x2e60, 0xab7: 0x2e68, 0xab8: 0x2e70, 0xab9: 0x2e78, 0xaba: 0x2e80, 0xabb: 0x2e88,
-	0xabc: 0x2ed3, 0xabd: 0x2e9b, 0xabe: 0x2e58,
+	0xa80: 0x2054, 0xa81: 0x205a, 0xa82: 0x2060, 0xa83: 0x2066, 0xa84: 0x206c, 0xa85: 0x2072,
+	0xa86: 0x2078, 0xa87: 0x207e, 0xa88: 0x2084, 0xa89: 0x208a, 0xa8a: 0x2090, 0xa8b: 0x2096,
+	0xa8c: 0x209c, 0xa8d: 0x20a2, 0xa8e: 0x2726, 0xa8f: 0x272f, 0xa90: 0x2738, 0xa91: 0x2741,
+	0xa92: 0x274a, 0xa93: 0x2753, 0xa94: 0x275c, 0xa95: 0x2765, 0xa96: 0x276e, 0xa97: 0x2780,
+	0xa98: 0x2789, 0xa99: 0x2792, 0xa9a: 0x279b, 0xa9b: 0x27a4, 0xa9c: 0x2777, 0xa9d: 0x2bac,
+	0xa9e: 0x2aed, 0xaa0: 0x20a8, 0xaa1: 0x20c0, 0xaa2: 0x20b4, 0xaa3: 0x2108,
+	0xaa4: 0x20c6, 0xaa5: 0x20e4, 0xaa6: 0x20ae, 0xaa7: 0x20de, 0xaa8: 0x20ba, 0xaa9: 0x20f0,
+	0xaaa: 0x2120, 0xaab: 0x213e, 0xaac: 0x2138, 0xaad: 0x212c, 0xaae: 0x217a, 0xaaf: 0x210e,
+	0xab0: 0x211a, 0xab1: 0x2132, 0xab2: 0x2126, 0xab3: 0x2150, 0xab4: 0x20fc, 0xab5: 0x2144,
+	0xab6: 0x216e, 0xab7: 0x2156, 0xab8: 0x20ea, 0xab9: 0x20cc, 0xaba: 0x2102, 0xabb: 0x2114,
+	0xabc: 0x214a, 0xabd: 0x20d2, 0xabe: 0x2174, 0xabf: 0x20f6,
 	// Block 0x2b, offset 0xac0
-	0xac0: 0x06bf, 0xac1: 0x071b, 0xac2: 0x06cb, 0xac3: 0x097b, 0xac4: 0x071f, 0xac5: 0x07af,
-	0xac6: 0x06c7, 0xac7: 0x07ab, 0xac8: 0x070b, 0xac9: 0x0887, 0xaca: 0x0d07, 0xacb: 0x0e8f,
-	0xacc: 0x0dd7, 0xacd: 0x0d1b, 0xace: 0x145f, 0xacf: 0x098b, 0xad0: 0x0ccf, 0xad1: 0x0d4b,
-	0xad2: 0x0d0b, 0xad3: 0x104b, 0xad4: 0x08fb, 0xad5: 0x0f03, 0xad6: 0x1387, 0xad7: 0x105f,
-	0xad8: 0x0843, 0xad9: 0x108f, 0xada: 0x0f9b, 0xadb: 0x0a17, 0xadc: 0x140f, 0xadd: 0x077f,
-	0xade: 0x08ab, 0xadf: 0x0df7, 0xae0: 0x1527, 0xae1: 0x0743, 0xae2: 0x07d3, 0xae3: 0x0d9b,
-	0xae4: 0x06cf, 0xae5: 0x06e7, 0xae6: 0x06d3, 0xae7: 0x0adb, 0xae8: 0x08ef, 0xae9: 0x087f,
-	0xaea: 0x0a57, 0xaeb: 0x0a4b, 0xaec: 0x0feb, 0xaed: 0x073f, 0xaee: 0x139b, 0xaef: 0x089b,
-	0xaf0: 0x09f3, 0xaf1: 0x18dc, 0xaf2: 0x18df, 0xaf3: 0x18e2, 0xaf4: 0x18e5, 0xaf5: 0x18ee,
-	0xaf6: 0x18f1, 0xaf7: 0x18f4, 0xaf8: 0x18f7, 0xaf9: 0x18fa, 0xafa: 0x18fd, 0xafb: 0x1900,
-	0xafc: 0x1903, 0xafd: 0x1906, 0xafe: 0x1909, 0xaff: 0x1912,
+	0xac0: 0x215c, 0xac1: 0x20d8, 0xac2: 0x2162, 0xac3: 0x2168, 0xac4: 0x092f, 0xac5: 0x0b03,
+	0xac6: 0x0ca7, 0xac7: 0x10c7,
+	0xad0: 0x1bc4, 0xad1: 0x18a9,
+	0xad2: 0x18ac, 0xad3: 0x18af, 0xad4: 0x18b2, 0xad5: 0x18b5, 0xad6: 0x18b8, 0xad7: 0x18bb,
+	0xad8: 0x18be, 0xad9: 0x18c1, 0xada: 0x18ca, 0xadb: 0x18cd, 0xadc: 0x18d0, 0xadd: 0x18d3,
+	0xade: 0x18d6, 0xadf: 0x18d9, 0xae0: 0x0313, 0xae1: 0x031b, 0xae2: 0x031f, 0xae3: 0x0327,
+	0xae4: 0x032b, 0xae5: 0x032f, 0xae6: 0x0337, 0xae7: 0x033f, 0xae8: 0x0343, 0xae9: 0x034b,
+	0xaea: 0x034f, 0xaeb: 0x0353, 0xaec: 0x0357, 0xaed: 0x035b, 0xaee: 0x2e18, 0xaef: 0x2e20,
+	0xaf0: 0x2e28, 0xaf1: 0x2e30, 0xaf2: 0x2e38, 0xaf3: 0x2e40, 0xaf4: 0x2e48, 0xaf5: 0x2e50,
+	0xaf6: 0x2e60, 0xaf7: 0x2e68, 0xaf8: 0x2e70, 0xaf9: 0x2e78, 0xafa: 0x2e80, 0xafb: 0x2e88,
+	0xafc: 0x2ed3, 0xafd: 0x2e9b, 0xafe: 0x2e58,
 	// Block 0x2c, offset 0xb00
-	0xb00: 0x1cc6, 0xb01: 0x1cd5, 0xb02: 0x1ce4, 0xb03: 0x1cf3, 0xb04: 0x1d02, 0xb05: 0x1d11,
-	0xb06: 0x1d20, 0xb07: 0x1d2f, 0xb08: 0x1d3e, 0xb09: 0x218c, 0xb0a: 0x219e, 0xb0b: 0x21b0,
-	0xb0c: 0x1954, 0xb0d: 0x1c04, 0xb0e: 0x19d2, 0xb0f: 0x1ba8, 0xb10: 0x04cb, 0xb11: 0x04d3,
-	0xb12: 0x04db, 0xb13: 0x04e3, 0xb14: 0x04eb, 0xb15: 0x04ef, 0xb16: 0x04f3, 0xb17: 0x04f7,
-	0xb18: 0x04fb, 0xb19: 0x04ff, 0xb1a: 0x0503, 0xb1b: 0x0507, 0xb1c: 0x050b, 0xb1d: 0x050f,
-	0xb1e: 0x0513, 0xb1f: 0x0517, 0xb20: 0x051b, 0xb21: 0x0523, 0xb22: 0x0527, 0xb23: 0x052b,
-	0xb24: 0x052f, 0xb25: 0x0533, 0xb26: 0x0537, 0xb27: 0x053b, 0xb28: 0x053f, 0xb29: 0x0543,
-	0xb2a: 0x0547, 0xb2b: 0x054b, 0xb2c: 0x054f, 0xb2d: 0x0553, 0xb2e: 0x0557, 0xb2f: 0x055b,
-	0xb30: 0x055f, 0xb31: 0x0563, 0xb32: 0x0567, 0xb33: 0x056f, 0xb34: 0x0577, 0xb35: 0x057f,
-	0xb36: 0x0583, 0xb37: 0x0587, 0xb38: 0x058b, 0xb39: 0x058f, 0xb3a: 0x0593, 0xb3b: 0x0597,
-	0xb3c: 0x059b, 0xb3d: 0x059f, 0xb3e: 0x05a3,
+	0xb00: 0x06bf, 0xb01: 0x071b, 0xb02: 0x06cb, 0xb03: 0x097b, 0xb04: 0x071f, 0xb05: 0x07af,
+	0xb06: 0x06c7, 0xb07: 0x07ab, 0xb08: 0x070b, 0xb09: 0x0887, 0xb0a: 0x0d07, 0xb0b: 0x0e8f,
+	0xb0c: 0x0dd7, 0xb0d: 0x0d1b, 0xb0e: 0x145f, 0xb0f: 0x098b, 0xb10: 0x0ccf, 0xb11: 0x0d4b,
+	0xb12: 0x0d0b, 0xb13: 0x104b, 0xb14: 0x08fb, 0xb15: 0x0f03, 0xb16: 0x1387, 0xb17: 0x105f,
+	0xb18: 0x0843, 0xb19: 0x108f, 0xb1a: 0x0f9b, 0xb1b: 0x0a17, 0xb1c: 0x140f, 0xb1d: 0x077f,
+	0xb1e: 0x08ab, 0xb1f: 0x0df7, 0xb20: 0x1527, 0xb21: 0x0743, 0xb22: 0x07d3, 0xb23: 0x0d9b,
+	0xb24: 0x06cf, 0xb25: 0x06e7, 0xb26: 0x06d3, 0xb27: 0x0adb, 0xb28: 0x08ef, 0xb29: 0x087f,
+	0xb2a: 0x0a57, 0xb2b: 0x0a4b, 0xb2c: 0x0feb, 0xb2d: 0x073f, 0xb2e: 0x139b, 0xb2f: 0x089b,
+	0xb30: 0x09f3, 0xb31: 0x18dc, 0xb32: 0x18df, 0xb33: 0x18e2, 0xb34: 0x18e5, 0xb35: 0x18ee,
+	0xb36: 0x18f1, 0xb37: 0x18f4, 0xb38: 0x18f7, 0xb39: 0x18fa, 0xb3a: 0x18fd, 0xb3b: 0x1900,
+	0xb3c: 0x1903, 0xb3d: 0x1906, 0xb3e: 0x1909, 0xb3f: 0x1912,
 	// Block 0x2d, offset 0xb40
-	0xb40: 0x2b0c, 0xb41: 0x29a8, 0xb42: 0x2b1c, 0xb43: 0x2880, 0xb44: 0x2ee4, 0xb45: 0x288a,
-	0xb46: 0x2894, 0xb47: 0x2f28, 0xb48: 0x29b5, 0xb49: 0x289e, 0xb4a: 0x28a8, 0xb4b: 0x28b2,
-	0xb4c: 0x29dc, 0xb4d: 0x29e9, 0xb4e: 0x29c2, 0xb4f: 0x29cf, 0xb50: 0x2ea9, 0xb51: 0x29f6,
-	0xb52: 0x2a03, 0xb53: 0x2bbe, 0xb54: 0x26bb, 0xb55: 0x2bd1, 0xb56: 0x2be4, 0xb57: 0x2b2c,
-	0xb58: 0x2a10, 0xb59: 0x2bf7, 0xb5a: 0x2c0a, 0xb5b: 0x2a1d, 0xb5c: 0x28bc, 0xb5d: 0x28c6,
-	0xb5e: 0x2eb7, 0xb5f: 0x2a2a, 0xb60: 0x2b3c, 0xb61: 0x2ef5, 0xb62: 0x28d0, 0xb63: 0x28da,
-	0xb64: 0x2a37, 0xb65: 0x28e4, 0xb66: 0x28ee, 0xb67: 0x26d0, 0xb68: 0x26d7, 0xb69: 0x28f8,
-	0xb6a: 0x2902, 0xb6b: 0x2c1d, 0xb6c: 0x2a44, 0xb6d: 0x2b4c, 0xb6e: 0x2c30, 0xb6f: 0x2a51,
-	0xb70: 0x2916, 0xb71: 0x290c, 0xb72: 0x2f3c, 0xb73: 0x2a5e, 0xb74: 0x2c43, 0xb75: 0x2920,
-	0xb76: 0x2b5c, 0xb77: 0x292a, 0xb78: 0x2a78, 0xb79: 0x2934, 0xb7a: 0x2a85, 0xb7b: 0x2f06,
-	0xb7c: 0x2a6b, 0xb7d: 0x2b6c, 0xb7e: 0x2a92, 0xb7f: 0x26de,
+	0xb40: 0x1cc6, 0xb41: 0x1cd5, 0xb42: 0x1ce4, 0xb43: 0x1cf3, 0xb44: 0x1d02, 0xb45: 0x1d11,
+	0xb46: 0x1d20, 0xb47: 0x1d2f, 0xb48: 0x1d3e, 0xb49: 0x218c, 0xb4a: 0x219e, 0xb4b: 0x21b0,
+	0xb4c: 0x1954, 0xb4d: 0x1c04, 0xb4e: 0x19d2, 0xb4f: 0x1ba8, 0xb50: 0x04cb, 0xb51: 0x04d3,
+	0xb52: 0x04db, 0xb53: 0x04e3, 0xb54: 0x04eb, 0xb55: 0x04ef, 0xb56: 0x04f3, 0xb57: 0x04f7,
+	0xb58: 0x04fb, 0xb59: 0x04ff, 0xb5a: 0x0503, 0xb5b: 0x0507, 0xb5c: 0x050b, 0xb5d: 0x050f,
+	0xb5e: 0x0513, 0xb5f: 0x0517, 0xb60: 0x051b, 0xb61: 0x0523, 0xb62: 0x0527, 0xb63: 0x052b,
+	0xb64: 0x052f, 0xb65: 0x0533, 0xb66: 0x0537, 0xb67: 0x053b, 0xb68: 0x053f, 0xb69: 0x0543,
+	0xb6a: 0x0547, 0xb6b: 0x054b, 0xb6c: 0x054f, 0xb6d: 0x0553, 0xb6e: 0x0557, 0xb6f: 0x055b,
+	0xb70: 0x055f, 0xb71: 0x0563, 0xb72: 0x0567, 0xb73: 0x056f, 0xb74: 0x0577, 0xb75: 0x057f,
+	0xb76: 0x0583, 0xb77: 0x0587, 0xb78: 0x058b, 0xb79: 0x058f, 0xb7a: 0x0593, 0xb7b: 0x0597,
+	0xb7c: 0x059b, 0xb7d: 0x059f, 0xb7e: 0x05a3,
 	// Block 0x2e, offset 0xb80
-	0xb80: 0x2f17, 0xb81: 0x293e, 0xb82: 0x2948, 0xb83: 0x2a9f, 0xb84: 0x2952, 0xb85: 0x295c,
-	0xb86: 0x2966, 0xb87: 0x2b7c, 0xb88: 0x2aac, 0xb89: 0x26e5, 0xb8a: 0x2c56, 0xb8b: 0x2e90,
-	0xb8c: 0x2b8c, 0xb8d: 0x2ab9, 0xb8e: 0x2ec5, 0xb8f: 0x2970, 0xb90: 0x297a, 0xb91: 0x2ac6,
-	0xb92: 0x26ec, 0xb93: 0x2ad3, 0xb94: 0x2b9c, 0xb95: 0x26f3, 0xb96: 0x2c69, 0xb97: 0x2984,
-	0xb98: 0x1cb7, 0xb99: 0x1ccb, 0xb9a: 0x1cda, 0xb9b: 0x1ce9, 0xb9c: 0x1cf8, 0xb9d: 0x1d07,
-	0xb9e: 0x1d16, 0xb9f: 0x1d25, 0xba0: 0x1d34, 0xba1: 0x1d43, 0xba2: 0x2192, 0xba3: 0x21a4,
-	0xba4: 0x21b6, 0xba5: 0x21c2, 0xba6: 0x21ce, 0xba7: 0x21da, 0xba8: 0x21e6, 0xba9: 0x21f2,
-	0xbaa: 0x21fe, 0xbab: 0x220a, 0xbac: 0x2246, 0xbad: 0x2252, 0xbae: 0x225e, 0xbaf: 0x226a,
-	0xbb0: 0x2276, 0xbb1: 0x1c14, 0xbb2: 0x19c6, 0xbb3: 0x1936, 0xbb4: 0x1be4, 0xbb5: 0x1a47,
-	0xbb6: 0x1a56, 0xbb7: 0x19cc, 0xbb8: 0x1bfc, 0xbb9: 0x1c00, 0xbba: 0x1960, 0xbbb: 0x2701,
-	0xbbc: 0x270f, 0xbbd: 0x26fa, 0xbbe: 0x2708, 0xbbf: 0x2ae0,
+	0xb80: 0x2b0c, 0xb81: 0x29a8, 0xb82: 0x2b1c, 0xb83: 0x2880, 0xb84: 0x2ee4, 0xb85: 0x288a,
+	0xb86: 0x2894, 0xb87: 0x2f28, 0xb88: 0x29b5, 0xb89: 0x289e, 0xb8a: 0x28a8, 0xb8b: 0x28b2,
+	0xb8c: 0x29dc, 0xb8d: 0x29e9, 0xb8e: 0x29c2, 0xb8f: 0x29cf, 0xb90: 0x2ea9, 0xb91: 0x29f6,
+	0xb92: 0x2a03, 0xb93: 0x2bbe, 0xb94: 0x26bb, 0xb95: 0x2bd1, 0xb96: 0x2be4, 0xb97: 0x2b2c,
+	0xb98: 0x2a10, 0xb99: 0x2bf7, 0xb9a: 0x2c0a, 0xb9b: 0x2a1d, 0xb9c: 0x28bc, 0xb9d: 0x28c6,
+	0xb9e: 0x2eb7, 0xb9f: 0x2a2a, 0xba0: 0x2b3c, 0xba1: 0x2ef5, 0xba2: 0x28d0, 0xba3: 0x28da,
+	0xba4: 0x2a37, 0xba5: 0x28e4, 0xba6: 0x28ee, 0xba7: 0x26d0, 0xba8: 0x26d7, 0xba9: 0x28f8,
+	0xbaa: 0x2902, 0xbab: 0x2c1d, 0xbac: 0x2a44, 0xbad: 0x2b4c, 0xbae: 0x2c30, 0xbaf: 0x2a51,
+	0xbb0: 0x2916, 0xbb1: 0x290c, 0xbb2: 0x2f3c, 0xbb3: 0x2a5e, 0xbb4: 0x2c43, 0xbb5: 0x2920,
+	0xbb6: 0x2b5c, 0xbb7: 0x292a, 0xbb8: 0x2a78, 0xbb9: 0x2934, 0xbba: 0x2a85, 0xbbb: 0x2f06,
+	0xbbc: 0x2a6b, 0xbbd: 0x2b6c, 0xbbe: 0x2a92, 0xbbf: 0x26de,
 	// Block 0x2f, offset 0xbc0
-	0xbc0: 0x1a4a, 0xbc1: 0x1a32, 0xbc2: 0x1c60, 0xbc3: 0x1a1a, 0xbc4: 0x19f3, 0xbc5: 0x1969,
-	0xbc6: 0x1978, 0xbc7: 0x1948, 0xbc8: 0x1bf0, 0xbc9: 0x1d52, 0xbca: 0x1a4d, 0xbcb: 0x1a35,
-	0xbcc: 0x1c64, 0xbcd: 0x1c70, 0xbce: 0x1a26, 0xbcf: 0x19fc, 0xbd0: 0x1957, 0xbd1: 0x1c1c,
-	0xbd2: 0x1bb0, 0xbd3: 0x1b9c, 0xbd4: 0x1bcc, 0xbd5: 0x1c74, 0xbd6: 0x1a29, 0xbd7: 0x19c9,
-	0xbd8: 0x19ff, 0xbd9: 0x19de, 0xbda: 0x1a41, 0xbdb: 0x1c78, 0xbdc: 0x1a2c, 0xbdd: 0x19c0,
-	0xbde: 0x1a02, 0xbdf: 0x1c3c, 0xbe0: 0x1bf4, 0xbe1: 0x1a14, 0xbe2: 0x1c24, 0xbe3: 0x1c40,
-	0xbe4: 0x1bf8, 0xbe5: 0x1a17, 0xbe6: 0x1c28, 0xbe7: 0x22e8, 0xbe8: 0x22fc, 0xbe9: 0x1996,
-	0xbea: 0x1c20, 0xbeb: 0x1bb4, 0xbec: 0x1ba0, 0xbed: 0x1c48, 0xbee: 0x2716, 0xbef: 0x27ad,
-	0xbf0: 0x1a59, 0xbf1: 0x1a44, 0xbf2: 0x1c7c, 0xbf3: 0x1a2f, 0xbf4: 0x1a50, 0xbf5: 0x1a38,
-	0xbf6: 0x1c68, 0xbf7: 0x1a1d, 0xbf8: 0x19f6, 0xbf9: 0x1981, 0xbfa: 0x1a53, 0xbfb: 0x1a3b,
-	0xbfc: 0x1c6c, 0xbfd: 0x1a20, 0xbfe: 0x19f9, 0xbff: 0x1984,
+	0xbc0: 0x2f17, 0xbc1: 0x293e, 0xbc2: 0x2948, 0xbc3: 0x2a9f, 0xbc4: 0x2952, 0xbc5: 0x295c,
+	0xbc6: 0x2966, 0xbc7: 0x2b7c, 0xbc8: 0x2aac, 0xbc9: 0x26e5, 0xbca: 0x2c56, 0xbcb: 0x2e90,
+	0xbcc: 0x2b8c, 0xbcd: 0x2ab9, 0xbce: 0x2ec5, 0xbcf: 0x2970, 0xbd0: 0x297a, 0xbd1: 0x2ac6,
+	0xbd2: 0x26ec, 0xbd3: 0x2ad3, 0xbd4: 0x2b9c, 0xbd5: 0x26f3, 0xbd6: 0x2c69, 0xbd7: 0x2984,
+	0xbd8: 0x1cb7, 0xbd9: 0x1ccb, 0xbda: 0x1cda, 0xbdb: 0x1ce9, 0xbdc: 0x1cf8, 0xbdd: 0x1d07,
+	0xbde: 0x1d16, 0xbdf: 0x1d25, 0xbe0: 0x1d34, 0xbe1: 0x1d43, 0xbe2: 0x2192, 0xbe3: 0x21a4,
+	0xbe4: 0x21b6, 0xbe5: 0x21c2, 0xbe6: 0x21ce, 0xbe7: 0x21da, 0xbe8: 0x21e6, 0xbe9: 0x21f2,
+	0xbea: 0x21fe, 0xbeb: 0x220a, 0xbec: 0x2246, 0xbed: 0x2252, 0xbee: 0x225e, 0xbef: 0x226a,
+	0xbf0: 0x2276, 0xbf1: 0x1c14, 0xbf2: 0x19c6, 0xbf3: 0x1936, 0xbf4: 0x1be4, 0xbf5: 0x1a47,
+	0xbf6: 0x1a56, 0xbf7: 0x19cc, 0xbf8: 0x1bfc, 0xbf9: 0x1c00, 0xbfa: 0x1960, 0xbfb: 0x2701,
+	0xbfc: 0x270f, 0xbfd: 0x26fa, 0xbfe: 0x2708, 0xbff: 0x2ae0,
 	// Block 0x30, offset 0xc00
-	0xc00: 0x1c2c, 0xc01: 0x1bb8, 0xc02: 0x1d4d, 0xc03: 0x1939, 0xc04: 0x19ba, 0xc05: 0x19bd,
-	0xc06: 0x22f5, 0xc07: 0x1b94, 0xc08: 0x19c3, 0xc09: 0x194b, 0xc0a: 0x19e1, 0xc0b: 0x194e,
-	0xc0c: 0x19ea, 0xc0d: 0x196c, 0xc0e: 0x196f, 0xc0f: 0x1a05, 0xc10: 0x1a0b, 0xc11: 0x1a0e,
-	0xc12: 0x1c30, 0xc13: 0x1a11, 0xc14: 0x1a23, 0xc15: 0x1c38, 0xc16: 0x1c44, 0xc17: 0x1990,
-	0xc18: 0x1d57, 0xc19: 0x1bbc, 0xc1a: 0x1993, 0xc1b: 0x1a5c, 0xc1c: 0x19a5, 0xc1d: 0x19b4,
-	0xc1e: 0x22e2, 0xc1f: 0x22dc, 0xc20: 0x1cc1, 0xc21: 0x1cd0, 0xc22: 0x1cdf, 0xc23: 0x1cee,
-	0xc24: 0x1cfd, 0xc25: 0x1d0c, 0xc26: 0x1d1b, 0xc27: 0x1d2a, 0xc28: 0x1d39, 0xc29: 0x2186,
-	0xc2a: 0x2198, 0xc2b: 0x21aa, 0xc2c: 0x21bc, 0xc2d: 0x21c8, 0xc2e: 0x21d4, 0xc2f: 0x21e0,
-	0xc30: 0x21ec, 0xc31: 0x21f8, 0xc32: 0x2204, 0xc33: 0x2240, 0xc34: 0x224c, 0xc35: 0x2258,
-	0xc36: 0x2264, 0xc37: 0x2270, 0xc38: 0x227c, 0xc39: 0x2282, 0xc3a: 0x2288, 0xc3b: 0x228e,
-	0xc3c: 0x2294, 0xc3d: 0x22a6, 0xc3e: 0x22ac, 0xc3f: 0x1c10,
+	0xc00: 0x1a4a, 0xc01: 0x1a32, 0xc02: 0x1c60, 0xc03: 0x1a1a, 0xc04: 0x19f3, 0xc05: 0x1969,
+	0xc06: 0x1978, 0xc07: 0x1948, 0xc08: 0x1bf0, 0xc09: 0x1d52, 0xc0a: 0x1a4d, 0xc0b: 0x1a35,
+	0xc0c: 0x1c64, 0xc0d: 0x1c70, 0xc0e: 0x1a26, 0xc0f: 0x19fc, 0xc10: 0x1957, 0xc11: 0x1c1c,
+	0xc12: 0x1bb0, 0xc13: 0x1b9c, 0xc14: 0x1bcc, 0xc15: 0x1c74, 0xc16: 0x1a29, 0xc17: 0x19c9,
+	0xc18: 0x19ff, 0xc19: 0x19de, 0xc1a: 0x1a41, 0xc1b: 0x1c78, 0xc1c: 0x1a2c, 0xc1d: 0x19c0,
+	0xc1e: 0x1a02, 0xc1f: 0x1c3c, 0xc20: 0x1bf4, 0xc21: 0x1a14, 0xc22: 0x1c24, 0xc23: 0x1c40,
+	0xc24: 0x1bf8, 0xc25: 0x1a17, 0xc26: 0x1c28, 0xc27: 0x22e8, 0xc28: 0x22fc, 0xc29: 0x1996,
+	0xc2a: 0x1c20, 0xc2b: 0x1bb4, 0xc2c: 0x1ba0, 0xc2d: 0x1c48, 0xc2e: 0x2716, 0xc2f: 0x27ad,
+	0xc30: 0x1a59, 0xc31: 0x1a44, 0xc32: 0x1c7c, 0xc33: 0x1a2f, 0xc34: 0x1a50, 0xc35: 0x1a38,
+	0xc36: 0x1c68, 0xc37: 0x1a1d, 0xc38: 0x19f6, 0xc39: 0x1981, 0xc3a: 0x1a53, 0xc3b: 0x1a3b,
+	0xc3c: 0x1c6c, 0xc3d: 0x1a20, 0xc3e: 0x19f9, 0xc3f: 0x1984,
 	// Block 0x31, offset 0xc40
-	0xc40: 0x1377, 0xc41: 0x0cfb, 0xc42: 0x13d3, 0xc43: 0x139f, 0xc44: 0x0e57, 0xc45: 0x06eb,
-	0xc46: 0x08df, 0xc47: 0x162b, 0xc48: 0x162b, 0xc49: 0x0a0b, 0xc4a: 0x145f, 0xc4b: 0x0943,
-	0xc4c: 0x0a07, 0xc4d: 0x0bef, 0xc4e: 0x0fcf, 0xc4f: 0x115f, 0xc50: 0x1297, 0xc51: 0x12d3,
-	0xc52: 0x1307, 0xc53: 0x141b, 0xc54: 0x0d73, 0xc55: 0x0dff, 0xc56: 0x0eab, 0xc57: 0x0f43,
-	0xc58: 0x125f, 0xc59: 0x1447, 0xc5a: 0x1573, 0xc5b: 0x070f, 0xc5c: 0x08b3, 0xc5d: 0x0d87,
-	0xc5e: 0x0ecf, 0xc5f: 0x1293, 0xc60: 0x15c3, 0xc61: 0x0ab3, 0xc62: 0x0e77, 0xc63: 0x1283,
-	0xc64: 0x1317, 0xc65: 0x0c23, 0xc66: 0x11bb, 0xc67: 0x12df, 0xc68: 0x0b1f, 0xc69: 0x0d0f,
-	0xc6a: 0x0e17, 0xc6b: 0x0f1b, 0xc6c: 0x1427, 0xc6d: 0x074f, 0xc6e: 0x07e7, 0xc6f: 0x0853,
-	0xc70: 0x0c8b, 0xc71: 0x0d7f, 0xc72: 0x0ecb, 0xc73: 0x0fef, 0xc74: 0x1177, 0xc75: 0x128b,
-	0xc76: 0x12a3, 0xc77: 0x13c7, 0xc78: 0x14ef, 0xc79: 0x15a3, 0xc7a: 0x15bf, 0xc7b: 0x102b,
-	0xc7c: 0x106b, 0xc7d: 0x1123, 0xc7e: 0x1243, 0xc7f: 0x147b,
+	0xc40: 0x1c2c, 0xc41: 0x1bb8, 0xc42: 0x1d4d, 0xc43: 0x1939, 0xc44: 0x19ba, 0xc45: 0x19bd,
+	0xc46: 0x22f5, 0xc47: 0x1b94, 0xc48: 0x19c3, 0xc49: 0x194b, 0xc4a: 0x19e1, 0xc4b: 0x194e,
+	0xc4c: 0x19ea, 0xc4d: 0x196c, 0xc4e: 0x196f, 0xc4f: 0x1a05, 0xc50: 0x1a0b, 0xc51: 0x1a0e,
+	0xc52: 0x1c30, 0xc53: 0x1a11, 0xc54: 0x1a23, 0xc55: 0x1c38, 0xc56: 0x1c44, 0xc57: 0x1990,
+	0xc58: 0x1d57, 0xc59: 0x1bbc, 0xc5a: 0x1993, 0xc5b: 0x1a5c, 0xc5c: 0x19a5, 0xc5d: 0x19b4,
+	0xc5e: 0x22e2, 0xc5f: 0x22dc, 0xc60: 0x1cc1, 0xc61: 0x1cd0, 0xc62: 0x1cdf, 0xc63: 0x1cee,
+	0xc64: 0x1cfd, 0xc65: 0x1d0c, 0xc66: 0x1d1b, 0xc67: 0x1d2a, 0xc68: 0x1d39, 0xc69: 0x2186,
+	0xc6a: 0x2198, 0xc6b: 0x21aa, 0xc6c: 0x21bc, 0xc6d: 0x21c8, 0xc6e: 0x21d4, 0xc6f: 0x21e0,
+	0xc70: 0x21ec, 0xc71: 0x21f8, 0xc72: 0x2204, 0xc73: 0x2240, 0xc74: 0x224c, 0xc75: 0x2258,
+	0xc76: 0x2264, 0xc77: 0x2270, 0xc78: 0x227c, 0xc79: 0x2282, 0xc7a: 0x2288, 0xc7b: 0x228e,
+	0xc7c: 0x2294, 0xc7d: 0x22a6, 0xc7e: 0x22ac, 0xc7f: 0x1c10,
 	// Block 0x32, offset 0xc80
-	0xc80: 0x15cb, 0xc81: 0x134b, 0xc82: 0x09c7, 0xc83: 0x0b3b, 0xc84: 0x10db, 0xc85: 0x119b,
-	0xc86: 0x0eff, 0xc87: 0x1033, 0xc88: 0x1397, 0xc89: 0x14e7, 0xc8a: 0x09c3, 0xc8b: 0x0a8f,
-	0xc8c: 0x0d77, 0xc8d: 0x0e2b, 0xc8e: 0x0e5f, 0xc8f: 0x1113, 0xc90: 0x113b, 0xc91: 0x14a7,
-	0xc92: 0x084f, 0xc93: 0x11a7, 0xc94: 0x07f3, 0xc95: 0x07ef, 0xc96: 0x1097, 0xc97: 0x1127,
-	0xc98: 0x125b, 0xc99: 0x14af, 0xc9a: 0x1367, 0xc9b: 0x0c27, 0xc9c: 0x0d73, 0xc9d: 0x1357,
-	0xc9e: 0x06f7, 0xc9f: 0x0a63, 0xca0: 0x0b93, 0xca1: 0x0f2f, 0xca2: 0x0faf, 0xca3: 0x0873,
-	0xca4: 0x103b, 0xca5: 0x075f, 0xca6: 0x0b77, 0xca7: 0x06d7, 0xca8: 0x0deb, 0xca9: 0x0ca3,
-	0xcaa: 0x110f, 0xcab: 0x08c7, 0xcac: 0x09b3, 0xcad: 0x0ffb, 0xcae: 0x1263, 0xcaf: 0x133b,
-	0xcb0: 0x0db7, 0xcb1: 0x13f7, 0xcb2: 0x0de3, 0xcb3: 0x0c37, 0xcb4: 0x121b, 0xcb5: 0x0c57,
-	0xcb6: 0x0fab, 0xcb7: 0x072b, 0xcb8: 0x07a7, 0xcb9: 0x07eb, 0xcba: 0x0d53, 0xcbb: 0x10fb,
-	0xcbc: 0x11f3, 0xcbd: 0x1347, 0xcbe: 0x145b, 0xcbf: 0x085b,
+	0xc80: 0x1377, 0xc81: 0x0cfb, 0xc82: 0x13d3, 0xc83: 0x139f, 0xc84: 0x0e57, 0xc85: 0x06eb,
+	0xc86: 0x08df, 0xc87: 0x162b, 0xc88: 0x162b, 0xc89: 0x0a0b, 0xc8a: 0x145f, 0xc8b: 0x0943,
+	0xc8c: 0x0a07, 0xc8d: 0x0bef, 0xc8e: 0x0fcf, 0xc8f: 0x115f, 0xc90: 0x1297, 0xc91: 0x12d3,
+	0xc92: 0x1307, 0xc93: 0x141b, 0xc94: 0x0d73, 0xc95: 0x0dff, 0xc96: 0x0eab, 0xc97: 0x0f43,
+	0xc98: 0x125f, 0xc99: 0x1447, 0xc9a: 0x1573, 0xc9b: 0x070f, 0xc9c: 0x08b3, 0xc9d: 0x0d87,
+	0xc9e: 0x0ecf, 0xc9f: 0x1293, 0xca0: 0x15c3, 0xca1: 0x0ab3, 0xca2: 0x0e77, 0xca3: 0x1283,
+	0xca4: 0x1317, 0xca5: 0x0c23, 0xca6: 0x11bb, 0xca7: 0x12df, 0xca8: 0x0b1f, 0xca9: 0x0d0f,
+	0xcaa: 0x0e17, 0xcab: 0x0f1b, 0xcac: 0x1427, 0xcad: 0x074f, 0xcae: 0x07e7, 0xcaf: 0x0853,
+	0xcb0: 0x0c8b, 0xcb1: 0x0d7f, 0xcb2: 0x0ecb, 0xcb3: 0x0fef, 0xcb4: 0x1177, 0xcb5: 0x128b,
+	0xcb6: 0x12a3, 0xcb7: 0x13c7, 0xcb8: 0x14ef, 0xcb9: 0x15a3, 0xcba: 0x15bf, 0xcbb: 0x102b,
+	0xcbc: 0x106b, 0xcbd: 0x1123, 0xcbe: 0x1243, 0xcbf: 0x147b,
 	// Block 0x33, offset 0xcc0
-	0xcc0: 0x090f, 0xcc1: 0x0a17, 0xcc2: 0x0b2f, 0xcc3: 0x0cbf, 0xcc4: 0x0e7b, 0xcc5: 0x103f,
-	0xcc6: 0x1497, 0xcc7: 0x157b, 0xcc8: 0x15cf, 0xcc9: 0x15e7, 0xcca: 0x0837, 0xccb: 0x0cf3,
-	0xccc: 0x0da3, 0xccd: 0x13eb, 0xcce: 0x0afb, 0xccf: 0x0bd7, 0xcd0: 0x0bf3, 0xcd1: 0x0c83,
-	0xcd2: 0x0e6b, 0xcd3: 0x0eb7, 0xcd4: 0x0f67, 0xcd5: 0x108b, 0xcd6: 0x112f, 0xcd7: 0x1193,
-	0xcd8: 0x13db, 0xcd9: 0x126b, 0xcda: 0x1403, 0xcdb: 0x147f, 0xcdc: 0x080f, 0xcdd: 0x083b,
-	0xcde: 0x0923, 0xcdf: 0x0ea7, 0xce0: 0x12f3, 0xce1: 0x133b, 0xce2: 0x0b1b, 0xce3: 0x0b8b,
-	0xce4: 0x0c4f, 0xce5: 0x0daf, 0xce6: 0x10d7, 0xce7: 0x0f23, 0xce8: 0x073b, 0xce9: 0x097f,
-	0xcea: 0x0a63, 0xceb: 0x0ac7, 0xcec: 0x0b97, 0xced: 0x0f3f, 0xcee: 0x0f5b, 0xcef: 0x116b,
-	0xcf0: 0x118b, 0xcf1: 0x1463, 0xcf2: 0x14e3, 0xcf3: 0x14f3, 0xcf4: 0x152f, 0xcf5: 0x0753,
-	0xcf6: 0x107f, 0xcf7: 0x144f, 0xcf8: 0x14cb, 0xcf9: 0x0baf, 0xcfa: 0x0717, 0xcfb: 0x0777,
-	0xcfc: 0x0a67, 0xcfd: 0x0a87, 0xcfe: 0x0caf, 0xcff: 0x0d73,
+	0xcc0: 0x15cb, 0xcc1: 0x134b, 0xcc2: 0x09c7, 0xcc3: 0x0b3b, 0xcc4: 0x10db, 0xcc5: 0x119b,
+	0xcc6: 0x0eff, 0xcc7: 0x1033, 0xcc8: 0x1397, 0xcc9: 0x14e7, 0xcca: 0x09c3, 0xccb: 0x0a8f,
+	0xccc: 0x0d77, 0xccd: 0x0e2b, 0xcce: 0x0e5f, 0xccf: 0x1113, 0xcd0: 0x113b, 0xcd1: 0x14a7,
+	0xcd2: 0x084f, 0xcd3: 0x11a7, 0xcd4: 0x07f3, 0xcd5: 0x07ef, 0xcd6: 0x1097, 0xcd7: 0x1127,
+	0xcd8: 0x125b, 0xcd9: 0x14af, 0xcda: 0x1367, 0xcdb: 0x0c27, 0xcdc: 0x0d73, 0xcdd: 0x1357,
+	0xcde: 0x06f7, 0xcdf: 0x0a63, 0xce0: 0x0b93, 0xce1: 0x0f2f, 0xce2: 0x0faf, 0xce3: 0x0873,
+	0xce4: 0x103b, 0xce5: 0x075f, 0xce6: 0x0b77, 0xce7: 0x06d7, 0xce8: 0x0deb, 0xce9: 0x0ca3,
+	0xcea: 0x110f, 0xceb: 0x08c7, 0xcec: 0x09b3, 0xced: 0x0ffb, 0xcee: 0x1263, 0xcef: 0x133b,
+	0xcf0: 0x0db7, 0xcf1: 0x13f7, 0xcf2: 0x0de3, 0xcf3: 0x0c37, 0xcf4: 0x121b, 0xcf5: 0x0c57,
+	0xcf6: 0x0fab, 0xcf7: 0x072b, 0xcf8: 0x07a7, 0xcf9: 0x07eb, 0xcfa: 0x0d53, 0xcfb: 0x10fb,
+	0xcfc: 0x11f3, 0xcfd: 0x1347, 0xcfe: 0x145b, 0xcff: 0x085b,
 	// Block 0x34, offset 0xd00
-	0xd00: 0x0ec3, 0xd01: 0x0fcb, 0xd02: 0x1277, 0xd03: 0x1417, 0xd04: 0x1623, 0xd05: 0x0ce3,
-	0xd06: 0x14a3, 0xd07: 0x0833, 0xd08: 0x0d2f, 0xd09: 0x0d3b, 0xd0a: 0x0e0f, 0xd0b: 0x0e47,
-	0xd0c: 0x0f4b, 0xd0d: 0x0fa7, 0xd0e: 0x1027, 0xd0f: 0x110b, 0xd10: 0x153b, 0xd11: 0x07af,
-	0xd12: 0x0c03, 0xd13: 0x14b3, 0xd14: 0x0767, 0xd15: 0x0aab, 0xd16: 0x0e2f, 0xd17: 0x13df,
-	0xd18: 0x0b67, 0xd19: 0x0bb7, 0xd1a: 0x0d43, 0xd1b: 0x0f2f, 0xd1c: 0x14bb, 0xd1d: 0x0817,
-	0xd1e: 0x08ff, 0xd1f: 0x0a97, 0xd20: 0x0cd3, 0xd21: 0x0d1f, 0xd22: 0x0d5f, 0xd23: 0x0df3,
-	0xd24: 0x0f47, 0xd25: 0x0fbb, 0xd26: 0x1157, 0xd27: 0x12f7, 0xd28: 0x1303, 0xd29: 0x1457,
-	0xd2a: 0x14d7, 0xd2b: 0x0883, 0xd2c: 0x0e4b, 0xd2d: 0x0903, 0xd2e: 0x0ec7, 0xd2f: 0x0f6b,
-	0xd30: 0x1287, 0xd31: 0x14bf, 0xd32: 0x15ab, 0xd33: 0x15d3, 0xd34: 0x0d37, 0xd35: 0x0e27,
-	0xd36: 0x11c3, 0xd37: 0x10b7, 0xd38: 0x10c3, 0xd39: 0x10e7, 0xd3a: 0x0f17, 0xd3b: 0x0e9f,
-	0xd3c: 0x1363, 0xd3d: 0x0733, 0xd3e: 0x122b, 0xd3f: 0x081b,
+	0xd00: 0x090f, 0xd01: 0x0a17, 0xd02: 0x0b2f, 0xd03: 0x0cbf, 0xd04: 0x0e7b, 0xd05: 0x103f,
+	0xd06: 0x1497, 0xd07: 0x157b, 0xd08: 0x15cf, 0xd09: 0x15e7, 0xd0a: 0x0837, 0xd0b: 0x0cf3,
+	0xd0c: 0x0da3, 0xd0d: 0x13eb, 0xd0e: 0x0afb, 0xd0f: 0x0bd7, 0xd10: 0x0bf3, 0xd11: 0x0c83,
+	0xd12: 0x0e6b, 0xd13: 0x0eb7, 0xd14: 0x0f67, 0xd15: 0x108b, 0xd16: 0x112f, 0xd17: 0x1193,
+	0xd18: 0x13db, 0xd19: 0x126b, 0xd1a: 0x1403, 0xd1b: 0x147f, 0xd1c: 0x080f, 0xd1d: 0x083b,
+	0xd1e: 0x0923, 0xd1f: 0x0ea7, 0xd20: 0x12f3, 0xd21: 0x133b, 0xd22: 0x0b1b, 0xd23: 0x0b8b,
+	0xd24: 0x0c4f, 0xd25: 0x0daf, 0xd26: 0x10d7, 0xd27: 0x0f23, 0xd28: 0x073b, 0xd29: 0x097f,
+	0xd2a: 0x0a63, 0xd2b: 0x0ac7, 0xd2c: 0x0b97, 0xd2d: 0x0f3f, 0xd2e: 0x0f5b, 0xd2f: 0x116b,
+	0xd30: 0x118b, 0xd31: 0x1463, 0xd32: 0x14e3, 0xd33: 0x14f3, 0xd34: 0x152f, 0xd35: 0x0753,
+	0xd36: 0x107f, 0xd37: 0x144f, 0xd38: 0x14cb, 0xd39: 0x0baf, 0xd3a: 0x0717, 0xd3b: 0x0777,
+	0xd3c: 0x0a67, 0xd3d: 0x0a87, 0xd3e: 0x0caf, 0xd3f: 0x0d73,
 	// Block 0x35, offset 0xd40
-	0xd40: 0x080b, 0xd41: 0x0b0b, 0xd42: 0x0c2b, 0xd43: 0x10f3, 0xd44: 0x0a53, 0xd45: 0x0e03,
-	0xd46: 0x0cef, 0xd47: 0x13e7, 0xd48: 0x12e7, 0xd49: 0x14ab, 0xd4a: 0x1323, 0xd4b: 0x0b27,
-	0xd4c: 0x0787, 0xd4d: 0x095b, 0xd50: 0x09af,
-	0xd52: 0x0cdf, 0xd55: 0x07f7, 0xd56: 0x0f1f, 0xd57: 0x0fe3,
-	0xd58: 0x1047, 0xd59: 0x1063, 0xd5a: 0x1067, 0xd5b: 0x107b, 0xd5c: 0x14fb, 0xd5d: 0x10eb,
-	0xd5e: 0x116f, 0xd60: 0x128f, 0xd62: 0x1353,
-	0xd65: 0x1407, 0xd66: 0x1433,
-	0xd6a: 0x154f, 0xd6b: 0x1553, 0xd6c: 0x1557, 0xd6d: 0x15bb, 0xd6e: 0x142b, 0xd6f: 0x14c7,
-	0xd70: 0x0757, 0xd71: 0x077b, 0xd72: 0x078f, 0xd73: 0x084b, 0xd74: 0x0857, 0xd75: 0x0897,
-	0xd76: 0x094b, 0xd77: 0x0967, 0xd78: 0x096f, 0xd79: 0x09ab, 0xd7a: 0x09b7, 0xd7b: 0x0a93,
-	0xd7c: 0x0a9b, 0xd7d: 0x0ba3, 0xd7e: 0x0bcb, 0xd7f: 0x0bd3,
+	0xd40: 0x0ec3, 0xd41: 0x0fcb, 0xd42: 0x1277, 0xd43: 0x1417, 0xd44: 0x1623, 0xd45: 0x0ce3,
+	0xd46: 0x14a3, 0xd47: 0x0833, 0xd48: 0x0d2f, 0xd49: 0x0d3b, 0xd4a: 0x0e0f, 0xd4b: 0x0e47,
+	0xd4c: 0x0f4b, 0xd4d: 0x0fa7, 0xd4e: 0x1027, 0xd4f: 0x110b, 0xd50: 0x153b, 0xd51: 0x07af,
+	0xd52: 0x0c03, 0xd53: 0x14b3, 0xd54: 0x0767, 0xd55: 0x0aab, 0xd56: 0x0e2f, 0xd57: 0x13df,
+	0xd58: 0x0b67, 0xd59: 0x0bb7, 0xd5a: 0x0d43, 0xd5b: 0x0f2f, 0xd5c: 0x14bb, 0xd5d: 0x0817,
+	0xd5e: 0x08ff, 0xd5f: 0x0a97, 0xd60: 0x0cd3, 0xd61: 0x0d1f, 0xd62: 0x0d5f, 0xd63: 0x0df3,
+	0xd64: 0x0f47, 0xd65: 0x0fbb, 0xd66: 0x1157, 0xd67: 0x12f7, 0xd68: 0x1303, 0xd69: 0x1457,
+	0xd6a: 0x14d7, 0xd6b: 0x0883, 0xd6c: 0x0e4b, 0xd6d: 0x0903, 0xd6e: 0x0ec7, 0xd6f: 0x0f6b,
+	0xd70: 0x1287, 0xd71: 0x14bf, 0xd72: 0x15ab, 0xd73: 0x15d3, 0xd74: 0x0d37, 0xd75: 0x0e27,
+	0xd76: 0x11c3, 0xd77: 0x10b7, 0xd78: 0x10c3, 0xd79: 0x10e7, 0xd7a: 0x0f17, 0xd7b: 0x0e9f,
+	0xd7c: 0x1363, 0xd7d: 0x0733, 0xd7e: 0x122b, 0xd7f: 0x081b,
 	// Block 0x36, offset 0xd80
-	0xd80: 0x0beb, 0xd81: 0x0c97, 0xd82: 0x0cc7, 0xd83: 0x0ce7, 0xd84: 0x0d57, 0xd85: 0x0e1b,
-	0xd86: 0x0e37, 0xd87: 0x0e67, 0xd88: 0x0ebb, 0xd89: 0x0edb, 0xd8a: 0x0f4f, 0xd8b: 0x102f,
-	0xd8c: 0x104b, 0xd8d: 0x1053, 0xd8e: 0x104f, 0xd8f: 0x1057, 0xd90: 0x105b, 0xd91: 0x105f,
-	0xd92: 0x1073, 0xd93: 0x1077, 0xd94: 0x109b, 0xd95: 0x10af, 0xd96: 0x10cb, 0xd97: 0x112f,
-	0xd98: 0x1137, 0xd99: 0x113f, 0xd9a: 0x1153, 0xd9b: 0x117b, 0xd9c: 0x11cb, 0xd9d: 0x11ff,
-	0xd9e: 0x11ff, 0xd9f: 0x1267, 0xda0: 0x130f, 0xda1: 0x1327, 0xda2: 0x135b, 0xda3: 0x135f,
-	0xda4: 0x13a3, 0xda5: 0x13a7, 0xda6: 0x13ff, 0xda7: 0x1407, 0xda8: 0x14db, 0xda9: 0x151f,
-	0xdaa: 0x1537, 0xdab: 0x0b9b, 0xdac: 0x171e, 0xdad: 0x11e3,
-	0xdb0: 0x06df, 0xdb1: 0x07e3, 0xdb2: 0x07a3, 0xdb3: 0x074b, 0xdb4: 0x078b, 0xdb5: 0x07b7,
-	0xdb6: 0x0847, 0xdb7: 0x0863, 0xdb8: 0x094b, 0xdb9: 0x0937, 0xdba: 0x0947, 0xdbb: 0x0963,
-	0xdbc: 0x09af, 0xdbd: 0x09bf, 0xdbe: 0x0a03, 0xdbf: 0x0a0f,
+	0xd80: 0x080b, 0xd81: 0x0b0b, 0xd82: 0x0c2b, 0xd83: 0x10f3, 0xd84: 0x0a53, 0xd85: 0x0e03,
+	0xd86: 0x0cef, 0xd87: 0x13e7, 0xd88: 0x12e7, 0xd89: 0x14ab, 0xd8a: 0x1323, 0xd8b: 0x0b27,
+	0xd8c: 0x0787, 0xd8d: 0x095b, 0xd90: 0x09af,
+	0xd92: 0x0cdf, 0xd95: 0x07f7, 0xd96: 0x0f1f, 0xd97: 0x0fe3,
+	0xd98: 0x1047, 0xd99: 0x1063, 0xd9a: 0x1067, 0xd9b: 0x107b, 0xd9c: 0x14fb, 0xd9d: 0x10eb,
+	0xd9e: 0x116f, 0xda0: 0x128f, 0xda2: 0x1353,
+	0xda5: 0x1407, 0xda6: 0x1433,
+	0xdaa: 0x154f, 0xdab: 0x1553, 0xdac: 0x1557, 0xdad: 0x15bb, 0xdae: 0x142b, 0xdaf: 0x14c7,
+	0xdb0: 0x0757, 0xdb1: 0x077b, 0xdb2: 0x078f, 0xdb3: 0x084b, 0xdb4: 0x0857, 0xdb5: 0x0897,
+	0xdb6: 0x094b, 0xdb7: 0x0967, 0xdb8: 0x096f, 0xdb9: 0x09ab, 0xdba: 0x09b7, 0xdbb: 0x0a93,
+	0xdbc: 0x0a9b, 0xdbd: 0x0ba3, 0xdbe: 0x0bcb, 0xdbf: 0x0bd3,
 	// Block 0x37, offset 0xdc0
-	0xdc0: 0x0a2b, 0xdc1: 0x0a3b, 0xdc2: 0x0b23, 0xdc3: 0x0b2b, 0xdc4: 0x0b5b, 0xdc5: 0x0b7b,
-	0xdc6: 0x0bab, 0xdc7: 0x0bc3, 0xdc8: 0x0bb3, 0xdc9: 0x0bd3, 0xdca: 0x0bc7, 0xdcb: 0x0beb,
-	0xdcc: 0x0c07, 0xdcd: 0x0c5f, 0xdce: 0x0c6b, 0xdcf: 0x0c73, 0xdd0: 0x0c9b, 0xdd1: 0x0cdf,
-	0xdd2: 0x0d0f, 0xdd3: 0x0d13, 0xdd4: 0x0d27, 0xdd5: 0x0da7, 0xdd6: 0x0db7, 0xdd7: 0x0e0f,
-	0xdd8: 0x0e5b, 0xdd9: 0x0e53, 0xdda: 0x0e67, 0xddb: 0x0e83, 0xddc: 0x0ebb, 0xddd: 0x1013,
-	0xdde: 0x0edf, 0xddf: 0x0f13, 0xde0: 0x0f1f, 0xde1: 0x0f5f, 0xde2: 0x0f7b, 0xde3: 0x0f9f,
-	0xde4: 0x0fc3, 0xde5: 0x0fc7, 0xde6: 0x0fe3, 0xde7: 0x0fe7, 0xde8: 0x0ff7, 0xde9: 0x100b,
-	0xdea: 0x1007, 0xdeb: 0x1037, 0xdec: 0x10b3, 0xded: 0x10cb, 0xdee: 0x10e3, 0xdef: 0x111b,
-	0xdf0: 0x112f, 0xdf1: 0x114b, 0xdf2: 0x117b, 0xdf3: 0x122f, 0xdf4: 0x1257, 0xdf5: 0x12cb,
-	0xdf6: 0x1313, 0xdf7: 0x131f, 0xdf8: 0x1327, 0xdf9: 0x133f, 0xdfa: 0x1353, 0xdfb: 0x1343,
-	0xdfc: 0x135b, 0xdfd: 0x1357, 0xdfe: 0x134f, 0xdff: 0x135f,
+	0xdc0: 0x0beb, 0xdc1: 0x0c97, 0xdc2: 0x0cc7, 0xdc3: 0x0ce7, 0xdc4: 0x0d57, 0xdc5: 0x0e1b,
+	0xdc6: 0x0e37, 0xdc7: 0x0e67, 0xdc8: 0x0ebb, 0xdc9: 0x0edb, 0xdca: 0x0f4f, 0xdcb: 0x102f,
+	0xdcc: 0x104b, 0xdcd: 0x1053, 0xdce: 0x104f, 0xdcf: 0x1057, 0xdd0: 0x105b, 0xdd1: 0x105f,
+	0xdd2: 0x1073, 0xdd3: 0x1077, 0xdd4: 0x109b, 0xdd5: 0x10af, 0xdd6: 0x10cb, 0xdd7: 0x112f,
+	0xdd8: 0x1137, 0xdd9: 0x113f, 0xdda: 0x1153, 0xddb: 0x117b, 0xddc: 0x11cb, 0xddd: 0x11ff,
+	0xdde: 0x11ff, 0xddf: 0x1267, 0xde0: 0x130f, 0xde1: 0x1327, 0xde2: 0x135b, 0xde3: 0x135f,
+	0xde4: 0x13a3, 0xde5: 0x13a7, 0xde6: 0x13ff, 0xde7: 0x1407, 0xde8: 0x14db, 0xde9: 0x151f,
+	0xdea: 0x1537, 0xdeb: 0x0b9b, 0xdec: 0x171e, 0xded: 0x11e3,
+	0xdf0: 0x06df, 0xdf1: 0x07e3, 0xdf2: 0x07a3, 0xdf3: 0x074b, 0xdf4: 0x078b, 0xdf5: 0x07b7,
+	0xdf6: 0x0847, 0xdf7: 0x0863, 0xdf8: 0x094b, 0xdf9: 0x0937, 0xdfa: 0x0947, 0xdfb: 0x0963,
+	0xdfc: 0x09af, 0xdfd: 0x09bf, 0xdfe: 0x0a03, 0xdff: 0x0a0f,
 	// Block 0x38, offset 0xe00
-	0xe00: 0x136b, 0xe01: 0x13a7, 0xe02: 0x13e3, 0xe03: 0x1413, 0xe04: 0x144b, 0xe05: 0x146b,
-	0xe06: 0x14b7, 0xe07: 0x14db, 0xe08: 0x14fb, 0xe09: 0x150f, 0xe0a: 0x151f, 0xe0b: 0x152b,
-	0xe0c: 0x1537, 0xe0d: 0x158b, 0xe0e: 0x162b, 0xe0f: 0x16b5, 0xe10: 0x16b0, 0xe11: 0x16e2,
-	0xe12: 0x0607, 0xe13: 0x062f, 0xe14: 0x0633, 0xe15: 0x1764, 0xe16: 0x1791, 0xe17: 0x1809,
-	0xe18: 0x1617, 0xe19: 0x1627,
+	0xe00: 0x0a2b, 0xe01: 0x0a3b, 0xe02: 0x0b23, 0xe03: 0x0b2b, 0xe04: 0x0b5b, 0xe05: 0x0b7b,
+	0xe06: 0x0bab, 0xe07: 0x0bc3, 0xe08: 0x0bb3, 0xe09: 0x0bd3, 0xe0a: 0x0bc7, 0xe0b: 0x0beb,
+	0xe0c: 0x0c07, 0xe0d: 0x0c5f, 0xe0e: 0x0c6b, 0xe0f: 0x0c73, 0xe10: 0x0c9b, 0xe11: 0x0cdf,
+	0xe12: 0x0d0f, 0xe13: 0x0d13, 0xe14: 0x0d27, 0xe15: 0x0da7, 0xe16: 0x0db7, 0xe17: 0x0e0f,
+	0xe18: 0x0e5b, 0xe19: 0x0e53, 0xe1a: 0x0e67, 0xe1b: 0x0e83, 0xe1c: 0x0ebb, 0xe1d: 0x1013,
+	0xe1e: 0x0edf, 0xe1f: 0x0f13, 0xe20: 0x0f1f, 0xe21: 0x0f5f, 0xe22: 0x0f7b, 0xe23: 0x0f9f,
+	0xe24: 0x0fc3, 0xe25: 0x0fc7, 0xe26: 0x0fe3, 0xe27: 0x0fe7, 0xe28: 0x0ff7, 0xe29: 0x100b,
+	0xe2a: 0x1007, 0xe2b: 0x1037, 0xe2c: 0x10b3, 0xe2d: 0x10cb, 0xe2e: 0x10e3, 0xe2f: 0x111b,
+	0xe30: 0x112f, 0xe31: 0x114b, 0xe32: 0x117b, 0xe33: 0x122f, 0xe34: 0x1257, 0xe35: 0x12cb,
+	0xe36: 0x1313, 0xe37: 0x131f, 0xe38: 0x1327, 0xe39: 0x133f, 0xe3a: 0x1353, 0xe3b: 0x1343,
+	0xe3c: 0x135b, 0xe3d: 0x1357, 0xe3e: 0x134f, 0xe3f: 0x135f,
 	// Block 0x39, offset 0xe40
-	0xe40: 0x19d5, 0xe41: 0x19d8, 0xe42: 0x19db, 0xe43: 0x1c08, 0xe44: 0x1c0c, 0xe45: 0x1a5f,
-	0xe46: 0x1a5f,
-	0xe53: 0x1d75, 0xe54: 0x1d66, 0xe55: 0x1d6b, 0xe56: 0x1d7a, 0xe57: 0x1d70,
-	0xe5d: 0x4390,
-	0xe5e: 0x8115, 0xe5f: 0x4402, 0xe60: 0x022d, 0xe61: 0x0215, 0xe62: 0x021e, 0xe63: 0x0221,
-	0xe64: 0x0224, 0xe65: 0x0227, 0xe66: 0x022a, 0xe67: 0x0230, 0xe68: 0x0233, 0xe69: 0x0017,
-	0xe6a: 0x43f0, 0xe6b: 0x43f6, 0xe6c: 0x44f4, 0xe6d: 0x44fc, 0xe6e: 0x4348, 0xe6f: 0x434e,
-	0xe70: 0x4354, 0xe71: 0x435a, 0xe72: 0x4366, 0xe73: 0x436c, 0xe74: 0x4372, 0xe75: 0x437e,
-	0xe76: 0x4384, 0xe78: 0x438a, 0xe79: 0x4396, 0xe7a: 0x439c, 0xe7b: 0x43a2,
-	0xe7c: 0x43ae, 0xe7e: 0x43b4,
+	0xe40: 0x136b, 0xe41: 0x13a7, 0xe42: 0x13e3, 0xe43: 0x1413, 0xe44: 0x144b, 0xe45: 0x146b,
+	0xe46: 0x14b7, 0xe47: 0x14db, 0xe48: 0x14fb, 0xe49: 0x150f, 0xe4a: 0x151f, 0xe4b: 0x152b,
+	0xe4c: 0x1537, 0xe4d: 0x158b, 0xe4e: 0x162b, 0xe4f: 0x16b5, 0xe50: 0x16b0, 0xe51: 0x16e2,
+	0xe52: 0x0607, 0xe53: 0x062f, 0xe54: 0x0633, 0xe55: 0x1764, 0xe56: 0x1791, 0xe57: 0x1809,
+	0xe58: 0x1617, 0xe59: 0x1627,
 	// Block 0x3a, offset 0xe80
-	0xe80: 0x43ba, 0xe81: 0x43c0, 0xe83: 0x43c6, 0xe84: 0x43cc,
-	0xe86: 0x43d8, 0xe87: 0x43de, 0xe88: 0x43e4, 0xe89: 0x43ea, 0xe8a: 0x43fc, 0xe8b: 0x4378,
-	0xe8c: 0x4360, 0xe8d: 0x43a8, 0xe8e: 0x43d2, 0xe8f: 0x1d7f, 0xe90: 0x0299, 0xe91: 0x0299,
-	0xe92: 0x02a2, 0xe93: 0x02a2, 0xe94: 0x02a2, 0xe95: 0x02a2, 0xe96: 0x02a5, 0xe97: 0x02a5,
-	0xe98: 0x02a5, 0xe99: 0x02a5, 0xe9a: 0x02ab, 0xe9b: 0x02ab, 0xe9c: 0x02ab, 0xe9d: 0x02ab,
-	0xe9e: 0x029f, 0xe9f: 0x029f, 0xea0: 0x029f, 0xea1: 0x029f, 0xea2: 0x02a8, 0xea3: 0x02a8,
-	0xea4: 0x02a8, 0xea5: 0x02a8, 0xea6: 0x029c, 0xea7: 0x029c, 0xea8: 0x029c, 0xea9: 0x029c,
-	0xeaa: 0x02cf, 0xeab: 0x02cf, 0xeac: 0x02cf, 0xead: 0x02cf, 0xeae: 0x02d2, 0xeaf: 0x02d2,
-	0xeb0: 0x02d2, 0xeb1: 0x02d2, 0xeb2: 0x02b1, 0xeb3: 0x02b1, 0xeb4: 0x02b1, 0xeb5: 0x02b1,
-	0xeb6: 0x02ae, 0xeb7: 0x02ae, 0xeb8: 0x02ae, 0xeb9: 0x02ae, 0xeba: 0x02b4, 0xebb: 0x02b4,
-	0xebc: 0x02b4, 0xebd: 0x02b4, 0xebe: 0x02b7, 0xebf: 0x02b7,
+	0xe80: 0x19d5, 0xe81: 0x19d8, 0xe82: 0x19db, 0xe83: 0x1c08, 0xe84: 0x1c0c, 0xe85: 0x1a5f,
+	0xe86: 0x1a5f,
+	0xe93: 0x1d75, 0xe94: 0x1d66, 0xe95: 0x1d6b, 0xe96: 0x1d7a, 0xe97: 0x1d70,
+	0xe9d: 0x4390,
+	0xe9e: 0x8115, 0xe9f: 0x4402, 0xea0: 0x022d, 0xea1: 0x0215, 0xea2: 0x021e, 0xea3: 0x0221,
+	0xea4: 0x0224, 0xea5: 0x0227, 0xea6: 0x022a, 0xea7: 0x0230, 0xea8: 0x0233, 0xea9: 0x0017,
+	0xeaa: 0x43f0, 0xeab: 0x43f6, 0xeac: 0x44f4, 0xead: 0x44fc, 0xeae: 0x4348, 0xeaf: 0x434e,
+	0xeb0: 0x4354, 0xeb1: 0x435a, 0xeb2: 0x4366, 0xeb3: 0x436c, 0xeb4: 0x4372, 0xeb5: 0x437e,
+	0xeb6: 0x4384, 0xeb8: 0x438a, 0xeb9: 0x4396, 0xeba: 0x439c, 0xebb: 0x43a2,
+	0xebc: 0x43ae, 0xebe: 0x43b4,
 	// Block 0x3b, offset 0xec0
-	0xec0: 0x02b7, 0xec1: 0x02b7, 0xec2: 0x02c0, 0xec3: 0x02c0, 0xec4: 0x02bd, 0xec5: 0x02bd,
-	0xec6: 0x02c3, 0xec7: 0x02c3, 0xec8: 0x02ba, 0xec9: 0x02ba, 0xeca: 0x02c9, 0xecb: 0x02c9,
-	0xecc: 0x02c6, 0xecd: 0x02c6, 0xece: 0x02d5, 0xecf: 0x02d5, 0xed0: 0x02d5, 0xed1: 0x02d5,
-	0xed2: 0x02db, 0xed3: 0x02db, 0xed4: 0x02db, 0xed5: 0x02db, 0xed6: 0x02e1, 0xed7: 0x02e1,
-	0xed8: 0x02e1, 0xed9: 0x02e1, 0xeda: 0x02de, 0xedb: 0x02de, 0xedc: 0x02de, 0xedd: 0x02de,
-	0xede: 0x02e4, 0xedf: 0x02e4, 0xee0: 0x02e7, 0xee1: 0x02e7, 0xee2: 0x02e7, 0xee3: 0x02e7,
-	0xee4: 0x446e, 0xee5: 0x446e, 0xee6: 0x02ed, 0xee7: 0x02ed, 0xee8: 0x02ed, 0xee9: 0x02ed,
-	0xeea: 0x02ea, 0xeeb: 0x02ea, 0xeec: 0x02ea, 0xeed: 0x02ea, 0xeee: 0x0308, 0xeef: 0x0308,
-	0xef0: 0x4468, 0xef1: 0x4468,
+	0xec0: 0x43ba, 0xec1: 0x43c0, 0xec3: 0x43c6, 0xec4: 0x43cc,
+	0xec6: 0x43d8, 0xec7: 0x43de, 0xec8: 0x43e4, 0xec9: 0x43ea, 0xeca: 0x43fc, 0xecb: 0x4378,
+	0xecc: 0x4360, 0xecd: 0x43a8, 0xece: 0x43d2, 0xecf: 0x1d7f, 0xed0: 0x0299, 0xed1: 0x0299,
+	0xed2: 0x02a2, 0xed3: 0x02a2, 0xed4: 0x02a2, 0xed5: 0x02a2, 0xed6: 0x02a5, 0xed7: 0x02a5,
+	0xed8: 0x02a5, 0xed9: 0x02a5, 0xeda: 0x02ab, 0xedb: 0x02ab, 0xedc: 0x02ab, 0xedd: 0x02ab,
+	0xede: 0x029f, 0xedf: 0x029f, 0xee0: 0x029f, 0xee1: 0x029f, 0xee2: 0x02a8, 0xee3: 0x02a8,
+	0xee4: 0x02a8, 0xee5: 0x02a8, 0xee6: 0x029c, 0xee7: 0x029c, 0xee8: 0x029c, 0xee9: 0x029c,
+	0xeea: 0x02cf, 0xeeb: 0x02cf, 0xeec: 0x02cf, 0xeed: 0x02cf, 0xeee: 0x02d2, 0xeef: 0x02d2,
+	0xef0: 0x02d2, 0xef1: 0x02d2, 0xef2: 0x02b1, 0xef3: 0x02b1, 0xef4: 0x02b1, 0xef5: 0x02b1,
+	0xef6: 0x02ae, 0xef7: 0x02ae, 0xef8: 0x02ae, 0xef9: 0x02ae, 0xefa: 0x02b4, 0xefb: 0x02b4,
+	0xefc: 0x02b4, 0xefd: 0x02b4, 0xefe: 0x02b7, 0xeff: 0x02b7,
 	// Block 0x3c, offset 0xf00
-	0xf13: 0x02d8, 0xf14: 0x02d8, 0xf15: 0x02d8, 0xf16: 0x02d8, 0xf17: 0x02f6,
-	0xf18: 0x02f6, 0xf19: 0x02f3, 0xf1a: 0x02f3, 0xf1b: 0x02f9, 0xf1c: 0x02f9, 0xf1d: 0x204f,
-	0xf1e: 0x02ff, 0xf1f: 0x02ff, 0xf20: 0x02f0, 0xf21: 0x02f0, 0xf22: 0x02fc, 0xf23: 0x02fc,
-	0xf24: 0x0305, 0xf25: 0x0305, 0xf26: 0x0305, 0xf27: 0x0305, 0xf28: 0x028d, 0xf29: 0x028d,
-	0xf2a: 0x25aa, 0xf2b: 0x25aa, 0xf2c: 0x261a, 0xf2d: 0x261a, 0xf2e: 0x25e9, 0xf2f: 0x25e9,
-	0xf30: 0x2605, 0xf31: 0x2605, 0xf32: 0x25fe, 0xf33: 0x25fe, 0xf34: 0x260c, 0xf35: 0x260c,
-	0xf36: 0x2613, 0xf37: 0x2613, 0xf38: 0x2613, 0xf39: 0x25f0, 0xf3a: 0x25f0, 0xf3b: 0x25f0,
-	0xf3c: 0x0302, 0xf3d: 0x0302, 0xf3e: 0x0302, 0xf3f: 0x0302,
+	0xf00: 0x02b7, 0xf01: 0x02b7, 0xf02: 0x02c0, 0xf03: 0x02c0, 0xf04: 0x02bd, 0xf05: 0x02bd,
+	0xf06: 0x02c3, 0xf07: 0x02c3, 0xf08: 0x02ba, 0xf09: 0x02ba, 0xf0a: 0x02c9, 0xf0b: 0x02c9,
+	0xf0c: 0x02c6, 0xf0d: 0x02c6, 0xf0e: 0x02d5, 0xf0f: 0x02d5, 0xf10: 0x02d5, 0xf11: 0x02d5,
+	0xf12: 0x02db, 0xf13: 0x02db, 0xf14: 0x02db, 0xf15: 0x02db, 0xf16: 0x02e1, 0xf17: 0x02e1,
+	0xf18: 0x02e1, 0xf19: 0x02e1, 0xf1a: 0x02de, 0xf1b: 0x02de, 0xf1c: 0x02de, 0xf1d: 0x02de,
+	0xf1e: 0x02e4, 0xf1f: 0x02e4, 0xf20: 0x02e7, 0xf21: 0x02e7, 0xf22: 0x02e7, 0xf23: 0x02e7,
+	0xf24: 0x446e, 0xf25: 0x446e, 0xf26: 0x02ed, 0xf27: 0x02ed, 0xf28: 0x02ed, 0xf29: 0x02ed,
+	0xf2a: 0x02ea, 0xf2b: 0x02ea, 0xf2c: 0x02ea, 0xf2d: 0x02ea, 0xf2e: 0x0308, 0xf2f: 0x0308,
+	0xf30: 0x4468, 0xf31: 0x4468,
 	// Block 0x3d, offset 0xf40
-	0xf40: 0x25b1, 0xf41: 0x25b8, 0xf42: 0x25d4, 0xf43: 0x25f0, 0xf44: 0x25f7, 0xf45: 0x1d89,
-	0xf46: 0x1d8e, 0xf47: 0x1d93, 0xf48: 0x1da2, 0xf49: 0x1db1, 0xf4a: 0x1db6, 0xf4b: 0x1dbb,
-	0xf4c: 0x1dc0, 0xf4d: 0x1dc5, 0xf4e: 0x1dd4, 0xf4f: 0x1de3, 0xf50: 0x1de8, 0xf51: 0x1ded,
-	0xf52: 0x1dfc, 0xf53: 0x1e0b, 0xf54: 0x1e10, 0xf55: 0x1e15, 0xf56: 0x1e1a, 0xf57: 0x1e29,
-	0xf58: 0x1e2e, 0xf59: 0x1e3d, 0xf5a: 0x1e42, 0xf5b: 0x1e47, 0xf5c: 0x1e56, 0xf5d: 0x1e5b,
-	0xf5e: 0x1e60, 0xf5f: 0x1e6a, 0xf60: 0x1ea6, 0xf61: 0x1eb5, 0xf62: 0x1ec4, 0xf63: 0x1ec9,
-	0xf64: 0x1ece, 0xf65: 0x1ed8, 0xf66: 0x1ee7, 0xf67: 0x1eec, 0xf68: 0x1efb, 0xf69: 0x1f00,
-	0xf6a: 0x1f05, 0xf6b: 0x1f14, 0xf6c: 0x1f19, 0xf6d: 0x1f28, 0xf6e: 0x1f2d, 0xf6f: 0x1f32,
-	0xf70: 0x1f37, 0xf71: 0x1f3c, 0xf72: 0x1f41, 0xf73: 0x1f46, 0xf74: 0x1f4b, 0xf75: 0x1f50,
-	0xf76: 0x1f55, 0xf77: 0x1f5a, 0xf78: 0x1f5f, 0xf79: 0x1f64, 0xf7a: 0x1f69, 0xf7b: 0x1f6e,
-	0xf7c: 0x1f73, 0xf7d: 0x1f78, 0xf7e: 0x1f7d, 0xf7f: 0x1f87,
+	0xf53: 0x02d8, 0xf54: 0x02d8, 0xf55: 0x02d8, 0xf56: 0x02d8, 0xf57: 0x02f6,
+	0xf58: 0x02f6, 0xf59: 0x02f3, 0xf5a: 0x02f3, 0xf5b: 0x02f9, 0xf5c: 0x02f9, 0xf5d: 0x204f,
+	0xf5e: 0x02ff, 0xf5f: 0x02ff, 0xf60: 0x02f0, 0xf61: 0x02f0, 0xf62: 0x02fc, 0xf63: 0x02fc,
+	0xf64: 0x0305, 0xf65: 0x0305, 0xf66: 0x0305, 0xf67: 0x0305, 0xf68: 0x028d, 0xf69: 0x028d,
+	0xf6a: 0x25aa, 0xf6b: 0x25aa, 0xf6c: 0x261a, 0xf6d: 0x261a, 0xf6e: 0x25e9, 0xf6f: 0x25e9,
+	0xf70: 0x2605, 0xf71: 0x2605, 0xf72: 0x25fe, 0xf73: 0x25fe, 0xf74: 0x260c, 0xf75: 0x260c,
+	0xf76: 0x2613, 0xf77: 0x2613, 0xf78: 0x2613, 0xf79: 0x25f0, 0xf7a: 0x25f0, 0xf7b: 0x25f0,
+	0xf7c: 0x0302, 0xf7d: 0x0302, 0xf7e: 0x0302, 0xf7f: 0x0302,
 	// Block 0x3e, offset 0xf80
-	0xf80: 0x1f8c, 0xf81: 0x1f91, 0xf82: 0x1f96, 0xf83: 0x1fa0, 0xf84: 0x1fa5, 0xf85: 0x1faf,
-	0xf86: 0x1fb4, 0xf87: 0x1fb9, 0xf88: 0x1fbe, 0xf89: 0x1fc3, 0xf8a: 0x1fc8, 0xf8b: 0x1fcd,
-	0xf8c: 0x1fd2, 0xf8d: 0x1fd7, 0xf8e: 0x1fe6, 0xf8f: 0x1ff5, 0xf90: 0x1ffa, 0xf91: 0x1fff,
-	0xf92: 0x2004, 0xf93: 0x2009, 0xf94: 0x200e, 0xf95: 0x2018, 0xf96: 0x201d, 0xf97: 0x2022,
-	0xf98: 0x2031, 0xf99: 0x2040, 0xf9a: 0x2045, 0xf9b: 0x4420, 0xf9c: 0x4426, 0xf9d: 0x445c,
-	0xf9e: 0x44b3, 0xf9f: 0x44ba, 0xfa0: 0x44c1, 0xfa1: 0x44c8, 0xfa2: 0x44cf, 0xfa3: 0x44d6,
-	0xfa4: 0x25c6, 0xfa5: 0x25cd, 0xfa6: 0x25d4, 0xfa7: 0x25db, 0xfa8: 0x25f0, 0xfa9: 0x25f7,
-	0xfaa: 0x1d98, 0xfab: 0x1d9d, 0xfac: 0x1da2, 0xfad: 0x1da7, 0xfae: 0x1db1, 0xfaf: 0x1db6,
-	0xfb0: 0x1dca, 0xfb1: 0x1dcf, 0xfb2: 0x1dd4, 0xfb3: 0x1dd9, 0xfb4: 0x1de3, 0xfb5: 0x1de8,
-	0xfb6: 0x1df2, 0xfb7: 0x1df7, 0xfb8: 0x1dfc, 0xfb9: 0x1e01, 0xfba: 0x1e0b, 0xfbb: 0x1e10,
-	0xfbc: 0x1f3c, 0xfbd: 0x1f41, 0xfbe: 0x1f50, 0xfbf: 0x1f55,
+	0xf80: 0x25b1, 0xf81: 0x25b8, 0xf82: 0x25d4, 0xf83: 0x25f0, 0xf84: 0x25f7, 0xf85: 0x1d89,
+	0xf86: 0x1d8e, 0xf87: 0x1d93, 0xf88: 0x1da2, 0xf89: 0x1db1, 0xf8a: 0x1db6, 0xf8b: 0x1dbb,
+	0xf8c: 0x1dc0, 0xf8d: 0x1dc5, 0xf8e: 0x1dd4, 0xf8f: 0x1de3, 0xf90: 0x1de8, 0xf91: 0x1ded,
+	0xf92: 0x1dfc, 0xf93: 0x1e0b, 0xf94: 0x1e10, 0xf95: 0x1e15, 0xf96: 0x1e1a, 0xf97: 0x1e29,
+	0xf98: 0x1e2e, 0xf99: 0x1e3d, 0xf9a: 0x1e42, 0xf9b: 0x1e47, 0xf9c: 0x1e56, 0xf9d: 0x1e5b,
+	0xf9e: 0x1e60, 0xf9f: 0x1e6a, 0xfa0: 0x1ea6, 0xfa1: 0x1eb5, 0xfa2: 0x1ec4, 0xfa3: 0x1ec9,
+	0xfa4: 0x1ece, 0xfa5: 0x1ed8, 0xfa6: 0x1ee7, 0xfa7: 0x1eec, 0xfa8: 0x1efb, 0xfa9: 0x1f00,
+	0xfaa: 0x1f05, 0xfab: 0x1f14, 0xfac: 0x1f19, 0xfad: 0x1f28, 0xfae: 0x1f2d, 0xfaf: 0x1f32,
+	0xfb0: 0x1f37, 0xfb1: 0x1f3c, 0xfb2: 0x1f41, 0xfb3: 0x1f46, 0xfb4: 0x1f4b, 0xfb5: 0x1f50,
+	0xfb6: 0x1f55, 0xfb7: 0x1f5a, 0xfb8: 0x1f5f, 0xfb9: 0x1f64, 0xfba: 0x1f69, 0xfbb: 0x1f6e,
+	0xfbc: 0x1f73, 0xfbd: 0x1f78, 0xfbe: 0x1f7d, 0xfbf: 0x1f87,
 	// Block 0x3f, offset 0xfc0
-	0xfc0: 0x1f5a, 0xfc1: 0x1f6e, 0xfc2: 0x1f73, 0xfc3: 0x1f78, 0xfc4: 0x1f7d, 0xfc5: 0x1f96,
-	0xfc6: 0x1fa0, 0xfc7: 0x1fa5, 0xfc8: 0x1faa, 0xfc9: 0x1fbe, 0xfca: 0x1fdc, 0xfcb: 0x1fe1,
-	0xfcc: 0x1fe6, 0xfcd: 0x1feb, 0xfce: 0x1ff5, 0xfcf: 0x1ffa, 0xfd0: 0x445c, 0xfd1: 0x2027,
-	0xfd2: 0x202c, 0xfd3: 0x2031, 0xfd4: 0x2036, 0xfd5: 0x2040, 0xfd6: 0x2045, 0xfd7: 0x25b1,
-	0xfd8: 0x25b8, 0xfd9: 0x25bf, 0xfda: 0x25d4, 0xfdb: 0x25e2, 0xfdc: 0x1d89, 0xfdd: 0x1d8e,
-	0xfde: 0x1d93, 0xfdf: 0x1da2, 0xfe0: 0x1dac, 0xfe1: 0x1dbb, 0xfe2: 0x1dc0, 0xfe3: 0x1dc5,
-	0xfe4: 0x1dd4, 0xfe5: 0x1dde, 0xfe6: 0x1dfc, 0xfe7: 0x1e15, 0xfe8: 0x1e1a, 0xfe9: 0x1e29,
-	0xfea: 0x1e2e, 0xfeb: 0x1e3d, 0xfec: 0x1e47, 0xfed: 0x1e56, 0xfee: 0x1e5b, 0xfef: 0x1e60,
-	0xff0: 0x1e6a, 0xff1: 0x1ea6, 0xff2: 0x1eab, 0xff3: 0x1eb5, 0xff4: 0x1ec4, 0xff5: 0x1ec9,
-	0xff6: 0x1ece, 0xff7: 0x1ed8, 0xff8: 0x1ee7, 0xff9: 0x1efb, 0xffa: 0x1f00, 0xffb: 0x1f05,
-	0xffc: 0x1f14, 0xffd: 0x1f19, 0xffe: 0x1f28, 0xfff: 0x1f2d,
+	0xfc0: 0x1f8c, 0xfc1: 0x1f91, 0xfc2: 0x1f96, 0xfc3: 0x1fa0, 0xfc4: 0x1fa5, 0xfc5: 0x1faf,
+	0xfc6: 0x1fb4, 0xfc7: 0x1fb9, 0xfc8: 0x1fbe, 0xfc9: 0x1fc3, 0xfca: 0x1fc8, 0xfcb: 0x1fcd,
+	0xfcc: 0x1fd2, 0xfcd: 0x1fd7, 0xfce: 0x1fe6, 0xfcf: 0x1ff5, 0xfd0: 0x1ffa, 0xfd1: 0x1fff,
+	0xfd2: 0x2004, 0xfd3: 0x2009, 0xfd4: 0x200e, 0xfd5: 0x2018, 0xfd6: 0x201d, 0xfd7: 0x2022,
+	0xfd8: 0x2031, 0xfd9: 0x2040, 0xfda: 0x2045, 0xfdb: 0x4420, 0xfdc: 0x4426, 0xfdd: 0x445c,
+	0xfde: 0x44b3, 0xfdf: 0x44ba, 0xfe0: 0x44c1, 0xfe1: 0x44c8, 0xfe2: 0x44cf, 0xfe3: 0x44d6,
+	0xfe4: 0x25c6, 0xfe5: 0x25cd, 0xfe6: 0x25d4, 0xfe7: 0x25db, 0xfe8: 0x25f0, 0xfe9: 0x25f7,
+	0xfea: 0x1d98, 0xfeb: 0x1d9d, 0xfec: 0x1da2, 0xfed: 0x1da7, 0xfee: 0x1db1, 0xfef: 0x1db6,
+	0xff0: 0x1dca, 0xff1: 0x1dcf, 0xff2: 0x1dd4, 0xff3: 0x1dd9, 0xff4: 0x1de3, 0xff5: 0x1de8,
+	0xff6: 0x1df2, 0xff7: 0x1df7, 0xff8: 0x1dfc, 0xff9: 0x1e01, 0xffa: 0x1e0b, 0xffb: 0x1e10,
+	0xffc: 0x1f3c, 0xffd: 0x1f41, 0xffe: 0x1f50, 0xfff: 0x1f55,
 	// Block 0x40, offset 0x1000
-	0x1000: 0x1f32, 0x1001: 0x1f37, 0x1002: 0x1f46, 0x1003: 0x1f4b, 0x1004: 0x1f5f, 0x1005: 0x1f64,
-	0x1006: 0x1f69, 0x1007: 0x1f6e, 0x1008: 0x1f73, 0x1009: 0x1f87, 0x100a: 0x1f8c, 0x100b: 0x1f91,
-	0x100c: 0x1f96, 0x100d: 0x1f9b, 0x100e: 0x1faf, 0x100f: 0x1fb4, 0x1010: 0x1fb9, 0x1011: 0x1fbe,
-	0x1012: 0x1fcd, 0x1013: 0x1fd2, 0x1014: 0x1fd7, 0x1015: 0x1fe6, 0x1016: 0x1ff0, 0x1017: 0x1fff,
-	0x1018: 0x2004, 0x1019: 0x4450, 0x101a: 0x2018, 0x101b: 0x201d, 0x101c: 0x2022, 0x101d: 0x2031,
-	0x101e: 0x203b, 0x101f: 0x25d4, 0x1020: 0x25e2, 0x1021: 0x1da2, 0x1022: 0x1dac, 0x1023: 0x1dd4,
-	0x1024: 0x1dde, 0x1025: 0x1dfc, 0x1026: 0x1e06, 0x1027: 0x1e6a, 0x1028: 0x1e6f, 0x1029: 0x1e92,
-	0x102a: 0x1e97, 0x102b: 0x1f6e, 0x102c: 0x1f73, 0x102d: 0x1f96, 0x102e: 0x1fe6, 0x102f: 0x1ff0,
-	0x1030: 0x2031, 0x1031: 0x203b, 0x1032: 0x4504, 0x1033: 0x450c, 0x1034: 0x4514, 0x1035: 0x1ef1,
-	0x1036: 0x1ef6, 0x1037: 0x1f0a, 0x1038: 0x1f0f, 0x1039: 0x1f1e, 0x103a: 0x1f23, 0x103b: 0x1e74,
-	0x103c: 0x1e79, 0x103d: 0x1e9c, 0x103e: 0x1ea1, 0x103f: 0x1e33,
+	0x1000: 0x1f5a, 0x1001: 0x1f6e, 0x1002: 0x1f73, 0x1003: 0x1f78, 0x1004: 0x1f7d, 0x1005: 0x1f96,
+	0x1006: 0x1fa0, 0x1007: 0x1fa5, 0x1008: 0x1faa, 0x1009: 0x1fbe, 0x100a: 0x1fdc, 0x100b: 0x1fe1,
+	0x100c: 0x1fe6, 0x100d: 0x1feb, 0x100e: 0x1ff5, 0x100f: 0x1ffa, 0x1010: 0x445c, 0x1011: 0x2027,
+	0x1012: 0x202c, 0x1013: 0x2031, 0x1014: 0x2036, 0x1015: 0x2040, 0x1016: 0x2045, 0x1017: 0x25b1,
+	0x1018: 0x25b8, 0x1019: 0x25bf, 0x101a: 0x25d4, 0x101b: 0x25e2, 0x101c: 0x1d89, 0x101d: 0x1d8e,
+	0x101e: 0x1d93, 0x101f: 0x1da2, 0x1020: 0x1dac, 0x1021: 0x1dbb, 0x1022: 0x1dc0, 0x1023: 0x1dc5,
+	0x1024: 0x1dd4, 0x1025: 0x1dde, 0x1026: 0x1dfc, 0x1027: 0x1e15, 0x1028: 0x1e1a, 0x1029: 0x1e29,
+	0x102a: 0x1e2e, 0x102b: 0x1e3d, 0x102c: 0x1e47, 0x102d: 0x1e56, 0x102e: 0x1e5b, 0x102f: 0x1e60,
+	0x1030: 0x1e6a, 0x1031: 0x1ea6, 0x1032: 0x1eab, 0x1033: 0x1eb5, 0x1034: 0x1ec4, 0x1035: 0x1ec9,
+	0x1036: 0x1ece, 0x1037: 0x1ed8, 0x1038: 0x1ee7, 0x1039: 0x1efb, 0x103a: 0x1f00, 0x103b: 0x1f05,
+	0x103c: 0x1f14, 0x103d: 0x1f19, 0x103e: 0x1f28, 0x103f: 0x1f2d,
 	// Block 0x41, offset 0x1040
-	0x1040: 0x1e38, 0x1041: 0x1e1f, 0x1042: 0x1e24, 0x1043: 0x1e4c, 0x1044: 0x1e51, 0x1045: 0x1eba,
-	0x1046: 0x1ebf, 0x1047: 0x1edd, 0x1048: 0x1ee2, 0x1049: 0x1e7e, 0x104a: 0x1e83, 0x104b: 0x1e88,
-	0x104c: 0x1e92, 0x104d: 0x1e8d, 0x104e: 0x1e65, 0x104f: 0x1eb0, 0x1050: 0x1ed3, 0x1051: 0x1ef1,
-	0x1052: 0x1ef6, 0x1053: 0x1f0a, 0x1054: 0x1f0f, 0x1055: 0x1f1e, 0x1056: 0x1f23, 0x1057: 0x1e74,
-	0x1058: 0x1e79, 0x1059: 0x1e9c, 0x105a: 0x1ea1, 0x105b: 0x1e33, 0x105c: 0x1e38, 0x105d: 0x1e1f,
-	0x105e: 0x1e24, 0x105f: 0x1e4c, 0x1060: 0x1e51, 0x1061: 0x1eba, 0x1062: 0x1ebf, 0x1063: 0x1edd,
-	0x1064: 0x1ee2, 0x1065: 0x1e7e, 0x1066: 0x1e83, 0x1067: 0x1e88, 0x1068: 0x1e92, 0x1069: 0x1e8d,
-	0x106a: 0x1e65, 0x106b: 0x1eb0, 0x106c: 0x1ed3, 0x106d: 0x1e7e, 0x106e: 0x1e83, 0x106f: 0x1e88,
-	0x1070: 0x1e92, 0x1071: 0x1e6f, 0x1072: 0x1e97, 0x1073: 0x1eec, 0x1074: 0x1e56, 0x1075: 0x1e5b,
-	0x1076: 0x1e60, 0x1077: 0x1e7e, 0x1078: 0x1e83, 0x1079: 0x1e88, 0x107a: 0x1eec, 0x107b: 0x1efb,
-	0x107c: 0x4408, 0x107d: 0x4408,
+	0x1040: 0x1f32, 0x1041: 0x1f37, 0x1042: 0x1f46, 0x1043: 0x1f4b, 0x1044: 0x1f5f, 0x1045: 0x1f64,
+	0x1046: 0x1f69, 0x1047: 0x1f6e, 0x1048: 0x1f73, 0x1049: 0x1f87, 0x104a: 0x1f8c, 0x104b: 0x1f91,
+	0x104c: 0x1f96, 0x104d: 0x1f9b, 0x104e: 0x1faf, 0x104f: 0x1fb4, 0x1050: 0x1fb9, 0x1051: 0x1fbe,
+	0x1052: 0x1fcd, 0x1053: 0x1fd2, 0x1054: 0x1fd7, 0x1055: 0x1fe6, 0x1056: 0x1ff0, 0x1057: 0x1fff,
+	0x1058: 0x2004, 0x1059: 0x4450, 0x105a: 0x2018, 0x105b: 0x201d, 0x105c: 0x2022, 0x105d: 0x2031,
+	0x105e: 0x203b, 0x105f: 0x25d4, 0x1060: 0x25e2, 0x1061: 0x1da2, 0x1062: 0x1dac, 0x1063: 0x1dd4,
+	0x1064: 0x1dde, 0x1065: 0x1dfc, 0x1066: 0x1e06, 0x1067: 0x1e6a, 0x1068: 0x1e6f, 0x1069: 0x1e92,
+	0x106a: 0x1e97, 0x106b: 0x1f6e, 0x106c: 0x1f73, 0x106d: 0x1f96, 0x106e: 0x1fe6, 0x106f: 0x1ff0,
+	0x1070: 0x2031, 0x1071: 0x203b, 0x1072: 0x4504, 0x1073: 0x450c, 0x1074: 0x4514, 0x1075: 0x1ef1,
+	0x1076: 0x1ef6, 0x1077: 0x1f0a, 0x1078: 0x1f0f, 0x1079: 0x1f1e, 0x107a: 0x1f23, 0x107b: 0x1e74,
+	0x107c: 0x1e79, 0x107d: 0x1e9c, 0x107e: 0x1ea1, 0x107f: 0x1e33,
 	// Block 0x42, offset 0x1080
-	0x1090: 0x2311, 0x1091: 0x2326,
-	0x1092: 0x2326, 0x1093: 0x232d, 0x1094: 0x2334, 0x1095: 0x2349, 0x1096: 0x2350, 0x1097: 0x2357,
-	0x1098: 0x237a, 0x1099: 0x237a, 0x109a: 0x239d, 0x109b: 0x2396, 0x109c: 0x23b2, 0x109d: 0x23a4,
-	0x109e: 0x23ab, 0x109f: 0x23ce, 0x10a0: 0x23ce, 0x10a1: 0x23c7, 0x10a2: 0x23d5, 0x10a3: 0x23d5,
-	0x10a4: 0x23ff, 0x10a5: 0x23ff, 0x10a6: 0x241b, 0x10a7: 0x23e3, 0x10a8: 0x23e3, 0x10a9: 0x23dc,
-	0x10aa: 0x23f1, 0x10ab: 0x23f1, 0x10ac: 0x23f8, 0x10ad: 0x23f8, 0x10ae: 0x2422, 0x10af: 0x2430,
-	0x10b0: 0x2430, 0x10b1: 0x2437, 0x10b2: 0x2437, 0x10b3: 0x243e, 0x10b4: 0x2445, 0x10b5: 0x244c,
-	0x10b6: 0x2453, 0x10b7: 0x2453, 0x10b8: 0x245a, 0x10b9: 0x2468, 0x10ba: 0x2476, 0x10bb: 0x246f,
-	0x10bc: 0x247d, 0x10bd: 0x247d, 0x10be: 0x2492, 0x10bf: 0x2499,
+	0x1080: 0x1e38, 0x1081: 0x1e1f, 0x1082: 0x1e24, 0x1083: 0x1e4c, 0x1084: 0x1e51, 0x1085: 0x1eba,
+	0x1086: 0x1ebf, 0x1087: 0x1edd, 0x1088: 0x1ee2, 0x1089: 0x1e7e, 0x108a: 0x1e83, 0x108b: 0x1e88,
+	0x108c: 0x1e92, 0x108d: 0x1e8d, 0x108e: 0x1e65, 0x108f: 0x1eb0, 0x1090: 0x1ed3, 0x1091: 0x1ef1,
+	0x1092: 0x1ef6, 0x1093: 0x1f0a, 0x1094: 0x1f0f, 0x1095: 0x1f1e, 0x1096: 0x1f23, 0x1097: 0x1e74,
+	0x1098: 0x1e79, 0x1099: 0x1e9c, 0x109a: 0x1ea1, 0x109b: 0x1e33, 0x109c: 0x1e38, 0x109d: 0x1e1f,
+	0x109e: 0x1e24, 0x109f: 0x1e4c, 0x10a0: 0x1e51, 0x10a1: 0x1eba, 0x10a2: 0x1ebf, 0x10a3: 0x1edd,
+	0x10a4: 0x1ee2, 0x10a5: 0x1e7e, 0x10a6: 0x1e83, 0x10a7: 0x1e88, 0x10a8: 0x1e92, 0x10a9: 0x1e8d,
+	0x10aa: 0x1e65, 0x10ab: 0x1eb0, 0x10ac: 0x1ed3, 0x10ad: 0x1e7e, 0x10ae: 0x1e83, 0x10af: 0x1e88,
+	0x10b0: 0x1e92, 0x10b1: 0x1e6f, 0x10b2: 0x1e97, 0x10b3: 0x1eec, 0x10b4: 0x1e56, 0x10b5: 0x1e5b,
+	0x10b6: 0x1e60, 0x10b7: 0x1e7e, 0x10b8: 0x1e83, 0x10b9: 0x1e88, 0x10ba: 0x1eec, 0x10bb: 0x1efb,
+	0x10bc: 0x4408, 0x10bd: 0x4408,
 	// Block 0x43, offset 0x10c0
-	0x10c0: 0x24ca, 0x10c1: 0x24d8, 0x10c2: 0x24d1, 0x10c3: 0x24b5, 0x10c4: 0x24b5, 0x10c5: 0x24df,
-	0x10c6: 0x24df, 0x10c7: 0x24e6, 0x10c8: 0x24e6, 0x10c9: 0x2510, 0x10ca: 0x2517, 0x10cb: 0x251e,
-	0x10cc: 0x24f4, 0x10cd: 0x2502, 0x10ce: 0x2525, 0x10cf: 0x252c,
-	0x10d2: 0x24fb, 0x10d3: 0x2580, 0x10d4: 0x2587, 0x10d5: 0x255d, 0x10d6: 0x2564, 0x10d7: 0x2548,
-	0x10d8: 0x2548, 0x10d9: 0x254f, 0x10da: 0x2579, 0x10db: 0x2572, 0x10dc: 0x259c, 0x10dd: 0x259c,
-	0x10de: 0x230a, 0x10df: 0x231f, 0x10e0: 0x2318, 0x10e1: 0x2342, 0x10e2: 0x233b, 0x10e3: 0x2365,
-	0x10e4: 0x235e, 0x10e5: 0x2388, 0x10e6: 0x236c, 0x10e7: 0x2381, 0x10e8: 0x23b9, 0x10e9: 0x2406,
-	0x10ea: 0x23ea, 0x10eb: 0x2429, 0x10ec: 0x24c3, 0x10ed: 0x24ed, 0x10ee: 0x2595, 0x10ef: 0x258e,
-	0x10f0: 0x25a3, 0x10f1: 0x253a, 0x10f2: 0x24a0, 0x10f3: 0x256b, 0x10f4: 0x2492, 0x10f5: 0x24ca,
-	0x10f6: 0x2461, 0x10f7: 0x24ae, 0x10f8: 0x2541, 0x10f9: 0x2533, 0x10fa: 0x24bc, 0x10fb: 0x24a7,
-	0x10fc: 0x24bc, 0x10fd: 0x2541, 0x10fe: 0x2373, 0x10ff: 0x238f,
+	0x10d0: 0x2311, 0x10d1: 0x2326,
+	0x10d2: 0x2326, 0x10d3: 0x232d, 0x10d4: 0x2334, 0x10d5: 0x2349, 0x10d6: 0x2350, 0x10d7: 0x2357,
+	0x10d8: 0x237a, 0x10d9: 0x237a, 0x10da: 0x239d, 0x10db: 0x2396, 0x10dc: 0x23b2, 0x10dd: 0x23a4,
+	0x10de: 0x23ab, 0x10df: 0x23ce, 0x10e0: 0x23ce, 0x10e1: 0x23c7, 0x10e2: 0x23d5, 0x10e3: 0x23d5,
+	0x10e4: 0x23ff, 0x10e5: 0x23ff, 0x10e6: 0x241b, 0x10e7: 0x23e3, 0x10e8: 0x23e3, 0x10e9: 0x23dc,
+	0x10ea: 0x23f1, 0x10eb: 0x23f1, 0x10ec: 0x23f8, 0x10ed: 0x23f8, 0x10ee: 0x2422, 0x10ef: 0x2430,
+	0x10f0: 0x2430, 0x10f1: 0x2437, 0x10f2: 0x2437, 0x10f3: 0x243e, 0x10f4: 0x2445, 0x10f5: 0x244c,
+	0x10f6: 0x2453, 0x10f7: 0x2453, 0x10f8: 0x245a, 0x10f9: 0x2468, 0x10fa: 0x2476, 0x10fb: 0x246f,
+	0x10fc: 0x247d, 0x10fd: 0x247d, 0x10fe: 0x2492, 0x10ff: 0x2499,
 	// Block 0x44, offset 0x1100
-	0x1100: 0x2509, 0x1101: 0x2484, 0x1102: 0x2303, 0x1103: 0x24a7, 0x1104: 0x244c, 0x1105: 0x241b,
-	0x1106: 0x23c0, 0x1107: 0x2556,
-	0x1130: 0x2414, 0x1131: 0x248b, 0x1132: 0x27bf, 0x1133: 0x27b6, 0x1134: 0x27ec, 0x1135: 0x27da,
-	0x1136: 0x27c8, 0x1137: 0x27e3, 0x1138: 0x27f5, 0x1139: 0x240d, 0x113a: 0x2c7c, 0x113b: 0x2afc,
-	0x113c: 0x27d1,
+	0x1100: 0x24ca, 0x1101: 0x24d8, 0x1102: 0x24d1, 0x1103: 0x24b5, 0x1104: 0x24b5, 0x1105: 0x24df,
+	0x1106: 0x24df, 0x1107: 0x24e6, 0x1108: 0x24e6, 0x1109: 0x2510, 0x110a: 0x2517, 0x110b: 0x251e,
+	0x110c: 0x24f4, 0x110d: 0x2502, 0x110e: 0x2525, 0x110f: 0x252c,
+	0x1112: 0x24fb, 0x1113: 0x2580, 0x1114: 0x2587, 0x1115: 0x255d, 0x1116: 0x2564, 0x1117: 0x2548,
+	0x1118: 0x2548, 0x1119: 0x254f, 0x111a: 0x2579, 0x111b: 0x2572, 0x111c: 0x259c, 0x111d: 0x259c,
+	0x111e: 0x230a, 0x111f: 0x231f, 0x1120: 0x2318, 0x1121: 0x2342, 0x1122: 0x233b, 0x1123: 0x2365,
+	0x1124: 0x235e, 0x1125: 0x2388, 0x1126: 0x236c, 0x1127: 0x2381, 0x1128: 0x23b9, 0x1129: 0x2406,
+	0x112a: 0x23ea, 0x112b: 0x2429, 0x112c: 0x24c3, 0x112d: 0x24ed, 0x112e: 0x2595, 0x112f: 0x258e,
+	0x1130: 0x25a3, 0x1131: 0x253a, 0x1132: 0x24a0, 0x1133: 0x256b, 0x1134: 0x2492, 0x1135: 0x24ca,
+	0x1136: 0x2461, 0x1137: 0x24ae, 0x1138: 0x2541, 0x1139: 0x2533, 0x113a: 0x24bc, 0x113b: 0x24a7,
+	0x113c: 0x24bc, 0x113d: 0x2541, 0x113e: 0x2373, 0x113f: 0x238f,
 	// Block 0x45, offset 0x1140
-	0x1150: 0x0019, 0x1151: 0x0483,
-	0x1152: 0x0487, 0x1153: 0x0035, 0x1154: 0x0037, 0x1155: 0x0003, 0x1156: 0x003f, 0x1157: 0x04bf,
-	0x1158: 0x04c3, 0x1159: 0x1b5c,
-	0x1160: 0x8132, 0x1161: 0x8132, 0x1162: 0x8132, 0x1163: 0x8132,
-	0x1164: 0x8132, 0x1165: 0x8132, 0x1166: 0x8132, 0x1167: 0x812d, 0x1168: 0x812d, 0x1169: 0x812d,
-	0x116a: 0x812d, 0x116b: 0x812d, 0x116c: 0x812d, 0x116d: 0x812d, 0x116e: 0x8132, 0x116f: 0x8132,
-	0x1170: 0x1873, 0x1171: 0x0443, 0x1172: 0x043f, 0x1173: 0x007f, 0x1174: 0x007f, 0x1175: 0x0011,
-	0x1176: 0x0013, 0x1177: 0x00b7, 0x1178: 0x00bb, 0x1179: 0x04b7, 0x117a: 0x04bb, 0x117b: 0x04ab,
-	0x117c: 0x04af, 0x117d: 0x0493, 0x117e: 0x0497, 0x117f: 0x048b,
+	0x1140: 0x2509, 0x1141: 0x2484, 0x1142: 0x2303, 0x1143: 0x24a7, 0x1144: 0x244c, 0x1145: 0x241b,
+	0x1146: 0x23c0, 0x1147: 0x2556,
+	0x1170: 0x2414, 0x1171: 0x248b, 0x1172: 0x27bf, 0x1173: 0x27b6, 0x1174: 0x27ec, 0x1175: 0x27da,
+	0x1176: 0x27c8, 0x1177: 0x27e3, 0x1178: 0x27f5, 0x1179: 0x240d, 0x117a: 0x2c7c, 0x117b: 0x2afc,
+	0x117c: 0x27d1,
 	// Block 0x46, offset 0x1180
-	0x1180: 0x048f, 0x1181: 0x049b, 0x1182: 0x049f, 0x1183: 0x04a3, 0x1184: 0x04a7,
-	0x1187: 0x0077, 0x1188: 0x007b, 0x1189: 0x4269, 0x118a: 0x4269, 0x118b: 0x4269,
-	0x118c: 0x4269, 0x118d: 0x007f, 0x118e: 0x007f, 0x118f: 0x007f, 0x1190: 0x0019, 0x1191: 0x0483,
-	0x1192: 0x001d, 0x1194: 0x0037, 0x1195: 0x0035, 0x1196: 0x003f, 0x1197: 0x0003,
-	0x1198: 0x0443, 0x1199: 0x0011, 0x119a: 0x0013, 0x119b: 0x00b7, 0x119c: 0x00bb, 0x119d: 0x04b7,
-	0x119e: 0x04bb, 0x119f: 0x0007, 0x11a0: 0x000d, 0x11a1: 0x0015, 0x11a2: 0x0017, 0x11a3: 0x001b,
-	0x11a4: 0x0039, 0x11a5: 0x003d, 0x11a6: 0x003b, 0x11a8: 0x0079, 0x11a9: 0x0009,
-	0x11aa: 0x000b, 0x11ab: 0x0041,
-	0x11b0: 0x42aa, 0x11b1: 0x442c, 0x11b2: 0x42af, 0x11b4: 0x42b4,
-	0x11b6: 0x42b9, 0x11b7: 0x4432, 0x11b8: 0x42be, 0x11b9: 0x4438, 0x11ba: 0x42c3, 0x11bb: 0x443e,
-	0x11bc: 0x42c8, 0x11bd: 0x4444, 0x11be: 0x42cd, 0x11bf: 0x444a,
+	0x1190: 0x0019, 0x1191: 0x0483,
+	0x1192: 0x0487, 0x1193: 0x0035, 0x1194: 0x0037, 0x1195: 0x0003, 0x1196: 0x003f, 0x1197: 0x04bf,
+	0x1198: 0x04c3, 0x1199: 0x1b5c,
+	0x11a0: 0x8132, 0x11a1: 0x8132, 0x11a2: 0x8132, 0x11a3: 0x8132,
+	0x11a4: 0x8132, 0x11a5: 0x8132, 0x11a6: 0x8132, 0x11a7: 0x812d, 0x11a8: 0x812d, 0x11a9: 0x812d,
+	0x11aa: 0x812d, 0x11ab: 0x812d, 0x11ac: 0x812d, 0x11ad: 0x812d, 0x11ae: 0x8132, 0x11af: 0x8132,
+	0x11b0: 0x1873, 0x11b1: 0x0443, 0x11b2: 0x043f, 0x11b3: 0x007f, 0x11b4: 0x007f, 0x11b5: 0x0011,
+	0x11b6: 0x0013, 0x11b7: 0x00b7, 0x11b8: 0x00bb, 0x11b9: 0x04b7, 0x11ba: 0x04bb, 0x11bb: 0x04ab,
+	0x11bc: 0x04af, 0x11bd: 0x0493, 0x11be: 0x0497, 0x11bf: 0x048b,
 	// Block 0x47, offset 0x11c0
-	0x11c0: 0x0236, 0x11c1: 0x440e, 0x11c2: 0x440e, 0x11c3: 0x4414, 0x11c4: 0x4414, 0x11c5: 0x4456,
-	0x11c6: 0x4456, 0x11c7: 0x441a, 0x11c8: 0x441a, 0x11c9: 0x4462, 0x11ca: 0x4462, 0x11cb: 0x4462,
-	0x11cc: 0x4462, 0x11cd: 0x0239, 0x11ce: 0x0239, 0x11cf: 0x023c, 0x11d0: 0x023c, 0x11d1: 0x023c,
-	0x11d2: 0x023c, 0x11d3: 0x023f, 0x11d4: 0x023f, 0x11d5: 0x0242, 0x11d6: 0x0242, 0x11d7: 0x0242,
-	0x11d8: 0x0242, 0x11d9: 0x0245, 0x11da: 0x0245, 0x11db: 0x0245, 0x11dc: 0x0245, 0x11dd: 0x0248,
-	0x11de: 0x0248, 0x11df: 0x0248, 0x11e0: 0x0248, 0x11e1: 0x024b, 0x11e2: 0x024b, 0x11e3: 0x024b,
-	0x11e4: 0x024b, 0x11e5: 0x024e, 0x11e6: 0x024e, 0x11e7: 0x024e, 0x11e8: 0x024e, 0x11e9: 0x0251,
-	0x11ea: 0x0251, 0x11eb: 0x0254, 0x11ec: 0x0254, 0x11ed: 0x0257, 0x11ee: 0x0257, 0x11ef: 0x025a,
-	0x11f0: 0x025a, 0x11f1: 0x025d, 0x11f2: 0x025d, 0x11f3: 0x025d, 0x11f4: 0x025d, 0x11f5: 0x0260,
-	0x11f6: 0x0260, 0x11f7: 0x0260, 0x11f8: 0x0260, 0x11f9: 0x0263, 0x11fa: 0x0263, 0x11fb: 0x0263,
-	0x11fc: 0x0263, 0x11fd: 0x0266, 0x11fe: 0x0266, 0x11ff: 0x0266,
+	0x11c0: 0x048f, 0x11c1: 0x049b, 0x11c2: 0x049f, 0x11c3: 0x04a3, 0x11c4: 0x04a7,
+	0x11c7: 0x0077, 0x11c8: 0x007b, 0x11c9: 0x4269, 0x11ca: 0x4269, 0x11cb: 0x4269,
+	0x11cc: 0x4269, 0x11cd: 0x007f, 0x11ce: 0x007f, 0x11cf: 0x007f, 0x11d0: 0x0019, 0x11d1: 0x0483,
+	0x11d2: 0x001d, 0x11d4: 0x0037, 0x11d5: 0x0035, 0x11d6: 0x003f, 0x11d7: 0x0003,
+	0x11d8: 0x0443, 0x11d9: 0x0011, 0x11da: 0x0013, 0x11db: 0x00b7, 0x11dc: 0x00bb, 0x11dd: 0x04b7,
+	0x11de: 0x04bb, 0x11df: 0x0007, 0x11e0: 0x000d, 0x11e1: 0x0015, 0x11e2: 0x0017, 0x11e3: 0x001b,
+	0x11e4: 0x0039, 0x11e5: 0x003d, 0x11e6: 0x003b, 0x11e8: 0x0079, 0x11e9: 0x0009,
+	0x11ea: 0x000b, 0x11eb: 0x0041,
+	0x11f0: 0x42aa, 0x11f1: 0x442c, 0x11f2: 0x42af, 0x11f4: 0x42b4,
+	0x11f6: 0x42b9, 0x11f7: 0x4432, 0x11f8: 0x42be, 0x11f9: 0x4438, 0x11fa: 0x42c3, 0x11fb: 0x443e,
+	0x11fc: 0x42c8, 0x11fd: 0x4444, 0x11fe: 0x42cd, 0x11ff: 0x444a,
 	// Block 0x48, offset 0x1200
-	0x1200: 0x0266, 0x1201: 0x0269, 0x1202: 0x0269, 0x1203: 0x0269, 0x1204: 0x0269, 0x1205: 0x026c,
-	0x1206: 0x026c, 0x1207: 0x026c, 0x1208: 0x026c, 0x1209: 0x026f, 0x120a: 0x026f, 0x120b: 0x026f,
-	0x120c: 0x026f, 0x120d: 0x0272, 0x120e: 0x0272, 0x120f: 0x0272, 0x1210: 0x0272, 0x1211: 0x0275,
-	0x1212: 0x0275, 0x1213: 0x0275, 0x1214: 0x0275, 0x1215: 0x0278, 0x1216: 0x0278, 0x1217: 0x0278,
-	0x1218: 0x0278, 0x1219: 0x027b, 0x121a: 0x027b, 0x121b: 0x027b, 0x121c: 0x027b, 0x121d: 0x027e,
-	0x121e: 0x027e, 0x121f: 0x027e, 0x1220: 0x027e, 0x1221: 0x0281, 0x1222: 0x0281, 0x1223: 0x0281,
-	0x1224: 0x0281, 0x1225: 0x0284, 0x1226: 0x0284, 0x1227: 0x0284, 0x1228: 0x0284, 0x1229: 0x0287,
-	0x122a: 0x0287, 0x122b: 0x0287, 0x122c: 0x0287, 0x122d: 0x028a, 0x122e: 0x028a, 0x122f: 0x028d,
-	0x1230: 0x028d, 0x1231: 0x0290, 0x1232: 0x0290, 0x1233: 0x0290, 0x1234: 0x0290, 0x1235: 0x2e00,
-	0x1236: 0x2e00, 0x1237: 0x2e08, 0x1238: 0x2e08, 0x1239: 0x2e10, 0x123a: 0x2e10, 0x123b: 0x1f82,
-	0x123c: 0x1f82,
+	0x1200: 0x0236, 0x1201: 0x440e, 0x1202: 0x440e, 0x1203: 0x4414, 0x1204: 0x4414, 0x1205: 0x4456,
+	0x1206: 0x4456, 0x1207: 0x441a, 0x1208: 0x441a, 0x1209: 0x4462, 0x120a: 0x4462, 0x120b: 0x4462,
+	0x120c: 0x4462, 0x120d: 0x0239, 0x120e: 0x0239, 0x120f: 0x023c, 0x1210: 0x023c, 0x1211: 0x023c,
+	0x1212: 0x023c, 0x1213: 0x023f, 0x1214: 0x023f, 0x1215: 0x0242, 0x1216: 0x0242, 0x1217: 0x0242,
+	0x1218: 0x0242, 0x1219: 0x0245, 0x121a: 0x0245, 0x121b: 0x0245, 0x121c: 0x0245, 0x121d: 0x0248,
+	0x121e: 0x0248, 0x121f: 0x0248, 0x1220: 0x0248, 0x1221: 0x024b, 0x1222: 0x024b, 0x1223: 0x024b,
+	0x1224: 0x024b, 0x1225: 0x024e, 0x1226: 0x024e, 0x1227: 0x024e, 0x1228: 0x024e, 0x1229: 0x0251,
+	0x122a: 0x0251, 0x122b: 0x0254, 0x122c: 0x0254, 0x122d: 0x0257, 0x122e: 0x0257, 0x122f: 0x025a,
+	0x1230: 0x025a, 0x1231: 0x025d, 0x1232: 0x025d, 0x1233: 0x025d, 0x1234: 0x025d, 0x1235: 0x0260,
+	0x1236: 0x0260, 0x1237: 0x0260, 0x1238: 0x0260, 0x1239: 0x0263, 0x123a: 0x0263, 0x123b: 0x0263,
+	0x123c: 0x0263, 0x123d: 0x0266, 0x123e: 0x0266, 0x123f: 0x0266,
 	// Block 0x49, offset 0x1240
-	0x1240: 0x0081, 0x1241: 0x0083, 0x1242: 0x0085, 0x1243: 0x0087, 0x1244: 0x0089, 0x1245: 0x008b,
-	0x1246: 0x008d, 0x1247: 0x008f, 0x1248: 0x0091, 0x1249: 0x0093, 0x124a: 0x0095, 0x124b: 0x0097,
-	0x124c: 0x0099, 0x124d: 0x009b, 0x124e: 0x009d, 0x124f: 0x009f, 0x1250: 0x00a1, 0x1251: 0x00a3,
-	0x1252: 0x00a5, 0x1253: 0x00a7, 0x1254: 0x00a9, 0x1255: 0x00ab, 0x1256: 0x00ad, 0x1257: 0x00af,
-	0x1258: 0x00b1, 0x1259: 0x00b3, 0x125a: 0x00b5, 0x125b: 0x00b7, 0x125c: 0x00b9, 0x125d: 0x00bb,
-	0x125e: 0x00bd, 0x125f: 0x0477, 0x1260: 0x047b, 0x1261: 0x0487, 0x1262: 0x049b, 0x1263: 0x049f,
-	0x1264: 0x0483, 0x1265: 0x05ab, 0x1266: 0x05a3, 0x1267: 0x04c7, 0x1268: 0x04cf, 0x1269: 0x04d7,
-	0x126a: 0x04df, 0x126b: 0x04e7, 0x126c: 0x056b, 0x126d: 0x0573, 0x126e: 0x057b, 0x126f: 0x051f,
-	0x1270: 0x05af, 0x1271: 0x04cb, 0x1272: 0x04d3, 0x1273: 0x04db, 0x1274: 0x04e3, 0x1275: 0x04eb,
-	0x1276: 0x04ef, 0x1277: 0x04f3, 0x1278: 0x04f7, 0x1279: 0x04fb, 0x127a: 0x04ff, 0x127b: 0x0503,
-	0x127c: 0x0507, 0x127d: 0x050b, 0x127e: 0x050f, 0x127f: 0x0513,
+	0x1240: 0x0266, 0x1241: 0x0269, 0x1242: 0x0269, 0x1243: 0x0269, 0x1244: 0x0269, 0x1245: 0x026c,
+	0x1246: 0x026c, 0x1247: 0x026c, 0x1248: 0x026c, 0x1249: 0x026f, 0x124a: 0x026f, 0x124b: 0x026f,
+	0x124c: 0x026f, 0x124d: 0x0272, 0x124e: 0x0272, 0x124f: 0x0272, 0x1250: 0x0272, 0x1251: 0x0275,
+	0x1252: 0x0275, 0x1253: 0x0275, 0x1254: 0x0275, 0x1255: 0x0278, 0x1256: 0x0278, 0x1257: 0x0278,
+	0x1258: 0x0278, 0x1259: 0x027b, 0x125a: 0x027b, 0x125b: 0x027b, 0x125c: 0x027b, 0x125d: 0x027e,
+	0x125e: 0x027e, 0x125f: 0x027e, 0x1260: 0x027e, 0x1261: 0x0281, 0x1262: 0x0281, 0x1263: 0x0281,
+	0x1264: 0x0281, 0x1265: 0x0284, 0x1266: 0x0284, 0x1267: 0x0284, 0x1268: 0x0284, 0x1269: 0x0287,
+	0x126a: 0x0287, 0x126b: 0x0287, 0x126c: 0x0287, 0x126d: 0x028a, 0x126e: 0x028a, 0x126f: 0x028d,
+	0x1270: 0x028d, 0x1271: 0x0290, 0x1272: 0x0290, 0x1273: 0x0290, 0x1274: 0x0290, 0x1275: 0x2e00,
+	0x1276: 0x2e00, 0x1277: 0x2e08, 0x1278: 0x2e08, 0x1279: 0x2e10, 0x127a: 0x2e10, 0x127b: 0x1f82,
+	0x127c: 0x1f82,
 	// Block 0x4a, offset 0x1280
-	0x1280: 0x0517, 0x1281: 0x051b, 0x1282: 0x0523, 0x1283: 0x0527, 0x1284: 0x052b, 0x1285: 0x052f,
-	0x1286: 0x0533, 0x1287: 0x0537, 0x1288: 0x053b, 0x1289: 0x053f, 0x128a: 0x0543, 0x128b: 0x0547,
-	0x128c: 0x054b, 0x128d: 0x054f, 0x128e: 0x0553, 0x128f: 0x0557, 0x1290: 0x055b, 0x1291: 0x055f,
-	0x1292: 0x0563, 0x1293: 0x0567, 0x1294: 0x056f, 0x1295: 0x0577, 0x1296: 0x057f, 0x1297: 0x0583,
-	0x1298: 0x0587, 0x1299: 0x058b, 0x129a: 0x058f, 0x129b: 0x0593, 0x129c: 0x0597, 0x129d: 0x05a7,
-	0x129e: 0x4a78, 0x129f: 0x4a7e, 0x12a0: 0x03c3, 0x12a1: 0x0313, 0x12a2: 0x0317, 0x12a3: 0x4a3b,
-	0x12a4: 0x031b, 0x12a5: 0x4a41, 0x12a6: 0x4a47, 0x12a7: 0x031f, 0x12a8: 0x0323, 0x12a9: 0x0327,
-	0x12aa: 0x4a4d, 0x12ab: 0x4a53, 0x12ac: 0x4a59, 0x12ad: 0x4a5f, 0x12ae: 0x4a65, 0x12af: 0x4a6b,
-	0x12b0: 0x0367, 0x12b1: 0x032b, 0x12b2: 0x032f, 0x12b3: 0x0333, 0x12b4: 0x037b, 0x12b5: 0x0337,
-	0x12b6: 0x033b, 0x12b7: 0x033f, 0x12b8: 0x0343, 0x12b9: 0x0347, 0x12ba: 0x034b, 0x12bb: 0x034f,
-	0x12bc: 0x0353, 0x12bd: 0x0357, 0x12be: 0x035b,
+	0x1280: 0x0081, 0x1281: 0x0083, 0x1282: 0x0085, 0x1283: 0x0087, 0x1284: 0x0089, 0x1285: 0x008b,
+	0x1286: 0x008d, 0x1287: 0x008f, 0x1288: 0x0091, 0x1289: 0x0093, 0x128a: 0x0095, 0x128b: 0x0097,
+	0x128c: 0x0099, 0x128d: 0x009b, 0x128e: 0x009d, 0x128f: 0x009f, 0x1290: 0x00a1, 0x1291: 0x00a3,
+	0x1292: 0x00a5, 0x1293: 0x00a7, 0x1294: 0x00a9, 0x1295: 0x00ab, 0x1296: 0x00ad, 0x1297: 0x00af,
+	0x1298: 0x00b1, 0x1299: 0x00b3, 0x129a: 0x00b5, 0x129b: 0x00b7, 0x129c: 0x00b9, 0x129d: 0x00bb,
+	0x129e: 0x00bd, 0x129f: 0x0477, 0x12a0: 0x047b, 0x12a1: 0x0487, 0x12a2: 0x049b, 0x12a3: 0x049f,
+	0x12a4: 0x0483, 0x12a5: 0x05ab, 0x12a6: 0x05a3, 0x12a7: 0x04c7, 0x12a8: 0x04cf, 0x12a9: 0x04d7,
+	0x12aa: 0x04df, 0x12ab: 0x04e7, 0x12ac: 0x056b, 0x12ad: 0x0573, 0x12ae: 0x057b, 0x12af: 0x051f,
+	0x12b0: 0x05af, 0x12b1: 0x04cb, 0x12b2: 0x04d3, 0x12b3: 0x04db, 0x12b4: 0x04e3, 0x12b5: 0x04eb,
+	0x12b6: 0x04ef, 0x12b7: 0x04f3, 0x12b8: 0x04f7, 0x12b9: 0x04fb, 0x12ba: 0x04ff, 0x12bb: 0x0503,
+	0x12bc: 0x0507, 0x12bd: 0x050b, 0x12be: 0x050f, 0x12bf: 0x0513,
 	// Block 0x4b, offset 0x12c0
-	0x12c2: 0x49bd, 0x12c3: 0x49c3, 0x12c4: 0x49c9, 0x12c5: 0x49cf,
-	0x12c6: 0x49d5, 0x12c7: 0x49db, 0x12ca: 0x49e1, 0x12cb: 0x49e7,
-	0x12cc: 0x49ed, 0x12cd: 0x49f3, 0x12ce: 0x49f9, 0x12cf: 0x49ff,
-	0x12d2: 0x4a05, 0x12d3: 0x4a0b, 0x12d4: 0x4a11, 0x12d5: 0x4a17, 0x12d6: 0x4a1d, 0x12d7: 0x4a23,
-	0x12da: 0x4a29, 0x12db: 0x4a2f, 0x12dc: 0x4a35,
-	0x12e0: 0x00bf, 0x12e1: 0x00c2, 0x12e2: 0x00cb, 0x12e3: 0x4264,
-	0x12e4: 0x00c8, 0x12e5: 0x00c5, 0x12e6: 0x0447, 0x12e8: 0x046b, 0x12e9: 0x044b,
-	0x12ea: 0x044f, 0x12eb: 0x0453, 0x12ec: 0x0457, 0x12ed: 0x046f, 0x12ee: 0x0473,
+	0x12c0: 0x0517, 0x12c1: 0x051b, 0x12c2: 0x0523, 0x12c3: 0x0527, 0x12c4: 0x052b, 0x12c5: 0x052f,
+	0x12c6: 0x0533, 0x12c7: 0x0537, 0x12c8: 0x053b, 0x12c9: 0x053f, 0x12ca: 0x0543, 0x12cb: 0x0547,
+	0x12cc: 0x054b, 0x12cd: 0x054f, 0x12ce: 0x0553, 0x12cf: 0x0557, 0x12d0: 0x055b, 0x12d1: 0x055f,
+	0x12d2: 0x0563, 0x12d3: 0x0567, 0x12d4: 0x056f, 0x12d5: 0x0577, 0x12d6: 0x057f, 0x12d7: 0x0583,
+	0x12d8: 0x0587, 0x12d9: 0x058b, 0x12da: 0x058f, 0x12db: 0x0593, 0x12dc: 0x0597, 0x12dd: 0x05a7,
+	0x12de: 0x4a78, 0x12df: 0x4a7e, 0x12e0: 0x03c3, 0x12e1: 0x0313, 0x12e2: 0x0317, 0x12e3: 0x4a3b,
+	0x12e4: 0x031b, 0x12e5: 0x4a41, 0x12e6: 0x4a47, 0x12e7: 0x031f, 0x12e8: 0x0323, 0x12e9: 0x0327,
+	0x12ea: 0x4a4d, 0x12eb: 0x4a53, 0x12ec: 0x4a59, 0x12ed: 0x4a5f, 0x12ee: 0x4a65, 0x12ef: 0x4a6b,
+	0x12f0: 0x0367, 0x12f1: 0x032b, 0x12f2: 0x032f, 0x12f3: 0x0333, 0x12f4: 0x037b, 0x12f5: 0x0337,
+	0x12f6: 0x033b, 0x12f7: 0x033f, 0x12f8: 0x0343, 0x12f9: 0x0347, 0x12fa: 0x034b, 0x12fb: 0x034f,
+	0x12fc: 0x0353, 0x12fd: 0x0357, 0x12fe: 0x035b,
 	// Block 0x4c, offset 0x1300
-	0x1300: 0x0063, 0x1301: 0x0065, 0x1302: 0x0067, 0x1303: 0x0069, 0x1304: 0x006b, 0x1305: 0x006d,
-	0x1306: 0x006f, 0x1307: 0x0071, 0x1308: 0x0073, 0x1309: 0x0075, 0x130a: 0x0083, 0x130b: 0x0085,
-	0x130c: 0x0087, 0x130d: 0x0089, 0x130e: 0x008b, 0x130f: 0x008d, 0x1310: 0x008f, 0x1311: 0x0091,
-	0x1312: 0x0093, 0x1313: 0x0095, 0x1314: 0x0097, 0x1315: 0x0099, 0x1316: 0x009b, 0x1317: 0x009d,
-	0x1318: 0x009f, 0x1319: 0x00a1, 0x131a: 0x00a3, 0x131b: 0x00a5, 0x131c: 0x00a7, 0x131d: 0x00a9,
-	0x131e: 0x00ab, 0x131f: 0x00ad, 0x1320: 0x00af, 0x1321: 0x00b1, 0x1322: 0x00b3, 0x1323: 0x00b5,
-	0x1324: 0x00dd, 0x1325: 0x00f2, 0x1328: 0x0173, 0x1329: 0x0176,
-	0x132a: 0x0179, 0x132b: 0x017c, 0x132c: 0x017f, 0x132d: 0x0182, 0x132e: 0x0185, 0x132f: 0x0188,
-	0x1330: 0x018b, 0x1331: 0x018e, 0x1332: 0x0191, 0x1333: 0x0194, 0x1334: 0x0197, 0x1335: 0x019a,
-	0x1336: 0x019d, 0x1337: 0x01a0, 0x1338: 0x01a3, 0x1339: 0x0188, 0x133a: 0x01a6, 0x133b: 0x01a9,
-	0x133c: 0x01ac, 0x133d: 0x01af, 0x133e: 0x01b2, 0x133f: 0x01b5,
+	0x1302: 0x49bd, 0x1303: 0x49c3, 0x1304: 0x49c9, 0x1305: 0x49cf,
+	0x1306: 0x49d5, 0x1307: 0x49db, 0x130a: 0x49e1, 0x130b: 0x49e7,
+	0x130c: 0x49ed, 0x130d: 0x49f3, 0x130e: 0x49f9, 0x130f: 0x49ff,
+	0x1312: 0x4a05, 0x1313: 0x4a0b, 0x1314: 0x4a11, 0x1315: 0x4a17, 0x1316: 0x4a1d, 0x1317: 0x4a23,
+	0x131a: 0x4a29, 0x131b: 0x4a2f, 0x131c: 0x4a35,
+	0x1320: 0x00bf, 0x1321: 0x00c2, 0x1322: 0x00cb, 0x1323: 0x4264,
+	0x1324: 0x00c8, 0x1325: 0x00c5, 0x1326: 0x0447, 0x1328: 0x046b, 0x1329: 0x044b,
+	0x132a: 0x044f, 0x132b: 0x0453, 0x132c: 0x0457, 0x132d: 0x046f, 0x132e: 0x0473,
 	// Block 0x4d, offset 0x1340
-	0x1340: 0x01fd, 0x1341: 0x0200, 0x1342: 0x0203, 0x1343: 0x045b, 0x1344: 0x01c7, 0x1345: 0x01d0,
-	0x1346: 0x01d6, 0x1347: 0x01fa, 0x1348: 0x01eb, 0x1349: 0x01e8, 0x134a: 0x0206, 0x134b: 0x0209,
-	0x134e: 0x0021, 0x134f: 0x0023, 0x1350: 0x0025, 0x1351: 0x0027,
-	0x1352: 0x0029, 0x1353: 0x002b, 0x1354: 0x002d, 0x1355: 0x002f, 0x1356: 0x0031, 0x1357: 0x0033,
-	0x1358: 0x0021, 0x1359: 0x0023, 0x135a: 0x0025, 0x135b: 0x0027, 0x135c: 0x0029, 0x135d: 0x002b,
-	0x135e: 0x002d, 0x135f: 0x002f, 0x1360: 0x0031, 0x1361: 0x0033, 0x1362: 0x0021, 0x1363: 0x0023,
-	0x1364: 0x0025, 0x1365: 0x0027, 0x1366: 0x0029, 0x1367: 0x002b, 0x1368: 0x002d, 0x1369: 0x002f,
-	0x136a: 0x0031, 0x136b: 0x0033, 0x136c: 0x0021, 0x136d: 0x0023, 0x136e: 0x0025, 0x136f: 0x0027,
-	0x1370: 0x0029, 0x1371: 0x002b, 0x1372: 0x002d, 0x1373: 0x002f, 0x1374: 0x0031, 0x1375: 0x0033,
-	0x1376: 0x0021, 0x1377: 0x0023, 0x1378: 0x0025, 0x1379: 0x0027, 0x137a: 0x0029, 0x137b: 0x002b,
-	0x137c: 0x002d, 0x137d: 0x002f, 0x137e: 0x0031, 0x137f: 0x0033,
+	0x1340: 0x0063, 0x1341: 0x0065, 0x1342: 0x0067, 0x1343: 0x0069, 0x1344: 0x006b, 0x1345: 0x006d,
+	0x1346: 0x006f, 0x1347: 0x0071, 0x1348: 0x0073, 0x1349: 0x0075, 0x134a: 0x0083, 0x134b: 0x0085,
+	0x134c: 0x0087, 0x134d: 0x0089, 0x134e: 0x008b, 0x134f: 0x008d, 0x1350: 0x008f, 0x1351: 0x0091,
+	0x1352: 0x0093, 0x1353: 0x0095, 0x1354: 0x0097, 0x1355: 0x0099, 0x1356: 0x009b, 0x1357: 0x009d,
+	0x1358: 0x009f, 0x1359: 0x00a1, 0x135a: 0x00a3, 0x135b: 0x00a5, 0x135c: 0x00a7, 0x135d: 0x00a9,
+	0x135e: 0x00ab, 0x135f: 0x00ad, 0x1360: 0x00af, 0x1361: 0x00b1, 0x1362: 0x00b3, 0x1363: 0x00b5,
+	0x1364: 0x00dd, 0x1365: 0x00f2, 0x1368: 0x0173, 0x1369: 0x0176,
+	0x136a: 0x0179, 0x136b: 0x017c, 0x136c: 0x017f, 0x136d: 0x0182, 0x136e: 0x0185, 0x136f: 0x0188,
+	0x1370: 0x018b, 0x1371: 0x018e, 0x1372: 0x0191, 0x1373: 0x0194, 0x1374: 0x0197, 0x1375: 0x019a,
+	0x1376: 0x019d, 0x1377: 0x01a0, 0x1378: 0x01a3, 0x1379: 0x0188, 0x137a: 0x01a6, 0x137b: 0x01a9,
+	0x137c: 0x01ac, 0x137d: 0x01af, 0x137e: 0x01b2, 0x137f: 0x01b5,
 	// Block 0x4e, offset 0x1380
-	0x1380: 0x0239, 0x1381: 0x023c, 0x1382: 0x0248, 0x1383: 0x0251, 0x1385: 0x028a,
-	0x1386: 0x025a, 0x1387: 0x024b, 0x1388: 0x0269, 0x1389: 0x0290, 0x138a: 0x027b, 0x138b: 0x027e,
-	0x138c: 0x0281, 0x138d: 0x0284, 0x138e: 0x025d, 0x138f: 0x026f, 0x1390: 0x0275, 0x1391: 0x0263,
-	0x1392: 0x0278, 0x1393: 0x0257, 0x1394: 0x0260, 0x1395: 0x0242, 0x1396: 0x0245, 0x1397: 0x024e,
-	0x1398: 0x0254, 0x1399: 0x0266, 0x139a: 0x026c, 0x139b: 0x0272, 0x139c: 0x0293, 0x139d: 0x02e4,
-	0x139e: 0x02cc, 0x139f: 0x0296, 0x13a1: 0x023c, 0x13a2: 0x0248,
-	0x13a4: 0x0287, 0x13a7: 0x024b, 0x13a9: 0x0290,
-	0x13aa: 0x027b, 0x13ab: 0x027e, 0x13ac: 0x0281, 0x13ad: 0x0284, 0x13ae: 0x025d, 0x13af: 0x026f,
-	0x13b0: 0x0275, 0x13b1: 0x0263, 0x13b2: 0x0278, 0x13b4: 0x0260, 0x13b5: 0x0242,
-	0x13b6: 0x0245, 0x13b7: 0x024e, 0x13b9: 0x0266, 0x13bb: 0x0272,
+	0x1380: 0x01fd, 0x1381: 0x0200, 0x1382: 0x0203, 0x1383: 0x045b, 0x1384: 0x01c7, 0x1385: 0x01d0,
+	0x1386: 0x01d6, 0x1387: 0x01fa, 0x1388: 0x01eb, 0x1389: 0x01e8, 0x138a: 0x0206, 0x138b: 0x0209,
+	0x138e: 0x0021, 0x138f: 0x0023, 0x1390: 0x0025, 0x1391: 0x0027,
+	0x1392: 0x0029, 0x1393: 0x002b, 0x1394: 0x002d, 0x1395: 0x002f, 0x1396: 0x0031, 0x1397: 0x0033,
+	0x1398: 0x0021, 0x1399: 0x0023, 0x139a: 0x0025, 0x139b: 0x0027, 0x139c: 0x0029, 0x139d: 0x002b,
+	0x139e: 0x002d, 0x139f: 0x002f, 0x13a0: 0x0031, 0x13a1: 0x0033, 0x13a2: 0x0021, 0x13a3: 0x0023,
+	0x13a4: 0x0025, 0x13a5: 0x0027, 0x13a6: 0x0029, 0x13a7: 0x002b, 0x13a8: 0x002d, 0x13a9: 0x002f,
+	0x13aa: 0x0031, 0x13ab: 0x0033, 0x13ac: 0x0021, 0x13ad: 0x0023, 0x13ae: 0x0025, 0x13af: 0x0027,
+	0x13b0: 0x0029, 0x13b1: 0x002b, 0x13b2: 0x002d, 0x13b3: 0x002f, 0x13b4: 0x0031, 0x13b5: 0x0033,
+	0x13b6: 0x0021, 0x13b7: 0x0023, 0x13b8: 0x0025, 0x13b9: 0x0027, 0x13ba: 0x0029, 0x13bb: 0x002b,
+	0x13bc: 0x002d, 0x13bd: 0x002f, 0x13be: 0x0031, 0x13bf: 0x0033,
 	// Block 0x4f, offset 0x13c0
-	0x13c2: 0x0248,
-	0x13c7: 0x024b, 0x13c9: 0x0290, 0x13cb: 0x027e,
-	0x13cd: 0x0284, 0x13ce: 0x025d, 0x13cf: 0x026f, 0x13d1: 0x0263,
-	0x13d2: 0x0278, 0x13d4: 0x0260, 0x13d7: 0x024e,
-	0x13d9: 0x0266, 0x13db: 0x0272, 0x13dd: 0x02e4,
-	0x13df: 0x0296, 0x13e1: 0x023c, 0x13e2: 0x0248,
-	0x13e4: 0x0287, 0x13e7: 0x024b, 0x13e8: 0x0269, 0x13e9: 0x0290,
-	0x13ea: 0x027b, 0x13ec: 0x0281, 0x13ed: 0x0284, 0x13ee: 0x025d, 0x13ef: 0x026f,
+	0x13c0: 0x0239, 0x13c1: 0x023c, 0x13c2: 0x0248, 0x13c3: 0x0251, 0x13c5: 0x028a,
+	0x13c6: 0x025a, 0x13c7: 0x024b, 0x13c8: 0x0269, 0x13c9: 0x0290, 0x13ca: 0x027b, 0x13cb: 0x027e,
+	0x13cc: 0x0281, 0x13cd: 0x0284, 0x13ce: 0x025d, 0x13cf: 0x026f, 0x13d0: 0x0275, 0x13d1: 0x0263,
+	0x13d2: 0x0278, 0x13d3: 0x0257, 0x13d4: 0x0260, 0x13d5: 0x0242, 0x13d6: 0x0245, 0x13d7: 0x024e,
+	0x13d8: 0x0254, 0x13d9: 0x0266, 0x13da: 0x026c, 0x13db: 0x0272, 0x13dc: 0x0293, 0x13dd: 0x02e4,
+	0x13de: 0x02cc, 0x13df: 0x0296, 0x13e1: 0x023c, 0x13e2: 0x0248,
+	0x13e4: 0x0287, 0x13e7: 0x024b, 0x13e9: 0x0290,
+	0x13ea: 0x027b, 0x13eb: 0x027e, 0x13ec: 0x0281, 0x13ed: 0x0284, 0x13ee: 0x025d, 0x13ef: 0x026f,
 	0x13f0: 0x0275, 0x13f1: 0x0263, 0x13f2: 0x0278, 0x13f4: 0x0260, 0x13f5: 0x0242,
-	0x13f6: 0x0245, 0x13f7: 0x024e, 0x13f9: 0x0266, 0x13fa: 0x026c, 0x13fb: 0x0272,
-	0x13fc: 0x0293, 0x13fe: 0x02cc,
+	0x13f6: 0x0245, 0x13f7: 0x024e, 0x13f9: 0x0266, 0x13fb: 0x0272,
 	// Block 0x50, offset 0x1400
-	0x1400: 0x0239, 0x1401: 0x023c, 0x1402: 0x0248, 0x1403: 0x0251, 0x1404: 0x0287, 0x1405: 0x028a,
-	0x1406: 0x025a, 0x1407: 0x024b, 0x1408: 0x0269, 0x1409: 0x0290, 0x140b: 0x027e,
-	0x140c: 0x0281, 0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1410: 0x0275, 0x1411: 0x0263,
-	0x1412: 0x0278, 0x1413: 0x0257, 0x1414: 0x0260, 0x1415: 0x0242, 0x1416: 0x0245, 0x1417: 0x024e,
-	0x1418: 0x0254, 0x1419: 0x0266, 0x141a: 0x026c, 0x141b: 0x0272,
-	0x1421: 0x023c, 0x1422: 0x0248, 0x1423: 0x0251,
-	0x1425: 0x028a, 0x1426: 0x025a, 0x1427: 0x024b, 0x1428: 0x0269, 0x1429: 0x0290,
-	0x142b: 0x027e, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f,
-	0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1433: 0x0257, 0x1434: 0x0260, 0x1435: 0x0242,
-	0x1436: 0x0245, 0x1437: 0x024e, 0x1438: 0x0254, 0x1439: 0x0266, 0x143a: 0x026c, 0x143b: 0x0272,
+	0x1402: 0x0248,
+	0x1407: 0x024b, 0x1409: 0x0290, 0x140b: 0x027e,
+	0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1411: 0x0263,
+	0x1412: 0x0278, 0x1414: 0x0260, 0x1417: 0x024e,
+	0x1419: 0x0266, 0x141b: 0x0272, 0x141d: 0x02e4,
+	0x141f: 0x0296, 0x1421: 0x023c, 0x1422: 0x0248,
+	0x1424: 0x0287, 0x1427: 0x024b, 0x1428: 0x0269, 0x1429: 0x0290,
+	0x142a: 0x027b, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f,
+	0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1434: 0x0260, 0x1435: 0x0242,
+	0x1436: 0x0245, 0x1437: 0x024e, 0x1439: 0x0266, 0x143a: 0x026c, 0x143b: 0x0272,
+	0x143c: 0x0293, 0x143e: 0x02cc,
 	// Block 0x51, offset 0x1440
-	0x1440: 0x1879, 0x1441: 0x1876, 0x1442: 0x187c, 0x1443: 0x18a0, 0x1444: 0x18c4, 0x1445: 0x18e8,
-	0x1446: 0x190c, 0x1447: 0x1915, 0x1448: 0x191b, 0x1449: 0x1921, 0x144a: 0x1927,
-	0x1450: 0x1a8c, 0x1451: 0x1a90,
-	0x1452: 0x1a94, 0x1453: 0x1a98, 0x1454: 0x1a9c, 0x1455: 0x1aa0, 0x1456: 0x1aa4, 0x1457: 0x1aa8,
-	0x1458: 0x1aac, 0x1459: 0x1ab0, 0x145a: 0x1ab4, 0x145b: 0x1ab8, 0x145c: 0x1abc, 0x145d: 0x1ac0,
-	0x145e: 0x1ac4, 0x145f: 0x1ac8, 0x1460: 0x1acc, 0x1461: 0x1ad0, 0x1462: 0x1ad4, 0x1463: 0x1ad8,
-	0x1464: 0x1adc, 0x1465: 0x1ae0, 0x1466: 0x1ae4, 0x1467: 0x1ae8, 0x1468: 0x1aec, 0x1469: 0x1af0,
-	0x146a: 0x271e, 0x146b: 0x0047, 0x146c: 0x0065, 0x146d: 0x193c, 0x146e: 0x19b1,
-	0x1470: 0x0043, 0x1471: 0x0045, 0x1472: 0x0047, 0x1473: 0x0049, 0x1474: 0x004b, 0x1475: 0x004d,
-	0x1476: 0x004f, 0x1477: 0x0051, 0x1478: 0x0053, 0x1479: 0x0055, 0x147a: 0x0057, 0x147b: 0x0059,
-	0x147c: 0x005b, 0x147d: 0x005d, 0x147e: 0x005f, 0x147f: 0x0061,
+	0x1440: 0x0239, 0x1441: 0x023c, 0x1442: 0x0248, 0x1443: 0x0251, 0x1444: 0x0287, 0x1445: 0x028a,
+	0x1446: 0x025a, 0x1447: 0x024b, 0x1448: 0x0269, 0x1449: 0x0290, 0x144b: 0x027e,
+	0x144c: 0x0281, 0x144d: 0x0284, 0x144e: 0x025d, 0x144f: 0x026f, 0x1450: 0x0275, 0x1451: 0x0263,
+	0x1452: 0x0278, 0x1453: 0x0257, 0x1454: 0x0260, 0x1455: 0x0242, 0x1456: 0x0245, 0x1457: 0x024e,
+	0x1458: 0x0254, 0x1459: 0x0266, 0x145a: 0x026c, 0x145b: 0x0272,
+	0x1461: 0x023c, 0x1462: 0x0248, 0x1463: 0x0251,
+	0x1465: 0x028a, 0x1466: 0x025a, 0x1467: 0x024b, 0x1468: 0x0269, 0x1469: 0x0290,
+	0x146b: 0x027e, 0x146c: 0x0281, 0x146d: 0x0284, 0x146e: 0x025d, 0x146f: 0x026f,
+	0x1470: 0x0275, 0x1471: 0x0263, 0x1472: 0x0278, 0x1473: 0x0257, 0x1474: 0x0260, 0x1475: 0x0242,
+	0x1476: 0x0245, 0x1477: 0x024e, 0x1478: 0x0254, 0x1479: 0x0266, 0x147a: 0x026c, 0x147b: 0x0272,
 	// Block 0x52, offset 0x1480
-	0x1480: 0x26ad, 0x1481: 0x26c2, 0x1482: 0x0503,
-	0x1490: 0x0c0f, 0x1491: 0x0a47,
-	0x1492: 0x08d3, 0x1493: 0x45c4, 0x1494: 0x071b, 0x1495: 0x09ef, 0x1496: 0x132f, 0x1497: 0x09ff,
-	0x1498: 0x0727, 0x1499: 0x0cd7, 0x149a: 0x0eaf, 0x149b: 0x0caf, 0x149c: 0x0827, 0x149d: 0x0b6b,
-	0x149e: 0x07bf, 0x149f: 0x0cb7, 0x14a0: 0x0813, 0x14a1: 0x1117, 0x14a2: 0x0f83, 0x14a3: 0x138b,
-	0x14a4: 0x09d3, 0x14a5: 0x090b, 0x14a6: 0x0e63, 0x14a7: 0x0c1b, 0x14a8: 0x0c47, 0x14a9: 0x06bf,
-	0x14aa: 0x06cb, 0x14ab: 0x140b, 0x14ac: 0x0adb, 0x14ad: 0x06e7, 0x14ae: 0x08ef, 0x14af: 0x0c3b,
-	0x14b0: 0x13b3, 0x14b1: 0x0c13, 0x14b2: 0x106f, 0x14b3: 0x10ab, 0x14b4: 0x08f7, 0x14b5: 0x0e43,
-	0x14b6: 0x0d0b, 0x14b7: 0x0d07, 0x14b8: 0x0f97, 0x14b9: 0x082b, 0x14ba: 0x0957, 0x14bb: 0x1443,
+	0x1480: 0x1879, 0x1481: 0x1876, 0x1482: 0x187c, 0x1483: 0x18a0, 0x1484: 0x18c4, 0x1485: 0x18e8,
+	0x1486: 0x190c, 0x1487: 0x1915, 0x1488: 0x191b, 0x1489: 0x1921, 0x148a: 0x1927,
+	0x1490: 0x1a8c, 0x1491: 0x1a90,
+	0x1492: 0x1a94, 0x1493: 0x1a98, 0x1494: 0x1a9c, 0x1495: 0x1aa0, 0x1496: 0x1aa4, 0x1497: 0x1aa8,
+	0x1498: 0x1aac, 0x1499: 0x1ab0, 0x149a: 0x1ab4, 0x149b: 0x1ab8, 0x149c: 0x1abc, 0x149d: 0x1ac0,
+	0x149e: 0x1ac4, 0x149f: 0x1ac8, 0x14a0: 0x1acc, 0x14a1: 0x1ad0, 0x14a2: 0x1ad4, 0x14a3: 0x1ad8,
+	0x14a4: 0x1adc, 0x14a5: 0x1ae0, 0x14a6: 0x1ae4, 0x14a7: 0x1ae8, 0x14a8: 0x1aec, 0x14a9: 0x1af0,
+	0x14aa: 0x271e, 0x14ab: 0x0047, 0x14ac: 0x0065, 0x14ad: 0x193c, 0x14ae: 0x19b1,
+	0x14b0: 0x0043, 0x14b1: 0x0045, 0x14b2: 0x0047, 0x14b3: 0x0049, 0x14b4: 0x004b, 0x14b5: 0x004d,
+	0x14b6: 0x004f, 0x14b7: 0x0051, 0x14b8: 0x0053, 0x14b9: 0x0055, 0x14ba: 0x0057, 0x14bb: 0x0059,
+	0x14bc: 0x005b, 0x14bd: 0x005d, 0x14be: 0x005f, 0x14bf: 0x0061,
 	// Block 0x53, offset 0x14c0
-	0x14c0: 0x06fb, 0x14c1: 0x06f3, 0x14c2: 0x0703, 0x14c3: 0x1647, 0x14c4: 0x0747, 0x14c5: 0x0757,
-	0x14c6: 0x075b, 0x14c7: 0x0763, 0x14c8: 0x076b, 0x14c9: 0x076f, 0x14ca: 0x077b, 0x14cb: 0x0773,
-	0x14cc: 0x05b3, 0x14cd: 0x165b, 0x14ce: 0x078f, 0x14cf: 0x0793, 0x14d0: 0x0797, 0x14d1: 0x07b3,
-	0x14d2: 0x164c, 0x14d3: 0x05b7, 0x14d4: 0x079f, 0x14d5: 0x07bf, 0x14d6: 0x1656, 0x14d7: 0x07cf,
-	0x14d8: 0x07d7, 0x14d9: 0x0737, 0x14da: 0x07df, 0x14db: 0x07e3, 0x14dc: 0x1831, 0x14dd: 0x07ff,
-	0x14de: 0x0807, 0x14df: 0x05bf, 0x14e0: 0x081f, 0x14e1: 0x0823, 0x14e2: 0x082b, 0x14e3: 0x082f,
-	0x14e4: 0x05c3, 0x14e5: 0x0847, 0x14e6: 0x084b, 0x14e7: 0x0857, 0x14e8: 0x0863, 0x14e9: 0x0867,
-	0x14ea: 0x086b, 0x14eb: 0x0873, 0x14ec: 0x0893, 0x14ed: 0x0897, 0x14ee: 0x089f, 0x14ef: 0x08af,
-	0x14f0: 0x08b7, 0x14f1: 0x08bb, 0x14f2: 0x08bb, 0x14f3: 0x08bb, 0x14f4: 0x166a, 0x14f5: 0x0e93,
-	0x14f6: 0x08cf, 0x14f7: 0x08d7, 0x14f8: 0x166f, 0x14f9: 0x08e3, 0x14fa: 0x08eb, 0x14fb: 0x08f3,
-	0x14fc: 0x091b, 0x14fd: 0x0907, 0x14fe: 0x0913, 0x14ff: 0x0917,
+	0x14c0: 0x26ad, 0x14c1: 0x26c2, 0x14c2: 0x0503,
+	0x14d0: 0x0c0f, 0x14d1: 0x0a47,
+	0x14d2: 0x08d3, 0x14d3: 0x45c4, 0x14d4: 0x071b, 0x14d5: 0x09ef, 0x14d6: 0x132f, 0x14d7: 0x09ff,
+	0x14d8: 0x0727, 0x14d9: 0x0cd7, 0x14da: 0x0eaf, 0x14db: 0x0caf, 0x14dc: 0x0827, 0x14dd: 0x0b6b,
+	0x14de: 0x07bf, 0x14df: 0x0cb7, 0x14e0: 0x0813, 0x14e1: 0x1117, 0x14e2: 0x0f83, 0x14e3: 0x138b,
+	0x14e4: 0x09d3, 0x14e5: 0x090b, 0x14e6: 0x0e63, 0x14e7: 0x0c1b, 0x14e8: 0x0c47, 0x14e9: 0x06bf,
+	0x14ea: 0x06cb, 0x14eb: 0x140b, 0x14ec: 0x0adb, 0x14ed: 0x06e7, 0x14ee: 0x08ef, 0x14ef: 0x0c3b,
+	0x14f0: 0x13b3, 0x14f1: 0x0c13, 0x14f2: 0x106f, 0x14f3: 0x10ab, 0x14f4: 0x08f7, 0x14f5: 0x0e43,
+	0x14f6: 0x0d0b, 0x14f7: 0x0d07, 0x14f8: 0x0f97, 0x14f9: 0x082b, 0x14fa: 0x0957, 0x14fb: 0x1443,
 	// Block 0x54, offset 0x1500
-	0x1500: 0x091f, 0x1501: 0x0927, 0x1502: 0x092b, 0x1503: 0x0933, 0x1504: 0x093b, 0x1505: 0x093f,
-	0x1506: 0x093f, 0x1507: 0x0947, 0x1508: 0x094f, 0x1509: 0x0953, 0x150a: 0x095f, 0x150b: 0x0983,
-	0x150c: 0x0967, 0x150d: 0x0987, 0x150e: 0x096b, 0x150f: 0x0973, 0x1510: 0x080b, 0x1511: 0x09cf,
-	0x1512: 0x0997, 0x1513: 0x099b, 0x1514: 0x099f, 0x1515: 0x0993, 0x1516: 0x09a7, 0x1517: 0x09a3,
-	0x1518: 0x09bb, 0x1519: 0x1674, 0x151a: 0x09d7, 0x151b: 0x09db, 0x151c: 0x09e3, 0x151d: 0x09ef,
-	0x151e: 0x09f7, 0x151f: 0x0a13, 0x1520: 0x1679, 0x1521: 0x167e, 0x1522: 0x0a1f, 0x1523: 0x0a23,
-	0x1524: 0x0a27, 0x1525: 0x0a1b, 0x1526: 0x0a2f, 0x1527: 0x05c7, 0x1528: 0x05cb, 0x1529: 0x0a37,
-	0x152a: 0x0a3f, 0x152b: 0x0a3f, 0x152c: 0x1683, 0x152d: 0x0a5b, 0x152e: 0x0a5f, 0x152f: 0x0a63,
-	0x1530: 0x0a6b, 0x1531: 0x1688, 0x1532: 0x0a73, 0x1533: 0x0a77, 0x1534: 0x0b4f, 0x1535: 0x0a7f,
-	0x1536: 0x05cf, 0x1537: 0x0a8b, 0x1538: 0x0a9b, 0x1539: 0x0aa7, 0x153a: 0x0aa3, 0x153b: 0x1692,
-	0x153c: 0x0aaf, 0x153d: 0x1697, 0x153e: 0x0abb, 0x153f: 0x0ab7,
+	0x1500: 0x06fb, 0x1501: 0x06f3, 0x1502: 0x0703, 0x1503: 0x1647, 0x1504: 0x0747, 0x1505: 0x0757,
+	0x1506: 0x075b, 0x1507: 0x0763, 0x1508: 0x076b, 0x1509: 0x076f, 0x150a: 0x077b, 0x150b: 0x0773,
+	0x150c: 0x05b3, 0x150d: 0x165b, 0x150e: 0x078f, 0x150f: 0x0793, 0x1510: 0x0797, 0x1511: 0x07b3,
+	0x1512: 0x164c, 0x1513: 0x05b7, 0x1514: 0x079f, 0x1515: 0x07bf, 0x1516: 0x1656, 0x1517: 0x07cf,
+	0x1518: 0x07d7, 0x1519: 0x0737, 0x151a: 0x07df, 0x151b: 0x07e3, 0x151c: 0x1831, 0x151d: 0x07ff,
+	0x151e: 0x0807, 0x151f: 0x05bf, 0x1520: 0x081f, 0x1521: 0x0823, 0x1522: 0x082b, 0x1523: 0x082f,
+	0x1524: 0x05c3, 0x1525: 0x0847, 0x1526: 0x084b, 0x1527: 0x0857, 0x1528: 0x0863, 0x1529: 0x0867,
+	0x152a: 0x086b, 0x152b: 0x0873, 0x152c: 0x0893, 0x152d: 0x0897, 0x152e: 0x089f, 0x152f: 0x08af,
+	0x1530: 0x08b7, 0x1531: 0x08bb, 0x1532: 0x08bb, 0x1533: 0x08bb, 0x1534: 0x166a, 0x1535: 0x0e93,
+	0x1536: 0x08cf, 0x1537: 0x08d7, 0x1538: 0x166f, 0x1539: 0x08e3, 0x153a: 0x08eb, 0x153b: 0x08f3,
+	0x153c: 0x091b, 0x153d: 0x0907, 0x153e: 0x0913, 0x153f: 0x0917,
 	// Block 0x55, offset 0x1540
-	0x1540: 0x0abf, 0x1541: 0x0acf, 0x1542: 0x0ad3, 0x1543: 0x05d3, 0x1544: 0x0ae3, 0x1545: 0x0aeb,
-	0x1546: 0x0aef, 0x1547: 0x0af3, 0x1548: 0x05d7, 0x1549: 0x169c, 0x154a: 0x05db, 0x154b: 0x0b0f,
-	0x154c: 0x0b13, 0x154d: 0x0b17, 0x154e: 0x0b1f, 0x154f: 0x1863, 0x1550: 0x0b37, 0x1551: 0x16a6,
-	0x1552: 0x16a6, 0x1553: 0x11d7, 0x1554: 0x0b47, 0x1555: 0x0b47, 0x1556: 0x05df, 0x1557: 0x16c9,
-	0x1558: 0x179b, 0x1559: 0x0b57, 0x155a: 0x0b5f, 0x155b: 0x05e3, 0x155c: 0x0b73, 0x155d: 0x0b83,
-	0x155e: 0x0b87, 0x155f: 0x0b8f, 0x1560: 0x0b9f, 0x1561: 0x05eb, 0x1562: 0x05e7, 0x1563: 0x0ba3,
-	0x1564: 0x16ab, 0x1565: 0x0ba7, 0x1566: 0x0bbb, 0x1567: 0x0bbf, 0x1568: 0x0bc3, 0x1569: 0x0bbf,
-	0x156a: 0x0bcf, 0x156b: 0x0bd3, 0x156c: 0x0be3, 0x156d: 0x0bdb, 0x156e: 0x0bdf, 0x156f: 0x0be7,
-	0x1570: 0x0beb, 0x1571: 0x0bef, 0x1572: 0x0bfb, 0x1573: 0x0bff, 0x1574: 0x0c17, 0x1575: 0x0c1f,
-	0x1576: 0x0c2f, 0x1577: 0x0c43, 0x1578: 0x16ba, 0x1579: 0x0c3f, 0x157a: 0x0c33, 0x157b: 0x0c4b,
-	0x157c: 0x0c53, 0x157d: 0x0c67, 0x157e: 0x16bf, 0x157f: 0x0c6f,
+	0x1540: 0x091f, 0x1541: 0x0927, 0x1542: 0x092b, 0x1543: 0x0933, 0x1544: 0x093b, 0x1545: 0x093f,
+	0x1546: 0x093f, 0x1547: 0x0947, 0x1548: 0x094f, 0x1549: 0x0953, 0x154a: 0x095f, 0x154b: 0x0983,
+	0x154c: 0x0967, 0x154d: 0x0987, 0x154e: 0x096b, 0x154f: 0x0973, 0x1550: 0x080b, 0x1551: 0x09cf,
+	0x1552: 0x0997, 0x1553: 0x099b, 0x1554: 0x099f, 0x1555: 0x0993, 0x1556: 0x09a7, 0x1557: 0x09a3,
+	0x1558: 0x09bb, 0x1559: 0x1674, 0x155a: 0x09d7, 0x155b: 0x09db, 0x155c: 0x09e3, 0x155d: 0x09ef,
+	0x155e: 0x09f7, 0x155f: 0x0a13, 0x1560: 0x1679, 0x1561: 0x167e, 0x1562: 0x0a1f, 0x1563: 0x0a23,
+	0x1564: 0x0a27, 0x1565: 0x0a1b, 0x1566: 0x0a2f, 0x1567: 0x05c7, 0x1568: 0x05cb, 0x1569: 0x0a37,
+	0x156a: 0x0a3f, 0x156b: 0x0a3f, 0x156c: 0x1683, 0x156d: 0x0a5b, 0x156e: 0x0a5f, 0x156f: 0x0a63,
+	0x1570: 0x0a6b, 0x1571: 0x1688, 0x1572: 0x0a73, 0x1573: 0x0a77, 0x1574: 0x0b4f, 0x1575: 0x0a7f,
+	0x1576: 0x05cf, 0x1577: 0x0a8b, 0x1578: 0x0a9b, 0x1579: 0x0aa7, 0x157a: 0x0aa3, 0x157b: 0x1692,
+	0x157c: 0x0aaf, 0x157d: 0x1697, 0x157e: 0x0abb, 0x157f: 0x0ab7,
 	// Block 0x56, offset 0x1580
-	0x1580: 0x0c63, 0x1581: 0x0c5b, 0x1582: 0x05ef, 0x1583: 0x0c77, 0x1584: 0x0c7f, 0x1585: 0x0c87,
-	0x1586: 0x0c7b, 0x1587: 0x05f3, 0x1588: 0x0c97, 0x1589: 0x0c9f, 0x158a: 0x16c4, 0x158b: 0x0ccb,
-	0x158c: 0x0cff, 0x158d: 0x0cdb, 0x158e: 0x05ff, 0x158f: 0x0ce7, 0x1590: 0x05fb, 0x1591: 0x05f7,
-	0x1592: 0x07c3, 0x1593: 0x07c7, 0x1594: 0x0d03, 0x1595: 0x0ceb, 0x1596: 0x11ab, 0x1597: 0x0663,
-	0x1598: 0x0d0f, 0x1599: 0x0d13, 0x159a: 0x0d17, 0x159b: 0x0d2b, 0x159c: 0x0d23, 0x159d: 0x16dd,
-	0x159e: 0x0603, 0x159f: 0x0d3f, 0x15a0: 0x0d33, 0x15a1: 0x0d4f, 0x15a2: 0x0d57, 0x15a3: 0x16e7,
-	0x15a4: 0x0d5b, 0x15a5: 0x0d47, 0x15a6: 0x0d63, 0x15a7: 0x0607, 0x15a8: 0x0d67, 0x15a9: 0x0d6b,
-	0x15aa: 0x0d6f, 0x15ab: 0x0d7b, 0x15ac: 0x16ec, 0x15ad: 0x0d83, 0x15ae: 0x060b, 0x15af: 0x0d8f,
-	0x15b0: 0x16f1, 0x15b1: 0x0d93, 0x15b2: 0x060f, 0x15b3: 0x0d9f, 0x15b4: 0x0dab, 0x15b5: 0x0db7,
-	0x15b6: 0x0dbb, 0x15b7: 0x16f6, 0x15b8: 0x168d, 0x15b9: 0x16fb, 0x15ba: 0x0ddb, 0x15bb: 0x1700,
-	0x15bc: 0x0de7, 0x15bd: 0x0def, 0x15be: 0x0ddf, 0x15bf: 0x0dfb,
+	0x1580: 0x0abf, 0x1581: 0x0acf, 0x1582: 0x0ad3, 0x1583: 0x05d3, 0x1584: 0x0ae3, 0x1585: 0x0aeb,
+	0x1586: 0x0aef, 0x1587: 0x0af3, 0x1588: 0x05d7, 0x1589: 0x169c, 0x158a: 0x05db, 0x158b: 0x0b0f,
+	0x158c: 0x0b13, 0x158d: 0x0b17, 0x158e: 0x0b1f, 0x158f: 0x1863, 0x1590: 0x0b37, 0x1591: 0x16a6,
+	0x1592: 0x16a6, 0x1593: 0x11d7, 0x1594: 0x0b47, 0x1595: 0x0b47, 0x1596: 0x05df, 0x1597: 0x16c9,
+	0x1598: 0x179b, 0x1599: 0x0b57, 0x159a: 0x0b5f, 0x159b: 0x05e3, 0x159c: 0x0b73, 0x159d: 0x0b83,
+	0x159e: 0x0b87, 0x159f: 0x0b8f, 0x15a0: 0x0b9f, 0x15a1: 0x05eb, 0x15a2: 0x05e7, 0x15a3: 0x0ba3,
+	0x15a4: 0x16ab, 0x15a5: 0x0ba7, 0x15a6: 0x0bbb, 0x15a7: 0x0bbf, 0x15a8: 0x0bc3, 0x15a9: 0x0bbf,
+	0x15aa: 0x0bcf, 0x15ab: 0x0bd3, 0x15ac: 0x0be3, 0x15ad: 0x0bdb, 0x15ae: 0x0bdf, 0x15af: 0x0be7,
+	0x15b0: 0x0beb, 0x15b1: 0x0bef, 0x15b2: 0x0bfb, 0x15b3: 0x0bff, 0x15b4: 0x0c17, 0x15b5: 0x0c1f,
+	0x15b6: 0x0c2f, 0x15b7: 0x0c43, 0x15b8: 0x16ba, 0x15b9: 0x0c3f, 0x15ba: 0x0c33, 0x15bb: 0x0c4b,
+	0x15bc: 0x0c53, 0x15bd: 0x0c67, 0x15be: 0x16bf, 0x15bf: 0x0c6f,
 	// Block 0x57, offset 0x15c0
-	0x15c0: 0x0e0b, 0x15c1: 0x0e1b, 0x15c2: 0x0e0f, 0x15c3: 0x0e13, 0x15c4: 0x0e1f, 0x15c5: 0x0e23,
-	0x15c6: 0x1705, 0x15c7: 0x0e07, 0x15c8: 0x0e3b, 0x15c9: 0x0e3f, 0x15ca: 0x0613, 0x15cb: 0x0e53,
-	0x15cc: 0x0e4f, 0x15cd: 0x170a, 0x15ce: 0x0e33, 0x15cf: 0x0e6f, 0x15d0: 0x170f, 0x15d1: 0x1714,
-	0x15d2: 0x0e73, 0x15d3: 0x0e87, 0x15d4: 0x0e83, 0x15d5: 0x0e7f, 0x15d6: 0x0617, 0x15d7: 0x0e8b,
-	0x15d8: 0x0e9b, 0x15d9: 0x0e97, 0x15da: 0x0ea3, 0x15db: 0x1651, 0x15dc: 0x0eb3, 0x15dd: 0x1719,
-	0x15de: 0x0ebf, 0x15df: 0x1723, 0x15e0: 0x0ed3, 0x15e1: 0x0edf, 0x15e2: 0x0ef3, 0x15e3: 0x1728,
-	0x15e4: 0x0f07, 0x15e5: 0x0f0b, 0x15e6: 0x172d, 0x15e7: 0x1732, 0x15e8: 0x0f27, 0x15e9: 0x0f37,
-	0x15ea: 0x061b, 0x15eb: 0x0f3b, 0x15ec: 0x061f, 0x15ed: 0x061f, 0x15ee: 0x0f53, 0x15ef: 0x0f57,
-	0x15f0: 0x0f5f, 0x15f1: 0x0f63, 0x15f2: 0x0f6f, 0x15f3: 0x0623, 0x15f4: 0x0f87, 0x15f5: 0x1737,
-	0x15f6: 0x0fa3, 0x15f7: 0x173c, 0x15f8: 0x0faf, 0x15f9: 0x16a1, 0x15fa: 0x0fbf, 0x15fb: 0x1741,
-	0x15fc: 0x1746, 0x15fd: 0x174b, 0x15fe: 0x0627, 0x15ff: 0x062b,
+	0x15c0: 0x0c63, 0x15c1: 0x0c5b, 0x15c2: 0x05ef, 0x15c3: 0x0c77, 0x15c4: 0x0c7f, 0x15c5: 0x0c87,
+	0x15c6: 0x0c7b, 0x15c7: 0x05f3, 0x15c8: 0x0c97, 0x15c9: 0x0c9f, 0x15ca: 0x16c4, 0x15cb: 0x0ccb,
+	0x15cc: 0x0cff, 0x15cd: 0x0cdb, 0x15ce: 0x05ff, 0x15cf: 0x0ce7, 0x15d0: 0x05fb, 0x15d1: 0x05f7,
+	0x15d2: 0x07c3, 0x15d3: 0x07c7, 0x15d4: 0x0d03, 0x15d5: 0x0ceb, 0x15d6: 0x11ab, 0x15d7: 0x0663,
+	0x15d8: 0x0d0f, 0x15d9: 0x0d13, 0x15da: 0x0d17, 0x15db: 0x0d2b, 0x15dc: 0x0d23, 0x15dd: 0x16dd,
+	0x15de: 0x0603, 0x15df: 0x0d3f, 0x15e0: 0x0d33, 0x15e1: 0x0d4f, 0x15e2: 0x0d57, 0x15e3: 0x16e7,
+	0x15e4: 0x0d5b, 0x15e5: 0x0d47, 0x15e6: 0x0d63, 0x15e7: 0x0607, 0x15e8: 0x0d67, 0x15e9: 0x0d6b,
+	0x15ea: 0x0d6f, 0x15eb: 0x0d7b, 0x15ec: 0x16ec, 0x15ed: 0x0d83, 0x15ee: 0x060b, 0x15ef: 0x0d8f,
+	0x15f0: 0x16f1, 0x15f1: 0x0d93, 0x15f2: 0x060f, 0x15f3: 0x0d9f, 0x15f4: 0x0dab, 0x15f5: 0x0db7,
+	0x15f6: 0x0dbb, 0x15f7: 0x16f6, 0x15f8: 0x168d, 0x15f9: 0x16fb, 0x15fa: 0x0ddb, 0x15fb: 0x1700,
+	0x15fc: 0x0de7, 0x15fd: 0x0def, 0x15fe: 0x0ddf, 0x15ff: 0x0dfb,
 	// Block 0x58, offset 0x1600
-	0x1600: 0x0ff7, 0x1601: 0x1755, 0x1602: 0x1750, 0x1603: 0x175a, 0x1604: 0x175f, 0x1605: 0x0fff,
-	0x1606: 0x1003, 0x1607: 0x1003, 0x1608: 0x100b, 0x1609: 0x0633, 0x160a: 0x100f, 0x160b: 0x0637,
-	0x160c: 0x063b, 0x160d: 0x1769, 0x160e: 0x1023, 0x160f: 0x102b, 0x1610: 0x1037, 0x1611: 0x063f,
-	0x1612: 0x176e, 0x1613: 0x105b, 0x1614: 0x1773, 0x1615: 0x1778, 0x1616: 0x107b, 0x1617: 0x1093,
-	0x1618: 0x0643, 0x1619: 0x109b, 0x161a: 0x109f, 0x161b: 0x10a3, 0x161c: 0x177d, 0x161d: 0x1782,
-	0x161e: 0x1782, 0x161f: 0x10bb, 0x1620: 0x0647, 0x1621: 0x1787, 0x1622: 0x10cf, 0x1623: 0x10d3,
-	0x1624: 0x064b, 0x1625: 0x178c, 0x1626: 0x10ef, 0x1627: 0x064f, 0x1628: 0x10ff, 0x1629: 0x10f7,
-	0x162a: 0x1107, 0x162b: 0x1796, 0x162c: 0x111f, 0x162d: 0x0653, 0x162e: 0x112b, 0x162f: 0x1133,
-	0x1630: 0x1143, 0x1631: 0x0657, 0x1632: 0x17a0, 0x1633: 0x17a5, 0x1634: 0x065b, 0x1635: 0x17aa,
-	0x1636: 0x115b, 0x1637: 0x17af, 0x1638: 0x1167, 0x1639: 0x1173, 0x163a: 0x117b, 0x163b: 0x17b4,
-	0x163c: 0x17b9, 0x163d: 0x118f, 0x163e: 0x17be, 0x163f: 0x1197,
+	0x1600: 0x0e0b, 0x1601: 0x0e1b, 0x1602: 0x0e0f, 0x1603: 0x0e13, 0x1604: 0x0e1f, 0x1605: 0x0e23,
+	0x1606: 0x1705, 0x1607: 0x0e07, 0x1608: 0x0e3b, 0x1609: 0x0e3f, 0x160a: 0x0613, 0x160b: 0x0e53,
+	0x160c: 0x0e4f, 0x160d: 0x170a, 0x160e: 0x0e33, 0x160f: 0x0e6f, 0x1610: 0x170f, 0x1611: 0x1714,
+	0x1612: 0x0e73, 0x1613: 0x0e87, 0x1614: 0x0e83, 0x1615: 0x0e7f, 0x1616: 0x0617, 0x1617: 0x0e8b,
+	0x1618: 0x0e9b, 0x1619: 0x0e97, 0x161a: 0x0ea3, 0x161b: 0x1651, 0x161c: 0x0eb3, 0x161d: 0x1719,
+	0x161e: 0x0ebf, 0x161f: 0x1723, 0x1620: 0x0ed3, 0x1621: 0x0edf, 0x1622: 0x0ef3, 0x1623: 0x1728,
+	0x1624: 0x0f07, 0x1625: 0x0f0b, 0x1626: 0x172d, 0x1627: 0x1732, 0x1628: 0x0f27, 0x1629: 0x0f37,
+	0x162a: 0x061b, 0x162b: 0x0f3b, 0x162c: 0x061f, 0x162d: 0x061f, 0x162e: 0x0f53, 0x162f: 0x0f57,
+	0x1630: 0x0f5f, 0x1631: 0x0f63, 0x1632: 0x0f6f, 0x1633: 0x0623, 0x1634: 0x0f87, 0x1635: 0x1737,
+	0x1636: 0x0fa3, 0x1637: 0x173c, 0x1638: 0x0faf, 0x1639: 0x16a1, 0x163a: 0x0fbf, 0x163b: 0x1741,
+	0x163c: 0x1746, 0x163d: 0x174b, 0x163e: 0x0627, 0x163f: 0x062b,
 	// Block 0x59, offset 0x1640
-	0x1640: 0x16ce, 0x1641: 0x065f, 0x1642: 0x11af, 0x1643: 0x11b3, 0x1644: 0x0667, 0x1645: 0x11b7,
-	0x1646: 0x0a33, 0x1647: 0x17c3, 0x1648: 0x17c8, 0x1649: 0x16d3, 0x164a: 0x16d8, 0x164b: 0x11d7,
-	0x164c: 0x11db, 0x164d: 0x13f3, 0x164e: 0x066b, 0x164f: 0x1207, 0x1650: 0x1203, 0x1651: 0x120b,
-	0x1652: 0x083f, 0x1653: 0x120f, 0x1654: 0x1213, 0x1655: 0x1217, 0x1656: 0x121f, 0x1657: 0x17cd,
-	0x1658: 0x121b, 0x1659: 0x1223, 0x165a: 0x1237, 0x165b: 0x123b, 0x165c: 0x1227, 0x165d: 0x123f,
-	0x165e: 0x1253, 0x165f: 0x1267, 0x1660: 0x1233, 0x1661: 0x1247, 0x1662: 0x124b, 0x1663: 0x124f,
-	0x1664: 0x17d2, 0x1665: 0x17dc, 0x1666: 0x17d7, 0x1667: 0x066f, 0x1668: 0x126f, 0x1669: 0x1273,
-	0x166a: 0x127b, 0x166b: 0x17f0, 0x166c: 0x127f, 0x166d: 0x17e1, 0x166e: 0x0673, 0x166f: 0x0677,
-	0x1670: 0x17e6, 0x1671: 0x17eb, 0x1672: 0x067b, 0x1673: 0x129f, 0x1674: 0x12a3, 0x1675: 0x12a7,
-	0x1676: 0x12ab, 0x1677: 0x12b7, 0x1678: 0x12b3, 0x1679: 0x12bf, 0x167a: 0x12bb, 0x167b: 0x12cb,
-	0x167c: 0x12c3, 0x167d: 0x12c7, 0x167e: 0x12cf, 0x167f: 0x067f,
+	0x1640: 0x0ff7, 0x1641: 0x1755, 0x1642: 0x1750, 0x1643: 0x175a, 0x1644: 0x175f, 0x1645: 0x0fff,
+	0x1646: 0x1003, 0x1647: 0x1003, 0x1648: 0x100b, 0x1649: 0x0633, 0x164a: 0x100f, 0x164b: 0x0637,
+	0x164c: 0x063b, 0x164d: 0x1769, 0x164e: 0x1023, 0x164f: 0x102b, 0x1650: 0x1037, 0x1651: 0x063f,
+	0x1652: 0x176e, 0x1653: 0x105b, 0x1654: 0x1773, 0x1655: 0x1778, 0x1656: 0x107b, 0x1657: 0x1093,
+	0x1658: 0x0643, 0x1659: 0x109b, 0x165a: 0x109f, 0x165b: 0x10a3, 0x165c: 0x177d, 0x165d: 0x1782,
+	0x165e: 0x1782, 0x165f: 0x10bb, 0x1660: 0x0647, 0x1661: 0x1787, 0x1662: 0x10cf, 0x1663: 0x10d3,
+	0x1664: 0x064b, 0x1665: 0x178c, 0x1666: 0x10ef, 0x1667: 0x064f, 0x1668: 0x10ff, 0x1669: 0x10f7,
+	0x166a: 0x1107, 0x166b: 0x1796, 0x166c: 0x111f, 0x166d: 0x0653, 0x166e: 0x112b, 0x166f: 0x1133,
+	0x1670: 0x1143, 0x1671: 0x0657, 0x1672: 0x17a0, 0x1673: 0x17a5, 0x1674: 0x065b, 0x1675: 0x17aa,
+	0x1676: 0x115b, 0x1677: 0x17af, 0x1678: 0x1167, 0x1679: 0x1173, 0x167a: 0x117b, 0x167b: 0x17b4,
+	0x167c: 0x17b9, 0x167d: 0x118f, 0x167e: 0x17be, 0x167f: 0x1197,
 	// Block 0x5a, offset 0x1680
-	0x1680: 0x12d7, 0x1681: 0x12db, 0x1682: 0x0683, 0x1683: 0x12eb, 0x1684: 0x12ef, 0x1685: 0x17f5,
-	0x1686: 0x12fb, 0x1687: 0x12ff, 0x1688: 0x0687, 0x1689: 0x130b, 0x168a: 0x05bb, 0x168b: 0x17fa,
-	0x168c: 0x17ff, 0x168d: 0x068b, 0x168e: 0x068f, 0x168f: 0x1337, 0x1690: 0x134f, 0x1691: 0x136b,
-	0x1692: 0x137b, 0x1693: 0x1804, 0x1694: 0x138f, 0x1695: 0x1393, 0x1696: 0x13ab, 0x1697: 0x13b7,
-	0x1698: 0x180e, 0x1699: 0x1660, 0x169a: 0x13c3, 0x169b: 0x13bf, 0x169c: 0x13cb, 0x169d: 0x1665,
-	0x169e: 0x13d7, 0x169f: 0x13e3, 0x16a0: 0x1813, 0x16a1: 0x1818, 0x16a2: 0x1423, 0x16a3: 0x142f,
-	0x16a4: 0x1437, 0x16a5: 0x181d, 0x16a6: 0x143b, 0x16a7: 0x1467, 0x16a8: 0x1473, 0x16a9: 0x1477,
-	0x16aa: 0x146f, 0x16ab: 0x1483, 0x16ac: 0x1487, 0x16ad: 0x1822, 0x16ae: 0x1493, 0x16af: 0x0693,
-	0x16b0: 0x149b, 0x16b1: 0x1827, 0x16b2: 0x0697, 0x16b3: 0x14d3, 0x16b4: 0x0ac3, 0x16b5: 0x14eb,
-	0x16b6: 0x182c, 0x16b7: 0x1836, 0x16b8: 0x069b, 0x16b9: 0x069f, 0x16ba: 0x1513, 0x16bb: 0x183b,
-	0x16bc: 0x06a3, 0x16bd: 0x1840, 0x16be: 0x152b, 0x16bf: 0x152b,
+	0x1680: 0x16ce, 0x1681: 0x065f, 0x1682: 0x11af, 0x1683: 0x11b3, 0x1684: 0x0667, 0x1685: 0x11b7,
+	0x1686: 0x0a33, 0x1687: 0x17c3, 0x1688: 0x17c8, 0x1689: 0x16d3, 0x168a: 0x16d8, 0x168b: 0x11d7,
+	0x168c: 0x11db, 0x168d: 0x13f3, 0x168e: 0x066b, 0x168f: 0x1207, 0x1690: 0x1203, 0x1691: 0x120b,
+	0x1692: 0x083f, 0x1693: 0x120f, 0x1694: 0x1213, 0x1695: 0x1217, 0x1696: 0x121f, 0x1697: 0x17cd,
+	0x1698: 0x121b, 0x1699: 0x1223, 0x169a: 0x1237, 0x169b: 0x123b, 0x169c: 0x1227, 0x169d: 0x123f,
+	0x169e: 0x1253, 0x169f: 0x1267, 0x16a0: 0x1233, 0x16a1: 0x1247, 0x16a2: 0x124b, 0x16a3: 0x124f,
+	0x16a4: 0x17d2, 0x16a5: 0x17dc, 0x16a6: 0x17d7, 0x16a7: 0x066f, 0x16a8: 0x126f, 0x16a9: 0x1273,
+	0x16aa: 0x127b, 0x16ab: 0x17f0, 0x16ac: 0x127f, 0x16ad: 0x17e1, 0x16ae: 0x0673, 0x16af: 0x0677,
+	0x16b0: 0x17e6, 0x16b1: 0x17eb, 0x16b2: 0x067b, 0x16b3: 0x129f, 0x16b4: 0x12a3, 0x16b5: 0x12a7,
+	0x16b6: 0x12ab, 0x16b7: 0x12b7, 0x16b8: 0x12b3, 0x16b9: 0x12bf, 0x16ba: 0x12bb, 0x16bb: 0x12cb,
+	0x16bc: 0x12c3, 0x16bd: 0x12c7, 0x16be: 0x12cf, 0x16bf: 0x067f,
 	// Block 0x5b, offset 0x16c0
-	0x16c0: 0x1533, 0x16c1: 0x1845, 0x16c2: 0x154b, 0x16c3: 0x06a7, 0x16c4: 0x155b, 0x16c5: 0x1567,
-	0x16c6: 0x156f, 0x16c7: 0x1577, 0x16c8: 0x06ab, 0x16c9: 0x184a, 0x16ca: 0x158b, 0x16cb: 0x15a7,
-	0x16cc: 0x15b3, 0x16cd: 0x06af, 0x16ce: 0x06b3, 0x16cf: 0x15b7, 0x16d0: 0x184f, 0x16d1: 0x06b7,
-	0x16d2: 0x1854, 0x16d3: 0x1859, 0x16d4: 0x185e, 0x16d5: 0x15db, 0x16d6: 0x06bb, 0x16d7: 0x15ef,
-	0x16d8: 0x15f7, 0x16d9: 0x15fb, 0x16da: 0x1603, 0x16db: 0x160b, 0x16dc: 0x1613, 0x16dd: 0x1868,
+	0x16c0: 0x12d7, 0x16c1: 0x12db, 0x16c2: 0x0683, 0x16c3: 0x12eb, 0x16c4: 0x12ef, 0x16c5: 0x17f5,
+	0x16c6: 0x12fb, 0x16c7: 0x12ff, 0x16c8: 0x0687, 0x16c9: 0x130b, 0x16ca: 0x05bb, 0x16cb: 0x17fa,
+	0x16cc: 0x17ff, 0x16cd: 0x068b, 0x16ce: 0x068f, 0x16cf: 0x1337, 0x16d0: 0x134f, 0x16d1: 0x136b,
+	0x16d2: 0x137b, 0x16d3: 0x1804, 0x16d4: 0x138f, 0x16d5: 0x1393, 0x16d6: 0x13ab, 0x16d7: 0x13b7,
+	0x16d8: 0x180e, 0x16d9: 0x1660, 0x16da: 0x13c3, 0x16db: 0x13bf, 0x16dc: 0x13cb, 0x16dd: 0x1665,
+	0x16de: 0x13d7, 0x16df: 0x13e3, 0x16e0: 0x1813, 0x16e1: 0x1818, 0x16e2: 0x1423, 0x16e3: 0x142f,
+	0x16e4: 0x1437, 0x16e5: 0x181d, 0x16e6: 0x143b, 0x16e7: 0x1467, 0x16e8: 0x1473, 0x16e9: 0x1477,
+	0x16ea: 0x146f, 0x16eb: 0x1483, 0x16ec: 0x1487, 0x16ed: 0x1822, 0x16ee: 0x1493, 0x16ef: 0x0693,
+	0x16f0: 0x149b, 0x16f1: 0x1827, 0x16f2: 0x0697, 0x16f3: 0x14d3, 0x16f4: 0x0ac3, 0x16f5: 0x14eb,
+	0x16f6: 0x182c, 0x16f7: 0x1836, 0x16f8: 0x069b, 0x16f9: 0x069f, 0x16fa: 0x1513, 0x16fb: 0x183b,
+	0x16fc: 0x06a3, 0x16fd: 0x1840, 0x16fe: 0x152b, 0x16ff: 0x152b,
+	// Block 0x5c, offset 0x1700
+	0x1700: 0x1533, 0x1701: 0x1845, 0x1702: 0x154b, 0x1703: 0x06a7, 0x1704: 0x155b, 0x1705: 0x1567,
+	0x1706: 0x156f, 0x1707: 0x1577, 0x1708: 0x06ab, 0x1709: 0x184a, 0x170a: 0x158b, 0x170b: 0x15a7,
+	0x170c: 0x15b3, 0x170d: 0x06af, 0x170e: 0x06b3, 0x170f: 0x15b7, 0x1710: 0x184f, 0x1711: 0x06b7,
+	0x1712: 0x1854, 0x1713: 0x1859, 0x1714: 0x185e, 0x1715: 0x15db, 0x1716: 0x06bb, 0x1717: 0x15ef,
+	0x1718: 0x15f7, 0x1719: 0x15fb, 0x171a: 0x1603, 0x171b: 0x160b, 0x171c: 0x1613, 0x171d: 0x1868,
 }
 
 // nfkcIndex: 22 blocks, 1408 entries, 1408 bytes
@@ -5550,36 +5572,36 @@
 	// Block 0x1, offset 0x40
 	// Block 0x2, offset 0x80
 	// Block 0x3, offset 0xc0
-	0xc2: 0x5a, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5b, 0xc7: 0x04,
-	0xc8: 0x05, 0xca: 0x5c, 0xcb: 0x5d, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09,
-	0xd0: 0x0a, 0xd1: 0x5e, 0xd2: 0x5f, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x60,
-	0xd8: 0x61, 0xd9: 0x0d, 0xdb: 0x62, 0xdc: 0x63, 0xdd: 0x64, 0xdf: 0x65,
+	0xc2: 0x5b, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5c, 0xc7: 0x04,
+	0xc8: 0x05, 0xca: 0x5d, 0xcb: 0x5e, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09,
+	0xd0: 0x0a, 0xd1: 0x5f, 0xd2: 0x60, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x61,
+	0xd8: 0x62, 0xd9: 0x0d, 0xdb: 0x63, 0xdc: 0x64, 0xdd: 0x65, 0xdf: 0x66,
 	0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
 	0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
 	0xf0: 0x13,
 	// Block 0x4, offset 0x100
-	0x120: 0x66, 0x121: 0x67, 0x123: 0x68, 0x124: 0x69, 0x125: 0x6a, 0x126: 0x6b, 0x127: 0x6c,
-	0x128: 0x6d, 0x129: 0x6e, 0x12a: 0x6f, 0x12b: 0x70, 0x12c: 0x6b, 0x12d: 0x71, 0x12e: 0x72, 0x12f: 0x73,
-	0x131: 0x74, 0x132: 0x75, 0x133: 0x76, 0x134: 0x77, 0x135: 0x78, 0x137: 0x79,
-	0x138: 0x7a, 0x139: 0x7b, 0x13a: 0x7c, 0x13b: 0x7d, 0x13c: 0x7e, 0x13d: 0x7f, 0x13e: 0x80, 0x13f: 0x81,
+	0x120: 0x67, 0x121: 0x68, 0x123: 0x69, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d,
+	0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74,
+	0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a,
+	0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82,
 	// Block 0x5, offset 0x140
-	0x140: 0x82, 0x142: 0x83, 0x143: 0x84, 0x144: 0x85, 0x145: 0x86, 0x146: 0x87, 0x147: 0x88,
-	0x14d: 0x89,
-	0x15c: 0x8a, 0x15f: 0x8b,
-	0x162: 0x8c, 0x164: 0x8d,
-	0x168: 0x8e, 0x169: 0x8f, 0x16a: 0x90, 0x16c: 0x0e, 0x16d: 0x91, 0x16e: 0x92, 0x16f: 0x93,
-	0x170: 0x94, 0x173: 0x95, 0x174: 0x96, 0x175: 0x0f, 0x176: 0x10, 0x177: 0x97,
-	0x178: 0x11, 0x179: 0x12, 0x17a: 0x13, 0x17b: 0x14, 0x17c: 0x15, 0x17d: 0x16, 0x17e: 0x17, 0x17f: 0x18,
+	0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89,
+	0x14d: 0x8a,
+	0x15c: 0x8b, 0x15f: 0x8c,
+	0x162: 0x8d, 0x164: 0x8e,
+	0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16c: 0x0e, 0x16d: 0x92, 0x16e: 0x93, 0x16f: 0x94,
+	0x170: 0x95, 0x173: 0x96, 0x174: 0x97, 0x175: 0x0f, 0x176: 0x10, 0x177: 0x11,
+	0x178: 0x12, 0x179: 0x13, 0x17a: 0x14, 0x17b: 0x15, 0x17c: 0x16, 0x17d: 0x17, 0x17e: 0x18, 0x17f: 0x19,
 	// Block 0x6, offset 0x180
-	0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x19, 0x185: 0x1a, 0x186: 0x9c, 0x187: 0x9d,
-	0x188: 0x9e, 0x189: 0x1b, 0x18a: 0x1c, 0x18b: 0x9f, 0x18c: 0xa0,
-	0x191: 0x1d, 0x192: 0x1e, 0x193: 0xa1,
+	0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x1a, 0x185: 0x1b, 0x186: 0x9c, 0x187: 0x9d,
+	0x188: 0x9e, 0x189: 0x1c, 0x18a: 0x1d, 0x18b: 0x9f, 0x18c: 0xa0,
+	0x191: 0x1e, 0x192: 0x1f, 0x193: 0xa1,
 	0x1a8: 0xa2, 0x1a9: 0xa3, 0x1ab: 0xa4,
 	0x1b1: 0xa5, 0x1b3: 0xa6, 0x1b5: 0xa7, 0x1b7: 0xa8,
-	0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x1f, 0x1bd: 0x20, 0x1be: 0x21, 0x1bf: 0xab,
+	0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x20, 0x1bd: 0x21, 0x1be: 0x22, 0x1bf: 0xab,
 	// Block 0x7, offset 0x1c0
-	0x1c0: 0xac, 0x1c1: 0x22, 0x1c2: 0x23, 0x1c3: 0x24, 0x1c4: 0xad, 0x1c5: 0x25, 0x1c6: 0x26,
-	0x1c8: 0x27, 0x1c9: 0x28, 0x1ca: 0x29, 0x1cb: 0x2a, 0x1cc: 0x2b, 0x1cd: 0x2c, 0x1ce: 0x2d, 0x1cf: 0x2e,
+	0x1c0: 0xac, 0x1c1: 0x23, 0x1c2: 0x24, 0x1c3: 0x25, 0x1c4: 0xad, 0x1c5: 0x26, 0x1c6: 0x27,
+	0x1c8: 0x28, 0x1c9: 0x29, 0x1ca: 0x2a, 0x1cb: 0x2b, 0x1cc: 0x2c, 0x1cd: 0x2d, 0x1ce: 0x2e, 0x1cf: 0x2f,
 	// Block 0x8, offset 0x200
 	0x219: 0xae, 0x21a: 0xaf, 0x21b: 0xb0, 0x21d: 0xb1, 0x21f: 0xb2,
 	0x220: 0xb3, 0x223: 0xb4, 0x224: 0xb5, 0x225: 0xb6, 0x226: 0xb7, 0x227: 0xb8,
@@ -5610,50 +5632,51 @@
 	0x2d0: 0xc3, 0x2d1: 0xbd, 0x2d2: 0xbe, 0x2d3: 0xbf, 0x2d4: 0xc0, 0x2d5: 0xc1, 0x2d6: 0xc2, 0x2d7: 0xc3,
 	0x2d8: 0xbd, 0x2d9: 0xbe, 0x2da: 0xbf, 0x2db: 0xc0, 0x2dc: 0xc1, 0x2dd: 0xc2, 0x2de: 0xc4,
 	// Block 0xc, offset 0x300
-	0x324: 0x2f, 0x325: 0x30, 0x326: 0x31, 0x327: 0x32,
-	0x328: 0x33, 0x329: 0x34, 0x32a: 0x35, 0x32b: 0x36, 0x32c: 0x37, 0x32d: 0x38, 0x32e: 0x39, 0x32f: 0x3a,
-	0x330: 0x3b, 0x331: 0x3c, 0x332: 0x3d, 0x333: 0x3e, 0x334: 0x3f, 0x335: 0x40, 0x336: 0x41, 0x337: 0x42,
-	0x338: 0x43, 0x339: 0x44, 0x33a: 0x45, 0x33b: 0x46, 0x33c: 0xc5, 0x33d: 0x47, 0x33e: 0x48, 0x33f: 0x49,
+	0x324: 0x30, 0x325: 0x31, 0x326: 0x32, 0x327: 0x33,
+	0x328: 0x34, 0x329: 0x35, 0x32a: 0x36, 0x32b: 0x37, 0x32c: 0x38, 0x32d: 0x39, 0x32e: 0x3a, 0x32f: 0x3b,
+	0x330: 0x3c, 0x331: 0x3d, 0x332: 0x3e, 0x333: 0x3f, 0x334: 0x40, 0x335: 0x41, 0x336: 0x42, 0x337: 0x43,
+	0x338: 0x44, 0x339: 0x45, 0x33a: 0x46, 0x33b: 0x47, 0x33c: 0xc5, 0x33d: 0x48, 0x33e: 0x49, 0x33f: 0x4a,
 	// Block 0xd, offset 0x340
 	0x347: 0xc6,
 	0x34b: 0xc7, 0x34d: 0xc8,
 	0x368: 0xc9, 0x36b: 0xca,
 	// Block 0xe, offset 0x380
 	0x381: 0xcb, 0x382: 0xcc, 0x384: 0xcd, 0x385: 0xb7, 0x387: 0xce,
-	0x388: 0xcf, 0x38b: 0xd0, 0x38c: 0x6b, 0x38d: 0xd1,
+	0x388: 0xcf, 0x38b: 0xd0, 0x38c: 0x6c, 0x38d: 0xd1,
 	0x391: 0xd2, 0x392: 0xd3, 0x393: 0xd4, 0x396: 0xd5, 0x397: 0xd6,
 	0x398: 0xd7, 0x39a: 0xd8, 0x39c: 0xd9,
-	0x3b0: 0xd7,
+	0x3a8: 0xda, 0x3a9: 0xdb, 0x3aa: 0xdc,
+	0x3b0: 0xd7, 0x3b5: 0xdd,
 	// Block 0xf, offset 0x3c0
-	0x3eb: 0xda, 0x3ec: 0xdb,
+	0x3eb: 0xde, 0x3ec: 0xdf,
 	// Block 0x10, offset 0x400
-	0x432: 0xdc,
+	0x432: 0xe0,
 	// Block 0x11, offset 0x440
-	0x445: 0xdd, 0x446: 0xde, 0x447: 0xdf,
-	0x449: 0xe0,
-	0x450: 0xe1, 0x451: 0xe2, 0x452: 0xe3, 0x453: 0xe4, 0x454: 0xe5, 0x455: 0xe6, 0x456: 0xe7, 0x457: 0xe8,
-	0x458: 0xe9, 0x459: 0xea, 0x45a: 0x4a, 0x45b: 0xeb, 0x45c: 0xec, 0x45d: 0xed, 0x45e: 0xee, 0x45f: 0x4b,
+	0x445: 0xe1, 0x446: 0xe2, 0x447: 0xe3,
+	0x449: 0xe4,
+	0x450: 0xe5, 0x451: 0xe6, 0x452: 0xe7, 0x453: 0xe8, 0x454: 0xe9, 0x455: 0xea, 0x456: 0xeb, 0x457: 0xec,
+	0x458: 0xed, 0x459: 0xee, 0x45a: 0x4b, 0x45b: 0xef, 0x45c: 0xf0, 0x45d: 0xf1, 0x45e: 0xf2, 0x45f: 0x4c,
 	// Block 0x12, offset 0x480
-	0x480: 0xef,
-	0x4a3: 0xf0, 0x4a5: 0xf1,
-	0x4b8: 0x4c, 0x4b9: 0x4d, 0x4ba: 0x4e,
+	0x480: 0xf3,
+	0x4a3: 0xf4, 0x4a5: 0xf5,
+	0x4b8: 0x4d, 0x4b9: 0x4e, 0x4ba: 0x4f,
 	// Block 0x13, offset 0x4c0
-	0x4c4: 0x4f, 0x4c5: 0xf2, 0x4c6: 0xf3,
-	0x4c8: 0x50, 0x4c9: 0xf4,
+	0x4c4: 0x50, 0x4c5: 0xf6, 0x4c6: 0xf7,
+	0x4c8: 0x51, 0x4c9: 0xf8,
 	// Block 0x14, offset 0x500
-	0x520: 0x51, 0x521: 0x52, 0x522: 0x53, 0x523: 0x54, 0x524: 0x55, 0x525: 0x56, 0x526: 0x57, 0x527: 0x58,
-	0x528: 0x59,
+	0x520: 0x52, 0x521: 0x53, 0x522: 0x54, 0x523: 0x55, 0x524: 0x56, 0x525: 0x57, 0x526: 0x58, 0x527: 0x59,
+	0x528: 0x5a,
 	// Block 0x15, offset 0x540
 	0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
 	0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
 	0x56f: 0x12,
 }
 
-// nfkcSparseOffset: 155 entries, 310 bytes
-var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x6f, 0x74, 0x76, 0x87, 0x8f, 0x96, 0x99, 0xa0, 0xa4, 0xa8, 0xaa, 0xac, 0xb5, 0xb9, 0xc0, 0xc5, 0xc8, 0xd2, 0xd4, 0xdb, 0xe3, 0xe7, 0xe9, 0xec, 0xf0, 0xf6, 0x107, 0x113, 0x115, 0x11b, 0x11d, 0x11f, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12c, 0x12f, 0x131, 0x134, 0x137, 0x13b, 0x140, 0x149, 0x14b, 0x14e, 0x150, 0x15b, 0x166, 0x176, 0x184, 0x192, 0x1a2, 0x1b0, 0x1b7, 0x1bd, 0x1cc, 0x1d0, 0x1d2, 0x1d6, 0x1d8, 0x1db, 0x1dd, 0x1e0, 0x1e2, 0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1f7, 0x201, 0x20b, 0x20e, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21d, 0x21f, 0x221, 0x223, 0x225, 0x22b, 0x22e, 0x232, 0x234, 0x23b, 0x241, 0x247, 0x24f, 0x255, 0x25b, 0x261, 0x265, 0x267, 0x269, 0x26b, 0x26d, 0x273, 0x276, 0x279, 0x281, 0x288, 0x28b, 0x28e, 0x290, 0x298, 0x29b, 0x2a2, 0x2a5, 0x2ab, 0x2ad, 0x2af, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2c7, 0x2d1, 0x2d3, 0x2d5, 0x2d9, 0x2de, 0x2ea, 0x2ef, 0x2f8, 0x2fe, 0x303, 0x307, 0x30c, 0x310, 0x320, 0x32e, 0x33c, 0x34a, 0x350, 0x352, 0x355, 0x35f, 0x361}
+// nfkcSparseOffset: 158 entries, 316 bytes
+var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x6f, 0x74, 0x76, 0x87, 0x8f, 0x96, 0x99, 0xa0, 0xa4, 0xa8, 0xaa, 0xac, 0xb5, 0xb9, 0xc0, 0xc5, 0xc8, 0xd2, 0xd5, 0xdc, 0xe4, 0xe8, 0xea, 0xed, 0xf1, 0xf7, 0x108, 0x114, 0x116, 0x11c, 0x11e, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12a, 0x12d, 0x130, 0x132, 0x135, 0x138, 0x13c, 0x141, 0x14a, 0x14c, 0x14f, 0x151, 0x15c, 0x167, 0x175, 0x183, 0x193, 0x1a1, 0x1a8, 0x1ae, 0x1bd, 0x1c1, 0x1c3, 0x1c7, 0x1c9, 0x1cc, 0x1ce, 0x1d1, 0x1d3, 0x1d6, 0x1d8, 0x1da, 0x1dc, 0x1e8, 0x1f2, 0x1fc, 0x1ff, 0x203, 0x205, 0x207, 0x209, 0x20b, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x21c, 0x21f, 0x223, 0x225, 0x22c, 0x232, 0x238, 0x240, 0x246, 0x24c, 0x252, 0x256, 0x258, 0x25a, 0x25c, 0x25e, 0x264, 0x267, 0x26a, 0x272, 0x279, 0x27c, 0x27f, 0x281, 0x289, 0x28c, 0x293, 0x296, 0x29c, 0x29e, 0x2a0, 0x2a3, 0x2a5, 0x2a7, 0x2a9, 0x2ab, 0x2ae, 0x2b0, 0x2b2, 0x2b4, 0x2c1, 0x2cb, 0x2cd, 0x2cf, 0x2d3, 0x2d8, 0x2e4, 0x2e9, 0x2f2, 0x2f8, 0x2fd, 0x301, 0x306, 0x30a, 0x31a, 0x328, 0x336, 0x344, 0x34a, 0x34c, 0x34f, 0x359, 0x35b}
 
-// nfkcSparseValues: 875 entries, 3500 bytes
-var nfkcSparseValues = [875]valueRange{
+// nfkcSparseValues: 869 entries, 3476 bytes
+var nfkcSparseValues = [869]valueRange{
 	// Block 0x0, offset 0x0
 	{value: 0x0002, lo: 0x0d},
 	{value: 0x0001, lo: 0xa0, hi: 0xa0},
@@ -5894,9 +5917,10 @@
 	{value: 0x8104, lo: 0x8d, hi: 0x8d},
 	{value: 0x9900, lo: 0x95, hi: 0x96},
 	// Block 0x1d, offset 0xd2
-	{value: 0x0000, lo: 0x01},
+	{value: 0x0000, lo: 0x02},
+	{value: 0x8104, lo: 0xbb, hi: 0xbc},
 	{value: 0x9900, lo: 0xbe, hi: 0xbe},
-	// Block 0x1e, offset 0xd4
+	// Block 0x1e, offset 0xd5
 	{value: 0x0000, lo: 0x06},
 	{value: 0xa000, lo: 0x86, hi: 0x87},
 	{value: 0x2cfe, lo: 0x8a, hi: 0x8a},
@@ -5904,7 +5928,7 @@
 	{value: 0x2d06, lo: 0x8c, hi: 0x8c},
 	{value: 0x8104, lo: 0x8d, hi: 0x8d},
 	{value: 0x9900, lo: 0x97, hi: 0x97},
-	// Block 0x1f, offset 0xdb
+	// Block 0x1f, offset 0xdc
 	{value: 0x6bea, lo: 0x07},
 	{value: 0x9904, lo: 0x8a, hi: 0x8a},
 	{value: 0x9900, lo: 0x8f, hi: 0x8f},
@@ -5913,31 +5937,31 @@
 	{value: 0x2f58, lo: 0x9c, hi: 0x9c},
 	{value: 0x2de3, lo: 0x9d, hi: 0x9d},
 	{value: 0x2d16, lo: 0x9e, hi: 0x9f},
-	// Block 0x20, offset 0xe3
+	// Block 0x20, offset 0xe4
 	{value: 0x0000, lo: 0x03},
 	{value: 0x2621, lo: 0xb3, hi: 0xb3},
 	{value: 0x8122, lo: 0xb8, hi: 0xb9},
 	{value: 0x8104, lo: 0xba, hi: 0xba},
-	// Block 0x21, offset 0xe7
+	// Block 0x21, offset 0xe8
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8123, lo: 0x88, hi: 0x8b},
-	// Block 0x22, offset 0xe9
+	// Block 0x22, offset 0xea
 	{value: 0x0000, lo: 0x02},
 	{value: 0x2636, lo: 0xb3, hi: 0xb3},
 	{value: 0x8124, lo: 0xb8, hi: 0xb9},
-	// Block 0x23, offset 0xec
+	// Block 0x23, offset 0xed
 	{value: 0x0000, lo: 0x03},
 	{value: 0x8125, lo: 0x88, hi: 0x8b},
 	{value: 0x2628, lo: 0x9c, hi: 0x9c},
 	{value: 0x262f, lo: 0x9d, hi: 0x9d},
-	// Block 0x24, offset 0xf0
+	// Block 0x24, offset 0xf1
 	{value: 0x0000, lo: 0x05},
 	{value: 0x030b, lo: 0x8c, hi: 0x8c},
 	{value: 0x812d, lo: 0x98, hi: 0x99},
 	{value: 0x812d, lo: 0xb5, hi: 0xb5},
 	{value: 0x812d, lo: 0xb7, hi: 0xb7},
 	{value: 0x812b, lo: 0xb9, hi: 0xb9},
-	// Block 0x25, offset 0xf6
+	// Block 0x25, offset 0xf7
 	{value: 0x0000, lo: 0x10},
 	{value: 0x2644, lo: 0x83, hi: 0x83},
 	{value: 0x264b, lo: 0x8d, hi: 0x8d},
@@ -5955,7 +5979,7 @@
 	{value: 0x45bc, lo: 0xb8, hi: 0xb8},
 	{value: 0x45ff, lo: 0xb9, hi: 0xb9},
 	{value: 0x8127, lo: 0xba, hi: 0xbd},
-	// Block 0x26, offset 0x107
+	// Block 0x26, offset 0x108
 	{value: 0x0000, lo: 0x0b},
 	{value: 0x8127, lo: 0x80, hi: 0x80},
 	{value: 0x4a96, lo: 0x81, hi: 0x81},
@@ -5968,68 +5992,68 @@
 	{value: 0x2683, lo: 0xa7, hi: 0xa7},
 	{value: 0x268a, lo: 0xac, hi: 0xac},
 	{value: 0x2667, lo: 0xb9, hi: 0xb9},
-	// Block 0x27, offset 0x113
+	// Block 0x27, offset 0x114
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x86, hi: 0x86},
-	// Block 0x28, offset 0x115
+	// Block 0x28, offset 0x116
 	{value: 0x0000, lo: 0x05},
 	{value: 0xa000, lo: 0xa5, hi: 0xa5},
 	{value: 0x2d1e, lo: 0xa6, hi: 0xa6},
 	{value: 0x9900, lo: 0xae, hi: 0xae},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
 	{value: 0x8104, lo: 0xb9, hi: 0xba},
-	// Block 0x29, offset 0x11b
+	// Block 0x29, offset 0x11c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x8d, hi: 0x8d},
-	// Block 0x2a, offset 0x11d
+	// Block 0x2a, offset 0x11e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x030f, lo: 0xbc, hi: 0xbc},
-	// Block 0x2b, offset 0x11f
+	// Block 0x2b, offset 0x120
 	{value: 0x0000, lo: 0x01},
 	{value: 0xa000, lo: 0x80, hi: 0x92},
-	// Block 0x2c, offset 0x121
+	// Block 0x2c, offset 0x122
 	{value: 0x0000, lo: 0x01},
 	{value: 0xb900, lo: 0xa1, hi: 0xb5},
-	// Block 0x2d, offset 0x123
+	// Block 0x2d, offset 0x124
 	{value: 0x0000, lo: 0x01},
 	{value: 0x9900, lo: 0xa8, hi: 0xbf},
-	// Block 0x2e, offset 0x125
+	// Block 0x2e, offset 0x126
 	{value: 0x0000, lo: 0x01},
 	{value: 0x9900, lo: 0x80, hi: 0x82},
-	// Block 0x2f, offset 0x127
+	// Block 0x2f, offset 0x128
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0x9d, hi: 0x9f},
-	// Block 0x30, offset 0x129
+	// Block 0x30, offset 0x12a
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x94, hi: 0x94},
 	{value: 0x8104, lo: 0xb4, hi: 0xb4},
-	// Block 0x31, offset 0x12c
+	// Block 0x31, offset 0x12d
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x92, hi: 0x92},
 	{value: 0x8132, lo: 0x9d, hi: 0x9d},
-	// Block 0x32, offset 0x12f
+	// Block 0x32, offset 0x130
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8131, lo: 0xa9, hi: 0xa9},
-	// Block 0x33, offset 0x131
+	// Block 0x33, offset 0x132
 	{value: 0x0004, lo: 0x02},
 	{value: 0x812e, lo: 0xb9, hi: 0xba},
 	{value: 0x812d, lo: 0xbb, hi: 0xbb},
-	// Block 0x34, offset 0x134
+	// Block 0x34, offset 0x135
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x97, hi: 0x97},
 	{value: 0x812d, lo: 0x98, hi: 0x98},
-	// Block 0x35, offset 0x137
+	// Block 0x35, offset 0x138
 	{value: 0x0000, lo: 0x03},
 	{value: 0x8104, lo: 0xa0, hi: 0xa0},
 	{value: 0x8132, lo: 0xb5, hi: 0xbc},
 	{value: 0x812d, lo: 0xbf, hi: 0xbf},
-	// Block 0x36, offset 0x13b
+	// Block 0x36, offset 0x13c
 	{value: 0x0000, lo: 0x04},
 	{value: 0x8132, lo: 0xb0, hi: 0xb4},
 	{value: 0x812d, lo: 0xb5, hi: 0xba},
 	{value: 0x8132, lo: 0xbb, hi: 0xbc},
 	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	// Block 0x37, offset 0x140
+	// Block 0x37, offset 0x141
 	{value: 0x0000, lo: 0x08},
 	{value: 0x2d66, lo: 0x80, hi: 0x80},
 	{value: 0x2d6e, lo: 0x81, hi: 0x81},
@@ -6039,17 +6063,17 @@
 	{value: 0x8132, lo: 0xab, hi: 0xab},
 	{value: 0x812d, lo: 0xac, hi: 0xac},
 	{value: 0x8132, lo: 0xad, hi: 0xb3},
-	// Block 0x38, offset 0x149
+	// Block 0x38, offset 0x14a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xaa, hi: 0xab},
-	// Block 0x39, offset 0x14b
+	// Block 0x39, offset 0x14c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8102, lo: 0xa6, hi: 0xa6},
 	{value: 0x8104, lo: 0xb2, hi: 0xb3},
-	// Block 0x3a, offset 0x14e
+	// Block 0x3a, offset 0x14f
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
-	// Block 0x3b, offset 0x150
+	// Block 0x3b, offset 0x151
 	{value: 0x0000, lo: 0x0a},
 	{value: 0x8132, lo: 0x90, hi: 0x92},
 	{value: 0x8101, lo: 0x94, hi: 0x94},
@@ -6061,7 +6085,7 @@
 	{value: 0x812d, lo: 0xad, hi: 0xad},
 	{value: 0x8132, lo: 0xb4, hi: 0xb4},
 	{value: 0x8132, lo: 0xb8, hi: 0xb9},
-	// Block 0x3c, offset 0x15b
+	// Block 0x3c, offset 0x15c
 	{value: 0x0002, lo: 0x0a},
 	{value: 0x0043, lo: 0xac, hi: 0xac},
 	{value: 0x00d1, lo: 0xad, hi: 0xad},
@@ -6073,24 +6097,7 @@
 	{value: 0x00ef, lo: 0xbd, hi: 0xbd},
 	{value: 0x0061, lo: 0xbe, hi: 0xbe},
 	{value: 0x0065, lo: 0xbf, hi: 0xbf},
-	// Block 0x3d, offset 0x166
-	{value: 0x0000, lo: 0x0f},
-	{value: 0x8132, lo: 0x80, hi: 0x81},
-	{value: 0x812d, lo: 0x82, hi: 0x82},
-	{value: 0x8132, lo: 0x83, hi: 0x89},
-	{value: 0x812d, lo: 0x8a, hi: 0x8a},
-	{value: 0x8132, lo: 0x8b, hi: 0x8c},
-	{value: 0x8135, lo: 0x8d, hi: 0x8d},
-	{value: 0x812a, lo: 0x8e, hi: 0x8e},
-	{value: 0x812d, lo: 0x8f, hi: 0x8f},
-	{value: 0x8129, lo: 0x90, hi: 0x90},
-	{value: 0x8132, lo: 0x91, hi: 0xb5},
-	{value: 0x8132, lo: 0xbb, hi: 0xbb},
-	{value: 0x8134, lo: 0xbc, hi: 0xbc},
-	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	{value: 0x8132, lo: 0xbe, hi: 0xbe},
-	{value: 0x812d, lo: 0xbf, hi: 0xbf},
-	// Block 0x3e, offset 0x176
+	// Block 0x3d, offset 0x167
 	{value: 0x0000, lo: 0x0d},
 	{value: 0x0001, lo: 0x80, hi: 0x8a},
 	{value: 0x043b, lo: 0x91, hi: 0x91},
@@ -6105,7 +6112,7 @@
 	{value: 0x2808, lo: 0xb7, hi: 0xb7},
 	{value: 0x186d, lo: 0xbc, hi: 0xbc},
 	{value: 0x4269, lo: 0xbe, hi: 0xbe},
-	// Block 0x3f, offset 0x184
+	// Block 0x3e, offset 0x175
 	{value: 0x0002, lo: 0x0d},
 	{value: 0x1933, lo: 0x87, hi: 0x87},
 	{value: 0x1930, lo: 0x88, hi: 0x88},
@@ -6120,7 +6127,7 @@
 	{value: 0x003b, lo: 0xbc, hi: 0xbc},
 	{value: 0x0011, lo: 0xbd, hi: 0xbe},
 	{value: 0x009d, lo: 0xbf, hi: 0xbf},
-	// Block 0x40, offset 0x192
+	// Block 0x3f, offset 0x183
 	{value: 0x0002, lo: 0x0f},
 	{value: 0x0021, lo: 0x80, hi: 0x89},
 	{value: 0x0017, lo: 0x8a, hi: 0x8a},
@@ -6137,7 +6144,7 @@
 	{value: 0x00a1, lo: 0x9a, hi: 0x9a},
 	{value: 0x00a7, lo: 0x9b, hi: 0x9c},
 	{value: 0x1999, lo: 0xa8, hi: 0xa8},
-	// Block 0x41, offset 0x1a2
+	// Block 0x40, offset 0x193
 	{value: 0x0000, lo: 0x0d},
 	{value: 0x8132, lo: 0x90, hi: 0x91},
 	{value: 0x8101, lo: 0x92, hi: 0x93},
@@ -6152,7 +6159,7 @@
 	{value: 0x8101, lo: 0xaa, hi: 0xab},
 	{value: 0x812d, lo: 0xac, hi: 0xaf},
 	{value: 0x8132, lo: 0xb0, hi: 0xb0},
-	// Block 0x42, offset 0x1b0
+	// Block 0x41, offset 0x1a1
 	{value: 0x0007, lo: 0x06},
 	{value: 0x2180, lo: 0x89, hi: 0x89},
 	{value: 0xa000, lo: 0x90, hi: 0x90},
@@ -6160,14 +6167,14 @@
 	{value: 0xa000, lo: 0x94, hi: 0x94},
 	{value: 0x3bb9, lo: 0x9a, hi: 0x9b},
 	{value: 0x3bc7, lo: 0xae, hi: 0xae},
-	// Block 0x43, offset 0x1b7
+	// Block 0x42, offset 0x1a8
 	{value: 0x000e, lo: 0x05},
 	{value: 0x3bce, lo: 0x8d, hi: 0x8e},
 	{value: 0x3bd5, lo: 0x8f, hi: 0x8f},
 	{value: 0xa000, lo: 0x90, hi: 0x90},
 	{value: 0xa000, lo: 0x92, hi: 0x92},
 	{value: 0xa000, lo: 0x94, hi: 0x94},
-	// Block 0x44, offset 0x1bd
+	// Block 0x43, offset 0x1ae
 	{value: 0x0173, lo: 0x0e},
 	{value: 0xa000, lo: 0x83, hi: 0x83},
 	{value: 0x3be3, lo: 0x84, hi: 0x84},
@@ -6183,50 +6190,50 @@
 	{value: 0x26a6, lo: 0xaf, hi: 0xaf},
 	{value: 0x281c, lo: 0xb0, hi: 0xb0},
 	{value: 0xa000, lo: 0xbc, hi: 0xbc},
-	// Block 0x45, offset 0x1cc
+	// Block 0x44, offset 0x1bd
 	{value: 0x0007, lo: 0x03},
 	{value: 0x3c68, lo: 0xa0, hi: 0xa1},
 	{value: 0x3c92, lo: 0xa2, hi: 0xa3},
 	{value: 0x3cbc, lo: 0xaa, hi: 0xad},
-	// Block 0x46, offset 0x1d0
+	// Block 0x45, offset 0x1c1
 	{value: 0x0004, lo: 0x01},
 	{value: 0x048b, lo: 0xa9, hi: 0xaa},
-	// Block 0x47, offset 0x1d2
+	// Block 0x46, offset 0x1c3
 	{value: 0x0002, lo: 0x03},
 	{value: 0x0057, lo: 0x80, hi: 0x8f},
 	{value: 0x0083, lo: 0x90, hi: 0xa9},
 	{value: 0x0021, lo: 0xaa, hi: 0xaa},
-	// Block 0x48, offset 0x1d6
+	// Block 0x47, offset 0x1c7
 	{value: 0x0000, lo: 0x01},
 	{value: 0x299b, lo: 0x8c, hi: 0x8c},
-	// Block 0x49, offset 0x1d8
+	// Block 0x48, offset 0x1c9
 	{value: 0x0263, lo: 0x02},
 	{value: 0x1b8c, lo: 0xb4, hi: 0xb4},
 	{value: 0x192d, lo: 0xb5, hi: 0xb6},
-	// Block 0x4a, offset 0x1db
+	// Block 0x49, offset 0x1cc
 	{value: 0x0000, lo: 0x01},
 	{value: 0x44dd, lo: 0x9c, hi: 0x9c},
-	// Block 0x4b, offset 0x1dd
+	// Block 0x4a, offset 0x1ce
 	{value: 0x0000, lo: 0x02},
 	{value: 0x0095, lo: 0xbc, hi: 0xbc},
 	{value: 0x006d, lo: 0xbd, hi: 0xbd},
-	// Block 0x4c, offset 0x1e0
+	// Block 0x4b, offset 0x1d1
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xaf, hi: 0xb1},
-	// Block 0x4d, offset 0x1e2
+	// Block 0x4c, offset 0x1d3
 	{value: 0x0000, lo: 0x02},
 	{value: 0x047f, lo: 0xaf, hi: 0xaf},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x4e, offset 0x1e5
+	// Block 0x4d, offset 0x1d6
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xa0, hi: 0xbf},
-	// Block 0x4f, offset 0x1e7
+	// Block 0x4e, offset 0x1d8
 	{value: 0x0000, lo: 0x01},
 	{value: 0x0dc3, lo: 0x9f, hi: 0x9f},
-	// Block 0x50, offset 0x1e9
+	// Block 0x4f, offset 0x1da
 	{value: 0x0000, lo: 0x01},
 	{value: 0x162f, lo: 0xb3, hi: 0xb3},
-	// Block 0x51, offset 0x1eb
+	// Block 0x50, offset 0x1dc
 	{value: 0x0004, lo: 0x0b},
 	{value: 0x1597, lo: 0x80, hi: 0x82},
 	{value: 0x15af, lo: 0x83, hi: 0x83},
@@ -6239,7 +6246,7 @@
 	{value: 0x161b, lo: 0x91, hi: 0x93},
 	{value: 0x162b, lo: 0x94, hi: 0x94},
 	{value: 0x1633, lo: 0x95, hi: 0x95},
-	// Block 0x52, offset 0x1f7
+	// Block 0x51, offset 0x1e8
 	{value: 0x0004, lo: 0x09},
 	{value: 0x0001, lo: 0x80, hi: 0x80},
 	{value: 0x812c, lo: 0xaa, hi: 0xaa},
@@ -6250,7 +6257,7 @@
 	{value: 0x812f, lo: 0xaf, hi: 0xaf},
 	{value: 0x04b3, lo: 0xb6, hi: 0xb6},
 	{value: 0x0887, lo: 0xb8, hi: 0xba},
-	// Block 0x53, offset 0x201
+	// Block 0x52, offset 0x1f2
 	{value: 0x0006, lo: 0x09},
 	{value: 0x0313, lo: 0xb1, hi: 0xb1},
 	{value: 0x0317, lo: 0xb2, hi: 0xb2},
@@ -6261,63 +6268,63 @@
 	{value: 0x0323, lo: 0xb8, hi: 0xb8},
 	{value: 0x0327, lo: 0xb9, hi: 0xb9},
 	{value: 0x4a4d, lo: 0xba, hi: 0xbf},
-	// Block 0x54, offset 0x20b
+	// Block 0x53, offset 0x1fc
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0xaf, hi: 0xaf},
 	{value: 0x8132, lo: 0xb4, hi: 0xbd},
-	// Block 0x55, offset 0x20e
+	// Block 0x54, offset 0x1ff
 	{value: 0x0000, lo: 0x03},
 	{value: 0x020f, lo: 0x9c, hi: 0x9c},
 	{value: 0x0212, lo: 0x9d, hi: 0x9d},
 	{value: 0x8132, lo: 0x9e, hi: 0x9f},
-	// Block 0x56, offset 0x212
+	// Block 0x55, offset 0x203
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb0, hi: 0xb1},
-	// Block 0x57, offset 0x214
+	// Block 0x56, offset 0x205
 	{value: 0x0000, lo: 0x01},
 	{value: 0x163b, lo: 0xb0, hi: 0xb0},
-	// Block 0x58, offset 0x216
+	// Block 0x57, offset 0x207
 	{value: 0x000c, lo: 0x01},
 	{value: 0x00d7, lo: 0xb8, hi: 0xb9},
-	// Block 0x59, offset 0x218
+	// Block 0x58, offset 0x209
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x86, hi: 0x86},
-	// Block 0x5a, offset 0x21a
+	// Block 0x59, offset 0x20b
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x84, hi: 0x84},
 	{value: 0x8132, lo: 0xa0, hi: 0xb1},
-	// Block 0x5b, offset 0x21d
+	// Block 0x5a, offset 0x20e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xab, hi: 0xad},
-	// Block 0x5c, offset 0x21f
+	// Block 0x5b, offset 0x210
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x93, hi: 0x93},
-	// Block 0x5d, offset 0x221
+	// Block 0x5c, offset 0x212
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0xb3, hi: 0xb3},
-	// Block 0x5e, offset 0x223
+	// Block 0x5d, offset 0x214
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0x80, hi: 0x80},
-	// Block 0x5f, offset 0x225
+	// Block 0x5e, offset 0x216
 	{value: 0x0000, lo: 0x05},
 	{value: 0x8132, lo: 0xb0, hi: 0xb0},
 	{value: 0x8132, lo: 0xb2, hi: 0xb3},
 	{value: 0x812d, lo: 0xb4, hi: 0xb4},
 	{value: 0x8132, lo: 0xb7, hi: 0xb8},
 	{value: 0x8132, lo: 0xbe, hi: 0xbf},
-	// Block 0x60, offset 0x22b
+	// Block 0x5f, offset 0x21c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x81, hi: 0x81},
 	{value: 0x8104, lo: 0xb6, hi: 0xb6},
-	// Block 0x61, offset 0x22e
+	// Block 0x60, offset 0x21f
 	{value: 0x0008, lo: 0x03},
 	{value: 0x1637, lo: 0x9c, hi: 0x9d},
 	{value: 0x0125, lo: 0x9e, hi: 0x9e},
 	{value: 0x1643, lo: 0x9f, hi: 0x9f},
-	// Block 0x62, offset 0x232
+	// Block 0x61, offset 0x223
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xad, hi: 0xad},
-	// Block 0x63, offset 0x234
+	// Block 0x62, offset 0x225
 	{value: 0x0000, lo: 0x06},
 	{value: 0xe500, lo: 0x80, hi: 0x80},
 	{value: 0xc600, lo: 0x81, hi: 0x9b},
@@ -6325,21 +6332,21 @@
 	{value: 0xc600, lo: 0x9d, hi: 0xb7},
 	{value: 0xe500, lo: 0xb8, hi: 0xb8},
 	{value: 0xc600, lo: 0xb9, hi: 0xbf},
-	// Block 0x64, offset 0x23b
+	// Block 0x63, offset 0x22c
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x93},
 	{value: 0xe500, lo: 0x94, hi: 0x94},
 	{value: 0xc600, lo: 0x95, hi: 0xaf},
 	{value: 0xe500, lo: 0xb0, hi: 0xb0},
 	{value: 0xc600, lo: 0xb1, hi: 0xbf},
-	// Block 0x65, offset 0x241
+	// Block 0x64, offset 0x232
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x8b},
 	{value: 0xe500, lo: 0x8c, hi: 0x8c},
 	{value: 0xc600, lo: 0x8d, hi: 0xa7},
 	{value: 0xe500, lo: 0xa8, hi: 0xa8},
 	{value: 0xc600, lo: 0xa9, hi: 0xbf},
-	// Block 0x66, offset 0x247
+	// Block 0x65, offset 0x238
 	{value: 0x0000, lo: 0x07},
 	{value: 0xc600, lo: 0x80, hi: 0x83},
 	{value: 0xe500, lo: 0x84, hi: 0x84},
@@ -6348,60 +6355,60 @@
 	{value: 0xc600, lo: 0xa1, hi: 0xbb},
 	{value: 0xe500, lo: 0xbc, hi: 0xbc},
 	{value: 0xc600, lo: 0xbd, hi: 0xbf},
-	// Block 0x67, offset 0x24f
+	// Block 0x66, offset 0x240
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x97},
 	{value: 0xe500, lo: 0x98, hi: 0x98},
 	{value: 0xc600, lo: 0x99, hi: 0xb3},
 	{value: 0xe500, lo: 0xb4, hi: 0xb4},
 	{value: 0xc600, lo: 0xb5, hi: 0xbf},
-	// Block 0x68, offset 0x255
+	// Block 0x67, offset 0x246
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x8f},
 	{value: 0xe500, lo: 0x90, hi: 0x90},
 	{value: 0xc600, lo: 0x91, hi: 0xab},
 	{value: 0xe500, lo: 0xac, hi: 0xac},
 	{value: 0xc600, lo: 0xad, hi: 0xbf},
-	// Block 0x69, offset 0x25b
+	// Block 0x68, offset 0x24c
 	{value: 0x0000, lo: 0x05},
 	{value: 0xc600, lo: 0x80, hi: 0x87},
 	{value: 0xe500, lo: 0x88, hi: 0x88},
 	{value: 0xc600, lo: 0x89, hi: 0xa3},
 	{value: 0xe500, lo: 0xa4, hi: 0xa4},
 	{value: 0xc600, lo: 0xa5, hi: 0xbf},
-	// Block 0x6a, offset 0x261
+	// Block 0x69, offset 0x252
 	{value: 0x0000, lo: 0x03},
 	{value: 0xc600, lo: 0x80, hi: 0x87},
 	{value: 0xe500, lo: 0x88, hi: 0x88},
 	{value: 0xc600, lo: 0x89, hi: 0xa3},
-	// Block 0x6b, offset 0x265
+	// Block 0x6a, offset 0x256
 	{value: 0x0002, lo: 0x01},
 	{value: 0x0003, lo: 0x81, hi: 0xbf},
-	// Block 0x6c, offset 0x267
+	// Block 0x6b, offset 0x258
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xbd, hi: 0xbd},
-	// Block 0x6d, offset 0x269
+	// Block 0x6c, offset 0x25a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0xa0, hi: 0xa0},
-	// Block 0x6e, offset 0x26b
+	// Block 0x6d, offset 0x25c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb6, hi: 0xba},
-	// Block 0x6f, offset 0x26d
+	// Block 0x6e, offset 0x25e
 	{value: 0x002c, lo: 0x05},
 	{value: 0x812d, lo: 0x8d, hi: 0x8d},
 	{value: 0x8132, lo: 0x8f, hi: 0x8f},
 	{value: 0x8132, lo: 0xb8, hi: 0xb8},
 	{value: 0x8101, lo: 0xb9, hi: 0xba},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x70, offset 0x273
+	// Block 0x6f, offset 0x264
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0xa5, hi: 0xa5},
 	{value: 0x812d, lo: 0xa6, hi: 0xa6},
-	// Block 0x71, offset 0x276
+	// Block 0x70, offset 0x267
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x86, hi: 0x86},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x72, offset 0x279
+	// Block 0x71, offset 0x26a
 	{value: 0x17fe, lo: 0x07},
 	{value: 0xa000, lo: 0x99, hi: 0x99},
 	{value: 0x4238, lo: 0x9a, hi: 0x9a},
@@ -6410,7 +6417,7 @@
 	{value: 0xa000, lo: 0xa5, hi: 0xa5},
 	{value: 0x424c, lo: 0xab, hi: 0xab},
 	{value: 0x8104, lo: 0xb9, hi: 0xba},
-	// Block 0x73, offset 0x281
+	// Block 0x72, offset 0x272
 	{value: 0x0000, lo: 0x06},
 	{value: 0x8132, lo: 0x80, hi: 0x82},
 	{value: 0x9900, lo: 0xa7, hi: 0xa7},
@@ -6418,18 +6425,18 @@
 	{value: 0x2d88, lo: 0xaf, hi: 0xaf},
 	{value: 0xa000, lo: 0xb1, hi: 0xb2},
 	{value: 0x8104, lo: 0xb3, hi: 0xb4},
-	// Block 0x74, offset 0x288
+	// Block 0x73, offset 0x279
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x80, hi: 0x80},
 	{value: 0x8102, lo: 0x8a, hi: 0x8a},
-	// Block 0x75, offset 0x28b
+	// Block 0x74, offset 0x27c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0xb5, hi: 0xb5},
 	{value: 0x8102, lo: 0xb6, hi: 0xb6},
-	// Block 0x76, offset 0x28e
+	// Block 0x75, offset 0x27f
 	{value: 0x0002, lo: 0x01},
 	{value: 0x8102, lo: 0xa9, hi: 0xaa},
-	// Block 0x77, offset 0x290
+	// Block 0x76, offset 0x281
 	{value: 0x0000, lo: 0x07},
 	{value: 0xa000, lo: 0x87, hi: 0x87},
 	{value: 0x2d92, lo: 0x8b, hi: 0x8b},
@@ -6438,11 +6445,11 @@
 	{value: 0x9900, lo: 0x97, hi: 0x97},
 	{value: 0x8132, lo: 0xa6, hi: 0xac},
 	{value: 0x8132, lo: 0xb0, hi: 0xb4},
-	// Block 0x78, offset 0x298
+	// Block 0x77, offset 0x289
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x82, hi: 0x82},
 	{value: 0x8102, lo: 0x86, hi: 0x86},
-	// Block 0x79, offset 0x29b
+	// Block 0x78, offset 0x28c
 	{value: 0x6b5a, lo: 0x06},
 	{value: 0x9900, lo: 0xb0, hi: 0xb0},
 	{value: 0xa000, lo: 0xb9, hi: 0xb9},
@@ -6450,40 +6457,53 @@
 	{value: 0x2db0, lo: 0xbb, hi: 0xbb},
 	{value: 0x2da6, lo: 0xbc, hi: 0xbd},
 	{value: 0x2dba, lo: 0xbe, hi: 0xbe},
-	// Block 0x7a, offset 0x2a2
+	// Block 0x79, offset 0x293
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0x82, hi: 0x82},
 	{value: 0x8102, lo: 0x83, hi: 0x83},
-	// Block 0x7b, offset 0x2a5
+	// Block 0x7a, offset 0x296
 	{value: 0x0000, lo: 0x05},
 	{value: 0x9900, lo: 0xaf, hi: 0xaf},
 	{value: 0xa000, lo: 0xb8, hi: 0xb9},
 	{value: 0x2dc4, lo: 0xba, hi: 0xba},
 	{value: 0x2dce, lo: 0xbb, hi: 0xbb},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x7c, offset 0x2ab
+	// Block 0x7b, offset 0x29c
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8102, lo: 0x80, hi: 0x80},
-	// Block 0x7d, offset 0x2ad
+	// Block 0x7c, offset 0x29e
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xbf, hi: 0xbf},
-	// Block 0x7e, offset 0x2af
+	// Block 0x7d, offset 0x2a0
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8104, lo: 0xb6, hi: 0xb6},
 	{value: 0x8102, lo: 0xb7, hi: 0xb7},
-	// Block 0x7f, offset 0x2b2
+	// Block 0x7e, offset 0x2a3
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8104, lo: 0xab, hi: 0xab},
-	// Block 0x80, offset 0x2b4
+	// Block 0x7f, offset 0x2a5
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0xb4, hi: 0xb4},
+	// Block 0x80, offset 0x2a7
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0x87, hi: 0x87},
+	// Block 0x81, offset 0x2a9
+	{value: 0x0000, lo: 0x01},
+	{value: 0x8104, lo: 0x99, hi: 0x99},
+	// Block 0x82, offset 0x2ab
+	{value: 0x0000, lo: 0x02},
+	{value: 0x8102, lo: 0x82, hi: 0x82},
+	{value: 0x8104, lo: 0x84, hi: 0x85},
+	// Block 0x83, offset 0x2ae
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8101, lo: 0xb0, hi: 0xb4},
-	// Block 0x81, offset 0x2b6
+	// Block 0x84, offset 0x2b0
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0xb0, hi: 0xb6},
-	// Block 0x82, offset 0x2b8
+	// Block 0x85, offset 0x2b2
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8101, lo: 0x9e, hi: 0x9e},
-	// Block 0x83, offset 0x2ba
+	// Block 0x86, offset 0x2b4
 	{value: 0x0000, lo: 0x0c},
 	{value: 0x45cc, lo: 0x9e, hi: 0x9e},
 	{value: 0x45d6, lo: 0x9f, hi: 0x9f},
@@ -6497,7 +6517,7 @@
 	{value: 0x8130, lo: 0xad, hi: 0xad},
 	{value: 0x812b, lo: 0xae, hi: 0xb2},
 	{value: 0x812d, lo: 0xbb, hi: 0xbf},
-	// Block 0x84, offset 0x2c7
+	// Block 0x87, offset 0x2c1
 	{value: 0x0000, lo: 0x09},
 	{value: 0x812d, lo: 0x80, hi: 0x82},
 	{value: 0x8132, lo: 0x85, hi: 0x89},
@@ -6508,24 +6528,24 @@
 	{value: 0x4650, lo: 0xbd, hi: 0xbd},
 	{value: 0x466c, lo: 0xbe, hi: 0xbe},
 	{value: 0x465e, lo: 0xbf, hi: 0xbf},
-	// Block 0x85, offset 0x2d1
+	// Block 0x88, offset 0x2cb
 	{value: 0x0000, lo: 0x01},
 	{value: 0x467a, lo: 0x80, hi: 0x80},
-	// Block 0x86, offset 0x2d3
+	// Block 0x89, offset 0x2cd
 	{value: 0x0000, lo: 0x01},
 	{value: 0x8132, lo: 0x82, hi: 0x84},
-	// Block 0x87, offset 0x2d5
+	// Block 0x8a, offset 0x2cf
 	{value: 0x0002, lo: 0x03},
 	{value: 0x0043, lo: 0x80, hi: 0x99},
 	{value: 0x0083, lo: 0x9a, hi: 0xb3},
 	{value: 0x0043, lo: 0xb4, hi: 0xbf},
-	// Block 0x88, offset 0x2d9
+	// Block 0x8b, offset 0x2d3
 	{value: 0x0002, lo: 0x04},
 	{value: 0x005b, lo: 0x80, hi: 0x8d},
 	{value: 0x0083, lo: 0x8e, hi: 0x94},
 	{value: 0x0093, lo: 0x96, hi: 0xa7},
 	{value: 0x0043, lo: 0xa8, hi: 0xbf},
-	// Block 0x89, offset 0x2de
+	// Block 0x8c, offset 0x2d8
 	{value: 0x0002, lo: 0x0b},
 	{value: 0x0073, lo: 0x80, hi: 0x81},
 	{value: 0x0083, lo: 0x82, hi: 0x9b},
@@ -6538,13 +6558,13 @@
 	{value: 0x0083, lo: 0xb6, hi: 0xb9},
 	{value: 0x008d, lo: 0xbb, hi: 0xbb},
 	{value: 0x0091, lo: 0xbd, hi: 0xbf},
-	// Block 0x8a, offset 0x2ea
+	// Block 0x8d, offset 0x2e4
 	{value: 0x0002, lo: 0x04},
 	{value: 0x0097, lo: 0x80, hi: 0x83},
 	{value: 0x00a1, lo: 0x85, hi: 0x8f},
 	{value: 0x0043, lo: 0x90, hi: 0xa9},
 	{value: 0x0083, lo: 0xaa, hi: 0xbf},
-	// Block 0x8b, offset 0x2ef
+	// Block 0x8e, offset 0x2e9
 	{value: 0x0002, lo: 0x08},
 	{value: 0x00af, lo: 0x80, hi: 0x83},
 	{value: 0x0043, lo: 0x84, hi: 0x85},
@@ -6554,36 +6574,36 @@
 	{value: 0x0083, lo: 0x9e, hi: 0xb7},
 	{value: 0x0043, lo: 0xb8, hi: 0xb9},
 	{value: 0x0049, lo: 0xbb, hi: 0xbe},
-	// Block 0x8c, offset 0x2f8
+	// Block 0x8f, offset 0x2f2
 	{value: 0x0002, lo: 0x05},
 	{value: 0x0053, lo: 0x80, hi: 0x84},
 	{value: 0x005f, lo: 0x86, hi: 0x86},
 	{value: 0x0067, lo: 0x8a, hi: 0x90},
 	{value: 0x0083, lo: 0x92, hi: 0xab},
 	{value: 0x0043, lo: 0xac, hi: 0xbf},
-	// Block 0x8d, offset 0x2fe
+	// Block 0x90, offset 0x2f8
 	{value: 0x0002, lo: 0x04},
 	{value: 0x006b, lo: 0x80, hi: 0x85},
 	{value: 0x0083, lo: 0x86, hi: 0x9f},
 	{value: 0x0043, lo: 0xa0, hi: 0xb9},
 	{value: 0x0083, lo: 0xba, hi: 0xbf},
-	// Block 0x8e, offset 0x303
+	// Block 0x91, offset 0x2fd
 	{value: 0x0002, lo: 0x03},
 	{value: 0x008f, lo: 0x80, hi: 0x93},
 	{value: 0x0043, lo: 0x94, hi: 0xad},
 	{value: 0x0083, lo: 0xae, hi: 0xbf},
-	// Block 0x8f, offset 0x307
+	// Block 0x92, offset 0x301
 	{value: 0x0002, lo: 0x04},
 	{value: 0x00a7, lo: 0x80, hi: 0x87},
 	{value: 0x0043, lo: 0x88, hi: 0xa1},
 	{value: 0x0083, lo: 0xa2, hi: 0xbb},
 	{value: 0x0043, lo: 0xbc, hi: 0xbf},
-	// Block 0x90, offset 0x30c
+	// Block 0x93, offset 0x306
 	{value: 0x0002, lo: 0x03},
 	{value: 0x004b, lo: 0x80, hi: 0x95},
 	{value: 0x0083, lo: 0x96, hi: 0xaf},
 	{value: 0x0043, lo: 0xb0, hi: 0xbf},
-	// Block 0x91, offset 0x310
+	// Block 0x94, offset 0x30a
 	{value: 0x0003, lo: 0x0f},
 	{value: 0x01b8, lo: 0x80, hi: 0x80},
 	{value: 0x045f, lo: 0x81, hi: 0x81},
@@ -6600,7 +6620,7 @@
 	{value: 0x01a6, lo: 0xb4, hi: 0xba},
 	{value: 0x045f, lo: 0xbb, hi: 0xbb},
 	{value: 0x01bb, lo: 0xbc, hi: 0xbf},
-	// Block 0x92, offset 0x320
+	// Block 0x95, offset 0x31a
 	{value: 0x0003, lo: 0x0d},
 	{value: 0x01c7, lo: 0x80, hi: 0x94},
 	{value: 0x045b, lo: 0x95, hi: 0x95},
@@ -6615,7 +6635,7 @@
 	{value: 0x01a6, lo: 0xae, hi: 0xb4},
 	{value: 0x045f, lo: 0xb5, hi: 0xb5},
 	{value: 0x01bb, lo: 0xb6, hi: 0xbf},
-	// Block 0x93, offset 0x32e
+	// Block 0x96, offset 0x328
 	{value: 0x0003, lo: 0x0d},
 	{value: 0x01d9, lo: 0x80, hi: 0x8e},
 	{value: 0x045b, lo: 0x8f, hi: 0x8f},
@@ -6630,7 +6650,7 @@
 	{value: 0x01a6, lo: 0xa8, hi: 0xae},
 	{value: 0x045f, lo: 0xaf, hi: 0xaf},
 	{value: 0x01bb, lo: 0xb0, hi: 0xbf},
-	// Block 0x94, offset 0x33c
+	// Block 0x97, offset 0x336
 	{value: 0x0003, lo: 0x0d},
 	{value: 0x01eb, lo: 0x80, hi: 0x88},
 	{value: 0x045b, lo: 0x89, hi: 0x89},
@@ -6645,21 +6665,21 @@
 	{value: 0x01a6, lo: 0xa2, hi: 0xa8},
 	{value: 0x045f, lo: 0xa9, hi: 0xa9},
 	{value: 0x01bb, lo: 0xaa, hi: 0xbf},
-	// Block 0x95, offset 0x34a
+	// Block 0x98, offset 0x344
 	{value: 0x0000, lo: 0x05},
 	{value: 0x8132, lo: 0x80, hi: 0x86},
 	{value: 0x8132, lo: 0x88, hi: 0x98},
 	{value: 0x8132, lo: 0x9b, hi: 0xa1},
 	{value: 0x8132, lo: 0xa3, hi: 0xa4},
 	{value: 0x8132, lo: 0xa6, hi: 0xaa},
-	// Block 0x96, offset 0x350
+	// Block 0x99, offset 0x34a
 	{value: 0x0000, lo: 0x01},
 	{value: 0x812d, lo: 0x90, hi: 0x96},
-	// Block 0x97, offset 0x352
+	// Block 0x9a, offset 0x34c
 	{value: 0x0000, lo: 0x02},
 	{value: 0x8132, lo: 0x84, hi: 0x89},
 	{value: 0x8102, lo: 0x8a, hi: 0x8a},
-	// Block 0x98, offset 0x355
+	// Block 0x9b, offset 0x34f
 	{value: 0x0002, lo: 0x09},
 	{value: 0x0063, lo: 0x80, hi: 0x89},
 	{value: 0x1951, lo: 0x8a, hi: 0x8a},
@@ -6670,10 +6690,10 @@
 	{value: 0x19ae, lo: 0x8f, hi: 0x8f},
 	{value: 0x197b, lo: 0xaa, hi: 0xaa},
 	{value: 0x197e, lo: 0xab, hi: 0xab},
-	// Block 0x99, offset 0x35f
+	// Block 0x9c, offset 0x359
 	{value: 0x0000, lo: 0x01},
 	{value: 0x193f, lo: 0x90, hi: 0x90},
-	// Block 0x9a, offset 0x361
+	// Block 0x9d, offset 0x35b
 	{value: 0x0028, lo: 0x09},
 	{value: 0x2862, lo: 0x80, hi: 0x80},
 	{value: 0x2826, lo: 0x81, hi: 0x81},
@@ -7630,4 +7650,4 @@
 	0x15B915AF: 0x115BB,
 }
 
-// Total size of tables: 53KB (54006 bytes)
+// Total size of tables: 53KB (54226 bytes)
diff --git a/src/vendor/golang_org/x/text/unicode/norm/transform.go b/src/vendor/golang_org/x/text/unicode/norm/transform.go
index 4dec306..73869a5 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/transform.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/transform.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -42,7 +42,7 @@
 }
 
 func flushTransform(rb *reorderBuffer) bool {
-	// Write out (must fully fit in dst, or else it is a ErrShortDst).
+	// Write out (must fully fit in dst, or else it is an ErrShortDst).
 	if len(rb.out) < rb.nrune*utf8.UTFMax {
 		return false
 	}
diff --git a/src/vendor/golang_org/x/text/unicode/norm/trie.go b/src/vendor/golang_org/x/text/unicode/norm/trie.go
index 4cbea64..761439c 100644
--- a/src/vendor/golang_org/x/text/unicode/norm/trie.go
+++ b/src/vendor/golang_org/x/text/unicode/norm/trie.go
@@ -1,4 +1,4 @@
-// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/chan/sendstmt.go b/test/chan/sendstmt.go
index c0f1a29..d296a55 100644
--- a/test/chan/sendstmt.go
+++ b/test/chan/sendstmt.go
@@ -5,7 +5,7 @@
 // license that can be found in the LICENSE file.
 
 // Test various parsing cases that are a little
-// different now that send is a statement, not a expression.
+// different now that send is a statement, not an expression.
 
 package main
 
diff --git a/test/chancap.go b/test/chancap.go
index b3e4023..b08478a 100644
--- a/test/chancap.go
+++ b/test/chancap.go
@@ -8,8 +8,17 @@
 
 package main
 
+import (
+	"strings"
+	"unsafe"
+)
+
+type T chan int
+
+const ptrSize = unsafe.Sizeof((*byte)(nil))
+
 func main() {
-	c := make(chan int, 10)
+	c := make(T, 10)
 	if len(c) != 0 || cap(c) != 10 {
 		println("chan len/cap ", len(c), cap(c), " want 0 10")
 		panic("fail")
@@ -23,9 +32,39 @@
 		panic("fail")
 	}
 
-	c = make(chan int)
+	c = make(T)
 	if len(c) != 0 || cap(c) != 0 {
 		println("chan len/cap ", len(c), cap(c), " want 0 0")
 		panic("fail")
 	}
+
+	n := -1
+	shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+	shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+	if ptrSize == 8 {
+		n = 1 << 20
+		n <<= 20
+		shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+		n <<= 20
+		shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+	} else {
+		n = 1<<31 - 1
+		shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+		shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+	}
+}
+
+func shouldPanic(str string, f func()) {
+	defer func() {
+		err := recover()
+		if err == nil {
+			panic("did not panic")
+		}
+		s := err.(error).Error()
+		if !strings.Contains(s, str) {
+			panic("got panic " + s + ", want " + str)
+		}
+	}()
+
+	f()
 }
diff --git a/test/closure3.dir/main.go b/test/closure3.dir/main.go
new file mode 100644
index 0000000..4364343
--- /dev/null
+++ b/test/closure3.dir/main.go
@@ -0,0 +1,283 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases that
+// that are expected to be inlined
+
+package main
+
+var ok bool
+var sink int
+
+func main() {
+	{
+		if x := func() int { // ERROR "can inline main.func1"
+			return 1
+		}(); x != 1 { // ERROR "inlining call to main.func1"
+			panic("x != 1")
+		}
+		if x := func() int { // ERROR "can inline main.func2" "func literal does not escape"
+			return 1
+		}; x() != 1 { // ERROR "inlining call to main.func2"
+			panic("x() != 1")
+		}
+	}
+
+	{
+		if y := func(x int) int { // ERROR "can inline main.func3"
+			return x + 2
+		}(40); y != 42 { // ERROR "inlining call to main.func3"
+			panic("y != 42")
+		}
+		if y := func(x int) int { // ERROR "can inline main.func4" "func literal does not escape"
+			return x + 2
+		}; y(40) != 42 { // ERROR "inlining call to main.func4"
+			panic("y(40) != 42")
+		}
+	}
+
+	{
+		y := func(x int) int { // ERROR "can inline main.func5" "func literal does not escape"
+			return x + 2
+		}
+		y = func(x int) int { // ERROR "can inline main.func6" "func literal does not escape"
+			return x + 1
+		}
+		if y(40) != 41 {
+			panic("y(40) != 41")
+		}
+	}
+
+	{
+		func() { // ERROR "func literal does not escape"
+			y := func(x int) int { // ERROR "can inline main.func7.1" "func literal does not escape"
+				return x + 2
+			}
+			y = func(x int) int { // ERROR "can inline main.func7.2" "func literal does not escape"
+				return x + 1
+			}
+			if y(40) != 41 {
+				panic("y(40) != 41")
+			}
+		}()
+	}
+
+	{
+		y := func(x int) int { // ERROR "can inline main.func8" "func literal does not escape"
+			return x + 2
+		}
+		y, sink = func(x int) int { // ERROR "can inline main.func9" "func literal does not escape"
+			return x + 1
+		}, 42
+		if y(40) != 41 {
+			panic("y(40) != 41")
+		}
+	}
+
+	{
+		func() { // ERROR "func literal does not escape"
+			y := func(x int) int { // ERROR "can inline main.func10.1" "func literal does not escape"
+				return x + 2
+			}
+			y, sink = func(x int) int { // ERROR "can inline main.func10.2" "func literal does not escape"
+				return x + 1
+			}, 42
+			if y(40) != 41 {
+				panic("y(40) != 41")
+			}
+		}()
+	}
+
+	{
+		y := func(x int) int { // ERROR "can inline main.func11" "func literal does not escape"
+			return x + 2
+		}
+		y, sink = func() (func(int)int, int) { // ERROR "func literal does not escape"
+			return func(x int) int { // ERROR "can inline main.func12" "func literal escapes"
+				return x + 1
+			}, 42
+		}()
+		if y(40) != 41 {
+			panic("y(40) != 41")
+		}
+	}
+
+	{
+		func() { // ERROR "func literal does not escape"
+			y := func(x int) int { // ERROR "can inline main.func13.1" "func literal does not escape"
+				return x + 2
+			}
+			y, sink = func() (func(int) int, int) { // ERROR "func literal does not escape"
+				return func(x int) int { // ERROR "can inline main.func13.2" "func literal escapes"
+					return x + 1
+				}, 42
+			}()
+			if y(40) != 41 {
+				panic("y(40) != 41")
+			}
+		}()
+	}
+
+	{
+		y := func(x int) int { // ERROR "can inline main.func14" "func literal does not escape"
+			return x + 2
+		}
+		y, ok = map[int]func(int)int { // ERROR "does not escape"
+			0: func (x int) int { return x + 1 }, // ERROR "can inline main.func15" "func literal escapes"
+		}[0]
+		if y(40) != 41 {
+			panic("y(40) != 41")
+		}
+	}
+
+	{
+		func() { // ERROR "func literal does not escape"
+			y := func(x int) int { // ERROR "can inline main.func16.1" "func literal does not escape"
+				return x + 2
+			}
+			y, ok = map[int]func(int) int{// ERROR "does not escape"
+				0: func(x int) int { return x + 1 }, // ERROR "can inline main.func16.2" "func literal escapes"
+			}[0]
+			if y(40) != 41 {
+				panic("y(40) != 41")
+			}
+		}()
+	}
+
+	{
+		y := func(x int) int { // ERROR "can inline main.func17" "func literal does not escape"
+			return x + 2
+		}
+		y, ok = interface{}(func (x int) int { // ERROR "can inline main.func18" "does not escape"
+			return x + 1
+		}).(func(int)int)
+		if y(40) != 41 {
+			panic("y(40) != 41")
+		}
+	}
+
+	{
+		func() { // ERROR "func literal does not escape"
+			y := func(x int) int { // ERROR "can inline main.func19.1" "func literal does not escape"
+				return x + 2
+			}
+			y, ok = interface{}(func(x int) int { // ERROR "can inline main.func19.2" "does not escape"
+				return x + 1
+			}).(func(int) int)
+			if y(40) != 41 {
+				panic("y(40) != 41")
+			}
+		}()
+	}
+
+	{
+		x := 42
+		if y := func() int { // ERROR "can inline main.func20"
+			return x
+		}(); y != 42 { // ERROR "inlining call to main.func20"
+			panic("y != 42")
+		}
+		if y := func() int { // ERROR "can inline main.func21" "func literal does not escape"
+			return x
+		}; y() != 42 { // ERROR "inlining call to main.func21"
+			panic("y() != 42")
+		}
+	}
+
+	{
+		x := 42
+		if z := func(y int) int { // ERROR "func literal does not escape"
+			return func() int { // ERROR "can inline main.func22.1"
+				return x + y
+			}() // ERROR "inlining call to main.func22.1"
+		}(1); z != 43 {
+			panic("z != 43")
+		}
+		if z := func(y int) int { // ERROR "func literal does not escape"
+			return func() int { // ERROR "can inline main.func23.1"
+				return x + y
+			}() // ERROR "inlining call to main.func23.1"
+		}; z(1) != 43 {
+			panic("z(1) != 43")
+		}
+	}
+
+	{
+		a := 1
+		func() { // ERROR "func literal does not escape"
+			func() { // ERROR "can inline main.func24"
+				a = 2
+			}() // ERROR "inlining call to main.func24" "&a does not escape"
+		}()
+		if a != 2 {
+			panic("a != 2")
+		}
+	}
+
+	{
+		b := 2
+		func(b int) { // ERROR "func literal does not escape"
+			func() { // ERROR "can inline main.func25.1"
+				b = 3
+			}() // ERROR "inlining call to main.func25.1" "&b does not escape"
+			if b != 3 {
+				panic("b != 3")
+			}
+		}(b)
+		if b != 2 {
+			panic("b != 2")
+		}
+	}
+
+	{
+		c := 3
+		func() { // ERROR "func literal does not escape"
+			c = 4
+			func() { // ERROR "func literal does not escape"
+				if c != 4 {
+					panic("c != 4")
+				}
+			}()
+		}()
+		if c != 4 {
+			panic("c != 4")
+		}
+	}
+
+	{
+		a := 2
+		if r := func(x int) int { // ERROR "func literal does not escape"
+			b := 3
+			return func(y int) int { // ERROR "func literal does not escape"
+				c := 5
+				return func(z int) int { // ERROR "can inline main.func27.1.1"
+					return a*x + b*y + c*z
+				}(10) // ERROR "inlining call to main.func27.1.1"
+			}(100)
+		}(1000); r != 2350 {
+			panic("r != 2350")
+		}
+	}
+
+	{
+		a := 2
+		if r := func(x int) int { // ERROR "func literal does not escape"
+			b := 3
+			return func(y int) int { // ERROR "func literal does not escape"
+				c := 5
+				func(z int) { // ERROR "can inline main.func28.1.1"
+					a = a * x
+					b = b * y
+					c = c * z
+				}(10) // ERROR "inlining call to main.func28.1.1" "&a does not escape" "&b does not escape" "&c does not escape"
+				return a + c
+			}(100) + b
+		}(1000); r != 2350 {
+			panic("r != 2350")
+		}
+		if a != 2000 {
+			panic("a != 2000")
+		}
+	}
+}
diff --git a/test/closure3.go b/test/closure3.go
new file mode 100644
index 0000000..263d8fc
--- /dev/null
+++ b/test/closure3.go
@@ -0,0 +1,10 @@
+// errorcheckandrundir -0 -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases that
+// that are expected to be inlined
+
+package ignored
diff --git a/test/ddd1.go b/test/ddd1.go
index 4284e32..b4ad80b 100644
--- a/test/ddd1.go
+++ b/test/ddd1.go
@@ -53,8 +53,7 @@
 	_ = new(int...)	// ERROR "[.][.][.]"
 	n := 10
 	_ = make([]byte, n...)	// ERROR "[.][.][.]"
-	// TODO(rsc): enable after gofmt bug is fixed
-	//	_ = make([]byte, 10 ...)	// error "[.][.][.]"
+	_ = make([]byte, 10 ...)	// ERROR "[.][.][.]"
 	var x int
 	_ = unsafe.Pointer(&x...)	// ERROR "[.][.][.]"
 	_ = unsafe.Sizeof(x...)	// ERROR "[.][.][.]"
diff --git a/test/errchk b/test/errchk
index bc8ef19..1cb57bb 100755
--- a/test/errchk
+++ b/test/errchk
@@ -65,6 +65,9 @@
 
 close CMD;
 
+# Remove lines beginning with #, printed by go command to indicate package.
+@out = grep {!/^#/} @out;
+
 if($exitcode != 0 && $? == 0) {
 	print STDERR "BUG: errchk: command succeeded unexpectedly\n";
 	print STDERR @out;
diff --git a/test/escape2.go b/test/escape2.go
index e10dbc2..ef3d6a8 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -1204,7 +1204,7 @@
 		// loopdepth 1
 		var i int // ERROR "moved to heap: i$"
 		func() {  // ERROR "foo126 func literal does not escape$"
-			px = &i // ERROR "&i escapes to heap$"  "leaking closure reference i"
+			px = &i // ERROR "&i escapes to heap$" "leaking closure reference i"
 		}()
 	}
 	_ = px
diff --git a/test/escape2n.go b/test/escape2n.go
index 74f6f8d..b1130d3 100644
--- a/test/escape2n.go
+++ b/test/escape2n.go
@@ -1824,3 +1824,18 @@
 	copy(slice2, slice1)
 	return slice2[0]
 }
+
+func issue12397(x, y int) { // ERROR "moved to heap: y$"
+	// x does not escape below, because all relevant code is dead.
+	if false {
+		gxx = &x
+	} else {
+		gxx = &y // ERROR "&y escapes to heap$"
+	}
+
+	if true {
+		gxx = &y // ERROR "&y escapes to heap$"
+	} else {
+		gxx = &x
+	}
+}
diff --git a/test/escape4.go b/test/escape4.go
index 69a54ac..22a37c1 100644
--- a/test/escape4.go
+++ b/test/escape4.go
@@ -22,9 +22,9 @@
 
 	// Escape analysis used to miss inlined code in closures.
 
-	func() { // ERROR "func literal does not escape" "can inline f1.func1"
-		p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
-	}()
+	func() { // ERROR "can inline f1.func1"
+		p = alloc(3) // ERROR "inlining call to alloc"
+	}() // ERROR "inlining call to f1.func1" "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
 
 	f = func() { // ERROR "func literal escapes to heap" "can inline f1.func2"
 		p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
diff --git a/test/fixedbugs/bug289.go b/test/fixedbugs/bug289.go
index a3f7295..3fc7fb2 100644
--- a/test/fixedbugs/bug289.go
+++ b/test/fixedbugs/bug289.go
@@ -9,14 +9,14 @@
 package main
 
 func f1() {
-	a, b := f()	// ERROR "cannot assign|does not match"
+	a, b := f()	// ERROR "assignment mismatch|does not match"
 	_ = a
 	_ = b
 }
 
 func f2() {
 	var a, b int
-	a, b = f()	// ERROR "cannot assign|does not match"
+	a, b = f()	// ERROR "assignment mismatch|does not match"
 	_ = a
 	_ = b
 }
diff --git a/test/fixedbugs/bug388.go b/test/fixedbugs/bug388.go
index af0c9d9..2d50850 100644
--- a/test/fixedbugs/bug388.go
+++ b/test/fixedbugs/bug388.go
@@ -14,7 +14,7 @@
 }
 
 func bar(i int) {
-	runtime.UintType := i       // ERROR "cannot declare name runtime.UintType|non-name on left side|undefined identifier"
+	runtime.UintType := i       // ERROR "non-name runtime.UintType|non-name on left side|undefined identifier"
 	println(runtime.UintType)	// GCCGO_ERROR "invalid use of type|undefined identifier"
 }
 
diff --git a/test/fixedbugs/bug487.go b/test/fixedbugs/bug487.go
index 60a4ea9..ab61a19 100644
--- a/test/fixedbugs/bug487.go
+++ b/test/fixedbugs/bug487.go
@@ -14,8 +14,8 @@
 }
 
 func F() {
-	a, b := G()	// ERROR "cannot assign"
-	a, b = G()	// ERROR "cannot assign"
+	a, b := G()	// ERROR "assignment mismatch"
+	a, b = G()	// ERROR "assignment mismatch"
 	_, _ = a, b
 }
 
diff --git a/test/fixedbugs/bug503.go b/test/fixedbugs/bug503.go
new file mode 100644
index 0000000..7bbc798
--- /dev/null
+++ b/test/fixedbugs/bug503.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// gccgo crashed compiling this file, due to failing to correctly emit
+// the type descriptor for a named alias.
+
+package p
+
+type entry = struct {
+	a, b, c int
+}
+
+var V entry
diff --git a/test/fixedbugs/bug504.dir/a.go b/test/fixedbugs/bug504.dir/a.go
new file mode 100644
index 0000000..ac0be93
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type MyInt = int
diff --git a/test/fixedbugs/bug504.dir/b.go b/test/fixedbugs/bug504.dir/b.go
new file mode 100644
index 0000000..e8f8da9
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+func F() a.MyInt {
+	return 0
+}
diff --git a/test/fixedbugs/bug504.dir/c.go b/test/fixedbugs/bug504.dir/c.go
new file mode 100644
index 0000000..5a6e889
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/c.go
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package c
+
+import "./b"
+
+var V = b.F()
diff --git a/test/fixedbugs/bug504.dir/main.go b/test/fixedbugs/bug504.dir/main.go
new file mode 100644
index 0000000..bdbd95c
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/main.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "./c"
+
+func main() {
+	println(c.V)
+}
diff --git a/test/fixedbugs/bug504.go b/test/fixedbugs/bug504.go
new file mode 100644
index 0000000..ae1f2e5
--- /dev/null
+++ b/test/fixedbugs/bug504.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo mishandled a reference to a type alias in a package that was
+// not directly imported.
+
+package ignored
diff --git a/test/fixedbugs/bug505.go b/test/fixedbugs/bug505.go
new file mode 100644
index 0000000..062a087
--- /dev/null
+++ b/test/fixedbugs/bug505.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// gccgo crashed compiling this file with a failed conversion to the
+// alias type when constructing the composite literal.
+
+package p
+
+type I interface{ M() }
+type A = I
+type S struct {
+	f A
+}
+
+func F(i I) S {
+	return S{f: i}
+}
diff --git a/test/fixedbugs/issue13265.go b/test/fixedbugs/issue13265.go
new file mode 100644
index 0000000..3036ba7
--- /dev/null
+++ b/test/fixedbugs/issue13265.go
@@ -0,0 +1,15 @@
+// errorcheck -0 -race
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 13265: nil pointer deref.
+
+package p
+
+func f() {
+    var c chan chan chan int
+    for ; ; <-<-<-c {
+    }
+}
diff --git a/test/fixedbugs/issue14006.go b/test/fixedbugs/issue14006.go
index d69bdd4..02041cc 100644
--- a/test/fixedbugs/issue14006.go
+++ b/test/fixedbugs/issue14006.go
@@ -50,7 +50,10 @@
 		labelname:	// ERROR "missing statement after label"
 	case false:
 	}
+}
 
+func g() {
+	var z bool
 	switch {
 	case z:
 		labelname:	// ERROR "label labelname defined and not used"
diff --git a/test/fixedbugs/issue14540.go b/test/fixedbugs/issue14540.go
new file mode 100644
index 0000000..62b17a0
--- /dev/null
+++ b/test/fixedbugs/issue14540.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f(x int) {
+	switch x {
+	case 0:
+		fallthrough
+		; // ok
+	case 1:
+		fallthrough // ERROR "fallthrough statement out of place"
+		{}
+	case 2:
+		fallthrough // ERROR "cannot fallthrough"
+	}
+}
diff --git a/test/fixedbugs/issue15747.go b/test/fixedbugs/issue15747.go
index 836d0ea..decabc7 100644
--- a/test/fixedbugs/issue15747.go
+++ b/test/fixedbugs/issue15747.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live
+// errorcheck -0 -live -d=eagerwb
 
 // Copyright 2016 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -7,6 +7,10 @@
 // Issue 15747: liveness analysis was marking heap-escaped params live too much,
 // and worse was using the wrong bitmap bits to do so.
 
+// TODO(austin): This expects function calls to the write barrier, so
+// we enable the legacy eager write barrier. Fix this once the
+// buffered write barrier works on all arches.
+
 package p
 
 var global *[]byte
diff --git a/test/fixedbugs/issue15747b.go b/test/fixedbugs/issue15747b.go
index 9620d3d..bdb2a94 100644
--- a/test/fixedbugs/issue15747b.go
+++ b/test/fixedbugs/issue15747b.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Issue 15747: If a ODCL is dropped, for example when inlining,
+// Issue 15747: If an ODCL is dropped, for example when inlining,
 // then it's easy to end up not initializing the '&x' pseudo-variable
 // to point to an actual allocation. The liveness analysis will detect
 // this and abort the computation, so this test just checks that the
diff --git a/test/fixedbugs/issue18902.go b/test/fixedbugs/issue18902.go
index f5bca16..78c9218 100644
--- a/test/fixedbugs/issue18902.go
+++ b/test/fixedbugs/issue18902.go
@@ -50,13 +50,16 @@
 	testarch := os.Getenv("TESTARCH")     // Targets other platform in test compilation.
 	debug := os.Getenv("TESTDEBUG") != "" // Output the relevant assembly language.
 
-	cmd := exec.Command("go", "build", "-gcflags", "-S", "fixedbugs/issue18902b.go")
+	cmd := exec.Command("go", "tool", "compile", "-S", "fixedbugs/issue18902b.go")
 	var buf bytes.Buffer
 	cmd.Stdout = &buf
 	cmd.Stderr = &buf
 	cmd.Env = os.Environ()
 
-	updateEnv(&cmd.Env, "GOARCH", testarch)
+	if testarch != "" {
+		updateEnv(&cmd.Env, "GOARCH", testarch)
+		updateEnv(&cmd.Env, "GOOS", "linux") // Simplify multi-arch testing
+	}
 
 	err := cmd.Run()
 	if err != nil {
@@ -89,8 +92,9 @@
 		i = strings.Index(line, beforeLineNumber)
 		if i < 0 {
 			// Done reading lines
-			if scannedCount < 200 { // When test was written, 251 lines observed on amd64
-				fmt.Printf("Scanned only %d lines, was expecting more than 200", scannedCount)
+			const minLines = 150
+			if scannedCount <= minLines { // When test was written, 251 lines observed on amd64; arm64 now obtains 184
+				fmt.Printf("Scanned only %d lines, was expecting more than %d\n", int(scannedCount), minLines)
 				return
 			}
 			// Note: when test was written, before changes=92, after=50 (was 62 w/o rematerialization NoXPos in *Value.copyInto())
diff --git a/test/fixedbugs/issue19137.go b/test/fixedbugs/issue19137.go
index 946f029..0539a85 100644
--- a/test/fixedbugs/issue19137.go
+++ b/test/fixedbugs/issue19137.go
@@ -33,3 +33,19 @@
 	_ = x
 	return [20]byte{}, [20]byte{} // the second return value is not 8-byte aligned to SP
 }
+
+// Issue 21992: unaligned offset between 256 and 504 and handled
+// incorrectly.
+type T2 struct {
+	a [257]byte
+	// fields below are not 8-, 4-, 2-byte aligned
+	b [8]byte
+	c [4]byte
+	d [2]byte
+}
+
+func f2(x *T2) {
+	x.b = [8]byte{}
+	x.c = [4]byte{}
+	x.d = [2]byte{}
+}
diff --git a/test/fixedbugs/issue19261.dir/p.go b/test/fixedbugs/issue19261.dir/p.go
new file mode 100644
index 0000000..1c44d8a
--- /dev/null
+++ b/test/fixedbugs/issue19261.dir/p.go
@@ -0,0 +1,24 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func F() { // ERROR "can inline F"
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
+
+func G() {
+	F() // ERROR "inlining call to F"
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
diff --git a/test/fixedbugs/issue19261.dir/q.go b/test/fixedbugs/issue19261.dir/q.go
new file mode 100644
index 0000000..9f3550a
--- /dev/null
+++ b/test/fixedbugs/issue19261.dir/q.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package q
+
+import "./p"
+
+func H() {
+	p.F() // ERROR "inlining call to p.F"
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+	print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
diff --git a/test/fixedbugs/issue19261.go b/test/fixedbugs/issue19261.go
new file mode 100644
index 0000000..61cff6e
--- /dev/null
+++ b/test/fixedbugs/issue19261.go
@@ -0,0 +1,7 @@
+// errorcheckdir -0 -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue20250.go b/test/fixedbugs/issue20250.go
index f24710a..525192a 100644
--- a/test/fixedbugs/issue20250.go
+++ b/test/fixedbugs/issue20250.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live -d=compilelater
+// errorcheck -0 -live -l -d=compilelater,eagerwb
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -8,6 +8,10 @@
 // due to propagation of addrtaken to outer variables for
 // closure variables.
 
+// TODO(austin): This expects function calls to the write barrier, so
+// we enable the legacy eager write barrier. Fix this once the
+// buffered write barrier works on all arches.
+
 package p
 
 type T struct {
@@ -16,8 +20,8 @@
 
 func f(a T) { // ERROR "live at entry to f: a"
 	var e interface{}
-	func() { // ERROR "live at entry to f.func1: &e a"
-		e = a.s // ERROR "live at call to convT2Estring: &e a" "live at call to writebarrierptr: a"
+	func() { // ERROR "live at entry to f.func1: a &e"
+		e = a.s // ERROR "live at call to convT2Estring: a &e" "live at call to writebarrierptr: a"
 	}() // ERROR "live at call to f.func1: e$"
 	// Before the fix, both a and e were live at the previous line.
 	_ = e
diff --git a/test/fixedbugs/issue20739.go b/test/fixedbugs/issue20739.go
new file mode 100644
index 0000000..b71a25d
--- /dev/null
+++ b/test/fixedbugs/issue20739.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func F() {
+	var x struct {
+		x *int
+		w [1e9][1e9][1e9][0]*int
+		y *int
+	}
+	println(&x)
+}
diff --git a/test/fixedbugs/issue20812.go b/test/fixedbugs/issue20812.go
new file mode 100644
index 0000000..0175eed
--- /dev/null
+++ b/test/fixedbugs/issue20812.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+	_ = int("1")      // ERROR "cannot convert"
+	_ = bool(0)       // ERROR "cannot convert"
+	_ = bool("false") // ERROR "cannot convert"
+	_ = int(false)    // ERROR "cannot convert"
+	_ = string(true)  // ERROR "cannot convert"
+}
diff --git a/test/fixedbugs/issue21253.go b/test/fixedbugs/issue21253.go
new file mode 100644
index 0000000..3531b2b
--- /dev/null
+++ b/test/fixedbugs/issue21253.go
@@ -0,0 +1,27 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo crashed compiling this code due to failing to finalize
+// interfaces in the right order.
+
+package p
+
+type s1 struct {
+	f m
+	I
+}
+
+type m interface {
+	Mm(*s2)
+}
+
+type s2 struct {
+	*s1
+}
+
+type I interface {
+	MI()
+}
diff --git a/test/fixedbugs/issue21256.go b/test/fixedbugs/issue21256.go
new file mode 100644
index 0000000..3d36124
--- /dev/null
+++ b/test/fixedbugs/issue21256.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var main = func() {} // ERROR "must be func"
diff --git a/test/fixedbugs/issue21273.go b/test/fixedbugs/issue21273.go
new file mode 100644
index 0000000..7a790d1
--- /dev/null
+++ b/test/fixedbugs/issue21273.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type T0 T0 // ERROR "invalid recursive type"
+type _ map[T0]int
+
+type T1 struct{ T1 } // ERROR "invalid recursive type"
+type _ map[T1]int
+
+func f() {
+	type T2 T2 // ERROR "invalid recursive type"
+	type _ map[T2]int
+}
+
+func g() {
+	type T3 struct{ T3 } // ERROR "invalid recursive type"
+	type _ map[T3]int
+}
+
+func h() {
+	type T4 struct{ m map[T4]int } // ERROR "invalid map key"
+	type _ map[T4]int              // ERROR "invalid map key"
+}
diff --git a/test/fixedbugs/issue21317.go b/test/fixedbugs/issue21317.go
new file mode 100644
index 0000000..ae0e0b5
--- /dev/null
+++ b/test/fixedbugs/issue21317.go
@@ -0,0 +1,60 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// As of "Mon 6 Nov 2017", run.go doesn't yet have proper
+// column matching so instead match the output manually
+// by exec-ing
+
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+)
+
+func main() {
+	if runtime.Compiler != "gc" || runtime.GOOS == "nacl" {
+		return
+	}
+
+	f, err := ioutil.TempFile("", "issue21317.go")
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Fprintf(f, `
+package main
+
+import "fmt"
+
+func main() {
+        n, err := fmt.Println(1)
+}
+`)
+	f.Close()
+	defer os.RemoveAll(f.Name())
+
+	// compile and test output
+	cmd := exec.Command("go", "tool", "compile", f.Name())
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		log.Fatalf("expected cmd/compile to fail")
+	}
+	wantErrs := []string{
+		"7:9: n declared and not used",
+		"7:12: err declared and not used",
+	}
+	outStr := string(out)
+	for _, want := range wantErrs {
+		if !strings.Contains(outStr, want) {
+			log.Fatalf("failed to match %q\noutput: %q", want, outStr)
+		}
+	}
+}
diff --git a/test/fixedbugs/issue21655.go b/test/fixedbugs/issue21655.go
new file mode 100644
index 0000000..66d4e3a
--- /dev/null
+++ b/test/fixedbugs/issue21655.go
@@ -0,0 +1,62 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure assembly offsets don't get too large.
+
+// To trigger issue21655, the index offset needs to be small
+// enough to fit into an int32 (to get rewritten to an ADDQconst)
+// but large enough to overflow an int32 after multiplying by the stride.
+
+package main
+
+func f1(a []int64, i int64) int64 {
+	return a[i+1<<30]
+}
+func f2(a []int32, i int64) int32 {
+	return a[i+1<<30]
+}
+func f3(a []int16, i int64) int16 {
+	return a[i+1<<30]
+}
+func f4(a []int8, i int64) int8 {
+	return a[i+1<<31]
+}
+func f5(a []float64, i int64) float64 {
+	return a[i+1<<30]
+}
+func f6(a []float32, i int64) float32 {
+	return a[i+1<<30]
+}
+
+// Note: Before the fix for issue 21655, f{1,2,5,6} made
+// the compiler crash. f3 silently generated the wrong
+// code, using an offset of -1<<31 instead of 1<<31.
+// (This is due to the assembler accepting offsets
+// like 0x80000000 and silently using them as
+// signed 32 bit offsets.)
+// f4 was ok, but testing it can't hurt.
+
+func f7(ss []*string, i int) string {
+	const offset = 3 << 29 // 3<<29 * 4 = 3<<31 = 1<<31 mod 1<<32.
+	if i > offset {
+		return *ss[i-offset]
+	}
+	return ""
+}
+func f8(ss []*string, i int) string {
+	const offset = 3<<29 + 10
+	if i > offset {
+		return *ss[i-offset]
+	}
+	return ""
+}
+func f9(ss []*string, i int) string {
+	const offset = 3<<29 - 10
+	if i > offset {
+		return *ss[i-offset]
+	}
+	return ""
+}
diff --git a/test/fixedbugs/issue21687.go b/test/fixedbugs/issue21687.go
new file mode 100644
index 0000000..9b4c03f
--- /dev/null
+++ b/test/fixedbugs/issue21687.go
@@ -0,0 +1,68 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21687: cmd/compile evaluates x twice in "x op= y", which was
+// detectable if evaluating y affects x.
+
+package main
+
+func ptrs() (int, int) {
+	one := 1
+	two := 2
+
+	x := &one
+	*x += func() int {
+		x = &two
+		return 0
+	}()
+
+	return one, two
+}
+
+func slices() (int, int) {
+	one := []int{1}
+	two := []int{2}
+
+	x := one
+	x[0] += func() int {
+		x = two
+		return 0
+	}()
+
+	return one[0], two[0]
+}
+
+func maps() (int, int) {
+	one := map[int]int{0: 1}
+	two := map[int]int{0: 2}
+
+	x := one
+	x[0] += func() int {
+		x = two
+		return 0
+	}()
+
+	return one[0], two[0]
+}
+
+var tests = [...]func() (int, int){
+	ptrs,
+	slices,
+	maps,
+}
+
+func main() {
+	bad := 0
+	for i, f := range tests {
+		if a, b := f(); a+b != 3 {
+			println(i, a, b)
+			bad++
+		}
+	}
+	if bad != 0 {
+		panic(bad)
+	}
+}
diff --git a/test/fixedbugs/issue21709.go b/test/fixedbugs/issue21709.go
new file mode 100644
index 0000000..bf5d9d2
--- /dev/null
+++ b/test/fixedbugs/issue21709.go
@@ -0,0 +1,37 @@
+// errorcheck -0 -l -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21709: range expression overly escapes.
+
+package p
+
+type S struct{}
+
+func (s *S) Inc() {} // ERROR "\(\*S\).Inc s does not escape"
+var N int
+
+func F1() {
+	var s S // ERROR "moved to heap: s"
+	for i := 0; i < N; i++ {
+		fs := []func(){ // ERROR "F1 \[\]func\(\) literal does not escape"
+			s.Inc, // ERROR "F1 s.Inc does not escape" "s escapes to heap"
+		}
+		for _, f := range fs {
+			f()
+		}
+	}
+}
+
+func F2() {
+	var s S // ERROR "moved to heap: s"
+	for i := 0; i < N; i++ {
+		for _, f := range []func(){ // ERROR "F2 \[\]func\(\) literal does not escape"
+			s.Inc, // ERROR "F2 s.Inc does not escape" "s escapes to heap"
+		} {
+			f()
+		}
+	}
+}
diff --git a/test/fixedbugs/issue21770.go b/test/fixedbugs/issue21770.go
new file mode 100644
index 0000000..2f07d64
--- /dev/null
+++ b/test/fixedbugs/issue21770.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21770: gccgo incorrectly accepts "p.f = 0" where p is **struct
+
+package p
+
+type PP **struct{ f int }
+
+func f() {
+	// anonymous type
+	var p **struct{ f int }
+	p.f = 0 // ERROR "field"
+	// named type
+	var p2 PP
+	p2.f = 0 // ERROR "field"
+}
diff --git a/test/fixedbugs/issue21808.go b/test/fixedbugs/issue21808.go
new file mode 100644
index 0000000..d146200
--- /dev/null
+++ b/test/fixedbugs/issue21808.go
@@ -0,0 +1,17 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure println() prints a blank line.
+
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("A")
+	println()
+	fmt.Println("B")
+}
diff --git a/test/fixedbugs/issue21808.out b/test/fixedbugs/issue21808.out
new file mode 100644
index 0000000..655da03
--- /dev/null
+++ b/test/fixedbugs/issue21808.out
@@ -0,0 +1,3 @@
+A
+
+B
diff --git a/test/fixedbugs/issue21879.go b/test/fixedbugs/issue21879.go
new file mode 100644
index 0000000..1029ca0
--- /dev/null
+++ b/test/fixedbugs/issue21879.go
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"runtime"
+)
+
+func main() {
+	println(caller().frame.Function)
+
+	// Used to erroneously print "main.call.name" instead of
+	// "main.main".
+	println(caller().name())
+}
+
+func caller() call {
+	var pcs [3]uintptr
+	n := runtime.Callers(1, pcs[:])
+	frames := runtime.CallersFrames(pcs[:n])
+	frame, _ := frames.Next()
+	frame, _ = frames.Next()
+
+	return call{frame: frame}
+}
+
+type call struct {
+	frame runtime.Frame
+}
+
+func (c call) name() string {
+	return c.frame.Function
+}
diff --git a/test/fixedbugs/issue21879.out b/test/fixedbugs/issue21879.out
new file mode 100644
index 0000000..066f1a8
--- /dev/null
+++ b/test/fixedbugs/issue21879.out
@@ -0,0 +1,2 @@
+main.main
+main.main
diff --git a/test/fixedbugs/issue21882.go b/test/fixedbugs/issue21882.go
new file mode 100644
index 0000000..f77e046
--- /dev/null
+++ b/test/fixedbugs/issue21882.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T [2]T // ERROR "invalid recursive type"
diff --git a/test/fixedbugs/issue21887.go b/test/fixedbugs/issue21887.go
new file mode 100644
index 0000000..9e3e91f
--- /dev/null
+++ b/test/fixedbugs/issue21887.go
@@ -0,0 +1,25 @@
+// cmpout
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21887: println(^uint(0)) fails to compile
+
+package main
+
+import "strconv"
+
+func main() {
+	if strconv.IntSize == 32 {
+		println(^uint(0))
+	} else {
+		println(^uint32(0))
+	}
+
+	if strconv.IntSize == 64 {
+		println(^uint(0))
+	} else {
+		println(^uint64(0))
+	}
+}
diff --git a/test/fixedbugs/issue21887.out b/test/fixedbugs/issue21887.out
new file mode 100644
index 0000000..664b67d
--- /dev/null
+++ b/test/fixedbugs/issue21887.out
@@ -0,0 +1,2 @@
+4294967295
+18446744073709551615
diff --git a/test/fixedbugs/issue21963.go b/test/fixedbugs/issue21963.go
new file mode 100644
index 0000000..996bd63
--- /dev/null
+++ b/test/fixedbugs/issue21963.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"runtime"
+)
+
+//go:noinline
+func f(x []int32, y *int8) int32 {
+	c := int32(int16(*y))
+	runtime.GC()
+	return x[0] * c
+}
+
+func main() {
+	var x = [1]int32{5}
+	var y int8 = -1
+	if got, want := f(x[:], &y), int32(-5); got != want {
+		panic(fmt.Sprintf("wanted %d, got %d", want, got))
+	}
+}
diff --git a/test/fixedbugs/issue21988.go b/test/fixedbugs/issue21988.go
new file mode 100644
index 0000000..850e039
--- /dev/null
+++ b/test/fixedbugs/issue21988.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21988: panic on switch case with invalid value
+
+package p
+
+const X = Wrong(0) // ERROR "undefined: Wrong"
+
+func _() {
+	switch 0 {
+	case X:
+	}
+}
diff --git a/test/fixedbugs/issue22063.go b/test/fixedbugs/issue22063.go
new file mode 100644
index 0000000..bfdb2e0
--- /dev/null
+++ b/test/fixedbugs/issue22063.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22063: panic on interface switch case with invalid name
+
+package p
+
+const X = Wrong(0) // ERROR "undefined: Wrong"
+
+func _() {
+	switch interface{}(nil) {
+	case X:
+	}
+}
diff --git a/test/fixedbugs/issue22076.go b/test/fixedbugs/issue22076.go
new file mode 100644
index 0000000..5d628b9
--- /dev/null
+++ b/test/fixedbugs/issue22076.go
@@ -0,0 +1,25 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22076: Couldn't use ":=" to declare names that refer to
+// dot-imported symbols.
+
+package p
+
+import . "bytes"
+
+var _ Reader // use "bytes" import
+
+func _() {
+	Buffer := 0
+	_ = Buffer
+}
+
+func _() {
+	for Buffer := range []int{} {
+		_ = Buffer
+	}
+}
diff --git a/test/fixedbugs/issue22083.go b/test/fixedbugs/issue22083.go
new file mode 100644
index 0000000..a385102
--- /dev/null
+++ b/test/fixedbugs/issue22083.go
@@ -0,0 +1,41 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The compiler was panicking on the wrong line number, where
+// the panic was occurring in an inlined call.
+
+package main
+
+import (
+	"runtime/debug"
+	"strings"
+)
+
+type Wrapper struct {
+	a []int
+}
+
+func (w Wrapper) Get(i int) int {
+	return w.a[i]
+}
+
+func main() {
+	defer func() {
+		e := recover()
+		if e == nil {
+			panic("bounds check didn't fail")
+		}
+		stk := string(debug.Stack())
+		if !strings.Contains(stk, "issue22083.go:40") {
+			panic("wrong stack trace: " + stk)
+		}
+	}()
+	foo := Wrapper{a: []int{0, 1, 2}}
+	_ = foo.Get(0)
+	_ = foo.Get(1)
+	_ = foo.Get(2)
+	_ = foo.Get(3) // stack trace should mention this line
+}
diff --git a/test/fixedbugs/issue22164.go b/test/fixedbugs/issue22164.go
new file mode 100644
index 0000000..fad78e2
--- /dev/null
+++ b/test/fixedbugs/issue22164.go
@@ -0,0 +1,26 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test error recovery after missing closing parentheses in lists.
+
+package p
+
+func f() {
+	x := f(g() // ERROR "unexpected newline"
+	y := 1
+}
+
+func g() {
+}
+
+func h() {
+	x := f(g() // ERROR "unexpected newline"
+}
+
+func i() {
+	x := []int{1, 2, 3 // ERROR "unexpected newline"
+	y := 0
+}
\ No newline at end of file
diff --git a/test/fixedbugs/issue22198.go b/test/fixedbugs/issue22198.go
new file mode 100644
index 0000000..c874c1c
--- /dev/null
+++ b/test/fixedbugs/issue22198.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue22198
+
+func f(a *bool, b bool) {
+	if b {
+		return
+	}
+	c := '\n'
+	if b {
+		c = ' '
+	}
+	*a = c == '\n'
+}
diff --git a/test/fixedbugs/issue22200.go b/test/fixedbugs/issue22200.go
new file mode 100644
index 0000000..66b9538
--- /dev/null
+++ b/test/fixedbugs/issue22200.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1(x *[1<<30 - 1e6]byte) byte {
+	for _, b := range *x {
+		return b
+	}
+	return 0
+}
+func f2(x *[1<<30 + 1e6]byte) byte { // ERROR "stack frame too large"
+	for _, b := range *x {
+		return b
+	}
+	return 0
+}
diff --git a/test/fixedbugs/issue22200b.go b/test/fixedbugs/issue22200b.go
new file mode 100644
index 0000000..8d4515e
--- /dev/null
+++ b/test/fixedbugs/issue22200b.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !386,!amd64p32,!arm,!mips,!mipsle
+
+package p
+
+func f3(x *[1 << 31]byte) byte { // ERROR "stack frame too large"
+	for _, b := range *x {
+		return b
+	}
+	return 0
+}
+func f4(x *[1 << 32]byte) byte { // ERROR "stack frame too large"
+	for _, b := range *x {
+		return b
+	}
+	return 0
+}
+func f5(x *[1 << 33]byte) byte { // ERROR "stack frame too large"
+	for _, b := range *x {
+		return b
+	}
+	return 0
+}
diff --git a/test/fixedbugs/issue22351.go b/test/fixedbugs/issue22351.go
new file mode 100644
index 0000000..e46a0fb
--- /dev/null
+++ b/test/fixedbugs/issue22351.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "unsafe"
+
+const _ = uint64(unsafe.Offsetof(T{}.F)) // ERROR "undefined"
diff --git a/test/fixedbugs/issue22389.go b/test/fixedbugs/issue22389.go
new file mode 100644
index 0000000..706b449
--- /dev/null
+++ b/test/fixedbugs/issue22389.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Foo struct{}
+
+func (f *Foo) Call(cb func(*Foo)) {
+	cb(f)
+}
+
+func main() {
+	f := &Foo{}
+	f.Call(func(f) {}) // ERROR "f is not a type"
+}
diff --git a/test/fixedbugs/issue22429.go b/test/fixedbugs/issue22429.go
new file mode 100644
index 0000000..289b434
--- /dev/null
+++ b/test/fixedbugs/issue22429.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure SSA->assembly pass can handle SP as an index register.
+
+package p
+
+type T struct {
+	a,b,c,d float32
+}
+
+func f(a *[8]T, i,j,k int) float32 {
+	b := *a
+	return b[i].a + b[j].b + b[k].c
+}
diff --git a/test/fixedbugs/issue22458.go b/test/fixedbugs/issue22458.go
new file mode 100644
index 0000000..5c89929
--- /dev/null
+++ b/test/fixedbugs/issue22458.go
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure KeepAlive introduces a use of the spilled variable.
+
+package main
+
+import "runtime"
+
+type node struct {
+        next *node
+}
+
+var x bool
+
+func main() {
+        var head *node
+        for x {
+                head = &node{head}
+        }
+
+        runtime.KeepAlive(head)
+}
diff --git a/test/fixedbugs/issue22581.go b/test/fixedbugs/issue22581.go
new file mode 100644
index 0000000..2b637f2
--- /dev/null
+++ b/test/fixedbugs/issue22581.go
@@ -0,0 +1,27 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+	if i := g()); i == j { // ERROR "unexpected \)"
+	}
+
+	if i == g()] { // ERROR "unexpected \]"
+	}
+
+	switch i := g()); i { // ERROR "unexpected \)"
+	}
+
+	switch g()] { // ERROR "unexpected \]"
+	}
+
+	for i := g()); i < y; { // ERROR "unexpected \)"
+	}
+
+	for g()] { // ERROR "unexpected \]"
+	}
+}
diff --git a/test/fixedbugs/issue22605.go b/test/fixedbugs/issue22605.go
new file mode 100644
index 0000000..9e726f3
--- /dev/null
+++ b/test/fixedbugs/issue22605.go
@@ -0,0 +1,26 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// We were picking up a special noalg type from typelinks.
+
+package main
+
+import "reflect"
+
+func f(m map[string]int) int {
+	return m["a"]
+}
+
+func g(m map[[8]string]int) int {
+	t := reflect.ArrayOf(8, reflect.TypeOf(""))
+	a := reflect.New(t).Elem()
+	return m[a.Interface().([8]string)]
+}
+
+func main() {
+	m := map[[8]string]int{}
+	g(m)
+}
diff --git a/test/fixedbugs/issue22660.go b/test/fixedbugs/issue22660.go
new file mode 100644
index 0000000..48686fe
--- /dev/null
+++ b/test/fixedbugs/issue22660.go
@@ -0,0 +1,50 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+)
+
+func main() {
+	if runtime.GOOS == "nacl" {
+		return // no file system available on builders
+	}
+
+	f, err := ioutil.TempFile("", "issue22660.go")
+	if err != nil {
+		log.Fatal(err)
+	}
+	f.Close()
+	defer os.Remove(f.Name())
+
+	// path must appear in error messages even if we strip them with -trimpath
+	path := filepath.Join("users", "xxx", "go")
+	var src bytes.Buffer
+	fmt.Fprintf(&src, "//line %s:1\n", filepath.Join(path, "foo.go"))
+
+	if err := ioutil.WriteFile(f.Name(), src.Bytes(), 0660); err != nil {
+		log.Fatal(err)
+	}
+
+	out, err := exec.Command("go", "tool", "compile", fmt.Sprintf("-trimpath=%s", path), f.Name()).CombinedOutput()
+	if err == nil {
+		log.Fatalf("expected compiling %s to fail", f.Name())
+	}
+
+	if !strings.HasPrefix(string(out), path) {
+		log.Fatalf("expected full path (%s) in error message, got:\n%s", path, out)
+	}
+}
diff --git a/test/fixedbugs/issue22683.go b/test/fixedbugs/issue22683.go
new file mode 100644
index 0000000..a59a0ed
--- /dev/null
+++ b/test/fixedbugs/issue22683.go
@@ -0,0 +1,30 @@
+// cmpout
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type foo struct {
+	bar [1]*int
+}
+
+func main() {
+	ch := make(chan foo, 2)
+	var a int
+	var b [1]*int
+	b[0] = &a
+	ch <- foo{bar: b}
+	close(ch)
+
+	for v := range ch {
+		for i := 0; i < 1; i++ {
+			fmt.Println(v.bar[0] != nil)
+		}
+	}
+}
diff --git a/test/fixedbugs/issue22683.out b/test/fixedbugs/issue22683.out
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/test/fixedbugs/issue22683.out
@@ -0,0 +1 @@
+true
diff --git a/test/fixedbugs/issue22781.go b/test/fixedbugs/issue22781.go
new file mode 100644
index 0000000..5ad8239
--- /dev/null
+++ b/test/fixedbugs/issue22781.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime/debug"
+
+type T struct {
+	// >= 16 bytes to avoid tiny alloc.
+	a, b int
+}
+
+func main() {
+	debug.SetGCPercent(1)
+	for i := 0; i < 100000; i++ {
+		m := make(map[*T]struct{}, 0)
+		for j := 0; j < 20; j++ {
+			// During the call to mapassign_fast64, the key argument
+			// was incorrectly treated as a uint64. If the stack was
+			// scanned during that call, the only pointer to k was
+			// missed, leading to *k being collected prematurely.
+			k := new(T)
+			m[k] = struct{}{}
+		}
+	}
+}
diff --git a/test/fixedbugs/issue22794.go b/test/fixedbugs/issue22794.go
new file mode 100644
index 0000000..c7e9eb1
--- /dev/null
+++ b/test/fixedbugs/issue22794.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type it struct {
+	Floats bool
+	inner  string
+}
+
+func main() {
+	i1 := it{Floats: true}
+	if i1.floats { // ERROR "(type it .* field or method floats, but does have Floats)"
+	}
+	i2 := &it{floats: false} // ERROR "(but does have Floats)"
+	_ = &it{InneR: "foo"}    // ERROR "(but does have inner)"
+}
diff --git a/test/fixedbugs/issue22877.dir/p.go b/test/fixedbugs/issue22877.dir/p.go
new file mode 100644
index 0000000..fc86cb9
--- /dev/null
+++ b/test/fixedbugs/issue22877.dir/p.go
@@ -0,0 +1,14 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type S struct{ i int }
+type SS = S
+
+func sub()
+
+func main() {
+	sub()
+}
diff --git a/test/fixedbugs/issue22877.dir/p.s b/test/fixedbugs/issue22877.dir/p.s
new file mode 100644
index 0000000..8b14358
--- /dev/null
+++ b/test/fixedbugs/issue22877.dir/p.s
@@ -0,0 +1,8 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+
+TEXT ·sub(SB), 0, $0
+	RET
diff --git a/test/fixedbugs/issue22877.go b/test/fixedbugs/issue22877.go
new file mode 100644
index 0000000..284b680
--- /dev/null
+++ b/test/fixedbugs/issue22877.go
@@ -0,0 +1,7 @@
+// builddir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue22881.go b/test/fixedbugs/issue22881.go
new file mode 100644
index 0000000..61e99a2
--- /dev/null
+++ b/test/fixedbugs/issue22881.go
@@ -0,0 +1,72 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to make sure RHS is evaluated before map insert is started.
+// The RHS panics in all of these cases.
+
+package main
+
+import "fmt"
+
+func main() {
+	for i, f := range []func(map[int]int){
+		f0, f1, f2, f3, f4, f5, f6, f7,
+	} {
+		m := map[int]int{}
+		func() { // wrapper to scope the defer.
+			defer func() {
+				recover()
+			}()
+			f(m) // Will panic. Shouldn't modify m.
+			fmt.Printf("RHS didn't panic, case f%d\n", i)
+		}()
+		if len(m) != 0 {
+			fmt.Printf("map insert happened, case f%d\n", i)
+		}
+	}
+}
+
+func f0(m map[int]int) {
+	var p *int
+	m[0] = *p
+}
+
+func f1(m map[int]int) {
+	var p *int
+	m[0] += *p
+}
+
+func f2(m map[int]int) {
+	var p *int
+	sink, m[0] = sink, *p
+}
+
+func f3(m map[int]int) {
+	var p *chan int
+	m[0], sink = <-(*p)
+}
+
+func f4(m map[int]int) {
+	var p *interface{}
+	m[0], sink = (*p).(int)
+}
+
+func f5(m map[int]int) {
+	var p *map[int]int
+	m[0], sink = (*p)[0]
+}
+
+func f6(m map[int]int) {
+	var z int
+	m[0] /= z
+}
+
+func f7(m map[int]int) {
+	var a []int
+	m[0] = a[0]
+}
+
+var sink bool
diff --git a/test/fixedbugs/issue22904.go b/test/fixedbugs/issue22904.go
new file mode 100644
index 0000000..46cb7c0
--- /dev/null
+++ b/test/fixedbugs/issue22904.go
@@ -0,0 +1,19 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22904: Make sure the compiler emits a proper error message about
+// invalid recursive types rather than crashing.
+
+package p
+
+type a struct{ b }
+type b struct{ a } // ERROR "invalid recursive type"
+
+var x interface{}
+
+func f() {
+	x = a{}
+}
diff --git a/test/fixedbugs/issue22941.dir/a.go b/test/fixedbugs/issue22941.dir/a.go
new file mode 100644
index 0000000..7a4ede4
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package q
+
+type P int
diff --git a/test/fixedbugs/issue22941.dir/b.go b/test/fixedbugs/issue22941.dir/b.go
new file mode 100644
index 0000000..87d59a6
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/b.go
@@ -0,0 +1,30 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import q "./a"
+
+type T struct {
+	X *q.P
+}
+
+func F(in, out *T) {
+	*out = *in
+	if in.X != nil {
+		in, out := &in.X, &out.X
+		if *in == nil {
+			*out = nil
+		} else {
+			*out = new(q.P)
+			**out = **in
+		}
+	}
+	return
+}
+
+//go:noinline
+func G(x, y *T) {
+	F(x, y)
+}
diff --git a/test/fixedbugs/issue22941.dir/main.go b/test/fixedbugs/issue22941.dir/main.go
new file mode 100644
index 0000000..84666ad
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/main.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import p "./b"
+
+var G int
+
+func main() {
+	if G == 101 {
+		p.G(nil, nil)
+	}
+}
diff --git a/test/fixedbugs/issue22941.go b/test/fixedbugs/issue22941.go
new file mode 100644
index 0000000..c3732c3
--- /dev/null
+++ b/test/fixedbugs/issue22941.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue22962.dir/a.go b/test/fixedbugs/issue22962.dir/a.go
new file mode 100644
index 0000000..7257d7d
--- /dev/null
+++ b/test/fixedbugs/issue22962.dir/a.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func F() {
+	if x := 0; false {
+		_ = x
+	}
+}
diff --git a/test/fixedbugs/issue22962.dir/b.go b/test/fixedbugs/issue22962.dir/b.go
new file mode 100644
index 0000000..e1568c8
--- /dev/null
+++ b/test/fixedbugs/issue22962.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+var V = func() { a.F() }
diff --git a/test/fixedbugs/issue22962.go b/test/fixedbugs/issue22962.go
new file mode 100644
index 0000000..8000a52
--- /dev/null
+++ b/test/fixedbugs/issue22962.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue23093.go b/test/fixedbugs/issue23093.go
new file mode 100644
index 0000000..2fd7d5f
--- /dev/null
+++ b/test/fixedbugs/issue23093.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var f = func() { f() } // ERROR "initialization loop"
diff --git a/test/fixedbugs/issue23179.dir/a.go b/test/fixedbugs/issue23179.dir/a.go
new file mode 100644
index 0000000..3d2816f
--- /dev/null
+++ b/test/fixedbugs/issue23179.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type Large struct {
+	x [256]int
+}
+
+func F(x int, _ int, _ bool, _ Large) int {
+	return x
+}
diff --git a/test/fixedbugs/issue23179.dir/b.go b/test/fixedbugs/issue23179.dir/b.go
new file mode 100644
index 0000000..bec3d15
--- /dev/null
+++ b/test/fixedbugs/issue23179.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+func G(x int) int {
+	return a.F(x, 1, false, a.Large{})
+}
diff --git a/test/fixedbugs/issue23179.go b/test/fixedbugs/issue23179.go
new file mode 100644
index 0000000..8000a52
--- /dev/null
+++ b/test/fixedbugs/issue23179.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue23305.go b/test/fixedbugs/issue23305.go
new file mode 100644
index 0000000..28f400c
--- /dev/null
+++ b/test/fixedbugs/issue23305.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func mask1(a, b uint64) uint64 {
+	op1 := int32(a)
+	op2 := int32(b)
+	return uint64(uint32(op1 / op2))
+}
+
+var mask2 = mask1
+
+func main() {
+	res1 := mask1(0x1, 0xfffffffeffffffff)
+	res2 := mask2(0x1, 0xfffffffeffffffff)
+	if res1 != 0xffffffff {
+		println("got", res1, "want", 0xffffffff)
+		panic("FAIL")
+	}
+	if res2 != 0xffffffff {
+		println("got", res2, "want", 0xffffffff)
+		panic("FAIL")
+	}
+}
diff --git a/test/fixedbugs/issue23522.go b/test/fixedbugs/issue23522.go
new file mode 100644
index 0000000..cace86c
--- /dev/null
+++ b/test/fixedbugs/issue23522.go
@@ -0,0 +1,46 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"math"
+)
+
+type S struct {
+	u int64
+	n int32
+}
+
+func F1(f float64) *S {
+	s := f
+	pf := math.Copysign(f, 1)
+	u := math.Floor(pf)
+	return &S{
+		u: int64(math.Copysign(u, s)),
+		n: int32(math.Copysign((pf-u)*1e9, s)),
+	}
+}
+
+func F2(f float64) *S {
+	s := f
+	f = math.Copysign(f, 1)
+	u := math.Floor(f)
+	return &S{
+		u: int64(math.Copysign(u, s)),
+		n: int32(math.Copysign((f-u)*1e9, s)),
+	}
+}
+
+func main() {
+	s1 := F1(-1)
+	s2 := F2(-1)
+	if *s1 != *s2 {
+		println("F1:", s1.u, s1.n)
+		println("F2:", s2.u, s2.n)
+		panic("different")
+	}
+}
diff --git a/test/fixedbugs/issue23545.go b/test/fixedbugs/issue23545.go
new file mode 100644
index 0000000..24485c1
--- /dev/null
+++ b/test/fixedbugs/issue23545.go
@@ -0,0 +1,35 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gccgo
+
+// Issue 23545: gccgo didn't lower array comparison to
+// proper equality function in some case.
+// TODO: build only on gccgo for now, as it hits issue
+// #23546.
+
+package main
+
+func main() {
+	if a := Get(); a != dummyID(1234) {
+		panic("FAIL")
+	}
+}
+
+func dummyID(x int) [Size]interface{} {
+	var out [Size]interface{}
+	out[0] = x
+	return out
+}
+
+const Size = 32
+
+type OutputID [Size]interface{}
+
+//go:noinline
+func Get() OutputID {
+	return dummyID(1234)
+}
diff --git a/test/fixedbugs/issue23719.go b/test/fixedbugs/issue23719.go
new file mode 100644
index 0000000..c97e636
--- /dev/null
+++ b/test/fixedbugs/issue23719.go
@@ -0,0 +1,42 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+	v1 := [2]int32{-1, 88}
+	v2 := [2]int32{-1, 99}
+	if v1 == v2 {
+		panic("bad comparison")
+	}
+
+	w1 := [2]int16{-1, 88}
+	w2 := [2]int16{-1, 99}
+	if w1 == w2 {
+		panic("bad comparison")
+	}
+	x1 := [4]int16{-1, 88, 88, 88}
+	x2 := [4]int16{-1, 99, 99, 99}
+	if x1 == x2 {
+		panic("bad comparison")
+	}
+
+	a1 := [2]int8{-1, 88}
+	a2 := [2]int8{-1, 99}
+	if a1 == a2 {
+		panic("bad comparison")
+	}
+	b1 := [4]int8{-1, 88, 88, 88}
+	b2 := [4]int8{-1, 99, 99, 99}
+	if b1 == b2 {
+		panic("bad comparison")
+	}
+	c1 := [8]int8{-1, 88, 88, 88, 88, 88, 88, 88}
+	c2 := [8]int8{-1, 99, 99, 99, 99, 99, 99, 99}
+	if c1 == c2 {
+		panic("bad comparison")
+	}
+}
diff --git a/test/fixedbugs/issue23812.go b/test/fixedbugs/issue23812.go
new file mode 100644
index 0000000..0a40deb
--- /dev/null
+++ b/test/fixedbugs/issue23812.go
@@ -0,0 +1,34 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+func main() {
+	want := int32(0x3edae8)
+	got := foo(1)
+	if want != got {
+		panic(fmt.Sprintf("want %x, got %x", want, got))
+	}
+}
+
+func foo(a int32) int32 {
+	return shr1(int32(shr2(int64(0x14ff6e2207db5d1f), int(a))), 4)
+}
+
+func shr1(n int32, m int) int32 { return n >> uint(m) }
+
+func shr2(n int64, m int) int64 {
+	if m < 0 {
+		m = -m
+	}
+	if m >= 64 {
+		return n
+	}
+
+	return n >> uint(m)
+}
diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go
deleted file mode 100644
index 5bb05eb..0000000
--- a/test/fixedbugs/issue4388.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 (
-	"fmt"
-	"io"
-	"runtime"
-)
-
-type T struct {
-	io.Closer
-}
-
-func f1() {
-	// 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(5)
-	var t *T
-	var c io.Closer = t
-	c.Close()
-}
-
-func f2() {
-	defer checkLine(5)
-	var t T
-	var c io.Closer = t
-	c.Close()
-}
-
-func main() {
-	f1()
-	f2()
-}
-
-func checkLine(n int) {
-	if err := recover(); err == nil {
-		panic("did not panic")
-	}
-	var file string
-	var line int
-	for i := 1; i <= n; i++ {
-		_, file, line, _ = runtime.Caller(i)
-		if file != "<autogenerated>" || line != 1 {
-			continue
-		}
-		return
-	}
-	panic(fmt.Sprintf("expected <autogenerated>:1 have %s:%d", file, line))
-}
diff --git a/test/fixedbugs/issue7525.go b/test/fixedbugs/issue7525.go
index 6e69593..fcfab72 100644
--- a/test/fixedbugs/issue7525.go
+++ b/test/fixedbugs/issue7525.go
@@ -11,7 +11,5 @@
 import "unsafe"
 
 var x struct {
-	a [unsafe.Sizeof(x.a)]int   // ERROR "array bound|typechecking loop|invalid expression"
-	b [unsafe.Offsetof(x.b)]int // ERROR "array bound"
-	c [unsafe.Alignof(x.c)]int  // ERROR "array bound|invalid expression"
+	a [unsafe.Sizeof(x.a)]int // ERROR "array bound|typechecking loop|invalid expression"
 }
diff --git a/test/fixedbugs/issue7525d.go b/test/fixedbugs/issue7525d.go
new file mode 100644
index 0000000..141d675
--- /dev/null
+++ b/test/fixedbugs/issue7525d.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7525: self-referential array types.
+
+package main
+
+import "unsafe"
+
+var x struct {
+	b [unsafe.Offsetof(x.b)]int // ERROR "array bound|typechecking loop|invalid array"
+}
diff --git a/test/fixedbugs/issue7525e.go b/test/fixedbugs/issue7525e.go
new file mode 100644
index 0000000..c13194c
--- /dev/null
+++ b/test/fixedbugs/issue7525e.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7525: self-referential array types.
+
+package main
+
+import "unsafe"
+
+var x struct {
+	c [unsafe.Alignof(x.c)]int // ERROR "array bound|typechecking loop|invalid array"
+}
diff --git a/test/inline.go b/test/inline.go
index 773b047..2553230 100644
--- a/test/inline.go
+++ b/test/inline.go
@@ -9,7 +9,10 @@
 
 package foo
 
-import "unsafe"
+import (
+	"errors"
+	"unsafe"
+)
 
 func add2(p *byte, n uintptr) *byte { // ERROR "can inline add2" "leaking param: p to result"
 	return (*byte)(add1(unsafe.Pointer(p), n)) // ERROR "inlining call to add1"
@@ -46,6 +49,83 @@
 	}
 }
 
+var somethingWrong error = errors.New("something went wrong")
+
+// local closures can be inlined
+func l(x, y int) (int, int, error) {
+	e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result"
+		return 0, 0, err
+	}
+	if x == y {
+		e(somethingWrong) // ERROR "inlining call to l.func1"
+	}
+	return y, x, nil
+}
+
+// any re-assignment prevents closure inlining
+func m() int {
+	foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape"
+	x := foo()
+	foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape"
+	return x + foo()
+}
+
+// address taking prevents closure inlining
+func n() int {
+	foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape"
+	bar := &foo                    // ERROR "&foo does not escape"
+	x := (*bar)() + foo()
+	return x
+}
+
+// make sure assignment inside closure is detected
+func o() int {
+	foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
+	func(x int) {                  // ERROR "func literal does not escape"
+		if x > 10 {
+			foo = func() int { return 2 } // ERROR "can inline o.func2" "func literal escapes"
+		}
+	}(11)
+	return foo()
+}
+
+func p() int {
+	return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
+}
+
+func q(x int) int {
+	foo := func() int { return x * 2 } // ERROR "can inline q.func1" "q func literal does not escape"
+	return foo()                       // ERROR "inlining call to q.func1"
+}
+
+func r(z int) int {
+	foo := func(x int) int { // ERROR "can inline r.func1" "r func literal does not escape"
+		return x + z
+	}
+	bar := func(x int) int { // ERROR "r func literal does not escape"
+		return x + func(y int) int { // ERROR "can inline r.func2.1"
+			return 2*y + x*z
+		}(x) // ERROR "inlining call to r.func2.1"
+	}
+	return foo(42) + bar(42) // ERROR "inlining call to r.func1"
+}
+
+func s0(x int) int {
+	foo := func() { // ERROR "can inline s0.func1" "s0 func literal does not escape"
+		x = x + 1
+	}
+	foo() // ERROR "inlining call to s0.func1" "&x does not escape"
+	return x
+}
+
+func s1(x int) int {
+	foo := func() int { // ERROR "can inline s1.func1" "s1 func literal does not escape"
+		return x
+	}
+	x = x + 1
+	return foo() // ERROR "inlining call to s1.func1" "&x does not escape"
+}
+
 // can't currently inline functions with a break statement
 func switchBreak(x, y int) int {
 	var n int
@@ -72,3 +152,13 @@
 		return 0
 	}
 }
+
+type T struct{}
+
+func (T) meth(int, int) {} // ERROR "can inline T.meth"
+
+func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k"
+
+func _() { // ERROR "can inline _"
+	T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth"
+}
diff --git a/test/inline_callers.go b/test/inline_callers.go
index fb6ff6c..6df6861 100644
--- a/test/inline_callers.go
+++ b/test/inline_callers.go
@@ -1,4 +1,4 @@
-// run -gcflags -l=4
+// run -gcflags=-l=4
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -7,7 +7,7 @@
 package main
 
 import (
-	"log"
+	"fmt"
 	"runtime"
 )
 
@@ -83,13 +83,13 @@
 		frames := testCallers(i)
 		expected := expectedFrames[i]
 		if !same(frames, expected) {
-			log.Fatalf("testCallers(%d):\n got %v\n want %v", i, frames, expected)
+			fmt.Printf("testCallers(%d):\n got %v\n want %v\n", i, frames, expected)
 		}
 
 		frames = testCallersFrames(i)
 		expected = allFrames[i:]
 		if !same(frames, expected) {
-			log.Fatalf("testCallersFrames(%d):\n got %v\n want %v", i, frames, expected)
+			fmt.Printf("testCallersFrames(%d):\n got %v\n want %v\n", i, frames, expected)
 		}
 	}
 }
diff --git a/test/intrinsic_atomic.go b/test/intrinsic_atomic.go
index dd765a0..a90056e 100644
--- a/test/intrinsic_atomic.go
+++ b/test/intrinsic_atomic.go
@@ -1,5 +1,5 @@
 // errorcheck -0 -d=ssa/intrinsics/debug
-// +build amd64 arm64
+// +build amd64 arm64 mips mipsle mips64 mips64le ppc64 ppc64le s390x
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/live.go b/test/live.go
index ef988a0..e54336e 100644
--- a/test/live.go
+++ b/test/live.go
@@ -239,15 +239,6 @@
 
 func g14() string
 
-func f15() {
-	var x string
-	_ = &x
-	x = g15()      // ERROR "live at call to g15: x$"
-	printstring(x) // ERROR "live at call to printstring: x$"
-}
-
-func g15() string
-
 // Checking that various temporaries do not persist or cause
 // ambiguously live values that must be zeroed.
 // The exact temporary names are inconsequential but we are
@@ -384,10 +375,9 @@
 		return
 	}
 	var x string
-	_ = &x
-	x = g15()      // ERROR "live at call to g15: x$"
-	printstring(x) // ERROR "live at call to printstring: x$"
-} // ERROR "live at call to deferreturn: x$"
+	x = g14()
+	printstring(x)
+}
 
 func g25()
 
@@ -473,22 +463,30 @@
 }
 
 // copy of array of pointers should die at end of range loop
+var pstructarr [10]pstruct
 
-var ptrarr [10]*int
+// Struct size choosen to make pointer to element in pstructarr
+// not computable by strength reduction.
+type pstruct struct {
+	intp *int
+	_    [8]byte
+}
 
 func f30(b bool) {
-	// two live temps during print(p):
-	// the copy of ptrarr and the internal iterator pointer.
+	// two live temps during printintpointer(p):
+	// in the copy of p.intp and
+	// the internal iterator pointer if a pointer to pstruct in pstructarr
+	// can not be easily computed by strength reduction.
 	if b {
-		for _, p := range ptrarr {
-			printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+		for _, p := range pstructarr {
+			printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
 		}
 	}
-	for _, p := range ptrarr {
-		printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+	for _, p := range pstructarr {
+		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
 	}
-	for _, p := range ptrarr {
-		printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+	for _, p := range pstructarr {
+		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
 	}
 }
 
@@ -641,9 +639,12 @@
 	m map[int]int
 }
 
+//go:noescape
+func useT40(*T40)
+
 func newT40() *T40 {
 	ret := T40{}
-	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$"
+	ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
 	return &ret
 }
 
@@ -655,10 +656,10 @@
 
 func good40() {
 	ret := T40{}
-	ret.m = make(map[int]int) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
+	ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+ ret$"
 	t := &ret
 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
-	_ = t
+	useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
 }
 
 func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
diff --git a/test/live2.go b/test/live2.go
index 6138d36..cc1b0b7 100644
--- a/test/live2.go
+++ b/test/live2.go
@@ -14,26 +14,29 @@
 
 func printnl()
 
+//go:noescape
+func useT40(*T40)
+
 type T40 struct {
 	m map[int]int
 }
 
 func newT40() *T40 {
 	ret := T40{}
-	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$"
+	ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
 	return &ret
 }
 
 func bad40() {
 	t := newT40() // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
 	printnl()     // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
-	_ = t
+	useT40(t)     // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
 }
 
 func good40() {
 	ret := T40{}
-	ret.m = make(map[int]int) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
+	ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
 	t := &ret
 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
-	_ = t
+	useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
 }
diff --git a/test/live_syscall.go b/test/live_syscall.go
index f693e93..6d95465 100644
--- a/test/live_syscall.go
+++ b/test/live_syscall.go
@@ -26,3 +26,15 @@
 	var v int
 	syscall.Syscall(0, 1, uintptr(unsafe.Pointer(&v)), 2) // ERROR "live at call to Syscall: .?autotmp" "h &v does not escape"
 }
+
+func i() {
+	var t int
+	p := unsafe.Pointer(&t) // ERROR "i &t does not escape"
+	f(uintptr(p))           // ERROR "live at call to f: .?autotmp"
+}
+
+func j() {
+	var v int
+	p := unsafe.Pointer(&v)              // ERROR "j &v does not escape"
+	syscall.Syscall(0, 1, uintptr(p), 2) // ERROR "live at call to Syscall: .?autotmp"
+}
diff --git a/test/makechan.go b/test/makechan.go
new file mode 100644
index 0000000..0ac38c4
--- /dev/null
+++ b/test/makechan.go
@@ -0,0 +1,34 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that typed non-integer, negative and to large
+// values are not accepted as size argument in make for
+// channels.
+
+package main
+
+type T chan byte
+
+var sink T
+
+func main() {
+	sink = make(T, -1)            // ERROR "negative buffer argument in make.*"
+	sink = make(T, uint64(1<<63)) // ERROR "buffer argument too large in make.*"
+
+	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+	sink = make(T, 1.0)
+	sink = make(T, float32(1.0)) // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, float64(1.0)) // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, 1.0)
+	sink = make(T, float32(1.0)) // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, float64(1.0)) // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, 1+0i)
+	sink = make(T, complex64(1+0i))  // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, 1+0i)
+	sink = make(T, complex64(1+0i))  // ERROR "non-integer buffer argument in make.*"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer buffer argument in make.*"
+}
diff --git a/test/makemap.go b/test/makemap.go
new file mode 100644
index 0000000..60983c0
--- /dev/null
+++ b/test/makemap.go
@@ -0,0 +1,34 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that typed non-integer, negative and too large
+// values are not accepted as size argument in make for
+// maps.
+
+package main
+
+type T map[int]int
+
+var sink T
+
+func main() {
+	sink = make(T, -1)            // ERROR "negative size argument in make.*"
+	sink = make(T, uint64(1<<63)) // ERROR "size argument too large in make.*"
+
+	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+	sink = make(T, 1.0)
+	sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+	sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+	sink = make(T, 1.0)
+	sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+	sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+	sink = make(T, 1+0i)
+	sink = make(T, complex64(1+0i))  // ERROR "non-integer size argument in make.*"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+	sink = make(T, 1+0i)
+	sink = make(T, complex64(1+0i))  // ERROR "non-integer size argument in make.*"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+}
diff --git a/test/mergemul.go b/test/mergemul.go
new file mode 100644
index 0000000..a23115b
--- /dev/null
+++ b/test/mergemul.go
@@ -0,0 +1,117 @@
+// runoutput
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+// Check that expressions like (c*n + d*(n+k)) get correctly merged by
+// the compiler into (c+d)*n + d*k (with c+d and d*k computed at
+// compile time).
+//
+// The merging is performed by a combination of the multiplication
+// merge rules
+//  (c*n + d*n) -> (c+d)*n
+// and the distributive multiplication rules
+//  c * (d+x)  ->  c*d + c*x
+
+// Generate a MergeTest that looks like this:
+//
+//   a8, b8 = m1*n8 + m2*(n8+k), (m1+m2)*n8 + m2*k
+//   if a8 != b8 {
+// 	   // print error msg and panic
+//   }
+func makeMergeAddTest(m1, m2, k int, size string) string {
+
+	model := "    a" + size + ", b" + size
+	model += fmt.Sprintf(" = %%d*n%s + %%d*(n%s+%%d), (%%d+%%d)*n%s + (%%d*%%d)", size, size, size)
+
+	test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
+	test += fmt.Sprintf(`
+    if a%s != b%s {
+        fmt.Printf("MergeAddTest(%d, %d, %d, %s) failed\n")
+        fmt.Printf("%%d != %%d\n", a%s, b%s)
+        panic("FAIL")
+    }
+`, size, size, m1, m2, k, size, size, size)
+	return test + "\n"
+}
+
+// Check that expressions like (c*n - d*(n+k)) get correctly merged by
+// the compiler into (c-d)*n - d*k (with c-d and d*k computed at
+// compile time).
+//
+// The merging is performed by a combination of the multiplication
+// merge rules
+//  (c*n - d*n) -> (c-d)*n
+// and the distributive multiplication rules
+//  c * (d-x)  ->  c*d - c*x
+
+// Generate a MergeTest that looks like this:
+//
+//   a8, b8 = m1*n8 - m2*(n8+k), (m1-m2)*n8 - m2*k
+//   if a8 != b8 {
+// 	   // print error msg and panic
+//   }
+func makeMergeSubTest(m1, m2, k int, size string) string {
+
+	model := "    a" + size + ", b" + size
+	model += fmt.Sprintf(" = %%d*n%s - %%d*(n%s+%%d), (%%d-%%d)*n%s - (%%d*%%d)", size, size, size)
+
+	test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
+	test += fmt.Sprintf(`
+    if a%s != b%s {
+        fmt.Printf("MergeSubTest(%d, %d, %d, %s) failed\n")
+        fmt.Printf("%%d != %%d\n", a%s, b%s)
+        panic("FAIL")
+    }
+`, size, size, m1, m2, k, size, size, size)
+	return test + "\n"
+}
+
+func makeAllSizes(m1, m2, k int) string {
+	var tests string
+	tests += makeMergeAddTest(m1, m2, k, "8")
+	tests += makeMergeAddTest(m1, m2, k, "16")
+	tests += makeMergeAddTest(m1, m2, k, "32")
+	tests += makeMergeAddTest(m1, m2, k, "64")
+	tests += makeMergeSubTest(m1, m2, k, "8")
+	tests += makeMergeSubTest(m1, m2, k, "16")
+	tests += makeMergeSubTest(m1, m2, k, "32")
+	tests += makeMergeSubTest(m1, m2, k, "64")
+	tests += "\n"
+	return tests
+}
+
+func main() {
+	fmt.Println(`package main
+
+import "fmt"
+
+var n8 int8 = 42
+var n16 int16 = 42
+var n32 int32 = 42
+var n64 int64 = 42
+
+func main() {
+    var a8, b8 int8
+    var a16, b16 int16
+    var a32, b32 int32
+    var a64, b64 int64
+`)
+
+	fmt.Println(makeAllSizes(03, 05, 0)) // 3*n + 5*n
+	fmt.Println(makeAllSizes(17, 33, 0))
+	fmt.Println(makeAllSizes(80, 45, 0))
+	fmt.Println(makeAllSizes(32, 64, 0))
+
+	fmt.Println(makeAllSizes(7, 11, +1)) // 7*n + 11*(n+1)
+	fmt.Println(makeAllSizes(9, 13, +2))
+	fmt.Println(makeAllSizes(11, 16, -1))
+	fmt.Println(makeAllSizes(17, 9, -2))
+
+	fmt.Println("}")
+}
diff --git a/test/method2.go b/test/method2.go
index e55aee4..a45a943 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -35,3 +35,7 @@
 
 var _ = pv.val() // ERROR "pv.val undefined"
 var _ = pv.val   // ERROR "pv.val undefined"
+
+func (t *T) g() int { return t.a }
+
+var _ = (T).g() // ERROR "needs pointer receiver|undefined"
diff --git a/test/method6.go b/test/method6.go
new file mode 100644
index 0000000..20eccce
--- /dev/null
+++ b/test/method6.go
@@ -0,0 +1,22 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Verify that pointer method calls are caught during typechecking.
+// Reproducer extracted and adapted from method.go
+
+package foo
+
+type A struct {
+	B
+}
+type B int
+
+func (*B) g() {}
+
+var _ = func() {
+	var a A
+	A(a).g() // ERROR "cannot call pointer method on|cannot take the address of"
+}
diff --git a/test/method7.go b/test/method7.go
new file mode 100644
index 0000000..72c88b3
--- /dev/null
+++ b/test/method7.go
@@ -0,0 +1,56 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test forms of method expressions T.m where T is
+// a literal type.
+
+package main
+
+var got, want string
+
+type I interface {
+	m()
+}
+
+type S struct {
+}
+
+func (S) m()          { got += " m()" }
+func (S) m1(s string) { got += " m1(" + s + ")" }
+
+type T int
+
+func (T) m2() { got += " m2()" }
+
+func main() {
+	// method expressions with named receiver types
+	I.m(S{})
+	want += " m()"
+
+	S.m1(S{}, "a")
+	want += " m1(a)"
+
+	// method expressions with literal receiver types
+	f := interface{ m1(string) }.m1
+	f(S{}, "b")
+	want += " m1(b)"
+
+	interface{ m1(string) }.m1(S{}, "c")
+	want += " m1(c)"
+
+	x := S{}
+	interface{ m1(string) }.m1(x, "d")
+	want += " m1(d)"
+
+	// cannot link the call below - see #22444
+	// g := struct{ T }.m2
+	// g(struct{T}{})
+	// want += " m2()"
+
+	if got != want {
+		panic("got" + got + ", want" + want)
+	}
+}
diff --git a/test/nilptr3.go b/test/nilptr3.go
index 195c8ca..9a96bb5 100644
--- a/test/nilptr3.go
+++ b/test/nilptr3.go
@@ -259,3 +259,10 @@
 func f8(t *[8]int) [8]int {
 	return *t // ERROR "removed nil check"
 }
+
+func f9() []int {
+	x := new([1]int)
+	x[0] = 1  // ERROR "removed nil check"
+	y := x[:] // ERROR "removed nil check"
+	return y
+}
diff --git a/test/nosplit.go b/test/nosplit.go
index 989d8cc..e6ceceb 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -115,15 +115,15 @@
 main 136
 
 # A nosplit leaf can use the whole 128-CallSize bytes available on entry.
-# (CallSize is 32 on ppc64)
+# (CallSize is 32 on ppc64, 8 on amd64 for frame pointer.)
 main 96 nosplit
 main 100 nosplit; REJECT ppc64 ppc64le
 main 104 nosplit; REJECT ppc64 ppc64le
 main 108 nosplit; REJECT ppc64 ppc64le
 main 112 nosplit; REJECT ppc64 ppc64le
 main 116 nosplit; REJECT ppc64 ppc64le
-main 120 nosplit; REJECT ppc64 ppc64le
-main 124 nosplit; REJECT ppc64 ppc64le
+main 120 nosplit; REJECT ppc64 ppc64le amd64
+main 124 nosplit; REJECT ppc64 ppc64le amd64
 main 128 nosplit; REJECT
 main 132 nosplit; REJECT
 main 136 nosplit; REJECT
@@ -132,13 +132,14 @@
 # having room for the saved caller PC and the called frame.
 # Because ARM doesn't save LR in the leaf, it gets an extra 4 bytes.
 # Because arm64 doesn't save LR in the leaf, it gets an extra 8 bytes.
-# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 fewer bytes than amd64.
+# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 bytes.
+# Because AMD64 uses frame pointer, it has 8 fewer bytes.
 main 96 nosplit call f; f 0 nosplit
 main 100 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
 main 104 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
 main 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
-main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
-main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
+main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
+main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
 main 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
 main 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386
 main 128 nosplit call f; f 0 nosplit; REJECT
@@ -148,11 +149,11 @@
 # Calling a splitting function from a nosplit function requires
 # having room for the saved caller PC of the call but also the
 # saved caller PC for the call to morestack.
-# RISC architectures differ in the same way as before.
+# Architectures differ in the same way as before.
 main 96 nosplit call f; f 0 call f
 main 100 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
-main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
-main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
+main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
+main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
 main 112 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
 main 116 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
 main 120 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386
@@ -164,8 +165,8 @@
 # Indirect calls are assumed to be splitting functions.
 main 96 nosplit callind
 main 100 nosplit callind; REJECT ppc64 ppc64le
-main 104 nosplit callind; REJECT ppc64 ppc64le
-main 108 nosplit callind; REJECT ppc64 ppc64le
+main 104 nosplit callind; REJECT ppc64 ppc64le amd64
+main 108 nosplit callind; REJECT ppc64 ppc64le amd64
 main 112 nosplit callind; REJECT ppc64 ppc64le amd64
 main 116 nosplit callind; REJECT ppc64 ppc64le amd64
 main 120 nosplit callind; REJECT ppc64 ppc64le amd64 386
@@ -198,18 +199,14 @@
 		goarch = runtime.GOARCH
 	}
 
-	// Frame pointer is on by default now.
-	// golang.org/issue/18317.
-	return
-
 	version, err := exec.Command("go", "tool", "compile", "-V").Output()
 	if err != nil {
 		bug()
 		fmt.Printf("running go tool compile -V: %v\n", err)
 		return
 	}
-	if strings.Contains(string(version), "framepointer") {
-		// Skip this test if GOEXPERIMENT=framepointer
+	if s := string(version); goarch == "amd64" && strings.Contains(s, "X:") && !strings.Contains(s, "framepointer") {
+		// Skip this test if framepointer is NOT enabled on AMD64
 		return
 	}
 
@@ -266,18 +263,18 @@
 		ptrSize := 4
 		switch goarch {
 		case "mips", "mipsle":
-			fmt.Fprintf(&buf, "#define CALL JAL\n#define REGISTER (R0)\n")
+			fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
 		case "mips64", "mips64le":
 			ptrSize = 8
-			fmt.Fprintf(&buf, "#define CALL JAL\n#define REGISTER (R0)\n")
+			fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
 		case "ppc64", "ppc64le":
 			ptrSize = 8
-			fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (CTR)\n")
+			fmt.Fprintf(&buf, "#define REGISTER (CTR)\n")
 		case "arm":
-			fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
+			fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
 		case "arm64":
 			ptrSize = 8
-			fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
+			fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
 		case "amd64":
 			ptrSize = 8
 			fmt.Fprintf(&buf, "#define REGISTER AX\n")
@@ -307,7 +304,7 @@
 				name := m[1]
 				size, _ := strconv.Atoi(m[2])
 
-				// The limit was originally 128 but is now 592.
+				// The limit was originally 128 but is now 752 (880-128).
 				// Instead of rewriting the test cases above, adjust
 				// the first stack frame to use up the extra bytes.
 				if i == 0 {
diff --git a/test/notinheap3.go b/test/notinheap3.go
new file mode 100644
index 0000000..d48c2a0
--- /dev/null
+++ b/test/notinheap3.go
@@ -0,0 +1,60 @@
+// errorcheck -+ -0 -l -d=wb
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test write barrier elimination for notinheap.
+
+package p
+
+type t1 struct {
+	x *nih
+	s []nih
+	y [1024]byte // Prevent write decomposition
+}
+
+type t2 struct {
+	x *ih
+	s []ih
+	y [1024]byte
+}
+
+//go:notinheap
+type nih struct {
+	x uintptr
+}
+
+type ih struct { // In-heap type
+	x uintptr
+}
+
+var (
+	v1 t1
+	v2 t2
+
+	v1s []t1
+	v2s []t2
+)
+
+func f() {
+	// Test direct writes
+	v1.x = nil        // no barrier
+	v2.x = nil        // ERROR "write barrier"
+	v1.s = []nih(nil) // no barrier
+	v2.s = []ih(nil)  // ERROR "write barrier"
+}
+
+func g() {
+	// Test aggregate writes
+	v1 = t1{x: nil} // no barrier
+	v2 = t2{x: nil} // ERROR "write barrier"
+}
+
+func h() {
+	// Test copies and appends.
+	copy(v1s, v1s[1:])      // no barrier
+	copy(v2s, v2s[1:])      // ERROR "write barrier"
+	_ = append(v1s, v1s...) // no barrier
+	_ = append(v2s, v2s...) // ERROR "write barrier"
+}
diff --git a/test/nowritebarrier.go b/test/nowritebarrier.go
index 23dce75..64666fa 100644
--- a/test/nowritebarrier.go
+++ b/test/nowritebarrier.go
@@ -76,3 +76,18 @@
 func d4() {
 	d2()
 }
+
+//go:noinline
+func systemstack(func()) {}
+
+//go:nowritebarrierrec
+func e1() {
+	systemstack(e2)
+	systemstack(func() {
+		x.f = y // ERROR "write barrier prohibited by caller"
+	})
+}
+
+func e2() {
+	x.f = y // ERROR "write barrier prohibited by caller"
+}
diff --git a/test/print.go b/test/print.go
index 466e19f..b7f3db0 100644
--- a/test/print.go
+++ b/test/print.go
@@ -19,6 +19,11 @@
 	println(([]int)(nil))       // printslice
 	println(int64(-7))          // printint
 	println(uint64(7))          // printuint
+	println(uint32(7))          // printuint
+	println(uint16(7))          // printuint
+	println(uint8(7))           // printuint
+	println(uint(7))            // printuint
+	println(uintptr(7))         // printuint
 	println(8.0)                // printfloat
 	println(complex(9.0, 10.0)) // printcomplex
 	println(true)               // printbool
@@ -28,11 +33,18 @@
 
 	// test goprintf
 	defer println((interface{})(nil))
-	defer println((interface{f()})(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(uint32(12))
+	defer println(uint16(12))
+	defer println(uint8(12))
+	defer println(uint(12))
+	defer println(uintptr(12))
 	defer println(13.0)
 	defer println(complex(14.0, 15.0))
 	defer println(true)
diff --git a/test/print.out b/test/print.out
index 266fe5d..85376af 100644
--- a/test/print.out
+++ b/test/print.out
@@ -4,6 +4,11 @@
 [0/0]0x0
 -7
 7
+7
+7
+7
+7
+7
 +8.000000e+000
 (+9.000000e+000+1.000000e+001i)
 true
@@ -17,6 +22,11 @@
 (+1.400000e+001+1.500000e+001i)
 +1.300000e+001
 12
+12
+12
+12
+12
+12
 -11
 [0/0]0x0
 0x0
diff --git a/test/range.go b/test/range.go
index afdac57..3da7d17 100644
--- a/test/range.go
+++ b/test/range.go
@@ -23,12 +23,57 @@
 	return c
 }
 
+const alphabet = "abcdefghijklmnopqrstuvwxyz"
+
+func testblankvars() {
+	n := 0
+	for range alphabet {
+		n++
+	}
+	if n != 26 {
+		println("for range: wrong count", n, "want 26")
+		panic("fail")
+	}
+	n = 0
+	for _ = range alphabet {
+		n++
+	}
+	if n != 26 {
+		println("for _ = range: wrong count", n, "want 26")
+		panic("fail")
+	}
+	n = 0
+	for _, _ = range alphabet {
+		n++
+	}
+	if n != 26 {
+		println("for _, _ = range: wrong count", n, "want 26")
+		panic("fail")
+	}
+	s := 0
+	for i, _ := range alphabet {
+		s += i
+	}
+	if s != 325 {
+		println("for i, _ := range: wrong sum", s, "want 325")
+		panic("fail")
+	}
+	r := rune(0)
+	for _, v := range alphabet {
+		r += v
+	}
+	if r != 2847 {
+		println("for _, v := range: wrong sum", r, "want 2847")
+		panic("fail")
+	}
+}
+
 func testchan() {
 	s := ""
 	for i := range seq('a', 'z') {
 		s += string(i)
 	}
-	if s != "abcdefghijklmnopqrstuvwxyz" {
+	if s != alphabet {
 		println("Wanted lowercase alphabet; got", s)
 		panic("fail")
 	}
@@ -38,6 +83,7 @@
 	}
 	if n != 26 {
 		println("testchan wrong count", n, "want 26")
+		panic("fail")
 	}
 }
 
@@ -426,6 +472,7 @@
 }
 
 func main() {
+	testblankvars()
 	testchan()
 	testarray()
 	testarray1()
diff --git a/test/recover4.go b/test/recover4.go
index da5117c..67ed970 100644
--- a/test/recover4.go
+++ b/test/recover4.go
@@ -68,6 +68,6 @@
 		log.Fatal("no error from memcopy across memory hole")
 	}
 	if n != 8*size-5 {
-		log.Fatal("memcopy returned %d, want %d", n, 8*size-5)
+		log.Fatalf("memcopy returned %d, want %d", n, 8*size-5)
 	}
 }
diff --git a/test/rename1.go b/test/rename1.go
index a71e5b2..568aa13 100644
--- a/test/rename1.go
+++ b/test/rename1.go
@@ -10,10 +10,10 @@
 package main
 
 func main() {
-	var n byte       // ERROR "not a type|expected type"
+	var n byte         // ERROR "not a type|expected type"
 	var y = float32(0) // ERROR "cannot call|expected function"
 	const (
-		a = 1 + iota // ERROR "string|incompatible types" "convert iota"
+		a = 1 + iota // ERROR "invalid operation|incompatible types" "cannot convert iota"
 	)
 
 }
diff --git a/test/run.go b/test/run.go
index 2fa2067..22ec757 100644
--- a/test/run.go
+++ b/test/run.go
@@ -417,6 +417,14 @@
 
 func init() { checkShouldTest() }
 
+// goGcflags returns the -gcflags argument to use with go build / go run.
+// This must match the flags used for building the standard libary,
+// or else the commands will rebuild any needed packages (like runtime)
+// over and over.
+func goGcflags() string {
+	return "-gcflags=" + os.Getenv("GO_GCFLAGS")
+}
+
 // run runs a test.
 func (t *test) run() {
 	start := time.Now()
@@ -701,7 +709,7 @@
 		}
 
 	case "build":
-		_, err := runcmd("go", "build", "-o", "a.exe", long)
+		_, err := runcmd("go", "build", goGcflags(), "-o", "a.exe", long)
 		if err != nil {
 			t.err = err
 		}
@@ -728,6 +736,9 @@
 		}
 		var objs []string
 		cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"}
+		if len(asms) > 0 {
+			cmd = append(cmd, "-asmhdr", "go_asm.h")
+		}
 		for _, file := range gos {
 			cmd = append(cmd, filepath.Join(longdir, file.Name()))
 		}
@@ -766,7 +777,7 @@
 	case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop.
 		// TODO: not supported on NaCl
 		useTmp = true
-		cmd := []string{"go", "build", "-o", "a.exe"}
+		cmd := []string{"go", "build", goGcflags(), "-o", "a.exe"}
 		if *linkshared {
 			cmd = append(cmd, "-linkshared")
 		}
@@ -791,13 +802,38 @@
 
 	case "run":
 		useTmp = false
-		cmd := []string{"go", "run"}
-		if *linkshared {
-			cmd = append(cmd, "-linkshared")
+		var out []byte
+		var err error
+		if len(flags)+len(args) == 0 && goGcflags() == "" && !*linkshared {
+			// If we're not using special go command flags,
+			// skip all the go command machinery.
+			// This avoids any time the go command would
+			// spend checking whether, for example, the installed
+			// package runtime is up to date.
+			// Because we run lots of trivial test programs,
+			// the time adds up.
+			pkg := filepath.Join(t.tempDir, "pkg.a")
+			if _, err := runcmd("go", "tool", "compile", "-o", pkg, t.goFileName()); err != nil {
+				t.err = err
+				return
+			}
+			exe := filepath.Join(t.tempDir, "test.exe")
+			cmd := []string{"go", "tool", "link", "-s", "-w"}
+			cmd = append(cmd, "-o", exe, pkg)
+			if _, err := runcmd(cmd...); err != nil {
+				t.err = err
+				return
+			}
+			out, err = runcmd(append([]string{exe}, args...)...)
+		} else {
+			cmd := []string{"go", "run", goGcflags()}
+			if *linkshared {
+				cmd = append(cmd, "-linkshared")
+			}
+			cmd = append(cmd, flags...)
+			cmd = append(cmd, t.goFileName())
+			out, err = runcmd(append(cmd, args...)...)
 		}
-		cmd = append(cmd, flags...)
-		cmd = append(cmd, t.goFileName())
-		out, err := runcmd(append(cmd, args...)...)
 		if err != nil {
 			t.err = err
 			return
@@ -812,7 +848,7 @@
 			<-rungatec
 		}()
 		useTmp = false
-		cmd := []string{"go", "run"}
+		cmd := []string{"go", "run", goGcflags()}
 		if *linkshared {
 			cmd = append(cmd, "-linkshared")
 		}
@@ -827,7 +863,7 @@
 			t.err = fmt.Errorf("write tempfile:%s", err)
 			return
 		}
-		cmd = []string{"go", "run"}
+		cmd = []string{"go", "run", goGcflags()}
 		if *linkshared {
 			cmd = append(cmd, "-linkshared")
 		}
@@ -843,7 +879,7 @@
 
 	case "errorcheckoutput":
 		useTmp = false
-		cmd := []string{"go", "run"}
+		cmd := []string{"go", "run", goGcflags()}
 		if *linkshared {
 			cmd = append(cmd, "-linkshared")
 		}
diff --git a/test/shift1.go b/test/shift1.go
index c81ee51..01ecbed 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -152,8 +152,7 @@
 	var a []int
 	_ = a[1<<s]
 	_ = a[1.]
-	// For now, the spec disallows these. We may revisit past Go 1.1.
-	_ = a[1.<<s]  // ERROR "integer|shift of type float64"
+	_ = a[1.<<s]
 	_ = a[1.1<<s] // ERROR "integer|shift of type float64"
 
 	_ = make([]int, 1)